1 | // Boost.Convert test and usage example |
2 | // Copyright (c) 2009-2020 Vladimir Batov. |
3 | // Use, modification and distribution are subject to the Boost Software License, |
4 | // Version 1.0. See http://www.boost.org/LICENSE_1_0.txt. |
5 | |
6 | #include "./test.hpp" |
7 | |
8 | #if !defined(BOOST_CONVERT_CXX14) |
9 | int main(int, char const* []) { return 0; } |
10 | #else |
11 | |
12 | #include <boost/convert.hpp> |
13 | #include <boost/convert/lexical_cast.hpp> |
14 | #include <functional> |
15 | |
16 | using std::string; |
17 | using boost::convert; |
18 | using boost::lexical_cast; |
19 | |
20 | //[callable_example1 |
21 | void plain_old_func(string const& value_in, boost::optional<int>& value_out) |
22 | //] |
23 | { |
24 | try |
25 | { |
26 | value_out = lexical_cast<int>(value_in); |
27 | } |
28 | catch (...) |
29 | { |
30 | } |
31 | } |
32 | |
33 | template<typename TypeIn, typename TypeOut> |
34 | void |
35 | convert_all(TypeIn const&, boost::optional<TypeOut>&) |
36 | { |
37 | } |
38 | |
39 | template<typename Type> |
40 | void |
41 | assign(boost::optional<Type>& value_out, Type const& value_in) |
42 | { |
43 | value_out = value_in; |
44 | } |
45 | |
46 | struct converter1 |
47 | { |
48 | template<typename TypeIn, typename TypeOut> |
49 | void |
50 | operator()(TypeIn const&, boost::optional<TypeOut>&) const |
51 | { |
52 | } |
53 | }; |
54 | |
55 | //[callable_example4 |
56 | struct take_double { void operator()(double, boost::optional<string>&) const {}}; |
57 | struct take_int { void operator()(int, boost::optional<string>&) const {}}; |
58 | //] |
59 | |
60 | //[callable_example6 |
61 | struct double_only |
62 | { |
63 | // Declared for all types. |
64 | template<typename TypeIn> void operator()(TypeIn, boost::optional<string>&) const; |
65 | }; |
66 | |
67 | // Defined only for certain types. |
68 | template<> void double_only::operator()<double>(double, boost::optional<string>&) const {} |
69 | //] |
70 | |
71 | int |
72 | main(int, char const* []) |
73 | { |
74 | using func_type = std::function<void (string const& value_in, boost::optional<int>&)>; |
75 | |
76 | char const* const str = "-12" ; |
77 | |
78 | // Testing old-function-based converter. |
79 | //[callable_example2 |
80 | int v01 = convert<int>(str, plain_old_func).value_or(-1); |
81 | //] |
82 | // Testing std::function-based converter. |
83 | int v02 = convert<int>(str, func_type(plain_old_func)).value_or(-1); |
84 | // Testing crazy std::bind-based converter. |
85 | //[callable_example3 |
86 | int v03 = convert<int>(str, |
87 | std::bind(assign<int>, std::placeholders::_2, |
88 | std::bind(boost::lexical_cast<int, string>, std::placeholders::_1))).value_or(-1); |
89 | //] |
90 | BOOST_TEST(v01 == -12); |
91 | BOOST_TEST(v02 == -12); |
92 | BOOST_TEST(v03 == -12); |
93 | |
94 | convert<int>(str, convert_all<string, int>); |
95 | convert<string>(11, convert_all<int, string>); |
96 | convert< int>(str, converter1()); |
97 | convert<string>(11, converter1()); |
98 | convert<string>(11.23, take_double()); |
99 | convert<string>(11, take_int()); |
100 | //[callable_example5 |
101 | convert<string>(11, take_double()); // Compiler applies int-to-double promotion to call the converter. |
102 | convert<string>(11.23, take_int()); // Compiler applies double-to-int implicit truncation. |
103 | //] |
104 | //[callable_example7 |
105 | convert<string>(11.23, double_only()); // Fine. |
106 | // convert<string>(11, double_only()); // Fails: undefined reference to double_only::operator()<int> |
107 | //] |
108 | |
109 | return boost::report_errors(); |
110 | } |
111 | |
112 | #endif |
113 | |