BUUUUUNCH of shit, but added logger, more stl nonsense, improved code quaklity, squashed bugs.
This commit is contained in:
parent
3b1b2bfb06
commit
2a31d770ed
2
.vscode/launch.json
vendored
2
.vscode/launch.json
vendored
|
@ -6,7 +6,7 @@
|
|||
"configurations": [
|
||||
{
|
||||
"name": "(gdb) Launch",
|
||||
"type": "cppdbg",
|
||||
"type": "by-gdb",
|
||||
"request": "launch",
|
||||
"program": "${workspaceFolder}/test/test",
|
||||
"args": [],
|
||||
|
|
10
Makefile
10
Makefile
|
@ -2,11 +2,11 @@ LIB=libc+
|
|||
|
||||
COM_FLAGS = -fPIC -Isrc/include
|
||||
CC_FLAGS = -std=c23 -ggdb
|
||||
CXX_FLAGS = -std=c++23 -nostdinc++ -ggdb
|
||||
LD_FLAGS = -nostdlib++ -lsupc++ -ggdb
|
||||
CC=gcc
|
||||
CXX=g++
|
||||
LD=gcc
|
||||
CXX_FLAGS = -std=c++23 -nostdinc++ -ggdb -fexceptions
|
||||
LD_FLAGS = -nostdlib++ -lsupc++ -ggdb -fexceptions
|
||||
CC=clang
|
||||
CXX=clang
|
||||
LD=clang
|
||||
AR=ar
|
||||
|
||||
cxx_sources=$(wildcard src/*.cpp)
|
||||
|
|
35
src/include/collections/hasmap.hpp
Normal file
35
src/include/collections/hasmap.hpp
Normal file
|
@ -0,0 +1,35 @@
|
|||
#ifndef _H_LIBCP_COLLECTIONS_HASHMAP
|
||||
#define _H_LIBCP_COLLECTIONS_HASHMAP
|
||||
|
||||
#include "option.hpp"
|
||||
#include <collections/vec.hpp>
|
||||
#include <stdint.h>
|
||||
|
||||
namespace __internal {
|
||||
|
||||
template <typename K, typename V>
|
||||
struct HashMapPart {
|
||||
private:
|
||||
// uint8_t hash[4];
|
||||
K key;
|
||||
V val;
|
||||
|
||||
public:
|
||||
};
|
||||
} // namespace __internal
|
||||
|
||||
template <typename K, typename V>
|
||||
class HashMap {
|
||||
private:
|
||||
Vec<__internal::HashMapPart<K, V>> items;
|
||||
|
||||
public:
|
||||
HashMap() = default;
|
||||
~HashMap() = default;
|
||||
|
||||
Option<V> insert(K& key, V& value) {}
|
||||
|
||||
Option<V> get(K& key) {}
|
||||
};
|
||||
|
||||
#endif // !_H_LIBCP_COLLECTIONS_HASHMAP
|
|
@ -1,10 +1,10 @@
|
|||
#ifndef _H_LIBCP_COLLECTIONS_VEC
|
||||
#define _H_LIBCP_COLLECTIONS_VEC
|
||||
|
||||
#include "result.hpp"
|
||||
#include <result.hpp>
|
||||
#include <option.hpp>
|
||||
#include <stdint.h>
|
||||
#include <stddef.h>
|
||||
#include <stddef.hpp>
|
||||
|
||||
template <typename T>
|
||||
class Vec {
|
||||
|
|
23
src/include/config/platform.hpp
Normal file
23
src/include/config/platform.hpp
Normal file
|
@ -0,0 +1,23 @@
|
|||
#ifndef _H_LIBCP_CONFIG_PLATFORM
|
||||
|
||||
#if defined(__linux__)
|
||||
#define PLATFORM_LINUX
|
||||
#elif defined(__APPLE__) && defined(__MACH__)
|
||||
#define PLATFORM_MACOS
|
||||
#elif defined(__FreeBSD__)
|
||||
#define PLATFORM_FREEBSD
|
||||
#elif defined(__NetBSD__)
|
||||
#define PLATFORM_NETBSD
|
||||
#elif defined(__OpenBSD__)
|
||||
#define PLATFORM_OPENBSD
|
||||
#elif defined(_WIN32)
|
||||
#define PLATFORM_WINDOWS
|
||||
#else
|
||||
#define PLATFORM_UNKNOWN
|
||||
#endif
|
||||
|
||||
#ifdef PLATFORM_UNKNOWN
|
||||
#error This platform is not supported by this library yet
|
||||
#endif // PLATFORM_UNKNOWN
|
||||
|
||||
#endif // !_H_LIBCP_CONFIG_PLATFORM
|
|
@ -18,7 +18,7 @@ concept Format = requires(T t) {
|
|||
|
||||
#ifndef __CONCEPT_ONLY
|
||||
|
||||
namespace __internal {
|
||||
namespace {
|
||||
String format(Vec<String>& args, String& _fmt) {
|
||||
const char* fmt = _fmt.as_cstr();
|
||||
String str = String();
|
||||
|
@ -33,7 +33,9 @@ namespace __internal {
|
|||
}
|
||||
if (fmt[i + 1] == '}') {
|
||||
i += 1;
|
||||
String* arg = args.nth(args_idx).unwrap();
|
||||
if (args.len() <= args_idx) {
|
||||
}
|
||||
String* arg = args.nth(args_idx).expect("Amount of arguments dont match amount of placeholders in format string");
|
||||
str.push_str(*arg);
|
||||
args_idx += 1;
|
||||
}
|
||||
|
@ -54,17 +56,18 @@ namespace __internal {
|
|||
args.push(Formatter<ActualType>::fmt_to_str(var1));
|
||||
}
|
||||
|
||||
return __internal::format(args, fmt, var2...);
|
||||
return format(args, fmt, var2...);
|
||||
}
|
||||
} // namespace __internal
|
||||
} // namespace
|
||||
|
||||
template <typename... Types>
|
||||
String format(const char* fmt, Types... vars) {
|
||||
Vec<String> args = Vec<String>();
|
||||
String fmt_ = String(fmt);
|
||||
return __internal::format(args, fmt_, vars...);
|
||||
return format(args, fmt_, vars...);
|
||||
}
|
||||
|
||||
// Has to be here, cause c++
|
||||
template <Format T>
|
||||
struct Formatter<Vec<T>> {
|
||||
static String fmt_to_str(Vec<T>& val) {
|
||||
|
|
43
src/include/format/obj_fmt_helper.hpp
Normal file
43
src/include/format/obj_fmt_helper.hpp
Normal file
|
@ -0,0 +1,43 @@
|
|||
#ifndef _H_LIBCP_FORMAT_OBJ_FMT_HELPER
|
||||
#define _H_LIBCP_FORMAT_OBJ_FMT_HELPER
|
||||
|
||||
#include <stddef.h>
|
||||
#include <format/fmt.hpp>
|
||||
#include <string.hpp>
|
||||
#include <collections/vec.hpp>
|
||||
|
||||
class ObjFmtHelper {
|
||||
private:
|
||||
String buffer = String();
|
||||
size_t nest_level = 0;
|
||||
|
||||
public:
|
||||
ObjFmtHelper(const char* name) {
|
||||
buffer.push_str(name);
|
||||
buffer.push_str(" {\n");
|
||||
};
|
||||
|
||||
ObjFmtHelper(int level, const char* name) {
|
||||
this->nest_level = level;
|
||||
buffer.push_str(name);
|
||||
buffer.push_str(" {\n");
|
||||
};
|
||||
|
||||
~ObjFmtHelper() = default;
|
||||
|
||||
template <Format T>
|
||||
void add_field(const char* name, T val) {
|
||||
for (size_t i = 0; i < nest_level + 1; i++) {
|
||||
this->buffer.push_str(" ");
|
||||
}
|
||||
auto s = format("{}: {}\n", name, val);
|
||||
this->buffer.push_str(s);
|
||||
}
|
||||
|
||||
String finish() {
|
||||
this->buffer.push_str("}\n");
|
||||
return this->buffer;
|
||||
}
|
||||
};
|
||||
|
||||
#endif // !_H_LIBCP_FORMAT_OBJ_FMT_HELPER
|
17
src/include/hash/hash.hpp
Normal file
17
src/include/hash/hash.hpp
Normal file
|
@ -0,0 +1,17 @@
|
|||
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stl.hpp>
|
||||
#include <sys/types.h>
|
||||
|
||||
#define HASH_SIZE 4
|
||||
|
||||
template <typename T>
|
||||
struct Hasher;
|
||||
|
||||
template <typename T>
|
||||
concept Hash = requires(T t) {
|
||||
{ t.hash() } -> stl::same_as<uint8_t[HASH_SIZE]>;
|
||||
} || requires(T t) {
|
||||
{ Hasher<T>::hash(t) } -> stl::same_as<u_int8_t[HASH_SIZE]>;
|
||||
};
|
|
@ -4,14 +4,16 @@
|
|||
#include <format/fmt.hpp>
|
||||
|
||||
extern "C" {
|
||||
int puts(const char* s);
|
||||
int putchar(int c);
|
||||
}
|
||||
|
||||
template <typename... Types>
|
||||
void print(const char* fmt, Types... args) {
|
||||
String s = format(fmt, args...);
|
||||
puts(s.as_cstr());
|
||||
char* cs = s.as_cstr();
|
||||
for (int i = 0; i < s.len(); i++) {
|
||||
putchar(cs[i]);
|
||||
}
|
||||
}
|
||||
|
||||
template <typename... Types>
|
||||
|
|
60
src/include/logger.hpp
Normal file
60
src/include/logger.hpp
Normal file
|
@ -0,0 +1,60 @@
|
|||
#include "format/fmt.hpp"
|
||||
#ifndef _H_LIBCP_LOGGER
|
||||
|
||||
#include <io/print.hpp>
|
||||
#include <string.hpp>
|
||||
#include <sync/spinlock.hpp>
|
||||
|
||||
namespace log {
|
||||
#define LOG_LEVEL_COUNT 4
|
||||
|
||||
enum LogLevel { LOG_OFF = -1, LOG_ERROR = 0, LOG_WARN, LOG_INFO, LOG_DEBUG };
|
||||
|
||||
class Logger {
|
||||
private:
|
||||
LogLevel filter_level = LOG_INFO;
|
||||
const char* prefixes[LOG_LEVEL_COUNT];
|
||||
|
||||
public:
|
||||
void log(LogLevel level, const char* file, const int line, const char* func, const char* str);
|
||||
void log(LogLevel level, const char* file, const int line, const char* func, String str);
|
||||
|
||||
void set_log_level(LogLevel level);
|
||||
const char* get_prefix(LogLevel level);
|
||||
void load_default_prefixes_with_color();
|
||||
void load_default_prefixes();
|
||||
void load_custom_prefixes(const char* pfx[LOG_LEVEL_COUNT]);
|
||||
|
||||
Logger();
|
||||
~Logger() = default;
|
||||
|
||||
private:
|
||||
bool should_display(LogLevel level);
|
||||
};
|
||||
|
||||
namespace {
|
||||
SpinLock<log::Logger*> LOGGER = SpinLock<log::Logger*>(new log::Logger());
|
||||
}
|
||||
|
||||
template <typename... Args>
|
||||
void debug(const char* fmt, Args... args, const char* file = __builtin_FILE(), int line = __builtin_LINE(), const char* function = __builtin_FUNCTION()) {
|
||||
LOGGER.lock().get()->log(LOG_DEBUG, file, line, function, format(fmt, args...));
|
||||
}
|
||||
|
||||
template <typename... Args>
|
||||
void info(const char* fmt, Args... args, const char* file = __builtin_FILE(), int line = __builtin_LINE(), const char* function = __builtin_FUNCTION()) {
|
||||
LOGGER.lock().get()->log(LOG_INFO, file, line, function, format(fmt, args...));
|
||||
}
|
||||
|
||||
template <typename... Args>
|
||||
void warn(const char* fmt, Args... args, const char* file = __builtin_FILE(), int line = __builtin_LINE(), const char* function = __builtin_FUNCTION()) {
|
||||
LOGGER.lock().get()->log(LOG_WARN, file, line, function, format(fmt, args...));
|
||||
}
|
||||
|
||||
template <typename... Args>
|
||||
void error(const char* fmt, Args... args, const char* file = __builtin_FILE(), int line = __builtin_LINE(), const char* function = __builtin_FUNCTION()) {
|
||||
LOGGER.lock().get()->log(LOG_ERROR, file, line, function, format(fmt, args...));
|
||||
}
|
||||
} // namespace log
|
||||
|
||||
#endif // !_H_LIBCP_LOGGER
|
|
@ -3,6 +3,10 @@
|
|||
#define _H_LIBCP_OPTION
|
||||
#include <stl.hpp>
|
||||
|
||||
extern "C" {
|
||||
int puts(const char* s);
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
class Option {
|
||||
bool has_value = false;
|
||||
|
@ -35,8 +39,19 @@ public:
|
|||
return !has_value;
|
||||
}
|
||||
|
||||
T& expect(const char* str) {
|
||||
if (!has_value) {
|
||||
puts("PANIC: Unwrapped a None Option: ");
|
||||
puts(str);
|
||||
puts("\n");
|
||||
__builtin_trap();
|
||||
}
|
||||
return this->storage;
|
||||
}
|
||||
|
||||
T& unwrap() {
|
||||
if (!has_value) {
|
||||
puts("PANIC: Unwrapped a None Option\n");
|
||||
__builtin_trap();
|
||||
}
|
||||
return this->storage;
|
||||
|
|
|
@ -3,6 +3,10 @@
|
|||
|
||||
#include <stl.hpp>
|
||||
|
||||
extern "C" {
|
||||
int puts(const char* s);
|
||||
};
|
||||
|
||||
template <typename E>
|
||||
struct ResultErrBase {
|
||||
bool is_okay = true;
|
||||
|
@ -80,9 +84,20 @@ public:
|
|||
}
|
||||
}
|
||||
|
||||
T& expect(const char* str) {
|
||||
if (!this->is_ok()) {
|
||||
puts("PANIC: Unwrapped result with error: ");
|
||||
puts(str);
|
||||
puts("\n");
|
||||
__builtin_trap();
|
||||
}
|
||||
return &this->ok_data;
|
||||
}
|
||||
|
||||
T& unwrap() {
|
||||
if (!this->is_ok()) {
|
||||
throw "Unwrapped result with error";
|
||||
puts("PANIC: Unwrapped result with error\n");
|
||||
__builtin_trap();
|
||||
}
|
||||
return &this->ok_data;
|
||||
}
|
||||
|
|
|
@ -2,8 +2,8 @@
|
|||
#ifndef _H_LIBCP
|
||||
#define _H_LIBCP
|
||||
|
||||
#include <stddef.hpp>
|
||||
#include <stdint.h>
|
||||
|
||||
#include <string.hpp>
|
||||
#include <collections/vec.hpp>
|
||||
#include <format/fmt.hpp>
|
||||
|
|
7
src/include/stddef.hpp
Normal file
7
src/include/stddef.hpp
Normal file
|
@ -0,0 +1,7 @@
|
|||
#ifndef _H_LIBCP_STDDEF
|
||||
|
||||
using size_t = decltype(sizeof(int));
|
||||
using ptrdiff_t = decltype(static_cast<int*>(nullptr) - static_cast<int*>(nullptr));
|
||||
using nullptr_t = decltype(nullptr);
|
||||
|
||||
#endif // !_H_LIBCP_STDDEF
|
|
@ -9,6 +9,13 @@ namespace stl {
|
|||
#include <stl/move.hpp>
|
||||
#include <stl/remove_cvref.hpp>
|
||||
#include <stl/remove_reference.hpp>
|
||||
#include <stl/add_lvalue_reference.hpp>
|
||||
#include <stl/add_rvalue_reference.hpp>
|
||||
#include <stl/integer_sequence.hpp>
|
||||
#include <stl/is_constructable.hpp>
|
||||
#include <stl/void_t.hpp>
|
||||
#include <stl/is_referenceable.hpp>
|
||||
#include <stl/is_integral.hpp>
|
||||
} // namespace stl
|
||||
|
||||
#endif // _H_LIBCP_STL
|
35
src/include/stl/add_lvalue_reference.hpp
Normal file
35
src/include/stl/add_lvalue_reference.hpp
Normal file
|
@ -0,0 +1,35 @@
|
|||
#ifndef _H_LIBCP_STL_ADD_LVALUE_REF
|
||||
#define _H_LIBCP_STL_ADD_LVALUE_REF
|
||||
|
||||
#include <stl/is_referenceable.hpp>
|
||||
|
||||
#if __has_builtin(__add_lvalue_reference)
|
||||
|
||||
template <class _Tp>
|
||||
using __add_lvalue_reference_t = __add_lvalue_reference(_Tp);
|
||||
|
||||
#else
|
||||
|
||||
template <class _Tp, bool = __is_referenceable_v<_Tp>>
|
||||
struct __add_lvalue_reference_impl {
|
||||
using type = _Tp;
|
||||
};
|
||||
|
||||
template <class _Tp>
|
||||
struct __add_lvalue_reference_impl<_Tp, true> {
|
||||
using type = _Tp&;
|
||||
};
|
||||
|
||||
template <class _Tp>
|
||||
using __add_lvalue_reference_t = typename __add_lvalue_reference_impl<_Tp>::type;
|
||||
|
||||
#endif // __has_builtin(__add_lvalue_reference)
|
||||
|
||||
template <class _Tp>
|
||||
struct add_lvalue_reference {
|
||||
using type = __add_lvalue_reference_t<_Tp>;
|
||||
};
|
||||
|
||||
template <class _Tp>
|
||||
using add_lvalue_reference_t = __add_lvalue_reference_t<_Tp>;
|
||||
#endif // _H_LIBCP_STL_ADD_LVALUE_REF
|
36
src/include/stl/add_rvalue_reference.hpp
Normal file
36
src/include/stl/add_rvalue_reference.hpp
Normal file
|
@ -0,0 +1,36 @@
|
|||
#ifndef _H_LIBCP_STL_ADD_RVALUE_REF
|
||||
#define _H_LIBCP_STL_ADD_RVALUE_REF
|
||||
|
||||
#include <stl/is_referenceable.hpp>
|
||||
|
||||
#if __has_builtin(__add_rvalue_reference)
|
||||
|
||||
template <class _Tp>
|
||||
using __add_rvalue_reference_t = __add_rvalue_reference(_Tp);
|
||||
|
||||
#else
|
||||
|
||||
template <class _Tp, bool = __is_referenceable_v<_Tp>>
|
||||
struct __add_rvalue_reference_impl {
|
||||
using type = _Tp;
|
||||
};
|
||||
|
||||
template <class _Tp>
|
||||
struct __add_rvalue_reference_impl<_Tp, true> {
|
||||
using type = _Tp&&;
|
||||
};
|
||||
|
||||
template <class _Tp>
|
||||
using __add_rvalue_reference_t = typename __add_rvalue_reference_impl<_Tp>::type;
|
||||
|
||||
#endif // __has_builtin(__add_rvalue_reference)
|
||||
|
||||
template <class _Tp>
|
||||
struct add_rvalue_reference {
|
||||
using type = __add_rvalue_reference_t<_Tp>;
|
||||
};
|
||||
|
||||
template <class _Tp>
|
||||
using add_rvalue_reference_t = __add_rvalue_reference_t<_Tp>;
|
||||
|
||||
#endif // _H_LIBCP_STL_ADD_RVALUE_REF
|
67
src/include/stl/integer_sequence.hpp
Normal file
67
src/include/stl/integer_sequence.hpp
Normal file
|
@ -0,0 +1,67 @@
|
|||
#ifndef _H_LIBCP_STL_INTEGER_SEQUENCE
|
||||
#define _H_LIBCP_STL_INTEGER_SEQUENCE
|
||||
|
||||
#include <stddef.h>
|
||||
#include <stl/is_integral.hpp>
|
||||
template <size_t...>
|
||||
struct __tuple_indices;
|
||||
|
||||
template <class _IdxType, _IdxType... _Values>
|
||||
struct __integer_sequence {
|
||||
template <template <class _OIdxType, _OIdxType...> class _ToIndexSeq, class _ToIndexType>
|
||||
using __convert = _ToIndexSeq<_ToIndexType, _Values...>;
|
||||
|
||||
template <size_t _Sp>
|
||||
using __to_tuple_indices = __tuple_indices<(_Values + _Sp)...>;
|
||||
};
|
||||
|
||||
#if __has_builtin(__make_integer_seq)
|
||||
template <size_t _Ep, size_t _Sp>
|
||||
using __make_indices_imp = typename __make_integer_seq<__integer_sequence, size_t, _Ep - _Sp>::template __to_tuple_indices<_Sp>;
|
||||
#elif __has_builtin(__integer_pack)
|
||||
template <size_t _Ep, size_t _Sp>
|
||||
using __make_indices_imp = typename __integer_sequence<size_t, __integer_pack(_Ep - _Sp)...>::template __to_tuple_indices<_Sp>;
|
||||
#else
|
||||
#error "No known way to get an integer pack from the compiler"
|
||||
#endif
|
||||
|
||||
template <class _Tp, _Tp... _Ip>
|
||||
struct integer_sequence {
|
||||
typedef _Tp value_type;
|
||||
static_assert(is_integral<_Tp>::value, "std::integer_sequence can only be instantiated with an integral type");
|
||||
|
||||
static constexpr size_t size() noexcept {
|
||||
return sizeof...(_Ip);
|
||||
}
|
||||
};
|
||||
|
||||
template <size_t... _Ip>
|
||||
using index_sequence = integer_sequence<size_t, _Ip...>;
|
||||
|
||||
#if __has_builtin(__make_integer_seq)
|
||||
|
||||
template <class _Tp, _Tp _Ep>
|
||||
using make_integer_sequence = __make_integer_seq<integer_sequence, _Tp, _Ep>;
|
||||
|
||||
#elif __has_builtin(__integer_pack)
|
||||
|
||||
template <class _Tp, _Tp _SequenceSize>
|
||||
using make_integer_sequence = integer_sequence<_Tp, __integer_pack(_SequenceSize)...>;
|
||||
|
||||
#else
|
||||
#error "No known way to get an integer pack from the compiler"
|
||||
#endif
|
||||
|
||||
template <size_t _Np>
|
||||
using make_index_sequence = make_integer_sequence<size_t, _Np>;
|
||||
|
||||
template <class... _Tp>
|
||||
using index_sequence_for = make_index_sequence<sizeof...(_Tp)>;
|
||||
|
||||
// Executes __func for every element in an index_sequence.
|
||||
template <size_t... _Index, class _Function>
|
||||
constexpr void __for_each_index_sequence(index_sequence<_Index...>, _Function __func) {
|
||||
(__func.template operator()<_Index>(), ...);
|
||||
}
|
||||
|
||||
#endif // _H_LIBCP_STL_INTEGER_SEQUENCE
|
32
src/include/stl/is_constructable.hpp
Normal file
32
src/include/stl/is_constructable.hpp
Normal file
|
@ -0,0 +1,32 @@
|
|||
#ifndef _H_LIBCP_STL_IS_COPY_CONSTRUCTABLE
|
||||
#define _H_LIBCP_STL_IS_COPY_CONSTRUCTABLE
|
||||
|
||||
#include <stl/integral_constant.hpp>
|
||||
#include <stl/add_lvalue_reference.hpp>
|
||||
#include <stl/add_rvalue_reference.hpp>
|
||||
|
||||
template <class _Tp, class... _Args>
|
||||
struct is_constructible : integral_constant<bool, __is_constructible(_Tp, _Args...)> {};
|
||||
|
||||
template <class _Tp, class... _Args>
|
||||
inline constexpr bool is_constructible_v = __is_constructible(_Tp, _Args...);
|
||||
|
||||
template <class _Tp>
|
||||
struct is_copy_constructible : integral_constant<bool, __is_constructible(_Tp, __add_lvalue_reference_t<const _Tp>)> {};
|
||||
|
||||
template <class _Tp>
|
||||
inline constexpr bool is_copy_constructible_v = is_copy_constructible<_Tp>::value;
|
||||
|
||||
template <class _Tp>
|
||||
struct is_move_constructible : integral_constant<bool, __is_constructible(_Tp, __add_rvalue_reference_t<_Tp>)> {};
|
||||
|
||||
template <class _Tp>
|
||||
inline constexpr bool is_move_constructible_v = is_move_constructible<_Tp>::value;
|
||||
|
||||
template <class _Tp>
|
||||
struct is_default_constructible : integral_constant<bool, __is_constructible(_Tp)> {};
|
||||
|
||||
template <class _Tp>
|
||||
inline constexpr bool is_default_constructible_v = __is_constructible(_Tp);
|
||||
|
||||
#endif // _H_LIBCP_STL_IS_COPY_CONSTRUCTABLE
|
53
src/include/stl/is_integral.hpp
Normal file
53
src/include/stl/is_integral.hpp
Normal file
|
@ -0,0 +1,53 @@
|
|||
#ifndef _H_LIBCP_STL_IS_INTEGRAL
|
||||
#define _H_LIBCP_STL_IS_INTEGRAL
|
||||
|
||||
#include <stl/integral_constant.hpp>
|
||||
#include <stl/remove_cvref.hpp>
|
||||
|
||||
// clang-format off
|
||||
template <class _Tp> struct __libcpp_is_integral { enum { value = 0 }; };
|
||||
template <> struct __libcpp_is_integral<bool> { enum { value = 1 }; };
|
||||
template <> struct __libcpp_is_integral<char> { enum { value = 1 }; };
|
||||
template <> struct __libcpp_is_integral<signed char> { enum { value = 1 }; };
|
||||
template <> struct __libcpp_is_integral<unsigned char> { enum { value = 1 }; };
|
||||
#if _LIBCPP_HAS_WIDE_CHARACTERS
|
||||
template <> struct __libcpp_is_integral<wchar_t> { enum { value = 1 }; };
|
||||
#endif
|
||||
#if _LIBCPP_HAS_CHAR8_T
|
||||
template <> struct __libcpp_is_integral<char8_t> { enum { value = 1 }; };
|
||||
#endif
|
||||
template <> struct __libcpp_is_integral<char16_t> { enum { value = 1 }; };
|
||||
template <> struct __libcpp_is_integral<char32_t> { enum { value = 1 }; };
|
||||
template <> struct __libcpp_is_integral<short> { enum { value = 1 }; };
|
||||
template <> struct __libcpp_is_integral<unsigned short> { enum { value = 1 }; };
|
||||
template <> struct __libcpp_is_integral<int> { enum { value = 1 }; };
|
||||
template <> struct __libcpp_is_integral<unsigned int> { enum { value = 1 }; };
|
||||
template <> struct __libcpp_is_integral<long> { enum { value = 1 }; };
|
||||
template <> struct __libcpp_is_integral<unsigned long> { enum { value = 1 }; };
|
||||
template <> struct __libcpp_is_integral<long long> { enum { value = 1 }; };
|
||||
template <> struct __libcpp_is_integral<unsigned long long> { enum { value = 1 }; };
|
||||
#if _LIBCPP_HAS_INT128
|
||||
template <> struct __libcpp_is_integral<__int128_t> { enum { value = 1 }; };
|
||||
template <> struct __libcpp_is_integral<__uint128_t> { enum { value = 1 }; };
|
||||
#endif
|
||||
// clang-format on
|
||||
|
||||
#if __has_builtin(__is_integral)
|
||||
|
||||
template <class _Tp>
|
||||
struct is_integral : _BoolConstant<__is_integral(_Tp)> {};
|
||||
|
||||
template <class _Tp>
|
||||
inline constexpr bool is_integral_v = __is_integral(_Tp);
|
||||
|
||||
#else
|
||||
|
||||
template <class _Tp>
|
||||
struct is_integral : public _BoolConstant<__libcpp_is_integral<__remove_cvref_t<_Tp>>::value> {};
|
||||
|
||||
template <class _Tp>
|
||||
inline constexpr bool is_integral_v = is_integral<_Tp>::value;
|
||||
|
||||
#endif // __has_builtin(__is_integral)
|
||||
|
||||
#endif // !_H_LIBCP_STL_IS_INTEGRAL
|
15
src/include/stl/is_referenceable.hpp
Normal file
15
src/include/stl/is_referenceable.hpp
Normal file
|
@ -0,0 +1,15 @@
|
|||
#ifndef _H_LIBCP_STL_IS_REFERENCEABLE
|
||||
#define _H_LIBCP_STL_IS_REFERENCEABLE
|
||||
|
||||
#include <stl/void_t.hpp>
|
||||
|
||||
template <class _Tp, class = void>
|
||||
inline const bool __is_referenceable_v = false;
|
||||
|
||||
template <class _Tp>
|
||||
inline const bool __is_referenceable_v<_Tp, __void_t<_Tp&>> = true;
|
||||
|
||||
template <class _Tp>
|
||||
concept __referenceable = __is_referenceable_v<_Tp>;
|
||||
|
||||
#endif // !_H_LIBCP_STL_IS_REFERENCEABLE
|
10
src/include/stl/void_t.hpp
Normal file
10
src/include/stl/void_t.hpp
Normal file
|
@ -0,0 +1,10 @@
|
|||
#ifndef _H_LIBCP_STL_VOID_T
|
||||
#define _H_LIBCP_STL_VOID_T
|
||||
|
||||
template <class...>
|
||||
using void_t = void;
|
||||
|
||||
template <class...>
|
||||
using __void_t = void;
|
||||
|
||||
#endif // !_H_LIBCP_STL_VOID_T
|
77
src/include/sync/mutex.hpp
Normal file
77
src/include/sync/mutex.hpp
Normal file
|
@ -0,0 +1,77 @@
|
|||
#ifndef _H_LIBCP_SYNC_MUTEX
|
||||
#define _H_LIBCP_SYNC_MUTEX
|
||||
#include <config/platform.hpp>
|
||||
|
||||
#ifdef PLATFORM_LINUX
|
||||
#include <linux/futex.h>
|
||||
#include <sys/syscall.h>
|
||||
#endif
|
||||
#include <unistd.h>
|
||||
|
||||
template <typename T>
|
||||
struct Mutex {
|
||||
private:
|
||||
int locked = 0;
|
||||
T value;
|
||||
|
||||
Mutex() = default;
|
||||
|
||||
void acquire() {
|
||||
#ifdef PLATFORM_LINUX
|
||||
int expected = 0;
|
||||
if (!__atomic_compare_exchange_n(&this->locked, &expected, 1, false, __ATOMIC_ACQUIRE, __ATOMIC_RELAXED)) {
|
||||
// someone else already locked it, wait
|
||||
while (__atomic_exchange_n(&this->locked, 2, __ATOMIC_ACQUIRE) != 0) {
|
||||
syscall(SYS_futex, &this->locked, FUTEX_WAIT, 2, nullptr, nullptr, 0);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
void release() {
|
||||
#ifdef PLATFORM_LINUX
|
||||
if (__atomic_exchange_n(&this->locked, 0, __ATOMIC_RELEASE) == 2) {
|
||||
syscall(SYS_futex, &this->locked, FUTEX_WAKE, 1, nullptr, nullptr, 0);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
struct MutexGuard {
|
||||
private:
|
||||
Mutex<T>* parent;
|
||||
|
||||
public:
|
||||
MutexGuard(Mutex<T>* p) : parent(p) {
|
||||
parent->acquire();
|
||||
}
|
||||
|
||||
~MutexGuard() {
|
||||
parent->release();
|
||||
}
|
||||
|
||||
T& get() {
|
||||
return parent->value;
|
||||
}
|
||||
|
||||
T* operator->() {
|
||||
return &parent->value;
|
||||
}
|
||||
|
||||
T& operator*() {
|
||||
return parent->value;
|
||||
}
|
||||
|
||||
MutexGuard(const MutexGuard&) = delete;
|
||||
MutexGuard& operator=(const MutexGuard&) = delete;
|
||||
};
|
||||
|
||||
public:
|
||||
template <typename... Args>
|
||||
explicit Mutex(Args&&... args) : value((Args&&)args...) {}
|
||||
|
||||
MutexGuard lock() {
|
||||
return MutexGuard(this);
|
||||
}
|
||||
};
|
||||
|
||||
#endif // !_H_LIBCP_SYNC_MUTEX
|
64
src/include/sync/spinlock.hpp
Normal file
64
src/include/sync/spinlock.hpp
Normal file
|
@ -0,0 +1,64 @@
|
|||
#ifndef _H_LIBCP_SYNC_SPINLOCK
|
||||
#define _H_LIBCP_SYNC_SPINLOCK
|
||||
#include <io/print.hpp>
|
||||
#include <stdatomic.h>
|
||||
|
||||
template <typename T>
|
||||
struct SpinLock {
|
||||
private:
|
||||
volatile atomic_bool locked = ATOMIC_BOOL_LOCK_FREE;
|
||||
T value;
|
||||
|
||||
SpinLock() = default;
|
||||
|
||||
void acquire() {
|
||||
while (atomic_load_explicit(&locked, memory_order_acquire) == true) {
|
||||
// println("Locked");
|
||||
}
|
||||
}
|
||||
|
||||
void release() {
|
||||
atomic_store_explicit(&locked, false, memory_order_release);
|
||||
}
|
||||
|
||||
struct SpinGuard {
|
||||
private:
|
||||
SpinLock<T>* parent;
|
||||
|
||||
public:
|
||||
SpinGuard(SpinLock<T>* p) : parent(p) {
|
||||
parent->acquire();
|
||||
}
|
||||
|
||||
~SpinGuard() {
|
||||
parent->release();
|
||||
}
|
||||
|
||||
T& get() {
|
||||
return parent->value;
|
||||
}
|
||||
|
||||
T* operator->() {
|
||||
return &parent->value;
|
||||
}
|
||||
|
||||
T& operator*() {
|
||||
return parent->value;
|
||||
}
|
||||
|
||||
SpinGuard(const SpinGuard&) = delete;
|
||||
SpinGuard& operator=(const SpinGuard&) = delete;
|
||||
};
|
||||
|
||||
public:
|
||||
template <typename... Args>
|
||||
explicit SpinLock(Args&&... args) : value((Args&&)args...) {
|
||||
atomic_store_explicit(&locked, false, memory_order_release);
|
||||
}
|
||||
|
||||
SpinGuard lock() {
|
||||
return SpinGuard(this);
|
||||
}
|
||||
};
|
||||
|
||||
#endif // !_H_LIBCP_SYNC_SPINLOCK
|
0
src/include/thirdparty/field_reflection.hpp
vendored
Normal file
0
src/include/thirdparty/field_reflection.hpp
vendored
Normal file
701
src/include/thirdparty/field_reflection_std.hpp
vendored
Normal file
701
src/include/thirdparty/field_reflection_std.hpp
vendored
Normal file
|
@ -0,0 +1,701 @@
|
|||
/*===================================================*
|
||||
| field-reflection version v0.2.1 |
|
||||
| https://github.com/yosh-matsuda/field-reflection |
|
||||
| |
|
||||
| Copyright (c) 2024 Yoshiki Matsuda @yosh-matsuda |
|
||||
| |
|
||||
| This software is released under the MIT License. |
|
||||
| https://opensource.org/license/mit/ |
|
||||
====================================================*/
|
||||
|
||||
// Heavily modified by MCorange <mcorange@mcorangehq.xyz>
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <stl.hpp>
|
||||
#include <stddef.h>
|
||||
|
||||
namespace field_reflection {
|
||||
namespace detail {
|
||||
|
||||
#if defined(__GNUC__) || defined(__clang__)
|
||||
#pragma GCC diagnostic push
|
||||
#pragma GCC diagnostic ignored "-Wundefined-inline"
|
||||
#endif
|
||||
template <typename T, size_t = 0>
|
||||
struct any_lref {
|
||||
template <typename U>
|
||||
requires(!stl::same_as<U, T>)
|
||||
constexpr operator U&() const&& noexcept; // NOLINT
|
||||
template <typename U>
|
||||
requires(!stl::same_as<U, T>)
|
||||
constexpr operator U&() const& noexcept; // NOLINT
|
||||
};
|
||||
|
||||
template <typename T, size_t = 0>
|
||||
struct any_rref {
|
||||
template <typename U>
|
||||
requires(!stl::same_as<U, T>)
|
||||
constexpr operator U() const&& noexcept; // NOLINT
|
||||
};
|
||||
|
||||
template <typename T, size_t = 0>
|
||||
struct any_lref_no_base {
|
||||
template <typename U>
|
||||
requires(!stl::is_base_of_v<U, T> && !stl::same_as<U, T>)
|
||||
constexpr operator U&() const&& noexcept; // NOLINT
|
||||
template <typename U>
|
||||
requires(!stl::is_base_of_v<U, T> && !stl::same_as<U, T>)
|
||||
constexpr operator U&() const& noexcept; // NOLINT
|
||||
};
|
||||
|
||||
template <typename T, size_t = 0>
|
||||
struct any_rref_no_base {
|
||||
template <typename U>
|
||||
requires(!stl::is_base_of_v<U, T> && !stl::same_as<U, T>)
|
||||
constexpr operator U() const&& noexcept; // NOLINT
|
||||
};
|
||||
|
||||
template <typename T, size_t = 0>
|
||||
struct any_lref_base {
|
||||
template <typename U>
|
||||
requires stl::is_base_of_v<U, T>
|
||||
constexpr operator U&() const&& noexcept; // NOLINT
|
||||
template <typename U>
|
||||
requires stl::is_base_of_v<U, T>
|
||||
constexpr operator U&() const& noexcept; // NOLINT
|
||||
};
|
||||
|
||||
template <typename T, size_t = 0>
|
||||
struct any_rref_base {
|
||||
template <typename U>
|
||||
requires stl::is_base_of_v<U, T>
|
||||
constexpr operator U() const&& noexcept; // NOLINT
|
||||
};
|
||||
#if defined(__GNUC__) || defined(__clang__)
|
||||
#pragma GCC diagnostic pop
|
||||
#endif
|
||||
|
||||
template <typename T, size_t ArgNum>
|
||||
concept constructible = (ArgNum == 0 && requires { T{}; }) || []<size_t I0, size_t... Is>(stl::index_sequence<I0, Is...>) {
|
||||
if constexpr (stl::is_copy_constructible_v<T>) {
|
||||
return requires { T{any_lref_no_base<T, I0>(), any_lref<T, Is>()...}; };
|
||||
} else {
|
||||
return requires { T{any_rref_no_base<T, I0>(), any_rref<T, Is>()...}; };
|
||||
}
|
||||
}(stl::make_index_sequence<ArgNum>());
|
||||
|
||||
template <typename T>
|
||||
concept has_base = []() {
|
||||
if constexpr (stl::is_copy_constructible_v<T>) {
|
||||
return requires { T{stl::declval<any_lref_base<T>>()}; };
|
||||
} else {
|
||||
return requires { T{stl::declval<any_rref_base<T>>()}; };
|
||||
}
|
||||
}();
|
||||
|
||||
constexpr size_t macro_max_fields_count = 100;
|
||||
template <typename T>
|
||||
constexpr auto max_field_count = stl::min(size_t{macro_max_fields_count}, sizeof(T) * CHAR_BIT); // in consideration of bit field
|
||||
|
||||
template <typename T, size_t N>
|
||||
requires stl::is_aggregate_v<T>
|
||||
constexpr size_t field_count_impl = []() {
|
||||
if constexpr (N >= max_field_count<T>) {
|
||||
return stl::numeric_limits<size_t>::max();
|
||||
} else if constexpr (constructible<T, N> && !constructible<T, N + 1>) {
|
||||
return N;
|
||||
} else {
|
||||
return field_count_impl<T, N + 1>;
|
||||
}
|
||||
}();
|
||||
|
||||
template <typename T>
|
||||
requires stl::is_aggregate_v<T>
|
||||
constexpr size_t field_count_value = field_count_impl<T, 0>;
|
||||
|
||||
template <typename T>
|
||||
concept field_countable = stl::is_aggregate_v<T> && requires { requires field_count_value<T> <= max_field_count<T>; };
|
||||
|
||||
template <field_countable T>
|
||||
constexpr size_t field_count = field_count_value<T>;
|
||||
|
||||
template <typename T>
|
||||
concept field_referenceable = field_countable<T> && (!has_base<T>);
|
||||
|
||||
template <typename T, field_referenceable U = stl::remove_cvref_t<T>>
|
||||
constexpr auto to_ptr_tuple(T&&) {
|
||||
static_assert([] { return false; }(), "The supported maximum number of fields in struct must be <= 100.");
|
||||
}
|
||||
|
||||
template <typename T, field_referenceable U = stl::remove_cvref_t<T>>
|
||||
requires(field_count<U> == 0)
|
||||
constexpr auto to_ptr_tuple(T&&) {
|
||||
return stl::tie();
|
||||
}
|
||||
|
||||
template <typename T, field_referenceable U = stl::remove_cvref_t<T>>
|
||||
requires(field_count<U> == 0)
|
||||
constexpr auto to_tuple(T&&) {
|
||||
return stl::tie();
|
||||
}
|
||||
|
||||
#pragma region TO_TUPLE_TEMPLATE_MACRO
|
||||
// map macro: https://github.com/swansontec/map-macro
|
||||
#define FIELD_RFL_EVAL0(...) __VA_ARGS__
|
||||
#define FIELD_RFL_EVAL1(...) FIELD_RFL_EVAL0(FIELD_RFL_EVAL0(FIELD_RFL_EVAL0(__VA_ARGS__)))
|
||||
#define FIELD_RFL_EVAL2(...) FIELD_RFL_EVAL1(FIELD_RFL_EVAL1(FIELD_RFL_EVAL1(__VA_ARGS__)))
|
||||
#define FIELD_RFL_EVAL3(...) FIELD_RFL_EVAL2(FIELD_RFL_EVAL2(FIELD_RFL_EVAL2(__VA_ARGS__)))
|
||||
#define FIELD_RFL_EVAL4(...) FIELD_RFL_EVAL3(FIELD_RFL_EVAL3(FIELD_RFL_EVAL3(__VA_ARGS__)))
|
||||
#define FIELD_RFL_EVAL(...) FIELD_RFL_EVAL4(FIELD_RFL_EVAL4(FIELD_RFL_EVAL4(__VA_ARGS__)))
|
||||
|
||||
#define FIELD_RFL_MAP_END(...)
|
||||
#define FIELD_RFL_MAP_OUT
|
||||
#define FIELD_RFL_MAP_COMMA ,
|
||||
|
||||
#define FIELD_RFL_MAP_GET_END2() 0, FIELD_RFL_MAP_END
|
||||
#define FIELD_RFL_MAP_GET_END1(...) FIELD_RFL_MAP_GET_END2
|
||||
#define FIELD_RFL_MAP_GET_END(...) FIELD_RFL_MAP_GET_END1
|
||||
#define FIELD_RFL_MAP_NEXT0(test, next, ...) next FIELD_RFL_MAP_OUT
|
||||
#define FIELD_RFL_MAP_NEXT1(test, next) FIELD_RFL_MAP_NEXT0(test, next, 0)
|
||||
#define FIELD_RFL_MAP_NEXT(test, next) FIELD_RFL_MAP_NEXT1(FIELD_RFL_MAP_GET_END test, next)
|
||||
|
||||
#define FIELD_RFL_MAP0(f, x, peek, ...) f(x) FIELD_RFL_MAP_NEXT(peek, FIELD_RFL_MAP1)(f, peek, __VA_ARGS__)
|
||||
#define FIELD_RFL_MAP1(f, x, peek, ...) f(x) FIELD_RFL_MAP_NEXT(peek, FIELD_RFL_MAP0)(f, peek, __VA_ARGS__)
|
||||
|
||||
#define FIELD_RFL_MAP_LIST_NEXT1(test, next) FIELD_RFL_MAP_NEXT0(test, FIELD_RFL_MAP_COMMA next, 0)
|
||||
#define FIELD_RFL_MAP_LIST_NEXT(test, next) FIELD_RFL_MAP_LIST_NEXT1(FIELD_RFL_MAP_GET_END test, next)
|
||||
|
||||
#define FIELD_RFL_MAP_LIST0(f, x, peek, ...) f(x) FIELD_RFL_MAP_LIST_NEXT(peek, FIELD_RFL_MAP_LIST1)(f, peek, __VA_ARGS__)
|
||||
#define FIELD_RFL_MAP_LIST1(f, x, peek, ...) f(x) FIELD_RFL_MAP_LIST_NEXT(peek, FIELD_RFL_MAP_LIST0)(f, peek, __VA_ARGS__)
|
||||
#define FIELD_RFL_MAP(f, ...) FIELD_RFL_EVAL(FIELD_RFL_MAP1(f, __VA_ARGS__, ()()(), ()()(), ()()(), 0))
|
||||
#define FIELD_RFL_MAP_LIST(f, ...) FIELD_RFL_EVAL(FIELD_RFL_MAP_LIST1(f, __VA_ARGS__, ()()(), ()()(), ()()(), 0))
|
||||
|
||||
#define FIELD_RFL_ADDR(x) &x
|
||||
#define FIELD_RFL_DECLTYPE(x) decltype(x)
|
||||
#define FIELD_RFL_FORWARD(x) stl::forward<decltype(x)>(x)
|
||||
|
||||
#define TO_TUPLE_TEMPLATE(NUM, ...) \
|
||||
template <typename T, field_referenceable U = stl::remove_cvref_t<T>> \
|
||||
requires(field_count<U> == NUM) \
|
||||
constexpr auto to_ptr_tuple(T&& t) { \
|
||||
auto& [__VA_ARGS__] = t; \
|
||||
return stl::tuple(FIELD_RFL_MAP_LIST(FIELD_RFL_ADDR, __VA_ARGS__)); \
|
||||
} \
|
||||
template <typename T, field_referenceable U = stl::remove_cvref_t<T>> \
|
||||
requires(field_count<U> == NUM) \
|
||||
constexpr auto to_tuple(T&& t) { \
|
||||
auto [__VA_ARGS__] = stl::forward<T>(t); \
|
||||
return stl::tuple<FIELD_RFL_MAP_LIST(FIELD_RFL_DECLTYPE, __VA_ARGS__)>(FIELD_RFL_MAP_LIST(FIELD_RFL_FORWARD, __VA_ARGS__)); \
|
||||
}
|
||||
|
||||
TO_TUPLE_TEMPLATE(1, p0)
|
||||
TO_TUPLE_TEMPLATE(2, p0, p1)
|
||||
TO_TUPLE_TEMPLATE(3, p0, p1, p2)
|
||||
TO_TUPLE_TEMPLATE(4, p0, p1, p2, p3)
|
||||
TO_TUPLE_TEMPLATE(5, p0, p1, p2, p3, p4)
|
||||
TO_TUPLE_TEMPLATE(6, p0, p1, p2, p3, p4, p5)
|
||||
TO_TUPLE_TEMPLATE(7, p0, p1, p2, p3, p4, p5, p6)
|
||||
TO_TUPLE_TEMPLATE(8, p0, p1, p2, p3, p4, p5, p6, p7)
|
||||
TO_TUPLE_TEMPLATE(9, p0, p1, p2, p3, p4, p5, p6, p7, p8)
|
||||
TO_TUPLE_TEMPLATE(10, p0, p1, p2, p3, p4, p5, p6, p7, p8, p9)
|
||||
TO_TUPLE_TEMPLATE(11, p0, p1, p2, p3, p4, p5, p6, p7, p8, p9, p10)
|
||||
TO_TUPLE_TEMPLATE(12, p0, p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11)
|
||||
TO_TUPLE_TEMPLATE(13, p0, p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12)
|
||||
TO_TUPLE_TEMPLATE(14, p0, p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13)
|
||||
TO_TUPLE_TEMPLATE(15, p0, p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13, p14)
|
||||
TO_TUPLE_TEMPLATE(16, p0, p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13, p14, p15)
|
||||
TO_TUPLE_TEMPLATE(17, p0, p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13, p14, p15, p16)
|
||||
TO_TUPLE_TEMPLATE(18, p0, p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13, p14, p15, p16, p17)
|
||||
TO_TUPLE_TEMPLATE(19, p0, p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13, p14, p15, p16, p17, p18)
|
||||
TO_TUPLE_TEMPLATE(20, p0, p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13, p14, p15, p16, p17, p18, p19)
|
||||
TO_TUPLE_TEMPLATE(21, p0, p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13, p14, p15, p16, p17, p18, p19, p20)
|
||||
TO_TUPLE_TEMPLATE(22, p0, p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13, p14, p15, p16, p17, p18, p19, p20, p21)
|
||||
TO_TUPLE_TEMPLATE(23, p0, p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13, p14, p15, p16, p17, p18, p19, p20, p21, p22)
|
||||
TO_TUPLE_TEMPLATE(24, p0, p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13, p14, p15, p16, p17, p18, p19, p20, p21, p22, p23)
|
||||
TO_TUPLE_TEMPLATE(25, p0, p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13, p14, p15, p16, p17, p18, p19, p20, p21, p22, p23, p24)
|
||||
TO_TUPLE_TEMPLATE(26, p0, p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13, p14, p15, p16, p17, p18, p19, p20, p21, p22, p23, p24, p25)
|
||||
TO_TUPLE_TEMPLATE(27, p0, p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13, p14, p15, p16, p17, p18, p19, p20, p21, p22, p23, p24, p25, p26)
|
||||
TO_TUPLE_TEMPLATE(28, p0, p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13, p14, p15, p16, p17, p18, p19, p20, p21, p22, p23, p24, p25, p26, p27)
|
||||
TO_TUPLE_TEMPLATE(29, p0, p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13, p14, p15, p16, p17, p18, p19, p20, p21, p22, p23, p24, p25, p26, p27,
|
||||
p28)
|
||||
TO_TUPLE_TEMPLATE(30, p0, p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13, p14, p15, p16, p17, p18, p19, p20, p21, p22, p23, p24, p25, p26, p27,
|
||||
p28, p29)
|
||||
TO_TUPLE_TEMPLATE(31, p0, p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13, p14, p15, p16, p17, p18, p19, p20, p21, p22, p23, p24, p25, p26, p27,
|
||||
p28, p29, p30)
|
||||
TO_TUPLE_TEMPLATE(32, p0, p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13, p14, p15, p16, p17, p18, p19, p20, p21, p22, p23, p24, p25, p26, p27,
|
||||
p28, p29, p30, p31)
|
||||
TO_TUPLE_TEMPLATE(33, p0, p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13, p14, p15, p16, p17, p18, p19, p20, p21, p22, p23, p24, p25, p26, p27,
|
||||
p28, p29, p30, p31, p32)
|
||||
TO_TUPLE_TEMPLATE(34, p0, p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13, p14, p15, p16, p17, p18, p19, p20, p21, p22, p23, p24, p25, p26, p27,
|
||||
p28, p29, p30, p31, p32, p33)
|
||||
TO_TUPLE_TEMPLATE(35, p0, p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13, p14, p15, p16, p17, p18, p19, p20, p21, p22, p23, p24, p25, p26, p27,
|
||||
p28, p29, p30, p31, p32, p33, p34)
|
||||
TO_TUPLE_TEMPLATE(36, p0, p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13, p14, p15, p16, p17, p18, p19, p20, p21, p22, p23, p24, p25, p26, p27,
|
||||
p28, p29, p30, p31, p32, p33, p34, p35)
|
||||
TO_TUPLE_TEMPLATE(37, p0, p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13, p14, p15, p16, p17, p18, p19, p20, p21, p22, p23, p24, p25, p26, p27,
|
||||
p28, p29, p30, p31, p32, p33, p34, p35, p36)
|
||||
TO_TUPLE_TEMPLATE(38, p0, p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13, p14, p15, p16, p17, p18, p19, p20, p21, p22, p23, p24, p25, p26, p27,
|
||||
p28, p29, p30, p31, p32, p33, p34, p35, p36, p37)
|
||||
TO_TUPLE_TEMPLATE(39, p0, p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13, p14, p15, p16, p17, p18, p19, p20, p21, p22, p23, p24, p25, p26, p27,
|
||||
p28, p29, p30, p31, p32, p33, p34, p35, p36, p37, p38)
|
||||
TO_TUPLE_TEMPLATE(40, p0, p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13, p14, p15, p16, p17, p18, p19, p20, p21, p22, p23, p24, p25, p26, p27,
|
||||
p28, p29, p30, p31, p32, p33, p34, p35, p36, p37, p38, p39)
|
||||
TO_TUPLE_TEMPLATE(41, p0, p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13, p14, p15, p16, p17, p18, p19, p20, p21, p22, p23, p24, p25, p26, p27,
|
||||
p28, p29, p30, p31, p32, p33, p34, p35, p36, p37, p38, p39, p40)
|
||||
TO_TUPLE_TEMPLATE(42, p0, p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13, p14, p15, p16, p17, p18, p19, p20, p21, p22, p23, p24, p25, p26, p27,
|
||||
p28, p29, p30, p31, p32, p33, p34, p35, p36, p37, p38, p39, p40, p41)
|
||||
TO_TUPLE_TEMPLATE(43, p0, p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13, p14, p15, p16, p17, p18, p19, p20, p21, p22, p23, p24, p25, p26, p27,
|
||||
p28, p29, p30, p31, p32, p33, p34, p35, p36, p37, p38, p39, p40, p41, p42)
|
||||
TO_TUPLE_TEMPLATE(44, p0, p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13, p14, p15, p16, p17, p18, p19, p20, p21, p22, p23, p24, p25, p26, p27,
|
||||
p28, p29, p30, p31, p32, p33, p34, p35, p36, p37, p38, p39, p40, p41, p42, p43)
|
||||
TO_TUPLE_TEMPLATE(45, p0, p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13, p14, p15, p16, p17, p18, p19, p20, p21, p22, p23, p24, p25, p26, p27,
|
||||
p28, p29, p30, p31, p32, p33, p34, p35, p36, p37, p38, p39, p40, p41, p42, p43, p44)
|
||||
TO_TUPLE_TEMPLATE(46, p0, p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13, p14, p15, p16, p17, p18, p19, p20, p21, p22, p23, p24, p25, p26, p27,
|
||||
p28, p29, p30, p31, p32, p33, p34, p35, p36, p37, p38, p39, p40, p41, p42, p43, p44, p45)
|
||||
TO_TUPLE_TEMPLATE(47, p0, p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13, p14, p15, p16, p17, p18, p19, p20, p21, p22, p23, p24, p25, p26, p27,
|
||||
p28, p29, p30, p31, p32, p33, p34, p35, p36, p37, p38, p39, p40, p41, p42, p43, p44, p45, p46)
|
||||
TO_TUPLE_TEMPLATE(48, p0, p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13, p14, p15, p16, p17, p18, p19, p20, p21, p22, p23, p24, p25, p26, p27,
|
||||
p28, p29, p30, p31, p32, p33, p34, p35, p36, p37, p38, p39, p40, p41, p42, p43, p44, p45, p46, p47)
|
||||
TO_TUPLE_TEMPLATE(49, p0, p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13, p14, p15, p16, p17, p18, p19, p20, p21, p22, p23, p24, p25, p26, p27,
|
||||
p28, p29, p30, p31, p32, p33, p34, p35, p36, p37, p38, p39, p40, p41, p42, p43, p44, p45, p46, p47, p48)
|
||||
TO_TUPLE_TEMPLATE(50, p0, p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13, p14, p15, p16, p17, p18, p19, p20, p21, p22, p23, p24, p25, p26, p27,
|
||||
p28, p29, p30, p31, p32, p33, p34, p35, p36, p37, p38, p39, p40, p41, p42, p43, p44, p45, p46, p47, p48, p49)
|
||||
TO_TUPLE_TEMPLATE(51, p0, p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13, p14, p15, p16, p17, p18, p19, p20, p21, p22, p23, p24, p25, p26, p27,
|
||||
p28, p29, p30, p31, p32, p33, p34, p35, p36, p37, p38, p39, p40, p41, p42, p43, p44, p45, p46, p47, p48, p49, p50)
|
||||
TO_TUPLE_TEMPLATE(52, p0, p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13, p14, p15, p16, p17, p18, p19, p20, p21, p22, p23, p24, p25, p26, p27,
|
||||
p28, p29, p30, p31, p32, p33, p34, p35, p36, p37, p38, p39, p40, p41, p42, p43, p44, p45, p46, p47, p48, p49, p50, p51)
|
||||
TO_TUPLE_TEMPLATE(53, p0, p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13, p14, p15, p16, p17, p18, p19, p20, p21, p22, p23, p24, p25, p26, p27,
|
||||
p28, p29, p30, p31, p32, p33, p34, p35, p36, p37, p38, p39, p40, p41, p42, p43, p44, p45, p46, p47, p48, p49, p50, p51, p52)
|
||||
TO_TUPLE_TEMPLATE(54, p0, p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13, p14, p15, p16, p17, p18, p19, p20, p21, p22, p23, p24, p25, p26, p27,
|
||||
p28, p29, p30, p31, p32, p33, p34, p35, p36, p37, p38, p39, p40, p41, p42, p43, p44, p45, p46, p47, p48, p49, p50, p51, p52, p53)
|
||||
TO_TUPLE_TEMPLATE(55, p0, p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13, p14, p15, p16, p17, p18, p19, p20, p21, p22, p23, p24, p25, p26, p27,
|
||||
p28, p29, p30, p31, p32, p33, p34, p35, p36, p37, p38, p39, p40, p41, p42, p43, p44, p45, p46, p47, p48, p49, p50, p51, p52, p53, p54)
|
||||
TO_TUPLE_TEMPLATE(56, p0, p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13, p14, p15, p16, p17, p18, p19, p20, p21, p22, p23, p24, p25, p26, p27,
|
||||
p28, p29, p30, p31, p32, p33, p34, p35, p36, p37, p38, p39, p40, p41, p42, p43, p44, p45, p46, p47, p48, p49, p50, p51, p52, p53, p54,
|
||||
p55)
|
||||
TO_TUPLE_TEMPLATE(57, p0, p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13, p14, p15, p16, p17, p18, p19, p20, p21, p22, p23, p24, p25, p26, p27,
|
||||
p28, p29, p30, p31, p32, p33, p34, p35, p36, p37, p38, p39, p40, p41, p42, p43, p44, p45, p46, p47, p48, p49, p50, p51, p52, p53, p54,
|
||||
p55, p56)
|
||||
TO_TUPLE_TEMPLATE(58, p0, p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13, p14, p15, p16, p17, p18, p19, p20, p21, p22, p23, p24, p25, p26, p27,
|
||||
p28, p29, p30, p31, p32, p33, p34, p35, p36, p37, p38, p39, p40, p41, p42, p43, p44, p45, p46, p47, p48, p49, p50, p51, p52, p53, p54,
|
||||
p55, p56, p57)
|
||||
TO_TUPLE_TEMPLATE(59, p0, p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13, p14, p15, p16, p17, p18, p19, p20, p21, p22, p23, p24, p25, p26, p27,
|
||||
p28, p29, p30, p31, p32, p33, p34, p35, p36, p37, p38, p39, p40, p41, p42, p43, p44, p45, p46, p47, p48, p49, p50, p51, p52, p53, p54,
|
||||
p55, p56, p57, p58)
|
||||
TO_TUPLE_TEMPLATE(60, p0, p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13, p14, p15, p16, p17, p18, p19, p20, p21, p22, p23, p24, p25, p26, p27,
|
||||
p28, p29, p30, p31, p32, p33, p34, p35, p36, p37, p38, p39, p40, p41, p42, p43, p44, p45, p46, p47, p48, p49, p50, p51, p52, p53, p54,
|
||||
p55, p56, p57, p58, p59)
|
||||
TO_TUPLE_TEMPLATE(61, p0, p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13, p14, p15, p16, p17, p18, p19, p20, p21, p22, p23, p24, p25, p26, p27,
|
||||
p28, p29, p30, p31, p32, p33, p34, p35, p36, p37, p38, p39, p40, p41, p42, p43, p44, p45, p46, p47, p48, p49, p50, p51, p52, p53, p54,
|
||||
p55, p56, p57, p58, p59, p60)
|
||||
TO_TUPLE_TEMPLATE(62, p0, p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13, p14, p15, p16, p17, p18, p19, p20, p21, p22, p23, p24, p25, p26, p27,
|
||||
p28, p29, p30, p31, p32, p33, p34, p35, p36, p37, p38, p39, p40, p41, p42, p43, p44, p45, p46, p47, p48, p49, p50, p51, p52, p53, p54,
|
||||
p55, p56, p57, p58, p59, p60, p61)
|
||||
TO_TUPLE_TEMPLATE(63, p0, p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13, p14, p15, p16, p17, p18, p19, p20, p21, p22, p23, p24, p25, p26, p27,
|
||||
p28, p29, p30, p31, p32, p33, p34, p35, p36, p37, p38, p39, p40, p41, p42, p43, p44, p45, p46, p47, p48, p49, p50, p51, p52, p53, p54,
|
||||
p55, p56, p57, p58, p59, p60, p61, p62)
|
||||
TO_TUPLE_TEMPLATE(64, p0, p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13, p14, p15, p16, p17, p18, p19, p20, p21, p22, p23, p24, p25, p26, p27,
|
||||
p28, p29, p30, p31, p32, p33, p34, p35, p36, p37, p38, p39, p40, p41, p42, p43, p44, p45, p46, p47, p48, p49, p50, p51, p52, p53, p54,
|
||||
p55, p56, p57, p58, p59, p60, p61, p62, p63)
|
||||
TO_TUPLE_TEMPLATE(65, p0, p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13, p14, p15, p16, p17, p18, p19, p20, p21, p22, p23, p24, p25, p26, p27,
|
||||
p28, p29, p30, p31, p32, p33, p34, p35, p36, p37, p38, p39, p40, p41, p42, p43, p44, p45, p46, p47, p48, p49, p50, p51, p52, p53, p54,
|
||||
p55, p56, p57, p58, p59, p60, p61, p62, p63, p64)
|
||||
TO_TUPLE_TEMPLATE(66, p0, p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13, p14, p15, p16, p17, p18, p19, p20, p21, p22, p23, p24, p25, p26, p27,
|
||||
p28, p29, p30, p31, p32, p33, p34, p35, p36, p37, p38, p39, p40, p41, p42, p43, p44, p45, p46, p47, p48, p49, p50, p51, p52, p53, p54,
|
||||
p55, p56, p57, p58, p59, p60, p61, p62, p63, p64, p65)
|
||||
TO_TUPLE_TEMPLATE(67, p0, p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13, p14, p15, p16, p17, p18, p19, p20, p21, p22, p23, p24, p25, p26, p27,
|
||||
p28, p29, p30, p31, p32, p33, p34, p35, p36, p37, p38, p39, p40, p41, p42, p43, p44, p45, p46, p47, p48, p49, p50, p51, p52, p53, p54,
|
||||
p55, p56, p57, p58, p59, p60, p61, p62, p63, p64, p65, p66)
|
||||
TO_TUPLE_TEMPLATE(68, p0, p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13, p14, p15, p16, p17, p18, p19, p20, p21, p22, p23, p24, p25, p26, p27,
|
||||
p28, p29, p30, p31, p32, p33, p34, p35, p36, p37, p38, p39, p40, p41, p42, p43, p44, p45, p46, p47, p48, p49, p50, p51, p52, p53, p54,
|
||||
p55, p56, p57, p58, p59, p60, p61, p62, p63, p64, p65, p66, p67)
|
||||
TO_TUPLE_TEMPLATE(69, p0, p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13, p14, p15, p16, p17, p18, p19, p20, p21, p22, p23, p24, p25, p26, p27,
|
||||
p28, p29, p30, p31, p32, p33, p34, p35, p36, p37, p38, p39, p40, p41, p42, p43, p44, p45, p46, p47, p48, p49, p50, p51, p52, p53, p54,
|
||||
p55, p56, p57, p58, p59, p60, p61, p62, p63, p64, p65, p66, p67, p68)
|
||||
TO_TUPLE_TEMPLATE(70, p0, p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13, p14, p15, p16, p17, p18, p19, p20, p21, p22, p23, p24, p25, p26, p27,
|
||||
p28, p29, p30, p31, p32, p33, p34, p35, p36, p37, p38, p39, p40, p41, p42, p43, p44, p45, p46, p47, p48, p49, p50, p51, p52, p53, p54,
|
||||
p55, p56, p57, p58, p59, p60, p61, p62, p63, p64, p65, p66, p67, p68, p69)
|
||||
TO_TUPLE_TEMPLATE(71, p0, p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13, p14, p15, p16, p17, p18, p19, p20, p21, p22, p23, p24, p25, p26, p27,
|
||||
p28, p29, p30, p31, p32, p33, p34, p35, p36, p37, p38, p39, p40, p41, p42, p43, p44, p45, p46, p47, p48, p49, p50, p51, p52, p53, p54,
|
||||
p55, p56, p57, p58, p59, p60, p61, p62, p63, p64, p65, p66, p67, p68, p69, p70)
|
||||
TO_TUPLE_TEMPLATE(72, p0, p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13, p14, p15, p16, p17, p18, p19, p20, p21, p22, p23, p24, p25, p26, p27,
|
||||
p28, p29, p30, p31, p32, p33, p34, p35, p36, p37, p38, p39, p40, p41, p42, p43, p44, p45, p46, p47, p48, p49, p50, p51, p52, p53, p54,
|
||||
p55, p56, p57, p58, p59, p60, p61, p62, p63, p64, p65, p66, p67, p68, p69, p70, p71)
|
||||
TO_TUPLE_TEMPLATE(73, p0, p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13, p14, p15, p16, p17, p18, p19, p20, p21, p22, p23, p24, p25, p26, p27,
|
||||
p28, p29, p30, p31, p32, p33, p34, p35, p36, p37, p38, p39, p40, p41, p42, p43, p44, p45, p46, p47, p48, p49, p50, p51, p52, p53, p54,
|
||||
p55, p56, p57, p58, p59, p60, p61, p62, p63, p64, p65, p66, p67, p68, p69, p70, p71, p72)
|
||||
TO_TUPLE_TEMPLATE(74, p0, p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13, p14, p15, p16, p17, p18, p19, p20, p21, p22, p23, p24, p25, p26, p27,
|
||||
p28, p29, p30, p31, p32, p33, p34, p35, p36, p37, p38, p39, p40, p41, p42, p43, p44, p45, p46, p47, p48, p49, p50, p51, p52, p53, p54,
|
||||
p55, p56, p57, p58, p59, p60, p61, p62, p63, p64, p65, p66, p67, p68, p69, p70, p71, p72, p73)
|
||||
TO_TUPLE_TEMPLATE(75, p0, p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13, p14, p15, p16, p17, p18, p19, p20, p21, p22, p23, p24, p25, p26, p27,
|
||||
p28, p29, p30, p31, p32, p33, p34, p35, p36, p37, p38, p39, p40, p41, p42, p43, p44, p45, p46, p47, p48, p49, p50, p51, p52, p53, p54,
|
||||
p55, p56, p57, p58, p59, p60, p61, p62, p63, p64, p65, p66, p67, p68, p69, p70, p71, p72, p73, p74)
|
||||
TO_TUPLE_TEMPLATE(76, p0, p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13, p14, p15, p16, p17, p18, p19, p20, p21, p22, p23, p24, p25, p26, p27,
|
||||
p28, p29, p30, p31, p32, p33, p34, p35, p36, p37, p38, p39, p40, p41, p42, p43, p44, p45, p46, p47, p48, p49, p50, p51, p52, p53, p54,
|
||||
p55, p56, p57, p58, p59, p60, p61, p62, p63, p64, p65, p66, p67, p68, p69, p70, p71, p72, p73, p74, p75)
|
||||
TO_TUPLE_TEMPLATE(77, p0, p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13, p14, p15, p16, p17, p18, p19, p20, p21, p22, p23, p24, p25, p26, p27,
|
||||
p28, p29, p30, p31, p32, p33, p34, p35, p36, p37, p38, p39, p40, p41, p42, p43, p44, p45, p46, p47, p48, p49, p50, p51, p52, p53, p54,
|
||||
p55, p56, p57, p58, p59, p60, p61, p62, p63, p64, p65, p66, p67, p68, p69, p70, p71, p72, p73, p74, p75, p76)
|
||||
TO_TUPLE_TEMPLATE(78, p0, p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13, p14, p15, p16, p17, p18, p19, p20, p21, p22, p23, p24, p25, p26, p27,
|
||||
p28, p29, p30, p31, p32, p33, p34, p35, p36, p37, p38, p39, p40, p41, p42, p43, p44, p45, p46, p47, p48, p49, p50, p51, p52, p53, p54,
|
||||
p55, p56, p57, p58, p59, p60, p61, p62, p63, p64, p65, p66, p67, p68, p69, p70, p71, p72, p73, p74, p75, p76, p77)
|
||||
TO_TUPLE_TEMPLATE(79, p0, p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13, p14, p15, p16, p17, p18, p19, p20, p21, p22, p23, p24, p25, p26, p27,
|
||||
p28, p29, p30, p31, p32, p33, p34, p35, p36, p37, p38, p39, p40, p41, p42, p43, p44, p45, p46, p47, p48, p49, p50, p51, p52, p53, p54,
|
||||
p55, p56, p57, p58, p59, p60, p61, p62, p63, p64, p65, p66, p67, p68, p69, p70, p71, p72, p73, p74, p75, p76, p77, p78)
|
||||
TO_TUPLE_TEMPLATE(80, p0, p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13, p14, p15, p16, p17, p18, p19, p20, p21, p22, p23, p24, p25, p26, p27,
|
||||
p28, p29, p30, p31, p32, p33, p34, p35, p36, p37, p38, p39, p40, p41, p42, p43, p44, p45, p46, p47, p48, p49, p50, p51, p52, p53, p54,
|
||||
p55, p56, p57, p58, p59, p60, p61, p62, p63, p64, p65, p66, p67, p68, p69, p70, p71, p72, p73, p74, p75, p76, p77, p78, p79)
|
||||
TO_TUPLE_TEMPLATE(81, p0, p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13, p14, p15, p16, p17, p18, p19, p20, p21, p22, p23, p24, p25, p26, p27,
|
||||
p28, p29, p30, p31, p32, p33, p34, p35, p36, p37, p38, p39, p40, p41, p42, p43, p44, p45, p46, p47, p48, p49, p50, p51, p52, p53, p54,
|
||||
p55, p56, p57, p58, p59, p60, p61, p62, p63, p64, p65, p66, p67, p68, p69, p70, p71, p72, p73, p74, p75, p76, p77, p78, p79, p80)
|
||||
TO_TUPLE_TEMPLATE(82, p0, p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13, p14, p15, p16, p17, p18, p19, p20, p21, p22, p23, p24, p25, p26, p27,
|
||||
p28, p29, p30, p31, p32, p33, p34, p35, p36, p37, p38, p39, p40, p41, p42, p43, p44, p45, p46, p47, p48, p49, p50, p51, p52, p53, p54,
|
||||
p55, p56, p57, p58, p59, p60, p61, p62, p63, p64, p65, p66, p67, p68, p69, p70, p71, p72, p73, p74, p75, p76, p77, p78, p79, p80, p81)
|
||||
TO_TUPLE_TEMPLATE(83, p0, p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13, p14, p15, p16, p17, p18, p19, p20, p21, p22, p23, p24, p25, p26, p27,
|
||||
p28, p29, p30, p31, p32, p33, p34, p35, p36, p37, p38, p39, p40, p41, p42, p43, p44, p45, p46, p47, p48, p49, p50, p51, p52, p53, p54,
|
||||
p55, p56, p57, p58, p59, p60, p61, p62, p63, p64, p65, p66, p67, p68, p69, p70, p71, p72, p73, p74, p75, p76, p77, p78, p79, p80, p81,
|
||||
p82)
|
||||
TO_TUPLE_TEMPLATE(84, p0, p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13, p14, p15, p16, p17, p18, p19, p20, p21, p22, p23, p24, p25, p26, p27,
|
||||
p28, p29, p30, p31, p32, p33, p34, p35, p36, p37, p38, p39, p40, p41, p42, p43, p44, p45, p46, p47, p48, p49, p50, p51, p52, p53, p54,
|
||||
p55, p56, p57, p58, p59, p60, p61, p62, p63, p64, p65, p66, p67, p68, p69, p70, p71, p72, p73, p74, p75, p76, p77, p78, p79, p80, p81,
|
||||
p82, p83)
|
||||
TO_TUPLE_TEMPLATE(85, p0, p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13, p14, p15, p16, p17, p18, p19, p20, p21, p22, p23, p24, p25, p26, p27,
|
||||
p28, p29, p30, p31, p32, p33, p34, p35, p36, p37, p38, p39, p40, p41, p42, p43, p44, p45, p46, p47, p48, p49, p50, p51, p52, p53, p54,
|
||||
p55, p56, p57, p58, p59, p60, p61, p62, p63, p64, p65, p66, p67, p68, p69, p70, p71, p72, p73, p74, p75, p76, p77, p78, p79, p80, p81,
|
||||
p82, p83, p84)
|
||||
TO_TUPLE_TEMPLATE(86, p0, p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13, p14, p15, p16, p17, p18, p19, p20, p21, p22, p23, p24, p25, p26, p27,
|
||||
p28, p29, p30, p31, p32, p33, p34, p35, p36, p37, p38, p39, p40, p41, p42, p43, p44, p45, p46, p47, p48, p49, p50, p51, p52, p53, p54,
|
||||
p55, p56, p57, p58, p59, p60, p61, p62, p63, p64, p65, p66, p67, p68, p69, p70, p71, p72, p73, p74, p75, p76, p77, p78, p79, p80, p81,
|
||||
p82, p83, p84, p85)
|
||||
TO_TUPLE_TEMPLATE(87, p0, p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13, p14, p15, p16, p17, p18, p19, p20, p21, p22, p23, p24, p25, p26, p27,
|
||||
p28, p29, p30, p31, p32, p33, p34, p35, p36, p37, p38, p39, p40, p41, p42, p43, p44, p45, p46, p47, p48, p49, p50, p51, p52, p53, p54,
|
||||
p55, p56, p57, p58, p59, p60, p61, p62, p63, p64, p65, p66, p67, p68, p69, p70, p71, p72, p73, p74, p75, p76, p77, p78, p79, p80, p81,
|
||||
p82, p83, p84, p85, p86)
|
||||
TO_TUPLE_TEMPLATE(88, p0, p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13, p14, p15, p16, p17, p18, p19, p20, p21, p22, p23, p24, p25, p26, p27,
|
||||
p28, p29, p30, p31, p32, p33, p34, p35, p36, p37, p38, p39, p40, p41, p42, p43, p44, p45, p46, p47, p48, p49, p50, p51, p52, p53, p54,
|
||||
p55, p56, p57, p58, p59, p60, p61, p62, p63, p64, p65, p66, p67, p68, p69, p70, p71, p72, p73, p74, p75, p76, p77, p78, p79, p80, p81,
|
||||
p82, p83, p84, p85, p86, p87)
|
||||
TO_TUPLE_TEMPLATE(89, p0, p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13, p14, p15, p16, p17, p18, p19, p20, p21, p22, p23, p24, p25, p26, p27,
|
||||
p28, p29, p30, p31, p32, p33, p34, p35, p36, p37, p38, p39, p40, p41, p42, p43, p44, p45, p46, p47, p48, p49, p50, p51, p52, p53, p54,
|
||||
p55, p56, p57, p58, p59, p60, p61, p62, p63, p64, p65, p66, p67, p68, p69, p70, p71, p72, p73, p74, p75, p76, p77, p78, p79, p80, p81,
|
||||
p82, p83, p84, p85, p86, p87, p88)
|
||||
TO_TUPLE_TEMPLATE(90, p0, p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13, p14, p15, p16, p17, p18, p19, p20, p21, p22, p23, p24, p25, p26, p27,
|
||||
p28, p29, p30, p31, p32, p33, p34, p35, p36, p37, p38, p39, p40, p41, p42, p43, p44, p45, p46, p47, p48, p49, p50, p51, p52, p53, p54,
|
||||
p55, p56, p57, p58, p59, p60, p61, p62, p63, p64, p65, p66, p67, p68, p69, p70, p71, p72, p73, p74, p75, p76, p77, p78, p79, p80, p81,
|
||||
p82, p83, p84, p85, p86, p87, p88, p89)
|
||||
TO_TUPLE_TEMPLATE(91, p0, p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13, p14, p15, p16, p17, p18, p19, p20, p21, p22, p23, p24, p25, p26, p27,
|
||||
p28, p29, p30, p31, p32, p33, p34, p35, p36, p37, p38, p39, p40, p41, p42, p43, p44, p45, p46, p47, p48, p49, p50, p51, p52, p53, p54,
|
||||
p55, p56, p57, p58, p59, p60, p61, p62, p63, p64, p65, p66, p67, p68, p69, p70, p71, p72, p73, p74, p75, p76, p77, p78, p79, p80, p81,
|
||||
p82, p83, p84, p85, p86, p87, p88, p89, p90)
|
||||
TO_TUPLE_TEMPLATE(92, p0, p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13, p14, p15, p16, p17, p18, p19, p20, p21, p22, p23, p24, p25, p26, p27,
|
||||
p28, p29, p30, p31, p32, p33, p34, p35, p36, p37, p38, p39, p40, p41, p42, p43, p44, p45, p46, p47, p48, p49, p50, p51, p52, p53, p54,
|
||||
p55, p56, p57, p58, p59, p60, p61, p62, p63, p64, p65, p66, p67, p68, p69, p70, p71, p72, p73, p74, p75, p76, p77, p78, p79, p80, p81,
|
||||
p82, p83, p84, p85, p86, p87, p88, p89, p90, p91)
|
||||
TO_TUPLE_TEMPLATE(93, p0, p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13, p14, p15, p16, p17, p18, p19, p20, p21, p22, p23, p24, p25, p26, p27,
|
||||
p28, p29, p30, p31, p32, p33, p34, p35, p36, p37, p38, p39, p40, p41, p42, p43, p44, p45, p46, p47, p48, p49, p50, p51, p52, p53, p54,
|
||||
p55, p56, p57, p58, p59, p60, p61, p62, p63, p64, p65, p66, p67, p68, p69, p70, p71, p72, p73, p74, p75, p76, p77, p78, p79, p80, p81,
|
||||
p82, p83, p84, p85, p86, p87, p88, p89, p90, p91, p92)
|
||||
TO_TUPLE_TEMPLATE(94, p0, p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13, p14, p15, p16, p17, p18, p19, p20, p21, p22, p23, p24, p25, p26, p27,
|
||||
p28, p29, p30, p31, p32, p33, p34, p35, p36, p37, p38, p39, p40, p41, p42, p43, p44, p45, p46, p47, p48, p49, p50, p51, p52, p53, p54,
|
||||
p55, p56, p57, p58, p59, p60, p61, p62, p63, p64, p65, p66, p67, p68, p69, p70, p71, p72, p73, p74, p75, p76, p77, p78, p79, p80, p81,
|
||||
p82, p83, p84, p85, p86, p87, p88, p89, p90, p91, p92, p93)
|
||||
TO_TUPLE_TEMPLATE(95, p0, p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13, p14, p15, p16, p17, p18, p19, p20, p21, p22, p23, p24, p25, p26, p27,
|
||||
p28, p29, p30, p31, p32, p33, p34, p35, p36, p37, p38, p39, p40, p41, p42, p43, p44, p45, p46, p47, p48, p49, p50, p51, p52, p53, p54,
|
||||
p55, p56, p57, p58, p59, p60, p61, p62, p63, p64, p65, p66, p67, p68, p69, p70, p71, p72, p73, p74, p75, p76, p77, p78, p79, p80, p81,
|
||||
p82, p83, p84, p85, p86, p87, p88, p89, p90, p91, p92, p93, p94)
|
||||
TO_TUPLE_TEMPLATE(96, p0, p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13, p14, p15, p16, p17, p18, p19, p20, p21, p22, p23, p24, p25, p26, p27,
|
||||
p28, p29, p30, p31, p32, p33, p34, p35, p36, p37, p38, p39, p40, p41, p42, p43, p44, p45, p46, p47, p48, p49, p50, p51, p52, p53, p54,
|
||||
p55, p56, p57, p58, p59, p60, p61, p62, p63, p64, p65, p66, p67, p68, p69, p70, p71, p72, p73, p74, p75, p76, p77, p78, p79, p80, p81,
|
||||
p82, p83, p84, p85, p86, p87, p88, p89, p90, p91, p92, p93, p94, p95)
|
||||
TO_TUPLE_TEMPLATE(97, p0, p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13, p14, p15, p16, p17, p18, p19, p20, p21, p22, p23, p24, p25, p26, p27,
|
||||
p28, p29, p30, p31, p32, p33, p34, p35, p36, p37, p38, p39, p40, p41, p42, p43, p44, p45, p46, p47, p48, p49, p50, p51, p52, p53, p54,
|
||||
p55, p56, p57, p58, p59, p60, p61, p62, p63, p64, p65, p66, p67, p68, p69, p70, p71, p72, p73, p74, p75, p76, p77, p78, p79, p80, p81,
|
||||
p82, p83, p84, p85, p86, p87, p88, p89, p90, p91, p92, p93, p94, p95, p96)
|
||||
TO_TUPLE_TEMPLATE(98, p0, p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13, p14, p15, p16, p17, p18, p19, p20, p21, p22, p23, p24, p25, p26, p27,
|
||||
p28, p29, p30, p31, p32, p33, p34, p35, p36, p37, p38, p39, p40, p41, p42, p43, p44, p45, p46, p47, p48, p49, p50, p51, p52, p53, p54,
|
||||
p55, p56, p57, p58, p59, p60, p61, p62, p63, p64, p65, p66, p67, p68, p69, p70, p71, p72, p73, p74, p75, p76, p77, p78, p79, p80, p81,
|
||||
p82, p83, p84, p85, p86, p87, p88, p89, p90, p91, p92, p93, p94, p95, p96, p97)
|
||||
TO_TUPLE_TEMPLATE(99, p0, p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13, p14, p15, p16, p17, p18, p19, p20, p21, p22, p23, p24, p25, p26, p27,
|
||||
p28, p29, p30, p31, p32, p33, p34, p35, p36, p37, p38, p39, p40, p41, p42, p43, p44, p45, p46, p47, p48, p49, p50, p51, p52, p53, p54,
|
||||
p55, p56, p57, p58, p59, p60, p61, p62, p63, p64, p65, p66, p67, p68, p69, p70, p71, p72, p73, p74, p75, p76, p77, p78, p79, p80, p81,
|
||||
p82, p83, p84, p85, p86, p87, p88, p89, p90, p91, p92, p93, p94, p95, p96, p97, p98)
|
||||
TO_TUPLE_TEMPLATE(100, p0, p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13, p14, p15, p16, p17, p18, p19, p20, p21, p22, p23, p24, p25, p26, p27,
|
||||
p28, p29, p30, p31, p32, p33, p34, p35, p36, p37, p38, p39, p40, p41, p42, p43, p44, p45, p46, p47, p48, p49, p50, p51, p52, p53, p54,
|
||||
p55, p56, p57, p58, p59, p60, p61, p62, p63, p64, p65, p66, p67, p68, p69, p70, p71, p72, p73, p74, p75, p76, p77, p78, p79, p80, p81,
|
||||
p82, p83, p84, p85, p86, p87, p88, p89, p90, p91, p92, p93, p94, p95, p96, p97, p98, p99)
|
||||
#undef FIELD_RFL_EVAL0
|
||||
#undef FIELD_RFL_EVAL1
|
||||
#undef FIELD_RFL_EVAL2
|
||||
#undef FIELD_RFL_EVAL3
|
||||
#undef FIELD_RFL_EVAL4
|
||||
#undef FIELD_RFL_EVAL
|
||||
#undef FIELD_RFL_MAP_END
|
||||
#undef FIELD_RFL_MAP_OUT
|
||||
#undef FIELD_RFL_MAP_COMMA
|
||||
#undef FIELD_RFL_MAP_GET_END2
|
||||
#undef FIELD_RFL_MAP_GET_END1
|
||||
#undef FIELD_RFL_MAP_GET_END
|
||||
#undef FIELD_RFL_MAP_NEXT0
|
||||
#undef FIELD_RFL_MAP_NEXT1
|
||||
#undef FIELD_RFL_MAP_NEXT
|
||||
#undef FIELD_RFL_MAP0
|
||||
#undef FIELD_RFL_MAP1
|
||||
#undef FIELD_RFL_MAP_LIST_NEXT1
|
||||
#undef FIELD_RFL_MAP_LIST_NEXT
|
||||
#undef FIELD_RFL_MAP_LIST0
|
||||
#undef FIELD_RFL_MAP_LIST1
|
||||
#undef FIELD_RFL_MAP
|
||||
#undef FIELD_RFL_MAP_LIST
|
||||
#undef FIELD_RFL_DECLTYPE
|
||||
#undef FIELD_RFL_MOVE
|
||||
#undef FIELD_RFL_TO_TUPLE_TEMPLATE
|
||||
#pragma endregion TO_TUPLE_TEMPLATE_MACRO
|
||||
|
||||
#if defined(__clang__)
|
||||
#pragma clang diagnostic push
|
||||
#pragma clang diagnostic ignored "-Wundefined-internal"
|
||||
#pragma clang diagnostic ignored "-Wundefined-var-template"
|
||||
#elif defined(__GNUC__)
|
||||
#elif defined(_MSC_VER)
|
||||
#else
|
||||
#endif
|
||||
|
||||
template <typename T>
|
||||
struct wrapper {
|
||||
explicit constexpr wrapper(const T& v) : value(v) {}
|
||||
|
||||
T value;
|
||||
static wrapper<T> fake; // NOLINT
|
||||
};
|
||||
|
||||
template <typename T, size_t N> // NOLINT
|
||||
consteval auto get_ptr() noexcept {
|
||||
#if defined(__clang__)
|
||||
return wrapper(stl::get<N>(to_ptr_tuple(wrapper<T>::fake.value)));
|
||||
#else
|
||||
return stl::get<N>(to_ptr_tuple(wrapper<T>::fake.value));
|
||||
#endif
|
||||
}
|
||||
|
||||
#if defined(__clang__)
|
||||
#pragma clang diagnostic pop
|
||||
#elif __GNUC__
|
||||
#elif defined(_MSC_VER)
|
||||
#else
|
||||
#endif
|
||||
|
||||
template <auto Ptr>
|
||||
using nontype_template_parameter_helper = void;
|
||||
|
||||
template <typename T> // clang-format off
|
||||
concept field_namable = field_referenceable<T> && (field_count<T> > 0) && requires {
|
||||
typename nontype_template_parameter_helper<get_ptr<T, 0>()>;
|
||||
}; // clang-format on
|
||||
|
||||
template <typename T, auto Ptr>
|
||||
consteval stl::string_view get_function_name() {
|
||||
#if defined(__clang__) && defined(_WIN32)
|
||||
// clang-cl returns function_name() as __FUNCTION__ instead of __PRETTY_FUNCTION__
|
||||
return stl::string_view{__PRETTY_FUNCTION__};
|
||||
#else
|
||||
return stl::string_view{stl::source_location::current().function_name()};
|
||||
#endif
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
consteval stl::string_view get_function_name() {
|
||||
#if defined(__clang__) && defined(_WIN32)
|
||||
// clang-cl returns function_name() as __FUNCTION__ instead of __PRETTY_FUNCTION__
|
||||
return stl::string_view{__PRETTY_FUNCTION__};
|
||||
#else
|
||||
return stl::string_view{stl::source_location::current().function_name()};
|
||||
#endif
|
||||
}
|
||||
|
||||
template <typename T, auto Ptr>
|
||||
consteval stl::string_view get_field_name() {
|
||||
struct field_name_detector {
|
||||
void* dummy;
|
||||
};
|
||||
|
||||
constexpr auto detector_name = get_function_name<field_name_detector, get_ptr<field_name_detector, 0>()>();
|
||||
constexpr auto dummy_begin = detector_name.rfind(stl::string_view("dummy"));
|
||||
constexpr auto suffix = detector_name.substr(dummy_begin + stl::string_view("dummy").size());
|
||||
constexpr auto begin_sentinel = detector_name[dummy_begin - 1];
|
||||
|
||||
const auto field_name_raw = get_function_name<T, Ptr>();
|
||||
const auto last = field_name_raw.rfind(suffix);
|
||||
const auto begin = field_name_raw.rfind(begin_sentinel, last - 1) + 1;
|
||||
|
||||
assert(begin < field_name_raw.size());
|
||||
assert(last <= field_name_raw.size());
|
||||
assert(begin < last);
|
||||
|
||||
return field_name_raw.substr(begin, last - begin);
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
using remove_rvalue_reference_t = stl::conditional_t<stl::is_rvalue_reference_v<T>, stl::remove_reference_t<T>, T>;
|
||||
|
||||
template <field_namable T, size_t N>
|
||||
constexpr stl::string_view field_name = get_field_name<T, get_ptr<T, N>()>();
|
||||
|
||||
template <field_referenceable T, size_t N>
|
||||
using field_type = remove_rvalue_reference_t<decltype(stl::get<N>(to_tuple(stl::declval<T&>())))>;
|
||||
|
||||
struct type_name_detector {};
|
||||
|
||||
template <typename T>
|
||||
consteval stl::string_view get_type_name() {
|
||||
#if defined(__GNUC__) || defined(__clang__)
|
||||
constexpr auto detector_name = get_function_name<type_name_detector>();
|
||||
constexpr auto dummy = stl::string_view("T = ");
|
||||
constexpr auto dummy_begin = detector_name.find(dummy) + dummy.size();
|
||||
constexpr auto dummy2 = stl::string_view("type_name_detector");
|
||||
constexpr auto dummy_suffix_length = detector_name.size() - detector_name.find(dummy2) - dummy2.size();
|
||||
|
||||
constexpr auto type_name_raw = get_function_name<T>();
|
||||
return type_name_raw.substr(dummy_begin, type_name_raw.size() - dummy_begin - dummy_suffix_length);
|
||||
#else
|
||||
constexpr auto detector_name = get_function_name<type_name_detector>();
|
||||
constexpr auto dummy = stl::string_view("struct field_reflection::detail::type_name_detector");
|
||||
constexpr auto dummy_begin = detector_name.find(dummy);
|
||||
constexpr auto dummy_suffix_length = detector_name.size() - dummy_begin - dummy.size();
|
||||
|
||||
auto type_name_raw = get_function_name<T>();
|
||||
auto type_name = type_name_raw.substr(dummy_begin, type_name_raw.size() - dummy_begin - dummy_suffix_length);
|
||||
if (auto s = stl::string_view("struct "); type_name.starts_with(s)) {
|
||||
type_name.remove_prefix(s.size());
|
||||
}
|
||||
if (auto s = stl::string_view("class "); type_name.starts_with(s)) {
|
||||
type_name.remove_prefix(s.size());
|
||||
}
|
||||
return type_name;
|
||||
#endif
|
||||
}
|
||||
|
||||
template <class T>
|
||||
constexpr stl::string_view type_name = get_type_name<T>();
|
||||
|
||||
template <size_t N, typename T, field_referenceable U = stl::remove_cvref_t<T>>
|
||||
constexpr decltype(auto) get_field(T& t) noexcept {
|
||||
return *stl::get<N>(to_ptr_tuple(t));
|
||||
}
|
||||
|
||||
template <size_t N, typename T, field_referenceable U = stl::remove_cvref_t<T>>
|
||||
requires stl::is_rvalue_reference_v<T&&>
|
||||
constexpr auto get_field(T&& t) noexcept {
|
||||
return stl::get<N>(to_tuple(stl::forward<T>(t)));
|
||||
}
|
||||
|
||||
template <typename T, typename Func, size_t... Is, field_referenceable U = stl::remove_cvref_t<T>>
|
||||
void for_each_field_impl(T&& t, Func&& func, stl::index_sequence<Is...>) {
|
||||
if constexpr (requires { (func(get_field<Is>(t)), ...); }) {
|
||||
(func(get_field<Is>(t)), ...);
|
||||
} else if constexpr (requires { (func(field_name<U, Is>, get_field<Is>(t)), ...); }) {
|
||||
(func(field_name<U, Is>, get_field<Is>(t)), ...);
|
||||
} else {
|
||||
static_assert([] { return false; }(), "invalid function object for call to for_each_field");
|
||||
}
|
||||
}
|
||||
|
||||
template <typename T1, typename T2, typename Func, size_t... Is, field_referenceable U = stl::remove_cvref_t<T1>>
|
||||
void for_each_field_impl(T1&& t1, T2&& t2, Func&& func, stl::index_sequence<Is...>) {
|
||||
if constexpr (requires { (func(get_field<Is>(t1), get_field<Is>(t2)), ...); }) {
|
||||
(func(get_field<Is>(t1), get_field<Is>(t2)), ...);
|
||||
} else if constexpr (requires { (func(field_name<U, Is>, get_field<Is>(t1), get_field<Is>(t2)), ...); }) {
|
||||
(func(field_name<U, Is>, get_field<Is>(t1), get_field<Is>(t2)), ...);
|
||||
} else {
|
||||
static_assert([] { return false; }(), "invalid function object for call to for_each_field");
|
||||
}
|
||||
}
|
||||
|
||||
template <typename T, typename Func, size_t... Is, field_referenceable U = stl::remove_cvref_t<T>>
|
||||
bool all_of_field_impl(T&& t, Func&& func, stl::index_sequence<Is...>) {
|
||||
if constexpr (requires { (func(get_field<Is>(t)) && ...); }) {
|
||||
return (func(get_field<Is>(t)) && ...);
|
||||
} else if constexpr (requires { (func(field_name<U, Is>, get_field<Is>(t)) && ...); }) {
|
||||
return (func(field_name<U, Is>, get_field<Is>(t)) && ...);
|
||||
} else {
|
||||
static_assert([] { return false; }(), "invalid function object for call to all_of_field");
|
||||
}
|
||||
}
|
||||
|
||||
template <typename T1, typename T2, typename Func, size_t... Is, field_referenceable U = stl::remove_cvref_t<T1>>
|
||||
bool all_of_field_impl(T1&& t1, T2&& t2, Func&& func, stl::index_sequence<Is...>) {
|
||||
if constexpr (requires { (func(get_field<Is>(t1), get_field<Is>(t2)) && ...); }) {
|
||||
return (func(get_field<Is>(t1), get_field<Is>(t2)) && ...);
|
||||
} else if constexpr (requires { (func(field_name<U, Is>, get_field<Is>(t1), get_field<Is>(t2)) && ...); }) {
|
||||
return (func(field_name<U, Is>, get_field<Is>(t1), get_field<Is>(t2)) && ...);
|
||||
} else {
|
||||
static_assert([] { return false; }(), "invalid function object for call to all_of_field");
|
||||
}
|
||||
}
|
||||
|
||||
template <typename T, typename Func, size_t... Is, field_referenceable U = stl::remove_cvref_t<T>>
|
||||
bool any_of_field_impl(T&& t, Func&& func, stl::index_sequence<Is...>) {
|
||||
if constexpr (requires { (func(get_field<Is>(t)) || ...); }) {
|
||||
return (func(get_field<Is>(t)) || ...);
|
||||
} else if constexpr (requires { (func(field_name<U, Is>, get_field<Is>(t)) || ...); }) {
|
||||
return (func(field_name<U, Is>, get_field<Is>(t)) || ...);
|
||||
} else {
|
||||
static_assert([] { return false; }(), "invalid function object for call to any_of_field");
|
||||
}
|
||||
}
|
||||
|
||||
template <typename T1, typename T2, typename Func, size_t... Is, field_referenceable U = stl::remove_cvref_t<T1>>
|
||||
bool any_of_field_impl(T1&& t1, T2&& t2, Func&& func, stl::index_sequence<Is...>) {
|
||||
if constexpr (requires { (func(get_field<Is>(t1), get_field<Is>(t2)) || ...); }) {
|
||||
return (func(get_field<Is>(t1), get_field<Is>(t2)) || ...);
|
||||
} else if constexpr (requires { (func(field_name<U, Is>, get_field<Is>(t1), get_field<Is>(t2)) || ...); }) {
|
||||
return (func(field_name<U, Is>, get_field<Is>(t1), get_field<Is>(t2)) || ...);
|
||||
} else {
|
||||
static_assert([] { return false; }(), "invalid function object for call to any_of_field");
|
||||
}
|
||||
}
|
||||
} // namespace detail
|
||||
|
||||
using detail::field_count;
|
||||
using detail::field_countable;
|
||||
using detail::field_namable;
|
||||
using detail::field_name;
|
||||
using detail::field_referenceable;
|
||||
using detail::field_type;
|
||||
using detail::get_field;
|
||||
using detail::to_tuple;
|
||||
using detail::type_name;
|
||||
|
||||
template <typename T1, typename T2, typename Func, field_referenceable U1 = stl::remove_cvref_t<T1>, field_referenceable U2 = stl::remove_cvref_t<T2>>
|
||||
requires stl::is_same_v<U1, U2>
|
||||
void for_each_field(T1&& t1, T2&& t2, Func&& func) {
|
||||
detail::for_each_field_impl(stl::forward<T1>(t1), stl::forward<T2>(t2), stl::forward<Func>(func), stl::make_index_sequence<field_count<U1>>());
|
||||
}
|
||||
|
||||
template <typename T, typename Func, field_referenceable U = stl::remove_cvref_t<T>>
|
||||
void for_each_field(T&& t, Func&& func) {
|
||||
detail::for_each_field_impl(stl::forward<T>(t), stl::forward<Func>(func), stl::make_index_sequence<field_count<U>>());
|
||||
}
|
||||
|
||||
template <typename T1, typename T2, typename Func, field_referenceable U1 = stl::remove_cvref_t<T1>, field_referenceable U2 = stl::remove_cvref_t<T2>>
|
||||
requires stl::is_same_v<U1, U2>
|
||||
bool all_of_field(T1&& t1, T2&& t2, Func&& func) {
|
||||
return detail::all_of_field_impl(stl::forward<T1>(t1), stl::forward<T2>(t2), stl::forward<Func>(func), stl::make_index_sequence<field_count<U1>>());
|
||||
}
|
||||
|
||||
template <typename T, typename Func, field_referenceable U = stl::remove_cvref_t<T>>
|
||||
bool all_of_field(T&& t, Func&& func) {
|
||||
return detail::all_of_field_impl(stl::forward<T>(t), stl::forward<Func>(func), stl::make_index_sequence<field_count<U>>());
|
||||
}
|
||||
|
||||
template <typename T1, typename T2, typename Func, field_referenceable U1 = stl::remove_cvref_t<T1>, field_referenceable U2 = stl::remove_cvref_t<T2>>
|
||||
requires stl::is_same_v<U1, U2>
|
||||
bool any_of_field(T1&& t1, T2&& t2, Func&& func) {
|
||||
return detail::any_of_field_impl(stl::forward<T1>(t1), stl::forward<T2>(t2), stl::forward<Func>(func), stl::make_index_sequence<field_count<U1>>());
|
||||
}
|
||||
|
||||
template <typename T, typename Func, field_referenceable U = stl::remove_cvref_t<T>>
|
||||
bool any_of_field(T&& t, Func&& func) {
|
||||
return detail::any_of_field_impl(stl::forward<T>(t), stl::forward<Func>(func), stl::make_index_sequence<field_count<U>>());
|
||||
}
|
||||
} // namespace field_reflection
|
15
src/internals.cpp
Normal file
15
src/internals.cpp
Normal file
|
@ -0,0 +1,15 @@
|
|||
#include <stdlib.h>
|
||||
#include <std.hpp>
|
||||
|
||||
namespace std {
|
||||
void __glibcxx_assert_fail(char const* file, int line, char const* func, char const* info) {
|
||||
println("{}:{}:{}: {}", file, line, func, info);
|
||||
}
|
||||
|
||||
void terminate() {
|
||||
exit(1);
|
||||
}
|
||||
|
||||
} // namespace std
|
||||
|
||||
extern "C" void __cxa_begin_catch() {}
|
106
src/logger.cpp
Normal file
106
src/logger.cpp
Normal file
|
@ -0,0 +1,106 @@
|
|||
#include "io/print.hpp"
|
||||
#include <string.h>
|
||||
#include <logger.hpp>
|
||||
|
||||
using namespace log;
|
||||
|
||||
#define C_RS "\x1b[0m"
|
||||
#define C_BLACK "\x1b[30m"
|
||||
#define C_RED "\x1b[31m"
|
||||
#define C_GREEN "\x1b[32m"
|
||||
#define C_YELLOW "\x1b[33m"
|
||||
#define C_BLUE "\x1b[34m"
|
||||
#define C_MAGENTA "\x1b[35m"
|
||||
#define C_CYAN "\x1b[36m"
|
||||
#define C_WHITE "\x1b[37m"
|
||||
#define C_BOLD "\x1b[1m"
|
||||
#define C_DIM "\x1b[2m"
|
||||
#define C_ITALIC "\x1b[3m"
|
||||
#define C_UL "\x1b[4m"
|
||||
#define C_BLINK "\x1b[5m"
|
||||
|
||||
extern "C" char* getenv(const char* name);
|
||||
|
||||
Logger::Logger() {
|
||||
char* val = getenv("CPLUS_LOG");
|
||||
if (val != NULL) {
|
||||
if (strcmp(val, "OFF") == 0) {
|
||||
this->set_log_level(LOG_OFF);
|
||||
} else if (strcmp(val, "ERROR") == 0) {
|
||||
this->set_log_level(LOG_ERROR);
|
||||
} else if (strcmp(val, "WARN") == 0) {
|
||||
this->set_log_level(LOG_WARN);
|
||||
} else if (strcmp(val, "INFO") == 0) {
|
||||
this->set_log_level(LOG_INFO);
|
||||
} else if (strcmp(val, "DEBUG") == 0) {
|
||||
this->set_log_level(LOG_DEBUG);
|
||||
}
|
||||
}
|
||||
|
||||
val = getenv("CPLUS_LOG_COLOR");
|
||||
// clang-format off
|
||||
if (val != NULL) {
|
||||
if (
|
||||
strcmp(val, "false") == 0 ||
|
||||
strcmp(val, "FALSE") == 0 ||
|
||||
strcmp(val, "off") == 0 ||
|
||||
strcmp(val, "OFF") == 0 ||
|
||||
strcmp(val, "no") == 0 ||
|
||||
strcmp(val, "NO") == 0
|
||||
) {
|
||||
this->load_default_prefixes();
|
||||
} else {
|
||||
this->load_default_prefixes_with_color();
|
||||
}
|
||||
} else {
|
||||
this->load_default_prefixes_with_color();
|
||||
}
|
||||
}
|
||||
|
||||
void Logger::log(LogLevel level, const char* file, const int line, const char* func, const char* str) {
|
||||
String s = String(str);
|
||||
Logger::log(level, file, line, func, s);
|
||||
}
|
||||
|
||||
void Logger::log(LogLevel level, const char* file, const int line, const char* func, String str) {
|
||||
if (!this->should_display(level)) {
|
||||
return;
|
||||
}
|
||||
|
||||
println(this->get_prefix(level), file, line, func, str);
|
||||
}
|
||||
|
||||
void Logger::set_log_level(LogLevel level) {
|
||||
this->filter_level = level;
|
||||
}
|
||||
|
||||
// Fucking c++ and its implicit member variable access, god forbid C++ code looks clean.
|
||||
const char* Logger::get_prefix(LogLevel level) {
|
||||
return this->prefixes[level];
|
||||
}
|
||||
|
||||
void Logger::load_default_prefixes_with_color() {
|
||||
// clang-format off
|
||||
this->prefixes[LOG_ERROR] = C_UL "{}" C_RS ":" C_UL "{}" C_RS ":" C_CYAN " [" C_RS C_RED "ERROR" C_RS C_CYAN "] (" C_RS "{}" C_CYAN ")" C_RS ": {}";
|
||||
this->prefixes[LOG_WARN] = C_UL "{}" C_RS ":" C_UL "{}" C_RS ":" C_CYAN " [" C_RS C_YELLOW "WARN" C_RS C_CYAN "] (" C_RS "{}" C_CYAN ")" C_RS ": {}";
|
||||
this->prefixes[LOG_INFO] = C_UL "{}" C_RS ":" C_UL "{}" C_RS ":" C_CYAN " [" C_RS C_GREEN "INFO" C_RS C_CYAN "] (" C_RS "{}" C_CYAN ")" C_RS ": {}";
|
||||
this->prefixes[LOG_DEBUG] = C_UL "{}" C_RS ":" C_UL "{}" C_RS ":" C_CYAN " [" C_RS C_MAGENTA "DEBUG" C_RS C_CYAN "] (" C_RS "{}" C_CYAN ")" C_RS ": {}";
|
||||
// clang-format on
|
||||
}
|
||||
|
||||
void Logger::load_default_prefixes() {
|
||||
this->prefixes[LOG_ERROR] = "{}:{}: [ERROR] ({}): {}";
|
||||
this->prefixes[LOG_WARN] = "{}:{}: [WARN] ({}): {}";
|
||||
this->prefixes[LOG_INFO] = "{}:{}: [INFO] ({}): {}";
|
||||
this->prefixes[LOG_DEBUG] = "{}:{}: [DEBUG] ({}): {}";
|
||||
}
|
||||
|
||||
void Logger::load_custom_prefixes(const char* pfx[LOG_LEVEL_COUNT]) {
|
||||
for (int i = 0; i < LOG_LEVEL_COUNT; i++) {
|
||||
this->prefixes[i] = pfx[i];
|
||||
}
|
||||
}
|
||||
|
||||
bool Logger::should_display(LogLevel level) {
|
||||
return this->filter_level >= level;
|
||||
}
|
|
@ -1,4 +1,4 @@
|
|||
|
||||
CC = clang
|
||||
|
||||
all: ../build/libc+ test compile_commands.json
|
||||
|
||||
|
@ -6,10 +6,10 @@ clean:
|
|||
rm -rf test *.o compile_commands.json
|
||||
|
||||
test: test.o
|
||||
cc -o $@ $^ -L../build -l:libc+.a -ggdb # -nostdlib++ -lsupc++
|
||||
$(CC) -o $@ $^ -L../build -l:libc+.a -ggdb # -nostdlib++ -lsupc++
|
||||
|
||||
%.o: %.cpp
|
||||
cc -c -o $@ $< -std=c++23 -I../src/include -ggdb # -nostdinc++
|
||||
$(CC) -c -o $@ $< -std=c++23 -I../src/include -ggdb # -nostdinc++
|
||||
|
||||
../build/libc+:
|
||||
$(MAKE) -C ../
|
||||
|
|
|
@ -1,11 +1,95 @@
|
|||
#include "io/print.hpp"
|
||||
#include <std.hpp>
|
||||
#include <format/obj_fmt_helper.hpp>
|
||||
#include <sync/mutex.hpp>
|
||||
#include <sync/spinlock.hpp>
|
||||
#include <stddef.h>
|
||||
#include <pthread.h>
|
||||
#include <unistd.h>
|
||||
|
||||
int main(int argc, char* argv[]) {
|
||||
#include <logger.hpp>
|
||||
|
||||
struct Foo {
|
||||
int bar = 1;
|
||||
float baz = 2.0;
|
||||
|
||||
// IMPL: Format
|
||||
String fmt_to_str() {
|
||||
auto h = ObjFmtHelper("Foo");
|
||||
h.add_field("bar", this->bar);
|
||||
h.add_field("baz", this->baz);
|
||||
return h.finish();
|
||||
}
|
||||
};
|
||||
|
||||
Vec<int> test_vec() {
|
||||
Vec<int> v = Vec<int>();
|
||||
v.push(1);
|
||||
v.push(2);
|
||||
v.push(3);
|
||||
v.push(4);
|
||||
return v;
|
||||
}
|
||||
|
||||
void test_fmt(Vec<int> v) {
|
||||
Foo f = Foo();
|
||||
println("Hello!!!! {}, {}, {}, {}", "meow", 420.0, 49, v);
|
||||
println("> {}", f);
|
||||
}
|
||||
|
||||
extern "C" void* test_mutex_thread(void* arg) {
|
||||
Mutex<int>* m = (Mutex<int>*)arg;
|
||||
auto val = m->lock();
|
||||
println("mutex: changing {} to 69", *val);
|
||||
*val = 69;
|
||||
println("mutex: 5 second eep!! (eepy boyo)");
|
||||
sleep(5);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void test_mutex() {
|
||||
Mutex<int>* m = new Mutex<int>(0);
|
||||
pthread_t thread;
|
||||
println("mutex: Creating thread for mutex");
|
||||
if (pthread_create(&thread, NULL, test_mutex_thread, (void*)m) != 0) {
|
||||
println("Uh oh (mutex)");
|
||||
}
|
||||
|
||||
pthread_join(thread, NULL);
|
||||
auto val = m->lock();
|
||||
println("mutex: Value was {}", *val);
|
||||
}
|
||||
|
||||
extern "C" void* test_spinlock_thread(void* arg) {
|
||||
SpinLock<int>* sl = (SpinLock<int>*)arg;
|
||||
println("spinlock: changing {} to 5", *sl->lock());
|
||||
*sl->lock() = 5;
|
||||
println("spinlock: 5 second eep!! (eepy girlie)");
|
||||
sleep(5);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void test_spinlock() {
|
||||
SpinLock<int>* sl = new SpinLock<int>(0);
|
||||
pthread_t thread;
|
||||
println("spinlock: Creating thread for spinlock");
|
||||
if (pthread_create(&thread, NULL, test_spinlock_thread, (void*)sl) != 0) {
|
||||
println("Uh oh (spinlock)");
|
||||
}
|
||||
|
||||
pthread_join(thread, NULL);
|
||||
println("spinlock: Value was {}", *sl->lock());
|
||||
}
|
||||
|
||||
/// https://github.com/yosh-matsuda/field-reflection
|
||||
int main(int argc, char* argv[]) {
|
||||
// Vec<int> v = test_vec();
|
||||
// test_fmt(v);
|
||||
// test_spinlock();
|
||||
// test_mutex();
|
||||
log::debug("hemlo!!");
|
||||
log::info("hemlo!!");
|
||||
log::warn("hemlo!!");
|
||||
log::error("hemlo!!");
|
||||
return 0;
|
||||
}
|
Loading…
Reference in New Issue
Block a user