|
|
@@ -7,13 +7,14 @@
|
|
|
#define EQ_MEM(x) x == dynamic_cast<iterator const&>(other).x
|
|
|
|
|
|
#define DELEGATE_ITERATOR_IMPL_BASE(impl) \
|
|
|
-super* clone() const override { return new iterator{*this}; } \
|
|
|
-bool operator==(super const&other) const override { return EQ_MEM(impl); } \
|
|
|
+bool operator==(iterator const&other) const { return EQ_MEM(impl); } \
|
|
|
|
|
|
#define DELEGATE_ITERATOR_IMPL(impl) \
|
|
|
-super& operator++() override { ++impl; return *this; } \
|
|
|
+iterator& operator++() { ++impl; return *this; } \
|
|
|
DELEGATE_ITERATOR_IMPL_BASE(impl)
|
|
|
|
|
|
+std::map<void*, bool> data;
|
|
|
+
|
|
|
namespace stream {
|
|
|
template <typename T>
|
|
|
class iterator {
|
|
|
@@ -24,32 +25,68 @@ namespace stream {
|
|
|
using difference_type = std::ptrdiff_t;
|
|
|
using iterator_category = std::forward_iterator_tag;
|
|
|
public:
|
|
|
- iterator(detail::iterator_impl<T>* impl) : impl_(impl) {}
|
|
|
- iterator(iterator const& other) : impl_(other.impl_->clone()) { }
|
|
|
- iterator(iterator&& other) : impl_(nullptr) { std::swap(impl_, other.impl_); }
|
|
|
- ~iterator() { if (impl_) delete impl_; }
|
|
|
- T operator*() const { return **impl_; }
|
|
|
- iterator& operator++() { ++(*impl_); return *this; }
|
|
|
- bool operator==(iterator const&other) const { return *impl_ == *(other.impl_); }
|
|
|
- bool operator!=(iterator const&other) const { return *impl_ != *(other.impl_); }
|
|
|
+ iterator() = default;
|
|
|
+
|
|
|
+ template <typename Iter>
|
|
|
+ iterator(Iter impl) {
|
|
|
+ copy = [](void * p) { return (void*) new Iter(*(Iter*)(p)); };
|
|
|
+ dereference = [](void * p) -> T { return **((Iter*)p); };
|
|
|
+ compare = [](void * l, void * r) { return *((Iter*)l) == *((Iter*)r); };
|
|
|
+ destroy = [](void * p) { delete (Iter*)(p); };
|
|
|
+ advance = [](void * p) { ++(*(Iter*)(p)); };
|
|
|
+ type_ = typeid(Iter).name();
|
|
|
+ impl_ = copy(&impl);
|
|
|
+ }
|
|
|
+
|
|
|
+ iterator(iterator const& other)
|
|
|
+ : copy(other.copy)
|
|
|
+ , dereference(other.dereference)
|
|
|
+ , compare(other.compare)
|
|
|
+ , destroy(other.destroy)
|
|
|
+ , advance(other.advance)
|
|
|
+ , type_(other.type_)
|
|
|
+ , impl_(copy(other.impl_)) {
|
|
|
+ }
|
|
|
+
|
|
|
+ iterator & operator=(iterator const & other) {
|
|
|
+ iterator tmp{other};
|
|
|
+ swap(*this, tmp);
|
|
|
+ return *this;
|
|
|
+ }
|
|
|
+
|
|
|
+ ~iterator() { if (destroy) destroy(impl_); }
|
|
|
+
|
|
|
+ T operator*() const { return dereference(impl_); }
|
|
|
+ iterator& operator++() { advance(impl_); return *this; }
|
|
|
+ bool operator==(iterator const&other) const {
|
|
|
+ if (strcmp(type_, other.type_)) { return false; }
|
|
|
+ return compare(impl_, other.impl_);
|
|
|
+ }
|
|
|
+ bool operator!=(iterator const&other) const {
|
|
|
+ if (strcmp(type_, other.type_)) { return false; }
|
|
|
+ return !compare(impl_, other.impl_);
|
|
|
+ }
|
|
|
private:
|
|
|
- detail::iterator_impl<T>* impl_;
|
|
|
+ friend void swap(iterator & lhs, iterator & rhs) {
|
|
|
+ using std::swap;
|
|
|
+ swap(lhs.copy, rhs.copy);
|
|
|
+ swap(lhs.dereference, rhs.dereference);
|
|
|
+ swap(lhs.compare, rhs.compare);
|
|
|
+ swap(lhs.destroy, rhs.destroy);
|
|
|
+ swap(lhs.advance, rhs.advance);
|
|
|
+ swap(lhs.type_, rhs.type_);
|
|
|
+ swap(lhs.impl_, rhs.impl_);
|
|
|
+ }
|
|
|
+ using delegate = void(*)(void*);
|
|
|
+ void* (*copy)(void*){nullptr};
|
|
|
+ T (*dereference)(void*){nullptr};
|
|
|
+ bool (*compare)(void*, void*){nullptr};
|
|
|
+ delegate destroy{nullptr}, advance{nullptr};
|
|
|
+ char const * type_{nullptr};
|
|
|
+ void * impl_{nullptr};
|
|
|
};
|
|
|
|
|
|
namespace detail {
|
|
|
- template <typename T>
|
|
|
- class iterator_impl {
|
|
|
- public:
|
|
|
- virtual ~iterator_impl() {}
|
|
|
- virtual iterator_impl<T>* clone() const = 0;
|
|
|
- virtual T operator*() = 0;
|
|
|
- virtual iterator_impl<T>& operator++() = 0;
|
|
|
- virtual bool operator==(iterator_impl<T> const&other) const = 0;
|
|
|
- bool operator!=(iterator_impl<T> const&other) const {
|
|
|
- return !operator==(other);
|
|
|
- }
|
|
|
- };
|
|
|
-
|
|
|
template <typename T>
|
|
|
class stream_impl {
|
|
|
public:
|