Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: code/branches/core2/src/util/MultiTypeMath.cc @ 1001

Last change on this file since 1001 was 1001, checked in by landauf, 16 years ago

ok, be aware, here comes a big one. people with weak nerves should probably better look away or take some serious drugs.
this update includes partial and explicit class template specialization, partial and explicit specialized template function overloading, template meta programming and a simple typecast.
yeah right, a typecast. but let me explain the whole story from the beginning.

it all started with a simple problem: i had a double in a MultiType and wanted a float, but i always got 0. what was the problem? the conversion 'MultiType to anyting' was handled by the Converter class in util/Convert.h and the Converter was specialized for strings, multitypes, vectors and so on, but not for int, float, bool, …
so i've first wanted to implement a typecast as default, but this was a bad idea because it doesn't work for almost every generic type.
implementing an explicit specialization for every possible pair of primitives (did you ever happened to use an unsigned short? or a long double? no? ignorants :D) would have been a simple but ugly solution.
but there were other problems: if there's a rule to convert a string into anything and another rule to convert anything into an int - what happens if you want to convert a string into an int? compiler error! …ambiguous partial template specialization.
so i've spent days and nights to find a solution. this is my 5th try or so and i'm still really unsure if it works, but it's the first version i want to commit to have at least a backup.
if you're interested in looking at the code you better wait until i've cleaned up the whole thing, it's a real mess. and i want to do further tests, but now i'm tired. good night ;)

File size: 9.1 KB
Line 
1/*
2 *   ORXONOX - the hottest 3D action shooter ever to exist
3 *
4 *
5 *   License notice:
6 *
7 *   This program is free software; you can redistribute it and/or
8 *   modify it under the terms of the GNU General Public License
9 *   as published by the Free Software Foundation; either version 2
10 *   of the License, or (at your option) any later version.
11 *
12 *   This program is distributed in the hope that it will be useful,
13 *   but WITHOUT ANY WARRANTY; without even the implied warranty of
14 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15 *   GNU General Public License for more details.
16 *
17 *   You should have received a copy of the GNU General Public License
18 *   along with this program; if not, write to the Free Software
19 *   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
20 *
21 *   Author:
22 *      Fabian 'x3n' Landau
23 *   Co-authors:
24 *      ...
25 *
26 *   Inspiration: MultiType by Benjamin Grauer
27 */
28
29#include "MultiTypeMath.h"
30#include "Convert.h"
31
32MultiTypeMath::MultiTypeMath(MultiType type) : MultiTypeString(type)
33{
34    if (type == MT_vector2)
35        this->vector2_ = orxonox::Vector2(0, 0);
36    else if (type == MT_vector3)
37        this->vector3_ = orxonox::Vector3(0, 0, 0);
38    else if (type == MT_colourvalue)
39        this->colourvalue_ = orxonox::ColourValue(0, 0, 0, 0);
40    else if (type == MT_quaternion)
41        this->quaternion_ = orxonox::Quaternion(1, 0, 0, 0);
42    else if (type == MT_radian)
43        this->radian_ = orxonox::Radian(0);
44    else if (type == MT_degree)
45        this->degree_ = orxonox::Degree(0);
46}
47
48bool MultiTypeMath::operator==(const MultiTypeMath& mtm) const
49{
50    if (!MultiTypeString::operator==(mtm) && this->type_ == mtm.type_)
51    {
52        if (this->type_ == MT_vector2)
53            return (this->vector2_ == mtm.vector2_);
54        else if (this->type_ == MT_vector3)
55            return (this->vector3_ == mtm.vector3_);
56        else if (this->type_ == MT_colourvalue)
57            return (this->colourvalue_ == mtm.colourvalue_);
58        else if (this->type_ == MT_quaternion)
59            return (this->quaternion_ == mtm.quaternion_);
60        else if (this->type_ == MT_radian)
61            return (this->radian_ == mtm.radian_);
62        else if (this->type_ == MT_degree)
63            return (this->degree_ == mtm.degree_);
64    }
65
66    return false;
67}
68
69bool MultiTypeMath::operator!=(const MultiTypeMath& mtm) const
70{
71    if (MultiTypeString::operator==(mtm) && this->type_ == mtm.type_)
72    {
73        if (this->type_ == MT_vector2)
74            return (this->vector2_ != mtm.vector2_);
75        else if (this->type_ == MT_vector3)
76            return (this->vector3_ != mtm.vector3_);
77        else if (this->type_ == MT_colourvalue)
78            return (this->colourvalue_ != mtm.colourvalue_);
79        else if (this->type_ == MT_quaternion)
80            return (this->quaternion_ != mtm.quaternion_);
81        else if (this->type_ == MT_radian)
82            return (this->radian_ != mtm.radian_);
83        else if (this->type_ == MT_degree)
84            return (this->degree_ != mtm.degree_);
85    }
86
87    return true;
88}
89
90MultiTypeMath::operator void*() const
91{ return (this->type_ == MT_void) ? this->value_.void_ : getConvertedValue<MultiTypeMath, void*>(*this, 0); }
92MultiTypeMath::operator int() const
93{ return (this->type_ == MT_int) ? this->value_.int_ : getConvertedValue<MultiTypeMath, int>(*this, 0); }
94MultiTypeMath::operator unsigned int() const
95{ return (this->type_ == MT_uint) ? this->value_.uint_ : getConvertedValue<MultiTypeMath, unsigned int>(*this, 0); }
96MultiTypeMath::operator char() const
97{ return (this->type_ == MT_char) ? this->value_.char_ : getConvertedValue<MultiTypeMath, char>(*this, 0); }
98MultiTypeMath::operator unsigned char() const
99{ return (this->type_ == MT_uchar) ? this->value_.uchar_ : getConvertedValue<MultiTypeMath, unsigned char>(*this, 0); }
100MultiTypeMath::operator short() const
101{ return (this->type_ == MT_short) ? this->value_.short_ : getConvertedValue<MultiTypeMath, short>(*this, 0); }
102MultiTypeMath::operator unsigned short() const
103{ return (this->type_ == MT_ushort) ? this->value_.ushort_ : getConvertedValue<MultiTypeMath, unsigned short>(*this, 0); }
104MultiTypeMath::operator long() const
105{ return (this->type_ == MT_long) ? this->value_.long_ : getConvertedValue<MultiTypeMath, long>(*this, 0); }
106MultiTypeMath::operator unsigned long() const
107{ return (this->type_ == MT_ulong) ? this->value_.ulong_ : getConvertedValue<MultiTypeMath, unsigned long>(*this, 0); }
108MultiTypeMath::operator float() const
109{ return (this->type_ == MT_float) ? this->value_.float_ : getConvertedValue<MultiTypeMath, float>(*this, 0); }
110MultiTypeMath::operator double() const
111{ return (this->type_ == MT_double) ? this->value_.double_ : getConvertedValue<MultiTypeMath, double>(*this, 0); }
112MultiTypeMath::operator long double() const
113{ return (this->type_ == MT_longdouble) ? this->value_.longdouble_ : getConvertedValue<MultiTypeMath, long double>(*this, 0); }
114MultiTypeMath::operator bool() const
115{ return (this->type_ == MT_bool) ? this->value_.bool_ : getConvertedValue<MultiTypeMath, bool>(*this, 0); }
116MultiTypeMath::operator std::string() const
117{ return (this->type_ == MT_string) ? this->string_ : getConvertedValue<MultiTypeMath, std::string>(*this); }
118MultiTypeMath::operator const char*() const
119{ return ((this->type_ == MT_constchar) ? this->string_ : getConvertedValue<MultiTypeMath, std::string>(*this)).c_str(); }
120MultiTypeMath::operator orxonox::Vector2() const
121{ return (this->type_ == MT_vector2) ? this->vector2_ : getConvertedValue<MultiTypeMath, orxonox::Vector2>(*this); }
122MultiTypeMath::operator orxonox::Vector3() const
123{ return (this->type_ == MT_vector3) ? this->vector3_ : getConvertedValue<MultiTypeMath, orxonox::Vector3>(*this); }
124MultiTypeMath::operator orxonox::Quaternion() const
125{ return (this->type_ == MT_quaternion) ? this->quaternion_ : getConvertedValue<MultiTypeMath, orxonox::Quaternion>(*this); }
126MultiTypeMath::operator orxonox::ColourValue() const
127{ return (this->type_ == MT_colourvalue) ? this->colourvalue_ : getConvertedValue<MultiTypeMath, orxonox::ColourValue>(*this); }
128MultiTypeMath::operator orxonox::Radian() const
129{ return (this->type_ == MT_radian) ? this->radian_ : getConvertedValue<MultiTypeMath, orxonox::Radian>(*this); }
130MultiTypeMath::operator orxonox::Degree() const
131{ return (this->type_ == MT_degree) ? this->degree_ : getConvertedValue<MultiTypeMath, orxonox::Degree>(*this); }
132
133void MultiTypeMath::setValue(const MultiTypeMath& mtm)
134{
135    MultiTypeString::setValue(mtm);
136    this->vector2_ = mtm.vector2_;
137    this->vector3_ = mtm.vector3_;
138    this->quaternion_ = mtm.quaternion_;
139    this->colourvalue_ = mtm.colourvalue_;
140    this->radian_ = mtm.radian_;
141    this->degree_ = mtm.degree_;
142}
143
144std::string MultiTypeMath::getTypename() const
145{
146    if (this->type_ == MT_vector2)
147        return "Vector2";
148    else if (this->type_ == MT_vector3)
149        return "Vector3";
150    else if (this->type_ == MT_colourvalue)
151        return "ColourValue";
152    else if (this->type_ == MT_quaternion)
153        return "Quaternion";
154    else if (this->type_ == MT_radian)
155        return "Radian";
156    else if (this->type_ == MT_degree)
157        return "Degree";
158    else
159        return MultiTypeString::getTypename();
160}
161
162std::string MultiTypeMath::toString() const
163{
164    std::string output;
165
166    if (this->type_ == MT_vector2)
167        ConvertValue(&output, this->vector2_, CP_FromType);
168    else if (this->type_ == MT_vector3)
169        ConvertValue(&output, this->vector3_, CP_FromType);
170    else if (this->type_ == MT_colourvalue)
171    { std::cout << "3_1\n";
172        ConvertValue(&output, this->colourvalue_, CP_FromType);}
173    else if (this->type_ == MT_quaternion)
174        ConvertValue(&output, this->quaternion_, CP_FromType);
175    else if (this->type_ == MT_radian)
176        ConvertValue(&output, this->radian_);
177    else if (this->type_ == MT_degree)
178        ConvertValue(&output, this->degree_);
179    else
180        return MultiTypeString::toString();
181
182    return output;
183}
184
185bool MultiTypeMath::fromString(const std::string value)
186{
187    if (this->type_ == MT_vector2)
188        return ConvertValue(&this->vector2_, value, orxonox::Vector2(0, 0), CP_FromType);
189    else if (this->type_ == MT_vector3)
190        return ConvertValue(&this->vector3_, value, orxonox::Vector3(0, 0, 0), CP_FromType);
191    else if (this->type_ == MT_colourvalue)
192    { std::cout << "4_1\n";
193        return ConvertValue(&this->colourvalue_, value, orxonox::ColourValue(0, 0, 0, 0), CP_FromType); }
194    else if (this->type_ == MT_quaternion)
195        return ConvertValue(&this->quaternion_, value, orxonox::Quaternion(1, 0, 0, 0), CP_FromType);
196    else if (this->type_ == MT_radian)
197        return ConvertValue(&this->radian_, value, orxonox::Radian(0));
198    else if (this->type_ == MT_degree)
199        return ConvertValue(&this->degree_, value, orxonox::Degree(0));
200    else
201        return MultiTypeString::fromString(value);
202}
203
204std::ostream& operator<<(std::ostream& out, MultiTypeMath& mtm)
205{
206    out << mtm.toString();
207    return out;
208}
Note: See TracBrowser for help on using the repository browser.