]> git.proxmox.com Git - ceph.git/blob - ceph/src/boost/libs/hana/example/misc/ref_tuple.cpp
update sources to v12.2.3
[ceph.git] / ceph / src / boost / libs / hana / example / misc / ref_tuple.cpp
1 // Copyright Louis Dionne 2013-2017
2 // Distributed under the Boost Software License, Version 1.0.
3 // (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
4
5 #include <boost/hana/assert.hpp>
6 #include <boost/hana/at.hpp>
7 #include <boost/hana/core/make.hpp>
8 #include <boost/hana/core/tag_of.hpp>
9 #include <boost/hana/drop_front.hpp>
10 #include <boost/hana/is_empty.hpp>
11 #include <boost/hana/not.hpp>
12 #include <boost/hana/tuple.hpp>
13
14 #include <cstddef>
15 #include <functional>
16 namespace hana = boost::hana;
17
18
19 // A tuple that holds reference_wrappers to its elements, instead of the
20 // elements themselves.
21
22 struct RefTuple { };
23
24 template <typename ...T>
25 struct ref_tuple;
26
27 template <typename ...T>
28 struct ref_tuple<T&...> {
29 hana::tuple<std::reference_wrapper<T>...> storage_;
30 };
31
32
33 namespace boost { namespace hana {
34 template <typename ...T>
35 struct tag_of<ref_tuple<T...>> {
36 using type = RefTuple;
37 };
38
39 template <>
40 struct make_impl<RefTuple> {
41 template <typename ...T>
42 static constexpr auto apply(T& ...t) {
43 return ref_tuple<T&...>{{std::ref(t)...}};
44 }
45 };
46
47 template <>
48 struct at_impl<RefTuple> {
49 template <typename Xs, typename N>
50 static constexpr decltype(auto) apply(Xs&& xs, N const& n) {
51 return hana::at(static_cast<Xs&&>(xs).storage_, n).get();
52 }
53 };
54
55 template <>
56 struct is_empty_impl<RefTuple> {
57 template <typename Xs>
58 static constexpr auto apply(Xs const& xs) {
59 return hana::is_empty(xs.storage_);
60 }
61 };
62
63 template <>
64 struct drop_front_impl<RefTuple> {
65 template <std::size_t n, typename T, typename ...U, std::size_t ...i>
66 static constexpr auto helper(ref_tuple<T, U...> xs, std::index_sequence<i...>) {
67 return hana::make<RefTuple>(hana::at_c<n + i>(xs.storage_).get()...);
68 }
69
70 template <typename ...T, typename N>
71 static constexpr auto apply(ref_tuple<T...> xs, N const&) {
72 return helper<N::value>(xs, std::make_index_sequence<(
73 N::value < sizeof...(T) ? sizeof...(T) - N::value : 0
74 )>{});
75 }
76 };
77 }} // end namespace boost::hana
78
79
80 int main() {
81 int i = 0, j = 1, k = 2;
82
83 ref_tuple<int&, int&, int&> refs = hana::make<RefTuple>(i, j, k);
84 hana::at_c<0>(refs) = 3;
85 BOOST_HANA_RUNTIME_CHECK(i == 3);
86
87 BOOST_HANA_CONSTANT_CHECK(hana::not_(hana::is_empty(refs)));
88
89 ref_tuple<int&, int&> tail = hana::drop_front(refs);
90 hana::at_c<0>(tail) = 4;
91 BOOST_HANA_RUNTIME_CHECK(j == 4);
92 }