Skip to content

Instantly share code, notes, and snippets.

@deiuch
Last active October 1, 2020 21:26
Show Gist options
  • Save deiuch/8e82306596a6cd876f4b72ef5e012054 to your computer and use it in GitHub Desktop.
Save deiuch/8e82306596a6cd876f4b72ef5e012054 to your computer and use it in GitHub Desktop.
Cyclic iterator implementation draft.
#ifndef CYCLIC_ITERATOR_HPP_
#define CYCLIC_ITERATOR_HPP_
#include <iterator>
namespace std {
template <class ForwardIt>
class cyclic_iterator {
public:
using iterator_type = ForwardIt;
using iterator_concept = std::forward_iterator_tag;
using iterator_category = std::forward_iterator_tag;
using value_type = std::iter_value_t<ForwardIt>;
using difference_type = std::iter_difference_t<ForwardIt>;
using pointer = typename std::iterator_traits<ForwardIt>::pointer;
using reference = std::iter_reference_t<ForwardIt>;
constexpr cyclic_iterator() = default;
constexpr cyclic_iterator(iterator_type begin, iterator_type end)
: begin_{move(begin)}, end_{move(end)}, curr_{begin_} {}
[[nodiscard]] constexpr iterator_type begin() const { return begin_; }
[[nodiscard]] constexpr iterator_type end() const { return end_; }
[[nodiscard]] constexpr iterator_type base() const { return curr_; }
[[nodiscard]] constexpr reference operator*() const { return *curr_; }
[[nodiscard]] constexpr pointer operator->() const {
if constexpr (std::is_pointer_v<iterator_type>) {
return curr_;
} else {
return curr_.operator->();
}
}
constexpr cyclic_iterator& operator++() {
++curr_;
if (!(curr_ != end_)) {
curr_ = begin_;
}
return *this;
}
constexpr cyclic_iterator operator++(int) {
cyclic_iterator tmp = *this;
++*this;
return tmp;
}
private:
const iterator_type begin_, end_;
iterator_type curr_;
};
template <class ForwardIt1, class ForwardIt2>
[[nodiscard]] constexpr bool operator!=(
const cyclic_iterator<ForwardIt1>& left,
const cyclic_iterator<ForwardIt2>& right) {
return left.base() != right.base();
}
template <class ForwardIt>
[[nodiscard]] constexpr cyclic_iterator<ForwardIt> cycle(ForwardIt begin,
ForwardIt end) {
return cyclic_iterator<ForwardIt>{move(begin), move(end)};
}
template <class Container>
[[nodiscard]] constexpr cyclic_iterator<typename Container::iterator> cycle(
Container& c) {
return cycle(begin(c), end(c));
}
template <class Container>
[[nodiscard]] constexpr cyclic_iterator<typename Container::const_iterator>
cycle(const Container& c) {
return cycle(cbegin(c), cend(c));
}
} // namespace std
#endif // CYCLIC_ITERATOR_HPP_
#include <algorithm>
#include <array>
#include <forward_list>
#include <map>
#include <string>
#include <string_view>
#include "cyclic_iterator.hpp"
int main() {
const std::forward_list<int> nums = {1, 2, 3};
const std::array<std::string, 7> names = {"Denis", "Ivan", "Peter", "Nickolas",
"Alice", "Bob", "Andrew"};
std::map<std::string_view, int> mapped_names;
std::transform(names.begin(), names.end(), std::cycle(nums),
std::inserter(mapped_names, mapped_names.end()),
[](const std::string_view name,
const int n) -> decltype(mapped_names)::value_type {
return {name, n};
});
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment