]> git.proxmox.com Git - ceph.git/blob - ceph/src/boost/libs/convert/example/algorithms.cpp
import quincy beta 17.1.0
[ceph.git] / ceph / src / boost / libs / convert / example / algorithms.cpp
1 // Copyright (c) 2009-2020 Vladimir Batov.
2 // Use, modification and distribution are subject to the Boost Software License,
3 // Version 1.0. See http://www.boost.org/LICENSE_1_0.txt.
4
5 #include <boost/convert.hpp>
6 #include <boost/convert/stream.hpp>
7 #include <boost/convert/lexical_cast.hpp>
8 #include <boost/detail/lightweight_test.hpp>
9 #include <array>
10 #include <vector>
11 #include <functional>
12
13 using std::string;
14
15 static
16 void
17 introduction()
18 {
19 //[algorithm_introduction
20
21 /*`The following code demonstrates conversion of an array of integers from their textual ['hexadecimal]
22 representation. It assigns -1 to those which fail to convert:
23 */
24
25 std::array<char const*, 3> strs = {{ " 5", "0XF", "not an int" }};
26 std::vector<int> ints;
27 boost::cnv::cstream cnv;
28
29 // Configure converter to read hexadecimal, skip (leading) white spaces.
30 cnv(std::hex)(std::skipws);
31
32 std::transform(strs.begin(), strs.end(), std::back_inserter(ints),
33 boost::cnv::apply<int>(std::cref(cnv)).value_or(-1));
34
35 BOOST_TEST(ints.size() == 3); // Number of values processed.
36 BOOST_TEST(ints[0] == 5); // " 5"
37 BOOST_TEST(ints[1] == 15); // "0XF"
38 BOOST_TEST(ints[2] == -1); // "not an int"
39 //]
40 }
41
42 static
43 void
44 example1()
45 {
46 //[algorithm_example1
47 /*`The following code demonstrates a failed attempt (and one of the reasons ['Boost.Convert]
48 has been developed) to convert a few `string`s to `int`s with `boost::lexical_cast`:
49 */
50
51 std::array<char const*, 3> strs = {{ " 5", "0XF", "not an int" }};
52 std::vector<int> ints;
53
54 try
55 {
56 std::transform(strs.begin(), strs.end(), std::back_inserter(ints),
57 std::bind(boost::lexical_cast<int, string>, std::placeholders::_1));
58
59 BOOST_TEST(0 && "Never reached!");
60 }
61 catch (std::exception&)
62 {
63 BOOST_TEST(ints.size() == 0); // No strings converted.
64 }
65 //]
66 }
67
68 static
69 void
70 example2()
71 {
72 //[algorithm_example2
73 /*`If the exception-throwing behavior is the desired behavior, then ['Boost.Convert] supports that.
74 In addition, it also supports a non-throwing process-flow:
75 */
76 std::array<char const*, 3> strs = {{ " 5", "0XF", "not an int" }};
77 std::vector<int> ints;
78
79 std::transform(strs.begin(), strs.end(), std::back_inserter(ints),
80 boost::cnv::apply<int>(boost::cnv::lexical_cast()).value_or(-1));
81
82 BOOST_TEST(ints.size() == 3);
83 BOOST_TEST(ints[0] == -1); // Failed conversion does not throw.
84 BOOST_TEST(ints[1] == -1); // Failed conversion does not throw.
85 BOOST_TEST(ints[2] == -1); // Failed conversion does not throw.
86 //]
87 }
88
89 static
90 void
91 example3()
92 {
93 //[algorithm_example3
94 /*`Deploying `boost::cnv::cstream` with better formatting capabilities yields
95 better results with exception-throwing and non-throwing process-flows still supported:
96 */
97
98 std::array<char const*, 3> strs = {{ " 5", "0XF", "not an int" }};
99 std::vector<int> ints;
100 boost::cnv::cstream cnv;
101
102 try
103 {
104 std::transform(strs.begin(), strs.end(), std::back_inserter(ints),
105 boost::cnv::apply<int>(std::cref(cnv(std::hex)(std::skipws))));
106
107 BOOST_TEST(0 && "Never reached!");
108 }
109 catch (boost::bad_optional_access const&)
110 {
111 BOOST_TEST(ints.size() == 2); // Only the first two strings converted.
112 BOOST_TEST(ints[0] == 5); // " 5"
113 BOOST_TEST(ints[1] == 15); // "0XF"
114
115 // "not an int" causes the exception thrown.
116 }
117 //]
118 }
119
120 static
121 void
122 example4()
123 {
124 std::array<char const*, 3> strs = {{ " 5", "0XF", "not an int" }};
125 std::vector<int> ints;
126 boost::cnv::cstream cnv;
127
128 //[algorithm_example4
129
130 std::transform(strs.begin(), strs.end(), std::back_inserter(ints),
131 boost::cnv::apply<int>(std::cref(cnv(std::hex)(std::skipws))).value_or(-1));
132
133 BOOST_TEST(ints.size() == 3);
134 BOOST_TEST(ints[0] == 5);
135 BOOST_TEST(ints[1] == 15);
136 BOOST_TEST(ints[2] == -1); // Failed conversion
137
138 /*`[important One notable difference in the deployment of `boost::cnv::cstream` with algorithms is
139 the use of `std::cref`.
140
141 It needs to be remembered that with standard algorithms the deployed converter needs to be
142 [@http://en.cppreference.com/w/cpp/named_req/TriviallyCopyable copyable] or
143 [@http://en.cppreference.com/w/cpp/named_req/MoveAssignable movable (C++11)]
144 and is, in fact, copied or moved by the respective algorithm before being used.
145 Given that `std::cstringstream` is not copyable, `boost::cnv::cstream` is not copyable either.
146 That limitation is routinely worked-around using `std::ref` or `std::cref`.]
147 */
148 //]
149 }
150
151 static
152 void
153 example5()
154 {
155 //[algorithm_example5
156 /*`And now an example of algorithm-based integer-to-string formatted conversion with
157 `std::hex`, `std::uppercase` and `std::showbase` formatting applied:
158 */
159 std::array<int, 3> ints = {{ 15, 16, 17 }};
160 std::vector<std::string> strs;
161 boost::cnv::cstream cnv;
162
163 cnv(std::hex)(std::uppercase)(std::showbase);
164
165 std::transform(ints.begin(), ints.end(), std::back_inserter(strs),
166 boost::cnv::apply<string>(std::cref(cnv)));
167
168 BOOST_TEST(strs.size() == 3);
169 BOOST_TEST(strs[0] == "0XF"); // 15
170 BOOST_TEST(strs[1] == "0X10"); // 16
171 BOOST_TEST(strs[2] == "0X11"); // 17
172 //]
173 }
174
175 int
176 main(int, char const* [])
177 {
178 introduction();
179 example1();
180 example2();
181 example3();
182 example4();
183 example5();
184
185 return boost::report_errors();
186 }