Variant

class Variant

A basic type to hold a variety of data types.

Unfourtunatly C++ does not have a standard variant type so we have to create one here.

This is a fairly low performance class and is intended soley for infrequent operations such as Variant configuration parameters.

If Python support is enabled, this class can convert to and from a Python object.

Usage: This class can convert to and from any primitive data type, and some collections types. More type conversions will be added as needed.

To store a value, just assign it, the assignment operator automatically takes care of everything for you:

// store an int:
int i = 23;
Variant v = i;

// store a double:
Variant v = (double)0.123;

Extraction: To retrieve the stored data, uses the convert function, this is templated so it can convert and extract to any type:

Variant v = getSomeVariant();

// to convert to integer:
int i = v.convert<int>();

// to convert to std::string:
std::string s = v.convert<std::string>();

Rationale: C++ does not have a built in variant type. Other variant types exist such as boost::any and Poco dynamic var. However including the one of these as part of our public wrappers would forever tie us to that particular library, and would impose yet another dependency.

Only very basic variant type support is needed and this class exposes the absolute minimum possible wrappers to support such features, and provides just two methods of getting and storing native C++ types in it.

This is currently implemented by Poco but the implementation is fully opaque and may change in the future.

Public Types

enum TypeId

list of currently supported types that a Variant can hold.

Values:

enumerator STRING
enumerator BOOL
enumerator INT32
enumerator UINT32
enumerator INT64
enumerator UINT64
enumerator FLOAT
enumerator DOUBLE
enumerator CHAR
enumerator UCHAR
enumerator EMPTY
enumerator DOUBLEVECTOR

Public Functions

TypeId type() const

the current type that this Variant is.

Variant()

creates an emtpy variant

template<typename T>
inline Variant(const T &val)

create a new variant from an existing supported data type.

This templated constructor can assign any primitive type:

Variant v = (int)1;
Variant v = std::string("a std::string");

inline Variant(const char *str)
Variant(const Variant &other)

Copy constructor.

template<typename T>
inline Variant &operator=(const T &value)

Assignment operator for assigning POD to Var same as the constructor, this assigns a value to an existing Variant.

Variant &operator=(const Variant &other)

Assignment operator.

Assign one variant to another.

virtual ~Variant()

clean up any data owned by this object.

const std::type_info &typeInfo() const

get the type id of the stored data type.

This will let you check what kind of data is strored in this variant.

// to check if this is an integer:
Variant v = ...
if (v.type() == typeid(int))
    std::cout << "its an int";

// to check if its a std::string:
if (v.type() == typeid(std::string))
    std::cout << "ints a std::string";

template<typename T>
inline T convert() const

Convert this variant to a supported data type.

This method will try to perform type coercion, i.e. if this variant contains a std::string, and it is asked to convert to a int, the std::string will be parsed as an int. Similary, doubles will be rounded to int, so forth.

// convert to int:
int i = v.convert<int>();

VARIANT_IMPLICIT_CONVERT(std::string)
VARIANT_IMPLICIT_CONVERT(long)
VARIANT_IMPLICIT_CONVERT(bool)
VARIANT_IMPLICIT_CONVERT(float)
VARIANT_IMPLICIT_CONVERT(double)
VARIANT_IMPLICIT_CONVERT(unsigned long)
VARIANT_IMPLICIT_CONVERT(int)
VARIANT_IMPLICIT_CONVERT(unsigned int)
VARIANT_IMPLICIT_CONVERT(char)
VARIANT_IMPLICIT_CONVERT(unsigned char)
VARIANT_IMPLICIT_CONVERT(std::vector<double>)
std::string toString() const

Converts the Variant to a std::string in JSON format.

std::string pythonRepr() const

Convert to Python-compatible representation.

Author

JKM

bool isString() const

is this variant a std::string.

bool isInteger() const

was an integer stored here.

bool isNumeric() const

is this a numeric type.

bool isBool() const

is this a boolean type.

bool isEmpty() const

true if empty.

bool isSigned() const

true if this is a signed number.

bool isDoubleVector() const

Public Static Functions

static Variant parse(const std::string &val)

Parses the std::string which must be in JSON format.

This is a common way to read a Variant from a file or create a new one from a std::string:

Variant v = Variant::parse("0.123");

Private Functions

void alloc()
void assign(const std::type_info &info, const void *value)
void convert_to(const std::type_info &info, void *value) const

Private Members

struct VariantImpl *self

private implementation, this gives us the flexibility to use different implementations in the future and maintain binary compatability.