File indexing completed on 2025-12-15 09:53:11
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010 #ifndef BOOST_HANA_TYPE_HPP
0011 #define BOOST_HANA_TYPE_HPP
0012
0013 #include <boost/hana/fwd/type.hpp>
0014
0015 #include <boost/hana/bool.hpp>
0016 #include <boost/hana/config.hpp>
0017 #include <boost/hana/core/when.hpp>
0018 #include <boost/hana/detail/operators/adl.hpp>
0019 #include <boost/hana/detail/operators/comparable.hpp>
0020 #include <boost/hana/fwd/concept/metafunction.hpp>
0021 #include <boost/hana/fwd/core/make.hpp>
0022 #include <boost/hana/fwd/equal.hpp>
0023 #include <boost/hana/fwd/hash.hpp>
0024 #include <boost/hana/integral_constant.hpp>
0025
0026 #include <type_traits>
0027 #include <utility>
0028
0029
0030 namespace boost { namespace hana {
0031
0032
0033
0034
0035 template <typename T>
0036 struct basic_type : detail::operators::adl<basic_type<T>> {
0037 using hana_tag = type_tag;
0038
0039 using type = T;
0040 constexpr auto operator+() const { return *this; }
0041 };
0042
0043
0044
0045
0046
0047 template <typename T>
0048 struct type_impl {
0049 struct _ : basic_type<T> { };
0050 };
0051
0052
0053
0054
0055 namespace detail {
0056 template <typename T, typename = type_tag>
0057 struct decltype_t {
0058 using type = typename std::remove_reference<T>::type;
0059 };
0060
0061 template <typename T>
0062 struct decltype_t<T, typename hana::tag_of<T>::type> {
0063 using type = typename std::remove_reference<T>::type::type;
0064 };
0065 }
0066
0067
0068 template <typename T>
0069 constexpr auto decltype_t::operator()(T&&) const
0070 { return hana::type_c<typename detail::decltype_t<T>::type>; }
0071
0072
0073
0074
0075
0076 namespace detail {
0077 template <typename T, typename = type_tag>
0078 struct typeid_t {
0079 using type = typename std::remove_cv<
0080 typename std::remove_reference<T>::type
0081 >::type;
0082 };
0083
0084 template <typename T>
0085 struct typeid_t<T, typename hana::tag_of<T>::type> {
0086 using type = typename std::remove_reference<T>::type::type;
0087 };
0088 }
0089
0090 template <typename T>
0091 constexpr auto typeid_t::operator()(T&&) const
0092 { return hana::type_c<typename detail::typeid_t<T>::type>; }
0093
0094
0095
0096
0097
0098 template <>
0099 struct make_impl<type_tag> {
0100 template <typename T>
0101 static constexpr auto apply(T&& t)
0102 { return hana::typeid_(static_cast<T&&>(t)); }
0103 };
0104
0105
0106
0107
0108
0109 template <typename T>
0110 constexpr auto sizeof_t::operator()(T&&) const
0111 { return hana::size_c<sizeof(typename detail::decltype_t<T>::type)>; }
0112
0113
0114
0115
0116
0117
0118 template <typename T>
0119 constexpr auto alignof_t::operator()(T&&) const
0120 { return hana::size_c<alignof(typename detail::decltype_t<T>::type)>; }
0121
0122
0123
0124
0125
0126 namespace type_detail {
0127 template <typename F, typename ...Args, typename = decltype(
0128 std::declval<F&&>()(std::declval<Args&&>()...)
0129 )>
0130 constexpr auto is_valid_impl(int) { return hana::true_c; }
0131
0132 template <typename F, typename ...Args>
0133 constexpr auto is_valid_impl(...) { return hana::false_c; }
0134
0135 template <typename F>
0136 struct is_valid_fun {
0137 template <typename ...Args>
0138 constexpr auto operator()(Args&& ...) const
0139 { return is_valid_impl<F, Args&&...>(int{}); }
0140 };
0141 }
0142
0143
0144 template <typename F>
0145 constexpr auto is_valid_t::operator()(F&&) const
0146 { return type_detail::is_valid_fun<F&&>{}; }
0147
0148 template <typename F, typename ...Args>
0149 constexpr auto is_valid_t::operator()(F&&, Args&& ...) const
0150 { return type_detail::is_valid_impl<F&&, Args&&...>(int{}); }
0151
0152
0153
0154
0155
0156
0157
0158
0159 namespace template_detail {
0160 template <typename ...T> struct args;
0161 template <typename ...> using always_void = void;
0162
0163 template <template <typename ...> class F, typename Args, typename = void>
0164 struct specialization_is_valid
0165 : std::false_type
0166 { };
0167
0168 template <template <typename ...> class F, typename ...T>
0169 struct specialization_is_valid<F, args<T...>, always_void<F<T...>>>
0170 : std::true_type
0171 { };
0172 }
0173
0174 template <template <typename ...> class F>
0175 struct template_t {
0176 template <typename ...T>
0177 struct apply {
0178 using type = F<T...>;
0179 };
0180
0181 template <typename ...T, typename = std::enable_if_t<
0182 template_detail::specialization_is_valid<F, template_detail::args<typename T::type...>>::value
0183 >>
0184 constexpr auto operator()(T const& ...) const
0185 { return hana::type<F<typename T::type...>>{}; }
0186 };
0187
0188
0189
0190
0191 template <template <typename ...> class F>
0192 struct metafunction_t {
0193 template <typename ...T>
0194 using apply = F<T...>;
0195
0196 template <typename ...T>
0197 constexpr hana::type<typename F<typename T::type...>::type>
0198 operator()(T const& ...) const { return {}; }
0199 };
0200
0201
0202
0203
0204 namespace detail {
0205 template <typename F, typename ...T>
0206 struct always_first { using type = F; };
0207 }
0208 template <typename F>
0209 struct metafunction_class_t {
0210 template <typename ...T>
0211 using apply = typename detail::always_first<F, T...>::type::template apply<T...>;
0212
0213 template <typename ...T>
0214 constexpr hana::type<typename detail::always_first<F, T...>::type::template apply<typename T::type...>::type>
0215 operator()(T const& ...) const { return {}; }
0216 };
0217
0218
0219
0220
0221 template <template <typename ...> class F>
0222 struct Metafunction<template_t<F>> {
0223 static constexpr bool value = true;
0224 };
0225
0226 template <template <typename ...> class F>
0227 struct Metafunction<metafunction_t<F>> {
0228 static constexpr bool value = true;
0229 };
0230
0231 template <typename F>
0232 struct Metafunction<metafunction_class_t<F>> {
0233 static constexpr bool value = true;
0234 };
0235
0236
0237
0238
0239 template <typename F>
0240 struct integral_t {
0241 template <typename ...T, typename Result =
0242 typename detail::always_first<F, T...>::type::template apply<typename T::type...>::type
0243 >
0244 constexpr Result operator()(T const& ...) const {
0245 return Result{};
0246 }
0247 };
0248
0249
0250
0251
0252 namespace detail {
0253 template <>
0254 struct comparable_operators<type_tag> {
0255 static constexpr bool value = true;
0256 };
0257 }
0258
0259
0260
0261
0262 template <>
0263 struct equal_impl<type_tag, type_tag> {
0264 template <typename T, typename U>
0265 static constexpr auto apply(basic_type<T> const&, basic_type<U> const&)
0266 { return hana::false_c; }
0267
0268 template <typename T>
0269 static constexpr auto apply(basic_type<T> const&, basic_type<T> const&)
0270 { return hana::true_c; }
0271 };
0272
0273
0274
0275
0276 template <>
0277 struct hash_impl<hana::type_tag> {
0278 template <typename T>
0279 static constexpr T apply(T const& t)
0280 { return t; }
0281 };
0282 }}
0283
0284 #endif