Closed lgarithm closed 6 years ago
#include <cstdio> #include <cassert> #include <tuple> #include <utility> #include <iostream> template <typename T> struct range_ { const T from; const T to; explicit range_(T n) : from(0), to(n) { std::cout << "range_(" << from << "," << to << ")" << std::endl; } explicit range_(T m, T n) : from(m), to(n) { std::cout << "range_(" << from << "," << to << ")" << std::endl; } struct iterator { T pos; explicit iterator(T pos) : pos(pos) {} bool operator!=(const iterator &it) const { return pos != it.pos; } T operator*() const { return pos; } void operator++() { ++pos; } }; auto begin() const { std::cout << "range_::begin = " << from << std::endl; return iterator(from); } auto end() const { std::cout << "range_::end = " << to << std::endl; return iterator(to); } }; template <typename T> range_<T> range(T n) { std::cout << "creating range: [" << 0 << ", " << n << ")" << std::endl; return range_<T>(n); } template <typename T> range_<T> range(T m, T n) { std::cout << "creating range: [" << m << ", " << n << ")" << std::endl; return range_<T>(m, n); } template <typename S, typename T> struct zipper { const S &a; const T &b; zipper(const S &a, const T &b) : a(a), b(b) {} template <typename I, typename J> struct iterator { I i; J j; iterator(const I &i, const J &j) : i(i), j(j) {} bool operator!=(const iterator &p) const { return i != p.i || j != p.j; } void operator++() { ++i; ++j; } auto operator*() { return std::make_pair(*i, *j); } }; template <typename I, typename J> static iterator<I, J> iter(const I &i, const J &j) { return iterator<I, J>(i, j); } auto begin() const { std::cout << "zip begin: " << *a.begin() << "," << *b.begin() << std::endl; return iter(a.begin(), b.begin()); } auto end() const { std::cout << "zip end: " << *a.end() << "," << *b.end() << std::endl; return iter(a.end(), b.end()); } }; template <typename S, typename T> zipper<S, T> zip(const S &a, const T &b) { return zipper<S, T>(a, b); } void test_1() { const int n = 10; int idx = 0; // const auto r = range(n); const auto b = n; const auto e = b + n + 1; for (auto it : zip(range(n + 1), range(b, e))) { if (idx >= n + 1) { printf("%d >= %d\n", idx, n); assert(false); } printf("%d %d\n", std::get<0>(it), std::get<1>(it)); ++idx; } } int main() { test_1(); return 0; }
No plan to do more investigation on this ATM.
Note: clang++ doesn't have this problem.