]> git.proxmox.com Git - ceph.git/blobdiff - ceph/src/boost/libs/container/test/input_iterator.hpp
import quincy beta 17.1.0
[ceph.git] / ceph / src / boost / libs / container / test / input_iterator.hpp
diff --git a/ceph/src/boost/libs/container/test/input_iterator.hpp b/ceph/src/boost/libs/container/test/input_iterator.hpp
new file mode 100644 (file)
index 0000000..1d576cf
--- /dev/null
@@ -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);
+}