1 /*! 2 @file 3 Defines `boost::hana::then`. 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_THEN_HPP 11 #define BOOST_HANA_THEN_HPP 12 13 #include <boost/hana/fwd/then.hpp> 14 15 #include <boost/hana/chain.hpp> 16 #include <boost/hana/concept/monad.hpp> 17 #include <boost/hana/config.hpp> 18 #include <boost/hana/core/dispatch.hpp> 19 #include <boost/hana/functional/always.hpp> 20 21 22 BOOST_HANA_NAMESPACE_BEGIN 23 //! @cond 24 template <typename Before, typename Xs> operator ()(Before && before,Xs && xs) const25 constexpr decltype(auto) then_t::operator()(Before&& before, Xs&& xs) const { 26 using M = typename hana::tag_of<Before>::type; 27 using Then = BOOST_HANA_DISPATCH_IF(then_impl<M>, 28 hana::Monad<M>::value && 29 hana::Monad<Xs>::value 30 ); 31 32 #ifndef BOOST_HANA_CONFIG_DISABLE_CONCEPT_CHECKS 33 static_assert(hana::Monad<M>::value, 34 "hana::then(before, xs) requires 'before' to be a Monad"); 35 36 static_assert(hana::Monad<Xs>::value, 37 "hana::then(before, xs) requires 'xs' to be a Monad"); 38 #endif 39 40 return Then::apply(static_cast<Before&&>(before), 41 static_cast<Xs&&>(xs)); 42 } 43 //! @endcond 44 45 template <typename M, bool condition> 46 struct then_impl<M, when<condition>> : default_ { 47 template <typename Xs, typename Ys> applythen_impl48 static constexpr decltype(auto) apply(Xs&& xs, Ys&& ys) { 49 return hana::chain(static_cast<Xs&&>(xs), 50 hana::always(static_cast<Ys&&>(ys))); 51 } 52 }; 53 BOOST_HANA_NAMESPACE_END 54 55 #endif // !BOOST_HANA_THEN_HPP 56