Compare commits

...

11 Commits

6 changed files with 510 additions and 841 deletions

View File

@ -44,7 +44,7 @@ namespace cc {
constexpr explicit const_vector(const value_type &value) noexcept;
constexpr const_vector(size_type count, const value_type &value) noexcept;
constexpr explicit const_vector(const value_type (&array)[N]) noexcept;
constexpr const_vector(const value_type (&array)[N]) noexcept;
template <std::size_t N2>
constexpr explicit const_vector(const value_type (&array)[N2]);
@ -84,11 +84,11 @@ namespace cc {
constexpr T& operator[](size_type pos) { return _arr[pos]; }
constexpr const T& operator[](size_type pos) const { return _arr[pos]; }
[[nodiscard]] constexpr reference front() noexcept{ return _arr[0]; }
[[nodiscard]] constexpr reference front() noexcept { return _arr[0]; }
[[nodiscard]] constexpr const_reference front() const noexcept { return _arr[0]; }
[[nodiscard]] constexpr reference back() noexcept { return _arr[_size]; }
[[nodiscard]] constexpr const_reference back() const noexcept { return _arr[_size]; }
[[nodiscard]] constexpr reference back() noexcept { return _arr[_size - 1]; }
[[nodiscard]] constexpr const_reference back() const noexcept { return _arr[_size - 1]; }
[[nodiscard]] constexpr value_type * data() noexcept { return _arr; }
[[nodiscard]] constexpr const value_type * data() const noexcept { return _arr; }

View File

@ -20,55 +20,47 @@
template<typename T, std::size_t N>
consteval std::size_t c_arr_len(T (&arr)[N]) { return N; }
constexpr auto make_copy(auto& value) -> std::remove_cvref_t<decltype(value)> { return value; }
#define ADD_TYPE_HINT(type) template <> constexpr const char* const to_type_hint_str::value<type> = #type
#define TEST_FAIL(msg) ret_val_s { "", ReturnCode::FAILED, msg }
#define TEST_PASS() ret_val_s { "", ReturnCode::PASSED, nullptr }
#define TEST_PASS_MSG(msg) ret_val_s { "", ReturnCode::PASSED, msg }
#define TEST_SKIP() ret_val_s { "", ReturnCode::SKIPPED, nullptr}
#define TEST_SKIP_MSG(msg) ret_val_s { "", ReturnCode::SKIPPED, msg}
#define TEST_FAIL(msg, ...) _ret_val_from_ctx<__VA_ARGS__>(ReturnCode::FAILED, msg)
#define TEST_PASS(...) _ret_val_from_ctx<__VA_ARGS__>(ReturnCode::PASSED)
#define TEST_PASS_MSG(msg, ...) _ret_val_from_ctx<__VA_ARGS__>(ReturnCode::PASSED, msg)
#define TEST_SKIP(...) _ret_val_from_ctx<__VA_ARGS__>(ReturnCode::SKIPPED)
#define TEST_SKIP_MSG(msg, ...) _ret_val_from_ctx<__VA_ARGS__>(ReturnCode::SKIPPED, msg)
#define TEST_FAIL_TYPE(msg, type_hint) ret_val_s { "", ReturnCode::FAILED, msg, to_type_hint_str::value<type_hint> }
#define TEST_PASS_TYPE(type_hint) ret_val_s { "", ReturnCode::PASSED, nullptr, to_type_hint_str::value<type_hint> }
#define TEST_PASS_MSG_TYPE(msg, type_hint) ret_val_s { "", ReturnCode::PASSED, msg, to_type_hint_str::value<type_hint> }
#define TEST_SKIP_TYPE(type_hint) ret_val_s { "", ReturnCode::SKIPPED, nullptr, to_type_hint_str::value<type_hint> }
#define TEST_FAIL_TYPE_NUM(msg, type_hint, num) ret_val_s { "", ReturnCode::FAILED, msg, to_type_hint_str::value<type_hint>, num }
#define TEST_PASS_TYPE_NUM(type_hint, num) ret_val_s { "", ReturnCode::PASSED, nullptr, to_type_hint_str::value<type_hint>, num }
#define TEST_PASS_MSG_TYPE_NUM(msg, type_hint, num) ret_val_s { "", ReturnCode::PASSED, msg, to_type_hint_str::value<type_hint>, num }
#define TEST_SKIP_TYPE_NUM(type_hint, num) ret_val_s { "", ReturnCode::SKIPPED, nullptr, to_type_hint_str::value<type_hint>, num }
#define ASSERT_TYPE_NUM(condition, type, num) ASSERT_TYPE_NUM_MSG(condition, #condition "" _LOCATION, type, num)
#define ASSERT_TYPE_NUM_MSG(condition, msg, type, num) { if (!(condition)) return TEST_FAIL_TYPE_NUM(msg, type, num); } static_assert(true, "")
#define ASSERT_TYPE_NUM_ALL_EQ(first, last, eq, type, num) ASSERT_TYPE_NUM_MSG(all_eq_to(first, last, eq), "Not all elements in (" #first ", " #last ") equal " #eq "" _LOCATION, type, num)
#define ASSERT_TYPE_NUM_C_ARR_EQ(first, last, eq, type, num) ASSERT_TYPE_NUM_MSG(equal_to(first, last, eq), "Elements in (" #first ", " #last ") and " #eq " differ" _LOCATION, type, num)
#define ASSERT_TYPE(condition, type) ASSERT_TYPE_NUM(condition, type, -1ULL)
#define ASSERT_TYPE_MSG(condition, msg, type) ASSERT_TYPE_NUM_MSG(condition, msg, type -1ULL)
#define ASSERT_TYPE_ALL_EQ(first, last, eq, type) ASSERT_TYPE_NUM_ALL_EQ(first, last, eq, type, -1ULL)
#define ASSERT_TYPE_C_ARR_EQ(first, last, eq, type) ASSERT_TYPE_NUM_C_ARR_EQ(first, last, eq, type, -1ULL)
#define ASSERT(condition) ASSERT_TYPE(condition, std::nullptr_t)
#define ASSERT_MSG(condition, msg) ASSERT_TYPE_MSG(condition, msg, std::nullptr_t)
#define ASSERT_ALL_EQ(first, last, eq) ASSERT_TYPE_ALL_EQ(first, last, eq, std::nullptr_t)
#define ASSERT_C_ARR_EQ(first, last, eq) ASSERT_TYPE_C_ARR_EQ(first, last, eq, std::nullptr_t)
#define ASSERT_TYPE_NUM_THROWS(operation, exception_type, type, num) if not consteval { try { operation; ASSERT_TYPE_NUM_MSG(false, #operation " did not throw " #exception_type _LOCATION, type, num); } catch (exception_type &e) {} } static_assert(true, "")
#define ASSERT_TYPE_THROWS(operation, exception_type, type) ASSERT_TYPE_NUM_THROWS(operation, exception_type, type, -1ULL)
#define ASSERT_THROWS(operation, exception_type) ASSERT_TYPE_THROWS(operation, exception_type, std::nullptr_t)
#define ASSERT(condition, ...) ASSERT_MSG((condition), "Condition (" #condition ") evaluated to false" _LOCATION, __VA_ARGS__)
#define ASSERT_MSG(condition, msg, ...) { if (!(condition)) return _ret_val_from_ctx<__VA_ARGS__>(ReturnCode::FAILED, msg); } static_assert(true, "")
#define ASSERT_THROWS(operation, exception_type, ...) if not consteval { try { operation; ASSERT_MSG(false, #operation " did not throw " #exception_type _LOCATION, __VA_ARGS__); } catch (exception_type &e) {} } static_assert(true, "")
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::ranges::range R, StringLike T>
constexpr bool all_equal_to(R r, T t) {
auto rt = std::ranges::views::repeat(std::string_view(t), std::ranges::size(r));
return std::ranges::equal(r, rt);
}
template<std::ranges::range R, typename T>
constexpr bool all_equal_to(R r, T t) {
auto rt = std::ranges::views::repeat(t, std::ranges::size(r));
return std::ranges::equal(r, rt);
}
template<std::input_iterator I, std::sentinel_for<I> S, StringLike T>
constexpr bool all_eq_to(I first, S last, T t) {
constexpr bool all_equal_to(I first, S last, T t) {
auto r1 = std::ranges::subrange(first, last);
auto r2 = std::ranges::views::repeat(std::string_view(t), std::ranges::distance(first, last));
return std::ranges::equal(r1, r2);
}
template<std::input_iterator I, std::sentinel_for<I> S, typename T>
constexpr bool all_eq_to(I first, S last, T t) {
constexpr bool all_equal_to(I first, S last, T t) {
auto r1 = std::ranges::subrange(first, last);
auto r2 = std::ranges::views::repeat(t, std::ranges::distance(first, last));
return std::ranges::equal(r1, r2);
@ -112,6 +104,9 @@ struct to_type_hint_str {
static constexpr const char *value = nullptr;
};
template<typename T>
constexpr const char *to_type_hint_str_v = to_type_hint_str::value<T>;
ADD_TYPE_HINT(bool);
ADD_TYPE_HINT(int);
ADD_TYPE_HINT(char);
@ -154,17 +149,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 +186,115 @@ 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>;
}
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 >[]
template<typename ctx>
requires std::is_same_v<ctx, ctx_tn<typename ctx::type, ctx::nr>>
constexpr ret_val_s _ret_val_from_ctx(ReturnCode ret, const char *msg = nullptr) {
return ret_val_s {"", ret, msg, to_type_hint_str_v<typename ctx::type>, ctx::nr };
}
template<typename ctx>
requires std::is_same_v<ctx, ctx_t<typename ctx::type>>
constexpr ret_val_s _ret_val_from_ctx(ReturnCode ret, const char *msg = nullptr) {
return ret_val_s {"", ret, msg, to_type_hint_str_v<typename ctx::type> };
}
template<typename ctx>
requires std::is_same_v<ctx, ctx_n<ctx::nr>>
constexpr ret_val_s _ret_val_from_ctx(ReturnCode ret, const char *msg = nullptr) {
return ret_val_s {"", ret, msg, nullptr, ctx::nr };
}
template<typename ctx = void>
constexpr ret_val_s _ret_val_from_ctx(ReturnCode ret, const char *msg = nullptr) {
return ret_val_s {"", ret, msg };
}
#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 >[]
class test_definition {
@ -444,30 +512,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, ...) { \
@ -487,12 +545,12 @@ constexpr auto _repeat_for_types_n(auto f) {
} static_assert(true, "")
#define CREATE_FROM_IL(type, il, len) \
([]<std::size_t N, typename ArgType>(std::initializer_list<ArgType> args) { \
([]<std::size_t _N, typename ArgType>(std::initializer_list<ArgType> args) { \
auto creator = [&args] <std::size_t ..._idx> (std::index_sequence<_idx...>) { \
return type { (*std::next(std::begin(args), _idx))... }; \
}; \
return creator(std::make_index_sequence<N>()); \
}).operator()<len>(il)
return creator(std::make_index_sequence<_N>()); \
}).template operator()<len>(il)
#define OPERATOR_EQ_IL(obj, il, len) \
([&]<std::size_t N, typename ArgType>(std::initializer_list<ArgType> args) { \

View File

@ -3,24 +3,26 @@
#include <test.hpp>
#include "test_params.h"
#include <vector>
constexpr test_suite tests = define_tests("Assignment")
("const_vector::operator=(const const_vector& other)", []() constexpr {
REPEAT_FOR_TYPES_N(([]<typename T, std::size_t N, typename Ctx>() {
REPEAT_FOR_TYPES_N(([]<typename T, std::size_t N, typename ctx>() {
cc::const_vector original(Ctx::template value<"arr">);
cc::const_vector original(get_test_param<ctx, "arr">());
decltype(original) v1;
cc::const_vector<T, get_test_param<"capacity">()> v2;
cc::const_vector<T, c_arr_len(Ctx::template value<"arr">) - 1> too_small;
cc::const_vector<T, get_test_param<ctx, "capacity">()> v2;
cc::const_vector<T, c_arr_len(get_test_param<ctx, "arr">()) - 1> too_small;
v1 = original;
v2 = original;
ASSERT_TYPE_NUM_THROWS((too_small = original), std::invalid_argument, T, N);
ASSERT_THROWS((too_small = original), std::invalid_argument, ctx);
ASSERT_TYPE_NUM(std::ranges::equal(v1, Ctx::template value<"arr">), T, N);
ASSERT_TYPE_NUM(std::ranges::equal(v2, Ctx::template value<"arr">), T, N);
ASSERT_TYPE_NUM(std::ranges::equal(original, Ctx::template value<"arr">), T, N);
ASSERT(std::ranges::equal(v1, get_test_param<ctx, "arr">()), ctx);
ASSERT(std::ranges::equal(v2, get_test_param<ctx, "arr">()), ctx);
ASSERT(std::ranges::equal(original, get_test_param<ctx, "arr">()), ctx);
return TEST_PASS();
}), 2, int, char, const char *, TestObj);
@ -29,22 +31,22 @@ constexpr test_suite tests = define_tests("Assignment")
}, EvalFlag::RUNTIME_CONSTEVAL)
("const_vector::operator=(const_vector&& other)", []() constexpr {
REPEAT_FOR_TYPES_N(([]<typename T, std::size_t N, typename Ctx>() {
REPEAT_FOR_TYPES_N(([]<typename T, std::size_t N, typename ctx>() {
cc::const_vector original1(Ctx::template value<"arr">);
cc::const_vector original2(Ctx::template value<"arr">);
cc::const_vector original3(Ctx::template value<"arr">);
cc::const_vector original1(get_test_param<ctx, "arr">());
cc::const_vector original2(get_test_param<ctx, "arr">());
cc::const_vector original3(get_test_param<ctx, "arr">());
decltype(original1) v1;
cc::const_vector<T, test_params<"capacity", Ctx>> v2;
cc::const_vector<T, c_arr_len(Ctx::template value<"arr">) - 1> too_small;
cc::const_vector<T, get_test_param<ctx, "capacity">()> v2;
cc::const_vector<T, c_arr_len(get_test_param<ctx, "arr">()) - 1> too_small;
v1 = force_move(original1);
v2 = force_move(original2);
ASSERT_TYPE_NUM_THROWS((too_small = force_move(original3)), std::invalid_argument, T, N);
ASSERT_THROWS((too_small = force_move(original3)), std::invalid_argument, ctx);
ASSERT_TYPE_NUM(std::ranges::equal(v1, Ctx::template value<"arr">), T, N);
ASSERT_TYPE_NUM(std::ranges::equal(v2, Ctx::template value<"arr">), T, N);
ASSERT(std::ranges::equal(v1, get_test_param<ctx, "arr">()), ctx);
ASSERT(std::ranges::equal(v2, get_test_param<ctx, "arr">()), ctx);
return TEST_PASS();
}), 2, int, char, const char *, TestObj);
@ -53,22 +55,22 @@ constexpr test_suite tests = define_tests("Assignment")
}, EvalFlag::RUNTIME_CONSTEVAL)
("const_vector::operator=(const value_type (&array)[])", []() constexpr {
REPEAT_FOR_TYPES_N(([]<typename T, std::size_t N, typename Ctx>() {
REPEAT_FOR_TYPES_N(([]<typename T, std::size_t N, typename ctx>() {
std::remove_cvref_t<decltype(Ctx::template value<"arr">)> arr = {};
std::copy(std::begin(Ctx::template value<"arr">), std::end(Ctx::template value<"arr">), std::begin(arr));
std::remove_cvref_t<decltype(get_test_param<ctx, "arr">())> arr = {};
std::copy(std::begin(get_test_param<ctx, "arr">()), std::end(get_test_param<ctx, "arr">()), std::begin(arr));
cc::const_vector<T, c_arr_len(arr)> v1;
cc::const_vector<T, test_params<"capacity", Ctx>> v2;
cc::const_vector<T, c_arr_len(Ctx::template value<"arr">) - 1> too_small;
cc::const_vector<T, get_test_param<ctx, "capacity">()> v2;
cc::const_vector<T, c_arr_len(get_test_param<ctx, "arr">()) - 1> too_small;
v1 = arr;
v2 = arr;
ASSERT_TYPE_NUM_THROWS((too_small = arr), std::invalid_argument, T, N);
ASSERT_THROWS((too_small = arr), std::invalid_argument, ctx);
ASSERT_TYPE_NUM(std::ranges::equal(v1, Ctx::template value<"arr">), T, N);
ASSERT_TYPE_NUM(std::ranges::equal(v2, Ctx::template value<"arr">), T, N);
ASSERT_TYPE_NUM(std::ranges::equal(arr, Ctx::template value<"arr">), T, N);
ASSERT(std::ranges::equal(v1, get_test_param<ctx, "arr">()), ctx);
ASSERT(std::ranges::equal(v2, get_test_param<ctx, "arr">()), ctx);
ASSERT(std::ranges::equal(arr, get_test_param<ctx, "arr">()), ctx);
return TEST_PASS();
}), 2, int, char, const char *, TestObj);
@ -77,18 +79,18 @@ constexpr test_suite tests = define_tests("Assignment")
}, EvalFlag::RUNTIME_CONSTEVAL)
("const_vector::operator=(std::initializer_list<value_type> values)", []() constexpr {
REPEAT_FOR_TYPES_N(([]<typename T, std::size_t N, typename Ctx>() {
REPEAT_FOR_TYPES_N(([]<typename T, std::size_t N, typename ctx>() {
cc::const_vector<T, test_params<"ilist", Ctx>.size()> v1;
cc::const_vector<T, test_params<"capacity", Ctx>> v2;
cc::const_vector<T, test_params<"ilist", Ctx>.size() - 1> too_small;
cc::const_vector<T, get_test_param<ctx, "ilist">().size()> v1;
cc::const_vector<T, get_test_param<ctx, "capacity">()> v2;
cc::const_vector<T, get_test_param<ctx, "ilist">().size() - 1> too_small;
v1 = test_params<"ilist", Ctx>;
v2 = test_params<"ilist", Ctx>;
ASSERT_TYPE_NUM_THROWS((too_small = test_params<"ilist", Ctx>), std::invalid_argument, T, N);
v1 = get_test_param<ctx, "ilist">();
v2 = get_test_param<ctx, "ilist">();
ASSERT_THROWS((too_small = get_test_param<ctx, "ilist">()), std::invalid_argument, ctx);
ASSERT_TYPE_NUM(std::ranges::equal(v1, test_params<"ilist", Ctx>), T, N);
ASSERT_TYPE_NUM(std::ranges::equal(v2, test_params<"ilist", Ctx>), T, N);
ASSERT(std::ranges::equal(v1, get_test_param<ctx, "ilist">()), ctx);
ASSERT(std::ranges::equal(v2, get_test_param<ctx, "ilist">()), ctx);
return TEST_PASS();
}), 2, int, char, const char *, TestObj);
@ -98,12 +100,12 @@ constexpr test_suite tests = define_tests("Assignment")
("const_vector::assign(size_type count, const value_type& value)", []() constexpr {
REPEAT_FOR_TYPES_N(([]<typename T, std::size_t N, typename Ctx>() constexpr {
REPEAT_FOR_TYPES_N(([]<typename T, std::size_t N, typename ctx>() constexpr {
std::remove_cvref_t<decltype(test_params<"value", Ctx>)> value = test_params<"value", Ctx>;
auto value = make_copy(get_test_param<ctx, "value">());
cc::const_vector v1(test_params<"arr", Ctx>);
cc::const_vector v2(test_params<"arr", Ctx>);
cc::const_vector v1(get_test_param<ctx, "arr">());
cc::const_vector v2(get_test_param<ctx, "arr">());
auto count1 = v1.size();
auto count2 = v2.size() / 2;
@ -111,68 +113,65 @@ constexpr test_suite tests = define_tests("Assignment")
v1.assign(count1, value);
v2.assign(count2, value);
ASSERT_TYPE_NUM(v1.size() == count1, T, N);
ASSERT_TYPE_NUM(v2.size() == count2, T, N);
ASSERT_TYPE_NUM(std::ranges::all_of(v1, [value](auto&& e) { return e == value; }), T, N);
ASSERT_TYPE_NUM(std::ranges::all_of(v1, [value](auto&& e) { return e == value; }), T, N);
ASSERT(v1.size() == count1, ctx);
ASSERT(v2.size() == count2, ctx);
ASSERT(std::ranges::all_of(v1, [value](auto&& e) { return e == value; }), ctx);
ASSERT(std::ranges::all_of(v1, [value](auto&& e) { return e == value; }), ctx);
ASSERT_TYPE_NUM((value == test_params<"value", Ctx>), T, N);
ASSERT((value == get_test_param<ctx, "value">()), ctx);
return TEST_PASS();
}), 2, int, char, const char*, TestObj);
return TEST_PASS();
}, EvalFlag::RUNTIME_CONSTEVAL)
/*("const_vector::assign(InputIt first, InputIt last)", []() constexpr {
("const_vector::assign(InputIt first, InputIt last)", []() constexpr {
REPEAT_FOR_TYPES_N(([]<typename T, std::size_t n, typename params>() constexpr {
constexpr std::size_t N = n+1;
cc::const_vector<T, test_defs::get<T>::template arr_len<N>()> v1;
cc::const_vector<T, test_defs::get<T>::template il_len<N>()> v2;
cc::const_vector<T, test_defs::get<T>::template il_len<N>()> v3;
cc::const_vector<T, test_defs::get<T>::template arr_len<N>() - 1> v4;
REPEAT_FOR_TYPES_N(([]<typename T, std::size_t N, typename ctx>() constexpr {
std::vector<T> container = test_defs::get<T>::template i_list<N>;
cc::const_vector<T, c_arr_len(get_test_param<ctx, "arr">())> v1;
cc::const_vector<T, get_test_param<ctx, "capacity">()> v2;
cc::const_vector<T, get_test_param<ctx, "ilist">().size()> v3;
cc::const_vector<T, c_arr_len(get_test_param<ctx, "arr">()) - 1> too_small;
v1.assign(std::begin(test_defs::get<T>::template arr<N>), std::end(test_defs::get<T>::template arr<N>));
v2.assign(container.begin(), container.end());
v3.assign(container.begin(), std::next(container.begin(), test_defs::get<T>::template il_len<N>() / 2));
std::vector container = get_test_param<ctx, "ilist">();
ASSERT_TYPE_NUM_THROWS(
(v4.assign(std::begin(test_defs::get<T>::template arr<N>),
std::end(test_defs::get<T>::template arr<N>))), std::invalid_argument, T, N);
v1.assign(std::begin(get_test_param<ctx, "arr">()), std::end(get_test_param<ctx, "arr">()));
v2.assign(std::begin(get_test_param<ctx, "arr">()), std::end(get_test_param<ctx, "arr">()));
v3.assign(container.begin(), container.end());
ASSERT_TYPE_NUM_VEC_ARR_EQ(v1, test_defs::get<T>::template arr<N>, T, N);
ASSERT_TYPE_NUM(v1.size() == test_defs::get<T>::template arr_len<N>(), T, N);
ASSERT_TYPE_NUM_VEC_ARR_EQ(v2, container, T, N);
ASSERT_TYPE_NUM(v2.size() == container.size(), T, N);
ASSERT_TYPE_NUM_VEC_ARR_EQ(v3, container, T, N);
ASSERT_TYPE_NUM(v3.size() == container.size() / 2, T, N);
ASSERT_THROWS(
(too_small.assign(std::begin(get_test_param<ctx, "arr">()),
std::end(get_test_param<ctx, "arr">()))), std::invalid_argument, ctx);
return TEST_PASS();
}), 3, int, char, const char *, TestStruct);
return TEST_PASS();
}, EvalFlag::RUNTIME_CONSTEVAL)
("const_vector::assign(std::initializer_list<value_type> values)", []() constexpr {
REPEAT_FOR_TYPES_N(([]<typename T, std::size_t N, typename Ctx>() constexpr {
cc::const_vector<T, (test_params<"ilist", Ctx>).size()> v1;
cc::const_vector<T, (test_params<"ilist", Ctx>).size() - 1> v2;
v1.assign(test_params<"ilist", Ctx>);
ASSERT_TYPE_NUM_VEC_ARR_EQ(v1, (test_params<"ilist", Ctx>), T, N);
ASSERT_TYPE_NUM((v1.size() == test_params<"ilist", Ctx>.size()), T, N);
ASSERT_TYPE_NUM_THROWS(v2.assign(test_params<"ilist", Ctx>), std::invalid_argument, T, N);
ASSERT(std::ranges::equal(v1, get_test_param<ctx, "arr">()), ctx);
ASSERT(std::ranges::equal(v2, get_test_param<ctx, "arr">()), ctx);
ASSERT(std::ranges::equal(v3, container), ctx);
ASSERT(std::ranges::equal(container, get_test_param<ctx, "ilist">()), ctx);
return TEST_PASS();
}), 2, int, char, const char *, TestObj);
return TEST_PASS();
}, EvalFlag::RUNTIME_CONSTEVAL)*/;
}, EvalFlag::RUNTIME_CONSTEVAL)
("const_vector::assign(std::initializer_list<value_type> values)", []() constexpr {
REPEAT_FOR_TYPES_N(([]<typename T, std::size_t N, typename ctx>() constexpr {
cc::const_vector<T, get_test_param<ctx, "ilist">().size()> v;
cc::const_vector<T, get_test_param<ctx, "ilist">().size() - 1> too_small;
v.assign(get_test_param<ctx, "ilist">());
ASSERT(std::ranges::equal(v, get_test_param<ctx, "ilist">()), ctx);
ASSERT_THROWS(too_small.assign(get_test_param<ctx, "ilist">()), std::invalid_argument, ctx);
return TEST_PASS();
}), 2, int, char, const char *, TestObj);
return TEST_PASS();
}, EvalFlag::RUNTIME_CONSTEVAL);
int main() {
return tests.run();

View File

@ -1,678 +1,165 @@
#pragma clang diagnostic push
#pragma ide diagnostic ignored "readability-container-size-empty"
#include <const_vector.hpp>
#include "test.hpp"
#include "test_params.h"
#include "test_args.h"
#include <vector>
#define ASSERT_TYPE_NUM_ALL_VEC_EQ(vec, eq, type, num) ASSERT_TYPE_NUM_ALL_EQ((vec).begin(), (vec).end(), eq, type, num)
#define ASSERT_TYPE_NUM_RANGE_VEC_EQ(vec, startI, endI, eq, type, num) ASSERT_TYPE_NUM_ALL_EQ(((vec).data() + startI), ((vec).data() + endI), eq, type, num)
#define ASSERT_TYPE_NUM_VEC_ARR_EQ(vec, eq, type, num) ASSERT_TYPE_NUM_C_ARR_EQ((vec).data(), (vec).data() + (vec).size(), std::begin(eq), type, num)
#define ASSERT_TYPE_NUM_VEC_EQ(vec1, vec2, type, num) ASSERT_TYPE_NUM_C_ARR_EQ((vec1).data(), (vec1).data() + (vec1).size(), (vec2).data(), type, num)
#define ASSERT_TYPE_NUM_RANGE_VEC_ARR_EQ(vec, startI, endI, eq, type, num) ASSERT_TYPE_NUM_C_ARR_EQ(((vec).begin() + startI), ((vec).begin() + endI), std::begin(eq), type, num)
#define ASSERT_TYPE_ALL_VEC_EQ(vec, eq, type) ASSERT_TYPE_ALL_EQ((vec).begin(), (vec).end(), eq, type)
#define ASSERT_TYPE_RANGE_VEC_EQ(vec, startI, endI, eq, type) ASSERT_TYPE_ALL_EQ(((vec).data() + startI), ((vec).data() + endI), eq, type)
#define ASSERT_TYPE_VEC_ARR_EQ(vec, eq, type) ASSERT_TYPE_C_ARR_EQ((vec).data(), (vec).data() + (vec).size(), std::begin(eq), type)
#define ASSERT_TYPE_VEC_EQ(vec1, vec2, type) ASSERT_TYPE_C_ARR_EQ((vec1).data(), (vec1).data() + (vec1).size(), (vec2).data(), type)
#define ASSERT_TYPE_RANGE_VEC_ARR_EQ(vec, startI, endI, eq, type) ASSERT_TYPE_C_ARR_EQ(((vec).begin() + startI), ((vec).begin() + endI), std::begin(eq), type)
#define ASSERT_ALL_VEC_EQ(vec, eq) ASSERT_TYPE_ALL_VEC_EQ(vec, eq, std::nullptr_t)
#define ASSERT_RANGE_VEC_EQ(vec, startI, endI, eq) ASSERT_TYPE_RANGE_VEC_EQ(vec, startI, endI, eq, std::nullptr_t)
#define ASSERT_VEC_ARR_EQ(vec, eq) ASSERT_TYPE_VEC_ARR_EQ(vec, eq, std::nullptr_t)
#define ASSERT_VEC_EQ(vec1, vec2) ASSERT_TYPE_VEC_EQ(vec1, vec2, std::nullptr_t)
#define ASSERT_RANGE_VEC_ARR_EQ(vec, startI, endI, eq) ASSERT_TYPE_RANGE_VEC_ARR_EQ(vec, startI, endI, eq, std::nullptr_t)
constexpr test_suite tests = define_tests("Constructors")
("const_vector()", []() constexpr {
cc::const_vector<int, test_defs::get<int>::capacity<1>()> vi1;
cc::const_vector<int, test_defs::get<int>::capacity<2>()> vi2;
REPEAT_FOR_TYPES_N(([]<typename T, std::size_t N, typename ctx>() constexpr {
ASSERT(vi1.capacity() == test_defs::get<int>::capacity<1>());
ASSERT(vi2.capacity() == test_defs::get<int>::capacity<2>());
ASSERT(vi1.size() == 0);
ASSERT(vi2.size() == 0);
ASSERT(vi1.empty());
ASSERT(vi2.empty());
ASSERT_ALL_VEC_EQ(vi1, int());
ASSERT_ALL_VEC_EQ(vi2, int());
cc::const_vector<T, get_test_param<ctx, "capacity">()> v;
ASSERT((v.capacity() == get_test_param<ctx, "capacity">()), ctx);
ASSERT(v.empty(), ctx);
cc::const_vector<char, test_defs::get<char>::capacity<1>()> vc1;
cc::const_vector<char, test_defs::get<char>::capacity<2>()> vc2;
ASSERT(vc1.capacity() == test_defs::get<char>::capacity<1>());
ASSERT(vc2.capacity() == test_defs::get<char>::capacity<2>());
ASSERT(vc1.size() == 0);
ASSERT(vc2.size() == 0);
ASSERT(vc1.empty());
ASSERT(vc2.empty());
ASSERT_ALL_VEC_EQ(vc1, char());
ASSERT_ALL_VEC_EQ(vc2, char());
cc::const_vector<const char *, test_defs::get<const char*>::capacity<1>()> vs1;
cc::const_vector<const char *, test_defs::get<const char*>::capacity<2>()> vs2;
ASSERT(vs1.capacity() == test_defs::get<const char*>::capacity<1>());
ASSERT(vs2.capacity() == test_defs::get<const char*>::capacity<2>());
ASSERT(vs1.size() == 0);
ASSERT(vs2.size() == 0);
ASSERT(vs1.empty());
ASSERT(vs2.empty());
cc::const_vector<TestStruct, test_defs::get<TestStruct>::capacity<1>()> vo1;
cc::const_vector<TestStruct, test_defs::get<TestStruct>::capacity<2>()> vo2;
ASSERT(vo1.capacity() == test_defs::get<TestStruct>::capacity<1>());
ASSERT(vo2.capacity() == test_defs::get<TestStruct>::capacity<2>());
ASSERT(vo1.size() == 0);
ASSERT(vo2.size() == 0);
ASSERT(vo1.empty());
ASSERT(vo2.empty());
ASSERT_ALL_VEC_EQ(vo1, TestStruct{});
ASSERT_ALL_VEC_EQ(vo2, TestStruct{});
return TEST_PASS();
}, EvalFlag::RUNTIME_CONSTEVAL)
("const_vector(T &value)", []() constexpr {
cc::const_vector<int, test_defs::get<int>::capacity<1>()> vi1(test_defs::get<int>::value<1>());
cc::const_vector<int, test_defs::get<int>::capacity<2>()> vi2(test_defs::get<int>::value<2>());
ASSERT(vi1.capacity() == test_defs::get<int>::capacity<1>());
ASSERT(vi2.capacity() == test_defs::get<int>::capacity<2>());
ASSERT(vi1.size() == test_defs::get<char>::capacity<1>());
ASSERT(vi2.size() == test_defs::get<char>::capacity<2>());
ASSERT_ALL_VEC_EQ(vi1, test_defs::get<int>::value<1>());
ASSERT_ALL_VEC_EQ(vi2, test_defs::get<int>::value<2>());
cc::const_vector<char, test_defs::get<char>::capacity<1>()> vc1(test_defs::get<char>::value<1>());
cc::const_vector<char, test_defs::get<char>::capacity<2>()> vc2(test_defs::get<char>::value<2>());
ASSERT(vc1.capacity() == test_defs::get<char>::capacity<1>());
ASSERT(vc2.capacity() == test_defs::get<char>::capacity<2>());
ASSERT(vc1.size() == test_defs::get<char>::capacity<1>());
ASSERT(vc2.size() == test_defs::get<char>::capacity<2>());
ASSERT_ALL_VEC_EQ(vc1, test_defs::get<char>::value<1>());
ASSERT_ALL_VEC_EQ(vc2, test_defs::get<char>::value<2>());
cc::const_vector<const char *, test_defs::get<const char *>::capacity<1>()> vs1(test_defs::get<const char *>::value<1>());
cc::const_vector<const char *, test_defs::get<const char *>::capacity<2>()> vs2(test_defs::get<const char *>::value<2>());
ASSERT(vs1.capacity() == test_defs::get<const char *>::capacity<1>());
ASSERT(vs2.capacity() == test_defs::get<const char *>::capacity<2>());
ASSERT(vs1.size() == test_defs::get<const char *>::capacity<1>());
ASSERT(vs2.size() == test_defs::get<const char *>::capacity<2>());
ASSERT_ALL_VEC_EQ(vs1, test_defs::get<const char *>::value<1>());
ASSERT_ALL_VEC_EQ(vs2, test_defs::get<const char *>::value<2>());
cc::const_vector<TestStruct, test_defs::get<TestStruct>::capacity<1>()> vo1(test_defs::get<TestStruct>::value<1>());
cc::const_vector<TestStruct, test_defs::get<TestStruct>::capacity<2>()> vo2(test_defs::get<TestStruct>::value<2>());
ASSERT(vo1.capacity() == test_defs::get<TestStruct>::capacity<1>());
ASSERT(vo2.capacity() == test_defs::get<TestStruct>::capacity<2>());
ASSERT(vo1.size() == test_defs::get<TestStruct>::capacity<1>());
ASSERT(vo2.size() == test_defs::get<TestStruct>::capacity<2>());
ASSERT_ALL_VEC_EQ(vo1, test_defs::get<TestStruct>::value<1>());
ASSERT_ALL_VEC_EQ(vo2, test_defs::get<TestStruct>::value<2>());
return TEST_PASS();
}), 2, int , char, const char *, TestObj);
return TEST_PASS();
}, EvalFlag::RUNTIME_CONSTEVAL)
("const_vector(size_type size, T &value)", []() constexpr {
cc::const_vector<int, test_defs::get<int>::capacity<1>()> vi1(test_defs::get<int>::size<1>(), test_defs::get<int>::value<1>());
cc::const_vector<int, test_defs::get<int>::capacity<2>()> vi2(test_defs::get<int>::size<2>(), test_defs::get<int>::value<2>());
REPEAT_FOR_TYPES_N(([]<typename T, std::size_t N, typename ctx>() constexpr {
ASSERT(vi1.capacity() == test_defs::get<int>::capacity<1>());
ASSERT(vi2.capacity() == test_defs::get<int>::capacity<2>());
ASSERT(vi1.size() == test_defs::get<int>::size<1>());
ASSERT(vi2.size() == test_defs::get<int>::size<2>());
ASSERT_RANGE_VEC_EQ(vi1, 0, test_defs::get<int>::size<1>(), test_defs::get<int>::value<1>());
ASSERT_RANGE_VEC_EQ(vi1, test_defs::get<int>::size<1>(), test_defs::get<int>::capacity<1>(), int());
ASSERT_RANGE_VEC_EQ(vi2, 0, test_defs::get<int>::size<2>(), test_defs::get<int>::value<2>());
ASSERT_RANGE_VEC_EQ(vi2, test_defs::get<int>::size<2>(), test_defs::get<int>::capacity<2>(), int());
cc::const_vector<T, get_test_param<ctx, "capacity">()> v1(get_test_param<ctx, "capacity">(), get_test_param<ctx, "value">());
cc::const_vector<T, get_test_param<ctx, "capacity">()> v2(get_test_param<ctx, "capacity">() / 2, get_test_param<ctx, "value">());
cc::const_vector<char, test_defs::get<int>::capacity<1>()> vc1(test_defs::get<int>::size<1>(), test_defs::get<char>::value<1>());
cc::const_vector<char, test_defs::get<int>::capacity<2>()> vc2(test_defs::get<int>::size<2>(), test_defs::get<char>::value<2>());
ASSERT(vc1.capacity() == test_defs::get<int>::capacity<1>());
ASSERT(vc2.capacity() == test_defs::get<int>::capacity<2>());
ASSERT(vc1.size() == test_defs::get<int>::size<1>());
ASSERT(vc2.size() == test_defs::get<int>::size<2>());
ASSERT_RANGE_VEC_EQ(vc1, 0, test_defs::get<int>::size<1>(), test_defs::get<char>::value<1>());
ASSERT_RANGE_VEC_EQ(vc1, test_defs::get<int>::size<1>(), test_defs::get<int>::capacity<1>(), char());
ASSERT_RANGE_VEC_EQ(vc2, 0, test_defs::get<int>::size<2>(), test_defs::get<char>::value<2>());
ASSERT_RANGE_VEC_EQ(vc2, test_defs::get<int>::size<2>(), test_defs::get<int>::capacity<2>(), char());
cc::const_vector<const char *, test_defs::get<int>::capacity<1>()> vs1(test_defs::get<int>::size<1>(), test_defs::get<const char *>::value<1>());
cc::const_vector<const char *, test_defs::get<int>::capacity<2>()> vs2(test_defs::get<int>::size<2>(), test_defs::get<const char *>::value<2>());
ASSERT(vs1.capacity() == test_defs::get<int>::capacity<1>());
ASSERT(vs2.capacity() == test_defs::get<int>::capacity<2>());
ASSERT(vs1.size() == test_defs::get<int>::size<1>());
ASSERT(vs2.size() == test_defs::get<int>::size<2>());
ASSERT_RANGE_VEC_EQ(vs1, 0, test_defs::get<int>::size<1>(), test_defs::get<const char *>::value<1>());
ASSERT_RANGE_VEC_EQ(vs2, 0, test_defs::get<int>::size<2>(), test_defs::get<const char *>::value<2>());
cc::const_vector<TestStruct, test_defs::get<int>::capacity<1>()> vo1(test_defs::get<int>::size<1>(), test_defs::get<TestStruct>::value<1>());
cc::const_vector<TestStruct, test_defs::get<int>::capacity<2>()> vo2(test_defs::get<int>::size<2>(), test_defs::get<TestStruct>::value<2>());
ASSERT(vo1.capacity() == test_defs::get<int>::capacity<1>());
ASSERT(vo2.capacity() == test_defs::get<int>::capacity<2>());
ASSERT(vo1.size() == test_defs::get<int>::size<1>());
ASSERT(vo2.size() == test_defs::get<int>::size<2>());
ASSERT_RANGE_VEC_EQ(vo1, 0, test_defs::get<int>::size<1>(), test_defs::get<TestStruct>::value<1>());
ASSERT_RANGE_VEC_EQ(vo1, test_defs::get<int>::size<1>(), test_defs::get<int>::capacity<1>(), TestStruct {});
ASSERT_RANGE_VEC_EQ(vo2, 0, test_defs::get<int>::size<2>(), test_defs::get<TestStruct>::value<2>());
ASSERT_RANGE_VEC_EQ(vo2, test_defs::get<int>::size<2>(), test_defs::get<int>::capacity<2>(), TestStruct {});
return TEST_PASS();
}, EvalFlag::RUNTIME_CONSTEVAL)
("const_vector(const value_type (&array)[N])", []() constexpr {
cc::const_vector vi1(test_defs::get<int>::arr<1>);
cc::const_vector vi2(test_defs::get<int>::arr<2>);
/*cc::const_vector<int, test_defs::get<int>::capacity<1>()> vi3(test_defs::get<int>::arr<1>);
cc::const_vector<int, test_defs::get<int>::capacity<2>()> vi4(test_defs::get<int>::arr<2>);*/
ASSERT(vi1.capacity() == test_defs::get<int>::arr_len<1>());
ASSERT(vi2.capacity() == test_defs::get<int>::arr_len<2>());
ASSERT(vi1.size() == test_defs::get<int>::arr_len<1>());
ASSERT(vi2.size() == test_defs::get<int>::arr_len<2>());
ASSERT_VEC_ARR_EQ(vi1, test_defs::get<int>::arr<1>);
ASSERT_VEC_ARR_EQ(vi2, test_defs::get<int>::arr<2>);
/*ASSERT(vi3.capacity() == test_defs::get<int>::capacity<1>());
ASSERT(vi4.capacity() == test_defs::get<int>::capacity<2>());
ASSERT(vi3.size() == test_defs::get<int>::arr_len<1>());
ASSERT(vi4.size() == test_defs::get<int>::arr_len<2>());
ASSERT_RANGE_VEC_ARR_EQ(vi3, 0, test_defs::get<int>::arr_len<1>(), test_defs::get<int>::arr<1>);
ASSERT_RANGE_VEC_EQ(vi3, test_defs::get<int>::arr_len<1>(), test_defs::get<int>::capacity<1>(), int());
ASSERT_RANGE_VEC_ARR_EQ(vi4, 0, test_defs::get<int>::arr_len<2>(), test_defs::get<int>::arr<2>);
ASSERT_RANGE_VEC_EQ(vi4, test_defs::get<int>::arr_len<2>(), test_defs::get<int>::capacity<2>(), int());*/
cc::const_vector vc1(test_defs::get<char>::arr<1>);
cc::const_vector vc2(test_defs::get<char>::arr<2>);
/*cc::const_vector<char, test_defs::get<int>::capacity<1>()> vc3(test_defs::get<char>::arr<1>);
cc::const_vector<char, test_defs::get<int>::capacity<2>()> vc4(test_defs::get<char>::arr<2>);*/
ASSERT(vc1.capacity() == test_defs::get<char>::arr_len<1>());
ASSERT(vc2.capacity() == test_defs::get<char>::arr_len<2>());
ASSERT(vc1.size() == test_defs::get<char>::arr_len<1>());
ASSERT(vc2.size() == test_defs::get<char>::arr_len<2>());
ASSERT_VEC_ARR_EQ(vc1, test_defs::get<char>::arr<1>);
ASSERT_VEC_ARR_EQ(vc2, test_defs::get<char>::arr<2>);
/*ASSERT(vc3.capacity() == test_defs::get<int>::capacity<1>());
ASSERT(vc4.capacity() == test_defs::get<int>::capacity<2>());
ASSERT(vc3.size() == test_defs::get<char>::arr_len<1>());
ASSERT(vc4.size() == test_defs::get<char>::arr_len<2>());
ASSERT_RANGE_VEC_ARR_EQ(vc3, 0, test_defs::get<char>::arr_len<1>(), test_defs::get<char>::arr<1>);
ASSERT_RANGE_VEC_EQ(vc3, test_defs::get<char>::arr_len<1>(), test_defs::get<int>::capacity<1>(), char());
ASSERT_RANGE_VEC_ARR_EQ(vc4, 0, test_defs::get<char>::arr_len<2>(), test_defs::get<char>::arr<2>);
ASSERT_RANGE_VEC_EQ(vc4, test_defs::get<char>::arr_len<2>(), test_defs::get<int>::capacity<2>(), char());*/
cc::const_vector vs1(test_defs::get<const char *>::arr<1>);
cc::const_vector vs2(test_defs::get<const char *>::arr<2>);
/*cc::const_vector<const char *, test_defs::get<int>::capacity<1>()> vs3(test_defs::get<const char *>::arr<1>);
cc::const_vector<const char *, test_defs::get<int>::capacity<2>()> vs4(test_defs::get<const char *>::arr<2>);*/
ASSERT(vs1.capacity() == test_defs::get<const char *>::arr_len<1>());
ASSERT(vs2.capacity() == test_defs::get<const char *>::arr_len<2>());
ASSERT(vs1.size() == test_defs::get<const char *>::arr_len<1>());
ASSERT(vs2.size() == test_defs::get<const char *>::arr_len<2>());
ASSERT_VEC_ARR_EQ(vs1, test_defs::get<const char *>::arr<1>);
ASSERT_VEC_ARR_EQ(vs2, test_defs::get<const char *>::arr<2>);
/*ASSERT(vs3.capacity() == test_defs::get<int>::capacity<1>());
ASSERT(vs4.capacity() == test_defs::get<int>::capacity<2>());
ASSERT(vs3.size() == test_defs::get<const char *>::arr_len<1>());
ASSERT(vs4.size() == test_defs::get<const char *>::arr_len<2>());
ASSERT_RANGE_VEC_ARR_EQ(vs3, 0, test_defs::get<const char *>::arr_len<1>(), test_defs::get<const char *>::arr<1>);
ASSERT_RANGE_VEC_ARR_EQ(vs4, 0, test_defs::get<const char *>::arr_len<2>(), test_defs::get<const char *>::arr<2>);*/
cc::const_vector vo1(test_defs::get<TestStruct>::arr<1>);
cc::const_vector vo2(test_defs::get<TestStruct>::arr<2>);
/*cc::const_vector<TestStruct, test_defs::get<int>::capacity<1>()> vo3(test_defs::get<TestStruct>::arr<1>);
cc::const_vector<TestStruct, test_defs::get<int>::capacity<2>()> vo4(test_defs::get<TestStruct>::arr<2>);*/
ASSERT(vo1.capacity() == test_defs::get<TestStruct>::arr_len<1>());
ASSERT(vo2.capacity() == test_defs::get<TestStruct>::arr_len<2>());
ASSERT(vo1.size() == test_defs::get<TestStruct>::arr_len<1>());
ASSERT(vo2.size() == test_defs::get<TestStruct>::arr_len<2>());
ASSERT_VEC_ARR_EQ(vo1, test_defs::get<TestStruct>::arr<1>);
ASSERT_VEC_ARR_EQ(vo2, test_defs::get<TestStruct>::arr<2>);
/*ASSERT(vo3.capacity() == test_defs::get<int>::capacity<1>());
ASSERT(vo4.capacity() == test_defs::get<int>::capacity<2>());
ASSERT(vo3.size() == test_defs::get<TestStruct>::arr_len<1>());
ASSERT(vo4.size() == test_defs::get<TestStruct>::arr_len<2>());
ASSERT_RANGE_VEC_ARR_EQ(vo3, 0, test_defs::get<TestStruct>::arr_len<1>(), test_defs::get<TestStruct>::arr<1>);
ASSERT_RANGE_VEC_EQ(vo3, test_defs::get<TestStruct>::arr_len<1>(), test_defs::get<int>::capacity<1>(), TestStruct {});
ASSERT_RANGE_VEC_ARR_EQ(vo4, 0, test_defs::get<TestStruct>::arr_len<2>(), test_defs::get<TestStruct>::arr<2>);
ASSERT_RANGE_VEC_EQ(vo4, test_defs::get<TestStruct>::arr_len<2>(), test_defs::get<int>::capacity<2>(), TestStruct {});*/
return TEST_PASS();
}, EvalFlag::RUNTIME_CONSTEVAL)
("const_vector(const value_type (&array)[N2])", []() constexpr {
REPEAT_FOR_TYPES_N(([]<typename T, std::size_t N, typename Ctx>() constexpr {
cc::const_vector<T, test_params<"arr", Ctx>::get_arr_len() + 1> v(test_context_params<T, N>::template value<"arr">);
ASSERT_TYPE_NUM((v.size() == test_params<"arr", Ctx>::get_arr_len()), T, N);
ASSERT_TYPE_NUM_RANGE_VEC_ARR_EQ(v, 0, (test_params<"arr", Ctx>::get_arr_len()), (test_context_params<T, N>::template value<"arr">), T, N);
ASSERT_TYPE_NUM_THROWS((cc::const_vector<T, test_params<"arr", Ctx>::get_arr_len() - 1>(test_context_params<T, N>::template value<"arr">)), std::invalid_argument, T, N);
ASSERT((v1.capacity() == get_test_param<ctx, "capacity">()), ctx);
ASSERT((v1.size() == get_test_param<ctx, "capacity">()), ctx);
ASSERT(all_equal_to(v1, get_test_param<ctx, "value">()), ctx);
ASSERT((v2.capacity() == get_test_param<ctx, "capacity">()), ctx);
ASSERT((v2.size() == get_test_param<ctx, "capacity">() / 2), ctx);
ASSERT(all_equal_to(v2, get_test_param<ctx, "value">()), ctx);
return TEST_PASS();
}), 2, int, char, const char *, TestObj);
}), 2, int , char, const char *, TestObj);
return TEST_PASS();
}, EvalFlag::RUNTIME_CONSTEVAL)
("const_vector(const value_type (&array)[])", []() constexpr {
REPEAT_FOR_TYPES_N(([]<typename T, std::size_t N, typename ctx>() constexpr {
std::remove_cvref_t<decltype(get_test_param<ctx, "arr">())> arr = {};
std::copy(std::begin(get_test_param<ctx, "arr">()), std::end(get_test_param<ctx, "arr">()), std::begin(arr));
cc::const_vector v1(arr);
cc::const_vector<T, c_arr_len(get_test_param<ctx, "arr">()) + 1> v2(arr);
ASSERT((v1.capacity() == c_arr_len(arr)), ctx);
ASSERT(std::ranges::equal(v1, arr), ctx); // also checks size
ASSERT((v2.capacity() == c_arr_len(arr) + 1), ctx);
ASSERT(std::ranges::equal(v2, arr), ctx);
ASSERT(std::ranges::equal(arr, get_test_param<ctx, "arr">()));
return TEST_PASS();
}), 2, int , char, const char *, TestObj);
return TEST_PASS();
}, EvalFlag::RUNTIME_CONSTEVAL)
("const_vector(std::initializer_list<value_type> list)", []() constexpr {
auto vi1 = CREATE_FROM_IL(cc::const_vector, test_defs::get<int>::i_list<1>, test_defs::get<int>::il_len<1>());
auto vi2 = CREATE_FROM_IL(cc::const_vector, test_defs::get<int>::i_list<2>, test_defs::get<int>::il_len<2>());
cc::const_vector<int, test_defs::get<int>::capacity<1>()> vi3(test_defs::get<int>::i_list<1>);
cc::const_vector<int, test_defs::get<int>::capacity<2>()> vi4(test_defs::get<int>::i_list<2>);
REPEAT_FOR_TYPES_N(([]<typename T, std::size_t N, typename ctx>() constexpr {
ASSERT_THROWS((CREATE_FROM_IL((cc::const_vector<int, test_defs::get<int>::il_len<1>() - 1>), test_defs::get<int>::i_list<1>, test_defs::get<int>::il_len<1>())), std::invalid_argument);
ASSERT_THROWS((CREATE_FROM_IL((cc::const_vector<int, test_defs::get<int>::il_len<2>() - 1>), test_defs::get<int>::i_list<2>, test_defs::get<int>::il_len<2>())), std::invalid_argument);
auto v1 = CREATE_FROM_IL(cc::const_vector, (get_test_param<ctx, "ilist">()), (get_test_param<ctx, "ilist">().size()));
auto v2 = CREATE_FROM_IL((cc::const_vector<T, get_test_param<ctx, "ilist">().size() + 1>), (get_test_param<ctx, "ilist">()), (get_test_param<ctx, "ilist">().size()));
ASSERT(vi1.capacity() == test_defs::get<int>::arr_len<1>());
ASSERT(vi2.capacity() == test_defs::get<int>::arr_len<2>());
ASSERT(vi1.size() == test_defs::get<int>::arr_len<1>());
ASSERT(vi2.size() == test_defs::get<int>::arr_len<2>());
ASSERT_VEC_ARR_EQ(vi1, test_defs::get<int>::i_list<1>);
ASSERT_VEC_ARR_EQ(vi2, test_defs::get<int>::i_list<2>);
ASSERT(vi3.capacity() == test_defs::get<int>::capacity<1>());
ASSERT(vi4.capacity() == test_defs::get<int>::capacity<2>());
ASSERT(vi3.size() == test_defs::get<int>::arr_len<1>());
ASSERT(vi4.size() == test_defs::get<int>::arr_len<2>());
ASSERT_RANGE_VEC_ARR_EQ(vi3, 0, test_defs::get<int>::arr_len<1>(), test_defs::get<int>::i_list<1>);
ASSERT_RANGE_VEC_EQ(vi3, test_defs::get<int>::arr_len<1>(), test_defs::get<int>::capacity<1>(), int());
ASSERT_RANGE_VEC_ARR_EQ(vi4, 0, test_defs::get<int>::arr_len<2>(), test_defs::get<int>::i_list<2>);
ASSERT_RANGE_VEC_EQ(vi4, test_defs::get<int>::arr_len<2>(), test_defs::get<int>::capacity<2>(), int());
ASSERT_THROWS(CREATE_FROM_IL(cc::const_vector, (get_test_param<ctx, "ilist">()), (get_test_param<ctx, "ilist">().size())), std::invalid_argument, ctx);
ASSERT((v1.capacity() == get_test_param<ctx, "ilist">().size()), ctx);
ASSERT((v1.size() == get_test_param<ctx, "ilist">().size()), ctx);
ASSERT(std::ranges::equal(v1, get_test_param<ctx, "ilist">()), ctx);
ASSERT((v2.capacity() == get_test_param<ctx, "ilist">().size() + 1), ctx);
ASSERT((v2.size() == get_test_param<ctx, "ilist">().size()), ctx);
ASSERT(std::ranges::equal(v2, get_test_param<ctx, "ilist">()), ctx);
auto vc1 = CREATE_FROM_IL(cc::const_vector, test_defs::get<char>::i_list<1>, test_defs::get<char>::il_len<1>());
auto vc2 = CREATE_FROM_IL(cc::const_vector, test_defs::get<char>::i_list<2>, test_defs::get<char>::il_len<2>());
cc::const_vector<char, test_defs::get<int>::capacity<1>()> vc3(test_defs::get<char>::i_list<1>);
cc::const_vector<char, test_defs::get<int>::capacity<2>()> vc4(test_defs::get<char>::i_list<2>);
ASSERT_THROWS((CREATE_FROM_IL((cc::const_vector<char, test_defs::get<char>::il_len<1>() - 1>), test_defs::get<char>::i_list<1>, test_defs::get<char>::il_len<1>())), std::invalid_argument);
ASSERT_THROWS((CREATE_FROM_IL((cc::const_vector<char, test_defs::get<char>::il_len<2>() - 1>), test_defs::get<char>::i_list<2>, test_defs::get<char>::il_len<2>())), std::invalid_argument);
ASSERT(vc1.capacity() == test_defs::get<char>::arr_len<1>());
ASSERT(vc2.capacity() == test_defs::get<char>::arr_len<2>());
ASSERT(vc1.size() == test_defs::get<char>::arr_len<1>());
ASSERT(vc2.size() == test_defs::get<char>::arr_len<2>());
ASSERT_VEC_ARR_EQ(vc1, test_defs::get<char>::i_list<1>);
ASSERT_VEC_ARR_EQ(vc2, test_defs::get<char>::i_list<2>);
ASSERT(vc3.capacity() == test_defs::get<int>::capacity<1>());
ASSERT(vc4.capacity() == test_defs::get<int>::capacity<2>());
ASSERT(vc3.size() == test_defs::get<char>::arr_len<1>());
ASSERT(vc4.size() == test_defs::get<char>::arr_len<2>());
ASSERT_RANGE_VEC_ARR_EQ(vc3, 0, test_defs::get<char>::arr_len<1>(), test_defs::get<char>::i_list<1>);
ASSERT_RANGE_VEC_EQ(vc3, test_defs::get<char>::arr_len<1>(), test_defs::get<int>::capacity<1>(), char());
ASSERT_RANGE_VEC_ARR_EQ(vc4, 0, test_defs::get<char>::arr_len<2>(), test_defs::get<char>::i_list<2>);
ASSERT_RANGE_VEC_EQ(vc4, test_defs::get<char>::arr_len<2>(), test_defs::get<int>::capacity<2>(), char());
auto vs1 = CREATE_FROM_IL(cc::const_vector, test_defs::get<const char*>::i_list<1>, test_defs::get<const char*>::il_len<1>());
auto vs2 = CREATE_FROM_IL(cc::const_vector, test_defs::get<const char*>::i_list<2>, test_defs::get<const char*>::il_len<2>());
cc::const_vector<const char *, test_defs::get<int>::capacity<1>()> vs3(test_defs::get<const char *>::i_list<1>);
cc::const_vector<const char *, test_defs::get<int>::capacity<2>()> vs4(test_defs::get<const char *>::i_list<2>);
ASSERT_THROWS((CREATE_FROM_IL((cc::const_vector<const char*, test_defs::get<const char*>::il_len<1>() - 1>), test_defs::get<const char*>::i_list<1>, test_defs::get<const char*>::il_len<1>())), std::invalid_argument);
ASSERT_THROWS((CREATE_FROM_IL((cc::const_vector<const char*, test_defs::get<const char*>::il_len<2>() - 1>), test_defs::get<const char*>::i_list<2>, test_defs::get<const char*>::il_len<2>())), std::invalid_argument);
ASSERT(vs1.capacity() == test_defs::get<const char *>::arr_len<1>());
ASSERT(vs2.capacity() == test_defs::get<const char *>::arr_len<2>());
ASSERT(vs1.size() == test_defs::get<const char *>::arr_len<1>());
ASSERT(vs2.size() == test_defs::get<const char *>::arr_len<2>());
ASSERT_VEC_ARR_EQ(vs1, test_defs::get<const char *>::i_list<1>);
ASSERT_VEC_ARR_EQ(vs2, test_defs::get<const char *>::i_list<2>);
ASSERT(vs3.capacity() == test_defs::get<int>::capacity<1>());
ASSERT(vs4.capacity() == test_defs::get<int>::capacity<2>());
ASSERT(vs3.size() == test_defs::get<const char *>::arr_len<1>());
ASSERT(vs4.size() == test_defs::get<const char *>::arr_len<2>());
ASSERT_RANGE_VEC_ARR_EQ(vs3, 0, test_defs::get<const char *>::arr_len<1>(), test_defs::get<const char *>::i_list<1>);
ASSERT_RANGE_VEC_ARR_EQ(vs4, 0, test_defs::get<const char *>::arr_len<2>(), test_defs::get<const char *>::i_list<2>);
auto vo1 = CREATE_FROM_IL(cc::const_vector, test_defs::get<TestStruct>::i_list<1>, test_defs::get<TestStruct>::il_len<1>());
auto vo2 = CREATE_FROM_IL(cc::const_vector, test_defs::get<TestStruct>::i_list<2>, test_defs::get<TestStruct>::il_len<2>());
cc::const_vector<TestStruct, test_defs::get<int>::capacity<1>()> vo3(test_defs::get<TestStruct>::i_list<1>);
cc::const_vector<TestStruct, test_defs::get<int>::capacity<2>()> vo4(test_defs::get<TestStruct>::i_list<2>);
ASSERT_THROWS((CREATE_FROM_IL((cc::const_vector<TestStruct, test_defs::get<TestStruct>::il_len<1>() - 1>), test_defs::get<TestStruct>::i_list<1>, test_defs::get<TestStruct>::il_len<1>())), std::invalid_argument);
ASSERT_THROWS((CREATE_FROM_IL((cc::const_vector<TestStruct, test_defs::get<TestStruct>::il_len<2>() - 1>), test_defs::get<TestStruct>::i_list<2>, test_defs::get<TestStruct>::il_len<2>())), std::invalid_argument);
ASSERT(vo1.capacity() == test_defs::get<TestStruct>::arr_len<1>());
ASSERT(vo2.capacity() == test_defs::get<TestStruct>::arr_len<2>());
ASSERT(vo1.size() == test_defs::get<TestStruct>::arr_len<1>());
ASSERT(vo2.size() == test_defs::get<TestStruct>::arr_len<2>());
ASSERT_VEC_ARR_EQ(vo1, test_defs::get<TestStruct>::i_list<1>);
ASSERT_VEC_ARR_EQ(vo2, test_defs::get<TestStruct>::i_list<2>);
ASSERT(vo3.capacity() == test_defs::get<int>::capacity<1>());
ASSERT(vo4.capacity() == test_defs::get<int>::capacity<2>());
ASSERT(vo3.size() == test_defs::get<TestStruct>::arr_len<1>());
ASSERT(vo4.size() == test_defs::get<TestStruct>::arr_len<2>());
ASSERT_RANGE_VEC_ARR_EQ(vo3, 0, test_defs::get<TestStruct>::arr_len<1>(), test_defs::get<TestStruct>::i_list<1>);
ASSERT_RANGE_VEC_EQ(vo3, test_defs::get<TestStruct>::arr_len<1>(), test_defs::get<int>::capacity<1>(), TestStruct {});
ASSERT_RANGE_VEC_ARR_EQ(vo4, 0, test_defs::get<TestStruct>::arr_len<2>(), test_defs::get<TestStruct>::i_list<2>);
ASSERT_RANGE_VEC_EQ(vo4, test_defs::get<TestStruct>::arr_len<2>(), test_defs::get<int>::capacity<2>(), TestStruct {});
return TEST_PASS();
}), 2, int , char, const char *, TestObj);
return TEST_PASS();
}, EvalFlag::RUNTIME_CONSTEVAL)
("const_vector(InputIt first, InputIt last)", []() constexpr {
cc::const_vector<int, test_defs::get<int>::capacity<1>()> vi1(std::begin(test_defs::get<int>::arr<1>), std::end(test_defs::get<int>::arr<1>));
cc::const_vector<int, test_defs::get<int>::capacity<2>()> vi2(std::begin(test_defs::get<int>::arr<2>), std::end(test_defs::get<int>::arr<2>));
cc::const_vector<int, test_defs::get<int>::capacity<1>()> vi3(std::begin(test_defs::get<int>::arr<1>), std::end(test_defs::get<int>::arr<1>));
cc::const_vector<int, test_defs::get<int>::capacity<2>()> vi4(std::begin(test_defs::get<int>::arr<2>), std::end(test_defs::get<int>::arr<2>));
REPEAT_FOR_TYPES_N(([]<typename T, std::size_t N, typename ctx>() constexpr {
ASSERT(vi1.capacity() == test_defs::get<int>::capacity<1>());
ASSERT(vi2.capacity() == test_defs::get<int>::capacity<2>());
ASSERT(vi1.size() == test_defs::get<int>::arr_len<1>());
ASSERT(vi2.size() == test_defs::get<int>::arr_len<2>());
ASSERT_RANGE_VEC_ARR_EQ(vi1, 0, test_defs::get<int>::arr_len<1>(), test_defs::get<int>::arr<1>);
ASSERT_RANGE_VEC_EQ(vi1, test_defs::get<int>::arr_len<1>(), test_defs::get<int>::capacity<1>(), int());
ASSERT_RANGE_VEC_ARR_EQ(vi2, 0, test_defs::get<int>::arr_len<2>(), test_defs::get<int>::arr<2>);
ASSERT_RANGE_VEC_EQ(vi2, test_defs::get<int>::arr_len<2>(), test_defs::get<int>::capacity<2>(), int());
ASSERT(vi3.capacity() == test_defs::get<int>::capacity<1>());
ASSERT(vi4.capacity() == test_defs::get<int>::capacity<2>());
ASSERT(vi3.size() == test_defs::get<int>::arr_len<1>());
ASSERT(vi4.size() == test_defs::get<int>::arr_len<2>());
ASSERT_RANGE_VEC_ARR_EQ(vi3, 0, test_defs::get<int>::arr_len<1>(), test_defs::get<int>::arr<1>);
ASSERT_RANGE_VEC_EQ(vi3, test_defs::get<int>::arr_len<1>(), test_defs::get<int>::capacity<1>(), int());
ASSERT_RANGE_VEC_ARR_EQ(vi4, 0, test_defs::get<int>::arr_len<2>(), test_defs::get<int>::arr<2>);
ASSERT_RANGE_VEC_EQ(vi4, test_defs::get<int>::arr_len<2>(), test_defs::get<int>::capacity<2>(), int());
std::vector container = get_test_param<ctx, "ilist">();
cc::const_vector<T, c_arr_len(get_test_param<ctx, "arr">())> v1(std::begin(get_test_param<ctx, "arr">()), std::end(get_test_param<ctx, "arr">()));
cc::const_vector<T, c_arr_len(get_test_param<ctx, "arr">()) + 1> v2(std::begin(get_test_param<ctx, "arr">()), std::end(get_test_param<ctx, "arr">()));
cc::const_vector<T, get_test_param<ctx, "ilist">().size()> v3(container.begin(), container.end());
cc::const_vector<T, get_test_param<ctx, "ilist">().size() + 1> v4(container.begin(), container.end());
cc::const_vector<char, test_defs::get<int>::capacity<1>()> vc1(std::begin(test_defs::get<char>::arr<1>), std::end(test_defs::get<char>::arr<1>));
cc::const_vector<char, test_defs::get<int>::capacity<2>()> vc2(std::begin(test_defs::get<char>::arr<2>), std::end(test_defs::get<char>::arr<2>));
cc::const_vector<char, test_defs::get<int>::capacity<1>()> vc3(std::begin(test_defs::get<char>::arr<1>), std::end(test_defs::get<char>::arr<1>));
cc::const_vector<char, test_defs::get<int>::capacity<2>()> vc4(std::begin(test_defs::get<char>::arr<2>), std::end(test_defs::get<char>::arr<2>));
ASSERT_THROWS((cc::const_vector<T, get_test_param<ctx, "ilist">().size() - 1>(get_test_param<ctx, "ilist">())), std::invalid_argument, ctx);
ASSERT(vc1.capacity() == test_defs::get<int>::capacity<1>());
ASSERT(vc2.capacity() == test_defs::get<int>::capacity<2>());
ASSERT(vc1.size() == test_defs::get<char>::arr_len<1>());
ASSERT(vc2.size() == test_defs::get<char>::arr_len<2>());
ASSERT_RANGE_VEC_ARR_EQ(vc1, 0, test_defs::get<char>::arr_len<1>(), test_defs::get<char>::arr<1>);
ASSERT_RANGE_VEC_EQ(vc1, test_defs::get<char>::arr_len<1>(), test_defs::get<int>::capacity<1>(), char());
ASSERT_RANGE_VEC_ARR_EQ(vc2, 0, test_defs::get<char>::arr_len<2>(), test_defs::get<char>::arr<2>);
ASSERT_RANGE_VEC_EQ(vc2, test_defs::get<char>::arr_len<2>(), test_defs::get<int>::capacity<2>(), char());
ASSERT(vc3.capacity() == test_defs::get<int>::capacity<1>());
ASSERT(vc4.capacity() == test_defs::get<int>::capacity<2>());
ASSERT(vc3.size() == test_defs::get<char>::arr_len<1>());
ASSERT(vc4.size() == test_defs::get<char>::arr_len<2>());
ASSERT_RANGE_VEC_ARR_EQ(vc3, 0, test_defs::get<char>::arr_len<1>(), test_defs::get<char>::arr<1>);
ASSERT_RANGE_VEC_EQ(vc3, test_defs::get<char>::arr_len<1>(), test_defs::get<int>::capacity<1>(), char());
ASSERT_RANGE_VEC_ARR_EQ(vc4, 0, test_defs::get<char>::arr_len<2>(), test_defs::get<char>::arr<2>);
ASSERT_RANGE_VEC_EQ(vc4, test_defs::get<char>::arr_len<2>(), test_defs::get<int>::capacity<2>(), char());
ASSERT((v1.capacity() == c_arr_len(get_test_param<ctx, "arr">())), ctx);
ASSERT((v1.size() == c_arr_len(get_test_param<ctx, "arr">())), ctx);
ASSERT(std::ranges::equal(v1, get_test_param<ctx, "arr">()), ctx);
ASSERT((v2.capacity() == c_arr_len(get_test_param<ctx, "arr">()) + 1), ctx);
ASSERT((v2.size() == c_arr_len(get_test_param<ctx, "arr">())), ctx);
ASSERT(std::ranges::equal(v2, get_test_param<ctx, "arr">()), ctx);
ASSERT((v3.capacity() == get_test_param<ctx, "ilist">().size()), ctx);
ASSERT((v3.size() == container.size()), ctx);
ASSERT(std::ranges::equal(v3, container), ctx);
ASSERT((v4.capacity() == get_test_param<ctx, "ilist">().size() + 1), ctx);
ASSERT((v4.size() == container.size()), ctx);
ASSERT(std::ranges::equal(v4, container), ctx);
cc::const_vector<const char *, test_defs::get<int>::capacity<1>()> vs1(std::begin(test_defs::get<const char *>::arr<1>), std::end(test_defs::get<const char *>::arr<1>));
cc::const_vector<const char *, test_defs::get<int>::capacity<2>()> vs2(std::begin(test_defs::get<const char *>::arr<2>), std::end(test_defs::get<const char *>::arr<2>));
cc::const_vector<const char *, test_defs::get<int>::capacity<1>()> vs3(std::begin(test_defs::get<const char *>::arr<1>), std::end(test_defs::get<const char *>::arr<1>));
cc::const_vector<const char *, test_defs::get<int>::capacity<2>()> vs4(std::begin(test_defs::get<const char *>::arr<2>), std::end(test_defs::get<const char *>::arr<2>));
ASSERT(std::ranges::equal(container, get_test_param<ctx, "ilist">()));
ASSERT(vs1.capacity() == test_defs::get<int>::capacity<1>());
ASSERT(vs2.capacity() == test_defs::get<int>::capacity<2>());
ASSERT(vs1.size() == test_defs::get<const char *>::arr_len<1>());
ASSERT(vs2.size() == test_defs::get<const char *>::arr_len<2>());
ASSERT_RANGE_VEC_ARR_EQ(vs1, 0, test_defs::get<const char *>::arr_len<1>(), test_defs::get<const char *>::arr<1>);
ASSERT_RANGE_VEC_ARR_EQ(vs2, 0, test_defs::get<const char *>::arr_len<2>(), test_defs::get<const char *>::arr<2>);
ASSERT(vs3.capacity() == test_defs::get<int>::capacity<1>());
ASSERT(vs4.capacity() == test_defs::get<int>::capacity<2>());
ASSERT(vs3.size() == test_defs::get<const char *>::arr_len<1>());
ASSERT(vs4.size() == test_defs::get<const char *>::arr_len<2>());
ASSERT_RANGE_VEC_ARR_EQ(vs3, 0, test_defs::get<const char *>::arr_len<1>(), test_defs::get<const char *>::arr<1>);
ASSERT_RANGE_VEC_ARR_EQ(vs4, 0, test_defs::get<const char *>::arr_len<2>(), test_defs::get<const char *>::arr<2>);
cc::const_vector<TestStruct, test_defs::get<int>::capacity<1>()> vo1(std::begin(test_defs::get<TestStruct>::arr<1>), std::end(test_defs::get<TestStruct>::arr<1>));
cc::const_vector<TestStruct, test_defs::get<int>::capacity<2>()> vo2(std::begin(test_defs::get<TestStruct>::arr<2>), std::end(test_defs::get<TestStruct>::arr<2>));
cc::const_vector<TestStruct, test_defs::get<int>::capacity<1>()> vo3(std::begin(test_defs::get<TestStruct>::arr<1>), std::end(test_defs::get<TestStruct>::arr<1>));
cc::const_vector<TestStruct, test_defs::get<int>::capacity<2>()> vo4(std::begin(test_defs::get<TestStruct>::arr<2>), std::end(test_defs::get<TestStruct>::arr<2>));
ASSERT(vo1.capacity() == test_defs::get<int>::capacity<1>());
ASSERT(vo2.capacity() == test_defs::get<int>::capacity<2>());
ASSERT(vo1.size() == test_defs::get<TestStruct>::arr_len<1>());
ASSERT(vo2.size() == test_defs::get<TestStruct>::arr_len<2>());
ASSERT_RANGE_VEC_ARR_EQ(vo1, 0, test_defs::get<TestStruct>::arr_len<1>(), test_defs::get<TestStruct>::arr<1>);
ASSERT_RANGE_VEC_EQ(vo1, test_defs::get<TestStruct>::arr_len<1>(), test_defs::get<int>::capacity<1>(), TestStruct {});
ASSERT_RANGE_VEC_ARR_EQ(vo2, 0, test_defs::get<TestStruct>::arr_len<2>(), test_defs::get<TestStruct>::arr<2>);
ASSERT_RANGE_VEC_EQ(vo2, test_defs::get<TestStruct>::arr_len<2>(), test_defs::get<int>::capacity<2>(), TestStruct {});
ASSERT(vo3.capacity() == test_defs::get<int>::capacity<1>());
ASSERT(vo4.capacity() == test_defs::get<int>::capacity<2>());
ASSERT(vo3.size() == test_defs::get<TestStruct>::arr_len<1>());
ASSERT(vo4.size() == test_defs::get<TestStruct>::arr_len<2>());
ASSERT_RANGE_VEC_ARR_EQ(vo3, 0, test_defs::get<TestStruct>::arr_len<1>(), test_defs::get<TestStruct>::arr<1>);
ASSERT_RANGE_VEC_EQ(vo3, test_defs::get<TestStruct>::arr_len<1>(), test_defs::get<int>::capacity<1>(), TestStruct {});
ASSERT_RANGE_VEC_ARR_EQ(vo4, 0, test_defs::get<TestStruct>::arr_len<2>(), test_defs::get<TestStruct>::arr<2>);
ASSERT_RANGE_VEC_EQ(vo4, test_defs::get<TestStruct>::arr_len<2>(), test_defs::get<int>::capacity<2>(), TestStruct {});
return TEST_PASS();
}), 2, int , char, const char *, TestObj);
return TEST_PASS();
}, EvalFlag::RUNTIME_CONSTEVAL)
("const_vector(const const_vector& other)", []() constexpr {
cc::const_vector vi1(test_defs::get<int>::arr<1>);
cc::const_vector vi2(test_defs::get<int>::arr<2>);
cc::const_vector vi1c(vi1);
cc::const_vector vi2c(vi2);
cc::const_vector<int, test_defs::get<int>::capacity<1>()> vi3(vi1);
cc::const_vector<int, test_defs::get<int>::capacity<2>()> vi4(vi2);
REPEAT_FOR_TYPES_N(([]<typename T, std::size_t N, typename ctx>() {
ASSERT(vi1c.capacity() == vi1.capacity());
ASSERT(vi2c.capacity() == vi2.capacity());
ASSERT(vi1c.size() == vi1.size());
ASSERT(vi2c.size() == vi2.size());
ASSERT_VEC_EQ(vi1c, vi1);
ASSERT_VEC_EQ(vi2c, vi2);
ASSERT(vi3.capacity() == test_defs::get<int>::capacity<1>());
ASSERT(vi4.capacity() == test_defs::get<int>::capacity<2>());
ASSERT(vi3.size() == vi1.size());
ASSERT(vi4.size() == vi2.size());
ASSERT_VEC_EQ(vi3, vi1);
ASSERT_VEC_EQ(vi4, vi2);
cc::const_vector original(get_test_param<ctx, "arr">());
cc::const_vector v1(original);
cc::const_vector<T, c_arr_len(get_test_param<ctx, "arr">()) + 1> v2(original);
cc::const_vector vc1(test_defs::get<char>::arr<1>);
cc::const_vector vc2(test_defs::get<char>::arr<2>);
cc::const_vector vc1c(vc1);
cc::const_vector vc2c(vc2);
cc::const_vector<char, test_defs::get<int>::capacity<1>()> vc3(vc1);
cc::const_vector<char, test_defs::get<int>::capacity<2>()> vc4(vc2);
ASSERT_THROWS((cc::const_vector<T, c_arr_len(get_test_param<ctx, "arr">()) - 1>(original)), std::invalid_argument, ctx);
ASSERT(vc1c.capacity() == vc1.capacity());
ASSERT(vc2c.capacity() == vc2.capacity());
ASSERT(vc1c.size() == vc1.size());
ASSERT(vc2c.size() == vc2.size());
ASSERT_VEC_EQ(vc1c, vc1);
ASSERT_VEC_EQ(vc2c, vc2);
ASSERT(vc3.capacity() == test_defs::get<int>::capacity<1>());
ASSERT(vc4.capacity() == test_defs::get<int>::capacity<2>());
ASSERT(vc3.size() == vc1.size());
ASSERT(vc4.size() == vc2.size());
ASSERT_VEC_EQ(vc3, vc1);
ASSERT_VEC_EQ(vc4, vc2);
ASSERT(std::ranges::equal(v1, original), ctx);
ASSERT(std::ranges::equal(v2, original), ctx);
ASSERT(std::ranges::equal(original, get_test_param<ctx, "arr">()), ctx);
cc::const_vector vs1(test_defs::get<const char *>::arr<1>);
cc::const_vector vs2(test_defs::get<const char *>::arr<2>);
cc::const_vector vs1c(vs1);
cc::const_vector vs2c(vs2);
cc::const_vector<const char *, test_defs::get<int>::capacity<1>()> vs3(vs1);
cc::const_vector<const char *, test_defs::get<int>::capacity<2>()> vs4(vs2);
ASSERT(vs1c.capacity() == vs1.capacity());
ASSERT(vs2c.capacity() == vs2.capacity());
ASSERT(vs1c.size() == vs1.size());
ASSERT(vs2c.size() == vs2.size());
ASSERT_VEC_EQ(vs1c, vs1);
ASSERT_VEC_EQ(vs2c, vs2);
ASSERT(vs3.capacity() == test_defs::get<int>::capacity<1>());
ASSERT(vs4.capacity() == test_defs::get<int>::capacity<2>());
ASSERT(vs3.size() == vs1.size());
ASSERT(vs4.size() == vs2.size());
ASSERT_VEC_EQ(vs3, vs1);
ASSERT_VEC_EQ(vs4, vs2);
cc::const_vector vo1(test_defs::get<TestStruct>::arr<1>);
cc::const_vector vo2(test_defs::get<TestStruct>::arr<2>);
cc::const_vector vo1c(vo1);
cc::const_vector vo2c(vo2);
cc::const_vector<TestStruct, test_defs::get<TestStruct>::capacity<1>()> vo3(vo1);
cc::const_vector<TestStruct, test_defs::get<TestStruct>::capacity<2>()> vo4(vo2);
ASSERT(vo1c.capacity() == vo1.capacity());
ASSERT(vo2c.capacity() == vo2.capacity());
ASSERT(vo1c.size() == vo1.size());
ASSERT(vo2c.size() == vo2.size());
ASSERT_VEC_EQ(vo1c, vo1);
ASSERT_VEC_EQ(vo2c, vo2);
ASSERT(vo3.capacity() == test_defs::get<int>::capacity<1>());
ASSERT(vo4.capacity() == test_defs::get<int>::capacity<2>());
ASSERT(vo3.size() == vo1.size());
ASSERT(vo4.size() == vo2.size());
ASSERT_VEC_EQ(vo3, vo1);
ASSERT_VEC_EQ(vo4, vo2);
return TEST_PASS();
}), 2, int, char, const char *, TestObj);
return TEST_PASS();
}, EvalFlag::RUNTIME_CONSTEVAL)
("const_vector(const_vector&& other)", []() constexpr {
cc::const_vector vi11(test_defs::get<int>::arr<1>);
cc::const_vector vi21(test_defs::get<int>::arr<2>);
cc::const_vector vi12(test_defs::get<int>::arr<1>);
cc::const_vector vi22(test_defs::get<int>::arr<2>);
cc::const_vector vi13(test_defs::get<int>::arr<1>);
cc::const_vector vi23(test_defs::get<int>::arr<2>);
cc::const_vector vi1(force_move(vi11));
cc::const_vector vi2(force_move(vi21));
cc::const_vector<int, test_defs::get<int>::capacity<1>()> vi3(force_move(vi12));
cc::const_vector<int, test_defs::get<int>::capacity<2>()> vi4(force_move(vi22));
ASSERT_THROWS((cc::const_vector<int, (test_defs::get<int>::arr_len<1>() - 1)>(force_move(vi13))), std::invalid_argument);
ASSERT_THROWS((cc::const_vector<int, (test_defs::get<int>::arr_len<2>() - 1)>(force_move(vi23))), std::invalid_argument);
REPEAT_FOR_TYPES_N(([]<typename T, std::size_t N, typename ctx>() {
ASSERT(vi1.capacity() == test_defs::get<int>::arr_len<1>());
ASSERT(vi2.capacity() == test_defs::get<int>::arr_len<2>());
ASSERT(vi1.size() == test_defs::get<int>::arr_len<1>());
ASSERT(vi2.size() == test_defs::get<int>::arr_len<2>());
ASSERT_VEC_ARR_EQ(vi1, test_defs::get<int>::arr<1>);
ASSERT_VEC_ARR_EQ(vi2, test_defs::get<int>::arr<2>);
ASSERT(vi3.capacity() == test_defs::get<int>::capacity<1>());
ASSERT(vi4.capacity() == test_defs::get<int>::capacity<2>());
ASSERT(vi3.size() == test_defs::get<int>::arr_len<1>());
ASSERT(vi4.size() == test_defs::get<int>::arr_len<2>());
ASSERT_VEC_ARR_EQ(vi3, test_defs::get<int>::arr<1>);
ASSERT_VEC_ARR_EQ(vi4, test_defs::get<int>::arr<2>);
cc::const_vector original1(get_test_param<ctx, "arr">());
cc::const_vector original2(get_test_param<ctx, "arr">());
cc::const_vector original3(get_test_param<ctx, "arr">());
cc::const_vector vc11(test_defs::get<char>::arr<1>);
cc::const_vector vc21(test_defs::get<char>::arr<2>);
cc::const_vector vc12(test_defs::get<char>::arr<1>);
cc::const_vector vc22(test_defs::get<char>::arr<2>);
cc::const_vector vc13(test_defs::get<char>::arr<1>);
cc::const_vector vc23(test_defs::get<char>::arr<2>);
cc::const_vector vc1(force_move(vc11));
cc::const_vector vc2(force_move(vc21));
cc::const_vector<char, test_defs::get<char>::capacity<1>()> vc3(force_move(vc12));
cc::const_vector<char, test_defs::get<char>::capacity<2>()> vc4(force_move(vc22));
decltype(original1) v1(force_move(original1));
cc::const_vector<T, get_test_param<ctx, "capacity">()> v2(force_move(original2));
ASSERT_THROWS((cc::const_vector<char, (test_defs::get<char>::arr_len<1>() - 1)>(force_move(vc13))), std::invalid_argument);
ASSERT_THROWS((cc::const_vector<char, (test_defs::get<char>::arr_len<2>() - 1)>(force_move(vc23))), std::invalid_argument);
ASSERT_THROWS((cc::const_vector<T, c_arr_len(get_test_param<ctx, "arr">()) - 1>(force_move(original3))), std::invalid_argument, ctx);
ASSERT(vc1.capacity() == test_defs::get<char>::arr_len<1>());
ASSERT(vc2.capacity() == test_defs::get<char>::arr_len<2>());
ASSERT(vc1.size() == test_defs::get<char>::arr_len<1>());
ASSERT(vc2.size() == test_defs::get<char>::arr_len<2>());
ASSERT_VEC_ARR_EQ(vc1, test_defs::get<char>::arr<1>);
ASSERT_VEC_ARR_EQ(vc2, test_defs::get<char>::arr<2>);
ASSERT(vc3.capacity() == test_defs::get<char>::capacity<1>());
ASSERT(vc4.capacity() == test_defs::get<char>::capacity<2>());
ASSERT(vc3.size() == test_defs::get<char>::arr_len<1>());
ASSERT(vc4.size() == test_defs::get<char>::arr_len<2>());
ASSERT_VEC_ARR_EQ(vc3, test_defs::get<char>::arr<1>);
ASSERT_VEC_ARR_EQ(vc4, test_defs::get<char>::arr<2>);
ASSERT(std::ranges::equal(v1, get_test_param<ctx, "arr">()), ctx);
ASSERT(std::ranges::equal(v2, get_test_param<ctx, "arr">()), ctx);
cc::const_vector vs11(test_defs::get<const char *>::arr<1>);
cc::const_vector vs21(test_defs::get<const char *>::arr<2>);
cc::const_vector vs12(test_defs::get<const char *>::arr<1>);
cc::const_vector vs22(test_defs::get<const char *>::arr<2>);
cc::const_vector vs13(test_defs::get<const char *>::arr<1>);
cc::const_vector vs23(test_defs::get<const char *>::arr<2>);
cc::const_vector vs1(force_move(vs11));
cc::const_vector vs2(force_move(vs21));
cc::const_vector<const char *, test_defs::get<const char *>::capacity<1>()> vs3(force_move(vs12));
cc::const_vector<const char *, test_defs::get<const char *>::capacity<2>()> vs4(force_move(vs22));
return TEST_PASS();
}), 2, int, char, const char *, TestObj);
ASSERT_THROWS((cc::const_vector<const char *, (test_defs::get<const char *>::arr_len<1>() - 1)>(force_move(vs13))), std::invalid_argument);
ASSERT_THROWS((cc::const_vector<const char *, (test_defs::get<const char *>::arr_len<2>() - 1)>(force_move(vs23))), std::invalid_argument);
ASSERT(vs1.capacity() == test_defs::get<const char *>::arr_len<1>());
ASSERT(vs2.capacity() == test_defs::get<const char *>::arr_len<2>());
ASSERT(vs1.size() == test_defs::get<const char *>::arr_len<1>());
ASSERT(vs2.size() == test_defs::get<const char *>::arr_len<2>());
ASSERT_VEC_ARR_EQ(vs1, test_defs::get<const char *>::arr<1>);
ASSERT_VEC_ARR_EQ(vs2, test_defs::get<const char *>::arr<2>);
ASSERT(vs3.capacity() == test_defs::get<const char *>::capacity<1>());
ASSERT(vs4.capacity() == test_defs::get<const char *>::capacity<2>());
ASSERT(vs3.size() == test_defs::get<const char *>::arr_len<1>());
ASSERT(vs4.size() == test_defs::get<const char *>::arr_len<2>());
ASSERT_VEC_ARR_EQ(vs3, test_defs::get<const char *>::arr<1>);
ASSERT_VEC_ARR_EQ(vs4, test_defs::get<const char *>::arr<2>);
cc::const_vector vo11(test_defs::get<TestStruct>::arr<1>);
cc::const_vector vo21(test_defs::get<TestStruct>::arr<2>);
cc::const_vector vo12(test_defs::get<TestStruct>::arr<1>);
cc::const_vector vo22(test_defs::get<TestStruct>::arr<2>);
cc::const_vector vo13(test_defs::get<TestStruct>::arr<1>);
cc::const_vector vo23(test_defs::get<TestStruct>::arr<2>);
cc::const_vector vo1(force_move(vo11));
cc::const_vector vo2(force_move(vo21));
cc::const_vector<TestStruct, test_defs::get<TestStruct>::capacity<1>()> vo3(force_move(vo12));
cc::const_vector<TestStruct, test_defs::get<TestStruct>::capacity<2>()> vo4(force_move(vo22));
ASSERT_THROWS((cc::const_vector<TestStruct, (test_defs::get<TestStruct>::arr_len<1>() - 1)>(force_move(vo13))), std::invalid_argument);
ASSERT_THROWS((cc::const_vector<TestStruct, (test_defs::get<TestStruct>::arr_len<2>() - 1)>(force_move(vo23))), std::invalid_argument);
ASSERT(vo1.capacity() == test_defs::get<TestStruct>::arr_len<1>());
ASSERT(vo2.capacity() == test_defs::get<TestStruct>::arr_len<2>());
ASSERT(vo1.size() == test_defs::get<TestStruct>::arr_len<1>());
ASSERT(vo2.size() == test_defs::get<TestStruct>::arr_len<2>());
ASSERT_VEC_ARR_EQ(vo1, test_defs::get<TestStruct>::arr<1>);
ASSERT_VEC_ARR_EQ(vo2, test_defs::get<TestStruct>::arr<2>);
ASSERT(vo3.capacity() == test_defs::get<TestStruct>::capacity<1>());
ASSERT(vo4.capacity() == test_defs::get<TestStruct>::capacity<2>());
ASSERT(vo3.size() == test_defs::get<TestStruct>::arr_len<1>());
ASSERT(vo4.size() == test_defs::get<TestStruct>::arr_len<2>());
ASSERT_VEC_ARR_EQ(vo3, test_defs::get<TestStruct>::arr<1>);
ASSERT_VEC_ARR_EQ(vo4, test_defs::get<TestStruct>::arr<2>);
return TEST_PASS();
}, EvalFlag::RUNTIME_CONSTEVAL);
int main() {
return tests.run();
}
#pragma clang diagnostic pop
}

View File

@ -6,22 +6,153 @@
constexpr test_suite tests = define_tests("Data Access")
("const_vector::at(size_type pos)", []() constexpr {
REPEAT_FOR_TYPES_N(([]<typename T, std::size_t N, typename Ctx>() constexpr {
REPEAT_FOR_TYPES_N(([]<typename T, std::size_t N, typename ctx>() constexpr {
cc::const_vector<T, test_params<"arr", Ctx>::get_arr_len() + 1> v(test_context_params<T, N>::template value<"arr">);
const cc::const_vector<T, test_params<"arr", Ctx>::get_arr_len() + 1> cv(test_context_params<T, N>::template value<"arr">);
cc::const_vector<T, c_arr_len(get_test_param<ctx, "arr">()) + 1> v(get_test_param<ctx, "arr">());
const cc::const_vector<T, c_arr_len(get_test_param<ctx, "arr">()) + 1> cv(get_test_param<ctx, "arr">());
for (int i = 0; i < test_params<"arr", Ctx>::get_arr_len(); ++i) {
ASSERT_TYPE_NUM((v.at(i) == test_params<"arr", Ctx>::get()[i]), T, N);
ASSERT_TYPE_NUM((cv.at(i) == test_params<"arr", Ctx>::get()[i]), T, N);
for (int i = 0; i < c_arr_len(get_test_param<ctx, "arr">()); ++i) {
ASSERT((v.at(i) == get_test_param<ctx, "arr">()[i]), ctx);
ASSERT((cv.at(i) == get_test_param<ctx, "arr">()[i]), ctx);
}
ASSERT_TYPE_NUM_THROWS(v.at(test_params<"arr", Ctx>::get_arr_len()), std::out_of_range, T, N);
ASSERT_TYPE_NUM_THROWS(cv.at(test_params<"arr", Ctx>::get_arr_len()), std::out_of_range, T, N);
ASSERT_THROWS(v.at(c_arr_len(get_test_param<ctx, "arr">())), std::out_of_range, ctx);
ASSERT_THROWS(cv.at(c_arr_len(get_test_param<ctx, "arr">())), std::out_of_range, ctx);
v.at(v.size() / 2) = test_params<"value", Ctx>::get();
v.at(v.size() / 2) = get_test_param<ctx, "value">();
ASSERT_TYPE_NUM((v.data()[v.size() / 2] == test_params<"value", Ctx>::get()), T, N);
ASSERT((v.at(v.size() / 2) == get_test_param<ctx, "value">()), ctx);
return TEST_PASS();
}), 2, int, char, const char *, TestObj);
return TEST_PASS();
}, EvalFlag::RUNTIME_CONSTEVAL)
("const_vector::operator[](size_type pos)", []() constexpr {
REPEAT_FOR_TYPES_N(([]<typename T, std::size_t N, typename ctx>() constexpr {
cc::const_vector<T, c_arr_len(get_test_param<ctx, "arr">()) + 1> v(get_test_param<ctx, "arr">());
const cc::const_vector<T, c_arr_len(get_test_param<ctx, "arr">()) + 1> cv(get_test_param<ctx, "arr">());
for (int i = 0; i < c_arr_len(get_test_param<ctx, "arr">()); ++i) {
ASSERT((v[i] == get_test_param<ctx, "arr">()[i]), ctx);
ASSERT((cv[i] == get_test_param<ctx, "arr">()[i]), ctx);
}
v[v.size() / 2] = get_test_param<ctx, "value">();
ASSERT((v[v.size() / 2] == get_test_param<ctx, "value">()), ctx);
return TEST_PASS();
}), 2, int, char, const char *, TestObj);
return TEST_PASS();
}, EvalFlag::RUNTIME_CONSTEVAL)
("const_vector::front()", []() constexpr {
REPEAT_FOR_TYPES_N(([]<typename T, std::size_t N, typename ctx>() constexpr {
cc::const_vector<T, c_arr_len(get_test_param<ctx, "arr">()) + 1> v(get_test_param<ctx, "arr">());
const cc::const_vector<T, c_arr_len(get_test_param<ctx, "arr">()) + 1> cv(get_test_param<ctx, "arr">());
ASSERT((v.front() == get_test_param<ctx, "arr">()[0]), ctx);
ASSERT((cv.front() == get_test_param<ctx, "arr">()[0]), ctx);
v.front() = get_test_param<ctx, "value">();
ASSERT((v[0] == get_test_param<ctx, "value">()));
return TEST_PASS();
}), 2, int, char, const char *, TestObj);
return TEST_PASS();
}, EvalFlag::RUNTIME_CONSTEVAL)
("const_vector::back()", []() constexpr {
REPEAT_FOR_TYPES_N(([]<typename T, std::size_t N, typename ctx>() constexpr {
cc::const_vector<T, c_arr_len(get_test_param<ctx, "arr">()) + 1> v(get_test_param<ctx, "arr">());
const cc::const_vector<T, c_arr_len(get_test_param<ctx, "arr">()) + 1> cv(get_test_param<ctx, "arr">());
ASSERT((v.back() == get_test_param<ctx, "arr">()[c_arr_len(get_test_param<ctx, "arr">()) - 1]), ctx);
ASSERT((cv.back() == get_test_param<ctx, "arr">()[c_arr_len(get_test_param<ctx, "arr">()) - 1]), ctx);
v.back() = get_test_param<ctx, "value">();
ASSERT((v[v.size() - 1] == get_test_param<ctx, "value">()));
return TEST_PASS();
}), 2, int, char, const char *, TestObj);
return TEST_PASS();
}, EvalFlag::RUNTIME_CONSTEVAL)
("const_vector::(c)begin()/(c)end()", []() constexpr {
REPEAT_FOR_TYPES_N(([]<typename T, std::size_t N, typename ctx>() constexpr {
cc::const_vector<T, c_arr_len(get_test_param<ctx, "arr">()) + 1> v(get_test_param<ctx, "arr">());
const cc::const_vector<T, c_arr_len(get_test_param<ctx, "arr">()) + 1> cv(get_test_param<ctx, "arr">());
auto v_it = v.begin();
for (std::size_t i = 0; v_it != v.end(); ++v_it, ++i) {
ASSERT(*v_it == v[i], ctx);
*v_it = get_test_param<ctx, "value">();
ASSERT((v[i] == get_test_param<ctx, "value">()), ctx);
}
auto v_cit = v.cbegin();
for (std::size_t i = 0; v_cit != v.cend(); ++v_cit, ++i) {
ASSERT(*v_cit == v[i], ctx);
ASSERT(std::is_const_v<std::remove_reference_t<typename std::iterator_traits<decltype(v_cit)>::reference>>, ctx);
}
auto cv_it = cv.begin();
for (std::size_t i = 0; cv_it != cv.end(); ++cv_it, ++i) {
ASSERT(*cv_it == cv[i], ctx);
ASSERT(std::is_const_v<std::remove_reference_t<typename std::iterator_traits<decltype(cv_it)>::reference>>, ctx);
}
auto cv_cit = cv.cbegin();
for (std::size_t i = 0; cv_cit != cv.cend(); ++cv_cit, ++i) {
ASSERT(*cv_cit == cv[i], ctx);
ASSERT(std::is_const_v<std::remove_reference_t<typename std::iterator_traits<decltype(cv_cit)>::reference>>, ctx);
}
return TEST_PASS();
}), 2, int, char, const char *, TestObj);
return TEST_PASS();
}, EvalFlag::RUNTIME_CONSTEVAL)
("const_vector::(c)rbegin()/(c)rend()", []() constexpr {
REPEAT_FOR_TYPES_N(([]<typename T, std::size_t N, typename ctx>() constexpr {
cc::const_vector<T, c_arr_len(get_test_param<ctx, "arr">()) + 1> v(get_test_param<ctx, "arr">());
const cc::const_vector<T, c_arr_len(get_test_param<ctx, "arr">()) + 1> cv(get_test_param<ctx, "arr">());
auto v_it = v.rbegin();
for (std::size_t i = v.size() - 1; v_it != v.rend(); ++v_it, --i) {
ASSERT(*v_it == v[i], ctx);
*v_it = get_test_param<ctx, "value">();
ASSERT((v[i] == get_test_param<ctx, "value">()), ctx);
}
auto v_cit = v.crbegin();
for (std::size_t i = v.size() - 1; v_cit != v.crend(); ++v_cit, --i) {
ASSERT(*v_cit == v[i], ctx);
ASSERT(std::is_const_v<std::remove_reference_t<typename std::iterator_traits<decltype(v_cit)>::reference>>, ctx);
}
auto cv_it = cv.rbegin();
for (std::size_t i = v.size() - 1; cv_it != cv.rend(); ++cv_it, --i) {
ASSERT(*cv_it == cv[i], ctx);
ASSERT(std::is_const_v<std::remove_reference_t<typename std::iterator_traits<decltype(cv_it)>::reference>>, ctx);
}
auto cv_cit = cv.crbegin();
for (std::size_t i = v.size() - 1; cv_cit != cv.crend(); ++cv_cit, --i) {
ASSERT(*cv_cit == cv[i], ctx);
ASSERT(std::is_const_v<std::remove_reference_t<typename std::iterator_traits<decltype(cv_cit)>::reference>>, ctx);
}
return TEST_PASS();
}), 2, int, char, const char *, TestObj);

View File

@ -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