Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-18 09:37:58

0001 /*!
0002 @file
0003 Forward declares `boost::hana::Metafunction`.
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_CONCEPT_METAFUNCTION_HPP
0011 #define BOOST_HANA_FWD_CONCEPT_METAFUNCTION_HPP
0012 
0013 #include <boost/hana/config.hpp>
0014 
0015 
0016 namespace boost { namespace hana {
0017     //! @ingroup group-concepts
0018     //! @defgroup group-Metafunction Metafunction
0019     //! A `Metafunction` is a function that takes `hana::type`s as inputs and
0020     //! returns a `hana::type` as output.
0021     //!
0022     //! A `Metafunction` is an object satisfying the [FunctionObject][1]
0023     //! concept, but with additional requirements. First, it must be possible
0024     //! to apply a `Metafunction` to arguments whose tag is `type_tag`, and
0025     //! the result of such an application must be an object whose tag is also
0026     //! `type_tag`. Note that `hana::type` and `hana::basic_type` are the
0027     //! only such types.
0028     //!
0029     //! Secondly, a `Metafunction` must provide a nested `::%apply` template
0030     //! which allows performing the same type-level computation as is done by
0031     //! the call operator. In Boost.MPL parlance, a `Metafunction` `F` is
0032     //! hence a [MetafunctionClass][2] in addition to being a `FunctionObject`.
0033     //! Rigorously, the following must be satisfied by any object `f` of type
0034     //! `F` which is a `Metafunction`, and for arbitrary types `T...`:
0035     //! @code
0036     //!     f(hana::type_c<T>...) == hana::type_c<F::apply<T...>::type>
0037     //! @endcode
0038     //!
0039     //! Thirdly, to ease the inter-operation of values and types,
0040     //! `Metafunction`s must also allow being called with arguments that
0041     //! are not `hana::type`s. In that case, the result is equivalent to
0042     //! calling the metafunction on the types of the arguments. Rigorously,
0043     //! this means that for arbitrary objects `x...`,
0044     //! @code
0045     //!     f(x...) == f(hana::type_c<decltype(x)>...)
0046     //! @endcode
0047     //!
0048     //!
0049     //! Minimal complete definition
0050     //! ---------------------------
0051     //! The `Metafunction` concept does not have a minimal complete definition
0052     //! in terms of tag-dispatched methods. Instead, the syntactic requirements
0053     //! documented above should be satisfied, and the `Metafunction` struct
0054     //! should be specialized explicitly in Hana's namespace.
0055     //!
0056     //!
0057     //! Concrete models
0058     //! ---------------
0059     //! `hana::metafunction`, `hana::metafunction_class`, `hana::template_`
0060     //!
0061     //!
0062     //! Rationale: Why aren't `Metafunction`s `Comparable`?
0063     //! ---------------------------------------------------
0064     //! When seeing `hana::template_`, a question that naturally arises is
0065     //! whether `Metafunction`s should be made `Comparable`. Indeed, it
0066     //! would seem to make sense to compare two templates `F` and `G` with
0067     //! `template_<F> == template_<G>`. However, in the case where `F` and/or
0068     //! `G` are alias templates, it makes sense to talk about two types of
0069     //! comparisons. The first one is _shallow_ comparison, and it determines
0070     //! that two alias templates are equal if they are the same alias
0071     //! template. The second one is _deep_ comparison, and it determines
0072     //! that two template aliases are equal if they alias the same type for
0073     //! any template argument. For example, given `F` and `G` defined as
0074     //! @code
0075     //!     template <typename T>
0076     //!     using F = void;
0077     //!
0078     //!     template <typename T>
0079     //!     using G = void;
0080     //! @endcode
0081     //!
0082     //! shallow comparison would determine that `F` and `G` are different
0083     //! because they are two different template aliases, while deep comparison
0084     //! would determine that `F` and `G` are equal because they always
0085     //! expand to the same type, `void`. Unfortunately, deep comparison is
0086     //! impossible to implement because one would have to check `F` and `G`
0087     //! on all possible types. On the other hand, shallow comparison is not
0088     //! satisfactory because `Metafunction`s are nothing but functions on
0089     //! `type`s, and the equality of two functions is normally defined with
0090     //! deep comparison. Hence, we adopt a conservative stance and avoid
0091     //! providing comparison for `Metafunction`s.
0092     //!
0093     //! [1]: http://en.cppreference.com/w/cpp/named_req/FunctionObject
0094     //! [2]: http://www.boost.org/doc/libs/release/libs/mpl/doc/refmanual/metafunction-class.html
0095     template <typename F>
0096     struct Metafunction;
0097 }} // end namespace boost::hana
0098 
0099 #endif // !BOOST_HANA_FWD_CONCEPT_METAFUNCTION_HPP