Sequoia
Loading...
Searching...
No Matches
MemOrderedTuple.hpp
Go to the documentation of this file.
1
2// Copyright Oliver J. Rosten 2024. //
3// Distributed under the GNU GENERAL PUBLIC LICENSE, Version 3.0. //
4// (See accompanying file LICENSE.md or copy at //
5// https://www.gnu.org/licenses/gpl-3.0.en.html) //
7
8#pragma once
9
12#include <utility>
13
14#ifndef __cpp_pack_indexing
15 #include <tuple>
16#endif
17
18namespace sequoia
19{
20 namespace impl
21 {
22 template<class T, std::size_t I>
24 {
25 constexpr static std::size_t index{I};
26 T value;
27
28 [[nodiscard]]
29 friend auto constexpr operator<=>(const indexed_element&, const indexed_element&) noexcept = default;
30 };
31
32 template<class... Ts>
34
35 template<std::size_t... Is, class... Ts>
36 requires (sizeof...(Is) == sizeof...(Ts))
37 struct mem_ordered_tuple<std::index_sequence<Is...>, Ts...> : indexed_element<Ts, Is>...
38 {
39 constexpr mem_ordered_tuple()
40 requires (std::is_default_constructible_v<Ts> && ...)
42 {}
43
44 constexpr explicit(sizeof...(Ts) == 1) mem_ordered_tuple(const Ts&... ts)
45 requires (sizeof...(Ts) >= 1) && (std::is_copy_constructible_v<Ts> && ...)
46 : indexed_element<Ts, Is>{ts}...
47 {}
48
49 [[nodiscard]]
50 friend auto constexpr operator<=>(const mem_ordered_tuple&, const mem_ordered_tuple&) noexcept = default;
51 };
52 }
53
54 template<std::size_t I, class T>
56
57 template<std::size_t I, class T>
58 using mem_ordered_tuple_element_t = mem_ordered_tuple_element<I, T>::type;
59
60 template<class... Ts>
61 struct mem_ordered_tuple : private impl::mem_ordered_tuple<std::make_index_sequence<sizeof...(Ts)>, Ts...>
62 {
63 constexpr mem_ordered_tuple() requires (std::is_default_constructible_v<Ts> && ...) = default;
64
65 constexpr explicit(!(std::convertible_to<const Ts&, Ts> && ...)) mem_ordered_tuple(const Ts&... ts)
66 requires (sizeof...(Ts) >= 1) && (std::is_copy_constructible_v<Ts> && ...)
67 : impl::mem_ordered_tuple<std::make_index_sequence<sizeof...(Ts)>, Ts...>{ts...}
68 {}
69
70 [[nodiscard]]
71 friend auto constexpr operator<=>(const mem_ordered_tuple&, const mem_ordered_tuple&) noexcept = default;
72 private:
73 template<std::size_t I, class... Us>
74 friend constexpr mem_ordered_tuple_element_t<I, mem_ordered_tuple<Us...>>& get(mem_ordered_tuple<Us...>&) noexcept;
75
76 template<std::size_t I, class... Us>
77 friend constexpr mem_ordered_tuple_element_t<I, mem_ordered_tuple<Us...>> const& get(mem_ordered_tuple<Us...> const&) noexcept;
78
79 template<std::size_t I, class... Us>
80 friend constexpr mem_ordered_tuple_element_t<I, mem_ordered_tuple<Us...>>&& get(mem_ordered_tuple<Us...>&&) noexcept;
81
82 template<std::size_t I, class... Us>
83 friend constexpr mem_ordered_tuple_element_t<I, mem_ordered_tuple<Us...>> const&& get(mem_ordered_tuple<Us...> const&&) noexcept;
84 };
85
86 template<std::size_t I, class... Ts>
88 {
89 #ifdef __cpp_pack_indexing
90 using type = Ts...[I];
91 #else
92 using type = std::tuple_element_t<I, std::tuple<Ts...>>;
93 #endif
94 };
95
96 // TO DO: restore direct use of pack-indexing, once MSVC supports it
97 template<std::size_t I, class... Ts>
98 [[nodiscard]]
99 constexpr mem_ordered_tuple_element_t<I, mem_ordered_tuple<Ts...>>& get(mem_ordered_tuple<Ts...>& t) noexcept {
100 return static_cast<impl::indexed_element<mem_ordered_tuple_element_t<I, mem_ordered_tuple<Ts...>>, I>&>(t).value;
101 }
102
103 template<std::size_t I, class... Ts>
104 [[nodiscard]]
105 constexpr const mem_ordered_tuple_element_t<I, mem_ordered_tuple<Ts...>>& get(const mem_ordered_tuple<Ts...>& t) noexcept {
106 return static_cast<const impl::indexed_element<mem_ordered_tuple_element_t<I, mem_ordered_tuple<Ts...>>, I>&>(t).value;
107 }
108
109 template<std::size_t I, class... Ts>
110 [[nodiscard]]
111 constexpr mem_ordered_tuple_element_t<I, mem_ordered_tuple<Ts...>>&& get(mem_ordered_tuple<Ts...>&& t) noexcept {
112 return static_cast<impl::indexed_element<mem_ordered_tuple_element_t<I, mem_ordered_tuple<Ts...>>, I>&&>(t).value;
113 }
114
115 template<std::size_t I, class... Ts>
116 [[nodiscard]]
117 constexpr const mem_ordered_tuple_element_t<I, mem_ordered_tuple<Ts...>>&& get(const mem_ordered_tuple<Ts...>&& t) noexcept {
118 return static_cast<const impl::indexed_element<mem_ordered_tuple_element_t<I, mem_ordered_tuple<Ts...>>, I>&&>(t).value;
119 }
120}
Definition: MemOrderedTuple.hpp:24
Definition: MemOrderedTuple.hpp:33
Definition: MemOrderedTuple.hpp:55
Definition: MemOrderedTuple.hpp:62