From 1cd288897218a7f72d3a9ab07ca3f2173d7619fe Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Tom=C3=A1=C5=A1=20Oberhuber?= <oberhuber.tomas@gmail.com>
Date: Tue, 6 Apr 2021 15:14:25 +0200
Subject: [PATCH] Added segment element and segment view iterator.

---
 src/TNL/Algorithms/Segments/SegmentElement.h  | 57 +++++++++++++
 src/TNL/Algorithms/Segments/SegmentView.h     | 69 +++++++++++++++
 .../Algorithms/Segments/SegmentViewIterator.h | 84 +++++++++++++++++++
 .../Segments/SegmentViewIterator.hpp          | 83 ++++++++++++++++++
 src/TNL/Matrices/MatrixRowViewIterator.hpp    |  2 +-
 5 files changed, 294 insertions(+), 1 deletion(-)
 create mode 100644 src/TNL/Algorithms/Segments/SegmentElement.h
 create mode 100644 src/TNL/Algorithms/Segments/SegmentViewIterator.h
 create mode 100644 src/TNL/Algorithms/Segments/SegmentViewIterator.hpp

diff --git a/src/TNL/Algorithms/Segments/SegmentElement.h b/src/TNL/Algorithms/Segments/SegmentElement.h
new file mode 100644
index 0000000000..68088ba22c
--- /dev/null
+++ b/src/TNL/Algorithms/Segments/SegmentElement.h
@@ -0,0 +1,57 @@
+/***************************************************************************
+                          SegmentElement.h -  description
+                             -------------------
+    begin                : Apr 5, 2021
+    copyright            : (C) 2021 by Tomas Oberhuber
+    email                : tomas.oberhuber@fjfi.cvut.cz
+ ***************************************************************************/
+
+/* See Copyright Notice in tnl/Copyright */
+
+#pragma once
+
+#include <ostream>
+
+#include <TNL/Cuda/CudaCallable.h>
+
+namespace TNL {
+   namespace Algorithms {
+      namespace Segments {
+
+
+template< typename Index >
+class SegmentElement
+{
+   public:
+
+      using IndexType = Index;
+
+      __cuda_callable__
+      SegmentElement( const IndexType& segmentIdx,
+                      const IndexType& localIdx,
+                      const IndexType globalIdx )
+      : segmentIdx( segmentIdx ), localIdx( localIdx ), globalIdx( globalIdx ) {};
+
+      __cuda_callable__
+      const IndexType& segmentIndex() const { return segmentIdx; };
+
+      __cuda_callable__
+      const IndexType& localIndex() const { return localIdx; };
+
+      __cuda_callable__
+      const IndexType& globalIndex() const { return globalIdx; };
+
+   protected:
+
+      const IndexType& segmentIdx;
+
+      const IndexType& localIdx;
+
+      const IndexType globalIdx;
+
+
+};
+
+      } // namespace Segments
+   } // namespace Algorithms
+} // namespace TNL
diff --git a/src/TNL/Algorithms/Segments/SegmentView.h b/src/TNL/Algorithms/Segments/SegmentView.h
index ecf1c95f6e..399e3ddd14 100644
--- a/src/TNL/Algorithms/Segments/SegmentView.h
+++ b/src/TNL/Algorithms/Segments/SegmentView.h
@@ -11,6 +11,7 @@
 #pragma once
 
 #include <TNL/Algorithms/Segments/ElementsOrganization.h>
+#include <TNL/Algorithms/Segments/SegmentViewIterator.h>
 
 namespace TNL {
    namespace Algorithms {
@@ -27,6 +28,8 @@ class SegmentView< Index, ColumnMajorOrder >
 
       using IndexType = Index;
 
+      using IteratorType = SegmentViewIterator< SegmentView >;
+
       __cuda_callable__
       SegmentView( const IndexType segmentIdx,
                    const IndexType offset,
@@ -57,6 +60,38 @@ class SegmentView< Index, ColumnMajorOrder >
          return this->segmentIdx;
       };
 
+      /**
+       * \brief Returns iterator pointing at the beginning of the segment.
+       *
+       * \return iterator pointing at the beginning.
+       */
+      __cuda_callable__
+      IteratorType begin() const { return IteratorType( *this, 0 ); };
+
+      /**
+       * \brief Returns iterator pointing at the end of the segment.
+       *
+       * \return iterator pointing at the end.
+       */
+      __cuda_callable__
+      IteratorType end() const { return IteratorType( *this, this->getSize() ); };
+
+      /**
+       * \brief Returns constant iterator pointing at the beginning of the segment.
+       *
+       * \return iterator pointing at the beginning.
+       */
+      __cuda_callable__
+      const IteratorType cbegin() const { return IteratorType( *this, 0 ); };
+
+      /**
+       * \brief Returns constant iterator pointing at the end of the segment.
+       *
+       * \return iterator pointing at the end.
+       */
+      __cuda_callable__
+      const IteratorType cend() const { return IteratorType( *this, this->getSize() ); };
+
       protected:
 
          IndexType segmentIdx, segmentOffset, segmentSize, step;
@@ -69,6 +104,8 @@ class SegmentView< Index, RowMajorOrder >
 
       using IndexType = Index;
 
+      using IteratorType = SegmentViewIterator< SegmentView >;
+
       __cuda_callable__
       SegmentView( const IndexType segmentIdx,
                    const IndexType offset,
@@ -95,6 +132,38 @@ class SegmentView< Index, RowMajorOrder >
          return this->segmentIdx;
       };
 
+      /**
+       * \brief Returns iterator pointing at the beginning of the segment.
+       *
+       * \return iterator pointing at the beginning.
+       */
+      __cuda_callable__
+      IteratorType begin() const { return IteratorType( *this, 0 ); };
+
+      /**
+       * \brief Returns iterator pointing at the end of the segment.
+       *
+       * \return iterator pointing at the end.
+       */
+      __cuda_callable__
+      IteratorType end() const { return IteratorType( *this, this->getSize() ); };
+
+      /**
+       * \brief Returns constant iterator pointing at the beginning of the segment.
+       *
+       * \return iterator pointing at the beginning.
+       */
+      __cuda_callable__
+      const IteratorType cbegin() const { return IteratorType( *this, 0 ); };
+
+      /**
+       * \brief Returns constant iterator pointing at the end of the segment.
+       *
+       * \return iterator pointing at the end.
+       */
+      __cuda_callable__
+      const IteratorType cend() const { return IteratorType( *this, this->getSize() ); };
+
       protected:
 
          IndexType segmentIdx, segmentOffset, segmentSize;
diff --git a/src/TNL/Algorithms/Segments/SegmentViewIterator.h b/src/TNL/Algorithms/Segments/SegmentViewIterator.h
new file mode 100644
index 0000000000..335ce91aa1
--- /dev/null
+++ b/src/TNL/Algorithms/Segments/SegmentViewIterator.h
@@ -0,0 +1,84 @@
+ /***************************************************************************
+                          SegmentViewIterator.h -  description
+                             -------------------
+    begin                : Apr 5, 2021
+    copyright            : (C) 2021 by Tomas Oberhuber
+    email                : tomas.oberhuber@fjfi.cvut.cz
+ ***************************************************************************/
+
+/* See Copyright Notice in tnl/Copyright */
+
+#pragma once
+
+#include <ostream>
+
+#include <TNL/Cuda/CudaCallable.h>
+#include <TNL/Algorithms/Segments/SegmentElement.h>
+
+namespace TNL {
+   namespace Algorithms {
+      namespace Segments {
+
+template< typename SegmentView >
+class SegmentViewIterator
+{
+   public:
+
+      /**
+       * \brief Type of SegmentView
+       */
+      using SegmentViewType = SegmentView;
+
+      /**
+       * \brief The type used for matrix elements indexing.
+       */
+      using IndexType = typename SegmentViewType::IndexType;
+
+      /**
+       * \brief The type of related matrix element.
+       */
+      using SegmentElementType = SegmentElement< IndexType >;
+
+      __cuda_callable__
+      SegmentViewIterator( const SegmentViewType& segmentView,
+                           const IndexType& localIdx );
+
+      /**
+       * \brief Comparison of two matrix Segment iterators.
+       *
+       * \param other is another matrix Segment iterator.
+       * \return \e true if both iterators points at the same point of the same matrix, \e false otherwise.
+       */
+      __cuda_callable__
+      bool operator==( const SegmentViewIterator& other ) const;
+
+      /**
+       * \brief Comparison of two matrix Segment iterators.
+       *
+       * \param other is another matrix Segment iterator.
+       * \return \e false if both iterators points at the same point of the same matrix, \e true otherwise.
+       */
+      __cuda_callable__
+      bool operator!=( const SegmentViewIterator& other ) const;
+
+      __cuda_callable__
+      SegmentViewIterator& operator++();
+
+      __cuda_callable__
+      SegmentViewIterator& operator--();
+
+      __cuda_callable__
+      const SegmentElementType operator*() const;
+
+   protected:
+
+      const SegmentViewType& segmentView;
+
+      IndexType localIdx = 0;
+};
+
+      } // namespace Segments
+   } // namespace Algorithms
+} // namespace TNL
+
+#include <TNL/Algorithms/Segments/SegmentViewIterator.hpp>
diff --git a/src/TNL/Algorithms/Segments/SegmentViewIterator.hpp b/src/TNL/Algorithms/Segments/SegmentViewIterator.hpp
new file mode 100644
index 0000000000..47154da99e
--- /dev/null
+++ b/src/TNL/Algorithms/Segments/SegmentViewIterator.hpp
@@ -0,0 +1,83 @@
+/***************************************************************************
+                          SegmentViewIterator.hpp -  description
+                             -------------------
+    begin                : Apr 5, 2021
+    copyright            : (C) 2021 by Tomas Oberhuber
+    email                : tomas.oberhuber@fjfi.cvut.cz
+ ***************************************************************************/
+
+/* See Copyright Notice in tnl/Copyright */
+
+#pragma once
+
+#include <TNL/Algorithms/Segments/SegmentView.h>
+#include <TNL/Assert.h>
+
+namespace TNL {
+   namespace Algorithms {
+      namespace Segments {
+
+template< typename SegmentView >
+__cuda_callable__
+SegmentViewIterator< SegmentView >::
+SegmentViewIterator( const SegmentViewType& segmentView,
+                     const IndexType& localIdx )
+: segmentView( segmentView ), localIdx( localIdx )
+{
+}
+
+template< typename SegmentView >
+__cuda_callable__ bool
+SegmentViewIterator< SegmentView >::
+operator==( const SegmentViewIterator& other ) const
+{
+   if( &this->segmentView == &other.segmentView &&
+       localIdx == other.localIdx )
+      return true;
+   return false;
+}
+
+template< typename SegmentView >
+__cuda_callable__ bool
+SegmentViewIterator< SegmentView >::
+operator!=( const SegmentViewIterator& other ) const
+{
+   return ! ( other == *this );
+}
+
+template< typename SegmentView >
+__cuda_callable__
+SegmentViewIterator< SegmentView >&
+SegmentViewIterator< SegmentView >::
+operator++()
+{
+   if( localIdx < segmentView.getSize() )
+      localIdx ++;
+   return *this;
+}
+
+template< typename SegmentView >
+__cuda_callable__
+SegmentViewIterator< SegmentView >&
+SegmentViewIterator< SegmentView >::
+operator--()
+{
+   if( localIdx > 0 )
+      localIdx --;
+   return *this;
+}
+
+template< typename SegmentView >
+__cuda_callable__ auto
+SegmentViewIterator< SegmentView >::
+operator*() const -> const SegmentElementType
+{
+   return SegmentElementType(
+      this->segmentView.getSegmentIndex(),
+      this->localIdx,
+      this->segmentView.getGlobalIndex( this->localIdx ) );
+}
+
+      } // namespace Segments
+   } // namespace Algorithms
+} // namespace TNL
diff --git a/src/TNL/Matrices/MatrixRowViewIterator.hpp b/src/TNL/Matrices/MatrixRowViewIterator.hpp
index 7b233e47b0..7d217bc7af 100644
--- a/src/TNL/Matrices/MatrixRowViewIterator.hpp
+++ b/src/TNL/Matrices/MatrixRowViewIterator.hpp
@@ -1,5 +1,5 @@
 /***************************************************************************
-                          SparseMatrixRowView.hpp -  description
+                          MatrixRowViewIterator.hpp -  description
                              -------------------
     begin                : Mar 20, 2021
     copyright            : (C) 2021 by Tomas Oberhuber
-- 
GitLab