Skip to content

Instantly share code, notes, and snippets.

@langthom
Created December 21, 2017 22:28
Show Gist options
  • Save langthom/0dcfed25c5c058def8b554ad7542eb93 to your computer and use it in GitHub Desktop.
Save langthom/0dcfed25c5c058def8b554ad7542eb93 to your computer and use it in GitHub Desktop.
// 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