• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Boost.Convert test and usage example
2 // Copyright (c) 2009-2016 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_IS_NOT_SUPPORTED)
main(int,char const * [])9 int main(int, char const* []) { return 0; }
10 #else
11 
12 #include <boost/convert.hpp>
13 #include <boost/convert/lexical_cast.hpp>
14 #include <boost/detail/lightweight_test.hpp>
15 #include <boost/function.hpp>
16 #include <boost/bind.hpp>
17 
18 using std::string;
19 using boost::convert;
20 using boost::lexical_cast;
21 
22 //[callable_example1
plain_old_func(string const & value_in,boost::optional<int> & value_out)23 void plain_old_func(string const& value_in, boost::optional<int>& value_out)
24 //]
25 {
26     try
27     {
28         value_out = lexical_cast<int>(value_in);
29     }
30     catch (...)
31     {
32     }
33 }
34 
35 template<typename TypeIn, typename TypeOut>
36 void
convert_all(TypeIn const &,boost::optional<TypeOut> &)37 convert_all(TypeIn const&, boost::optional<TypeOut>&)
38 {
39 }
40 
41 template<typename Type>
42 void
assign(boost::optional<Type> & value_out,Type const & value_in)43 assign(boost::optional<Type>& value_out, Type const& value_in)
44 {
45     value_out = value_in;
46 }
47 
48 struct converter1
49 {
50     template<typename TypeIn, typename TypeOut>
51     void
operator ()converter152     operator()(TypeIn const&, boost::optional<TypeOut>&) const
53     {
54     }
55 };
56 
57 //[callable_example4
operator ()take_double58 struct take_double { void operator()(double, boost::optional<string>&) const {}};
operator ()take_int59 struct    take_int { void operator()(int, boost::optional<string>&) const {}};
60 //]
61 
62 //[callable_example6
63 struct double_only
64 {
65     // Declared for all types.
66     template<typename TypeIn> void operator()(TypeIn, boost::optional<string>&) const;
67 };
68 
69 // Defined only for certain types.
operator()70 template<> void double_only::operator()<double>(double, boost::optional<string>&) const {}
71 //]
72 
73 int
main(int,char const * [])74 main(int, char const* [])
75 {
76     typedef boost::function<void (string const& value_in, boost::optional<int>&)> boost_func;
77 
78     char const* const str = "-12";
79 
80     // Testing old-function-based converter.
81     //[callable_example2
82     int v01 = convert<int>(str, plain_old_func).value_or(-1);
83     //]
84     // Testing boost::function-based converter.
85     int v02 = convert<int>(str, boost_func(plain_old_func)).value_or(-1);
86     // Testing crazy boost::bind-based converter.
87     //[callable_example3
88     int v03 = convert<int>(str,
89                   boost::bind(assign<int>, _2,
90                       boost::bind(lexical_cast<int, string>, _1))).value_or(-1);
91     //]
92     BOOST_TEST(v01 == -12);
93     BOOST_TEST(v02 == -12);
94     BOOST_TEST(v03 == -12);
95 
96     convert<int>(str, convert_all<string, int>);
97     convert<string>(11, convert_all<int, string>);
98     convert<   int>(str,   converter1());
99     convert<string>(11,    converter1());
100     convert<string>(11.23, take_double());
101     convert<string>(11,    take_int());
102     //[callable_example5
103     convert<string>(11, take_double()); // Compiler applies int-to-double promotion to call the converter.
104     convert<string>(11.23, take_int()); // Compiler applies double-to-int implicit truncation.
105     //]
106     //[callable_example7
107     convert<string>(11.23, double_only()); // Fine.
108 //  convert<string>(11,    double_only()); // Fails: undefined reference to double_only::operator()<int>
109     //]
110 
111     return boost::report_errors();
112 }
113 
114 #endif
115