]> git.proxmox.com Git - ceph.git/blob - ceph/src/boost/libs/hana/include/boost/hana/slice.hpp
bump version to 12.2.2-pve1
[ceph.git] / ceph / src / boost / libs / hana / include / boost / hana / slice.hpp
1 /*!
2 @file
3 Defines `boost::hana::slice` and `boost::hana::slice_c`.
4
5 @copyright Louis Dionne 2013-2016
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_SLICE_HPP
11 #define BOOST_HANA_SLICE_HPP
12
13 #include <boost/hana/fwd/slice.hpp>
14
15 #include <boost/hana/at.hpp>
16 #include <boost/hana/concept/foldable.hpp>
17 #include <boost/hana/concept/sequence.hpp>
18 #include <boost/hana/config.hpp>
19 #include <boost/hana/core/dispatch.hpp>
20 #include <boost/hana/core/make.hpp>
21 #include <boost/hana/range.hpp>
22 #include <boost/hana/unpack.hpp>
23
24 #include <cstddef>
25 #include <utility>
26
27
28 BOOST_HANA_NAMESPACE_BEGIN
29 //! @cond
30 template <typename Xs, typename Indices>
31 constexpr auto slice_t::operator()(Xs&& xs, Indices&& indices) const {
32 using S = typename hana::tag_of<Xs>::type;
33 using Slice = BOOST_HANA_DISPATCH_IF(slice_impl<S>,
34 hana::Sequence<S>::value &&
35 hana::Foldable<Indices>::value
36 );
37
38 #ifndef BOOST_HANA_CONFIG_DISABLE_CONCEPT_CHECKS
39 static_assert(hana::Sequence<S>::value,
40 "hana::slice(xs, indices) requires 'xs' to be a Sequence");
41
42 static_assert(hana::Foldable<Indices>::value,
43 "hana::slice(xs, indices) requires 'indices' to be Foldable");
44 #endif
45
46 return Slice::apply(static_cast<Xs&&>(xs), static_cast<Indices&&>(indices));
47 }
48 //! @endcond
49
50 namespace detail {
51 template <typename Xs>
52 struct take_arbitrary {
53 Xs& xs;
54 using S = typename hana::tag_of<Xs>::type;
55
56 template <typename ...N>
57 constexpr auto operator()(N const& ...) const {
58 return hana::make<S>(hana::at_c<N::value>(xs)...);
59 }
60 };
61 }
62
63 template <typename S, bool condition>
64 struct slice_impl<S, when<condition>> : default_ {
65 template <std::size_t from, typename Xs, std::size_t ...i>
66 static constexpr auto from_offset(Xs&& xs, std::index_sequence<i...>) {
67 return hana::make<S>(hana::at_c<from + i>(static_cast<Xs&&>(xs))...);
68 }
69
70 template <typename Xs, typename T, T from, T to>
71 static constexpr auto apply(Xs&& xs, hana::range<T, from, to> const&) {
72 return slice_impl::from_offset<from>(
73 static_cast<Xs&&>(xs), std::make_index_sequence<to - from>{}
74 );
75 }
76
77 //! @todo
78 //! Since we have the right to specify the same index more than once,
79 //! we can't move from the elements of the source sequence even if it
80 //! is a temporary object: we could end up double-moving. Perhaps it
81 //! would be possible to determine the indices from which we can move
82 //! without incurring a too large compile-time penalty?
83 template <typename Xs, typename Indices>
84 static constexpr auto apply(Xs const& xs, Indices const& indices) {
85 return hana::unpack(indices, detail::take_arbitrary<Xs const>{xs});
86 }
87 };
88
89 template <std::size_t from, std::size_t to>
90 struct slice_c_t {
91 template <typename Xs>
92 constexpr auto operator()(Xs&& xs) const {
93 return hana::slice(static_cast<Xs&&>(xs),
94 hana::range_c<std::size_t, from, to>);
95 }
96 };
97 BOOST_HANA_NAMESPACE_END
98
99 #endif // !BOOST_HANA_SLICE_HPP