-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathenumeration.hpp
133 lines (111 loc) · 3.38 KB
/
enumeration.hpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
#ifndef NJOY_UTILITY_ENUMERATION
#define NJOY_UTILITY_ENUMERATION
// system includes
// other includes
#include "Log.hpp"
namespace njoy {
namespace utility {
namespace enumeration {
/**
* @brief Forward declaration of the templated enumeration Map used to convert
* enumeration values to/from string
*/
template < typename Enumeration >
struct Map {};
/**
* @brief Return whether or not a string is a symbol for an enumeration
*
* @param[in] value the enumeration value
*
* @return true/false
*/
template < typename Enumeration,
typename = typename std::enable_if< std::is_enum< Enumeration >::value >::type >
bool isSymbol( const std::string& symbol ) {
return Map< Enumeration >::symbols.find( symbol )
!= Map< Enumeration >::symbols.end();
}
/**
* @brief Return a string symbol of the enumeration value
*
* @param[in] value the enumeration value
*
* @return A string symbol representing the enumeration value
*/
template < typename Enumeration,
typename = typename std::enable_if< std::is_enum< Enumeration >::value >::type >
const std::string& toString( const Enumeration& value ) {
auto found = Map< Enumeration >::values.find( value );
if ( found == Map< Enumeration >::values.end() ) {
Log::error( "An enumeration value for {} has no registered symbol",
typeid( Enumeration ).name() );
throw std::exception();
}
return found->second;
}
/**
* @brief Return an enumeration value based on a string symbol
*
* @param[in] symbol the enumeration symbol
*
* @return An enumeration value derived from the string symbol
*/
template < typename Enumeration,
typename = typename std::enable_if< std::is_enum< Enumeration >::value >::type >
const Enumeration& fromString( const std::string& symbol ) {
auto found = Map< Enumeration >::symbols.find( symbol );
if ( found == Map< Enumeration >::symbols.end() ) {
Log::error( "An enumeration symbol for {} has no registered value: \"{}\"",
typeid( Enumeration ).name(), symbol );
throw std::exception();
}
return found->second;
}
/**
* @brief operator>> for enumerations
*
* @param[in] in the input stream
* @param[in] value the enumeration value
*
* @return the input stream (position is unchanged and failbit is set if no
* enumeration value could be read)
*/
template < typename Enumeration,
typename = typename std::enable_if< std::is_enum< Enumeration >::value >::type >
std::istream &operator>>( std::istream& in, Enumeration& value ) {
auto position = in.tellg();
std::string symbol;
in >> symbol;
if ( in.fail() ) {
in.clear();
in.seekg( position );
in.setstate( std::ios::failbit );
}
else {
try {
value = fromString< Enumeration >( symbol );
}
catch ( std::exception& ) {
in.seekg( position );
in.setstate( std::ios::failbit );
}
}
return in;
}
/**
* @brief operator<< for enumerations
*
* @param[in] in the input stream
* @param[in] value the enumeration value
*
* @return the output stream
*/
template < typename Enumeration,
typename = typename std::enable_if< std::is_enum< Enumeration >::value >::type >
std::ostream& operator<<( std::ostream& out, const Enumeration& value ) {
return out << toString( value );
}
} // enumeration namespace
} // utility namespace
} // njoy namespace
#endif