finished context impl
This commit is contained in:
parent
953ad58939
commit
99690fd38b
|
|
@ -60,6 +60,10 @@ consteval std::size_t c_arr_len(T (&arr)[N]) { return N; }
|
|||
template<typename T>
|
||||
concept StringLike = std::is_convertible_v<T, std::string_view>;
|
||||
|
||||
template<typename T, typename U>
|
||||
concept not_base_type_same_as = !std::is_same_v<std::remove_cvref_t<T>, std::remove_cvref_t<U>>;
|
||||
|
||||
|
||||
template<std::input_iterator I, std::sentinel_for<I> S, StringLike T>
|
||||
constexpr bool all_eq_to(I first, S last, T t) {
|
||||
auto r1 = std::ranges::subrange(first, last);
|
||||
|
|
@ -154,17 +158,36 @@ struct ret_val {
|
|||
constexpr inline const ret_val_s& operator[](std::size_t i) const { return vals[i]; }
|
||||
};
|
||||
|
||||
template<typename Ctx>
|
||||
concept ctx_has_type_num = requires {
|
||||
typename Ctx::type;
|
||||
{ Ctx::nr } -> std::convertible_to<std::size_t>;
|
||||
struct ctx_base {};
|
||||
|
||||
template<typename T, std::size_t Nr>
|
||||
struct ctx_tn : ctx_base {
|
||||
using type = T;
|
||||
constexpr static std::size_t nr = Nr;
|
||||
};
|
||||
|
||||
template<typename Ctx>
|
||||
concept ctx_has_type = requires {
|
||||
typename Ctx::type;
|
||||
template<typename T>
|
||||
struct ctx_t : ctx_base {
|
||||
using type = T;
|
||||
};
|
||||
|
||||
template<std::size_t Nr>
|
||||
struct ctx_n : ctx_base {
|
||||
constexpr static std::size_t nr = Nr;
|
||||
};
|
||||
|
||||
template<typename ctx>
|
||||
concept require_context = requires {
|
||||
std::is_base_of_v<ctx_base, ctx>;
|
||||
};
|
||||
|
||||
template<typename T> auto create_ctx() { return ctx_t<T>{}; }
|
||||
template<std::size_t Nr> auto create_ctx() { return ctx_n<Nr>{}; }
|
||||
template<typename T, std::size_t Nr> auto create_ctx() { return ctx_tn<T, Nr>{}; }
|
||||
|
||||
#define CONTEXT(...) decltype(create_ctx<__VA_ARGS__>())
|
||||
|
||||
|
||||
struct empty_param {};
|
||||
|
||||
struct test_common_params {
|
||||
|
|
@ -172,61 +195,94 @@ struct test_common_params {
|
|||
constexpr static auto value = empty_param{};
|
||||
};
|
||||
|
||||
template<typename T, std::size_t Nr = 0>
|
||||
template<require_context ctx>
|
||||
struct test_context_params {
|
||||
using type = T;
|
||||
constexpr static std::size_t nr = Nr;
|
||||
using context = ctx;
|
||||
|
||||
template<tstring var_name>
|
||||
constexpr static auto value = empty_param{};
|
||||
};
|
||||
|
||||
template<typename ctx, tstring var_name>
|
||||
concept param_is_defined = require_context<ctx> && requires {
|
||||
test_context_params<ctx>::template value<var_name>;
|
||||
{ test_context_params<ctx>::template value<var_name> } -> not_base_type_same_as<empty_param>;
|
||||
};
|
||||
|
||||
template<typename ctx, tstring var_name>
|
||||
concept param_is_defined_number_context = require_context<ctx> && requires {
|
||||
test_context_params<CONTEXT(ctx::nr)>::template value<var_name>;
|
||||
{ test_context_params<CONTEXT(ctx::nr)>::template value<var_name> } -> not_base_type_same_as<empty_param>;
|
||||
};
|
||||
|
||||
template<typename ctx, tstring var_name>
|
||||
concept param_is_defined_type_context = require_context<ctx> && requires {
|
||||
test_context_params<CONTEXT(ctx::type)>::template value<var_name>;
|
||||
{ test_context_params<CONTEXT(ctx::type)>::template value<var_name> } -> not_base_type_same_as<empty_param>;
|
||||
};
|
||||
|
||||
template<tstring var_name>
|
||||
concept param_is_defined_common = requires {
|
||||
test_common_params::value<var_name>;
|
||||
{ test_common_params::value<var_name> } -> not_base_type_same_as<empty_param>;
|
||||
};
|
||||
|
||||
|
||||
template<tstring name>
|
||||
requires param_is_defined_common<name>
|
||||
constexpr auto& get_test_param() {
|
||||
return test_common_params::value<name>;
|
||||
}
|
||||
|
||||
template<typename Ctx, tstring name>
|
||||
requires requires { typename Ctx::type; { Ctx::nr } -> std::convertible_to<std::size_t>; }
|
||||
template<require_context ctx, tstring name>
|
||||
requires param_is_defined<ctx, name>
|
||||
constexpr auto& get_test_param() {
|
||||
return test_context_params<typename Ctx::type, Ctx::nr>::template value<name>;
|
||||
return test_context_params<ctx>::template value<name>;
|
||||
}
|
||||
|
||||
template<typename Ctx, tstring name>
|
||||
requires requires { typename Ctx::type; } && (!requires { Ctx::nr; })
|
||||
constexpr auto& get_test_param() {
|
||||
return test_context_params<typename Ctx::type, Ctx::nr>::template value<name>;
|
||||
template<require_context ctx, tstring name>
|
||||
requires (!param_is_defined<ctx, name>)
|
||||
&& param_is_defined_number_context<ctx, name>
|
||||
&& param_is_defined_type_context<ctx, name>
|
||||
constexpr void get_test_param() {
|
||||
throw std::invalid_argument(std::string_view("Could not resolve ambiguous parameter name ") + name);
|
||||
}
|
||||
|
||||
/*template<tstring Name, typename Ctx = void>
|
||||
struct test_params {
|
||||
constexpr static auto get() {
|
||||
if constexpr (requires { typename Ctx::type; }) {
|
||||
if constexpr (requires { { Ctx::nr } -> std::convertible_to<std::size_t>; }) {
|
||||
return test_context_params<typename Ctx::type, Ctx::nr>::template value<Name>;
|
||||
} else {
|
||||
return test_context_params<typename Ctx::type>::template value<Name>;
|
||||
}
|
||||
} else {
|
||||
return test_common_params::template value<Name>;
|
||||
}
|
||||
}
|
||||
template<require_context ctx, tstring name>
|
||||
requires (!param_is_defined<ctx, name>)
|
||||
&& param_is_defined_number_context<ctx, name>
|
||||
&& (!param_is_defined_type_context<ctx, name>)
|
||||
constexpr auto& get_test_param() {
|
||||
return test_context_params<CONTEXT(ctx::nr)>::template value<name>;
|
||||
}
|
||||
|
||||
constexpr static auto get_arr_len() {
|
||||
if constexpr (requires { typename Ctx::type; }) {
|
||||
if constexpr (requires { { Ctx::nr } -> std::convertible_to<std::size_t>; }) {
|
||||
return c_arr_len(test_context_params<typename Ctx::type, Ctx::nr>::template value<Name>);
|
||||
} else {
|
||||
return c_arr_len(test_context_params<typename Ctx::type>::template value<Name>);
|
||||
}
|
||||
} else {
|
||||
return c_arr_len(test_common_params::template value<Name>);
|
||||
}
|
||||
}
|
||||
};*/
|
||||
template<require_context ctx, tstring name>
|
||||
requires (!param_is_defined<ctx, name>)
|
||||
&& (!param_is_defined_number_context<ctx, name>)
|
||||
&& param_is_defined_type_context<ctx, name>
|
||||
constexpr auto& get_test_param() {
|
||||
return test_context_params<CONTEXT(ctx::type)>::template value<name>;
|
||||
}
|
||||
|
||||
#define CONTEXT_PARAM(type, name, ...) template<> template<> constexpr type test_context_params<__VA_ARGS__>::value< #name >
|
||||
#define CONTEXT_PARAM_ARR(type, name, ...) template<> template<> constexpr type test_context_params<__VA_ARGS__>::value< #name >[]
|
||||
template<require_context ctx, tstring name>
|
||||
requires (!param_is_defined<ctx, name>) && param_is_defined_common<name>
|
||||
constexpr auto& get_test_param() {
|
||||
return test_common_params::value<name>;
|
||||
}
|
||||
|
||||
template<require_context ctx, tstring name>
|
||||
constexpr void get_test_param() {
|
||||
throw std::invalid_argument(std::string("Parameter ") + name.value + " could not be found in context");
|
||||
}
|
||||
|
||||
template<tstring name>
|
||||
constexpr void get_test_param() {
|
||||
throw std::invalid_argument(std::string("Parameter ") + name.value + " could not be found");
|
||||
}
|
||||
|
||||
|
||||
#define CONTEXT_PARAM(type, name, ...) template<> template<> constexpr type test_context_params<CONTEXT(__VA_ARGS__)>::value< #name >
|
||||
#define CONTEXT_PARAM_ARR(type, name, ...) template<> template<> constexpr type test_context_params<CONTEXT(__VA_ARGS__)>::value< #name >[]
|
||||
|
||||
|
||||
class test_definition {
|
||||
|
|
@ -444,30 +500,20 @@ inline std::ostream& operator<<(std::ostream& os, ReturnCode rc) {
|
|||
|
||||
template <typename ...Ts>
|
||||
constexpr auto _repeat_for_types(auto f) {
|
||||
std::array<ret_val_s, sizeof...(Ts)> rets { (f.template operator()<Ts>())... };
|
||||
std::array<ret_val_s, sizeof...(Ts)> rets { (f.template operator()<Ts, CONTEXT(Ts)>())... };
|
||||
return rets;
|
||||
}
|
||||
|
||||
template <std::size_t _N, typename ...Ts, std::size_t N = _N - 1>
|
||||
template <std::size_t N, typename ...Ts>
|
||||
constexpr auto _repeat_for_types_n(auto f) {
|
||||
std::array rets = {
|
||||
[&]<typename T, std::size_t ...Ns>(std::index_sequence<Ns...>) constexpr {
|
||||
return std::array {
|
||||
(f.template operator()<T, Ns, test_context_params<T, Ns>>())...
|
||||
(f.template operator()<T, Ns, CONTEXT(T, Ns)>())...
|
||||
};
|
||||
}.template operator()<Ts>(std::make_index_sequence<N>())...
|
||||
};
|
||||
// Clion does not accept this as a constant expression
|
||||
// even though it compiles and works as intended
|
||||
//return rets | std::ranges::views::join;
|
||||
std::array<ret_val_s, sizeof...(Ts) * N> arr;
|
||||
auto arr_it = std::begin(arr);
|
||||
for (auto&& rp : rets) {
|
||||
for (ret_val_s& r : rp) {
|
||||
*(arr_it++) = r;
|
||||
}
|
||||
}
|
||||
return arr;
|
||||
return rets | std::ranges::views::join;
|
||||
}
|
||||
|
||||
#define REPEAT_FOR_TYPES(func, ...) { \
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@
|
|||
|
||||
#include "test.hpp"
|
||||
|
||||
#define GEN_TEST_OBJ_FROM_ARR(nr, i) TestObj(test_context_params<int, nr>::value<"arr">[i], test_context_params<char, nr>::value<"arr">[i], test_context_params<const char *, nr>::value<"arr">[i])
|
||||
#define GEN_TEST_OBJ_FROM_ARR(nr, i) TestObj(test_context_params<CONTEXT(int, nr)>::value<"arr">[i], test_context_params<CONTEXT(char, nr)>::value<"arr">[i], test_context_params<CONTEXT(const char *, nr)>::value<"arr">[i])
|
||||
|
||||
struct TestObj {
|
||||
int x = 0;
|
||||
|
|
@ -14,18 +14,18 @@ struct TestObj {
|
|||
};
|
||||
ADD_TYPE_HINT(TestObj);
|
||||
|
||||
template<> template<> constexpr int test_context_params<int, 0>::value<"arr">[] = { 1, 2, 3, 4 };
|
||||
template<> template<> constexpr int test_context_params<int, 1>::value<"arr">[] = { 5, 6, 7, 8, 9, 10, 11, 12 };
|
||||
template<> template<> constexpr char test_context_params<char, 0>::value<"arr">[] = { 'a', 'B', 'c', 'D' };
|
||||
template<> template<> constexpr char test_context_params<char, 1>::value<"arr">[] = { 'e', 'F', 'g', 'H', 'i', 'J', '\n', '\0' };
|
||||
template<> template<> constexpr const char * test_context_params<const char *, 0>::value<"arr">[] = { "Lorem", "ipsum", "dolor", "sit" };
|
||||
template<> template<> constexpr const char * test_context_params<const char *, 1>::value<"arr">[] = { "amet", "consetetur", "sadipscing", "elitr", "sed", "diam", "nonumy", "eirmod", "tempor", "\0" };
|
||||
template<> template<> constexpr TestObj test_context_params<TestObj, 0>::value<"arr">[] = {
|
||||
template<> template<> constexpr int test_context_params<CONTEXT(int, 0)>::value<"arr">[] = { 1, 2, 3, 4 };
|
||||
template<> template<> constexpr int test_context_params<CONTEXT(int, 1)>::value<"arr">[] = { 5, 6, 7, 8, 9, 10, 11, 12 };
|
||||
template<> template<> constexpr char test_context_params<CONTEXT(char, 0)>::value<"arr">[] = { 'a', 'B', 'c', 'D' };
|
||||
template<> template<> constexpr char test_context_params<CONTEXT(char, 1)>::value<"arr">[] = { 'e', 'F', 'g', 'H', 'i', 'J', '\n', '\0' };
|
||||
template<> template<> constexpr const char * test_context_params<CONTEXT(const char *, 0)>::value<"arr">[] = { "Lorem", "ipsum", "dolor", "sit" };
|
||||
template<> template<> constexpr const char * test_context_params<CONTEXT(const char *, 1)>::value<"arr">[] = { "amet", "consetetur", "sadipscing", "elitr", "sed", "diam", "nonumy", "eirmod", "tempor", "\0" };
|
||||
template<> template<> constexpr TestObj test_context_params<CONTEXT(TestObj, 0)>::value<"arr">[] = {
|
||||
GEN_TEST_OBJ_FROM_ARR(0, 0),
|
||||
GEN_TEST_OBJ_FROM_ARR(0, 1),
|
||||
GEN_TEST_OBJ_FROM_ARR(0, 2),
|
||||
GEN_TEST_OBJ_FROM_ARR(0, 3) };
|
||||
template<> template<> constexpr TestObj test_context_params<TestObj, 1>::value<"arr">[] = {
|
||||
template<> template<> constexpr TestObj test_context_params<CONTEXT(TestObj, 1)>::value<"arr">[] = {
|
||||
GEN_TEST_OBJ_FROM_ARR(1, 0),
|
||||
GEN_TEST_OBJ_FROM_ARR(1, 1),
|
||||
GEN_TEST_OBJ_FROM_ARR(1, 2),
|
||||
|
|
@ -35,18 +35,18 @@ template<> template<> constexpr TestObj test_context_params<TestObj, 1>::value<"
|
|||
GEN_TEST_OBJ_FROM_ARR(1, 6),
|
||||
GEN_TEST_OBJ_FROM_ARR(1, 7) };
|
||||
|
||||
template<> template<> constexpr std::initializer_list<int> test_context_params<int, 0>::value<"ilist"> = { 1, 2, 3, 4 };
|
||||
template<> template<> constexpr std::initializer_list<int> test_context_params<int, 1>::value<"ilist"> = { 5, 6, 7, 8, 9, 10, 11, 12 };
|
||||
template<> template<> constexpr std::initializer_list<char> test_context_params<char, 0>::value<"ilist"> = { 'a', 'B', 'c', 'D' };
|
||||
template<> template<> constexpr std::initializer_list<char> test_context_params<char, 1>::value<"ilist"> = { 'e', 'F', 'g', 'H', 'i', 'J', '\n', '\0' };
|
||||
template<> template<> constexpr std::initializer_list<const char *> test_context_params<const char *, 0>::value<"ilist"> = { "Lorem", "ipsum", "dolor", "sit" };
|
||||
template<> template<> constexpr std::initializer_list<const char *> test_context_params<const char *, 1>::value<"ilist"> = { "amet", "consetetur", "sadipscing", "elitr", "sed", "diam", "nonumy", "eirmod", "tempor", "\0" };
|
||||
template<> template<> constexpr std::initializer_list<TestObj> test_context_params<TestObj, 0>::value<"ilist"> = {
|
||||
template<> template<> constexpr std::initializer_list<int> test_context_params<CONTEXT(int, 0)>::value<"ilist"> = { 1, 2, 3, 4 };
|
||||
template<> template<> constexpr std::initializer_list<int> test_context_params<CONTEXT(int, 1)>::value<"ilist"> = { 5, 6, 7, 8, 9, 10, 11, 12 };
|
||||
template<> template<> constexpr std::initializer_list<char> test_context_params<CONTEXT(char, 0)>::value<"ilist"> = { 'a', 'B', 'c', 'D' };
|
||||
template<> template<> constexpr std::initializer_list<char> test_context_params<CONTEXT(char, 1)>::value<"ilist"> = { 'e', 'F', 'g', 'H', 'i', 'J', '\n', '\0' };
|
||||
template<> template<> constexpr std::initializer_list<const char *> test_context_params<CONTEXT(const char *, 0)>::value<"ilist"> = { "Lorem", "ipsum", "dolor", "sit" };
|
||||
template<> template<> constexpr std::initializer_list<const char *> test_context_params<CONTEXT(const char *, 1)>::value<"ilist"> = { "amet", "consetetur", "sadipscing", "elitr", "sed", "diam", "nonumy", "eirmod", "tempor", "\0" };
|
||||
template<> template<> constexpr std::initializer_list<TestObj> test_context_params<CONTEXT(TestObj, 0)>::value<"ilist"> = {
|
||||
GEN_TEST_OBJ_FROM_ARR(0, 0),
|
||||
GEN_TEST_OBJ_FROM_ARR(0, 1),
|
||||
GEN_TEST_OBJ_FROM_ARR(0, 2),
|
||||
GEN_TEST_OBJ_FROM_ARR(0, 3) };
|
||||
template<> template<> constexpr std::initializer_list<TestObj> test_context_params<TestObj, 1>::value<"ilist"> = {
|
||||
template<> template<> constexpr std::initializer_list<TestObj> test_context_params<CONTEXT(TestObj, 1)>::value<"ilist"> = {
|
||||
GEN_TEST_OBJ_FROM_ARR(1, 0),
|
||||
GEN_TEST_OBJ_FROM_ARR(1, 1),
|
||||
GEN_TEST_OBJ_FROM_ARR(1, 2),
|
||||
|
|
@ -56,31 +56,25 @@ template<> template<> constexpr std::initializer_list<TestObj> test_context_para
|
|||
GEN_TEST_OBJ_FROM_ARR(1, 6),
|
||||
GEN_TEST_OBJ_FROM_ARR(1, 7) };
|
||||
|
||||
template<> template<> constexpr std::size_t test_context_params<int, 0>::value<"capacity"> = 10;
|
||||
template<> template<> constexpr std::size_t test_context_params<char, 0>::value<"capacity"> = 10;
|
||||
template<> template<> constexpr std::size_t test_context_params<const char *, 0>::value<"capacity"> = 10;
|
||||
template<> template<> constexpr std::size_t test_context_params<TestObj, 0>::value<"capacity"> = 10;
|
||||
template<> template<> constexpr std::size_t test_context_params<int, 1>::value<"capacity"> = 200;
|
||||
template<> template<> constexpr std::size_t test_context_params<char, 1>::value<"capacity"> = 200;
|
||||
template<> template<> constexpr std::size_t test_context_params<const char *, 1>::value<"capacity"> = 200;
|
||||
template<> template<> constexpr std::size_t test_context_params<TestObj, 1>::value<"capacity"> = 200;
|
||||
template<> template<> constexpr std::size_t test_context_params<CONTEXT(0)>::value<"capacity"> = 10;
|
||||
template<> template<> constexpr std::size_t test_context_params<CONTEXT(1)>::value<"capacity"> = 200;
|
||||
|
||||
template<> template<> constexpr std::size_t test_context_params<int, 0>::value<"size"> = 25;
|
||||
template<> template<> constexpr std::size_t test_context_params<char, 0>::value<"size"> = 25;
|
||||
template<> template<> constexpr std::size_t test_context_params<const char *, 0>::value<"size"> = 25;
|
||||
template<> template<> constexpr std::size_t test_context_params<TestObj, 0>::value<"size"> = 25;
|
||||
template<> template<> constexpr std::size_t test_context_params<int, 1>::value<"size"> = 50;
|
||||
template<> template<> constexpr std::size_t test_context_params<char, 1>::value<"size"> = 50;
|
||||
template<> template<> constexpr std::size_t test_context_params<const char *, 1>::value<"size"> = 50;
|
||||
template<> template<> constexpr std::size_t test_context_params<TestObj, 1>::value<"size"> = 50;
|
||||
template<> template<> constexpr std::size_t test_context_params<CONTEXT(int, 0)>::value<"size"> = 25;
|
||||
template<> template<> constexpr std::size_t test_context_params<CONTEXT(char, 0)>::value<"size"> = 25;
|
||||
template<> template<> constexpr std::size_t test_context_params<CONTEXT(const char *, 0)>::value<"size"> = 25;
|
||||
template<> template<> constexpr std::size_t test_context_params<CONTEXT(TestObj, 0)>::value<"size"> = 25;
|
||||
template<> template<> constexpr std::size_t test_context_params<CONTEXT(int, 1)>::value<"size"> = 50;
|
||||
template<> template<> constexpr std::size_t test_context_params<CONTEXT(char, 1)>::value<"size"> = 50;
|
||||
template<> template<> constexpr std::size_t test_context_params<CONTEXT(const char *, 1)>::value<"size"> = 50;
|
||||
template<> template<> constexpr std::size_t test_context_params<CONTEXT(TestObj, 1)>::value<"size"> = 50;
|
||||
|
||||
template<> template<> constexpr int test_context_params<int, 0>::value<"value"> = 5;
|
||||
template<> template<> constexpr int test_context_params<int, 1>::value<"value"> = INT_MIN;
|
||||
template<> template<> constexpr char test_context_params<char, 0>::value<"value"> = 'P';
|
||||
template<> template<> constexpr char test_context_params<char, 1>::value<"value"> = CHAR_MAX;
|
||||
template<> template<> constexpr const char * test_context_params<const char *, 0>::value<"value"> = "Test string 1";
|
||||
template<> template<> constexpr const char * test_context_params<const char *, 1>::value<"value"> = "Test string 2";
|
||||
template<> template<> constexpr TestObj test_context_params<TestObj, 0>::value<"value"> = TestObj(5, 'P', "Object String 1");
|
||||
template<> template<> constexpr TestObj test_context_params<TestObj, 1>::value<"value"> = TestObj(INT_MAX, 'p', "2 Object String");
|
||||
template<> template<> constexpr int test_context_params<CONTEXT(int, 0)>::value<"value"> = 5;
|
||||
template<> template<> constexpr int test_context_params<CONTEXT(int, 1)>::value<"value"> = INT_MIN;
|
||||
template<> template<> constexpr char test_context_params<CONTEXT(char, 0)>::value<"value"> = 'P';
|
||||
template<> template<> constexpr char test_context_params<CONTEXT(char, 1)>::value<"value"> = CHAR_MAX;
|
||||
template<> template<> constexpr const char * test_context_params<CONTEXT(const char *, 0)>::value<"value"> = "Test string 1";
|
||||
template<> template<> constexpr const char * test_context_params<CONTEXT(const char *, 1)>::value<"value"> = "Test string 2";
|
||||
template<> template<> constexpr TestObj test_context_params<CONTEXT(TestObj, 0)>::value<"value"> = TestObj(5, 'P', "Object String 1");
|
||||
template<> template<> constexpr TestObj test_context_params<CONTEXT(TestObj, 1)>::value<"value"> = TestObj(INT_MAX, 'p', "2 Object String");
|
||||
|
||||
#endif //CONST_CONTAINER_TEST_ARGS_H
|
||||
|
|
|
|||
Loading…
Reference in New Issue