Author: mordante
Date: Sat May 16 22:42:15 2009
New Revision: 35667

URL: http://svn.gna.org/viewcvs/wesnoth?rev=35667&view=rev
Log:
Add more specialized lexical_cast versions.

Modified:
    trunk/src/lexical_cast.hpp
    trunk/src/tests/test_lexical_cast.cpp

Modified: trunk/src/lexical_cast.hpp
URL: 
http://svn.gna.org/viewcvs/wesnoth/trunk/src/lexical_cast.hpp?rev=35667&r1=35666&r2=35667&view=diff
==============================================================================
--- trunk/src/lexical_cast.hpp (original)
+++ trunk/src/lexical_cast.hpp Sat May 16 22:42:15 2009
@@ -43,8 +43,9 @@
 
 #include <string>
 #include <sstream>
+#include <boost/mpl/set.hpp>
+#include <boost/type_traits.hpp>
 #include <boost/utility/enable_if.hpp>
-#include <boost/type_traits.hpp>
 
 #define DEBUG_THROW(id)
 #endif
@@ -146,6 +147,209 @@
        }
 };
 
+/**
+ * Specialized conversion class.
+ *
+ * Specialized for returning a long long from a (const) char*.
+ * @note is separate from the other signed types since a long long has a
+ * performance penalty at 32 bit systems.
+ */
+template <class From>
+struct tlexical_cast<
+         long long
+       , From
+       , void
+       , typename boost::enable_if<boost::mpl::has_key<boost::mpl::set<
+                       char*, const char*> , From> >::type
+       >
+{
+       long long operator()(From value)
+       {
+               DEBUG_THROW("specialized - To long long - From (const) char*");
+
+               char* endptr;
+               int res = strtoll(value, &endptr, 10);
+
+               if (*value == '\0' || *endptr != '\0') {
+                       throw bad_lexical_cast();
+               } else {
+                       return res;
+               }
+       }
+};
+
+/**
+ * Specialized conversion class.
+ *
+ * Specialized for returning a long long from a std::string.
+ * @note is separate from the other signed types since a long long has a
+ * performance penalty at 32 bit systems.
+ */
+template <>
+struct tlexical_cast<
+         long long
+       , std::string
+       >
+{
+       long long operator()(const std::string& value)
+       {
+               DEBUG_THROW("specialized - To long long - From std::string");
+
+               return lexical_cast<long long>(value.c_str());
+       }
+};
+
+/**
+ * Specialized conversion class.
+ *
+ * Specialized for returning a signed type from a (const) char*.
+ */
+template <class To, class From>
+struct tlexical_cast<
+         To
+       , From
+       , typename boost::enable_if<boost::is_signed<To> >::type
+       , typename boost::enable_if<boost::mpl::has_key<boost::mpl::set<
+                       char*, const char*> , From> >::type
+       >
+{
+       To operator()(From value)
+       {
+               DEBUG_THROW("specialized - To signed - From (const) char*");
+
+               char* endptr;
+               int res = strtol(value, &endptr, 10);
+
+               if (*value == '\0' || *endptr != '\0') {
+                       throw bad_lexical_cast();
+               } else {
+                       return res;
+               }
+       }
+};
+
+/**
+ * Specialized conversion class.
+ *
+ * Specialized for returning a signed type from a std::string.
+ */
+template <class To>
+struct tlexical_cast<
+         To
+       , std::string
+       , typename boost::enable_if<boost::is_signed<To> >::type
+       >
+{
+       To operator()(const std::string& value)
+       {
+               DEBUG_THROW("specialized - To signed - From std::string");
+
+               return lexical_cast<To>(value.c_str());
+       }
+};
+
+/**
+ * Specialized conversion class.
+ *
+ * Specialized for returning a unsigned long long from a (const) char*.
+ * @note is separate from the other unsigned types since a unsigned long long
+ * has a performance penalty at 32 bit systems.
+ */
+template <class From>
+struct tlexical_cast<
+         unsigned long long
+       , From
+       , void
+       , typename boost::enable_if<boost::mpl::has_key<boost::mpl::set<
+                       char*, const char*> , From> >::type
+       >
+{
+       long long operator()(From value)
+       {
+               DEBUG_THROW(
+                               "specialized - To unsigned long long - From 
(const) char*");
+
+               char* endptr;
+               int res = strtoull(value, &endptr, 10);
+
+               if (*value == '\0' || *endptr != '\0') {
+                       throw bad_lexical_cast();
+               } else {
+                       return res;
+               }
+       }
+};
+
+/**
+ * Specialized conversion class.
+ *
+ * Specialized for returning a unsigned long long from a std::string.
+ * @note is separate from the other unsigned types since a unsigned long long
+ * has a performance penalty at 32 bit systems.
+ */
+template <>
+struct tlexical_cast<
+         unsigned long long
+       , std::string
+       >
+{
+       long long operator()(const std::string& value)
+       {
+               DEBUG_THROW("specialized - To unsigned long long - From 
std::string");
+
+               return lexical_cast<unsigned long long>(value.c_str());
+       }
+};
+
+/**
+ * Specialized conversion class.
+ *
+ * Specialized for returning a unsigned type from a (const) char*.
+ */
+template <class To, class From>
+struct tlexical_cast<
+         To
+       , From
+       , typename boost::enable_if<boost::is_unsigned<To> >::type
+       , typename boost::enable_if<boost::mpl::has_key<boost::mpl::set<
+                       char*, const char*> , From> >::type
+       >
+{
+       To operator()(From value)
+       {
+               DEBUG_THROW("specialized - To unsigned - From (const) char*");
+
+               char* endptr;
+               int res = strtoul(value, &endptr, 10);
+
+               if (*value == '\0' || *endptr != '\0') {
+                       throw bad_lexical_cast();
+               } else {
+                       return res;
+               }
+       }
+};
+
+/**
+ * Specialized conversion class.
+ *
+ * Specialized for returning a unsigned type from a std::string.
+ */
+template <class To>
+struct tlexical_cast<
+         To
+       , std::string
+       , typename boost::enable_if<boost::is_unsigned<To> >::type
+       >
+{
+       To operator()(const std::string& value)
+       {
+               DEBUG_THROW("specialized - To unsigned - From std::string");
+
+               return lexical_cast<To>(value.c_str());
+       }
+};
+
 } // namespace implementation
 
 #endif

Modified: trunk/src/tests/test_lexical_cast.cpp
URL: 
http://svn.gna.org/viewcvs/wesnoth/trunk/src/tests/test_lexical_cast.cpp?rev=35667&r1=35666&r2=35667&view=diff
==============================================================================
--- trunk/src/tests/test_lexical_cast.cpp (original)
+++ trunk/src/tests/test_lexical_cast.cpp Sat May 16 22:42:15 2009
@@ -12,16 +12,19 @@
    See the COPYING file for more details.
 */
 
+#define GETTEXT_DOMAIN "wesnoth-test"
+
+#include "lexical_cast.hpp"
+
 #include "utils/test_support.hpp"
+
 #include <boost/mpl/vector.hpp>
 #include <boost/mpl/copy.hpp>
 #include <boost/mpl/back_inserter.hpp>
 #include <boost/mpl/contains.hpp>
 #include <boost/test/test_case_template.hpp>
 
-#define GETTEXT_DOMAIN "wesnoth-test"
-
-#include "lexical_cast.hpp"
+#include <iostream>
 
 namespace test_throw {
 
@@ -59,7 +62,13 @@
 
 bool validate(const char* str)
 {
-       return str == result;
+       if(str != result) {
+               std::cerr << "Received " << str << '\n'
+                               << "Expected " << result << '\n';
+               return false;
+       } else {
+               return true;
+       }
 }
 
 } // namespace
@@ -95,7 +104,88 @@
        TEST_CASE(T* const, &);
        TEST_CASE(const T* const, &);
 }
+
 #undef TEST_CASE
+
+typedef boost::mpl::vector<
+         signed char
+       , short
+       , int
+       , long> test_lexical_cast_signed_types;
+
+BOOST_AUTO_TEST_CASE_TEMPLATE(
+               test_lexical_cast_signed, T, test_lexical_cast_signed_types)
+{
+       result = "specialized - To signed - From (const) char*";
+
+       const char* value = "test";
+       BOOST_CHECK_EXCEPTION(lexical_cast<T>(
+                       value), const char*, validate);
+       BOOST_CHECK_EXCEPTION(lexical_cast<T>(
+                       const_cast<char*>(value)), const char*, validate);
+
+       result = "specialized - To signed - From std::string";
+
+       BOOST_CHECK_EXCEPTION(lexical_cast<T>(
+                       std::string(value)), const char*, validate);
+}
+
+BOOST_AUTO_TEST_CASE(test_lexical_cast_long_long)
+{
+       result = "specialized - To long long - From (const) char*";
+
+       const char* value = "test";
+       BOOST_CHECK_EXCEPTION(lexical_cast<long long>(
+                       value), const char*, validate);
+       BOOST_CHECK_EXCEPTION(lexical_cast<long long>(
+                       const_cast<char*>(value)), const char*, validate);
+
+       result = "specialized - To long long - From std::string";
+
+       BOOST_CHECK_EXCEPTION(lexical_cast<long long>(
+                       std::string(value)), const char*, validate);
+}
+
+typedef boost::mpl::vector<
+         bool
+       , unsigned char
+       , unsigned short
+       , unsigned int
+       , unsigned long> test_lexical_cast_unsigned_types;
+
+BOOST_AUTO_TEST_CASE_TEMPLATE(
+               test_lexical_cast_unsigned, T, test_lexical_cast_unsigned_types)
+{
+       result = "specialized - To unsigned - From (const) char*";
+
+       const char* value = "test";
+       BOOST_CHECK_EXCEPTION(lexical_cast<T>(
+                       value), const char*, validate);
+       BOOST_CHECK_EXCEPTION(lexical_cast<T>(
+                       const_cast<char*>(value)), const char*, validate);
+
+       result = "specialized - To unsigned - From std::string";
+
+       BOOST_CHECK_EXCEPTION(lexical_cast<T>(
+                       std::string(value)), const char*, validate);
+
+}
+
+BOOST_AUTO_TEST_CASE(test_lexical_cast_unsigned_long_long)
+{
+       result = "specialized - To unsigned long long - From (const) char*";
+
+       const char* value = "test";
+       BOOST_CHECK_EXCEPTION(lexical_cast<unsigned long long>(
+                       value), const char*, validate);
+       BOOST_CHECK_EXCEPTION(lexical_cast<unsigned long long>(
+                       const_cast<char*>(value)), const char*, validate);
+
+       result = "specialized - To unsigned long long - From std::string";
+
+       BOOST_CHECK_EXCEPTION(lexical_cast<unsigned long long>(
+                       std::string(value)), const char*, validate);
+}
 
 } //  namespace test_throw
 
@@ -109,4 +199,8 @@
 
        BOOST_CHECK_EQUAL(lexical_cast<std::string>(1.2f), "1.2");
        BOOST_CHECK_EQUAL(lexical_cast<std::string>(1.2), "1.2");
-}
+
+       BOOST_CHECK_EQUAL(lexical_cast<int>("1"), 1);
+       BOOST_CHECK_EQUAL(lexical_cast<int>("-1"), -1);
+       BOOST_CHECK_EQUAL(lexical_cast<unsigned>("1"), 1);
+}


_______________________________________________
Wesnoth-commits mailing list
[email protected]
https://mail.gna.org/listinfo/wesnoth-commits

Reply via email to