text: //=================================================================================================
  /*!
  //  \file blaze/math/dense/DenseIterator.h
  //  \brief Header file for the DenseIterator class template
  //
  //  Copyright (C) 2012-2020 Klaus Iglberger - All Rights Reserved
  //
  //  This file is part of the Blaze library. You can redistribute it and/or modify it under
  //
  //  * The names of its contributors may not be used to endorse or promote products derived
  //    from this software without specific prior written permission.
  //
  //  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY
  //  EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
  //  OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
  //  SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
  //  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
  //  TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
  //  BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
  //  CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
  //  ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
  //  DAMAGE.
  */
  //=================================================================================================
  
  #ifndef _BLAZE_MATH_DENSE_DENSEITERATOR_H_
  #define _BLAZE_MATH_DENSE_DENSEITERATOR_H_
  
  
  //*************************************************************************************************
  // Includes
  //*************************************************************************************************
  
  #include <iterator>
  #include <blaze/math/AlignmentFlag.h>
  #include <blaze/math/SIMD.h>
  #include <blaze/util/AlignmentCheck.h>
  #include <blaze/util/Assert.h>
  #include <blaze/util/Types.h>
  
  
  namespace blaze {
  
  //=================================================================================================
  //
  //  CLASS DEFINITION
  //
  //=================================================================================================
  
  //*************************************************************************************************
  /*!\brief Implementation of a generic iterator for dense vectors and matrices.
  // \ingroup math
  //
  // The DenseIterator represents a generic random-access iterator that can be used for dense
  // vectors and specific rows/columns of dense matrices.
  */
  template< typename Type       // Type of the elements
          , AlignmentFlag AF >  // Alignment flag
  class DenseIterator
  {
   public:
     //**Type definitions****************************************************************************
     using IteratorCategory = std::random_access_iterator_tag;  //!< The iterator category.
     using ValueType        = Type;                             //!< Type of the underlying elements.
     using PointerType      = Type*;                            //!< Pointer return type.
     using ReferenceType    = Type&;                            //!< Reference return type.
     using DifferenceType   = ptrdiff_t;                        //!< Difference between two iterators.
  
     // STL iterator requirements
     using iterator_category = IteratorCategory;  //!< The iterator category.
     using value_type        = ValueType;         //!< Type of the underlying elements.
     using pointer           = PointerType;       //!< Pointer return type.
     using reference         = ReferenceType;     //!< Reference return type.
     using difference_type   = DifferenceType;    //!< Difference between two iterators.
  
     //! SIMD type of the elements.
     using SIMDType = SIMDTrait_t<Type>;
     //**********************************************************************************************
  
     //**Constructors********************************************************************************
     /*!\name Constructors */
     //@{
     explicit constexpr DenseIterator() noexcept;
     explicit constexpr DenseIterator( Type* ptr ) noexcept;
  
     template< typename Other, AlignmentFlag AF2 >
     constexpr DenseIterator( const DenseIterator<Other,AF2>& it ) noexcept;
  
     DenseIterator( const DenseIterator& ) = default;
     //@}
     //**********************************************************************************************
  
     //**Destructor**********************************************************************************
     /*!\name Destructor */
     //@{
     ~DenseIterator() = default;
     //@}
     //**********************************************************************************************
  
     //**Assignment operators************************************************************************
     /*!\name Assignment operators */
     //@{
     constexpr DenseIterator& operator+=( ptrdiff_t inc ) noexcept;
     constexpr DenseIterator& operator-=( ptrdiff_t inc ) noexcept;
  
     DenseIterator& operator=( const DenseIterator& ) = default;
     //@}
     //**********************************************************************************************
  
     //**Increment/decrement operators***************************************************************
     /*!\name Increment/decrement operators */
     //@{
     constexpr DenseIterator&      operator++()      noexcept;
     constexpr const DenseIterator operator++( int ) noexcept;
     constexpr DenseIterator&      operator--()      noexcept;
     constexpr const DenseIterator operator--( int ) noexcept;
     //@}
     //**********************************************************************************************
  
     //**Access operators****************************************************************************
     /*!\name Access operators */
     //@{
     constexpr ReferenceType operator[]( size_t index ) const noexcept;
     constexpr ReferenceType operator* () const noexcept;
     constexpr PointerType   operator->() const noexcept;
     //@}
     //**********************************************************************************************
  
     //**Utility functions***************************************************************************
     /*!\name Utility functions */
     //@{
     constexpr PointerType base() const noexcept;
     //@}
     //**********************************************************************************************
  
     //**Expression template evaluation functions****************************************************
     /*!\name Expression template evaluation functions */
     //@{
     inline const SIMDType load  () const noexcept;
     inline const SIMDType loada () const noexcept;
     inline const SIMDType loadu () const noexcept;
     inline void           store ( const SIMDType& value ) const noexcept;
     inline void           storea( const SIMDType& value ) const noexcept;
     inline void           storeu( const SIMDType& value ) const noexcept;
     inline void           stream( const SIMDType& value ) const noexcept;
     //@}
     //**********************************************************************************************
  
   private:
     //**Member variables****************************************************************************
     /*!\name Member variables */
     //@{
     PointerType ptr_;  //!< Pointer to the current element.
     //@}
     //**********************************************************************************************
  };
  //*************************************************************************************************
  
  
  
  
  //=================================================================================================
  //
  //  CONSTRUCTORS
  //
  //=================================================================================================
  
  //*************************************************************************************************
  /*!\brief Default constructor for the DenseIterator class.
  */
  template< typename Type       // Type of the elements
          , AlignmentFlag AF >  // Alignment flag
  constexpr DenseIterator<Type,AF>::DenseIterator() noexcept
     : ptr_( nullptr )  // Pointer to the current element
  {}
  //*************************************************************************************************
  
  
  //*************************************************************************************************
  /*!\brief Constructor for the DenseIterator class.
  //
  // \param ptr Pointer to the initial element.
  */
  template< typename Type       // Type of the elements
          , AlignmentFlag AF >  // Alignment flag
  constexpr DenseIterator<Type,AF>::DenseIterator( Type* ptr ) noexcept
     : ptr_( ptr )  // Pointer to the current element
  {}
  //*************************************************************************************************
  
  
  //*************************************************************************************************
  /*!\brief Conversion constructor from different DenseIterator instances.
  //
  // \param it The foreign DenseIterator instance to be copied.
  */
  template< typename Type        // Type of the elements
          , AlignmentFlag AF >   // Alignment flag
  template< typename Other       // Type of the foreign elements
          , AlignmentFlag AF2 >  // Alignment flag of the foreign iterator
  constexpr DenseIterator<Type,AF>::DenseIterator( const DenseIterator<Other,AF2>& it ) noexcept
     : ptr_( it.base() )  // Pointer to the current element
  {}
  //*************************************************************************************************
  
  
  
  
  //=================================================================================================
  //
  //  ASSIGNMENT OPERATORS
  //
  //=================================================================================================
  
  //*************************************************************************************************
  /*!\brief Addition assignment operator.
  //
  // \param inc The increment of the iterator.
  // \return Reference to the incremented iterator.
  */
  template< typename Type       // Type of the elements
          , AlignmentFlag AF >  // Alignment flag
  constexpr DenseIterator<Type,AF>&
     DenseIterator<Type,AF>::operator+=( ptrdiff_t inc ) noexcept
  {
     ptr_ += inc;
     return *this;
  }
  //*************************************************************************************************
  
  
  //*************************************************************************************************
  /*!\brief Subtraction assignment operator.
  //
  // \param dec The decrement of the iterator.
  // \return Reference to the decremented iterator.
  */
  template< typename Type       // Type of the elements
          , AlignmentFlag AF >  // Alignment flag
  constexpr DenseIterator<Type,AF>&
     DenseIterator<Type,AF>::operator-=( ptrdiff_t dec ) noexcept
  {
     ptr_ -= dec;
     return *this;
  }
  //*************************************************************************************************
  
  
  
  
  //=================================================================================================
  //
  //  INCREMENT/DECREMENT OPERATORS
  //
  //=================================================================================================
  
  //*************************************************************************************************
  /*!\brief Pre-increment operator.
  //
  // \return Reference to the incremented iterator.
  */
  template< typename Type       // Type of the elements
          , AlignmentFlag AF >  // Alignment flag
  constexpr DenseIterator<Type,AF>& DenseIterator<Type,AF>::operator++() noexcept
  {
     ++ptr_;
     return *this;
  }
  //*************************************************************************************************
  
  
  //*************************************************************************************************
  /*!\brief Post-increment operator.
  //
  // \return The previous position of the iterator.
  */
  template< typename Type       // Type of the elements
          , AlignmentFlag AF >  // Alignment flag
  constexpr const DenseIterator<Type,AF> DenseIterator<Type,AF>::operator++( int ) noexcept
  {
     return DenseIterator( ptr_++ );
  }
  //*************************************************************************************************
  
  
  //*************************************************************************************************
  /*!\brief Pre-decrement operator.
  //
  // \return Reference to the decremented iterator.
  */
  template< typename Type       // Type of the elements
          , AlignmentFlag AF >  // Alignment flag
  constexpr DenseIterator<Type,AF>& DenseIterator<Type,AF>::operator--() noexcept
  {
     --ptr_;
     return *this;
  }
  //*************************************************************************************************
  
  
  //*************************************************************************************************
  /*!\brief Post-decrement operator.
  //
  // \return The previous position of the iterator.
  */
  template< typename Type       // Type of the elements
          , AlignmentFlag AF >  // Alignment flag
  constexpr const DenseIterator<Type,AF> DenseIterator<Type,AF>::operator--( int ) noexcept
  {
     return DenseIterator( ptr_-- );
  }
  //*************************************************************************************************
  
  
  
  
  //=================================================================================================
  //
  //  ACCESS OPERATORS
  //
  //=================================================================================================
  
  //*************************************************************************************************
  /*!\brief Direct access to the underlying elements.
  //
  // \param index Access index.
  // \return Reference to the accessed value.
  */
  template< typename Type       // Type of the elements
          , AlignmentFlag AF >  // Alignment flag
  constexpr typename DenseIterator<Type,AF>::ReferenceType
     DenseIterator<Type,AF>::operator[]( size_t index ) const noexcept
  {
     return ptr_[index];
  }
  //*************************************************************************************************
  
  
  //*************************************************************************************************
  /*!\brief Direct access to the element at the current iterator position.
  //
  // \return Reference to the current element.
  */
  template< typename Type       // Type of the elements
          , AlignmentFlag AF >  // Alignment flag
  constexpr typename DenseIterator<Type,AF>::ReferenceType
     DenseIterator<Type,AF>::operator*() const noexcept
  {
     return *ptr_;
  }
  //*************************************************************************************************
  
  
  //*************************************************************************************************
  /*!\brief Direct access to the element at the current iterator position.
  //
  // \return Pointer to the element at the current iterator position.
  */
  template< typename Type       // Type of the elements
          , AlignmentFlag AF >  // Alignment flag
  constexpr typename DenseIterator<Type,AF>::PointerType
     DenseIterator<Type,AF>::operator->() const noexcept
  {
     return ptr_;
  }
  //*************************************************************************************************
  
  
  
  
  //=================================================================================================
  //
  //  UTILITY FUNCTIONS
  //
  //=================================================================================================
  
  //*************************************************************************************************
  /*!\brief Low-level access to the underlying member of the iterator.
  //
  // \return Pointer to the current memory location.
  */
  template< typename Type       // Type of the elements
          , AlignmentFlag AF >  // Alignment flag
  constexpr typename DenseIterator<Type,AF>::PointerType
     DenseIterator<Type,AF>::base() const noexcept
  {
     return ptr_;
  }
  //*************************************************************************************************
  
  
  
  
  //=================================================================================================
  //
  //  EXPRESSION TEMPLATE EVALUATION FUNCTIONS
  //
  //=================================================================================================
  
  //*************************************************************************************************
  /*!\brief Load of the SIMD element at the current iterator position.
  //
  // \return The loaded SIMD element.
  //
  // This function performs a load of the SIMD element of the current element. This function must
  // \b NOT be called explicitly! It is used internally for the performance optimized evaluation
  // of expression templates. Calling this function explicitly might result in erroneous results
  // and/or in compilation errors.
  */
  template< typename Type       // Type of the elements
          , AlignmentFlag AF >  // Alignment flag
  inline const typename DenseIterator<Type,AF>::SIMDType
     DenseIterator<Type,AF>::load() const noexcept
  {
     if( AF )
        return loada();
     else
        return loadu();
  }
  //*************************************************************************************************
  
  
  //*************************************************************************************************
  /*!\brief Aligned load of the SIMD element at the current iterator position.
  //
  // \return The loaded SIMD element.
  //
  // This function performs an aligned load of the SIMD element of the current element. This
  // function must \b NOT be called explicitly! It is used internally for the performance optimized
  // evaluation of expression templates. Calling this function explicitly might result in erroneous
  // results and/or in compilation errors.
  */
  template< typename Type       // Type of the elements
          , AlignmentFlag AF >  // Alignment flag
  inline const typename DenseIterator<Type,AF>::SIMDType
     DenseIterator<Type,AF>::loada() const noexcept
  {
     BLAZE_INTERNAL_ASSERT( checkAlignment( ptr_ ), "Invalid alignment detected" );
  
     return blaze::loada( ptr_ );
  }
  //*************************************************************************************************
  
  
  //*************************************************************************************************
  /*!\brief Unaligned load of the SIMD element at the current iterator position.
  //
  // \return The loaded SIMD element.
  //
  // This function performs an unaligned load of the SIMD element of the current element. This
  // function must \b NOT be called explicitly! It is used internally for the performance optimized
  // evaluation of expression templates. Calling this function explicitly might result in erroneous
  // results and/or in compilation errors.
  */
  template< typename Type       // Type of the elements
          , AlignmentFlag AF >  // Alignment flag
  inline const typename DenseIterator<Type,AF>::SIMDType
     DenseIterator<Type,AF>::loadu() const noexcept
  {
     return blaze::loadu( ptr_ );
  }
  //*************************************************************************************************
  
  
  //*************************************************************************************************
  /*!\brief Store of the SIMD element at the current iterator position.
  //
  // \param value The SIMD element to be stored.
  // \return void
  //
  // This function performs a store of the SIMD element of the current element. This function must
  // \b NOT be called explicitly! It is used internally for the performance optimized evaluation
  // of expression templates. Calling this function explicitly might result in erroneous results
  // and/or in compilation errors.
  */
  template< typename Type       // Type of the elements
          , AlignmentFlag AF >  // Alignment flag
  inline void DenseIterator<Type,AF>::store( const SIMDType& value ) const noexcept
  {
     if( AF )
        storea( value );
     else
        storeu( value );
  }
  //*************************************************************************************************
  
  
  //*************************************************************************************************
  /*!\brief Aligned store of the SIMD element at the current iterator position.
  //
  // \param value The SIMD element to be stored.
  // \return void
  //
  // This function performs an aligned store of the SIMD element of the current element. This
  // function must \b NOT be called explicitly! It is used internally for the performance optimized
  // evaluation of expression templates. Calling this function explicitly might result in erroneous
  // results and/or in compilation errors.
  */
  template< typename Type       // Type of the elements
          , AlignmentFlag AF >  // Alignment flag
  inline void DenseIterator<Type,AF>::storea( const SIMDType& value ) const noexcept
  {
     blaze::storea( ptr_, value );
  }
  //*************************************************************************************************
  
  
  //*************************************************************************************************
  /*!\brief Unaligned store of the SIMD element at the current iterator position.
  //
  // \param value The SIMD element to be stored.
  // \return void
  //
  // This function performs an unaligned store of the SIMD element of the current element. This
  // function must \b NOT be called explicitly! It is used internally for the performance optimized
  // evaluation of expression templates. Calling this function explicitly might result in erroneous
  // results and/or in compilation errors.
  */
  template< typename Type       // Type of the elements
          , AlignmentFlag AF >  // Alignment flag
  inline void DenseIterator<Type,AF>::storeu( const SIMDType& value ) const noexcept
  {
     blaze::storeu( ptr_, value );
  }
  //*************************************************************************************************
  
  
  //*************************************************************************************************
  /*!\brief Aligned, non-temporal store of the SIMD element at the current iterator position.
  //
  // \param value The SIMD element to be stored.
  // \return void
  //
  // This function performs an aligned, non-temporal store of the SIMD element of the current
  // element. This function must \b NOT be called explicitly! It is used internally for the
  // performance optimized evaluation of expression templates. Calling this function explicitly
  // might result in erroneous results and/or in compilation errors.
  */
  template< typename Type       // Type of the elements
          , AlignmentFlag AF >  // Alignment flag
  inline void DenseIterator<Type,AF>::stream( const SIMDType& value ) const noexcept
  {
     blaze::stream( ptr_, value );
  }
  //*************************************************************************************************
  
  
  
  
  //=================================================================================================
  //
  //  GLOBAL OPERATORS
  //
  //=================================================================================================
  
  //*************************************************************************************************
  /*!\name DenseIterator operators */
  //@{
  template< typename T1, AlignmentFlag AF1, typename T2, AlignmentFlag AF2 >
  constexpr bool
     operator==( const DenseIterator<T1,AF1>& lhs, const DenseIterator<T2,AF2>& rhs ) noexcept;
  
  template< typename T1, AlignmentFlag AF1, typename T2, AlignmentFlag AF2 >
  constexpr bool
     operator!=( const DenseIterator<T1,AF1>& lhs, const DenseIterator<T2,AF2>& rhs ) noexcept;
  
  template< typename T1, AlignmentFlag AF1, typename T2, AlignmentFlag AF2 >
  constexpr bool
     operator<( const DenseIterator<T1,AF1>& lhs, const DenseIterator<T2,AF2>& rhs ) noexcept;
  
  template< typename T1, AlignmentFlag AF1, typename T2, AlignmentFlag AF2 >
  constexpr bool
     operator>( const DenseIterator<T1,AF1>& lhs, const DenseIterator<T2,AF2>& rhs ) noexcept;
  
  template< typename T1, AlignmentFlag AF1, typename T2, AlignmentFlag AF2 >
  constexpr bool
     operator<=( const DenseIterator<T1,AF1>& lhs, const DenseIterator<T2,AF2>& rhs ) noexcept;
  
  template< typename T1, AlignmentFlag AF1, typename T2, AlignmentFlag AF2 >
  constexpr bool
     operator>=( const DenseIterator<T1,AF1>& lhs, const DenseIterator<T2,AF2>& rhs ) noexcept;
  
  template< typename Type, AlignmentFlag AF >
  constexpr const DenseIterator<Type,AF>
     operator+( const DenseIterator<Type,AF>& it, ptrdiff_t inc ) noexcept;
  
  template< typename Type, AlignmentFlag AF >
  constexpr const DenseIterator<Type,AF>
     operator+( ptrdiff_t inc, const DenseIterator<Type,AF>& it ) noexcept;
  
  template< typename Type, AlignmentFlag AF >
  constexpr const DenseIterator<Type,AF>
     operator-( const DenseIterator<Type,AF>& it, ptrdiff_t inc ) noexcept;
  
  template< typename Type, AlignmentFlag AF >
  constexpr ptrdiff_t
     operator-( const DenseIterator<Type,AF>& lhs, const DenseIterator<Type,AF>& rhs ) noexcept;
  //@}
  //*************************************************************************************************
  
  
  //*************************************************************************************************
  /*!\brief Equality comparison between two DenseIterator objects.
  //
  // \param lhs The left-hand side iterator.
  // \param rhs The right-hand side iterator.
  // \return \a true if the iterators refer to the same element, \a false if not.
  */
  template< typename T1          // Element type of the left-hand side iterator
          , AlignmentFlag AF1    // Alignment flag of the left-hand side iterator
          , typename T2          // Element type of the right-hand side iterator
          , AlignmentFlag AF2 >  // Alignment flag of the right-hand side iterator
  constexpr bool operator==( const DenseIterator<T1,AF1>& lhs, const DenseIterator<T2,AF2>& rhs ) noexcept
  {
     return lhs.base() == rhs.base();
  }
  //*************************************************************************************************
  
  
  //*************************************************************************************************
  /*!\brief Inequality comparison between two DenseIterator objects.
  //
  // \param lhs The left-hand side iterator.
  // \param rhs The right-hand side iterator.
  // \return \a true if the iterators don't refer to the same element, \a false if they do.
  */
  template< typename T1          // Element type of the left-hand side iterator
          , AlignmentFlag AF1    // Alignment flag of the left-hand side iterator
          , typename T2          // Element type of the right-hand side iterator
          , AlignmentFlag AF2 >  // Alignment flag of the right-hand side iterator
  constexpr bool operator!=( const DenseIterator<T1,AF1>& lhs, const DenseIterator<T2,AF2>& rhs ) noexcept
  {
     return lhs.base() != rhs.base();
  }
  //*************************************************************************************************
  
  
  //*************************************************************************************************
  /*!\brief Less-than comparison between two DenseIterator objects.
  //
  // \param lhs The left-hand side iterator.
  // \param rhs The right-hand side iterator.
  // \return \a true if the left-hand side iterator is smaller, \a false if not.
  */
  template< typename T1          // Element type of the left-hand side iterator
          , AlignmentFlag AF1    // Alignment flag of the left-hand side iterator
          , typename T2          // Element type of the right-hand side iterator
          , AlignmentFlag AF2 >  // Alignment flag of the right-hand side iterator
  constexpr bool operator<( const DenseIterator<T1,AF1>& lhs, const DenseIterator<T2,AF2>& rhs ) noexcept
  {
     return lhs.base() < rhs.base();
  }
  //*************************************************************************************************
  
  
  //*************************************************************************************************
  /*!\brief Greater-than comparison between two DenseIterator objects.
  //
  // \param lhs The left-hand side iterator.
  // \param rhs The right-hand side iterator.
  // \return \a true if the left-hand side iterator is greater, \a false if not.
  */
  template< typename T1          // Element type of the left-hand side iterator
          , AlignmentFlag AF1    // Alignment flag of the left-hand side iterator
          , typename T2          // Element type of the right-hand side iterator
          , AlignmentFlag AF2 >  // Alignment flag of the right-hand side iterator
  constexpr bool operator>( const DenseIterator<T1,AF1>& lhs, const DenseIterator<T2,AF2>& rhs ) noexcept
  {
     return lhs.base() > rhs.base();
  }
  //*************************************************************************************************
  
  
  //*************************************************************************************************
  /*!\brief Less-or-equal-than comparison between two DenseIterator objects.
  //
  // \param lhs The left-hand side iterator.
  // \param rhs The right-hand side iterator.
  // \return \a true if the left-hand side iterator is less or equal, \a false if not.
  */
  template< typename T1          // Element type of the left-hand side iterator
          , AlignmentFlag AF1    // Alignment flag of the left-hand side iterator
          , typename T2          // Element type of the right-hand side iterator
          , AlignmentFlag AF2 >  // Alignment flag of the right-hand side iterator
  constexpr bool operator<=( const DenseIterator<T1,AF1>& lhs, const DenseIterator<T2,AF2>& rhs ) noexcept
  {
     return lhs.base() <= rhs.base();
  }
  //*************************************************************************************************
  
  
  //*************************************************************************************************
  /*!\brief Greater-or-equal-than comparison between two DenseIterator objects.
  //
  // \param lhs The left-hand side iterator.
  // \param rhs The right-hand side iterator.
  // \return \a true if the left-hand side iterator is greater or equal, \a false if not.
  */
  template< typename T1          // Element type of the left-hand side iterator
          , AlignmentFlag AF1    // Alignment flag of the left-hand side iterator
          , typename T2          // Element type of the right-hand side iterator
          , AlignmentFlag AF2 >  // Alignment flag of the right-hand side iterator
  constexpr bool operator>=( const DenseIterator<T1,AF1>& lhs, const DenseIterator<T2,AF2>& rhs ) noexcept
  {
     return lhs.base() >= rhs.base();
  }
  //*************************************************************************************************
  
  
  //*************************************************************************************************
  /*!\brief Addition between a DenseIterator and an integral value.
  //
  // \param it The iterator to be incremented.
  // \param inc The number of elements the iterator is incremented.
  // \return The incremented iterator.
  */
  template< typename Type       // Element type of the iterator
          , AlignmentFlag AF >  // Alignment flag of the iterator
  constexpr const DenseIterator<Type,AF> operator+( const DenseIterator<Type,AF>& it, ptrdiff_t inc ) noexcept
  {
     return DenseIterator<Type,AF>( it.base() + inc );
  }
  //*************************************************************************************************
  
  
  //*************************************************************************************************
  /*!\brief Addition between an integral value and a DenseIterator.
  //
  // \param inc The number of elements the iterator is incremented.
  // \param it The iterator to be incremented.
  // \return The incremented iterator.
  */
  template< typename Type       // Element type of the iterator
          , AlignmentFlag AF >  // Alignment flag of the iterator
  constexpr const DenseIterator<Type,AF> operator+( ptrdiff_t inc, const DenseIterator<Type,AF>& it ) noexcept
  {
     return DenseIterator<Type,AF>( it.base() + inc );
  }
  //*************************************************************************************************
  
  
  //*************************************************************************************************
  /*!\brief Subtraction between a DenseIterator and an integral value.
  //
  // \param it The iterator to be decremented.
  // \param dec The number of elements the iterator is decremented.
  // \return The decremented iterator.
  */
  template< typename Type       // Element type of the iterator
          , AlignmentFlag AF >  // Alignment flag of the iterator
  constexpr const DenseIterator<Type,AF> operator-( const DenseIterator<Type,AF>& it, ptrdiff_t dec ) noexcept
  {
     return DenseIterator<Type,AF>( it.base() - dec );
  }
  //*************************************************************************************************
  
  
  //*************************************************************************************************
  /*!\brief Calculating the number of elements between two DenseIterator objects.
  //
  // \param lhs The left-hand side iterator.
  // \param rhs The right-hand side iterator.
  // \return The number of elements between the two iterators.
  */
  template< typename Type       // Element type of the iterator
          , AlignmentFlag AF >  // Alignment flag of the iterator
  constexpr ptrdiff_t operator-( const DenseIterator<Type,AF>& lhs, const DenseIterator<Type,AF>& rhs ) noexcept
  {
     return lhs.base() - rhs.base();
  }
  //*************************************************************************************************
  
  } // namespace blaze
  
  #endif
  