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 |