]> git.proxmox.com Git - ceph.git/blob - ceph/src/boost/libs/hana/include/boost/hana/fwd/core/to.hpp
add subtree-ish sources for 12.0.3
[ceph.git] / ceph / src / boost / libs / hana / include / boost / hana / fwd / core / to.hpp
1 /*!
2 @file
3 Forward declares `boost::hana::to` 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_FWD_CORE_TO_HPP
11 #define BOOST_HANA_FWD_CORE_TO_HPP
12
13 #include <boost/hana/config.hpp>
14
15
16 BOOST_HANA_NAMESPACE_BEGIN
17 //! @ingroup group-core
18 //! Converts an object from one data type to another.
19 //!
20 //! `to` is a natural extension of the `static_cast` language construct to
21 //! data types. Given a destination data type `To` and an object `x`, `to`
22 //! creates a new object of data type `To` from `x`. Note, however, that
23 //! `to` is not required to actually create a new object, and may return a
24 //! reference to the original object (for example when trying to convert
25 //! an object to its own data type).
26 //!
27 //! As a natural extension to `static_cast`, `to` provides a default
28 //! behavior. For the purpose of what follows, let `To` be the destination
29 //! data type and `From` be the data type of `x`, i.e. the source data type.
30 //! Then, `to` has the following default behavior:
31 //! 1. If the `To` and `From` data types are the same, then the object
32 //! is forwarded as-is.
33 //! 2. Otherwise, if `From` is convertible to `To` using `static_cast`,
34 //! `x` is converted to `From` using `static_cast`.
35 //! 3. Otherwise, calling `to<From>(x)` triggers a static assertion.
36 //!
37 //! However, `to` is a tag-dispatched function, which means that `to_impl`
38 //! may be specialized in the `boost::hana` namespace to customize its
39 //! behavior for arbitrary data types. Also note that `to` is tag-dispatched
40 //! using both the `To` and the `From` data types, which means that `to_impl`
41 //! is called as `to_impl<To, From>::%apply(x)`. Also note that some
42 //! concepts provide conversions to or from their models. For example,
43 //! any `Foldable` may be converted into a `Sequence`. This is achieved
44 //! by specializing `to_impl<To, From>` whenever `To` is a `Sequence` and
45 //! `From` is a `Foldable`. When such conversions are provided, they are
46 //! documented in the source concept, in this case `Foldable`.
47 //!
48 //!
49 //! Hana-convertibility
50 //! -------------------
51 //! When an object `x` of data type `From` can be converted to a data type
52 //! `To` using `to`, we say that `x` is Hana-convertible to the data type
53 //! `To`. We also say that there is a Hana-conversion from `From` to `To`.
54 //! This bit of terminology is useful to avoid mistaking the various kinds
55 //! of conversions C++ offers.
56 //!
57 //!
58 //! Embeddings
59 //! ----------
60 //! As you might have seen by now, Hana uses algebraic and category-
61 //! theoretical structures all around the place to help specify concepts
62 //! in a rigorous way. These structures always have operations associated
63 //! to them, which is why they are useful. The notion of embedding captures
64 //! the idea of injecting a smaller structure into a larger one while
65 //! preserving the operations of the structure. In other words, an
66 //! embedding is an injective mapping that is also structure-preserving.
67 //! Exactly what it means for a structure's operations to be preserved is
68 //! left to explain by the documentation of each structure. For example,
69 //! when we talk of a Monoid-embedding from a Monoid `A` to a Monoid `B`,
70 //! we simply mean an injective transformation that preserves the identity
71 //! and the associative operation, as documented in `Monoid`.
72 //!
73 //! But what does this have to do with the `to` function? Quite simply,
74 //! the `to` function is a mapping between two data types, which will
75 //! sometimes be some kind of structure, and it is sometimes useful to
76 //! know whether such a mapping is well-behaved, i.e. lossless and
77 //! structure preserving. The criterion for this conversion to be well-
78 //! behaved is exactly that of being an embedding. To specify that a
79 //! conversion is an embedding, simply use the `embedding` type as a
80 //! base class of the corresponding `to_impl` specialization. Obviously,
81 //! you should make sure the conversion is really an embedding, unless
82 //! you want to shoot yourself in the foot.
83 //!
84 //!
85 //! @tparam To
86 //! The data type to which `x` should be converted.
87 //!
88 //! @param x
89 //! The object to convert to the given data type.
90 //!
91 //!
92 //! Example
93 //! -------
94 //! @include example/core/convert/to.cpp
95 #ifdef BOOST_HANA_DOXYGEN_INVOKED
96 template <typename To>
97 constexpr auto to = [](auto&& x) -> decltype(auto) {
98 return tag-dispatched;
99 };
100 #else
101 template <typename To, typename From, typename = void>
102 struct to_impl;
103
104 template <typename To>
105 struct to_t {
106 template <typename X>
107 constexpr decltype(auto) operator()(X&& x) const;
108 };
109
110 template <typename To>
111 constexpr to_t<To> to{};
112 #endif
113
114 //! @ingroup group-core
115 //! Returns whether there is a Hana-conversion from a data type to another.
116 //!
117 //! Specifically, `is_convertible<From, To>` is whether calling `to<To>`
118 //! with an object of data type `From` would _not_ trigger a static
119 //! assertion.
120 //!
121 //!
122 //! Example
123 //! -------
124 //! @include example/core/convert/is_convertible.cpp
125 #ifdef BOOST_HANA_DOXYGEN_INVOKED
126 template <typename From, typename To>
127 struct is_convertible { see documentation };
128 #else
129 template <typename From, typename To, typename = void>
130 struct is_convertible;
131 #endif
132
133 //! @ingroup group-core
134 //! Marks a conversion between data types as being an embedding.
135 //!
136 //! To mark a conversion between two data types `To` and `From` as
137 //! an embedding, simply use `embedding<true>` (or simply `embedding<>`)
138 //! as a base class of the corresponding `to_impl` specialization.
139 //! If a `to_impl` specialization does not inherit `embedding<true>`
140 //! or `embedding<>`, then it is not considered an embedding by the
141 //! `is_embedded` metafunction.
142 //!
143 //! > #### Tip
144 //! > The boolean template parameter is useful for marking a conversion
145 //! > as an embedding only when some condition is satisfied.
146 //!
147 //!
148 //! Example
149 //! -------
150 //! @include example/core/convert/embedding.cpp
151 template <bool = true>
152 struct embedding { };
153
154 //! @ingroup group-core
155 //! Returns whether a data type can be embedded into another data type.
156 //!
157 //! Given two data types `To` and `From`, `is_embedded<From, To>` returns
158 //! whether `From` is convertible to `To`, and whether that conversion is
159 //! also an embedding, as signaled by the `embedding` type.
160 //!
161 //!
162 //! Example
163 //! -------
164 //! @include example/core/convert/is_embedded.cpp
165 #ifdef BOOST_HANA_DOXYGEN_INVOKED
166 template <typename From, typename To>
167 struct is_embedded { see documentation };
168 #else
169 template <typename From, typename To, typename = void>
170 struct is_embedded;
171 #endif
172 BOOST_HANA_NAMESPACE_END
173
174 #endif // !BOOST_HANA_FWD_CORE_TO_HPP