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 constexpr (std::copy_constructible <ElementType>)
75 {
76 if (std::is_constant_evaluated())
77 {
78 if constexpr (extent > 0)
79 Vctr::storage.fill (value_type());
80 }
81 }
82 }
83
85 constexpr Array (ElementType initialValue)
86 requires (extent > 1)
87 {
88 Vctr::storage.fill (initialValue);
89 }
90
92 template <std::convertible_to<ElementType> T>
93 constexpr Array (T&& initialValue)
94 requires (extent == 1)
95 : Vctr (StdArrayType { initialValue }) {}
96
98 template <is::suitableInitializerForElementType<ElementType>... T>
99 requires (sizeof...(T) > 1)
100 constexpr Array (T&&... initialValues) : Vctr (StdArrayType { std::forward<T> (initialValues)... })
101 {}
102
104 template <class OtherElementType, size_t otherSize>
105 constexpr Array (std::array<OtherElementType, otherSize>&& other) : Vctr (std::move (other)) {}
106
116 template <is::triviallyCopyableWithDataAndSize OtherContainer>
117 requires (std::same_as<value_type, ValueType<OtherContainer>> && ! std::same_as<Array, OtherContainer>)
118 constexpr Array (const OtherContainer& other)
119 {
120 if (std::is_constant_evaluated())
121 {
122 for (size_t i = 0; i < extent; ++i)
123 Vctr::storage[i] = other[i];
124 }
125 else
126 {
127 Vctr::copyFrom (other.data(), other.size());
128 }
129 }
130
138 template <is::iteratorCopyable OtherContainer>
139 constexpr Array (const OtherContainer& other) : Array (other.begin(), other.end()) {}
140
142 constexpr Array (const ElementType* data, size_t size)
143 {
144 Vctr::copyFrom (data, size);
145 }
146
148 template <is::inputIteratorToConstructValuesOfType<ElementType> Iterator, std::sentinel_for<Iterator> Sentinel>
149 constexpr Array (Iterator first, [[maybe_unused]] Sentinel last)
150 {
151 for (size_t i = 0; i < extent; ++i, ++first)
152 Vctr::storage[i] = *first;
153
154 if (! std::is_constant_evaluated())
155 {
156 // If you hit this assertion, the extent of the Array did not match the distance between first and last
157 VCTR_ASSERT (first == last);
158 }
159 }
160
166 template <is::suitableInitializerFunctionForElementType<ElementType> Fn>
167 constexpr Array (Fn&& initializerFunction) : Array (std::forward<Fn> (initializerFunction), std::make_index_sequence<extent>()) {}
168
177 template <is::expression Expression>
178 constexpr Array (Expression&& e)
179 {
180 VCTR_ASSERT (e.size() == extent);
181 Vctr::assignExpressionTemplate (std::forward<Expression> (e));
182 }
183
184 //==============================================================================
185 // Operators
186 //==============================================================================
188 template <has::sizeAndDataWithElementType<ElementType> Container>
189 constexpr Array& operator= (Container&& containerToCopyDataFrom)
190 {
191 if constexpr (Vctr::template shouldMoveFromOtherContainer<Container>)
192 {
193 VCTR_ASSERT (containerToCopyDataFrom.size() == Vctr::size());
194 std::copy (std::make_move_iterator (containerToCopyDataFrom.begin()), std::make_move_iterator (containerToCopyDataFrom.end()), Vctr::storage.begin());
195 }
196 else
197 {
198 Vctr::copyFrom (containerToCopyDataFrom.data(), containerToCopyDataFrom.size());
199 }
200
201 return *this;
202 }
203
205 constexpr Array& operator= (std::initializer_list<ElementType> elementsToAssign)
206 {
207 Vctr::assign (std::move (elementsToAssign));
208 return *this;
209 }
210
215 template <is::expression E>
216 constexpr void operator= (const E& expression)
217 {
218 if (! std::is_constant_evaluated())
219 VCTR_ASSERT (expression.size() == extent);
220
221 Vctr::assignExpressionTemplate (expression);
222 }
223
224private:
225 //==============================================================================
226 template <is::suitableInitializerFunction Fn, size_t... i>
227 constexpr Array (Fn&& initializerFunction, std::index_sequence<i...>) : Vctr (StdArrayType { initializerFunction (i)... }) {}
228};
229
231template <class OwnedElementType, size_t extent>
232class OwnedArray : public Array<std::unique_ptr<OwnedElementType>, extent>
233{
234private:
235 //==============================================================================
237
238public:
239 //==============================================================================
240 OwnedArray() = default;
241
243 template <is::pointer... Pointer>
244 OwnedArray (Pointer... elementsToOwn) : OwnedArray (std::unique_ptr<OwnedElementType> (elementsToOwn)...) {}
245
247 template <is::noPointer... Args>
248 OwnedArray (Args&&... args) : ArrayType (std::forward<Args> (args)...) {}
249};
250
251//==============================================================================
252// Deduction guides
253//==============================================================================
254
255template <class OtherElementType, size_t otherSize>
256Array (std::array<OtherElementType, otherSize>&&) -> Array<OtherElementType, otherSize, otherSize>;
257
258template <class First, is::suitableInitializerForElementType<std::remove_cvref_t<First>>... Other>
259Array (First&&, Other&&...) -> Array<std::remove_cvref_t<First>, sizeof...(Other) + 1>;
260
261namespace detail
262{
263
264// Clang failed to respect constrained single template types in deduction guides for some reasons.
265// Using this as workaround for the single argument deduction guide below
266template <class T>
267struct SingleArgDeductionHelper
268{
269 using Type = std::remove_cvref_t<T>;
270 static constexpr size_t extent = 1;
271};
272
273template <has::size T>
274struct SingleArgDeductionHelper<T>
275{
276 using Type = vctr::ValueType<T>;
277 static constexpr size_t extent = extentOf<T>;
278};
279
280} // namespace detail
281
282template <class SingleArg>
283Array (SingleArg&&) -> Array<typename detail::SingleArgDeductionHelper<SingleArg>::Type, detail::SingleArgDeductionHelper<SingleArg>::extent>;
284
285template <class Pointer, std::same_as<Pointer>... Pointers>
286OwnedArray (Pointer*, Pointers*...) -> OwnedArray<Pointer, sizeof...(Pointers) + 1>;
287
288} // 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:85
constexpr Array(std::array< OtherElementType, otherSize > &&other)
Creates an Array by moving a std::array into it.
Definition: Array.h:105
constexpr Array(T &&initialValue)
Creates an Array with extent 1 from an initial value.
Definition: Array.h:93
constexpr Array(Fn &&initializerFunction)
Creates a vector of the given size and initialises all elements by calling initializerFunction with t...
Definition: Array.h:167
constexpr Array(T &&... initialValues)
Creates an Array from a list of at least two initial values.
Definition: Array.h:100
constexpr Array(Expression &&e)
Creates an Array from an expression template.
Definition: Array.h:178
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:149
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:142
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:139
A handy shortcut for Array<std::unique_ptr<OwnedElementType>, n>.
Definition: Array.h:233
OwnedArray(Args &&... args)
Forwards every other constructor call to the base class constructor.
Definition: Array.h:248
OwnedArray(Pointer... elementsToOwn)
Creates an OwnedArray from a list of raw pointers that will be owned by the Array.
Definition: Array.h:244
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:363
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