1// See http://www.boost.org/libs/any for Documentation.
2
3#ifndef BOOST_ANY_INCLUDED
4#define BOOST_ANY_INCLUDED
5
6#if defined(_MSC_VER)
7# pragma once
8#endif
9
10// what: variant type boost::any
11// who: contributed by Kevlin Henney,
12// with features contributed and bugs found by
13// Antony Polukhin, Ed Brey, Mark Rodgers,
14// Peter Dimov, and James Curran
15// when: July 2001, April 2013 - May 2013
16
17#include <algorithm>
18
19#include <boost/config.hpp>
20#include <boost/type_index.hpp>
21#include <boost/type_traits/remove_reference.hpp>
22#include <boost/type_traits/decay.hpp>
23#include <boost/type_traits/remove_cv.hpp>
24#include <boost/type_traits/add_reference.hpp>
25#include <boost/type_traits/is_reference.hpp>
26#include <boost/type_traits/is_const.hpp>
27#include <boost/throw_exception.hpp>
28#include <boost/static_assert.hpp>
29#include <boost/utility/enable_if.hpp>
30#include <boost/core/addressof.hpp>
31#include <boost/type_traits/is_same.hpp>
32#include <boost/type_traits/is_const.hpp>
33#include <boost/mpl/if.hpp>
34
35namespace boost
36{
37 class any
38 {
39 public: // structors
40
41 any() BOOST_NOEXCEPT
42 : content(0)
43 {
44 }
45
46 template<typename ValueType>
47 any(const ValueType & value)
48 : content(new holder<
49 BOOST_DEDUCED_TYPENAME remove_cv<BOOST_DEDUCED_TYPENAME decay<const ValueType>::type>::type
50 >(value))
51 {
52 }
53
54 any(const any & other)
55 : content(other.content ? other.content->clone() : 0)
56 {
57 }
58
59#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
60 // Move constructor
61 any(any&& other) BOOST_NOEXCEPT
62 : content(other.content)
63 {
64 other.content = 0;
65 }
66
67 // Perfect forwarding of ValueType
68 template<typename ValueType>
69 any(ValueType&& value
70 , typename boost::disable_if<boost::is_same<any&, ValueType> >::type* = 0 // disable if value has type `any&`
71 , typename boost::disable_if<boost::is_const<ValueType> >::type* = 0) // disable if value has type `const ValueType&&`
72 : content(new holder< typename decay<ValueType>::type >(static_cast<ValueType&&>(value)))
73 {
74 }
75#endif
76
77 ~any() BOOST_NOEXCEPT
78 {
79 delete content;
80 }
81
82 public: // modifiers
83
84 any & swap(any & rhs) BOOST_NOEXCEPT
85 {
86 std::swap(content, rhs.content);
87 return *this;
88 }
89
90
91#ifdef BOOST_NO_CXX11_RVALUE_REFERENCES
92 template<typename ValueType>
93 any & operator=(const ValueType & rhs)
94 {
95 any(rhs).swap(*this);
96 return *this;
97 }
98
99 any & operator=(any rhs)
100 {
101 any(rhs).swap(*this);
102 return *this;
103 }
104
105#else
106 any & operator=(const any& rhs)
107 {
108 any(rhs).swap(*this);
109 return *this;
110 }
111
112 // move assignement
113 any & operator=(any&& rhs) BOOST_NOEXCEPT
114 {
115 rhs.swap(*this);
116 any().swap(rhs);
117 return *this;
118 }
119
120 // Perfect forwarding of ValueType
121 template <class ValueType>
122 any & operator=(ValueType&& rhs)
123 {
124 any(static_cast<ValueType&&>(rhs)).swap(*this);
125 return *this;
126 }
127#endif
128
129 public: // queries
130
131 bool empty() const BOOST_NOEXCEPT
132 {
133 return !content;
134 }
135
136 void clear() BOOST_NOEXCEPT
137 {
138 any().swap(*this);
139 }
140
141 const boost::typeindex::type_info& type() const BOOST_NOEXCEPT
142 {
143 return content ? content->type() : boost::typeindex::type_id<void>().type_info();
144 }
145
146#ifndef BOOST_NO_MEMBER_TEMPLATE_FRIENDS
147 private: // types
148#else
149 public: // types (public so any_cast can be non-friend)
150#endif
151
152 class placeholder
153 {
154 public: // structors
155
156 virtual ~placeholder()
157 {
158 }
159
160 public: // queries
161
162 virtual const boost::typeindex::type_info& type() const BOOST_NOEXCEPT = 0;
163
164 virtual placeholder * clone() const = 0;
165
166 };
167
168 template<typename ValueType>
169 class holder : public placeholder
170 {
171 public: // structors
172
173 holder(const ValueType & value)
174 : held(value)
175 {
176 }
177
178#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
179 holder(ValueType&& value)
180 : held(static_cast< ValueType&& >(value))
181 {
182 }
183#endif
184 public: // queries
185
186 virtual const boost::typeindex::type_info& type() const BOOST_NOEXCEPT
187 {
188 return boost::typeindex::type_id<ValueType>().type_info();
189 }
190
191 virtual placeholder * clone() const
192 {
193 return new holder(held);
194 }
195
196 public: // representation
197
198 ValueType held;
199
200 private: // intentionally left unimplemented
201 holder & operator=(const holder &);
202 };
203
204#ifndef BOOST_NO_MEMBER_TEMPLATE_FRIENDS
205
206 private: // representation
207
208 template<typename ValueType>
209 friend ValueType * any_cast(any *) BOOST_NOEXCEPT;
210
211 template<typename ValueType>
212 friend ValueType * unsafe_any_cast(any *) BOOST_NOEXCEPT;
213
214#else
215
216 public: // representation (public so any_cast can be non-friend)
217
218#endif
219
220 placeholder * content;
221
222 };
223
224 inline void swap(any & lhs, any & rhs) BOOST_NOEXCEPT
225 {
226 lhs.swap(rhs);
227 }
228
229 class BOOST_SYMBOL_VISIBLE bad_any_cast :
230#ifndef BOOST_NO_RTTI
231 public std::bad_cast
232#else
233 public std::exception
234#endif
235 {
236 public:
237 virtual const char * what() const BOOST_NOEXCEPT_OR_NOTHROW
238 {
239 return "boost::bad_any_cast: "
240 "failed conversion using boost::any_cast";
241 }
242 };
243
244 template<typename ValueType>
245 ValueType * any_cast(any * operand) BOOST_NOEXCEPT
246 {
247 return operand && operand->type() == boost::typeindex::type_id<ValueType>()
248 ? boost::addressof(
249 static_cast<any::holder<BOOST_DEDUCED_TYPENAME remove_cv<ValueType>::type> *>(operand->content)->held
250 )
251 : 0;
252 }
253
254 template<typename ValueType>
255 inline const ValueType * any_cast(const any * operand) BOOST_NOEXCEPT
256 {
257 return any_cast<ValueType>(const_cast<any *>(operand));
258 }
259
260 template<typename ValueType>
261 ValueType any_cast(any & operand)
262 {
263 typedef BOOST_DEDUCED_TYPENAME remove_reference<ValueType>::type nonref;
264
265
266 nonref * result = any_cast<nonref>(boost::addressof(operand));
267 if(!result)
268 boost::throw_exception(bad_any_cast());
269
270 // Attempt to avoid construction of a temporary object in cases when
271 // `ValueType` is not a reference. Example:
272 // `static_cast<std::string>(*result);`
273 // which is equal to `std::string(*result);`
274 typedef BOOST_DEDUCED_TYPENAME boost::mpl::if_<
275 boost::is_reference<ValueType>,
276 ValueType,
277 BOOST_DEDUCED_TYPENAME boost::add_reference<ValueType>::type
278 >::type ref_type;
279
280#ifdef BOOST_MSVC
281# pragma warning(push)
282# pragma warning(disable: 4172) // "returning address of local variable or temporary" but *result is not local!
283#endif
284 return static_cast<ref_type>(*result);
285#ifdef BOOST_MSVC
286# pragma warning(pop)
287#endif
288 }
289
290 template<typename ValueType>
291 inline ValueType any_cast(const any & operand)
292 {
293 typedef BOOST_DEDUCED_TYPENAME remove_reference<ValueType>::type nonref;
294 return any_cast<const nonref &>(const_cast<any &>(operand));
295 }
296
297#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
298 template<typename ValueType>
299 inline ValueType any_cast(any&& operand)
300 {
301 BOOST_STATIC_ASSERT_MSG(
302 boost::is_rvalue_reference<ValueType&&>::value /*true if ValueType is rvalue or just a value*/
303 || boost::is_const< typename boost::remove_reference<ValueType>::type >::value,
304 "boost::any_cast shall not be used for getting nonconst references to temporary objects"
305 );
306 return any_cast<ValueType>(operand);
307 }
308#endif
309
310
311 // Note: The "unsafe" versions of any_cast are not part of the
312 // public interface and may be removed at any time. They are
313 // required where we know what type is stored in the any and can't
314 // use typeid() comparison, e.g., when our types may travel across
315 // different shared libraries.
316 template<typename ValueType>
317 inline ValueType * unsafe_any_cast(any * operand) BOOST_NOEXCEPT
318 {
319 return boost::addressof(
320 static_cast<any::holder<ValueType> *>(operand->content)->held
321 );
322 }
323
324 template<typename ValueType>
325 inline const ValueType * unsafe_any_cast(const any * operand) BOOST_NOEXCEPT
326 {
327 return unsafe_any_cast<ValueType>(const_cast<any *>(operand));
328 }
329}
330
331// Copyright Kevlin Henney, 2000, 2001, 2002. All rights reserved.
332//
333// Distributed under the Boost Software License, Version 1.0. (See
334// accompanying file LICENSE_1_0.txt or copy at
335// http://www.boost.org/LICENSE_1_0.txt)
336
337#endif
338