Created
December 19, 2014 22:40
-
-
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
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#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__ |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#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__ |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#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__ |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#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_; | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#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