Back to home page

EIC code displayed by LXR

 
 

    


Warning, file /include/boost/hana/fwd/core/to.hpp was not indexed or was modified since last indexation (in which case cross-reference links may be missing, inaccurate or erroneous).

0001 /*!
0002 @file
0003 Forward declares `boost::hana::to` and related utilities.
0004 
0005 Copyright Louis Dionne 2013-2022
0006 Distributed under the Boost Software License, Version 1.0.
0007 (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
0008  */
0009 
0010 #ifndef BOOST_HANA_FWD_CORE_TO_HPP
0011 #define BOOST_HANA_FWD_CORE_TO_HPP
0012 
0013 #include <boost/hana/config.hpp>
0014 
0015 
0016 namespace boost { namespace hana {
0017     //! @ingroup group-core
0018     //! Converts an object from one data type to another.
0019     //!
0020     //! `to` is a natural extension of the `static_cast` language construct to
0021     //! data types. Given a destination data type `To` and an object `x`, `to`
0022     //! creates a new object of data type `To` from `x`. Note, however, that
0023     //! `to` is not required to actually create a new object, and may return a
0024     //! reference to the original object (for example when trying to convert
0025     //! an object to its own data type).
0026     //!
0027     //! As a natural extension to `static_cast`, `to` provides a default
0028     //! behavior. For the purpose of what follows, let `To` be the destination
0029     //! data type and `From` be the data type of `x`, i.e. the source data type.
0030     //! Then, `to` has the following default behavior:
0031     //! 1. If the `To` and `From` data types are the same, then the object
0032     //!    is forwarded as-is.
0033     //! 2. Otherwise, if `From` is convertible to `To` using `static_cast`,
0034     //!    `x` is converted to `From` using `static_cast`.
0035     //! 3. Otherwise, calling `to<From>(x)` triggers a static assertion.
0036     //!
0037     //! However, `to` is a tag-dispatched function, which means that `to_impl`
0038     //! may be specialized in the `boost::hana` namespace to customize its
0039     //! behavior for arbitrary data types. Also note that `to` is tag-dispatched
0040     //! using both the `To` and the `From` data types, which means that `to_impl`
0041     //! is called as `to_impl<To, From>::%apply(x)`. Also note that some
0042     //! concepts provide conversions to or from their models. For example,
0043     //! any `Foldable` may be converted into a `Sequence`. This is achieved
0044     //! by specializing `to_impl<To, From>` whenever `To` is a `Sequence` and
0045     //! `From` is a `Foldable`. When such conversions are provided, they are
0046     //! documented in the source concept, in this case `Foldable`.
0047     //!
0048     //!
0049     //! Hana-convertibility
0050     //! -------------------
0051     //! When an object `x` of data type `From` can be converted to a data type
0052     //! `To` using `to`, we say that `x` is Hana-convertible to the data type
0053     //! `To`. We also say that there is a Hana-conversion from `From` to `To`.
0054     //! This bit of terminology is useful to avoid mistaking the various kinds
0055     //! of conversions C++ offers.
0056     //!
0057     //!
0058     //! Embeddings
0059     //! ----------
0060     //! As you might have seen by now, Hana uses algebraic and category-
0061     //! theoretical structures all around the place to help specify concepts
0062     //! in a rigorous way. These structures always have operations associated
0063     //! to them, which is why they are useful. The notion of embedding captures
0064     //! the idea of injecting a smaller structure into a larger one while
0065     //! preserving the operations of the structure. In other words, an
0066     //! embedding is an injective mapping that is also structure-preserving.
0067     //! Exactly what it means for a structure's operations to be preserved is
0068     //! left to explain by the documentation of each structure. For example,
0069     //! when we talk of a Monoid-embedding from a Monoid `A` to a Monoid `B`,
0070     //! we simply mean an injective transformation that preserves the identity
0071     //! and the associative operation, as documented in `Monoid`.
0072     //!
0073     //! But what does this have to do with the `to` function? Quite simply,
0074     //! the `to` function is a mapping between two data types, which will
0075     //! sometimes be some kind of structure, and it is sometimes useful to
0076     //! know whether such a mapping is well-behaved, i.e. lossless and
0077     //! structure preserving. The criterion for this conversion to be well-
0078     //! behaved is exactly that of being an embedding. To specify that a
0079     //! conversion is an embedding, simply use the `embedding` type as a
0080     //! base class of the corresponding `to_impl` specialization. Obviously,
0081     //! you should make sure the conversion is really an embedding, unless
0082     //! you want to shoot yourself in the foot.
0083     //!
0084     //!
0085     //! @tparam To
0086     //! The data type to which `x` should be converted.
0087     //!
0088     //! @param x
0089     //! The object to convert to the given data type.
0090     //!
0091     //!
0092     //! Example
0093     //! -------
0094     //! @include example/core/convert/to.cpp
0095 #ifdef BOOST_HANA_DOXYGEN_INVOKED
0096     template <typename To>
0097     constexpr auto to = [](auto&& x) -> decltype(auto) {
0098         return tag-dispatched;
0099     };
0100 #else
0101     template <typename To, typename From, typename = void>
0102     struct to_impl;
0103 
0104     template <typename To>
0105     struct to_t {
0106         template <typename X>
0107         constexpr decltype(auto) operator()(X&& x) const;
0108     };
0109 
0110     template <typename To>
0111     BOOST_HANA_INLINE_VARIABLE constexpr to_t<To> to{};
0112 #endif
0113 
0114     //! @ingroup group-core
0115     //! Returns whether there is a Hana-conversion from a data type to another.
0116     //!
0117     //! Specifically, `is_convertible<From, To>` is whether calling `to<To>`
0118     //! with an object of data type `From` would _not_ trigger a static
0119     //! assertion.
0120     //!
0121     //!
0122     //! Example
0123     //! -------
0124     //! @include example/core/convert/is_convertible.cpp
0125 #ifdef BOOST_HANA_DOXYGEN_INVOKED
0126     template <typename From, typename To>
0127     struct is_convertible { see documentation };
0128 #else
0129     template <typename From, typename To, typename = void>
0130     struct is_convertible;
0131 #endif
0132 
0133     //! @ingroup group-core
0134     //! Marks a conversion between data types as being an embedding.
0135     //!
0136     //! To mark a conversion between two data types `To` and `From` as
0137     //! an embedding, simply use `embedding<true>` (or simply `embedding<>`)
0138     //! as a base class of the corresponding `to_impl` specialization.
0139     //! If a `to_impl` specialization does not inherit `embedding<true>`
0140     //! or `embedding<>`, then it is not considered an embedding by the
0141     //! `is_embedded` metafunction.
0142     //!
0143     //! > #### Tip
0144     //! > The boolean template parameter is useful for marking a conversion
0145     //! > as an embedding only when some condition is satisfied.
0146     //!
0147     //!
0148     //! Example
0149     //! -------
0150     //! @include example/core/convert/embedding.cpp
0151     template <bool = true>
0152     struct embedding { };
0153 
0154     //! @ingroup group-core
0155     //! Returns whether a data type can be embedded into another data type.
0156     //!
0157     //! Given two data types `To` and `From`, `is_embedded<From, To>` returns
0158     //! whether `From` is convertible to `To`, and whether that conversion is
0159     //! also an embedding, as signaled by the `embedding` type.
0160     //!
0161     //!
0162     //! Example
0163     //! -------
0164     //! @include example/core/convert/is_embedded.cpp
0165 #ifdef BOOST_HANA_DOXYGEN_INVOKED
0166     template <typename From, typename To>
0167     struct is_embedded { see documentation };
0168 #else
0169     template <typename From, typename To, typename = void>
0170     struct is_embedded;
0171 #endif
0172 }} // end namespace boost::hana
0173 
0174 #endif // !BOOST_HANA_FWD_CORE_TO_HPP