]> git.proxmox.com Git - ceph.git/blame - ceph/src/boost/libs/hana/include/boost/hana/core/to.hpp
bump version to 12.2.2-pve1
[ceph.git] / ceph / src / boost / libs / hana / include / boost / hana / core / to.hpp
CommitLineData
7c673cae
FG
1/*!
2@file
3Defines `boost::hana::to` and related utilities.
4
5@copyright Louis Dionne 2013-2016
6Distributed 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_CORE_TO_HPP
11#define BOOST_HANA_CORE_TO_HPP
12
13#include <boost/hana/fwd/core/to.hpp>
14
15#include <boost/hana/concept/constant.hpp>
16#include <boost/hana/concept/foldable.hpp>
17#include <boost/hana/concept/sequence.hpp>
18#include <boost/hana/config.hpp>
19#include <boost/hana/core/common.hpp>
20#include <boost/hana/core/dispatch.hpp>
21#include <boost/hana/core/make.hpp>
22#include <boost/hana/detail/wrong.hpp>
23#include <boost/hana/unpack.hpp>
24#include <boost/hana/value.hpp>
25
26#include <type_traits>
27#include <utility>
28
29
30BOOST_HANA_NAMESPACE_BEGIN
31 //////////////////////////////////////////////////////////////////////////
32 // to
33 //////////////////////////////////////////////////////////////////////////
34 //! @cond
35 template <typename To, typename From, typename>
36 struct to_impl : to_impl<To, From, when<true>> { };
37 //! @endcond
38
39 namespace convert_detail {
40 struct no_conversion { };
41
42 template <typename ...>
43 struct is_valid { static constexpr bool value = true; };
44 }
45
46 template <typename To, typename From, bool condition>
47 struct to_impl<To, From, when<condition>> : convert_detail::no_conversion {
48 template <typename X>
49 static constexpr auto apply(X const&) {
50 static_assert(detail::wrong<to_impl<To, From>, X>{},
51 "no conversion is available between the provided types");
52 }
53 };
54
55 template <typename To, typename From>
56 struct to_impl<To, From, when<convert_detail::is_valid<
57 decltype(static_cast<To>(std::declval<From>()))
58 >::value>> {
59 template <typename X>
60 static constexpr To apply(X&& x)
61 { return static_cast<To>(static_cast<X&&>(x)); }
62 };
63
64 template <typename To>
65 struct to_impl<To, To> : embedding<> {
66 template <typename X>
67 static constexpr X apply(X&& x)
68 { return static_cast<X&&>(x); }
69 };
70
71 //! @cond
72 template <typename To>
73 template <typename X>
74 constexpr decltype(auto) to_t<To>::operator()(X&& x) const {
75 using From = typename hana::tag_of<X>::type;
76 return to_impl<To, From>::apply(static_cast<X&&>(x));
77 }
78 //! @endcond
79
80#define BOOST_HANA_DEFINE_EMBEDDING_IMPL(TO, FROM) \
81 template <> \
82 struct to_impl<TO, FROM> : embedding<> \
83 { static constexpr TO apply(FROM x) { return x; } } \
84/**/
85 BOOST_HANA_DEFINE_EMBEDDING_IMPL(long double, double);
86 BOOST_HANA_DEFINE_EMBEDDING_IMPL(long double, float);
87 BOOST_HANA_DEFINE_EMBEDDING_IMPL(double , float);
88
89 BOOST_HANA_DEFINE_EMBEDDING_IMPL(signed long long, signed long);
90 BOOST_HANA_DEFINE_EMBEDDING_IMPL(signed long long, signed int);
91 BOOST_HANA_DEFINE_EMBEDDING_IMPL(signed long long, signed short);
92 BOOST_HANA_DEFINE_EMBEDDING_IMPL(signed long long, signed char);
93 BOOST_HANA_DEFINE_EMBEDDING_IMPL(signed long , signed int);
94 BOOST_HANA_DEFINE_EMBEDDING_IMPL(signed long , signed short);
95 BOOST_HANA_DEFINE_EMBEDDING_IMPL(signed long , signed char);
96 BOOST_HANA_DEFINE_EMBEDDING_IMPL(signed int , signed short);
97 BOOST_HANA_DEFINE_EMBEDDING_IMPL(signed int , signed char);
98 BOOST_HANA_DEFINE_EMBEDDING_IMPL(signed short , signed char);
99
100 BOOST_HANA_DEFINE_EMBEDDING_IMPL(unsigned long long, unsigned long);
101 BOOST_HANA_DEFINE_EMBEDDING_IMPL(unsigned long long, unsigned int);
102 BOOST_HANA_DEFINE_EMBEDDING_IMPL(unsigned long long, unsigned short);
103 BOOST_HANA_DEFINE_EMBEDDING_IMPL(unsigned long long, unsigned char);
104 BOOST_HANA_DEFINE_EMBEDDING_IMPL(unsigned long , unsigned int);
105 BOOST_HANA_DEFINE_EMBEDDING_IMPL(unsigned long , unsigned short);
106 BOOST_HANA_DEFINE_EMBEDDING_IMPL(unsigned long , unsigned char);
107 BOOST_HANA_DEFINE_EMBEDDING_IMPL(unsigned int , unsigned short);
108 BOOST_HANA_DEFINE_EMBEDDING_IMPL(unsigned int , unsigned char);
109 BOOST_HANA_DEFINE_EMBEDDING_IMPL(unsigned short , unsigned char);
110#undef BOOST_HANA_DEFINE_EMBEDDING_IMPL
111
112 namespace detail {
113 template <typename T>
114 struct copy_char_signedness {
115 using type = typename std::conditional<std::is_signed<char>::value,
116 std::make_signed<T>, std::make_unsigned<T>
117 >::type::type;
118 };
119 }
120
121 // If `char` is signed, we define an embedding from `char` to any signed
122 // integral type. Otherwise, we define one from `char` to any unsigned
123 // integral type.
124#define BOOST_HANA_DEFINE_CHAR_EMBEDDING_IMPL(TO) \
125 template <> \
126 struct to_impl<detail::copy_char_signedness<TO>::type, char> \
127 : embedding<> \
128 { \
129 static constexpr detail::copy_char_signedness<TO>::type \
130 apply(char x) \
131 { return x; } \
132 } \
133/**/
134 BOOST_HANA_DEFINE_CHAR_EMBEDDING_IMPL(long long);
135 BOOST_HANA_DEFINE_CHAR_EMBEDDING_IMPL(long);
136 BOOST_HANA_DEFINE_CHAR_EMBEDDING_IMPL(int);
137 BOOST_HANA_DEFINE_CHAR_EMBEDDING_IMPL(short);
138#undef BOOST_HANA_DEFINE_CHAR_EMBEDDING_IMPL
139
140 template <typename T>
141 struct to_impl<T*, decltype(nullptr)> : embedding<> {
142 static constexpr T* apply(decltype(nullptr)) { return nullptr; }
143 };
144
145 //////////////////////////////////////////////////////////////////////////
146 // is_convertible
147 //////////////////////////////////////////////////////////////////////////
148 template <typename From, typename To, typename>
149 struct is_convertible : std::true_type { };
150
151 template <typename From, typename To>
152 struct is_convertible<From, To, decltype((void)
153 static_cast<convert_detail::no_conversion>(*(to_impl<To, From>*)0)
154 )> : std::false_type { };
155
156 //////////////////////////////////////////////////////////////////////////
157 // is_embedded
158 //////////////////////////////////////////////////////////////////////////
159 template <typename From, typename To, typename>
160 struct is_embedded : std::false_type { };
161
162 template <typename From, typename To>
163 struct is_embedded<From, To, decltype((void)
164 static_cast<embedding<true>>(*(to_impl<To, From>*)0)
165 )> : std::true_type { };
166
167 //////////////////////////////////////////////////////////////////////////
168 // Conversion for Constants
169 //////////////////////////////////////////////////////////////////////////
170 template <typename To, typename From>
171 struct to_impl<To, From, when<
172 hana::Constant<From>::value &&
173 is_convertible<typename From::value_type, To>::value
174 >> : embedding<is_embedded<typename From::value_type, To>::value> {
175 template <typename X>
176 static constexpr decltype(auto) apply(X const&)
177 { return hana::to<To>(hana::value<X>()); }
178 };
179
180 //////////////////////////////////////////////////////////////////////////
181 // Foldable -> Sequence
182 //////////////////////////////////////////////////////////////////////////
183 template <typename S, typename F>
184 struct to_impl<S, F, when<
185 hana::Sequence<S>::value &&
186 hana::Foldable<F>::value
187 >> : embedding<Sequence<F>::value> {
188 template <typename Xs>
189 static constexpr decltype(auto) apply(Xs&& xs)
190 { return hana::unpack(static_cast<Xs&&>(xs), hana::make<S>); }
191 };
192BOOST_HANA_NAMESPACE_END
193
194#endif // !BOOST_HANA_CORE_TO_HPP