Index: code/branches/core3/src/util/Convert.h
===================================================================
--- code/branches/core3/src/util/Convert.h	(revision 1780)
+++ code/branches/core3/src/util/Convert.h	(revision 2014)
@@ -23,5 +23,5 @@
  *      Benjamin Grauer
  *      Fabian 'x3n' Landau
- *      Reto Grieder (direct conversion tests)
+ *      Reto Grieder
  *   Co-authors:
  *      ...
@@ -45,16 +45,18 @@
 #include "Debug.h"
 
-// Gcc generates warnings when implicitely casting from float to int for instance.
-// This is however exactly what convertValue does, so we need to suppress the warnings.
-// They only occur in when using the ImplicitConversion template.
+// GCC generates warnings when implicitely casting from float to int for instance.
+// This is however exactly what convertValue does, so we need to suppress these warnings.
+// They only occur when using the ImplicitConversion template.
 #if ORXONOX_COMPILER == ORXONOX_COMPILER_GNUC
 #  pragma GCC system_header
 #endif
 
+
 ///////////////////////////////////////////////
 // Static detection for conversion functions //
 ///////////////////////////////////////////////
+
 /* The idea to use the sizeof() operator on return functions to determine function existance
-   is described in 'Moder C++ design' by Alexandrescu (2001). */
+   is described in 'Modern C++ design' by Alexandrescu (2001). */
 
 // disable warnings about possible loss of data
@@ -64,31 +66,20 @@
 #endif
 
-namespace conversionTests
-{
-    // A struct that is guaranteed to be larger than any return type of our conversion functions.
-    // So we simply add all the sizes of the return types plus a little bit more.
-    struct VeryBigStruct
-    {
-        char intSize[sizeof(int)];
-        char addingMore[4096]; // just to be sure ;)
-    };
-
-    template <class FromType, class ToType>
-    class ImplicitConversion
-    {
-    private:
-        ImplicitConversion(); ImplicitConversion(const ImplicitConversion&); ~ImplicitConversion();
-        // Gets chosen only if there is an implicit conversion from FromType to ToType.
-        static int test(ToType);
-        // Accepts any argument. Why do we not use a template? The reason is that with templates,
-        // the function above is only taken iff it is an exact type match. But since we want to
-        // check for implicit conversion, we have to use the ellipsis.
-        static VeryBigStruct   test(...);
-        static FromType object; // helper object to handle private c'tor and d'tor
-    public:
-        // test(object) only has 'VerySmallStruct' return type iff the compiler doesn't choose test(...)
-        enum { exists = !(sizeof(test(object)) == sizeof(VeryBigStruct)) };
-    };
-}
+template <class FromType, class ToType>
+class ImplicitConversion
+{
+private:
+    ImplicitConversion(); ImplicitConversion(const ImplicitConversion&); ~ImplicitConversion();
+    // Gets chosen only if there is an implicit conversion from FromType to ToType.
+    static char test(ToType);
+    // Accepts any argument. Why do we not use a template? The reason is that with templates,
+    // the function above is only taken iff it is an exact type match. But since we want to
+    // check for implicit conversion, we have to use the ellipsis.
+    static long long test(...);
+    static FromType object; // helper object to handle private c'tor and d'tor
+public:
+    // test(object) only has 'long long' return type iff the compiler doesn't choose test(...)
+    enum { exists = (sizeof(test(object)) == sizeof(char)) };
+};
 
 #if ORXONOX_COMPILER == ORXONOX_COMPILER_MSVC
@@ -102,28 +93,30 @@
 /*
     There is a distinct priority when choosing the right conversion function:
-    Overwrites:
-    1. (Partial) template specialisation of ConverterExplicit::convert
-    2. Global functions convertValue(ToType* output, const FromType input)
+    Overwrite:
+    1. (Partial) template specialisation of ConverterExplicit::convert()
     Fallbacks:
-    3. Any possible implicit conversion. This includes FooBar --> int if FooBar defines operator float().
-    4. Global or member operators for stringstream when converting from or to std::string (or FROM const char*)
-    5. Function that simply displays "Could not convert value" with information obtained from typeid().
-
-    A note: There has to be an exact type match (or according to the rules of template spec.) except for 3.
-
-    There are obviously a lot of ways to specifiy a user defined conversion. What should I use?
-    When using any non-template function based conversion (implicit conversion, convertValue, << or >>)
-    then you should consider that this function has to be defined prior to including this file.
-    If you do not whish do do that, you will have to spcecialsize the ConverterExplicit template.
-    There is a not so obvious advantage of the other way (non-template): You could declare each conversion function
-    in the Prereqs file of the corresponding library. Then you can use the conversion everywhere.
-    This is not possible with template specialisations even when defining them in this file (You would create
-    a circular dependency when using a class from Core for instance, because complete template specialisations
-    get compiled anyway (there is no template parameter)).
+    2. Any possible implicit conversion. This includes 'FooBar' --> 'int' if FooBar defines operator float().
+    3. Global or member operators for stringstream when converting from or to std::string (or FROM const char*)
+    4. (Partial) template specialisation of ConverterFallback::convert()
+    5. Function that simply displays "Could not convert value" with type information obtained from typeid().
+
+    Notes:
+    There has to be an exact type match when using template specialisations.
+    Template specialisations can be defined after including this file. Any implicit cast function or iostream
+    operator has to be declared BEFORE this file gets parsed.
+
+    Defining your own functions:
+    There are obviously 4 ways to specifiy a user defined conversion. What should I use?
+
+    Usually, ConverterFallback fits quite well. You won't have to deal with the conversion from
+    'MyClass' to 'MyClass' by using another explicit template specialisation to avoid ambiguities.
+
+    However if you want to overwrite an implicit conversion or an iostream operator, you really need to
+    make use of ConverterExplicit.
 */
 
 namespace
 {
-    // little template that maps to ints to entire types (Alexandrescu 2001)
+    //! Little template that maps integers to entire types (Alexandrescu 2001)
     template <int I>
     struct Int2Type { };
@@ -141,6 +134,6 @@
     static bool convert(ToType* output, const FromType& input)
     {
-        COUT(2) << "Could not convert value of type " << typeid(FromType).name()
-                << " to type " << typeid(ToType).name() << std::endl;
+        //COUT(2) << "Could not convert value of type " << typeid(FromType).name()
+        //        << " to type " << typeid(ToType).name() << std::endl;
         return false;
     }
@@ -183,5 +176,5 @@
 }
 
-// template that evaluates whether OStringStream is possible for conversions to std::string
+// template that evaluates whether we can convert to std::string via ostringstream
 template <class FromType>
 struct ConverterStringStream<std::string, FromType>
@@ -190,4 +183,5 @@
     {
         using namespace fallbackTemplates;
+        // this operator call only chooses fallbackTemplates::operator<< if there's no other fitting function
         std::ostringstream oss;
         if (oss << input)
@@ -216,5 +210,5 @@
 }
 
-// template that evaluates whether IStringStream is possible for conversions from std::string
+// template that evaluates whether we can convert from std::string via ostringstream
 template <class ToType>
 struct ConverterStringStream<ToType, std::string>
@@ -224,4 +218,5 @@
         using namespace fallbackTemplates;
         std::istringstream iss(input);
+        // this operator call only chooses fallbackTemplates::operator>> if there's no other fitting function
         if (iss >> (*output))
         {
@@ -238,5 +233,5 @@
 ///////////////////
 
-// static cast no possible, try stringstream conversion next
+// implicit cast not possible, try stringstream conversion next
 template <class ToType, class FromType>
 inline bool convertImplicitely(ToType* output, const FromType& input, ::Int2Type<false>)
@@ -254,7 +249,7 @@
 
 
-///////////////////////
-// Explicit Fallback //
-///////////////////////
+////////////////////////////////
+// ConverterExplicit Fallback //
+////////////////////////////////
 
 // Default template if no specialisation is available
@@ -264,6 +259,7 @@
     static bool convert(ToType* output, const FromType& input)
     {
-        // try implict conversion by probing first because we use '...' instead of a template
-        const bool probe = conversionTests::ImplicitConversion<FromType, ToType>::exists;
+        // Try implict cast and probe first. If a simple cast is not possible, it will not compile
+        // We therefore have to out source it into another template function
+        const bool probe = ImplicitConversion<FromType, ToType>::exists;
         return convertImplicitely(output, input, ::Int2Type<probe>());
     }
@@ -278,9 +274,7 @@
 @brief
     Converts any value to any other as long as there exists a conversion.
-    Otherwise, the conversion will generate a runtime warning.
+    Otherwise, the conversion will generate a runtime warning and return false.
     For information about the different conversion methods (user defined too), see the section
     'Actual conversion sequence' in this file above.
-@note
-    This function is only a fallback if there is no appropriate 'convertValue' function.
 */
 template <class ToType, class FromType>
@@ -299,12 +293,31 @@
 // Calls convertValue and returns true if the conversion was successful.
 // Otherwise the fallback is used.
+/**
+@brief
+    Converts any value to any other as long as there exists a conversion.
+    Otherwise, the conversion will generate a runtime warning and return false.
+    For information about the different conversion methods (user defined too), see the section
+    'Actual conversion sequence' in this file above.
+    If the conversion doesn't succeed, 'fallback' is written to '*output'.
+@param fallback
+    A default value that gets written to '*output' if there is no conversion.
+*/
+template<class FromType, class ToType>
+inline bool convertValue(ToType* output, const FromType& input, const ToType& fallback)
+{
+    if (convertValue(output, input))
+        return true;
+    else
+    {
+        (*output) = fallback;
+        return false;
+    }
+}
+
+// for compatibility reason. (capital 'c' in ConvertValue)
 template<class FromType, class ToType>
 inline bool ConvertValue(ToType* output, const FromType& input, const ToType& fallback)
 {
-    if (convertValue(output, input))
-        return true;
-
-    (*output) = fallback;
-    return false;
+    return convertValue(output, input, fallback);
 }
 
@@ -314,5 +327,5 @@
 {
     ToType output;
-    ConvertValue(&output, input);
+    convertValue(&output, input);
     return output;
 }
@@ -323,5 +336,5 @@
 {
     ToType output;
-    ConvertValue(&output, input, fallback);
+    convertValue(&output, input, fallback);
     return output;
 }
@@ -333,14 +346,5 @@
 {
     ToType output;
-    ConvertValue(&output, input);
-    return output;
-}
-
-// Like conversion_cast above, but uses a fallback on failure.
-template<class ToType, class FromType>
-inline ToType conversion_cast(const FromType& input, const ToType& fallback)
-{
-    ToType output;
-    ConvertValue(&output, input, fallback);
+    convertValue(&output, input);
     return output;
 }
@@ -351,5 +355,5 @@
 ////////////////////////////////
 
-// delegate conversion from const char* to std::string
+// Delegate conversion from const char* to std::string
 template <class ToType>
 struct ConverterExplicit<ToType, const char*>
Index: code/branches/core3/src/util/MathConvert.h
===================================================================
--- code/branches/core3/src/util/MathConvert.h	(revision 1780)
+++ code/branches/core3/src/util/MathConvert.h	(revision 2014)
@@ -37,6 +37,6 @@
 
 #include "UtilPrereqs.h"
+#include "Math.h"
 #include "Convert.h"
-#include "Math.h"
 
 
@@ -153,43 +153,55 @@
 // From Radian
 template <class ToType>
-inline bool fallbackConversion(ToType* output, const orxonox::Radian input)
-{
-    return convertValue<ToType, Ogre::Real>(output, input.valueRadians()); 
-}
+struct ConverterFallback<ToType, orxonox::Radian>
+{
+    static bool convert(ToType* output, const orxonox::Radian& input)
+    {
+        return convertValue<ToType, Ogre::Real>(output, input.valueRadians());
+    }
+};
 
 // From Degree
 template <class ToType>
-inline bool fallbackConversion(ToType* output, const orxonox::Degree input)
-{
-    return convertValue<ToType, Ogre::Real>(output, input.valueDegrees()); 
-}
+struct ConverterFallback<ToType, orxonox::Degree>
+{
+    static bool convert(ToType* output, const orxonox::Degree& input)
+    {
+        return convertValue<ToType, Ogre::Real>(output, input.valueDegrees());
+    }
+};
 
 // To Radian
 template <class FromType>
-inline bool fallbackConversion(orxonox::Radian* output, const FromType input)
-{
-    float temp;
-    if (convertValue(&temp, input))
-    {
-        *output = temp;
-        return true;
-    }
-    else
-        return false;
-}
+struct ConverterFallback<orxonox::Radian, FromType>
+{
+    static bool convert(orxonox::Radian* output, const FromType& input)
+    {
+        float temp;
+        if (convertValue(&temp, input))
+        {
+            *output = temp;
+            return true;
+        }
+        else
+            return false;
+    }
+};
 
 // To Degree
 template <class FromType>
-inline bool fallbackConversion(orxonox::Degree* output, const FromType input)
-{
-    float temp;
-    if (convertValue(&temp, input))
-    {
-        *output = temp;
-        return true;
-    }
-    else
-        return false;
-}
+struct ConverterFallback<orxonox::Degree, FromType>
+{
+    static bool convert(orxonox::Degree* output, const FromType& input)
+    {
+        float temp;
+        if (convertValue(&temp, input))
+        {
+            *output = temp;
+            return true;
+        }
+        else
+            return false;
+    }
+};
 
 #endif /* _MathConvert_H__ */
