cartobase
5.0.5
|
#include <cartobase/object/object.h>
Public Member Functions | |
Object () | |
Object (const Object &) | |
Object (GenericObject *data, bool externalowner=false) | |
virtual | ~Object () |
Object & | operator= (const Object &) |
uses the reference-counting so the underlying GenericObject is shared More... | |
bool | isSameObject (const Object &) const |
compares the addresses of the underlying GenericObjects More... | |
bool | isNone () const |
check if we hold a "none" object. More... | |
bool | operator== (const Object &other) const |
bool | operator!= (const Object &other) const |
template<> | |
Object | value (const Object &value) |
![]() | |
rc_ptr () | |
rc_ptr (GenericObject *p) | |
rc_ptr (GenericObject *p, bool externalowner) | |
rc_ptr (std::auto_ptr< U > r) | |
void | reset (GenericObject *p=NULL) |
GenericObject * | get () const |
bool | operator< (const rc_ptr< GenericObject > &other) const |
operator insipid * () const | |
![]() | |
ref () | |
ref (GenericObject *pObject) | |
ref (GenericObject *pObject, bool externalowner) | |
ref (std::auto_ptr< U > r) | |
ref (const ref< GenericObject > &other) | |
ref (const ref< R > &other) | |
~ref () | |
GenericObject * | release () |
ref< GenericObject > & | operator= (const ref< GenericObject > &other) |
GenericObject * | operator-> () const |
GenericObject & | operator* () const |
GenericObject * | pointer () const |
![]() | |
const_ref () | |
const_ref (const GenericObject *pObject) | |
const_ref (const GenericObject *pObject, bool externalowner) | |
const_ref (std::auto_ptr< U > r) | |
const_ref (const ref< GenericObject > &other) | |
const_ref (const const_ref< GenericObject > &other) | |
const_ref (const ref< R > &o) | |
const_ref (const const_ref< R > &other) | |
~const_ref () | |
const_ref< GenericObject > & | operator= (const ref< GenericObject > &other) |
const_ref< GenericObject > & | operator= (const const_ref< GenericObject > &other) |
bool | isNull () const |
bool | operator== (const ref< GenericObject > &other) const |
bool | operator== (const GenericObject *pointer) const |
bool | operator== (const const_ref< GenericObject > &other) const |
bool | operator!= (const ref< GenericObject > &other) const |
bool | operator!= (const const_ref< GenericObject > &other) const |
bool | operator!= (const GenericObject *pointer) const |
const GenericObject * | operator-> () const |
const GenericObject & | operator* () const |
const GenericObject * | pointer () const |
int | refCount () const |
![]() | |
int | count () const |
Static Public Member Functions | |
template<typename T > | |
static Object | value () |
factory function: builds an Object by using the default constructor More... | |
template<typename T > | |
static Object | value (const T &) |
factory function: builds an Object by copying the value into a ValueObject storage wrapper More... | |
template<typename T > | |
static Object | reference (T &value) |
factory function: builds an Object by referencing the value from a ReferenceObject storage wrapper. More... | |
template<typename T > | |
static Object | reference (const T &value) |
This method remove "constness" of it argument and call its non const equivalent. More... | |
Additional Inherited Members | |
![]() | |
typedef GenericObject | referenced_type |
![]() | |
typedef GenericObject | referenced_type |
Basically, an Object is used whenever it is necessary to use data which type is not known at compile time. Therefore, an Object instance can contain any type of data and it can change at run time. However, C++ is a strongly typed language, it is therefore impossible to handle untyped data. To be able to define a typed generic API for untyped objects, we choosed to base our API on a limited (but extensible) set of atoms and aggregates. Atoms are objects that cannot be split into smaller objects. Aggregates are structures composed of objects (which are either atoms or aggregates).
The basic Object
API uses the following standard atoms:
Scalar
: represents any numeric value String
: a characters string (like the C++ standard library class std::string
) Atoms can be grouped and/or organised with the following standard aggregates:
Array
: an ordered series of objects. The number of objects in the array as well as the type of each element can vary at run time. Dictionary
: a kind of untyped C/C++ structure
. A Dictionary
is composed of a series of (key, value) pairs where key is a String
and value is an object. All these atoms and aggregates (i.e. all objects) can be accessed through a set of C++ classes inheriting from Interface
and described below.
There are two main reasons that led us to build generic object API. The first one is the need to have untyped dynamic array and dictionaries. This structures are required to store data from the generic minf format. This format contains a Dictionary
which content is read from a file at run time. The main idea is to allow the storage of any kind of value in a minf file. The second reason is related to the need to exchange complex data and algorithm between C++ programs and other language (mainly Python. It can be thought as a generalization of the minf requirement. The minf format can be considered as an external (i.e. non C++) language. Therefore, if the tools defined to wrap C++ objects to minf format are generic enough, they can be used to wrap these objects to other languages. Now, the Interface
API is generic and language independant, therefore it is being used to create wrappers between C++ and various languages (at least minf-python, minf-XML and Python).
The main class that is going to be declared by generic objects users is Object. This class behaves like a pointer to a virtual class called GenericObject. Most people will not have to bother about GenericObject. The only point to remember is just that since Object is pointer alike, almost all of its methods are accessed through the "arrow" syntax (e.g. object->method()
) instead of the "dot" syntax (e.g. object.method()
).
Object's methods are grouped by interface. Each interface correspond to a set of methods implementing access to a specific atom or aggregate. Interfaces are pure virtual classes derived from Interface. There is a set of standard interfaces which define the API for standard atoms and standard aggregate. It is also possible to define new custom interfaces as explained below.
The standard interface methods differ from custom interface methods. Indeed, standard interfaces are defined before generic objects but custom interfaces are not known when generic objects are defined. Therefore, only standard interfaces methods can be accessed directly from Object's instance (via inheritance). Access to custom interface is described below.
Here is a summary of the standard interfaces. Report to each interface documentation for more information:
Object behave much like a generic pointer to a real C++ value. Unlike pointers, Object instances can manage memory usage and do all necessary memory allocation/deallocation. In this case the C++ value "belongs" to the Object. Such objects are called value objects. On the other hand, it is sometimes necessary to reference an existing C++ value as a generic object without memory management. Such objects are called reference objects.
There are two functions to create either a value object or a reference. Object::value() returns an Object containing a copy of the value given in parameter whereas Object::reference() returns an object pointing to the object given in parameter. The real type of the object is the type of the parameter (these functions are template).
Example:
But if you want to reference an existing object:
There are two ways to read or modify the value of an object. If you know the real type of the object, you can access to the stored via the value() and setValue() functions. These functions only work if you try to access the correct data type (exact type match: no inheritance is taken into account), otherwise the functions throw an exception. On the other hand, if you do not know the real object type, you must use either the standard interface or the custom interface API.
To do...
Object API uses an Interface system: subclasses of Interface implement some "standard" APIs that can be accessed via the GenericObject::getInterface function. All GenericObjects inherit the most common interfaces: ScalarInterface, StringInterface, DictionaryInterface, DynArrayInterface, DictionaryIteratorInterface, and others implied by those listed here.
A specialized GenericObject which stores (or references) an object that implements a specific Interface will allow to get and use this interface: getInterface() will return a pointer to the stored object matching interface. If the stored object itself does not implement the interface, getInterface() will return a null pointer.
Some Interface may be implemented by the specialized GenericObject, not by the stored object. For instance DictionaryInterface is implemented on map<string, Object> GenericObject specializations even if map doesn't implement it directly.
To do...
Generic objects can be read from and written to disk in two formats:
see PythonReader, PythonWriter, readMinfXML.
|
inline |
Definition at line 1405 of file object.h.
Referenced by operator==(), reference(), and value().
|
inline |
|
inline |
check if we hold a "none" object.
At the moment, a "none" object is null: the reference counter holds a null pointer, so you must check it before accessing any GenericObject method via the operator->()
. In the future, we may define a None type which will not be a null pointer, allowing the use of GenericObject methods, which will throw exceptions rather than crash the program.
Note that a singleton None object is defined as a global variable: carto::none()
bool carto::Object::isSameObject | ( | const Object & | ) | const |
compares the addresses of the underlying GenericObjects
|
inline |
Definition at line 651 of file object.h.
References carto::DictionaryInterface::getProperty(), operator==(), and carto::DictionaryInterface::setProperty().
uses the reference-counting so the underlying GenericObject is shared
|
inline |
Definition at line 1438 of file object.h.
References carto::rc_ptr< T >::get(), Object(), and value().
|
inlinestatic |
factory function: builds an Object by referencing the value from a ReferenceObject storage wrapper.
The original value
object must not be destroyed while the new object is still in use.
Definition at line 1532 of file object.h.
References Object().
Referenced by carto::PropertySet::addBuiltinProperty(), carto::ReferenceObject< T >::clone(), carto::getObjectHeader(), reference(), carto::PropertySet::setProperty(), and value().
|
inlinestatic |
This method remove "constness" of it argument and call its non const equivalent.
Definition at line 1541 of file object.h.
References reference().
|
inlinestatic |
factory function: builds an Object by using the default constructor
Definition at line 1482 of file object.h.
References Object().
Referenced by carto::ValueObject< SyntaxedInterfaceType< T > >::clone(), carto::AlgorithmCaller::operator<<(), operator==(), carto::ObjectFactory::registerDefaultFactory(), carto::PropertySet::setProperty(), and value().
|
inlinestatic |
factory function: builds an Object by copying the value into a ValueObject storage wrapper
Definition at line 1491 of file object.h.
References Object().
Definition at line 1500 of file object.h.
References Object(), reference(), and value().