Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: code/branches/core2/src/util/Convert.h @ 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: 29.0 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 *      Benjamin Grauer
23 *   Co-authors:
24 *      Fabian 'x3n' Landau
25 */
26
27/*!
28    @file Convert.h
29    @brief Definition and Implementation of the Convert class.
30*/
31
32#ifndef _Convert_H__
33#define _Convert_H__
34
35#include <string>
36#include <sstream>
37
38#include "UtilPrereqs.h"
39#include "Math.h"
40#include "SubString.h"
41#include "MultiTypeMath.h"
42
43
44//////////
45// Main //
46//////////
47/*
48enum ConversionPreference
49{
50    CP_ToType,
51    CP_FromType
52};
53
54// Helper classes to determine the preferred partial template specialization
55class _AnyType_  {};
56class _ToType_   {} static __to__;
57class _FromType_ {} static __from__;
58class _Explicit_ {} static __explicit__;
59
60
61// The default convert functions
62template <class FromType, class ToType>
63static bool convert(ToType* output, const FromType& input, _ToType_* type)
64{ std::cout << "default to" << std::endl; return false; }
65template <class FromType, class ToType>
66static bool convert(ToType* output, const FromType& input, _FromType_* type)
67{ std::cout << "default from" << std::endl; return false; }
68template <class FromType, class ToType>
69static bool convert(ToType* output, const FromType& input, _Explicit_* type)
70{ std::cout << "default explicit" << std::endl; return false; }
71
72
73// The default convert function if both types are the same
74template <class BothTypes>
75static bool convert(BothTypes* output, const BothTypes& input, _Explicit_* type)
76{ (*output) = input; return true; }
77
78
79// The default conversion of primitives: A typecast (defined over two partial specialized templates to exclude all non-primitive types and classes)
80template <class FromType, class ToType, class Type>
81static bool convertDefault(ToType* output, const FromType& input, Type* type)
82{ return false; }
83#define CONVERT_PRIMITIVE_DEFAULT(primitive) \
84template <class FromType> static bool convertDefault(primitive* output, const FromType& input, _ToType_* type) { return convertDefault(output, input, &__from__); } \
85template <class ToType>   static bool convertDefault(ToType* output, const primitive& input, _FromType_* type) { (*output) = (ToType)input; return true; }
86CONVERT_PRIMITIVE_DEFAULT(int)
87CONVERT_PRIMITIVE_DEFAULT(unsigned int)
88CONVERT_PRIMITIVE_DEFAULT(char)
89CONVERT_PRIMITIVE_DEFAULT(unsigned char)
90CONVERT_PRIMITIVE_DEFAULT(short)
91CONVERT_PRIMITIVE_DEFAULT(unsigned short)
92CONVERT_PRIMITIVE_DEFAULT(long)
93CONVERT_PRIMITIVE_DEFAULT(unsigned long)
94CONVERT_PRIMITIVE_DEFAULT(float)
95CONVERT_PRIMITIVE_DEFAULT(double)
96CONVERT_PRIMITIVE_DEFAULT(long double)
97CONVERT_PRIMITIVE_DEFAULT(bool)
98
99// Calls all four possibilities of converting two values: (the order of 2 and 3 can be changed by setting bPreferToType to false)
100// 1) explicit specialization
101// 2) partial specialization for ToType
102// 3) partial specialization of the FromType
103// 4) default conversion if available
104template<class FromType, class ToType>
105static bool convertValue(ToType* output, const FromType& input, ConversionPreference preference = CP_ToType)
106{
107std::cout << "1_1\n";
108    if (convert(output, input, &__explicit__))
109        return true;
110
111std::cout << "1_2\n";
112    if (preference == CP_ToType)
113    {
114std::cout << "1_3\n";
115        if (convert(output, input, &__to__))
116            return true;
117std::cout << "1_4\n";
118        if (convert(output, input, &__from__))
119            return true;
120std::cout << "1_5\n";
121    }
122    else
123    {
124std::cout << "1_6\n";
125        if (convert(output, input, &__from__))
126            return true;
127std::cout << "1_7\n";
128        if (convert(output, input, &__to__))
129            return true;
130std::cout << "1_8\n";
131    }
132std::cout << "1_9\n";
133    return convertDefault(output, input, &__to__);
134}
135*/
136
137    // Enum to declare the wanted conversion preference in case of equal type-levels
138    enum ConversionPreference
139    {
140        CP_ToType,
141        CP_FromType
142    };
143
144    // Helper classes to determine the preferred partial template specialization
145    class _AnyType_  {};
146    class _ToType_   {} static __to__;
147    class _FromType_ {} static __from__;
148    class _Explicit_ {} static __explicit__;
149
150
151    // The default convert functions
152    template <class FromType, class ToType>
153    static bool convert(ToType* output, const FromType& input, _ToType_* type)
154    { std::cout << "default to" << std::endl; return false; }
155    template <class FromType, class ToType>
156    static bool convert(ToType* output, const FromType& input, _FromType_* type)
157    { std::cout << "default from" << std::endl; return false; }
158    template <class FromType, class ToType>
159    static bool convert(ToType* output, const FromType& input, _Explicit_* type)
160    { std::cout << "default explicit" << std::endl; return false; }
161
162
163    // The default convert function if both types are the same
164    template <class BothTypes>
165    static bool convert(BothTypes* output, const BothTypes& input, _Explicit_* type)
166    { (*output) = input; return true; }
167
168
169    // The possible levels
170    #define __low__  0
171    #define __mid__  1
172    #define __high__ 2
173
174    // Defines the levels of all types
175    template <class T> struct ConverterLeveL          { enum { level = __high__ }; };
176    template <> struct ConverterLeveL<std::string>    { enum { level = __mid__ }; };
177    template <> struct ConverterLeveL<int>            { enum { level = __low__ }; };
178    template <> struct ConverterLeveL<unsigned int>   { enum { level = __low__ }; };
179    template <> struct ConverterLeveL<char>           { enum { level = __low__ }; };
180    template <> struct ConverterLeveL<unsigned char>  { enum { level = __low__ }; };
181    template <> struct ConverterLeveL<short>          { enum { level = __low__ }; };
182    template <> struct ConverterLeveL<unsigned short> { enum { level = __low__ }; };
183    template <> struct ConverterLeveL<long>           { enum { level = __low__ }; };
184    template <> struct ConverterLeveL<unsigned long>  { enum { level = __low__ }; };
185    template <> struct ConverterLeveL<float>          { enum { level = __low__ }; };
186    template <> struct ConverterLeveL<double>         { enum { level = __low__ }; };
187    template <> struct ConverterLeveL<long double>    { enum { level = __low__ }; };
188    template <> struct ConverterLeveL<bool>           { enum { level = __low__ }; };
189
190
191    // Calculates the preference based on the levels of FromType and ToType
192    template <int from, int to>
193    struct ConverterPreference
194    {
195        enum
196        {
197            max = (from > to) ? from : to,
198            diff = ((to - from) > 1) ? 1 : (((to - from) < -1) ? -1 : to - from)
199        };
200    };
201
202
203    // The default conversion: This usually does nothing
204    template <int max, class FromType, class ToType, class Type>
205    struct ConverterDefault
206    {
207        static bool convert(ToType* output, const FromType& input, Type* type)
208        {
209            return false;
210        }
211    };
212    // The default conversion for primitives: A typecast (defined over two partial specialized templates to exclude all non-primitive types and classes)    template <int max, class FromType, class ToType>
213    template <class FromType, class ToType, class Type>
214    struct ConverterDefault<0, FromType, ToType, Type>
215    {
216        static bool convert(ToType* output, const FromType& input, Type* type)
217        {
218            (*output) = (ToType)input;
219            return true;
220        }
221    };
222
223
224    // Converter: Converts input of FromType into output of ToType
225    template <int diff, int max, class FromType, class ToType>
226    struct Converter
227    {
228        static bool convertValue(ToType* output, const FromType& input, ConversionPreference preference = CP_ToType)
229        {
230            return false;
231        }
232    };
233    // Converter: FromType-level > ToType-level
234    template <int max, class FromType, class ToType>
235    struct Converter<-1, max, FromType, ToType>
236    {
237        static bool convertValue(ToType* output, const FromType& input, ConversionPreference preference = CP_ToType)
238        {
239            if (convert(output, input, &__explicit__))
240                return true;
241            if (convert(output, input, &__from__))
242                return true;
243            if (ConverterDefault<max, FromType, ToType, _ToType_>::convert(output, input, &__to__))
244                return true;
245
246            return false;
247        }
248    };
249    // Converter: ToType-level > FromType-level
250    template <int max, class FromType, class ToType>
251    struct Converter<1, max, FromType, ToType>
252    {
253        static bool convertValue(ToType* output, const FromType& input, ConversionPreference preference = CP_ToType)
254        {
255            if (convert(output, input, &__explicit__))
256                return true;
257            if (convert(output, input, &__to__))
258                return true;
259            if (ConverterDefault<max, FromType, ToType, _ToType_>::convert(output, input, &__to__))
260                return true;
261
262            return false;
263        }
264    };
265    // Converter: ToType-level = ToType-level
266    template <int max, class FromType, class ToType>
267    struct Converter<0, max, FromType, ToType>
268    {
269        static bool convertValue(ToType* output, const FromType& input, ConversionPreference preference = CP_ToType)
270        {
271            if (convert(output, input, &__explicit__))
272                return true;
273
274            if (preference == CP_ToType)
275            {
276                if (convert(output, input, &__to__))
277                    return true;
278                if (convert(output, input, &__from__))
279                    return true;
280            }
281            else
282            {
283                if (convert(output, input, &__from__))
284                    return true;
285                if (convert(output, input, &__to__))
286                    return true;
287            }
288
289            if (ConverterDefault<max, FromType, ToType, _ToType_>::convert(output, input, &__to__))
290                return true;
291
292            return false;
293        }
294    };
295
296
297    // Calls the Converter::convertValue function with the correct template type parameters calculated by ConverterPreference
298    template <class FromType, class ToType>
299    static bool convertValue(ToType* output, const FromType& input, ConversionPreference preference = CP_ToType)
300    {
301        return Converter<ConverterPreference<ConverterLeveL<FromType>::level, ConverterLeveL<ToType>::level>::diff, ConverterPreference<ConverterLeveL<FromType>::level, ConverterLeveL<ToType>::level>::max, FromType, ToType>::convertValue(output, input, preference);
302    }
303
304
305// Helper function: Calls convertValue with and without default value and returns true if the conversion was successful
306template<class FromType, class ToType>
307static bool ConvertValue(ToType* output, const FromType& input, ConversionPreference preference = CP_ToType)
308{
309    return convertValue(output, input, preference);
310}
311template<class FromType, class ToType>
312static bool ConvertValue(ToType* output, const FromType& input, const ToType& fallback, ConversionPreference preference = CP_ToType)
313{
314    if (convertValue(output, input, preference))
315        return true;
316
317    (*output) = fallback;
318    return false;
319}
320
321// Helper function: Calls convertValue with and without default value and returns the converted value
322template<class FromType, class ToType>
323static ToType getConvertedValue(const FromType& input, ConversionPreference preference = CP_ToType)
324{
325    ToType output = ToType();
326    ConvertValue(&output, input, preference);
327    return output;
328}
329template<class FromType, class ToType>
330static ToType getConvertedValue(const FromType& input, const ToType& fallback, ConversionPreference preference = CP_ToType)
331{
332    ToType output = fallback;
333    ConvertValue(&output, input, fallback, preference);
334    return output;
335}
336
337/////////////////////
338// SPECIALISATIONS //
339/////////////////////
340
341/*
342template <class FromType>
343static bool convertDefault(primitive* output, const FromType& input, _ToType_* type)
344{
345
346}
347
348template <class ToType>
349static bool convertDefault(ToType* output, const primitive& input, _FromType_* type)
350{
351
352}
353
354
355template <>
356static bool convertDefault(ToType* output, const FromType& input, _Explicit_* type)
357{
358
359}
360*/
361
362////////////
363// String //
364////////////
365
366// convert to string
367template <class FromType>
368static bool convert(std::string* output, const FromType& input, _ToType_* type)
369{
370    std::ostringstream oss;
371    if (oss << input)
372    {
373        (*output) = oss.str();
374        return true;
375    }
376    else
377        return false;
378}
379
380// convert from string
381template <class ToType>
382static bool convert(ToType* output, const std::string& input, _FromType_* type)
383{
384    std::istringstream iss(input);
385    if (iss >> (*output))
386        return true;
387    else
388        return false;
389}
390
391
392////////////////
393// MULTITYPES //
394////////////////
395
396// convert from MultiTypePrimitive
397template <class ToType>
398static bool convert(ToType* output, const MultiTypePrimitive& input, _FromType_* type)
399{
400    if (input.getType() == MT_void)
401        return ConvertValue(output, input.getVoid());
402    else if (input.getType() == MT_int)
403        return ConvertValue(output, input.getInt());
404    else if (input.getType() == MT_uint)
405        return ConvertValue(output, input.getUnsignedInt());
406    else if (input.getType() == MT_char)
407        return ConvertValue(output, input.getChar());
408    else if (input.getType() == MT_uchar)
409        return ConvertValue(output, input.getUnsignedChar());
410    else if (input.getType() == MT_short)
411        return ConvertValue(output, input.getShort());
412    else if (input.getType() == MT_ushort)
413        return ConvertValue(output, input.getUnsignedShort());
414    else if (input.getType() == MT_long)
415        return ConvertValue(output, input.getLong());
416    else if (input.getType() == MT_ulong)
417        return ConvertValue(output, input.getUnsignedLong());
418    else if (input.getType() == MT_float)
419        return ConvertValue(output, input.getFloat());
420    else if (input.getType() == MT_double)
421        return ConvertValue(output, input.getDouble());
422    else if (input.getType() == MT_longdouble)
423        return ConvertValue(output, input.getLongDouble());
424    else if (input.getType() == MT_bool)
425        return ConvertValue(output, input.getBool());
426    else
427        return false;
428}
429
430// convert from MultiTypeString
431template <class ToType>
432static bool convert(ToType* output, const MultiTypeString& input, _FromType_* type)
433{
434    if (input.getType() == MT_constchar)
435        return ConvertValue(output, input.getConstChar());
436    else if (input.getType() == MT_string)
437        return ConvertValue(output, input.getString());
438    else
439        return ConvertValue(output, (MultiTypePrimitive)input);
440}
441
442// convert from MultiTypeMath
443template <class ToType>
444static bool convert(ToType* output, const MultiTypeMath& input, _FromType_* type)
445{
446    if (input.getType() == MT_vector2)
447        return ConvertValue(output, input.getVector2(), CP_FromType);
448    else if (input.getType() == MT_vector3)
449        return ConvertValue(output, input.getVector3(), CP_FromType);
450    else if (input.getType() == MT_quaternion)
451        return ConvertValue(output, input.getQuaternion(), CP_FromType);
452    else if (input.getType() == MT_colourvalue)
453        return ConvertValue(output, input.getColourValue(), CP_FromType);
454    else if (input.getType() == MT_radian)
455        return ConvertValue(output, input.getRadian());
456    else if (input.getType() == MT_degree)
457        return ConvertValue(output, input.getDegree());
458    else
459        return ConvertValue(output, (MultiTypeString)input);
460}
461
462
463////////////////////
464// MATH TO STRING //
465////////////////////
466
467// Vector2 to std::string
468template <>
469static bool convert(std::string* output, const orxonox::Vector2& input, _Explicit_* type)
470{
471    std::ostringstream ostream;
472    if (ostream << input.x << "," << input.y)
473    {
474        (*output) = ostream.str();
475        return true;
476    }
477    return false;
478}
479
480/*
481// Vector2 to std::string
482template <>
483class Converter<orxonox::Vector2, std::string>
484{
485  public:
486    bool operator()(std::string* output, const orxonox::Vector2& input) const
487    {
488      std::ostringstream ostream;
489      if (ostream << input.x << "," << input.y)
490      {
491        (*output) = ostream.str();
492        return true;
493      }
494
495      return false;
496    }
497};
498*/
499// Vector3 to std::string
500template <>
501static bool convert(std::string* output, const orxonox::Vector3& input, _Explicit_* type)
502{
503    std::ostringstream ostream;
504    if (ostream << input.x << "," << input.y << "," << input.z)
505    {
506        (*output) = ostream.str();
507        return true;
508    }
509    return false;
510}
511
512/*
513// Vector3 to std::string
514template <>
515class Converter<orxonox::Vector3, std::string>
516{
517  public:
518    bool operator()(std::string* output, const orxonox::Vector3& input) const
519    {
520      std::ostringstream ostream;
521      if (ostream << input.x << "," << input.y << "," << input.z)
522      {
523        (*output) = ostream.str();
524        return true;
525      }
526
527      return false;
528    }
529};
530*/
531// Vector4 to std::string
532template <>
533static bool convert(std::string* output, const orxonox::Vector4& input, _Explicit_* type)
534{
535    std::ostringstream ostream;
536    if (ostream << input.x << "," << input.y << "," << input.z << "," << input.w)
537    {
538        (*output) = ostream.str();
539        return true;
540    }
541    return false;
542}
543/*
544// Vector4 to std::string
545template <>
546class Converter<orxonox::Vector4, std::string>
547{
548  public:
549    bool operator()(std::string* output, const orxonox::Vector4& input) const
550    {
551      std::ostringstream ostream;
552      if (ostream << input.x << "," << input.y << "," << input.z << "," << input.w)
553      {
554        (*output) = ostream.str();
555        return true;
556      }
557
558      return false;
559    }
560};
561*/
562// Quaternion to std::string
563template <>
564static bool convert(std::string* output, const orxonox::Quaternion& input, _Explicit_* type)
565{
566    std::ostringstream ostream;
567    if (ostream << input.w << "," << input.x << "," << input.y << "," << input.z)
568    {
569        (*output) = ostream.str();
570        return true;
571    }
572    return false;
573}
574/*
575// Quaternion to std::string
576template <>
577class Converter<orxonox::Quaternion, std::string>
578{
579  public:
580    bool operator()(std::string* output, const orxonox::Quaternion& input) const
581    {
582      std::ostringstream ostream;
583      if (ostream << input.w << "," << input.x << "," << input.y << "," << input.z)
584      {
585        (*output) = ostream.str();
586        return true;
587      }
588
589      return false;
590    }
591};
592*/
593// ColourValue to std::string
594template <>
595static bool convert(std::string* output, const orxonox::ColourValue& input, _Explicit_* type)
596{
597    std::ostringstream ostream;
598    if (ostream << input.r << "," << input.g << "," << input.b << "," << input.a)
599    {
600        (*output) = ostream.str();
601        return true;
602    }
603    return false;
604}
605/*
606// ColourValue to std::string
607template <>
608class Converter<orxonox::ColourValue, std::string>
609{
610  public:
611    bool operator()(std::string* output, const orxonox::ColourValue& input) const
612    {
613      std::ostringstream ostream;
614      if (ostream << input.r << "," << input.g << "," << input.b << "," << input.a)
615      {
616        (*output) = ostream.str();
617        return true;
618      }
619
620      return false;
621    }
622};
623*/
624
625
626////////////////////
627// STRING TO MATH //
628////////////////////
629
630// std::string to Vector2
631template <>
632static bool convert(orxonox::Vector2* output, const std::string& input, _Explicit_* type)
633{
634    unsigned int opening_parenthesis, closing_parenthesis = input.find(')');
635    if ((opening_parenthesis = input.find('(')) == std::string::npos) { opening_parenthesis = 0; } else { opening_parenthesis++; }
636
637    SubString tokens(input.substr(opening_parenthesis, closing_parenthesis - opening_parenthesis), ",", SubString::WhiteSpaces, false, '\\', true, '"', true, '\0', '\0', true, '\0');
638    if (tokens.size() >= 2)
639    {
640        if (!ConvertValue(&(output->x), tokens[0]))
641            return false;
642        if (!ConvertValue(&(output->y), tokens[1]))
643            return false;
644
645        return true;
646    }
647    return false;
648}
649/*
650// std::string to Vector2
651template <>
652class Converter<std::string, orxonox::Vector2>
653{
654  public:
655    bool operator()(orxonox::Vector2* output, const std::string& input) const
656    {
657      unsigned int opening_parenthesis, closing_parenthesis = input.find(')');
658      if ((opening_parenthesis = input.find('(')) == std::string::npos) { opening_parenthesis = 0; } else { opening_parenthesis++; }
659
660      SubString tokens(input.substr(opening_parenthesis, closing_parenthesis - opening_parenthesis), ",", SubString::WhiteSpaces, false, '\\', true, '"', true, '\0', '\0', true, '\0');
661
662      if (tokens.size() >= 2)
663      {
664        if (!ConvertValue(&(output->x), tokens[0]))
665          return false;
666        if (!ConvertValue(&(output->y), tokens[1]))
667          return false;
668
669        return true;
670      }
671
672      return false;
673    }
674};
675*/
676// std::string to Vector3
677template <>
678static bool convert(orxonox::Vector3* output, const std::string& input, _Explicit_* type)
679{
680    unsigned int opening_parenthesis, closing_parenthesis = input.find(')');
681    if ((opening_parenthesis = input.find('(')) == std::string::npos) { opening_parenthesis = 0; } else { opening_parenthesis++; }
682
683    SubString tokens(input.substr(opening_parenthesis, closing_parenthesis - opening_parenthesis), ",", SubString::WhiteSpaces, false, '\\', true, '"', true, '\0', '\0', true, '\0');
684    if (tokens.size() >= 3)
685    {
686        if (!ConvertValue(&(output->x), tokens[0]))
687            return false;
688        if (!ConvertValue(&(output->y), tokens[1]))
689            return false;
690        if (!ConvertValue(&(output->z), tokens[2]))
691            return false;
692
693        return true;
694    }
695    return false;
696}
697/*
698// std::string to Vector3
699template <>
700class Converter<std::string, orxonox::Vector3>
701{
702  public:
703    bool operator()(orxonox::Vector3* output, const std::string& input) const
704    {
705      unsigned int opening_parenthesis, closing_parenthesis = input.find(')');
706      if ((opening_parenthesis = input.find('(')) == std::string::npos) { opening_parenthesis = 0; } else { opening_parenthesis++; }
707
708      SubString tokens(input.substr(opening_parenthesis, closing_parenthesis - opening_parenthesis), ",", SubString::WhiteSpaces, false, '\\', true, '"', true, '\0', '\0', true, '\0');
709
710      if (tokens.size() >= 3)
711      {
712        if (!ConvertValue(&(output->x), tokens[0]))
713          return false;
714        if (!ConvertValue(&(output->y), tokens[1]))
715          return false;
716        if (!ConvertValue(&(output->z), tokens[2]))
717          return false;
718
719        return true;
720      }
721
722      return false;
723    }
724};
725*/
726// std::string to Vector4
727template <>
728static bool convert(orxonox::Vector4* output, const std::string& input, _Explicit_* type)
729{
730    unsigned int opening_parenthesis, closing_parenthesis = input.find(')');
731    if ((opening_parenthesis = input.find('(')) == std::string::npos) { opening_parenthesis = 0; } else { opening_parenthesis++; }
732
733    SubString tokens(input.substr(opening_parenthesis, closing_parenthesis - opening_parenthesis), ",", SubString::WhiteSpaces, false, '\\', true, '"', true, '\0', '\0', true, '\0');
734    if (tokens.size() >= 4)
735    {
736        if (!ConvertValue(&(output->x), tokens[0]))
737            return false;
738        if (!ConvertValue(&(output->y), tokens[1]))
739            return false;
740        if (!ConvertValue(&(output->z), tokens[2]))
741            return false;
742        if (!ConvertValue(&(output->w), tokens[3]))
743            return false;
744
745        return true;
746    }
747    return false;
748}
749/*
750// std::string to Vector4
751template <>
752class Converter<std::string, orxonox::Vector4>
753{
754  public:
755    bool operator()(orxonox::Vector4* output, const std::string& input) const
756    {
757      unsigned int opening_parenthesis, closing_parenthesis = input.find(')');
758      if ((opening_parenthesis = input.find('(')) == std::string::npos) { opening_parenthesis = 0; } else { opening_parenthesis++; }
759
760      SubString tokens(input.substr(opening_parenthesis, closing_parenthesis - opening_parenthesis), ",", SubString::WhiteSpaces, false, '\\', true, '"', true, '\0', '\0', true, '\0');
761
762      if (tokens.size() >= 4)
763      {
764        if (!ConvertValue(&(output->x), tokens[0]))
765          return false;
766        if (!ConvertValue(&(output->y), tokens[1]))
767          return false;
768        if (!ConvertValue(&(output->z), tokens[2]))
769          return false;
770        if (!ConvertValue(&(output->w), tokens[3]))
771          return false;
772
773        return true;
774      }
775
776      return false;
777    }
778};
779*/
780// std::string to Quaternion
781template <>
782static bool convert(orxonox::Quaternion* output, const std::string& input, _Explicit_* type)
783{
784    unsigned int opening_parenthesis, closing_parenthesis = input.find(')');
785    if ((opening_parenthesis = input.find('(')) == std::string::npos) { opening_parenthesis = 0; } else { opening_parenthesis++; }
786
787    SubString tokens(input.substr(opening_parenthesis, closing_parenthesis - opening_parenthesis), ",", SubString::WhiteSpaces, false, '\\', true, '"', true, '\0', '\0', true, '\0');
788    if (tokens.size() >= 4)
789    {
790        if (!ConvertValue(&(output->w), tokens[0]))
791            return false;
792        if (!ConvertValue(&(output->x), tokens[1]))
793            return false;
794        if (!ConvertValue(&(output->y), tokens[2]))
795            return false;
796        if (!ConvertValue(&(output->z), tokens[3]))
797            return false;
798
799        return true;
800    }
801    return false;
802}
803/*
804// std::string to Quaternion
805template <>
806class Converter<std::string, orxonox::Quaternion>
807{
808  public:
809    bool operator()(orxonox::Quaternion* output, const std::string& input) const
810    {
811      unsigned int opening_parenthesis, closing_parenthesis = input.find(')');
812      if ((opening_parenthesis = input.find('(')) == std::string::npos) { opening_parenthesis = 0; } else { opening_parenthesis++; }
813
814      SubString tokens(input.substr(opening_parenthesis, closing_parenthesis - opening_parenthesis), ",", SubString::WhiteSpaces, false, '\\', true, '"', true, '\0', '\0', true, '\0');
815
816      if (tokens.size() >= 4)
817      {
818        if (!ConvertValue(&(output->w), tokens[0]))
819          return false;
820        if (!ConvertValue(&(output->x), tokens[1]))
821          return false;
822        if (!ConvertValue(&(output->y), tokens[2]))
823          return false;
824        if (!ConvertValue(&(output->z), tokens[3]))
825          return false;
826
827        return true;
828      }
829
830      return false;
831    }
832};
833*/
834// std::string to ColourValue
835template <>
836static bool convert(orxonox::ColourValue* output, const std::string& input, _Explicit_* type)
837{
838    unsigned int opening_parenthesis, closing_parenthesis = input.find(')');
839    if ((opening_parenthesis = input.find('(')) == std::string::npos) { opening_parenthesis = 0; } else { opening_parenthesis++; }
840
841    SubString tokens(input.substr(opening_parenthesis, closing_parenthesis - opening_parenthesis), ",", SubString::WhiteSpaces, false, '\\', true, '"', true, '\0', '\0', true, '\0');
842    if (tokens.size() >= 4)
843    {
844        if (!ConvertValue(&(output->r), tokens[0]))
845            return false;
846        if (!ConvertValue(&(output->g), tokens[1]))
847            return false;
848        if (!ConvertValue(&(output->b), tokens[2]))
849            return false;
850        if (!ConvertValue(&(output->a), tokens[3]))
851            return false;
852
853        return true;
854    }
855    return false;
856}
857/*
858// std::string to ColourValue
859template <>
860class Converter<std::string, orxonox::ColourValue>
861{
862  public:
863    bool operator()(orxonox::ColourValue* output, const std::string& input) const
864    {
865      unsigned int opening_parenthesis, closing_parenthesis = input.find(')');
866      if ((opening_parenthesis = input.find('(')) == std::string::npos) { opening_parenthesis = 0; } else { opening_parenthesis++; }
867
868      SubString tokens(input.substr(opening_parenthesis, closing_parenthesis - opening_parenthesis), ",", SubString::WhiteSpaces, false, '\\', true, '"', true, '\0', '\0', true, '\0');
869
870      if (tokens.size() >= 4)
871      {
872        if (!ConvertValue(&(output->r), tokens[0]))
873          return false;
874        if (!ConvertValue(&(output->g), tokens[1]))
875          return false;
876        if (!ConvertValue(&(output->b), tokens[2]))
877          return false;
878        if (!ConvertValue(&(output->a), tokens[3]))
879          return false;
880
881        return true;
882      }
883
884      return false;
885    }
886};
887*/
888
889
890#endif /* _Convert_H__ */
Note: See TracBrowser for help on using the repository browser.