Back to home page

EIC code displayed by LXR

 
 

    


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

0001 /*=============================================================================
0002     Copyright (c) 2014 Paul Fultz II
0003     always.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_ALWAYS_H
0009 #define BOOST_HOF_GUARD_FUNCTION_ALWAYS_H
0010 
0011 #include <boost/hof/detail/delegate.hpp>
0012 #include <boost/hof/detail/unwrap.hpp>
0013 #include <boost/hof/detail/static_const_var.hpp>
0014 
0015 /// always
0016 /// ======
0017 /// 
0018 /// Description
0019 /// -----------
0020 /// 
0021 /// The `always` function returns a function object that will always return
0022 /// the value given to it, no matter what parameters are passed to the
0023 /// function object. The nullary version(i.e. `always(void)`) will return
0024 /// `void`. On compilers, that don't support constexpr functions returning
0025 /// `void`, a private empty type is returned instead. This return type is
0026 /// specified as `BOOST_HOF_ALWAYS_VOID_RETURN`.
0027 /// 
0028 /// Synopsis
0029 /// --------
0030 /// 
0031 ///     template<class T>
0032 ///     constexpr auto always(T value);
0033 /// 
0034 ///     template<class T>
0035 ///     constexpr auto always(void);
0036 /// 
0037 /// 
0038 /// Semantics
0039 /// ---------
0040 /// 
0041 ///     assert(always(x)(xs...) == x);
0042 /// 
0043 /// Requirements
0044 /// ------------
0045 /// 
0046 /// T must be:
0047 /// 
0048 /// * CopyConstructible
0049 /// 
0050 /// Example
0051 /// -------
0052 /// 
0053 ///     #include <boost/hof.hpp>
0054 ///     #include <algorithm>
0055 ///     #include <cassert>
0056 ///     using namespace boost::hof;
0057 /// 
0058 ///     int main() {
0059 ///         int ten = 10;
0060 ///         assert( always(ten)(1,2,3,4,5) == 10 );
0061 ///     }
0062 /// 
0063 ///     // Count all
0064 ///     template<class Iterator, class T>
0065 ///     auto count(Iterator first, Iterator last)
0066 ///     {
0067 ///         return std::count_if(first, last, always(true));
0068 ///     }
0069 /// 
0070 
0071 
0072 #ifndef BOOST_HOF_NO_CONSTEXPR_VOID
0073 #if defined(__clang__) && BOOST_HOF_HAS_RELAXED_CONSTEXPR
0074 #define BOOST_HOF_NO_CONSTEXPR_VOID 0
0075 #else
0076 #define BOOST_HOF_NO_CONSTEXPR_VOID 1
0077 #endif
0078 #endif
0079 
0080 namespace boost { namespace hof { namespace always_detail {
0081 
0082 template<class T, class=void>
0083 struct always_base
0084 {
0085     T x;
0086 
0087     BOOST_HOF_DELEGATE_CONSTRUCTOR(always_base, T, x)
0088 
0089     typedef typename detail::unwrap_reference<T>::type result_type;
0090 
0091     template<class... As>
0092     constexpr result_type
0093     operator()(As&&...) const
0094     noexcept(std::is_reference<result_type>::value || BOOST_HOF_IS_NOTHROW_COPY_CONSTRUCTIBLE(result_type))
0095     {
0096         return this->x;
0097     }
0098 };
0099 
0100 template<class T>
0101 struct always_base<T, typename std::enable_if<!BOOST_HOF_IS_EMPTY(T)>::type>
0102 {
0103     T x;
0104 
0105     constexpr always_base(T xp) noexcept(BOOST_HOF_IS_NOTHROW_COPY_CONSTRUCTIBLE(T))
0106     : x(xp)
0107     {}
0108 
0109     typedef typename detail::unwrap_reference<T>::type result_type;
0110 
0111     template<class... As>
0112     constexpr result_type 
0113     operator()(As&&...) const 
0114     noexcept(std::is_reference<result_type>::value || BOOST_HOF_IS_NOTHROW_COPY_CONSTRUCTIBLE(result_type))
0115     {
0116         return this->x;
0117     }
0118 };
0119 
0120 #if BOOST_HOF_NO_CONSTEXPR_VOID
0121 #define BOOST_HOF_ALWAYS_VOID_RETURN boost::hof::always_detail::always_base<void>::void_
0122 #else
0123 #define BOOST_HOF_ALWAYS_VOID_RETURN void
0124 #endif
0125 
0126 template<>
0127 struct always_base<void>
0128 {
0129     
0130     constexpr always_base() noexcept
0131     {}
0132 
0133     struct void_ {};
0134 
0135     template<class... As>
0136     constexpr BOOST_HOF_ALWAYS_VOID_RETURN 
0137     operator()(As&&...) const noexcept
0138     {
0139 #if BOOST_HOF_NO_CONSTEXPR_VOID
0140         return void_();
0141 #endif
0142     }
0143 };
0144 
0145 struct always_f
0146 {
0147     template<class T>
0148     constexpr always_detail::always_base<T> operator()(T x) const noexcept(BOOST_HOF_IS_NOTHROW_COPY_CONSTRUCTIBLE(T))
0149     {
0150         return always_detail::always_base<T>(x);
0151     }
0152 
0153     constexpr always_detail::always_base<void> operator()() const noexcept
0154     {
0155         return always_detail::always_base<void>();
0156     }
0157 };
0158 
0159 struct always_ref_f
0160 {
0161     template<class T>
0162     constexpr always_detail::always_base<T&> operator()(T& x) const noexcept
0163     {
0164         return always_detail::always_base<T&>(x);
0165     }
0166 };
0167 
0168 }
0169 BOOST_HOF_DECLARE_STATIC_VAR(always, always_detail::always_f);
0170 BOOST_HOF_DECLARE_STATIC_VAR(always_ref, always_detail::always_ref_f);
0171 
0172 }} // namespace boost::hof
0173 
0174 #endif