source: NonGTP/Boost/boost/any.hpp @ 857

Revision 857, 6.1 KB checked in by igarcia, 19 years ago (diff)
Line 
1// See http://www.boost.org/libs/any for Documentation.
2
3#ifndef BOOST_ANY_INCLUDED
4#define BOOST_ANY_INCLUDED
5
6// what:  variant type boost::any
7// who:   contributed by Kevlin Henney,
8//        with features contributed and bugs found by
9//        Ed Brey, Mark Rodgers, Peter Dimov, and James Curran
10// when:  July 2001
11// where: tested with BCC 5.5, MSVC 6.0, and g++ 2.95
12
13#include <algorithm>
14#include <typeinfo>
15
16#include "boost/config.hpp"
17#include <boost/type_traits/remove_reference.hpp>
18#include <boost/type_traits/is_reference.hpp>
19#include <boost/throw_exception.hpp>
20#include <boost/static_assert.hpp>
21
22namespace boost
23{
24    class any
25    {
26    public: // structors
27
28        any()
29          : content(0)
30        {
31        }
32
33        template<typename ValueType>
34        any(const ValueType & value)
35          : content(new holder<ValueType>(value))
36        {
37        }
38
39        any(const any & other)
40          : content(other.content ? other.content->clone() : 0)
41        {
42        }
43
44        ~any()
45        {
46            delete content;
47        }
48
49    public: // modifiers
50
51        any & swap(any & rhs)
52        {
53            std::swap(content, rhs.content);
54            return *this;
55        }
56
57        template<typename ValueType>
58        any & operator=(const ValueType & rhs)
59        {
60            any(rhs).swap(*this);
61            return *this;
62        }
63
64        any & operator=(const any & rhs)
65        {
66            any(rhs).swap(*this);
67            return *this;
68        }
69
70    public: // queries
71
72        bool empty() const
73        {
74            return !content;
75        }
76
77        const std::type_info & type() const
78        {
79            return content ? content->type() : typeid(void);
80        }
81
82#ifndef BOOST_NO_MEMBER_TEMPLATE_FRIENDS
83    private: // types
84#else
85    public: // types (public so any_cast can be non-friend)
86#endif
87
88        class placeholder
89        {
90        public: // structors
91
92            virtual ~placeholder()
93            {
94            }
95
96        public: // queries
97
98            virtual const std::type_info & type() const = 0;
99
100            virtual placeholder * clone() const = 0;
101
102        };
103
104        template<typename ValueType>
105        class holder : public placeholder
106        {
107        public: // structors
108
109            holder(const ValueType & value)
110              : held(value)
111            {
112            }
113
114        public: // queries
115
116            virtual const std::type_info & type() const
117            {
118                return typeid(ValueType);
119            }
120
121            virtual placeholder * clone() const
122            {
123                return new holder(held);
124            }
125
126        public: // representation
127
128            ValueType held;
129
130        };
131
132#ifndef BOOST_NO_MEMBER_TEMPLATE_FRIENDS
133
134    private: // representation
135
136        template<typename ValueType>
137        friend ValueType * any_cast(any *);
138
139        template<typename ValueType>
140        friend ValueType * unsafe_any_cast(any *);
141
142#else
143
144    public: // representation (public so any_cast can be non-friend)
145
146#endif
147
148        placeholder * content;
149
150    };
151
152    class bad_any_cast : public std::bad_cast
153    {
154    public:
155        virtual const char * what() const throw()
156        {
157            return "boost::bad_any_cast: "
158                   "failed conversion using boost::any_cast";
159        }
160    };
161
162    template<typename ValueType>
163    ValueType * any_cast(any * operand)
164    {
165        return operand && operand->type() == typeid(ValueType)
166                    ? &static_cast<any::holder<ValueType> *>(operand->content)->held
167                    : 0;
168    }
169
170    template<typename ValueType>
171    const ValueType * any_cast(const any * operand)
172    {
173        return any_cast<ValueType>(const_cast<any *>(operand));
174    }
175
176    template<typename ValueType>
177    ValueType any_cast(const any & operand)
178    {
179        typedef BOOST_DEDUCED_TYPENAME remove_reference<ValueType>::type nonref;
180
181#ifdef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
182        // If 'nonref' is still reference type, it means the user has not
183        // specialized 'remove_reference'.
184
185        // Please use BOOST_BROKEN_COMPILER_TYPE_TRAITS_SPECIALIZATION macro
186        // to generate specialization of remove_reference for your class
187        // See type traits library documentation for details
188        BOOST_STATIC_ASSERT(!is_reference<nonref>::value);
189#endif
190
191        const nonref * result = any_cast<nonref>(&operand);
192        if(!result)
193            boost::throw_exception(bad_any_cast());
194        return *result;
195    }
196
197    template<typename ValueType>
198    ValueType any_cast(any & operand)
199    {
200        typedef BOOST_DEDUCED_TYPENAME remove_reference<ValueType>::type nonref;
201
202#ifdef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
203        // The comment in the above version of 'any_cast' explains when this
204        // assert is fired and what to do.
205        BOOST_STATIC_ASSERT(!is_reference<nonref>::value);
206#endif
207
208        nonref * result = any_cast<nonref>(&operand);
209        if(!result)
210            boost::throw_exception(bad_any_cast());
211        return *result;
212    }
213
214    // Note: The "unsafe" versions of any_cast are not part of the
215    // public interface and may be removed at any time. They are
216    // required where we know what type is stored in the any and can't
217    // use typeid() comparison, e.g., when our types may travel across
218    // different shared libraries.
219    template<typename ValueType>
220    ValueType * unsafe_any_cast(any * operand)
221    {
222        return &static_cast<any::holder<ValueType> *>(operand->content)->held;
223    }
224
225    template<typename ValueType>
226    const ValueType * unsafe_any_cast(const any * operand)
227    {
228        return any_cast<ValueType>(const_cast<any *>(operand));
229    }
230}
231
232// Copyright Kevlin Henney, 2000, 2001, 2002. All rights reserved.
233//
234// Distributed under the Boost Software License, Version 1.0. (See
235// accompanying file LICENSE_1_0.txt or copy at
236// http://www.boost.org/LICENSE_1_0.txt)
237
238#endif
Note: See TracBrowser for help on using the repository browser.