Replace iterator_facade and iterator_adaptor with std iterators

Borrows the 'proxy reference' technique used in the boost templates
This commit is contained in:
Matt Blair 2015-04-29 17:47:30 -04:00
parent 7c26845bb4
commit f09c4b44e1
2 changed files with 57 additions and 21 deletions

View File

@ -10,7 +10,7 @@
#include "yaml-cpp/dll.h"
#include "yaml-cpp/node/ptr.h"
#include "yaml-cpp/node/detail/node_iterator.h"
#include <boost/iterator/iterator_adaptor.hpp>
#include <iterator>
namespace YAML {
namespace detail {
@ -18,13 +18,21 @@ struct iterator_value;
template <typename V>
class iterator_base
: public boost::iterator_adaptor<iterator_base<V>, node_iterator, V,
std::forward_iterator_tag, V> {
: public std::iterator<std::forward_iterator_tag, V, ptrdiff_t, V*, V> {
private:
template <typename>
friend class iterator_base;
struct enabler {};
typedef typename iterator_base::base_type base_type;
typedef node_iterator base_type;
struct proxy {
explicit proxy(const V& x) : m_ref(x) {}
V* operator->() { return std::addressof(m_ref); }
operator V*() { return std::addressof(m_ref); }
V m_ref;
};
public:
typedef typename iterator_base::value_type value_type;
@ -32,22 +40,28 @@ class iterator_base
public:
iterator_base() {}
explicit iterator_base(base_type rhs, shared_memory_holder pMemory)
: iterator_base::iterator_adaptor_(rhs), m_pMemory(pMemory) {}
: m_iterator(rhs), m_pMemory(pMemory) {}
template <class W>
iterator_base(const iterator_base<W>& rhs,
typename std::enable_if<std::is_convertible<W*, V*>::value,
enabler>::type = enabler())
: iterator_base::iterator_adaptor_(rhs.base()),
m_pMemory(rhs.m_pMemory) {}
: m_iterator(rhs.m_iterator), m_pMemory(rhs.m_pMemory) {}
private:
friend class boost::iterator_core_access;
iterator_base<V>& operator++() { ++m_iterator; return *this; }
void increment() { this->base_reference() = std::next(this->base()); }
template <typename W>
bool operator==(const iterator_base<W>& rhs) {
return m_iterator == rhs.m_iterator;
}
value_type dereference() const {
const typename base_type::value_type& v = *this->base();
template <typename W>
bool operator!=(const iterator_base<W>& rhs) {
return m_iterator != rhs.m_iterator;
}
value_type operator*() const {
const typename base_type::value_type& v = *m_iterator;
if (v.pNode)
return value_type(Node(*v, m_pMemory));
if (v.first && v.second)
@ -55,7 +69,12 @@ class iterator_base
return value_type();
}
value_type* operator->() const {
return proxy(**this);
}
private:
base_type m_iterator;
shared_memory_holder m_pMemory;
};
}

View File

@ -9,7 +9,8 @@
#include "yaml-cpp/dll.h"
#include "yaml-cpp/node/ptr.h"
#include <boost/iterator/iterator_facade.hpp>
#include <iterator>
#include <memory>
#include <map>
#include <utility>
#include <vector>
@ -51,12 +52,20 @@ struct node_iterator_type<const V> {
template <typename V>
class node_iterator_base
: public boost::iterator_facade<
node_iterator_base<V>, node_iterator_value<V>,
std::forward_iterator_tag, node_iterator_value<V> > {
: public std::iterator<
std::forward_iterator_tag, node_iterator_value<V>,
ptrdiff_t, node_iterator_value<V>*, node_iterator_value<V> > {
private:
struct enabler {};
struct proxy {
explicit proxy(const node_iterator_value<V>& x) : m_ref(x) {}
node_iterator_value<V>* operator->() { return std::addressof(m_ref); }
operator node_iterator_value<V>*() { return std::addressof(m_ref); }
node_iterator_value<V> m_ref;
};
public:
typedef typename node_iterator_type<V>::seq SeqIter;
typedef typename node_iterator_type<V>::map MapIter;
@ -86,13 +95,11 @@ class node_iterator_base
m_mapIt(rhs.m_mapIt),
m_mapEnd(rhs.m_mapEnd) {}
private:
friend class boost::iterator_core_access;
template <typename>
friend class node_iterator_base;
template <typename W>
bool equal(const node_iterator_base<W>& rhs) const {
bool operator==(const node_iterator_base<W>& rhs) const {
if (m_type != rhs.m_type)
return false;
@ -107,7 +114,12 @@ class node_iterator_base
return true;
}
void increment() {
template <typename W>
bool operator!=(const node_iterator_base<W>& rhs) const {
return !(*this==rhs);
}
node_iterator_base<V>& operator++() {
switch (m_type) {
case iterator_type::None:
break;
@ -119,9 +131,10 @@ class node_iterator_base
m_mapIt = increment_until_defined(m_mapIt);
break;
}
return *this;
}
value_type dereference() const {
value_type operator*() const {
switch (m_type) {
case iterator_type::None:
return value_type();
@ -133,6 +146,10 @@ class node_iterator_base
return value_type();
}
value_type* operator->() const {
return proxy(**this);
}
MapIter increment_until_defined(MapIter it) {
while (it != m_mapEnd && !is_defined(it))
++it;