1// Boost.Convert test and usage example
2// Copyright (c) 2009-2020 Vladimir Batov.
3// Use, modification and distribution are subject to the Boost Software License,
4// Version 1.0. See http://www.boost.org/LICENSE_1_0.txt.
5
6#include "./test.hpp"
7
8#if !defined(BOOST_CONVERT_CXX14)
9int main(int, char const* []) { return 0; }
10#else
11
12#include <boost/convert.hpp>
13#include <boost/convert/lexical_cast.hpp>
14#include <functional>
15
16using std::string;
17using boost::convert;
18using boost::lexical_cast;
19
20//[callable_example1
21void plain_old_func(string const& value_in, boost::optional<int>& value_out)
22//]
23{
24 try
25 {
26 value_out = lexical_cast<int>(value_in);
27 }
28 catch (...)
29 {
30 }
31}
32
33template<typename TypeIn, typename TypeOut>
34void
35convert_all(TypeIn const&, boost::optional<TypeOut>&)
36{
37}
38
39template<typename Type>
40void
41assign(boost::optional<Type>& value_out, Type const& value_in)
42{
43 value_out = value_in;
44}
45
46struct converter1
47{
48 template<typename TypeIn, typename TypeOut>
49 void
50 operator()(TypeIn const&, boost::optional<TypeOut>&) const
51 {
52 }
53};
54
55//[callable_example4
56struct take_double { void operator()(double, boost::optional<string>&) const {}};
57struct take_int { void operator()(int, boost::optional<string>&) const {}};
58//]
59
60//[callable_example6
61struct double_only
62{
63 // Declared for all types.
64 template<typename TypeIn> void operator()(TypeIn, boost::optional<string>&) const;
65};
66
67// Defined only for certain types.
68template<> void double_only::operator()<double>(double, boost::optional<string>&) const {}
69//]
70
71int
72main(int, char const* [])
73{
74 using func_type = std::function<void (string const& value_in, boost::optional<int>&)>;
75
76 char const* const str = "-12";
77
78 // Testing old-function-based converter.
79 //[callable_example2
80 int v01 = convert<int>(str, plain_old_func).value_or(-1);
81 //]
82 // Testing std::function-based converter.
83 int v02 = convert<int>(str, func_type(plain_old_func)).value_or(-1);
84 // Testing crazy std::bind-based converter.
85 //[callable_example3
86 int v03 = convert<int>(str,
87 std::bind(assign<int>, std::placeholders::_2,
88 std::bind(boost::lexical_cast<int, string>, std::placeholders::_1))).value_or(-1);
89 //]
90 BOOST_TEST(v01 == -12);
91 BOOST_TEST(v02 == -12);
92 BOOST_TEST(v03 == -12);
93
94 convert<int>(str, convert_all<string, int>);
95 convert<string>(11, convert_all<int, string>);
96 convert< int>(str, converter1());
97 convert<string>(11, converter1());
98 convert<string>(11.23, take_double());
99 convert<string>(11, take_int());
100 //[callable_example5
101 convert<string>(11, take_double()); // Compiler applies int-to-double promotion to call the converter.
102 convert<string>(11.23, take_int()); // Compiler applies double-to-int implicit truncation.
103 //]
104 //[callable_example7
105 convert<string>(11.23, double_only()); // Fine.
106// convert<string>(11, double_only()); // Fails: undefined reference to double_only::operator()<int>
107 //]
108
109 return boost::report_errors();
110}
111
112#endif
113

source code of boost/libs/convert/test/callable.cpp