1 /*
2  * This source file is part of libRocket, the HTML/CSS Interface Middleware
3  *
4  * For the latest information, see http://www.librocket.com
5  *
6  * Copyright (c) 2008-2010 CodePoint Ltd, Shift Technology Ltd
7  *
8  * Permission is hereby granted, free of charge, to any person obtaining a copy
9  * of this software and associated documentation files (the "Software"), to deal
10  * in the Software without restriction, including without limitation the rights
11  * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
12  * copies of the Software, and to permit persons to whom the Software is
13  * furnished to do so, subject to the following conditions:
14  *
15  * The above copyright notice and this permission notice shall be included in
16  * all copies or substantial portions of the Software.
17  *
18  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
19  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
20  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
21  * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
22  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
23  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
24  * THE SOFTWARE.
25  *
26  */
27 
28 #ifndef ROCKETVARIANT_H
29 #define ROCKETVARIANT_H
30 
31 #include "Header.h"
32 #include "Types.h"
33 #include "TypeConverter.h"
34 #include <list>
35 #include <type_traits>
36 
37 namespace Rocket {
38 namespace Core {
39 
40 /**
41 	Variant is a container that can store a selection of basic types. The variant will store the
42 	value in the native form corresponding to the version of Set that was called.
43 
44 	Get is templated to convert from the stored form to the requested form by using a TypeConverter.
45 
46 	@author Lloyd Weehuizen
47  */
48 
49 class ROCKETCORE_API Variant
50 {
51 public:
52 	Variant();
53 	/// Templatised constructors don't work for the copy constructor, so we have to define it
54 	/// explicitly.
55 	Variant(const Variant&);
56 	/// Constructs a variant with internal data.
57 	/// @param[in] t Data of a supported type to set on the variant.
58 	template< typename T >
59 	Variant(const T& t);
60 
61 	~Variant();
62 
63 	/// Type of data stored in the variant.
64 	enum Type
65 	{
66 		NONE = '-',
67 		BYTE = 'b',
68 		CHAR = 'c',
69 		FLOAT = 'f',
70 		INT = 'i',
71 		STRING = 's',
72 		WORD = 'w',
73 		VECTOR2 = '2',
74 		COLOURF = 'g',
75 		COLOURB = 'h',
76 		SCRIPTINTERFACE = 'p',
77 		VOIDPTR = '*',
78 	};
79 
80 	/// Clears the data structure stored by the variant.
81 	void Clear();
82 
83 	/// Gets the current internal representation type.
84 	/// @return The type of data stored in the variant internally.
85 	Type GetType() const;
86 
87 	/// Shares another variant's data with this variant.
88 	/// @param[in] copy Variant to share data.
89 	void Set(const Variant& copy);
90 	/// Sets a byte value on this variant.
91 	/// @param[in] value New value to set.
92 	void Set(const byte value);
93 	/// Sets a signed char value on this variant.
94 	/// @param[in] value New value to set.
95 	void Set(const char value);
96 	/// Sets a float value on this variant.
97 	/// @param[in] value New value to set.
98 	void Set(const float value);
99 	/// Sets a signed int value on this variant.
100 	/// @param[in] value New value to set.
101 	void Set(const int value);
102 	/// Sets a word value on this variant.
103 	/// @param[in] value New value to set.
104 	void Set(const word value);
105 	/// Sets a constant C string value on this variant.
106 	/// @param[in] value New value to set.
107 	void Set(const char* value);
108 	/// Sets a generic void* value on this variant.
109 	/// @param[in] value New value to set.
110 	void Set(void* value);
111 	/// Sets an EMP string value on this variant.
112 	/// @param[in] value New value to set.
113 	void Set(const String& value);
114 	/// Sets a Vector2f value on this variant.
115 	/// @param[in] value New value to set.
116 	void Set(const Vector2f& value);
117 	/// Sets a Colourf value on this variant.
118 	/// @param[in] value New value to set.
119 	void Set(const Colourf& value);
120 	/// Sets a Colourb value on this variant.
121 	/// @param[in] value New value to set.
122 	void Set(const Colourb& value);
123 	/// Sets a script object value on this variant.
124 	/// @param[in] value New value to set.
125 	void Set(ScriptInterface* value);
126 
127 	/// Templatised data accessor. TypeConverters will be used to attempt to convert from the
128 	/// internal representation to the requested representation.
129 	/// @return Data in the requested type.
130 	template< typename T >
131 	T Get() const;
132 
133 	/// Templatised data accessor. TypeConverters will be used to attempt to convert from the
134 	/// internal representation to the requested representation.
135 	/// @param[out] value Data in the requested type.
136 	/// @return True if the value was converted and returned, false if no data was stored in the variant.
137 	template< typename T >
138 	bool GetInto(T& value) const;
139 
140 	/// Assigns another variant's internal data to this variant.
141 	/// @param[in] copy Variant to share data.
142 	Variant& operator=(const Variant& copy);
143 
144 private:
145 
146 #ifdef ROCKET_ARCH_64
147 		static const size_t LOCAL_DATA_SIZE = 40; // Required for Strings
148 #else
149 		static const size_t LOCAL_DATA_SIZE = 24;
150 #endif
151     Type type;
152     std::aligned_union<0, byte, char, float, int, String, word, Vector2f, Colourf, Colourb, ScriptInterface*,
153                        void*>::type data;
154 };
155 
156 #include "Variant.inl"
157 
158 }
159 }
160 
161 #endif
162