comparison DEPENDENCIES/generic/include/boost/variant/get.hpp @ 101:c530137014c0

Update Boost headers (1.58.0)
author Chris Cannam
date Mon, 07 Sep 2015 11:12:49 +0100
parents 2665513ce2d3
children
comparison
equal deleted inserted replaced
100:793467b5e61c 101:c530137014c0
1 //----------------------------------------------------------------------------- 1 //-----------------------------------------------------------------------------
2 // boost variant/get.hpp header file 2 // boost variant/get.hpp header file
3 // See http://www.boost.org for updates, documentation, and revision history. 3 // See http://www.boost.org for updates, documentation, and revision history.
4 //----------------------------------------------------------------------------- 4 //-----------------------------------------------------------------------------
5 // 5 //
6 // Copyright (c) 2003 6 // Copyright (c) 2003 Eric Friedman, Itay Maman
7 // Eric Friedman, Itay Maman 7 // Copyright (c) 2014 Antony Polukhin
8 // 8 //
9 // Distributed under the Boost Software License, Version 1.0. (See 9 // Distributed under the Boost Software License, Version 1.0. (See
10 // accompanying file LICENSE_1_0.txt or copy at 10 // accompanying file LICENSE_1_0.txt or copy at
11 // http://www.boost.org/LICENSE_1_0.txt) 11 // http://www.boost.org/LICENSE_1_0.txt)
12 12
15 15
16 #include <exception> 16 #include <exception>
17 17
18 #include "boost/config.hpp" 18 #include "boost/config.hpp"
19 #include "boost/detail/workaround.hpp" 19 #include "boost/detail/workaround.hpp"
20 #include "boost/static_assert.hpp"
20 #include "boost/throw_exception.hpp" 21 #include "boost/throw_exception.hpp"
21 #include "boost/utility/addressof.hpp" 22 #include "boost/utility/addressof.hpp"
22 #include "boost/variant/variant_fwd.hpp" 23 #include "boost/variant/variant_fwd.hpp"
24 #include "boost/variant/detail/element_index.hpp"
23 25
24 #include "boost/type_traits/add_reference.hpp" 26 #include "boost/type_traits/add_reference.hpp"
25 #include "boost/type_traits/add_pointer.hpp" 27 #include "boost/type_traits/add_pointer.hpp"
26 28
27 #if BOOST_WORKAROUND(BOOST_MSVC, < 1300)
28 # include "boost/mpl/bool.hpp"
29 # include "boost/mpl/or.hpp"
30 # include "boost/type_traits/is_same.hpp"
31 #endif
32
33 namespace boost { 29 namespace boost {
34 30
35 ////////////////////////////////////////////////////////////////////////// 31 //////////////////////////////////////////////////////////////////////////
36 // class bad_get 32 // class bad_get
37 // 33 //
38 // The exception thrown in the event of a failed get of a value. 34 // The exception thrown in the event of a failed get of a value.
39 // 35 //
40 class bad_get 36 class BOOST_SYMBOL_VISIBLE bad_get
41 : public std::exception 37 : public std::exception
42 { 38 {
43 public: // std::exception implementation 39 public: // std::exception implementation
44 40
45 virtual const char * what() const BOOST_NOEXCEPT_OR_NOTHROW 41 virtual const char * what() const BOOST_NOEXCEPT_OR_NOTHROW
76 72
77 typedef pointer result_type; 73 typedef pointer result_type;
78 74
79 public: // visitor interfaces 75 public: // visitor interfaces
80 76
81 #if !BOOST_WORKAROUND(BOOST_MSVC, < 1300) 77 pointer operator()(reference operand) const BOOST_NOEXCEPT
82
83 pointer operator()(reference operand) const
84 { 78 {
85 return boost::addressof(operand); 79 return boost::addressof(operand);
86 } 80 }
87 81
88 template <typename U> 82 template <typename U>
89 pointer operator()(const U&) const 83 pointer operator()(const U&) const BOOST_NOEXCEPT
90 { 84 {
91 return static_cast<pointer>(0); 85 return static_cast<pointer>(0);
92 } 86 }
93
94 #else // MSVC6
95
96 private: // helpers, for visitor interfaces (below)
97
98 pointer execute_impl(reference operand, mpl::true_) const
99 {
100 return boost::addressof(operand);
101 }
102
103 template <typename U>
104 pointer execute_impl(const U& operand, mpl::false_) const
105 {
106 return static_cast<pointer>(0);
107 }
108
109 public: // visitor interfaces
110
111 template <typename U>
112 pointer operator()(U& operand) const
113 {
114 // MSVC6 finds normal implementation (above) ambiguous,
115 // so we must explicitly disambiguate
116
117 typedef typename mpl::or_<
118 is_same<U, T>
119 , is_same<const U, T>
120 >::type U_is_T;
121
122 return execute_impl(operand, U_is_T());
123 }
124
125 #endif // MSVC6 workaround
126
127 }; 87 };
128 88
129 }} // namespace detail::variant 89 }} // namespace detail::variant
130 90
131 #if !BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x0551)) 91 #ifndef BOOST_VARIANT_AUX_GET_EXPLICIT_TEMPLATE_TYPE
132 # define BOOST_VARIANT_AUX_GET_EXPLICIT_TEMPLATE_TYPE(t) \ 92 # if !BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x0551))
133 BOOST_APPEND_EXPLICIT_TEMPLATE_TYPE(t) 93 # define BOOST_VARIANT_AUX_GET_EXPLICIT_TEMPLATE_TYPE(t)
134 #else 94 # else
135 # define BOOST_VARIANT_AUX_GET_EXPLICIT_TEMPLATE_TYPE(t) \ 95 # define BOOST_VARIANT_AUX_GET_EXPLICIT_TEMPLATE_TYPE(t) \
136 , t* = 0 96 , t* = 0
137 #endif 97 # endif
98 #endif
99
100 /////////////////////////////////////////////////////////////////////////////////////////////////////////////
101 // relaxed_get<U>(variant) methods
102 //
103 template <typename U, BOOST_VARIANT_ENUM_PARAMS(typename T) >
104 inline
105 typename add_pointer<U>::type
106 relaxed_get(
107 boost::variant< BOOST_VARIANT_ENUM_PARAMS(T) >* operand
108 BOOST_VARIANT_AUX_GET_EXPLICIT_TEMPLATE_TYPE(U)
109 ) BOOST_NOEXCEPT
110 {
111 typedef typename add_pointer<U>::type U_ptr;
112 if (!operand) return static_cast<U_ptr>(0);
113
114 detail::variant::get_visitor<U> v;
115 return operand->apply_visitor(v);
116 }
117
118 template <typename U, BOOST_VARIANT_ENUM_PARAMS(typename T) >
119 inline
120 typename add_pointer<const U>::type
121 relaxed_get(
122 const boost::variant< BOOST_VARIANT_ENUM_PARAMS(T) >* operand
123 BOOST_VARIANT_AUX_GET_EXPLICIT_TEMPLATE_TYPE(U)
124 ) BOOST_NOEXCEPT
125 {
126 typedef typename add_pointer<const U>::type U_ptr;
127 if (!operand) return static_cast<U_ptr>(0);
128
129 detail::variant::get_visitor<const U> v;
130 return operand->apply_visitor(v);
131 }
132
133 template <typename U, BOOST_VARIANT_ENUM_PARAMS(typename T) >
134 inline
135 typename add_reference<U>::type
136 relaxed_get(
137 boost::variant< BOOST_VARIANT_ENUM_PARAMS(T) >& operand
138 BOOST_VARIANT_AUX_GET_EXPLICIT_TEMPLATE_TYPE(U)
139 )
140 {
141 typedef typename add_pointer<U>::type U_ptr;
142 U_ptr result = relaxed_get<U>(&operand);
143
144 if (!result)
145 boost::throw_exception(bad_get());
146 return *result;
147 }
148
149 template <typename U, BOOST_VARIANT_ENUM_PARAMS(typename T) >
150 inline
151 typename add_reference<const U>::type
152 relaxed_get(
153 const boost::variant< BOOST_VARIANT_ENUM_PARAMS(T) >& operand
154 BOOST_VARIANT_AUX_GET_EXPLICIT_TEMPLATE_TYPE(U)
155 )
156 {
157 typedef typename add_pointer<const U>::type U_ptr;
158 U_ptr result = relaxed_get<const U>(&operand);
159
160 if (!result)
161 boost::throw_exception(bad_get());
162 return *result;
163 }
164
165
166
167 /////////////////////////////////////////////////////////////////////////////////////////////////////////////
168 // strict_get<U>(variant) methods
169 //
170 template <typename U, BOOST_VARIANT_ENUM_PARAMS(typename T) >
171 inline
172 typename add_pointer<U>::type
173 strict_get(
174 boost::variant< BOOST_VARIANT_ENUM_PARAMS(T) >* operand
175 BOOST_VARIANT_AUX_GET_EXPLICIT_TEMPLATE_TYPE(U)
176 ) BOOST_NOEXCEPT
177 {
178 BOOST_STATIC_ASSERT_MSG(
179 (boost::detail::variant::holds_element<boost::variant< BOOST_VARIANT_ENUM_PARAMS(T) >, U >::value),
180 "boost::variant does not contain specified type U, "
181 "call to boost::get<U>(boost::variant<T...>*) will always return NULL"
182 );
183
184 return relaxed_get<U>(operand);
185 }
186
187 template <typename U, BOOST_VARIANT_ENUM_PARAMS(typename T) >
188 inline
189 typename add_pointer<const U>::type
190 strict_get(
191 const boost::variant< BOOST_VARIANT_ENUM_PARAMS(T) >* operand
192 BOOST_VARIANT_AUX_GET_EXPLICIT_TEMPLATE_TYPE(U)
193 ) BOOST_NOEXCEPT
194 {
195 BOOST_STATIC_ASSERT_MSG(
196 (boost::detail::variant::holds_element<boost::variant< BOOST_VARIANT_ENUM_PARAMS(T) >, const U >::value),
197 "boost::variant does not contain specified type U, "
198 "call to boost::get<U>(const boost::variant<T...>*) will always return NULL"
199 );
200
201 return relaxed_get<U>(operand);
202 }
203
204 template <typename U, BOOST_VARIANT_ENUM_PARAMS(typename T) >
205 inline
206 typename add_reference<U>::type
207 strict_get(
208 boost::variant< BOOST_VARIANT_ENUM_PARAMS(T) >& operand
209 BOOST_VARIANT_AUX_GET_EXPLICIT_TEMPLATE_TYPE(U)
210 )
211 {
212 BOOST_STATIC_ASSERT_MSG(
213 (boost::detail::variant::holds_element<boost::variant< BOOST_VARIANT_ENUM_PARAMS(T) >, U >::value),
214 "boost::variant does not contain specified type U, "
215 "call to boost::get<U>(boost::variant<T...>&) will always throw boost::bad_get exception"
216 );
217
218 return relaxed_get<U>(operand);
219 }
220
221 template <typename U, BOOST_VARIANT_ENUM_PARAMS(typename T) >
222 inline
223 typename add_reference<const U>::type
224 strict_get(
225 const boost::variant< BOOST_VARIANT_ENUM_PARAMS(T) >& operand
226 BOOST_VARIANT_AUX_GET_EXPLICIT_TEMPLATE_TYPE(U)
227 )
228 {
229 BOOST_STATIC_ASSERT_MSG(
230 (boost::detail::variant::holds_element<boost::variant< BOOST_VARIANT_ENUM_PARAMS(T) >, const U >::value),
231 "boost::variant does not contain specified type U, "
232 "call to boost::get<U>(const boost::variant<T...>&) will always throw boost::bad_get exception"
233 );
234
235 return relaxed_get<U>(operand);
236 }
237
238 /////////////////////////////////////////////////////////////////////////////////////////////////////////////
239 // get<U>(variant) methods
240 //
138 241
139 template <typename U, BOOST_VARIANT_ENUM_PARAMS(typename T) > 242 template <typename U, BOOST_VARIANT_ENUM_PARAMS(typename T) >
140 inline 243 inline
141 typename add_pointer<U>::type 244 typename add_pointer<U>::type
142 get( 245 get(
143 boost::variant< BOOST_VARIANT_ENUM_PARAMS(T) >* operand 246 boost::variant< BOOST_VARIANT_ENUM_PARAMS(T) >* operand
144 BOOST_VARIANT_AUX_GET_EXPLICIT_TEMPLATE_TYPE(U) 247 BOOST_VARIANT_AUX_GET_EXPLICIT_TEMPLATE_TYPE(U)
145 ) 248 ) BOOST_NOEXCEPT
146 { 249 {
147 typedef typename add_pointer<U>::type U_ptr; 250 #ifdef BOOST_VARIANT_USE_RELAXED_GET_BY_DEFAULT
148 if (!operand) return static_cast<U_ptr>(0); 251 return relaxed_get<U>(operand);
149 252 #else
150 detail::variant::get_visitor<U> v; 253 return strict_get<U>(operand);
151 return operand->apply_visitor(v); 254 #endif
255
152 } 256 }
153 257
154 template <typename U, BOOST_VARIANT_ENUM_PARAMS(typename T) > 258 template <typename U, BOOST_VARIANT_ENUM_PARAMS(typename T) >
155 inline 259 inline
156 typename add_pointer<const U>::type 260 typename add_pointer<const U>::type
157 get( 261 get(
158 const boost::variant< BOOST_VARIANT_ENUM_PARAMS(T) >* operand 262 const boost::variant< BOOST_VARIANT_ENUM_PARAMS(T) >* operand
159 BOOST_VARIANT_AUX_GET_EXPLICIT_TEMPLATE_TYPE(U) 263 BOOST_VARIANT_AUX_GET_EXPLICIT_TEMPLATE_TYPE(U)
160 ) 264 ) BOOST_NOEXCEPT
161 { 265 {
162 typedef typename add_pointer<const U>::type U_ptr; 266 #ifdef BOOST_VARIANT_USE_RELAXED_GET_BY_DEFAULT
163 if (!operand) return static_cast<U_ptr>(0); 267 return relaxed_get<U>(operand);
164 268 #else
165 detail::variant::get_visitor<const U> v; 269 return strict_get<U>(operand);
166 return operand->apply_visitor(v); 270 #endif
167 } 271 }
168 272
169 template <typename U, BOOST_VARIANT_ENUM_PARAMS(typename T) > 273 template <typename U, BOOST_VARIANT_ENUM_PARAMS(typename T) >
170 inline 274 inline
171 typename add_reference<U>::type 275 typename add_reference<U>::type
172 get( 276 get(
173 boost::variant< BOOST_VARIANT_ENUM_PARAMS(T) >& operand 277 boost::variant< BOOST_VARIANT_ENUM_PARAMS(T) >& operand
174 BOOST_VARIANT_AUX_GET_EXPLICIT_TEMPLATE_TYPE(U) 278 BOOST_VARIANT_AUX_GET_EXPLICIT_TEMPLATE_TYPE(U)
175 ) 279 )
176 { 280 {
177 typedef typename add_pointer<U>::type U_ptr; 281 #ifdef BOOST_VARIANT_USE_RELAXED_GET_BY_DEFAULT
178 U_ptr result = get<U>(&operand); 282 return relaxed_get<U>(operand);
179 283 #else
180 if (!result) 284 return strict_get<U>(operand);
181 boost::throw_exception(bad_get()); 285 #endif
182 return *result;
183 } 286 }
184 287
185 template <typename U, BOOST_VARIANT_ENUM_PARAMS(typename T) > 288 template <typename U, BOOST_VARIANT_ENUM_PARAMS(typename T) >
186 inline 289 inline
187 typename add_reference<const U>::type 290 typename add_reference<const U>::type
188 get( 291 get(
189 const boost::variant< BOOST_VARIANT_ENUM_PARAMS(T) >& operand 292 const boost::variant< BOOST_VARIANT_ENUM_PARAMS(T) >& operand
190 BOOST_VARIANT_AUX_GET_EXPLICIT_TEMPLATE_TYPE(U) 293 BOOST_VARIANT_AUX_GET_EXPLICIT_TEMPLATE_TYPE(U)
191 ) 294 )
192 { 295 {
193 typedef typename add_pointer<const U>::type U_ptr; 296 #ifdef BOOST_VARIANT_USE_RELAXED_GET_BY_DEFAULT
194 U_ptr result = get<const U>(&operand); 297 return relaxed_get<U>(operand);
195 298 #else
196 if (!result) 299 return strict_get<U>(operand);
197 boost::throw_exception(bad_get()); 300 #endif
198 return *result;
199 } 301 }
200 302
201 } // namespace boost 303 } // namespace boost
202 304
203 #endif // BOOST_VARIANT_GET_HPP 305 #endif // BOOST_VARIANT_GET_HPP