From 4df14dcb1b595a09a17a1e196f365142e01ec192 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Tom=C3=A1=C5=A1=20Oberhuber?= <oberhuber.tomas@gmail.com>
Date: Sun, 18 Apr 2021 12:38:34 +0200
Subject: [PATCH] Added method print to Segments for better use with output
 streams.

---
 .../SegmentsExample_CSR_constructor_1.cpp     |  2 +-
 .../SegmentsExample_CSR_constructor_2.cpp     |  2 +-
 .../SegmentsExample_CSR_forElements.cpp       |  2 +-
 .../SegmentsExample_CSR_forSegments.cpp       |  2 +-
 .../Segments/SegmentsExample_General.cpp      |  2 +-
 .../Segments/SegmentsExample_forElements.cpp  |  4 ++--
 .../SegmentsExample_forSegments-1.cpp         |  2 +-
 .../SegmentsExample_forSegments-2.cpp         |  4 ++--
 .../SegmentsExample_reduceSegments.cpp        |  2 +-
 .../Segments/SegmentsPrintingExample-2.cpp    |  2 +-
 src/TNL/Algorithms/Segments/BiEllpack.h       |  3 +++
 src/TNL/Algorithms/Segments/BiEllpack.hpp     | 13 ++++++++++
 src/TNL/Algorithms/Segments/BiEllpackView.h   |  3 +++
 src/TNL/Algorithms/Segments/BiEllpackView.hpp | 12 ++++++++++
 src/TNL/Algorithms/Segments/CSR.h             | 21 ++++++++++++++++
 src/TNL/Algorithms/Segments/CSR.hpp           | 12 ++++++++++
 src/TNL/Algorithms/Segments/CSRView.h         |  3 +++
 src/TNL/Algorithms/Segments/CSRView.hpp       | 12 ++++++++++
 src/TNL/Algorithms/Segments/ChunkedEllpack.h  |  3 +++
 .../Algorithms/Segments/ChunkedEllpack.hpp    | 12 ++++++++++
 .../Algorithms/Segments/ChunkedEllpackView.h  |  3 +++
 .../Segments/ChunkedEllpackView.hpp           | 12 ++++++++++
 src/TNL/Algorithms/Segments/Ellpack.h         |  3 +++
 src/TNL/Algorithms/Segments/Ellpack.hpp       | 13 ++++++++++
 src/TNL/Algorithms/Segments/EllpackView.h     |  3 +++
 src/TNL/Algorithms/Segments/EllpackView.hpp   | 12 ++++++++++
 .../Algorithms/Segments/SegmentsPrinting.h    | 24 +++++++++++++++++++
 src/TNL/Algorithms/Segments/SlicedEllpack.h   |  3 +++
 src/TNL/Algorithms/Segments/SlicedEllpack.hpp | 13 ++++++++++
 .../Algorithms/Segments/SlicedEllpackView.h   |  3 +++
 .../Algorithms/Segments/SlicedEllpackView.hpp | 12 ++++++++++
 31 files changed, 207 insertions(+), 12 deletions(-)

diff --git a/Documentation/Examples/Algorithms/Segments/SegmentsExample_CSR_constructor_1.cpp b/Documentation/Examples/Algorithms/Segments/SegmentsExample_CSR_constructor_1.cpp
index 0ceb7a6bd4..ed25d6df47 100644
--- a/Documentation/Examples/Algorithms/Segments/SegmentsExample_CSR_constructor_1.cpp
+++ b/Documentation/Examples/Algorithms/Segments/SegmentsExample_CSR_constructor_1.cpp
@@ -35,7 +35,7 @@ void SegmentsExample()
     * Print the data managed by the segments.
     */
    auto fetch = [=] __cuda_callable__ ( int globalIdx ) -> double { return data_view[ globalIdx ]; };
-   printSegments( segments, fetch, std::cout );
+   std::cout << segments.print( fetch ) << std::endl;
 }
 
 int main( int argc, char* argv[] )
diff --git a/Documentation/Examples/Algorithms/Segments/SegmentsExample_CSR_constructor_2.cpp b/Documentation/Examples/Algorithms/Segments/SegmentsExample_CSR_constructor_2.cpp
index 9493758b49..a71c51519e 100644
--- a/Documentation/Examples/Algorithms/Segments/SegmentsExample_CSR_constructor_2.cpp
+++ b/Documentation/Examples/Algorithms/Segments/SegmentsExample_CSR_constructor_2.cpp
@@ -34,7 +34,7 @@ void SegmentsExample()
     * Print the data managed by the segments.
     */
    auto fetch = [=] __cuda_callable__ ( int globalIdx ) -> double { return data_view[ globalIdx ]; };
-   printSegments( segments, fetch, std::cout );
+   std::cout << segments.print( fetch ) << std::endl;
 }
 
 int main( int argc, char* argv[] )
diff --git a/Documentation/Examples/Algorithms/Segments/SegmentsExample_CSR_forElements.cpp b/Documentation/Examples/Algorithms/Segments/SegmentsExample_CSR_forElements.cpp
index 37267a889f..2649980462 100644
--- a/Documentation/Examples/Algorithms/Segments/SegmentsExample_CSR_forElements.cpp
+++ b/Documentation/Examples/Algorithms/Segments/SegmentsExample_CSR_forElements.cpp
@@ -33,7 +33,7 @@ void SegmentsExample()
     * Print the data managed by the segments.
     */
    auto fetch = [=] __cuda_callable__ ( int globalIdx ) -> double { return data_view[ globalIdx ]; };
-   printSegments( segments, fetch, std::cout );
+   std::cout << segments.print( fetch ) << std::endl;
 }
 
 int main( int argc, char* argv[] )
diff --git a/Documentation/Examples/Algorithms/Segments/SegmentsExample_CSR_forSegments.cpp b/Documentation/Examples/Algorithms/Segments/SegmentsExample_CSR_forSegments.cpp
index 3bf7cc50bd..f2eb0ae13a 100644
--- a/Documentation/Examples/Algorithms/Segments/SegmentsExample_CSR_forSegments.cpp
+++ b/Documentation/Examples/Algorithms/Segments/SegmentsExample_CSR_forSegments.cpp
@@ -36,7 +36,7 @@ void SegmentsExample()
     * Print the data managed by the segments.
     */
    auto fetch = [=] __cuda_callable__ ( int globalIdx ) -> double { return data_view[ globalIdx ]; };
-   printSegments( segments, fetch, std::cout );
+   std::cout << segments.print( fetch ) << std::endl;
 }
 
 int main( int argc, char* argv[] )
diff --git a/Documentation/Examples/Algorithms/Segments/SegmentsExample_General.cpp b/Documentation/Examples/Algorithms/Segments/SegmentsExample_General.cpp
index ade0263fbc..7e4aced7ea 100644
--- a/Documentation/Examples/Algorithms/Segments/SegmentsExample_General.cpp
+++ b/Documentation/Examples/Algorithms/Segments/SegmentsExample_General.cpp
@@ -36,7 +36,7 @@ void SegmentsExample()
     * Print the data managed by the segments.
     */
    auto fetch = [=] __cuda_callable__ ( IndexType globalIdx ) -> double { return data_view[ globalIdx ]; };
-   printSegments( segments, fetch, std::cout );
+   std::cout << segments.print( fetch ) << std::endl;
 
    /***
     * Compute sums of elements in particular segments.
diff --git a/Documentation/Examples/Algorithms/Segments/SegmentsExample_forElements.cpp b/Documentation/Examples/Algorithms/Segments/SegmentsExample_forElements.cpp
index 8b34501678..621a2123ae 100644
--- a/Documentation/Examples/Algorithms/Segments/SegmentsExample_forElements.cpp
+++ b/Documentation/Examples/Algorithms/Segments/SegmentsExample_forElements.cpp
@@ -34,7 +34,7 @@ void SegmentsExample()
    std::cout << "Data setup with no check ... " << std::endl;
    std::cout << "Array: " << data << std::endl;
    auto fetch = [=] __cuda_callable__ ( int globalIdx ) -> double { return data_view[ globalIdx ]; };
-   printSegments( segments, fetch, std::cout ) << std::endl;
+   std::cout << segments.print( fetch ) << std::endl;
 
    /***
     * Insert data into particular segments.
@@ -50,7 +50,7 @@ void SegmentsExample()
     */
    std::cout << "Data setup with check for padding elements..." << std::endl;
    std::cout << "Array: " << data << std::endl;
-   printSegments( segments, fetch, std::cout ) << std::endl;
+   std::cout << segments.print( fetch ) << std::endl;
 }
 
 int main( int argc, char* argv[] )
diff --git a/Documentation/Examples/Algorithms/Segments/SegmentsExample_forSegments-1.cpp b/Documentation/Examples/Algorithms/Segments/SegmentsExample_forSegments-1.cpp
index d8be1f04c7..fa81662e8a 100644
--- a/Documentation/Examples/Algorithms/Segments/SegmentsExample_forSegments-1.cpp
+++ b/Documentation/Examples/Algorithms/Segments/SegmentsExample_forSegments-1.cpp
@@ -39,7 +39,7 @@ void SegmentsExample()
     * Print the data managed by the segments.
     */
    auto fetch = [=] __cuda_callable__ ( int globalIdx ) -> double { return data_view[ globalIdx ]; };
-   printSegments( segments, fetch, std::cout );
+   std::cout << segments.print( fetch ) << std::endl;
 }
 
 int main( int argc, char* argv[] )
diff --git a/Documentation/Examples/Algorithms/Segments/SegmentsExample_forSegments-2.cpp b/Documentation/Examples/Algorithms/Segments/SegmentsExample_forSegments-2.cpp
index a5d7d0caa9..0439b846a1 100644
--- a/Documentation/Examples/Algorithms/Segments/SegmentsExample_forSegments-2.cpp
+++ b/Documentation/Examples/Algorithms/Segments/SegmentsExample_forSegments-2.cpp
@@ -33,7 +33,7 @@ void SegmentsExample()
     */
    std::cout << "Values of elements after intial setup: " << std::endl;
    auto fetch = [=] __cuda_callable__ ( int globalIdx ) -> double { return data_view[ globalIdx ]; };
-   printSegments( segments, fetch, std::cout );
+   std::cout << segments.print( fetch );
 
    /***
     * Divide elements in each segment by a sum of all elements in the segment
@@ -55,7 +55,7 @@ void SegmentsExample()
     * Print the data managed by the segments.
     */
    std::cout << "Value of elements after dividing by sum in each segment:" << std::endl;
-   printSegments( segments, fetch, std::cout );
+   std::cout << segments.print( fetch ) << std::endl;
 }
 
 int main( int argc, char* argv[] )
diff --git a/Documentation/Examples/Algorithms/Segments/SegmentsExample_reduceSegments.cpp b/Documentation/Examples/Algorithms/Segments/SegmentsExample_reduceSegments.cpp
index c9a7476c72..e6701f36bb 100644
--- a/Documentation/Examples/Algorithms/Segments/SegmentsExample_reduceSegments.cpp
+++ b/Documentation/Examples/Algorithms/Segments/SegmentsExample_reduceSegments.cpp
@@ -36,7 +36,7 @@ void SegmentsExample()
     */
    std::cout << "Values of elements after intial setup: " << std::endl;
    auto fetch = [=] __cuda_callable__ ( int globalIdx ) -> double { return data_view[ globalIdx ]; };
-   printSegments( segments, fetch, std::cout );
+   std::cout << segments.print( fetch ) << std::endl;
 
    /***
     * Compute sums of elements in each segment.
diff --git a/Documentation/Examples/Algorithms/Segments/SegmentsPrintingExample-2.cpp b/Documentation/Examples/Algorithms/Segments/SegmentsPrintingExample-2.cpp
index 8d98455a57..73d2e415d7 100644
--- a/Documentation/Examples/Algorithms/Segments/SegmentsPrintingExample-2.cpp
+++ b/Documentation/Examples/Algorithms/Segments/SegmentsPrintingExample-2.cpp
@@ -32,7 +32,7 @@ void SegmentsExample()
     */
    auto data_view = data.getView();
    auto fetch = [=] __cuda_callable__ ( int globalIdx ) -> double { return data_view[ globalIdx ]; };
-   printSegments( segments, fetch, std::cout );
+   std::cout << segments.print( fetch ) << std::endl;
    std::cout << std::endl;
 }
 
diff --git a/src/TNL/Algorithms/Segments/BiEllpack.h b/src/TNL/Algorithms/Segments/BiEllpack.h
index ee202d25ce..3830d8e141 100644
--- a/src/TNL/Algorithms/Segments/BiEllpack.h
+++ b/src/TNL/Algorithms/Segments/BiEllpack.h
@@ -135,6 +135,9 @@ class BiEllpack
 
       void load(File &file);
 
+      template< typename Fetch >
+      SegmentsPrinter< BiEllpack, Fetch > print( Fetch&& fetch ) const;
+
       void printStructure(std::ostream &str) const;
 
       // TODO: nvcc needs this public because of lambda function used inside
diff --git a/src/TNL/Algorithms/Segments/BiEllpack.hpp b/src/TNL/Algorithms/Segments/BiEllpack.hpp
index 1412d1be50..4bbccbb0ee 100644
--- a/src/TNL/Algorithms/Segments/BiEllpack.hpp
+++ b/src/TNL/Algorithms/Segments/BiEllpack.hpp
@@ -581,6 +581,19 @@ load( File& file )
         >> this->groupPointers;
 }
 
+template< typename Device,
+          typename Index,
+          typename IndexAllocator,
+          ElementsOrganization Organization,
+          int WarpSize >
+      template< typename Fetch >
+auto
+BiEllpack< Device, Index, IndexAllocator, Organization, WarpSize >::
+print( Fetch&& fetch ) const -> SegmentsPrinter< BiEllpack, Fetch >
+{
+   return SegmentsPrinter< BiEllpack, Fetch >( *this, fetch );
+}
+
 template< typename Device,
           typename Index,
           typename IndexAllocator,
diff --git a/src/TNL/Algorithms/Segments/BiEllpackView.h b/src/TNL/Algorithms/Segments/BiEllpackView.h
index c0ae1559e8..62d60509c2 100644
--- a/src/TNL/Algorithms/Segments/BiEllpackView.h
+++ b/src/TNL/Algorithms/Segments/BiEllpackView.h
@@ -138,6 +138,9 @@ class BiEllpackView
 
       void load( File& file );
 
+      template< typename Fetch >
+      SegmentsPrinter< BiEllpackView, Fetch > print( Fetch&& fetch ) const;
+
       void printStructure( std::ostream& str ) const;
 
    protected:
diff --git a/src/TNL/Algorithms/Segments/BiEllpackView.hpp b/src/TNL/Algorithms/Segments/BiEllpackView.hpp
index b480deac08..ab79d58333 100644
--- a/src/TNL/Algorithms/Segments/BiEllpackView.hpp
+++ b/src/TNL/Algorithms/Segments/BiEllpackView.hpp
@@ -477,6 +477,18 @@ save( File& file ) const
         << this->groupPointers;
 }
 
+template< typename Device,
+          typename Index,
+          ElementsOrganization Organization,
+          int WarpSize >
+      template< typename Fetch >
+auto
+BiEllpackView< Device, Index, Organization, WarpSize >::
+print( Fetch&& fetch ) const -> SegmentsPrinter< BiEllpackView, Fetch >
+{
+   return SegmentsPrinter< BiEllpackView, Fetch >( *this, fetch );
+}
+
 template< typename Device,
           typename Index,
           ElementsOrganization Organization,
diff --git a/src/TNL/Algorithms/Segments/CSR.h b/src/TNL/Algorithms/Segments/CSR.h
index f3f1aa8810..eebd186a6f 100644
--- a/src/TNL/Algorithms/Segments/CSR.h
+++ b/src/TNL/Algorithms/Segments/CSR.h
@@ -486,6 +486,27 @@ class CSR
        */
       void load( File& file );
 
+      /**
+       * \brief Return simple proxy object for insertion to output stream.
+       *
+       * The proxy object serves for wrapping segments with lambda function mediating access to data managed by the segments.
+       *
+       * \tparam Fetch is type of lambda function for data access.
+       * \param fetch is an instance of lambda function for data access. It is supposed to be defined as
+       *
+       * ```
+       * auto fetch = [=] __cuda_callable__ ( IndexType globalIdx ) -> ValueType { return data_view[ globalIdx ]; };
+       * ```
+       * \return Proxy object for insertion to output stream.
+       *
+       * \par Example
+       * \include Algorithms/Segments/SegmentsPrintingExample-2.cpp
+       * \par Output
+       * \include SegmentsPrintingExample-2.out
+       */
+      template< typename Fetch >
+      SegmentsPrinter< CSR, Fetch > print( Fetch&& fetch ) const;
+
    protected:
 
       OffsetsContainer offsets;
diff --git a/src/TNL/Algorithms/Segments/CSR.hpp b/src/TNL/Algorithms/Segments/CSR.hpp
index b427f4acde..0d15790bf8 100644
--- a/src/TNL/Algorithms/Segments/CSR.hpp
+++ b/src/TNL/Algorithms/Segments/CSR.hpp
@@ -368,6 +368,18 @@ load( File& file )
    this->kernel.init( this->offsets );
 }
 
+template< typename Device,
+          typename Index,
+          typename Kernel,
+          typename IndexAllocator >
+      template< typename Fetch >
+auto
+CSR< Device, Index, Kernel, IndexAllocator >::
+print( Fetch&& fetch ) const -> SegmentsPrinter< CSR, Fetch >
+{
+   return SegmentsPrinter< CSR, Fetch >( *this, fetch );
+}
+
       } // namespace Segments
    }  // namespace Algorithms
 } // namespace TNL
diff --git a/src/TNL/Algorithms/Segments/CSRView.h b/src/TNL/Algorithms/Segments/CSRView.h
index 5daa3e7c28..dee96ba5ad 100644
--- a/src/TNL/Algorithms/Segments/CSRView.h
+++ b/src/TNL/Algorithms/Segments/CSRView.h
@@ -139,6 +139,9 @@ class CSRView
 
       void load( File& file );
 
+      template< typename Fetch >
+      SegmentsPrinter< CSRView, Fetch > print( Fetch&& fetch ) const;
+
    protected:
 
       OffsetsView offsets;
diff --git a/src/TNL/Algorithms/Segments/CSRView.hpp b/src/TNL/Algorithms/Segments/CSRView.hpp
index 08822ca948..b69e61e5a9 100644
--- a/src/TNL/Algorithms/Segments/CSRView.hpp
+++ b/src/TNL/Algorithms/Segments/CSRView.hpp
@@ -318,6 +318,18 @@ load( File& file )
    this->kernel.init( this->offsets );
 }
 
+template< typename Device,
+          typename Index,
+          typename Kernel >
+      template< typename Fetch >
+auto
+CSRView< Device, Index, Kernel >::
+print( Fetch&& fetch ) const -> SegmentsPrinter< CSRView, Fetch >
+{
+   return SegmentsPrinter< CSRView, Fetch >( *this, fetch );
+}
+
+
       } // namespace Segments
    }  // namespace Containers
 } // namespace TNL
diff --git a/src/TNL/Algorithms/Segments/ChunkedEllpack.h b/src/TNL/Algorithms/Segments/ChunkedEllpack.h
index 5b0916d201..1d4f9fabcd 100644
--- a/src/TNL/Algorithms/Segments/ChunkedEllpack.h
+++ b/src/TNL/Algorithms/Segments/ChunkedEllpack.h
@@ -131,6 +131,9 @@ class ChunkedEllpack
 
       void load( File& file );
 
+      template< typename Fetch >
+      SegmentsPrinter< ChunkedEllpack, Fetch > print( Fetch&& fetch ) const;
+
       void printStructure( std::ostream& str ); // TODO const;
 
    protected:
diff --git a/src/TNL/Algorithms/Segments/ChunkedEllpack.hpp b/src/TNL/Algorithms/Segments/ChunkedEllpack.hpp
index 82ddd7d8ed..e39a166707 100644
--- a/src/TNL/Algorithms/Segments/ChunkedEllpack.hpp
+++ b/src/TNL/Algorithms/Segments/ChunkedEllpack.hpp
@@ -534,6 +534,18 @@ load( File& file )
    file.load( &this->numberOfSlices );
 }
 
+template< typename Device,
+          typename Index,
+          typename IndexAllocator,
+          ElementsOrganization Organization >
+      template< typename Fetch >
+auto
+ChunkedEllpack< Device, Index, IndexAllocator, Organization >::
+print( Fetch&& fetch ) const -> SegmentsPrinter< ChunkedEllpack, Fetch >
+{
+   return SegmentsPrinter< ChunkedEllpack, Fetch >( *this, fetch );
+}
+
 template< typename Device,
           typename Index,
           typename IndexAllocator,
diff --git a/src/TNL/Algorithms/Segments/ChunkedEllpackView.h b/src/TNL/Algorithms/Segments/ChunkedEllpackView.h
index a20d5a41a6..a54f8e5ef4 100644
--- a/src/TNL/Algorithms/Segments/ChunkedEllpackView.h
+++ b/src/TNL/Algorithms/Segments/ChunkedEllpackView.h
@@ -150,6 +150,9 @@ class ChunkedEllpackView
 
       void save( File& file ) const;
 
+      template< typename Fetch >
+      SegmentsPrinter< ChunkedEllpackView, Fetch > print( Fetch&& fetch ) const;
+
       void printStructure( std::ostream& str ) const;
 
    protected:
diff --git a/src/TNL/Algorithms/Segments/ChunkedEllpackView.hpp b/src/TNL/Algorithms/Segments/ChunkedEllpackView.hpp
index 5f73fd8ab2..6fc7671079 100644
--- a/src/TNL/Algorithms/Segments/ChunkedEllpackView.hpp
+++ b/src/TNL/Algorithms/Segments/ChunkedEllpackView.hpp
@@ -513,6 +513,18 @@ save( File& file ) const
    file.save( &this->numberOfSlices );
 }
 
+template< typename Device,
+          typename Index,
+          ElementsOrganization Organization >
+      template< typename Fetch >
+auto
+ChunkedEllpackView< Device, Index, Organization >::
+print( Fetch&& fetch ) const -> SegmentsPrinter< ChunkedEllpackView, Fetch >
+{
+   return SegmentsPrinter< ChunkedEllpackView, Fetch >( *this, fetch );
+}
+
+
 template< typename Device,
           typename Index,
           ElementsOrganization Organization >
diff --git a/src/TNL/Algorithms/Segments/Ellpack.h b/src/TNL/Algorithms/Segments/Ellpack.h
index e68ebdf622..c363d30003 100644
--- a/src/TNL/Algorithms/Segments/Ellpack.h
+++ b/src/TNL/Algorithms/Segments/Ellpack.h
@@ -130,6 +130,9 @@ class Ellpack
 
       void load( File& file );
 
+      template< typename Fetch >
+      SegmentsPrinter< Ellpack, Fetch > print( Fetch&& fetch ) const;
+
    protected:
 
       IndexType segmentSize, size, alignedSize;
diff --git a/src/TNL/Algorithms/Segments/Ellpack.hpp b/src/TNL/Algorithms/Segments/Ellpack.hpp
index 589d9f9448..27e7dcbe3c 100644
--- a/src/TNL/Algorithms/Segments/Ellpack.hpp
+++ b/src/TNL/Algorithms/Segments/Ellpack.hpp
@@ -383,6 +383,19 @@ load( File& file )
    file.load( &alignedSize );
 }
 
+template< typename Device,
+          typename Index,
+          typename IndexAllocator,
+          ElementsOrganization Organization,
+          int Alignment >
+      template< typename Fetch >
+auto
+Ellpack< Device, Index, IndexAllocator, Organization, Alignment >::
+print( Fetch&& fetch ) const -> SegmentsPrinter< Ellpack, Fetch >
+{
+   return SegmentsPrinter< Ellpack, Fetch >( *this, fetch );
+}
+
       } // namespace Segments
    }  // namespace Containers
 } // namespace TNL
diff --git a/src/TNL/Algorithms/Segments/EllpackView.h b/src/TNL/Algorithms/Segments/EllpackView.h
index 0857886f2f..6e4995e1d8 100644
--- a/src/TNL/Algorithms/Segments/EllpackView.h
+++ b/src/TNL/Algorithms/Segments/EllpackView.h
@@ -123,6 +123,9 @@ class EllpackView
 
       void load( File& file );
 
+      template< typename Fetch >
+      SegmentsPrinter< EllpackView, Fetch > print( Fetch&& fetch ) const;
+
    protected:
 
       IndexType segmentSize, segmentsCount, alignedSize;
diff --git a/src/TNL/Algorithms/Segments/EllpackView.hpp b/src/TNL/Algorithms/Segments/EllpackView.hpp
index 1ec928336b..18f1cde7b3 100644
--- a/src/TNL/Algorithms/Segments/EllpackView.hpp
+++ b/src/TNL/Algorithms/Segments/EllpackView.hpp
@@ -357,6 +357,18 @@ load( File& file )
    file.load( &alignedSize );
 }
 
+template< typename Device,
+          typename Index,
+          ElementsOrganization Organization,
+          int Alignment >
+      template< typename Fetch >
+auto
+EllpackView< Device, Index, Organization, Alignment >::
+print( Fetch&& fetch ) const -> SegmentsPrinter< EllpackView, Fetch >
+{
+   return SegmentsPrinter< EllpackView, Fetch >( *this, fetch );
+}
+
       } // namespace Segments
    }  // namespace Algorithms
 } // namespace TNL
diff --git a/src/TNL/Algorithms/Segments/SegmentsPrinting.h b/src/TNL/Algorithms/Segments/SegmentsPrinting.h
index 5018471b35..260ad71e8d 100644
--- a/src/TNL/Algorithms/Segments/SegmentsPrinting.h
+++ b/src/TNL/Algorithms/Segments/SegmentsPrinting.h
@@ -99,6 +99,30 @@ std::ostream& printSegments( const Segments& segments, Fetch&& fetch, std::ostre
    return str;
 }
 
+
+template< typename Segments,
+          typename Fetch >
+struct SegmentsPrinter
+{
+   SegmentsPrinter( const Segments& segments, Fetch& fetch )
+   : segments( segments ), fetch( fetch ) {}
+
+   std::ostream& print( std::ostream& str ) const { return printSegments( segments, fetch, str ); }
+
+   protected:
+
+   const Segments& segments;
+
+   Fetch& fetch;
+};
+
+template< typename Segments,
+          typename Fetch >
+std::ostream& operator<<( std::ostream& str, const SegmentsPrinter< Segments, Fetch >& printer )
+{
+   return printer.print( str );
+}
+
       } // namespace Segments
    } // namespace Algorithms
 } // namespace TNL
diff --git a/src/TNL/Algorithms/Segments/SlicedEllpack.h b/src/TNL/Algorithms/Segments/SlicedEllpack.h
index 092af6a1f1..974087e4b8 100644
--- a/src/TNL/Algorithms/Segments/SlicedEllpack.h
+++ b/src/TNL/Algorithms/Segments/SlicedEllpack.h
@@ -127,6 +127,9 @@ class SlicedEllpack
 
       void load( File& file );
 
+      template< typename Fetch >
+      SegmentsPrinter< SlicedEllpack, Fetch > print( Fetch&& fetch ) const;
+
    protected:
 
       IndexType size, alignedSize, segmentsCount;
diff --git a/src/TNL/Algorithms/Segments/SlicedEllpack.hpp b/src/TNL/Algorithms/Segments/SlicedEllpack.hpp
index 6c58c3ed13..8a4903cbd6 100644
--- a/src/TNL/Algorithms/Segments/SlicedEllpack.hpp
+++ b/src/TNL/Algorithms/Segments/SlicedEllpack.hpp
@@ -423,6 +423,19 @@ load( File& file )
    file >> this->sliceSegmentSizes;
 }
 
+template< typename Device,
+          typename Index,
+          typename IndexAllocator,
+          ElementsOrganization Organization,
+          int SliceSize >
+      template< typename Fetch >
+auto
+SlicedEllpack< Device, Index, IndexAllocator, Organization, SliceSize >::
+print( Fetch&& fetch ) const -> SegmentsPrinter< SlicedEllpack, Fetch >
+{
+   return SegmentsPrinter< SlicedEllpack, Fetch >( *this, fetch );
+}
+
       } // namespace Segments
    }  // namespace Algorithms
 } // namespace TNL
diff --git a/src/TNL/Algorithms/Segments/SlicedEllpackView.h b/src/TNL/Algorithms/Segments/SlicedEllpackView.h
index e614f9dc0e..16e2c082f5 100644
--- a/src/TNL/Algorithms/Segments/SlicedEllpackView.h
+++ b/src/TNL/Algorithms/Segments/SlicedEllpackView.h
@@ -121,6 +121,9 @@ class SlicedEllpackView
 
       void load( File& file );
 
+      template< typename Fetch >
+      SegmentsPrinter< SlicedEllpackView, Fetch > print( Fetch&& fetch ) const;
+
    protected:
 
       IndexType size, alignedSize, segmentsCount;
diff --git a/src/TNL/Algorithms/Segments/SlicedEllpackView.hpp b/src/TNL/Algorithms/Segments/SlicedEllpackView.hpp
index 871aa2da05..5b97c72e20 100644
--- a/src/TNL/Algorithms/Segments/SlicedEllpackView.hpp
+++ b/src/TNL/Algorithms/Segments/SlicedEllpackView.hpp
@@ -427,6 +427,18 @@ load( File& file )
    file >> this->sliceSegmentSizes;
 }
 
+template< typename Device,
+          typename Index,
+          ElementsOrganization Organization,
+          int SliceSize >
+      template< typename Fetch >
+auto
+SlicedEllpackView< Device, Index, Organization, SliceSize >::
+print( Fetch&& fetch ) const -> SegmentsPrinter< SlicedEllpackView, Fetch >
+{
+   return SegmentsPrinter< SlicedEllpackView, Fetch >( *this, fetch );
+}
+
       } // namespace Segments
    }  // namespace Algorithms
 } // namespace TNL
-- 
GitLab