Program Listing for File SequenceRange.h

↰ Return to documentation for file (ADS/sequence/SequenceRange.h)

/*--------------------------------------------------------------------------*/
/*-------------------------- File SequenceRange.h --------------------------*/
/*--------------------------------------------------------------------------*/
/*--------------------------------------------------------------------------*/
/*----------------------------- DEFINITIONS --------------------------------*/
/*--------------------------------------------------------------------------*/

#ifndef __ADS_SequenceRange
 #define __ADS_SequenceRange
                      /* self-identification: #endif constant */

/*--------------------------------------------------------------------------*/
/*------------------------------ INCLUDES ----------------------------------*/
/*--------------------------------------------------------------------------*/

#include "ADS/ADT.h"
#include "ADS/Contract.h"

#include <cstddef>
#include <iterator>
#include <ranges>

/*--------------------------------------------------------------------------*/
/*--------------------------- NAMESPACE ------------------------------------*/
/*--------------------------------------------------------------------------*/

namespace ADS {

/*--------------------------------------------------------------------------*/
/*------------------------- CLASS SequenceRange ----------------------------*/
/*--------------------------------------------------------------------------*/

template< Sequence S >
class SequenceRange
 : public std::ranges::view_interface< SequenceRange< S > > {

/*--------------------------------------------------------------------------*/
 public:

 class iterator {
  public:
  using iterator_category = std::forward_iterator_tag;
  using value_type = typename S::Item;
  using difference_type = std::ptrdiff_t;
  using reference = const value_type &;
  using pointer = const value_type *;

  iterator( void ) = default;
  iterator( const S * s , typename S::Pos p ) : f_s( s ) , f_p( p ) {}

  static iterator end( const S * s ) {
   iterator e;
   e.f_s = s;
   e.f_end = true;
   return( e );
   }

  [[nodiscard]] reference operator*( void ) const {
   return( f_s->read( f_p ) );
   }

  [[nodiscard]] pointer operator->( void ) const { return( &**this ); }

  iterator & operator++( void ) {
   f_p = f_s->next( f_p );
   return( *this );
   }

  iterator operator++( int ) {
   iterator t = *this;
   ++*this;
   return( t );
   }

  [[nodiscard]] bool operator==( std::default_sentinel_t ) const {
   return( atEnd() );
   }

  [[nodiscard]] bool operator==( const iterator & o ) const {
   const bool a = atEnd() , b = o.atEnd();
   return( ( a == b ) && ( a || ( f_p == o.f_p ) ) );
   }

  [[nodiscard]] typename S::Pos position( void ) const { return( f_p ); }

  private:
  [[nodiscard]] bool atEnd( void ) const {
   return( f_end || ( f_s == nullptr ) || f_s->finished( f_p ) );
   }

  const S * f_s = nullptr;
  typename S::Pos f_p{};
  bool f_end = false;
  };

 SequenceRange( void ) = default;

 explicit SequenceRange( const S & s ) : f_s( &s ) {}

 [[nodiscard]] iterator begin( void ) const {
  return( iterator( f_s , f_s->head() ) );
  }

 [[nodiscard]] iterator end( void ) const { return( iterator::end( f_s ) ); }

/*--------------------------------------------------------------------------*/
 private:

 const S * f_s = nullptr;

 };  // end( class SequenceRange )

template< Sequence S >
SequenceRange< S > range( const S & s );

/*--------------------------------------------------------------------------*/

}  // end( namespace ADS )

template< ADS::Sequence S >
inline constexpr bool
std::ranges::enable_borrowed_range< ADS::SequenceRange< S > > = true;

/*--------------------------------------------------------------------------*/
/*-------------------------- IMPLEMENTATION --------------------------------*/
/*--------------------------------------------------------------------------*/

#include "ADS/sequence/impl/SequenceRange.tpp"

/*--------------------------------------------------------------------------*/

#endif  /* SequenceRange.h included */

/*--------------------------------------------------------------------------*/
/*------------------------ End File SequenceRange.h ------------------------*/
/*--------------------------------------------------------------------------*/