annotate DEPENDENCIES/generic/include/boost/variant/polymorphic_get.hpp @ 125:34e428693f5d vext

Vext -> Repoint
author Chris Cannam
date Thu, 14 Jun 2018 11:15:39 +0100
parents f46d142149f5
children
rev   line source
Chris@102 1 //-----------------------------------------------------------------------------
Chris@102 2 // boost variant/polymorphic_get.hpp header file
Chris@102 3 // See http://www.boost.org for updates, documentation, and revision history.
Chris@102 4 //-----------------------------------------------------------------------------
Chris@102 5 //
Chris@102 6 // Copyright (c) 2013-2015 Antony Polukhin
Chris@102 7 //
Chris@102 8 // Distributed under the Boost Software License, Version 1.0. (See
Chris@102 9 // accompanying file LICENSE_1_0.txt or copy at
Chris@102 10 // http://www.boost.org/LICENSE_1_0.txt)
Chris@102 11
Chris@102 12 #ifndef BOOST_VARIANT_POLYMORPHIC_GET_HPP
Chris@102 13 #define BOOST_VARIANT_POLYMORPHIC_GET_HPP
Chris@102 14
Chris@102 15 #include <exception>
Chris@102 16
Chris@102 17 #include "boost/config.hpp"
Chris@102 18 #include "boost/detail/workaround.hpp"
Chris@102 19 #include "boost/static_assert.hpp"
Chris@102 20 #include "boost/throw_exception.hpp"
Chris@102 21 #include "boost/utility/addressof.hpp"
Chris@102 22 #include "boost/variant/variant_fwd.hpp"
Chris@102 23 #include "boost/variant/get.hpp"
Chris@102 24
Chris@102 25 #include "boost/type_traits/add_reference.hpp"
Chris@102 26 #include "boost/type_traits/add_pointer.hpp"
Chris@102 27 #include "boost/type_traits/is_base_of.hpp"
Chris@102 28
Chris@102 29 namespace boost {
Chris@102 30
Chris@102 31 //////////////////////////////////////////////////////////////////////////
Chris@102 32 // class bad_polymorphic_get
Chris@102 33 //
Chris@102 34 // The exception thrown in the event of a failed get of a value.
Chris@102 35 //
Chris@102 36 class BOOST_SYMBOL_VISIBLE bad_polymorphic_get
Chris@102 37 : public bad_get
Chris@102 38 {
Chris@102 39 public: // std::exception implementation
Chris@102 40
Chris@102 41 virtual const char * what() const BOOST_NOEXCEPT_OR_NOTHROW
Chris@102 42 {
Chris@102 43 return "boost::bad_polymorphic_get: "
Chris@102 44 "failed value get using boost::polymorphic_get";
Chris@102 45 }
Chris@102 46
Chris@102 47 };
Chris@102 48
Chris@102 49 //////////////////////////////////////////////////////////////////////////
Chris@102 50 // function template get<T>
Chris@102 51 //
Chris@102 52 // Retrieves content of given variant object if content is of type T.
Chris@102 53 // Otherwise: pointer ver. returns 0; reference ver. throws bad_get.
Chris@102 54 //
Chris@102 55
Chris@102 56 namespace detail { namespace variant {
Chris@102 57
Chris@102 58
Chris@102 59 ///////////////////////////////////////////////////////////////////////////////////////////////////
Chris@102 60 // polymorphic metafunctions to detect index of a value
Chris@102 61 //
Chris@102 62
Chris@102 63 template <class Types, class T>
Chris@102 64 struct element_polymorphic_iterator_impl :
Chris@102 65 boost::mpl::find_if<
Chris@102 66 Types,
Chris@102 67 boost::mpl::or_<
Chris@102 68 variant_element_functor<boost::mpl::_1, T>,
Chris@102 69 variant_element_functor<boost::mpl::_1, typename boost::remove_cv<T>::type >,
Chris@102 70 boost::is_base_of<T, boost::mpl::_1>
Chris@102 71 >
Chris@102 72 >
Chris@102 73 {};
Chris@102 74
Chris@102 75 template <class Variant, class T>
Chris@102 76 struct holds_element_polymorphic :
Chris@102 77 boost::mpl::not_<
Chris@102 78 boost::is_same<
Chris@102 79 typename boost::mpl::end<typename Variant::types>::type,
Chris@102 80 typename element_polymorphic_iterator_impl<typename Variant::types, T>::type
Chris@102 81 >
Chris@102 82 >
Chris@102 83 {};
Chris@102 84
Chris@102 85 // (detail) class template get_polymorphic_visitor
Chris@102 86 //
Chris@102 87 // Generic static visitor that: if the value is of the specified
Chris@102 88 // type or of a type derived from specified, returns a pointer
Chris@102 89 // to the value it visits; else a null pointer.
Chris@102 90 //
Chris@102 91 template <typename Base>
Chris@102 92 struct get_polymorphic_visitor
Chris@102 93 {
Chris@102 94 private: // private typedefs
Chris@102 95 typedef get_polymorphic_visitor<Base> this_type;
Chris@102 96 typedef typename add_pointer<Base>::type pointer;
Chris@102 97 typedef typename add_reference<Base>::type reference;
Chris@102 98
Chris@102 99 pointer get(reference operand, boost::true_type) const BOOST_NOEXCEPT
Chris@102 100 {
Chris@102 101 return boost::addressof(operand);
Chris@102 102 }
Chris@102 103
Chris@102 104 template <class T>
Chris@102 105 pointer get(T&, boost::false_type) const BOOST_NOEXCEPT
Chris@102 106 {
Chris@102 107 return static_cast<pointer>(0);
Chris@102 108 }
Chris@102 109
Chris@102 110 public: // visitor interfaces
Chris@102 111 typedef pointer result_type;
Chris@102 112
Chris@102 113 template <typename U>
Chris@102 114 pointer operator()(U& operand) const BOOST_NOEXCEPT
Chris@102 115 {
Chris@102 116 typedef boost::integral_constant<
Chris@102 117 bool,
Chris@102 118 boost::mpl::or_<
Chris@102 119 boost::is_base_of<Base, U>,
Chris@102 120 boost::is_same<Base, U>,
Chris@102 121 boost::is_same<typename boost::remove_cv<Base>::type, U >
Chris@102 122 >::value
Chris@102 123 > tag_t;
Chris@102 124
Chris@102 125 return this_type::get(operand, tag_t());
Chris@102 126 }
Chris@102 127 };
Chris@102 128
Chris@102 129 }} // namespace detail::variant
Chris@102 130
Chris@102 131 #ifndef BOOST_VARIANT_AUX_GET_EXPLICIT_TEMPLATE_TYPE
Chris@102 132 # if !BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x0551))
Chris@102 133 # define BOOST_VARIANT_AUX_GET_EXPLICIT_TEMPLATE_TYPE(t)
Chris@102 134 # else
Chris@102 135 # define BOOST_VARIANT_AUX_GET_EXPLICIT_TEMPLATE_TYPE(t) \
Chris@102 136 , t* = 0
Chris@102 137 # endif
Chris@102 138 #endif
Chris@102 139
Chris@102 140 //////////////////////////////////////////////////////////////////////////////////////////////////////////
Chris@102 141 // polymorphic_relaxed_get
Chris@102 142 //
Chris@102 143
Chris@102 144 template <typename U, BOOST_VARIANT_ENUM_PARAMS(typename T) >
Chris@102 145 inline
Chris@102 146 typename add_pointer<U>::type
Chris@102 147 polymorphic_relaxed_get(
Chris@102 148 boost::variant< BOOST_VARIANT_ENUM_PARAMS(T) >* operand
Chris@102 149 BOOST_VARIANT_AUX_GET_EXPLICIT_TEMPLATE_TYPE(U)
Chris@102 150 ) BOOST_NOEXCEPT
Chris@102 151 {
Chris@102 152 typedef typename add_pointer<U>::type U_ptr;
Chris@102 153 if (!operand) return static_cast<U_ptr>(0);
Chris@102 154
Chris@102 155 detail::variant::get_polymorphic_visitor<U> v;
Chris@102 156 return operand->apply_visitor(v);
Chris@102 157 }
Chris@102 158
Chris@102 159 template <typename U, BOOST_VARIANT_ENUM_PARAMS(typename T) >
Chris@102 160 inline
Chris@102 161 typename add_pointer<const U>::type
Chris@102 162 polymorphic_relaxed_get(
Chris@102 163 const boost::variant< BOOST_VARIANT_ENUM_PARAMS(T) >* operand
Chris@102 164 BOOST_VARIANT_AUX_GET_EXPLICIT_TEMPLATE_TYPE(U)
Chris@102 165 ) BOOST_NOEXCEPT
Chris@102 166 {
Chris@102 167 typedef typename add_pointer<const U>::type U_ptr;
Chris@102 168 if (!operand) return static_cast<U_ptr>(0);
Chris@102 169
Chris@102 170 detail::variant::get_polymorphic_visitor<const U> v;
Chris@102 171 return operand->apply_visitor(v);
Chris@102 172 }
Chris@102 173
Chris@102 174 template <typename U, BOOST_VARIANT_ENUM_PARAMS(typename T) >
Chris@102 175 inline
Chris@102 176 typename add_reference<U>::type
Chris@102 177 polymorphic_relaxed_get(
Chris@102 178 boost::variant< BOOST_VARIANT_ENUM_PARAMS(T) >& operand
Chris@102 179 BOOST_VARIANT_AUX_GET_EXPLICIT_TEMPLATE_TYPE(U)
Chris@102 180 )
Chris@102 181 {
Chris@102 182 typedef typename add_pointer<U>::type U_ptr;
Chris@102 183 U_ptr result = polymorphic_relaxed_get<U>(&operand);
Chris@102 184
Chris@102 185 if (!result)
Chris@102 186 boost::throw_exception(bad_polymorphic_get());
Chris@102 187 return *result;
Chris@102 188 }
Chris@102 189
Chris@102 190 template <typename U, BOOST_VARIANT_ENUM_PARAMS(typename T) >
Chris@102 191 inline
Chris@102 192 typename add_reference<const U>::type
Chris@102 193 polymorphic_relaxed_get(
Chris@102 194 const boost::variant< BOOST_VARIANT_ENUM_PARAMS(T) >& operand
Chris@102 195 BOOST_VARIANT_AUX_GET_EXPLICIT_TEMPLATE_TYPE(U)
Chris@102 196 )
Chris@102 197 {
Chris@102 198 typedef typename add_pointer<const U>::type U_ptr;
Chris@102 199 U_ptr result = polymorphic_relaxed_get<const U>(&operand);
Chris@102 200
Chris@102 201 if (!result)
Chris@102 202 boost::throw_exception(bad_polymorphic_get());
Chris@102 203 return *result;
Chris@102 204 }
Chris@102 205
Chris@102 206 //////////////////////////////////////////////////////////////////////////////////////////////////////////
Chris@102 207 // polymorphic_strict_get
Chris@102 208 //
Chris@102 209
Chris@102 210 template <typename U, BOOST_VARIANT_ENUM_PARAMS(typename T) >
Chris@102 211 inline
Chris@102 212 typename add_pointer<U>::type
Chris@102 213 polymorphic_strict_get(
Chris@102 214 boost::variant< BOOST_VARIANT_ENUM_PARAMS(T) >* operand
Chris@102 215 BOOST_VARIANT_AUX_GET_EXPLICIT_TEMPLATE_TYPE(U)
Chris@102 216 ) BOOST_NOEXCEPT
Chris@102 217 {
Chris@102 218 BOOST_STATIC_ASSERT_MSG(
Chris@102 219 (boost::detail::variant::holds_element_polymorphic<boost::variant< BOOST_VARIANT_ENUM_PARAMS(T) >, U >::value),
Chris@102 220 "boost::variant does not contain specified type U, "
Chris@102 221 "call to boost::polymorphic_get<U>(boost::variant<T...>*) will always return NULL"
Chris@102 222 );
Chris@102 223
Chris@102 224 return polymorphic_relaxed_get<U>(operand);
Chris@102 225 }
Chris@102 226
Chris@102 227 template <typename U, BOOST_VARIANT_ENUM_PARAMS(typename T) >
Chris@102 228 inline
Chris@102 229 typename add_pointer<const U>::type
Chris@102 230 polymorphic_strict_get(
Chris@102 231 const boost::variant< BOOST_VARIANT_ENUM_PARAMS(T) >* operand
Chris@102 232 BOOST_VARIANT_AUX_GET_EXPLICIT_TEMPLATE_TYPE(U)
Chris@102 233 ) BOOST_NOEXCEPT
Chris@102 234 {
Chris@102 235 BOOST_STATIC_ASSERT_MSG(
Chris@102 236 (boost::detail::variant::holds_element_polymorphic<boost::variant< BOOST_VARIANT_ENUM_PARAMS(T) >, U >::value),
Chris@102 237 "boost::variant does not contain specified type U, "
Chris@102 238 "call to boost::polymorphic_get<U>(const boost::variant<T...>*) will always return NULL"
Chris@102 239 );
Chris@102 240
Chris@102 241 return polymorphic_relaxed_get<U>(operand);
Chris@102 242 }
Chris@102 243
Chris@102 244 template <typename U, BOOST_VARIANT_ENUM_PARAMS(typename T) >
Chris@102 245 inline
Chris@102 246 typename add_reference<U>::type
Chris@102 247 polymorphic_strict_get(
Chris@102 248 boost::variant< BOOST_VARIANT_ENUM_PARAMS(T) >& operand
Chris@102 249 BOOST_VARIANT_AUX_GET_EXPLICIT_TEMPLATE_TYPE(U)
Chris@102 250 )
Chris@102 251 {
Chris@102 252 BOOST_STATIC_ASSERT_MSG(
Chris@102 253 (boost::detail::variant::holds_element_polymorphic<boost::variant< BOOST_VARIANT_ENUM_PARAMS(T) >, U >::value),
Chris@102 254 "boost::variant does not contain specified type U, "
Chris@102 255 "call to boost::polymorphic_get<U>(boost::variant<T...>&) will always throw boost::bad_polymorphic_get exception"
Chris@102 256 );
Chris@102 257
Chris@102 258 return polymorphic_relaxed_get<U>(operand);
Chris@102 259 }
Chris@102 260
Chris@102 261 template <typename U, BOOST_VARIANT_ENUM_PARAMS(typename T) >
Chris@102 262 inline
Chris@102 263 typename add_reference<const U>::type
Chris@102 264 polymorphic_strict_get(
Chris@102 265 const boost::variant< BOOST_VARIANT_ENUM_PARAMS(T) >& operand
Chris@102 266 BOOST_VARIANT_AUX_GET_EXPLICIT_TEMPLATE_TYPE(U)
Chris@102 267 )
Chris@102 268 {
Chris@102 269 BOOST_STATIC_ASSERT_MSG(
Chris@102 270 (boost::detail::variant::holds_element_polymorphic<boost::variant< BOOST_VARIANT_ENUM_PARAMS(T) >, U >::value),
Chris@102 271 "boost::variant does not contain specified type U, "
Chris@102 272 "call to boost::polymorphic_get<U>(const boost::variant<T...>&) will always throw boost::bad_polymorphic_get exception"
Chris@102 273 );
Chris@102 274
Chris@102 275 return polymorphic_relaxed_get<U>(operand);
Chris@102 276 }
Chris@102 277
Chris@102 278 /////////////////////////////////////////////////////////////////////////////////////////////////////////////
Chris@102 279 // polymorphic_get<U>(variant) methods
Chris@102 280 //
Chris@102 281
Chris@102 282 template <typename U, BOOST_VARIANT_ENUM_PARAMS(typename T) >
Chris@102 283 inline
Chris@102 284 typename add_pointer<U>::type
Chris@102 285 polymorphic_get(
Chris@102 286 boost::variant< BOOST_VARIANT_ENUM_PARAMS(T) >* operand
Chris@102 287 BOOST_VARIANT_AUX_GET_EXPLICIT_TEMPLATE_TYPE(U)
Chris@102 288 ) BOOST_NOEXCEPT
Chris@102 289 {
Chris@102 290 #ifdef BOOST_VARIANT_USE_RELAXED_GET_BY_DEFAULT
Chris@102 291 return polymorphic_relaxed_get<U>(operand);
Chris@102 292 #else
Chris@102 293 return polymorphic_strict_get<U>(operand);
Chris@102 294 #endif
Chris@102 295
Chris@102 296 }
Chris@102 297
Chris@102 298 template <typename U, BOOST_VARIANT_ENUM_PARAMS(typename T) >
Chris@102 299 inline
Chris@102 300 typename add_pointer<const U>::type
Chris@102 301 polymorphic_get(
Chris@102 302 const boost::variant< BOOST_VARIANT_ENUM_PARAMS(T) >* operand
Chris@102 303 BOOST_VARIANT_AUX_GET_EXPLICIT_TEMPLATE_TYPE(U)
Chris@102 304 ) BOOST_NOEXCEPT
Chris@102 305 {
Chris@102 306 #ifdef BOOST_VARIANT_USE_RELAXED_GET_BY_DEFAULT
Chris@102 307 return polymorphic_relaxed_get<U>(operand);
Chris@102 308 #else
Chris@102 309 return polymorphic_strict_get<U>(operand);
Chris@102 310 #endif
Chris@102 311 }
Chris@102 312
Chris@102 313 template <typename U, BOOST_VARIANT_ENUM_PARAMS(typename T) >
Chris@102 314 inline
Chris@102 315 typename add_reference<U>::type
Chris@102 316 polymorphic_get(
Chris@102 317 boost::variant< BOOST_VARIANT_ENUM_PARAMS(T) >& operand
Chris@102 318 BOOST_VARIANT_AUX_GET_EXPLICIT_TEMPLATE_TYPE(U)
Chris@102 319 )
Chris@102 320 {
Chris@102 321 #ifdef BOOST_VARIANT_USE_RELAXED_GET_BY_DEFAULT
Chris@102 322 return polymorphic_relaxed_get<U>(operand);
Chris@102 323 #else
Chris@102 324 return polymorphic_strict_get<U>(operand);
Chris@102 325 #endif
Chris@102 326 }
Chris@102 327
Chris@102 328 template <typename U, BOOST_VARIANT_ENUM_PARAMS(typename T) >
Chris@102 329 inline
Chris@102 330 typename add_reference<const U>::type
Chris@102 331 polymorphic_get(
Chris@102 332 const boost::variant< BOOST_VARIANT_ENUM_PARAMS(T) >& operand
Chris@102 333 BOOST_VARIANT_AUX_GET_EXPLICIT_TEMPLATE_TYPE(U)
Chris@102 334 )
Chris@102 335 {
Chris@102 336 #ifdef BOOST_VARIANT_USE_RELAXED_GET_BY_DEFAULT
Chris@102 337 return polymorphic_relaxed_get<U>(operand);
Chris@102 338 #else
Chris@102 339 return polymorphic_strict_get<U>(operand);
Chris@102 340 #endif
Chris@102 341 }
Chris@102 342 } // namespace boost
Chris@102 343
Chris@102 344 #endif // BOOST_VARIANT_POLYMORPHIC_GET_HPP