]> git.proxmox.com Git - ceph.git/blame - ceph/src/boost/boost/convert.hpp
import quincy beta 17.1.0
[ceph.git] / ceph / src / boost / boost / convert.hpp
CommitLineData
7c673cae
FG
1/// @file
2// Boost.Convert
20effc67 3// Copyright (c) 2009-2020 Vladimir Batov.
7c673cae
FG
4//
5// Many thanks to Julian Gonggrijp, Rob Stewart, Andrzej Krzemienski, Matus Chochlik, Jeroen Habraken,
6// Hartmut Kaiser, Joel De Guzman, Thijs (M.A.) van den Berg, Roland Bock, Gavin Lambert, Paul Bristow,
7// Alex Hagen-Zanker, Christopher Kormanyos for taking part in the Boost.Convert review.
8//
9// Special thanks to:
10//
11// 1. Alex Hagen-Zanker, Roland Bock, Rob Stewart for their considerable contributions to the design
12// and implementation of the library;
13// 2. Andrzej Krzemienski for helping to partition responsibilities and to ultimately pave
14// the way for the boost::optional and future std::tr2::optional deployment;
15// 3. Edward Diener the Boost Review Manager for helping with the converters' design, his continuous
16// involvement, technical and administrative help, guidance and advice;
17// 4. Joel De Guzman, Rob Stewart and Alex Hagen-Zanker for making sure the performance tests work
18// as they should;
19// 5. Paul Bristow for helping great deal with the documentation;
20// 6. Kevlin Henney and Dave Abrahams for their lexical_cast-related insights and explanations.
b32b8144 21//
7c673cae
FG
22// Use, modification and distribution are subject to the Boost Software License,
23// Version 1.0. See http://www.boost.org/LICENSE_1_0.txt.
24
25#ifndef BOOST_CONVERT_HPP
26#define BOOST_CONVERT_HPP
27
28#include <boost/convert/detail/is_fun.hpp>
20effc67 29#include <boost/core/ref.hpp>
7c673cae
FG
30
31namespace boost
32{
33 namespace detail { enum throw_on_failure {}; }
34
b32b8144
FG
35 /// @details boost::throw_on_failure is the 'tag' object
36 /// to request the exception-throwing behavior.
7c673cae
FG
37 detail::throw_on_failure const throw_on_failure = detail::throw_on_failure(0);
38
39 namespace cnv
40 {
41 template<typename, typename, typename> struct reference;
42 struct by_default;
43 }
44
45 /// @brief Boost.Convert main deployment interface
b32b8144 46 /// @param[in] value_in Value of the TypeIn type to be converted to the TypeOut type
7c673cae
FG
47 /// @param[in] converter Converter to be used for conversion
48 /// @return boost::optional<TypeOut> result of conversion together with the indication of
49 /// success or failure of the conversion request.
50 /// @details For example,
51 /// @code
52 /// boost::cnv::cstream cnv;
53 ///
54 /// boost::optional<int> i = boost::convert<int>("12", cnv);
55 /// boost::optional<string> s = boost::convert<string>(123.456, cnv);
56 /// @endcode
57
58 template<typename TypeOut, typename TypeIn, typename Converter>
59 boost::optional<TypeOut>
60 convert(TypeIn const& value_in, Converter const& converter)
61 {
62 optional<TypeOut> result;
63 boost::unwrap_ref(converter)(value_in, result);
64 return result;
65 }
66
67 namespace cnv { namespace detail
68 {
69 template<typename TypeOut, typename TypeIn, typename Converter =boost::cnv::by_default>
70 struct delayed_resolution
71 {
72 static optional<TypeOut> convert(TypeIn const& value_in)
73 {
74 return boost::convert<TypeOut>(value_in, Converter());
75 }
76 };
77 }}
78 /// @brief Boost.Convert deployment interface with the default converter
79 /// @details For example,
80 /// @code
b32b8144 81 /// struct boost::cnv::by_default : boost::cnv::cstream {};
7c673cae
FG
82 ///
83 /// // boost::cnv::cstream (through boost::cnv::by_default) is deployed
84 /// // as the default converter when no converter is provided explicitly.
85 /// boost::optional<int> i = boost::convert<int>("12");
86 /// boost::optional<string> s = boost::convert<string>(123.456);
87 /// @endcode
88
89 template<typename TypeOut, typename TypeIn>
90 boost::optional<TypeOut>
91 convert(TypeIn const& value_in)
92 {
93 return cnv::detail::delayed_resolution<TypeOut, TypeIn>::convert(value_in);
94 }
95}
96
97namespace boost
98{
99 /// @brief Boost.Convert non-optional deployment interface
100
101 template<typename TypeOut, typename TypeIn, typename Converter>
102 TypeOut
103 convert(TypeIn const& value_in, Converter const& converter, boost::detail::throw_on_failure)
104 {
105 return convert<TypeOut>(value_in, converter).value();
106 }
107
108 template<typename TypeOut, typename TypeIn, typename Converter, typename Fallback>
20effc67 109 typename std::enable_if<is_convertible<Fallback, TypeOut>::value, TypeOut>::type
7c673cae
FG
110 convert(TypeIn const& value_in, Converter const& converter, Fallback const& fallback)
111 {
112 return convert<TypeOut>(value_in, converter).value_or(fallback);
113 }
114
115 template<typename TypeOut, typename TypeIn, typename Converter, typename Fallback>
20effc67 116 typename std::enable_if<cnv::is_fun<Fallback, TypeOut>::value, TypeOut>::type
7c673cae
FG
117 convert(TypeIn const& value_in, Converter const& converter, Fallback fallback)
118 {
119 return convert<TypeOut>(value_in, converter).value_or_eval(fallback);
120 }
121}
122
123namespace boost { namespace cnv
124{
125 template<typename Converter, typename TypeOut, typename TypeIn>
126 struct reference
127 {
20effc67 128 using this_type = reference;
7c673cae 129
20effc67
TL
130 reference (Converter const& cnv) : converter_(cnv) {}
131 reference (Converter&& cnv) : converter_(std::move(cnv)) {}
7c673cae
FG
132
133 this_type&
134 value_or(TypeOut const& fallback)
135 {
136 return (fallback_ = fallback, *this);
137 }
138
139 TypeOut
20effc67 140 operator()(TypeIn const& value_in) const
7c673cae
FG
141 {
142 optional<TypeOut> result = convert<TypeOut>(value_in, converter_);
143 return result ? result.get() : fallback_.value();
144 }
145
146 private:
147
148 Converter converter_;
149 optional<TypeOut> fallback_;
150 };
151 template<typename Converter, typename TypeOut>
152 struct reference<Converter, TypeOut, void>
153 {
20effc67 154 using this_type = reference;
7c673cae 155
20effc67
TL
156 reference (Converter const& cnv) : converter_(cnv) {}
157 reference (Converter&& cnv) : converter_(std::move(cnv)) {}
7c673cae
FG
158
159 this_type&
160 value_or(TypeOut const& fallback)
161 {
162 return (fallback_ = fallback, *this);
163 }
164
165 template<typename TypeIn>
166 TypeOut
20effc67 167 operator()(TypeIn const& value_in) const
7c673cae
FG
168 {
169 optional<TypeOut> result = convert<TypeOut>(value_in, converter_);
170 return result ? result.get() : fallback_.value();
171 }
172
173 private:
174
175 Converter converter_;
176 optional<TypeOut> fallback_;
177 };
178
179 /// @brief Boost.Convert deployment interface with algorithms
180 /// @details For example,
181 /// @code
20effc67
TL
182 /// std::array<char const*, 3> strs = {{ " 5", "0XF", "not an int" }};
183 /// std::vector<int> ints;
184 /// boost::cnv::cstream cnv;
7c673cae
FG
185 ///
186 /// cnv(std::hex)(std::skipws);
187 ///
188 /// std::transform(
189 /// strs.begin(),
190 /// strs.end(),
191 /// std::back_inserter(ints),
20effc67 192 /// boost::cnv::apply<int>(std::cref(cnv)).value_or(-1));
7c673cae
FG
193 /// @endcode
194
195 template<typename TypeOut, typename TypeIn, typename Converter>
196 reference<Converter, TypeOut, TypeIn>
197 apply(Converter const& cnv)
198 {
199 return cnv::reference<Converter, TypeOut, TypeIn>(cnv);
200 }
201 template<typename TypeOut, typename Converter>
202 reference<Converter, TypeOut, void>
203 apply(Converter const& cnv)
204 {
205 return cnv::reference<Converter, TypeOut, void>(cnv);
206 }
207}}
208
209#endif // BOOST_CONVERT_HPP