VCTR
Loading...
Searching...
No Matches
Span.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
31template <class ElementType>
32consteval auto simdAlignedSpanStorageInfo() { return StaticStorageInfo<true, false, alignof (std::span<ElementType>)>(); }
33
34// clang-format off
35
49template <class ElementType, size_t extent = std::dynamic_extent, class StorageInfoType = StorageInfoWithMemberAlignment<alignof (std::span<ElementType, extent>), StorageInfo<std::span<ElementType, extent> > > > // Extra whitespaces are needed for proper doxygen rendering
50class Span : public VctrBase<ElementType, std::span<ElementType, extent>, extent, StorageInfoType>
51{
52// clang-format on
53private:
54 //==============================================================================
56 using StdSpanType = std::span<ElementType, extent>;
57
58public:
59 //==============================================================================
60 using value_type = typename Vctr::value_type;
61
62 using element_type = ElementType;
63
64 //==============================================================================
65 // Constructors
66 //==============================================================================
67
69 constexpr Span (ElementType* ptr, size_t size)
70 : Vctr (StdSpanType (ptr, size))
71 {
72 VCTR_ASSERT (extent == size || extent == std::dynamic_extent);
73 }
74
80 template <bool isDataSIMDAligned, bool isStorageSIMDExtended>
81 constexpr Span (ElementType* ptr, size_t size, const StaticStorageInfo<isDataSIMDAligned, isStorageSIMDExtended, alignof (StdSpanType)>& info)
82 : Vctr (StdSpanType (ptr, size), info)
83 {
84 VCTR_ASSERT (extent == size || extent == std::dynamic_extent);
85
86 if constexpr (isDataSIMDAligned)
87 {
88 // If you hit this assertion, you passed a StaticStorageInfo that specifies SIMD aligned
89 // memory, but it is not aligned. Required alignment is 32 byte on x64 and 16 byte on ARM.
90 VCTR_ASSERT (detail::isPtrAligned (ptr));
91 }
92 }
93
98 template <has::sizeAndDataWithElementType<ElementType> Container>
99 constexpr Span (Container&& containerToView)
100 : Vctr (StdSpanType (containerToView.data(), containerToView.size()), makeStorageInfo (containerToView))
101 {
102 VCTR_ASSERT (extent == containerToView.size() || extent == std::dynamic_extent);
103 }
104
105 //==============================================================================
106 // Operators
107 //==============================================================================
108 // Deleting the default copy operator forces the usage of the intended operator below
109 Span& operator= (const Span&) = delete;
110
112 template <has::sizeAndDataWithElementType<ElementType> Container>
113 constexpr Span& operator= (Container&& containerToCopyDataFrom)
114 {
115 if constexpr (Vctr::template shouldMoveFromOtherContainer<Container>)
116 {
117 VCTR_ASSERT (containerToCopyDataFrom.size() == Vctr::size());
118 std::copy (std::make_move_iterator (containerToCopyDataFrom.begin()), std::make_move_iterator (containerToCopyDataFrom.end()), Vctr::storage.begin());
119 }
120 else
121 {
122 Vctr::copyFrom (containerToCopyDataFrom.data(), containerToCopyDataFrom.size());
123 }
124
125 return *this;
126 }
127
129 constexpr Span& operator= (std::initializer_list<ElementType> elementsToAssign)
130 {
131 Vctr::assign (std::move (elementsToAssign));
132 return *this;
133 }
134
139 template <is::expression E>
140 constexpr void operator= (const E& expression)
141 {
142 VCTR_ASSERT (expression.size() == Vctr::size());
143
144 Vctr::assignExpressionTemplate (expression);
145 }
146
147private:
148 //==============================================================================
149 template <has::sizeAndData Container>
150 static constexpr auto makeStorageInfo (const Container& container)
151 {
152 constexpr size_t memberAlignment = alignof (StdSpanType);
153
154 if constexpr (is::anyVctr<Container>)
155 {
156 const auto& info = container.getStorageInfo();
157 return StorageInfoWithMemberAlignment<memberAlignment, std::remove_cvref_t<decltype (info)>> (info);
158 }
159 else
160 {
161 return StorageInfoWithMemberAlignment<memberAlignment, StorageInfo<Container>>().init (container.data(), container.size());
162 }
163 }
164};
165
166//==============================================================================
167// Deduction guides
168//==============================================================================
169
170template <class ElementType, bool isDataSIMDAligned, bool isStorageSIMDExtended>
171Span (ElementType*, size_t, const StaticStorageInfo<isDataSIMDAligned, isStorageSIMDExtended, alignof (std::span<ElementType>)>&) -> Span<ElementType, std::dynamic_extent, StaticStorageInfo<isDataSIMDAligned, isStorageSIMDExtended, alignof (std::span<ElementType>)>>;
172
173template <class Container>
174Span (Container&&) -> Span<DataType<Container>, extentOf<Container>, StorageInfoWithMemberAlignment<alignof (std::span<DataType<Container>, extentOf<Container>>), StorageInfoType<Container>>>;
175
177template <class ElementType>
178auto makeSimdAlignedSpan (ElementType* data, size_t size)
179{
180 // If you hit this assertion, you passed a StaticStorageInfo that specifies SIMD aligned
181 // memory, but it is not aligned. Required alignment is 32 byte on x64 and 16 byte on ARM.
182 VCTR_ASSERT (detail::isPtrAligned (data));
183
184 return Span<ElementType, std::dynamic_extent, StaticStorageInfo<true, false, alignof (std::span<ElementType>)>> (data, size);
185}
186
188template <size_t extent, class ElementType>
189requires (extent != std::dynamic_extent)
190auto makeSimdAlignedSpan (ElementType* data)
191{
192 // If you hit this assertion, you passed a StaticStorageInfo that specifies SIMD aligned
193 // memory, but it is not aligned. Required alignment is 32 byte on x64 and 16 byte on ARM.
194 VCTR_ASSERT (detail::isPtrAligned (data));
195
196 return Span<ElementType, extent, StaticStorageInfo<true, false, alignof (std::span<ElementType>)>> (data, extent);
197}
198
199} // namespace vctr
The view type.
Definition: Span.h:51
constexpr Span(ElementType *ptr, size_t size, const StaticStorageInfo< isDataSIMDAligned, isStorageSIMDExtended, alignof(StdSpanType)> &info)
Creates a Span with a given size that views externally managed data, accessed by ptr.
Definition: Span.h:81
constexpr Span(ElementType *ptr, size_t size)
Creates a Span with a given size that views externally managed data, accessed by ptr.
Definition: Span.h:69
constexpr Span(Container &&containerToView)
Creates a Span that acts as a view to the given container.
Definition: Span.h:99
The base class to all one dimensional containers and views in the VCTR project.
Definition: VctrBase.h:38
constexpr size_t size() const noexcept
Returns the number of elements.
Definition: VctrBase.h:61
constexpr void assign(std::initializer_list< ElementType > elements)
Assigns elements from the initializer list to this instance.
Definition: VctrBase.h:262
constexpr void copyFrom(const ElementType *otherData, size_t otherSize)
Copies the content from otherData to this instance.
Definition: VctrBase.h:281
VCTR_FORCEDINLINE constexpr auto * data()
Returns a raw pointer to the underlying storage.
Definition: VctrBase.h:123
Constrains a type to be any derived instance of VctrBase.
Definition: ContainerAndExpressionConcepts.h:192
The main namespace of the VCTR project.
Definition: Array.h:24
typename detail::StorageInfoType< std::remove_cvref_t< T > >::Type StorageInfoType
If t is a type derived from VctrBase, this will equal the return value of T::getStorageInfo,...
Definition: Traits.h:227
auto makeSimdAlignedSpan(ElementType *data, size_t size)
Creates a span with dynamic extent pointing to a memory location that is expected to be SIMD aligned.
Definition: Span.h:178
consteval auto simdAlignedSpanStorageInfo()
Creates a StaticStorageInfo instance suitable to be passed to a Span constructor.
Definition: Span.h:32
A storage info type especially used to pass compile time constant traits when viewing externally owne...
Definition: SIMDHelpers.h:150
A storage info type especially used for vctr::Span.
Definition: SIMDHelpers.h:164