]> git.proxmox.com Git - ceph.git/blame - ceph/src/boost/libs/convert/example/algorithms.cpp
import new upstream nautilus stable release 14.2.8
[ceph.git] / ceph / src / boost / libs / convert / example / algorithms.cpp
CommitLineData
7c673cae
FG
1// Copyright (c) 2009-2016 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 <boost/array.hpp>
10#include <boost/bind.hpp>
11#include <vector>
12
13using std::string;
14
15static
16void
17introduction()
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 boost::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>(boost::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
42static
43void
44example1()
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 boost::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 boost::bind(boost::lexical_cast<int, string>, _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
68static
69void
70example2()
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 boost::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
89static
90void
91example3()
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 boost::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>(boost::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
120static
121void
122example4()
123{
124 boost::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>(boost::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 `boost::cref` (or `std::cref` in C++11).
140
141 It needs to be remembered that with standard algorithms the deployed converter needs to be
92f5a8d4
TL
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)]
7c673cae
FG
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 `boost::ref` or `boost::cref`.]
147 */
148//]
149}
150
151static
152void
153example5()
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 boost::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>(boost::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
175int
176main(int, char const* [])
177{
178 introduction();
179 example1();
180 example2();
181 example3();
182 example4();
183 example5();
184
185 return boost::report_errors();
186}