lua++
|
00001 #ifndef LUAPP_VAR_H 00002 #define LUAPP_VAR_H 00003 00004 #include "luapp_exception.hpp" 00005 #include <utils_refptr.hpp> 00006 #include <typeinfo> 00007 00008 namespace lua 00009 { 00010 typedef std::type_info var_type; 00011 00012 /// Base type : untyped variable 00013 /** The purpose of this class is to have an untyped 00014 * return value / argument. It allows simple manipulation 00015 * of events, and a lot of other things.<br><br> 00016 * It uses a little bit more memory than a simple object :<br> 00017 * sizeof(void*) + sizeof(T)<br>... and has the overhead of 00018 * using the v-table (because of inheritance). At last, var 00019 * does a dynamic_cast (which is not the fastest thing in the 00020 * world) each time you call get().<br> 00021 * So this class is definatly slower than base types : <b>use it 00022 * wisely</b>. 00023 * \note This class is highly inspired from boost::any. 00024 */ 00025 class var 00026 { 00027 public : 00028 00029 /// Default constructor. 00030 var(); 00031 00032 /// Value assignment constructor. 00033 /** \param mValue The value to assign 00034 */ 00035 template <class T> 00036 var(const T& mValue) : pValue_(new value<T>(mValue)) {} 00037 00038 /// Copy constructor. 00039 /** \param mVar The var to copy 00040 */ 00041 var(const var& mVar); 00042 00043 var& operator = (const var& mVar); 00044 00045 bool operator == (const var& mVar) const; 00046 00047 bool operator != (const var& mVar); 00048 00049 /// Swaps this value with another. 00050 /** \param mVar the value to swap with this one 00051 */ 00052 void swap(var& mVar); 00053 00054 /// Returns the contained value. 00055 /** \return The contained value 00056 * \note If the provided type doesn't match the 00057 * contained value's, a Warning is printed 00058 * in the log, and this function returns a 00059 * default value. 00060 */ 00061 template<class T> 00062 const T get() const 00063 { 00064 const value<T>* pValue = dynamic_cast<const value<T>*>(pValue_.get()); 00065 if (pValue) 00066 { 00067 return pValue->mT_; 00068 } 00069 else 00070 { 00071 if (pValue_) 00072 throw lua::exception("var", 00073 "Conversion from type \""+std::string(pValue_->get_type().name())+ 00074 "\" to \""+typeid(T).name()+"\" failed. Returning default " 00075 "value." 00076 ); 00077 00078 return T(); 00079 } 00080 } 00081 00082 /// Checks if this variable is empty. 00083 /** \return 'true' if this variable is empty 00084 * \note Only the default constructor of var returns 00085 * an empty variable. 00086 */ 00087 bool is_empty() const; 00088 00089 /// Returns the type of the contained value. 00090 /** \return The type of the contained value 00091 * \note Returns typeid(void) if the variable is empty. 00092 */ 00093 const var_type& get_type() const; 00094 00095 /// Checks the contained value's type. 00096 /** \return 'true' if the contained value's type is the one 00097 * you provided 00098 */ 00099 template<class T> 00100 bool is_of_type() const 00101 { 00102 if (pValue_) 00103 { 00104 return pValue_->get_type() == typeid(T); 00105 } 00106 else 00107 { 00108 return typeid(void) == typeid(T); 00109 } 00110 } 00111 00112 /// Converts this variable to a string. 00113 /** \return This variable converted to a string 00114 */ 00115 std::string to_string() const; 00116 00117 static const var_type& VALUE_NONE; 00118 static const var_type& VALUE_INT; 00119 static const var_type& VALUE_UINT; 00120 static const var_type& VALUE_FLOAT; 00121 static const var_type& VALUE_DOUBLE; 00122 static const var_type& VALUE_BOOL; 00123 static const var_type& VALUE_STRING; 00124 static const var_type& VALUE_POINTER; 00125 00126 private : 00127 00128 /** \cond NOT_REMOVE_FROM_DOC 00129 */ 00130 00131 class value_base 00132 { 00133 public : 00134 00135 virtual ~value_base() {} 00136 virtual value_base* clone() const = 0; 00137 virtual const var_type& get_type() const = 0; 00138 }; 00139 00140 template <class T> 00141 class value : public value_base 00142 { 00143 public : 00144 00145 #ifdef MSVC 00146 // Note : Disable a false warning from Microsoft's Visual C++ : 00147 // "the inline specifier cannot be used when a friend declaration 00148 // refers to a specialization of a function template" 00149 #pragma warning( disable : 4396 ) 00150 #endif 00151 friend const T var::get<>() const; 00152 00153 value(const T& mT) : mT_(mT) {} 00154 00155 value_base* clone() const 00156 { 00157 return new value(mT_); 00158 } 00159 00160 const var_type& get_type() const 00161 { 00162 return typeid(T); 00163 } 00164 00165 private : 00166 00167 T mT_; 00168 }; 00169 00170 /** \endcond 00171 */ 00172 00173 utils::refptr<value_base> pValue_; 00174 }; 00175 } 00176 00177 #endif