Back to home page

EIC code displayed by LXR

 
 

    


Warning, file /include/boost/hana/fwd/core/common.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::common` and `boost::hana::common_t`.
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_COMMON_HPP
0011 #define BOOST_HANA_FWD_CORE_COMMON_HPP
0012 
0013 #include <boost/hana/config.hpp>
0014 
0015 
0016 namespace boost { namespace hana {
0017     //! @ingroup group-core
0018     //! %Metafunction returning the common data type between two data types.
0019     //!
0020     //! `common` is a natural extension of the `std::common_type` metafunction
0021     //! to data types. Given two data types `T` and `U`, we say that they share
0022     //! a common type `C` if both objects of data type `T` and objects of data
0023     //! type `U` may be converted (using `to`) to an object of data type `C`,
0024     //! and if that conversion is equality preserving. In other words, this
0025     //! means that for any objects `t1, t2` of data type `T` and `u1, u2` of
0026     //! data type `U`, the following law is satisfied:
0027     //! @code
0028     //!     to<C>(t1) == to<C>(t2)  if and only if  t1 == t2
0029     //!     to<C>(u1) == to<C>(u2)  if and only if  u1 == u2
0030     //! @endcode
0031     //!
0032     //! The role of `common` is to provide an alias to such a `C` if it exists.
0033     //! In other words, if `T` and `U` have a common data type `C`,
0034     //! `common<T, U>::%type` is an alias to `C`. Otherwise, `common<T, U>`
0035     //! has no nested `type` and can be used in dependent contexts to exploit
0036     //! SFINAE. By default, the exact steps followed by `common` to determine
0037     //! the common type `C` of `T` and `U` are
0038     //! 1. If `T` and `U` are the same, then `C` is `T`.
0039     //! 2. Otherwise, if `true ? std::declval<T>() : std::declval<U>()` is
0040     //!    well-formed, then `C` is the type of this expression after using
0041     //!    `std::decay` on it. This is exactly the type that would have been
0042     //!    returned by `std::common_type`, except that custom specializations
0043     //!    of `std::common_type` are not taken into account.
0044     //! 3. Otherwise, no common data type is detected and `common<T, U>` does
0045     //!    not have a nested `type` alias, unless it is specialized explicitly.
0046     //!
0047     //! As point 3 suggests, it is also possible (and sometimes necessary) to
0048     //! specialize `common` in the `boost::hana` namespace for pairs of custom
0049     //! data types when the default behavior of `common` is not sufficient.
0050     //! Note that `when`-based specialization is supported when specializing
0051     //! `common` in the `boost::hana` namespace.
0052     //!
0053     //! > #### Rationale for requiring the conversion to be equality-preserving
0054     //! > This decision is aligned with a proposed concept design for the
0055     //! > standard library ([N3351][1]). Also, if we did not require this,
0056     //! > then all data types would trivially share the common data type
0057     //! > `void`, since all objects can be converted to it.
0058     //!
0059     //!
0060     //! Example
0061     //! -------
0062     //! @include example/core/common/common.cpp
0063     //!
0064     //!
0065     //! [1]: http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2012/n3351.pdf
0066 #ifdef BOOST_HANA_DOXYGEN_INVOKED
0067     template <typename T, typename U, optional when-based enabler>
0068     struct common { see documentation };
0069 #else
0070     template <typename T, typename U, typename = void>
0071     struct common;
0072 #endif
0073 
0074     //! @ingroup group-core
0075     //! %Metafunction returning whether two data types share a common data type.
0076     //!
0077     //! Given two data types `T` and `U`, this metafunction simply returns
0078     //! whether `common<T, U>::%type` is well-formed.
0079     //!
0080     //!
0081     //! Example
0082     //! -------
0083     //! @include example/core/common/has_common.cpp
0084 #ifdef BOOST_HANA_DOXYGEN_INVOKED
0085     template <typename T, typename U>
0086     struct has_common { whether common<T, U>::type is well-formed };
0087 #else
0088     template <typename T, typename U, typename = void>
0089     struct has_common;
0090 #endif
0091 
0092     //! @ingroup group-core
0093     //! Alias to `common<T, U>::%type`, provided for convenience.
0094     //!
0095     //!
0096     //! Example
0097     //! -------
0098     //! @include example/core/common/common_t.cpp
0099     template <typename T, typename U>
0100     using common_t = typename common<T, U>::type;
0101 }} // end namespace boost::hana
0102 
0103 #endif // !BOOST_HANA_FWD_CORE_COMMON_HPP