Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-30 10:02:09

0001 //-----------------------------------------------------------------------------
0002 // boost variant/get.hpp header file
0003 // See http://www.boost.org for updates, documentation, and revision history.
0004 //-----------------------------------------------------------------------------
0005 //
0006 // Copyright (c) 2003 Eric Friedman, Itay Maman
0007 // Copyright (c) 2014-2023 Antony Polukhin
0008 //
0009 // Distributed under the Boost Software License, Version 1.0. (See
0010 // accompanying file LICENSE_1_0.txt or copy at
0011 // http://www.boost.org/LICENSE_1_0.txt)
0012 
0013 #ifndef BOOST_VARIANT_GET_HPP
0014 #define BOOST_VARIANT_GET_HPP
0015 
0016 #include <exception>
0017 
0018 #include <boost/config.hpp>
0019 #include <boost/core/addressof.hpp>
0020 #include <boost/detail/workaround.hpp>
0021 #include <boost/static_assert.hpp>
0022 #include <boost/throw_exception.hpp>
0023 #include <boost/variant/variant_fwd.hpp>
0024 #include <boost/variant/detail/element_index.hpp>
0025 #include <boost/variant/detail/move.hpp>
0026 
0027 #include <boost/type_traits/add_reference.hpp>
0028 #include <boost/type_traits/add_pointer.hpp>
0029 #include <boost/type_traits/is_lvalue_reference.hpp>
0030 
0031 namespace boost {
0032 
0033 #if defined(BOOST_CLANG)
0034 #   pragma clang diagnostic push
0035 #   pragma clang diagnostic ignored "-Wweak-vtables"
0036 #endif
0037 //////////////////////////////////////////////////////////////////////////
0038 // class bad_get
0039 //
0040 // The exception thrown in the event of a failed get of a value.
0041 //
0042 class BOOST_SYMBOL_VISIBLE bad_get
0043     : public std::exception
0044 {
0045 public: // std::exception implementation
0046 
0047     const char * what() const BOOST_NOEXCEPT_OR_NOTHROW BOOST_OVERRIDE
0048     {
0049         return "boost::bad_get: "
0050                "failed value get using boost::get";
0051     }
0052 
0053 };
0054 #if defined(BOOST_CLANG)
0055 #   pragma clang diagnostic pop
0056 #endif
0057 
0058 
0059 //////////////////////////////////////////////////////////////////////////
0060 // function template get<T>
0061 //
0062 // Retrieves content of given variant object if content is of type T.
0063 // Otherwise: pointer ver. returns 0; reference ver. throws bad_get.
0064 //
0065 
0066 namespace detail { namespace variant {
0067 
0068 // (detail) class template get_visitor
0069 //
0070 // Generic static visitor that: if the value is of the specified type,
0071 // returns a pointer to the value it visits; else a null pointer.
0072 //
0073 template <typename T>
0074 struct get_visitor
0075 {
0076 private: // private typedefs
0077 
0078     typedef typename add_pointer<T>::type pointer;
0079     typedef typename add_reference<T>::type reference;
0080 
0081 public: // visitor typedefs
0082 
0083     typedef pointer result_type;
0084 
0085 public: // visitor interfaces
0086 
0087     pointer operator()(reference operand) const BOOST_NOEXCEPT
0088     {
0089         return boost::addressof(operand);
0090     }
0091 
0092     template <typename U>
0093     pointer operator()(const U&) const BOOST_NOEXCEPT
0094     {
0095         return static_cast<pointer>(0);
0096     }
0097 };
0098 
0099 }} // namespace detail::variant
0100 
0101 #ifndef BOOST_VARIANT_AUX_GET_EXPLICIT_TEMPLATE_TYPE
0102 #   if !BOOST_WORKAROUND(BOOST_BORLANDC, BOOST_TESTED_AT(0x0551))
0103 #       define BOOST_VARIANT_AUX_GET_EXPLICIT_TEMPLATE_TYPE(t)
0104 #   else
0105 #       if defined(BOOST_NO_CXX11_NULLPTR)
0106 #           define BOOST_VARIANT_AUX_GET_EXPLICIT_TEMPLATE_TYPE(t)  \
0107             , t* = 0
0108 #       else
0109 #           define BOOST_VARIANT_AUX_GET_EXPLICIT_TEMPLATE_TYPE(t)  \
0110             , t* = nullptr
0111 #       endif
0112 #   endif
0113 #endif
0114 
0115 /////////////////////////////////////////////////////////////////////////////////////////////////////////////
0116 // relaxed_get<U>(variant) methods
0117 //
0118 template <typename U, BOOST_VARIANT_ENUM_PARAMS(typename T) >
0119 inline
0120     typename add_pointer<U>::type
0121 relaxed_get(
0122       boost::variant< BOOST_VARIANT_ENUM_PARAMS(T) >* operand
0123       BOOST_VARIANT_AUX_GET_EXPLICIT_TEMPLATE_TYPE(U)
0124     ) BOOST_NOEXCEPT
0125 {
0126     typedef typename add_pointer<U>::type U_ptr;
0127     if (!operand) return static_cast<U_ptr>(0);
0128 
0129     detail::variant::get_visitor<U> v;
0130     return operand->apply_visitor(v);
0131 }
0132 
0133 template <typename U, BOOST_VARIANT_ENUM_PARAMS(typename T) >
0134 inline
0135     typename add_pointer<const U>::type
0136 relaxed_get(
0137       const boost::variant< BOOST_VARIANT_ENUM_PARAMS(T) >* operand
0138       BOOST_VARIANT_AUX_GET_EXPLICIT_TEMPLATE_TYPE(U)
0139     ) BOOST_NOEXCEPT
0140 {
0141     typedef typename add_pointer<const U>::type U_ptr;
0142     if (!operand) return static_cast<U_ptr>(0);
0143 
0144     detail::variant::get_visitor<const U> v;
0145     return operand->apply_visitor(v);
0146 }
0147 
0148 template <typename U, BOOST_VARIANT_ENUM_PARAMS(typename T) >
0149 inline
0150     typename add_reference<U>::type
0151 relaxed_get(
0152       boost::variant< BOOST_VARIANT_ENUM_PARAMS(T) >& operand
0153       BOOST_VARIANT_AUX_GET_EXPLICIT_TEMPLATE_TYPE(U)
0154     )
0155 {
0156     typedef typename add_pointer<U>::type U_ptr;
0157     U_ptr result = relaxed_get<U>(boost::addressof(operand));
0158 
0159     if (!result)
0160         boost::throw_exception(bad_get());
0161     return *result;
0162 }
0163 
0164 template <typename U, BOOST_VARIANT_ENUM_PARAMS(typename T) >
0165 inline
0166     typename add_reference<const U>::type
0167 relaxed_get(
0168       const boost::variant< BOOST_VARIANT_ENUM_PARAMS(T) >& operand
0169       BOOST_VARIANT_AUX_GET_EXPLICIT_TEMPLATE_TYPE(U)
0170     )
0171 {
0172     typedef typename add_pointer<const U>::type U_ptr;
0173     U_ptr result = relaxed_get<const U>(boost::addressof(operand));
0174 
0175     if (!result)
0176         boost::throw_exception(bad_get());
0177     return *result;
0178 }
0179 
0180 #ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
0181 
0182 #if defined(BOOST_MSVC) && (_MSC_VER < 1900) // MSVC-2014 has fixed the incorrect diagnostics.
0183 #   pragma warning(push)
0184 #   pragma warning(disable: 4172) // returning address of local variable or temporary
0185 #endif
0186 
0187 template <typename U, BOOST_VARIANT_ENUM_PARAMS(typename T) >
0188 inline
0189     U&&
0190 relaxed_get(
0191       boost::variant< BOOST_VARIANT_ENUM_PARAMS(T) >&& operand
0192       BOOST_VARIANT_AUX_GET_EXPLICIT_TEMPLATE_TYPE(U)
0193     )
0194 {
0195     typedef typename add_pointer<U>::type U_ptr;
0196     U_ptr result = relaxed_get<U>(boost::addressof(operand));
0197 
0198     if (!result)
0199         boost::throw_exception(bad_get());
0200     return static_cast<U&&>(*result);
0201 }
0202 
0203 #if defined(BOOST_MSVC) && (_MSC_VER < 1900)
0204 #   pragma warning(pop)
0205 #endif
0206 
0207 #endif
0208 
0209 /////////////////////////////////////////////////////////////////////////////////////////////////////////////
0210 // strict_get<U>(variant) methods
0211 //
0212 template <typename U, BOOST_VARIANT_ENUM_PARAMS(typename T) >
0213 inline
0214     typename add_pointer<U>::type
0215 strict_get(
0216       boost::variant< BOOST_VARIANT_ENUM_PARAMS(T) >* operand
0217       BOOST_VARIANT_AUX_GET_EXPLICIT_TEMPLATE_TYPE(U)
0218     ) BOOST_NOEXCEPT
0219 {
0220     BOOST_STATIC_ASSERT_MSG(
0221         (boost::detail::variant::holds_element<boost::variant< BOOST_VARIANT_ENUM_PARAMS(T) >, U >::value),
0222         "boost::variant does not contain specified type U, "
0223         "call to boost::get<U>(boost::variant<T...>*) will always return NULL"
0224     );
0225 
0226     return relaxed_get<U>(operand);
0227 }
0228 
0229 template <typename U, BOOST_VARIANT_ENUM_PARAMS(typename T) >
0230 inline
0231     typename add_pointer<const U>::type
0232 strict_get(
0233       const boost::variant< BOOST_VARIANT_ENUM_PARAMS(T) >* operand
0234       BOOST_VARIANT_AUX_GET_EXPLICIT_TEMPLATE_TYPE(U)
0235     ) BOOST_NOEXCEPT
0236 {
0237     BOOST_STATIC_ASSERT_MSG(
0238         (boost::detail::variant::holds_element<boost::variant< BOOST_VARIANT_ENUM_PARAMS(T) >, const U >::value),
0239         "boost::variant does not contain specified type U, "
0240         "call to boost::get<U>(const boost::variant<T...>*) will always return NULL"
0241     );
0242 
0243     return relaxed_get<U>(operand);
0244 }
0245 
0246 template <typename U, BOOST_VARIANT_ENUM_PARAMS(typename T) >
0247 inline
0248     typename add_reference<U>::type
0249 strict_get(
0250       boost::variant< BOOST_VARIANT_ENUM_PARAMS(T) >& operand
0251       BOOST_VARIANT_AUX_GET_EXPLICIT_TEMPLATE_TYPE(U)
0252     )
0253 {
0254     BOOST_STATIC_ASSERT_MSG(
0255         (boost::detail::variant::holds_element<boost::variant< BOOST_VARIANT_ENUM_PARAMS(T) >, U >::value),
0256         "boost::variant does not contain specified type U, "
0257         "call to boost::get<U>(boost::variant<T...>&) will always throw boost::bad_get exception"
0258     );
0259 
0260     return relaxed_get<U>(operand);
0261 }
0262 
0263 template <typename U, BOOST_VARIANT_ENUM_PARAMS(typename T) >
0264 inline
0265     typename add_reference<const U>::type
0266 strict_get(
0267       const boost::variant< BOOST_VARIANT_ENUM_PARAMS(T) >& operand
0268       BOOST_VARIANT_AUX_GET_EXPLICIT_TEMPLATE_TYPE(U)
0269     )
0270 {
0271     BOOST_STATIC_ASSERT_MSG(
0272         (boost::detail::variant::holds_element<boost::variant< BOOST_VARIANT_ENUM_PARAMS(T) >, const U >::value),
0273         "boost::variant does not contain specified type U, "
0274         "call to boost::get<U>(const boost::variant<T...>&) will always throw boost::bad_get exception"
0275     );
0276 
0277     return relaxed_get<U>(operand);
0278 }
0279 
0280 #ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
0281 template <typename U, BOOST_VARIANT_ENUM_PARAMS(typename T) >
0282 inline
0283     U&&
0284 strict_get(
0285       boost::variant< BOOST_VARIANT_ENUM_PARAMS(T) >&& operand
0286       BOOST_VARIANT_AUX_GET_EXPLICIT_TEMPLATE_TYPE(U)
0287     )
0288 {
0289     BOOST_STATIC_ASSERT_MSG(
0290         (!boost::is_lvalue_reference<U>::value),
0291         "remove ampersand '&' from template type U in boost::get<U>(boost::variant<T...>&&) "
0292     );
0293 
0294     BOOST_STATIC_ASSERT_MSG(
0295         (boost::detail::variant::holds_element<boost::variant< BOOST_VARIANT_ENUM_PARAMS(T) >, U >::value),
0296         "boost::variant does not contain specified type U, "
0297         "call to boost::get<U>(const boost::variant<T...>&) will always throw boost::bad_get exception"
0298     );
0299 
0300     return relaxed_get<U>(detail::variant::move(operand));
0301 }
0302 #endif
0303 
0304 /////////////////////////////////////////////////////////////////////////////////////////////////////////////
0305 // get<U>(variant) methods
0306 //
0307 
0308 template <typename U, BOOST_VARIANT_ENUM_PARAMS(typename T) >
0309 inline
0310     typename add_pointer<U>::type
0311 get(
0312       boost::variant< BOOST_VARIANT_ENUM_PARAMS(T) >* operand
0313       BOOST_VARIANT_AUX_GET_EXPLICIT_TEMPLATE_TYPE(U)
0314     ) BOOST_NOEXCEPT
0315 {
0316 #ifdef BOOST_VARIANT_USE_RELAXED_GET_BY_DEFAULT
0317     return relaxed_get<U>(operand);
0318 #else
0319     return strict_get<U>(operand);
0320 #endif
0321 
0322 }
0323 
0324 template <typename U, BOOST_VARIANT_ENUM_PARAMS(typename T) >
0325 inline
0326     typename add_pointer<const U>::type
0327 get(
0328       const boost::variant< BOOST_VARIANT_ENUM_PARAMS(T) >* operand
0329       BOOST_VARIANT_AUX_GET_EXPLICIT_TEMPLATE_TYPE(U)
0330     ) BOOST_NOEXCEPT
0331 {
0332 #ifdef BOOST_VARIANT_USE_RELAXED_GET_BY_DEFAULT
0333     return relaxed_get<U>(operand);
0334 #else
0335     return strict_get<U>(operand);
0336 #endif
0337 }
0338 
0339 template <typename U, BOOST_VARIANT_ENUM_PARAMS(typename T) >
0340 inline
0341     typename add_reference<U>::type
0342 get(
0343       boost::variant< BOOST_VARIANT_ENUM_PARAMS(T) >& operand
0344       BOOST_VARIANT_AUX_GET_EXPLICIT_TEMPLATE_TYPE(U)
0345     )
0346 {
0347 #ifdef BOOST_VARIANT_USE_RELAXED_GET_BY_DEFAULT
0348     return relaxed_get<U>(operand);
0349 #else
0350     return strict_get<U>(operand);
0351 #endif
0352 }
0353 
0354 template <typename U, BOOST_VARIANT_ENUM_PARAMS(typename T) >
0355 inline
0356     typename add_reference<const U>::type
0357 get(
0358       const boost::variant< BOOST_VARIANT_ENUM_PARAMS(T) >& operand
0359       BOOST_VARIANT_AUX_GET_EXPLICIT_TEMPLATE_TYPE(U)
0360     )
0361 {
0362 #ifdef BOOST_VARIANT_USE_RELAXED_GET_BY_DEFAULT
0363     return relaxed_get<U>(operand);
0364 #else
0365     return strict_get<U>(operand);
0366 #endif
0367 }
0368 
0369 #ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
0370 template <typename U, BOOST_VARIANT_ENUM_PARAMS(typename T) >
0371 inline
0372     U&&
0373 get(
0374       boost::variant< BOOST_VARIANT_ENUM_PARAMS(T) >&& operand
0375       BOOST_VARIANT_AUX_GET_EXPLICIT_TEMPLATE_TYPE(U)
0376     )
0377 {
0378 #ifdef BOOST_VARIANT_USE_RELAXED_GET_BY_DEFAULT
0379     return relaxed_get<U>(detail::variant::move(operand));
0380 #else
0381     return strict_get<U>(detail::variant::move(operand));
0382 #endif
0383 }
0384 #endif
0385 
0386 } // namespace boost
0387 
0388 #endif // BOOST_VARIANT_GET_HPP