Blaze 3.9
DenseIterator.h
Go to the documentation of this file.
1//=================================================================================================
24//=================================================================================================
25
26#ifndef _BLAZE_MATH_DENSE_DENSEITERATOR_H_
27#define _BLAZE_MATH_DENSE_DENSEITERATOR_H_
28
29
30//*************************************************************************************************
31// Includes
32//*************************************************************************************************
33
34#include <iterator>
36#include <blaze/math/SIMD.h>
38#include <blaze/util/Assert.h>
39#include <blaze/util/Types.h>
40
41
42namespace blaze {
43
44//=================================================================================================
45//
46// CLASS DEFINITION
47//
48//=================================================================================================
49
50//*************************************************************************************************
57template< typename Type // Type of the elements
58 , AlignmentFlag AF > // Alignment flag
60{
61 public:
62 //**Type definitions****************************************************************************
63 using IteratorCategory = std::random_access_iterator_tag;
64 using ValueType = Type;
65 using PointerType = Type*;
66 using ReferenceType = Type&;
67 using DifferenceType = ptrdiff_t;
68
69 // STL iterator requirements
75
78 //**********************************************************************************************
79
80 //**Constructors********************************************************************************
83 explicit constexpr DenseIterator() noexcept;
84 explicit constexpr DenseIterator( Type* ptr ) noexcept;
85
86 template< typename Other, AlignmentFlag AF2 >
87 constexpr DenseIterator( const DenseIterator<Other,AF2>& it ) noexcept;
88
89 DenseIterator( const DenseIterator& ) = default;
91 //**********************************************************************************************
92
93 //**Destructor**********************************************************************************
96 ~DenseIterator() = default;
98 //**********************************************************************************************
99
100 //**Assignment operators************************************************************************
103 constexpr DenseIterator& operator+=( ptrdiff_t inc ) noexcept;
104 constexpr DenseIterator& operator-=( ptrdiff_t inc ) noexcept;
105
106 DenseIterator& operator=( const DenseIterator& ) = default;
108 //**********************************************************************************************
109
110 //**Increment/decrement operators***************************************************************
113 constexpr DenseIterator& operator++() noexcept;
114 constexpr const DenseIterator operator++( int ) noexcept;
115 constexpr DenseIterator& operator--() noexcept;
116 constexpr const DenseIterator operator--( int ) noexcept;
118 //**********************************************************************************************
119
120 //**Access operators****************************************************************************
123 constexpr ReferenceType operator[]( size_t index ) const noexcept;
124 constexpr ReferenceType operator* () const noexcept;
125 constexpr PointerType operator->() const noexcept;
127 //**********************************************************************************************
128
129 //**Utility functions***************************************************************************
132 constexpr PointerType base() const noexcept;
134 //**********************************************************************************************
135
136 //**Expression template evaluation functions****************************************************
139 inline const SIMDType load () const noexcept;
140 inline const SIMDType loada () const noexcept;
141 inline const SIMDType loadu () const noexcept;
142 inline void store ( const SIMDType& value ) const noexcept;
143 inline void storea( const SIMDType& value ) const noexcept;
144 inline void storeu( const SIMDType& value ) const noexcept;
145 inline void stream( const SIMDType& value ) const noexcept;
147 //**********************************************************************************************
148
149 private:
150 //**Member variables****************************************************************************
155 //**********************************************************************************************
156};
157//*************************************************************************************************
158
159
160
161
162//=================================================================================================
163//
164// CONSTRUCTORS
165//
166//=================================================================================================
167
168//*************************************************************************************************
171template< typename Type // Type of the elements
172 , AlignmentFlag AF > // Alignment flag
173constexpr DenseIterator<Type,AF>::DenseIterator() noexcept
174 : ptr_( nullptr ) // Pointer to the current element
175{}
176//*************************************************************************************************
177
178
179//*************************************************************************************************
184template< typename Type // Type of the elements
185 , AlignmentFlag AF > // Alignment flag
186constexpr DenseIterator<Type,AF>::DenseIterator( Type* ptr ) noexcept
187 : ptr_( ptr ) // Pointer to the current element
188{}
189//*************************************************************************************************
190
191
192//*************************************************************************************************
197template< typename Type // Type of the elements
198 , AlignmentFlag AF > // Alignment flag
199template< typename Other // Type of the foreign elements
200 , AlignmentFlag AF2 > // Alignment flag of the foreign iterator
202 : ptr_( it.base() ) // Pointer to the current element
203{}
204//*************************************************************************************************
205
206
207
208
209//=================================================================================================
210//
211// ASSIGNMENT OPERATORS
212//
213//=================================================================================================
214
215//*************************************************************************************************
221template< typename Type // Type of the elements
222 , AlignmentFlag AF > // Alignment flag
223constexpr DenseIterator<Type,AF>&
224 DenseIterator<Type,AF>::operator+=( ptrdiff_t inc ) noexcept
225{
226 ptr_ += inc;
227 return *this;
228}
229//*************************************************************************************************
230
231
232//*************************************************************************************************
238template< typename Type // Type of the elements
239 , AlignmentFlag AF > // Alignment flag
240constexpr DenseIterator<Type,AF>&
241 DenseIterator<Type,AF>::operator-=( ptrdiff_t dec ) noexcept
242{
243 ptr_ -= dec;
244 return *this;
245}
246//*************************************************************************************************
247
248
249
250
251//=================================================================================================
252//
253// INCREMENT/DECREMENT OPERATORS
254//
255//=================================================================================================
256
257//*************************************************************************************************
262template< typename Type // Type of the elements
263 , AlignmentFlag AF > // Alignment flag
265{
266 ++ptr_;
267 return *this;
268}
269//*************************************************************************************************
270
271
272//*************************************************************************************************
277template< typename Type // Type of the elements
278 , AlignmentFlag AF > // Alignment flag
280{
281 return DenseIterator( ptr_++ );
282}
283//*************************************************************************************************
284
285
286//*************************************************************************************************
291template< typename Type // Type of the elements
292 , AlignmentFlag AF > // Alignment flag
294{
295 --ptr_;
296 return *this;
297}
298//*************************************************************************************************
299
300
301//*************************************************************************************************
306template< typename Type // Type of the elements
307 , AlignmentFlag AF > // Alignment flag
309{
310 return DenseIterator( ptr_-- );
311}
312//*************************************************************************************************
313
314
315
316
317//=================================================================================================
318//
319// ACCESS OPERATORS
320//
321//=================================================================================================
322
323//*************************************************************************************************
329template< typename Type // Type of the elements
330 , AlignmentFlag AF > // Alignment flag
332 DenseIterator<Type,AF>::operator[]( size_t index ) const noexcept
333{
334 return ptr_[index];
335}
336//*************************************************************************************************
337
338
339//*************************************************************************************************
344template< typename Type // Type of the elements
345 , AlignmentFlag AF > // Alignment flag
348{
349 return *ptr_;
350}
351//*************************************************************************************************
352
353
354//*************************************************************************************************
359template< typename Type // Type of the elements
360 , AlignmentFlag AF > // Alignment flag
363{
364 return ptr_;
365}
366//*************************************************************************************************
367
368
369
370
371//=================================================================================================
372//
373// UTILITY FUNCTIONS
374//
375//=================================================================================================
376
377//*************************************************************************************************
382template< typename Type // Type of the elements
383 , AlignmentFlag AF > // Alignment flag
386{
387 return ptr_;
388}
389//*************************************************************************************************
390
391
392
393
394//=================================================================================================
395//
396// EXPRESSION TEMPLATE EVALUATION FUNCTIONS
397//
398//=================================================================================================
399
400//*************************************************************************************************
410template< typename Type // Type of the elements
411 , AlignmentFlag AF > // Alignment flag
412inline const typename DenseIterator<Type,AF>::SIMDType
414{
415 if( AF )
416 return loada();
417 else
418 return loadu();
419}
420//*************************************************************************************************
421
422
423//*************************************************************************************************
433template< typename Type // Type of the elements
434 , AlignmentFlag AF > // Alignment flag
435inline const typename DenseIterator<Type,AF>::SIMDType
437{
438 BLAZE_INTERNAL_ASSERT( checkAlignment( ptr_ ), "Invalid alignment detected" );
439
440 return blaze::loada( ptr_ );
441}
442//*************************************************************************************************
443
444
445//*************************************************************************************************
455template< typename Type // Type of the elements
456 , AlignmentFlag AF > // Alignment flag
457inline const typename DenseIterator<Type,AF>::SIMDType
459{
460 return blaze::loadu( ptr_ );
461}
462//*************************************************************************************************
463
464
465//*************************************************************************************************
476template< typename Type // Type of the elements
477 , AlignmentFlag AF > // Alignment flag
478inline void DenseIterator<Type,AF>::store( const SIMDType& value ) const noexcept
479{
480 if( AF )
481 storea( value );
482 else
483 storeu( value );
484}
485//*************************************************************************************************
486
487
488//*************************************************************************************************
499template< typename Type // Type of the elements
500 , AlignmentFlag AF > // Alignment flag
501inline void DenseIterator<Type,AF>::storea( const SIMDType& value ) const noexcept
502{
503 blaze::storea( ptr_, value );
504}
505//*************************************************************************************************
506
507
508//*************************************************************************************************
519template< typename Type // Type of the elements
520 , AlignmentFlag AF > // Alignment flag
521inline void DenseIterator<Type,AF>::storeu( const SIMDType& value ) const noexcept
522{
523 blaze::storeu( ptr_, value );
524}
525//*************************************************************************************************
526
527
528//*************************************************************************************************
539template< typename Type // Type of the elements
540 , AlignmentFlag AF > // Alignment flag
541inline void DenseIterator<Type,AF>::stream( const SIMDType& value ) const noexcept
542{
543 blaze::stream( ptr_, value );
544}
545//*************************************************************************************************
546
547
548
549
550//=================================================================================================
551//
552// GLOBAL OPERATORS
553//
554//=================================================================================================
555
556//*************************************************************************************************
559template< typename T1, AlignmentFlag AF1, typename T2, AlignmentFlag AF2 >
560constexpr bool
561 operator==( const DenseIterator<T1,AF1>& lhs, const DenseIterator<T2,AF2>& rhs ) noexcept;
562
563template< typename T1, AlignmentFlag AF1, typename T2, AlignmentFlag AF2 >
564constexpr bool
565 operator!=( const DenseIterator<T1,AF1>& lhs, const DenseIterator<T2,AF2>& rhs ) noexcept;
566
567template< typename T1, AlignmentFlag AF1, typename T2, AlignmentFlag AF2 >
568constexpr bool
569 operator<( const DenseIterator<T1,AF1>& lhs, const DenseIterator<T2,AF2>& rhs ) noexcept;
570
571template< typename T1, AlignmentFlag AF1, typename T2, AlignmentFlag AF2 >
572constexpr bool
573 operator>( const DenseIterator<T1,AF1>& lhs, const DenseIterator<T2,AF2>& rhs ) noexcept;
574
575template< typename T1, AlignmentFlag AF1, typename T2, AlignmentFlag AF2 >
576constexpr bool
577 operator<=( const DenseIterator<T1,AF1>& lhs, const DenseIterator<T2,AF2>& rhs ) noexcept;
578
579template< typename T1, AlignmentFlag AF1, typename T2, AlignmentFlag AF2 >
580constexpr bool
581 operator>=( const DenseIterator<T1,AF1>& lhs, const DenseIterator<T2,AF2>& rhs ) noexcept;
582
583template< typename Type, AlignmentFlag AF >
584constexpr const DenseIterator<Type,AF>
585 operator+( const DenseIterator<Type,AF>& it, ptrdiff_t inc ) noexcept;
586
587template< typename Type, AlignmentFlag AF >
588constexpr const DenseIterator<Type,AF>
589 operator+( ptrdiff_t inc, const DenseIterator<Type,AF>& it ) noexcept;
590
591template< typename Type, AlignmentFlag AF >
592constexpr const DenseIterator<Type,AF>
593 operator-( const DenseIterator<Type,AF>& it, ptrdiff_t inc ) noexcept;
594
595template< typename Type, AlignmentFlag AF >
596constexpr ptrdiff_t
597 operator-( const DenseIterator<Type,AF>& lhs, const DenseIterator<Type,AF>& rhs ) noexcept;
599//*************************************************************************************************
600
601
602//*************************************************************************************************
609template< typename T1 // Element type of the left-hand side iterator
610 , AlignmentFlag AF1 // Alignment flag of the left-hand side iterator
611 , typename T2 // Element type of the right-hand side iterator
612 , AlignmentFlag AF2 > // Alignment flag of the right-hand side iterator
613constexpr bool operator==( const DenseIterator<T1,AF1>& lhs, const DenseIterator<T2,AF2>& rhs ) noexcept
614{
615 return lhs.base() == rhs.base();
616}
617//*************************************************************************************************
618
619
620//*************************************************************************************************
627template< typename T1 // Element type of the left-hand side iterator
628 , AlignmentFlag AF1 // Alignment flag of the left-hand side iterator
629 , typename T2 // Element type of the right-hand side iterator
630 , AlignmentFlag AF2 > // Alignment flag of the right-hand side iterator
631constexpr bool operator!=( const DenseIterator<T1,AF1>& lhs, const DenseIterator<T2,AF2>& rhs ) noexcept
632{
633 return lhs.base() != rhs.base();
634}
635//*************************************************************************************************
636
637
638//*************************************************************************************************
645template< typename T1 // Element type of the left-hand side iterator
646 , AlignmentFlag AF1 // Alignment flag of the left-hand side iterator
647 , typename T2 // Element type of the right-hand side iterator
648 , AlignmentFlag AF2 > // Alignment flag of the right-hand side iterator
649constexpr bool operator<( const DenseIterator<T1,AF1>& lhs, const DenseIterator<T2,AF2>& rhs ) noexcept
650{
651 return lhs.base() < rhs.base();
652}
653//*************************************************************************************************
654
655
656//*************************************************************************************************
663template< typename T1 // Element type of the left-hand side iterator
664 , AlignmentFlag AF1 // Alignment flag of the left-hand side iterator
665 , typename T2 // Element type of the right-hand side iterator
666 , AlignmentFlag AF2 > // Alignment flag of the right-hand side iterator
667constexpr bool operator>( const DenseIterator<T1,AF1>& lhs, const DenseIterator<T2,AF2>& rhs ) noexcept
668{
669 return lhs.base() > rhs.base();
670}
671//*************************************************************************************************
672
673
674//*************************************************************************************************
681template< typename T1 // Element type of the left-hand side iterator
682 , AlignmentFlag AF1 // Alignment flag of the left-hand side iterator
683 , typename T2 // Element type of the right-hand side iterator
684 , AlignmentFlag AF2 > // Alignment flag of the right-hand side iterator
685constexpr bool operator<=( const DenseIterator<T1,AF1>& lhs, const DenseIterator<T2,AF2>& rhs ) noexcept
686{
687 return lhs.base() <= rhs.base();
688}
689//*************************************************************************************************
690
691
692//*************************************************************************************************
699template< typename T1 // Element type of the left-hand side iterator
700 , AlignmentFlag AF1 // Alignment flag of the left-hand side iterator
701 , typename T2 // Element type of the right-hand side iterator
702 , AlignmentFlag AF2 > // Alignment flag of the right-hand side iterator
703constexpr bool operator>=( const DenseIterator<T1,AF1>& lhs, const DenseIterator<T2,AF2>& rhs ) noexcept
704{
705 return lhs.base() >= rhs.base();
706}
707//*************************************************************************************************
708
709
710//*************************************************************************************************
717template< typename Type // Element type of the iterator
718 , AlignmentFlag AF > // Alignment flag of the iterator
719constexpr const DenseIterator<Type,AF> operator+( const DenseIterator<Type,AF>& it, ptrdiff_t inc ) noexcept
720{
721 return DenseIterator<Type,AF>( it.base() + inc );
722}
723//*************************************************************************************************
724
725
726//*************************************************************************************************
733template< typename Type // Element type of the iterator
734 , AlignmentFlag AF > // Alignment flag of the iterator
735constexpr const DenseIterator<Type,AF> operator+( ptrdiff_t inc, const DenseIterator<Type,AF>& it ) noexcept
736{
737 return DenseIterator<Type,AF>( it.base() + inc );
738}
739//*************************************************************************************************
740
741
742//*************************************************************************************************
749template< typename Type // Element type of the iterator
750 , AlignmentFlag AF > // Alignment flag of the iterator
751constexpr const DenseIterator<Type,AF> operator-( const DenseIterator<Type,AF>& it, ptrdiff_t dec ) noexcept
752{
753 return DenseIterator<Type,AF>( it.base() - dec );
754}
755//*************************************************************************************************
756
757
758//*************************************************************************************************
765template< typename Type // Element type of the iterator
766 , AlignmentFlag AF > // Alignment flag of the iterator
767constexpr ptrdiff_t operator-( const DenseIterator<Type,AF>& lhs, const DenseIterator<Type,AF>& rhs ) noexcept
768{
769 return lhs.base() - rhs.base();
770}
771//*************************************************************************************************
772
773} // namespace blaze
774
775#endif
Header file for the alignment check function.
Header file for the alignment flag enumeration.
Header file for run time assertion macros.
constexpr const DenseIterator< Type, AF > operator-(const DenseIterator< Type, AF > &it, ptrdiff_t inc) noexcept
Subtraction between a DenseIterator and an integral value.
Definition: DenseIterator.h:751
constexpr const DenseIterator< Type, AF > operator+(const DenseIterator< Type, AF > &it, ptrdiff_t inc) noexcept
Addition between a DenseIterator and an integral value.
Definition: DenseIterator.h:719
Header file for all SIMD functionality.
Implementation of a generic iterator for dense vectors and matrices.
Definition: DenseIterator.h:60
void storeu(const SIMDType &value) const noexcept
Unaligned store of the SIMD element at the current iterator position.
Definition: DenseIterator.h:521
constexpr ReferenceType operator*() const noexcept
Direct access to the element at the current iterator position.
Definition: DenseIterator.h:347
const SIMDType loadu() const noexcept
Unaligned load of the SIMD element at the current iterator position.
Definition: DenseIterator.h:458
const SIMDType loada() const noexcept
Aligned load of the SIMD element at the current iterator position.
Definition: DenseIterator.h:436
PointerType pointer
Pointer return type.
Definition: DenseIterator.h:72
constexpr DenseIterator & operator-=(ptrdiff_t inc) noexcept
Subtraction assignment operator.
Definition: DenseIterator.h:241
void store(const SIMDType &value) const noexcept
Store of the SIMD element at the current iterator position.
Definition: DenseIterator.h:478
ValueType value_type
Type of the underlying elements.
Definition: DenseIterator.h:71
IteratorCategory iterator_category
The iterator category.
Definition: DenseIterator.h:70
Type & ReferenceType
Reference return type.
Definition: DenseIterator.h:66
Type ValueType
Type of the underlying elements.
Definition: DenseIterator.h:64
void storea(const SIMDType &value) const noexcept
Aligned store of the SIMD element at the current iterator position.
Definition: DenseIterator.h:501
constexpr DenseIterator & operator--() noexcept
Pre-decrement operator.
Definition: DenseIterator.h:293
const SIMDType load() const noexcept
Load of the SIMD element at the current iterator position.
Definition: DenseIterator.h:413
DifferenceType difference_type
Difference between two iterators.
Definition: DenseIterator.h:74
constexpr DenseIterator() noexcept
Default constructor for the DenseIterator class.
Definition: DenseIterator.h:173
void stream(const SIMDType &value) const noexcept
Aligned, non-temporal store of the SIMD element at the current iterator position.
Definition: DenseIterator.h:541
PointerType ptr_
Pointer to the current element.
Definition: DenseIterator.h:153
constexpr PointerType base() const noexcept
Low-level access to the underlying member of the iterator.
Definition: DenseIterator.h:385
Type * PointerType
Pointer return type.
Definition: DenseIterator.h:65
constexpr PointerType operator->() const noexcept
Direct access to the element at the current iterator position.
Definition: DenseIterator.h:362
constexpr DenseIterator & operator+=(ptrdiff_t inc) noexcept
Addition assignment operator.
Definition: DenseIterator.h:224
constexpr ReferenceType operator[](size_t index) const noexcept
Direct access to the underlying elements.
Definition: DenseIterator.h:332
SIMDTrait_t< Type > SIMDType
SIMD type of the elements.
Definition: DenseIterator.h:77
constexpr DenseIterator & operator++() noexcept
Pre-increment operator.
Definition: DenseIterator.h:264
std::random_access_iterator_tag IteratorCategory
The iterator category.
Definition: DenseIterator.h:63
ReferenceType reference
Reference return type.
Definition: DenseIterator.h:73
ptrdiff_t DifferenceType
Difference between two iterators.
Definition: DenseIterator.h:67
constexpr bool operator>(const NegativeAccuracy< A > &lhs, const T &rhs)
Greater-than comparison between a NegativeAccuracy object and a floating point value.
Definition: Accuracy.h:370
constexpr bool operator==(const NegativeAccuracy< A > &lhs, const T &rhs)
Equality comparison between a NegativeAccuracy object and a floating point value.
Definition: Accuracy.h:253
AlignmentFlag
Alignment flag for (un-)aligned vectors and matrices.
Definition: AlignmentFlag.h:63
constexpr bool operator<(const NegativeAccuracy< A > &lhs, const T &rhs)
Less-than comparison between a NegativeAccuracy object and a floating point value.
Definition: Accuracy.h:332
constexpr bool operator>=(const NegativeAccuracy< A > &, const T &rhs)
Greater-or-equal-than comparison between a NegativeAccuracy object and a floating point value.
Definition: Accuracy.h:446
constexpr bool operator!=(const NegativeAccuracy< A > &lhs, const T &rhs)
Inequality comparison between a NegativeAccuracy object and a floating point value.
Definition: Accuracy.h:293
constexpr bool operator<=(const NegativeAccuracy< A > &, const T &rhs)
Less-or-equal-than comparison between a NegativeAccuracy object and a floating point value.
Definition: Accuracy.h:408
#define BLAZE_INTERNAL_ASSERT(expr, msg)
Run time assertion macro for internal checks.
Definition: Assert.h:101
typename SIMDTrait< T >::Type SIMDTrait_t
Auxiliary alias declaration for the SIMDTrait class template.
Definition: SIMDTrait.h:315
BLAZE_ALWAYS_INLINE EnableIf_t< IsIntegral_v< T1 > &&HasSize_v< T1, 1UL > > storea(T1 *address, const SIMDi8< T2 > &value) noexcept
Aligned store of a vector of 1-byte integral values.
Definition: Storea.h:78
BLAZE_ALWAYS_INLINE EnableIf_t< IsIntegral_v< T1 > &&HasSize_v< T1, 1UL > > storeu(T1 *address, const SIMDi8< T2 > &value) noexcept
Unaligned store of a vector of 1-byte integral values.
Definition: Storeu.h:75
BLAZE_ALWAYS_INLINE EnableIf_t< IsIntegral_v< T1 > &&HasSize_v< T1, 1UL > > stream(T1 *address, const SIMDi8< T2 > &value) noexcept
Aligned, non-temporal store of a vector of 1-byte integral values.
Definition: Stream.h:74
BLAZE_ALWAYS_INLINE const EnableIf_t< IsIntegral_v< T > &&HasSize_v< T, 1UL >, If_t< IsSigned_v< T >, SIMDint8, SIMDuint8 > > loadu(const T *address) noexcept
Loads a vector of 1-byte integral values.
Definition: Loadu.h:76
BLAZE_ALWAYS_INLINE const EnableIf_t< IsIntegral_v< T > &&HasSize_v< T, 1UL >, If_t< IsSigned_v< T >, SIMDint8, SIMDuint8 > > loada(const T *address) noexcept
Loads a vector of 1-byte integral values.
Definition: Loada.h:79
BLAZE_ALWAYS_INLINE bool checkAlignment(const T *address)
Checks the alignment of the given address.
Definition: AlignmentCheck.h:68
Header file for basic type definitions.