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