Skip to content

Instantly share code, notes, and snippets.

@wancw
Created December 19, 2014 22:40
Show Gist options
  • Save wancw/203f53756baba9a32caf to your computer and use it in GitHub Desktop.
Save wancw/203f53756baba9a32caf to your computer and use it in GitHub Desktop.
Use iterator pointer in range-based for loop. Or you may just use boost::indirect_iterator - http://www.boost.org/doc/libs/1_57_0/libs/iterator/doc/indirect_iterator.html
#ifndef __01_ITERATOR_HELPER_H__
#define __01_ITERATOR_HELPER_H__
#include <memory>
/* We need a concreate iterator class */
template<typename It, typename Vt = typename It::valuetype>
class IteratorPointerWrapper {
public:
IteratorPointerWrapper(It* iter_ptr) : iter_ptr_(iter_ptr) {}
const Vt& operator*() const {
return **iter_ptr_;
}
const Vt* operator->() const {
return &(**iter_ptr_);
}
IteratorPointerWrapper& operator++() {
++(*iter_ptr_);
return *this;
}
bool operator!=(const IteratorPointerWrapper& other) const {
return (*other.iter_ptr_) != (*iter_ptr_);
}
private:
std::unique_ptr<It> iter_ptr_;
};
/* Helper base class to ensure all need methods are implemented. */
template<typename VT>
struct BaseIterator
{
typedef VT valuetype;
typedef BaseIterator<VT> base_iterator_type;
virtual const valuetype& operator*() const = 0;
virtual const valuetype* operator->() const = 0;
virtual base_iterator_type& operator++() = 0;
virtual bool operator!=(const base_iterator_type& other) const = 0;
};
#endif // __01_ITERATOR_HELPER_H__
#ifndef __02_NODE_CONTAINER_H__
#define __02_NODE_CONTAINER_H__
#include "01_iterator_helper.hpp"
struct Node {
int value;
};
typedef BaseIterator<Node> BaseNodeIterator;
struct NodeList {
typedef IteratorPointerWrapper<BaseNodeIterator> iterator;
virtual ~NodeList() = default;
virtual iterator begin() const = 0;
virtual iterator end() const = 0;
};
#endif // __02_NODE_CONTAINER_H__
#ifndef __03_NODE_IN_VECTOR_H__
#define __03_NODE_IN_VECTOR_H__
#include <vector>
#include "02_node_container.hpp"
class NodeSequence : public NodeList {
public:
NodeSequence(int min, int max);
iterator begin() const;
iterator end() const;
const Node& operator[](int i) const;
private:
int min_, max_;
std::vector<Node> nodes_;
};
class NodeSequenceIterator : public BaseNodeIterator {
public:
NodeSequenceIterator(const NodeSequence &seq, int pos);
const valuetype& operator*() const;
const valuetype* operator->() const;
base_iterator_type& operator++();
bool operator!= (const base_iterator_type& other) const;
private:
const NodeSequence & seq_;
int pos_;
};
#endif // __03_NODE_IN_VECTOR_H__
#include "03_node_in_vector.hpp"
NodeSequence::NodeSequence(int min, int max)
: min_(min), max_(max), nodes_{static_cast<std::vector<Node>::size_type>(max-min)} {
for (int i=0, v = min; v < max; ++i, ++v) {
nodes_[i].value = v;
}
}
NodeSequence::iterator NodeSequence::begin() const {
return iterator { new NodeSequenceIterator(*this, 0) };
}
NodeSequence::iterator NodeSequence::end() const {
return iterator { new NodeSequenceIterator(*this, max_ - min_) };
}
const Node& NodeSequence::operator[](int i) const {
return nodes_[i];
}
NodeSequenceIterator::NodeSequenceIterator(const NodeSequence &seq, int pos)
: seq_(seq), pos_(pos) {
}
const Node& NodeSequenceIterator::operator*() const {
return seq_[pos_];
}
const Node* NodeSequenceIterator::operator->() const {
return &(seq_[pos_]);
}
NodeSequenceIterator::base_iterator_type& NodeSequenceIterator::operator++() {
++pos_;
return *this;
}
bool NodeSequenceIterator::operator!= (const base_iterator_type& other) const {
const NodeSequenceIterator * imother = dynamic_cast<const NodeSequenceIterator *>(&other);
return imother == nullptr || imother->pos_ != pos_;
}
#include <iostream>
#include "03_node_in_vector.hpp"
int main () {
std::unique_ptr<NodeList> pnl { new NodeSequence(3, 6) };
for (auto n : *pnl) {
std::cout << n.value << std::endl;
}
std::cout << std::endl;
for (auto i = pnl->begin(), e = pnl->end(); i != e; ++i) {
std::cout << (*i).value << ", " << i->value << std::endl;
}
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment