From 2d30b3ce853ecb71e9676796c020244eb2cfa49b Mon Sep 17 00:00:00 2001 From: Avril Date: Wed, 3 May 2023 04:08:39 +0100 Subject: [PATCH] Adding polymorphic boxing helpers. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Fortune for libexopt's current commit: Small blessing − 小吉 --- include/boxed.h | 34 +++++++++++++++++++++++++++++++++- 1 file changed, 33 insertions(+), 1 deletion(-) diff --git a/include/boxed.h b/include/boxed.h index ba7e41c..b1b3eaa 100644 --- a/include/boxed.h +++ b/include/boxed.h @@ -34,7 +34,9 @@ namespace exopt::types { namespace boxed { #endif return std::make_unique(*c); } - + template + concept binary_convertible = std::is_convertible_v and std::is_convertible_v; + template struct Box { typedef boxable_value_type::type type; @@ -102,6 +104,21 @@ namespace exopt::types { namespace boxed { std::unique_ptr m_ptr; // Unique m_ptr; }; +#define _EO_ADD_RV std::add_rvalue_reference_v + + template + constexpr inline bool is_boxable_v = binary_convertible<_EO_ADD_RV, _EO_ADD_RV > and requires(T&& value) { + typename Box; + typename Box::type; + { std::make_unique(std::move(value)) } -> std::same_as>; + }; + template concept is_boxable = is_boxable_v; + + template + constexpr inline bool is_nothrow_boxable_v = is_boxable_v && std::is_nothrow_constructible_v, T>; + +#undef _EO_ADD_RV + template requires(requires(T&& o) { static_cast(o); }) constexpr Box static_box_cast(Box&& b) noexcept { return Box::from_raw_ptr(static_cast(b.release())); } @@ -115,6 +132,21 @@ namespace exopt::types { namespace boxed { throw; } } //TODO: Overload for `const&` that does the type check *before* the copy allocation. + + template requires(std::derived_from) + constexpr Box box(R&& value, util::comptime auto Check = _EO_CONSTANT_VALUE(false)) noexcept(std::is_nothrow_invocable_v< Box::new_dynamic) //XXX: This seems illegal... + { return Box::template new_dynamic(std::move(value)); } + + template + constexpr Box box(std::convertible_to auto&& value) noexcept(std::is_nothrow_constructible_v, std::add_rvalue_reference_v>) + { + /*if constexpr(requires(decltype(value) v) { static_cast(std::move(v)); }) { + return Box::template new_dynamic(std::move(value)); + } else */return { static_cast(std::move(value)) }; + } + template + constexpr Box box(T&& value) noexcept(std::is_nothrow_constructible_v, T>) + { return { std::move(value) }; } } using boxed::Box; }