creating a dynamic variable type

Started by
45 comments, last by thre3dee 15 years, 11 months ago
I am wanting to create an object that is basically a object that can store any type of variable(int, string, user created, etc...) by doing something like:

variable* a_string = new variable("string", "data");
variable* a_int = new variable("int", 4);


now the trouble i am having is storing the data. Now i know i can use template for a class/function when the passed variable might be anything but is there a way to do that for a variable?
Advertisement
well... I've made a property class before.

Basically without having type checks you can simply do it like this:

// we need a destructor function for each typetypedef void (*Dtor)(void*); // this generates a simple destructor for any template typetemplate <class T>void Destructor (void* p){	delete (T*) p;} // Our property holderclass Property{private:	// pointer to the object	void* data;	// function ptr to its destructor	Dtor dtor; public:	// constructor	Property () : data (0), dtor (0) { }	// destructor	~Property ()	{		// destroy if object is present		if (data)			dtor (data);	} 	// set the property (destroy existing if present)	template <class T>	void Set (T* object)	{		if (data)			dtor (data);		data = object;		dtor = &Destructor<T>;	} 	// get the property	template <class T>	T& Get (void)	{		return *(T*) data;	}}; // test it outint main (){	Property p;	p.Set (new int (123));	if (p.Get<int>() == 123) {		printf ("It works!!!!");	}	p.Set (new std::string ("Hello, world!"));	if (p.Get<std::string>() == "Hello, world!") {		printf ("It still works!!!!");	}}


This is a very quick version of a variable type. You'd need proper checks and whatnot.
Boost.Variant.
Agreed, though ur own version doesnt involve 20mb of headers.

[forgive me if you only need a few headers for variant - ive tried using boost and its waaaaaaaayyyyy too big]
Quote:Original post by thre3dee
Agreed, though ur own version doesnt involve 20mb of headers.

[forgive me if you only need a few headers for variant - ive tried using boost and its waaaaaaaayyyyy too big]


The reason for that is that the Boost version covers all the cases, such as containers, copying, type-safety, and more.

Stuff like:
p.Set (new int (123));	if (p.Get<std::string>() == "123") {		printf ("What happens here?");	}        std::vector<Property> properties; // will either leak memory or crash


Variant type is also not optimal, there's boost::any, or, if you want a light-weight version, cdiggins::any.

The advantage of any types is that all variables smaller or equal to sizeof(void*) will be allocated in place, thereby not trashing the heap or cause extra dereference on access.
Oh, yes. It definitely depends on your intentions for it. Diggins' version is a good solution if you're planning on using something like this in a tight loop. Variant also requires one to specify the types you plan on it holding, so it wouldn't be comfortable if they plan on stuffing anything and everything in there.

Still, no matter which you go with, something like Boost or Diggins' implementation would be best. Boost is very well made and will introduce heaps of safe functionality that would otherwise take years to (re)implement. Also, you'd have to include every single header in the Boost library to get 20MiB — you typically wouldn't go that far unless you're actually using everything in there. Variant or Any alone are only going to add ~10KiB.
Please I after i say this I really don't want to here people telling me don't to do this because i frankly don't care if people think this is a waste of time, I don't think it is and it is something the is very interesting to me. The reason for this functionality is for my custom scripting language i am building.

The only reason I am timid about using the Boost library is because i have been told it was not that great and not to use it. Now this must have been over a year ago so I am sure a lot has changed. I also do not remember if i was told not to use it because it license what not free enough(I would like to be able to release my code under whatever license i want without having to release any of my source code except for and modification I make to the boost library) or if the code was not the best in speed. How is Boost speed wise? From what i see it seem like license would allow for me to use the code it any licensed project, is that right?
Quote:Original post by 3dmodelerguy

Now this must have been over a year ago so I am sure a lot has changed.


Nothing has changed in one year. Where exactly did boost turn out to be a bottle-neck for you? What did you use as alternative?

Quote:I also do not remember if i was told not to use it because it license what not free enough(I would like to be able to release my code under whatever license i want without having to release any of my source code except for and modification I make to the boost library)


Boost license is permissive to open source or commercial projects. It's the only reason it's even usable, anything less wouldn't make it viable.

Quote:From what i see it seem like license would allow for me to use the code it any licensed project, is that right?


Yes.


Quote:or if the code was not the best in speed. How is Boost speed wise?


It did Kessel run in 12 parsecs. It's fast enough for you, young man. :)


What are your performance requirements? If you looked at the link I provided about cdiggins any version, it explains nicely why it exists.

All libraries explain the performance implications of the design decisions made. In some cases, it matters, in others, it doesn't.

Notable examples include function and signal libraries, which, for sake of reliability and portability allocate more memory as is usually necessary, as well as perform dynamic allocations.

Same "problem" exists with boost::any, which is why I suggested a light-weight alternative, which covers what you want to do completely (std::pair<std::string, any>, for example).

Keep in mind that such hacks are surprisingly complex, and have many hidden pitfalls. The existing ::any implementations have been tested well enough to be shown to work.
Quote:Original post by 3dmodelerguy

The only reason I am timid about using the Boost library is because i have been told it was not that great and not to use it.


I'd like to find whoever told you that and smack him/her upside the head. [smile]

IMO the boost smart pointer classes are about as important as std::string.
If you're on Windows why not get the VARIANT type a chance? or _variant_t (wrapper for it in MFC) ?

Boost is always good but indeed can be scary at first:)

This topic is closed to new replies.

Advertisement