CGII/framework/include/libs/ppp_lib/variant.h
2018-05-17 15:50:03 +02:00

215 lines
6.8 KiB
C++

#pragma once
#include "operators.h"
#include <vector>
#include <map>
#include "lib_begin.h"
namespace cgv {
namespace media {
namespace text {
namespace ppp {
class ph_processor;
struct namespace_info;
enum ValueType { UNDEF_VALUE, BOOL_VALUE, INT_VALUE, DOUBLE_VALUE, STRING_VALUE,
REFERENCE_VALUE, NAME_VALUE, LIST_VALUE, MAP_VALUE, FUNC_VALUE };
struct func_type
{
unsigned block_begin;
unsigned block_end;
ph_processor* ph_proc;
namespace_info* ns;
func_type(unsigned _i, unsigned _j, ph_processor* _ph_proc = 0, namespace_info* _ns = 0);
};
class CGV_API variant
{
public:
typedef std::vector<variant> list_type;
typedef std::map<std::string,variant> map_type;
protected:
/// store type of value
ValueType vt;
union {
bool bool_value;
int int_value;
double dbl_value;
std::string* string_value;
variant* reference_value;
std::string* name_value;
list_type* list_value;
map_type* map_value;
func_type* func_value;
};
public:
/**@name constructors*/
//@{
/// construct undefined value
variant();
/// use assign operator for copy constructor
variant(const variant& v);
/// construct bool value
variant(bool v);
/// construct integer value
variant(int v);
/// construct double value
variant(double v);
/// construct string value
variant(const std::string& v);
/// construct reference value
variant(variant* v);
/// construct name value
variant(ValueType vt, const std::string& v);
/// construct list value
variant(const list_type& v);
/// construct map value
variant(const map_type& v);
/// construct func value
variant(const func_type& v);
/// remove all elements from a list or map and set to undefined type
void clear();
/// assignment operator
variant& operator = (const variant& v);
/// destructor
~variant();
//@}
/**@name operator interface*/
//@{
bool is_unary_applicable(OperatorType ot);
bool unary_check_defined(OperatorType ot);
void apply_unary(OperatorType ot);
bool is_binary_applicable(OperatorType ot, const variant& v2);
bool binary_check_defined(OperatorType ot, const variant& v2);
void apply_binary(OperatorType ot, const variant& v2);
//@}
/**@name query type*/
//@{
/// return the variant type
ValueType get_type() const;
/// lookup names and follow references and return value type
ValueType get_value_type() const;
/// lookup names and follow references and return whether variant is undefined
bool is_undefined() const;
/// lookup names and follow references and return whether variant is int
bool is_int() const;
/// lookup names and follow references and return whether variant is double
bool is_double() const;
/// lookup names and follow references and return whether variant is bool
bool is_bool() const;
/// lookup names and follow references and return whether variant is string
bool is_str() const;
/// lookup names and follow references and return whether variant is list
bool is_list() const;
/// lookup names and follow references and return whether variant is map
bool is_map() const;
/// lookup names and follow references and return whether variant is func
bool is_func() const;
/// name and reference type return true
bool is_reference() const;
/// only a name returns true
bool is_name() const;
//@}
/**@name access to values with implicit type conversions accept list and map types */
//@{
/// lookup names and follow references and convert to bool: undef ... false, int ... compares unequal zero, string ... convert to int and compare unequal zero, list/map ... check size unequal zero
bool get_bool() const;
/// lookup names and follow references and convert to int: undef ... -1, bool ... 0 or 1, string ... atoi, list/map ... size
int get_int() const;
/// lookup names and follow references and convert to double: undef ... -1, bool ... 0 or 1, string ... atof, list/map ... size
double get_double() const;
/// lookup names and follow references and convert to string
std::string get_str() const;
/// constant access to list value
const list_type& get_list() const;
/// constant access to map value
const map_type& get_map() const;
/// convert to int type
void ensure_int_type();
/// convert to int or double such that result of binary operators can be stored in this variant without loss of data, return whether conversion was to int
bool match_number_type(const variant& v2);
//@}
/**@name references to values. Before usage ensure that type is matched. */
//@{
bool& ref_bool();
int& ref_int();
double& ref_double();
std::string& ref_str();
list_type& ref_list();
map_type& ref_map();
func_type& ref_func();
//@}
/**@name setters*/
//@{
void set_bool(bool v);
void set_int(int v);
void set_double(double v);
void set_str(const std::string& v);
void set_name(const std::string& n);
void set_list();
void set_list(const std::vector<variant>& l);
void set_map();
void set_map(const std::map<std::string,variant>& m);
//@}
/**@name name and reference interface*/
//@{
/// lookup names and follow references and return the reached variant
const variant& get_value() const;
/// lookup names and follow references and return reference to the reached variant
variant& ref_value();
/// return the pointer of a reference
variant* get_reference() const;
/// return the name of a name value
const std::string& get_name() const;
//@}
/**@name common list and map interface*/
//@{
/// return number of elements in a list or map
unsigned int get_size() const;
/// return total number of elements in a list or map summing over all elements recursively
unsigned get_total_nr_elements() const;
/// return a reference to the i-th element in a list or map
variant& ref_element(unsigned int i);
/// return a const reference to the i-th element in a list or map
const variant& get_element(unsigned int i) const;
//@}
/**@name list interface*/
//@{
void append_to_list(const variant& v);
void prepend_to_list(const variant& v);
void pop_back_from_list();
void pop_front_from_list();
//@}
/**@name map interface*/
//@{
/// reference an element of a map by name
variant& ref_element(const std::string& name);
/// const reference an element of a map by name
const variant& get_element(const std::string& name);
/// return the name of the i-th element in a map
const std::string& get_element_name(unsigned int i) const;
/// insert a new entry to the map
void insert(const std::string& name, const variant& v);
//@}
};
/// stream out a variant
extern CGV_API std::ostream& operator << (std::ostream& os, const variant& v);
}
}
}
}
#include <cgv/config/lib_end.h>