Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

Ignore:
Timestamp:
Sep 8, 2008, 6:33:19 PM (16 years ago)
Author:
rgrieder
Message:

Modified Convert.h to choose the right conversion function itself.
It is possible to overwrite any conversion by defining 'explicitConversion(ToType* output, const FromType input)'. That even works for fundamental types. But the declaration has to be put before Convert.h gets included. Best thing would be do declare them in the Prereqs file and define them at the actual spot.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • code/branches/core3/src/util/Convert.h

    r1723 r1743  
    3939#include <string>
    4040#include <sstream>
     41#include <istream>
     42#include <boost/static_assert.hpp>
    4143
    4244#include "Math.h"
     
    4446#include "SubString.h"
    4547
    46 // disable annoying warning about forcing value to boolean
    47 #if ORXONOX_COMPILER == ORXONOX_COMPILER_MSVC
    48 #pragma warning(push)
    49 #pragma warning(disable:4100 4800)
     48///////////////////////////////////
     49// Explicit Conversion Functions //
     50///////////////////////////////////
     51
     52inline bool explicitConversion(std::string* output, const char input)
     53{
     54    return true;
     55}
     56inline bool explicitConversion(std::string* output, const unsigned char input)
     57{
     58    return true;
     59}
     60inline bool explicitConversion(char* output, const std::string input)
     61{
     62    return true;
     63}
     64inline bool explicitConversion(unsigned char* output, const std::string input)
     65{
     66    return true;
     67}
     68
     69///////////////////////////
     70// Static type detection //
     71///////////////////////////
     72
     73/* The idea to use the sizeof() operator on return functions to determine function existance
     74   is described in 'Moder C++ design' by Alexandrescu (2001). */
     75
     76template <int a, int b>
     77struct TemplateDebugger
     78{
     79    static int debug(int c, int d) { BOOST_STATIC_ASSERT(0); }
     80};
     81
     82namespace conversionTests
     83{
     84
     85    // Two struct with very different sizes
     86    struct VerySmallStruct { char dummy[1]; };
     87    struct VeryBigStruct   { char dummy[1024]; }; // Big is surely larger than Small, even with alignments
     88}
     89
     90namespace generalFunctionTemplate
     91{
     92    // Keep this function out of conversion namespaces because the compiler gives a general
     93    // template in the same namesapace a higher priority than any specialisation.
     94    // This function simply accepts anything but has lower priority to specialisations.
     95    // It can be identified by the larger return value.
     96    template <class AnyToType, class AnyFromType>
     97    conversionTests::VeryBigStruct explicitConversion(AnyToType* output, const AnyFromType input)
     98    {
     99        // The function is exposed globally because of the "using namespace" in conversionTests.
     100        // We have to make sure noboy uses it, so a good compiler error would be nice.
     101        *output = (AnyToType)input; // Do not use this function!
     102        BOOST_STATIC_ASSERT(0); // just to be sure
     103    }
     104}
     105
     106namespace conversionTests
     107{
     108    using namespace generalFunctionTemplate; // Why in separate namespace? See above
     109
     110    template <class Any>
     111    conversionTests::VeryBigStruct operator<<(std::ostream& outstream, const Any anything);
     112    template <class Any>
     113    conversionTests::VeryBigStruct operator>>(std::istream& instream,  const Any anything);
     114
     115    template <class FromType, class ToType>
     116    class ImplicitConversion
     117    {
     118    private:
     119        static VerySmallStruct test(ToType); // only accepts ToType, but is preferred over '...'
     120        static VeryBigStruct   test(...);    // accepts anything
     121        static FromType object; // helper object to handle private c'tor and d'tor
     122    public:
     123        enum { exists = sizeof(test(object)) == sizeof(VerySmallStruct) };
     124    };
     125
     126    template <class FromType, class ToType, int asdf>
     127    class ExplicitConversion
     128    {
     129    private:
     130        static FromType objectFromType; // helper object to handle private c'tor and d'tor
     131        static ToType   objectToType;   // helper object to handle private c'tor and d'tor
     132    public:
     133        enum { exists = sizeof(explicitConversion(&objectToType, objectFromType)) == sizeof(VerySmallStruct) };
     134        static void test();
     135    };
     136
     137    template <int asdf>
     138    class ExplicitConversion<float, int, asdf>
     139    {
     140    private:
     141        static float objectFromType; // helper object to handle private c'tor and d'tor
     142        static int   objectToType;   // helper object to handle private c'tor and d'tor
     143    public:
     144        enum { exists = sizeof(explicitConversion(&objectToType, objectFromType)) == sizeof(VerySmallStruct) };
     145        static void test() { TemplateDebugger<sizeof(explicitConversion(&objectToType, objectFromType)), sizeof(VerySmallStruct)>::debug(1,2); }
     146    };
     147
     148    template <class Type>
     149    class IStringStreamOperator
     150    {
     151        static std::istringstream istream_; // helper object to perform the '>>' operation
     152        static Type object;                 // helper object to handle private c'tor and d'tor
     153    public:
     154        enum { exists = (sizeof(istream_ >> object) < sizeof(VerySmallStruct) + 512) };
     155    };
     156
     157    template <class Type>
     158    class OStringStreamOperator
     159    {
     160        static std::ostringstream ostream_; // helper object to perform the '<<' operation
     161        static Type object;                 // helper object to handle private c'tor and d'tor
     162    public:
     163        enum { exists = (sizeof(ostream_ << object) < sizeof(VerySmallStruct) + 512) };
     164    };
     165}
     166
     167// shortcut without namespace
     168template <class FromType, class ToType>
     169struct ImplicitConversion
     170{ enum { exists = conversionTests::ImplicitConversion<FromType, ToType>::exists }; };
     171
     172// shortcut without namespace
     173template <class FromType, class ToType>
     174struct ExplicitConversion
     175{ enum { exists = conversionTests::ExplicitConversion<FromType, ToType, 4>::exists }; };
     176
     177// shortcut without namespace
     178template <class Type>
     179struct IStringStreamOperator
     180{ enum { exists = conversionTests::IStringStreamOperator<Type>::exists }; };
     181
     182// shortcut without namespace
     183template <class Type>
     184struct OStringStreamOperator
     185{ enum { exists = conversionTests::OStringStreamOperator<Type>::exists }; };
     186
     187
     188///////////////////////////////
     189// Conversion Template Stuff //
     190///////////////////////////////
     191
     192namespace conversion
     193{
     194    // Maps bools to types in order to use function overloading instead of template specialisation (Alexandrescu 2001)
     195    template <bool WhetherOrNot>
     196    struct ImplicitPossible { };
     197    template <bool WhetherOrNot>
     198    struct ExplicitPossible { };
     199    template <bool WhetherOrNot>
     200    struct StringStreamPossible { };
     201
     202    // No Conversion possible, default template
     203    template <class ToType, class FromType, int Dummy>
     204    struct Converter
     205    {
     206        static bool convert(ToType* output, FromType input)
     207        {
     208            // Do not allow impossible conversions
     209            //(*output) = input; // this WILL trigger a compiler error
     210            //BOOST_STATIC_ASSERT(sizeof(ToType) == 0); // just to be sure..
     211            return false;
     212        }
     213    };
     214
     215
     216    ///////////////////////
     217    //Explicit Conversion//
     218    ///////////////////////
     219
     220    // We can cast explicitely, this overwrites any other possible cast
     221    template <class ToType, class FromType>
     222    inline bool convert(ToType* output, const FromType& input, ExplicitPossible<true>)
     223    {
     224        // This function can by anywhere globally!
     225        //int a = TemplateDebugger<1,2>::debug(1,1);
     226        //conversionTests::ExplicitConversion<FromType, ToType, 4>::test();
     227        //BOOST_STATIC_ASSERT(0);
     228        return explicitConversion(output, input);
     229    }
     230
     231    // No explict cast, try implicit
     232    template <class ToType, class FromType>
     233    inline bool convert(ToType* output, const FromType& input, ExplicitPossible<false>)
     234    {
     235        return convert(output, input, ImplicitPossible<ImplicitConversion<FromType, ToType>::exists>());
     236    }
     237
     238
     239    /////////////////
     240    //Implicit Cast//
     241    /////////////////
     242
     243    // We can cast implicitely
     244    template <class ToType, class FromType>
     245    inline bool convert(ToType* output, const FromType& input, ImplicitPossible<true>)
     246    {
     247        (*output) = static_cast<ToType>(input);
     248        return true;
     249    }
     250
     251    // No implicit cast, leave it up to << and >>
     252    template <class ToType, class FromType>
     253    inline bool convert(ToType* output, const FromType& input, ImplicitPossible<false>)
     254    {
     255        return Converter<ToType, FromType, 0>::convert(output, input);
     256    }
     257
     258
     259    /////////////////
     260    //OStringStream//
     261    /////////////////
     262
     263    // Conversion via ostringstream
     264    template <class FromType>
     265    bool convertOStringStream(std::string* output, const FromType& input)
     266    {
     267        std::ostringstream oss;
     268        if (oss << input)
     269        {
     270            (*output) = oss.str();
     271            return true;
     272        }
     273        else
     274            return false;
     275    }
     276
     277    // template that evaluates whether OStringStream is possible
     278    template <class FromType, int Dummy>
     279    struct Converter<std::string, FromType, Dummy>
     280    {
     281        // convert to std::string, probe for '<<' stringstream operator
     282        static bool convert(std::string* output, const FromType& input)
     283        {
     284            return convert(output, input, StringStreamPossible<OStringStreamOperator<FromType>::exists>());
     285            //conversion::OStringStreamOperator<FromType>::test();
     286        }
     287
     288        // Conversion with ostringstream possible
     289        static bool convert(std::string* output, const FromType& input, StringStreamPossible<true>)
     290        {
     291            return convertOStringStream(output, input);
     292        }
     293
     294        // Conversion with ostringstream not possible
     295        static bool convert(std::string* output, const FromType& input, StringStreamPossible<false>)
     296        {
     297            // Do not allow impossible conversions
     298            //(*output) = input; // this WILL trigger a compiler error
     299            //BOOST_STATIC_ASSERT(sizeof(ToType) == 0); // just to be sure..
     300            return false;
     301        }
     302    };
     303
     304
     305    /////////////////
     306    //IStringStream//
     307    /////////////////
     308
     309    // conversion from std::string via istringstream
     310    template <class ToType>
     311    bool convertIStringStream(ToType* output, const std::string& input)
     312    {
     313        std::istringstream iss(input);
     314        if (iss >> (*output))
     315        {
     316            return true;
     317        }
     318        else
     319            return false;
     320    }
     321
     322    // template that evaluates whether IStringStream is possible
     323    template <class ToType, int Dummy>
     324    struct Converter<ToType, std::string, Dummy>
     325    {
     326        // convert from std::string, probe for '>>' stringstream operator
     327        static bool convert(ToType* output, const std::string& input)
     328        {
     329            return convert(output, input, StringStreamPossible<IStringStreamOperator<ToType>::exists>());
     330        }
     331
     332        // Conversion with istringstream possible
     333        static bool convert(ToType* output, const std::string& input, StringStreamPossible<true>)
     334        {
     335            return convertIStringStream(output, input);
     336        }
     337
     338        // Conversion with istringstream not possible
     339        static bool convert(ToType* output, const std::string& input, StringStreamPossible<false>)
     340        {
     341            // Do not allow impossible conversions
     342            //(*output) = input; // this WILL trigger a compiler error
     343            //BOOST_STATIC_ASSERT(sizeof(ToType) == 0); // just to be sure..
     344            return false;
     345        }
     346    };
     347
     348
     349    /////////////////
     350    //Special Cases//
     351    /////////////////
     352
     353    // delegate conversion from const char* via string
     354    template <class ToType, int Dummy>
     355    struct Converter<ToType, const char*, Dummy>
     356    {
     357        // convert from const char* via std::string
     358        static bool convert(ToType* output, const char* input)
     359        { return Converter<ToType, std::string>::convert(output, input); }
     360    };
     361#if 0
     362    // conversion char to std::string leads to ambiguous operator <<
     363    template <int Dummy>
     364    struct Converter<std::string, char, Dummy>
     365    {
     366        static bool convert(std::string* output, const char input)
     367        { return convertOStringStream(output, input); }
     368    };
     369
     370    // conversion unsigned char to std::string leads to ambiguous operator <<
     371    template <int Dummy>
     372    struct Converter<std::string, unsigned char, Dummy>
     373    {
     374        static bool convert(std::string* output, const char input)
     375        { return convertOStringStream(output, input); }
     376    };
     377
     378    // conversion std::string to char leads to ambiguous operator >>
     379    template <int Dummy>
     380    struct Converter<char, std::string, Dummy>
     381    {
     382        static bool convert(char* output, const std::string input)
     383        { return convertIStringStream(output, input); }
     384    };
     385
     386    // conversion std::string to unsigned char leads to ambiguous operator >>
     387    template <int Dummy>
     388    struct Converter<unsigned char, std::string, Dummy>
     389    {
     390        static bool convert(unsigned char* output, const std::string input)
     391        { return convertIStringStream(output, input); }
     392    };
    50393#endif
    51 
    52 
    53 //////////
    54 // MAIN //
    55 //////////
    56 
    57 // Enum to declare the wanted conversion preference in case of equal type-levels
    58 enum ConversionPreference
    59 {
    60     CP_PreferToType,
    61     CP_PreferFromType,
    62 };
    63 
    64 // Helper classes to determine the preferred partial template specialization
    65 class _ToType_   {};
    66 class _FromType_ {};
    67 class _Explicit_ {};
    68 
    69 
    70 // The default convert functions
    71 template <class FromType, class ToType, class Type>
    72 struct ConverterSpecialized
    73 {
    74     enum { specialized = false };
    75     static bool convert(ToType* output, const FromType& input)
    76     {
    77         COUT(2) << "Warning: Couldn't convert a value." << std::endl;
    78         return false;
    79     }
    80 };
    81 
    82 
    83 // The default convert function if both types are the same
    84 template <class BothTypes>
    85 struct ConverterSpecialized<BothTypes, BothTypes, _Explicit_>
    86 {
    87     enum { specialized = true };
    88     static bool convert(BothTypes* output, const BothTypes& input)
    89     { (*output) = input; return true; }
    90 };
    91 
    92 
    93 // The possible levels
    94 #define __low__  0 // Everything that is or behaves like a primitive type (an can be converted with a typecast to every other low-level type)
    95 #define __mid__  1 // Everything that has overloaded << and >> operators to operate on a std::stream
    96 #define __high__ 2 // Everything that doesn't fullfill the lowerlevel-requirements and therefore needs specialized conversions
    97 
    98 // Defines the levels of all types: Default is __high__ so you don't have to define every high-level type
    99 template <class T> struct ConverterLevel              { enum { level = __high__ }; };
    100 template <> struct ConverterLevel<std::string>        { enum { level = __mid__ }; };
    101 template <> struct ConverterLevel<orxonox::Radian>    { enum { level = __mid__ }; };
    102 template <> struct ConverterLevel<orxonox::Degree>    { enum { level = __mid__ }; };
    103 template <> struct ConverterLevel<int>                { enum { level = __low__ }; };
    104 template <> struct ConverterLevel<unsigned int>       { enum { level = __low__ }; };
    105 template <> struct ConverterLevel<char>               { enum { level = __low__ }; };
    106 template <> struct ConverterLevel<unsigned char>      { enum { level = __low__ }; };
    107 template <> struct ConverterLevel<short>              { enum { level = __low__ }; };
    108 template <> struct ConverterLevel<unsigned short>     { enum { level = __low__ }; };
    109 template <> struct ConverterLevel<long>               { enum { level = __low__ }; };
    110 template <> struct ConverterLevel<unsigned long>      { enum { level = __low__ }; };
    111 template <> struct ConverterLevel<long long>          { enum { level = __low__ }; };
    112 template <> struct ConverterLevel<unsigned long long> { enum { level = __low__ }; };
    113 template <> struct ConverterLevel<float>              { enum { level = __low__ }; };
    114 template <> struct ConverterLevel<double>             { enum { level = __low__ }; };
    115 template <> struct ConverterLevel<long double>        { enum { level = __low__ }; };
    116 template <> struct ConverterLevel<bool>               { enum { level = __low__ }; };
    117 
    118 
    119 // Calculates the preference based on the levels of FromType and ToType
    120 template <int from, int to>
    121 struct ConverterPreference
    122 {
    123     enum
    124     {
    125         // The maximum of both levels: element of {0, 1, 2}
    126         // max 0: Both types are primitives or have a similar behaviour
    127         // max 1: At least one type is not a primitive, but both can be put on a std::stream
    128         // max 2: There is at least one generic type that needs specialized conversions
    129         max = (from > to) ? from : to,
    130 
    131         // The difference between both levels limited to +-1: element of {-1, 0, 1}
    132         // diff -1: The FromType has higher level than the ToType
    133         // diff  0: Both types have the same level
    134         // diff  1: The ToType has higher level than the FromType
    135         diff = ((to - from) > 1) ? 1 : (((to - from) < -1) ? -1 : to - from)
    136     };
    137 };
    138 
    139 
    140 // The default conversion: This usually does nothing
    141 template <int max, class FromType, class ToType>
    142 struct ConverterDefault
    143 {
    144     static bool convert(ToType* output, const FromType& input)
    145     {
    146         COUT(2) << "Warning: Couldn't convert a value." << std::endl;
    147         return false;
    148     }
    149 };
    150 // 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>
    151 template <class FromType, class ToType>
    152 struct ConverterDefault<0, FromType, ToType>
    153 {
    154     static bool convert(ToType* output, const FromType& input)
    155     {
    156         (*output) = (ToType)input;
    157         return true;
    158     }
    159 };
    160 
    161 
    162 // Converter: Converts input of FromType into output of ToType
    163 template <int diff, int max, class FromType, class ToType, ConversionPreference pref>
    164 struct Converter
    165 {
    166     static bool convert(ToType* output, const FromType& input)
    167     {
    168         return false;
    169     }
    170 };
    171 // Converter: level{FromType} > level{ToType}
    172 template <int max, class FromType, class ToType, ConversionPreference pref>
    173 struct Converter<-1, max, FromType, ToType, pref>
    174 {   static bool convert(ToType* output, const FromType& input)
    175     { return (ConverterSpecialized<FromType, ToType, _Explicit_>::specialized) ? (ConverterSpecialized<FromType, ToType, _Explicit_>::convert(output, input)) : (ConverterSpecialized<FromType, ToType, _FromType_>::specialized) ? (ConverterSpecialized<FromType, ToType, _FromType_>::convert(output, input)) : (ConverterDefault<max, FromType, ToType>::convert(output, input)); } };
    176 // Converter: level{FromType} < level{ToType}
    177 template <int max, class FromType, class ToType, ConversionPreference pref>
    178 struct Converter<1, max, FromType, ToType, pref>
    179 {   static bool convert(ToType* output, const FromType& input)
    180     { return (ConverterSpecialized<FromType, ToType, _Explicit_>::specialized) ? (ConverterSpecialized<FromType, ToType, _Explicit_>::convert(output, input)) : (ConverterSpecialized<FromType, ToType, _ToType_>::specialized) ? (ConverterSpecialized<FromType, ToType, _ToType_>::convert(output, input)) : (ConverterDefault<max, FromType, ToType>::convert(output, input)); } };
    181 // Converter: level{FromType} = level{ToType}
    182 // CP_PreferToType
    183 template <int max, class FromType, class ToType>
    184 struct Converter<0, max, FromType, ToType, CP_PreferToType>
    185 {   static bool convert(ToType* output, const FromType& input)
    186     { return (ConverterSpecialized<FromType, ToType, _Explicit_>::specialized) ? (ConverterSpecialized<FromType, ToType, _Explicit_>::convert(output, input)) : (ConverterSpecialized<FromType, ToType, _ToType_>::specialized) ? (ConverterSpecialized<FromType, ToType, _ToType_>::convert(output, input)) : (ConverterSpecialized<FromType, ToType, _FromType_>::specialized) ? (ConverterSpecialized<FromType, ToType, _FromType_>::convert(output, input)) : (ConverterDefault<max, FromType, ToType>::convert(output, input)); } };
    187 // CP_PreferFromType
    188 template <int max, class FromType, class ToType>
    189 struct Converter<0, max, FromType, ToType, CP_PreferFromType>
    190 {   static bool convert(ToType* output, const FromType& input)
    191     { return (ConverterSpecialized<FromType, ToType, _Explicit_>::specialized) ? (ConverterSpecialized<FromType, ToType, _Explicit_>::convert(output, input)) : (ConverterSpecialized<FromType, ToType, _FromType_>::specialized) ? (ConverterSpecialized<FromType, ToType, _FromType_>::convert(output, input)) : (ConverterSpecialized<FromType, ToType, _ToType_>::specialized) ? (ConverterSpecialized<FromType, ToType, _ToType_>::convert(output, input)) : (ConverterDefault<max, FromType, ToType>::convert(output, input)); } };
    192 
    193 
    194 // Calls the Converter::convertValue function with the correct template type parameters calculated by ConverterPreference
    195 template <class FromType, class ToType>
    196 static bool convertValue(ToType* output, const FromType& input, ConversionPreference preference = CP_PreferToType)
    197 {
    198     return (preference == CP_PreferToType) ?
    199            Converter<ConverterPreference<ConverterLevel<FromType>::level, ConverterLevel<ToType>::level>::diff,
    200                      ConverterPreference<ConverterLevel<FromType>::level, ConverterLevel<ToType>::level>::max,
    201                      FromType,
    202                      ToType,
    203                      CP_PreferToType>::convert(output, input)
    204          : Converter<ConverterPreference<ConverterLevel<FromType>::level, ConverterLevel<ToType>::level>::diff,
    205                      ConverterPreference<ConverterLevel<FromType>::level, ConverterLevel<ToType>::level>::max,
    206                      FromType,
    207                      ToType,
    208                      CP_PreferFromType>::convert(output, input);
    209 }
    210 
    211 
    212 //////////////////////
    213 // HELPER FUNCTIONS //
    214 //////////////////////
     394}
     395
     396
     397////////////////////
     398//Public Functions//
     399////////////////////
     400
     401/**
     402@brief
     403    Converts any value to any other as long as there exits a conversion.
     404    Otherwise, the conversion will generate a runtime warning.
     405*/
     406template <class ToType, class FromType>
     407inline bool convertValue(ToType* output, const FromType& input)
     408{
     409    // check whether we can convert one type to the other explicitely.
     410    //conversionTests::ExplicitConversion<FromType, ToType, 4>::test();
     411    return conversion::convert(output, input,
     412        conversion::ExplicitPossible<ExplicitConversion<FromType, ToType>::exists>());
     413}
    215414
    216415// Helper function: Calls convertValue with and without default value and returns true if the conversion was successful
    217416template<class FromType, class ToType>
    218 static bool ConvertValue(ToType* output, const FromType& input, ConversionPreference preference = CP_PreferToType)
    219 {
    220     return convertValue(output, input, preference);
     417static bool ConvertValue(ToType* output, const FromType& input)
     418{
     419    return convertValue(output, input);
    221420}
    222421template<class FromType, class ToType>
    223 static bool ConvertValue(ToType* output, const FromType& input, const ToType& fallback, ConversionPreference preference = CP_PreferToType)
    224 {
    225     if (convertValue(output, input, preference))
     422static bool ConvertValue(ToType* output, const FromType& input, const ToType& fallback)
     423{
     424    if (convertValue(output, input))
    226425        return true;
    227426
     
    232431// Helper function: Calls convertValue with and without default value and returns the converted value
    233432template<class FromType, class ToType>
    234 static ToType getConvertedValue(const FromType& input, ConversionPreference preference = CP_PreferToType)
     433static ToType getConvertedValue(const FromType& input)
    235434{
    236435    ToType output = ToType();
    237     ConvertValue(&output, input, preference);
     436    ConvertValue(&output, input);
    238437    return output;
    239438}
    240439template<class FromType, class ToType>
    241 static ToType getConvertedValue(const FromType& input, const ToType& fallback, ConversionPreference preference = CP_PreferToType)
     440static ToType getConvertedValue(const FromType& input, const ToType& fallback)
    242441{
    243442    ToType output = fallback;
    244     ConvertValue(&output, input, fallback, preference);
     443    ConvertValue(&output, input, fallback);
    245444    return output;
    246445}
     
    283482*/
    284483
    285 ////////////
    286 // STRING //
    287 ////////////
    288 
    289 // convert to string
    290 template <class FromType>
    291 struct ConverterSpecialized<FromType, std::string, _ToType_>
    292 {
    293     enum { specialized = true };
    294     static bool convert(std::string* output, const FromType& input)
    295     {
    296         std::ostringstream oss;
    297         if (oss << input)
    298         {
    299             (*output) = oss.str();
    300             return true;
    301         }
    302         else
    303             return false;
    304     }
    305 };
    306 
    307 // convert from string
    308 template <class ToType>
    309 struct ConverterSpecialized<std::string, ToType, _FromType_>
    310 {
    311     enum { specialized = true };
    312     static bool convert(ToType* output, const std::string& input)
    313     {
    314         std::istringstream iss(input);
    315         if (iss >> (*output))
    316             return true;
    317         else
    318             return false;
    319     }
    320 };
    321 
     484
     485/////////////////
     486// CONST CHAR* //
     487/////////////////
     488/*
     489// convert from const char* --> use conversions with std::string
     490template <class ToType, class Type>
     491struct ConverterSpecialized<const char*, ToType, Type>
     492{
     493    enum { specialized = true };
     494    static bool convert(ToType* output, const char* input)
     495    {
     496        return ConverterSpecialized<std::string, ToType, Type>::convert(output, input);
     497    }
     498};
     499
     500// convert from const char* --> use conversions with std::string
     501template <>
     502struct ConverterSpecialized<const char*, std::string, _ToType_>
     503{
     504    enum { specialized = true };
     505    static bool convert(std::string* output, const char* input)
     506    {
     507        *output = input;
     508        return true;
     509    }
     510};
     511
     512// convert from const char* _Explicit_ --> use conversions with std::string
     513//template <class ToType>
     514//struct ConverterSpecialized<const char*, ToType, _Explicit_>
     515//{
     516//    enum { specialized = true };
     517//    static bool convert(ToType* output, const char* input)
     518//    {
     519//        return ConverterSpecialized<std::string, ToType, _Explicit_>::convert(output, input);
     520//    }
     521//};
     522
     523// convert from char* without const is not allowed
     524//template <class ToType, class Type>
     525//struct ConverterSpecialized<char*, ToType, Type>
     526//{
     527//    enum { specialized = true };
     528//    static bool convert(ToType* output, const char* input)
     529//    {
     530//        BOOST_STATIC_ASSERT(sizeof(ToType) == 0);
     531//    }
     532//};
     533
     534// No support for char* without const
     535//template <class ToType, class Type>
     536//struct ConverterSpecialized<char*, ToType, Type>
     537//{
     538//    enum { specialized = true };
     539//    static bool convert(ToType* output, const char* input)
     540//    {
     541//        BOOST_STATIC_ASSERT(sizeof(ToType) == 0);
     542//    }
     543//};
     544
     545// convert to const char* is not supported (possible memory leak)
     546template <class FromType, class Type>
     547struct ConverterSpecialized<FromType, const char*, Type>
     548{
     549    enum { specialized = true };
     550    static bool convert(const char** output, const FromType& input)
     551    {
     552        BOOST_STATIC_ASSERT(sizeof(FromType) == 0);
     553    }
     554};
     555
     556// convert to char* is not supported (possible memory leak)
     557// Note: It actually does need both specializations for const char* and char*
     558//template <class FromType, class Type>
     559//struct ConverterSpecialized<FromType, char*, Type>
     560//{
     561//    enum { specialized = true };
     562//    static bool convert(char** output, const FromType& input)
     563//    {
     564//        BOOST_STATIC_ASSERT(sizeof(FromType) == 0);
     565//    }
     566//};
    322567
    323568
     
    549794    }
    550795};
    551 
    552 #if ORXONOX_COMPILER == ORXONOX_COMPILER_MSVC
    553 #pragma warning(pop)
    554 #endif
    555 
     796*/
    556797#endif /* _Convert_H__ */
Note: See TracChangeset for help on using the changeset viewer.