Boost logo

Boost :

From: Frank Laub (frank.laub_at_[hidden])
Date: 2005-12-07 17:10:22


There should be no problems using this macro in a header file. I get around
the one definition rule by simply making the enum actually be a namespace
with static functions inside that namespace. So basically:

BOOST_ENUM(Foo, (a)(b))

expands into:

namespace Foo
{
    enum type
    {
        a,
        b,
        size = 2,
        Invalid = -1
    };

    typedef boost::array<const std::string, size+1> array_type;

    static const array_type names =
    {
        "a",
        "b",
        "2"
    };

    static const std::string& str(type index)
    {
        assert(index >= 0 && index <= size);
        return names[(int)index];
    }

    static bool parse(const std::string& str, type& value)
    {
        array_type::const_iterator it = std::find(names.begin(), names.end(),
str);
        if(it == names.end()) return false;
        value = (type)(it - names.begin());
        return true;
    }

    static std::ostream& operator << (std::ostream& os, type value)
    {
        os << str(value);
        return os;
    }
}

On 12/7/05, Martin Bonner <martin.bonner_at_[hidden]> wrote:
>
> ----Original Message----
> From: Frank Laub [mailto:frank.laub_at_[hidden]]
> Sent: 07 December 2005 11:47
> To: boost_at_[hidden]
> Subject: [boost] BOOST_ENUM proposal
>
> > Hello fellow boosters,
> >
> > I've recently come up with a way to use the boost preprocesor to
> > generate a 'better' enum type. The following is an example of some
> > typical usage. Is anyone else interested in this sort of thing?
>
> **YES**!!
>
> > I'm
> > hoping to get suggestions for how to make it more 'boost-like' in
> > both its implementation and its usage. Is this very readable? Is
> > there a place I can upload the code for people to peruse?
> >
> >
> > #include <iostream>
> > #include <boost/enum.hpp>
> > #include <boost/foreach.hpp>
> > #define foreach BOOST_FOREACH
> I hope that this line is just needed for the demo code in main.
>
> >
> > BOOST_ENUM(Level,
> > (Abort)("unrecoverable problem")
> > (Error)("recoverable problem")
> > (Alert)("unexpected behavior")
> > (Info)("expected behavior")
> > (Trace)("normal flow of execution")
> > (Debug)("detailed object state listings")
> > )
>
> Now we come to the meat of the problem. Here you have defined 'Level' at
> directly in a cpp file. Normally, I would want to define an enum in a
> header file, and I see potential problems with violations of the
> one-definition-rule.
>
> Also: does your implementation cope with defining an enum inside a class?
> (I could live with an answer of "No" - I would just have to put the enum
> outside the class.)
>
> Is your implementation limited to 255 elements (normal boost preprocessor
> limit)?
>
> Can I specify enum values (ie Abort=0, Info=16)?
> >
> > int main()
> > {
> > foreach(const string& name, Level::names)
> > {
> > cout << name << endl;
> > }
> > cout << "1: " << Level::names[1] << endl;
> > cout << "toString(Abort): " << Level::toString(Level::Abort) <<
> > endl; cout << "getValue(Abort): " <<
> > Level::getValue(Level::Abort) << endl;
> >
> > Level::type value = Level::Invalid;
> > bool ret = Level::fromString("Abort", value);
> > cout << "fromString(\"Abort\"): " << ret << ", " << value << endl;
> >
> > value = Level::Invalid;
> > ret = Level::fromString("Debug", value);
> > cout << "fromString(\"Debug\"): " << ret << ", " << value << endl;
> >
> > value = Level::Invalid;
> > ret = Level::fromString("not in enum", value);
> > cout << "fromString(\"not in enum\"): " << ret << ", " << value
> > << endl;
> >
> > return 0;
> > }
> >
> >
> > With the program output being:
> >
> > Abort
> > Error
> > Alert
> > Info
> > Trace
> > Debug
> > Invalid
> > 1: Error
> > toString(Abort): Abort
> > getValue(Abort): unrecoverable problem
> > fromString("Abort"): 1, 0
> > fromString("Debug"): 1, 5
> > fromString("not in enum"): 0, 6
> >
> > -Frank
>
>
> --
> Martin Bonner
> Martin.Bonner_at_[hidden]
> Pi Technology, Milton Hall, Ely Road, Milton, Cambridge, CB4 6WZ,
> ENGLAND Tel: +44 (0)1223 441434
> _______________________________________________
> Unsubscribe & other changes:
> http://lists.boost.org/mailman/listinfo.cgi/boost
>


Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk