iterator: add dereference_adapter for iterators
This commit is contained in:
parent
bf535de083
commit
edc245e2d1
89
iterator.hpp
89
iterator.hpp
@ -645,6 +645,93 @@ namespace cruft {
|
|||||||
private:
|
private:
|
||||||
std::size_t m_count = 0;
|
std::size_t m_count = 0;
|
||||||
};
|
};
|
||||||
};
|
|
||||||
|
|
||||||
|
///////////////////////////////////////////////////////////////////////////
|
||||||
|
/// Adapts a supplied iterator by dereferencing any operations that deal
|
||||||
|
/// with the underlying value_type of the supplied iterator.
|
||||||
|
template <typename IteratorT>
|
||||||
|
struct dereference_adapter {
|
||||||
|
//---------------------------------------------------------------------
|
||||||
|
using difference_type = typename std::iterator_traits<IteratorT>::difference_type;
|
||||||
|
using iterator_category = typename std::iterator_traits<IteratorT>::iterator_category;
|
||||||
|
|
||||||
|
using value_type = std::remove_reference_t<
|
||||||
|
decltype(
|
||||||
|
*std::declval<
|
||||||
|
typename std::iterator_traits<IteratorT>::value_type
|
||||||
|
> ()
|
||||||
|
)
|
||||||
|
>;
|
||||||
|
|
||||||
|
using pointer = value_type*;
|
||||||
|
using reference = value_type&;
|
||||||
|
|
||||||
|
|
||||||
|
//---------------------------------------------------------------------
|
||||||
|
dereference_adapter (IteratorT _cursor)
|
||||||
|
: m_cursor (_cursor)
|
||||||
|
{ ; }
|
||||||
|
|
||||||
|
|
||||||
|
//---------------------------------------------------------------------
|
||||||
|
// Trivial conditional operations
|
||||||
|
decltype(auto)
|
||||||
|
operator== (dereference_adapter const &rhs) const
|
||||||
|
{
|
||||||
|
return m_cursor == rhs.m_cursor;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
decltype(auto)
|
||||||
|
operator!= (dereference_adapter const &rhs) const
|
||||||
|
{
|
||||||
|
return !(*this == rhs);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//---------------------------------------------------------------------
|
||||||
|
// Iterator movement operations
|
||||||
|
dereference_adapter&
|
||||||
|
operator++ ()
|
||||||
|
{
|
||||||
|
++m_cursor;
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
difference_type
|
||||||
|
operator- (dereference_adapter const &rhs) const
|
||||||
|
{
|
||||||
|
return m_cursor - rhs.m_cursor;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
auto
|
||||||
|
operator+ (difference_type offset) const
|
||||||
|
{
|
||||||
|
return dereference_adapter { m_cursor + offset };
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//---------------------------------------------------------------------
|
||||||
|
// value_type operations
|
||||||
|
decltype(auto)
|
||||||
|
operator= (value_type const &rhs)
|
||||||
|
{
|
||||||
|
return **m_cursor = rhs;
|
||||||
|
}
|
||||||
|
|
||||||
|
decltype(auto) operator* () { return **m_cursor; }
|
||||||
|
decltype(auto) operator-> () { return **m_cursor; }
|
||||||
|
|
||||||
|
decltype(auto) operator* () const { return **m_cursor; }
|
||||||
|
decltype(auto) operator-> () const { return **m_cursor; }
|
||||||
|
|
||||||
|
|
||||||
|
private:
|
||||||
|
IteratorT m_cursor;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -19,6 +19,22 @@ test_counting_output_iterator (cruft::TAP::logger &tap)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
test_dereference_iterator (cruft::TAP::logger &tap)
|
||||||
|
{
|
||||||
|
int values[4] { 0, 1, 2, 3 };
|
||||||
|
int const* pointers[4] = { values + 0, values + 1, values + 2, values + 3 };
|
||||||
|
|
||||||
|
auto const sum = std::accumulate (
|
||||||
|
cruft::dereference_adapter (std::cbegin (pointers)),
|
||||||
|
cruft::dereference_adapter (std::cend (pointers)),
|
||||||
|
0
|
||||||
|
);
|
||||||
|
|
||||||
|
tap.expect_eq (sum, 6, "dereference_adapter used in accumulate");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
int
|
int
|
||||||
main (int, char**)
|
main (int, char**)
|
||||||
|
Loading…
Reference in New Issue
Block a user