- Main Page
- Namespaces
- Classes
- Files

- File List
- File Members

# D:/Programmation/Sources/Tensor2/Utils/include/frost_utils_var.h

Go to the documentation of this file.

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