]> git.proxmox.com Git - ceph.git/blame - 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
CommitLineData
b32b8144 1// Copyright Louis Dionne 2013-2017
7c673cae
FG
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>
b32b8144 15#include <functional>
7c673cae
FG
16namespace hana = boost::hana;
17
18
b32b8144
FG
19// A tuple that holds reference_wrappers to its elements, instead of the
20// elements themselves.
21
7c673cae
FG
22struct RefTuple { };
23
24template <typename ...T>
b32b8144
FG
25struct ref_tuple;
26
27template <typename ...T>
28struct ref_tuple<T&...> {
29 hana::tuple<std::reference_wrapper<T>...> storage_;
7c673cae
FG
30};
31
32
33namespace 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>
b32b8144
FG
42 static constexpr auto apply(T& ...t) {
43 return ref_tuple<T&...>{{std::ref(t)...}};
7c673cae
FG
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) {
b32b8144 51 return hana::at(static_cast<Xs&&>(xs).storage_, n).get();
7c673cae
FG
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...>) {
b32b8144 67 return hana::make<RefTuple>(hana::at_c<n + i>(xs.storage_).get()...);
7c673cae
FG
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 };
b32b8144 77}} // end namespace boost::hana
7c673cae
FG
78
79
80int main() {
81 int i = 0, j = 1, k = 2;
82
b32b8144 83 ref_tuple<int&, int&, int&> refs = hana::make<RefTuple>(i, j, k);
7c673cae
FG
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}