By default, enums are treated as though they are integers. This works well for serialisation, but if the data is meant to be read by a human, it is desirable to display the enums in symbolic form.
In order to do this, classdesc will emit descriptors using
Enum_handle<E>
, where E
is an enum, which wraps an enum
variable. In particular, the Enum_handle
will return a string
symbolic representation of the enum, or assign the appropriate value
to the enum variable when assigned a string constant representing the
symbolic value of the enum:
template <class T> //T is an enum class Enum_handle { public: Enum_handle(T& arg); // wrap enum arg operator std::string() const; //symbolic form of enum operator int() const; //integral value of the enum const Enum_handle& operator=(T x); const Enum_handle& operator=(int x); const Enum_handle& operator=(const std::string& x); //symbolic assignment };Classdesc handles writing the dictionaries needed to perform this conversion to and from symbolic constants. See the
xml_pack
descriptor for an example of its use.
Access to the enum reflection data is via the EnumKeys class
template <class T> class EnumKeys { public: int operator()(std::string key); std::string operator()(int val); size_t size() const; iterator begin() const; iterator end() const; Siterator sbegin() const {return begin();} Siterator send() const {return end();} Viterator vbegin() const {return begin();} Viterator vend() const {return end();} }; template <class T> const EnumKeys<T>& enum_keys();So
enum_keys<enum Foo>()("bar")
returns the numerical value of
the enum constant bar
and enum_keys<enum Foo>()(bar)
returns the string value "bar"
.
The various iterators allow iteration, or population of containers:
const EnumKeys<Foo> e(enum_keys<Foo>()); map<Foo,string> m(e.begin(), e.end()); vector<string> s(e.sbegin(), e.send()); vector<Foo> v(e.vbegin(), e.vend()); for (auto i: enum_keys<Foo>()) cout << i.second <<"="<<i.first<< endl;