mirror of
https://github.com/BlackMATov/meta.hpp.git
synced 2026-03-22 04:53:59 +07:00
Compare commits
4 Commits
8f74952047
...
c72e4047c0
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
c72e4047c0 | ||
|
|
774d0c04c2 | ||
|
|
41855b3ed7 | ||
|
|
5d5ba52045 |
@@ -10461,20 +10461,99 @@ namespace meta_hpp::detail
|
||||
|
||||
template < typename T >
|
||||
concept has_copy_traits //
|
||||
= requires(const T& v) { copy_traits<T>{}(v); };
|
||||
= requires(const T& v) { copy_traits<std::remove_cv_t<T>>{}(v); };
|
||||
}
|
||||
|
||||
namespace meta_hpp::detail
|
||||
{
|
||||
template < typename T >
|
||||
requires requires(const T& v) { uvalue{v}; }
|
||||
requires(!std::is_class_v<T>) && requires(T v) { uvalue{v}; }
|
||||
struct copy_traits<T> {
|
||||
uvalue operator()(const T& v) const {
|
||||
uvalue operator()(T v) const {
|
||||
return uvalue{v};
|
||||
}
|
||||
};
|
||||
|
||||
template < typename T, std::size_t Size >
|
||||
requires has_copy_traits<T>
|
||||
struct copy_traits<std::array<T, Size>> {
|
||||
using value_t = std::array<T, Size>;
|
||||
|
||||
uvalue operator()(const value_t& v) const {
|
||||
return uvalue{v};
|
||||
}
|
||||
};
|
||||
|
||||
template < typename T, typename Traits, typename Allocator >
|
||||
requires has_copy_traits<T>
|
||||
struct copy_traits<std::basic_string<T, Traits, Allocator>> {
|
||||
using value_t = std::basic_string<T, Traits, Allocator>;
|
||||
|
||||
uvalue operator()(const value_t& v) const {
|
||||
return uvalue{v};
|
||||
}
|
||||
};
|
||||
|
||||
template < typename T, typename Traits >
|
||||
requires has_copy_traits<T>
|
||||
struct copy_traits<std::basic_string_view<T, Traits>> {
|
||||
using value_t = std::basic_string_view<T, Traits>;
|
||||
|
||||
uvalue operator()(const value_t& v) const {
|
||||
return uvalue{v};
|
||||
}
|
||||
};
|
||||
|
||||
template < typename T, typename Allocator >
|
||||
requires has_copy_traits<T>
|
||||
struct copy_traits<std::vector<T, Allocator>> {
|
||||
using value_t = std::vector<T, Allocator>;
|
||||
|
||||
uvalue operator()(const value_t& v) const {
|
||||
return uvalue{v};
|
||||
}
|
||||
};
|
||||
|
||||
template < typename T >
|
||||
struct copy_traits<std::shared_ptr<T>> {
|
||||
using value_t = std::shared_ptr<T>;
|
||||
|
||||
uvalue operator()(const value_t& v) const {
|
||||
return uvalue{v};
|
||||
}
|
||||
};
|
||||
|
||||
template < typename T >
|
||||
struct copy_traits<std::reference_wrapper<T>> {
|
||||
using value_t = std::reference_wrapper<T>;
|
||||
|
||||
uvalue operator()(const value_t& v) const {
|
||||
return uvalue{v};
|
||||
}
|
||||
};
|
||||
|
||||
template < typename... Ts >
|
||||
requires(... && has_copy_traits<Ts>)
|
||||
struct copy_traits<std::tuple<Ts...>> {
|
||||
using value_t = std::tuple<Ts...>;
|
||||
|
||||
uvalue operator()(const value_t& v) const {
|
||||
return uvalue{v};
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
#define META_HPP_DECLARE_COPY_TRAITS_FOR(T) \
|
||||
namespace meta_hpp::detail \
|
||||
{ \
|
||||
template <> \
|
||||
struct copy_traits<T> { \
|
||||
uvalue operator()(const T& v) const { \
|
||||
return uvalue{v}; \
|
||||
} \
|
||||
}; \
|
||||
}
|
||||
|
||||
namespace meta_hpp::detail
|
||||
{
|
||||
template < typename T >
|
||||
@@ -10482,13 +10561,13 @@ namespace meta_hpp::detail
|
||||
|
||||
template < typename T >
|
||||
concept has_deref_traits //
|
||||
= requires(const T& v) { deref_traits<T>{}(v); };
|
||||
= requires(const T& v) { deref_traits<std::remove_cv_t<T>>{}(v); };
|
||||
}
|
||||
|
||||
namespace meta_hpp::detail
|
||||
{
|
||||
template < typename T >
|
||||
requires std::is_copy_constructible_v<T>
|
||||
requires has_copy_traits<T> && (!std::is_function_v<T>)
|
||||
struct deref_traits<T*> {
|
||||
uvalue operator()(T* v) const {
|
||||
return v != nullptr ? uvalue{*v} : uvalue{};
|
||||
@@ -10496,22 +10575,37 @@ namespace meta_hpp::detail
|
||||
};
|
||||
|
||||
template < typename T >
|
||||
requires std::is_copy_constructible_v<T>
|
||||
requires has_copy_traits<T>
|
||||
struct deref_traits<std::shared_ptr<T>> {
|
||||
uvalue operator()(const std::shared_ptr<T>& v) const {
|
||||
using value_t = std::shared_ptr<T>;
|
||||
|
||||
uvalue operator()(const value_t& v) const {
|
||||
return v != nullptr ? uvalue{*v} : uvalue{};
|
||||
}
|
||||
};
|
||||
|
||||
template < typename T, typename Deleter >
|
||||
requires std::is_copy_constructible_v<T>
|
||||
requires has_copy_traits<T>
|
||||
struct deref_traits<std::unique_ptr<T, Deleter>> {
|
||||
uvalue operator()(const std::unique_ptr<T, Deleter>& v) const {
|
||||
using value_t = std::unique_ptr<T, Deleter>;
|
||||
|
||||
uvalue operator()(const value_t& v) const {
|
||||
return v != nullptr ? uvalue{*v} : uvalue{};
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
#define META_HPP_DECLARE_DEREF_TRAITS_FOR(T) \
|
||||
namespace meta_hpp::detail \
|
||||
{ \
|
||||
template <> \
|
||||
struct deref_traits<T> { \
|
||||
uvalue operator()(const T& v) const { \
|
||||
return uvalue{*v}; \
|
||||
} \
|
||||
}; \
|
||||
}
|
||||
|
||||
namespace meta_hpp::detail
|
||||
{
|
||||
template < typename T >
|
||||
@@ -10519,17 +10613,17 @@ namespace meta_hpp::detail
|
||||
|
||||
template < typename T >
|
||||
concept has_equals_traits //
|
||||
= requires(const T& v) { equals_traits<T>{}(v, v); };
|
||||
= requires(const T& v) { equals_traits<std::remove_cv_t<T>>{}(v, v); };
|
||||
}
|
||||
|
||||
namespace meta_hpp::detail
|
||||
{
|
||||
template < typename T >
|
||||
requires requires(const T& v) {
|
||||
{ v == v } -> std::convertible_to<bool>;
|
||||
} && (!class_kind<T> || type_list_arity_v<typename class_traits<T>::argument_types> == 0)
|
||||
requires(!std::is_class_v<T>) && requires(T v) {
|
||||
{ v == v } -> std::convertible_to<bool>;
|
||||
}
|
||||
struct equals_traits<T> {
|
||||
bool operator()(const T& l, const T& r) const {
|
||||
bool operator()(T l, T r) const {
|
||||
META_HPP_DETAIL_IGNORE_COMPARISON_WARNINGS_PUSH()
|
||||
return l == r;
|
||||
META_HPP_DETAIL_IGNORE_COMPARISON_WARNINGS_POP()
|
||||
@@ -10633,13 +10727,13 @@ namespace meta_hpp::detail
|
||||
|
||||
template < typename T >
|
||||
concept has_index_traits //
|
||||
= requires(const T& v, std::size_t i) { index_traits<T>{}(v, i); };
|
||||
= requires(const T& v, std::size_t i) { index_traits<std::remove_cv_t<T>>{}(v, i); };
|
||||
}
|
||||
|
||||
namespace meta_hpp::detail
|
||||
{
|
||||
template < typename T >
|
||||
requires std::is_copy_constructible_v<T>
|
||||
requires has_copy_traits<T> && (!std::is_function_v<T>)
|
||||
struct index_traits<T*> {
|
||||
uvalue operator()(T* v, std::size_t i) const {
|
||||
// NOLINTNEXTLINE(*-pointer-arithmetic)
|
||||
@@ -10648,7 +10742,7 @@ namespace meta_hpp::detail
|
||||
};
|
||||
|
||||
template < typename T, std::size_t Size >
|
||||
requires std::is_copy_constructible_v<T>
|
||||
requires has_copy_traits<T>
|
||||
struct index_traits<std::array<T, Size>> {
|
||||
uvalue operator()(const std::array<T, Size>& v, std::size_t i) const {
|
||||
return i < v.size() ? uvalue{v[i]} : uvalue{};
|
||||
@@ -10656,7 +10750,7 @@ namespace meta_hpp::detail
|
||||
};
|
||||
|
||||
template < typename T, typename Traits, typename Allocator >
|
||||
requires std::is_copy_constructible_v<T>
|
||||
requires has_copy_traits<T>
|
||||
struct index_traits<std::basic_string<T, Traits, Allocator>> {
|
||||
uvalue operator()(const std::basic_string<T, Traits, Allocator>& v, std::size_t i) const {
|
||||
return i < v.size() ? uvalue{v[i]} : uvalue{};
|
||||
@@ -10664,7 +10758,7 @@ namespace meta_hpp::detail
|
||||
};
|
||||
|
||||
template < typename T, typename Traits >
|
||||
requires std::is_copy_constructible_v<T>
|
||||
requires has_copy_traits<T>
|
||||
struct index_traits<std::basic_string_view<T, Traits>> {
|
||||
uvalue operator()(const std::basic_string_view<T, Traits>& v, std::size_t i) const {
|
||||
return i < v.size() ? uvalue{v[i]} : uvalue{};
|
||||
@@ -10672,7 +10766,7 @@ namespace meta_hpp::detail
|
||||
};
|
||||
|
||||
template < typename T, std::size_t Extent >
|
||||
requires std::is_copy_constructible_v<T>
|
||||
requires has_copy_traits<T>
|
||||
struct index_traits<std::span<T, Extent>> {
|
||||
uvalue operator()(const std::span<T, Extent>& v, std::size_t i) const {
|
||||
return i < v.size() ? uvalue{v[i]} : uvalue{};
|
||||
@@ -10680,7 +10774,7 @@ namespace meta_hpp::detail
|
||||
};
|
||||
|
||||
template < typename T, typename Allocator >
|
||||
requires std::is_copy_constructible_v<T>
|
||||
requires has_copy_traits<T>
|
||||
struct index_traits<std::vector<T, Allocator>> {
|
||||
uvalue operator()(const std::vector<T, Allocator>& v, std::size_t i) const {
|
||||
return i < v.size() ? uvalue{v[i]} : uvalue{};
|
||||
@@ -10688,6 +10782,17 @@ namespace meta_hpp::detail
|
||||
};
|
||||
}
|
||||
|
||||
#define META_HPP_DECLARE_INDEX_TRAITS_FOR(T) \
|
||||
namespace meta_hpp::detail \
|
||||
{ \
|
||||
template <> \
|
||||
struct index_traits<T> { \
|
||||
uvalue operator()(const T& v, std::size_t i) const { \
|
||||
return uvalue{v[i]}; \
|
||||
} \
|
||||
}; \
|
||||
}
|
||||
|
||||
namespace meta_hpp::detail
|
||||
{
|
||||
template < typename T >
|
||||
@@ -10695,17 +10800,17 @@ namespace meta_hpp::detail
|
||||
|
||||
template < typename T >
|
||||
concept has_less_traits //
|
||||
= requires(const T& v) { less_traits<T>{}(v, v); };
|
||||
= requires(const T& v) { less_traits<std::remove_cv_t<T>>{}(v, v); };
|
||||
}
|
||||
|
||||
namespace meta_hpp::detail
|
||||
{
|
||||
template < typename T >
|
||||
requires requires(const T& v) {
|
||||
{ v < v } -> std::convertible_to<bool>;
|
||||
} && (!class_kind<T> || type_list_arity_v<typename class_traits<T>::argument_types> == 0)
|
||||
requires(!std::is_class_v<T>) && requires(T v) {
|
||||
{ v < v } -> std::convertible_to<bool>;
|
||||
}
|
||||
struct less_traits<T> {
|
||||
bool operator()(const T& l, const T& r) const {
|
||||
bool operator()(T l, T r) const {
|
||||
META_HPP_DETAIL_IGNORE_COMPARISON_WARNINGS_PUSH()
|
||||
return l < r;
|
||||
META_HPP_DETAIL_IGNORE_COMPARISON_WARNINGS_POP()
|
||||
@@ -10809,7 +10914,7 @@ namespace meta_hpp::detail
|
||||
|
||||
template < typename T >
|
||||
concept has_unmap_traits //
|
||||
= requires(const T& v) { unmap_traits<T>{}(v); };
|
||||
= requires(const T& v) { unmap_traits<std::remove_cv_t<T>>{}(v); };
|
||||
}
|
||||
|
||||
namespace meta_hpp::detail
|
||||
|
||||
@@ -90,6 +90,9 @@ namespace
|
||||
int ivec2_big::copy_constructor_counter{0};
|
||||
}
|
||||
|
||||
META_HPP_DECLARE_COPY_TRAITS_FOR(ivec2)
|
||||
META_HPP_DECLARE_COPY_TRAITS_FOR(ivec2_big)
|
||||
|
||||
TEST_CASE("meta/meta_utilities/value2") {
|
||||
namespace meta = meta_hpp;
|
||||
|
||||
|
||||
@@ -46,6 +46,8 @@ namespace
|
||||
};
|
||||
}
|
||||
|
||||
META_HPP_DECLARE_COPY_TRAITS_FOR(clazz_throw_dtor)
|
||||
|
||||
TEST_CASE("meta/meta_utilities/value4") {
|
||||
namespace meta = meta_hpp;
|
||||
|
||||
|
||||
@@ -38,6 +38,10 @@ namespace
|
||||
return *this;
|
||||
}
|
||||
|
||||
int operator[](std::size_t i) const noexcept {
|
||||
return i == 0 ? x : y;
|
||||
}
|
||||
|
||||
ivec2& operator=(ivec2&& other) = delete;
|
||||
ivec2& operator=(const ivec2& other) = delete;
|
||||
public:
|
||||
@@ -107,8 +111,37 @@ namespace
|
||||
bool operator==(const ivec2_big& l, const ivec2_big& r) noexcept {
|
||||
return l.x == r.x && l.y == r.y;
|
||||
}
|
||||
|
||||
struct deref_custom_class {
|
||||
int operator*() const { return 42; }
|
||||
};
|
||||
|
||||
struct custom_class_without_comparison {};
|
||||
|
||||
struct custom_class_with_fake_comparison {
|
||||
std::vector<custom_class_without_comparison> vs;
|
||||
bool operator==(const custom_class_with_fake_comparison&) const = default;
|
||||
};
|
||||
|
||||
struct custom_class_with_comparison {
|
||||
std::vector<int> vs;
|
||||
bool operator<(const custom_class_with_comparison& r) const { return vs < r.vs; }
|
||||
bool operator==(const custom_class_with_comparison& r) const { return vs == r.vs; }
|
||||
};
|
||||
}
|
||||
|
||||
META_HPP_DECLARE_COPY_TRAITS_FOR(ivec2)
|
||||
META_HPP_DECLARE_COPY_TRAITS_FOR(ivec2_big)
|
||||
|
||||
META_HPP_DECLARE_DEREF_TRAITS_FOR(deref_custom_class)
|
||||
|
||||
META_HPP_DECLARE_INDEX_TRAITS_FOR(ivec2)
|
||||
|
||||
META_HPP_DECLARE_EQUALS_TRAITS_FOR(ivec2)
|
||||
|
||||
META_HPP_DECLARE_LESS_TRAITS_FOR(custom_class_with_comparison)
|
||||
META_HPP_DECLARE_EQUALS_TRAITS_FOR(custom_class_with_comparison)
|
||||
|
||||
TEST_CASE("meta/meta_utilities/value/_") {
|
||||
namespace meta = meta_hpp;
|
||||
|
||||
@@ -497,6 +530,36 @@ TEST_CASE("meta/meta_utilities/value") {
|
||||
CHECK_FALSE(u.has_copy_op());
|
||||
CHECK_THROWS(std::ignore = u.copy());
|
||||
}
|
||||
{
|
||||
CHECK(meta::uvalue{std::array<int, 1>{}}.has_copy_op());
|
||||
CHECK_FALSE(meta::uvalue{std::array<std::unique_ptr<int>, 1>{}}.has_copy_op());
|
||||
CHECK(meta::uvalue{std::string{}}.has_copy_op());
|
||||
CHECK(meta::uvalue{std::string_view{}}.has_copy_op());
|
||||
CHECK(meta::uvalue{std::vector{42, 21}}.has_copy_op());
|
||||
CHECK_FALSE(meta::uvalue{std::vector<std::unique_ptr<int>>{}}.has_copy_op());
|
||||
CHECK(meta::uvalue{std::shared_ptr<int>{}}.has_copy_op());
|
||||
{
|
||||
using ref_t = std::reference_wrapper<std::unique_ptr<int>>;
|
||||
using cref_t = std::reference_wrapper<const std::unique_ptr<int>>;
|
||||
|
||||
std::unique_ptr u = std::make_unique<int>(42);
|
||||
CHECK(meta::uvalue{ref_t{u}}.has_copy_op());
|
||||
CHECK(meta::uvalue{cref_t{u}}.has_copy_op());
|
||||
meta::uvalue v1 = meta::uvalue{ref_t{u}}.copy();
|
||||
meta::uvalue v2 = meta::uvalue{cref_t{u}}.copy();
|
||||
CHECK(v1.get_type() == meta::resolve_type<ref_t>());
|
||||
CHECK(v1.as<ref_t>().get().get() == u.get());
|
||||
CHECK(v2.get_type() == meta::resolve_type<cref_t>());
|
||||
CHECK(v2.as<cref_t>().get().get() == u.get());
|
||||
}
|
||||
{
|
||||
ivec2 u = ivec2{42, 21};
|
||||
CHECK(meta::uvalue{std::ref(u)}.has_copy_op());
|
||||
CHECK(meta::uvalue{std::cref(u)}.has_copy_op());
|
||||
}
|
||||
CHECK(meta::uvalue{std::make_tuple(42, std::make_shared<int>(42))}.has_copy_op());
|
||||
CHECK_FALSE(meta::uvalue{std::make_tuple(42, std::make_unique<int>(42))}.has_copy_op());
|
||||
}
|
||||
}
|
||||
|
||||
SUBCASE("unmap") {
|
||||
@@ -623,6 +686,22 @@ TEST_CASE("meta/meta_utilities/value") {
|
||||
meta::uvalue v{std::make_unique<int>(42)};
|
||||
CHECK((*v).as<int>() == 42);
|
||||
}
|
||||
{
|
||||
CHECK(meta::uvalue{std::make_shared<std::vector<std::shared_ptr<int>>>()}.has_deref_op());
|
||||
CHECK_FALSE(meta::uvalue{std::make_shared<std::vector<std::unique_ptr<int>>>()}.has_deref_op());
|
||||
}
|
||||
{
|
||||
const meta::uvalue v{deref_custom_class{}};
|
||||
CHECK(v.has_deref_op());
|
||||
|
||||
const meta::uvalue u = *v;
|
||||
CHECK(u.get_type() == meta::resolve_type<int>());
|
||||
CHECK(u.as<int>() == 42);
|
||||
}
|
||||
{
|
||||
CHECK(meta::uvalue{std::unique_ptr<ivec2>{}}.has_deref_op());
|
||||
CHECK(meta::uvalue{std::unique_ptr<const ivec2>{}}.has_deref_op());
|
||||
}
|
||||
}
|
||||
|
||||
SUBCASE("less/equal") {
|
||||
@@ -812,6 +891,16 @@ TEST_CASE("meta/meta_utilities/value") {
|
||||
CHECK(meta::uvalue{std::cref(v2)}.has_equals_op());
|
||||
}
|
||||
}
|
||||
{
|
||||
meta::uvalue v{custom_class_with_comparison{}};
|
||||
CHECK(v.has_less_op());
|
||||
CHECK(v.has_equals_op());
|
||||
}
|
||||
{
|
||||
meta::uvalue v{custom_class_with_fake_comparison{}};
|
||||
CHECK_FALSE(v.has_less_op());
|
||||
CHECK_FALSE(v.has_equals_op());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -938,6 +1027,23 @@ TEST_CASE("meta/meta_utilities/value/arrays") {
|
||||
CHECK(v[2].as<int>() == 3);
|
||||
CHECK_FALSE(v[3]);
|
||||
}
|
||||
|
||||
SUBCASE("ivec2/ivec3") {
|
||||
{
|
||||
meta::uvalue v{ivec2{1,2}};
|
||||
CHECK(v.get_type() == meta::resolve_type<ivec2>());
|
||||
CHECK(v.has_index_op());
|
||||
|
||||
CHECK(v[0].as<int>() == 1);
|
||||
CHECK(v[1].as<int>() == 2);
|
||||
}
|
||||
{
|
||||
meta::uvalue v{ivec3{1,2,3}};
|
||||
CHECK(v.get_type() == meta::resolve_type<ivec3>());
|
||||
CHECK_FALSE(v.has_index_op());
|
||||
CHECK_THROWS(std::ignore = v[0]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
TEST_CASE("meta/meta_utilities/value/functions") {
|
||||
|
||||
@@ -16,16 +16,95 @@ namespace meta_hpp::detail
|
||||
|
||||
template < typename T >
|
||||
concept has_copy_traits //
|
||||
= requires(const T& v) { copy_traits<T>{}(v); };
|
||||
= requires(const T& v) { copy_traits<std::remove_cv_t<T>>{}(v); };
|
||||
}
|
||||
|
||||
namespace meta_hpp::detail
|
||||
{
|
||||
template < typename T >
|
||||
requires requires(const T& v) { uvalue{v}; }
|
||||
requires(!std::is_class_v<T>) && requires(T v) { uvalue{v}; }
|
||||
struct copy_traits<T> {
|
||||
uvalue operator()(const T& v) const {
|
||||
uvalue operator()(T v) const {
|
||||
return uvalue{v};
|
||||
}
|
||||
};
|
||||
|
||||
template < typename T, std::size_t Size >
|
||||
requires has_copy_traits<T>
|
||||
struct copy_traits<std::array<T, Size>> {
|
||||
using value_t = std::array<T, Size>;
|
||||
|
||||
uvalue operator()(const value_t& v) const {
|
||||
return uvalue{v};
|
||||
}
|
||||
};
|
||||
|
||||
template < typename T, typename Traits, typename Allocator >
|
||||
requires has_copy_traits<T>
|
||||
struct copy_traits<std::basic_string<T, Traits, Allocator>> {
|
||||
using value_t = std::basic_string<T, Traits, Allocator>;
|
||||
|
||||
uvalue operator()(const value_t& v) const {
|
||||
return uvalue{v};
|
||||
}
|
||||
};
|
||||
|
||||
template < typename T, typename Traits >
|
||||
requires has_copy_traits<T>
|
||||
struct copy_traits<std::basic_string_view<T, Traits>> {
|
||||
using value_t = std::basic_string_view<T, Traits>;
|
||||
|
||||
uvalue operator()(const value_t& v) const {
|
||||
return uvalue{v};
|
||||
}
|
||||
};
|
||||
|
||||
template < typename T, typename Allocator >
|
||||
requires has_copy_traits<T>
|
||||
struct copy_traits<std::vector<T, Allocator>> {
|
||||
using value_t = std::vector<T, Allocator>;
|
||||
|
||||
uvalue operator()(const value_t& v) const {
|
||||
return uvalue{v};
|
||||
}
|
||||
};
|
||||
|
||||
template < typename T >
|
||||
struct copy_traits<std::shared_ptr<T>> {
|
||||
using value_t = std::shared_ptr<T>;
|
||||
|
||||
uvalue operator()(const value_t& v) const {
|
||||
return uvalue{v};
|
||||
}
|
||||
};
|
||||
|
||||
template < typename T >
|
||||
struct copy_traits<std::reference_wrapper<T>> {
|
||||
using value_t = std::reference_wrapper<T>;
|
||||
|
||||
uvalue operator()(const value_t& v) const {
|
||||
return uvalue{v};
|
||||
}
|
||||
};
|
||||
|
||||
template < typename... Ts >
|
||||
requires(... && has_copy_traits<Ts>)
|
||||
struct copy_traits<std::tuple<Ts...>> {
|
||||
using value_t = std::tuple<Ts...>;
|
||||
|
||||
uvalue operator()(const value_t& v) const {
|
||||
return uvalue{v};
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
#define META_HPP_DECLARE_COPY_TRAITS_FOR(T) \
|
||||
namespace meta_hpp::detail \
|
||||
{ \
|
||||
template <> \
|
||||
struct copy_traits<T> { \
|
||||
uvalue operator()(const T& v) const { \
|
||||
return uvalue{v}; \
|
||||
} \
|
||||
}; \
|
||||
}
|
||||
|
||||
@@ -9,6 +9,8 @@
|
||||
#include "../../meta_base.hpp"
|
||||
#include "../../meta_uvalue.hpp"
|
||||
|
||||
#include "copy_traits.hpp"
|
||||
|
||||
namespace meta_hpp::detail
|
||||
{
|
||||
template < typename T >
|
||||
@@ -16,13 +18,13 @@ namespace meta_hpp::detail
|
||||
|
||||
template < typename T >
|
||||
concept has_deref_traits //
|
||||
= requires(const T& v) { deref_traits<T>{}(v); };
|
||||
= requires(const T& v) { deref_traits<std::remove_cv_t<T>>{}(v); };
|
||||
}
|
||||
|
||||
namespace meta_hpp::detail
|
||||
{
|
||||
template < typename T >
|
||||
requires std::is_copy_constructible_v<T>
|
||||
requires has_copy_traits<T> && (!std::is_function_v<T>)
|
||||
struct deref_traits<T*> {
|
||||
uvalue operator()(T* v) const {
|
||||
return v != nullptr ? uvalue{*v} : uvalue{};
|
||||
@@ -30,18 +32,33 @@ namespace meta_hpp::detail
|
||||
};
|
||||
|
||||
template < typename T >
|
||||
requires std::is_copy_constructible_v<T>
|
||||
requires has_copy_traits<T>
|
||||
struct deref_traits<std::shared_ptr<T>> {
|
||||
uvalue operator()(const std::shared_ptr<T>& v) const {
|
||||
using value_t = std::shared_ptr<T>;
|
||||
|
||||
uvalue operator()(const value_t& v) const {
|
||||
return v != nullptr ? uvalue{*v} : uvalue{};
|
||||
}
|
||||
};
|
||||
|
||||
template < typename T, typename Deleter >
|
||||
requires std::is_copy_constructible_v<T>
|
||||
requires has_copy_traits<T>
|
||||
struct deref_traits<std::unique_ptr<T, Deleter>> {
|
||||
uvalue operator()(const std::unique_ptr<T, Deleter>& v) const {
|
||||
using value_t = std::unique_ptr<T, Deleter>;
|
||||
|
||||
uvalue operator()(const value_t& v) const {
|
||||
return v != nullptr ? uvalue{*v} : uvalue{};
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
#define META_HPP_DECLARE_DEREF_TRAITS_FOR(T) \
|
||||
namespace meta_hpp::detail \
|
||||
{ \
|
||||
template <> \
|
||||
struct deref_traits<T> { \
|
||||
uvalue operator()(const T& v) const { \
|
||||
return uvalue{*v}; \
|
||||
} \
|
||||
}; \
|
||||
}
|
||||
|
||||
@@ -16,17 +16,17 @@ namespace meta_hpp::detail
|
||||
|
||||
template < typename T >
|
||||
concept has_equals_traits //
|
||||
= requires(const T& v) { equals_traits<T>{}(v, v); };
|
||||
= requires(const T& v) { equals_traits<std::remove_cv_t<T>>{}(v, v); };
|
||||
}
|
||||
|
||||
namespace meta_hpp::detail
|
||||
{
|
||||
template < typename T >
|
||||
requires requires(const T& v) {
|
||||
{ v == v } -> std::convertible_to<bool>;
|
||||
} && (!class_kind<T> || type_list_arity_v<typename class_traits<T>::argument_types> == 0)
|
||||
requires(!std::is_class_v<T>) && requires(T v) {
|
||||
{ v == v } -> std::convertible_to<bool>;
|
||||
}
|
||||
struct equals_traits<T> {
|
||||
bool operator()(const T& l, const T& r) const {
|
||||
bool operator()(T l, T r) const {
|
||||
META_HPP_DETAIL_IGNORE_COMPARISON_WARNINGS_PUSH()
|
||||
return l == r;
|
||||
META_HPP_DETAIL_IGNORE_COMPARISON_WARNINGS_POP()
|
||||
|
||||
@@ -9,6 +9,8 @@
|
||||
#include "../../meta_base.hpp"
|
||||
#include "../../meta_uvalue.hpp"
|
||||
|
||||
#include "copy_traits.hpp"
|
||||
|
||||
namespace meta_hpp::detail
|
||||
{
|
||||
template < typename T >
|
||||
@@ -16,13 +18,13 @@ namespace meta_hpp::detail
|
||||
|
||||
template < typename T >
|
||||
concept has_index_traits //
|
||||
= requires(const T& v, std::size_t i) { index_traits<T>{}(v, i); };
|
||||
= requires(const T& v, std::size_t i) { index_traits<std::remove_cv_t<T>>{}(v, i); };
|
||||
}
|
||||
|
||||
namespace meta_hpp::detail
|
||||
{
|
||||
template < typename T >
|
||||
requires std::is_copy_constructible_v<T>
|
||||
requires has_copy_traits<T> && (!std::is_function_v<T>)
|
||||
struct index_traits<T*> {
|
||||
uvalue operator()(T* v, std::size_t i) const {
|
||||
// NOLINTNEXTLINE(*-pointer-arithmetic)
|
||||
@@ -31,7 +33,7 @@ namespace meta_hpp::detail
|
||||
};
|
||||
|
||||
template < typename T, std::size_t Size >
|
||||
requires std::is_copy_constructible_v<T>
|
||||
requires has_copy_traits<T>
|
||||
struct index_traits<std::array<T, Size>> {
|
||||
uvalue operator()(const std::array<T, Size>& v, std::size_t i) const {
|
||||
return i < v.size() ? uvalue{v[i]} : uvalue{};
|
||||
@@ -39,7 +41,7 @@ namespace meta_hpp::detail
|
||||
};
|
||||
|
||||
template < typename T, typename Traits, typename Allocator >
|
||||
requires std::is_copy_constructible_v<T>
|
||||
requires has_copy_traits<T>
|
||||
struct index_traits<std::basic_string<T, Traits, Allocator>> {
|
||||
uvalue operator()(const std::basic_string<T, Traits, Allocator>& v, std::size_t i) const {
|
||||
return i < v.size() ? uvalue{v[i]} : uvalue{};
|
||||
@@ -47,7 +49,7 @@ namespace meta_hpp::detail
|
||||
};
|
||||
|
||||
template < typename T, typename Traits >
|
||||
requires std::is_copy_constructible_v<T>
|
||||
requires has_copy_traits<T>
|
||||
struct index_traits<std::basic_string_view<T, Traits>> {
|
||||
uvalue operator()(const std::basic_string_view<T, Traits>& v, std::size_t i) const {
|
||||
return i < v.size() ? uvalue{v[i]} : uvalue{};
|
||||
@@ -55,7 +57,7 @@ namespace meta_hpp::detail
|
||||
};
|
||||
|
||||
template < typename T, std::size_t Extent >
|
||||
requires std::is_copy_constructible_v<T>
|
||||
requires has_copy_traits<T>
|
||||
struct index_traits<std::span<T, Extent>> {
|
||||
uvalue operator()(const std::span<T, Extent>& v, std::size_t i) const {
|
||||
return i < v.size() ? uvalue{v[i]} : uvalue{};
|
||||
@@ -63,10 +65,21 @@ namespace meta_hpp::detail
|
||||
};
|
||||
|
||||
template < typename T, typename Allocator >
|
||||
requires std::is_copy_constructible_v<T>
|
||||
requires has_copy_traits<T>
|
||||
struct index_traits<std::vector<T, Allocator>> {
|
||||
uvalue operator()(const std::vector<T, Allocator>& v, std::size_t i) const {
|
||||
return i < v.size() ? uvalue{v[i]} : uvalue{};
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
#define META_HPP_DECLARE_INDEX_TRAITS_FOR(T) \
|
||||
namespace meta_hpp::detail \
|
||||
{ \
|
||||
template <> \
|
||||
struct index_traits<T> { \
|
||||
uvalue operator()(const T& v, std::size_t i) const { \
|
||||
return uvalue{v[i]}; \
|
||||
} \
|
||||
}; \
|
||||
}
|
||||
|
||||
@@ -16,17 +16,17 @@ namespace meta_hpp::detail
|
||||
|
||||
template < typename T >
|
||||
concept has_less_traits //
|
||||
= requires(const T& v) { less_traits<T>{}(v, v); };
|
||||
= requires(const T& v) { less_traits<std::remove_cv_t<T>>{}(v, v); };
|
||||
}
|
||||
|
||||
namespace meta_hpp::detail
|
||||
{
|
||||
template < typename T >
|
||||
requires requires(const T& v) {
|
||||
{ v < v } -> std::convertible_to<bool>;
|
||||
} && (!class_kind<T> || type_list_arity_v<typename class_traits<T>::argument_types> == 0)
|
||||
requires(!std::is_class_v<T>) && requires(T v) {
|
||||
{ v < v } -> std::convertible_to<bool>;
|
||||
}
|
||||
struct less_traits<T> {
|
||||
bool operator()(const T& l, const T& r) const {
|
||||
bool operator()(T l, T r) const {
|
||||
META_HPP_DETAIL_IGNORE_COMPARISON_WARNINGS_PUSH()
|
||||
return l < r;
|
||||
META_HPP_DETAIL_IGNORE_COMPARISON_WARNINGS_POP()
|
||||
|
||||
@@ -16,7 +16,7 @@ namespace meta_hpp::detail
|
||||
|
||||
template < typename T >
|
||||
concept has_unmap_traits //
|
||||
= requires(const T& v) { unmap_traits<T>{}(v); };
|
||||
= requires(const T& v) { unmap_traits<std::remove_cv_t<T>>{}(v); };
|
||||
}
|
||||
|
||||
namespace meta_hpp::detail
|
||||
|
||||
Reference in New Issue
Block a user