Status & Roadmap
Authors & License
Funding Ultimate++
Search on this site

SourceForge.net Logo

Storing custom data types in Values

Of course it is possible to store custom data types in Values, that's what they're for. In fact, even the "standard" value types like INT_V or STRING_V have very little special support in Value, in most aspects their encapsulation in Value is implemented in just the same way as for any other types.


The main question is: how "rich" encapsulation you want? The simplest available option is called "raw value type". The only two things it supports is wrapping an object into a Value and getting it back. To turn an object into Value in this way, use e.g.:


MyType t;

Value v;


v = RawToValue(t);


For pick types, i.e. for types with "destructive copy" as default, you can use




or, if type has alternative deep copy option




depending on whether the value of t should be picked (destroyed). When it should, using RawPickToValue should be faster.


When you need the value back, use


const MyType& t = ValueTo<MyType>(v);


Note that the function ValueTo returns a constant reference. This is consistent with default Value behaviour, according to which data once put into Value should never change afterwards. This is necessary because, upon copying, multiple variables of type Value can hold the same data "packet" and changing its contents would affect all these copies, which is normally undesirable. If you break the const-ness using a mutable member or by a const_cast, you should not forget that.


Of course, you can make copy of value referenced by this constant reference as well


    MyType t = ValueTo<MyType>(v);


but be careful about transfer semantics of MyType (doing this with type that has pick default transfer semantics is error).


A higher level of encapsulation defines a few more operations on such custom Value types: it is called the "rich value type" and allows such Values to be compared (for equality, there is currently no general way to define ordering for custom Value types), text-formatted, serialized and checked for Null-ness. You can either use RichToValue (much like RawToValue), or (which is common for objects with high level Value encapsulation) define a conversion operator within the object class. ValueTo<> is the same as in the raw case, moreover it is usually handy to define a constructor from a Value or const Value& for this purpose. You can get clue about his this is done by examining e.g. Color class code.


The highest currently possible encapsulation level is the rich value type + type registration, which allows the Value serializer to recognize the custom types when loading data from a stream and create the necessary custom Value object on-the-fly. You activate this behaviour by defining a ValueTypeNo function and assigning the new type an unique code.


Last edit by cxl on 12/02/2017. Do you want to contribute?. T++