diff --git a/develop/untests/meta_utilities/value4_tests.cpp b/develop/untests/meta_utilities/value4_tests.cpp index c469142..7b18826 100644 --- a/develop/untests/meta_utilities/value4_tests.cpp +++ b/develop/untests/meta_utilities/value4_tests.cpp @@ -46,6 +46,8 @@ namespace }; } +META_HPP_DECLARE_COPY_TRAITS_FOR(clazz_throw_dtor) + TEST_CASE("meta/meta_utilities/value4") { namespace meta = meta_hpp; diff --git a/develop/untests/meta_utilities/value_tests.cpp b/develop/untests/meta_utilities/value_tests.cpp index 673db51..e4e7d77 100644 --- a/develop/untests/meta_utilities/value_tests.cpp +++ b/develop/untests/meta_utilities/value_tests.cpp @@ -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: @@ -118,6 +122,8 @@ META_HPP_DECLARE_COPY_TRAITS_FOR(ivec2_big) META_HPP_DECLARE_DEREF_TRAITS_FOR(deref_custom_class) +META_HPP_DECLARE_INDEX_TRAITS_FOR(ivec2) + TEST_CASE("meta/meta_utilities/value/_") { namespace meta = meta_hpp; @@ -978,6 +984,23 @@ TEST_CASE("meta/meta_utilities/value/arrays") { CHECK(v[2].as() == 3); CHECK_FALSE(v[3]); } + + SUBCASE("ivec2/ivec3") { + { + meta::uvalue v{ivec2{1,2}}; + CHECK(v.get_type() == meta::resolve_type()); + CHECK(v.has_index_op()); + + CHECK(v[0].as() == 1); + CHECK(v[1].as() == 2); + } + { + meta::uvalue v{ivec3{1,2,3}}; + CHECK(v.get_type() == meta::resolve_type()); + CHECK_FALSE(v.has_index_op()); + CHECK_THROWS(std::ignore = v[0]); + } + } } TEST_CASE("meta/meta_utilities/value/functions") { diff --git a/headers/meta.hpp/meta_detail/value_traits/index_traits.hpp b/headers/meta.hpp/meta_detail/value_traits/index_traits.hpp index edf4e06..7aba1ee 100644 --- a/headers/meta.hpp/meta_detail/value_traits/index_traits.hpp +++ b/headers/meta.hpp/meta_detail/value_traits/index_traits.hpp @@ -9,6 +9,8 @@ #include "../../meta_base.hpp" #include "../../meta_uvalue.hpp" +#include "copy_traits.hpp" + namespace meta_hpp::detail { template < typename T > @@ -22,7 +24,7 @@ namespace meta_hpp::detail namespace meta_hpp::detail { template < typename T > - requires std::is_copy_constructible_v + requires has_copy_traits struct index_traits { 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 + requires has_copy_traits struct index_traits> { uvalue operator()(const std::array& 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 + requires has_copy_traits struct index_traits> { uvalue operator()(const std::basic_string& 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 + requires has_copy_traits struct index_traits> { uvalue operator()(const std::basic_string_view& 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 + requires has_copy_traits struct index_traits> { uvalue operator()(const std::span& 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 + requires has_copy_traits struct index_traits> { uvalue operator()(const std::vector& 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 { \ + uvalue operator()(const T& v, std::size_t i) const { \ + return uvalue{v[i]}; \ + } \ + }; \ + }