Compare commits

...

4 Commits

Author SHA1 Message Date
BlackMATov
c72e4047c0 fix all uvalue traits
ref: https://github.com/BlackMATov/meta.hpp/issues/100
2024-09-05 08:49:30 +07:00
BlackMATov
774d0c04c2 fix uvalue index traits
ref: https://github.com/BlackMATov/meta.hpp/issues/100
2024-09-05 07:28:05 +07:00
BlackMATov
41855b3ed7 fix uvalue deref traits
ref: https://github.com/BlackMATov/meta.hpp/issues/100
2024-09-05 07:18:15 +07:00
BlackMATov
5d5ba52045 fix uvalue copy traits
ref: https://github.com/BlackMATov/meta.hpp/issues/100
2024-09-05 06:30:44 +07:00
10 changed files with 379 additions and 54 deletions

View File

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

View File

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

View File

@@ -46,6 +46,8 @@ namespace
};
}
META_HPP_DECLARE_COPY_TRAITS_FOR(clazz_throw_dtor)
TEST_CASE("meta/meta_utilities/value4") {
namespace meta = meta_hpp;

View File

@@ -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") {

View File

@@ -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}; \
} \
}; \
}

View File

@@ -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}; \
} \
}; \
}

View File

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

View File

@@ -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]}; \
} \
}; \
}

View File

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

View File

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