Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2026-08-06 09:04:50

0001 // Copyright (c) 2016-2025 Antony Polukhin
0002 //
0003 // Distributed under the Boost Software License, Version 1.0. (See accompanying
0004 // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
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 ///////////////////// Tuple that holds its values in the supplied order
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     // We do not use `noexcept` in the following functions, because if user forget to put one then clang will issue an error:
0038     // "error: exception specification of explicitly defaulted default constructor does not match the calculated one".
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     // NOLINTNEXTLINE(clang-analyzer-core.uninitialized.UndefReturn,clang-analyzer-core.CallAndMessage)
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     // NOLINTNEXTLINE(clang-analyzer-core.uninitialized.UndefReturn,clang-analyzer-core.CallAndMessage)
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     // NOLINTNEXTLINE(clang-analyzer-core.uninitialized.UndefReturn,clang-analyzer-core.CallAndMessage)
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     // NOLINTNEXTLINE(clang-analyzer-core.uninitialized.UndefReturn,clang-analyzer-core.CallAndMessage)
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     // NOLINTNEXTLINE(clang-analyzer-core.uninitialized.UndefReturn,clang-analyzer-core.CallAndMessage)
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     // NOLINTNEXTLINE(clang-analyzer-core.uninitialized.UndefReturn,clang-analyzer-core.CallAndMessage)
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     // NOLINTNEXTLINE(clang-analyzer-core.uninitialized.UndefReturn,clang-analyzer-core.CallAndMessage)
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     // NOLINTNEXTLINE(clang-analyzer-core.uninitialized.UndefReturn,clang-analyzer-core.CallAndMessage)
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     // NOLINTNEXTLINE(clang-analyzer-core.uninitialized.UndefReturn,clang-analyzer-core.CallAndMessage)
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     // NOLINTNEXTLINE(clang-analyzer-core.uninitialized.UndefReturn,clang-analyzer-core.CallAndMessage)
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     // NOLINTNEXTLINE(clang-analyzer-core.uninitialized.UndefReturn,clang-analyzer-core.CallAndMessage)
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 }}}} // namespace boost::pfr::detail::sequence_tuple
0179 
0180 #endif // BOOST_PFR_CORE_HPP