14#include <type_safe/strong_typedef.hpp>
17template <
template <
typename...>
class BaseTemplateT,
typename DerivedT>
20 template <
typename... Args>
21 static constexpr std::true_type
22 internal_test (
const BaseTemplateT<Args...> *);
24 static constexpr std::false_type internal_test (...);
26 static constexpr bool value =
27 decltype (internal_test (std::declval<DerivedT *> ()))::value;
31template <
template <
typename...>
class BaseTemplateT,
typename DerivedT>
32inline constexpr bool is_derived_from_template_v =
33 is_derived_from_template<BaseTemplateT, DerivedT>::value;
35namespace internal_test
50static_assert (is_derived_from_template_v<MyTemplateBase, Derived>);
51static_assert (!is_derived_from_template_v<MyTemplateBase, int>);
52static_assert (!is_derived_from_template_v<MyTemplateBase, OtherBase>);
53static_assert (!is_derived_from_template_v<OtherTemplateBase, Derived>);
59 typename T::value_type;
61 typename T::const_iterator;
62 { t.begin () } -> std::same_as<typename T::iterator>;
63 { t.end () } -> std::same_as<typename T::iterator>;
64 { t.size () } -> std::convertible_to<std::size_t>;
73template <
typename... Ts>
76template <
typename... Ts>
81concept FinalClass = std::is_final_v<T> && std::is_class_v<T>;
92 requires requires (T v) {
93 []<
typename... Vs> (std::variant<Vs...> &) { }(v);
104 []<
typename... Vs> (std::variant<Vs...> &)
105 requires (std::is_pointer_v<Vs> && ...)
114 typename T::value_type;
115 requires std::same_as<T, std::optional<typename T::value_type>>;
128template <
typename T,
typename Deleter>
148using remove_smart_pointer_t =
typename remove_smart_pointer<T>::type;
153using base_type = std::remove_cvref_t<
154 remove_smart_pointer_t<std::remove_pointer_t<std::decay_t<T>>>>;
155static_assert (std::is_same_v<base_type<int * const &>,
int>);
156static_assert (std::is_same_v<base_type<std::shared_ptr<int>
const &>,
int>);
160 typename std::array<typename T::value_type, std::tuple_size<T>::value>;
161 requires std::same_as<
162 T, std::array<typename T::value_type, std::tuple_size<T>::value>>;
170template <
typename T>
struct is_unique_ptr<std::unique_ptr<T>> : std::true_type
175static_assert (is_unique_ptr_v<std::unique_ptr<int>>);
176static_assert (!is_unique_ptr_v<std::shared_ptr<int>>);
181template <
typename T>
struct is_shared_ptr<std::shared_ptr<T>> : std::true_type
187concept SmartPtr = is_unique_ptr_v<T> || is_shared_ptr_v<T>;
189template <
typename Derived,
typename Base>
191 std::derived_from<Derived, Base> && !std::same_as<Derived, Base>;
193template <
typename Derived,
template <
typename>
class BaseTemplate>
198template <
typename T>
class CRTPBase
200 CRTPBase () =
default;
219#define DEBUG_TEMPLATE_PARAM(tparam) \
220 [[maybe_unused]] typedef typename tparam::something_made_up X;
222template <
typename R,
typename T>
224 std::ranges::range<R>
225 && (std::derived_from<std::ranges::range_value_t<R>, T> ||
231struct build_test_type
233 template <
typename... Args>
234 build_test_type (Args &&...) { }
243 t.template build<detail::build_test_type> ()
244 } -> std::same_as<std::unique_ptr<detail::build_test_type>>;
246namespace object_builder_test
250 template <
typename T>
auto build () {
return std::make_unique<T> (); }
254 template <
typename T>
void build () { }
Concept that checks if a type is a builder for objects.