|
|
@@ -5,11 +5,9 @@
|
|
|
#include <numeric>
|
|
|
#include <vector>
|
|
|
|
|
|
-namespace stream {
|
|
|
-#define STREAM_ITERATOR_COPY() \
|
|
|
- copy(other.copy), dereference(other.dereference), compare(other.compare), \
|
|
|
- destroy(other.destroy), advance(other.advance), type_(other.type_)
|
|
|
+#include "ifd_pointer.hpp"
|
|
|
|
|
|
+namespace stream {
|
|
|
template <typename T> class iterator {
|
|
|
public:
|
|
|
using value_type = typename std::remove_reference<T>::type;
|
|
|
@@ -18,71 +16,56 @@ namespace stream {
|
|
|
using difference_type = std::ptrdiff_t;
|
|
|
using iterator_category = std::forward_iterator_tag;
|
|
|
|
|
|
+ private:
|
|
|
+ T (*dereference)(void *){nullptr};
|
|
|
+ bool (*compare)(void *, void *){nullptr};
|
|
|
+ void (*advance)(void *){nullptr};
|
|
|
+ char const * type_{nullptr};
|
|
|
+ detail::ifd_pointer impl_{};
|
|
|
+
|
|
|
public:
|
|
|
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)
|
|
|
- : STREAM_ITERATOR_COPY(), impl_(copy(other.impl_)) {}
|
|
|
-
|
|
|
- iterator(iterator && other) : STREAM_ITERATOR_COPY(), impl_(other.impl_) {
|
|
|
- other.impl_ = nullptr;
|
|
|
- }
|
|
|
-
|
|
|
- iterator & operator=(iterator const & other) {
|
|
|
- return *this = iterator{other};
|
|
|
- }
|
|
|
-
|
|
|
- iterator & operator=(iterator && other) {
|
|
|
- swap(*this, other);
|
|
|
- return *this;
|
|
|
- }
|
|
|
+ template <typename Iter>
|
|
|
+ iterator(Iter impl)
|
|
|
+ : dereference(&iterator::dereference_<Iter>),
|
|
|
+ compare(&iterator::compare_<Iter>),
|
|
|
+ advance(&iterator::advance_<Iter>), type_(typeid(Iter).name()),
|
|
|
+ impl_(std::forward<Iter>(impl)) {}
|
|
|
|
|
|
- ~iterator() {
|
|
|
- if (destroy) destroy(impl_);
|
|
|
- }
|
|
|
-
|
|
|
- T operator*() const { return dereference(impl_); }
|
|
|
+ T operator*() const { return dereference(impl_.get()); }
|
|
|
iterator & operator++() {
|
|
|
- advance(impl_);
|
|
|
+ advance(impl_.get());
|
|
|
return *this;
|
|
|
}
|
|
|
+
|
|
|
bool operator==(iterator const & other) const {
|
|
|
if (strcmp(type_, other.type_)) { return false; }
|
|
|
- return compare(impl_, other.impl_);
|
|
|
+ return compare(impl_.get(), other.impl_.get());
|
|
|
}
|
|
|
+
|
|
|
bool operator!=(iterator const & other) const {
|
|
|
if (strcmp(type_, other.type_)) { return false; }
|
|
|
- return !compare(impl_, other.impl_);
|
|
|
+ return !compare(impl_.get(), other.impl_.get());
|
|
|
}
|
|
|
|
|
|
private:
|
|
|
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};
|
|
|
+
|
|
|
+ template <typename It> static T dereference_(void * p) {
|
|
|
+ return **((It *)p);
|
|
|
+ }
|
|
|
+ template <typename It> static bool compare_(void * l, void * r) {
|
|
|
+ return *((It *)l) == *((It *)r);
|
|
|
+ }
|
|
|
+ template <typename It> static void advance_(void * p) { ++(*(It *)(p)); }
|
|
|
};
|
|
|
|
|
|
namespace detail {
|