#include <iostream>
#include <stdexcept>
#include <type_traits>
//Concept looted from https://stackoverflow.com/a/16000226
// definitely take the time to read the answer to grok what's going on.
template < typename T, typename = int >
struct HasFirst : std:: false_type { } ;
template < typename T>
struct HasFirst < T, decltype( ( void ) T:: First , 0 ) > : std:: true_type { } ;
template < typename T, typename = int >
struct HasLast : std:: false_type { } ;
template < typename T>
struct HasLast < T, decltype( ( void ) T:: Last , 0 ) > : std:: true_type { } ;
template < class TYPE>
TYPE do_conversion( int value)
{
static_assert( HasFirst< TYPE> :: value , "Need First" ) ;
static_assert( HasLast< TYPE> :: value , "Need Last" ) ;
if ( value >= static_cast < int > ( TYPE:: First ) &&
value < static_cast < int > ( TYPE:: Last ) )
{
return static_cast < TYPE> ( value) ;
}
throw std:: out_of_range ( "Inv value" ) ;
}
enum class Weekday
{
Monday,
Tuesday,
Wednesday,
Thursday,
Friday,
Saturday,
Sunday,
Last,
First = Monday
} ;
void demo( int value)
{
try
{
std:: cout << "Day " << value << " is " ;
switch ( do_conversion< Weekday> ( value) )
{
case Weekday:: Monday :
std:: cout << "Monday\n " ;
break ;
case Weekday:: Tuesday :
std:: cout << "Tuesday\n " ;
break ;
case Weekday:: Wednesday :
std:: cout << "Wednesday\n " ;
break ;
case Weekday:: Thursday :
std:: cout << "Thursday\n " ;
break ;
case Weekday:: Friday :
std:: cout << "Friday\n " ;
break ;
case Weekday:: Saturday :
std:: cout << "Saturday\n " ;
break ;
case Weekday:: Sunday :
std:: cout << "Sunday\n " ;
break ;
default :
std:: cout << "Huh. How did we get here?\n " ;
break ;
}
}
catch ( const std:: out_of_range & ) {
std:: cout << "Invalid\n " ;
}
}
int main( )
{
for ( int i = - 1 ; i < 10 ; i++ )
{
demo( i) ;
}
}
I2luY2x1ZGUgPGlvc3RyZWFtPgojaW5jbHVkZSA8c3RkZXhjZXB0PgojaW5jbHVkZSA8dHlwZV90cmFpdHM+Ci8vQ29uY2VwdCBsb290ZWQgZnJvbSBodHRwczovL3N0YWNrb3ZlcmZsb3cuY29tL2EvMTYwMDAyMjYKLy8gZGVmaW5pdGVseSB0YWtlIHRoZSB0aW1lIHRvIHJlYWQgdGhlIGFuc3dlciB0byBncm9rIHdoYXQncyBnb2luZyBvbi4KdGVtcGxhdGUgPHR5cGVuYW1lIFQsIHR5cGVuYW1lID0gaW50PgpzdHJ1Y3QgSGFzRmlyc3QgOiBzdGQ6OmZhbHNlX3R5cGUgeyB9OwoKdGVtcGxhdGUgPHR5cGVuYW1lIFQ+CnN0cnVjdCBIYXNGaXJzdCA8VCwgZGVjbHR5cGUoKHZvaWQpIFQ6OkZpcnN0LCAwKT4gOiBzdGQ6OnRydWVfdHlwZSB7IH07Cgp0ZW1wbGF0ZSA8dHlwZW5hbWUgVCwgdHlwZW5hbWUgPSBpbnQ+CnN0cnVjdCBIYXNMYXN0IDogc3RkOjpmYWxzZV90eXBlIHsgfTsKCnRlbXBsYXRlIDx0eXBlbmFtZSBUPgpzdHJ1Y3QgSGFzTGFzdCA8VCwgZGVjbHR5cGUoKHZvaWQpIFQ6Okxhc3QsIDApPiA6IHN0ZDo6dHJ1ZV90eXBlIHsgfTsKCnRlbXBsYXRlIDxjbGFzcyBUWVBFPgpUWVBFIGRvX2NvbnZlcnNpb24oaW50IHZhbHVlKQp7CiAgICBzdGF0aWNfYXNzZXJ0KEhhc0ZpcnN0PFRZUEU+Ojp2YWx1ZSwgIk5lZWQgRmlyc3QiKTsKICAgIHN0YXRpY19hc3NlcnQoSGFzTGFzdDxUWVBFPjo6dmFsdWUsICJOZWVkIExhc3QiKTsKICAgIGlmICh2YWx1ZSA+PSBzdGF0aWNfY2FzdDxpbnQ+KFRZUEU6OkZpcnN0KSAmJgogICAgICAgIHZhbHVlIDwgc3RhdGljX2Nhc3Q8aW50PihUWVBFOjpMYXN0KSkKICAgIHsKICAgICAgICByZXR1cm4gc3RhdGljX2Nhc3Q8VFlQRT4odmFsdWUpOwogICAgfQogICAgdGhyb3cgc3RkOjpvdXRfb2ZfcmFuZ2UoIkludiB2YWx1ZSIpOwp9CgplbnVtIGNsYXNzIFdlZWtkYXkKewogICAgTW9uZGF5LAogICAgVHVlc2RheSwKICAgIFdlZG5lc2RheSwKICAgIFRodXJzZGF5LAogICAgRnJpZGF5LAogICAgU2F0dXJkYXksCiAgICBTdW5kYXksCiAgICBMYXN0LAogICAgRmlyc3QgPSBNb25kYXkKfTsKCnZvaWQgZGVtbyhpbnQgdmFsdWUpCnsKICAgIHRyeQogICAgewogICAgICAgIHN0ZDo6Y291dCA8PCAiRGF5ICIgPDwgdmFsdWUgPDwgIiBpcyAiOwogICAgICAgIHN3aXRjaCAoZG9fY29udmVyc2lvbjxXZWVrZGF5Pih2YWx1ZSkpCiAgICAgICAgewogICAgICAgICAgICBjYXNlIFdlZWtkYXk6Ok1vbmRheToKICAgICAgICAgICAgICAgIHN0ZDo6Y291dCA8PCAiTW9uZGF5XG4iOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgIGNhc2UgV2Vla2RheTo6VHVlc2RheToKICAgICAgICAgICAgICAgIHN0ZDo6Y291dCA8PCAiVHVlc2RheVxuIjsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICBjYXNlIFdlZWtkYXk6OldlZG5lc2RheToKICAgICAgICAgICAgICAgIHN0ZDo6Y291dCA8PCAiV2VkbmVzZGF5XG4iOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgIGNhc2UgV2Vla2RheTo6VGh1cnNkYXk6CiAgICAgICAgICAgICAgICBzdGQ6OmNvdXQgPDwgIlRodXJzZGF5XG4iOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgIGNhc2UgV2Vla2RheTo6RnJpZGF5OgogICAgICAgICAgICAgICAgc3RkOjpjb3V0IDw8ICJGcmlkYXlcbiI7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgY2FzZSBXZWVrZGF5OjpTYXR1cmRheToKICAgICAgICAgICAgICAgIHN0ZDo6Y291dCA8PCAiU2F0dXJkYXlcbiI7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgY2FzZSBXZWVrZGF5OjpTdW5kYXk6CiAgICAgICAgICAgICAgICBzdGQ6OmNvdXQgPDwgIlN1bmRheVxuIjsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICBkZWZhdWx0OgogICAgICAgICAgICAgICAgc3RkOjpjb3V0IDw8ICJIdWguIEhvdyBkaWQgd2UgZ2V0IGhlcmU/XG4iOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgfQogICAgfQogICAgY2F0Y2ggKGNvbnN0IHN0ZDo6b3V0X29mX3JhbmdlJiApIHsKICAgICAgICBzdGQ6OmNvdXQgPDwgIkludmFsaWRcbiI7CiAgICB9Cn0KCmludCBtYWluKCkKewogICAgZm9yIChpbnQgaSA9IC0xOyBpIDwgMTA7IGkrKykKICAgIHsKICAgICAgICBkZW1vKGkpOwogICAgfQp9Cg==