Skip to content

Instantly share code, notes, and snippets.

@juliangaal
Created January 22, 2019 11:08
Show Gist options
  • Save juliangaal/943dcaa2396462b68780e4feca71df6d to your computer and use it in GitHub Desktop.
Save juliangaal/943dcaa2396462b68780e4feca71df6d to your computer and use it in GitHub Desktop.
enumerate and zip operators (similar to python) for C++
// tested with xcode10 and g++8.2
namespace tools
{
template<typename T,
typename TIter = decltype(std::begin(std::declval<T>())),
typename = decltype(std::end(std::declval<T>()))>
constexpr auto enumerate(T &&iterable)
{
struct iterator
{
size_t i;
TIter iter;
bool operator!=(const iterator &other) const
{
return iter != other.iter;
}
void operator++()
{
++i;
++iter;
}
auto operator*() const
{
return std::tie(i, *iter);
}
};
struct iterable_wrapper
{
T iterable;
auto begin()
{
return iterator{0, std::begin(iterable)};
}
auto end()
{
return iterator{0, std::end(iterable)};
}
};
return iterable_wrapper{std::forward<T>(iterable)};
}
template<typename T,
typename S,
typename TIter = decltype(std::begin(std::declval<T>())),
typename SIter = decltype(std::begin(std::declval<S>()))>
constexpr auto zip(T &&iterable1, S &&iterable2)
{
struct iterator
{
TIter iter1;
SIter iter2;
bool operator!=(const iterator &other) const
{
return iter1 != other.iter1 && iter2 != other.iter2;
}
void operator++()
{
++iter1;
++iter2;
}
auto operator*() const
{
return std::tie(*iter1, *iter2);
}
};
struct iterable_wrapper
{
T iterable1;
S iterable2;
auto begin()
{
return iterator{std::begin(iterable1), std::begin(iterable2)};
}
auto end()
{
return iterator{std::end(iterable1), std::end(iterable2)};
}
};
assert(iterable1.size() == iterable2.size());
return iterable_wrapper{std::forward<T>(iterable1), std::forward<S>(iterable2)};
}
} // namespace tools
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment