1 /*! 2 @file 3 Defines `boost::hana::eval_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_EVAL_IF_HPP 11 #define BOOST_HANA_EVAL_IF_HPP 12 13 #include <boost/hana/fwd/eval_if.hpp> 14 15 #include <boost/hana/bool.hpp> 16 #include <boost/hana/concept/constant.hpp> 17 #include <boost/hana/concept/logical.hpp> 18 #include <boost/hana/config.hpp> 19 #include <boost/hana/core/dispatch.hpp> 20 #include <boost/hana/eval.hpp> 21 #include <boost/hana/if.hpp> 22 23 #include <type_traits> 24 25 26 BOOST_HANA_NAMESPACE_BEGIN 27 //! @cond 28 template <typename Cond, typename Then, typename Else> operator ()(Cond && cond,Then && then_,Else && else_) const29 constexpr decltype(auto) eval_if_t::operator()(Cond&& cond, Then&& then_, Else&& else_) const { 30 using Bool = typename hana::tag_of<Cond>::type; 31 using EvalIf = BOOST_HANA_DISPATCH_IF(eval_if_impl<Bool>, 32 hana::Logical<Bool>::value 33 ); 34 35 #ifndef BOOST_HANA_CONFIG_DISABLE_CONCEPT_CHECKS 36 static_assert(hana::Logical<Bool>::value, 37 "hana::eval_if(cond, then, else) requires 'cond' to be a Logical"); 38 #endif 39 40 return EvalIf::apply(static_cast<Cond&&>(cond), 41 static_cast<Then&&>(then_), 42 static_cast<Else&&>(else_)); 43 } 44 //! @endcond 45 46 template <typename L, bool condition> 47 struct eval_if_impl<L, when<condition>> : default_ { 48 template <typename ...Args> 49 static constexpr auto apply(Args&& ...) = delete; 50 }; 51 52 ////////////////////////////////////////////////////////////////////////// 53 // Model for arithmetic data types 54 ////////////////////////////////////////////////////////////////////////// 55 template <typename L> 56 struct eval_if_impl<L, when<std::is_arithmetic<L>::value>> { 57 template <typename Cond, typename T, typename E> applyeval_if_impl58 static constexpr auto apply(Cond const& cond, T&& t, E&& e) { 59 return cond ? hana::eval(static_cast<T&&>(t)) 60 : hana::eval(static_cast<E&&>(e)); 61 } 62 }; 63 64 ////////////////////////////////////////////////////////////////////////// 65 // Model for Constants over a Logical 66 ////////////////////////////////////////////////////////////////////////// 67 template <typename C> 68 struct eval_if_impl<C, when< 69 hana::Constant<C>::value && 70 Logical<typename C::value_type>::value 71 >> { 72 template <typename Then, typename Else> 73 static constexpr decltype(auto) eval_if_helpereval_if_impl74 eval_if_helper(hana::true_, Then&& t, Else&&) 75 { return hana::eval(static_cast<Then&&>(t)); } 76 77 template <typename Then, typename Else> 78 static constexpr decltype(auto) eval_if_helpereval_if_impl79 eval_if_helper(hana::false_, Then&&, Else&& e) 80 { return hana::eval(static_cast<Else&&>(e)); } 81 82 template <typename Cond, typename Then, typename Else> applyeval_if_impl83 static constexpr decltype(auto) apply(Cond const&, Then&& t, Else&& e) { 84 constexpr auto cond = hana::value<Cond>(); 85 constexpr bool truth_value = hana::if_(cond, true, false); 86 return eval_if_helper(hana::bool_<truth_value>{}, 87 static_cast<Then&&>(t), 88 static_cast<Else&&>(e)); 89 } 90 }; 91 BOOST_HANA_NAMESPACE_END 92 93 #endif // !BOOST_HANA_EVAL_IF_HPP 94