halcheck 1.0
Loading...
Searching...
No Matches
type_traits.hpp
1#ifndef HALCHECK_LIB_TYPE_TRAITS_HPP
2#define HALCHECK_LIB_TYPE_TRAITS_HPP
3
11#include <cstddef>
12#include <functional>
13#include <istream>
14#include <ostream>
15#include <string>
16#include <tuple>
17#include <type_traits> // IWYU pragma: export
18
19#ifdef HALCHECK_DOXYGEN
24#define HALCHECK_REQUIRE(...)
29#define HALCHECK_REQUIRE_(...)
30#else
31#define HALCHECK_REQUIRE(...) ::halcheck::lib::enable_if_t<(__VA_ARGS__), int> = 0
32#define HALCHECK_REQUIRE_(...) ::halcheck::lib::enable_if_t<(__VA_ARGS__), int>
33#endif
34
35namespace halcheck { namespace lib {
36
42template<typename...>
43using void_t = void;
44
50template<bool Cond, typename T, typename F>
52
58template<typename... Args>
60
61template<>
62struct conjunction<> : std::true_type {};
63
64template<typename T>
65struct conjunction<T> : T {};
66
67template<typename T, typename... Args>
68struct conjunction<T, Args...> : lib::conditional_t<bool(T::value), conjunction<Args...>, T> {};
69
75template<typename... Args>
77
78template<>
79struct disjunction<> : std::false_type {};
80
81template<typename T>
82struct disjunction<T> : T {};
83
84template<typename T, typename... Args>
85struct disjunction<T, Args...> : lib::conditional_t<bool(T::value), T, disjunction<Args...>> {};
86
92template<bool Cond, typename T = void>
94
100template<typename T>
102
108template<typename T>
110
116template<typename T>
118
124template<typename T>
126
132template<typename... Args>
133using common_type_t = typename std::common_type<Args...>::type;
134
140template<typename T>
142
148template<typename T, typename...>
150 using type = T;
151};
152
158template<typename T, typename...>
160
166template<std::size_t I, typename T>
167using tuple_element_t = typename std::tuple_element<I, T>::type;
168
174template<typename T>
176
182template<typename T>
184
190template<typename T>
192
198template<typename T>
200
206template<typename T>
208
214template<typename T>
216
222template<typename T>
224
230template<typename T>
232
233namespace detail {
234template<typename, template<typename...> class Op, typename... Args>
235struct is_detected_helper : std::false_type {};
236
237template<template<typename...> class Op, typename... Args>
238struct is_detected_helper<lib::void_t<Op<Args...>>, Op, Args...> : std::true_type {};
239} // namespace detail
240
246template<template<typename...> class Op, typename... Args>
247struct is_detected : detail::is_detected_helper<void, Op, Args...> {};
248
250template<typename From, typename To>
252
254template<typename T, typename U>
256
258template<typename T, typename U>
260
262template<typename T>
263using tuple_like = decltype(std::tuple_size<T>::value);
264
266template<typename T>
267struct is_tuple_like : lib::is_detected<lib::tuple_like, T> {};
268
270template<class T, typename... Args>
271using brace_constructible = decltype(T{std::declval<Args>()...});
272
279template<class T, typename... Args>
280struct is_brace_constructible : lib::is_detected<lib::brace_constructible, T, Args...> {};
281
282namespace detail {
283using std::swap;
284
286template<typename T>
287using swappable = decltype(swap(std::declval<T &>(), std::declval<T &>()));
288
290template<typename T>
292} // namespace detail
293
294using detail::nothrow_swappable;
295using detail::swappable;
296
302template<typename T>
303struct is_swappable : lib::is_detected<lib::swappable, T> {};
304
310template<typename T>
311struct is_nothrow_swappable : lib::is_detected<lib::nothrow_swappable, T> {};
312
314template<typename T>
315using destructible = lib::enable_if_t<std::is_destructible<T>{}>;
316
318template<typename T>
319using default_constructible = lib::enable_if_t<std::is_default_constructible<T>{}>;
320
322template<typename T>
323using move_constructible = lib::enable_if_t<std::is_move_constructible<T>{}>;
324
326template<typename T>
327using move_assignable = lib::enable_if_t<std::is_move_assignable<T>{}>;
328
330template<typename T>
331using movable = lib::void_t<lib::move_constructible<T>, lib::move_assignable<T>>;
332
335template<typename T>
336struct is_movable : lib::is_detected<lib::movable, T> {};
337
339template<typename T>
340using copy_constructible = lib::enable_if_t<std::is_copy_constructible<T>{}>;
341
343template<typename T>
344using copy_assignable = lib::enable_if_t<std::is_copy_assignable<T>{}>;
345
347template<typename T>
348using copyable = lib::void_t<lib::copy_constructible<T>, lib::copy_assignable<T>>;
349
354template<typename T>
355struct is_copyable : lib::is_detected<lib::copyable, T> {};
356
358template<typename B>
359using boolean_testable =
360 lib::void_t<lib::convertible<B, bool>, lib::convertible<decltype(!std::forward<B>(std::declval<B &>())), bool>>;
361
369template<typename B>
370struct is_boolean_testable : lib::is_detected<lib::boolean_testable, B> {};
371
373template<typename T>
374using equality_comparable = lib::void_t<
375 lib::boolean_testable<decltype(std::declval<const T &>() == std::declval<const T &>())>,
376 lib::boolean_testable<decltype(std::declval<const T &>() != std::declval<const T &>())>>;
377
385template<typename T>
386struct is_equality_comparable : lib::is_detected<lib::equality_comparable, T> {};
387
389template<typename T>
390using hashable = lib::same<decltype(std::declval<std::hash<T>>()(std::declval<T &>())), std::size_t>;
391
397template<typename T>
398struct is_hashable : lib::is_detected<lib::hashable, T> {};
399
401template<typename T, typename Stream>
402using printable = lib::same<decltype(std::declval<Stream &>() << std::declval<const T &>()), Stream &>;
403
412template<typename T, typename CharT = char, typename Traits = std::char_traits<CharT>>
413struct is_printable : lib::is_detected<lib::printable, T, std::basic_ostream<CharT, Traits>> {};
414
416template<typename T, typename Stream>
417using parsable = lib::same<decltype(std::declval<Stream &>() >> std::declval<T &>()), Stream &>;
418
427template<typename T, typename CharT = char, typename Traits = std::char_traits<CharT>>
428struct is_parsable : lib::is_detected<lib::parsable, T, std::basic_istream<CharT, Traits>> {};
429
436template<typename T, template<typename...> class F>
438
439template<typename... Args, template<typename...> class F>
440struct is_specialization_of<F<Args...>, F> : std::true_type {};
441
443template<typename T, template<typename...> class F>
444using specialization_of = lib::enable_if_t<lib::is_specialization_of<T, F>{}>;
445
446}} // namespace halcheck::lib
447
448#endif
T declval(T... args)
typename std::add_pointer< T >::type add_pointer_t
An implementation of std::add_pointer_t.
Definition type_traits.hpp:223
typename std::add_lvalue_reference< T >::type add_lvalue_reference_t
An implementation of std::add_lvalue_reference_t.
Definition type_traits.hpp:199
typename std::remove_cv< typename std::remove_reference< T >::type >::type remove_cvref_t
An implementation of std::remove_cvref_t.
Definition type_traits.hpp:141
typename std::decay< T >::type decay_t
An implementation of std::decay_t.
Definition type_traits.hpp:101
typename std::remove_cv< T >::type remove_cv_t
An implementation of std::remove_cv_t.
Definition type_traits.hpp:109
typename std::add_rvalue_reference< T >::type add_rvalue_reference_t
An implementation of std::add_rvalue_reference_t.
Definition type_traits.hpp:207
typename std::enable_if< Cond, T >::type enable_if_t
An implementation of std::enable_if_t.
Definition type_traits.hpp:93
typename std::remove_extent< T >::type remove_extent_t
An implementation of std::remove_extent_t.
Definition type_traits.hpp:117
typename std::make_signed< T >::type make_signed_t
An implementation of std::make_signed_t.
Definition type_traits.hpp:191
typename std::tuple_element< I, T >::type tuple_element_t
Provides compile-time access the the types of the elements of a tuple.
Definition type_traits.hpp:167
typename std::remove_reference< T >::type remove_reference_t
An implementation of std::remove_reference_t.
Definition type_traits.hpp:175
typename std::make_unsigned< T >::type make_unsigned_t
An implementation of std::make_unsigned_t.
Definition type_traits.hpp:125
typename std::common_type< Args... >::type common_type_t
An implementation of std::common_type_t.
Definition type_traits.hpp:133
void void_t
An implementation of std::void_t.
Definition type_traits.hpp:43
typename std::conditional< Cond, T, F >::type conditional_t
An implementation of std::conditional_t.
Definition type_traits.hpp:51
typename std::add_const< T >::type add_const_t
An implementation of std::add_const_t.
Definition type_traits.hpp:215
typename std::remove_pointer< T >::type remove_pointer_t
An implementation of std::remove_pointer_t.
Definition type_traits.hpp:231
T type_identity_t
An implementation of std::type_identity_t.
Definition type_traits.hpp:159
typename std::remove_const< T >::type remove_const_t
An implementation of std::remove_const_t.
Definition type_traits.hpp:183
An implementation of std::conjunction.
Definition type_traits.hpp:59
An implementation of std::disjunction.
Definition type_traits.hpp:76
Determines if a type is satisfies the boolean-testable concept.
Definition type_traits.hpp:370
Determines if a type is constructible from a given set of argument types using initiailizer-list-styl...
Definition type_traits.hpp:280
Determines if a type is copy constructible and copy assignable.
Definition type_traits.hpp:355
An implementation of std::experimental::is_detected.
Definition type_traits.hpp:247
Determines if a type satisfies the EqualityComparable concept.
Definition type_traits.hpp:386
Determines if a type has a valid std::hash specialization.
Definition type_traits.hpp:398
Determines if a type is move constructible and move assignable.
Definition type_traits.hpp:336
An implementation of std::is_nothrow_swappable.
Definition type_traits.hpp:311
Determines whether a type is parsable (i.e. can be read from a std::basic_istream ).
Definition type_traits.hpp:428
Determines whether a type is printable (i.e. can be output on a std::basic_ostream ).
Definition type_traits.hpp:413
Determines if a type is a specialization of a template class.
Definition type_traits.hpp:437
An implementation of std::is_swappable.
Definition type_traits.hpp:303
An implementation of std::type_identity.
Definition type_traits.hpp:149
T swap(T... args)