variant.hpp

Go to the documentation of this file.
00001 #ifndef VARIANT_HPP_INCLUDED
00002 #define VARIANT_HPP_INCLUDED
00003 
00004 #include <boost/shared_ptr.hpp>
00005 #include <string>
00006 #include <map>
00007 #include <vector>
00008 
00009 namespace game_logic {
00010 class formula_callable;
00011 }
00012 
00013 void push_call_stack(const char* str);
00014 void pop_call_stack();
00015 std::string get_call_stack();
00016 
00017 struct call_stack_manager {
00018     explicit call_stack_manager(const char* str) {
00019         push_call_stack(str);
00020     }
00021 
00022     ~call_stack_manager() {
00023         pop_call_stack();
00024     }
00025 };
00026 
00027 struct variant_list;
00028 struct variant_string;
00029 struct variant_map;
00030 
00031 struct type_error {
00032     explicit type_error(const std::string& str);
00033     std::string message;
00034 };
00035 
00036 class variant {
00037 public:
00038     variant();
00039     explicit variant(int n);
00040     explicit variant(const game_logic::formula_callable* callable);
00041     explicit variant(std::vector<variant>* array);
00042     explicit variant(const std::string& str);
00043     explicit variant(std::map<variant,variant>* map);
00044     ~variant();
00045 
00046     variant(const variant& v);
00047     const variant& operator=(const variant& v);
00048 
00049     const variant& operator[](size_t n) const;
00050     const variant& operator[](const variant v) const;
00051     size_t num_elements() const;
00052 
00053     variant get_member(const std::string& str) const;
00054 
00055     bool is_string() const { return type_ == TYPE_STRING; }
00056     bool is_null() const { return type_ == TYPE_NULL; }
00057     bool is_int() const { return type_ == TYPE_INT; }
00058     bool is_map() const { return type_ == TYPE_MAP; }
00059     int as_int() const { if(type_ == TYPE_NULL) { return 0; } must_be(TYPE_INT); return int_value_; }
00060     bool as_bool() const;
00061 
00062     bool is_list() const { return type_ == TYPE_LIST; }
00063 
00064     const std::string& as_string() const;
00065 
00066     bool is_callable() const { return type_ == TYPE_CALLABLE; }
00067     const game_logic::formula_callable* as_callable() const {
00068         must_be(TYPE_CALLABLE); return callable_; }
00069     game_logic::formula_callable* mutable_callable() const {
00070         must_be(TYPE_CALLABLE); return mutable_callable_; }
00071 
00072     template<typename T>
00073     T* try_convert() const {
00074         if(!is_callable()) {
00075             return NULL;
00076         }
00077 
00078         return dynamic_cast<T*>(mutable_callable());
00079     }
00080 
00081     template<typename T>
00082     T* convert_to() const {
00083         T* res = dynamic_cast<T*>(mutable_callable());
00084         if(!res) {
00085             throw type_error("could not convert type");
00086         }
00087 
00088         return res;
00089     }
00090 
00091     variant operator+(const variant&) const;
00092     variant operator-(const variant&) const;
00093     variant operator*(const variant&) const;
00094     variant operator/(const variant&) const;
00095     variant operator^(const variant&) const;
00096     variant operator%(const variant&) const;
00097     variant operator-() const;
00098 
00099     bool operator==(const variant&) const;
00100     bool operator!=(const variant&) const;
00101     bool operator<(const variant&) const;
00102     bool operator>(const variant&) const;
00103     bool operator<=(const variant&) const;
00104     bool operator>=(const variant&) const;
00105 
00106     std::map<variant, variant> get_map() const;
00107     variant get_keys() const;
00108     variant get_values() const;
00109 
00110     void serialize_to_string(std::string& str) const;
00111     void serialize_from_string(const std::string& str);
00112 
00113     int refcount() const;
00114 
00115     std::string string_cast() const;
00116 
00117     std::string to_debug_string(std::vector<const game_logic::formula_callable*>* seen=NULL) const;
00118     enum TYPE { TYPE_NULL, TYPE_INT, TYPE_CALLABLE, TYPE_LIST, TYPE_STRING, TYPE_MAP };
00119 private:
00120     void must_be(TYPE t) const;
00121     TYPE type_;
00122     union {
00123         int int_value_;
00124         const game_logic::formula_callable* callable_;
00125         game_logic::formula_callable* mutable_callable_;
00126         variant_list* list_;
00127         variant_string* string_;
00128         variant_map* map_;
00129     };
00130 
00131     void increment_refcount();
00132     void release();
00133 };
00134 
00135 template<typename T>
00136 T* convert_variant(const variant& v) {
00137     T* res = dynamic_cast<T*>(v.mutable_callable());
00138     if(!res) {
00139         throw type_error("could not convert type");
00140     }
00141 
00142     return res;
00143 }
00144 
00145 template<typename T>
00146 T* try_convert_variant(const variant& v) {
00147     if(!v.is_callable()) {
00148         return NULL;
00149     }
00150 
00151     return dynamic_cast<T*>(v.mutable_callable());
00152 }
00153 
00154 #endif

Generated by doxygen 1.5.5 on 23 May 2008 for The Battle for Wesnoth
Gna! | Forum | Wiki | CIA | devdocs