Back to home page

EIC code displayed by LXR

 
 

    


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

0001 /*=============================================================================
0002     Copyright (c) 2015 Paul Fultz II
0003     decorate.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_DECORATE_H
0009 #define BOOST_HOF_GUARD_DECORATE_H
0010 
0011 /// decorate
0012 /// ========
0013 /// 
0014 /// Description
0015 /// -----------
0016 /// 
0017 /// The `decorate` function adaptor helps create simple function decorators. 
0018 /// 
0019 /// A function adaptor takes a function and returns a new functions whereas a
0020 /// decorator takes some parameters and returns a function adaptor. The
0021 /// `decorate` function adaptor will return a decorator that returns a
0022 /// function adaptor. Eventually, it will invoke the function with the user-
0023 /// provided parameter and function.
0024 /// 
0025 /// Synopsis
0026 /// --------
0027 /// 
0028 ///     template<class F>
0029 ///     constexpr decorate_adaptor<F> decorate(F f);
0030 /// 
0031 /// Semantics
0032 /// ---------
0033 /// 
0034 ///     assert(decorate(f)(x)(g)(xs...) == f(x, g, xs...));
0035 /// 
0036 /// Requirements
0037 /// ------------
0038 /// 
0039 /// F must be:
0040 /// 
0041 /// * [ConstInvocable](ConstInvocable)
0042 /// * MoveConstructible
0043 /// 
0044 /// Example
0045 /// -------
0046 /// 
0047 ///     #include <boost/hof.hpp>
0048 ///     #include <cassert>
0049 ///     #include <iostream>
0050 ///     #include <string>
0051 ///     using namespace boost::hof;
0052 /// 
0053 ///     struct logger_f
0054 ///     {
0055 ///         template<class F, class... Ts>
0056 ///         auto operator()(const std::string& message, F&& f, Ts&&... xs) const 
0057 ///             -> decltype(f(std::forward<Ts>(xs)...))
0058 ///         {
0059 ///             // Message to print out when the function is called
0060 ///             std::cout << message << std::endl;
0061 ///             // Call the function
0062 ///             return f(std::forward<Ts>(xs)...);
0063 ///         }
0064 ///     };
0065 ///     // The logger decorator
0066 ///     BOOST_HOF_STATIC_FUNCTION(logger) = boost::hof::decorate(logger_f());
0067 ///     
0068 ///     struct sum_f
0069 ///     {
0070 ///         template<class T, class U>
0071 ///         T operator()(T x, U y) const
0072 ///         {
0073 ///             return x+y;
0074 ///         }
0075 ///     };
0076 ///     
0077 ///     BOOST_HOF_STATIC_FUNCTION(sum) = sum_f();
0078 ///     int main() {
0079 ///         // Use the logger decorator to print "Calling sum" when the function is called
0080 ///         assert(3 == logger("Calling sum")(sum)(1, 2));
0081 ///     }
0082 /// 
0083 
0084 #include <boost/hof/reveal.hpp>
0085 #include <boost/hof/detail/delegate.hpp>
0086 #include <boost/hof/detail/move.hpp>
0087 #include <boost/hof/detail/make.hpp>
0088 #include <boost/hof/detail/callable_base.hpp>
0089 #include <boost/hof/detail/static_const_var.hpp>
0090 #include <boost/hof/detail/compressed_pair.hpp>
0091 
0092 namespace boost { namespace hof { namespace detail {
0093 
0094 template<class D, class T, class F>
0095 struct decorator_invoke
0096 // : compressed_pair<compressed_pair<F, T>, D>
0097 : compressed_pair<compressed_pair<D, T>, F>
0098 {
0099     // typedef compressed_pair<F, T> base;
0100     typedef compressed_pair<compressed_pair<D, T>, F> base;
0101 
0102     BOOST_HOF_INHERIT_CONSTRUCTOR(decorator_invoke, base)
0103 
0104     template<class... Ts>
0105     constexpr const compressed_pair<D, T>& get_pair(Ts&&... xs) const noexcept
0106     {
0107         return this->first(xs...);
0108     }
0109 
0110     template<class... Ts>
0111     constexpr const F& base_function(Ts&&... xs) const noexcept
0112     {
0113         return this->second(xs...);
0114     }
0115 
0116     template<class... Ts>
0117     constexpr const D& get_decorator(Ts&&... xs) const noexcept
0118     {
0119         return this->get_pair(xs...).first(xs...);
0120     }
0121 
0122     template<class... Ts>
0123     constexpr const T& get_data(Ts&&... xs) const noexcept
0124     {
0125         return this->get_pair(xs...).second(xs...);
0126     }
0127 
0128     BOOST_HOF_RETURNS_CLASS(decorator_invoke);
0129 
0130     struct decorator_invoke_failure
0131     {
0132         template<class Failure>
0133         struct apply
0134         {
0135             template<class... Ts>
0136             struct of
0137             : Failure::template of<const T&, const F&, Ts...>
0138             {};
0139         };
0140     };
0141 
0142     struct failure
0143     : failure_map<decorator_invoke_failure, D>
0144     {};
0145 
0146     template<class... Ts>
0147     constexpr BOOST_HOF_SFINAE_RESULT(const D&, id_<const T&>, id_<const F&>, id_<Ts>...) 
0148     operator()(Ts&&... xs) const BOOST_HOF_SFINAE_RETURNS
0149     (
0150         BOOST_HOF_MANGLE_CAST(const D&)(BOOST_HOF_CONST_THIS->get_decorator(xs...))(
0151             BOOST_HOF_MANGLE_CAST(const T&)(BOOST_HOF_CONST_THIS->get_data(xs...)),
0152             BOOST_HOF_MANGLE_CAST(const F&)(BOOST_HOF_CONST_THIS->base_function(xs...)),
0153             BOOST_HOF_FORWARD(Ts)(xs)...
0154         )
0155     );
0156 };
0157 
0158 template<class D, class T>
0159 struct decoration
0160 : compressed_pair<D, T>
0161 {
0162     typedef compressed_pair<D, T> base;
0163     BOOST_HOF_INHERIT_CONSTRUCTOR(decoration, base)
0164 
0165     template<class... Ts>
0166     constexpr const D& get_decorator(Ts&&... xs) const noexcept
0167     {
0168         return this->first(xs...);
0169     }
0170 
0171     template<class... Ts>
0172     constexpr const T& get_data(Ts&&... xs) const noexcept
0173     {
0174         return this->second(xs...);
0175     }
0176 
0177     template<class F>
0178     constexpr decorator_invoke<D, T, detail::callable_base<F>> operator()(F f) const
0179     BOOST_HOF_NOEXCEPT(BOOST_HOF_IS_NOTHROW_CONSTRUCTIBLE(decorator_invoke<D, T, detail::callable_base<F>>, compressed_pair<D, T>, detail::callable_base<F>&&))
0180     {
0181         return decorator_invoke<D, T, detail::callable_base<F>>(
0182             *this, static_cast<detail::callable_base<F>&&>(f)
0183         );
0184     }
0185 };
0186 
0187 }
0188 
0189 template<class F>
0190 struct decorate_adaptor : detail::callable_base<F>
0191 {
0192     typedef decorate_adaptor fit_rewritable1_tag;
0193     typedef detail::callable_base<F> base;
0194     BOOST_HOF_INHERIT_CONSTRUCTOR(decorate_adaptor, detail::callable_base<F>)
0195 
0196     template<class... Ts>
0197     constexpr const base& base_function(Ts&&... xs) const noexcept
0198     {
0199         return boost::hof::always_ref(*this)(xs...);
0200     }
0201 
0202     // TODO: Add predicate for constraints
0203 
0204     template<class T>
0205     constexpr detail::decoration<base, T> operator()(T x) const 
0206     BOOST_HOF_NOEXCEPT(BOOST_HOF_IS_NOTHROW_CONSTRUCTIBLE(base, const base&) && BOOST_HOF_IS_NOTHROW_CONSTRUCTIBLE(T, T&&))
0207     {
0208         return detail::decoration<base, T>(this->base_function(x), static_cast<T&&>(x));
0209     }
0210 
0211 };
0212 
0213 BOOST_HOF_DECLARE_STATIC_VAR(decorate, detail::make<decorate_adaptor>);
0214 
0215 }} // namespace boost::hof
0216 
0217 #endif