// 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 "./example.hpp" #include #include #include #include #include #include static void introduction() { //[algorithm_introduction /*`For example, the following code converts an array of integers from their textual hexadecimal representation and assigns -1 to those which fail to convert: */ boost::array strs = {{ " 5", "0XF", "not an int" }}; std::vector ints; boost::cnv::cstream cnv; cnv(std::hex)(std::skipws); // Instruct reading hexadecimal. Skip white spaces. std::transform( strs.begin(), strs.end(), std::back_inserter(ints), boost::convert(boost::cref(cnv)).value_or(-1)); BOOST_TEST(ints.size() == 3); BOOST_TEST(ints[0] == 5); BOOST_TEST(ints[1] == 15); BOOST_TEST(ints[2] == -1); // Failed conversion //] } static void example1() { //[algorithm_example1 /*`The following code demonstrates a failed attempt to convert a few strings with `boost::lexical_cast` (and one of the reasons ['Boost.Convert] has been developed): */ boost::array strs = {{ " 5", "0XF", "not an int" }}; std::vector ints; try { std::transform( strs.begin(), strs.end(), std::back_inserter(ints), boost::bind(boost::lexical_cast, _1)); BOOST_TEST(0 && "Never reached"); } catch (std::exception&) { BOOST_TEST(ints.size() == 0); // No strings converted. } //] } static void example2() { //[algorithm_example2 /*`Still, if the exception-throwing behavior is the desired behavior, then ['Boost.Convert] supports that or, alternatively, offers a non-throwing process flow potentially using the same `boost::lexical_cast` converter: */ boost::array strs = {{ " 5", "0XF", "not an int" }}; std::vector ints; boost::cnv::lexical_cast cnv; std::transform( strs.begin(), strs.end(), std::back_inserter(ints), boost::convert(cnv).value_or(INT_MAX)); BOOST_TEST(ints.size() == 3); BOOST_TEST(ints[0] == INT_MAX); // Failed conversion BOOST_TEST(ints[1] == INT_MAX); // Failed conversion BOOST_TEST(ints[2] == INT_MAX); // Failed conversion //] } static void example3() { //[algorithm_example3 /*`Replacing the original `boost::lexical_cast`-based converter yields better results with exception-throwing and non-throwing process flows supported: */ boost::array strs = {{ " 5", "0XF", "not an int" }}; std::vector ints; boost::cnv::cstream cnv; try { std::transform( strs.begin(), strs.end(), std::back_inserter(ints), boost::convert(boost::cref(cnv(std::hex)(std::skipws)))); BOOST_TEST(0 && "Never reached"); } catch (boost::bad_optional_access const&) { BOOST_TEST(ints.size() == 2); // Only the first two strings converted. BOOST_TEST(ints[0] == 5); BOOST_TEST(ints[1] == 15); } //] } static void example4() { boost::array strs = {{ " 5", "0XF", "not an int" }}; std::vector ints; boost::cnv::cstream cnv; //[algorithm_example4 std::transform( strs.begin(), strs.end(), std::back_inserter(ints), boost::convert(boost::cref(cnv(std::hex)(std::skipws))).value_or(-1)); BOOST_TEST(ints.size() == 3); BOOST_TEST(ints[0] == 5); BOOST_TEST(ints[1] == 15); BOOST_TEST(ints[2] == -1); // Failed conversion /*`[important One notable difference in the deployment of `boost::cnv::cstream` with algorithms is the use of `boost::cref` (or `std::ref` in C++11). It needs to be remembered that with standard algorithms the deployed converter needs to be copyable or moveable (C++11) and is, in fact, copied or moved by the respective algorithm before being used. Given that `std::cstringstream` is not copyable, `boost::cnv::cstream` is not copyable either. That limitation is routinely worked around using `boost::ref`.] */ //] } static void example5() { //[algorithm_example5 /*`And, lastly, an example of algorithm-based integer-to-string formatted conversion with `std::uppercase` and `std::showbase` formatting applied: */ boost::array ints = {{ 15, 16, 17 }}; std::vector strs; boost::cnv::cstream cnv; cnv(std::hex)(std::uppercase)(std::showbase); std::transform( ints.begin(), ints.end(), std::back_inserter(strs), boost::convert(boost::cref(cnv))); BOOST_TEST(strs.size() == 3); BOOST_TEST(strs[0] == "0XF"); BOOST_TEST(strs[1] == "0X10"); BOOST_TEST(strs[2] == "0X11"); //] } void example::algorithms() { introduction(); example1(); example2(); example3(); example4(); example5(); }