From 63a608e4db9dbdc8ef8956a488ba51a2c81a637e Mon Sep 17 00:00:00 2001 From: Mike Date: Sat, 1 Mar 2014 10:30:44 +1100 Subject: [PATCH] cleanup --- include/api.hpp | 22 ++++++++--- test/algorithms.cpp | 89 ++++++++++++++++++++++++++++++++++++++++++ test/performance.cpp | 1 - test/sfinae.cpp | 1 - test/test.hpp | 4 ++ test/test_convert.cpp | 91 ++----------------------------------------- 6 files changed, 112 insertions(+), 96 deletions(-) create mode 100644 test/algorithms.cpp diff --git a/include/api.hpp b/include/api.hpp index 2e11129..e3e21fb 100644 --- a/include/api.hpp +++ b/include/api.hpp @@ -32,22 +32,32 @@ namespace boost template struct boost::convert { - struct result; + // C1. TypeOut needs to be normalized as, say, "char const*" might be provided when + // std::string will be used instead (as we have to have storage for the conversion result). + // C2. TypeIn oth the other hand needs to be passed in to the Converter as-is. + // That way the converter will be able to optimize the conversion based on that TypeIn type. + // C3. convert::from() allocates storage for the conversion result. + // The Pascal-style passing of the out_type& to the converter is ugly. However, it + // a) ensures the consistent requirement with regard to "out_type" + // (rather than every converter imposing their own); + // b) relieves the converter of that responsibility and makes writing converters easier. + + struct result; template struct algorithm_helper; typedef boost::convert this_type; - typedef typename convert_detail::corrected::type out_type; - typedef typename boost::convert::result result_type; + typedef typename convert_detail::corrected::type out_type; //C1 + typedef typename boost::convert::result result_type; //C1 static out_type create_storage() { return out_type(); } template static result_type - from(TypeIn const& value_in, Converter const& converter) //C1. + from(TypeIn const& value_in, Converter const& converter) { - result_type result (this_type::create_storage()); //C2 - bool success = converter(value_in, result.value_); //C3 + result_type result (this_type::create_storage()); //C1,C3 + bool success = converter(value_in, result.value_); //C1,C2,C3 return success ? result : result(false); } diff --git a/test/algorithms.cpp b/test/algorithms.cpp new file mode 100644 index 0000000..a512bfd --- /dev/null +++ b/test/algorithms.cpp @@ -0,0 +1,89 @@ +// Boost.Convert library test and usage example +// Copyright (c) 2009-2014 Vladimir Batov. +// Use, modification and distribution are subject to the Boost Software License, +// Version 1.0. See http://www.boost.org/LICENSE_1_0.txt. + +#include "./test.hpp" + +void +test::algorithms() +{ + boost::array strings = {{ "0XF", "0X10", "0X11", "0X12", "not int" }}; + std::vector integers; + std::vector new_strings; + boost::cstringstream_converter ccnv; // stringstream-based char converter + + //////////////////////////////////////////////////////////////////////////// + // String to integer conversion. + // No explicit fallback, i.e. throws on failure. Hex formatting. + //////////////////////////////////////////////////////////////////////////// + try + { + std::transform( + strings.begin(), + strings.end(), + std::back_inserter(integers), + boost::bind(boost::lexical_cast, _1)); + + BOOST_ASSERT(!"We should not be here"); + } + catch (std::exception&) + { + // Expected behavior. + printf("boost::lexical_cast processed: %d entries.\n", int(integers.size())); + } + try + { + std::transform( + strings.begin(), + strings.end(), + std::back_inserter(integers), + boost::convert::from(ccnv(std::hex))); + + BOOST_ASSERT(!"We should not be here"); + } + catch (std::exception&) + { + // Expected behavior. + printf("boost::convert processed: %d entries.\n", int(integers.size())); + } + BOOST_ASSERT(integers[0] == 15); + BOOST_ASSERT(integers[1] == 16); + BOOST_ASSERT(integers[2] == 17); + BOOST_ASSERT(integers[3] == 18); + + integers.clear(); + + //////////////////////////////////////////////////////////////////////////// + // String to integer conversion. Explicit fallback, i.e. no throwing. Hex formatting. + //////////////////////////////////////////////////////////////////////////// + std::transform( + strings.begin(), + strings.end(), + std::back_inserter(integers), + boost::convert::from(ccnv(arg::base = cnv::base::hex)).value_or(-1)); + + BOOST_ASSERT(integers[0] == 15); + BOOST_ASSERT(integers[1] == 16); + BOOST_ASSERT(integers[2] == 17); + BOOST_ASSERT(integers[3] == 18); + BOOST_ASSERT(integers[4] == -1); // Failed conversion + + //////////////////////////////////////////////////////////////////////////// + // int-to-string conversion. No explicit fallback value. + //////////////////////////////////////////////////////////////////////////// + std::transform( + integers.begin(), + integers.end(), + std::back_inserter(new_strings), + boost::convert::from(ccnv(std::dec))); + +// for (size_t k = 0; k < new_strings.size(); ++k) +// printf("%d. %s\n", int(k), new_strings[k].c_str()); + + BOOST_ASSERT(new_strings[0] == "15"); + BOOST_ASSERT(new_strings[1] == "16"); + BOOST_ASSERT(new_strings[2] == "17"); + BOOST_ASSERT(new_strings[3] == "18"); + BOOST_ASSERT(new_strings[4] == "-1"); +} \ No newline at end of file diff --git a/test/performance.cpp b/test/performance.cpp index 90b2501..b72f718 100644 --- a/test/performance.cpp +++ b/test/performance.cpp @@ -1,5 +1,4 @@ // Boost.Convert library test and usage example -// // Copyright (c) 2009-2014 Vladimir Batov. // Use, modification and distribution are subject to the Boost Software License, // Version 1.0. See http://www.boost.org/LICENSE_1_0.txt. diff --git a/test/sfinae.cpp b/test/sfinae.cpp index 7e1f921..9c24793 100644 --- a/test/sfinae.cpp +++ b/test/sfinae.cpp @@ -1,5 +1,4 @@ // Boost.Convert library test and usage example -// // Copyright (c) 2009-2014 Vladimir Batov. // Use, modification and distribution are subject to the Boost Software License, // Version 1.0. See http://www.boost.org/LICENSE_1_0.txt. diff --git a/test/test.hpp b/test/test.hpp index f9ef2e1..8d3d766 100644 --- a/test/test.hpp +++ b/test/test.hpp @@ -94,10 +94,14 @@ struct test #endif static void sfinae(); + static void algorithms(); static void performance(); template static void type_to_string(Converter const&); template static void string_to_type(Converter const&); }; +namespace cnv = boost::conversion; +namespace arg = boost::conversion::parameter; + #endif // BOOST_CONVERT_TEST_HPP diff --git a/test/test_convert.cpp b/test/test_convert.cpp index 778298e..9caab09 100644 --- a/test/test_convert.cpp +++ b/test/test_convert.cpp @@ -1,5 +1,4 @@ // Boost.Convert library test and usage example -// // Copyright (c) 2009-2014 Vladimir Batov. // Use, modification and distribution are subject to the Boost Software License, // Version 1.0. See http://www.boost.org/LICENSE_1_0.txt. @@ -7,17 +6,14 @@ #include "./test.hpp" #if !defined(_MSC_VER) #include "./sfinae.cpp" +#include "./algorithms.cpp" #include "./performance.cpp" #endif using std::string; using std::wstring; -using boost::array; using boost::convert; -namespace cnv = boost::conversion; -namespace arg = boost::conversion::parameter; - bool my_cypher(std::string const& value_in, std::string& value_out) { @@ -64,10 +60,11 @@ int main(int argc, char const* argv[]) { test::sfinae(); - test::performance(); test::string_to_type(boost::strtol_converter()); test::string_to_type(boost::printf_converter()); test::type_to_string(boost::printf_converter()); + test::algorithms(); + test::performance(); string const not_int_str = "not an int"; string const std_str = "-11"; @@ -266,70 +263,6 @@ main(int argc, char const* argv[]) BOOST_ASSERT(dn_dir4 == direction::dn); BOOST_ASSERT(!up_dir4); // Failed conversion - //////////////////////////////////////////////////////////////////////////// - // Testing with algorithms - //////////////////////////////////////////////////////////////////////////// - - array strings = {{ "0XF", "0X10", "0X11", "0X12", "not int" }}; - std::vector integers; - std::vector new_strings; - - //////////////////////////////////////////////////////////////////////////// - // String to integer conversion. - // No explicit fallback, i.e. throws on failure. Hex formatting. - //////////////////////////////////////////////////////////////////////////// - try - { - std::transform( - strings.begin(), - strings.end(), - std::back_inserter(integers), - boost::bind(boost::lexical_cast, _1)); - - BOOST_ASSERT(!"We should not be here"); - } - catch (std::exception&) - { - // Expected behavior. - printf("boost::lexical_cast processed: %d entries.\n", int(integers.size())); - } - try - { - std::transform( - strings.begin(), - strings.end(), - std::back_inserter(integers), - convert::from(ccnv(std::hex))); - - BOOST_ASSERT(!"We should not be here"); - } - catch (std::exception&) - { - // Expected behavior. - printf("boost::convert processed: %d entries.\n", int(integers.size())); - } - BOOST_ASSERT(integers[0] == 15); - BOOST_ASSERT(integers[1] == 16); - BOOST_ASSERT(integers[2] == 17); - BOOST_ASSERT(integers[3] == 18); - - integers.clear(); - - //////////////////////////////////////////////////////////////////////////// - // String to integer conversion. Explicit fallback, i.e. no throwing. Hex formatting. - //////////////////////////////////////////////////////////////////////////// - std::transform( - strings.begin(), - strings.end(), - std::back_inserter(integers), - convert::from(ccnv(arg::base = cnv::base::hex)).value_or(-1)); - - BOOST_ASSERT(integers[0] == 15); - BOOST_ASSERT(integers[1] == 16); - BOOST_ASSERT(integers[2] == 17); - BOOST_ASSERT(integers[3] == 18); - BOOST_ASSERT(integers[4] == -1); // Failed conversion - //////////////////////////////////////////////////////////////////////////// // Testing formatters/manipulators //////////////////////////////////////////////////////////////////////////// @@ -405,24 +338,6 @@ main(int argc, char const* argv[]) BOOST_ASSERT(double_rus == rus_expected); BOOST_ASSERT(double_eng == eng_expected); - //////////////////////////////////////////////////////////////////////////// - // int-to-string conversion. No explicit fallback value. - //////////////////////////////////////////////////////////////////////////// - std::transform( - integers.begin(), - integers.end(), - std::back_inserter(new_strings), - convert::from(ccnv(std::dec))); - -// for (size_t k = 0; k < new_strings.size(); ++k) -// printf("%d. %s\n", int(k), new_strings[k].c_str()); - - BOOST_ASSERT(new_strings[0] == "15"); - BOOST_ASSERT(new_strings[1] == "16"); - BOOST_ASSERT(new_strings[2] == "17"); - BOOST_ASSERT(new_strings[3] == "18"); - BOOST_ASSERT(new_strings[4] == "-1"); - //////////////////////////////////////////////////////////////////////////// // Testing string-to-bool and bool-to-string conversions ////////////////////////////////////////////////////////////////////////////