14#include <type_safe/strong_typedef.hpp>
20template <
template <
typename...>
class BaseTemplateT,
typename DerivedT>
23 template <
typename... Args>
24 static constexpr std::true_type
25 internal_test (
const BaseTemplateT<Args...> *);
27 static constexpr std::false_type internal_test (...);
29 static constexpr bool value =
30 decltype (internal_test (std::declval<DerivedT *> ()))::value;
34template <
template <
typename...>
class BaseTemplateT,
typename DerivedT>
35inline constexpr bool is_derived_from_template_v =
36 is_derived_from_template<BaseTemplateT, DerivedT>::value;
38namespace internal_test
53static_assert (is_derived_from_template_v<MyTemplateBase, Derived>);
54static_assert (!is_derived_from_template_v<MyTemplateBase, int>);
55static_assert (!is_derived_from_template_v<MyTemplateBase, OtherBase>);
56static_assert (!is_derived_from_template_v<OtherTemplateBase, Derived>);
62 typename T::value_type;
64 typename T::const_iterator;
65 { t.begin () } -> std::same_as<typename T::iterator>;
66 { t.end () } -> std::same_as<typename T::iterator>;
67 { t.size () } -> std::convertible_to<std::size_t>;
76template <
typename... Ts>
79template <
typename... Ts>
84concept FinalClass = std::is_final_v<T> && std::is_class_v<T>;
95 requires requires (T v) {
96 []<
typename... Vs> (std::variant<Vs...> &) { }(v);
107 []<
typename... Vs> (std::variant<Vs...> &)
108 requires (std::is_pointer_v<Vs> && ...)
117 typename T::value_type;
118 requires std::same_as<T, std::optional<typename T::value_type>>;
131template <
typename T,
typename Deleter>
151using remove_smart_pointer_t =
typename remove_smart_pointer<T>::type;
157 remove_smart_pointer_t<std::remove_pointer_t<std::decay_t<T>>>>;
158static_assert (std::is_same_v<base_type<int * const &>,
int>);
159static_assert (std::is_same_v<base_type<std::shared_ptr<int>
const &>,
int>);
163 typename std::array<typename T::value_type, std::tuple_size<T>::value>;
164 requires std::same_as<
165 T, std::array<typename T::value_type, std::tuple_size<T>::value>>;
173template <
typename T>
struct is_unique_ptr<std::unique_ptr<T>> : std::true_type
178static_assert (is_unique_ptr_v<std::unique_ptr<int>>);
179static_assert (!is_unique_ptr_v<std::shared_ptr<int>>);
184template <
typename T>
struct is_shared_ptr<std::shared_ptr<T>> : std::true_type
190concept SmartPtr = is_unique_ptr_v<T> || is_shared_ptr_v<T>;
192template <
typename Derived,
typename Base>
194 std::derived_from<Derived, Base> && !std::same_as<Derived, Base>;
196template <
typename Derived,
template <
typename>
class BaseTemplate>
201template <
typename T>
class CRTPBase
203 CRTPBase () =
default;
222#define DEBUG_TEMPLATE_PARAM(tparam) \
223 [[maybe_unused]] typedef typename tparam::something_made_up X;
225template <
typename R,
typename T>
227 std::ranges::range<R>
228 && (std::derived_from<std::ranges::range_value_t<R>, T> ||
234struct build_test_type
236 template <
typename... Args>
237 build_test_type (Args &&...) { }
246 t.template build<detail::build_test_type> ()
247 } -> std::same_as<std::unique_ptr<detail::build_test_type>>;
249namespace object_builder_test
253 template <
typename T>
auto build () {
return std::make_unique<T> (); }
257 template <
typename T>
void build () { }
Concept that checks if a type is a builder for objects.
std::remove_cvref_t< remove_smart_pointer_t< std::remove_pointer_t< std::decay_t< T > > > > base_type
An improved version of std::decay_t that also removes raw and smart pointers.