Overloaded constructors and cast operators for Glib::Value?



Hello All,

I am planning a project. It's in a design stage. For that project,
I need a generic value type.

By that I mean, that it should be possible to construct that type from
any (some reasonable set) other type and be castable to any such type,
perhaps using dynamic_cast method like RefPtr does. This cast or method
would throw bad_cast, if the object actualy contained incompatible type.

What I want is to allow:

    void foo(int x);

    Value a = 1;
    Value b = "string";
    
    foo(a); // OK, a is an integer
    foo(b); // throws bad_cast, because it's not a number.

Since I will be passing that type to Gtkmm calls a lot, I want it
convertible to Glib::ValueBase. Thus I thought that it could in fact be
based on the existing Glib::Value infrastructure.

I thought about something like this:

class Value : Glib::ValueBase {
  protected:
    void swap(Value &that)
    {
        GValue tmp;
        tmp = that.gobject_;
        that.gobject_ = this->gobject_;
        this->gobject_ = tmp;
    }
  public:
    // some not-interesting default constructor
    
    // template constructor from anything
    template <class VT> Value(VT &val)
    {
        Glib::Value<VT> tmp;
        tmp.set(val);
        this->swap(tmp);
    }
    template <> Value(Glib::ValueBase &val) :
	Glib::ValueBase(val)
    {};

    // operator= using above constructors and swap

    // And now the highest madness! The cast operators!
    // FIXME This won't work. It does not do sane checking.
    template <class VT> operator VT()
    {
	Glib::Value<VT> tmp;
	tmp = *this; // FIXME This does not exist!
	return tmp.get();
    }

    // Perhaps some more operations should be defined too, like
    // a stringification operation for printing and such.
}

The FIXME denotes the point where I am in trouble. What I need is an
operation, that would copy one Glib::ValueBase to a Glib::ValueBase
descendant calling g_value_transform and throwing a bad_cast exception
if it returns NULL.

I think it should be possible to implement the operation here -- after
all, it inherits Glib::ValueBase and thus has access to it's guts. I am
nowever not completely sure HOW it should be done. What are your
opinions on this?

Also it does not work with enums and flags, because enums are
Glib::Value_Enum and flags are Glib::Value_Flags. It would suffice to
use static constructor methods for enums. Does anyone have a better
idea?

Since I don't have much experience with C++, it's quite possible that
there are other bugs too. Please correct me if I am wrong somewhere.

-------------------------------------------------------------------------------
						 Jan 'Bulb' Hudec <bulb ucw cz>

Attachment: signature.asc
Description: Digital signature



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]