Created
September 8, 2018 02:39
-
-
Save aryan-gupta/154a179ec2d2dbbbf25aec88c4691f37 to your computer and use it in GitHub Desktop.
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 <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