]> git.proxmox.com Git - ceph.git/blob - ceph/src/boost/boost/pfr/detail/sequence_tuple.hpp
update ceph source to reef 18.1.2
[ceph.git] / ceph / src / boost / boost / pfr / detail / sequence_tuple.hpp
1 // Copyright (c) 2016-2022 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_SEQUENCE_TUPLE_HPP
7 #define BOOST_PFR_DETAIL_SEQUENCE_TUPLE_HPP
8 #pragma once
9
10 #include <boost/pfr/detail/config.hpp>
11 #include <boost/pfr/detail/make_integer_sequence.hpp>
12
13 #include <utility> // metaprogramming stuff
14 #include <cstddef> // std::size_t
15
16 ///////////////////// Tuple that holds its values in the supplied order
17 namespace boost { namespace pfr { namespace detail { namespace sequence_tuple {
18
19 template <std::size_t N, class T>
20 struct base_from_member {
21 T value;
22 };
23
24 template <class I, class ...Tail>
25 struct tuple_base;
26
27
28
29 template <std::size_t... I, class ...Tail>
30 struct tuple_base< std::index_sequence<I...>, Tail... >
31 : base_from_member<I , Tail>...
32 {
33 static constexpr std::size_t size_v = sizeof...(I);
34
35 // We do not use `noexcept` in the following functions, because if user forget to put one then clang will issue an error:
36 // "error: exception specification of explicitly defaulted default constructor does not match the calculated one".
37 constexpr tuple_base() = default;
38 constexpr tuple_base(tuple_base&&) = default;
39 constexpr tuple_base(const tuple_base&) = default;
40
41 constexpr tuple_base(Tail... v) noexcept
42 : base_from_member<I, Tail>{ v }...
43 {}
44 };
45
46 template <>
47 struct tuple_base<std::index_sequence<> > {
48 static constexpr std::size_t size_v = 0;
49 };
50
51 template <std::size_t N, class T>
52 constexpr T& get_impl(base_from_member<N, T>& t) noexcept {
53 return t.value;
54 }
55
56 template <std::size_t N, class T>
57 constexpr const T& get_impl(const base_from_member<N, T>& t) noexcept {
58 return t.value;
59 }
60
61 template <std::size_t N, class T>
62 constexpr volatile T& get_impl(volatile base_from_member<N, T>& t) noexcept {
63 return t.value;
64 }
65
66 template <std::size_t N, class T>
67 constexpr const volatile T& get_impl(const volatile base_from_member<N, T>& t) noexcept {
68 return t.value;
69 }
70
71 template <std::size_t N, class T>
72 constexpr T&& get_impl(base_from_member<N, T>&& t) noexcept {
73 return std::forward<T>(t.value);
74 }
75
76
77 template <class ...Values>
78 struct tuple: tuple_base<
79 detail::index_sequence_for<Values...>,
80 Values...>
81 {
82 using tuple_base<
83 detail::index_sequence_for<Values...>,
84 Values...
85 >::tuple_base;
86 };
87
88
89 template <std::size_t N, class ...T>
90 constexpr decltype(auto) get(tuple<T...>& t) noexcept {
91 static_assert(N < tuple<T...>::size_v, "====================> Boost.PFR: Tuple index out of bounds");
92 return sequence_tuple::get_impl<N>(t);
93 }
94
95 template <std::size_t N, class ...T>
96 constexpr decltype(auto) get(const tuple<T...>& t) noexcept {
97 static_assert(N < tuple<T...>::size_v, "====================> Boost.PFR: Tuple index out of bounds");
98 return sequence_tuple::get_impl<N>(t);
99 }
100
101 template <std::size_t N, class ...T>
102 constexpr decltype(auto) get(const volatile tuple<T...>& t) noexcept {
103 static_assert(N < tuple<T...>::size_v, "====================> Boost.PFR: Tuple index out of bounds");
104 return sequence_tuple::get_impl<N>(t);
105 }
106
107 template <std::size_t N, class ...T>
108 constexpr decltype(auto) get(volatile tuple<T...>& t) noexcept {
109 static_assert(N < tuple<T...>::size_v, "====================> Boost.PFR: Tuple index out of bounds");
110 return sequence_tuple::get_impl<N>(t);
111 }
112
113 template <std::size_t N, class ...T>
114 constexpr decltype(auto) get(tuple<T...>&& t) noexcept {
115 static_assert(N < tuple<T...>::size_v, "====================> Boost.PFR: Tuple index out of bounds");
116 return sequence_tuple::get_impl<N>(std::move(t));
117 }
118
119 template <std::size_t I, class T>
120 using tuple_element = std::remove_reference< decltype(
121 ::boost::pfr::detail::sequence_tuple::get<I>( std::declval<T>() )
122 ) >;
123
124
125 }}}} // namespace boost::pfr::detail::sequence_tuple
126
127 #endif // BOOST_PFR_CORE_HPP