forked from boostorg/container
Integrate and adapt "devector's", from Thaler Benedek's implementation.
This commit is contained in:
@@ -0,0 +1,119 @@
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// \(C\) Copyright Benedek Thaler 2015-2016
|
||||
// \(C\) Copyright Ion Gaztanaga 2019-2020. Distributed under the Boost
|
||||
// Software License, Version 1.0. (See accompanying file
|
||||
// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
//
|
||||
// See http://erenon.hu/double_ended for documentation.
|
||||
//
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
/**
|
||||
* Emulates input iterator, validates algorithm
|
||||
* does a single pass only, removes visited elements.
|
||||
*
|
||||
* Container::erase(front_iterator) must not invalidate other iterators.
|
||||
*
|
||||
* The hack around `_erase_on_destroy` is required to make `*it++` work.
|
||||
*/
|
||||
template <typename Container>
|
||||
class input_iterator
|
||||
{
|
||||
typedef typename Container::iterator iterator;
|
||||
|
||||
public:
|
||||
|
||||
typedef std::input_iterator_tag iterator_category;
|
||||
typedef typename Container::value_type value_type;
|
||||
typedef typename Container::pointer pointer;
|
||||
typedef typename Container::reference reference;
|
||||
typedef typename Container::difference_type difference_type;
|
||||
|
||||
struct erase_on_destroy {};
|
||||
|
||||
public:
|
||||
|
||||
input_iterator()
|
||||
: _container()
|
||||
, _it()
|
||||
, _erase_on_destroy()
|
||||
{}
|
||||
|
||||
input_iterator(Container& c, iterator it)
|
||||
:_container(&c)
|
||||
, _it(it)
|
||||
, _erase_on_destroy()
|
||||
{}
|
||||
|
||||
input_iterator(const input_iterator& rhs)
|
||||
:_container(rhs._container),
|
||||
_it(rhs._it),
|
||||
_erase_on_destroy(rhs._erase_on_destroy)
|
||||
{
|
||||
rhs._erase_on_destroy = false;
|
||||
}
|
||||
|
||||
input_iterator & operator=(const input_iterator& rhs)
|
||||
{
|
||||
_container = rhs._container;
|
||||
_it = rhs._it;
|
||||
_erase_on_destroy = rhs._erase_on_destroy;
|
||||
rhs._erase_on_destroy = false;
|
||||
return *this;
|
||||
}
|
||||
|
||||
input_iterator(const input_iterator& rhs, erase_on_destroy)
|
||||
:_container(rhs._container),
|
||||
_it(rhs._it),
|
||||
_erase_on_destroy(true)
|
||||
{}
|
||||
|
||||
~input_iterator()
|
||||
{
|
||||
if (_erase_on_destroy)
|
||||
{
|
||||
_container->erase(_it); // must not invalidate other iterators
|
||||
}
|
||||
}
|
||||
|
||||
const value_type& operator*()
|
||||
{
|
||||
return *_it;
|
||||
}
|
||||
|
||||
input_iterator operator++()
|
||||
{
|
||||
_container->erase(_it);
|
||||
++_it;
|
||||
return *this;
|
||||
}
|
||||
|
||||
input_iterator operator++(int)
|
||||
{
|
||||
input_iterator old(*this, erase_on_destroy());
|
||||
++_it;
|
||||
return old;
|
||||
}
|
||||
|
||||
friend bool operator==(const input_iterator a, const input_iterator b)
|
||||
{
|
||||
return a._it == b._it;
|
||||
}
|
||||
|
||||
friend bool operator!=(const input_iterator a, const input_iterator b)
|
||||
{
|
||||
return !(a == b);
|
||||
}
|
||||
|
||||
private:
|
||||
Container* _container;
|
||||
iterator _it;
|
||||
mutable bool _erase_on_destroy;
|
||||
};
|
||||
|
||||
template <typename Container>
|
||||
input_iterator<Container> make_input_iterator(Container& c, typename Container::iterator it)
|
||||
{
|
||||
return input_iterator<Container>(c, it);
|
||||
}
|
||||
Reference in New Issue
Block a user