mirror of
https://github.com/BlackMATov/meta.hpp.git
synced 2025-12-14 19:41:29 +07:00
fix uvalue copy traits
ref: https://github.com/BlackMATov/meta.hpp/issues/100
This commit is contained in:
@@ -90,6 +90,9 @@ namespace
|
|||||||
int ivec2_big::copy_constructor_counter{0};
|
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") {
|
TEST_CASE("meta/meta_utilities/value2") {
|
||||||
namespace meta = meta_hpp;
|
namespace meta = meta_hpp;
|
||||||
|
|
||||||
|
|||||||
@@ -109,6 +109,9 @@ namespace
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
META_HPP_DECLARE_COPY_TRAITS_FOR(ivec2)
|
||||||
|
META_HPP_DECLARE_COPY_TRAITS_FOR(ivec2_big)
|
||||||
|
|
||||||
TEST_CASE("meta/meta_utilities/value/_") {
|
TEST_CASE("meta/meta_utilities/value/_") {
|
||||||
namespace meta = meta_hpp;
|
namespace meta = meta_hpp;
|
||||||
|
|
||||||
@@ -497,6 +500,25 @@ TEST_CASE("meta/meta_utilities/value") {
|
|||||||
CHECK_FALSE(u.has_copy_op());
|
CHECK_FALSE(u.has_copy_op());
|
||||||
CHECK_THROWS(std::ignore = u.copy());
|
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<const std::unique_ptr<int>>;
|
||||||
|
std::unique_ptr u = std::make_unique<int>(42);
|
||||||
|
CHECK(meta::uvalue{ref_t{u}}.has_copy_op());
|
||||||
|
meta::uvalue v = meta::uvalue{ref_t{u}}.copy();
|
||||||
|
CHECK(v.get_type() == meta::resolve_type<ref_t>());
|
||||||
|
CHECK(v.as<ref_t>().get().get() == u.get());
|
||||||
|
}
|
||||||
|
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") {
|
SUBCASE("unmap") {
|
||||||
|
|||||||
@@ -22,10 +22,89 @@ namespace meta_hpp::detail
|
|||||||
namespace meta_hpp::detail
|
namespace meta_hpp::detail
|
||||||
{
|
{
|
||||||
template < typename T >
|
template < typename T >
|
||||||
requires requires(const T& v) { uvalue{v}; }
|
requires(!std::is_class_v<T> && std::is_copy_constructible_v<T>)
|
||||||
struct copy_traits<T> {
|
struct copy_traits<T> {
|
||||||
uvalue operator()(const T& v) const {
|
uvalue operator()(const T& v) const {
|
||||||
return uvalue{v};
|
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}; \
|
||||||
|
} \
|
||||||
|
}; \
|
||||||
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user