diff options
author | Stefan Radomski <github@mintwerk.de> | 2017-01-13 11:58:41 (GMT) |
---|---|---|
committer | Stefan Radomski <github@mintwerk.de> | 2017-01-13 11:58:41 (GMT) |
commit | 0aa0fe08dc308c94379c47d0bf9745e341cb4c81 (patch) | |
tree | 514b009d3d1658af6988e059874014fc26fc0395 /contrib/src/boost/type_index/stl_type_index.hpp | |
parent | 6952ce94491e4b7bc2acded0788e4609ca2c76e8 (diff) | |
download | uscxml-0aa0fe08dc308c94379c47d0bf9745e341cb4c81.zip uscxml-0aa0fe08dc308c94379c47d0bf9745e341cb4c81.tar.gz uscxml-0aa0fe08dc308c94379c47d0bf9745e341cb4c81.tar.bz2 |
Updated boost headers
Diffstat (limited to 'contrib/src/boost/type_index/stl_type_index.hpp')
-rw-r--r-- | contrib/src/boost/type_index/stl_type_index.hpp | 272 |
1 files changed, 272 insertions, 0 deletions
diff --git a/contrib/src/boost/type_index/stl_type_index.hpp b/contrib/src/boost/type_index/stl_type_index.hpp new file mode 100644 index 0000000..a5add88 --- /dev/null +++ b/contrib/src/boost/type_index/stl_type_index.hpp @@ -0,0 +1,272 @@ +// +// Copyright (c) Antony Polukhin, 2013-2015. +// +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// + +#ifndef BOOST_TYPE_INDEX_STL_TYPE_INDEX_HPP +#define BOOST_TYPE_INDEX_STL_TYPE_INDEX_HPP + +/// \file stl_type_index.hpp +/// \brief Contains boost::typeindex::stl_type_index class. +/// +/// boost::typeindex::stl_type_index class can be used as a drop-in replacement +/// for std::type_index. +/// +/// It is used in situations when RTTI is enabled or typeid() method is available. +/// When typeid() is disabled or BOOST_TYPE_INDEX_FORCE_NO_RTTI_COMPATIBILITY macro +/// is defined boost::typeindex::ctti is usually used instead of boost::typeindex::stl_type_index. + +#include <boost/type_index/type_index_facade.hpp> + +// MSVC is capable of calling typeid(T) even when RTTI is off +#if defined(BOOST_NO_RTTI) && !defined(BOOST_MSVC) +#error "File boost/type_index/stl_type_index.ipp is not usable when typeid() is not available." +#endif + +#include <typeinfo> +#include <cstring> // std::strcmp, std::strlen, std::strstr +#include <stdexcept> +#include <boost/static_assert.hpp> +#include <boost/throw_exception.hpp> +#include <boost/core/demangle.hpp> +#include <boost/type_traits/is_const.hpp> +#include <boost/type_traits/is_reference.hpp> +#include <boost/type_traits/is_volatile.hpp> +#include <boost/type_traits/remove_cv.hpp> +#include <boost/type_traits/remove_reference.hpp> +#include <boost/mpl/if.hpp> +#include <boost/mpl/or.hpp> + +#if (defined(__EDG_VERSION__) && __EDG_VERSION__ < 245) \ + || (defined(__sgi) && defined(_COMPILER_VERSION) && _COMPILER_VERSION <= 744) +# include <boost/type_traits/is_signed.hpp> +# include <boost/type_traits/make_signed.hpp> +# include <boost/mpl/identity.hpp> +#endif + +#ifdef BOOST_HAS_PRAGMA_ONCE +# pragma once +#endif + +namespace boost { namespace typeindex { + +/// \class stl_type_index +/// This class is a wrapper around std::type_info, that workarounds issues and provides +/// much more rich interface. \b For \b description \b of \b functions \b see type_index_facade. +/// +/// This class requires typeid() to work. For cases when RTTI is disabled see ctti_type_index. +class stl_type_index + : public type_index_facade< + stl_type_index, + #ifdef BOOST_NO_STD_TYPEINFO + type_info + #else + std::type_info + #endif + > +{ +public: +#ifdef BOOST_NO_STD_TYPEINFO + typedef type_info type_info_t; +#else + typedef std::type_info type_info_t; +#endif + +private: + const type_info_t* data_; + +public: + inline stl_type_index() BOOST_NOEXCEPT + : data_(&typeid(void)) + {} + + inline stl_type_index(const type_info_t& data) BOOST_NOEXCEPT + : data_(&data) + {} + + inline const type_info_t& type_info() const BOOST_NOEXCEPT; + + inline const char* raw_name() const BOOST_NOEXCEPT; + inline const char* name() const BOOST_NOEXCEPT; + inline std::string pretty_name() const; + + inline std::size_t hash_code() const BOOST_NOEXCEPT; + inline bool equal(const stl_type_index& rhs) const BOOST_NOEXCEPT; + inline bool before(const stl_type_index& rhs) const BOOST_NOEXCEPT; + + template <class T> + inline static stl_type_index type_id() BOOST_NOEXCEPT; + + template <class T> + inline static stl_type_index type_id_with_cvr() BOOST_NOEXCEPT; + + template <class T> + inline static stl_type_index type_id_runtime(const T& value) BOOST_NOEXCEPT; +}; + +inline const stl_type_index::type_info_t& stl_type_index::type_info() const BOOST_NOEXCEPT { + return *data_; +} + + +inline const char* stl_type_index::raw_name() const BOOST_NOEXCEPT { +#ifdef _MSC_VER + return data_->raw_name(); +#else + return data_->name(); +#endif +} + +inline const char* stl_type_index::name() const BOOST_NOEXCEPT { + return data_->name(); +} + +inline std::string stl_type_index::pretty_name() const { + static const char cvr_saver_name[] = "boost::typeindex::detail::cvr_saver<"; + static BOOST_CONSTEXPR_OR_CONST std::string::size_type cvr_saver_name_len = sizeof(cvr_saver_name) - 1; + + // In case of MSVC demangle() is a no-op, and name() already returns demangled name. + // In case of GCC and Clang (on non-Windows systems) name() returns mangled name and demangle() undecorates it. + const boost::core::scoped_demangled_name demangled_name(data_->name()); + + const char* begin = demangled_name.get(); + if (!begin) { + boost::throw_exception(std::runtime_error("Type name demangling failed")); + } + + const std::string::size_type len = std::strlen(begin); + const char* end = begin + len; + + if (len > cvr_saver_name_len) { + const char* b = std::strstr(begin, cvr_saver_name); + if (b) { + b += cvr_saver_name_len; + + // Trim leading spaces + while (*b == ' ') { // the string is zero terminated, we won't exceed the buffer size + ++ b; + } + + // Skip the closing angle bracket + const char* e = end - 1; + while (e > b && *e != '>') { + -- e; + } + + // Trim trailing spaces + while (e > b && *(e - 1) == ' ') { + -- e; + } + + if (b < e) { + // Parsing seems to have succeeded, the type name is not empty + begin = b; + end = e; + } + } + } + + return std::string(begin, end); +} + + +inline std::size_t stl_type_index::hash_code() const BOOST_NOEXCEPT { +#if _MSC_VER > 1600 || (__GNUC__ == 4 && __GNUC_MINOR__ > 5 && defined(__GXX_EXPERIMENTAL_CXX0X__)) + return data_->hash_code(); +#else + return boost::hash_range(raw_name(), raw_name() + std::strlen(raw_name())); +#endif +} + + +/// @cond + +// for this compiler at least, cross-shared-library type_info +// comparisons don't work, so we are using typeid(x).name() instead. +# if (defined(__GNUC__) && (__GNUC__ < 4 || (__GNUC__ == 4 && __GNUC_MINOR__ < 5))) \ + || defined(_AIX) \ + || (defined(__sgi) && defined(__host_mips)) \ + || (defined(__hpux) && defined(__HP_aCC)) \ + || (defined(linux) && defined(__INTEL_COMPILER) && defined(__ICC)) +# define BOOST_CLASSINFO_COMPARE_BY_NAMES +# endif + +/// @endcond + +inline bool stl_type_index::equal(const stl_type_index& rhs) const BOOST_NOEXCEPT { +#ifdef BOOST_CLASSINFO_COMPARE_BY_NAMES + return raw_name() == rhs.raw_name() || !std::strcmp(raw_name(), rhs.raw_name()); +#else + return !!(*data_ == *rhs.data_); +#endif +} + +inline bool stl_type_index::before(const stl_type_index& rhs) const BOOST_NOEXCEPT { +#ifdef BOOST_CLASSINFO_COMPARE_BY_NAMES + return raw_name() != rhs.raw_name() && std::strcmp(raw_name(), rhs.raw_name()) < 0; +#else + return !!data_->before(*rhs.data_); +#endif +} + +#ifdef BOOST_CLASSINFO_COMPARE_BY_NAMES +#undef BOOST_CLASSINFO_COMPARE_BY_NAMES +#endif + + + +template <class T> +inline stl_type_index stl_type_index::type_id() BOOST_NOEXCEPT { + typedef BOOST_DEDUCED_TYPENAME boost::remove_reference<T>::type no_ref_t; + typedef BOOST_DEDUCED_TYPENAME boost::remove_cv<no_ref_t>::type no_cvr_prefinal_t; + + # if (defined(__EDG_VERSION__) && __EDG_VERSION__ < 245) \ + || (defined(__sgi) && defined(_COMPILER_VERSION) && _COMPILER_VERSION <= 744) + + // Old EDG-based compilers seem to mistakenly distinguish 'integral' from 'signed integral' + // in typeid() expressions. Full template specialization for 'integral' fixes that issue: + typedef BOOST_DEDUCED_TYPENAME boost::mpl::if_< + boost::is_signed<no_cvr_prefinal_t>, + boost::make_signed<no_cvr_prefinal_t>, + boost::mpl::identity<no_cvr_prefinal_t> + >::type no_cvr_prefinal_lazy_t; + + typedef BOOST_DEDUCED_TYPENAME no_cvr_prefinal_t::type no_cvr_t; + #else + typedef no_cvr_prefinal_t no_cvr_t; + #endif + + return typeid(no_cvr_t); +} + +namespace detail { + template <class T> class cvr_saver{}; +} + +template <class T> +inline stl_type_index stl_type_index::type_id_with_cvr() BOOST_NOEXCEPT { + typedef BOOST_DEDUCED_TYPENAME boost::mpl::if_< + boost::mpl::or_<boost::is_reference<T>, boost::is_const<T>, boost::is_volatile<T> >, + detail::cvr_saver<T>, + T + >::type type; + + return typeid(type); +} + + +template <class T> +inline stl_type_index stl_type_index::type_id_runtime(const T& value) BOOST_NOEXCEPT { +#ifdef BOOST_NO_RTTI + return value.boost_type_index_type_id_runtime_(); +#else + return typeid(value); +#endif +} + +}} // namespace boost::typeindex + +#endif // BOOST_TYPE_INDEX_STL_TYPE_INDEX_HPP |