Skip to content

Instantly share code, notes, and snippets.

@aryan-gupta
Created September 8, 2018 02:39
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save aryan-gupta/154a179ec2d2dbbbf25aec88c4691f37 to your computer and use it in GitHub Desktop.
Save aryan-gupta/154a179ec2d2dbbbf25aec88c4691f37 to your computer and use it in GitHub Desktop.
#include <iostream>
using namespace std;
using ENUM_TYPE = int;
/// LEGEND:
///
/// for( range_declaration : range_expression )
///
/// translates to:
///
/// {
/// auto && __range = range_expression ;
/// auto __begin = begin_expr;
/// auto __end = end_expr
/// for (;__begin != __end; ++__begin) {
/// range_declaration = *__begin;
/// loop_statement
/// }
/// }
//// ============ ORDERED ==============
/// This is only valid if the enum values are one after the other
/// this way we can cast to an int, then increment it and return it
/// If the enum has weird values then we need another solution
/// See unordered_enum enum. When declaring the range based loop, the
/// range_expression may be left default init if the first enum value is 0
/// meaning if ONUM1 has a value of 0, I can type for (ordered_enum t : ordered_enum{ })
/// however if my ONUM1 has a value other than 0, I must specify the starting integer.
/// for example: for (ordered_enum t : ordered_enum{ ONUM1 }). When using the unordered_enum,
/// the starting point must always be declared
enum ordered_enum {
ONUM1,
ONUM2,
ONUM3,
ONUM4,
ONUMEND
};
ordered_enum begin(ordered_enum t) {
// return ONUM1;
return t;
}
ordered_enum end(ordered_enum t) {
return ONUMEND;
}
ordered_enum operator*(ordered_enum t) {
return t;
}
ordered_enum operator++(ordered_enum& t) {
ENUM_TYPE a = static_cast<ENUM_TYPE>(t);
return t = static_cast<ordered_enum>(++a);
}
std::ostream& operator<<(std::ostream& out, ordered_enum t) {
switch(t) {
case ONUM1:
out << "ONUM1";
break;
case ONUM2:
out << "ONUM2";
break;
case ONUM3:
out << "ONUM3";
break;
case ONUM4:
out << "ONUM4";
break;
case ONUMEND:
out << "ONUMEND";
break;
}
return out;
}
/// ============== UNORDERED ===========
/// This enum is unordered, meaning the values don't follow incrementally
/// one after the other. All the functions are the same except the ++ operator
enum unordered_enum {
UNUM1 = 10,
UNUM2 = 3,
UNUM3 = 101,
UNUM4 = -4,
UNUMEND = 0
};
unordered_enum begin(unordered_enum t) {
return t;
}
unordered_enum end(unordered_enum t) {
return UNUMEND;
}
unordered_enum operator*(unordered_enum t) {
return t;
}
unordered_enum operator++(unordered_enum& t) {
switch(t) {
case UNUM1: t = UNUM2; break;
case UNUM2: t = UNUM3; break;
case UNUM3: t = UNUM4; break;
case UNUM4: t = UNUMEND; break;
default: t = UNUM1; break;
}
return t;
}
std::ostream& operator<<(std::ostream& out, unordered_enum t) {
switch(t) {
case UNUM1:
out << "UNUM1";
break;
case UNUM2:
out << "UNUM2";
break;
case UNUM3:
out << "UNUM3";
break;
case UNUM4:
out << "UNUM4";
break;
case UNUMEND:
out << "UNUMEND";
break;
}
return out;
}
int main() {
/// Ordered tests
{
auto && range = ordered_enum{ ONUM1 };
auto begin_ = begin(range);
auto end_ = end(range);
for (;begin_ != end_; ++begin_) {
ordered_enum t = *begin_;
cout << t << endl;
}
}
cout << endl;
for (ordered_enum t : ordered_enum{ }) {
cout << t << endl;
}
cout << endl;
/// Unordered tests
{
auto && range = unordered_enum{ UNUM1 };
auto begin_ = begin(range);
auto end_ = end(range);
for (;begin_ != end_; ++begin_) {
unordered_enum t = *begin_;
cout << t << endl;
}
}
cout << endl;
for (unordered_enum t : unordered_enum{ UNUM1 }) {
cout << t << endl;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment