Fixing ranges for pointer iterators.

This commit is contained in:
Can Bölük 2020-08-28 10:37:45 +02:00
parent 0d18747a7c
commit 6e78367b3a
3 changed files with 31 additions and 22 deletions

View file

@ -55,34 +55,36 @@ namespace vtil
// Default constructor.
//
iterator( value_type at, value_type limit = 0 ) :
constexpr iterator( value_type at, value_type limit = 0 ) :
at( at ), limit( limit ) {}
// Support bidirectional iteration.
//
iterator& operator++() { at++; return *this; }
iterator& operator--() { at--; return *this; }
constexpr iterator& operator++() { at++; return *this; }
constexpr iterator& operator--() { at--; return *this; }
constexpr iterator operator++( int ) { auto s = *this; operator--(); return s; }
constexpr iterator operator--( int ) { auto s = *this; operator++(); return s; }
// Equality check against another iterator.
//
bool operator==( const iterator& other ) const
constexpr bool operator==( const iterator& other ) const
{
return at == other.at && limit == other.limit;
}
bool operator!=( const iterator& other ) const
constexpr bool operator!=( const iterator& other ) const
{
return at != other.at || limit != other.limit;
}
// Equality check against special end iterator.
//
bool operator==( iterator_end_tag_t ) const { return at == limit; }
bool operator!=( iterator_end_tag_t ) const { return at != limit; }
constexpr bool operator==( iterator_end_tag_t ) const { return at == limit; }
constexpr bool operator!=( iterator_end_tag_t ) const { return at != limit; }
// Redirect dereferencing to container.
//
value_type operator*() { return at; }
value_type operator*() const { return at; }
constexpr value_type operator*() { return at; }
constexpr value_type operator*() const { return at; }
};
using const_iterator = iterator;

View file

@ -47,27 +47,35 @@ namespace vtil
{
// Declare proxying iterator.
//
struct iterator : base_iterator
struct iterator
{
// Modify certain traits.
//
using reference = decltype( std::declval<F>()( std::declval<typename base_iterator::reference>() ) );
using reference = decltype( std::declval<F>()( *std::declval<base_iterator>() ) );
using value_type = typename std::remove_reference_t<reference>;
// Constructed by the original iterator and a reference to transformation function.
//
const F& transform;
constexpr iterator( base_iterator&& i, const F& transform ) : base_iterator( std::move( i ) ), transform( transform ) {}
constexpr iterator( const base_iterator& i, const F& transform ) : base_iterator( i ), transform( transform ) {}
base_iterator at;
constexpr iterator( base_iterator&& i, const F& transform ) : at( std::move( i ) ), transform( transform ) {}
constexpr iterator( const base_iterator& i, const F& transform ) : at( i ), transform( transform ) {}
// Support bidirectional iteration.
//
constexpr iterator& operator++() { at++; return *this; }
constexpr iterator& operator--() { at--; return *this; }
constexpr iterator operator++( int ) { auto s = *this; operator--(); return s; }
constexpr iterator operator--( int ) { auto s = *this; operator++(); return s; }
// Equality check against another iterator.
//
constexpr bool operator==( const iterator& other ) const { return at == other.at; }
constexpr bool operator!=( const iterator& other ) const { return at != other.at; }
// Override accessor to apply transformation where relevant.
//
reference operator*() const { return transform( base_iterator::operator*() ); }
// Inherit rest from operator base.
//
using base_iterator::operator==;
using base_iterator::operator!=;
constexpr reference operator*() const { return transform( base_iterator::operator*() ); }
};
using const_iterator = iterator;
@ -83,9 +91,6 @@ namespace vtil
constexpr iterator end() const { return { iend, transform }; }
constexpr size_t size() const { return ( size_t ) std::distance( begin(), end() ); }
};
template<typename I, typename F>
range_proxy( F, I, I )->range_proxy<I, F>;
};
template<typename It, typename Fn>

View file

@ -118,6 +118,8 @@ namespace vtil
template<typename T>
concept Integral = std::is_integral_v<T>;
template<typename T>
concept FloatingPoint = std::is_floating_point_v<T>;
template<typename T>
concept Trivial = std::is_trivial_v<T>;
template<typename T>
concept Enum = std::is_enum_v<T>;