VCTR
Loading...
Searching...
No Matches
Array.h
1/*
2 ==============================================================================
3 DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4
5 Copyright 2022- by sonible GmbH.
6
7 This file is part of VCTR - Versatile Container Templates Reconceptualized.
8
9 VCTR is free software: you can redistribute it and/or modify
10 it under the terms of the GNU Lesser General Public License version 3
11 only, as published by the Free Software Foundation.
12
13 VCTR is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU Lesser General Public License version 3 for more details.
17
18 You should have received a copy of the GNU Lesser General Public License
19 version 3 along with VCTR. If not, see <https://www.gnu.org/licenses/>.
20 ==============================================================================
21*/
22
23namespace vctr
24{
25
26namespace detail
27{
28
29template <class T, size_t e>
30struct StorageExtent
31{
32 static constexpr size_t extent = e;
33};
34
35template <is::number T, size_t e>
36struct StorageExtent<T, e>
37{
38 static constexpr size_t extent = nextMultipleOf<Config::maxSIMDRegisterSize / sizeof (T)> (e);
39};
40} // namespace detail
41
50template <class ElementType, size_t extent, size_t storageExtent = detail::StorageExtent<ElementType, extent>::extent>
51requires (extent != std::dynamic_extent && extent <= storageExtent)
52class Array : public VctrBase<ElementType, std::array<ElementType, storageExtent>, extent>
53{
54protected:
55 //==============================================================================
57 using StdArrayType = std::array<ElementType, storageExtent>;
58
59public:
60 //==============================================================================
61 using value_type = typename Vctr::value_type;
62
63 //==============================================================================
64 // Constructors
65 //==============================================================================
66
72 constexpr Array()
73 {
74 if (std::is_constant_evaluated())
75 Vctr::storage.fill (value_type());
76 }
77
79 constexpr Array (ElementType initialValue)
80 requires (extent > 1)
81 {
82 Vctr::storage.fill (initialValue);
83 }
84
86 template <is::suitableInitializerForElementType<ElementType>... T>
87 requires (sizeof...(T) > 1)
88 constexpr Array (T&&... initialValues) : Vctr (StdArrayType { std::forward<T> (initialValues)... })
89 {}
90
92 template <std::convertible_to<ElementType> T>
93 constexpr Array (T&& initialValues) : Vctr (StdArrayType { initialValues }) {}
94
96 template <class OtherElementType, size_t otherSize>
97 constexpr Array (std::array<OtherElementType, otherSize>&& other) : Vctr (std::move (other)) {}
98
108 template <is::triviallyCopyableWithDataAndSize OtherContainer>
109 requires (std::same_as<value_type, ValueType<OtherContainer>> && ! std::same_as<Array, OtherContainer>)
110 constexpr Array (const OtherContainer& other)
111 {
112 if (std::is_constant_evaluated())
113 {
114 for (size_t i = 0; i < extent; ++i)
115 Vctr::storage[i] = other[i];
116 }
117 else
118 {
119 Vctr::copyFrom (other.data(), other.size());
120 }
121 }
122
130 template <is::iteratorCopyable OtherContainer>
131 constexpr Array (const OtherContainer& other) : Array (other.begin(), other.end()) {}
132
134 constexpr Array (const ElementType* data, size_t size)
135 {
136 Vctr::copyFrom (data, size);
137 }
138
140 template <is::inputIteratorToConstructValuesOfType<ElementType> Iterator, std::sentinel_for<Iterator> Sentinel>
141 constexpr Array (Iterator first, [[maybe_unused]] Sentinel last)
142 {
143 for (size_t i = 0; i < extent; ++i, ++first)
144 Vctr::storage[i] = *first;
145
146 if (! std::is_constant_evaluated())
147 {
148 // If you hit this assertion, the extent of the Array did not match the distance between first and last
149 VCTR_ASSERT (first == last);
150 }
151 }
152
158 template <is::suitableInitializerFunctionForElementType<ElementType> Fn>
159 constexpr Array (Fn&& initializerFunction) : Array (std::forward<Fn> (initializerFunction), std::make_index_sequence<extent>()) {}
160
169 template <is::expression Expression>
170 constexpr Array (Expression&& e)
171 {
172 VCTR_ASSERT (e.size() == extent);
173 Vctr::assignExpressionTemplate (std::forward<Expression> (e));
174 }
175
176 //==============================================================================
177 // Operators
178 //==============================================================================
180 template <has::sizeAndDataWithElementType<ElementType> Container>
181 constexpr Array& operator= (Container&& containerToCopyDataFrom)
182 {
183 if constexpr (Vctr::template shouldMoveFromOtherContainer<Container>)
184 {
185 VCTR_ASSERT (containerToCopyDataFrom.size() == Vctr::size());
186 std::copy (std::make_move_iterator (containerToCopyDataFrom.begin()), std::make_move_iterator (containerToCopyDataFrom.end()), Vctr::storage.begin());
187 }
188 else
189 {
190 Vctr::copyFrom (containerToCopyDataFrom.data(), containerToCopyDataFrom.size());
191 }
192
193 return *this;
194 }
195
197 constexpr Array& operator= (std::initializer_list<ElementType> elementsToAssign)
198 {
199 Vctr::assign (std::move (elementsToAssign));
200 return *this;
201 }
202
207 template <is::expression E>
208 constexpr void operator= (const E& expression)
209 {
210 if (! std::is_constant_evaluated())
211 VCTR_ASSERT (expression.size() == extent);
212
213 Vctr::assignExpressionTemplate (expression);
214 }
215
216private:
217 //==============================================================================
218 template <is::suitableInitializerFunction Fn, size_t... i>
219 constexpr Array (Fn&& initializerFunction, std::index_sequence<i...>) : Vctr (StdArrayType { initializerFunction (i)... }) {}
220};
221
223template <class OwnedElementType, size_t extent>
224class OwnedArray : public Array<std::unique_ptr<OwnedElementType>, extent>
225{
226private:
227 //==============================================================================
229
230public:
231 //==============================================================================
232 OwnedArray() = default;
233
235 template <is::pointer... Pointer>
236 OwnedArray (Pointer... elementsToOwn) : OwnedArray (std::unique_ptr<OwnedElementType> (elementsToOwn)...) {}
237
239 template <is::noPointer... Args>
240 OwnedArray (Args&&... args) : ArrayType (std::forward<Args> (args)...) {}
241};
242
243//==============================================================================
244// Deduction guides
245//==============================================================================
246
247template <class OtherElementType, size_t otherSize>
248Array (std::array<OtherElementType, otherSize>&&) -> Array<OtherElementType, otherSize, otherSize>;
249
250template <class First, is::suitableInitializerForElementType<std::remove_cvref_t<First>>... Other>
251Array (First&&, Other&&...) -> Array<std::remove_cvref_t<First>, sizeof...(Other) + 1>;
252
253namespace detail
254{
255
256// Clang failed to respect constrained single template types in deduction guides for some reasons.
257// Using this as workaround for the single argument deduction guide below
258template <class T>
259struct SingleArgDeductionHelper
260{
261 using Type = std::remove_cvref_t<T>;
262 static constexpr size_t extent = 1;
263};
264
265template <has::size T>
266struct SingleArgDeductionHelper<T>
267{
268 using Type = vctr::ValueType<T>;
269 static constexpr size_t extent = extentOf<T>;
270};
271
272} // namespace detail
273
274template <class SingleArg>
275Array (SingleArg&&) -> Array<typename detail::SingleArgDeductionHelper<SingleArg>::Type, detail::SingleArgDeductionHelper<SingleArg>::extent>;
276
277template <class Pointer, std::same_as<Pointer>... Pointers>
278OwnedArray (Pointer*, Pointers*...) -> OwnedArray<Pointer, sizeof...(Pointers) + 1>;
279
280} // namespace vctr
The stack-based container type.
Definition: Array.h:53
constexpr Array(ElementType initialValue)
Creates an Array with all elements initialised to initialValue.
Definition: Array.h:79
constexpr Array(T &&initialValues)
Creates an Array with extent 1 from an initial value.
Definition: Array.h:93
constexpr Array(std::array< OtherElementType, otherSize > &&other)
Creates an Array by moving a std::array into it.
Definition: Array.h:97
constexpr Array(Fn &&initializerFunction)
Creates a vector of the given size and initialises all elements by calling initializerFunction with t...
Definition: Array.h:159
constexpr Array(T &&... initialValues)
Creates an Array from a list of at least two initial values.
Definition: Array.h:88
constexpr Array(Expression &&e)
Creates an Array from an expression template.
Definition: Array.h:170
constexpr Array(Iterator first, Sentinel last)
Creates an Array from an iterator and a sentinel by initialising the Array with the content read from...
Definition: Array.h:141
constexpr Array()
Creates an uninitialised Array.
Definition: Array.h:72
constexpr Array(const ElementType *data, size_t size)
Copies size elements from the memory location pointed to by data.
Definition: Array.h:134
constexpr Array(const OtherContainer &other)
This constructor will create an Array instance of the same size as OtherContainer and will copy its v...
Definition: Array.h:131
A handy shortcut for Array<std::unique_ptr<OwnedElementType>, n>.
Definition: Array.h:225
OwnedArray(Args &&... args)
Forwards every other constructor call to the base class constructor.
Definition: Array.h:240
OwnedArray(Pointer... elementsToOwn)
Creates an OwnedArray from a list of raw pointers that will be owned by the Array.
Definition: Array.h:236
The base class to all one dimensional containers and views in the VCTR project.
Definition: VctrBase.h:38
Constrains a type to be no pointer of a reference to a pointer.
Definition: GenericConcepts.h:96
Constrains a type to be a pointer of a reference to a pointer.
Definition: GenericConcepts.h:92
Constrains the type to be a function suitable for initializing the nth element of a Vctr,...
Definition: ContainerAndExpressionConcepts.h:345
The main namespace of the VCTR project.
Definition: Array.h:24
typename detail::ValueType< std::remove_cvref_t< T > >::Type ValueType
If T is an expression template, it equals its return type, if it's a type that defines value_type as ...
Definition: Traits.h:201