Created
December 21, 2017 22:28
-
-
Save langthom/0dcfed25c5c058def8b554ad7542eb93 to your computer and use it in GitHub Desktop.
This file contains hidden or 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
// Short snippet for a custom iterator, taken from cppreference. | |
// Minimally adapted, just for the sake of showing it. | |
// clang++ -Wall -std=c++1z -o rangetest -O3 Range.cc | |
#include <iostream> | |
#include <iterator> | |
namespace range { | |
// A simple range [From .. To] | |
template<int From, int To> | |
class Range { | |
public: | |
// A custom forward iterator able to return the current processed number. | |
class range_iterator : std::iterator< | |
std::forward_iterator_tag, // Mark it as a forward iterator. | |
int // Type returned on dereferencation | |
> { | |
public: | |
range_iterator(int current_) : current(current_) {} | |
// SFINAE overload #1: If T >= F i.e. if we have a positive range, | |
// increment the current element. | |
template<int F = From, int T = To> | |
typename std::enable_if<(T >= F), void>::type operator++() { | |
current++; | |
} | |
// SFINAE overload #2: If Tr < Fr i.e. if we have a negative range | |
// like [5 .. 1], decrement the counter. | |
template<int Fr = From, int Tr = To> | |
typename std::enable_if<(Tr < Fr), void>::type operator++() { | |
current--; | |
} | |
// Comparsion operators. | |
bool operator==(const range_iterator& other) { return current == other.current; } | |
bool operator!=(const range_iterator& other) { return !(current == other.current); } | |
// Dereferencing operator. | |
int operator*() { return current; } | |
private: | |
int current; // Currently "processed" element of range. | |
}; | |
// Begin: Start from "From". | |
range_iterator begin() { return range_iterator(From); } | |
// End: If we have a positive range, end one past the To value, if we have a | |
// negative range (e.g. 5..1), then end at one past the lowest element. | |
range_iterator end() { return range_iterator(To >= From ? To + 1 : To - 1); } | |
}; | |
} // range | |
int main(void) { | |
auto positiveRange = range::Range<1, 5>(); | |
for (auto&& current : positiveRange) { | |
std::cout << "+ Range it: " << current << std::endl; | |
} | |
std::cout << std::endl; | |
auto negativeRange = range::Range<5, 1>(); | |
for (auto&& current : negativeRange) { | |
std::cout << "- Range it: " << current << std::endl; | |
} | |
return 0; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment