2022-06-08 01:36:46 +02:00
// Copyright (c) 2021-2022 The Dash Core developers
2022-04-26 01:40:41 +02:00
// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
// Original implementation here: https://github.com/whoshuu/cpp_range/blob/cd6897e40176c3031ad1e4c8069d672b2e544996/include/range.h under MIT software license
# ifndef BITCOIN_UTIL_IRANGE_H
# define BITCOIN_UTIL_IRANGE_H
# include <iterator>
# include <stdexcept>
namespace irange {
namespace detail {
template < typename T >
class Range {
// T must be an integral type
static_assert ( std : : is_integral < T > ( ) ) ;
public :
Range ( const T start , const T stop , const T step ) : start_ { start } , stop_ { stop } , step_ { step } {
if ( step_ = = 0 ) {
throw std : : invalid_argument ( " Range step argument must not be zero " ) ;
} else {
if ( ( start_ > stop_ & & step_ > 0 ) | | ( start_ < stop_ & & step_ < 0 ) ) {
throw std : : invalid_argument ( " Range arguments must result in termination " ) ;
}
}
}
class iterator {
public :
typedef std : : forward_iterator_tag iterator_category ;
typedef T value_type ;
typedef T & reference ;
typedef T * pointer ;
iterator ( value_type value , value_type step , value_type boundary ) : value_ { value } , step_ { step } ,
boundary_ { boundary } ,
positive_step_ ( step_ > 0 ) { }
iterator operator + + ( ) { value_ + = step_ ; return * this ; }
reference operator * ( ) { return value_ ; }
const pointer operator - > ( ) { return & value_ ; }
2022-05-09 16:49:33 +02:00
bool operator = = ( const iterator & rhs ) const { return positive_step_ ? ( value_ > = rhs . value_ & & value_ > boundary_ )
: ( value_ < = rhs . value_ & & value_ < boundary_ ) ; }
bool operator ! = ( const iterator & rhs ) const { return positive_step_ ? ( value_ < rhs . value_ & & value_ > = boundary_ )
: ( value_ > rhs . value_ & & value_ < = boundary_ ) ; }
2022-04-26 01:40:41 +02:00
private :
value_type value_ ;
const T step_ ;
const T boundary_ ;
const bool positive_step_ ;
} ;
iterator begin ( ) const {
return iterator ( start_ , step_ , start_ ) ;
}
iterator end ( ) const {
return iterator ( stop_ , step_ , start_ ) ;
}
private :
const T start_ ;
const T stop_ ;
const T step_ ;
} ;
} // namespace detail
template < typename T >
detail : : Range < T > range ( const T stop ) {
return detail : : Range < T > ( T { 0 } , stop , T { 1 } ) ;
}
template < typename T >
detail : : Range < T > range ( const T start , const T stop ) {
return detail : : Range < T > ( start , stop , T { 1 } ) ;
}
template < typename T >
detail : : Range < T > range ( const T start , const T stop , const T step ) {
return detail : : Range < T > ( start , stop , step ) ;
}
} // namespace irange
# endif // BITCOIN_UTIL_IRANGE_H