di 0.1.0
Loading...
Searching...
No Matches
span_fixed_size.h
Go to the documentation of this file.
1#pragma once
2
18#include "di/meta/compare.h"
19#include "di/meta/constexpr.h"
20#include "di/meta/core.h"
21#include "di/meta/language.h"
22#include "di/meta/operations.h"
23#include "di/meta/vocab.h"
24#include "di/types/size_t.h"
27#include "di/util/to_address.h"
34
35namespace di::vocab {
36template<typename T, types::size_t extent>
37struct Array;
38
39template<typename T, types::size_t extent>
40requires(extent != dynamic_extent)
42 : public meta::EnableView<Span<T, extent>>
43 , public meta::EnableBorrowedContainer<Span<T, extent>>
44 , public util::AddMemberGet<Span<T, extent>> {
45public:
46 using Element = T;
47
48 constexpr explicit Span()
49 requires(extent == 0)
50 = default;
51
52 template<concepts::ContiguousIterator Iter>
54 constexpr explicit Span(Iter first, types::size_t count) : m_data(util::to_address(first)) {
55 DI_ASSERT(count == extent);
56 }
57
58 template<concepts::ContiguousIterator Iter, concepts::SizedSentinelFor<Iter> Sent>
61 constexpr explicit Span(Iter it, Sent sent) : m_data(util::to_address(it)) {
62 DI_ASSERT(sent - it == extent);
63 }
64
65 template<types::size_t size>
66 requires(size == extent)
67 constexpr Span(T (&array)[size]) : m_data(array) {}
68
69 template<concepts::QualificationConvertibleTo<T> U, types::size_t size>
70 requires(size == extent)
71 constexpr Span(vocab::Array<U, size>& array) : m_data(array.data()) {}
72
73 template<typename U, types::size_t size>
75 constexpr Span(vocab::Array<U, size> const& array) : m_data(array.data()) {}
76
77 template<concepts::ContiguousContainer Con>
81 constexpr explicit Span(Con&& container) : m_data(container::data(container)) {
83 }
84
85 template<concepts::QualificationConvertibleTo<T> U, types::size_t other_extent>
86 requires((other_extent == dynamic_extent || extent == other_extent))
87 constexpr explicit(other_extent == dynamic_extent) Span(Span<U, other_extent> const& other) : m_data(other.data()) {
88 DI_ASSERT(other.size() == extent);
89 }
90
91 constexpr Span(Span const&) = default;
92
93 constexpr auto operator=(Span const&) -> Span& = default;
94
95 constexpr auto begin() const -> T* { return data(); }
96 constexpr auto end() const -> T* { return data() + extent; }
97
98 constexpr auto front() const -> T&
99 requires(extent > 0)
100 {
101 return *data();
102 }
103
104 constexpr auto back() const -> T&
105 requires(extent > 0)
106 {
107 return *(end() - 1);
108 }
109
110 constexpr auto at(types::size_t index) const -> vocab::Optional<T&> {
111 if (index >= extent) {
112 return nullopt;
113 }
114 return (*this)[index];
115 }
116
117 constexpr auto operator[](types::size_t index) const -> T&
118 requires(extent > 0)
119 {
120 DI_ASSERT(index < extent);
121 return data()[index];
122 }
123
124 constexpr auto data() const -> T* { return m_data; }
125
126 constexpr auto size() const -> types::size_t { return extent; }
127 constexpr auto size_bytes() const -> types::size_t { return sizeof(T) * extent; }
128
129 [[nodiscard]] constexpr auto empty() const -> bool { return extent == 0; }
130
131 constexpr auto first(types::size_t count) const -> Optional<Span<T>> {
132 if (count > extent) {
133 return nullopt;
134 }
135 return Span<T> { data(), count };
136 }
137
138 constexpr auto last(types::size_t count) const -> Optional<Span<T>> {
139 if (count > extent) {
140 return nullopt;
141 }
142 return Span<T> { end() - count, count };
143 }
144
145 constexpr auto subspan(types::size_t offset) const -> Optional<Span<T>> {
146 if (offset > extent) {
147 return nullopt;
148 }
149 return Span<T> { data() + offset, extent - offset };
150 }
151
152 constexpr auto subspan(types::size_t offset, types::size_t count) const -> Optional<Span<T>> {
153 if (offset + count > extent) {
154 return nullopt;
155 }
156 return Span<T> { data() + offset, count };
157 }
158
159 template<types::size_t count>
160 requires(count <= extent)
161 constexpr auto first() const {
162 return Span<T, count> { data(), count };
163 }
164
165 template<types::size_t count>
166 requires(count <= extent)
167 constexpr auto last() const {
168 return Span<T, count> { end() - count, count };
169 }
170
171 template<types::size_t offset, types::size_t count = dynamic_extent>
172 requires(offset <= extent && (count == dynamic_extent || offset + count <= extent))
173 constexpr auto subspan() const {
174 if constexpr (count == dynamic_extent) {
175 return Span<T, extent - offset> { data() + offset, end() };
176 } else {
177 return Span<T, count> { data() + offset, count };
178 }
179 }
180
181 template<typename U = meta::RemoveCV<T>>
183 constexpr auto to_owned() const -> Array<U, extent> {
184 return apply(
185 [](auto const&... args) {
186 return Array<U, extent> { args... };
187 },
188 *this);
189 }
190
191private:
192 constexpr friend auto operator==(Span a, Span b) -> bool
194 {
195 return container::equal(a, b);
196 }
197
198 constexpr friend auto operator<=>(Span a, Span b)
200 {
201 return container::compare(a, b);
202 }
203
204 template<concepts::ContiguousIterator It, concepts::SizedSentinelFor<It> Sent>
207 -> Span<T> {
208 return Span<T>(util::move(first), util::move(last));
209 }
210
211 template<types::size_t index>
212 requires(index < extent)
217
218 template<types::size_t index>
219 requires(index < extent)
224
226 return extent;
227 }
228
229 template<types::size_t index>
230 requires(index < extent)
232 return self[index];
233 }
234
235 T* m_data { nullptr };
236};
237
238template<typename T, types::size_t size>
240
241template<typename T, types::size_t size>
243
244template<typename T, types::size_t size>
246}
#define DI_ASSERT(...)
Definition assert_bool.h:7
Definition optional_forward_declaration.h:5
constexpr other_extent const & other
Definition span_fixed_size.h:88
constexpr Span(Con &&container)
Definition span_fixed_size.h:81
constexpr auto data() const -> T *
Definition span_fixed_size.h:124
constexpr Span(Iter it, Sent sent)
Definition span_fixed_size.h:61
constexpr auto size() const -> types::size_t
Definition span_fixed_size.h:126
constexpr friend auto tag_invoke(types::Tag< tuple_element >, types::InPlaceType< Span >, Constexpr< index >) -> InPlaceType< T >
Definition span_fixed_size.h:213
constexpr friend auto tag_invoke(types::Tag< util::get_in_place >, Constexpr< index >, Span self) -> T &
Definition span_fixed_size.h:231
constexpr friend auto operator<=>(Span a, Span b)
Definition span_fixed_size.h:198
constexpr friend auto tag_invoke(types::Tag< container::reconstruct >, InPlaceType< Span >, It first, Sent last) -> Span< T >
Definition span_fixed_size.h:206
constexpr Span(vocab::Array< U, size > &array)
Definition span_fixed_size.h:71
constexpr auto back() const -> T &requires(extent > 0)
Definition span_fixed_size.h:104
constexpr auto first() const
Definition span_fixed_size.h:161
constexpr auto last() const
Definition span_fixed_size.h:167
constexpr Span(vocab::Array< U, size > const &array)
Definition span_fixed_size.h:75
constexpr Span()=default
constexpr auto front() const -> T &requires(extent > 0)
Definition span_fixed_size.h:98
T Element
Definition span_fixed_size.h:46
constexpr auto end() const -> T *
Definition span_fixed_size.h:96
constexpr friend auto tag_invoke(types::Tag< tuple_size >, types::InPlaceType< Span >) -> types::size_t
Definition span_fixed_size.h:225
constexpr auto subspan(types::size_t offset, types::size_t count) const -> Optional< Span< T > >
Definition span_fixed_size.h:152
constexpr auto operator=(Span const &) -> Span &=default
constexpr Span(Span const &)=default
constexpr auto to_owned() const -> Array< U, extent >
Definition span_fixed_size.h:183
constexpr auto operator[](types::size_t index) const -> T &requires(extent > 0)
Definition span_fixed_size.h:117
constexpr auto at(types::size_t index) const -> vocab::Optional< T & >
Definition span_fixed_size.h:110
constexpr auto begin() const -> T *
Definition span_fixed_size.h:95
constexpr auto first(types::size_t count) const -> Optional< Span< T > >
Definition span_fixed_size.h:131
constexpr friend auto operator==(Span a, Span b) -> bool requires(concepts::EqualityComparable< T >)
Definition span_fixed_size.h:192
constexpr Span(Iter first, types::size_t count)
Definition span_fixed_size.h:54
constexpr auto empty() const -> bool
Definition span_fixed_size.h:129
constexpr friend auto tag_invoke(types::Tag< tuple_element >, types::InPlaceType< Span const >, Constexpr< index >) -> InPlaceType< T >
Definition span_fixed_size.h:220
constexpr auto subspan(types::size_t offset) const -> Optional< Span< T > >
Definition span_fixed_size.h:145
constexpr auto size_bytes() const -> types::size_t
Definition span_fixed_size.h:127
constexpr auto last(types::size_t count) const -> Optional< Span< T > >
Definition span_fixed_size.h:138
constexpr auto subspan() const
Definition span_fixed_size.h:173
constexpr Span(T(&array)[size])
Definition span_fixed_size.h:67
Definition span_forward_declaration.h:10
Definition vocab.h:27
Definition borrowed_container.h:8
Definition language.h:18
Definition operations.h:99
Definition operations.h:34
Definition compare.h:82
Definition language.h:110
Definition sized_container.h:8
Definition vocab.h:146
Definition compare.h:91
Definition sequence.h:12
constexpr auto size
Definition size.h:62
constexpr auto data
Definition data.h:51
constexpr auto equal
Definition equal.h:46
constexpr auto compare
Definition compare.h:40
Definition merge_interfaces.h:6
Definition method.h:5
std::size_t size_t
Definition size_t.h:12
di::meta::Decay< decltype(T)> Tag
Definition tag_invoke.h:28
Definition vocab.h:96
constexpr auto to_address
Definition to_address.h:22
Definition lazy.h:165
constexpr auto apply(F &&f, Tup &&tuple) -> decltype(detail::apply_impl(meta::MakeIndexSequence< meta::TupleSize< Tup > > {}, util::forward< F >(f), util::forward< Tup >(tuple)))
Definition apply.h:22
Span(Iter, SentOrSize) -> Span< meta::RemoveReference< meta::IteratorReference< Iter > > >
constexpr auto nullopt
Definition nullopt.h:15
constexpr auto dynamic_extent
Definition span_forward_declaration.h:7
constexpr auto size
Definition size.h:62
constexpr auto data
Definition data.h:51
constexpr auto count
Definition count.h:37
constexpr auto end
Definition end.h:55
A wrapper for a constexpr value.
Definition constexpr.h:36
Definition in_place_type.h:5
Definition array.h:27
constexpr auto data() -> T *
Definition array.h:75