]> git.proxmox.com Git - ceph.git/blob - ceph/src/boost/boost/pfr/detail/make_flat_tuple_of_references.hpp
import quincy beta 17.1.0
[ceph.git] / ceph / src / boost / boost / pfr / detail / make_flat_tuple_of_references.hpp
1 // Copyright (c) 2016-2020 Antony Polukhin
2 //
3 // Distributed under the Boost Software License, Version 1.0. (See accompanying
4 // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
5
6 #ifndef BOOST_PFR_DETAIL_MAKE_FLAT_TUPLE_OF_REFERENCES_HPP
7 #define BOOST_PFR_DETAIL_MAKE_FLAT_TUPLE_OF_REFERENCES_HPP
8 #pragma once
9
10 #include <boost/pfr/detail/config.hpp>
11
12 #include <utility> // metaprogramming stuff
13 #include <boost/pfr/detail/sequence_tuple.hpp>
14 #include <boost/pfr/detail/rvalue_t.hpp>
15 #include <boost/pfr/detail/make_integer_sequence.hpp>
16
17
18 namespace boost { namespace pfr { namespace detail {
19
20 template <std::size_t Index>
21 using size_t_ = std::integral_constant<std::size_t, Index >;
22
23 // Helper: Make a "getter" object corresponding to built-in tuple::get
24 // For user-defined structures, the getter should be "offset_based_getter"
25 struct sequence_tuple_getter {
26 template <std::size_t idx, typename TupleOfReferences>
27 decltype(auto) get(TupleOfReferences&& t, size_t_<idx>) const noexcept {
28 return sequence_tuple::get<idx>(std::forward<TupleOfReferences>(t));
29 }
30 };
31
32
33 template <class TupleOrUserType, class Getter, std::size_t Begin, std::size_t Size>
34 constexpr auto make_flat_tuple_of_references(TupleOrUserType&, const Getter&, size_t_<Begin>, size_t_<Size>) noexcept;
35
36 template <class TupleOrUserType, class Getter, std::size_t Begin>
37 constexpr sequence_tuple::tuple<> make_flat_tuple_of_references(TupleOrUserType&, const Getter&, size_t_<Begin>, size_t_<0>) noexcept;
38
39 template <class TupleOrUserType, class Getter, std::size_t Begin>
40 constexpr auto make_flat_tuple_of_references(TupleOrUserType&, const Getter&, size_t_<Begin>, size_t_<1>) noexcept;
41
42 template <class... T>
43 constexpr auto tie_as_tuple_with_references(T&... args) noexcept {
44 return sequence_tuple::tuple<T&...>{ args... };
45 }
46
47 template <class... T>
48 constexpr decltype(auto) tie_as_tuple_with_references(detail::sequence_tuple::tuple<T...>& t) noexcept {
49 return detail::make_flat_tuple_of_references(t, sequence_tuple_getter{}, size_t_<0>{}, size_t_<sequence_tuple::tuple<T...>::size_v>{});
50 }
51
52 template <class... T>
53 constexpr decltype(auto) tie_as_tuple_with_references(const detail::sequence_tuple::tuple<T...>& t) noexcept {
54 return detail::make_flat_tuple_of_references(t, sequence_tuple_getter{}, size_t_<0>{}, size_t_<sequence_tuple::tuple<T...>::size_v>{});
55 }
56
57 template <class Tuple1, std::size_t... I1, class Tuple2, std::size_t... I2>
58 constexpr auto my_tuple_cat_impl(const Tuple1& t1, std::index_sequence<I1...>, const Tuple2& t2, std::index_sequence<I2...>) noexcept {
59 return detail::tie_as_tuple_with_references(
60 sequence_tuple::get<I1>(t1)...,
61 sequence_tuple::get<I2>(t2)...
62 );
63 }
64
65 template <class Tuple1, class Tuple2>
66 constexpr auto my_tuple_cat(const Tuple1& t1, const Tuple2& t2) noexcept {
67 return detail::my_tuple_cat_impl(
68 t1, detail::make_index_sequence< Tuple1::size_v >{},
69 t2, detail::make_index_sequence< Tuple2::size_v >{}
70 );
71 }
72
73 template <class TupleOrUserType, class Getter, std::size_t Begin, std::size_t Size>
74 constexpr auto make_flat_tuple_of_references(TupleOrUserType& t, const Getter& g, size_t_<Begin>, size_t_<Size>) noexcept {
75 constexpr std::size_t next_size = Size / 2;
76 return detail::my_tuple_cat(
77 detail::make_flat_tuple_of_references(t, g, size_t_<Begin>{}, size_t_<next_size>{}),
78 detail::make_flat_tuple_of_references(t, g, size_t_<Begin + Size / 2>{}, size_t_<Size - next_size>{})
79 );
80 }
81
82 template <class TupleOrUserType, class Getter, std::size_t Begin>
83 constexpr sequence_tuple::tuple<> make_flat_tuple_of_references(TupleOrUserType&, const Getter&, size_t_<Begin>, size_t_<0>) noexcept {
84 return {};
85 }
86
87 template <class TupleOrUserType, class Getter, std::size_t Begin>
88 constexpr auto make_flat_tuple_of_references(TupleOrUserType& t, const Getter& g, size_t_<Begin>, size_t_<1>) noexcept {
89 return detail::tie_as_tuple_with_references(
90 g.get(t, size_t_<Begin>{})
91 );
92 }
93
94 }}} // namespace boost::pfr::detail
95
96 #endif // BOOST_PFR_DETAIL_MAKE_FLAT_TUPLE_OF_REFERENCES_HPP