Last active
October 1, 2020 21:26
-
-
Save deiuch/8e82306596a6cd876f4b72ef5e012054 to your computer and use it in GitHub Desktop.
Cyclic iterator implementation draft.
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
#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_ |
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 <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