Back to home page

EIC code displayed by LXR

 
 

    


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

0001 /*=============================================================================
0002     Copyright (c) 2014 Paul Fultz II
0003     function.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_FUNCTION_H
0009 #define BOOST_HOF_GUARD_FUNCTION_FUNCTION_H
0010 
0011 /// BOOST_HOF_STATIC_FUNCTION
0012 /// ===================
0013 /// 
0014 /// Description
0015 /// -----------
0016 /// 
0017 
0018 /// The `BOOST_HOF_STATIC_FUNCTION` macro allows initializing a function object from a
0019 /// `constexpr` expression. It uses the best practices as outlined in
0020 /// [N4381](http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2015/n4381.html).
0021 /// This includes using `const` to avoid global state, compile-time
0022 /// initialization of the function object to avoid the [static initialization
0023 /// order fiasco](https://isocpp.org/wiki/faq/ctors#static-init-order), and an
0024 /// external address of the function object that is the same across translation
0025 /// units to avoid possible One-Definition-Rule(ODR) violations.
0026 /// 
0027 /// In C++17, this achieved using the `inline` keyword. However, on older
0028 /// compilers it is initialized using a reference to a static member variable.
0029 /// The static member variable is default constructed, as such the user variable
0030 /// is always default constructed regardless of the expression.
0031 /// 
0032 /// By default, all functions defined with `BOOST_HOF_STATIC_FUNCTION` use the
0033 /// [`boost::hof::reveal`](/include/boost/hof/reveal) adaptor to improve error messages.
0034 /// 
0035 /// Example
0036 /// -------
0037 /// 
0038 ///     #include <boost/hof.hpp>
0039 ///     #include <cassert>
0040 /// 
0041 ///     struct sum_f
0042 ///     {
0043 ///         template<class T, class U>
0044 ///         T operator()(T x, U y) const
0045 ///         {
0046 ///             return x+y;
0047 ///         }
0048 ///     };
0049 /// 
0050 ///     BOOST_HOF_STATIC_FUNCTION(sum) = sum_f();
0051 ///     BOOST_HOF_STATIC_FUNCTION(partial_sum) = boost::hof::partial(sum_f());
0052 /// 
0053 ///     int main() {
0054 ///         assert(sum(1, 2) == partial_sum(1)(2));
0055 ///     }
0056 /// 
0057 
0058 #include <boost/hof/reveal.hpp>
0059 #if !BOOST_HOF_HAS_INLINE_VARIABLES
0060 #include <boost/hof/detail/static_const_var.hpp>
0061 #include <boost/hof/detail/constexpr_deduce.hpp>
0062 #endif
0063 
0064 namespace boost { namespace hof {
0065 
0066 namespace detail {
0067 
0068 struct reveal_static_const_factory
0069 {
0070     constexpr reveal_static_const_factory()
0071     {}
0072     template<class F>
0073     constexpr reveal_adaptor<F> operator=(const F& f) const
0074     {
0075 #if BOOST_HOF_HAS_INLINE_VARIABLES
0076 #else
0077         static_assert(BOOST_HOF_IS_DEFAULT_CONSTRUCTIBLE(F), "Static functions must be default constructible");
0078 #endif
0079         return reveal_adaptor<F>(f);
0080     }
0081 };
0082 }}} // namespace boost::hof
0083 
0084 #if BOOST_HOF_HAS_INLINE_VARIABLES
0085 #define BOOST_HOF_STATIC_FUNCTION(name) inline const constexpr auto name = boost::hof::detail::reveal_static_const_factory()
0086 #else
0087 #define BOOST_HOF_STATIC_FUNCTION(name) BOOST_HOF_STATIC_CONST_VAR(name) = BOOST_HOF_DETAIL_MSVC_CONSTEXPR_DEDUCE boost::hof::detail::reveal_static_const_factory()
0088 #endif
0089 
0090 #endif