By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
429,263 Members | 2,640 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 429,263 IT Pros & Developers. It's quick & easy.

Streaming enum in and out in symbolic form

P: n/a
*** I posted this on comp.lang.c++.moderated a couple days ago, and
got a near-flippant response from someone who clearly didn't take the
time to consider the import. I replied, and it's still not in
evidence. Maybe it's my fault for having reacted with a little
annoyance, but anyway I'm tired of waiting days for moderators, have
had several posts not get through moderation at all which were
certainly not inappropriate, and an email from someone who mentioned
their post to clc++m wasn't appearing (it never did), so am posting
here too. Hopefully that will allow some meaningfully interactive
discussion. - Tony ***

Hi all,

Every now and then on [clc++m] someone asks how to print out the
identifier(s) associated with an enum, or parse an identifier into an
enum variable. Last time it was mentioned I opened my big mouth and
promised some code to help would come out of a collaboration with
Andrew Marlow. That code is now available, and this message is
ultimately soliciting reviewers. I'm also aware that an early draft
of the enum-related proposal for C++0x postulated this functionality,
but later revisions dropped the symbolic-to-numeric abilities.
Perhaps this library could be used as a way of experimenting with,
understanding and refining such facilities with a view to
incorporation as a language feature at some time in the future...?


Streaming of symbolic values is particularly useful for logging and
serialisation, as numeric values don't convey meaning to human
readers, and if serialised in one application and read in another
version of the application with different value assignment, leads to
corrupted state.


The basic idea is that instead of declaring...

enum X { <some enumerations}; use...

SOME_MACRO(X, <some enumerations);

Agreed it's not exactly elegant, but thereafter you can stream objects
of type X in and out in symbolic form (when they exactly match one of
the identifiers). For more complex situations, you can use further
macros within the list of enumerations to associate mutually-exclusive
enumerations, bit masks, boolean bit fields, implicitly understood
values that don't need printing, i.e. intentions behind the values).
This allows the library to stream meaningful combinations of the
enumeration identifiers, falling back on numeric values only as a last


It all works by a couple simple mechanisms:

- variable number of arguments to macros (which is not Standard C++,
but is somewhat portable - GCC 3+, VC++2005+)
- stringification of enum parameters, allowing parsing to extract
enumeration identifiers on first run-time use of streaming
- capture of enumeration values

The last is a little tricky, but all the smarts boil down to:
- declare enum X { <some enumerations};
- in a more restrictive scope (so avoid identifier clashes), declare
Benum::Incrementing<TYPE<some enumerations>;
which creates a list of variables, of a user-defined type that
stores integers and increments by default, for which both default and
explicit assignments will be numerically correct (even if expressed in
terms of earlier-defined identifiers)
- create an array of these values so they can be cross-referenced with
the identifiers extracted at run-time

This code does that work:

static Meta& instance() { \
static Benum::Incrementing<TYPE__VA_ARGS__; \
static const int values[] = { __VA_ARGS__ }; \
static Meta meta(#TYPE, #__VA_ARGS__, values, \
sizeof values / sizeof(int)); \
return meta; \
} \


Anyway, like half the known universe, this facility is being proposed
for boost (hasn't entered formal review yet), and any feedback would
aid that process and be very much appreciated (at least by me).

The current code's not intended to be fully end-user deployable,
documented or even fully optimised: but if you're a reasonably
advanced programmer with an interest and time to spare, you'll find
I've documented the code reasonably and provide examples of a complex
usage scenario in a test file. Please consider reviewing it. It can
be found in the boost vault as at
(that link will only work in some browsers due to the un-encoded & and
=, but the site doesn't support hex-encoded values).


Sep 25 '08 #1
Share this question for a faster answer!
Share on Google+

This discussion thread is closed

Replies have been disabled for this discussion.