traits.hpp 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216
  1. /*!
  2. @file
  3. Defines function-like equivalents to the standard `<type_traits>`, and also
  4. to some utilities like `std::declval`.
  5. Copyright Louis Dionne 2013-2022
  6. Distributed under the Boost Software License, Version 1.0.
  7. (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
  8. */
  9. #ifndef BOOST_HANA_TRAITS_HPP
  10. #define BOOST_HANA_TRAITS_HPP
  11. #include <boost/hana/config.hpp>
  12. #include <boost/hana/integral_constant.hpp>
  13. #include <boost/hana/type.hpp>
  14. #include <cstddef>
  15. #include <type_traits>
  16. namespace boost { namespace hana { namespace traits {
  17. namespace detail {
  18. // We use this instead of hana::integral because we want to return
  19. // hana::integral_constants instead of std::integral_constants.
  20. template <template <typename ...> class F>
  21. struct hana_trait {
  22. template <typename ...T>
  23. constexpr auto operator()(T const& ...) const {
  24. using Result = typename F<typename T::type...>::type;
  25. return hana::integral_c<typename Result::value_type, Result::value>;
  26. }
  27. };
  28. }
  29. ///////////////////////
  30. // Type properties
  31. ///////////////////////
  32. // Primary type categories
  33. BOOST_HANA_INLINE_VARIABLE constexpr auto is_void = detail::hana_trait<std::is_void>{};
  34. BOOST_HANA_INLINE_VARIABLE constexpr auto is_null_pointer = detail::hana_trait<std::is_null_pointer>{};
  35. BOOST_HANA_INLINE_VARIABLE constexpr auto is_integral = detail::hana_trait<std::is_integral>{};
  36. BOOST_HANA_INLINE_VARIABLE constexpr auto is_floating_point = detail::hana_trait<std::is_floating_point>{};
  37. BOOST_HANA_INLINE_VARIABLE constexpr auto is_array = detail::hana_trait<std::is_array>{};
  38. BOOST_HANA_INLINE_VARIABLE constexpr auto is_enum = detail::hana_trait<std::is_enum>{};
  39. BOOST_HANA_INLINE_VARIABLE constexpr auto is_union = detail::hana_trait<std::is_union>{};
  40. BOOST_HANA_INLINE_VARIABLE constexpr auto is_class = detail::hana_trait<std::is_class>{};
  41. BOOST_HANA_INLINE_VARIABLE constexpr auto is_function = detail::hana_trait<std::is_function>{};
  42. BOOST_HANA_INLINE_VARIABLE constexpr auto is_pointer = detail::hana_trait<std::is_pointer>{};
  43. BOOST_HANA_INLINE_VARIABLE constexpr auto is_lvalue_reference = detail::hana_trait<std::is_lvalue_reference>{};
  44. BOOST_HANA_INLINE_VARIABLE constexpr auto is_rvalue_reference = detail::hana_trait<std::is_rvalue_reference>{};
  45. BOOST_HANA_INLINE_VARIABLE constexpr auto is_member_object_pointer = detail::hana_trait<std::is_member_object_pointer>{};
  46. BOOST_HANA_INLINE_VARIABLE constexpr auto is_member_function_pointer = detail::hana_trait<std::is_member_function_pointer>{};
  47. // Composite type categories
  48. BOOST_HANA_INLINE_VARIABLE constexpr auto is_fundamental = detail::hana_trait<std::is_fundamental>{};
  49. BOOST_HANA_INLINE_VARIABLE constexpr auto is_arithmetic = detail::hana_trait<std::is_arithmetic>{};
  50. BOOST_HANA_INLINE_VARIABLE constexpr auto is_scalar = detail::hana_trait<std::is_scalar>{};
  51. BOOST_HANA_INLINE_VARIABLE constexpr auto is_object = detail::hana_trait<std::is_object>{};
  52. BOOST_HANA_INLINE_VARIABLE constexpr auto is_compound = detail::hana_trait<std::is_compound>{};
  53. BOOST_HANA_INLINE_VARIABLE constexpr auto is_reference = detail::hana_trait<std::is_reference>{};
  54. BOOST_HANA_INLINE_VARIABLE constexpr auto is_member_pointer = detail::hana_trait<std::is_member_pointer>{};
  55. // Type properties
  56. BOOST_HANA_INLINE_VARIABLE constexpr auto is_const = detail::hana_trait<std::is_const>{};
  57. BOOST_HANA_INLINE_VARIABLE constexpr auto is_volatile = detail::hana_trait<std::is_volatile>{};
  58. BOOST_HANA_INLINE_VARIABLE constexpr auto is_trivial = detail::hana_trait<std::is_trivial>{};
  59. BOOST_HANA_INLINE_VARIABLE constexpr auto is_trivially_copyable = detail::hana_trait<std::is_trivially_copyable>{};
  60. BOOST_HANA_INLINE_VARIABLE constexpr auto is_standard_layout = detail::hana_trait<std::is_standard_layout>{};
  61. #if __cplusplus < 202002L
  62. BOOST_HANA_INLINE_VARIABLE constexpr auto is_pod = detail::hana_trait<std::is_pod>{};
  63. #endif
  64. #if __cplusplus < 201703L
  65. BOOST_HANA_INLINE_VARIABLE constexpr auto is_literal_type = detail::hana_trait<std::is_literal_type>{};
  66. #endif
  67. BOOST_HANA_INLINE_VARIABLE constexpr auto is_empty = detail::hana_trait<std::is_empty>{};
  68. BOOST_HANA_INLINE_VARIABLE constexpr auto is_polymorphic = detail::hana_trait<std::is_polymorphic>{};
  69. BOOST_HANA_INLINE_VARIABLE constexpr auto is_abstract = detail::hana_trait<std::is_abstract>{};
  70. BOOST_HANA_INLINE_VARIABLE constexpr auto is_signed = detail::hana_trait<std::is_signed>{};
  71. BOOST_HANA_INLINE_VARIABLE constexpr auto is_unsigned = detail::hana_trait<std::is_unsigned>{};
  72. // Supported operations
  73. BOOST_HANA_INLINE_VARIABLE constexpr auto is_constructible = detail::hana_trait<std::is_constructible>{};
  74. BOOST_HANA_INLINE_VARIABLE constexpr auto is_trivially_constructible = detail::hana_trait<std::is_trivially_constructible>{};
  75. BOOST_HANA_INLINE_VARIABLE constexpr auto is_nothrow_constructible = detail::hana_trait<std::is_nothrow_constructible>{};
  76. BOOST_HANA_INLINE_VARIABLE constexpr auto is_default_constructible = detail::hana_trait<std::is_default_constructible>{};
  77. BOOST_HANA_INLINE_VARIABLE constexpr auto is_trivially_default_constructible = detail::hana_trait<std::is_trivially_default_constructible>{};
  78. BOOST_HANA_INLINE_VARIABLE constexpr auto is_nothrow_default_constructible = detail::hana_trait<std::is_nothrow_default_constructible>{};
  79. BOOST_HANA_INLINE_VARIABLE constexpr auto is_copy_constructible = detail::hana_trait<std::is_copy_constructible>{};
  80. BOOST_HANA_INLINE_VARIABLE constexpr auto is_trivially_copy_constructible = detail::hana_trait<std::is_trivially_copy_constructible>{};
  81. BOOST_HANA_INLINE_VARIABLE constexpr auto is_nothrow_copy_constructible = detail::hana_trait<std::is_nothrow_copy_constructible>{};
  82. BOOST_HANA_INLINE_VARIABLE constexpr auto is_move_constructible = detail::hana_trait<std::is_move_constructible>{};
  83. BOOST_HANA_INLINE_VARIABLE constexpr auto is_trivially_move_constructible = detail::hana_trait<std::is_trivially_move_constructible>{};
  84. BOOST_HANA_INLINE_VARIABLE constexpr auto is_nothrow_move_constructible = detail::hana_trait<std::is_nothrow_move_constructible>{};
  85. BOOST_HANA_INLINE_VARIABLE constexpr auto is_assignable = detail::hana_trait<std::is_assignable>{};
  86. BOOST_HANA_INLINE_VARIABLE constexpr auto is_trivially_assignable = detail::hana_trait<std::is_trivially_assignable>{};
  87. BOOST_HANA_INLINE_VARIABLE constexpr auto is_nothrow_assignable = detail::hana_trait<std::is_nothrow_assignable>{};
  88. BOOST_HANA_INLINE_VARIABLE constexpr auto is_copy_assignable = detail::hana_trait<std::is_copy_assignable>{};
  89. BOOST_HANA_INLINE_VARIABLE constexpr auto is_trivially_copy_assignable = detail::hana_trait<std::is_trivially_copy_assignable>{};
  90. BOOST_HANA_INLINE_VARIABLE constexpr auto is_nothrow_copy_assignable = detail::hana_trait<std::is_nothrow_copy_assignable>{};
  91. BOOST_HANA_INLINE_VARIABLE constexpr auto is_move_assignable = detail::hana_trait<std::is_move_assignable>{};
  92. BOOST_HANA_INLINE_VARIABLE constexpr auto is_trivially_move_assignable = detail::hana_trait<std::is_trivially_move_assignable>{};
  93. BOOST_HANA_INLINE_VARIABLE constexpr auto is_nothrow_move_assignable = detail::hana_trait<std::is_nothrow_move_assignable>{};
  94. BOOST_HANA_INLINE_VARIABLE constexpr auto is_destructible = detail::hana_trait<std::is_destructible>{};
  95. BOOST_HANA_INLINE_VARIABLE constexpr auto is_trivially_destructible = detail::hana_trait<std::is_trivially_destructible>{};
  96. BOOST_HANA_INLINE_VARIABLE constexpr auto is_nothrow_destructible = detail::hana_trait<std::is_nothrow_destructible>{};
  97. BOOST_HANA_INLINE_VARIABLE constexpr auto has_virtual_destructor = detail::hana_trait<std::has_virtual_destructor>{};
  98. // Property queries
  99. BOOST_HANA_INLINE_VARIABLE constexpr auto alignment_of = detail::hana_trait<std::alignment_of>{};
  100. BOOST_HANA_INLINE_VARIABLE constexpr auto rank = detail::hana_trait<std::rank>{};
  101. BOOST_HANA_INLINE_VARIABLE constexpr struct extent_t {
  102. template <typename T, typename N>
  103. constexpr auto operator()(T const&, N const&) const {
  104. constexpr unsigned n = N::value;
  105. using Result = typename std::extent<typename T::type, n>::type;
  106. return hana::integral_c<typename Result::value_type, Result::value>;
  107. }
  108. template <typename T>
  109. constexpr auto operator()(T const& t) const
  110. { return (*this)(t, hana::uint_c<0>); }
  111. } extent{};
  112. // Type relationships
  113. BOOST_HANA_INLINE_VARIABLE constexpr auto is_same = detail::hana_trait<std::is_same>{};
  114. BOOST_HANA_INLINE_VARIABLE constexpr auto is_base_of = detail::hana_trait<std::is_base_of>{};
  115. BOOST_HANA_INLINE_VARIABLE constexpr auto is_convertible = detail::hana_trait<std::is_convertible>{};
  116. ///////////////////////
  117. // Type modifications
  118. ///////////////////////
  119. // Const-volatility specifiers
  120. BOOST_HANA_INLINE_VARIABLE constexpr auto remove_cv = metafunction<std::remove_cv>;
  121. BOOST_HANA_INLINE_VARIABLE constexpr auto remove_const = metafunction<std::remove_const>;
  122. BOOST_HANA_INLINE_VARIABLE constexpr auto remove_volatile = metafunction<std::remove_volatile>;
  123. BOOST_HANA_INLINE_VARIABLE constexpr auto add_cv = metafunction<std::add_cv>;
  124. BOOST_HANA_INLINE_VARIABLE constexpr auto add_const = metafunction<std::add_const>;
  125. BOOST_HANA_INLINE_VARIABLE constexpr auto add_volatile = metafunction<std::add_volatile>;
  126. // References
  127. BOOST_HANA_INLINE_VARIABLE constexpr auto remove_reference = metafunction<std::remove_reference>;
  128. BOOST_HANA_INLINE_VARIABLE constexpr auto add_lvalue_reference = metafunction<std::add_lvalue_reference>;
  129. BOOST_HANA_INLINE_VARIABLE constexpr auto add_rvalue_reference = metafunction<std::add_rvalue_reference>;
  130. // Pointers
  131. BOOST_HANA_INLINE_VARIABLE constexpr auto remove_pointer = metafunction<std::remove_pointer>;
  132. BOOST_HANA_INLINE_VARIABLE constexpr auto add_pointer = metafunction<std::add_pointer>;
  133. // Sign modifiers
  134. BOOST_HANA_INLINE_VARIABLE constexpr auto make_signed = metafunction<std::make_signed>;
  135. BOOST_HANA_INLINE_VARIABLE constexpr auto make_unsigned = metafunction<std::make_unsigned>;
  136. // Arrays
  137. BOOST_HANA_INLINE_VARIABLE constexpr auto remove_extent = metafunction<std::remove_extent>;
  138. BOOST_HANA_INLINE_VARIABLE constexpr auto remove_all_extents = metafunction<std::remove_all_extents>;
  139. // Miscellaneous transformations
  140. BOOST_HANA_INLINE_VARIABLE constexpr struct aligned_storage_t {
  141. template <typename Len, typename Align>
  142. constexpr auto operator()(Len const&, Align const&) const {
  143. constexpr std::size_t len = Len::value;
  144. constexpr std::size_t align = Align::value;
  145. using Result = typename std::aligned_storage<len, align>::type;
  146. return hana::type_c<Result>;
  147. }
  148. template <typename Len>
  149. constexpr auto operator()(Len const&) const {
  150. constexpr std::size_t len = Len::value;
  151. using Result = typename std::aligned_storage<len>::type;
  152. return hana::type_c<Result>;
  153. }
  154. } aligned_storage{};
  155. BOOST_HANA_INLINE_VARIABLE constexpr struct aligned_union_t {
  156. template <typename Len, typename ...T>
  157. constexpr auto operator()(Len const&, T const&...) const {
  158. constexpr std::size_t len = Len::value;
  159. using Result = typename std::aligned_union<len, typename T::type...>::type;
  160. return hana::type_c<Result>;
  161. }
  162. } aligned_union{};
  163. BOOST_HANA_INLINE_VARIABLE constexpr auto decay = metafunction<std::decay>;
  164. // enable_if
  165. // disable_if
  166. // conditional
  167. BOOST_HANA_INLINE_VARIABLE constexpr auto common_type = metafunction<std::common_type>;
  168. BOOST_HANA_INLINE_VARIABLE constexpr auto underlying_type = metafunction<std::underlying_type>;
  169. ///////////////////////
  170. // Utilities
  171. ///////////////////////
  172. struct declval_t {
  173. template <typename T>
  174. typename std::add_rvalue_reference<
  175. typename T::type
  176. >::type operator()(T const&) const;
  177. };
  178. BOOST_HANA_INLINE_VARIABLE constexpr declval_t declval{};
  179. } }} // end namespace boost::hana
  180. #endif // !BOOST_HANA_TRAITS_HPP