123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127 |
- // Copyright (c) 2016-2021 Antony Polukhin
- //
- // Distributed under the Boost Software License, Version 1.0. (See accompanying
- // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
- #ifndef BOOST_PFR_DETAIL_SEQUENCE_TUPLE_HPP
- #define BOOST_PFR_DETAIL_SEQUENCE_TUPLE_HPP
- #pragma once
- #include <boost/pfr/detail/config.hpp>
- #include <boost/pfr/detail/make_integer_sequence.hpp>
- #include <utility> // metaprogramming stuff
- #include <cstddef> // std::size_t
- ///////////////////// Tuple that holds its values in the supplied order
- namespace boost { namespace pfr { namespace detail { namespace sequence_tuple {
- template <std::size_t N, class T>
- struct base_from_member {
- T value;
- };
- template <class I, class ...Tail>
- struct tuple_base;
- template <std::size_t... I, class ...Tail>
- struct tuple_base< std::index_sequence<I...>, Tail... >
- : base_from_member<I , Tail>...
- {
- static constexpr std::size_t size_v = sizeof...(I);
- // We do not use `noexcept` in the following functions, because if user forget to put one then clang will issue an error:
- // "error: exception specification of explicitly defaulted default constructor does not match the calculated one".
- constexpr tuple_base() = default;
- constexpr tuple_base(tuple_base&&) = default;
- constexpr tuple_base(const tuple_base&) = default;
- constexpr tuple_base(Tail... v) noexcept
- : base_from_member<I, Tail>{ v }...
- {}
- };
- template <>
- struct tuple_base<std::index_sequence<> > {
- static constexpr std::size_t size_v = 0;
- };
- template <std::size_t N, class T>
- constexpr T& get_impl(base_from_member<N, T>& t) noexcept {
- return t.value;
- }
- template <std::size_t N, class T>
- constexpr const T& get_impl(const base_from_member<N, T>& t) noexcept {
- return t.value;
- }
- template <std::size_t N, class T>
- constexpr volatile T& get_impl(volatile base_from_member<N, T>& t) noexcept {
- return t.value;
- }
- template <std::size_t N, class T>
- constexpr const volatile T& get_impl(const volatile base_from_member<N, T>& t) noexcept {
- return t.value;
- }
- template <std::size_t N, class T>
- constexpr T&& get_impl(base_from_member<N, T>&& t) noexcept {
- return std::forward<T>(t.value);
- }
- template <class ...Values>
- struct tuple: tuple_base<
- detail::index_sequence_for<Values...>,
- Values...>
- {
- using tuple_base<
- detail::index_sequence_for<Values...>,
- Values...
- >::tuple_base;
- };
- template <std::size_t N, class ...T>
- constexpr decltype(auto) get(tuple<T...>& t) noexcept {
- static_assert(N < tuple<T...>::size_v, "====================> Boost.PFR: Tuple index out of bounds");
- return sequence_tuple::get_impl<N>(t);
- }
- template <std::size_t N, class ...T>
- constexpr decltype(auto) get(const tuple<T...>& t) noexcept {
- static_assert(N < tuple<T...>::size_v, "====================> Boost.PFR: Tuple index out of bounds");
- return sequence_tuple::get_impl<N>(t);
- }
- template <std::size_t N, class ...T>
- constexpr decltype(auto) get(const volatile tuple<T...>& t) noexcept {
- static_assert(N < tuple<T...>::size_v, "====================> Boost.PFR: Tuple index out of bounds");
- return sequence_tuple::get_impl<N>(t);
- }
- template <std::size_t N, class ...T>
- constexpr decltype(auto) get(volatile tuple<T...>& t) noexcept {
- static_assert(N < tuple<T...>::size_v, "====================> Boost.PFR: Tuple index out of bounds");
- return sequence_tuple::get_impl<N>(t);
- }
- template <std::size_t N, class ...T>
- constexpr decltype(auto) get(tuple<T...>&& t) noexcept {
- static_assert(N < tuple<T...>::size_v, "====================> Boost.PFR: Tuple index out of bounds");
- return sequence_tuple::get_impl<N>(std::move(t));
- }
- template <std::size_t I, class T>
- using tuple_element = std::remove_reference< decltype(
- ::boost::pfr::detail::sequence_tuple::get<I>( std::declval<T>() )
- ) >;
- }}}} // namespace boost::pfr::detail::sequence_tuple
- #endif // BOOST_PFR_CORE_HPP
|