• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*=============================================================================
2     Copyright (c) 2016 Paul Fultz II
3     limit.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_LIMIT_H
9 #define BOOST_HOF_GUARD_LIMIT_H
10 
11 /// limit
12 /// =====
13 ///
14 /// Description
15 /// -----------
16 ///
17 /// The `limit` function decorator annotates the function with the max number
18 /// of parameters. The `limit_c` version can be used to give the max number
19 /// directly(instead of relying on an integral constant). The parameter limit
20 /// can be read by using the [`function_param_limit`](function_param_limit)
21 /// trait. Using `limit` is useful to improve error reporting with partially
22 /// evaluated functions.
23 ///
24 /// Synopsis
25 /// --------
26 ///
27 ///     template<class IntegralConstant>
28 ///     constexpr auto limit(IntegralConstant);
29 ///
30 ///     template<std::size_t N, class F>
31 ///     constexpr auto limit_c(F);
32 ///
33 /// Requirements
34 /// ------------
35 ///
36 /// IntegralConstant must be:
37 ///
38 /// * IntegralConstant
39 ///
40 /// F must be:
41 ///
42 /// * [ConstInvocable](ConstInvocable)
43 /// * MoveConstructible
44 ///
45 /// Example
46 /// -------
47 ///
48 ///     #include <boost/hof.hpp>
49 ///     #include <cassert>
50 ///     using namespace boost::hof;
51 ///
52 ///     struct sum_f
53 ///     {
54 ///         template<class T>
55 ///         int operator()(T x, T y) const
56 ///         {
57 ///             return x+y;
58 ///         }
59 ///     };
60 ///     BOOST_HOF_STATIC_FUNCTION(sum) = limit_c<2>(sum_f());
61 ///
62 ///     int main() {
63 ///         assert(3 == sum(1, 2));
64 ///     }
65 ///
66 /// See Also
67 /// --------
68 ///
69 /// * [Partial function evaluation](<Partial function evaluation>)
70 /// * [function_param_limit](function_param_limit)
71 ///
72 
73 #include <boost/hof/detail/callable_base.hpp>
74 #include <boost/hof/detail/forward.hpp>
75 #include <boost/hof/detail/delegate.hpp>
76 #include <boost/hof/detail/move.hpp>
77 #include <boost/hof/detail/static_const_var.hpp>
78 #include <boost/hof/always.hpp>
79 #include <boost/hof/function_param_limit.hpp>
80 
81 namespace boost { namespace hof {
82 
83 namespace detail {
84 // TODO: Make this work with fit_rewritable1_tag
85 template<std::size_t N, class F>
86 struct limit_adaptor : detail::callable_base<F>
87 {
88     typedef std::integral_constant<std::size_t, N> fit_function_param_limit;
BOOST_HOF_INHERIT_CONSTRUCTORboost::hof::detail::limit_adaptor89     BOOST_HOF_INHERIT_CONSTRUCTOR(limit_adaptor, detail::callable_base<F>)
90 
91     template<class... Ts>
92     constexpr const detail::callable_base<F>& base_function(Ts&&... xs) const
93     {
94         return boost::hof::always_ref(*this)(xs...);
95     }
96 
97     BOOST_HOF_RETURNS_CLASS(limit_adaptor);
98 
99     template<class... Ts, class=typename std::enable_if<(sizeof...(Ts) <= N)>::type>
100     constexpr BOOST_HOF_SFINAE_RESULT(const detail::callable_base<F>&, id_<Ts>...)
101     operator()(Ts&&... xs) const BOOST_HOF_SFINAE_RETURNS
102     (
103         (BOOST_HOF_MANGLE_CAST(const detail::callable_base<F>&)(BOOST_HOF_CONST_THIS->base_function(xs...)))
104             (BOOST_HOF_FORWARD(Ts)(xs)...)
105     );
106 
107 };
108 
109 template<std::size_t N>
110 struct make_limit_f
111 {
make_limit_fboost::hof::detail::make_limit_f112     constexpr make_limit_f()
113     {}
114     template<class F>
operator ()boost::hof::detail::make_limit_f115     constexpr limit_adaptor<N, F> operator()(F f) const
116     {
117         return limit_adaptor<N, F>(static_cast<F&&>(f));
118     }
119 };
120 
121 struct limit_f
122 {
123     template<class IntegralConstant, std::size_t N=IntegralConstant::type::value>
operator ()boost::hof::detail::limit_f124     constexpr make_limit_f<N> operator()(IntegralConstant) const
125     {
126         return {};
127     }
128 };
129 
130 }
131 
132 template<std::size_t N, class F>
limit_c(F f)133 constexpr detail::limit_adaptor<N, F> limit_c(F f)
134 {
135     return detail::limit_adaptor<N, F>(static_cast<F&&>(f));
136 }
137 
138 BOOST_HOF_DECLARE_STATIC_VAR(limit, detail::limit_f);
139 
140 }} // namespace boost::hof
141 
142 #endif
143