File indexing completed on 2025-01-30 09:43:40
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010 #ifndef BOOST_HANA_WHILE_HPP
0011 #define BOOST_HANA_WHILE_HPP
0012
0013 #include <boost/hana/fwd/while.hpp>
0014
0015 #include <boost/hana/bool.hpp>
0016 #include <boost/hana/concept/constant.hpp>
0017 #include <boost/hana/concept/constant.hpp>
0018 #include <boost/hana/concept/logical.hpp>
0019 #include <boost/hana/config.hpp>
0020 #include <boost/hana/core/to.hpp>
0021 #include <boost/hana/core/dispatch.hpp>
0022 #include <boost/hana/detail/canonical_constant.hpp>
0023
0024 #include <type_traits>
0025
0026
0027 namespace boost { namespace hana {
0028
0029 template <typename Pred, typename State, typename F>
0030 constexpr decltype(auto) while_t::operator()(Pred&& pred, State&& state, F&& f) const {
0031 using Cond = decltype(pred(state));
0032 using Bool = typename hana::tag_of<Cond>::type;
0033 using While = BOOST_HANA_DISPATCH_IF(while_impl<Bool>,
0034 hana::Logical<Bool>::value
0035 );
0036
0037 #ifndef BOOST_HANA_CONFIG_DISABLE_CONCEPT_CHECKS
0038 static_assert(hana::Logical<Bool>::value,
0039 "hana::while_(pred, state, f) requires 'pred(state)' to be a Logical");
0040 #endif
0041
0042 return While::apply(static_cast<Pred&&>(pred),
0043 static_cast<State&&>(state),
0044 static_cast<F&&>(f));
0045 }
0046
0047
0048 template <typename L, bool condition>
0049 struct while_impl<L, hana::when<condition>> : hana::default_ {
0050 template <typename ...Args>
0051 static constexpr auto apply(Args&& ...) = delete;
0052 };
0053
0054 template <typename L>
0055 struct while_impl<L, hana::when<std::is_arithmetic<L>::value>> {
0056 template <typename Pred, typename State, typename F>
0057 static auto apply(Pred&& pred, State&& state, F&& f)
0058 -> decltype(
0059 true ? f(static_cast<State&&>(state))
0060 : static_cast<State&&>(state)
0061 )
0062 {
0063 if (pred(state)) {
0064 decltype(auto) r = f(static_cast<State&&>(state));
0065 return hana::while_(static_cast<Pred&&>(pred),
0066 static_cast<decltype(r)&&>(r),
0067 static_cast<F&&>(f));
0068 }
0069 else {
0070 return static_cast<State&&>(state);
0071 }
0072 }
0073 };
0074
0075 template <typename C>
0076 struct while_impl<C, hana::when<
0077 hana::Constant<C>::value &&
0078 hana::Logical<typename C::value_type>::value
0079 >> {
0080 template <typename Pred, typename State, typename F>
0081 static constexpr State
0082 while_helper(hana::false_, Pred&&, State&& state, F&&) {
0083 return static_cast<State&&>(state);
0084 }
0085
0086 template <typename Pred, typename State, typename F>
0087 static constexpr decltype(auto)
0088 while_helper(hana::true_, Pred&& pred, State&& state, F&& f) {
0089 decltype(auto) r = f(static_cast<State&&>(state));
0090 return hana::while_(static_cast<Pred&&>(pred),
0091 static_cast<decltype(r)&&>(r),
0092 static_cast<F&&>(f));
0093 }
0094
0095 template <typename Pred, typename State, typename F>
0096 static constexpr decltype(auto)
0097 apply(Pred&& pred, State&& state, F&& f) {
0098
0099
0100
0101
0102
0103
0104
0105
0106 auto cond_ = pred(state);
0107 constexpr auto cond = hana::value(cond_);
0108 constexpr bool truth_value = hana::if_(cond, true, false);
0109 return while_helper(hana::bool_c<truth_value>,
0110 static_cast<Pred&&>(pred),
0111 static_cast<State&&>(state),
0112 static_cast<F&&>(f));
0113 }
0114 };
0115 }}
0116
0117 #endif