Boost logo

Boost :

From: Andy Little (andy_at_[hidden])
Date: 2003-11-08 09:20:16


"Oleg Grunin" <ogrunin_at_[hidden]> wrote in message
news:boi6fh$id$1_at_sea.gmane.org...
> It's kind of sad that boost::variant lacks implicit conversion to each
> of its bound types. I think, convience and symmetry calls for the syntax
> like this:

[snipped more refined example, which proposes compiler error on incorrect
cast...nice and a great improvement on my code!]

Yup !

Heres some code I worked on a couple of years ago. Its certainly Not
presented as an example of good style, or a good solution
 but of the need for what Oleg is proposing
I called it an E_ptr but its a Variant, except types are hard coded
Point is that I (theoretically should!) always check what type is in there
before extracting. (hmm .... thats because its a Variant :-) )
In use you use the E_ptrs operator()() to find out what type you have in
there:

I would certainly prefer to catch typos at compile time !

Andy Little
/////////////////////
/*
returns true if entity is a type
*/
bool Scopes::IdExpr::isType()const

{

Scope::E_ptr u = getTargetScope().FindMember(getUnqualifiedId());

switch (u()){

case Scope::E_ptr::CLASS:

case Scope::E_ptr::UNION:

case Scope::E_ptr::TYPEDEF:

case Scope::E_ptr::ENUM:

//classtemplate

return true;

default:

return false;

}

}

/////////////////
struct BadE_ptr{

//throw on type mismatch in E_ptr

};

struct E_ptr{

public:

enum Entity{

NOTFOUND,OBJECT,

CLASS,UNION,

ENUM,FNC_LST,

TYPEDEF,

NAMESPACE,

CLASS_TEMPLATE

};

private:

Entity entity;

union{

void* m_notfound;

Objects::Object* m_object;

Class* m_class;

Union* m_union;

Enum* m_enum;

Typedef* m_typedef;

FncLst* m_fncLst;

Namespace* m_namespace;

ClassTemplate* m_classTemplate;

// add typename ...?

};

void Assert(Entity e){if( entity != e)throw BadE_ptr();}

void chk_null_ptr(){if (!m_notfound) entity = NOTFOUND;/* could throw
exception instead*/}

public:

bool operator==(Entity e)const{return entity == e;}

bool operator!=(Entity e)const{return entity != e;}

Entity operator()()const{return entity;}

operator Class*() {Assert(CLASS);return m_class;}

operator Union*() {Assert(UNION);return m_union;}

operator Enum*() {Assert(ENUM);return m_enum;}

operator Namespace*(){Assert(NAMESPACE);return m_namespace;}

operator Objects::Object*(){Assert(OBJECT);return m_object;}

operator Typedef*(){Assert(TYPEDEF);return m_typedef;}

operator FncLst*(){Assert(FNC_LST);return m_fncLst;}

operator ClassTemplate*(){Assert(CLASS_TEMPLATE);return m_classTemplate;}

E_ptr(): entity(NOTFOUND),m_notfound(0){}

E_ptr(Objects::Object* ob):entity(OBJECT),m_object(ob){chk_null_ptr();}

E_ptr(Class* c): entity(CLASS),m_class(c){chk_null_ptr();}

E_ptr(Union* u): entity(UNION),m_union(u){chk_null_ptr();}

E_ptr(Enum* e): entity(ENUM),m_enum(e){chk_null_ptr();}

E_ptr(FncLst* fl):entity(FNC_LST),m_fncLst(fl){chk_null_ptr();}

E_ptr(Namespace* n): entity(NAMESPACE),m_namespace(n){chk_null_ptr();}

E_ptr(ClassTemplate* ct):
entity(CLASS_TEMPLATE),m_classTemplate(ct){chk_null_ptr();}

E_ptr(Typedef* t):entity(TYPEDEF),m_typedef(t){chk_null_ptr();}

};


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