Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-09-15 08:44:22

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