]> git.proxmox.com Git - ceph.git/blob - ceph/src/boost/libs/hana/include/boost/hana/type.hpp
bump version to 12.2.2-pve1
[ceph.git] / ceph / src / boost / libs / hana / include / boost / hana / type.hpp
1 /*!
2 @file
3 Defines `boost::hana::type` and related utilities.
4
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)
8 */
9
10 #ifndef BOOST_HANA_TYPE_HPP
11 #define BOOST_HANA_TYPE_HPP
12
13 #include <boost/hana/fwd/type.hpp>
14
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>
24
25 #include <type_traits>
26 #include <utility>
27
28
29 BOOST_HANA_NAMESPACE_BEGIN
30 //////////////////////////////////////////////////////////////////////////
31 // basic_type
32 //////////////////////////////////////////////////////////////////////////
33 //! @cond
34 template <typename T>
35 struct basic_type : detail::operators::adl<basic_type<T>> {
36 using hana_tag = type_tag;
37
38 using type = T;
39 constexpr auto operator+() const { return *this; }
40 };
41 //! @endcond
42
43 //////////////////////////////////////////////////////////////////////////
44 // type
45 //////////////////////////////////////////////////////////////////////////
46 template <typename T>
47 struct type_impl {
48 struct _ : basic_type<T> { };
49 };
50
51 //////////////////////////////////////////////////////////////////////////
52 // decltype_
53 //////////////////////////////////////////////////////////////////////////
54 namespace detail {
55 template <typename T, typename = type_tag>
56 struct decltype_t {
57 using type = typename std::remove_reference<T>::type;
58 };
59
60 template <typename T>
61 struct decltype_t<T, typename hana::tag_of<T>::type> {
62 using type = typename std::remove_reference<T>::type::type;
63 };
64 }
65
66 //! @cond
67 template <typename T>
68 constexpr auto decltype_t::operator()(T&&) const
69 { return hana::type_c<typename detail::decltype_t<T>::type>; }
70 //! @endcond
71
72 //////////////////////////////////////////////////////////////////////////
73 // typeid_
74 //////////////////////////////////////////////////////////////////////////
75 namespace detail {
76 template <typename T, typename = type_tag>
77 struct typeid_t {
78 using type = typename std::remove_cv<
79 typename std::remove_reference<T>::type
80 >::type;
81 };
82
83 template <typename T>
84 struct typeid_t<T, typename hana::tag_of<T>::type> {
85 using type = typename std::remove_reference<T>::type::type;
86 };
87 }
88 //! @cond
89 template <typename T>
90 constexpr auto typeid_t::operator()(T&&) const
91 { return hana::type_c<typename detail::typeid_t<T>::type>; }
92 //! @endcond
93
94 //////////////////////////////////////////////////////////////////////////
95 // make<type_tag>
96 //////////////////////////////////////////////////////////////////////////
97 template <>
98 struct make_impl<type_tag> {
99 template <typename T>
100 static constexpr auto apply(T&& t)
101 { return hana::typeid_(static_cast<T&&>(t)); }
102 };
103
104 //////////////////////////////////////////////////////////////////////////
105 // sizeof_
106 //////////////////////////////////////////////////////////////////////////
107 //! @cond
108 template <typename T>
109 constexpr auto sizeof_t::operator()(T&&) const
110 { return hana::size_c<sizeof(typename detail::decltype_t<T>::type)>; }
111 //! @endcond
112
113 //////////////////////////////////////////////////////////////////////////
114 // alignof_
115 //////////////////////////////////////////////////////////////////////////
116 //! @cond
117 template <typename T>
118 constexpr auto alignof_t::operator()(T&&) const
119 { return hana::size_c<alignof(typename detail::decltype_t<T>::type)>; }
120 //! @endcond
121
122 //////////////////////////////////////////////////////////////////////////
123 // is_valid
124 //////////////////////////////////////////////////////////////////////////
125 namespace type_detail {
126 template <typename F, typename ...Args, typename = decltype(
127 std::declval<F&&>()(std::declval<Args&&>()...)
128 )>
129 constexpr auto is_valid_impl(int) { return hana::true_c; }
130
131 template <typename F, typename ...Args>
132 constexpr auto is_valid_impl(...) { return hana::false_c; }
133
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{}); }
139 };
140 }
141
142 //! @cond
143 template <typename F>
144 constexpr auto is_valid_t::operator()(F&&) const
145 { return type_detail::is_valid_fun<F&&>{}; }
146
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{}); }
150 //! @endcond
151
152 //////////////////////////////////////////////////////////////////////////
153 // template_
154 //////////////////////////////////////////////////////////////////////////
155 template <template <typename ...> class F>
156 struct template_t {
157 template <typename ...T>
158 struct apply {
159 using type = F<T...>;
160 };
161
162 template <typename ...T>
163 constexpr auto operator()(T const& ...) const
164 { return hana::type<F<typename T::type...>>{}; }
165 };
166
167 //////////////////////////////////////////////////////////////////////////
168 // metafunction
169 //////////////////////////////////////////////////////////////////////////
170 template <template <typename ...> class F>
171 struct metafunction_t {
172 template <typename ...T>
173 using apply = F<T...>;
174
175 template <typename ...T>
176 constexpr hana::type<typename F<typename T::type...>::type>
177 operator()(T const& ...) const { return {}; }
178 };
179
180 //////////////////////////////////////////////////////////////////////////
181 // Metafunction
182 //////////////////////////////////////////////////////////////////////////
183 template <template <typename ...> class F>
184 struct Metafunction<template_t<F>> {
185 static constexpr bool value = true;
186 };
187
188 template <template <typename ...> class F>
189 struct Metafunction<metafunction_t<F>> {
190 static constexpr bool value = true;
191 };
192
193 template <typename F>
194 struct Metafunction<metafunction_class_t<F>> {
195 static constexpr bool value = true;
196 };
197
198 //////////////////////////////////////////////////////////////////////////
199 // integral
200 //////////////////////////////////////////////////////////////////////////
201 template <typename F>
202 struct integral_t {
203 template <typename ...T>
204 constexpr auto operator()(T const& ...) const {
205 using Result = typename F::template apply<typename T::type...>::type;
206 return Result{};
207 }
208 };
209
210 //////////////////////////////////////////////////////////////////////////
211 // Operators
212 //////////////////////////////////////////////////////////////////////////
213 namespace detail {
214 template <>
215 struct comparable_operators<type_tag> {
216 static constexpr bool value = true;
217 };
218 }
219
220 //////////////////////////////////////////////////////////////////////////
221 // Comparable
222 //////////////////////////////////////////////////////////////////////////
223 template <>
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; }
228
229 template <typename T>
230 static constexpr auto apply(basic_type<T> const&, basic_type<T> const&)
231 { return hana::true_c; }
232 };
233
234 //////////////////////////////////////////////////////////////////////////
235 // Hashable
236 //////////////////////////////////////////////////////////////////////////
237 template <>
238 struct hash_impl<hana::type_tag> {
239 template <typename T>
240 static constexpr T apply(T const& t)
241 { return t; }
242 };
243 BOOST_HANA_NAMESPACE_END
244
245 #endif // !BOOST_HANA_TYPE_HPP