• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 #ifdef _MSC_VER
6 #  pragma warning(disable : 4127)  // conditional expression is constant.
7 #  pragma warning(disable : 4189)  // local variable is initialized but not referenced.
8 #  pragma warning(disable : 4100)  // unreferenced formal parameter.
9 #  pragma warning(disable : 4714)  // marked as __forceinline not inlined.
10 #endif
11 
12 namespace { namespace local
13 {
14 #if defined(_MSC_VER)
15     static bool const is_msc = true;
16 #else
17     static bool const is_msc = false;
18 #endif
19 }}
20 
21 #include <boost/bind.hpp>
22 #include <boost/detail/lightweight_test.hpp>
23 
24 static
25 void
log(char const *)26 log(char const*)
27 {
28   // Dummy function to demonstrate how problems might be logged.
29 }
30 
31 //[getting_started_headers1
32 #include <boost/convert.hpp>
33 #include <boost/convert/lexical_cast.hpp>
34 //]
35 
36 //[getting_started_using
37 using std::string;
38 using boost::lexical_cast;
39 using boost::convert;
40 //]
41 //[getting_started_default_converter
42 // Definition of the default converter (optional)
43 struct boost::cnv::by_default : boost::cnv::lexical_cast {};
44 //]
45 
46 static
47 void
getting_started_example1()48 getting_started_example1()
49 {
50     //[getting_started_example1
51     try
52     {
53         boost::cnv::lexical_cast cnv; // boost::lexical_cast-based converter
54 
55         int    i1 = lexical_cast<int>("123");          // boost::lexical_cast standard deployment
56         int    i2 = convert<int>("123").value();       // boost::convert with the default converter
57         int    i3 = convert<int>("123", cnv).value();  // boost::convert with an explicit converter
58         string s1 = lexical_cast<string>(123);         // boost::lexical_cast standard deployment
59         string s2 = convert<string>(123).value();      // boost::convert with the default converter
60         string s3 = convert<string>(123, cnv).value(); // boost::convert with an explicit converter
61 
62         BOOST_TEST(i1 == 123);
63         BOOST_TEST(i2 == 123);
64         BOOST_TEST(i3 == 123);
65         BOOST_TEST(s1 == "123");
66         BOOST_TEST(s2 == "123");
67         BOOST_TEST(s3 == "123");
68     }
69     catch (std::exception const& ex)
70     {
71         // Please be aware that the conversion requests above can fail.
72         // Use try'n'catch blocks to handle any exceptions thrown.
73         // Ignore this at your peril!
74         std::cerr << "Exception " << ex.what() << std::endl;
75     }
76     //] [/getting_started_example1]
77 }
78 
79 static
80 void
getting_started_example2()81 getting_started_example2()
82 {
83     //[getting_started_example2
84     // Does not throw. Returns fallback value (-1) when failed.
85     int i = convert<int>("uhm", boost::cnv::lexical_cast()).value_or(-1);
86 
87     BOOST_TEST(i == -1); // Conversion failed. 'i' assigned the fallback value.
88     //]
89 }
90 
91 //[getting_started_headers3
92 #include <boost/convert/strtol.hpp>
93 #include <boost/convert/spirit.hpp>
94 //]
95 
96 static
97 void
getting_started_example3()98 getting_started_example3()
99 {
100     //[getting_started_example3
101     boost::cnv::lexical_cast cnv1;
102     boost::cnv::strtol       cnv2;
103     boost::cnv::spirit       cnv3;
104 
105     int i1 = convert<int>("123", cnv1).value();
106     int i2 = convert<int>("123", cnv2).value(); // Two times faster than lexical_cast.
107     int i3 = convert<int>("123", cnv3).value(); // Four times faster than lexical_cast.
108     //]
109 }
110 
111 //[getting_started_headers4
112 #include <boost/convert/stream.hpp>
113 //]
114 
115 static
116 void
getting_started_example4()117 getting_started_example4()
118 {
119     //[getting_started_example4
120     boost::cnv::cstream cnv;
121 
122     try
123     {
124         int i1 = lexical_cast<int>("   123"); // Does not work.
125         BOOST_TEST(!"Never reached");
126     }
127     catch (...) {}
128 
129     int          i2 = convert<int>("   123", cnv(std::skipws)).value(); // Success
130     string       s1 = lexical_cast<string>(12.34567);
131     string       s2 = convert<string>(12.34567, cnv(std::fixed)(std::setprecision(3))).value();
132     string       s3 = convert<string>(12.34567, cnv(std::scientific)(std::setprecision(3))).value();
133     string expected = local::is_msc ? "1.235e+001" : "1.235e+01";
134 
135     BOOST_TEST(i2 == 123);        // boost::cnv::cstream. Successful conversion of "   123".
136     BOOST_TEST(s1 == "12.34567"); // boost::lexical_cast. Precision is not configurable.
137     BOOST_TEST(s2 == "12.346");   // boost::cnv::cstream. Precision was set to 3. Fixed.
138     BOOST_TEST(s3 == expected);   // boost::cnv::cstream. Precision was set to 3. Scientific.
139     //]
140 }
141 
142 static
143 void
getting_started_example5()144 getting_started_example5()
145 {
146     //[getting_started_example5
147     boost::cnv::cstream cnv;
148 
149     int i1 = lexical_cast<int>("123");              // Throws when conversion fails.
150     int i2 = convert<int>("123", cnv).value();      // Throws when conversion fails.
151     int i3 = convert<int>("uhm", cnv).value_or(-1); // Returns -1 when conversion fails.
152 
153     BOOST_TEST(i1 == 123);
154     BOOST_TEST(i2 == 123);
155     BOOST_TEST(i3 == -1);
156     //]
157 }
158 
159 static
160 void
getting_started_example6()161 getting_started_example6()
162 {
163     std::string const    s1 = "123";
164     std::string const    s2 = "456";
165     int const    default_i1 = 11;
166     int const    default_i2 = 12;
167     boost::cnv::cstream cnv;
168 
169     //[getting_started_example6
170 
171     int i1 = convert<int>(s1, cnv(std::hex)).value_or(-1); // Read as hex
172     int i2 = convert<int>(s2, cnv(std::dec)).value_or(-1); // Read as decimal
173 
174     if (i1 == -1) log("bad i1"), i1 = default_i1; // Log failure. Proceed with the default
175     if (i2 == -1) log("bad i2"), i2 = default_i2; // Log failure. Proceed with the default
176 
177     // ... proceed
178     //]
179     BOOST_TEST(i1 == 291);
180     BOOST_TEST(i2 == 456);
181 }
182 
183 static
184 void
getting_started_example7()185 getting_started_example7()
186 {
187     std::string const    s1 = "123";
188     std::string const    s2 = "456";
189     int const    default_i1 = 11;
190     int const    default_i2 = 12;
191     boost::cnv::cstream cnv;
192 
193     //[getting_started_example7
194 
195     int i1 = convert<int>(s1, cnv(std::hex)).value_or(default_i1); // If failed, proceed with the default
196     int i2 = convert<int>(s2, cnv(std::dec)).value_or(default_i2); // If failed, proceed with the default
197     // ... proceed
198     //]
199     BOOST_TEST(i1 == 291);
200     BOOST_TEST(i2 == 456);
201 }
202 
203 static
204 //[getting_started_example9_func
205 int
fallback_fun(char const * msg,int fallback_value)206 fallback_fun(char const* msg, int fallback_value)
207 {
208     // The principal advantage of a fallback_func over a fallback_value
209     // is that the former is only called when the conversion request fails.
210     // Consequently, the returned fallback_value is only calculated (which
211     // potentially might be expensive) when it is absolutely necessary.
212     log(msg); return fallback_value;
213 }
214 //]
215 static
216 void
getting_started_example9()217 getting_started_example9()
218 {
219     std::string const s1 = "123";
220     std::string const s2 = "456";
221     int const default_i1 = 11;
222     int const default_i2 = 12;
223 
224     //[getting_started_example9
225     int i1 = convert<int>(s1).value_or_eval(boost::bind(fallback_fun, "bad i1", default_i1));
226     int i2 = convert<int>(s2).value_or_eval(boost::bind(fallback_fun, "bad i2", default_i2));
227     // ... proceed
228     //]
229     BOOST_TEST(i1 == 123);
230     BOOST_TEST(i2 == 456);
231 }
232 
233 static
234 void
getting_started_example8()235 getting_started_example8()
236 {
237     std::string const str = "123";
238     int const  default_i1 = 12;
239     //[getting_started_example8
240     int i1 = default_i1;
241 
242     try
243     {
244         i1 = lexical_cast<int>(str);
245     }
246     catch (...)
247     {
248         log("bad i1");
249     }
250     //]
251     BOOST_TEST(i1 == 123);
252 }
253 
254 int
main(int,char const * [])255 main(int, char const* [])
256 {
257     getting_started_example1();
258     getting_started_example2();
259     getting_started_example3();
260     getting_started_example4();
261     getting_started_example5();
262     getting_started_example6();
263     getting_started_example7();
264     getting_started_example8();
265     getting_started_example9();
266 
267     return boost::report_errors();
268 }
269