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