71 #include <type_traits>
102 template <
typename T>
111 template <
typename T,
typename =
void>
114 template <
typename T>
115 struct Callable<T, std::void_t<decltype(std::declval<T>()())>> : std::true_type {};
124 template <
typename OT,
typename T,
typename =
void>
127 template <
typename OT,
typename T>
128 struct Assignable<OT, T, std::void_t<decltype(std::declval<OT&>() = std::declval<T>())>> : std::true_type {};
137 template <
typename OT,
typename T,
typename =
void>
140 template <
typename OT,
typename T>
141 struct EqualityComparable<OT, T, std::void_t<decltype(std::declval<OT>() == std::declval<T>())>> : std::true_type {};
150 template <
typename OT,
typename T,
typename =
void>
153 template <
typename OT,
typename T>
156 std::void_t<decltype(std::declval<OT&>() < std::declval<T>()), decltype(std::declval<OT&>() > std::declval<T&>())>>
166 template <
typename OT,
typename T,
typename =
void>
169 template <
typename OT,
typename T>
171 std::void_t<decltype(std::declval<OT&>() << std::declval<T>()),
172 decltype(std::declval<OT&>() >> std::declval<T&>())>> : std::true_type {};
180 template <
typename T>
183 template <
typename T>
184 struct IsAtomic<std::atomic<T>> : std::true_type {};
192 template <
typename T,
typename =
void>
195 template <
typename T>
197 : std::is_base_of<std::shared_ptr<typename T::element_type>, T> {};
209 template <typename T, bool = IsSharedPtr<T>::value>
214 template <
typename T>
216 using Type =
typename T::element_type;
233 template <
typename T,
typename F>
234 [[nodiscard]]
static constexpr
auto has_member(F&& f) noexcept -> decltype(f(std::declval<T>()),
true) {
240 [[nodiscard]]
static constexpr
auto has_member(...) noexcept {
254 template <
typename T>
255 [[nodiscard]]
static constexpr
auto is_non_char_ptr() noexcept {
256 return std::is_pointer_v<std::decay_t<T>> &&
257 !std::is_same_v<std::remove_cv_t<std::remove_pointer_t<std::decay_t<T>>>,
char>;
270 template <
typename T>
271 [[nodiscard]]
static constexpr
bool is_integer() {
272 using U = std::remove_cv_t<T>;
273 return std::is_integral_v<U> && !std::is_same_v<U, bool> && !std::is_same_v<U, char> &&
274 !std::is_same_v<U, signed char> && !std::is_same_v<U, unsigned char>;
283 template <
typename T>
284 [[nodiscard]]
static constexpr
bool is_floating() {
285 return std::is_floating_point_v<std::remove_cv_t<T>>;
316 #define VLINK_HAS_MEMBER(T, member) \
317 vlink::Traits::has_member<T>([](auto&& obj) -> decltype((void)(obj.member), 0) { return 0; })
Detects whether a value of type T can be assigned to an instance of OT.
Definition: traits.h:125
Detects whether T can be invoked with no arguments.
Definition: traits.h:112
Empty tag type used wherever a type parameter must be supplied but carries no payload.
Definition: traits.h:89
Detects whether OT supports operator== with T.
Definition: traits.h:138
Type trait that always derives from std::false_type for any T.
Definition: traits.h:103
Detects whether OT supports both operator< and operator> with T.
Definition: traits.h:151
Detects whether T is a std::atomic specialisation.
Definition: traits.h:181
Detects whether T is (or derives from) a std::shared_ptr specialisation.
Definition: traits.h:193
Detects whether OT supports stream insertion (<<) and extraction (>>) with T.
Definition: traits.h:167
typename T::element_type Type
Element type unwrapped from the shared_ptr.
Definition: traits.h:216
Removes a single std::shared_ptr wrapper from T, leaving non-pointer types unchanged.
Definition: traits.h:210
T Type
Resolved type after optional shared_ptr removal.
Definition: traits.h:211