1 // Copyright (c) 2009-2014 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 BOOST_MSVC
6 #  pragma warning(disable : 4127)  // conditional expression is constant.
7 #  pragma warning(disable : 4189)  // local variable is initialized but not referenced.
8 #endif
9 
10 #include <boost/convert.hpp>
11 #include <boost/convert/stream.hpp>
12 #include <boost/convert/lexical_cast.hpp>
13 
14 using std::string;
15 using boost::convert;
16 using boost::lexical_cast;
17 using boost::optional;
18 
process_failure()19 static void process_failure() {}
log(...)20 static void log(...) {}
fallback_function()21 static int fallback_function() { return -1; }
22 
23 //[getting_serious_default_converter
24 struct boost::cnv::by_default : public boost::cnv::cstream {};
25 //]
26 static
27 void
example1()28 example1()
29 {
30     boost::cnv::cstream  cnv;
31     std::string const    str = "123";
32     std::string const   str1 = "123";
33     std::string const   str2 = "123";
34     std::string const   str3 = "123";
35     int const fallback_value = -1;
36 
37     {
38         //[getting_serious_example1
39         int i2 = convert<int>("not an int", cnv).value_or(-1); // after the call i2==-1
40 
41         if (i2 == -1) process_failure();
42         //]
43     }
44     {
45         //[getting_serious_example2
46         try
47         {
48             int i1 = lexical_cast<int>(str);         // Throws if the conversion fails.
49             int i2 = convert<int>(str, cnv).value(); // Throws if the conversion fails.
50         }
51         catch (...)
52         {
53             process_failure();
54         }
55         //]
56     }
57     {
58         //[getting_serious_example3
59         optional<int> r1 = convert<int>(str1, cnv); // Does not throw on conversion failure.
60         optional<int> r2 = convert<int>(str2, cnv); // Does not throw on conversion failure.
61         // ...
62         try // Delayed processing of potential exceptions.
63         {
64             int i1 = r1.value(); // Will throw if conversion failed.
65             int i2 = r2.value(); // Will throw if conversion failed.
66         }
67         catch (boost::bad_optional_access const&)
68         {
69             // Handle failed conversion.
70         }
71 
72         // Exceptions are avoided altogether.
73         int i1 = r1 ? r1.value() : fallback_value;
74         int i2 = r2.value_or(fallback_value);
75         int i3 = convert<int>(str3, cnv).value_or(fallback_value);
76         int i4 = convert<int>(str3, cnv).value_or_eval(fallback_function);
77         //]
78     }
79 }
80 
81 //[getting_serious_example5
82 struct fallback_func
83 {
operator ()fallback_func84     int operator()() const { log("Failed to convert"); return 42; }
85 };
86 //]
87 
88 static
89 void
example4()90 example4()
91 {
92     boost::cnv::cstream  cnv;
93     std::string const    str = "123";
94     int const fallback_value = -1;
95     //[getting_serious_example4
96     boost::optional<int> res = boost::convert<int>(str, cnv);
97 
98     if (!res) log("str conversion failed!");
99 
100     int i1 = res.value_or(fallback_value);
101 
102     // ...proceed
103     //]
104     //[getting_serious_example6
105     // Fallback function is called when failed
106     int i2 = convert<int>(str, cnv).value_or_eval(fallback_func());
107     int i3 = convert<int>(str, cnv, fallback_func());
108     //]
109 }
110 
111 static
112 void
example7()113 example7()
114 {
115     boost::cnv::cstream  cnv;
116     std::string const    str = "123";
117     int const fallback_value = -1;
118     //[getting_serious_example7
119     // Error-processing behavior are specified unambiguously and uniformly.
120     // a) i1: Returns the provided fallback value;
121     // b) i2: Calls the provided failure-processing function;
122     // c) i3: Throws an exception.
123 
124     int i1 = convert<int>(str, cnv, fallback_value);
125     int i2 = convert<int>(str, cnv, fallback_func());
126 
127     try
128     {
129         // Throwing behavior specified explicitly rather than implied.
130         int i3 = convert<int>(str, cnv, boost::throw_on_failure);
131     }
132     catch (boost::bad_optional_access const&)
133     {
134       // Handle failed conversion.
135     }
136     //]
137     //[getting_serious_example8
138     int m1 = convert<int>(str, cnv).value_or(fallback_value);
139     int m2 = convert<int>(str, cnv).value_or_eval(fallback_func());
140     int m3 = convert<int>(str, cnv).value();
141     //]
142     //[getting_serious_example9
143     int n1 = convert<int>(str).value_or(fallback_value);
144     int n2 = convert<int>(str).value_or_eval(fallback_func());
145     int n3 = convert<int>(str).value();
146     //]
147 }
148 
149 int
main(int argc,char const * argv[])150 main(int argc, char const* argv[])
151 {
152     example1();
153     example4();
154     example7();
155 }
156