fork(1) download
  1. #include <functional>
  2. #include <numeric>
  3. #include <iostream>
  4. #include <tuple>
  5. #include <vector>
  6.  
  7. template <typename...T>
  8. class ZipIterator
  9. {
  10. public:
  11.  
  12. using reference = std::tuple<decltype(*std::declval<T>())...>;
  13.  
  14. public:
  15.  
  16. ZipIterator(T&&...i) : m(std::forward<T>(i)...) { };
  17.  
  18. reference operator * () const { return std::tie(*std::get<T>(m)...); }
  19. ZipIterator operator ++ () { char c[]{ (++std::get<T>(m), 0)... }; return *this; }
  20.  
  21. bool operator == (const ZipIterator& other) const {
  22. const bool eq[]{ (std::get<T>(m) == std::get<T>(other.m))... };
  23. return std::accumulate(std::begin(eq), std::end(eq), false, std::logical_or<>());
  24. }
  25. bool operator != (const ZipIterator& other) const { return !(*this == other); }
  26.  
  27. private:
  28. std::tuple<T...> m;
  29. };
  30.  
  31. template <typename T>
  32. struct IteratorRange
  33. {
  34. T m_begin;
  35. T m_end;
  36.  
  37. const T& begin() const { return m_begin; }
  38. const T& end() const { return m_end; }
  39. };
  40.  
  41. template <typename...T>
  42. using ZipRange = IteratorRange<ZipIterator<decltype(std::begin(std::declval<T>()))...>>;
  43.  
  44. template <typename...T>
  45. ZipRange<T...> make_zip_range(T&&...t) { return {{std::begin(t)...},{ std::end(t)...} }; }
  46.  
  47. int main()
  48. {
  49. std::vector<int> a { 1, 2, 3 };
  50. std::vector<std::string> b { "hello", "world", "foo", "bar" };
  51. int c[] { 9, 8, 7, 6, 5, 4, 3, 2, 1, 0 };
  52.  
  53. for (auto&& entry : make_zip_range(a, b, c))
  54. {
  55. std::cout << std::get<0>(entry) << ", " << std::get<1>(entry) << ", " << std::get<2>(entry) << std::endl;
  56. }
  57. }
  58.  
  59.  
Success #stdin #stdout 0s 4392KB
stdin
Standard input is empty
stdout
1, hello, 9
2, world, 8
3, foo, 7