/work/workdir/UnpackedTarball/boost/boost/any.hpp
Line | Count | Source |
1 | | // See http://www.boost.org/libs/any for Documentation. |
2 | | |
3 | | #ifndef BOOST_ANY_INCLUDED |
4 | | #define BOOST_ANY_INCLUDED |
5 | | |
6 | | #include <boost/any/detail/config.hpp> |
7 | | |
8 | | #if !defined(BOOST_USE_MODULES) || defined(BOOST_ANY_INTERFACE_UNIT) |
9 | | |
10 | | /// \file boost/any.hpp |
11 | | /// \brief \copybrief boost::any |
12 | | |
13 | | #ifndef BOOST_ANY_INTERFACE_UNIT |
14 | | #include <boost/config.hpp> |
15 | | #ifdef BOOST_HAS_PRAGMA_ONCE |
16 | | # pragma once |
17 | | #endif |
18 | | |
19 | | #include <memory> // for std::addressof |
20 | | #include <type_traits> |
21 | | |
22 | | #include <boost/throw_exception.hpp> |
23 | | #include <boost/type_index.hpp> |
24 | | |
25 | | #endif // #ifndef BOOST_ANY_INTERFACE_UNIT |
26 | | |
27 | | // what: variant type boost::any |
28 | | // who: contributed by Kevlin Henney, |
29 | | // with features contributed and bugs found by |
30 | | // Antony Polukhin, Ed Brey, Mark Rodgers, |
31 | | // Peter Dimov, and James Curran |
32 | | // when: July 2001, April 2013 - 2020 |
33 | | |
34 | | #include <boost/any/bad_any_cast.hpp> |
35 | | #include <boost/any/fwd.hpp> |
36 | | #include <boost/any/detail/placeholder.hpp> |
37 | | |
38 | | namespace boost { |
39 | | |
40 | | BOOST_ANY_BEGIN_MODULE_EXPORT |
41 | | |
42 | | /// \brief A class whose instances can hold instances of any |
43 | | /// type that satisfies \forcedlink{ValueType} requirements. |
44 | | class any |
45 | | { |
46 | | public: |
47 | | |
48 | | /// \post this->empty() is true. |
49 | | constexpr any() noexcept |
50 | 0 | : content(0) |
51 | 0 | { |
52 | 0 | } |
53 | | |
54 | | /// Makes a copy of `value`, so |
55 | | /// that the initial content of the new instance is equivalent |
56 | | /// in both type and value to `value`. |
57 | | /// |
58 | | /// \throws std::bad_alloc or any exceptions arising from the copy |
59 | | /// constructor of the contained type. |
60 | | template<typename ValueType> |
61 | | any(const ValueType & value) |
62 | 0 | : content(new holder< |
63 | 0 | typename std::remove_cv<typename std::decay<const ValueType>::type>::type |
64 | 0 | >(value)) |
65 | 0 | { |
66 | 0 | static_assert( |
67 | 0 | !anys::detail::is_basic_any<ValueType>::value, |
68 | 0 | "boost::any shall not be constructed from boost::anys::basic_any" |
69 | 0 | ); |
70 | 0 | } Unexecuted instantiation: boost::any::any<boost::property_tree::string_path<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, boost::property_tree::id_translator<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > > > >(boost::property_tree::string_path<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, boost::property_tree::id_translator<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > > > const&) Unexecuted instantiation: boost::any::any<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > >(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&) |
71 | | |
72 | | /// Copy constructor that copies content of |
73 | | /// `other` into new instance, so that any content |
74 | | /// is equivalent in both type and value to the content of |
75 | | /// `other`, or empty if `other` is empty. |
76 | | /// |
77 | | /// \throws May fail with a `std::bad_alloc` |
78 | | /// exception or any exceptions arising from the copy |
79 | | /// constructor of the contained type. |
80 | | any(const any & other) |
81 | 0 | : content(other.content ? other.content->clone() : 0) |
82 | 0 | { |
83 | 0 | } |
84 | | |
85 | | /// Move constructor that moves content of |
86 | | /// `other` into new instance and leaves `other` empty. |
87 | | /// |
88 | | /// \post other->empty() is true |
89 | | /// \throws Nothing. |
90 | | any(any&& other) noexcept |
91 | | : content(other.content) |
92 | 0 | { |
93 | 0 | other.content = 0; |
94 | 0 | } |
95 | | |
96 | | /// Forwards `value`, so |
97 | | /// that the initial content of the new instance is equivalent |
98 | | /// in both type and value to `value` before the forward. |
99 | | /// |
100 | | /// \throws std::bad_alloc or any exceptions arising from the move or |
101 | | /// copy constructor of the contained type. |
102 | | template<typename ValueType> |
103 | | any(ValueType&& value |
104 | | , typename std::enable_if<!std::is_same<any&, ValueType>::value >::type* = 0 // disable if value has type `any&` |
105 | | , typename std::enable_if<!std::is_const<ValueType>::value >::type* = 0) // disable if value has type `const ValueType&&` |
106 | | : content(new holder< typename std::decay<ValueType>::type >(std::forward<ValueType>(value))) |
107 | | { |
108 | | static_assert( |
109 | | !anys::detail::is_basic_any<typename std::decay<ValueType>::type>::value, |
110 | | "boost::any shall not be constructed from boost::anys::basic_any" |
111 | | ); |
112 | | } |
113 | | |
114 | | /// Releases any and all resources used in management of instance. |
115 | | /// |
116 | | /// \throws Nothing. |
117 | | ~any() noexcept |
118 | 0 | { |
119 | 0 | delete content; |
120 | 0 | } |
121 | | |
122 | | public: // modifiers |
123 | | |
124 | | /// Exchange of the contents of `*this` and `rhs`. |
125 | | /// |
126 | | /// \returns `*this` |
127 | | /// \throws Nothing. |
128 | | any & swap(any & rhs) noexcept |
129 | 0 | { |
130 | 0 | placeholder* tmp = content; |
131 | 0 | content = rhs.content; |
132 | 0 | rhs.content = tmp; |
133 | 0 | return *this; |
134 | 0 | } |
135 | | |
136 | | /// Copies content of `rhs` into |
137 | | /// current instance, discarding previous content, so that the |
138 | | /// new content is equivalent in both type and value to the |
139 | | /// content of `rhs`, or empty if `rhs.empty()`. |
140 | | /// |
141 | | /// \throws std::bad_alloc |
142 | | /// or any exceptions arising from the copy constructor of the |
143 | | /// contained type. Assignment satisfies the strong guarantee |
144 | | /// of exception safety. |
145 | | any & operator=(const any& rhs) |
146 | 0 | { |
147 | 0 | any(rhs).swap(*this); |
148 | 0 | return *this; |
149 | 0 | } |
150 | | |
151 | | /// Moves content of `rhs` into |
152 | | /// current instance, discarding previous content, so that the |
153 | | /// new content is equivalent in both type and value to the |
154 | | /// content of `rhs` before move, or empty if |
155 | | /// `rhs.empty()`. |
156 | | /// |
157 | | /// \post `rhs->empty()` is true |
158 | | /// \throws Nothing. |
159 | | any & operator=(any&& rhs) noexcept |
160 | 0 | { |
161 | 0 | rhs.swap(*this); |
162 | 0 | any().swap(rhs); |
163 | 0 | return *this; |
164 | 0 | } |
165 | | |
166 | | /// Forwards `rhs`, |
167 | | /// discarding previous content, so that the new content of is |
168 | | /// equivalent in both type and value to |
169 | | /// `rhs` before forward. |
170 | | /// |
171 | | /// \throws std::bad_alloc |
172 | | /// or any exceptions arising from the move or copy constructor of the |
173 | | /// contained type. Assignment satisfies the strong guarantee |
174 | | /// of exception safety. |
175 | | template <class ValueType> |
176 | | any & operator=(ValueType&& rhs) |
177 | | { |
178 | | static_assert( |
179 | | !anys::detail::is_basic_any<typename std::decay<ValueType>::type>::value, |
180 | | "boost::anys::basic_any shall not be assigned into boost::any" |
181 | | ); |
182 | | any(std::forward<ValueType>(rhs)).swap(*this); |
183 | | return *this; |
184 | | } |
185 | | |
186 | | public: // queries |
187 | | |
188 | | /// \returns `true` if instance is empty, otherwise `false`. |
189 | | /// \throws Nothing. |
190 | | bool empty() const noexcept |
191 | 0 | { |
192 | 0 | return !content; |
193 | 0 | } |
194 | | |
195 | | /// \post this->empty() is true |
196 | | void clear() noexcept |
197 | 0 | { |
198 | 0 | any().swap(*this); |
199 | 0 | } |
200 | | |
201 | | /// \returns the `typeid` of the |
202 | | /// contained value if instance is non-empty, otherwise |
203 | | /// `typeid(void)`. |
204 | | /// |
205 | | /// Useful for querying against types known either at compile time or |
206 | | /// only at runtime. |
207 | | const boost::typeindex::type_info& type() const noexcept |
208 | 0 | { |
209 | 0 | return content ? content->type() : boost::typeindex::type_id<void>().type_info(); |
210 | 0 | } |
211 | | |
212 | | private: // types |
213 | | /// @cond |
214 | | class BOOST_SYMBOL_VISIBLE placeholder: public boost::anys::detail::placeholder |
215 | | { |
216 | | public: |
217 | | virtual placeholder * clone() const = 0; |
218 | | }; |
219 | | |
220 | | template<typename ValueType> |
221 | | class holder final |
222 | | : public placeholder |
223 | | { |
224 | | public: // structors |
225 | | |
226 | | holder(const ValueType & value) |
227 | 0 | : held(value) |
228 | 0 | { |
229 | 0 | } Unexecuted instantiation: boost::any::holder<boost::property_tree::string_path<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, boost::property_tree::id_translator<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > > > >::holder(boost::property_tree::string_path<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, boost::property_tree::id_translator<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > > > const&) Unexecuted instantiation: boost::any::holder<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > >::holder(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&) |
230 | | |
231 | | holder(ValueType&& value) |
232 | | : held(static_cast< ValueType&& >(value)) |
233 | | { |
234 | | } |
235 | | |
236 | | public: // queries |
237 | | |
238 | | const boost::typeindex::type_info& type() const noexcept override |
239 | 0 | { |
240 | 0 | return boost::typeindex::type_id<ValueType>().type_info(); |
241 | 0 | } Unexecuted instantiation: boost::any::holder<boost::property_tree::string_path<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, boost::property_tree::id_translator<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > > > >::type() const Unexecuted instantiation: boost::any::holder<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > >::type() const |
242 | | |
243 | | placeholder * clone() const BOOST_OVERRIDE |
244 | 0 | { |
245 | 0 | return new holder(held); |
246 | 0 | } Unexecuted instantiation: boost::any::holder<boost::property_tree::string_path<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, boost::property_tree::id_translator<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > > > >::clone() const Unexecuted instantiation: boost::any::holder<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > >::clone() const |
247 | | |
248 | | public: // representation |
249 | | |
250 | | ValueType held; |
251 | | |
252 | | private: // intentionally left unimplemented |
253 | | holder & operator=(const holder &); |
254 | | }; |
255 | | |
256 | | private: // representation |
257 | | template<typename ValueType> |
258 | | friend ValueType * unsafe_any_cast(any *) noexcept; |
259 | | |
260 | | friend class boost::anys::unique_any; |
261 | | |
262 | | placeholder * content; |
263 | | /// @endcond |
264 | | }; |
265 | | |
266 | | /// Exchange of the contents of `lhs` and `rhs`. |
267 | | /// \throws Nothing. |
268 | | inline void swap(any & lhs, any & rhs) noexcept |
269 | 0 | { |
270 | 0 | lhs.swap(rhs); |
271 | 0 | } |
272 | | |
273 | | /// @cond |
274 | | |
275 | | // Note: The "unsafe" versions of any_cast are not part of the |
276 | | // public interface and may be removed at any time. They are |
277 | | // required where we know what type is stored in the any and can't |
278 | | // use typeid() comparison, e.g., when our types may travel across |
279 | | // different shared libraries. |
280 | | template<typename ValueType> |
281 | | inline ValueType * unsafe_any_cast(any * operand) noexcept |
282 | | { |
283 | | return std::addressof( |
284 | | static_cast<any::holder<ValueType> *>(operand->content)->held |
285 | | ); |
286 | | } |
287 | | |
288 | | template<typename ValueType> |
289 | | inline const ValueType * unsafe_any_cast(const any * operand) noexcept |
290 | | { |
291 | | return boost::unsafe_any_cast<ValueType>(const_cast<any *>(operand)); |
292 | | } |
293 | | /// @endcond |
294 | | |
295 | | /// \returns Pointer to a ValueType stored in `operand`, nullptr if |
296 | | /// `operand` does not contain specified `ValueType`. |
297 | | template<typename ValueType> |
298 | | ValueType * any_cast(any * operand) noexcept |
299 | | { |
300 | | return operand && operand->type() == boost::typeindex::type_id<ValueType>() |
301 | | ? boost::unsafe_any_cast<typename std::remove_cv<ValueType>::type>(operand) |
302 | | : 0; |
303 | | } |
304 | | |
305 | | /// \returns Const pointer to a ValueType stored in `operand`, nullptr if |
306 | | /// `operand` does not contain specified `ValueType`. |
307 | | template<typename ValueType> |
308 | | inline const ValueType * any_cast(const any * operand) noexcept |
309 | | { |
310 | | return boost::any_cast<ValueType>(const_cast<any *>(operand)); |
311 | | } |
312 | | |
313 | | /// \returns ValueType stored in `operand` |
314 | | /// \throws boost::bad_any_cast if `operand` does not contain |
315 | | /// specified ValueType. |
316 | | template<typename ValueType> |
317 | | ValueType any_cast(any & operand) |
318 | | { |
319 | | using nonref = typename std::remove_reference<ValueType>::type; |
320 | | |
321 | | nonref * result = boost::any_cast<nonref>(std::addressof(operand)); |
322 | | if(!result) |
323 | | boost::throw_exception(bad_any_cast()); |
324 | | |
325 | | // Attempt to avoid construction of a temporary object in cases when |
326 | | // `ValueType` is not a reference. Example: |
327 | | // `static_cast<std::string>(*result);` |
328 | | // which is equal to `std::string(*result);` |
329 | | typedef typename std::conditional< |
330 | | std::is_reference<ValueType>::value, |
331 | | ValueType, |
332 | | typename std::add_lvalue_reference<ValueType>::type |
333 | | >::type ref_type; |
334 | | |
335 | | #ifdef BOOST_MSVC |
336 | | # pragma warning(push) |
337 | | # pragma warning(disable: 4172) // "returning address of local variable or temporary" but *result is not local! |
338 | | #endif |
339 | | return static_cast<ref_type>(*result); |
340 | | #ifdef BOOST_MSVC |
341 | | # pragma warning(pop) |
342 | | #endif |
343 | | } |
344 | | |
345 | | /// \returns `ValueType` stored in `operand` |
346 | | /// \throws boost::bad_any_cast if `operand` does not contain |
347 | | /// specified `ValueType`. |
348 | | template<typename ValueType> |
349 | | inline ValueType any_cast(const any & operand) |
350 | | { |
351 | | using nonref = typename std::remove_reference<ValueType>::type; |
352 | | return boost::any_cast<const nonref &>(const_cast<any &>(operand)); |
353 | | } |
354 | | |
355 | | /// \returns `ValueType` stored in `operand`, leaving the `operand` empty. |
356 | | /// \throws boost::bad_any_cast if `operand` does not contain |
357 | | /// specified `ValueType`. |
358 | | template<typename ValueType> |
359 | | inline ValueType any_cast(any&& operand) |
360 | | { |
361 | | static_assert( |
362 | | std::is_rvalue_reference<ValueType&&>::value /*true if ValueType is rvalue or just a value*/ |
363 | | || std::is_const< typename std::remove_reference<ValueType>::type >::value, |
364 | | "boost::any_cast shall not be used for getting nonconst references to temporary objects" |
365 | | ); |
366 | | return boost::any_cast<ValueType>(operand); |
367 | | } |
368 | | |
369 | | BOOST_ANY_END_MODULE_EXPORT |
370 | | |
371 | | } |
372 | | |
373 | | // Copyright Kevlin Henney, 2000, 2001, 2002. All rights reserved. |
374 | | // Copyright Antony Polukhin, 2013-2025. |
375 | | // |
376 | | // Distributed under the Boost Software License, Version 1.0. (See |
377 | | // accompanying file LICENSE_1_0.txt or copy at |
378 | | // http://www.boost.org/LICENSE_1_0.txt) |
379 | | |
380 | | #endif // #if !defined(BOOST_USE_MODULES) || defined(BOOST_ANY_INTERFACE_UNIT) |
381 | | |
382 | | #endif |