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     arg.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_ARGS_H
0009 #define BOOST_HOF_GUARD_FUNCTION_ARGS_H
0010 
0011 #include <boost/hof/detail/seq.hpp>
0012 #include <boost/hof/returns.hpp>
0013 #include <boost/hof/detail/static_const_var.hpp>
0014 #include <utility>
0015 
0016 /// arg
0017 /// ===
0018 /// 
0019 /// Description
0020 /// -----------
0021 /// 
0022 /// The `arg` function returns a function object that returns the Nth argument
0023 /// passed to it. It actually starts at 1, so it is not the zero-based index
0024 /// of the argument.
0025 /// 
0026 /// Synopsis
0027 /// --------
0028 /// 
0029 ///     template<class IntegralConstant>
0030 ///     constexpr auto arg(IntegralConstant);
0031 /// 
0032 ///     template<std::size_t N, class... Ts>
0033 ///     constexpr auto arg_c(Ts&&...);
0034 /// 
0035 /// 
0036 /// Example
0037 /// -------
0038 /// 
0039 ///     #include <boost/hof.hpp>
0040 ///     #include <cassert>
0041 ///     using namespace boost::hof;
0042 /// 
0043 ///     int main() {
0044 ///         assert(arg(std::integral_constant<int, 3>())(1,2,3,4,5) == 3);
0045 ///     }
0046 /// 
0047 
0048 namespace boost { namespace hof {
0049 
0050 namespace detail {
0051 
0052 template<class T>
0053 struct perfect_ref
0054 {
0055     typedef T type;
0056     typedef typename std::remove_reference<T>::type value_type;
0057     T&& value;
0058     constexpr perfect_ref(value_type& x) noexcept
0059     : value(BOOST_HOF_FORWARD(T)(x))
0060     {}
0061 };
0062 
0063 template<std::size_t N>
0064 struct ignore
0065 {
0066     template<class T>
0067     constexpr ignore(T&&...) noexcept
0068     {}
0069 };
0070 
0071 template<std::size_t... N>
0072 struct args_at
0073 {
0074     template<class T, class... Ts>
0075     constexpr auto operator()(ignore<N>..., T x, Ts...) const 
0076     BOOST_HOF_RETURNS(BOOST_HOF_FORWARD(typename T::type)(x.value));
0077 };
0078 
0079 template<std::size_t... N>
0080 constexpr args_at<N...> make_args_at(seq<N...>) noexcept
0081 {
0082     return {};
0083 }
0084 
0085 template<std::size_t N, class... Ts>
0086 constexpr auto get_args(Ts&&... xs) BOOST_HOF_RETURNS
0087 (
0088     boost::hof::detail::make_args_at(typename gens<N>::type())(nullptr, BOOST_HOF_RETURNS_CONSTRUCT(perfect_ref<Ts>)(xs)...)
0089 );
0090 
0091 template<class T, T N>
0092 struct make_args_f
0093 {
0094     template<class... Ts, class=typename std::enable_if<(N <= sizeof...(Ts))>::type>
0095     constexpr auto operator()(Ts&&... xs) const BOOST_HOF_RETURNS
0096     (
0097         boost::hof::detail::get_args<N>(BOOST_HOF_FORWARD(Ts)(xs)...)
0098     );
0099 };
0100 
0101 struct arg_f
0102 {
0103     template<class IntegralConstant>
0104     constexpr make_args_f<std::size_t, IntegralConstant::value> operator()(IntegralConstant) const noexcept
0105     {
0106         return make_args_f<std::size_t, IntegralConstant::value>();
0107     }
0108 };
0109 
0110 }
0111 #if BOOST_HOF_HAS_VARIABLE_TEMPLATES
0112 template<std::size_t N>
0113 BOOST_HOF_STATIC_CONSTEXPR detail::make_args_f<std::size_t, N> arg_c = {};
0114 #else
0115 template<std::size_t N, class... Ts>
0116 constexpr auto arg_c(Ts&&... xs) BOOST_HOF_RETURNS
0117 (
0118     boost::hof::detail::get_args<N>(BOOST_HOF_FORWARD(Ts)(xs)...)
0119 );
0120 #endif
0121 
0122 BOOST_HOF_DECLARE_STATIC_VAR(arg, detail::arg_f);
0123 
0124 }} // namespace boost::hof
0125 
0126 #endif