1 /*! 2 @file 3 Defines `boost::hana::adjust_if`. 4 5 @copyright Louis Dionne 2013-2017 6 Distributed under the Boost Software License, Version 1.0. 7 (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt) 8 */ 9 10 #ifndef BOOST_HANA_ADJUST_IF_HPP 11 #define BOOST_HANA_ADJUST_IF_HPP 12 13 #include <boost/hana/fwd/adjust_if.hpp> 14 15 #include <boost/hana/bool.hpp> 16 #include <boost/hana/concept/functor.hpp> 17 #include <boost/hana/config.hpp> 18 #include <boost/hana/core/dispatch.hpp> 19 #include <boost/hana/if.hpp> 20 #include <boost/hana/transform.hpp> 21 22 23 BOOST_HANA_NAMESPACE_BEGIN 24 //! @cond 25 template <typename Xs, typename Pred, typename F> operator ()(Xs && xs,Pred const & pred,F const & f) const26 constexpr auto adjust_if_t::operator()(Xs&& xs, Pred const& pred, F const& f) const { 27 using S = typename hana::tag_of<Xs>::type; 28 using AdjustIf = BOOST_HANA_DISPATCH_IF(adjust_if_impl<S>, 29 hana::Functor<S>::value 30 ); 31 32 #ifndef BOOST_HANA_CONFIG_DISABLE_CONCEPT_CHECKS 33 static_assert(hana::Functor<S>::value, 34 "hana::adjust_if(xs, pred, f) requires 'xs' to be a Functor"); 35 #endif 36 37 return AdjustIf::apply(static_cast<Xs&&>(xs), pred, f); 38 } 39 //! @endcond 40 41 namespace detail { 42 template <typename Pred, typename F> 43 struct apply_if { 44 Pred const& pred; 45 F const& f; 46 47 template <typename X> helperdetail::apply_if48 constexpr decltype(auto) helper(bool cond, X&& x) const 49 { return cond ? f(static_cast<X&&>(x)) : static_cast<X&&>(x); } 50 51 template <typename X> helperdetail::apply_if52 constexpr decltype(auto) helper(hana::true_, X&& x) const 53 { return f(static_cast<X&&>(x)); } 54 55 template <typename X> helperdetail::apply_if56 constexpr decltype(auto) helper(hana::false_, X&& x) const 57 { return static_cast<X&&>(x); } 58 59 60 template <typename X> operator ()detail::apply_if61 constexpr decltype(auto) operator()(X&& x) const { 62 auto cond = hana::if_(pred(x), hana::true_c, hana::false_c); 63 return this->helper(cond, static_cast<X&&>(x)); 64 } 65 }; 66 } 67 68 template <typename Fun, bool condition> 69 struct adjust_if_impl<Fun, when<condition>> : default_ { 70 template <typename Xs, typename Pred, typename F> applyadjust_if_impl71 static constexpr auto apply(Xs&& xs, Pred const& pred, F const& f) { 72 return hana::transform(static_cast<Xs&&>(xs), 73 detail::apply_if<Pred, F>{pred, f}); 74 } 75 }; 76 BOOST_HANA_NAMESPACE_END 77 78 #endif // !BOOST_HANA_ADJUST_IF_HPP 79