Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-18 09:43:38

0001 // Copyright (c) 2016-2023 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 #include <utility>      // metaprogramming stuff
0014 #include <cstddef>      // std::size_t
0015 
0016 ///////////////////// Tuple that holds its values in the supplied order
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     // We do not use `noexcept` in the following functions, because if user forget to put one then clang will issue an error:
0036     // "error: exception specification of explicitly defaulted default constructor does not match the calculated one".
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     // NOLINTNEXTLINE(clang-analyzer-core.uninitialized.UndefReturn)
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     // NOLINTNEXTLINE(clang-analyzer-core.uninitialized.UndefReturn)
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     // NOLINTNEXTLINE(clang-analyzer-core.uninitialized.UndefReturn)
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     // NOLINTNEXTLINE(clang-analyzer-core.uninitialized.UndefReturn)
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     // NOLINTNEXTLINE(clang-analyzer-core.uninitialized.UndefReturn)
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     // NOLINTNEXTLINE(clang-analyzer-core.uninitialized.UndefReturn)
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     // NOLINTNEXTLINE(clang-analyzer-core.uninitialized.UndefReturn)
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     // NOLINTNEXTLINE(clang-analyzer-core.uninitialized.UndefReturn)
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     // NOLINTNEXTLINE(clang-analyzer-core.uninitialized.UndefReturn)
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     // NOLINTNEXTLINE(clang-analyzer-core.uninitialized.UndefReturn)
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     // NOLINTNEXTLINE(clang-analyzer-core.uninitialized.UndefReturn)
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 }}}} // namespace boost::pfr::detail::sequence_tuple
0177 
0178 #endif // BOOST_PFR_CORE_HPP