#pragma once #include "operators.h" #include #include #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 list_type; typedef std::map 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& l); void set_map(); void set_map(const std::map& 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