]> git.lyx.org Git - lyx.git/blob - boost/boost/any.hpp
Cmake build: Omit files with names not starting with aplha character.
[lyx.git] / boost / boost / any.hpp
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) && (_MSC_VER >= 1020)
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 #include <typeinfo>
19
20 #include "boost/config.hpp"
21 #include <boost/type_traits/remove_reference.hpp>
22 #include <boost/type_traits/decay.hpp>
23 #include <boost/type_traits/add_reference.hpp>
24 #include <boost/type_traits/is_reference.hpp>
25 #include <boost/type_traits/is_const.hpp>
26 #include <boost/throw_exception.hpp>
27 #include <boost/static_assert.hpp>
28 #include <boost/utility/enable_if.hpp>
29 #include <boost/type_traits/is_same.hpp>
30 #include <boost/type_traits/is_const.hpp>
31
32 // See boost/python/type_id.hpp
33 // TODO: add BOOST_TYPEID_COMPARE_BY_NAME to config.hpp
34 # if (defined(__GNUC__) && __GNUC__ >= 3) \
35  || defined(_AIX) \
36  || (   defined(__sgi) && defined(__host_mips)) \
37  || (defined(__hpux) && defined(__HP_aCC)) \
38  || (defined(linux) && defined(__INTEL_COMPILER) && defined(__ICC))
39 #  define BOOST_AUX_ANY_TYPE_ID_NAME
40 #include <cstring>
41 # endif 
42
43 #if defined(_MSC_VER) 
44 #pragma warning(push)
45 #pragma warning(disable: 4172) // Mistakenly warns: returning address of local variable or temporary
46 #endif
47
48 namespace boost
49 {
50     class any
51     {
52     public: // structors
53
54         any() BOOST_NOEXCEPT
55           : content(0)
56         {
57         }
58
59         template<typename ValueType>
60         any(const ValueType & value)
61           : content(new holder<BOOST_DEDUCED_TYPENAME decay<const ValueType>::type>(value))
62         {
63         }
64
65         any(const any & other)
66           : content(other.content ? other.content->clone() : 0)
67         {
68         }
69
70 #ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
71         // Move constructor
72         any(any&& other) BOOST_NOEXCEPT
73           : content(other.content)
74         {
75             other.content = 0;
76         }
77
78         // Perfect forwarding of ValueType
79         template<typename ValueType>
80         any(ValueType&& value
81             , typename boost::disable_if<boost::is_same<any&, ValueType> >::type* = 0 // disable if value has type `any&`
82             , typename boost::disable_if<boost::is_const<ValueType> >::type* = 0) // disable if value has type `const ValueType&&`
83           : content(new holder< typename decay<ValueType>::type >(static_cast<ValueType&&>(value)))
84         {
85         }
86 #endif
87
88         ~any() BOOST_NOEXCEPT
89         {
90             delete content;
91         }
92
93     public: // modifiers
94
95         any & swap(any & rhs) BOOST_NOEXCEPT
96         {
97             std::swap(content, rhs.content);
98             return *this;
99         }
100
101
102 #ifdef BOOST_NO_CXX11_RVALUE_REFERENCES
103         template<typename ValueType>
104         any & operator=(const ValueType & rhs)
105         {
106             any(rhs).swap(*this);
107             return *this;
108         }
109
110         any & operator=(any rhs)
111         {
112             any(rhs).swap(*this);
113             return *this;
114         }
115
116 #else 
117         any & operator=(const any& rhs)
118         {
119             any(rhs).swap(*this);
120             return *this;
121         }
122
123         // move assignement
124         any & operator=(any&& rhs) BOOST_NOEXCEPT
125         {
126             rhs.swap(*this);
127             any().swap(rhs);
128             return *this;
129         }
130
131         // Perfect forwarding of ValueType
132         template <class ValueType>
133         any & operator=(ValueType&& rhs)
134         {
135             any(static_cast<ValueType&&>(rhs)).swap(*this);
136             return *this;
137         }
138 #endif
139
140     public: // queries
141
142         bool empty() const BOOST_NOEXCEPT
143         {
144             return !content;
145         }
146
147         void clear() BOOST_NOEXCEPT
148         {
149             any().swap(*this);
150         }
151
152         const std::type_info & type() const BOOST_NOEXCEPT
153         {
154             return content ? content->type() : typeid(void);
155         }
156
157 #ifndef BOOST_NO_MEMBER_TEMPLATE_FRIENDS
158     private: // types
159 #else
160     public: // types (public so any_cast can be non-friend)
161 #endif
162
163         class placeholder
164         {
165         public: // structors
166
167             virtual ~placeholder()
168             {
169             }
170
171         public: // queries
172
173             virtual const std::type_info & type() const BOOST_NOEXCEPT = 0;
174
175             virtual placeholder * clone() const = 0;
176
177         };
178
179         template<typename ValueType>
180         class holder : public placeholder
181         {
182         public: // structors
183
184             holder(const ValueType & value)
185               : held(value)
186             {
187             }
188
189 #ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
190             holder(ValueType&& value)
191               : held(static_cast< ValueType&& >(value))
192             {
193             }
194 #endif
195         public: // queries
196
197             virtual const std::type_info & type() const BOOST_NOEXCEPT
198             {
199                 return typeid(ValueType);
200             }
201
202             virtual placeholder * clone() const
203             {
204                 return new holder(held);
205             }
206
207         public: // representation
208
209             ValueType held;
210
211         private: // intentionally left unimplemented
212             holder & operator=(const holder &);
213         };
214
215 #ifndef BOOST_NO_MEMBER_TEMPLATE_FRIENDS
216
217     private: // representation
218
219         template<typename ValueType>
220         friend ValueType * any_cast(any *) BOOST_NOEXCEPT;
221
222         template<typename ValueType>
223         friend ValueType * unsafe_any_cast(any *) BOOST_NOEXCEPT;
224
225 #else
226
227     public: // representation (public so any_cast can be non-friend)
228
229 #endif
230
231         placeholder * content;
232
233     };
234  
235     inline void swap(any & lhs, any & rhs) BOOST_NOEXCEPT
236     {
237         lhs.swap(rhs);
238     }
239
240     class BOOST_SYMBOL_VISIBLE bad_any_cast : public std::bad_cast
241     {
242     public:
243         virtual const char * what() const BOOST_NOEXCEPT_OR_NOTHROW
244         {
245             return "boost::bad_any_cast: "
246                    "failed conversion using boost::any_cast";
247         }
248     };
249
250     template<typename ValueType>
251     ValueType * any_cast(any * operand) BOOST_NOEXCEPT
252     {
253         return operand && 
254 #ifdef BOOST_AUX_ANY_TYPE_ID_NAME
255             std::strcmp(operand->type().name(), typeid(ValueType).name()) == 0
256 #else
257             operand->type() == typeid(ValueType)
258 #endif
259             ? &static_cast<any::holder<ValueType> *>(operand->content)->held
260             : 0;
261     }
262
263     template<typename ValueType>
264     inline const ValueType * any_cast(const any * operand) BOOST_NOEXCEPT
265     {
266         return any_cast<ValueType>(const_cast<any *>(operand));
267     }
268
269     template<typename ValueType>
270     ValueType any_cast(any & operand)
271     {
272         typedef BOOST_DEDUCED_TYPENAME remove_reference<ValueType>::type nonref;
273
274 #ifdef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
275         // If 'nonref' is still reference type, it means the user has not
276         // specialized 'remove_reference'.
277
278         // Please use BOOST_BROKEN_COMPILER_TYPE_TRAITS_SPECIALIZATION macro
279         // to generate specialization of remove_reference for your class
280         // See type traits library documentation for details
281         BOOST_STATIC_ASSERT(!is_reference<nonref>::value);
282 #endif
283
284         nonref * result = any_cast<nonref>(&operand);
285         if(!result)
286             boost::throw_exception(bad_any_cast());
287
288         // Attempt to avoid construction of a temporary object in cases when 
289         // `ValueType` is not a reference. Example:
290         // `static_cast<std::string>(*result);` 
291         // which is equal to `std::string(*result);`
292         typedef BOOST_DEDUCED_TYPENAME boost::mpl::if_<
293             boost::is_reference<ValueType>,
294             ValueType,
295             BOOST_DEDUCED_TYPENAME boost::add_reference<ValueType>::type
296         >::type ref_type;
297
298         return static_cast<ref_type>(*result);
299     }
300
301     template<typename ValueType>
302     inline ValueType any_cast(const any & operand)
303     {
304         typedef BOOST_DEDUCED_TYPENAME remove_reference<ValueType>::type nonref;
305
306 #ifdef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
307         // The comment in the above version of 'any_cast' explains when this
308         // assert is fired and what to do.
309         BOOST_STATIC_ASSERT(!is_reference<nonref>::value);
310 #endif
311
312         return any_cast<const nonref &>(const_cast<any &>(operand));
313     }
314
315 #ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
316     template<typename ValueType>
317     inline ValueType&& any_cast(any&& operand)
318     {
319         BOOST_STATIC_ASSERT_MSG(
320             boost::is_rvalue_reference<ValueType&&>::value 
321             || boost::is_const< typename boost::remove_reference<ValueType>::type >::value,
322             "boost::any_cast shall not be used for getting nonconst references to temporary objects" 
323         );
324         return any_cast<ValueType&&>(operand);
325     }
326 #endif
327
328
329     // Note: The "unsafe" versions of any_cast are not part of the
330     // public interface and may be removed at any time. They are
331     // required where we know what type is stored in the any and can't
332     // use typeid() comparison, e.g., when our types may travel across
333     // different shared libraries.
334     template<typename ValueType>
335     inline ValueType * unsafe_any_cast(any * operand) BOOST_NOEXCEPT
336     {
337         return &static_cast<any::holder<ValueType> *>(operand->content)->held;
338     }
339
340     template<typename ValueType>
341     inline const ValueType * unsafe_any_cast(const any * operand) BOOST_NOEXCEPT
342     {
343         return unsafe_any_cast<ValueType>(const_cast<any *>(operand));
344     }
345 }
346
347 // Copyright Kevlin Henney, 2000, 2001, 2002. All rights reserved.
348 //
349 // Distributed under the Boost Software License, Version 1.0. (See
350 // accompanying file LICENSE_1_0.txt or copy at
351 // http://www.boost.org/LICENSE_1_0.txt)
352
353 #if defined(_MSC_VER)
354 #pragma warning(pop)
355 #endif
356
357 #endif