Index: code/branches/core3/src/util/Convert.h
===================================================================
--- code/branches/core3/src/util/Convert.h	(revision 1742)
+++ code/branches/core3/src/util/Convert.h	(revision 1743)
@@ -39,4 +39,6 @@
 #include <string>
 #include <sstream>
+#include <istream>
+#include <boost/static_assert.hpp>
 
 #include "Math.h"
@@ -44,184 +46,381 @@
 #include "SubString.h"
 
-// disable annoying warning about forcing value to boolean
-#if ORXONOX_COMPILER == ORXONOX_COMPILER_MSVC
-#pragma warning(push)
-#pragma warning(disable:4100 4800)
+///////////////////////////////////
+// Explicit Conversion Functions //
+///////////////////////////////////
+
+inline bool explicitConversion(std::string* output, const char input)
+{
+    return true;
+}
+inline bool explicitConversion(std::string* output, const unsigned char input)
+{
+    return true;
+}
+inline bool explicitConversion(char* output, const std::string input)
+{
+    return true;
+}
+inline bool explicitConversion(unsigned char* output, const std::string input)
+{
+    return true;
+}
+
+///////////////////////////
+// Static type detection //
+///////////////////////////
+
+/* The idea to use the sizeof() operator on return functions to determine function existance
+   is described in 'Moder C++ design' by Alexandrescu (2001). */
+
+template <int a, int b>
+struct TemplateDebugger
+{
+    static int debug(int c, int d) { BOOST_STATIC_ASSERT(0); }
+};
+
+namespace conversionTests
+{
+
+    // Two struct with very different sizes
+    struct VerySmallStruct { char dummy[1]; };
+    struct VeryBigStruct   { char dummy[1024]; }; // Big is surely larger than Small, even with alignments
+}
+
+namespace generalFunctionTemplate
+{
+    // Keep this function out of conversion namespaces because the compiler gives a general
+    // template in the same namesapace a higher priority than any specialisation.
+    // This function simply accepts anything but has lower priority to specialisations.
+    // It can be identified by the larger return value.
+    template <class AnyToType, class AnyFromType>
+    conversionTests::VeryBigStruct explicitConversion(AnyToType* output, const AnyFromType input)
+    {
+        // The function is exposed globally because of the "using namespace" in conversionTests.
+        // We have to make sure noboy uses it, so a good compiler error would be nice.
+        *output = (AnyToType)input; // Do not use this function!
+        BOOST_STATIC_ASSERT(0); // just to be sure
+    }
+}
+
+namespace conversionTests
+{
+    using namespace generalFunctionTemplate; // Why in separate namespace? See above
+
+    template <class Any>
+    conversionTests::VeryBigStruct operator<<(std::ostream& outstream, const Any anything);
+    template <class Any>
+    conversionTests::VeryBigStruct operator>>(std::istream& instream,  const Any anything);
+
+    template <class FromType, class ToType>
+    class ImplicitConversion
+    {
+    private:
+        static VerySmallStruct test(ToType); // only accepts ToType, but is preferred over '...'
+        static VeryBigStruct   test(...);    // accepts anything
+        static FromType object; // helper object to handle private c'tor and d'tor
+    public:
+        enum { exists = sizeof(test(object)) == sizeof(VerySmallStruct) };
+    };
+
+    template <class FromType, class ToType, int asdf>
+    class ExplicitConversion
+    {
+    private:
+        static FromType objectFromType; // helper object to handle private c'tor and d'tor
+        static ToType   objectToType;   // helper object to handle private c'tor and d'tor
+    public:
+        enum { exists = sizeof(explicitConversion(&objectToType, objectFromType)) == sizeof(VerySmallStruct) };
+        static void test();
+    };
+
+    template <int asdf>
+    class ExplicitConversion<float, int, asdf>
+    {
+    private:
+        static float objectFromType; // helper object to handle private c'tor and d'tor
+        static int   objectToType;   // helper object to handle private c'tor and d'tor
+    public:
+        enum { exists = sizeof(explicitConversion(&objectToType, objectFromType)) == sizeof(VerySmallStruct) };
+        static void test() { TemplateDebugger<sizeof(explicitConversion(&objectToType, objectFromType)), sizeof(VerySmallStruct)>::debug(1,2); }
+    };
+
+    template <class Type>
+    class IStringStreamOperator
+    {
+        static std::istringstream istream_; // helper object to perform the '>>' operation
+        static Type object;                 // helper object to handle private c'tor and d'tor
+    public:
+        enum { exists = (sizeof(istream_ >> object) < sizeof(VerySmallStruct) + 512) };
+    };
+
+    template <class Type>
+    class OStringStreamOperator
+    {
+        static std::ostringstream ostream_; // helper object to perform the '<<' operation
+        static Type object;                 // helper object to handle private c'tor and d'tor
+    public:
+        enum { exists = (sizeof(ostream_ << object) < sizeof(VerySmallStruct) + 512) };
+    };
+}
+
+// shortcut without namespace
+template <class FromType, class ToType>
+struct ImplicitConversion
+{ enum { exists = conversionTests::ImplicitConversion<FromType, ToType>::exists }; };
+
+// shortcut without namespace
+template <class FromType, class ToType>
+struct ExplicitConversion
+{ enum { exists = conversionTests::ExplicitConversion<FromType, ToType, 4>::exists }; };
+
+// shortcut without namespace
+template <class Type>
+struct IStringStreamOperator
+{ enum { exists = conversionTests::IStringStreamOperator<Type>::exists }; };
+
+// shortcut without namespace
+template <class Type>
+struct OStringStreamOperator
+{ enum { exists = conversionTests::OStringStreamOperator<Type>::exists }; };
+
+
+///////////////////////////////
+// Conversion Template Stuff //
+///////////////////////////////
+
+namespace conversion
+{
+    // Maps bools to types in order to use function overloading instead of template specialisation (Alexandrescu 2001)
+    template <bool WhetherOrNot>
+    struct ImplicitPossible { };
+    template <bool WhetherOrNot>
+    struct ExplicitPossible { };
+    template <bool WhetherOrNot>
+    struct StringStreamPossible { };
+
+    // No Conversion possible, default template
+    template <class ToType, class FromType, int Dummy>
+    struct Converter
+    {
+        static bool convert(ToType* output, FromType input)
+        {
+            // Do not allow impossible conversions
+            //(*output) = input; // this WILL trigger a compiler error
+            //BOOST_STATIC_ASSERT(sizeof(ToType) == 0); // just to be sure..
+            return false;
+        }
+    };
+
+
+    ///////////////////////
+    //Explicit Conversion//
+    ///////////////////////
+
+    // We can cast explicitely, this overwrites any other possible cast
+    template <class ToType, class FromType>
+    inline bool convert(ToType* output, const FromType& input, ExplicitPossible<true>)
+    {
+        // This function can by anywhere globally!
+        //int a = TemplateDebugger<1,2>::debug(1,1);
+        //conversionTests::ExplicitConversion<FromType, ToType, 4>::test();
+        //BOOST_STATIC_ASSERT(0);
+        return explicitConversion(output, input);
+    }
+
+    // No explict cast, try implicit
+    template <class ToType, class FromType>
+    inline bool convert(ToType* output, const FromType& input, ExplicitPossible<false>)
+    {
+        return convert(output, input, ImplicitPossible<ImplicitConversion<FromType, ToType>::exists>());
+    }
+
+
+    /////////////////
+    //Implicit Cast//
+    /////////////////
+
+    // We can cast implicitely
+    template <class ToType, class FromType>
+    inline bool convert(ToType* output, const FromType& input, ImplicitPossible<true>)
+    {
+        (*output) = static_cast<ToType>(input);
+        return true;
+    }
+
+    // No implicit cast, leave it up to << and >>
+    template <class ToType, class FromType>
+    inline bool convert(ToType* output, const FromType& input, ImplicitPossible<false>)
+    {
+        return Converter<ToType, FromType, 0>::convert(output, input);
+    }
+
+
+    /////////////////
+    //OStringStream//
+    /////////////////
+
+    // Conversion via ostringstream
+    template <class FromType>
+    bool convertOStringStream(std::string* output, const FromType& input)
+    {
+        std::ostringstream oss;
+        if (oss << input)
+        {
+            (*output) = oss.str();
+            return true;
+        }
+        else
+            return false;
+    }
+
+    // template that evaluates whether OStringStream is possible
+    template <class FromType, int Dummy>
+    struct Converter<std::string, FromType, Dummy>
+    {
+        // convert to std::string, probe for '<<' stringstream operator
+        static bool convert(std::string* output, const FromType& input)
+        {
+            return convert(output, input, StringStreamPossible<OStringStreamOperator<FromType>::exists>());
+            //conversion::OStringStreamOperator<FromType>::test();
+        }
+
+        // Conversion with ostringstream possible
+        static bool convert(std::string* output, const FromType& input, StringStreamPossible<true>)
+        {
+            return convertOStringStream(output, input);
+        }
+
+        // Conversion with ostringstream not possible
+        static bool convert(std::string* output, const FromType& input, StringStreamPossible<false>)
+        {
+            // Do not allow impossible conversions
+            //(*output) = input; // this WILL trigger a compiler error
+            //BOOST_STATIC_ASSERT(sizeof(ToType) == 0); // just to be sure..
+            return false;
+        }
+    };
+
+
+    /////////////////
+    //IStringStream//
+    /////////////////
+
+    // conversion from std::string via istringstream
+    template <class ToType>
+    bool convertIStringStream(ToType* output, const std::string& input)
+    {
+        std::istringstream iss(input);
+        if (iss >> (*output))
+        {
+            return true;
+        }
+        else
+            return false;
+    }
+
+    // template that evaluates whether IStringStream is possible
+    template <class ToType, int Dummy>
+    struct Converter<ToType, std::string, Dummy>
+    {
+        // convert from std::string, probe for '>>' stringstream operator
+        static bool convert(ToType* output, const std::string& input)
+        {
+            return convert(output, input, StringStreamPossible<IStringStreamOperator<ToType>::exists>());
+        }
+
+        // Conversion with istringstream possible
+        static bool convert(ToType* output, const std::string& input, StringStreamPossible<true>)
+        {
+            return convertIStringStream(output, input);
+        }
+
+        // Conversion with istringstream not possible
+        static bool convert(ToType* output, const std::string& input, StringStreamPossible<false>)
+        {
+            // Do not allow impossible conversions
+            //(*output) = input; // this WILL trigger a compiler error
+            //BOOST_STATIC_ASSERT(sizeof(ToType) == 0); // just to be sure..
+            return false;
+        }
+    };
+
+
+    /////////////////
+    //Special Cases//
+    /////////////////
+
+    // delegate conversion from const char* via string
+    template <class ToType, int Dummy>
+    struct Converter<ToType, const char*, Dummy>
+    {
+        // convert from const char* via std::string
+        static bool convert(ToType* output, const char* input)
+        { return Converter<ToType, std::string>::convert(output, input); }
+    };
+#if 0
+    // conversion char to std::string leads to ambiguous operator <<
+    template <int Dummy>
+    struct Converter<std::string, char, Dummy>
+    {
+        static bool convert(std::string* output, const char input)
+        { return convertOStringStream(output, input); }
+    };
+
+    // conversion unsigned char to std::string leads to ambiguous operator <<
+    template <int Dummy>
+    struct Converter<std::string, unsigned char, Dummy>
+    {
+        static bool convert(std::string* output, const char input)
+        { return convertOStringStream(output, input); }
+    };
+
+    // conversion std::string to char leads to ambiguous operator >>
+    template <int Dummy>
+    struct Converter<char, std::string, Dummy>
+    {
+        static bool convert(char* output, const std::string input)
+        { return convertIStringStream(output, input); }
+    };
+
+    // conversion std::string to unsigned char leads to ambiguous operator >>
+    template <int Dummy>
+    struct Converter<unsigned char, std::string, Dummy>
+    {
+        static bool convert(unsigned char* output, const std::string input)
+        { return convertIStringStream(output, input); }
+    };
 #endif
-
-
-//////////
-// MAIN //
-//////////
-
-// Enum to declare the wanted conversion preference in case of equal type-levels
-enum ConversionPreference
-{
-    CP_PreferToType,
-    CP_PreferFromType,
-};
-
-// Helper classes to determine the preferred partial template specialization
-class _ToType_   {};
-class _FromType_ {};
-class _Explicit_ {};
-
-
-// The default convert functions
-template <class FromType, class ToType, class Type>
-struct ConverterSpecialized
-{
-    enum { specialized = false };
-    static bool convert(ToType* output, const FromType& input)
-    {
-        COUT(2) << "Warning: Couldn't convert a value." << std::endl;
-        return false;
-    }
-};
-
-
-// The default convert function if both types are the same
-template <class BothTypes>
-struct ConverterSpecialized<BothTypes, BothTypes, _Explicit_>
-{
-    enum { specialized = true };
-    static bool convert(BothTypes* output, const BothTypes& input)
-    { (*output) = input; return true; }
-};
-
-
-// The possible levels
-#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)
-#define __mid__  1 // Everything that has overloaded << and >> operators to operate on a std::stream
-#define __high__ 2 // Everything that doesn't fullfill the lowerlevel-requirements and therefore needs specialized conversions
-
-// Defines the levels of all types: Default is __high__ so you don't have to define every high-level type
-template <class T> struct ConverterLevel              { enum { level = __high__ }; };
-template <> struct ConverterLevel<std::string>        { enum { level = __mid__ }; };
-template <> struct ConverterLevel<orxonox::Radian>    { enum { level = __mid__ }; };
-template <> struct ConverterLevel<orxonox::Degree>    { enum { level = __mid__ }; };
-template <> struct ConverterLevel<int>                { enum { level = __low__ }; };
-template <> struct ConverterLevel<unsigned int>       { enum { level = __low__ }; };
-template <> struct ConverterLevel<char>               { enum { level = __low__ }; };
-template <> struct ConverterLevel<unsigned char>      { enum { level = __low__ }; };
-template <> struct ConverterLevel<short>              { enum { level = __low__ }; };
-template <> struct ConverterLevel<unsigned short>     { enum { level = __low__ }; };
-template <> struct ConverterLevel<long>               { enum { level = __low__ }; };
-template <> struct ConverterLevel<unsigned long>      { enum { level = __low__ }; };
-template <> struct ConverterLevel<long long>          { enum { level = __low__ }; };
-template <> struct ConverterLevel<unsigned long long> { enum { level = __low__ }; };
-template <> struct ConverterLevel<float>              { enum { level = __low__ }; };
-template <> struct ConverterLevel<double>             { enum { level = __low__ }; };
-template <> struct ConverterLevel<long double>        { enum { level = __low__ }; };
-template <> struct ConverterLevel<bool>               { enum { level = __low__ }; };
-
-
-// Calculates the preference based on the levels of FromType and ToType
-template <int from, int to>
-struct ConverterPreference
-{
-    enum
-    {
-        // The maximum of both levels: element of {0, 1, 2}
-        // max 0: Both types are primitives or have a similar behaviour
-        // max 1: At least one type is not a primitive, but both can be put on a std::stream
-        // max 2: There is at least one generic type that needs specialized conversions
-        max = (from > to) ? from : to,
-
-        // The difference between both levels limited to +-1: element of {-1, 0, 1}
-        // diff -1: The FromType has higher level than the ToType
-        // diff  0: Both types have the same level
-        // diff  1: The ToType has higher level than the FromType
-        diff = ((to - from) > 1) ? 1 : (((to - from) < -1) ? -1 : to - from)
-    };
-};
-
-
-// The default conversion: This usually does nothing
-template <int max, class FromType, class ToType>
-struct ConverterDefault
-{
-    static bool convert(ToType* output, const FromType& input)
-    {
-        COUT(2) << "Warning: Couldn't convert a value." << std::endl;
-        return false;
-    }
-};
-// 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>
-template <class FromType, class ToType>
-struct ConverterDefault<0, FromType, ToType>
-{
-    static bool convert(ToType* output, const FromType& input)
-    {
-        (*output) = (ToType)input;
-        return true;
-    }
-};
-
-
-// Converter: Converts input of FromType into output of ToType
-template <int diff, int max, class FromType, class ToType, ConversionPreference pref>
-struct Converter
-{
-    static bool convert(ToType* output, const FromType& input)
-    {
-        return false;
-    }
-};
-// Converter: level{FromType} > level{ToType}
-template <int max, class FromType, class ToType, ConversionPreference pref>
-struct Converter<-1, max, FromType, ToType, pref>
-{   static bool convert(ToType* output, const FromType& input)
-    { 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)); } };
-// Converter: level{FromType} < level{ToType}
-template <int max, class FromType, class ToType, ConversionPreference pref>
-struct Converter<1, max, FromType, ToType, pref>
-{   static bool convert(ToType* output, const FromType& input)
-    { 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)); } };
-// Converter: level{FromType} = level{ToType}
-// CP_PreferToType
-template <int max, class FromType, class ToType>
-struct Converter<0, max, FromType, ToType, CP_PreferToType>
-{   static bool convert(ToType* output, const FromType& input)
-    { 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)); } };
-// CP_PreferFromType
-template <int max, class FromType, class ToType>
-struct Converter<0, max, FromType, ToType, CP_PreferFromType>
-{   static bool convert(ToType* output, const FromType& input)
-    { 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)); } };
-
-
-// Calls the Converter::convertValue function with the correct template type parameters calculated by ConverterPreference
-template <class FromType, class ToType>
-static bool convertValue(ToType* output, const FromType& input, ConversionPreference preference = CP_PreferToType)
-{
-    return (preference == CP_PreferToType) ?
-           Converter<ConverterPreference<ConverterLevel<FromType>::level, ConverterLevel<ToType>::level>::diff,
-                     ConverterPreference<ConverterLevel<FromType>::level, ConverterLevel<ToType>::level>::max,
-                     FromType,
-                     ToType,
-                     CP_PreferToType>::convert(output, input)
-         : Converter<ConverterPreference<ConverterLevel<FromType>::level, ConverterLevel<ToType>::level>::diff,
-                     ConverterPreference<ConverterLevel<FromType>::level, ConverterLevel<ToType>::level>::max,
-                     FromType,
-                     ToType,
-                     CP_PreferFromType>::convert(output, input);
-}
-
-
-//////////////////////
-// HELPER FUNCTIONS //
-//////////////////////
+}
+
+
+////////////////////
+//Public Functions//
+////////////////////
+
+/**
+@brief
+    Converts any value to any other as long as there exits a conversion.
+    Otherwise, the conversion will generate a runtime warning.
+*/
+template <class ToType, class FromType>
+inline bool convertValue(ToType* output, const FromType& input)
+{
+    // check whether we can convert one type to the other explicitely.
+    //conversionTests::ExplicitConversion<FromType, ToType, 4>::test();
+    return conversion::convert(output, input,
+        conversion::ExplicitPossible<ExplicitConversion<FromType, ToType>::exists>());
+}
 
 // Helper function: Calls convertValue with and without default value and returns true if the conversion was successful
 template<class FromType, class ToType>
-static bool ConvertValue(ToType* output, const FromType& input, ConversionPreference preference = CP_PreferToType)
-{
-    return convertValue(output, input, preference);
+static bool ConvertValue(ToType* output, const FromType& input)
+{
+    return convertValue(output, input);
 }
 template<class FromType, class ToType>
-static bool ConvertValue(ToType* output, const FromType& input, const ToType& fallback, ConversionPreference preference = CP_PreferToType)
-{
-    if (convertValue(output, input, preference))
+static bool ConvertValue(ToType* output, const FromType& input, const ToType& fallback)
+{
+    if (convertValue(output, input))
         return true;
 
@@ -232,15 +431,15 @@
 // Helper function: Calls convertValue with and without default value and returns the converted value
 template<class FromType, class ToType>
-static ToType getConvertedValue(const FromType& input, ConversionPreference preference = CP_PreferToType)
+static ToType getConvertedValue(const FromType& input)
 {
     ToType output = ToType();
-    ConvertValue(&output, input, preference);
+    ConvertValue(&output, input);
     return output;
 }
 template<class FromType, class ToType>
-static ToType getConvertedValue(const FromType& input, const ToType& fallback, ConversionPreference preference = CP_PreferToType)
+static ToType getConvertedValue(const FromType& input, const ToType& fallback)
 {
     ToType output = fallback;
-    ConvertValue(&output, input, fallback, preference);
+    ConvertValue(&output, input, fallback);
     return output;
 }
@@ -283,41 +482,87 @@
 */
 
-////////////
-// STRING //
-////////////
-
-// convert to string
-template <class FromType>
-struct ConverterSpecialized<FromType, std::string, _ToType_>
-{
-    enum { specialized = true };
-    static bool convert(std::string* output, const FromType& input)
-    {
-        std::ostringstream oss;
-        if (oss << input)
-        {
-            (*output) = oss.str();
-            return true;
-        }
-        else
-            return false;
-    }
-};
-
-// convert from string
-template <class ToType>
-struct ConverterSpecialized<std::string, ToType, _FromType_>
-{
-    enum { specialized = true };
-    static bool convert(ToType* output, const std::string& input)
-    {
-        std::istringstream iss(input);
-        if (iss >> (*output))
-            return true;
-        else
-            return false;
-    }
-};
-
+
+/////////////////
+// CONST CHAR* //
+/////////////////
+/*
+// convert from const char* --> use conversions with std::string
+template <class ToType, class Type>
+struct ConverterSpecialized<const char*, ToType, Type>
+{
+    enum { specialized = true };
+    static bool convert(ToType* output, const char* input)
+    {
+        return ConverterSpecialized<std::string, ToType, Type>::convert(output, input);
+    }
+};
+
+// convert from const char* --> use conversions with std::string
+template <>
+struct ConverterSpecialized<const char*, std::string, _ToType_>
+{
+    enum { specialized = true };
+    static bool convert(std::string* output, const char* input)
+    {
+        *output = input;
+        return true;
+    }
+};
+
+// convert from const char* _Explicit_ --> use conversions with std::string
+//template <class ToType>
+//struct ConverterSpecialized<const char*, ToType, _Explicit_>
+//{
+//    enum { specialized = true };
+//    static bool convert(ToType* output, const char* input)
+//    {
+//        return ConverterSpecialized<std::string, ToType, _Explicit_>::convert(output, input);
+//    }
+//};
+
+// convert from char* without const is not allowed
+//template <class ToType, class Type>
+//struct ConverterSpecialized<char*, ToType, Type>
+//{
+//    enum { specialized = true };
+//    static bool convert(ToType* output, const char* input)
+//    {
+//        BOOST_STATIC_ASSERT(sizeof(ToType) == 0);
+//    }
+//};
+
+// No support for char* without const
+//template <class ToType, class Type>
+//struct ConverterSpecialized<char*, ToType, Type>
+//{
+//    enum { specialized = true };
+//    static bool convert(ToType* output, const char* input)
+//    {
+//        BOOST_STATIC_ASSERT(sizeof(ToType) == 0);
+//    }
+//};
+
+// convert to const char* is not supported (possible memory leak)
+template <class FromType, class Type>
+struct ConverterSpecialized<FromType, const char*, Type>
+{
+    enum { specialized = true };
+    static bool convert(const char** output, const FromType& input)
+    {
+        BOOST_STATIC_ASSERT(sizeof(FromType) == 0);
+    }
+};
+
+// convert to char* is not supported (possible memory leak)
+// Note: It actually does need both specializations for const char* and char*
+//template <class FromType, class Type>
+//struct ConverterSpecialized<FromType, char*, Type>
+//{
+//    enum { specialized = true };
+//    static bool convert(char** output, const FromType& input)
+//    {
+//        BOOST_STATIC_ASSERT(sizeof(FromType) == 0);
+//    }
+//};
 
 
@@ -549,8 +794,4 @@
     }
 };
-
-#if ORXONOX_COMPILER == ORXONOX_COMPILER_MSVC
-#pragma warning(pop)
-#endif
-
+*/
 #endif /* _Convert_H__ */
