1 /*! 2 @file 3 Defines `boost::hana::eval`. 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_HPP 11 #define BOOST_HANA_EVAL_HPP 12 13 #include <boost/hana/fwd/eval.hpp> 14 15 #include <boost/hana/config.hpp> 16 #include <boost/hana/core/dispatch.hpp> 17 #include <boost/hana/detail/wrong.hpp> 18 #include <boost/hana/functional/id.hpp> 19 20 21 BOOST_HANA_NAMESPACE_BEGIN 22 //! @cond 23 template <typename Expr> operator ()(Expr && expr) const24 constexpr decltype(auto) eval_t::operator()(Expr&& expr) const { 25 return eval_impl<typename hana::tag_of<Expr>::type>::apply( 26 static_cast<Expr&&>(expr) 27 ); 28 } 29 //! @endcond 30 31 template <typename T, bool condition> 32 struct eval_impl<T, when<condition>> : default_ { 33 template <typename Expr> eval_helpereval_impl34 static constexpr auto eval_helper(Expr&& expr, int) 35 -> decltype(static_cast<Expr&&>(expr)()) 36 { return static_cast<Expr&&>(expr)(); } 37 38 template <typename Expr> eval_helpereval_impl39 static constexpr auto eval_helper(Expr&& expr, long) 40 -> decltype(static_cast<Expr&&>(expr)(hana::id)) 41 { return static_cast<Expr&&>(expr)(hana::id); } 42 43 template <typename Expr> eval_helpereval_impl44 static constexpr auto eval_helper(Expr&&, ...) { 45 static_assert(detail::wrong<Expr>{}, 46 "hana::eval(expr) requires the expression to be a hana::lazy, " 47 "a nullary Callable or a unary Callable that may be " 48 "called with hana::id"); 49 } 50 51 template <typename Expr> applyeval_impl52 static constexpr decltype(auto) apply(Expr&& expr) 53 { return eval_helper(static_cast<Expr&&>(expr), int{}); } 54 }; 55 BOOST_HANA_NAMESPACE_END 56 57 #endif // !BOOST_HANA_EVAL_HPP 58