• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1/*=============================================================================
2    Copyright (c) 2014 Paul Fultz II
3    static.h
4    Distributed under the Boost Software License, Version 1.0. (See accompanying
5    file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
6==============================================================================*/
7
8#ifndef BOOST_HOF_GUARD_FUNCTION_STATIC_H
9#define BOOST_HOF_GUARD_FUNCTION_STATIC_H
10
11/// static
12/// ======
13///
14/// Description
15/// -----------
16///
17/// The `static_` adaptor is a static function adaptor that allows any
18/// default-constructible function object to be static-initialized. Functions
19/// initialized by `static_` cannot be used in `constexpr` functions. If the
20/// function needs to be statically initialized and called in a `constexpr`
21/// context, then a `constexpr` constructor needs to be used rather than
22/// `static_`.
23///
24/// Synopsis
25/// --------
26///
27///     template<class F>
28///     class static_;
29///
30/// Requirements
31/// ------------
32///
33/// F must be:
34///
35/// * [ConstFunctionObject](ConstFunctionObject)
36/// * DefaultConstructible
37///
38/// Example
39/// -------
40///
41///     #include <boost/hof.hpp>
42///     #include <cassert>
43///     using namespace boost::hof;
44///
45///     // In C++ this class can't be static-initialized, because of the non-
46///     // trivial default constructor.
47///     struct times_function
48///     {
49///         double factor;
50///         times_function() : factor(2)
51///         {}
52///         template<class T>
53///         T operator()(T x) const
54///         {
55///             return x*factor;
56///         }
57///     };
58///
59///     static constexpr static_<times_function> times2 = {};
60///
61///     int main() {
62///         assert(6 == times2(3));
63///     }
64///
65
66#include <boost/hof/detail/result_of.hpp>
67#include <boost/hof/reveal.hpp>
68
69namespace boost { namespace hof {
70
71template<class F>
72struct static_
73{
74
75    struct failure
76    : failure_for<F>
77    {};
78
79    const F& base_function() const
80    BOOST_HOF_NOEXCEPT_CONSTRUCTIBLE(F)
81    {
82        static F f;
83        return f;
84    }
85
86    BOOST_HOF_RETURNS_CLASS(static_);
87
88    template<class... Ts>
89    BOOST_HOF_SFINAE_RESULT(F, id_<Ts>...)
90    operator()(Ts && ... xs) const
91    BOOST_HOF_SFINAE_RETURNS(BOOST_HOF_CONST_THIS->base_function()(BOOST_HOF_FORWARD(Ts)(xs)...));
92};
93
94
95}} // namespace boost::hof
96
97#endif
98