Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-18 09:38:15

0001 /*=============================================================================
0002     Copyright (c) 2012 Paul Fultz II
0003     implicit.h
0004     Distributed under the Boost Software License, Version 1.0. (See accompanying
0005     file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
0006 ==============================================================================*/
0007 
0008 #ifndef BOOST_HOF_GUARD_FUNCTION_IMPLICIT_H
0009 #define BOOST_HOF_GUARD_FUNCTION_IMPLICIT_H
0010 
0011 /// implicit
0012 /// ========
0013 /// 
0014 /// Description
0015 /// -----------
0016 /// 
0017 /// The `implicit` adaptor is a static function adaptor that uses the type
0018 /// that the return value can be converted to, in order to determine the type
0019 /// of the template parameter. In essence, it will deduce the type for the
0020 /// template parameter using the type of variable the result is assigned to.
0021 /// Since it is a static function adaptor, the function must be default
0022 /// constructible.
0023 /// 
0024 /// Synopsis
0025 /// --------
0026 /// 
0027 ///     template<template <class...> class F>
0028 ///     class implicit<F>;
0029 /// 
0030 /// Semantics
0031 /// ---------
0032 /// 
0033 ///     assert(T(implicit<F>()(xs...)) == F<T>()(xs...));
0034 /// 
0035 /// Requirements
0036 /// ------------
0037 /// 
0038 /// F must be a template class, that is a:
0039 /// 
0040 /// * [ConstFunctionObject](ConstFunctionObject)
0041 /// * DefaultConstructible
0042 /// 
0043 /// Example
0044 /// -------
0045 /// 
0046 ///     #include <boost/hof.hpp>
0047 ///     #include <cassert>
0048 ///     using namespace boost::hof;
0049 /// 
0050 ///     template<class T>
0051 ///     struct auto_caster
0052 ///     {
0053 ///         template<class U>
0054 ///         T operator()(U x)
0055 ///         {
0056 ///             return T(x);
0057 ///         }
0058 ///     };
0059 /// 
0060 ///     static constexpr implicit<auto_caster> auto_cast = {};
0061 /// 
0062 ///     struct auto_caster_foo
0063 ///     {
0064 ///         int i;
0065 ///         explicit auto_caster_foo(int i_) : i(i_) {}
0066 /// 
0067 ///     };
0068 /// 
0069 ///     int main() {
0070 ///         float f = 1.5;
0071 ///         int i = auto_cast(f);
0072 ///         auto_caster_foo x = auto_cast(1);
0073 ///         assert(1 == i);
0074 ///         assert(1 == x.i);
0075 ///     }
0076 /// 
0077 
0078 #include <boost/hof/pack.hpp>
0079 #include <boost/hof/detail/result_of.hpp>
0080 
0081 namespace boost { namespace hof { namespace detail {
0082 
0083 template<class F, class Pack, class X, class=void>
0084 struct is_implicit_callable
0085 : std::false_type
0086 {};
0087 
0088 #if BOOST_HOF_NO_EXPRESSION_SFINAE
0089 template<class F, class Pack, class X>
0090 struct is_implicit_callable<F, Pack, X, typename std::enable_if<
0091     std::is_convertible<typename result_of<Pack, id_<F>>::type, X>::value
0092 >::type>
0093 : std::true_type
0094 {};
0095 #else
0096 template<class F, class Pack, class X>
0097 struct is_implicit_callable<F, Pack, X, typename std::enable_if<
0098     std::is_convertible<decltype(std::declval<Pack>()(std::declval<F>())), X>::value
0099 >::type>
0100 : std::true_type
0101 {};
0102 #endif
0103 
0104 }
0105 
0106 
0107 template<template <class...> class F>
0108 struct implicit
0109 {
0110     template<class Pack>
0111     struct invoker
0112     {
0113         Pack p;
0114 
0115         constexpr invoker(Pack pp) BOOST_HOF_NOEXCEPT_CONSTRUCTIBLE(Pack, Pack&&)
0116         : p(boost::hof::move(pp))
0117         {}
0118 
0119         template<class X, class=typename std::enable_if<detail::is_implicit_callable<F<X>, Pack, X>::value>::type>
0120         constexpr operator X() const BOOST_HOF_NOEXCEPT(noexcept(p(F<X>())))
0121         {
0122             return p(F<X>());
0123         }
0124 
0125 #if !(defined(__GNUC__) && !defined (__clang__) && __GNUC__ == 4 && __GNUC_MINOR__ < 7)
0126         invoker (const invoker&) = delete;
0127         invoker& operator= (const invoker&) = delete;
0128 
0129     private:
0130         friend struct implicit;
0131         invoker (invoker&&) = default;
0132 #endif
0133     };
0134 
0135     struct make_invoker
0136     {
0137         template<class Pack>
0138         constexpr invoker<Pack> operator()(Pack p) const BOOST_HOF_NOEXCEPT(noexcept(invoker<Pack>(boost::hof::move(p))))
0139         {
0140             return invoker<Pack>(boost::hof::move(p));
0141         }
0142 
0143     };
0144 
0145     template<class... Ts>
0146     constexpr auto operator()(Ts&&... xs) const 
0147     BOOST_HOF_RETURNS
0148     (
0149         BOOST_HOF_RETURNS_CONSTRUCT(make_invoker)()(boost::hof::pack_basic(BOOST_HOF_FORWARD(Ts)(xs)...))
0150     );
0151 };
0152 
0153 }} // namespace boost::hof
0154 
0155 #endif