]>
Commit | Line | Data |
---|---|---|
7c673cae | 1 | // Boost.Convert test and usage example |
20effc67 | 2 | // Copyright (c) 2009-2020 Vladimir Batov. |
7c673cae FG |
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 | ||
b32b8144 | 8 | #if defined(BOOST_CONVERT_IS_NOT_SUPPORTED) |
7c673cae FG |
9 | int main(int, char const* []) { return 0; } |
10 | #else | |
11 | ||
12 | #include <boost/convert.hpp> | |
13 | #include <boost/convert/lexical_cast.hpp> | |
20effc67 | 14 | #include <functional> |
7c673cae FG |
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 | { | |
20effc67 | 74 | typedef std::function<void (string const& value_in, boost::optional<int>&)> boost_func; |
7c673cae FG |
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 | //] | |
20effc67 | 82 | // Testing std::function-based converter. |
7c673cae | 83 | int v02 = convert<int>(str, boost_func(plain_old_func)).value_or(-1); |
20effc67 | 84 | // Testing crazy std::bind-based converter. |
7c673cae FG |
85 | //[callable_example3 |
86 | int v03 = convert<int>(str, | |
20effc67 TL |
87 | std::bind(assign<int>, std::placeholders::_2, |
88 | std::bind(boost::lexical_cast<int, string>, std::placeholders::_1))).value_or(-1); | |
7c673cae FG |
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 |