|
1 |
| -# **`enum_traits`** |
| 1 | +# **`enum_traits`** and **`enumerator_traits`** |
2 | 2 |
|
3 | 3 | ## **`enum_traits`** for properties of C / C++ enum types
|
4 | 4 |
|
5 |
| -> C++17. Targets GCC, Clang, MSVC. Namespace `ltl`. |
| 5 | +> C++17. Targets GCC & Clang (MSVC is WIP). Namespace `ltl`. |
6 | 6 |
|
7 | 7 | <details><summary>Copyright © 2019 Will Wray. Distributed under the Boost Software License, V1.0</summary>
|
8 | 8 |
|
@@ -39,18 +39,272 @@ Also at [boost.org](http://www.boost.org/LICENSE_1_0.txt) and accompanying file
|
39 | 39 | </details>
|
40 | 40 |
|
41 | 41 | ```C++
|
42 |
| - ltl::is_scoped_enum<T>; // Test if type T is a scoped enum (lazy). |
43 |
| - ltl::is_scoped_enum_v<T>; // Test if type T is a scoped enum (eager). |
| 42 | + ltl::is_scoped_enum<T>; // Test if type T is a scoped enum (lazy). |
| 43 | + ltl::is_scoped_enum_v<T>; // Test if type T is a scoped enum (eager). |
44 | 44 |
|
45 |
| - ltl::is_fixed_enum<T>; // Test if type T is a 'fixed' enum, |
46 |
| - ltl::is_fixed_enum_v<T>; // i.e. an enum with fixed underlying type. |
| 45 | + ltl::is_fixed_enum<T>; // Test if type T is a 'fixed' enum, |
| 46 | + ltl::is_fixed_enum_v<T>; // i.e. an enum with fixed underlying type. |
47 | 47 |
|
48 |
| - ltl::underlying_type<T>; // c++17 port of c++20's improved UB-free |
49 |
| - // 'SFINAE-friendly' std::underlying_type. |
| 48 | + ltl::underlying_type<T>; // c++17 port of c++20's improved UB-free |
| 49 | + ltl::underlying_type_t<T>; // 'SFINAE-friendly' std::underlying_type. |
50 | 50 |
|
51 |
| - ltl::to_underlying(e); // Convenience cast to underlying type P1682. |
| 51 | + ltl::to_underlying(e); // Convenience cast to underlying type P1682. |
52 | 52 | ```
|
53 | 53 |
|
| 54 | +## **`enumerator_traits`** for reflection of enumerated values |
| 55 | +
|
| 56 | +> C++17. Targets GCC>=9 and Clang (recent MSVC possible). Namespace `ltl`. |
| 57 | +
|
| 58 | +<details><summary>Copyright © 2019 Will Wray. Distributed under LGPL-3.0-or-later.</summary> |
| 59 | +
|
| 60 | +```txt |
| 61 | + GNU LESSER GENERAL PUBLIC LICENSE |
| 62 | + Version 3, 29 June 2007 |
| 63 | +
|
| 64 | + Copyright (C) 2007 Free Software Foundation, Inc. <https://fsf.org/> |
| 65 | + Everyone is permitted to copy and distribute verbatim copies |
| 66 | + of this license document, but changing it is not allowed. |
| 67 | +
|
| 68 | +
|
| 69 | + This version of the GNU Lesser General Public License incorporates |
| 70 | +the terms and conditions of version 3 of the GNU General Public |
| 71 | +License, supplemented by the additional permissions listed below. |
| 72 | +
|
| 73 | + 0. Additional Definitions. |
| 74 | +
|
| 75 | + As used herein, "this License" refers to version 3 of the GNU Lesser |
| 76 | +General Public License, and the "GNU GPL" refers to version 3 of the GNU |
| 77 | +General Public License. |
| 78 | +
|
| 79 | + "The Library" refers to a covered work governed by this License, |
| 80 | +other than an Application or a Combined Work as defined below. |
| 81 | +
|
| 82 | + An "Application" is any work that makes use of an interface provided |
| 83 | +by the Library, but which is not otherwise based on the Library. |
| 84 | +Defining a subclass of a class defined by the Library is deemed a mode |
| 85 | +of using an interface provided by the Library. |
| 86 | +
|
| 87 | + A "Combined Work" is a work produced by combining or linking an |
| 88 | +Application with the Library. The particular version of the Library |
| 89 | +with which the Combined Work was made is also called the "Linked |
| 90 | +Version". |
| 91 | +
|
| 92 | + The "Minimal Corresponding Source" for a Combined Work means the |
| 93 | +Corresponding Source for the Combined Work, excluding any source code |
| 94 | +for portions of the Combined Work that, considered in isolation, are |
| 95 | +based on the Application, and not on the Linked Version. |
| 96 | +
|
| 97 | + The "Corresponding Application Code" for a Combined Work means the |
| 98 | +object code and/or source code for the Application, including any data |
| 99 | +and utility programs needed for reproducing the Combined Work from the |
| 100 | +Application, but excluding the System Libraries of the Combined Work. |
| 101 | +
|
| 102 | + 1. Exception to Section 3 of the GNU GPL. |
| 103 | +
|
| 104 | + You may convey a covered work under sections 3 and 4 of this License |
| 105 | +without being bound by section 3 of the GNU GPL. |
| 106 | +
|
| 107 | + 2. Conveying Modified Versions. |
| 108 | +
|
| 109 | + If you modify a copy of the Library, and, in your modifications, a |
| 110 | +facility refers to a function or data to be supplied by an Application |
| 111 | +that uses the facility (other than as an argument passed when the |
| 112 | +facility is invoked), then you may convey a copy of the modified |
| 113 | +version: |
| 114 | +
|
| 115 | + a) under this License, provided that you make a good faith effort to |
| 116 | + ensure that, in the event an Application does not supply the |
| 117 | + function or data, the facility still operates, and performs |
| 118 | + whatever part of its purpose remains meaningful, or |
| 119 | +
|
| 120 | + b) under the GNU GPL, with none of the additional permissions of |
| 121 | + this License applicable to that copy. |
| 122 | +
|
| 123 | + 3. Object Code Incorporating Material from Library Header Files. |
| 124 | +
|
| 125 | + The object code form of an Application may incorporate material from |
| 126 | +a header file that is part of the Library. You may convey such object |
| 127 | +code under terms of your choice, provided that, if the incorporated |
| 128 | +material is not limited to numerical parameters, data structure |
| 129 | +layouts and accessors, or small macros, inline functions and templates |
| 130 | +(ten or fewer lines in length), you do both of the following: |
| 131 | +
|
| 132 | + a) Give prominent notice with each copy of the object code that the |
| 133 | + Library is used in it and that the Library and its use are |
| 134 | + covered by this License. |
| 135 | +
|
| 136 | + b) Accompany the object code with a copy of the GNU GPL and this license |
| 137 | + document. |
| 138 | +
|
| 139 | + 4. Combined Works. |
| 140 | +
|
| 141 | + You may convey a Combined Work under terms of your choice that, |
| 142 | +taken together, effectively do not restrict modification of the |
| 143 | +portions of the Library contained in the Combined Work and reverse |
| 144 | +engineering for debugging such modifications, if you also do each of |
| 145 | +the following: |
| 146 | +
|
| 147 | + a) Give prominent notice with each copy of the Combined Work that |
| 148 | + the Library is used in it and that the Library and its use are |
| 149 | + covered by this License. |
| 150 | +
|
| 151 | + b) Accompany the Combined Work with a copy of the GNU GPL and this license |
| 152 | + document. |
| 153 | +
|
| 154 | + c) For a Combined Work that displays copyright notices during |
| 155 | + execution, include the copyright notice for the Library among |
| 156 | + these notices, as well as a reference directing the user to the |
| 157 | + copies of the GNU GPL and this license document. |
| 158 | +
|
| 159 | + d) Do one of the following: |
| 160 | +
|
| 161 | + 0) Convey the Minimal Corresponding Source under the terms of this |
| 162 | + License, and the Corresponding Application Code in a form |
| 163 | + suitable for, and under terms that permit, the user to |
| 164 | + recombine or relink the Application with a modified version of |
| 165 | + the Linked Version to produce a modified Combined Work, in the |
| 166 | + manner specified by section 6 of the GNU GPL for conveying |
| 167 | + Corresponding Source. |
| 168 | +
|
| 169 | + 1) Use a suitable shared library mechanism for linking with the |
| 170 | + Library. A suitable mechanism is one that (a) uses at run time |
| 171 | + a copy of the Library already present on the user's computer |
| 172 | + system, and (b) will operate properly with a modified version |
| 173 | + of the Library that is interface-compatible with the Linked |
| 174 | + Version. |
| 175 | +
|
| 176 | + e) Provide Installation Information, but only if you would otherwise |
| 177 | + be required to provide such information under section 6 of the |
| 178 | + GNU GPL, and only to the extent that such information is |
| 179 | + necessary to install and execute a modified version of the |
| 180 | + Combined Work produced by recombining or relinking the |
| 181 | + Application with a modified version of the Linked Version. (If |
| 182 | + you use option 4d0, the Installation Information must accompany |
| 183 | + the Minimal Corresponding Source and Corresponding Application |
| 184 | + Code. If you use option 4d1, you must provide the Installation |
| 185 | + Information in the manner specified by section 6 of the GNU GPL |
| 186 | + for conveying Corresponding Source.) |
| 187 | +
|
| 188 | + 5. Combined Libraries. |
| 189 | +
|
| 190 | + You may place library facilities that are a work based on the |
| 191 | +Library side by side in a single library together with other library |
| 192 | +facilities that are not Applications and are not covered by this |
| 193 | +License, and convey such a combined library under terms of your |
| 194 | +choice, if you do both of the following: |
| 195 | +
|
| 196 | + a) Accompany the combined library with a copy of the same work based |
| 197 | + on the Library, uncombined with any other library facilities, |
| 198 | + conveyed under the terms of this License. |
| 199 | +
|
| 200 | + b) Give prominent notice with the combined library that part of it |
| 201 | + is a work based on the Library, and explaining where to find the |
| 202 | + accompanying uncombined form of the same work. |
| 203 | +
|
| 204 | + 6. Revised Versions of the GNU Lesser General Public License. |
| 205 | +
|
| 206 | + The Free Software Foundation may publish revised and/or new versions |
| 207 | +of the GNU Lesser General Public License from time to time. Such new |
| 208 | +versions will be similar in spirit to the present version, but may |
| 209 | +differ in detail to address new problems or concerns. |
| 210 | +
|
| 211 | + Each version is given a distinguishing version number. If the |
| 212 | +Library as you received it specifies that a certain numbered version |
| 213 | +of the GNU Lesser General Public License "or any later version" |
| 214 | +applies to it, you have the option of following the terms and |
| 215 | +conditions either of that published version or of any later version |
| 216 | +published by the Free Software Foundation. If the Library as you |
| 217 | +received it does not specify a version number of the GNU Lesser |
| 218 | +General Public License, you may choose any version of the GNU Lesser |
| 219 | +General Public License ever published by the Free Software Foundation. |
| 220 | +
|
| 221 | + If the Library as you received it specifies that a proxy can decide |
| 222 | +whether future versions of the GNU Lesser General Public License shall |
| 223 | +apply, that proxy's public statement of acceptance of any version is |
| 224 | +permanent authorization for you to choose that version for the |
| 225 | +Library. |
| 226 | +``` |
| 227 | + |
| 228 | +[](https://www.boost.org/LICENSE_1_0.txt) |
| 229 | + |
| 230 | +Also at [boost.org](http://www.boost.org/LICENSE_1_0.txt) and accompanying file [LICENSE_1_0.txt](LICENSE_1_0.txt) |
| 231 | + |
| 232 | +</details> |
| 233 | + |
| 234 | +---- |
| 235 | + |
| 236 | +```C++ |
| 237 | + ltl::is_enumerated_v<e>; // Test if enum value e corresponds to an |
| 238 | + // enumerator of its enum type decltype(e). |
| 239 | + |
| 240 | + ltl::enumerators_v<E>; // Array of enumerated values of enum type E |
| 241 | + // (see note on duplicate-valued enumerators). |
| 242 | + ltl::enumerators_t<E>; // integer_sequence<underlying_type_t<E>,u...> |
| 243 | + // of E's enumerators' underlying values u... |
| 244 | + ltl::enumerators<E>; // Trait class for enumerated values of E with |
| 245 | + // array 'value' and typedef 'type' members. |
| 246 | +``` |
| 247 | + |
| 248 | +The array returned by `enumerators_v` is of an internal type, sufficient |
| 249 | +to index, |
| 250 | +range-for iterate or copy into another container. |
| 251 | + |
| 252 | +## Description |
| 253 | + |
| 254 | +Two header-only libraries of 'type traits'; template-based utilities to query: |
| 255 | + |
| 256 | +1. **`enum_traits`** Properties of enum types |
| 257 | +2. **`enumerator_traits`** Enumerated values of an enum type |
| 258 | + |
| 259 | +The traits interface is constexpr; runtime facilities can be built on top. |
| 260 | +These libraries deal only with enumerated *values*, not with *names* of ids. |
| 261 | +Reflection of names can be dealt with at a higher level. |
| 262 | + |
| 263 | +> See the example repo for full reflection of enum types, including names. |
| 264 | +
|
| 265 | +---- |
| 266 | + |
| 267 | +## Reflection of enumerated values |
| 268 | + |
| 269 | +A 'brute force' method is used to check possible values of the underlying type. |
| 270 | +It takes around a second to exhaustively check all 2^16 values of a 16-bit enum |
| 271 | +(on a decent recent dev box - GCC faster than Clang, MSVC out of the game). |
| 272 | + |
| 273 | +### Support for `underlying_type` bit-widths |
| 274 | + |
| 275 | +Enum types with <= **16-bit** underlying type are fully supported - exhaustive check |
| 276 | +Enum types with **32-bit** underlying type are partially supported - far from exhaustive. |
| 277 | + |
| 278 | +### **32-bit** underlying type partial support |
| 279 | + |
| 280 | +2^16 values of the same-signed 16-bit integer are checked, plus: |
| 281 | + |
| 282 | +* for **uint32**, check 392 high values (`UINT16_MAX`, `UINT32_MAX`]. |
| 283 | +* for **int32**, check 32 negative values [`INT32_MIN`, `INT16_MIN`) |
| 284 | + * and 360 high positive values (`INT16_MAX`, `INT32_MAX`]. |
| 285 | + |
| 286 | +The 32-bit `Int_MAX` high ranges comprise all values with a contiguous run of set bits. |
| 287 | +This means that 'flag enums' with contiguous bitfield / bitmask values are supported. |
| 288 | + |
| 289 | +Enum types with **64-bit** underlying type are unsupported, giving a compile error. |
| 290 | + |
| 291 | +---- |
| 292 | + |
| 293 | +## Platform support |
| 294 | + |
| 295 | +GCC>=9 is required for a bugfix (earlier versions can be patched). |
| 296 | +MSVC is work in progress. 8-bit underlying value works. |
| 297 | +C++17 for auto template parameters, constexpr if, inline variables... |
| 298 | + |
| 299 | +### Disclaimers |
| 300 | + |
| 301 | +Enumerator extraction uses non-standard 'pretty function' preprocessor |
| 302 | +extensions whose output differs between compilers & compiler versions. |
| 303 | +This is not a future-proof solution. Use with caution. |
| 304 | +Test for your use-case and target platforms. |
| 305 | + |
| 306 | +---- |
| 307 | + |
54 | 308 | ## Build
|
55 | 309 |
|
56 | 310 | Meson build script provided, e.g. use with ninja backend
|
|
0 commit comments