1 /******************************************************************************
2 
3   This source file is part of the Avogadro project.
4 
5   Copyright 2011-2012 Kitware, Inc.
6 
7   This source code is released under the New BSD License, (the "License").
8 
9   Unless required by applicable law or agreed to in writing, software
10   distributed under the License is distributed on an "AS IS" BASIS,
11   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12   See the License for the specific language governing permissions and
13   limitations under the License.
14 
15 ******************************************************************************/
16 
17 #ifndef AVOGADRO_CORE_VARIANT_H
18 #define AVOGADRO_CORE_VARIANT_H
19 
20 #include "avogadrocore.h"
21 #include "matrix.h"
22 
23 #include <string>
24 
25 namespace Avogadro {
26 namespace Core {
27 
28 /**
29  * @class Variant variant.h <avogadro/core/variant.h>
30  * @brief The Variant class represents a union of data values.
31  *
32  * Variant objects allow for the storage of and conversion between a variety of
33  * different data types.
34  */
35 
36 class AVOGADROCORE_EXPORT Variant
37 {
38 public:
39   // enumerations
40   enum Type
41   {
42     Null,
43     Bool,
44     Int,
45     Long,
46     Float,
47     Double,
48     Pointer,
49     String,
50     Matrix
51   };
52 
53   /** Creates a null variant. */
54   inline Variant();
55 
56   /** Creates a variant to store @p value. */
57   template <typename T>
58   Variant(T value);
59 
60   /** Creates a new copy of @p variant. */
61   inline Variant(const Variant& variant);
62 
63   /** Destroys the variant object. */
64   inline ~Variant();
65 
66   /** Returns variant's type. */
67   inline Type type() const;
68 
69   /** Returns \c true if the variant is null. */
70   inline bool isNull() const;
71 
72   /** Sets the value of the variant to @p value. */
73   template <typename T>
74   bool setValue(T value);
75 
76   /** Returns the value of the variant in the type given by \c T. */
77   template <typename T>
78   T value() const;
79 
80   /** Clears the variant's data and sets the variant to null. */
81   inline void clear();
82 
83   /** Returns the value of the variant as a \c bool. */
84   inline bool toBool() const;
85 
86   /** Returns the value of the variant as a \c char. */
87   inline char toChar() const;
88 
89   /** Returns the value of the variant as an \c unsigned \c char. */
90   inline unsigned char toUChar() const;
91 
92   /** Returns the value of the variant as a \c short. */
93   inline short toShort() const;
94 
95   /** Returns the value of the variant as an \c unsigned \c short. */
96   inline unsigned short toUShort() const;
97 
98   /** Returns the value of the variant as an \c int. */
99   inline int toInt() const;
100 
101   /** Returns the value of the variant as an \c unsigned \c int. */
102   inline unsigned int toUInt() const;
103 
104   /**  Returns the value of the variant as a \c long. */
105   inline long toLong() const;
106 
107   /**  Returns the value of the variant as an \c unsigned \c long. */
108   inline unsigned long toULong() const;
109 
110   /** Returns the value of the variant as a \c float. */
111   inline float toFloat() const;
112 
113   /** Returns the value of the variant as a \c double. */
114   inline double toDouble() const;
115 
116   /** Returns the value of the variant as a \c Real. */
117   inline Real toReal() const;
118 
119   /** Returns the value of the variant as a pointer. */
120   inline void* toPointer() const;
121 
122   /** Returns the value of the variant as a string. */
123   inline std::string toString() const;
124 
125   /** Returns the value of the variant as a MatrixX. */
126   inline MatrixX toMatrix() const;
127 
128   /**
129    * Returns a reference to the value of the variant as a MatrixX.
130    * This method will not perform any casting -- if type() is not exactly
131    * MatrixX, the function will fail and return a reference to an empty MatrixX.
132    */
133   inline const MatrixX& toMatrixRef() const;
134 
135   // operators
136   inline Variant& operator=(const Variant& variant);
137 
138 private:
139   template <typename T>
140   static T lexical_cast(const std::string& string);
141 
142 private:
143   Type m_type;
144   union
145   {
146     bool _bool;
147     char _char;
148     int _int;
149     long _long;
150     float _float;
151     double _double;
152     void* pointer;
153     std::string* string;
154     MatrixX* matrix;
155   } m_value;
156 };
157 
158 } // end Core namespace
159 } // end Avogadro namespace
160 
161 #include "variant-inline.h"
162 
163 #endif // AVOGADRO_CORE_VARIANT_H
164