|
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