1/*============================================================================= 2 Copyright (c) 2015 Paul Fultz II 3 if_.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_IF_H 9#define BOOST_HOF_GUARD_IF_H 10 11/// if 12/// == 13/// 14/// Description 15/// ----------- 16/// 17/// The `if_` function decorator makes the function callable if the boolean 18/// condition is true. The `if_c` version can be used to give a boolean 19/// condition directly(instead of relying on an integral constant). 20/// 21/// When `if_` is false, the function is not callable. It is a subtitution 22/// failure to call the function. 23/// 24/// Synopsis 25/// -------- 26/// 27/// template<class IntegralConstant> 28/// constexpr auto if_(IntegralConstant); 29/// 30/// template<bool B, class F> 31/// constexpr auto if_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/// 51/// struct sum_f 52/// { 53/// template<class T> 54/// int operator()(T x, T y) const 55/// { 56/// return boost::hof::first_of( 57/// boost::hof::if_(std::is_integral<T>())(boost::hof::_ + boost::hof::_), 58/// boost::hof::always(0) 59/// )(x, y); 60/// } 61/// }; 62/// 63/// int main() { 64/// assert(sum_f()(1, 2) == 3); 65/// assert(sum_f()("", "") == 0); 66/// } 67/// 68/// References 69/// ---------- 70/// 71/// * [static_if](static_if) 72/// 73 74#include <boost/hof/always.hpp> 75#include <boost/hof/detail/callable_base.hpp> 76#include <boost/hof/detail/forward.hpp> 77#include <boost/hof/detail/delegate.hpp> 78#include <boost/hof/detail/move.hpp> 79#include <boost/hof/detail/static_const_var.hpp> 80 81namespace boost { namespace hof { 82 83namespace detail { 84 85template<class C, class...> 86struct if_depend 87: C 88{}; 89 90template<bool Cond, class F> 91struct if_adaptor : detail::callable_base<F> 92{ 93 BOOST_HOF_INHERIT_CONSTRUCTOR(if_adaptor, detail::callable_base<F>) 94}; 95 96template<class F> 97struct if_adaptor<false, F> 98{ 99 template<class... Ts> 100 constexpr if_adaptor(Ts&&...) noexcept 101 {} 102}; 103 104template<bool Cond> 105struct make_if_f 106{ 107 constexpr make_if_f() noexcept 108 {} 109 template<class F> 110 constexpr if_adaptor<Cond, F> operator()(F f) const BOOST_HOF_NOEXCEPT_CONSTRUCTIBLE(F, F&&) 111 { 112 return if_adaptor<Cond, F>(static_cast<F&&>(f)); 113 } 114}; 115 116struct if_f 117{ 118 constexpr if_f() 119 {} 120 template<class Cond, bool B=Cond::type::value> 121 constexpr make_if_f<B> operator()(Cond) const noexcept 122 { 123 return {}; 124 } 125}; 126 127} 128#if BOOST_HOF_HAS_VARIABLE_TEMPLATES 129template<bool B> 130BOOST_HOF_STATIC_CONSTEXPR detail::make_if_f<B> if_c = {}; 131#else 132template<bool B, class F> 133constexpr detail::if_adaptor<B, F> if_c(F f) BOOST_HOF_NOEXCEPT_CONSTRUCTIBLE(F, F&&) 134{ 135 return detail::if_adaptor<B, F>(static_cast<F&&>(f)); 136} 137#endif 138 139BOOST_HOF_DECLARE_STATIC_VAR(if_, detail::if_f); 140 141}} // namespace boost::hof 142 143#endif 144