]> git.proxmox.com Git - ceph.git/blob - ceph/src/boost/libs/leaf/examples/print_half.cpp
import quincy beta 17.1.0
[ceph.git] / ceph / src / boost / libs / leaf / examples / print_half.cpp
1 // Copyright (c) 2018-2020 Emil Dotchevski and Reverge Studios, Inc.
2
3 // Distributed under the Boost Software License, Version 1.0. (See accompanying
4 // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
5
6 // This program is an adaptation of the following Boost Outcome example:
7 // https://github.com/ned14/outcome/blob/master/doc/src/snippets/using_result.cpp
8
9 #include <boost/leaf/handle_errors.hpp>
10 #include <boost/leaf/pred.hpp>
11 #include <boost/leaf/result.hpp>
12 #include <algorithm>
13 #include <ctype.h>
14 #include <string>
15 #include <iostream>
16
17 namespace leaf = boost::leaf;
18
19 enum class ConversionErrc
20 {
21 EmptyString = 1,
22 IllegalChar,
23 TooLong
24 };
25
26 leaf::result<int> convert(const std::string& str) noexcept
27 {
28 if (str.empty())
29 return leaf::new_error(ConversionErrc::EmptyString);
30
31 if (!std::all_of(str.begin(), str.end(), ::isdigit))
32 return leaf::new_error(ConversionErrc::IllegalChar);
33
34 if (str.length() > 9)
35 return leaf::new_error(ConversionErrc::TooLong);
36
37 return atoi(str.c_str());
38 }
39
40 // Do not static_store BigInt to actually work -- it's a stub.
41 struct BigInt
42 {
43 static leaf::result<BigInt> fromString(const std::string& s) { return BigInt{s}; }
44 explicit BigInt(const std::string&) { }
45 BigInt half() const { return BigInt{""}; }
46 friend std::ostream& operator<<(std::ostream& o, const BigInt&) { return o << "big int half"; }
47 };
48
49 // This function handles ConversionErrc::TooLong errors, forwards any other error to the caller.
50 leaf::result<void> print_half(const std::string& text)
51 {
52 return leaf::try_handle_some(
53 [&]() -> leaf::result<void>
54 {
55 BOOST_LEAF_AUTO(r,convert(text));
56 std::cout << r / 2 << std::endl;
57 return { };
58 },
59 [&]( leaf::match<ConversionErrc, ConversionErrc::TooLong> ) -> leaf::result<void>
60 {
61 BOOST_LEAF_AUTO(i, BigInt::fromString(text));
62 std::cout << i.half() << std::endl;
63 return { };
64 } );
65 }
66
67 int main( int argc, char const * argv[] )
68 {
69 return leaf::try_handle_all(
70 [&]() -> leaf::result<int>
71 {
72 BOOST_LEAF_CHECK( print_half(argc<2 ? "" : argv[1]) );
73 std::cout << "ok" << std::endl;
74 return 0;
75 },
76
77 []( leaf::match<ConversionErrc, ConversionErrc::EmptyString> )
78 {
79 std::cerr << "Empty string!" << std::endl;
80 return 1;
81 },
82
83 []( leaf::match<ConversionErrc, ConversionErrc::IllegalChar> )
84 {
85 std::cerr << "Illegal char!" << std::endl;
86 return 2;
87 },
88
89 []( leaf::error_info const & unmatched )
90 {
91 // This will never execute in this program, but it would detect logic errors where an unknown error reaches main.
92 // In this case, we print diagnostic information.
93 std::cerr <<
94 "Unknown failure detected" << std::endl <<
95 "Cryptic diagnostic information follows" << std::endl <<
96 unmatched;
97 return 3;
98 } );
99 }
100
101 ////////////////////////////////////////
102
103 #ifdef BOOST_LEAF_NO_EXCEPTIONS
104
105 namespace boost
106 {
107 BOOST_LEAF_NORETURN void throw_exception( std::exception const & e )
108 {
109 std::cerr << "Terminating due to a C++ exception under BOOST_LEAF_NO_EXCEPTIONS: " << e.what();
110 std::terminate();
111 }
112
113 struct source_location;
114 BOOST_LEAF_NORETURN void throw_exception( std::exception const & e, boost::source_location const & )
115 {
116 throw_exception(e);
117 }
118 }
119
120 #endif