File indexing completed on 2026-08-06 09:04:50
0001
0002
0003
0004
0005
0006 #ifndef BOOST_PFR_DETAIL_SEQUENCE_TUPLE_HPP
0007 #define BOOST_PFR_DETAIL_SEQUENCE_TUPLE_HPP
0008 #pragma once
0009
0010 #include <boost/pfr/detail/config.hpp>
0011 #include <boost/pfr/detail/make_integer_sequence.hpp>
0012
0013 #if !defined(BOOST_PFR_INTERFACE_UNIT)
0014 #include <utility> // metaprogramming stuff
0015 #include <cstddef> // std::size_t
0016 #endif
0017
0018
0019 namespace boost { namespace pfr { namespace detail { namespace sequence_tuple {
0020
0021 template <std::size_t N, class T>
0022 struct base_from_member {
0023 T value;
0024 };
0025
0026 template <class I, class ...Tail>
0027 struct tuple_base;
0028
0029
0030
0031 template <std::size_t... I, class ...Tail>
0032 struct tuple_base< std::index_sequence<I...>, Tail... >
0033 : base_from_member<I , Tail>...
0034 {
0035 static constexpr std::size_t size_v = sizeof...(I);
0036
0037
0038
0039 constexpr tuple_base() = default;
0040 constexpr tuple_base(tuple_base&&) = default;
0041 constexpr tuple_base(const tuple_base&) = default;
0042
0043 constexpr tuple_base(Tail... v) noexcept
0044 : base_from_member<I, Tail>{ v }...
0045 {}
0046 };
0047
0048 template <>
0049 struct tuple_base<std::index_sequence<> > {
0050 static constexpr std::size_t size_v = 0;
0051 };
0052
0053 template <std::size_t N, class T>
0054 constexpr T& get_impl(base_from_member<N, T>& t) noexcept {
0055
0056 return t.value;
0057 }
0058
0059 template <std::size_t N, class T>
0060 constexpr const T& get_impl(const base_from_member<N, T>& t) noexcept {
0061
0062 return t.value;
0063 }
0064
0065 template <std::size_t N, class T>
0066 constexpr volatile T& get_impl(volatile base_from_member<N, T>& t) noexcept {
0067
0068 return t.value;
0069 }
0070
0071 template <std::size_t N, class T>
0072 constexpr const volatile T& get_impl(const volatile base_from_member<N, T>& t) noexcept {
0073
0074 return t.value;
0075 }
0076
0077 template <std::size_t N, class T>
0078 constexpr T&& get_impl(base_from_member<N, T>&& t) noexcept {
0079
0080 return std::forward<T>(t.value);
0081 }
0082
0083
0084 template <class T, std::size_t N>
0085 constexpr T& get_by_type_impl(base_from_member<N, T>& t) noexcept {
0086
0087 return t.value;
0088 }
0089
0090 template <class T, std::size_t N>
0091 constexpr const T& get_by_type_impl(const base_from_member<N, T>& t) noexcept {
0092
0093 return t.value;
0094 }
0095
0096 template <class T, std::size_t N>
0097 constexpr volatile T& get_by_type_impl(volatile base_from_member<N, T>& t) noexcept {
0098
0099 return t.value;
0100 }
0101
0102 template <class T, std::size_t N>
0103 constexpr const volatile T& get_by_type_impl(const volatile base_from_member<N, T>& t) noexcept {
0104
0105 return t.value;
0106 }
0107
0108 template <class T, std::size_t N>
0109 constexpr T&& get_by_type_impl(base_from_member<N, T>&& t) noexcept {
0110
0111 return std::forward<T>(t.value);
0112 }
0113
0114 template <class T, std::size_t N>
0115 constexpr const T&& get_by_type_impl(const base_from_member<N, T>&& t) noexcept {
0116
0117 return std::forward<T>(t.value);
0118 }
0119
0120
0121
0122
0123 template <class ...Values>
0124 struct tuple: tuple_base<
0125 detail::index_sequence_for<Values...>,
0126 Values...>
0127 {
0128 using tuple_base<
0129 detail::index_sequence_for<Values...>,
0130 Values...
0131 >::tuple_base;
0132
0133 constexpr static std::size_t size() noexcept { return sizeof...(Values); }
0134 constexpr static bool empty() noexcept { return size() == 0; }
0135 };
0136
0137
0138 template <std::size_t N, class ...T>
0139 constexpr decltype(auto) get(tuple<T...>& t) noexcept {
0140 static_assert(N < tuple<T...>::size_v, "====================> Boost.PFR: Tuple index out of bounds");
0141 return sequence_tuple::get_impl<N>(t);
0142 }
0143
0144 template <std::size_t N, class ...T>
0145 constexpr decltype(auto) get(const tuple<T...>& t) noexcept {
0146 static_assert(N < tuple<T...>::size_v, "====================> Boost.PFR: Tuple index out of bounds");
0147 return sequence_tuple::get_impl<N>(t);
0148 }
0149
0150 template <std::size_t N, class ...T>
0151 constexpr decltype(auto) get(const volatile tuple<T...>& t) noexcept {
0152 static_assert(N < tuple<T...>::size_v, "====================> Boost.PFR: Tuple index out of bounds");
0153 return sequence_tuple::get_impl<N>(t);
0154 }
0155
0156 template <std::size_t N, class ...T>
0157 constexpr decltype(auto) get(volatile tuple<T...>& t) noexcept {
0158 static_assert(N < tuple<T...>::size_v, "====================> Boost.PFR: Tuple index out of bounds");
0159 return sequence_tuple::get_impl<N>(t);
0160 }
0161
0162 template <std::size_t N, class ...T>
0163 constexpr decltype(auto) get(tuple<T...>&& t) noexcept {
0164 static_assert(N < tuple<T...>::size_v, "====================> Boost.PFR: Tuple index out of bounds");
0165 return sequence_tuple::get_impl<N>(std::move(t));
0166 }
0167
0168 template <std::size_t I, class T>
0169 using tuple_element = std::remove_reference< decltype(
0170 ::boost::pfr::detail::sequence_tuple::get<I>( std::declval<T>() )
0171 ) >;
0172
0173 template <class... Args>
0174 constexpr auto make_sequence_tuple(Args... args) noexcept {
0175 return ::boost::pfr::detail::sequence_tuple::tuple<Args...>{ args... };
0176 }
0177
0178 }}}}
0179
0180 #endif