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