
Hi all, I'm currently writing a C++ library to add some functionalities to enums, and am looking for comments and feedbacks. Boost is a reference, and I would be glad if some C++ expert here could take a moment to look at what I've written and tell me his thoughts. I know that there was already some discussions about enums here, and some early implementations of enum libraries at Boost, but I couldn't find any that fitted my requirements, or any that was in an stable enough stage. My goal wasn't to submit another one to Boost (although I would be really proud of it, I'm not thinking about it yet, just looking for comments), but to implement something usable for some of my specific needs. Initially I was only looking for enum (de)serialization, however I think that these needs can be quite common, and that the library could be used by others as well. That's why I'm trying to find some comments and to share my work. My goal was to implement a library following these requirements : - Extend the enum concept with different flavors. - Scope the enum constants out of namespace scope. - Do not get rid of implicit integer cast, or at least, try to provide enum/integer interoperability so we don't have to cast all the time. - No overhead, keep the enum constants as light as they are natively. For the first requirement, I wanted to add three new flavors to enums, that I've called "static enums", "dynamic enums" and "bit fields". The main difference between them is the way these enums are (de)serialized and the available enum / enum and enum / integer operators when this is meaningful (only when using C++0x, with scoped enums). - Static enums only allow explicitly defined constants (with specified or implicit integer values), any other value will result in a (de)serialization to special value "unknown". - Dynamic enums allow explicitly defined constants and offsets from these constants, within a given global range (from the first constant to the specified upper integer limit). Every value within the range will be serializable, any other will result in "unknown". An integer value between two enum constants will be (de)serialized as the nearest lower enum constant plus an offset. For example, if the enum is defined as { value1 = 1, value2 = 5..., unknown = 10 }, the available range would be from 1 to 9, and the integer 4 will be serialized as "value1#3" which means (value1 + 3). - Bit fields enums only allow combination of explicitely defined constants. These will be (de)serialized as a combination of every defined enum constants, any other value will be (de)serialized as "unknown". This flavor restricts constants values to bitwise distinct integers, and to values different from 0 in order to be able to decompose the enum into the specified enum constants. 0 being the special "unknown" value for this flavor. For example, for an enum defined as { bit1 = 0b001, bit2 = 0b010, bit3 = 0b100... }, an instance of this enum with an integer value of 3 will be serialized as "bit1+bit2", and "bit1+bit3" will be deserialized as an enum instance of integer value 5. As I said, the library obviously uses Boost, and in an extensive way Boost Preprocessor macros, and tries to integrate nicely with Boost libraries. Serialization, for example, is done through stream template operators, and should be usable with the Boost Lexical Cast library. These isn't any real documentation yet, except from doxygen (although not yet complete, I've tried to be verbose), but I think that the library is simple enough to be understood by reading the source code, and I've got some unit tests to help getting the genereal idea. Lastly, I still have some issues about some points, mostly because of the use of macros and boilerplate code, but I hope to be able to fix them. - No namespace support. - Enum declaration comes with the serialization code. I would like to be able to separate definition and declaration of this code, but I'm not sure how to do that properly without overhead for the developer. I'll have to think about it. - The writing overhead of the enum declaration (compared to plain old enum) is still a little bit too much for my taste, but I don't know if I'll be able to do much better without introducing some obscure and meaningless helper macros. This is mainly because of the need of declaring the enum constants in a Boost Preprocessor sequence, in order to be able to use it at various places to generate the enum declaration as well as the serialization code. - Also, the declaration could be cleaner if I could find a way to implement optional parameters in macros, but that seems like difficult to do (or I haven't found out yet how to do). - I don't have any other environment available except from my Debian Linux box, so I couldn't test on anything else than gcc. I don't really expect it to work with anything else. Actually, my main build scripts themselves are probably broken on anything else than my computer. [1] That said, if anyone wants to take a look at it and share his thoughts, the library can be found here : https://github.com/berenm/libtenum Best regards, Beren Minor Notes: [1] I've added a "portable-build" branch to my git repo if anyone want to try running the tests cases somewhere else. Build is done with bjam.