3 Defines `boost::hana::type` and related utilities.
5 @copyright Louis Dionne 2013-2016
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)
10 #ifndef BOOST_HANA_TYPE_HPP
11 #define BOOST_HANA_TYPE_HPP
13 #include <boost/hana/fwd/type.hpp>
15 #include <boost/hana/bool.hpp>
16 #include <boost/hana/config.hpp>
17 #include <boost/hana/detail/operators/adl.hpp>
18 #include <boost/hana/detail/operators/comparable.hpp>
19 #include <boost/hana/fwd/concept/metafunction.hpp>
20 #include <boost/hana/fwd/core/make.hpp>
21 #include <boost/hana/fwd/equal.hpp>
22 #include <boost/hana/fwd/hash.hpp>
23 #include <boost/hana/integral_constant.hpp>
25 #include <type_traits>
29 BOOST_HANA_NAMESPACE_BEGIN
30 //////////////////////////////////////////////////////////////////////////
32 //////////////////////////////////////////////////////////////////////////
35 struct basic_type : detail::operators::adl<basic_type<T>> {
36 using hana_tag = type_tag;
39 constexpr auto operator+() const { return *this; }
43 //////////////////////////////////////////////////////////////////////////
45 //////////////////////////////////////////////////////////////////////////
48 struct _ : basic_type<T> { };
51 //////////////////////////////////////////////////////////////////////////
53 //////////////////////////////////////////////////////////////////////////
55 template <typename T, typename = type_tag>
57 using type = typename std::remove_reference<T>::type;
61 struct decltype_t<T, typename hana::tag_of<T>::type> {
62 using type = typename std::remove_reference<T>::type::type;
68 constexpr auto decltype_t::operator()(T&&) const
69 { return hana::type_c<typename detail::decltype_t<T>::type>; }
72 //////////////////////////////////////////////////////////////////////////
74 //////////////////////////////////////////////////////////////////////////
76 template <typename T, typename = type_tag>
78 using type = typename std::remove_cv<
79 typename std::remove_reference<T>::type
84 struct typeid_t<T, typename hana::tag_of<T>::type> {
85 using type = typename std::remove_reference<T>::type::type;
90 constexpr auto typeid_t::operator()(T&&) const
91 { return hana::type_c<typename detail::typeid_t<T>::type>; }
94 //////////////////////////////////////////////////////////////////////////
96 //////////////////////////////////////////////////////////////////////////
98 struct make_impl<type_tag> {
100 static constexpr auto apply(T&& t)
101 { return hana::typeid_(static_cast<T&&>(t)); }
104 //////////////////////////////////////////////////////////////////////////
106 //////////////////////////////////////////////////////////////////////////
108 template <typename T>
109 constexpr auto sizeof_t::operator()(T&&) const
110 { return hana::size_c<sizeof(typename detail::decltype_t<T>::type)>; }
113 //////////////////////////////////////////////////////////////////////////
115 //////////////////////////////////////////////////////////////////////////
117 template <typename T>
118 constexpr auto alignof_t::operator()(T&&) const
119 { return hana::size_c<alignof(typename detail::decltype_t<T>::type)>; }
122 //////////////////////////////////////////////////////////////////////////
124 //////////////////////////////////////////////////////////////////////////
125 namespace type_detail {
126 template <typename F, typename ...Args, typename = decltype(
127 std::declval<F&&>()(std::declval<Args&&>()...)
129 constexpr auto is_valid_impl(int) { return hana::true_c; }
131 template <typename F, typename ...Args>
132 constexpr auto is_valid_impl(...) { return hana::false_c; }
134 template <typename F>
135 struct is_valid_fun {
136 template <typename ...Args>
137 constexpr auto operator()(Args&& ...) const
138 { return is_valid_impl<F, Args&&...>(int{}); }
143 template <typename F>
144 constexpr auto is_valid_t::operator()(F&&) const
145 { return type_detail::is_valid_fun<F&&>{}; }
147 template <typename F, typename ...Args>
148 constexpr auto is_valid_t::operator()(F&&, Args&& ...) const
149 { return type_detail::is_valid_impl<F&&, Args&&...>(int{}); }
152 //////////////////////////////////////////////////////////////////////////
154 //////////////////////////////////////////////////////////////////////////
155 template <template <typename ...> class F>
157 template <typename ...T>
159 using type = F<T...>;
162 template <typename ...T>
163 constexpr auto operator()(T const& ...) const
164 { return hana::type<F<typename T::type...>>{}; }
167 //////////////////////////////////////////////////////////////////////////
169 //////////////////////////////////////////////////////////////////////////
170 template <template <typename ...> class F>
171 struct metafunction_t {
172 template <typename ...T>
173 using apply = F<T...>;
175 template <typename ...T>
176 constexpr hana::type<typename F<typename T::type...>::type>
177 operator()(T const& ...) const { return {}; }
180 //////////////////////////////////////////////////////////////////////////
182 //////////////////////////////////////////////////////////////////////////
183 template <template <typename ...> class F>
184 struct Metafunction<template_t<F>> {
185 static constexpr bool value = true;
188 template <template <typename ...> class F>
189 struct Metafunction<metafunction_t<F>> {
190 static constexpr bool value = true;
193 template <typename F>
194 struct Metafunction<metafunction_class_t<F>> {
195 static constexpr bool value = true;
198 //////////////////////////////////////////////////////////////////////////
200 //////////////////////////////////////////////////////////////////////////
201 template <typename F>
203 template <typename ...T>
204 constexpr auto operator()(T const& ...) const {
205 using Result = typename F::template apply<typename T::type...>::type;
210 //////////////////////////////////////////////////////////////////////////
212 //////////////////////////////////////////////////////////////////////////
215 struct comparable_operators<type_tag> {
216 static constexpr bool value = true;
220 //////////////////////////////////////////////////////////////////////////
222 //////////////////////////////////////////////////////////////////////////
224 struct equal_impl<type_tag, type_tag> {
225 template <typename T, typename U>
226 static constexpr auto apply(basic_type<T> const&, basic_type<U> const&)
227 { return hana::false_c; }
229 template <typename T>
230 static constexpr auto apply(basic_type<T> const&, basic_type<T> const&)
231 { return hana::true_c; }
234 //////////////////////////////////////////////////////////////////////////
236 //////////////////////////////////////////////////////////////////////////
238 struct hash_impl<hana::type_tag> {
239 template <typename T>
240 static constexpr T apply(T const& t)
243 BOOST_HANA_NAMESPACE_END
245 #endif // !BOOST_HANA_TYPE_HPP