C:/Projets/hexamonkey/core/variant.h
Go to the documentation of this file.
00001 //This file is part of the HexaMonkey project, a multimedia analyser
00002 //Copyright (C) 2013  Sevan Drapeau-Martin, Nicolas Fleury
00003 
00004 //This program is free software; you can redistribute it and/or
00005 //modify it under the terms of the GNU General Public License
00006 //as published by the Free Software Foundation; either version 2
00007 //of the License, or (at your option) any later version.
00008 
00009 //This program is distributed in the hope that it will be useful,
00010 //but WITHOUT ANY WARRANTY; without even the implied warranty of
00011 //MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00012 //GNU General Public License for more details.
00013 
00014 //You should have received a copy of the GNU General Public License
00015 //along with this program; if not, write to the Free Software
00016 //Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
00017 
00018 #ifndef VARIANT_H
00019 #define VARIANT_H
00020 
00021 #include <exception>
00022 #include <iostream>
00023 #include <string>
00024 
00025 class ObjectType;
00026 
00040 class Variant
00041 {
00042 public:
00043     enum Type{
00045         valuelessType       = 0x00,
00047         undefinedType       = 0x00,
00049         nullType            = 0x04,
00051         numericalType       = 0x01,
00054         integerType         = 0x05,
00057         unsignedIntegerType = 0x01,
00060         floatingType        = 0x09,
00062         stringType          = 0x02,
00064         objectType          = 0x03
00065     };
00066 
00067     enum Display{
00068         decimal     = 0x00,
00069         binary      = 0x10,
00070         octal       = 0x20,
00071         hexadecimal = 0x30
00072     };
00073 
00075     class InvalidTypeConversionException: public std::exception
00076     {
00077       virtual const char* what() const throw()
00078       {
00079         return "Variant: invalid type conversion";
00080       }
00081     };
00082 
00083     class InvalidOperationException: public std::exception
00084     {
00085       virtual const char* what() const throw()
00086       {
00087         return "Variant: invalid operation";
00088       }
00089     };
00091 
00092     Variant();
00093     static Variant null();
00094 
00095     Variant(const Variant& other);
00096 
00097     Variant(bool l);
00098     Variant(char l);
00099     Variant(int l);
00100     Variant(long l);
00101     Variant(long long l);
00102 
00103     Variant(unsigned char ul);
00104     Variant(unsigned int ul);
00105     Variant(unsigned long ul);
00106     Variant(unsigned long long ul);
00107 
00108     Variant(float f);
00109     Variant(double f);
00110 
00111     Variant(const std::string& s);
00112     Variant(const char* s);
00113 
00114     Variant(const ObjectType& t);
00115 
00116     ~Variant();
00117 
00118     void setValue(Variant other);
00119 
00120     void setValue(bool l);
00121     void setValue(char l);
00122     void setValue(int l);
00123     void setValue(long l);
00124     void setValue(long long l);
00125 
00126     void setValue(unsigned char ul);
00127     void setValue(unsigned int ul);
00128     void setValue(unsigned long ul);
00129     void setValue(unsigned long long ul);
00130 
00131     void setValue(float f);
00132     void setValue(double f);
00133 
00134     void setValue(const std::string& s);
00135     void setValue(const char* s);
00136 
00137     void setValue(const ObjectType& t);
00138 
00139     void clear();
00140 
00141     Variant& operator=(Variant other);
00142     friend void swap(Variant& a, Variant& b);
00143 
00144     bool canConvertTo(Type otherType) const;
00145     Variant &convertTo(Type newType);
00146 
00147     long long          toInteger()         const;
00148     unsigned long long toUnsignedInteger() const;
00149     double             toDouble()          const;
00150     const std::string& toString()          const;
00151     const ObjectType&  toObjectType()      const;
00152     ObjectType&        toObjectType()           ;
00153     bool               toBool()            const;
00154 
00155     Type type() const;
00156     bool hasNumericalType() const;
00157     bool isValueless() const;
00158     bool isNull() const;
00159     bool isUndefined() const;
00160 
00161     friend bool operator==(const Variant& a, const Variant& b);
00162     friend bool operator< (const Variant& a, const Variant& b);
00163     friend bool operator<=(const Variant& a, const Variant& b);
00164 
00165     Variant& operator+=(const Variant& other);
00166     Variant& operator-=(const Variant& other);
00167     Variant& operator*=(const Variant& other);
00168     Variant& operator/=(const Variant& other);
00169     Variant& operator%=(const Variant& other);
00170 
00171     Variant& operator++();
00172     Variant  operator++(int);
00173     Variant& operator--();
00174     Variant  operator--(int);
00175 
00176 
00177     Variant operator-() const;
00178 
00179     Variant& operator|=(const Variant& other);
00180     Variant& operator^=(const Variant& other);
00181     Variant& operator&=(const Variant& other);
00182     Variant& operator<<=(const Variant& other);
00183     Variant& operator>>=(const Variant& other);
00184 
00185     Variant operator~() const;
00186 
00187     bool operator!() const;
00188 
00189     void setDisplayType(Display display);
00190     std::ostream& display(std::ostream& out, bool setFlags = true) const;
00191 
00192 
00193 
00194 private:
00195     typedef union{
00196         long long l;
00197         unsigned long long ul;
00198         double f;
00199         std::string* s;
00200         ObjectType* t;
00201     } Data;
00202 
00203     Data    _data;
00204     uint8_t _type;
00205 
00206     static const uint8_t superTypeMask = 0x03;
00207     static const uint8_t typeMask = 0x0f;
00208     static const uint8_t displayMask = 0x30;
00209     static const uint8_t signedBit = 0x04;
00210 };
00211 
00212 void swap(Variant& a, Variant& b);
00213 
00214 Variant operator+ (Variant a, const Variant& b);
00215 Variant operator- (Variant a, const Variant& b);
00216 Variant operator* (Variant a, const Variant& b);
00217 Variant operator/ (Variant a, const Variant& b);
00218 Variant operator% (Variant a, const Variant& b);
00219 
00220 Variant operator| (Variant a, const Variant& b);
00221 Variant operator^ (Variant a, const Variant& b);
00222 Variant operator& (Variant a, const Variant& b);
00223 Variant operator<<(Variant a, const Variant& b);
00224 Variant operator>>(Variant a, const Variant& b);
00225 
00226 bool operator==(const Variant& a, const Variant& b);
00227 bool operator!=(const Variant& a, const Variant& b);
00228 bool operator< (const Variant& a, const Variant& b);
00229 bool operator<=(const Variant& a, const Variant& b);
00230 bool operator> (const Variant& a, const Variant& b);
00231 bool operator>=(const Variant& a, const Variant& b);
00232 
00233 bool operator&&(const Variant& a, const Variant& b);
00234 bool operator||(const Variant& a, const Variant& b);
00235 
00236 std::ostream& operator<<(std::ostream& out, const Variant& variant);
00237 
00239 namespace std
00240 {
00241     template<>
00242     struct hash<Variant>
00243     {
00244         std::size_t operator()(Variant const& var) const
00245         {
00246             std::size_t const h1 ( std::hash<int>()(var.type()) );
00247             std::size_t const h2 ( std::hash<std::string>()(var.toString()) );
00248             return h1 ^ (h2 << 3);
00249         }
00250     };
00251 }
00254 #endif // VARIANT_H