Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-30 09:43:40

0001 /*!
0002 @file
0003 Defines `boost::hana::while_`.
0004 
0005 Copyright Louis Dionne 2013-2022
0006 Distributed under the Boost Software License, Version 1.0.
0007 (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
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     //! @cond
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     //! @endcond
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             // Since `pred(state)` returns a `Constant`, we do not actually
0099             // need to call it; we only need its decltype. However, we still
0100             // call it to run potential side effects. I'm not sure whether
0101             // that is desirable, since we pretty much take for granted that
0102             // functions are pure, but we'll do it like this for now. Also, I
0103             // think there is something rather deep hidden behind this, and
0104             // understanding what must be done here should give us a better
0105             // understanding of something non-trivial.
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 }} // end namespace boost::hana
0116 
0117 #endif // !BOOST_HANA_WHILE_HPP