Last active
June 19, 2016 02:12
-
-
Save danshapero/4cdac531587203a50bc141cadf8a92e9 to your computer and use it in GitHub Desktop.
C++11 multi-iterator
This file contains 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 <tuple> | |
/* ============== | |
* Multi-iterator | |
* ============== */ | |
template <size_t> struct int_{}; | |
template <class... Args> | |
struct MultiIterator | |
{ | |
static const size_t size = sizeof...(Args); | |
using value_type = std::tuple<Args...>; | |
using iterator = MultiIterator<Args...>; | |
value_type& operator*() | |
{ | |
return its; | |
} | |
const value_type& operator*() const | |
{ | |
return its; | |
} | |
template <size_t N> | |
iterator& increment(int_<N>) | |
{ | |
++std::get<N>(its); | |
return increment(int_<N + 1>()); | |
} | |
iterator& increment(int_<size>) | |
{ | |
return *this; | |
} | |
iterator& operator++() | |
{ | |
return increment(int_<0>()); | |
} | |
bool operator!=(const iterator& multi_it) const | |
{ | |
return its != multi_it.its; | |
} | |
value_type its; | |
}; | |
template <class... Args> | |
MultiIterator<Args...> make_multi_iterator(Args&&... args) | |
{ | |
return MultiIterator<Args...>{std::make_tuple(args...)}; | |
} | |
template <size_t N, class Tuple, class T, class... Ts> | |
Tuple& | |
tuple_begin(int_<N>, Tuple& it, T&& t, Ts&&... ts) | |
{ | |
std::get<N>(it) = std::begin(t); | |
return tuple_begin(int_<N + 1>(), it, std::forward<Ts>(ts)...); | |
} | |
template <class Tuple, class... Ts> | |
Tuple& | |
tuple_begin(int_<std::tuple_size<Tuple>::value>, Tuple& it, Ts&&...) | |
{ | |
return it; | |
} | |
template <class... Args> | |
std::tuple<typename std::remove_reference<Args>::type::iterator...> tuple_begin(Args&&... args) | |
{ | |
std::tuple<typename std::remove_reference<Args>::type::iterator...> it; | |
it = tuple_begin(int_<0>(), it, std::forward<Args>(args)...); | |
return it; | |
} | |
/* ============ | |
* Test program | |
* ============ */ | |
#include <iostream> | |
#include <vector> | |
int main() | |
{ | |
std::vector<int> v = {0, 1, 2, 3, 4}; | |
std::vector<char> a = {'a', 'b', 'c', 'd', 'e'}; | |
for (auto it = make_multi_iterator(v.begin(), a.begin()); | |
it != make_multi_iterator(v.end(), a.end()); | |
++it) | |
std::cout << *std::get<0>(*it) << ", " << *std::get<1>(*it) << std::endl; | |
auto it = tuple_begin(v, a); | |
std::cout << *std::get<0>(it) << ", " << *std::get<1>(it) << std::endl; | |
return 0; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment