]> git.proxmox.com Git - ceph.git/blame - ceph/src/boost/libs/hana/include/boost/hana/while.hpp
bump version to 12.2.2-pve1
[ceph.git] / ceph / src / boost / libs / hana / include / boost / hana / while.hpp
CommitLineData
7c673cae
FG
1/*!
2@file
3Defines `boost::hana::while_`.
4
5@copyright Louis Dionne 2013-2016
6Distributed 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_WHILE_HPP
11#define BOOST_HANA_WHILE_HPP
12
13#include <boost/hana/fwd/while.hpp>
14
15#include <boost/hana/bool.hpp>
16#include <boost/hana/concept/constant.hpp>
17#include <boost/hana/concept/constant.hpp>
18#include <boost/hana/concept/logical.hpp>
19#include <boost/hana/config.hpp>
20#include <boost/hana/core/to.hpp>
21#include <boost/hana/core/dispatch.hpp>
22#include <boost/hana/detail/canonical_constant.hpp>
23
24#include <type_traits>
25
26
27BOOST_HANA_NAMESPACE_BEGIN
28 //! @cond
29 template <typename Pred, typename State, typename F>
30 constexpr decltype(auto) while_t::operator()(Pred&& pred, State&& state, F&& f) const {
31 using Cond = decltype(pred(state));
32 using Bool = typename hana::tag_of<Cond>::type;
33 using While = BOOST_HANA_DISPATCH_IF(while_impl<Bool>,
34 hana::Logical<Bool>::value
35 );
36
37 #ifndef BOOST_HANA_CONFIG_DISABLE_CONCEPT_CHECKS
38 static_assert(hana::Logical<Bool>::value,
39 "hana::while_(pred, state, f) requires 'pred(state)' to be a Logical");
40 #endif
41
42 return While::apply(static_cast<Pred&&>(pred),
43 static_cast<State&&>(state),
44 static_cast<F&&>(f));
45 }
46 //! @endcond
47
48 template <typename L, bool condition>
49 struct while_impl<L, hana::when<condition>> : hana::default_ {
50 template <typename ...Args>
51 static constexpr auto apply(Args&& ...) = delete;
52 };
53
54 template <typename L>
55 struct while_impl<L, hana::when<std::is_arithmetic<L>::value>> {
56 template <typename Pred, typename State, typename F>
57 static auto apply(Pred&& pred, State&& state, F&& f)
58 -> decltype(
59 true ? f(static_cast<State&&>(state))
60 : static_cast<State&&>(state)
61 )
62 {
63 if (pred(state)) {
64 decltype(auto) r = f(static_cast<State&&>(state));
65 return hana::while_(static_cast<Pred&&>(pred),
66 static_cast<decltype(r)&&>(r),
67 static_cast<F&&>(f));
68 }
69 else {
70 return static_cast<State&&>(state);
71 }
72 }
73 };
74
75 template <typename C>
76 struct while_impl<C, hana::when<
77 hana::Constant<C>::value &&
78 hana::Logical<typename C::value_type>::value
79 >> {
80 template <typename Pred, typename State, typename F>
81 static constexpr State
82 while_helper(hana::false_, Pred&&, State&& state, F&&) {
83 return static_cast<State&&>(state);
84 }
85
86 template <typename Pred, typename State, typename F>
87 static constexpr decltype(auto)
88 while_helper(hana::true_, Pred&& pred, State&& state, F&& f) {
89 decltype(auto) r = f(static_cast<State&&>(state));
90 return hana::while_(static_cast<Pred&&>(pred),
91 static_cast<decltype(r)&&>(r),
92 static_cast<F&&>(f));
93 }
94
95 template <typename Pred, typename State, typename F>
96 static constexpr decltype(auto)
97 apply(Pred&& pred, State&& state, F&& f) {
98 // Since `pred(state)` returns a `Constant`, we do not actually
99 // need to call it; we only need its decltype. However, we still
100 // call it to run potential side effects. I'm not sure whether
101 // that is desirable, since we pretty much take for granted that
102 // functions are pure, but we'll do it like this for now. Also, I
103 // think there is something rather deep hidden behind this, and
104 // understanding what must be done here should give us a better
105 // understanding of something non-trivial.
106 auto cond_ = pred(state);
107 constexpr auto cond = hana::value(cond_);
108 constexpr bool truth_value = hana::if_(cond, true, false);
109 return while_helper(hana::bool_c<truth_value>,
110 static_cast<Pred&&>(pred),
111 static_cast<State&&>(state),
112 static_cast<F&&>(f));
113 }
114 };
115BOOST_HANA_NAMESPACE_END
116
117#endif // !BOOST_HANA_WHILE_HPP