eval_if.hpp 3.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293
  1. /*!
  2. @file
  3. Defines `boost::hana::eval_if`.
  4. @copyright Louis Dionne 2013-2017
  5. Distributed under the Boost Software License, Version 1.0.
  6. (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
  7. */
  8. #ifndef BOOST_HANA_EVAL_IF_HPP
  9. #define BOOST_HANA_EVAL_IF_HPP
  10. #include <boost/hana/fwd/eval_if.hpp>
  11. #include <boost/hana/bool.hpp>
  12. #include <boost/hana/concept/constant.hpp>
  13. #include <boost/hana/concept/logical.hpp>
  14. #include <boost/hana/config.hpp>
  15. #include <boost/hana/core/dispatch.hpp>
  16. #include <boost/hana/eval.hpp>
  17. #include <boost/hana/if.hpp>
  18. #include <type_traits>
  19. BOOST_HANA_NAMESPACE_BEGIN
  20. //! @cond
  21. template <typename Cond, typename Then, typename Else>
  22. constexpr decltype(auto) eval_if_t::operator()(Cond&& cond, Then&& then_, Else&& else_) const {
  23. using Bool = typename hana::tag_of<Cond>::type;
  24. using EvalIf = BOOST_HANA_DISPATCH_IF(eval_if_impl<Bool>,
  25. hana::Logical<Bool>::value
  26. );
  27. #ifndef BOOST_HANA_CONFIG_DISABLE_CONCEPT_CHECKS
  28. static_assert(hana::Logical<Bool>::value,
  29. "hana::eval_if(cond, then, else) requires 'cond' to be a Logical");
  30. #endif
  31. return EvalIf::apply(static_cast<Cond&&>(cond),
  32. static_cast<Then&&>(then_),
  33. static_cast<Else&&>(else_));
  34. }
  35. //! @endcond
  36. template <typename L, bool condition>
  37. struct eval_if_impl<L, when<condition>> : default_ {
  38. template <typename ...Args>
  39. static constexpr auto apply(Args&& ...) = delete;
  40. };
  41. //////////////////////////////////////////////////////////////////////////
  42. // Model for arithmetic data types
  43. //////////////////////////////////////////////////////////////////////////
  44. template <typename L>
  45. struct eval_if_impl<L, when<std::is_arithmetic<L>::value>> {
  46. template <typename Cond, typename T, typename E>
  47. static constexpr auto apply(Cond const& cond, T&& t, E&& e) {
  48. return cond ? hana::eval(static_cast<T&&>(t))
  49. : hana::eval(static_cast<E&&>(e));
  50. }
  51. };
  52. //////////////////////////////////////////////////////////////////////////
  53. // Model for Constants over a Logical
  54. //////////////////////////////////////////////////////////////////////////
  55. template <typename C>
  56. struct eval_if_impl<C, when<
  57. hana::Constant<C>::value &&
  58. Logical<typename C::value_type>::value
  59. >> {
  60. template <typename Then, typename Else>
  61. static constexpr decltype(auto)
  62. eval_if_helper(hana::true_, Then&& t, Else&&)
  63. { return hana::eval(static_cast<Then&&>(t)); }
  64. template <typename Then, typename Else>
  65. static constexpr decltype(auto)
  66. eval_if_helper(hana::false_, Then&&, Else&& e)
  67. { return hana::eval(static_cast<Else&&>(e)); }
  68. template <typename Cond, typename Then, typename Else>
  69. static constexpr decltype(auto) apply(Cond const&, Then&& t, Else&& e) {
  70. constexpr auto cond = hana::value<Cond>();
  71. constexpr bool truth_value = hana::if_(cond, true, false);
  72. return eval_if_helper(hana::bool_<truth_value>{},
  73. static_cast<Then&&>(t),
  74. static_cast<Else&&>(e));
  75. }
  76. };
  77. BOOST_HANA_NAMESPACE_END
  78. #endif // !BOOST_HANA_EVAL_IF_HPP