Skip to content

Commit e6a13f4

Browse files
authored
Create README.md
1 parent 643a660 commit e6a13f4

File tree

1 file changed

+189
-0
lines changed

1 file changed

+189
-0
lines changed

README.md

Lines changed: 189 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,189 @@
1+
# enum_values
2+
Yet another post-build step and class to bring reflection to C++ enumerations!
3+
4+
# Description
5+
6+
This project consists of two parts: a pre-build step called `enum_reader` and two classes: `enum_value` and `enum_static`.
7+
8+
Given the following enumeration, the reader will parse out the enumeration and create a file name in a location of your choosing with the values and their names.
9+
10+
```cpp
11+
namespace MyNamespace
12+
{
13+
// an enumeration description!
14+
enum class theirvalues : int //ns@MyNamespace
15+
{
16+
zero, // nope
17+
one,
18+
two,
19+
also_two = two, // does it work?
20+
three, // ah!!
21+
four,
22+
five,
23+
};
24+
}
25+
```
26+
27+
It does this by creating a compilable cpp file intended to be included directly in your application that are linked to the `enum_value` and `enum_static` classes. Forward declarations of all enums it captures are included.
28+
29+
# Example
30+
31+
The above `enum` will result in a file with the following contents:
32+
33+
```cpp
34+
namespace MyNamespace
35+
{
36+
enum class theirvalues : int;
37+
}
38+
const std::string enum_static<espace::theirvalues>::enum_desc = "";
39+
const std::unordered_map<int, std::string> enum_static<MyNamespace::theirvalues>::value_to_name = {
40+
{ 0, "zero" },
41+
{ 1, "one" },
42+
{ 2, "two" },
43+
{ 2, "also_two" },
44+
{ 3, "three" },
45+
{ 4, "four" },
46+
{ 5, "five" },
47+
};
48+
const std::unordered_map<std::string, int> enum_static<MyNamespace::theirvalues>::name_to_value = {
49+
{ "zero", 0 },
50+
{ "one", 1 },
51+
{ "two", 2 },
52+
{ "also_two", 2 },
53+
{ "three", 3 },
54+
{ "four", 4 },
55+
{ "five", 5 },
56+
};
57+
```
58+
59+
# Usage
60+
61+
`enum_static` contains static versions of common enum operations:
62+
* `has_flag`
63+
* `flag_set`
64+
* `flag_remove`
65+
* `flag_toggle`
66+
* `from_string`
67+
* `to_string`
68+
* `to_flag_string`
69+
* `from_flag_string`
70+
* `iterable_by_values`
71+
* `iterable_by_name`
72+
73+
`enum_value` contains the above functions as members, as well as:
74+
* Enum value and underlying type constructor
75+
* `enum_value` assignment and equality
76+
* Postfix and prefix increment and decrement
77+
* Overloaded `operator*`, returning enum value (non-const overload allows value to be directly changed)
78+
* `data()`, returning the value of the enum's underlying type (non-const overload allows value to be directly changed)
79+
80+
```cpp
81+
// these values are used by those values, top kek!
82+
enum class myvalues
83+
{
84+
zero = 0, // nope
85+
one = 1,
86+
two = 2,
87+
88+
// this is not the world we want to save!
89+
three = 3,
90+
also_three = three, //yay?
91+
four = 4, // ahh!
92+
five = 5
93+
};
94+
95+
enum class yourvalues : int
96+
{
97+
zero, // nope
98+
one,
99+
two,
100+
also_two = two, // does it work?
101+
three, // ah!!
102+
four,
103+
five,
104+
};
105+
106+
namespace espace
107+
{
108+
enum class theirvalues : int //ns@espace
109+
{
110+
zero, // nope
111+
one,
112+
two,
113+
also_two = two, // does it work?
114+
three, // ah!!
115+
four,
116+
five,
117+
};
118+
}
119+
120+
// get description
121+
std::cout << enum_static<myvalues>::description() << std::endl;
122+
std::cout << enum_static<espace::theirvalues>::description() << std::endl;
123+
124+
// using the enum_value class to hold values (useful for flags
125+
enum_value<myvalues> val1;
126+
enum_value<myvalues> val2;
127+
128+
// reset to 0
129+
val1.clear();
130+
131+
// assign to enum
132+
val1 = myvalues::two;
133+
134+
// assignment by data()
135+
val1.data() = 10;
136+
val2.data() = 5;
137+
138+
// assignment by enum directly
139+
*val1 = myvalues::three;
140+
141+
auto ok = (val1.data() == 5);
142+
143+
// comparison of two enum_values
144+
ok = (val1 == val2);
145+
146+
// comparison by enum
147+
ok = (val1 == myvalues::three);
148+
149+
// enum_value asignment
150+
val1 = val2;
151+
152+
auto c = val1.data();
153+
std::cout << c << std::endl;
154+
155+
// iterate over full list of values
156+
for (auto v : enum_static<myvalues>::iterable_by_names())
157+
{
158+
std::cout << v.second << std::endl;
159+
}
160+
161+
// assign by string
162+
val1.from_string("zero");
163+
std::cout << val1.to_string() << std::endl;
164+
165+
// assign by string flag
166+
auto unknowns = val1.from_flag_string("one!+!two!+!four", "!+!");
167+
assert(unknowns.empty());
168+
169+
// detect unknown flag text
170+
unknowns = val1.from_flag_string("one+two+four", "!+!");
171+
assert(unknowns == "one+two+four");
172+
173+
unknowns = val1.from_flag_string("eight+sixteen+two+four+thirty-two", "+");
174+
assert(unknowns == "eight+sixteen+thirty-two");
175+
176+
// to flag string
177+
std::cout << val1.to_flag_string("+") << std::endl;
178+
179+
// pass enum direct
180+
foo(*val1);
181+
```
182+
183+
184+
# Limitations
185+
186+
The parser currently has the following limitations:
187+
* Any and all classes and namespaces required for a forward declaration are ignored. (Provide this information manually with the `//@ns` comment in the format shown.)
188+
* An alias will return the first value seen in the enum definition.
189+
* Only single-term expressions will be evaluated. `two_and_three = two | three` will currently set the value to `-1`.

0 commit comments

Comments
 (0)