]> git.proxmox.com Git - ceph.git/blame - ceph/src/boost/libs/type_erasure/include/boost/type_erasure/any_cast.hpp
bump version to 12.2.2-pve1
[ceph.git] / ceph / src / boost / libs / type_erasure / include / boost / type_erasure / any_cast.hpp
CommitLineData
7c673cae
FG
1// Boost.TypeErasure library
2//
3// Copyright 2011 Steven Watanabe
4//
5// Distributed under the Boost Software License Version 1.0. (See
6// accompanying file LICENSE_1_0.txt or copy at
7// http://www.boost.org/LICENSE_1_0.txt)
8//
9// $Id$
10
11#ifndef BOOST_TYPE_ERASURE_ANY_CAST_HPP_INCLUDED
12#define BOOST_TYPE_ERASURE_ANY_CAST_HPP_INCLUDED
13
14#include <stdexcept>
15#include <boost/throw_exception.hpp>
16#include <boost/type_traits/add_const.hpp>
17#include <boost/type_traits/is_pointer.hpp>
18#include <boost/type_traits/remove_cv.hpp>
19#include <boost/type_traits/remove_reference.hpp>
20#include <boost/type_traits/remove_pointer.hpp>
21#include <boost/type_traits/is_void.hpp>
22#include <boost/mpl/assert.hpp>
23#include <boost/mpl/bool.hpp>
24#include <boost/type_erasure/any.hpp>
25#include <boost/type_erasure/builtin.hpp>
26#include <boost/type_erasure/exception.hpp>
27#include <boost/type_erasure/detail/access.hpp>
28
29namespace boost {
30namespace type_erasure {
31
32namespace detail {
33
34template<class Concept, class T>
35void* get_pointer(::boost::type_erasure::any<Concept, T>& arg)
36{
37 return ::boost::type_erasure::detail::access::data(arg).data;
38}
39
40template<class Concept, class T>
41const void* get_pointer(const ::boost::type_erasure::any<Concept, T>& arg)
42{
43 return ::boost::type_erasure::detail::access::data(arg).data;
44}
45
46template<class Concept, class T>
47void* get_pointer(::boost::type_erasure::any<Concept, T&>& arg)
48{
49 return ::boost::type_erasure::detail::access::data(arg).data;
50}
51
52template<class Concept, class T>
53void* get_pointer(const ::boost::type_erasure::any<Concept, T&>& arg)
54{
55 return ::boost::type_erasure::detail::access::data(arg).data;
56}
57
58template<class Concept, class T>
59const void* get_pointer(::boost::type_erasure::any<Concept, const T&>& arg)
60{
61 return ::boost::type_erasure::detail::access::data(arg).data;
62}
63
64template<class Concept, class T>
65const void* get_pointer(const ::boost::type_erasure::any<Concept, const T&>& arg)
66{
67 return ::boost::type_erasure::detail::access::data(arg).data;
68}
69
70template<class T, class Concept, class Tag>
71bool check_any_cast(const any<Concept, Tag>&, ::boost::mpl::true_)
72{
73 return true;
74}
75
76template<class T, class Concept, class Tag>
77bool check_any_cast(const any<Concept, Tag>& arg, ::boost::mpl::false_)
78{
79 typedef typename ::boost::remove_cv<
80 typename ::boost::remove_reference<Tag>::type
81 >::type tag_type;
82 return ::boost::type_erasure::detail::access::table(arg)
83 .template find<typeid_<tag_type> >()() == typeid(T);
84}
85
86template<class T, class Concept, class Tag>
87bool check_any_cast(const any<Concept, Tag>& arg)
88{
89 return ::boost::type_erasure::detail::check_any_cast<T>(
90 arg, ::boost::is_void<typename ::boost::remove_reference<T>::type>());
91}
92
93}
94
95/**
96 * Attempts to extract the object that @c arg holds.
97 * If casting to a pointer fails, \any_cast returns
98 * a null pointer. Casting to @c void* always succeeds
99 * and returns the address of stored object.
100 *
101 * \code
102 * any<mpl::vector<typeid_<>, copy_constructible<> > > x(1);
103 * any_cast<int>(x); // returns 1
104 * any_cast<int&>(x); // returns a reference to the contents of x
105 * any_cast<double>(x); // throws bad_any_cast
106 * any_cast<int*>(&x); // returns a pointer to the contents of x
107 * any_cast<void*>(&x); // returns a pointer to the contents of x
108 * any_cast<double*>(&x); // returns NULL
109 * \endcode
110 *
111 * \pre if @c arg is a pointer, @c T must be a pointer type.
112 * \pre @c Concept must contain @ref typeid_<tt>&lt;Tag&gt;</tt>.
113 *
114 * \throws bad_any_cast if @c arg doesn't contain
115 * an object of type @c T and we're casting
116 * to a value or reference.
117 */
118template<class T, class Concept, class Tag>
119T any_cast(any<Concept, Tag>& arg)
120{
121 if(::boost::type_erasure::detail::check_any_cast<T>(arg)) {
122 return *static_cast<
123 typename ::boost::remove_reference<
124 typename ::boost::add_const<T>::type
125 >::type*
126 >(::boost::type_erasure::detail::get_pointer(arg));
127 } else {
128 BOOST_THROW_EXCEPTION(::boost::type_erasure::bad_any_cast());
129 }
130}
131
132/** \overload */
133template<class T, class Concept, class Tag>
134T any_cast(const any<Concept, Tag>& arg)
135{
136 if(::boost::type_erasure::detail::check_any_cast<T>(arg)) {
137 return *static_cast<
138 typename ::boost::remove_reference<
139 typename ::boost::add_const<T>::type
140 >::type*
141 >(::boost::type_erasure::detail::get_pointer(arg));
142 } else {
143 BOOST_THROW_EXCEPTION(::boost::type_erasure::bad_any_cast());
144 }
145}
146
147/** \overload */
148template<class T, class Concept, class Tag>
149T any_cast(any<Concept, Tag>* arg)
150{
151 BOOST_MPL_ASSERT((::boost::is_pointer<T>));
152 if(::boost::type_erasure::detail::check_any_cast<
153 typename ::boost::remove_pointer<T>::type>(*arg)) {
154 return static_cast<
155 typename ::boost::remove_pointer<T>::type*>(
156 ::boost::type_erasure::detail::get_pointer(*arg));
157 } else {
158 return 0;
159 }
160}
161
162/** \overload */
163template<class T, class Concept, class Tag>
164T any_cast(const any<Concept, Tag>* arg)
165{
166 BOOST_MPL_ASSERT((::boost::is_pointer<T>));
167 if(::boost::type_erasure::detail::check_any_cast<
168 typename ::boost::remove_pointer<T>::type>(*arg)) {
169 return static_cast<
170 typename ::boost::remove_pointer<T>::type*>(
171 ::boost::type_erasure::detail::get_pointer(*arg));
172 } else {
173 return 0;
174 }
175}
176
177}
178}
179
180#endif