diff --git a/CHANGES.rst b/CHANGES.rst index e936a088b..e074a44e4 100644 --- a/CHANGES.rst +++ b/CHANGES.rst @@ -2,10 +2,13 @@ Changes ========= -4.0.1 (unreleased) +4.1.0 (unreleased) ================== -- Nothing changed yet. +- Update the bundled version of the Boost libraries from 1.75 to 1.83 + to support newer compilers like GCC 13. +- Compile in C++ 11 mode instead of whatever the compiler default was + (sometimes C++ 03), because the latter is deprecated by Boost. 4.0.0 (2023-12-11) diff --git a/include/README.rst b/include/README.rst index e6dcf523c..d05ca8636 100644 --- a/include/README.rst +++ b/include/README.rst @@ -31,3 +31,11 @@ A one liner to update from a boost distribution unpacked beside this boost/ directory:: for i in `find . -type f`; do gcp -f ../boost_1_75_0/boost/${i:2} $i; done + +1.83 +==== + +In December 2023, this was updated to boost 1.83 to fix compilation +problems with gcc13, using a similar one-liner:: + + for i in `find . -type f`; do gcp -f ../boost_1_83_0/boost/${i:2} $i; done diff --git a/include/boost/assert/source_location.hpp b/include/boost/assert/source_location.hpp index a85e67952..09770f7d3 100644 --- a/include/boost/assert/source_location.hpp +++ b/include/boost/assert/source_location.hpp @@ -1,16 +1,24 @@ #ifndef BOOST_ASSERT_SOURCE_LOCATION_HPP_INCLUDED #define BOOST_ASSERT_SOURCE_LOCATION_HPP_INCLUDED -// http://www.boost.org/libs/assert +// http://www.boost.org/libs/assert // -// Copyright 2019 Peter Dimov -// Distributed under the Boost Software License, Version 1.0. -// http://www.boost.org/LICENSE_1_0.txt +// Copyright 2019, 2021 Peter Dimov +// Distributed under the Boost Software License, Version 1.0. +// http://www.boost.org/LICENSE_1_0.txt #include #include +#include #include #include +#include +#include +#include + +#if defined(__cpp_lib_source_location) && __cpp_lib_source_location >= 201907L +# include +#endif namespace boost { @@ -26,7 +34,7 @@ struct source_location public: - BOOST_CONSTEXPR source_location() BOOST_NOEXCEPT: file_( "(unknown)" ), function_( "(unknown)" ), line_( 0 ), column_( 0 ) + BOOST_CONSTEXPR source_location() BOOST_NOEXCEPT: file_( "" ), function_( "" ), line_( 0 ), column_( 0 ) { } @@ -34,6 +42,14 @@ struct source_location { } +#if defined(__cpp_lib_source_location) && __cpp_lib_source_location >= 201907L + + BOOST_CONSTEXPR source_location( std::source_location const& loc ) BOOST_NOEXCEPT: file_( loc.file_name() ), function_( loc.function_name() ), line_( loc.line() ), column_( loc.column() ) + { + } + +#endif + BOOST_CONSTEXPR char const * file_name() const BOOST_NOEXCEPT { return file_; @@ -53,40 +69,123 @@ struct source_location { return column_; } -}; -template std::basic_ostream & operator<<( std::basic_ostream & os, source_location const & loc ) -{ - os.width( 0 ); +#if defined(BOOST_MSVC) +# pragma warning( push ) +# pragma warning( disable: 4996 ) +#endif - if( loc.line() == 0 ) - { - os << "(unknown source location)"; - } - else +#if ( defined(_MSC_VER) && _MSC_VER < 1900 ) || ( defined(__MINGW32__) && !defined(__MINGW64_VERSION_MAJOR) ) +# define BOOST_ASSERT_SNPRINTF(buffer, format, arg) std::sprintf(buffer, format, arg) +#else +# define BOOST_ASSERT_SNPRINTF(buffer, format, arg) std::snprintf(buffer, sizeof(buffer)/sizeof(buffer[0]), format, arg) +#endif + + std::string to_string() const { - os << loc.file_name() << ':' << loc.line(); + unsigned long ln = line(); + + if( ln == 0 ) + { + return "(unknown source location)"; + } + + std::string r = file_name(); + + char buffer[ 16 ]; + + BOOST_ASSERT_SNPRINTF( buffer, ":%lu", ln ); + r += buffer; + + unsigned long co = column(); + + if( co ) + { + BOOST_ASSERT_SNPRINTF( buffer, ":%lu", co ); + r += buffer; + } + + char const* fn = function_name(); - if( loc.column() ) + if( *fn != 0 ) { - os << ':' << loc.column(); + r += " in function '"; + r += fn; + r += '\''; } - os << ": in function '" << loc.function_name() << '\''; + return r; } +#undef BOOST_ASSERT_SNPRINTF + +#if defined(BOOST_MSVC) +# pragma warning( pop ) +#endif + + inline friend bool operator==( source_location const& s1, source_location const& s2 ) BOOST_NOEXCEPT + { + return std::strcmp( s1.file_, s2.file_ ) == 0 && std::strcmp( s1.function_, s2.function_ ) == 0 && s1.line_ == s2.line_ && s1.column_ == s2.column_; + } + + inline friend bool operator!=( source_location const& s1, source_location const& s2 ) BOOST_NOEXCEPT + { + return !( s1 == s2 ); + } +}; + +template std::basic_ostream & operator<<( std::basic_ostream & os, source_location const & loc ) +{ + os << loc.to_string(); return os; } } // namespace boost -#if defined( BOOST_DISABLE_CURRENT_LOCATION ) +#if defined(BOOST_DISABLE_CURRENT_LOCATION) + +# define BOOST_CURRENT_LOCATION ::boost::source_location() + +#elif defined(BOOST_MSVC) && BOOST_MSVC >= 1926 + +// std::source_location::current() is available in -std:c++20, but fails with consteval errors before 19.31, and doesn't produce +// the correct result under 19.31, so prefer the built-ins +# define BOOST_CURRENT_LOCATION ::boost::source_location(__builtin_FILE(), __builtin_LINE(), __builtin_FUNCTION(), __builtin_COLUMN()) + +#elif defined(BOOST_MSVC) + +// __LINE__ is not a constant expression under /ZI (edit and continue) for 1925 and before + +# define BOOST_CURRENT_LOCATION_IMPL_1(x) BOOST_CURRENT_LOCATION_IMPL_2(x) +# define BOOST_CURRENT_LOCATION_IMPL_2(x) (x##0 / 10) + +# define BOOST_CURRENT_LOCATION ::boost::source_location(__FILE__, BOOST_CURRENT_LOCATION_IMPL_1(__LINE__), "") + +#elif defined(__cpp_lib_source_location) && __cpp_lib_source_location >= 201907L && !defined(__NVCC__) + +// Under nvcc, __builtin_source_location is not constexpr +// https://github.com/boostorg/assert/issues/32 + +# define BOOST_CURRENT_LOCATION ::boost::source_location(::std::source_location::current()) + +#elif defined(BOOST_CLANG) && BOOST_CLANG_VERSION >= 90000 + +# define BOOST_CURRENT_LOCATION ::boost::source_location(__builtin_FILE(), __builtin_LINE(), __builtin_FUNCTION(), __builtin_COLUMN()) + +#elif defined(BOOST_GCC) && BOOST_GCC >= 70000 + +// The built-ins are available in 4.8+, but are not constant expressions until 7 +# define BOOST_CURRENT_LOCATION ::boost::source_location(__builtin_FILE(), __builtin_LINE(), __builtin_FUNCTION()) + +#elif defined(BOOST_GCC) && BOOST_GCC >= 50000 -# define BOOST_CURRENT_LOCATION ::boost::source_location() +// __PRETTY_FUNCTION__ is allowed outside functions under GCC, but 4.x suffers from codegen bugs +# define BOOST_CURRENT_LOCATION ::boost::source_location(__FILE__, __LINE__, __PRETTY_FUNCTION__) #else -# define BOOST_CURRENT_LOCATION ::boost::source_location(__FILE__, __LINE__, BOOST_CURRENT_FUNCTION) +// __func__ macros aren't allowed outside functions, but BOOST_CURRENT_LOCATION is +# define BOOST_CURRENT_LOCATION ::boost::source_location(__FILE__, __LINE__, "") #endif diff --git a/include/boost/config/compiler/borland.hpp b/include/boost/config/compiler/borland.hpp new file mode 100644 index 000000000..567636c5b --- /dev/null +++ b/include/boost/config/compiler/borland.hpp @@ -0,0 +1,339 @@ +// (C) Copyright John Maddock 2001 - 2003. +// (C) Copyright David Abrahams 2002 - 2003. +// (C) Copyright Aleksey Gurtovoy 2002. +// Use, modification and distribution are subject to 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) + +// See http://www.boost.org for most recent version. + +// Borland C++ compiler setup: + +// +// versions check: +// we don't support Borland prior to version 5.4: +#if __BORLANDC__ < 0x540 +# error "Compiler not supported or configured - please reconfigure" +#endif + +// last known compiler version: +#if (__BORLANDC__ > 0x613) +//# if defined(BOOST_ASSERT_CONFIG) +# error "boost: Unknown compiler version - please run the configure tests and report the results" +//# else +//# pragma message( "boost: Unknown compiler version - please run the configure tests and report the results") +//# endif +#elif (__BORLANDC__ == 0x600) +# error "CBuilderX preview compiler is no longer supported" +#endif + +// +// Support macros to help with standard library detection +#if (__BORLANDC__ < 0x560) || defined(_USE_OLD_RW_STL) +# define BOOST_BCB_WITH_ROGUE_WAVE +#elif __BORLANDC__ < 0x570 +# define BOOST_BCB_WITH_STLPORT +#else +# define BOOST_BCB_WITH_DINKUMWARE +#endif + +// +// Version 5.0 and below: +# if __BORLANDC__ <= 0x0550 +// Borland C++Builder 4 and 5: +# define BOOST_NO_MEMBER_TEMPLATE_FRIENDS +# if __BORLANDC__ == 0x0550 +// Borland C++Builder 5, command-line compiler 5.5: +# define BOOST_NO_OPERATORS_IN_NAMESPACE +# endif +// Variadic macros do not exist for C++ Builder versions 5 and below +#define BOOST_NO_CXX11_VARIADIC_MACROS +# endif + +// Version 5.51 and below: +#if (__BORLANDC__ <= 0x551) +# define BOOST_NO_CV_SPECIALIZATIONS +# define BOOST_NO_CV_VOID_SPECIALIZATIONS +# define BOOST_NO_DEDUCED_TYPENAME +// workaround for missing WCHAR_MAX/WCHAR_MIN: +#ifdef __cplusplus +#include +#include +#else +#include +#include +#endif // __cplusplus +#ifndef WCHAR_MAX +# define WCHAR_MAX 0xffff +#endif +#ifndef WCHAR_MIN +# define WCHAR_MIN 0 +#endif +#endif + +// Borland C++ Builder 6 and below: +#if (__BORLANDC__ <= 0x564) + +# if defined(NDEBUG) && defined(__cplusplus) + // fix broken so that Boost.test works: +# include +# undef strcmp +# endif + // fix broken errno declaration: +# include +# ifndef errno +# define errno errno +# endif + +#endif + +// +// new bug in 5.61: +#if (__BORLANDC__ >= 0x561) && (__BORLANDC__ <= 0x580) + // this seems to be needed by the command line compiler, but not the IDE: +# define BOOST_NO_MEMBER_FUNCTION_SPECIALIZATIONS +#endif + +// Borland C++ Builder 2006 Update 2 and below: +#if (__BORLANDC__ <= 0x582) +# define BOOST_NO_SFINAE +# define BOOST_BCB_PARTIAL_SPECIALIZATION_BUG +# define BOOST_NO_TEMPLATE_TEMPLATES + +# define BOOST_NO_PRIVATE_IN_AGGREGATE + +# ifdef _WIN32 +# define BOOST_NO_SWPRINTF +# elif defined(linux) || defined(__linux__) || defined(__linux) + // we should really be able to do without this + // but the wcs* functions aren't imported into std:: +# define BOOST_NO_STDC_NAMESPACE + // _CPPUNWIND doesn't get automatically set for some reason: +# pragma defineonoption BOOST_CPPUNWIND -x +# endif +#endif + +#if (__BORLANDC__ <= 0x613) // Beman has asked Alisdair for more info + // we shouldn't really need this - but too many things choke + // without it, this needs more investigation: +# define BOOST_NO_LIMITS_COMPILE_TIME_CONSTANTS +# define BOOST_NO_IS_ABSTRACT +# define BOOST_NO_FUNCTION_TYPE_SPECIALIZATIONS +# define BOOST_NO_USING_TEMPLATE +# define BOOST_SP_NO_SP_CONVERTIBLE + +// Temporary workaround +#define BOOST_MPL_CFG_NO_PREPROCESSED_HEADERS +#endif + +// Borland C++ Builder 2008 and below: +# define BOOST_NO_INTEGRAL_INT64_T +# define BOOST_FUNCTION_SCOPE_USING_DECLARATION_BREAKS_ADL +# define BOOST_NO_DEPENDENT_NESTED_DERIVATIONS +# define BOOST_NO_MEMBER_TEMPLATE_FRIENDS +# define BOOST_NO_TWO_PHASE_NAME_LOOKUP +# define BOOST_NO_USING_DECLARATION_OVERLOADS_FROM_TYPENAME_BASE +# define BOOST_NO_NESTED_FRIENDSHIP +# define BOOST_NO_TYPENAME_WITH_CTOR +#if (__BORLANDC__ < 0x600) +# define BOOST_ILLEGAL_CV_REFERENCES +#endif + +// +// Positive Feature detection +// +// Borland C++ Builder 2008 and below: +#if (__BORLANDC__ >= 0x599) +# pragma defineonoption BOOST_CODEGEAR_0X_SUPPORT -Ax +#endif +// +// C++0x Macros: +// +#if !defined( BOOST_CODEGEAR_0X_SUPPORT ) || (__BORLANDC__ < 0x610) +# define BOOST_NO_CXX11_CHAR16_T +# define BOOST_NO_CXX11_CHAR32_T +# define BOOST_NO_CXX11_DECLTYPE +# define BOOST_NO_CXX11_EXPLICIT_CONVERSION_OPERATORS +# define BOOST_NO_CXX11_EXTERN_TEMPLATE +# define BOOST_NO_CXX11_RVALUE_REFERENCES +# define BOOST_NO_CXX11_SCOPED_ENUMS +# define BOOST_NO_CXX11_STATIC_ASSERT +#else +# define BOOST_HAS_ALIGNOF +# define BOOST_HAS_CHAR16_T +# define BOOST_HAS_CHAR32_T +# define BOOST_HAS_DECLTYPE +# define BOOST_HAS_EXPLICIT_CONVERSION_OPS +# define BOOST_HAS_REF_QUALIFIER +# define BOOST_HAS_RVALUE_REFS +# define BOOST_HAS_STATIC_ASSERT +#endif + +#define BOOST_NO_CXX11_AUTO_DECLARATIONS +#define BOOST_NO_CXX11_AUTO_MULTIDECLARATIONS +#define BOOST_NO_CXX11_CONSTEXPR +#define BOOST_NO_CXX11_DECLTYPE_N3276 +#define BOOST_NO_CXX11_DEFAULTED_FUNCTIONS +#define BOOST_NO_CXX11_DEFAULTED_MOVES +#define BOOST_NO_CXX11_DELETED_FUNCTIONS +#define BOOST_NO_CXX11_FUNCTION_TEMPLATE_DEFAULT_ARGS +#define BOOST_NO_CXX11_HDR_INITIALIZER_LIST +#define BOOST_NO_CXX11_LAMBDAS +#define BOOST_NO_CXX11_LOCAL_CLASS_TEMPLATE_PARAMETERS +#define BOOST_NO_CXX11_NULLPTR +#define BOOST_NO_CXX11_RANGE_BASED_FOR +#define BOOST_NO_CXX11_RAW_LITERALS +#define BOOST_NO_CXX11_RVALUE_REFERENCES +#define BOOST_NO_CXX11_SCOPED_ENUMS +#define BOOST_NO_SFINAE_EXPR +#define BOOST_NO_CXX11_SFINAE_EXPR +#define BOOST_NO_CXX11_TEMPLATE_ALIASES +#define BOOST_NO_CXX11_UNICODE_LITERALS // UTF-8 still not supported +#define BOOST_NO_CXX11_VARIADIC_TEMPLATES +#define BOOST_NO_CXX11_NOEXCEPT +#define BOOST_NO_CXX11_UNIFIED_INITIALIZATION_SYNTAX +#define BOOST_NO_CXX11_USER_DEFINED_LITERALS +#define BOOST_NO_CXX11_ALIGNAS +#define BOOST_NO_CXX11_ALIGNOF +#define BOOST_NO_CXX11_TRAILING_RESULT_TYPES +#define BOOST_NO_CXX11_INLINE_NAMESPACES +#define BOOST_NO_CXX11_REF_QUALIFIERS +#define BOOST_NO_CXX11_FINAL +#define BOOST_NO_CXX11_OVERRIDE +#define BOOST_NO_CXX11_THREAD_LOCAL +#define BOOST_NO_CXX11_UNRESTRICTED_UNION + +// C++ 14: +#if !defined(__cpp_aggregate_nsdmi) || (__cpp_aggregate_nsdmi < 201304) +# define BOOST_NO_CXX14_AGGREGATE_NSDMI +#endif +#if !defined(__cpp_binary_literals) || (__cpp_binary_literals < 201304) +# define BOOST_NO_CXX14_BINARY_LITERALS +#endif +#if !defined(__cpp_constexpr) || (__cpp_constexpr < 201304) +# define BOOST_NO_CXX14_CONSTEXPR +#endif +#if !defined(__cpp_decltype_auto) || (__cpp_decltype_auto < 201304) +# define BOOST_NO_CXX14_DECLTYPE_AUTO +#endif +#if (__cplusplus < 201304) // There's no SD6 check for this.... +# define BOOST_NO_CXX14_DIGIT_SEPARATORS +#endif +#if !defined(__cpp_generic_lambdas) || (__cpp_generic_lambdas < 201304) +# define BOOST_NO_CXX14_GENERIC_LAMBDAS +#endif +#if !defined(__cpp_init_captures) || (__cpp_init_captures < 201304) +# define BOOST_NO_CXX14_INITIALIZED_LAMBDA_CAPTURES +#endif +#if !defined(__cpp_return_type_deduction) || (__cpp_return_type_deduction < 201304) +# define BOOST_NO_CXX14_RETURN_TYPE_DEDUCTION +#endif +#if !defined(__cpp_variable_templates) || (__cpp_variable_templates < 201304) +# define BOOST_NO_CXX14_VARIABLE_TEMPLATES +#endif + +// C++17 +#if !defined(__cpp_structured_bindings) || (__cpp_structured_bindings < 201606) +# define BOOST_NO_CXX17_STRUCTURED_BINDINGS +#endif +#if !defined(__cpp_inline_variables) || (__cpp_inline_variables < 201606) +# define BOOST_NO_CXX17_INLINE_VARIABLES +#endif +#if !defined(__cpp_fold_expressions) || (__cpp_fold_expressions < 201603) +# define BOOST_NO_CXX17_FOLD_EXPRESSIONS +#endif +#if !defined(__cpp_if_constexpr) || (__cpp_if_constexpr < 201606) +# define BOOST_NO_CXX17_IF_CONSTEXPR +#endif + +#if __BORLANDC__ >= 0x590 +# define BOOST_HAS_TR1_HASH + +# define BOOST_HAS_MACRO_USE_FACET +#endif + +// +// Post 0x561 we have long long and stdint.h: +#if __BORLANDC__ >= 0x561 +# ifndef __NO_LONG_LONG +# define BOOST_HAS_LONG_LONG +# else +# define BOOST_NO_LONG_LONG +# endif + // On non-Win32 platforms let the platform config figure this out: +# ifdef _WIN32 +# define BOOST_HAS_STDINT_H +# endif +#endif + +// Borland C++Builder 6 defaults to using STLPort. If _USE_OLD_RW_STL is +// defined, then we have 0x560 or greater with the Rogue Wave implementation +// which presumably has the std::DBL_MAX bug. +#if defined( BOOST_BCB_WITH_ROGUE_WAVE ) +// is partly broken, some macros define symbols that are really in +// namespace std, so you end up having to use illegal constructs like +// std::DBL_MAX, as a fix we'll just include float.h and have done with: +#include +#endif +// +// __int64: +// +#if (__BORLANDC__ >= 0x530) && !defined(__STRICT_ANSI__) +# define BOOST_HAS_MS_INT64 +#endif +// +// check for exception handling support: +// +#if !defined(_CPPUNWIND) && !defined(BOOST_CPPUNWIND) && !defined(__EXCEPTIONS) && !defined(BOOST_NO_EXCEPTIONS) +# define BOOST_NO_EXCEPTIONS +#endif +// +// all versions have a : +// +#ifndef __STRICT_ANSI__ +# define BOOST_HAS_DIRENT_H +#endif +// +// all versions support __declspec: +// +#if defined(__STRICT_ANSI__) +// config/platform/win32.hpp will define BOOST_SYMBOL_EXPORT, etc., unless already defined +# define BOOST_SYMBOL_EXPORT +#endif +// +// ABI fixing headers: +// +#if __BORLANDC__ != 0x600 // not implemented for version 6 compiler yet +#ifndef BOOST_ABI_PREFIX +# define BOOST_ABI_PREFIX "boost/config/abi/borland_prefix.hpp" +#endif +#ifndef BOOST_ABI_SUFFIX +# define BOOST_ABI_SUFFIX "boost/config/abi/borland_suffix.hpp" +#endif +#endif +// +// Disable Win32 support in ANSI mode: +// +#if __BORLANDC__ < 0x600 +# pragma defineonoption BOOST_DISABLE_WIN32 -A +#elif defined(__STRICT_ANSI__) +# define BOOST_DISABLE_WIN32 +#endif +// +// MSVC compatibility mode does some nasty things: +// TODO: look up if this doesn't apply to the whole 12xx range +// +#if defined(_MSC_VER) && (_MSC_VER <= 1200) +# define BOOST_NO_ARGUMENT_DEPENDENT_LOOKUP +# define BOOST_NO_VOID_RETURNS +#endif + +// Borland did not implement value-initialization completely, as I reported +// in 2007, Borland Report 51854, "Value-initialization: POD struct should be +// zero-initialized", http://qc.embarcadero.com/wc/qcmain.aspx?d=51854 +// See also: http://www.boost.org/libs/utility/value_init.htm#compiler_issues +// (Niels Dekker, LKEB, April 2010) +#define BOOST_NO_COMPLETE_VALUE_INITIALIZATION + +#define BOOST_BORLANDC __BORLANDC__ +#define BOOST_COMPILER "Classic Borland C++ version " BOOST_STRINGIZE(__BORLANDC__) diff --git a/include/boost/config/compiler/clang.hpp b/include/boost/config/compiler/clang.hpp index 9d8ba7d71..1eeed315d 100644 --- a/include/boost/config/compiler/clang.hpp +++ b/include/boost/config/compiler/clang.hpp @@ -240,6 +240,10 @@ # define BOOST_NO_CXX11_ALIGNAS #endif +#if !__has_feature(cxx_alignof) +# define BOOST_NO_CXX11_ALIGNOF +#endif + #if !__has_feature(cxx_trailing_return) # define BOOST_NO_CXX11_TRAILING_RESULT_TYPES #endif @@ -325,11 +329,18 @@ // All versions with __cplusplus above this value seem to support this: # define BOOST_NO_CXX14_DIGIT_SEPARATORS #endif -// -// __builtin_unreachable: -#if defined(__has_builtin) && __has_builtin(__builtin_unreachable) + +// Unreachable code markup +#if defined(__has_builtin) +#if __has_builtin(__builtin_unreachable) #define BOOST_UNREACHABLE_RETURN(x) __builtin_unreachable(); #endif +#endif + +// Deprecated symbol markup +#if __has_attribute(deprecated) +#define BOOST_DEPRECATED(msg) __attribute__((deprecated(msg))) +#endif #if (__clang_major__ == 3) && (__clang_minor__ == 0) // Apparently a clang bug: @@ -351,3 +362,5 @@ // Macro used to identify the Clang compiler. #define BOOST_CLANG 1 +// BOOST_CLANG_VERSION +#include diff --git a/include/boost/config/compiler/clang_version.hpp b/include/boost/config/compiler/clang_version.hpp new file mode 100644 index 000000000..70c5507c4 --- /dev/null +++ b/include/boost/config/compiler/clang_version.hpp @@ -0,0 +1,83 @@ +// Copyright 2021 Peter Dimov +// Distributed under the Boost Software License, Version 1.0. +// https://www.boost.org/LICENSE_1_0.txt) + +#if !defined(__APPLE__) + +# define BOOST_CLANG_VERSION (__clang_major__ * 10000 + __clang_minor__ * 100 + __clang_patchlevel__ % 100) + +#else +# define BOOST_CLANG_REPORTED_VERSION (__clang_major__ * 10000 + __clang_minor__ * 100 + __clang_patchlevel__ % 100) + +// https://en.wikipedia.org/wiki/Xcode#Toolchain_versions + +# if BOOST_CLANG_REPORTED_VERSION >= 140000 +# define BOOST_CLANG_VERSION 140000 + +# elif BOOST_CLANG_REPORTED_VERSION >= 130100 +# define BOOST_CLANG_VERSION 130000 + +# elif BOOST_CLANG_REPORTED_VERSION >= 130000 +# define BOOST_CLANG_VERSION 120000 + +# elif BOOST_CLANG_REPORTED_VERSION >= 120005 +# define BOOST_CLANG_VERSION 110100 + +# elif BOOST_CLANG_REPORTED_VERSION >= 120000 +# define BOOST_CLANG_VERSION 100000 + +# elif BOOST_CLANG_REPORTED_VERSION >= 110003 +# define BOOST_CLANG_VERSION 90000 + +# elif BOOST_CLANG_REPORTED_VERSION >= 110000 +# define BOOST_CLANG_VERSION 80000 + +# elif BOOST_CLANG_REPORTED_VERSION >= 100001 +# define BOOST_CLANG_VERSION 70000 + +# elif BOOST_CLANG_REPORTED_VERSION >= 100000 +# define BOOST_CLANG_VERSION 60001 + +# elif BOOST_CLANG_REPORTED_VERSION >= 90100 +# define BOOST_CLANG_VERSION 50002 + +# elif BOOST_CLANG_REPORTED_VERSION >= 90000 +# define BOOST_CLANG_VERSION 40000 + +# elif BOOST_CLANG_REPORTED_VERSION >= 80000 +# define BOOST_CLANG_VERSION 30900 + +# elif BOOST_CLANG_REPORTED_VERSION >= 70300 +# define BOOST_CLANG_VERSION 30800 + +# elif BOOST_CLANG_REPORTED_VERSION >= 70000 +# define BOOST_CLANG_VERSION 30700 + +# elif BOOST_CLANG_REPORTED_VERSION >= 60100 +# define BOOST_CLANG_VERSION 30600 + +# elif BOOST_CLANG_REPORTED_VERSION >= 60000 +# define BOOST_CLANG_VERSION 30500 + +# elif BOOST_CLANG_REPORTED_VERSION >= 50100 +# define BOOST_CLANG_VERSION 30400 + +# elif BOOST_CLANG_REPORTED_VERSION >= 50000 +# define BOOST_CLANG_VERSION 30300 + +# elif BOOST_CLANG_REPORTED_VERSION >= 40200 +# define BOOST_CLANG_VERSION 30200 + +# elif BOOST_CLANG_REPORTED_VERSION >= 30100 +# define BOOST_CLANG_VERSION 30100 + +# elif BOOST_CLANG_REPORTED_VERSION >= 20100 +# define BOOST_CLANG_VERSION 30000 + +# else +# define BOOST_CLANG_VERSION 20900 + +# endif + +# undef BOOST_CLANG_REPORTED_VERSION +#endif diff --git a/include/boost/config/compiler/codegear.hpp b/include/boost/config/compiler/codegear.hpp index 77949aaf4..4d3f42aef 100644 --- a/include/boost/config/compiler/codegear.hpp +++ b/include/boost/config/compiler/codegear.hpp @@ -260,6 +260,7 @@ #define BOOST_NO_CXX11_UNIFIED_INITIALIZATION_SYNTAX #define BOOST_NO_CXX11_USER_DEFINED_LITERALS #define BOOST_NO_CXX11_ALIGNAS +#define BOOST_NO_CXX11_ALIGNOF #define BOOST_NO_CXX11_TRAILING_RESULT_TYPES #define BOOST_NO_CXX11_INLINE_NAMESPACES #define BOOST_NO_CXX11_REF_QUALIFIERS diff --git a/include/boost/config/compiler/comeau.hpp b/include/boost/config/compiler/comeau.hpp new file mode 100644 index 000000000..ca80fac37 --- /dev/null +++ b/include/boost/config/compiler/comeau.hpp @@ -0,0 +1,59 @@ +// (C) Copyright John Maddock 2001. +// (C) Copyright Douglas Gregor 2001. +// (C) Copyright Peter Dimov 2001. +// (C) Copyright Aleksey Gurtovoy 2003. +// (C) Copyright Beman Dawes 2003. +// (C) Copyright Jens Maurer 2003. +// Use, modification and distribution are subject to 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) + +// See http://www.boost.org for most recent version. + +// Comeau C++ compiler setup: + +#include + +#if (__COMO_VERSION__ <= 4245) + +# if defined(_MSC_VER) && _MSC_VER <= 1300 +# if _MSC_VER > 100 + // only set this in non-strict mode: +# define BOOST_NO_ARGUMENT_DEPENDENT_LOOKUP +# endif +# endif + +// Void returns don't work when emulating VC 6 (Peter Dimov) +// TODO: look up if this doesn't apply to the whole 12xx range +# if defined(_MSC_VER) && (_MSC_VER < 1300) +# define BOOST_NO_VOID_RETURNS +# endif + +#endif // version 4245 + +// +// enable __int64 support in VC emulation mode +// +# if defined(_MSC_VER) && (_MSC_VER >= 1200) +# define BOOST_HAS_MS_INT64 +# endif + +#define BOOST_COMPILER "Comeau compiler version " BOOST_STRINGIZE(__COMO_VERSION__) + +// +// versions check: +// we don't know Comeau prior to version 4245: +#if __COMO_VERSION__ < 4245 +# error "Compiler not configured - please reconfigure" +#endif +// +// last known and checked version is 4245: +#if (__COMO_VERSION__ > 4245) +# if defined(BOOST_ASSERT_CONFIG) +# error "boost: Unknown compiler version - please run the configure tests and report the results" +# endif +#endif + + + + diff --git a/include/boost/config/compiler/common_edg.hpp b/include/boost/config/compiler/common_edg.hpp index 6597cd2ac..dc049893c 100644 --- a/include/boost/config/compiler/common_edg.hpp +++ b/include/boost/config/compiler/common_edg.hpp @@ -77,32 +77,22 @@ #define BOOST_NO_CXX11_AUTO_DECLARATIONS #define BOOST_NO_CXX11_AUTO_MULTIDECLARATIONS -#define BOOST_NO_CXX11_CHAR16_T -#define BOOST_NO_CXX11_CHAR32_T -#define BOOST_NO_CXX11_CONSTEXPR -#define BOOST_NO_CXX11_DECLTYPE -#define BOOST_NO_CXX11_DECLTYPE_N3276 #define BOOST_NO_CXX11_DEFAULTED_FUNCTIONS #define BOOST_NO_CXX11_DELETED_FUNCTIONS #define BOOST_NO_CXX11_EXPLICIT_CONVERSION_OPERATORS #define BOOST_NO_CXX11_FUNCTION_TEMPLATE_DEFAULT_ARGS -#define BOOST_NO_CXX11_LAMBDAS #define BOOST_NO_CXX11_LOCAL_CLASS_TEMPLATE_PARAMETERS #define BOOST_NO_CXX11_NOEXCEPT #define BOOST_NO_CXX11_NULLPTR -#define BOOST_NO_CXX11_RANGE_BASED_FOR -#define BOOST_NO_CXX11_RAW_LITERALS #define BOOST_NO_CXX11_RVALUE_REFERENCES #define BOOST_NO_CXX11_SCOPED_ENUMS #define BOOST_NO_SFINAE_EXPR #define BOOST_NO_CXX11_SFINAE_EXPR #define BOOST_NO_CXX11_STATIC_ASSERT #define BOOST_NO_CXX11_TEMPLATE_ALIASES -#define BOOST_NO_CXX11_UNICODE_LITERALS -#define BOOST_NO_CXX11_VARIADIC_TEMPLATES #define BOOST_NO_CXX11_UNIFIED_INITIALIZATION_SYNTAX -#define BOOST_NO_CXX11_USER_DEFINED_LITERALS #define BOOST_NO_CXX11_ALIGNAS +#define BOOST_NO_CXX11_ALIGNOF #define BOOST_NO_CXX11_TRAILING_RESULT_TYPES #define BOOST_NO_CXX11_INLINE_NAMESPACES #define BOOST_NO_CXX11_REF_QUALIFIERS @@ -111,6 +101,37 @@ #define BOOST_NO_CXX11_THREAD_LOCAL #define BOOST_NO_CXX11_UNRESTRICTED_UNION +//__cpp_decltype 200707 possibly? +#define BOOST_NO_CXX11_DECLTYPE +#define BOOST_NO_CXX11_DECLTYPE_N3276 + +#if !defined(__cpp_unicode_characters) || (__cpp_unicode_characters < 200704) +# define BOOST_NO_CXX11_CHAR16_T +# define BOOST_NO_CXX11_CHAR32_T +#endif +#if !defined(__cpp_unicode_literals) || (__cpp_unicode_literals < 200710) +# define BOOST_NO_CXX11_UNICODE_LITERALS +#endif +#if !defined(__cpp_user_defined_literals) || (__cpp_user_defined_literals < 200809) +# define BOOST_NO_CXX11_USER_DEFINED_LITERALS +#endif +#if !defined(__cpp_variadic_templates) || (__cpp_variadic_templates < 200704) +# define BOOST_NO_CXX11_VARIADIC_TEMPLATES +#endif +#if !defined(__cpp_constexpr) || (__cpp_constexpr < 200907) +# define BOOST_NO_CXX11_CONSTEXPR +#endif +#if !defined(__cpp_lambdas) || (__cpp_lambdas < 200907) +# define BOOST_NO_CXX11_LAMBDAS +#endif +#if !defined(__cpp_range_based_for) || (__cpp_range_based_for < 200710) +# define BOOST_NO_CXX11_RANGE_BASED_FOR +#endif +#if !defined(__cpp_raw_strings) || (__cpp_raw_strings < 200610) +# define BOOST_NO_CXX11_RAW_LITERALS +#endif + + // C++ 14: #if !defined(__cpp_aggregate_nsdmi) || (__cpp_aggregate_nsdmi < 201304) # define BOOST_NO_CXX14_AGGREGATE_NSDMI diff --git a/include/boost/config/compiler/compaq_cxx.hpp b/include/boost/config/compiler/compaq_cxx.hpp new file mode 100644 index 000000000..4d6b8ab3a --- /dev/null +++ b/include/boost/config/compiler/compaq_cxx.hpp @@ -0,0 +1,19 @@ +// (C) Copyright John Maddock 2001 - 2003. +// Use, modification and distribution are subject to 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) + +// See http://www.boost.org for most recent version. + +// Tru64 C++ compiler setup (now HP): + +#define BOOST_COMPILER "HP Tru64 C++ " BOOST_STRINGIZE(__DECCXX_VER) + +#include + +// +// versions check: +// Nothing to do here? + + + diff --git a/include/boost/config/compiler/cray.hpp b/include/boost/config/compiler/cray.hpp new file mode 100644 index 000000000..e40fd05ac --- /dev/null +++ b/include/boost/config/compiler/cray.hpp @@ -0,0 +1,446 @@ +// Copyright 2011 John Maddock +// Copyright 2013, 2017-2018 Cray, Inc. +// Use, modification and distribution are subject to 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) + +// See http://www.boost.org for most recent version. + +// Cray C++ compiler setup. +// +// There are a few parameters that affect the macros defined in this file: +// +// - What version of CCE (Cray Compiling Environment) are we running? This +// comes from the '_RELEASE_MAJOR', '_RELEASE_MINOR', and +// '_RELEASE_PATCHLEVEL' macros. +// - What C++ standards conformance level are we using (e.g. '-h +// std=c++14')? This comes from the '__cplusplus' macro. +// - Are we using GCC extensions ('-h gnu' or '-h nognu')? If we have '-h +// gnu' then CCE emulates GCC, and the macros '__GNUC__', +// '__GNUC_MINOR__', and '__GNUC_PATCHLEVEL__' are defined. +// +// This file is organized as follows: +// +// - Verify that the combination of parameters listed above is supported. +// If we have an unsupported combination, we abort with '#error'. +// - Establish baseline values for all Boost macros. +// - Apply changes to the baseline macros based on compiler version. These +// changes are cummulative so each version section only describes the +// changes since the previous version. +// - Within each version section, we may also apply changes based on +// other parameters (i.e. C++ standards conformance level and GCC +// extensions). +// +// To test changes to this file: +// +// ``` +// module load cce/8.6.5 # Pick the version you want to test. +// cd boost/libs/config/test/all +// b2 -j 8 toolset=cray cxxstd=03 cxxstd=11 cxxstd=14 cxxstd-dialect=gnu linkflags=-lrt +// ``` +// Note: Using 'cxxstd-dialect=iso' is not supported at this time (the +// tests run, but many tests fail). +// +// Note: 'linkflags=-lrt' is needed in Cray Linux Environment. Otherwise +// you get an 'undefined reference to clock_gettime' error. +// +// Note: If a test '*_fail.cpp' file compiles, but fails to run, then it is +// reported as a defect. However, this is not actually a defect. This is an +// area where the test system is somewhat broken. Tests that are failing +// because of this problem are noted in the comments. +// +// Pay attention to the macro definitions for the macros you wish to +// modify. For example, only macros categorized as compiler macros should +// appear in this file; platform macros should not appear in this file. +// Also, some macros have to be defined to specific values; it is not +// always enough to define or undefine a macro. +// +// Macro definitions are available in the source code at: +// +// `boost/libs/config/doc/html/boost_config/boost_macro_reference.html` +// +// Macro definitions are also available online at: +// +// http://www.boost.org/doc/libs/master/libs/config/doc/html/boost_config/boost_macro_reference.html +// +// Typically, if you enable a feature, and the tests pass, then you have +// nothing to worry about. However, it's sometimes hard to figure out if a +// disabled feature needs to stay disabled. To get a list of disabled +// features, run 'b2' in 'boost/libs/config/checks'. These are the macros +// you should pay attention to (in addition to macros that cause test +// failures). + +//// +//// Front matter +//// + +// In a developer build of the Cray compiler (i.e. a compiler built by a +// Cray employee), the release patch level is reported as "x". This gives +// versions that look like e.g. "8.6.x". +// +// To accomplish this, the the Cray compiler preprocessor inserts: +// +// #define _RELEASE_PATCHLEVEL x +// +// If we are using a developer build of the compiler, we want to use the +// configuration macros for the most recent patch level of the release. To +// accomplish this, we'll pretend that _RELEASE_PATCHLEVEL is 99. +// +// However, it's difficult to detect if _RELEASE_PATCHLEVEL is x. We must +// consider that the x will be expanded if x is defined as a macro +// elsewhere. For example, imagine if someone put "-D x=3" on the command +// line, and _RELEASE_PATCHLEVEL is x. Then _RELEASE_PATCHLEVEL would +// expand to 3, and we could not distinguish it from an actual +// _RELEASE_PATCHLEVEL of 3. This problem only affects developer builds; in +// production builds, _RELEASE_PATCHLEVEL is always an integer. +// +// IMPORTANT: In developer builds, if x is defined as a macro, you will get +// an incorrect configuration. The behavior in this case is undefined. +// +// Even if x is not defined, we have to use some trickery to detect if +// _RELEASE_PATCHLEVEL is x. First we define BOOST_CRAY_x to some arbitrary +// magic value, 9867657. Then we use BOOST_CRAY_APPEND to append the +// expanded value of _RELEASE_PATCHLEVEL to the string "BOOST_CRAY_". +// +// - If _RELEASE_PATCHLEVEL is undefined, we get "BOOST_CRAY_". +// - If _RELEASE_PATCHLEVEL is 5, we get "BOOST_CRAY_5". +// - If _RELEASE_PATCHLEVEL is x (and x is not defined) we get +// "BOOST_CRAY_x": +// +// Then we check if BOOST_CRAY_x is equal to the output of +// BOOST_CRAY_APPEND. In other words, the output of BOOST_CRAY_APPEND is +// treated as a macro name, and expanded again. If we can safely assume +// that BOOST_CRAY_ is not a macro defined as our magic number, and +// BOOST_CRAY_5 is not a macro defined as our magic number, then the only +// way the equality test can pass is if _RELEASE_PATCHLEVEL expands to x. +// +// So, that is how we detect if we are using a developer build of the Cray +// compiler. + +#define BOOST_CRAY_x 9867657 // Arbitrary number +#define BOOST_CRAY_APPEND(MACRO) BOOST_CRAY_APPEND_INTERNAL(MACRO) +#define BOOST_CRAY_APPEND_INTERNAL(MACRO) BOOST_CRAY_##MACRO + +#if BOOST_CRAY_x == BOOST_CRAY_APPEND(_RELEASE_PATCHLEVEL) + + // This is a developer build. + // + // - _RELEASE_PATCHLEVEL is defined as x, and x is not defined as a macro. + + // Pretend _RELEASE_PATCHLEVEL is 99, so we get the configuration for the + // most recent patch level in this release. + + #define BOOST_CRAY_VERSION (_RELEASE_MAJOR * 10000 + _RELEASE_MINOR * 100 + 99) + +#else + + // This is a production build. + // + // _RELEASE_PATCHLEVEL is not defined as x, or x is defined as a macro. + + #define BOOST_CRAY_VERSION (_RELEASE_MAJOR * 10000 + _RELEASE_MINOR * 100 + _RELEASE_PATCHLEVEL) + +#endif // BOOST_CRAY_x == BOOST_CRAY_APPEND(_RELEASE_PATCHLEVEL) + +#undef BOOST_CRAY_APPEND_INTERNAL +#undef BOOST_CRAY_APPEND +#undef BOOST_CRAY_x + + +#ifdef __GNUC__ +# define BOOST_GCC_VERSION (__GNUC__ * 10000 + __GNUC_MINOR__ * 100 + __GNUC_PATCHLEVEL__) +#endif + +#ifndef BOOST_COMPILER +# define BOOST_COMPILER "Cray C++ version " BOOST_STRINGIZE(_RELEASE_MAJOR) "." BOOST_STRINGIZE(_RELEASE_MINOR) "." BOOST_STRINGIZE(_RELEASE_PATCHLEVEL) +#endif + +// Since the Cray compiler defines '__GNUC__', we have to emulate some +// additional GCC macros in order to make everything work. +// +// FIXME: Perhaps Cray should fix the compiler to define these additional +// macros for GCC emulation? + +#if __cplusplus >= 201103L && defined(__GNUC__) && !defined(__GXX_EXPERIMENTAL_CXX0X__) +# define __GXX_EXPERIMENTAL_CXX0X__ 1 +#endif + +//// +//// Parameter validation +//// + +// FIXME: Do we really need to support compilers before 8.5? Do they pass +// the Boost.Config tests? + +#if BOOST_CRAY_VERSION < 80000 +# error "Boost is not configured for Cray compilers prior to version 8, please try the configure script." +#endif + +// We only support recent EDG based compilers. + +#ifndef __EDG__ +# error "Unsupported Cray compiler, please try running the configure script." +#endif + +//// +//// Baseline values +//// + +#include + +#define BOOST_HAS_NRVO +#define BOOST_NO_COMPLETE_VALUE_INITIALIZATION +#define BOOST_NO_CXX11_AUTO_DECLARATIONS +#define BOOST_NO_CXX11_AUTO_MULTIDECLARATIONS +#define BOOST_NO_CXX11_CHAR16_T +#define BOOST_NO_CXX11_CHAR32_T +#define BOOST_NO_CXX11_CONSTEXPR +#define BOOST_NO_CXX11_DECLTYPE +#define BOOST_NO_CXX11_DECLTYPE_N3276 +#define BOOST_NO_CXX11_DEFAULTED_FUNCTIONS +#define BOOST_NO_CXX11_DELETED_FUNCTIONS +#define BOOST_NO_CXX11_EXPLICIT_CONVERSION_OPERATORS +#define BOOST_NO_CXX11_FINAL +#define BOOST_NO_CXX11_OVERRIDE +#define BOOST_NO_CXX11_FUNCTION_TEMPLATE_DEFAULT_ARGS +#define BOOST_NO_CXX11_LAMBDAS +#define BOOST_NO_CXX11_LOCAL_CLASS_TEMPLATE_PARAMETERS +#define BOOST_NO_CXX11_NOEXCEPT +#define BOOST_NO_CXX11_NULLPTR +#define BOOST_NO_CXX11_RANGE_BASED_FOR +#define BOOST_NO_CXX11_RAW_LITERALS +#define BOOST_NO_CXX11_REF_QUALIFIERS +#define BOOST_NO_CXX11_RVALUE_REFERENCES +#define BOOST_NO_CXX11_SCOPED_ENUMS +#define BOOST_NO_CXX11_SFINAE_EXPR +#define BOOST_NO_CXX11_STATIC_ASSERT +#define BOOST_NO_CXX11_TEMPLATE_ALIASES +#define BOOST_NO_CXX11_THREAD_LOCAL +#define BOOST_NO_CXX11_UNICODE_LITERALS +#define BOOST_NO_CXX11_UNIFIED_INITIALIZATION_SYNTAX +#define BOOST_NO_CXX11_USER_DEFINED_LITERALS +#define BOOST_NO_CXX11_VARIADIC_MACROS +#define BOOST_NO_CXX11_VARIADIC_TEMPLATES +#define BOOST_NO_CXX11_UNRESTRICTED_UNION +#define BOOST_NO_SFINAE_EXPR +#define BOOST_NO_TWO_PHASE_NAME_LOOKUP + +//#define BOOST_BCB_PARTIAL_SPECIALIZATION_BUG +#define BOOST_MATH_DISABLE_STD_FPCLASSIFY +//#define BOOST_HAS_FPCLASSIFY + +#define BOOST_SP_USE_PTHREADS +#define BOOST_AC_USE_PTHREADS + +// +// Everything that follows is working around what are thought to be +// compiler shortcomings. Revist all of these regularly. +// + +//#define BOOST_USE_ENUM_STATIC_ASSERT +//#define BOOST_BUGGY_INTEGRAL_CONSTANT_EXPRESSIONS //(this may be implied by the previous #define + +// These constants should be provided by the compiler. + +#ifndef __ATOMIC_RELAXED +#define __ATOMIC_RELAXED 0 +#define __ATOMIC_CONSUME 1 +#define __ATOMIC_ACQUIRE 2 +#define __ATOMIC_RELEASE 3 +#define __ATOMIC_ACQ_REL 4 +#define __ATOMIC_SEQ_CST 5 +#endif + +//// +//// Version changes +//// + +// +// 8.5.0 +// + +#if BOOST_CRAY_VERSION >= 80500 + +#if __cplusplus >= 201103L + +#undef BOOST_HAS_NRVO +#undef BOOST_NO_COMPLETE_VALUE_INITIALIZATION +#undef BOOST_NO_CXX11_AUTO_DECLARATIONS +#undef BOOST_NO_CXX11_AUTO_MULTIDECLARATIONS +#undef BOOST_NO_CXX11_CHAR16_T +#undef BOOST_NO_CXX11_CHAR32_T +#undef BOOST_NO_CXX11_CONSTEXPR +#undef BOOST_NO_CXX11_DECLTYPE +#undef BOOST_NO_CXX11_DECLTYPE_N3276 +#undef BOOST_NO_CXX11_DEFAULTED_FUNCTIONS +#undef BOOST_NO_CXX11_DELETED_FUNCTIONS +#undef BOOST_NO_CXX11_EXPLICIT_CONVERSION_OPERATORS +#undef BOOST_NO_CXX11_FINAL +#undef BOOST_NO_CXX11_OVERRIDE +#undef BOOST_NO_CXX11_FUNCTION_TEMPLATE_DEFAULT_ARGS +#undef BOOST_NO_CXX11_LAMBDAS +#undef BOOST_NO_CXX11_LOCAL_CLASS_TEMPLATE_PARAMETERS +#undef BOOST_NO_CXX11_NOEXCEPT +#undef BOOST_NO_CXX11_NULLPTR +#undef BOOST_NO_CXX11_RANGE_BASED_FOR +#undef BOOST_NO_CXX11_RAW_LITERALS +#undef BOOST_NO_CXX11_REF_QUALIFIERS +#undef BOOST_NO_CXX11_RVALUE_REFERENCES +#undef BOOST_NO_CXX11_SCOPED_ENUMS +#undef BOOST_NO_CXX11_SFINAE_EXPR +#undef BOOST_NO_CXX11_STATIC_ASSERT +#undef BOOST_NO_CXX11_TEMPLATE_ALIASES +#undef BOOST_NO_CXX11_THREAD_LOCAL +#undef BOOST_NO_CXX11_UNICODE_LITERALS +#undef BOOST_NO_CXX11_UNIFIED_INITIALIZATION_SYNTAX +#undef BOOST_NO_CXX11_USER_DEFINED_LITERALS +#undef BOOST_NO_CXX11_VARIADIC_MACROS +#undef BOOST_NO_CXX11_VARIADIC_TEMPLATES +#undef BOOST_NO_CXX11_UNRESTRICTED_UNION +#undef BOOST_NO_SFINAE_EXPR +#undef BOOST_NO_TWO_PHASE_NAME_LOOKUP +#undef BOOST_MATH_DISABLE_STD_FPCLASSIFY +#undef BOOST_SP_USE_PTHREADS +#undef BOOST_AC_USE_PTHREADS + +#define BOOST_HAS_VARIADIC_TMPL +#define BOOST_HAS_UNISTD_H +#define BOOST_HAS_TR1_COMPLEX_INVERSE_TRIG +#define BOOST_HAS_TR1_COMPLEX_OVERLOADS +#define BOOST_HAS_STDINT_H +#define BOOST_HAS_STATIC_ASSERT +#define BOOST_HAS_SIGACTION +#define BOOST_HAS_SCHED_YIELD +#define BOOST_HAS_RVALUE_REFS +#define BOOST_HAS_PTHREADS +#define BOOST_HAS_PTHREAD_YIELD +#define BOOST_HAS_PTHREAD_MUTEXATTR_SETTYPE +#define BOOST_HAS_PARTIAL_STD_ALLOCATOR +#define BOOST_HAS_NRVO +#define BOOST_HAS_NL_TYPES_H +#define BOOST_HAS_NANOSLEEP +#define BOOST_NO_CXX11_SMART_PTR +#define BOOST_NO_CXX11_HDR_FUNCTIONAL +#define BOOST_NO_CXX14_CONSTEXPR +#define BOOST_HAS_LONG_LONG +#define BOOST_HAS_FLOAT128 + +#if __cplusplus < 201402L +#define BOOST_NO_CXX11_DECLTYPE_N3276 +#endif // __cplusplus < 201402L + +#endif // __cplusplus >= 201103L + +#endif // BOOST_CRAY_VERSION >= 80500 + +// +// 8.6.4 +// (versions prior to 8.6.5 do not define _RELEASE_PATCHLEVEL) +// + +#if BOOST_CRAY_VERSION >= 80600 + +#if __cplusplus >= 199711L +#define BOOST_HAS_FLOAT128 +#define BOOST_HAS_PTHREAD_YIELD // This is a platform macro, but it improves test results. +#define BOOST_NO_COMPLETE_VALUE_INITIALIZATION // This is correct. Test compiles, but fails to run. +#undef BOOST_NO_CXX11_CHAR16_T +#undef BOOST_NO_CXX11_CHAR32_T +#undef BOOST_NO_CXX11_INLINE_NAMESPACES +#undef BOOST_NO_CXX11_FINAL +#undef BOOST_NO_CXX11_OVERRIDE +#undef BOOST_NO_CXX11_FIXED_LENGTH_VARIADIC_TEMPLATE_EXPANSION_PACKS +#undef BOOST_NO_CXX11_FUNCTION_TEMPLATE_DEFAULT_ARGS +#define BOOST_NO_CXX11_SFINAE_EXPR // This is correct, even though '*_fail.cpp' test fails. +#undef BOOST_NO_CXX11_UNIFIED_INITIALIZATION_SYNTAX +#undef BOOST_NO_CXX11_VARIADIC_MACROS +#undef BOOST_NO_CXX11_VARIADIC_TEMPLATES +// 'BOOST_NO_DEDUCED_TYPENAME' test is broken. The test files are enabled / +// disabled with an '#ifdef BOOST_DEDUCED_TYPENAME'. However, +// 'boost/libs/config/include/boost/config/detail/suffix.hpp' ensures that +// 'BOOST_DEDUCED_TYPENAME' is always defined (the value it is defined as +// depends on 'BOOST_NO_DEDUCED_TYPENAME'). So, modifying +// 'BOOST_NO_DEDUCED_TYPENAME' has no effect on which tests are run. +// +// The 'no_ded_typename_pass.cpp' test should always compile and run +// successfully, because 'BOOST_DEDUCED_TYPENAME' must always have an +// appropriate value (it's not just something that you turn on or off). +// Therefore, if you wish to test changes to 'BOOST_NO_DEDUCED_TYPENAME', +// you have to modify 'no_ded_typename_pass.cpp' to unconditionally include +// 'boost_no_ded_typename.ipp'. +#undef BOOST_NO_DEDUCED_TYPENAME // This is correct. Test is broken. +#undef BOOST_NO_SFINAE_EXPR +#undef BOOST_NO_TWO_PHASE_NAME_LOOKUP +#endif // __cplusplus >= 199711L + +#if __cplusplus >= 201103L +#undef BOOST_NO_CXX11_ALIGNAS +#undef BOOST_NO_CXX11_ALIGNOF +#undef BOOST_NO_CXX11_DECLTYPE_N3276 +#define BOOST_NO_CXX11_HDR_ATOMIC +#undef BOOST_NO_CXX11_HDR_FUNCTIONAL +#define BOOST_NO_CXX11_HDR_REGEX // This is correct. Test compiles, but fails to run. +#undef BOOST_NO_CXX11_SFINAE_EXPR +#undef BOOST_NO_CXX11_SMART_PTR +#undef BOOST_NO_CXX11_TRAILING_RESULT_TYPES +#endif // __cplusplus >= 201103L + +#if __cplusplus >= 201402L +#undef BOOST_NO_CXX14_CONSTEXPR +#define BOOST_NO_CXX14_DIGIT_SEPARATORS +#endif // __cplusplus == 201402L + +#endif // BOOST_CRAY_VERSION >= 80600 + +// +// 8.6.5 +// (no change from 8.6.4) +// + +// +// 8.7.0 +// + +#if BOOST_CRAY_VERSION >= 80700 + +#if __cplusplus >= 199711L +#endif // __cplusplus >= 199711L + +#if __cplusplus >= 201103L +#undef BOOST_NO_CXX11_HDR_ATOMIC +#undef BOOST_NO_CXX11_HDR_REGEX +#endif // __cplusplus >= 201103L + +#if __cplusplus >= 201402L +#endif // __cplusplus == 201402L + +#endif // BOOST_CRAY_VERSION >= 80700 + +// +// Next release +// + +#if BOOST_CRAY_VERSION > 80799 + +#if __cplusplus >= 199711L +#endif // __cplusplus >= 199711L + +#if __cplusplus >= 201103L +#endif // __cplusplus >= 201103L + +#if __cplusplus >= 201402L +#endif // __cplusplus == 201402L + +#endif // BOOST_CRAY_VERSION > 80799 + +//// +//// Remove temporary macros +//// + +// I've commented out some '#undef' statements to signify that we purposely +// want to keep certain macros. + +//#undef __GXX_EXPERIMENTAL_CXX0X__ +//#undef BOOST_COMPILER +#undef BOOST_GCC_VERSION +#undef BOOST_CRAY_VERSION diff --git a/include/boost/config/compiler/digitalmars.hpp b/include/boost/config/compiler/digitalmars.hpp new file mode 100644 index 000000000..bb56ff6c0 --- /dev/null +++ b/include/boost/config/compiler/digitalmars.hpp @@ -0,0 +1,143 @@ +// Copyright (C) Christof Meerwald 2003 +// Copyright (C) Dan Watkins 2003 +// +// Use, modification and distribution are subject to 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) + +// Digital Mars C++ compiler setup: +#define BOOST_COMPILER __DMC_VERSION_STRING__ + +#define BOOST_HAS_LONG_LONG +#define BOOST_HAS_PRAGMA_ONCE + +#if !defined(BOOST_STRICT_CONFIG) +#define BOOST_NO_MEMBER_TEMPLATE_FRIENDS +#define BOOST_NO_OPERATORS_IN_NAMESPACE +#define BOOST_NO_UNREACHABLE_RETURN_DETECTION +#define BOOST_NO_SFINAE +#define BOOST_NO_USING_TEMPLATE +#define BOOST_FUNCTION_SCOPE_USING_DECLARATION_BREAKS_ADL +#endif + +// +// has macros: +#define BOOST_HAS_DIRENT_H +#define BOOST_HAS_STDINT_H +#define BOOST_HAS_WINTHREADS + +#if (__DMC__ >= 0x847) +#define BOOST_HAS_EXPM1 +#define BOOST_HAS_LOG1P +#endif + +// +// Is this really the best way to detect whether the std lib is in namespace std? +// +#ifdef __cplusplus +#include +#endif +#if !defined(__STL_IMPORT_VENDOR_CSTD) && !defined(_STLP_IMPORT_VENDOR_CSTD) +# define BOOST_NO_STDC_NAMESPACE +#endif + + +// check for exception handling support: +#if !defined(_CPPUNWIND) && !defined(BOOST_NO_EXCEPTIONS) +# define BOOST_NO_EXCEPTIONS +#endif + +// +// C++0x features +// +#define BOOST_NO_CXX11_AUTO_DECLARATIONS +#define BOOST_NO_CXX11_AUTO_MULTIDECLARATIONS +#define BOOST_NO_CXX11_CHAR16_T +#define BOOST_NO_CXX11_CHAR32_T +#define BOOST_NO_CXX11_CONSTEXPR +#define BOOST_NO_CXX11_DECLTYPE +#define BOOST_NO_CXX11_DECLTYPE_N3276 +#define BOOST_NO_CXX11_DEFAULTED_FUNCTIONS +#define BOOST_NO_CXX11_DELETED_FUNCTIONS +#define BOOST_NO_CXX11_EXPLICIT_CONVERSION_OPERATORS +#define BOOST_NO_CXX11_EXTERN_TEMPLATE +#define BOOST_NO_CXX11_HDR_INITIALIZER_LIST +#define BOOST_NO_CXX11_LAMBDAS +#define BOOST_NO_CXX11_LOCAL_CLASS_TEMPLATE_PARAMETERS +#define BOOST_NO_CXX11_NOEXCEPT +#define BOOST_NO_CXX11_NULLPTR +#define BOOST_NO_CXX11_RANGE_BASED_FOR +#define BOOST_NO_CXX11_RAW_LITERALS +#define BOOST_NO_CXX11_RVALUE_REFERENCES +#define BOOST_NO_CXX11_SCOPED_ENUMS +#define BOOST_NO_SFINAE_EXPR +#define BOOST_NO_CXX11_SFINAE_EXPR +#define BOOST_NO_CXX11_STATIC_ASSERT +#define BOOST_NO_CXX11_TEMPLATE_ALIASES +#define BOOST_NO_CXX11_UNICODE_LITERALS +#define BOOST_NO_CXX11_VARIADIC_TEMPLATES +#define BOOST_NO_CXX11_UNIFIED_INITIALIZATION_SYNTAX +#define BOOST_NO_CXX11_USER_DEFINED_LITERALS +#define BOOST_NO_CXX11_ALIGNAS +#define BOOST_NO_CXX11_ALIGNOF +#define BOOST_NO_CXX11_TRAILING_RESULT_TYPES +#define BOOST_NO_CXX11_INLINE_NAMESPACES +#define BOOST_NO_CXX11_REF_QUALIFIERS +#define BOOST_NO_CXX11_FINAL +#define BOOST_NO_CXX11_OVERRIDE +#define BOOST_NO_CXX11_THREAD_LOCAL +#define BOOST_NO_CXX11_UNRESTRICTED_UNION + +// C++ 14: +#if !defined(__cpp_aggregate_nsdmi) || (__cpp_aggregate_nsdmi < 201304) +# define BOOST_NO_CXX14_AGGREGATE_NSDMI +#endif +#if !defined(__cpp_binary_literals) || (__cpp_binary_literals < 201304) +# define BOOST_NO_CXX14_BINARY_LITERALS +#endif +#if !defined(__cpp_constexpr) || (__cpp_constexpr < 201304) +# define BOOST_NO_CXX14_CONSTEXPR +#endif +#if !defined(__cpp_decltype_auto) || (__cpp_decltype_auto < 201304) +# define BOOST_NO_CXX14_DECLTYPE_AUTO +#endif +#if (__cplusplus < 201304) // There's no SD6 check for this.... +# define BOOST_NO_CXX14_DIGIT_SEPARATORS +#endif +#if !defined(__cpp_generic_lambdas) || (__cpp_generic_lambdas < 201304) +# define BOOST_NO_CXX14_GENERIC_LAMBDAS +#endif +#if !defined(__cpp_init_captures) || (__cpp_init_captures < 201304) +# define BOOST_NO_CXX14_INITIALIZED_LAMBDA_CAPTURES +#endif +#if !defined(__cpp_return_type_deduction) || (__cpp_return_type_deduction < 201304) +# define BOOST_NO_CXX14_RETURN_TYPE_DEDUCTION +#endif +#if !defined(__cpp_variable_templates) || (__cpp_variable_templates < 201304) +# define BOOST_NO_CXX14_VARIABLE_TEMPLATES +#endif + +// C++17 +#if !defined(__cpp_structured_bindings) || (__cpp_structured_bindings < 201606) +# define BOOST_NO_CXX17_STRUCTURED_BINDINGS +#endif +#if !defined(__cpp_inline_variables) || (__cpp_inline_variables < 201606) +# define BOOST_NO_CXX17_INLINE_VARIABLES +#endif +#if !defined(__cpp_fold_expressions) || (__cpp_fold_expressions < 201603) +# define BOOST_NO_CXX17_FOLD_EXPRESSIONS +#endif +#if !defined(__cpp_if_constexpr) || (__cpp_if_constexpr < 201606) +# define BOOST_NO_CXX17_IF_CONSTEXPR +#endif + +#if (__DMC__ <= 0x840) +#error "Compiler not supported or configured - please reconfigure" +#endif +// +// last known and checked version is ...: +#if (__DMC__ > 0x848) +# if defined(BOOST_ASSERT_CONFIG) +# error "boost: Unknown compiler version - please run the configure tests and report the results" +# endif +#endif diff --git a/include/boost/config/compiler/gcc.hpp b/include/boost/config/compiler/gcc.hpp index da1a43229..2f1fe5508 100644 --- a/include/boost/config/compiler/gcc.hpp +++ b/include/boost/config/compiler/gcc.hpp @@ -219,6 +219,7 @@ # define BOOST_NO_CXX11_LOCAL_CLASS_TEMPLATE_PARAMETERS # define BOOST_NO_CXX11_RAW_LITERALS # define BOOST_NO_CXX11_UNICODE_LITERALS +# define BOOST_NO_CXX11_ALIGNOF #endif // C++0x features in 4.5.1 and later @@ -271,7 +272,7 @@ // #if (BOOST_GCC_VERSION < 40900) || !defined(BOOST_GCC_CXX11) // Although alignas support is added in gcc 4.8, it does not accept -// constant expressions as an argument until gcc 4.9. +// dependent constant expressions as an argument until gcc 4.9. # define BOOST_NO_CXX11_ALIGNAS #endif @@ -323,9 +324,10 @@ # define BOOST_FALLTHROUGH __attribute__((fallthrough)) #endif -#if defined(__MINGW32__) && !defined(__MINGW64__) -// Currently (March 2019) thread_local is broken on mingw for all current 32bit compiler releases, see +#if (__GNUC__ < 11) && defined(__MINGW32__) && !defined(__MINGW64__) +// thread_local was broken on mingw for all 32bit compiler releases prior to 11.x, see // https://sourceforge.net/p/mingw-w64/bugs/527/ +// https://gcc.gnu.org/bugzilla/show_bug.cgi?id=83562 // Not setting this causes program termination on thread exit. #define BOOST_NO_CXX11_THREAD_LOCAL #endif @@ -339,12 +341,18 @@ // Type aliasing hint. Supported since gcc 3.3. #define BOOST_MAY_ALIAS __attribute__((__may_alias__)) -// -// __builtin_unreachable: +// Unreachable code markup #if BOOST_GCC_VERSION >= 40500 #define BOOST_UNREACHABLE_RETURN(x) __builtin_unreachable(); #endif +// Deprecated symbol markup +#if BOOST_GCC_VERSION >= 40500 +#define BOOST_DEPRECATED(msg) __attribute__((deprecated(msg))) +#else +#define BOOST_DEPRECATED(msg) __attribute__((deprecated)) +#endif + #ifndef BOOST_COMPILER # define BOOST_COMPILER "GNU C++ version " __VERSION__ #endif @@ -358,7 +366,7 @@ // versions check: // we don't know gcc prior to version 3.30: -#if (BOOST_GCC_VERSION< 30300) +#if (BOOST_GCC_VERSION < 30300) # error "Compiler not configured - please reconfigure" #endif // diff --git a/include/boost/config/compiler/gcc_xml.hpp b/include/boost/config/compiler/gcc_xml.hpp new file mode 100644 index 000000000..75cac44e9 --- /dev/null +++ b/include/boost/config/compiler/gcc_xml.hpp @@ -0,0 +1,114 @@ +// (C) Copyright John Maddock 2006. +// Use, modification and distribution are subject to 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) + +// See http://www.boost.org for most recent version. + +// GCC-XML C++ compiler setup: + +# if !defined(__GCCXML_GNUC__) || ((__GCCXML_GNUC__ <= 3) && (__GCCXML_GNUC_MINOR__ <= 3)) +# define BOOST_NO_IS_ABSTRACT +# endif + +// +// Threading support: Turn this on unconditionally here (except for +// those platforms where we can know for sure). It will get turned off again +// later if no threading API is detected. +// +#if !defined(__MINGW32__) && !defined(_MSC_VER) && !defined(linux) && !defined(__linux) && !defined(__linux__) +# define BOOST_HAS_THREADS +#endif + +// +// gcc has "long long" +// +#define BOOST_HAS_LONG_LONG + +// C++0x features: +// +# define BOOST_NO_CXX11_CONSTEXPR +# define BOOST_NO_CXX11_NULLPTR +# define BOOST_NO_CXX11_TEMPLATE_ALIASES +# define BOOST_NO_CXX11_DECLTYPE +# define BOOST_NO_CXX11_DECLTYPE_N3276 +# define BOOST_NO_CXX11_FUNCTION_TEMPLATE_DEFAULT_ARGS +# define BOOST_NO_CXX11_RVALUE_REFERENCES +# define BOOST_NO_CXX11_STATIC_ASSERT +# define BOOST_NO_CXX11_VARIADIC_TEMPLATES +# define BOOST_NO_CXX11_VARIADIC_MACROS +# define BOOST_NO_CXX11_AUTO_DECLARATIONS +# define BOOST_NO_CXX11_AUTO_MULTIDECLARATIONS +# define BOOST_NO_CXX11_CHAR16_T +# define BOOST_NO_CXX11_CHAR32_T +# define BOOST_NO_CXX11_DEFAULTED_FUNCTIONS +# define BOOST_NO_CXX11_DELETED_FUNCTIONS +# define BOOST_NO_CXX11_HDR_INITIALIZER_LIST +# define BOOST_NO_CXX11_SCOPED_ENUMS +# define BOOST_NO_SFINAE_EXPR +# define BOOST_NO_CXX11_SFINAE_EXPR +# define BOOST_NO_CXX11_EXPLICIT_CONVERSION_OPERATORS +# define BOOST_NO_CXX11_LAMBDAS +# define BOOST_NO_CXX11_LOCAL_CLASS_TEMPLATE_PARAMETERS +# define BOOST_NO_CXX11_RANGE_BASED_FOR +# define BOOST_NO_CXX11_RAW_LITERALS +# define BOOST_NO_CXX11_UNICODE_LITERALS +# define BOOST_NO_CXX11_NOEXCEPT +# define BOOST_NO_CXX11_UNIFIED_INITIALIZATION_SYNTAX +# define BOOST_NO_CXX11_USER_DEFINED_LITERALS +# define BOOST_NO_CXX11_ALIGNAS +# define BOOST_NO_CXX11_ALIGNOF +# define BOOST_NO_CXX11_TRAILING_RESULT_TYPES +# define BOOST_NO_CXX11_INLINE_NAMESPACES +# define BOOST_NO_CXX11_REF_QUALIFIERS +# define BOOST_NO_CXX11_FINAL +# define BOOST_NO_CXX11_OVERRIDE +# define BOOST_NO_CXX11_THREAD_LOCAL +# define BOOST_NO_CXX11_UNRESTRICTED_UNION + +// C++ 14: +#if !defined(__cpp_aggregate_nsdmi) || (__cpp_aggregate_nsdmi < 201304) +# define BOOST_NO_CXX14_AGGREGATE_NSDMI +#endif +#if !defined(__cpp_binary_literals) || (__cpp_binary_literals < 201304) +# define BOOST_NO_CXX14_BINARY_LITERALS +#endif +#if !defined(__cpp_constexpr) || (__cpp_constexpr < 201304) +# define BOOST_NO_CXX14_CONSTEXPR +#endif +#if !defined(__cpp_decltype_auto) || (__cpp_decltype_auto < 201304) +# define BOOST_NO_CXX14_DECLTYPE_AUTO +#endif +#if (__cplusplus < 201304) // There's no SD6 check for this.... +# define BOOST_NO_CXX14_DIGIT_SEPARATORS +#endif +#if !defined(__cpp_generic_lambdas) || (__cpp_generic_lambdas < 201304) +# define BOOST_NO_CXX14_GENERIC_LAMBDAS +#endif +#if !defined(__cpp_init_captures) || (__cpp_init_captures < 201304) +# define BOOST_NO_CXX14_INITIALIZED_LAMBDA_CAPTURES +#endif +#if !defined(__cpp_return_type_deduction) || (__cpp_return_type_deduction < 201304) +# define BOOST_NO_CXX14_RETURN_TYPE_DEDUCTION +#endif +#if !defined(__cpp_variable_templates) || (__cpp_variable_templates < 201304) +# define BOOST_NO_CXX14_VARIABLE_TEMPLATES +#endif + +// C++17 +#if !defined(__cpp_structured_bindings) || (__cpp_structured_bindings < 201606) +# define BOOST_NO_CXX17_STRUCTURED_BINDINGS +#endif +#if !defined(__cpp_inline_variables) || (__cpp_inline_variables < 201606) +# define BOOST_NO_CXX17_INLINE_VARIABLES +#endif +#if !defined(__cpp_fold_expressions) || (__cpp_fold_expressions < 201603) +# define BOOST_NO_CXX17_FOLD_EXPRESSIONS +#endif +#if !defined(__cpp_if_constexpr) || (__cpp_if_constexpr < 201606) +# define BOOST_NO_CXX17_IF_CONSTEXPR +#endif + +#define BOOST_COMPILER "GCC-XML C++ version " __GCCXML__ + + diff --git a/include/boost/config/compiler/greenhills.hpp b/include/boost/config/compiler/greenhills.hpp new file mode 100644 index 000000000..39112c2c1 --- /dev/null +++ b/include/boost/config/compiler/greenhills.hpp @@ -0,0 +1,28 @@ +// (C) Copyright John Maddock 2001. +// Use, modification and distribution are subject to 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) + +// See http://www.boost.org for most recent version. + +// Greenhills C++ compiler setup: + +#define BOOST_COMPILER "Greenhills C++ version " BOOST_STRINGIZE(__ghs) + +#include + +// +// versions check: +// we don't support Greenhills prior to version 0: +#if __ghs < 0 +# error "Compiler not supported or configured - please reconfigure" +#endif +// +// last known and checked version is 0: +#if (__ghs > 0) +# if defined(BOOST_ASSERT_CONFIG) +# error "boost: Unknown compiler version - please run the configure tests and report the results" +# endif +#endif + + diff --git a/include/boost/config/compiler/hp_acc.hpp b/include/boost/config/compiler/hp_acc.hpp index cf5667b52..25636324b 100644 --- a/include/boost/config/compiler/hp_acc.hpp +++ b/include/boost/config/compiler/hp_acc.hpp @@ -121,6 +121,7 @@ #define BOOST_NO_CXX11_VARIADIC_TEMPLATES #define BOOST_NO_CXX11_USER_DEFINED_LITERALS #define BOOST_NO_CXX11_ALIGNAS +#define BOOST_NO_CXX11_ALIGNOF #define BOOST_NO_CXX11_TRAILING_RESULT_TYPES #define BOOST_NO_CXX11_INLINE_NAMESPACES #define BOOST_NO_CXX11_REF_QUALIFIERS diff --git a/include/boost/config/compiler/intel.hpp b/include/boost/config/compiler/intel.hpp index 9a06d2fe3..6a343972e 100644 --- a/include/boost/config/compiler/intel.hpp +++ b/include/boost/config/compiler/intel.hpp @@ -483,6 +483,7 @@ template<> struct assert_intrinsic_wchar_t {}; // BOOST_NO_CXX11_ALIGNAS #if (BOOST_INTEL_CXX_VERSION >= 1500) && (!defined(BOOST_INTEL_GCC_VERSION) || (BOOST_INTEL_GCC_VERSION >= 40800)) && (!defined(_MSC_VER) || (_MSC_FULL_VER >= 190021730)) # undef BOOST_NO_CXX11_ALIGNAS +# undef BOOST_NO_CXX11_ALIGNOF #endif // BOOST_NO_CXX11_TRAILING_RESULT_TYPES diff --git a/include/boost/config/compiler/kai.hpp b/include/boost/config/compiler/kai.hpp new file mode 100644 index 000000000..0b22ec1d6 --- /dev/null +++ b/include/boost/config/compiler/kai.hpp @@ -0,0 +1,33 @@ +// (C) Copyright John Maddock 2001. +// (C) Copyright David Abrahams 2002. +// (C) Copyright Aleksey Gurtovoy 2002. +// Use, modification and distribution are subject to 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) + +// See http://www.boost.org for most recent version. + +// Kai C++ compiler setup: + +#include + +# if (__KCC_VERSION <= 4001) || !defined(BOOST_STRICT_CONFIG) + // at least on Sun, the contents of is not in namespace std +# define BOOST_NO_STDC_NAMESPACE +# endif + +// see also common_edg.hpp which needs a special check for __KCC +# if !defined(_EXCEPTIONS) && !defined(BOOST_NO_EXCEPTIONS) +# define BOOST_NO_EXCEPTIONS +# endif + +// +// last known and checked version is 4001: +#if (__KCC_VERSION > 4001) +# if defined(BOOST_ASSERT_CONFIG) +# error "boost: Unknown compiler version - please run the configure tests and report the results" +# endif +#endif + + + diff --git a/include/boost/config/compiler/metrowerks.hpp b/include/boost/config/compiler/metrowerks.hpp new file mode 100644 index 000000000..448ab67bc --- /dev/null +++ b/include/boost/config/compiler/metrowerks.hpp @@ -0,0 +1,198 @@ +// (C) Copyright John Maddock 2001. +// (C) Copyright Darin Adler 2001. +// (C) Copyright Peter Dimov 2001. +// (C) Copyright David Abrahams 2001 - 2002. +// (C) Copyright Beman Dawes 2001 - 2003. +// (C) Copyright Stefan Slapeta 2004. +// Use, modification and distribution are subject to 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) + +// See http://www.boost.org for most recent version. + +// Metrowerks C++ compiler setup: + +// locale support is disabled when linking with the dynamic runtime +# ifdef _MSL_NO_LOCALE +# define BOOST_NO_STD_LOCALE +# endif + +# if __MWERKS__ <= 0x2301 // 5.3 +# define BOOST_NO_FUNCTION_TEMPLATE_ORDERING +# define BOOST_NO_POINTER_TO_MEMBER_CONST +# define BOOST_NO_DEPENDENT_TYPES_IN_TEMPLATE_VALUE_PARAMETERS +# define BOOST_NO_MEMBER_TEMPLATE_KEYWORD +# endif + +# if __MWERKS__ <= 0x2401 // 6.2 +//# define BOOST_NO_FUNCTION_TEMPLATE_ORDERING +# endif + +# if(__MWERKS__ <= 0x2407) // 7.x +# define BOOST_NO_MEMBER_FUNCTION_SPECIALIZATIONS +# define BOOST_NO_UNREACHABLE_RETURN_DETECTION +# endif + +# if(__MWERKS__ <= 0x3003) // 8.x +# define BOOST_NO_SFINAE +# endif + +// the "|| !defined(BOOST_STRICT_CONFIG)" part should apply to the last +// tested version *only*: +# if(__MWERKS__ <= 0x3207) || !defined(BOOST_STRICT_CONFIG) // 9.6 +# define BOOST_NO_MEMBER_TEMPLATE_FRIENDS +# define BOOST_NO_IS_ABSTRACT +# endif + +#if !__option(wchar_type) +# define BOOST_NO_INTRINSIC_WCHAR_T +#endif + +#if !__option(exceptions) && !defined(BOOST_NO_EXCEPTIONS) +# define BOOST_NO_EXCEPTIONS +#endif + +#if (__INTEL__ && _WIN32) || (__POWERPC__ && macintosh) +# if __MWERKS__ == 0x3000 +# define BOOST_COMPILER_VERSION 8.0 +# elif __MWERKS__ == 0x3001 +# define BOOST_COMPILER_VERSION 8.1 +# elif __MWERKS__ == 0x3002 +# define BOOST_COMPILER_VERSION 8.2 +# elif __MWERKS__ == 0x3003 +# define BOOST_COMPILER_VERSION 8.3 +# elif __MWERKS__ == 0x3200 +# define BOOST_COMPILER_VERSION 9.0 +# elif __MWERKS__ == 0x3201 +# define BOOST_COMPILER_VERSION 9.1 +# elif __MWERKS__ == 0x3202 +# define BOOST_COMPILER_VERSION 9.2 +# elif __MWERKS__ == 0x3204 +# define BOOST_COMPILER_VERSION 9.3 +# elif __MWERKS__ == 0x3205 +# define BOOST_COMPILER_VERSION 9.4 +# elif __MWERKS__ == 0x3206 +# define BOOST_COMPILER_VERSION 9.5 +# elif __MWERKS__ == 0x3207 +# define BOOST_COMPILER_VERSION 9.6 +# else +# define BOOST_COMPILER_VERSION __MWERKS__ +# endif +#else +# define BOOST_COMPILER_VERSION __MWERKS__ +#endif + +// +// C++0x features +// +// See boost\config\suffix.hpp for BOOST_NO_LONG_LONG +// +#if __MWERKS__ > 0x3206 && __option(rvalue_refs) +# define BOOST_HAS_RVALUE_REFS +#else +# define BOOST_NO_CXX11_RVALUE_REFERENCES +#endif +#define BOOST_NO_CXX11_AUTO_DECLARATIONS +#define BOOST_NO_CXX11_AUTO_MULTIDECLARATIONS +#define BOOST_NO_CXX11_CHAR16_T +#define BOOST_NO_CXX11_CHAR32_T +#define BOOST_NO_CXX11_CONSTEXPR +#define BOOST_NO_CXX11_DECLTYPE +#define BOOST_NO_CXX11_DECLTYPE_N3276 +#define BOOST_NO_CXX11_DEFAULTED_FUNCTIONS +#define BOOST_NO_CXX11_DELETED_FUNCTIONS +#define BOOST_NO_CXX11_EXPLICIT_CONVERSION_OPERATORS +#define BOOST_NO_CXX11_EXTERN_TEMPLATE +#define BOOST_NO_CXX11_FUNCTION_TEMPLATE_DEFAULT_ARGS +#define BOOST_NO_CXX11_HDR_INITIALIZER_LIST +#define BOOST_NO_CXX11_LAMBDAS +#define BOOST_NO_CXX11_LOCAL_CLASS_TEMPLATE_PARAMETERS +#define BOOST_NO_CXX11_NOEXCEPT +#define BOOST_NO_CXX11_NULLPTR +#define BOOST_NO_CXX11_RANGE_BASED_FOR +#define BOOST_NO_CXX11_RAW_LITERALS +#define BOOST_NO_CXX11_SCOPED_ENUMS +#define BOOST_NO_SFINAE_EXPR +#define BOOST_NO_CXX11_SFINAE_EXPR +#define BOOST_NO_CXX11_STATIC_ASSERT +#define BOOST_NO_CXX11_TEMPLATE_ALIASES +#define BOOST_NO_CXX11_UNICODE_LITERALS +#define BOOST_NO_CXX11_VARIADIC_TEMPLATES +#define BOOST_NO_CXX11_VARIADIC_MACROS +#define BOOST_NO_CXX11_UNIFIED_INITIALIZATION_SYNTAX +#define BOOST_NO_CXX11_USER_DEFINED_LITERALS +#define BOOST_NO_CXX11_ALIGNAS +#define BOOST_NO_CXX11_ALIGNOF +#define BOOST_NO_CXX11_TRAILING_RESULT_TYPES +#define BOOST_NO_CXX11_INLINE_NAMESPACES +#define BOOST_NO_CXX11_REF_QUALIFIERS +#define BOOST_NO_CXX11_FINAL +#define BOOST_NO_CXX11_OVERRIDE +#define BOOST_NO_CXX11_THREAD_LOCAL +#define BOOST_NO_CXX11_UNRESTRICTED_UNION + +// C++ 14: +#if !defined(__cpp_aggregate_nsdmi) || (__cpp_aggregate_nsdmi < 201304) +# define BOOST_NO_CXX14_AGGREGATE_NSDMI +#endif +#if !defined(__cpp_binary_literals) || (__cpp_binary_literals < 201304) +# define BOOST_NO_CXX14_BINARY_LITERALS +#endif +#if !defined(__cpp_constexpr) || (__cpp_constexpr < 201304) +# define BOOST_NO_CXX14_CONSTEXPR +#endif +#if !defined(__cpp_decltype_auto) || (__cpp_decltype_auto < 201304) +# define BOOST_NO_CXX14_DECLTYPE_AUTO +#endif +#if (__cplusplus < 201304) // There's no SD6 check for this.... +# define BOOST_NO_CXX14_DIGIT_SEPARATORS +#endif +#if !defined(__cpp_generic_lambdas) || (__cpp_generic_lambdas < 201304) +# define BOOST_NO_CXX14_GENERIC_LAMBDAS +#endif +#if !defined(__cpp_init_captures) || (__cpp_init_captures < 201304) +# define BOOST_NO_CXX14_INITIALIZED_LAMBDA_CAPTURES +#endif +#if !defined(__cpp_return_type_deduction) || (__cpp_return_type_deduction < 201304) +# define BOOST_NO_CXX14_RETURN_TYPE_DEDUCTION +#endif +#if !defined(__cpp_variable_templates) || (__cpp_variable_templates < 201304) +# define BOOST_NO_CXX14_VARIABLE_TEMPLATES +#endif + +// C++17 +#if !defined(__cpp_structured_bindings) || (__cpp_structured_bindings < 201606) +# define BOOST_NO_CXX17_STRUCTURED_BINDINGS +#endif +#if !defined(__cpp_inline_variables) || (__cpp_inline_variables < 201606) +# define BOOST_NO_CXX17_INLINE_VARIABLES +#endif +#if !defined(__cpp_fold_expressions) || (__cpp_fold_expressions < 201603) +# define BOOST_NO_CXX17_FOLD_EXPRESSIONS +#endif +#if !defined(__cpp_if_constexpr) || (__cpp_if_constexpr < 201606) +# define BOOST_NO_CXX17_IF_CONSTEXPR +#endif + +#define BOOST_COMPILER "Metrowerks CodeWarrior C++ version " BOOST_STRINGIZE(BOOST_COMPILER_VERSION) + +// +// versions check: +// we don't support Metrowerks prior to version 5.3: +#if __MWERKS__ < 0x2301 +# error "Compiler not supported or configured - please reconfigure" +#endif +// +// last known and checked version: +#if (__MWERKS__ > 0x3205) +# if defined(BOOST_ASSERT_CONFIG) +# error "boost: Unknown compiler version - please run the configure tests and report the results" +# endif +#endif + + + + + + + diff --git a/include/boost/config/compiler/mpw.hpp b/include/boost/config/compiler/mpw.hpp new file mode 100644 index 000000000..8433f3719 --- /dev/null +++ b/include/boost/config/compiler/mpw.hpp @@ -0,0 +1,140 @@ +// (C) Copyright John Maddock 2001 - 2002. +// (C) Copyright Aleksey Gurtovoy 2002. +// Use, modification and distribution are subject to 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) + +// See http://www.boost.org for most recent version. + +// MPW C++ compilers setup: + +# if defined(__SC__) +# define BOOST_COMPILER "MPW SCpp version " BOOST_STRINGIZE(__SC__) +# elif defined(__MRC__) +# define BOOST_COMPILER "MPW MrCpp version " BOOST_STRINGIZE(__MRC__) +# else +# error "Using MPW compiler configuration by mistake. Please update." +# endif + +// +// MPW 8.90: +// +#if (MPW_CPLUS <= 0x890) || !defined(BOOST_STRICT_CONFIG) +# define BOOST_NO_CV_SPECIALIZATIONS +# define BOOST_NO_DEPENDENT_NESTED_DERIVATIONS +# define BOOST_NO_DEPENDENT_TYPES_IN_TEMPLATE_VALUE_PARAMETERS +# define BOOST_NO_INCLASS_MEMBER_INITIALIZATION +# define BOOST_NO_INTRINSIC_WCHAR_T +# define BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION +# define BOOST_NO_USING_TEMPLATE + +# define BOOST_NO_CWCHAR +# define BOOST_NO_LIMITS_COMPILE_TIME_CONSTANTS + +# define BOOST_NO_STD_ALLOCATOR /* actually a bug with const reference overloading */ + +#endif + +// +// C++0x features +// +// See boost\config\suffix.hpp for BOOST_NO_LONG_LONG +// +#define BOOST_NO_CXX11_AUTO_DECLARATIONS +#define BOOST_NO_CXX11_AUTO_MULTIDECLARATIONS +#define BOOST_NO_CXX11_CHAR16_T +#define BOOST_NO_CXX11_CHAR32_T +#define BOOST_NO_CXX11_CONSTEXPR +#define BOOST_NO_CXX11_DECLTYPE +#define BOOST_NO_CXX11_DECLTYPE_N3276 +#define BOOST_NO_CXX11_DEFAULTED_FUNCTIONS +#define BOOST_NO_CXX11_DELETED_FUNCTIONS +#define BOOST_NO_CXX11_EXPLICIT_CONVERSION_OPERATORS +#define BOOST_NO_CXX11_EXTERN_TEMPLATE +#define BOOST_NO_CXX11_FUNCTION_TEMPLATE_DEFAULT_ARGS +#define BOOST_NO_CXX11_HDR_INITIALIZER_LIST +#define BOOST_NO_CXX11_LAMBDAS +#define BOOST_NO_CXX11_LOCAL_CLASS_TEMPLATE_PARAMETERS +#define BOOST_NO_CXX11_NOEXCEPT +#define BOOST_NO_CXX11_NULLPTR +#define BOOST_NO_CXX11_RANGE_BASED_FOR +#define BOOST_NO_CXX11_RAW_LITERALS +#define BOOST_NO_CXX11_RVALUE_REFERENCES +#define BOOST_NO_CXX11_SCOPED_ENUMS +#define BOOST_NO_SFINAE_EXPR +#define BOOST_NO_CXX11_SFINAE_EXPR +#define BOOST_NO_CXX11_STATIC_ASSERT +#define BOOST_NO_CXX11_TEMPLATE_ALIASES +#define BOOST_NO_CXX11_UNICODE_LITERALS +#define BOOST_NO_CXX11_VARIADIC_TEMPLATES +#define BOOST_NO_CXX11_VARIADIC_MACROS +#define BOOST_NO_CXX11_UNIFIED_INITIALIZATION_SYNTAX +#define BOOST_NO_CXX11_USER_DEFINED_LITERALS +#define BOOST_NO_CXX11_ALIGNAS +#define BOOST_NO_CXX11_ALIGNOF +#define BOOST_NO_CXX11_TRAILING_RESULT_TYPES +#define BOOST_NO_CXX11_INLINE_NAMESPACES +#define BOOST_NO_CXX11_REF_QUALIFIERS +#define BOOST_NO_CXX11_FINAL +#define BOOST_NO_CXX11_OVERRIDE +#define BOOST_NO_CXX11_THREAD_LOCAL +#define BOOST_NO_CXX11_UNRESTRICTED_UNION + +// C++ 14: +#if !defined(__cpp_aggregate_nsdmi) || (__cpp_aggregate_nsdmi < 201304) +# define BOOST_NO_CXX14_AGGREGATE_NSDMI +#endif +#if !defined(__cpp_binary_literals) || (__cpp_binary_literals < 201304) +# define BOOST_NO_CXX14_BINARY_LITERALS +#endif +#if !defined(__cpp_constexpr) || (__cpp_constexpr < 201304) +# define BOOST_NO_CXX14_CONSTEXPR +#endif +#if !defined(__cpp_decltype_auto) || (__cpp_decltype_auto < 201304) +# define BOOST_NO_CXX14_DECLTYPE_AUTO +#endif +#if (__cplusplus < 201304) // There's no SD6 check for this.... +# define BOOST_NO_CXX14_DIGIT_SEPARATORS +#endif +#if !defined(__cpp_generic_lambdas) || (__cpp_generic_lambdas < 201304) +# define BOOST_NO_CXX14_GENERIC_LAMBDAS +#endif +#if !defined(__cpp_init_captures) || (__cpp_init_captures < 201304) +# define BOOST_NO_CXX14_INITIALIZED_LAMBDA_CAPTURES +#endif +#if !defined(__cpp_return_type_deduction) || (__cpp_return_type_deduction < 201304) +# define BOOST_NO_CXX14_RETURN_TYPE_DEDUCTION +#endif +#if !defined(__cpp_variable_templates) || (__cpp_variable_templates < 201304) +# define BOOST_NO_CXX14_VARIABLE_TEMPLATES +#endif + +// C++17 +#if !defined(__cpp_structured_bindings) || (__cpp_structured_bindings < 201606) +# define BOOST_NO_CXX17_STRUCTURED_BINDINGS +#endif +#if !defined(__cpp_inline_variables) || (__cpp_inline_variables < 201606) +# define BOOST_NO_CXX17_INLINE_VARIABLES +#endif +#if !defined(__cpp_fold_expressions) || (__cpp_fold_expressions < 201603) +# define BOOST_NO_CXX17_FOLD_EXPRESSIONS +#endif +#if !defined(__cpp_if_constexpr) || (__cpp_if_constexpr < 201606) +# define BOOST_NO_CXX17_IF_CONSTEXPR +#endif + +// +// versions check: +// we don't support MPW prior to version 8.9: +#if MPW_CPLUS < 0x890 +# error "Compiler not supported or configured - please reconfigure" +#endif +// +// last known and checked version is 0x890: +#if (MPW_CPLUS > 0x890) +# if defined(BOOST_ASSERT_CONFIG) +# error "boost: Unknown compiler version - please run the configure tests and report the results" +# endif +#endif + + diff --git a/include/boost/config/compiler/nvcc.hpp b/include/boost/config/compiler/nvcc.hpp new file mode 100644 index 000000000..419dd724a --- /dev/null +++ b/include/boost/config/compiler/nvcc.hpp @@ -0,0 +1,61 @@ +// (C) Copyright Eric Jourdanneau, Joel Falcou 2010 +// Use, modification and distribution are subject to 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) + +// See http://www.boost.org for most recent version. + +// NVIDIA CUDA C++ compiler setup + +#ifndef BOOST_COMPILER +# define BOOST_COMPILER "NVIDIA CUDA C++ Compiler" +#endif + +#if defined(__CUDACC_VER_MAJOR__) && defined(__CUDACC_VER_MINOR__) && defined(__CUDACC_VER_BUILD__) +# define BOOST_CUDA_VERSION (__CUDACC_VER_MAJOR__ * 1000000 + __CUDACC_VER_MINOR__ * 10000 + __CUDACC_VER_BUILD__) +#else +// We don't really know what the CUDA version is, but it's definitely before 7.5: +# define BOOST_CUDA_VERSION 7000000 +#endif + +// NVIDIA Specific support +// BOOST_GPU_ENABLED : Flag a function or a method as being enabled on the host and device +#define BOOST_GPU_ENABLED __host__ __device__ + +#if !defined(__clang__) || defined(__NVCC__) +// A bug in version 7.0 of CUDA prevents use of variadic templates in some occasions +// https://svn.boost.org/trac/boost/ticket/11897 +// This is fixed in 7.5. As the following version macro was introduced in 7.5 an existance +// check is enough to detect versions < 7.5 +#if BOOST_CUDA_VERSION < 7050000 +# define BOOST_NO_CXX11_VARIADIC_TEMPLATES +#endif +// The same bug is back again in 8.0: +#if (BOOST_CUDA_VERSION > 8000000) && (BOOST_CUDA_VERSION < 8010000) +# define BOOST_NO_CXX11_VARIADIC_TEMPLATES +#endif +// CUDA (8.0) has no constexpr support in msvc mode: +#if defined(_MSC_VER) && (BOOST_CUDA_VERSION < 9000000) +# define BOOST_NO_CXX11_CONSTEXPR +#endif + +#endif + +#ifdef __CUDACC__ +// +// When compiing .cu files, there's a bunch of stuff that doesn't work with msvc: +// +#if defined(_MSC_VER) +# define BOOST_NO_CXX14_DIGIT_SEPARATORS +# define BOOST_NO_CXX11_UNICODE_LITERALS +#endif +// +// And this one effects the NVCC front end, +// See https://svn.boost.org/trac/boost/ticket/13049 +// +#if (BOOST_CUDA_VERSION >= 8000000) && (BOOST_CUDA_VERSION < 8010000) +# define BOOST_NO_CXX11_NOEXCEPT +#endif + +#endif + diff --git a/include/boost/config/compiler/pathscale.hpp b/include/boost/config/compiler/pathscale.hpp new file mode 100644 index 000000000..5348cf7f7 --- /dev/null +++ b/include/boost/config/compiler/pathscale.hpp @@ -0,0 +1,138 @@ +// (C) Copyright Bryce Lelbach 2011 + +// Use, modification and distribution are subject to 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) + +// See http://www.boost.org for most recent version. + +// PathScale EKOPath C++ Compiler + +#ifndef BOOST_COMPILER +# define BOOST_COMPILER "PathScale EKOPath C++ Compiler version " __PATHSCALE__ +#endif + +#if __PATHCC__ >= 6 +// PathCC is based on clang, and supports the __has_*() builtins used +// to detect features in clang.hpp. Since the clang toolset is much +// better maintained, it is more convenient to reuse its definitions. +# include "boost/config/compiler/clang.hpp" +#elif __PATHCC__ >= 4 +# define BOOST_MSVC6_MEMBER_TEMPLATES +# define BOOST_HAS_UNISTD_H +# define BOOST_HAS_STDINT_H +# define BOOST_HAS_SIGACTION +# define BOOST_HAS_SCHED_YIELD +# define BOOST_HAS_THREADS +# define BOOST_HAS_PTHREADS +# define BOOST_HAS_PTHREAD_YIELD +# define BOOST_HAS_PTHREAD_MUTEXATTR_SETTYPE +# define BOOST_HAS_PARTIAL_STD_ALLOCATOR +# define BOOST_HAS_NRVO +# define BOOST_HAS_NL_TYPES_H +# define BOOST_HAS_NANOSLEEP +# define BOOST_HAS_LONG_LONG +# define BOOST_HAS_LOG1P +# define BOOST_HAS_GETTIMEOFDAY +# define BOOST_HAS_EXPM1 +# define BOOST_HAS_DIRENT_H +# define BOOST_HAS_CLOCK_GETTIME +# define BOOST_NO_CXX11_VARIADIC_TEMPLATES +# define BOOST_NO_CXX11_UNICODE_LITERALS +# define BOOST_NO_CXX11_TEMPLATE_ALIASES +# define BOOST_NO_CXX11_STATIC_ASSERT +# define BOOST_NO_SFINAE_EXPR +# define BOOST_NO_CXX11_SFINAE_EXPR +# define BOOST_NO_CXX11_SCOPED_ENUMS +# define BOOST_NO_CXX11_RVALUE_REFERENCES +# define BOOST_NO_CXX11_RANGE_BASED_FOR +# define BOOST_NO_CXX11_RAW_LITERALS +# define BOOST_NO_CXX11_NULLPTR +# define BOOST_NO_CXX11_NUMERIC_LIMITS +# define BOOST_NO_CXX11_NOEXCEPT +# define BOOST_NO_CXX11_LAMBDAS +# define BOOST_NO_CXX11_LOCAL_CLASS_TEMPLATE_PARAMETERS +# define BOOST_NO_MS_INT64_NUMERIC_LIMITS +# define BOOST_NO_CXX11_FUNCTION_TEMPLATE_DEFAULT_ARGS +# define BOOST_NO_CXX11_EXPLICIT_CONVERSION_OPERATORS +# define BOOST_NO_CXX11_DELETED_FUNCTIONS +# define BOOST_NO_CXX11_DEFAULTED_FUNCTIONS +# define BOOST_NO_CXX11_DECLTYPE +# define BOOST_NO_CXX11_DECLTYPE_N3276 +# define BOOST_NO_CXX11_CONSTEXPR +# define BOOST_NO_COMPLETE_VALUE_INITIALIZATION +# define BOOST_NO_CXX11_CHAR32_T +# define BOOST_NO_CXX11_CHAR16_T +# define BOOST_NO_CXX11_AUTO_MULTIDECLARATIONS +# define BOOST_NO_CXX11_AUTO_DECLARATIONS +# define BOOST_NO_CXX11_UNIFIED_INITIALIZATION_SYNTAX +# define BOOST_NO_CXX11_HDR_UNORDERED_SET +# define BOOST_NO_CXX11_HDR_UNORDERED_MAP +# define BOOST_NO_CXX11_HDR_TYPEINDEX +# define BOOST_NO_CXX11_HDR_TUPLE +# define BOOST_NO_CXX11_HDR_THREAD +# define BOOST_NO_CXX11_HDR_SYSTEM_ERROR +# define BOOST_NO_CXX11_HDR_REGEX +# define BOOST_NO_CXX11_HDR_RATIO +# define BOOST_NO_CXX11_HDR_RANDOM +# define BOOST_NO_CXX11_HDR_MUTEX +# define BOOST_NO_CXX11_HDR_INITIALIZER_LIST +# define BOOST_NO_CXX11_HDR_FUTURE +# define BOOST_NO_CXX11_HDR_FORWARD_LIST +# define BOOST_NO_CXX11_HDR_CONDITION_VARIABLE +# define BOOST_NO_CXX11_HDR_CODECVT +# define BOOST_NO_CXX11_HDR_CHRONO +# define BOOST_NO_CXX11_USER_DEFINED_LITERALS +# define BOOST_NO_CXX11_ALIGNAS +# define BOOST_NO_CXX11_ALIGNOF +# define BOOST_NO_CXX11_TRAILING_RESULT_TYPES +# define BOOST_NO_CXX11_INLINE_NAMESPACES +# define BOOST_NO_CXX11_REF_QUALIFIERS +# define BOOST_NO_CXX11_FINAL +# define BOOST_NO_CXX11_OVERRIDE +# define BOOST_NO_CXX11_THREAD_LOCAL +# define BOOST_NO_CXX11_UNRESTRICTED_UNION + +// C++ 14: +#if !defined(__cpp_aggregate_nsdmi) || (__cpp_aggregate_nsdmi < 201304) +# define BOOST_NO_CXX14_AGGREGATE_NSDMI +#endif +#if !defined(__cpp_binary_literals) || (__cpp_binary_literals < 201304) +# define BOOST_NO_CXX14_BINARY_LITERALS +#endif +#if !defined(__cpp_constexpr) || (__cpp_constexpr < 201304) +# define BOOST_NO_CXX14_CONSTEXPR +#endif +#if !defined(__cpp_decltype_auto) || (__cpp_decltype_auto < 201304) +# define BOOST_NO_CXX14_DECLTYPE_AUTO +#endif +#if (__cplusplus < 201304) // There's no SD6 check for this.... +# define BOOST_NO_CXX14_DIGIT_SEPARATORS +#endif +#if !defined(__cpp_generic_lambdas) || (__cpp_generic_lambdas < 201304) +# define BOOST_NO_CXX14_GENERIC_LAMBDAS +#endif +#if !defined(__cpp_init_captures) || (__cpp_init_captures < 201304) +# define BOOST_NO_CXX14_INITIALIZED_LAMBDA_CAPTURES +#endif +#if !defined(__cpp_return_type_deduction) || (__cpp_return_type_deduction < 201304) +# define BOOST_NO_CXX14_RETURN_TYPE_DEDUCTION +#endif +#if !defined(__cpp_variable_templates) || (__cpp_variable_templates < 201304) +# define BOOST_NO_CXX14_VARIABLE_TEMPLATES +#endif + +// C++17 +#if !defined(__cpp_structured_bindings) || (__cpp_structured_bindings < 201606) +# define BOOST_NO_CXX17_STRUCTURED_BINDINGS +#endif +#if !defined(__cpp_inline_variables) || (__cpp_inline_variables < 201606) +# define BOOST_NO_CXX17_INLINE_VARIABLES +#endif +#if !defined(__cpp_fold_expressions) || (__cpp_fold_expressions < 201603) +# define BOOST_NO_CXX17_FOLD_EXPRESSIONS +#endif +#if !defined(__cpp_if_constexpr) || (__cpp_if_constexpr < 201606) +# define BOOST_NO_CXX17_IF_CONSTEXPR +#endif +#endif diff --git a/include/boost/config/compiler/pgi.hpp b/include/boost/config/compiler/pgi.hpp new file mode 100644 index 000000000..4e909d8a1 --- /dev/null +++ b/include/boost/config/compiler/pgi.hpp @@ -0,0 +1,23 @@ +// (C) Copyright Noel Belcourt 2007. +// Copyright 2017, NVIDIA CORPORATION. +// Use, modification and distribution are subject to 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) + +// See http://www.boost.org for most recent version. + +// PGI C++ compiler setup: + +#define BOOST_COMPILER_VERSION __PGIC__##__PGIC_MINOR__ +#define BOOST_COMPILER "PGI compiler version " BOOST_STRINGIZE(BOOST_COMPILER_VERSION) + +// PGI is mostly GNU compatible. So start with that. +#include + +// Now adjust for things that are different. + +// __float128 is a typedef, not a distinct type. +#undef BOOST_HAS_FLOAT128 + +// __int128 is not supported. +#undef BOOST_HAS_INT128 diff --git a/include/boost/config/compiler/sgi_mipspro.hpp b/include/boost/config/compiler/sgi_mipspro.hpp new file mode 100644 index 000000000..54433c997 --- /dev/null +++ b/include/boost/config/compiler/sgi_mipspro.hpp @@ -0,0 +1,29 @@ +// (C) Copyright John Maddock 2001 - 2002. +// Use, modification and distribution are subject to 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) + +// See http://www.boost.org for most recent version. + +// SGI C++ compiler setup: + +#define BOOST_COMPILER "SGI Irix compiler version " BOOST_STRINGIZE(_COMPILER_VERSION) + +#include + +// +// Threading support: +// Turn this on unconditionally here, it will get turned off again later +// if no threading API is detected. +// +#define BOOST_HAS_THREADS +#define BOOST_NO_TWO_PHASE_NAME_LOOKUP + +#undef BOOST_NO_SWPRINTF +#undef BOOST_DEDUCED_TYPENAME + +// +// version check: +// probably nothing to do here? + + diff --git a/include/boost/config/compiler/sunpro_cc.hpp b/include/boost/config/compiler/sunpro_cc.hpp index c674e8ab5..490dc76dc 100644 --- a/include/boost/config/compiler/sunpro_cc.hpp +++ b/include/boost/config/compiler/sunpro_cc.hpp @@ -86,6 +86,12 @@ # define BOOST_SYMBOL_VISIBLE __global #endif +// Deprecated symbol markup +// Oracle Studio 12.4 supports deprecated attribute with a message; this is the first release that supports the attribute. +#if (__SUNPRO_CC >= 0x5130) +#define BOOST_DEPRECATED(msg) __attribute__((deprecated(msg))) +#endif + #if (__SUNPRO_CC < 0x5130) // C++03 features in 12.4: #define BOOST_NO_TWO_PHASE_NAME_LOOKUP @@ -120,6 +126,7 @@ #define BOOST_NO_CXX11_TEMPLATE_ALIASES #define BOOST_NO_CXX11_UNICODE_LITERALS #define BOOST_NO_CXX11_ALIGNAS +#define BOOST_NO_CXX11_ALIGNOF #define BOOST_NO_CXX11_TRAILING_RESULT_TYPES #define BOOST_NO_CXX11_INLINE_NAMESPACES #define BOOST_NO_CXX11_FINAL diff --git a/include/boost/config/compiler/vacpp.hpp b/include/boost/config/compiler/vacpp.hpp new file mode 100644 index 000000000..9cfa1adf8 --- /dev/null +++ b/include/boost/config/compiler/vacpp.hpp @@ -0,0 +1,186 @@ +// (C) Copyright John Maddock 2001 - 2003. +// (C) Copyright Toon Knapen 2001 - 2003. +// (C) Copyright Lie-Quan Lee 2001. +// (C) Copyright Markus Schoepflin 2002 - 2003. +// (C) Copyright Beman Dawes 2002 - 2003. +// Use, modification and distribution are subject to 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) + +// See http://www.boost.org for most recent version. + +// Visual Age (IBM) C++ compiler setup: + +#if __IBMCPP__ <= 501 +# define BOOST_NO_MEMBER_TEMPLATE_FRIENDS +# define BOOST_NO_MEMBER_FUNCTION_SPECIALIZATIONS +#endif + +#if (__IBMCPP__ <= 502) +// Actually the compiler supports inclass member initialization but it +// requires a definition for the class member and it doesn't recognize +// it as an integral constant expression when used as a template argument. +# define BOOST_NO_INCLASS_MEMBER_INITIALIZATION +# define BOOST_NO_INTEGRAL_INT64_T +# define BOOST_NO_MEMBER_TEMPLATE_KEYWORD +#endif + +#if (__IBMCPP__ <= 600) || !defined(BOOST_STRICT_CONFIG) +# define BOOST_NO_POINTER_TO_MEMBER_TEMPLATE_PARAMETERS +#endif + +#if (__IBMCPP__ <= 1110) +// XL C++ V11.1 and earlier versions may not always value-initialize +// a temporary object T(), when T is a non-POD aggregate class type. +// Michael Wong (IBM Canada Ltd) has confirmed this issue and gave it +// high priority. -- Niels Dekker (LKEB), May 2010. +# define BOOST_NO_COMPLETE_VALUE_INITIALIZATION +#endif + +// +// On AIX thread support seems to be indicated by _THREAD_SAFE: +// +#ifdef _THREAD_SAFE +# define BOOST_HAS_THREADS +#endif + +#define BOOST_COMPILER "IBM Visual Age version " BOOST_STRINGIZE(__IBMCPP__) + +// +// versions check: +// we don't support Visual age prior to version 5: +#if __IBMCPP__ < 500 +#error "Compiler not supported or configured - please reconfigure" +#endif +// +// last known and checked version is 1210: +#if (__IBMCPP__ > 1210) +# if defined(BOOST_ASSERT_CONFIG) +# error "boost: Unknown compiler version - please run the configure tests and report the results" +# endif +#endif + +// Some versions of the compiler have issues with default arguments on partial specializations +#if __IBMCPP__ <= 1010 +#define BOOST_NO_PARTIAL_SPECIALIZATION_IMPLICIT_DEFAULT_ARGS +#endif + +// Type aliasing hint. Supported since XL C++ 13.1 +#if (__IBMCPP__ >= 1310) +# define BOOST_MAY_ALIAS __attribute__((__may_alias__)) +#endif + +// +// C++0x features +// +// See boost\config\suffix.hpp for BOOST_NO_LONG_LONG +// +#if ! __IBMCPP_AUTO_TYPEDEDUCTION +# define BOOST_NO_CXX11_AUTO_DECLARATIONS +# define BOOST_NO_CXX11_AUTO_MULTIDECLARATIONS +#endif +#if ! __IBMCPP_UTF_LITERAL__ +# define BOOST_NO_CXX11_CHAR16_T +# define BOOST_NO_CXX11_CHAR32_T +#endif +#if ! __IBMCPP_CONSTEXPR +# define BOOST_NO_CXX11_CONSTEXPR +#endif +#if ! __IBMCPP_DECLTYPE +# define BOOST_NO_CXX11_DECLTYPE +#else +# define BOOST_HAS_DECLTYPE +#endif +#define BOOST_NO_CXX11_DECLTYPE_N3276 +#define BOOST_NO_CXX11_DEFAULTED_FUNCTIONS +#define BOOST_NO_CXX11_DELETED_FUNCTIONS +#if ! __IBMCPP_EXPLICIT_CONVERSION_OPERATORS +# define BOOST_NO_CXX11_EXPLICIT_CONVERSION_OPERATORS +#endif +#if ! __IBMCPP_EXTERN_TEMPLATE +# define BOOST_NO_CXX11_EXTERN_TEMPLATE +#endif +#if ! __IBMCPP_VARIADIC_TEMPLATES +// not enabled separately at this time +# define BOOST_NO_CXX11_FUNCTION_TEMPLATE_DEFAULT_ARGS +#endif +#define BOOST_NO_CXX11_HDR_INITIALIZER_LIST +#define BOOST_NO_CXX11_LAMBDAS +#define BOOST_NO_CXX11_LOCAL_CLASS_TEMPLATE_PARAMETERS +#define BOOST_NO_CXX11_NOEXCEPT +#define BOOST_NO_CXX11_NULLPTR +#define BOOST_NO_CXX11_RANGE_BASED_FOR +#define BOOST_NO_CXX11_RAW_LITERALS +#define BOOST_NO_CXX11_USER_DEFINED_LITERALS +#if ! __IBMCPP_RVALUE_REFERENCES +# define BOOST_NO_CXX11_RVALUE_REFERENCES +#endif +#if ! __IBMCPP_SCOPED_ENUM +# define BOOST_NO_CXX11_SCOPED_ENUMS +#endif +#define BOOST_NO_SFINAE_EXPR +#define BOOST_NO_CXX11_SFINAE_EXPR +#define BOOST_NO_CXX11_UNIFIED_INITIALIZATION_SYNTAX +#if ! __IBMCPP_STATIC_ASSERT +# define BOOST_NO_CXX11_STATIC_ASSERT +#endif +#define BOOST_NO_CXX11_TEMPLATE_ALIASES +#define BOOST_NO_CXX11_UNICODE_LITERALS +#if ! __IBMCPP_VARIADIC_TEMPLATES +# define BOOST_NO_CXX11_VARIADIC_TEMPLATES +#endif +#if ! __C99_MACRO_WITH_VA_ARGS +# define BOOST_NO_CXX11_VARIADIC_MACROS +#endif +#define BOOST_NO_CXX11_ALIGNAS +#define BOOST_NO_CXX11_ALIGNOF +#define BOOST_NO_CXX11_TRAILING_RESULT_TYPES +#define BOOST_NO_CXX11_INLINE_NAMESPACES +#define BOOST_NO_CXX11_REF_QUALIFIERS +#define BOOST_NO_CXX11_FINAL +#define BOOST_NO_CXX11_OVERRIDE +#define BOOST_NO_CXX11_THREAD_LOCAL +#define BOOST_NO_CXX11_UNRESTRICTED_UNION + +// C++ 14: +#if !defined(__cpp_aggregate_nsdmi) || (__cpp_aggregate_nsdmi < 201304) +# define BOOST_NO_CXX14_AGGREGATE_NSDMI +#endif +#if !defined(__cpp_binary_literals) || (__cpp_binary_literals < 201304) +# define BOOST_NO_CXX14_BINARY_LITERALS +#endif +#if !defined(__cpp_constexpr) || (__cpp_constexpr < 201304) +# define BOOST_NO_CXX14_CONSTEXPR +#endif +#if !defined(__cpp_decltype_auto) || (__cpp_decltype_auto < 201304) +# define BOOST_NO_CXX14_DECLTYPE_AUTO +#endif +#if (__cplusplus < 201304) // There's no SD6 check for this.... +# define BOOST_NO_CXX14_DIGIT_SEPARATORS +#endif +#if !defined(__cpp_generic_lambdas) || (__cpp_generic_lambdas < 201304) +# define BOOST_NO_CXX14_GENERIC_LAMBDAS +#endif +#if !defined(__cpp_init_captures) || (__cpp_init_captures < 201304) +# define BOOST_NO_CXX14_INITIALIZED_LAMBDA_CAPTURES +#endif +#if !defined(__cpp_return_type_deduction) || (__cpp_return_type_deduction < 201304) +# define BOOST_NO_CXX14_RETURN_TYPE_DEDUCTION +#endif +#if !defined(__cpp_variable_templates) || (__cpp_variable_templates < 201304) +# define BOOST_NO_CXX14_VARIABLE_TEMPLATES +#endif + +// C++17 +#if !defined(__cpp_structured_bindings) || (__cpp_structured_bindings < 201606) +# define BOOST_NO_CXX17_STRUCTURED_BINDINGS +#endif +#if !defined(__cpp_inline_variables) || (__cpp_inline_variables < 201606) +# define BOOST_NO_CXX17_INLINE_VARIABLES +#endif +#if !defined(__cpp_fold_expressions) || (__cpp_fold_expressions < 201603) +# define BOOST_NO_CXX17_FOLD_EXPRESSIONS +#endif +#if !defined(__cpp_if_constexpr) || (__cpp_if_constexpr < 201606) +# define BOOST_NO_CXX17_IF_CONSTEXPR +#endif diff --git a/include/boost/config/compiler/visualc.hpp b/include/boost/config/compiler/visualc.hpp index 7335540db..ae631219a 100644 --- a/include/boost/config/compiler/visualc.hpp +++ b/include/boost/config/compiler/visualc.hpp @@ -107,6 +107,14 @@ # define BOOST_NO_RTTI #endif +// Deprecated symbol markup +#if (_MSC_VER >= 1400) +#define BOOST_DEPRECATED(msg) __declspec(deprecated(msg)) +#else +// MSVC 7.1 only supports the attribute without a message +#define BOOST_DEPRECATED(msg) __declspec(deprecated) +#endif + // // TR1 features: // @@ -175,6 +183,7 @@ # define BOOST_NO_CXX11_REF_QUALIFIERS # define BOOST_NO_CXX11_USER_DEFINED_LITERALS # define BOOST_NO_CXX11_ALIGNAS +# define BOOST_NO_CXX11_ALIGNOF # define BOOST_NO_CXX11_INLINE_NAMESPACES # define BOOST_NO_CXX11_CHAR16_T # define BOOST_NO_CXX11_CHAR32_T @@ -236,7 +245,9 @@ // if this is in effect or not, in any case nothing in Boost is currently using this, so we'll just go // on defining it for now: // +#if (_MSC_FULL_VER < 193030705) || (_MSVC_LANG < 202004) # define BOOST_NO_TWO_PHASE_NAME_LOOKUP +#endif #if (_MSC_VER < 1912) || (_MSVC_LANG < 201402) // Supported from msvc-15.5 onwards: @@ -260,7 +271,7 @@ #ifndef BOOST_NO_CXX11_THREAD_LOCAL # define BOOST_NO_CXX11_THREAD_LOCAL #endif -#ifndef BOOST_NO_SFINAE_EXPR +#if !defined(BOOST_NO_SFINAE_EXPR) && !defined(_MSVC_LANG) # define BOOST_NO_SFINAE_EXPR #endif #ifndef BOOST_NO_CXX11_REF_QUALIFIERS @@ -283,6 +294,17 @@ # define BOOST_ABI_SUFFIX "boost/config/abi/msvc_suffix.hpp" #endif +// +// Approximate compiler conformance version +// +#ifdef _MSVC_LANG +# define BOOST_CXX_VERSION _MSVC_LANG +#elif defined(_HAS_CXX17) +# define BOOST_CXX_VERSION 201703L +#elif BOOST_MSVC >= 1916 +# define BOOST_CXX_VERSION 201402L +#endif + #ifndef BOOST_COMPILER // TODO: // these things are mostly bogus. 1200 means version 12.0 of the compiler. The @@ -343,6 +365,8 @@ # define BOOST_COMPILER_VERSION 14.1 # elif _MSC_VER < 1930 # define BOOST_COMPILER_VERSION 14.2 +# elif _MSC_VER < 1940 +# define BOOST_COMPILER_VERSION 14.3 # else # define BOOST_COMPILER_VERSION _MSC_VER # endif @@ -354,8 +378,8 @@ #include // -// last known and checked version is 19.20.27508 (VC++ 2019 RC3): -#if (_MSC_VER > 1920) +// last known and checked version is 19.3x (VS2022): +#if (_MSC_VER >= 1940) # if defined(BOOST_ASSERT_CONFIG) # error "Boost.Config is older than your current compiler version." # elif !defined(BOOST_CONFIG_SUPPRESS_OUTDATED_MESSAGE) diff --git a/include/boost/config/compiler/xlcpp.hpp b/include/boost/config/compiler/xlcpp.hpp new file mode 100644 index 000000000..99b8b2455 --- /dev/null +++ b/include/boost/config/compiler/xlcpp.hpp @@ -0,0 +1,299 @@ +// (C) Copyright Douglas Gregor 2010 +// +// Use, modification and distribution are subject to 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) + +// See http://www.boost.org for most recent version. + +// compiler setup for IBM XL C/C++ for Linux (Little Endian) based on clang. + +#define BOOST_HAS_PRAGMA_ONCE + +// Detecting `-fms-extension` compiler flag assuming that _MSC_VER defined when that flag is used. +#if defined (_MSC_VER) && (__clang_major__ > 3 || (__clang_major__ == 3 && __clang_minor__ >= 4)) +# define BOOST_HAS_PRAGMA_DETECT_MISMATCH +#endif + +// When compiling with clang before __has_extension was defined, +// even if one writes 'defined(__has_extension) && __has_extension(xxx)', +// clang reports a compiler error. So the only workaround found is: + +#ifndef __has_extension +#define __has_extension __has_feature +#endif + +#ifndef __has_cpp_attribute +#define __has_cpp_attribute(x) 0 +#endif + +#if !__has_feature(cxx_exceptions) && !defined(BOOST_NO_EXCEPTIONS) +# define BOOST_NO_EXCEPTIONS +#endif + +#if !__has_feature(cxx_rtti) && !defined(BOOST_NO_RTTI) +# define BOOST_NO_RTTI +#endif + +#if !__has_feature(cxx_rtti) && !defined(BOOST_NO_TYPEID) +# define BOOST_NO_TYPEID +#endif + +#if defined(__int64) && !defined(__GNUC__) +# define BOOST_HAS_MS_INT64 +#endif + +#define BOOST_HAS_NRVO + +// Branch prediction hints +#if defined(__has_builtin) +#if __has_builtin(__builtin_expect) +#define BOOST_LIKELY(x) __builtin_expect(x, 1) +#define BOOST_UNLIKELY(x) __builtin_expect(x, 0) +#endif +#endif + +// Clang supports "long long" in all compilation modes. +#define BOOST_HAS_LONG_LONG + +// +// Dynamic shared object (DSO) and dynamic-link library (DLL) support +// +#if !defined(_WIN32) && !defined(__WIN32__) && !defined(WIN32) +# define BOOST_SYMBOL_EXPORT __attribute__((__visibility__("default"))) +# define BOOST_SYMBOL_IMPORT +# define BOOST_SYMBOL_VISIBLE __attribute__((__visibility__("default"))) +#endif + +// +// The BOOST_FALLTHROUGH macro can be used to annotate implicit fall-through +// between switch labels. +// +#if __cplusplus >= 201103L && defined(__has_warning) +# if __has_feature(cxx_attributes) && __has_warning("-Wimplicit-fallthrough") +# define BOOST_FALLTHROUGH [[clang::fallthrough]] +# endif +#endif + +#if !__has_feature(cxx_auto_type) +# define BOOST_NO_CXX11_AUTO_DECLARATIONS +# define BOOST_NO_CXX11_AUTO_MULTIDECLARATIONS +#endif + +// +// Currently clang on Windows using VC++ RTL does not support C++11's char16_t or char32_t +// +#if defined(_MSC_VER) || !(defined(__GXX_EXPERIMENTAL_CXX0X__) || __cplusplus >= 201103L) +# define BOOST_NO_CXX11_CHAR16_T +# define BOOST_NO_CXX11_CHAR32_T +#endif + +#if !__has_feature(cxx_constexpr) +# define BOOST_NO_CXX11_CONSTEXPR +#endif + +#if !__has_feature(cxx_decltype) +# define BOOST_NO_CXX11_DECLTYPE +#endif + +#if !__has_feature(cxx_decltype_incomplete_return_types) +# define BOOST_NO_CXX11_DECLTYPE_N3276 +#endif + +#if !__has_feature(cxx_defaulted_functions) +# define BOOST_NO_CXX11_DEFAULTED_FUNCTIONS +#endif + +#if !__has_feature(cxx_deleted_functions) +# define BOOST_NO_CXX11_DELETED_FUNCTIONS +#endif + +#if !__has_feature(cxx_explicit_conversions) +# define BOOST_NO_CXX11_EXPLICIT_CONVERSION_OPERATORS +#endif + +#if !__has_feature(cxx_default_function_template_args) +# define BOOST_NO_CXX11_FUNCTION_TEMPLATE_DEFAULT_ARGS +#endif + +#if !__has_feature(cxx_generalized_initializers) +# define BOOST_NO_CXX11_HDR_INITIALIZER_LIST +#endif + +#if !__has_feature(cxx_lambdas) +# define BOOST_NO_CXX11_LAMBDAS +#endif + +#if !__has_feature(cxx_local_type_template_args) +# define BOOST_NO_CXX11_LOCAL_CLASS_TEMPLATE_PARAMETERS +#endif + +#if !__has_feature(cxx_noexcept) +# define BOOST_NO_CXX11_NOEXCEPT +#endif + +#if !__has_feature(cxx_nullptr) +# define BOOST_NO_CXX11_NULLPTR +#endif + +#if !__has_feature(cxx_range_for) +# define BOOST_NO_CXX11_RANGE_BASED_FOR +#endif + +#if !__has_feature(cxx_raw_string_literals) +# define BOOST_NO_CXX11_RAW_LITERALS +#endif + +#if !__has_feature(cxx_reference_qualified_functions) +# define BOOST_NO_CXX11_REF_QUALIFIERS +#endif + +#if !__has_feature(cxx_generalized_initializers) +# define BOOST_NO_CXX11_UNIFIED_INITIALIZATION_SYNTAX +#endif + +#if !__has_feature(cxx_rvalue_references) +# define BOOST_NO_CXX11_RVALUE_REFERENCES +#endif + +#if !__has_feature(cxx_strong_enums) +# define BOOST_NO_CXX11_SCOPED_ENUMS +#endif + +#if !__has_feature(cxx_static_assert) +# define BOOST_NO_CXX11_STATIC_ASSERT +#endif + +#if !__has_feature(cxx_alias_templates) +# define BOOST_NO_CXX11_TEMPLATE_ALIASES +#endif + +#if !__has_feature(cxx_unicode_literals) +# define BOOST_NO_CXX11_UNICODE_LITERALS +#endif + +#if !__has_feature(cxx_variadic_templates) +# define BOOST_NO_CXX11_VARIADIC_TEMPLATES +#endif + +#if !__has_feature(cxx_user_literals) +# define BOOST_NO_CXX11_USER_DEFINED_LITERALS +#endif + +#if !__has_feature(cxx_alignas) +# define BOOST_NO_CXX11_ALIGNAS +#endif + +#if !__has_feature(cxx_alignof) +# define BOOST_NO_CXX11_ALIGNOF +#endif + +#if !__has_feature(cxx_trailing_return) +# define BOOST_NO_CXX11_TRAILING_RESULT_TYPES +#endif + +#if !__has_feature(cxx_inline_namespaces) +# define BOOST_NO_CXX11_INLINE_NAMESPACES +#endif + +#if !__has_feature(cxx_override_control) +# define BOOST_NO_CXX11_FINAL +# define BOOST_NO_CXX11_OVERRIDE +#endif + +#if !__has_feature(cxx_unrestricted_unions) +# define BOOST_NO_CXX11_UNRESTRICTED_UNION +#endif + +#if !(__has_feature(__cxx_binary_literals__) || __has_extension(__cxx_binary_literals__)) +# define BOOST_NO_CXX14_BINARY_LITERALS +#endif + +#if !__has_feature(__cxx_decltype_auto__) +# define BOOST_NO_CXX14_DECLTYPE_AUTO +#endif + +#if !__has_feature(__cxx_aggregate_nsdmi__) +# define BOOST_NO_CXX14_AGGREGATE_NSDMI +#endif + +#if !__has_feature(__cxx_init_captures__) +# define BOOST_NO_CXX14_INITIALIZED_LAMBDA_CAPTURES +#endif + +#if !__has_feature(__cxx_generic_lambdas__) +# define BOOST_NO_CXX14_GENERIC_LAMBDAS +#endif + +// clang < 3.5 has a defect with dependent type, like following. +// +// template +// constexpr typename enable_if >::type foo(T &) +// { } // error: no return statement in constexpr function +// +// This issue also affects C++11 mode, but C++11 constexpr requires return stmt. +// Therefore we don't care such case. +// +// Note that we can't check Clang version directly as the numbering system changes depending who's +// creating the Clang release (see https://github.com/boostorg/config/pull/39#issuecomment-59927873) +// so instead verify that we have a feature that was introduced at the same time as working C++14 +// constexpr (generic lambda's in this case): +// +#if !__has_feature(__cxx_generic_lambdas__) || !__has_feature(__cxx_relaxed_constexpr__) +# define BOOST_NO_CXX14_CONSTEXPR +#endif + +#if !__has_feature(__cxx_return_type_deduction__) +# define BOOST_NO_CXX14_RETURN_TYPE_DEDUCTION +#endif + +#if !__has_feature(__cxx_variable_templates__) +# define BOOST_NO_CXX14_VARIABLE_TEMPLATES +#endif + +#if !defined(__cpp_structured_bindings) || (__cpp_structured_bindings < 201606) +# define BOOST_NO_CXX17_STRUCTURED_BINDINGS +#endif + +#if !defined(__cpp_if_constexpr) || (__cpp_if_constexpr < 201606) +# define BOOST_NO_CXX17_IF_CONSTEXPR +#endif + +// Clang 3.9+ in c++1z +#if !__has_cpp_attribute(fallthrough) || __cplusplus < 201406L +# define BOOST_NO_CXX17_INLINE_VARIABLES +# define BOOST_NO_CXX17_FOLD_EXPRESSIONS +#endif + +#if !__has_feature(cxx_thread_local) +# define BOOST_NO_CXX11_THREAD_LOCAL +#endif + +#if __cplusplus < 201400 +// All versions with __cplusplus above this value seem to support this: +# define BOOST_NO_CXX14_DIGIT_SEPARATORS +#endif + +// Deprecated symbol markup +#if __has_attribute(deprecated) +#define BOOST_DEPRECATED(msg) __attribute__((deprecated(msg))) +#endif + +// Unused attribute: +#if defined(__GNUC__) && (__GNUC__ >= 4) +# define BOOST_ATTRIBUTE_UNUSED __attribute__((unused)) +#endif + +// Type aliasing hint. +#if __has_attribute(__may_alias__) +# define BOOST_MAY_ALIAS __attribute__((__may_alias__)) +#endif + +#ifndef BOOST_COMPILER +# define BOOST_COMPILER "Clang version " __clang_version__ +#endif + +// Macro used to identify the Clang compiler. +#define BOOST_CLANG 1 + +#define BOOST_CLANG_VERSION (__clang_major__ * 10000 + __clang_minor__ * 100 + __clang_patchlevel__) diff --git a/include/boost/config/compiler/xlcpp_zos.hpp b/include/boost/config/compiler/xlcpp_zos.hpp new file mode 100644 index 000000000..9a177f1bb --- /dev/null +++ b/include/boost/config/compiler/xlcpp_zos.hpp @@ -0,0 +1,173 @@ +// Copyright (c) 2017 Dynatrace +// +// 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 + +// See http://www.boost.org for most recent version. + +// Compiler setup for IBM z/OS XL C/C++ compiler. + +// Oldest compiler version currently supported is 2.1 (V2R1) +#if !defined(__IBMCPP__) || !defined(__COMPILER_VER__) || __COMPILER_VER__ < 0x42010000 +# error "Compiler not supported or configured - please reconfigure" +#endif + +#if __COMPILER_VER__ > 0x42010000 +# if defined(BOOST_ASSERT_CONFIG) +# error "Unknown compiler version - please run the configure tests and report the results" +# endif +#endif + +#define BOOST_COMPILER "IBM z/OS XL C/C++ version " BOOST_STRINGIZE(__COMPILER_VER__) +#define BOOST_XLCPP_ZOS __COMPILER_VER__ + +// ------------------------------------- + +#include // For __UU, __C99, __TR1, ... + +#if !defined(__IBMCPP_DEFAULTED_AND_DELETED_FUNCTIONS) +# define BOOST_NO_CXX11_DELETED_FUNCTIONS +# define BOOST_NO_CXX11_DEFAULTED_FUNCTIONS +# define BOOST_NO_CXX11_NON_PUBLIC_DEFAULTED_FUNCTIONS +#endif + +// ------------------------------------- + +#if defined(__UU) || defined(__C99) || defined(__TR1) +# define BOOST_HAS_LOG1P +# define BOOST_HAS_EXPM1 +#endif + +#if defined(__C99) || defined(__TR1) +# define BOOST_HAS_STDINT_H +#else +# define BOOST_NO_FENV_H +#endif + +// ------------------------------------- + +#define BOOST_HAS_NRVO + +#if !defined(__RTTI_ALL__) +# define BOOST_NO_RTTI +#endif + +#if !defined(_CPPUNWIND) && !defined(__EXCEPTIONS) +# define BOOST_NO_EXCEPTIONS +#endif + +#if defined(_LONG_LONG) || defined(__IBMCPP_C99_LONG_LONG) || defined(__LL) +# define BOOST_HAS_LONG_LONG +#else +# define BOOST_NO_LONG_LONG +#endif + +#if defined(_LONG_LONG) || defined(__IBMCPP_C99_LONG_LONG) || defined(__LL) || defined(_LP64) +# define BOOST_HAS_MS_INT64 +#endif + +#define BOOST_NO_SFINAE_EXPR +#define BOOST_NO_CXX11_SFINAE_EXPR + +#if defined(__IBMCPP_VARIADIC_TEMPLATES) +# define BOOST_HAS_VARIADIC_TMPL +#else +# define BOOST_NO_CXX11_VARIADIC_TEMPLATES +# define BOOST_NO_CXX11_FUNCTION_TEMPLATE_DEFAULT_ARGS +#endif + +#if defined(__IBMCPP_STATIC_ASSERT) +# define BOOST_HAS_STATIC_ASSERT +#else +# define BOOST_NO_CXX11_STATIC_ASSERT +#endif + +#if defined(__IBMCPP_RVALUE_REFERENCES) +# define BOOST_HAS_RVALUE_REFS +#else +# define BOOST_NO_CXX11_RVALUE_REFERENCES +#endif + +#if !defined(__IBMCPP_SCOPED_ENUM) +# define BOOST_NO_CXX11_SCOPED_ENUMS +#endif + +#define BOOST_NO_CXX11_FIXED_LENGTH_VARIADIC_TEMPLATE_EXPANSION_PACKS +#define BOOST_NO_CXX11_TEMPLATE_ALIASES +#define BOOST_NO_CXX11_LOCAL_CLASS_TEMPLATE_PARAMETERS + +#if !defined(__IBMCPP_EXPLICIT_CONVERSION_OPERATORS) +# define BOOST_NO_CXX11_EXPLICIT_CONVERSION_OPERATORS +#endif + +#if !defined(__IBMCPP_DECLTYPE) +# define BOOST_NO_CXX11_DECLTYPE +#else +# define BOOST_HAS_DECLTYPE +#endif +#define BOOST_NO_CXX11_DECLTYPE_N3276 + +#if !defined(__IBMCPP_INLINE_NAMESPACE) +# define BOOST_NO_CXX11_INLINE_NAMESPACES +#endif + +#if !defined(__IBMCPP_AUTO_TYPEDEDUCTION) +# define BOOST_NO_CXX11_AUTO_MULTIDECLARATIONS +# define BOOST_NO_CXX11_AUTO_DECLARATIONS +# define BOOST_NO_CXX11_TRAILING_RESULT_TYPES +#endif + +#if !defined(__IBM_CHAR32_T__) +# define BOOST_NO_CXX11_CHAR32_T +#endif +#if !defined(__IBM_CHAR16_T__) +# define BOOST_NO_CXX11_CHAR16_T +#endif + +#if !defined(__IBMCPP_CONSTEXPR) +# define BOOST_NO_CXX11_CONSTEXPR +#endif + +#define BOOST_NO_CXX11_UNIFIED_INITIALIZATION_SYNTAX +#define BOOST_NO_CXX11_UNICODE_LITERALS +#define BOOST_NO_CXX11_RAW_LITERALS +#define BOOST_NO_CXX11_RANGE_BASED_FOR +#define BOOST_NO_CXX11_NULLPTR +#define BOOST_NO_CXX11_NOEXCEPT +#define BOOST_NO_CXX11_LAMBDAS +#define BOOST_NO_CXX11_USER_DEFINED_LITERALS +#define BOOST_NO_CXX11_THREAD_LOCAL +#define BOOST_NO_CXX11_REF_QUALIFIERS +#define BOOST_NO_CXX11_FINAL +#define BOOST_NO_CXX11_OVERRIDE +#define BOOST_NO_CXX11_ALIGNAS +#define BOOST_NO_CXX11_ALIGNOF +#define BOOST_NO_CXX11_UNRESTRICTED_UNION +#define BOOST_NO_CXX14_VARIABLE_TEMPLATES +#define BOOST_NO_CXX14_RETURN_TYPE_DEDUCTION +#define BOOST_NO_CXX14_AGGREGATE_NSDMI +#define BOOST_NO_CXX14_INITIALIZED_LAMBDA_CAPTURES +#define BOOST_NO_CXX14_GENERIC_LAMBDAS +#define BOOST_NO_CXX14_DIGIT_SEPARATORS +#define BOOST_NO_CXX14_DECLTYPE_AUTO +#define BOOST_NO_CXX14_CONSTEXPR +#define BOOST_NO_CXX14_BINARY_LITERALS +#define BOOST_NO_CXX17_STRUCTURED_BINDINGS +#define BOOST_NO_CXX17_INLINE_VARIABLES +#define BOOST_NO_CXX17_FOLD_EXPRESSIONS +#define BOOST_NO_CXX17_IF_CONSTEXPR + +// ------------------------------------- + +#if defined(__IBM_ATTRIBUTES) +# define BOOST_FORCEINLINE inline __attribute__ ((__always_inline__)) +# define BOOST_NOINLINE __attribute__ ((__noinline__)) +# define BOOST_MAY_ALIAS __attribute__((__may_alias__)) +// No BOOST_ALIGNMENT - explicit alignment support is broken (V2R1). +#endif + +extern "builtin" long __builtin_expect(long, long); + +#define BOOST_LIKELY(x) __builtin_expect((x) && true, 1) +#define BOOST_UNLIKELY(x) __builtin_expect((x) && true, 0) diff --git a/include/boost/config/detail/cxx_composite.hpp b/include/boost/config/detail/cxx_composite.hpp new file mode 100644 index 000000000..a243d41f8 --- /dev/null +++ b/include/boost/config/detail/cxx_composite.hpp @@ -0,0 +1,203 @@ +// This file was automatically generated on Sun Jun 5 16:50:18 2022 +// by libs/config/tools/generate.cpp +// Copyright John Maddock 2002-21. +// Use, modification and distribution are subject to 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) + +// See http://www.boost.org/libs/config for the most recent version.// +// Revision $Id$ +// + +#if defined(BOOST_NO_ADL_BARRIER)\ + || defined(BOOST_NO_ARGUMENT_DEPENDENT_LOOKUP)\ + || defined(BOOST_NO_ARRAY_TYPE_SPECIALIZATIONS)\ + || defined(BOOST_NO_COMPLETE_VALUE_INITIALIZATION)\ + || defined(BOOST_NO_CTYPE_FUNCTIONS)\ + || defined(BOOST_NO_CV_SPECIALIZATIONS)\ + || defined(BOOST_NO_CV_VOID_SPECIALIZATIONS)\ + || defined(BOOST_NO_CWCHAR)\ + || defined(BOOST_NO_CWCTYPE)\ + || defined(BOOST_NO_DEPENDENT_NESTED_DERIVATIONS)\ + || defined(BOOST_NO_DEPENDENT_TYPES_IN_TEMPLATE_VALUE_PARAMETERS)\ + || defined(BOOST_NO_EXCEPTIONS)\ + || defined(BOOST_NO_EXCEPTION_STD_NAMESPACE)\ + || defined(BOOST_NO_EXPLICIT_FUNCTION_TEMPLATE_ARGUMENTS)\ + || defined(BOOST_NO_FENV_H)\ + || defined(BOOST_NO_FUNCTION_TEMPLATE_ORDERING)\ + || defined(BOOST_NO_FUNCTION_TYPE_SPECIALIZATIONS)\ + || defined(BOOST_NO_INCLASS_MEMBER_INITIALIZATION)\ + || defined(BOOST_NO_INTEGRAL_INT64_T)\ + || defined(BOOST_NO_INTRINSIC_WCHAR_T)\ + || defined(BOOST_NO_IOSFWD)\ + || defined(BOOST_NO_IOSTREAM)\ + || defined(BOOST_NO_IS_ABSTRACT)\ + || defined(BOOST_NO_LIMITS)\ + || defined(BOOST_NO_LIMITS_COMPILE_TIME_CONSTANTS)\ + || defined(BOOST_NO_LONG_LONG)\ + || defined(BOOST_NO_LONG_LONG_NUMERIC_LIMITS)\ + || defined(BOOST_NO_MEMBER_FUNCTION_SPECIALIZATIONS)\ + || defined(BOOST_NO_MEMBER_TEMPLATES)\ + || defined(BOOST_NO_MEMBER_TEMPLATE_FRIENDS)\ + || defined(BOOST_NO_MEMBER_TEMPLATE_KEYWORD)\ + || defined(BOOST_NO_NESTED_FRIENDSHIP)\ + || defined(BOOST_NO_OPERATORS_IN_NAMESPACE)\ + || defined(BOOST_NO_PARTIAL_SPECIALIZATION_IMPLICIT_DEFAULT_ARGS)\ + || defined(BOOST_NO_POINTER_TO_MEMBER_CONST)\ + || defined(BOOST_NO_POINTER_TO_MEMBER_TEMPLATE_PARAMETERS)\ + || defined(BOOST_NO_PRIVATE_IN_AGGREGATE)\ + || defined(BOOST_NO_RESTRICT_REFERENCES)\ + || defined(BOOST_NO_RTTI)\ + || defined(BOOST_NO_SFINAE)\ + || defined(BOOST_NO_SFINAE_EXPR)\ + || defined(BOOST_NO_STDC_NAMESPACE)\ + || defined(BOOST_NO_STD_ALLOCATOR)\ + || defined(BOOST_NO_STD_DISTANCE)\ + || defined(BOOST_NO_STD_ITERATOR)\ + || defined(BOOST_NO_STD_ITERATOR_TRAITS)\ + || defined(BOOST_NO_STD_LOCALE)\ + || defined(BOOST_NO_STD_MESSAGES)\ + || defined(BOOST_NO_STD_MIN_MAX)\ + || defined(BOOST_NO_STD_OUTPUT_ITERATOR_ASSIGN)\ + || defined(BOOST_NO_STD_TYPEINFO)\ + || defined(BOOST_NO_STD_USE_FACET)\ + || defined(BOOST_NO_STD_WSTREAMBUF)\ + || defined(BOOST_NO_STD_WSTRING)\ + || defined(BOOST_NO_STRINGSTREAM)\ + || defined(BOOST_NO_TEMPLATED_IOSTREAMS)\ + || defined(BOOST_NO_TEMPLATED_ITERATOR_CONSTRUCTORS)\ + || defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION)\ + || defined(BOOST_NO_TEMPLATE_TEMPLATES)\ + || defined(BOOST_NO_TWO_PHASE_NAME_LOOKUP)\ + || defined(BOOST_NO_TYPEID)\ + || defined(BOOST_NO_TYPENAME_WITH_CTOR)\ + || defined(BOOST_NO_UNREACHABLE_RETURN_DETECTION)\ + || defined(BOOST_NO_USING_DECLARATION_OVERLOADS_FROM_TYPENAME_BASE)\ + || defined(BOOST_NO_USING_TEMPLATE)\ + || defined(BOOST_NO_VOID_RETURNS) +# define BOOST_NO_CXX03 +#endif + +#if defined(BOOST_NO_CXX03)\ + || defined(BOOST_NO_CXX11_ADDRESSOF)\ + || defined(BOOST_NO_CXX11_ALIGNAS)\ + || defined(BOOST_NO_CXX11_ALLOCATOR)\ + || defined(BOOST_NO_CXX11_AUTO_DECLARATIONS)\ + || defined(BOOST_NO_CXX11_AUTO_MULTIDECLARATIONS)\ + || defined(BOOST_NO_CXX11_CHAR16_T)\ + || defined(BOOST_NO_CXX11_CHAR32_T)\ + || defined(BOOST_NO_CXX11_CONSTEXPR)\ + || defined(BOOST_NO_CXX11_DECLTYPE)\ + || defined(BOOST_NO_CXX11_DECLTYPE_N3276)\ + || defined(BOOST_NO_CXX11_DEFAULTED_FUNCTIONS)\ + || defined(BOOST_NO_CXX11_DEFAULTED_MOVES)\ + || defined(BOOST_NO_CXX11_DELETED_FUNCTIONS)\ + || defined(BOOST_NO_CXX11_EXPLICIT_CONVERSION_OPERATORS)\ + || defined(BOOST_NO_CXX11_EXTERN_TEMPLATE)\ + || defined(BOOST_NO_CXX11_FINAL)\ + || defined(BOOST_NO_CXX11_FIXED_LENGTH_VARIADIC_TEMPLATE_EXPANSION_PACKS)\ + || defined(BOOST_NO_CXX11_FUNCTION_TEMPLATE_DEFAULT_ARGS)\ + || defined(BOOST_NO_CXX11_HDR_ARRAY)\ + || defined(BOOST_NO_CXX11_HDR_ATOMIC)\ + || defined(BOOST_NO_CXX11_HDR_CHRONO)\ + || defined(BOOST_NO_CXX11_HDR_CONDITION_VARIABLE)\ + || defined(BOOST_NO_CXX11_HDR_EXCEPTION)\ + || defined(BOOST_NO_CXX11_HDR_FORWARD_LIST)\ + || defined(BOOST_NO_CXX11_HDR_FUNCTIONAL)\ + || defined(BOOST_NO_CXX11_HDR_FUTURE)\ + || defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST)\ + || defined(BOOST_NO_CXX11_HDR_MUTEX)\ + || defined(BOOST_NO_CXX11_HDR_RANDOM)\ + || defined(BOOST_NO_CXX11_HDR_RATIO)\ + || defined(BOOST_NO_CXX11_HDR_REGEX)\ + || defined(BOOST_NO_CXX11_HDR_SYSTEM_ERROR)\ + || defined(BOOST_NO_CXX11_HDR_THREAD)\ + || defined(BOOST_NO_CXX11_HDR_TUPLE)\ + || defined(BOOST_NO_CXX11_HDR_TYPEINDEX)\ + || defined(BOOST_NO_CXX11_HDR_TYPE_TRAITS)\ + || defined(BOOST_NO_CXX11_HDR_UNORDERED_MAP)\ + || defined(BOOST_NO_CXX11_HDR_UNORDERED_SET)\ + || defined(BOOST_NO_CXX11_INLINE_NAMESPACES)\ + || defined(BOOST_NO_CXX11_LAMBDAS)\ + || defined(BOOST_NO_CXX11_LOCAL_CLASS_TEMPLATE_PARAMETERS)\ + || defined(BOOST_NO_CXX11_NOEXCEPT)\ + || defined(BOOST_NO_CXX11_NON_PUBLIC_DEFAULTED_FUNCTIONS)\ + || defined(BOOST_NO_CXX11_NULLPTR)\ + || defined(BOOST_NO_CXX11_NUMERIC_LIMITS)\ + || defined(BOOST_NO_CXX11_OVERRIDE)\ + || defined(BOOST_NO_CXX11_POINTER_TRAITS)\ + || defined(BOOST_NO_CXX11_RANGE_BASED_FOR)\ + || defined(BOOST_NO_CXX11_RAW_LITERALS)\ + || defined(BOOST_NO_CXX11_REF_QUALIFIERS)\ + || defined(BOOST_NO_CXX11_RVALUE_REFERENCES)\ + || defined(BOOST_NO_CXX11_SCOPED_ENUMS)\ + || defined(BOOST_NO_CXX11_SFINAE_EXPR)\ + || defined(BOOST_NO_CXX11_SMART_PTR)\ + || defined(BOOST_NO_CXX11_STATIC_ASSERT)\ + || defined(BOOST_NO_CXX11_STD_ALIGN)\ + || defined(BOOST_NO_CXX11_TEMPLATE_ALIASES)\ + || defined(BOOST_NO_CXX11_THREAD_LOCAL)\ + || defined(BOOST_NO_CXX11_TRAILING_RESULT_TYPES)\ + || defined(BOOST_NO_CXX11_UNICODE_LITERALS)\ + || defined(BOOST_NO_CXX11_UNIFIED_INITIALIZATION_SYNTAX)\ + || defined(BOOST_NO_CXX11_UNRESTRICTED_UNION)\ + || defined(BOOST_NO_CXX11_USER_DEFINED_LITERALS)\ + || defined(BOOST_NO_CXX11_VARIADIC_MACROS)\ + || defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) +# define BOOST_NO_CXX11 +#endif + +#if defined(BOOST_NO_CXX11)\ + || defined(BOOST_NO_CXX14_AGGREGATE_NSDMI)\ + || defined(BOOST_NO_CXX14_BINARY_LITERALS)\ + || defined(BOOST_NO_CXX14_CONSTEXPR)\ + || defined(BOOST_NO_CXX14_DECLTYPE_AUTO)\ + || defined(BOOST_NO_CXX14_DIGIT_SEPARATORS)\ + || defined(BOOST_NO_CXX14_GENERIC_LAMBDAS)\ + || defined(BOOST_NO_CXX14_HDR_SHARED_MUTEX)\ + || defined(BOOST_NO_CXX14_INITIALIZED_LAMBDA_CAPTURES)\ + || defined(BOOST_NO_CXX14_RETURN_TYPE_DEDUCTION)\ + || defined(BOOST_NO_CXX14_STD_EXCHANGE)\ + || defined(BOOST_NO_CXX14_VARIABLE_TEMPLATES) +# define BOOST_NO_CXX14 +#endif + +#if defined(BOOST_NO_CXX14)\ + || defined(BOOST_NO_CXX17_DEDUCTION_GUIDES)\ + || defined(BOOST_NO_CXX17_FOLD_EXPRESSIONS)\ + || defined(BOOST_NO_CXX17_HDR_ANY)\ + || defined(BOOST_NO_CXX17_HDR_CHARCONV)\ + || defined(BOOST_NO_CXX17_HDR_EXECUTION)\ + || defined(BOOST_NO_CXX17_HDR_FILESYSTEM)\ + || defined(BOOST_NO_CXX17_HDR_MEMORY_RESOURCE)\ + || defined(BOOST_NO_CXX17_HDR_OPTIONAL)\ + || defined(BOOST_NO_CXX17_HDR_STRING_VIEW)\ + || defined(BOOST_NO_CXX17_HDR_VARIANT)\ + || defined(BOOST_NO_CXX17_IF_CONSTEXPR)\ + || defined(BOOST_NO_CXX17_INLINE_VARIABLES)\ + || defined(BOOST_NO_CXX17_ITERATOR_TRAITS)\ + || defined(BOOST_NO_CXX17_STD_APPLY)\ + || defined(BOOST_NO_CXX17_STD_INVOKE)\ + || defined(BOOST_NO_CXX17_STRUCTURED_BINDINGS) +# define BOOST_NO_CXX17 +#endif + +#if defined(BOOST_NO_CXX17)\ + || defined(BOOST_NO_CXX20_HDR_BARRIER)\ + || defined(BOOST_NO_CXX20_HDR_BIT)\ + || defined(BOOST_NO_CXX20_HDR_COMPARE)\ + || defined(BOOST_NO_CXX20_HDR_CONCEPTS)\ + || defined(BOOST_NO_CXX20_HDR_COROUTINE)\ + || defined(BOOST_NO_CXX20_HDR_FORMAT)\ + || defined(BOOST_NO_CXX20_HDR_LATCH)\ + || defined(BOOST_NO_CXX20_HDR_NUMBERS)\ + || defined(BOOST_NO_CXX20_HDR_RANGES)\ + || defined(BOOST_NO_CXX20_HDR_SEMAPHORE)\ + || defined(BOOST_NO_CXX20_HDR_SOURCE_LOCATION)\ + || defined(BOOST_NO_CXX20_HDR_SPAN)\ + || defined(BOOST_NO_CXX20_HDR_STOP_TOKEN)\ + || defined(BOOST_NO_CXX20_HDR_SYNCSTREAM)\ + || defined(BOOST_NO_CXX20_HDR_VERSION) +# define BOOST_NO_CXX20 +#endif + diff --git a/include/boost/config/detail/select_platform_config.hpp b/include/boost/config/detail/select_platform_config.hpp index b36eca57a..dbff74aaf 100644 --- a/include/boost/config/detail/select_platform_config.hpp +++ b/include/boost/config/detail/select_platform_config.hpp @@ -88,6 +88,11 @@ #elif defined(__CloudABI__) // Nuxi CloudABI: # define BOOST_PLATFORM_CONFIG "boost/config/platform/cloudabi.hpp" + +#elif defined (__wasm__) +// Web assembly: +# define BOOST_PLATFORM_CONFIG "boost/config/platform/wasm.hpp" + #else # if defined(unix) \ diff --git a/include/boost/config/detail/suffix.hpp b/include/boost/config/detail/suffix.hpp index 994dce928..b28d46f18 100644 --- a/include/boost/config/detail/suffix.hpp +++ b/include/boost/config/detail/suffix.hpp @@ -47,6 +47,22 @@ # define BOOST_SYMBOL_VISIBLE #endif +// +// disable explicitly enforced visibility +// +#if defined(BOOST_DISABLE_EXPLICIT_SYMBOL_VISIBILITY) + +#undef BOOST_SYMBOL_EXPORT +#define BOOST_SYMBOL_EXPORT + +#undef BOOST_SYMBOL_IMPORT +#define BOOST_SYMBOL_IMPORT + +#undef BOOST_SYMBOL_VISIBLE +#define BOOST_SYMBOL_VISIBLE + +#endif + // // look for long long by looking for the appropriate macros in . // Note that we use limits.h rather than climits for maximal portability, @@ -475,6 +491,16 @@ namespace std { # define BOOST_CTOR_TYPENAME #endif +// +// If we're on a CUDA device (note DEVICE not HOST, irrespective of compiler) then disable __int128 and __float128 support if present: +// +#if defined(__CUDA_ARCH__) && defined(BOOST_HAS_FLOAT128) +# undef BOOST_HAS_FLOAT128 +#endif +#if defined(__CUDA_ARCH__) && defined(BOOST_HAS_INT128) +# undef BOOST_HAS_INT128 +#endif + // long long workaround ------------------------------------------// // On gcc (and maybe other compilers?) long long is alway supported // but it's use may generate either warnings (with -ansi), or errors @@ -622,6 +648,9 @@ namespace std{ using ::type_info; } // nvcc doesn't always parse __noinline__, // see: https://svn.boost.org/trac/boost/ticket/9392 # define BOOST_NOINLINE __attribute__ ((noinline)) +# elif defined(__HIP__) + // See https://github.com/boostorg/config/issues/392 +# define BOOST_NOINLINE __attribute__ ((noinline)) # else # define BOOST_NOINLINE __attribute__ ((__noinline__)) # endif @@ -655,6 +684,23 @@ namespace std{ using ::type_info; } # define BOOST_NORETURN #endif +// BOOST_DEPRECATED -------------------------------------------// +// The macro can be used to mark deprecated symbols, such as functions, objects and types. +// Any code that uses these symbols will produce warnings, possibly with a message specified +// as an argument. The warnings can be suppressed by defining BOOST_ALLOW_DEPRECATED_SYMBOLS +// or BOOST_ALLOW_DEPRECATED. +#if !defined(BOOST_DEPRECATED) && __cplusplus >= 201402 +#define BOOST_DEPRECATED(msg) [[deprecated(msg)]] +#endif + +#if defined(BOOST_ALLOW_DEPRECATED_SYMBOLS) || defined(BOOST_ALLOW_DEPRECATED) +#undef BOOST_DEPRECATED +#endif + +#if !defined(BOOST_DEPRECATED) +#define BOOST_DEPRECATED(msg) +#endif + // Branch prediction hints // These macros are intended to wrap conditional expressions that yield true or false // @@ -1002,6 +1048,9 @@ namespace std{ using ::type_info; } #else #define BOOST_CXX14_CONSTEXPR constexpr #endif +#if !defined(BOOST_NO_CXX17_STRUCTURED_BINDINGS) && defined(BOOST_NO_CXX11_HDR_TUPLE) +# define BOOST_NO_CXX17_STRUCTURED_BINDINGS +#endif // // C++17 inline variables @@ -1025,9 +1074,22 @@ namespace std{ using ::type_info; } // // Unused variable/typedef workarounds: // +#ifndef BOOST_ATTRIBUTE_UNUSED +# if defined(__has_attribute) && defined(__SUNPRO_CC) && (__SUNPRO_CC > 0x5130) +# if __has_attribute(maybe_unused) +# define BOOST_ATTRIBUTE_UNUSED [[maybe_unused]] +# endif +# elif defined(__has_cpp_attribute) +# if __has_cpp_attribute(maybe_unused) +# define BOOST_ATTRIBUTE_UNUSED [[maybe_unused]] +# endif +# endif +#endif + #ifndef BOOST_ATTRIBUTE_UNUSED # define BOOST_ATTRIBUTE_UNUSED #endif + // // [[nodiscard]]: // @@ -1040,7 +1102,7 @@ namespace std{ using ::type_info; } #endif #elif defined(__has_cpp_attribute) // clang-6 accepts [[nodiscard]] with -std=c++14, but warns about it -pedantic -#if __has_cpp_attribute(nodiscard) && !(defined(__clang__) && (__cplusplus < 201703L)) +#if __has_cpp_attribute(nodiscard) && !(defined(__clang__) && (__cplusplus < 201703L)) && !(defined(__GNUC__) && (__cplusplus < 201100)) # define BOOST_ATTRIBUTE_NODISCARD [[nodiscard]] #endif #if __has_cpp_attribute(no_unique_address) && !(defined(__GNUC__) && (__cplusplus < 201100)) @@ -1056,6 +1118,12 @@ namespace std{ using ::type_info; } #define BOOST_STATIC_CONSTEXPR static BOOST_CONSTEXPR_OR_CONST +#if !defined(BOOST_NO_CXX11_NULLPTR) +# define BOOST_NULLPTR nullptr +#else +# define BOOST_NULLPTR 0 +#endif + // // Set BOOST_HAS_STATIC_ASSERT when BOOST_NO_CXX11_STATIC_ASSERT is not defined // @@ -1090,6 +1158,11 @@ namespace std{ using ::type_info; } # define BOOST_NO_CXX17_HDR_OPTIONAL # define BOOST_NO_CXX17_HDR_STRING_VIEW # define BOOST_NO_CXX17_HDR_VARIANT +# define BOOST_NO_CXX17_HDR_ANY +# define BOOST_NO_CXX17_HDR_MEMORY_RESOURCE +# define BOOST_NO_CXX17_HDR_CHARCONV +# define BOOST_NO_CXX17_HDR_EXECUTION +# define BOOST_NO_CXX17_HDR_FILESYSTEM #else #if !__has_include() # define BOOST_NO_CXX17_HDR_OPTIONAL @@ -1100,8 +1173,113 @@ namespace std{ using ::type_info; } #if !__has_include() # define BOOST_NO_CXX17_HDR_VARIANT #endif +#if !__has_include() +# define BOOST_NO_CXX17_HDR_ANY +#endif +#if !__has_include() +# define BOOST_NO_CXX17_HDR_MEMORY_RESOURCE +#endif +#if !__has_include() +# define BOOST_NO_CXX17_HDR_CHARCONV +#endif +#if !__has_include() +# define BOOST_NO_CXX17_HDR_EXECUTION #endif +#if !__has_include() +# define BOOST_NO_CXX17_HDR_FILESYSTEM #endif +#endif +#endif +// +// Define the std level that the compiler claims to support: +// +#ifndef BOOST_CXX_VERSION +# define BOOST_CXX_VERSION __cplusplus +#endif + +#if (!defined(__has_include) || (BOOST_CXX_VERSION < 201704)) +# define BOOST_NO_CXX20_HDR_BARRIER +# define BOOST_NO_CXX20_HDR_FORMAT +# define BOOST_NO_CXX20_HDR_SOURCE_LOCATION +# define BOOST_NO_CXX20_HDR_BIT +# define BOOST_NO_CXX20_HDR_LATCH +# define BOOST_NO_CXX20_HDR_SPAN +# define BOOST_NO_CXX20_HDR_COMPARE +# define BOOST_NO_CXX20_HDR_NUMBERS +# define BOOST_NO_CXX20_HDR_STOP_TOKEN +# define BOOST_NO_CXX20_HDR_CONCEPTS +# define BOOST_NO_CXX20_HDR_RANGES +# define BOOST_NO_CXX20_HDR_SYNCSTREAM +# define BOOST_NO_CXX20_HDR_COROUTINE +# define BOOST_NO_CXX20_HDR_SEMAPHORE +#else +#if (!__has_include() || !defined(__cpp_lib_barrier) || (__cpp_lib_barrier < 201907L)) && !defined(BOOST_NO_CXX20_HDR_BARRIER) +# define BOOST_NO_CXX20_HDR_BARRIER +#endif +#if (!__has_include() || !defined(__cpp_lib_format) || (__cpp_lib_format < 201907L)) && !defined(BOOST_NO_CXX20_HDR_FORMAT) +# define BOOST_NO_CXX20_HDR_FORMAT +#endif +#if (!__has_include() || !defined(__cpp_lib_source_location) || (__cpp_lib_source_location < 201907L)) && !defined(BOOST_NO_CXX20_HDR_SOURCE_LOCATION) +# define BOOST_NO_CXX20_HDR_SOURCE_LOCATION +#endif +#if (!__has_include() || !defined(__cpp_lib_bit_cast) || (__cpp_lib_bit_cast < 201806L) || !defined(__cpp_lib_bitops) || (__cpp_lib_bitops < 201907L) || !defined(__cpp_lib_endian) || (__cpp_lib_endian < 201907L)) && !defined(BOOST_NO_CXX20_HDR_BIT) +# define BOOST_NO_CXX20_HDR_BIT +#endif +#if (!__has_include() || !defined(__cpp_lib_latch) || (__cpp_lib_latch < 201907L)) && !defined(BOOST_NO_CXX20_HDR_LATCH) +# define BOOST_NO_CXX20_HDR_LATCH +#endif +#if (!__has_include() || !defined(__cpp_lib_span) || (__cpp_lib_span < 202002L)) && !defined(BOOST_NO_CXX20_HDR_SPAN) +# define BOOST_NO_CXX20_HDR_SPAN +#endif +#if (!__has_include() || !defined(__cpp_lib_three_way_comparison) || (__cpp_lib_three_way_comparison < 201907L)) && !defined(BOOST_NO_CXX20_HDR_COMPARE) +# define BOOST_NO_CXX20_HDR_COMPARE +#endif +#if (!__has_include() || !defined(__cpp_lib_math_constants) || (__cpp_lib_math_constants < 201907L)) && !defined(BOOST_NO_CXX20_HDR_NUMBERS) +# define BOOST_NO_CXX20_HDR_NUMBERS +#endif +#if (!__has_include() || !defined(__cpp_lib_jthread) || (__cpp_lib_jthread < 201911L)) && !defined(BOOST_NO_CXX20_HDR_STOP_TOKEN) +# define BOOST_NO_CXX20_HDR_STOP_TOKEN +#endif +#if (!__has_include() || !defined(__cpp_lib_concepts) || (__cpp_lib_concepts < 202002L)) && !defined(_YVALS) && !defined(_CPPLIB_VER) && !defined(BOOST_NO_CXX20_HDR_CONCEPTS) +# define BOOST_NO_CXX20_HDR_CONCEPTS +#endif +#if (!__has_include() || !defined(__cpp_lib_ranges) || (__cpp_lib_ranges < 201911L)) && !defined(BOOST_NO_CXX20_HDR_RANGES) +# define BOOST_NO_CXX20_HDR_RANGES +#endif +#if (!__has_include() || !defined(__cpp_lib_syncbuf) || (__cpp_lib_syncbuf < 201803L)) && !defined(BOOST_NO_CXX20_HDR_SYNCSTREAM) +# define BOOST_NO_CXX20_HDR_SYNCSTREAM +#endif +#if (!__has_include() || !defined(__cpp_lib_coroutine) || (__cpp_lib_coroutine < 201902L)) && !defined(BOOST_NO_CXX20_HDR_COROUTINE) +# define BOOST_NO_CXX20_HDR_COROUTINE +#endif +#if (!__has_include() || !defined(__cpp_lib_semaphore) || (__cpp_lib_semaphore < 201907L)) && !defined(BOOST_NO_CXX20_HDR_SEMAPHORE) +# define BOOST_NO_CXX20_HDR_SEMAPHORE +#endif +#endif + +#if defined(__cplusplus) && defined(__has_include) +#if !__has_include() +# define BOOST_NO_CXX20_HDR_VERSION +#else +// For convenience, this is always included: +# include +#endif +#else +# define BOOST_NO_CXX20_HDR_VERSION +#endif + +#if defined(BOOST_MSVC) +#if (BOOST_MSVC < 1914) || (_MSVC_LANG < 201703) +# define BOOST_NO_CXX17_DEDUCTION_GUIDES +#endif +#elif !defined(__cpp_deduction_guides) || (__cpp_deduction_guides < 201606) +# define BOOST_NO_CXX17_DEDUCTION_GUIDES +#endif + +// +// Define composite agregate macros: +// +#include // // Finish off with checks for macros that are depricated / no longer supported, diff --git a/include/boost/config/header_deprecated.hpp b/include/boost/config/header_deprecated.hpp index 864554f2a..120b4b3a9 100644 --- a/include/boost/config/header_deprecated.hpp +++ b/include/boost/config/header_deprecated.hpp @@ -17,7 +17,7 @@ #include -#if defined(BOOST_ALLOW_DEPRECATED_HEADERS) +#if defined(BOOST_ALLOW_DEPRECATED_HEADERS) || defined(BOOST_ALLOW_DEPRECATED) # define BOOST_HEADER_DEPRECATED(a) #else # define BOOST_HEADER_DEPRECATED(a) BOOST_PRAGMA_MESSAGE("This header is deprecated. Use " a " instead.") diff --git a/include/boost/config/platform/bsd.hpp b/include/boost/config/platform/bsd.hpp index 79e74a080..ccc7eb05a 100644 --- a/include/boost/config/platform/bsd.hpp +++ b/include/boost/config/platform/bsd.hpp @@ -28,7 +28,8 @@ // FreeBSD has but does not // advertise the fact in : // -#if (defined(__FreeBSD__) && (__FreeBSD__ >= 3)) || defined(__DragonFly__) +#if (defined(__FreeBSD__) && (__FreeBSD__ >= 3)) \ + || defined(__OpenBSD__) || defined(__DragonFly__) # define BOOST_HAS_NL_TYPES_H #endif @@ -56,7 +57,8 @@ #endif #if !((defined(__FreeBSD__) && (__FreeBSD__ >= 5)) \ - || (defined(__NetBSD_GCC__) && (__NetBSD_GCC__ >= 2095003)) || defined(__DragonFly__)) + || (defined(__NetBSD_GCC__) && (__NetBSD_GCC__ >= 2095003)) \ + || defined(__OpenBSD__) || defined(__DragonFly__)) # define BOOST_NO_CWCHAR #endif // @@ -74,13 +76,8 @@ #define BOOST_HAS_GETTIMEOFDAY #define BOOST_HAS_PTHREAD_MUTEXATTR_SETTYPE #define BOOST_HAS_SIGACTION +#define BOOST_HAS_CLOCK_GETTIME // boilerplate code: #define BOOST_HAS_UNISTD_H #include - - - - - - diff --git a/include/boost/config/stdlib/dinkumware.hpp b/include/boost/config/stdlib/dinkumware.hpp index 3dc6d5086..46ffe093e 100644 --- a/include/boost/config/stdlib/dinkumware.hpp +++ b/include/boost/config/stdlib/dinkumware.hpp @@ -176,17 +176,29 @@ #endif // C++17 features -#if !defined(_CPPLIB_VER) || (_CPPLIB_VER < 650) || !defined(BOOST_MSVC) || (BOOST_MSVC < 1910) || !defined(_HAS_CXX17) || (_HAS_CXX17 == 0) +#if !defined(_CPPLIB_VER) || (_CPPLIB_VER < 650) \ + || ((!defined(BOOST_MSVC) || (BOOST_MSVC < 1910))) && (!defined(__clang__) || !defined(_MSC_VER) || (_MSC_VER < 1929))\ + || !defined(_HAS_CXX17) || (_HAS_CXX17 == 0) # define BOOST_NO_CXX17_STD_APPLY # define BOOST_NO_CXX17_ITERATOR_TRAITS # define BOOST_NO_CXX17_HDR_STRING_VIEW # define BOOST_NO_CXX17_HDR_OPTIONAL # define BOOST_NO_CXX17_HDR_VARIANT +# define BOOST_NO_CXX17_HDR_ANY +# define BOOST_NO_CXX17_HDR_MEMORY_RESOURCE +# define BOOST_NO_CXX17_HDR_CHARCONV +# define BOOST_NO_CXX17_HDR_EXECUTION +# define BOOST_NO_CXX17_HDR_FILESYSTEM #endif #if !defined(_CPPLIB_VER) || (_CPPLIB_VER < 650) || !defined(_HAS_CXX17) || (_HAS_CXX17 == 0) || !defined(_MSVC_STL_UPDATE) || (_MSVC_STL_UPDATE < 201709) # define BOOST_NO_CXX17_STD_INVOKE #endif +// C++20 features which aren't configured in suffix.hpp correctly: +#if !defined(_MSVC_STL_UPDATE) || (_MSVC_STL_UPDATE < 202008L) || !defined(_HAS_CXX20) || (_HAS_CXX20 == 0) +# define BOOST_NO_CXX20_HDR_CONCEPTS +#endif + #if !(!defined(_CPPLIB_VER) || (_CPPLIB_VER < 650) || !defined(BOOST_MSVC) || (BOOST_MSVC < 1912) || !defined(_HAS_CXX17) || (_HAS_CXX17 == 0)) // Deprecated std::iterator: # define BOOST_NO_STD_ITERATOR @@ -207,7 +219,15 @@ // Bug specific to VC14, // See https://connect.microsoft.com/VisualStudio/feedback/details/1348277/link-error-when-using-std-codecvt-utf8-utf16-char16-t // and discussion here: http://blogs.msdn.com/b/vcblog/archive/2014/11/12/visual-studio-2015-preview-now-available.aspx?PageIndex=2 -#if defined(_CPPLIB_VER) && (_CPPLIB_VER == 650) +#if defined(_CPPLIB_VER) && (_CPPLIB_VER == 650) && (!defined(_MSVC_STL_VERSION) || (_MSVC_STL_VERSION < 142)) +# define BOOST_NO_CXX11_HDR_CODECVT +#endif + +#if (_MSVC_LANG > 201700) && !defined(BOOST_NO_CXX11_HDR_CODECVT) +// +// is deprected as of C++17, and by default MSVC emits hard errors +// if you try to use it, so mark it as unavailable: +// # define BOOST_NO_CXX11_HDR_CODECVT #endif @@ -220,8 +240,16 @@ # define BOOST_NO_CXX98_RANDOM_SHUFFLE # define BOOST_NO_CXX98_FUNCTION_BASE # define BOOST_NO_CXX98_BINDERS +# elif defined(_HAS_DEPRECATED_ADAPTOR_TYPEDEFS) && (_HAS_DEPRECATED_ADAPTOR_TYPEDEFS == 0) +# define BOOST_NO_CXX98_BINDERS # endif #endif +// +// Things deprecated in C++20: +// +#if defined(_HAS_CXX20) +# define BOOST_NO_CXX11_ATOMIC_SMART_PTR +#endif // @@ -259,6 +287,36 @@ # define BOOST_DINKUMWARE_STDLIB 1 #endif +// BOOST_MSSTL_VERSION: as _MSVC_STL_VERSION, but for earlier releases as well + +#if defined(_MSVC_STL_VERSION) // VS2017 (14.1) and above +# define BOOST_MSSTL_VERSION _MSVC_STL_VERSION + +#elif defined(_CPPLIB_VER) && _CPPLIB_VER >= 650 // VS2015 (14.0) +# define BOOST_MSSTL_VERSION 140 + +#elif defined(_CPPLIB_VER) && _CPPLIB_VER >= 610 // VS2013 (12.0) +# define BOOST_MSSTL_VERSION 120 + +#elif defined(_CPPLIB_VER) && _CPPLIB_VER >= 540 // VS2012 (11.0) +# define BOOST_MSSTL_VERSION 110 + +#elif defined(_CPPLIB_VER) && _CPPLIB_VER >= 520 // VS2010 (10.0) +# define BOOST_MSSTL_VERSION 100 + +#elif defined(_CPPLIB_VER) && _CPPLIB_VER >= 505 // VS2008SP1 (9.0) +# define BOOST_MSSTL_VERSION 91 + +#elif defined(_CPPLIB_VER) && _CPPLIB_VER >= 503 // VS2008 (also 9.0) +# define BOOST_MSSTL_VERSION 90 + +#elif defined(_CPPLIB_VER) && _CPPLIB_VER >= 405 // VS2005 (8.0) +# define BOOST_MSSTL_VERSION 80 + +#endif + +// + #ifdef _CPPLIB_VER # define BOOST_STDLIB "Dinkumware standard library version " BOOST_STRINGIZE(_CPPLIB_VER) #else diff --git a/include/boost/config/stdlib/libcpp.hpp b/include/boost/config/stdlib/libcpp.hpp index e8eea9117..0e9f2445e 100644 --- a/include/boost/config/stdlib/libcpp.hpp +++ b/include/boost/config/stdlib/libcpp.hpp @@ -104,8 +104,34 @@ # define BOOST_NO_CXX98_BINDERS #endif -#define BOOST_NO_CXX17_ITERATOR_TRAITS +#if defined(__cplusplus) && defined(__has_include) +#if __has_include() +#include + +#if !defined(__cpp_lib_execution) || (__cpp_lib_execution < 201603L) +# define BOOST_NO_CXX17_HDR_EXECUTION +#endif +#if !defined(__cpp_lib_invoke) || (__cpp_lib_invoke < 201411L) +#define BOOST_NO_CXX17_STD_INVOKE +#endif + +#if(_LIBCPP_VERSION < 9000) +// as_writable_bytes is missing. +# define BOOST_NO_CXX20_HDR_SPAN +#endif + +#else +#define BOOST_NO_CXX17_STD_INVOKE // Invoke support is incomplete (no invoke_result) +#define BOOST_NO_CXX17_HDR_EXECUTION +#endif +#else #define BOOST_NO_CXX17_STD_INVOKE // Invoke support is incomplete (no invoke_result) +#define BOOST_NO_CXX17_HDR_EXECUTION +#endif + +#if _LIBCPP_VERSION < 10000 // What's the correct version check here? +#define BOOST_NO_CXX17_ITERATOR_TRAITS +#endif #if (_LIBCPP_VERSION <= 1101) && !defined(BOOST_NO_CXX11_THREAD_LOCAL) // This is a bit of a sledgehammer, because really it's just libc++abi that has no @@ -142,4 +168,13 @@ # define BOOST_NO_CXX14_HDR_SHARED_MUTEX #endif +#if _LIBCPP_VERSION >= 15000 +// +// Unary function is now deprecated in C++11 and later: +// +#if __cplusplus >= 201103L +#define BOOST_NO_CXX98_FUNCTION_BASE +#endif +#endif + // --- end --- diff --git a/include/boost/config/stdlib/libstdcpp3.hpp b/include/boost/config/stdlib/libstdcpp3.hpp index ee8f2a20a..ad70936de 100644 --- a/include/boost/config/stdlib/libstdcpp3.hpp +++ b/include/boost/config/stdlib/libstdcpp3.hpp @@ -94,6 +94,20 @@ #endif #endif +#if defined(__has_include) +#if defined(BOOST_HAS_HASH) +#if !__has_include(BOOST_HASH_SET_HEADER) || (__GNUC__ >= 10) +#undef BOOST_HAS_HASH +#undef BOOST_HAS_SET_HEADER +#undef BOOST_HAS_MAP_HEADER +#endif +#if !__has_include(BOOST_SLIST_HEADER) +#undef BOOST_HAS_SLIST +#undef BOOST_HAS_SLIST_HEADER +#endif +#endif +#endif + // // Decide whether we have C++11 support turned on: // @@ -125,7 +139,18 @@ // #ifdef __clang__ -#if __has_include() +#ifdef _GLIBCXX_RELEASE +# define BOOST_LIBSTDCXX_VERSION (_GLIBCXX_RELEASE * 10000 + 100) +#else +// +// We figure out which gcc version issued this std lib +// by checking which headers are available: +// +#if __has_include() +# define BOOST_LIBSTDCXX_VERSION 120100 +#elif __has_include() +# define BOOST_LIBSTDCXX_VERSION 110100 +#elif __has_include() # define BOOST_LIBSTDCXX_VERSION 100100 #elif __has_include() # define BOOST_LIBSTDCXX_VERSION 90100 @@ -152,6 +177,34 @@ #elif __has_include() # define BOOST_LIBSTDCXX_VERSION 40300 #endif +#endif +// +// If BOOST_HAS_FLOAT128 is set, now that we know the std lib is libstdc++3, check to see if the std lib is +// configured to support this type. If not disable it: +// +#if defined(BOOST_HAS_FLOAT128) && !defined(_GLIBCXX_USE_FLOAT128) +# undef BOOST_HAS_FLOAT128 +#endif + +#if (BOOST_LIBSTDCXX_VERSION >= 100000) && defined(BOOST_HAS_HASH) +// +// hash_set/hash_map deprecated and have terminal bugs: +// +#undef BOOST_HAS_HASH +#undef BOOST_HAS_SET_HEADER +#undef BOOST_HAS_MAP_HEADER +#endif + + +#if (BOOST_LIBSTDCXX_VERSION >= 100000) && defined(BOOST_HAS_HASH) +// +// hash_set/hash_map deprecated and have terminal bugs: +// +#undef BOOST_HAS_HASH +#undef BOOST_HAS_SET_HEADER +#undef BOOST_HAS_MAP_HEADER +#endif + #if (BOOST_LIBSTDCXX_VERSION < 50100) // libstdc++ does not define this function as it's deprecated in C++11, but clang still looks for it, @@ -214,8 +267,9 @@ extern "C" char *gets (char *__s); # if !_GLIBCXX_DEPRECATED # define BOOST_NO_AUTO_PTR # endif -# elif !_GLIBCXX_USE_DEPRECATED +# elif !defined(_GLIBCXX_USE_DEPRECATED) || !_GLIBCXX_USE_DEPRECATED # define BOOST_NO_AUTO_PTR +# define BOOST_NO_CXX98_BINDERS # endif #endif @@ -288,10 +342,6 @@ extern "C" char *gets (char *__s); # define BOOST_NO_CXX14_STD_EXCHANGE #endif -#if defined(__clang_major__) && ((__clang_major__ < 3) || ((__clang_major__ == 3) && (__clang_minor__ < 7))) -// As of clang-3.6, libstdc++ header throws up errors with clang: -# define BOOST_NO_CXX11_HDR_ATOMIC -#endif // // C++0x features in GCC 5.1 and later // @@ -319,10 +369,83 @@ extern "C" char *gets (char *__s); #elif __cplusplus <= 201103 # define BOOST_NO_CXX14_HDR_SHARED_MUTEX #endif +// +// has a dependency to Intel's thread building blocks: +// unless these are installed seperately, including leads +// to inscrutable errors inside libstdc++'s own headers. +// +#if (BOOST_LIBSTDCXX_VERSION < 100100) +#if !__has_include() +#define BOOST_NO_CXX17_HDR_EXECUTION +#endif +#endif #elif __cplusplus < 201402 || (BOOST_LIBSTDCXX_VERSION < 40900) || !defined(BOOST_LIBSTDCXX11) # define BOOST_NO_CXX14_HDR_SHARED_MUTEX #endif +#if BOOST_LIBSTDCXX_VERSION < 100100 +// +// The header may be present but is incomplete: +// +# define BOOST_NO_CXX17_HDR_CHARCONV +#endif + +#if BOOST_LIBSTDCXX_VERSION < 110000 +// +// Header may be present but lacks std::bit_cast: +// +#define BOOST_NO_CXX20_HDR_BIT +#endif + +#if BOOST_LIBSTDCXX_VERSION >= 120000 +// +// Unary function is now deprecated in C++11 and later: +// +#if __cplusplus >= 201103L +#define BOOST_NO_CXX98_FUNCTION_BASE +#endif +#endif + +#ifndef __cpp_impl_coroutine +# define BOOST_NO_CXX20_HDR_COROUTINE +#endif + +// +// These next defines are mostly for older clang versions with a newer libstdc++ : +// +#if !defined(__cpp_lib_concepts) +#if !defined(BOOST_NO_CXX20_HDR_COMPARE) +# define BOOST_NO_CXX20_HDR_COMPARE +#endif +#if !defined(BOOST_NO_CXX20_HDR_CONCEPTS) +# define BOOST_NO_CXX20_HDR_CONCEPTS +#endif +#if !defined(BOOST_NO_CXX20_HDR_SPAN) +# define BOOST_NO_CXX20_HDR_SPAN +#endif +#if !defined(BOOST_NO_CXX20_HDR_RANGES) +# define BOOST_NO_CXX20_HDR_RANGES +#endif +#endif + +#if defined(__clang__) +#if (__clang_major__ < 11) && !defined(BOOST_NO_CXX20_HDR_RANGES) +# define BOOST_NO_CXX20_HDR_RANGES +#endif +#if (__clang_major__ < 10) && (BOOST_LIBSTDCXX_VERSION >= 110000) && !defined(BOOST_NO_CXX11_HDR_CHRONO) +// Old clang can't parse : +# define BOOST_NO_CXX11_HDR_CHRONO +# define BOOST_NO_CXX11_HDR_CONDITION_VARIABLE +#endif +#endif + +#if defined(__clang__) && (BOOST_LIBSTDCXX_VERSION < 40300) && !defined(BOOST_NO_CXX11_NULLPTR) +# define BOOST_NO_CXX11_NULLPTR +#endif +#if defined(__clang__) && (BOOST_LIBSTDCXX_VERSION < 40300) && defined(BOOST_HAS_INT128) && defined(__APPLE_CC__) +#undef BOOST_HAS_INT128 +#endif + // // Headers not present on Solaris with the Oracle compiler: #if defined(__SUNPRO_CC) && (__SUNPRO_CC < 0x5140) @@ -351,7 +474,7 @@ extern "C" char *gets (char *__s); # endif #endif -#if (!defined(_GTHREAD_USE_MUTEX_TIMEDLOCK) || (_GTHREAD_USE_MUTEX_TIMEDLOCK == 0)) && !defined(BOOST_NO_CXX11_HDR_MUTEX) +#if (!defined(_GTHREAD_USE_MUTEX_TIMEDLOCK) || (_GTHREAD_USE_MUTEX_TIMEDLOCK == 0)) && !defined(BOOST_NO_CXX11_HDR_MUTEX) && (__GNUC__ < 6) // Timed mutexes are not always available: # define BOOST_NO_CXX11_HDR_MUTEX #endif diff --git a/include/boost/config/workaround.hpp b/include/boost/config/workaround.hpp index 7c6a2e62f..688f96366 100644 --- a/include/boost/config/workaround.hpp +++ b/include/boost/config/workaround.hpp @@ -192,6 +192,11 @@ #else #define _COMPILER_VERSION_WORKAROUND_GUARD 0 #endif +#ifndef __clang_major__ +#define __clang_major___WORKAROUND_GUARD 1 +#else +#define __clang_major___WORKAROUND_GUARD 0 +#endif #ifndef _RWSTD_VER #define _RWSTD_VER_WORKAROUND_GUARD 1 @@ -254,6 +259,12 @@ #else #define BOOST_INTEL_WORKAROUND_GUARD 0 #endif +#ifndef BOOST_CLANG_VERSION +#define BOOST_CLANG_VERSION_WORKAROUND_GUARD 1 +#else +#define BOOST_CLANG_VERSION_WORKAROUND_GUARD 0 +#endif + // Always define to zero, if it's used it'll be defined my MPL: #define BOOST_MPL_CFG_GCC_WORKAROUND_GUARD 0 diff --git a/include/boost/container_hash/detail/hash_mix.hpp b/include/boost/container_hash/detail/hash_mix.hpp new file mode 100644 index 000000000..327da9e51 --- /dev/null +++ b/include/boost/container_hash/detail/hash_mix.hpp @@ -0,0 +1,113 @@ +// Copyright 2022 Peter Dimov +// Distributed under the Boost Software License, Version 1.0. +// https://www.boost.org/LICENSE_1_0.txt + +#ifndef BOOST_HASH_DETAIL_HASH_MIX_HPP +#define BOOST_HASH_DETAIL_HASH_MIX_HPP + +#include +#include +#include + +namespace boost +{ +namespace hash_detail +{ + +template struct hash_mix_impl; + +// hash_mix for 64 bit size_t +// +// The general "xmxmx" form of state of the art 64 bit mixers originates +// from Murmur3 by Austin Appleby, which uses the following function as +// its "final mix": +// +// k ^= k >> 33; +// k *= 0xff51afd7ed558ccd; +// k ^= k >> 33; +// k *= 0xc4ceb9fe1a85ec53; +// k ^= k >> 33; +// +// (https://github.com/aappleby/smhasher/blob/master/src/MurmurHash3.cpp) +// +// It has subsequently been improved multiple times by different authors +// by changing the constants. The most well known improvement is the +// so-called "variant 13" function by David Stafford: +// +// k ^= k >> 30; +// k *= 0xbf58476d1ce4e5b9; +// k ^= k >> 27; +// k *= 0x94d049bb133111eb; +// k ^= k >> 31; +// +// (https://zimbry.blogspot.com/2011/09/better-bit-mixing-improving-on.html) +// +// This mixing function is used in the splitmix64 RNG: +// http://xorshift.di.unimi.it/splitmix64.c +// +// We use Jon Maiga's implementation from +// http://jonkagstrom.com/mx3/mx3_rev2.html +// +// x ^= x >> 32; +// x *= 0xe9846af9b1a615d; +// x ^= x >> 32; +// x *= 0xe9846af9b1a615d; +// x ^= x >> 28; +// +// An equally good alternative is Pelle Evensen's Moremur: +// +// x ^= x >> 27; +// x *= 0x3C79AC492BA7B653; +// x ^= x >> 33; +// x *= 0x1C69B3F74AC4AE35; +// x ^= x >> 27; +// +// (https://mostlymangling.blogspot.com/2019/12/stronger-better-morer-moremur-better.html) + +template<> struct hash_mix_impl<64> +{ + inline static boost::uint64_t fn( boost::uint64_t x ) + { + boost::uint64_t const m = (boost::uint64_t(0xe9846af) << 32) + 0x9b1a615d; + + x ^= x >> 32; + x *= m; + x ^= x >> 32; + x *= m; + x ^= x >> 28; + + return x; + } +}; + +// hash_mix for 32 bit size_t +// +// We use the "best xmxmx" implementation from +// https://github.com/skeeto/hash-prospector/issues/19 + +template<> struct hash_mix_impl<32> +{ + inline static boost::uint32_t fn( boost::uint32_t x ) + { + boost::uint32_t const m1 = 0x21f0aaad; + boost::uint32_t const m2 = 0x735a2d97; + + x ^= x >> 16; + x *= m1; + x ^= x >> 15; + x *= m2; + x ^= x >> 15; + + return x; + } +}; + +inline std::size_t hash_mix( std::size_t v ) +{ + return hash_mix_impl::fn( v ); +} + +} // namespace hash_detail +} // namespace boost + +#endif // #ifndef BOOST_HASH_DETAIL_HASH_MIX_HPP diff --git a/include/boost/container_hash/detail/hash_range.hpp b/include/boost/container_hash/detail/hash_range.hpp new file mode 100644 index 000000000..84ec97da5 --- /dev/null +++ b/include/boost/container_hash/detail/hash_range.hpp @@ -0,0 +1,410 @@ +// Copyright 2022 Peter Dimov +// Distributed under the Boost Software License, Version 1.0. +// https://www.boost.org/LICENSE_1_0.txt + +#ifndef BOOST_HASH_DETAIL_HASH_RANGE_HPP +#define BOOST_HASH_DETAIL_HASH_RANGE_HPP + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +namespace boost +{ +namespace hash_detail +{ + +template struct is_char_type: public boost::false_type {}; + +#if CHAR_BIT == 8 + +template<> struct is_char_type: public boost::true_type {}; +template<> struct is_char_type: public boost::true_type {}; +template<> struct is_char_type: public boost::true_type {}; + +#if defined(__cpp_char8_t) && __cpp_char8_t >= 201811L +template<> struct is_char_type: public boost::true_type {}; +#endif + +#if defined(__cpp_lib_byte) && __cpp_lib_byte >= 201603L +template<> struct is_char_type: public boost::true_type {}; +#endif + +#endif + +// generic version + +template +inline typename boost::enable_if_< + !is_char_type::value_type>::value, +std::size_t >::type + hash_range( std::size_t seed, It first, It last ) +{ + for( ; first != last; ++first ) + { + hash_combine::value_type>( seed, *first ); + } + + return seed; +} + +// specialized char[] version, 32 bit + +template inline boost::uint32_t read32le( It p ) +{ + // clang 5+, gcc 5+ figure out this pattern and use a single mov on x86 + // gcc on s390x and power BE even knows how to use load-reverse + + boost::uint32_t w = + static_cast( static_cast( p[0] ) ) | + static_cast( static_cast( p[1] ) ) << 8 | + static_cast( static_cast( p[2] ) ) << 16 | + static_cast( static_cast( p[3] ) ) << 24; + + return w; +} + +#if defined(_MSC_VER) && !defined(__clang__) + +template inline boost::uint32_t read32le( T* p ) +{ + boost::uint32_t w; + + std::memcpy( &w, p, 4 ); + return w; +} + +#endif + +inline boost::uint64_t mul32( boost::uint32_t x, boost::uint32_t y ) +{ + return static_cast( x ) * y; +} + +template +inline typename boost::enable_if_< + is_char_type::value_type>::value && + is_same::iterator_category, std::random_access_iterator_tag>::value && + std::numeric_limits::digits <= 32, +std::size_t>::type + hash_range( std::size_t seed, It first, It last ) +{ + It p = first; + std::size_t n = static_cast( last - first ); + + boost::uint32_t const q = 0x9e3779b9U; + boost::uint32_t const k = 0xe35e67b1U; // q * q + + boost::uint64_t h = mul32( static_cast( seed ) + q, k ); + boost::uint32_t w = static_cast( h & 0xFFFFFFFF ); + + h ^= n; + + while( n >= 4 ) + { + boost::uint32_t v1 = read32le( p ); + + w += q; + h ^= mul32( v1 + w, k ); + + p += 4; + n -= 4; + } + + { + boost::uint32_t v1 = 0; + + if( n >= 1 ) + { + std::size_t const x1 = ( n - 1 ) & 2; // 1: 0, 2: 0, 3: 2 + std::size_t const x2 = n >> 1; // 1: 0, 2: 1, 3: 1 + + v1 = + static_cast( static_cast( p[ static_cast( x1 ) ] ) ) << x1 * 8 | + static_cast( static_cast( p[ static_cast( x2 ) ] ) ) << x2 * 8 | + static_cast( static_cast( p[ 0 ] ) ); + } + + w += q; + h ^= mul32( v1 + w, k ); + } + + w += q; + h ^= mul32( static_cast( h & 0xFFFFFFFF ) + w, static_cast( h >> 32 ) + w + k ); + + return static_cast( h & 0xFFFFFFFF ) ^ static_cast( h >> 32 ); +} + +template +inline typename boost::enable_if_< + is_char_type::value_type>::value && + !is_same::iterator_category, std::random_access_iterator_tag>::value && + std::numeric_limits::digits <= 32, +std::size_t>::type + hash_range( std::size_t seed, It first, It last ) +{ + std::size_t n = 0; + + boost::uint32_t const q = 0x9e3779b9U; + boost::uint32_t const k = 0xe35e67b1U; // q * q + + boost::uint64_t h = mul32( static_cast( seed ) + q, k ); + boost::uint32_t w = static_cast( h & 0xFFFFFFFF ); + + boost::uint32_t v1 = 0; + + for( ;; ) + { + v1 = 0; + + if( first == last ) + { + break; + } + + v1 |= static_cast( static_cast( *first ) ); + ++first; + ++n; + + if( first == last ) + { + break; + } + + v1 |= static_cast( static_cast( *first ) ) << 8; + ++first; + ++n; + + if( first == last ) + { + break; + } + + v1 |= static_cast( static_cast( *first ) ) << 16; + ++first; + ++n; + + if( first == last ) + { + break; + } + + v1 |= static_cast( static_cast( *first ) ) << 24; + ++first; + ++n; + + w += q; + h ^= mul32( v1 + w, k ); + } + + h ^= n; + + w += q; + h ^= mul32( v1 + w, k ); + + w += q; + h ^= mul32( static_cast( h & 0xFFFFFFFF ) + w, static_cast( h >> 32 ) + w + k ); + + return static_cast( h & 0xFFFFFFFF ) ^ static_cast( h >> 32 ); +} + +// specialized char[] version, 64 bit + +template inline boost::uint64_t read64le( It p ) +{ + boost::uint64_t w = + static_cast( static_cast( p[0] ) ) | + static_cast( static_cast( p[1] ) ) << 8 | + static_cast( static_cast( p[2] ) ) << 16 | + static_cast( static_cast( p[3] ) ) << 24 | + static_cast( static_cast( p[4] ) ) << 32 | + static_cast( static_cast( p[5] ) ) << 40 | + static_cast( static_cast( p[6] ) ) << 48 | + static_cast( static_cast( p[7] ) ) << 56; + + return w; +} + +#if defined(_MSC_VER) && !defined(__clang__) + +template inline boost::uint64_t read64le( T* p ) +{ + boost::uint64_t w; + + std::memcpy( &w, p, 8 ); + return w; +} + +#endif + +template +inline typename boost::enable_if_< + is_char_type::value_type>::value && + is_same::iterator_category, std::random_access_iterator_tag>::value && + (std::numeric_limits::digits > 32), +std::size_t>::type + hash_range( std::size_t seed, It first, It last ) +{ + It p = first; + std::size_t n = static_cast( last - first ); + + boost::uint64_t const q = static_cast( 0x9e3779b9 ) << 32 | 0x7f4a7c15; + boost::uint64_t const k = static_cast( 0xdf442d22 ) << 32 | 0xce4859b9; // q * q + + boost::uint64_t w = mulx( seed + q, k ); + boost::uint64_t h = w ^ n; + + while( n >= 8 ) + { + boost::uint64_t v1 = read64le( p ); + + w += q; + h ^= mulx( v1 + w, k ); + + p += 8; + n -= 8; + } + + { + boost::uint64_t v1 = 0; + + if( n >= 4 ) + { + v1 = static_cast( read32le( p + static_cast( n - 4 ) ) ) << ( n - 4 ) * 8 | read32le( p ); + } + else if( n >= 1 ) + { + std::size_t const x1 = ( n - 1 ) & 2; // 1: 0, 2: 0, 3: 2 + std::size_t const x2 = n >> 1; // 1: 0, 2: 1, 3: 1 + + v1 = + static_cast( static_cast( p[ static_cast( x1 ) ] ) ) << x1 * 8 | + static_cast( static_cast( p[ static_cast( x2 ) ] ) ) << x2 * 8 | + static_cast( static_cast( p[ 0 ] ) ); + } + + w += q; + h ^= mulx( v1 + w, k ); + } + + return mulx( h + w, k ); +} + +template +inline typename boost::enable_if_< + is_char_type::value_type>::value && + !is_same::iterator_category, std::random_access_iterator_tag>::value && + (std::numeric_limits::digits > 32), +std::size_t>::type + hash_range( std::size_t seed, It first, It last ) +{ + std::size_t n = 0; + + boost::uint64_t const q = static_cast( 0x9e3779b9 ) << 32 | 0x7f4a7c15; + boost::uint64_t const k = static_cast( 0xdf442d22 ) << 32 | 0xce4859b9; // q * q + + boost::uint64_t w = mulx( seed + q, k ); + boost::uint64_t h = w; + + boost::uint64_t v1 = 0; + + for( ;; ) + { + v1 = 0; + + if( first == last ) + { + break; + } + + v1 |= static_cast( static_cast( *first ) ); + ++first; + ++n; + + if( first == last ) + { + break; + } + + v1 |= static_cast( static_cast( *first ) ) << 8; + ++first; + ++n; + + if( first == last ) + { + break; + } + + v1 |= static_cast( static_cast( *first ) ) << 16; + ++first; + ++n; + + if( first == last ) + { + break; + } + + v1 |= static_cast( static_cast( *first ) ) << 24; + ++first; + ++n; + + if( first == last ) + { + break; + } + + v1 |= static_cast( static_cast( *first ) ) << 32; + ++first; + ++n; + + if( first == last ) + { + break; + } + + v1 |= static_cast( static_cast( *first ) ) << 40; + ++first; + ++n; + + if( first == last ) + { + break; + } + + v1 |= static_cast( static_cast( *first ) ) << 48; + ++first; + ++n; + + if( first == last ) + { + break; + } + + v1 |= static_cast( static_cast( *first ) ) << 56; + ++first; + ++n; + + w += q; + h ^= mulx( v1 + w, k ); + } + + h ^= n; + + w += q; + h ^= mulx( v1 + w, k ); + + return mulx( h + w, k ); +} + +} // namespace hash_detail +} // namespace boost + +#endif // #ifndef BOOST_HASH_DETAIL_HASH_RANGE_HPP diff --git a/include/boost/container_hash/detail/hash_tuple_like.hpp b/include/boost/container_hash/detail/hash_tuple_like.hpp new file mode 100644 index 000000000..f9f5a5bae --- /dev/null +++ b/include/boost/container_hash/detail/hash_tuple_like.hpp @@ -0,0 +1,156 @@ +// Copyright 2005-2009 Daniel James. +// Copyright 2021 Peter Dimov. +// Distributed under the Boost Software License, Version 1.0. +// https://www.boost.org/LICENSE_1_0.txt + +#ifndef BOOST_HASH_DETAIL_HASH_TUPLE_LIKE_HPP +#define BOOST_HASH_DETAIL_HASH_TUPLE_LIKE_HPP + +#include +#include +#include +#include +#include +#include + +#if defined(BOOST_NO_CXX11_HDR_TUPLE) + +// no support for tuple-likes + +#else + +#include + +namespace boost +{ +namespace hash_detail +{ + +template +inline +typename boost::enable_if_<(I == std::tuple_size::value), void>::type + hash_combine_tuple_like( std::size_t&, T const& ) +{ +} + +template +inline +typename boost::enable_if_<(I < std::tuple_size::value), void>::type + hash_combine_tuple_like( std::size_t& seed, T const& v ) +{ + using std::get; + boost::hash_combine( seed, get( v ) ); + + boost::hash_detail::hash_combine_tuple_like( seed, v ); +} + +template +inline std::size_t hash_tuple_like( T const& v ) +{ + std::size_t seed = 0; + + boost::hash_detail::hash_combine_tuple_like<0>( seed, v ); + + return seed; +} + +} // namespace hash_detail + +#if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) + +#if !BOOST_WORKAROUND(BOOST_MSVC, <= 1800) + +template +inline +typename boost::enable_if_< + container_hash::is_tuple_like::value && !container_hash::is_range::value, +std::size_t>::type + hash_value( T const& v ) +{ + return boost::hash_detail::hash_tuple_like( v ); +} + +#else + +template +inline std::size_t hash_value( std::tuple const& v ) +{ + return boost::hash_detail::hash_tuple_like( v ); +} + +#endif + +#else + +inline std::size_t hash_value( std::tuple<> const& v ) +{ + return boost::hash_detail::hash_tuple_like( v ); +} + +template +inline std::size_t hash_value( std::tuple const& v ) +{ + return boost::hash_detail::hash_tuple_like( v ); +} + +template +inline std::size_t hash_value( std::tuple const& v ) +{ + return boost::hash_detail::hash_tuple_like( v ); +} + +template +inline std::size_t hash_value( std::tuple const& v ) +{ + return boost::hash_detail::hash_tuple_like( v ); +} + +template +inline std::size_t hash_value( std::tuple const& v ) +{ + return boost::hash_detail::hash_tuple_like( v ); +} + +template +inline std::size_t hash_value( std::tuple const& v ) +{ + return boost::hash_detail::hash_tuple_like( v ); +} + +template +inline std::size_t hash_value( std::tuple const& v ) +{ + return boost::hash_detail::hash_tuple_like( v ); +} + +template +inline std::size_t hash_value( std::tuple const& v ) +{ + return boost::hash_detail::hash_tuple_like( v ); +} + +template +inline std::size_t hash_value( std::tuple const& v ) +{ + return boost::hash_detail::hash_tuple_like( v ); +} + +template +inline std::size_t hash_value( std::tuple const& v ) +{ + return boost::hash_detail::hash_tuple_like( v ); +} + +template +inline std::size_t hash_value( std::tuple const& v ) +{ + return boost::hash_detail::hash_tuple_like( v ); +} + +#endif // #if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) + +} // namespace boost + +#endif // #if defined(BOOST_NO_CXX11_HDR_TUPLE) + +#endif // #ifndef BOOST_HASH_DETAIL_HASH_TUPLE_LIKE_HPP diff --git a/include/boost/container_hash/detail/limits.hpp b/include/boost/container_hash/detail/limits.hpp index 4a971a6ac..789030955 100644 --- a/include/boost/container_hash/detail/limits.hpp +++ b/include/boost/container_hash/detail/limits.hpp @@ -1,28 +1,11 @@ - // Copyright 2005-2009 Daniel James. // 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) -// -// On some platforms std::limits gives incorrect values for long double. -// This tries to work around them. -#if !defined(BOOST_FUNCTIONAL_HASH_DETAIL_LIMITS_HEADER) +#ifndef BOOST_FUNCTIONAL_HASH_DETAIL_LIMITS_HEADER #define BOOST_FUNCTIONAL_HASH_DETAIL_LIMITS_HEADER -#include -#if defined(BOOST_HAS_PRAGMA_ONCE) -#pragma once -#endif - -#include - -// On OpenBSD, numeric_limits is not reliable for long doubles, but -// the macros defined in are and support long double when STLport -// doesn't. - -#if defined(__OpenBSD__) || defined(_STLP_NO_LONG_DOUBLE) -#include -#endif +#include namespace boost { @@ -30,33 +13,7 @@ namespace boost { template struct limits : std::numeric_limits {}; - -#if defined(__OpenBSD__) || defined(_STLP_NO_LONG_DOUBLE) - template <> - struct limits - : std::numeric_limits - { - static long double epsilon() { - return LDBL_EPSILON; - } - - static long double (max)() { - return LDBL_MAX; - } - - static long double (min)() { - return LDBL_MIN; - } - - BOOST_STATIC_CONSTANT(int, digits = LDBL_MANT_DIG); - BOOST_STATIC_CONSTANT(int, max_exponent = LDBL_MAX_EXP); - BOOST_STATIC_CONSTANT(int, min_exponent = LDBL_MIN_EXP); -#if defined(_STLP_NO_LONG_DOUBLE) - BOOST_STATIC_CONSTANT(int, radix = FLT_RADIX); -#endif - }; -#endif // __OpenBSD__ } } -#endif +#endif // #ifndef BOOST_FUNCTIONAL_HASH_DETAIL_LIMITS_HEADER diff --git a/include/boost/container_hash/detail/mulx.hpp b/include/boost/container_hash/detail/mulx.hpp new file mode 100644 index 000000000..da6f21a24 --- /dev/null +++ b/include/boost/container_hash/detail/mulx.hpp @@ -0,0 +1,79 @@ +// Copyright 2022, 2023 Peter Dimov +// Distributed under the Boost Software License, Version 1.0. +// https://www.boost.org/LICENSE_1_0.txt + +#ifndef BOOST_HASH_DETAIL_MULX_HPP +#define BOOST_HASH_DETAIL_MULX_HPP + +#include +#if defined(_MSC_VER) +# include +#endif + +namespace boost +{ +namespace hash_detail +{ + +#if defined(_MSC_VER) && defined(_M_X64) && !defined(__clang__) + +__forceinline boost::uint64_t mulx( boost::uint64_t x, boost::uint64_t y ) +{ + boost::uint64_t r2; + boost::uint64_t r = _umul128( x, y, &r2 ); + return r ^ r2; +} + +#elif defined(_MSC_VER) && defined(_M_ARM64) && !defined(__clang__) + +__forceinline boost::uint64_t mulx( boost::uint64_t x, boost::uint64_t y ) +{ + boost::uint64_t r = x * y; + boost::uint64_t r2 = __umulh( x, y ); + return r ^ r2; +} + +#elif defined(__SIZEOF_INT128__) + +inline boost::uint64_t mulx( boost::uint64_t x, boost::uint64_t y ) +{ + __uint128_t r = static_cast<__uint128_t>( x ) * y; + return static_cast( r ) ^ static_cast( r >> 64 ); +} + +#else + +inline boost::uint64_t mulx( boost::uint64_t x, boost::uint64_t y ) +{ + boost::uint64_t x1 = static_cast( x ); + boost::uint64_t x2 = x >> 32; + + boost::uint64_t y1 = static_cast( y ); + boost::uint64_t y2 = y >> 32; + + boost::uint64_t r3 = x2 * y2; + + boost::uint64_t r2a = x1 * y2; + + r3 += r2a >> 32; + + boost::uint64_t r2b = x2 * y1; + + r3 += r2b >> 32; + + boost::uint64_t r1 = x1 * y1; + + boost::uint64_t r2 = (r1 >> 32) + static_cast( r2a ) + static_cast( r2b ); + + r1 = (r2 << 32) + static_cast( r1 ); + r3 += r2 >> 32; + + return r1 ^ r3; +} + +#endif + +} // namespace hash_detail +} // namespace boost + +#endif // #ifndef BOOST_HASH_DETAIL_MULX_HPP diff --git a/include/boost/container_hash/detail/requires_cxx11.hpp b/include/boost/container_hash/detail/requires_cxx11.hpp new file mode 100644 index 000000000..f123f9275 --- /dev/null +++ b/include/boost/container_hash/detail/requires_cxx11.hpp @@ -0,0 +1,22 @@ +#ifndef BOOST_HASH_DETAIL_REQUIRES_CXX11_HPP_INCLUDED +#define BOOST_HASH_DETAIL_REQUIRES_CXX11_HPP_INCLUDED + +// Copyright 2023 Peter Dimov +// Distributed under the Boost Software License, Version 1.0. +// https://www.boost.org/LICENSE_1_0.txt + +#include +#include + +#if defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) || \ + defined(BOOST_NO_CXX11_RVALUE_REFERENCES) || \ + defined(BOOST_NO_CXX11_DECLTYPE) || \ + defined(BOOST_NO_CXX11_CONSTEXPR) || \ + defined(BOOST_NO_CXX11_NOEXCEPT) || \ + defined(BOOST_NO_CXX11_HDR_TUPLE) + +BOOST_PRAGMA_MESSAGE("C++03 support was deprecated in Boost.ContainerHash 1.82 and will be removed in Boost.ContainerHash 1.84. Please open an issue in https://github.com/boostorg/container_hash if you want it retained.") + +#endif + +#endif // #ifndef BOOST_HASH_DETAIL_REQUIRES_CXX11_HPP_INCLUDED diff --git a/include/boost/container_hash/extensions.hpp b/include/boost/container_hash/extensions.hpp index aa4f9cff8..809d39783 100644 --- a/include/boost/container_hash/extensions.hpp +++ b/include/boost/container_hash/extensions.hpp @@ -1,361 +1,10 @@ - // Copyright 2005-2009 Daniel James. // 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) -// Based on Peter Dimov's proposal -// http://www.open-std.org/JTC1/SC22/WG21/docs/papers/2005/n1756.pdf -// issue 6.18. - -// This implements the extensions to the standard. -// It's undocumented, so you shouldn't use it.... - -#if !defined(BOOST_FUNCTIONAL_HASH_EXTENSIONS_HPP) +#ifndef BOOST_FUNCTIONAL_HASH_EXTENSIONS_HPP #define BOOST_FUNCTIONAL_HASH_EXTENSIONS_HPP -#include -#if defined(BOOST_HAS_PRAGMA_ONCE) -#pragma once -#endif - #include -#include -#include -#include - -#if !defined(BOOST_NO_CXX11_HDR_ARRAY) -# include -#endif - -#if !defined(BOOST_NO_CXX11_HDR_TUPLE) -# include -#endif - -#include - -#if defined(BOOST_NO_FUNCTION_TEMPLATE_ORDERING) -#include -#endif - -namespace boost -{ - template - std::size_t hash_value(std::pair const&); - template - std::size_t hash_value(std::vector const&); - template - std::size_t hash_value(std::list const& v); - template - std::size_t hash_value(std::deque const& v); - template - std::size_t hash_value(std::set const& v); - template - std::size_t hash_value(std::multiset const& v); - template - std::size_t hash_value(std::map const& v); - template - std::size_t hash_value(std::multimap const& v); - - template - std::size_t hash_value(std::complex const&); - - template - std::size_t hash_value(std::pair const& v) - { - std::size_t seed = 0; - boost::hash_combine(seed, v.first); - boost::hash_combine(seed, v.second); - return seed; - } - - template - std::size_t hash_value(std::vector const& v) - { - return boost::hash_range(v.begin(), v.end()); - } - - template - std::size_t hash_value(std::list const& v) - { - return boost::hash_range(v.begin(), v.end()); - } - - template - std::size_t hash_value(std::deque const& v) - { - return boost::hash_range(v.begin(), v.end()); - } - - template - std::size_t hash_value(std::set const& v) - { - return boost::hash_range(v.begin(), v.end()); - } - - template - std::size_t hash_value(std::multiset const& v) - { - return boost::hash_range(v.begin(), v.end()); - } - - template - std::size_t hash_value(std::map const& v) - { - return boost::hash_range(v.begin(), v.end()); - } - - template - std::size_t hash_value(std::multimap const& v) - { - return boost::hash_range(v.begin(), v.end()); - } - - template - std::size_t hash_value(std::complex const& v) - { - boost::hash hasher; - std::size_t seed = hasher(v.imag()); - seed ^= hasher(v.real()) + (seed<<6) + (seed>>2); - return seed; - } - -#if !defined(BOOST_NO_CXX11_HDR_ARRAY) - template - std::size_t hash_value(std::array const& v) - { - return boost::hash_range(v.begin(), v.end()); - } -#endif - -#if !defined(BOOST_NO_CXX11_HDR_TUPLE) - namespace hash_detail { - template - inline typename boost::enable_if_c<(I == std::tuple_size::value), - void>::type - hash_combine_tuple(std::size_t&, T const&) - { - } - - template - inline typename boost::enable_if_c<(I < std::tuple_size::value), - void>::type - hash_combine_tuple(std::size_t& seed, T const& v) - { - boost::hash_combine(seed, std::get(v)); - boost::hash_detail::hash_combine_tuple(seed, v); - } - - template - inline std::size_t hash_tuple(T const& v) - { - std::size_t seed = 0; - boost::hash_detail::hash_combine_tuple<0>(seed, v); - return seed; - } - } - -#if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) - template - inline std::size_t hash_value(std::tuple const& v) - { - return boost::hash_detail::hash_tuple(v); - } -#else - - inline std::size_t hash_value(std::tuple<> const& v) - { - return boost::hash_detail::hash_tuple(v); - } - - template - inline std::size_t hash_value(std::tuple const& v) - { - return boost::hash_detail::hash_tuple(v); - } - - template - inline std::size_t hash_value(std::tuple const& v) - { - return boost::hash_detail::hash_tuple(v); - } - - template - inline std::size_t hash_value(std::tuple const& v) - { - return boost::hash_detail::hash_tuple(v); - } - - template - inline std::size_t hash_value(std::tuple const& v) - { - return boost::hash_detail::hash_tuple(v); - } - - template - inline std::size_t hash_value(std::tuple const& v) - { - return boost::hash_detail::hash_tuple(v); - } - - template - inline std::size_t hash_value(std::tuple const& v) - { - return boost::hash_detail::hash_tuple(v); - } - - template - inline std::size_t hash_value(std::tuple const& v) - { - return boost::hash_detail::hash_tuple(v); - } - - template - inline std::size_t hash_value(std::tuple const& v) - { - return boost::hash_detail::hash_tuple(v); - } - - template - inline std::size_t hash_value(std::tuple const& v) - { - return boost::hash_detail::hash_tuple(v); - } - - template - inline std::size_t hash_value(std::tuple const& v) - { - return boost::hash_detail::hash_tuple(v); - } - -#endif - -#endif - -#if !defined(BOOST_NO_CXX11_SMART_PTR) - template - inline std::size_t hash_value(std::shared_ptr const& x) { - return boost::hash_value(x.get()); - } - - template - inline std::size_t hash_value(std::unique_ptr const& x) { - return boost::hash_value(x.get()); - } -#endif - - // - // call_hash_impl - // - - // On compilers without function template ordering, this deals with arrays. - -#if defined(BOOST_NO_FUNCTION_TEMPLATE_ORDERING) - namespace hash_detail - { - template - struct call_hash_impl - { - template - struct inner - { - static std::size_t call(T const& v) - { - using namespace boost; - return hash_value(v); - } - }; - }; - - template <> - struct call_hash_impl - { - template - struct inner - { - static std::size_t call(Array const& v) - { - const int size = sizeof(v) / sizeof(*v); - return boost::hash_range(v, v + size); - } - }; - }; - - template - struct call_hash - : public call_hash_impl::value> - ::BOOST_NESTED_TEMPLATE inner - { - }; - } -#endif // BOOST_NO_FUNCTION_TEMPLATE_ORDERING - - // - // boost::hash - // - - -#if !defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION) - - template struct hash - : boost::hash_detail::hash_base - { -#if !defined(BOOST_NO_FUNCTION_TEMPLATE_ORDERING) - std::size_t operator()(T const& val) const - { - return hash_value(val); - } -#else - std::size_t operator()(T const& val) const - { - return hash_detail::call_hash::call(val); - } -#endif - }; - -#if BOOST_WORKAROUND(__DMC__, <= 0x848) - template struct hash - : boost::hash_detail::hash_base - { - std::size_t operator()(const T* val) const - { - return boost::hash_range(val, val+n); - } - }; -#endif - -#else // BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION - - // On compilers without partial specialization, boost::hash - // has already been declared to deal with pointers, so just - // need to supply the non-pointer version of hash_impl. - - namespace hash_detail - { - template - struct hash_impl; - - template <> - struct hash_impl - { - template - struct inner - : boost::hash_detail::hash_base - { -#if !defined(BOOST_NO_FUNCTION_TEMPLATE_ORDERING) - std::size_t operator()(T const& val) const - { - return hash_value(val); - } -#else - std::size_t operator()(T const& val) const - { - return hash_detail::call_hash::call(val); - } -#endif - }; - }; - } -#endif // BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION -} -#endif +#endif // #ifndef BOOST_FUNCTIONAL_HASH_EXTENSIONS_HPP diff --git a/include/boost/container_hash/hash.hpp b/include/boost/container_hash/hash.hpp index 6059fee19..605644b35 100644 --- a/include/boost/container_hash/hash.hpp +++ b/include/boost/container_hash/hash.hpp @@ -1,34 +1,52 @@ - // Copyright 2005-2014 Daniel James. -// 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) - -// Based on Peter Dimov's proposal -// http://www.open-std.org/JTC1/SC22/WG21/docs/papers/2005/n1756.pdf -// issue 6.18. -// -// This also contains public domain code from MurmurHash. From the -// MurmurHash header: +// Copyright 2021, 2022 Peter Dimov. +// Distributed under the Boost Software License, Version 1.0. +// https://www.boost.org/LICENSE_1_0.txt -// MurmurHash3 was written by Austin Appleby, and is placed in the public -// domain. The author hereby disclaims copyright to this source code. +// Based on Peter Dimov's proposal +// http://www.open-std.org/JTC1/SC22/WG21/docs/papers/2005/n1756.pdf +// issue 6.18. -#if !defined(BOOST_FUNCTIONAL_HASH_HASH_HPP) +#ifndef BOOST_FUNCTIONAL_HASH_HASH_HPP #define BOOST_FUNCTIONAL_HASH_HASH_HPP #include -#include -#include -#include -#include -#include +#include +#include +#include +#include +#include +#include +#include +#include #include #include -#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include #include -#if defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION) -#include +#if defined(BOOST_DESCRIBE_CXX14) +# include +#endif + +#include +#include +#include +#include +#include +#include +#include + +#if !defined(BOOST_NO_CXX11_SMART_PTR) +# include #endif #if !defined(BOOST_NO_CXX11_HDR_TYPEINDEX) @@ -39,724 +57,621 @@ #include #endif -#if defined(BOOST_MSVC) -#pragma warning(push) - -#if BOOST_MSVC >= 1400 -#pragma warning(disable:6295) // Ill-defined for-loop : 'unsigned int' values - // are always of range '0' to '4294967295'. - // Loop executes infinitely. -#endif - -#endif - -#if BOOST_WORKAROUND(__GNUC__, < 3) \ - && !defined(__SGI_STL_PORT) && !defined(_STLPORT_VERSION) -#define BOOST_HASH_CHAR_TRAITS string_char_traits -#else -#define BOOST_HASH_CHAR_TRAITS char_traits -#endif - -#if defined(_MSC_VER) -# define BOOST_FUNCTIONAL_HASH_ROTL32(x, r) _rotl(x,r) -#else -# define BOOST_FUNCTIONAL_HASH_ROTL32(x, r) (x << r) | (x >> (32 - r)) -#endif - -// Detect whether standard library has C++17 headers - -#if !defined(BOOST_HASH_CXX17) -# if defined(BOOST_MSVC) -# if defined(_HAS_CXX17) && _HAS_CXX17 -# define BOOST_HASH_CXX17 1 -# endif -# elif defined(__cplusplus) && __cplusplus >= 201703 -# define BOOST_HASH_CXX17 1 -# endif -#endif - -#if !defined(BOOST_HASH_CXX17) -# define BOOST_HASH_CXX17 0 -#endif - -#if BOOST_HASH_CXX17 && defined(__has_include) -# if !defined(BOOST_HASH_HAS_STRING_VIEW) && __has_include() -# define BOOST_HASH_HAS_STRING_VIEW 1 -# endif -# if !defined(BOOST_HASH_HAS_OPTIONAL) && __has_include() -# define BOOST_HASH_HAS_OPTIONAL 1 -# endif -# if !defined(BOOST_HASH_HAS_VARIANT) && __has_include() -# define BOOST_HASH_HAS_VARIANT 1 -# endif -#endif - -#if !defined(BOOST_HASH_HAS_STRING_VIEW) -# define BOOST_HASH_HAS_STRING_VIEW 0 +#if !defined(BOOST_NO_CXX17_HDR_OPTIONAL) +#include #endif -#if !defined(BOOST_HASH_HAS_OPTIONAL) -# define BOOST_HASH_HAS_OPTIONAL 0 +#if !defined(BOOST_NO_CXX17_HDR_VARIANT) +#include #endif -#if !defined(BOOST_HASH_HAS_VARIANT) -# define BOOST_HASH_HAS_VARIANT 0 +#if !defined(BOOST_NO_CXX17_HDR_STRING_VIEW) +# include #endif -#if BOOST_HASH_HAS_STRING_VIEW -# include -#endif +namespace boost +{ -#if BOOST_HASH_HAS_OPTIONAL -# include -#endif + // + // boost::hash_value + // -#if BOOST_HASH_HAS_VARIANT -# include -#endif + // integral types -namespace boost -{ namespace hash_detail { -#if defined(BOOST_NO_CXX98_FUNCTION_BASE) - template - struct hash_base + template sizeof(std::size_t)), + bool is_unsigned = boost::is_unsigned::value, + std::size_t size_t_bits = sizeof(std::size_t) * CHAR_BIT, + std::size_t type_bits = sizeof(T) * CHAR_BIT> + struct hash_integral_impl; + + template struct hash_integral_impl { - typedef T argument_type; - typedef std::size_t result_type; + static std::size_t fn( T v ) + { + return static_cast( v ); + } }; -#else - template - struct hash_base : std::unary_function {}; -#endif - - struct enable_hash_value { typedef std::size_t type; }; - - template struct basic_numbers {}; - template struct long_numbers; - template struct ulong_numbers; - template struct float_numbers {}; - - template <> struct basic_numbers : - boost::hash_detail::enable_hash_value {}; - template <> struct basic_numbers : - boost::hash_detail::enable_hash_value {}; - template <> struct basic_numbers : - boost::hash_detail::enable_hash_value {}; - template <> struct basic_numbers : - boost::hash_detail::enable_hash_value {}; - template <> struct basic_numbers : - boost::hash_detail::enable_hash_value {}; - template <> struct basic_numbers : - boost::hash_detail::enable_hash_value {}; - template <> struct basic_numbers : - boost::hash_detail::enable_hash_value {}; - template <> struct basic_numbers : - boost::hash_detail::enable_hash_value {}; - template <> struct basic_numbers : - boost::hash_detail::enable_hash_value {}; - template <> struct basic_numbers : - boost::hash_detail::enable_hash_value {}; - -#if !defined(BOOST_NO_INTRINSIC_WCHAR_T) - template <> struct basic_numbers : - boost::hash_detail::enable_hash_value {}; -#endif -#if !defined(BOOST_NO_CXX11_CHAR16_T) - template <> struct basic_numbers : - boost::hash_detail::enable_hash_value {}; -#endif + template struct hash_integral_impl + { + static std::size_t fn( T v ) + { + typedef typename boost::make_unsigned::type U; -#if !defined(BOOST_NO_CXX11_CHAR32_T) - template <> struct basic_numbers : - boost::hash_detail::enable_hash_value {}; -#endif + if( v >= 0 ) + { + return hash_integral_impl::fn( static_cast( v ) ); + } + else + { + return ~hash_integral_impl::fn( static_cast( ~static_cast( v ) ) ); + } + } + }; - // long_numbers is defined like this to allow for separate - // specialization for long_long and int128_type, in case - // they conflict. - template struct long_numbers2 {}; - template struct ulong_numbers2 {}; - template struct long_numbers : long_numbers2 {}; - template struct ulong_numbers : ulong_numbers2 {}; - -#if !defined(BOOST_NO_LONG_LONG) - template <> struct long_numbers : - boost::hash_detail::enable_hash_value {}; - template <> struct ulong_numbers : - boost::hash_detail::enable_hash_value {}; -#endif + template struct hash_integral_impl + { + static std::size_t fn( T v ) + { + std::size_t seed = 0; -#if defined(BOOST_HAS_INT128) - template <> struct long_numbers2 : - boost::hash_detail::enable_hash_value {}; - template <> struct ulong_numbers2 : - boost::hash_detail::enable_hash_value {}; -#endif + seed = static_cast( v >> 32 ) + hash_detail::hash_mix( seed ); + seed = static_cast( v & 0xFFFFFFFF ) + hash_detail::hash_mix( seed ); - template <> struct float_numbers : - boost::hash_detail::enable_hash_value {}; - template <> struct float_numbers : - boost::hash_detail::enable_hash_value {}; - template <> struct float_numbers : - boost::hash_detail::enable_hash_value {}; - } + return seed; + } + }; - template - typename boost::hash_detail::basic_numbers::type hash_value(T); - template - typename boost::hash_detail::long_numbers::type hash_value(T); - template - typename boost::hash_detail::ulong_numbers::type hash_value(T); + template struct hash_integral_impl + { + static std::size_t fn( T v ) + { + std::size_t seed = 0; - template - typename boost::enable_if, std::size_t>::type - hash_value(T); + seed = static_cast( v >> 96 ) + hash_detail::hash_mix( seed ); + seed = static_cast( v >> 64 ) + hash_detail::hash_mix( seed ); + seed = static_cast( v >> 32 ) + hash_detail::hash_mix( seed ); + seed = static_cast( v ) + hash_detail::hash_mix( seed ); -#if !BOOST_WORKAROUND(__DMC__, <= 0x848) - template std::size_t hash_value(T* const&); -#else - template std::size_t hash_value(T*); -#endif + return seed; + } + }; -#if !defined(BOOST_NO_FUNCTION_TEMPLATE_ORDERING) - template< class T, unsigned N > - std::size_t hash_value(const T (&x)[N]); + template struct hash_integral_impl + { + static std::size_t fn( T v ) + { + std::size_t seed = 0; - template< class T, unsigned N > - std::size_t hash_value(T (&x)[N]); -#endif + seed = static_cast( v >> 64 ) + hash_detail::hash_mix( seed ); + seed = static_cast( v ) + hash_detail::hash_mix( seed ); - template - std::size_t hash_value( - std::basic_string, A> const&); + return seed; + } + }; -#if BOOST_HASH_HAS_STRING_VIEW - template - std::size_t hash_value( - std::basic_string_view > const&); -#endif + } // namespace hash_detail template - typename boost::hash_detail::float_numbers::type hash_value(T); + typename boost::enable_if_::value, std::size_t>::type + hash_value( T v ) + { + return hash_detail::hash_integral_impl::fn( v ); + } + + // enumeration types -#if BOOST_HASH_HAS_OPTIONAL template - std::size_t hash_value(std::optional const&); -#endif + typename boost::enable_if_::value, std::size_t>::type + hash_value( T v ) + { + // This should in principle return the equivalent of + // + // boost::hash_value( to_underlying(v) ); + // + // However, the C++03 implementation of underlying_type, + // + // conditional, make_signed, make_unsigned>::type::type + // + // generates a legitimate -Wconversion warning in is_signed, + // because -1 is not a valid enum value when all the enumerators + // are nonnegative. + // + // So the legacy implementation will have to do for now. + + return static_cast( v ); + } -#if BOOST_HASH_HAS_VARIANT - std::size_t hash_value(std::monostate); - template - std::size_t hash_value(std::variant const&); -#endif + // floating point types -#if !defined(BOOST_NO_CXX11_HDR_TYPEINDEX) - std::size_t hash_value(std::type_index); -#endif + namespace hash_detail + { + template::digits> + struct hash_float_impl; -#if !defined(BOOST_NO_CXX11_HDR_SYSTEM_ERROR) - std::size_t hash_value(std::error_code const&); - std::size_t hash_value(std::error_condition const&); -#endif + // float + template struct hash_float_impl + { + static std::size_t fn( T v ) + { + boost::uint32_t w; + std::memcpy( &w, &v, sizeof( v ) ); - // Implementation + return w; + } + }; - namespace hash_detail - { - template - inline std::size_t hash_value_signed(T val) + // double + template struct hash_float_impl { - const unsigned int size_t_bits = std::numeric_limits::digits; - // ceiling(std::numeric_limits::digits / size_t_bits) - 1 - const int length = (std::numeric_limits::digits - 1) - / static_cast(size_t_bits); - - std::size_t seed = 0; - T positive = val < 0 ? -1 - val : val; - - // Hopefully, this loop can be unrolled. - for(unsigned int i = length * size_t_bits; i > 0; i -= size_t_bits) - { - seed ^= (std::size_t) (positive >> i) + (seed<<6) + (seed>>2); - } - seed ^= (std::size_t) val + (seed<<6) + (seed>>2); - - return seed; - } + static std::size_t fn( T v ) + { + boost::uint64_t w; + std::memcpy( &w, &v, sizeof( v ) ); - template - inline std::size_t hash_value_unsigned(T val) + return hash_value( w ); + } + }; + + // 80 bit long double in 12 bytes + template struct hash_float_impl { - const unsigned int size_t_bits = std::numeric_limits::digits; - // ceiling(std::numeric_limits::digits / size_t_bits) - 1 - const int length = (std::numeric_limits::digits - 1) - / static_cast(size_t_bits); + static std::size_t fn( T v ) + { + boost::uint64_t w[ 2 ] = {}; + std::memcpy( &w, &v, 80 / CHAR_BIT ); - std::size_t seed = 0; + std::size_t seed = 0; - // Hopefully, this loop can be unrolled. - for(unsigned int i = length * size_t_bits; i > 0; i -= size_t_bits) - { - seed ^= (std::size_t) (val >> i) + (seed<<6) + (seed>>2); - } - seed ^= (std::size_t) val + (seed<<6) + (seed>>2); + seed = hash_value( w[0] ) + hash_detail::hash_mix( seed ); + seed = hash_value( w[1] ) + hash_detail::hash_mix( seed ); - return seed; - } + return seed; + } + }; - template - inline void hash_combine_impl(SizeT& seed, SizeT value) + // 80 bit long double in 16 bytes + template struct hash_float_impl { - seed ^= value + 0x9e3779b9 + (seed<<6) + (seed>>2); - } + static std::size_t fn( T v ) + { + boost::uint64_t w[ 2 ] = {}; + std::memcpy( &w, &v, 80 / CHAR_BIT ); - inline void hash_combine_impl(boost::uint32_t& h1, - boost::uint32_t k1) - { - const uint32_t c1 = 0xcc9e2d51; - const uint32_t c2 = 0x1b873593; + std::size_t seed = 0; - k1 *= c1; - k1 = BOOST_FUNCTIONAL_HASH_ROTL32(k1,15); - k1 *= c2; + seed = hash_value( w[0] ) + hash_detail::hash_mix( seed ); + seed = hash_value( w[1] ) + hash_detail::hash_mix( seed ); - h1 ^= k1; - h1 = BOOST_FUNCTIONAL_HASH_ROTL32(h1,13); - h1 = h1*5+0xe6546b64; - } + return seed; + } + }; + // 128 bit long double + template struct hash_float_impl + { + static std::size_t fn( T v ) + { + boost::uint64_t w[ 2 ]; + std::memcpy( &w, &v, sizeof( v ) ); -// Don't define 64-bit hash combine on platforms without 64 bit integers, -// and also not for 32-bit gcc as it warns about the 64-bit constant. -#if !defined(BOOST_NO_INT64_T) && \ - !(defined(__GNUC__) && ULONG_MAX == 0xffffffff) + std::size_t seed = 0; - inline void hash_combine_impl(boost::uint64_t& h, - boost::uint64_t k) - { - const boost::uint64_t m = UINT64_C(0xc6a4a7935bd1e995); - const int r = 47; +#if defined(__FLOAT_WORD_ORDER__) && defined(__ORDER_BIG_ENDIAN__) && __FLOAT_WORD_ORDER__ == __ORDER_BIG_ENDIAN__ - k *= m; - k ^= k >> r; - k *= m; + seed = hash_value( w[1] ) + hash_detail::hash_mix( seed ); + seed = hash_value( w[0] ) + hash_detail::hash_mix( seed ); - h ^= k; - h *= m; +#else - // Completely arbitrary number, to prevent 0's - // from hashing to 0. - h += 0xe6546b64; - } + seed = hash_value( w[0] ) + hash_detail::hash_mix( seed ); + seed = hash_value( w[1] ) + hash_detail::hash_mix( seed ); -#endif // BOOST_NO_INT64_T - } +#endif + return seed; + } + }; - template - typename boost::hash_detail::basic_numbers::type hash_value(T v) - { - return static_cast(v); - } + } // namespace hash_detail template - typename boost::hash_detail::long_numbers::type hash_value(T v) + typename boost::enable_if_::value, std::size_t>::type + hash_value( T v ) { - return hash_detail::hash_value_signed(v); + return boost::hash_detail::hash_float_impl::fn( v + 0 ); } - template - typename boost::hash_detail::ulong_numbers::type hash_value(T v) + // pointer types + + // `x + (x >> 3)` adjustment by Alberto Barbati and Dave Harris. + template std::size_t hash_value( T* const& v ) { - return hash_detail::hash_value_unsigned(v); + boost::uintptr_t x = reinterpret_cast( v ); + return boost::hash_value( x + (x >> 3) ); } - template - typename boost::enable_if, std::size_t>::type - hash_value(T v) + // array types + + template + inline std::size_t hash_value( T const (&x)[ N ] ) { - return static_cast(v); + return boost::hash_range( x, x + N ); } - // Implementation by Alberto Barbati and Dave Harris. -#if !BOOST_WORKAROUND(__DMC__, <= 0x848) - template std::size_t hash_value(T* const& v) -#else - template std::size_t hash_value(T* v) -#endif + template + inline std::size_t hash_value( T (&x)[ N ] ) { -#if defined(__VMS) && __INITIAL_POINTER_SIZE == 64 - // for some reason ptrdiff_t on OpenVMS compiler with - // 64 bit is not 64 bit !!! - std::size_t x = static_cast( - reinterpret_cast(v)); -#else - std::size_t x = static_cast( - reinterpret_cast(v)); -#endif - return x + (x >> 3); + return boost::hash_range( x, x + N ); } -#if defined(BOOST_MSVC) -#pragma warning(push) -#if BOOST_MSVC <= 1400 -#pragma warning(disable:4267) // 'argument' : conversion from 'size_t' to - // 'unsigned int', possible loss of data - // A misguided attempt to detect 64-bit - // incompatability. -#endif -#endif + // complex template - inline void hash_combine(std::size_t& seed, T const& v) + std::size_t hash_value( std::complex const& v ) { - boost::hash hasher; - return boost::hash_detail::hash_combine_impl(seed, hasher(v)); + std::size_t re = boost::hash()( v.real() ); + std::size_t im = boost::hash()( v.imag() ); + + return re + hash_detail::hash_mix( im ); } -#if defined(BOOST_MSVC) -#pragma warning(pop) -#endif + // pair - template - inline std::size_t hash_range(It first, It last) + template + std::size_t hash_value( std::pair const& v ) { std::size_t seed = 0; - for(; first != last; ++first) - { - hash_combine::value_type>(seed, *first); - } + boost::hash_combine( seed, v.first ); + boost::hash_combine( seed, v.second ); return seed; } - template - inline void hash_range(std::size_t& seed, It first, It last) - { - for(; first != last; ++first) - { - hash_combine::value_type>(seed, *first); - } - } + // ranges (list, set, deque...) -#if BOOST_WORKAROUND(BOOST_BORLANDC, BOOST_TESTED_AT(0x551)) - template - inline std::size_t hash_range(T* first, T* last) + template + typename boost::enable_if_::value && !container_hash::is_contiguous_range::value && !container_hash::is_unordered_range::value, std::size_t>::type + hash_value( T const& v ) { - std::size_t seed = 0; + return boost::hash_range( v.begin(), v.end() ); + } - for(; first != last; ++first) - { - boost::hash hasher; - seed ^= hasher(*first) + 0x9e3779b9 + (seed<<6) + (seed>>2); - } + // contiguous ranges (string, vector, array) - return seed; + template + typename boost::enable_if_::value, std::size_t>::type + hash_value( T const& v ) + { + return boost::hash_range( v.data(), v.data() + v.size() ); } - template - inline void hash_range(std::size_t& seed, T* first, T* last) + // unordered ranges (unordered_set, unordered_map) + + template + typename boost::enable_if_::value, std::size_t>::type + hash_value( T const& v ) { - for(; first != last; ++first) - { - boost::hash hasher; - seed ^= hasher(*first) + 0x9e3779b9 + (seed<<6) + (seed>>2); - } + return boost::hash_unordered_range( v.begin(), v.end() ); } -#endif -#if !defined(BOOST_NO_FUNCTION_TEMPLATE_ORDERING) - template< class T, unsigned N > - inline std::size_t hash_value(const T (&x)[N]) +#if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) && ( \ + ( defined(_MSVC_STL_VERSION) && _MSVC_STL_VERSION < 142 ) || \ + ( !defined(_MSVC_STL_VERSION) && defined(_CPPLIB_VER) && _CPPLIB_VER >= 520 ) ) + + // resolve ambiguity with unconstrained stdext::hash_value in :-/ + + template class L, class... T> + typename boost::enable_if_>::value && !container_hash::is_contiguous_range>::value && !container_hash::is_unordered_range>::value, std::size_t>::type + hash_value( L const& v ) { - return hash_range(x, x + N); + return boost::hash_range( v.begin(), v.end() ); } - template< class T, unsigned N > - inline std::size_t hash_value(T (&x)[N]) + // contiguous ranges (string, vector, array) + + template class L, class... T> + typename boost::enable_if_>::value, std::size_t>::type + hash_value( L const& v ) { - return hash_range(x, x + N); + return boost::hash_range( v.data(), v.data() + v.size() ); } -#endif - template - inline std::size_t hash_value( - std::basic_string, A> const& v) + template class L, class T, std::size_t N> + typename boost::enable_if_>::value, std::size_t>::type + hash_value( L const& v ) { - return hash_range(v.begin(), v.end()); + return boost::hash_range( v.data(), v.data() + v.size() ); } -#if BOOST_HASH_HAS_STRING_VIEW - template - inline std::size_t hash_value( - std::basic_string_view > const& v) + // unordered ranges (unordered_set, unordered_map) + + template class L, class... T> + typename boost::enable_if_>::value, std::size_t>::type + hash_value( L const& v ) { - return hash_range(v.begin(), v.end()); + return boost::hash_unordered_range( v.begin(), v.end() ); } + +#endif + + // described classes + +#if defined(BOOST_DESCRIBE_CXX14) + +#if defined(_MSC_VER) && _MSC_VER == 1900 +# pragma warning(push) +# pragma warning(disable: 4100) // unreferenced formal parameter #endif template - typename boost::hash_detail::float_numbers::type hash_value(T v) + typename boost::enable_if_::value, std::size_t>::type + hash_value( T const& v ) { - return boost::hash_detail::float_hash_value(v); - } + static_assert( !boost::is_union::value, "described unions are not supported" ); -#if BOOST_HASH_HAS_OPTIONAL - template - inline std::size_t hash_value(std::optional const& v) { - if (!v) { - // Arbitray value for empty optional. - return 0x12345678; - } else { - boost::hash hf; - return hf(*v); - } + std::size_t r = 0; + + using Bd = describe::describe_bases; + + mp11::mp_for_each([&](auto D){ + + using B = typename decltype(D)::type; + boost::hash_combine( r, (B const&)v ); + + }); + + using Md = describe::describe_members; + + mp11::mp_for_each([&](auto D){ + + boost::hash_combine( r, v.*D.pointer ); + + }); + + return r; } + +#if defined(_MSC_VER) && _MSC_VER == 1900 +# pragma warning(pop) #endif -#if BOOST_HASH_HAS_VARIANT - inline std::size_t hash_value(std::monostate) { - return 0x87654321; +#endif + + // std::unique_ptr, std::shared_ptr + +#if !defined(BOOST_NO_CXX11_SMART_PTR) + + template + std::size_t hash_value( std::shared_ptr const& x ) + { + return boost::hash_value( x.get() ); } - template - inline std::size_t hash_value(std::variant const& v) { - std::size_t seed = 0; - hash_combine(seed, v.index()); - std::visit([&seed](auto&& x) { hash_combine(seed, x); }, v); - return seed; + template + std::size_t hash_value( std::unique_ptr const& x ) + { + return boost::hash_value( x.get() ); } + #endif + // std::type_index #if !defined(BOOST_NO_CXX11_HDR_TYPEINDEX) - inline std::size_t hash_value(std::type_index v) + + inline std::size_t hash_value( std::type_index const& v ) { return v.hash_code(); } + #endif + // std::error_code, std::error_condition + #if !defined(BOOST_NO_CXX11_HDR_SYSTEM_ERROR) - inline std::size_t hash_value(std::error_code const& v) { + + inline std::size_t hash_value( std::error_code const& v ) + { std::size_t seed = 0; - hash_combine(seed, v.value()); - hash_combine(seed, &v.category()); + + boost::hash_combine( seed, v.value() ); + boost::hash_combine( seed, &v.category() ); + + return seed; + } + + inline std::size_t hash_value( std::error_condition const& v ) + { + std::size_t seed = 0; + + boost::hash_combine( seed, v.value() ); + boost::hash_combine( seed, &v.category() ); + return seed; } - inline std::size_t hash_value(std::error_condition const& v) { +#endif + + // std::nullptr_t + +#if !defined(BOOST_NO_CXX11_NULLPTR) + + template + typename boost::enable_if_::value, std::size_t>::type + hash_value( T const& /*v*/ ) + { + return boost::hash_value( static_cast( nullptr ) ); + } + +#endif + + // std::optional + +#if !defined(BOOST_NO_CXX17_HDR_OPTIONAL) + + template + std::size_t hash_value( std::optional const& v ) + { + if( !v ) + { + // Arbitray value for empty optional. + return 0x12345678; + } + else + { + return boost::hash()(*v); + } + } + +#endif + + // std::variant + +#if !defined(BOOST_NO_CXX17_HDR_VARIANT) + + inline std::size_t hash_value( std::monostate ) + { + return 0x87654321; + } + + template + std::size_t hash_value( std::variant const& v ) + { std::size_t seed = 0; - hash_combine(seed, v.value()); - hash_combine(seed, &v.category()); + + hash_combine( seed, v.index() ); + std::visit( [&seed](auto&& x) { hash_combine(seed, x); }, v ); + return seed; } + #endif // - // boost::hash + // boost::hash_combine // - // Define the specializations required by the standard. The general purpose - // boost::hash is defined later in extensions.hpp if - // BOOST_HASH_NO_EXTENSIONS is not defined. + template + inline void hash_combine( std::size_t& seed, T const& v ) + { + seed = boost::hash_detail::hash_mix( seed + 0x9e3779b9 + boost::hash()( v ) ); + } - // BOOST_HASH_SPECIALIZE - define a specialization for a type which is - // passed by copy. // - // BOOST_HASH_SPECIALIZE_REF - define a specialization for a type which is - // passed by const reference. + // boost::hash_range // - // These are undefined later. - -#define BOOST_HASH_SPECIALIZE(type) \ - template <> struct hash \ - : public boost::hash_detail::hash_base \ - { \ - std::size_t operator()(type v) const \ - { \ - return boost::hash_value(v); \ - } \ - }; -#define BOOST_HASH_SPECIALIZE_REF(type) \ - template <> struct hash \ - : public boost::hash_detail::hash_base \ - { \ - std::size_t operator()(type const& v) const \ - { \ - return boost::hash_value(v); \ - } \ - }; + template + inline void hash_range( std::size_t& seed, It first, It last ) + { + seed = hash_detail::hash_range( seed, first, last ); + } -#define BOOST_HASH_SPECIALIZE_TEMPLATE_REF(type) \ - struct hash \ - : public boost::hash_detail::hash_base \ - { \ - std::size_t operator()(type const& v) const \ - { \ - return boost::hash_value(v); \ - } \ - }; + template + inline std::size_t hash_range( It first, It last ) + { + std::size_t seed = 0; - BOOST_HASH_SPECIALIZE(bool) - BOOST_HASH_SPECIALIZE(char) - BOOST_HASH_SPECIALIZE(signed char) - BOOST_HASH_SPECIALIZE(unsigned char) -#if !defined(BOOST_NO_INTRINSIC_WCHAR_T) - BOOST_HASH_SPECIALIZE(wchar_t) -#endif -#if !defined(BOOST_NO_CXX11_CHAR16_T) - BOOST_HASH_SPECIALIZE(char16_t) -#endif -#if !defined(BOOST_NO_CXX11_CHAR32_T) - BOOST_HASH_SPECIALIZE(char32_t) -#endif - BOOST_HASH_SPECIALIZE(short) - BOOST_HASH_SPECIALIZE(unsigned short) - BOOST_HASH_SPECIALIZE(int) - BOOST_HASH_SPECIALIZE(unsigned int) - BOOST_HASH_SPECIALIZE(long) - BOOST_HASH_SPECIALIZE(unsigned long) - - BOOST_HASH_SPECIALIZE(float) - BOOST_HASH_SPECIALIZE(double) - BOOST_HASH_SPECIALIZE(long double) - - BOOST_HASH_SPECIALIZE_REF(std::string) -#if !defined(BOOST_NO_STD_WSTRING) && !defined(BOOST_NO_INTRINSIC_WCHAR_T) - BOOST_HASH_SPECIALIZE_REF(std::wstring) -#endif -#if !defined(BOOST_NO_CXX11_CHAR16_T) - BOOST_HASH_SPECIALIZE_REF(std::basic_string) -#endif -#if !defined(BOOST_NO_CXX11_CHAR32_T) - BOOST_HASH_SPECIALIZE_REF(std::basic_string) -#endif + hash_range( seed, first, last ); -#if BOOST_HASH_HAS_STRING_VIEW - BOOST_HASH_SPECIALIZE_REF(std::string_view) -# if !defined(BOOST_NO_STD_WSTRING) && !defined(BOOST_NO_INTRINSIC_WCHAR_T) - BOOST_HASH_SPECIALIZE_REF(std::wstring_view) -# endif -# if !defined(BOOST_NO_CXX11_CHAR16_T) - BOOST_HASH_SPECIALIZE_REF(std::basic_string_view) -# endif -# if !defined(BOOST_NO_CXX11_CHAR32_T) - BOOST_HASH_SPECIALIZE_REF(std::basic_string_view) -# endif -#endif + return seed; + } -#if !defined(BOOST_NO_LONG_LONG) - BOOST_HASH_SPECIALIZE(boost::long_long_type) - BOOST_HASH_SPECIALIZE(boost::ulong_long_type) -#endif + // + // boost::hash_unordered_range + // -#if defined(BOOST_HAS_INT128) - BOOST_HASH_SPECIALIZE(boost::int128_type) - BOOST_HASH_SPECIALIZE(boost::uint128_type) -#endif + template + inline void hash_unordered_range( std::size_t& seed, It first, It last ) + { + std::size_t r = 0; + std::size_t const s2( seed ); -#if BOOST_HASH_HAS_OPTIONAL - template - BOOST_HASH_SPECIALIZE_TEMPLATE_REF(std::optional) -#endif + for( ; first != last; ++first ) + { + std::size_t s3( s2 ); -#if !defined(BOOST_HASH_HAS_VARIANT) - template - BOOST_HASH_SPECIALIZE_TEMPLATE_REF(std::variant) - BOOST_HASH_SPECIALIZE(std::monostate) -#endif + hash_combine::value_type>( s3, *first ); -#if !defined(BOOST_NO_CXX11_HDR_TYPEINDEX) - BOOST_HASH_SPECIALIZE(std::type_index) -#endif + r += s3; + } -#undef BOOST_HASH_SPECIALIZE -#undef BOOST_HASH_SPECIALIZE_REF -#undef BOOST_HASH_SPECIALIZE_TEMPLATE_REF + seed += r; + } -// Specializing boost::hash for pointers. + template + inline std::size_t hash_unordered_range( It first, It last ) + { + std::size_t seed = 0; -#if !defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION) + hash_unordered_range( seed, first, last ); - template - struct hash - : public boost::hash_detail::hash_base + return seed; + } + + // + // boost::hash + // + + template struct hash { - std::size_t operator()(T* v) const - { -#if !BOOST_WORKAROUND(__SUNPRO_CC, <= 0x590) - return boost::hash_value(v); -#else - std::size_t x = static_cast( - reinterpret_cast(v)); + typedef T argument_type; + typedef std::size_t result_type; - return x + (x >> 3); -#endif + std::size_t operator()( T const& val ) const + { + return hash_value( val ); } }; -#else +#if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) && ( \ + ( defined(_MSVC_STL_VERSION) && _MSVC_STL_VERSION < 142 ) || \ + ( !defined(_MSVC_STL_VERSION) && defined(_CPPLIB_VER) && _CPPLIB_VER >= 520 ) ) - // For compilers without partial specialization, we define a - // boost::hash for all remaining types. But hash_impl is only defined - // for pointers in 'extensions.hpp' - so when BOOST_HASH_NO_EXTENSIONS - // is defined there will still be a compile error for types not supported - // in the standard. + // Dinkumware has stdext::hash_value for basic_string in :-/ - namespace hash_detail + template struct hash< std::basic_string > { - template - struct hash_impl; + typedef std::basic_string argument_type; + typedef std::size_t result_type; - template <> - struct hash_impl + std::size_t operator()( std::basic_string const& val ) const { - template - struct inner - : public boost::hash_detail::hash_base - { - std::size_t operator()(T val) const - { -#if !BOOST_WORKAROUND(__SUNPRO_CC, <= 590) - return boost::hash_value(val); -#else - std::size_t x = static_cast( - reinterpret_cast(val)); + return boost::hash_value( val ); + } + }; - return x + (x >> 3); #endif - } - }; - }; - } - template struct hash - : public boost::hash_detail::hash_impl::value> - ::BOOST_NESTED_TEMPLATE inner + // boost::unordered::hash_is_avalanching + + namespace unordered { - }; + template struct hash_is_avalanching; + template struct hash_is_avalanching< boost::hash< std::basic_string > >: boost::is_integral {}; + // boost::is_integral is false, but should be true (https://github.com/boostorg/type_traits/issues/175) +#if defined(__cpp_char8_t) && __cpp_char8_t >= 201811L + template<> struct hash_is_avalanching< boost::hash< std::basic_string > >: boost::true_type {}; #endif -} -#undef BOOST_HASH_CHAR_TRAITS -#undef BOOST_FUNCTIONAL_HASH_ROTL32 +#if !defined(BOOST_NO_CXX17_HDR_STRING_VIEW) + + template struct hash_is_avalanching< boost::hash< std::basic_string_view > >: boost::is_integral {}; -#if defined(BOOST_MSVC) -#pragma warning(pop) +#if defined(__cpp_char8_t) && __cpp_char8_t >= 201811L + template<> struct hash_is_avalanching< boost::hash< std::basic_string_view > >: boost::true_type {}; #endif -#endif // BOOST_FUNCTIONAL_HASH_HASH_HPP +#endif + } // namespace unordered -// Include this outside of the include guards in case the file is included -// twice - once with BOOST_HASH_NO_EXTENSIONS defined, and then with it -// undefined. +} // namespace boost -#if !defined(BOOST_HASH_NO_EXTENSIONS) \ - && !defined(BOOST_FUNCTIONAL_HASH_EXTENSIONS_HPP) -#include -#endif +#endif // #ifndef BOOST_FUNCTIONAL_HASH_HASH_HPP diff --git a/include/boost/container_hash/hash_fwd.hpp b/include/boost/container_hash/hash_fwd.hpp index 46340b3f4..32388ac54 100644 --- a/include/boost/container_hash/hash_fwd.hpp +++ b/include/boost/container_hash/hash_fwd.hpp @@ -1,36 +1,37 @@ - // Copyright 2005-2009 Daniel James. -// 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) - -// Based on Peter Dimov's proposal -// http://www.open-std.org/JTC1/SC22/WG21/docs/papers/2005/n1756.pdf -// issue 6.18. +// Copyright 2021, 2022 Peter Dimov. +// Distributed under the Boost Software License, Version 1.0. +// https://www.boost.org/LICENSE_1_0.txt -#if !defined(BOOST_FUNCTIONAL_HASH_FWD_HPP) +#ifndef BOOST_FUNCTIONAL_HASH_FWD_HPP #define BOOST_FUNCTIONAL_HASH_FWD_HPP -#include #include -#if defined(BOOST_HAS_PRAGMA_ONCE) -#pragma once -#endif - - namespace boost { - template struct hash; - template void hash_combine(std::size_t& seed, T const& v); +namespace container_hash +{ + +template struct is_range; +template struct is_contiguous_range; +template struct is_unordered_range; +template struct is_described_class; +template struct is_tuple_like; + +} // namespace container_hash + +template struct hash; + +template void hash_combine( std::size_t& seed, T const& v ); + +template void hash_range( std::size_t&, It, It ); +template std::size_t hash_range( It, It ); - template std::size_t hash_range(It, It); - template void hash_range(std::size_t&, It, It); +template void hash_unordered_range( std::size_t&, It, It ); +template std::size_t hash_unordered_range( It, It ); -#if BOOST_WORKAROUND(BOOST_BORLANDC, BOOST_TESTED_AT(0x551)) - template inline std::size_t hash_range(T*, T*); - template inline void hash_range(std::size_t&, T*, T*); -#endif -} +} // namespace boost -#endif +#endif // #ifndef BOOST_FUNCTIONAL_HASH_FWD_HPP diff --git a/include/boost/container_hash/is_contiguous_range.hpp b/include/boost/container_hash/is_contiguous_range.hpp new file mode 100644 index 000000000..96043ccd5 --- /dev/null +++ b/include/boost/container_hash/is_contiguous_range.hpp @@ -0,0 +1,92 @@ +// Copyright 2017, 2018 Peter Dimov. +// Distributed under the Boost Software License, Version 1.0. +// https://www.boost.org/LICENSE_1_0.txt + +#ifndef BOOST_HASH_IS_CONTIGUOUS_RANGE_HPP_INCLUDED +#define BOOST_HASH_IS_CONTIGUOUS_RANGE_HPP_INCLUDED + +#include +#include +#include +#include +#include + +#if !defined(BOOST_NO_CXX11_DECLTYPE) && !defined(BOOST_NO_SFINAE_EXPR) && !BOOST_WORKAROUND(BOOST_GCC, < 40700) && !BOOST_WORKAROUND(BOOST_MSVC, < 1910) + +#include +#include +#include +#include + +namespace boost +{ +namespace hash_detail +{ + +template + integral_constant< bool, is_same::value_type, T>::value && is_integral::value > + is_contiguous_range_check( It first, It last, T const*, T const*, S ); + +template decltype( is_contiguous_range_check( declval().begin(), declval().end(), declval().data(), declval().data() + declval().size(), declval().size() ) ) is_contiguous_range_( int ); +template false_type is_contiguous_range_( ... ); + +template struct is_contiguous_range: decltype( hash_detail::is_contiguous_range_( 0 ) ) +{ +}; + +} // namespace hash_detail + +namespace container_hash +{ + +template struct is_contiguous_range: integral_constant< bool, is_range::value && hash_detail::is_contiguous_range::value > +{ +}; + +} // namespace container_hash +} // namespace boost + +#else // !defined(BOOST_NO_CXX11_DECLTYPE) && !defined(BOOST_NO_SFINAE_EXPR) + +#include +#include +#include +#if !defined(BOOST_NO_CXX11_HDR_ARRAY) +#include +#endif + +namespace boost +{ +namespace container_hash +{ + +template struct is_contiguous_range: false_type +{ +}; + +template struct is_contiguous_range< std::basic_string >: true_type +{ +}; + +template struct is_contiguous_range< std::basic_string const >: true_type +{ +}; + +#if !defined(BOOST_NO_CXX11_HDR_ARRAY) + +template struct is_contiguous_range< std::array >: true_type +{ +}; + +template struct is_contiguous_range< std::array const >: true_type +{ +}; + +#endif + +} // namespace container_hash +} // namespace boost + +#endif // !defined(BOOST_NO_CXX11_DECLTYPE) && !defined(BOOST_NO_SFINAE_EXPR) + +#endif // #ifndef BOOST_HASH_IS_CONTIGUOUS_RANGE_HPP_INCLUDED diff --git a/include/boost/container_hash/is_described_class.hpp b/include/boost/container_hash/is_described_class.hpp new file mode 100644 index 000000000..cd2e1db4d --- /dev/null +++ b/include/boost/container_hash/is_described_class.hpp @@ -0,0 +1,38 @@ +// Copyright 2022 Peter Dimov. +// Distributed under the Boost Software License, Version 1.0. +// https://www.boost.org/LICENSE_1_0.txt + +#ifndef BOOST_HASH_IS_DESCRIBED_CLASS_HPP_INCLUDED +#define BOOST_HASH_IS_DESCRIBED_CLASS_HPP_INCLUDED + +#include +#include +#include +#include + +namespace boost +{ +namespace container_hash +{ + +#if defined(BOOST_DESCRIBE_CXX11) + +template struct is_described_class: boost::integral_constant::value && + describe::has_describe_members::value && + !boost::is_union::value> +{ +}; + +#else + +template struct is_described_class: boost::false_type +{ +}; + +#endif + +} // namespace container_hash +} // namespace boost + +#endif // #ifndef BOOST_HASH_IS_DESCRIBED_CLASS_HPP_INCLUDED diff --git a/include/boost/container_hash/is_range.hpp b/include/boost/container_hash/is_range.hpp new file mode 100644 index 000000000..2d3746cd2 --- /dev/null +++ b/include/boost/container_hash/is_range.hpp @@ -0,0 +1,74 @@ +// Copyright 2017 Peter Dimov. +// Distributed under the Boost Software License, Version 1.0. +// https://www.boost.org/LICENSE_1_0.txt + +#ifndef BOOST_HASH_IS_RANGE_HPP_INCLUDED +#define BOOST_HASH_IS_RANGE_HPP_INCLUDED + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +namespace boost +{ +#if !defined(BOOST_NO_CXX11_DECLTYPE) && !defined(BOOST_NO_SFINAE_EXPR) && !BOOST_WORKAROUND(BOOST_GCC, < 40700) + +namespace hash_detail +{ + +template + integral_constant< bool, !is_same::type, typename std::iterator_traits::value_type>::value > + is_range_check( It first, It last ); + +template decltype( is_range_check( declval().begin(), declval().end() ) ) is_range_( int ); +template false_type is_range_( ... ); + +} // namespace hash_detail + +namespace container_hash +{ + +template struct is_range: decltype( hash_detail::is_range_( 0 ) ) +{ +}; + +} // namespace container_hash + +#else + +namespace hash_detail +{ + +template struct is_range_: false_type +{ +}; + +template struct is_range_< T, integral_constant< bool, + is_same::value_type>::value && + is_integral::value + > >: true_type +{ +}; + +} // namespace hash_detail + +namespace container_hash +{ + +template struct is_range: hash_detail::is_range_ +{ +}; + +} // namespace container_hash + +#endif // !defined(BOOST_NO_CXX11_DECLTYPE) && !defined(BOOST_NO_SFINAE_EXPR) + +} // namespace boost + +#endif // #ifndef BOOST_HASH_IS_RANGE_HPP_INCLUDED diff --git a/include/boost/container_hash/is_tuple_like.hpp b/include/boost/container_hash/is_tuple_like.hpp new file mode 100644 index 000000000..8f57364e2 --- /dev/null +++ b/include/boost/container_hash/is_tuple_like.hpp @@ -0,0 +1,42 @@ +#ifndef BOOST_HASH_IS_TUPLE_LIKE_HPP_INCLUDED +#define BOOST_HASH_IS_TUPLE_LIKE_HPP_INCLUDED + +// Copyright 2017, 2022 Peter Dimov. +// Distributed under the Boost Software License, Version 1.0. +// https://www.boost.org/LICENSE_1_0.txt + +#include +#include +#include +#include + +namespace boost +{ +namespace hash_detail +{ + +template struct is_tuple_like_: false_type +{ +}; + +#if !defined(BOOST_NO_CXX11_HDR_TUPLE) && !BOOST_WORKAROUND(BOOST_MSVC, <= 1800) + +template struct is_tuple_like_::value == std::tuple_size::value> >: true_type +{ +}; + +#endif + +} // namespace hash_detail + +namespace container_hash +{ + +template struct is_tuple_like: hash_detail::is_tuple_like_ +{ +}; + +} // namespace container_hash +} // namespace boost + +#endif // #ifndef BOOST_HASH_IS_TUPLE_LIKE_HPP_INCLUDED diff --git a/include/boost/container_hash/is_unordered_range.hpp b/include/boost/container_hash/is_unordered_range.hpp new file mode 100644 index 000000000..11ee386cd --- /dev/null +++ b/include/boost/container_hash/is_unordered_range.hpp @@ -0,0 +1,39 @@ +// Copyright 2017 Peter Dimov. +// Distributed under the Boost Software License, Version 1.0. +// https://www.boost.org/LICENSE_1_0.txt + +#ifndef BOOST_HASH_IS_UNORDERED_RANGE_HPP_INCLUDED +#define BOOST_HASH_IS_UNORDERED_RANGE_HPP_INCLUDED + +#include +#include +#include + +namespace boost +{ +namespace hash_detail +{ + +template struct has_hasher_: false_type +{ +}; + +template struct has_hasher_< T, integral_constant< bool, + is_same::value + > >: true_type +{ +}; + +} // namespace hash_detail + +namespace container_hash +{ + +template struct is_unordered_range: integral_constant< bool, is_range::value && hash_detail::has_hasher_::value > +{ +}; + +} // namespace container_hash +} // namespace boost + +#endif // #ifndef BOOST_HASH_IS_UNORDERED_RANGE_HPP_INCLUDED diff --git a/include/boost/core/allocator_access.hpp b/include/boost/core/allocator_access.hpp new file mode 100644 index 000000000..8e33ebb04 --- /dev/null +++ b/include/boost/core/allocator_access.hpp @@ -0,0 +1,820 @@ +/* +Copyright 2020-2022 Glen Joseph Fernandes +(glenjofe@gmail.com) + +Distributed under the Boost Software License, Version 1.0. +(http://www.boost.org/LICENSE_1_0.txt) +*/ +#ifndef BOOST_CORE_ALLOCATOR_ACCESS_HPP +#define BOOST_CORE_ALLOCATOR_ACCESS_HPP + +#include +#include +#include +#include +#if !defined(BOOST_NO_CXX11_ALLOCATOR) +#include +#endif +#if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES) +#include +#endif + +#if defined(BOOST_GCC_VERSION) && (BOOST_GCC_VERSION >= 40300) +#define BOOST_DETAIL_ALLOC_EMPTY(T) __is_empty(T) +#elif defined(BOOST_INTEL) && defined(_MSC_VER) && (_MSC_VER >= 1500) +#define BOOST_DETAIL_ALLOC_EMPTY(T) __is_empty(T) +#elif defined(BOOST_MSVC) && (BOOST_MSVC >= 1400) +#define BOOST_DETAIL_ALLOC_EMPTY(T) __is_empty(T) +#elif defined(BOOST_CLANG) && !defined(__CUDACC__) +#if __has_feature(is_empty) +#define BOOST_DETAIL_ALLOC_EMPTY(T) __is_empty(T) +#endif +#elif defined(__SUNPRO_CC) && (__SUNPRO_CC >= 0x5130) +#define BOOST_DETAIL_ALLOC_EMPTY(T) __oracle_is_empty(T) +#elif defined(__ghs__) && (__GHS_VERSION_NUMBER >= 600) +#define BOOST_DETAIL_ALLOC_EMPTY(T) __is_empty(T) +#elif defined(BOOST_CODEGEARC) +#define BOOST_DETAIL_ALLOC_EMPTY(T) __is_empty(T) +#endif + +#if defined(_LIBCPP_SUPPRESS_DEPRECATED_PUSH) +_LIBCPP_SUPPRESS_DEPRECATED_PUSH +#endif +#if defined(_STL_DISABLE_DEPRECATED_WARNING) +_STL_DISABLE_DEPRECATED_WARNING +#endif +#if defined(_MSC_VER) +#pragma warning(push) +#pragma warning(disable:4996) +#endif + +namespace boost { + +template +struct allocator_value_type { + typedef typename A::value_type type; +}; + +namespace detail { + +template +struct alloc_ptr { + typedef typename boost::allocator_value_type::type* type; +}; + +template +struct alloc_void { + typedef void type; +}; + +template +struct alloc_ptr::type> { + typedef typename A::pointer type; +}; + +} /* detail */ + +template +struct allocator_pointer { + typedef typename detail::alloc_ptr::type type; +}; + +namespace detail { + +template +struct alloc_const_ptr { + typedef typename boost::pointer_traits::type>::template rebind_to::type>::type type; +}; + +template +struct alloc_const_ptr::type> { + typedef typename A::const_pointer type; +}; + +} /* detail */ + +template +struct allocator_const_pointer { + typedef typename detail::alloc_const_ptr::type type; +}; + +namespace detail { + +template +struct alloc_to { }; + +#if defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) +template class A, class T, class U> +struct alloc_to, T> { + typedef A type; +}; + +template class A, class T, class U, class V> +struct alloc_to, T> { + typedef A type; +}; + +template class A, class T, class U, class V1, + class V2> +struct alloc_to, T> { + typedef A type; +}; +#else +template class A, class T, class U, class... V> +struct alloc_to, T> { + typedef A type; +}; +#endif + +template +struct alloc_rebind { + typedef typename alloc_to::type type; +}; + +template +struct alloc_rebind::other>::type> { + typedef typename A::template rebind::other type; +}; + +} /* detail */ + +template +struct allocator_rebind { + typedef typename detail::alloc_rebind::type type; +}; + +namespace detail { + +template +struct alloc_void_ptr { + typedef typename boost::pointer_traits::type>::template + rebind_to::type type; +}; + +template +struct alloc_void_ptr::type> { + typedef typename A::void_pointer type; +}; + +} /* detail */ + +template +struct allocator_void_pointer { + typedef typename detail::alloc_void_ptr::type type; +}; + +namespace detail { + +template +struct alloc_const_void_ptr { + typedef typename boost::pointer_traits::type>::template + rebind_to::type type; +}; + +template +struct alloc_const_void_ptr::type> { + typedef typename A::const_void_pointer type; +}; + +} /* detail */ + +template +struct allocator_const_void_pointer { + typedef typename detail::alloc_const_void_ptr::type type; +}; + +namespace detail { + +template +struct alloc_diff_type { + typedef typename boost::pointer_traits::type>::difference_type type; +}; + +template +struct alloc_diff_type::type> { + typedef typename A::difference_type type; +}; + +} /* detail */ + +template +struct allocator_difference_type { + typedef typename detail::alloc_diff_type::type type; +}; + +namespace detail { + +#if defined(BOOST_NO_CXX11_ALLOCATOR) +template +struct alloc_size_type { + typedef std::size_t type; +}; +#else +template +struct alloc_size_type { + typedef typename std::make_unsigned::type>::type type; +}; +#endif + +template +struct alloc_size_type::type> { + typedef typename A::size_type type; +}; + +} /* detail */ + +template +struct allocator_size_type { + typedef typename detail::alloc_size_type::type type; +}; + +namespace detail { + +#if defined(BOOST_NO_CXX11_ALLOCATOR) +template +struct alloc_bool { + typedef bool value_type; + typedef alloc_bool type; + + static const bool value = V; + + operator bool() const BOOST_NOEXCEPT { + return V; + } + + bool operator()() const BOOST_NOEXCEPT { + return V; + } +}; + +template +const bool alloc_bool::value; + +typedef alloc_bool alloc_false; +#else +typedef std::false_type alloc_false; +#endif + +template +struct alloc_pocca { + typedef alloc_false type; +}; + +template +struct alloc_pocca::type> { + typedef typename A::propagate_on_container_copy_assignment type; +}; + +} /* detail */ + +template +struct allocator_propagate_on_container_copy_assignment { + typedef typename detail::alloc_pocca::type type; +}; + +namespace detail { + +template +struct alloc_pocma { + typedef alloc_false type; +}; + +template +struct alloc_pocma::type> { + typedef typename A::propagate_on_container_move_assignment type; +}; + +} /* detail */ + +template +struct allocator_propagate_on_container_move_assignment { + typedef typename detail::alloc_pocma::type type; +}; + +namespace detail { + +template +struct alloc_pocs { + typedef alloc_false type; +}; + +template +struct alloc_pocs::type> { + typedef typename A::propagate_on_container_swap type; +}; + +} /* detail */ + +template +struct allocator_propagate_on_container_swap { + typedef typename detail::alloc_pocs::type type; +}; + +namespace detail { + +#if !defined(BOOST_NO_CXX11_ALLOCATOR) +template +struct alloc_equal { + typedef typename std::is_empty::type type; +}; +#elif defined(BOOST_DETAIL_ALLOC_EMPTY) +template +struct alloc_equal { + typedef alloc_bool type; +}; +#else +template +struct alloc_equal { + typedef alloc_false type; +}; +#endif + +template +struct alloc_equal::type> { + typedef typename A::is_always_equal type; +}; + +} /* detail */ + +template +struct allocator_is_always_equal { + typedef typename detail::alloc_equal::type type; +}; + +template +inline typename allocator_pointer::type +allocator_allocate(A& a, typename allocator_size_type::type n) +{ + return a.allocate(n); +} + +template +inline void +allocator_deallocate(A& a, typename allocator_pointer::type p, + typename allocator_size_type::type n) +{ + a.deallocate(p, n); +} + +#if defined(BOOST_NO_CXX11_ALLOCATOR) +template +inline typename allocator_pointer::type +allocator_allocate(A& a, typename allocator_size_type::type n, + typename allocator_const_void_pointer::type h) +{ + return a.allocate(n, h); +} +#else +namespace detail { + +template +struct alloc_no { + char x, y; +}; + +template +class alloc_has_allocate { + template + static auto check(int) + -> alloc_no().allocate(std::declval::type>(), std::declval::type>()))>; + + template + static char check(long); + +public: + BOOST_STATIC_CONSTEXPR bool value = sizeof(check(0)) > 1; +}; + +} /* detail */ + +template +inline typename std::enable_if::value, + typename allocator_pointer::type>::type +allocator_allocate(A& a, typename allocator_size_type::type n, + typename allocator_const_void_pointer::type h) +{ + return a.allocate(n, h); +} + +template +inline typename std::enable_if::value, + typename allocator_pointer::type>::type +allocator_allocate(A& a, typename allocator_size_type::type n, + typename allocator_const_void_pointer::type) +{ + return a.allocate(n); +} +#endif + +namespace detail { + +#if defined(BOOST_NO_CXX11_ALLOCATOR) +template +struct alloc_has_construct { + BOOST_STATIC_CONSTEXPR bool value = false; +}; + +template +struct alloc_has_construct::type> { + BOOST_STATIC_CONSTEXPR bool value = true; +}; +#else +template +class alloc_has_construct { + template + static auto check(int) + -> alloc_no().construct(std::declval(), + std::declval()...))>; + + template + static char check(long); + +public: + BOOST_STATIC_CONSTEXPR bool value = sizeof(check(0)) > 1; +}; +#endif + +template +struct alloc_if { }; + +template +struct alloc_if { + typedef T type; +}; + +} /* detail */ + +#if defined(BOOST_NO_CXX11_ALLOCATOR) +template +inline typename detail::alloc_if::value>::type +allocator_construct(A& a, T* p) +{ + a.construct(p); +} + +template +inline typename detail::alloc_if::value>::type +allocator_construct(A&, T* p) +{ + ::new((void*)p) T(); +} + +#if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES) +#if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) +template +inline void +allocator_construct(A&, T* p, V&& v, Args&&... args) +{ + ::new((void*)p) T(std::forward(v), std::forward(args)...); +} +#else +template +inline void +allocator_construct(A&, T* p, V&& v) +{ + ::new((void*)p) T(std::forward(v)); +} +#endif +#else +template +inline void +allocator_construct(A&, T* p, const V& v) +{ + ::new((void*)p) T(v); +} + +template +inline void +allocator_construct(A&, T* p, V& v) +{ + ::new((void*)p) T(v); +} +#endif +#else +template +inline typename std::enable_if::value>::type +allocator_construct(A& a, T* p, Args&&... args) +{ + a.construct(p, std::forward(args)...); +} + +template +inline typename std::enable_if::value>::type +allocator_construct(A&, T* p, Args&&... args) +{ + ::new((void*)p) T(std::forward(args)...); +} +#endif + +namespace detail { + +#if defined(BOOST_NO_CXX11_ALLOCATOR) +template +struct alloc_has_destroy { + BOOST_STATIC_CONSTEXPR bool value = false; +}; + +template +struct alloc_has_destroy::type> { + BOOST_STATIC_CONSTEXPR bool value = true; +}; +#else +template +class alloc_has_destroy { + template + static auto check(int) + -> alloc_no().destroy(std::declval()))>; + + template + static char check(long); + +public: + BOOST_STATIC_CONSTEXPR bool value = sizeof(check(0)) > 1; +}; +#endif + +} /* detail */ + +template +inline typename detail::alloc_if::value>::type +allocator_destroy(A& a, T* p) +{ + a.destroy(p); +} + +template +inline typename detail::alloc_if::value>::type +allocator_destroy(A&, T* p) +{ + p->~T(); + (void)p; +} + +namespace detail { + +#if defined(BOOST_NO_CXX11_ALLOCATOR) +template +struct alloc_no { + char x, y; +}; + +template +class alloc_has_max_size { + template + static alloc_no::type(O::*)(), + &O::max_size> check(int); + + template + static alloc_no::type(O::*)() const, + &O::max_size> check(int); + + template + static alloc_no::type(*)(), + &O::max_size> check(int); + + template + static char check(long); + +public: + BOOST_STATIC_CONSTEXPR bool value = sizeof(check(0)) > 1; +}; +#else +template +class alloc_has_max_size { + template + static auto check(int) + -> alloc_no().max_size())>; + + template + static char check(long); + +public: + BOOST_STATIC_CONSTEXPR bool value = sizeof(check(0)) > 1; +}; +#endif + +} /* detail */ + +template +inline typename detail::alloc_if::value, + typename allocator_size_type::type>::type +allocator_max_size(const A& a) BOOST_NOEXCEPT +{ + return a.max_size(); +} + +template +inline typename detail::alloc_if::value, + typename allocator_size_type::type>::type +allocator_max_size(const A&) BOOST_NOEXCEPT +{ + return (std::numeric_limits::type>::max)() / + sizeof(typename allocator_value_type::type); +} + +namespace detail { + +#if defined(BOOST_NO_CXX11_ALLOCATOR) +template +class alloc_has_soccc { + template + static alloc_no + check(int); + + template + static alloc_no + check(int); + + template + static alloc_no + check(int); + + template + static char check(long); + +public: + BOOST_STATIC_CONSTEXPR bool value = sizeof(check(0)) > 1; +}; +#else +template +class alloc_has_soccc { + template + static auto check(int) -> alloc_no().select_on_container_copy_construction())>; + + template + static char check(long); + +public: + BOOST_STATIC_CONSTEXPR bool value = sizeof(check(0)) > 1; +}; +#endif + +} /* detail */ + +template +inline typename detail::alloc_if::value, A>::type +allocator_select_on_container_copy_construction(const A& a) +{ + return a.select_on_container_copy_construction(); +} + +template +inline typename detail::alloc_if::value, A>::type +allocator_select_on_container_copy_construction(const A& a) +{ + return a; +} + +template +inline void +allocator_destroy_n(A& a, T* p, std::size_t n) +{ + while (n > 0) { + boost::allocator_destroy(a, p + --n); + } +} + +namespace detail { + +template +class alloc_destroyer { +public: + alloc_destroyer(A& a, T* p) BOOST_NOEXCEPT + : a_(a), p_(p), n_(0) { } + + ~alloc_destroyer() { + boost::allocator_destroy_n(a_, p_, n_); + } + + std::size_t& size() BOOST_NOEXCEPT { + return n_; + } + +private: + alloc_destroyer(const alloc_destroyer&); + alloc_destroyer& operator=(const alloc_destroyer&); + + A& a_; + T* p_; + std::size_t n_; +}; + +} /* detail */ + +template +inline void +allocator_construct_n(A& a, T* p, std::size_t n) +{ + detail::alloc_destroyer d(a, p); + for (std::size_t& i = d.size(); i < n; ++i) { + boost::allocator_construct(a, p + i); + } + d.size() = 0; +} + +template +inline void +allocator_construct_n(A& a, T* p, std::size_t n, const T* l, std::size_t m) +{ + detail::alloc_destroyer d(a, p); + for (std::size_t& i = d.size(); i < n; ++i) { + boost::allocator_construct(a, p + i, l[i % m]); + } + d.size() = 0; +} + +template +inline void +allocator_construct_n(A& a, T* p, std::size_t n, I b) +{ + detail::alloc_destroyer d(a, p); + for (std::size_t& i = d.size(); i < n; void(++i), void(++b)) { + boost::allocator_construct(a, p + i, *b); + } + d.size() = 0; +} + +#if !defined(BOOST_NO_CXX11_TEMPLATE_ALIASES) +template +using allocator_value_type_t = typename allocator_value_type::type; + +template +using allocator_pointer_t = typename allocator_pointer::type; + +template +using allocator_const_pointer_t = typename allocator_const_pointer::type; + +template +using allocator_void_pointer_t = typename allocator_void_pointer::type; + +template +using allocator_const_void_pointer_t = + typename allocator_const_void_pointer::type; + +template +using allocator_difference_type_t = + typename allocator_difference_type::type; + +template +using allocator_size_type_t = typename allocator_size_type::type; + +template +using allocator_propagate_on_container_copy_assignment_t = + typename allocator_propagate_on_container_copy_assignment::type; + +template +using allocator_propagate_on_container_move_assignment_t = + typename allocator_propagate_on_container_move_assignment::type; + +template +using allocator_propagate_on_container_swap_t = + typename allocator_propagate_on_container_swap::type; + +template +using allocator_is_always_equal_t = + typename allocator_is_always_equal::type; + +template +using allocator_rebind_t = typename allocator_rebind::type; +#endif + +} /* boost */ + +#if defined(_MSC_VER) +#pragma warning(pop) +#endif +#if defined(_STL_RESTORE_DEPRECATED_WARNING) +_STL_RESTORE_DEPRECATED_WARNING +#endif +#if defined(_LIBCPP_SUPPRESS_DEPRECATED_POP) +_LIBCPP_SUPPRESS_DEPRECATED_POP +#endif + +#endif diff --git a/include/boost/core/allocator_traits.hpp b/include/boost/core/allocator_traits.hpp new file mode 100644 index 000000000..bf8749d8c --- /dev/null +++ b/include/boost/core/allocator_traits.hpp @@ -0,0 +1,112 @@ +/* +Copyright 2021 Glen Joseph Fernandes +(glenjofe@gmail.com) + +Distributed under the Boost Software License, Version 1.0. +(http://www.boost.org/LICENSE_1_0.txt) +*/ +#ifndef BOOST_CORE_ALLOCATOR_TRAITS_HPP +#define BOOST_CORE_ALLOCATOR_TRAITS_HPP + +#include + +namespace boost { + +template +struct allocator_traits { + typedef A allocator_type; + + typedef typename allocator_value_type::type value_type; + + typedef typename allocator_pointer::type pointer; + + typedef typename allocator_const_pointer::type const_pointer; + + typedef typename allocator_void_pointer::type void_pointer; + + typedef typename allocator_const_void_pointer::type const_void_pointer; + + typedef typename allocator_difference_type::type difference_type; + + typedef typename allocator_size_type::type size_type; + + typedef typename allocator_propagate_on_container_copy_assignment::type + propagate_on_container_copy_assignment; + + typedef typename allocator_propagate_on_container_move_assignment::type + propagate_on_container_move_assignment; + + typedef typename allocator_propagate_on_container_swap::type + propagate_on_container_swap; + + typedef typename allocator_is_always_equal::type is_always_equal; + +#if !defined(BOOST_NO_CXX11_TEMPLATE_ALIASES) + template + using rebind_traits = allocator_traits::type>; +#else + template + struct rebind_traits + : allocator_traits::type> { }; +#endif + + static pointer allocate(A& a, size_type n) { + return boost::allocator_allocate(a, n); + } + + static pointer allocate(A& a, size_type n, const_void_pointer h) { + return boost::allocator_allocate(a, n, h); + } + + static void deallocate(A& a, pointer p, size_type n) { + return boost::allocator_deallocate(a, p, n); + } + + template + static void construct(A& a, T* p) { + boost::allocator_construct(a, p); + } + +#if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES) +#if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) + template + static void construct(A& a, T* p, V&& v, Args&&... args) { + boost::allocator_construct(a, p, std::forward(v), + std::forward(args)...); + } +#else + template + static void construct(A& a, T* p, V&& v) { + boost::allocator_construct(a, p, std::forward(v)); + } +#endif +#else + template + static void construct(A& a, T* p, const V& v) { + boost::allocator_construct(a, p, v); + } + + template + static void construct(A& a, T* p, V& v) { + boost::allocator_construct(a, p, v); + } +#endif + + template + static void destroy(A& a, T* p) { + boost::allocator_destroy(a, p); + } + + static size_type max_size(const A& a) BOOST_NOEXCEPT { + return boost::allocator_max_size(a); + } + + static A select_on_container_copy_construction(const A& a) { + return boost::allocator_select_on_container_copy_construction(a); + } +}; + +} /* boost */ + +#endif diff --git a/include/boost/core/bit.hpp b/include/boost/core/bit.hpp new file mode 100644 index 000000000..a6147e4d4 --- /dev/null +++ b/include/boost/core/bit.hpp @@ -0,0 +1,936 @@ +#ifndef BOOST_CORE_BIT_HPP_INCLUDED +#define BOOST_CORE_BIT_HPP_INCLUDED + +// MS compatible compilers support #pragma once + +#if defined(_MSC_VER) && (_MSC_VER >= 1020) +# pragma once +#endif + +// boost/core/bit.hpp +// +// A portable version of the C++20 standard header +// +// Copyright 2020 Peter Dimov +// Distributed under the Boost Software License, Version 1.0. +// https://www.boost.org/LICENSE_1_0.txt + +#include +#include +#include +#include +#include +#include + +#if defined(_MSC_VER) + +# include +# pragma intrinsic(_BitScanForward) +# pragma intrinsic(_BitScanReverse) + +# if defined(_M_X64) +# pragma intrinsic(_BitScanForward64) +# pragma intrinsic(_BitScanReverse64) +# endif + +# pragma warning(push) +# pragma warning(disable: 4127) // conditional expression is constant +# pragma warning(disable: 4244) // conversion from int to T + +#endif // defined(_MSC_VER) + +#if defined(BOOST_MSVC) && BOOST_MSVC >= 1925 +# define BOOST_CORE_HAS_BUILTIN_ISCONSTEVAL +#endif + +#if defined(__has_builtin) +# if __has_builtin(__builtin_bit_cast) +# define BOOST_CORE_HAS_BUILTIN_BIT_CAST +# endif +#endif + +#if defined(BOOST_MSVC) && BOOST_MSVC >= 1926 +# define BOOST_CORE_HAS_BUILTIN_BIT_CAST +#endif + +namespace boost +{ +namespace core +{ + +// bit_cast + +#if defined(BOOST_CORE_HAS_BUILTIN_BIT_CAST) + +template +BOOST_CONSTEXPR To bit_cast( From const & from ) BOOST_NOEXCEPT +{ + return __builtin_bit_cast( To, from ); +} + +#else + +template +To bit_cast( From const & from ) BOOST_NOEXCEPT +{ + BOOST_STATIC_ASSERT( sizeof(To) == sizeof(From) ); + + To to; + std::memcpy( &to, &from, sizeof(To) ); + return to; +} + +#endif + +// countl + +#if defined(__GNUC__) || defined(__clang__) + +namespace detail +{ + +BOOST_CONSTEXPR inline int countl_impl( unsigned char x ) BOOST_NOEXCEPT +{ + return x? __builtin_clz( x ) - ( std::numeric_limits::digits - std::numeric_limits::digits ): std::numeric_limits::digits; +} + +BOOST_CONSTEXPR inline int countl_impl( unsigned short x ) BOOST_NOEXCEPT +{ + return x? __builtin_clz( x ) - ( std::numeric_limits::digits - std::numeric_limits::digits ): std::numeric_limits::digits; +} + +BOOST_CONSTEXPR inline int countl_impl( unsigned int x ) BOOST_NOEXCEPT +{ + return x? __builtin_clz( x ): std::numeric_limits::digits; +} + +BOOST_CONSTEXPR inline int countl_impl( unsigned long x ) BOOST_NOEXCEPT +{ + return x? __builtin_clzl( x ): std::numeric_limits::digits; +} + +BOOST_CONSTEXPR inline int countl_impl( boost::ulong_long_type x ) BOOST_NOEXCEPT +{ + return x? __builtin_clzll( x ): std::numeric_limits::digits; +} + +} // namespace detail + +template +BOOST_CONSTEXPR int countl_zero( T x ) BOOST_NOEXCEPT +{ + BOOST_STATIC_ASSERT( std::numeric_limits::is_integer && !std::numeric_limits::is_signed ); + + return boost::core::detail::countl_impl( x ); +} + +#else // defined(__GNUC__) || defined(__clang__) + +namespace detail +{ + +#if defined(_MSC_VER) && defined(BOOST_CORE_HAS_BUILTIN_ISCONSTEVAL) + +BOOST_CXX14_CONSTEXPR inline int countl_impl( boost::uint32_t x ) BOOST_NOEXCEPT +{ + if( __builtin_is_constant_evaluated() ) + { + constexpr unsigned char mod37[ 37 ] = { 32, 31, 6, 30, 9, 5, 0, 29, 16, 8, 2, 4, 21, 0, 19, 28, 25, 15, 0, 7, 10, 1, 17, 3, 22, 20, 26, 0, 11, 18, 23, 27, 12, 24, 13, 14, 0 }; + + x |= x >> 1; + x |= x >> 2; + x |= x >> 4; + x |= x >> 8; + x |= x >> 16; + + return mod37[ x % 37 ]; + } + else + { + unsigned long r; + + if( _BitScanReverse( &r, x ) ) + { + return 31 - static_cast( r ); + } + else + { + return 32; + } + } +} + +BOOST_CXX14_CONSTEXPR inline int countl_impl( boost::uint8_t x ) BOOST_NOEXCEPT +{ + return boost::core::detail::countl_impl( static_cast( x ) ) - 24; +} + +BOOST_CXX14_CONSTEXPR inline int countl_impl( boost::uint16_t x ) BOOST_NOEXCEPT +{ + return boost::core::detail::countl_impl( static_cast( x ) ) - 16; +} + +#elif defined(_MSC_VER) + +inline int countl_impl( boost::uint32_t x ) BOOST_NOEXCEPT +{ + unsigned long r; + + if( _BitScanReverse( &r, x ) ) + { + return 31 - static_cast( r ); + } + else + { + return 32; + } +} + +inline int countl_impl( boost::uint8_t x ) BOOST_NOEXCEPT +{ + return boost::core::detail::countl_impl( static_cast( x ) ) - 24; +} + +inline int countl_impl( boost::uint16_t x ) BOOST_NOEXCEPT +{ + return boost::core::detail::countl_impl( static_cast( x ) ) - 16; +} + +#else + +inline int countl_impl( boost::uint32_t x ) BOOST_NOEXCEPT +{ + static unsigned char const mod37[ 37 ] = { 32, 31, 6, 30, 9, 5, 0, 29, 16, 8, 2, 4, 21, 0, 19, 28, 25, 15, 0, 7, 10, 1, 17, 3, 22, 20, 26, 0, 11, 18, 23, 27, 12, 24, 13, 14, 0 }; + + x |= x >> 1; + x |= x >> 2; + x |= x >> 4; + x |= x >> 8; + x |= x >> 16; + + return mod37[ x % 37 ]; +} + +inline int countl_impl( boost::uint8_t x ) BOOST_NOEXCEPT +{ + return boost::core::detail::countl_impl( static_cast( x ) ) - 24; +} + +inline int countl_impl( boost::uint16_t x ) BOOST_NOEXCEPT +{ + return boost::core::detail::countl_impl( static_cast( x ) ) - 16; +} + +#endif + +#if defined(_MSC_VER) && defined(_M_X64) && defined(BOOST_CORE_HAS_BUILTIN_ISCONSTEVAL) + +BOOST_CXX14_CONSTEXPR inline int countl_impl( boost::uint64_t x ) BOOST_NOEXCEPT +{ + if( __builtin_is_constant_evaluated() ) + { + return static_cast( x >> 32 ) != 0? + boost::core::detail::countl_impl( static_cast( x >> 32 ) ): + boost::core::detail::countl_impl( static_cast( x ) ) + 32; + } + else + { + unsigned long r; + + if( _BitScanReverse64( &r, x ) ) + { + return 63 - static_cast( r ); + } + else + { + return 64; + } + } +} + +#elif defined(_MSC_VER) && defined(_M_X64) + +inline int countl_impl( boost::uint64_t x ) BOOST_NOEXCEPT +{ + unsigned long r; + + if( _BitScanReverse64( &r, x ) ) + { + return 63 - static_cast( r ); + } + else + { + return 64; + } +} + +#elif defined(_MSC_VER) && defined(BOOST_CORE_HAS_BUILTIN_ISCONSTEVAL) + +BOOST_CXX14_CONSTEXPR inline int countl_impl( boost::uint64_t x ) BOOST_NOEXCEPT +{ + return static_cast( x >> 32 ) != 0? + boost::core::detail::countl_impl( static_cast( x >> 32 ) ): + boost::core::detail::countl_impl( static_cast( x ) ) + 32; +} + +#else + +inline int countl_impl( boost::uint64_t x ) BOOST_NOEXCEPT +{ + return static_cast( x >> 32 ) != 0? + boost::core::detail::countl_impl( static_cast( x >> 32 ) ): + boost::core::detail::countl_impl( static_cast( x ) ) + 32; +} + +#endif + +} // namespace detail + +template +BOOST_CXX14_CONSTEXPR int countl_zero( T x ) BOOST_NOEXCEPT +{ + BOOST_STATIC_ASSERT( std::numeric_limits::is_integer && !std::numeric_limits::is_signed ); + + BOOST_STATIC_ASSERT( sizeof(T) == sizeof(boost::uint8_t) || sizeof(T) == sizeof(boost::uint16_t) || sizeof(T) == sizeof(boost::uint32_t) || sizeof(T) == sizeof(boost::uint64_t) ); + + BOOST_IF_CONSTEXPR ( sizeof(T) == sizeof(boost::uint8_t) ) + { + return boost::core::detail::countl_impl( static_cast( x ) ); + } + else BOOST_IF_CONSTEXPR ( sizeof(T) == sizeof(boost::uint16_t) ) + { + return boost::core::detail::countl_impl( static_cast( x ) ); + } + else BOOST_IF_CONSTEXPR ( sizeof(T) == sizeof(boost::uint32_t) ) + { + return boost::core::detail::countl_impl( static_cast( x ) ); + } + else + { + return boost::core::detail::countl_impl( static_cast( x ) ); + } +} + +#endif // defined(__GNUC__) || defined(__clang__) + +template +BOOST_CONSTEXPR int countl_one( T x ) BOOST_NOEXCEPT +{ + BOOST_STATIC_ASSERT( std::numeric_limits::is_integer && !std::numeric_limits::is_signed ); + + return boost::core::countl_zero( static_cast( ~x ) ); +} + +// countr + +#if defined(__GNUC__) || defined(__clang__) + +namespace detail +{ + +BOOST_CONSTEXPR inline int countr_impl( unsigned char x ) BOOST_NOEXCEPT +{ + return x? __builtin_ctz( x ): std::numeric_limits::digits; +} + +BOOST_CONSTEXPR inline int countr_impl( unsigned short x ) BOOST_NOEXCEPT +{ + return x? __builtin_ctz( x ): std::numeric_limits::digits; +} + +BOOST_CONSTEXPR inline int countr_impl( unsigned int x ) BOOST_NOEXCEPT +{ + return x? __builtin_ctz( x ): std::numeric_limits::digits; +} + +BOOST_CONSTEXPR inline int countr_impl( unsigned long x ) BOOST_NOEXCEPT +{ + return x? __builtin_ctzl( x ): std::numeric_limits::digits; +} + +BOOST_CONSTEXPR inline int countr_impl( boost::ulong_long_type x ) BOOST_NOEXCEPT +{ + return x? __builtin_ctzll( x ): std::numeric_limits::digits; +} + +} // namespace detail + +template +BOOST_CONSTEXPR int countr_zero( T x ) BOOST_NOEXCEPT +{ + BOOST_STATIC_ASSERT( std::numeric_limits::is_integer && !std::numeric_limits::is_signed ); + + return boost::core::detail::countr_impl( x ); +} + +#else // defined(__GNUC__) || defined(__clang__) + +namespace detail +{ + +#if defined(_MSC_VER) && defined(BOOST_CORE_HAS_BUILTIN_ISCONSTEVAL) + +BOOST_CXX14_CONSTEXPR inline int countr_impl( boost::uint32_t x ) BOOST_NOEXCEPT +{ + if( __builtin_is_constant_evaluated() ) + { + constexpr unsigned char mod37[ 37 ] = { 32, 0, 1, 26, 2, 23, 27, 0, 3, 16, 24, 30, 28, 11, 0, 13, 4, 7, 17, 0, 25, 22, 31, 15, 29, 10, 12, 6, 0, 21, 14, 9, 5, 20, 8, 19, 18 }; + return mod37[ ( -(boost::int32_t)x & x ) % 37 ]; + } + else + { + unsigned long r; + + if( _BitScanForward( &r, x ) ) + { + return static_cast( r ); + } + else + { + return 32; + } + } +} + +BOOST_CXX14_CONSTEXPR inline int countr_impl( boost::uint8_t x ) BOOST_NOEXCEPT +{ + return boost::core::detail::countr_impl( static_cast( x ) | 0x100 ); +} + +BOOST_CXX14_CONSTEXPR inline int countr_impl( boost::uint16_t x ) BOOST_NOEXCEPT +{ + return boost::core::detail::countr_impl( static_cast( x ) | 0x10000 ); +} + +#elif defined(_MSC_VER) + +inline int countr_impl( boost::uint32_t x ) BOOST_NOEXCEPT +{ + unsigned long r; + + if( _BitScanForward( &r, x ) ) + { + return static_cast( r ); + } + else + { + return 32; + } +} + +inline int countr_impl( boost::uint8_t x ) BOOST_NOEXCEPT +{ + return boost::core::detail::countr_impl( static_cast( x ) | 0x100 ); +} + +inline int countr_impl( boost::uint16_t x ) BOOST_NOEXCEPT +{ + return boost::core::detail::countr_impl( static_cast( x ) | 0x10000 ); +} + +#else + +inline int countr_impl( boost::uint32_t x ) BOOST_NOEXCEPT +{ + static unsigned char const mod37[ 37 ] = { 32, 0, 1, 26, 2, 23, 27, 0, 3, 16, 24, 30, 28, 11, 0, 13, 4, 7, 17, 0, 25, 22, 31, 15, 29, 10, 12, 6, 0, 21, 14, 9, 5, 20, 8, 19, 18 }; + return mod37[ ( -(boost::int32_t)x & x ) % 37 ]; +} + +inline int countr_impl( boost::uint8_t x ) BOOST_NOEXCEPT +{ + return boost::core::detail::countr_impl( static_cast( x ) | 0x100 ); +} + +inline int countr_impl( boost::uint16_t x ) BOOST_NOEXCEPT +{ + return boost::core::detail::countr_impl( static_cast( x ) | 0x10000 ); +} + +#endif + +#if defined(_MSC_VER) && defined(_M_X64) && defined(BOOST_CORE_HAS_BUILTIN_ISCONSTEVAL) + +BOOST_CXX14_CONSTEXPR inline int countr_impl( boost::uint64_t x ) BOOST_NOEXCEPT +{ + if( __builtin_is_constant_evaluated() ) + { + return static_cast( x ) != 0? + boost::core::detail::countr_impl( static_cast( x ) ): + boost::core::detail::countr_impl( static_cast( x >> 32 ) ) + 32; + } + else + { + unsigned long r; + + if( _BitScanForward64( &r, x ) ) + { + return static_cast( r ); + } + else + { + return 64; + } + } +} + +#elif defined(_MSC_VER) && defined(_M_X64) + +inline int countr_impl( boost::uint64_t x ) BOOST_NOEXCEPT +{ + unsigned long r; + + if( _BitScanForward64( &r, x ) ) + { + return static_cast( r ); + } + else + { + return 64; + } +} + +#elif defined(_MSC_VER) && defined(BOOST_CORE_HAS_BUILTIN_ISCONSTEVAL) + +BOOST_CXX14_CONSTEXPR inline int countr_impl( boost::uint64_t x ) BOOST_NOEXCEPT +{ + return static_cast( x ) != 0? + boost::core::detail::countr_impl( static_cast( x ) ): + boost::core::detail::countr_impl( static_cast( x >> 32 ) ) + 32; +} + +#else + +inline int countr_impl( boost::uint64_t x ) BOOST_NOEXCEPT +{ + return static_cast( x ) != 0? + boost::core::detail::countr_impl( static_cast( x ) ): + boost::core::detail::countr_impl( static_cast( x >> 32 ) ) + 32; +} + +#endif + +} // namespace detail + +template +BOOST_CXX14_CONSTEXPR int countr_zero( T x ) BOOST_NOEXCEPT +{ + BOOST_STATIC_ASSERT( std::numeric_limits::is_integer && !std::numeric_limits::is_signed ); + + BOOST_STATIC_ASSERT( sizeof(T) == sizeof(boost::uint8_t) || sizeof(T) == sizeof(boost::uint16_t) || sizeof(T) == sizeof(boost::uint32_t) || sizeof(T) == sizeof(boost::uint64_t) ); + + BOOST_IF_CONSTEXPR ( sizeof(T) == sizeof(boost::uint8_t) ) + { + return boost::core::detail::countr_impl( static_cast( x ) ); + } + else BOOST_IF_CONSTEXPR ( sizeof(T) == sizeof(boost::uint16_t) ) + { + return boost::core::detail::countr_impl( static_cast( x ) ); + } + else BOOST_IF_CONSTEXPR ( sizeof(T) == sizeof(boost::uint32_t) ) + { + return boost::core::detail::countr_impl( static_cast( x ) ); + } + else + { + return boost::core::detail::countr_impl( static_cast( x ) ); + } +} + +#endif // defined(__GNUC__) || defined(__clang__) + +template +BOOST_CONSTEXPR int countr_one( T x ) BOOST_NOEXCEPT +{ + BOOST_STATIC_ASSERT( std::numeric_limits::is_integer && !std::numeric_limits::is_signed ); + + return boost::core::countr_zero( static_cast( ~x ) ); +} + +// popcount + +#if defined(__GNUC__) || defined(__clang__) + +#if defined(__clang__) && __clang_major__ * 100 + __clang_minor__ < 304 +# define BOOST_CORE_POPCOUNT_CONSTEXPR +#else +# define BOOST_CORE_POPCOUNT_CONSTEXPR BOOST_CONSTEXPR +#endif + +namespace detail +{ + +BOOST_CORE_POPCOUNT_CONSTEXPR inline int popcount_impl( unsigned char x ) BOOST_NOEXCEPT +{ + return __builtin_popcount( x ); +} + +BOOST_CORE_POPCOUNT_CONSTEXPR inline int popcount_impl( unsigned short x ) BOOST_NOEXCEPT +{ + return __builtin_popcount( x ); +} + +BOOST_CORE_POPCOUNT_CONSTEXPR inline int popcount_impl( unsigned int x ) BOOST_NOEXCEPT +{ + return __builtin_popcount( x ); +} + +BOOST_CORE_POPCOUNT_CONSTEXPR inline int popcount_impl( unsigned long x ) BOOST_NOEXCEPT +{ + return __builtin_popcountl( x ); +} + +BOOST_CORE_POPCOUNT_CONSTEXPR inline int popcount_impl( boost::ulong_long_type x ) BOOST_NOEXCEPT +{ + return __builtin_popcountll( x ); +} + +} // namespace detail + +#undef BOOST_CORE_POPCOUNT_CONSTEXPR + +template +BOOST_CONSTEXPR int popcount( T x ) BOOST_NOEXCEPT +{ + BOOST_STATIC_ASSERT( std::numeric_limits::is_integer && !std::numeric_limits::is_signed ); + + return boost::core::detail::popcount_impl( x ); +} + +#else // defined(__GNUC__) || defined(__clang__) + +namespace detail +{ + +BOOST_CXX14_CONSTEXPR inline int popcount_impl( boost::uint32_t x ) BOOST_NOEXCEPT +{ + x = x - ( ( x >> 1 ) & 0x55555555 ); + x = ( x & 0x33333333 ) + ( ( x >> 2 ) & 0x33333333 ); + x = ( x + ( x >> 4 ) ) & 0x0F0F0F0F; + + return static_cast( ( x * 0x01010101 ) >> 24 ); +} + +BOOST_CXX14_CONSTEXPR inline int popcount_impl( boost::uint64_t x ) BOOST_NOEXCEPT +{ + x = x - ( ( x >> 1 ) & 0x5555555555555555 ); + x = ( x & 0x3333333333333333 ) + ( ( x >> 2 ) & 0x3333333333333333 ); + x = ( x + ( x >> 4 ) ) & 0x0F0F0F0F0F0F0F0F; + + return static_cast( ( x * 0x0101010101010101 ) >> 56 ); +} + +} // namespace detail + +template +BOOST_CXX14_CONSTEXPR int popcount( T x ) BOOST_NOEXCEPT +{ + BOOST_STATIC_ASSERT( std::numeric_limits::is_integer && !std::numeric_limits::is_signed ); + + BOOST_STATIC_ASSERT( sizeof(T) <= sizeof(boost::uint64_t) ); + + BOOST_IF_CONSTEXPR ( sizeof(T) <= sizeof(boost::uint32_t) ) + { + return boost::core::detail::popcount_impl( static_cast( x ) ); + } + else + { + return boost::core::detail::popcount_impl( static_cast( x ) ); + } +} + +#endif // defined(__GNUC__) || defined(__clang__) + +// rotating + +template +BOOST_CXX14_CONSTEXPR T rotl( T x, int s ) BOOST_NOEXCEPT +{ + BOOST_STATIC_ASSERT( std::numeric_limits::is_integer && !std::numeric_limits::is_signed ); + + unsigned const mask = std::numeric_limits::digits - 1; + return static_cast( x << (static_cast( s ) & mask) | x >> (static_cast( -s ) & mask) ); +} + +template +BOOST_CXX14_CONSTEXPR T rotr( T x, int s ) BOOST_NOEXCEPT +{ + BOOST_STATIC_ASSERT( std::numeric_limits::is_integer && !std::numeric_limits::is_signed ); + + unsigned const mask = std::numeric_limits::digits - 1; + return static_cast( x >> (static_cast( s ) & mask) | x << (static_cast( -s ) & mask) ); +} + +// integral powers of 2 + +template +BOOST_CONSTEXPR bool has_single_bit( T x ) BOOST_NOEXCEPT +{ + BOOST_STATIC_ASSERT( std::numeric_limits::is_integer && !std::numeric_limits::is_signed ); + + return x != 0 && ( x & ( x - 1 ) ) == 0; +} + +// bit_width returns `int` now, https://cplusplus.github.io/LWG/issue3656 +// has been applied to C++20 as a DR + +template +BOOST_CONSTEXPR int bit_width( T x ) BOOST_NOEXCEPT +{ + BOOST_STATIC_ASSERT( std::numeric_limits::is_integer && !std::numeric_limits::is_signed ); + + return std::numeric_limits::digits - boost::core::countl_zero( x ); +} + +template +BOOST_CONSTEXPR T bit_floor( T x ) BOOST_NOEXCEPT +{ + BOOST_STATIC_ASSERT( std::numeric_limits::is_integer && !std::numeric_limits::is_signed ); + + return x == 0? T(0): static_cast( T(1) << ( boost::core::bit_width( x ) - 1 ) ); +} + +namespace detail +{ + +BOOST_CXX14_CONSTEXPR inline boost::uint32_t bit_ceil_impl( boost::uint32_t x ) BOOST_NOEXCEPT +{ + if( x == 0 ) + { + return 0; + } + + --x; + + x |= x >> 1; + x |= x >> 2; + x |= x >> 4; + x |= x >> 8; + x |= x >> 16; + + ++x; + + return x; +} + +BOOST_CXX14_CONSTEXPR inline boost::uint64_t bit_ceil_impl( boost::uint64_t x ) BOOST_NOEXCEPT +{ + if( x == 0 ) + { + return 0; + } + + --x; + + x |= x >> 1; + x |= x >> 2; + x |= x >> 4; + x |= x >> 8; + x |= x >> 16; + x |= x >> 32; + + ++x; + + return x; +} + +} // namespace detail + +template +BOOST_CXX14_CONSTEXPR T bit_ceil( T x ) BOOST_NOEXCEPT +{ + BOOST_STATIC_ASSERT( std::numeric_limits::is_integer && !std::numeric_limits::is_signed ); + + BOOST_STATIC_ASSERT( sizeof(T) <= sizeof(boost::uint64_t) ); + + BOOST_IF_CONSTEXPR ( sizeof(T) <= sizeof(boost::uint32_t) ) + { + return static_cast( boost::core::detail::bit_ceil_impl( static_cast( x ) ) ); + } + else + { + return static_cast( boost::core::detail::bit_ceil_impl( static_cast( x ) ) ); + } +} + +// endian + +#if defined(__BYTE_ORDER__) && defined(__ORDER_LITTLE_ENDIAN__) && __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__ + +# define BOOST_CORE_BIT_NATIVE_INITIALIZER =little + +#elif defined(__BYTE_ORDER__) && defined(__ORDER_BIG_ENDIAN__) && __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__ + +# define BOOST_CORE_BIT_NATIVE_INITIALIZER =big + +#elif defined(__BYTE_ORDER__) && defined(__ORDER_PDP_ENDIAN__) && __BYTE_ORDER__ == __ORDER_PDP_ENDIAN__ + +# define BOOST_CORE_BIT_NATIVE_INITIALIZER + +#elif defined(__LITTLE_ENDIAN__) + +# define BOOST_CORE_BIT_NATIVE_INITIALIZER =little + +#elif defined(__BIG_ENDIAN__) + +# define BOOST_CORE_BIT_NATIVE_INITIALIZER =big + +#elif defined(_MSC_VER) || defined(__i386__) || defined(__x86_64__) + +# define BOOST_CORE_BIT_NATIVE_INITIALIZER =little + +#else + +# define BOOST_CORE_BIT_NATIVE_INITIALIZER + +#endif + +#if !defined(BOOST_NO_CXX11_SCOPED_ENUMS) + +enum class endian +{ + big, + little, + native BOOST_CORE_BIT_NATIVE_INITIALIZER +}; + +typedef endian endian_type; + +#else + +namespace endian +{ + +enum type +{ + big, + little, + native BOOST_CORE_BIT_NATIVE_INITIALIZER +}; + +} // namespace endian + +typedef endian::type endian_type; + +#endif + +#undef BOOST_CORE_BIT_NATIVE_INITIALIZER + +// byteswap + +namespace detail +{ + +BOOST_CONSTEXPR inline boost::uint8_t byteswap_impl( boost::uint8_t x ) BOOST_NOEXCEPT +{ + return x; +} + +BOOST_CONSTEXPR inline boost::uint16_t byteswap_impl( boost::uint16_t x ) BOOST_NOEXCEPT +{ + return static_cast( x << 8 | x >> 8 ); +} + +#if defined(__GNUC__) || defined(__clang__) + +BOOST_CXX14_CONSTEXPR inline boost::uint32_t byteswap_impl( boost::uint32_t x ) BOOST_NOEXCEPT +{ + return __builtin_bswap32( x ); +} + +BOOST_CXX14_CONSTEXPR inline boost::uint64_t byteswap_impl( boost::uint64_t x ) BOOST_NOEXCEPT +{ + return __builtin_bswap64( x ); +} + +#elif defined(_MSC_VER) && defined(BOOST_CORE_HAS_BUILTIN_ISCONSTEVAL) + +BOOST_CXX14_CONSTEXPR inline boost::uint32_t byteswap_impl( boost::uint32_t x ) BOOST_NOEXCEPT +{ + if( __builtin_is_constant_evaluated() ) + { + boost::uint32_t step16 = x << 16 | x >> 16; + return ((step16 << 8) & 0xff00ff00) | ((step16 >> 8) & 0x00ff00ff); + } + else + { + return _byteswap_ulong( x ); + } +} + +BOOST_CXX14_CONSTEXPR inline boost::uint64_t byteswap_impl( boost::uint64_t x ) BOOST_NOEXCEPT +{ + if( __builtin_is_constant_evaluated() ) + { + boost::uint64_t step32 = x << 32 | x >> 32; + boost::uint64_t step16 = (step32 & 0x0000FFFF0000FFFFULL) << 16 | (step32 & 0xFFFF0000FFFF0000ULL) >> 16; + return (step16 & 0x00FF00FF00FF00FFULL) << 8 | (step16 & 0xFF00FF00FF00FF00ULL) >> 8; + } + else + { + return _byteswap_uint64( x ); + } +} + +#elif defined(_MSC_VER) + +inline boost::uint32_t byteswap_impl( boost::uint32_t x ) BOOST_NOEXCEPT +{ + return _byteswap_ulong( x ); +} + +inline boost::uint64_t byteswap_impl( boost::uint64_t x ) BOOST_NOEXCEPT +{ + return _byteswap_uint64( x ); +} + +#else + +BOOST_CXX14_CONSTEXPR inline boost::uint32_t byteswap_impl( boost::uint32_t x ) BOOST_NOEXCEPT +{ + boost::uint32_t step16 = x << 16 | x >> 16; + return ((step16 << 8) & 0xff00ff00) | ((step16 >> 8) & 0x00ff00ff); +} + +BOOST_CXX14_CONSTEXPR inline boost::uint64_t byteswap_impl( boost::uint64_t x ) BOOST_NOEXCEPT +{ + boost::uint64_t step32 = x << 32 | x >> 32; + boost::uint64_t step16 = (step32 & 0x0000FFFF0000FFFFULL) << 16 | (step32 & 0xFFFF0000FFFF0000ULL) >> 16; + return (step16 & 0x00FF00FF00FF00FFULL) << 8 | (step16 & 0xFF00FF00FF00FF00ULL) >> 8; +} + +#endif + +} // namespace detail + +template BOOST_CXX14_CONSTEXPR T byteswap( T x ) BOOST_NOEXCEPT +{ + BOOST_STATIC_ASSERT( std::numeric_limits::is_integer ); + + BOOST_STATIC_ASSERT( sizeof(T) == sizeof(boost::uint8_t) || sizeof(T) == sizeof(boost::uint16_t) || sizeof(T) == sizeof(boost::uint32_t) || sizeof(T) == sizeof(boost::uint64_t) ); + + BOOST_IF_CONSTEXPR ( sizeof(T) == sizeof(boost::uint8_t) ) + { + return static_cast( boost::core::detail::byteswap_impl( static_cast( x ) ) ); + } + else BOOST_IF_CONSTEXPR ( sizeof(T) == sizeof(boost::uint16_t) ) + { + return static_cast( boost::core::detail::byteswap_impl( static_cast( x ) ) ); + } + else BOOST_IF_CONSTEXPR ( sizeof(T) == sizeof(boost::uint32_t) ) + { + return static_cast( boost::core::detail::byteswap_impl( static_cast( x ) ) ); + } + else + { + return static_cast( boost::core::detail::byteswap_impl( static_cast( x ) ) ); + } +} + +} // namespace core +} // namespace boost + +#if defined(_MSC_VER) +# pragma warning(pop) +#endif + +#endif // #ifndef BOOST_CORE_BIT_HPP_INCLUDED diff --git a/include/boost/core/empty_value.hpp b/include/boost/core/empty_value.hpp new file mode 100644 index 000000000..d8ffa30b4 --- /dev/null +++ b/include/boost/core/empty_value.hpp @@ -0,0 +1,155 @@ +/* +Copyright 2018 Glen Joseph Fernandes +(glenjofe@gmail.com) + +Distributed under the Boost Software License, Version 1.0. +(http://www.boost.org/LICENSE_1_0.txt) +*/ +#ifndef BOOST_CORE_EMPTY_VALUE_HPP +#define BOOST_CORE_EMPTY_VALUE_HPP + +#include +#if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES) +#include +#endif + +#if defined(BOOST_GCC_VERSION) && (BOOST_GCC_VERSION >= 40700) +#define BOOST_DETAIL_EMPTY_VALUE_BASE +#elif defined(BOOST_INTEL) && defined(_MSC_VER) && (_MSC_VER >= 1800) +#define BOOST_DETAIL_EMPTY_VALUE_BASE +#elif defined(BOOST_MSVC) && (BOOST_MSVC >= 1800) +#define BOOST_DETAIL_EMPTY_VALUE_BASE +#elif defined(BOOST_CLANG) && !defined(__CUDACC__) +#if __has_feature(is_empty) && __has_feature(is_final) +#define BOOST_DETAIL_EMPTY_VALUE_BASE +#endif +#endif + +#if defined(_MSC_VER) +#pragma warning(push) +#pragma warning(disable:4510) +#endif + +namespace boost { + +template +struct use_empty_value_base { + enum { +#if defined(BOOST_DETAIL_EMPTY_VALUE_BASE) + value = __is_empty(T) && !__is_final(T) +#else + value = false +#endif + }; +}; + +struct empty_init_t { }; + +namespace empty_ { + +template::value> +class empty_value { +public: + typedef T type; + +#if !defined(BOOST_NO_CXX11_DEFAULTED_FUNCTIONS) + empty_value() = default; +#else + BOOST_CONSTEXPR empty_value() { } +#endif + + BOOST_CONSTEXPR empty_value(boost::empty_init_t) + : value_() { } + +#if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES) +#if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) + template + BOOST_CONSTEXPR empty_value(boost::empty_init_t, U&& value, Args&&... args) + : value_(std::forward(value), std::forward(args)...) { } +#else + template + BOOST_CONSTEXPR empty_value(boost::empty_init_t, U&& value) + : value_(std::forward(value)) { } +#endif +#else + template + BOOST_CONSTEXPR empty_value(boost::empty_init_t, const U& value) + : value_(value) { } + + template + BOOST_CONSTEXPR empty_value(boost::empty_init_t, U& value) + : value_(value) { } +#endif + + BOOST_CONSTEXPR const T& get() const BOOST_NOEXCEPT { + return value_; + } + + BOOST_CXX14_CONSTEXPR T& get() BOOST_NOEXCEPT { + return value_; + } + +private: + T value_; +}; + +#if !defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION) +template +class empty_value + : T { +public: + typedef T type; + +#if !defined(BOOST_NO_CXX11_DEFAULTED_FUNCTIONS) + empty_value() = default; +#else + BOOST_CONSTEXPR empty_value() { } +#endif + + BOOST_CONSTEXPR empty_value(boost::empty_init_t) + : T() { } + +#if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES) +#if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) + template + BOOST_CONSTEXPR empty_value(boost::empty_init_t, U&& value, Args&&... args) + : T(std::forward(value), std::forward(args)...) { } +#else + template + BOOST_CONSTEXPR empty_value(boost::empty_init_t, U&& value) + : T(std::forward(value)) { } +#endif +#else + template + BOOST_CONSTEXPR empty_value(boost::empty_init_t, const U& value) + : T(value) { } + + template + BOOST_CONSTEXPR empty_value(boost::empty_init_t, U& value) + : T(value) { } +#endif + + BOOST_CONSTEXPR const T& get() const BOOST_NOEXCEPT { + return *this; + } + + BOOST_CXX14_CONSTEXPR T& get() BOOST_NOEXCEPT { + return *this; + } +}; +#endif + +} /* empty_ */ + +using empty_::empty_value; + +BOOST_INLINE_CONSTEXPR empty_init_t empty_init = empty_init_t(); + +} /* boost */ + +#if defined(_MSC_VER) +#pragma warning(pop) +#endif + +#endif diff --git a/include/boost/core/pointer_traits.hpp b/include/boost/core/pointer_traits.hpp index e66194d60..7de7a8e97 100644 --- a/include/boost/core/pointer_traits.hpp +++ b/include/boost/core/pointer_traits.hpp @@ -1,5 +1,5 @@ /* -Copyright 2017-2018 Glen Joseph Fernandes +Copyright 2017-2021 Glen Joseph Fernandes (glenjofe@gmail.com) Distributed under the Boost Software License, Version 1.0. @@ -9,43 +9,23 @@ Distributed under the Boost Software License, Version 1.0. #define BOOST_CORE_POINTER_TRAITS_HPP #include -#if !defined(BOOST_NO_CXX11_POINTER_TRAITS) -#include -#else #include #include -#endif namespace boost { - -#if !defined(BOOST_NO_CXX11_POINTER_TRAITS) -template -struct pointer_traits - : std::pointer_traits { - template - struct rebind_to { - typedef typename std::pointer_traits::template rebind type; - }; -}; - -template -struct pointer_traits - : std::pointer_traits { - template - struct rebind_to { - typedef U* type; - }; -}; -#else namespace detail { +struct ptr_none { }; + template -struct ptr_void { +struct ptr_valid { typedef void type; }; -template -struct ptr_first; +template +struct ptr_first { + typedef ptr_none type; +}; #if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) template class T, class U, class... Args> @@ -75,7 +55,7 @@ struct ptr_element { }; template -struct ptr_element::type> { +struct ptr_element::type> { typedef typename T::element_type type; }; @@ -86,12 +66,12 @@ struct ptr_difference { template struct ptr_difference::type> { + typename ptr_valid::type> { typedef typename T::difference_type type; }; -template -struct ptr_transform; +template +struct ptr_transform { }; #if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) template class T, class U, class... Args, class V> @@ -117,68 +97,139 @@ struct ptr_transform, V> { #endif template -struct ptr_rebind { - typedef typename ptr_transform::type type; -}; +struct ptr_rebind + : ptr_transform { }; #if !defined(BOOST_NO_CXX11_TEMPLATE_ALIASES) template struct ptr_rebind >::type> { + typename ptr_valid >::type> { typedef typename T::template rebind type; }; +#else +template +struct ptr_rebind::other>::type> { + typedef typename T::template rebind::other type; +}; +#endif + +#if !defined(BOOST_NO_CXX11_DECLTYPE_N3276) +template +class ptr_to_expr { + template + struct result { + char x, y; + }; + + static E& source(); + + template + static auto check(int) -> result; + + template + static char check(long); + +public: + BOOST_STATIC_CONSTEXPR bool value = sizeof(check(0)) > 1; +}; + +template +struct ptr_to_expr { + BOOST_STATIC_CONSTEXPR bool value = true; +}; + +template +struct ptr_has_to { + BOOST_STATIC_CONSTEXPR bool value = ptr_to_expr::value; +}; +#else +template +struct ptr_has_to { + BOOST_STATIC_CONSTEXPR bool value = true; +}; #endif template -struct ptr_value { - typedef T type; +struct ptr_has_to { + BOOST_STATIC_CONSTEXPR bool value = false; }; -template<> -struct ptr_value { - typedef struct { } type; +template +struct ptr_has_to { + BOOST_STATIC_CONSTEXPR bool value = false; }; -} /* detail */ +template +struct ptr_has_to { + BOOST_STATIC_CONSTEXPR bool value = false; +}; template -struct pointer_traits { +struct ptr_has_to { + BOOST_STATIC_CONSTEXPR bool value = false; +}; + +template::value> +struct ptr_to { }; + +template +struct ptr_to { + static T pointer_to(E& v) { + return T::pointer_to(v); + } +}; + +template +struct ptr_to { + static T* pointer_to(T& v) BOOST_NOEXCEPT { + return boost::addressof(v); + } +}; + +template +struct ptr_traits + : ptr_to { typedef T pointer; - typedef typename detail::ptr_element::type element_type; - typedef typename detail::ptr_difference::type difference_type; + typedef E element_type; + typedef typename ptr_difference::type difference_type; + template - struct rebind_to { - typedef typename detail::ptr_rebind::type type; - }; + struct rebind_to + : ptr_rebind { }; + #if !defined(BOOST_NO_CXX11_TEMPLATE_ALIASES) template - using rebind = typename detail::ptr_rebind::type; + using rebind = typename rebind_to::type; #endif - static pointer - pointer_to(typename detail::ptr_value::type& v) { - return pointer::pointer_to(v); - } }; template -struct pointer_traits { +struct ptr_traits { }; + +} /* detail */ + +template +struct pointer_traits + : detail::ptr_traits::type> { }; + +template +struct pointer_traits + : detail::ptr_to { typedef T* pointer; typedef T element_type; typedef std::ptrdiff_t difference_type; + template struct rebind_to { typedef U* type; }; + #if !defined(BOOST_NO_CXX11_TEMPLATE_ALIASES) template - using rebind = U*; + using rebind = typename rebind_to::type; #endif - static T* - pointer_to(typename detail::ptr_value::type& v) BOOST_NOEXCEPT { - return boost::addressof(v); - } }; -#endif template BOOST_CONSTEXPR inline T* diff --git a/include/boost/core/ref.hpp b/include/boost/core/ref.hpp index 79f0b63c8..d29a4d6fb 100644 --- a/include/boost/core/ref.hpp +++ b/include/boost/core/ref.hpp @@ -1,15 +1,14 @@ #ifndef BOOST_CORE_REF_HPP #define BOOST_CORE_REF_HPP -// MS compatible compilers support #pragma once - -#if defined(_MSC_VER) && (_MSC_VER >= 1020) -# pragma once -#endif - #include #include #include +#include + +#if defined(BOOST_HAS_PRAGMA_ONCE) +# pragma once +#endif // // ref.hpp - ref/cref, useful helper functions @@ -46,6 +45,28 @@ namespace boost #endif +namespace detail +{ + +template< class Y, class T > struct ref_convertible +{ + typedef char (&yes) [1]; + typedef char (&no) [2]; + + static yes f( T* ); + static no f( ... ); + + enum _vt { value = sizeof( (f)( static_cast(0) ) ) == sizeof(yes) }; +}; + +#if defined(BOOST_NO_CXX11_FUNCTION_TEMPLATE_DEFAULT_ARGS) +struct ref_empty +{ +}; +#endif + +} // namespace detail + // reference_wrapper /** @@ -71,11 +92,11 @@ template class reference_wrapper @remark Does not throw. */ - BOOST_FORCEINLINE explicit reference_wrapper(T& t): t_(boost::addressof(t)) {} + BOOST_FORCEINLINE explicit reference_wrapper(T& t) BOOST_NOEXCEPT : t_(boost::addressof(t)) {} #if defined( BOOST_MSVC ) && BOOST_WORKAROUND( BOOST_MSVC, == 1600 ) - BOOST_FORCEINLINE explicit reference_wrapper( T & t, ref_workaround_tag ): t_( boost::addressof( t ) ) {} + BOOST_FORCEINLINE explicit reference_wrapper( T & t, ref_workaround_tag ) BOOST_NOEXCEPT : t_( boost::addressof( t ) ) {} #endif @@ -87,24 +108,46 @@ template class reference_wrapper public: #endif + template friend class reference_wrapper; + + /** + Constructs a `reference_wrapper` object that stores the + reference stored in the compatible `reference_wrapper` `r`. + + @remark Only enabled when `Y*` is convertible to `T*`. + @remark Does not throw. + */ +#if !defined(BOOST_NO_CXX11_FUNCTION_TEMPLATE_DEFAULT_ARGS) + template::value>::type> + reference_wrapper( reference_wrapper r ) BOOST_NOEXCEPT : t_( r.t_ ) + { + } +#else + template reference_wrapper( reference_wrapper r, + typename enable_if_c::value, + boost::detail::ref_empty>::type = boost::detail::ref_empty() ) BOOST_NOEXCEPT : t_( r.t_ ) + { + } +#endif + /** @return The stored reference. @remark Does not throw. */ - BOOST_FORCEINLINE operator T& () const { return *t_; } + BOOST_FORCEINLINE operator T& () const BOOST_NOEXCEPT { return *t_; } /** @return The stored reference. @remark Does not throw. */ - BOOST_FORCEINLINE T& get() const { return *t_; } + BOOST_FORCEINLINE T& get() const BOOST_NOEXCEPT { return *t_; } /** @return A pointer to the object referenced by the stored reference. @remark Does not throw. */ - BOOST_FORCEINLINE T* get_pointer() const { return t_; } + BOOST_FORCEINLINE T* get_pointer() const BOOST_NOEXCEPT { return t_; } private: @@ -129,7 +172,7 @@ template class reference_wrapper @return `reference_wrapper(t)` @remark Does not throw. */ -template BOOST_FORCEINLINE reference_wrapper BOOST_REF_CONST ref( T & t ) +template BOOST_FORCEINLINE reference_wrapper BOOST_REF_CONST ref( T & t ) BOOST_NOEXCEPT { #if defined( BOOST_MSVC ) && BOOST_WORKAROUND( BOOST_MSVC, == 1600 ) @@ -148,7 +191,7 @@ template BOOST_FORCEINLINE reference_wrapper BOOST_REF_CONST ref( T @return `reference_wrapper(t)` @remark Does not throw. */ -template BOOST_FORCEINLINE reference_wrapper BOOST_REF_CONST cref( T const & t ) +template BOOST_FORCEINLINE reference_wrapper BOOST_REF_CONST cref( T const & t ) BOOST_NOEXCEPT { return reference_wrapper(t); } @@ -279,7 +322,7 @@ template struct unwrap_reference< reference_wrapper const volatil @return `unwrap_reference::type&(t)` @remark Does not throw. */ -template BOOST_FORCEINLINE typename unwrap_reference::type& unwrap_ref( T & t ) +template BOOST_FORCEINLINE typename unwrap_reference::type& unwrap_ref( T & t ) BOOST_NOEXCEPT { return t; } @@ -289,7 +332,7 @@ template BOOST_FORCEINLINE typename unwrap_reference::type& unwrap_r /** @cond */ -template BOOST_FORCEINLINE T* get_pointer( reference_wrapper const & r ) +template BOOST_FORCEINLINE T* get_pointer( reference_wrapper const & r ) BOOST_NOEXCEPT { return r.get_pointer(); } diff --git a/include/boost/core/swap.hpp b/include/boost/core/swap.hpp index 49e1b2dbb..7add2fbf8 100644 --- a/include/boost/core/swap.hpp +++ b/include/boost/core/swap.hpp @@ -13,10 +13,10 @@ // - swap_impl is put outside the boost namespace, to avoid infinite // recursion (causing stack overflow) when swapping objects of a primitive // type. -// - swap_impl has a using-directive, rather than a using-declaration, -// because some compilers (including MSVC 7.1, Borland 5.9.3, and -// Intel 8.1) don't do argument-dependent lookup when it has a -// using-declaration instead. +// - std::swap is imported with a using-directive, rather than +// a using-declaration, because some compilers (including MSVC 7.1, +// Borland 5.9.3, and Intel 8.1) don't do argument-dependent lookup +// when it has a using-declaration instead. // - boost::swap has two template arguments, instead of one, to // avoid ambiguity when swapping objects of a Boost type that does // not have its own boost::swap overload. @@ -30,6 +30,17 @@ #endif #include // for std::size_t +#ifdef BOOST_HAS_PRAGMA_ONCE +#pragma once +#endif + +#if defined(BOOST_GCC) && (BOOST_GCC < 40700) +// gcc 4.6 ICEs on noexcept specifications below +#define BOOST_CORE_SWAP_NOEXCEPT_IF(x) +#else +#define BOOST_CORE_SWAP_NOEXCEPT_IF(x) BOOST_NOEXCEPT_IF(x) +#endif + namespace boost_swap_impl { // we can't use type_traits here @@ -37,17 +48,22 @@ namespace boost_swap_impl template struct is_const { enum _vt { value = 0 }; }; template struct is_const { enum _vt { value = 1 }; }; + // Use std::swap if argument dependent lookup fails. + // We need to have this at namespace scope to be able to use unqualified swap() call + // in noexcept specification. + using namespace std; + template BOOST_GPU_ENABLED - void swap_impl(T& left, T& right) + void swap_impl(T& left, T& right) BOOST_CORE_SWAP_NOEXCEPT_IF(BOOST_NOEXCEPT_EXPR(swap(left, right))) { - using namespace std;//use std::swap if argument dependent lookup fails - swap(left,right); + swap(left, right); } template BOOST_GPU_ENABLED void swap_impl(T (& left)[N], T (& right)[N]) + BOOST_CORE_SWAP_NOEXCEPT_IF(BOOST_NOEXCEPT_EXPR(::boost_swap_impl::swap_impl(left[0], right[0]))) { for (std::size_t i = 0; i < N; ++i) { @@ -62,9 +78,12 @@ namespace boost BOOST_GPU_ENABLED typename enable_if_c< !boost_swap_impl::is_const::value && !boost_swap_impl::is_const::value >::type swap(T1& left, T2& right) + BOOST_CORE_SWAP_NOEXCEPT_IF(BOOST_NOEXCEPT_EXPR(::boost_swap_impl::swap_impl(left, right))) { ::boost_swap_impl::swap_impl(left, right); } } -#endif +#undef BOOST_CORE_SWAP_NOEXCEPT_IF + +#endif // BOOST_CORE_SWAP_HPP diff --git a/include/boost/describe/bases.hpp b/include/boost/describe/bases.hpp new file mode 100644 index 000000000..b01313e04 --- /dev/null +++ b/include/boost/describe/bases.hpp @@ -0,0 +1,50 @@ +#ifndef BOOST_DESCRIBE_BASES_HPP_INCLUDED +#define BOOST_DESCRIBE_BASES_HPP_INCLUDED + +// Copyright 2020, 2021 Peter Dimov +// Distributed under the Boost Software License, Version 1.0. +// https://www.boost.org/LICENSE_1_0.txt + +#include +#include +#include + +#if defined(BOOST_DESCRIBE_CXX11) + +#include +#include + +namespace boost +{ +namespace describe +{ +namespace detail +{ + +template using _describe_bases = decltype( boost_base_descriptor_fn( static_cast(0) ) ); + +template struct base_filter +{ + template using fn = mp11::mp_bool< ( M & mod_any_access & T::modifiers ) != 0 >; +}; + +template struct has_describe_bases: std::false_type +{ +}; + +template struct has_describe_bases>>: std::true_type +{ +}; + +} // namespace detail + +template using describe_bases = mp11::mp_copy_if_q, detail::base_filter>; + +template using has_describe_bases = detail::has_describe_bases; + +} // namespace describe +} // namespace boost + +#endif // !defined(BOOST_DESCRIBE_CXX11) + +#endif // #ifndef BOOST_DESCRIBE_BASES_HPP_INCLUDED diff --git a/include/boost/describe/class.hpp b/include/boost/describe/class.hpp new file mode 100644 index 000000000..8d3fdcbd8 --- /dev/null +++ b/include/boost/describe/class.hpp @@ -0,0 +1,76 @@ +#ifndef BOOST_DESCRIBE_CLASS_HPP_INCLUDED +#define BOOST_DESCRIBE_CLASS_HPP_INCLUDED + +// Copyright 2020 Peter Dimov +// Distributed under the Boost Software License, Version 1.0. +// https://www.boost.org/LICENSE_1_0.txt + +#include + +#if !defined(BOOST_DESCRIBE_CXX14) + +#define BOOST_DESCRIBE_CLASS(C, Bases, Public, Protected, Private) +#define BOOST_DESCRIBE_STRUCT(C, Bases, Members) + +#else + +#include +#include +#include + +namespace boost +{ +namespace describe +{ + +#if defined(_MSC_VER) && !defined(__clang__) + +#define BOOST_DESCRIBE_PP_UNPACK(...) __VA_ARGS__ + +#define BOOST_DESCRIBE_CLASS(C, Bases, Public, Protected, Private) \ + friend BOOST_DESCRIBE_BASES(C, BOOST_DESCRIBE_PP_UNPACK Bases) \ + friend BOOST_DESCRIBE_PUBLIC_MEMBERS(C, BOOST_DESCRIBE_PP_UNPACK Public) \ + friend BOOST_DESCRIBE_PROTECTED_MEMBERS(C, BOOST_DESCRIBE_PP_UNPACK Protected) \ + friend BOOST_DESCRIBE_PRIVATE_MEMBERS(C, BOOST_DESCRIBE_PP_UNPACK Private) + +#define BOOST_DESCRIBE_STRUCT(C, Bases, Members) \ + static_assert(std::is_class::value || std::is_union::value, "BOOST_DESCRIBE_STRUCT should only be used with class types"); \ + BOOST_DESCRIBE_BASES(C, BOOST_DESCRIBE_PP_UNPACK Bases) \ + BOOST_DESCRIBE_PUBLIC_MEMBERS(C, BOOST_DESCRIBE_PP_UNPACK Members) \ + BOOST_DESCRIBE_PROTECTED_MEMBERS(C) \ + BOOST_DESCRIBE_PRIVATE_MEMBERS(C) + +#else + +#if defined(__GNUC__) && __GNUC__ >= 8 +# define BOOST_DESCRIBE_PP_UNPACK(...) __VA_OPT__(,) __VA_ARGS__ +#else +# define BOOST_DESCRIBE_PP_UNPACK(...) , ##__VA_ARGS__ +#endif + +#define BOOST_DESCRIBE_BASES_(...) BOOST_DESCRIBE_BASES(__VA_ARGS__) +#define BOOST_DESCRIBE_PUBLIC_MEMBERS_(...) BOOST_DESCRIBE_PUBLIC_MEMBERS(__VA_ARGS__) +#define BOOST_DESCRIBE_PROTECTED_MEMBERS_(...) BOOST_DESCRIBE_PROTECTED_MEMBERS(__VA_ARGS__) +#define BOOST_DESCRIBE_PRIVATE_MEMBERS_(...) BOOST_DESCRIBE_PRIVATE_MEMBERS(__VA_ARGS__) + +#define BOOST_DESCRIBE_CLASS(C, Bases, Public, Protected, Private) \ + BOOST_DESCRIBE_MAYBE_UNUSED friend BOOST_DESCRIBE_BASES_(C BOOST_DESCRIBE_PP_UNPACK Bases) \ + BOOST_DESCRIBE_MAYBE_UNUSED friend BOOST_DESCRIBE_PUBLIC_MEMBERS_(C BOOST_DESCRIBE_PP_UNPACK Public) \ + BOOST_DESCRIBE_MAYBE_UNUSED friend BOOST_DESCRIBE_PROTECTED_MEMBERS_(C BOOST_DESCRIBE_PP_UNPACK Protected) \ + BOOST_DESCRIBE_MAYBE_UNUSED friend BOOST_DESCRIBE_PRIVATE_MEMBERS_(C BOOST_DESCRIBE_PP_UNPACK Private) + +#define BOOST_DESCRIBE_STRUCT(C, Bases, Members) \ + static_assert(std::is_class::value || std::is_union::value, "BOOST_DESCRIBE_STRUCT should only be used with class types"); \ + BOOST_DESCRIBE_MAYBE_UNUSED BOOST_DESCRIBE_BASES_(C BOOST_DESCRIBE_PP_UNPACK Bases) \ + BOOST_DESCRIBE_MAYBE_UNUSED BOOST_DESCRIBE_PUBLIC_MEMBERS_(C BOOST_DESCRIBE_PP_UNPACK Members) \ + BOOST_DESCRIBE_MAYBE_UNUSED BOOST_DESCRIBE_PROTECTED_MEMBERS_(C) \ + BOOST_DESCRIBE_MAYBE_UNUSED BOOST_DESCRIBE_PRIVATE_MEMBERS_(C) + +#endif + +} // namespace describe +} // namespace boost + +#endif // !defined(BOOST_DESCRIBE_CXX14) + +#endif // #ifndef BOOST_DESCRIBE_CLASS_HPP_INCLUDED diff --git a/include/boost/describe/descriptor_by_name.hpp b/include/boost/describe/descriptor_by_name.hpp new file mode 100644 index 000000000..141f4649e --- /dev/null +++ b/include/boost/describe/descriptor_by_name.hpp @@ -0,0 +1,41 @@ +#ifndef BOOST_DESCRIBE_DESCRIPTOR_BY_NAME_HPP_INCLUDED +#define BOOST_DESCRIBE_DESCRIPTOR_BY_NAME_HPP_INCLUDED + +// Copyright 2021 Peter Dimov +// Distributed under the Boost Software License, Version 1.0. +// https://www.boost.org/LICENSE_1_0.txt + +#include +#include + +#if defined(BOOST_DESCRIBE_CXX14) + +#include +#include +#include + +namespace boost +{ +namespace describe +{ + +namespace detail +{ + +template using match_by_name = mp11::mp_bool; + +#define BOOST_DESCRIBE_MAKE_NAME_IMPL2(s, k) struct _boost_name_##s##_##k { static constexpr char const * name() { return #s; } } +#define BOOST_DESCRIBE_MAKE_NAME_IMPL(s, k) BOOST_DESCRIBE_MAKE_NAME_IMPL2(s, k) + +} // namespace detail + +#define BOOST_DESCRIBE_MAKE_NAME(s) BOOST_DESCRIBE_MAKE_NAME_IMPL(s, __LINE__) + +template using descriptor_by_name = mp11::mp_at>>; + +} // namespace describe +} // namespace boost + +#endif // defined(BOOST_DESCRIBE_CXX14) + +#endif // #ifndef BOOST_DESCRIBE_DESCRIPTOR_BY_NAME_HPP_INCLUDED diff --git a/include/boost/describe/descriptor_by_pointer.hpp b/include/boost/describe/descriptor_by_pointer.hpp new file mode 100644 index 000000000..9ef31a191 --- /dev/null +++ b/include/boost/describe/descriptor_by_pointer.hpp @@ -0,0 +1,48 @@ +#ifndef BOOST_DESCRIBE_DESCRIPTOR_BY_POINTER_HPP_INCLUDED +#define BOOST_DESCRIBE_DESCRIPTOR_BY_POINTER_HPP_INCLUDED + +// Copyright 2021 Peter Dimov +// Distributed under the Boost Software License, Version 1.0. +// https://www.boost.org/LICENSE_1_0.txt + +#include + +#if defined(__cpp_nontype_template_parameter_auto) && __cpp_nontype_template_parameter_auto >= 201606L + +#include +#include +#include + +namespace boost +{ +namespace describe +{ + +namespace detail +{ + +template constexpr bool cx_pmeq( Pm p1, Pm p2 ) +{ + return p1 == p2; +} + +template constexpr bool cx_pmeq( Pm1, Pm2 ) +{ + return false; +} + +template struct match_by_pointer +{ + template using fn = mp11::mp_bool< cx_pmeq( D::pointer, Pm ) >; +}; + +} // namespace detail + +template using descriptor_by_pointer = mp11::mp_at>>; + +} // namespace describe +} // namespace boost + +#endif // __cpp_nontype_template_parameter_auto + +#endif // #ifndef BOOST_DESCRIBE_DESCRIPTOR_BY_POINTER_HPP_INCLUDED diff --git a/include/boost/describe/detail/bases.hpp b/include/boost/describe/detail/bases.hpp new file mode 100644 index 000000000..3a08064d4 --- /dev/null +++ b/include/boost/describe/detail/bases.hpp @@ -0,0 +1,56 @@ +#ifndef BOOST_DESCRIBE_DETAIL_BASES_HPP_INCLUDED +#define BOOST_DESCRIBE_DETAIL_BASES_HPP_INCLUDED + +// Copyright 2020 Peter Dimov +// Distributed under the Boost Software License, Version 1.0. +// https://www.boost.org/LICENSE_1_0.txt + +#include +#include +#include +#include + +namespace boost +{ +namespace describe +{ +namespace detail +{ + +// base_descriptor +template struct base_descriptor +{ + static_assert( std::is_base_of::value, "A type listed as a base is not one" ); + + using type = B; + static constexpr unsigned modifiers = compute_base_modifiers(); +}; + +#ifndef __cpp_inline_variables +template constexpr unsigned base_descriptor::modifiers; +#endif + +template auto base_descriptor_fn_impl( int, T... ) +{ + return list(); +} + +#define BOOST_DESCRIBE_BASE_IMPL(C, B) , boost::describe::detail::base_descriptor() + +#if defined(_MSC_VER) && !defined(__clang__) + +#define BOOST_DESCRIBE_BASES(C, ...) inline auto boost_base_descriptor_fn( C** ) \ +{ return boost::describe::detail::base_descriptor_fn_impl( 0 BOOST_DESCRIBE_PP_FOR_EACH(BOOST_DESCRIBE_BASE_IMPL, C, __VA_ARGS__) ); } + +#else + +#define BOOST_DESCRIBE_BASES(C, ...) inline auto boost_base_descriptor_fn( C** ) \ +{ return boost::describe::detail::base_descriptor_fn_impl( 0 BOOST_DESCRIBE_PP_FOR_EACH(BOOST_DESCRIBE_BASE_IMPL, C, ##__VA_ARGS__) ); } + +#endif + +} // namespace detail +} // namespace describe +} // namespace boost + +#endif // #ifndef BOOST_DESCRIBE_DETAIL_BASES_HPP_INCLUDED diff --git a/include/boost/describe/detail/compute_base_modifiers.hpp b/include/boost/describe/detail/compute_base_modifiers.hpp new file mode 100644 index 000000000..7da2cf245 --- /dev/null +++ b/include/boost/describe/detail/compute_base_modifiers.hpp @@ -0,0 +1,73 @@ +#ifndef BOOST_DESCRIBE_DETAIL_COMPUTE_BASE_MODIFIERS_HPP_INCLUDED +#define BOOST_DESCRIBE_DETAIL_COMPUTE_BASE_MODIFIERS_HPP_INCLUDED + +// Copyright 2020, 2021 Peter Dimov +// Distributed under the Boost Software License, Version 1.0. +// https://www.boost.org/LICENSE_1_0.txt + +#include +#include + +namespace boost +{ +namespace describe +{ +namespace detail +{ + +#if defined(_MSC_VER) +# pragma warning(push) +# pragma warning(disable: 4594) // can never be instantiated - indirect virtual base class is inaccessible +# pragma warning(disable: 4624) // destructor was implicitly defined as deleted +#endif + +// is_public_base_of + +template using is_public_base_of = std::is_convertible; + +// is_protected_base_of + +struct ipb_final +{ + template using fn = std::false_type; +}; + +struct ipb_non_final +{ + template struct fn: U + { + static std::true_type f( T* ); + + template static auto g( X x ) -> decltype( f(x) ); + static std::false_type g( ... ); + + using type = decltype( g((U*)0) ); + }; +}; + +template using is_protected_base_of = + typename std::conditional::value || std::is_union::value, ipb_final, ipb_non_final>::type::template fn::type; + +// is_virtual_base_of + +template struct can_cast: std::false_type {}; +template struct can_cast: std::true_type {}; + +template using is_virtual_base_of = + std::integral_constant::value && !can_cast::value>; + +// compute_base_modifiers +template constexpr unsigned compute_base_modifiers() noexcept +{ + return (is_public_base_of::value? mod_public: (is_protected_base_of::value? mod_protected: mod_private)) | (is_virtual_base_of::value? mod_virtual: 0); +} + +#if defined(_MSC_VER) +# pragma warning(pop) +#endif + +} // namespace detail +} // namespace describe +} // namespace boost + +#endif // #ifndef BOOST_DESCRIBE_DETAIL_COMPUTE_BASE_MODIFIERS_HPP_INCLUDED diff --git a/include/boost/describe/detail/config.hpp b/include/boost/describe/detail/config.hpp new file mode 100644 index 000000000..c24a070e3 --- /dev/null +++ b/include/boost/describe/detail/config.hpp @@ -0,0 +1,40 @@ +#ifndef BOOST_DESCRIBE_DETAIL_CONFIG_HPP_INCLUDED +#define BOOST_DESCRIBE_DETAIL_CONFIG_HPP_INCLUDED + +// Copyright 2021 Peter Dimov +// Distributed under the Boost Software License, Version 1.0. +// https://www.boost.org/LICENSE_1_0.txt + +#if __cplusplus >= 201402L + +# define BOOST_DESCRIBE_CXX14 +# define BOOST_DESCRIBE_CXX11 + +#elif defined(_MSC_VER) && _MSC_VER >= 1900 + +# define BOOST_DESCRIBE_CXX14 +# define BOOST_DESCRIBE_CXX11 + +#elif __cplusplus >= 201103L + +# define BOOST_DESCRIBE_CXX11 + +# if defined(__GNUC__) && __GNUC__ == 4 && __GNUC_MINOR__ == 7 +# undef BOOST_DESCRIBE_CXX11 +# endif + +#endif + +#if defined(BOOST_DESCRIBE_CXX11) +# define BOOST_DESCRIBE_CONSTEXPR_OR_CONST constexpr +#else +# define BOOST_DESCRIBE_CONSTEXPR_OR_CONST const +#endif + +#if defined(__clang__) +# define BOOST_DESCRIBE_MAYBE_UNUSED __attribute__((unused)) +#else +# define BOOST_DESCRIBE_MAYBE_UNUSED +#endif + +#endif // #ifndef BOOST_DESCRIBE_DETAIL_CONFIG_HPP_INCLUDED diff --git a/include/boost/describe/detail/cx_streq.hpp b/include/boost/describe/detail/cx_streq.hpp new file mode 100644 index 000000000..15e87dc27 --- /dev/null +++ b/include/boost/describe/detail/cx_streq.hpp @@ -0,0 +1,30 @@ +#ifndef BOOST_DESCRIBE_DETAIL_CX_STREQ_HPP_INCLUDED +#define BOOST_DESCRIBE_DETAIL_CX_STREQ_HPP_INCLUDED + +// Copyright 2021 Peter Dimov +// Distributed under the Boost Software License, Version 1.0. +// https://www.boost.org/LICENSE_1_0.txt + +#include + +#if defined(BOOST_DESCRIBE_CXX11) + +namespace boost +{ +namespace describe +{ +namespace detail +{ + +constexpr bool cx_streq( char const * s1, char const * s2 ) +{ + return s1[0] == s2[0] && ( s1[0] == 0 || cx_streq( s1 + 1, s2 + 1 ) ); +} + +} // namespace detail +} // namespace describe +} // namespace boost + +#endif // defined(BOOST_DESCRIBE_CXX11) + +#endif // #ifndef BOOST_DESCRIBE_DETAIL_CX_STREQ_HPP_INCLUDED diff --git a/include/boost/describe/detail/list.hpp b/include/boost/describe/detail/list.hpp new file mode 100644 index 000000000..0b2089221 --- /dev/null +++ b/include/boost/describe/detail/list.hpp @@ -0,0 +1,27 @@ +#ifndef BOOST_DESCRIBE_DETAIL_LIST_HPP_INCLUDED +#define BOOST_DESCRIBE_DETAIL_LIST_HPP_INCLUDED + +// Copyright 2020 Peter Dimov +// Distributed under the Boost Software License, Version 1.0. +// https://www.boost.org/LICENSE_1_0.txt + +#include + +#if defined(BOOST_DESCRIBE_CXX11) + +namespace boost +{ +namespace describe +{ +namespace detail +{ + +template struct list {}; + +} // namespace detail +} // namespace describe +} // namespace boost + +#endif // defined(BOOST_DESCRIBE_CXX11) + +#endif // #ifndef BOOST_DESCRIBE_DETAIL_LIST_HPP_INCLUDED diff --git a/include/boost/describe/detail/members.hpp b/include/boost/describe/detail/members.hpp new file mode 100644 index 000000000..8be5387fe --- /dev/null +++ b/include/boost/describe/detail/members.hpp @@ -0,0 +1,84 @@ +#ifndef BOOST_DESCRIBE_DETAIL_MEMBERS_HPP_INCLUDED +#define BOOST_DESCRIBE_DETAIL_MEMBERS_HPP_INCLUDED + +// Copyright 2020 Peter Dimov +// Distributed under the Boost Software License, Version 1.0. +// https://www.boost.org/LICENSE_1_0.txt + +#include +#include +#include +#include +#include + +namespace boost +{ +namespace describe +{ +namespace detail +{ + +template constexpr unsigned add_static_modifier( Pm ) +{ + return std::is_member_pointer::value? 0: mod_static; +} + +template constexpr unsigned add_function_modifier( Pm ) +{ + return std::is_member_function_pointer::value || std::is_function< std::remove_pointer_t >::value? mod_function: 0; +} + +template struct member_descriptor +{ + static constexpr decltype(D::pointer()) pointer = D::pointer(); + static constexpr decltype(D::name()) name = D::name(); + static constexpr unsigned modifiers = M | add_static_modifier( D::pointer() ) | add_function_modifier( D::pointer() ); +}; + +#ifndef __cpp_inline_variables +template constexpr decltype(D::pointer()) member_descriptor::pointer; +template constexpr decltype(D::name()) member_descriptor::name; +template constexpr unsigned member_descriptor::modifiers; +#endif + +template auto member_descriptor_fn_impl( int, T... ) +{ + return list...>(); +} + +template constexpr auto mfn( F C::* p ) { return p; } +template constexpr auto mfn( F * p ) { return p; } + +#define BOOST_DESCRIBE_MEMBER_IMPL(C, m) , []{ struct _boost_desc { \ + static constexpr auto pointer() noexcept { return BOOST_DESCRIBE_PP_POINTER(C, m); } \ + static constexpr auto name() noexcept { return BOOST_DESCRIBE_PP_NAME(m); } }; return _boost_desc(); }() + +#if defined(_MSC_VER) && !defined(__clang__) + +#define BOOST_DESCRIBE_PUBLIC_MEMBERS(C, ...) inline auto boost_public_member_descriptor_fn( C** ) \ +{ return boost::describe::detail::member_descriptor_fn_impl( 0 BOOST_DESCRIBE_PP_FOR_EACH(BOOST_DESCRIBE_MEMBER_IMPL, C, __VA_ARGS__) ); } + +#define BOOST_DESCRIBE_PROTECTED_MEMBERS(C, ...) inline auto boost_protected_member_descriptor_fn( C** ) \ +{ return boost::describe::detail::member_descriptor_fn_impl( 0 BOOST_DESCRIBE_PP_FOR_EACH(BOOST_DESCRIBE_MEMBER_IMPL, C, __VA_ARGS__) ); } + +#define BOOST_DESCRIBE_PRIVATE_MEMBERS(C, ...) inline auto boost_private_member_descriptor_fn( C** ) \ +{ return boost::describe::detail::member_descriptor_fn_impl( 0 BOOST_DESCRIBE_PP_FOR_EACH(BOOST_DESCRIBE_MEMBER_IMPL, C, __VA_ARGS__) ); } + +#else + +#define BOOST_DESCRIBE_PUBLIC_MEMBERS(C, ...) inline auto boost_public_member_descriptor_fn( C** ) \ +{ return boost::describe::detail::member_descriptor_fn_impl( 0 BOOST_DESCRIBE_PP_FOR_EACH(BOOST_DESCRIBE_MEMBER_IMPL, C, ##__VA_ARGS__) ); } + +#define BOOST_DESCRIBE_PROTECTED_MEMBERS(C, ...) inline auto boost_protected_member_descriptor_fn( C** ) \ +{ return boost::describe::detail::member_descriptor_fn_impl( 0 BOOST_DESCRIBE_PP_FOR_EACH(BOOST_DESCRIBE_MEMBER_IMPL, C, ##__VA_ARGS__) ); } + +#define BOOST_DESCRIBE_PRIVATE_MEMBERS(C, ...) inline auto boost_private_member_descriptor_fn( C** ) \ +{ return boost::describe::detail::member_descriptor_fn_impl( 0 BOOST_DESCRIBE_PP_FOR_EACH(BOOST_DESCRIBE_MEMBER_IMPL, C, ##__VA_ARGS__) ); } + +#endif + +} // namespace detail +} // namespace describe +} // namespace boost + +#endif // #ifndef BOOST_DESCRIBE_DETAIL_MEMBERS_HPP_INCLUDED diff --git a/include/boost/describe/detail/pp_for_each.hpp b/include/boost/describe/detail/pp_for_each.hpp new file mode 100644 index 000000000..ab1287f82 --- /dev/null +++ b/include/boost/describe/detail/pp_for_each.hpp @@ -0,0 +1,122 @@ +#ifndef BOOST_DESCRIBE_DETAIL_PP_FOR_EACH_HPP_INCLUDED +#define BOOST_DESCRIBE_DETAIL_PP_FOR_EACH_HPP_INCLUDED + +// Copyright 2020 Peter Dimov +// Distributed under the Boost Software License, Version 1.0. +// https://www.boost.org/LICENSE_1_0.txt + +#include + +#define BOOST_DESCRIBE_PP_FOR_EACH_0(F, a) +#define BOOST_DESCRIBE_PP_FOR_EACH_1(F, a, x) BOOST_DESCRIBE_PP_CALL(F, a, x) +#define BOOST_DESCRIBE_PP_FOR_EACH_2(F, a, x, ...) BOOST_DESCRIBE_PP_EXPAND(BOOST_DESCRIBE_PP_CALL(F, a, x) BOOST_DESCRIBE_PP_FOR_EACH_1(F, a, __VA_ARGS__)) +#define BOOST_DESCRIBE_PP_FOR_EACH_3(F, a, x, ...) BOOST_DESCRIBE_PP_EXPAND(BOOST_DESCRIBE_PP_CALL(F, a, x) BOOST_DESCRIBE_PP_FOR_EACH_2(F, a, __VA_ARGS__)) +#define BOOST_DESCRIBE_PP_FOR_EACH_4(F, a, x, ...) BOOST_DESCRIBE_PP_EXPAND(BOOST_DESCRIBE_PP_CALL(F, a, x) BOOST_DESCRIBE_PP_FOR_EACH_3(F, a, __VA_ARGS__)) +#define BOOST_DESCRIBE_PP_FOR_EACH_5(F, a, x, ...) BOOST_DESCRIBE_PP_EXPAND(BOOST_DESCRIBE_PP_CALL(F, a, x) BOOST_DESCRIBE_PP_FOR_EACH_4(F, a, __VA_ARGS__)) +#define BOOST_DESCRIBE_PP_FOR_EACH_6(F, a, x, ...) BOOST_DESCRIBE_PP_EXPAND(BOOST_DESCRIBE_PP_CALL(F, a, x) BOOST_DESCRIBE_PP_FOR_EACH_5(F, a, __VA_ARGS__)) +#define BOOST_DESCRIBE_PP_FOR_EACH_7(F, a, x, ...) BOOST_DESCRIBE_PP_EXPAND(BOOST_DESCRIBE_PP_CALL(F, a, x) BOOST_DESCRIBE_PP_FOR_EACH_6(F, a, __VA_ARGS__)) +#define BOOST_DESCRIBE_PP_FOR_EACH_8(F, a, x, ...) BOOST_DESCRIBE_PP_EXPAND(BOOST_DESCRIBE_PP_CALL(F, a, x) BOOST_DESCRIBE_PP_FOR_EACH_7(F, a, __VA_ARGS__)) +#define BOOST_DESCRIBE_PP_FOR_EACH_9(F, a, x, ...) BOOST_DESCRIBE_PP_EXPAND(BOOST_DESCRIBE_PP_CALL(F, a, x) BOOST_DESCRIBE_PP_FOR_EACH_8(F, a, __VA_ARGS__)) +#define BOOST_DESCRIBE_PP_FOR_EACH_10(F, a, x, ...) BOOST_DESCRIBE_PP_EXPAND(BOOST_DESCRIBE_PP_CALL(F, a, x) BOOST_DESCRIBE_PP_FOR_EACH_9(F, a, __VA_ARGS__)) +#define BOOST_DESCRIBE_PP_FOR_EACH_11(F, a, x, ...) BOOST_DESCRIBE_PP_EXPAND(BOOST_DESCRIBE_PP_CALL(F, a, x) BOOST_DESCRIBE_PP_FOR_EACH_10(F, a, __VA_ARGS__)) +#define BOOST_DESCRIBE_PP_FOR_EACH_12(F, a, x, ...) BOOST_DESCRIBE_PP_EXPAND(BOOST_DESCRIBE_PP_CALL(F, a, x) BOOST_DESCRIBE_PP_FOR_EACH_11(F, a, __VA_ARGS__)) +#define BOOST_DESCRIBE_PP_FOR_EACH_13(F, a, x, ...) BOOST_DESCRIBE_PP_EXPAND(BOOST_DESCRIBE_PP_CALL(F, a, x) BOOST_DESCRIBE_PP_FOR_EACH_12(F, a, __VA_ARGS__)) +#define BOOST_DESCRIBE_PP_FOR_EACH_14(F, a, x, ...) BOOST_DESCRIBE_PP_EXPAND(BOOST_DESCRIBE_PP_CALL(F, a, x) BOOST_DESCRIBE_PP_FOR_EACH_13(F, a, __VA_ARGS__)) +#define BOOST_DESCRIBE_PP_FOR_EACH_15(F, a, x, ...) BOOST_DESCRIBE_PP_EXPAND(BOOST_DESCRIBE_PP_CALL(F, a, x) BOOST_DESCRIBE_PP_FOR_EACH_14(F, a, __VA_ARGS__)) +#define BOOST_DESCRIBE_PP_FOR_EACH_16(F, a, x, ...) BOOST_DESCRIBE_PP_EXPAND(BOOST_DESCRIBE_PP_CALL(F, a, x) BOOST_DESCRIBE_PP_FOR_EACH_15(F, a, __VA_ARGS__)) +#define BOOST_DESCRIBE_PP_FOR_EACH_17(F, a, x, ...) BOOST_DESCRIBE_PP_EXPAND(BOOST_DESCRIBE_PP_CALL(F, a, x) BOOST_DESCRIBE_PP_FOR_EACH_16(F, a, __VA_ARGS__)) +#define BOOST_DESCRIBE_PP_FOR_EACH_18(F, a, x, ...) BOOST_DESCRIBE_PP_EXPAND(BOOST_DESCRIBE_PP_CALL(F, a, x) BOOST_DESCRIBE_PP_FOR_EACH_17(F, a, __VA_ARGS__)) +#define BOOST_DESCRIBE_PP_FOR_EACH_19(F, a, x, ...) BOOST_DESCRIBE_PP_EXPAND(BOOST_DESCRIBE_PP_CALL(F, a, x) BOOST_DESCRIBE_PP_FOR_EACH_18(F, a, __VA_ARGS__)) +#define BOOST_DESCRIBE_PP_FOR_EACH_20(F, a, x, ...) BOOST_DESCRIBE_PP_EXPAND(BOOST_DESCRIBE_PP_CALL(F, a, x) BOOST_DESCRIBE_PP_FOR_EACH_19(F, a, __VA_ARGS__)) +#define BOOST_DESCRIBE_PP_FOR_EACH_21(F, a, x, ...) BOOST_DESCRIBE_PP_EXPAND(BOOST_DESCRIBE_PP_CALL(F, a, x) BOOST_DESCRIBE_PP_FOR_EACH_20(F, a, __VA_ARGS__)) +#define BOOST_DESCRIBE_PP_FOR_EACH_22(F, a, x, ...) BOOST_DESCRIBE_PP_EXPAND(BOOST_DESCRIBE_PP_CALL(F, a, x) BOOST_DESCRIBE_PP_FOR_EACH_21(F, a, __VA_ARGS__)) +#define BOOST_DESCRIBE_PP_FOR_EACH_23(F, a, x, ...) BOOST_DESCRIBE_PP_EXPAND(BOOST_DESCRIBE_PP_CALL(F, a, x) BOOST_DESCRIBE_PP_FOR_EACH_22(F, a, __VA_ARGS__)) +#define BOOST_DESCRIBE_PP_FOR_EACH_24(F, a, x, ...) BOOST_DESCRIBE_PP_EXPAND(BOOST_DESCRIBE_PP_CALL(F, a, x) BOOST_DESCRIBE_PP_FOR_EACH_23(F, a, __VA_ARGS__)) +#define BOOST_DESCRIBE_PP_FOR_EACH_25(F, a, x, ...) BOOST_DESCRIBE_PP_EXPAND(BOOST_DESCRIBE_PP_CALL(F, a, x) BOOST_DESCRIBE_PP_FOR_EACH_24(F, a, __VA_ARGS__)) +#define BOOST_DESCRIBE_PP_FOR_EACH_26(F, a, x, ...) BOOST_DESCRIBE_PP_EXPAND(BOOST_DESCRIBE_PP_CALL(F, a, x) BOOST_DESCRIBE_PP_FOR_EACH_25(F, a, __VA_ARGS__)) +#define BOOST_DESCRIBE_PP_FOR_EACH_27(F, a, x, ...) BOOST_DESCRIBE_PP_EXPAND(BOOST_DESCRIBE_PP_CALL(F, a, x) BOOST_DESCRIBE_PP_FOR_EACH_26(F, a, __VA_ARGS__)) +#define BOOST_DESCRIBE_PP_FOR_EACH_28(F, a, x, ...) BOOST_DESCRIBE_PP_EXPAND(BOOST_DESCRIBE_PP_CALL(F, a, x) BOOST_DESCRIBE_PP_FOR_EACH_27(F, a, __VA_ARGS__)) +#define BOOST_DESCRIBE_PP_FOR_EACH_29(F, a, x, ...) BOOST_DESCRIBE_PP_EXPAND(BOOST_DESCRIBE_PP_CALL(F, a, x) BOOST_DESCRIBE_PP_FOR_EACH_28(F, a, __VA_ARGS__)) +#define BOOST_DESCRIBE_PP_FOR_EACH_30(F, a, x, ...) BOOST_DESCRIBE_PP_EXPAND(BOOST_DESCRIBE_PP_CALL(F, a, x) BOOST_DESCRIBE_PP_FOR_EACH_29(F, a, __VA_ARGS__)) +#define BOOST_DESCRIBE_PP_FOR_EACH_31(F, a, x, ...) BOOST_DESCRIBE_PP_EXPAND(BOOST_DESCRIBE_PP_CALL(F, a, x) BOOST_DESCRIBE_PP_FOR_EACH_30(F, a, __VA_ARGS__)) +#define BOOST_DESCRIBE_PP_FOR_EACH_32(F, a, x, ...) BOOST_DESCRIBE_PP_EXPAND(BOOST_DESCRIBE_PP_CALL(F, a, x) BOOST_DESCRIBE_PP_FOR_EACH_31(F, a, __VA_ARGS__)) +#define BOOST_DESCRIBE_PP_FOR_EACH_33(F, a, x, ...) BOOST_DESCRIBE_PP_EXPAND(BOOST_DESCRIBE_PP_CALL(F, a, x) BOOST_DESCRIBE_PP_FOR_EACH_32(F, a, __VA_ARGS__)) +#define BOOST_DESCRIBE_PP_FOR_EACH_34(F, a, x, ...) BOOST_DESCRIBE_PP_EXPAND(BOOST_DESCRIBE_PP_CALL(F, a, x) BOOST_DESCRIBE_PP_FOR_EACH_33(F, a, __VA_ARGS__)) +#define BOOST_DESCRIBE_PP_FOR_EACH_35(F, a, x, ...) BOOST_DESCRIBE_PP_EXPAND(BOOST_DESCRIBE_PP_CALL(F, a, x) BOOST_DESCRIBE_PP_FOR_EACH_34(F, a, __VA_ARGS__)) +#define BOOST_DESCRIBE_PP_FOR_EACH_36(F, a, x, ...) BOOST_DESCRIBE_PP_EXPAND(BOOST_DESCRIBE_PP_CALL(F, a, x) BOOST_DESCRIBE_PP_FOR_EACH_35(F, a, __VA_ARGS__)) +#define BOOST_DESCRIBE_PP_FOR_EACH_37(F, a, x, ...) BOOST_DESCRIBE_PP_EXPAND(BOOST_DESCRIBE_PP_CALL(F, a, x) BOOST_DESCRIBE_PP_FOR_EACH_36(F, a, __VA_ARGS__)) +#define BOOST_DESCRIBE_PP_FOR_EACH_38(F, a, x, ...) BOOST_DESCRIBE_PP_EXPAND(BOOST_DESCRIBE_PP_CALL(F, a, x) BOOST_DESCRIBE_PP_FOR_EACH_37(F, a, __VA_ARGS__)) +#define BOOST_DESCRIBE_PP_FOR_EACH_39(F, a, x, ...) BOOST_DESCRIBE_PP_EXPAND(BOOST_DESCRIBE_PP_CALL(F, a, x) BOOST_DESCRIBE_PP_FOR_EACH_38(F, a, __VA_ARGS__)) +#define BOOST_DESCRIBE_PP_FOR_EACH_40(F, a, x, ...) BOOST_DESCRIBE_PP_EXPAND(BOOST_DESCRIBE_PP_CALL(F, a, x) BOOST_DESCRIBE_PP_FOR_EACH_39(F, a, __VA_ARGS__)) +#define BOOST_DESCRIBE_PP_FOR_EACH_41(F, a, x, ...) BOOST_DESCRIBE_PP_EXPAND(BOOST_DESCRIBE_PP_CALL(F, a, x) BOOST_DESCRIBE_PP_FOR_EACH_40(F, a, __VA_ARGS__)) +#define BOOST_DESCRIBE_PP_FOR_EACH_42(F, a, x, ...) BOOST_DESCRIBE_PP_EXPAND(BOOST_DESCRIBE_PP_CALL(F, a, x) BOOST_DESCRIBE_PP_FOR_EACH_41(F, a, __VA_ARGS__)) +#define BOOST_DESCRIBE_PP_FOR_EACH_43(F, a, x, ...) BOOST_DESCRIBE_PP_EXPAND(BOOST_DESCRIBE_PP_CALL(F, a, x) BOOST_DESCRIBE_PP_FOR_EACH_42(F, a, __VA_ARGS__)) +#define BOOST_DESCRIBE_PP_FOR_EACH_44(F, a, x, ...) BOOST_DESCRIBE_PP_EXPAND(BOOST_DESCRIBE_PP_CALL(F, a, x) BOOST_DESCRIBE_PP_FOR_EACH_43(F, a, __VA_ARGS__)) +#define BOOST_DESCRIBE_PP_FOR_EACH_45(F, a, x, ...) BOOST_DESCRIBE_PP_EXPAND(BOOST_DESCRIBE_PP_CALL(F, a, x) BOOST_DESCRIBE_PP_FOR_EACH_44(F, a, __VA_ARGS__)) +#define BOOST_DESCRIBE_PP_FOR_EACH_46(F, a, x, ...) BOOST_DESCRIBE_PP_EXPAND(BOOST_DESCRIBE_PP_CALL(F, a, x) BOOST_DESCRIBE_PP_FOR_EACH_45(F, a, __VA_ARGS__)) +#define BOOST_DESCRIBE_PP_FOR_EACH_47(F, a, x, ...) BOOST_DESCRIBE_PP_EXPAND(BOOST_DESCRIBE_PP_CALL(F, a, x) BOOST_DESCRIBE_PP_FOR_EACH_46(F, a, __VA_ARGS__)) +#define BOOST_DESCRIBE_PP_FOR_EACH_48(F, a, x, ...) BOOST_DESCRIBE_PP_EXPAND(BOOST_DESCRIBE_PP_CALL(F, a, x) BOOST_DESCRIBE_PP_FOR_EACH_47(F, a, __VA_ARGS__)) +#define BOOST_DESCRIBE_PP_FOR_EACH_49(F, a, x, ...) BOOST_DESCRIBE_PP_EXPAND(BOOST_DESCRIBE_PP_CALL(F, a, x) BOOST_DESCRIBE_PP_FOR_EACH_48(F, a, __VA_ARGS__)) +#define BOOST_DESCRIBE_PP_FOR_EACH_50(F, a, x, ...) BOOST_DESCRIBE_PP_EXPAND(BOOST_DESCRIBE_PP_CALL(F, a, x) BOOST_DESCRIBE_PP_FOR_EACH_49(F, a, __VA_ARGS__)) +#define BOOST_DESCRIBE_PP_FOR_EACH_51(F, a, x, ...) BOOST_DESCRIBE_PP_EXPAND(BOOST_DESCRIBE_PP_CALL(F, a, x) BOOST_DESCRIBE_PP_FOR_EACH_50(F, a, __VA_ARGS__)) +#define BOOST_DESCRIBE_PP_FOR_EACH_52(F, a, x, ...) BOOST_DESCRIBE_PP_EXPAND(BOOST_DESCRIBE_PP_CALL(F, a, x) BOOST_DESCRIBE_PP_FOR_EACH_51(F, a, __VA_ARGS__)) + +#define BOOST_DESCRIBE_PP_FE_EXTRACT(_0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16, _17, _18, _19, _20, _21, _22, _23, _24, _25, _26, _27, _28, _29, _30, _31, _32, _33, _34, _35, _36, _37, _38, _39, _40, _41, _42, _43, _44, _45, _46, _47, _48, _49, _50, _51, _52, V, ...) V + +#define BOOST_DESCRIBE_PP_FOR_EACH(F, ...) \ + BOOST_DESCRIBE_PP_EXPAND(BOOST_DESCRIBE_PP_EXPAND(BOOST_DESCRIBE_PP_FE_EXTRACT(__VA_ARGS__, \ + BOOST_DESCRIBE_PP_FOR_EACH_52, \ + BOOST_DESCRIBE_PP_FOR_EACH_51, \ + BOOST_DESCRIBE_PP_FOR_EACH_50, \ + BOOST_DESCRIBE_PP_FOR_EACH_49, \ + BOOST_DESCRIBE_PP_FOR_EACH_48, \ + BOOST_DESCRIBE_PP_FOR_EACH_47, \ + BOOST_DESCRIBE_PP_FOR_EACH_46, \ + BOOST_DESCRIBE_PP_FOR_EACH_45, \ + BOOST_DESCRIBE_PP_FOR_EACH_44, \ + BOOST_DESCRIBE_PP_FOR_EACH_43, \ + BOOST_DESCRIBE_PP_FOR_EACH_42, \ + BOOST_DESCRIBE_PP_FOR_EACH_41, \ + BOOST_DESCRIBE_PP_FOR_EACH_40, \ + BOOST_DESCRIBE_PP_FOR_EACH_39, \ + BOOST_DESCRIBE_PP_FOR_EACH_38, \ + BOOST_DESCRIBE_PP_FOR_EACH_37, \ + BOOST_DESCRIBE_PP_FOR_EACH_36, \ + BOOST_DESCRIBE_PP_FOR_EACH_35, \ + BOOST_DESCRIBE_PP_FOR_EACH_34, \ + BOOST_DESCRIBE_PP_FOR_EACH_33, \ + BOOST_DESCRIBE_PP_FOR_EACH_32, \ + BOOST_DESCRIBE_PP_FOR_EACH_31, \ + BOOST_DESCRIBE_PP_FOR_EACH_30, \ + BOOST_DESCRIBE_PP_FOR_EACH_29, \ + BOOST_DESCRIBE_PP_FOR_EACH_28, \ + BOOST_DESCRIBE_PP_FOR_EACH_27, \ + BOOST_DESCRIBE_PP_FOR_EACH_26, \ + BOOST_DESCRIBE_PP_FOR_EACH_25, \ + BOOST_DESCRIBE_PP_FOR_EACH_24, \ + BOOST_DESCRIBE_PP_FOR_EACH_23, \ + BOOST_DESCRIBE_PP_FOR_EACH_22, \ + BOOST_DESCRIBE_PP_FOR_EACH_21, \ + BOOST_DESCRIBE_PP_FOR_EACH_20, \ + BOOST_DESCRIBE_PP_FOR_EACH_19, \ + BOOST_DESCRIBE_PP_FOR_EACH_18, \ + BOOST_DESCRIBE_PP_FOR_EACH_17, \ + BOOST_DESCRIBE_PP_FOR_EACH_16, \ + BOOST_DESCRIBE_PP_FOR_EACH_15, \ + BOOST_DESCRIBE_PP_FOR_EACH_14, \ + BOOST_DESCRIBE_PP_FOR_EACH_13, \ + BOOST_DESCRIBE_PP_FOR_EACH_12, \ + BOOST_DESCRIBE_PP_FOR_EACH_11, \ + BOOST_DESCRIBE_PP_FOR_EACH_10, \ + BOOST_DESCRIBE_PP_FOR_EACH_9, \ + BOOST_DESCRIBE_PP_FOR_EACH_8, \ + BOOST_DESCRIBE_PP_FOR_EACH_7, \ + BOOST_DESCRIBE_PP_FOR_EACH_6, \ + BOOST_DESCRIBE_PP_FOR_EACH_5, \ + BOOST_DESCRIBE_PP_FOR_EACH_4, \ + BOOST_DESCRIBE_PP_FOR_EACH_3, \ + BOOST_DESCRIBE_PP_FOR_EACH_2, \ + BOOST_DESCRIBE_PP_FOR_EACH_1, \ + BOOST_DESCRIBE_PP_FOR_EACH_0))(F, __VA_ARGS__)) + +#endif // #ifndef BOOST_DESCRIBE_DETAIL_PP_FOR_EACH_HPP_INCLUDED diff --git a/include/boost/describe/detail/pp_utilities.hpp b/include/boost/describe/detail/pp_utilities.hpp new file mode 100644 index 000000000..860f4812d --- /dev/null +++ b/include/boost/describe/detail/pp_utilities.hpp @@ -0,0 +1,92 @@ +#ifndef BOOST_DESCRIBE_DETAIL_PP_UTILITIES_HPP_INCLUDED +#define BOOST_DESCRIBE_DETAIL_PP_UTILITIES_HPP_INCLUDED + +// Copyright 2021 Peter Dimov +// Distributed under the Boost Software License, Version 1.0. +// https://www.boost.org/LICENSE_1_0.txt + +#define BOOST_DESCRIBE_PP_EXPAND(x) x + +#define BOOST_DESCRIBE_PP_CAT(x, y) BOOST_DESCRIBE_PP_CAT_I(x, y) +#define BOOST_DESCRIBE_PP_CAT_I(x, ...) x ## __VA_ARGS__ + +#if defined(_MSC_VER) && !defined(__clang__) + +#define BOOST_DESCRIBE_PP_FIRST(x) BOOST_DESCRIBE_PP_FIRST_I((x)) +#define BOOST_DESCRIBE_PP_FIRST_I(x) BOOST_DESCRIBE_PP_FIRST_II x +#define BOOST_DESCRIBE_PP_FIRST_II(x, ...) x + +#else + +#define BOOST_DESCRIBE_PP_FIRST(x) BOOST_DESCRIBE_PP_FIRST_I(x) +#define BOOST_DESCRIBE_PP_FIRST_I(x, ...) x + +#endif + +#define BOOST_DESCRIBE_PP_IS_PAREN_I(x) BOOST_DESCRIBE_PP_CAT(BOOST_DESCRIBE_PP_IS_PAREN_I_, BOOST_DESCRIBE_PP_IS_PAREN_II x) +#define BOOST_DESCRIBE_PP_IS_PAREN_II(...) 0 +#define BOOST_DESCRIBE_PP_IS_PAREN_I_0 1, +#define BOOST_DESCRIBE_PP_IS_PAREN_I_BOOST_DESCRIBE_PP_IS_PAREN_II 0, + +#define BOOST_DESCRIBE_PP_IS_PAREN(x) BOOST_DESCRIBE_PP_FIRST(BOOST_DESCRIBE_PP_IS_PAREN_I(x)) + +#define BOOST_DESCRIBE_PP_EMPTY + +#define BOOST_DESCRIBE_PP_IS_EMPTY(x) BOOST_DESCRIBE_PP_IS_EMPTY_I(BOOST_DESCRIBE_PP_IS_PAREN(x), BOOST_DESCRIBE_PP_IS_PAREN(x BOOST_DESCRIBE_PP_EMPTY ())) +#define BOOST_DESCRIBE_PP_IS_EMPTY_I(x, y) BOOST_DESCRIBE_PP_IS_EMPTY_II(x, y) +#define BOOST_DESCRIBE_PP_IS_EMPTY_II(x, y) BOOST_DESCRIBE_PP_IS_EMPTY_III(x, y) +#define BOOST_DESCRIBE_PP_IS_EMPTY_III(x, y) BOOST_DESCRIBE_PP_IS_EMPTY_III_ ## x ## y +#define BOOST_DESCRIBE_PP_IS_EMPTY_III_00 0 +#define BOOST_DESCRIBE_PP_IS_EMPTY_III_01 1 +#define BOOST_DESCRIBE_PP_IS_EMPTY_III_10 0 +#define BOOST_DESCRIBE_PP_IS_EMPTY_III_11 0 + +#define BOOST_DESCRIBE_PP_CALL(F, a, x) BOOST_DESCRIBE_PP_CAT(BOOST_DESCRIBE_PP_CALL_I_, BOOST_DESCRIBE_PP_IS_EMPTY(x))(F, a, x) +#define BOOST_DESCRIBE_PP_CALL_I_0(F, a, x) F(a, x) +#define BOOST_DESCRIBE_PP_CALL_I_1(F, a, x) + +#define BOOST_DESCRIBE_PP_PARSE(x) BOOST_DESCRIBE_PP_CAT(BOOST_DESCRIBE_PP_PARSE_I_, BOOST_DESCRIBE_PP_PARSE_II x) +#define BOOST_DESCRIBE_PP_PARSE_II(...) 0, (__VA_ARGS__), +#define BOOST_DESCRIBE_PP_PARSE_I_BOOST_DESCRIBE_PP_PARSE_II 0, ~, +#define BOOST_DESCRIBE_PP_PARSE_I_0 1 + +#if defined(_MSC_VER) && !defined(__clang__) + +#define BOOST_DESCRIBE_PP_NAME(x) BOOST_DESCRIBE_PP_NAME_I(BOOST_DESCRIBE_PP_PARSE(x)) +#define BOOST_DESCRIBE_PP_NAME_I(x) BOOST_DESCRIBE_PP_NAME_II((x)) +#define BOOST_DESCRIBE_PP_NAME_II(x) BOOST_DESCRIBE_PP_NAME_III x +#define BOOST_DESCRIBE_PP_NAME_III(x, y, z) #z + +#else + +#define BOOST_DESCRIBE_PP_NAME(x) BOOST_DESCRIBE_PP_NAME_I(BOOST_DESCRIBE_PP_PARSE(x)) +#define BOOST_DESCRIBE_PP_NAME_I(x) BOOST_DESCRIBE_PP_NAME_II(x) +#define BOOST_DESCRIBE_PP_NAME_II(x, y, z) #z + +#endif + +// template constexpr auto mfn( F C::* p ) { return p; } +// template constexpr auto mfn( F * p ) { return p; } + +#define BOOST_DESCRIBE_PP_POINTER(C, x) BOOST_DESCRIBE_PP_POINTER_I(C, BOOST_DESCRIBE_PP_PARSE(x)) + +#define BOOST_DESCRIBE_PP_EXPAND_V(...) __VA_ARGS__ + +#if defined(_MSC_VER) && !defined(__clang__) + +#define BOOST_DESCRIBE_PP_POINTER_I(C, x) BOOST_DESCRIBE_PP_POINTER_II((C, x)) +#define BOOST_DESCRIBE_PP_POINTER_II(x) BOOST_DESCRIBE_PP_POINTER_III x +#define BOOST_DESCRIBE_PP_POINTER_III(C, x, y, z) BOOST_DESCRIBE_PP_POINTER_III_##x(C, y, z) +#define BOOST_DESCRIBE_PP_POINTER_III_0(C, y, z) &C::z +#define BOOST_DESCRIBE_PP_POINTER_III_1(C, y, z) ::boost::describe::detail::mfn(&C::z) + +#else + +#define BOOST_DESCRIBE_PP_POINTER_I(C, x) BOOST_DESCRIBE_PP_POINTER_II(C, x) +#define BOOST_DESCRIBE_PP_POINTER_II(C, x, y, z) BOOST_DESCRIBE_PP_POINTER_III_##x(C, y, z) +#define BOOST_DESCRIBE_PP_POINTER_III_0(C, y, z) &C::z +#define BOOST_DESCRIBE_PP_POINTER_III_1(C, y, z) ::boost::describe::detail::mfn(&C::z) + +#endif + +#endif // #ifndef BOOST_DESCRIBE_DETAIL_PP_UTILITIES_HPP_INCLUDED diff --git a/include/boost/describe/detail/void_t.hpp b/include/boost/describe/detail/void_t.hpp new file mode 100644 index 000000000..f304250d8 --- /dev/null +++ b/include/boost/describe/detail/void_t.hpp @@ -0,0 +1,32 @@ +#ifndef BOOST_DESCRIBE_DETAIL_VOID_T_HPP_INCLUDED +#define BOOST_DESCRIBE_DETAIL_VOID_T_HPP_INCLUDED + +// Copyright 2021 Peter Dimov +// Distributed under the Boost Software License, Version 1.0. +// https://www.boost.org/LICENSE_1_0.txt + +#include + +#if defined(BOOST_DESCRIBE_CXX11) + +namespace boost +{ +namespace describe +{ +namespace detail +{ + +template struct make_void +{ + using type = void; +}; + +template using void_t = typename make_void::type; + +} // namespace detail +} // namespace describe +} // namespace boost + +#endif // defined(BOOST_DESCRIBE_CXX11) + +#endif // #ifndef BOOST_DESCRIBE_DETAIL_VOID_T_HPP_INCLUDED diff --git a/include/boost/describe/enum.hpp b/include/boost/describe/enum.hpp new file mode 100644 index 000000000..dc0f473d4 --- /dev/null +++ b/include/boost/describe/enum.hpp @@ -0,0 +1,113 @@ +#ifndef BOOST_DESCRIBE_ENUM_HPP_INCLUDED +#define BOOST_DESCRIBE_ENUM_HPP_INCLUDED + +// Copyright 2020 Peter Dimov +// Distributed under the Boost Software License, Version 1.0. +// https://www.boost.org/LICENSE_1_0.txt + +#include + +#if !defined(BOOST_DESCRIBE_CXX14) + +#define BOOST_DESCRIBE_ENUM(E, ...) +#define BOOST_DESCRIBE_NESTED_ENUM(E, ...) + +#else + +#include +#include +#include + +namespace boost +{ +namespace describe +{ +namespace detail +{ + +template struct enum_descriptor +{ + // can't use auto here because of the need to supply the definitions below + static constexpr decltype(D::value()) value = D::value(); + static constexpr decltype(D::name()) name = D::name(); +}; + +#ifndef __cpp_inline_variables +// GCC requires these definitions +template constexpr decltype(D::value()) enum_descriptor::value; +template constexpr decltype(D::name()) enum_descriptor::name; +#endif + +template auto enum_descriptor_fn_impl( int, T... ) +{ + return list...>(); +} + +#define BOOST_DESCRIBE_ENUM_BEGIN(E) \ + inline auto boost_enum_descriptor_fn( E** ) \ + { return boost::describe::detail::enum_descriptor_fn_impl( 0 + +#define BOOST_DESCRIBE_ENUM_ENTRY(E, e) , []{ struct _boost_desc { \ + static constexpr auto value() noexcept { return E::e; } \ + static constexpr auto name() noexcept { return #e; } }; return _boost_desc(); }() + +#define BOOST_DESCRIBE_ENUM_END(E) ); } + +} // namespace detail + +#if defined(_MSC_VER) && !defined(__clang__) + +#define BOOST_DESCRIBE_ENUM(E, ...) \ + namespace should_use_BOOST_DESCRIBE_NESTED_ENUM {} \ + static_assert(std::is_enum::value, "BOOST_DESCRIBE_ENUM should only be used with enums"); \ + BOOST_DESCRIBE_ENUM_BEGIN(E) \ + BOOST_DESCRIBE_PP_FOR_EACH(BOOST_DESCRIBE_ENUM_ENTRY, E, __VA_ARGS__) \ + BOOST_DESCRIBE_ENUM_END(E) + +#define BOOST_DESCRIBE_NESTED_ENUM(E, ...) \ + static_assert(std::is_enum::value, "BOOST_DESCRIBE_NESTED_ENUM should only be used with enums"); \ + friend BOOST_DESCRIBE_ENUM_BEGIN(E) \ + BOOST_DESCRIBE_PP_FOR_EACH(BOOST_DESCRIBE_ENUM_ENTRY, E, __VA_ARGS__) \ + BOOST_DESCRIBE_ENUM_END(E) + +#else + +#define BOOST_DESCRIBE_ENUM(E, ...) \ + namespace should_use_BOOST_DESCRIBE_NESTED_ENUM {} \ + static_assert(std::is_enum::value, "BOOST_DESCRIBE_ENUM should only be used with enums"); \ + BOOST_DESCRIBE_MAYBE_UNUSED BOOST_DESCRIBE_ENUM_BEGIN(E) \ + BOOST_DESCRIBE_PP_FOR_EACH(BOOST_DESCRIBE_ENUM_ENTRY, E, ##__VA_ARGS__) \ + BOOST_DESCRIBE_ENUM_END(E) + +#define BOOST_DESCRIBE_NESTED_ENUM(E, ...) \ + static_assert(std::is_enum::value, "BOOST_DESCRIBE_NESTED_ENUM should only be used with enums"); \ + BOOST_DESCRIBE_MAYBE_UNUSED friend BOOST_DESCRIBE_ENUM_BEGIN(E) \ + BOOST_DESCRIBE_PP_FOR_EACH(BOOST_DESCRIBE_ENUM_ENTRY, E, ##__VA_ARGS__) \ + BOOST_DESCRIBE_ENUM_END(E) + +#endif + +} // namespace describe +} // namespace boost + +#endif // defined(BOOST_DESCRIBE_CXX14) + +#if defined(_MSC_VER) && !defined(__clang__) + +#define BOOST_DEFINE_ENUM(E, ...) enum E { __VA_ARGS__ }; BOOST_DESCRIBE_ENUM(E, __VA_ARGS__) +#define BOOST_DEFINE_ENUM_CLASS(E, ...) enum class E { __VA_ARGS__ }; BOOST_DESCRIBE_ENUM(E, __VA_ARGS__) + +#define BOOST_DEFINE_FIXED_ENUM(E, Base, ...) enum E: Base { __VA_ARGS__ }; BOOST_DESCRIBE_ENUM(E, __VA_ARGS__) +#define BOOST_DEFINE_FIXED_ENUM_CLASS(E, Base, ...) enum class E: Base { __VA_ARGS__ }; BOOST_DESCRIBE_ENUM(E, __VA_ARGS__) + +#else + +#define BOOST_DEFINE_ENUM(E, ...) enum E { __VA_ARGS__ }; BOOST_DESCRIBE_ENUM(E, ##__VA_ARGS__) +#define BOOST_DEFINE_ENUM_CLASS(E, ...) enum class E { __VA_ARGS__ }; BOOST_DESCRIBE_ENUM(E, ##__VA_ARGS__) + +#define BOOST_DEFINE_FIXED_ENUM(E, Base, ...) enum E: Base { __VA_ARGS__ }; BOOST_DESCRIBE_ENUM(E, ##__VA_ARGS__) +#define BOOST_DEFINE_FIXED_ENUM_CLASS(E, Base, ...) enum class E: Base { __VA_ARGS__ }; BOOST_DESCRIBE_ENUM(E, ##__VA_ARGS__) + +#endif + +#endif // #ifndef BOOST_DESCRIBE_ENUM_HPP_INCLUDED diff --git a/include/boost/describe/enum_from_string.hpp b/include/boost/describe/enum_from_string.hpp new file mode 100644 index 000000000..3bdc4cf23 --- /dev/null +++ b/include/boost/describe/enum_from_string.hpp @@ -0,0 +1,53 @@ +#ifndef BOOST_DESCRIBE_ENUM_FROM_STRING_HPP_INCLUDED +#define BOOST_DESCRIBE_ENUM_FROM_STRING_HPP_INCLUDED + +// Copyright 2020, 2021 Peter Dimov +// Distributed under the Boost Software License, Version 1.0. +// https://www.boost.org/LICENSE_1_0.txt + +#include + +#if defined(BOOST_DESCRIBE_CXX14) + +#include +#include +#include + +#if defined(_MSC_VER) && _MSC_VER == 1900 +# pragma warning(push) +# pragma warning(disable: 4100) // unreferenced formal parameter +#endif + +namespace boost +{ +namespace describe +{ + +template> +bool enum_from_string( char const* name, E& e ) noexcept +{ + bool found = false; + + mp11::mp_for_each([&](auto D){ + + if( !found && std::strcmp( D.name, name ) == 0 ) + { + found = true; + e = D.value; + } + + }); + + return found; +} + +} // namespace describe +} // namespace boost + +#if defined(_MSC_VER) && _MSC_VER == 1900 +# pragma warning(pop) +#endif + +#endif // defined(BOOST_DESCRIBE_CXX14) + +#endif // #ifndef BOOST_DESCRIBE_ENUM_FROM_STRING_HPP_INCLUDED diff --git a/include/boost/describe/enum_to_string.hpp b/include/boost/describe/enum_to_string.hpp new file mode 100644 index 000000000..b06e3ac48 --- /dev/null +++ b/include/boost/describe/enum_to_string.hpp @@ -0,0 +1,48 @@ +#ifndef BOOST_DESCRIBE_ENUM_TO_STRING_HPP_INCLUDED +#define BOOST_DESCRIBE_ENUM_TO_STRING_HPP_INCLUDED + +// Copyright 2020, 2021 Peter Dimov +// Distributed under the Boost Software License, Version 1.0. +// https://www.boost.org/LICENSE_1_0.txt + +#include + +#if defined(BOOST_DESCRIBE_CXX14) + +#include +#include + +#if defined(_MSC_VER) && _MSC_VER == 1900 +# pragma warning(push) +# pragma warning(disable: 4100) // unreferenced formal parameter +#endif + +namespace boost +{ +namespace describe +{ + +template> +char const * enum_to_string( E e, char const* def ) noexcept +{ + char const * r = def; + + mp11::mp_for_each([&](auto D){ + + if( e == D.value ) r = D.name; + + }); + + return r; +} + +} // namespace describe +} // namespace boost + +#if defined(_MSC_VER) && _MSC_VER == 1900 +# pragma warning(pop) +#endif + +#endif // defined(BOOST_DESCRIBE_CXX14) + +#endif // #ifndef BOOST_DESCRIBE_ENUM_TO_STRING_HPP_INCLUDED diff --git a/include/boost/describe/enumerators.hpp b/include/boost/describe/enumerators.hpp new file mode 100644 index 000000000..f50c47084 --- /dev/null +++ b/include/boost/describe/enumerators.hpp @@ -0,0 +1,46 @@ +#ifndef BOOST_DESCRIBE_ENUMERATORS_HPP_INCLUDED +#define BOOST_DESCRIBE_ENUMERATORS_HPP_INCLUDED + +// Copyright 2020, 2021 Peter Dimov +// Distributed under the Boost Software License, Version 1.0. +// https://www.boost.org/LICENSE_1_0.txt + +#include +#include + +#if defined(BOOST_DESCRIBE_CXX11) + +#include + +namespace boost +{ +namespace describe +{ + +// describe_enumerators + +template using describe_enumerators = decltype( boost_enum_descriptor_fn( static_cast(0) ) ); + +// has_describe_enumerators + +namespace detail +{ + +template struct has_describe_enumerators: std::false_type +{ +}; + +template struct has_describe_enumerators>>: std::true_type +{ +}; + +} // namespace detail + +template using has_describe_enumerators = detail::has_describe_enumerators; + +} // namespace describe +} // namespace boost + +#endif // defined(BOOST_DESCRIBE_CXX11) + +#endif // #ifndef BOOST_DESCRIBE_ENUMERATORS_HPP_INCLUDED diff --git a/include/boost/describe/members.hpp b/include/boost/describe/members.hpp new file mode 100644 index 000000000..828c49559 --- /dev/null +++ b/include/boost/describe/members.hpp @@ -0,0 +1,161 @@ +#ifndef BOOST_DESCRIBE_DATA_MEMBERS_HPP_INCLUDED +#define BOOST_DESCRIBE_DATA_MEMBERS_HPP_INCLUDED + +// Copyright 2020 Peter Dimov +// Distributed under the Boost Software License, Version 1.0. +// https://www.boost.org/LICENSE_1_0.txt + +#include +#include +#include +#include +#include + +#if defined(BOOST_DESCRIBE_CXX11) + +#include +#include +#include +#include +#include +#include + +namespace boost +{ +namespace describe +{ +namespace detail +{ + +// _describe_members + +template using _describe_public_members = decltype( boost_public_member_descriptor_fn( static_cast(0) ) ); +template using _describe_protected_members = decltype( boost_protected_member_descriptor_fn( static_cast(0) ) ); +template using _describe_private_members = decltype( boost_private_member_descriptor_fn( static_cast(0) ) ); + +template using _describe_members = mp11::mp_append<_describe_public_members, _describe_protected_members, _describe_private_members>; + +// describe_inherited_members + +// T: type +// V: list of virtual bases visited so far +template struct describe_inherited_members_impl; +template using describe_inherited_members = typename describe_inherited_members_impl::type; + +// L: list of base class descriptors +// T: derived type +// V: list of virtual bases visited so far +template struct describe_inherited_members2_impl; +template using describe_inherited_members2 = typename describe_inherited_members2_impl::type; + +template struct describe_inherited_members_impl +{ + using R1 = describe_inherited_members2, T, V>; + using R2 = _describe_members; + + using type = mp11::mp_append; +}; + +template class L, class T, class V> struct describe_inherited_members2_impl, T, V> +{ + using type = L<>; +}; + +template using name_matches = mp11::mp_bool< cx_streq( D1::name, D2::name ) >; + +template using name_is_hidden = mp11::mp_any_of_q>; + +constexpr unsigned cx_max( unsigned m1, unsigned m2 ) +{ + return m1 > m2? m1: m2; +} + +template struct update_modifiers +{ + template struct fn + { + using L = _describe_members; + static constexpr unsigned hidden = name_is_hidden::value? mod_hidden: 0; + + static constexpr unsigned mods = D::modifiers; + static constexpr unsigned access = cx_max( mods & mod_any_access, Bm & mod_any_access ); + + static constexpr decltype(D::pointer) pointer = D::pointer; + static constexpr decltype(D::name) name = D::name; + static constexpr unsigned modifiers = ( mods & ~mod_any_access ) | access | mod_inherited | hidden; + }; +}; + +#ifndef __cpp_inline_variables +template template constexpr decltype(D::pointer) update_modifiers::fn::pointer; +template template constexpr decltype(D::name) update_modifiers::fn::name; +template template constexpr unsigned update_modifiers::fn::modifiers; +#endif + +template struct gather_virtual_bases_impl; +template using gather_virtual_bases = typename gather_virtual_bases_impl::type; + +template struct gather_virtual_bases_impl +{ + using B = typename D::type; + static constexpr unsigned M = D::modifiers; + + using R1 = mp11::mp_transform>; + using R2 = mp11::mp_apply; + + using type = mp11::mp_if_c<(M & mod_virtual) != 0, mp11::mp_push_front, R2>; +}; + +template class L, class D1, class... D, class T, class V> struct describe_inherited_members2_impl, T, V> +{ + using B = typename D1::type; + static constexpr unsigned M = D1::modifiers; + + using R1 = mp11::mp_if_c<(M & mod_virtual) && mp11::mp_contains::value, L<>, describe_inherited_members>; + + using R2 = mp11::mp_transform_q, R1>; + + using V2 = mp11::mp_append>; + using R3 = describe_inherited_members2, T, V2>; + + using type = mp11::mp_append; +}; + +// describe_members + +template using describe_members = mp11::mp_eval_if_c<(M & mod_inherited) == 0, _describe_members, describe_inherited_members, T, mp11::mp_list<>>; + +// member_filter + +template struct member_filter +{ + template using fn = mp11::mp_bool< + (M & mod_any_access & T::modifiers) != 0 && + ( (M & mod_any_member) != 0 || (M & mod_static) == (T::modifiers & mod_static) ) && + ( (M & mod_any_member) != 0 || (M & mod_function) == (T::modifiers & mod_function) ) && + (M & mod_hidden) >= (T::modifiers & mod_hidden) + >; +}; + +// has_describe_members + +template struct has_describe_members: std::false_type +{ +}; + +template struct has_describe_members>>: std::true_type +{ +}; + +} // namespace detail + +template using describe_members = mp11::mp_copy_if_q, detail::member_filter>; + +template using has_describe_members = detail::has_describe_members; + +} // namespace describe +} // namespace boost + +#endif // !defined(BOOST_DESCRIBE_CXX11) + +#endif // #ifndef BOOST_DESCRIBE_DATA_MEMBERS_HPP_INCLUDED diff --git a/include/boost/describe/modifier_description.hpp b/include/boost/describe/modifier_description.hpp new file mode 100644 index 000000000..8429665bf --- /dev/null +++ b/include/boost/describe/modifier_description.hpp @@ -0,0 +1,30 @@ +#ifndef BOOST_DESCRIBE_MODIFIER_DESCRIPTION_HPP_INCLUDED +#define BOOST_DESCRIBE_MODIFIER_DESCRIPTION_HPP_INCLUDED + +// Copyright 2020, 2022 Peter Dimov +// Distributed under the Boost Software License, Version 1.0. +// https://www.boost.org/LICENSE_1_0.txt + +#include +#include + +namespace boost +{ +namespace describe +{ + +BOOST_DESCRIBE_ENUM(modifiers, + mod_public, + mod_protected, + mod_private, + mod_virtual, + mod_static, + mod_function, + mod_any_member, + mod_inherited, + mod_hidden) + +} // namespace describe +} // namespace boost + +#endif // #ifndef BOOST_DESCRIBE_MODIFIER_DESCRIPTION_HPP_INCLUDED diff --git a/include/boost/describe/modifiers.hpp b/include/boost/describe/modifiers.hpp new file mode 100644 index 000000000..06650ea1d --- /dev/null +++ b/include/boost/describe/modifiers.hpp @@ -0,0 +1,33 @@ +#ifndef BOOST_DESCRIBE_MODIFIERS_HPP_INCLUDED +#define BOOST_DESCRIBE_MODIFIERS_HPP_INCLUDED + +// Copyright 2020 Peter Dimov +// Distributed under the Boost Software License, Version 1.0. +// https://www.boost.org/LICENSE_1_0.txt + +#include + +namespace boost +{ +namespace describe +{ + +enum modifiers +{ + mod_public = 1, + mod_protected = 2, + mod_private = 4, + mod_virtual = 8, + mod_static = 16, + mod_function = 32, + mod_any_member = 64, + mod_inherited = 128, + mod_hidden = 256 +}; + +BOOST_DESCRIBE_CONSTEXPR_OR_CONST modifiers mod_any_access = static_cast( mod_public | mod_protected | mod_private ); + +} // namespace describe +} // namespace boost + +#endif // #ifndef BOOST_DESCRIBE_MODIFIERS_HPP_INCLUDED diff --git a/include/boost/describe/operators.hpp b/include/boost/describe/operators.hpp new file mode 100644 index 000000000..780ce94cf --- /dev/null +++ b/include/boost/describe/operators.hpp @@ -0,0 +1,179 @@ +#ifndef BOOST_DESCRIBE_OPERATORS_HPP_INCLUDED +#define BOOST_DESCRIBE_OPERATORS_HPP_INCLUDED + +// Copyright 2020, 2021 Peter Dimov +// Distributed under the Boost Software License, Version 1.0. +// https://www.boost.org/LICENSE_1_0.txt + +#include + +#if defined(BOOST_DESCRIBE_CXX14) + +#include +#include +#include +#include +#include +#include + +#if defined(_MSC_VER) && _MSC_VER == 1900 +# pragma warning(push) +# pragma warning(disable: 4100) // unreferenced formal parameter +#endif + +namespace boost +{ +namespace describe +{ + +namespace detail +{ + +template, + class Md = describe::describe_members> +bool eq( T const& t1, T const& t2 ) +{ + bool r = true; + + mp11::mp_for_each([&](auto D){ + + using B = typename decltype(D)::type; + r = r && (B const&)t1 == (B const&)t2; + + }); + + mp11::mp_for_each([&](auto D){ + + r = r && t1.*D.pointer == t2.*D.pointer; + + }); + + return r; +} + +template, + class Md = describe::describe_members> +bool lt( T const& t1, T const& t2 ) +{ + int r = 0; + + mp11::mp_for_each([&](auto D){ + + using B = typename decltype(D)::type; + if( r == 0 && (B const&)t1 < (B const&)t2 ) r = -1; + if( r == 0 && (B const&)t2 < (B const&)t1 ) r = +1; + + }); + + mp11::mp_for_each([&](auto D){ + + if( r == 0 && t1.*D.pointer < t2.*D.pointer ) r = -1; + if( r == 0 && t2.*D.pointer < t1.*D.pointer ) r = +1; + + }); + + return r < 0; +} + +template, + class Md = describe::describe_members> +void print( Os& os, T const& t ) +{ + os << "{"; + + bool first = true; + + mp11::mp_for_each([&](auto D){ + + if( !first ) { os << ", "; } + first = false; + + using B = typename decltype(D)::type; + os << (B const&)t; + + }); + + mp11::mp_for_each([&](auto D){ + + if( !first ) { os << ", "; } + first = false; + + os << "." << D.name << " = " << t.*D.pointer; + + }); + + os << "}"; +} + +} // namespace detail + +namespace operators +{ + +template std::enable_if_t< + has_describe_bases::value && has_describe_members::value && !std::is_union::value, bool> + operator==( T const& t1, T const& t2 ) +{ + return detail::eq( t1, t2 ); +} + +template std::enable_if_t< + has_describe_bases::value && has_describe_members::value && !std::is_union::value, bool> + operator!=( T const& t1, T const& t2 ) +{ + return !detail::eq( t1, t2 ); +} + +template std::enable_if_t< + has_describe_bases::value && has_describe_members::value && !std::is_union::value, bool> + operator<( T const& t1, T const& t2 ) +{ + return detail::lt( t1, t2 ); +} + +template std::enable_if_t< + has_describe_bases::value && has_describe_members::value && !std::is_union::value, bool> + operator>=( T const& t1, T const& t2 ) +{ + return !detail::lt( t1, t2 ); +} + +template std::enable_if_t< + has_describe_bases::value && has_describe_members::value && !std::is_union::value, bool> + operator>( T const& t1, T const& t2 ) +{ + return detail::lt( t2, t1 ); +} + +template std::enable_if_t< + has_describe_bases::value && has_describe_members::value && !std::is_union::value, bool> + operator<=( T const& t1, T const& t2 ) +{ + return !detail::lt( t2, t1 ); +} + +template std::enable_if_t< + has_describe_bases::value && has_describe_members::value && !std::is_union::value, + std::basic_ostream&> + operator<<( std::basic_ostream& os, T const& t ) +{ + os.width( 0 ); + detail::print( os, t ); + return os; +} + +} // namespace operators + +} // namespace describe +} // namespace boost + +#if defined(_MSC_VER) && _MSC_VER == 1900 +# pragma warning(pop) +#endif + +#endif // defined(BOOST_DESCRIBE_CXX14) + +#endif // #ifndef BOOST_DESCRIBE_OPERATORS_HPP_INCLUDED diff --git a/include/boost/detail/workaround.hpp b/include/boost/detail/workaround.hpp index fb9611588..9c392182a 100644 --- a/include/boost/detail/workaround.hpp +++ b/include/boost/detail/workaround.hpp @@ -2,9 +2,9 @@ // 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 WORKAROUND_DWA2002126_HPP -#define WORKAROUND_DWA2002126_HPP +#ifndef BOOST_WORKAROUND_DWA2002126_HPP +#define BOOST_WORKAROUND_DWA2002126_HPP #include -#endif // WORKAROUND_DWA2002126_HPP +#endif // BOOST_WORKAROUND_DWA2002126_HPP diff --git a/include/boost/exception/exception.hpp b/include/boost/exception/exception.hpp index 37a582c2e..ca8d83359 100644 --- a/include/boost/exception/exception.hpp +++ b/include/boost/exception/exception.hpp @@ -6,7 +6,9 @@ #ifndef BOOST_EXCEPTION_274DA366004E11DCB1DDFE2E56D89593 #define BOOST_EXCEPTION_274DA366004E11DCB1DDFE2E56D89593 +#include #include +#include #ifdef BOOST_EXCEPTION_MINI_BOOST #include @@ -106,6 +108,7 @@ boost typedef error_info throw_function; typedef error_info throw_file; typedef error_info throw_line; + typedef error_info throw_column; template <> class @@ -149,6 +152,20 @@ boost } }; + template <> + class + error_info + { + public: + typedef int value_type; + value_type v_; + explicit + error_info( value_type v ): + v_(v) + { + } + }; + class BOOST_SYMBOL_VISIBLE exception; @@ -188,6 +205,9 @@ boost template <> struct get_info; + template <> + struct get_info; + template struct set_info_rv; @@ -200,6 +220,9 @@ boost template <> struct set_info_rv; + template <> + struct set_info_rv; + char const * get_diagnostic_information( exception const &, char const * ); void copy_boost_exception( exception *, exception const * ); @@ -215,6 +238,11 @@ boost template E const & set_info( E const &, throw_line const & ); + + template + E const & set_info( E const &, throw_column const & ); + + boost::source_location get_exception_throw_location( exception const & ); } class @@ -232,7 +260,8 @@ boost exception(): throw_function_(0), throw_file_(0), - throw_line_(-1) + throw_line_(-1), + throw_column_(-1) { } @@ -243,7 +272,8 @@ boost data_(x.data_), throw_function_(x.throw_function_), throw_file_(x.throw_file_), - throw_line_(x.throw_line_) + throw_line_(x.throw_line_), + throw_column_(x.throw_column_) { } #endif @@ -268,27 +298,35 @@ boost template friend E const & exception_detail::set_info( E const &, throw_line const & ); + template + friend E const & exception_detail::set_info( E const &, throw_column const & ); + template friend E const & exception_detail::set_info( E const &, error_info const & ); friend char const * exception_detail::get_diagnostic_information( exception const &, char const * ); + friend boost::source_location exception_detail::get_exception_throw_location( exception const & ); + template friend struct exception_detail::get_info; friend struct exception_detail::get_info; friend struct exception_detail::get_info; friend struct exception_detail::get_info; + friend struct exception_detail::get_info; template friend struct exception_detail::set_info_rv; friend struct exception_detail::set_info_rv; friend struct exception_detail::set_info_rv; friend struct exception_detail::set_info_rv; + friend struct exception_detail::set_info_rv; friend void exception_detail::copy_boost_exception( exception *, exception const * ); #endif mutable exception_detail::refcount_ptr data_; mutable char const * throw_function_; mutable char const * throw_file_; mutable int throw_line_; + mutable int throw_column_; }; inline @@ -323,6 +361,42 @@ boost x.throw_line_=y.v_; return x; } + + template + E const & + set_info( E const & x, throw_column const & y ) + { + x.throw_column_=y.v_; + return x; + } + +#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES + + template <> + struct + set_info_rv + { + template + static + E const & + set( E const & x, throw_column && y ) + { + x.throw_column_=y.v_; + return x; + } + }; + +#endif + + inline boost::source_location get_exception_throw_location( exception const & x ) + { + return boost::source_location( + x.throw_file_? x.throw_file_: "", + x.throw_line_ >= 0? x.throw_line_: 0, + x.throw_function_? x.throw_function_: "", + x.throw_column_ >= 0? x.throw_column_: 0 + ); + } } //////////////////////////////////////////////////////////////////////// @@ -390,6 +464,9 @@ boost } //////////////////////////////////////////////////////////////////////// +#if defined(BOOST_NO_EXCEPTIONS) + BOOST_NORETURN void throw_exception(std::exception const & e); // user defined +#endif namespace exception_detail @@ -419,6 +496,7 @@ boost a->throw_file_ = b->throw_file_; a->throw_line_ = b->throw_line_; a->throw_function_ = b->throw_function_; + a->throw_column_ = b->throw_column_; a->data_ = data; } @@ -466,7 +544,11 @@ boost void rethrow() const { +#if defined(BOOST_NO_EXCEPTIONS) + boost::throw_exception(*this); +#else throw*this; +#endif } }; } diff --git a/include/boost/integer/static_log2.hpp b/include/boost/integer/static_log2.hpp index db3aba2d0..325ea2c11 100644 --- a/include/boost/integer/static_log2.hpp +++ b/include/boost/integer/static_log2.hpp @@ -6,10 +6,10 @@ // // 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) +// https://www.boost.org/LICENSE_1_0.txt) // // --------------------------------------------------- -// See http://www.boost.org/libs/integer for documentation. +// See https://www.boost.org/libs/integer for documentation. // ------------------------------------------------------------------------- // diff --git a/include/boost/integer_fwd.hpp b/include/boost/integer_fwd.hpp index 18519dd69..6eac5aafb 100644 --- a/include/boost/integer_fwd.hpp +++ b/include/boost/integer_fwd.hpp @@ -2,9 +2,9 @@ // (C) Copyright Dave Abrahams and Daryle Walker 2001. 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) +// LICENSE_1_0.txt or copy at https://www.boost.org/LICENSE_1_0.txt) -// See http://www.boost.org/libs/integer for documentation. +// See https://www.boost.org/libs/integer for documentation. #ifndef BOOST_INTEGER_FWD_HPP #define BOOST_INTEGER_FWD_HPP diff --git a/include/boost/intrusive/any_hook.hpp b/include/boost/intrusive/any_hook.hpp index 6d187812a..72abc9ee2 100644 --- a/include/boost/intrusive/any_hook.hpp +++ b/include/boost/intrusive/any_hook.hpp @@ -194,7 +194,7 @@ class any_member_hook //! initializes the node to an unlinked state. //! //! Throws: Nothing. - any_member_hook(); + any_member_hook() BOOST_NOEXCEPT; //! Effects: If link_mode is or \c safe_link //! initializes the node to an unlinked state. The argument is ignored. @@ -205,7 +205,7 @@ class any_member_hook //! makes classes using the hook STL-compliant without forcing the //! user to do some additional work. \c swap can be used to emulate //! move-semantics. - any_member_hook(const any_member_hook& ); + any_member_hook(const any_member_hook&) BOOST_NOEXCEPT; //! Effects: Empty function. The argument is ignored. //! @@ -215,7 +215,7 @@ class any_member_hook //! makes classes using the hook STL-compliant without forcing the //! user to do some additional work. \c swap can be used to emulate //! move-semantics. - any_member_hook& operator=(const any_member_hook& ); + any_member_hook& operator=(const any_member_hook&) BOOST_NOEXCEPT; //! Effects: If link_mode is \c normal_link, the destructor does //! nothing (ie. no code is generated). If link_mode is \c safe_link and the @@ -231,7 +231,7 @@ class any_member_hook //! will return a valid iterator. //! //! Complexity: Constant - bool is_linked() const; + bool is_linked() const BOOST_NOEXCEPT; #endif }; diff --git a/include/boost/intrusive/avl_set.hpp b/include/boost/intrusive/avl_set.hpp index d714ab12f..b03d30459 100644 --- a/include/boost/intrusive/avl_set.hpp +++ b/include/boost/intrusive/avl_set.hpp @@ -120,22 +120,22 @@ class avl_set_impl ~avl_set_impl(); //! @copydoc ::boost::intrusive::avltree::begin() - iterator begin(); + iterator begin() BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::avltree::begin()const - const_iterator begin() const; + const_iterator begin() const BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::avltree::cbegin()const - const_iterator cbegin() const; + const_iterator cbegin() const BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::avltree::end() - iterator end(); + iterator end() BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::avltree::end()const - const_iterator end() const; + const_iterator end() const BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::avltree::cend()const - const_iterator cend() const; + const_iterator cend() const BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::avltree::begin() reverse_iterator avlegin(); @@ -144,37 +144,37 @@ class avl_set_impl const_reverse_iterator avlegin() const; //! @copydoc ::boost::intrusive::avltree::crbegin()const - const_reverse_iterator crbegin() const; + const_reverse_iterator crbegin() const BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::avltree::rend() - reverse_iterator rend(); + reverse_iterator rend() BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::avltree::rend()const - const_reverse_iterator rend() const; + const_reverse_iterator rend() const BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::avltree::crend()const - const_reverse_iterator crend() const; + const_reverse_iterator crend() const BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::avltree::root() - iterator root(); + iterator root() BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::avltree::root()const - const_iterator root() const; + const_iterator root() const BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::avltree::croot()const - const_iterator croot() const; + const_iterator croot() const BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::avltree::container_from_end_iterator(iterator) - static avl_set_impl &container_from_end_iterator(iterator end_iterator); + static avl_set_impl &container_from_end_iterator(iterator end_iterator) BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::avltree::container_from_end_iterator(const_iterator) - static const avl_set_impl &container_from_end_iterator(const_iterator end_iterator); + static const avl_set_impl &container_from_end_iterator(const_iterator end_iterator) BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::avltree::container_from_iterator(iterator) - static avl_set_impl &container_from_iterator(iterator it); + static avl_set_impl &container_from_iterator(iterator it) BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::avltree::container_from_iterator(const_iterator) - static const avl_set_impl &container_from_iterator(const_iterator it); + static const avl_set_impl &container_from_iterator(const_iterator it) BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::avltree::key_comp()const key_compare key_comp() const; @@ -183,10 +183,10 @@ class avl_set_impl value_compare value_comp() const; //! @copydoc ::boost::intrusive::avltree::empty()const - bool empty() const; + bool empty() const BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::avltree::size()const - size_type size() const; + size_type size() const BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::avltree::swap void swap(avl_set_impl& other); @@ -244,24 +244,24 @@ class avl_set_impl { tree_type::insert_unique(b, e); } //! @copydoc ::boost::intrusive::avltree::insert_unique_commit - iterator insert_commit(reference value, const insert_commit_data &commit_data) + iterator insert_commit(reference value, const insert_commit_data &commit_data) BOOST_NOEXCEPT { return tree_type::insert_unique_commit(value, commit_data); } #ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED //! @copydoc ::boost::intrusive::avltree::insert_before - iterator insert_before(const_iterator pos, reference value); + iterator insert_before(const_iterator pos, reference value) BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::avltree::push_back - void push_back(reference value); + void push_back(reference value) BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::avltree::push_front - void push_front(reference value); + void push_front(reference value) BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::avltree::erase(const_iterator) - iterator erase(const_iterator i); + iterator erase(const_iterator i) BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::avltree::erase(const_iterator,const_iterator) - iterator erase(const_iterator b, const_iterator e); + iterator erase(const_iterator b, const_iterator e) BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::avltree::erase(const key_type &key) size_type erase(const key_type &key); @@ -272,11 +272,11 @@ class avl_set_impl //! @copydoc ::boost::intrusive::avltree::erase_and_dispose(const_iterator,Disposer) template - iterator erase_and_dispose(const_iterator i, Disposer disposer); + iterator erase_and_dispose(const_iterator i, Disposer disposer) BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::avltree::erase_and_dispose(const_iterator,const_iterator,Disposer) template - iterator erase_and_dispose(const_iterator b, const_iterator e, Disposer disposer); + iterator erase_and_dispose(const_iterator b, const_iterator e, Disposer disposer) BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::avltree::erase_and_dispose(const key_type &, Disposer) template @@ -287,11 +287,11 @@ class avl_set_impl size_type erase_and_dispose(const KeyType& key, KeyTypeKeyCompare comp, Disposer disposer); //! @copydoc ::boost::intrusive::avltree::clear - void clear(); + void clear() BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::avltree::clear_and_dispose template - void clear_and_dispose(Disposer disposer); + void clear_and_dispose(Disposer disposer) BOOST_NOEXCEPT; #endif // #ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED @@ -391,28 +391,28 @@ class avl_set_impl (const KeyType& lower_key, const KeyType& upper_key, KeyTypeKeyCompare comp, bool left_closed, bool right_closed) const; //! @copydoc ::boost::intrusive::avltree::s_iterator_to(reference) - static iterator s_iterator_to(reference value); + static iterator s_iterator_to(reference value) BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::avltree::s_iterator_to(const_reference) - static const_iterator s_iterator_to(const_reference value); + static const_iterator s_iterator_to(const_reference value) BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::avltree::iterator_to(reference) - iterator iterator_to(reference value); + iterator iterator_to(reference value) BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::avltree::iterator_to(const_reference)const - const_iterator iterator_to(const_reference value) const; + const_iterator iterator_to(const_reference value) const BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::avltree::init_node(reference) - static void init_node(reference value); + static void init_node(reference value) BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::avltree::unlink_leftmost_without_rebalance - pointer unlink_leftmost_without_rebalance(); + pointer unlink_leftmost_without_rebalance() BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::avltree::replace_node - void replace_node(iterator replace_this, reference with_this); + void replace_node(iterator replace_this, reference with_this) BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::avltree::remove_node - void remove_node(reference value); + void remove_node(reference value) BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::avltree::merge_unique template @@ -555,16 +555,16 @@ class avl_set BOOST_INTRUSIVE_FORCEINLINE void clone_from(BOOST_RV_REF(avl_set) src, Cloner cloner, Disposer disposer) { Base::clone_from(BOOST_MOVE_BASE(Base, src), cloner, disposer); } - BOOST_INTRUSIVE_FORCEINLINE static avl_set &container_from_end_iterator(iterator end_iterator) + BOOST_INTRUSIVE_FORCEINLINE static avl_set &container_from_end_iterator(iterator end_iterator) BOOST_NOEXCEPT { return static_cast(Base::container_from_end_iterator(end_iterator)); } - BOOST_INTRUSIVE_FORCEINLINE static const avl_set &container_from_end_iterator(const_iterator end_iterator) + BOOST_INTRUSIVE_FORCEINLINE static const avl_set &container_from_end_iterator(const_iterator end_iterator) BOOST_NOEXCEPT { return static_cast(Base::container_from_end_iterator(end_iterator)); } - BOOST_INTRUSIVE_FORCEINLINE static avl_set &container_from_iterator(iterator it) + BOOST_INTRUSIVE_FORCEINLINE static avl_set &container_from_iterator(iterator it) BOOST_NOEXCEPT { return static_cast(Base::container_from_iterator(it)); } - BOOST_INTRUSIVE_FORCEINLINE static const avl_set &container_from_iterator(const_iterator it) + BOOST_INTRUSIVE_FORCEINLINE static const avl_set &container_from_iterator(const_iterator it) BOOST_NOEXCEPT { return static_cast(Base::container_from_iterator(it)); } }; @@ -657,61 +657,61 @@ class avl_multiset_impl ~avl_multiset_impl(); //! @copydoc ::boost::intrusive::avltree::begin() - iterator begin(); + iterator begin() BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::avltree::begin()const - const_iterator begin() const; + const_iterator begin() const BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::avltree::cbegin()const - const_iterator cbegin() const; + const_iterator cbegin() const BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::avltree::end() - iterator end(); + iterator end() BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::avltree::end()const - const_iterator end() const; + const_iterator end() const BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::avltree::cend()const - const_iterator cend() const; + const_iterator cend() const BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::avltree::rbegin() - reverse_iterator rbegin(); + reverse_iterator rbegin() BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::avltree::rbegin()const - const_reverse_iterator rbegin() const; + const_reverse_iterator rbegin() const BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::avltree::crbegin()const - const_reverse_iterator crbegin() const; + const_reverse_iterator crbegin() const BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::avltree::rend() - reverse_iterator rend(); + reverse_iterator rend() BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::avltree::rend()const - const_reverse_iterator rend() const; + const_reverse_iterator rend() const BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::avltree::crend()const - const_reverse_iterator crend() const; + const_reverse_iterator crend() const BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::avltree::root() - iterator root(); + iterator root() BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::avltree::root()const - const_iterator root() const; + const_iterator root() const BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::avltree::croot()const - const_iterator croot() const; + const_iterator croot() const BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::avltree::container_from_end_iterator(iterator) - static avl_multiset_impl &container_from_end_iterator(iterator end_iterator); + static avl_multiset_impl &container_from_end_iterator(iterator end_iterator) BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::avltree::container_from_end_iterator(const_iterator) - static const avl_multiset_impl &container_from_end_iterator(const_iterator end_iterator); + static const avl_multiset_impl &container_from_end_iterator(const_iterator end_iterator) BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::avltree::container_from_iterator(iterator) - static avl_multiset_impl &container_from_iterator(iterator it); + static avl_multiset_impl &container_from_iterator(iterator it) BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::avltree::container_from_iterator(const_iterator) - static const avl_multiset_impl &container_from_iterator(const_iterator it); + static const avl_multiset_impl &container_from_iterator(const_iterator it) BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::avltree::key_comp()const key_compare key_comp() const; @@ -720,10 +720,10 @@ class avl_multiset_impl value_compare value_comp() const; //! @copydoc ::boost::intrusive::avltree::empty()const - bool empty() const; + bool empty() const BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::avltree::size()const - size_type size() const; + size_type size() const BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::avltree::swap void swap(avl_multiset_impl& other); @@ -758,19 +758,19 @@ class avl_multiset_impl #ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED //! @copydoc ::boost::intrusive::avltree::insert_before - iterator insert_before(const_iterator pos, reference value); + iterator insert_before(const_iterator pos, reference value) BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::avltree::push_back - void push_back(reference value); + void push_back(reference value) BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::avltree::push_front - void push_front(reference value); + void push_front(reference value) BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::avltree::erase(const_iterator) - iterator erase(const_iterator i); + iterator erase(const_iterator i) BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::avltree::erase(const_iterator,const_iterator) - iterator erase(const_iterator b, const_iterator e); + iterator erase(const_iterator b, const_iterator e) BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::avltree::erase(const key_type &) size_type erase(const key_type &key); @@ -781,11 +781,11 @@ class avl_multiset_impl //! @copydoc ::boost::intrusive::avltree::erase_and_dispose(const_iterator,Disposer) template - iterator erase_and_dispose(const_iterator i, Disposer disposer); + iterator erase_and_dispose(const_iterator i, Disposer disposer) BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::avltree::erase_and_dispose(const_iterator,const_iterator,Disposer) template - iterator erase_and_dispose(const_iterator b, const_iterator e, Disposer disposer); + iterator erase_and_dispose(const_iterator b, const_iterator e, Disposer disposer) BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::avltree::erase_and_dispose(const key_type &, Disposer) template @@ -796,11 +796,11 @@ class avl_multiset_impl size_type erase_and_dispose(const KeyType& key, KeyTypeKeyCompare comp, Disposer disposer); //! @copydoc ::boost::intrusive::avltree::clear - void clear(); + void clear() BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::avltree::clear_and_dispose template - void clear_and_dispose(Disposer disposer); + void clear_and_dispose(Disposer disposer) BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::avltree::count(const key_type &)const size_type count(const key_type &key) const; @@ -886,28 +886,28 @@ class avl_multiset_impl (const KeyType& lower_key, const KeyType& upper_key, KeyTypeKeyCompare comp, bool left_closed, bool right_closed) const; //! @copydoc ::boost::intrusive::avltree::s_iterator_to(reference) - static iterator s_iterator_to(reference value); + static iterator s_iterator_to(reference value) BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::avltree::s_iterator_to(const_reference) - static const_iterator s_iterator_to(const_reference value); + static const_iterator s_iterator_to(const_reference value) BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::avltree::iterator_to(reference) - iterator iterator_to(reference value); + iterator iterator_to(reference value) BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::avltree::iterator_to(const_reference)const - const_iterator iterator_to(const_reference value) const; + const_iterator iterator_to(const_reference value) const BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::avltree::init_node(reference) - static void init_node(reference value); + static void init_node(reference value) BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::avltree::unlink_leftmost_without_rebalance - pointer unlink_leftmost_without_rebalance(); + pointer unlink_leftmost_without_rebalance() BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::avltree::replace_node - void replace_node(iterator replace_this, reference with_this); + void replace_node(iterator replace_this, reference with_this) BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::avltree::remove_node - void remove_node(reference value); + void remove_node(reference value) BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::avltree::merge_equal template @@ -1050,16 +1050,16 @@ class avl_multiset BOOST_INTRUSIVE_FORCEINLINE void clone_from(BOOST_RV_REF(avl_multiset) src, Cloner cloner, Disposer disposer) { Base::clone_from(BOOST_MOVE_BASE(Base, src), cloner, disposer); } - BOOST_INTRUSIVE_FORCEINLINE static avl_multiset &container_from_end_iterator(iterator end_iterator) + BOOST_INTRUSIVE_FORCEINLINE static avl_multiset &container_from_end_iterator(iterator end_iterator) BOOST_NOEXCEPT { return static_cast(Base::container_from_end_iterator(end_iterator)); } - BOOST_INTRUSIVE_FORCEINLINE static const avl_multiset &container_from_end_iterator(const_iterator end_iterator) + BOOST_INTRUSIVE_FORCEINLINE static const avl_multiset &container_from_end_iterator(const_iterator end_iterator) BOOST_NOEXCEPT { return static_cast(Base::container_from_end_iterator(end_iterator)); } - BOOST_INTRUSIVE_FORCEINLINE static avl_multiset &container_from_iterator(iterator it) + BOOST_INTRUSIVE_FORCEINLINE static avl_multiset &container_from_iterator(iterator it) BOOST_NOEXCEPT { return static_cast(Base::container_from_iterator(it)); } - BOOST_INTRUSIVE_FORCEINLINE static const avl_multiset &container_from_iterator(const_iterator it) + BOOST_INTRUSIVE_FORCEINLINE static const avl_multiset &container_from_iterator(const_iterator it) BOOST_NOEXCEPT { return static_cast(Base::container_from_iterator(it)); } }; diff --git a/include/boost/intrusive/avltree.hpp b/include/boost/intrusive/avltree.hpp index b80cb938e..747d41cc3 100644 --- a/include/boost/intrusive/avltree.hpp +++ b/include/boost/intrusive/avltree.hpp @@ -154,61 +154,61 @@ class avltree_impl ~avltree_impl(); //! @copydoc ::boost::intrusive::bstree::begin() - iterator begin(); + iterator begin() BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::bstree::begin()const - const_iterator begin() const; + const_iterator begin() const BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::bstree::cbegin()const - const_iterator cbegin() const; + const_iterator cbegin() const BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::bstree::end() - iterator end(); + iterator end() BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::bstree::end()const - const_iterator end() const; + const_iterator end() const BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::bstree::cend()const - const_iterator cend() const; + const_iterator cend() const BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::bstree::rbegin() - reverse_iterator rbegin(); + reverse_iterator rbegin() BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::bstree::rbegin()const - const_reverse_iterator rbegin() const; + const_reverse_iterator rbegin() const BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::bstree::crbegin()const - const_reverse_iterator crbegin() const; + const_reverse_iterator crbegin() const BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::bstree::rend() - reverse_iterator rend(); + reverse_iterator rend() BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::bstree::rend()const - const_reverse_iterator rend() const; + const_reverse_iterator rend() const BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::bstree::crend()const - const_reverse_iterator crend() const; + const_reverse_iterator crend() const BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::bstree::root() - iterator root(); + iterator root() BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::bstree::root()const - const_iterator root() const; + const_iterator root() const BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::bstree::croot()const - const_iterator croot() const; + const_iterator croot() const BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::bstree::container_from_end_iterator(iterator) - static avltree_impl &container_from_end_iterator(iterator end_iterator); + static avltree_impl &container_from_end_iterator(iterator end_iterator) BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::bstree::container_from_end_iterator(const_iterator) - static const avltree_impl &container_from_end_iterator(const_iterator end_iterator); + static const avltree_impl &container_from_end_iterator(const_iterator end_iterator) BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::bstree::container_from_iterator(iterator) - static avltree_impl &container_from_iterator(iterator it); + static avltree_impl &container_from_iterator(iterator it) BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::bstree::container_from_iterator(const_iterator) - static const avltree_impl &container_from_iterator(const_iterator it); + static const avltree_impl &container_from_iterator(const_iterator it) BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::bstree::key_comp()const key_compare key_comp() const; @@ -217,10 +217,10 @@ class avltree_impl value_compare value_comp() const; //! @copydoc ::boost::intrusive::bstree::empty()const - bool empty() const; + bool empty() const BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::bstree::size()const - size_type size() const; + size_type size() const BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::bstree::swap void swap(avltree_impl& other); @@ -278,26 +278,26 @@ class avltree_impl (const_iterator hint, const key_type &key, insert_commit_data &commit_data); //! @copydoc ::boost::intrusive::bstree::insert_unique_commit - iterator insert_unique_commit(reference value, const insert_commit_data &commit_data); + iterator insert_unique_commit(reference value, const insert_commit_data &commit_data) BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::bstree::insert_unique(Iterator,Iterator) template void insert_unique(Iterator b, Iterator e); //! @copydoc ::boost::intrusive::bstree::insert_before - iterator insert_before(const_iterator pos, reference value); + iterator insert_before(const_iterator pos, reference value) BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::bstree::push_back - void push_back(reference value); + void push_back(reference value) BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::bstree::push_front - void push_front(reference value); + void push_front(reference value) BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::bstree::erase(const_iterator) - iterator erase(const_iterator i); + iterator erase(const_iterator i) BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::bstree::erase(const_iterator,const_iterator) - iterator erase(const_iterator b, const_iterator e); + iterator erase(const_iterator b, const_iterator e) BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::bstree::erase(const key_type &) size_type erase(const key_type &key); @@ -308,11 +308,11 @@ class avltree_impl //! @copydoc ::boost::intrusive::bstree::erase_and_dispose(const_iterator,Disposer) template - iterator erase_and_dispose(const_iterator i, Disposer disposer); + iterator erase_and_dispose(const_iterator i, Disposer disposer) BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::bstree::erase_and_dispose(const_iterator,const_iterator,Disposer) template - iterator erase_and_dispose(const_iterator b, const_iterator e, Disposer disposer); + iterator erase_and_dispose(const_iterator b, const_iterator e, Disposer disposer) BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::bstree::erase_and_dispose(const key_type &, Disposer) template @@ -323,11 +323,11 @@ class avltree_impl size_type erase_and_dispose(const KeyType& key, KeyTypeKeyCompare comp, Disposer disposer); //! @copydoc ::boost::intrusive::bstree::clear - void clear(); + void clear() BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::bstree::clear_and_dispose template - void clear_and_dispose(Disposer disposer); + void clear_and_dispose(Disposer disposer) BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::bstree::count(const key_type &ke)const size_type count(const key_type &key) const; @@ -413,28 +413,28 @@ class avltree_impl (const KeyType& lower_key, const KeyType& upper_key, KeyTypeKeyCompare comp, bool left_closed, bool right_closed) const; //! @copydoc ::boost::intrusive::bstree::s_iterator_to(reference) - static iterator s_iterator_to(reference value); + static iterator s_iterator_to(reference value) BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::bstree::s_iterator_to(const_reference) - static const_iterator s_iterator_to(const_reference value); + static const_iterator s_iterator_to(const_reference value) BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::bstree::iterator_to(reference) - iterator iterator_to(reference value); + iterator iterator_to(reference value) BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::bstree::iterator_to(const_reference)const - const_iterator iterator_to(const_reference value) const; + const_iterator iterator_to(const_reference value) const BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::bstree::init_node(reference) - static void init_node(reference value); + static void init_node(reference value) BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::bstree::unlink_leftmost_without_rebalance - pointer unlink_leftmost_without_rebalance(); + pointer unlink_leftmost_without_rebalance() BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::bstree::replace_node - void replace_node(iterator replace_this, reference with_this); + void replace_node(iterator replace_this, reference with_this) BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::bstree::remove_node - void remove_node(reference value); + void remove_node(reference value) BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::bstree::merge_unique(bstree&) template @@ -565,16 +565,16 @@ class avltree BOOST_INTRUSIVE_FORCEINLINE void clone_from(BOOST_RV_REF(avltree) src, Cloner cloner, Disposer disposer) { Base::clone_from(BOOST_MOVE_BASE(Base, src), cloner, disposer); } - BOOST_INTRUSIVE_FORCEINLINE static avltree &container_from_end_iterator(iterator end_iterator) + BOOST_INTRUSIVE_FORCEINLINE static avltree &container_from_end_iterator(iterator end_iterator) BOOST_NOEXCEPT { return static_cast(Base::container_from_end_iterator(end_iterator)); } - BOOST_INTRUSIVE_FORCEINLINE static const avltree &container_from_end_iterator(const_iterator end_iterator) + BOOST_INTRUSIVE_FORCEINLINE static const avltree &container_from_end_iterator(const_iterator end_iterator) BOOST_NOEXCEPT { return static_cast(Base::container_from_end_iterator(end_iterator)); } - BOOST_INTRUSIVE_FORCEINLINE static avltree &container_from_iterator(iterator it) + BOOST_INTRUSIVE_FORCEINLINE static avltree &container_from_iterator(iterator it) BOOST_NOEXCEPT { return static_cast(Base::container_from_iterator(it)); } - BOOST_INTRUSIVE_FORCEINLINE static const avltree &container_from_iterator(const_iterator it) + BOOST_INTRUSIVE_FORCEINLINE static const avltree &container_from_iterator(const_iterator it) BOOST_NOEXCEPT { return static_cast(Base::container_from_iterator(it)); } }; diff --git a/include/boost/intrusive/avltree_algorithms.hpp b/include/boost/intrusive/avltree_algorithms.hpp index 1d206cdc6..0fd158d59 100644 --- a/include/boost/intrusive/avltree_algorithms.hpp +++ b/include/boost/intrusive/avltree_algorithms.hpp @@ -46,14 +46,14 @@ struct avltree_node_cloner : base_t(f) {} - BOOST_INTRUSIVE_FORCEINLINE node_ptr operator()(const node_ptr & p) + node_ptr operator()(node_ptr p) { node_ptr n = base_t::get()(p); NodeTraits::set_balance(n, NodeTraits::get_balance(p)); return n; } - BOOST_INTRUSIVE_FORCEINLINE node_ptr operator()(const node_ptr & p) const + node_ptr operator()(node_ptr p) const { node_ptr n = base_t::get()(p); NodeTraits::set_balance(n, NodeTraits::get_balance(p)); @@ -83,7 +83,7 @@ struct avltree_node_checker : base_checker_t(comp, extra_checker) {} - void operator () (const const_node_ptr& p, + void operator () (const_node_ptr p, const return_type& check_return_left, const return_type& check_return_right, return_type& check_return) { @@ -166,22 +166,22 @@ class avltree_algorithms #ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED - //! @copydoc ::boost::intrusive::bstree_algorithms::get_header(const const_node_ptr&) - static node_ptr get_header(const const_node_ptr & n); + //! @copydoc ::boost::intrusive::bstree_algorithms::get_header(const_node_ptr) + static node_ptr get_header(const_node_ptr n) BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::bstree_algorithms::begin_node - static node_ptr begin_node(const const_node_ptr & header); + static node_ptr begin_node(const_node_ptr header) BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::bstree_algorithms::end_node - static node_ptr end_node(const const_node_ptr & header); + static node_ptr end_node(const_node_ptr header) BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::bstree_algorithms::swap_tree - static void swap_tree(node_ptr header1, node_ptr header2); + static void swap_tree(node_ptr header1, node_ptr header2) BOOST_NOEXCEPT; #endif //#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED //! @copydoc ::boost::intrusive::bstree_algorithms::swap_nodes(node_ptr,node_ptr) - static void swap_nodes(node_ptr node1, node_ptr node2) + static void swap_nodes(node_ptr node1, node_ptr node2) BOOST_NOEXCEPT { if(node1 == node2) return; @@ -191,7 +191,7 @@ class avltree_algorithms } //! @copydoc ::boost::intrusive::bstree_algorithms::swap_nodes(node_ptr,node_ptr,node_ptr,node_ptr) - static void swap_nodes(node_ptr node1, node_ptr header1, node_ptr node2, node_ptr header2) + static void swap_nodes(node_ptr node1, node_ptr header1, node_ptr node2, node_ptr header2) BOOST_NOEXCEPT { if(node1 == node2) return; @@ -203,7 +203,7 @@ class avltree_algorithms } //! @copydoc ::boost::intrusive::bstree_algorithms::replace_node(node_ptr,node_ptr) - static void replace_node(node_ptr node_to_be_replaced, node_ptr new_node) + static void replace_node(node_ptr node_to_be_replaced, node_ptr new_node) BOOST_NOEXCEPT { if(node_to_be_replaced == new_node) return; @@ -211,44 +211,44 @@ class avltree_algorithms } //! @copydoc ::boost::intrusive::bstree_algorithms::replace_node(node_ptr,node_ptr,node_ptr) - static void replace_node(node_ptr node_to_be_replaced, node_ptr header, node_ptr new_node) + static void replace_node(node_ptr node_to_be_replaced, node_ptr header, node_ptr new_node) BOOST_NOEXCEPT { bstree_algo::replace_node(node_to_be_replaced, header, new_node); NodeTraits::set_balance(new_node, NodeTraits::get_balance(node_to_be_replaced)); } //! @copydoc ::boost::intrusive::bstree_algorithms::unlink(node_ptr) - static void unlink(node_ptr node) + static void unlink(node_ptr n) BOOST_NOEXCEPT { - node_ptr x = NodeTraits::get_parent(node); + node_ptr x = NodeTraits::get_parent(n); if(x){ while(!is_header(x)) x = NodeTraits::get_parent(x); - erase(x, node); + erase(x, n); } } #ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED //! @copydoc ::boost::intrusive::bstree_algorithms::unlink_leftmost_without_rebalance - static node_ptr unlink_leftmost_without_rebalance(const node_ptr & header); + static node_ptr unlink_leftmost_without_rebalance(node_ptr header) BOOST_NOEXCEPT; - //! @copydoc ::boost::intrusive::bstree_algorithms::unique(const const_node_ptr&) - static bool unique(const const_node_ptr & node); + //! @copydoc ::boost::intrusive::bstree_algorithms::unique(const_node_ptr) + static bool unique(const_node_ptr n) BOOST_NOEXCEPT; - //! @copydoc ::boost::intrusive::bstree_algorithms::size(const const_node_ptr&) - static std::size_t size(const const_node_ptr & header); + //! @copydoc ::boost::intrusive::bstree_algorithms::size(const_node_ptr) + static std::size_t size(const_node_ptr header) BOOST_NOEXCEPT; - //! @copydoc ::boost::intrusive::bstree_algorithms::next_node(const node_ptr&) - static node_ptr next_node(const node_ptr & node); + //! @copydoc ::boost::intrusive::bstree_algorithms::next_node(node_ptr) + static node_ptr next_node(node_ptr n) BOOST_NOEXCEPT; - //! @copydoc ::boost::intrusive::bstree_algorithms::prev_node(const node_ptr&) - static node_ptr prev_node(const node_ptr & node); + //! @copydoc ::boost::intrusive::bstree_algorithms::prev_node(node_ptr) + static node_ptr prev_node(node_ptr n) BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::bstree_algorithms::init(node_ptr) - static void init(const node_ptr & node); + static void init(node_ptr n) BOOST_NOEXCEPT; #endif //#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED - //! Requires: node must not be part of any tree. + //! Requires: header must not be part of any tree. //! //! Effects: Initializes the header to represent an empty tree. //! unique(header) == true. @@ -257,15 +257,15 @@ class avltree_algorithms //! //! Throws: Nothing. //! - //! Nodes: If node is inserted in a tree, this function corrupts the tree. - static void init_header(node_ptr header) + //! Nodes: If header is inserted in a tree, this function corrupts the tree. + static void init_header(node_ptr header) BOOST_NOEXCEPT { bstree_algo::init_header(header); NodeTraits::set_balance(header, NodeTraits::zero()); } //! @copydoc ::boost::intrusive::bstree_algorithms::erase(node_ptr,node_ptr) - static node_ptr erase(node_ptr header, node_ptr z) + static node_ptr erase(node_ptr header, node_ptr z) BOOST_NOEXCEPT { typename bstree_algo::data_for_rebalance info; bstree_algo::erase(header, z, info); @@ -298,49 +298,49 @@ class avltree_algorithms rebalance_after_insertion(header1, z); } - //! @copydoc ::boost::intrusive::bstree_algorithms::clone(const const_node_ptr&,node_ptr,Cloner,Disposer) + //! @copydoc ::boost::intrusive::bstree_algorithms::clone(const_node_ptr,node_ptr,Cloner,Disposer) template static void clone - (const const_node_ptr & source_header, node_ptr target_header, Cloner cloner, Disposer disposer) + (const_node_ptr source_header, node_ptr target_header, Cloner cloner, Disposer disposer) { avltree_node_cloner new_cloner(cloner); bstree_algo::clone(source_header, target_header, new_cloner, disposer); } #ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED - //! @copydoc ::boost::intrusive::bstree_algorithms::clear_and_dispose(const node_ptr&,Disposer) + //! @copydoc ::boost::intrusive::bstree_algorithms::clear_and_dispose(node_ptr,Disposer) template - static void clear_and_dispose(const node_ptr & header, Disposer disposer); + static void clear_and_dispose(node_ptr header, Disposer disposer) BOOST_NOEXCEPT; - //! @copydoc ::boost::intrusive::bstree_algorithms::lower_bound(const const_node_ptr&,const KeyType&,KeyNodePtrCompare) + //! @copydoc ::boost::intrusive::bstree_algorithms::lower_bound(const_node_ptr,const KeyType&,KeyNodePtrCompare) template static node_ptr lower_bound - (const const_node_ptr & header, const KeyType &key, KeyNodePtrCompare comp); + (const_node_ptr header, const KeyType &key, KeyNodePtrCompare comp); - //! @copydoc ::boost::intrusive::bstree_algorithms::upper_bound(const const_node_ptr&,const KeyType&,KeyNodePtrCompare) + //! @copydoc ::boost::intrusive::bstree_algorithms::upper_bound(const_node_ptr,const KeyType&,KeyNodePtrCompare) template static node_ptr upper_bound - (const const_node_ptr & header, const KeyType &key, KeyNodePtrCompare comp); + (const_node_ptr header, const KeyType &key, KeyNodePtrCompare comp); - //! @copydoc ::boost::intrusive::bstree_algorithms::find(const const_node_ptr&,const KeyType&,KeyNodePtrCompare) + //! @copydoc ::boost::intrusive::bstree_algorithms::find(const_node_ptr,const KeyType&,KeyNodePtrCompare) template static node_ptr find - (const const_node_ptr & header, const KeyType &key, KeyNodePtrCompare comp); + (const_node_ptr header, const KeyType &key, KeyNodePtrCompare comp); - //! @copydoc ::boost::intrusive::bstree_algorithms::equal_range(const const_node_ptr&,const KeyType&,KeyNodePtrCompare) + //! @copydoc ::boost::intrusive::bstree_algorithms::equal_range(const_node_ptr,const KeyType&,KeyNodePtrCompare) template static std::pair equal_range - (const const_node_ptr & header, const KeyType &key, KeyNodePtrCompare comp); + (const_node_ptr header, const KeyType &key, KeyNodePtrCompare comp); - //! @copydoc ::boost::intrusive::bstree_algorithms::bounded_range(const const_node_ptr&,const KeyType&,const KeyType&,KeyNodePtrCompare,bool,bool) + //! @copydoc ::boost::intrusive::bstree_algorithms::bounded_range(const_node_ptr,const KeyType&,const KeyType&,KeyNodePtrCompare,bool,bool) template static std::pair bounded_range - (const const_node_ptr & header, const KeyType &lower_key, const KeyType &upper_key, KeyNodePtrCompare comp + (const_node_ptr header, const KeyType &lower_key, const KeyType &upper_key, KeyNodePtrCompare comp , bool left_closed, bool right_closed); - //! @copydoc ::boost::intrusive::bstree_algorithms::count(const const_node_ptr&,const KeyType&,KeyNodePtrCompare) + //! @copydoc ::boost::intrusive::bstree_algorithms::count(const_node_ptr,const KeyType&,KeyNodePtrCompare) template - static std::size_t count(const const_node_ptr & header, const KeyType &key, KeyNodePtrCompare comp); + static std::size_t count(const_node_ptr header, const KeyType &key, KeyNodePtrCompare comp); #endif //#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED @@ -376,7 +376,7 @@ class avltree_algorithms //! @copydoc ::boost::intrusive::bstree_algorithms::insert_before(node_ptr,node_ptr,node_ptr) static node_ptr insert_before - (node_ptr header, node_ptr pos, node_ptr new_node) + (node_ptr header, node_ptr pos, node_ptr new_node) BOOST_NOEXCEPT { bstree_algo::insert_before(header, pos, new_node); rebalance_after_insertion(header, new_node); @@ -384,48 +384,48 @@ class avltree_algorithms } //! @copydoc ::boost::intrusive::bstree_algorithms::push_back(node_ptr,node_ptr) - static void push_back(node_ptr header, node_ptr new_node) + static void push_back(node_ptr header, node_ptr new_node) BOOST_NOEXCEPT { bstree_algo::push_back(header, new_node); rebalance_after_insertion(header, new_node); } //! @copydoc ::boost::intrusive::bstree_algorithms::push_front(node_ptr,node_ptr) - static void push_front(node_ptr header, node_ptr new_node) + static void push_front(node_ptr header, node_ptr new_node) BOOST_NOEXCEPT { bstree_algo::push_front(header, new_node); rebalance_after_insertion(header, new_node); } #ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED - //! @copydoc ::boost::intrusive::bstree_algorithms::insert_unique_check(const const_node_ptr&,const KeyType&,KeyNodePtrCompare,insert_commit_data&) + //! @copydoc ::boost::intrusive::bstree_algorithms::insert_unique_check(const_node_ptr,const KeyType&,KeyNodePtrCompare,insert_commit_data&) template static std::pair insert_unique_check - (const const_node_ptr & header, const KeyType &key + (const_node_ptr header, const KeyType &key ,KeyNodePtrCompare comp, insert_commit_data &commit_data); - //! @copydoc ::boost::intrusive::bstree_algorithms::insert_unique_check(const const_node_ptr&,const node_ptr&,const KeyType&,KeyNodePtrCompare,insert_commit_data&) + //! @copydoc ::boost::intrusive::bstree_algorithms::insert_unique_check(const_node_ptr,node_ptr,const KeyType&,KeyNodePtrCompare,insert_commit_data&) template static std::pair insert_unique_check - (const const_node_ptr & header, const node_ptr &hint, const KeyType &key + (const_node_ptr header, node_ptr hint, const KeyType &key ,KeyNodePtrCompare comp, insert_commit_data &commit_data); #endif //#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED //! @copydoc ::boost::intrusive::bstree_algorithms::insert_unique_commit(node_ptr,node_ptr,const insert_commit_data &) static void insert_unique_commit - (node_ptr header, node_ptr new_value, const insert_commit_data &commit_data) + (node_ptr header, node_ptr new_value, const insert_commit_data &commit_data) BOOST_NOEXCEPT { bstree_algo::insert_unique_commit(header, new_value, commit_data); rebalance_after_insertion(header, new_value); } //! @copydoc ::boost::intrusive::bstree_algorithms::is_header - static bool is_header(const const_node_ptr & p) + static bool is_header(const_node_ptr p) BOOST_NOEXCEPT { return NodeTraits::get_balance(p) == NodeTraits::zero() && bstree_algo::is_header(p); } /// @cond - static bool verify(const node_ptr &header) + static bool verify(node_ptr header) { std::size_t height; std::size_t count; @@ -483,7 +483,7 @@ class avltree_algorithms } static void rebalance_after_erasure - ( node_ptr header, node_ptr z, const typename bstree_algo::data_for_rebalance &info) + ( node_ptr header, node_ptr z, const typename bstree_algo::data_for_rebalance &info) BOOST_NOEXCEPT { if(info.y != z){ NodeTraits::set_balance(info.y, NodeTraits::get_balance(z)); @@ -492,7 +492,7 @@ class avltree_algorithms rebalance_after_erasure_restore_invariants(header, info.x, info.x_parent); } - static void rebalance_after_erasure_restore_invariants(node_ptr header, node_ptr x, node_ptr x_parent) + static void rebalance_after_erasure_restore_invariants(node_ptr header, node_ptr x, node_ptr x_parent) BOOST_NOEXCEPT { for ( node_ptr root = NodeTraits::get_parent(header) ; x != root @@ -560,7 +560,7 @@ class avltree_algorithms } } - static void rebalance_after_insertion(node_ptr header, node_ptr x) + static void rebalance_after_insertion(node_ptr header, node_ptr x) BOOST_NOEXCEPT { NodeTraits::set_balance(x, NodeTraits::zero()); // Rebalance. @@ -605,7 +605,7 @@ class avltree_algorithms } } - static void left_right_balancing(node_ptr a, node_ptr b, node_ptr c) + static void left_right_balancing(node_ptr a, node_ptr b, node_ptr c) BOOST_NOEXCEPT { // balancing... const balance c_balance = NodeTraits::get_balance(c); @@ -630,7 +630,7 @@ class avltree_algorithms } } - static node_ptr avl_rotate_left_right(const node_ptr a, const node_ptr a_oldleft, node_ptr hdr) + static node_ptr avl_rotate_left_right(const node_ptr a, const node_ptr a_oldleft, node_ptr hdr) BOOST_NOEXCEPT { // [note: 'a_oldleft' is 'b'] // | | // // a(-2) c // @@ -650,7 +650,7 @@ class avltree_algorithms return c; } - static node_ptr avl_rotate_right_left(const node_ptr a, const node_ptr a_oldright, node_ptr hdr) + static node_ptr avl_rotate_right_left(const node_ptr a, const node_ptr a_oldright, node_ptr hdr) BOOST_NOEXCEPT { // [note: 'a_oldright' is 'b'] // | | // // a(pos) c // @@ -670,7 +670,7 @@ class avltree_algorithms return c; } - static void avl_rotate_left(node_ptr x, node_ptr x_oldright, node_ptr hdr) + static void avl_rotate_left(node_ptr x, node_ptr x_oldright, node_ptr hdr) BOOST_NOEXCEPT { bstree_algo::rotate_left(x, x_oldright, NodeTraits::get_parent(x), hdr); @@ -685,7 +685,7 @@ class avltree_algorithms } } - static void avl_rotate_right(node_ptr x, node_ptr x_oldleft, node_ptr hdr) + static void avl_rotate_right(node_ptr x, node_ptr x_oldleft, node_ptr hdr) BOOST_NOEXCEPT { bstree_algo::rotate_right(x, x_oldleft, NodeTraits::get_parent(x), hdr); diff --git a/include/boost/intrusive/bs_set.hpp b/include/boost/intrusive/bs_set.hpp index cbb2a35f8..1755decf1 100644 --- a/include/boost/intrusive/bs_set.hpp +++ b/include/boost/intrusive/bs_set.hpp @@ -117,61 +117,61 @@ class bs_set_impl ~bs_set_impl(); //! @copydoc ::boost::intrusive::bstree::begin() - iterator begin(); + iterator begin() BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::bstree::begin()const - const_iterator begin() const; + const_iterator begin() const BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::bstree::cbegin()const - const_iterator cbegin() const; + const_iterator cbegin() const BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::bstree::end() - iterator end(); + iterator end() BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::bstree::end()const - const_iterator end() const; + const_iterator end() const BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::bstree::cend()const - const_iterator cend() const; + const_iterator cend() const BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::bstree::rbegin() - reverse_iterator rbegin(); + reverse_iterator rbegin() BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::bstree::rbegin()const - const_reverse_iterator rbegin() const; + const_reverse_iterator rbegin() const BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::bstree::crbegin()const - const_reverse_iterator crbegin() const; + const_reverse_iterator crbegin() const BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::bstree::rend() - reverse_iterator rend(); + reverse_iterator rend() BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::bstree::rend()const - const_reverse_iterator rend() const; + const_reverse_iterator rend() const BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::bstree::crend()const - const_reverse_iterator crend() const; + const_reverse_iterator crend() const BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::bstree::root() - iterator root(); + iterator root() BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::bstree::root()const - const_iterator root() const; + const_iterator root() const BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::bstree::croot()const - const_iterator croot() const; + const_iterator croot() const BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::bstree::container_from_end_iterator(iterator) - static bs_set_impl &container_from_end_iterator(iterator end_iterator); + static bs_set_impl &container_from_end_iterator(iterator end_iterator) BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::bstree::container_from_end_iterator(const_iterator) - static const bs_set_impl &container_from_end_iterator(const_iterator end_iterator); + static const bs_set_impl &container_from_end_iterator(const_iterator end_iterator) BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::bstree::container_from_iterator(iterator) - static bs_set_impl &container_from_iterator(iterator it); + static bs_set_impl &container_from_iterator(iterator it) BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::bstree::container_from_iterator(const_iterator) - static const bs_set_impl &container_from_iterator(const_iterator it); + static const bs_set_impl &container_from_iterator(const_iterator it) BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::bstree::key_comp()const key_compare key_comp() const; @@ -180,10 +180,10 @@ class bs_set_impl value_compare value_comp() const; //! @copydoc ::boost::intrusive::bstree::empty()const - bool empty() const; + bool empty() const BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::bstree::size()const - size_type size() const; + size_type size() const BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::bstree::swap void swap(bs_set_impl& other); @@ -241,24 +241,24 @@ class bs_set_impl { tree_type::insert_unique(b, e); } //! @copydoc ::boost::intrusive::bstree::insert_unique_commit - iterator insert_commit(reference value, const insert_commit_data &commit_data) + iterator insert_commit(reference value, const insert_commit_data &commit_data) BOOST_NOEXCEPT { return tree_type::insert_unique_commit(value, commit_data); } #ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED //! @copydoc ::boost::intrusive::bstree::insert_before - iterator insert_before(const_iterator pos, reference value); + iterator insert_before(const_iterator pos, reference value) BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::bstree::push_back - void push_back(reference value); + void push_back(reference value) BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::bstree::push_front - void push_front(reference value); + void push_front(reference value) BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::bstree::erase(const_iterator) - iterator erase(const_iterator i); + iterator erase(const_iterator i) BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::bstree::erase(const_iterator,const_iterator) - iterator erase(const_iterator b, const_iterator e); + iterator erase(const_iterator b, const_iterator e) BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::bstree::erase(const key_type &) size_type erase(const key_type &key); @@ -269,11 +269,11 @@ class bs_set_impl //! @copydoc ::boost::intrusive::bstree::erase_and_dispose(const_iterator,Disposer) template - iterator erase_and_dispose(const_iterator i, Disposer disposer); + iterator erase_and_dispose(const_iterator i, Disposer disposer) BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::bstree::erase_and_dispose(const_iterator,const_iterator,Disposer) template - iterator erase_and_dispose(const_iterator b, const_iterator e, Disposer disposer); + iterator erase_and_dispose(const_iterator b, const_iterator e, Disposer disposer) BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::bstree::erase_and_dispose(const key_type &, Disposer) template @@ -284,11 +284,11 @@ class bs_set_impl size_type erase_and_dispose(const KeyType& key, KeyTypeKeyCompare comp, Disposer disposer); //! @copydoc ::boost::intrusive::bstree::clear - void clear(); + void clear() BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::bstree::clear_and_dispose template - void clear_and_dispose(Disposer disposer); + void clear_and_dispose(Disposer disposer) BOOST_NOEXCEPT; #endif // #ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED @@ -388,28 +388,28 @@ class bs_set_impl (const KeyType& lower_key, const KeyType& upper_key, KeyTypeKeyCompare comp, bool left_closed, bool right_closed) const; //! @copydoc ::boost::intrusive::bstree::s_iterator_to(reference) - static iterator s_iterator_to(reference value); + static iterator s_iterator_to(reference value) BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::bstree::s_iterator_to(const_reference) - static const_iterator s_iterator_to(const_reference value); + static const_iterator s_iterator_to(const_reference value) BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::bstree::iterator_to(reference) - iterator iterator_to(reference value); + iterator iterator_to(reference value) BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::bstree::iterator_to(const_reference)const - const_iterator iterator_to(const_reference value) const; + const_iterator iterator_to(const_reference value) const BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::bstree::init_node(reference) - static void init_node(reference value); + static void init_node(reference value) BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::bstree::unlink_leftmost_without_rebalance - pointer unlink_leftmost_without_rebalance(); + pointer unlink_leftmost_without_rebalance() BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::bstree::replace_node - void replace_node(iterator replace_this, reference with_this); + void replace_node(iterator replace_this, reference with_this) BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::bstree::remove_node - void remove_node(reference value); + void remove_node(reference value) BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::bstree::merge_unique template @@ -552,16 +552,16 @@ class bs_set BOOST_INTRUSIVE_FORCEINLINE void clone_from(BOOST_RV_REF(bs_set) src, Cloner cloner, Disposer disposer) { Base::clone_from(BOOST_MOVE_BASE(Base, src), cloner, disposer); } - BOOST_INTRUSIVE_FORCEINLINE static bs_set &container_from_end_iterator(iterator end_iterator) + BOOST_INTRUSIVE_FORCEINLINE static bs_set &container_from_end_iterator(iterator end_iterator) BOOST_NOEXCEPT { return static_cast(Base::container_from_end_iterator(end_iterator)); } - BOOST_INTRUSIVE_FORCEINLINE static const bs_set &container_from_end_iterator(const_iterator end_iterator) + BOOST_INTRUSIVE_FORCEINLINE static const bs_set &container_from_end_iterator(const_iterator end_iterator) BOOST_NOEXCEPT { return static_cast(Base::container_from_end_iterator(end_iterator)); } - BOOST_INTRUSIVE_FORCEINLINE static bs_set &container_from_iterator(iterator it) + BOOST_INTRUSIVE_FORCEINLINE static bs_set &container_from_iterator(iterator it) BOOST_NOEXCEPT { return static_cast(Base::container_from_iterator(it)); } - BOOST_INTRUSIVE_FORCEINLINE static const bs_set &container_from_iterator(const_iterator it) + BOOST_INTRUSIVE_FORCEINLINE static const bs_set &container_from_iterator(const_iterator it) BOOST_NOEXCEPT { return static_cast(Base::container_from_iterator(it)); } }; @@ -653,61 +653,61 @@ class bs_multiset_impl ~bs_multiset_impl(); //! @copydoc ::boost::intrusive::bstree::begin() - iterator begin(); + iterator begin() BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::bstree::begin()const - const_iterator begin() const; + const_iterator begin() const BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::bstree::cbegin()const - const_iterator cbegin() const; + const_iterator cbegin() const BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::bstree::end() - iterator end(); + iterator end() BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::bstree::end()const - const_iterator end() const; + const_iterator end() const BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::bstree::cend()const - const_iterator cend() const; + const_iterator cend() const BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::bstree::rbegin() - reverse_iterator rbegin(); + reverse_iterator rbegin() BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::bstree::rbegin()const - const_reverse_iterator rbegin() const; + const_reverse_iterator rbegin() const BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::bstree::crbegin()const - const_reverse_iterator crbegin() const; + const_reverse_iterator crbegin() const BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::bstree::rend() - reverse_iterator rend(); + reverse_iterator rend() BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::bstree::rend()const - const_reverse_iterator rend() const; + const_reverse_iterator rend() const BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::bstree::crend()const - const_reverse_iterator crend() const; + const_reverse_iterator crend() const BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::bstree::root() - iterator root(); + iterator root() BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::bstree::root()const - const_iterator root() const; + const_iterator root() const BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::bstree::croot()const - const_iterator croot() const; + const_iterator croot() const BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::bstree::container_from_end_iterator(iterator) - static bs_multiset_impl &container_from_end_iterator(iterator end_iterator); + static bs_multiset_impl &container_from_end_iterator(iterator end_iterator) BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::bstree::container_from_end_iterator(const_iterator) - static const bs_multiset_impl &container_from_end_iterator(const_iterator end_iterator); + static const bs_multiset_impl &container_from_end_iterator(const_iterator end_iterator) BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::bstree::container_from_iterator(iterator) - static bs_multiset_impl &container_from_iterator(iterator it); + static bs_multiset_impl &container_from_iterator(iterator it) BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::bstree::container_from_iterator(const_iterator) - static const bs_multiset_impl &container_from_iterator(const_iterator it); + static const bs_multiset_impl &container_from_iterator(const_iterator it) BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::bstree::key_comp()const key_compare key_comp() const; @@ -716,10 +716,10 @@ class bs_multiset_impl value_compare value_comp() const; //! @copydoc ::boost::intrusive::bstree::empty()const - bool empty() const; + bool empty() const BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::bstree::size()const - size_type size() const; + size_type size() const BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::bstree::swap void swap(bs_multiset_impl& other); @@ -754,19 +754,19 @@ class bs_multiset_impl #ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED //! @copydoc ::boost::intrusive::bstree::insert_before - iterator insert_before(const_iterator pos, reference value); + iterator insert_before(const_iterator pos, reference value) BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::bstree::push_back - void push_back(reference value); + void push_back(reference value) BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::bstree::push_front - void push_front(reference value); + void push_front(reference value) BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::bstree::erase(const_iterator) - iterator erase(const_iterator i); + iterator erase(const_iterator i) BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::bstree::erase(const_iterator,const_iterator) - iterator erase(const_iterator b, const_iterator e); + iterator erase(const_iterator b, const_iterator e) BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::bstree::erase(const key_type &) size_type erase(const key_type &key); @@ -777,11 +777,11 @@ class bs_multiset_impl //! @copydoc ::boost::intrusive::bstree::erase_and_dispose(const_iterator,Disposer) template - iterator erase_and_dispose(const_iterator i, Disposer disposer); + iterator erase_and_dispose(const_iterator i, Disposer disposer) BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::bstree::erase_and_dispose(const_iterator,const_iterator,Disposer) template - iterator erase_and_dispose(const_iterator b, const_iterator e, Disposer disposer); + iterator erase_and_dispose(const_iterator b, const_iterator e, Disposer disposer) BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::bstree::erase_and_dispose(const key_type &, Disposer) template @@ -792,11 +792,11 @@ class bs_multiset_impl size_type erase_and_dispose(const KeyType& key, KeyTypeKeyCompare comp, Disposer disposer); //! @copydoc ::boost::intrusive::bstree::clear - void clear(); + void clear() BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::bstree::clear_and_dispose template - void clear_and_dispose(Disposer disposer); + void clear_and_dispose(Disposer disposer) BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::bstree::count(const key_type &)const size_type count(const key_type &key) const; @@ -882,28 +882,28 @@ class bs_multiset_impl (const KeyType& lower_key, const KeyType& upper_key, KeyTypeKeyCompare comp, bool left_closed, bool right_closed) const; //! @copydoc ::boost::intrusive::bstree::s_iterator_to(reference) - static iterator s_iterator_to(reference value); + static iterator s_iterator_to(reference value) BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::bstree::s_iterator_to(const_reference) - static const_iterator s_iterator_to(const_reference value); + static const_iterator s_iterator_to(const_reference value) BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::bstree::iterator_to(reference) - iterator iterator_to(reference value); + iterator iterator_to(reference value) BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::bstree::iterator_to(const_reference)const - const_iterator iterator_to(const_reference value) const; + const_iterator iterator_to(const_reference value) const BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::bstree::init_node(reference) - static void init_node(reference value); + static void init_node(reference value) BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::bstree::unlink_leftmost_without_rebalance - pointer unlink_leftmost_without_rebalance(); + pointer unlink_leftmost_without_rebalance() BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::bstree::replace_node - void replace_node(iterator replace_this, reference with_this); + void replace_node(iterator replace_this, reference with_this) BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::bstree::remove_node - void remove_node(reference value); + void remove_node(reference value) BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::bstree::merge_equal template @@ -1046,16 +1046,16 @@ class bs_multiset BOOST_INTRUSIVE_FORCEINLINE void clone_from(BOOST_RV_REF(bs_multiset) src, Cloner cloner, Disposer disposer) { Base::clone_from(BOOST_MOVE_BASE(Base, src), cloner, disposer); } - BOOST_INTRUSIVE_FORCEINLINE static bs_multiset &container_from_end_iterator(iterator end_iterator) + BOOST_INTRUSIVE_FORCEINLINE static bs_multiset &container_from_end_iterator(iterator end_iterator) BOOST_NOEXCEPT { return static_cast(Base::container_from_end_iterator(end_iterator)); } - BOOST_INTRUSIVE_FORCEINLINE static const bs_multiset &container_from_end_iterator(const_iterator end_iterator) + BOOST_INTRUSIVE_FORCEINLINE static const bs_multiset &container_from_end_iterator(const_iterator end_iterator) BOOST_NOEXCEPT { return static_cast(Base::container_from_end_iterator(end_iterator)); } - BOOST_INTRUSIVE_FORCEINLINE static bs_multiset &container_from_iterator(iterator it) + BOOST_INTRUSIVE_FORCEINLINE static bs_multiset &container_from_iterator(iterator it) BOOST_NOEXCEPT { return static_cast(Base::container_from_iterator(it)); } - BOOST_INTRUSIVE_FORCEINLINE static const bs_multiset &container_from_iterator(const_iterator it) + BOOST_INTRUSIVE_FORCEINLINE static const bs_multiset &container_from_iterator(const_iterator it) BOOST_NOEXCEPT { return static_cast(Base::container_from_iterator(it)); } }; diff --git a/include/boost/intrusive/bstree.hpp b/include/boost/intrusive/bstree.hpp index f9d4c3c00..51687ebd2 100644 --- a/include/boost/intrusive/bstree.hpp +++ b/include/boost/intrusive/bstree.hpp @@ -145,22 +145,22 @@ struct bstbase3 BOOST_INTRUSIVE_FORCEINLINE const_value_traits_ptr priv_value_traits_ptr() const { return pointer_traits::pointer_to(this->get_value_traits()); } - iterator begin() + BOOST_INTRUSIVE_FORCEINLINE iterator begin() BOOST_NOEXCEPT { return iterator(node_algorithms::begin_node(this->header_ptr()), this->priv_value_traits_ptr()); } - BOOST_INTRUSIVE_FORCEINLINE const_iterator begin() const + BOOST_INTRUSIVE_FORCEINLINE const_iterator begin() const BOOST_NOEXCEPT { return cbegin(); } - const_iterator cbegin() const + BOOST_INTRUSIVE_FORCEINLINE const_iterator cbegin() const BOOST_NOEXCEPT { return const_iterator(node_algorithms::begin_node(this->header_ptr()), this->priv_value_traits_ptr()); } - iterator end() + BOOST_INTRUSIVE_FORCEINLINE iterator end() BOOST_NOEXCEPT { return iterator(node_algorithms::end_node(this->header_ptr()), this->priv_value_traits_ptr()); } - BOOST_INTRUSIVE_FORCEINLINE const_iterator end() const + BOOST_INTRUSIVE_FORCEINLINE const_iterator end() const BOOST_NOEXCEPT { return cend(); } - BOOST_INTRUSIVE_FORCEINLINE const_iterator cend() const + BOOST_INTRUSIVE_FORCEINLINE const_iterator cend() const BOOST_NOEXCEPT { return const_iterator(node_algorithms::end_node(this->header_ptr()), this->priv_value_traits_ptr()); } BOOST_INTRUSIVE_FORCEINLINE iterator root() @@ -195,32 +195,32 @@ struct bstbase3 node_algorithms::replace_node( get_value_traits().to_node_ptr(*replace_this) , this->header_ptr() , get_value_traits().to_node_ptr(with_this)); - if(safemode_or_autounlink) + BOOST_IF_CONSTEXPR(safemode_or_autounlink) node_algorithms::init(replace_this.pointed_node()); } - BOOST_INTRUSIVE_FORCEINLINE void rebalance() + BOOST_INTRUSIVE_FORCEINLINE void rebalance() BOOST_NOEXCEPT { node_algorithms::rebalance(this->header_ptr()); } - iterator rebalance_subtree(iterator root) - { return iterator(node_algorithms::rebalance_subtree(root.pointed_node()), this->priv_value_traits_ptr()); } + iterator rebalance_subtree(iterator r) BOOST_NOEXCEPT + { return iterator(node_algorithms::rebalance_subtree(r.pointed_node()), this->priv_value_traits_ptr()); } - static iterator s_iterator_to(reference value) + static iterator s_iterator_to(reference value) BOOST_NOEXCEPT { BOOST_STATIC_ASSERT((!stateful_value_traits)); return iterator (value_traits::to_node_ptr(value), const_value_traits_ptr()); } - static const_iterator s_iterator_to(const_reference value) + static const_iterator s_iterator_to(const_reference value) BOOST_NOEXCEPT { BOOST_STATIC_ASSERT((!stateful_value_traits)); return const_iterator (value_traits::to_node_ptr(*pointer_traits::const_cast_from(pointer_traits::pointer_to(value))), const_value_traits_ptr()); } - iterator iterator_to(reference value) + iterator iterator_to(reference value) BOOST_NOEXCEPT { return iterator (this->get_value_traits().to_node_ptr(value), this->priv_value_traits_ptr()); } - const_iterator iterator_to(const_reference value) const + const_iterator iterator_to(const_reference value) const BOOST_NOEXCEPT { return const_iterator (this->get_value_traits().to_node_ptr(*pointer_traits::const_cast_from(pointer_traits::pointer_to(value))), this->priv_value_traits_ptr()); } BOOST_INTRUSIVE_FORCEINLINE static void init_node(reference value) @@ -301,10 +301,10 @@ struct bstbase2 : detail::ebo_functor_holder(value_compare(comp)), treeheader_t(vtraits) {} - const value_compare &comp() const + const value_compare &get_comp() const { return this->get(); } - value_compare &comp() + value_compare &get_comp() { return this->get(); } typedef BOOST_INTRUSIVE_IMPDEF(typename value_traits::pointer) pointer; @@ -315,10 +315,10 @@ struct bstbase2 typedef typename node_algorithms::insert_commit_data insert_commit_data; BOOST_INTRUSIVE_FORCEINLINE value_compare value_comp() const - { return this->comp(); } + { return this->get_comp(); } BOOST_INTRUSIVE_FORCEINLINE key_compare key_comp() const - { return this->comp().key_comp(); } + { return this->get_comp().key_comp(); } //lower_bound BOOST_INTRUSIVE_FORCEINLINE iterator lower_bound(const key_type &key) @@ -400,8 +400,8 @@ struct bstbase2 template std::pair equal_range(const KeyType &key, KeyTypeKeyCompare comp) { - std::pair ret - (node_algorithms::equal_range(this->header_ptr(), key, this->key_node_comp(comp))); + std::pair ret = + node_algorithms::equal_range(this->header_ptr(), key, this->key_node_comp(comp)); return std::pair( iterator(ret.first, this->priv_value_traits_ptr()) , iterator(ret.second, this->priv_value_traits_ptr())); } @@ -414,8 +414,8 @@ struct bstbase2 std::pair equal_range(const KeyType &key, KeyTypeKeyCompare comp) const { - std::pair ret - (node_algorithms::equal_range(this->header_ptr(), key, this->key_node_comp(comp))); + std::pair ret = + node_algorithms::equal_range(this->header_ptr(), key, this->key_node_comp(comp)); return std::pair( const_iterator(ret.first, this->priv_value_traits_ptr()) , const_iterator(ret.second, this->priv_value_traits_ptr())); } @@ -427,8 +427,8 @@ struct bstbase2 template std::pair lower_bound_range(const KeyType &key, KeyTypeKeyCompare comp) { - std::pair ret - (node_algorithms::lower_bound_range(this->header_ptr(), key, this->key_node_comp(comp))); + std::pair ret = + node_algorithms::lower_bound_range(this->header_ptr(), key, this->key_node_comp(comp)); return std::pair( iterator(ret.first, this->priv_value_traits_ptr()) , iterator(ret.second, this->priv_value_traits_ptr())); } @@ -441,8 +441,8 @@ struct bstbase2 std::pair lower_bound_range(const KeyType &key, KeyTypeKeyCompare comp) const { - std::pair ret - (node_algorithms::lower_bound_range(this->header_ptr(), key, this->key_node_comp(comp))); + std::pair ret = + node_algorithms::lower_bound_range(this->header_ptr(), key, this->key_node_comp(comp)); return std::pair( const_iterator(ret.first, this->priv_value_traits_ptr()) , const_iterator(ret.second, this->priv_value_traits_ptr())); } @@ -456,9 +456,9 @@ struct bstbase2 std::pair bounded_range (const KeyType &lower_key, const KeyType &upper_key, KeyTypeKeyCompare comp, bool left_closed, bool right_closed) { - std::pair ret - (node_algorithms::bounded_range - (this->header_ptr(), lower_key, upper_key, this->key_node_comp(comp), left_closed, right_closed)); + std::pair ret = + node_algorithms::bounded_range + (this->header_ptr(), lower_key, upper_key, this->key_node_comp(comp), left_closed, right_closed); return std::pair( iterator(ret.first, this->priv_value_traits_ptr()) , iterator(ret.second, this->priv_value_traits_ptr())); } @@ -471,9 +471,9 @@ struct bstbase2 std::pair bounded_range (const KeyType &lower_key, const KeyType &upper_key, KeyTypeKeyCompare comp, bool left_closed, bool right_closed) const { - std::pair ret - (node_algorithms::bounded_range - (this->header_ptr(), lower_key, upper_key, this->key_node_comp(comp), left_closed, right_closed)); + std::pair ret = + node_algorithms::bounded_range + (this->header_ptr(), lower_key, upper_key, this->key_node_comp(comp), left_closed, right_closed); return std::pair( const_iterator(ret.first, this->priv_value_traits_ptr()) , const_iterator(ret.second, this->priv_value_traits_ptr())); } @@ -735,7 +735,7 @@ class bstree_impl //! move constructor throws (this does not happen with predefined Boost.Intrusive hooks) //! or the move constructor of the comparison objet throws. bstree_impl(BOOST_RV_REF(bstree_impl) x) - : data_type(::boost::move(x.comp()), ::boost::move(x.get_value_traits())) + : data_type(::boost::move(x.get_comp()), ::boost::move(x.get_value_traits())) { this->swap(x); } @@ -761,42 +761,42 @@ class bstree_impl //! Complexity: Constant. //! //! Throws: Nothing. - iterator begin(); + iterator begin() BOOST_NOEXCEPT; //! Effects: Returns a const_iterator pointing to the beginning of the container. //! //! Complexity: Constant. //! //! Throws: Nothing. - const_iterator begin() const; + const_iterator begin() const BOOST_NOEXCEPT; //! Effects: Returns a const_iterator pointing to the beginning of the container. //! //! Complexity: Constant. //! //! Throws: Nothing. - const_iterator cbegin() const; + const_iterator cbegin() const BOOST_NOEXCEPT; //! Effects: Returns an iterator pointing to the end of the container. //! //! Complexity: Constant. //! //! Throws: Nothing. - iterator end(); + iterator end() BOOST_NOEXCEPT; //! Effects: Returns a const_iterator pointing to the end of the container. //! //! Complexity: Constant. //! //! Throws: Nothing. - const_iterator end() const; + const_iterator end() const BOOST_NOEXCEPT; //! Effects: Returns a const_iterator pointing to the end of the container. //! //! Complexity: Constant. //! //! Throws: Nothing. - const_iterator cend() const; + const_iterator cend() const BOOST_NOEXCEPT; //! Effects: Returns a reverse_iterator pointing to the beginning of the //! reversed container. @@ -804,7 +804,7 @@ class bstree_impl //! Complexity: Constant. //! //! Throws: Nothing. - reverse_iterator rbegin(); + reverse_iterator rbegin() BOOST_NOEXCEPT; //! Effects: Returns a const_reverse_iterator pointing to the beginning //! of the reversed container. @@ -812,7 +812,7 @@ class bstree_impl //! Complexity: Constant. //! //! Throws: Nothing. - const_reverse_iterator rbegin() const; + const_reverse_iterator rbegin() const BOOST_NOEXCEPT; //! Effects: Returns a const_reverse_iterator pointing to the beginning //! of the reversed container. @@ -820,7 +820,7 @@ class bstree_impl //! Complexity: Constant. //! //! Throws: Nothing. - const_reverse_iterator crbegin() const; + const_reverse_iterator crbegin() const BOOST_NOEXCEPT; //! Effects: Returns a reverse_iterator pointing to the end //! of the reversed container. @@ -828,7 +828,7 @@ class bstree_impl //! Complexity: Constant. //! //! Throws: Nothing. - reverse_iterator rend(); + reverse_iterator rend() BOOST_NOEXCEPT; //! Effects: Returns a const_reverse_iterator pointing to the end //! of the reversed container. @@ -836,7 +836,7 @@ class bstree_impl //! Complexity: Constant. //! //! Throws: Nothing. - const_reverse_iterator rend() const; + const_reverse_iterator rend() const BOOST_NOEXCEPT; //! Effects: Returns a const_reverse_iterator pointing to the end //! of the reversed container. @@ -844,28 +844,28 @@ class bstree_impl //! Complexity: Constant. //! //! Throws: Nothing. - const_reverse_iterator crend() const; + const_reverse_iterator crend() const BOOST_NOEXCEPT; //! Effects: Returns a iterator pointing to the root node of the container or end() if not present. //! //! Complexity: Constant. //! //! Throws: Nothing. - iterator root(); + iterator root() BOOST_NOEXCEPT; //! Effects: Returns a const_iterator pointing to the root node of the container or cend() if not present. //! //! Complexity: Constant. //! //! Throws: Nothing. - const_iterator root() const; + const_iterator root() const BOOST_NOEXCEPT; //! Effects: Returns a const_iterator pointing to the root node of the container or cend() if not present. //! //! Complexity: Constant. //! //! Throws: Nothing. - const_iterator croot() const; + const_iterator croot() const BOOST_NOEXCEPT; #endif //#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED @@ -877,7 +877,7 @@ class bstree_impl //! Throws: Nothing. //! //! Complexity: Constant. - static bstree_impl &container_from_end_iterator(iterator end_iterator) + static bstree_impl &container_from_end_iterator(iterator end_iterator) BOOST_NOEXCEPT { return static_cast (data_type::get_tree_base_from_end_iterator(end_iterator)); @@ -891,7 +891,7 @@ class bstree_impl //! Throws: Nothing. //! //! Complexity: Constant. - static const bstree_impl &container_from_end_iterator(const_iterator end_iterator) + static const bstree_impl &container_from_end_iterator(const_iterator end_iterator) BOOST_NOEXCEPT { return static_cast (data_type::get_tree_base_from_end_iterator(end_iterator)); @@ -905,7 +905,7 @@ class bstree_impl //! Throws: Nothing. //! //! Complexity: Logarithmic. - static bstree_impl &container_from_iterator(iterator it) + static bstree_impl &container_from_iterator(iterator it) BOOST_NOEXCEPT { return container_from_end_iterator(it.end_iterator_from_it()); } //! Precondition: it must be a valid end const_iterator @@ -916,7 +916,7 @@ class bstree_impl //! Throws: Nothing. //! //! Complexity: Logarithmic. - static const bstree_impl &container_from_iterator(const_iterator it) + static const bstree_impl &container_from_iterator(const_iterator it) BOOST_NOEXCEPT { return container_from_end_iterator(it.end_iterator_from_it()); } #ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED @@ -942,7 +942,7 @@ class bstree_impl //! Complexity: Constant. //! //! Throws: Nothing. - bool empty() const + bool empty() const BOOST_NOEXCEPT { if(ConstantTimeSize){ return !this->data_type::sz_traits().get_size(); @@ -958,9 +958,9 @@ class bstree_impl //! if constant-time size option is disabled. Constant time otherwise. //! //! Throws: Nothing. - size_type size() const + size_type size() const BOOST_NOEXCEPT { - if(constant_time_size) + BOOST_IF_CONSTEXPR(constant_time_size) return this->sz_traits().get_size(); else{ return (size_type)node_algorithms::size(this->header_ptr()); @@ -975,7 +975,7 @@ class bstree_impl void swap(bstree_impl& other) { //This can throw - ::boost::adl_move_swap(this->comp(), other.comp()); + ::boost::adl_move_swap(this->get_comp(), other.get_comp()); //These can't throw node_algorithms::swap_tree(this->header_ptr(), node_ptr(other.header_ptr())); this->sz_traits().swap(other.sz_traits()); @@ -1008,7 +1008,7 @@ class bstree_impl ,detail::node_cloner (cloner, &this->get_value_traits()) ,detail::node_disposer(disposer, &this->get_value_traits())); this->sz_traits().set_size(src.sz_traits().get_size()); - this->comp() = src.comp(); + this->get_comp() = src.get_comp(); rollback.release(); } } @@ -1043,7 +1043,7 @@ class bstree_impl ,detail::node_cloner (cloner, &this->get_value_traits()) ,detail::node_disposer(disposer, &this->get_value_traits())); this->sz_traits().set_size(src.sz_traits().get_size()); - this->comp() = src.comp(); + this->get_comp() = src.get_comp(); rollback.release(); } } @@ -1103,7 +1103,7 @@ class bstree_impl //! size of the range. However, it is linear in N if the range is already sorted //! by value_comp(). //! - //! Throws: Nothing. + //! Throws: If the comparison functor call throws. //! //! Note: Does not affect the validity of iterators and references. //! No copy-constructors are called. @@ -1123,7 +1123,7 @@ class bstree_impl //! Complexity: Average complexity for insert element is at //! most logarithmic. //! - //! Throws: Nothing. + //! Throws: If the comparison functor call throws. //! //! Note: Does not affect the validity of iterators and references. //! No copy-constructors are called. @@ -1149,7 +1149,7 @@ class bstree_impl //! constant time (two comparisons in the worst case) //! if t is inserted immediately before hint. //! - //! Throws: Nothing. + //! Throws: If the comparison functor call throws. //! //! Note: Does not affect the validity of iterators and references. //! No copy-constructors are called. @@ -1172,7 +1172,7 @@ class bstree_impl //! size of the range. However, it is linear in N if the range is already sorted //! by value_comp(). //! - //! Throws: Nothing. + //! Throws: If the comparison functor call throws. //! //! Note: Does not affect the validity of iterators and references. //! No copy-constructors are called. @@ -1312,7 +1312,7 @@ class bstree_impl //! Notes: This function has only sense if a "insert_check" has been //! previously executed to fill "commit_data". No value should be inserted or //! erased between the "insert_check" and "insert_commit" calls. - iterator insert_unique_commit(reference value, const insert_commit_data &commit_data) + iterator insert_unique_commit(reference value, const insert_commit_data &commit_data) BOOST_NOEXCEPT { node_ptr to_insert(this->get_value_traits().to_node_ptr(value)); BOOST_INTRUSIVE_SAFE_HOOK_DEFAULT_ASSERT(!safemode_or_autounlink || node_algorithms::unique(to_insert)); @@ -1325,8 +1325,8 @@ class bstree_impl } //Check if the insertion point is correct to detect wrong //uses insert_unique_check - BOOST_ASSERT(( p == this->end() || !this->comp()(*p, value) )); - BOOST_ASSERT(( p == this->begin() || !this->comp()(value, *--p) )); + BOOST_ASSERT(( p == this->end() || !this->get_comp()(*p, value) )); + BOOST_ASSERT(( p == this->begin() || !this->get_comp()(value, *--p) )); #endif node_algorithms::insert_unique_commit @@ -1349,7 +1349,7 @@ class bstree_impl //! the successor of "value" container ordering invariant will be broken. //! This is a low-level function to be used only for performance reasons //! by advanced users. - iterator insert_before(const_iterator pos, reference value) + iterator insert_before(const_iterator pos, reference value) BOOST_NOEXCEPT { node_ptr to_insert(this->get_value_traits().to_node_ptr(value)); BOOST_INTRUSIVE_SAFE_HOOK_DEFAULT_ASSERT(!safemode_or_autounlink || node_algorithms::unique(to_insert)); @@ -1372,7 +1372,7 @@ class bstree_impl //! This function is slightly more efficient than using "insert_before". //! This is a low-level function to be used only for performance reasons //! by advanced users. - void push_back(reference value) + void push_back(reference value) BOOST_NOEXCEPT { node_ptr to_insert(this->get_value_traits().to_node_ptr(value)); BOOST_INTRUSIVE_SAFE_HOOK_DEFAULT_ASSERT(!safemode_or_autounlink || node_algorithms::unique(to_insert)); @@ -1394,7 +1394,7 @@ class bstree_impl //! This function is slightly more efficient than using "insert_before". //! This is a low-level function to be used only for performance reasons //! by advanced users. - void push_front(reference value) + void push_front(reference value) BOOST_NOEXCEPT { node_ptr to_insert(this->get_value_traits().to_node_ptr(value)); BOOST_INTRUSIVE_SAFE_HOOK_DEFAULT_ASSERT(!safemode_or_autounlink || node_algorithms::unique(to_insert)); @@ -1410,7 +1410,7 @@ class bstree_impl //! //! Note: Invalidates the iterators (but not the references) //! to the erased elements. No destructors are called. - iterator erase(const_iterator i) + iterator erase(const_iterator i) BOOST_NOEXCEPT { const_iterator ret(i); ++ret; @@ -1418,7 +1418,7 @@ class bstree_impl BOOST_INTRUSIVE_SAFE_HOOK_DEFAULT_ASSERT(!safemode_or_autounlink || !node_algorithms::unique(to_erase)); node_algorithms::erase(this->header_ptr(), to_erase); this->sz_traits().decrement(); - if(safemode_or_autounlink) + BOOST_IF_CONSTEXPR(safemode_or_autounlink) node_algorithms::init(to_erase); return ret.unconst(); } @@ -1432,7 +1432,7 @@ class bstree_impl //! //! Note: Invalidates the iterators (but not the references) //! to the erased elements. No destructors are called. - iterator erase(const_iterator b, const_iterator e) + iterator erase(const_iterator b, const_iterator e) BOOST_NOEXCEPT { size_type n; return this->private_erase(b, e, n); } //! Effects: Erases all the elements with the given value. @@ -1445,7 +1445,7 @@ class bstree_impl //! //! Note: Invalidates the iterators (but not the references) //! to the erased elements. No destructors are called. - size_type erase(const key_type &key) + size_type erase(const key_type &key) BOOST_NOEXCEPT { return this->erase(key, this->key_comp()); } //! Requires: key is a value such that `*this` is partitioned with respect to @@ -1486,7 +1486,7 @@ class bstree_impl //! Note: Invalidates the iterators //! to the erased elements. template - iterator erase_and_dispose(const_iterator i, Disposer disposer) + iterator erase_and_dispose(const_iterator i, Disposer disposer) BOOST_NOEXCEPT { node_ptr to_erase(i.pointed_node()); iterator ret(this->erase(i)); @@ -1529,7 +1529,7 @@ class bstree_impl //! Note: Invalidates the iterators //! to the erased elements. template - iterator erase_and_dispose(const_iterator b, const_iterator e, Disposer disposer) + iterator erase_and_dispose(const_iterator b, const_iterator e, Disposer disposer) BOOST_NOEXCEPT { size_type n; return this->private_erase(b, e, n, disposer); } //! Requires: key is a value such that `*this` is partitioned with respect to @@ -1570,9 +1570,9 @@ class bstree_impl //! //! Note: Invalidates the iterators (but not the references) //! to the erased elements. No destructors are called. - void clear() + void clear() BOOST_NOEXCEPT { - if(safemode_or_autounlink){ + BOOST_IF_CONSTEXPR(safemode_or_autounlink){ this->clear_and_dispose(detail::null_disposer()); } else{ @@ -1591,7 +1591,7 @@ class bstree_impl //! Note: Invalidates the iterators (but not the references) //! to the erased elements. Calls N times to disposer functor. template - void clear_and_dispose(Disposer disposer) + void clear_and_dispose(Disposer disposer) BOOST_NOEXCEPT { node_algorithms::clear_and_dispose(this->header_ptr() , detail::node_disposer(disposer, &this->get_value_traits())); @@ -1834,7 +1834,7 @@ class bstree_impl //! //! Note: This static function is available only if the value traits //! is stateless. - static iterator s_iterator_to(reference value); + static iterator s_iterator_to(reference value) BOOST_NOEXCEPT; //! Requires: value must be an lvalue and shall be in a set of //! appropriate type. Otherwise the behavior is undefined. @@ -1848,7 +1848,7 @@ class bstree_impl //! //! Note: This static function is available only if the value traits //! is stateless. - static const_iterator s_iterator_to(const_reference value); + static const_iterator s_iterator_to(const_reference value) BOOST_NOEXCEPT; //! Requires: value must be an lvalue and shall be in a set of //! appropriate type. Otherwise the behavior is undefined. @@ -1859,7 +1859,7 @@ class bstree_impl //! Complexity: Constant. //! //! Throws: Nothing. - iterator iterator_to(reference value); + iterator iterator_to(reference value) BOOST_NOEXCEPT; //! Requires: value must be an lvalue and shall be in a set of //! appropriate type. Otherwise the behavior is undefined. @@ -1870,7 +1870,7 @@ class bstree_impl //! Complexity: Constant. //! //! Throws: Nothing. - const_iterator iterator_to(const_reference value) const; + const_iterator iterator_to(const_reference value) const BOOST_NOEXCEPT; //! Requires: value shall not be in a container. //! @@ -1883,7 +1883,7 @@ class bstree_impl //! //! Note: This function puts the hook in the well-known default state //! used by auto_unlink and safe hooks. - static void init_node(reference value); + static void init_node(reference value) BOOST_NOEXCEPT; #endif //#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED) @@ -1897,14 +1897,14 @@ class bstree_impl //! only be used for more unlink_leftmost_without_rebalance calls. //! This function is normally used to achieve a step by step //! controlled destruction of the container. - pointer unlink_leftmost_without_rebalance() + pointer unlink_leftmost_without_rebalance() BOOST_NOEXCEPT { node_ptr to_be_disposed(node_algorithms::unlink_leftmost_without_rebalance (this->header_ptr())); if(!to_be_disposed) return 0; this->sz_traits().decrement(); - if(safemode_or_autounlink)//If this is commented does not work with normal_link + BOOST_IF_CONSTEXPR(safemode_or_autounlink)//If this is commented does not work with normal_link node_algorithms::init(to_be_disposed); return this->get_value_traits().to_value_ptr(to_be_disposed); } @@ -1925,14 +1925,14 @@ class bstree_impl //! with_this is not equivalent to *replace_this according to the //! ordering rules. This function is faster than erasing and inserting //! the node, since no rebalancing or comparison is needed. - void replace_node(iterator replace_this, reference with_this); + void replace_node(iterator replace_this, reference with_this) BOOST_NOEXCEPT; //! Effects: Rebalances the tree. //! //! Throws: Nothing. //! //! Complexity: Linear. - void rebalance(); + void rebalance() BOOST_NOEXCEPT; //! Requires: old_root is a node of a tree. //! @@ -1943,7 +1943,7 @@ class bstree_impl //! Throws: Nothing. //! //! Complexity: Linear to the elements in the subtree. - iterator rebalance_subtree(iterator root); + iterator rebalance_subtree(iterator r) BOOST_NOEXCEPT; #endif //#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED) @@ -1959,12 +1959,12 @@ class bstree_impl //! If the user calls //! this function with a constant time size container or stateful comparison //! functor a compilation error will be issued. - static void remove_node(reference value) + static void remove_node(reference value) BOOST_NOEXCEPT { BOOST_STATIC_ASSERT((!constant_time_size)); node_ptr to_remove(value_traits::to_node_ptr(value)); node_algorithms::unlink(to_remove); - if(safemode_or_autounlink) + BOOST_IF_CONSTEXPR(safemode_or_autounlink) node_algorithms::init(to_remove); } @@ -2216,16 +2216,16 @@ class bstree BOOST_INTRUSIVE_FORCEINLINE void clone_from(BOOST_RV_REF(bstree) src, Cloner cloner, Disposer disposer) { Base::clone_from(BOOST_MOVE_BASE(Base, src), cloner, disposer); } - BOOST_INTRUSIVE_FORCEINLINE static bstree &container_from_end_iterator(iterator end_iterator) + BOOST_INTRUSIVE_FORCEINLINE static bstree &container_from_end_iterator(iterator end_iterator) BOOST_NOEXCEPT { return static_cast(Base::container_from_end_iterator(end_iterator)); } - BOOST_INTRUSIVE_FORCEINLINE static const bstree &container_from_end_iterator(const_iterator end_iterator) + BOOST_INTRUSIVE_FORCEINLINE static const bstree &container_from_end_iterator(const_iterator end_iterator) BOOST_NOEXCEPT { return static_cast(Base::container_from_end_iterator(end_iterator)); } - BOOST_INTRUSIVE_FORCEINLINE static bstree &container_from_iterator(iterator it) + BOOST_INTRUSIVE_FORCEINLINE static bstree &container_from_iterator(iterator it) BOOST_NOEXCEPT { return static_cast(Base::container_from_iterator(it)); } - BOOST_INTRUSIVE_FORCEINLINE static const bstree &container_from_iterator(const_iterator it) + BOOST_INTRUSIVE_FORCEINLINE static const bstree &container_from_iterator(const_iterator it) BOOST_NOEXCEPT { return static_cast(Base::container_from_iterator(it)); } }; diff --git a/include/boost/intrusive/bstree_algorithms.hpp b/include/boost/intrusive/bstree_algorithms.hpp index e85e96466..5113a584b 100644 --- a/include/boost/intrusive/bstree_algorithms.hpp +++ b/include/boost/intrusive/bstree_algorithms.hpp @@ -1,6 +1,7 @@ ///////////////////////////////////////////////////////////////////////////// // -// (C) Copyright Ion Gaztanaga 2007-2014 +// (C) Copyright Ion Gaztanaga 2007-2021 +// (C) Copyright Daniel Steck 2021 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at @@ -79,7 +80,7 @@ struct bstree_node_checker : base_checker_t(extra_checker), comp_(comp) {} - void operator () (const const_node_ptr& p, + void operator () (const_node_ptr p, const return_type& check_return_left, const return_type& check_return_right, return_type& check_return) { @@ -185,7 +186,7 @@ class bstree_algorithms : public bstree_algorithms_base template struct dispose_subtree_disposer { - BOOST_INTRUSIVE_FORCEINLINE dispose_subtree_disposer(Disposer &disp, const node_ptr & subtree) + BOOST_INTRUSIVE_FORCEINLINE dispose_subtree_disposer(Disposer &disp, node_ptr subtree) : disposer_(&disp), subtree_(subtree) {} @@ -212,7 +213,7 @@ class bstree_algorithms : public bstree_algorithms_base //! Complexity: Constant time. //! //! Throws: Nothing. - BOOST_INTRUSIVE_FORCEINLINE static node_ptr begin_node(const const_node_ptr & header) + BOOST_INTRUSIVE_FORCEINLINE static node_ptr begin_node(const_node_ptr header) BOOST_NOEXCEPT { return node_traits::get_left(header); } //! Requires: 'header' is the header node of a tree. @@ -222,7 +223,7 @@ class bstree_algorithms : public bstree_algorithms_base //! Complexity: Constant time. //! //! Throws: Nothing. - BOOST_INTRUSIVE_FORCEINLINE static node_ptr end_node(const const_node_ptr & header) + BOOST_INTRUSIVE_FORCEINLINE static node_ptr end_node(const_node_ptr header) BOOST_NOEXCEPT { return detail::uncast(header); } //! Requires: 'header' is the header node of a tree. @@ -232,13 +233,13 @@ class bstree_algorithms : public bstree_algorithms_base //! Complexity: Constant time. //! //! Throws: Nothing. - BOOST_INTRUSIVE_FORCEINLINE static node_ptr root_node(const const_node_ptr & header) + BOOST_INTRUSIVE_FORCEINLINE static node_ptr root_node(const_node_ptr header) BOOST_NOEXCEPT { node_ptr p = node_traits::get_parent(header); return p ? p : detail::uncast(header); } - //! Requires: 'node' is a node of the tree or a node initialized + //! Requires: 'n' is a node of the tree or a node initialized //! by init(...) or init_node. //! //! Effects: Returns true if the node is initialized by init() or init_node(). @@ -246,18 +247,18 @@ class bstree_algorithms : public bstree_algorithms_base //! Complexity: Constant time. //! //! Throws: Nothing. - BOOST_INTRUSIVE_FORCEINLINE static bool unique(const const_node_ptr & node) - { return !NodeTraits::get_parent(node); } + BOOST_INTRUSIVE_FORCEINLINE static bool unique(const_node_ptr n) BOOST_NOEXCEPT + { return !NodeTraits::get_parent(n); } #if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED) - //! Requires: 'node' is a node of the tree or a header node. + //! Requires: 'n' is a node of the tree or a header node. //! //! Effects: Returns the header of the tree. //! //! Complexity: Logarithmic. //! //! Throws: Nothing. - static node_ptr get_header(const const_node_ptr & node); + static node_ptr get_header(const_node_ptr n); #endif //! Requires: node1 and node2 can't be header nodes @@ -275,7 +276,7 @@ class bstree_algorithms : public bstree_algorithms_base //! node1 and node2 are not equivalent according to the ordering rules. //! //!Experimental function - static void swap_nodes(node_ptr node1, node_ptr node2) + static void swap_nodes(node_ptr node1, node_ptr node2) BOOST_NOEXCEPT { if(node1 == node2) return; @@ -299,7 +300,7 @@ class bstree_algorithms : public bstree_algorithms_base //! node1 and node2 are not equivalent according to the ordering rules. //! //!Experimental function - static void swap_nodes(node_ptr node1, node_ptr header1, node_ptr node2, node_ptr header2) + static void swap_nodes(node_ptr node1, node_ptr header1, node_ptr node2, node_ptr header2) BOOST_NOEXCEPT { if(node1 == node2) return; @@ -396,38 +397,47 @@ class bstree_algorithms : public bstree_algorithms_base NodeTraits::set_parent(node1, NodeTraits::get_parent(node2)); NodeTraits::set_parent(node2, temp); - //Now adjust adjacent nodes for newly inserted node 1 + //Now adjust child nodes for newly inserted node 1 if((temp = NodeTraits::get_left(node1))){ NodeTraits::set_parent(temp, node1); } if((temp = NodeTraits::get_right(node1))){ NodeTraits::set_parent(temp, node1); } - if((temp = NodeTraits::get_parent(node1)) && - //The header has been already updated so avoid it - temp != header2){ - if(NodeTraits::get_left(temp) == node2){ - NodeTraits::set_left(temp, node1); - } - if(NodeTraits::get_right(temp) == node2){ - NodeTraits::set_right(temp, node1); - } - } - //Now adjust adjacent nodes for newly inserted node 2 + //Now adjust child nodes for newly inserted node 2 if((temp = NodeTraits::get_left(node2))){ NodeTraits::set_parent(temp, node2); } if((temp = NodeTraits::get_right(node2))){ NodeTraits::set_parent(temp, node2); } - if((temp = NodeTraits::get_parent(node2)) && - //The header has been already updated so avoid it - temp != header1){ - if(NodeTraits::get_left(temp) == node1){ - NodeTraits::set_left(temp, node2); + + //Finally adjust parent nodes + if ((temp = NodeTraits::get_parent(node1)) == NodeTraits::get_parent(node2)) { + // special logic for the case where the nodes are siblings + const node_ptr left = NodeTraits::get_left(temp); + NodeTraits::set_left(temp, NodeTraits::get_right(temp)); + NodeTraits::set_right(temp, left); + } else { + if ((temp = NodeTraits::get_parent(node1)) && + //The header has been already updated so avoid it + temp != header2) { + if (NodeTraits::get_left(temp) == node2) { + NodeTraits::set_left(temp, node1); + } + if (NodeTraits::get_right(temp) == node2) { + NodeTraits::set_right(temp, node1); + } } - if(NodeTraits::get_right(temp) == node1){ - NodeTraits::set_right(temp, node2); + if ((temp = NodeTraits::get_parent(node2)) && + //The header has been already updated so avoid it + temp != header1) { + if (NodeTraits::get_left(temp) == node1) { + NodeTraits::set_left(temp, node2); + } + if (NodeTraits::get_right(temp) == node1) { + NodeTraits::set_right(temp, node2); + } } } } @@ -446,10 +456,8 @@ class bstree_algorithms : public bstree_algorithms_base //! new_node is not equivalent to node_to_be_replaced according to the //! ordering rules. This function is faster than erasing and inserting //! the node, since no rebalancing and comparison is needed. Experimental function - BOOST_INTRUSIVE_FORCEINLINE static void replace_node(node_ptr node_to_be_replaced, node_ptr new_node) + BOOST_INTRUSIVE_FORCEINLINE static void replace_node(node_ptr node_to_be_replaced, node_ptr new_node) BOOST_NOEXCEPT { - if(node_to_be_replaced == new_node) - return; replace_node(node_to_be_replaced, base_type::get_header(node_to_be_replaced), new_node); } @@ -467,10 +475,9 @@ class bstree_algorithms : public bstree_algorithms_base //! new_node is not equivalent to node_to_be_replaced according to the //! ordering rules. This function is faster than erasing and inserting //! the node, since no rebalancing or comparison is needed. Experimental function - static void replace_node(node_ptr node_to_be_replaced, node_ptr header, node_ptr new_node) + static void replace_node(node_ptr node_to_be_replaced, node_ptr header, node_ptr new_node) BOOST_NOEXCEPT { - if(node_to_be_replaced == new_node) - return; + BOOST_ASSERT(node_to_be_replaced != new_node); //Update header if necessary if(node_to_be_replaced == NodeTraits::get_left(header)){ @@ -511,44 +518,44 @@ class bstree_algorithms : public bstree_algorithms_base } #if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED) - //! Requires: 'node' is a node from the tree except the header. + //! Requires: 'n' is a node from the tree except the header. //! //! Effects: Returns the next node of the tree. //! //! Complexity: Average constant time. //! //! Throws: Nothing. - static node_ptr next_node(const node_ptr & node); + static node_ptr next_node(node_ptr n) BOOST_NOEXCEPT; - //! Requires: 'node' is a node from the tree except the leftmost node. + //! Requires: 'n' is a node from the tree except the leftmost node. //! //! Effects: Returns the previous node of the tree. //! //! Complexity: Average constant time. //! //! Throws: Nothing. - static node_ptr prev_node(const node_ptr & node); + static node_ptr prev_node(node_ptr n) BOOST_NOEXCEPT; - //! Requires: 'node' is a node of a tree but not the header. + //! Requires: 'n' is a node of a tree but not the header. //! //! Effects: Returns the minimum node of the subtree starting at p. //! //! Complexity: Logarithmic to the size of the subtree. //! //! Throws: Nothing. - static node_ptr minimum(node_ptr node); + static node_ptr minimum(node_ptr n); - //! Requires: 'node' is a node of a tree but not the header. + //! Requires: 'n' is a node of a tree but not the header. //! //! Effects: Returns the maximum node of the subtree starting at p. //! //! Complexity: Logarithmic to the size of the subtree. //! //! Throws: Nothing. - static node_ptr maximum(node_ptr node); + static node_ptr maximum(node_ptr n); #endif - //! Requires: 'node' must not be part of any tree. + //! Requires: 'n' must not be part of any tree. //! //! Effects: After the function unique(node) == true. //! @@ -557,11 +564,11 @@ class bstree_algorithms : public bstree_algorithms_base //! Throws: Nothing. //! //! Nodes: If node is inserted in a tree, this function corrupts the tree. - BOOST_INTRUSIVE_FORCEINLINE static void init(node_ptr node) + static void init(node_ptr n) BOOST_NOEXCEPT { - NodeTraits::set_parent(node, node_ptr()); - NodeTraits::set_left(node, node_ptr()); - NodeTraits::set_right(node, node_ptr()); + NodeTraits::set_parent(n, node_ptr()); + NodeTraits::set_left(n, node_ptr()); + NodeTraits::set_right(n, node_ptr()); } //! Effects: Returns true if node is in the same state as if called init(node) @@ -569,14 +576,14 @@ class bstree_algorithms : public bstree_algorithms_base //! Complexity: Constant. //! //! Throws: Nothing. - BOOST_INTRUSIVE_FORCEINLINE static bool inited(const const_node_ptr & node) + static bool inited(const_node_ptr n) { - return !NodeTraits::get_parent(node) && - !NodeTraits::get_left(node) && - !NodeTraits::get_right(node) ; + return !NodeTraits::get_parent(n) && + !NodeTraits::get_left(n) && + !NodeTraits::get_right(n) ; } - //! Requires: node must not be part of any tree. + //! Requires: header must not be part of any tree. //! //! Effects: Initializes the header to represent an empty tree. //! unique(header) == true. @@ -585,8 +592,8 @@ class bstree_algorithms : public bstree_algorithms_base //! //! Throws: Nothing. //! - //! Nodes: If node is inserted in a tree, this function corrupts the tree. - BOOST_INTRUSIVE_FORCEINLINE static void init_header(node_ptr header) + //! Nodes: If header is inserted in a tree, this function corrupts the tree. + static void init_header(node_ptr header) BOOST_NOEXCEPT { NodeTraits::set_parent(header, node_ptr()); NodeTraits::set_left(header, header); @@ -597,15 +604,15 @@ class bstree_algorithms : public bstree_algorithms_base //! taking a node_ptr parameter and shouldn't throw. //! //! Effects: Empties the target tree calling - //! void disposer::operator()(const node_ptr &) for every node of the tree + //! void disposer::operator()(node_ptr) for every node of the tree //! except the header. //! //! Complexity: Linear to the number of element of the source tree plus the. //! number of elements of tree target tree when calling this function. //! - //! Throws: If cloner functor throws. If this happens target nodes are disposed. + //! Throws: Nothing. template - static void clear_and_dispose(const node_ptr & header, Disposer disposer) + static void clear_and_dispose(node_ptr header, Disposer disposer) BOOST_NOEXCEPT { node_ptr source_root = NodeTraits::get_parent(header); if(!source_root) @@ -627,7 +634,7 @@ class bstree_algorithms : public bstree_algorithms_base //! only be used for more unlink_leftmost_without_rebalance calls. //! This function is normally used to achieve a step by step //! controlled destruction of the tree. - static node_ptr unlink_leftmost_without_rebalance(node_ptr header) + static node_ptr unlink_leftmost_without_rebalance(node_ptr header) BOOST_NOEXCEPT { node_ptr leftmost = NodeTraits::get_left(header); if (leftmost == header) @@ -657,14 +664,14 @@ class bstree_algorithms : public bstree_algorithms_base return leftmost; } - //! Requires: node is a node of the tree but it's not the header. + //! Requires: 'header' the header of the tree. //! - //! Effects: Returns the number of nodes of the subtree. + //! Effects: Returns the number of nodes of the tree. //! //! Complexity: Linear time. //! //! Throws: Nothing. - static std::size_t size(const const_node_ptr & header) + static std::size_t size(const_node_ptr header) BOOST_NOEXCEPT { node_ptr beg(begin_node(header)); node_ptr end(end_node(header)); @@ -682,7 +689,7 @@ class bstree_algorithms : public bstree_algorithms_base //! Complexity: Constant. //! //! Throws: Nothing. - static void swap_tree(node_ptr header1, node_ptr header2) + static void swap_tree(node_ptr header1, node_ptr header2) BOOST_NOEXCEPT { if(header1 == header2) return; @@ -730,7 +737,7 @@ class bstree_algorithms : public bstree_algorithms_base //! Complexity: Constant. //! //! Throws: Nothing. - static bool is_header(const const_node_ptr & p); + static bool is_header(const_node_ptr p) BOOST_NOEXCEPT; #endif //! Requires: "header" must be the header node of a tree. @@ -746,7 +753,7 @@ class bstree_algorithms : public bstree_algorithms_base //! Throws: If "comp" throws. template static node_ptr find - (const const_node_ptr & header, const KeyType &key, KeyNodePtrCompare comp) + (const_node_ptr header, const KeyType &key, KeyNodePtrCompare comp) { node_ptr end = detail::uncast(header); node_ptr y = lower_bound(header, key, comp); @@ -776,7 +783,7 @@ class bstree_algorithms : public bstree_algorithms_base //! Note: Experimental function, the interface might change. template< class KeyType, class KeyNodePtrCompare> static std::pair bounded_range - ( const const_node_ptr & header + ( const_node_ptr header , const KeyType &lower_key , const KeyType &upper_key , KeyNodePtrCompare comp @@ -843,7 +850,7 @@ class bstree_algorithms : public bstree_algorithms_base //! Throws: If "comp" throws. template static std::size_t count - (const const_node_ptr & header, const KeyType &key, KeyNodePtrCompare comp) + (const_node_ptr header, const KeyType &key, KeyNodePtrCompare comp) { std::pair ret = equal_range(header, key, comp); std::size_t n = 0; @@ -869,7 +876,7 @@ class bstree_algorithms : public bstree_algorithms_base //! Throws: If "comp" throws. template BOOST_INTRUSIVE_FORCEINLINE static std::pair equal_range - (const const_node_ptr & header, const KeyType &key, KeyNodePtrCompare comp) + (const_node_ptr header, const KeyType &key, KeyNodePtrCompare comp) { return bounded_range(header, key, key, comp, true, true); } @@ -889,7 +896,7 @@ class bstree_algorithms : public bstree_algorithms_base //! Throws: If "comp" throws. template static std::pair lower_bound_range - (const const_node_ptr & header, const KeyType &key, KeyNodePtrCompare comp) + (const_node_ptr header, const KeyType &key, KeyNodePtrCompare comp) { node_ptr const lb(lower_bound(header, key, comp)); std::pair ret_ii(lb, lb); @@ -913,7 +920,7 @@ class bstree_algorithms : public bstree_algorithms_base //! Throws: If "comp" throws. template BOOST_INTRUSIVE_FORCEINLINE static node_ptr lower_bound - (const const_node_ptr & header, const KeyType &key, KeyNodePtrCompare comp) + (const_node_ptr header, const KeyType &key, KeyNodePtrCompare comp) { return lower_bound_loop(NodeTraits::get_parent(header), detail::uncast(header), key, comp); } @@ -931,7 +938,7 @@ class bstree_algorithms : public bstree_algorithms_base //! Throws: If "comp" throws. template BOOST_INTRUSIVE_FORCEINLINE static node_ptr upper_bound - (const const_node_ptr & header, const KeyType &key, KeyNodePtrCompare comp) + (const_node_ptr header, const KeyType &key, KeyNodePtrCompare comp) { return upper_bound_loop(NodeTraits::get_parent(header), detail::uncast(header), key, comp); } @@ -954,7 +961,7 @@ class bstree_algorithms : public bstree_algorithms_base //! previously executed to fill "commit_data". No value should be inserted or //! erased between the "insert_check" and "insert_commit" calls. BOOST_INTRUSIVE_FORCEINLINE static void insert_unique_commit - (node_ptr header, node_ptr new_value, const insert_commit_data &commit_data) + (node_ptr header, node_ptr new_value, const insert_commit_data &commit_data) BOOST_NOEXCEPT { return insert_commit(header, new_value, commit_data); } //! Requires: "header" must be the header node of a tree. @@ -993,7 +1000,7 @@ class bstree_algorithms : public bstree_algorithms_base //! if no more objects are inserted or erased from the set. template static std::pair insert_unique_check - (const const_node_ptr & header, const KeyType &key + (const_node_ptr header, const KeyType &key ,KeyNodePtrCompare comp, insert_commit_data &commit_data #ifndef BOOST_INTRUSIVE_DOXYGEN_INVOKED , std::size_t *pdepth = 0 @@ -1071,7 +1078,7 @@ class bstree_algorithms : public bstree_algorithms_base //! if no more objects are inserted or erased from the set. template static std::pair insert_unique_check - (const const_node_ptr & header, const node_ptr &hint, const KeyType &key + (const_node_ptr header, node_ptr hint, const KeyType &key ,KeyNodePtrCompare comp, insert_commit_data &commit_data #ifndef BOOST_INTRUSIVE_DOXYGEN_INVOKED , std::size_t *pdepth = 0 @@ -1194,7 +1201,7 @@ class bstree_algorithms : public bstree_algorithms_base #ifndef BOOST_INTRUSIVE_DOXYGEN_INVOKED , std::size_t *pdepth = 0 #endif - ) + ) BOOST_NOEXCEPT { insert_commit_data commit_data; insert_before_check(header, pos, commit_data, pdepth); @@ -1220,7 +1227,7 @@ class bstree_algorithms : public bstree_algorithms_base #ifndef BOOST_INTRUSIVE_DOXYGEN_INVOKED , std::size_t *pdepth = 0 #endif - ) + ) BOOST_NOEXCEPT { insert_commit_data commit_data; push_back_check(header, commit_data, pdepth); @@ -1245,14 +1252,14 @@ class bstree_algorithms : public bstree_algorithms_base #ifndef BOOST_INTRUSIVE_DOXYGEN_INVOKED , std::size_t *pdepth = 0 #endif - ) + ) BOOST_NOEXCEPT { insert_commit_data commit_data; push_front_check(header, commit_data, pdepth); insert_commit(header, new_node, commit_data); } - //! Requires: 'node' can't be a header node. + //! Requires: 'n' can't be a header node. //! //! Effects: Calculates the depth of a node: the depth of a //! node is the length (number of edges) of the path from the root @@ -1261,13 +1268,13 @@ class bstree_algorithms : public bstree_algorithms_base //! Complexity: Logarithmic to the number of nodes in the tree. //! //! Throws: Nothing. - static std::size_t depth(const_node_ptr node) + static std::size_t depth(const_node_ptr n) BOOST_NOEXCEPT { std::size_t depth = 0; node_ptr p_parent; - while(node != NodeTraits::get_parent(p_parent = NodeTraits::get_parent(node))){ + while(n != NodeTraits::get_parent(p_parent = NodeTraits::get_parent(n))){ ++depth; - node = p_parent; + n = p_parent; } return depth; } @@ -1277,13 +1284,13 @@ class bstree_algorithms : public bstree_algorithms_base //! take a node_ptr and shouldn't throw. //! //! Effects: First empties target tree calling - //! void disposer::operator()(const node_ptr &) for every node of the tree + //! void disposer::operator()(node_ptr) for every node of the tree //! except the header. //! //! Then, duplicates the entire tree pointed by "source_header" cloning each - //! source node with node_ptr Cloner::operator()(const node_ptr &) to obtain + //! source node with node_ptr Cloner::operator()(node_ptr) to obtain //! the nodes of the target tree. If "cloner" throws, the cloned target nodes - //! are disposed using void disposer(const node_ptr &). + //! are disposed using void disposer(node_ptr ). //! //! Complexity: Linear to the number of element of the source tree plus the //! number of elements of tree target tree when calling this function. @@ -1291,7 +1298,7 @@ class bstree_algorithms : public bstree_algorithms_base //! Throws: If cloner functor throws. If this happens target nodes are disposed. template static void clone - (const const_node_ptr & source_header, node_ptr target_header, Cloner cloner, Disposer disposer) + (const_node_ptr source_header, node_ptr target_header, Cloner cloner, Disposer disposer) { if(!unique(target_header)){ clear_and_dispose(target_header, disposer); @@ -1315,7 +1322,7 @@ class bstree_algorithms : public bstree_algorithms_base //! Complexity: Amortized constant time. //! //! Throws: Nothing. - BOOST_INTRUSIVE_FORCEINLINE static void erase(node_ptr header, node_ptr z) + BOOST_INTRUSIVE_FORCEINLINE static void erase(node_ptr header, node_ptr z) BOOST_NOEXCEPT { data_for_rebalance ignored; erase(header, z, ignored); @@ -1358,20 +1365,20 @@ class bstree_algorithms : public bstree_algorithms_base transfer_equal(header1, comp, header2, z, ignored); } - //! Requires: node is a tree node but not the header. + //! Requires: 'n' is a tree node but not the header. //! //! Effects: Unlinks the node and rebalances the tree. //! //! Complexity: Average complexity is constant time. //! //! Throws: Nothing. - static void unlink(node_ptr node) + static void unlink(node_ptr n) BOOST_NOEXCEPT { - node_ptr x = NodeTraits::get_parent(node); + node_ptr x = NodeTraits::get_parent(n); if(x){ while(!base_type::is_header(x)) x = NodeTraits::get_parent(x); - erase(x, node); + erase(x, n); } } @@ -1382,7 +1389,7 @@ class bstree_algorithms : public bstree_algorithms_base //! Throws: Nothing. //! //! Complexity: Linear. - static void rebalance(node_ptr header) + static void rebalance(node_ptr header) BOOST_NOEXCEPT { node_ptr root = NodeTraits::get_parent(header); if(root){ @@ -1399,7 +1406,7 @@ class bstree_algorithms : public bstree_algorithms_base //! Throws: Nothing. //! //! Complexity: Linear. - static node_ptr rebalance_subtree(node_ptr old_root) + static node_ptr rebalance_subtree(node_ptr old_root) BOOST_NOEXCEPT { //Taken from: //"Tree rebalancing in optimal time and space" @@ -1448,7 +1455,7 @@ class bstree_algorithms : public bstree_algorithms_base //! Note: The method might not have effect when asserts are turned off (e.g., with NDEBUG). //! Experimental function, interface might change in future versions. template - static void check(const const_node_ptr& header, Checker checker, typename Checker::return_type& checker_return) + static void check(const_node_ptr header, Checker checker, typename Checker::return_type& checker_return) { const_node_ptr root_node_ptr = NodeTraits::get_parent(header); if (!root_node_ptr){ @@ -1578,14 +1585,14 @@ class bstree_algorithms : public bstree_algorithms_base info.x_parent = x_parent; } - //! Requires: node is a node of the tree but it's not the header. + //! Requires: 'subtree' is a node of the tree but it's not the header. //! //! Effects: Returns the number of nodes of the subtree. //! //! Complexity: Linear time. //! //! Throws: Nothing. - static std::size_t subtree_size(const const_node_ptr & subtree) + static std::size_t subtree_size(const_node_ptr subtree) BOOST_NOEXCEPT { std::size_t count = 0; if (subtree){ @@ -1628,7 +1635,7 @@ class bstree_algorithms : public bstree_algorithms_base //! Complexity: Constant. //! //! Throws: Nothing. - BOOST_INTRUSIVE_FORCEINLINE static bool is_left_child(const node_ptr & p) + BOOST_INTRUSIVE_FORCEINLINE static bool is_left_child(node_ptr p) BOOST_NOEXCEPT { return NodeTraits::get_left(NodeTraits::get_parent(p)) == p; } //! Requires: p is a node of a tree. @@ -1638,7 +1645,7 @@ class bstree_algorithms : public bstree_algorithms_base //! Complexity: Constant. //! //! Throws: Nothing. - BOOST_INTRUSIVE_FORCEINLINE static bool is_right_child(const node_ptr & p) + BOOST_INTRUSIVE_FORCEINLINE static bool is_right_child(node_ptr p) BOOST_NOEXCEPT { return NodeTraits::get_right(NodeTraits::get_parent(p)) == p; } static void insert_before_check @@ -1665,7 +1672,7 @@ class bstree_algorithms : public bstree_algorithms_base #ifndef BOOST_INTRUSIVE_DOXYGEN_INVOKED , std::size_t *pdepth = 0 #endif - ) + ) BOOST_NOEXCEPT { node_ptr prev(NodeTraits::get_right(header)); if(pdepth){ @@ -1680,7 +1687,7 @@ class bstree_algorithms : public bstree_algorithms_base #ifndef BOOST_INTRUSIVE_DOXYGEN_INVOKED , std::size_t *pdepth = 0 #endif - ) + ) BOOST_NOEXCEPT { node_ptr pos(NodeTraits::get_left(header)); if(pdepth){ @@ -1758,7 +1765,7 @@ class bstree_algorithms : public bstree_algorithms_base } static void insert_commit - (node_ptr header, node_ptr new_node, const insert_commit_data &commit_data) + (node_ptr header, node_ptr new_node, const insert_commit_data &commit_data) BOOST_NOEXCEPT { //Check if commit_data has not been initialized by a insert_unique_check call. BOOST_INTRUSIVE_INVARIANT_ASSERT(commit_data.node != node_ptr()); @@ -1784,7 +1791,7 @@ class bstree_algorithms : public bstree_algorithms_base } //Fix header and own's parent data when replacing x with own, providing own's old data with parent - static void set_child(node_ptr header, node_ptr new_child, node_ptr new_parent, const bool link_left) + static void set_child(node_ptr header, node_ptr new_child, node_ptr new_parent, const bool link_left) BOOST_NOEXCEPT { if(new_parent == header) NodeTraits::set_parent(header, new_child); @@ -1795,7 +1802,7 @@ class bstree_algorithms : public bstree_algorithms_base } // rotate p to left (no header and p's parent fixup) - static void rotate_left_no_parent_fix(node_ptr p, node_ptr p_right) + static void rotate_left_no_parent_fix(node_ptr p, node_ptr p_right) BOOST_NOEXCEPT { node_ptr p_right_left(NodeTraits::get_left(p_right)); NodeTraits::set_right(p, p_right_left); @@ -1807,7 +1814,7 @@ class bstree_algorithms : public bstree_algorithms_base } // rotate p to left (with header and p's parent fixup) - static void rotate_left(node_ptr p, node_ptr p_right, node_ptr p_parent, node_ptr header) + static void rotate_left(node_ptr p, node_ptr p_right, node_ptr p_parent, node_ptr header) BOOST_NOEXCEPT { const bool p_was_left(NodeTraits::get_left(p_parent) == p); rotate_left_no_parent_fix(p, p_right); @@ -1816,7 +1823,7 @@ class bstree_algorithms : public bstree_algorithms_base } // rotate p to right (no header and p's parent fixup) - static void rotate_right_no_parent_fix(node_ptr p, node_ptr p_left) + static void rotate_right_no_parent_fix(node_ptr p, node_ptr p_left) BOOST_NOEXCEPT { node_ptr p_left_right(NodeTraits::get_right(p_left)); NodeTraits::set_left(p, p_left_right); @@ -1828,7 +1835,7 @@ class bstree_algorithms : public bstree_algorithms_base } // rotate p to right (with header and p's parent fixup) - static void rotate_right(node_ptr p, node_ptr p_left, node_ptr p_parent, node_ptr header) + static void rotate_right(node_ptr p, node_ptr p_left, node_ptr p_parent, node_ptr header) BOOST_NOEXCEPT { const bool p_was_left(NodeTraits::get_left(p_parent) == p); rotate_right_no_parent_fix(p, p_left); @@ -1838,7 +1845,7 @@ class bstree_algorithms : public bstree_algorithms_base private: - static void subtree_to_vine(node_ptr vine_tail, std::size_t &size) + static void subtree_to_vine(node_ptr vine_tail, std::size_t &size) BOOST_NOEXCEPT { //Inspired by LibAVL: //It uses a clever optimization for trees with parent pointers. @@ -1865,7 +1872,7 @@ class bstree_algorithms : public bstree_algorithms_base size = len; } - static void compress_subtree(node_ptr scanner, std::size_t count) + static void compress_subtree(node_ptr scanner, std::size_t count) BOOST_NOEXCEPT { while(count--){ //compress "count" spine nodes in the tree with pseudo-root scanner node_ptr child = NodeTraits::get_right(scanner); @@ -1882,7 +1889,7 @@ class bstree_algorithms : public bstree_algorithms_base } } - static void vine_to_subtree(node_ptr super_root, std::size_t count) + static void vine_to_subtree(node_ptr super_root, std::size_t count) BOOST_NOEXCEPT { const std::size_t one_szt = 1u; std::size_t leaf_nodes = count + one_szt - std::size_t(one_szt << detail::floor_log2(count + one_szt)); @@ -1909,10 +1916,10 @@ class bstree_algorithms : public bstree_algorithms_base //! Complexity: Logarithmic. //! //! Throws: Nothing. - static node_ptr get_root(const node_ptr & node) + static node_ptr get_root(node_ptr n) BOOST_NOEXCEPT { - BOOST_INTRUSIVE_INVARIANT_ASSERT((!inited(node))); - node_ptr x = NodeTraits::get_parent(node); + BOOST_INTRUSIVE_INVARIANT_ASSERT((!inited(n))); + node_ptr x = NodeTraits::get_parent(n); if(x){ while(!base_type::is_header(x)){ x = NodeTraits::get_parent(x); @@ -1920,13 +1927,13 @@ class bstree_algorithms : public bstree_algorithms_base return x; } else{ - return node; + return n; } } template static node_ptr clone_subtree - (const const_node_ptr &source_parent, node_ptr target_parent + (const_node_ptr source_parent, node_ptr target_parent , Cloner cloner, Disposer disposer , node_ptr &leftmost_out, node_ptr &rightmost_out ) @@ -2001,7 +2008,7 @@ class bstree_algorithms : public bstree_algorithms_base } template - static void dispose_subtree(node_ptr x, Disposer disposer) + static void dispose_subtree(node_ptr x, Disposer disposer) BOOST_NOEXCEPT { while (x){ node_ptr save(NodeTraits::get_left(x)); @@ -2052,23 +2059,23 @@ class bstree_algorithms : public bstree_algorithms_base } template - static void check_subtree(const const_node_ptr& node, Checker checker, typename Checker::return_type& check_return) + static void check_subtree(const_node_ptr n, Checker checker, typename Checker::return_type& check_return) { - const_node_ptr left = NodeTraits::get_left(node); - const_node_ptr right = NodeTraits::get_right(node); + const_node_ptr left = NodeTraits::get_left(n); + const_node_ptr right = NodeTraits::get_right(n); typename Checker::return_type check_return_left; typename Checker::return_type check_return_right; if (left) { - BOOST_INTRUSIVE_INVARIANT_ASSERT(NodeTraits::get_parent(left) == node); + BOOST_INTRUSIVE_INVARIANT_ASSERT(NodeTraits::get_parent(left) == n); check_subtree(left, checker, check_return_left); } if (right) { - BOOST_INTRUSIVE_INVARIANT_ASSERT(NodeTraits::get_parent(right) == node); + BOOST_INTRUSIVE_INVARIANT_ASSERT(NodeTraits::get_parent(right) == n); check_subtree(right, checker, check_return_right); } - checker(node, check_return_left, check_return_right, check_return); + checker(n, check_return_left, check_return_right, check_return); } }; diff --git a/include/boost/intrusive/circular_list_algorithms.hpp b/include/boost/intrusive/circular_list_algorithms.hpp index e5d417504..ab34c7e30 100644 --- a/include/boost/intrusive/circular_list_algorithms.hpp +++ b/include/boost/intrusive/circular_list_algorithms.hpp @@ -16,8 +16,8 @@ #include #include +#include #include -#include #include #if defined(BOOST_HAS_PRAGMA_ONCE) @@ -67,7 +67,7 @@ class circular_list_algorithms //! Complexity: Constant //! //! Throws: Nothing. - BOOST_INTRUSIVE_FORCEINLINE static void init(node_ptr this_node) + static void init(node_ptr this_node) BOOST_NOEXCEPT { const node_ptr null_node = node_ptr(); NodeTraits::set_next(this_node, null_node); @@ -80,7 +80,7 @@ class circular_list_algorithms //! Complexity: Constant //! //! Throws: Nothing. - BOOST_INTRUSIVE_FORCEINLINE static bool inited(const const_node_ptr &this_node) + BOOST_INTRUSIVE_FORCEINLINE static bool inited(const_node_ptr this_node) BOOST_NOEXCEPT { return !NodeTraits::get_next(this_node); } //! Effects: Constructs an empty list, making this_node the only @@ -91,12 +91,21 @@ class circular_list_algorithms //! Complexity: Constant //! //! Throws: Nothing. - BOOST_INTRUSIVE_FORCEINLINE static void init_header(node_ptr this_node) + static void init_header(node_ptr this_node) BOOST_NOEXCEPT { NodeTraits::set_next(this_node, this_node); NodeTraits::set_previous(this_node, this_node); } + //! Effects: Returns true if this_node_points to an empty list. + //! + //! Complexity: Constant + //! + //! Throws: Nothing. + BOOST_INTRUSIVE_FORCEINLINE static bool is_empty(const_node_ptr this_node) BOOST_NOEXCEPT + { + return NodeTraits::get_next(this_node) == this_node; + } //! Requires: this_node must be in a circular list or be an empty circular list. //! @@ -106,7 +115,7 @@ class circular_list_algorithms //! Complexity: Constant //! //! Throws: Nothing. - BOOST_INTRUSIVE_FORCEINLINE static bool unique(const const_node_ptr &this_node) + static bool unique(const_node_ptr this_node) BOOST_NOEXCEPT { node_ptr next = NodeTraits::get_next(this_node); return !next || next == this_node; @@ -120,7 +129,7 @@ class circular_list_algorithms //! Complexity: Linear //! //! Throws: Nothing. - static std::size_t count(const const_node_ptr &this_node) + static std::size_t count(const_node_ptr this_node) BOOST_NOEXCEPT { std::size_t result = 0; const_node_ptr p = this_node; @@ -138,7 +147,7 @@ class circular_list_algorithms //! Complexity: Constant //! //! Throws: Nothing. - BOOST_INTRUSIVE_FORCEINLINE static node_ptr unlink(node_ptr this_node) + static node_ptr unlink(node_ptr this_node) BOOST_NOEXCEPT { node_ptr next(NodeTraits::get_next(this_node)); node_ptr prev(NodeTraits::get_previous(this_node)); @@ -154,7 +163,7 @@ class circular_list_algorithms //! Complexity: Constant //! //! Throws: Nothing. - BOOST_INTRUSIVE_FORCEINLINE static void unlink(node_ptr b, node_ptr e) + static void unlink(node_ptr b, node_ptr e) BOOST_NOEXCEPT { if (b != e) { node_ptr prevb(NodeTraits::get_previous(b)); @@ -170,7 +179,7 @@ class circular_list_algorithms //! Complexity: Constant //! //! Throws: Nothing. - BOOST_INTRUSIVE_FORCEINLINE static void link_before(node_ptr nxt_node, node_ptr this_node) + static void link_before(node_ptr nxt_node, node_ptr this_node) BOOST_NOEXCEPT { node_ptr prev(NodeTraits::get_previous(nxt_node)); NodeTraits::set_previous(this_node, prev); @@ -189,7 +198,7 @@ class circular_list_algorithms //! Complexity: Constant //! //! Throws: Nothing. - BOOST_INTRUSIVE_FORCEINLINE static void link_after(node_ptr prev_node, node_ptr this_node) + static void link_after(node_ptr prev_node, node_ptr this_node) BOOST_NOEXCEPT { node_ptr next(NodeTraits::get_next(prev_node)); NodeTraits::set_previous(this_node, prev_node); @@ -211,7 +220,7 @@ class circular_list_algorithms //! Complexity: Constant //! //! Throws: Nothing. - static void swap_nodes(node_ptr this_node, node_ptr other_node) + static void swap_nodes(node_ptr this_node, node_ptr other_node) BOOST_NOEXCEPT { if (other_node == this_node) return; @@ -252,9 +261,9 @@ class circular_list_algorithms //! Complexity: Constant //! //! Throws: Nothing. - static void transfer(node_ptr p, node_ptr b, node_ptr e) + static void transfer(node_ptr p, node_ptr b, node_ptr e) BOOST_NOEXCEPT { - if (b != e) { + if (b != e && p != b && p != e) { node_ptr prev_p(NodeTraits::get_previous(p)); node_ptr prev_b(NodeTraits::get_previous(b)); node_ptr prev_e(NodeTraits::get_previous(e)); @@ -277,7 +286,7 @@ class circular_list_algorithms //! Complexity: Constant //! //! Throws: Nothing. - static void transfer(node_ptr p, node_ptr i) + static void transfer(node_ptr p, node_ptr i) BOOST_NOEXCEPT { node_ptr n(NodeTraits::get_next(i)); if(n != p && i != p){ @@ -298,7 +307,7 @@ class circular_list_algorithms //! Throws: Nothing. //! //! Complexity: This function is linear time. - static void reverse(node_ptr p) + static void reverse(node_ptr p) BOOST_NOEXCEPT { node_ptr f(NodeTraits::get_next(p)); node_ptr i(NodeTraits::get_next(f)), e(p); @@ -316,7 +325,7 @@ class circular_list_algorithms //! Throws: Nothing. //! //! Complexity: Linear to the number of moved positions. - static void move_backwards(node_ptr p, std::size_t n) + static void move_backwards(node_ptr p, std::size_t n) BOOST_NOEXCEPT { //Null shift, nothing to do if(!n) return; @@ -336,7 +345,7 @@ class circular_list_algorithms //! Throws: Nothing. //! //! Complexity: Linear to the number of moved positions. - static void move_forward(node_ptr p, std::size_t n) + static void move_forward(node_ptr p, std::size_t n) BOOST_NOEXCEPT { //Null shift, nothing to do if(!n) return; @@ -359,12 +368,11 @@ class circular_list_algorithms //! Complexity: Linear //! //! Throws: Nothing. - static std::size_t distance(const const_node_ptr &f, const const_node_ptr &l) + static std::size_t distance(const_node_ptr f, const_node_ptr l) BOOST_NOEXCEPT { - const_node_ptr i(f); std::size_t result = 0; - while(i != l){ - i = NodeTraits::get_next(i); + while(f != l){ + f = NodeTraits::get_next(f); ++result; } return result; @@ -397,7 +405,7 @@ class circular_list_algorithms new_f = cur; bcur = cur; cur = node_traits::get_next(cur); - BOOST_TRY{ + BOOST_INTRUSIVE_TRY{ //Main loop while(cur != end){ if(pred(cur)){ //Might throw @@ -418,12 +426,12 @@ class circular_list_algorithms } } } - BOOST_CATCH(...){ + BOOST_INTRUSIVE_CATCH(...){ node_traits::set_next (last_to_remove, new_f); node_traits::set_previous(new_f, last_to_remove); - BOOST_RETHROW; + BOOST_INTRUSIVE_RETHROW; } - BOOST_CATCH_END + BOOST_INTRUSIVE_CATCH_END node_traits::set_next(last_to_remove, new_f); node_traits::set_previous(new_f, last_to_remove); break; @@ -435,14 +443,14 @@ class circular_list_algorithms } private: - BOOST_INTRUSIVE_FORCEINLINE static void swap_prev(node_ptr this_node, node_ptr other_node) + static void swap_prev(node_ptr this_node, node_ptr other_node) BOOST_NOEXCEPT { node_ptr temp(NodeTraits::get_previous(this_node)); NodeTraits::set_previous(this_node, NodeTraits::get_previous(other_node)); NodeTraits::set_previous(other_node, temp); } - BOOST_INTRUSIVE_FORCEINLINE static void swap_next(node_ptr this_node, node_ptr other_node) + static void swap_next(node_ptr this_node, node_ptr other_node) BOOST_NOEXCEPT { node_ptr temp(NodeTraits::get_next(this_node)); NodeTraits::set_next(this_node, NodeTraits::get_next(other_node)); diff --git a/include/boost/intrusive/circular_slist_algorithms.hpp b/include/boost/intrusive/circular_slist_algorithms.hpp index bc5b48178..5ce4e8cdb 100644 --- a/include/boost/intrusive/circular_slist_algorithms.hpp +++ b/include/boost/intrusive/circular_slist_algorithms.hpp @@ -18,6 +18,7 @@ #include #include #include +#include #include #if defined(BOOST_HAS_PRAGMA_ONCE) @@ -72,7 +73,7 @@ class circular_slist_algorithms //! Complexity: Constant //! //! Throws: Nothing. - static void init(node_ptr this_node); + static void init(node_ptr this_node) BOOST_NOEXCEPT; //! Requires: this_node must be in a circular list or be an empty circular list. //! @@ -83,7 +84,7 @@ class circular_slist_algorithms //! Complexity: Constant //! //! Throws: Nothing. - static bool unique(const_node_ptr this_node); + static bool unique(const_node_ptr this_node) BOOST_NOEXCEPT; //! Effects: Returns true is "this_node" has the same state as //! if it was inited using "init(node_ptr)" @@ -91,7 +92,7 @@ class circular_slist_algorithms //! Complexity: Constant //! //! Throws: Nothing. - static bool inited(const_node_ptr this_node); + static bool inited(const_node_ptr this_node) BOOST_NOEXCEPT; //! Requires: prev_node must be in a circular list or be an empty circular list. //! @@ -100,7 +101,7 @@ class circular_slist_algorithms //! Complexity: Constant //! //! Throws: Nothing. - static void unlink_after(node_ptr prev_node); + static void unlink_after(node_ptr prev_node) BOOST_NOEXCEPT; //! Requires: prev_node and last_node must be in a circular list //! or be an empty circular list. @@ -110,7 +111,7 @@ class circular_slist_algorithms //! Complexity: Constant //! //! Throws: Nothing. - static void unlink_after(node_ptr prev_node, node_ptr last_node); + static void unlink_after(node_ptr prev_node, node_ptr last_node) BOOST_NOEXCEPT; //! Requires: prev_node must be a node of a circular list. //! @@ -119,7 +120,7 @@ class circular_slist_algorithms //! Complexity: Constant //! //! Throws: Nothing. - static void link_after(node_ptr prev_node, node_ptr this_node); + static void link_after(node_ptr prev_node, node_ptr this_node) BOOST_NOEXCEPT; //! Requires: b and e must be nodes of the same circular list or an empty range. //! and p must be a node of a different circular list. @@ -130,7 +131,11 @@ class circular_slist_algorithms //! Complexity: Constant //! //! Throws: Nothing. - static void transfer_after(node_ptr p, node_ptr b, node_ptr e); + static void transfer_after(node_ptr p, node_ptr b, node_ptr e) BOOST_NOEXCEPT; + + #else + + using base_t::transfer_after; #endif //#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED) @@ -141,9 +146,44 @@ class circular_slist_algorithms //! Complexity: Constant //! //! Throws: Nothing. - BOOST_INTRUSIVE_FORCEINLINE static void init_header(node_ptr this_node) + BOOST_INTRUSIVE_FORCEINLINE static void init_header(node_ptr this_node) BOOST_NOEXCEPT { NodeTraits::set_next(this_node, this_node); } + //! Requires: 'p' is the first node of a list. + //! + //! Effects: Returns a pointer to a node that represents the "end" (one past end) node + //! + //! Complexity: Constant time. + //! + //! Throws: Nothing. + BOOST_INTRUSIVE_FORCEINLINE static node_ptr end_node(const_node_ptr p) BOOST_NOEXCEPT + { return detail::uncast(p); } + + //! Effects: Returns true if this_node_points to an empty list. + //! + //! Complexity: Constant + //! + //! Throws: Nothing. + BOOST_INTRUSIVE_FORCEINLINE static bool is_empty(const_node_ptr this_node) BOOST_NOEXCEPT + { return NodeTraits::get_next(this_node) == this_node; } + + //! Effects: Returns true if this_node points to a sentinel node. + //! + //! Complexity: Constant + //! + //! Throws: Nothing. + BOOST_INTRUSIVE_FORCEINLINE static bool is_sentinel(const_node_ptr this_node) BOOST_NOEXCEPT + { return NodeTraits::get_next(this_node) == node_ptr(); } + + //! Effects: Marks this node as a "sentinel" node, a special state that is different from "empty", + //! that can be used to mark a special state of the list + //! + //! Complexity: Constant + //! + //! Throws: Nothing. + BOOST_INTRUSIVE_FORCEINLINE static void set_sentinel(node_ptr this_node) BOOST_NOEXCEPT + { NodeTraits::set_next(this_node, node_ptr()); } + //! Requires: this_node and prev_init_node must be in the same circular list. //! //! Effects: Returns the previous node of this_node in the circular list starting. @@ -153,7 +193,7 @@ class circular_slist_algorithms //! Complexity: Linear to the number of elements between prev_init_node and this_node. //! //! Throws: Nothing. - BOOST_INTRUSIVE_FORCEINLINE static node_ptr get_previous_node(const node_ptr &prev_init_node, const node_ptr &this_node) + BOOST_INTRUSIVE_FORCEINLINE static node_ptr get_previous_node(node_ptr prev_init_node, node_ptr this_node) BOOST_NOEXCEPT { return base_t::get_previous_node(prev_init_node, this_node); } //! Requires: this_node must be in a circular list or be an empty circular list. @@ -163,7 +203,7 @@ class circular_slist_algorithms //! Complexity: Linear to the number of elements in the circular list. //! //! Throws: Nothing. - BOOST_INTRUSIVE_FORCEINLINE static node_ptr get_previous_node(const node_ptr & this_node) + BOOST_INTRUSIVE_FORCEINLINE static node_ptr get_previous_node(node_ptr this_node) BOOST_NOEXCEPT { return base_t::get_previous_node(this_node, this_node); } //! Requires: this_node must be in a circular list or be an empty circular list. @@ -173,7 +213,7 @@ class circular_slist_algorithms //! Complexity: Linear to the number of elements in the circular list. //! //! Throws: Nothing. - BOOST_INTRUSIVE_FORCEINLINE static node_ptr get_previous_previous_node(const node_ptr & this_node) + BOOST_INTRUSIVE_FORCEINLINE static node_ptr get_previous_previous_node(node_ptr this_node) BOOST_NOEXCEPT { return get_previous_previous_node(this_node, this_node); } //! Requires: this_node and p must be in the same circular list. @@ -185,7 +225,7 @@ class circular_slist_algorithms //! Complexity: Linear to the number of elements in the circular list. //! //! Throws: Nothing. - static node_ptr get_previous_previous_node(node_ptr p, const node_ptr & this_node) + static node_ptr get_previous_previous_node(node_ptr p, node_ptr this_node) BOOST_NOEXCEPT { node_ptr p_next = NodeTraits::get_next(p); node_ptr p_next_next = NodeTraits::get_next(p_next); @@ -205,7 +245,7 @@ class circular_slist_algorithms //! Complexity: Linear //! //! Throws: Nothing. - static std::size_t count(const const_node_ptr & this_node) + static std::size_t count(const_node_ptr this_node) BOOST_NOEXCEPT { std::size_t result = 0; const_node_ptr p = this_node; @@ -223,7 +263,7 @@ class circular_slist_algorithms //! Complexity: Linear to the number of elements in the circular list //! //! Throws: Nothing. - BOOST_INTRUSIVE_FORCEINLINE static void unlink(node_ptr this_node) + static void unlink(node_ptr this_node) BOOST_NOEXCEPT { if(NodeTraits::get_next(this_node)) base_t::unlink_after(get_previous_node(this_node)); @@ -236,7 +276,7 @@ class circular_slist_algorithms //! Complexity: Linear to the number of elements in the circular list. //! //! Throws: Nothing. - BOOST_INTRUSIVE_FORCEINLINE static void link_before (node_ptr nxt_node, node_ptr this_node) + BOOST_INTRUSIVE_FORCEINLINE static void link_before (node_ptr nxt_node, node_ptr this_node) BOOST_NOEXCEPT { base_t::link_after(get_previous_node(nxt_node), this_node); } //! Requires: this_node and other_node must be nodes inserted @@ -249,7 +289,7 @@ class circular_slist_algorithms //! Complexity: Linear to number of elements of both lists //! //! Throws: Nothing. - static void swap_nodes(node_ptr this_node, node_ptr other_node) + static void swap_nodes(node_ptr this_node, node_ptr other_node) BOOST_NOEXCEPT { if (other_node == this_node) return; @@ -275,7 +315,7 @@ class circular_slist_algorithms //! Throws: Nothing. //! //! Complexity: This function is linear to the contained elements. - static void reverse(node_ptr p) + static void reverse(node_ptr p) BOOST_NOEXCEPT { node_ptr i = NodeTraits::get_next(p), e(p); for (;;) { @@ -294,7 +334,7 @@ class circular_slist_algorithms //! Throws: Nothing. //! //! Complexity: Linear to the number of elements plus the number moved positions. - static node_ptr move_backwards(node_ptr p, std::size_t n) + static node_ptr move_backwards(node_ptr p, std::size_t n) BOOST_NOEXCEPT { //Null shift, nothing to do if(!n) return node_ptr(); @@ -346,7 +386,7 @@ class circular_slist_algorithms //! Throws: Nothing. //! //! Complexity: Linear to the number of elements plus the number moved positions. - static node_ptr move_forward(node_ptr p, std::size_t n) + static node_ptr move_forward(node_ptr p, std::size_t n) BOOST_NOEXCEPT { //Null shift, nothing to do if(!n) return node_ptr(); @@ -386,6 +426,35 @@ class circular_slist_algorithms base_t::link_after(new_last, p); return new_last; } + + //! Requires: other must be a list and p must be a node of a different list. + //! + //! Effects: Transfers all nodes from other after p in p's list. + //! + //! Complexity: Linear + //! + //! Throws: Nothing. + static void transfer_after(node_ptr p, node_ptr other) BOOST_NOEXCEPT + { + node_ptr other_last((get_previous_node)(other)); + base_t::transfer_after(p, other, other_last); + } + + //! Requires: "disposer" must be an object function + //! taking a node_ptr parameter and shouldn't throw. + //! + //! Effects: Unlinks all nodes reachable from p (but not p) and calls + //! void disposer::operator()(node_ptr) for every node of the list + //! where p is linked. + //! + //! Returns: The number of disposed nodes + //! + //! Complexity: Linear to the number of element of the list. + //! + //! Throws: Nothing. + template + BOOST_INTRUSIVE_FORCEINLINE static std::size_t detach_and_dispose(node_ptr p, Disposer disposer) BOOST_NOEXCEPT + { return base_t::unlink_after_and_dispose(p, p, disposer); } }; /// @cond diff --git a/include/boost/intrusive/derivation_value_traits.hpp b/include/boost/intrusive/derivation_value_traits.hpp index 223b98363..626031257 100644 --- a/include/boost/intrusive/derivation_value_traits.hpp +++ b/include/boost/intrusive/derivation_value_traits.hpp @@ -52,18 +52,18 @@ struct derivation_value_traits pointer_traits::reference const_reference; static const link_mode_type link_mode = LinkMode; - static node_ptr to_node_ptr(reference value) + BOOST_INTRUSIVE_FORCEINLINE static node_ptr to_node_ptr(reference value) BOOST_NOEXCEPT { return node_ptr(&value); } - static const_node_ptr to_node_ptr(const_reference value) + BOOST_INTRUSIVE_FORCEINLINE static const_node_ptr to_node_ptr(const_reference value) BOOST_NOEXCEPT { return node_ptr(&value); } - static pointer to_value_ptr(const node_ptr &n) + BOOST_INTRUSIVE_FORCEINLINE static pointer to_value_ptr(node_ptr n) BOOST_NOEXCEPT { return pointer_traits::pointer_to(static_cast(*n)); } - static const_pointer to_value_ptr(const const_node_ptr &n) + BOOST_INTRUSIVE_FORCEINLINE static const_pointer to_value_ptr(const_node_ptr n) BOOST_NOEXCEPT { return pointer_traits::pointer_to(static_cast(*n)); } diff --git a/include/boost/intrusive/detail/any_node_and_algorithms.hpp b/include/boost/intrusive/detail/any_node_and_algorithms.hpp index f04491840..7949eecdb 100644 --- a/include/boost/intrusive/detail/any_node_and_algorithms.hpp +++ b/include/boost/intrusive/detail/any_node_and_algorithms.hpp @@ -49,13 +49,13 @@ struct any_list_node_traits typedef typename node::node_ptr node_ptr; typedef typename node::const_node_ptr const_node_ptr; - BOOST_INTRUSIVE_FORCEINLINE static node_ptr get_next(const const_node_ptr & n) + BOOST_INTRUSIVE_FORCEINLINE static node_ptr get_next(const_node_ptr n) { return n->node_ptr_1; } BOOST_INTRUSIVE_FORCEINLINE static void set_next(node_ptr n, node_ptr next) { n->node_ptr_1 = next; } - BOOST_INTRUSIVE_FORCEINLINE static node_ptr get_previous(const const_node_ptr & n) + BOOST_INTRUSIVE_FORCEINLINE static node_ptr get_previous(const_node_ptr n) { return n->node_ptr_2; } BOOST_INTRUSIVE_FORCEINLINE static void set_previous(node_ptr n, node_ptr prev) @@ -70,7 +70,7 @@ struct any_slist_node_traits typedef typename node::node_ptr node_ptr; typedef typename node::const_node_ptr const_node_ptr; - BOOST_INTRUSIVE_FORCEINLINE static node_ptr get_next(const const_node_ptr & n) + BOOST_INTRUSIVE_FORCEINLINE static node_ptr get_next(const_node_ptr n) { return n->node_ptr_1; } BOOST_INTRUSIVE_FORCEINLINE static void set_next(node_ptr n, node_ptr next) @@ -90,22 +90,22 @@ struct any_unordered_node_traits static const bool store_hash = true; static const bool optimize_multikey = true; - BOOST_INTRUSIVE_FORCEINLINE static node_ptr get_next(const const_node_ptr & n) + BOOST_INTRUSIVE_FORCEINLINE static node_ptr get_next(const_node_ptr n) { return n->node_ptr_1; } BOOST_INTRUSIVE_FORCEINLINE static void set_next(node_ptr n, node_ptr next) { n->node_ptr_1 = next; } - BOOST_INTRUSIVE_FORCEINLINE static node_ptr get_prev_in_group(const const_node_ptr & n) + BOOST_INTRUSIVE_FORCEINLINE static node_ptr get_prev_in_group(const_node_ptr n) { return n->node_ptr_2; } BOOST_INTRUSIVE_FORCEINLINE static void set_prev_in_group(node_ptr n, node_ptr prev) { n->node_ptr_2 = prev; } - BOOST_INTRUSIVE_FORCEINLINE static std::size_t get_hash(const const_node_ptr & n) + BOOST_INTRUSIVE_FORCEINLINE static std::size_t get_hash(const_node_ptr n) { return n->size_t_1; } - BOOST_INTRUSIVE_FORCEINLINE static void set_hash(const node_ptr & n, std::size_t h) + BOOST_INTRUSIVE_FORCEINLINE static void set_hash(node_ptr n, std::size_t h) { n->size_t_1 = h; } }; @@ -119,28 +119,28 @@ struct any_rbtree_node_traits typedef std::size_t color; - BOOST_INTRUSIVE_FORCEINLINE static node_ptr get_parent(const const_node_ptr & n) + BOOST_INTRUSIVE_FORCEINLINE static node_ptr get_parent(const_node_ptr n) { return n->node_ptr_1; } BOOST_INTRUSIVE_FORCEINLINE static void set_parent(node_ptr n, node_ptr p) { n->node_ptr_1 = p; } - BOOST_INTRUSIVE_FORCEINLINE static node_ptr get_left(const const_node_ptr & n) + BOOST_INTRUSIVE_FORCEINLINE static node_ptr get_left(const_node_ptr n) { return n->node_ptr_2; } BOOST_INTRUSIVE_FORCEINLINE static void set_left(node_ptr n, node_ptr l) { n->node_ptr_2 = l; } - BOOST_INTRUSIVE_FORCEINLINE static node_ptr get_right(const const_node_ptr & n) + BOOST_INTRUSIVE_FORCEINLINE static node_ptr get_right(const_node_ptr n) { return n->node_ptr_3; } BOOST_INTRUSIVE_FORCEINLINE static void set_right(node_ptr n, node_ptr r) { n->node_ptr_3 = r; } - BOOST_INTRUSIVE_FORCEINLINE static color get_color(const const_node_ptr & n) + BOOST_INTRUSIVE_FORCEINLINE static color get_color(const_node_ptr n) { return n->size_t_1; } - BOOST_INTRUSIVE_FORCEINLINE static void set_color(const node_ptr & n, color c) + BOOST_INTRUSIVE_FORCEINLINE static void set_color(node_ptr n, color c) { n->size_t_1 = c; } BOOST_INTRUSIVE_FORCEINLINE static color black() @@ -160,28 +160,28 @@ struct any_avltree_node_traits typedef std::size_t balance; - BOOST_INTRUSIVE_FORCEINLINE static node_ptr get_parent(const const_node_ptr & n) + BOOST_INTRUSIVE_FORCEINLINE static node_ptr get_parent(const_node_ptr n) { return n->node_ptr_1; } BOOST_INTRUSIVE_FORCEINLINE static void set_parent(node_ptr n, node_ptr p) { n->node_ptr_1 = p; } - BOOST_INTRUSIVE_FORCEINLINE static node_ptr get_left(const const_node_ptr & n) + BOOST_INTRUSIVE_FORCEINLINE static node_ptr get_left(const_node_ptr n) { return n->node_ptr_2; } BOOST_INTRUSIVE_FORCEINLINE static void set_left(node_ptr n, node_ptr l) { n->node_ptr_2 = l; } - BOOST_INTRUSIVE_FORCEINLINE static node_ptr get_right(const const_node_ptr & n) + BOOST_INTRUSIVE_FORCEINLINE static node_ptr get_right(const_node_ptr n) { return n->node_ptr_3; } BOOST_INTRUSIVE_FORCEINLINE static void set_right(node_ptr n, node_ptr r) { n->node_ptr_3 = r; } - BOOST_INTRUSIVE_FORCEINLINE static balance get_balance(const const_node_ptr & n) + BOOST_INTRUSIVE_FORCEINLINE static balance get_balance(const_node_ptr n) { return n->size_t_1; } - BOOST_INTRUSIVE_FORCEINLINE static void set_balance(const node_ptr & n, balance b) + BOOST_INTRUSIVE_FORCEINLINE static void set_balance(node_ptr n, balance b) { n->size_t_1 = b; } BOOST_INTRUSIVE_FORCEINLINE static balance negative() @@ -202,19 +202,19 @@ struct any_tree_node_traits typedef typename node::node_ptr node_ptr; typedef typename node::const_node_ptr const_node_ptr; - BOOST_INTRUSIVE_FORCEINLINE static node_ptr get_parent(const const_node_ptr & n) + BOOST_INTRUSIVE_FORCEINLINE static node_ptr get_parent(const_node_ptr n) { return n->node_ptr_1; } BOOST_INTRUSIVE_FORCEINLINE static void set_parent(node_ptr n, node_ptr p) { n->node_ptr_1 = p; } - BOOST_INTRUSIVE_FORCEINLINE static node_ptr get_left(const const_node_ptr & n) + BOOST_INTRUSIVE_FORCEINLINE static node_ptr get_left(const_node_ptr n) { return n->node_ptr_2; } BOOST_INTRUSIVE_FORCEINLINE static void set_left(node_ptr n, node_ptr l) { n->node_ptr_2 = l; } - BOOST_INTRUSIVE_FORCEINLINE static node_ptr get_right(const const_node_ptr & n) + BOOST_INTRUSIVE_FORCEINLINE static node_ptr get_right(const_node_ptr n) { return n->node_ptr_3; } BOOST_INTRUSIVE_FORCEINLINE static void set_right(node_ptr n, node_ptr r) @@ -243,7 +243,7 @@ class any_algorithms typedef typename node::const_node_ptr const_node_ptr; typedef any_node_traits node_traits; - //! Requires: node must not be part of any tree. + //! Requires: 'n' must not be part of any tree. //! //! Effects: After the function unique(node) == true. //! @@ -252,27 +252,27 @@ class any_algorithms //! Throws: Nothing. //! //! Nodes: If node is inserted in a tree, this function corrupts the tree. - BOOST_INTRUSIVE_FORCEINLINE static void init(const node_ptr & node) - { node->node_ptr_1 = node_ptr(); }; + BOOST_INTRUSIVE_FORCEINLINE static void init(node_ptr n) BOOST_NOEXCEPT + { n->node_ptr_1 = node_ptr(); }; - //! Effects: Returns true if node is in the same state as if called init(node) + //! Effects: Returns true if 'n' is in the same state as if called init(node) //! //! Complexity: Constant. //! //! Throws: Nothing. - BOOST_INTRUSIVE_FORCEINLINE static bool inited(const const_node_ptr & node) - { return !node->node_ptr_1; }; + BOOST_INTRUSIVE_FORCEINLINE static bool inited(const_node_ptr n) + { return !n->node_ptr_1; }; - BOOST_INTRUSIVE_FORCEINLINE static bool unique(const const_node_ptr & node) - { return !node->node_ptr_1; } + BOOST_INTRUSIVE_FORCEINLINE static bool unique(const_node_ptr n) BOOST_NOEXCEPT + { return !n->node_ptr_1; } - static void unlink(const node_ptr &) + static void unlink(node_ptr) { //Auto-unlink hooks and unlink() are not available for any hooks any_algorithms::template function_not_available_for_any_hooks(); } - static void swap_nodes(const node_ptr &, const node_ptr &) + static void swap_nodes(node_ptr, node_ptr) { //Any nodes have no swap_nodes capability because they don't know //what algorithm they must use to unlink the node from the container diff --git a/include/boost/intrusive/detail/array_initializer.hpp b/include/boost/intrusive/detail/array_initializer.hpp index d9ed5bd97..554edadfa 100644 --- a/include/boost/intrusive/detail/array_initializer.hpp +++ b/include/boost/intrusive/detail/array_initializer.hpp @@ -22,8 +22,9 @@ #endif #include -#include +#include #include +#include namespace boost { namespace intrusive { @@ -54,20 +55,20 @@ class array_initializer { char *init_buf = (char*)rawbuf; std::size_t i = 0; - BOOST_TRY{ + BOOST_INTRUSIVE_TRY{ for(; i != N; ++i){ ::new(init_buf, boost_move_new_t()) T(init); init_buf += sizeof(T); } } - BOOST_CATCH(...){ + BOOST_INTRUSIVE_CATCH(...){ while(i--){ init_buf -= sizeof(T); - ((T*)init_buf)->~T(); + move_detail::force_ptr(init_buf)->~T(); } - BOOST_RETHROW; + BOOST_INTRUSIVE_RETHROW; } - BOOST_CATCH_END + BOOST_INTRUSIVE_CATCH_END } operator T* () @@ -81,7 +82,7 @@ class array_initializer char *init_buf = (char*)rawbuf + N*sizeof(T); for(std::size_t i = 0; i != N; ++i){ init_buf -= sizeof(T); - ((T*)init_buf)->~T(); + move_detail::force_ptr(init_buf)->~T(); } } diff --git a/include/boost/intrusive/detail/avltree_node.hpp b/include/boost/intrusive/detail/avltree_node.hpp index 85a864260..b9c52dcaa 100644 --- a/include/boost/intrusive/detail/avltree_node.hpp +++ b/include/boost/intrusive/detail/avltree_node.hpp @@ -69,40 +69,40 @@ struct default_avltree_node_traits_impl typedef typename node::balance balance; - BOOST_INTRUSIVE_FORCEINLINE static node_ptr get_parent(const const_node_ptr & n) + BOOST_INTRUSIVE_FORCEINLINE static node_ptr get_parent(const_node_ptr n) { return n->parent_; } - BOOST_INTRUSIVE_FORCEINLINE static node_ptr get_parent(const node_ptr & n) + BOOST_INTRUSIVE_FORCEINLINE static node_ptr get_parent(node_ptr n) { return n->parent_; } BOOST_INTRUSIVE_FORCEINLINE static void set_parent(node_ptr n, node_ptr p) { n->parent_ = p; } - BOOST_INTRUSIVE_FORCEINLINE static node_ptr get_left(const const_node_ptr & n) + BOOST_INTRUSIVE_FORCEINLINE static node_ptr get_left(const_node_ptr n) { return n->left_; } - BOOST_INTRUSIVE_FORCEINLINE static node_ptr get_left(const node_ptr & n) + BOOST_INTRUSIVE_FORCEINLINE static node_ptr get_left(node_ptr n) { return n->left_; } BOOST_INTRUSIVE_FORCEINLINE static void set_left(node_ptr n, node_ptr l) { n->left_ = l; } - BOOST_INTRUSIVE_FORCEINLINE static node_ptr get_right(const const_node_ptr & n) + BOOST_INTRUSIVE_FORCEINLINE static node_ptr get_right(const_node_ptr n) { return n->right_; } - BOOST_INTRUSIVE_FORCEINLINE static node_ptr get_right(const node_ptr & n) + BOOST_INTRUSIVE_FORCEINLINE static node_ptr get_right(node_ptr n) { return n->right_; } BOOST_INTRUSIVE_FORCEINLINE static void set_right(node_ptr n, node_ptr r) { n->right_ = r; } - BOOST_INTRUSIVE_FORCEINLINE static balance get_balance(const const_node_ptr & n) + BOOST_INTRUSIVE_FORCEINLINE static balance get_balance(const_node_ptr n) { return n->balance_; } - BOOST_INTRUSIVE_FORCEINLINE static balance get_balance(const node_ptr & n) + BOOST_INTRUSIVE_FORCEINLINE static balance get_balance(node_ptr n) { return n->balance_; } - BOOST_INTRUSIVE_FORCEINLINE static void set_balance(const node_ptr & n, balance b) + BOOST_INTRUSIVE_FORCEINLINE static void set_balance(node_ptr n, balance b) { n->balance_ = b; } BOOST_INTRUSIVE_FORCEINLINE static balance negative() @@ -127,28 +127,28 @@ struct compact_avltree_node_traits_impl typedef pointer_plus_bits ptr_bit; - BOOST_INTRUSIVE_FORCEINLINE static node_ptr get_parent(const const_node_ptr & n) + BOOST_INTRUSIVE_FORCEINLINE static node_ptr get_parent(const_node_ptr n) { return ptr_bit::get_pointer(n->parent_); } BOOST_INTRUSIVE_FORCEINLINE static void set_parent(node_ptr n, node_ptr p) { ptr_bit::set_pointer(n->parent_, p); } - BOOST_INTRUSIVE_FORCEINLINE static node_ptr get_left(const const_node_ptr & n) + BOOST_INTRUSIVE_FORCEINLINE static node_ptr get_left(const_node_ptr n) { return n->left_; } BOOST_INTRUSIVE_FORCEINLINE static void set_left(node_ptr n, node_ptr l) { n->left_ = l; } - BOOST_INTRUSIVE_FORCEINLINE static node_ptr get_right(const const_node_ptr & n) + BOOST_INTRUSIVE_FORCEINLINE static node_ptr get_right(const_node_ptr n) { return n->right_; } BOOST_INTRUSIVE_FORCEINLINE static void set_right(node_ptr n, node_ptr r) { n->right_ = r; } - BOOST_INTRUSIVE_FORCEINLINE static balance get_balance(const const_node_ptr & n) + BOOST_INTRUSIVE_FORCEINLINE static balance get_balance(const_node_ptr n) { return (balance)ptr_bit::get_bits(n->parent_); } - BOOST_INTRUSIVE_FORCEINLINE static void set_balance(const node_ptr & n, balance b) + BOOST_INTRUSIVE_FORCEINLINE static void set_balance(node_ptr n, balance b) { ptr_bit::set_bits(n->parent_, (std::size_t)b); } BOOST_INTRUSIVE_FORCEINLINE static balance negative() diff --git a/include/boost/intrusive/detail/bstree_algorithms_base.hpp b/include/boost/intrusive/detail/bstree_algorithms_base.hpp index 840401056..1dbd491ed 100644 --- a/include/boost/intrusive/detail/bstree_algorithms_base.hpp +++ b/include/boost/intrusive/detail/bstree_algorithms_base.hpp @@ -35,21 +35,20 @@ class bstree_algorithms_base typedef typename NodeTraits::node_ptr node_ptr; typedef typename NodeTraits::const_node_ptr const_node_ptr; - //! Requires: 'node' is a node from the tree except the header. + //! Requires: 'n' is a node from the tree except the header. //! //! Effects: Returns the next node of the tree. //! //! Complexity: Average constant time. //! //! Throws: Nothing. - static node_ptr next_node(const node_ptr & node) + static node_ptr next_node(node_ptr n) BOOST_NOEXCEPT { - node_ptr const n_right(NodeTraits::get_right(node)); + node_ptr const n_right(NodeTraits::get_right(n)); if(n_right){ return minimum(n_right); } else { - node_ptr n(node); node_ptr p(NodeTraits::get_parent(n)); while(n == NodeTraits::get_right(p)){ n = p; @@ -59,24 +58,23 @@ class bstree_algorithms_base } } - //! Requires: 'node' is a node from the tree except the leftmost node. + //! Requires: 'n' is a node from the tree except the leftmost node. //! //! Effects: Returns the previous node of the tree. //! //! Complexity: Average constant time. //! //! Throws: Nothing. - static node_ptr prev_node(const node_ptr & node) + static node_ptr prev_node(node_ptr n) BOOST_NOEXCEPT { - if(is_header(node)){ - //return NodeTraits::get_right(node); - return maximum(NodeTraits::get_parent(node)); + if(is_header(n)){ + return NodeTraits::get_right(n); } - else if(NodeTraits::get_left(node)){ - return maximum(NodeTraits::get_left(node)); + else if(NodeTraits::get_left(n)){ + return maximum(NodeTraits::get_left(n)); } else { - node_ptr p(node); + node_ptr p(n); node_ptr x = NodeTraits::get_parent(p); while(p == NodeTraits::get_left(x)){ p = x; @@ -86,38 +84,38 @@ class bstree_algorithms_base } } - //! Requires: 'node' is a node of a tree but not the header. + //! Requires: 'n' is a node of a tree but not the header. //! //! Effects: Returns the minimum node of the subtree starting at p. //! //! Complexity: Logarithmic to the size of the subtree. //! //! Throws: Nothing. - static node_ptr minimum(node_ptr node) + static node_ptr minimum(node_ptr n) { - for(node_ptr p_left = NodeTraits::get_left(node) + for(node_ptr p_left = NodeTraits::get_left(n) ;p_left - ;p_left = NodeTraits::get_left(node)){ - node = p_left; + ;p_left = NodeTraits::get_left(n)){ + n = p_left; } - return node; + return n; } - //! Requires: 'node' is a node of a tree but not the header. + //! Requires: 'n' is a node of a tree but not the header. //! //! Effects: Returns the maximum node of the subtree starting at p. //! //! Complexity: Logarithmic to the size of the subtree. //! //! Throws: Nothing. - static node_ptr maximum(node_ptr node) + static node_ptr maximum(node_ptr n) { - for(node_ptr p_right = NodeTraits::get_right(node) + for(node_ptr p_right = NodeTraits::get_right(n) ;p_right - ;p_right = NodeTraits::get_right(node)){ - node = p_right; + ;p_right = NodeTraits::get_right(n)){ + n = p_right; } - return node; + return n; } //! Requires: p is a node of a tree. @@ -127,7 +125,7 @@ class bstree_algorithms_base //! Complexity: Constant. //! //! Throws: Nothing. - static bool is_header(const const_node_ptr & p) + static bool is_header(const_node_ptr p) BOOST_NOEXCEPT { node_ptr p_left (NodeTraits::get_left(p)); node_ptr p_right(NodeTraits::get_right(p)); @@ -144,37 +142,37 @@ class bstree_algorithms_base return false; } - //! Requires: 'node' is a node of the tree or a header node. + //! Requires: 'n' is a node of the tree or a header node. //! //! Effects: Returns the header of the tree. //! //! Complexity: Logarithmic. //! //! Throws: Nothing. - static node_ptr get_header(const const_node_ptr & node) + static node_ptr get_header(const_node_ptr n) { - node_ptr n(detail::uncast(node)); - node_ptr p(NodeTraits::get_parent(node)); - //If p is null, then n is the header of an empty tree + node_ptr nn(detail::uncast(n)); + node_ptr p(NodeTraits::get_parent(n)); + //If p is null, then nn is the header of an empty tree if(p){ - //Non-empty tree, check if n is neither root nor header + //Non-empty tree, check if nn is neither root nor header node_ptr pp(NodeTraits::get_parent(p)); - //If granparent is not equal to n, then n is neither root nor header, + //If granparent is not equal to nn, then nn is neither root nor header, //the try the fast path - if(n != pp){ + if(nn != pp){ do{ - n = p; + nn = p; p = pp; pp = NodeTraits::get_parent(pp); - }while(n != pp); - n = p; + }while(nn != pp); + nn = p; } - //Check if n is root or header when size() > 0 - else if(!bstree_algorithms_base::is_header(n)){ - n = p; + //Check if nn is root or header when size() > 0 + else if(!bstree_algorithms_base::is_header(nn)){ + nn = p; } } - return n; + return nn; } }; diff --git a/include/boost/intrusive/detail/common_slist_algorithms.hpp b/include/boost/intrusive/detail/common_slist_algorithms.hpp index 88f3fedac..8310231e3 100644 --- a/include/boost/intrusive/detail/common_slist_algorithms.hpp +++ b/include/boost/intrusive/detail/common_slist_algorithms.hpp @@ -22,9 +22,9 @@ #endif #include +#include #include #include -#include #include namespace boost { @@ -40,7 +40,7 @@ class common_slist_algorithms typedef typename NodeTraits::const_node_ptr const_node_ptr; typedef NodeTraits node_traits; - static node_ptr get_previous_node(node_ptr p, const node_ptr & this_node) + static node_ptr get_previous_node(node_ptr p, node_ptr this_node) { for( node_ptr p_next ; this_node != (p_next = NodeTraits::get_next(p)) @@ -52,41 +52,41 @@ class common_slist_algorithms return p; } - BOOST_INTRUSIVE_FORCEINLINE static void init(node_ptr this_node) + BOOST_INTRUSIVE_FORCEINLINE static void init(node_ptr this_node) BOOST_NOEXCEPT { NodeTraits::set_next(this_node, node_ptr()); } - BOOST_INTRUSIVE_FORCEINLINE static bool unique(const const_node_ptr & this_node) + static bool unique(const_node_ptr this_node) BOOST_NOEXCEPT { node_ptr next = NodeTraits::get_next(this_node); return !next || next == this_node; } - BOOST_INTRUSIVE_FORCEINLINE static bool inited(const const_node_ptr & this_node) + BOOST_INTRUSIVE_FORCEINLINE static bool inited(const_node_ptr this_node) BOOST_NOEXCEPT { return !NodeTraits::get_next(this_node); } - BOOST_INTRUSIVE_FORCEINLINE static void unlink_after(node_ptr prev_node) + BOOST_INTRUSIVE_FORCEINLINE static void unlink_after(node_ptr prev_node) BOOST_NOEXCEPT { const_node_ptr this_node(NodeTraits::get_next(prev_node)); NodeTraits::set_next(prev_node, NodeTraits::get_next(this_node)); } - BOOST_INTRUSIVE_FORCEINLINE static void unlink_after(node_ptr prev_node, node_ptr last_node) + BOOST_INTRUSIVE_FORCEINLINE static void unlink_after(node_ptr prev_node, node_ptr last_node) BOOST_NOEXCEPT { NodeTraits::set_next(prev_node, last_node); } - BOOST_INTRUSIVE_FORCEINLINE static void link_after(node_ptr prev_node, node_ptr this_node) + static void link_after(node_ptr prev_node, node_ptr this_node) BOOST_NOEXCEPT { NodeTraits::set_next(this_node, NodeTraits::get_next(prev_node)); NodeTraits::set_next(prev_node, this_node); } - BOOST_INTRUSIVE_FORCEINLINE static void incorporate_after(node_ptr bp, node_ptr b, node_ptr be) + static void incorporate_after(node_ptr bp, node_ptr b, node_ptr be) BOOST_NOEXCEPT { node_ptr p(NodeTraits::get_next(bp)); NodeTraits::set_next(bp, b); NodeTraits::set_next(be, p); } - static void transfer_after(node_ptr bp, node_ptr bb, node_ptr be) + static void transfer_after(node_ptr bp, node_ptr bb, node_ptr be) BOOST_NOEXCEPT { if (bp != bb && bp != be && bb != be) { node_ptr next_b = NodeTraits::get_next(bb); @@ -126,7 +126,7 @@ class common_slist_algorithms new_f = cur; bcur = cur; cur = node_traits::get_next(cur); - BOOST_TRY{ + BOOST_INTRUSIVE_TRY{ //Main loop while(cur != end){ if(pred(cur)){ //Might throw @@ -145,11 +145,11 @@ class common_slist_algorithms } } } - BOOST_CATCH(...){ + BOOST_INTRUSIVE_CATCH(...){ node_traits::set_next(last_to_remove, new_f); - BOOST_RETHROW; + BOOST_INTRUSIVE_RETHROW; } - BOOST_CATCH_END + BOOST_INTRUSIVE_CATCH_END node_traits::set_next(last_to_remove, new_f); break; } @@ -167,7 +167,7 @@ class common_slist_algorithms //! Complexity: Linear //! //! Throws: Nothing. - static std::size_t distance(const const_node_ptr &f, const const_node_ptr &l) + static std::size_t distance(const_node_ptr f, const_node_ptr l) BOOST_NOEXCEPT { const_node_ptr i(f); std::size_t result = 0; @@ -177,6 +177,75 @@ class common_slist_algorithms } return result; } + + //! Requires: "disposer" must be an object function + //! taking a node_ptr parameter and shouldn't throw. + //! + //! Effects: Calls + //! void disposer::operator()(node_ptr) for every node of the list + //! [p, e). + //! + //! Returns: The number of unlinked/disposed nodes + //! + //! Complexity: Linear to the number of element of the list. + //! + //! Throws: Nothing. + template + static std::size_t unlink_after_and_dispose(node_ptr bb, node_ptr e, Disposer disposer) BOOST_NOEXCEPT + { + std::size_t n = 0u; + node_ptr i = node_traits::get_next(bb); + while (i != e) { + node_ptr to_erase(i); + i = node_traits::get_next(i); + disposer(to_erase); + ++n; + } + node_traits::set_next(bb, e); + return n; + } + + //! Requires: "disposer" must be an object function + //! taking a node_ptr parameter and shouldn't throw. + //! + //! Effects: Calls + //! void disposer::operator()(node_ptr) for every node of the list + //! after p (but not for p). Works for circular or linear lists + //! + //! Complexity: Linear to the number of element of the list. + //! + //! Throws: Nothing. + template + BOOST_INTRUSIVE_FORCEINLINE static void unlink_after_and_dispose(node_ptr bb, Disposer disposer) BOOST_NOEXCEPT + { + node_ptr i = node_traits::get_next(bb); + node_traits::set_next(bb, node_traits::get_next(i)); + disposer(i); + } + + //! Requires: "disposer" must be an object function + //! taking a node_ptr parameter and shouldn't throw. + //! + //! Effects: Unlinks all nodes reachable from p (but not p) and calls + //! void disposer::operator()(node_ptr) for every node of the list + //! where p is linked. + //! + //! Complexity: Linear to the number of element of the list. + //! + //! Throws: Nothing. + template + static std::size_t detach_and_dispose(node_ptr p, Disposer disposer) BOOST_NOEXCEPT + { + std::size_t n = 0; + node_ptr i = node_traits::get_next(p); + while ( i != p || i != node_ptr() ) { + node_ptr to_erase(i); + i = node_traits::get_next(i); + disposer(to_erase); + } + node_traits::set_next(p, i); + return n; + } }; /// @endcond diff --git a/include/boost/intrusive/detail/config_begin.hpp b/include/boost/intrusive/detail/config_begin.hpp index 8bd57a3b5..b261ca91d 100644 --- a/include/boost/intrusive/detail/config_begin.hpp +++ b/include/boost/intrusive/detail/config_begin.hpp @@ -17,6 +17,7 @@ #ifdef BOOST_MSVC #pragma warning (push) + #pragma warning (disable : 4619) // there is no warning number 'XXXX' #pragma warning (disable : 4275) // non DLL-interface classkey "identifier" used as base for DLL-interface classkey "identifier" #pragma warning (disable : 4251) // "identifier" : class "type" needs to have dll-interface to be used by clients of class "type2" #pragma warning (disable : 4675) // "method" should be declared "static" and have exactly one parameter diff --git a/include/boost/intrusive/detail/default_header_holder.hpp b/include/boost/intrusive/detail/default_header_holder.hpp index ba561b5f5..42f35d2be 100644 --- a/include/boost/intrusive/detail/default_header_holder.hpp +++ b/include/boost/intrusive/detail/default_header_holder.hpp @@ -47,7 +47,7 @@ struct default_header_holder : public NodeTraits::node { return pointer_traits< node_ptr >::pointer_to(*static_cast< node* >(this)); } // (unsafe) downcast used to implement container-from-iterator - BOOST_INTRUSIVE_FORCEINLINE static default_header_holder* get_holder(const node_ptr &p) + BOOST_INTRUSIVE_FORCEINLINE static default_header_holder* get_holder(node_ptr p) { return static_cast< default_header_holder* >(boost::movelib::to_raw_pointer(p)); } }; diff --git a/include/boost/intrusive/detail/empty_node_checker.hpp b/include/boost/intrusive/detail/empty_node_checker.hpp index 16aa5600e..fbff4b673 100644 --- a/include/boost/intrusive/detail/empty_node_checker.hpp +++ b/include/boost/intrusive/detail/empty_node_checker.hpp @@ -34,7 +34,7 @@ struct empty_node_checker struct return_type {}; - void operator () (const const_node_ptr&, const return_type&, const return_type&, return_type&) {} + void operator () (const_node_ptr, const return_type&, const return_type&, return_type&) {} }; } //namespace detail{ diff --git a/include/boost/intrusive/detail/exception_disposer.hpp b/include/boost/intrusive/detail/exception_disposer.hpp index 91c5bf3b6..0e21faeba 100644 --- a/include/boost/intrusive/detail/exception_disposer.hpp +++ b/include/boost/intrusive/detail/exception_disposer.hpp @@ -52,37 +52,6 @@ class exception_disposer } }; -template -class exception_array_disposer -{ - Container *cont_; - Disposer &disp_; - SizeType &constructed_; - - exception_array_disposer(const exception_array_disposer&); - exception_array_disposer &operator=(const exception_array_disposer&); - - public: - - exception_array_disposer - (Container &cont, Disposer &disp, SizeType &constructed) - : cont_(&cont), disp_(disp), constructed_(constructed) - {} - - BOOST_INTRUSIVE_FORCEINLINE void release() - { cont_ = 0; } - - ~exception_array_disposer() - { - SizeType n = constructed_; - if(cont_){ - while(n--){ - cont_[n].clear_and_dispose(disp_); - } - } - } -}; - } //namespace detail{ } //namespace intrusive{ } //namespace boost{ diff --git a/include/boost/intrusive/detail/generic_hook.hpp b/include/boost/intrusive/detail/generic_hook.hpp index a4921dec8..6e43f90d9 100644 --- a/include/boost/intrusive/detail/generic_hook.hpp +++ b/include/boost/intrusive/detail/generic_hook.hpp @@ -161,30 +161,30 @@ class generic_hook < NodeTraits , Tag, LinkMode, BaseHookType> hooktags; - BOOST_INTRUSIVE_FORCEINLINE node_ptr this_ptr() + BOOST_INTRUSIVE_FORCEINLINE node_ptr this_ptr() BOOST_NOEXCEPT { return pointer_traits::pointer_to(static_cast(*this)); } - BOOST_INTRUSIVE_FORCEINLINE const_node_ptr this_ptr() const + BOOST_INTRUSIVE_FORCEINLINE const_node_ptr this_ptr() const BOOST_NOEXCEPT { return pointer_traits::pointer_to(static_cast(*this)); } public: /// @endcond - BOOST_INTRUSIVE_FORCEINLINE generic_hook() + BOOST_INTRUSIVE_FORCEINLINE generic_hook() BOOST_NOEXCEPT { if(hooktags::safemode_or_autounlink){ node_algorithms::init(this->this_ptr()); } } - BOOST_INTRUSIVE_FORCEINLINE generic_hook(const generic_hook& ) + BOOST_INTRUSIVE_FORCEINLINE generic_hook(const generic_hook& ) BOOST_NOEXCEPT { if(hooktags::safemode_or_autounlink){ node_algorithms::init(this->this_ptr()); } } - BOOST_INTRUSIVE_FORCEINLINE generic_hook& operator=(const generic_hook& ) + BOOST_INTRUSIVE_FORCEINLINE generic_hook& operator=(const generic_hook& ) BOOST_NOEXCEPT { return *this; } BOOST_INTRUSIVE_FORCEINLINE ~generic_hook() @@ -193,20 +193,20 @@ class generic_hook (*this, detail::link_dispatch()); } - BOOST_INTRUSIVE_FORCEINLINE void swap_nodes(generic_hook &other) + BOOST_INTRUSIVE_FORCEINLINE void swap_nodes(generic_hook &other) BOOST_NOEXCEPT { node_algorithms::swap_nodes (this->this_ptr(), other.this_ptr()); } - BOOST_INTRUSIVE_FORCEINLINE bool is_linked() const + BOOST_INTRUSIVE_FORCEINLINE bool is_linked() const BOOST_NOEXCEPT { //is_linked() can be only used in safe-mode or auto-unlink BOOST_STATIC_ASSERT(( hooktags::safemode_or_autounlink )); return !node_algorithms::unique(this->this_ptr()); } - BOOST_INTRUSIVE_FORCEINLINE void unlink() + BOOST_INTRUSIVE_FORCEINLINE void unlink() BOOST_NOEXCEPT { BOOST_STATIC_ASSERT(( (int)hooktags::link_mode == (int)auto_unlink )); node_ptr n(this->this_ptr()); diff --git a/include/boost/intrusive/detail/hash_combine.hpp b/include/boost/intrusive/detail/hash_combine.hpp new file mode 100644 index 000000000..f089fb0cc --- /dev/null +++ b/include/boost/intrusive/detail/hash_combine.hpp @@ -0,0 +1,92 @@ +// Copyright 2005-2014 Daniel James. +// 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) +// +// Based on Peter Dimov's proposal +// http://www.open-std.org/JTC1/SC22/WG21/docs/papers/2005/n1756.pdf +// issue 6.18. +// +// This also contains public domain code from MurmurHash. From the +// MurmurHash header: +// +// MurmurHash3 was written by Austin Appleby, and is placed in the public +// domain. The author hereby disclaims copyright to this source code. +// +// Copyright 2021 Ion Gaztanaga +// Refactored the original boost/container_hash/hash.hpp to avoid +// any heavy std header dependencies to just combine two hash +// values represented in a std::size_t type. + +#ifndef BOOST_INTRUSIVE_DETAIL_HASH_COMBINE_HPP +#define BOOST_INTRUSIVE_DETAIL_HASH_COMBINE_HPP + +#ifndef BOOST_CONFIG_HPP +# include +#endif + +#if defined(BOOST_HAS_PRAGMA_ONCE) +# pragma once +#endif + +#include + +#if defined(_MSC_VER) +# include +# define BOOST_INTRUSIVE_HASH_ROTL32(x, r) _rotl(x,r) +#else +# define BOOST_INTRUSIVE_HASH_ROTL32(x, r) (x << r) | (x >> (32 - r)) +#endif + +namespace boost { +namespace intrusive { +namespace detail { + +template +inline void hash_combine_size_t(SizeT& seed, SizeT value) +{ + seed ^= value + 0x9e3779b9 + (seed<<6) + (seed>>2); +} + +inline void hash_combine_size_t(boost::uint32_t& h1, boost::uint32_t k1) +{ + const uint32_t c1 = 0xcc9e2d51; + const uint32_t c2 = 0x1b873593; + + k1 *= c1; + k1 = BOOST_INTRUSIVE_HASH_ROTL32(k1,15); + k1 *= c2; + + h1 ^= k1; + h1 = BOOST_INTRUSIVE_HASH_ROTL32(h1,13); + h1 = h1*5+0xe6546b64; +} + + + // Don't define 64-bit hash combine on platforms without 64 bit integers, + // and also not for 32-bit gcc as it warns about the 64-bit constant. + #if !defined(BOOST_NO_INT64_T) && \ + !(defined(__GNUC__) && ULONG_MAX == 0xffffffff) + inline void hash_combine_size_t(boost::uint64_t& h, boost::uint64_t k) + { + const boost::uint64_t m = UINT64_C(0xc6a4a7935bd1e995); + const int r = 47; + + k *= m; + k ^= k >> r; + k *= m; + + h ^= k; + h *= m; + + // Completely arbitrary number, to prevent 0's + // from hashing to 0. + h += 0xe6546b64; + } + + #endif // BOOST_NO_INT64_T + +} //namespace detail { +} //namespace intrusive { +} //namespace boost { + +#endif //BOOST_INTRUSIVE_DETAIL_HASH_COMBINE_HPP diff --git a/include/boost/intrusive/detail/hashtable_node.hpp b/include/boost/intrusive/detail/hashtable_node.hpp index 913c38da7..8e9a06258 100644 --- a/include/boost/intrusive/detail/hashtable_node.hpp +++ b/include/boost/intrusive/detail/hashtable_node.hpp @@ -26,7 +26,10 @@ #include #include #include -#include //make_slist +#include +#include +#include +#include #include #include #include @@ -35,79 +38,43 @@ namespace boost { namespace intrusive { -template -struct bucket_impl : public Slist +template +struct bucket_impl + : public NodeTraits::node { - typedef Slist slist_type; - BOOST_INTRUSIVE_FORCEINLINE bucket_impl() - {} - - BOOST_INTRUSIVE_FORCEINLINE bucket_impl(const bucket_impl &) - {} - - BOOST_INTRUSIVE_FORCEINLINE ~bucket_impl() - { - //This bucket is still being used! - BOOST_INTRUSIVE_INVARIANT_ASSERT(Slist::empty()); - } - - BOOST_INTRUSIVE_FORCEINLINE bucket_impl &operator=(const bucket_impl&) - { - //This bucket is still in use! - BOOST_INTRUSIVE_INVARIANT_ASSERT(Slist::empty()); - return *this; - } -}; + public: + typedef NodeTraits node_traits; -template -struct bucket_traits_impl -{ private: - BOOST_COPYABLE_AND_MOVABLE(bucket_traits_impl) + typedef typename node_traits::node_ptr node_ptr; + typedef typename node_traits::const_node_ptr const_node_ptr; + + typedef detail::common_slist_algorithms algo_t; public: - /// @cond + BOOST_INTRUSIVE_FORCEINLINE bucket_impl() + {} - typedef typename pointer_traits - ::template rebind_pointer - < bucket_impl >::type bucket_ptr; - typedef Slist slist; - typedef typename Slist::size_type size_type; - /// @endcond - - BOOST_INTRUSIVE_FORCEINLINE bucket_traits_impl(bucket_ptr buckets, size_type len) - : buckets_(buckets), buckets_len_(len) + BOOST_INTRUSIVE_FORCEINLINE bucket_impl(const bucket_impl &) {} - BOOST_INTRUSIVE_FORCEINLINE bucket_traits_impl(const bucket_traits_impl &x) - : buckets_(x.buckets_), buckets_len_(x.buckets_len_) + BOOST_INTRUSIVE_FORCEINLINE ~bucket_impl() {} - BOOST_INTRUSIVE_FORCEINLINE bucket_traits_impl(BOOST_RV_REF(bucket_traits_impl) x) - : buckets_(x.buckets_), buckets_len_(x.buckets_len_) - { x.buckets_ = bucket_ptr(); x.buckets_len_ = 0; } + BOOST_INTRUSIVE_FORCEINLINE bucket_impl &operator=(const bucket_impl&) + { return *this; } - BOOST_INTRUSIVE_FORCEINLINE bucket_traits_impl& operator=(BOOST_RV_REF(bucket_traits_impl) x) - { - buckets_ = x.buckets_; buckets_len_ = x.buckets_len_; - x.buckets_ = bucket_ptr(); x.buckets_len_ = 0; return *this; - } + BOOST_INTRUSIVE_FORCEINLINE node_ptr get_node_ptr() + { return pointer_traits::pointer_to(*this); } - BOOST_INTRUSIVE_FORCEINLINE bucket_traits_impl& operator=(BOOST_COPY_ASSIGN_REF(bucket_traits_impl) x) - { - buckets_ = x.buckets_; buckets_len_ = x.buckets_len_; return *this; - } + BOOST_INTRUSIVE_FORCEINLINE const_node_ptr get_node_ptr() const + { return pointer_traits::pointer_to(*this); } - BOOST_INTRUSIVE_FORCEINLINE const bucket_ptr &bucket_begin() const - { return buckets_; } + BOOST_INTRUSIVE_FORCEINLINE node_ptr begin_ptr() + { return node_traits::get_next(get_node_ptr()); } +}; - BOOST_INTRUSIVE_FORCEINLINE size_type bucket_count() const - { return buckets_len_; } - private: - bucket_ptr buckets_; - size_type buckets_len_; -}; template struct hash_reduced_slist_node_traits @@ -133,22 +100,7 @@ struct reduced_slist_node_traits >::type type; }; -template -struct get_slist_impl -{ - typedef trivial_value_traits trivial_traits; - - //Reducing symbol length - struct type : make_slist - < typename NodeTraits::node - , boost::intrusive::value_traits - , boost::intrusive::constant_time_size - , boost::intrusive::size_type - >::type - {}; -}; - -template +template class hashtable_iterator { typedef typename BucketValueTraits::value_traits value_traits; @@ -166,24 +118,25 @@ class hashtable_iterator private: typedef typename value_traits::node_traits node_traits; typedef typename node_traits::node_ptr node_ptr; - typedef typename get_slist_impl - < typename reduced_slist_node_traits - ::type >::type slist_impl; - typedef typename slist_impl::iterator siterator; - typedef typename slist_impl::const_iterator const_siterator; - typedef bucket_impl bucket_type; + typedef typename BucketValueTraits::bucket_type bucket_type; + typedef typename bucket_type::node_traits slist_node_traits; + typedef typename slist_node_traits::node_ptr slist_node_ptr; + typedef trivial_value_traits + slist_value_traits; + typedef slist_iterator siterator; + typedef slist_iterator const_siterator; + typedef circular_slist_algorithms slist_node_algorithms; typedef typename pointer_traits ::template rebind_pointer < const BucketValueTraits >::type const_bucketvaltraits_ptr; - typedef typename slist_impl::size_type size_type; class nat; typedef typename detail::if_c< IsConst - , hashtable_iterator + , hashtable_iterator , nat>::type nonconst_iterator; - BOOST_INTRUSIVE_FORCEINLINE static node_ptr downcast_bucket(typename bucket_type::node_ptr p) + BOOST_INTRUSIVE_FORCEINLINE static node_ptr downcast_bucket(typename bucket_type::node_traits::node_ptr p) { return pointer_traits:: pointer_to(static_cast(*p)); @@ -211,8 +164,8 @@ class hashtable_iterator BOOST_INTRUSIVE_FORCEINLINE const siterator &slist_it() const { return slist_it_; } - BOOST_INTRUSIVE_FORCEINLINE hashtable_iterator unconst() const - { return hashtable_iterator(this->slist_it(), this->get_bucket_value_traits()); } + BOOST_INTRUSIVE_FORCEINLINE hashtable_iterator unconst() const + { return hashtable_iterator(this->slist_it(), this->get_bucket_value_traits()); } BOOST_INTRUSIVE_FORCEINLINE hashtable_iterator& operator++() { this->increment(); return *this; } @@ -242,43 +195,42 @@ class hashtable_iterator (downcast_bucket(slist_it_.pointed_node())); } - BOOST_INTRUSIVE_FORCEINLINE const const_bucketvaltraits_ptr &get_bucket_value_traits() const + BOOST_INTRUSIVE_FORCEINLINE const_bucketvaltraits_ptr get_bucket_value_traits() const { return traitsptr_; } BOOST_INTRUSIVE_FORCEINLINE const value_traits &priv_value_traits() const { return traitsptr_->priv_value_traits(); } - BOOST_INTRUSIVE_FORCEINLINE const bucket_traits &priv_bucket_traits() const - { return traitsptr_->priv_bucket_traits(); } - private: + void increment() { - const bucket_traits &rbuck_traits = this->priv_bucket_traits(); - bucket_type* const buckets = boost::movelib::to_raw_pointer(rbuck_traits.bucket_begin()); - const size_type buckets_len = rbuck_traits.bucket_count(); + bucket_type* const buckets = boost::movelib::to_raw_pointer(traitsptr_->priv_bucket_traits().bucket_begin()); + const std::size_t buckets_len = traitsptr_->priv_bucket_traits().bucket_count(); ++slist_it_; - const typename slist_impl::node_ptr n = slist_it_.pointed_node(); - const siterator first_bucket_bbegin = buckets->end(); - if(first_bucket_bbegin.pointed_node() <= n && n <= buckets[buckets_len-1].cend().pointed_node()){ + const slist_node_ptr n = slist_it_.pointed_node(); + const siterator first_bucket_bbegin(buckets->get_node_ptr()); + if(first_bucket_bbegin.pointed_node() <= n && n <= buckets[buckets_len-1].get_node_ptr()){ //If one-past the node is inside the bucket then look for the next non-empty bucket //1. get the bucket_impl from the iterator - const bucket_type &b = static_cast - (bucket_type::slist_type::container_from_end_iterator(slist_it_)); + const bucket_type &b = static_cast(*n); //2. Now just calculate the index b has in the bucket array - size_type n_bucket = static_cast(&b - buckets); + std::size_t n_bucket = static_cast(&b - buckets); //3. Iterate until a non-empty bucket is found + slist_node_ptr bucket_nodeptr = buckets->get_node_ptr(); do{ if (++n_bucket >= buckets_len){ //bucket overflow, return end() iterator - slist_it_ = buckets->before_begin(); + slist_it_ = first_bucket_bbegin; return; } + bucket_nodeptr = buckets[n_bucket].get_node_ptr(); } - while (buckets[n_bucket].empty()); - slist_it_ = buckets[n_bucket].begin(); + while (slist_node_algorithms::is_empty(bucket_nodeptr)); + slist_it_ = siterator(bucket_nodeptr); + ++slist_it_; } else{ //++slist_it_ yield to a valid object @@ -289,6 +241,134 @@ class hashtable_iterator const_bucketvaltraits_ptr traitsptr_; }; +template +class hashtable_iterator +{ + typedef typename BucketValueTraits::value_traits value_traits; + typedef typename BucketValueTraits::bucket_traits bucket_traits; + + typedef iiterator< value_traits, IsConst + , std::forward_iterator_tag> types_t; + public: + typedef typename types_t::iterator_type::difference_type difference_type; + typedef typename types_t::iterator_type::value_type value_type; + typedef typename types_t::iterator_type::pointer pointer; + typedef typename types_t::iterator_type::reference reference; + typedef typename types_t::iterator_type::iterator_category iterator_category; + + private: + typedef typename value_traits::node_traits node_traits; + typedef typename node_traits::node_ptr node_ptr; + typedef typename BucketValueTraits::bucket_type bucket_type; + typedef typename BucketValueTraits::bucket_ptr bucket_ptr; + typedef typename bucket_type::node_traits slist_node_traits; + typedef linear_slist_algorithms slist_node_algorithms; + typedef typename slist_node_traits::node_ptr slist_node_ptr; + typedef trivial_value_traits + slist_value_traits; + typedef slist_iterator siterator; + typedef slist_iterator const_siterator; + + static const bool stateful_value_traits = + detail::is_stateful_value_traits::value; + + typedef typename pointer_traits + ::template rebind_pointer + < const value_traits >::type const_value_traits_ptr; + class nat; + typedef typename + detail::if_c< IsConst + , hashtable_iterator + , nat>::type nonconst_iterator; + + BOOST_INTRUSIVE_FORCEINLINE static node_ptr downcast_bucket(slist_node_ptr p) + { + return pointer_traits:: + pointer_to(static_cast(*p)); + } + + public: + + BOOST_INTRUSIVE_FORCEINLINE hashtable_iterator () + : slist_it_() //Value initialization to achieve "null iterators" (N3644) + , members_() + {} + + BOOST_INTRUSIVE_FORCEINLINE explicit hashtable_iterator(siterator ptr, bucket_ptr bp, const_value_traits_ptr traits_ptr) + : slist_it_ (ptr) + , members_ (bp, traits_ptr) + {} + + BOOST_INTRUSIVE_FORCEINLINE hashtable_iterator(const hashtable_iterator &other) + : slist_it_(other.slist_it()), members_(other.get_bucket_ptr(), other.get_value_traits()) + {} + + BOOST_INTRUSIVE_FORCEINLINE hashtable_iterator(const nonconst_iterator &other) + : slist_it_(other.slist_it()), members_(other.get_bucket_ptr(), other.get_value_traits()) + {} + + BOOST_INTRUSIVE_FORCEINLINE const siterator &slist_it() const + { return slist_it_; } + + BOOST_INTRUSIVE_FORCEINLINE hashtable_iterator unconst() const + { return hashtable_iterator(this->slist_it(), members_.nodeptr_, members_.get_ptr()); } + + BOOST_INTRUSIVE_FORCEINLINE hashtable_iterator& operator++() + { this->increment(); return *this; } + + BOOST_INTRUSIVE_FORCEINLINE hashtable_iterator &operator=(const hashtable_iterator &other) + { slist_it_ = other.slist_it(); members_ = other.members_; return *this; } + + BOOST_INTRUSIVE_FORCEINLINE hashtable_iterator operator++(int) + { + hashtable_iterator result (*this); + this->increment(); + return result; + } + + BOOST_INTRUSIVE_FORCEINLINE friend bool operator== (const hashtable_iterator& i, const hashtable_iterator& i2) + { return i.slist_it_ == i2.slist_it_; } + + BOOST_INTRUSIVE_FORCEINLINE friend bool operator!= (const hashtable_iterator& i, const hashtable_iterator& i2) + { return i.slist_it_ != i2.slist_it_; } + + BOOST_INTRUSIVE_FORCEINLINE reference operator*() const + { return *this->operator ->(); } + + BOOST_INTRUSIVE_FORCEINLINE pointer operator->() const + { return this->operator_arrow(detail::bool_()); } + + BOOST_INTRUSIVE_FORCEINLINE const_value_traits_ptr get_value_traits() const + { return members_.get_ptr(); } + + BOOST_INTRUSIVE_FORCEINLINE bucket_ptr get_bucket_ptr() const + { return members_.nodeptr_; } + + private: + + BOOST_INTRUSIVE_FORCEINLINE pointer operator_arrow(detail::false_) const + { return value_traits::to_value_ptr(downcast_bucket(slist_it_.pointed_node())); } + + BOOST_INTRUSIVE_FORCEINLINE pointer operator_arrow(detail::true_) const + { return this->get_value_traits()->to_value_ptr(downcast_bucket(slist_it_.pointed_node())); } + + void increment() + { + ++slist_it_; + if (slist_it_ == siterator()){ + slist_node_ptr bucket_nodeptr; + do { + ++members_.nodeptr_; + bucket_nodeptr = members_.nodeptr_->get_node_ptr(); + }while(slist_node_algorithms::is_empty(bucket_nodeptr)); + slist_it_ = siterator(slist_node_traits::get_next(bucket_nodeptr)); + } + } + + siterator slist_it_; + iiterator_members members_; +}; + } //namespace intrusive { } //namespace boost { diff --git a/include/boost/intrusive/detail/hook_traits.hpp b/include/boost/intrusive/detail/hook_traits.hpp index 7f7dc27e0..06713487f 100644 --- a/include/boost/intrusive/detail/hook_traits.hpp +++ b/include/boost/intrusive/detail/hook_traits.hpp @@ -28,6 +28,7 @@ #include #include #include +#include namespace boost { namespace intrusive { @@ -55,7 +56,7 @@ struct bhtraits_base typedef node& node_reference; typedef const node & const_node_reference; - BOOST_INTRUSIVE_FORCEINLINE static pointer to_value_ptr(const node_ptr & n) + BOOST_INTRUSIVE_FORCEINLINE static pointer to_value_ptr(node_ptr n) { pointer p = pointer_traits::pointer_to (static_cast(static_cast(*n))); @@ -63,7 +64,7 @@ struct bhtraits_base return p; } - BOOST_INTRUSIVE_FORCEINLINE static const_pointer to_value_ptr(const const_node_ptr & n) + BOOST_INTRUSIVE_FORCEINLINE static const_pointer to_value_ptr(const_node_ptr n) { const_pointer p = pointer_traits::pointer_to (static_cast(static_cast(*n))); @@ -132,14 +133,14 @@ struct mhtraits (static_cast(static_cast(value.*P))); } - BOOST_INTRUSIVE_FORCEINLINE static pointer to_value_ptr(const node_ptr & n) + BOOST_INTRUSIVE_FORCEINLINE static pointer to_value_ptr(node_ptr n) { return pointer_traits::pointer_to (*detail::parent_from_member (static_cast(boost::movelib::to_raw_pointer(n)), P)); } - BOOST_INTRUSIVE_FORCEINLINE static const_pointer to_value_ptr(const const_node_ptr & n) + BOOST_INTRUSIVE_FORCEINLINE static const_pointer to_value_ptr(const_node_ptr n) { return pointer_traits::pointer_to (*detail::parent_from_member @@ -174,17 +175,17 @@ struct fhtraits static const_node_ptr to_node_ptr(const_reference value) { return static_cast(boost::movelib::to_raw_pointer(Functor::to_hook_ptr(value))); } - static pointer to_value_ptr(const node_ptr & n) + static pointer to_value_ptr(node_ptr n) { return Functor::to_value_ptr(to_hook_ptr(n)); } - static const_pointer to_value_ptr(const const_node_ptr & n) + static const_pointer to_value_ptr(const_node_ptr n) { return Functor::to_value_ptr(to_hook_ptr(n)); } private: - static hook_ptr to_hook_ptr(const node_ptr & n) + static hook_ptr to_hook_ptr(node_ptr n) { return hook_ptr(&*static_cast(&*n)); } - static const_hook_ptr to_hook_ptr(const const_node_ptr & n) + static const_hook_ptr to_hook_ptr(const_node_ptr n) { return const_hook_ptr(&*static_cast(&*n)); } }; diff --git a/include/boost/intrusive/detail/iterator.hpp b/include/boost/intrusive/detail/iterator.hpp index 41ffca125..ec91cd4f2 100644 --- a/include/boost/intrusive/detail/iterator.hpp +++ b/include/boost/intrusive/detail/iterator.hpp @@ -49,6 +49,11 @@ namespace boost { namespace intrusive { using boost::movelib::iterator_traits; +using boost::movelib::iter_difference; +using boost::movelib::iter_value; +using boost::movelib::iter_category; +using boost::movelib::iter_size; + //////////////////// // iterator @@ -63,26 +68,59 @@ struct iterator typedef Reference reference; }; -//////////////////////////////////////// -// iterator_[dis|en]able_if_boost_iterator -//////////////////////////////////////// -template -struct is_boost_iterator +//////////////////////////////////////////////////////////////////////////////// +// Conversion from boost::iterator traversals to std tags +//////////////////////////////////////////////////////////////////////////////// + +template +struct get_std_category_from_tag { - static const bool value = false; + typedef Tag type; }; -template -struct is_boost_iterator< boost::iterators::detail::iterator_category_with_traversal > +template +struct get_std_category_from_tag + > { - static const bool value = true; + typedef std::input_iterator_tag type; }; -template -struct iterator_enable_if_boost_iterator - : ::boost::move_detail::enable_if_c - < is_boost_iterator::iterator_category >::value - , R> +template +struct get_std_category_from_tag + > +{ + typedef std::input_iterator_tag type; +}; + +template +struct get_std_category_from_tag + > +{ + typedef std::input_iterator_tag type; +}; + +template +struct get_std_category_from_tag + > +{ + typedef std::bidirectional_iterator_tag type; +}; + +template +struct get_std_category_from_tag + > +{ + typedef std::random_access_iterator_tag type; +}; + +template +struct get_std_category_from_it + : get_std_category_from_tag< typename boost::intrusive::iter_category::type > {}; //////////////////////////////////////// @@ -92,7 +130,7 @@ template struct iterator_enable_if_tag : ::boost::move_detail::enable_if_c < ::boost::move_detail::is_same - < typename boost::intrusive::iterator_traits::iterator_category + < typename get_std_category_from_it::type , Tag >::value , R> @@ -102,7 +140,7 @@ template struct iterator_disable_if_tag : ::boost::move_detail::enable_if_c < !::boost::move_detail::is_same - < typename boost::intrusive::iterator_traits::iterator_category + < typename get_std_category_from_it::type , Tag >::value , R> @@ -115,11 +153,11 @@ template struct iterator_enable_if_convertible_tag : ::boost::move_detail::enable_if_c < ::boost::move_detail::is_same_or_convertible - < typename boost::intrusive::iterator_traits::iterator_category + < typename get_std_category_from_it::type , Tag >::value && !::boost::move_detail::is_same_or_convertible - < typename boost::intrusive::iterator_traits::iterator_category + < typename get_std_category_from_it::type , Tag2 >::value , R> @@ -130,37 +168,37 @@ struct iterator_enable_if_convertible_tag //////////////////////////////////////// template struct iterator_enable_if_tag_difference_type - : iterator_enable_if_tag::difference_type> + : iterator_enable_if_tag::type> {}; template struct iterator_disable_if_tag_difference_type - : iterator_disable_if_tag::difference_type> + : iterator_disable_if_tag::type> {}; //////////////////// // advance //////////////////// -template +template BOOST_INTRUSIVE_FORCEINLINE typename iterator_enable_if_tag::type - iterator_advance(InputIt& it, Distance n) + iterator_advance(InputIt& it, typename iter_difference::type n) { while(n--) ++it; } -template +template typename iterator_enable_if_tag::type - iterator_advance(InputIt& it, Distance n) + iterator_advance(InputIt& it, typename iter_difference::type n) { while(n--) ++it; } -template +template BOOST_INTRUSIVE_FORCEINLINE typename iterator_enable_if_tag::type - iterator_advance(InputIt& it, Distance n) + iterator_advance(InputIt& it, typename iter_difference::type n) { for (; 0 < n; --n) ++it; @@ -176,62 +214,37 @@ BOOST_INTRUSIVE_FORCEINLINE typename iterator_enable_if_tag -BOOST_INTRUSIVE_FORCEINLINE typename iterator_enable_if_convertible_tag - ::type - iterator_advance(InputIt& it, Distance n) -{ - while(n--) - ++it; -} - -template -BOOST_INTRUSIVE_FORCEINLINE typename iterator_enable_if_convertible_tag - ::type - iterator_advance(InputIt& it, Distance n) -{ - while(n--) - ++it; -} - -template -BOOST_INTRUSIVE_FORCEINLINE typename iterator_enable_if_convertible_tag - ::type - iterator_advance(InputIt& it, Distance n) +BOOST_INTRUSIVE_FORCEINLINE typename iterator_enable_if_tag::type + make_iterator_advance(InputIt it, Distance n) { - while(n--) - ++it; + (iterator_advance)(it, n); + return it; } -template -BOOST_INTRUSIVE_FORCEINLINE typename iterator_enable_if_convertible_tag - ::type - iterator_advance(InputIt& it, Distance n) +template +BOOST_INTRUSIVE_FORCEINLINE + void iterator_uadvance(It& it, typename iter_size::type n) { - for (; 0 < n; --n) - ++it; - for (; n < 0; ++n) - --it; + (iterator_advance)(it, (typename iterator_traits::difference_type)n); } -class fake{}; - -template -BOOST_INTRUSIVE_FORCEINLINE typename iterator_enable_if_convertible_tag - ::type - iterator_advance(InputIt& it, Distance n) +template +BOOST_INTRUSIVE_FORCEINLINE +It make_iterator_uadvance(It it, typename iter_size::type n) { - it += n; + (iterator_uadvance)(it, n); + return it; } -//////////////////// -// distance -//////////////////// +//////////////////////////////////////// +// iterator_distance +//////////////////////////////////////// template inline typename iterator_disable_if_tag_difference_type ::type iterator_distance(InputIt first, InputIt last) { - typename iterator_traits::difference_type off = 0; + typename iter_difference::type off = 0; while(first != last){ ++off; ++first; @@ -244,10 +257,43 @@ BOOST_INTRUSIVE_FORCEINLINE typename iterator_enable_if_tag_difference_type ::type iterator_distance(InputIt first, InputIt last) { - typename iterator_traits::difference_type off = last - first; + typename iter_difference::type off = last - first; return off; } +//////////////////////////////////////// +// iterator_udistance +//////////////////////////////////////// + +template +BOOST_INTRUSIVE_FORCEINLINE typename iter_size::type + iterator_udistance(It first, It last) +{ + return (typename iter_size::type)(iterator_distance)(first, last); +} + +//////////////////////////////////////// +// iterator_next +//////////////////////////////////////// + +template +BOOST_INTRUSIVE_FORCEINLINE InputIt iterator_next(InputIt it, typename iter_difference::type n) +{ + (iterator_advance)(it, n); + return it; +} + +template +BOOST_INTRUSIVE_FORCEINLINE InputIt iterator_unext(InputIt it, typename iterator_traits::size_type n) +{ + (iterator_uadvance)(it, n); + return it; +} + +//////////////////////////////////////// +// iterator_arrow_result +//////////////////////////////////////// + template BOOST_INTRUSIVE_FORCEINLINE typename iterator_traits::pointer iterator_arrow_result(const I &i) { return i.operator->(); } diff --git a/include/boost/intrusive/detail/list_iterator.hpp b/include/boost/intrusive/detail/list_iterator.hpp index 880b6a984..f301a4b8e 100644 --- a/include/boost/intrusive/detail/list_iterator.hpp +++ b/include/boost/intrusive/detail/list_iterator.hpp @@ -63,7 +63,7 @@ class list_iterator BOOST_INTRUSIVE_FORCEINLINE list_iterator() {} - BOOST_INTRUSIVE_FORCEINLINE explicit list_iterator(const node_ptr & nodeptr, const const_value_traits_ptr &traits_ptr) + BOOST_INTRUSIVE_FORCEINLINE explicit list_iterator(node_ptr nodeptr, const_value_traits_ptr traits_ptr) : members_(nodeptr, traits_ptr) {} @@ -81,8 +81,8 @@ class list_iterator BOOST_INTRUSIVE_FORCEINLINE node_ptr pointed_node() const { return members_.nodeptr_; } - BOOST_INTRUSIVE_FORCEINLINE list_iterator &operator=(const node_ptr &node) - { members_.nodeptr_ = node; return *this; } + BOOST_INTRUSIVE_FORCEINLINE list_iterator &operator=(node_ptr nodeptr) + { members_.nodeptr_ = nodeptr; return *this; } BOOST_INTRUSIVE_FORCEINLINE const_value_traits_ptr get_value_traits() const { return members_.get_ptr(); } diff --git a/include/boost/intrusive/detail/list_node.hpp b/include/boost/intrusive/detail/list_node.hpp index bc30e89f2..eac56f6d4 100644 --- a/include/boost/intrusive/detail/list_node.hpp +++ b/include/boost/intrusive/detail/list_node.hpp @@ -47,19 +47,19 @@ struct list_node_traits typedef typename node::node_ptr node_ptr; typedef typename pointer_rebind::type const_node_ptr; - BOOST_INTRUSIVE_FORCEINLINE static node_ptr get_previous(const const_node_ptr & n) + BOOST_INTRUSIVE_FORCEINLINE static node_ptr get_previous(const_node_ptr n) { return n->prev_; } - BOOST_INTRUSIVE_FORCEINLINE static node_ptr get_previous(const node_ptr & n) + BOOST_INTRUSIVE_FORCEINLINE static node_ptr get_previous(node_ptr n) { return n->prev_; } BOOST_INTRUSIVE_FORCEINLINE static void set_previous(node_ptr n, node_ptr prev) { n->prev_ = prev; } - BOOST_INTRUSIVE_FORCEINLINE static node_ptr get_next(const const_node_ptr & n) + BOOST_INTRUSIVE_FORCEINLINE static node_ptr get_next(const_node_ptr n) { return n->next_; } - BOOST_INTRUSIVE_FORCEINLINE static node_ptr get_next(const node_ptr & n) + BOOST_INTRUSIVE_FORCEINLINE static node_ptr get_next(node_ptr n) { return n->next_; } BOOST_INTRUSIVE_FORCEINLINE static void set_next(node_ptr n, node_ptr next) diff --git a/include/boost/intrusive/detail/math.hpp b/include/boost/intrusive/detail/math.hpp index c13e745a2..ff379f658 100644 --- a/include/boost/intrusive/detail/math.hpp +++ b/include/boost/intrusive/detail/math.hpp @@ -93,7 +93,7 @@ namespace detail { struct builtin_clz_dispatch< ::boost::ulong_long_type > { static ::boost::ulong_long_type call(::boost::ulong_long_type n) - { return __builtin_clzll(n); } + { return (::boost::ulong_long_type)__builtin_clzll(n); } }; #endif @@ -101,14 +101,14 @@ namespace detail { struct builtin_clz_dispatch { static unsigned long call(unsigned long n) - { return __builtin_clzl(n); } + { return (unsigned long)__builtin_clzl(n); } }; template<> struct builtin_clz_dispatch { static unsigned int call(unsigned int n) - { return __builtin_clz(n); } + { return (unsigned int)__builtin_clz(n); } }; inline std::size_t floor_log2(std::size_t n) @@ -150,53 +150,6 @@ namespace detail { return log2; } - //////////////////////////// - // DeBruijn method - //////////////////////////// - - //Taken from: - //http://stackoverflow.com/questions/11376288/fast-computing-of-log2-for-64-bit-integers - //Thanks to Desmond Hume - - inline std::size_t floor_log2 (std::size_t v, integral_constant) - { - static const int MultiplyDeBruijnBitPosition[32] = - { - 0, 9, 1, 10, 13, 21, 2, 29, 11, 14, 16, 18, 22, 25, 3, 30, - 8, 12, 20, 28, 15, 17, 24, 7, 19, 27, 23, 6, 26, 5, 4, 31 - }; - - v |= v >> 1; - v |= v >> 2; - v |= v >> 4; - v |= v >> 8; - v |= v >> 16; - - return MultiplyDeBruijnBitPosition[(std::size_t)(v * 0x07C4ACDDU) >> 27]; - } - - inline std::size_t floor_log2 (std::size_t v, integral_constant) - { - static const std::size_t MultiplyDeBruijnBitPosition[64] = { - 63, 0, 58, 1, 59, 47, 53, 2, - 60, 39, 48, 27, 54, 33, 42, 3, - 61, 51, 37, 40, 49, 18, 28, 20, - 55, 30, 34, 11, 43, 14, 22, 4, - 62, 57, 46, 52, 38, 26, 32, 41, - 50, 36, 17, 19, 29, 10, 13, 21, - 56, 45, 25, 31, 35, 16, 9, 12, - 44, 24, 15, 8, 23, 7, 6, 5}; - - v |= v >> 1; - v |= v >> 2; - v |= v >> 4; - v |= v >> 8; - v |= v >> 16; - v |= v >> 32; - return MultiplyDeBruijnBitPosition[((std::size_t)((v - (v >> 1))*0x07EDD5E59A4E28C2ULL)) >> 58]; - } - - inline std::size_t floor_log2 (std::size_t x) { const std::size_t Bits = sizeof(std::size_t)*CHAR_BIT; @@ -209,13 +162,12 @@ namespace detail { //http://www.flipcode.com/archives/Fast_log_Function.shtml inline float fast_log2 (float val) { - float f = val; unsigned x; - std::memcpy(&x, &val, sizeof(f)); + std::memcpy(&x, &val, sizeof(float)); const int log_2 = int((x >> 23) & 255) - 128; x &= ~(unsigned(255u) << 23u); x += unsigned(127) << 23u; - std::memcpy(&val, &x, sizeof(f)); + std::memcpy(&val, &x, sizeof(float)); //1+log2(m), m ranging from 1 to 2 //3rd degree polynomial keeping first derivate continuity. //For less precision the line can be commented out diff --git a/include/boost/intrusive/detail/mpl.hpp b/include/boost/intrusive/detail/mpl.hpp index 935c04c28..d86fa4f3c 100644 --- a/include/boost/intrusive/detail/mpl.hpp +++ b/include/boost/intrusive/detail/mpl.hpp @@ -155,7 +155,7 @@ template \ struct TRAITS_PREFIX##_bool\ {\ template\ - struct two_or_three {yes_type _[2 + Add];};\ + struct two_or_three {yes_type _[2u + (unsigned)Add];};\ template static yes_type test(...);\ template static two_or_three test (int);\ static const std::size_t value = sizeof(test(0));\ diff --git a/include/boost/intrusive/detail/node_cloner_disposer.hpp b/include/boost/intrusive/detail/node_cloner_disposer.hpp index 8ed3c4dab..97e8d1532 100644 --- a/include/boost/intrusive/detail/node_cloner_disposer.hpp +++ b/include/boost/intrusive/detail/node_cloner_disposer.hpp @@ -59,7 +59,7 @@ struct node_cloner {} // tree-based containers use this method, which is proxy-reference friendly - BOOST_INTRUSIVE_FORCEINLINE node_ptr operator()(const node_ptr & p) + BOOST_INTRUSIVE_FORCEINLINE node_ptr operator()(node_ptr p) { reference_type v = *traits_->to_value_ptr(p); node_ptr n = traits_->to_node_ptr(*base_t::get()(v)); @@ -85,13 +85,13 @@ struct node_disposer static const bool safemode_or_autounlink = is_safe_autounlink::value; - node_disposer(F f, const ValueTraits *cont) + BOOST_INTRUSIVE_FORCEINLINE node_disposer(F f, const ValueTraits *cont) : base_t(f), traits_(cont) {} - BOOST_INTRUSIVE_FORCEINLINE void operator()(const node_ptr & p) + BOOST_INTRUSIVE_FORCEINLINE void operator()(node_ptr p) { - if(safemode_or_autounlink) + BOOST_IF_CONSTEXPR(safemode_or_autounlink) node_algorithms::init(p); base_t::get()(traits_->to_value_ptr(p)); } diff --git a/include/boost/intrusive/detail/node_to_value.hpp b/include/boost/intrusive/detail/node_to_value.hpp index 218e78e4e..3085e0c3a 100644 --- a/include/boost/intrusive/detail/node_to_value.hpp +++ b/include/boost/intrusive/detail/node_to_value.hpp @@ -103,7 +103,7 @@ struct node_to_value typedef typename pointer_traits:: template rebind_pointer::type const_value_traits_ptr; - node_to_value(const const_value_traits_ptr &ptr) + node_to_value(const_value_traits_ptr ptr) : Base(ptr) {} diff --git a/include/boost/intrusive/detail/rbtree_node.hpp b/include/boost/intrusive/detail/rbtree_node.hpp index 8b573ecc2..07811991c 100644 --- a/include/boost/intrusive/detail/rbtree_node.hpp +++ b/include/boost/intrusive/detail/rbtree_node.hpp @@ -74,40 +74,40 @@ struct default_rbtree_node_traits_impl typedef typename node::color color; - BOOST_INTRUSIVE_FORCEINLINE static node_ptr get_parent(const const_node_ptr & n) + BOOST_INTRUSIVE_FORCEINLINE static node_ptr get_parent(const_node_ptr n) { return n->parent_; } - BOOST_INTRUSIVE_FORCEINLINE static node_ptr get_parent(const node_ptr & n) + BOOST_INTRUSIVE_FORCEINLINE static node_ptr get_parent(node_ptr n) { return n->parent_; } BOOST_INTRUSIVE_FORCEINLINE static void set_parent(node_ptr n, node_ptr p) { n->parent_ = p; } - BOOST_INTRUSIVE_FORCEINLINE static node_ptr get_left(const const_node_ptr & n) + BOOST_INTRUSIVE_FORCEINLINE static node_ptr get_left(const_node_ptr n) { return n->left_; } - BOOST_INTRUSIVE_FORCEINLINE static node_ptr get_left(const node_ptr & n) + BOOST_INTRUSIVE_FORCEINLINE static node_ptr get_left(node_ptr n) { return n->left_; } BOOST_INTRUSIVE_FORCEINLINE static void set_left(node_ptr n, node_ptr l) { n->left_ = l; } - BOOST_INTRUSIVE_FORCEINLINE static node_ptr get_right(const const_node_ptr & n) + BOOST_INTRUSIVE_FORCEINLINE static node_ptr get_right(const_node_ptr n) { return n->right_; } - BOOST_INTRUSIVE_FORCEINLINE static node_ptr get_right(const node_ptr & n) + BOOST_INTRUSIVE_FORCEINLINE static node_ptr get_right(node_ptr n) { return n->right_; } BOOST_INTRUSIVE_FORCEINLINE static void set_right(node_ptr n, node_ptr r) { n->right_ = r; } - BOOST_INTRUSIVE_FORCEINLINE static color get_color(const const_node_ptr & n) + BOOST_INTRUSIVE_FORCEINLINE static color get_color(const_node_ptr n) { return n->color_; } - BOOST_INTRUSIVE_FORCEINLINE static color get_color(const node_ptr & n) + BOOST_INTRUSIVE_FORCEINLINE static color get_color(node_ptr n) { return n->color_; } - BOOST_INTRUSIVE_FORCEINLINE static void set_color(const node_ptr & n, color c) + BOOST_INTRUSIVE_FORCEINLINE static void set_color(node_ptr n, color c) { n->color_ = c; } BOOST_INTRUSIVE_FORCEINLINE static color black() @@ -130,40 +130,40 @@ struct compact_rbtree_node_traits_impl typedef typename node::color color; - BOOST_INTRUSIVE_FORCEINLINE static node_ptr get_parent(const const_node_ptr & n) + BOOST_INTRUSIVE_FORCEINLINE static node_ptr get_parent(const_node_ptr n) { return ptr_bit::get_pointer(n->parent_); } - BOOST_INTRUSIVE_FORCEINLINE static node_ptr get_parent(const node_ptr & n) + BOOST_INTRUSIVE_FORCEINLINE static node_ptr get_parent(node_ptr n) { return ptr_bit::get_pointer(n->parent_); } BOOST_INTRUSIVE_FORCEINLINE static void set_parent(node_ptr n, node_ptr p) { ptr_bit::set_pointer(n->parent_, p); } - BOOST_INTRUSIVE_FORCEINLINE static node_ptr get_left(const const_node_ptr & n) + BOOST_INTRUSIVE_FORCEINLINE static node_ptr get_left(const_node_ptr n) { return n->left_; } - BOOST_INTRUSIVE_FORCEINLINE static node_ptr get_left(const node_ptr & n) + BOOST_INTRUSIVE_FORCEINLINE static node_ptr get_left(node_ptr n) { return n->left_; } BOOST_INTRUSIVE_FORCEINLINE static void set_left(node_ptr n, node_ptr l) { n->left_ = l; } - BOOST_INTRUSIVE_FORCEINLINE static node_ptr get_right(const const_node_ptr & n) + BOOST_INTRUSIVE_FORCEINLINE static node_ptr get_right(const_node_ptr n) { return n->right_; } - BOOST_INTRUSIVE_FORCEINLINE static node_ptr get_right(const node_ptr & n) + BOOST_INTRUSIVE_FORCEINLINE static node_ptr get_right(node_ptr n) { return n->right_; } BOOST_INTRUSIVE_FORCEINLINE static void set_right(node_ptr n, node_ptr r) { n->right_ = r; } - BOOST_INTRUSIVE_FORCEINLINE static color get_color(const const_node_ptr & n) + BOOST_INTRUSIVE_FORCEINLINE static color get_color(const_node_ptr n) { return (color)ptr_bit::get_bits(n->parent_); } - BOOST_INTRUSIVE_FORCEINLINE static color get_color(const node_ptr & n) + BOOST_INTRUSIVE_FORCEINLINE static color get_color(node_ptr n) { return (color)ptr_bit::get_bits(n->parent_); } - BOOST_INTRUSIVE_FORCEINLINE static void set_color(const node_ptr & n, color c) + BOOST_INTRUSIVE_FORCEINLINE static void set_color(node_ptr n, color c) { ptr_bit::set_bits(n->parent_, c != 0); } BOOST_INTRUSIVE_FORCEINLINE static color black() diff --git a/include/boost/intrusive/detail/reverse_iterator.hpp b/include/boost/intrusive/detail/reverse_iterator.hpp index 57631feb5..00b0e5f35 100644 --- a/include/boost/intrusive/detail/reverse_iterator.hpp +++ b/include/boost/intrusive/detail/reverse_iterator.hpp @@ -13,153 +13,16 @@ #ifndef BOOST_INTRUSIVE_DETAIL_REVERSE_ITERATOR_HPP #define BOOST_INTRUSIVE_DETAIL_REVERSE_ITERATOR_HPP -#ifndef BOOST_CONFIG_HPP -# include -#endif - -#if defined(BOOST_HAS_PRAGMA_ONCE) -# pragma once -#endif - -#include -#include -#include +#include namespace boost { namespace intrusive { -template -class reverse_iterator -{ - public: - typedef typename boost::intrusive::iterator_traits::pointer pointer; - typedef typename boost::intrusive::iterator_traits::reference reference; - typedef typename boost::intrusive::iterator_traits::difference_type difference_type; - typedef typename boost::intrusive::iterator_traits::iterator_category iterator_category; - typedef typename boost::intrusive::iterator_traits::value_type value_type; - - - typedef It iterator_type; - - reverse_iterator() - : m_current() //Value initialization to achieve "null iterators" (N3644) - {} - - explicit reverse_iterator(It r) - : m_current(r) - {} - - reverse_iterator(const reverse_iterator& r) - : m_current(r.base()) - {} - - template - reverse_iterator( const reverse_iterator& r - , typename boost::intrusive::detail::enable_if_convertible::type* =0 - ) - : m_current(r.base()) - {} - - reverse_iterator & operator=( const reverse_iterator& r) - { m_current = r.base(); return *this; } - - template - typename boost::intrusive::detail::enable_if_convertible::type - operator=( const reverse_iterator& r) - { m_current = r.base(); return *this; } - - It base() const - { return m_current; } - - reference operator*() const - { - It temp(m_current); - --temp; - reference r = *temp; - return r; - } - - pointer operator->() const - { - It temp(m_current); - --temp; - return iterator_arrow_result(temp); - } - - reference operator[](difference_type off) const - { - return this->m_current[-off - 1]; - } - - reverse_iterator& operator++() - { - --m_current; - return *this; - } - - reverse_iterator operator++(int) - { - reverse_iterator temp((*this)); - --m_current; - return temp; - } - - reverse_iterator& operator--() - { - ++m_current; - return *this; - } - - reverse_iterator operator--(int) - { - reverse_iterator temp((*this)); - ++m_current; - return temp; - } - - friend bool operator==(const reverse_iterator& l, const reverse_iterator& r) - { return l.m_current == r.m_current; } - - friend bool operator!=(const reverse_iterator& l, const reverse_iterator& r) - { return l.m_current != r.m_current; } - - friend bool operator<(const reverse_iterator& l, const reverse_iterator& r) - { return l.m_current > r.m_current; } - - friend bool operator<=(const reverse_iterator& l, const reverse_iterator& r) - { return l.m_current >= r.m_current; } - - friend bool operator>(const reverse_iterator& l, const reverse_iterator& r) - { return l.m_current < r.m_current; } - - friend bool operator>=(const reverse_iterator& l, const reverse_iterator& r) - { return l.m_current <= r.m_current; } - - reverse_iterator& operator+=(difference_type off) - { m_current -= off; return *this; } - - reverse_iterator& operator-=(difference_type off) - { m_current += off; return *this; } - - friend reverse_iterator operator+(reverse_iterator l, difference_type off) - { return (l += off); } - - friend reverse_iterator operator+(difference_type off, reverse_iterator r) - { return (r += off); } - - friend reverse_iterator operator-(reverse_iterator l, difference_type off) - { return (l-= off); } - - friend difference_type operator-(const reverse_iterator& l, const reverse_iterator& r) - { return r.m_current - l.m_current; } - - private: - It m_current; // the wrapped iterator -}; +using boost::movelib::reverse_iterator; +using boost::movelib::make_reverse_iterator; } //namespace intrusive { } //namespace boost { -#include #endif //BOOST_INTRUSIVE_DETAIL_REVERSE_ITERATOR_HPP diff --git a/include/boost/intrusive/detail/simple_disposers.hpp b/include/boost/intrusive/detail/simple_disposers.hpp index 17fa1e46b..6b9bd4bc6 100644 --- a/include/boost/intrusive/detail/simple_disposers.hpp +++ b/include/boost/intrusive/detail/simple_disposers.hpp @@ -41,7 +41,7 @@ class init_disposer typedef typename NodeAlgorithms::node_ptr node_ptr; public: - BOOST_INTRUSIVE_FORCEINLINE void operator()(const node_ptr & p) + BOOST_INTRUSIVE_FORCEINLINE void operator()(node_ptr p) { NodeAlgorithms::init(p); } }; diff --git a/include/boost/intrusive/detail/slist_iterator.hpp b/include/boost/intrusive/detail/slist_iterator.hpp index 9e72af9f3..9c5ee2747 100644 --- a/include/boost/intrusive/detail/slist_iterator.hpp +++ b/include/boost/intrusive/detail/slist_iterator.hpp @@ -27,6 +27,7 @@ #include #include #include +#include namespace boost { namespace intrusive { @@ -65,10 +66,14 @@ class slist_iterator BOOST_INTRUSIVE_FORCEINLINE slist_iterator() {} - BOOST_INTRUSIVE_FORCEINLINE explicit slist_iterator(const node_ptr & nodeptr, const const_value_traits_ptr &traits_ptr) + BOOST_INTRUSIVE_FORCEINLINE slist_iterator(node_ptr nodeptr, const_value_traits_ptr traits_ptr) : members_(nodeptr, traits_ptr) {} + BOOST_INTRUSIVE_FORCEINLINE explicit slist_iterator(node_ptr nodeptr) + : members_(nodeptr, const_value_traits_ptr()) + { BOOST_STATIC_ASSERT((stateful_value_traits == false)); } + BOOST_INTRUSIVE_FORCEINLINE slist_iterator(const slist_iterator &other) : members_(other.pointed_node(), other.get_value_traits()) {} @@ -83,12 +88,15 @@ class slist_iterator BOOST_INTRUSIVE_FORCEINLINE node_ptr pointed_node() const { return members_.nodeptr_; } - BOOST_INTRUSIVE_FORCEINLINE slist_iterator &operator=(const node_ptr &node) - { members_.nodeptr_ = node; return static_cast(*this); } + BOOST_INTRUSIVE_FORCEINLINE slist_iterator &operator=(node_ptr n) + { members_.nodeptr_ = n; return static_cast(*this); } BOOST_INTRUSIVE_FORCEINLINE const_value_traits_ptr get_value_traits() const { return members_.get_ptr(); } + BOOST_INTRUSIVE_FORCEINLINE bool operator!() const + { return !members_.nodeptr_; } + public: BOOST_INTRUSIVE_FORCEINLINE slist_iterator& operator++() { @@ -107,7 +115,7 @@ class slist_iterator { return l.pointed_node() == r.pointed_node(); } BOOST_INTRUSIVE_FORCEINLINE friend bool operator!= (const slist_iterator& l, const slist_iterator& r) - { return !(l == r); } + { return l.pointed_node() != r.pointed_node(); } BOOST_INTRUSIVE_FORCEINLINE reference operator*() const { return *operator->(); } diff --git a/include/boost/intrusive/detail/slist_node.hpp b/include/boost/intrusive/detail/slist_node.hpp index ee8ab40a3..d209f76ad 100644 --- a/include/boost/intrusive/detail/slist_node.hpp +++ b/include/boost/intrusive/detail/slist_node.hpp @@ -46,10 +46,10 @@ struct slist_node_traits typedef typename node::node_ptr node_ptr; typedef typename pointer_rebind::type const_node_ptr; - BOOST_INTRUSIVE_FORCEINLINE static node_ptr get_next(const const_node_ptr & n) + BOOST_INTRUSIVE_FORCEINLINE static node_ptr get_next(const_node_ptr n) { return n->next_; } - BOOST_INTRUSIVE_FORCEINLINE static node_ptr get_next(const node_ptr & n) + BOOST_INTRUSIVE_FORCEINLINE static node_ptr get_next(node_ptr n) { return n->next_; } BOOST_INTRUSIVE_FORCEINLINE static void set_next(node_ptr n, node_ptr next) diff --git a/include/boost/intrusive/detail/tree_iterator.hpp b/include/boost/intrusive/detail/tree_iterator.hpp index 41988cf18..ba1375f8c 100644 --- a/include/boost/intrusive/detail/tree_iterator.hpp +++ b/include/boost/intrusive/detail/tree_iterator.hpp @@ -71,7 +71,7 @@ class tree_iterator BOOST_INTRUSIVE_FORCEINLINE tree_iterator() {} - BOOST_INTRUSIVE_FORCEINLINE explicit tree_iterator(const node_ptr & nodeptr, const const_value_traits_ptr &traits_ptr) + BOOST_INTRUSIVE_FORCEINLINE explicit tree_iterator(node_ptr nodeptr, const_value_traits_ptr traits_ptr) : members_(nodeptr, traits_ptr) {} @@ -86,7 +86,7 @@ class tree_iterator BOOST_INTRUSIVE_FORCEINLINE tree_iterator &operator=(const tree_iterator &other) { members_.nodeptr_ = other.members_.nodeptr_; return *this; } - BOOST_INTRUSIVE_FORCEINLINE tree_iterator &operator=(const node_ptr &nodeptr) + BOOST_INTRUSIVE_FORCEINLINE tree_iterator &operator=(node_ptr nodeptr) { members_.nodeptr_ = nodeptr; return *this; } BOOST_INTRUSIVE_FORCEINLINE node_ptr pointed_node() const diff --git a/include/boost/intrusive/detail/tree_node.hpp b/include/boost/intrusive/detail/tree_node.hpp index 6df3343e0..949d2d913 100644 --- a/include/boost/intrusive/detail/tree_node.hpp +++ b/include/boost/intrusive/detail/tree_node.hpp @@ -44,28 +44,28 @@ struct tree_node_traits typedef typename node::node_ptr node_ptr; typedef typename pointer_rebind::type const_node_ptr; - BOOST_INTRUSIVE_FORCEINLINE static node_ptr get_parent(const const_node_ptr & n) + BOOST_INTRUSIVE_FORCEINLINE static node_ptr get_parent(const_node_ptr n) { return n->parent_; } - BOOST_INTRUSIVE_FORCEINLINE static node_ptr get_parent(const node_ptr & n) + BOOST_INTRUSIVE_FORCEINLINE static node_ptr get_parent(node_ptr n) { return n->parent_; } BOOST_INTRUSIVE_FORCEINLINE static void set_parent(node_ptr n, node_ptr p) { n->parent_ = p; } - BOOST_INTRUSIVE_FORCEINLINE static node_ptr get_left(const const_node_ptr & n) + BOOST_INTRUSIVE_FORCEINLINE static node_ptr get_left(const_node_ptr n) { return n->left_; } - BOOST_INTRUSIVE_FORCEINLINE static node_ptr get_left(const node_ptr & n) + BOOST_INTRUSIVE_FORCEINLINE static node_ptr get_left(node_ptr n) { return n->left_; } BOOST_INTRUSIVE_FORCEINLINE static void set_left(node_ptr n, node_ptr l) { n->left_ = l; } - BOOST_INTRUSIVE_FORCEINLINE static node_ptr get_right(const const_node_ptr & n) + BOOST_INTRUSIVE_FORCEINLINE static node_ptr get_right(const_node_ptr n) { return n->right_; } - BOOST_INTRUSIVE_FORCEINLINE static node_ptr get_right(const node_ptr & n) + BOOST_INTRUSIVE_FORCEINLINE static node_ptr get_right(node_ptr n) { return n->right_; } BOOST_INTRUSIVE_FORCEINLINE static void set_right(node_ptr n, node_ptr r) diff --git a/include/boost/intrusive/detail/twin.hpp b/include/boost/intrusive/detail/twin.hpp new file mode 100644 index 000000000..b778732f4 --- /dev/null +++ b/include/boost/intrusive/detail/twin.hpp @@ -0,0 +1,49 @@ +///////////////////////////////////////////////////////////////////////////// +// +// (C) Copyright Ion Gaztanaga 2014-2014 +// +// 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) +// +// See http://www.boost.org/libs/intrusive for documentation. +// +///////////////////////////////////////////////////////////////////////////// + +#ifndef BOOST_INTRUSIVE_DETAIL_TWIN_HPP +#define BOOST_INTRUSIVE_DETAIL_TWIN_HPP + +#ifndef BOOST_CONFIG_HPP +# include +#endif + +#if defined(BOOST_HAS_PRAGMA_ONCE) +# pragma once +#endif + +//A tiny utility to avoid pulling std::pair / utility for +//very simple algorithms/types + +namespace boost { +namespace intrusive { + +template +struct twin +{ + typedef T type; + twin() + : first(), second() + {} + + twin(const type &f, const type &s) + : first(f), second(s) + {} + + T first; + T second; +}; + +} //namespace intrusive{ +} //namespace boost{ + +#endif //BOOST_INTRUSIVE_DETAIL_TWIN_HPP diff --git a/include/boost/intrusive/detail/value_functors.hpp b/include/boost/intrusive/detail/value_functors.hpp new file mode 100644 index 000000000..7e220ebef --- /dev/null +++ b/include/boost/intrusive/detail/value_functors.hpp @@ -0,0 +1,52 @@ +#ifndef BOOST_INTRUSIVE_DETAIL_VALUE_FUNCTORS_HPP +#define BOOST_INTRUSIVE_DETAIL_VALUE_FUNCTORS_HPP +/////////////////////////////////////////////////////////////////////////////// +// +// (C) Copyright Ion Gaztanaga 2017-2021. 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) +// +// See http://www.boost.org/libs/intrusive for documentation. +// +/////////////////////////////////////////////////////////////////////////////// + +#ifndef BOOST_CONFIG_HPP +# include +#endif + +#if defined(BOOST_HAS_PRAGMA_ONCE) +# pragma once +#endif + +#include + +namespace boost { +namespace intrusive { + +//Functors for member algorithm defaults +template +struct value_less +{ + bool operator()(const ValueType &a, const ValueType &b) const + { return a < b; } +}; + +//Functors for member algorithm defaults +template +struct value_less +{ + bool operator()(const T *a, const T* b) const + { return std::size_t(a) < std::size_t(b); } +}; + +template +struct value_equal +{ + bool operator()(const ValueType &a, const ValueType &b) const + { return a == b; } +}; + +} //namespace intrusive { +} //namespace boost { + +#endif //BOOST_INTRUSIVE_DETAIL_VALUE_FUNCTORS_HPP diff --git a/include/boost/intrusive/detail/workaround.hpp b/include/boost/intrusive/detail/workaround.hpp index f0cfaf2b2..0011fb5bf 100644 --- a/include/boost/intrusive/detail/workaround.hpp +++ b/include/boost/intrusive/detail/workaround.hpp @@ -45,14 +45,40 @@ #define BOOST_INTRUSIVE_FORCEINLINE inline #elif defined(BOOST_INTRUSIVE_FORCEINLINE_IS_BOOST_FORCELINE) #define BOOST_INTRUSIVE_FORCEINLINE BOOST_FORCEINLINE -#elif defined(BOOST_MSVC) && defined(_DEBUG) - //"__forceinline" and MSVC seems to have some bugs in debug mode +#elif defined(BOOST_MSVC) && (_MSC_VER < 1900 || defined(_DEBUG)) + //"__forceinline" and MSVC seems to have some bugs in old versions and in debug mode #define BOOST_INTRUSIVE_FORCEINLINE inline -#elif defined(__GNUC__) && ((__GNUC__ < 4) || (__GNUC__ == 4 && (__GNUC_MINOR__ < 5))) +#elif defined(BOOST_GCC) && ((__GNUC__ <= 5) || defined(__MINGW32__)) //Older GCCs have problems with forceinline #define BOOST_INTRUSIVE_FORCEINLINE inline #else #define BOOST_INTRUSIVE_FORCEINLINE BOOST_FORCEINLINE #endif +#if !(defined BOOST_NO_EXCEPTIONS) +# define BOOST_INTRUSIVE_TRY { try +# define BOOST_INTRUSIVE_CATCH(x) catch(x) +# define BOOST_INTRUSIVE_RETHROW throw; +# define BOOST_INTRUSIVE_CATCH_END } +#else +# if !defined(BOOST_MSVC) || BOOST_MSVC >= 1900 +# define BOOST_INTRUSIVE_TRY { if (true) +# define BOOST_INTRUSIVE_CATCH(x) else if (false) +# else +// warning C4127: conditional expression is constant +# define BOOST_INTRUSIVE_TRY { \ + __pragma(warning(push)) \ + __pragma(warning(disable: 4127)) \ + if (true) \ + __pragma(warning(pop)) +# define BOOST_INTRUSIVE_CATCH(x) else \ + __pragma(warning(push)) \ + __pragma(warning(disable: 4127)) \ + if (false) \ + __pragma(warning(pop)) +# endif +# define BOOST_INTRUSIVE_RETHROW +# define BOOST_INTRUSIVE_CATCH_END } +#endif + #endif //#ifndef BOOST_INTRUSIVE_DETAIL_WORKAROUND_HPP diff --git a/include/boost/intrusive/hashtable.hpp b/include/boost/intrusive/hashtable.hpp index 1fada98f8..688fb9b22 100644 --- a/include/boost/intrusive/hashtable.hpp +++ b/include/boost/intrusive/hashtable.hpp @@ -1,6 +1,8 @@ ///////////////////////////////////////////////////////////////////////////// // -// (C) Copyright Ion Gaztanaga 2006-2015 +// (C) Copyright Ion Gaztanaga 2006-2022 +// (C) Copyright 2022 Joaquin M Lopez Munoz. +// (C) Copyright 2022 Christian Mazakas // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at @@ -9,6 +11,21 @@ // See http://www.boost.org/libs/intrusive for documentation. // ///////////////////////////////////////////////////////////////////////////// + +// fastmod_buckets option is implemented reusing parts of Joaquin M. Lopez +// Munoz's "fxa_unordered" library (proof of concept of closed- and +// open-addressing unordered associative containers), released under +// Boost Software License: +// +// https://github.com/joaquintides/fxa_unordered/ +// +// On cases and systems that can't take advantage of Daniel Lemire's +// "fastmod" (https://github.com/lemire/fastmod) approach, +// precomputed divisions are used. +// +// As always, thanks Joaquin for your great work! + + #ifndef BOOST_INTRUSIVE_HASHTABLE_HPP #define BOOST_INTRUSIVE_HASHTABLE_HPP @@ -27,41 +44,336 @@ #include #include #include +#include +#include +#include //Implementation utilities #include -#include +#include #include #include +#include +#include //boost -#include +#include #include #include #include #include +#include //std C++ -#include //std::equal_to #include //std::pair -#include //std::lower_bound, std::upper_bound #include //std::size_t +#include //std::uint64_t #if defined(BOOST_HAS_PRAGMA_ONCE) # pragma once #endif +#ifdef _MSC_VER +#include +#endif + + namespace boost { namespace intrusive { +#if !defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED) + /// @cond +//We only support LLP64(Win64) or LP64(most Unix) data models +#ifdef _WIN64 //In 64 bit windows sizeof(size_t) == sizeof(unsigned long long) +# define BOOST_INTRUSIVE_SIZE_C(NUMBER) NUMBER##ULL +# define BOOST_INTRUSIVE_64_BIT_SIZE_T 1 +#else //In 32 bit windows and 32/64 bit unixes sizeof(size_t) == sizeof(unsigned long) +# define BOOST_INTRUSIVE_SIZE_C(NUMBER) NUMBER##UL +# define BOOST_INTRUSIVE_64_BIT_SIZE_T (((((ULONG_MAX>>16)>>16)>>16)>>15) != 0) +#endif + +template +struct prime_list_holder +{ + private: + + template // sizeof(SizeType) < sizeof(std::size_t) + static BOOST_INTRUSIVE_FORCEINLINE SizeType truncate_size_type(std::size_t n, detail::true_) + { return n < std::size_t(SizeType(-1)) ? static_cast(n) : SizeType(-1); } + + template // sizeof(SizeType) == sizeof(std::size_t) + static BOOST_INTRUSIVE_FORCEINLINE SizeType truncate_size_type(std::size_t n, detail::false_) + { return static_cast(n); } + + static const std::size_t prime_list[]; + static const std::size_t prime_list_size; + + static const std::size_t *suggested_lower_bucket_count_ptr(std::size_t n) + { + const std::size_t *primes = &prime_list[0]; + const std::size_t *primes_end = primes + prime_list_size; + std::size_t const* bound = + boost::movelib::lower_bound(primes, primes_end, n, value_less()); + bound -= std::size_t(bound == primes_end); + return bound; + } + + static const std::size_t *suggested_upper_bucket_count_ptr(std::size_t n) + { + const std::size_t *primes = &prime_list[0]; + const std::size_t *primes_end = primes + prime_list_size; + std::size_t const* bound = + boost::movelib::upper_bound(primes, primes_end, n, value_less()); + bound -= std::size_t(bound == primes_end); + return bound; + } + + static std::size_t suggested_lower_bucket_count_impl(std::size_t n) + { return *suggested_lower_bucket_count_ptr(n); } + + static std::size_t suggested_upper_bucket_count_impl(std::size_t n) + { return *suggested_upper_bucket_count_ptr(n); } + + public: + + template + static BOOST_INTRUSIVE_FORCEINLINE SizeType suggested_upper_bucket_count(SizeType n) + { + std::size_t const c = suggested_upper_bucket_count_impl(static_cast(n)); + return truncate_size_type(c, detail::bool_<(sizeof(SizeType) < sizeof(std::size_t))>()); + } + + template + static BOOST_INTRUSIVE_FORCEINLINE SizeType suggested_lower_bucket_count(SizeType n) + { + std::size_t const c = suggested_lower_bucket_count_impl(static_cast(n)); + return truncate_size_type(c, detail::bool_<(sizeof(SizeType) < sizeof(std::size_t))>()); + } + + static BOOST_INTRUSIVE_FORCEINLINE std::size_t suggested_lower_bucket_count_idx(std::size_t n) + { return static_cast(suggested_lower_bucket_count_ptr(n) - &prime_list[0]); } + + static BOOST_INTRUSIVE_FORCEINLINE std::size_t suggested_upper_bucket_count_idx(std::size_t n) + { return static_cast(suggested_upper_bucket_count_ptr(n) - &prime_list[0]); } + + static BOOST_INTRUSIVE_FORCEINLINE std::size_t size_from_index(std::size_t n) + { return prime_list[std::ptrdiff_t(n)]; } + + template + BOOST_INTRUSIVE_FORCEINLINE static std::size_t modfunc(std::size_t hash) { return hash % SizeIndex; } + + static std::size_t(*const positions[])(std::size_t); + + #if BOOST_INTRUSIVE_64_BIT_SIZE_T + static const uint64_t inv_sizes32[]; + static const std::size_t inv_sizes32_size; + #endif + + BOOST_INTRUSIVE_FORCEINLINE static std::size_t lower_size_index(std::size_t n) + { return prime_list_holder<>::suggested_lower_bucket_count_idx(n); } + + BOOST_INTRUSIVE_FORCEINLINE static std::size_t upper_size_index(std::size_t n) + { return prime_list_holder<>::suggested_upper_bucket_count_idx(n); } + + BOOST_INTRUSIVE_FORCEINLINE static std::size_t size(std::size_t size_index) + { return prime_list_holder<>::size_from_index(size_index); } + + #if BOOST_INTRUSIVE_64_BIT_SIZE_T + // https://github.com/lemire/fastmod + + BOOST_INTRUSIVE_FORCEINLINE static uint64_t mul128_u32(uint64_t lowbits, uint32_t d) + { + #if defined(_MSC_VER) + return __umulh(lowbits, d); + #elif defined(BOOST_HAS_INT128) + return static_cast((uint128_type(lowbits) * d) >> 64); + #else + uint64_t r1 = (lowbits & UINT32_MAX) * d; + uint64_t r2 = (lowbits >> 32) * d; + r2 += r1 >> 32; + return r2 >> 32; + #endif + } + + BOOST_INTRUSIVE_FORCEINLINE static uint32_t fastmod_u32(uint32_t a, uint64_t M, uint32_t d) + { + uint64_t lowbits = M * a; + return (uint32_t)(mul128_u32(lowbits, d)); + } + #endif // BOOST_INTRUSIVE_64_BIT_SIZE_T + + BOOST_INTRUSIVE_FORCEINLINE static std::size_t position(std::size_t hash,std::size_t size_index) + { + #if BOOST_INTRUSIVE_64_BIT_SIZE_T + BOOST_CONSTEXPR_OR_CONST std::size_t sizes_under_32bit = sizeof(inv_sizes32)/sizeof(inv_sizes32[0]); + if(BOOST_LIKELY(size_index < sizes_under_32bit)){ + return fastmod_u32( uint32_t(hash)+uint32_t(hash>>32) + , inv_sizes32[size_index] + , uint32_t(prime_list[size_index]) ); + } + else{ + return positions[size_index](hash); + } + #else + return positions[size_index](hash); + #endif // BOOST_INTRUSIVE_64_BIT_SIZE_T + } +}; + +template +std::size_t(* const prime_list_holder::positions[])(std::size_t) = +{ + modfunc, modfunc, + modfunc, modfunc, + modfunc, modfunc, + modfunc, modfunc, + modfunc, modfunc, + modfunc, modfunc, + modfunc, modfunc, + modfunc, modfunc, + modfunc, modfunc, + modfunc, modfunc, + modfunc, modfunc, + modfunc, modfunc, + modfunc, modfunc, + modfunc, modfunc, + modfunc, modfunc, + modfunc, //0-30 indexes +#if BOOST_INTRUSIVE_64_BIT_SIZE_T + //Taken from Boost.MultiIndex code, thanks to Joaquin M. Lopez Munoz. + modfunc, //<- 32 bit values stop here (index 31) + modfunc, modfunc, + modfunc, modfunc, + modfunc, modfunc, + modfunc, modfunc, + modfunc, modfunc, + modfunc, modfunc, + modfunc, modfunc, + modfunc, modfunc, + modfunc, modfunc, + modfunc, modfunc, + modfunc, modfunc, + modfunc, modfunc, + modfunc, modfunc, + modfunc, modfunc, + modfunc, modfunc, + modfunc, modfunc //(index 63) +#else + modfunc //<- 32 bit stops here (index 31) as ptrdiff_t is signed +#endif + }; + +template +const std::size_t prime_list_holder::prime_list[] = { + BOOST_INTRUSIVE_SIZE_C(3), BOOST_INTRUSIVE_SIZE_C(7), + BOOST_INTRUSIVE_SIZE_C(11), BOOST_INTRUSIVE_SIZE_C(17), + BOOST_INTRUSIVE_SIZE_C(29), BOOST_INTRUSIVE_SIZE_C(53), + BOOST_INTRUSIVE_SIZE_C(97), BOOST_INTRUSIVE_SIZE_C(193), + BOOST_INTRUSIVE_SIZE_C(389), BOOST_INTRUSIVE_SIZE_C(769), + BOOST_INTRUSIVE_SIZE_C(1543), BOOST_INTRUSIVE_SIZE_C(3079), + BOOST_INTRUSIVE_SIZE_C(6151), BOOST_INTRUSIVE_SIZE_C(12289), + BOOST_INTRUSIVE_SIZE_C(24593), BOOST_INTRUSIVE_SIZE_C(49157), + BOOST_INTRUSIVE_SIZE_C(98317), BOOST_INTRUSIVE_SIZE_C(196613), + BOOST_INTRUSIVE_SIZE_C(393241), BOOST_INTRUSIVE_SIZE_C(786433), + BOOST_INTRUSIVE_SIZE_C(1572869), BOOST_INTRUSIVE_SIZE_C(3145739), + BOOST_INTRUSIVE_SIZE_C(6291469), BOOST_INTRUSIVE_SIZE_C(12582917), + BOOST_INTRUSIVE_SIZE_C(25165843), BOOST_INTRUSIVE_SIZE_C(50331653), + BOOST_INTRUSIVE_SIZE_C(100663319), BOOST_INTRUSIVE_SIZE_C(201326611), + BOOST_INTRUSIVE_SIZE_C(402653189), BOOST_INTRUSIVE_SIZE_C(805306457), + BOOST_INTRUSIVE_SIZE_C(1610612741), //0-30 indexes +#if BOOST_INTRUSIVE_64_BIT_SIZE_T + //Taken from Boost.MultiIndex code, thanks to Joaquin M. Lopez Munoz. + BOOST_INTRUSIVE_SIZE_C(3221225473), //<- 32 bit values stop here (index 31) + BOOST_INTRUSIVE_SIZE_C(6442450939), BOOST_INTRUSIVE_SIZE_C(12884901893), + BOOST_INTRUSIVE_SIZE_C(25769803751), BOOST_INTRUSIVE_SIZE_C(51539607551), + BOOST_INTRUSIVE_SIZE_C(103079215111), BOOST_INTRUSIVE_SIZE_C(206158430209), + BOOST_INTRUSIVE_SIZE_C(412316860441), BOOST_INTRUSIVE_SIZE_C(824633720831), + BOOST_INTRUSIVE_SIZE_C(1649267441651), BOOST_INTRUSIVE_SIZE_C(3298534883309), + BOOST_INTRUSIVE_SIZE_C(6597069766657), BOOST_INTRUSIVE_SIZE_C(13194139533299), + BOOST_INTRUSIVE_SIZE_C(26388279066623), BOOST_INTRUSIVE_SIZE_C(52776558133303), + BOOST_INTRUSIVE_SIZE_C(105553116266489), BOOST_INTRUSIVE_SIZE_C(211106232532969), + BOOST_INTRUSIVE_SIZE_C(422212465066001), BOOST_INTRUSIVE_SIZE_C(844424930131963), + BOOST_INTRUSIVE_SIZE_C(1688849860263953), BOOST_INTRUSIVE_SIZE_C(3377699720527861), + BOOST_INTRUSIVE_SIZE_C(6755399441055731), BOOST_INTRUSIVE_SIZE_C(13510798882111483), + BOOST_INTRUSIVE_SIZE_C(27021597764222939), BOOST_INTRUSIVE_SIZE_C(54043195528445957), + BOOST_INTRUSIVE_SIZE_C(108086391056891903), BOOST_INTRUSIVE_SIZE_C(216172782113783843), + BOOST_INTRUSIVE_SIZE_C(432345564227567621), BOOST_INTRUSIVE_SIZE_C(864691128455135207), + BOOST_INTRUSIVE_SIZE_C(1729382256910270481), BOOST_INTRUSIVE_SIZE_C(3458764513820540933), + BOOST_INTRUSIVE_SIZE_C(6917529027641081903), BOOST_INTRUSIVE_SIZE_C(9223372036854775783) //(index 63) +#else + BOOST_INTRUSIVE_SIZE_C(2147483647) //<- 32 bit stops here (index 31) as ptrdiff_t is signed +#endif +}; + +template +const std::size_t prime_list_holder::prime_list_size + = sizeof(prime_list) / sizeof(std::size_t); + + +#if BOOST_INTRUSIVE_64_BIT_SIZE_T + +template +const uint64_t prime_list_holder::inv_sizes32[] = { + BOOST_INTRUSIVE_SIZE_C(6148914691236517206), //3 + BOOST_INTRUSIVE_SIZE_C(2635249153387078803), //7 + BOOST_INTRUSIVE_SIZE_C(1676976733973595602), //11 + BOOST_INTRUSIVE_SIZE_C(1085102592571150096), //17 + BOOST_INTRUSIVE_SIZE_C(636094623231363849), //29 + BOOST_INTRUSIVE_SIZE_C(348051774975651918), //53 + BOOST_INTRUSIVE_SIZE_C(190172619316593316), //97 + BOOST_INTRUSIVE_SIZE_C(95578984837873325), //193 + BOOST_INTRUSIVE_SIZE_C(47420935922132524), //389 + BOOST_INTRUSIVE_SIZE_C(23987963684927896), //769 + BOOST_INTRUSIVE_SIZE_C(11955116055547344), //1543 + BOOST_INTRUSIVE_SIZE_C(5991147799191151), //3079 + BOOST_INTRUSIVE_SIZE_C(2998982941588287), //6151 + BOOST_INTRUSIVE_SIZE_C(1501077717772769), //12289 + BOOST_INTRUSIVE_SIZE_C(750081082979285), //24593 + BOOST_INTRUSIVE_SIZE_C(375261795343686), //49157 + BOOST_INTRUSIVE_SIZE_C(187625172388393), //98317 + BOOST_INTRUSIVE_SIZE_C(93822606204624), //196613 + BOOST_INTRUSIVE_SIZE_C(46909513691883), //393241 + BOOST_INTRUSIVE_SIZE_C(23456218233098), //786433 + BOOST_INTRUSIVE_SIZE_C(11728086747027), //1572869 + BOOST_INTRUSIVE_SIZE_C(5864041509391), //3145739 + BOOST_INTRUSIVE_SIZE_C(2932024948977), //6291469 + BOOST_INTRUSIVE_SIZE_C(1466014921160), //12582917 + BOOST_INTRUSIVE_SIZE_C(733007198436), //25165843 + BOOST_INTRUSIVE_SIZE_C(366503839517), //50331653 + BOOST_INTRUSIVE_SIZE_C(183251896093), //100663319 + BOOST_INTRUSIVE_SIZE_C(91625960335), //201326611 + BOOST_INTRUSIVE_SIZE_C(45812983922), //402653189 + BOOST_INTRUSIVE_SIZE_C(22906489714), //805306457 + BOOST_INTRUSIVE_SIZE_C(11453246088), //1610612741 + BOOST_INTRUSIVE_SIZE_C(5726623060) //3221225473 +}; + +template +const std::size_t prime_list_holder::inv_sizes32_size + = sizeof(inv_sizes32) / sizeof(uint64_t); + +#endif // BOOST_INTRUSIVE_64_BIT_SIZE_T + +struct prime_fmod_size : prime_list_holder<> +{ +}; + + +#undef BOOST_INTRUSIVE_SIZE_C +#undef BOOST_INTRUSIVE_64_BIT_SIZE_T + +#endif //#if !defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED) + + + template InputIt priv_algo_find(InputIt first, InputIt last, const T& value) { for (; first != last; ++first) { if (*first == value) { - return first; + return first; } } return last; @@ -105,234 +417,173 @@ bool priv_algo_is_permutation(ForwardIterator1 first1, ForwardIterator1 last1, F continue; //We've seen this one before. } distance_type matches = (priv_algo_count)(first2, last2, *scan); - if (0 == matches || (priv_algo_count)(scan, last1, *scan != matches)){ + if (0 == matches || (priv_algo_count)(scan, last1, *scan) != matches){ return false; } } return true; } -template -struct prime_list_holder +struct hash_bool_flags { - private: - - template // sizeof(SizeType) < sizeof(std::size_t) - static BOOST_INTRUSIVE_FORCEINLINE SizeType truncate_size_type(std::size_t n, detail::true_) - { - return n < std::size_t(SizeType(-1)) ? static_cast(n) : SizeType(-1); - } + static const std::size_t unique_keys_pos = 1u; + static const std::size_t constant_time_size_pos = 2u; + static const std::size_t power_2_buckets_pos = 4u; + static const std::size_t cache_begin_pos = 8u; + static const std::size_t compare_hash_pos = 16u; + static const std::size_t incremental_pos = 32u; + static const std::size_t linear_buckets_pos = 64u; + static const std::size_t fastmod_buckets_pos = 128u; +}; - template // sizeof(SizeType) == sizeof(std::size_t) - static BOOST_INTRUSIVE_FORCEINLINE SizeType truncate_size_type(std::size_t n, detail::false_) - { - return static_cast(n); - } +template +class exception_bucket_disposer +{ + Bucket *cont_; + Disposer &disp_; + const SizeType &constructed_; - template //sizeof(SizeType) > sizeof(std::size_t) - static BOOST_INTRUSIVE_FORCEINLINE SizeType suggested_upper_bucket_count_dispatch(SizeType n, detail::true_) - { - std::size_t const c = n > std::size_t(-1) - ? std::size_t(-1) - : suggested_upper_bucket_count_impl(static_cast(n)); - return static_cast(c); - } + exception_bucket_disposer(const exception_bucket_disposer&); + exception_bucket_disposer &operator=(const exception_bucket_disposer&); - template //sizeof(SizeType) > sizeof(std::size_t) - static BOOST_INTRUSIVE_FORCEINLINE SizeType suggested_lower_bucket_count_dispatch(SizeType n, detail::true_) - { - std::size_t const c = n > std::size_t(-1) - ? std::size_t(-1) - : suggested_lower_bucket_count_impl(static_cast(n)); - return static_cast(c); - } + public: - template - static BOOST_INTRUSIVE_FORCEINLINE SizeType suggested_upper_bucket_count_dispatch(SizeType n, detail::false_) - { - std::size_t const c = suggested_upper_bucket_count_impl(static_cast(n)); - return truncate_size_type(c, detail::bool_<(sizeof(SizeType) < sizeof(std::size_t))>()); + exception_bucket_disposer + (Bucket &cont, Disposer &disp, const SizeType &constructed) + : cont_(&cont), disp_(disp), constructed_(constructed) + {} - } + BOOST_INTRUSIVE_FORCEINLINE void release() + { cont_ = 0; } - template - static BOOST_INTRUSIVE_FORCEINLINE SizeType suggested_lower_bucket_count_dispatch(SizeType n, detail::false_) + ~exception_bucket_disposer() { - std::size_t const c = suggested_lower_bucket_count_impl(static_cast(n)); - return truncate_size_type(c, detail::bool_<(sizeof(SizeType) < sizeof(std::size_t))>()); + SizeType n = constructed_; + if(cont_){ + while(n--){ + Algo::detach_and_dispose(cont_[n].get_node_ptr(), disp_); + } + } } +}; - static const std::size_t prime_list[]; - static const std::size_t prime_list_size; +template +struct unordered_bucket_impl +{ + typedef typename detail::get_node_traits + ::type node_traits; + typedef typename reduced_slist_node_traits + ::type reduced_node_traits; + typedef bucket_impl type; - static std::size_t suggested_lower_bucket_count_impl(std::size_t n) - { - const std::size_t *primes = &prime_list_holder<0>::prime_list[0]; - const std::size_t *primes_end = primes + prime_list_holder<0>::prime_list_size; - std::size_t const* bound = std::lower_bound(primes, primes_end, n); - //Tables have upper SIZE_MAX, so we must always found an entry - BOOST_INTRUSIVE_INVARIANT_ASSERT(bound != primes_end); - bound -= std::size_t(bound != primes); - return *bound; - } + typedef typename pointer_traits + + ::template rebind_pointer::type pointer; +}; - static std::size_t suggested_upper_bucket_count_impl(std::size_t n) - { - const std::size_t *primes = &prime_list_holder<0>::prime_list[0]; - const std::size_t *primes_end = primes + prime_list_holder<0>::prime_list_size; - std::size_t const* bound = std::upper_bound(primes, primes_end, n); - bound -= std::size_t(bound == primes_end); - return *bound; - } +template +struct unordered_bucket_ptr_impl +{ + typedef typename unordered_bucket_impl::pointer type; +}; - public: - template - static BOOST_INTRUSIVE_FORCEINLINE SizeType suggested_upper_bucket_count(SizeType n) - { - return (suggested_upper_bucket_count_dispatch)(n, detail::bool_<(sizeof(SizeType) > sizeof(std::size_t))>()); - } +template +struct bucket_traits_impl +{ +private: + BOOST_COPYABLE_AND_MOVABLE(bucket_traits_impl) - template - static BOOST_INTRUSIVE_FORCEINLINE SizeType suggested_lower_bucket_count(SizeType n) - { - return (suggested_lower_bucket_count_dispatch)(n, detail::bool_<(sizeof(SizeType) > sizeof(std::size_t))>()); - } -}; +public: + /// @cond -#if !defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED) + typedef BucketPtr bucket_ptr; + typedef SizeType size_type; -//We only support LLP64(Win64) or LP64(most Unix) data models -#ifdef _WIN64 //In 64 bit windows sizeof(size_t) == sizeof(unsigned long long) - #define BOOST_INTRUSIVE_PRIME_C(NUMBER) NUMBER##ULL - #define BOOST_INTRUSIVE_64_BIT_SIZE_T 1 -#else //In 32 bit windows and 32/64 bit unixes sizeof(size_t) == sizeof(unsigned long) - #define BOOST_INTRUSIVE_PRIME_C(NUMBER) NUMBER##UL - #define BOOST_INTRUSIVE_64_BIT_SIZE_T (((((ULONG_MAX>>16)>>16)>>16)>>15) != 0) -#endif + /// @endcond -template -const std::size_t prime_list_holder::prime_list[] = { - BOOST_INTRUSIVE_PRIME_C(3), BOOST_INTRUSIVE_PRIME_C(7), - BOOST_INTRUSIVE_PRIME_C(11), BOOST_INTRUSIVE_PRIME_C(17), - BOOST_INTRUSIVE_PRIME_C(29), BOOST_INTRUSIVE_PRIME_C(53), - BOOST_INTRUSIVE_PRIME_C(97), BOOST_INTRUSIVE_PRIME_C(193), - BOOST_INTRUSIVE_PRIME_C(389), BOOST_INTRUSIVE_PRIME_C(769), - BOOST_INTRUSIVE_PRIME_C(1543), BOOST_INTRUSIVE_PRIME_C(3079), - BOOST_INTRUSIVE_PRIME_C(6151), BOOST_INTRUSIVE_PRIME_C(12289), - BOOST_INTRUSIVE_PRIME_C(24593), BOOST_INTRUSIVE_PRIME_C(49157), - BOOST_INTRUSIVE_PRIME_C(98317), BOOST_INTRUSIVE_PRIME_C(196613), - BOOST_INTRUSIVE_PRIME_C(393241), BOOST_INTRUSIVE_PRIME_C(786433), - BOOST_INTRUSIVE_PRIME_C(1572869), BOOST_INTRUSIVE_PRIME_C(3145739), - BOOST_INTRUSIVE_PRIME_C(6291469), BOOST_INTRUSIVE_PRIME_C(12582917), - BOOST_INTRUSIVE_PRIME_C(25165843), BOOST_INTRUSIVE_PRIME_C(50331653), - BOOST_INTRUSIVE_PRIME_C(100663319), BOOST_INTRUSIVE_PRIME_C(201326611), - BOOST_INTRUSIVE_PRIME_C(402653189), BOOST_INTRUSIVE_PRIME_C(805306457), - BOOST_INTRUSIVE_PRIME_C(1610612741), BOOST_INTRUSIVE_PRIME_C(3221225473), -#if BOOST_INTRUSIVE_64_BIT_SIZE_T - //Taken from Boost.MultiIndex code, thanks to Joaquin M Lopez Munoz. - BOOST_INTRUSIVE_PRIME_C(6442450939), BOOST_INTRUSIVE_PRIME_C(12884901893), - BOOST_INTRUSIVE_PRIME_C(25769803751), BOOST_INTRUSIVE_PRIME_C(51539607551), - BOOST_INTRUSIVE_PRIME_C(103079215111), BOOST_INTRUSIVE_PRIME_C(206158430209), - BOOST_INTRUSIVE_PRIME_C(412316860441), BOOST_INTRUSIVE_PRIME_C(824633720831), - BOOST_INTRUSIVE_PRIME_C(1649267441651), BOOST_INTRUSIVE_PRIME_C(3298534883309), - BOOST_INTRUSIVE_PRIME_C(6597069766657), BOOST_INTRUSIVE_PRIME_C(13194139533299), - BOOST_INTRUSIVE_PRIME_C(26388279066623), BOOST_INTRUSIVE_PRIME_C(52776558133303), - BOOST_INTRUSIVE_PRIME_C(105553116266489), BOOST_INTRUSIVE_PRIME_C(211106232532969), - BOOST_INTRUSIVE_PRIME_C(422212465066001), BOOST_INTRUSIVE_PRIME_C(844424930131963), - BOOST_INTRUSIVE_PRIME_C(1688849860263953), BOOST_INTRUSIVE_PRIME_C(3377699720527861), - BOOST_INTRUSIVE_PRIME_C(6755399441055731), BOOST_INTRUSIVE_PRIME_C(13510798882111483), - BOOST_INTRUSIVE_PRIME_C(27021597764222939), BOOST_INTRUSIVE_PRIME_C(54043195528445957), - BOOST_INTRUSIVE_PRIME_C(108086391056891903), BOOST_INTRUSIVE_PRIME_C(216172782113783843), - BOOST_INTRUSIVE_PRIME_C(432345564227567621), BOOST_INTRUSIVE_PRIME_C(864691128455135207), - BOOST_INTRUSIVE_PRIME_C(1729382256910270481), BOOST_INTRUSIVE_PRIME_C(3458764513820540933), - BOOST_INTRUSIVE_PRIME_C(6917529027641081903), BOOST_INTRUSIVE_PRIME_C(13835058055282163729), - BOOST_INTRUSIVE_PRIME_C(18446744073709551557), BOOST_INTRUSIVE_PRIME_C(18446744073709551615) //Upper limit, just in case -#else - BOOST_INTRUSIVE_PRIME_C(4294967291), BOOST_INTRUSIVE_PRIME_C(4294967295) //Upper limit, just in case -#endif - }; + BOOST_INTRUSIVE_FORCEINLINE bucket_traits_impl(bucket_ptr buckets, size_type len) + : buckets_(buckets), buckets_len_(len) + {} -#undef BOOST_INTRUSIVE_PRIME_C -#undef BOOST_INTRUSIVE_64_BIT_SIZE_T + BOOST_INTRUSIVE_FORCEINLINE bucket_traits_impl(const bucket_traits_impl& x) + : buckets_(x.buckets_), buckets_len_(x.buckets_len_) + {} -#endif //#if !defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED) + BOOST_INTRUSIVE_FORCEINLINE bucket_traits_impl(BOOST_RV_REF(bucket_traits_impl) x) + : buckets_(x.buckets_), buckets_len_(x.buckets_len_) + { + x.buckets_ = bucket_ptr(); x.buckets_len_ = 0u; + } -template -const std::size_t prime_list_holder::prime_list_size - = sizeof(prime_list)/sizeof(std::size_t); + BOOST_INTRUSIVE_FORCEINLINE bucket_traits_impl& operator=(BOOST_RV_REF(bucket_traits_impl) x) + { + buckets_ = x.buckets_; buckets_len_ = x.buckets_len_; + x.buckets_ = bucket_ptr(); x.buckets_len_ = 0u; return *this; + } -struct hash_bool_flags -{ - static const std::size_t unique_keys_pos = 1u; - static const std::size_t constant_time_size_pos = 2u; - static const std::size_t power_2_buckets_pos = 4u; - static const std::size_t cache_begin_pos = 8u; - static const std::size_t compare_hash_pos = 16u; - static const std::size_t incremental_pos = 32u; -}; + BOOST_INTRUSIVE_FORCEINLINE bucket_traits_impl& operator=(BOOST_COPY_ASSIGN_REF(bucket_traits_impl) x) + { + buckets_ = x.buckets_; buckets_len_ = x.buckets_len_; return *this; + } -namespace detail { + BOOST_INTRUSIVE_FORCEINLINE bucket_ptr bucket_begin() const + { + return buckets_; + } -template -struct get_slist_impl_from_supposed_value_traits -{ - typedef SupposedValueTraits value_traits; - typedef typename detail::get_node_traits - ::type node_traits; - typedef typename get_slist_impl - ::type - >::type type; -}; + BOOST_INTRUSIVE_FORCEINLINE size_type bucket_count() const BOOST_NOEXCEPT + { + return buckets_len_; + } -template -struct unordered_bucket_impl -{ - typedef typename - get_slist_impl_from_supposed_value_traits - ::type slist_impl; - typedef bucket_impl implementation_defined; - typedef implementation_defined type; +private: + bucket_ptr buckets_; + size_type buckets_len_; }; -template -struct unordered_bucket_ptr_impl -{ - typedef typename detail::get_node_traits - ::type::node_ptr node_ptr; - typedef typename unordered_bucket_impl - ::type bucket_type; - - typedef typename pointer_traits - ::template rebind_pointer - < bucket_type >::type implementation_defined; - typedef implementation_defined type; -}; template struct store_hash_is_true { template - struct two_or_three {yes_type _[2 + Add];}; - template static yes_type test(...); + struct two_or_three {detail::yes_type _[2u + (unsigned)Add];}; + template static detail::yes_type test(...); template static two_or_three test (int); - static const bool value = sizeof(test(0)) > sizeof(yes_type)*2; + static const bool value = sizeof(test(0)) > sizeof(detail::yes_type)*2u; }; template struct optimize_multikey_is_true { template - struct two_or_three {yes_type _[2 + Add];}; - template static yes_type test(...); + struct two_or_three { detail::yes_type _[2u + (unsigned)Add];}; + template static detail::yes_type test(...); template static two_or_three test (int); - static const bool value = sizeof(test(0)) > sizeof(yes_type)*2; + static const bool value = sizeof(test(0)) > sizeof(detail::yes_type)*2u; }; +template struct insert_commit_data_impl { std::size_t hash; + std::size_t bucket_idx; + BOOST_INTRUSIVE_FORCEINLINE std::size_t get_hash() const + { return hash; } + + BOOST_INTRUSIVE_FORCEINLINE void set_hash(std::size_t h) + { hash = h; } +}; + +template<> +struct insert_commit_data_impl +{ + std::size_t bucket_idx; + BOOST_INTRUSIVE_FORCEINLINE std::size_t get_hash() const + { return 0U; } + + BOOST_INTRUSIVE_FORCEINLINE void set_hash(std::size_t) + {} }; template @@ -375,21 +626,22 @@ struct group_functions typedef circular_slist_algorithms node_algorithms; static slist_node_ptr get_bucket_before_begin - (slist_node_ptr bucket_beg, slist_node_ptr bucket_end, node_ptr p) + (slist_node_ptr bucket_beg, slist_node_ptr bucket_last, slist_node_ptr sp, detail::true_) { //First find the last node of p's group. //This requires checking the first node of the next group or //the bucket node. + node_ptr p = dcast_bucket_ptr(sp); node_ptr prev_node = p; node_ptr nxt(node_traits::get_next(p)); - while(!(bucket_beg <= nxt && nxt <= bucket_end) && + while(!(bucket_beg <= nxt && nxt <= bucket_last) && (group_traits::get_next(nxt) == prev_node)){ prev_node = nxt; nxt = node_traits::get_next(nxt); } //If we've reached the bucket node just return it. - if(bucket_beg <= nxt && nxt <= bucket_end){ + if(bucket_beg <= nxt && nxt <= bucket_last){ return nxt; } @@ -398,17 +650,28 @@ struct group_functions node_ptr last_node_group = group_traits::get_next(first_node_of_group); slist_node_ptr possible_end = node_traits::get_next(last_node_group); - while(!(bucket_beg <= possible_end && possible_end <= bucket_end)){ - first_node_of_group = detail::dcast_bucket_ptr(possible_end); + while(!(bucket_beg <= possible_end && possible_end <= bucket_last)){ + first_node_of_group = dcast_bucket_ptr(possible_end); last_node_group = group_traits::get_next(first_node_of_group); possible_end = node_traits::get_next(last_node_group); } return possible_end; } + static slist_node_ptr get_bucket_before_begin + (slist_node_ptr bucket_beg, slist_node_ptr bucket_last, slist_node_ptr sp, detail::false_) + { + //The end node is embedded in the singly linked list: + //iterate until we reach it. + while (!(bucket_beg <= sp && sp <= bucket_last)){ + sp = reduced_node_traits::get_next(sp); + } + return sp; + } + static node_ptr get_prev_to_first_in_group(slist_node_ptr bucket_node, node_ptr first_in_group) { - node_ptr nb = detail::dcast_bucket_ptr(bucket_node); + node_ptr nb = dcast_bucket_ptr(bucket_node); node_ptr n; while((n = node_traits::get_next(nb)) != first_in_group){ nb = group_traits::get_next(n); //go to last in group @@ -426,7 +689,7 @@ struct group_functions } } - BOOST_INTRUSIVE_FORCEINLINE static void erase_from_group(const slist_node_ptr&, const node_ptr&, detail::false_) + BOOST_INTRUSIVE_FORCEINLINE static void erase_from_group(slist_node_ptr, node_ptr, detail::false_) {} BOOST_INTRUSIVE_FORCEINLINE static node_ptr get_last_in_group(node_ptr first_in_group, detail::true_) @@ -444,33 +707,35 @@ struct group_functions return n; } - BOOST_INTRUSIVE_FORCEINLINE static node_ptr next_group_if_first_in_group(node_ptr ptr) - { - return node_traits::get_next(group_traits::get_next(ptr)); - } - BOOST_INTRUSIVE_FORCEINLINE static node_ptr get_first_in_group(node_ptr n, detail::false_) { return n; } - BOOST_INTRUSIVE_FORCEINLINE static void insert_in_group(node_ptr first_in_group, node_ptr n, true_) + BOOST_INTRUSIVE_FORCEINLINE static bool is_first_in_group(node_ptr ptr) + { return node_traits::get_next(group_traits::get_next(ptr)) != ptr; } + + + BOOST_INTRUSIVE_FORCEINLINE static void insert_in_group(node_ptr first_in_group, node_ptr n, detail::true_) { group_algorithms::link_after(first_in_group, n); } - static void insert_in_group(const node_ptr&, const node_ptr&, false_) + BOOST_INTRUSIVE_FORCEINLINE static void insert_in_group(node_ptr, node_ptr, detail::false_) {} - BOOST_INTRUSIVE_FORCEINLINE static node_ptr split_group(node_ptr const new_first_in_group) + //Splits a group in two groups, and makes "new_first" the first node in the second group. + //Returns the first element of the first group + static node_ptr split_group(node_ptr const new_first) { - node_ptr const first((get_first_in_group)(new_first_in_group, detail::true_())); - if(first != new_first_in_group){ - node_ptr const last = group_traits::get_next(first); - group_traits::set_next(first, group_traits::get_next(new_first_in_group)); - group_traits::set_next(new_first_in_group, last); + node_ptr const old_first((get_first_in_group)(new_first, detail::true_())); + //Check new_first was not the first in group + if(old_first != new_first){ + node_ptr const last = group_traits::get_next(old_first); + group_traits::set_next(old_first, group_traits::get_next(new_first)); + group_traits::set_next(new_first, last); } - return first; + return old_first; } }; -template +template class incremental_rehash_rollback { private: @@ -483,9 +748,9 @@ class incremental_rehash_rollback public: incremental_rehash_rollback - (bucket_type &source_bucket, bucket_type &destiny_bucket, split_traits &split_traits) + (bucket_type &source_bucket, bucket_type &destiny_bucket, split_traits &split_tr) : source_bucket_(source_bucket), destiny_bucket_(destiny_bucket) - , split_traits_(split_traits), released_(false) + , split_traits_(split_tr), released_(false) {} BOOST_INTRUSIVE_FORCEINLINE void release() @@ -496,7 +761,7 @@ class incremental_rehash_rollback if(!released_){ //If an exception is thrown, just put all moved nodes back in the old bucket //and move back the split mark. - destiny_bucket_.splice_after(destiny_bucket_.before_begin(), source_bucket_); + SlistNodeAlgorithms::transfer_after(destiny_bucket_.get_node_ptr(), source_bucket_.get_node_ptr()); split_traits_.decrement(); } } @@ -511,10 +776,10 @@ class incremental_rehash_rollback template struct node_functions { - BOOST_INTRUSIVE_FORCEINLINE static void store_hash(typename NodeTraits::node_ptr p, std::size_t h, true_) + BOOST_INTRUSIVE_FORCEINLINE static void store_hash(typename NodeTraits::node_ptr p, std::size_t h, detail::true_) { return NodeTraits::set_hash(p, h); } - BOOST_INTRUSIVE_FORCEINLINE static void store_hash(typename NodeTraits::node_ptr, std::size_t, false_) + BOOST_INTRUSIVE_FORCEINLINE static void store_hash(typename NodeTraits::node_ptr, std::size_t, detail::false_) {} }; @@ -524,26 +789,29 @@ BOOST_INTRUSIVE_FORCEINLINE std::size_t hash_to_bucket(std::size_t hash_value, s BOOST_INTRUSIVE_FORCEINLINE std::size_t hash_to_bucket(std::size_t hash_value, std::size_t bucket_cnt, detail::true_) { return hash_value & (bucket_cnt - 1); } -template -BOOST_INTRUSIVE_FORCEINLINE std::size_t hash_to_bucket_split(std::size_t hash_value, std::size_t bucket_cnt, std::size_t split) +template //!fastmod_buckets +BOOST_INTRUSIVE_FORCEINLINE std::size_t hash_to_bucket_split(std::size_t hash_value, std::size_t bucket_cnt, std::size_t split, detail::false_) { - std::size_t bucket_number = detail::hash_to_bucket(hash_value, bucket_cnt, detail::bool_()); - if(Incremental) + std::size_t bucket_number = hash_to_bucket(hash_value, bucket_cnt, detail::bool_()); + BOOST_IF_CONSTEXPR(Incremental) bucket_number -= static_cast(bucket_number >= split)*(bucket_cnt/2); return bucket_number; } -} //namespace detail { +template //fastmod_buckets +BOOST_INTRUSIVE_FORCEINLINE std::size_t hash_to_bucket_split(std::size_t hash_value, std::size_t , std::size_t split, detail::true_) +{ + return prime_fmod_size::position(hash_value, split); +} //!This metafunction will obtain the type of a bucket //!from the value_traits or hook option to be used with //!a hash container. template struct unordered_bucket - : public detail::unordered_bucket_impl - ::proto_value_traits - > + : public unordered_bucket_impl + < typename ValueTraitsOrHookOption:: + template pack::proto_value_traits> {}; //!This metafunction will obtain the type of a bucket pointer @@ -551,10 +819,9 @@ struct unordered_bucket //!a hash container. template struct unordered_bucket_ptr - : public detail::unordered_bucket_ptr_impl - ::proto_value_traits - > + : public unordered_bucket_ptr_impl + < typename ValueTraitsOrHookOption:: + template pack::proto_value_traits> {}; //!This metafunction will obtain the type of the default bucket traits @@ -565,13 +832,12 @@ template struct unordered_default_bucket_traits { typedef typename ValueTraitsOrHookOption:: - template pack::proto_value_traits supposed_value_traits; - typedef typename detail:: - get_slist_impl_from_supposed_value_traits - ::type slist_impl; + template pack::proto_value_traits supposed_value_traits; + typedef bucket_traits_impl - implementation_defined; - typedef implementation_defined type; + < typename unordered_bucket_ptr_impl + ::type + , std::size_t> type; }; struct default_bucket_traits; @@ -597,30 +863,30 @@ struct hashtable_defaults static const bool cache_begin = false; static const bool compare_hash = false; static const bool incremental = false; + static const bool linear_buckets = false; + static const bool fastmod_buckets = false; }; template struct downcast_node_to_value_t : public detail::node_to_value { - typedef detail::node_to_value base_t; - typedef typename base_t::result_type result_type; - typedef ValueTraits value_traits; - typedef typename get_slist_impl - ::type - >::type slist_impl; + typedef detail::node_to_value base_t; + typedef typename base_t::result_type result_type; + typedef ValueTraits value_traits; + typedef typename unordered_bucket_impl + ::type::node_traits::node node; typedef typename detail::add_const_if_c - ::type & first_argument_type; + ::type &first_argument_type; typedef typename detail::add_const_if_c < typename ValueTraits::node_traits::node - , IsConst>::type & intermediate_argument_type; + , IsConst>::type &intermediate_argument_type; typedef typename pointer_traits :: template rebind_pointer ::type const_value_traits_ptr; - BOOST_INTRUSIVE_FORCEINLINE downcast_node_to_value_t(const const_value_traits_ptr &ptr) + BOOST_INTRUSIVE_FORCEINLINE downcast_node_to_value_t(const_value_traits_ptr ptr) : base_t(ptr) {} @@ -655,25 +921,58 @@ struct node_cast_adaptor //bucket_plus_vtraits stores ValueTraits + BucketTraits //this data is needed by iterators to obtain the //value from the iterator and detect the bucket -template +template struct bucket_plus_vtraits { + private: + BOOST_MOVABLE_BUT_NOT_COPYABLE(bucket_plus_vtraits) + + + struct data_type + : public ValueTraits, BucketTraits + { + private: + BOOST_MOVABLE_BUT_NOT_COPYABLE(data_type) + + public: + BOOST_INTRUSIVE_FORCEINLINE data_type(const ValueTraits& val_traits, const BucketTraits& b_traits) + : ValueTraits(val_traits), BucketTraits(b_traits) + {} + + BOOST_INTRUSIVE_FORCEINLINE data_type(BOOST_RV_REF(data_type) other) + : ValueTraits (BOOST_MOVE_BASE(ValueTraits, other)) + , BucketTraits(BOOST_MOVE_BASE(BucketTraits, other)) + {} + } m_data; + + public: typedef BucketTraits bucket_traits; typedef ValueTraits value_traits; static const bool safemode_or_autounlink = is_safe_autounlink::value; - typedef typename - detail::get_slist_impl_from_supposed_value_traits - ::type slist_impl; + typedef typename unordered_bucket_impl + ::type bucket_type; + typedef typename unordered_bucket_ptr_impl + ::type bucket_ptr; typedef typename value_traits::node_traits node_traits; + typedef typename bucket_type::node_traits slist_node_traits; typedef unordered_group_adapter group_traits; - typedef typename slist_impl::iterator siterator; - typedef bucket_impl bucket_type; - typedef detail::group_functions group_functions_t; - typedef typename slist_impl::node_algorithms node_algorithms; - typedef typename slist_impl::node_ptr slist_node_ptr; - typedef typename node_traits::node_ptr node_ptr; + typedef group_functions group_functions_t; + typedef typename detail::if_c + < LinearBuckets + , linear_slist_algorithms + , circular_slist_algorithms + >::type slist_node_algorithms; + + typedef typename slist_node_traits::node_ptr slist_node_ptr; + typedef trivial_value_traits + slist_value_traits; + typedef slist_iterator siterator; + typedef slist_iterator const_siterator; + + typedef typename node_traits::node_ptr node_ptr; + typedef typename node_traits::const_node_ptr const_node_ptr; typedef typename node_traits::node node; typedef typename value_traits::value_type value_type; typedef typename value_traits::pointer pointer; @@ -690,16 +989,18 @@ struct bucket_plus_vtraits :: template rebind_pointer ::type const_bucket_value_traits_ptr; - typedef typename detail::unordered_bucket_ptr_impl - ::type bucket_ptr; + typedef detail::bool_ linear_buckets_t; + typedef bucket_plus_vtraits& this_ref; + + static const std::size_t bucket_overhead = LinearBuckets ? 1u : 0u; - template - BOOST_INTRUSIVE_FORCEINLINE bucket_plus_vtraits(const ValueTraits &val_traits, BOOST_FWD_REF(BucketTraitsType) b_traits) - : data(val_traits, ::boost::forward(b_traits)) + BOOST_INTRUSIVE_FORCEINLINE bucket_plus_vtraits(const ValueTraits &val_traits, const bucket_traits &b_traits) + : m_data(val_traits, b_traits) {} - BOOST_INTRUSIVE_FORCEINLINE bucket_plus_vtraits & operator =(const bucket_plus_vtraits &x) - { data.bucket_traits_ = x.data.bucket_traits_; return *this; } + BOOST_INTRUSIVE_FORCEINLINE bucket_plus_vtraits(BOOST_RV_REF(bucket_plus_vtraits) other) + : m_data(boost::move(((bucket_plus_vtraits&)other).m_data)) + {} BOOST_INTRUSIVE_FORCEINLINE const_value_traits_ptr priv_value_traits_ptr() const { return pointer_traits::pointer_to(this->priv_value_traits()); } @@ -718,47 +1019,129 @@ struct bucket_plus_vtraits //value traits // BOOST_INTRUSIVE_FORCEINLINE const value_traits &priv_value_traits() const - { return this->data; } + { return static_cast(this->m_data); } BOOST_INTRUSIVE_FORCEINLINE value_traits &priv_value_traits() - { return this->data; } + { return static_cast(this->m_data); } - //bucket_traits + //value traits // BOOST_INTRUSIVE_FORCEINLINE const bucket_traits &priv_bucket_traits() const - { return this->data.bucket_traits_; } + { return static_cast(this->m_data); } - BOOST_INTRUSIVE_FORCEINLINE bucket_traits &priv_bucket_traits() - { return this->data.bucket_traits_; } + BOOST_INTRUSIVE_FORCEINLINE bucket_traits& priv_bucket_traits() + { return static_cast(this->m_data); } //bucket operations - BOOST_INTRUSIVE_FORCEINLINE bucket_ptr priv_bucket_pointer() const + BOOST_INTRUSIVE_FORCEINLINE bucket_ptr priv_bucket_pointer() const BOOST_NOEXCEPT { return this->priv_bucket_traits().bucket_begin(); } - std::size_t priv_bucket_count() const - { return this->priv_bucket_traits().bucket_count(); } + BOOST_INTRUSIVE_FORCEINLINE std::size_t priv_usable_bucket_count() const BOOST_NOEXCEPT + { + BOOST_IF_CONSTEXPR(bucket_overhead){ + const std::size_t n = this->priv_bucket_traits().bucket_count(); + return n - std::size_t(n != 0)*bucket_overhead; + } + else{ + return this->priv_bucket_traits().bucket_count(); + } + } - BOOST_INTRUSIVE_FORCEINLINE bucket_ptr priv_invalid_bucket() const + BOOST_INTRUSIVE_FORCEINLINE bucket_type &priv_bucket(std::size_t n) const BOOST_NOEXCEPT { - const bucket_traits &rbt = this->priv_bucket_traits(); - return rbt.bucket_begin() + rbt.bucket_count(); + BOOST_INTRUSIVE_INVARIANT_ASSERT(n < this->priv_usable_bucket_count()); + return this->priv_bucket_pointer()[std::ptrdiff_t(n)]; } - BOOST_INTRUSIVE_FORCEINLINE siterator priv_invalid_local_it() const - { return this->priv_bucket_traits().bucket_begin()->before_begin(); } + BOOST_INTRUSIVE_FORCEINLINE bucket_ptr priv_bucket_ptr(std::size_t n) const BOOST_NOEXCEPT + { return pointer_traits::pointer_to(this->priv_bucket(n)); } + + BOOST_INTRUSIVE_FORCEINLINE bucket_ptr priv_past_usable_bucket_ptr() const + { return this->priv_bucket_pointer() + std::ptrdiff_t(priv_usable_bucket_count()); } + + BOOST_INTRUSIVE_FORCEINLINE bucket_ptr priv_invalid_bucket_ptr() const + { + BOOST_IF_CONSTEXPR(LinearBuckets) { + return bucket_ptr(); + } + else{ + return this->priv_past_usable_bucket_ptr(); + } + } + + BOOST_INTRUSIVE_FORCEINLINE void priv_set_sentinel_bucket() const + { + BOOST_IF_CONSTEXPR(LinearBuckets) { + BOOST_INTRUSIVE_INVARIANT_ASSERT(this->priv_bucket_traits().bucket_count() > 1); + bucket_type &b = this->priv_bucket_pointer()[std::ptrdiff_t(this->priv_usable_bucket_count())]; + slist_node_algorithms::set_sentinel(b.get_node_ptr()); + } + } + + BOOST_INTRUSIVE_FORCEINLINE void priv_unset_sentinel_bucket() const + { + BOOST_IF_CONSTEXPR(LinearBuckets) { + BOOST_INTRUSIVE_INVARIANT_ASSERT(this->priv_bucket_traits().bucket_count() > 1); + bucket_type& b = this->priv_bucket_pointer()[std::ptrdiff_t(this->priv_usable_bucket_count())]; + slist_node_algorithms::init_header(b.get_node_ptr()); + } + } + + BOOST_INTRUSIVE_FORCEINLINE siterator priv_end_sit() const + { return priv_end_sit(linear_buckets_t()); } + + BOOST_INTRUSIVE_FORCEINLINE siterator priv_end_sit(detail::true_) const + { return siterator(this->priv_bucket_pointer() + std::ptrdiff_t(this->priv_bucket_traits().bucket_count() - bucket_overhead)); } + + BOOST_INTRUSIVE_FORCEINLINE siterator priv_end_sit(detail::false_) const + { return siterator(this->priv_bucket_pointer()->get_node_ptr()); } + + BOOST_INTRUSIVE_FORCEINLINE siterator priv_bucket_lbegin(std::size_t n) const + { siterator s(this->priv_bucket_lbbegin(n)); return ++s; } + + BOOST_INTRUSIVE_FORCEINLINE siterator priv_bucket_lbbegin(std::size_t n) const + { return this->sit_bbegin(this->priv_bucket(n)); } + + BOOST_INTRUSIVE_FORCEINLINE siterator priv_bucket_lend(std::size_t n) const + { return this->sit_end(this->priv_bucket(n)); } + + BOOST_INTRUSIVE_FORCEINLINE std::size_t priv_bucket_size(std::size_t n) const + { return slist_node_algorithms::count(this->priv_bucket(n).get_node_ptr())-1u; } + + BOOST_INTRUSIVE_FORCEINLINE bool priv_bucket_empty(std::size_t n) const + { return slist_node_algorithms::is_empty(this->priv_bucket(n).get_node_ptr()); } + + BOOST_INTRUSIVE_FORCEINLINE bool priv_bucket_empty(bucket_ptr p) const + { return slist_node_algorithms::is_empty(p->get_node_ptr()); } + + static BOOST_INTRUSIVE_FORCEINLINE siterator priv_bucket_lbegin(bucket_type &b) + { return siterator(slist_node_traits::get_next(b.get_node_ptr())); } + + static BOOST_INTRUSIVE_FORCEINLINE siterator priv_bucket_lbbegin(bucket_type& b) + { return siterator(b.get_node_ptr()); } + + static BOOST_INTRUSIVE_FORCEINLINE siterator priv_bucket_lend(bucket_type& b) + { return siterator(slist_node_algorithms::end_node(b.get_node_ptr())); } + + static BOOST_INTRUSIVE_FORCEINLINE std::size_t priv_bucket_size(const bucket_type& b) + { return slist_node_algorithms::count(b.get_node_ptr())-1u; } + + static BOOST_INTRUSIVE_FORCEINLINE bool priv_bucket_empty(const bucket_type& b) + { return slist_node_algorithms::is_empty(b.get_node_ptr()); } template - static std::size_t priv_erase_from_single_bucket(bucket_type &b, siterator sbefore_first, siterator slast, NodeDisposer node_disposer, detail::true_) //optimize multikey + static std::size_t priv_erase_from_single_bucket + (bucket_type &b, siterator sbefore_first, siterator slast, NodeDisposer node_disposer, detail::true_) //optimize multikey { std::size_t n = 0; siterator const sfirst(++siterator(sbefore_first)); if(sfirst != slast){ - node_ptr const nf = detail::dcast_bucket_ptr(sfirst.pointed_node()); - node_ptr const nl = detail::dcast_bucket_ptr(slast.pointed_node()); - node_ptr const ne = detail::dcast_bucket_ptr(b.end().pointed_node()); + node_ptr const nf = dcast_bucket_ptr(sfirst.pointed_node()); + node_ptr const nl = dcast_bucket_ptr(slast.pointed_node()); + slist_node_ptr const ne = (priv_bucket_lend(b)).pointed_node(); - if(group_functions_t::next_group_if_first_in_group(nf) != nf) { - // The node is at the beginning of a group. + if(group_functions_t::is_first_in_group(nf)) { + // The first node is at the beginning of a group. if(nl != ne){ group_functions_t::split_group(nl); } @@ -766,52 +1149,42 @@ struct bucket_plus_vtraits else { node_ptr const group1 = group_functions_t::split_group(nf); if(nl != ne) { - node_ptr const group2 = group_functions_t::split_group(ne); + node_ptr const group2 = group_functions_t::split_group(nl); if(nf == group2) { //Both first and last in the same group //so join group1 and group2 node_ptr const end1 = group_traits::get_next(group1); node_ptr const end2 = group_traits::get_next(group2); group_traits::set_next(group1, end2); - group_traits::set_next(group2, end1); + group_traits::set_next(nl, end1); } } } - siterator it(++siterator(sbefore_first)); - while(it != slast){ - node_disposer((it++).pointed_node()); - ++n; - } - b.erase_after(sbefore_first, slast); + n = slist_node_algorithms::unlink_after_and_dispose(sbefore_first.pointed_node(), slast.pointed_node(), node_disposer); } return n; } template - static std::size_t priv_erase_from_single_bucket(bucket_type &b, siterator sbefore_first, siterator slast, NodeDisposer node_disposer, detail::false_) //optimize multikey + static std::size_t priv_erase_from_single_bucket + (bucket_type &, siterator sbefore_first, siterator slast, NodeDisposer node_disposer, detail::false_) //optimize multikey { - std::size_t n = 0; - siterator it(++siterator(sbefore_first)); - while(it != slast){ - node_disposer((it++).pointed_node()); - ++n; - } - b.erase_after(sbefore_first, slast); - return n; + return slist_node_algorithms::unlink_after_and_dispose(sbefore_first.pointed_node(), slast.pointed_node(), node_disposer); } template static void priv_erase_node(bucket_type &b, siterator i, NodeDisposer node_disposer, detail::true_) //optimize multikey { - node_ptr const ne(detail::dcast_bucket_ptr(b.end().pointed_node())); - node_ptr n(detail::dcast_bucket_ptr(i.pointed_node())); + slist_node_ptr const ne(priv_bucket_lend(b).pointed_node()); + slist_node_ptr const nbb(priv_bucket_lbbegin(b).pointed_node()); + node_ptr n(dcast_bucket_ptr(i.pointed_node())); node_ptr pos = node_traits::get_next(group_traits::get_next(n)); node_ptr bn; node_ptr nn(node_traits::get_next(n)); if(pos != n) { //Node is the first of the group - bn = group_functions_t::get_prev_to_first_in_group(ne, n); + bn = group_functions_t::get_prev_to_first_in_group(nbb, n); //Unlink the rest of the group if it's not the last node of its group if(nn != ne && group_traits::get_next(nn) == n){ @@ -829,12 +1202,15 @@ struct bucket_plus_vtraits node_ptr const x(group_algorithms::get_previous_node(n)); group_algorithms::unlink_after(x); } - b.erase_after_and_dispose(bucket_type::s_iterator_to(*bn), node_disposer); + slist_node_algorithms::unlink_after_and_dispose(bn, node_disposer); } template - BOOST_INTRUSIVE_FORCEINLINE static void priv_erase_node(bucket_type &b, siterator i, NodeDisposer node_disposer, detail::false_) //optimize multikey - { b.erase_after_and_dispose(b.previous(i), node_disposer); } + BOOST_INTRUSIVE_FORCEINLINE static void priv_erase_node(bucket_type &b, siterator i, NodeDisposer node_disposer, detail::false_) //!optimize multikey + { + slist_node_ptr bi = slist_node_algorithms::get_previous_node(b.get_node_ptr(), i.pointed_node()); + slist_node_algorithms::unlink_after_and_dispose(bi, node_disposer); + } template std::size_t priv_erase_node_range( siterator const &before_first_it, std::size_t const first_bucket @@ -844,19 +1220,19 @@ struct bucket_plus_vtraits std::size_t num_erased(0); siterator last_step_before_it; if(first_bucket != last_bucket){ - bucket_type *b = (&this->priv_bucket_pointer()[0]); + bucket_type *b = &this->priv_bucket(0); num_erased += this->priv_erase_from_single_bucket - (b[first_bucket], before_first_it, b[first_bucket].end(), node_disposer, optimize_multikey_tag); + (b[first_bucket], before_first_it, this->priv_bucket_lend(first_bucket), node_disposer, optimize_multikey_tag); for(std::size_t i = 0, n = (last_bucket - first_bucket - 1); i != n; ++i){ num_erased += this->priv_erase_whole_bucket(b[first_bucket+i+1], node_disposer); } - last_step_before_it = b[last_bucket].before_begin(); + last_step_before_it = this->priv_bucket_lbbegin(last_bucket); } else{ last_step_before_it = before_first_it; } num_erased += this->priv_erase_from_single_bucket - (this->priv_bucket_pointer()[last_bucket], last_step_before_it, last_it, node_disposer, optimize_multikey_tag); + (this->priv_bucket(last_bucket), last_step_before_it, last_it, node_disposer, optimize_multikey_tag); return num_erased; } @@ -865,88 +1241,74 @@ struct bucket_plus_vtraits //First find the last node of p's group. //This requires checking the first node of the next group or //the bucket node. - slist_node_ptr end_ptr(b.end().pointed_node()); - node_ptr possible_end(node_traits::get_next( detail::dcast_bucket_ptr(end_ptr))); - node_ptr last_node_group(possible_end); + slist_node_ptr end_ptr(sit_end(b).pointed_node()); + slist_node_ptr last_node_group(b.get_node_ptr()); + slist_node_ptr possible_end(slist_node_traits::get_next(last_node_group)); while(end_ptr != possible_end){ - last_node_group = group_traits::get_next(detail::dcast_bucket_ptr(possible_end)); - possible_end = node_traits::get_next(last_node_group); + last_node_group = group_traits::get_next(dcast_bucket_ptr(possible_end)); + possible_end = slist_node_traits::get_next(last_node_group); } - return bucket_type::s_iterator_to(*last_node_group); + return siterator(last_node_group); } - template - std::size_t priv_erase_whole_bucket(bucket_type &b, NodeDisposer node_disposer) - { - std::size_t num_erased = 0; - siterator b_begin(b.before_begin()); - siterator nxt(b_begin); - ++nxt; - siterator const end_sit(b.end()); - while(nxt != end_sit){ - //No need to init group links as we'll delete all bucket nodes - nxt = bucket_type::s_erase_after_and_dispose(b_begin, node_disposer); - ++num_erased; - } - return num_erased; + BOOST_INTRUSIVE_FORCEINLINE static siterator priv_get_last(bucket_type &b, detail::false_) //NOT optimize multikey + { + slist_node_ptr p = b.get_node_ptr(); + return siterator(slist_node_algorithms::get_previous_node(p, slist_node_algorithms::end_node(p))); } - BOOST_INTRUSIVE_FORCEINLINE static siterator priv_get_last(bucket_type &b, detail::false_) //NOT optimize multikey - { return b.previous(b.end()); } + template + static BOOST_INTRUSIVE_FORCEINLINE std::size_t priv_erase_whole_bucket(bucket_type &b, NodeDisposer node_disposer) + { return slist_node_algorithms::detach_and_dispose(b.get_node_ptr(), node_disposer); } static siterator priv_get_previous(bucket_type &b, siterator i, detail::true_) //optimize multikey { - node_ptr const elem(detail::dcast_bucket_ptr(i.pointed_node())); + node_ptr const elem(dcast_bucket_ptr(i.pointed_node())); node_ptr const prev_in_group(group_traits::get_next(elem)); bool const first_in_group = node_traits::get_next(prev_in_group) != elem; - typename bucket_type::node &n = first_in_group - ? *group_functions_t::get_prev_to_first_in_group(b.end().pointed_node(), elem) - : *group_traits::get_next(elem) + slist_node_ptr n = first_in_group + ? group_functions_t::get_prev_to_first_in_group(b.get_node_ptr(), elem) + : group_traits::get_next(elem) ; - return bucket_type::s_iterator_to(n); + return siterator(n); } BOOST_INTRUSIVE_FORCEINLINE static siterator priv_get_previous(bucket_type &b, siterator i, detail::false_) //NOT optimize multikey - { return b.previous(i); } + { return siterator(slist_node_algorithms::get_previous_node(b.get_node_ptr(), i.pointed_node())); } - std::size_t priv_get_bucket_num_no_hash_store(siterator it, detail::true_) //optimize multikey + template + struct typeof_node_disposer { - const bucket_ptr f(this->priv_bucket_pointer()), l(f + this->priv_bucket_count() - 1); - slist_node_ptr bb = group_functions_t::get_bucket_before_begin - ( f->end().pointed_node() - , l->end().pointed_node() - , detail::dcast_bucket_ptr(it.pointed_node())); - //Now get the bucket_impl from the iterator - const bucket_type &b = static_cast - (bucket_type::slist_type::container_from_end_iterator(bucket_type::s_iterator_to(*bb))); - //Now just calculate the index b has in the bucket array - return static_cast(&b - &*f); - } + typedef node_cast_adaptor + < detail::node_disposer< Disposer, value_traits, CommonSListAlgorithms> + , slist_node_ptr, node_ptr > type; + }; - std::size_t priv_get_bucket_num_no_hash_store(siterator it, detail::false_) //NO optimize multikey + template + BOOST_INTRUSIVE_FORCEINLINE typename typeof_node_disposer::type + make_node_disposer(const Disposer &disposer) const { - bucket_ptr f(this->priv_bucket_pointer()), l(f + this->priv_bucket_count() - 1); - slist_node_ptr first_ptr(f->cend().pointed_node()) - , last_ptr(l->cend().pointed_node()); + typedef typename typeof_node_disposer::type return_t; + return return_t(disposer, &this->priv_value_traits()); + } - //The end node is embedded in the singly linked list: - //iterate until we reach it. - while(!(first_ptr <= it.pointed_node() && it.pointed_node() <= last_ptr)){ - ++it; - } - //Now get the bucket_impl from the iterator - const bucket_type &b = static_cast - (bucket_type::container_from_end_iterator(it)); + static BOOST_INTRUSIVE_FORCEINLINE bucket_ptr to_ptr(bucket_type &b) + { return pointer_traits::pointer_to(b); } - //Now just calculate the index b has in the bucket array - return static_cast(&b - &*f); - } + static BOOST_INTRUSIVE_FORCEINLINE siterator sit_bbegin(bucket_type& b) + { return siterator(b.get_node_ptr()); } + + static BOOST_INTRUSIVE_FORCEINLINE siterator sit_begin(bucket_type& b) + { return siterator(b.begin_ptr()); } - BOOST_INTRUSIVE_FORCEINLINE static std::size_t priv_stored_hash(slist_node_ptr n, detail::true_) //store_hash - { return node_traits::get_hash(detail::dcast_bucket_ptr(n)); } + static BOOST_INTRUSIVE_FORCEINLINE siterator sit_end(bucket_type& b) + { return siterator(slist_node_algorithms::end_node(b.get_node_ptr())); } - BOOST_INTRUSIVE_FORCEINLINE static std::size_t priv_stored_hash(slist_node_ptr, detail::false_) //NO store_hash + BOOST_INTRUSIVE_FORCEINLINE static std::size_t priv_stored_hash(siterator s, detail::true_) //store_hash + { return node_traits::get_hash(dcast_bucket_ptr(s.pointed_node())); } + + BOOST_INTRUSIVE_FORCEINLINE static std::size_t priv_stored_hash(siterator, detail::false_) //NO store_hash { return std::size_t(-1); } BOOST_INTRUSIVE_FORCEINLINE node &priv_value_to_node(reference v) @@ -955,21 +1317,36 @@ struct bucket_plus_vtraits BOOST_INTRUSIVE_FORCEINLINE const node &priv_value_to_node(const_reference v) const { return *this->priv_value_traits().to_node_ptr(v); } - BOOST_INTRUSIVE_FORCEINLINE reference priv_value_from_slist_node(slist_node_ptr n) - { return *this->priv_value_traits().to_value_ptr(detail::dcast_bucket_ptr(n)); } + BOOST_INTRUSIVE_FORCEINLINE node_ptr priv_value_to_node_ptr(reference v) + { return this->priv_value_traits().to_node_ptr(v); } + + BOOST_INTRUSIVE_FORCEINLINE const_node_ptr priv_value_to_node_ptr(const_reference v) const + { return this->priv_value_traits().to_node_ptr(v); } - BOOST_INTRUSIVE_FORCEINLINE const_reference priv_value_from_slist_node(slist_node_ptr n) const - { return *this->priv_value_traits().to_value_ptr(detail::dcast_bucket_ptr(n)); } + BOOST_INTRUSIVE_FORCEINLINE reference priv_value_from_siterator(siterator s) + { return *this->priv_value_traits().to_value_ptr(dcast_bucket_ptr(s.pointed_node())); } + + BOOST_INTRUSIVE_FORCEINLINE const_reference priv_value_from_siterator(siterator s) const + { return *this->priv_value_traits().to_value_ptr(dcast_bucket_ptr(s.pointed_node())); } + + static void priv_init_buckets(const bucket_ptr buckets_ptr, const std::size_t bucket_cnt) + { + bucket_ptr buckets_it = buckets_ptr; + for (std::size_t bucket_i = 0; bucket_i != bucket_cnt; ++buckets_it, ++bucket_i) { + slist_node_algorithms::init_header(buckets_it->get_node_ptr()); + } + } void priv_clear_buckets(const bucket_ptr buckets_ptr, const std::size_t bucket_cnt) { bucket_ptr buckets_it = buckets_ptr; for(std::size_t bucket_i = 0; bucket_i != bucket_cnt; ++buckets_it, ++bucket_i){ - if(safemode_or_autounlink){ - buckets_it->clear_and_dispose(detail::init_disposer()); + bucket_type &b = *buckets_it; + BOOST_IF_CONSTEXPR(safemode_or_autounlink){ + slist_node_algorithms::detach_and_dispose(b.get_node_ptr(), this->make_node_disposer(detail::null_disposer())); } else{ - buckets_it->clear(); + slist_node_algorithms::init_header(b.get_node_ptr()); } } } @@ -977,28 +1354,35 @@ struct bucket_plus_vtraits BOOST_INTRUSIVE_FORCEINLINE std::size_t priv_stored_or_compute_hash(const value_type &v, detail::true_) const //For store_hash == true { return node_traits::get_hash(this->priv_value_traits().to_node_ptr(v)); } - typedef hashtable_iterator iterator; - typedef hashtable_iterator const_iterator; + typedef hashtable_iterator iterator; + typedef hashtable_iterator const_iterator; - BOOST_INTRUSIVE_FORCEINLINE iterator end() - { return iterator(this->priv_invalid_local_it(), 0); } + BOOST_INTRUSIVE_FORCEINLINE iterator end() BOOST_NOEXCEPT + { return this->build_iterator(this->priv_end_sit(), bucket_ptr()); } - BOOST_INTRUSIVE_FORCEINLINE const_iterator end() const - { return this->cend(); } + BOOST_INTRUSIVE_FORCEINLINE const_iterator end() const BOOST_NOEXCEPT + { return this->cend(); } - BOOST_INTRUSIVE_FORCEINLINE const_iterator cend() const - { return const_iterator(this->priv_invalid_local_it(), 0); } + BOOST_INTRUSIVE_FORCEINLINE const_iterator cend() const BOOST_NOEXCEPT + { return this->build_const_iterator(this->priv_end_sit(), bucket_ptr()); } - //Public functions: - struct data_type : public ValueTraits - { - template - BOOST_INTRUSIVE_FORCEINLINE data_type(const ValueTraits &val_traits, BOOST_FWD_REF(BucketTraitsType) b_traits) - : ValueTraits(val_traits), bucket_traits_(::boost::forward(b_traits)) - {} + BOOST_INTRUSIVE_FORCEINLINE iterator build_iterator(siterator s, bucket_ptr p) + { return this->build_iterator(s, p, linear_buckets_t()); } + + BOOST_INTRUSIVE_FORCEINLINE iterator build_iterator(siterator s, bucket_ptr p, detail::true_) //linear buckets + { return iterator(s, p, this->priv_value_traits_ptr()); } + + BOOST_INTRUSIVE_FORCEINLINE iterator build_iterator(siterator s, bucket_ptr, detail::false_) //!linear buckets + { return iterator(s, &this->get_bucket_value_traits()); } + + BOOST_INTRUSIVE_FORCEINLINE const_iterator build_const_iterator(siterator s, bucket_ptr p) const + { return this->build_const_iterator(s, p, linear_buckets_t()); } - bucket_traits bucket_traits_; - } data; + BOOST_INTRUSIVE_FORCEINLINE const_iterator build_const_iterator(siterator s, bucket_ptr p, detail::true_) const //linear buckets + { return const_iterator(s, p, this->priv_value_traits_ptr()); } + + BOOST_INTRUSIVE_FORCEINLINE const_iterator build_const_iterator(siterator s, bucket_ptr, detail::false_) const //!linear buckets + { return const_iterator(s, &this->get_bucket_value_traits()); } }; template @@ -1022,7 +1406,7 @@ struct get_equal_to template struct get_equal_to { - typedef std::equal_to type; + typedef value_equal type; }; template @@ -1064,18 +1448,24 @@ struct hash_key_equal //bucket_hash_t //Stores bucket_plus_vtraits plust the hash function -template +template struct bucket_hash_t //Use public inheritance to avoid MSVC bugs with closures : public detail::ebo_functor_holder - ::value_traits::value_type + ::value_traits::value_type , VoidOrKeyOfValue , VoidOrKeyHash >::type > - , bucket_plus_vtraits //4 + , bucket_plus_vtraits //4 { - typedef typename bucket_plus_vtraits::value_traits value_traits; + private: + BOOST_MOVABLE_BUT_NOT_COPYABLE(bucket_hash_t) + + public: + + typedef typename bucket_plus_vtraits + ::value_traits value_traits; typedef typename value_traits::value_type value_type; typedef typename value_traits::node_traits node_traits; typedef hash_key_hash @@ -1084,18 +1474,27 @@ struct bucket_hash_t typedef typename hash_key_types_base::key_of_value key_of_value; typedef BucketTraits bucket_traits; - typedef bucket_plus_vtraits bucket_plus_vtraits_t; + typedef bucket_plus_vtraits bucket_plus_vtraits_t; typedef detail::ebo_functor_holder base_t; - template - BOOST_INTRUSIVE_FORCEINLINE bucket_hash_t(const ValueTraits &val_traits, BOOST_FWD_REF(BucketTraitsType) b_traits, const hasher & h) - : detail::ebo_functor_holder(h), bucket_plus_vtraits_t(val_traits, ::boost::forward(b_traits)) + BOOST_INTRUSIVE_FORCEINLINE bucket_hash_t(const ValueTraits &val_traits, const bucket_traits &b_traits, const hasher & h) + : base_t(h) + , bucket_plus_vtraits_t(val_traits, b_traits) + {} + + BOOST_INTRUSIVE_FORCEINLINE bucket_hash_t(BOOST_RV_REF(bucket_hash_t) other) + : base_t(BOOST_MOVE_BASE(base_t, other)) + , bucket_plus_vtraits_t(BOOST_MOVE_BASE(bucket_plus_vtraits_t, other)) {} + template + BOOST_INTRUSIVE_FORCEINLINE std::size_t priv_hash(const K &k) const + { return this->base_t::operator()(k); } + BOOST_INTRUSIVE_FORCEINLINE const hasher &priv_hasher() const { return this->base_t::get(); } - hasher &priv_hasher() + BOOST_INTRUSIVE_FORCEINLINE hasher &priv_hasher() { return this->base_t::get(); } using bucket_plus_vtraits_t::priv_stored_or_compute_hash; //For store_hash == true @@ -1104,11 +1503,12 @@ struct bucket_hash_t { return this->priv_hasher()(key_of_value()(v)); } }; -template +template struct hashtable_equal_holder { typedef detail::ebo_functor_holder - < typename hash_key_equal < typename bucket_plus_vtraits::value_traits::value_type + < typename hash_key_equal < typename bucket_plus_vtraits + ::value_traits::value_type , VoidOrKeyOfValue , VoidOrKeyEqual >::type @@ -1119,57 +1519,76 @@ struct hashtable_equal_holder //bucket_hash_equal_t //Stores bucket_hash_t and the equality function when the first //non-empty bucket shall not be cached. -template +template struct bucket_hash_equal_t //Use public inheritance to avoid MSVC bugs with closures - : public bucket_hash_t //3 - , public hashtable_equal_holder::type //equal + : public bucket_hash_t //3 + , public hashtable_equal_holder::type //equal { + private: + BOOST_MOVABLE_BUT_NOT_COPYABLE(bucket_hash_equal_t) + + public: typedef typename hashtable_equal_holder - ::type equal_holder_t; - typedef bucket_hash_t bucket_hash_type; - typedef bucket_plus_vtraits bucket_plus_vtraits_t; - typedef ValueTraits value_traits; - typedef typename equal_holder_t::functor_type key_equal; - typedef typename bucket_hash_type::hasher hasher; - typedef BucketTraits bucket_traits; - typedef typename bucket_plus_vtraits_t::slist_impl slist_impl; - typedef typename slist_impl::iterator siterator; - typedef bucket_impl bucket_type; - typedef typename detail::unordered_bucket_ptr_impl::type bucket_ptr; - - template - bucket_hash_equal_t(const ValueTraits &val_traits, BOOST_FWD_REF(BucketTraitsType) b_traits, const hasher & h, const key_equal &e) - : bucket_hash_type(val_traits, ::boost::forward(b_traits), h) + < ValueTraits, BucketTraits, VoidOrKeyOfValue + , VoidOrKeyEqual, LinearBuckets>::type equal_holder_t; + typedef bucket_hash_t< ValueTraits, VoidOrKeyOfValue + , VoidOrKeyHash, BucketTraits + , LinearBuckets> bucket_hash_type; + typedef bucket_plus_vtraits + bucket_plus_vtraits_t; + typedef ValueTraits value_traits; + typedef typename equal_holder_t::functor_type key_equal; + typedef typename bucket_hash_type::hasher hasher; + typedef BucketTraits bucket_traits; + typedef typename bucket_plus_vtraits_t::siterator siterator; + typedef typename bucket_plus_vtraits_t::const_siterator const_siterator; + typedef typename bucket_plus_vtraits_t::bucket_type bucket_type; + typedef typename bucket_plus_vtraits_t::slist_node_algorithms slist_node_algorithms; + typedef typename unordered_bucket_ptr_impl + ::type bucket_ptr; + + bucket_hash_equal_t(const ValueTraits &val_traits, const bucket_traits &b_traits, const hasher & h, const key_equal &e) + : bucket_hash_type(val_traits, b_traits, h) , equal_holder_t(e) {} + BOOST_INTRUSIVE_FORCEINLINE bucket_hash_equal_t(BOOST_RV_REF(bucket_hash_equal_t) other) + : bucket_hash_type(BOOST_MOVE_BASE(bucket_hash_type, other)) + , equal_holder_t(BOOST_MOVE_BASE(equal_holder_t, other)) + {} + BOOST_INTRUSIVE_FORCEINLINE bucket_ptr priv_get_cache() - { return this->bucket_hash_type::priv_bucket_pointer(); } + { return this->priv_bucket_pointer(); } - BOOST_INTRUSIVE_FORCEINLINE void priv_set_cache(const bucket_ptr &) + BOOST_INTRUSIVE_FORCEINLINE void priv_set_cache(bucket_ptr) + {} + + BOOST_INTRUSIVE_FORCEINLINE void priv_set_cache_bucket_num(std::size_t) {} BOOST_INTRUSIVE_FORCEINLINE std::size_t priv_get_cache_bucket_num() { return 0u; } - BOOST_INTRUSIVE_FORCEINLINE void priv_initialize_cache() + BOOST_INTRUSIVE_FORCEINLINE void priv_init_cache() {} BOOST_INTRUSIVE_FORCEINLINE void priv_swap_cache(bucket_hash_equal_t &) {} - siterator priv_begin() const + siterator priv_begin(bucket_ptr &pbucketptr) const { std::size_t n = 0; - std::size_t bucket_cnt = this->bucket_hash_type::priv_bucket_count(); + std::size_t bucket_cnt = this->priv_usable_bucket_count(); for (n = 0; n < bucket_cnt; ++n){ - bucket_type &b = this->bucket_hash_type::priv_bucket_pointer()[n]; - if(!b.empty()){ - return b.begin(); + bucket_type &b = this->priv_bucket(n); + if(!slist_node_algorithms::is_empty(b.get_node_ptr())){ + pbucketptr = this->to_ptr(b); + return siterator(b.begin_ptr()); } } - return this->bucket_hash_type::priv_invalid_local_it(); + pbucketptr = this->priv_invalid_bucket_ptr(); + return this->priv_end_sit(); } BOOST_INTRUSIVE_FORCEINLINE void priv_insertion_update_cache(std::size_t) @@ -1178,6 +1597,9 @@ struct bucket_hash_equal_t BOOST_INTRUSIVE_FORCEINLINE void priv_erasure_update_cache_range(std::size_t, std::size_t) {} + BOOST_INTRUSIVE_FORCEINLINE void priv_erasure_update_cache(bucket_ptr) + {} + BOOST_INTRUSIVE_FORCEINLINE void priv_erasure_update_cache() {} @@ -1191,65 +1613,82 @@ struct bucket_hash_equal_t //bucket_hash_equal_t //Stores bucket_hash_t and the equality function when the first //non-empty bucket shall be cached. -template //cache_begin == true version -struct bucket_hash_equal_t +template //cache_begin == true version +struct bucket_hash_equal_t //Use public inheritance to avoid MSVC bugs with closures - : bucket_hash_t //2 - , hashtable_equal_holder::type + : public bucket_hash_t //2 + , public hashtable_equal_holder::type { + private: + BOOST_MOVABLE_BUT_NOT_COPYABLE(bucket_hash_equal_t) + + public: + typedef typename hashtable_equal_holder - ::type equal_holder_t; + < ValueTraits, BucketTraits + , VoidOrKeyOfValue, VoidOrKeyEqual, LinearBuckets>::type equal_holder_t; - typedef bucket_plus_vtraits bucket_plus_vtraits_t; + typedef bucket_plus_vtraits + < ValueTraits, BucketTraits, LinearBuckets> bucket_plus_vtraits_t; typedef ValueTraits value_traits; typedef typename equal_holder_t::functor_type key_equal; - typedef bucket_hash_t bucket_hash_type; + typedef bucket_hash_t + < ValueTraits, VoidOrKeyOfValue + , VoidOrKeyHash, BucketTraits, LinearBuckets> bucket_hash_type; typedef typename bucket_hash_type::hasher hasher; typedef BucketTraits bucket_traits; - typedef typename bucket_plus_vtraits_t::slist_impl::iterator siterator; + typedef typename bucket_plus_vtraits_t::siterator siterator; + typedef typename bucket_plus_vtraits_t::slist_node_algorithms slist_node_algorithms; - template - bucket_hash_equal_t(const ValueTraits &val_traits, BOOST_FWD_REF(BucketTraitsType) b_traits, const hasher & h, const key_equal &e) - : bucket_hash_type(val_traits, ::boost::forward(b_traits), h) + bucket_hash_equal_t(const ValueTraits &val_traits, const bucket_traits &b_traits, const hasher & h, const key_equal &e) + : bucket_hash_type(val_traits, b_traits, h) , equal_holder_t(e) {} - typedef typename detail::unordered_bucket_ptr_impl - ::type bucket_ptr; + BOOST_INTRUSIVE_FORCEINLINE bucket_hash_equal_t(BOOST_RV_REF(bucket_hash_equal_t) other) + : bucket_hash_type(BOOST_MOVE_BASE(bucket_hash_type, other)) + , equal_holder_t(BOOST_MOVE_BASE(equal_holder_t, other)) + {} - BOOST_INTRUSIVE_FORCEINLINE bucket_ptr &priv_get_cache() - { return cached_begin_; } + typedef typename unordered_bucket_ptr_impl + ::type bucket_ptr; - BOOST_INTRUSIVE_FORCEINLINE const bucket_ptr &priv_get_cache() const + BOOST_INTRUSIVE_FORCEINLINE bucket_ptr priv_get_cache() const { return cached_begin_; } - BOOST_INTRUSIVE_FORCEINLINE void priv_set_cache(const bucket_ptr &p) + BOOST_INTRUSIVE_FORCEINLINE void priv_set_cache(bucket_ptr p) { cached_begin_ = p; } + BOOST_INTRUSIVE_FORCEINLINE void priv_set_cache_bucket_num(std::size_t insertion_bucket) + { + BOOST_INTRUSIVE_INVARIANT_ASSERT(insertion_bucket <= this->priv_usable_bucket_count()); + this->cached_begin_ = this->priv_bucket_pointer() + std::ptrdiff_t(insertion_bucket); + } + BOOST_INTRUSIVE_FORCEINLINE std::size_t priv_get_cache_bucket_num() - { return this->cached_begin_ - this->bucket_hash_type::priv_bucket_pointer(); } + { return std::size_t(this->cached_begin_ - this->priv_bucket_pointer()); } - BOOST_INTRUSIVE_FORCEINLINE void priv_initialize_cache() - { this->cached_begin_ = this->bucket_hash_type::priv_invalid_bucket(); } + BOOST_INTRUSIVE_FORCEINLINE void priv_init_cache() + { this->cached_begin_ = this->priv_past_usable_bucket_ptr(); } - BOOST_INTRUSIVE_FORCEINLINE void priv_swap_cache(bucket_hash_equal_t &other) - { - ::boost::adl_move_swap(this->cached_begin_, other.cached_begin_); - } + BOOST_INTRUSIVE_FORCEINLINE void priv_swap_cache(bucket_hash_equal_t &other) + { ::boost::adl_move_swap(this->cached_begin_, other.cached_begin_); } - siterator priv_begin() const + siterator priv_begin(bucket_ptr& pbucketptr) const { - if(this->cached_begin_ == this->bucket_hash_type::priv_invalid_bucket()){ - return this->bucket_hash_type::priv_invalid_local_it(); + pbucketptr = this->cached_begin_; + if(this->cached_begin_ == this->priv_past_usable_bucket_ptr()){ + return this->priv_end_sit(); } else{ - return this->cached_begin_->begin(); + return siterator(cached_begin_->begin_ptr()); } } void priv_insertion_update_cache(std::size_t insertion_bucket) { - bucket_ptr p = this->bucket_hash_type::priv_bucket_pointer() + insertion_bucket; + BOOST_INTRUSIVE_INVARIANT_ASSERT(insertion_bucket < this->priv_usable_bucket_count()); + bucket_ptr p = this->priv_bucket_pointer() + std::ptrdiff_t(insertion_bucket); if(p < this->cached_begin_){ this->cached_begin_ = p; } @@ -1266,24 +1705,30 @@ struct bucket_hash_equal_tpriv_get_cache_bucket_num() == first_bucket_num && - this->bucket_hash_type::priv_bucket_pointer()[first_bucket_num].empty() ){ - this->priv_set_cache(this->bucket_hash_type::priv_bucket_pointer() + last_bucket_num); + this->priv_bucket_empty(first_bucket_num) ){ + this->priv_set_cache(this->priv_bucket_pointer() + std::ptrdiff_t(last_bucket_num)); + this->priv_erasure_update_cache(); + } + } + + void priv_erasure_update_cache(bucket_ptr first_bucket) + { + //If the last bucket is the end, the cache must be updated + //to the last position if all + if (this->priv_get_cache() == first_bucket && + this->priv_bucket_empty(first_bucket)) { this->priv_erasure_update_cache(); } } void priv_erasure_update_cache() { - if(this->cached_begin_ != this->bucket_hash_type::priv_invalid_bucket()){ - std::size_t current_n = this->priv_get_cache() - this->bucket_hash_type::priv_bucket_pointer(); - for( const std::size_t num_buckets = this->bucket_hash_type::priv_bucket_count() - ; current_n < num_buckets - ; ++current_n, ++this->priv_get_cache()){ - if(!this->priv_get_cache()->empty()){ - return; - } + const bucket_ptr cache_end = this->priv_past_usable_bucket_ptr(); + while( cached_begin_ != cache_end) { + if (!slist_node_algorithms::is_empty(cached_begin_->get_node_ptr())) { + return; } - this->priv_initialize_cache(); + ++cached_begin_; } } @@ -1294,42 +1739,67 @@ struct bucket_hash_equal_t -struct hashtable_size_traits_wrapper +struct hashtable_size_wrapper : public DeriveFrom { + private: + BOOST_MOVABLE_BUT_NOT_COPYABLE(hashtable_size_wrapper) + + public: template - hashtable_size_traits_wrapper( BOOST_FWD_REF(Base) base, BOOST_FWD_REF(Arg0) arg0 - , BOOST_FWD_REF(Arg1) arg1, BOOST_FWD_REF(Arg2) arg2) - : DeriveFrom(::boost::forward(base) - , ::boost::forward(arg0) - , ::boost::forward(arg1) - , ::boost::forward(arg2)) + hashtable_size_wrapper( BOOST_FWD_REF(Base) base, BOOST_FWD_REF(Arg0) arg0 + , BOOST_FWD_REF(Arg1) arg1, BOOST_FWD_REF(Arg2) arg2) + : DeriveFrom( ::boost::forward(base) + , ::boost::forward(arg0) + , ::boost::forward(arg1) + , ::boost::forward(arg2)) {} typedef detail::size_holder < true, SizeType> size_traits;//size_traits + BOOST_INTRUSIVE_FORCEINLINE hashtable_size_wrapper(BOOST_RV_REF(hashtable_size_wrapper) other) + : DeriveFrom(BOOST_MOVE_BASE(DeriveFrom, other)) + {} + size_traits size_traits_; typedef const size_traits & size_traits_const_t; typedef size_traits & size_traits_t; - BOOST_INTRUSIVE_FORCEINLINE size_traits_const_t priv_size_traits() const - { return size_traits_; } + BOOST_INTRUSIVE_FORCEINLINE SizeType get_hashtable_size_wrapper_size() const + { return size_traits_.get_size(); } + + BOOST_INTRUSIVE_FORCEINLINE void set_hashtable_size_wrapper_size(SizeType s) + { size_traits_.set_size(s); } + + BOOST_INTRUSIVE_FORCEINLINE void inc_hashtable_size_wrapper_size() + { size_traits_.increment(); } + + BOOST_INTRUSIVE_FORCEINLINE void dec_hashtable_size_wrapper_size() + { size_traits_.decrement(); } BOOST_INTRUSIVE_FORCEINLINE size_traits_t priv_size_traits() { return size_traits_; } }; template -struct hashtable_size_traits_wrapper +struct hashtable_size_wrapper : public DeriveFrom { + private: + BOOST_MOVABLE_BUT_NOT_COPYABLE(hashtable_size_wrapper) + + public: template - hashtable_size_traits_wrapper( BOOST_FWD_REF(Base) base, BOOST_FWD_REF(Arg0) arg0 - , BOOST_FWD_REF(Arg1) arg1, BOOST_FWD_REF(Arg2) arg2) - : DeriveFrom(::boost::forward(base) - , ::boost::forward(arg0) - , ::boost::forward(arg1) - , ::boost::forward(arg2)) + hashtable_size_wrapper( BOOST_FWD_REF(Base) base, BOOST_FWD_REF(Arg0) arg0 + , BOOST_FWD_REF(Arg1) arg1, BOOST_FWD_REF(Arg2) arg2) + : DeriveFrom( ::boost::forward(base) + , ::boost::forward(arg0) + , ::boost::forward(arg1) + , ::boost::forward(arg2)) + {} + + BOOST_INTRUSIVE_FORCEINLINE hashtable_size_wrapper(BOOST_RV_REF(hashtable_size_wrapper) other) + : DeriveFrom(BOOST_MOVE_BASE(DeriveFrom, other)) {} typedef detail::size_holder< false, SizeType> size_traits; @@ -1337,38 +1807,61 @@ struct hashtable_size_traits_wrapper typedef size_traits size_traits_const_t; typedef size_traits size_traits_t; - BOOST_INTRUSIVE_FORCEINLINE size_traits priv_size_traits() const + BOOST_INTRUSIVE_FORCEINLINE SizeType get_hashtable_size_wrapper_size() const + { return 0u; } + + BOOST_INTRUSIVE_FORCEINLINE void set_hashtable_size_wrapper_size(SizeType) + {} + + BOOST_INTRUSIVE_FORCEINLINE void inc_hashtable_size_wrapper_size() + {} + + BOOST_INTRUSIVE_FORCEINLINE void dec_hashtable_size_wrapper_size() + {} + + BOOST_INTRUSIVE_FORCEINLINE size_traits priv_size_traits() { return size_traits(); } }; -//hashdata_internal -//Stores bucket_hash_equal_t and split_traits -template -struct hashdata_internal - : public hashtable_size_traits_wrapper - < bucket_hash_equal_t - < ValueTraits, VoidOrKeyOfValue, VoidOrKeyHash, VoidOrKeyEqual - , BucketTraits - , 0 != (BoolFlags & hash_bool_flags::cache_begin_pos) - > //2 - , SizeType - , (BoolFlags & hash_bool_flags::incremental_pos) != 0 - > +template< class ValueTraits, class VoidOrKeyOfValue, class VoidOrKeyHash + , class VoidOrKeyEqual, class BucketTraits, class SizeType + , std::size_t BoolFlags> +struct get_hashtable_size_wrapper_bucket { - typedef hashtable_size_traits_wrapper + typedef hashtable_size_wrapper < bucket_hash_equal_t < ValueTraits, VoidOrKeyOfValue, VoidOrKeyHash, VoidOrKeyEqual , BucketTraits + , 0 != (BoolFlags & hash_bool_flags::linear_buckets_pos) , 0 != (BoolFlags & hash_bool_flags::cache_begin_pos) > //2 , SizeType - , (BoolFlags & hash_bool_flags::incremental_pos) != 0 - > internal_type; - typedef typename internal_type::key_equal key_equal; - typedef typename internal_type::hasher hasher; - typedef bucket_plus_vtraits bucket_plus_vtraits_t; + , (BoolFlags & hash_bool_flags::incremental_pos) != 0 || + (BoolFlags & hash_bool_flags::fastmod_buckets_pos) != 0 + > type; +}; + +//hashdata_internal +//Stores bucket_hash_equal_t and split_traits +template +struct hashdata_internal + : public get_hashtable_size_wrapper_bucket + ::type +{ + private: + BOOST_MOVABLE_BUT_NOT_COPYABLE(hashdata_internal) + + public: + static const bool linear_buckets = 0 != (BoolFlags & hash_bool_flags::linear_buckets_pos); + typedef typename get_hashtable_size_wrapper_bucket + ::type split_bucket_hash_equal_t; + + typedef typename split_bucket_hash_equal_t::key_equal key_equal; + typedef typename split_bucket_hash_equal_t::hasher hasher; + typedef bucket_plus_vtraits + bucket_plus_vtraits_t; typedef SizeType size_type; - typedef typename internal_type::size_traits split_traits; + typedef typename split_bucket_hash_equal_t::size_traits split_traits; typedef typename bucket_plus_vtraits_t::bucket_ptr bucket_ptr; typedef typename bucket_plus_vtraits_t::const_value_traits_ptr const_value_traits_ptr; typedef typename bucket_plus_vtraits_t::siterator siterator; @@ -1383,15 +1876,10 @@ struct hashdata_internal ::reference const_reference; typedef typename value_traits::node_traits node_traits; typedef typename node_traits::node node; - typedef typename node_traits::node_ptr node_ptr; - typedef typename node_traits::const_node_ptr const_node_ptr; - typedef detail::node_functions node_functions_t; - typedef typename get_slist_impl - ::type - >::type slist_impl; - typedef typename slist_impl::node_algorithms node_algorithms; - typedef typename slist_impl::node_ptr slist_node_ptr; + typedef typename node_traits::node_ptr node_ptr; + typedef typename node_traits::const_node_ptr const_node_ptr; + typedef typename bucket_plus_vtraits_t::slist_node_algorithms slist_node_algorithms; + typedef typename bucket_plus_vtraits_t::slist_node_ptr slist_node_ptr; typedef hash_key_types_base < typename ValueTraits::value_type @@ -1399,187 +1887,278 @@ struct hashdata_internal > hash_types_base; typedef typename hash_types_base::key_of_value key_of_value; - static const bool store_hash = detail::store_hash_is_true::value; + static const bool store_hash = store_hash_is_true::value; static const bool safemode_or_autounlink = is_safe_autounlink::value; static const bool stateful_value_traits = detail::is_stateful_value_traits::value; typedef detail::bool_ store_hash_t; typedef detail::transform_iterator - < typename slist_impl::iterator - , downcast_node_to_value_t - < value_traits - , false> > local_iterator; + < siterator + , downcast_node_to_value_t > local_iterator; typedef detail::transform_iterator - < typename slist_impl::iterator - , downcast_node_to_value_t - < value_traits - , true> > const_local_iterator; - // + < siterator + , downcast_node_to_value_t > const_local_iterator; - template - hashdata_internal( const ValueTraits &val_traits, BOOST_FWD_REF(BucketTraitsType) b_traits + typedef detail::bool_ linear_buckets_t; + + hashdata_internal( const ValueTraits &val_traits, const bucket_traits &b_traits , const hasher & h, const key_equal &e) - : internal_type(val_traits, ::boost::forward(b_traits), h, e) + : split_bucket_hash_equal_t(val_traits, b_traits, h, e) {} - BOOST_INTRUSIVE_FORCEINLINE typename internal_type::size_traits_t priv_split_traits() - { return this->priv_size_traits(); } + BOOST_INTRUSIVE_FORCEINLINE hashdata_internal(BOOST_RV_REF(hashdata_internal) other) + : split_bucket_hash_equal_t(BOOST_MOVE_BASE(split_bucket_hash_equal_t, other)) + {} - BOOST_INTRUSIVE_FORCEINLINE typename internal_type::size_traits_const_t priv_split_traits() const + BOOST_INTRUSIVE_FORCEINLINE typename split_bucket_hash_equal_t::size_traits_t priv_split_traits() { return this->priv_size_traits(); } ~hashdata_internal() { this->priv_clear_buckets(); } + using split_bucket_hash_equal_t::priv_clear_buckets; + void priv_clear_buckets() { - this->internal_type::priv_clear_buckets - ( this->priv_get_cache() - , this->internal_type::priv_bucket_count() - - (this->priv_get_cache() - - this->internal_type::priv_bucket_pointer())); + const std::size_t cache_num = this->priv_get_cache_bucket_num(); + this->priv_clear_buckets(this->priv_get_cache(), this->priv_usable_bucket_count() - cache_num); } void priv_clear_buckets_and_cache() { this->priv_clear_buckets(); - this->priv_initialize_cache(); + this->priv_init_cache(); } - void priv_initialize_buckets_and_cache() + void priv_init_buckets_and_cache() { - this->internal_type::priv_clear_buckets - ( this->internal_type::priv_bucket_pointer() - , this->internal_type::priv_bucket_count()); - this->priv_initialize_cache(); + this->priv_init_buckets(this->priv_bucket_pointer(), this->priv_usable_bucket_count()); + this->priv_init_cache(); } + + typedef typename bucket_plus_vtraits_t::iterator iterator; + typedef typename bucket_plus_vtraits_t::const_iterator const_iterator; - typedef hashtable_iterator iterator; - typedef hashtable_iterator const_iterator; - - static std::size_t priv_stored_hash(slist_node_ptr n, detail::true_ true_value) - { return bucket_plus_vtraits::priv_stored_hash(n, true_value); } + //public functions + BOOST_INTRUSIVE_FORCEINLINE SizeType split_count() const BOOST_NOEXCEPT + { return this->split_bucket_hash_equal_t::get_hashtable_size_wrapper_size(); } - static std::size_t priv_stored_hash(slist_node_ptr n, detail::false_ false_value) - { return bucket_plus_vtraits::priv_stored_hash(n, false_value); } + BOOST_INTRUSIVE_FORCEINLINE void split_count(SizeType s) BOOST_NOEXCEPT + { this->split_bucket_hash_equal_t::set_hashtable_size_wrapper_size(s); } //public functions - BOOST_INTRUSIVE_FORCEINLINE SizeType split_count() const + BOOST_INTRUSIVE_FORCEINLINE void inc_split_count() BOOST_NOEXCEPT + { this->split_bucket_hash_equal_t::inc_hashtable_size_wrapper_size(); } + + BOOST_INTRUSIVE_FORCEINLINE void dec_split_count() BOOST_NOEXCEPT + { this->split_bucket_hash_equal_t::dec_hashtable_size_wrapper_size(); } + + BOOST_INTRUSIVE_FORCEINLINE static SizeType initial_split_from_bucket_count(SizeType bc) BOOST_NOEXCEPT + { + BOOST_IF_CONSTEXPR(fastmod_buckets) { + size_type split; + split = static_cast(prime_fmod_size::lower_size_index(bc)); + //The passed bucket size must be exactly the supported one + BOOST_ASSERT(prime_fmod_size::size(split) == bc); + return split; + } + else { + BOOST_IF_CONSTEXPR(incremental) { + BOOST_ASSERT(0 == (std::size_t(bc) & (std::size_t(bc) - 1u))); + return size_type(bc >> 1u); + } + else{ + return bc; + } + } + } + + BOOST_INTRUSIVE_FORCEINLINE static SizeType rehash_split_from_bucket_count(SizeType bc) BOOST_NOEXCEPT { - return this->priv_split_traits().get_size(); + BOOST_IF_CONSTEXPR(fastmod_buckets) { + return (initial_split_from_bucket_count)(bc); + } + else { + BOOST_IF_CONSTEXPR(incremental) { + BOOST_ASSERT(0 == (std::size_t(bc) & (std::size_t(bc) - 1u))); + return bc; + } + else{ + return bc; + } + } } - BOOST_INTRUSIVE_FORCEINLINE iterator iterator_to(reference value) + BOOST_INTRUSIVE_FORCEINLINE iterator iterator_to(reference value) BOOST_NOEXCEPT_IF(!linear_buckets) + { return iterator_to(value, linear_buckets_t()); } + + const_iterator iterator_to(const_reference value) const BOOST_NOEXCEPT_IF(!linear_buckets) + { return iterator_to(value, linear_buckets_t()); } + + iterator iterator_to(reference value, detail::true_) //linear_buckets { - return iterator(bucket_type::s_iterator_to - (this->priv_value_to_node(value)), &this->get_bucket_value_traits()); + const std::size_t h = this->priv_stored_or_compute_hash(value, store_hash_t()); + siterator sit(this->priv_value_to_node_ptr(value)); + return this->build_iterator(sit, this->priv_hash_to_bucket_ptr(h)); } - const_iterator iterator_to(const_reference value) const + const_iterator iterator_to(const_reference value, detail::true_) const //linear_buckets { - siterator const sit = bucket_type::s_iterator_to - ( *pointer_traits::const_cast_from - (pointer_traits::pointer_to(this->priv_value_to_node(value))) + const std::size_t h = this->priv_stored_or_compute_hash(value, store_hash_t()); + siterator const sit = siterator + ( pointer_traits::const_cast_from(this->priv_value_to_node_ptr(value)) ); + return this->build_const_iterator(sit, this->priv_hash_to_bucket_ptr(h)); + } + + static const bool incremental = 0 != (BoolFlags & hash_bool_flags::incremental_pos); + static const bool power_2_buckets = incremental || (0 != (BoolFlags & hash_bool_flags::power_2_buckets_pos)); + static const bool fastmod_buckets = 0 != (BoolFlags & hash_bool_flags::fastmod_buckets_pos); + + typedef detail::bool_ fastmod_buckets_t; + + BOOST_INTRUSIVE_FORCEINLINE bucket_type &priv_hash_to_bucket(std::size_t hash_value) const + { return this->priv_bucket(this->priv_hash_to_nbucket(hash_value)); } + + BOOST_INTRUSIVE_FORCEINLINE bucket_ptr priv_hash_to_bucket_ptr(std::size_t hash_value) const + { return this->priv_bucket_ptr(this->priv_hash_to_nbucket(hash_value)); } + + BOOST_INTRUSIVE_FORCEINLINE size_type priv_hash_to_nbucket(std::size_t hash_value) const + { return (priv_hash_to_nbucket)(hash_value, fastmod_buckets_t()); } + + BOOST_INTRUSIVE_FORCEINLINE size_type priv_hash_to_nbucket(std::size_t hash_value, detail::true_) const //fastmod_buckets_t + { return static_cast(prime_fmod_size::position(hash_value, this->split_count())); } + + BOOST_INTRUSIVE_FORCEINLINE size_type priv_hash_to_nbucket(std::size_t hash_value, detail::false_) const //!fastmod_buckets_t + { + return static_cast(hash_to_bucket_split + (hash_value, this->priv_usable_bucket_count(), this->split_count(), detail::false_())); + } + + BOOST_INTRUSIVE_FORCEINLINE iterator iterator_to(reference value, detail::false_) BOOST_NOEXCEPT + { + return iterator( siterator(this->priv_value_to_node_ptr(value)) + , &this->get_bucket_value_traits()); + } + + const_iterator iterator_to(const_reference value, detail::false_) const BOOST_NOEXCEPT + { + siterator const sit = siterator + ( pointer_traits::const_cast_from(this->priv_value_to_node_ptr(value)) ); return const_iterator(sit, &this->get_bucket_value_traits()); } - static local_iterator s_local_iterator_to(reference value) + + static local_iterator s_local_iterator_to(reference value) BOOST_NOEXCEPT { BOOST_STATIC_ASSERT((!stateful_value_traits)); - siterator sit = bucket_type::s_iterator_to(*value_traits::to_node_ptr(value)); + siterator sit(value_traits::to_node_ptr(value)); return local_iterator(sit, const_value_traits_ptr()); } - static const_local_iterator s_local_iterator_to(const_reference value) + static const_local_iterator s_local_iterator_to(const_reference value) BOOST_NOEXCEPT { BOOST_STATIC_ASSERT((!stateful_value_traits)); - siterator const sit = bucket_type::s_iterator_to - ( *pointer_traits::const_cast_from + siterator const sit = siterator + ( pointer_traits::const_cast_from (value_traits::to_node_ptr(value)) ); return const_local_iterator(sit, const_value_traits_ptr()); } - local_iterator local_iterator_to(reference value) + local_iterator local_iterator_to(reference value) BOOST_NOEXCEPT { - siterator sit = bucket_type::s_iterator_to(this->priv_value_to_node(value)); + siterator sit(this->priv_value_to_node_ptr(value)); return local_iterator(sit, this->priv_value_traits_ptr()); } - const_local_iterator local_iterator_to(const_reference value) const + const_local_iterator local_iterator_to(const_reference value) const BOOST_NOEXCEPT { - siterator sit = bucket_type::s_iterator_to - ( *pointer_traits::const_cast_from - (pointer_traits::pointer_to(this->priv_value_to_node(value))) - ); + siterator sit + ( pointer_traits::const_cast_from(this->priv_value_to_node_ptr(value)) ); return const_local_iterator(sit, this->priv_value_traits_ptr()); } - BOOST_INTRUSIVE_FORCEINLINE size_type bucket_count() const - { - const std::size_t bc = this->priv_bucket_count(); - BOOST_INTRUSIVE_INVARIANT_ASSERT(sizeof(size_type) >= sizeof(std::size_t) || bc <= size_type(-1)); - return static_cast(bc); - } + BOOST_INTRUSIVE_FORCEINLINE size_type bucket_count() const BOOST_NOEXCEPT + { return size_type(this->priv_usable_bucket_count()); } - BOOST_INTRUSIVE_FORCEINLINE size_type bucket_size(size_type n) const - { return this->priv_bucket_pointer()[n].size(); } + BOOST_INTRUSIVE_FORCEINLINE size_type bucket_size(size_type n) const BOOST_NOEXCEPT + { return (size_type)this->priv_bucket_size(n); } - BOOST_INTRUSIVE_FORCEINLINE bucket_ptr bucket_pointer() const + BOOST_INTRUSIVE_FORCEINLINE bucket_ptr bucket_pointer() const BOOST_NOEXCEPT { return this->priv_bucket_pointer(); } - BOOST_INTRUSIVE_FORCEINLINE local_iterator begin(size_type n) - { return local_iterator(this->priv_bucket_pointer()[n].begin(), this->priv_value_traits_ptr()); } + BOOST_INTRUSIVE_FORCEINLINE local_iterator begin(size_type n) BOOST_NOEXCEPT + { return local_iterator(this->priv_bucket_lbegin(n), this->priv_value_traits_ptr()); } - BOOST_INTRUSIVE_FORCEINLINE const_local_iterator begin(size_type n) const + BOOST_INTRUSIVE_FORCEINLINE const_local_iterator begin(size_type n) const BOOST_NOEXCEPT { return this->cbegin(n); } - static BOOST_INTRUSIVE_FORCEINLINE size_type suggested_upper_bucket_count(size_type n) + static BOOST_INTRUSIVE_FORCEINLINE size_type suggested_upper_bucket_count(size_type n) BOOST_NOEXCEPT { - return prime_list_holder<0>::suggested_upper_bucket_count(n); + BOOST_IF_CONSTEXPR(fastmod_buckets){ + std::size_t s = prime_fmod_size::upper_size_index(n); + return static_cast(prime_fmod_size::size(s)); + } + else{ + return prime_list_holder<0>::suggested_upper_bucket_count(n); + } } - static BOOST_INTRUSIVE_FORCEINLINE size_type suggested_lower_bucket_count(size_type n) + static BOOST_INTRUSIVE_FORCEINLINE size_type suggested_lower_bucket_count(size_type n) BOOST_NOEXCEPT { - return prime_list_holder<0>::suggested_lower_bucket_count(n); + BOOST_IF_CONSTEXPR(fastmod_buckets){ + std::size_t s = prime_fmod_size::lower_size_index(n); + return static_cast(prime_fmod_size::size(s)); + } + else{ + return prime_list_holder<0>::suggested_lower_bucket_count(n); + } } - const_local_iterator cbegin(size_type n) const + const_local_iterator cbegin(size_type n) const BOOST_NOEXCEPT { return const_local_iterator - ( pointer_traits::const_cast_from(this->priv_bucket_pointer())[n].begin() + (this->priv_bucket_lbegin(n) , this->priv_value_traits_ptr()); } - using internal_type::end; - using internal_type::cend; + using split_bucket_hash_equal_t::end; + using split_bucket_hash_equal_t::cend; - local_iterator end(size_type n) - { return local_iterator(this->priv_bucket_pointer()[n].end(), this->priv_value_traits_ptr()); } + local_iterator end(size_type n) BOOST_NOEXCEPT + { return local_iterator(this->priv_bucket_lend(n), this->priv_value_traits_ptr()); } - BOOST_INTRUSIVE_FORCEINLINE const_local_iterator end(size_type n) const + BOOST_INTRUSIVE_FORCEINLINE const_local_iterator end(size_type n) const BOOST_NOEXCEPT { return this->cend(n); } - const_local_iterator cend(size_type n) const + const_local_iterator cend(size_type n) const BOOST_NOEXCEPT { return const_local_iterator - ( pointer_traits::const_cast_from(this->priv_bucket_pointer())[n].end() + ( this->priv_bucket_lend(n) , this->priv_value_traits_ptr()); } //Public functions for hashtable_impl - BOOST_INTRUSIVE_FORCEINLINE iterator begin() - { return iterator(this->priv_begin(), &this->get_bucket_value_traits()); } + BOOST_INTRUSIVE_FORCEINLINE iterator begin() BOOST_NOEXCEPT + { + bucket_ptr p; + siterator s = this->priv_begin(p); + return this->build_iterator(s, p); + } - BOOST_INTRUSIVE_FORCEINLINE const_iterator begin() const + BOOST_INTRUSIVE_FORCEINLINE const_iterator begin() const BOOST_NOEXCEPT { return this->cbegin(); } - BOOST_INTRUSIVE_FORCEINLINE const_iterator cbegin() const - { return const_iterator(this->priv_begin(), &this->get_bucket_value_traits()); } + BOOST_INTRUSIVE_FORCEINLINE const_iterator cbegin() const BOOST_NOEXCEPT + { + bucket_ptr p; + siterator s = this->priv_begin(p); + return this->build_const_iterator(s, p); + } BOOST_INTRUSIVE_FORCEINLINE hasher hash_function() const { return this->priv_hasher(); } @@ -1588,6 +2167,23 @@ struct hashdata_internal { return this->priv_equal(); } }; +template< class ValueTraits, class VoidOrKeyOfValue, class VoidOrKeyHash + , class VoidOrKeyEqual, class BucketTraits, class SizeType + , std::size_t BoolFlags> +struct get_hashtable_size_wrapper_internal +{ + typedef hashtable_size_wrapper + < hashdata_internal + < ValueTraits + , VoidOrKeyOfValue, VoidOrKeyHash, VoidOrKeyEqual + , BucketTraits, SizeType + , BoolFlags & ~(hash_bool_flags::constant_time_size_pos) //1 + > + , SizeType + , (BoolFlags& hash_bool_flags::constant_time_size_pos) != 0 + > type; +}; + /// @endcond //! The class template hashtable is an intrusive hash table container, that @@ -1632,27 +2228,13 @@ template template #endif class hashtable_impl - : private hashtable_size_traits_wrapper - < hashdata_internal - < ValueTraits - , VoidOrKeyOfValue, VoidOrKeyHash, VoidOrKeyEqual - , BucketTraits, SizeType - , BoolFlags & (hash_bool_flags::incremental_pos | hash_bool_flags::cache_begin_pos) //1 - > - , SizeType - , (BoolFlags & hash_bool_flags::constant_time_size_pos) != 0 - > + : private get_hashtable_size_wrapper_internal + ::type { - typedef hashtable_size_traits_wrapper - < hashdata_internal - < ValueTraits - , VoidOrKeyOfValue, VoidOrKeyHash, VoidOrKeyEqual - , BucketTraits, SizeType - , BoolFlags & (hash_bool_flags::incremental_pos | hash_bool_flags::cache_begin_pos) //1 - > - , SizeType - , (BoolFlags & hash_bool_flags::constant_time_size_pos) != 0 - > internal_type; + static const bool linear_buckets_flag = (BoolFlags & hash_bool_flags::linear_buckets_pos) != 0; + typedef typename get_hashtable_size_wrapper_internal + ::type + internal_type; typedef typename internal_type::size_traits size_traits; typedef hash_key_types_base < typename ValueTraits::value_type @@ -1664,10 +2246,14 @@ class hashtable_impl /// @cond typedef BucketTraits bucket_traits; - typedef typename internal_type::slist_impl slist_impl; - typedef bucket_plus_vtraits bucket_plus_vtraits_t; + typedef bucket_plus_vtraits + bucket_plus_vtraits_t; typedef typename bucket_plus_vtraits_t::const_value_traits_ptr const_value_traits_ptr; + typedef detail::bool_ linear_buckets_t; + + typedef typename internal_type::siterator siterator; + typedef typename internal_type::const_siterator const_siterator; using internal_type::begin; using internal_type::cbegin; using internal_type::end; @@ -1697,10 +2283,8 @@ class hashtable_impl typedef SizeType size_type; typedef typename internal_type::key_equal key_equal; typedef typename internal_type::hasher hasher; - typedef bucket_impl bucket_type; + typedef typename internal_type::bucket_type bucket_type; typedef typename internal_type::bucket_ptr bucket_ptr; - typedef typename slist_impl::iterator siterator; - typedef typename slist_impl::const_iterator const_siterator; typedef typename internal_type::iterator iterator; typedef typename internal_type::const_iterator const_iterator; typedef typename internal_type::local_iterator local_iterator; @@ -1717,7 +2301,7 @@ class hashtable_impl ::reference node_reference; typedef typename pointer_traits ::reference const_node_reference; - typedef typename slist_impl::node_algorithms node_algorithms; + typedef typename internal_type::slist_node_algorithms slist_node_algorithms; static const bool stateful_value_traits = internal_type::stateful_value_traits; static const bool store_hash = internal_type::store_hash; @@ -1728,9 +2312,10 @@ class hashtable_impl static const bool compare_hash = 0 != (BoolFlags & hash_bool_flags::compare_hash_pos); static const bool incremental = 0 != (BoolFlags & hash_bool_flags::incremental_pos); static const bool power_2_buckets = incremental || (0 != (BoolFlags & hash_bool_flags::power_2_buckets_pos)); - - static const bool optimize_multikey - = detail::optimize_multikey_is_true::value && !unique_keys; + static const bool optimize_multikey = optimize_multikey_is_true::value && !unique_keys; + static const bool linear_buckets = linear_buckets_flag; + static const bool fastmod_buckets = 0 != (BoolFlags & hash_bool_flags::fastmod_buckets_pos); + static const std::size_t bucket_overhead = internal_type::bucket_overhead; /// @cond static const bool is_multikey = !unique_keys; @@ -1740,7 +2325,11 @@ class hashtable_impl //See documentation for more explanations BOOST_STATIC_ASSERT((!compare_hash || store_hash)); - typedef typename slist_impl::node_ptr slist_node_ptr; + //Configuration error: fasmod_buckets<> can't be specified with incremental<> or power_2_buckets<> + //See documentation for more explanations + BOOST_STATIC_ASSERT(!(fastmod_buckets && power_2_buckets)); + + typedef typename internal_type::slist_node_ptr slist_node_ptr; typedef typename pointer_traits ::template rebind_pointer < void >::type void_pointer; @@ -1752,9 +2341,11 @@ class hashtable_impl typedef detail::bool_ optimize_multikey_t; typedef detail::bool_ cache_begin_t; typedef detail::bool_ power_2_buckets_t; + typedef detail::bool_ fastmod_buckets_t; + typedef detail::bool_ compare_hash_t; typedef typename internal_type::split_traits split_traits; - typedef detail::group_functions group_functions_t; - typedef detail::node_functions node_functions_t; + typedef group_functions group_functions_t; + typedef node_functions node_functions_t; private: //noncopyable, movable @@ -1767,27 +2358,37 @@ class hashtable_impl //Cache begin is incompatible with auto-unlink hooks! BOOST_STATIC_ASSERT(!(cache_begin && ((int)value_traits::link_mode == (int)auto_unlink))); - template - struct typeof_node_disposer - { - typedef node_cast_adaptor - < detail::node_disposer< Disposer, value_traits, CircularSListAlgorithms> - , slist_node_ptr, node_ptr > type; - }; - template - typename typeof_node_disposer::type - make_node_disposer(const Disposer &disposer) const + /// @endcond + + public: + typedef insert_commit_data_impl insert_commit_data; + + private: + void default_init_actions() { - typedef typename typeof_node_disposer::type return_t; - return return_t(disposer, &this->priv_value_traits()); + this->priv_set_sentinel_bucket(); + this->priv_init_buckets_and_cache(); + this->priv_size_count(size_type(0)); + size_type bucket_sz = this->bucket_count(); + BOOST_INTRUSIVE_INVARIANT_ASSERT(bucket_sz != 0); + //Check power of two bucket array if the option is activated + BOOST_INTRUSIVE_INVARIANT_ASSERT + (!power_2_buckets || (0 == (bucket_sz & (bucket_sz - 1)))); + this->split_count(this->initial_split_from_bucket_count(bucket_sz)); } - /// @endcond + BOOST_INTRUSIVE_FORCEINLINE SizeType priv_size_count() const BOOST_NOEXCEPT + { return this->internal_type::get_hashtable_size_wrapper_size(); } - public: - typedef detail::insert_commit_data_impl insert_commit_data; + BOOST_INTRUSIVE_FORCEINLINE void priv_size_count(SizeType s) BOOST_NOEXCEPT + { this->internal_type::set_hashtable_size_wrapper_size(s); } + + BOOST_INTRUSIVE_FORCEINLINE void priv_size_inc() BOOST_NOEXCEPT + { this->internal_type::inc_hashtable_size_wrapper_size(); } + BOOST_INTRUSIVE_FORCEINLINE void priv_size_dec() BOOST_NOEXCEPT + { this->internal_type::dec_hashtable_size_wrapper_size(); } public: @@ -1809,16 +2410,7 @@ class hashtable_impl , const key_equal &equal_func = key_equal() , const value_traits &v_traits = value_traits()) : internal_type(v_traits, b_traits, hash_func, equal_func) - { - this->priv_initialize_buckets_and_cache(); - this->priv_size_traits().set_size(size_type(0)); - size_type bucket_sz = this->bucket_count(); - BOOST_INTRUSIVE_INVARIANT_ASSERT(bucket_sz != 0); - //Check power of two bucket array if the option is activated - BOOST_INTRUSIVE_INVARIANT_ASSERT - (!power_2_buckets || (0 == (bucket_sz & (bucket_sz-1)))); - this->priv_split_traits().set_size(bucket_sz>>1); - } + { this->default_init_actions(); } //! Requires: buckets must not be being used by any other resource //! and dereferencing iterator must yield an lvalue of type value_type. @@ -1843,14 +2435,8 @@ class hashtable_impl , const value_traits &v_traits = value_traits()) : internal_type(v_traits, b_traits, hash_func, equal_func) { - this->priv_initialize_buckets_and_cache(); - this->priv_size_traits().set_size(size_type(0)); - size_type bucket_sz = this->bucket_count(); - BOOST_INTRUSIVE_INVARIANT_ASSERT(bucket_sz != 0); - //Check power of two bucket array if the option is activated - BOOST_INTRUSIVE_INVARIANT_ASSERT - (!power_2_buckets || (0 == (bucket_sz & (bucket_sz-1)))); - this->priv_split_traits().set_size(bucket_sz>>1); + this->default_init_actions(); + //Now insert if(unique) this->insert_unique(b, e); @@ -1868,18 +2454,14 @@ class hashtable_impl //! move constructor throws (this does not happen with predefined Boost.Intrusive hooks) //! or the move constructor of value traits, bucket traits, hasher or comparison throws. hashtable_impl(BOOST_RV_REF(hashtable_impl) x) - : internal_type( ::boost::move(x.priv_value_traits()) - , ::boost::move(x.priv_bucket_traits()) - , ::boost::move(x.priv_hasher()) - , ::boost::move(x.priv_equal()) - ) + : internal_type(BOOST_MOVE_BASE(internal_type, x)) { this->priv_swap_cache(x); - x.priv_initialize_cache(); - this->priv_size_traits().set_size(x.priv_size_traits().get_size()); - x.priv_size_traits().set_size(size_type(0)); - this->priv_split_traits().set_size(x.priv_split_traits().get_size()); - x.priv_split_traits().set_size(size_type(0)); + x.priv_init_cache(); + this->priv_size_count(x.priv_size_count()); + x.priv_size_count(size_type(0)); + this->split_count(x.split_count()); + x.split_count(size_type(0)); } //! Effects: Equivalent to swap. @@ -1887,7 +2469,6 @@ class hashtable_impl hashtable_impl& operator=(BOOST_RV_REF(hashtable_impl) x) { this->swap(x); return *this; } - #if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED) //! Effects: Detaches all elements from this. The objects in the unordered_set //! are not deleted (i.e. no destructors are called). //! @@ -1895,15 +2476,17 @@ class hashtable_impl //! it's a safe-mode or auto-unlink value. Otherwise constant. //! //! Throws: Nothing. - ~hashtable_impl(); + ~hashtable_impl() + {} + #if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED) //! Effects: Returns an iterator pointing to the beginning of the unordered_set. //! //! Complexity: Amortized constant time. //! Worst case (empty unordered_set): O(this->bucket_count()) //! //! Throws: Nothing. - iterator begin(); + iterator begin() BOOST_NOEXCEPT; //! Effects: Returns a const_iterator pointing to the beginning //! of the unordered_set. @@ -1912,7 +2495,7 @@ class hashtable_impl //! Worst case (empty unordered_set): O(this->bucket_count()) //! //! Throws: Nothing. - const_iterator begin() const; + const_iterator begin() const BOOST_NOEXCEPT; //! Effects: Returns a const_iterator pointing to the beginning //! of the unordered_set. @@ -1921,28 +2504,28 @@ class hashtable_impl //! Worst case (empty unordered_set): O(this->bucket_count()) //! //! Throws: Nothing. - const_iterator cbegin() const; + const_iterator cbegin() const BOOST_NOEXCEPT; //! Effects: Returns an iterator pointing to the end of the unordered_set. //! //! Complexity: Constant. //! //! Throws: Nothing. - iterator end(); + iterator end() BOOST_NOEXCEPT; //! Effects: Returns a const_iterator pointing to the end of the unordered_set. //! //! Complexity: Constant. //! //! Throws: Nothing. - const_iterator end() const; + const_iterator end() const BOOST_NOEXCEPT; //! Effects: Returns a const_iterator pointing to the end of the unordered_set. //! //! Complexity: Constant. //! //! Throws: Nothing. - const_iterator cend() const; + const_iterator cend() const BOOST_NOEXCEPT; //! Effects: Returns the hasher object used by the unordered_set. //! @@ -1967,9 +2550,9 @@ class hashtable_impl //! Otherwise constant. //! //! Throws: Nothing. - bool empty() const + bool empty() const BOOST_NOEXCEPT { - if(constant_time_size){ + BOOST_IF_CONSTEXPR(constant_time_size){ return !this->size(); } else if(cache_begin){ @@ -1979,7 +2562,7 @@ class hashtable_impl size_type bucket_cnt = this->bucket_count(); const bucket_type *b = boost::movelib::to_raw_pointer(this->priv_bucket_pointer()); for (size_type n = 0; n < bucket_cnt; ++n, ++b){ - if(!b->empty()){ + if(!slist_node_algorithms::is_empty(b->get_node_ptr())){ return false; } } @@ -1993,18 +2576,19 @@ class hashtable_impl //! constant_time_size is false. Constant-time otherwise. //! //! Throws: Nothing. - size_type size() const + size_type size() const BOOST_NOEXCEPT { - if(constant_time_size) - return this->priv_size_traits().get_size(); + BOOST_IF_CONSTEXPR(constant_time_size) + return this->priv_size_count(); else{ - size_type len = 0; - size_type bucket_cnt = this->bucket_count(); + std::size_t len = 0; + std::size_t bucket_cnt = this->bucket_count(); const bucket_type *b = boost::movelib::to_raw_pointer(this->priv_bucket_pointer()); - for (size_type n = 0; n < bucket_cnt; ++n, ++b){ - len += b->size(); + for (std::size_t n = 0; n < bucket_cnt; ++n, ++b){ + len += slist_node_algorithms::count(b->get_node_ptr()) - 1u; } - return len; + BOOST_INTRUSIVE_INVARIANT_ASSERT((len <= SizeType(-1))); + return size_type(len); } } @@ -2096,7 +2680,7 @@ class hashtable_impl siterator prev; siterator const it = this->priv_find (key_of_value()(value), this->priv_hasher(), this->priv_equal(), bucket_num, hash_value, prev); - bool const next_is_in_group = optimize_multikey && it != this->priv_invalid_local_it(); + bool const next_is_in_group = optimize_multikey && it != this->priv_end_sit(); return this->priv_insert_equal_after_find(value, bucket_num, hash_value, prev, next_is_in_group); } @@ -2206,12 +2790,15 @@ class hashtable_impl , KeyEqual equal_func , insert_commit_data &commit_data) { - size_type bucket_num; - siterator prev; - siterator const pos = this->priv_find(key, hash_func, equal_func, bucket_num, commit_data.hash, prev); - return std::pair - ( iterator(pos, &this->get_bucket_value_traits()) - , pos == this->priv_invalid_local_it()); + const std::size_t h = hash_func(key); + const std::size_t bn = this->priv_hash_to_nbucket(h); + + commit_data.bucket_idx = bn; + commit_data.set_hash(h); + + bucket_ptr bp = this->priv_bucket_ptr(bn); + siterator const s = this->priv_find_in_bucket(*bp, key, equal_func, h); + return std::pair(this->build_iterator(s, bp), s == this->priv_end_sit()); } //! Effects: Checks if a value can be inserted in the unordered_set, using @@ -2264,17 +2851,17 @@ class hashtable_impl //! erased between the "insert_check" and "insert_commit" calls. //! //! After a successful rehashing insert_commit_data remains valid. - iterator insert_unique_commit(reference value, const insert_commit_data &commit_data) - { - size_type bucket_num = this->priv_hash_to_bucket(commit_data.hash); - bucket_type &b = this->priv_bucket_pointer()[bucket_num]; - this->priv_size_traits().increment(); - node_ptr const n = pointer_traits::pointer_to(this->priv_value_to_node(value)); - BOOST_INTRUSIVE_SAFE_HOOK_DEFAULT_ASSERT(!safemode_or_autounlink || node_algorithms::unique(n)); - node_functions_t::store_hash(n, commit_data.hash, store_hash_t()); - this->priv_insertion_update_cache(bucket_num); + iterator insert_unique_commit(reference value, const insert_commit_data &commit_data) BOOST_NOEXCEPT + { + this->priv_size_inc(); + node_ptr const n = this->priv_value_to_node_ptr(value); + BOOST_INTRUSIVE_SAFE_HOOK_DEFAULT_ASSERT(!safemode_or_autounlink || slist_node_algorithms::unique(n)); + node_functions_t::store_hash(n, commit_data.get_hash(), store_hash_t()); + this->priv_insertion_update_cache(static_cast(commit_data.bucket_idx)); group_functions_t::insert_in_group(n, n, optimize_multikey_t()); - return iterator(b.insert_after(b.before_begin(), *n), &this->get_bucket_value_traits()); + bucket_type& b = this->priv_bucket(commit_data.bucket_idx); + slist_node_algorithms::link_after(b.get_node_ptr(), n); + return this->build_iterator(siterator(n), this->to_ptr(b)); } //! Effects: Erases the element pointed to by i. @@ -2285,7 +2872,7 @@ class hashtable_impl //! //! Note: Invalidates the iterators (but not the references) //! to the erased element. No destructors are called. - BOOST_INTRUSIVE_FORCEINLINE void erase(const_iterator i) + BOOST_INTRUSIVE_FORCEINLINE void erase(const_iterator i) BOOST_NOEXCEPT { this->erase_and_dispose(i, detail::null_disposer()); } //! Effects: Erases the range pointed to by b end e. @@ -2297,7 +2884,7 @@ class hashtable_impl //! //! Note: Invalidates the iterators (but not the references) //! to the erased elements. No destructors are called. - BOOST_INTRUSIVE_FORCEINLINE void erase(const_iterator b, const_iterator e) + BOOST_INTRUSIVE_FORCEINLINE void erase(const_iterator b, const_iterator e) BOOST_NOEXCEPT { this->erase_and_dispose(b, e, detail::null_disposer()); } //! Effects: Erases all the elements with the given value. @@ -2353,14 +2940,13 @@ class hashtable_impl template BOOST_INTRUSIVE_DOC1ST(void , typename detail::disable_if_convertible::type) - erase_and_dispose(const_iterator i, Disposer disposer) + erase_and_dispose(const_iterator i, Disposer disposer) BOOST_NOEXCEPT { //Get the bucket number and local iterator for both iterators - siterator const first_local_it(i.slist_it()); - size_type const first_bucket_num = this->priv_get_bucket_num(first_local_it); - this->priv_erase_node(this->priv_bucket_pointer()[first_bucket_num], first_local_it, make_node_disposer(disposer), optimize_multikey_t()); - this->priv_size_traits().decrement(); - this->priv_erasure_update_cache_range(first_bucket_num, first_bucket_num); + const bucket_ptr bp = this->priv_get_bucket_ptr(i); + this->priv_erase_node(*bp, i.slist_it(), this->make_node_disposer(disposer), optimize_multikey_t()); + this->priv_size_dec(); + this->priv_erasure_update_cache(bp); } //! Requires: Disposer::operator()(pointer) shouldn't throw. @@ -2376,33 +2962,31 @@ class hashtable_impl //! Note: Invalidates the iterators //! to the erased elements. template - void erase_and_dispose(const_iterator b, const_iterator e, Disposer disposer) + void erase_and_dispose(const_iterator b, const_iterator e, Disposer disposer) BOOST_NOEXCEPT { if(b != e){ //Get the bucket number and local iterator for both iterators - siterator first_local_it(b.slist_it()); - size_type first_bucket_num = this->priv_get_bucket_num(first_local_it); + size_type first_bucket_num = this->priv_get_bucket_num(b); - const bucket_ptr buck_ptr = this->priv_bucket_pointer(); siterator before_first_local_it - = this->priv_get_previous(buck_ptr[first_bucket_num], first_local_it); + = this->priv_get_previous(this->priv_bucket(first_bucket_num), b.slist_it(), optimize_multikey_t()); size_type last_bucket_num; siterator last_local_it; //For the end iterator, we will assign the end iterator //of the last bucket if(e == this->end()){ - last_bucket_num = this->bucket_count() - 1; - last_local_it = buck_ptr[last_bucket_num].end(); + last_bucket_num = size_type(this->bucket_count() - 1u); + last_local_it = this->sit_end(this->priv_bucket(last_bucket_num)); } else{ last_local_it = e.slist_it(); - last_bucket_num = this->priv_get_bucket_num(last_local_it); + last_bucket_num = this->priv_get_bucket_num(e); } - size_type const num_erased = this->priv_erase_node_range + size_type const num_erased = (size_type)this->priv_erase_node_range ( before_first_local_it, first_bucket_num, last_local_it, last_bucket_num - , make_node_disposer(disposer), optimize_multikey_t()); - this->priv_size_traits().set_size(this->priv_size_traits().get_size()-num_erased); + , this->make_node_disposer(disposer), optimize_multikey_t()); + this->priv_size_count(size_type(this->priv_size_count()-num_erased)); this->priv_erasure_update_cache_range(first_bucket_num, last_bucket_num); } } @@ -2449,30 +3033,34 @@ class hashtable_impl std::size_t h; siterator prev; siterator it = this->priv_find(key, hash_func, equal_func, bucket_num, h, prev); - bool const success = it != this->priv_invalid_local_it(); + bool const success = it != this->priv_end_sit(); - size_type cnt(0); + std::size_t cnt(0); if(success){ if(optimize_multikey){ + siterator past_last_in_group = it; + (priv_go_to_last_in_group)(past_last_in_group, optimize_multikey_t()); + ++past_last_in_group; cnt = this->priv_erase_from_single_bucket - (this->priv_bucket_pointer()[bucket_num], prev, ++(priv_last_in_group)(it), make_node_disposer(disposer), optimize_multikey_t()); + ( this->priv_bucket(bucket_num), prev + , past_last_in_group + , this->make_node_disposer(disposer), optimize_multikey_t()); } else{ - bucket_type &b = this->priv_bucket_pointer()[bucket_num]; - siterator const end_sit = b.end(); + siterator const end_sit = this->priv_bucket_lend(bucket_num); do{ ++cnt; ++it; }while(it != end_sit && - this->priv_is_value_equal_to_key - (this->priv_value_from_slist_node(it.pointed_node()), h, key, equal_func)); - bucket_type::s_erase_after_and_dispose(prev, it, make_node_disposer(disposer)); + this->priv_is_value_equal_to_key + (this->priv_value_from_siterator(it), h, key, equal_func, compare_hash_t())); + slist_node_algorithms::unlink_after_and_dispose(prev.pointed_node(), it.pointed_node(), this->make_node_disposer(disposer)); } - this->priv_size_traits().set_size(this->priv_size_traits().get_size()-cnt); + this->priv_size_count(size_type(this->priv_size_count()-cnt)); this->priv_erasure_update_cache(); } - return cnt; + return static_cast(cnt); } //! Effects: Erases all of the elements. @@ -2484,10 +3072,10 @@ class hashtable_impl //! //! Note: Invalidates the iterators (but not the references) //! to the erased elements. No destructors are called. - void clear() + void clear() BOOST_NOEXCEPT { this->priv_clear_buckets_and_cache(); - this->priv_size_traits().set_size(size_type(0)); + this->priv_size_count(size_type(0)); } //! Requires: Disposer::operator()(pointer) shouldn't throw. @@ -2502,18 +3090,19 @@ class hashtable_impl //! Note: Invalidates the iterators (but not the references) //! to the erased elements. No destructors are called. template - void clear_and_dispose(Disposer disposer) + void clear_and_dispose(Disposer disposer) BOOST_NOEXCEPT { if(!constant_time_size || !this->empty()){ size_type num_buckets = this->bucket_count(); bucket_ptr b = this->priv_bucket_pointer(); - typename typeof_node_disposer::type d(disposer, &this->priv_value_traits()); - for(; num_buckets--; ++b){ - b->clear_and_dispose(d); + typename internal_type::template typeof_node_disposer::type d(disposer, &this->priv_value_traits()); + for(; num_buckets; ++b){ + --num_buckets; + slist_node_algorithms::detach_and_dispose(b->get_node_ptr(), d); } - this->priv_size_traits().set_size(size_type(0)); + this->priv_size_count(size_type(0)); } - this->priv_initialize_cache(); + this->priv_init_cache(); } //! Effects: Returns the number of contained elements with the given value @@ -2577,11 +3166,10 @@ class hashtable_impl template iterator find(const KeyType &key, KeyHasher hash_func, KeyEqual equal_func) { - size_type bucket_n; - std::size_t hash; - siterator prev; - return iterator( this->priv_find(key, hash_func, equal_func, bucket_n, hash, prev) - , &this->get_bucket_value_traits()); + std::size_t h = hash_func(key); + bucket_ptr bp = this->priv_hash_to_bucket_ptr(h); + siterator s = this->priv_find_in_bucket(*bp, key, equal_func, h); + return this->build_iterator(s, bp); } //! Effects: Finds a const_iterator to the first element whose key is @@ -2616,11 +3204,10 @@ class hashtable_impl const_iterator find (const KeyType &key, KeyHasher hash_func, KeyEqual equal_func) const { - size_type bucket_n; - std::size_t hash_value; - siterator prev; - return const_iterator( this->priv_find(key, hash_func, equal_func, bucket_n, hash_value, prev) - , &this->get_bucket_value_traits()); + std::size_t h = hash_func(key); + bucket_ptr bp = this->priv_hash_to_bucket_ptr(h); + siterator s = this->priv_find_in_bucket(*bp, key, equal_func, h); + return this->build_const_iterator(s, bp); } //! Effects: Returns a range containing all elements with values equivalent @@ -2657,11 +3244,11 @@ class hashtable_impl std::pair equal_range (const KeyType &key, KeyHasher hash_func, KeyEqual equal_func) { - std::pair ret = + priv_equal_range_result ret = this->priv_equal_range(key, hash_func, equal_func); return std::pair - ( iterator(ret.first, &this->get_bucket_value_traits()) - , iterator(ret.second, &this->get_bucket_value_traits())); + ( this->build_iterator(ret.first, ret.bucket_first) + , this->build_iterator(ret.second, ret.bucket_second)); } //! Effects: Returns a range containing all elements with values equivalent @@ -2699,11 +3286,11 @@ class hashtable_impl std::pair equal_range (const KeyType &key, KeyHasher hash_func, KeyEqual equal_func) const { - std::pair ret = + priv_equal_range_result ret = this->priv_equal_range(key, hash_func, equal_func); return std::pair - ( const_iterator(ret.first, &this->get_bucket_value_traits()) - , const_iterator(ret.second, &this->get_bucket_value_traits())); + ( this->build_const_iterator(ret.first, ret.bucket_first) + , this->build_const_iterator(ret.second, ret.bucket_second)); } #if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED) @@ -2717,7 +3304,7 @@ class hashtable_impl //! Complexity: Constant. //! //! Throws: If the internal hash function throws. - iterator iterator_to(reference value); + iterator iterator_to(reference value) BOOST_NOEXCEPT; //! Requires: value must be an lvalue and shall be in a unordered_set of //! appropriate type. Otherwise the behavior is undefined. @@ -2728,7 +3315,7 @@ class hashtable_impl //! Complexity: Constant. //! //! Throws: If the internal hash function throws. - const_iterator iterator_to(const_reference value) const; + const_iterator iterator_to(const_reference value) const BOOST_NOEXCEPT; //! Requires: value must be an lvalue and shall be in a unordered_set of //! appropriate type. Otherwise the behavior is undefined. @@ -2742,7 +3329,7 @@ class hashtable_impl //! //! Note: This static function is available only if the value traits //! is stateless. - static local_iterator s_local_iterator_to(reference value); + static local_iterator s_local_iterator_to(reference value) BOOST_NOEXCEPT; //! Requires: value must be an lvalue and shall be in a unordered_set of //! appropriate type. Otherwise the behavior is undefined. @@ -2756,7 +3343,7 @@ class hashtable_impl //! //! Note: This static function is available only if the value traits //! is stateless. - static const_local_iterator s_local_iterator_to(const_reference value); + static const_local_iterator s_local_iterator_to(const_reference value) BOOST_NOEXCEPT; //! Requires: value must be an lvalue and shall be in a unordered_set of //! appropriate type. Otherwise the behavior is undefined. @@ -2767,7 +3354,7 @@ class hashtable_impl //! Complexity: Constant. //! //! Throws: Nothing. - local_iterator local_iterator_to(reference value); + local_iterator local_iterator_to(reference value) BOOST_NOEXCEPT; //! Requires: value must be an lvalue and shall be in a unordered_set of //! appropriate type. Otherwise the behavior is undefined. @@ -2778,7 +3365,7 @@ class hashtable_impl //! Complexity: Constant. //! //! Throws: Nothing. - const_local_iterator local_iterator_to(const_reference value) const; + const_local_iterator local_iterator_to(const_reference value) const BOOST_NOEXCEPT; //! Effects: Returns the number of buckets passed in the constructor //! or the last rehash function. @@ -2786,7 +3373,7 @@ class hashtable_impl //! Complexity: Constant. //! //! Throws: Nothing. - size_type bucket_count() const; + size_type bucket_count() const BOOST_NOEXCEPT; //! Requires: n is in the range [0, this->bucket_count()). //! @@ -2795,7 +3382,7 @@ class hashtable_impl //! Complexity: Constant. //! //! Throws: Nothing. - size_type bucket_size(size_type n) const; + size_type bucket_size(size_type n) const BOOST_NOEXCEPT; #endif //#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED) //! Effects: Returns the index of the bucket in which elements @@ -2806,8 +3393,8 @@ class hashtable_impl //! Throws: If the hash functor throws. //! //! Note: the return value is in the range [0, this->bucket_count()). - BOOST_INTRUSIVE_FORCEINLINE size_type bucket(const key_type& k) const - { return this->bucket(k, this->priv_hasher()); } + BOOST_INTRUSIVE_FORCEINLINE size_type bucket(const key_type& k) const + { return this->priv_hash_to_nbucket(this->priv_hash(k)); } //! Requires: "hash_func" must be a hash function that induces //! the same hash values as the stored hasher. The difference is that @@ -2823,7 +3410,7 @@ class hashtable_impl //! Note: the return value is in the range [0, this->bucket_count()). template BOOST_INTRUSIVE_FORCEINLINE size_type bucket(const KeyType& k, KeyHasher hash_func) const - { return this->priv_hash_to_bucket(hash_func(k)); } + { return this->priv_hash_to_nbucket(hash_func(k)); } #if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED) //! Effects: Returns the bucket array pointer passed in the constructor @@ -2832,7 +3419,7 @@ class hashtable_impl //! Complexity: Constant. //! //! Throws: Nothing. - bucket_ptr bucket_pointer() const; + bucket_ptr bucket_pointer() const BOOST_NOEXCEPT; //! Requires: n is in the range [0, this->bucket_count()). //! @@ -2845,7 +3432,7 @@ class hashtable_impl //! //! Note: [this->begin(n), this->end(n)) is a valid range //! containing all of the elements in the nth bucket. - local_iterator begin(size_type n); + local_iterator begin(size_type n) BOOST_NOEXCEPT; //! Requires: n is in the range [0, this->bucket_count()). //! @@ -2858,7 +3445,7 @@ class hashtable_impl //! //! Note: [this->begin(n), this->end(n)) is a valid range //! containing all of the elements in the nth bucket. - const_local_iterator begin(size_type n) const; + const_local_iterator begin(size_type n) const BOOST_NOEXCEPT; //! Requires: n is in the range [0, this->bucket_count()). //! @@ -2871,7 +3458,7 @@ class hashtable_impl //! //! Note: [this->begin(n), this->end(n)) is a valid range //! containing all of the elements in the nth bucket. - const_local_iterator cbegin(size_type n) const; + const_local_iterator cbegin(size_type n) const BOOST_NOEXCEPT; //! Requires: n is in the range [0, this->bucket_count()). //! @@ -2884,7 +3471,7 @@ class hashtable_impl //! //! Note: [this->begin(n), this->end(n)) is a valid range //! containing all of the elements in the nth bucket. - local_iterator end(size_type n); + local_iterator end(size_type n) BOOST_NOEXCEPT; //! Requires: n is in the range [0, this->bucket_count()). //! @@ -2897,7 +3484,7 @@ class hashtable_impl //! //! Note: [this->begin(n), this->end(n)) is a valid range //! containing all of the elements in the nth bucket. - const_local_iterator end(size_type n) const; + const_local_iterator end(size_type n) const BOOST_NOEXCEPT; //! Requires: n is in the range [0, this->bucket_count()). //! @@ -2910,7 +3497,7 @@ class hashtable_impl //! //! Note: [this->begin(n), this->end(n)) is a valid range //! containing all of the elements in the nth bucket. - const_local_iterator cend(size_type n) const; + const_local_iterator cend(size_type n) const BOOST_NOEXCEPT; #endif //#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED) //! Requires: new_bucket_traits can hold a pointer to a new bucket array @@ -2941,7 +3528,7 @@ class hashtable_impl //! //! Throws: If the hasher functor throws. Basic guarantee. BOOST_INTRUSIVE_FORCEINLINE void rehash(const bucket_traits &new_bucket_traits) - { this->rehash_impl(new_bucket_traits, false); } + { this->priv_rehash_impl(new_bucket_traits, false); } //! Note: This function is used when keys from inserted elements are changed //! (e.g. a language change when key is a string) but uniqueness and hash properties are @@ -2964,7 +3551,7 @@ class hashtable_impl //! //! Throws: If the hasher functor throws. Basic guarantee. BOOST_INTRUSIVE_FORCEINLINE void full_rehash() - { this->rehash_impl(this->priv_bucket_traits(), true); } + { this->priv_rehash_impl(this->priv_bucket_traits(), true); } //! Requires: //! @@ -2979,47 +3566,49 @@ class hashtable_impl { //This function is only available for containers with incremental hashing BOOST_STATIC_ASSERT(( incremental && power_2_buckets )); - const size_type split_idx = this->priv_split_traits().get_size(); - const size_type bucket_cnt = this->bucket_count(); - const bucket_ptr buck_ptr = this->priv_bucket_pointer(); + const std::size_t split_idx = this->split_count(); + const std::size_t bucket_cnt = this->bucket_count(); bool ret = false; if(grow){ //Test if the split variable can be changed if((ret = split_idx < bucket_cnt)){ - const size_type bucket_to_rehash = split_idx - bucket_cnt/2; - bucket_type &old_bucket = buck_ptr[bucket_to_rehash]; - this->priv_split_traits().increment(); + const std::size_t bucket_to_rehash = split_idx - bucket_cnt/2u; + bucket_type &old_bucket = this->priv_bucket(bucket_to_rehash); + this->inc_split_count(); //Anti-exception stuff: if an exception is thrown while //moving elements from old_bucket to the target bucket, all moved //elements are moved back to the original one. - detail::incremental_rehash_rollback rollback - ( buck_ptr[split_idx], old_bucket, this->priv_split_traits()); - for( siterator before_i(old_bucket.before_begin()), i(old_bucket.begin()), end_sit(old_bucket.end()) - ; i != end_sit; i = before_i, ++i){ - const value_type &v = this->priv_value_from_slist_node(i.pointed_node()); + incremental_rehash_rollback rollback + ( this->priv_bucket(split_idx), old_bucket, this->priv_split_traits()); + siterator before_i(old_bucket.get_node_ptr()); + siterator i(before_i); ++i; + siterator end_sit = linear_buckets ? siterator() : before_i; + for( ; i != end_sit; i = before_i, ++i){ + const value_type &v = this->priv_value_from_siterator(i); const std::size_t hash_value = this->priv_stored_or_compute_hash(v, store_hash_t()); - const size_type new_n = this->priv_hash_to_bucket(hash_value); - siterator const last = (priv_last_in_group)(i); + const std::size_t new_n = this->priv_hash_to_nbucket(hash_value); + siterator last = i; + (priv_go_to_last_in_group)(last, optimize_multikey_t()); if(new_n == bucket_to_rehash){ before_i = last; } else{ - bucket_type &new_b = buck_ptr[new_n]; - new_b.splice_after(new_b.before_begin(), old_bucket, before_i, last); + bucket_type &new_b = this->priv_bucket(new_n); + slist_node_algorithms::transfer_after(new_b.get_node_ptr(), before_i.pointed_node(), last.pointed_node()); } } rollback.release(); this->priv_erasure_update_cache(); } } - else if((ret = split_idx > bucket_cnt/2)){ //!grow - const size_type target_bucket_num = split_idx - 1 - bucket_cnt/2; - bucket_type &target_bucket = buck_ptr[target_bucket_num]; - bucket_type &source_bucket = buck_ptr[split_idx-1]; - target_bucket.splice_after(target_bucket.cbefore_begin(), source_bucket); - this->priv_split_traits().decrement(); + else if((ret = split_idx > bucket_cnt/2u)){ //!grow + const std::size_t target_bucket_num = split_idx - 1u - bucket_cnt/2u; + bucket_type &target_bucket = this->priv_bucket(target_bucket_num); + bucket_type &source_bucket = this->priv_bucket(split_idx-1u); + slist_node_algorithms::transfer_after(target_bucket.get_node_ptr(), source_bucket.get_node_ptr()); + this->dec_split_count(); this->priv_insertion_update_cache(target_bucket_num); } return ret; @@ -3038,40 +3627,50 @@ class hashtable_impl //! Throws: Nothing //! //! Note: this method is only available if incremental option is activated. - bool incremental_rehash(const bucket_traits &new_bucket_traits) + bool incremental_rehash(const bucket_traits &new_bucket_traits) BOOST_NOEXCEPT { //This function is only available for containers with incremental hashing BOOST_STATIC_ASSERT(( incremental && power_2_buckets )); - size_type const new_bucket_traits_size = new_bucket_traits.bucket_count(); - size_type const cur_bucket_traits = this->bucket_count(); + const bucket_ptr new_buckets = new_bucket_traits.bucket_begin(); + const size_type new_bucket_count_stdszt = static_cast(new_bucket_traits.bucket_count() - bucket_overhead); + BOOST_INTRUSIVE_INVARIANT_ASSERT(sizeof(size_type) >= sizeof(std::size_t) || new_bucket_count_stdszt <= size_type(-1)); + size_type new_bucket_count = static_cast(new_bucket_count_stdszt); + const size_type old_bucket_count = static_cast(this->priv_usable_bucket_count()); const size_type split_idx = this->split_count(); //Test new bucket size is consistent with internal bucket size and split count - if(new_bucket_traits_size/2 == cur_bucket_traits){ - if(!(split_idx >= cur_bucket_traits)) + if(new_bucket_count/2 == old_bucket_count){ + if(!(split_idx >= old_bucket_count)) return false; } - else if(new_bucket_traits_size == cur_bucket_traits/2){ - if(!(split_idx <= new_bucket_traits_size)) + else if(new_bucket_count == old_bucket_count/2){ + if(!(split_idx <= new_bucket_count)) return false; } else{ return false; } - const size_type ini_n = this->priv_get_cache_bucket_num(); + const size_type ini_n = (size_type)this->priv_get_cache_bucket_num(); const bucket_ptr old_buckets = this->priv_bucket_pointer(); - this->priv_bucket_traits() = new_bucket_traits; - if(new_bucket_traits.bucket_begin() != old_buckets){ + + + this->priv_unset_sentinel_bucket(); + this->priv_initialize_new_buckets(old_buckets, old_bucket_count, new_buckets, new_bucket_count); + if (&new_bucket_traits != &this->priv_bucket_traits()) + this->priv_bucket_traits() = new_bucket_traits; + + if(old_buckets != new_buckets){ for(size_type n = ini_n; n < split_idx; ++n){ - bucket_type &new_bucket = new_bucket_traits.bucket_begin()[n]; - bucket_type &old_bucket = old_buckets[n]; - new_bucket.splice_after(new_bucket.cbefore_begin(), old_bucket); + slist_node_ptr new_bucket_nodeptr = new_bucket_traits.bucket_begin()[difference_type(n)].get_node_ptr(); + slist_node_ptr old_bucket_node_ptr = old_buckets[difference_type(n)].get_node_ptr(); + slist_node_algorithms::transfer_after(new_bucket_nodeptr, old_bucket_node_ptr); } - //Put cache to safe position - this->priv_initialize_cache(); - this->priv_insertion_update_cache(ini_n); + //Reset cache to safe position + this->priv_set_cache_bucket_num(ini_n); } + + this->priv_set_sentinel_bucket(); return true; } @@ -3084,7 +3683,7 @@ class hashtable_impl //! Complexity: Constant //! //! Throws: Nothing - size_type split_count() const; + size_type split_count() const BOOST_NOEXCEPT; //! Effects: Returns the nearest new bucket count optimized for //! the container that is bigger or equal than n. This suggestion can be @@ -3095,7 +3694,7 @@ class hashtable_impl //! Complexity: Amortized constant time. //! //! Throws: Nothing. - static size_type suggested_upper_bucket_count(size_type n); + static size_type suggested_upper_bucket_count(size_type n) BOOST_NOEXCEPT; //! Effects: Returns the nearest new bucket count optimized for //! the container that is smaller or equal than n. This suggestion can be @@ -3106,7 +3705,7 @@ class hashtable_impl //! Complexity: Amortized constant time. //! //! Throws: Nothing. - static size_type suggested_lower_bucket_count(size_type n); + static size_type suggested_lower_bucket_count(size_type n) BOOST_NOEXCEPT; #endif //#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED) @@ -3116,6 +3715,10 @@ class hashtable_impl if(constant_time_size && x.size() != y.size()){ return false; } + + if (boost::intrusive::iterator_udistance(x.begin(), x.end()) != x.size()) + return false; + for (const_iterator ix = x.cbegin(), ex = x.cend(); ix != ex; ++ix){ std::pair eqx(x.equal_range(key_of_value()(*ix))), eqy(y.equal_range(key_of_value()(*ix))); @@ -3148,18 +3751,45 @@ class hashtable_impl BOOST_INTRUSIVE_FORCEINLINE void check() const {} private: - void rehash_impl(const bucket_traits &new_bucket_traits, bool do_full_rehash) + static void priv_initialize_new_buckets + ( bucket_ptr old_buckets, size_type old_bucket_count + , bucket_ptr new_buckets, size_type new_bucket_count) + { + //Initialize new buckets + const bool same_buffer = old_buckets == new_buckets; + if (same_buffer && new_bucket_count <= old_bucket_count) { + //Nothing to do here + } + else { + bucket_ptr p; + size_type c; + + if (same_buffer) { + p = old_buckets + std::ptrdiff_t(old_bucket_count); + c = size_type(new_bucket_count - old_bucket_count); + } + else { + p = new_buckets; + c = new_bucket_count; + } + internal_type::priv_init_buckets(p, c); + } + } + + void priv_rehash_impl(const bucket_traits &new_bucket_traits, bool do_full_rehash) { + const std::size_t nbc = new_bucket_traits.bucket_count() - bucket_overhead; + BOOST_INTRUSIVE_INVARIANT_ASSERT(sizeof(SizeType) >= sizeof(std::size_t) || nbc <= SizeType(-1)); + const bucket_ptr new_buckets = new_bucket_traits.bucket_begin(); - size_type new_bucket_count = new_bucket_traits.bucket_count(); + const size_type new_bucket_count = static_cast(nbc); const bucket_ptr old_buckets = this->priv_bucket_pointer(); - size_type old_bucket_count = this->bucket_count(); + const size_type old_bucket_count = this->bucket_count(); //Check power of two bucket array if the option is activated BOOST_INTRUSIVE_INVARIANT_ASSERT (!power_2_buckets || (0 == (new_bucket_count & (new_bucket_count-1u)))); - size_type n = this->priv_get_cache_bucket_num(); const bool same_buffer = old_buckets == new_buckets; //If the new bucket length is a common factor //of the old one we can avoid hash calculations. @@ -3168,86 +3798,95 @@ class hashtable_impl //If we are shrinking the same bucket array and it's //is a fast shrink, just rehash the last nodes size_type new_first_bucket_num = new_bucket_count; - if(same_buffer && fast_shrink && (n < new_bucket_count)){ - new_first_bucket_num = n; - n = new_bucket_count; + size_type old_bucket_cache = (size_type)this->priv_get_cache_bucket_num(); + if(same_buffer && fast_shrink && (old_bucket_cache < new_bucket_count)){ + new_first_bucket_num = old_bucket_cache; + old_bucket_cache = new_bucket_count; } + if (!do_full_rehash) + this->priv_initialize_new_buckets(old_buckets, old_bucket_count, new_buckets, new_bucket_count); + //Anti-exception stuff: they destroy the elements if something goes wrong. //If the source and destination buckets are the same, the second rollback function //is harmless, because all elements have been already unlinked and destroyed - typedef detail::init_disposer NodeDisposer; - typedef detail::exception_array_disposer ArrayDisposer; - NodeDisposer node_disp; - ArrayDisposer rollback1(new_buckets[0], node_disp, new_bucket_count); - ArrayDisposer rollback2(old_buckets[0], node_disp, old_bucket_count); + + typedef typename internal_type::template typeof_node_disposer::type NodeDisposer; + typedef exception_bucket_disposer ArrayDisposer; + NodeDisposer nd(this->make_node_disposer(detail::null_disposer())); + ArrayDisposer rollback1(new_buckets[0], nd, new_bucket_count); + ArrayDisposer rollback2(old_buckets[0], nd, old_bucket_count); //Put size in a safe value for rollback exception - size_type const size_backup = this->priv_size_traits().get_size(); - this->priv_size_traits().set_size(0); + size_type const size_backup = this->priv_size_count(); + this->priv_size_count(0); //Put cache to safe position - this->priv_initialize_cache(); - this->priv_insertion_update_cache(size_type(0u)); + this->priv_init_cache(); + this->priv_unset_sentinel_bucket(); + + const size_type split = this->rehash_split_from_bucket_count(new_bucket_count); //Iterate through nodes - for(; n < old_bucket_count; ++n){ - bucket_type &old_bucket = old_buckets[n]; + for(size_type n = old_bucket_cache; n < old_bucket_count; ++n){ + bucket_type &old_bucket = old_buckets[difference_type(n)]; if(!fast_shrink){ - for( siterator before_i(old_bucket.before_begin()), i(old_bucket.begin()), end_sit(old_bucket.end()) + siterator before_i(old_bucket.get_node_ptr()); + siterator i(before_i); ++i; + siterator end_sit(this->sit_end(old_bucket)); + for( // ; i != end_sit ; i = before_i, ++i){ //First obtain hash value (and store it if do_full_rehash) std::size_t hash_value; if(do_full_rehash){ - value_type &v = this->priv_value_from_slist_node(i.pointed_node()); + value_type &v = this->priv_value_from_siterator(i); hash_value = this->priv_hasher()(key_of_value()(v)); - node_functions_t::store_hash(pointer_traits::pointer_to(this->priv_value_to_node(v)), hash_value, store_hash_t()); + node_functions_t::store_hash(this->priv_value_to_node_ptr(v), hash_value, store_hash_t()); } else{ - const value_type &v = this->priv_value_from_slist_node(i.pointed_node()); + const value_type &v = this->priv_value_from_siterator(i); hash_value = this->priv_stored_or_compute_hash(v, store_hash_t()); } //Now calculate the new bucket position - const size_type new_n = detail::hash_to_bucket_split - (hash_value, new_bucket_count, new_bucket_count); + const size_type new_n = (size_type)hash_to_bucket_split + (hash_value, new_bucket_count, split, fastmod_buckets_t()); //Update first used bucket cache if(cache_begin && new_n < new_first_bucket_num) new_first_bucket_num = new_n; //If the target bucket is new, transfer the whole group - siterator const last = (priv_last_in_group)(i); + siterator last = i; + (priv_go_to_last_in_group)(i, optimize_multikey_t()); if(same_buffer && new_n == n){ before_i = last; } else{ - bucket_type &new_b = new_buckets[new_n]; - new_b.splice_after(new_b.before_begin(), old_bucket, before_i, last); + bucket_type &new_b = new_buckets[difference_type(new_n)]; + slist_node_algorithms::transfer_after(new_b.get_node_ptr(), before_i.pointed_node(), last.pointed_node()); } } } else{ - const size_type new_n = detail::hash_to_bucket_split(n, new_bucket_count, new_bucket_count); + const size_type new_n = (size_type)hash_to_bucket_split + (n, new_bucket_count, split, fastmod_buckets_t()); if(cache_begin && new_n < new_first_bucket_num) new_first_bucket_num = new_n; - bucket_type &new_b = new_buckets[new_n]; - new_b.splice_after( new_b.before_begin() - , old_bucket - , old_bucket.before_begin() - , bucket_plus_vtraits_t::priv_get_last(old_bucket, optimize_multikey_t())); + bucket_type &new_b = new_buckets[difference_type(new_n)]; + siterator last = this->priv_get_last(old_bucket, optimize_multikey_t()); + slist_node_algorithms::transfer_after(new_b.get_node_ptr(), old_bucket.get_node_ptr(), last.pointed_node()); } } - this->priv_size_traits().set_size(size_backup); - this->priv_split_traits().set_size(new_bucket_count); - if(&new_bucket_traits != &this->priv_bucket_traits()){ + this->priv_size_count(size_backup); + this->split_count(split); + if(&new_bucket_traits != &this->priv_bucket_traits()) this->priv_bucket_traits() = new_bucket_traits; - } - this->priv_initialize_cache(); - this->priv_insertion_update_cache(new_first_bucket_num); + this->priv_set_sentinel_bucket(); + this->priv_set_cache_bucket_num(new_first_bucket_num); rollback1.release(); rollback2.release(); } @@ -3282,8 +3921,8 @@ class hashtable_impl for(; b != e; ++b){ //No need to check for duplicates and insert it in the first position //as this is an unordered container. So use minimal insertion code - std::size_t const hash_to_store = this->priv_stored_or_compute_hash(*b, store_hash_t());; - size_type const bucket_number = this->priv_hash_to_bucket(hash_to_store); + std::size_t const hash_to_store = this->priv_stored_or_compute_hash(*b, store_hash_t()); + size_type const bucket_number = this->priv_hash_to_nbucket(hash_to_store); typedef typename detail::if_c ::value, const_reference, reference>::type reference_type; reference_type r = *b; @@ -3301,16 +3940,14 @@ class hashtable_impl { //No need to check for duplicates and insert it in the first position //as this is an unordered container. So use minimal insertion code - //std::size_t const hash_value = this->priv_stored_or_compute_hash(src_ref, store_hash_t());; - //size_type const bucket_number = this->priv_hash_to_bucket(hash_value); - bucket_type &cur_bucket = this->priv_bucket_pointer()[bucket_number]; - siterator const prev(cur_bucket.before_begin()); + bucket_type &cur_bucket = this->priv_bucket(bucket_number); + siterator const prev(cur_bucket.get_node_ptr()); //Just check if the cloned node is equal to the first inserted value in the new bucket //as equal src values were contiguous and they should be already inserted in the //destination bucket. - bool const next_is_in_group = optimize_multikey && !cur_bucket.empty() && + bool const next_is_in_group = optimize_multikey && !this->priv_bucket_empty(bucket_number) && this->priv_equal()( key_of_value()(src_ref) - , key_of_value()(this->priv_value_from_slist_node((++siterator(prev)).pointed_node()))); + , key_of_value()(this->priv_value_from_siterator(++siterator(prev)))); this->priv_insert_equal_after_find(*cloner(src_ref), bucket_number, hash_to_store, prev, next_is_in_group); } @@ -3320,108 +3957,122 @@ class hashtable_impl //First clone the first ones const size_type src_bucket_count = src.bucket_count(); const size_type dst_bucket_count = this->bucket_count(); - const bucket_ptr src_buckets = src.priv_bucket_pointer(); - const bucket_ptr dst_buckets = this->priv_bucket_pointer(); size_type constructed = 0; - typedef node_cast_adaptor< detail::node_disposer - , slist_node_ptr, node_ptr > NodeDisposer; + typedef typename internal_type::template typeof_node_disposer::type NodeDisposer; NodeDisposer node_disp(disposer, &this->priv_value_traits()); - detail::exception_array_disposer - rollback(dst_buckets[0], node_disp, constructed); + exception_bucket_disposer + rollback(this->priv_bucket(0), node_disp, constructed); //Now insert the remaining ones using the modulo trick for( //"constructed" already initialized ; constructed < src_bucket_count ; ++constructed){ - //Since incremental hashing can't be structurally copied, avoid hash_to_bucket_split - const std::size_t new_n = detail::hash_to_bucket(constructed, dst_bucket_count, detail::bool_()); - bucket_type &src_b = src_buckets[constructed]; - for( siterator b(src_b.begin()), e(src_b.end()); b != e; ++b){ - slist_node_ptr const n(b.pointed_node()); + + const size_type new_n = (size_type)hash_to_bucket_split + (constructed, dst_bucket_count, this->split_count(), fastmod_buckets_t()); + bucket_type &src_b = src.priv_bucket(constructed); + for( siterator b(this->priv_bucket_lbegin(src_b)), e(this->priv_bucket_lend(src_b)); b != e; ++b){ typedef typename detail::if_c ::value, const_reference, reference>::type reference_type; - reference_type r = this->priv_value_from_slist_node(n); + reference_type r = this->priv_value_from_siterator(b); this->priv_clone_front_in_bucket - (new_n, r, this->priv_stored_hash(n, store_hash_t()), cloner); + (new_n, r, this->priv_stored_hash(b, store_hash_t()), cloner); } } this->priv_hasher() = src.priv_hasher(); this->priv_equal() = src.priv_equal(); rollback.release(); - this->priv_size_traits().set_size(src.priv_size_traits().get_size()); - this->priv_split_traits().set_size(dst_bucket_count); - this->priv_insertion_update_cache(0u); + this->priv_size_count(src.priv_size_count()); + this->split_count(dst_bucket_count); + this->priv_set_cache_bucket_num(0u); this->priv_erasure_update_cache(); } - std::size_t priv_hash_to_bucket(std::size_t hash_value) const - { - return detail::hash_to_bucket_split - (hash_value, this->priv_bucket_traits().bucket_count(), this->priv_split_traits().get_size()); - } - iterator priv_insert_equal_after_find(reference value, size_type bucket_num, std::size_t hash_value, siterator prev, bool const next_is_in_group) { //Now store hash if needed - node_ptr n = pointer_traits::pointer_to(this->priv_value_to_node(value)); + node_ptr n = this->priv_value_to_node_ptr(value); node_functions_t::store_hash(n, hash_value, store_hash_t()); //Checks for some modes - BOOST_INTRUSIVE_SAFE_HOOK_DEFAULT_ASSERT(!safemode_or_autounlink || node_algorithms::unique(n)); + BOOST_INTRUSIVE_SAFE_HOOK_DEFAULT_ASSERT(!safemode_or_autounlink || slist_node_algorithms::unique(n)); //Shortcut to optimize_multikey cases group_functions_t::insert_in_group - ( next_is_in_group ? detail::dcast_bucket_ptr((++siterator(prev)).pointed_node()) : n + ( next_is_in_group ? dcast_bucket_ptr((++siterator(prev)).pointed_node()) : n , n, optimize_multikey_t()); //Update cache and increment size if needed this->priv_insertion_update_cache(bucket_num); - this->priv_size_traits().increment(); - //Insert the element in the bucket after it - return iterator(bucket_type::s_insert_after(prev, *n), &this->get_bucket_value_traits()); + this->priv_size_inc(); + slist_node_algorithms::link_after(prev.pointed_node(), n); + return this->build_iterator(siterator(n), this->priv_bucket_ptr(bucket_num)); } template - siterator priv_find //In case it is not found previt is bucket.before_begin() + siterator priv_find //In case it is not found previt is priv_end_sit() ( const KeyType &key, KeyHasher hash_func , KeyEqual equal_func, size_type &bucket_number, std::size_t &h, siterator &previt) const { h = hash_func(key); - return this->priv_find_with_hash(key, equal_func, bucket_number, h, previt); - } - template - bool priv_is_value_equal_to_key(const value_type &v, const std::size_t h, const KeyType &key, KeyEqual equal_func) const - { - (void)h; - return (!compare_hash || this->priv_stored_or_compute_hash(v, store_hash_t()) == h) && equal_func(key, key_of_value()(v)); - } + bucket_number = this->priv_hash_to_nbucket(h); + bucket_type& b = this->priv_bucket(bucket_number); + siterator prev = this->sit_bbegin(b); + siterator it = prev; + siterator const endit = this->sit_end(b); - //return previous iterator to the next equal range group in case - static siterator priv_last_in_group(const siterator &it_first_in_group) - { - return bucket_type::s_iterator_to - (*group_functions_t::get_last_in_group - (detail::dcast_bucket_ptr(it_first_in_group.pointed_node()), optimize_multikey_t())); + while (++it != endit) { + if (this->priv_is_value_equal_to_key + (this->priv_value_from_siterator(it), h, key, equal_func, compare_hash_t())) { + previt = prev; + return it; + } + (priv_go_to_last_in_group)(it, optimize_multikey_t()); + prev = it; + } + previt = b.get_node_ptr(); + return this->priv_end_sit(); } + template - siterator priv_find_with_hash //In case it is not found previt is bucket.before_begin() - ( const KeyType &key, KeyEqual equal_func, size_type &bucket_number, const std::size_t h, siterator &previt) const + siterator priv_find_in_bucket //In case it is not found previt is priv_end_sit() + (bucket_type &b, const KeyType& key, KeyEqual equal_func, const std::size_t h) const { - bucket_number = this->priv_hash_to_bucket(h); - bucket_type &b = this->priv_bucket_pointer()[bucket_number]; - previt = b.before_begin(); - siterator it = previt; - siterator const endit = b.end(); + siterator it(this->sit_begin(b)); + siterator const endit(this->sit_end(b)); - while(++it != endit){ - if(this->priv_is_value_equal_to_key(this->priv_value_from_slist_node(it.pointed_node()), h, key, equal_func)){ + for (; it != endit; (priv_go_to_last_in_group)(it, optimize_multikey_t()), ++it) { + if (BOOST_LIKELY(this->priv_is_value_equal_to_key + (this->priv_value_from_siterator(it), h, key, equal_func, compare_hash_t()))) { return it; } - previt = it = (priv_last_in_group)(it); } - previt = b.before_begin(); - return this->priv_invalid_local_it(); + return this->priv_end_sit(); + } + + template + BOOST_INTRUSIVE_FORCEINLINE bool priv_is_value_equal_to_key + (const value_type &v, const std::size_t h, const KeyType &key, KeyEqual equal_func, detail::true_) const //compare_hash + { return this->priv_stored_or_compute_hash(v, store_hash_t()) == h && equal_func(key, key_of_value()(v)); } + + template + BOOST_INTRUSIVE_FORCEINLINE bool priv_is_value_equal_to_key + (const value_type& v, const std::size_t , const KeyType& key, KeyEqual equal_func, detail::false_) const //compare_hash + { return equal_func(key, key_of_value()(v)); } + + //return previous iterator to the next equal range group in case + BOOST_INTRUSIVE_FORCEINLINE static void priv_go_to_last_in_group + (siterator &it_first_in_group, detail::true_) BOOST_NOEXCEPT //optimize_multikey + { + it_first_in_group = + (group_functions_t::get_last_in_group + (dcast_bucket_ptr(it_first_in_group.pointed_node()), optimize_multikey_t())); } + //return previous iterator to the next equal range group in case + BOOST_INTRUSIVE_FORCEINLINE static void priv_go_to_last_in_group //!optimize_multikey + (siterator /*&it_first_in_group*/, detail::false_) BOOST_NOEXCEPT + { } + template std::pair priv_local_equal_range ( const KeyType &key @@ -3430,7 +4081,7 @@ class hashtable_impl , size_type &found_bucket , size_type &cnt) const { - size_type internal_cnt = 0; + std::size_t internal_cnt = 0; //Let's see if the element is present siterator prev; @@ -3438,34 +4089,47 @@ class hashtable_impl std::size_t h; std::pair to_return ( this->priv_find(key, hash_func, equal_func, n_bucket, h, prev) - , this->priv_invalid_local_it()); + , this->priv_end_sit()); if(to_return.first != to_return.second){ found_bucket = n_bucket; //If it's present, find the first that it's not equal in //the same bucket - bucket_type &b = this->priv_bucket_pointer()[n_bucket]; siterator it = to_return.first; - ++internal_cnt; //At least one is found - if(optimize_multikey){ - to_return.second = ++(priv_last_in_group)(it); - internal_cnt += boost::intrusive::iterator_distance(++it, to_return.second); + siterator const bend = this->priv_bucket_lend(n_bucket); + BOOST_IF_CONSTEXPR(optimize_multikey){ + siterator past_last_in_group_it = it; + (priv_go_to_last_in_group)(past_last_in_group_it, optimize_multikey_t()); + ++past_last_in_group_it; + internal_cnt += boost::intrusive::iterator_udistance(++it, past_last_in_group_it) + 1u; + if (past_last_in_group_it != bend) + to_return.second = past_last_in_group_it; } else{ - siterator const bend = b.end(); - while(++it != bend && - this->priv_is_value_equal_to_key(this->priv_value_from_slist_node(it.pointed_node()), h, key, equal_func)){ - ++internal_cnt; - } - to_return.second = it; + do { + ++internal_cnt; //At least one is found + ++it; + } while(it != bend && + this->priv_is_value_equal_to_key + (this->priv_value_from_siterator(it), h, key, equal_func, compare_hash_t())); + if (it != bend) + to_return.second = it; } } - cnt = internal_cnt; + cnt = size_type(internal_cnt); return to_return; } + struct priv_equal_range_result + { + siterator first; + siterator second; + bucket_ptr bucket_first; + bucket_ptr bucket_second; + }; + template - std::pair priv_equal_range + priv_equal_range_result priv_equal_range ( const KeyType &key , KeyHasher hash_func , KeyEqual equal_func) const @@ -3474,71 +4138,103 @@ class hashtable_impl size_type cnt; //Let's see if the element is present - std::pair to_return + const std::pair to_return (this->priv_local_equal_range(key, hash_func, equal_func, n_bucket, cnt)); + priv_equal_range_result r; + r.first = to_return.first; + r.second = to_return.second; + //If not, find the next element as ".second" if ".second" local iterator //is not pointing to an element. - bucket_ptr const bp = this->priv_bucket_pointer(); - if(to_return.first != to_return.second && - to_return.second == bp[n_bucket].end()){ - to_return.second = this->priv_invalid_local_it(); - ++n_bucket; - for( const size_type max_bucket = this->bucket_count() - ; n_bucket != max_bucket - ; ++n_bucket){ - bucket_type &b = bp[n_bucket]; - if(!b.empty()){ - to_return.second = b.begin(); - break; - } + if(to_return.first == to_return.second) { + r.bucket_first = r.bucket_second = this->priv_invalid_bucket_ptr(); + } + else if (to_return.second != this->priv_end_sit()) { + r.bucket_first = this->priv_bucket_ptr(n_bucket); + } + else{ + r.bucket_first = this->priv_bucket_ptr(n_bucket); + const size_type max_bucket = this->bucket_count(); + do{ + ++n_bucket; + } while (n_bucket != max_bucket && this->priv_bucket_empty(n_bucket)); + + if (n_bucket == max_bucket){ + r.bucket_second = this->priv_invalid_bucket_ptr(); + } + else{ + r.bucket_second = this->priv_bucket_ptr(n_bucket); + r.second = siterator(r.bucket_second->begin_ptr()); } } - return to_return; + + return r; } - std::size_t priv_get_bucket_num(siterator it) - { return this->priv_get_bucket_num_hash_dispatch(it, store_hash_t()); } + BOOST_INTRUSIVE_FORCEINLINE size_type priv_get_bucket_num(const_iterator it) BOOST_NOEXCEPT + { return this->priv_get_bucket_num(it, linear_buckets_t()); } + + BOOST_INTRUSIVE_FORCEINLINE size_type priv_get_bucket_num(const_iterator it, detail::true_) BOOST_NOEXCEPT //linear + { return size_type(it.get_bucket_ptr() - this->priv_bucket_pointer()); } + + BOOST_INTRUSIVE_FORCEINLINE size_type priv_get_bucket_num(const_iterator it, detail::false_) BOOST_NOEXCEPT //!linear + { return this->priv_get_bucket_num_hash_dispatch(it.slist_it(), store_hash_t()); } + + BOOST_INTRUSIVE_FORCEINLINE size_type priv_get_bucket_num_hash_dispatch(siterator it, detail::true_) BOOST_NOEXCEPT //store_hash + { return (size_type)this->priv_hash_to_nbucket(this->priv_stored_hash(it, store_hash_t())); } - std::size_t priv_get_bucket_num_hash_dispatch(siterator it, detail::true_) //store_hash + size_type priv_get_bucket_num_hash_dispatch(siterator it, detail::false_) BOOST_NOEXCEPT //NO store_hash { - return this->priv_hash_to_bucket - (this->priv_stored_hash(it.pointed_node(), store_hash_t())); + const bucket_type &f = this->priv_bucket(0u); + slist_node_ptr bb = group_functions_t::get_bucket_before_begin + ( this->priv_bucket_lbbegin(0u).pointed_node() + , this->priv_bucket_lbbegin(this->priv_usable_bucket_count() - 1u).pointed_node() + , it.pointed_node() + , optimize_multikey_t()); + + //Now get the bucket_impl from the iterator + const bucket_type &b = static_cast(*bb); + //Now just calculate the index b has in the bucket array + return static_cast(&b - &f); } - std::size_t priv_get_bucket_num_hash_dispatch(siterator it, detail::false_) //NO store_hash - { return this->priv_get_bucket_num_no_hash_store(it, optimize_multikey_t()); } - static siterator priv_get_previous(bucket_type &b, siterator i) - { return bucket_plus_vtraits_t::priv_get_previous(b, i, optimize_multikey_t()); } + BOOST_INTRUSIVE_FORCEINLINE bucket_ptr priv_get_bucket_ptr(const_iterator it) BOOST_NOEXCEPT + { return this->priv_get_bucket_ptr(it, linear_buckets_t()); } + + BOOST_INTRUSIVE_FORCEINLINE bucket_ptr priv_get_bucket_ptr(const_iterator it, detail::true_) BOOST_NOEXCEPT //linear + { return it.get_bucket_ptr(); } + + BOOST_INTRUSIVE_FORCEINLINE bucket_ptr priv_get_bucket_ptr(const_iterator it, detail::false_) BOOST_NOEXCEPT //!linear + { return this->priv_bucket_ptr(this->priv_get_bucket_num_hash_dispatch(it.slist_it(), store_hash_t())); } /// @endcond }; /// @cond template < class T - , bool UniqueKeys , class PackedOptions > struct make_bucket_traits { //Real value traits must be calculated from options typedef typename detail::get_value_traits - ::type value_traits; + ::type value_traits; typedef typename PackedOptions::bucket_traits specified_bucket_traits; //Real bucket traits must be calculated from options and calculated value_traits - typedef typename get_slist_impl - ::type - >::type slist_impl; + typedef bucket_traits_impl + < typename unordered_bucket_ptr_impl + ::type + , std::size_t> bucket_traits_t; typedef typename detail::if_c< detail::is_same < specified_bucket_traits , default_bucket_traits >::value - , bucket_traits_impl + , bucket_traits_t , specified_bucket_traits >::type type; }; @@ -3554,6 +4250,7 @@ template #endif struct make_hashtable @@ -3562,7 +4259,7 @@ struct make_hashtable typedef typename pack_options < hashtable_defaults, #if !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES) - O1, O2, O3, O4, O5, O6, O7, O8, O9, O10 + O1, O2, O3, O4, O5, O6, O7, O8, O9, O10, O11 #else Options... #endif @@ -3572,7 +4269,7 @@ struct make_hashtable ::type value_traits; typedef typename make_bucket_traits - ::type bucket_traits; + ::type bucket_traits; typedef hashtable_impl < value_traits @@ -3587,6 +4284,8 @@ struct make_hashtable |(std::size_t(packed_options::cache_begin)*hash_bool_flags::cache_begin_pos) |(std::size_t(packed_options::compare_hash)*hash_bool_flags::compare_hash_pos) |(std::size_t(packed_options::incremental)*hash_bool_flags::incremental_pos) + |(std::size_t(packed_options::linear_buckets)*hash_bool_flags::linear_buckets_pos) + |(std::size_t(packed_options::fastmod_buckets)*hash_bool_flags::fastmod_buckets_pos) > implementation_defined; /// @endcond diff --git a/include/boost/intrusive/intrusive_fwd.hpp b/include/boost/intrusive/intrusive_fwd.hpp index 37cdb6613..127dbc9e8 100644 --- a/include/boost/intrusive/intrusive_fwd.hpp +++ b/include/boost/intrusive/intrusive_fwd.hpp @@ -570,6 +570,7 @@ template , class O8 = void , class O9 = void , class O10 = void + , class O11 = void > #else template @@ -589,6 +590,7 @@ template , class O8 = void , class O9 = void , class O10 = void + , class O11 = void > #else template diff --git a/include/boost/intrusive/linear_slist_algorithms.hpp b/include/boost/intrusive/linear_slist_algorithms.hpp index 6aeb036ab..a616d7ed7 100644 --- a/include/boost/intrusive/linear_slist_algorithms.hpp +++ b/include/boost/intrusive/linear_slist_algorithms.hpp @@ -19,7 +19,7 @@ #include #include #include -#include //std::pair +#include //for node_pair #if defined(BOOST_HAS_PRAGMA_ONCE) # pragma once @@ -62,6 +62,12 @@ class linear_slist_algorithms typedef typename NodeTraits::node_ptr node_ptr; typedef typename NodeTraits::const_node_ptr const_node_ptr; typedef NodeTraits node_traits; + //A simple struct containing: + // + // typedef node_ptr type; + // node_ptr first; + // node_ptr second; + typedef twin node_pair; #if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED) @@ -72,7 +78,7 @@ class linear_slist_algorithms //! Complexity: Constant //! //! Throws: Nothing. - static void init(const node_ptr & this_node); + static void init(node_ptr this_node) BOOST_NOEXCEPT; //! Requires: this_node must be in a circular list or be an empty circular list. //! @@ -83,7 +89,7 @@ class linear_slist_algorithms //! Complexity: Constant //! //! Throws: Nothing. - static bool unique(const_node_ptr this_node); + static bool unique(const_node_ptr this_node) BOOST_NOEXCEPT; //! Effects: Returns true is "this_node" has the same state as if //! it was inited using "init(node_ptr)" @@ -91,7 +97,7 @@ class linear_slist_algorithms //! Complexity: Constant //! //! Throws: Nothing. - static bool inited(const_node_ptr this_node); + static bool inited(const_node_ptr this_node) BOOST_NOEXCEPT; //! Requires: prev_node must be in a circular list or be an empty circular list. //! @@ -100,7 +106,7 @@ class linear_slist_algorithms //! Complexity: Constant //! //! Throws: Nothing. - static void unlink_after(const node_ptr & prev_node); + static void unlink_after(node_ptr prev_node) BOOST_NOEXCEPT; //! Requires: prev_node and last_node must be in a circular list //! or be an empty circular list. @@ -110,7 +116,7 @@ class linear_slist_algorithms //! Complexity: Constant //! //! Throws: Nothing. - static void unlink_after(const node_ptr & prev_node, const node_ptr & last_node); + static void unlink_after(node_ptr prev_node, node_ptr last_node) BOOST_NOEXCEPT; //! Requires: prev_node must be a node of a linear list. //! @@ -119,7 +125,7 @@ class linear_slist_algorithms //! Complexity: Constant //! //! Throws: Nothing. - static void link_after(const node_ptr & prev_node, const node_ptr & this_node); + static void link_after(node_ptr prev_node, node_ptr this_node) BOOST_NOEXCEPT; //! Requires: b and e must be nodes of the same linear list or an empty range. //! and p must be a node of a different linear list. @@ -130,7 +136,11 @@ class linear_slist_algorithms //! Complexity: Constant //! //! Throws: Nothing. - static void transfer_after(const node_ptr & p, const node_ptr & b, const node_ptr & e); + static void transfer_after(node_ptr p, node_ptr b, node_ptr e) BOOST_NOEXCEPT; + + #else + + using base_t::transfer_after; #endif //#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED) @@ -141,9 +151,44 @@ class linear_slist_algorithms //! Complexity: Constant //! //! Throws: Nothing. - BOOST_INTRUSIVE_FORCEINLINE static void init_header(const node_ptr & this_node) + BOOST_INTRUSIVE_FORCEINLINE static void init_header(node_ptr this_node) BOOST_NOEXCEPT { NodeTraits::set_next(this_node, node_ptr ()); } + //! Requires: 'p' is the first node of a list. + //! + //! Effects: Returns a pointer to a node that represents the "end" (one past end) node + //! + //! Complexity: Constant time. + //! + //! Throws: Nothing. + BOOST_INTRUSIVE_FORCEINLINE static node_ptr end_node(const_node_ptr) BOOST_NOEXCEPT + { return node_ptr(); } + + //! Effects: Returns true if this_node_points to an empty list. + //! + //! Complexity: Constant + //! + //! Throws: Nothing. + BOOST_INTRUSIVE_FORCEINLINE static bool is_empty(const_node_ptr this_node) BOOST_NOEXCEPT + { return !NodeTraits::get_next(this_node); } + + //! Effects: Returns true if this_node points to a sentinel node. + //! + //! Complexity: Constant + //! + //! Throws: Nothing. + BOOST_INTRUSIVE_FORCEINLINE static bool is_sentinel(const_node_ptr this_node) BOOST_NOEXCEPT + { return NodeTraits::get_next(this_node) == this_node; } + + //! Effects: Marks this node as a "sentinel" node, a special state that is different from "empty", + //! that can be used to mark a special state of the list + //! + //! Complexity: Constant + //! + //! Throws: Nothing. + BOOST_INTRUSIVE_FORCEINLINE static void set_sentinel(node_ptr this_node) BOOST_NOEXCEPT + { NodeTraits::set_next(this_node, this_node); } + //! Requires: this_node and prev_init_node must be in the same linear list. //! //! Effects: Returns the previous node of this_node in the linear list starting. @@ -153,7 +198,8 @@ class linear_slist_algorithms //! Complexity: Linear to the number of elements between prev_init_node and this_node. //! //! Throws: Nothing. - BOOST_INTRUSIVE_FORCEINLINE static node_ptr get_previous_node(const node_ptr & prev_init_node, const node_ptr & this_node) + BOOST_INTRUSIVE_FORCEINLINE static node_ptr + get_previous_node(node_ptr prev_init_node, node_ptr this_node) BOOST_NOEXCEPT { return base_t::get_previous_node(prev_init_node, this_node); } //! Requires: this_node must be in a linear list or be an empty linear list. @@ -164,7 +210,7 @@ class linear_slist_algorithms //! Complexity: Linear //! //! Throws: Nothing. - static std::size_t count(const const_node_ptr & this_node) + static std::size_t count(const_node_ptr this_node) BOOST_NOEXCEPT { std::size_t result = 0; const_node_ptr p = this_node; @@ -184,7 +230,7 @@ class linear_slist_algorithms //! Complexity: Constant //! //! Throws: Nothing. - static void swap_trailing_nodes(node_ptr this_node, node_ptr other_node) + BOOST_INTRUSIVE_FORCEINLINE static void swap_trailing_nodes(node_ptr this_node, node_ptr other_node) BOOST_NOEXCEPT { node_ptr this_nxt = NodeTraits::get_next(this_node); node_ptr other_nxt = NodeTraits::get_next(other_node); @@ -199,7 +245,7 @@ class linear_slist_algorithms //! Throws: Nothing. //! //! Complexity: This function is linear to the contained elements. - static node_ptr reverse(node_ptr p) + static node_ptr reverse(node_ptr p) BOOST_NOEXCEPT { if(!p) return node_ptr(); node_ptr i = NodeTraits::get_next(p); @@ -222,9 +268,9 @@ class linear_slist_algorithms //! Throws: Nothing. //! //! Complexity: Linear to the number of elements plus the number moved positions. - static std::pair move_first_n_backwards(node_ptr p, std::size_t n) + static node_pair move_first_n_backwards(node_ptr p, std::size_t n) BOOST_NOEXCEPT { - std::pair ret; + node_pair ret; //Null shift, or count() == 0 or 1, nothing to do if(!n || !p || !NodeTraits::get_next(p)){ return ret; @@ -277,9 +323,9 @@ class linear_slist_algorithms //! Throws: Nothing. //! //! Complexity: Linear to the number of elements plus the number moved positions. - static std::pair move_first_n_forward(node_ptr p, std::size_t n) + static node_pair move_first_n_forward(node_ptr p, std::size_t n) BOOST_NOEXCEPT { - std::pair ret; + node_pair ret; //Null shift, or count() == 0 or 1, nothing to do if(!n || !p || !NodeTraits::get_next(p)) return ret; @@ -322,6 +368,40 @@ class linear_slist_algorithms ret.second = new_last; return ret; } + + //! Requires: other must be a list and p must be a node of a different linear list. + //! + //! Effects: Transfers all nodes from other after p in p's linear list. + //! + //! Complexity: Linear + //! + //! Throws: Nothing. + static void transfer_after(node_ptr p, node_ptr other) BOOST_NOEXCEPT + { + if ((is_empty)(p)) { + (swap_trailing_nodes)(p, other); + } + else { + node_ptr other_last((get_previous_node)(other, node_ptr())); + base_t::transfer_after(p, other, other_last); + } + } + + //! Requires: "disposer" must be an object function + //! taking a node_ptr parameter and shouldn't throw. + //! + //! Effects: Unlinks all nodes reachable from p (but not p) and calls + //! void disposer::operator()(node_ptr) for every node of the list + //! where p is linked. + //! + //! Returns: The number of disposed nodes + //! + //! Complexity: Linear to the number of element of the list. + //! + //! Throws: Nothing. + template + BOOST_INTRUSIVE_FORCEINLINE static std::size_t detach_and_dispose(node_ptr p, Disposer disposer) BOOST_NOEXCEPT + { return base_t::unlink_after_and_dispose(p, node_ptr(), disposer); } }; /// @cond diff --git a/include/boost/intrusive/list.hpp b/include/boost/intrusive/list.hpp index 4313f124f..62291b480 100644 --- a/include/boost/intrusive/list.hpp +++ b/include/boost/intrusive/list.hpp @@ -39,7 +39,7 @@ #include #include -#include //std::less +#include #include //std::size_t, etc. #if defined(BOOST_HAS_PRAGMA_ONCE) @@ -127,10 +127,10 @@ class list_impl ((int)value_traits::link_mode == (int)auto_unlink) )); - node_ptr get_root_node() + BOOST_INTRUSIVE_FORCEINLINE node_ptr get_root_node() { return data_.root_plus_size_.m_header.get_node(); } - const_node_ptr get_root_node() const + BOOST_INTRUSIVE_FORCEINLINE const_node_ptr get_root_node() const { return data_.root_plus_size_.m_header.get_node(); } struct root_plus_size : public size_traits @@ -141,29 +141,29 @@ class list_impl struct data_t : public value_traits { typedef typename list_impl::value_traits value_traits; - explicit data_t(const value_traits &val_traits) + BOOST_INTRUSIVE_FORCEINLINE explicit data_t(const value_traits &val_traits) : value_traits(val_traits) {} root_plus_size root_plus_size_; } data_; - size_traits &priv_size_traits() + BOOST_INTRUSIVE_FORCEINLINE size_traits &priv_size_traits() BOOST_NOEXCEPT { return data_.root_plus_size_; } - const size_traits &priv_size_traits() const + BOOST_INTRUSIVE_FORCEINLINE const size_traits &priv_size_traits() const BOOST_NOEXCEPT { return data_.root_plus_size_; } - const value_traits &priv_value_traits() const + BOOST_INTRUSIVE_FORCEINLINE const value_traits &priv_value_traits() const BOOST_NOEXCEPT { return data_; } - value_traits &priv_value_traits() + BOOST_INTRUSIVE_FORCEINLINE value_traits &priv_value_traits() BOOST_NOEXCEPT { return data_; } typedef typename boost::intrusive::value_traits_pointers ::const_value_traits_ptr const_value_traits_ptr; - const_value_traits_ptr priv_value_traits_ptr() const + BOOST_INTRUSIVE_FORCEINLINE const_value_traits_ptr priv_value_traits_ptr() const BOOST_NOEXCEPT { return pointer_traits::pointer_to(this->priv_value_traits()); } /// @endcond @@ -245,11 +245,13 @@ class list_impl //! are called), but the hooks according to the ValueTraits template parameter //! are set to their default value. //! + //! Throws: Nothing. + //! //! Complexity: Linear to the number of elements in the list, if //! it's a safe-mode or auto-unlink value . Otherwise constant. ~list_impl() { - if(is_safe_autounlink::value){ + BOOST_IF_CONSTEXPR(is_safe_autounlink::value){ this->clear(); node_algorithms::init(this->get_root_node()); } @@ -265,7 +267,7 @@ class list_impl //! Complexity: Constant. //! //! Note: Does not affect the validity of iterators and references. - void push_back(reference value) + void push_back(reference value) BOOST_NOEXCEPT { node_ptr to_insert = priv_value_traits().to_node_ptr(value); BOOST_INTRUSIVE_SAFE_HOOK_DEFAULT_ASSERT(!safemode_or_autounlink || node_algorithms::inited(to_insert)); @@ -283,7 +285,7 @@ class list_impl //! Complexity: Constant. //! //! Note: Does not affect the validity of iterators and references. - void push_front(reference value) + void push_front(reference value) BOOST_NOEXCEPT { node_ptr to_insert = priv_value_traits().to_node_ptr(value); BOOST_INTRUSIVE_SAFE_HOOK_DEFAULT_ASSERT(!safemode_or_autounlink || node_algorithms::inited(to_insert)); @@ -299,7 +301,7 @@ class list_impl //! Complexity: Constant. //! //! Note: Invalidates the iterators (but not the references) to the erased element. - void pop_back() + void pop_back() BOOST_NOEXCEPT { return this->pop_back_and_dispose(detail::null_disposer()); } //! Requires: Disposer::operator()(pointer) shouldn't throw. @@ -314,12 +316,12 @@ class list_impl //! //! Note: Invalidates the iterators to the erased element. template - void pop_back_and_dispose(Disposer disposer) + void pop_back_and_dispose(Disposer disposer) BOOST_NOEXCEPT { node_ptr to_erase = node_traits::get_previous(this->get_root_node()); node_algorithms::unlink(to_erase); this->priv_size_traits().decrement(); - if(safemode_or_autounlink) + BOOST_IF_CONSTEXPR(safemode_or_autounlink) node_algorithms::init(to_erase); disposer(priv_value_traits().to_value_ptr(to_erase)); } @@ -332,7 +334,7 @@ class list_impl //! Complexity: Constant. //! //! Note: Invalidates the iterators (but not the references) to the erased element. - void pop_front() + void pop_front() BOOST_NOEXCEPT { return this->pop_front_and_dispose(detail::null_disposer()); } //! Requires: Disposer::operator()(pointer) shouldn't throw. @@ -347,12 +349,12 @@ class list_impl //! //! Note: Invalidates the iterators to the erased element. template - void pop_front_and_dispose(Disposer disposer) + void pop_front_and_dispose(Disposer disposer) BOOST_NOEXCEPT { node_ptr to_erase = node_traits::get_next(this->get_root_node()); node_algorithms::unlink(to_erase); this->priv_size_traits().decrement(); - if(safemode_or_autounlink) + BOOST_IF_CONSTEXPR(safemode_or_autounlink) node_algorithms::init(to_erase); disposer(priv_value_traits().to_value_ptr(to_erase)); } @@ -362,7 +364,7 @@ class list_impl //! Throws: Nothing. //! //! Complexity: Constant. - reference front() + BOOST_INTRUSIVE_FORCEINLINE reference front() BOOST_NOEXCEPT { return *priv_value_traits().to_value_ptr(node_traits::get_next(this->get_root_node())); } //! Effects: Returns a const_reference to the first element of the list. @@ -370,7 +372,7 @@ class list_impl //! Throws: Nothing. //! //! Complexity: Constant. - const_reference front() const + BOOST_INTRUSIVE_FORCEINLINE const_reference front() const BOOST_NOEXCEPT { return *priv_value_traits().to_value_ptr(node_traits::get_next(this->get_root_node())); } //! Effects: Returns a reference to the last element of the list. @@ -378,7 +380,7 @@ class list_impl //! Throws: Nothing. //! //! Complexity: Constant. - reference back() + BOOST_INTRUSIVE_FORCEINLINE reference back() BOOST_NOEXCEPT { return *priv_value_traits().to_value_ptr(node_traits::get_previous(this->get_root_node())); } //! Effects: Returns a const_reference to the last element of the list. @@ -386,7 +388,7 @@ class list_impl //! Throws: Nothing. //! //! Complexity: Constant. - const_reference back() const + BOOST_INTRUSIVE_FORCEINLINE const_reference back() const BOOST_NOEXCEPT { return *priv_value_traits().to_value_ptr(detail::uncast(node_traits::get_previous(this->get_root_node()))); } //! Effects: Returns an iterator to the first element contained in the list. @@ -394,7 +396,7 @@ class list_impl //! Throws: Nothing. //! //! Complexity: Constant. - iterator begin() + BOOST_INTRUSIVE_FORCEINLINE iterator begin() BOOST_NOEXCEPT { return iterator(node_traits::get_next(this->get_root_node()), this->priv_value_traits_ptr()); } //! Effects: Returns a const_iterator to the first element contained in the list. @@ -402,7 +404,7 @@ class list_impl //! Throws: Nothing. //! //! Complexity: Constant. - const_iterator begin() const + BOOST_INTRUSIVE_FORCEINLINE const_iterator begin() const BOOST_NOEXCEPT { return this->cbegin(); } //! Effects: Returns a const_iterator to the first element contained in the list. @@ -410,7 +412,7 @@ class list_impl //! Throws: Nothing. //! //! Complexity: Constant. - const_iterator cbegin() const + BOOST_INTRUSIVE_FORCEINLINE const_iterator cbegin() const BOOST_NOEXCEPT { return const_iterator(node_traits::get_next(this->get_root_node()), this->priv_value_traits_ptr()); } //! Effects: Returns an iterator to the end of the list. @@ -418,7 +420,7 @@ class list_impl //! Throws: Nothing. //! //! Complexity: Constant. - iterator end() + BOOST_INTRUSIVE_FORCEINLINE iterator end() BOOST_NOEXCEPT { return iterator(this->get_root_node(), this->priv_value_traits_ptr()); } //! Effects: Returns a const_iterator to the end of the list. @@ -426,7 +428,7 @@ class list_impl //! Throws: Nothing. //! //! Complexity: Constant. - const_iterator end() const + BOOST_INTRUSIVE_FORCEINLINE const_iterator end() const BOOST_NOEXCEPT { return this->cend(); } //! Effects: Returns a constant iterator to the end of the list. @@ -434,7 +436,7 @@ class list_impl //! Throws: Nothing. //! //! Complexity: Constant. - const_iterator cend() const + BOOST_INTRUSIVE_FORCEINLINE const_iterator cend() const BOOST_NOEXCEPT { return const_iterator(detail::uncast(this->get_root_node()), this->priv_value_traits_ptr()); } //! Effects: Returns a reverse_iterator pointing to the beginning @@ -443,7 +445,7 @@ class list_impl //! Throws: Nothing. //! //! Complexity: Constant. - reverse_iterator rbegin() + BOOST_INTRUSIVE_FORCEINLINE reverse_iterator rbegin() BOOST_NOEXCEPT { return reverse_iterator(this->end()); } //! Effects: Returns a const_reverse_iterator pointing to the beginning @@ -452,7 +454,7 @@ class list_impl //! Throws: Nothing. //! //! Complexity: Constant. - const_reverse_iterator rbegin() const + BOOST_INTRUSIVE_FORCEINLINE const_reverse_iterator rbegin() const BOOST_NOEXCEPT { return this->crbegin(); } //! Effects: Returns a const_reverse_iterator pointing to the beginning @@ -461,7 +463,7 @@ class list_impl //! Throws: Nothing. //! //! Complexity: Constant. - const_reverse_iterator crbegin() const + BOOST_INTRUSIVE_FORCEINLINE const_reverse_iterator crbegin() const BOOST_NOEXCEPT { return const_reverse_iterator(end()); } //! Effects: Returns a reverse_iterator pointing to the end @@ -470,7 +472,7 @@ class list_impl //! Throws: Nothing. //! //! Complexity: Constant. - reverse_iterator rend() + BOOST_INTRUSIVE_FORCEINLINE reverse_iterator rend() BOOST_NOEXCEPT { return reverse_iterator(begin()); } //! Effects: Returns a const_reverse_iterator pointing to the end @@ -479,7 +481,7 @@ class list_impl //! Throws: Nothing. //! //! Complexity: Constant. - const_reverse_iterator rend() const + BOOST_INTRUSIVE_FORCEINLINE const_reverse_iterator rend() const BOOST_NOEXCEPT { return this->crend(); } //! Effects: Returns a const_reverse_iterator pointing to the end @@ -488,7 +490,7 @@ class list_impl //! Throws: Nothing. //! //! Complexity: Constant. - const_reverse_iterator crend() const + BOOST_INTRUSIVE_FORCEINLINE const_reverse_iterator crend() const BOOST_NOEXCEPT { return const_reverse_iterator(this->begin()); } //! Precondition: end_iterator must be a valid end iterator @@ -499,7 +501,7 @@ class list_impl //! Throws: Nothing. //! //! Complexity: Constant. - static list_impl &container_from_end_iterator(iterator end_iterator) + BOOST_INTRUSIVE_FORCEINLINE static list_impl &container_from_end_iterator(iterator end_iterator) BOOST_NOEXCEPT { return list_impl::priv_container_from_end_iterator(end_iterator); } //! Precondition: end_iterator must be a valid end const_iterator @@ -510,7 +512,7 @@ class list_impl //! Throws: Nothing. //! //! Complexity: Constant. - static const list_impl &container_from_end_iterator(const_iterator end_iterator) + BOOST_INTRUSIVE_FORCEINLINE static const list_impl &container_from_end_iterator(const_iterator end_iterator) BOOST_NOEXCEPT { return list_impl::priv_container_from_end_iterator(end_iterator); } //! Effects: Returns the number of the elements contained in the list. @@ -521,9 +523,9 @@ class list_impl //! if constant-time size option is disabled. Constant time otherwise. //! //! Note: Does not affect the validity of iterators and references. - size_type size() const + BOOST_INTRUSIVE_FORCEINLINE size_type size() const BOOST_NOEXCEPT { - if(constant_time_size) + BOOST_IF_CONSTEXPR(constant_time_size) return this->priv_size_traits().get_size(); else return node_algorithms::count(this->get_root_node()) - 1; @@ -536,7 +538,7 @@ class list_impl //! Complexity: Constant. //! //! Note: Does not affect the validity of iterators and references. - bool empty() const + BOOST_INTRUSIVE_FORCEINLINE bool empty() const BOOST_NOEXCEPT { return node_algorithms::unique(this->get_root_node()); } //! Effects: Swaps the elements of x and *this. @@ -546,7 +548,7 @@ class list_impl //! Complexity: Constant. //! //! Note: Does not affect the validity of iterators and references. - void swap(list_impl& other) + void swap(list_impl& other) BOOST_NOEXCEPT { node_algorithms::swap_nodes(this->get_root_node(), other.get_root_node()); this->priv_size_traits().swap(other.priv_size_traits()); @@ -561,7 +563,7 @@ class list_impl //! Complexity: Linear to the number of shifts. //! //! Note: Does not affect the validity of iterators and references. - void shift_backwards(size_type n = 1) + BOOST_INTRUSIVE_FORCEINLINE void shift_backwards(size_type n = 1) BOOST_NOEXCEPT { node_algorithms::move_forward(this->get_root_node(), n); } //! Effects: Moves forward all the elements, so that the second @@ -573,7 +575,7 @@ class list_impl //! Complexity: Linear to the number of shifts. //! //! Note: Does not affect the validity of iterators and references. - void shift_forward(size_type n = 1) + BOOST_INTRUSIVE_FORCEINLINE void shift_forward(size_type n = 1) BOOST_NOEXCEPT { node_algorithms::move_backwards(this->get_root_node(), n); } //! Effects: Erases the element pointed by i of the list. @@ -588,7 +590,7 @@ class list_impl //! //! Note: Invalidates the iterators (but not the references) to the //! erased element. - iterator erase(const_iterator i) + BOOST_INTRUSIVE_FORCEINLINE iterator erase(const_iterator i) BOOST_NOEXCEPT { return this->erase_and_dispose(i, detail::null_disposer()); } //! Requires: b and e must be valid iterators to elements in *this. @@ -606,9 +608,9 @@ class list_impl //! //! Note: Invalidates the iterators (but not the references) to the //! erased elements. - iterator erase(const_iterator b, const_iterator e) + BOOST_INTRUSIVE_FORCEINLINE iterator erase(const_iterator b, const_iterator e) BOOST_NOEXCEPT { - if(safemode_or_autounlink || constant_time_size){ + BOOST_IF_CONSTEXPR(safemode_or_autounlink || constant_time_size){ return this->erase_and_dispose(b, e, detail::null_disposer()); } else{ @@ -633,14 +635,15 @@ class list_impl //! //! Note: Invalidates the iterators (but not the references) to the //! erased elements. - iterator erase(const_iterator b, const_iterator e, size_type n) + iterator erase(const_iterator b, const_iterator e, size_type n) BOOST_NOEXCEPT { BOOST_INTRUSIVE_INVARIANT_ASSERT(node_algorithms::distance(b.pointed_node(), e.pointed_node()) == n); - if(safemode_or_autounlink || constant_time_size){ + (void)n; + BOOST_IF_CONSTEXPR(safemode_or_autounlink){ return this->erase_and_dispose(b, e, detail::null_disposer()); } else{ - if(constant_time_size){ + BOOST_IF_CONSTEXPR(constant_time_size){ this->priv_size_traits().decrease(n); } node_algorithms::unlink(b.pointed_node(), e.pointed_node()); @@ -663,13 +666,13 @@ class list_impl //! //! Note: Invalidates the iterators to the erased element. template - iterator erase_and_dispose(const_iterator i, Disposer disposer) + iterator erase_and_dispose(const_iterator i, Disposer disposer) BOOST_NOEXCEPT { node_ptr to_erase(i.pointed_node()); ++i; node_algorithms::unlink(to_erase); this->priv_size_traits().decrement(); - if(safemode_or_autounlink) + BOOST_IF_CONSTEXPR(safemode_or_autounlink) node_algorithms::init(to_erase); disposer(this->priv_value_traits().to_value_ptr(to_erase)); return i.unconst(); @@ -677,7 +680,7 @@ class list_impl #if !defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED) template - iterator erase_and_dispose(iterator i, Disposer disposer) + iterator erase_and_dispose(iterator i, Disposer disposer) BOOST_NOEXCEPT { return this->erase_and_dispose(const_iterator(i), disposer); } #endif @@ -696,14 +699,14 @@ class list_impl //! //! Note: Invalidates the iterators to the erased elements. template - iterator erase_and_dispose(const_iterator b, const_iterator e, Disposer disposer) + iterator erase_and_dispose(const_iterator b, const_iterator e, Disposer disposer) BOOST_NOEXCEPT { node_ptr bp(b.pointed_node()), ep(e.pointed_node()); node_algorithms::unlink(bp, ep); while(bp != ep){ node_ptr to_erase(bp); bp = node_traits::get_next(bp); - if(safemode_or_autounlink) + BOOST_IF_CONSTEXPR(safemode_or_autounlink) node_algorithms::init(to_erase); disposer(priv_value_traits().to_value_ptr(to_erase)); this->priv_size_traits().decrement(); @@ -720,9 +723,9 @@ class list_impl //! if it's a safe-mode or auto-unlink value_type. Constant time otherwise. //! //! Note: Invalidates the iterators (but not the references) to the erased elements. - void clear() + void clear() BOOST_NOEXCEPT { - if(safemode_or_autounlink){ + BOOST_IF_CONSTEXPR(safemode_or_autounlink){ this->clear_and_dispose(detail::null_disposer()); } else{ @@ -743,13 +746,13 @@ class list_impl //! //! Note: Invalidates the iterators to the erased elements. template - void clear_and_dispose(Disposer disposer) + void clear_and_dispose(Disposer disposer) BOOST_NOEXCEPT { const_iterator it(this->begin()), itend(this->end()); while(it != itend){ node_ptr to_erase(it.pointed_node()); ++it; - if(safemode_or_autounlink) + BOOST_IF_CONSTEXPR(safemode_or_autounlink) node_algorithms::init(to_erase); disposer(priv_value_traits().to_value_ptr(to_erase)); } @@ -822,7 +825,7 @@ class list_impl //! Complexity: Constant time. No copy constructors are called. //! //! Note: Does not affect the validity of iterators and references. - iterator insert(const_iterator p, reference value) + iterator insert(const_iterator p, reference value) BOOST_NOEXCEPT { node_ptr to_insert = this->priv_value_traits().to_node_ptr(value); BOOST_INTRUSIVE_SAFE_HOOK_DEFAULT_ASSERT(!safemode_or_autounlink || node_algorithms::inited(to_insert)); @@ -843,7 +846,7 @@ class list_impl //! //! Note: Does not affect the validity of iterators and references. template - void insert(const_iterator p, Iterator b, Iterator e) + void insert(const_iterator p, Iterator b, Iterator e) BOOST_NOEXCEPT { for (; b != e; ++b) this->insert(p, *b); @@ -865,7 +868,7 @@ class list_impl //! Note: Invalidates the iterators (but not the references) //! to the erased elements. template - void assign(Iterator b, Iterator e) + void assign(Iterator b, Iterator e) BOOST_NOEXCEPT { this->clear(); this->insert(this->cend(), b, e); @@ -888,7 +891,7 @@ class list_impl //! Note: Invalidates the iterators (but not the references) //! to the erased elements. template - void dispose_and_assign(Disposer disposer, Iterator b, Iterator e) + void dispose_and_assign(Disposer disposer, Iterator b, Iterator e) BOOST_NOEXCEPT { this->clear_and_dispose(disposer); this->insert(this->cend(), b, e); @@ -905,7 +908,7 @@ class list_impl //! //! Note: Iterators of values obtained from list x now point to elements of //! this list. Iterators of this list and all the references are not invalidated. - void splice(const_iterator p, list_impl& x) + void splice(const_iterator p, list_impl& x) BOOST_NOEXCEPT { if(!x.empty()){ node_algorithms::transfer @@ -930,7 +933,7 @@ class list_impl //! //! Note: Iterators of values obtained from list x now point to elements of this //! list. Iterators of this list and all the references are not invalidated. - void splice(const_iterator p, list_impl&x, const_iterator new_ele) + void splice(const_iterator p, list_impl&x, const_iterator new_ele) BOOST_NOEXCEPT { node_algorithms::transfer(p.pointed_node(), new_ele.pointed_node()); x.priv_size_traits().decrement(); @@ -950,9 +953,9 @@ class list_impl //! //! Note: Iterators of values obtained from list x now point to elements of this //! list. Iterators of this list and all the references are not invalidated. - void splice(const_iterator p, list_impl&x, const_iterator f, const_iterator e) + void splice(const_iterator p, list_impl&x, const_iterator f, const_iterator e) BOOST_NOEXCEPT { - if(constant_time_size) + BOOST_IF_CONSTEXPR(constant_time_size) this->splice(p, x, f, e, node_algorithms::distance(f.pointed_node(), e.pointed_node())); else this->splice(p, x, f, e, 1);//intrusive::iterator_distance is a dummy value @@ -971,10 +974,10 @@ class list_impl //! //! Note: Iterators of values obtained from list x now point to elements of this //! list. Iterators of this list and all the references are not invalidated. - void splice(const_iterator p, list_impl&x, const_iterator f, const_iterator e, size_type n) + void splice(const_iterator p, list_impl&x, const_iterator f, const_iterator e, size_type n) BOOST_NOEXCEPT { if(n){ - if(constant_time_size){ + BOOST_IF_CONSTEXPR(constant_time_size){ BOOST_INTRUSIVE_INVARIANT_ASSERT(n == node_algorithms::distance(f.pointed_node(), e.pointed_node())); node_algorithms::transfer(p.pointed_node(), f.pointed_node(), e.pointed_node()); size_traits &thist = this->priv_size_traits(); @@ -988,19 +991,19 @@ class list_impl } } - //! Effects: This function sorts the list *this according to std::less. + //! Effects: This function sorts the list *this according to operator <. //! The sort is stable, that is, the relative order of equivalent elements is preserved. //! //! Throws: If value_traits::node_traits::node //! constructor throws (this does not happen with predefined Boost.Intrusive hooks) - //! or std::less throws. Basic guarantee. + //! or operator < throws. Basic guarantee. //! //! Notes: Iterators and references are not invalidated. //! //! Complexity: The number of comparisons is approximately N log N, where N //! is the list's size. void sort() - { this->sort(std::less()); } + { this->sort(value_less()); } //! Requires: p must be a comparison function that induces a strict weak ordering //! @@ -1043,18 +1046,18 @@ class list_impl } //! Effects: This function removes all of x's elements and inserts them - //! in order into *this according to std::less. The merge is stable; + //! in order into *this according to operator <. The merge is stable; //! that is, if an element from *this is equivalent to one from x, then the element //! from *this will precede the one from x. //! - //! Throws: If std::less throws. Basic guarantee. + //! Throws: If operator < throws. Basic guarantee. //! //! Complexity: This function is linear time: it performs at most //! size() + x.size() - 1 comparisons. //! //! Note: Iterators and references are not invalidated void merge(list_impl& x) - { this->merge(x, std::less()); } + { this->merge(x, value_less()); } //! Requires: p must be a comparison function that induces a strict weak //! ordering and both *this and x must be sorted according to that ordering @@ -1102,19 +1105,19 @@ class list_impl //! Complexity: This function is linear time. //! //! Note: Iterators and references are not invalidated - void reverse() + void reverse() BOOST_NOEXCEPT { node_algorithms::reverse(this->get_root_node()); } //! Effects: Removes all the elements that compare equal to value. //! No destructors are called. //! - //! Throws: If std::equal_to throws. Basic guarantee. + //! Throws: If operator == throws. Basic guarantee. //! //! Complexity: Linear time. It performs exactly size() comparisons for equality. //! //! Note: The relative order of elements that are not removed is unchanged, //! and iterators to elements that are not removed remain valid. - void remove(const_reference value) + void remove(const_reference value) BOOST_NOEXCEPT { this->remove_if(detail::equal_to_value(value)); } //! Requires: Disposer::operator()(pointer) shouldn't throw. @@ -1122,14 +1125,14 @@ class list_impl //! Effects: Removes all the elements that compare equal to value. //! Disposer::operator()(pointer) is called for every removed element. //! - //! Throws: If std::equal_to throws. Basic guarantee. + //! Throws: If operator == throws. Basic guarantee. //! //! Complexity: Linear time. It performs exactly size() comparisons for equality. //! //! Note: The relative order of elements that are not removed is unchanged, //! and iterators to elements that are not removed remain valid. template - void remove_and_dispose(const_reference value, Disposer disposer) + void remove_and_dispose(const_reference value, Disposer disposer) BOOST_NOEXCEPT { this->remove_and_dispose_if(detail::equal_to_value(value), disposer); } //! Effects: Removes all the elements for which a specified @@ -1267,7 +1270,7 @@ class list_impl //! Note: Iterators and references are not invalidated. //! This static function is available only if the value traits //! is stateless. - static iterator s_iterator_to(reference value) + static iterator s_iterator_to(reference value) BOOST_NOEXCEPT { BOOST_STATIC_ASSERT((!stateful_value_traits)); BOOST_INTRUSIVE_INVARIANT_ASSERT(!node_algorithms::inited(value_traits::to_node_ptr(value))); @@ -1285,7 +1288,7 @@ class list_impl //! Note: Iterators and references are not invalidated. //! This static function is available only if the value traits //! is stateless. - static const_iterator s_iterator_to(const_reference value) + static const_iterator s_iterator_to(const_reference value) BOOST_NOEXCEPT { BOOST_STATIC_ASSERT((!stateful_value_traits)); reference r =*detail::uncast(pointer_traits::pointer_to(value)); @@ -1302,7 +1305,7 @@ class list_impl //! Complexity: Constant time. //! //! Note: Iterators and references are not invalidated. - iterator iterator_to(reference value) + iterator iterator_to(reference value) BOOST_NOEXCEPT { BOOST_INTRUSIVE_INVARIANT_ASSERT(!node_algorithms::inited(this->priv_value_traits().to_node_ptr(value))); return iterator(this->priv_value_traits().to_node_ptr(value), this->priv_value_traits_ptr()); @@ -1317,7 +1320,7 @@ class list_impl //! Complexity: Constant time. //! //! Note: Iterators and references are not invalidated. - const_iterator iterator_to(const_reference value) const + const_iterator iterator_to(const_reference value) const BOOST_NOEXCEPT { reference r = *detail::uncast(pointer_traits::pointer_to(value)); BOOST_INTRUSIVE_INVARIANT_ASSERT(!node_algorithms::inited(this->priv_value_traits().to_node_ptr(r))); @@ -1341,11 +1344,11 @@ class list_impl == (node_traits::get_previous(header_ptr) == header_ptr)); if (node_traits::get_next(header_ptr) == header_ptr) { - if (constant_time_size) + BOOST_IF_CONSTEXPR(constant_time_size) BOOST_INTRUSIVE_INVARIANT_ASSERT(this->priv_size_traits().get_size() == 0); return; } - size_t node_count = 0; + size_t node_count = 0; (void)node_count; const_node_ptr p = header_ptr; while (true) { @@ -1356,7 +1359,7 @@ class list_impl if (p == header_ptr) break; ++node_count; } - if (constant_time_size) + BOOST_IF_CONSTEXPR(constant_time_size) BOOST_INTRUSIVE_INVARIANT_ASSERT(this->priv_size_traits().get_size() == node_count); } @@ -1368,28 +1371,28 @@ class list_impl return ::boost::intrusive::algo_equal(x.cbegin(), x.cend(), y.cbegin(), y.cend()); } - friend bool operator!=(const list_impl &x, const list_impl &y) + BOOST_INTRUSIVE_FORCEINLINE friend bool operator!=(const list_impl &x, const list_impl &y) { return !(x == y); } - friend bool operator<(const list_impl &x, const list_impl &y) + BOOST_INTRUSIVE_FORCEINLINE friend bool operator<(const list_impl &x, const list_impl &y) { return ::boost::intrusive::algo_lexicographical_compare(x.begin(), x.end(), y.begin(), y.end()); } - friend bool operator>(const list_impl &x, const list_impl &y) + BOOST_INTRUSIVE_FORCEINLINE friend bool operator>(const list_impl &x, const list_impl &y) { return y < x; } - friend bool operator<=(const list_impl &x, const list_impl &y) + BOOST_INTRUSIVE_FORCEINLINE friend bool operator<=(const list_impl &x, const list_impl &y) { return !(y < x); } - friend bool operator>=(const list_impl &x, const list_impl &y) + BOOST_INTRUSIVE_FORCEINLINE friend bool operator>=(const list_impl &x, const list_impl &y) { return !(x < y); } - friend void swap(list_impl &x, list_impl &y) + BOOST_INTRUSIVE_FORCEINLINE friend void swap(list_impl &x, list_impl &y) BOOST_NOEXCEPT { x.swap(y); } /// @cond private: - static list_impl &priv_container_from_end_iterator(const const_iterator &end_iterator) + static list_impl &priv_container_from_end_iterator(const const_iterator &end_iterator) BOOST_NOEXCEPT { BOOST_STATIC_ASSERT((has_container_from_iterator)); node_ptr p = end_iterator.pointed_node(); @@ -1499,10 +1502,10 @@ class list BOOST_INTRUSIVE_FORCEINLINE void clone_from(BOOST_RV_REF(list) src, Cloner cloner, Disposer disposer) { Base::clone_from(BOOST_MOVE_BASE(Base, src), cloner, disposer); } - BOOST_INTRUSIVE_FORCEINLINE static list &container_from_end_iterator(iterator end_iterator) + BOOST_INTRUSIVE_FORCEINLINE static list &container_from_end_iterator(iterator end_iterator) BOOST_NOEXCEPT { return static_cast(Base::container_from_end_iterator(end_iterator)); } - BOOST_INTRUSIVE_FORCEINLINE static const list &container_from_end_iterator(const_iterator end_iterator) + BOOST_INTRUSIVE_FORCEINLINE static const list &container_from_end_iterator(const_iterator end_iterator) BOOST_NOEXCEPT { return static_cast(Base::container_from_end_iterator(end_iterator)); } }; diff --git a/include/boost/intrusive/list_hook.hpp b/include/boost/intrusive/list_hook.hpp index 892e4e20d..03cf9a563 100644 --- a/include/boost/intrusive/list_hook.hpp +++ b/include/boost/intrusive/list_hook.hpp @@ -96,7 +96,7 @@ class list_base_hook //! initializes the node to an unlinked state. //! //! Throws: Nothing. - list_base_hook(); + list_base_hook() BOOST_NOEXCEPT; //! Effects: If link_mode is \c auto_unlink or \c safe_link //! initializes the node to an unlinked state. The argument is ignored. @@ -107,7 +107,7 @@ class list_base_hook //! makes classes using the hook STL-compliant without forcing the //! user to do some additional work. \c swap can be used to emulate //! move-semantics. - list_base_hook(const list_base_hook& ); + list_base_hook(const list_base_hook& ) BOOST_NOEXCEPT; //! Effects: Empty function. The argument is ignored. //! @@ -117,7 +117,7 @@ class list_base_hook //! makes classes using the hook STL-compliant without forcing the //! user to do some additional work. \c swap can be used to emulate //! move-semantics. - list_base_hook& operator=(const list_base_hook& ); + list_base_hook& operator=(const list_base_hook& ) BOOST_NOEXCEPT; //! Effects: If link_mode is \c normal_link, the destructor does //! nothing (ie. no code is generated). If link_mode is \c safe_link and the @@ -139,7 +139,7 @@ class list_base_hook //! Complexity: Constant //! //! Throws: Nothing. - void swap_nodes(list_base_hook &other); + void swap_nodes(list_base_hook &other) BOOST_NOEXCEPT; //! Precondition: link_mode must be \c safe_link or \c auto_unlink. //! @@ -154,7 +154,7 @@ class list_base_hook //! This function is only allowed if link_mode is \c auto_unlink. //! //! Throws: Nothing. - void unlink(); + void unlink() BOOST_NOEXCEPT; #endif }; @@ -219,7 +219,7 @@ class list_member_hook //! initializes the node to an unlinked state. //! //! Throws: Nothing. - list_member_hook(); + list_member_hook() BOOST_NOEXCEPT; //! Effects: If link_mode is \c auto_unlink or \c safe_link //! initializes the node to an unlinked state. The argument is ignored. @@ -230,7 +230,7 @@ class list_member_hook //! makes classes using the hook STL-compliant without forcing the //! user to do some additional work. \c swap can be used to emulate //! move-semantics. - list_member_hook(const list_member_hook& ); + list_member_hook(const list_member_hook& ) BOOST_NOEXCEPT; //! Effects: Empty function. The argument is ignored. //! @@ -240,7 +240,7 @@ class list_member_hook //! makes classes using the hook STL-compliant without forcing the //! user to do some additional work. \c swap can be used to emulate //! move-semantics. - list_member_hook& operator=(const list_member_hook& ); + list_member_hook& operator=(const list_member_hook& ) BOOST_NOEXCEPT; //! Effects: If link_mode is \c normal_link, the destructor does //! nothing (ie. no code is generated). If link_mode is \c safe_link and the @@ -262,7 +262,7 @@ class list_member_hook //! Complexity: Constant //! //! Throws: Nothing. - void swap_nodes(list_member_hook &other); + void swap_nodes(list_member_hook &other) BOOST_NOEXCEPT; //! Precondition: link_mode must be \c safe_link or \c auto_unlink. //! @@ -277,7 +277,7 @@ class list_member_hook //! This function is only allowed if link_mode is \c auto_unlink. //! //! Throws: Nothing. - void unlink(); + void unlink() BOOST_NOEXCEPT; #endif }; diff --git a/include/boost/intrusive/member_value_traits.hpp b/include/boost/intrusive/member_value_traits.hpp index 0ab7ffb11..f673b6417 100644 --- a/include/boost/intrusive/member_value_traits.hpp +++ b/include/boost/intrusive/member_value_traits.hpp @@ -57,19 +57,19 @@ struct member_value_traits typedef const value_type & const_reference; static const link_mode_type link_mode = LinkMode; - BOOST_INTRUSIVE_FORCEINLINE static node_ptr to_node_ptr(reference value) + BOOST_INTRUSIVE_FORCEINLINE static node_ptr to_node_ptr(reference value) BOOST_NOEXCEPT { return pointer_traits::pointer_to(value.*PtrToMember); } - BOOST_INTRUSIVE_FORCEINLINE static const_node_ptr to_node_ptr(const_reference value) + BOOST_INTRUSIVE_FORCEINLINE static const_node_ptr to_node_ptr(const_reference value) BOOST_NOEXCEPT { return pointer_traits::pointer_to(value.*PtrToMember); } - BOOST_INTRUSIVE_FORCEINLINE static pointer to_value_ptr(const node_ptr &n) + BOOST_INTRUSIVE_FORCEINLINE static pointer to_value_ptr(node_ptr n) BOOST_NOEXCEPT { return pointer_traits::pointer_to(*detail::parent_from_member (boost::movelib::to_raw_pointer(n), PtrToMember)); } - BOOST_INTRUSIVE_FORCEINLINE static const_pointer to_value_ptr(const const_node_ptr &n) + BOOST_INTRUSIVE_FORCEINLINE static const_pointer to_value_ptr(const_node_ptr n) BOOST_NOEXCEPT { return pointer_traits::pointer_to(*detail::parent_from_member (boost::movelib::to_raw_pointer(n), PtrToMember)); diff --git a/include/boost/intrusive/options.hpp b/include/boost/intrusive/options.hpp index 8bf9ca8a8..ff6902e8f 100644 --- a/include/boost/intrusive/options.hpp +++ b/include/boost/intrusive/options.hpp @@ -212,13 +212,22 @@ BOOST_INTRUSIVE_OPTION_CONSTANT(store_hash, bool, Enabled, store_hash) //!with the same key. BOOST_INTRUSIVE_OPTION_CONSTANT(optimize_multikey, bool, Enabled, optimize_multikey) -//!This option setter specifies if the bucket array will be always power of two. +//!This option setter specifies if the length of the bucket array provided by +//!the user will always be power of two. //!This allows using masks instead of the default modulo operation to determine //!the bucket number from the hash value, leading to better performance. -//!In debug mode, if power of two buckets mode is activated, the bucket length -//!will be checked with assertions. +//!In debug mode, the provided bucket array length will be checked with assertions. BOOST_INTRUSIVE_OPTION_CONSTANT(power_2_buckets, bool, Enabled, power_2_buckets) +//!WARNING: this option is EXPERIMENTAL, don't use it in production code +//!This option setter specifies if the length of the bucket array provided by +//!the user will always be a value specified by the +//!suggested_upper|lower_bucket_count call. This allows the use of some +//!precomputed values and speeds hash to bucket index operations, leading +//!to better performance. +//!In debug mode, the provided bucket array length will be checked with assertions. +BOOST_INTRUSIVE_OPTION_CONSTANT(fastmod_buckets, bool, Enabled, fastmod_buckets) + //!This option setter specifies if the container will cache a pointer to the first //!non-empty bucket so that begin() is always constant-time. //!This is specially helpful when we can have containers with a few elements @@ -241,6 +250,11 @@ BOOST_INTRUSIVE_OPTION_CONSTANT(compare_hash, bool, Enabled, compare_hash) //!(rehashing the whole bucket array) is not admisible. BOOST_INTRUSIVE_OPTION_CONSTANT(incremental, bool, Enabled, incremental) +//!This option setter specifies if the buckets (which form a singly linked lists of nodes) +//!are linear (true) or circular (false, default value). Linear buckets can improve performance +//!in some cases, but the container loses some features like obtaining an iterator from a value. +BOOST_INTRUSIVE_OPTION_CONSTANT(linear_buckets, bool, Enabled, linear_buckets) + /// @cond struct hook_defaults diff --git a/include/boost/intrusive/pack_options.hpp b/include/boost/intrusive/pack_options.hpp index ff07678ff..66761d762 100644 --- a/include/boost/intrusive/pack_options.hpp +++ b/include/boost/intrusive/pack_options.hpp @@ -19,6 +19,8 @@ # pragma once #endif +#include + namespace boost { namespace intrusive { @@ -97,19 +99,19 @@ struct pack_options #else //index_tuple -template +template struct index_tuple{}; //build_number_seq template > struct build_number_seq; -template +template struct build_number_seq > : build_number_seq > {}; -template +template struct build_number_seq<0, index_tuple > { typedef index_tuple type; }; @@ -121,10 +123,10 @@ struct typelist template struct invert_typelist; -template +template struct typelist_element; -template +template struct typelist_element > { typedef typename typelist_element >::type type; @@ -136,7 +138,7 @@ struct typelist_element<0, typelist > typedef Head type; }; -template +template typelist >::type...> inverted_typelist(index_tuple, typelist) { @@ -158,7 +160,7 @@ template struct invert_typelist_impl; -template +template struct invert_typelist_impl< Typelist, index_tuple > { static const std::size_t last_idx = sizeof_typelist::value - 1; @@ -166,7 +168,7 @@ struct invert_typelist_impl< Typelist, index_tuple > ::type...> type; }; -template +template struct invert_typelist_impl< Typelist, index_tuple > { typedef Typelist type; @@ -249,6 +251,8 @@ struct OPTION_NAME \ template< TYPE VALUE> \ struct OPTION_NAME \ { \ + static const TYPE value = VALUE; \ + \ template \ struct pack : Base \ { \ diff --git a/include/boost/intrusive/parent_from_member.hpp b/include/boost/intrusive/parent_from_member.hpp index a9a9293c7..9c8f167da 100644 --- a/include/boost/intrusive/parent_from_member.hpp +++ b/include/boost/intrusive/parent_from_member.hpp @@ -30,7 +30,7 @@ namespace intrusive { //! Note: this function does not work with pointer to members that rely on //! virtual inheritance. template -BOOST_INTRUSIVE_FORCEINLINE Parent *get_parent_from_member(Member *member, const Member Parent::* ptr_to_member) +BOOST_INTRUSIVE_FORCEINLINE Parent *get_parent_from_member(Member *member, const Member Parent::* ptr_to_member) BOOST_NOEXCEPT { return ::boost::intrusive::detail::parent_from_member(member, ptr_to_member); } //! Given a const pointer to a member and its corresponding const pointer to data member, @@ -38,7 +38,7 @@ BOOST_INTRUSIVE_FORCEINLINE Parent *get_parent_from_member(Member *member, const //! Note: this function does not work with pointer to members that rely on //! virtual inheritance. template -BOOST_INTRUSIVE_FORCEINLINE const Parent *get_parent_from_member(const Member *member, const Member Parent::* ptr_to_member) +BOOST_INTRUSIVE_FORCEINLINE const Parent *get_parent_from_member(const Member *member, const Member Parent::* ptr_to_member) BOOST_NOEXCEPT { return ::boost::intrusive::detail::parent_from_member(member, ptr_to_member); } } //namespace intrusive { diff --git a/include/boost/intrusive/pointer_plus_bits.hpp b/include/boost/intrusive/pointer_plus_bits.hpp index 2130f3c41..b967bb636 100644 --- a/include/boost/intrusive/pointer_plus_bits.hpp +++ b/include/boost/intrusive/pointer_plus_bits.hpp @@ -81,19 +81,19 @@ struct pointer_plus_bits static const uintptr_t Mask = uintptr_t((uintptr_t(1u) << NumBits) - 1); typedef T* pointer; - BOOST_INTRUSIVE_FORCEINLINE static pointer get_pointer(pointer n) + BOOST_INTRUSIVE_FORCEINLINE static pointer get_pointer(pointer n) BOOST_NOEXCEPT { return pointer(uintptr_t(n) & uintptr_t(~Mask)); } - BOOST_INTRUSIVE_FORCEINLINE static void set_pointer(pointer &n, pointer p) + BOOST_INTRUSIVE_FORCEINLINE static void set_pointer(pointer &n, pointer p) BOOST_NOEXCEPT { BOOST_INTRUSIVE_INVARIANT_ASSERT(0 == (uintptr_t(p) & Mask)); n = pointer(uintptr_t(p) | (uintptr_t(n) & Mask)); } - BOOST_INTRUSIVE_FORCEINLINE static std::size_t get_bits(pointer n) + BOOST_INTRUSIVE_FORCEINLINE static std::size_t get_bits(pointer n) BOOST_NOEXCEPT { return std::size_t(uintptr_t(n) & Mask); } - BOOST_INTRUSIVE_FORCEINLINE static void set_bits(pointer &n, std::size_t c) + BOOST_INTRUSIVE_FORCEINLINE static void set_bits(pointer &n, std::size_t c) BOOST_NOEXCEPT { BOOST_INTRUSIVE_INVARIANT_ASSERT(uintptr_t(c) <= Mask); n = pointer(uintptr_t((get_pointer)(n)) | uintptr_t(c)); diff --git a/include/boost/intrusive/pointer_traits.hpp b/include/boost/intrusive/pointer_traits.hpp index 9e8d36496..1b2ed0576 100644 --- a/include/boost/intrusive/pointer_traits.hpp +++ b/include/boost/intrusive/pointer_traits.hpp @@ -46,6 +46,7 @@ BOOST_INTRUSIVE_HAS_MEMBER_FUNC_CALLED_IGNORE_SIGNATURE(has_member_function_call BOOST_INTRUSIVE_INSTANTIATE_EVAL_DEFAULT_TYPE_TMPLT(element_type) BOOST_INTRUSIVE_INSTANTIATE_DEFAULT_TYPE_TMPLT(difference_type) +BOOST_INTRUSIVE_INSTANTIATE_DEFAULT_TYPE_TMPLT(size_type) BOOST_INTRUSIVE_INSTANTIATE_DEFAULT_TYPE_TMPLT(reference) BOOST_INTRUSIVE_INSTANTIATE_DEFAULT_TYPE_TMPLT(value_traits_ptr) @@ -103,7 +104,13 @@ struct pointer_traits (boost::intrusive::detail::, Ptr, difference_type, std::ptrdiff_t) difference_type; typedef BOOST_INTRUSIVE_OBTAIN_TYPE_WITH_DEFAULT - (boost::intrusive::detail::, Ptr, reference, typename boost::intrusive::detail::unvoid_ref::type) reference; + ( boost::intrusive::detail::, Ptr, size_type + , typename boost::move_detail:: + make_unsigned::type) size_type; + + typedef BOOST_INTRUSIVE_OBTAIN_TYPE_WITH_DEFAULT + ( boost::intrusive::detail::, Ptr, reference + , typename boost::intrusive::detail::unvoid_ref::type) reference; // template struct rebind_pointer { @@ -123,7 +130,7 @@ struct pointer_traits //! //! Note: For non-conforming compilers only the existence of a member function called //! pointer_to is checked. - BOOST_INTRUSIVE_FORCEINLINE static pointer pointer_to(reference r) + BOOST_INTRUSIVE_FORCEINLINE static pointer pointer_to(reference r) BOOST_NOEXCEPT { //Non-standard extension, it does not require Ptr::pointer_to. If not present //tries to converts &r to pointer. @@ -143,7 +150,7 @@ struct pointer_traits //! Note: For non-conforming compilers only the existence of a member function called //! static_cast_from is checked. template - BOOST_INTRUSIVE_FORCEINLINE static pointer static_cast_from(const UPtr &uptr) + BOOST_INTRUSIVE_FORCEINLINE static pointer static_cast_from(const UPtr &uptr) BOOST_NOEXCEPT { typedef const UPtr &RefArg; const bool value = boost::intrusive::detail:: @@ -164,7 +171,7 @@ struct pointer_traits //! Note: For non-conforming compilers only the existence of a member function called //! const_cast_from is checked. template - BOOST_INTRUSIVE_FORCEINLINE static pointer const_cast_from(const UPtr &uptr) + BOOST_INTRUSIVE_FORCEINLINE static pointer const_cast_from(const UPtr &uptr) BOOST_NOEXCEPT { typedef const UPtr &RefArg; const bool value = boost::intrusive::detail:: @@ -185,7 +192,7 @@ struct pointer_traits //! Note: For non-conforming compilers only the existence of a member function called //! dynamic_cast_from is checked. template - BOOST_INTRUSIVE_FORCEINLINE static pointer dynamic_cast_from(const UPtr &uptr) + BOOST_INTRUSIVE_FORCEINLINE static pointer dynamic_cast_from(const UPtr &uptr) BOOST_NOEXCEPT { typedef const UPtr &RefArg; const bool value = boost::intrusive::detail:: @@ -201,46 +208,46 @@ struct pointer_traits private: //priv_to_raw_pointer template - BOOST_INTRUSIVE_FORCEINLINE static T* to_raw_pointer(T* p) + BOOST_INTRUSIVE_FORCEINLINE static T* to_raw_pointer(T* p) BOOST_NOEXCEPT { return p; } template BOOST_INTRUSIVE_FORCEINLINE static typename pointer_traits::element_type* - to_raw_pointer(const Pointer &p) + to_raw_pointer(const Pointer &p) BOOST_NOEXCEPT { return pointer_traits::to_raw_pointer(p.operator->()); } //priv_pointer_to - BOOST_INTRUSIVE_FORCEINLINE static pointer priv_pointer_to(boost::intrusive::detail::true_, reference r) + BOOST_INTRUSIVE_FORCEINLINE static pointer priv_pointer_to(boost::intrusive::detail::true_, reference r) BOOST_NOEXCEPT { return Ptr::pointer_to(r); } - BOOST_INTRUSIVE_FORCEINLINE static pointer priv_pointer_to(boost::intrusive::detail::false_, reference r) + BOOST_INTRUSIVE_FORCEINLINE static pointer priv_pointer_to(boost::intrusive::detail::false_, reference r) BOOST_NOEXCEPT { return pointer(boost::intrusive::detail::addressof(r)); } //priv_static_cast_from template - BOOST_INTRUSIVE_FORCEINLINE static pointer priv_static_cast_from(boost::intrusive::detail::true_, const UPtr &uptr) + BOOST_INTRUSIVE_FORCEINLINE static pointer priv_static_cast_from(boost::intrusive::detail::true_, const UPtr &uptr) BOOST_NOEXCEPT { return Ptr::static_cast_from(uptr); } template - BOOST_INTRUSIVE_FORCEINLINE static pointer priv_static_cast_from(boost::intrusive::detail::false_, const UPtr &uptr) + BOOST_INTRUSIVE_FORCEINLINE static pointer priv_static_cast_from(boost::intrusive::detail::false_, const UPtr &uptr) BOOST_NOEXCEPT { return uptr ? pointer_to(*static_cast(to_raw_pointer(uptr))) : pointer(); } //priv_const_cast_from template - BOOST_INTRUSIVE_FORCEINLINE static pointer priv_const_cast_from(boost::intrusive::detail::true_, const UPtr &uptr) + BOOST_INTRUSIVE_FORCEINLINE static pointer priv_const_cast_from(boost::intrusive::detail::true_, const UPtr &uptr) BOOST_NOEXCEPT { return Ptr::const_cast_from(uptr); } template - BOOST_INTRUSIVE_FORCEINLINE static pointer priv_const_cast_from(boost::intrusive::detail::false_, const UPtr &uptr) + BOOST_INTRUSIVE_FORCEINLINE static pointer priv_const_cast_from(boost::intrusive::detail::false_, const UPtr &uptr) BOOST_NOEXCEPT { return uptr ? pointer_to(const_cast(*uptr)) : pointer(); } //priv_dynamic_cast_from template - BOOST_INTRUSIVE_FORCEINLINE static pointer priv_dynamic_cast_from(boost::intrusive::detail::true_, const UPtr &uptr) + BOOST_INTRUSIVE_FORCEINLINE static pointer priv_dynamic_cast_from(boost::intrusive::detail::true_, const UPtr &uptr) BOOST_NOEXCEPT { return Ptr::dynamic_cast_from(uptr); } template - BOOST_INTRUSIVE_FORCEINLINE static pointer priv_dynamic_cast_from(boost::intrusive::detail::false_, const UPtr &uptr) + BOOST_INTRUSIVE_FORCEINLINE static pointer priv_dynamic_cast_from(boost::intrusive::detail::false_, const UPtr &uptr) BOOST_NOEXCEPT { return uptr ? pointer_to(dynamic_cast(*uptr)) : pointer(); } ///@endcond }; @@ -265,9 +272,10 @@ struct pointer_traits : pointer_traits { }; template struct pointer_traits { - typedef T element_type; - typedef T* pointer; - typedef std::ptrdiff_t difference_type; + typedef T element_type; + typedef T* pointer; + typedef std::ptrdiff_t difference_type; + typedef std::size_t size_type; #ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED typedef T & reference; @@ -288,25 +296,25 @@ struct pointer_traits //! Returns: addressof(r) //! - BOOST_INTRUSIVE_FORCEINLINE static pointer pointer_to(reference r) + BOOST_INTRUSIVE_FORCEINLINE static pointer pointer_to(reference r) BOOST_NOEXCEPT { return boost::intrusive::detail::addressof(r); } //! Returns: static_cast(uptr) //! template - BOOST_INTRUSIVE_FORCEINLINE static pointer static_cast_from(U *uptr) + BOOST_INTRUSIVE_FORCEINLINE static pointer static_cast_from(U *uptr) BOOST_NOEXCEPT { return static_cast(uptr); } //! Returns: const_cast(uptr) //! template - BOOST_INTRUSIVE_FORCEINLINE static pointer const_cast_from(U *uptr) + BOOST_INTRUSIVE_FORCEINLINE static pointer const_cast_from(U *uptr) BOOST_NOEXCEPT { return const_cast(uptr); } //! Returns: dynamic_cast(uptr) //! template - BOOST_INTRUSIVE_FORCEINLINE static pointer dynamic_cast_from(U *uptr) + BOOST_INTRUSIVE_FORCEINLINE static pointer dynamic_cast_from(U *uptr) BOOST_NOEXCEPT { return dynamic_cast(uptr); } }; diff --git a/include/boost/intrusive/priority_compare.hpp b/include/boost/intrusive/priority_compare.hpp index 3cf2b1c62..3e83ada19 100644 --- a/include/boost/intrusive/priority_compare.hpp +++ b/include/boost/intrusive/priority_compare.hpp @@ -28,8 +28,13 @@ namespace intrusive { /// @cond -template -void priority_order(); +namespace adldft { + +template +BOOST_INTRUSIVE_FORCEINLINE bool priority_order(const T &t, const U &u) +{ return t < u; } + +} //namespace adldft { /// @endcond @@ -43,6 +48,7 @@ struct priority_compare BOOST_INTRUSIVE_FORCEINLINE bool operator()(const T &val, const T &val2) const { + using adldft::priority_order; return priority_order(val, val2); } }; @@ -53,6 +59,7 @@ struct priority_compare template BOOST_INTRUSIVE_FORCEINLINE bool operator()(const T &t, const U &u) const { + using adldft::priority_order; return priority_order(t, u); } }; diff --git a/include/boost/intrusive/rbtree.hpp b/include/boost/intrusive/rbtree.hpp index 9d9b1169d..922fce51b 100644 --- a/include/boost/intrusive/rbtree.hpp +++ b/include/boost/intrusive/rbtree.hpp @@ -153,61 +153,61 @@ class rbtree_impl ~rbtree_impl(); //! @copydoc ::boost::intrusive::bstree::begin() - iterator begin(); + iterator begin() BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::bstree::begin()const - const_iterator begin() const; + const_iterator begin() const BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::bstree::cbegin()const - const_iterator cbegin() const; + const_iterator cbegin() const BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::bstree::end() - iterator end(); + iterator end() BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::bstree::end()const - const_iterator end() const; + const_iterator end() const BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::bstree::cend()const - const_iterator cend() const; + const_iterator cend() const BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::bstree::rbegin() - reverse_iterator rbegin(); + reverse_iterator rbegin() BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::bstree::rbegin()const - const_reverse_iterator rbegin() const; + const_reverse_iterator rbegin() const BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::bstree::crbegin()const - const_reverse_iterator crbegin() const; + const_reverse_iterator crbegin() const BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::bstree::rend() - reverse_iterator rend(); + reverse_iterator rend() BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::bstree::rend()const - const_reverse_iterator rend() const; + const_reverse_iterator rend() const BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::bstree::crend()const - const_reverse_iterator crend() const; + const_reverse_iterator crend() const BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::bstree::root() - iterator root(); + iterator root() BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::bstree::root()const - const_iterator root() const; + const_iterator root() const BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::bstree::croot()const - const_iterator croot() const; + const_iterator croot() const BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::bstree::container_from_end_iterator(iterator) - static rbtree_impl &container_from_end_iterator(iterator end_iterator); + static rbtree_impl &container_from_end_iterator(iterator end_iterator) BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::bstree::container_from_end_iterator(const_iterator) - static const rbtree_impl &container_from_end_iterator(const_iterator end_iterator); + static const rbtree_impl &container_from_end_iterator(const_iterator end_iterator) BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::bstree::container_from_iterator(iterator) - static rbtree_impl &container_from_iterator(iterator it); + static rbtree_impl &container_from_iterator(iterator it) BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::bstree::container_from_iterator(const_iterator) - static const rbtree_impl &container_from_iterator(const_iterator it); + static const rbtree_impl &container_from_iterator(const_iterator it) BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::bstree::key_comp()const key_compare key_comp() const; @@ -216,10 +216,10 @@ class rbtree_impl value_compare value_comp() const; //! @copydoc ::boost::intrusive::bstree::empty()const - bool empty() const; + bool empty() const BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::bstree::size()const - size_type size() const; + size_type size() const BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::bstree::swap void swap(rbtree_impl& other); @@ -281,26 +281,26 @@ class rbtree_impl (const_iterator hint, const key_type &key, insert_commit_data &commit_data); //! @copydoc ::boost::intrusive::bstree::insert_unique_commit - iterator insert_unique_commit(reference value, const insert_commit_data &commit_data); + iterator insert_unique_commit(reference value, const insert_commit_data &commit_data) BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::bstree::insert_unique(Iterator,Iterator) template void insert_unique(Iterator b, Iterator e); //! @copydoc ::boost::intrusive::bstree::insert_before - iterator insert_before(const_iterator pos, reference value); + iterator insert_before(const_iterator pos, reference value) BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::bstree::push_back - void push_back(reference value); + void push_back(reference value) BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::bstree::push_front - void push_front(reference value); + void push_front(reference value) BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::bstree::erase(const_iterator) - iterator erase(const_iterator i); + iterator erase(const_iterator i) BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::bstree::erase(const_iterator,const_iterator) - iterator erase(const_iterator b, const_iterator e); + iterator erase(const_iterator b, const_iterator e) BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::bstree::erase(const key_type &key) size_type erase(const key_type &key); @@ -311,11 +311,11 @@ class rbtree_impl //! @copydoc ::boost::intrusive::bstree::erase_and_dispose(const_iterator,Disposer) template - iterator erase_and_dispose(const_iterator i, Disposer disposer); + iterator erase_and_dispose(const_iterator i, Disposer disposer) BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::bstree::erase_and_dispose(const_iterator,const_iterator,Disposer) template - iterator erase_and_dispose(const_iterator b, const_iterator e, Disposer disposer); + iterator erase_and_dispose(const_iterator b, const_iterator e, Disposer disposer) BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::bstree::erase_and_dispose(const key_type &, Disposer) template @@ -326,11 +326,11 @@ class rbtree_impl size_type erase_and_dispose(const KeyType& key, KeyTypeKeyCompare comp, Disposer disposer); //! @copydoc ::boost::intrusive::bstree::clear - void clear(); + void clear() BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::bstree::clear_and_dispose template - void clear_and_dispose(Disposer disposer); + void clear_and_dispose(Disposer disposer) BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::bstree::count(const key_type &)const size_type count(const key_type &key) const; @@ -416,28 +416,28 @@ class rbtree_impl (const KeyType& lower_key, const KeyType& upper_key, KeyTypeKeyCompare comp, bool left_closed, bool right_closed) const; //! @copydoc ::boost::intrusive::bstree::s_iterator_to(reference) - static iterator s_iterator_to(reference value); + static iterator s_iterator_to(reference value) BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::bstree::s_iterator_to(const_reference) - static const_iterator s_iterator_to(const_reference value); + static const_iterator s_iterator_to(const_reference value) BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::bstree::iterator_to(reference) - iterator iterator_to(reference value); + iterator iterator_to(reference value) BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::bstree::iterator_to(const_reference)const - const_iterator iterator_to(const_reference value) const; + const_iterator iterator_to(const_reference value) const BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::bstree::init_node(reference) - static void init_node(reference value); + static void init_node(reference value) BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::bstree::unlink_leftmost_without_rebalance - pointer unlink_leftmost_without_rebalance(); + pointer unlink_leftmost_without_rebalance() BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::bstree::replace_node - void replace_node(iterator replace_this, reference with_this); + void replace_node(iterator replace_this, reference with_this) BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::bstree::remove_node - void remove_node(reference value); + void remove_node(reference value) BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::bstree::merge_unique(bstree&) template @@ -568,16 +568,16 @@ class rbtree BOOST_INTRUSIVE_FORCEINLINE void clone_from(BOOST_RV_REF(rbtree) src, Cloner cloner, Disposer disposer) { Base::clone_from(BOOST_MOVE_BASE(Base, src), cloner, disposer); } - BOOST_INTRUSIVE_FORCEINLINE static rbtree &container_from_end_iterator(iterator end_iterator) + BOOST_INTRUSIVE_FORCEINLINE static rbtree &container_from_end_iterator(iterator end_iterator) BOOST_NOEXCEPT { return static_cast(Base::container_from_end_iterator(end_iterator)); } - BOOST_INTRUSIVE_FORCEINLINE static const rbtree &container_from_end_iterator(const_iterator end_iterator) + BOOST_INTRUSIVE_FORCEINLINE static const rbtree &container_from_end_iterator(const_iterator end_iterator) BOOST_NOEXCEPT { return static_cast(Base::container_from_end_iterator(end_iterator)); } - BOOST_INTRUSIVE_FORCEINLINE static rbtree &container_from_iterator(iterator it) + BOOST_INTRUSIVE_FORCEINLINE static rbtree &container_from_iterator(iterator it) BOOST_NOEXCEPT { return static_cast(Base::container_from_iterator(it)); } - BOOST_INTRUSIVE_FORCEINLINE static const rbtree &container_from_iterator(const_iterator it) + BOOST_INTRUSIVE_FORCEINLINE static const rbtree &container_from_iterator(const_iterator it) BOOST_NOEXCEPT { return static_cast(Base::container_from_iterator(it)); } }; diff --git a/include/boost/intrusive/rbtree_algorithms.hpp b/include/boost/intrusive/rbtree_algorithms.hpp index 3f3bc2507..bbb3f0f12 100644 --- a/include/boost/intrusive/rbtree_algorithms.hpp +++ b/include/boost/intrusive/rbtree_algorithms.hpp @@ -54,7 +54,7 @@ struct rbtree_node_cloner : base_t(f) {} - BOOST_INTRUSIVE_FORCEINLINE node_ptr operator()(node_ptr p) + node_ptr operator()(node_ptr p) { node_ptr n = base_t::get()(p); NodeTraits::set_color(n, NodeTraits::get_color(p)); @@ -85,7 +85,7 @@ struct rbtree_node_checker : base_checker_t(comp, extra_checker) {} - void operator () (const const_node_ptr& p, + void operator () (const_node_ptr p, const return_type& check_return_left, const return_type& check_return_right, return_type& check_return) { @@ -190,22 +190,22 @@ class rbtree_algorithms #ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED - //! @copydoc ::boost::intrusive::bstree_algorithms::get_header(const const_node_ptr&) - static node_ptr get_header(const const_node_ptr & n); + //! @copydoc ::boost::intrusive::bstree_algorithms::get_header(const_node_ptr) + static node_ptr get_header(const_node_ptr n) BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::bstree_algorithms::begin_node - static node_ptr begin_node(const const_node_ptr & header); + static node_ptr begin_node(const_node_ptr header) BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::bstree_algorithms::end_node - static node_ptr end_node(const const_node_ptr & header); + static node_ptr end_node(const_node_ptr header) BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::bstree_algorithms::swap_tree - static void swap_tree(node_ptr header1, node_ptr header2); + static void swap_tree(node_ptr header1, node_ptr header2) BOOST_NOEXCEPT; #endif //#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED //! @copydoc ::boost::intrusive::bstree_algorithms::swap_nodes(node_ptr,node_ptr) - static void swap_nodes(node_ptr node1, node_ptr node2) + static void swap_nodes(node_ptr node1, node_ptr node2) BOOST_NOEXCEPT { if(node1 == node2) return; @@ -215,7 +215,7 @@ class rbtree_algorithms } //! @copydoc ::boost::intrusive::bstree_algorithms::swap_nodes(node_ptr,node_ptr,node_ptr,node_ptr) - static void swap_nodes(node_ptr node1, node_ptr header1, node_ptr node2, node_ptr header2) + static void swap_nodes(node_ptr node1, node_ptr header1, node_ptr node2, node_ptr header2) BOOST_NOEXCEPT { if(node1 == node2) return; @@ -227,7 +227,7 @@ class rbtree_algorithms } //! @copydoc ::boost::intrusive::bstree_algorithms::replace_node(node_ptr,node_ptr) - static void replace_node(node_ptr node_to_be_replaced, node_ptr new_node) + static void replace_node(node_ptr node_to_be_replaced, node_ptr new_node) BOOST_NOEXCEPT { if(node_to_be_replaced == new_node) return; @@ -235,52 +235,52 @@ class rbtree_algorithms } //! @copydoc ::boost::intrusive::bstree_algorithms::replace_node(node_ptr,node_ptr,node_ptr) - static void replace_node(node_ptr node_to_be_replaced, node_ptr header, node_ptr new_node) + static void replace_node(node_ptr node_to_be_replaced, node_ptr header, node_ptr new_node) BOOST_NOEXCEPT { bstree_algo::replace_node(node_to_be_replaced, header, new_node); NodeTraits::set_color(new_node, NodeTraits::get_color(node_to_be_replaced)); } //! @copydoc ::boost::intrusive::bstree_algorithms::unlink(node_ptr) - static void unlink(const node_ptr& node) + static void unlink(node_ptr n) BOOST_NOEXCEPT { - node_ptr x = NodeTraits::get_parent(node); + node_ptr x = NodeTraits::get_parent(n); if(x){ while(!is_header(x)) x = NodeTraits::get_parent(x); - erase(x, node); + erase(x, n); } } #ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED //! @copydoc ::boost::intrusive::bstree_algorithms::unlink_leftmost_without_rebalance - static node_ptr unlink_leftmost_without_rebalance(const node_ptr & header); + static node_ptr unlink_leftmost_without_rebalance(node_ptr header) BOOST_NOEXCEPT; - //! @copydoc ::boost::intrusive::bstree_algorithms::unique(const const_node_ptr&) - static bool unique(const const_node_ptr & node); + //! @copydoc ::boost::intrusive::bstree_algorithms::unique(const_node_ptr) + static bool unique(const_node_ptr n) BOOST_NOEXCEPT; - //! @copydoc ::boost::intrusive::bstree_algorithms::size(const const_node_ptr&) - static std::size_t size(const const_node_ptr & header); + //! @copydoc ::boost::intrusive::bstree_algorithms::size(const_node_ptr) + static std::size_t size(const_node_ptr header) BOOST_NOEXCEPT; - //! @copydoc ::boost::intrusive::bstree_algorithms::next_node(const node_ptr&) - static node_ptr next_node(const node_ptr & node); + //! @copydoc ::boost::intrusive::bstree_algorithms::next_node(const_node_ptr) + static node_ptr next_node(node_ptr n) BOOST_NOEXCEPT; - //! @copydoc ::boost::intrusive::bstree_algorithms::prev_node(const node_ptr&) - static node_ptr prev_node(const node_ptr & node); + //! @copydoc ::boost::intrusive::bstree_algorithms::prev_node(const_node_ptr) + static node_ptr prev_node(node_ptr n) BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::bstree_algorithms::init(node_ptr) - static void init(const node_ptr & node); + static void init(node_ptr n) BOOST_NOEXCEPT; #endif //#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED //! @copydoc ::boost::intrusive::bstree_algorithms::init_header(node_ptr) - BOOST_INTRUSIVE_FORCEINLINE static void init_header(node_ptr header) + static void init_header(node_ptr header) BOOST_NOEXCEPT { bstree_algo::init_header(header); NodeTraits::set_color(header, NodeTraits::red()); } //! @copydoc ::boost::intrusive::bstree_algorithms::erase(node_ptr,node_ptr) - static node_ptr erase(node_ptr header, node_ptr z) + static node_ptr erase(node_ptr header, node_ptr z) BOOST_NOEXCEPT { typename bstree_algo::data_for_rebalance info; bstree_algo::erase(header, z, info); @@ -313,7 +313,7 @@ class rbtree_algorithms rebalance_after_insertion(header1, z); } - //! @copydoc ::boost::intrusive::bstree_algorithms::clone(const const_node_ptr&,node_ptr,Cloner,Disposer) + //! @copydoc ::boost::intrusive::bstree_algorithms::clone(const_node_ptr,node_ptr,Cloner,Disposer) template static void clone (const_node_ptr source_header, node_ptr target_header, Cloner cloner, Disposer disposer) @@ -323,39 +323,39 @@ class rbtree_algorithms } #ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED - //! @copydoc ::boost::intrusive::bstree_algorithms::clear_and_dispose(const node_ptr&,Disposer) + //! @copydoc ::boost::intrusive::bstree_algorithms::clear_and_dispose(const_node_ptr,Disposer) template - static void clear_and_dispose(const node_ptr & header, Disposer disposer); + static void clear_and_dispose(node_ptr header, Disposer disposer) BOOST_NOEXCEPT; - //! @copydoc ::boost::intrusive::bstree_algorithms::lower_bound(const const_node_ptr&,const KeyType&,KeyNodePtrCompare) + //! @copydoc ::boost::intrusive::bstree_algorithms::lower_bound(const_node_ptr,const KeyType&,KeyNodePtrCompare) template static node_ptr lower_bound - (const const_node_ptr & header, const KeyType &key, KeyNodePtrCompare comp); + (const_node_ptr header, const KeyType &key, KeyNodePtrCompare comp); - //! @copydoc ::boost::intrusive::bstree_algorithms::upper_bound(const const_node_ptr&,const KeyType&,KeyNodePtrCompare) + //! @copydoc ::boost::intrusive::bstree_algorithms::upper_bound(const_node_ptr,const KeyType&,KeyNodePtrCompare) template static node_ptr upper_bound - (const const_node_ptr & header, const KeyType &key, KeyNodePtrCompare comp); + (const_node_ptr header, const KeyType &key, KeyNodePtrCompare comp); - //! @copydoc ::boost::intrusive::bstree_algorithms::find(const const_node_ptr&, const KeyType&,KeyNodePtrCompare) + //! @copydoc ::boost::intrusive::bstree_algorithms::find(const_node_ptr, const KeyType&,KeyNodePtrCompare) template static node_ptr find - (const const_node_ptr & header, const KeyType &key, KeyNodePtrCompare comp); + (const_node_ptr header, const KeyType &key, KeyNodePtrCompare comp); - //! @copydoc ::boost::intrusive::bstree_algorithms::equal_range(const const_node_ptr&,const KeyType&,KeyNodePtrCompare) + //! @copydoc ::boost::intrusive::bstree_algorithms::equal_range(const_node_ptr,const KeyType&,KeyNodePtrCompare) template static std::pair equal_range - (const const_node_ptr & header, const KeyType &key, KeyNodePtrCompare comp); + (const_node_ptr header, const KeyType &key, KeyNodePtrCompare comp); - //! @copydoc ::boost::intrusive::bstree_algorithms::bounded_range(const const_node_ptr&,const KeyType&,const KeyType&,KeyNodePtrCompare,bool,bool) + //! @copydoc ::boost::intrusive::bstree_algorithms::bounded_range(const_node_ptr,const KeyType&,const KeyType&,KeyNodePtrCompare,bool,bool) template static std::pair bounded_range - (const const_node_ptr & header, const KeyType &lower_key, const KeyType &upper_key, KeyNodePtrCompare comp + (const_node_ptr eader, const KeyType &lower_key, const KeyType &upper_key, KeyNodePtrCompare comp , bool left_closed, bool right_closed); - //! @copydoc ::boost::intrusive::bstree_algorithms::count(const const_node_ptr&,const KeyType&,KeyNodePtrCompare) + //! @copydoc ::boost::intrusive::bstree_algorithms::count(const_node_ptr,const KeyType&,KeyNodePtrCompare) template - static std::size_t count(const const_node_ptr & header, const KeyType &key, KeyNodePtrCompare comp); + static std::size_t count(const_node_ptr header, const KeyType &key, KeyNodePtrCompare comp); #endif //#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED @@ -391,7 +391,7 @@ class rbtree_algorithms //! @copydoc ::boost::intrusive::bstree_algorithms::insert_before(node_ptr,node_ptr,node_ptr) static node_ptr insert_before - (node_ptr header, node_ptr pos, node_ptr new_node) + (node_ptr header, node_ptr pos, node_ptr new_node) BOOST_NOEXCEPT { bstree_algo::insert_before(header, pos, new_node); rebalance_after_insertion(header, new_node); @@ -399,27 +399,27 @@ class rbtree_algorithms } //! @copydoc ::boost::intrusive::bstree_algorithms::push_back(node_ptr,node_ptr) - static void push_back(node_ptr header, node_ptr new_node) + static void push_back(node_ptr header, node_ptr new_node) BOOST_NOEXCEPT { bstree_algo::push_back(header, new_node); rebalance_after_insertion(header, new_node); } //! @copydoc ::boost::intrusive::bstree_algorithms::push_front(node_ptr,node_ptr) - static void push_front(node_ptr header, node_ptr new_node) + static void push_front(node_ptr header, node_ptr new_node) BOOST_NOEXCEPT { bstree_algo::push_front(header, new_node); rebalance_after_insertion(header, new_node); } #ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED - //! @copydoc ::boost::intrusive::bstree_algorithms::insert_unique_check(const const_node_ptr&,const KeyType&,KeyNodePtrCompare,insert_commit_data&) + //! @copydoc ::boost::intrusive::bstree_algorithms::insert_unique_check(const_node_ptr,const KeyType&,KeyNodePtrCompare,insert_commit_data&) template static std::pair insert_unique_check (const_node_ptr header, const KeyType &key ,KeyNodePtrCompare comp, insert_commit_data &commit_data); - //! @copydoc ::boost::intrusive::bstree_algorithms::insert_unique_check(const const_node_ptr&,const node_ptr&,const KeyType&,KeyNodePtrCompare,insert_commit_data&) + //! @copydoc ::boost::intrusive::bstree_algorithms::insert_unique_check(const_node_ptr,const_node_ptr,const KeyType&,KeyNodePtrCompare,insert_commit_data&) template static std::pair insert_unique_check (const_node_ptr header, node_ptr hint, const KeyType &key @@ -428,14 +428,14 @@ class rbtree_algorithms //! @copydoc ::boost::intrusive::bstree_algorithms::insert_unique_commit(node_ptr,node_ptr,const insert_commit_data&) static void insert_unique_commit - (node_ptr header, node_ptr new_value, const insert_commit_data &commit_data) + (node_ptr header, node_ptr new_value, const insert_commit_data &commit_data) BOOST_NOEXCEPT { bstree_algo::insert_unique_commit(header, new_value, commit_data); rebalance_after_insertion(header, new_value); } //! @copydoc ::boost::intrusive::bstree_algorithms::is_header - static bool is_header(const const_node_ptr & p) + static bool is_header(const_node_ptr p) BOOST_NOEXCEPT { return NodeTraits::get_color(p) == NodeTraits::red() && bstree_algo::is_header(p); @@ -445,7 +445,7 @@ class rbtree_algorithms private: static void rebalance_after_erasure - ( node_ptr header, node_ptr z, const typename bstree_algo::data_for_rebalance &info) + ( node_ptr header, node_ptr z, const typename bstree_algo::data_for_rebalance &info) BOOST_NOEXCEPT { color new_z_color; if(info.y != z){ @@ -461,7 +461,7 @@ class rbtree_algorithms } } - static void rebalance_after_erasure_restore_invariants(node_ptr header, node_ptr x, node_ptr x_parent) + static void rebalance_after_erasure_restore_invariants(node_ptr header, node_ptr x, node_ptr x_parent) BOOST_NOEXCEPT { while(1){ if(x_parent == header || (x && NodeTraits::get_color(x) != NodeTraits::black())){ @@ -545,7 +545,7 @@ class rbtree_algorithms NodeTraits::set_color(x, NodeTraits::black()); } - static void rebalance_after_insertion(node_ptr header, node_ptr p) + static void rebalance_after_insertion(node_ptr header, node_ptr p) BOOST_NOEXCEPT { NodeTraits::set_color(p, NodeTraits::red()); while(1){ diff --git a/include/boost/intrusive/set.hpp b/include/boost/intrusive/set.hpp index 366931f54..30f0760d2 100644 --- a/include/boost/intrusive/set.hpp +++ b/include/boost/intrusive/set.hpp @@ -120,61 +120,61 @@ class set_impl ~set_impl(); //! @copydoc ::boost::intrusive::rbtree::begin() - iterator begin(); + iterator begin() BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::rbtree::begin()const - const_iterator begin() const; + const_iterator begin() const BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::rbtree::cbegin()const - const_iterator cbegin() const; + const_iterator cbegin() const BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::rbtree::end() - iterator end(); + iterator end() BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::rbtree::end()const - const_iterator end() const; + const_iterator end() const BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::rbtree::cend()const - const_iterator cend() const; + const_iterator cend() const BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::rbtree::rbegin() - reverse_iterator rbegin(); + reverse_iterator rbegin() BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::rbtree::rbegin()const - const_reverse_iterator rbegin() const; + const_reverse_iterator rbegin() const BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::rbtree::crbegin()const - const_reverse_iterator crbegin() const; + const_reverse_iterator crbegin() const BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::rbtree::rend() - reverse_iterator rend(); + reverse_iterator rend() BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::rbtree::rend()const - const_reverse_iterator rend() const; + const_reverse_iterator rend() const BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::rbtree::crend()const - const_reverse_iterator crend() const; + const_reverse_iterator crend() const BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::rbtree::root() - iterator root(); + iterator root() BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::rbtree::root()const - const_iterator root() const; + const_iterator root() const BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::rbtree::croot()const - const_iterator croot() const; + const_iterator croot() const BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::rbtree::container_from_end_iterator(iterator) - static set_impl &container_from_end_iterator(iterator end_iterator); + static set_impl &container_from_end_iterator(iterator end_iterator) BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::rbtree::container_from_end_iterator(const_iterator) - static const set_impl &container_from_end_iterator(const_iterator end_iterator); + static const set_impl &container_from_end_iterator(const_iterator end_iterator) BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::rbtree::container_from_iterator(iterator) - static set_impl &container_from_iterator(iterator it); + static set_impl &container_from_iterator(iterator it) BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::rbtree::container_from_iterator(const_iterator) - static const set_impl &container_from_iterator(const_iterator it); + static const set_impl &container_from_iterator(const_iterator it) BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::rbtree::key_comp()const key_compare key_comp() const; @@ -183,10 +183,10 @@ class set_impl value_compare value_comp() const; //! @copydoc ::boost::intrusive::rbtree::empty()const - bool empty() const; + bool empty() const BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::rbtree::size()const - size_type size() const; + size_type size() const BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::rbtree::swap void swap(set_impl& other); @@ -244,24 +244,24 @@ class set_impl { tree_type::insert_unique(b, e); } //! @copydoc ::boost::intrusive::rbtree::insert_unique_commit - iterator insert_commit(reference value, const insert_commit_data &commit_data) + iterator insert_commit(reference value, const insert_commit_data &commit_data) BOOST_NOEXCEPT { return tree_type::insert_unique_commit(value, commit_data); } #ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED //! @copydoc ::boost::intrusive::rbtree::insert_before - iterator insert_before(const_iterator pos, reference value); + iterator insert_before(const_iterator pos, reference value) BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::rbtree::push_back - void push_back(reference value); + void push_back(reference value) BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::rbtree::push_front - void push_front(reference value); + void push_front(reference value) BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::rbtree::erase(const_iterator) - iterator erase(const_iterator i); + iterator erase(const_iterator i) BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::rbtree::erase(const_iterator,const_iterator) - iterator erase(const_iterator b, const_iterator e); + iterator erase(const_iterator b, const_iterator e) BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::rbtree::erase(const key_type &) size_type erase(const key_type &key); @@ -272,11 +272,11 @@ class set_impl //! @copydoc ::boost::intrusive::rbtree::erase_and_dispose(const_iterator,Disposer) template - iterator erase_and_dispose(const_iterator i, Disposer disposer); + iterator erase_and_dispose(const_iterator i, Disposer disposer) BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::rbtree::erase_and_dispose(const_iterator,const_iterator,Disposer) template - iterator erase_and_dispose(const_iterator b, const_iterator e, Disposer disposer); + iterator erase_and_dispose(const_iterator b, const_iterator e, Disposer disposer) BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::rbtree::erase_and_dispose(const key_type &, Disposer) template @@ -287,11 +287,11 @@ class set_impl size_type erase_and_dispose(const KeyType& key, KeyTypeKeyCompare comp, Disposer disposer); //! @copydoc ::boost::intrusive::rbtree::clear - void clear(); + void clear() BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::rbtree::clear_and_dispose template - void clear_and_dispose(Disposer disposer); + void clear_and_dispose(Disposer disposer) BOOST_NOEXCEPT; #endif // #ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED @@ -391,28 +391,28 @@ class set_impl (const KeyType& lower_key, const KeyType& upper_key, KeyTypeKeyCompare comp, bool left_closed, bool right_closed) const; //! @copydoc ::boost::intrusive::rbtree::s_iterator_to(reference) - static iterator s_iterator_to(reference value); + static iterator s_iterator_to(reference value) BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::rbtree::s_iterator_to(const_reference) - static const_iterator s_iterator_to(const_reference value); + static const_iterator s_iterator_to(const_reference value) BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::rbtree::iterator_to(reference) - iterator iterator_to(reference value); + iterator iterator_to(reference value) BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::rbtree::iterator_to(const_reference)const - const_iterator iterator_to(const_reference value) const; + const_iterator iterator_to(const_reference value) const BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::rbtree::init_node(reference) - static void init_node(reference value); + static void init_node(reference value) BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::rbtree::unlink_leftmost_without_rebalance - pointer unlink_leftmost_without_rebalance(); + pointer unlink_leftmost_without_rebalance() BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::rbtree::replace_node - void replace_node(iterator replace_this, reference with_this); + void replace_node(iterator replace_this, reference with_this) BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::rbtree::remove_node - void remove_node(reference value); + void remove_node(reference value) BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::rbtree::merge_unique template @@ -555,16 +555,16 @@ class set BOOST_INTRUSIVE_FORCEINLINE void clone_from(BOOST_RV_REF(set) src, Cloner cloner, Disposer disposer) { Base::clone_from(BOOST_MOVE_BASE(Base, src), cloner, disposer); } - BOOST_INTRUSIVE_FORCEINLINE static set &container_from_end_iterator(iterator end_iterator) + BOOST_INTRUSIVE_FORCEINLINE static set &container_from_end_iterator(iterator end_iterator) BOOST_NOEXCEPT { return static_cast(Base::container_from_end_iterator(end_iterator)); } - BOOST_INTRUSIVE_FORCEINLINE static const set &container_from_end_iterator(const_iterator end_iterator) + BOOST_INTRUSIVE_FORCEINLINE static const set &container_from_end_iterator(const_iterator end_iterator) BOOST_NOEXCEPT { return static_cast(Base::container_from_end_iterator(end_iterator)); } - BOOST_INTRUSIVE_FORCEINLINE static set &container_from_iterator(iterator it) + BOOST_INTRUSIVE_FORCEINLINE static set &container_from_iterator(iterator it) BOOST_NOEXCEPT { return static_cast(Base::container_from_iterator(it)); } - BOOST_INTRUSIVE_FORCEINLINE static const set &container_from_iterator(const_iterator it) + BOOST_INTRUSIVE_FORCEINLINE static const set &container_from_iterator(const_iterator it) BOOST_NOEXCEPT { return static_cast(Base::container_from_iterator(it)); } }; @@ -657,61 +657,61 @@ class multiset_impl ~multiset_impl(); //! @copydoc ::boost::intrusive::rbtree::begin() - iterator begin(); + iterator begin() BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::rbtree::begin()const - const_iterator begin() const; + const_iterator begin() const BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::rbtree::cbegin()const - const_iterator cbegin() const; + const_iterator cbegin() const BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::rbtree::end() - iterator end(); + iterator end() BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::rbtree::end()const - const_iterator end() const; + const_iterator end() const BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::rbtree::cend()const - const_iterator cend() const; + const_iterator cend() const BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::rbtree::rbegin() - reverse_iterator rbegin(); + reverse_iterator rbegin() BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::rbtree::rbegin()const - const_reverse_iterator rbegin() const; + const_reverse_iterator rbegin() const BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::rbtree::crbegin()const - const_reverse_iterator crbegin() const; + const_reverse_iterator crbegin() const BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::rbtree::rend() - reverse_iterator rend(); + reverse_iterator rend() BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::rbtree::rend()const - const_reverse_iterator rend() const; + const_reverse_iterator rend() const BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::rbtree::crend()const - const_reverse_iterator crend() const; + const_reverse_iterator crend() const BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::rbtree::root() - iterator root(); + iterator root() BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::rbtree::root()const - const_iterator root() const; + const_iterator root() const BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::rbtree::croot()const - const_iterator croot() const; + const_iterator croot() const BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::rbtree::container_from_end_iterator(iterator) - static multiset_impl &container_from_end_iterator(iterator end_iterator); + static multiset_impl &container_from_end_iterator(iterator end_iterator) BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::rbtree::container_from_end_iterator(const_iterator) - static const multiset_impl &container_from_end_iterator(const_iterator end_iterator); + static const multiset_impl &container_from_end_iterator(const_iterator end_iterator) BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::rbtree::container_from_iterator(iterator) - static multiset_impl &container_from_iterator(iterator it); + static multiset_impl &container_from_iterator(iterator it) BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::rbtree::container_from_iterator(const_iterator) - static const multiset_impl &container_from_iterator(const_iterator it); + static const multiset_impl &container_from_iterator(const_iterator it) BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::rbtree::key_comp()const key_compare key_comp() const; @@ -720,10 +720,10 @@ class multiset_impl value_compare value_comp() const; //! @copydoc ::boost::intrusive::rbtree::empty()const - bool empty() const; + bool empty() const BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::rbtree::size()const - size_type size() const; + size_type size() const BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::rbtree::swap void swap(multiset_impl& other); @@ -758,19 +758,19 @@ class multiset_impl #ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED //! @copydoc ::boost::intrusive::rbtree::insert_before - iterator insert_before(const_iterator pos, reference value); + iterator insert_before(const_iterator pos, reference value) BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::rbtree::push_back - void push_back(reference value); + void push_back(reference value) BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::rbtree::push_front - void push_front(reference value); + void push_front(reference value) BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::rbtree::erase(const_iterator) - iterator erase(const_iterator i); + iterator erase(const_iterator i) BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::rbtree::erase(const_iterator,const_iterator) - iterator erase(const_iterator b, const_iterator e); + iterator erase(const_iterator b, const_iterator e) BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::rbtree::erase(const key_type &) size_type erase(const key_type &key); @@ -781,11 +781,11 @@ class multiset_impl //! @copydoc ::boost::intrusive::rbtree::erase_and_dispose(const_iterator,Disposer) template - iterator erase_and_dispose(const_iterator i, Disposer disposer); + iterator erase_and_dispose(const_iterator i, Disposer disposer) BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::rbtree::erase_and_dispose(const_iterator,const_iterator,Disposer) template - iterator erase_and_dispose(const_iterator b, const_iterator e, Disposer disposer); + iterator erase_and_dispose(const_iterator b, const_iterator e, Disposer disposer) BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::rbtree::erase_and_dispose(const key_type &, Disposer) template @@ -796,11 +796,11 @@ class multiset_impl size_type erase_and_dispose(const KeyType& key, KeyTypeKeyCompare comp, Disposer disposer); //! @copydoc ::boost::intrusive::rbtree::clear - void clear(); + void clear() BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::rbtree::clear_and_dispose template - void clear_and_dispose(Disposer disposer); + void clear_and_dispose(Disposer disposer) BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::rbtree::count(const key_type &)const size_type count(const key_type &key) const; @@ -886,28 +886,28 @@ class multiset_impl (const KeyType& lower_key, const KeyType& upper_key, KeyTypeKeyCompare comp, bool left_closed, bool right_closed) const; //! @copydoc ::boost::intrusive::rbtree::s_iterator_to(reference) - static iterator s_iterator_to(reference value); + static iterator s_iterator_to(reference value) BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::rbtree::s_iterator_to(const_reference) - static const_iterator s_iterator_to(const_reference value); + static const_iterator s_iterator_to(const_reference value) BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::rbtree::iterator_to(reference) - iterator iterator_to(reference value); + iterator iterator_to(reference value) BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::rbtree::iterator_to(const_reference)const - const_iterator iterator_to(const_reference value) const; + const_iterator iterator_to(const_reference value) const BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::rbtree::init_node(reference) - static void init_node(reference value); + static void init_node(reference value) BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::rbtree::unlink_leftmost_without_rebalance - pointer unlink_leftmost_without_rebalance(); + pointer unlink_leftmost_without_rebalance() BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::rbtree::replace_node - void replace_node(iterator replace_this, reference with_this); + void replace_node(iterator replace_this, reference with_this) BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::rbtree::remove_node - void remove_node(reference value); + void remove_node(reference value) BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::rbtree::merge_equal template @@ -1050,16 +1050,16 @@ class multiset BOOST_INTRUSIVE_FORCEINLINE void clone_from(BOOST_RV_REF(multiset) src, Cloner cloner, Disposer disposer) { Base::clone_from(BOOST_MOVE_BASE(Base, src), cloner, disposer); } - BOOST_INTRUSIVE_FORCEINLINE static multiset &container_from_end_iterator(iterator end_iterator) + BOOST_INTRUSIVE_FORCEINLINE static multiset &container_from_end_iterator(iterator end_iterator) BOOST_NOEXCEPT { return static_cast(Base::container_from_end_iterator(end_iterator)); } - BOOST_INTRUSIVE_FORCEINLINE static const multiset &container_from_end_iterator(const_iterator end_iterator) + BOOST_INTRUSIVE_FORCEINLINE static const multiset &container_from_end_iterator(const_iterator end_iterator) BOOST_NOEXCEPT { return static_cast(Base::container_from_end_iterator(end_iterator)); } - BOOST_INTRUSIVE_FORCEINLINE static multiset &container_from_iterator(iterator it) + BOOST_INTRUSIVE_FORCEINLINE static multiset &container_from_iterator(iterator it) BOOST_NOEXCEPT { return static_cast(Base::container_from_iterator(it)); } - BOOST_INTRUSIVE_FORCEINLINE static const multiset &container_from_iterator(const_iterator it) + BOOST_INTRUSIVE_FORCEINLINE static const multiset &container_from_iterator(const_iterator it) BOOST_NOEXCEPT { return static_cast(Base::container_from_iterator(it)); } }; diff --git a/include/boost/intrusive/set_hook.hpp b/include/boost/intrusive/set_hook.hpp index e303b6442..fed331cce 100644 --- a/include/boost/intrusive/set_hook.hpp +++ b/include/boost/intrusive/set_hook.hpp @@ -99,7 +99,7 @@ class set_base_hook //! initializes the node to an unlinked state. //! //! Throws: Nothing. - set_base_hook(); + set_base_hook() BOOST_NOEXCEPT; //! Effects: If link_mode is \c auto_unlink or \c safe_link //! initializes the node to an unlinked state. The argument is ignored. @@ -110,7 +110,7 @@ class set_base_hook //! makes classes using the hook STL-compliant without forcing the //! user to do some additional work. \c swap can be used to emulate //! move-semantics. - set_base_hook(const set_base_hook& ); + set_base_hook(const set_base_hook& ) BOOST_NOEXCEPT; //! Effects: Empty function. The argument is ignored. //! @@ -120,7 +120,7 @@ class set_base_hook //! makes classes using the hook STL-compliant without forcing the //! user to do some additional work. \c swap can be used to emulate //! move-semantics. - set_base_hook& operator=(const set_base_hook& ); + set_base_hook& operator=(const set_base_hook& ) BOOST_NOEXCEPT; //! Effects: If link_mode is \c normal_link, the destructor does //! nothing (ie. no code is generated). If link_mode is \c safe_link and the @@ -142,7 +142,7 @@ class set_base_hook //! Complexity: Constant //! //! Throws: Nothing. - void swap_nodes(set_base_hook &other); + void swap_nodes(set_base_hook &other) BOOST_NOEXCEPT; //! Precondition: link_mode must be \c safe_link or \c auto_unlink. //! @@ -151,13 +151,13 @@ class set_base_hook //! will return a valid iterator. //! //! Complexity: Constant - bool is_linked() const; + bool is_linked() const BOOST_NOEXCEPT; //! Effects: Removes the node if it's inserted in a container. //! This function is only allowed if link_mode is \c auto_unlink. //! //! Throws: Nothing. - void unlink(); + void unlink() BOOST_NOEXCEPT; #endif }; @@ -226,7 +226,7 @@ class set_member_hook //! initializes the node to an unlinked state. //! //! Throws: Nothing. - set_member_hook(); + set_member_hook() BOOST_NOEXCEPT; //! Effects: If link_mode is \c auto_unlink or \c safe_link //! initializes the node to an unlinked state. The argument is ignored. @@ -237,7 +237,7 @@ class set_member_hook //! makes classes using the hook STL-compliant without forcing the //! user to do some additional work. \c swap can be used to emulate //! move-semantics. - set_member_hook(const set_member_hook& ); + set_member_hook(const set_member_hook& ) BOOST_NOEXCEPT; //! Effects: Empty function. The argument is ignored. //! @@ -247,7 +247,7 @@ class set_member_hook //! makes classes using the hook STL-compliant without forcing the //! user to do some additional work. \c swap can be used to emulate //! move-semantics. - set_member_hook& operator=(const set_member_hook& ); + set_member_hook& operator=(const set_member_hook& ) BOOST_NOEXCEPT; //! Effects: If link_mode is \c normal_link, the destructor does //! nothing (ie. no code is generated). If link_mode is \c safe_link and the @@ -269,7 +269,7 @@ class set_member_hook //! Complexity: Constant //! //! Throws: Nothing. - void swap_nodes(set_member_hook &other); + void swap_nodes(set_member_hook &other) BOOST_NOEXCEPT; //! Precondition: link_mode must be \c safe_link or \c auto_unlink. //! @@ -278,13 +278,13 @@ class set_member_hook //! will return a valid iterator. //! //! Complexity: Constant - bool is_linked() const; + bool is_linked() const BOOST_NOEXCEPT; //! Effects: Removes the node if it's inserted in a container. //! This function is only allowed if link_mode is \c auto_unlink. //! //! Throws: Nothing. - void unlink(); + void unlink() BOOST_NOEXCEPT; #endif }; diff --git a/include/boost/intrusive/sg_set.hpp b/include/boost/intrusive/sg_set.hpp index 4144e14ba..72c412d65 100644 --- a/include/boost/intrusive/sg_set.hpp +++ b/include/boost/intrusive/sg_set.hpp @@ -118,61 +118,61 @@ class sg_set_impl ~sg_set_impl(); //! @copydoc ::boost::intrusive::sgtree::begin() - iterator begin(); + iterator begin() BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::sgtree::begin()const - const_iterator begin() const; + const_iterator begin() const BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::sgtree::cbegin()const - const_iterator cbegin() const; + const_iterator cbegin() const BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::sgtree::end() - iterator end(); + iterator end() BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::sgtree::end()const - const_iterator end() const; + const_iterator end() const BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::sgtree::cend()const - const_iterator cend() const; + const_iterator cend() const BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::sgtree::rbegin() - reverse_iterator rbegin(); + reverse_iterator rbegin() BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::sgtree::rbegin()const - const_reverse_iterator rbegin() const; + const_reverse_iterator rbegin() const BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::sgtree::crbegin()const - const_reverse_iterator crbegin() const; + const_reverse_iterator crbegin() const BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::sgtree::rend() - reverse_iterator rend(); + reverse_iterator rend() BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::sgtree::rend()const - const_reverse_iterator rend() const; + const_reverse_iterator rend() const BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::sgtree::crend()const - const_reverse_iterator crend() const; + const_reverse_iterator crend() const BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::sgtree::root() - iterator root(); + iterator root() BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::sgtree::root()const - const_iterator root() const; + const_iterator root() const BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::sgtree::croot()const - const_iterator croot() const; + const_iterator croot() const BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::sgtree::container_from_end_iterator(iterator) - static sg_set_impl &container_from_end_iterator(iterator end_iterator); + static sg_set_impl &container_from_end_iterator(iterator end_iterator) BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::sgtree::container_from_end_iterator(const_iterator) - static const sg_set_impl &container_from_end_iterator(const_iterator end_iterator); + static const sg_set_impl &container_from_end_iterator(const_iterator end_iterator) BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::sgtree::container_from_iterator(iterator) - static sg_set_impl &container_from_iterator(iterator it); + static sg_set_impl &container_from_iterator(iterator it) BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::sgtree::container_from_iterator(const_iterator) - static const sg_set_impl &container_from_iterator(const_iterator it); + static const sg_set_impl &container_from_iterator(const_iterator it) BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::sgtree::key_comp()const key_compare key_comp() const; @@ -181,10 +181,10 @@ class sg_set_impl value_compare value_comp() const; //! @copydoc ::boost::intrusive::sgtree::empty()const - bool empty() const; + bool empty() const BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::sgtree::size()const - size_type size() const; + size_type size() const BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::sgtree::swap void swap(sg_set_impl& other); @@ -242,24 +242,24 @@ class sg_set_impl { tree_type::insert_unique(b, e); } //! @copydoc ::boost::intrusive::sgtree::insert_unique_commit - iterator insert_commit(reference value, const insert_commit_data &commit_data) + iterator insert_commit(reference value, const insert_commit_data &commit_data) BOOST_NOEXCEPT { return tree_type::insert_unique_commit(value, commit_data); } #ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED //! @copydoc ::boost::intrusive::sgtree::insert_before - iterator insert_before(const_iterator pos, reference value); + iterator insert_before(const_iterator pos, reference value) BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::sgtree::push_back - void push_back(reference value); + void push_back(reference value) BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::sgtree::push_front - void push_front(reference value); + void push_front(reference value) BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::sgtree::erase(const_iterator) - iterator erase(const_iterator i); + iterator erase(const_iterator i) BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::sgtree::erase(const_iterator,const_iterator) - iterator erase(const_iterator b, const_iterator e); + iterator erase(const_iterator b, const_iterator e) BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::sgtree::erase(const key_type &) size_type erase(const key_type &key); @@ -270,11 +270,11 @@ class sg_set_impl //! @copydoc ::boost::intrusive::sgtree::erase_and_dispose(const_iterator,Disposer) template - iterator erase_and_dispose(const_iterator i, Disposer disposer); + iterator erase_and_dispose(const_iterator i, Disposer disposer) BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::sgtree::erase_and_dispose(const_iterator,const_iterator,Disposer) template - iterator erase_and_dispose(const_iterator b, const_iterator e, Disposer disposer); + iterator erase_and_dispose(const_iterator b, const_iterator e, Disposer disposer) BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::sgtree::erase_and_dispose(const key_type &, Disposer) template @@ -285,11 +285,11 @@ class sg_set_impl size_type erase_and_dispose(const KeyType& key, KeyTypeKeyCompare comp, Disposer disposer); //! @copydoc ::boost::intrusive::sgtree::clear - void clear(); + void clear() BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::sgtree::clear_and_dispose template - void clear_and_dispose(Disposer disposer); + void clear_and_dispose(Disposer disposer) BOOST_NOEXCEPT; #endif // #ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED @@ -389,40 +389,40 @@ class sg_set_impl (const KeyType& lower_key, const KeyType& upper_key, KeyTypeKeyCompare comp, bool left_closed, bool right_closed) const; //! @copydoc ::boost::intrusive::sgtree::s_iterator_to(reference) - static iterator s_iterator_to(reference value); + static iterator s_iterator_to(reference value) BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::sgtree::s_iterator_to(const_reference) - static const_iterator s_iterator_to(const_reference value); + static const_iterator s_iterator_to(const_reference value) BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::sgtree::iterator_to(reference) - iterator iterator_to(reference value); + iterator iterator_to(reference value) BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::sgtree::iterator_to(const_reference)const - const_iterator iterator_to(const_reference value) const; + const_iterator iterator_to(const_reference value) const BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::sgtree::init_node(reference) - static void init_node(reference value); + static void init_node(reference value) BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::sgtree::unlink_leftmost_without_rebalance - pointer unlink_leftmost_without_rebalance(); + pointer unlink_leftmost_without_rebalance() BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::sgtree::replace_node - void replace_node(iterator replace_this, reference with_this); + void replace_node(iterator replace_this, reference with_this) BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::sgtree::remove_node - void remove_node(reference value); + void remove_node(reference value) BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::sgtree::rebalance - void rebalance(); + void rebalance() BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::sgtree::rebalance_subtree - iterator rebalance_subtree(iterator root); + iterator rebalance_subtree(iterator root) BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::sgtree::balance_factor() - float balance_factor() const; + float balance_factor() const BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::sgtree::balance_factor(float) - void balance_factor(float new_alpha); + void balance_factor(float new_alpha) BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::rbtree::merge_unique template @@ -564,16 +564,16 @@ class sg_set BOOST_INTRUSIVE_FORCEINLINE void clone_from(BOOST_RV_REF(sg_set) src, Cloner cloner, Disposer disposer) { Base::clone_from(BOOST_MOVE_BASE(Base, src), cloner, disposer); } - BOOST_INTRUSIVE_FORCEINLINE static sg_set &container_from_end_iterator(iterator end_iterator) + BOOST_INTRUSIVE_FORCEINLINE static sg_set &container_from_end_iterator(iterator end_iterator) BOOST_NOEXCEPT { return static_cast(Base::container_from_end_iterator(end_iterator)); } - BOOST_INTRUSIVE_FORCEINLINE static const sg_set &container_from_end_iterator(const_iterator end_iterator) + BOOST_INTRUSIVE_FORCEINLINE static const sg_set &container_from_end_iterator(const_iterator end_iterator) BOOST_NOEXCEPT { return static_cast(Base::container_from_end_iterator(end_iterator)); } - BOOST_INTRUSIVE_FORCEINLINE static sg_set &container_from_iterator(iterator it) + BOOST_INTRUSIVE_FORCEINLINE static sg_set &container_from_iterator(iterator it) BOOST_NOEXCEPT { return static_cast(Base::container_from_iterator(it)); } - BOOST_INTRUSIVE_FORCEINLINE static const sg_set &container_from_iterator(const_iterator it) + BOOST_INTRUSIVE_FORCEINLINE static const sg_set &container_from_iterator(const_iterator it) BOOST_NOEXCEPT { return static_cast(Base::container_from_iterator(it)); } }; @@ -666,61 +666,61 @@ class sg_multiset_impl ~sg_multiset_impl(); //! @copydoc ::boost::intrusive::sgtree::begin() - iterator begin(); + iterator begin() BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::sgtree::begin()const - const_iterator begin() const; + const_iterator begin() const BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::sgtree::cbegin()const - const_iterator cbegin() const; + const_iterator cbegin() const BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::sgtree::end() - iterator end(); + iterator end() BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::sgtree::end()const - const_iterator end() const; + const_iterator end() const BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::sgtree::cend()const - const_iterator cend() const; + const_iterator cend() const BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::sgtree::rbegin() - reverse_iterator rbegin(); + reverse_iterator rbegin() BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::sgtree::rbegin()const - const_reverse_iterator rbegin() const; + const_reverse_iterator rbegin() const BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::sgtree::crbegin()const - const_reverse_iterator crbegin() const; + const_reverse_iterator crbegin() const BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::sgtree::rend() - reverse_iterator rend(); + reverse_iterator rend() BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::sgtree::rend()const - const_reverse_iterator rend() const; + const_reverse_iterator rend() const BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::sgtree::crend()const - const_reverse_iterator crend() const; + const_reverse_iterator crend() const BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::sgtree::root() - iterator root(); + iterator root() BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::sgtree::root()const - const_iterator root() const; + const_iterator root() const BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::sgtree::croot()const - const_iterator croot() const; + const_iterator croot() const BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::sgtree::container_from_end_iterator(iterator) - static sg_multiset_impl &container_from_end_iterator(iterator end_iterator); + static sg_multiset_impl &container_from_end_iterator(iterator end_iterator) BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::sgtree::container_from_end_iterator(const_iterator) - static const sg_multiset_impl &container_from_end_iterator(const_iterator end_iterator); + static const sg_multiset_impl &container_from_end_iterator(const_iterator end_iterator) BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::sgtree::container_from_iterator(iterator) - static sg_multiset_impl &container_from_iterator(iterator it); + static sg_multiset_impl &container_from_iterator(iterator it) BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::sgtree::container_from_iterator(const_iterator) - static const sg_multiset_impl &container_from_iterator(const_iterator it); + static const sg_multiset_impl &container_from_iterator(const_iterator it) BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::sgtree::key_comp()const key_compare key_comp() const; @@ -729,10 +729,10 @@ class sg_multiset_impl value_compare value_comp() const; //! @copydoc ::boost::intrusive::sgtree::empty()const - bool empty() const; + bool empty() const BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::sgtree::size()const - size_type size() const; + size_type size() const BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::sgtree::swap void swap(sg_multiset_impl& other); @@ -767,19 +767,19 @@ class sg_multiset_impl #ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED //! @copydoc ::boost::intrusive::sgtree::insert_before - iterator insert_before(const_iterator pos, reference value); + iterator insert_before(const_iterator pos, reference value) BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::sgtree::push_back - void push_back(reference value); + void push_back(reference value) BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::sgtree::push_front - void push_front(reference value); + void push_front(reference value) BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::sgtree::erase(const_iterator) - iterator erase(const_iterator i); + iterator erase(const_iterator i) BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::sgtree::erase(const_iterator,const_iterator) - iterator erase(const_iterator b, const_iterator e); + iterator erase(const_iterator b, const_iterator e) BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::sgtree::erase(const key_type &) size_type erase(const key_type &key); @@ -790,11 +790,11 @@ class sg_multiset_impl //! @copydoc ::boost::intrusive::sgtree::erase_and_dispose(const_iterator,Disposer) template - iterator erase_and_dispose(const_iterator i, Disposer disposer); + iterator erase_and_dispose(const_iterator i, Disposer disposer) BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::sgtree::erase_and_dispose(const_iterator,const_iterator,Disposer) template - iterator erase_and_dispose(const_iterator b, const_iterator e, Disposer disposer); + iterator erase_and_dispose(const_iterator b, const_iterator e, Disposer disposer) BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::sgtree::erase_and_dispose(const key_type &, Disposer) template @@ -805,11 +805,11 @@ class sg_multiset_impl size_type erase_and_dispose(const KeyType& key, KeyTypeKeyCompare comp, Disposer disposer); //! @copydoc ::boost::intrusive::sgtree::clear - void clear(); + void clear() BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::sgtree::clear_and_dispose template - void clear_and_dispose(Disposer disposer); + void clear_and_dispose(Disposer disposer) BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::sgtree::count(const key_type &)const size_type count(const key_type &key) const; @@ -895,40 +895,40 @@ class sg_multiset_impl (const KeyType& lower_key, const KeyType& upper_key, KeyTypeKeyCompare comp, bool left_closed, bool right_closed) const; //! @copydoc ::boost::intrusive::sgtree::s_iterator_to(reference) - static iterator s_iterator_to(reference value); + static iterator s_iterator_to(reference value) BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::sgtree::s_iterator_to(const_reference) - static const_iterator s_iterator_to(const_reference value); + static const_iterator s_iterator_to(const_reference value) BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::sgtree::iterator_to(reference) - iterator iterator_to(reference value); + iterator iterator_to(reference value) BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::sgtree::iterator_to(const_reference)const - const_iterator iterator_to(const_reference value) const; + const_iterator iterator_to(const_reference value) const BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::sgtree::init_node(reference) - static void init_node(reference value); + static void init_node(reference value) BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::sgtree::unlink_leftmost_without_rebalance - pointer unlink_leftmost_without_rebalance(); + pointer unlink_leftmost_without_rebalance() BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::sgtree::replace_node - void replace_node(iterator replace_this, reference with_this); + void replace_node(iterator replace_this, reference with_this) BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::sgtree::remove_node - void remove_node(reference value); + void remove_node(reference value) BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::sgtree::rebalance - void rebalance(); + void rebalance() BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::sgtree::rebalance_subtree - iterator rebalance_subtree(iterator root); + iterator rebalance_subtree(iterator root) BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::sgtree::balance_factor() - float balance_factor() const; + float balance_factor() const BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::sgtree::balance_factor(float) - void balance_factor(float new_alpha); + void balance_factor(float new_alpha) BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::treap::merge_unique template @@ -1071,16 +1071,16 @@ class sg_multiset BOOST_INTRUSIVE_FORCEINLINE void clone_from(BOOST_RV_REF(sg_multiset) src, Cloner cloner, Disposer disposer) { Base::clone_from(BOOST_MOVE_BASE(Base, src), cloner, disposer); } - BOOST_INTRUSIVE_FORCEINLINE static sg_multiset &container_from_end_iterator(iterator end_iterator) + BOOST_INTRUSIVE_FORCEINLINE static sg_multiset &container_from_end_iterator(iterator end_iterator) BOOST_NOEXCEPT { return static_cast(Base::container_from_end_iterator(end_iterator)); } - BOOST_INTRUSIVE_FORCEINLINE static const sg_multiset &container_from_end_iterator(const_iterator end_iterator) + BOOST_INTRUSIVE_FORCEINLINE static const sg_multiset &container_from_end_iterator(const_iterator end_iterator) BOOST_NOEXCEPT { return static_cast(Base::container_from_end_iterator(end_iterator)); } - BOOST_INTRUSIVE_FORCEINLINE static sg_multiset &container_from_iterator(iterator it) + BOOST_INTRUSIVE_FORCEINLINE static sg_multiset &container_from_iterator(iterator it) BOOST_NOEXCEPT { return static_cast(Base::container_from_iterator(it)); } - BOOST_INTRUSIVE_FORCEINLINE static const sg_multiset &container_from_iterator(const_iterator it) + BOOST_INTRUSIVE_FORCEINLINE static const sg_multiset &container_from_iterator(const_iterator it) BOOST_NOEXCEPT { return static_cast(Base::container_from_iterator(it)); } }; diff --git a/include/boost/intrusive/sgtree.hpp b/include/boost/intrusive/sgtree.hpp index 15e7d0c46..9e687da10 100644 --- a/include/boost/intrusive/sgtree.hpp +++ b/include/boost/intrusive/sgtree.hpp @@ -39,7 +39,6 @@ #include #include #include //std::pair -#include #include #if defined(BOOST_HAS_PRAGMA_ONCE) @@ -347,61 +346,61 @@ class sgtree_impl ~sgtree_impl(); //! @copydoc ::boost::intrusive::bstree::begin() - iterator begin(); + iterator begin() BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::bstree::begin()const - const_iterator begin() const; + const_iterator begin() const BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::bstree::cbegin()const - const_iterator cbegin() const; + const_iterator cbegin() const BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::bstree::end() - iterator end(); + iterator end() BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::bstree::end()const - const_iterator end() const; + const_iterator end() const BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::bstree::cend()const - const_iterator cend() const; + const_iterator cend() const BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::bstree::rbegin() - reverse_iterator rbegin(); + reverse_iterator rbegin() BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::bstree::rbegin()const - const_reverse_iterator rbegin() const; + const_reverse_iterator rbegin() const BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::bstree::crbegin()const - const_reverse_iterator crbegin() const; + const_reverse_iterator crbegin() const BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::bstree::rend() - reverse_iterator rend(); + reverse_iterator rend() BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::bstree::rend()const - const_reverse_iterator rend() const; + const_reverse_iterator rend() const BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::bstree::crend()const - const_reverse_iterator crend() const; + const_reverse_iterator crend() const BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::bstree::root() - iterator root(); + iterator root() BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::bstree::root()const - const_iterator root() const; + const_iterator root() const BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::bstree::croot()const - const_iterator croot() const; + const_iterator croot() const BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::bstree::container_from_end_iterator(iterator) - static sgtree_impl &container_from_end_iterator(iterator end_iterator); + static sgtree_impl &container_from_end_iterator(iterator end_iterator) BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::bstree::container_from_end_iterator(const_iterator) - static const sgtree_impl &container_from_end_iterator(const_iterator end_iterator); + static const sgtree_impl &container_from_end_iterator(const_iterator end_iterator) BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::bstree::container_from_iterator(iterator) - static sgtree_impl &container_from_iterator(iterator it); + static sgtree_impl &container_from_iterator(iterator it) BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::bstree::container_from_iterator(const_iterator) - static const sgtree_impl &container_from_iterator(const_iterator it); + static const sgtree_impl &container_from_iterator(const_iterator it) BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::bstree::key_comp()const key_compare key_comp() const; @@ -410,10 +409,10 @@ class sgtree_impl value_compare value_comp() const; //! @copydoc ::boost::intrusive::bstree::empty()const - bool empty() const; + bool empty() const BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::bstree::size()const - size_type size() const; + size_type size() const BOOST_NOEXCEPT; #endif //#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED @@ -540,7 +539,7 @@ class sgtree_impl { return this->insert_unique_check(hint, key, this->key_comp(), commit_data); } //! @copydoc ::boost::intrusive::bstree::insert_unique_commit - iterator insert_unique_commit(reference value, const insert_commit_data &commit_data) + iterator insert_unique_commit(reference value, const insert_commit_data &commit_data) BOOST_NOEXCEPT { node_ptr to_insert(this->get_value_traits().to_node_ptr(value)); BOOST_INTRUSIVE_SAFE_HOOK_DEFAULT_ASSERT(!safemode_or_autounlink || node_algorithms::unique(to_insert)); @@ -569,7 +568,7 @@ class sgtree_impl } //! @copydoc ::boost::intrusive::bstree::insert_before - iterator insert_before(const_iterator pos, reference value) + iterator insert_before(const_iterator pos, reference value) BOOST_NOEXCEPT { node_ptr to_insert(this->get_value_traits().to_node_ptr(value)); BOOST_INTRUSIVE_SAFE_HOOK_DEFAULT_ASSERT(!safemode_or_autounlink || node_algorithms::unique(to_insert)); @@ -583,7 +582,7 @@ class sgtree_impl } //! @copydoc ::boost::intrusive::bstree::push_back - void push_back(reference value) + void push_back(reference value) BOOST_NOEXCEPT { node_ptr to_insert(this->get_value_traits().to_node_ptr(value)); BOOST_INTRUSIVE_SAFE_HOOK_DEFAULT_ASSERT(!safemode_or_autounlink || node_algorithms::unique(to_insert)); @@ -596,7 +595,7 @@ class sgtree_impl } //! @copydoc ::boost::intrusive::bstree::push_front - void push_front(reference value) + void push_front(reference value) BOOST_NOEXCEPT { node_ptr to_insert(this->get_value_traits().to_node_ptr(value)); BOOST_INTRUSIVE_SAFE_HOOK_DEFAULT_ASSERT(!safemode_or_autounlink || node_algorithms::unique(to_insert)); @@ -610,7 +609,7 @@ class sgtree_impl //! @copydoc ::boost::intrusive::bstree::erase(const_iterator) - iterator erase(const_iterator i) + iterator erase(const_iterator i) BOOST_NOEXCEPT { const_iterator ret(i); ++ret; @@ -622,13 +621,13 @@ class sgtree_impl , max_tree_size, this->get_alpha_by_max_size_func()); this->max_tree_size_ = (size_type)max_tree_size; this->tree_type::sz_traits().decrement(); - if(safemode_or_autounlink) + BOOST_IF_CONSTEXPR(safemode_or_autounlink) node_algorithms::init(to_erase); return ret.unconst(); } //! @copydoc ::boost::intrusive::bstree::erase(const_iterator,const_iterator) - iterator erase(const_iterator b, const_iterator e) + iterator erase(const_iterator b, const_iterator e) BOOST_NOEXCEPT { size_type n; return private_erase(b, e, n); } //! @copydoc ::boost::intrusive::bstree::erase(const key_type &) @@ -649,7 +648,7 @@ class sgtree_impl //! @copydoc ::boost::intrusive::bstree::erase_and_dispose(const_iterator,Disposer) template - iterator erase_and_dispose(const_iterator i, Disposer disposer) + iterator erase_and_dispose(const_iterator i, Disposer disposer) BOOST_NOEXCEPT { node_ptr to_erase(i.pointed_node()); iterator ret(this->erase(i)); @@ -659,13 +658,13 @@ class sgtree_impl #if !defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED) template - iterator erase_and_dispose(iterator i, Disposer disposer) + iterator erase_and_dispose(iterator i, Disposer disposer) BOOST_NOEXCEPT { return this->erase_and_dispose(const_iterator(i), disposer); } #endif //! @copydoc ::boost::intrusive::bstree::erase_and_dispose(const_iterator,const_iterator,Disposer) template - iterator erase_and_dispose(const_iterator b, const_iterator e, Disposer disposer) + iterator erase_and_dispose(const_iterator b, const_iterator e, Disposer disposer) BOOST_NOEXCEPT { size_type n; return private_erase(b, e, n, disposer); } //! @copydoc ::boost::intrusive::bstree::erase_and_dispose(const key_type &, Disposer) @@ -691,7 +690,7 @@ class sgtree_impl } //! @copydoc ::boost::intrusive::bstree::clear - void clear() + void clear() BOOST_NOEXCEPT { tree_type::clear(); this->max_tree_size_ = 0; @@ -699,7 +698,7 @@ class sgtree_impl //! @copydoc ::boost::intrusive::bstree::clear_and_dispose template - void clear_and_dispose(Disposer disposer) + void clear_and_dispose(Disposer disposer) BOOST_NOEXCEPT { tree_type::clear_and_dispose(disposer); this->max_tree_size_ = 0; @@ -850,34 +849,34 @@ class sgtree_impl (const KeyType& lower_key, const KeyType& upper_key, KeyTypeKeyCompare comp, bool left_closed, bool right_closed) const; //! @copydoc ::boost::intrusive::bstree::s_iterator_to(reference) - static iterator s_iterator_to(reference value); + static iterator s_iterator_to(reference value) BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::bstree::s_iterator_to(const_reference) - static const_iterator s_iterator_to(const_reference value); + static const_iterator s_iterator_to(const_reference value) BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::bstree::iterator_to(reference) - iterator iterator_to(reference value); + iterator iterator_to(reference value) BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::bstree::iterator_to(const_reference)const - const_iterator iterator_to(const_reference value) const; + const_iterator iterator_to(const_reference value) const BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::bstree::init_node(reference) - static void init_node(reference value); + static void init_node(reference value) BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::bstree::unlink_leftmost_without_rebalance - pointer unlink_leftmost_without_rebalance(); + pointer unlink_leftmost_without_rebalance() BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::bstree::replace_node - void replace_node(iterator replace_this, reference with_this); + void replace_node(iterator replace_this, reference with_this) BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::bstree::remove_node - void remove_node(reference value); + void remove_node(reference value) BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::bstree::rebalance - void rebalance(); + void rebalance() BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::bstree::rebalance_subtree - iterator rebalance_subtree(iterator root); + iterator rebalance_subtree(iterator root) BOOST_NOEXCEPT; friend bool operator< (const sgtree_impl &x, const sgtree_impl &y); @@ -900,7 +899,7 @@ class sgtree_impl //! Throws: Nothing. //! //! Complexity: Constant. - float balance_factor() const + float balance_factor() const BOOST_NOEXCEPT { return this->get_alpha_traits().get_alpha(); } //! Requires: new_alpha must be a value between 0.5 and 1.0 @@ -911,7 +910,7 @@ class sgtree_impl //! Throws: Nothing. //! //! Complexity: Linear to the elements in the subtree. - void balance_factor(float new_alpha) + void balance_factor(float new_alpha) BOOST_NOEXCEPT { //The alpha factor CAN't be changed if the fixed, floating operation-less //1/sqrt(2) alpha factor option is activated @@ -930,14 +929,14 @@ class sgtree_impl /// @cond private: template - iterator private_erase(const_iterator b, const_iterator e, size_type &n, Disposer disposer) + iterator private_erase(const_iterator b, const_iterator e, size_type &n, Disposer disposer) BOOST_NOEXCEPT { for(n = 0; b != e; ++n) this->erase_and_dispose(b++, disposer); return b.unconst(); } - iterator private_erase(const_iterator b, const_iterator e, size_type &n) + iterator private_erase(const_iterator b, const_iterator e, size_type &n) BOOST_NOEXCEPT { for(n = 0; b != e; ++n) this->erase(b++); @@ -1051,16 +1050,16 @@ class sgtree BOOST_INTRUSIVE_FORCEINLINE void clone_from(BOOST_RV_REF(sgtree) src, Cloner cloner, Disposer disposer) { Base::clone_from(BOOST_MOVE_BASE(Base, src), cloner, disposer); } - BOOST_INTRUSIVE_FORCEINLINE static sgtree &container_from_end_iterator(iterator end_iterator) + BOOST_INTRUSIVE_FORCEINLINE static sgtree &container_from_end_iterator(iterator end_iterator) BOOST_NOEXCEPT { return static_cast(Base::container_from_end_iterator(end_iterator)); } - BOOST_INTRUSIVE_FORCEINLINE static const sgtree &container_from_end_iterator(const_iterator end_iterator) + BOOST_INTRUSIVE_FORCEINLINE static const sgtree &container_from_end_iterator(const_iterator end_iterator) BOOST_NOEXCEPT { return static_cast(Base::container_from_end_iterator(end_iterator)); } - BOOST_INTRUSIVE_FORCEINLINE static sgtree &container_from_iterator(iterator it) + BOOST_INTRUSIVE_FORCEINLINE static sgtree &container_from_iterator(iterator it) BOOST_NOEXCEPT { return static_cast(Base::container_from_iterator(it)); } - BOOST_INTRUSIVE_FORCEINLINE static const sgtree &container_from_iterator(const_iterator it) + BOOST_INTRUSIVE_FORCEINLINE static const sgtree &container_from_iterator(const_iterator it) BOOST_NOEXCEPT { return static_cast(Base::container_from_iterator(it)); } }; diff --git a/include/boost/intrusive/sgtree_algorithms.hpp b/include/boost/intrusive/sgtree_algorithms.hpp index a3e233ce0..726dbb997 100644 --- a/include/boost/intrusive/sgtree_algorithms.hpp +++ b/include/boost/intrusive/sgtree_algorithms.hpp @@ -85,53 +85,53 @@ class sgtree_algorithms }; #ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED - //! @copydoc ::boost::intrusive::bstree_algorithms::get_header(const const_node_ptr&) - static node_ptr get_header(const_node_ptr n); + //! @copydoc ::boost::intrusive::bstree_algorithms::get_header(const_node_ptr) + static node_ptr get_header(const_node_ptr n) BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::bstree_algorithms::begin_node - static node_ptr begin_node(const_node_ptr header); + static node_ptr begin_node(const_node_ptr header) BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::bstree_algorithms::end_node - static node_ptr end_node(const_node_ptr header); + static node_ptr end_node(const_node_ptr header) BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::bstree_algorithms::swap_tree - static void swap_tree(node_ptr header1, node_ptr header2); + static void swap_tree(node_ptr header1, node_ptr header2) BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::bstree_algorithms::swap_nodes(node_ptr,node_ptr) - static void swap_nodes(node_ptr node1, node_ptr node2); + static void swap_nodes(node_ptr node1, node_ptr node2) BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::bstree_algorithms::swap_nodes(node_ptr,node_ptr,node_ptr,node_ptr) - static void swap_nodes(node_ptr node1, node_ptr header1, node_ptr node2, node_ptr header2); + static void swap_nodes(node_ptr node1, node_ptr header1, node_ptr node2, node_ptr header2) BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::bstree_algorithms::replace_node(node_ptr,node_ptr) - static void replace_node(node_ptr node_to_be_replaced, node_ptr new_node); + static void replace_node(node_ptr node_to_be_replaced, node_ptr new_node) BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::bstree_algorithms::replace_node(node_ptr,node_ptr,node_ptr) - static void replace_node(node_ptr node_to_be_replaced, node_ptr header, node_ptr new_node); + static void replace_node(node_ptr node_to_be_replaced, node_ptr header, node_ptr new_node) BOOST_NOEXCEPT; //Unlink is not possible since tree metadata is needed to update the tree - //!static void unlink(node_ptr node); + //!static void unlink(node_ptr n) BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::bstree_algorithms::unlink_leftmost_without_rebalance - static node_ptr unlink_leftmost_without_rebalance(node_ptr header); + static node_ptr unlink_leftmost_without_rebalance(node_ptr header) BOOST_NOEXCEPT; - //! @copydoc ::boost::intrusive::bstree_algorithms::unique(const const_node_ptr&) - static bool unique(const_node_ptr node); + //! @copydoc ::boost::intrusive::bstree_algorithms::unique(const_node_ptr) + static bool unique(const_node_ptr n) BOOST_NOEXCEPT; - //! @copydoc ::boost::intrusive::bstree_algorithms::size(const const_node_ptr&) - static std::size_t size(const_node_ptr header); + //! @copydoc ::boost::intrusive::bstree_algorithms::size(const_node_ptr) + static std::size_t size(const_node_ptr header) BOOST_NOEXCEPT; - //! @copydoc ::boost::intrusive::bstree_algorithms::next_node(const node_ptr&) - static node_ptr next_node(node_ptr node); + //! @copydoc ::boost::intrusive::bstree_algorithms::next_node(node_ptr) + static node_ptr next_node(node_ptr n) BOOST_NOEXCEPT; - //! @copydoc ::boost::intrusive::bstree_algorithms::prev_node(const node_ptr&) - static node_ptr prev_node(node_ptr node); + //! @copydoc ::boost::intrusive::bstree_algorithms::prev_node(node_ptr) + static node_ptr prev_node(node_ptr n) BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::bstree_algorithms::init(node_ptr) - static void init(node_ptr node); + static void init(node_ptr n) BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::bstree_algorithms::init_header(node_ptr) - static void init_header(node_ptr header); + static void init_header(node_ptr header) BOOST_NOEXCEPT; #endif //#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED //! @copydoc ::boost::intrusive::bstree_algorithms::erase(node_ptr,node_ptr) @@ -141,7 +141,7 @@ class sgtree_algorithms bstree_algo::erase(header, z); --tree_size; if (tree_size > 0 && - tree_size < alpha_by_maxsize(max_tree_size)){ + tree_size < static_cast(alpha_by_maxsize(max_tree_size))){ bstree_algo::rebalance(header); max_tree_size = tree_size; } @@ -149,42 +149,42 @@ class sgtree_algorithms } #ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED - //! @copydoc ::boost::intrusive::bstree_algorithms::clone(const const_node_ptr&,node_ptr,Cloner,Disposer) + //! @copydoc ::boost::intrusive::bstree_algorithms::clone(const_node_ptr,node_ptr,Cloner,Disposer) template static void clone (const_node_ptr source_header, node_ptr target_header, Cloner cloner, Disposer disposer); - //! @copydoc ::boost::intrusive::bstree_algorithms::clear_and_dispose(const node_ptr&,Disposer) + //! @copydoc ::boost::intrusive::bstree_algorithms::clear_and_dispose(node_ptr,Disposer) template - static void clear_and_dispose(node_ptr header, Disposer disposer); + static void clear_and_dispose(node_ptr header, Disposer disposer) BOOST_NOEXCEPT; - //! @copydoc ::boost::intrusive::bstree_algorithms::lower_bound(const const_node_ptr&,const KeyType&,KeyNodePtrCompare) + //! @copydoc ::boost::intrusive::bstree_algorithms::lower_bound(const_node_ptr,const KeyType&,KeyNodePtrCompare) template static node_ptr lower_bound (const_node_ptr header, const KeyType &key, KeyNodePtrCompare comp); - //! @copydoc ::boost::intrusive::bstree_algorithms::upper_bound(const const_node_ptr&,const KeyType&,KeyNodePtrCompare) + //! @copydoc ::boost::intrusive::bstree_algorithms::upper_bound(const_node_ptr,const KeyType&,KeyNodePtrCompare) template static node_ptr upper_bound (const_node_ptr header, const KeyType &key, KeyNodePtrCompare comp); - //! @copydoc ::boost::intrusive::bstree_algorithms::find(const const_node_ptr&, const KeyType&,KeyNodePtrCompare) + //! @copydoc ::boost::intrusive::bstree_algorithms::find(const_node_ptr, const KeyType&,KeyNodePtrCompare) template static node_ptr find (const_node_ptr header, const KeyType &key, KeyNodePtrCompare comp); - //! @copydoc ::boost::intrusive::bstree_algorithms::equal_range(const const_node_ptr&,const KeyType&,KeyNodePtrCompare) + //! @copydoc ::boost::intrusive::bstree_algorithms::equal_range(const_node_ptr,const KeyType&,KeyNodePtrCompare) template static std::pair equal_range (const_node_ptr header, const KeyType &key, KeyNodePtrCompare comp); - //! @copydoc ::boost::intrusive::bstree_algorithms::bounded_range(const const_node_ptr&,const KeyType&,const KeyType&,KeyNodePtrCompare,bool,bool) + //! @copydoc ::boost::intrusive::bstree_algorithms::bounded_range(const_node_ptr,const KeyType&,const KeyType&,KeyNodePtrCompare,bool,bool) template static std::pair bounded_range (const_node_ptr header, const KeyType &lower_key, const KeyType &upper_key, KeyNodePtrCompare comp , bool left_closed, bool right_closed); - //! @copydoc ::boost::intrusive::bstree_algorithms::count(const const_node_ptr&,const KeyType&,KeyNodePtrCompare) + //! @copydoc ::boost::intrusive::bstree_algorithms::count(const_node_ptr,const KeyType&,KeyNodePtrCompare) template static std::size_t count(const_node_ptr header, const KeyType &key, KeyNodePtrCompare comp); @@ -241,7 +241,7 @@ class sgtree_algorithms //! @copydoc ::boost::intrusive::bstree_algorithms::push_back(node_ptr,node_ptr) template static void push_back(node_ptr header, node_ptr new_node - ,std::size_t tree_size, H_Alpha h_alpha, std::size_t &max_tree_size) + ,std::size_t tree_size, H_Alpha h_alpha, std::size_t &max_tree_size) BOOST_NOEXCEPT { std::size_t depth; bstree_algo::push_back(header, new_node, &depth); @@ -251,14 +251,14 @@ class sgtree_algorithms //! @copydoc ::boost::intrusive::bstree_algorithms::push_front(node_ptr,node_ptr) template static void push_front(node_ptr header, node_ptr new_node - ,std::size_t tree_size, H_Alpha h_alpha, std::size_t &max_tree_size) + ,std::size_t tree_size, H_Alpha h_alpha, std::size_t &max_tree_size) BOOST_NOEXCEPT { std::size_t depth; bstree_algo::push_front(header, new_node, &depth); rebalance_after_insertion(new_node, depth, tree_size+1, h_alpha, max_tree_size); } - //! @copydoc ::boost::intrusive::bstree_algorithms::insert_unique_check(const const_node_ptr&,const KeyType&,KeyNodePtrCompare,insert_commit_data&) + //! @copydoc ::boost::intrusive::bstree_algorithms::insert_unique_check(const_node_ptr,const KeyType&,KeyNodePtrCompare,insert_commit_data&) template static std::pair insert_unique_check (const_node_ptr header, const KeyType &key @@ -271,7 +271,7 @@ class sgtree_algorithms return ret; } - //! @copydoc ::boost::intrusive::bstree_algorithms::insert_unique_check(const const_node_ptr&,const node_ptr&,const KeyType&,KeyNodePtrCompare,insert_commit_data&) + //! @copydoc ::boost::intrusive::bstree_algorithms::insert_unique_check(const_node_ptr,node_ptr,const KeyType&,KeyNodePtrCompare,insert_commit_data&) template static std::pair insert_unique_check (const_node_ptr header, node_ptr hint, const KeyType &key @@ -323,13 +323,13 @@ class sgtree_algorithms #ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED //! @copydoc ::boost::intrusive::bstree_algorithms::is_header - static bool is_header(const_node_ptr p); + static bool is_header(const_node_ptr p) BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::bstree_algorithms::is_header - static void rebalance(node_ptr header); + static void rebalance(node_ptr header) BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::bstree_algorithms::rebalance_subtree - static node_ptr rebalance_subtree(node_ptr old_root) + static node_ptr rebalance_subtree(node_ptr old_root) BOOST_NOEXCEPT #endif //#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED /// @cond @@ -348,7 +348,7 @@ class sgtree_algorithms template static void insert_commit (node_ptr header, node_ptr new_value, const insert_commit_data &commit_data - ,std::size_t tree_size, H_Alpha h_alpha, std::size_t &max_tree_size) + ,std::size_t tree_size, H_Alpha h_alpha, std::size_t &max_tree_size) BOOST_NOEXCEPT { bstree_algo::insert_unique_commit(header, new_value, commit_data); rebalance_after_insertion(new_value, commit_data.depth, tree_size+1, h_alpha, max_tree_size); @@ -357,7 +357,7 @@ class sgtree_algorithms template static void rebalance_after_insertion (node_ptr x, std::size_t depth - , std::size_t tree_size, H_Alpha h_alpha, std::size_t &max_tree_size) + , std::size_t tree_size, H_Alpha h_alpha, std::size_t &max_tree_size) BOOST_NOEXCEPT { if(tree_size > max_tree_size) max_tree_size = tree_size; diff --git a/include/boost/intrusive/slist.hpp b/include/boost/intrusive/slist.hpp index 444f8e93c..7319bf313 100644 --- a/include/boost/intrusive/slist.hpp +++ b/include/boost/intrusive/slist.hpp @@ -37,13 +37,13 @@ #include #include #include +#include +#include #include #include -#include //std::less #include //std::size_t -#include //std::pair #if defined(BOOST_HAS_PRAGMA_ONCE) # pragma once @@ -172,56 +172,54 @@ class slist_impl //A list with cached last node is incompatible with auto-unlink hooks! BOOST_STATIC_ASSERT(!(cache_last && ((int)value_traits::link_mode == (int)auto_unlink))); - node_ptr get_end_node() - { return node_ptr(linear ? node_ptr() : this->get_root_node()); } + BOOST_INTRUSIVE_FORCEINLINE node_ptr get_end_node() + { return node_algorithms::end_node(this->get_root_node()); } - const_node_ptr get_end_node() const - { - return const_node_ptr - (linear ? const_node_ptr() : this->get_root_node()); } + BOOST_INTRUSIVE_FORCEINLINE const_node_ptr get_end_node() const + { return node_algorithms::end_node(this->get_root_node()); } - node_ptr get_root_node() + BOOST_INTRUSIVE_FORCEINLINE node_ptr get_root_node() { return data_.root_plus_size_.header_holder_.get_node(); } - const_node_ptr get_root_node() const + BOOST_INTRUSIVE_FORCEINLINE const_node_ptr get_root_node() const { return data_.root_plus_size_.header_holder_.get_node(); } - node_ptr get_last_node() + BOOST_INTRUSIVE_FORCEINLINE node_ptr get_last_node() { return this->get_last_node(detail::bool_()); } - const_node_ptr get_last_node() const + BOOST_INTRUSIVE_FORCEINLINE const_node_ptr get_last_node() const { return this->get_last_node(detail::bool_()); } - void set_last_node(const node_ptr &n) + BOOST_INTRUSIVE_FORCEINLINE void set_last_node(node_ptr n) { return this->set_last_node(n, detail::bool_()); } - static node_ptr get_last_node(detail::bool_) + BOOST_INTRUSIVE_FORCEINLINE static node_ptr get_last_node(detail::bool_) { //This function shall not be used if cache_last is not true BOOST_INTRUSIVE_INVARIANT_ASSERT(cache_last); return node_ptr(); } - static void set_last_node(const node_ptr &, detail::bool_) + BOOST_INTRUSIVE_FORCEINLINE static void set_last_node(node_ptr , detail::bool_) { //This function shall not be used if cache_last is not true BOOST_INTRUSIVE_INVARIANT_ASSERT(cache_last); } - node_ptr get_last_node(detail::bool_) + BOOST_INTRUSIVE_FORCEINLINE node_ptr get_last_node(detail::bool_) { return node_ptr(data_.root_plus_size_.last_); } - const_node_ptr get_last_node(detail::bool_) const + BOOST_INTRUSIVE_FORCEINLINE const_node_ptr get_last_node(detail::bool_) const { return const_node_ptr(data_.root_plus_size_.last_); } - void set_last_node(const node_ptr & n, detail::bool_) + BOOST_INTRUSIVE_FORCEINLINE void set_last_node(node_ptr n, detail::bool_) { data_.root_plus_size_.last_ = n; } void set_default_constructed_state() { node_algorithms::init_header(this->get_root_node()); this->priv_size_traits().set_size(size_type(0)); - if(cache_last){ + BOOST_IF_CONSTEXPR(cache_last){ this->set_last_node(this->get_root_node()); } } @@ -243,22 +241,22 @@ class slist_impl root_plus_size root_plus_size_; } data_; - size_traits &priv_size_traits() + BOOST_INTRUSIVE_FORCEINLINE size_traits &priv_size_traits() { return data_.root_plus_size_; } - const size_traits &priv_size_traits() const + BOOST_INTRUSIVE_FORCEINLINE const size_traits &priv_size_traits() const { return data_.root_plus_size_; } - const value_traits &priv_value_traits() const + BOOST_INTRUSIVE_FORCEINLINE const value_traits &priv_value_traits() const { return data_; } - value_traits &priv_value_traits() + BOOST_INTRUSIVE_FORCEINLINE value_traits &priv_value_traits() { return data_; } typedef typename boost::intrusive::value_traits_pointers ::const_value_traits_ptr const_value_traits_ptr; - const_value_traits_ptr priv_value_traits_ptr() const + BOOST_INTRUSIVE_FORCEINLINE const_value_traits_ptr priv_value_traits_ptr() const { return pointer_traits::pointer_to(this->priv_value_traits()); } /// @endcond @@ -282,13 +280,13 @@ class slist_impl //! list. Iterators of this list and all the references are not invalidated. //! //! Warning: Experimental function, don't use it! - slist_impl( const node_ptr & f, const node_ptr & before_l + slist_impl( node_ptr f, node_ptr before_l , size_type n, const value_traits &v_traits = value_traits()) : data_(v_traits) { if(n){ this->priv_size_traits().set_size(n); - if(cache_last){ + BOOST_IF_CONSTEXPR(cache_last){ this->set_last_node(before_l); } node_traits::set_next(this->get_root_node(), f); @@ -371,7 +369,7 @@ class slist_impl //! it's a safe-mode or auto-unlink value. Otherwise constant. ~slist_impl() { - if(is_safe_autounlink::value){ + BOOST_IF_CONSTEXPR(is_safe_autounlink::value){ this->clear(); node_algorithms::init(this->get_root_node()); } @@ -385,9 +383,9 @@ class slist_impl //! if it's a safe-mode or auto-unlink value_type. Constant time otherwise. //! //! Note: Invalidates the iterators (but not the references) to the erased elements. - void clear() + void clear() BOOST_NOEXCEPT { - if(safemode_or_autounlink){ + BOOST_IF_CONSTEXPR(safemode_or_autounlink){ this->clear_and_dispose(detail::null_disposer()); } else{ @@ -406,16 +404,12 @@ class slist_impl //! //! Note: Invalidates the iterators to the erased elements. template - void clear_and_dispose(Disposer disposer) + void clear_and_dispose(Disposer disposer) BOOST_NOEXCEPT { - const_iterator it(this->begin()), itend(this->end()); - while(it != itend){ - node_ptr to_erase(it.pointed_node()); - ++it; - if(safemode_or_autounlink) - node_algorithms::init(to_erase); - disposer(priv_value_traits().to_value_ptr(to_erase)); - } + node_algorithms::detach_and_dispose + ( this->get_root_node() + , detail::node_disposer + (disposer, &this->priv_value_traits()) ); this->set_default_constructed_state(); } @@ -429,11 +423,11 @@ class slist_impl //! Complexity: Constant. //! //! Note: Does not affect the validity of iterators and references. - void push_front(reference value) + void push_front(reference value) BOOST_NOEXCEPT { node_ptr to_insert = priv_value_traits().to_node_ptr(value); BOOST_INTRUSIVE_SAFE_HOOK_DEFAULT_ASSERT(!safemode_or_autounlink || node_algorithms::inited(to_insert)); - if(cache_last){ + BOOST_IF_CONSTEXPR(cache_last){ if(this->empty()){ this->set_last_node(to_insert); } @@ -453,13 +447,13 @@ class slist_impl //! //! Note: Does not affect the validity of iterators and references. //! This function is only available is cache_last<> is true. - void push_back(reference value) + void push_back(reference value) BOOST_NOEXCEPT { BOOST_STATIC_ASSERT((cache_last)); node_ptr n = priv_value_traits().to_node_ptr(value); BOOST_INTRUSIVE_SAFE_HOOK_DEFAULT_ASSERT(!safemode_or_autounlink || node_algorithms::inited(n)); node_algorithms::link_after(this->get_last_node(), n); - if(cache_last){ + BOOST_IF_CONSTEXPR(cache_last){ this->set_last_node(n); } this->priv_size_traits().increment(); @@ -473,7 +467,7 @@ class slist_impl //! Complexity: Constant. //! //! Note: Invalidates the iterators (but not the references) to the erased element. - void pop_front() + void pop_front() BOOST_NOEXCEPT { return this->pop_front_and_dispose(detail::null_disposer()); } //! Requires: Disposer::operator()(pointer) shouldn't throw. @@ -487,15 +481,15 @@ class slist_impl //! //! Note: Invalidates the iterators to the erased element. template - void pop_front_and_dispose(Disposer disposer) + void pop_front_and_dispose(Disposer disposer) BOOST_NOEXCEPT { node_ptr to_erase = node_traits::get_next(this->get_root_node()); node_algorithms::unlink_after(this->get_root_node()); this->priv_size_traits().decrement(); - if(safemode_or_autounlink) + BOOST_IF_CONSTEXPR(safemode_or_autounlink) node_algorithms::init(to_erase); disposer(priv_value_traits().to_value_ptr(to_erase)); - if(cache_last){ + BOOST_IF_CONSTEXPR(cache_last){ if(this->empty()){ this->set_last_node(this->get_root_node()); } @@ -507,7 +501,7 @@ class slist_impl //! Throws: Nothing. //! //! Complexity: Constant. - reference front() + BOOST_INTRUSIVE_FORCEINLINE reference front() BOOST_NOEXCEPT { return *this->priv_value_traits().to_value_ptr(node_traits::get_next(this->get_root_node())); } //! Effects: Returns a const_reference to the first element of the list. @@ -515,7 +509,7 @@ class slist_impl //! Throws: Nothing. //! //! Complexity: Constant. - const_reference front() const + BOOST_INTRUSIVE_FORCEINLINE const_reference front() const BOOST_NOEXCEPT { return *this->priv_value_traits().to_value_ptr(detail::uncast(node_traits::get_next(this->get_root_node()))); } //! Effects: Returns a reference to the last element of the list. @@ -526,7 +520,7 @@ class slist_impl //! //! Note: Does not affect the validity of iterators and references. //! This function is only available is cache_last<> is true. - reference back() + reference back() BOOST_NOEXCEPT { BOOST_STATIC_ASSERT((cache_last)); return *this->priv_value_traits().to_value_ptr(this->get_last_node()); @@ -540,7 +534,7 @@ class slist_impl //! //! Note: Does not affect the validity of iterators and references. //! This function is only available is cache_last<> is true. - const_reference back() const + BOOST_INTRUSIVE_FORCEINLINE const_reference back() const BOOST_NOEXCEPT { BOOST_STATIC_ASSERT((cache_last)); return *this->priv_value_traits().to_value_ptr(this->get_last_node()); @@ -551,7 +545,7 @@ class slist_impl //! Throws: Nothing. //! //! Complexity: Constant. - iterator begin() + BOOST_INTRUSIVE_FORCEINLINE iterator begin() BOOST_NOEXCEPT { return iterator (node_traits::get_next(this->get_root_node()), this->priv_value_traits_ptr()); } //! Effects: Returns a const_iterator to the first element contained in the list. @@ -559,7 +553,7 @@ class slist_impl //! Throws: Nothing. //! //! Complexity: Constant. - const_iterator begin() const + BOOST_INTRUSIVE_FORCEINLINE const_iterator begin() const BOOST_NOEXCEPT { return const_iterator (node_traits::get_next(this->get_root_node()), this->priv_value_traits_ptr()); } //! Effects: Returns a const_iterator to the first element contained in the list. @@ -567,7 +561,7 @@ class slist_impl //! Throws: Nothing. //! //! Complexity: Constant. - const_iterator cbegin() const + BOOST_INTRUSIVE_FORCEINLINE const_iterator cbegin() const BOOST_NOEXCEPT { return const_iterator(node_traits::get_next(this->get_root_node()), this->priv_value_traits_ptr()); } //! Effects: Returns an iterator to the end of the list. @@ -575,7 +569,7 @@ class slist_impl //! Throws: Nothing. //! //! Complexity: Constant. - iterator end() + BOOST_INTRUSIVE_FORCEINLINE iterator end() BOOST_NOEXCEPT { return iterator(this->get_end_node(), this->priv_value_traits_ptr()); } //! Effects: Returns a const_iterator to the end of the list. @@ -583,7 +577,7 @@ class slist_impl //! Throws: Nothing. //! //! Complexity: Constant. - const_iterator end() const + BOOST_INTRUSIVE_FORCEINLINE const_iterator end() const BOOST_NOEXCEPT { return const_iterator(detail::uncast(this->get_end_node()), this->priv_value_traits_ptr()); } //! Effects: Returns a const_iterator to the end of the list. @@ -591,7 +585,7 @@ class slist_impl //! Throws: Nothing. //! //! Complexity: Constant. - const_iterator cend() const + BOOST_INTRUSIVE_FORCEINLINE const_iterator cend() const BOOST_NOEXCEPT { return this->end(); } //! Effects: Returns an iterator that points to a position @@ -600,7 +594,7 @@ class slist_impl //! Throws: Nothing. //! //! Complexity: Constant. - iterator before_begin() + BOOST_INTRUSIVE_FORCEINLINE iterator before_begin() BOOST_NOEXCEPT { return iterator(this->get_root_node(), this->priv_value_traits_ptr()); } //! Effects: Returns an iterator that points to a position @@ -609,7 +603,7 @@ class slist_impl //! Throws: Nothing. //! //! Complexity: Constant. - const_iterator before_begin() const + BOOST_INTRUSIVE_FORCEINLINE const_iterator before_begin() const BOOST_NOEXCEPT { return const_iterator(detail::uncast(this->get_root_node()), this->priv_value_traits_ptr()); } //! Effects: Returns an iterator that points to a position @@ -618,7 +612,7 @@ class slist_impl //! Throws: Nothing. //! //! Complexity: Constant. - const_iterator cbefore_begin() const + BOOST_INTRUSIVE_FORCEINLINE const_iterator cbefore_begin() const BOOST_NOEXCEPT { return this->before_begin(); } //! Effects: Returns an iterator to the last element contained in the list. @@ -628,7 +622,7 @@ class slist_impl //! Complexity: Constant. //! //! Note: This function is present only if cached_last<> option is true. - iterator last() + BOOST_INTRUSIVE_FORCEINLINE iterator last() BOOST_NOEXCEPT { //This function shall not be used if cache_last is not true BOOST_INTRUSIVE_INVARIANT_ASSERT(cache_last); @@ -642,7 +636,7 @@ class slist_impl //! Complexity: Constant. //! //! Note: This function is present only if cached_last<> option is true. - const_iterator last() const + BOOST_INTRUSIVE_FORCEINLINE const_iterator last() const BOOST_NOEXCEPT { //This function shall not be used if cache_last is not true BOOST_INTRUSIVE_INVARIANT_ASSERT(cache_last); @@ -656,7 +650,7 @@ class slist_impl //! Complexity: Constant. //! //! Note: This function is present only if cached_last<> option is true. - const_iterator clast() const + BOOST_INTRUSIVE_FORCEINLINE const_iterator clast() const BOOST_NOEXCEPT { return const_iterator(this->get_last_node(), this->priv_value_traits_ptr()); } //! Precondition: end_iterator must be a valid end iterator @@ -667,7 +661,7 @@ class slist_impl //! Throws: Nothing. //! //! Complexity: Constant. - static slist_impl &container_from_end_iterator(iterator end_iterator) + BOOST_INTRUSIVE_FORCEINLINE static slist_impl &container_from_end_iterator(iterator end_iterator) BOOST_NOEXCEPT { return slist_impl::priv_container_from_end_iterator(end_iterator); } //! Precondition: end_iterator must be a valid end const_iterator @@ -678,7 +672,7 @@ class slist_impl //! Throws: Nothing. //! //! Complexity: Constant. - static const slist_impl &container_from_end_iterator(const_iterator end_iterator) + BOOST_INTRUSIVE_FORCEINLINE static const slist_impl &container_from_end_iterator(const_iterator end_iterator) BOOST_NOEXCEPT { return slist_impl::priv_container_from_end_iterator(end_iterator); } //! Effects: Returns the number of the elements contained in the list. @@ -689,9 +683,9 @@ class slist_impl //! if constant_time_size is false. Constant time otherwise. //! //! Note: Does not affect the validity of iterators and references. - size_type size() const + BOOST_INTRUSIVE_FORCEINLINE size_type size() const BOOST_NOEXCEPT { - if(constant_time_size) + BOOST_IF_CONSTEXPR(constant_time_size) return this->priv_size_traits().get_size(); else return node_algorithms::count(this->get_root_node()) - 1; @@ -704,8 +698,8 @@ class slist_impl //! Complexity: Constant. //! //! Note: Does not affect the validity of iterators and references. - bool empty() const - { return node_algorithms::unique(this->get_root_node()); } + BOOST_INTRUSIVE_FORCEINLINE bool empty() const BOOST_NOEXCEPT + { return node_algorithms::is_empty(this->get_root_node()); } //! Effects: Swaps the elements of x and *this. //! @@ -717,7 +711,7 @@ class slist_impl //! Note: Does not affect the validity of iterators and references. void swap(slist_impl& other) { - if(cache_last){ + BOOST_IF_CONSTEXPR(cache_last){ priv_swap_cache_last(this, &other); } else{ @@ -735,7 +729,7 @@ class slist_impl //! Complexity: Linear to the number of elements plus the number shifts. //! //! Note: Iterators Does not affect the validity of iterators and references. - void shift_backwards(size_type n = 1) + void shift_backwards(size_type n = 1) BOOST_NOEXCEPT { this->priv_shift_backwards(n, detail::bool_()); } //! Effects: Moves forward all the elements, so that the second @@ -747,7 +741,7 @@ class slist_impl //! Complexity: Linear to the number of elements plus the number shifts. //! //! Note: Does not affect the validity of iterators and references. - void shift_forward(size_type n = 1) + void shift_forward(size_type n = 1) BOOST_NOEXCEPT { this->priv_shift_forward(n, detail::bool_()); } //! Requires: Disposer::operator()(pointer) shouldn't throw. @@ -819,7 +813,7 @@ class slist_impl //! Complexity: Constant. //! //! Note: Does not affect the validity of iterators and references. - iterator insert_after(const_iterator prev_p, reference value) + iterator insert_after(const_iterator prev_p, reference value) BOOST_NOEXCEPT { node_ptr n = priv_value_traits().to_node_ptr(value); BOOST_INTRUSIVE_SAFE_HOOK_DEFAULT_ASSERT(!safemode_or_autounlink || node_algorithms::inited(n)); @@ -845,7 +839,7 @@ class slist_impl //! //! Note: Does not affect the validity of iterators and references. template - void insert_after(const_iterator prev_p, Iterator f, Iterator l) + void insert_after(const_iterator prev_p, Iterator f, Iterator l) BOOST_NOEXCEPT { //Insert first nodes avoiding cache and size checks size_type count = 0; @@ -860,7 +854,7 @@ class slist_impl if(cache_last && (this->get_last_node() == prev_p.pointed_node())){ this->set_last_node(prev_n); } - if(constant_time_size){ + BOOST_IF_CONSTEXPR(constant_time_size){ this->priv_size_traits().increase(count); } } @@ -877,7 +871,7 @@ class slist_impl //! Constant-time if cache_last<> is true and p == end(). //! //! Note: Does not affect the validity of iterators and references. - iterator insert(const_iterator p, reference value) + iterator insert(const_iterator p, reference value) BOOST_NOEXCEPT { return this->insert_after(this->previous(p), value); } //! Requires: Dereferencing iterator must yield @@ -895,7 +889,7 @@ class slist_impl //! //! Note: Does not affect the validity of iterators and references. template - void insert(const_iterator p, Iterator b, Iterator e) + void insert(const_iterator p, Iterator b, Iterator e) BOOST_NOEXCEPT { return this->insert_after(this->previous(p), b, e); } //! Effects: Erases the element after the element pointed by prev of @@ -910,7 +904,7 @@ class slist_impl //! //! Note: Invalidates the iterators (but not the references) to the //! erased element. - iterator erase_after(const_iterator prev) + iterator erase_after(const_iterator prev) BOOST_NOEXCEPT { return this->erase_after_and_dispose(prev, detail::null_disposer()); } //! Effects: Erases the range (before_f, l) from @@ -926,15 +920,15 @@ class slist_impl //! //! Note: Invalidates the iterators (but not the references) to the //! erased element. - iterator erase_after(const_iterator before_f, const_iterator l) + iterator erase_after(const_iterator before_f, const_iterator l) BOOST_NOEXCEPT { - if(safemode_or_autounlink || constant_time_size){ + BOOST_IF_CONSTEXPR(safemode_or_autounlink || constant_time_size){ return this->erase_after_and_dispose(before_f, l, detail::null_disposer()); } else{ const node_ptr bfp = before_f.pointed_node(); const node_ptr lp = l.pointed_node(); - if(cache_last){ + BOOST_IF_CONSTEXPR(cache_last){ if(lp == this->get_end_node()){ this->set_last_node(bfp); } @@ -958,22 +952,23 @@ class slist_impl //! //! Note: Invalidates the iterators (but not the references) to the //! erased element. - iterator erase_after(const_iterator before_f, const_iterator l, size_type n) + iterator erase_after(const_iterator before_f, const_iterator l, size_type n) BOOST_NOEXCEPT { BOOST_INTRUSIVE_INVARIANT_ASSERT(node_algorithms::distance((++const_iterator(before_f)).pointed_node(), l.pointed_node()) == n); - if(safemode_or_autounlink){ + (void)n; + BOOST_IF_CONSTEXPR(safemode_or_autounlink){ return this->erase_after(before_f, l); } else{ const node_ptr bfp = before_f.pointed_node(); const node_ptr lp = l.pointed_node(); - if(cache_last){ + BOOST_IF_CONSTEXPR(cache_last){ if((lp == this->get_end_node())){ this->set_last_node(bfp); } } node_algorithms::unlink_after(bfp, lp); - if(constant_time_size){ + BOOST_IF_CONSTEXPR(constant_time_size){ this->priv_size_traits().decrease(n); } return l.unconst(); @@ -992,7 +987,7 @@ class slist_impl //! //! Note: Invalidates the iterators (but not the references) to the //! erased element. - iterator erase(const_iterator i) + iterator erase(const_iterator i) BOOST_NOEXCEPT { return this->erase_after(this->previous(i)); } //! Requires: f and l must be valid iterator to elements in *this. @@ -1009,7 +1004,7 @@ class slist_impl //! //! Note: Invalidates the iterators (but not the references) to the //! erased elements. - iterator erase(const_iterator f, const_iterator l) + iterator erase(const_iterator f, const_iterator l) BOOST_NOEXCEPT { return this->erase_after(this->previous(f), l); } //! Effects: Erases the range [f, l) from @@ -1026,7 +1021,7 @@ class slist_impl //! //! Note: Invalidates the iterators (but not the references) to the //! erased element. - iterator erase(const_iterator f, const_iterator l, size_type n) + iterator erase(const_iterator f, const_iterator l, size_type n) BOOST_NOEXCEPT { return this->erase_after(this->previous(f), l, n); } //! Requires: Disposer::operator()(pointer) shouldn't throw. @@ -1044,7 +1039,7 @@ class slist_impl //! //! Note: Invalidates the iterators to the erased element. template - iterator erase_after_and_dispose(const_iterator prev, Disposer disposer) + iterator erase_after_and_dispose(const_iterator prev, Disposer disposer) BOOST_NOEXCEPT { const_iterator it(prev); ++it; @@ -1055,7 +1050,7 @@ class slist_impl if(cache_last && (to_erase == this->get_last_node())){ this->set_last_node(prev_n); } - if(safemode_or_autounlink) + BOOST_IF_CONSTEXPR(safemode_or_autounlink) node_algorithms::init(to_erase); disposer(priv_value_traits().to_value_ptr(to_erase)); this->priv_size_traits().decrement(); @@ -1064,7 +1059,7 @@ class slist_impl /// @cond - static iterator s_insert_after(const_iterator const prev_p, reference value) + static iterator s_insert_after(const_iterator const prev_p, reference value) BOOST_NOEXCEPT { BOOST_STATIC_ASSERT(((!cache_last)&&(!constant_time_size)&&(!stateful_value_traits))); node_ptr const n = value_traits::to_node_ptr(value); @@ -1074,7 +1069,7 @@ class slist_impl } template - static iterator s_erase_after_and_dispose(const_iterator prev, Disposer disposer) + static iterator s_erase_after_and_dispose(const_iterator prev, Disposer disposer) BOOST_NOEXCEPT { BOOST_STATIC_ASSERT(((!cache_last)&&(!constant_time_size)&&(!stateful_value_traits))); const_iterator it(prev); @@ -1083,14 +1078,14 @@ class slist_impl ++it; node_ptr prev_n(prev.pointed_node()); node_algorithms::unlink_after(prev_n); - if(safemode_or_autounlink) + BOOST_IF_CONSTEXPR(safemode_or_autounlink) node_algorithms::init(to_erase); disposer(value_traits::to_value_ptr(to_erase)); return it.unconst(); } template - static iterator s_erase_after_and_dispose(const_iterator before_f, const_iterator l, Disposer disposer) + static iterator s_erase_after_and_dispose(const_iterator before_f, const_iterator l, Disposer disposer) BOOST_NOEXCEPT { BOOST_STATIC_ASSERT(((!cache_last)&&(!constant_time_size)&&(!stateful_value_traits))); node_ptr bfp(before_f.pointed_node()), lp(l.pointed_node()); @@ -1099,14 +1094,14 @@ class slist_impl while(fp != lp){ node_ptr to_erase(fp); fp = node_traits::get_next(fp); - if(safemode_or_autounlink) + BOOST_IF_CONSTEXPR(safemode_or_autounlink) node_algorithms::init(to_erase); disposer(value_traits::to_value_ptr(to_erase)); } return l.unconst(); } - static iterator s_erase_after(const_iterator prev) + static iterator s_erase_after(const_iterator prev) BOOST_NOEXCEPT { return s_erase_after_and_dispose(prev, detail::null_disposer()); } /// @endcond @@ -1126,7 +1121,7 @@ class slist_impl //! //! Note: Invalidates the iterators to the erased element. template - iterator erase_after_and_dispose(const_iterator before_f, const_iterator l, Disposer disposer) + iterator erase_after_and_dispose(const_iterator before_f, const_iterator l, Disposer disposer) BOOST_NOEXCEPT { node_ptr bfp(before_f.pointed_node()), lp(l.pointed_node()); node_ptr fp(node_traits::get_next(bfp)); @@ -1134,7 +1129,7 @@ class slist_impl while(fp != lp){ node_ptr to_erase(fp); fp = node_traits::get_next(fp); - if(safemode_or_autounlink) + BOOST_IF_CONSTEXPR(safemode_or_autounlink) node_algorithms::init(to_erase); disposer(priv_value_traits().to_value_ptr(to_erase)); this->priv_size_traits().decrement(); @@ -1161,12 +1156,12 @@ class slist_impl //! Note: Invalidates the iterators (but not the references) to the //! erased element. template - iterator erase_and_dispose(const_iterator i, Disposer disposer) + iterator erase_and_dispose(const_iterator i, Disposer disposer) BOOST_NOEXCEPT { return this->erase_after_and_dispose(this->previous(i), disposer); } #if !defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED) template - iterator erase_and_dispose(iterator i, Disposer disposer) + iterator erase_and_dispose(iterator i, Disposer disposer) BOOST_NOEXCEPT { return this->erase_and_dispose(const_iterator(i), disposer); } #endif @@ -1188,7 +1183,7 @@ class slist_impl //! Note: Invalidates the iterators (but not the references) to the //! erased elements. template - iterator erase_and_dispose(const_iterator f, const_iterator l, Disposer disposer) + iterator erase_and_dispose(const_iterator f, const_iterator l, Disposer disposer) BOOST_NOEXCEPT { return this->erase_after_and_dispose(this->previous(f), l, disposer); } //! Requires: Dereferencing iterator must yield @@ -1257,7 +1252,7 @@ class slist_impl //! assigned to the last spliced element or prev if x is empty. //! This iterator can be used as new "prev" iterator for a new splice_after call. //! that will splice new values after the previously spliced values. - void splice_after(const_iterator prev, slist_impl &x, const_iterator *l = 0) + void splice_after(const_iterator prev, slist_impl &x, const_iterator *l = 0) BOOST_NOEXCEPT { if(x.empty()){ if(l) *l = prev; @@ -1270,7 +1265,7 @@ class slist_impl const_iterator last_x(x.previous(x.end())); //constant time if cache_last is active node_ptr prev_n(prev.pointed_node()); node_ptr last_x_n(last_x.pointed_node()); - if(cache_last){ + BOOST_IF_CONSTEXPR(cache_last){ x.set_last_node(x.get_root_node()); if(node_traits::get_next(prev_n) == this->get_end_node()){ this->set_last_node(last_x_n); @@ -1296,7 +1291,7 @@ class slist_impl //! //! Note: Iterators of values obtained from list x now point to elements of this //! list. Iterators of this list and all the references are not invalidated. - void splice_after(const_iterator prev_pos, slist_impl &x, const_iterator prev_ele) + void splice_after(const_iterator prev_pos, slist_impl &x, const_iterator prev_ele) BOOST_NOEXCEPT { const_iterator elem = prev_ele; this->splice_after(prev_pos, x, prev_ele, ++elem, 1); @@ -1317,9 +1312,9 @@ class slist_impl //! //! Note: Iterators of values obtained from list x now point to elements of this //! list. Iterators of this list and all the references are not invalidated. - void splice_after(const_iterator prev_pos, slist_impl &x, const_iterator before_f, const_iterator before_l) + void splice_after(const_iterator prev_pos, slist_impl &x, const_iterator before_f, const_iterator before_l) BOOST_NOEXCEPT { - if(constant_time_size) + BOOST_IF_CONSTEXPR(constant_time_size) this->splice_after(prev_pos, x, before_f, before_l, node_algorithms::distance(before_f.pointed_node(), before_l.pointed_node())); else this->priv_splice_after @@ -1340,12 +1335,13 @@ class slist_impl //! //! Note: Iterators of values obtained from list x now point to elements of this //! list. Iterators of this list and all the references are not invalidated. - void splice_after(const_iterator prev_pos, slist_impl &x, const_iterator before_f, const_iterator before_l, size_type n) + void splice_after(const_iterator prev_pos, slist_impl &x, const_iterator before_f, const_iterator before_l, size_type n) BOOST_NOEXCEPT { BOOST_INTRUSIVE_INVARIANT_ASSERT(node_algorithms::distance(before_f.pointed_node(), before_l.pointed_node()) == n); + (void)n; this->priv_splice_after (prev_pos.pointed_node(), x, before_f.pointed_node(), before_l.pointed_node()); - if(constant_time_size){ + BOOST_IF_CONSTEXPR(constant_time_size){ this->priv_size_traits().increase(n); x.priv_size_traits().decrease(n); } @@ -1372,7 +1368,7 @@ class slist_impl //! assigned to the last spliced element or prev if x is empty. //! This iterator can be used as new "prev" iterator for a new splice_after call. //! that will splice new values after the previously spliced values. - void splice(const_iterator it, slist_impl &x, const_iterator *l = 0) + void splice(const_iterator it, slist_impl &x, const_iterator *l = 0) BOOST_NOEXCEPT { this->splice_after(this->previous(it), x, l); } //! Requires: it p must be a valid iterator of *this. @@ -1389,7 +1385,7 @@ class slist_impl //! //! Note: Iterators of values obtained from list x now point to elements of this //! list. Iterators of this list and all the references are not invalidated. - void splice(const_iterator pos, slist_impl &x, const_iterator elem) + void splice(const_iterator pos, slist_impl &x, const_iterator elem) BOOST_NOEXCEPT { return this->splice_after(this->previous(pos), x, x.previous(elem)); } //! Requires: pos must be a dereferenceable iterator in *this @@ -1409,7 +1405,7 @@ class slist_impl //! //! Note: Iterators of values obtained from list x now point to elements of this //! list. Iterators of this list and all the references are not invalidated. - void splice(const_iterator pos, slist_impl &x, const_iterator f, const_iterator l) + void splice(const_iterator pos, slist_impl &x, const_iterator f, const_iterator l) BOOST_NOEXCEPT { return this->splice_after(this->previous(pos), x, x.previous(f), x.previous(l)); } //! Requires: pos must be a dereferenceable iterator in *this @@ -1428,10 +1424,10 @@ class slist_impl //! //! Note: Iterators of values obtained from list x now point to elements of this //! list. Iterators of this list and all the references are not invalidated. - void splice(const_iterator pos, slist_impl &x, const_iterator f, const_iterator l, size_type n) + void splice(const_iterator pos, slist_impl &x, const_iterator f, const_iterator l, size_type n) BOOST_NOEXCEPT { return this->splice_after(this->previous(pos), x, x.previous(f), x.previous(l), n); } - //! Effects: This function sorts the list *this according to std::less. + //! Effects: This function sorts the list *this according to operator<. //! The sort is stable, that is, the relative order of equivalent elements is preserved. //! //! Throws: If value_traits::node_traits::node @@ -1463,7 +1459,7 @@ class slist_impl BOOST_INTRUSIVE_INVARIANT_ASSERT(counter[i].empty()); const_iterator last_element(carry.previous(last_inserted, carry.end())); - if(constant_time_size){ + BOOST_IF_CONSTEXPR(constant_time_size){ counter[i].splice_after( counter[i].cbefore_begin(), carry , carry.cbefore_begin(), last_element , carry.size()); @@ -1480,7 +1476,7 @@ class slist_impl counter[i].merge(counter[i-1], p, &last_inserted); --fill; const_iterator last_element(counter[fill].previous(last_inserted, counter[fill].end())); - if(constant_time_size){ + BOOST_IF_CONSTEXPR(constant_time_size){ this->splice_after( cbefore_begin(), counter[fill], counter[fill].cbefore_begin() , last_element, counter[fill].size()); } @@ -1501,14 +1497,14 @@ class slist_impl //! //! Throws: If value_traits::node_traits::node //! constructor throws (this does not happen with predefined Boost.Intrusive hooks) - //! or std::less throws. Basic guarantee. + //! or operator< throws. Basic guarantee. //! //! Complexity: This function is linear time: it performs at most //! size() + x.size() - 1 comparisons. //! //! Note: Iterators and references are not invalidated. void sort() - { this->sort(std::less()); } + { this->sort(value_less()); } //! Requires: p must be a comparison function that induces a strict weak //! ordering and both *this and x must be sorted according to that ordering @@ -1557,18 +1553,18 @@ class slist_impl } //! Effects: This function removes all of x's elements and inserts them - //! in order into *this according to std::less. The merge is stable; + //! in order into *this according to operator<. The merge is stable; //! that is, if an element from *this is equivalent to one from x, then the element //! from *this will precede the one from x. //! - //! Throws: if std::less throws. Basic guarantee. + //! Throws: if operator< throws. Basic guarantee. //! //! Complexity: This function is linear time: it performs at most //! size() + x.size() - 1 comparisons. //! //! Note: Iterators and references are not invalidated void merge(slist_impl& x) - { this->merge(x, std::less()); } + { this->merge(x, value_less()); } //! Effects: Reverses the order of elements in the list. //! @@ -1577,7 +1573,7 @@ class slist_impl //! Complexity: This function is linear to the contained elements. //! //! Note: Iterators and references are not invalidated - void reverse() + void reverse() BOOST_NOEXCEPT { if(cache_last && !this->empty()){ this->set_last_node(node_traits::get_next(this->get_root_node())); @@ -1588,14 +1584,14 @@ class slist_impl //! Effects: Removes all the elements that compare equal to value. //! No destructors are called. //! - //! Throws: If std::equal_to throws. Basic guarantee. + //! Throws: If operator== throws. Basic guarantee. //! //! Complexity: Linear time. It performs exactly size() comparisons for equality. //! //! Note: The relative order of elements that are not removed is unchanged, //! and iterators to elements that are not removed remain valid. This function is //! linear time: it performs exactly size() comparisons for equality. - void remove(const_reference value) + void remove(const_reference value) BOOST_NOEXCEPT { this->remove_if(detail::equal_to_value(value)); } //! Requires: Disposer::operator()(pointer) shouldn't throw. @@ -1603,14 +1599,14 @@ class slist_impl //! Effects: Removes all the elements that compare equal to value. //! Disposer::operator()(pointer) is called for every removed element. //! - //! Throws: If std::equal_to throws. Basic guarantee. + //! Throws: If operator== throws. Basic guarantee. //! //! Complexity: Linear time. It performs exactly size() comparisons for equality. //! //! Note: The relative order of elements that are not removed is unchanged, //! and iterators to elements that are not removed remain valid. template - void remove_and_dispose(const_reference value, Disposer disposer) + void remove_and_dispose(const_reference value, Disposer disposer) BOOST_NOEXCEPT { this->remove_and_dispose_if(detail::equal_to_value(value), disposer); } //! Effects: Removes all the elements for which a specified @@ -1630,7 +1626,7 @@ class slist_impl node_algorithms::stable_partition (bbeg, this->get_end_node(), detail::key_nodeptr_comp(pred, &this->priv_value_traits()), info); //After cache last is set, slist invariants are preserved... - if(cache_last){ + BOOST_IF_CONSTEXPR(cache_last){ this->set_last_node(info.new_last_node); } //...so erase can be safely called @@ -1659,7 +1655,7 @@ class slist_impl node_algorithms::stable_partition (bbeg, this->get_end_node(), detail::key_nodeptr_comp(pred, &this->priv_value_traits()), info); //After cache last is set, slist invariants are preserved... - if(cache_last){ + BOOST_IF_CONSTEXPR(cache_last){ this->set_last_node(info.new_last_node); } //...so erase can be safely called @@ -1671,14 +1667,14 @@ class slist_impl //! Effects: Removes adjacent duplicate elements or adjacent //! elements that are equal from the list. No destructors are called. //! - //! Throws: If std::equal_to throws. Basic guarantee. + //! Throws: If operator== throws. Basic guarantee. //! //! Complexity: Linear time (size()-1) comparisons calls to pred()). //! //! Note: The relative order of elements that are not removed is unchanged, //! and iterators to elements that are not removed remain valid. void unique() - { this->unique_and_dispose(std::equal_to(), detail::null_disposer()); } + { this->unique_and_dispose(value_equal(), detail::null_disposer()); } //! Effects: Removes adjacent duplicate elements or adjacent //! elements that satisfy some binary predicate from the list. @@ -1700,7 +1696,7 @@ class slist_impl //! elements that satisfy some binary predicate from the list. //! Disposer::operator()(pointer) is called for every removed element. //! - //! Throws: If std::equal_to throws. Basic guarantee. + //! Throws: If operator== throws. Basic guarantee. //! //! Complexity: Linear time (size()-1) comparisons equality comparisons. //! @@ -1708,7 +1704,7 @@ class slist_impl //! and iterators to elements that are not removed remain valid. template void unique_and_dispose(Disposer disposer) - { this->unique(std::equal_to(), disposer); } + { this->unique(value_equal(), disposer); } //! Requires: Disposer::operator()(pointer) shouldn't throw. //! @@ -1739,7 +1735,7 @@ class slist_impl ++cur; } } - if(cache_last){ + BOOST_IF_CONSTEXPR(cache_last){ this->set_last_node(bcur.pointed_node()); } } @@ -1756,7 +1752,7 @@ class slist_impl //! Note: Iterators and references are not invalidated. //! This static function is available only if the value traits //! is stateless. - static iterator s_iterator_to(reference value) + static iterator s_iterator_to(reference value) BOOST_NOEXCEPT { BOOST_STATIC_ASSERT((!stateful_value_traits)); return iterator (value_traits::to_node_ptr(value), const_value_traits_ptr()); @@ -1773,7 +1769,7 @@ class slist_impl //! Note: Iterators and references are not invalidated. //! This static function is available only if the value traits //! is stateless. - static const_iterator s_iterator_to(const_reference value) + static const_iterator s_iterator_to(const_reference value) BOOST_NOEXCEPT { BOOST_STATIC_ASSERT((!stateful_value_traits)); reference r =*detail::uncast(pointer_traits::pointer_to(value)); @@ -1789,7 +1785,7 @@ class slist_impl //! Complexity: Constant time. //! //! Note: Iterators and references are not invalidated. - iterator iterator_to(reference value) + iterator iterator_to(reference value) BOOST_NOEXCEPT { BOOST_INTRUSIVE_INVARIANT_ASSERT(linear || !node_algorithms::inited(this->priv_value_traits().to_node_ptr(value))); return iterator (this->priv_value_traits().to_node_ptr(value), this->priv_value_traits_ptr()); @@ -1804,7 +1800,7 @@ class slist_impl //! Complexity: Constant time. //! //! Note: Iterators and references are not invalidated. - const_iterator iterator_to(const_reference value) const + const_iterator iterator_to(const_reference value) const BOOST_NOEXCEPT { reference r =*detail::uncast(pointer_traits::pointer_to(value)); BOOST_INTRUSIVE_INVARIANT_ASSERT (linear || !node_algorithms::inited(this->priv_value_traits().to_node_ptr(r))); @@ -1819,7 +1815,7 @@ class slist_impl //! //! Complexity: Linear to the number of elements before i. //! Constant if cache_last<> is true and i == end(). - iterator previous(iterator i) + iterator previous(iterator i) BOOST_NOEXCEPT { return this->previous(this->cbefore_begin(), i); } //! Returns: The const_iterator to the element before i in the list. @@ -1830,7 +1826,7 @@ class slist_impl //! //! Complexity: Linear to the number of elements before i. //! Constant if cache_last<> is true and i == end(). - const_iterator previous(const_iterator i) const + const_iterator previous(const_iterator i) const BOOST_NOEXCEPT { return this->previous(this->cbefore_begin(), i); } //! Returns: The iterator to the element before i in the list, @@ -1842,7 +1838,7 @@ class slist_impl //! //! Complexity: Linear to the number of elements before i. //! Constant if cache_last<> is true and i == end(). - iterator previous(const_iterator prev_from, iterator i) + iterator previous(const_iterator prev_from, iterator i) BOOST_NOEXCEPT { return this->previous(prev_from, const_iterator(i)).unconst(); } //! Returns: The const_iterator to the element before i in the list, @@ -1854,7 +1850,7 @@ class slist_impl //! //! Complexity: Linear to the number of elements before i. //! Constant if cache_last<> is true and i == end(). - const_iterator previous(const_iterator prev_from, const_iterator i) const + const_iterator previous(const_iterator prev_from, const_iterator i) const BOOST_NOEXCEPT { if(cache_last && (i.pointed_node() == this->get_end_node())){ return const_iterator(detail::uncast(this->get_last_node()), this->priv_value_traits_ptr()); @@ -1882,9 +1878,9 @@ class slist_impl //! point to elements of this list. Iterators of this list and all the references are not invalidated. //! //! Warning: Experimental function, don't use it! - void incorporate_after(const_iterator prev_pos, const node_ptr & f, const node_ptr & before_l) + void incorporate_after(const_iterator prev_pos, node_ptr f, node_ptr before_l) BOOST_NOEXCEPT { - if(constant_time_size) + BOOST_IF_CONSTEXPR(constant_time_size) this->incorporate_after(prev_pos, f, before_l, node_algorithms::distance(f.pointed_node(), before_l.pointed_node())+1); else this->priv_incorporate_after(prev_pos.pointed_node(), f, before_l); @@ -1906,7 +1902,7 @@ class slist_impl //! point to elements of this list. Iterators of this list and all the references are not invalidated. //! //! Warning: Experimental function, don't use it! - void incorporate_after(const_iterator prev_pos, const node_ptr & f, const node_ptr & before_l, size_type n) + void incorporate_after(const_iterator prev_pos, node_ptr f, node_ptr before_l, size_type n) BOOST_NOEXCEPT { if(n){ BOOST_INTRUSIVE_INVARIANT_ASSERT(n > 0); @@ -1916,7 +1912,7 @@ class slist_impl , iterator(before_l, this->priv_value_traits_ptr()))) +1 == n); this->priv_incorporate_after(prev_pos.pointed_node(), f, before_l); - if(constant_time_size){ + BOOST_IF_CONSTEXPR(constant_time_size){ this->priv_size_traits().increase(n); } } @@ -1940,12 +1936,12 @@ class slist_impl BOOST_INTRUSIVE_INVARIANT_ASSERT(!constant_time_size || this->priv_size_traits().get_size() == 0); return; } - size_t node_count = 0; + size_t node_count = 0; (void)node_count; const_node_ptr p = header_ptr; while (true) { const_node_ptr next_p = node_traits::get_next(p); - if (!linear) + BOOST_IF_CONSTEXPR(!linear) { BOOST_INTRUSIVE_INVARIANT_ASSERT(next_p); } @@ -2007,7 +2003,7 @@ class slist_impl void priv_incorporate_after(node_ptr prev_pos_n, node_ptr first_n, node_ptr before_l_n) { - if(cache_last){ + BOOST_IF_CONSTEXPR(cache_last){ if(prev_pos_n == this->get_last_node()){ this->set_last_node(before_l_n); } @@ -2035,12 +2031,12 @@ class slist_impl void priv_shift_backwards(size_type n, detail::bool_) { - std::pair ret( + typename node_algorithms::node_pair ret( node_algorithms::move_first_n_forward (node_traits::get_next(this->get_root_node()), (std::size_t)n)); if(ret.first){ node_traits::set_next(this->get_root_node(), ret.first); - if(cache_last){ + BOOST_IF_CONSTEXPR(cache_last){ this->set_last_node(ret.second); } } @@ -2056,12 +2052,12 @@ class slist_impl void priv_shift_forward(size_type n, detail::bool_) { - std::pair ret( + typename node_algorithms::node_pair ret( node_algorithms::move_first_n_backwards (node_traits::get_next(this->get_root_node()), (std::size_t)n)); if(ret.first){ node_traits::set_next(this->get_root_node(), ret.first); - if(cache_last){ + BOOST_IF_CONSTEXPR(cache_last){ this->set_last_node(ret.second); } } @@ -2209,7 +2205,7 @@ class slist struct incorporate_t{}; - BOOST_INTRUSIVE_FORCEINLINE slist( const node_ptr & f, const node_ptr & before_l + BOOST_INTRUSIVE_FORCEINLINE slist( node_ptr f, node_ptr before_l , size_type n, const value_traits &v_traits = value_traits()) : Base(f, before_l, n, v_traits) {} @@ -2234,10 +2230,10 @@ class slist BOOST_INTRUSIVE_FORCEINLINE void clone_from(BOOST_RV_REF(slist) src, Cloner cloner, Disposer disposer) { Base::clone_from(BOOST_MOVE_BASE(Base, src), cloner, disposer); } - BOOST_INTRUSIVE_FORCEINLINE static slist &container_from_end_iterator(iterator end_iterator) + BOOST_INTRUSIVE_FORCEINLINE static slist &container_from_end_iterator(iterator end_iterator) BOOST_NOEXCEPT { return static_cast(Base::container_from_end_iterator(end_iterator)); } - BOOST_INTRUSIVE_FORCEINLINE static const slist &container_from_end_iterator(const_iterator end_iterator) + BOOST_INTRUSIVE_FORCEINLINE static const slist &container_from_end_iterator(const_iterator end_iterator) BOOST_NOEXCEPT { return static_cast(Base::container_from_end_iterator(end_iterator)); } }; diff --git a/include/boost/intrusive/slist_hook.hpp b/include/boost/intrusive/slist_hook.hpp index 0f37772c6..380818cf2 100644 --- a/include/boost/intrusive/slist_hook.hpp +++ b/include/boost/intrusive/slist_hook.hpp @@ -97,7 +97,7 @@ class slist_base_hook //! initializes the node to an unlinked state. //! //! Throws: Nothing. - slist_base_hook(); + slist_base_hook() BOOST_NOEXCEPT; //! Effects: If link_mode is \c auto_unlink or \c safe_link //! initializes the node to an unlinked state. The argument is ignored. @@ -108,7 +108,7 @@ class slist_base_hook //! makes classes using the hook STL-compliant without forcing the //! user to do some additional work. \c swap can be used to emulate //! move-semantics. - slist_base_hook(const slist_base_hook& ); + slist_base_hook(const slist_base_hook& ) BOOST_NOEXCEPT; //! Effects: Empty function. The argument is ignored. //! @@ -118,7 +118,7 @@ class slist_base_hook //! makes classes using the hook STL-compliant without forcing the //! user to do some additional work. \c swap can be used to emulate //! move-semantics. - slist_base_hook& operator=(const slist_base_hook& ); + slist_base_hook& operator=(const slist_base_hook& ) BOOST_NOEXCEPT; //! Effects: If link_mode is \c normal_link, the destructor does //! nothing (ie. no code is generated). If link_mode is \c safe_link and the @@ -140,7 +140,7 @@ class slist_base_hook //! Complexity: Constant //! //! Throws: Nothing. - void swap_nodes(slist_base_hook &other); + void swap_nodes(slist_base_hook &other) BOOST_NOEXCEPT; //! Precondition: link_mode must be \c safe_link or \c auto_unlink. //! @@ -148,14 +148,16 @@ class slist_base_hook //! otherwise. This function can be used to test whether \c slist::iterator_to //! will return a valid iterator. //! + //! Throws: Nothing. + //! //! Complexity: Constant - bool is_linked() const; + bool is_linked() const BOOST_NOEXCEPT; //! Effects: Removes the node if it's inserted in a container. //! This function is only allowed if link_mode is \c auto_unlink. //! //! Throws: Nothing. - void unlink(); + void unlink() BOOST_NOEXCEPT; #endif }; diff --git a/include/boost/intrusive/splay_set.hpp b/include/boost/intrusive/splay_set.hpp index 9f6e92e93..f700934fa 100644 --- a/include/boost/intrusive/splay_set.hpp +++ b/include/boost/intrusive/splay_set.hpp @@ -118,61 +118,61 @@ class splay_set_impl ~splay_set_impl(); //! @copydoc ::boost::intrusive::splaytree::begin() - iterator begin(); + iterator begin() BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::splaytree::begin()const - const_iterator begin() const; + const_iterator begin() const BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::splaytree::cbegin()const - const_iterator cbegin() const; + const_iterator cbegin() const BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::splaytree::end() - iterator end(); + iterator end() BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::splaytree::end()const - const_iterator end() const; + const_iterator end() const BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::splaytree::cend()const - const_iterator cend() const; + const_iterator cend() const BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::splaytree::rbegin() - reverse_iterator rbegin(); + reverse_iterator rbegin() BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::splaytree::rbegin()const - const_reverse_iterator rbegin() const; + const_reverse_iterator rbegin() const BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::splaytree::crbegin()const - const_reverse_iterator crbegin() const; + const_reverse_iterator crbegin() const BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::splaytree::rend() - reverse_iterator rend(); + reverse_iterator rend() BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::splaytree::rend()const - const_reverse_iterator rend() const; + const_reverse_iterator rend() const BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::splaytree::crend()const - const_reverse_iterator crend() const; + const_reverse_iterator crend() const BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::splaytree::root() - iterator root(); + iterator root() BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::splaytree::root()const - const_iterator root() const; + const_iterator root() const BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::splaytree::croot()const - const_iterator croot() const; + const_iterator croot() const BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::splaytree::container_from_end_iterator(iterator) - static splay_set_impl &container_from_end_iterator(iterator end_iterator); + static splay_set_impl &container_from_end_iterator(iterator end_iterator) BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::splaytree::container_from_end_iterator(const_iterator) - static const splay_set_impl &container_from_end_iterator(const_iterator end_iterator); + static const splay_set_impl &container_from_end_iterator(const_iterator end_iterator) BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::splaytree::container_from_iterator(iterator) - static splay_set_impl &container_from_iterator(iterator it); + static splay_set_impl &container_from_iterator(iterator it) BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::splaytree::container_from_iterator(const_iterator) - static const splay_set_impl &container_from_iterator(const_iterator it); + static const splay_set_impl &container_from_iterator(const_iterator it) BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::splaytree::key_comp()const key_compare key_comp() const; @@ -181,10 +181,10 @@ class splay_set_impl value_compare value_comp() const; //! @copydoc ::boost::intrusive::splaytree::empty()const - bool empty() const; + bool empty() const BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::splaytree::size()const - size_type size() const; + size_type size() const BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::splaytree::swap void swap(splay_set_impl& other); @@ -242,24 +242,24 @@ class splay_set_impl { tree_type::insert_unique(b, e); } //! @copydoc ::boost::intrusive::splaytree::insert_unique_commit - iterator insert_commit(reference value, const insert_commit_data &commit_data) + iterator insert_commit(reference value, const insert_commit_data &commit_data) BOOST_NOEXCEPT { return tree_type::insert_unique_commit(value, commit_data); } #ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED //! @copydoc ::boost::intrusive::splaytree::insert_before - iterator insert_before(const_iterator pos, reference value); + iterator insert_before(const_iterator pos, reference value) BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::splaytree::push_back - void push_back(reference value); + void push_back(reference value) BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::splaytree::push_front - void push_front(reference value); + void push_front(reference value) BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::splaytree::erase(const_iterator) - iterator erase(const_iterator i); + iterator erase(const_iterator i) BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::splaytree::erase(const_iterator,const_iterator) - iterator erase(const_iterator b, const_iterator e); + iterator erase(const_iterator b, const_iterator e) BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::splaytree::erase(const key_type &) size_type erase(const key_type &key); @@ -270,11 +270,11 @@ class splay_set_impl //! @copydoc ::boost::intrusive::splaytree::erase_and_dispose(const_iterator,Disposer) template - iterator erase_and_dispose(const_iterator i, Disposer disposer); + iterator erase_and_dispose(const_iterator i, Disposer disposer) BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::splaytree::erase_and_dispose(const_iterator,const_iterator,Disposer) template - iterator erase_and_dispose(const_iterator b, const_iterator e, Disposer disposer); + iterator erase_and_dispose(const_iterator b, const_iterator e, Disposer disposer) BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::splaytree::erase_and_dispose(const key_type &, Disposer) template @@ -285,11 +285,11 @@ class splay_set_impl size_type erase_and_dispose(const KeyType& key, KeyTypeKeyCompare comp, Disposer disposer); //! @copydoc ::boost::intrusive::splaytree::clear - void clear(); + void clear() BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::splaytree::clear_and_dispose template - void clear_and_dispose(Disposer disposer); + void clear_and_dispose(Disposer disposer) BOOST_NOEXCEPT; #endif // #ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED @@ -396,31 +396,31 @@ class splay_set_impl (const KeyType& lower_key, const KeyType& upper_key, KeyTypeKeyCompare comp, bool left_closed, bool right_closed) const; //! @copydoc ::boost::intrusive::splaytree::s_iterator_to(reference) - static iterator s_iterator_to(reference value); + static iterator s_iterator_to(reference value) BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::splaytree::s_iterator_to(const_reference) - static const_iterator s_iterator_to(const_reference value); + static const_iterator s_iterator_to(const_reference value) BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::splaytree::iterator_to(reference) - iterator iterator_to(reference value); + iterator iterator_to(reference value) BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::splaytree::iterator_to(const_reference)const - const_iterator iterator_to(const_reference value) const; + const_iterator iterator_to(const_reference value) const BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::splaytree::init_node(reference) - static void init_node(reference value); + static void init_node(reference value) BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::splaytree::unlink_leftmost_without_rebalance - pointer unlink_leftmost_without_rebalance(); + pointer unlink_leftmost_without_rebalance() BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::splaytree::replace_node - void replace_node(iterator replace_this, reference with_this); + void replace_node(iterator replace_this, reference with_this) BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::splaytree::remove_node - void remove_node(reference value); + void remove_node(reference value) BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::splaytree::splay_up(iterator) - void splay_up(iterator i); + void splay_up(iterator i) BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::splaytree::splay_down(const KeyType&,KeyTypeKeyCompare) template @@ -430,10 +430,10 @@ class splay_set_impl iterator splay_down(const key_type &key); //! @copydoc ::boost::intrusive::splaytree::rebalance - void rebalance(); + void rebalance() BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::splaytree::rebalance_subtree - iterator rebalance_subtree(iterator root); + iterator rebalance_subtree(iterator root) BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::splaytree::merge_unique template @@ -576,16 +576,16 @@ class splay_set BOOST_INTRUSIVE_FORCEINLINE void clone_from(BOOST_RV_REF(splay_set) src, Cloner cloner, Disposer disposer) { Base::clone_from(BOOST_MOVE_BASE(Base, src), cloner, disposer); } - BOOST_INTRUSIVE_FORCEINLINE static splay_set &container_from_end_iterator(iterator end_iterator) + BOOST_INTRUSIVE_FORCEINLINE static splay_set &container_from_end_iterator(iterator end_iterator) BOOST_NOEXCEPT { return static_cast(Base::container_from_end_iterator(end_iterator)); } - BOOST_INTRUSIVE_FORCEINLINE static const splay_set &container_from_end_iterator(const_iterator end_iterator) + BOOST_INTRUSIVE_FORCEINLINE static const splay_set &container_from_end_iterator(const_iterator end_iterator) BOOST_NOEXCEPT { return static_cast(Base::container_from_end_iterator(end_iterator)); } - BOOST_INTRUSIVE_FORCEINLINE static splay_set &container_from_iterator(iterator it) + BOOST_INTRUSIVE_FORCEINLINE static splay_set &container_from_iterator(iterator it) BOOST_NOEXCEPT { return static_cast(Base::container_from_iterator(it)); } - BOOST_INTRUSIVE_FORCEINLINE static const splay_set &container_from_iterator(const_iterator it) + BOOST_INTRUSIVE_FORCEINLINE static const splay_set &container_from_iterator(const_iterator it) BOOST_NOEXCEPT { return static_cast(Base::container_from_iterator(it)); } }; @@ -678,61 +678,61 @@ class splay_multiset_impl ~splay_multiset_impl(); //! @copydoc ::boost::intrusive::splaytree::begin() - iterator begin(); + iterator begin() BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::splaytree::begin()const - const_iterator begin() const; + const_iterator begin() const BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::splaytree::cbegin()const - const_iterator cbegin() const; + const_iterator cbegin() const BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::splaytree::end() - iterator end(); + iterator end() BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::splaytree::end()const - const_iterator end() const; + const_iterator end() const BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::splaytree::cend()const - const_iterator cend() const; + const_iterator cend() const BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::splaytree::rbegin() - reverse_iterator rbegin(); + reverse_iterator rbegin() BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::splaytree::rbegin()const - const_reverse_iterator rbegin() const; + const_reverse_iterator rbegin() const BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::splaytree::crbegin()const - const_reverse_iterator crbegin() const; + const_reverse_iterator crbegin() const BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::splaytree::rend() - reverse_iterator rend(); + reverse_iterator rend() BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::splaytree::rend()const - const_reverse_iterator rend() const; + const_reverse_iterator rend() const BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::splaytree::crend()const - const_reverse_iterator crend() const; + const_reverse_iterator crend() const BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::splaytree::root() - iterator root(); + iterator root() BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::splaytree::root()const - const_iterator root() const; + const_iterator root() const BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::splaytree::croot()const - const_iterator croot() const; + const_iterator croot() const BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::splaytree::container_from_end_iterator(iterator) - static splay_multiset_impl &container_from_end_iterator(iterator end_iterator); + static splay_multiset_impl &container_from_end_iterator(iterator end_iterator) BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::splaytree::container_from_end_iterator(const_iterator) - static const splay_multiset_impl &container_from_end_iterator(const_iterator end_iterator); + static const splay_multiset_impl &container_from_end_iterator(const_iterator end_iterator) BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::splaytree::container_from_iterator(iterator) - static splay_multiset_impl &container_from_iterator(iterator it); + static splay_multiset_impl &container_from_iterator(iterator it) BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::splaytree::container_from_iterator(const_iterator) - static const splay_multiset_impl &container_from_iterator(const_iterator it); + static const splay_multiset_impl &container_from_iterator(const_iterator it) BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::splaytree::key_comp()const key_compare key_comp() const; @@ -741,10 +741,10 @@ class splay_multiset_impl value_compare value_comp() const; //! @copydoc ::boost::intrusive::splaytree::empty()const - bool empty() const; + bool empty() const BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::splaytree::size()const - size_type size() const; + size_type size() const BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::splaytree::swap void swap(splay_multiset_impl& other); @@ -779,19 +779,19 @@ class splay_multiset_impl #ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED //! @copydoc ::boost::intrusive::splaytree::insert_before - iterator insert_before(const_iterator pos, reference value); + iterator insert_before(const_iterator pos, reference value) BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::splaytree::push_back - void push_back(reference value); + void push_back(reference value) BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::splaytree::push_front - void push_front(reference value); + void push_front(reference value) BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::splaytree::erase(const_iterator) - iterator erase(const_iterator i); + iterator erase(const_iterator i) BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::splaytree::erase(const_iterator,const_iterator) - iterator erase(const_iterator b, const_iterator e); + iterator erase(const_iterator b, const_iterator e) BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::splaytree::erase(const key_type&) size_type erase(const key_type &key); @@ -802,11 +802,11 @@ class splay_multiset_impl //! @copydoc ::boost::intrusive::splaytree::erase_and_dispose(const_iterator,Disposer) template - iterator erase_and_dispose(const_iterator i, Disposer disposer); + iterator erase_and_dispose(const_iterator i, Disposer disposer) BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::splaytree::erase_and_dispose(const_iterator,const_iterator,Disposer) template - iterator erase_and_dispose(const_iterator b, const_iterator e, Disposer disposer); + iterator erase_and_dispose(const_iterator b, const_iterator e, Disposer disposer) BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::splaytree::erase_and_dispose(const key_type&, Disposer) template @@ -817,11 +817,11 @@ class splay_multiset_impl size_type erase_and_dispose(const KeyType& key, KeyTypeKeyCompare comp, Disposer disposer); //! @copydoc ::boost::intrusive::splaytree::clear - void clear(); + void clear() BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::splaytree::clear_and_dispose template - void clear_and_dispose(Disposer disposer); + void clear_and_dispose(Disposer disposer) BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::splaytree::count(const key_type&) size_type count(const key_type&); @@ -907,31 +907,31 @@ class splay_multiset_impl (const KeyType& lower_key, const KeyType& upper_key, KeyTypeKeyCompare comp, bool left_closed, bool right_closed) const; //! @copydoc ::boost::intrusive::splaytree::s_iterator_to(reference) - static iterator s_iterator_to(reference value); + static iterator s_iterator_to(reference value) BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::splaytree::s_iterator_to(const_reference) - static const_iterator s_iterator_to(const_reference value); + static const_iterator s_iterator_to(const_reference value) BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::splaytree::iterator_to(reference) - iterator iterator_to(reference value); + iterator iterator_to(reference value) BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::splaytree::iterator_to(const_reference)const - const_iterator iterator_to(const_reference value) const; + const_iterator iterator_to(const_reference value) const BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::splaytree::init_node(reference) - static void init_node(reference value); + static void init_node(reference value) BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::splaytree::unlink_leftmost_without_rebalance - pointer unlink_leftmost_without_rebalance(); + pointer unlink_leftmost_without_rebalance() BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::splaytree::replace_node - void replace_node(iterator replace_this, reference with_this); + void replace_node(iterator replace_this, reference with_this) BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::splaytree::remove_node - void remove_node(reference value); + void remove_node(reference value) BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::splaytree::splay_up(iterator) - void splay_up(iterator i); + void splay_up(iterator i) BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::splaytree::splay_down(const KeyType&,KeyTypeKeyCompare) template @@ -941,10 +941,10 @@ class splay_multiset_impl iterator splay_down(const key_type &key); //! @copydoc ::boost::intrusive::splaytree::rebalance - void rebalance(); + void rebalance() BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::splaytree::rebalance_subtree - iterator rebalance_subtree(iterator root); + iterator rebalance_subtree(iterator root) BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::splaytree::merge_equal template @@ -1087,16 +1087,16 @@ class splay_multiset BOOST_INTRUSIVE_FORCEINLINE void clone_from(BOOST_RV_REF(splay_multiset) src, Cloner cloner, Disposer disposer) { Base::clone_from(BOOST_MOVE_BASE(Base, src), cloner, disposer); } - BOOST_INTRUSIVE_FORCEINLINE static splay_multiset &container_from_end_iterator(iterator end_iterator) + BOOST_INTRUSIVE_FORCEINLINE static splay_multiset &container_from_end_iterator(iterator end_iterator) BOOST_NOEXCEPT { return static_cast(Base::container_from_end_iterator(end_iterator)); } - BOOST_INTRUSIVE_FORCEINLINE static const splay_multiset &container_from_end_iterator(const_iterator end_iterator) + BOOST_INTRUSIVE_FORCEINLINE static const splay_multiset &container_from_end_iterator(const_iterator end_iterator) BOOST_NOEXCEPT { return static_cast(Base::container_from_end_iterator(end_iterator)); } - BOOST_INTRUSIVE_FORCEINLINE static splay_multiset &container_from_iterator(iterator it) + BOOST_INTRUSIVE_FORCEINLINE static splay_multiset &container_from_iterator(iterator it) BOOST_NOEXCEPT { return static_cast(Base::container_from_iterator(it)); } - BOOST_INTRUSIVE_FORCEINLINE static const splay_multiset &container_from_iterator(const_iterator it) + BOOST_INTRUSIVE_FORCEINLINE static const splay_multiset &container_from_iterator(const_iterator it) BOOST_NOEXCEPT { return static_cast(Base::container_from_iterator(it)); } }; diff --git a/include/boost/intrusive/splaytree.hpp b/include/boost/intrusive/splaytree.hpp index a93f1f7b1..44e5c7867 100644 --- a/include/boost/intrusive/splaytree.hpp +++ b/include/boost/intrusive/splaytree.hpp @@ -148,61 +148,61 @@ class splaytree_impl ~splaytree_impl(); //! @copydoc ::boost::intrusive::bstree::begin() - iterator begin(); + iterator begin() BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::bstree::begin()const - const_iterator begin() const; + const_iterator begin() const BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::bstree::cbegin()const - const_iterator cbegin() const; + const_iterator cbegin() const BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::bstree::end() - iterator end(); + iterator end() BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::bstree::end()const - const_iterator end() const; + const_iterator end() const BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::bstree::cend()const - const_iterator cend() const; + const_iterator cend() const BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::bstree::rbegin() - reverse_iterator rbegin(); + reverse_iterator rbegin() BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::bstree::rbegin()const - const_reverse_iterator rbegin() const; + const_reverse_iterator rbegin() const BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::bstree::crbegin()const - const_reverse_iterator crbegin() const; + const_reverse_iterator crbegin() const BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::bstree::rend() - reverse_iterator rend(); + reverse_iterator rend() BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::bstree::rend()const - const_reverse_iterator rend() const; + const_reverse_iterator rend() const BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::bstree::crend()const - const_reverse_iterator crend() const; + const_reverse_iterator crend() const BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::bstree::root() - iterator root(); + iterator root() BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::bstree::root()const - const_iterator root() const; + const_iterator root() const BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::bstree::croot()const - const_iterator croot() const; + const_iterator croot() const BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::bstree::container_from_end_iterator(iterator) - static splaytree_impl &container_from_end_iterator(iterator end_iterator); + static splaytree_impl &container_from_end_iterator(iterator end_iterator) BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::bstree::container_from_end_iterator(const_iterator) - static const splaytree_impl &container_from_end_iterator(const_iterator end_iterator); + static const splaytree_impl &container_from_end_iterator(const_iterator end_iterator) BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::bstree::container_from_iterator(iterator) - static splaytree_impl &container_from_iterator(iterator it); + static splaytree_impl &container_from_iterator(iterator it) BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::bstree::container_from_iterator(const_iterator) - static const splaytree_impl &container_from_iterator(const_iterator it); + static const splaytree_impl &container_from_iterator(const_iterator it) BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::bstree::key_comp()const key_compare key_comp() const; @@ -211,10 +211,10 @@ class splaytree_impl value_compare value_comp() const; //! @copydoc ::boost::intrusive::bstree::empty()const - bool empty() const; + bool empty() const BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::bstree::size()const - size_type size() const; + size_type size() const BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::bstree::swap void swap(splaytree_impl& other); @@ -273,26 +273,26 @@ class splaytree_impl ,KeyTypeKeyCompare comp, insert_commit_data &commit_data); //! @copydoc ::boost::intrusive::bstree::insert_unique_commit - iterator insert_unique_commit(reference value, const insert_commit_data &commit_data); + iterator insert_unique_commit(reference value, const insert_commit_data &commit_data) BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::bstree::insert_unique(Iterator,Iterator) template void insert_unique(Iterator b, Iterator e); //! @copydoc ::boost::intrusive::bstree::insert_before - iterator insert_before(const_iterator pos, reference value); + iterator insert_before(const_iterator pos, reference value) BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::bstree::push_back - void push_back(reference value); + void push_back(reference value) BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::bstree::push_front - void push_front(reference value); + void push_front(reference value) BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::bstree::erase(const_iterator) - iterator erase(const_iterator i); + iterator erase(const_iterator i) BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::bstree::erase(const_iterator,const_iterator) - iterator erase(const_iterator b, const_iterator e); + iterator erase(const_iterator b, const_iterator e) BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::bstree::erase(const key_type &) size_type erase(const key_type &key); @@ -303,11 +303,11 @@ class splaytree_impl //! @copydoc ::boost::intrusive::bstree::erase_and_dispose(const_iterator,Disposer) template - iterator erase_and_dispose(const_iterator i, Disposer disposer); + iterator erase_and_dispose(const_iterator i, Disposer disposer) BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::bstree::erase_and_dispose(const_iterator,const_iterator,Disposer) template - iterator erase_and_dispose(const_iterator b, const_iterator e, Disposer disposer); + iterator erase_and_dispose(const_iterator b, const_iterator e, Disposer disposer) BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::bstree::erase_and_dispose(const key_type &, Disposer) template @@ -318,11 +318,11 @@ class splaytree_impl size_type erase_and_dispose(const KeyType& key, KeyTypeKeyCompare comp, Disposer disposer); //! @copydoc ::boost::intrusive::bstree::clear - void clear(); + void clear() BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::bstree::clear_and_dispose template - void clear_and_dispose(Disposer disposer); + void clear_and_dispose(Disposer disposer) BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::bstree::count(const key_type &)const //! Additional note: non-const function, splaying is performed. @@ -440,28 +440,28 @@ class splaytree_impl (const KeyType& lower_key, const KeyType& upper_key, KeyTypeKeyCompare comp, bool left_closed, bool right_closed) const; //! @copydoc ::boost::intrusive::bstree::s_iterator_to(reference) - static iterator s_iterator_to(reference value); + static iterator s_iterator_to(reference value) BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::bstree::s_iterator_to(const_reference) - static const_iterator s_iterator_to(const_reference value); + static const_iterator s_iterator_to(const_reference value) BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::bstree::iterator_to(reference) - iterator iterator_to(reference value); + iterator iterator_to(reference value) BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::bstree::iterator_to(const_reference)const - const_iterator iterator_to(const_reference value) const; + const_iterator iterator_to(const_reference value) const BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::bstree::init_node(reference) - static void init_node(reference value); + static void init_node(reference value) BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::bstree::unlink_leftmost_without_rebalance - pointer unlink_leftmost_without_rebalance(); + pointer unlink_leftmost_without_rebalance() BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::bstree::replace_node - void replace_node(iterator replace_this, reference with_this); + void replace_node(iterator replace_this, reference with_this) BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::bstree::remove_node - void remove_node(reference value); + void remove_node(reference value) BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::bstree::merge_unique(bstree&) template @@ -481,7 +481,7 @@ class splaytree_impl //! Complexity: Amortized logarithmic. //! //! Throws: Nothing. - void splay_up(iterator i) + void splay_up(iterator i) BOOST_NOEXCEPT { return node_algorithms::splay_up(i.pointed_node(), tree_type::header_ptr()); } //! Effects: Rearranges the container so that if *this stores an element @@ -517,10 +517,10 @@ class splaytree_impl #ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED //! @copydoc ::boost::intrusive::bstree::rebalance - void rebalance(); + void rebalance() BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::bstree::rebalance_subtree - iterator rebalance_subtree(iterator root); + iterator rebalance_subtree(iterator root) BOOST_NOEXCEPT; friend bool operator< (const splaytree_impl &x, const splaytree_impl &y); @@ -643,16 +643,16 @@ class splaytree BOOST_INTRUSIVE_FORCEINLINE void clone_from(BOOST_RV_REF(splaytree) src, Cloner cloner, Disposer disposer) { Base::clone_from(BOOST_MOVE_BASE(Base, src), cloner, disposer); } - BOOST_INTRUSIVE_FORCEINLINE static splaytree &container_from_end_iterator(iterator end_iterator) + BOOST_INTRUSIVE_FORCEINLINE static splaytree &container_from_end_iterator(iterator end_iterator) BOOST_NOEXCEPT { return static_cast(Base::container_from_end_iterator(end_iterator)); } - BOOST_INTRUSIVE_FORCEINLINE static const splaytree &container_from_end_iterator(const_iterator end_iterator) + BOOST_INTRUSIVE_FORCEINLINE static const splaytree &container_from_end_iterator(const_iterator end_iterator) BOOST_NOEXCEPT { return static_cast(Base::container_from_end_iterator(end_iterator)); } - BOOST_INTRUSIVE_FORCEINLINE static splaytree &container_from_iterator(iterator it) + BOOST_INTRUSIVE_FORCEINLINE static splaytree &container_from_iterator(iterator it) BOOST_NOEXCEPT { return static_cast(Base::container_from_iterator(it)); } - BOOST_INTRUSIVE_FORCEINLINE static const splaytree &container_from_iterator(const_iterator it) + BOOST_INTRUSIVE_FORCEINLINE static const splaytree &container_from_iterator(const_iterator it) BOOST_NOEXCEPT { return static_cast(Base::container_from_iterator(it)); } }; diff --git a/include/boost/intrusive/splaytree_algorithms.hpp b/include/boost/intrusive/splaytree_algorithms.hpp index 6376d32af..bef440a8b 100644 --- a/include/boost/intrusive/splaytree_algorithms.hpp +++ b/include/boost/intrusive/splaytree_algorithms.hpp @@ -54,7 +54,7 @@ struct splaydown_assemble_and_fix_header { typedef typename NodeTraits::node_ptr node_ptr; - splaydown_assemble_and_fix_header(node_ptr t, node_ptr header, node_ptr leftmost, node_ptr rightmost) + splaydown_assemble_and_fix_header(node_ptr t, node_ptr header, node_ptr leftmost, node_ptr rightmost) BOOST_NOEXCEPT : t_(t) , null_node_(header) , l_(null_node_) @@ -79,7 +79,7 @@ struct splaydown_assemble_and_fix_header private: - void assemble() + void assemble() BOOST_NOEXCEPT { //procedure assemble; // left(r), right(l) := right(t), left(t); @@ -175,59 +175,59 @@ class splaytree_algorithms public: #ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED - //! @copydoc ::boost::intrusive::bstree_algorithms::get_header(const const_node_ptr&) - static node_ptr get_header(const const_node_ptr & n); + //! @copydoc ::boost::intrusive::bstree_algorithms::get_header(const_node_ptr) + static node_ptr get_header(const_node_ptr n) BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::bstree_algorithms::begin_node - static node_ptr begin_node(const const_node_ptr & header); + static node_ptr begin_node(const_node_ptr header) BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::bstree_algorithms::end_node - static node_ptr end_node(const const_node_ptr & header); + static node_ptr end_node(const_node_ptr header) BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::bstree_algorithms::swap_tree - static void swap_tree(const node_ptr & header1, const node_ptr & header2); + static void swap_tree(node_ptr header1, node_ptr header2); //! @copydoc ::boost::intrusive::bstree_algorithms::swap_nodes(node_ptr,node_ptr) - static void swap_nodes(node_ptr node1, node_ptr node2); + static void swap_nodes(node_ptr node1, node_ptr node2) BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::bstree_algorithms::swap_nodes(node_ptr,node_ptr,node_ptr,node_ptr) - static void swap_nodes(node_ptr node1, node_ptr header1, node_ptr node2, node_ptr header2); + static void swap_nodes(node_ptr node1, node_ptr header1, node_ptr node2, node_ptr header2) BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::bstree_algorithms::replace_node(node_ptr,node_ptr) - static void replace_node(node_ptr node_to_be_replaced, node_ptr new_node); + static void replace_node(node_ptr node_to_be_replaced, node_ptr new_node) BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::bstree_algorithms::replace_node(node_ptr,node_ptr,node_ptr) - static void replace_node(node_ptr node_to_be_replaced, node_ptr header, node_ptr new_node); + static void replace_node(node_ptr node_to_be_replaced, node_ptr header, node_ptr new_node) BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::bstree_algorithms::unlink(node_ptr) - static void unlink(node_ptr node); + static void unlink(node_ptr n) BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::bstree_algorithms::unlink_leftmost_without_rebalance - static node_ptr unlink_leftmost_without_rebalance(node_ptr header); + static node_ptr unlink_leftmost_without_rebalance(node_ptr header) BOOST_NOEXCEPT; - //! @copydoc ::boost::intrusive::bstree_algorithms::unique(const const_node_ptr&) - static bool unique(const_node_ptr node); + //! @copydoc ::boost::intrusive::bstree_algorithms::unique(const_node_ptr) + static bool unique(const_node_ptr n) BOOST_NOEXCEPT; - //! @copydoc ::boost::intrusive::bstree_algorithms::size(const const_node_ptr&) - static std::size_t size(const_node_ptr header); + //! @copydoc ::boost::intrusive::bstree_algorithms::size(const_node_ptr) + static std::size_t size(const_node_ptr header) BOOST_NOEXCEPT; - //! @copydoc ::boost::intrusive::bstree_algorithms::next_node(const node_ptr&) - static node_ptr next_node(node_ptr node); + //! @copydoc ::boost::intrusive::bstree_algorithms::next_node(node_ptr) + static node_ptr next_node(node_ptr n) BOOST_NOEXCEPT; - //! @copydoc ::boost::intrusive::bstree_algorithms::prev_node(const node_ptr&) - static node_ptr prev_node(node_ptr node); + //! @copydoc ::boost::intrusive::bstree_algorithms::prev_node(node_ptr) + static node_ptr prev_node(node_ptr n) BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::bstree_algorithms::init(node_ptr) - static void init(node_ptr node); + static void init(node_ptr n) BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::bstree_algorithms::init_header(node_ptr) - static void init_header(node_ptr header); + static void init_header(node_ptr header) BOOST_NOEXCEPT; #endif //#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED //! @copydoc ::boost::intrusive::bstree_algorithms::erase(node_ptr,node_ptr) //! Additional notes: the previous node of z is splayed to speed up range deletions. - static void erase(node_ptr header, node_ptr z) + static void erase(node_ptr header, node_ptr z) BOOST_NOEXCEPT { //posibility 1 if(NodeTraits::get_left(z)){ @@ -279,17 +279,17 @@ class splaytree_algorithms } #ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED - //! @copydoc ::boost::intrusive::bstree_algorithms::clone(const const_node_ptr&,node_ptr,Cloner,Disposer) + //! @copydoc ::boost::intrusive::bstree_algorithms::clone(const_node_ptr,node_ptr,Cloner,Disposer) template static void clone (const_node_ptr source_header, node_ptr target_header, Cloner cloner, Disposer disposer); - //! @copydoc ::boost::intrusive::bstree_algorithms::clear_and_dispose(const node_ptr&,Disposer) + //! @copydoc ::boost::intrusive::bstree_algorithms::clear_and_dispose(node_ptr,Disposer) template - static void clear_and_dispose(node_ptr header, Disposer disposer); + static void clear_and_dispose(node_ptr header, Disposer disposer) BOOST_NOEXCEPT; #endif //#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED - //! @copydoc ::boost::intrusive::bstree_algorithms::count(const const_node_ptr&,const KeyType&,KeyNodePtrCompare) + //! @copydoc ::boost::intrusive::bstree_algorithms::count(const_node_ptr,const KeyType&,KeyNodePtrCompare) //! Additional notes: an element with key `key` is splayed. template static std::size_t count @@ -304,14 +304,14 @@ class splaytree_algorithms return n; } - //! @copydoc ::boost::intrusive::bstree_algorithms::count(const const_node_ptr&,const KeyType&,KeyNodePtrCompare) + //! @copydoc ::boost::intrusive::bstree_algorithms::count(const_node_ptr,const KeyType&,KeyNodePtrCompare) //! Additional note: no splaying is performed template static std::size_t count (const_node_ptr header, const KeyType &key, KeyNodePtrCompare comp) { return bstree_algo::count(header, key, comp); } - //! @copydoc ::boost::intrusive::bstree_algorithms::lower_bound(const const_node_ptr&,const KeyType&,KeyNodePtrCompare) + //! @copydoc ::boost::intrusive::bstree_algorithms::lower_bound(const_node_ptr,const KeyType&,KeyNodePtrCompare) //! Additional notes: the first node of the range is splayed. template static node_ptr lower_bound @@ -323,14 +323,14 @@ class splaytree_algorithms return y; } - //! @copydoc ::boost::intrusive::bstree_algorithms::lower_bound(const const_node_ptr&,const KeyType&,KeyNodePtrCompare) + //! @copydoc ::boost::intrusive::bstree_algorithms::lower_bound(const_node_ptr,const KeyType&,KeyNodePtrCompare) //! Additional note: no splaying is performed template static node_ptr lower_bound (const_node_ptr header, const KeyType &key, KeyNodePtrCompare comp) { return bstree_algo::lower_bound(header, key, comp); } - //! @copydoc ::boost::intrusive::bstree_algorithms::upper_bound(const const_node_ptr&,const KeyType&,KeyNodePtrCompare) + //! @copydoc ::boost::intrusive::bstree_algorithms::upper_bound(const_node_ptr,const KeyType&,KeyNodePtrCompare) //! Additional notes: the first node of the range is splayed. template static node_ptr upper_bound @@ -342,14 +342,14 @@ class splaytree_algorithms return y; } - //! @copydoc ::boost::intrusive::bstree_algorithms::upper_bound(const const_node_ptr&,const KeyType&,KeyNodePtrCompare) + //! @copydoc ::boost::intrusive::bstree_algorithms::upper_bound(const_node_ptr,const KeyType&,KeyNodePtrCompare) //! Additional note: no splaying is performed template static node_ptr upper_bound (const_node_ptr header, const KeyType &key, KeyNodePtrCompare comp) { return bstree_algo::upper_bound(header, key, comp); } - //! @copydoc ::boost::intrusive::bstree_algorithms::find(const const_node_ptr&, const KeyType&,KeyNodePtrCompare) + //! @copydoc ::boost::intrusive::bstree_algorithms::find(const_node_ptr, const KeyType&,KeyNodePtrCompare) //! Additional notes: the found node of the lower bound is splayed. template static node_ptr find @@ -359,14 +359,14 @@ class splaytree_algorithms return bstree_algo::find(header, key, comp); } - //! @copydoc ::boost::intrusive::bstree_algorithms::find(const const_node_ptr&, const KeyType&,KeyNodePtrCompare) + //! @copydoc ::boost::intrusive::bstree_algorithms::find(const_node_ptr, const KeyType&,KeyNodePtrCompare) //! Additional note: no splaying is performed template static node_ptr find (const_node_ptr header, const KeyType &key, KeyNodePtrCompare comp) { return bstree_algo::find(header, key, comp); } - //! @copydoc ::boost::intrusive::bstree_algorithms::equal_range(const const_node_ptr&,const KeyType&,KeyNodePtrCompare) + //! @copydoc ::boost::intrusive::bstree_algorithms::equal_range(const_node_ptr,const KeyType&,KeyNodePtrCompare) //! Additional notes: the first node of the range is splayed. template static std::pair equal_range @@ -378,14 +378,14 @@ class splaytree_algorithms return ret; } - //! @copydoc ::boost::intrusive::bstree_algorithms::equal_range(const const_node_ptr&,const KeyType&,KeyNodePtrCompare) + //! @copydoc ::boost::intrusive::bstree_algorithms::equal_range(const_node_ptr,const KeyType&,KeyNodePtrCompare) //! Additional note: no splaying is performed template static std::pair equal_range (const_node_ptr header, const KeyType &key, KeyNodePtrCompare comp) { return bstree_algo::equal_range(header, key, comp); } - //! @copydoc ::boost::intrusive::bstree_algorithms::lower_bound_range(const const_node_ptr&,const KeyType&,KeyNodePtrCompare) + //! @copydoc ::boost::intrusive::bstree_algorithms::lower_bound_range(const_node_ptr,const KeyType&,KeyNodePtrCompare) //! Additional notes: the first node of the range is splayed. template static std::pair lower_bound_range @@ -397,14 +397,14 @@ class splaytree_algorithms return ret; } - //! @copydoc ::boost::intrusive::bstree_algorithms::lower_bound_range(const const_node_ptr&,const KeyType&,KeyNodePtrCompare) + //! @copydoc ::boost::intrusive::bstree_algorithms::lower_bound_range(const_node_ptr,const KeyType&,KeyNodePtrCompare) //! Additional note: no splaying is performed template static std::pair lower_bound_range (const_node_ptr header, const KeyType &key, KeyNodePtrCompare comp) { return bstree_algo::lower_bound_range(header, key, comp); } - //! @copydoc ::boost::intrusive::bstree_algorithms::bounded_range(const const_node_ptr&,const KeyType&,const KeyType&,KeyNodePtrCompare,bool,bool) + //! @copydoc ::boost::intrusive::bstree_algorithms::bounded_range(const_node_ptr,const KeyType&,const KeyType&,KeyNodePtrCompare,bool,bool) //! Additional notes: the first node of the range is splayed. template static std::pair bounded_range @@ -418,7 +418,7 @@ class splaytree_algorithms return ret; } - //! @copydoc ::boost::intrusive::bstree_algorithms::bounded_range(const const_node_ptr&,const KeyType&,const KeyType&,KeyNodePtrCompare,bool,bool) + //! @copydoc ::boost::intrusive::bstree_algorithms::bounded_range(const_node_ptr,const KeyType&,const KeyType&,KeyNodePtrCompare,bool,bool) //! Additional note: no splaying is performed template static std::pair bounded_range @@ -459,7 +459,7 @@ class splaytree_algorithms //! @copydoc ::boost::intrusive::bstree_algorithms::insert_before(node_ptr,node_ptr,node_ptr) //! Additional note: the inserted node is splayed static node_ptr insert_before - (node_ptr header, node_ptr pos, node_ptr new_node) + (node_ptr header, node_ptr pos, node_ptr new_node) BOOST_NOEXCEPT { bstree_algo::insert_before(header, pos, new_node); splay_up(new_node, header); @@ -468,7 +468,7 @@ class splaytree_algorithms //! @copydoc ::boost::intrusive::bstree_algorithms::push_back(node_ptr,node_ptr) //! Additional note: the inserted node is splayed - static void push_back(node_ptr header, node_ptr new_node) + static void push_back(node_ptr header, node_ptr new_node) BOOST_NOEXCEPT { bstree_algo::push_back(header, new_node); splay_up(new_node, header); @@ -476,13 +476,13 @@ class splaytree_algorithms //! @copydoc ::boost::intrusive::bstree_algorithms::push_front(node_ptr,node_ptr) //! Additional note: the inserted node is splayed - static void push_front(node_ptr header, node_ptr new_node) + static void push_front(node_ptr header, node_ptr new_node) BOOST_NOEXCEPT { bstree_algo::push_front(header, new_node); splay_up(new_node, header); } - //! @copydoc ::boost::intrusive::bstree_algorithms::insert_unique_check(const const_node_ptr&,const KeyType&,KeyNodePtrCompare,insert_commit_data&) + //! @copydoc ::boost::intrusive::bstree_algorithms::insert_unique_check(const_node_ptr,const KeyType&,KeyNodePtrCompare,insert_commit_data&) //! Additional note: nodes with the given key are splayed template static std::pair insert_unique_check @@ -493,7 +493,7 @@ class splaytree_algorithms return bstree_algo::insert_unique_check(header, key, comp, commit_data); } - //! @copydoc ::boost::intrusive::bstree_algorithms::insert_unique_check(const const_node_ptr&,const node_ptr&,const KeyType&,KeyNodePtrCompare,insert_commit_data&) + //! @copydoc ::boost::intrusive::bstree_algorithms::insert_unique_check(const_node_ptr,node_ptr,const KeyType&,KeyNodePtrCompare,insert_commit_data&) //! Additional note: nodes with the given key are splayed template static std::pair insert_unique_check @@ -507,22 +507,22 @@ class splaytree_algorithms #ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED //! @copydoc ::boost::intrusive::bstree_algorithms::insert_unique_commit(node_ptr,node_ptr,const insert_commit_data&) static void insert_unique_commit - (node_ptr header, node_ptr new_value, const insert_commit_data &commit_data); + (node_ptr header, node_ptr new_value, const insert_commit_data &commit_data) BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::bstree_algorithms::is_header - static bool is_header(const_node_ptr p); + static bool is_header(const_node_ptr p) BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::bstree_algorithms::rebalance - static void rebalance(node_ptr header); + static void rebalance(node_ptr header) BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::bstree_algorithms::rebalance_subtree - static node_ptr rebalance_subtree(node_ptr old_root); + static node_ptr rebalance_subtree(node_ptr old_root) BOOST_NOEXCEPT; #endif //#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED // bottom-up splay, use data_ as parent for n | complexity : logarithmic | exception : nothrow - static void splay_up(node_ptr node, node_ptr header) - { priv_splay_up(node, header); } + static void splay_up(node_ptr n, node_ptr header) BOOST_NOEXCEPT + { priv_splay_up(n, header); } // top-down splay | complexity : logarithmic | exception : strong, note A template @@ -535,12 +535,14 @@ class splaytree_algorithms // bottom-up splay, use data_ as parent for n | complexity : logarithmic | exception : nothrow template - static void priv_splay_up(node_ptr node, node_ptr header) + static void priv_splay_up(node_ptr n, node_ptr header) BOOST_NOEXCEPT { // If (node == header) do a splay for the right most node instead // this is to boost performance of equal_range/count on equivalent containers in the case // where there are many equal elements at the end - node_ptr n((node == header) ? NodeTraits::get_right(header) : node); + if(n == header) + n = NodeTraits::get_right(header); + node_ptr t(header); if( n == t ) return; @@ -660,7 +662,7 @@ class splaytree_algorithms } // break link to left child node and attach it to left tree pointed to by l | complexity : constant | exception : nothrow - static void link_left(node_ptr & t, node_ptr & l) + static void link_left(node_ptr & t, node_ptr & l) BOOST_NOEXCEPT { //procedure link_left; // t, l, right(l) := right(t), t, t @@ -672,7 +674,7 @@ class splaytree_algorithms } // break link to right child node and attach it to right tree pointed to by r | complexity : constant | exception : nothrow - static void link_right(node_ptr & t, node_ptr & r) + static void link_right(node_ptr & t, node_ptr & r) BOOST_NOEXCEPT { //procedure link_right; // t, r, left(r) := left(t), t, t @@ -684,7 +686,7 @@ class splaytree_algorithms } // rotate n with its parent | complexity : constant | exception : nothrow - static void rotate(node_ptr n) + static void rotate(node_ptr n) BOOST_NOEXCEPT { //procedure rotate_left; // t, right(t), left(right(t)) := right(t), left(right(t)), t diff --git a/include/boost/intrusive/treap.hpp b/include/boost/intrusive/treap.hpp index d5e3c0ce8..ff84b7472 100644 --- a/include/boost/intrusive/treap.hpp +++ b/include/boost/intrusive/treap.hpp @@ -232,22 +232,22 @@ class treap_impl ~treap_impl(); //! @copydoc ::boost::intrusive::bstree::begin() - iterator begin(); + iterator begin() BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::bstree::begin()const - const_iterator begin() const; + const_iterator begin() const BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::bstree::cbegin()const - const_iterator cbegin() const; + const_iterator cbegin() const BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::bstree::end() - iterator end(); + iterator end() BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::bstree::end()const - const_iterator end() const; + const_iterator end() const BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::bstree::cend()const - const_iterator cend() const; + const_iterator cend() const BOOST_NOEXCEPT; #endif //! Effects: Returns an iterator pointing to the highest priority object of the treap. @@ -255,7 +255,7 @@ class treap_impl //! Complexity: Constant. //! //! Throws: Nothing. - iterator top() + BOOST_INTRUSIVE_FORCEINLINE iterator top() BOOST_NOEXCEPT { return this->tree_type::root(); } //! Effects: Returns a const_iterator pointing to the highest priority object of the treap.. @@ -263,7 +263,7 @@ class treap_impl //! Complexity: Constant. //! //! Throws: Nothing. - const_iterator top() const + BOOST_INTRUSIVE_FORCEINLINE const_iterator top() const BOOST_NOEXCEPT { return this->ctop(); } //! Effects: Returns a const_iterator pointing to the highest priority object of the treap.. @@ -271,36 +271,36 @@ class treap_impl //! Complexity: Constant. //! //! Throws: Nothing. - const_iterator ctop() const + BOOST_INTRUSIVE_FORCEINLINE const_iterator ctop() const BOOST_NOEXCEPT { return this->tree_type::root(); } #ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED //! @copydoc ::boost::intrusive::bstree::rbegin() - reverse_iterator rbegin(); + reverse_iterator rbegin() BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::bstree::rbegin()const - const_reverse_iterator rbegin() const; + const_reverse_iterator rbegin() const BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::bstree::crbegin()const - const_reverse_iterator crbegin() const; + const_reverse_iterator crbegin() const BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::bstree::rend() - reverse_iterator rend(); + reverse_iterator rend() BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::bstree::rend()const - const_reverse_iterator rend() const; + const_reverse_iterator rend() const BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::bstree::crend()const - const_reverse_iterator crend() const; + const_reverse_iterator crend() const BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::bstree::root() - iterator root(); + iterator root() BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::bstree::root()const - const_iterator root() const; + const_iterator root() const BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::bstree::croot()const - const_iterator croot() const; + const_iterator croot() const BOOST_NOEXCEPT; #endif @@ -310,7 +310,7 @@ class treap_impl //! Complexity: Constant. //! //! Throws: Nothing. - reverse_iterator rtop() + BOOST_INTRUSIVE_FORCEINLINE reverse_iterator rtop() BOOST_NOEXCEPT { return reverse_iterator(this->top()); } //! Effects: Returns a const_reverse_iterator pointing to the highest priority objec @@ -319,7 +319,7 @@ class treap_impl //! Complexity: Constant. //! //! Throws: Nothing. - const_reverse_iterator rtop() const + BOOST_INTRUSIVE_FORCEINLINE const_reverse_iterator rtop() const BOOST_NOEXCEPT { return const_reverse_iterator(this->top()); } //! Effects: Returns a const_reverse_iterator pointing to the highest priority object @@ -328,21 +328,21 @@ class treap_impl //! Complexity: Constant. //! //! Throws: Nothing. - const_reverse_iterator crtop() const + BOOST_INTRUSIVE_FORCEINLINE const_reverse_iterator crtop() const BOOST_NOEXCEPT { return const_reverse_iterator(this->top()); } #ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED //! @copydoc ::boost::intrusive::bstree::container_from_end_iterator(iterator) - static treap_impl &container_from_end_iterator(iterator end_iterator); + static treap_impl &container_from_end_iterator(iterator end_iterator) BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::bstree::container_from_end_iterator(const_iterator) - static const treap_impl &container_from_end_iterator(const_iterator end_iterator); + static const treap_impl &container_from_end_iterator(const_iterator end_iterator) BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::bstree::container_from_iterator(iterator) - static treap_impl &container_from_iterator(iterator it); + static treap_impl &container_from_iterator(iterator it) BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::bstree::container_from_iterator(const_iterator) - static const treap_impl &container_from_iterator(const_iterator it); + static const treap_impl &container_from_iterator(const_iterator it) BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::bstree::key_comp()const key_compare key_comp() const; @@ -351,10 +351,10 @@ class treap_impl value_compare value_comp() const; //! @copydoc ::boost::intrusive::bstree::empty()const - bool empty() const; + bool empty() const BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::bstree::size()const - size_type size() const; + size_type size() const BOOST_NOEXCEPT; #endif //#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED //! Effects: Returns the priority_compare object used by the container. @@ -755,7 +755,7 @@ class treap_impl //! Notes: This function has only sense if a "insert_check" has been //! previously executed to fill "commit_data". No value should be inserted or //! erased between the "insert_check" and "insert_commit" calls. - iterator insert_unique_commit(reference value, const insert_commit_data &commit_data) + iterator insert_unique_commit(reference value, const insert_commit_data &commit_data) BOOST_NOEXCEPT { node_ptr to_insert(this->get_value_traits().to_node_ptr(value)); BOOST_INTRUSIVE_SAFE_HOOK_DEFAULT_ASSERT(!safemode_or_autounlink || node_algorithms::unique(to_insert)); @@ -778,7 +778,7 @@ class treap_impl //! the successor of "value" container ordering invariant will be broken. //! This is a low-level function to be used only for performance reasons //! by advanced users. - iterator insert_before(const_iterator pos, reference value) + iterator insert_before(const_iterator pos, reference value) BOOST_NOEXCEPT { node_ptr to_insert(this->get_value_traits().to_node_ptr(value)); BOOST_INTRUSIVE_SAFE_HOOK_DEFAULT_ASSERT(!safemode_or_autounlink || node_algorithms::unique(to_insert)); @@ -808,7 +808,7 @@ class treap_impl //! This function is slightly more efficient than using "insert_before". //! This is a low-level function to be used only for performance reasons //! by advanced users. - void push_back(reference value) + void push_back(reference value) BOOST_NOEXCEPT { node_ptr to_insert(this->get_value_traits().to_node_ptr(value)); BOOST_INTRUSIVE_SAFE_HOOK_DEFAULT_ASSERT(!safemode_or_autounlink || node_algorithms::unique(to_insert)); @@ -831,7 +831,7 @@ class treap_impl //! This function is slightly more efficient than using "insert_before". //! This is a low-level function to be used only for performance reasons //! by advanced users. - void push_front(reference value) + void push_front(reference value) BOOST_NOEXCEPT { node_ptr to_insert(this->get_value_traits().to_node_ptr(value)); BOOST_INTRUSIVE_SAFE_HOOK_DEFAULT_ASSERT(!safemode_or_autounlink || node_algorithms::unique(to_insert)); @@ -848,7 +848,7 @@ class treap_impl //! //! Note: Invalidates the iterators (but not the references) //! to the erased elements. No destructors are called. - iterator erase(const_iterator i) + iterator erase(const_iterator i) BOOST_NOEXCEPT { const_iterator ret(i); ++ret; @@ -857,7 +857,7 @@ class treap_impl node_algorithms::erase (this->tree_type::header_ptr(), to_erase, this->prio_node_prio_comp(this->priv_pcomp())); this->tree_type::sz_traits().decrement(); - if(safemode_or_autounlink) + BOOST_IF_CONSTEXPR(safemode_or_autounlink) node_algorithms::init(to_erase); return ret.unconst(); } @@ -871,7 +871,7 @@ class treap_impl //! //! Note: Invalidates the iterators (but not the references) //! to the erased elements. No destructors are called. - iterator erase(const_iterator b, const_iterator e) + iterator erase(const_iterator b, const_iterator e) BOOST_NOEXCEPT { size_type n; return private_erase(b, e, n); } //! Effects: Erases all the elements with the given value. @@ -922,7 +922,7 @@ class treap_impl //! Note: Invalidates the iterators //! to the erased elements. template - iterator erase_and_dispose(const_iterator i, Disposer disposer) + iterator erase_and_dispose(const_iterator i, Disposer disposer) BOOST_NOEXCEPT { node_ptr to_erase(i.pointed_node()); iterator ret(this->erase(i)); @@ -932,7 +932,7 @@ class treap_impl #if !defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED) template - iterator erase_and_dispose(iterator i, Disposer disposer) + iterator erase_and_dispose(iterator i, Disposer disposer) BOOST_NOEXCEPT { return this->erase_and_dispose(const_iterator(i), disposer); } #endif @@ -949,7 +949,7 @@ class treap_impl //! Note: Invalidates the iterators //! to the erased elements. template - iterator erase_and_dispose(const_iterator b, const_iterator e, Disposer disposer) + iterator erase_and_dispose(const_iterator b, const_iterator e, Disposer disposer) BOOST_NOEXCEPT { size_type n; return private_erase(b, e, n, disposer); } //! Requires: Disposer::operator()(pointer) shouldn't throw. @@ -1010,7 +1010,7 @@ class treap_impl //! //! Note: Invalidates the iterators (but not the references) //! to the erased elements. No destructors are called. - void clear() + void clear() BOOST_NOEXCEPT { tree_type::clear(); } //! Effects: Erases all of the elements calling disposer(p) for @@ -1023,7 +1023,7 @@ class treap_impl //! Note: Invalidates the iterators (but not the references) //! to the erased elements. Calls N times to disposer functor. template - void clear_and_dispose(Disposer disposer) + void clear_and_dispose(Disposer disposer) BOOST_NOEXCEPT { node_algorithms::clear_and_dispose(this->tree_type::header_ptr() , detail::node_disposer(disposer, &this->get_value_traits())); @@ -1180,28 +1180,28 @@ class treap_impl (const KeyType& lower_key, const KeyType& upper_key, KeyTypeKeyCompare comp, bool left_closed, bool right_closed) const; //! @copydoc ::boost::intrusive::bstree::s_iterator_to(reference) - static iterator s_iterator_to(reference value); + static iterator s_iterator_to(reference value) BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::bstree::s_iterator_to(const_reference) - static const_iterator s_iterator_to(const_reference value); + static const_iterator s_iterator_to(const_reference value) BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::bstree::iterator_to(reference) - iterator iterator_to(reference value); + iterator iterator_to(reference value) BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::bstree::iterator_to(const_reference)const - const_iterator iterator_to(const_reference value) const; + const_iterator iterator_to(const_reference value) const BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::bstree::init_node(reference) - static void init_node(reference value); + static void init_node(reference value) BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::bstree::unlink_leftmost_without_rebalance - pointer unlink_leftmost_without_rebalance(); + pointer unlink_leftmost_without_rebalance() BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::bstree::replace_node - void replace_node(iterator replace_this, reference with_this); + void replace_node(iterator replace_this, reference with_this) BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::bstree::remove_node - void remove_node(reference value); + void remove_node(reference value) BOOST_NOEXCEPT; friend bool operator< (const treap_impl &x, const treap_impl &y); @@ -1348,16 +1348,16 @@ class treap BOOST_INTRUSIVE_FORCEINLINE void clone_from(BOOST_RV_REF(treap) src, Cloner cloner, Disposer disposer) { Base::clone_from(BOOST_MOVE_BASE(Base, src), cloner, disposer); } - BOOST_INTRUSIVE_FORCEINLINE static treap &container_from_end_iterator(iterator end_iterator) + BOOST_INTRUSIVE_FORCEINLINE static treap &container_from_end_iterator(iterator end_iterator) BOOST_NOEXCEPT { return static_cast(Base::container_from_end_iterator(end_iterator)); } - BOOST_INTRUSIVE_FORCEINLINE static const treap &container_from_end_iterator(const_iterator end_iterator) + BOOST_INTRUSIVE_FORCEINLINE static const treap &container_from_end_iterator(const_iterator end_iterator) BOOST_NOEXCEPT { return static_cast(Base::container_from_end_iterator(end_iterator)); } - BOOST_INTRUSIVE_FORCEINLINE static treap &container_from_iterator(iterator it) + BOOST_INTRUSIVE_FORCEINLINE static treap &container_from_iterator(iterator it) BOOST_NOEXCEPT { return static_cast(Base::container_from_iterator(it)); } - BOOST_INTRUSIVE_FORCEINLINE static const treap &container_from_iterator(const_iterator it) + BOOST_INTRUSIVE_FORCEINLINE static const treap &container_from_iterator(const_iterator it) BOOST_NOEXCEPT { return static_cast(Base::container_from_iterator(it)); } }; diff --git a/include/boost/intrusive/treap_algorithms.hpp b/include/boost/intrusive/treap_algorithms.hpp index a2a29d213..a8ddee6e3 100644 --- a/include/boost/intrusive/treap_algorithms.hpp +++ b/include/boost/intrusive/treap_algorithms.hpp @@ -49,7 +49,7 @@ struct treap_node_extra_checker : base_checker_t(extra_checker), prio_comp_(prio_comp) {} - void operator () (const const_node_ptr& p, + void operator () (const_node_ptr p, const return_type& check_return_left, const return_type& check_return_right, return_type& check_return) { @@ -178,64 +178,64 @@ class treap_algorithms #ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED - //! @copydoc ::boost::intrusive::bstree_algorithms::get_header(const const_node_ptr&) - static node_ptr get_header(const_node_ptr n); + //! @copydoc ::boost::intrusive::bstree_algorithms::get_header(const_node_ptr) + static node_ptr get_header(const_node_ptr n) BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::bstree_algorithms::begin_node - static node_ptr begin_node(const_node_ptr header); + static node_ptr begin_node(const_node_ptr header) BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::bstree_algorithms::end_node - static node_ptr end_node(const_node_ptr header); + static node_ptr end_node(const_node_ptr header) BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::bstree_algorithms::swap_tree - static void swap_tree(node_ptr header1, node_ptr header2); + static void swap_tree(node_ptr header1, node_ptr header2) BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::bstree_algorithms::swap_nodes(node_ptr,node_ptr) - static void swap_nodes(node_ptr node1, node_ptr node2); + static void swap_nodes(node_ptr node1, node_ptr node2) BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::bstree_algorithms::swap_nodes(node_ptr,node_ptr,node_ptr,node_ptr) - static void swap_nodes(node_ptr node1, node_ptr header1, node_ptr node2, node_ptr header2); + static void swap_nodes(node_ptr node1, node_ptr header1, node_ptr node2, node_ptr header2) BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::bstree_algorithms::replace_node(node_ptr,node_ptr) - static void replace_node(node_ptr node_to_be_replaced, node_ptr new_node); + static void replace_node(node_ptr node_to_be_replaced, node_ptr new_node) BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::bstree_algorithms::replace_node(node_ptr,node_ptr,node_ptr) - static void replace_node(node_ptr node_to_be_replaced, node_ptr header, node_ptr new_node); + static void replace_node(node_ptr node_to_be_replaced, node_ptr header, node_ptr new_node) BOOST_NOEXCEPT; #endif //#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED //! @copydoc ::boost::intrusive::bstree_algorithms::unlink(node_ptr) template - static void unlink(node_ptr node, NodePtrPriorityCompare pcomp) + static void unlink(node_ptr n, NodePtrPriorityCompare pcomp) { - node_ptr x = NodeTraits::get_parent(node); + node_ptr x = NodeTraits::get_parent(n); if(x){ while(!bstree_algo::is_header(x)) x = NodeTraits::get_parent(x); - erase(x, node, pcomp); + erase(x, n, pcomp); } } #ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED //! @copydoc ::boost::intrusive::bstree_algorithms::unlink_leftmost_without_rebalance - static node_ptr unlink_leftmost_without_rebalance(node_ptr header); + static node_ptr unlink_leftmost_without_rebalance(node_ptr header) BOOST_NOEXCEPT; - //! @copydoc ::boost::intrusive::bstree_algorithms::unique(const const_node_ptr&) - static bool unique(const_node_ptr node); + //! @copydoc ::boost::intrusive::bstree_algorithms::unique(const_node_ptr) + static bool unique(const_node_ptr n) BOOST_NOEXCEPT; - //! @copydoc ::boost::intrusive::bstree_algorithms::size(const const_node_ptr&) - static std::size_t size(const_node_ptr header); + //! @copydoc ::boost::intrusive::bstree_algorithms::size(const_node_ptr) + static std::size_t size(const_node_ptr header) BOOST_NOEXCEPT; - //! @copydoc ::boost::intrusive::bstree_algorithms::next_node(const node_ptr&) - static node_ptr next_node(node_ptr node); + //! @copydoc ::boost::intrusive::bstree_algorithms::next_node(node_ptr) + static node_ptr next_node(node_ptr n) BOOST_NOEXCEPT; - //! @copydoc ::boost::intrusive::bstree_algorithms::prev_node(const node_ptr&) - static node_ptr prev_node(node_ptr node); + //! @copydoc ::boost::intrusive::bstree_algorithms::prev_node(node_ptr) + static node_ptr prev_node(node_ptr n) BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::bstree_algorithms::init(node_ptr) - static void init(node_ptr node); + static void init(node_ptr n) BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::bstree_algorithms::init_header(node_ptr) - static void init_header(node_ptr header); + static void init_header(node_ptr header) BOOST_NOEXCEPT; #endif //#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED //! @copydoc ::boost::intrusive::bstree_algorithms::erase(node_ptr,node_ptr) @@ -248,42 +248,42 @@ class treap_algorithms } #ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED - //! @copydoc ::boost::intrusive::bstree_algorithms::clone(const const_node_ptr&,node_ptr,Cloner,Disposer) + //! @copydoc ::boost::intrusive::bstree_algorithms::clone(const_node_ptr,node_ptr,Cloner,Disposer) template static void clone (const_node_ptr source_header, node_ptr target_header, Cloner cloner, Disposer disposer); - //! @copydoc ::boost::intrusive::bstree_algorithms::clear_and_dispose(const node_ptr&,Disposer) + //! @copydoc ::boost::intrusive::bstree_algorithms::clear_and_dispose(node_ptr,Disposer) template - static void clear_and_dispose(node_ptr header, Disposer disposer); + static void clear_and_dispose(node_ptr header, Disposer disposer) BOOST_NOEXCEPT; - //! @copydoc ::boost::intrusive::bstree_algorithms::lower_bound(const const_node_ptr&,const KeyType&,KeyNodePtrCompare) + //! @copydoc ::boost::intrusive::bstree_algorithms::lower_bound(const_node_ptr,const KeyType&,KeyNodePtrCompare) template static node_ptr lower_bound (const_node_ptr header, const KeyType &key, KeyNodePtrCompare comp); - //! @copydoc ::boost::intrusive::bstree_algorithms::upper_bound(const const_node_ptr&,const KeyType&,KeyNodePtrCompare) + //! @copydoc ::boost::intrusive::bstree_algorithms::upper_bound(const_node_ptr,const KeyType&,KeyNodePtrCompare) template static node_ptr upper_bound (const_node_ptr header, const KeyType &key, KeyNodePtrCompare comp); - //! @copydoc ::boost::intrusive::bstree_algorithms::find(const const_node_ptr&, const KeyType&,KeyNodePtrCompare) + //! @copydoc ::boost::intrusive::bstree_algorithms::find(const_node_ptr, const KeyType&,KeyNodePtrCompare) template static node_ptr find (const_node_ptr header, const KeyType &key, KeyNodePtrCompare comp); - //! @copydoc ::boost::intrusive::bstree_algorithms::equal_range(const const_node_ptr&,const KeyType&,KeyNodePtrCompare) + //! @copydoc ::boost::intrusive::bstree_algorithms::equal_range(const_node_ptr,const KeyType&,KeyNodePtrCompare) template static std::pair equal_range (const_node_ptr header, const KeyType &key, KeyNodePtrCompare comp); - //! @copydoc ::boost::intrusive::bstree_algorithms::bounded_range(const const_node_ptr&,const KeyType&,const KeyType&,KeyNodePtrCompare,bool,bool) + //! @copydoc ::boost::intrusive::bstree_algorithms::bounded_range(const_node_ptr,const KeyType&,const KeyType&,KeyNodePtrCompare,bool,bool) template static std::pair bounded_range (const_node_ptr header, const KeyType &lower_key, const KeyType &upper_key, KeyNodePtrCompare comp , bool left_closed, bool right_closed); - //! @copydoc ::boost::intrusive::bstree_algorithms::count(const const_node_ptr&,const KeyType&,KeyNodePtrCompare) + //! @copydoc ::boost::intrusive::bstree_algorithms::count(const_node_ptr,const KeyType&,KeyNodePtrCompare) template static std::size_t count(const_node_ptr header, const KeyType &key, KeyNodePtrCompare comp); @@ -564,7 +564,7 @@ class treap_algorithms //! previously executed to fill "commit_data". No value should be inserted or //! erased between the "insert_check" and "insert_commit" calls. static void insert_unique_commit - (node_ptr header, node_ptr new_node, const insert_commit_data &commit_data) + (node_ptr header, node_ptr new_node, const insert_commit_data &commit_data) BOOST_NOEXCEPT { bstree_algo::insert_unique_commit(header, new_node, commit_data); rotate_up_n(header, new_node, commit_data.rotations); @@ -601,7 +601,7 @@ class treap_algorithms #ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED //! @copydoc ::boost::intrusive::bstree_algorithms::is_header - static bool is_header(const_node_ptr p); + static bool is_header(const_node_ptr p) BOOST_NOEXCEPT; #endif //#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED /// @cond diff --git a/include/boost/intrusive/treap_set.hpp b/include/boost/intrusive/treap_set.hpp index 31d0f6a03..d15a83b49 100644 --- a/include/boost/intrusive/treap_set.hpp +++ b/include/boost/intrusive/treap_set.hpp @@ -126,61 +126,61 @@ class treap_set_impl ~treap_set_impl(); //! @copydoc ::boost::intrusive::treap::begin() - iterator begin(); + iterator begin() BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::treap::begin()const - const_iterator begin() const; + const_iterator begin() const BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::treap::cbegin()const - const_iterator cbegin() const; + const_iterator cbegin() const BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::treap::end() - iterator end(); + iterator end() BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::treap::end()const - const_iterator end() const; + const_iterator end() const BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::treap::cend()const - const_iterator cend() const; + const_iterator cend() const BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::treap::rbegin() - reverse_iterator rbegin(); + reverse_iterator rbegin() BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::treap::rbegin()const - const_reverse_iterator rbegin() const; + const_reverse_iterator rbegin() const BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::treap::crbegin()const - const_reverse_iterator crbegin() const; + const_reverse_iterator crbegin() const BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::treap::rend() - reverse_iterator rend(); + reverse_iterator rend() BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::treap::rend()const - const_reverse_iterator rend() const; + const_reverse_iterator rend() const BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::treap::crend()const - const_reverse_iterator crend() const; + const_reverse_iterator crend() const BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::treap::root() - iterator root(); + iterator root() BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::treap::root()const - const_iterator root() const; + const_iterator root() const BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::treap::croot()const - const_iterator croot() const; + const_iterator croot() const BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::treap::container_from_end_iterator(iterator) - static treap_set_impl &container_from_end_iterator(iterator end_iterator); + static treap_set_impl &container_from_end_iterator(iterator end_iterator) BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::treap::container_from_end_iterator(const_iterator) - static const treap_set_impl &container_from_end_iterator(const_iterator end_iterator); + static const treap_set_impl &container_from_end_iterator(const_iterator end_iterator) BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::treap::container_from_iterator(iterator) - static treap_set_impl &container_from_iterator(iterator it); + static treap_set_impl &container_from_iterator(iterator it) BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::treap::container_from_iterator(const_iterator) - static const treap_set_impl &container_from_iterator(const_iterator it); + static const treap_set_impl &container_from_iterator(const_iterator it) BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::treap::key_comp()const key_compare key_comp() const; @@ -189,10 +189,10 @@ class treap_set_impl value_compare value_comp() const; //! @copydoc ::boost::intrusive::treap::empty()const - bool empty() const; + bool empty() const BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::treap::size()const - size_type size() const; + size_type size() const BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::treap::swap void swap(treap_set_impl& other); @@ -215,22 +215,22 @@ class treap_set_impl #if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED) //! @copydoc ::boost::intrusive::treap::top() - iterator top(); + BOOST_INTRUSIVE_FORCEINLINE iterator top() BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::treap::top()const - const_iterator top() const; + BOOST_INTRUSIVE_FORCEINLINE const_iterator top() const BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::treap::ctop()const - const_iterator ctop() const; + BOOST_INTRUSIVE_FORCEINLINE const_iterator ctop() const BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::treap::rtop() - reverse_iterator rtop(); + BOOST_INTRUSIVE_FORCEINLINE reverse_iterator rtop() BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::treap::rtop()const - const_reverse_iterator rtop() const; + BOOST_INTRUSIVE_FORCEINLINE const_reverse_iterator rtop() const BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::treap::crtop()const - const_reverse_iterator crtop() const; + BOOST_INTRUSIVE_FORCEINLINE const_reverse_iterator crtop() const BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::treap::crtop() const priority_compare priority_comp() const; @@ -275,24 +275,24 @@ class treap_set_impl { tree_type::insert_unique(b, e); } //! @copydoc ::boost::intrusive::treap::insert_unique_commit - iterator insert_commit(reference value, const insert_commit_data &commit_data) + iterator insert_commit(reference value, const insert_commit_data &commit_data) BOOST_NOEXCEPT { return tree_type::insert_unique_commit(value, commit_data); } #ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED //! @copydoc ::boost::intrusive::treap::insert_before - iterator insert_before(const_iterator pos, reference value); + iterator insert_before(const_iterator pos, reference value) BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::treap::push_back - void push_back(reference value); + void push_back(reference value) BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::treap::push_front - void push_front(reference value); + void push_front(reference value) BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::treap::erase(const_iterator) - iterator erase(const_iterator i); + iterator erase(const_iterator i) BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::treap::erase(const_iterator,const_iterator) - iterator erase(const_iterator b, const_iterator e); + iterator erase(const_iterator b, const_iterator e) BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::treap::erase(const key_type &) size_type erase(const key_type &key); @@ -303,11 +303,11 @@ class treap_set_impl //! @copydoc ::boost::intrusive::treap::erase_and_dispose(const_iterator,Disposer) template - iterator erase_and_dispose(const_iterator i, Disposer disposer); + iterator erase_and_dispose(const_iterator i, Disposer disposer) BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::treap::erase_and_dispose(const_iterator,const_iterator,Disposer) template - iterator erase_and_dispose(const_iterator b, const_iterator e, Disposer disposer); + iterator erase_and_dispose(const_iterator b, const_iterator e, Disposer disposer) BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::treap::erase_and_dispose(const key_type &, Disposer) template @@ -318,11 +318,11 @@ class treap_set_impl size_type erase_and_dispose(const KeyType& key, KeyTypeKeyCompare comp, Disposer disposer); //! @copydoc ::boost::intrusive::treap::clear - void clear(); + void clear() BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::treap::clear_and_dispose template - void clear_and_dispose(Disposer disposer); + void clear_and_dispose(Disposer disposer) BOOST_NOEXCEPT; #endif // #ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED @@ -422,28 +422,28 @@ class treap_set_impl (const KeyType& lower_key, const KeyType& upper_key, KeyTypeKeyCompare comp, bool left_closed, bool right_closed) const; //! @copydoc ::boost::intrusive::treap::s_iterator_to(reference) - static iterator s_iterator_to(reference value); + static iterator s_iterator_to(reference value) BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::treap::s_iterator_to(const_reference) - static const_iterator s_iterator_to(const_reference value); + static const_iterator s_iterator_to(const_reference value) BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::treap::iterator_to(reference) - iterator iterator_to(reference value); + iterator iterator_to(reference value) BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::treap::iterator_to(const_reference)const - const_iterator iterator_to(const_reference value) const; + const_iterator iterator_to(const_reference value) const BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::treap::init_node(reference) - static void init_node(reference value); + static void init_node(reference value) BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::treap::unlink_leftmost_without_rebalance - pointer unlink_leftmost_without_rebalance(); + pointer unlink_leftmost_without_rebalance() BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::treap::replace_node - void replace_node(iterator replace_this, reference with_this); + void replace_node(iterator replace_this, reference with_this) BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::treap::remove_node - void remove_node(reference value); + void remove_node(reference value) BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::treap::merge_unique @@ -575,16 +575,16 @@ class treap_set BOOST_INTRUSIVE_FORCEINLINE void clone_from(BOOST_RV_REF(treap_set) src, Cloner cloner, Disposer disposer) { Base::clone_from(BOOST_MOVE_BASE(Base, src), cloner, disposer); } - BOOST_INTRUSIVE_FORCEINLINE static treap_set &container_from_end_iterator(iterator end_iterator) + BOOST_INTRUSIVE_FORCEINLINE static treap_set &container_from_end_iterator(iterator end_iterator) BOOST_NOEXCEPT { return static_cast(Base::container_from_end_iterator(end_iterator)); } - BOOST_INTRUSIVE_FORCEINLINE static const treap_set &container_from_end_iterator(const_iterator end_iterator) + BOOST_INTRUSIVE_FORCEINLINE static const treap_set &container_from_end_iterator(const_iterator end_iterator) BOOST_NOEXCEPT { return static_cast(Base::container_from_end_iterator(end_iterator)); } - BOOST_INTRUSIVE_FORCEINLINE static treap_set &container_from_iterator(iterator it) + BOOST_INTRUSIVE_FORCEINLINE static treap_set &container_from_iterator(iterator it) BOOST_NOEXCEPT { return static_cast(Base::container_from_iterator(it)); } - BOOST_INTRUSIVE_FORCEINLINE static const treap_set &container_from_iterator(const_iterator it) + BOOST_INTRUSIVE_FORCEINLINE static const treap_set &container_from_iterator(const_iterator it) BOOST_NOEXCEPT { return static_cast(Base::container_from_iterator(it)); } }; @@ -685,61 +685,61 @@ class treap_multiset_impl ~treap_multiset_impl(); //! @copydoc ::boost::intrusive::treap::begin() - iterator begin(); + iterator begin() BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::treap::begin()const - const_iterator begin() const; + const_iterator begin() const BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::treap::cbegin()const - const_iterator cbegin() const; + const_iterator cbegin() const BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::treap::end() - iterator end(); + iterator end() BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::treap::end()const - const_iterator end() const; + const_iterator end() const BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::treap::cend()const - const_iterator cend() const; + const_iterator cend() const BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::treap::rbegin() - reverse_iterator rbegin(); + reverse_iterator rbegin() BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::treap::rbegin()const - const_reverse_iterator rbegin() const; + const_reverse_iterator rbegin() const BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::treap::crbegin()const - const_reverse_iterator crbegin() const; + const_reverse_iterator crbegin() const BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::treap::rend() - reverse_iterator rend(); + reverse_iterator rend() BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::treap::rend()const - const_reverse_iterator rend() const; + const_reverse_iterator rend() const BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::treap::crend()const - const_reverse_iterator crend() const; + const_reverse_iterator crend() const BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::treap::root() - iterator root(); + iterator root() BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::treap::root()const - const_iterator root() const; + const_iterator root() const BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::treap::croot()const - const_iterator croot() const; + const_iterator croot() const BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::treap::container_from_end_iterator(iterator) - static treap_multiset_impl &container_from_end_iterator(iterator end_iterator); + static treap_multiset_impl &container_from_end_iterator(iterator end_iterator) BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::treap::container_from_end_iterator(const_iterator) - static const treap_multiset_impl &container_from_end_iterator(const_iterator end_iterator); + static const treap_multiset_impl &container_from_end_iterator(const_iterator end_iterator) BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::treap::container_from_iterator(iterator) - static treap_multiset_impl &container_from_iterator(iterator it); + static treap_multiset_impl &container_from_iterator(iterator it) BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::treap::container_from_iterator(const_iterator) - static const treap_multiset_impl &container_from_iterator(const_iterator it); + static const treap_multiset_impl &container_from_iterator(const_iterator it) BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::treap::key_comp()const key_compare key_comp() const; @@ -748,10 +748,10 @@ class treap_multiset_impl value_compare value_comp() const; //! @copydoc ::boost::intrusive::treap::empty()const - bool empty() const; + bool empty() const BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::treap::size()const - size_type size() const; + size_type size() const BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::treap::swap void swap(treap_multiset_impl& other); @@ -774,22 +774,22 @@ class treap_multiset_impl #if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED) //! @copydoc ::boost::intrusive::treap::top() - iterator top(); + BOOST_INTRUSIVE_FORCEINLINE iterator top() BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::treap::top()const - const_iterator top() const; + BOOST_INTRUSIVE_FORCEINLINE const_iterator top() const BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::treap::ctop()const - const_iterator ctop() const; + BOOST_INTRUSIVE_FORCEINLINE const_iterator ctop() const BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::treap::rtop() - reverse_iterator rtop(); + BOOST_INTRUSIVE_FORCEINLINE reverse_iterator rtop() BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::treap::rtop()const - const_reverse_iterator rtop() const; + BOOST_INTRUSIVE_FORCEINLINE const_reverse_iterator rtop() const BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::treap::crtop()const - const_reverse_iterator crtop() const; + BOOST_INTRUSIVE_FORCEINLINE const_reverse_iterator crtop() const BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::treap::crtop() const priority_compare priority_comp() const; @@ -810,19 +810,19 @@ class treap_multiset_impl #ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED //! @copydoc ::boost::intrusive::treap::insert_before - iterator insert_before(const_iterator pos, reference value); + iterator insert_before(const_iterator pos, reference value) BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::treap::push_back - void push_back(reference value); + void push_back(reference value) BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::treap::push_front - void push_front(reference value); + void push_front(reference value) BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::treap::erase(const_iterator) - iterator erase(const_iterator i); + iterator erase(const_iterator i) BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::treap::erase(const_iterator,const_iterator) - iterator erase(const_iterator b, const_iterator e); + iterator erase(const_iterator b, const_iterator e) BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::treap::erase(const key_type &) size_type erase(const key_type &key); @@ -833,11 +833,11 @@ class treap_multiset_impl //! @copydoc ::boost::intrusive::treap::erase_and_dispose(const_iterator,Disposer) template - iterator erase_and_dispose(const_iterator i, Disposer disposer); + iterator erase_and_dispose(const_iterator i, Disposer disposer) BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::treap::erase_and_dispose(const_iterator,const_iterator,Disposer) template - iterator erase_and_dispose(const_iterator b, const_iterator e, Disposer disposer); + iterator erase_and_dispose(const_iterator b, const_iterator e, Disposer disposer) BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::treap::erase_and_dispose(const key_type &, Disposer) template @@ -848,11 +848,11 @@ class treap_multiset_impl size_type erase_and_dispose(const KeyType& key, KeyTypeKeyCompare comp, Disposer disposer); //! @copydoc ::boost::intrusive::treap::clear - void clear(); + void clear() BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::treap::clear_and_dispose template - void clear_and_dispose(Disposer disposer); + void clear_and_dispose(Disposer disposer) BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::treap::count(const key_type &)const size_type count(const key_type &key) const; @@ -938,28 +938,28 @@ class treap_multiset_impl (const KeyType& lower_key, const KeyType& upper_key, KeyTypeKeyCompare comp, bool left_closed, bool right_closed) const; //! @copydoc ::boost::intrusive::treap::s_iterator_to(reference) - static iterator s_iterator_to(reference value); + static iterator s_iterator_to(reference value) BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::treap::s_iterator_to(const_reference) - static const_iterator s_iterator_to(const_reference value); + static const_iterator s_iterator_to(const_reference value) BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::treap::iterator_to(reference) - iterator iterator_to(reference value); + iterator iterator_to(reference value) BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::treap::iterator_to(const_reference)const - const_iterator iterator_to(const_reference value) const; + const_iterator iterator_to(const_reference value) const BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::treap::init_node(reference) - static void init_node(reference value); + static void init_node(reference value) BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::treap::unlink_leftmost_without_rebalance - pointer unlink_leftmost_without_rebalance(); + pointer unlink_leftmost_without_rebalance() BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::treap::replace_node - void replace_node(iterator replace_this, reference with_this); + void replace_node(iterator replace_this, reference with_this) BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::treap::remove_node - void remove_node(reference value); + void remove_node(reference value) BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::treap::merge_unique template @@ -1090,16 +1090,16 @@ class treap_multiset BOOST_INTRUSIVE_FORCEINLINE void clone_from(BOOST_RV_REF(treap_multiset) src, Cloner cloner, Disposer disposer) { Base::clone_from(BOOST_MOVE_BASE(Base, src), cloner, disposer); } - BOOST_INTRUSIVE_FORCEINLINE static treap_multiset &container_from_end_iterator(iterator end_iterator) + BOOST_INTRUSIVE_FORCEINLINE static treap_multiset &container_from_end_iterator(iterator end_iterator) BOOST_NOEXCEPT { return static_cast(Base::container_from_end_iterator(end_iterator)); } - BOOST_INTRUSIVE_FORCEINLINE static const treap_multiset &container_from_end_iterator(const_iterator end_iterator) + BOOST_INTRUSIVE_FORCEINLINE static const treap_multiset &container_from_end_iterator(const_iterator end_iterator) BOOST_NOEXCEPT { return static_cast(Base::container_from_end_iterator(end_iterator)); } - BOOST_INTRUSIVE_FORCEINLINE static treap_multiset &container_from_iterator(iterator it) + BOOST_INTRUSIVE_FORCEINLINE static treap_multiset &container_from_iterator(iterator it) BOOST_NOEXCEPT { return static_cast(Base::container_from_iterator(it)); } - BOOST_INTRUSIVE_FORCEINLINE static const treap_multiset &container_from_iterator(const_iterator it) + BOOST_INTRUSIVE_FORCEINLINE static const treap_multiset &container_from_iterator(const_iterator it) BOOST_NOEXCEPT { return static_cast(Base::container_from_iterator(it)); } }; diff --git a/include/boost/intrusive/trivial_value_traits.hpp b/include/boost/intrusive/trivial_value_traits.hpp index 84fac665d..3968fa636 100644 --- a/include/boost/intrusive/trivial_value_traits.hpp +++ b/include/boost/intrusive/trivial_value_traits.hpp @@ -43,12 +43,14 @@ struct trivial_value_traits typedef node_ptr pointer; typedef const_node_ptr const_pointer; static const link_mode_type link_mode = LinkMode; - BOOST_INTRUSIVE_FORCEINLINE static node_ptr to_node_ptr (value_type &value) + BOOST_INTRUSIVE_FORCEINLINE static node_ptr to_node_ptr (value_type &value) BOOST_NOEXCEPT { return pointer_traits::pointer_to(value); } - BOOST_INTRUSIVE_FORCEINLINE static const_node_ptr to_node_ptr (const value_type &value) + BOOST_INTRUSIVE_FORCEINLINE static const_node_ptr to_node_ptr (const value_type &value) BOOST_NOEXCEPT { return pointer_traits::pointer_to(value); } - BOOST_INTRUSIVE_FORCEINLINE static const pointer & to_value_ptr(const node_ptr &n) { return n; } - BOOST_INTRUSIVE_FORCEINLINE static const const_pointer &to_value_ptr(const const_node_ptr &n) { return n; } + BOOST_INTRUSIVE_FORCEINLINE static pointer to_value_ptr(node_ptr n) BOOST_NOEXCEPT + { return n; } + BOOST_INTRUSIVE_FORCEINLINE static const_pointer to_value_ptr(const_node_ptr n) BOOST_NOEXCEPT + { return n; } }; } //namespace intrusive diff --git a/include/boost/intrusive/unordered_set.hpp b/include/boost/intrusive/unordered_set.hpp index 5588cb160..51023b8b6 100644 --- a/include/boost/intrusive/unordered_set.hpp +++ b/include/boost/intrusive/unordered_set.hpp @@ -67,7 +67,9 @@ template template #endif class unordered_set_impl + #ifndef BOOST_INTRUSIVE_DOXYGEN_INVOKED : public hashtable_impl + #endif { /// @cond private: @@ -115,7 +117,6 @@ class unordered_set_impl typedef typename implementation_defined::node node; typedef typename implementation_defined::node_ptr node_ptr; typedef typename implementation_defined::const_node_ptr const_node_ptr; - typedef typename implementation_defined::node_algorithms node_algorithms; public: @@ -152,22 +153,22 @@ class unordered_set_impl ~unordered_set_impl(); //! @copydoc ::boost::intrusive::hashtable::begin() - iterator begin(); + iterator begin() BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::hashtable::begin()const - const_iterator begin() const; + const_iterator begin() const BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::hashtable::cbegin()const - const_iterator cbegin() const; + const_iterator cbegin() const BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::hashtable::end() - iterator end(); + iterator end() BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::hashtable::end()const - const_iterator end() const; + const_iterator end() const BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::hashtable::cend()const - const_iterator cend() const; + const_iterator cend() const BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::hashtable::hash_function()const hasher hash_function() const; @@ -176,10 +177,10 @@ class unordered_set_impl key_equal key_eq() const; //! @copydoc ::boost::intrusive::hashtable::empty()const - bool empty() const; + bool empty() const BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::hashtable::size()const - size_type size() const; + size_type size() const BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::hashtable::hashtable void swap(unordered_set_impl& other); @@ -215,11 +216,11 @@ class unordered_set_impl //! @copydoc ::boost::intrusive::hashtable::insert_unique_check(const KeyType&,KeyHasher,KeyEqual,insert_commit_data&) template BOOST_INTRUSIVE_FORCEINLINE std::pair insert_check - (const KeyType &key, KeyHasher hasher, KeyEqual key_value_equal, insert_commit_data &commit_data) - { return table_type::insert_unique_check(key, hasher, key_value_equal, commit_data); } + (const KeyType &key, KeyHasher hash_func, KeyEqual key_value_equal, insert_commit_data &commit_data) + { return table_type::insert_unique_check(key, hash_func, key_value_equal, commit_data); } //! @copydoc ::boost::intrusive::hashtable::insert_unique_commit - BOOST_INTRUSIVE_FORCEINLINE iterator insert_commit(reference value, const insert_commit_data &commit_data) + BOOST_INTRUSIVE_FORCEINLINE iterator insert_commit(reference value, const insert_commit_data &commit_data) BOOST_NOEXCEPT { return table_type::insert_unique_commit(value, commit_data); } #ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED @@ -228,7 +229,7 @@ class unordered_set_impl void erase(const_iterator i); //! @copydoc ::boost::intrusive::hashtable::erase(const_iterator,const_iterator) - void erase(const_iterator b, const_iterator e); + void erase(const_iterator b, const_iterator e) BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::hashtable::erase(const key_type &) size_type erase(const key_type &key); @@ -241,11 +242,11 @@ class unordered_set_impl template BOOST_INTRUSIVE_DOC1ST(void , typename detail::disable_if_convertible::type) - erase_and_dispose(const_iterator i, Disposer disposer); + erase_and_dispose(const_iterator i, Disposer disposer) BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::hashtable::erase_and_dispose(const_iterator,const_iterator,Disposer) template - void erase_and_dispose(const_iterator b, const_iterator e, Disposer disposer); + void erase_and_dispose(const_iterator b, const_iterator e, Disposer disposer) BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::hashtable::erase_and_dispose(const key_type &,Disposer) template @@ -256,11 +257,11 @@ class unordered_set_impl size_type erase_and_dispose(const KeyType& key, KeyHasher hash_func, KeyEqual equal_func, Disposer disposer); //! @copydoc ::boost::intrusive::hashtable::clear - void clear(); + void clear() BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::hashtable::clear_and_dispose template - void clear_and_dispose(Disposer disposer); + void clear_and_dispose(Disposer disposer) BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::hashtable::count(const key_type &)const size_type count(const key_type &key) const; @@ -306,28 +307,28 @@ class unordered_set_impl #if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED) //! @copydoc ::boost::intrusive::hashtable::iterator_to(reference) - iterator iterator_to(reference value); + iterator iterator_to(reference value) BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::hashtable::iterator_to(const_reference)const - const_iterator iterator_to(const_reference value) const; + const_iterator iterator_to(const_reference value) const BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::hashtable::s_local_iterator_to(reference) - static local_iterator s_local_iterator_to(reference value); + static local_iterator s_local_iterator_to(reference value) BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::hashtable::s_local_iterator_to(const_reference) - static const_local_iterator s_local_iterator_to(const_reference value); + static const_local_iterator s_local_iterator_to(const_reference value) BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::hashtable::local_iterator_to(reference) - local_iterator local_iterator_to(reference value); + local_iterator local_iterator_to(reference value) BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::hashtable::local_iterator_to(const_reference) - const_local_iterator local_iterator_to(const_reference value) const; + const_local_iterator local_iterator_to(const_reference value) const BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::hashtable::bucket_count - size_type bucket_count() const; + size_type bucket_count() const BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::hashtable::bucket_size - size_type bucket_size(size_type n) const; + size_type bucket_size(size_type n) const BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::hashtable::bucket(const key_type&)const size_type bucket(const key_type& k) const; @@ -337,25 +338,25 @@ class unordered_set_impl size_type bucket(const KeyType& k, KeyHasher hash_func) const; //! @copydoc ::boost::intrusive::hashtable::bucket_pointer - bucket_ptr bucket_pointer() const; + bucket_ptr bucket_pointer() const BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::hashtable::begin(size_type) - local_iterator begin(size_type n); + local_iterator begin(size_type n) BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::hashtable::begin(size_type)const - const_local_iterator begin(size_type n) const; + const_local_iterator begin(size_type n) const BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::hashtable::cbegin(size_type)const - const_local_iterator cbegin(size_type n) const; + const_local_iterator cbegin(size_type n) const BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::hashtable::end(size_type) - local_iterator end(size_type n); + local_iterator end(size_type n) BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::hashtable::end(size_type)const - const_local_iterator end(size_type n) const; + const_local_iterator end(size_type n) const BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::hashtable::cend(size_type)const - const_local_iterator cend(size_type n) const; + const_local_iterator cend(size_type n) const BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::hashtable::rehash(const bucket_traits &) void rehash(const bucket_traits &new_bucket_traits); @@ -370,13 +371,13 @@ class unordered_set_impl bool incremental_rehash(const bucket_traits &new_bucket_traits); //! @copydoc ::boost::intrusive::hashtable::split_count - size_type split_count() const; + size_type split_count() const BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::hashtable::suggested_upper_bucket_count - static size_type suggested_upper_bucket_count(size_type n); + static size_type suggested_upper_bucket_count(size_type n) BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::hashtable::suggested_lower_bucket_count - static size_type suggested_lower_bucket_count(size_type n); + static size_type suggested_lower_bucket_count(size_type n) BOOST_NOEXCEPT; #endif // #ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED @@ -420,6 +421,7 @@ template #endif struct make_unordered_set @@ -428,7 +430,7 @@ struct make_unordered_set typedef typename pack_options < hashtable_defaults, #if !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES) - O1, O2, O3, O4, O5, O6, O7, O8, O9, O10 + O1, O2, O3, O4, O5, O6, O7, O8, O9, O10, O11 #else Options... #endif @@ -438,7 +440,7 @@ struct make_unordered_set ::type value_traits; typedef typename make_bucket_traits - ::type bucket_traits; + ::type bucket_traits; typedef unordered_set_impl < value_traits @@ -453,6 +455,8 @@ struct make_unordered_set | (std::size_t(packed_options::cache_begin)*hash_bool_flags::cache_begin_pos) | (std::size_t(packed_options::compare_hash)*hash_bool_flags::compare_hash_pos) | (std::size_t(packed_options::incremental)*hash_bool_flags::incremental_pos) + | (std::size_t(packed_options::linear_buckets)*hash_bool_flags::linear_buckets_pos) + | (std::size_t(packed_options::fastmod_buckets)*hash_bool_flags::fastmod_buckets_pos) > implementation_defined; /// @endcond @@ -462,27 +466,26 @@ struct make_unordered_set #ifndef BOOST_INTRUSIVE_DOXYGEN_INVOKED #if !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES) -template +template #else template #endif class unordered_set : public make_unordered_set::type { - typedef typename make_unordered_set - ::type Base; + >::type Base; //Assert if passed value traits are compatible with the type BOOST_STATIC_ASSERT((detail::is_same::value)); @@ -526,11 +529,11 @@ class unordered_set template BOOST_INTRUSIVE_FORCEINLINE void clone_from(const unordered_set &src, Cloner cloner, Disposer disposer) - { Base::clone_from(src, cloner, disposer); } + { this->Base::clone_from(src, cloner, disposer); } template BOOST_INTRUSIVE_FORCEINLINE void clone_from(BOOST_RV_REF(unordered_set) src, Cloner cloner, Disposer disposer) - { Base::clone_from(BOOST_MOVE_BASE(Base, src), cloner, disposer); } + { this->Base::clone_from(BOOST_MOVE_BASE(Base, src), cloner, disposer); } }; #endif @@ -577,7 +580,9 @@ template template #endif class unordered_multiset_impl + #ifndef BOOST_INTRUSIVE_DOXYGEN_INVOKED : public hashtable_impl + #endif { /// @cond private: @@ -613,7 +618,6 @@ class unordered_multiset_impl typedef typename implementation_defined::node node; typedef typename implementation_defined::node_ptr node_ptr; typedef typename implementation_defined::const_node_ptr const_node_ptr; - typedef typename implementation_defined::node_algorithms node_algorithms; public: @@ -653,22 +657,22 @@ class unordered_multiset_impl ~unordered_multiset_impl(); //! @copydoc ::boost::intrusive::hashtable::begin() - iterator begin(); + iterator begin() BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::hashtable::begin()const - const_iterator begin() const; + const_iterator begin() const BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::hashtable::cbegin()const - const_iterator cbegin() const; + const_iterator cbegin() const BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::hashtable::end() - iterator end(); + iterator end() BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::hashtable::end()const - const_iterator end() const; + const_iterator end() const BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::hashtable::cend()const - const_iterator cend() const; + const_iterator cend() const BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::hashtable::hash_function()const hasher hash_function() const; @@ -677,10 +681,10 @@ class unordered_multiset_impl key_equal key_eq() const; //! @copydoc ::boost::intrusive::hashtable::empty()const - bool empty() const; + bool empty() const BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::hashtable::size()const - size_type size() const; + size_type size() const BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::hashtable::hashtable void swap(unordered_multiset_impl& other); @@ -715,7 +719,7 @@ class unordered_multiset_impl void erase(const_iterator i); //! @copydoc ::boost::intrusive::hashtable::erase(const_iterator,const_iterator) - void erase(const_iterator b, const_iterator e); + void erase(const_iterator b, const_iterator e) BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::hashtable::erase(const key_type &) size_type erase(const key_type &key); @@ -728,11 +732,11 @@ class unordered_multiset_impl template BOOST_INTRUSIVE_DOC1ST(void , typename detail::disable_if_convertible::type) - erase_and_dispose(const_iterator i, Disposer disposer); + erase_and_dispose(const_iterator i, Disposer disposer) BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::hashtable::erase_and_dispose(const_iterator,const_iterator,Disposer) template - void erase_and_dispose(const_iterator b, const_iterator e, Disposer disposer); + void erase_and_dispose(const_iterator b, const_iterator e, Disposer disposer) BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::hashtable::erase_and_dispose(const key_type &,Disposer) template @@ -743,11 +747,11 @@ class unordered_multiset_impl size_type erase_and_dispose(const KeyType& key, KeyHasher hash_func, KeyEqual equal_func, Disposer disposer); //! @copydoc ::boost::intrusive::hashtable::clear - void clear(); + void clear() BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::hashtable::clear_and_dispose template - void clear_and_dispose(Disposer disposer); + void clear_and_dispose(Disposer disposer) BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::hashtable::count(const key_type &)const size_type count(const key_type &key) const; @@ -787,28 +791,28 @@ class unordered_multiset_impl equal_range(const KeyType& key, KeyHasher hash_func, KeyEqual equal_func) const; //! @copydoc ::boost::intrusive::hashtable::iterator_to(reference) - iterator iterator_to(reference value); + iterator iterator_to(reference value) BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::hashtable::iterator_to(const_reference)const - const_iterator iterator_to(const_reference value) const; + const_iterator iterator_to(const_reference value) const BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::hashtable::s_local_iterator_to(reference) - static local_iterator s_local_iterator_to(reference value); + static local_iterator s_local_iterator_to(reference value) BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::hashtable::s_local_iterator_to(const_reference) - static const_local_iterator s_local_iterator_to(const_reference value); + static const_local_iterator s_local_iterator_to(const_reference value) BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::hashtable::local_iterator_to(reference) - local_iterator local_iterator_to(reference value); + local_iterator local_iterator_to(reference value) BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::hashtable::local_iterator_to(const_reference) - const_local_iterator local_iterator_to(const_reference value) const; + const_local_iterator local_iterator_to(const_reference value) const BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::hashtable::bucket_count - size_type bucket_count() const; + size_type bucket_count() const BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::hashtable::bucket_size - size_type bucket_size(size_type n) const; + size_type bucket_size(size_type n) const BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::hashtable::bucket(const key_type&)const size_type bucket(const key_type& k) const; @@ -818,25 +822,25 @@ class unordered_multiset_impl size_type bucket(const KeyType& k, KeyHasher hash_func) const; //! @copydoc ::boost::intrusive::hashtable::bucket_pointer - bucket_ptr bucket_pointer() const; + bucket_ptr bucket_pointer() const BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::hashtable::begin(size_type) - local_iterator begin(size_type n); + local_iterator begin(size_type n) BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::hashtable::begin(size_type)const - const_local_iterator begin(size_type n) const; + const_local_iterator begin(size_type n) const BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::hashtable::cbegin(size_type)const - const_local_iterator cbegin(size_type n) const; + const_local_iterator cbegin(size_type n) const BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::hashtable::end(size_type) - local_iterator end(size_type n); + local_iterator end(size_type n) BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::hashtable::end(size_type)const - const_local_iterator end(size_type n) const; + const_local_iterator end(size_type n) const BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::hashtable::cend(size_type)const - const_local_iterator cend(size_type n) const; + const_local_iterator cend(size_type n) const BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::hashtable::rehash(const bucket_traits &) void rehash(const bucket_traits &new_bucket_traits); @@ -851,13 +855,13 @@ class unordered_multiset_impl bool incremental_rehash(const bucket_traits &new_bucket_traits); //! @copydoc ::boost::intrusive::hashtable::split_count - size_type split_count() const; + size_type split_count() const BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::hashtable::suggested_upper_bucket_count - static size_type suggested_upper_bucket_count(size_type n); + static size_type suggested_upper_bucket_count(size_type n) BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::hashtable::suggested_lower_bucket_count - static size_type suggested_lower_bucket_count(size_type n); + static size_type suggested_lower_bucket_count(size_type n) BOOST_NOEXCEPT; #endif // #ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED }; @@ -872,6 +876,7 @@ template #endif struct make_unordered_multiset @@ -880,7 +885,7 @@ struct make_unordered_multiset typedef typename pack_options < hashtable_defaults, #if !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES) - O1, O2, O3, O4, O5, O6, O7, O8, O9, O10 + O1, O2, O3, O4, O5, O6, O7, O8, O9, O10, O11 #else Options... #endif @@ -890,7 +895,7 @@ struct make_unordered_multiset ::type value_traits; typedef typename make_bucket_traits - ::type bucket_traits; + ::type bucket_traits; typedef unordered_multiset_impl < value_traits @@ -905,6 +910,8 @@ struct make_unordered_multiset | (std::size_t(packed_options::cache_begin)*hash_bool_flags::cache_begin_pos) | (std::size_t(packed_options::compare_hash)*hash_bool_flags::compare_hash_pos) | (std::size_t(packed_options::incremental)*hash_bool_flags::incremental_pos) + | (std::size_t(packed_options::linear_buckets)*hash_bool_flags::linear_buckets_pos) + | (std::size_t(packed_options::fastmod_buckets)*hash_bool_flags::fastmod_buckets_pos) > implementation_defined; /// @endcond @@ -914,14 +921,14 @@ struct make_unordered_multiset #ifndef BOOST_INTRUSIVE_DOXYGEN_INVOKED #if !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES) -template +template #else template #endif class unordered_multiset : public make_unordered_multiset BOOST_INTRUSIVE_FORCEINLINE void clone_from(const unordered_multiset &src, Cloner cloner, Disposer disposer) - { Base::clone_from(src, cloner, disposer); } + { this->Base::clone_from(src, cloner, disposer); } template BOOST_INTRUSIVE_FORCEINLINE void clone_from(BOOST_RV_REF(unordered_multiset) src, Cloner cloner, Disposer disposer) - { Base::clone_from(BOOST_MOVE_BASE(Base, src), cloner, disposer); } + { this->Base::clone_from(BOOST_MOVE_BASE(Base, src), cloner, disposer); } }; #endif diff --git a/include/boost/intrusive/unordered_set_hook.hpp b/include/boost/intrusive/unordered_set_hook.hpp index 54a04d373..cfa4f2594 100644 --- a/include/boost/intrusive/unordered_set_hook.hpp +++ b/include/boost/intrusive/unordered_set_hook.hpp @@ -82,22 +82,22 @@ struct unordered_node_traits static const bool store_hash = StoreHash; static const bool optimize_multikey = OptimizeMultiKey; - BOOST_INTRUSIVE_FORCEINLINE static node_ptr get_next(const const_node_ptr & n) + BOOST_INTRUSIVE_FORCEINLINE static node_ptr get_next(const_node_ptr n) BOOST_NOEXCEPT { return pointer_traits::static_cast_from(n->next_); } - BOOST_INTRUSIVE_FORCEINLINE static void set_next(node_ptr n, node_ptr next) + BOOST_INTRUSIVE_FORCEINLINE static void set_next(node_ptr n, node_ptr next) BOOST_NOEXCEPT { n->next_ = next; } - BOOST_INTRUSIVE_FORCEINLINE static node_ptr get_prev_in_group(const const_node_ptr & n) + BOOST_INTRUSIVE_FORCEINLINE static node_ptr get_prev_in_group(const_node_ptr n) BOOST_NOEXCEPT { return n->prev_in_group_; } - BOOST_INTRUSIVE_FORCEINLINE static void set_prev_in_group(node_ptr n, node_ptr prev) + BOOST_INTRUSIVE_FORCEINLINE static void set_prev_in_group(node_ptr n, node_ptr prev) BOOST_NOEXCEPT { n->prev_in_group_ = prev; } - BOOST_INTRUSIVE_FORCEINLINE static std::size_t get_hash(const const_node_ptr & n) + BOOST_INTRUSIVE_FORCEINLINE static std::size_t get_hash(const_node_ptr n) BOOST_NOEXCEPT { return n->hash_; } - BOOST_INTRUSIVE_FORCEINLINE static void set_hash(const node_ptr & n, std::size_t h) + BOOST_INTRUSIVE_FORCEINLINE static void set_hash(node_ptr n, std::size_t h) BOOST_NOEXCEPT { n->hash_ = h; } }; @@ -108,10 +108,10 @@ struct unordered_group_adapter typedef typename NodeTraits::node_ptr node_ptr; typedef typename NodeTraits::const_node_ptr const_node_ptr; - static node_ptr get_next(const const_node_ptr & n) + BOOST_INTRUSIVE_FORCEINLINE static node_ptr get_next(const_node_ptr n) { return NodeTraits::get_prev_in_group(n); } - static void set_next(node_ptr n, node_ptr next) + BOOST_INTRUSIVE_FORCEINLINE static void set_next(node_ptr n, node_ptr next) { NodeTraits::set_prev_in_group(n, next); } }; @@ -127,19 +127,19 @@ struct unordered_algorithms typedef typename NodeTraits::node_ptr node_ptr; typedef typename NodeTraits::const_node_ptr const_node_ptr; - BOOST_INTRUSIVE_FORCEINLINE static void init(typename base_type::node_ptr n) + BOOST_INTRUSIVE_FORCEINLINE static void init(typename base_type::node_ptr n) BOOST_NOEXCEPT { base_type::init(n); group_algorithms::init(n); } - BOOST_INTRUSIVE_FORCEINLINE static void init_header(typename base_type::node_ptr n) + BOOST_INTRUSIVE_FORCEINLINE static void init_header(typename base_type::node_ptr n) BOOST_NOEXCEPT { base_type::init_header(n); group_algorithms::init_header(n); } - BOOST_INTRUSIVE_FORCEINLINE static void unlink(typename base_type::node_ptr n) + BOOST_INTRUSIVE_FORCEINLINE static void unlink(typename base_type::node_ptr n) BOOST_NOEXCEPT { base_type::unlink(n); group_algorithms::unlink(n); @@ -258,7 +258,7 @@ class unordered_set_base_hook //! initializes the node to an unlinked state. //! //! Throws: Nothing. - unordered_set_base_hook(); + unordered_set_base_hook() BOOST_NOEXCEPT; //! Effects: If link_mode is \c auto_unlink or \c safe_link //! initializes the node to an unlinked state. The argument is ignored. @@ -269,7 +269,7 @@ class unordered_set_base_hook //! makes classes using the hook STL-compliant without forcing the //! user to do some additional work. \c swap can be used to emulate //! move-semantics. - unordered_set_base_hook(const unordered_set_base_hook& ); + unordered_set_base_hook(const unordered_set_base_hook& ) BOOST_NOEXCEPT; //! Effects: Empty function. The argument is ignored. //! @@ -279,7 +279,7 @@ class unordered_set_base_hook //! makes classes using the hook STL-compliant without forcing the //! user to do some additional work. \c swap can be used to emulate //! move-semantics. - unordered_set_base_hook& operator=(const unordered_set_base_hook& ); + unordered_set_base_hook& operator=(const unordered_set_base_hook& ) BOOST_NOEXCEPT; //! Effects: If link_mode is \c normal_link, the destructor does //! nothing (ie. no code is generated). If link_mode is \c safe_link and the @@ -301,7 +301,7 @@ class unordered_set_base_hook //! Complexity: Constant //! //! Throws: Nothing. - void swap_nodes(unordered_set_base_hook &other); + void swap_nodes(unordered_set_base_hook &other) BOOST_NOEXCEPT; //! Precondition: link_mode must be \c safe_link or \c auto_unlink. //! @@ -310,13 +310,13 @@ class unordered_set_base_hook //! will return a valid iterator. //! //! Complexity: Constant - bool is_linked() const; + bool is_linked() const BOOST_NOEXCEPT; //! Effects: Removes the node if it's inserted in a container. //! This function is only allowed if link_mode is \c auto_unlink. //! //! Throws: Nothing. - void unlink(); + void unlink() BOOST_NOEXCEPT; #endif }; diff --git a/include/boost/limits.hpp b/include/boost/limits.hpp index 47d815561..1b54477ec 100644 --- a/include/boost/limits.hpp +++ b/include/boost/limits.hpp @@ -59,8 +59,8 @@ namespace std BOOST_STATIC_CONSTANT(bool, is_integer = true); BOOST_STATIC_CONSTANT(bool, is_exact = true); BOOST_STATIC_CONSTANT(int, radix = 2); - static BOOST_LLT epsilon() throw() { return 0; }; - static BOOST_LLT round_error() throw() { return 0; }; + static BOOST_LLT epsilon() BOOST_NOEXCEPT_OR_NOTHROW { return 0; }; + static BOOST_LLT round_error() BOOST_NOEXCEPT_OR_NOTHROW { return 0; }; BOOST_STATIC_CONSTANT(int, min_exponent = 0); BOOST_STATIC_CONSTANT(int, min_exponent10 = 0); @@ -72,10 +72,10 @@ namespace std BOOST_STATIC_CONSTANT(bool, has_signaling_NaN = false); BOOST_STATIC_CONSTANT(bool, has_denorm = false); BOOST_STATIC_CONSTANT(bool, has_denorm_loss = false); - static BOOST_LLT infinity() throw() { return 0; }; - static BOOST_LLT quiet_NaN() throw() { return 0; }; - static BOOST_LLT signaling_NaN() throw() { return 0; }; - static BOOST_LLT denorm_min() throw() { return 0; }; + static BOOST_LLT infinity() BOOST_NOEXCEPT_OR_NOTHROW { return 0; }; + static BOOST_LLT quiet_NaN() BOOST_NOEXCEPT_OR_NOTHROW { return 0; }; + static BOOST_LLT signaling_NaN() BOOST_NOEXCEPT_OR_NOTHROW { return 0; }; + static BOOST_LLT denorm_min() BOOST_NOEXCEPT_OR_NOTHROW { return 0; }; BOOST_STATIC_CONSTANT(bool, is_iec559 = false); BOOST_STATIC_CONSTANT(bool, is_bounded = true); @@ -112,8 +112,8 @@ namespace std BOOST_STATIC_CONSTANT(bool, is_integer = true); BOOST_STATIC_CONSTANT(bool, is_exact = true); BOOST_STATIC_CONSTANT(int, radix = 2); - static BOOST_ULLT epsilon() throw() { return 0; }; - static BOOST_ULLT round_error() throw() { return 0; }; + static BOOST_ULLT epsilon() BOOST_NOEXCEPT_OR_NOTHROW { return 0; }; + static BOOST_ULLT round_error() BOOST_NOEXCEPT_OR_NOTHROW { return 0; }; BOOST_STATIC_CONSTANT(int, min_exponent = 0); BOOST_STATIC_CONSTANT(int, min_exponent10 = 0); @@ -125,10 +125,10 @@ namespace std BOOST_STATIC_CONSTANT(bool, has_signaling_NaN = false); BOOST_STATIC_CONSTANT(bool, has_denorm = false); BOOST_STATIC_CONSTANT(bool, has_denorm_loss = false); - static BOOST_ULLT infinity() throw() { return 0; }; - static BOOST_ULLT quiet_NaN() throw() { return 0; }; - static BOOST_ULLT signaling_NaN() throw() { return 0; }; - static BOOST_ULLT denorm_min() throw() { return 0; }; + static BOOST_ULLT infinity() BOOST_NOEXCEPT_OR_NOTHROW { return 0; }; + static BOOST_ULLT quiet_NaN() BOOST_NOEXCEPT_OR_NOTHROW { return 0; }; + static BOOST_ULLT signaling_NaN() BOOST_NOEXCEPT_OR_NOTHROW { return 0; }; + static BOOST_ULLT denorm_min() BOOST_NOEXCEPT_OR_NOTHROW { return 0; }; BOOST_STATIC_CONSTANT(bool, is_iec559 = false); BOOST_STATIC_CONSTANT(bool, is_bounded = true); diff --git a/include/boost/move/algo/move.hpp b/include/boost/move/algo/move.hpp index 5d5ba19ea..9a3eaccaf 100644 --- a/include/boost/move/algo/move.hpp +++ b/include/boost/move/algo/move.hpp @@ -27,7 +27,10 @@ #include #include #include -#include +#include +#if defined(BOOST_MOVE_USE_STANDARD_LIBRARY_MOVE) +#include +#endif namespace boost { @@ -118,20 +121,20 @@ F uninitialized_move(I f, I l, F r typedef typename boost::movelib::iterator_traits::value_type input_value_type; F back = r; - BOOST_TRY{ + BOOST_MOVE_TRY{ while (f != l) { void * const addr = static_cast(::boost::move_detail::addressof(*r)); ::new(addr) input_value_type(::boost::move(*f)); ++f; ++r; } } - BOOST_CATCH(...){ + BOOST_MOVE_CATCH(...){ for (; back != r; ++back){ boost::movelib::iterator_to_raw_pointer(back)->~input_value_type(); } - BOOST_RETHROW; + BOOST_MOVE_RETHROW; } - BOOST_CATCH_END + BOOST_MOVE_CATCH_END return r; } diff --git a/include/boost/move/algorithm.hpp b/include/boost/move/algorithm.hpp index 880d661e7..67a69064d 100644 --- a/include/boost/move/algorithm.hpp +++ b/include/boost/move/algorithm.hpp @@ -27,7 +27,6 @@ #include #include #include -#include #include //copy, copy_backward #include //uninitialized_copy diff --git a/include/boost/move/core.hpp b/include/boost/move/core.hpp index b34740dcf..7b604e678 100644 --- a/include/boost/move/core.hpp +++ b/include/boost/move/core.hpp @@ -58,6 +58,7 @@ #include #define BOOST_MOVE_TO_RV_CAST(RV_TYPE, ARG) reinterpret_cast(ARG) + #define BOOST_MOVE_TO_LV_CAST(LV_TYPE, ARG) static_cast(ARG) //Move emulation rv breaks standard aliasing rules so add workarounds for some compilers #if defined(BOOST_GCC) && (BOOST_GCC >= 40400) && (BOOST_GCC < 40500) @@ -218,6 +219,10 @@ return x; } + template + BOOST_MOVE_FORCEINLINE T& unrv(::boost::rv &rv) BOOST_NOEXCEPT + { return BOOST_MOVE_TO_LV_CAST(T&, rv); } + } //namespace move_detail { } //namespace boost { @@ -229,6 +234,11 @@ ::boost::move((BASE_TYPE&)(ARG)) // + #define BOOST_MOVE_TO_LV(ARG) \ + ::boost::move_detail::unrv(ARG) + // + + ////////////////////////////////////////////////////////////////////////////// // // BOOST_MOVABLE_BUT_NOT_COPYABLE @@ -480,6 +490,17 @@ ::boost::move((BASE_TYPE&)(ARG)) // + //!This macro is used to achieve portable optimal move constructors. + //! + //!In C++03 mode, when accessing a member of type through a rvalue (implemented as a `rv &` type, where rv derives + //!from T) triggers a potential UB as the program never creates objects of type rv. This macro casts back `rv` to + //!`T&` so that access to member types are done through the original type. + //! + //!In C++11 compilers the cast from a rvalue reference of a derived type to a rvalue reference of + //!a base type is implicit, so it's a no-op. + #define BOOST_MOVE_TO_LV(ARG) ARG + // + namespace boost { namespace move_detail { diff --git a/include/boost/move/detail/addressof.hpp b/include/boost/move/detail/addressof.hpp new file mode 100644 index 000000000..8679fa943 --- /dev/null +++ b/include/boost/move/detail/addressof.hpp @@ -0,0 +1,61 @@ +////////////////////////////////////////////////////////////////////////////// +// +// (C) Copyright Ion Gaztanaga 2014-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) +// +// See http://www.boost.org/libs/container for documentation. +// +////////////////////////////////////////////////////////////////////////////// +#ifndef BOOST_MOVE_DETAIL_ADDRESSOF_HPP +#define BOOST_MOVE_DETAIL_ADDRESSOF_HPP + +#ifndef BOOST_CONFIG_HPP +# include +#endif + +#if defined(BOOST_HAS_PRAGMA_ONCE) +# pragma once +#endif + +#include + +namespace boost { +namespace move_detail { + +#if defined(BOOST_MSVC_FULL_VER) && BOOST_MSVC_FULL_VER >= 190024215 +#define BOOST_MOVE_HAS_BUILTIN_ADDRESSOF +#elif defined(BOOST_GCC) && BOOST_GCC >= 70000 +#define BOOST_MOVE_HAS_BUILTIN_ADDRESSOF +#elif defined(__has_builtin) +#if __has_builtin(__builtin_addressof) +#define BOOST_MOVE_HAS_BUILTIN_ADDRESSOF +#endif +#endif + +#ifdef BOOST_MOVE_HAS_BUILTIN_ADDRESSOF + +template +BOOST_MOVE_FORCEINLINE T *addressof( T & v ) BOOST_NOEXCEPT +{ + return __builtin_addressof(v); +} + +#else //BOOST_MOVE_HAS_BUILTIN_ADDRESSOF + +template +BOOST_MOVE_FORCEINLINE T* addressof(T& obj) +{ + return static_cast( + static_cast( + const_cast( + &reinterpret_cast(obj) + ))); +} + +#endif //BOOST_MOVE_HAS_BUILTIN_ADDRESSOF + +} //namespace move_detail { +} //namespace boost { + +#endif //#ifndef BOOST_MOVE_DETAIL_ADDRESSOF_HPP diff --git a/include/boost/move/detail/config_begin.hpp b/include/boost/move/detail/config_begin.hpp index 637eb158b..4e95a4aba 100644 --- a/include/boost/move/detail/config_begin.hpp +++ b/include/boost/move/detail/config_begin.hpp @@ -13,6 +13,7 @@ #ifdef BOOST_MSVC # pragma warning (push) +# pragma warning (disable : 4619) // there is no warning number 'XXXX' # pragma warning (disable : 4324) // structure was padded due to __declspec(align()) # pragma warning (disable : 4675) // "function": resolved overload was found by argument-dependent lookup # pragma warning (disable : 4996) // "function": was declared deprecated (_CRT_SECURE_NO_DEPRECATE/_SCL_SECURE_NO_WARNINGS) diff --git a/include/boost/move/detail/force_ptr.hpp b/include/boost/move/detail/force_ptr.hpp new file mode 100644 index 000000000..3abed2d8c --- /dev/null +++ b/include/boost/move/detail/force_ptr.hpp @@ -0,0 +1,36 @@ +////////////////////////////////////////////////////////////////////////////// +// +// (C) Copyright Ion Gaztanaga 2014-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) +// +// See http://www.boost.org/libs/container for documentation. +// +////////////////////////////////////////////////////////////////////////////// +#ifndef BOOST_MOVE_DETAIL_FORCE_CAST_HPP +#define BOOST_MOVE_DETAIL_FORCE_CAST_HPP + +#ifndef BOOST_CONFIG_HPP +# include +#endif + +#if defined(BOOST_HAS_PRAGMA_ONCE) +# pragma once +#endif + +#include + +namespace boost { +namespace move_detail { + + +template +BOOST_MOVE_FORCEINLINE T force_ptr(const volatile void *p) +{ + return static_cast(const_cast(p)); +} + +} //namespace move_detail { +} //namespace boost { + +#endif //#ifndef BOOST_MOVE_DETAIL_FORCE_CAST_HPP diff --git a/include/boost/move/detail/iterator_traits.hpp b/include/boost/move/detail/iterator_traits.hpp index 5ffcb2cf0..9ea01c25e 100644 --- a/include/boost/move/detail/iterator_traits.hpp +++ b/include/boost/move/detail/iterator_traits.hpp @@ -22,10 +22,44 @@ # pragma once #endif +#if (BOOST_CXX_VERSION > 201703L) && defined(__cpp_lib_concepts) + +#include + +#define BOOST_MOVE_CONTIGUOUS_ITERATOR_TAG + +namespace boost { +namespace movelib { + + using std::iterator_traits; + + template + struct iter_difference + { + typedef typename std::iterator_traits::difference_type type; + }; + + template + struct iter_value + { + typedef typename std::iterator_traits::value_type type; + }; + + template + struct iter_category + { + typedef typename std::iterator_traits::iterator_category type; + }; + +}} //namespace boost::movelib + +#else + #include #include #include + BOOST_MOVE_STD_NS_BEG struct input_iterator_tag; @@ -34,20 +68,73 @@ struct bidirectional_iterator_tag; struct random_access_iterator_tag; struct output_iterator_tag; +#if ( (defined(BOOST_GNU_STDLIB) && (__cplusplus > 201703L))\ + || (defined(_LIBCPP_VERSION) && (_LIBCPP_STD_VER > 17))\ + || (defined(_YVALS) && defined(_CPPLIB_VER) && defined(__cpp_lib_concepts))\ + || (__cplusplus >= 202002L)\ + ) +# define BOOST_MOVE_CONTIGUOUS_ITERATOR_TAG +struct contiguous_iterator_tag; + +#endif + BOOST_MOVE_STD_NS_END + #include namespace boost{ namespace movelib{ +template +struct iter_difference +{ + typedef typename T::difference_type type; +}; + +template +struct iter_difference +{ + typedef std::ptrdiff_t type; +}; + +template +struct iter_value +{ + typedef typename T::value_type type; +}; + +template +struct iter_value +{ + typedef T type; +}; + +template +struct iter_value +{ + typedef T type; +}; + +template +struct iter_category +{ + typedef typename T::iterator_category type; +}; + + +template +struct iter_category +{ + typedef std::random_access_iterator_tag type; +}; + template struct iterator_traits { - typedef typename Iterator::difference_type difference_type; - typedef typename Iterator::value_type value_type; - typedef typename Iterator::pointer pointer; - typedef typename Iterator::reference reference; - typedef typename Iterator::iterator_category iterator_category; - typedef typename boost::move_detail::make_unsigned::type size_type; + typedef typename iter_difference::type difference_type; + typedef typename iter_value::type value_type; + typedef typename Iterator::pointer pointer; + typedef typename Iterator::reference reference; + typedef typename iter_category::type iterator_category; }; template @@ -58,7 +145,6 @@ struct iterator_traits typedef T* pointer; typedef T& reference; typedef std::random_access_iterator_tag iterator_category; - typedef typename boost::move_detail::make_unsigned::type size_type; }; template @@ -69,9 +155,23 @@ struct iterator_traits typedef const T* pointer; typedef const T& reference; typedef std::random_access_iterator_tag iterator_category; - typedef typename boost::move_detail::make_unsigned::type size_type; }; -}} //namespace boost { namespace movelib{ +}} //namespace boost::movelib + +#endif // + +#include + +namespace boost { +namespace movelib { + +template +struct iter_size + : boost::move_detail:: + make_unsigned::type > +{}; + +}} //namespace boost move_detail { #endif //#ifndef BOOST_MOVE_DETAIL_ITERATOR_TRAITS_HPP diff --git a/include/boost/move/detail/meta_utils.hpp b/include/boost/move/detail/meta_utils.hpp index f16e185d6..7c90de287 100644 --- a/include/boost/move/detail/meta_utils.hpp +++ b/include/boost/move/detail/meta_utils.hpp @@ -21,6 +21,7 @@ #include //forceinline #include #include //for std::size_t +#include //Small meta-typetraits to support move @@ -56,8 +57,8 @@ struct apply template< bool C_ > struct bool_ : integral_constant { - operator bool() const { return C_; } - bool operator()() const { return C_; } + BOOST_MOVE_FORCEINLINE operator bool() const { return C_; } + BOOST_MOVE_FORCEINLINE bool operator()() const { return C_; } }; typedef bool_ true_; @@ -70,6 +71,10 @@ struct nat{}; struct nat2{}; struct nat3{}; +template +struct natN +{}; + ////////////////////////////////////// // yes_type/no_type ////////////////////////////////////// @@ -220,7 +225,7 @@ struct identity { typedef T type; typedef typename add_const_lvalue_reference::type reference; - reference operator()(reference t) + BOOST_MOVE_FORCEINLINE reference operator()(reference t) const { return t; } }; @@ -241,36 +246,7 @@ struct is_class_or_union ////////////////////////////////////// // addressof ////////////////////////////////////// -template -struct addr_impl_ref -{ - T & v_; - BOOST_MOVE_FORCEINLINE addr_impl_ref( T & v ): v_( v ) {} - BOOST_MOVE_FORCEINLINE operator T& () const { return v_; } - - private: - addr_impl_ref & operator=(const addr_impl_ref &); -}; -template -struct addressof_impl -{ - BOOST_MOVE_FORCEINLINE static T * f( T & v, long ) - { - return reinterpret_cast( - &const_cast(reinterpret_cast(v))); - } - - BOOST_MOVE_FORCEINLINE static T * f( T * v, int ) - { return v; } -}; - -template -BOOST_MOVE_FORCEINLINE T * addressof( T & v ) -{ - return ::boost::move_detail::addressof_impl::f - ( ::boost::move_detail::addr_impl_ref( v ), 0 ); -} ////////////////////////////////////// // has_pointer_type diff --git a/include/boost/move/detail/reverse_iterator.hpp b/include/boost/move/detail/reverse_iterator.hpp new file mode 100644 index 000000000..7fda6edf0 --- /dev/null +++ b/include/boost/move/detail/reverse_iterator.hpp @@ -0,0 +1,178 @@ +///////////////////////////////////////////////////////////////////////////// +// +// (C) Copyright Ion Gaztanaga 2014-2014 +// +// 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) +// +// See http://www.boost.org/libs/move for documentation. +// +///////////////////////////////////////////////////////////////////////////// + +#ifndef BOOST_MOVE_DETAIL_REVERSE_ITERATOR_HPP +#define BOOST_MOVE_DETAIL_REVERSE_ITERATOR_HPP + +#ifndef BOOST_CONFIG_HPP +# include +#endif + +#if defined(BOOST_HAS_PRAGMA_ONCE) +# pragma once +#endif + +#include +#include +#include + +namespace boost { +namespace movelib { + +template +BOOST_MOVE_FORCEINLINE typename iterator_traits::pointer iterator_arrow_result(const I &i) +{ return i.operator->(); } + +template +BOOST_MOVE_FORCEINLINE T * iterator_arrow_result(T *p) +{ return p; } + +template +class reverse_iterator +{ + public: + typedef typename boost::movelib::iterator_traits::pointer pointer; + typedef typename boost::movelib::iterator_traits::reference reference; + typedef typename boost::movelib::iterator_traits::difference_type difference_type; + typedef typename boost::movelib::iterator_traits::iterator_category iterator_category; + typedef typename boost::movelib::iterator_traits::value_type value_type; + + + typedef It iterator_type; + + BOOST_MOVE_FORCEINLINE reverse_iterator() + : m_current() //Value initialization to achieve "null iterators" (N3644) + {} + + BOOST_MOVE_FORCEINLINE explicit reverse_iterator(It r) + : m_current(r) + {} + + BOOST_MOVE_FORCEINLINE reverse_iterator(const reverse_iterator& r) + : m_current(r.base()) + {} + + template + BOOST_MOVE_FORCEINLINE + reverse_iterator( const reverse_iterator& r + , typename boost::move_detail::enable_if_convertible::type* =0 + ) + : m_current(r.base()) + {} + + BOOST_MOVE_FORCEINLINE reverse_iterator & operator=( const reverse_iterator& r) + { m_current = r.base(); return *this; } + + template + BOOST_MOVE_FORCEINLINE typename boost::move_detail::enable_if_convertible::type + operator=( const reverse_iterator& r) + { m_current = r.base(); return *this; } + + BOOST_MOVE_FORCEINLINE It base() const + { return m_current; } + + BOOST_MOVE_FORCEINLINE reference operator*() const + { + It temp(m_current); + --temp; + reference r = *temp; + return r; + } + + BOOST_MOVE_FORCEINLINE pointer operator->() const + { + It temp(m_current); + --temp; + return (iterator_arrow_result)(temp); + } + + BOOST_MOVE_FORCEINLINE reference operator[](difference_type off) const + { + return this->m_current[difference_type(-off - 1)]; + } + + BOOST_MOVE_FORCEINLINE reverse_iterator& operator++() + { + --m_current; + return *this; + } + + BOOST_MOVE_FORCEINLINE reverse_iterator operator++(int) + { + reverse_iterator temp((*this)); + --m_current; + return temp; + } + + BOOST_MOVE_FORCEINLINE reverse_iterator& operator--() + { + ++m_current; + return *this; + } + + BOOST_MOVE_FORCEINLINE reverse_iterator operator--(int) + { + reverse_iterator temp((*this)); + ++m_current; + return temp; + } + + BOOST_MOVE_FORCEINLINE friend bool operator==(const reverse_iterator& l, const reverse_iterator& r) + { return l.m_current == r.m_current; } + + BOOST_MOVE_FORCEINLINE friend bool operator!=(const reverse_iterator& l, const reverse_iterator& r) + { return l.m_current != r.m_current; } + + BOOST_MOVE_FORCEINLINE friend bool operator<(const reverse_iterator& l, const reverse_iterator& r) + { return l.m_current > r.m_current; } + + BOOST_MOVE_FORCEINLINE friend bool operator<=(const reverse_iterator& l, const reverse_iterator& r) + { return l.m_current >= r.m_current; } + + BOOST_MOVE_FORCEINLINE friend bool operator>(const reverse_iterator& l, const reverse_iterator& r) + { return l.m_current < r.m_current; } + + BOOST_MOVE_FORCEINLINE friend bool operator>=(const reverse_iterator& l, const reverse_iterator& r) + { return l.m_current <= r.m_current; } + + BOOST_MOVE_FORCEINLINE reverse_iterator& operator+=(difference_type off) + { m_current -= off; return *this; } + + BOOST_MOVE_FORCEINLINE reverse_iterator& operator-=(difference_type off) + { m_current += off; return *this; } + + BOOST_MOVE_FORCEINLINE friend reverse_iterator operator+(reverse_iterator l, difference_type off) + { return (l += off); } + + BOOST_MOVE_FORCEINLINE friend reverse_iterator operator+(difference_type off, reverse_iterator r) + { return (r += off); } + + BOOST_MOVE_FORCEINLINE friend reverse_iterator operator-(reverse_iterator l, difference_type off) + { return (l-= off); } + + BOOST_MOVE_FORCEINLINE friend difference_type operator-(const reverse_iterator& l, const reverse_iterator& r) + { return r.m_current - l.m_current; } + + private: + It m_current; // the wrapped iterator +}; + +template< class Iterator > +BOOST_MOVE_FORCEINLINE reverse_iterator make_reverse_iterator( Iterator i ) +{ return reverse_iterator(i); } + +} //namespace movelib { +} //namespace boost { + +#include + +#endif //BOOST_MOVE_DETAIL_REVERSE_ITERATOR_HPP diff --git a/include/boost/move/detail/std_ns_begin.hpp b/include/boost/move/detail/std_ns_begin.hpp index a768e61a1..1d28117b7 100644 --- a/include/boost/move/detail/std_ns_begin.hpp +++ b/include/boost/move/detail/std_ns_begin.hpp @@ -24,7 +24,11 @@ #define BOOST_MOVE_STD_NS_BEG _GLIBCXX_BEGIN_NAMESPACE(std) #define BOOST_MOVE_STD_NS_END _GLIBCXX_END_NAMESPACE #else + #if defined(_MSC_VER) && (_MSC_VER >= 1915) + #pragma warning (push) + #pragma warning (disable : 4643) // Forward declaring 'X' in namespace std is not permitted by the C++ Standard + #endif + #define BOOST_MOVE_STD_NS_BEG namespace std{ #define BOOST_MOVE_STD_NS_END } #endif - diff --git a/include/boost/move/detail/std_ns_end.hpp b/include/boost/move/detail/std_ns_end.hpp index 097505995..61af2d7b1 100644 --- a/include/boost/move/detail/std_ns_end.hpp +++ b/include/boost/move/detail/std_ns_end.hpp @@ -11,4 +11,6 @@ #ifdef BOOST_MOVE_STD_NS_GCC_DIAGNOSTIC_PUSH #pragma GCC diagnostic pop #undef BOOST_MOVE_STD_NS_GCC_DIAGNOSTIC_PUSH +#elif defined(_MSC_VER) && (_MSC_VER >= 1915) + #pragma warning (pop) #endif //BOOST_MOVE_STD_NS_GCC_DIAGNOSTIC_PUSH diff --git a/include/boost/move/detail/type_traits.hpp b/include/boost/move/detail/type_traits.hpp index c8bc74a18..5a093186c 100644 --- a/include/boost/move/detail/type_traits.hpp +++ b/include/boost/move/detail/type_traits.hpp @@ -30,8 +30,7 @@ // move/detail #include // other -#include -#include +#include // std #include @@ -65,7 +64,7 @@ // BOOST_MOVE_HAS_NOTHROW_COPY(T) should evaluate to true if T(t) can not throw // BOOST_MOVE_HAS_NOTHROW_ASSIGN(T) should evaluate to true if t = u can not throw // BOOST_MOVE_IS_ENUM(T) should evaluate to true it t is a union type. -// BOOST_MOVE_HAS_NOTHROW_MOVE_CONSTRUCT(T) should evaluate to true if T has a non-throwing move constructor. +// BOOST_MOVE_HAS_NOTHROW_MOVE_CONSTRUCTOR(T) should evaluate to true if T has a non-throwing move constructor. // BOOST_MOVE_HAS_NOTHROW_MOVE_ASSIGN(T) should evaluate to true if T has a non-throwing move assignment operator. // // The following can also be defined: when detected our implementation is greatly simplified. @@ -106,13 +105,15 @@ # endif # if _MSC_FULL_VER >= 180020827 # define BOOST_MOVE_HAS_NOTHROW_MOVE_ASSIGN(T) (__is_nothrow_assignable(T&, T&&)) -# define BOOST_MOVE_HAS_NOTHROW_MOVE_CONSTRUCT(T) (__is_nothrow_constructible(T, T&&)) +# define BOOST_MOVE_HAS_NOTHROW_MOVE_CONSTRUCTOR(T) (__is_nothrow_constructible(T, T&&)) # endif #endif #if defined(BOOST_CLANG) // BOOST_MOVE_HAS_TRAIT -# ifdef __has_extension +# if defined __is_identifier +# define BOOST_MOVE_HAS_TRAIT(T) (__has_extension(T) || !__is_identifier(__##T)) +# elif defined(__has_extension) # define BOOST_MOVE_HAS_TRAIT(T) __has_extension(T) # else # define BOOST_MOVE_HAS_TRAIT(T) 0 @@ -188,7 +189,9 @@ # endif // BOOST_MOVE_HAS_TRIVIAL_MOVE_CONSTRUCTOR -# if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES) && BOOST_MOVE_HAS_TRAIT(is_constructible) && BOOST_MOVE_HAS_TRAIT(is_trivially_constructible) +# if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES) + +# if BOOST_MOVE_HAS_TRAIT(is_constructible) && BOOST_MOVE_HAS_TRAIT(is_trivially_constructible) # define BOOST_MOVE_HAS_TRIVIAL_MOVE_CONSTRUCTOR(T) (__is_constructible(T, T&&) && __is_trivially_constructible(T, T&&)) # elif BOOST_MOVE_HAS_TRAIT(has_trivial_move_constructor) # define BOOST_MOVE_HAS_TRIVIAL_MOVE_CONSTRUCTOR(T) __has_trivial_move_constructor(T) @@ -200,6 +203,24 @@ # elif BOOST_MOVE_HAS_TRAIT(has_trivial_move_assign) # define BOOST_MOVE_HAS_TRIVIAL_MOVE_ASSIGN(T) __has_trivial_move_assign(T) # endif + +// BOOST_MOVE_HAS_NOTHROW_MOVE_CONSTRUCTOR +# if BOOST_MOVE_HAS_TRAIT(is_constructible) && BOOST_MOVE_HAS_TRAIT(is_nothrow_constructible) +# define BOOST_MOVE_HAS_NOTHROW_MOVE_CONSTRUCTOR(T) (__is_constructible(T, T&&) && __is_nothrow_constructible(T, T&&)) +# elif BOOST_MOVE_HAS_TRAIT(has_nothrow_move_constructor) +# define BOOST_MOVE_HAS_NOTHROW_MOVE_CONSTRUCTOR(T) __has_nothrow_move_constructor(T) +# endif + +// BOOST_MOVE_HAS_NOTHROW_MOVE_ASSIGN +# if BOOST_MOVE_HAS_TRAIT(is_assignable) && BOOST_MOVE_HAS_TRAIT(is_nothrow_assignable) +# define BOOST_MOVE_HAS_NOTHROW_MOVE_ASSIGN(T) (__is_assignable(T, T&&) && __is_nothrow_assignable(T, T&&)) +# elif BOOST_MOVE_HAS_TRAIT(has_nothrow_move_assign) +# define BOOST_MOVE_HAS_NOTHROW_MOVE_ASSIGN(T) __has_nothrow_move_assign(T) +# endif + +# endif //BOOST_NO_CXX11_RVALUE_REFERENCES + +// BOOST_MOVE_ALIGNMENT_OF # define BOOST_MOVE_ALIGNMENT_OF(T) __alignof(T) #endif //#if defined(BOOST_CLANG) @@ -230,7 +251,92 @@ # define BOOST_MOVE_HAS_NOTHROW_COPY(T) ((__has_nothrow_copy(T) BOOST_MOVE_INTEL_TT_OPTS)) # define BOOST_MOVE_HAS_NOTHROW_ASSIGN(T) ((__has_nothrow_assign(T) BOOST_MOVE_INTEL_TT_OPTS)) +#if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES) && !defined(BOOST_NO_CXX11_SFINAE_EXPR) + + template + T && boost_move_tt_declval() BOOST_NOEXCEPT; + +# if defined(BOOST_GCC) && (BOOST_GCC >= 80000) +// __is_assignable / __is_constructible implemented +# define BOOST_MOVE_IS_ASSIGNABLE(T, U) __is_assignable(T, U) +# define BOOST_MOVE_IS_CONSTRUCTIBLE(T, U) __is_constructible(T, U) +# else + + template + class boost_move_tt_is_assignable + { + struct twochar { char dummy[2]; }; + template < class T + , class U + , class = decltype(boost_move_tt_declval() = boost_move_tt_declval()) + > static char test(int); + + template static twochar test(...); + + public: + static const bool value = sizeof(test(0)) == sizeof(char); + }; + + template + class boost_move_tt_is_constructible + { + struct twochar { char dummy[2]; }; + template < class T + , class U + , class = decltype(T(boost_move_tt_declval())) + > static char test(int); + + template static twochar test(...); + + public: + static const bool value = sizeof(test(0)) == sizeof(char); + }; + +# define BOOST_MOVE_IS_ASSIGNABLE(T, U) boost_move_tt_is_assignable::value +# define BOOST_MOVE_IS_CONSTRUCTIBLE(T, U) boost_move_tt_is_constructible::value + +# endif + + template + struct boost_move_tt_is_nothrow_assignable + { + static const bool value = false; + }; + + template + struct boost_move_tt_is_nothrow_assignable + { + #if !defined(BOOST_NO_CXX11_NOEXCEPT) + static const bool value = noexcept(boost_move_tt_declval() = boost_move_tt_declval()); + #else + static const bool value = false; + #endif + }; + + template + struct boost_move_tt_is_nothrow_constructible + { + static const bool value = false; + }; + + template + struct boost_move_tt_is_nothrow_constructible + { + #if !defined(BOOST_NO_CXX11_NOEXCEPT) + static const bool value = noexcept(T(boost_move_tt_declval())); + #else + static const bool value = false; + #endif + }; + +# define BOOST_MOVE_HAS_NOTHROW_MOVE_ASSIGN(T) boost_move_tt_is_nothrow_assignable::value +# define BOOST_MOVE_HAS_NOTHROW_MOVE_CONSTRUCTOR(T) boost_move_tt_is_nothrow_constructible::value + +# endif + # define BOOST_MOVE_IS_ENUM(T) __is_enum(T) + +// BOOST_MOVE_ALIGNMENT_OF # if (!defined(unix) && !defined(__unix__)) || defined(__LP64__) // GCC sometimes lies about alignment requirements // of type double on 32-bit unix platforms, use the @@ -355,8 +461,8 @@ #define BOOST_MOVE_IS_NOTHROW_COPY_ASSIGNABLE(T) BOOST_MOVE_IS_TRIVIALLY_COPY_ASSIGNABLE(T) #endif -#ifdef BOOST_MOVE_HAS_NOTHROW_MOVE_CONSTRUCT - #define BOOST_MOVE_IS_NOTHROW_MOVE_CONSTRUCTIBLE(T) BOOST_MOVE_HAS_NOTHROW_MOVE_CONSTRUCT(T) || ::boost::move_detail::is_pod::value +#ifdef BOOST_MOVE_HAS_NOTHROW_MOVE_CONSTRUCTOR + #define BOOST_MOVE_IS_NOTHROW_MOVE_CONSTRUCTIBLE(T) BOOST_MOVE_HAS_NOTHROW_MOVE_CONSTRUCTOR(T) || ::boost::move_detail::is_pod::value #else #define BOOST_MOVE_IS_NOTHROW_MOVE_CONSTRUCTIBLE(T) BOOST_MOVE_IS_TRIVIALLY_MOVE_ASSIGNABLE(T) #endif @@ -999,7 +1105,7 @@ struct alignment_of class alignment_dummy; typedef void (*function_ptr)(); typedef int (alignment_dummy::*member_ptr); -typedef int (alignment_dummy::*member_function_ptr)(); + struct alignment_struct { long double dummy[4]; }; @@ -1022,7 +1128,6 @@ union max_align long double long_double_[4]; alignment_dummy *unknown_class_ptr_; function_ptr function_ptr_; - member_function_ptr member_function_ptr_; alignment_struct alignment_struct_; }; @@ -1132,7 +1237,7 @@ struct aligned_next; template struct aligned_next { - BOOST_STATIC_ASSERT((alignment_of::value == Align)); + BOOST_MOVE_STATIC_ASSERT((alignment_of::value == Align)); typedef aligned_union type; }; @@ -1172,13 +1277,13 @@ template::value> struct aligned_storage { //Sanity checks for input parameters - BOOST_STATIC_ASSERT(Align > 0); + BOOST_MOVE_STATIC_ASSERT(Align > 0); //Sanity checks for output type typedef typename aligned_storage_impl::type type; static const std::size_t value = alignment_of::value; - BOOST_STATIC_ASSERT(value >= Align); - BOOST_STATIC_ASSERT((value % Align) == 0); + BOOST_MOVE_STATIC_ASSERT(value >= Align); + BOOST_MOVE_STATIC_ASSERT((value % Align) == 0); //Just in case someone instantiates aligned_storage //instead of aligned_storage::type (typical error). diff --git a/include/boost/move/detail/workaround.hpp b/include/boost/move/detail/workaround.hpp index 1d16f2433..2fcd027d8 100644 --- a/include/boost/move/detail/workaround.hpp +++ b/include/boost/move/detail/workaround.hpp @@ -52,18 +52,97 @@ #define BOOST_MOVE_MSVC_AUTO_MOVE_RETURN_BUG #endif +//#define BOOST_MOVE_DISABLE_FORCEINLINE + #if defined(BOOST_MOVE_DISABLE_FORCEINLINE) #define BOOST_MOVE_FORCEINLINE inline #elif defined(BOOST_MOVE_FORCEINLINE_IS_BOOST_FORCELINE) #define BOOST_MOVE_FORCEINLINE BOOST_FORCEINLINE -#elif defined(BOOST_MSVC) && defined(_DEBUG) - //"__forceinline" and MSVC seems to have some bugs in debug mode +#elif defined(BOOST_MSVC) && (_MSC_VER < 1900 || defined(_DEBUG)) + //"__forceinline" and MSVC seems to have some bugs in old versions and in debug mode #define BOOST_MOVE_FORCEINLINE inline -#elif defined(__GNUC__) && ((__GNUC__ < 4) || (__GNUC__ == 4 && (__GNUC_MINOR__ < 5))) +#elif defined(BOOST_GCC) && (__GNUC__ <= 5) //Older GCCs have problems with forceinline #define BOOST_MOVE_FORCEINLINE inline #else #define BOOST_MOVE_FORCEINLINE BOOST_FORCEINLINE #endif +namespace boost { +namespace movelib { + +template +BOOST_FORCEINLINE BOOST_CXX14_CONSTEXPR void ignore(T1 const&) +{} + +}} //namespace boost::movelib { + +#if !(defined BOOST_NO_EXCEPTIONS) +# define BOOST_MOVE_TRY { try +# define BOOST_MOVE_CATCH(x) catch(x) +# define BOOST_MOVE_RETHROW throw; +# define BOOST_MOVE_CATCH_END } +#else +# if !defined(BOOST_MSVC) || BOOST_MSVC >= 1900 +# define BOOST_MOVE_TRY { if (true) +# define BOOST_MOVE_CATCH(x) else if (false) +# else +// warning C4127: conditional expression is constant +# define BOOST_MOVE_TRY { \ + __pragma(warning(push)) \ + __pragma(warning(disable: 4127)) \ + if (true) \ + __pragma(warning(pop)) +# define BOOST_MOVE_CATCH(x) else \ + __pragma(warning(push)) \ + __pragma(warning(disable: 4127)) \ + if (false) \ + __pragma(warning(pop)) +# endif +# define BOOST_MOVE_RETHROW +# define BOOST_MOVE_CATCH_END } +#endif + +#ifndef BOOST_NO_CXX11_STATIC_ASSERT +# ifndef BOOST_NO_CXX11_VARIADIC_MACROS +# define BOOST_MOVE_STATIC_ASSERT( ... ) static_assert(__VA_ARGS__, #__VA_ARGS__) +# else +# define BOOST_MOVE_STATIC_ASSERT( B ) static_assert(B, #B) +# endif +#else +namespace boost { +namespace move_detail { + +template +struct STATIC_ASSERTION_FAILURE; + +template<> +struct STATIC_ASSERTION_FAILURE{}; + +template struct static_assert_test {}; + +}} + +#define BOOST_MOVE_STATIC_ASSERT(B) \ + typedef ::boost::move_detail::static_assert_test<\ + (unsigned)sizeof(::boost::move_detail::STATIC_ASSERTION_FAILURE)>\ + BOOST_JOIN(boost_static_assert_typedef_, __LINE__) BOOST_ATTRIBUTE_UNUSED + +#endif + +#if !defined(__has_cpp_attribute) || defined(__CUDACC__) +#define BOOST_MOVE_HAS_MSVC_ATTRIBUTE(ATTR) 0 +#else +#define BOOST_MOVE_HAS_MSVC_ATTRIBUTE(ATTR) __has_cpp_attribute(msvc::ATTR) +#endif + +// See https://devblogs.microsoft.com/cppblog/improving-the-state-of-debug-performance-in-c/ +// for details on how MSVC has improved debug experience, specifically for move/forward-like utilities +#if BOOST_MOVE_HAS_MSVC_ATTRIBUTE(intrinsic) +#define BOOST_MOVE_INTRINSIC_CAST [[msvc::intrinsic]] +#else +#define BOOST_MOVE_INTRINSIC_CAST BOOST_MOVE_FORCEINLINE +#endif + #endif //#ifndef BOOST_MOVE_DETAIL_WORKAROUND_HPP + diff --git a/include/boost/move/utility.hpp b/include/boost/move/utility.hpp index 28de7935c..9c94d7707 100644 --- a/include/boost/move/utility.hpp +++ b/include/boost/move/utility.hpp @@ -126,13 +126,13 @@ #else //BOOST_MOVE_DOXYGEN_INVOKED template - BOOST_MOVE_FORCEINLINE typename ::boost::move_detail::enable_if_c + BOOST_MOVE_INTRINSIC_CAST typename ::boost::move_detail::enable_if_c < ::boost::move_detail::is_nothrow_move_constructible_or_uncopyable::value, T&&>::type move_if_noexcept(T& x) BOOST_NOEXCEPT { return ::boost::move(x); } template - BOOST_MOVE_FORCEINLINE typename ::boost::move_detail::enable_if_c + BOOST_MOVE_INTRINSIC_CAST typename ::boost::move_detail::enable_if_c < !::boost::move_detail::is_nothrow_move_constructible_or_uncopyable::value, const T&>::type move_if_noexcept(T& x) BOOST_NOEXCEPT { return x; } diff --git a/include/boost/move/utility_core.hpp b/include/boost/move/utility_core.hpp index 55042a9bb..907b7641d 100644 --- a/include/boost/move/utility_core.hpp +++ b/include/boost/move/utility_core.hpp @@ -29,7 +29,6 @@ #include //forceinline #include #include -#include #if defined(BOOST_NO_CXX11_RVALUE_REFERENCES) && !defined(BOOST_MOVE_DOXYGEN_INVOKED) @@ -209,7 +208,8 @@ #else //BOOST_MOVE_OLD_RVALUE_REF_BINDING_RULES template - BOOST_MOVE_FORCEINLINE typename ::boost::move_detail::remove_reference::type && move(T&& t) BOOST_NOEXCEPT + BOOST_MOVE_INTRINSIC_CAST + typename ::boost::move_detail::remove_reference::type && move(T&& t) BOOST_NOEXCEPT { return static_cast::type &&>(t); } #endif //BOOST_MOVE_OLD_RVALUE_REF_BINDING_RULES @@ -245,57 +245,62 @@ #else //Old move template - BOOST_MOVE_FORCEINLINE T&& forward(typename ::boost::move_detail::remove_reference::type& t) BOOST_NOEXCEPT + BOOST_MOVE_INTRINSIC_CAST + T&& forward(typename ::boost::move_detail::remove_reference::type& t) BOOST_NOEXCEPT { return static_cast(t); } template - BOOST_MOVE_FORCEINLINE T&& forward(typename ::boost::move_detail::remove_reference::type&& t) BOOST_NOEXCEPT + BOOST_MOVE_INTRINSIC_CAST + T&& forward(typename ::boost::move_detail::remove_reference::type&& t) BOOST_NOEXCEPT { //"boost::forward error: 'T' is a lvalue reference, can't forward as rvalue."; - BOOST_STATIC_ASSERT(!boost::move_detail::is_lvalue_reference::value); + BOOST_MOVE_STATIC_ASSERT(!boost::move_detail::is_lvalue_reference::value); return static_cast(t); } #endif //BOOST_MOVE_DOXYGEN_INVOKED - ////////////////////////////////////////////////////////////////////////////// - // - // move_if_not_lvalue_reference - // - ////////////////////////////////////////////////////////////////////////////// + } //namespace boost { + #endif //BOOST_MOVE_USE_STANDARD_LIBRARY_MOVE - #if defined(BOOST_MOVE_DOXYGEN_INVOKED) - //! Effects: Calls `boost::move` if `input_reference` is not a lvalue reference. - //! Otherwise returns the reference - template output_reference move_if_not_lvalue_reference(input_reference) noexcept; - #elif defined(BOOST_MOVE_OLD_RVALUE_REF_BINDING_RULES) + ////////////////////////////////////////////////////////////////////////////// + // + // move_if_not_lvalue_reference + // + ////////////////////////////////////////////////////////////////////////////// - //Old move approach, lvalues could bind to rvalue references + namespace boost { - template - BOOST_MOVE_FORCEINLINE T&& move_if_not_lvalue_reference(typename ::boost::move_detail::identity::type&& t) BOOST_NOEXCEPT - { return t; } + #if defined(BOOST_MOVE_DOXYGEN_INVOKED) + //! Effects: Calls `boost::move` if `input_reference` is not a lvalue reference. + //! Otherwise returns the reference + template output_reference move_if_not_lvalue_reference(input_reference) noexcept; + #elif defined(BOOST_MOVE_OLD_RVALUE_REF_BINDING_RULES) - #else //Old move + //Old move approach, lvalues could bind to rvalue references - template - BOOST_MOVE_FORCEINLINE T&& move_if_not_lvalue_reference(typename ::boost::move_detail::remove_reference::type& t) BOOST_NOEXCEPT - { return static_cast(t); } + template + BOOST_MOVE_FORCEINLINE T&& move_if_not_lvalue_reference(typename ::boost::move_detail::identity::type&& t) BOOST_NOEXCEPT + { return t; } - template - BOOST_MOVE_FORCEINLINE T&& move_if_not_lvalue_reference(typename ::boost::move_detail::remove_reference::type&& t) BOOST_NOEXCEPT - { - //"boost::forward error: 'T' is a lvalue reference, can't forward as rvalue."; - BOOST_STATIC_ASSERT(!boost::move_detail::is_lvalue_reference::value); - return static_cast(t); - } + #else //Old move - #endif //BOOST_MOVE_DOXYGEN_INVOKED + template + BOOST_MOVE_FORCEINLINE T&& move_if_not_lvalue_reference(typename ::boost::move_detail::remove_reference::type& t) BOOST_NOEXCEPT + { return static_cast(t); } - } //namespace boost { + template + BOOST_MOVE_FORCEINLINE T&& move_if_not_lvalue_reference(typename ::boost::move_detail::remove_reference::type&& t) BOOST_NOEXCEPT + { + //"boost::forward error: 'T' is a lvalue reference, can't forward as rvalue."; + BOOST_MOVE_STATIC_ASSERT(!boost::move_detail::is_lvalue_reference::value); + return static_cast(t); + } + + #endif //BOOST_MOVE_DOXYGEN_INVOKED - #endif //#if defined(BOOST_MOVE_USE_STANDARD_LIBRARY_MOVE) + } //namespace boost { #endif //BOOST_NO_CXX11_RVALUE_REFERENCES diff --git a/include/boost/mp11/algorithm.hpp b/include/boost/mp11/algorithm.hpp new file mode 100644 index 000000000..be377f5a6 --- /dev/null +++ b/include/boost/mp11/algorithm.hpp @@ -0,0 +1,1327 @@ +#ifndef BOOST_MP11_ALGORITHM_HPP_INCLUDED +#define BOOST_MP11_ALGORITHM_HPP_INCLUDED + +// Copyright 2015-2019 Peter Dimov +// +// 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 + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +namespace boost +{ +namespace mp11 +{ + +// mp_transform +namespace detail +{ + +template class F, class... L> struct mp_transform_impl +{ +}; + +template class F, template class L, class... T> struct mp_transform_impl> +{ +#if BOOST_MP11_WORKAROUND( BOOST_MP11_MSVC, < 1920 ) + + template struct f { using type = F; }; + + using type = L::type...>; + +#else + + using type = L...>; + +#endif +}; + +template class F, template class L1, class... T1, template class L2, class... T2> struct mp_transform_impl, L2> +{ +#if BOOST_MP11_WORKAROUND( BOOST_MP11_MSVC, < 1920 ) + + template struct f { using type = F; }; + + using type = L1::type...>; + +#else + + using type = L1...>; + +#endif +}; + +template class F, template class L1, class... T1, template class L2, class... T2, template class L3, class... T3> struct mp_transform_impl, L2, L3> +{ +#if BOOST_MP11_WORKAROUND( BOOST_MP11_MSVC, < 1920 ) + + template struct f { using type = F; }; + + using type = L1::type...>; + +#else + + using type = L1...>; + +#endif +}; + +#if BOOST_MP11_WORKAROUND( BOOST_MP11_MSVC, == 1900 ) || BOOST_MP11_WORKAROUND( BOOST_MP11_GCC, < 40800 ) + +template using mp_same_size_1 = mp_same...>; +template struct mp_same_size_2: mp_defer {}; + +#endif + +struct list_size_mismatch +{ +}; + +#if BOOST_MP11_WORKAROUND( BOOST_MP11_CUDA, >= 9000000 && BOOST_MP11_CUDA < 10000000 ) + +template class F, class... L> struct mp_transform_cuda_workaround +{ + using type = mp_if...>, detail::mp_transform_impl, detail::list_size_mismatch>; +}; + +#endif + +} // namespace detail + +#if BOOST_MP11_WORKAROUND( BOOST_MP11_MSVC, == 1900 ) || BOOST_MP11_WORKAROUND( BOOST_MP11_GCC, < 40800 ) + +template class F, class... L> using mp_transform = typename mp_if::type, detail::mp_transform_impl, detail::list_size_mismatch>::type; + +#else + +#if BOOST_MP11_WORKAROUND( BOOST_MP11_CUDA, >= 9000000 && BOOST_MP11_CUDA < 10000000 ) + +template class F, class... L> using mp_transform = typename detail::mp_transform_cuda_workaround< F, L...>::type::type; + +#else + +template class F, class... L> using mp_transform = typename mp_if...>, detail::mp_transform_impl, detail::list_size_mismatch>::type; + +#endif + +#endif + +template using mp_transform_q = mp_transform; + +namespace detail +{ + +template class F, template class L1, class... T1, template class L2, class... T2, template class L3, class... T3, template class L4, class... T4, class... L> struct mp_transform_impl, L2, L3, L4, L...> +{ + using A1 = L1...>; + + template using _f = mp_transform; + + using A2 = mp_fold, A1, _f>; + + template using _g = mp_apply; + + using type = mp_transform<_g, A2>; +}; + +} // namespace detail + +// mp_transform_if +namespace detail +{ + +template class P, template class F, class... L> struct mp_transform_if_impl +{ + // the stupid quote-unquote dance avoids "pack expansion used as argument for non-pack parameter of alias template" + + using Qp = mp_quote

; + using Qf = mp_quote; + +#if BOOST_MP11_WORKAROUND( BOOST_MP11_MSVC, < 1920 ) + + template struct _f_ { using type = mp_eval_if_q>, mp_first>, Qf, U...>; }; + template using _f = typename _f_::type; + +#else + + template using _f = mp_eval_if_q>, mp_first>, Qf, U...>; + +#endif + + using type = mp_transform<_f, L...>; +}; + +} // namespace detail + +template class P, template class F, class... L> using mp_transform_if = typename detail::mp_transform_if_impl::type; +template using mp_transform_if_q = typename detail::mp_transform_if_impl::type; + +// mp_filter +namespace detail +{ + +template class P, class L1, class... L> struct mp_filter_impl +{ + using Qp = mp_quote

; + + template using _f = mp_if< mp_invoke_q, mp_list, mp_list<> >; + + using _t1 = mp_transform<_f, L1, L...>; + using _t2 = mp_apply; + + using type = mp_assign; +}; + +} // namespace detail + +template class P, class... L> using mp_filter = typename detail::mp_filter_impl::type; +template using mp_filter_q = typename detail::mp_filter_impl::type; + +// mp_fill +namespace detail +{ + +template struct mp_fill_impl +{ +// An error "no type named 'type'" here means that the L argument of mp_fill is not a list +}; + +template class L, class... T, class V> struct mp_fill_impl, V> +{ +#if BOOST_MP11_WORKAROUND( BOOST_MP11_MSVC, <= 1900 ) + + template struct _f { using type = V; }; + using type = L::type...>; + +#else + + template using _f = V; + using type = L<_f...>; + +#endif +}; + +#if defined(BOOST_MP11_HAS_TEMPLATE_AUTO) + +template class L, auto... A, class V> struct mp_fill_impl, V> +{ + using type = L<((void)A, V::value)...>; +}; + +#endif + +} // namespace detail + +template using mp_fill = typename detail::mp_fill_impl::type; + +// mp_contains +template using mp_contains = mp_to_bool>; + +// mp_repeat(_c) +namespace detail +{ + +template struct mp_repeat_c_impl +{ + using _l1 = typename mp_repeat_c_impl::type; + using _l2 = typename mp_repeat_c_impl::type; + + using type = mp_append<_l1, _l1, _l2>; +}; + +template struct mp_repeat_c_impl +{ + using type = mp_clear; +}; + +template struct mp_repeat_c_impl +{ + using type = L; +}; + +} // namespace detail + +template using mp_repeat_c = typename detail::mp_repeat_c_impl::type; +template using mp_repeat = typename detail::mp_repeat_c_impl::type; + +// mp_product +namespace detail +{ + +template class F, class P, class... L> struct mp_product_impl_2 +{ +}; + +template class F, class P> struct mp_product_impl_2 +{ + using type = mp_list>; +}; + +template class F, class P, template class L1, class... T1, class... L> struct mp_product_impl_2, L...> +{ + using type = mp_append, L...>::type...>; +}; + +template class F, class... L> struct mp_product_impl +{ +}; + +template class F> struct mp_product_impl +{ + using type = mp_list< F<> >; +}; + +template class F, class L1, class... L> struct mp_product_impl +{ + using type = mp_assign, L1, L...>::type>; +}; + +} // namespace detail + +template class F, class... L> using mp_product = typename detail::mp_product_impl::type; +template using mp_product_q = typename detail::mp_product_impl::type; + +// mp_drop(_c) +namespace detail +{ + +template struct mp_drop_impl; + +template class L, class... T, template class L2, class... U> struct mp_drop_impl, L2, mp_true> +{ + template static mp_identity> f( U*..., mp_identity*... ); + + using R = decltype( f( static_cast*>(0) ... ) ); + + using type = typename R::type; +}; + +} // namespace detail + +template using mp_drop_c = mp_assign, mp_repeat_c, N>, mp_bool::value>>::type>; + +template using mp_drop = mp_drop_c; + +// mp_from_sequence +namespace detail +{ + +template struct mp_from_sequence_impl; + +template class S, class U, U... J, class F> struct mp_from_sequence_impl, F> +{ + using type = mp_list_c; +}; + +} // namespace detail + +template> using mp_from_sequence = typename detail::mp_from_sequence_impl::type; + +// mp_iota(_c) +template using mp_iota_c = mp_from_sequence, mp_size_t>; +template> using mp_iota = mp_from_sequence::type, N::value>, F>; + +// mp_at(_c) +namespace detail +{ + +template struct mp_at_c_impl; + +#if defined(BOOST_MP11_HAS_TYPE_PACK_ELEMENT) + +template class L, class... T, std::size_t I> struct mp_at_c_impl, I> +{ + using type = __type_pack_element; +}; + +#if defined(BOOST_MP11_HAS_TEMPLATE_AUTO) + +template class L, auto... A, std::size_t I> struct mp_at_c_impl, I> +{ + using type = __type_pack_element...>; +}; + +#endif + +#else + +template struct mp_at_c_impl +{ + using _map = mp_transform >, mp_rename>; + using type = mp_second > >; +}; + +#endif + +#if BOOST_MP11_WORKAROUND( BOOST_MP11_CUDA, >= 9000000 && BOOST_MP11_CUDA < 10000000 ) + +template struct mp_at_c_cuda_workaround +{ + using type = mp_if_c<(I < mp_size::value), detail::mp_at_c_impl, void>; +}; + +#endif + +} // namespace detail + +#if BOOST_MP11_WORKAROUND( BOOST_MP11_CUDA, >= 9000000 && BOOST_MP11_CUDA < 10000000 ) + +template using mp_at_c = typename detail::mp_at_c_cuda_workaround< L, I >::type::type; + +#else + +template using mp_at_c = typename mp_if_c<(I < mp_size::value), detail::mp_at_c_impl, void>::type; + +#endif + +template using mp_at = mp_at_c; + +// mp_take(_c) +namespace detail +{ + +template struct mp_take_c_impl +{ +}; + +template class L, class... T> +struct mp_take_c_impl<0, L> +{ + using type = L<>; +}; + +template class L, class T1, class... T> +struct mp_take_c_impl<1, L> +{ + using type = L; +}; + +template class L, class T1, class T2, class... T> +struct mp_take_c_impl<2, L> +{ + using type = L; +}; + +template class L, class T1, class T2, class T3, class... T> +struct mp_take_c_impl<3, L> +{ + using type = L; +}; + +template class L, class T1, class T2, class T3, class T4, class... T> +struct mp_take_c_impl<4, L> +{ + using type = L; +}; + +template class L, class T1, class T2, class T3, class T4, class T5, class... T> +struct mp_take_c_impl<5, L> +{ + using type = L; +}; + +template class L, class T1, class T2, class T3, class T4, class T5, class T6, class... T> +struct mp_take_c_impl<6, L> +{ + using type = L; +}; + +template class L, class T1, class T2, class T3, class T4, class T5, class T6, class T7, class... T> +struct mp_take_c_impl<7, L> +{ + using type = L; +}; + +template class L, class T1, class T2, class T3, class T4, class T5, class T6, class T7, class T8, class... T> +struct mp_take_c_impl<8, L> +{ + using type = L; +}; + +template class L, class T1, class T2, class T3, class T4, class T5, class T6, class T7, class T8, class T9, class... T> +struct mp_take_c_impl<9, L> +{ + using type = L; +}; + +template class L, class T1, class T2, class T3, class T4, class T5, class T6, class T7, class T8, class T9, class T10, class... T, std::size_t N> +struct mp_take_c_impl, typename std::enable_if= 10>::type> +{ + using type = mp_append, typename mp_take_c_impl>::type>; +}; + +} // namespace detail + +template using mp_take_c = mp_assign>::type>; +template using mp_take = mp_take_c; + +// mp_back +template using mp_back = mp_at_c::value - 1>; + +// mp_pop_back +template using mp_pop_back = mp_take_c::value - 1>; + +// mp_replace +namespace detail +{ + +template struct mp_replace_impl; + +template class L, class... T, class V, class W> struct mp_replace_impl, V, W> +{ +#if BOOST_MP11_WORKAROUND( BOOST_MP11_MSVC, <= 1800 ) + template struct _f { using type = mp_if, W, A>; }; + using type = L::type...>; +#else + template using _f = mp_if, W, A>; + using type = L<_f...>; +#endif +}; + +} // namespace detail + +template using mp_replace = typename detail::mp_replace_impl::type; + +// mp_replace_if +namespace detail +{ + +template class P, class W> struct mp_replace_if_impl; + +template class L, class... T, template class P, class W> struct mp_replace_if_impl, P, W> +{ +#if BOOST_MP11_WORKAROUND( BOOST_MP11_MSVC, < 1920 ) + template struct _f { using type = mp_if, W, U>; }; + using type = L::type...>; +#else + template using _f = mp_if, W, U>; + using type = L<_f...>; +#endif +}; + +} // namespace detail + +template class P, class W> using mp_replace_if = typename detail::mp_replace_if_impl::type; +template using mp_replace_if_q = mp_replace_if; + +// mp_copy_if +// in detail/mp_copy_if.hpp + +// mp_remove +namespace detail +{ + +template struct mp_remove_impl; + +template class L, class... T, class V> struct mp_remove_impl, V> +{ +#if BOOST_MP11_WORKAROUND( BOOST_MP11_MSVC, < 1920 ) + template struct _f { using type = mp_if, mp_list<>, mp_list>; }; + using type = mp_append, typename _f::type...>; +#else + template using _f = mp_if, mp_list<>, mp_list>; + using type = mp_append, _f...>; +#endif +}; + +} // namespace detail + +template using mp_remove = typename detail::mp_remove_impl::type; + +// mp_remove_if +// in detail/mp_remove_if.hpp + +// mp_flatten> +namespace detail +{ + +template struct mp_flatten_impl +{ + template using fn = mp_if, T, mp_list>; +}; + +} // namespace detail + +template> using mp_flatten = mp_apply, L>, mp_clear>>; + +// mp_partition +namespace detail +{ + +template class P> struct mp_partition_impl; + +template class L, class... T, template class P> struct mp_partition_impl, P> +{ + using type = L, P>, mp_remove_if, P>>; +}; + +} // namespace detail + +template class P> using mp_partition = typename detail::mp_partition_impl::type; +template using mp_partition_q = mp_partition; + +// mp_sort +namespace detail +{ + +template class P> struct mp_sort_impl; + +#if BOOST_MP11_WORKAROUND( BOOST_MP11_MSVC, <= 1800 ) + +template class L, class... T, template class P> struct mp_sort_impl, P> +{ + static_assert( sizeof...(T) == 0, "T... must be empty" ); + using type = L<>; +}; + +#else + +template class L, template class P> struct mp_sort_impl, P> +{ + using type = L<>; +}; + +#endif + +template class L, class T1, template class P> struct mp_sort_impl, P> +{ + using type = L; +}; + +template class L, class T1, class... T, template class P> struct mp_sort_impl, P> +{ + template using F = P; + + using part = mp_partition, F>; + + using S1 = typename mp_sort_impl, P>::type; + using S2 = typename mp_sort_impl, P>::type; + + using type = mp_append, S2>; +}; + +} // namespace detail + +template class P> using mp_sort = typename detail::mp_sort_impl::type; +template using mp_sort_q = mp_sort; + +// mp_nth_element(_c) +namespace detail +{ + +template class P> struct mp_nth_element_impl; + +template class L, class T1, std::size_t I, template class P> struct mp_nth_element_impl, I, P> +{ + static_assert( I == 0, "mp_nth_element index out of range" ); + using type = T1; +}; + +template class L, class T1, class... T, std::size_t I, template class P> struct mp_nth_element_impl, I, P> +{ + static_assert( I < 1 + sizeof...(T), "mp_nth_element index out of range" ); + + template using F = P; + + using part = mp_partition, F>; + + using L1 = mp_first; + static std::size_t const N1 = mp_size::value; + + using L2 = mp_second; + +#if BOOST_MP11_WORKAROUND( BOOST_MP11_CUDA, >= 9000000 && BOOST_MP11_CUDA < 10000000 ) + + struct detail + { + struct mp_nth_element_impl_cuda_workaround + { + using type = mp_cond< + + mp_bool<(I < N1)>, mp_nth_element_impl, + mp_bool<(I == N1)>, mp_identity, + mp_true, mp_nth_element_impl + + >; + }; + }; + + using type = typename detail::mp_nth_element_impl_cuda_workaround::type::type; + +#else + + using type = typename mp_cond< + + mp_bool<(I < N1)>, mp_nth_element_impl, + mp_bool<(I == N1)>, mp_identity, + mp_true, mp_nth_element_impl + + >::type; + +#endif +}; + +} // namespace detail + +template class P> using mp_nth_element_c = typename detail::mp_nth_element_impl::type; +template class P> using mp_nth_element = typename detail::mp_nth_element_impl::type; +template using mp_nth_element_q = mp_nth_element; + +// mp_find +namespace detail +{ + +template struct mp_find_impl; + +#if BOOST_MP11_CLANG && defined( BOOST_MP11_HAS_FOLD_EXPRESSIONS ) + +struct mp_index_holder +{ + std::size_t i_; + bool f_; +}; + +constexpr inline mp_index_holder operator+( mp_index_holder const & v, bool f ) +{ + if( v.f_ ) + { + return v; + } + else if( f ) + { + return { v.i_, true }; + } + else + { + return { v.i_ + 1, false }; + } +} + +template class L, class... T, class V> struct mp_find_impl, V> +{ + static constexpr mp_index_holder _v{ 0, false }; + using type = mp_size_t< (_v + ... + std::is_same::value).i_ >; +}; + +#elif !defined( BOOST_MP11_NO_CONSTEXPR ) + +template class L, class V> struct mp_find_impl, V> +{ + using type = mp_size_t<0>; +}; + +#if defined( BOOST_MP11_HAS_CXX14_CONSTEXPR ) + +constexpr std::size_t cx_find_index( bool const * first, bool const * last ) +{ + std::size_t m = 0; + + while( first != last && !*first ) + { + ++m; + ++first; + } + + return m; +} + +#else + +constexpr std::size_t cx_find_index( bool const * first, bool const * last ) +{ + return first == last || *first? 0: 1 + cx_find_index( first + 1, last ); +} + +#endif + +template class L, class... T, class V> struct mp_find_impl, V> +{ + static constexpr bool _v[] = { std::is_same::value... }; + using type = mp_size_t< cx_find_index( _v, _v + sizeof...(T) ) >; +}; + +#else + +#if BOOST_MP11_WORKAROUND( BOOST_MP11_MSVC, <= 1800 ) + +template class L, class... T, class V> struct mp_find_impl, V> +{ + static_assert( sizeof...(T) == 0, "T... must be empty" ); + using type = mp_size_t<0>; +}; + +#else + +template class L, class V> struct mp_find_impl, V> +{ + using type = mp_size_t<0>; +}; + +#endif + +template class L, class... T, class V> struct mp_find_impl, V> +{ + using type = mp_size_t<0>; +}; + +template class L, class T1, class... T, class V> struct mp_find_impl, V> +{ + using _r = typename mp_find_impl, V>::type; + using type = mp_size_t<1 + _r::value>; +}; + +#endif + +} // namespace detail + +template using mp_find = typename detail::mp_find_impl::type; + +// mp_find_if +namespace detail +{ + +template class P> struct mp_find_if_impl; + +#if BOOST_MP11_CLANG && defined( BOOST_MP11_HAS_FOLD_EXPRESSIONS ) + +template class L, class... T, template class P> struct mp_find_if_impl, P> +{ + static constexpr mp_index_holder _v{ 0, false }; + using type = mp_size_t< (_v + ... + P::value).i_ >; +}; + +#elif !defined( BOOST_MP11_NO_CONSTEXPR ) + +template class L, template class P> struct mp_find_if_impl, P> +{ + using type = mp_size_t<0>; +}; + +template class L, class... T, template class P> struct mp_find_if_impl, P> +{ + static constexpr bool _v[] = { P::value... }; + using type = mp_size_t< cx_find_index( _v, _v + sizeof...(T) ) >; +}; + +#else + +#if BOOST_MP11_WORKAROUND( BOOST_MP11_MSVC, <= 1800 ) + +template class L, class... T, template class P> struct mp_find_if_impl, P> +{ + static_assert( sizeof...(T) == 0, "T... must be empty" ); + using type = mp_size_t<0>; +}; + +#else + +template class L, template class P> struct mp_find_if_impl, P> +{ + using type = mp_size_t<0>; +}; + +#endif + +template class P> struct mp_find_if_impl_2 +{ + using _r = typename mp_find_if_impl::type; + using type = mp_size_t<1 + _r::value>; +}; + +template class L, class T1, class... T, template class P> struct mp_find_if_impl, P> +{ + using type = typename mp_if, mp_identity>, mp_find_if_impl_2, P>>::type; +}; + +#endif + +} // namespace detail + +template class P> using mp_find_if = typename detail::mp_find_if_impl::type; +template using mp_find_if_q = mp_find_if; + +// mp_reverse +namespace detail +{ + +template struct mp_reverse_impl; + +#if BOOST_MP11_WORKAROUND( BOOST_MP11_MSVC, <= 1800 ) + +template class L, class... T> struct mp_reverse_impl> +{ + static_assert( sizeof...(T) == 0, "T... must be empty" ); + using type = L<>; +}; + +#else + +template class L> struct mp_reverse_impl> +{ + using type = L<>; +}; + +#endif + +template class L, class T1> struct mp_reverse_impl> +{ + using type = L; +}; + +template class L, class T1, class T2> struct mp_reverse_impl> +{ + using type = L; +}; + +template class L, class T1, class T2, class T3> struct mp_reverse_impl> +{ + using type = L; +}; + +template class L, class T1, class T2, class T3, class T4> struct mp_reverse_impl> +{ + using type = L; +}; + +template class L, class T1, class T2, class T3, class T4, class T5> struct mp_reverse_impl> +{ + using type = L; +}; + +template class L, class T1, class T2, class T3, class T4, class T5, class T6> struct mp_reverse_impl> +{ + using type = L; +}; + +template class L, class T1, class T2, class T3, class T4, class T5, class T6, class T7> struct mp_reverse_impl> +{ + using type = L; +}; + +template class L, class T1, class T2, class T3, class T4, class T5, class T6, class T7, class T8> struct mp_reverse_impl> +{ + using type = L; +}; + +template class L, class T1, class T2, class T3, class T4, class T5, class T6, class T7, class T8, class T9> struct mp_reverse_impl> +{ + using type = L; +}; + +template class L, class T1, class T2, class T3, class T4, class T5, class T6, class T7, class T8, class T9, class T10, class... T> struct mp_reverse_impl> +{ + using type = mp_push_back>::type, T10, T9, T8, T7, T6, T5, T4, T3, T2, T1>; +}; + +} // namespace detail + +template using mp_reverse = typename detail::mp_reverse_impl::type; + +// mp_fold +// in detail/mp_fold.hpp + +// mp_reverse_fold +namespace detail +{ + +template class F> struct mp_reverse_fold_impl; + +#if BOOST_MP11_WORKAROUND( BOOST_MP11_MSVC, <= 1800 ) + +template class L, class... T, class V, template class F> struct mp_reverse_fold_impl, V, F> +{ + static_assert( sizeof...(T) == 0, "T... must be empty" ); + using type = V; +}; + +#else + +template class L, class V, template class F> struct mp_reverse_fold_impl, V, F> +{ + using type = V; +}; + +#endif + +template class L, class T1, class... T, class V, template class F> struct mp_reverse_fold_impl, V, F> +{ + using rest = typename mp_reverse_fold_impl, V, F>::type; + using type = F; +}; + +template class L, class T1, class T2, class T3, class T4, class T5, class T6, class T7, class T8, class T9, class T10, class... T, class V, template class F> struct mp_reverse_fold_impl, V, F> +{ + using rest = typename mp_reverse_fold_impl, V, F>::type; + using type = F > > > > > > > > >; +}; + +} // namespace detail + +template class F> using mp_reverse_fold = typename detail::mp_reverse_fold_impl::type; +template using mp_reverse_fold_q = mp_reverse_fold; + +// mp_unique +namespace detail +{ + +template struct mp_unique_impl; + +template class L, class... T> struct mp_unique_impl> +{ + using type = mp_set_push_back, T...>; +}; + +} // namespace detail + +template using mp_unique = typename detail::mp_unique_impl::type; + +// mp_unique_if +namespace detail +{ + +template class P> struct mp_unique_if_push_back +{ + template struct impl + { + }; + + template class L, class... Ts, class T> + struct impl, T> + { + using type = mp_if...>, L, L>; + }; + + template using fn = typename impl::type; +}; + +} // namespace detail + +template class P> +using mp_unique_if = mp_fold_q, detail::mp_unique_if_push_back

>; + +template using mp_unique_if_q = mp_unique_if; + +// mp_all_of +template class P> using mp_all_of = mp_bool< mp_count_if::value == mp_size::value >; +template using mp_all_of_q = mp_all_of; + +// mp_none_of +template class P> using mp_none_of = mp_bool< mp_count_if::value == 0 >; +template using mp_none_of_q = mp_none_of; + +// mp_any_of +template class P> using mp_any_of = mp_bool< mp_count_if::value != 0 >; +template using mp_any_of_q = mp_any_of; + +// mp_replace_at_c +namespace detail +{ + +template struct mp_replace_at_impl +{ + static_assert( I::value >= 0, "mp_replace_at: I must not be negative" ); + + template using _p = std::is_same>; + template using _f = W; + + using type = mp_transform_if<_p, _f, L, mp_iota > >; +}; + +} // namespace detail + +template using mp_replace_at = typename detail::mp_replace_at_impl::type; +template using mp_replace_at_c = typename detail::mp_replace_at_impl, W>::type; + +//mp_for_each(f) +namespace detail +{ + +template BOOST_MP11_CONSTEXPR F mp_for_each_impl( mp_list, F && f ) +{ + using A = int[sizeof...(T)]; + return (void)A{ ((void)f(T()), 0)... }, std::forward(f); +} + +template BOOST_MP11_CONSTEXPR F mp_for_each_impl( mp_list<>, F && f ) +{ + return std::forward(f); +} + +} // namespace detail + +#if BOOST_MP11_WORKAROUND( BOOST_MP11_MSVC, >= 1900 ) + +// msvc has a limit of 1024 + +template BOOST_MP11_CONSTEXPR mp_if_c::value <= 1024, F> mp_for_each( F && f ) +{ + return detail::mp_for_each_impl( mp_rename(), std::forward(f) ); +} + +template BOOST_MP11_CONSTEXPR mp_if_c::value >= 1025, F> mp_for_each( F && f ) +{ + using L2 = mp_rename; + + using L3 = mp_take_c; + using L4 = mp_drop_c; + + return mp_for_each( mp_for_each( std::forward(f) ) ); +} + +#else + +template BOOST_MP11_CONSTEXPR F mp_for_each( F && f ) +{ + return detail::mp_for_each_impl( mp_rename(), std::forward(f) ); +} + +#endif + +// mp_insert +template using mp_insert = mp_append, mp_push_front, T...>>; + +// mp_insert_c +template using mp_insert_c = mp_append, mp_push_front, T...>>; + +// mp_erase +template using mp_erase = mp_append, mp_drop>; + +// mp_erase_c +template using mp_erase_c = mp_append, mp_drop_c>; + +// mp_starts_with +// contributed by Glen Joseph Fernandes (glenjofe@gmail.com) +namespace detail { + +template +struct mp_starts_with_impl { }; + +template class L1, class... T1, template class L2, + class... T2> +struct mp_starts_with_impl, L2 > { + template + static mp_false check(L); + + template + static mp_true check(mp_list); + + using type = decltype(check(mp_list())); +}; + +} // namespace detail + +template +using mp_starts_with = typename detail::mp_starts_with_impl::type; + +// mp_rotate_left(_c) +namespace detail +{ + +// limit divisor to 1 to avoid division by 0 and give a rotation of 0 for lists containing 0 or 1 elements +template using canonical_left_rotation = mp_size_t; + +// perform right rotation as a left rotation by inverting the number of elements to rotate +template using canonical_right_rotation = mp_size_t; + +// avoid errors when rotating fixed-sized lists by using mp_list for the transformation +template> using mp_rotate_impl = mp_assign, mp_take >>; + +} // namespace detail + +template using mp_rotate_left_c = detail::mp_rotate_impl::value, N>>; +template using mp_rotate_left = mp_rotate_left_c; + +// mp_rotate_right(_c) +template using mp_rotate_right_c = mp_rotate_left::value, N>>; +template using mp_rotate_right = mp_rotate_right_c; + +// mp_min_element +// mp_max_element +// in detail/mp_min_element.hpp + +// mp_power_set +namespace detail +{ + +template struct mp_power_set_impl; + +} // namespace detail + +template using mp_power_set = typename detail::mp_power_set_impl::type; + +namespace detail +{ + +#if BOOST_MP11_WORKAROUND( BOOST_MP11_MSVC, <= 1800 ) + +template class L, class... T> struct mp_power_set_impl< L > +{ + static_assert( sizeof...(T) == 0, "T... must be empty" ); + using type = L< L<> >; +}; + +#else + +template class L> struct mp_power_set_impl< L<> > +{ + using type = L< L<> >; +}; + +#endif + +template class L, class T1, class... T> struct mp_power_set_impl< L > +{ + using S1 = mp_power_set< L >; + + template using _f = mp_push_front; + + using S2 = mp_transform<_f, S1>; + + using type = mp_append< S1, S2 >; +}; + +} // namespace detail + +// mp_partial_sum +namespace detail +{ + +template class F> struct mp_partial_sum_impl_f +{ +#if BOOST_MP11_WORKAROUND( BOOST_MP11_MSVC, <= 1900 ) + + template using fn = mp_list, T>, mp_push_back, F, T>> >; + +#else + + template, T>> using fn = mp_list, N>>; + +#endif +}; + +} // namespace detail + +template class F> using mp_partial_sum = mp_second>, detail::mp_partial_sum_impl_f> >; +template using mp_partial_sum_q = mp_partial_sum; + +// mp_iterate +namespace detail +{ + +template class F, template class R, class N> struct mp_iterate_impl; + +} // namespace detail + +template class F, template class R> using mp_iterate = typename detail::mp_iterate_impl>::type; + +namespace detail +{ + +template class F, template class R> struct mp_iterate_impl +{ + template using _f = mp_list>; + using type = mp_eval_or, _f, V>; +}; + +template class F, template class R> struct mp_iterate_impl +{ + using type = mp_push_front, F, R>, F>; +}; + +} // namespace detail + +template using mp_iterate_q = mp_iterate; + +// mp_pairwise_fold +namespace detail +{ + +template using mp_pairwise_fold_impl = mp_transform_q, mp_pop_front>; + +} // namespace detail + +template using mp_pairwise_fold_q = mp_eval_if, mp_clear, detail::mp_pairwise_fold_impl, L, Q>; +template class F> using mp_pairwise_fold = mp_pairwise_fold_q>; + +// mp_intersperse +namespace detail +{ + +template struct mp_intersperse_impl +{ +}; + +#if BOOST_MP11_WORKAROUND( BOOST_MP11_MSVC, <= 1800 ) + +template class L, class... T, class S> struct mp_intersperse_impl, S> +{ + static_assert( sizeof...(T) == 0, "T... must be empty" ); + using type = L<>; +}; + +#else + +template class L, class S> struct mp_intersperse_impl, S> +{ + using type = L<>; +}; + +#endif + +template class L, class T1, class... T, class S> struct mp_intersperse_impl, S> +{ + using type = mp_append, L...>; +}; + +} // namespace detail + +template using mp_intersperse = typename detail::mp_intersperse_impl::type; + +// mp_split +namespace detail +{ + +template struct mp_split_impl; + +} // namespace detail + +template using mp_split = typename detail::mp_split_impl>::type; + +namespace detail +{ + +template using mp_split_impl_ = mp_push_front, S>, mp_take>; + +template struct mp_split_impl +{ + using type = mp_eval_if_c::value == J::value, mp_push_back, L>, mp_split_impl_, L, S, J>; +}; + +} // namespace detail + +// mp_join + +template using mp_join = mp_apply>>; + +} // namespace mp11 +} // namespace boost + +#endif // #ifndef BOOST_MP11_ALGORITHM_HPP_INCLUDED diff --git a/include/boost/mp11/bind.hpp b/include/boost/mp11/bind.hpp new file mode 100644 index 000000000..bbdecd220 --- /dev/null +++ b/include/boost/mp11/bind.hpp @@ -0,0 +1,111 @@ +#ifndef BOOST_MP11_BIND_HPP_INCLUDED +#define BOOST_MP11_BIND_HPP_INCLUDED + +// Copyright 2017, 2018 Peter Dimov. +// +// 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 + +#include +#include +#include + +namespace boost +{ +namespace mp11 +{ + +// mp_bind_front +template class F, class... T> struct mp_bind_front +{ + // the indirection through mp_defer works around the language inability + // to expand U... into a fixed parameter list of an alias template + + template using fn = typename mp_defer::type; +}; + +template using mp_bind_front_q = mp_bind_front; + +// mp_bind_back +template class F, class... T> struct mp_bind_back +{ + template using fn = typename mp_defer::type; +}; + +template using mp_bind_back_q = mp_bind_back; + +// mp_arg +template struct mp_arg +{ + template using fn = mp_at_c, I>; +}; + +using _1 = mp_arg<0>; +using _2 = mp_arg<1>; +using _3 = mp_arg<2>; +using _4 = mp_arg<3>; +using _5 = mp_arg<4>; +using _6 = mp_arg<5>; +using _7 = mp_arg<6>; +using _8 = mp_arg<7>; +using _9 = mp_arg<8>; + +// mp_bind +template class F, class... T> struct mp_bind; + +namespace detail +{ + +template struct eval_bound_arg +{ + using type = V; +}; + +template struct eval_bound_arg, T...> +{ + using type = typename mp_arg::template fn; +}; + +template class F, class... U, class... T> struct eval_bound_arg, T...> +{ + using type = typename mp_bind::template fn; +}; + +template class F, class... U, class... T> struct eval_bound_arg, T...> +{ + using type = typename mp_bind_front::template fn; +}; + +template class F, class... U, class... T> struct eval_bound_arg, T...> +{ + using type = typename mp_bind_back::template fn; +}; + +} // namespace detail + +template class F, class... T> struct mp_bind +{ +#if BOOST_MP11_WORKAROUND( BOOST_MP11_MSVC, == 1915 ) +private: + + template struct _f { using type = F::type...>; }; + +public: + + template using fn = typename _f::type; + +#else + + template using fn = F::type...>; + +#endif +}; + +template using mp_bind_q = mp_bind; + +} // namespace mp11 +} // namespace boost + +#endif // #ifndef BOOST_MP11_BIND_HPP_INCLUDED diff --git a/include/boost/mp11/detail/config.hpp b/include/boost/mp11/detail/config.hpp new file mode 100644 index 000000000..44686c73e --- /dev/null +++ b/include/boost/mp11/detail/config.hpp @@ -0,0 +1,149 @@ +#ifndef BOOST_MP11_DETAIL_CONFIG_HPP_INCLUDED +#define BOOST_MP11_DETAIL_CONFIG_HPP_INCLUDED + +// Copyright 2016, 2018, 2019 Peter Dimov. +// +// 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 + +// BOOST_MP11_WORKAROUND + +#if defined( BOOST_STRICT_CONFIG ) || defined( BOOST_MP11_NO_WORKAROUNDS ) + +# define BOOST_MP11_WORKAROUND( symbol, test ) 0 + +#else + +# define BOOST_MP11_WORKAROUND( symbol, test ) ((symbol) != 0 && ((symbol) test)) + +#endif + +// + +#define BOOST_MP11_CUDA 0 +#define BOOST_MP11_CLANG 0 +#define BOOST_MP11_INTEL 0 +#define BOOST_MP11_GCC 0 +#define BOOST_MP11_MSVC 0 + +#define BOOST_MP11_CONSTEXPR constexpr + +#if defined( __CUDACC__ ) + +// nvcc + +# undef BOOST_MP11_CUDA +# define BOOST_MP11_CUDA (__CUDACC_VER_MAJOR__ * 1000000 + __CUDACC_VER_MINOR__ * 10000 + __CUDACC_VER_BUILD__) + +// CUDA (8.0) has no constexpr support in msvc mode: +# if defined(_MSC_VER) && (BOOST_MP11_CUDA < 9000000) + +# define BOOST_MP11_NO_CONSTEXPR + +# undef BOOST_MP11_CONSTEXPR +# define BOOST_MP11_CONSTEXPR + +# endif + +#endif + +#if defined(__clang__) + +// Clang + +# undef BOOST_MP11_CLANG +# define BOOST_MP11_CLANG (__clang_major__ * 100 + __clang_minor__) + +# if defined(__has_cpp_attribute) +# if __has_cpp_attribute(fallthrough) && __cplusplus >= 201406L // Clang 3.9+ in c++1z mode +# define BOOST_MP11_HAS_FOLD_EXPRESSIONS +# endif +# endif + +#if BOOST_MP11_CLANG < 400 && __cplusplus >= 201402L \ + && defined( __GLIBCXX__ ) && !__has_include() + +// Clang pre-4 in C++14 mode, libstdc++ pre-4.9, ::gets is not defined, +// but Clang tries to import it into std + + extern "C" char *gets (char *__s); +#endif + +#elif defined(__INTEL_COMPILER) + +// Intel C++ + +# undef BOOST_MP11_INTEL +# define BOOST_MP11_INTEL __INTEL_COMPILER + +#elif defined(__GNUC__) + +// g++ + +# undef BOOST_MP11_GCC +# define BOOST_MP11_GCC (__GNUC__ * 10000 + __GNUC_MINOR__ * 100 + __GNUC_PATCHLEVEL__) + +#elif defined(_MSC_VER) + +// MS Visual C++ + +# undef BOOST_MP11_MSVC +# define BOOST_MP11_MSVC _MSC_VER + +# if BOOST_MP11_WORKAROUND( BOOST_MP11_MSVC, < 1920 ) +# define BOOST_MP11_NO_CONSTEXPR +# endif + +#if _MSC_FULL_VER < 190024210 // 2015u3 +# undef BOOST_MP11_CONSTEXPR +# define BOOST_MP11_CONSTEXPR +#endif + +#endif + +// BOOST_MP11_HAS_CXX14_CONSTEXPR + +#if !defined(BOOST_MP11_NO_CONSTEXPR) && defined(__cpp_constexpr) && __cpp_constexpr >= 201304 +# define BOOST_MP11_HAS_CXX14_CONSTEXPR +#endif + +// BOOST_MP11_HAS_FOLD_EXPRESSIONS + +#if !defined(BOOST_MP11_HAS_FOLD_EXPRESSIONS) && defined(__cpp_fold_expressions) && __cpp_fold_expressions >= 201603 +# define BOOST_MP11_HAS_FOLD_EXPRESSIONS +#endif + +// BOOST_MP11_HAS_TYPE_PACK_ELEMENT + +#if defined(__has_builtin) +# if __has_builtin(__type_pack_element) +# define BOOST_MP11_HAS_TYPE_PACK_ELEMENT +# endif +#endif + +// BOOST_MP11_HAS_TEMPLATE_AUTO + +#if defined(__cpp_nontype_template_parameter_auto) && __cpp_nontype_template_parameter_auto >= 201606L +# define BOOST_MP11_HAS_TEMPLATE_AUTO +#endif + +#if BOOST_MP11_WORKAROUND( BOOST_MP11_MSVC, < 1920 ) +// mp_value<0> is bool, mp_value<-1L> is int, etc +# undef BOOST_MP11_HAS_TEMPLATE_AUTO +#endif + +// BOOST_MP11_DEPRECATED(msg) + +#if BOOST_MP11_WORKAROUND( BOOST_MP11_CLANG, < 304 ) +# define BOOST_MP11_DEPRECATED(msg) +#elif defined(__GNUC__) || defined(__clang__) +# define BOOST_MP11_DEPRECATED(msg) __attribute__((deprecated(msg))) +#elif defined(_MSC_VER) && _MSC_VER >= 1900 +# define BOOST_MP11_DEPRECATED(msg) [[deprecated(msg)]] +#else +# define BOOST_MP11_DEPRECATED(msg) +#endif + +#endif // #ifndef BOOST_MP11_DETAIL_CONFIG_HPP_INCLUDED diff --git a/include/boost/mp11/detail/mp_append.hpp b/include/boost/mp11/detail/mp_append.hpp new file mode 100644 index 000000000..858ee24e6 --- /dev/null +++ b/include/boost/mp11/detail/mp_append.hpp @@ -0,0 +1,321 @@ +#ifndef BOOST_MP11_DETAIL_MP_APPEND_HPP_INCLUDED +#define BOOST_MP11_DETAIL_MP_APPEND_HPP_INCLUDED + +// Copyright 2015-2017 Peter Dimov. +// +// 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 + +#include +#include +#include +#include +#include +#include + +namespace boost +{ +namespace mp11 +{ + +// mp_append + +namespace detail +{ + +// append_type_lists + +template struct mp_append_impl; + +#if BOOST_MP11_WORKAROUND( BOOST_MP11_MSVC, <= 1800 ) + +template struct mp_append_impl +{ +}; + +template<> struct mp_append_impl<> +{ + using type = mp_list<>; +}; + +template class L, class... T> struct mp_append_impl> +{ + using type = L; +}; + +template class L1, class... T1, template class L2, class... T2> struct mp_append_impl, L2> +{ + using type = L1; +}; + +template class L1, class... T1, template class L2, class... T2, template class L3, class... T3> struct mp_append_impl, L2, L3> +{ + using type = L1; +}; + +template class L1, class... T1, template class L2, class... T2, template class L3, class... T3, template class L4, class... T4> struct mp_append_impl, L2, L3, L4> +{ + using type = L1; +}; + +template class L1, class... T1, template class L2, class... T2, template class L3, class... T3, template class L4, class... T4, template class L5, class... T5, class... Lr> struct mp_append_impl, L2, L3, L4, L5, Lr...> +{ + using type = typename mp_append_impl, Lr...>::type; +}; + +#else + +template, class L2 = mp_list<>, class L3 = mp_list<>, class L4 = mp_list<>, class L5 = mp_list<>, class L6 = mp_list<>, class L7 = mp_list<>, class L8 = mp_list<>, class L9 = mp_list<>, class L10 = mp_list<>, class L11 = mp_list<>> struct append_11_impl +{ +}; + +template< + template class L1, class... T1, + template class L2, class... T2, + template class L3, class... T3, + template class L4, class... T4, + template class L5, class... T5, + template class L6, class... T6, + template class L7, class... T7, + template class L8, class... T8, + template class L9, class... T9, + template class L10, class... T10, + template class L11, class... T11> + +struct append_11_impl, L2, L3, L4, L5, L6, L7, L8, L9, L10, L11> +{ + using type = L1; +}; + +template< + + class L00 = mp_list<>, class L01 = mp_list<>, class L02 = mp_list<>, class L03 = mp_list<>, class L04 = mp_list<>, class L05 = mp_list<>, class L06 = mp_list<>, class L07 = mp_list<>, class L08 = mp_list<>, class L09 = mp_list<>, class L0A = mp_list<>, + class L10 = mp_list<>, class L11 = mp_list<>, class L12 = mp_list<>, class L13 = mp_list<>, class L14 = mp_list<>, class L15 = mp_list<>, class L16 = mp_list<>, class L17 = mp_list<>, class L18 = mp_list<>, class L19 = mp_list<>, + class L20 = mp_list<>, class L21 = mp_list<>, class L22 = mp_list<>, class L23 = mp_list<>, class L24 = mp_list<>, class L25 = mp_list<>, class L26 = mp_list<>, class L27 = mp_list<>, class L28 = mp_list<>, class L29 = mp_list<>, + class L30 = mp_list<>, class L31 = mp_list<>, class L32 = mp_list<>, class L33 = mp_list<>, class L34 = mp_list<>, class L35 = mp_list<>, class L36 = mp_list<>, class L37 = mp_list<>, class L38 = mp_list<>, class L39 = mp_list<>, + class L40 = mp_list<>, class L41 = mp_list<>, class L42 = mp_list<>, class L43 = mp_list<>, class L44 = mp_list<>, class L45 = mp_list<>, class L46 = mp_list<>, class L47 = mp_list<>, class L48 = mp_list<>, class L49 = mp_list<>, + class L50 = mp_list<>, class L51 = mp_list<>, class L52 = mp_list<>, class L53 = mp_list<>, class L54 = mp_list<>, class L55 = mp_list<>, class L56 = mp_list<>, class L57 = mp_list<>, class L58 = mp_list<>, class L59 = mp_list<>, + class L60 = mp_list<>, class L61 = mp_list<>, class L62 = mp_list<>, class L63 = mp_list<>, class L64 = mp_list<>, class L65 = mp_list<>, class L66 = mp_list<>, class L67 = mp_list<>, class L68 = mp_list<>, class L69 = mp_list<>, + class L70 = mp_list<>, class L71 = mp_list<>, class L72 = mp_list<>, class L73 = mp_list<>, class L74 = mp_list<>, class L75 = mp_list<>, class L76 = mp_list<>, class L77 = mp_list<>, class L78 = mp_list<>, class L79 = mp_list<>, + class L80 = mp_list<>, class L81 = mp_list<>, class L82 = mp_list<>, class L83 = mp_list<>, class L84 = mp_list<>, class L85 = mp_list<>, class L86 = mp_list<>, class L87 = mp_list<>, class L88 = mp_list<>, class L89 = mp_list<>, + class L90 = mp_list<>, class L91 = mp_list<>, class L92 = mp_list<>, class L93 = mp_list<>, class L94 = mp_list<>, class L95 = mp_list<>, class L96 = mp_list<>, class L97 = mp_list<>, class L98 = mp_list<>, class L99 = mp_list<>, + class LA0 = mp_list<>, class LA1 = mp_list<>, class LA2 = mp_list<>, class LA3 = mp_list<>, class LA4 = mp_list<>, class LA5 = mp_list<>, class LA6 = mp_list<>, class LA7 = mp_list<>, class LA8 = mp_list<>, class LA9 = mp_list<> + +> struct append_111_impl +{ + using type = typename append_11_impl< + + typename append_11_impl::type, + typename append_11_impl, L10, L11, L12, L13, L14, L15, L16, L17, L18, L19>::type, + typename append_11_impl, L20, L21, L22, L23, L24, L25, L26, L27, L28, L29>::type, + typename append_11_impl, L30, L31, L32, L33, L34, L35, L36, L37, L38, L39>::type, + typename append_11_impl, L40, L41, L42, L43, L44, L45, L46, L47, L48, L49>::type, + typename append_11_impl, L50, L51, L52, L53, L54, L55, L56, L57, L58, L59>::type, + typename append_11_impl, L60, L61, L62, L63, L64, L65, L66, L67, L68, L69>::type, + typename append_11_impl, L70, L71, L72, L73, L74, L75, L76, L77, L78, L79>::type, + typename append_11_impl, L80, L81, L82, L83, L84, L85, L86, L87, L88, L89>::type, + typename append_11_impl, L90, L91, L92, L93, L94, L95, L96, L97, L98, L99>::type, + typename append_11_impl, LA0, LA1, LA2, LA3, LA4, LA5, LA6, LA7, LA8, LA9>::type + + >::type; +}; + +template< + + class L00, class L01, class L02, class L03, class L04, class L05, class L06, class L07, class L08, class L09, class L0A, + class L10, class L11, class L12, class L13, class L14, class L15, class L16, class L17, class L18, class L19, + class L20, class L21, class L22, class L23, class L24, class L25, class L26, class L27, class L28, class L29, + class L30, class L31, class L32, class L33, class L34, class L35, class L36, class L37, class L38, class L39, + class L40, class L41, class L42, class L43, class L44, class L45, class L46, class L47, class L48, class L49, + class L50, class L51, class L52, class L53, class L54, class L55, class L56, class L57, class L58, class L59, + class L60, class L61, class L62, class L63, class L64, class L65, class L66, class L67, class L68, class L69, + class L70, class L71, class L72, class L73, class L74, class L75, class L76, class L77, class L78, class L79, + class L80, class L81, class L82, class L83, class L84, class L85, class L86, class L87, class L88, class L89, + class L90, class L91, class L92, class L93, class L94, class L95, class L96, class L97, class L98, class L99, + class LA0, class LA1, class LA2, class LA3, class LA4, class LA5, class LA6, class LA7, class LA8, class LA9, + class... Lr + +> struct append_inf_impl +{ + using prefix = typename append_111_impl< + + L00, L01, L02, L03, L04, L05, L06, L07, L08, L09, L0A, + L10, L11, L12, L13, L14, L15, L16, L17, L18, L19, + L20, L21, L22, L23, L24, L25, L26, L27, L28, L29, + L30, L31, L32, L33, L34, L35, L36, L37, L38, L39, + L40, L41, L42, L43, L44, L45, L46, L47, L48, L49, + L50, L51, L52, L53, L54, L55, L56, L57, L58, L59, + L60, L61, L62, L63, L64, L65, L66, L67, L68, L69, + L70, L71, L72, L73, L74, L75, L76, L77, L78, L79, + L80, L81, L82, L83, L84, L85, L86, L87, L88, L89, + L90, L91, L92, L93, L94, L95, L96, L97, L98, L99, + LA0, LA1, LA2, LA3, LA4, LA5, LA6, LA7, LA8, LA9 + + >::type; + + using type = typename mp_append_impl::type; +}; + +#if BOOST_MP11_WORKAROUND( BOOST_MP11_CUDA, >= 9000000 && BOOST_MP11_CUDA < 10000000 ) + +template +struct mp_append_impl_cuda_workaround +{ + using type = mp_if_c<(sizeof...(L) > 111), mp_quote, mp_if_c<(sizeof...(L) > 11), mp_quote, mp_quote > >; +}; + +template struct mp_append_impl: mp_append_impl_cuda_workaround::type::template fn +{ +}; + +#else + +template struct mp_append_impl: + mp_cond< + mp_bool<(sizeof...(L) > 111)>, mp_quote, + mp_bool<(sizeof...(L) > 11)>, mp_quote, + mp_true, mp_quote + >::template fn +{ +}; + +#endif // #if BOOST_MP11_WORKAROUND( BOOST_MP11_CUDA, >= 9000000 && BOOST_MP11_CUDA < 10000000 ) + +#endif // #if BOOST_MP11_WORKAROUND( BOOST_MP11_MSVC, <= 1800 ) + +struct append_type_lists +{ + template using fn = typename mp_append_impl::type; +}; + +// append_value_lists + +#if defined(BOOST_MP11_HAS_TEMPLATE_AUTO) + +template struct append_value_impl; + +template, class L2 = mp_list_v<>, class L3 = mp_list_v<>, class L4 = mp_list_v<>, class L5 = mp_list_v<>, class L6 = mp_list_v<>, class L7 = mp_list_v<>, class L8 = mp_list_v<>, class L9 = mp_list_v<>, class L10 = mp_list_v<>, class L11 = mp_list_v<>> struct append_value_11_impl +{ +}; + +template< + template class L1, auto... T1, + template class L2, auto... T2, + template class L3, auto... T3, + template class L4, auto... T4, + template class L5, auto... T5, + template class L6, auto... T6, + template class L7, auto... T7, + template class L8, auto... T8, + template class L9, auto... T9, + template class L10, auto... T10, + template class L11, auto... T11> + +struct append_value_11_impl, L2, L3, L4, L5, L6, L7, L8, L9, L10, L11> +{ + using type = L1; +}; + +template< + + class L00 = mp_list_v<>, class L01 = mp_list_v<>, class L02 = mp_list_v<>, class L03 = mp_list_v<>, class L04 = mp_list_v<>, class L05 = mp_list_v<>, class L06 = mp_list_v<>, class L07 = mp_list_v<>, class L08 = mp_list_v<>, class L09 = mp_list_v<>, class L0A = mp_list_v<>, + class L10 = mp_list_v<>, class L11 = mp_list_v<>, class L12 = mp_list_v<>, class L13 = mp_list_v<>, class L14 = mp_list_v<>, class L15 = mp_list_v<>, class L16 = mp_list_v<>, class L17 = mp_list_v<>, class L18 = mp_list_v<>, class L19 = mp_list_v<>, + class L20 = mp_list_v<>, class L21 = mp_list_v<>, class L22 = mp_list_v<>, class L23 = mp_list_v<>, class L24 = mp_list_v<>, class L25 = mp_list_v<>, class L26 = mp_list_v<>, class L27 = mp_list_v<>, class L28 = mp_list_v<>, class L29 = mp_list_v<>, + class L30 = mp_list_v<>, class L31 = mp_list_v<>, class L32 = mp_list_v<>, class L33 = mp_list_v<>, class L34 = mp_list_v<>, class L35 = mp_list_v<>, class L36 = mp_list_v<>, class L37 = mp_list_v<>, class L38 = mp_list_v<>, class L39 = mp_list_v<>, + class L40 = mp_list_v<>, class L41 = mp_list_v<>, class L42 = mp_list_v<>, class L43 = mp_list_v<>, class L44 = mp_list_v<>, class L45 = mp_list_v<>, class L46 = mp_list_v<>, class L47 = mp_list_v<>, class L48 = mp_list_v<>, class L49 = mp_list_v<>, + class L50 = mp_list_v<>, class L51 = mp_list_v<>, class L52 = mp_list_v<>, class L53 = mp_list_v<>, class L54 = mp_list_v<>, class L55 = mp_list_v<>, class L56 = mp_list_v<>, class L57 = mp_list_v<>, class L58 = mp_list_v<>, class L59 = mp_list_v<>, + class L60 = mp_list_v<>, class L61 = mp_list_v<>, class L62 = mp_list_v<>, class L63 = mp_list_v<>, class L64 = mp_list_v<>, class L65 = mp_list_v<>, class L66 = mp_list_v<>, class L67 = mp_list_v<>, class L68 = mp_list_v<>, class L69 = mp_list_v<>, + class L70 = mp_list_v<>, class L71 = mp_list_v<>, class L72 = mp_list_v<>, class L73 = mp_list_v<>, class L74 = mp_list_v<>, class L75 = mp_list_v<>, class L76 = mp_list_v<>, class L77 = mp_list_v<>, class L78 = mp_list_v<>, class L79 = mp_list_v<>, + class L80 = mp_list_v<>, class L81 = mp_list_v<>, class L82 = mp_list_v<>, class L83 = mp_list_v<>, class L84 = mp_list_v<>, class L85 = mp_list_v<>, class L86 = mp_list_v<>, class L87 = mp_list_v<>, class L88 = mp_list_v<>, class L89 = mp_list_v<>, + class L90 = mp_list_v<>, class L91 = mp_list_v<>, class L92 = mp_list_v<>, class L93 = mp_list_v<>, class L94 = mp_list_v<>, class L95 = mp_list_v<>, class L96 = mp_list_v<>, class L97 = mp_list_v<>, class L98 = mp_list_v<>, class L99 = mp_list_v<>, + class LA0 = mp_list_v<>, class LA1 = mp_list_v<>, class LA2 = mp_list_v<>, class LA3 = mp_list_v<>, class LA4 = mp_list_v<>, class LA5 = mp_list_v<>, class LA6 = mp_list_v<>, class LA7 = mp_list_v<>, class LA8 = mp_list_v<>, class LA9 = mp_list_v<> + +> struct append_value_111_impl +{ + using type = typename append_value_11_impl< + + typename append_value_11_impl::type, + typename append_value_11_impl, L10, L11, L12, L13, L14, L15, L16, L17, L18, L19>::type, + typename append_value_11_impl, L20, L21, L22, L23, L24, L25, L26, L27, L28, L29>::type, + typename append_value_11_impl, L30, L31, L32, L33, L34, L35, L36, L37, L38, L39>::type, + typename append_value_11_impl, L40, L41, L42, L43, L44, L45, L46, L47, L48, L49>::type, + typename append_value_11_impl, L50, L51, L52, L53, L54, L55, L56, L57, L58, L59>::type, + typename append_value_11_impl, L60, L61, L62, L63, L64, L65, L66, L67, L68, L69>::type, + typename append_value_11_impl, L70, L71, L72, L73, L74, L75, L76, L77, L78, L79>::type, + typename append_value_11_impl, L80, L81, L82, L83, L84, L85, L86, L87, L88, L89>::type, + typename append_value_11_impl, L90, L91, L92, L93, L94, L95, L96, L97, L98, L99>::type, + typename append_value_11_impl, LA0, LA1, LA2, LA3, LA4, LA5, LA6, LA7, LA8, LA9>::type + + >::type; +}; + +template< + + class L00, class L01, class L02, class L03, class L04, class L05, class L06, class L07, class L08, class L09, class L0A, + class L10, class L11, class L12, class L13, class L14, class L15, class L16, class L17, class L18, class L19, + class L20, class L21, class L22, class L23, class L24, class L25, class L26, class L27, class L28, class L29, + class L30, class L31, class L32, class L33, class L34, class L35, class L36, class L37, class L38, class L39, + class L40, class L41, class L42, class L43, class L44, class L45, class L46, class L47, class L48, class L49, + class L50, class L51, class L52, class L53, class L54, class L55, class L56, class L57, class L58, class L59, + class L60, class L61, class L62, class L63, class L64, class L65, class L66, class L67, class L68, class L69, + class L70, class L71, class L72, class L73, class L74, class L75, class L76, class L77, class L78, class L79, + class L80, class L81, class L82, class L83, class L84, class L85, class L86, class L87, class L88, class L89, + class L90, class L91, class L92, class L93, class L94, class L95, class L96, class L97, class L98, class L99, + class LA0, class LA1, class LA2, class LA3, class LA4, class LA5, class LA6, class LA7, class LA8, class LA9, + class... Lr + +> struct append_value_inf_impl +{ + using prefix = typename append_value_111_impl< + + L00, L01, L02, L03, L04, L05, L06, L07, L08, L09, L0A, + L10, L11, L12, L13, L14, L15, L16, L17, L18, L19, + L20, L21, L22, L23, L24, L25, L26, L27, L28, L29, + L30, L31, L32, L33, L34, L35, L36, L37, L38, L39, + L40, L41, L42, L43, L44, L45, L46, L47, L48, L49, + L50, L51, L52, L53, L54, L55, L56, L57, L58, L59, + L60, L61, L62, L63, L64, L65, L66, L67, L68, L69, + L70, L71, L72, L73, L74, L75, L76, L77, L78, L79, + L80, L81, L82, L83, L84, L85, L86, L87, L88, L89, + L90, L91, L92, L93, L94, L95, L96, L97, L98, L99, + LA0, LA1, LA2, LA3, LA4, LA5, LA6, LA7, LA8, LA9 + + >::type; + + using type = typename append_value_impl::type; +}; + +template struct append_value_impl: + mp_cond< + mp_bool<(sizeof...(L) > 111)>, mp_quote, + mp_bool<(sizeof...(L) > 11)>, mp_quote, + mp_true, mp_quote + >::template fn +{ +}; + +struct append_value_lists +{ + template using fn = typename append_value_impl::type; +}; + +#endif // #if defined(BOOST_MP11_HAS_TEMPLATE_AUTO) + +} // namespace detail + +#if defined(BOOST_MP11_HAS_TEMPLATE_AUTO) + +template using mp_append = typename mp_if_c<(sizeof...(L) > 0 && sizeof...(L) == mp_count_if, mp_is_value_list>::value), detail::append_value_lists, detail::append_type_lists>::template fn; + +#else + +template using mp_append = detail::append_type_lists::fn; + +#endif + +} // namespace mp11 +} // namespace boost + +#endif // #ifndef BOOST_MP11_DETAIL_MP_APPEND_HPP_INCLUDED diff --git a/include/boost/mp11/detail/mp_copy_if.hpp b/include/boost/mp11/detail/mp_copy_if.hpp new file mode 100644 index 000000000..4edcde090 --- /dev/null +++ b/include/boost/mp11/detail/mp_copy_if.hpp @@ -0,0 +1,48 @@ +#ifndef BOOST_MP11_DETAIL_MP_COPY_IF_HPP_INCLUDED +#define BOOST_MP11_DETAIL_MP_COPY_IF_HPP_INCLUDED + +// Copyright 2015-2019 Peter Dimov. +// +// 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 + +#include +#include +#include +#include + +namespace boost +{ +namespace mp11 +{ + +// mp_copy_if +namespace detail +{ + +template class P> struct mp_copy_if_impl +{ +}; + +template class L, class... T, template class P> struct mp_copy_if_impl, P> +{ +#if BOOST_MP11_WORKAROUND( BOOST_MP11_MSVC, < 1920 ) + template struct _f { using type = mp_if, mp_list, mp_list<>>; }; + using type = mp_append, typename _f::type...>; +#else + template using _f = mp_if, mp_list, mp_list<>>; + using type = mp_append, _f...>; +#endif +}; + +} // namespace detail + +template class P> using mp_copy_if = typename detail::mp_copy_if_impl::type; +template using mp_copy_if_q = mp_copy_if; + +} // namespace mp11 +} // namespace boost + +#endif // #ifndef BOOST_MP11_DETAIL_MP_COPY_IF_HPP_INCLUDED diff --git a/include/boost/mp11/detail/mp_count.hpp b/include/boost/mp11/detail/mp_count.hpp new file mode 100644 index 000000000..37b39ed54 --- /dev/null +++ b/include/boost/mp11/detail/mp_count.hpp @@ -0,0 +1,147 @@ +#ifndef BOOST_MP11_DETAIL_MP_COUNT_HPP_INCLUDED +#define BOOST_MP11_DETAIL_MP_COUNT_HPP_INCLUDED + +// Copyright 2015, 2016 Peter Dimov. +// +// 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 + +#include +#include +#include + +namespace boost +{ +namespace mp11 +{ + +// mp_count +namespace detail +{ + +#if !defined( BOOST_MP11_NO_CONSTEXPR ) + +constexpr std::size_t cx_plus() +{ + return 0; +} + +template constexpr std::size_t cx_plus(T1 t1, T... t) +{ + return static_cast(t1) + cx_plus(t...); +} + +template +constexpr std::size_t cx_plus(T1 t1, T2 t2, T3 t3, T4 t4, T5 t5, T6 t6, T7 t7, T8 t8, T9 t9, T10 t10, T... t) +{ + return static_cast(t1 + t2 + t3 + t4 + t5 + t6 + t7 + t8 + t9 + t10) + cx_plus(t...); +} + +#endif + +template struct mp_count_impl; + +#if defined( BOOST_MP11_HAS_CXX14_CONSTEXPR ) + +template constexpr std::size_t cx_count() +{ + constexpr bool a[] = { false, std::is_same::value... }; + + std::size_t r = 0; + + for( std::size_t i = 1; i < sizeof...(T) + 1; ++i ) + { + r += a[ i ]; + } + + return r; +} + +template class L, class... T, class V> struct mp_count_impl, V> +{ + using type = mp_size_t()>; +}; + +#elif !defined( BOOST_MP11_NO_CONSTEXPR ) + +template class L, class... T, class V> struct mp_count_impl, V> +{ + using type = mp_size_t::value...)>; +}; + +#else + +template class L, class... T, class V> struct mp_count_impl, V> +{ + using type = mp_size_t...>::value>; +}; + +#endif + +} // namespace detail + +template using mp_count = typename detail::mp_count_impl::type; + +// mp_count_if +namespace detail +{ + +template class P> struct mp_count_if_impl; + +#if defined( BOOST_MP11_HAS_CXX14_CONSTEXPR ) && !BOOST_MP11_WORKAROUND( BOOST_MP11_MSVC, < 1930 ) + +template class P, class... T> constexpr std::size_t cx_count_if() +{ + constexpr bool a[] = { false, static_cast( P::value )... }; + + std::size_t r = 0; + + for( std::size_t i = 1; i < sizeof...(T) + 1; ++i ) + { + r += a[ i ]; + } + + return r; +} + +template class L, class... T, template class P> struct mp_count_if_impl, P> +{ + using type = mp_size_t()>; +}; + +#elif !defined( BOOST_MP11_NO_CONSTEXPR ) + +template class L, class... T, template class P> struct mp_count_if_impl, P> +{ + using type = mp_size_t>::value...)>; +}; + +#else + +template class L, class... T, template class P> struct mp_count_if_impl, P> +{ +#if BOOST_MP11_WORKAROUND( BOOST_MP11_MSVC, < 1920 ) + + template struct _f { using type = mp_to_bool>; }; + using type = mp_size_t::type...>::value>; + +#else + + using type = mp_size_t>...>::value>; + +#endif +}; + +#endif + +} // namespace detail + +template class P> using mp_count_if = typename detail::mp_count_if_impl::type; +template using mp_count_if_q = mp_count_if; + +} // namespace mp11 +} // namespace boost + +#endif // #ifndef BOOST_MP11_DETAIL_MP_COUNT_HPP_INCLUDED diff --git a/include/boost/mp11/detail/mp_defer.hpp b/include/boost/mp11/detail/mp_defer.hpp new file mode 100644 index 000000000..9aaca99ea --- /dev/null +++ b/include/boost/mp11/detail/mp_defer.hpp @@ -0,0 +1,119 @@ +#ifndef BOOST_MP11_DETAIL_MP_DEFER_HPP_INCLUDED +#define BOOST_MP11_DETAIL_MP_DEFER_HPP_INCLUDED + +// Copyright 2015-2020, 2023 Peter Dimov +// Distributed under the Boost Software License, Version 1.0. +// https://www.boost.org/LICENSE_1_0.txt + +#include +#include + +namespace boost +{ +namespace mp11 +{ + +// mp_if, mp_if_c +namespace detail +{ + +template struct mp_if_c_impl +{ +}; + +template struct mp_if_c_impl +{ + using type = T; +}; + +template struct mp_if_c_impl +{ + using type = E; +}; + +} // namespace detail + +template using mp_if_c = typename detail::mp_if_c_impl::type; +template using mp_if = typename detail::mp_if_c_impl(C::value), T, E...>::type; + +// mp_valid + +#if BOOST_MP11_WORKAROUND( BOOST_MP11_INTEL, != 0 ) // tested at 1800 + +// contributed by Roland Schulz in https://github.com/boostorg/mp11/issues/17 + +namespace detail +{ + +template using void_t = void; + +template class F, class... T> +struct mp_valid_impl: mp_false {}; + +template class F, class... T> +struct mp_valid_impl>, F, T...>: mp_true {}; + +} // namespace detail + +template class F, class... T> using mp_valid = typename detail::mp_valid_impl; + +#else + +// implementation by Bruno Dutra (by the name is_evaluable) +namespace detail +{ + +template class F, class... T> struct mp_valid_impl +{ + template class G, class = G> static mp_true check(int); + template class> static mp_false check(...); + + using type = decltype(check(0)); +}; + +} // namespace detail + +template class F, class... T> using mp_valid = typename detail::mp_valid_impl::type; + +#endif + +template using mp_valid_q = mp_valid; + +// mp_defer +namespace detail +{ + +template class F, class... T> struct mp_defer_impl +{ + using type = F; +}; + +struct mp_no_type +{ +}; + +#if BOOST_MP11_WORKAROUND( BOOST_MP11_CUDA, >= 9000000 && BOOST_MP11_CUDA < 10000000 ) + +template class F, class... T> struct mp_defer_cuda_workaround +{ + using type = mp_if, detail::mp_defer_impl, detail::mp_no_type>; +}; + +#endif + +} // namespace detail + +#if BOOST_MP11_WORKAROUND( BOOST_MP11_CUDA, >= 9000000 && BOOST_MP11_CUDA < 10000000 ) + +template class F, class... T> using mp_defer = typename detail::mp_defer_cuda_workaround< F, T...>::type; + +#else + +template class F, class... T> using mp_defer = mp_if, detail::mp_defer_impl, detail::mp_no_type>; + +#endif + +} // namespace mp11 +} // namespace boost + +#endif // #ifndef BOOST_MP11_DETAIL_MP_DEFER_HPP_INCLUDED diff --git a/include/boost/mp11/detail/mp_fold.hpp b/include/boost/mp11/detail/mp_fold.hpp new file mode 100644 index 000000000..266d9c18f --- /dev/null +++ b/include/boost/mp11/detail/mp_fold.hpp @@ -0,0 +1,164 @@ +#ifndef BOOST_MP11_DETAIL_MP_FOLD_HPP_INCLUDED +#define BOOST_MP11_DETAIL_MP_FOLD_HPP_INCLUDED + +// Copyright 2015-2017 Peter Dimov. +// +// 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 + +#include +#include + +namespace boost +{ +namespace mp11 +{ + +// mp_fold +namespace detail +{ + +template class F> struct mp_fold_impl +{ +// An error "no type named 'type'" here means that the first argument to mp_fold is not a list +}; + +#if BOOST_MP11_WORKAROUND( BOOST_MP11_MSVC, <= 1800 ) + +template class L, class... T, class V, template class F> struct mp_fold_impl, V, F> +{ + static_assert( sizeof...(T) == 0, "T... must be empty" ); + using type = V; +}; + +#else + +template class L, class V, template class F> struct mp_fold_impl, V, F> +{ + using type = V; +}; + +#endif + +// + +template class F> struct mp_fold_Q1 +{ + template + using fn = F; +}; + +template class F> struct mp_fold_Q2 +{ + template + using fn = F, T2>; +}; + +template class F> struct mp_fold_Q3 +{ + template + using fn = F, T2>, T3>; +}; + +template class F> struct mp_fold_Q4 +{ + template + using fn = F, T2>, T3>, T4>; +}; + +template class F> struct mp_fold_Q5 +{ + template + using fn = F, T2>, T3>, T4>, T5>; +}; + +template class F> struct mp_fold_Q6 +{ + template + using fn = F, T2>, T3>, T4>, T5>, T6>; +}; + +template class F> struct mp_fold_Q7 +{ + template + using fn = F, T2>, T3>, T4>, T5>, T6>, T7>; +}; + +template class F> struct mp_fold_Q8 +{ + template + using fn = F, T2>, T3>, T4>, T5>, T6>, T7>, T8>; +}; + +template class F> struct mp_fold_Q9 +{ + template + using fn = F, T2>, T3>, T4>, T5>, T6>, T7>, T8>, T9>; +}; + +// + +template class L, class T1, class V, template class F> +struct mp_fold_impl, V, F>: mp_defer::template fn, T1> +{ +}; + +template class L, class T1, class T2, class V, template class F> +struct mp_fold_impl, V, F>: mp_defer::template fn, T1, T2> +{ +}; + +template class L, class T1, class T2, class T3, class V, template class F> +struct mp_fold_impl, V, F>: mp_defer::template fn, T1, T2, T3> +{ +}; + +template class L, class T1, class T2, class T3, class T4, class V, template class F> +struct mp_fold_impl, V, F>: mp_defer::template fn, T1, T2, T3, T4> +{ +}; + +template class L, class T1, class T2, class T3, class T4, class T5, class V, template class F> +struct mp_fold_impl, V, F>: mp_defer::template fn, T1, T2, T3, T4, T5> +{ +}; + +template class L, class T1, class T2, class T3, class T4, class T5, class T6, class V, template class F> +struct mp_fold_impl, V, F>: mp_defer::template fn, T1, T2, T3, T4, T5, T6> +{ +}; + +template class L, class T1, class T2, class T3, class T4, class T5, class T6, class T7, class V, template class F> +struct mp_fold_impl, V, F>: mp_defer::template fn, T1, T2, T3, T4, T5, T6, T7> +{ +}; + +template class L, class T1, class T2, class T3, class T4, class T5, class T6, class T7, class T8, class V, template class F> +struct mp_fold_impl, V, F>: mp_defer::template fn, T1, T2, T3, T4, T5, T6, T7, T8> +{ +}; + +template class L, class T1, class T2, class T3, class T4, class T5, class T6, class T7, class T8, class T9, class V, template class F> +struct mp_fold_impl, V, F>: mp_defer::template fn, T1, T2, T3, T4, T5, T6, T7, T8, T9> +{ +}; + +// + +template class L, class T1, class T2, class T3, class T4, class T5, class T6, class T7, class T8, class T9, class T10, class... T, class V, template class F> +struct mp_fold_impl, V, F> +{ + using type = typename mp_fold_impl, F, T2>, T3>, T4>, T5>, T6>, T7>, T8>, T9>, T10>, F>::type; +}; + +} // namespace detail + +template class F> using mp_fold = typename detail::mp_fold_impl::type; +template using mp_fold_q = mp_fold; + +} // namespace mp11 +} // namespace boost + +#endif // #ifndef BOOST_MP11_DETAIL_MP_FOLD_HPP_INCLUDED diff --git a/include/boost/mp11/detail/mp_front.hpp b/include/boost/mp11/detail/mp_front.hpp new file mode 100644 index 000000000..53a73ac32 --- /dev/null +++ b/include/boost/mp11/detail/mp_front.hpp @@ -0,0 +1,50 @@ +#ifndef BOOST_MP11_DETAIL_MP_FRONT_HPP_INCLUDED +#define BOOST_MP11_DETAIL_MP_FRONT_HPP_INCLUDED + +// Copyright 2015-2023 Peter Dimov. +// +// 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 + +#include +#include + +namespace boost +{ +namespace mp11 +{ + +// mp_front +namespace detail +{ + +template struct mp_front_impl +{ +// An error "no type named 'type'" here means that the argument to mp_front +// is either not a list, or is an empty list +}; + +template class L, class T1, class... T> struct mp_front_impl> +{ + using type = T1; +}; + +#if defined(BOOST_MP11_HAS_TEMPLATE_AUTO) + +template class L, auto A1, auto... A> struct mp_front_impl> +{ + using type = mp_value; +}; + +#endif + +} // namespace detail + +template using mp_front = typename detail::mp_front_impl::type; + +} // namespace mp11 +} // namespace boost + +#endif // #ifndef BOOST_MP11_DETAIL_MP_FRONT_HPP_INCLUDED diff --git a/include/boost/mp11/detail/mp_is_list.hpp b/include/boost/mp11/detail/mp_is_list.hpp new file mode 100644 index 000000000..25b378bde --- /dev/null +++ b/include/boost/mp11/detail/mp_is_list.hpp @@ -0,0 +1,39 @@ +#ifndef BOOST_MP11_DETAIL_MP_IS_LIST_HPP_INCLUDED +#define BOOST_MP11_DETAIL_MP_IS_LIST_HPP_INCLUDED + +// Copyright 2015-2019 Peter Dimov. +// +// 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 + +#include + +namespace boost +{ +namespace mp11 +{ + +// mp_is_list +namespace detail +{ + +template struct mp_is_list_impl +{ + using type = mp_false; +}; + +template class L, class... T> struct mp_is_list_impl> +{ + using type = mp_true; +}; + +} // namespace detail + +template using mp_is_list = typename detail::mp_is_list_impl::type; + +} // namespace mp11 +} // namespace boost + +#endif // #ifndef BOOST_MP11_DETAIL_MP_IS_LIST_HPP_INCLUDED diff --git a/include/boost/mp11/detail/mp_is_value_list.hpp b/include/boost/mp11/detail/mp_is_value_list.hpp new file mode 100644 index 000000000..8f94f030c --- /dev/null +++ b/include/boost/mp11/detail/mp_is_value_list.hpp @@ -0,0 +1,41 @@ +#ifndef BOOST_MP11_DETAIL_MP_IS_VALUE_LIST_HPP_INCLUDED +#define BOOST_MP11_DETAIL_MP_IS_VALUE_LIST_HPP_INCLUDED + +// Copyright 2023 Peter Dimov +// Distributed under the Boost Software License, Version 1.0. +// https://www.boost.org/LICENSE_1_0.txt + +#include +#include + +namespace boost +{ +namespace mp11 +{ + +// mp_is_value_list +namespace detail +{ + +template struct mp_is_value_list_impl +{ + using type = mp_false; +}; + +#if defined(BOOST_MP11_HAS_TEMPLATE_AUTO) + +template class L, auto... A> struct mp_is_value_list_impl> +{ + using type = mp_true; +}; + +#endif + +} // namespace detail + +template using mp_is_value_list = typename detail::mp_is_value_list_impl::type; + +} // namespace mp11 +} // namespace boost + +#endif // #ifndef BOOST_MP11_DETAIL_MP_IS_VALUE_LIST_HPP_INCLUDED diff --git a/include/boost/mp11/detail/mp_list.hpp b/include/boost/mp11/detail/mp_list.hpp new file mode 100644 index 000000000..8e8d3e5e9 --- /dev/null +++ b/include/boost/mp11/detail/mp_list.hpp @@ -0,0 +1,24 @@ +#ifndef BOOST_MP11_DETAIL_MP_LIST_HPP_INCLUDED +#define BOOST_MP11_DETAIL_MP_LIST_HPP_INCLUDED + +// Copyright 2015, 2016 Peter Dimov. +// +// 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 + +namespace boost +{ +namespace mp11 +{ + +// mp_list +template struct mp_list +{ +}; + +} // namespace mp11 +} // namespace boost + +#endif // #ifndef BOOST_MP11_DETAIL_MP_LIST_HPP_INCLUDED diff --git a/include/boost/mp11/detail/mp_list_v.hpp b/include/boost/mp11/detail/mp_list_v.hpp new file mode 100644 index 000000000..bc05238a5 --- /dev/null +++ b/include/boost/mp11/detail/mp_list_v.hpp @@ -0,0 +1,27 @@ +#ifndef BOOST_MP11_DETAIL_MP_LIST_V_HPP_INCLUDED +#define BOOST_MP11_DETAIL_MP_LIST_V_HPP_INCLUDED + +// Copyright 2023 Peter Dimov +// Distributed under the Boost Software License, Version 1.0. +// http://www.boost.org/LICENSE_1_0.txt + +#include + +namespace boost +{ +namespace mp11 +{ + +#if defined(BOOST_MP11_HAS_TEMPLATE_AUTO) + +// mp_list_v +template struct mp_list_v +{ +}; + +#endif + +} // namespace mp11 +} // namespace boost + +#endif // #ifndef BOOST_MP11_DETAIL_MP_LIST_V_HPP_INCLUDED diff --git a/include/boost/mp11/detail/mp_map_find.hpp b/include/boost/mp11/detail/mp_map_find.hpp new file mode 100644 index 000000000..2fb70d8e9 --- /dev/null +++ b/include/boost/mp11/detail/mp_map_find.hpp @@ -0,0 +1,87 @@ +#ifndef BOOST_MP11_DETAIL_MP_MAP_FIND_HPP_INCLUDED +#define BOOST_MP11_DETAIL_MP_MAP_FIND_HPP_INCLUDED + +// Copyright 2015 Peter Dimov. +// +// 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 + +#include +#include + +#if BOOST_MP11_WORKAROUND( BOOST_MP11_MSVC, < 1930 ) + +// not exactly good practice, but... +namespace std +{ + template class tuple; +} + +#endif + +namespace boost +{ +namespace mp11 +{ + +// mp_map_find +namespace detail +{ + +#if !BOOST_MP11_WORKAROUND( BOOST_MP11_MSVC, < 1930 ) + +template using mpmf_wrap = mp_identity; +template using mpmf_unwrap = typename T::type; + +#else + +template struct mpmf_tuple {}; + +template struct mpmf_wrap_impl +{ + using type = mp_identity; +}; + +template struct mpmf_wrap_impl< std::tuple > +{ + using type = mp_identity< mpmf_tuple >; +}; + +template using mpmf_wrap = typename mpmf_wrap_impl::type; + +template struct mpmf_unwrap_impl +{ + using type = typename T::type; +}; + +template struct mpmf_unwrap_impl< mp_identity< mpmf_tuple > > +{ + using type = std::tuple; +}; + +template using mpmf_unwrap = typename mpmf_unwrap_impl::type; + +#endif // #if !BOOST_MP11_WORKAROUND( BOOST_MP11_MSVC, < 1930 ) + +template struct mp_map_find_impl; + +template class M, class... T, class K> struct mp_map_find_impl, K> +{ + using U = mp_inherit...>; + + template class L, class... U> static mp_identity> f( mp_identity>* ); + static mp_identity f( ... ); + + using type = mpmf_unwrap< decltype( f( static_cast(0) ) ) >; +}; + +} // namespace detail + +template using mp_map_find = typename detail::mp_map_find_impl::type; + +} // namespace mp11 +} // namespace boost + +#endif // #ifndef BOOST_MP11_DETAIL_MP_MAP_FIND_HPP_INCLUDED diff --git a/include/boost/mp11/detail/mp_min_element.hpp b/include/boost/mp11/detail/mp_min_element.hpp new file mode 100644 index 000000000..55c21acd0 --- /dev/null +++ b/include/boost/mp11/detail/mp_min_element.hpp @@ -0,0 +1,51 @@ +#ifndef BOOST_MP11_DETAIL_MP_MIN_ELEMENT_HPP_INCLUDED +#define BOOST_MP11_DETAIL_MP_MIN_ELEMENT_HPP_INCLUDED + +// Copyright 2015-2017 Peter Dimov. +// +// 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 + +#include +#include +#include + +namespace boost +{ +namespace mp11 +{ + +// mp_min_element +namespace detail +{ + +template class P> struct select_min +{ + template using fn = mp_if, T1, T2>; +}; + +} // namespace detail + +template class P> using mp_min_element = mp_fold_q, mp_first, detail::select_min

>; +template using mp_min_element_q = mp_min_element; + +// mp_max_element +namespace detail +{ + +template class P> struct select_max +{ + template using fn = mp_if, T1, T2>; +}; + +} // namespace detail + +template class P> using mp_max_element = mp_fold_q, mp_first, detail::select_max

>; +template using mp_max_element_q = mp_max_element; + +} // namespace mp11 +} // namespace boost + +#endif // #ifndef BOOST_MP11_DETAIL_MP_MIN_ELEMENT_HPP_INCLUDED diff --git a/include/boost/mp11/detail/mp_plus.hpp b/include/boost/mp11/detail/mp_plus.hpp new file mode 100644 index 000000000..5c9417cd3 --- /dev/null +++ b/include/boost/mp11/detail/mp_plus.hpp @@ -0,0 +1,84 @@ +#ifndef BOOST_MP11_DETAIL_MP_PLUS_HPP_INCLUDED +#define BOOST_MP11_DETAIL_MP_PLUS_HPP_INCLUDED + +// Copyright 2015 Peter Dimov. +// +// 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 + +#include +#include + +namespace boost +{ +namespace mp11 +{ + +// mp_plus +namespace detail +{ + +#if defined( BOOST_MP11_HAS_FOLD_EXPRESSIONS ) && !BOOST_MP11_WORKAROUND( BOOST_MP11_MSVC, != 0 ) && !BOOST_MP11_WORKAROUND( BOOST_MP11_CLANG, != 0 ) + +// msvc fails with parser stack overflow for large sizeof...(T) +// clang exceeds -fbracket-depth, which defaults to 256 + +template struct mp_plus_impl +{ + static const auto _v = (T::value + ... + 0); + using type = std::integral_constant::type, _v>; +}; + +#else + +template struct mp_plus_impl; + +template<> struct mp_plus_impl<> +{ + using type = std::integral_constant; +}; + +#if BOOST_MP11_WORKAROUND( BOOST_MP11_GCC, < 40800 ) + +template struct mp_plus_impl +{ + static const decltype(T1::value + mp_plus_impl::type::value) _v = T1::value + mp_plus_impl::type::value; + using type = std::integral_constant::type, _v>; +}; + +template struct mp_plus_impl +{ + static const + decltype(T1::value + T2::value + T3::value + T4::value + T5::value + T6::value + T7::value + T8::value + T9::value + T10::value + mp_plus_impl::type::value) + _v = T1::value + T2::value + T3::value + T4::value + T5::value + T6::value + T7::value + T8::value + T9::value + T10::value + mp_plus_impl::type::value; + using type = std::integral_constant::type, _v>; +}; + +#else + +template struct mp_plus_impl +{ + static const auto _v = T1::value + mp_plus_impl::type::value; + using type = std::integral_constant::type, _v>; +}; + +template struct mp_plus_impl +{ + static const auto _v = T1::value + T2::value + T3::value + T4::value + T5::value + T6::value + T7::value + T8::value + T9::value + T10::value + mp_plus_impl::type::value; + using type = std::integral_constant::type, _v>; +}; + +#endif + +#endif + +} // namespace detail + +template using mp_plus = typename detail::mp_plus_impl::type; + +} // namespace mp11 +} // namespace boost + +#endif // #ifndef BOOST_MP11_DETAIL_MP_PLUS_HPP_INCLUDED diff --git a/include/boost/mp11/detail/mp_remove_if.hpp b/include/boost/mp11/detail/mp_remove_if.hpp new file mode 100644 index 000000000..9687b4a16 --- /dev/null +++ b/include/boost/mp11/detail/mp_remove_if.hpp @@ -0,0 +1,48 @@ +#ifndef BOOST_MP11_DETAIL_MP_REMOVE_IF_HPP_INCLUDED +#define BOOST_MP11_DETAIL_MP_REMOVE_IF_HPP_INCLUDED + +// Copyright 2015-2019 Peter Dimov. +// +// 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 + +#include +#include +#include +#include + +namespace boost +{ +namespace mp11 +{ + +// mp_remove_if +namespace detail +{ + +template class P> struct mp_remove_if_impl +{ +}; + +template class L, class... T, template class P> struct mp_remove_if_impl, P> +{ +#if BOOST_MP11_WORKAROUND( BOOST_MP11_MSVC, < 1920 ) + template struct _f { using type = mp_if, mp_list<>, mp_list>; }; + using type = mp_append, typename _f::type...>; +#else + template using _f = mp_if, mp_list<>, mp_list>; + using type = mp_append, _f...>; +#endif +}; + +} // namespace detail + +template class P> using mp_remove_if = typename detail::mp_remove_if_impl::type; +template using mp_remove_if_q = mp_remove_if; + +} // namespace mp11 +} // namespace boost + +#endif // #ifndef BOOST_MP11_DETAIL_MP_REMOVE_IF_HPP_INCLUDED diff --git a/include/boost/mp11/detail/mp_rename.hpp b/include/boost/mp11/detail/mp_rename.hpp new file mode 100644 index 000000000..dde8f6f48 --- /dev/null +++ b/include/boost/mp11/detail/mp_rename.hpp @@ -0,0 +1,54 @@ +#ifndef BOOST_MP11_DETAIL_MP_RENAME_HPP_INCLUDED +#define BOOST_MP11_DETAIL_MP_RENAME_HPP_INCLUDED + +// Copyright 2015-2023 Peter Dimov. +// +// 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 + +#include +#include +#include + +namespace boost +{ +namespace mp11 +{ + +// mp_rename +namespace detail +{ + +template class B> struct mp_rename_impl +{ +// An error "no type named 'type'" here means that the first argument to mp_rename is not a list +}; + +template class L, class... T, template class B> struct mp_rename_impl, B>: mp_defer +{ +}; + +#if defined(BOOST_MP11_HAS_TEMPLATE_AUTO) + +template class L, auto... A, template class B> struct mp_rename_impl, B>: mp_defer...> +{ +}; + +#endif + +} // namespace detail + +template class B> using mp_rename = typename detail::mp_rename_impl::type; + +// mp_apply +template class F, class L> using mp_apply = typename detail::mp_rename_impl::type; + +// mp_apply_q +template using mp_apply_q = typename detail::mp_rename_impl::type; + +} // namespace mp11 +} // namespace boost + +#endif // #ifndef BOOST_MP11_DETAIL_MP_RENAME_HPP_INCLUDED diff --git a/include/boost/mp11/detail/mp_value.hpp b/include/boost/mp11/detail/mp_value.hpp new file mode 100644 index 000000000..d0e598250 --- /dev/null +++ b/include/boost/mp11/detail/mp_value.hpp @@ -0,0 +1,25 @@ +#ifndef BOOST_MP11_DETAIL_MP_VALUE_HPP_INCLUDED +#define BOOST_MP11_DETAIL_MP_VALUE_HPP_INCLUDED + +// Copyright 2023 Peter Dimov +// Distributed under the Boost Software License, Version 1.0. +// https://www.boost.org/LICENSE_1_0.txt + +#include +#include + +#if defined(BOOST_MP11_HAS_TEMPLATE_AUTO) + +namespace boost +{ +namespace mp11 +{ + +template using mp_value = std::integral_constant; + +} // namespace mp11 +} // namespace boost + +#endif // #if defined(BOOST_MP11_HAS_TEMPLATE_AUTO) + +#endif // #ifndef BOOST_MP11_DETAIL_MP_VALUE_HPP_INCLUDED diff --git a/include/boost/mp11/detail/mp_void.hpp b/include/boost/mp11/detail/mp_void.hpp new file mode 100644 index 000000000..a7ac7b716 --- /dev/null +++ b/include/boost/mp11/detail/mp_void.hpp @@ -0,0 +1,32 @@ +#ifndef BOOST_MP11_DETAIL_MP_VOID_HPP_INCLUDED +#define BOOST_MP11_DETAIL_MP_VOID_HPP_INCLUDED + +// Copyright 2015-2017 Peter Dimov. +// +// 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 + +namespace boost +{ +namespace mp11 +{ + +// mp_void +namespace detail +{ + +template struct mp_void_impl +{ + using type = void; +}; + +} // namespace detail + +template using mp_void = typename detail::mp_void_impl::type; + +} // namespace mp11 +} // namespace boost + +#endif // #ifndef BOOST_MP11_DETAIL_MP_VOID_HPP_INCLUDED diff --git a/include/boost/mp11/detail/mp_with_index.hpp b/include/boost/mp11/detail/mp_with_index.hpp new file mode 100644 index 000000000..b6932f2d4 --- /dev/null +++ b/include/boost/mp11/detail/mp_with_index.hpp @@ -0,0 +1,385 @@ +#ifndef BOOST_MP11_DETAIL_MP_WITH_INDEX_HPP_INCLUDED +#define BOOST_MP11_DETAIL_MP_WITH_INDEX_HPP_INCLUDED + +// Copyright 2017 Peter Dimov. +// +// 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 + +#include +#include +#include +#include +#include + +#if defined( BOOST_MP11_HAS_CXX14_CONSTEXPR ) +# define BOOST_MP11_CONSTEXPR14 constexpr +#else +# define BOOST_MP11_CONSTEXPR14 +#endif + +#if defined( __GNUC__ ) || defined( __clang__ ) +# define BOOST_MP11_UNREACHABLE_DEFAULT default: __builtin_unreachable(); +#elif defined( _MSC_VER ) +# define BOOST_MP11_UNREACHABLE_DEFAULT default: __assume(false); +#else +# define BOOST_MP11_UNREACHABLE_DEFAULT +#endif + +namespace boost +{ +namespace mp11 +{ + +namespace detail +{ + +template struct mp_with_index_impl_ +{ + template static BOOST_MP11_CONSTEXPR14 decltype(std::declval()(std::declval>())) call( std::size_t i, F && f ) + { + if( i < N / 2 ) + { + return mp_with_index_impl_::template call( i, std::forward(f) ); + } + else + { + return mp_with_index_impl_::template call( i - N/2, std::forward(f) ); + } + } +}; + +template<> struct mp_with_index_impl_<0> +{ +}; + +template<> struct mp_with_index_impl_<1> +{ + template static BOOST_MP11_CONSTEXPR14 decltype(std::declval()(std::declval>())) call( std::size_t /*i*/, F && f ) + { + return std::forward(f)( mp_size_t() ); + } +}; + +template<> struct mp_with_index_impl_<2> +{ + template static BOOST_MP11_CONSTEXPR14 decltype(std::declval()(std::declval>())) call( std::size_t i, F && f ) + { + switch( i ) + { + BOOST_MP11_UNREACHABLE_DEFAULT + case 0: return std::forward(f)( mp_size_t() ); + case 1: return std::forward(f)( mp_size_t() ); + } + } +}; + +template<> struct mp_with_index_impl_<3> +{ + template static BOOST_MP11_CONSTEXPR14 decltype(std::declval()(std::declval>())) call( std::size_t i, F && f ) + { + switch( i ) + { + BOOST_MP11_UNREACHABLE_DEFAULT + case 0: return std::forward(f)( mp_size_t() ); + case 1: return std::forward(f)( mp_size_t() ); + case 2: return std::forward(f)( mp_size_t() ); + } + } +}; + +template<> struct mp_with_index_impl_<4> +{ + template static BOOST_MP11_CONSTEXPR14 decltype(std::declval()(std::declval>())) call( std::size_t i, F && f ) + { + switch( i ) + { + BOOST_MP11_UNREACHABLE_DEFAULT + case 0: return std::forward(f)( mp_size_t() ); + case 1: return std::forward(f)( mp_size_t() ); + case 2: return std::forward(f)( mp_size_t() ); + case 3: return std::forward(f)( mp_size_t() ); + } + } +}; + +template<> struct mp_with_index_impl_<5> +{ + template static BOOST_MP11_CONSTEXPR14 decltype(std::declval()(std::declval>())) call( std::size_t i, F && f ) + { + switch( i ) + { + BOOST_MP11_UNREACHABLE_DEFAULT + case 0: return std::forward(f)( mp_size_t() ); + case 1: return std::forward(f)( mp_size_t() ); + case 2: return std::forward(f)( mp_size_t() ); + case 3: return std::forward(f)( mp_size_t() ); + case 4: return std::forward(f)( mp_size_t() ); + } + } +}; + +template<> struct mp_with_index_impl_<6> +{ + template static BOOST_MP11_CONSTEXPR14 decltype(std::declval()(std::declval>())) call( std::size_t i, F && f ) + { + switch( i ) + { + BOOST_MP11_UNREACHABLE_DEFAULT + case 0: return std::forward(f)( mp_size_t() ); + case 1: return std::forward(f)( mp_size_t() ); + case 2: return std::forward(f)( mp_size_t() ); + case 3: return std::forward(f)( mp_size_t() ); + case 4: return std::forward(f)( mp_size_t() ); + case 5: return std::forward(f)( mp_size_t() ); + } + } +}; + +template<> struct mp_with_index_impl_<7> +{ + template static BOOST_MP11_CONSTEXPR14 decltype(std::declval()(std::declval>())) call( std::size_t i, F && f ) + { + switch( i ) + { + BOOST_MP11_UNREACHABLE_DEFAULT + case 0: return std::forward(f)( mp_size_t() ); + case 1: return std::forward(f)( mp_size_t() ); + case 2: return std::forward(f)( mp_size_t() ); + case 3: return std::forward(f)( mp_size_t() ); + case 4: return std::forward(f)( mp_size_t() ); + case 5: return std::forward(f)( mp_size_t() ); + case 6: return std::forward(f)( mp_size_t() ); + } + } +}; + +template<> struct mp_with_index_impl_<8> +{ + template static BOOST_MP11_CONSTEXPR14 decltype(std::declval()(std::declval>())) call( std::size_t i, F && f ) + { + switch( i ) + { + BOOST_MP11_UNREACHABLE_DEFAULT + case 0: return std::forward(f)( mp_size_t() ); + case 1: return std::forward(f)( mp_size_t() ); + case 2: return std::forward(f)( mp_size_t() ); + case 3: return std::forward(f)( mp_size_t() ); + case 4: return std::forward(f)( mp_size_t() ); + case 5: return std::forward(f)( mp_size_t() ); + case 6: return std::forward(f)( mp_size_t() ); + case 7: return std::forward(f)( mp_size_t() ); + } + } +}; + +template<> struct mp_with_index_impl_<9> +{ + template static BOOST_MP11_CONSTEXPR14 decltype(std::declval()(std::declval>())) call( std::size_t i, F && f ) + { + switch( i ) + { + BOOST_MP11_UNREACHABLE_DEFAULT + case 0: return std::forward(f)( mp_size_t() ); + case 1: return std::forward(f)( mp_size_t() ); + case 2: return std::forward(f)( mp_size_t() ); + case 3: return std::forward(f)( mp_size_t() ); + case 4: return std::forward(f)( mp_size_t() ); + case 5: return std::forward(f)( mp_size_t() ); + case 6: return std::forward(f)( mp_size_t() ); + case 7: return std::forward(f)( mp_size_t() ); + case 8: return std::forward(f)( mp_size_t() ); + } + } +}; + +template<> struct mp_with_index_impl_<10> +{ + template static BOOST_MP11_CONSTEXPR14 decltype(std::declval()(std::declval>())) call( std::size_t i, F && f ) + { + switch( i ) + { + BOOST_MP11_UNREACHABLE_DEFAULT + case 0: return std::forward(f)( mp_size_t() ); + case 1: return std::forward(f)( mp_size_t() ); + case 2: return std::forward(f)( mp_size_t() ); + case 3: return std::forward(f)( mp_size_t() ); + case 4: return std::forward(f)( mp_size_t() ); + case 5: return std::forward(f)( mp_size_t() ); + case 6: return std::forward(f)( mp_size_t() ); + case 7: return std::forward(f)( mp_size_t() ); + case 8: return std::forward(f)( mp_size_t() ); + case 9: return std::forward(f)( mp_size_t() ); + } + } +}; + +template<> struct mp_with_index_impl_<11> +{ + template static BOOST_MP11_CONSTEXPR14 decltype(std::declval()(std::declval>())) call( std::size_t i, F && f ) + { + switch( i ) + { + BOOST_MP11_UNREACHABLE_DEFAULT + case 0: return std::forward(f)( mp_size_t() ); + case 1: return std::forward(f)( mp_size_t() ); + case 2: return std::forward(f)( mp_size_t() ); + case 3: return std::forward(f)( mp_size_t() ); + case 4: return std::forward(f)( mp_size_t() ); + case 5: return std::forward(f)( mp_size_t() ); + case 6: return std::forward(f)( mp_size_t() ); + case 7: return std::forward(f)( mp_size_t() ); + case 8: return std::forward(f)( mp_size_t() ); + case 9: return std::forward(f)( mp_size_t() ); + case 10: return std::forward(f)( mp_size_t() ); + } + } +}; + +template<> struct mp_with_index_impl_<12> +{ + template static BOOST_MP11_CONSTEXPR14 decltype(std::declval()(std::declval>())) call( std::size_t i, F && f ) + { + switch( i ) + { + BOOST_MP11_UNREACHABLE_DEFAULT + case 0: return std::forward(f)( mp_size_t() ); + case 1: return std::forward(f)( mp_size_t() ); + case 2: return std::forward(f)( mp_size_t() ); + case 3: return std::forward(f)( mp_size_t() ); + case 4: return std::forward(f)( mp_size_t() ); + case 5: return std::forward(f)( mp_size_t() ); + case 6: return std::forward(f)( mp_size_t() ); + case 7: return std::forward(f)( mp_size_t() ); + case 8: return std::forward(f)( mp_size_t() ); + case 9: return std::forward(f)( mp_size_t() ); + case 10: return std::forward(f)( mp_size_t() ); + case 11: return std::forward(f)( mp_size_t() ); + } + } +}; + +template<> struct mp_with_index_impl_<13> +{ + template static BOOST_MP11_CONSTEXPR14 decltype(std::declval()(std::declval>())) call( std::size_t i, F && f ) + { + switch( i ) + { + BOOST_MP11_UNREACHABLE_DEFAULT + case 0: return std::forward(f)( mp_size_t() ); + case 1: return std::forward(f)( mp_size_t() ); + case 2: return std::forward(f)( mp_size_t() ); + case 3: return std::forward(f)( mp_size_t() ); + case 4: return std::forward(f)( mp_size_t() ); + case 5: return std::forward(f)( mp_size_t() ); + case 6: return std::forward(f)( mp_size_t() ); + case 7: return std::forward(f)( mp_size_t() ); + case 8: return std::forward(f)( mp_size_t() ); + case 9: return std::forward(f)( mp_size_t() ); + case 10: return std::forward(f)( mp_size_t() ); + case 11: return std::forward(f)( mp_size_t() ); + case 12: return std::forward(f)( mp_size_t() ); + } + } +}; + +template<> struct mp_with_index_impl_<14> +{ + template static BOOST_MP11_CONSTEXPR14 decltype(std::declval()(std::declval>())) call( std::size_t i, F && f ) + { + switch( i ) + { + BOOST_MP11_UNREACHABLE_DEFAULT + case 0: return std::forward(f)( mp_size_t() ); + case 1: return std::forward(f)( mp_size_t() ); + case 2: return std::forward(f)( mp_size_t() ); + case 3: return std::forward(f)( mp_size_t() ); + case 4: return std::forward(f)( mp_size_t() ); + case 5: return std::forward(f)( mp_size_t() ); + case 6: return std::forward(f)( mp_size_t() ); + case 7: return std::forward(f)( mp_size_t() ); + case 8: return std::forward(f)( mp_size_t() ); + case 9: return std::forward(f)( mp_size_t() ); + case 10: return std::forward(f)( mp_size_t() ); + case 11: return std::forward(f)( mp_size_t() ); + case 12: return std::forward(f)( mp_size_t() ); + case 13: return std::forward(f)( mp_size_t() ); + } + } +}; + +template<> struct mp_with_index_impl_<15> +{ + template static BOOST_MP11_CONSTEXPR14 decltype(std::declval()(std::declval>())) call( std::size_t i, F && f ) + { + switch( i ) + { + BOOST_MP11_UNREACHABLE_DEFAULT + case 0: return std::forward(f)( mp_size_t() ); + case 1: return std::forward(f)( mp_size_t() ); + case 2: return std::forward(f)( mp_size_t() ); + case 3: return std::forward(f)( mp_size_t() ); + case 4: return std::forward(f)( mp_size_t() ); + case 5: return std::forward(f)( mp_size_t() ); + case 6: return std::forward(f)( mp_size_t() ); + case 7: return std::forward(f)( mp_size_t() ); + case 8: return std::forward(f)( mp_size_t() ); + case 9: return std::forward(f)( mp_size_t() ); + case 10: return std::forward(f)( mp_size_t() ); + case 11: return std::forward(f)( mp_size_t() ); + case 12: return std::forward(f)( mp_size_t() ); + case 13: return std::forward(f)( mp_size_t() ); + case 14: return std::forward(f)( mp_size_t() ); + } + } +}; + +template<> struct mp_with_index_impl_<16> +{ + template static BOOST_MP11_CONSTEXPR14 decltype(std::declval()(std::declval>())) call( std::size_t i, F && f ) + { + switch( i ) + { + BOOST_MP11_UNREACHABLE_DEFAULT + case 0: return std::forward(f)( mp_size_t() ); + case 1: return std::forward(f)( mp_size_t() ); + case 2: return std::forward(f)( mp_size_t() ); + case 3: return std::forward(f)( mp_size_t() ); + case 4: return std::forward(f)( mp_size_t() ); + case 5: return std::forward(f)( mp_size_t() ); + case 6: return std::forward(f)( mp_size_t() ); + case 7: return std::forward(f)( mp_size_t() ); + case 8: return std::forward(f)( mp_size_t() ); + case 9: return std::forward(f)( mp_size_t() ); + case 10: return std::forward(f)( mp_size_t() ); + case 11: return std::forward(f)( mp_size_t() ); + case 12: return std::forward(f)( mp_size_t() ); + case 13: return std::forward(f)( mp_size_t() ); + case 14: return std::forward(f)( mp_size_t() ); + case 15: return std::forward(f)( mp_size_t() ); + } + } +}; + +} // namespace detail + +template inline BOOST_MP11_CONSTEXPR14 decltype(std::declval()(std::declval>())) mp_with_index( std::size_t i, F && f ) +{ + assert( i < N ); + return detail::mp_with_index_impl_::template call<0>( i, std::forward(f) ); +} + +template inline BOOST_MP11_CONSTEXPR14 decltype(std::declval()(std::declval>())) mp_with_index( std::size_t i, F && f ) +{ + return mp_with_index( i, std::forward(f) ); +} + +#undef BOOST_MP11_CONSTEXPR14 +#undef BOOST_MP11_UNREACHABLE_DEFAULT + +} // namespace mp11 +} // namespace boost + +#endif // #ifndef BOOST_MP11_DETAIL_MP_WITH_INDEX_HPP_INCLUDED diff --git a/include/boost/mp11/detail/mpl_common.hpp b/include/boost/mp11/detail/mpl_common.hpp new file mode 100644 index 000000000..208885cbd --- /dev/null +++ b/include/boost/mp11/detail/mpl_common.hpp @@ -0,0 +1,160 @@ +#ifndef BOOST_MP11_DETAIL_MPL_COMMON_HPP_INCLUDED +#define BOOST_MP11_DETAIL_MPL_COMMON_HPP_INCLUDED + +// Copyright 2017, 2019 Peter Dimov. +// +// 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 + +#include +#include + +namespace boost +{ +namespace mpl +{ + +struct forward_iterator_tag; + +namespace aux +{ + +struct mp11_tag {}; + +template struct mp11_iterator +{ + using category = forward_iterator_tag; + + using type = mp11::mp_first; + using next = mp11_iterator>; +}; + +} // namespace aux + +// at + +template< typename Tag > struct at_impl; + +template<> struct at_impl +{ + template struct apply + { + using type = mp11::mp_at; + }; +}; + +// back + +template< typename Tag > struct back_impl; + +template<> struct back_impl +{ + template struct apply + { + using N = mp11::mp_size; + using type = mp11::mp_at_c; + }; +}; + +// begin + +template< typename Tag > struct begin_impl; + +template<> struct begin_impl +{ + template struct apply + { + using type = aux::mp11_iterator; + }; +}; + +// clear + +template< typename Tag > struct clear_impl; + +template<> struct clear_impl +{ + template struct apply + { + using type = mp11::mp_clear; + }; +}; + +// end + +template< typename Tag > struct end_impl; + +template<> struct end_impl +{ + template struct apply + { + using type = aux::mp11_iterator>; + }; +}; + +// front + +template< typename Tag > struct front_impl; + +template<> struct front_impl +{ + template struct apply + { + using type = mp11::mp_front; + }; +}; + +// pop_front + +template< typename Tag > struct pop_front_impl; + +template<> struct pop_front_impl +{ + template struct apply + { + using type = mp11::mp_pop_front; + }; +}; + +// push_back + +template< typename Tag > struct push_back_impl; + +template<> struct push_back_impl +{ + template struct apply + { + using type = mp11::mp_push_back; + }; +}; + +// push_front + +template< typename Tag > struct push_front_impl; + +template<> struct push_front_impl +{ + template struct apply + { + using type = mp11::mp_push_front; + }; +}; + +// size + +template< typename Tag > struct size_impl; + +template<> struct size_impl +{ + template struct apply + { + using type = mp11::mp_size; + }; +}; + +} // namespace mpl +} // namespace boost + +#endif // #ifndef BOOST_MP11_DETAIL_MPL_COMMON_HPP_INCLUDED diff --git a/include/boost/mp11/function.hpp b/include/boost/mp11/function.hpp new file mode 100644 index 000000000..e20b45200 --- /dev/null +++ b/include/boost/mp11/function.hpp @@ -0,0 +1,222 @@ +#ifndef BOOST_MP11_FUNCTION_HPP_INCLUDED +#define BOOST_MP11_FUNCTION_HPP_INCLUDED + +// Copyright 2015-2019 Peter Dimov. +// +// 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 + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +namespace boost +{ +namespace mp11 +{ + +// mp_void +// in detail/mp_void.hpp + +// mp_and +#if BOOST_MP11_WORKAROUND( BOOST_MP11_MSVC, < 1910 ) + +namespace detail +{ + +template struct mp_and_impl; + +} // namespace detail + +template using mp_and = mp_to_bool< typename detail::mp_and_impl::type >; + +namespace detail +{ + +template<> struct mp_and_impl<> +{ + using type = mp_true; +}; + +template struct mp_and_impl +{ + using type = T; +}; + +template struct mp_and_impl +{ + using type = mp_eval_if< mp_not, T1, mp_and, T... >; +}; + +} // namespace detail + +#else + +namespace detail +{ + +template struct mp_and_impl +{ + using type = mp_false; +}; + +template struct mp_and_impl< mp_list, mp_void...> > +{ + using type = mp_true; +}; + +} // namespace detail + +template using mp_and = typename detail::mp_and_impl>::type; + +#endif + +// mp_all +// https://gcc.gnu.org/bugzilla/show_bug.cgi?id=86355 +#if BOOST_MP11_WORKAROUND( BOOST_MP11_MSVC, < 1920 ) || BOOST_MP11_WORKAROUND( BOOST_MP11_GCC, != 0 ) + +template using mp_all = mp_bool< mp_count_if< mp_list, mp_not >::value == 0 >; + +#else + +template using mp_all = mp_bool< mp_count< mp_list...>, mp_false >::value == 0 >; + +#endif + +// mp_or +namespace detail +{ + +template struct mp_or_impl; + +} // namespace detail + +template using mp_or = mp_to_bool< typename detail::mp_or_impl::type >; + +namespace detail +{ + +template<> struct mp_or_impl<> +{ + using type = mp_false; +}; + +template struct mp_or_impl +{ + using type = T; +}; + +template struct mp_or_impl +{ + using type = mp_eval_if< T1, T1, mp_or, T... >; +}; + +} // namespace detail + +// mp_any +// https://gcc.gnu.org/bugzilla/show_bug.cgi?id=86356 +#if BOOST_MP11_WORKAROUND( BOOST_MP11_MSVC, < 1920 ) || BOOST_MP11_WORKAROUND( BOOST_MP11_GCC, != 0 ) + +template using mp_any = mp_bool< mp_count_if< mp_list, mp_to_bool >::value != 0 >; + +#else + +template using mp_any = mp_bool< mp_count< mp_list...>, mp_true >::value != 0 >; + +#endif + +// mp_same +namespace detail +{ + +template struct mp_same_impl; + +template<> struct mp_same_impl<> +{ + using type = mp_true; +}; + +template struct mp_same_impl +{ + using type = mp_bool< mp_count, T1>::value == sizeof...(T) >; +}; + +} // namespace detail + +template using mp_same = typename detail::mp_same_impl::type; + +// mp_similar +namespace detail +{ + +template struct mp_similar_impl; + +template<> struct mp_similar_impl<> +{ + using type = mp_true; +}; + +template struct mp_similar_impl +{ + using type = mp_true; +}; + +template struct mp_similar_impl +{ + using type = mp_true; +}; + +template struct mp_similar_impl +{ + using type = mp_false; +}; + +template class L, class... T1, class... T2> struct mp_similar_impl, L> +{ + using type = mp_true; +}; + +template class L, class... T> struct mp_similar_impl, L> +{ + using type = mp_true; +}; + +template struct mp_similar_impl +{ + using type = mp_all< typename mp_similar_impl::type, typename mp_similar_impl::type, typename mp_similar_impl::type... >; +}; + +} // namespace detail + +template using mp_similar = typename detail::mp_similar_impl::type; + +#if BOOST_MP11_GCC +# pragma GCC diagnostic push +# pragma GCC diagnostic ignored "-Wsign-compare" +#endif + +// mp_less +template using mp_less = mp_bool<(T1::value < 0 && T2::value >= 0) || ((T1::value < T2::value) && !(T1::value >= 0 && T2::value < 0))>; + +#if BOOST_MP11_GCC +# pragma GCC diagnostic pop +#endif + +// mp_min +template using mp_min = mp_min_element, mp_less>; + +// mp_max +template using mp_max = mp_max_element, mp_less>; + +} // namespace mp11 +} // namespace boost + +#endif // #ifndef BOOST_MP11_FUNCTION_HPP_INCLUDED diff --git a/include/boost/mp11/integer_sequence.hpp b/include/boost/mp11/integer_sequence.hpp new file mode 100644 index 000000000..83e24501b --- /dev/null +++ b/include/boost/mp11/integer_sequence.hpp @@ -0,0 +1,112 @@ +#ifndef BOOST_MP11_INTEGER_SEQUENCE_HPP_INCLUDED +#define BOOST_MP11_INTEGER_SEQUENCE_HPP_INCLUDED + +// Copyright 2015, 2017, 2019 Peter Dimov. +// +// 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 + +#include +#include + +#if defined(__has_builtin) +# if __has_builtin(__make_integer_seq) +# define BOOST_MP11_HAS_MAKE_INTEGER_SEQ +# endif +#endif + +namespace boost +{ +namespace mp11 +{ + +// integer_sequence +template struct integer_sequence +{ +}; + +#if defined(BOOST_MP11_HAS_MAKE_INTEGER_SEQ) + +template using make_integer_sequence = __make_integer_seq; + +#else + +// detail::make_integer_sequence_impl +namespace detail +{ + +// iseq_if_c +template struct iseq_if_c_impl; + +template struct iseq_if_c_impl +{ + using type = T; +}; + +template struct iseq_if_c_impl +{ + using type = E; +}; + +template using iseq_if_c = typename iseq_if_c_impl::type; + +// iseq_identity +template struct iseq_identity +{ + using type = T; +}; + +template struct append_integer_sequence; + +template struct append_integer_sequence, integer_sequence> +{ + using type = integer_sequence< T, I..., ( J + sizeof...(I) )... >; +}; + +template struct make_integer_sequence_impl; + +template struct make_integer_sequence_impl_ +{ +private: + + static_assert( N >= 0, "make_integer_sequence: N must not be negative" ); + + static T const M = N / 2; + static T const R = N % 2; + + using S1 = typename make_integer_sequence_impl::type; + using S2 = typename append_integer_sequence::type; + using S3 = typename make_integer_sequence_impl::type; + using S4 = typename append_integer_sequence::type; + +public: + + using type = S4; +}; + +template struct make_integer_sequence_impl: iseq_if_c>, iseq_if_c>, make_integer_sequence_impl_ > > +{ +}; + +} // namespace detail + +// make_integer_sequence +template using make_integer_sequence = typename detail::make_integer_sequence_impl::type; + +#endif // defined(BOOST_MP11_HAS_MAKE_INTEGER_SEQ) + +// index_sequence +template using index_sequence = integer_sequence; + +// make_index_sequence +template using make_index_sequence = make_integer_sequence; + +// index_sequence_for +template using index_sequence_for = make_integer_sequence; + +} // namespace mp11 +} // namespace boost + +#endif // #ifndef BOOST_MP11_INTEGER_SEQUENCE_HPP_INCLUDED diff --git a/include/boost/mp11/integral.hpp b/include/boost/mp11/integral.hpp new file mode 100644 index 000000000..1b4fea3e2 --- /dev/null +++ b/include/boost/mp11/integral.hpp @@ -0,0 +1,42 @@ +#ifndef BOOST_MP11_INTEGRAL_HPP_INCLUDED +#define BOOST_MP11_INTEGRAL_HPP_INCLUDED + +// Copyright 2015 Peter Dimov. +// +// 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 + +#include +#include +#include +#include + +namespace boost +{ +namespace mp11 +{ + +// mp_bool +template using mp_bool = std::integral_constant; + +using mp_true = mp_bool; +using mp_false = mp_bool; + +// mp_to_bool +template using mp_to_bool = mp_bool( T::value )>; + +// mp_not +template using mp_not = mp_bool< !T::value >; + +// mp_int +template using mp_int = std::integral_constant; + +// mp_size_t +template using mp_size_t = std::integral_constant; + +} // namespace mp11 +} // namespace boost + +#endif // #ifndef BOOST_MP11_INTEGRAL_HPP_INCLUDED diff --git a/include/boost/mp11/list.hpp b/include/boost/mp11/list.hpp new file mode 100644 index 000000000..364676445 --- /dev/null +++ b/include/boost/mp11/list.hpp @@ -0,0 +1,472 @@ +#ifndef BOOST_MP11_LIST_HPP_INCLUDED +#define BOOST_MP11_LIST_HPP_INCLUDED + +// Copyright 2015-2023 Peter Dimov. +// +// 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 + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +namespace boost +{ +namespace mp11 +{ + +// mp_list +// in detail/mp_list.hpp + +// mp_list_c +template using mp_list_c = mp_list...>; + +// mp_list_v +// in detail/mp_list_v.hpp + +// mp_is_list +// in detail/mp_is_list.hpp + +// mp_is_value_list +// in detail/mp_is_value_list.hpp + +// mp_size +namespace detail +{ + +template struct mp_size_impl +{ +// An error "no type named 'type'" here means that the argument to mp_size is not a list +}; + +template class L, class... T> struct mp_size_impl> +{ + using type = mp_size_t; +}; + +#if defined(BOOST_MP11_HAS_TEMPLATE_AUTO) + +template class L, auto... A> struct mp_size_impl> +{ + using type = mp_size_t; +}; + +#endif + +} // namespace detail + +template using mp_size = typename detail::mp_size_impl::type; + +// mp_empty +template using mp_empty = mp_bool< mp_size::value == 0 >; + +// mp_assign +namespace detail +{ + +template struct mp_assign_impl +{ +// An error "no type named 'type'" here means that the arguments to mp_assign aren't lists +}; + +template class L1, class... T, template class L2, class... U> struct mp_assign_impl, L2> +{ + using type = L1; +}; + +#if defined(BOOST_MP11_HAS_TEMPLATE_AUTO) + +template class L1, auto... A, template class L2, class... U> struct mp_assign_impl, L2> +{ + using type = L1; +}; + +template class L1, class... T, template class L2, auto... B> struct mp_assign_impl, L2> +{ + using type = L1...>; +}; + +template class L1, auto... A, template class L2, auto... B> struct mp_assign_impl, L2> +{ + using type = L1; +}; + +#endif + +} // namespace detail + +template using mp_assign = typename detail::mp_assign_impl::type; + +// mp_clear +template using mp_clear = mp_assign>; + +// mp_front +// in detail/mp_front.hpp + +// mp_pop_front +namespace detail +{ + +template struct mp_pop_front_impl +{ +// An error "no type named 'type'" here means that the argument to mp_pop_front +// is either not a list, or is an empty list +}; + +template class L, class T1, class... T> struct mp_pop_front_impl> +{ + using type = L; +}; + +#if defined(BOOST_MP11_HAS_TEMPLATE_AUTO) + +template class L, auto A1, auto... A> struct mp_pop_front_impl> +{ + using type = L; +}; + +#endif + +} // namespace detail + +template using mp_pop_front = typename detail::mp_pop_front_impl::type; + +// mp_first +template using mp_first = mp_front; + +// mp_rest +template using mp_rest = mp_pop_front; + +// mp_second +namespace detail +{ + +template struct mp_second_impl +{ +// An error "no type named 'type'" here means that the argument to mp_second +// is either not a list, or has fewer than two elements +}; + +template class L, class T1, class T2, class... T> struct mp_second_impl> +{ + using type = T2; +}; + +#if defined(BOOST_MP11_HAS_TEMPLATE_AUTO) + +template class L, auto A1, auto A2, auto... A> struct mp_second_impl> +{ + using type = mp_value; +}; + +#endif + +} // namespace detail + +template using mp_second = typename detail::mp_second_impl::type; + +// mp_third +namespace detail +{ + +template struct mp_third_impl +{ +// An error "no type named 'type'" here means that the argument to mp_third +// is either not a list, or has fewer than three elements +}; + +template class L, class T1, class T2, class T3, class... T> struct mp_third_impl> +{ + using type = T3; +}; + +#if defined(BOOST_MP11_HAS_TEMPLATE_AUTO) + +template class L, auto A1, auto A2, auto A3, auto... A> struct mp_third_impl> +{ + using type = mp_value; +}; + +#endif + +} // namespace detail + +template using mp_third = typename detail::mp_third_impl::type; + +// mp_push_front +namespace detail +{ + +template struct mp_push_front_impl +{ +// An error "no type named 'type'" here means that the first argument to mp_push_front is not a list +}; + +template class L, class... U, class... T> struct mp_push_front_impl, T...> +{ + using type = L; +}; + +#if defined(BOOST_MP11_HAS_TEMPLATE_AUTO) + +template class L, auto... A, class... T> struct mp_push_front_impl, T...> +{ + using type = L; +}; + +#endif + +} // namespace detail + +template using mp_push_front = typename detail::mp_push_front_impl::type; + +// mp_push_back +namespace detail +{ + +template struct mp_push_back_impl +{ +// An error "no type named 'type'" here means that the first argument to mp_push_back is not a list +}; + +template class L, class... U, class... T> struct mp_push_back_impl, T...> +{ + using type = L; +}; + +#if defined(BOOST_MP11_HAS_TEMPLATE_AUTO) + +template class L, auto... A, class... T> struct mp_push_back_impl, T...> +{ + using type = L; +}; + +#endif + +} // namespace detail + +template using mp_push_back = typename detail::mp_push_back_impl::type; + +// mp_rename +// mp_apply +// mp_apply_q +// in detail/mp_rename.hpp + +// mp_rename_v +#if defined(BOOST_MP11_HAS_TEMPLATE_AUTO) + +namespace detail +{ + +template class B> struct mp_rename_v_impl +{ +// An error "no type named 'type'" here means that the first argument to mp_rename_v is not a list +}; + +template class L, class... T, template class B> struct mp_rename_v_impl, B> +{ + using type = B; +}; + +template class L, auto... A, template class B> struct mp_rename_v_impl, B> +{ + using type = B; +}; + +} // namespace detail + +template class B> using mp_rename_v = typename detail::mp_rename_v_impl::type; + +#endif + +// mp_replace_front +namespace detail +{ + +template struct mp_replace_front_impl +{ +// An error "no type named 'type'" here means that the first argument to mp_replace_front +// is either not a list, or is an empty list +}; + +template class L, class U1, class... U, class T> struct mp_replace_front_impl, T> +{ + using type = L; +}; + +#if defined(BOOST_MP11_HAS_TEMPLATE_AUTO) + +template class L, auto A1, auto... A, class T> struct mp_replace_front_impl, T> +{ + using type = L; +}; + +#endif + +} // namespace detail + +template using mp_replace_front = typename detail::mp_replace_front_impl::type; + +// mp_replace_first +template using mp_replace_first = typename detail::mp_replace_front_impl::type; + +// mp_replace_second +namespace detail +{ + +template struct mp_replace_second_impl +{ +// An error "no type named 'type'" here means that the first argument to mp_replace_second +// is either not a list, or has fewer than two elements +}; + +template class L, class U1, class U2, class... U, class T> struct mp_replace_second_impl, T> +{ + using type = L; +}; + +#if defined(BOOST_MP11_HAS_TEMPLATE_AUTO) + +template class L, auto A1, auto A2, auto... A, class T> struct mp_replace_second_impl, T> +{ + using type = L; +}; + +#endif + +} // namespace detail + +template using mp_replace_second = typename detail::mp_replace_second_impl::type; + +// mp_replace_third +namespace detail +{ + +template struct mp_replace_third_impl +{ +// An error "no type named 'type'" here means that the first argument to mp_replace_third +// is either not a list, or has fewer than three elements +}; + +template class L, class U1, class U2, class U3, class... U, class T> struct mp_replace_third_impl, T> +{ + using type = L; +}; + +#if defined(BOOST_MP11_HAS_TEMPLATE_AUTO) + +template class L, auto A1, auto A2, auto A3, auto... A, class T> struct mp_replace_third_impl, T> +{ + using type = L; +}; + +#endif + +} // namespace detail + +template using mp_replace_third = typename detail::mp_replace_third_impl::type; + +// mp_transform_front +namespace detail +{ + +template class F> struct mp_transform_front_impl +{ +// An error "no type named 'type'" here means that the first argument to mp_transform_front +// is either not a list, or is an empty list +}; + +template class L, class U1, class... U, template class F> struct mp_transform_front_impl, F> +{ + using type = L, U...>; +}; + +#if defined(BOOST_MP11_HAS_TEMPLATE_AUTO) + +template class L, auto A1, auto... A, template class F> struct mp_transform_front_impl, F> +{ + using type = L>::value, A...>; +}; + +#endif + +} // namespace detail + +template class F> using mp_transform_front = typename detail::mp_transform_front_impl::type; +template using mp_transform_front_q = mp_transform_front; + +// mp_transform_first +template class F> using mp_transform_first = typename detail::mp_transform_front_impl::type; +template using mp_transform_first_q = mp_transform_first; + +// mp_transform_second +namespace detail +{ + +template class F> struct mp_transform_second_impl +{ +// An error "no type named 'type'" here means that the first argument to mp_transform_second +// is either not a list, or has fewer than two elements +}; + +template class L, class U1, class U2, class... U, template class F> struct mp_transform_second_impl, F> +{ + using type = L, U...>; +}; + +#if defined(BOOST_MP11_HAS_TEMPLATE_AUTO) + +template class L, auto A1, auto A2, auto... A, template class F> struct mp_transform_second_impl, F> +{ + using type = L>::value, A...>; +}; + +#endif + +} // namespace detail + +template class F> using mp_transform_second = typename detail::mp_transform_second_impl::type; +template using mp_transform_second_q = mp_transform_second; + +// mp_transform_third +namespace detail +{ + +template class F> struct mp_transform_third_impl +{ +// An error "no type named 'type'" here means that the first argument to mp_transform_third +// is either not a list, or has fewer than three elements +}; + +template class L, class U1, class U2, class U3, class... U, template class F> struct mp_transform_third_impl, F> +{ + using type = L, U...>; +}; + +#if defined(BOOST_MP11_HAS_TEMPLATE_AUTO) + +template class L, auto A1, auto A2, auto A3, auto... A, template class F> struct mp_transform_third_impl, F> +{ + using type = L>::value, A...>; +}; + +#endif + +} // namespace detail + +template class F> using mp_transform_third = typename detail::mp_transform_third_impl::type; +template using mp_transform_third_q = mp_transform_third; + +} // namespace mp11 +} // namespace boost + +#endif // #ifndef BOOST_MP11_LIST_HPP_INCLUDED diff --git a/include/boost/mp11/set.hpp b/include/boost/mp11/set.hpp new file mode 100644 index 000000000..808636b72 --- /dev/null +++ b/include/boost/mp11/set.hpp @@ -0,0 +1,188 @@ +#ifndef BOOST_MP11_SET_HPP_INCLUDED +#define BOOST_MP11_SET_HPP_INCLUDED + +// Copyright 2015, 2019 Peter Dimov. +// +// 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 + +#include +#include +#include +#include +#include +#include +#include +#include + +namespace boost +{ +namespace mp11 +{ + +// mp_set_contains +namespace detail +{ + +template struct mp_set_contains_impl +{ +}; + +template class L, class... T, class V> struct mp_set_contains_impl, V> +{ + using type = mp_to_bool, mp_inherit...> > >; +}; + +} // namespace detail + +template using mp_set_contains = typename detail::mp_set_contains_impl::type; + +// mp_set_push_back +namespace detail +{ + +template struct mp_set_push_back_impl +{ +}; + +template class L, class... U> struct mp_set_push_back_impl> +{ + using type = L; +}; + +template class L, class... U, class T1, class... T> struct mp_set_push_back_impl, T1, T...> +{ + using S = mp_if, T1>, L, L>; + using type = typename mp_set_push_back_impl::type; +}; + +} // namespace detail + +template using mp_set_push_back = typename detail::mp_set_push_back_impl::type; + +// mp_set_push_front +namespace detail +{ + +template struct mp_set_push_front_impl +{ +}; + +template class L, class... U> struct mp_set_push_front_impl> +{ + using type = L; +}; + +template class L, class... U, class T1> struct mp_set_push_front_impl, T1> +{ + using type = mp_if, T1>, L, L>; +}; + +template class L, class... U, class T1, class... T> struct mp_set_push_front_impl, T1, T...> +{ + using S = typename mp_set_push_front_impl, T...>::type; + using type = typename mp_set_push_front_impl::type; +}; + +} // namespace detail + +template using mp_set_push_front = typename detail::mp_set_push_front_impl::type; + +// mp_is_set +namespace detail +{ + +template struct mp_is_set_impl +{ + using type = mp_false; +}; + +template class L, class... T> struct mp_is_set_impl> +{ + using type = mp_to_bool, mp_set_push_back, T...> > >; +}; + +} // namespace detail + +template using mp_is_set = typename detail::mp_is_set_impl::type; + +// mp_set_union +namespace detail +{ + +template struct mp_set_union_impl +{ +}; + +template<> struct mp_set_union_impl<> +{ + using type = mp_list<>; +}; + +template class L, class... T> struct mp_set_union_impl> +{ + using type = L; +}; + +template class L1, class... T1, template class L2, class... T2> struct mp_set_union_impl, L2> +{ + using type = mp_set_push_back, T2...>; +}; + +template using mp_set_union_ = typename mp_set_union_impl, L...>>::type; + +template struct mp_set_union_impl: mp_defer +{ +}; + +} // namespace detail + +template using mp_set_union = typename detail::mp_set_union_impl::type; + +// mp_set_intersection +namespace detail +{ + +template struct in_all_sets +{ + template using fn = mp_all< mp_set_contains... >; +}; + +template using mp_set_intersection_ = mp_if< mp_all...>, mp_copy_if_q> >; + +template struct mp_set_intersection_impl +{ +}; + +template<> struct mp_set_intersection_impl<> +{ + using type = mp_list<>; +}; + +template struct mp_set_intersection_impl: mp_defer +{ +}; + +} // namespace detail + +template using mp_set_intersection = typename detail::mp_set_intersection_impl::type; + +// mp_set_difference +namespace detail +{ + +template struct in_any_set +{ + template using fn = mp_any< mp_set_contains... >; +}; + +} // namespace detail + +template using mp_set_difference = mp_if< mp_all...>, mp_remove_if_q> >; + +} // namespace mp11 +} // namespace boost + +#endif // #ifndef BOOST_MP11_SET_HPP_INCLUDED diff --git a/include/boost/mp11/utility.hpp b/include/boost/mp11/utility.hpp new file mode 100644 index 000000000..4010aee2e --- /dev/null +++ b/include/boost/mp11/utility.hpp @@ -0,0 +1,169 @@ +#ifndef BOOST_MP11_UTILITY_HPP_INCLUDED +#define BOOST_MP11_UTILITY_HPP_INCLUDED + +// Copyright 2015-2020 Peter Dimov. +// +// 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 + +#include +#include +#include +#include +#include +#include +#include + +namespace boost +{ +namespace mp11 +{ + +// mp_identity +template struct mp_identity +{ + using type = T; +}; + +// mp_identity_t +template using mp_identity_t = typename mp_identity::type; + +// mp_inherit +template struct mp_inherit: T... {}; + +// mp_if, mp_if_c +// mp_valid +// mp_defer +// moved to detail/mp_defer.hpp + +// mp_eval_if, mp_eval_if_c +namespace detail +{ + +template class F, class... U> struct mp_eval_if_c_impl; + +template class F, class... U> struct mp_eval_if_c_impl +{ + using type = T; +}; + +template class F, class... U> struct mp_eval_if_c_impl: mp_defer +{ +}; + +} // namespace detail + +template class F, class... U> using mp_eval_if_c = typename detail::mp_eval_if_c_impl::type; +template class F, class... U> using mp_eval_if = typename detail::mp_eval_if_c_impl(C::value), T, F, U...>::type; +template using mp_eval_if_q = typename detail::mp_eval_if_c_impl(C::value), T, Q::template fn, U...>::type; + +// mp_eval_if_not +template class F, class... U> using mp_eval_if_not = mp_eval_if, T, F, U...>; +template using mp_eval_if_not_q = mp_eval_if, T, Q::template fn, U...>; + +// mp_eval_or +template class F, class... U> using mp_eval_or = mp_eval_if_not, T, F, U...>; +template using mp_eval_or_q = mp_eval_or; + +// mp_valid_and_true +template class F, class... T> using mp_valid_and_true = mp_eval_or; +template using mp_valid_and_true_q = mp_valid_and_true; + +// mp_cond + +// so elegant; so doesn't work +// template using mp_cond = mp_eval_if; + +namespace detail +{ + +template struct mp_cond_impl; + +} // namespace detail + +template using mp_cond = typename detail::mp_cond_impl::type; + +namespace detail +{ + +template using mp_cond_ = mp_eval_if; + +template struct mp_cond_impl: mp_defer +{ +}; + +} // namespace detail + +// mp_quote +template class F> struct mp_quote +{ + // the indirection through mp_defer works around the language inability + // to expand T... into a fixed parameter list of an alias template + + template using fn = typename mp_defer::type; +}; + +// mp_quote_trait +template class F> struct mp_quote_trait +{ + template using fn = typename F::type; +}; + +// mp_invoke_q +#if BOOST_MP11_WORKAROUND( BOOST_MP11_MSVC, < 1900 ) + +namespace detail +{ + +template struct mp_invoke_q_impl: mp_defer {}; + +} // namespace detail + +template using mp_invoke_q = typename detail::mp_invoke_q_impl::type; + +#elif BOOST_MP11_WORKAROUND( BOOST_MP11_GCC, < 50000 ) + +template using mp_invoke_q = typename mp_defer::type; + +#else + +template using mp_invoke_q = typename Q::template fn; + +#endif + +// mp_not_fn

+template class P> struct mp_not_fn +{ + template using fn = mp_not< mp_invoke_q, T...> >; +}; + +template using mp_not_fn_q = mp_not_fn; + +// mp_compose +namespace detail +{ + +template using mp_compose_helper = mp_list< mp_apply_q >; + +} // namespace detail + +#if !BOOST_MP11_WORKAROUND( BOOST_MP11_MSVC, < 1900 ) + +template class... F> struct mp_compose +{ + template using fn = mp_front< mp_fold...>, mp_list, detail::mp_compose_helper> >; +}; + +#endif + +template struct mp_compose_q +{ + template using fn = mp_front< mp_fold, mp_list, detail::mp_compose_helper> >; +}; + +} // namespace mp11 +} // namespace boost + +#endif // #ifndef BOOST_MP11_UTILITY_HPP_INCLUDED diff --git a/include/boost/mp11/version.hpp b/include/boost/mp11/version.hpp new file mode 100644 index 000000000..091266530 --- /dev/null +++ b/include/boost/mp11/version.hpp @@ -0,0 +1,16 @@ +#ifndef BOOST_MP11_VERSION_HPP_INCLUDED +#define BOOST_MP11_VERSION_HPP_INCLUDED + +// Copyright 2019 Peter Dimov +// +// 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 + +// Same format as BOOST_VERSION: +// major * 100000 + minor * 100 + patch + +#define BOOST_MP11_VERSION 108300 + +#endif // #ifndef BOOST_MP11_VERSION_HPP_INCLUDED diff --git a/include/boost/predef/architecture.h b/include/boost/predef/architecture.h index 732d6f0e5..b131a8928 100644 --- a/include/boost/predef/architecture.h +++ b/include/boost/predef/architecture.h @@ -14,7 +14,9 @@ Distributed under the Boost Software License, Version 1.0. #include #include #include +#include #include +#include #include #include #include @@ -29,6 +31,5 @@ Distributed under the Boost Software License, Version 1.0. #include #include #include -/*#include */ #endif diff --git a/include/boost/predef/architecture/alpha.h b/include/boost/predef/architecture/alpha.h index a24b10fac..64d3dad3c 100644 --- a/include/boost/predef/architecture/alpha.h +++ b/include/boost/predef/architecture/alpha.h @@ -52,6 +52,11 @@ Distributed under the Boost Software License, Version 1.0. # define BOOST_ARCH_ALPHA_AVAILABLE #endif +#if BOOST_ARCH_ALPHA +# undef BOOST_ARCH_WORD_BITS_64 +# define BOOST_ARCH_WORD_BITS_64 BOOST_VERSION_NUMBER_AVAILABLE +#endif + #define BOOST_ARCH_ALPHA_NAME "DEC Alpha" #endif diff --git a/include/boost/predef/architecture/arm.h b/include/boost/predef/architecture/arm.h index b7a8a835d..8ab20b2d1 100644 --- a/include/boost/predef/architecture/arm.h +++ b/include/boost/predef/architecture/arm.h @@ -126,6 +126,16 @@ Distributed under the Boost Software License, Version 1.0. # define BOOST_ARCH_ARM_AVAILABLE #endif +#if BOOST_ARCH_ARM +# if BOOST_ARCH_ARM >= BOOST_VERSION_NUMBER(8,0,0) +# undef BOOST_ARCH_WORD_BITS_64 +# define BOOST_ARCH_WORD_BITS_64 BOOST_VERSION_NUMBER_AVAILABLE +# else +# undef BOOST_ARCH_WORD_BITS_32 +# define BOOST_ARCH_WORD_BITS_32 BOOST_VERSION_NUMBER_AVAILABLE +# endif +#endif + #define BOOST_ARCH_ARM_NAME "ARM" #endif diff --git a/include/boost/predef/architecture/blackfin.h b/include/boost/predef/architecture/blackfin.h index ce1a65557..5c94b448d 100644 --- a/include/boost/predef/architecture/blackfin.h +++ b/include/boost/predef/architecture/blackfin.h @@ -39,6 +39,11 @@ Blackfin Processors from Analog Devices. # define BOOST_ARCH_BLACKFIN_AVAILABLE #endif +#if BOOST_ARCH_BLACKFIN +# undef BOOST_ARCH_WORD_BITS_16 +# define BOOST_ARCH_WORD_BITS_16 BOOST_VERSION_NUMBER_AVAILABLE +#endif + #define BOOST_ARCH_BLACKFIN_NAME "Blackfin" #endif diff --git a/include/boost/predef/architecture/convex.h b/include/boost/predef/architecture/convex.h index 5ce59c753..eb73d083e 100644 --- a/include/boost/predef/architecture/convex.h +++ b/include/boost/predef/architecture/convex.h @@ -58,6 +58,11 @@ Distributed under the Boost Software License, Version 1.0. # define BOOST_ARCH_CONVEX_AVAILABLE #endif +#if BOOST_ARCH_CONVEX +# undef BOOST_ARCH_WORD_BITS_32 +# define BOOST_ARCH_WORD_BITS_32 BOOST_VERSION_NUMBER_AVAILABLE +#endif + #define BOOST_ARCH_CONVEX_NAME "Convex Computer" #endif diff --git a/include/boost/predef/architecture/e2k.h b/include/boost/predef/architecture/e2k.h new file mode 100644 index 000000000..92edc9e26 --- /dev/null +++ b/include/boost/predef/architecture/e2k.h @@ -0,0 +1,54 @@ +/* +Copyright Konstantin Ivlev 2021 +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_PREDEF_ARCHITECTURE_E2K_H +#define BOOST_PREDEF_ARCHITECTURE_E2K_H + +#include +#include + +/* tag::reference[] += `BOOST_ARCH_E2K` + +https://en.wikipedia.org/wiki/Elbrus_2000[E2K] architecture. + +[options="header"] +|=== +| {predef_symbol} | {predef_version} + +| `+__e2k__+` | {predef_detection} + +| `+__e2k__+` | V.0.0 +|=== +*/ // end::reference[] + +#define BOOST_ARCH_E2K BOOST_VERSION_NUMBER_NOT_AVAILABLE + +#if defined(__e2k__) +# undef BOOST_ARCH_E2K +# if !defined(BOOST_ARCH_E2K) && defined(__iset__) +# define BOOST_ARCH_E2K BOOST_VERSION_NUMBER(__iset__,0,0) +# endif +# if !defined(BOOST_ARCH_E2K) +# define BOOST_ARCH_E2K BOOST_VERSION_NUMBER_AVAILABLE +# endif +#endif + +#if BOOST_ARCH_E2K +# define BOOST_ARCH_E2K_AVAILABLE +#endif + +#if BOOST_ARCH_E2K +# define BOOST_ARCH_WORD_BITS_64 BOOST_VERSION_NUMBER_AVAILABLE +#endif + +#define BOOST_ARCH_E2K_NAME "E2K" + +#endif + +#include +BOOST_PREDEF_DECLARE_TEST(BOOST_ARCH_E2K,BOOST_ARCH_E2K_NAME) diff --git a/include/boost/predef/architecture/ia64.h b/include/boost/predef/architecture/ia64.h index 12a08d14e..1f4b58a04 100644 --- a/include/boost/predef/architecture/ia64.h +++ b/include/boost/predef/architecture/ia64.h @@ -42,6 +42,11 @@ Distributed under the Boost Software License, Version 1.0. # define BOOST_ARCH_IA64_AVAILABLE #endif +#if BOOST_ARCH_IA64 +# undef BOOST_ARCH_WORD_BITS_64 +# define BOOST_ARCH_WORD_BITS_64 BOOST_VERSION_NUMBER_AVAILABLE +#endif + #define BOOST_ARCH_IA64_NAME "Intel Itanium 64" #endif diff --git a/include/boost/predef/architecture/loongarch.h b/include/boost/predef/architecture/loongarch.h new file mode 100644 index 000000000..e3e163bd6 --- /dev/null +++ b/include/boost/predef/architecture/loongarch.h @@ -0,0 +1,41 @@ +/* +Copyright Zhang Na 2022 +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_PREDEF_ARCHITECTURE_LOONGARCH_H +#define BOOST_PREDEF_ARCHITECTURE_LOONGARCH_H + +#include +#include + +/* tag::reference[] += `BOOST_ARCH_LOONGARCH` + +[options="header"] +|=== +| {predef_symbol} | {predef_version} + +| `+__loongarch__+` | {predef_detection} +|=== +*/ // end::reference[] + +#define BOOST_ARCH_LOONGARCH BOOST_VERSION_NUMBER_NOT_AVAILABLE + +#if defined(__loongarch__) +# undef BOOST_ARCH_LOONGARCH +# define BOOST_ARCH_LOONGARCH BOOST_VERSION_NUMBER_AVAILABLE +#endif + +#if BOOST_ARCH_LOONGARCH +# define BOOST_ARCH_LOONGARCH_AVAILABLE +#endif + +#define BOOST_ARCH_LOONGARCH_NAME "LoongArch" + +#endif + +#include +BOOST_PREDEF_DECLARE_TEST(BOOST_ARCH_LOONGARCH,BOOST_ARCH_LOONGARCH_NAME) diff --git a/include/boost/predef/architecture/m68k.h b/include/boost/predef/architecture/m68k.h index 2d8774521..a59453782 100644 --- a/include/boost/predef/architecture/m68k.h +++ b/include/boost/predef/architecture/m68k.h @@ -75,6 +75,11 @@ Distributed under the Boost Software License, Version 1.0. # define BOOST_ARCH_M68K_AVAILABLE #endif +#if BOOST_ARCH_M68K +# undef BOOST_ARCH_WORD_BITS_32 +# define BOOST_ARCH_WORD_BITS_32 BOOST_VERSION_NUMBER_AVAILABLE +#endif + #define BOOST_ARCH_M68K_NAME "Motorola 68k" #endif diff --git a/include/boost/predef/architecture/mips.h b/include/boost/predef/architecture/mips.h index 490c5e590..e35d23ab1 100644 --- a/include/boost/predef/architecture/mips.h +++ b/include/boost/predef/architecture/mips.h @@ -66,6 +66,16 @@ Distributed under the Boost Software License, Version 1.0. # define BOOST_ARCH_MIPS_AVAILABLE #endif +#if BOOST_ARCH_MIPS +# if BOOST_ARCH_MIPS >= BOOST_VERSION_NUMBER(3,0,0) +# undef BOOST_ARCH_WORD_BITS_64 +# define BOOST_ARCH_WORD_BITS_64 BOOST_VERSION_NUMBER_AVAILABLE +# else +# undef BOOST_ARCH_WORD_BITS_32 +# define BOOST_ARCH_WORD_BITS_32 BOOST_VERSION_NUMBER_AVAILABLE +# endif +#endif + #define BOOST_ARCH_MIPS_NAME "MIPS" #endif diff --git a/include/boost/predef/architecture/parisc.h b/include/boost/predef/architecture/parisc.h index 0825445a3..b93bfd9eb 100644 --- a/include/boost/predef/architecture/parisc.h +++ b/include/boost/predef/architecture/parisc.h @@ -57,6 +57,11 @@ Distributed under the Boost Software License, Version 1.0. # define BOOST_ARCH_PARISC_AVAILABLE #endif +#if BOOST_ARCH_PARISC +# undef BOOST_ARCH_WORD_BITS_32 +# define BOOST_ARCH_WORD_BITS_32 BOOST_VERSION_NUMBER_AVAILABLE +#endif + #define BOOST_ARCH_PARISC_NAME "HP/PA RISC" #endif diff --git a/include/boost/predef/architecture/ppc.h b/include/boost/predef/architecture/ppc.h index 019e11be8..73d99f33b 100644 --- a/include/boost/predef/architecture/ppc.h +++ b/include/boost/predef/architecture/ppc.h @@ -22,13 +22,19 @@ Distributed under the Boost Software License, Version 1.0. | `+__powerpc+` | {predef_detection} | `+__powerpc__+` | {predef_detection} +| `+__powerpc64__+` | {predef_detection} | `+__POWERPC__+` | {predef_detection} | `+__ppc__+` | {predef_detection} +| `+__ppc64__+` | {predef_detection} +| `+__PPC__+` | {predef_detection} +| `+__PPC64__+` | {predef_detection} | `+_M_PPC+` | {predef_detection} | `+_ARCH_PPC+` | {predef_detection} +| `+_ARCH_PPC64+` | {predef_detection} | `+__PPCGECKO__+` | {predef_detection} | `+__PPCBROADWAY__+` | {predef_detection} | `+_XENON+` | {predef_detection} +| `+__ppc+` | {predef_detection} | `+__ppc601__+` | 6.1.0 | `+_ARCH_601+` | 6.1.0 @@ -41,11 +47,13 @@ Distributed under the Boost Software License, Version 1.0. #define BOOST_ARCH_PPC BOOST_VERSION_NUMBER_NOT_AVAILABLE -#if defined(__powerpc) || defined(__powerpc__) || \ - defined(__POWERPC__) || defined(__ppc__) || \ - defined(_M_PPC) || defined(_ARCH_PPC) || \ +#if defined(__powerpc) || defined(__powerpc__) || defined(__powerpc64__) || \ + defined(__POWERPC__) || defined(__ppc__) || defined(__ppc64__) || \ + defined(__PPC__) || defined(__PPC64__) || \ + defined(_M_PPC) || defined(_ARCH_PPC) || defined(_ARCH_PPC64) || \ defined(__PPCGECKO__) || defined(__PPCBROADWAY__) || \ - defined(_XENON) + defined(_XENON) || \ + defined(__ppc) # undef BOOST_ARCH_PPC # if !defined (BOOST_ARCH_PPC) && (defined(__ppc601__) || defined(_ARCH_601)) # define BOOST_ARCH_PPC BOOST_VERSION_NUMBER(6,1,0) @@ -67,7 +75,50 @@ Distributed under the Boost Software License, Version 1.0. #define BOOST_ARCH_PPC_NAME "PowerPC" + +/* tag::reference[] += `BOOST_ARCH_PPC_64` + +http://en.wikipedia.org/wiki/PowerPC[PowerPC] 64 bit architecture. + +[options="header"] +|=== +| {predef_symbol} | {predef_version} + +| `+__powerpc64__+` | {predef_detection} +| `+__ppc64__+` | {predef_detection} +| `+__PPC64__+` | {predef_detection} +| `+_ARCH_PPC64+` | {predef_detection} +|=== +*/ // end::reference[] + +#define BOOST_ARCH_PPC_64 BOOST_VERSION_NUMBER_NOT_AVAILABLE + +#if defined(__powerpc64__) || defined(__ppc64__) || defined(__PPC64__) || \ + defined(_ARCH_PPC64) +# undef BOOST_ARCH_PPC_64 +# define BOOST_ARCH_PPC_64 BOOST_VERSION_NUMBER_AVAILABLE +#endif + +#if BOOST_ARCH_PPC_64 +# define BOOST_ARCH_PPC_64_AVAILABLE +#endif + +#define BOOST_ARCH_PPC_64_NAME "PowerPC64" + + +#if BOOST_ARCH_PPC_64 +# undef BOOST_ARCH_WORD_BITS_64 +# define BOOST_ARCH_WORD_BITS_64 BOOST_VERSION_NUMBER_AVAILABLE +#else +# undef BOOST_ARCH_WORD_BITS_32 +# define BOOST_ARCH_WORD_BITS_32 BOOST_VERSION_NUMBER_AVAILABLE +#endif + #endif #include BOOST_PREDEF_DECLARE_TEST(BOOST_ARCH_PPC,BOOST_ARCH_PPC_NAME) + +#include +BOOST_PREDEF_DECLARE_TEST(BOOST_ARCH_PPC_64,BOOST_ARCH_PPC_64_NAME) diff --git a/include/boost/predef/architecture/ptx.h b/include/boost/predef/architecture/ptx.h index a3310943e..773721361 100644 --- a/include/boost/predef/architecture/ptx.h +++ b/include/boost/predef/architecture/ptx.h @@ -37,6 +37,11 @@ Distributed under the Boost Software License, Version 1.0. # define BOOST_ARCH_PTX_AVAILABLE #endif +#if BOOST_ARCH_PTX +# undef BOOST_ARCH_WORD_BITS_64 +# define BOOST_ARCH_WORD_BITS_64 BOOST_VERSION_NUMBER_AVAILABLE +#endif + #define BOOST_ARCH_PTX_NAME "PTX" #endif diff --git a/include/boost/predef/architecture/pyramid.h b/include/boost/predef/architecture/pyramid.h index afcd1a96e..40c5359bf 100644 --- a/include/boost/predef/architecture/pyramid.h +++ b/include/boost/predef/architecture/pyramid.h @@ -35,6 +35,11 @@ Pyramid 9810 architecture. # define BOOST_ARCH_PYRAMID_AVAILABLE #endif +#if BOOST_ARCH_PYRAMID +# undef BOOST_ARCH_WORD_BITS_32 +# define BOOST_ARCH_WORD_BITS_32 BOOST_VERSION_NUMBER_AVAILABLE +#endif + #define BOOST_ARCH_PYRAMID_NAME "Pyramid 9810" #endif diff --git a/include/boost/predef/architecture/riscv.h b/include/boost/predef/architecture/riscv.h index 7c3a7ba05..8b819d77e 100644 --- a/include/boost/predef/architecture/riscv.h +++ b/include/boost/predef/architecture/riscv.h @@ -35,6 +35,11 @@ Distributed under the Boost Software License, Version 1.0. # define BOOST_ARCH_RISCV_AVAILABLE #endif +#if BOOST_ARCH_RISCV +# undef BOOST_ARCH_WORD_BITS_32 +# define BOOST_ARCH_WORD_BITS_32 BOOST_VERSION_NUMBER_AVAILABLE +#endif + #define BOOST_ARCH_RISCV_NAME "RISC-V" #endif diff --git a/include/boost/predef/architecture/rs6k.h b/include/boost/predef/architecture/rs6k.h index e33c7935e..1c6d987dd 100644 --- a/include/boost/predef/architecture/rs6k.h +++ b/include/boost/predef/architecture/rs6k.h @@ -41,6 +41,11 @@ Distributed under the Boost Software License, Version 1.0. # define BOOST_ARCH_RS6000_AVAILABLE #endif +#if BOOST_ARCH_RS6000 +# undef BOOST_ARCH_WORD_BITS_32 +# define BOOST_ARCH_WORD_BITS_32 BOOST_VERSION_NUMBER_AVAILABLE +#endif + #define BOOST_ARCH_RS6000_NAME "RS/6000" #define BOOST_ARCH_PWR BOOST_ARCH_RS6000 @@ -49,6 +54,11 @@ Distributed under the Boost Software License, Version 1.0. # define BOOST_ARCH_PWR_AVAILABLE #endif +#if BOOST_ARCH_PWR +# undef BOOST_ARCH_WORD_BITS_32 +# define BOOST_ARCH_WORD_BITS_32 BOOST_VERSION_NUMBER_AVAILABLE +#endif + #define BOOST_ARCH_PWR_NAME BOOST_ARCH_RS6000_NAME #endif diff --git a/include/boost/predef/architecture/sparc.h b/include/boost/predef/architecture/sparc.h index 31551e393..d01605e8a 100644 --- a/include/boost/predef/architecture/sparc.h +++ b/include/boost/predef/architecture/sparc.h @@ -24,7 +24,9 @@ Distributed under the Boost Software License, Version 1.0. | `+__sparc+` | {predef_detection} | `+__sparcv9+` | 9.0.0 +| `+__sparc_v9__+` | 9.0.0 | `+__sparcv8+` | 8.0.0 +| `+__sparc_v8__+` | 8.0.0 |=== */ // end::reference[] @@ -32,10 +34,10 @@ Distributed under the Boost Software License, Version 1.0. #if defined(__sparc__) || defined(__sparc) # undef BOOST_ARCH_SPARC -# if !defined(BOOST_ARCH_SPARC) && defined(__sparcv9) +# if !defined(BOOST_ARCH_SPARC) && (defined(__sparcv9) || defined(__sparc_v9__)) # define BOOST_ARCH_SPARC BOOST_VERSION_NUMBER(9,0,0) # endif -# if !defined(BOOST_ARCH_SPARC) && defined(__sparcv8) +# if !defined(BOOST_ARCH_SPARC) && (defined(__sparcv8) || defined(__sparc_v8__)) # define BOOST_ARCH_SPARC BOOST_VERSION_NUMBER(8,0,0) # endif # if !defined(BOOST_ARCH_SPARC) @@ -47,6 +49,16 @@ Distributed under the Boost Software License, Version 1.0. # define BOOST_ARCH_SPARC_AVAILABLE #endif +#if BOOST_ARCH_SPARC +# if BOOST_ARCH_SPARC >= BOOST_VERSION_NUMBER(9,0,0) +# undef BOOST_ARCH_WORD_BITS_64 +# define BOOST_ARCH_WORD_BITS_64 BOOST_VERSION_NUMBER_AVAILABLE +# else +# undef BOOST_ARCH_WORD_BITS_32 +# define BOOST_ARCH_WORD_BITS_32 BOOST_VERSION_NUMBER_AVAILABLE +# endif +#endif + #define BOOST_ARCH_SPARC_NAME "SPARC" #endif diff --git a/include/boost/predef/architecture/superh.h b/include/boost/predef/architecture/superh.h index 5034d90b3..f72dc8b19 100644 --- a/include/boost/predef/architecture/superh.h +++ b/include/boost/predef/architecture/superh.h @@ -60,6 +60,19 @@ If available versions [1-5] are specifically detected. # define BOOST_ARCH_SH_AVAILABLE #endif +#if BOOST_ARCH_SH +# if BOOST_ARCH_SH >= BOOST_VERSION_NUMBER(5,0,0) +# undef BOOST_ARCH_WORD_BITS_64 +# define BOOST_ARCH_WORD_BITS_64 BOOST_VERSION_NUMBER_AVAILABLE +# elif BOOST_ARCH_SH >= BOOST_VERSION_NUMBER(3,0,0) +# undef BOOST_ARCH_WORD_BITS_32 +# define BOOST_ARCH_WORD_BITS_32 BOOST_VERSION_NUMBER_AVAILABLE +# else +# undef BOOST_ARCH_WORD_BITS_16 +# define BOOST_ARCH_WORD_BITS_16 BOOST_VERSION_NUMBER_AVAILABLE +# endif +#endif + #define BOOST_ARCH_SH_NAME "SuperH" #endif diff --git a/include/boost/predef/architecture/sys370.h b/include/boost/predef/architecture/sys370.h index 265d0f055..5500d253d 100644 --- a/include/boost/predef/architecture/sys370.h +++ b/include/boost/predef/architecture/sys370.h @@ -36,6 +36,11 @@ Distributed under the Boost Software License, Version 1.0. # define BOOST_ARCH_SYS370_AVAILABLE #endif +#if BOOST_ARCH_SYS370 +# undef BOOST_ARCH_WORD_BITS_32 +# define BOOST_ARCH_WORD_BITS_32 BOOST_VERSION_NUMBER_AVAILABLE +#endif + #define BOOST_ARCH_SYS370_NAME "System/370" #endif diff --git a/include/boost/predef/architecture/sys390.h b/include/boost/predef/architecture/sys390.h index 155c9beac..9aba56858 100644 --- a/include/boost/predef/architecture/sys390.h +++ b/include/boost/predef/architecture/sys390.h @@ -36,6 +36,11 @@ Distributed under the Boost Software License, Version 1.0. # define BOOST_ARCH_SYS390_AVAILABLE #endif +#if BOOST_ARCH_SYS390 +# undef BOOST_ARCH_WORD_BITS_32 +# define BOOST_ARCH_WORD_BITS_32 BOOST_VERSION_NUMBER_AVAILABLE +#endif + #define BOOST_ARCH_SYS390_NAME "System/390" #endif diff --git a/include/boost/predef/architecture/x86/32.h b/include/boost/predef/architecture/x86/32.h index cd2e7504f..b20fed9d1 100644 --- a/include/boost/predef/architecture/x86/32.h +++ b/include/boost/predef/architecture/x86/32.h @@ -78,6 +78,11 @@ If available versions [3-6] are specifically detected. # define BOOST_ARCH_X86_32_AVAILABLE #endif +#if BOOST_ARCH_X86_32 +# undef BOOST_ARCH_WORD_BITS_32 +# define BOOST_ARCH_WORD_BITS_32 BOOST_VERSION_NUMBER_AVAILABLE +#endif + #define BOOST_ARCH_X86_32_NAME "Intel x86-32" #include diff --git a/include/boost/predef/architecture/x86/64.h b/include/boost/predef/architecture/x86/64.h index ebd80fb5e..6f59722b3 100644 --- a/include/boost/predef/architecture/x86/64.h +++ b/include/boost/predef/architecture/x86/64.h @@ -1,5 +1,5 @@ /* -Copyright Rene Rivera 2008-2015 +Copyright Rene Rivera 2008-2021 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) @@ -14,7 +14,7 @@ Distributed under the Boost Software License, Version 1.0. /* tag::reference[] = `BOOST_ARCH_X86_64` -http://en.wikipedia.org/wiki/Ia64[Intel IA-64] architecture. +https://en.wikipedia.org/wiki/X86-64[X86-64] architecture. [options="header"] |=== @@ -41,6 +41,11 @@ Distributed under the Boost Software License, Version 1.0. # define BOOST_ARCH_X86_64_AVAILABLE #endif +#if BOOST_ARCH_X86_64 +# undef BOOST_ARCH_WORD_BITS_64 +# define BOOST_ARCH_WORD_BITS_64 BOOST_VERSION_NUMBER_AVAILABLE +#endif + #define BOOST_ARCH_X86_64_NAME "Intel x86-64" #include diff --git a/include/boost/predef/architecture/z.h b/include/boost/predef/architecture/z.h index d2d8e95f4..a5f79796c 100644 --- a/include/boost/predef/architecture/z.h +++ b/include/boost/predef/architecture/z.h @@ -35,6 +35,11 @@ Distributed under the Boost Software License, Version 1.0. # define BOOST_ARCH_Z_AVAILABLE #endif +#if BOOST_ARCH_Z +# undef BOOST_ARCH_WORD_BITS_64 +# define BOOST_ARCH_WORD_BITS_64 BOOST_VERSION_NUMBER_AVAILABLE +#endif + #define BOOST_ARCH_Z_NAME "z/Architecture" #endif diff --git a/include/boost/predef/language/stdc.h b/include/boost/predef/language/stdc.h index 94e30fe6c..8cbd6a10c 100644 --- a/include/boost/predef/language/stdc.h +++ b/include/boost/predef/language/stdc.h @@ -15,7 +15,7 @@ Distributed under the Boost Software License, Version 1.0. = `BOOST_LANG_STDC` http://en.wikipedia.org/wiki/C_(programming_language)[Standard C] language. -If available, the year of the standard is detected as YYYY.MM.1 from the Epoc date. +If available, the year of the standard is detected as YYYY.MM.1 from the Epoch date. [options="header"] |=== diff --git a/include/boost/predef/language/stdcpp.h b/include/boost/predef/language/stdcpp.h index fc83431ce..daa14cfc0 100644 --- a/include/boost/predef/language/stdcpp.h +++ b/include/boost/predef/language/stdcpp.h @@ -15,7 +15,7 @@ Distributed under the Boost Software License, Version 1.0. = `BOOST_LANG_STDCPP` http://en.wikipedia.org/wiki/C%2B%2B[Standard {CPP}] language. -If available, the year of the standard is detected as YYYY.MM.1 from the Epoc date. +If available, the year of the standard is detected as YYYY.MM.1 from the Epoch date. Because of the way the {CPP} standardization process works the defined version year will not be the commonly known year of the standard. Specifically the defined versions are: @@ -61,7 +61,7 @@ Specifically the defined versions are: = `BOOST_LANG_STDCPPCLI` http://en.wikipedia.org/wiki/C%2B%2B/CLI[Standard {CPP}/CLI] language. -If available, the year of the standard is detected as YYYY.MM.1 from the Epoc date. +If available, the year of the standard is detected as YYYY.MM.1 from the Epoch date. [options="header"] |=== diff --git a/include/boost/predef/library/std/cxx.h b/include/boost/predef/library/std/cxx.h index 61a09a8c3..470c80da1 100644 --- a/include/boost/predef/library/std/cxx.h +++ b/include/boost/predef/library/std/cxx.h @@ -32,7 +32,7 @@ Distributed under the Boost Software License, Version 1.0. #if defined(_LIBCPP_VERSION) # undef BOOST_LIB_STD_CXX -# define BOOST_LIB_STD_CXX BOOST_PREDEF_MAKE_10_VPPP(_LIBCPP_VERSION) +# define BOOST_LIB_STD_CXX BOOST_PREDEF_MAKE_10_VVPPP(_LIBCPP_VERSION) #endif #if BOOST_LIB_STD_CXX diff --git a/include/boost/predef/library/std/stdcpp3.h b/include/boost/predef/library/std/stdcpp3.h index bc9717a2c..90aa3d183 100644 --- a/include/boost/predef/library/std/stdcpp3.h +++ b/include/boost/predef/library/std/stdcpp3.h @@ -16,7 +16,7 @@ Distributed under the Boost Software License, Version 1.0. /* tag::reference[] = `BOOST_LIB_STD_GNU` -http://gcc.gnu.org/libstdc++/[GNU libstdc++] Standard {CPP} library. +https://gcc.gnu.org/onlinedocs/libstdc%2b%2b/[GNU libstdc++] Standard {CPP} library. Version number available as year (from 1970), month, and day. [options="header"] diff --git a/include/boost/predef/make.h b/include/boost/predef/make.h index 810ba456e..e65a0e1bd 100644 --- a/include/boost/predef/make.h +++ b/include/boost/predef/make.h @@ -66,6 +66,10 @@ Macros are: */ // end::reference[] #define BOOST_PREDEF_MAKE_10_VPPP(V) BOOST_VERSION_NUMBER(((V)/1000)%10,0,(V)%1000) /* tag::reference[] +* `BOOST_PREDEF_MAKE_10_VVPPP(V)` +*/ // end::reference[] +#define BOOST_PREDEF_MAKE_10_VVPPP(V) BOOST_VERSION_NUMBER(((V)/1000)%100,0,(V)%1000) +/* tag::reference[] * `BOOST_PREDEF_MAKE_10_VR0(V)` */ // end::reference[] #define BOOST_PREDEF_MAKE_10_VR0(V) BOOST_VERSION_NUMBER(((V)/100)%10,((V)/10)%10,0) diff --git a/include/boost/predef/os/bsd/bsdi.h b/include/boost/predef/os/bsd/bsdi.h index 0c90f6d41..d0a5dcd9f 100644 --- a/include/boost/predef/os/bsd/bsdi.h +++ b/include/boost/predef/os/bsd/bsdi.h @@ -29,6 +29,7 @@ Distributed under the Boost Software License, Version 1.0. defined(__bsdi__) \ ) # ifndef BOOST_OS_BSD_AVAILABLE +# undef BOOST_OS_BSD # define BOOST_OS_BSD BOOST_VERSION_NUMBER_AVAILABLE # define BOOST_OS_BSD_AVAILABLE # endif diff --git a/include/boost/predef/os/bsd/dragonfly.h b/include/boost/predef/os/bsd/dragonfly.h index 253f0e24e..432077796 100644 --- a/include/boost/predef/os/bsd/dragonfly.h +++ b/include/boost/predef/os/bsd/dragonfly.h @@ -29,6 +29,7 @@ Distributed under the Boost Software License, Version 1.0. defined(__DragonFly__) \ ) # ifndef BOOST_OS_BSD_AVAILABLE +# undef BOOST_OS_BSD # define BOOST_OS_BSD BOOST_VERSION_NUMBER_AVAILABLE # define BOOST_OS_BSD_AVAILABLE # endif diff --git a/include/boost/predef/os/bsd/free.h b/include/boost/predef/os/bsd/free.h index 0cf82ae9d..4098b3a35 100644 --- a/include/boost/predef/os/bsd/free.h +++ b/include/boost/predef/os/bsd/free.h @@ -31,6 +31,7 @@ Distributed under the Boost Software License, Version 1.0. defined(__FreeBSD__) \ ) # ifndef BOOST_OS_BSD_AVAILABLE +# undef BOOST_OS_BSD # define BOOST_OS_BSD BOOST_VERSION_NUMBER_AVAILABLE # define BOOST_OS_BSD_AVAILABLE # endif diff --git a/include/boost/predef/os/bsd/net.h b/include/boost/predef/os/bsd/net.h index c4e3c92ba..537f16a14 100644 --- a/include/boost/predef/os/bsd/net.h +++ b/include/boost/predef/os/bsd/net.h @@ -36,6 +36,7 @@ Distributed under the Boost Software License, Version 1.0. defined(__NETBSD__) || defined(__NetBSD__) \ ) # ifndef BOOST_OS_BSD_AVAILABLE +# undef BOOST_OS_BSD # define BOOST_OS_BSD BOOST_VERSION_NUMBER_AVAILABLE # define BOOST_OS_BSD_AVAILABLE # endif diff --git a/include/boost/predef/os/bsd/open.h b/include/boost/predef/os/bsd/open.h index 3a9081c85..34f0a71a0 100644 --- a/include/boost/predef/os/bsd/open.h +++ b/include/boost/predef/os/bsd/open.h @@ -80,6 +80,7 @@ Distributed under the Boost Software License, Version 1.0. defined(__OpenBSD__) \ ) # ifndef BOOST_OS_BSD_AVAILABLE +# undef BOOST_OS_BSD # define BOOST_OS_BSD BOOST_VERSION_NUMBER_AVAILABLE # define BOOST_OS_BSD_AVAILABLE # endif diff --git a/include/boost/predef/other.h b/include/boost/predef/other.h index c09ad4945..dc7e341e0 100644 --- a/include/boost/predef/other.h +++ b/include/boost/predef/other.h @@ -1,5 +1,5 @@ /* -Copyright Rene Rivera 2013-2015 +Copyright Rene Ferdinand Rivera Morell 2013-2020 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) @@ -11,6 +11,7 @@ Distributed under the Boost Software License, Version 1.0. #endif #include -/*#include */ +#include +#include #endif diff --git a/include/boost/predef/other/endian.h b/include/boost/predef/other/endian.h index 0281e4a3f..435492a07 100644 --- a/include/boost/predef/other/endian.h +++ b/include/boost/predef/other/endian.h @@ -54,18 +54,14 @@ information and acquired knowledge: */ #if !BOOST_ENDIAN_BIG_BYTE && !BOOST_ENDIAN_BIG_WORD && \ !BOOST_ENDIAN_LITTLE_BYTE && !BOOST_ENDIAN_LITTLE_WORD -# if BOOST_LIB_C_GNU || BOOST_PLAT_ANDROID +# if BOOST_LIB_C_GNU || BOOST_PLAT_ANDROID || BOOST_OS_BSD_OPEN # include # else # if BOOST_OS_MACOS # include # else # if BOOST_OS_BSD -# if BOOST_OS_BSD_OPEN -# include -# else -# include -# endif +# include # endif # endif # endif @@ -99,7 +95,7 @@ information and acquired knowledge: # endif #endif -/* Built-in byte-swpped big-endian macros. +/* Built-in byte-swapped big-endian macros. */ #if !BOOST_ENDIAN_BIG_BYTE && !BOOST_ENDIAN_BIG_WORD && \ !BOOST_ENDIAN_LITTLE_BYTE && !BOOST_ENDIAN_LITTLE_WORD @@ -116,7 +112,7 @@ information and acquired knowledge: # endif #endif -/* Built-in byte-swpped little-endian macros. +/* Built-in byte-swapped little-endian macros. */ #if !BOOST_ENDIAN_BIG_BYTE && !BOOST_ENDIAN_BIG_WORD && \ !BOOST_ENDIAN_LITTLE_BYTE && !BOOST_ENDIAN_LITTLE_WORD @@ -125,10 +121,12 @@ information and acquired knowledge: defined(__ARMEL__) || \ defined(__THUMBEL__) || \ defined(__AARCH64EL__) || \ + defined(__loongarch__) || \ defined(_MIPSEL) || \ defined(__MIPSEL) || \ defined(__MIPSEL__) || \ - defined(__riscv) + defined(__riscv) || \ + defined(__e2k__) # undef BOOST_ENDIAN_LITTLE_BYTE # define BOOST_ENDIAN_LITTLE_BYTE BOOST_VERSION_NUMBER_AVAILABLE # endif @@ -158,7 +156,7 @@ information and acquired knowledge: #endif /* Windows on ARM, if not otherwise detected/specified, is always - * byte-swaped little-endian. + * byte-swapped little-endian. */ #if !BOOST_ENDIAN_BIG_BYTE && !BOOST_ENDIAN_BIG_WORD && \ !BOOST_ENDIAN_LITTLE_BYTE && !BOOST_ENDIAN_LITTLE_WORD diff --git a/include/boost/predef/other/wordsize.h b/include/boost/predef/other/wordsize.h new file mode 100644 index 000000000..ce3016feb --- /dev/null +++ b/include/boost/predef/other/wordsize.h @@ -0,0 +1,73 @@ +/* +Copyright Rene Ferdinand Rivera Morell 2020-2021 +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_PREDEF_OTHER_WORD_SIZE_H +#define BOOST_PREDEF_OTHER_WORD_SIZE_H + +#include +#include +#include + +/* tag::reference[] += `BOOST_ARCH_WORD_BITS` + +Detects the native word size, in bits, for the current architecture. There are +two types of macros for this detection: + +* `BOOST_ARCH_WORD_BITS`, gives the number of word size bits + (16, 32, 64). +* `BOOST_ARCH_WORD_BITS_16`, `BOOST_ARCH_WORD_BITS_32`, and + `BOOST_ARCH_WORD_BITS_64`, indicate when the given word size is + detected. + +They allow for both single checks and direct use of the size in code. + +NOTE: The word size is determined manually on each architecture. Hence use of +the `wordsize.h` header will also include all the architecture headers. + +*/ // end::reference[] + +#if !defined(BOOST_ARCH_WORD_BITS_64) +# define BOOST_ARCH_WORD_BITS_64 BOOST_VERSION_NUMBER_NOT_AVAILABLE +#elif !defined(BOOST_ARCH_WORD_BITS) +# define BOOST_ARCH_WORD_BITS 64 +#endif + +#if !defined(BOOST_ARCH_WORD_BITS_32) +# define BOOST_ARCH_WORD_BITS_32 BOOST_VERSION_NUMBER_NOT_AVAILABLE +#elif !defined(BOOST_ARCH_WORD_BITS) +# define BOOST_ARCH_WORD_BITS 32 +#endif + +#if !defined(BOOST_ARCH_WORD_BITS_16) +# define BOOST_ARCH_WORD_BITS_16 BOOST_VERSION_NUMBER_NOT_AVAILABLE +#elif !defined(BOOST_ARCH_WORD_BITS) +# define BOOST_ARCH_WORD_BITS 16 +#endif + +#if !defined(BOOST_ARCH_WORD_BITS) +# define BOOST_ARCH_WORD_BITS 0 +#endif + +#define BOOST_ARCH_WORD_BITS_NAME "Word Bits" +#define BOOST_ARCH_WORD_BITS_16_NAME "16-bit Word Size" +#define BOOST_ARCH_WORD_BITS_32_NAME "32-bit Word Size" +#define BOOST_ARCH_WORD_BITS_64_NAME "64-bit Word Size" + +#endif + +#include +BOOST_PREDEF_DECLARE_TEST(BOOST_ARCH_WORD_BITS,BOOST_ARCH_WORD_BITS_NAME) + +#include +BOOST_PREDEF_DECLARE_TEST(BOOST_ARCH_WORD_BITS_16,BOOST_ARCH_WORD_BITS_16_NAME) + +#include +BOOST_PREDEF_DECLARE_TEST(BOOST_ARCH_WORD_BITS_32,BOOST_ARCH_WORD_BITS_32_NAME) + +#include +BOOST_PREDEF_DECLARE_TEST(BOOST_ARCH_WORD_BITS_64,BOOST_ARCH_WORD_BITS_64_NAME) diff --git a/include/boost/predef/platform.h b/include/boost/predef/platform.h index 65a0e2ac0..756d65fd9 100644 --- a/include/boost/predef/platform.h +++ b/include/boost/predef/platform.h @@ -24,6 +24,5 @@ Distributed under the Boost Software License, Version 1.0. #include #include // deprecated #include -/*#include */ #endif diff --git a/include/boost/predef/version.h b/include/boost/predef/version.h index 39ef2b49a..172d22e52 100644 --- a/include/boost/predef/version.h +++ b/include/boost/predef/version.h @@ -10,6 +10,6 @@ Distributed under the Boost Software License, Version 1.0. #include -#define BOOST_PREDEF_VERSION BOOST_VERSION_NUMBER(1,11,0) +#define BOOST_PREDEF_VERSION BOOST_VERSION_NUMBER(1,14,0) #endif diff --git a/include/boost/preprocessor/config/config.hpp b/include/boost/preprocessor/config/config.hpp index 1fc29ac50..3c2067221 100644 --- a/include/boost/preprocessor/config/config.hpp +++ b/include/boost/preprocessor/config/config.hpp @@ -83,7 +83,7 @@ # undef BOOST_PP_VARIADICS_MSVC # endif # define BOOST_PP_VARIADICS 1 -# if defined _MSC_VER && _MSC_VER >= 1400 && !defined(__clang__) && (defined(__INTELLISENSE__) || (defined(__INTEL_COMPILER) && __INTEL_COMPILER >= 1700) || !(defined __EDG__ || defined __GCCXML__ || (defined __NVCC__ && defined __CUDACC__) || defined __PATHSCALE__ || defined __DMC__ || defined __CODEGEARC__ || defined __BORLANDC__ || defined __MWERKS__ || defined __SUNPRO_CC || defined __HP_aCC || defined __MRC__ || defined __SC__ || defined __IBMCPP__ || defined __PGI)) && (!defined(_MSVC_TRADITIONAL) || _MSVC_TRADITIONAL) +# if defined _MSC_VER && _MSC_VER >= 1400 && !defined(__clang__) && (defined(__INTELLISENSE__) || (defined(__INTEL_COMPILER) && __INTEL_COMPILER >= 1700) || !(defined __EDG__ || defined __GCCXML__ || defined __PATHSCALE__ || defined __DMC__ || defined __CODEGEARC__ || defined __BORLANDC__ || defined __MWERKS__ || defined __SUNPRO_CC || defined __HP_aCC || defined __MRC__ || defined __SC__ || defined __IBMCPP__ || defined __PGI)) && (!defined(_MSVC_TRADITIONAL) || _MSVC_TRADITIONAL) # define BOOST_PP_VARIADICS_MSVC 1 # else # define BOOST_PP_VARIADICS_MSVC 0 diff --git a/include/boost/preprocessor/variadic/has_opt.hpp b/include/boost/preprocessor/variadic/has_opt.hpp index b2cceff5d..7054e9455 100644 --- a/include/boost/preprocessor/variadic/has_opt.hpp +++ b/include/boost/preprocessor/variadic/has_opt.hpp @@ -17,10 +17,14 @@ # /* BOOST_PP_VARIADIC_HAS_OPT */ # # if defined(__cplusplus) && __cplusplus > 201703L -# include -# define BOOST_PP_VARIADIC_HAS_OPT() \ +# if defined(__GNUC__) && !defined(__clang__) && __GNUC__ >= 8 && __GNUC__ < 10 +# define BOOST_PP_VARIADIC_HAS_OPT() 0 +# else +# include +# define BOOST_PP_VARIADIC_HAS_OPT() \ BOOST_PP_VARIADIC_HAS_OPT_ELEM2(BOOST_PP_VARIADIC_HAS_OPT_FUNCTION(?),) \ /**/ +# endif # else # define BOOST_PP_VARIADIC_HAS_OPT() 0 # endif diff --git a/include/boost/static_assert.hpp b/include/boost/static_assert.hpp index 0c9c5a5fd..d94ca8070 100644 --- a/include/boost/static_assert.hpp +++ b/include/boost/static_assert.hpp @@ -16,6 +16,7 @@ #include #include +#include //for std::size_t #if defined(__GNUC__) && !defined(__GXX_EXPERIMENTAL_CXX0X__) // @@ -81,7 +82,7 @@ template struct STATIC_ASSERTION_FAILURE; template <> struct STATIC_ASSERTION_FAILURE { enum { value = 1 }; }; // HP aCC cannot deal with missing names for template value parameters -template struct static_assert_test{}; +template struct static_assert_test{}; } diff --git a/include/boost/throw_exception.hpp b/include/boost/throw_exception.hpp index 37b79b620..7c7fcbddc 100644 --- a/include/boost/throw_exception.hpp +++ b/include/boost/throw_exception.hpp @@ -7,10 +7,9 @@ # pragma once #endif -// // boost/throw_exception.hpp // -// Copyright (c) 2002, 2018, 2019 Peter Dimov +// Copyright (c) 2002, 2018-2022 Peter Dimov // Copyright (c) 2008-2009 Emil Dotchevski and Reverge Studios, Inc. // // Distributed under the Boost Software License, Version 1.0. (See @@ -18,12 +17,17 @@ // http://www.boost.org/LICENSE_1_0.txt) // // http://www.boost.org/libs/throw_exception -// +#include #include #include #include #include +#include +#include +#if !defined(BOOST_NO_CXX11_HDR_TYPE_TRAITS) +#include +#endif #if !defined( BOOST_EXCEPTION_DISABLE ) && defined( BOOST_BORLANDC ) && BOOST_WORKAROUND( BOOST_BORLANDC, BOOST_TESTED_AT(0x593) ) # define BOOST_EXCEPTION_DISABLE @@ -32,48 +36,12 @@ namespace boost { -// All boost exceptions are required to derive from std::exception, -// to ensure compatibility with BOOST_NO_EXCEPTIONS. - -inline void throw_exception_assert_compatibility( std::exception const & ) {} - -} // namespace boost - #if defined( BOOST_NO_EXCEPTIONS ) -namespace boost -{ - BOOST_NORETURN void throw_exception( std::exception const & e ); // user defined BOOST_NORETURN void throw_exception( std::exception const & e, boost::source_location const & loc ); // user defined -} // namespace boost - -#elif defined( BOOST_EXCEPTION_DISABLE ) - -namespace boost -{ - -template BOOST_NORETURN void throw_exception( E const & e ) -{ - throw_exception_assert_compatibility( e ); - throw e; -} - -template BOOST_NORETURN void throw_exception( E const & e, boost::source_location const & ) -{ - throw_exception_assert_compatibility( e ); - throw e; -} - -} // namespace boost - -#else // !defined( BOOST_NO_EXCEPTIONS ) && !defined( BOOST_EXCEPTION_DISABLE ) - -#include - -namespace boost -{ +#endif // boost::wrapexcept @@ -86,7 +54,7 @@ typedef char (&wrapexcept_s2)[ 2 ]; template wrapexcept_s1 wrapexcept_is_convertible( T* ); template wrapexcept_s2 wrapexcept_is_convertible( void* ); -template( static_cast< E* >( 0 ) ) ) > struct wrapexcept_add_base; +template( static_cast< E* >( BOOST_NULLPTR ) ) ) > struct wrapexcept_add_base; template struct wrapexcept_add_base { @@ -136,8 +104,9 @@ template struct BOOST_SYMBOL_VISIBLE wrapexcept: copy_from( &e ); set_info( *this, throw_file( loc.file_name() ) ); - set_info( *this, throw_line( loc.line() ) ); + set_info( *this, throw_line( static_cast( loc.line() ) ) ); set_info( *this, throw_function( loc.function_name() ) ); + set_info( *this, throw_column( static_cast( loc.column() ) ) ); } virtual boost::exception_detail::clone_base const * clone() const BOOST_OVERRIDE @@ -147,18 +116,49 @@ template struct BOOST_SYMBOL_VISIBLE wrapexcept: boost::exception_detail::copy_boost_exception( p, this ); - del.p_ = 0; + del.p_ = BOOST_NULLPTR; return p; } virtual void rethrow() const BOOST_OVERRIDE { +#if defined( BOOST_NO_EXCEPTIONS ) + + boost::throw_exception( *this ); + +#else + throw *this; + +#endif } }; +// All boost exceptions are required to derive from std::exception, +// to ensure compatibility with BOOST_NO_EXCEPTIONS. + +inline void throw_exception_assert_compatibility( std::exception const & ) {} + // boost::throw_exception +#if !defined( BOOST_NO_EXCEPTIONS ) + +#if defined( BOOST_EXCEPTION_DISABLE ) + +template BOOST_NORETURN void throw_exception( E const & e ) +{ + throw_exception_assert_compatibility( e ); + throw e; +} + +template BOOST_NORETURN void throw_exception( E const & e, boost::source_location const & ) +{ + throw_exception_assert_compatibility( e ); + throw e; +} + +#else // defined( BOOST_EXCEPTION_DISABLE ) + template BOOST_NORETURN void throw_exception( E const & e ) { throw_exception_assert_compatibility( e ); @@ -171,12 +171,108 @@ template BOOST_NORETURN void throw_exception( E const & e, boost::sourc throw wrapexcept( e, loc ); } -} // namespace boost +#endif // defined( BOOST_EXCEPTION_DISABLE ) -#endif +#endif // !defined( BOOST_NO_EXCEPTIONS ) + +} // namespace boost // BOOST_THROW_EXCEPTION #define BOOST_THROW_EXCEPTION(x) ::boost::throw_exception(x, BOOST_CURRENT_LOCATION) +namespace boost +{ + +// throw_with_location + +namespace detail +{ + +struct BOOST_SYMBOL_VISIBLE throw_location +{ + boost::source_location location_; + + explicit throw_location( boost::source_location const & loc ): location_( loc ) + { + } +}; + +template class BOOST_SYMBOL_VISIBLE with_throw_location: public E, public throw_location +{ +public: + + with_throw_location( E const & e, boost::source_location const & loc ): E( e ), throw_location( loc ) + { + } + +#if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES) + + with_throw_location( E && e, boost::source_location const & loc ): E( std::move( e ) ), throw_location( loc ) + { + } + +#endif +}; + +} // namespace detail + +#if !defined(BOOST_NO_EXCEPTIONS) + +#if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES) && !defined(BOOST_NO_CXX11_HDR_TYPE_TRAITS) + +template BOOST_NORETURN void throw_with_location( E && e, boost::source_location const & loc = BOOST_CURRENT_LOCATION ) +{ + throw_exception_assert_compatibility( e ); + throw detail::with_throw_location::type>( std::forward( e ), loc ); +} + +#else + +template BOOST_NORETURN void throw_with_location( E const & e, boost::source_location const & loc = BOOST_CURRENT_LOCATION ) +{ + throw_exception_assert_compatibility( e ); + throw detail::with_throw_location( e, loc ); +} + +#endif + +#else + +template BOOST_NORETURN void throw_with_location( E const & e, boost::source_location const & loc = BOOST_CURRENT_LOCATION ) +{ + boost::throw_exception( e, loc ); +} + +#endif + +// get_throw_location + +template boost::source_location get_throw_location( E const & e ) +{ +#if defined(BOOST_NO_RTTI) + + (void)e; + return boost::source_location(); + +#else + + if( detail::throw_location const* pl = dynamic_cast< detail::throw_location const* >( &e ) ) + { + return pl->location_; + } + else if( boost::exception const* px = dynamic_cast< boost::exception const* >( &e ) ) + { + return exception_detail::get_exception_throw_location( *px ); + } + else + { + return boost::source_location(); + } + +#endif +} + +} // namespace boost + #endif // #ifndef BOOST_THROW_EXCEPTION_HPP_INCLUDED diff --git a/include/boost/tuple/detail/tuple_basic.hpp b/include/boost/tuple/detail/tuple_basic.hpp index bed30425f..96fb5bde1 100644 --- a/include/boost/tuple/detail/tuple_basic.hpp +++ b/include/boost/tuple/detail/tuple_basic.hpp @@ -34,6 +34,7 @@ #include // needed for the assignment from pair to tuple +#include // for std::size_t #include #include @@ -93,7 +94,7 @@ namespace detail { template class generate_error; -template +template struct drop_front { template struct apply { @@ -127,14 +128,14 @@ struct drop_front<0> { #ifndef BOOST_NO_CV_SPECIALIZATIONS -template +template struct element { typedef BOOST_DEDUCED_TYPENAME detail::drop_front::BOOST_NESTED_TEMPLATE apply::type::head_type type; }; -template +template struct element { private: @@ -151,14 +152,14 @@ struct element namespace detail { -template +template struct element_impl { typedef BOOST_DEDUCED_TYPENAME detail::drop_front::BOOST_NESTED_TEMPLATE apply::type::head_type type; }; -template +template struct element_impl { typedef BOOST_DEDUCED_TYPENAME detail::drop_front::BOOST_NESTED_TEMPLATE @@ -169,7 +170,7 @@ struct element_impl } // end of namespace detail -template +template struct element: public detail::element_impl::value> { @@ -210,7 +211,7 @@ template struct access_traits { // get function for non-const cons-lists, returns a reference to the element -template +template inline typename access_traits< typename element >::type >::non_const_type @@ -224,7 +225,7 @@ get(cons& c) { // get function for const cons-lists, returns a const reference to // the element. If the element is a reference, returns the reference // as such (that is, can return a non-const reference) -template +template inline typename access_traits< typename element >::type >::const_type @@ -333,7 +334,7 @@ struct cons { } // get member functions (non-const and const) - template + template typename access_traits< typename element >::type >::non_const_type @@ -341,7 +342,7 @@ struct cons { return boost::tuples::get(*this); // delegate to non-member get } - template + template typename access_traits< typename element >::type >::const_type @@ -403,7 +404,7 @@ struct cons { // is illformed if HT is a reference cons& operator=(const cons& u) { head = u.head; return *this; } - template + template typename access_traits< typename element::type >::non_const_type @@ -411,7 +412,7 @@ struct cons { return boost::tuples::get(*this); } - template + template typename access_traits< typename element::type >::const_type @@ -424,27 +425,27 @@ struct cons { // templates for finding out the length of the tuple ------------------- template -struct length: boost::integral_constant::value> +struct length: boost::integral_constant::value> { }; template<> -struct length >: boost::integral_constant +struct length >: boost::integral_constant { }; template<> -struct length const>: boost::integral_constant +struct length const>: boost::integral_constant { }; template<> -struct length: boost::integral_constant +struct length: boost::integral_constant { }; template<> -struct length: boost::integral_constant +struct length: boost::integral_constant { }; @@ -676,20 +677,20 @@ struct make_tuple_traits { // All arrays are converted to const. This is because make_tuple takes its // parameters as const T& and thus the knowledge of the potential // non-constness of actual argument is lost. -template struct make_tuple_traits { +template struct make_tuple_traits { typedef const T (&type)[n]; }; -template +template struct make_tuple_traits { typedef const T (&type)[n]; }; -template struct make_tuple_traits { +template struct make_tuple_traits { typedef const volatile T (&type)[n]; }; -template +template struct make_tuple_traits { typedef const volatile T (&type)[n]; }; diff --git a/include/boost/type_traits/detail/config.hpp b/include/boost/type_traits/detail/config.hpp index 8ac3b4a66..679ad08bd 100644 --- a/include/boost/type_traits/detail/config.hpp +++ b/include/boost/type_traits/detail/config.hpp @@ -83,7 +83,7 @@ // #if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) && !BOOST_WORKAROUND(BOOST_GCC, < 40805)\ && !BOOST_WORKAROUND(BOOST_MSVC, < 1900) && !BOOST_WORKAROUND(__clang_major__, <= 4) -# define BOOST_TT_HAS_ASCCURATE_IS_FUNCTION +# define BOOST_TT_HAS_ACCURATE_IS_FUNCTION #endif #if defined(_MSVC_LANG) && (_MSVC_LANG >= 201703) @@ -107,6 +107,9 @@ #if defined(BOOST_MSVC) && !defined(__cpp_rvalue_references) && !defined(BOOST_TT_NO_NOEXCEPT_SEPARATE_TYPE) && !defined(_NOEXCEPT_TYPES_SUPPORTED) # define BOOST_TT_NO_NOEXCEPT_SEPARATE_TYPE #endif +#if defined(__cpp_rvalue_references) && defined(__NVCC__) && defined(__CUDACC__) && !defined(BOOST_TT_NO_NOEXCEPT_SEPARATE_TYPE) +# define BOOST_TT_NO_NOEXCEPT_SEPARATE_TYPE +#endif #endif // BOOST_TT_CONFIG_HPP_INCLUDED diff --git a/include/boost/type_traits/detail/is_function_cxx_11.hpp b/include/boost/type_traits/detail/is_function_cxx_11.hpp index 4de74a737..2dbe1de0e 100644 --- a/include/boost/type_traits/detail/is_function_cxx_11.hpp +++ b/include/boost/type_traits/detail/is_function_cxx_11.hpp @@ -32,276 +32,317 @@ namespace boost { #define BOOST_TT_DEF_CALL #endif +#if !defined(_M_CEE_SAFE) && !defined(_M_CEE_PURE) template struct is_function : public true_type {}; +#endif template struct is_function : public true_type {}; // const qualified: + +#if !defined(_M_CEE_SAFE) && !defined(_M_CEE_PURE) template struct is_function : public true_type {}; +#endif template struct is_function : public true_type {}; // volatile: + +#if !defined(_M_CEE_SAFE) && !defined(_M_CEE_PURE) template struct is_function : public true_type {}; +#endif template struct is_function : public true_type {}; // const volatile +#if !defined(_M_CEE_SAFE) && !defined(_M_CEE_PURE) template struct is_function : public true_type {}; +#endif template struct is_function : public true_type {}; // Reference qualified: +#if !defined(_M_CEE_SAFE) && !defined(_M_CEE_PURE) template struct is_function : public true_type {}; +#endif template struct is_function : public true_type {}; // const qualified: +#if !defined(_M_CEE_SAFE) && !defined(_M_CEE_PURE) template struct is_function : public true_type {}; +#endif template struct is_function : public true_type {}; // volatile: +#if !defined(_M_CEE_SAFE) && !defined(_M_CEE_PURE) template struct is_function : public true_type {}; +#endif template struct is_function : public true_type {}; // const volatile +#if !defined(_M_CEE_SAFE) && !defined(_M_CEE_PURE) template struct is_function : public true_type {}; +#endif template struct is_function : public true_type {}; // rvalue reference qualified: +#if !defined(_M_CEE_SAFE) && !defined(_M_CEE_PURE) template struct is_function : public true_type {}; +#endif template struct is_function : public true_type {}; // const qualified: +#if !defined(_M_CEE_SAFE) && !defined(_M_CEE_PURE) template struct is_function : public true_type {}; +#endif template struct is_function : public true_type {}; // volatile: +#if !defined(_M_CEE_SAFE) && !defined(_M_CEE_PURE) template struct is_function : public true_type {}; +#endif template struct is_function : public true_type {}; // const volatile +#if !defined(_M_CEE_SAFE) && !defined(_M_CEE_PURE) template struct is_function : public true_type {}; +#endif template struct is_function : public true_type {}; + #if defined(_MSC_VER) && !defined(_M_ARM) && !defined(_M_ARM64) -#ifdef __CLR_VER + +#if !defined(_M_X64) && !defined(_M_CEE_SAFE) && !defined(_M_CEE_PURE) template - struct is_function : public true_type {}; + struct is_function : public true_type {}; #endif -#ifndef _M_AMD64 +#ifdef _MANAGED template - struct is_function : public true_type {}; -#ifndef __CLR_VER + struct is_function : public true_type {}; +#else +#ifndef _M_X64 template struct is_function : public true_type {}; #endif -#endif -#if !defined(__CLR_VER) && (defined(_M_IX86_FP) && (_M_IX86_FP >= 2) || defined(_M_X64)) +#if defined(_M_IX86_FP) && (_M_IX86_FP >= 2) || defined(_M_X64) template struct is_function : public true_type {}; +#endif #endif // const: -#ifdef __CLR_VER + +#if !defined(_M_X64) && !defined(_M_CEE_SAFE) && !defined(_M_CEE_PURE) template - struct is_function : public true_type {}; + struct is_function : public true_type {}; #endif -#ifndef _M_AMD64 +#ifdef _MANAGED template - struct is_function : public true_type {}; -#ifndef __CLR_VER + struct is_function : public true_type {}; +#else +#ifndef _M_AMD64 template struct is_function : public true_type {}; #endif -#endif -#if !defined(__CLR_VER) && (defined(_M_IX86_FP) && (_M_IX86_FP >= 2) || defined(_M_X64)) +#if defined(_M_IX86_FP) && (_M_IX86_FP >= 2) || defined(_M_X64) template struct is_function : public true_type {}; +#endif #endif // volatile: -#ifdef __CLR_VER +#if !defined(_M_X64) && !defined(_M_CEE_SAFE) && !defined(_M_CEE_PURE) template - struct is_function : public true_type {}; + struct is_function : public true_type {}; #endif -#ifndef _M_AMD64 +#ifdef _MANAGED template - struct is_function : public true_type {}; -#ifndef __CLR_VER + struct is_function : public true_type {}; +#else +#ifndef _M_AMD64 template struct is_function : public true_type {}; #endif -#endif -#if !defined(__CLR_VER) && (defined(_M_IX86_FP) && (_M_IX86_FP >= 2) || defined(_M_X64)) +#if defined(_M_IX86_FP) && (_M_IX86_FP >= 2) || defined(_M_X64) template struct is_function : public true_type {}; +#endif #endif // const volatile: -#ifdef __CLR_VER +#if !defined(_M_X64) && !defined(_M_CEE_SAFE) && !defined(_M_CEE_PURE) template - struct is_function : public true_type {}; + struct is_function : public true_type {}; #endif -#ifndef _M_AMD64 +#ifdef _MANAGED template - struct is_function : public true_type {}; -#ifndef __CLR_VER + struct is_function : public true_type {}; +#else +#ifndef _M_AMD64 template struct is_function : public true_type {}; #endif -#endif -#if !defined(__CLR_VER) && (defined(_M_IX86_FP) && (_M_IX86_FP >= 2) || defined(_M_X64)) +#if defined(_M_IX86_FP) && (_M_IX86_FP >= 2) || defined(_M_X64) template struct is_function : public true_type {}; +#endif #endif // reference qualified: -#ifdef __CLR_VER +#if !defined(_M_X64) && !defined(_M_CEE_SAFE) && !defined(_M_CEE_PURE) template - struct is_function : public true_type {}; + struct is_function : public true_type {}; #endif -#ifndef _M_AMD64 +#ifdef _MANAGED template - struct is_function : public true_type {}; -#ifndef __CLR_VER + struct is_function : public true_type {}; +#else +#ifndef _M_AMD64 template struct is_function : public true_type {}; #endif -#endif -#if !defined(__CLR_VER) && (defined(_M_IX86_FP) && (_M_IX86_FP >= 2) || defined(_M_X64)) +#if defined(_M_IX86_FP) && (_M_IX86_FP >= 2) || defined(_M_X64) template struct is_function : public true_type {}; +#endif #endif // const: -#ifdef __CLR_VER +#if !defined(_M_X64) && !defined(_M_CEE_SAFE) && !defined(_M_CEE_PURE) template - struct is_function : public true_type {}; + struct is_function : public true_type {}; #endif -#ifndef _M_AMD64 +#ifdef _MANAGED template - struct is_function : public true_type {}; -#ifndef __CLR_VER + struct is_function : public true_type {}; +#else +#ifndef _M_AMD64 template struct is_function : public true_type {}; #endif -#endif -#if !defined(__CLR_VER) && (defined(_M_IX86_FP) && (_M_IX86_FP >= 2) || defined(_M_X64)) +#if defined(_M_IX86_FP) && (_M_IX86_FP >= 2) || defined(_M_X64) template struct is_function : public true_type {}; +#endif #endif // volatile: -#ifdef __CLR_VER +#if !defined(_M_X64) && !defined(_M_CEE_SAFE) && !defined(_M_CEE_PURE) template - struct is_function : public true_type {}; + struct is_function : public true_type {}; #endif -#ifndef _M_AMD64 +#ifdef _MANAGED template - struct is_function : public true_type {}; -#ifndef __CLR_VER + struct is_function : public true_type {}; +#else +#ifndef _M_AMD64 template struct is_function : public true_type {}; #endif -#endif -#if !defined(__CLR_VER) && (defined(_M_IX86_FP) && (_M_IX86_FP >= 2) || defined(_M_X64)) +#if defined(_M_IX86_FP) && (_M_IX86_FP >= 2) || defined(_M_X64) template struct is_function : public true_type {}; +#endif #endif // const volatile: -#ifdef __CLR_VER +#if !defined(_M_X64) && !defined(_M_CEE_SAFE) && !defined(_M_CEE_PURE) template - struct is_function : public true_type {}; + struct is_function : public true_type {}; #endif -#ifndef _M_AMD64 +#ifdef _MANAGED template - struct is_function : public true_type {}; -#ifndef __CLR_VER + struct is_function : public true_type {}; +#else +#ifndef _M_AMD64 template struct is_function : public true_type {}; #endif -#endif -#if !defined(__CLR_VER) && (defined(_M_IX86_FP) && (_M_IX86_FP >= 2) || defined(_M_X64)) +#if defined(_M_IX86_FP) && (_M_IX86_FP >= 2) || defined(_M_X64) template struct is_function : public true_type {}; +#endif #endif // rvalue reference qualified: -#ifdef __CLR_VER +#if !defined(_M_X64) && !defined(_M_CEE_SAFE) && !defined(_M_CEE_PURE) template - struct is_function : public true_type {}; + struct is_function : public true_type {}; #endif -#ifndef _M_AMD64 +#ifdef _MANAGED template - struct is_function : public true_type {}; -#ifndef __CLR_VER + struct is_function : public true_type {}; +#else +#ifndef _M_AMD64 template struct is_function : public true_type {}; #endif -#endif -#if !defined(__CLR_VER) && (defined(_M_IX86_FP) && (_M_IX86_FP >= 2) || defined(_M_X64)) +#if defined(_M_IX86_FP) && (_M_IX86_FP >= 2) || defined(_M_X64) template struct is_function : public true_type {}; +#endif #endif // const: -#ifdef __CLR_VER +#if !defined(_M_X64) && !defined(_M_CEE_SAFE) && !defined(_M_CEE_PURE) template - struct is_function : public true_type {}; + struct is_function : public true_type {}; #endif -#ifndef _M_AMD64 +#ifdef _MANAGED template - struct is_function : public true_type {}; -#ifndef __CLR_VER + struct is_function : public true_type {}; +#else +#ifndef _M_AMD64 template struct is_function : public true_type {}; #endif -#endif -#if !defined(__CLR_VER) && (defined(_M_IX86_FP) && (_M_IX86_FP >= 2) || defined(_M_X64)) +#if defined(_M_IX86_FP) && (_M_IX86_FP >= 2) || defined(_M_X64) template struct is_function : public true_type {}; +#endif #endif // volatile: -#ifdef __CLR_VER +#if !defined(_M_X64) && !defined(_M_CEE_SAFE) && !defined(_M_CEE_PURE) template - struct is_function : public true_type {}; + struct is_function : public true_type {}; #endif -#ifndef _M_AMD64 +#ifdef _MANAGED template - struct is_function : public true_type {}; -#ifndef __CLR_VER + struct is_function : public true_type {}; +#else +#ifndef _M_AMD64 template struct is_function : public true_type {}; #endif -#endif -#if !defined(__CLR_VER) && (defined(_M_IX86_FP) && (_M_IX86_FP >= 2) || defined(_M_X64)) +#if defined(_M_IX86_FP) && (_M_IX86_FP >= 2) || defined(_M_X64) template struct is_function : public true_type {}; +#endif #endif // const volatile: -#ifdef __CLR_VER +#if !defined(_M_X64) && !defined(_M_CEE_SAFE) && !defined(_M_CEE_PURE) template - struct is_function : public true_type {}; + struct is_function : public true_type {}; #endif -#ifndef _M_AMD64 +#ifdef _MANAGED template - struct is_function : public true_type {}; -#ifndef __CLR_VER + struct is_function : public true_type {}; +#else +#ifndef _M_AMD64 template struct is_function : public true_type {}; #endif -#endif -#if !defined(__CLR_VER) && (defined(_M_IX86_FP) && (_M_IX86_FP >= 2) || defined(_M_X64)) +#if defined(_M_IX86_FP) && (_M_IX86_FP >= 2) || defined(_M_X64) template struct is_function : public true_type {}; #endif +#endif #endif // _MSC_VER @@ -312,276 +353,314 @@ namespace boost { #undef BOOST_TT_NOEXCEPT_DECL #define BOOST_TT_NOEXCEPT_DECL noexcept +#if !defined(_M_CEE_SAFE) && !defined(_M_CEE_PURE) template struct is_function : public true_type {}; +#endif template struct is_function : public true_type {}; // const qualified: +#if !defined(_M_CEE_SAFE) && !defined(_M_CEE_PURE) template struct is_function : public true_type {}; +#endif template struct is_function : public true_type {}; // volatile: +#if !defined(_M_CEE_SAFE) && !defined(_M_CEE_PURE) template struct is_function : public true_type {}; +#endif template struct is_function : public true_type {}; // const volatile +#if !defined(_M_CEE_SAFE) && !defined(_M_CEE_PURE) template struct is_function : public true_type {}; +#endif template struct is_function : public true_type {}; // Reference qualified: +#if !defined(_M_CEE_SAFE) && !defined(_M_CEE_PURE) template struct is_function : public true_type {}; +#endif template struct is_function : public true_type {}; // const qualified: +#if !defined(_M_CEE_SAFE) && !defined(_M_CEE_PURE) template struct is_function : public true_type {}; +#endif template struct is_function : public true_type {}; // volatile: +#if !defined(_M_CEE_SAFE) && !defined(_M_CEE_PURE) template struct is_function : public true_type {}; +#endif template struct is_function : public true_type {}; // const volatile +#if !defined(_M_CEE_SAFE) && !defined(_M_CEE_PURE) template struct is_function : public true_type {}; +#endif template struct is_function : public true_type {}; // rvalue reference qualified: +#if !defined(_M_CEE_SAFE) && !defined(_M_CEE_PURE) template struct is_function : public true_type {}; +#endif template struct is_function : public true_type {}; // const qualified: +#if !defined(_M_CEE_SAFE) && !defined(_M_CEE_PURE) template struct is_function : public true_type {}; +#endif template struct is_function : public true_type {}; // volatile: +#if !defined(_M_CEE_SAFE) && !defined(_M_CEE_PURE) template struct is_function : public true_type {}; +#endif template struct is_function : public true_type {}; // const volatile +#if !defined(_M_CEE_SAFE) && !defined(_M_CEE_PURE) template struct is_function : public true_type {}; +#endif template struct is_function : public true_type {}; + #if defined(_MSC_VER) && !defined(_M_ARM) && !defined(_M_ARM64) -#ifdef __CLR_VER + +#if !defined(_M_X64) && !defined(_M_CEE_SAFE) && !defined(_M_CEE_PURE) template - struct is_function : public true_type {}; + struct is_function : public true_type {}; #endif -#ifndef _M_AMD64 +#ifdef _MANAGED template - struct is_function : public true_type {}; -#ifndef __CLR_VER + struct is_function : public true_type {}; +#else +#ifndef _M_AMD64 template struct is_function : public true_type {}; #endif -#endif -#if !defined(__CLR_VER) && (defined(_M_IX86_FP) && (_M_IX86_FP >= 2) || defined(_M_X64)) +#if defined(_M_IX86_FP) && (_M_IX86_FP >= 2) || defined(_M_X64) template struct is_function : public true_type {}; +#endif #endif // const: -#ifdef __CLR_VER +#if !defined(_M_X64) && !defined(_M_CEE_SAFE) && !defined(_M_CEE_PURE) template - struct is_function : public true_type {}; + struct is_function : public true_type {}; #endif -#ifndef _M_AMD64 +#ifdef _MANAGED template - struct is_function : public true_type {}; -#ifndef __CLR_VER + struct is_function : public true_type {}; +#else +#ifndef _M_AMD64 template struct is_function : public true_type {}; #endif -#endif -#if !defined(__CLR_VER) && (defined(_M_IX86_FP) && (_M_IX86_FP >= 2) || defined(_M_X64)) +#if defined(_M_IX86_FP) && (_M_IX86_FP >= 2) || defined(_M_X64) template struct is_function : public true_type {}; +#endif #endif // volatile: -#ifdef __CLR_VER +#if !defined(_M_X64) && !defined(_M_CEE_SAFE) && !defined(_M_CEE_PURE) template - struct is_function : public true_type {}; + struct is_function : public true_type {}; #endif -#ifndef _M_AMD64 +#ifdef _MANAGED template - struct is_function : public true_type {}; -#ifndef __CLR_VER + struct is_function : public true_type {}; +#else +#ifndef _M_AMD64 template struct is_function : public true_type {}; #endif -#endif -#if !defined(__CLR_VER) && (defined(_M_IX86_FP) && (_M_IX86_FP >= 2) || defined(_M_X64)) +#if defined(_M_IX86_FP) && (_M_IX86_FP >= 2) || defined(_M_X64) template struct is_function : public true_type {}; +#endif #endif // const volatile: -#ifdef __CLR_VER +#if !defined(_M_X64) && !defined(_M_CEE_SAFE) && !defined(_M_CEE_PURE) template - struct is_function : public true_type {}; + struct is_function : public true_type {}; #endif -#ifndef _M_AMD64 +#ifdef _MANAGED template - struct is_function : public true_type {}; -#ifndef __CLR_VER + struct is_function : public true_type {}; +#else +#ifndef _M_AMD64 template struct is_function : public true_type {}; #endif -#endif -#if !defined(__CLR_VER) && (defined(_M_IX86_FP) && (_M_IX86_FP >= 2) || defined(_M_X64)) +#if defined(_M_IX86_FP) && (_M_IX86_FP >= 2) || defined(_M_X64) template struct is_function : public true_type {}; +#endif #endif // reference qualified: -#ifdef __CLR_VER +#if !defined(_M_X64) && !defined(_M_CEE_SAFE) && !defined(_M_CEE_PURE) template - struct is_function : public true_type {}; + struct is_function : public true_type {}; #endif -#ifndef _M_AMD64 +#ifdef _MANAGED template - struct is_function : public true_type {}; -#ifndef __CLR_VER + struct is_function : public true_type {}; +#else +#ifndef _M_AMD64 template struct is_function : public true_type {}; #endif -#endif -#if !defined(__CLR_VER) && (defined(_M_IX86_FP) && (_M_IX86_FP >= 2) || defined(_M_X64)) +#if defined(_M_IX86_FP) && (_M_IX86_FP >= 2) || defined(_M_X64) template struct is_function : public true_type {}; +#endif #endif // const: -#ifdef __CLR_VER +#if !defined(_M_X64) && !defined(_M_CEE_SAFE) && !defined(_M_CEE_PURE) template - struct is_function : public true_type {}; + struct is_function : public true_type {}; #endif -#ifndef _M_AMD64 +#ifdef _MANAGED template - struct is_function : public true_type {}; -#ifndef __CLR_VER + struct is_function : public true_type {}; +#else +#ifndef _M_AMD64 template struct is_function : public true_type {}; #endif -#endif -#if !defined(__CLR_VER) && (defined(_M_IX86_FP) && (_M_IX86_FP >= 2) || defined(_M_X64)) +#if defined(_M_IX86_FP) && (_M_IX86_FP >= 2) || defined(_M_X64) template struct is_function : public true_type {}; +#endif #endif // volatile: -#ifdef __CLR_VER +#if !defined(_M_X64) && !defined(_M_CEE_SAFE) && !defined(_M_CEE_PURE) template - struct is_function : public true_type {}; + struct is_function : public true_type {}; #endif -#ifndef _M_AMD64 +#ifdef _MANAGED template - struct is_function : public true_type {}; -#ifndef __CLR_VER + struct is_function : public true_type {}; +#else +#ifndef _M_AMD64 template struct is_function : public true_type {}; #endif -#endif -#if !defined(__CLR_VER) && (defined(_M_IX86_FP) && (_M_IX86_FP >= 2) || defined(_M_X64)) +#if defined(_M_IX86_FP) && (_M_IX86_FP >= 2) || defined(_M_X64) template struct is_function : public true_type {}; +#endif #endif // const volatile: -#ifdef __CLR_VER +#if !defined(_M_X64) && !defined(_M_CEE_SAFE) && !defined(_M_CEE_PURE) template - struct is_function : public true_type {}; + struct is_function : public true_type {}; #endif -#ifndef _M_AMD64 +#ifdef _MANAGED template - struct is_function : public true_type {}; -#ifndef __CLR_VER + struct is_function : public true_type {}; +#else +#ifndef _M_AMD64 template struct is_function : public true_type {}; #endif -#endif -#if !defined(__CLR_VER) && (defined(_M_IX86_FP) && (_M_IX86_FP >= 2) || defined(_M_X64)) +#if defined(_M_IX86_FP) && (_M_IX86_FP >= 2) || defined(_M_X64) template struct is_function : public true_type {}; +#endif #endif // rvalue reference qualified: -#ifdef __CLR_VER +#if !defined(_M_X64) && !defined(_M_CEE_SAFE) && !defined(_M_CEE_PURE) template - struct is_function : public true_type {}; + struct is_function : public true_type {}; #endif -#ifndef _M_AMD64 +#ifdef _MANAGED template - struct is_function : public true_type {}; -#ifndef __CLR_VER + struct is_function : public true_type {}; +#else +#ifndef _M_AMD64 template struct is_function : public true_type {}; #endif -#endif -#if !defined(__CLR_VER) && (defined(_M_IX86_FP) && (_M_IX86_FP >= 2) || defined(_M_X64)) +#if defined(_M_IX86_FP) && (_M_IX86_FP >= 2) || defined(_M_X64) template struct is_function : public true_type {}; +#endif #endif // const: -#ifdef __CLR_VER +#if !defined(_M_X64) && !defined(_M_CEE_SAFE) && !defined(_M_CEE_PURE) template - struct is_function : public true_type {}; + struct is_function : public true_type {}; #endif -#ifndef _M_AMD64 +#ifdef _MANAGED template - struct is_function : public true_type {}; -#ifndef __CLR_VER + struct is_function : public true_type {}; +#else +#ifndef _M_AMD64 template struct is_function : public true_type {}; #endif -#endif -#if !defined(__CLR_VER) && (defined(_M_IX86_FP) && (_M_IX86_FP >= 2) || defined(_M_X64)) +#if defined(_M_IX86_FP) && (_M_IX86_FP >= 2) || defined(_M_X64) template struct is_function : public true_type {}; +#endif #endif // volatile: -#ifdef __CLR_VER +#if !defined(_M_X64) && !defined(_M_CEE_SAFE) && !defined(_M_CEE_PURE) template - struct is_function : public true_type {}; + struct is_function : public true_type {}; #endif -#ifndef _M_AMD64 +#ifdef _MANAGED template - struct is_function : public true_type {}; -#ifndef __CLR_VER + struct is_function : public true_type {}; +#else +#ifndef _M_AMD64 template struct is_function : public true_type {}; #endif -#endif -#if !defined(__CLR_VER) && (defined(_M_IX86_FP) && (_M_IX86_FP >= 2) || defined(_M_X64)) +#if defined(_M_IX86_FP) && (_M_IX86_FP >= 2) || defined(_M_X64) template struct is_function : public true_type {}; +#endif #endif // const volatile: -#ifdef __CLR_VER +#if !defined(_M_X64) && !defined(_M_CEE_SAFE) && !defined(_M_CEE_PURE) template - struct is_function : public true_type {}; + struct is_function : public true_type {}; #endif -#ifndef _M_AMD64 +#ifdef _MANAGED template - struct is_function : public true_type {}; -#ifndef __CLR_VER + struct is_function : public true_type {}; +#else +#ifndef _M_AMD64 template struct is_function : public true_type {}; #endif -#endif -#if !defined(__CLR_VER) && (defined(_M_IX86_FP) && (_M_IX86_FP >= 2) || defined(_M_X64)) +#if defined(_M_IX86_FP) && (_M_IX86_FP >= 2) || defined(_M_X64) template struct is_function : public true_type {}; #endif +#endif #endif // defined(_MSC_VER) && !defined(_M_ARM) && !defined(_M_ARM64) diff --git a/include/boost/type_traits/detail/is_function_ptr_helper.hpp b/include/boost/type_traits/detail/is_function_ptr_helper.hpp index 73a705cc3..688c5dad9 100644 --- a/include/boost/type_traits/detail/is_function_ptr_helper.hpp +++ b/include/boost/type_traits/detail/is_function_ptr_helper.hpp @@ -49,7 +49,7 @@ struct is_function_ptr_helper { BOOST_STATIC_CONSTANT(bool, value = true template struct is_function_ptr_helper { BOOST_STATIC_CONSTANT(bool, value = true); }; #endif -#if __cpp_noexcept_function_type +#ifdef __cpp_noexcept_function_type template struct is_function_ptr_helper { BOOST_STATIC_CONSTANT(bool, value = true); }; #ifndef BOOST_TT_NO_ELLIPSIS_IN_FUNC_TESTING @@ -63,7 +63,7 @@ struct is_function_ptr_helper { BOOST_STATIC_CONSTANT(bool, value = tr template struct is_function_ptr_helper { BOOST_STATIC_CONSTANT(bool, value = true); }; #endif -#if __cpp_noexcept_function_type +#ifdef __cpp_noexcept_function_type template struct is_function_ptr_helper { BOOST_STATIC_CONSTANT(bool, value = true); }; #ifndef BOOST_TT_NO_ELLIPSIS_IN_FUNC_TESTING @@ -77,7 +77,7 @@ struct is_function_ptr_helper { BOOST_STATIC_CONSTANT(bool, value template struct is_function_ptr_helper { BOOST_STATIC_CONSTANT(bool, value = true); }; #endif -#if __cpp_noexcept_function_type +#ifdef __cpp_noexcept_function_type template struct is_function_ptr_helper { BOOST_STATIC_CONSTANT(bool, value = true); }; #ifndef BOOST_TT_NO_ELLIPSIS_IN_FUNC_TESTING @@ -91,7 +91,7 @@ struct is_function_ptr_helper { BOOST_STATIC_CONSTANT(bool, va template struct is_function_ptr_helper { BOOST_STATIC_CONSTANT(bool, value = true); }; #endif -#if __cpp_noexcept_function_type +#ifdef __cpp_noexcept_function_type template struct is_function_ptr_helper { BOOST_STATIC_CONSTANT(bool, value = true); }; #ifndef BOOST_TT_NO_ELLIPSIS_IN_FUNC_TESTING @@ -105,7 +105,7 @@ struct is_function_ptr_helper { BOOST_STATIC_CONSTANT(bool template struct is_function_ptr_helper { BOOST_STATIC_CONSTANT(bool, value = true); }; #endif -#if __cpp_noexcept_function_type +#ifdef __cpp_noexcept_function_type template struct is_function_ptr_helper { BOOST_STATIC_CONSTANT(bool, value = true); }; #ifndef BOOST_TT_NO_ELLIPSIS_IN_FUNC_TESTING @@ -119,7 +119,7 @@ struct is_function_ptr_helper { BOOST_STATIC_CONSTANT( template struct is_function_ptr_helper { BOOST_STATIC_CONSTANT(bool, value = true); }; #endif -#if __cpp_noexcept_function_type +#ifdef __cpp_noexcept_function_type template struct is_function_ptr_helper { BOOST_STATIC_CONSTANT(bool, value = true); }; #ifndef BOOST_TT_NO_ELLIPSIS_IN_FUNC_TESTING @@ -133,7 +133,7 @@ struct is_function_ptr_helper { BOOST_STATIC_CONST template struct is_function_ptr_helper { BOOST_STATIC_CONSTANT(bool, value = true); }; #endif -#if __cpp_noexcept_function_type +#ifdef __cpp_noexcept_function_type template struct is_function_ptr_helper { BOOST_STATIC_CONSTANT(bool, value = true); }; #ifndef BOOST_TT_NO_ELLIPSIS_IN_FUNC_TESTING @@ -147,7 +147,7 @@ struct is_function_ptr_helper { BOOST_STATIC_C template struct is_function_ptr_helper { BOOST_STATIC_CONSTANT(bool, value = true); }; #endif -#if __cpp_noexcept_function_type +#ifdef __cpp_noexcept_function_type template struct is_function_ptr_helper { BOOST_STATIC_CONSTANT(bool, value = true); }; #ifndef BOOST_TT_NO_ELLIPSIS_IN_FUNC_TESTING @@ -161,7 +161,7 @@ struct is_function_ptr_helper { BOOST_STAT template struct is_function_ptr_helper { BOOST_STATIC_CONSTANT(bool, value = true); }; #endif -#if __cpp_noexcept_function_type +#ifdef __cpp_noexcept_function_type template struct is_function_ptr_helper { BOOST_STATIC_CONSTANT(bool, value = true); }; #ifndef BOOST_TT_NO_ELLIPSIS_IN_FUNC_TESTING @@ -175,7 +175,7 @@ struct is_function_ptr_helper { BOOST_ template struct is_function_ptr_helper { BOOST_STATIC_CONSTANT(bool, value = true); }; #endif -#if __cpp_noexcept_function_type +#ifdef __cpp_noexcept_function_type template struct is_function_ptr_helper { BOOST_STATIC_CONSTANT(bool, value = true); }; #ifndef BOOST_TT_NO_ELLIPSIS_IN_FUNC_TESTING @@ -189,7 +189,7 @@ struct is_function_ptr_helper { BO template struct is_function_ptr_helper { BOOST_STATIC_CONSTANT(bool, value = true); }; #endif -#if __cpp_noexcept_function_type +#ifdef __cpp_noexcept_function_type template struct is_function_ptr_helper { BOOST_STATIC_CONSTANT(bool, value = true); }; #ifndef BOOST_TT_NO_ELLIPSIS_IN_FUNC_TESTING @@ -203,7 +203,7 @@ struct is_function_ptr_helper template struct is_function_ptr_helper { BOOST_STATIC_CONSTANT(bool, value = true); }; #endif -#if __cpp_noexcept_function_type +#ifdef __cpp_noexcept_function_type template struct is_function_ptr_helper { BOOST_STATIC_CONSTANT(bool, value = true); }; #ifndef BOOST_TT_NO_ELLIPSIS_IN_FUNC_TESTING @@ -217,7 +217,7 @@ struct is_function_ptr_helper struct is_function_ptr_helper { BOOST_STATIC_CONSTANT(bool, value = true); }; #endif -#if __cpp_noexcept_function_type +#ifdef __cpp_noexcept_function_type template struct is_function_ptr_helper { BOOST_STATIC_CONSTANT(bool, value = true); }; #ifndef BOOST_TT_NO_ELLIPSIS_IN_FUNC_TESTING @@ -231,7 +231,7 @@ struct is_function_ptr_helper struct is_function_ptr_helper { BOOST_STATIC_CONSTANT(bool, value = true); }; #endif -#if __cpp_noexcept_function_type +#ifdef __cpp_noexcept_function_type template struct is_function_ptr_helper { BOOST_STATIC_CONSTANT(bool, value = true); }; #ifndef BOOST_TT_NO_ELLIPSIS_IN_FUNC_TESTING @@ -245,7 +245,7 @@ struct is_function_ptr_helper struct is_function_ptr_helper { BOOST_STATIC_CONSTANT(bool, value = true); }; #endif -#if __cpp_noexcept_function_type +#ifdef __cpp_noexcept_function_type template struct is_function_ptr_helper { BOOST_STATIC_CONSTANT(bool, value = true); }; #ifndef BOOST_TT_NO_ELLIPSIS_IN_FUNC_TESTING @@ -259,7 +259,7 @@ struct is_function_ptr_helper struct is_function_ptr_helper { BOOST_STATIC_CONSTANT(bool, value = true); }; #endif -#if __cpp_noexcept_function_type +#ifdef __cpp_noexcept_function_type template struct is_function_ptr_helper { BOOST_STATIC_CONSTANT(bool, value = true); }; #ifndef BOOST_TT_NO_ELLIPSIS_IN_FUNC_TESTING @@ -273,7 +273,7 @@ struct is_function_ptr_helper struct is_function_ptr_helper { BOOST_STATIC_CONSTANT(bool, value = true); }; #endif -#if __cpp_noexcept_function_type +#ifdef __cpp_noexcept_function_type template struct is_function_ptr_helper { BOOST_STATIC_CONSTANT(bool, value = true); }; #ifndef BOOST_TT_NO_ELLIPSIS_IN_FUNC_TESTING @@ -287,7 +287,7 @@ struct is_function_ptr_helper struct is_function_ptr_helper { BOOST_STATIC_CONSTANT(bool, value = true); }; #endif -#if __cpp_noexcept_function_type +#ifdef __cpp_noexcept_function_type template struct is_function_ptr_helper { BOOST_STATIC_CONSTANT(bool, value = true); }; #ifndef BOOST_TT_NO_ELLIPSIS_IN_FUNC_TESTING @@ -301,7 +301,7 @@ struct is_function_ptr_helper struct is_function_ptr_helper { BOOST_STATIC_CONSTANT(bool, value = true); }; #endif -#if __cpp_noexcept_function_type +#ifdef __cpp_noexcept_function_type template struct is_function_ptr_helper { BOOST_STATIC_CONSTANT(bool, value = true); }; #ifndef BOOST_TT_NO_ELLIPSIS_IN_FUNC_TESTING @@ -315,7 +315,7 @@ struct is_function_ptr_helper struct is_function_ptr_helper { BOOST_STATIC_CONSTANT(bool, value = true); }; #endif -#if __cpp_noexcept_function_type +#ifdef __cpp_noexcept_function_type template struct is_function_ptr_helper { BOOST_STATIC_CONSTANT(bool, value = true); }; #ifndef BOOST_TT_NO_ELLIPSIS_IN_FUNC_TESTING @@ -329,7 +329,7 @@ struct is_function_ptr_helper struct is_function_ptr_helper { BOOST_STATIC_CONSTANT(bool, value = true); }; #endif -#if __cpp_noexcept_function_type +#ifdef __cpp_noexcept_function_type template struct is_function_ptr_helper { BOOST_STATIC_CONSTANT(bool, value = true); }; #ifndef BOOST_TT_NO_ELLIPSIS_IN_FUNC_TESTING @@ -343,7 +343,7 @@ struct is_function_ptr_helper struct is_function_ptr_helper { BOOST_STATIC_CONSTANT(bool, value = true); }; #endif -#if __cpp_noexcept_function_type +#ifdef __cpp_noexcept_function_type template struct is_function_ptr_helper { BOOST_STATIC_CONSTANT(bool, value = true); }; #ifndef BOOST_TT_NO_ELLIPSIS_IN_FUNC_TESTING @@ -357,7 +357,7 @@ struct is_function_ptr_helper struct is_function_ptr_helper { BOOST_STATIC_CONSTANT(bool, value = true); }; #endif -#if __cpp_noexcept_function_type +#ifdef __cpp_noexcept_function_type template struct is_function_ptr_helper { BOOST_STATIC_CONSTANT(bool, value = true); }; #ifndef BOOST_TT_NO_ELLIPSIS_IN_FUNC_TESTING @@ -371,7 +371,7 @@ struct is_function_ptr_helper struct is_function_ptr_helper { BOOST_STATIC_CONSTANT(bool, value = true); }; #endif -#if __cpp_noexcept_function_type +#ifdef __cpp_noexcept_function_type template struct is_function_ptr_helper { BOOST_STATIC_CONSTANT(bool, value = true); }; #ifndef BOOST_TT_NO_ELLIPSIS_IN_FUNC_TESTING @@ -385,7 +385,7 @@ struct is_function_ptr_helper struct is_function_ptr_helper { BOOST_STATIC_CONSTANT(bool, value = true); }; #endif -#if __cpp_noexcept_function_type +#ifdef __cpp_noexcept_function_type template struct is_function_ptr_helper { BOOST_STATIC_CONSTANT(bool, value = true); }; #ifndef BOOST_TT_NO_ELLIPSIS_IN_FUNC_TESTING @@ -399,7 +399,7 @@ struct is_function_ptr_helper struct is_function_ptr_helper { BOOST_STATIC_CONSTANT(bool, value = true); }; #endif -#if __cpp_noexcept_function_type +#ifdef __cpp_noexcept_function_type template struct is_function_ptr_helper { BOOST_STATIC_CONSTANT(bool, value = true); }; #ifndef BOOST_TT_NO_ELLIPSIS_IN_FUNC_TESTING @@ -432,7 +432,7 @@ struct is_function_ptr_helper { template struct is_function_ptr_helper { BOOST_STATIC_CONSTANT(bool, value = true); }; @#endif -@#if __cpp_noexcept_function_type +@#ifdef __cpp_noexcept_function_type template struct is_function_ptr_helper { BOOST_STATIC_CONSTANT(bool, value = true); }; @#ifndef BOOST_TT_NO_ELLIPSIS_IN_FUNC_TESTING diff --git a/include/boost/type_traits/detail/is_function_ptr_tester.hpp b/include/boost/type_traits/detail/is_function_ptr_tester.hpp index 41ddd2260..1c8683c04 100644 --- a/include/boost/type_traits/detail/is_function_ptr_tester.hpp +++ b/include/boost/type_traits/detail/is_function_ptr_tester.hpp @@ -52,7 +52,7 @@ yes_type is_function_ptr_tester(R(*)(...)); #ifdef BOOST_TT_TEST_MS_FUNC_SIGS template yes_type is_function_ptr_tester(R(__stdcall*)()); -#if (_MSC_VER >= 1800) && !defined(__CLR_VER) && (defined(_M_IX86_FP) && (_M_IX86_FP >= 2) || defined(_M_X64)) +#if (_MSC_VER >= 1800) && !defined(_MANAGED) && (defined(_M_IX86_FP) && (_M_IX86_FP >= 2) || defined(_M_X64)) template yes_type is_function_ptr_tester(R(__vectorcall*)()); #endif @@ -72,7 +72,7 @@ yes_type is_function_ptr_tester(R(*)(T0 ...)); #ifdef BOOST_TT_TEST_MS_FUNC_SIGS template yes_type is_function_ptr_tester(R(__stdcall*)(T0)); -#if (_MSC_VER >= 1800) && !defined(__CLR_VER) && (defined(_M_IX86_FP) && (_M_IX86_FP >= 2) || defined(_M_X64)) +#if (_MSC_VER >= 1800) && !defined(_MANAGED) && (defined(_M_IX86_FP) && (_M_IX86_FP >= 2) || defined(_M_X64)) template yes_type is_function_ptr_tester(R(__vectorcall*)(T0)); #endif @@ -92,7 +92,7 @@ yes_type is_function_ptr_tester(R(*)(T0, T1 ...)); #ifdef BOOST_TT_TEST_MS_FUNC_SIGS template yes_type is_function_ptr_tester(R(__stdcall*)(T0, T1)); -#if (_MSC_VER >= 1800) && !defined(__CLR_VER) && (defined(_M_IX86_FP) && (_M_IX86_FP >= 2) || defined(_M_X64)) +#if (_MSC_VER >= 1800) && !defined(_MANAGED) && (defined(_M_IX86_FP) && (_M_IX86_FP >= 2) || defined(_M_X64)) template yes_type is_function_ptr_tester(R(__vectorcall*)(T0, T1)); #endif @@ -112,7 +112,7 @@ yes_type is_function_ptr_tester(R(*)(T0, T1, T2 ...)); #ifdef BOOST_TT_TEST_MS_FUNC_SIGS template yes_type is_function_ptr_tester(R(__stdcall*)(T0, T1, T2)); -#if (_MSC_VER >= 1800) && !defined(__CLR_VER) && (defined(_M_IX86_FP) && (_M_IX86_FP >= 2) || defined(_M_X64)) +#if (_MSC_VER >= 1800) && !defined(_MANAGED) && (defined(_M_IX86_FP) && (_M_IX86_FP >= 2) || defined(_M_X64)) template yes_type is_function_ptr_tester(R(__vectorcall*)(T0, T1, T2)); #endif @@ -132,7 +132,7 @@ yes_type is_function_ptr_tester(R(*)(T0, T1, T2, T3 ...)); #ifdef BOOST_TT_TEST_MS_FUNC_SIGS template yes_type is_function_ptr_tester(R(__stdcall*)(T0, T1, T2, T3)); -#if (_MSC_VER >= 1800) && !defined(__CLR_VER) && (defined(_M_IX86_FP) && (_M_IX86_FP >= 2) || defined(_M_X64)) +#if (_MSC_VER >= 1800) && !defined(_MANAGED) && (defined(_M_IX86_FP) && (_M_IX86_FP >= 2) || defined(_M_X64)) template yes_type is_function_ptr_tester(R(__vectorcall*)(T0, T1, T2, T3)); #endif @@ -152,7 +152,7 @@ yes_type is_function_ptr_tester(R(*)(T0, T1, T2, T3, T4 ...)); #ifdef BOOST_TT_TEST_MS_FUNC_SIGS template yes_type is_function_ptr_tester(R(__stdcall*)(T0, T1, T2, T3, T4)); -#if (_MSC_VER >= 1800) && !defined(__CLR_VER) && (defined(_M_IX86_FP) && (_M_IX86_FP >= 2) || defined(_M_X64)) +#if (_MSC_VER >= 1800) && !defined(_MANAGED) && (defined(_M_IX86_FP) && (_M_IX86_FP >= 2) || defined(_M_X64)) template yes_type is_function_ptr_tester(R(__vectorcall*)(T0, T1, T2, T3, T4)); #endif @@ -172,7 +172,7 @@ yes_type is_function_ptr_tester(R(*)(T0, T1, T2, T3, T4, T5 ...)); #ifdef BOOST_TT_TEST_MS_FUNC_SIGS template yes_type is_function_ptr_tester(R(__stdcall*)(T0, T1, T2, T3, T4, T5)); -#if (_MSC_VER >= 1800) && !defined(__CLR_VER) && (defined(_M_IX86_FP) && (_M_IX86_FP >= 2) || defined(_M_X64)) +#if (_MSC_VER >= 1800) && !defined(_MANAGED) && (defined(_M_IX86_FP) && (_M_IX86_FP >= 2) || defined(_M_X64)) template yes_type is_function_ptr_tester(R(__vectorcall*)(T0, T1, T2, T3, T4, T5)); #endif @@ -192,7 +192,7 @@ yes_type is_function_ptr_tester(R(*)(T0, T1, T2, T3, T4, T5, T6 ...)); #ifdef BOOST_TT_TEST_MS_FUNC_SIGS template yes_type is_function_ptr_tester(R(__stdcall*)(T0, T1, T2, T3, T4, T5, T6)); -#if (_MSC_VER >= 1800) && !defined(__CLR_VER) && (defined(_M_IX86_FP) && (_M_IX86_FP >= 2) || defined(_M_X64)) +#if (_MSC_VER >= 1800) && !defined(_MANAGED) && (defined(_M_IX86_FP) && (_M_IX86_FP >= 2) || defined(_M_X64)) template yes_type is_function_ptr_tester(R(__vectorcall*)(T0, T1, T2, T3, T4, T5, T6)); #endif @@ -212,7 +212,7 @@ yes_type is_function_ptr_tester(R(*)(T0, T1, T2, T3, T4, T5, T6, T7 ...)); #ifdef BOOST_TT_TEST_MS_FUNC_SIGS template yes_type is_function_ptr_tester(R(__stdcall*)(T0, T1, T2, T3, T4, T5, T6, T7)); -#if (_MSC_VER >= 1800) && !defined(__CLR_VER) && (defined(_M_IX86_FP) && (_M_IX86_FP >= 2) || defined(_M_X64)) +#if (_MSC_VER >= 1800) && !defined(_MANAGED) && (defined(_M_IX86_FP) && (_M_IX86_FP >= 2) || defined(_M_X64)) template yes_type is_function_ptr_tester(R(__vectorcall*)(T0, T1, T2, T3, T4, T5, T6, T7)); #endif @@ -232,7 +232,7 @@ yes_type is_function_ptr_tester(R(*)(T0, T1, T2, T3, T4, T5, T6, T7, T8 ...)); #ifdef BOOST_TT_TEST_MS_FUNC_SIGS template yes_type is_function_ptr_tester(R(__stdcall*)(T0, T1, T2, T3, T4, T5, T6, T7, T8)); -#if (_MSC_VER >= 1800) && !defined(__CLR_VER) && (defined(_M_IX86_FP) && (_M_IX86_FP >= 2) || defined(_M_X64)) +#if (_MSC_VER >= 1800) && !defined(_MANAGED) && (defined(_M_IX86_FP) && (_M_IX86_FP >= 2) || defined(_M_X64)) template yes_type is_function_ptr_tester(R(__vectorcall*)(T0, T1, T2, T3, T4, T5, T6, T7, T8)); #endif @@ -252,7 +252,7 @@ yes_type is_function_ptr_tester(R(*)(T0, T1, T2, T3, T4, T5, T6, T7, T8, T9 ...) #ifdef BOOST_TT_TEST_MS_FUNC_SIGS template yes_type is_function_ptr_tester(R(__stdcall*)(T0, T1, T2, T3, T4, T5, T6, T7, T8, T9)); -#if (_MSC_VER >= 1800) && !defined(__CLR_VER) && (defined(_M_IX86_FP) && (_M_IX86_FP >= 2) || defined(_M_X64)) +#if (_MSC_VER >= 1800) && !defined(_MANAGED) && (defined(_M_IX86_FP) && (_M_IX86_FP >= 2) || defined(_M_X64)) template yes_type is_function_ptr_tester(R(__vectorcall*)(T0, T1, T2, T3, T4, T5, T6, T7, T8, T9)); #endif @@ -272,7 +272,7 @@ yes_type is_function_ptr_tester(R(*)(T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10 #ifdef BOOST_TT_TEST_MS_FUNC_SIGS template yes_type is_function_ptr_tester(R(__stdcall*)(T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10)); -#if (_MSC_VER >= 1800) && !defined(__CLR_VER) && (defined(_M_IX86_FP) && (_M_IX86_FP >= 2) || defined(_M_X64)) +#if (_MSC_VER >= 1800) && !defined(_MANAGED) && (defined(_M_IX86_FP) && (_M_IX86_FP >= 2) || defined(_M_X64)) template yes_type is_function_ptr_tester(R(__vectorcall*)(T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10)); #endif @@ -292,7 +292,7 @@ yes_type is_function_ptr_tester(R(*)(T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10 #ifdef BOOST_TT_TEST_MS_FUNC_SIGS template yes_type is_function_ptr_tester(R(__stdcall*)(T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11)); -#if (_MSC_VER >= 1800) && !defined(__CLR_VER) && (defined(_M_IX86_FP) && (_M_IX86_FP >= 2) || defined(_M_X64)) +#if (_MSC_VER >= 1800) && !defined(_MANAGED) && (defined(_M_IX86_FP) && (_M_IX86_FP >= 2) || defined(_M_X64)) template yes_type is_function_ptr_tester(R(__vectorcall*)(T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11)); #endif @@ -312,7 +312,7 @@ yes_type is_function_ptr_tester(R(*)(T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10 #ifdef BOOST_TT_TEST_MS_FUNC_SIGS template yes_type is_function_ptr_tester(R(__stdcall*)(T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12)); -#if (_MSC_VER >= 1800) && !defined(__CLR_VER) && (defined(_M_IX86_FP) && (_M_IX86_FP >= 2) || defined(_M_X64)) +#if (_MSC_VER >= 1800) && !defined(_MANAGED) && (defined(_M_IX86_FP) && (_M_IX86_FP >= 2) || defined(_M_X64)) template yes_type is_function_ptr_tester(R(__vectorcall*)(T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12)); #endif @@ -332,7 +332,7 @@ yes_type is_function_ptr_tester(R(*)(T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10 #ifdef BOOST_TT_TEST_MS_FUNC_SIGS template yes_type is_function_ptr_tester(R(__stdcall*)(T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13)); -#if (_MSC_VER >= 1800) && !defined(__CLR_VER) && (defined(_M_IX86_FP) && (_M_IX86_FP >= 2) || defined(_M_X64)) +#if (_MSC_VER >= 1800) && !defined(_MANAGED) && (defined(_M_IX86_FP) && (_M_IX86_FP >= 2) || defined(_M_X64)) template yes_type is_function_ptr_tester(R(__vectorcall*)(T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13)); #endif @@ -352,7 +352,7 @@ yes_type is_function_ptr_tester(R(*)(T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10 #ifdef BOOST_TT_TEST_MS_FUNC_SIGS template yes_type is_function_ptr_tester(R(__stdcall*)(T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14)); -#if (_MSC_VER >= 1800) && !defined(__CLR_VER) && (defined(_M_IX86_FP) && (_M_IX86_FP >= 2) || defined(_M_X64)) +#if (_MSC_VER >= 1800) && !defined(_MANAGED) && (defined(_M_IX86_FP) && (_M_IX86_FP >= 2) || defined(_M_X64)) template yes_type is_function_ptr_tester(R(__vectorcall*)(T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14)); #endif @@ -372,7 +372,7 @@ yes_type is_function_ptr_tester(R(*)(T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10 #ifdef BOOST_TT_TEST_MS_FUNC_SIGS template yes_type is_function_ptr_tester(R(__stdcall*)(T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15)); -#if (_MSC_VER >= 1800) && !defined(__CLR_VER) && (defined(_M_IX86_FP) && (_M_IX86_FP >= 2) || defined(_M_X64)) +#if (_MSC_VER >= 1800) && !defined(_MANAGED) && (defined(_M_IX86_FP) && (_M_IX86_FP >= 2) || defined(_M_X64)) template yes_type is_function_ptr_tester(R(__vectorcall*)(T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15)); #endif @@ -392,7 +392,7 @@ yes_type is_function_ptr_tester(R(*)(T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10 #ifdef BOOST_TT_TEST_MS_FUNC_SIGS template yes_type is_function_ptr_tester(R(__stdcall*)(T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16)); -#if (_MSC_VER >= 1800) && !defined(__CLR_VER) && (defined(_M_IX86_FP) && (_M_IX86_FP >= 2) || defined(_M_X64)) +#if (_MSC_VER >= 1800) && !defined(_MANAGED) && (defined(_M_IX86_FP) && (_M_IX86_FP >= 2) || defined(_M_X64)) template yes_type is_function_ptr_tester(R(__vectorcall*)(T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16)); #endif @@ -412,7 +412,7 @@ yes_type is_function_ptr_tester(R(*)(T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10 #ifdef BOOST_TT_TEST_MS_FUNC_SIGS template yes_type is_function_ptr_tester(R(__stdcall*)(T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17)); -#if (_MSC_VER >= 1800) && !defined(__CLR_VER) && (defined(_M_IX86_FP) && (_M_IX86_FP >= 2) || defined(_M_X64)) +#if (_MSC_VER >= 1800) && !defined(_MANAGED) && (defined(_M_IX86_FP) && (_M_IX86_FP >= 2) || defined(_M_X64)) template yes_type is_function_ptr_tester(R(__vectorcall*)(T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17)); #endif @@ -432,7 +432,7 @@ yes_type is_function_ptr_tester(R(*)(T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10 #ifdef BOOST_TT_TEST_MS_FUNC_SIGS template yes_type is_function_ptr_tester(R(__stdcall*)(T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18)); -#if (_MSC_VER >= 1800) && !defined(__CLR_VER) && (defined(_M_IX86_FP) && (_M_IX86_FP >= 2) || defined(_M_X64)) +#if (_MSC_VER >= 1800) && !defined(_MANAGED) && (defined(_M_IX86_FP) && (_M_IX86_FP >= 2) || defined(_M_X64)) template yes_type is_function_ptr_tester(R(__vectorcall*)(T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18)); #endif @@ -452,7 +452,7 @@ yes_type is_function_ptr_tester(R(*)(T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10 #ifdef BOOST_TT_TEST_MS_FUNC_SIGS template yes_type is_function_ptr_tester(R(__stdcall*)(T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19)); -#if (_MSC_VER >= 1800) && !defined(__CLR_VER) && (defined(_M_IX86_FP) && (_M_IX86_FP >= 2) || defined(_M_X64)) +#if (_MSC_VER >= 1800) && !defined(_MANAGED) && (defined(_M_IX86_FP) && (_M_IX86_FP >= 2) || defined(_M_X64)) template yes_type is_function_ptr_tester(R(__vectorcall*)(T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19)); #endif @@ -472,7 +472,7 @@ yes_type is_function_ptr_tester(R(*)(T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10 #ifdef BOOST_TT_TEST_MS_FUNC_SIGS template yes_type is_function_ptr_tester(R(__stdcall*)(T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19, T20)); -#if (_MSC_VER >= 1800) && !defined(__CLR_VER) && (defined(_M_IX86_FP) && (_M_IX86_FP >= 2) || defined(_M_X64)) +#if (_MSC_VER >= 1800) && !defined(_MANAGED) && (defined(_M_IX86_FP) && (_M_IX86_FP >= 2) || defined(_M_X64)) template yes_type is_function_ptr_tester(R(__vectorcall*)(T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19, T20)); #endif @@ -492,7 +492,7 @@ yes_type is_function_ptr_tester(R(*)(T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10 #ifdef BOOST_TT_TEST_MS_FUNC_SIGS template yes_type is_function_ptr_tester(R(__stdcall*)(T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, T21)); -#if (_MSC_VER >= 1800) && !defined(__CLR_VER) && (defined(_M_IX86_FP) && (_M_IX86_FP >= 2) || defined(_M_X64)) +#if (_MSC_VER >= 1800) && !defined(_MANAGED) && (defined(_M_IX86_FP) && (_M_IX86_FP >= 2) || defined(_M_X64)) template yes_type is_function_ptr_tester(R(__vectorcall*)(T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, T21)); #endif @@ -512,7 +512,7 @@ yes_type is_function_ptr_tester(R(*)(T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10 #ifdef BOOST_TT_TEST_MS_FUNC_SIGS template yes_type is_function_ptr_tester(R(__stdcall*)(T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, T21, T22)); -#if (_MSC_VER >= 1800) && !defined(__CLR_VER) && (defined(_M_IX86_FP) && (_M_IX86_FP >= 2) || defined(_M_X64)) +#if (_MSC_VER >= 1800) && !defined(_MANAGED) && (defined(_M_IX86_FP) && (_M_IX86_FP >= 2) || defined(_M_X64)) template yes_type is_function_ptr_tester(R(__vectorcall*)(T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, T21, T22)); #endif @@ -532,7 +532,7 @@ yes_type is_function_ptr_tester(R(*)(T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10 #ifdef BOOST_TT_TEST_MS_FUNC_SIGS template yes_type is_function_ptr_tester(R(__stdcall*)(T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, T23)); -#if (_MSC_VER >= 1800) && !defined(__CLR_VER) && (defined(_M_IX86_FP) && (_M_IX86_FP >= 2) || defined(_M_X64)) +#if (_MSC_VER >= 1800) && !defined(_MANAGED) && (defined(_M_IX86_FP) && (_M_IX86_FP >= 2) || defined(_M_X64)) template yes_type is_function_ptr_tester(R(__vectorcall*)(T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, T23)); #endif @@ -552,7 +552,7 @@ yes_type is_function_ptr_tester(R(*)(T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10 #ifdef BOOST_TT_TEST_MS_FUNC_SIGS template yes_type is_function_ptr_tester(R(__stdcall*)(T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24)); -#if (_MSC_VER >= 1800) && !defined(__CLR_VER) && (defined(_M_IX86_FP) && (_M_IX86_FP >= 2) || defined(_M_X64)) +#if (_MSC_VER >= 1800) && !defined(_MANAGED) && (defined(_M_IX86_FP) && (_M_IX86_FP >= 2) || defined(_M_X64)) template yes_type is_function_ptr_tester(R(__vectorcall*)(T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24)); #endif @@ -593,7 +593,7 @@ yes_type is_function_ptr_tester(R (*)(BOOST_PP_ENUM_PARAMS(BOOST_PP_COUNTER,T) . @#ifdef BOOST_TT_TEST_MS_FUNC_SIGS template yes_type is_function_ptr_tester(R (__stdcall*)(BOOST_PP_ENUM_PARAMS(BOOST_PP_COUNTER,T))); -@#if (_MSC_VER >= 1800) && !defined(__CLR_VER) && (defined(_M_IX86_FP) && (_M_IX86_FP >= 2) || defined(_M_X64)) +@#if (_MSC_VER >= 1800) && !defined(_MANAGED) && (defined(_M_IX86_FP) && (_M_IX86_FP >= 2) || defined(_M_X64)) template yes_type is_function_ptr_tester(R(__vectorcall*)(BOOST_PP_ENUM_PARAMS(BOOST_PP_COUNTER, T))); @#endif diff --git a/include/boost/type_traits/detail/is_likely_lambda.hpp b/include/boost/type_traits/detail/is_likely_lambda.hpp index 21810dda4..893b4ba05 100644 --- a/include/boost/type_traits/detail/is_likely_lambda.hpp +++ b/include/boost/type_traits/detail/is_likely_lambda.hpp @@ -28,7 +28,7 @@ struct is_likely_stateless_lambda : public false_type {}; }} #elif !defined(BOOST_NO_CXX11_LAMBDAS) && !defined(BOOST_NO_CXX11_DECLTYPE) && !defined(BOOST_NO_CXX11_TEMPLATE_ALIASES) && !BOOST_WORKAROUND(BOOST_MSVC, < 1900)\ - && !(BOOST_WORKAROUND(BOOST_MSVC, == 1900) && defined(__CLR_VER)) + && !(BOOST_WORKAROUND(BOOST_MSVC, == 1900) && defined(_MANAGED)) #include #include diff --git a/include/boost/type_traits/detail/is_mem_fun_pointer_impl.hpp b/include/boost/type_traits/detail/is_mem_fun_pointer_impl.hpp index dcc6e2a0a..90b825dd0 100644 --- a/include/boost/type_traits/detail/is_mem_fun_pointer_impl.hpp +++ b/include/boost/type_traits/detail/is_mem_fun_pointer_impl.hpp @@ -67,7 +67,7 @@ template struct is_mem_fun_pointer_impl { BOOST_STATIC_CONSTANT(bool, value = true); }; #endif #endif -#if __cpp_noexcept_function_type +#ifdef __cpp_noexcept_function_type template struct is_mem_fun_pointer_impl { BOOST_STATIC_CONSTANT(bool, value = true); }; #ifndef BOOST_TT_NO_ELLIPSIS_IN_FUNC_TESTING @@ -113,7 +113,7 @@ template struct is_mem_fun_pointer_impl { BOOST_STATIC_CONSTANT(bool, value = true); }; #endif #endif -#if __cpp_noexcept_function_type +#ifdef __cpp_noexcept_function_type template struct is_mem_fun_pointer_impl { BOOST_STATIC_CONSTANT(bool, value = true); }; #ifndef BOOST_TT_NO_ELLIPSIS_IN_FUNC_TESTING @@ -159,7 +159,7 @@ template struct is_mem_fun_pointer_impl { BOOST_STATIC_CONSTANT(bool, value = true); }; #endif #endif -#if __cpp_noexcept_function_type +#ifdef __cpp_noexcept_function_type template struct is_mem_fun_pointer_impl { BOOST_STATIC_CONSTANT(bool, value = true); }; #ifndef BOOST_TT_NO_ELLIPSIS_IN_FUNC_TESTING @@ -205,7 +205,7 @@ template struct is_mem_fun_pointer_impl { BOOST_STATIC_CONSTANT(bool, value = true); }; #endif #endif -#if __cpp_noexcept_function_type +#ifdef __cpp_noexcept_function_type template struct is_mem_fun_pointer_impl { BOOST_STATIC_CONSTANT(bool, value = true); }; #ifndef BOOST_TT_NO_ELLIPSIS_IN_FUNC_TESTING @@ -251,7 +251,7 @@ template struct is_mem_fun_pointer_impl { BOOST_STATIC_CONSTANT(bool, value = true); }; #endif #endif -#if __cpp_noexcept_function_type +#ifdef __cpp_noexcept_function_type template struct is_mem_fun_pointer_impl { BOOST_STATIC_CONSTANT(bool, value = true); }; #ifndef BOOST_TT_NO_ELLIPSIS_IN_FUNC_TESTING @@ -297,7 +297,7 @@ template struct is_mem_fun_pointer_impl { BOOST_STATIC_CONSTANT(bool, value = true); }; #endif #endif -#if __cpp_noexcept_function_type +#ifdef __cpp_noexcept_function_type template struct is_mem_fun_pointer_impl { BOOST_STATIC_CONSTANT(bool, value = true); }; #ifndef BOOST_TT_NO_ELLIPSIS_IN_FUNC_TESTING @@ -343,7 +343,7 @@ template { BOOST_STATIC_CONSTANT(bool, value = true); }; #endif #endif -#if __cpp_noexcept_function_type +#ifdef __cpp_noexcept_function_type template struct is_mem_fun_pointer_impl { BOOST_STATIC_CONSTANT(bool, value = true); }; #ifndef BOOST_TT_NO_ELLIPSIS_IN_FUNC_TESTING @@ -389,7 +389,7 @@ template { BOOST_STATIC_CONSTANT(bool, value = true); }; #endif #endif -#if __cpp_noexcept_function_type +#ifdef __cpp_noexcept_function_type template struct is_mem_fun_pointer_impl { BOOST_STATIC_CONSTANT(bool, value = true); }; #ifndef BOOST_TT_NO_ELLIPSIS_IN_FUNC_TESTING @@ -435,7 +435,7 @@ template { BOOST_STATIC_CONSTANT(bool, value = true); }; #endif #endif -#if __cpp_noexcept_function_type +#ifdef __cpp_noexcept_function_type template struct is_mem_fun_pointer_impl { BOOST_STATIC_CONSTANT(bool, value = true); }; #ifndef BOOST_TT_NO_ELLIPSIS_IN_FUNC_TESTING @@ -481,7 +481,7 @@ template { BOOST_STATIC_CONSTANT(bool, value = true); }; #endif #endif -#if __cpp_noexcept_function_type +#ifdef __cpp_noexcept_function_type template struct is_mem_fun_pointer_impl { BOOST_STATIC_CONSTANT(bool, value = true); }; #ifndef BOOST_TT_NO_ELLIPSIS_IN_FUNC_TESTING @@ -527,7 +527,7 @@ template { BOOST_STATIC_CONSTANT(bool, value = true); }; #endif #endif -#if __cpp_noexcept_function_type +#ifdef __cpp_noexcept_function_type template struct is_mem_fun_pointer_impl { BOOST_STATIC_CONSTANT(bool, value = true); }; #ifndef BOOST_TT_NO_ELLIPSIS_IN_FUNC_TESTING @@ -573,7 +573,7 @@ template { BOOST_STATIC_CONSTANT(bool, value = true); }; #endif #endif -#if __cpp_noexcept_function_type +#ifdef __cpp_noexcept_function_type template struct is_mem_fun_pointer_impl { BOOST_STATIC_CONSTANT(bool, value = true); }; #ifndef BOOST_TT_NO_ELLIPSIS_IN_FUNC_TESTING @@ -619,7 +619,7 @@ template { BOOST_STATIC_CONSTANT(bool, value = true); }; #endif #endif -#if __cpp_noexcept_function_type +#ifdef __cpp_noexcept_function_type template struct is_mem_fun_pointer_impl { BOOST_STATIC_CONSTANT(bool, value = true); }; #ifndef BOOST_TT_NO_ELLIPSIS_IN_FUNC_TESTING @@ -665,7 +665,7 @@ template { BOOST_STATIC_CONSTANT(bool, value = true); }; #endif #endif -#if __cpp_noexcept_function_type +#ifdef __cpp_noexcept_function_type template struct is_mem_fun_pointer_impl { BOOST_STATIC_CONSTANT(bool, value = true); }; #ifndef BOOST_TT_NO_ELLIPSIS_IN_FUNC_TESTING @@ -711,7 +711,7 @@ template { BOOST_STATIC_CONSTANT(bool, value = true); }; #endif #endif -#if __cpp_noexcept_function_type +#ifdef __cpp_noexcept_function_type template struct is_mem_fun_pointer_impl { BOOST_STATIC_CONSTANT(bool, value = true); }; #ifndef BOOST_TT_NO_ELLIPSIS_IN_FUNC_TESTING @@ -757,7 +757,7 @@ template { BOOST_STATIC_CONSTANT(bool, value = true); }; #endif #endif -#if __cpp_noexcept_function_type +#ifdef __cpp_noexcept_function_type template struct is_mem_fun_pointer_impl { BOOST_STATIC_CONSTANT(bool, value = true); }; #ifndef BOOST_TT_NO_ELLIPSIS_IN_FUNC_TESTING @@ -803,7 +803,7 @@ template { BOOST_STATIC_CONSTANT(bool, value = true); }; #endif #endif -#if __cpp_noexcept_function_type +#ifdef __cpp_noexcept_function_type template struct is_mem_fun_pointer_impl { BOOST_STATIC_CONSTANT(bool, value = true); }; #ifndef BOOST_TT_NO_ELLIPSIS_IN_FUNC_TESTING @@ -849,7 +849,7 @@ template { BOOST_STATIC_CONSTANT(bool, value = true); }; #endif #endif -#if __cpp_noexcept_function_type +#ifdef __cpp_noexcept_function_type template struct is_mem_fun_pointer_impl { BOOST_STATIC_CONSTANT(bool, value = true); }; #ifndef BOOST_TT_NO_ELLIPSIS_IN_FUNC_TESTING @@ -895,7 +895,7 @@ template { BOOST_STATIC_CONSTANT(bool, value = true); }; #endif #endif -#if __cpp_noexcept_function_type +#ifdef __cpp_noexcept_function_type template struct is_mem_fun_pointer_impl { BOOST_STATIC_CONSTANT(bool, value = true); }; #ifndef BOOST_TT_NO_ELLIPSIS_IN_FUNC_TESTING @@ -941,7 +941,7 @@ template { BOOST_STATIC_CONSTANT(bool, value = true); }; #endif #endif -#if __cpp_noexcept_function_type +#ifdef __cpp_noexcept_function_type template struct is_mem_fun_pointer_impl { BOOST_STATIC_CONSTANT(bool, value = true); }; #ifndef BOOST_TT_NO_ELLIPSIS_IN_FUNC_TESTING @@ -987,7 +987,7 @@ template { BOOST_STATIC_CONSTANT(bool, value = true); }; #endif #endif -#if __cpp_noexcept_function_type +#ifdef __cpp_noexcept_function_type template struct is_mem_fun_pointer_impl { BOOST_STATIC_CONSTANT(bool, value = true); }; #ifndef BOOST_TT_NO_ELLIPSIS_IN_FUNC_TESTING @@ -1033,7 +1033,7 @@ template { BOOST_STATIC_CONSTANT(bool, value = true); }; #endif #endif -#if __cpp_noexcept_function_type +#ifdef __cpp_noexcept_function_type template struct is_mem_fun_pointer_impl { BOOST_STATIC_CONSTANT(bool, value = true); }; #ifndef BOOST_TT_NO_ELLIPSIS_IN_FUNC_TESTING @@ -1079,7 +1079,7 @@ template { BOOST_STATIC_CONSTANT(bool, value = true); }; #endif #endif -#if __cpp_noexcept_function_type +#ifdef __cpp_noexcept_function_type template struct is_mem_fun_pointer_impl { BOOST_STATIC_CONSTANT(bool, value = true); }; #ifndef BOOST_TT_NO_ELLIPSIS_IN_FUNC_TESTING @@ -1125,7 +1125,7 @@ template { BOOST_STATIC_CONSTANT(bool, value = true); }; #endif #endif -#if __cpp_noexcept_function_type +#ifdef __cpp_noexcept_function_type template struct is_mem_fun_pointer_impl { BOOST_STATIC_CONSTANT(bool, value = true); }; #ifndef BOOST_TT_NO_ELLIPSIS_IN_FUNC_TESTING @@ -1171,7 +1171,7 @@ template { BOOST_STATIC_CONSTANT(bool, value = true); }; #endif #endif -#if __cpp_noexcept_function_type +#ifdef __cpp_noexcept_function_type template struct is_mem_fun_pointer_impl { BOOST_STATIC_CONSTANT(bool, value = true); }; #ifndef BOOST_TT_NO_ELLIPSIS_IN_FUNC_TESTING @@ -1217,7 +1217,7 @@ template { BOOST_STATIC_CONSTANT(bool, value = true); }; #endif #endif -#if __cpp_noexcept_function_type +#ifdef __cpp_noexcept_function_type template struct is_mem_fun_pointer_impl { BOOST_STATIC_CONSTANT(bool, value = true); }; #ifndef BOOST_TT_NO_ELLIPSIS_IN_FUNC_TESTING @@ -1290,7 +1290,7 @@ struct is_mem_fun_pointer_impl struct is_mem_fun_pointer_impl { BOOST_STATIC_CONSTANT(bool, value = true); }; diff --git a/include/boost/type_traits/detail/is_mem_fun_pointer_tester.hpp b/include/boost/type_traits/detail/is_mem_fun_pointer_tester.hpp index 2de883ffb..083a10fd2 100644 --- a/include/boost/type_traits/detail/is_mem_fun_pointer_tester.hpp +++ b/include/boost/type_traits/detail/is_mem_fun_pointer_tester.hpp @@ -69,7 +69,7 @@ template yes_type is_mem_fun_pointer_tester(R(__stdcall T::*const volatile*)() volatile); template yes_type is_mem_fun_pointer_tester(R(__stdcall T::*const volatile*)() const volatile); -#if (_MSC_VER >= 1800) && !defined(__CLR_VER) && (defined(_M_IX86_FP) && (_M_IX86_FP >= 2) || defined(_M_X64)) +#if (_MSC_VER >= 1800) && !defined(_MANAGED) && (defined(_M_IX86_FP) && (_M_IX86_FP >= 2) || defined(_M_X64)) template yes_type is_mem_fun_pointer_tester(R(__vectorcall T::*const volatile*)()); template @@ -125,7 +125,7 @@ template yes_type is_mem_fun_pointer_tester(R(__stdcall T::*const volatile*)(T0) volatile); template yes_type is_mem_fun_pointer_tester(R(__stdcall T::*const volatile*)(T0) const volatile); -#if (_MSC_VER >= 1800) && !defined(__CLR_VER) && (defined(_M_IX86_FP) && (_M_IX86_FP >= 2) || defined(_M_X64)) +#if (_MSC_VER >= 1800) && !defined(_MANAGED) && (defined(_M_IX86_FP) && (_M_IX86_FP >= 2) || defined(_M_X64)) template yes_type is_mem_fun_pointer_tester(R(__vectorcall T::*const volatile*)(T0)); template @@ -181,7 +181,7 @@ template yes_type is_mem_fun_pointer_tester(R(__stdcall T::*const volatile*)(T0, T1) volatile); template yes_type is_mem_fun_pointer_tester(R(__stdcall T::*const volatile*)(T0, T1) const volatile); -#if (_MSC_VER >= 1800) && !defined(__CLR_VER) && (defined(_M_IX86_FP) && (_M_IX86_FP >= 2) || defined(_M_X64)) +#if (_MSC_VER >= 1800) && !defined(_MANAGED) && (defined(_M_IX86_FP) && (_M_IX86_FP >= 2) || defined(_M_X64)) template yes_type is_mem_fun_pointer_tester(R(__vectorcall T::*const volatile*)(T0, T1)); template @@ -237,7 +237,7 @@ template yes_type is_mem_fun_pointer_tester(R(__stdcall T::*const volatile*)(T0, T1, T2) volatile); template yes_type is_mem_fun_pointer_tester(R(__stdcall T::*const volatile*)(T0, T1, T2) const volatile); -#if (_MSC_VER >= 1800) && !defined(__CLR_VER) && (defined(_M_IX86_FP) && (_M_IX86_FP >= 2) || defined(_M_X64)) +#if (_MSC_VER >= 1800) && !defined(_MANAGED) && (defined(_M_IX86_FP) && (_M_IX86_FP >= 2) || defined(_M_X64)) template yes_type is_mem_fun_pointer_tester(R(__vectorcall T::*const volatile*)(T0, T1, T2)); template @@ -293,7 +293,7 @@ template yes_type is_mem_fun_pointer_tester(R(__stdcall T::*const volatile*)(T0, T1, T2, T3) volatile); template yes_type is_mem_fun_pointer_tester(R(__stdcall T::*const volatile*)(T0, T1, T2, T3) const volatile); -#if (_MSC_VER >= 1800) && !defined(__CLR_VER) && (defined(_M_IX86_FP) && (_M_IX86_FP >= 2) || defined(_M_X64)) +#if (_MSC_VER >= 1800) && !defined(_MANAGED) && (defined(_M_IX86_FP) && (_M_IX86_FP >= 2) || defined(_M_X64)) template yes_type is_mem_fun_pointer_tester(R(__vectorcall T::*const volatile*)(T0, T1, T2, T3)); template @@ -349,7 +349,7 @@ template yes_type is_mem_fun_pointer_tester(R(__stdcall T::*const volatile*)(T0, T1, T2, T3, T4) volatile); template yes_type is_mem_fun_pointer_tester(R(__stdcall T::*const volatile*)(T0, T1, T2, T3, T4) const volatile); -#if (_MSC_VER >= 1800) && !defined(__CLR_VER) && (defined(_M_IX86_FP) && (_M_IX86_FP >= 2) || defined(_M_X64)) +#if (_MSC_VER >= 1800) && !defined(_MANAGED) && (defined(_M_IX86_FP) && (_M_IX86_FP >= 2) || defined(_M_X64)) template yes_type is_mem_fun_pointer_tester(R(__vectorcall T::*const volatile*)(T0, T1, T2, T3, T4)); template @@ -405,7 +405,7 @@ template yes_type is_mem_fun_pointer_tester(R(__stdcall T::*const volatile*)(T0, T1, T2, T3, T4, T5) const volatile); -#if (_MSC_VER >= 1800) && !defined(__CLR_VER) && (defined(_M_IX86_FP) && (_M_IX86_FP >= 2) || defined(_M_X64)) +#if (_MSC_VER >= 1800) && !defined(_MANAGED) && (defined(_M_IX86_FP) && (_M_IX86_FP >= 2) || defined(_M_X64)) template yes_type is_mem_fun_pointer_tester(R(__vectorcall T::*const volatile*)(T0, T1, T2, T3, T4, T5)); template @@ -461,7 +461,7 @@ template yes_type is_mem_fun_pointer_tester(R(__stdcall T::*const volatile*)(T0, T1, T2, T3, T4, T5, T6) const volatile); -#if (_MSC_VER >= 1800) && !defined(__CLR_VER) && (defined(_M_IX86_FP) && (_M_IX86_FP >= 2) || defined(_M_X64)) +#if (_MSC_VER >= 1800) && !defined(_MANAGED) && (defined(_M_IX86_FP) && (_M_IX86_FP >= 2) || defined(_M_X64)) template yes_type is_mem_fun_pointer_tester(R(__vectorcall T::*const volatile*)(T0, T1, T2, T3, T4, T5, T6)); template @@ -517,7 +517,7 @@ template yes_type is_mem_fun_pointer_tester(R(__stdcall T::*const volatile*)(T0, T1, T2, T3, T4, T5, T6, T7) const volatile); -#if (_MSC_VER >= 1800) && !defined(__CLR_VER) && (defined(_M_IX86_FP) && (_M_IX86_FP >= 2) || defined(_M_X64)) +#if (_MSC_VER >= 1800) && !defined(_MANAGED) && (defined(_M_IX86_FP) && (_M_IX86_FP >= 2) || defined(_M_X64)) template yes_type is_mem_fun_pointer_tester(R(__vectorcall T::*const volatile*)(T0, T1, T2, T3, T4, T5, T6, T7)); template @@ -573,7 +573,7 @@ template yes_type is_mem_fun_pointer_tester(R(__stdcall T::*const volatile*)(T0, T1, T2, T3, T4, T5, T6, T7, T8) const volatile); -#if (_MSC_VER >= 1800) && !defined(__CLR_VER) && (defined(_M_IX86_FP) && (_M_IX86_FP >= 2) || defined(_M_X64)) +#if (_MSC_VER >= 1800) && !defined(_MANAGED) && (defined(_M_IX86_FP) && (_M_IX86_FP >= 2) || defined(_M_X64)) template yes_type is_mem_fun_pointer_tester(R(__vectorcall T::*const volatile*)(T0, T1, T2, T3, T4, T5, T6, T7, T8)); template @@ -629,7 +629,7 @@ template yes_type is_mem_fun_pointer_tester(R(__stdcall T::*const volatile*)(T0, T1, T2, T3, T4, T5, T6, T7, T8, T9) const volatile); -#if (_MSC_VER >= 1800) && !defined(__CLR_VER) && (defined(_M_IX86_FP) && (_M_IX86_FP >= 2) || defined(_M_X64)) +#if (_MSC_VER >= 1800) && !defined(_MANAGED) && (defined(_M_IX86_FP) && (_M_IX86_FP >= 2) || defined(_M_X64)) template yes_type is_mem_fun_pointer_tester(R(__vectorcall T::*const volatile*)(T0, T1, T2, T3, T4, T5, T6, T7, T8, T9)); template @@ -685,7 +685,7 @@ template yes_type is_mem_fun_pointer_tester(R(__stdcall T::*const volatile*)(T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10) const volatile); -#if (_MSC_VER >= 1800) && !defined(__CLR_VER) && (defined(_M_IX86_FP) && (_M_IX86_FP >= 2) || defined(_M_X64)) +#if (_MSC_VER >= 1800) && !defined(_MANAGED) && (defined(_M_IX86_FP) && (_M_IX86_FP >= 2) || defined(_M_X64)) template yes_type is_mem_fun_pointer_tester(R(__vectorcall T::*const volatile*)(T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10)); template @@ -741,7 +741,7 @@ template yes_type is_mem_fun_pointer_tester(R(__stdcall T::*const volatile*)(T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11) const volatile); -#if (_MSC_VER >= 1800) && !defined(__CLR_VER) && (defined(_M_IX86_FP) && (_M_IX86_FP >= 2) || defined(_M_X64)) +#if (_MSC_VER >= 1800) && !defined(_MANAGED) && (defined(_M_IX86_FP) && (_M_IX86_FP >= 2) || defined(_M_X64)) template yes_type is_mem_fun_pointer_tester(R(__vectorcall T::*const volatile*)(T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11)); template @@ -797,7 +797,7 @@ template yes_type is_mem_fun_pointer_tester(R(__stdcall T::*const volatile*)(T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12) const volatile); -#if (_MSC_VER >= 1800) && !defined(__CLR_VER) && (defined(_M_IX86_FP) && (_M_IX86_FP >= 2) || defined(_M_X64)) +#if (_MSC_VER >= 1800) && !defined(_MANAGED) && (defined(_M_IX86_FP) && (_M_IX86_FP >= 2) || defined(_M_X64)) template yes_type is_mem_fun_pointer_tester(R(__vectorcall T::*const volatile*)(T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12)); template @@ -853,7 +853,7 @@ template yes_type is_mem_fun_pointer_tester(R(__stdcall T::*const volatile*)(T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13) const volatile); -#if (_MSC_VER >= 1800) && !defined(__CLR_VER) && (defined(_M_IX86_FP) && (_M_IX86_FP >= 2) || defined(_M_X64)) +#if (_MSC_VER >= 1800) && !defined(_MANAGED) && (defined(_M_IX86_FP) && (_M_IX86_FP >= 2) || defined(_M_X64)) template yes_type is_mem_fun_pointer_tester(R(__vectorcall T::*const volatile*)(T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13)); template @@ -909,7 +909,7 @@ template yes_type is_mem_fun_pointer_tester(R(__stdcall T::*const volatile*)(T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14) const volatile); -#if (_MSC_VER >= 1800) && !defined(__CLR_VER) && (defined(_M_IX86_FP) && (_M_IX86_FP >= 2) || defined(_M_X64)) +#if (_MSC_VER >= 1800) && !defined(_MANAGED) && (defined(_M_IX86_FP) && (_M_IX86_FP >= 2) || defined(_M_X64)) template yes_type is_mem_fun_pointer_tester(R(__vectorcall T::*const volatile*)(T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14)); template @@ -965,7 +965,7 @@ template yes_type is_mem_fun_pointer_tester(R(__stdcall T::*const volatile*)(T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15) const volatile); -#if (_MSC_VER >= 1800) && !defined(__CLR_VER) && (defined(_M_IX86_FP) && (_M_IX86_FP >= 2) || defined(_M_X64)) +#if (_MSC_VER >= 1800) && !defined(_MANAGED) && (defined(_M_IX86_FP) && (_M_IX86_FP >= 2) || defined(_M_X64)) template yes_type is_mem_fun_pointer_tester(R(__vectorcall T::*const volatile*)(T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15)); template @@ -1021,7 +1021,7 @@ template yes_type is_mem_fun_pointer_tester(R(__stdcall T::*const volatile*)(T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16) const volatile); -#if (_MSC_VER >= 1800) && !defined(__CLR_VER) && (defined(_M_IX86_FP) && (_M_IX86_FP >= 2) || defined(_M_X64)) +#if (_MSC_VER >= 1800) && !defined(_MANAGED) && (defined(_M_IX86_FP) && (_M_IX86_FP >= 2) || defined(_M_X64)) template yes_type is_mem_fun_pointer_tester(R(__vectorcall T::*const volatile*)(T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16)); template @@ -1077,7 +1077,7 @@ template yes_type is_mem_fun_pointer_tester(R(__stdcall T::*const volatile*)(T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17) const volatile); -#if (_MSC_VER >= 1800) && !defined(__CLR_VER) && (defined(_M_IX86_FP) && (_M_IX86_FP >= 2) || defined(_M_X64)) +#if (_MSC_VER >= 1800) && !defined(_MANAGED) && (defined(_M_IX86_FP) && (_M_IX86_FP >= 2) || defined(_M_X64)) template yes_type is_mem_fun_pointer_tester(R(__vectorcall T::*const volatile*)(T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17)); template @@ -1133,7 +1133,7 @@ template yes_type is_mem_fun_pointer_tester(R(__stdcall T::*const volatile*)(T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18) const volatile); -#if (_MSC_VER >= 1800) && !defined(__CLR_VER) && (defined(_M_IX86_FP) && (_M_IX86_FP >= 2) || defined(_M_X64)) +#if (_MSC_VER >= 1800) && !defined(_MANAGED) && (defined(_M_IX86_FP) && (_M_IX86_FP >= 2) || defined(_M_X64)) template yes_type is_mem_fun_pointer_tester(R(__vectorcall T::*const volatile*)(T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18)); template @@ -1189,7 +1189,7 @@ template yes_type is_mem_fun_pointer_tester(R(__stdcall T::*const volatile*)(T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19) const volatile); -#if (_MSC_VER >= 1800) && !defined(__CLR_VER) && (defined(_M_IX86_FP) && (_M_IX86_FP >= 2) || defined(_M_X64)) +#if (_MSC_VER >= 1800) && !defined(_MANAGED) && (defined(_M_IX86_FP) && (_M_IX86_FP >= 2) || defined(_M_X64)) template yes_type is_mem_fun_pointer_tester(R(__vectorcall T::*const volatile*)(T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19)); template @@ -1245,7 +1245,7 @@ template yes_type is_mem_fun_pointer_tester(R(__stdcall T::*const volatile*)(T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19, T20) const volatile); -#if (_MSC_VER >= 1800) && !defined(__CLR_VER) && (defined(_M_IX86_FP) && (_M_IX86_FP >= 2) || defined(_M_X64)) +#if (_MSC_VER >= 1800) && !defined(_MANAGED) && (defined(_M_IX86_FP) && (_M_IX86_FP >= 2) || defined(_M_X64)) template yes_type is_mem_fun_pointer_tester(R(__vectorcall T::*const volatile*)(T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19, T20)); template @@ -1301,7 +1301,7 @@ template yes_type is_mem_fun_pointer_tester(R(__stdcall T::*const volatile*)(T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, T21) const volatile); -#if (_MSC_VER >= 1800) && !defined(__CLR_VER) && (defined(_M_IX86_FP) && (_M_IX86_FP >= 2) || defined(_M_X64)) +#if (_MSC_VER >= 1800) && !defined(_MANAGED) && (defined(_M_IX86_FP) && (_M_IX86_FP >= 2) || defined(_M_X64)) template yes_type is_mem_fun_pointer_tester(R(__vectorcall T::*const volatile*)(T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, T21)); template @@ -1357,7 +1357,7 @@ template yes_type is_mem_fun_pointer_tester(R(__stdcall T::*const volatile*)(T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, T21, T22) const volatile); -#if (_MSC_VER >= 1800) && !defined(__CLR_VER) && (defined(_M_IX86_FP) && (_M_IX86_FP >= 2) || defined(_M_X64)) +#if (_MSC_VER >= 1800) && !defined(_MANAGED) && (defined(_M_IX86_FP) && (_M_IX86_FP >= 2) || defined(_M_X64)) template yes_type is_mem_fun_pointer_tester(R(__vectorcall T::*const volatile*)(T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, T21, T22)); template @@ -1413,7 +1413,7 @@ template yes_type is_mem_fun_pointer_tester(R(__stdcall T::*const volatile*)(T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, T23) const volatile); -#if (_MSC_VER >= 1800) && !defined(__CLR_VER) && (defined(_M_IX86_FP) && (_M_IX86_FP >= 2) || defined(_M_X64)) +#if (_MSC_VER >= 1800) && !defined(_MANAGED) && (defined(_M_IX86_FP) && (_M_IX86_FP >= 2) || defined(_M_X64)) template yes_type is_mem_fun_pointer_tester(R(__vectorcall T::*const volatile*)(T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, T23)); template @@ -1469,7 +1469,7 @@ template yes_type is_mem_fun_pointer_tester(R(__stdcall T::*const volatile*)(T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24) const volatile); -#if (_MSC_VER >= 1800) && !defined(__CLR_VER) && (defined(_M_IX86_FP) && (_M_IX86_FP >= 2) || defined(_M_X64)) +#if (_MSC_VER >= 1800) && !defined(_MANAGED) && (defined(_M_IX86_FP) && (_M_IX86_FP >= 2) || defined(_M_X64)) template yes_type is_mem_fun_pointer_tester(R(__vectorcall T::*const volatile*)(T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24)); template @@ -1557,7 +1557,7 @@ yes_type is_mem_fun_pointer_tester(R (__stdcall T::*const volatile*)(BOOST_PP_EN template yes_type is_mem_fun_pointer_tester(R (__stdcall T::*const volatile*)(BOOST_PP_ENUM_PARAMS(BOOST_PP_COUNTER,T)) const volatile); -@#if (_MSC_VER >= 1800) && !defined(__CLR_VER) && (defined(_M_IX86_FP) && (_M_IX86_FP >= 2) || defined(_M_X64)) +@#if (_MSC_VER >= 1800) && !defined(_MANAGED) && (defined(_M_IX86_FP) && (_M_IX86_FP >= 2) || defined(_M_X64)) template yes_type is_mem_fun_pointer_tester(R (__vectorcall T::*const volatile*)(BOOST_PP_ENUM_PARAMS(BOOST_PP_COUNTER,T))); diff --git a/include/boost/type_traits/detail/is_member_function_pointer_cxx_11.hpp b/include/boost/type_traits/detail/is_member_function_pointer_cxx_11.hpp index b0502cbe8..ac3477b38 100644 --- a/include/boost/type_traits/detail/is_member_function_pointer_cxx_11.hpp +++ b/include/boost/type_traits/detail/is_member_function_pointer_cxx_11.hpp @@ -109,246 +109,259 @@ namespace boost { struct is_member_function_pointer : public true_type {}; #if defined(_MSC_VER) && !defined(_M_ARM) && !defined(_M_ARM64) -#ifdef __CLR_VER - template - struct is_member_function_pointer : public true_type {}; -#endif -#ifndef _M_AMD64 +#if !defined(_M_X64) && !defined(_M_CEE_SAFE) && !defined(_M_CEE_PURE) template struct is_member_function_pointer : public true_type {}; -#ifndef __CLR_VER template - struct is_member_function_pointer : public true_type {}; + struct is_member_function_pointer : public true_type {}; #endif +#ifdef _MANAGED template - struct is_member_function_pointer : public true_type {}; + struct is_member_function_pointer : public true_type {}; +#else +#ifndef _M_AMD64 + template + struct is_member_function_pointer : public true_type {}; #endif -#if !defined(__CLR_VER) && (defined(_M_IX86_FP) && (_M_IX86_FP >= 2) || defined(_M_X64)) +#if defined(_M_IX86_FP) && (_M_IX86_FP >= 2) || defined(_M_X64) template struct is_member_function_pointer : public true_type {}; +#endif #endif // const: -#ifdef __CLR_VER - template - struct is_member_function_pointer : public true_type {}; -#endif -#ifndef _M_AMD64 +#if !defined(_M_X64) && !defined(_M_CEE_SAFE) && !defined(_M_CEE_PURE) template struct is_member_function_pointer : public true_type {}; -#ifndef __CLR_VER template - struct is_member_function_pointer : public true_type {}; + struct is_member_function_pointer : public true_type {}; #endif +#ifdef _MANAGED template - struct is_member_function_pointer : public true_type {}; + struct is_member_function_pointer : public true_type {}; +#else +#ifndef _M_AMD64 + template + struct is_member_function_pointer : public true_type {}; #endif -#if !defined(__CLR_VER) && (defined(_M_IX86_FP) && (_M_IX86_FP >= 2) || defined(_M_X64)) +#if defined(_M_IX86_FP) && (_M_IX86_FP >= 2) || defined(_M_X64) template struct is_member_function_pointer : public true_type {}; +#endif #endif // volatile: -#ifdef __CLR_VER - template - struct is_member_function_pointer : public true_type {}; -#endif -#ifndef _M_AMD64 +#if !defined(_M_X64) && !defined(_M_CEE_SAFE) && !defined(_M_CEE_PURE) template struct is_member_function_pointer : public true_type {}; -#ifndef __CLR_VER template - struct is_member_function_pointer : public true_type {}; + struct is_member_function_pointer : public true_type {}; #endif +#ifdef _MANAGED template - struct is_member_function_pointer : public true_type {}; + struct is_member_function_pointer : public true_type {}; +#else +#ifndef _M_AMD64 + template + struct is_member_function_pointer : public true_type {}; #endif -#if !defined(__CLR_VER) && (defined(_M_IX86_FP) && (_M_IX86_FP >= 2) || defined(_M_X64)) +#if defined(_M_IX86_FP) && (_M_IX86_FP >= 2) || defined(_M_X64) template struct is_member_function_pointer : public true_type {}; +#endif #endif // const volatile: -#ifdef __CLR_VER - template - struct is_member_function_pointer : public true_type {}; -#endif -#ifndef _M_AMD64 +#if !defined(_M_X64) && !defined(_M_CEE_SAFE) && !defined(_M_CEE_PURE) template struct is_member_function_pointer : public true_type {}; -#ifndef __CLR_VER template - struct is_member_function_pointer : public true_type {}; + struct is_member_function_pointer : public true_type {}; #endif +#ifdef _MANAGED template - struct is_member_function_pointer : public true_type {}; + struct is_member_function_pointer : public true_type {}; +#else +#ifndef _M_AMD64 + template + struct is_member_function_pointer : public true_type {}; #endif -#if !defined(__CLR_VER) && (defined(_M_IX86_FP) && (_M_IX86_FP >= 2) || defined(_M_X64)) +#if defined(_M_IX86_FP) && (_M_IX86_FP >= 2) || defined(_M_X64) template struct is_member_function_pointer : public true_type {}; +#endif #endif // reference qualified: -#ifdef __CLR_VER - template - struct is_member_function_pointer : public true_type {}; -#endif -#ifndef _M_AMD64 +#if !defined(_M_X64) && !defined(_M_CEE_SAFE) && !defined(_M_CEE_PURE) template struct is_member_function_pointer : public true_type {}; -#ifndef __CLR_VER template - struct is_member_function_pointer : public true_type {}; + struct is_member_function_pointer : public true_type {}; #endif +#ifdef _MANAGED template - struct is_member_function_pointer : public true_type {}; + struct is_member_function_pointer : public true_type {}; +#else +#ifndef _M_AMD64 + template + struct is_member_function_pointer : public true_type {}; #endif -#if !defined(__CLR_VER) && (defined(_M_IX86_FP) && (_M_IX86_FP >= 2) || defined(_M_X64)) +#if defined(_M_IX86_FP) && (_M_IX86_FP >= 2) || defined(_M_X64) template struct is_member_function_pointer : public true_type {}; +#endif #endif // const: -#ifdef __CLR_VER - template - struct is_member_function_pointer : public true_type {}; -#endif -#ifndef _M_AMD64 +#if !defined(_M_X64) && !defined(_M_CEE_SAFE) && !defined(_M_CEE_PURE) template struct is_member_function_pointer : public true_type {}; -#ifndef __CLR_VER template - struct is_member_function_pointer : public true_type {}; + struct is_member_function_pointer : public true_type {}; #endif +#ifdef _MANAGED template - struct is_member_function_pointer : public true_type {}; + struct is_member_function_pointer : public true_type {}; +#else +#ifndef _M_AMD64 + template + struct is_member_function_pointer : public true_type {}; #endif -#if !defined(__CLR_VER) && (defined(_M_IX86_FP) && (_M_IX86_FP >= 2) || defined(_M_X64)) +#if defined(_M_IX86_FP) && (_M_IX86_FP >= 2) || defined(_M_X64) template struct is_member_function_pointer : public true_type {}; +#endif #endif // volatile: -#ifdef __CLR_VER - template - struct is_member_function_pointer : public true_type {}; -#endif -#ifndef _M_AMD64 +#if !defined(_M_X64) && !defined(_M_CEE_SAFE) && !defined(_M_CEE_PURE) template struct is_member_function_pointer : public true_type {}; -#ifndef __CLR_VER template - struct is_member_function_pointer : public true_type {}; + struct is_member_function_pointer : public true_type {}; #endif +#ifdef _MANAGED template - struct is_member_function_pointer : public true_type {}; + struct is_member_function_pointer : public true_type {}; +#else +#ifndef _M_AMD64 + template + struct is_member_function_pointer : public true_type {}; #endif -#if !defined(__CLR_VER) && (defined(_M_IX86_FP) && (_M_IX86_FP >= 2) || defined(_M_X64)) +#if defined(_M_IX86_FP) && (_M_IX86_FP >= 2) || defined(_M_X64) template struct is_member_function_pointer : public true_type {}; +#endif #endif // const volatile: -#ifdef __CLR_VER - template - struct is_member_function_pointer : public true_type {}; -#endif -#ifndef _M_AMD64 +#if !defined(_M_X64) && !defined(_M_CEE_SAFE) && !defined(_M_CEE_PURE) template struct is_member_function_pointer : public true_type {}; -#ifndef __CLR_VER template - struct is_member_function_pointer : public true_type {}; + struct is_member_function_pointer : public true_type {}; #endif +#ifdef _MANAGED template - struct is_member_function_pointer : public true_type {}; + struct is_member_function_pointer : public true_type {}; +#else +#ifndef _M_AMD64 + template + struct is_member_function_pointer : public true_type {}; #endif -#if !defined(__CLR_VER) && (defined(_M_IX86_FP) && (_M_IX86_FP >= 2) || defined(_M_X64)) +#if defined(_M_IX86_FP) && (_M_IX86_FP >= 2) || defined(_M_X64) template struct is_member_function_pointer : public true_type {}; +#endif #endif // rvalue reference qualified: -#ifdef __CLR_VER - template - struct is_member_function_pointer : public true_type {}; -#endif -#ifndef _M_AMD64 +#if !defined(_M_X64) && !defined(_M_CEE_SAFE) && !defined(_M_CEE_PURE) template struct is_member_function_pointer : public true_type {}; -#ifndef __CLR_VER template - struct is_member_function_pointer : public true_type {}; + struct is_member_function_pointer : public true_type {}; #endif +#ifdef _MANAGED template - struct is_member_function_pointer : public true_type {}; + struct is_member_function_pointer : public true_type {}; +#else +#ifndef _M_AMD64 + template + struct is_member_function_pointer : public true_type {}; #endif -#if !defined(__CLR_VER) && (defined(_M_IX86_FP) && (_M_IX86_FP >= 2) || defined(_M_X64)) +#if defined(_M_IX86_FP) && (_M_IX86_FP >= 2) || defined(_M_X64) template struct is_member_function_pointer : public true_type {}; +#endif #endif // const: -#ifdef __CLR_VER - template - struct is_member_function_pointer : public true_type {}; -#endif -#ifndef _M_AMD64 +#if !defined(_M_X64) && !defined(_M_CEE_SAFE) && !defined(_M_CEE_PURE) template struct is_member_function_pointer : public true_type {}; -#ifndef __CLR_VER template - struct is_member_function_pointer : public true_type {}; + struct is_member_function_pointer : public true_type {}; #endif +#ifdef _MANAGED template - struct is_member_function_pointer : public true_type {}; + struct is_member_function_pointer : public true_type {}; +#else +#ifndef _M_AMD64 + template + struct is_member_function_pointer : public true_type {}; #endif -#if !defined(__CLR_VER) && (defined(_M_IX86_FP) && (_M_IX86_FP >= 2) || defined(_M_X64)) +#if defined(_M_IX86_FP) && (_M_IX86_FP >= 2) || defined(_M_X64) template struct is_member_function_pointer : public true_type {}; +#endif #endif // volatile: -#ifdef __CLR_VER - template - struct is_member_function_pointer : public true_type {}; -#endif -#ifndef _M_AMD64 +#if !defined(_M_X64) && !defined(_M_CEE_SAFE) && !defined(_M_CEE_PURE) template struct is_member_function_pointer : public true_type {}; -#ifndef __CLR_VER template - struct is_member_function_pointer : public true_type {}; + struct is_member_function_pointer : public true_type {}; #endif +#ifdef _MANAGED template - struct is_member_function_pointer : public true_type {}; + struct is_member_function_pointer : public true_type {}; +#else +#ifndef _M_AMD64 + template + struct is_member_function_pointer : public true_type {}; #endif -#if !defined(__CLR_VER) && (defined(_M_IX86_FP) && (_M_IX86_FP >= 2) || defined(_M_X64)) +#if defined(_M_IX86_FP) && (_M_IX86_FP >= 2) || defined(_M_X64) template struct is_member_function_pointer : public true_type {}; +#endif #endif // const volatile: -#ifdef __CLR_VER - template - struct is_member_function_pointer : public true_type {}; -#endif -#ifndef _M_AMD64 +#if !defined(_M_X64) && !defined(_M_CEE_SAFE) && !defined(_M_CEE_PURE) template struct is_member_function_pointer : public true_type {}; -#ifndef __CLR_VER template - struct is_member_function_pointer : public true_type {}; + struct is_member_function_pointer : public true_type {}; #endif +#ifdef _MANAGED template - struct is_member_function_pointer : public true_type {}; + struct is_member_function_pointer : public true_type {}; +#else +#ifndef _M_AMD64 + template + struct is_member_function_pointer : public true_type {}; #endif -#if !defined(__CLR_VER) && (defined(_M_IX86_FP) && (_M_IX86_FP >= 2) || defined(_M_X64)) +#if defined(_M_IX86_FP) && (_M_IX86_FP >= 2) || defined(_M_X64) template struct is_member_function_pointer : public true_type {}; #endif #endif +#endif + #if defined(BOOST_TT_NO_DEDUCED_NOEXCEPT_PARAM) && !defined(BOOST_TT_NO_NOEXCEPT_SEPARATE_TYPE) @@ -420,247 +433,259 @@ namespace boost { struct is_member_function_pointer : public true_type {}; #if defined(_MSC_VER) && !defined(_M_ARM) && !defined(_M_ARM64) -#ifdef __CLR_VER - template - struct is_member_function_pointer : public true_type {}; -#endif -#ifndef _M_AMD64 +#if !defined(_M_X64) && !defined(_M_CEE_SAFE) && !defined(_M_CEE_PURE) template struct is_member_function_pointer : public true_type {}; -#ifndef __CLR_VER template - struct is_member_function_pointer : public true_type {}; + struct is_member_function_pointer : public true_type {}; #endif +#ifdef _MANAGED template - struct is_member_function_pointer : public true_type {}; + struct is_member_function_pointer : public true_type {}; +#else +#ifndef _M_AMD64 + template + struct is_member_function_pointer : public true_type {}; #endif -#if !defined(__CLR_VER) && (defined(_M_IX86_FP) && (_M_IX86_FP >= 2) || defined(_M_X64)) +#if defined(_M_IX86_FP) && (_M_IX86_FP >= 2) || defined(_M_X64) template struct is_member_function_pointer : public true_type {}; +#endif #endif // const: -#ifdef __CLR_VER - template - struct is_member_function_pointer : public true_type {}; -#endif -#ifndef _M_AMD64 +#if !defined(_M_X64) && !defined(_M_CEE_SAFE) && !defined(_M_CEE_PURE) template struct is_member_function_pointer : public true_type {}; -#ifndef __CLR_VER template - struct is_member_function_pointer : public true_type {}; + struct is_member_function_pointer : public true_type {}; #endif +#ifdef _MANAGED template - struct is_member_function_pointer : public true_type {}; + struct is_member_function_pointer : public true_type {}; +#else +#ifndef _M_AMD64 + template + struct is_member_function_pointer : public true_type {}; #endif -#if !defined(__CLR_VER) && (defined(_M_IX86_FP) && (_M_IX86_FP >= 2) || defined(_M_X64)) +#if defined(_M_IX86_FP) && (_M_IX86_FP >= 2) || defined(_M_X64) template struct is_member_function_pointer : public true_type {}; +#endif #endif // volatile: -#ifdef __CLR_VER - template - struct is_member_function_pointer : public true_type {}; -#endif -#ifndef _M_AMD64 +#if !defined(_M_X64) && !defined(_M_CEE_SAFE) && !defined(_M_CEE_PURE) template struct is_member_function_pointer : public true_type {}; -#ifndef __CLR_VER template - struct is_member_function_pointer : public true_type {}; + struct is_member_function_pointer : public true_type {}; #endif +#ifdef _MANAGED template - struct is_member_function_pointer : public true_type {}; + struct is_member_function_pointer : public true_type {}; +#else +#ifndef _M_AMD64 + template + struct is_member_function_pointer : public true_type {}; #endif -#if !defined(__CLR_VER) && (defined(_M_IX86_FP) && (_M_IX86_FP >= 2) || defined(_M_X64)) +#if defined(_M_IX86_FP) && (_M_IX86_FP >= 2) || defined(_M_X64) template struct is_member_function_pointer : public true_type {}; +#endif #endif // const volatile: -#ifdef __CLR_VER - template - struct is_member_function_pointer : public true_type {}; -#endif -#ifndef _M_AMD64 +#if !defined(_M_X64) && !defined(_M_CEE_SAFE) && !defined(_M_CEE_PURE) template struct is_member_function_pointer : public true_type {}; -#ifndef __CLR_VER template - struct is_member_function_pointer : public true_type {}; + struct is_member_function_pointer : public true_type {}; #endif +#ifdef _MANAGED template - struct is_member_function_pointer : public true_type {}; + struct is_member_function_pointer : public true_type {}; +#else +#ifndef _M_AMD64 + template + struct is_member_function_pointer : public true_type {}; #endif -#if !defined(__CLR_VER) && (defined(_M_IX86_FP) && (_M_IX86_FP >= 2) || defined(_M_X64)) +#if defined(_M_IX86_FP) && (_M_IX86_FP >= 2) || defined(_M_X64) template struct is_member_function_pointer : public true_type {}; +#endif #endif // reference qualified: -#ifdef __CLR_VER - template - struct is_member_function_pointer : public true_type {}; -#endif -#ifndef _M_AMD64 +#if !defined(_M_X64) && !defined(_M_CEE_SAFE) && !defined(_M_CEE_PURE) template struct is_member_function_pointer : public true_type {}; -#ifndef __CLR_VER template - struct is_member_function_pointer : public true_type {}; + struct is_member_function_pointer : public true_type {}; #endif +#ifdef _MANAGED template - struct is_member_function_pointer : public true_type {}; + struct is_member_function_pointer : public true_type {}; +#else +#ifndef _M_AMD64 + template + struct is_member_function_pointer : public true_type {}; #endif -#if !defined(__CLR_VER) && (defined(_M_IX86_FP) && (_M_IX86_FP >= 2) || defined(_M_X64)) +#if defined(_M_IX86_FP) && (_M_IX86_FP >= 2) || defined(_M_X64) template struct is_member_function_pointer : public true_type {}; +#endif #endif // const: -#ifdef __CLR_VER - template - struct is_member_function_pointer : public true_type {}; -#endif -#ifndef _M_AMD64 +#if !defined(_M_X64) && !defined(_M_CEE_SAFE) && !defined(_M_CEE_PURE) template struct is_member_function_pointer : public true_type {}; -#ifndef __CLR_VER template - struct is_member_function_pointer : public true_type {}; + struct is_member_function_pointer : public true_type {}; #endif +#ifdef _MANAGED template - struct is_member_function_pointer : public true_type {}; + struct is_member_function_pointer : public true_type {}; +#else +#ifndef _M_AMD64 + template + struct is_member_function_pointer : public true_type {}; #endif -#if !defined(__CLR_VER) && (defined(_M_IX86_FP) && (_M_IX86_FP >= 2) || defined(_M_X64)) +#if defined(_M_IX86_FP) && (_M_IX86_FP >= 2) || defined(_M_X64) template struct is_member_function_pointer : public true_type {}; +#endif #endif // volatile: -#ifdef __CLR_VER - template - struct is_member_function_pointer : public true_type {}; -#endif -#ifndef _M_AMD64 +#if !defined(_M_X64) && !defined(_M_CEE_SAFE) && !defined(_M_CEE_PURE) template struct is_member_function_pointer : public true_type {}; -#ifndef __CLR_VER template - struct is_member_function_pointer : public true_type {}; + struct is_member_function_pointer : public true_type {}; #endif +#ifdef _MANAGED template - struct is_member_function_pointer : public true_type {}; + struct is_member_function_pointer : public true_type {}; +#else +#ifndef _M_AMD64 + template + struct is_member_function_pointer : public true_type {}; #endif -#if !defined(__CLR_VER) && (defined(_M_IX86_FP) && (_M_IX86_FP >= 2) || defined(_M_X64)) +#if defined(_M_IX86_FP) && (_M_IX86_FP >= 2) || defined(_M_X64) template struct is_member_function_pointer : public true_type {}; +#endif #endif // const volatile: -#ifdef __CLR_VER - template - struct is_member_function_pointer : public true_type {}; -#endif -#ifndef _M_AMD64 +#if !defined(_M_X64) && !defined(_M_CEE_SAFE) && !defined(_M_CEE_PURE) template struct is_member_function_pointer : public true_type {}; -#ifndef __CLR_VER template - struct is_member_function_pointer : public true_type {}; + struct is_member_function_pointer : public true_type {}; #endif +#ifdef _MANAGED template - struct is_member_function_pointer : public true_type {}; + struct is_member_function_pointer : public true_type {}; +#else +#ifndef _M_AMD64 + template + struct is_member_function_pointer : public true_type {}; #endif -#if !defined(__CLR_VER) && (defined(_M_IX86_FP) && (_M_IX86_FP >= 2) || defined(_M_X64)) +#if defined(_M_IX86_FP) && (_M_IX86_FP >= 2) || defined(_M_X64) template struct is_member_function_pointer : public true_type {}; +#endif #endif // rvalue reference qualified: -#ifdef __CLR_VER - template - struct is_member_function_pointer : public true_type {}; -#endif -#ifndef _M_AMD64 +#if !defined(_M_X64) && !defined(_M_CEE_SAFE) && !defined(_M_CEE_PURE) template struct is_member_function_pointer : public true_type {}; -#ifndef __CLR_VER template - struct is_member_function_pointer : public true_type {}; + struct is_member_function_pointer : public true_type {}; #endif +#ifdef _MANAGED template - struct is_member_function_pointer : public true_type {}; + struct is_member_function_pointer : public true_type {}; +#else +#ifndef _M_AMD64 + template + struct is_member_function_pointer : public true_type {}; #endif -#if !defined(__CLR_VER) && (defined(_M_IX86_FP) && (_M_IX86_FP >= 2) || defined(_M_X64)) +#if defined(_M_IX86_FP) && (_M_IX86_FP >= 2) || defined(_M_X64) template struct is_member_function_pointer : public true_type {}; +#endif #endif // const: -#ifdef __CLR_VER - template - struct is_member_function_pointer : public true_type {}; -#endif -#ifndef _M_AMD64 +#if !defined(_M_X64) && !defined(_M_CEE_SAFE) && !defined(_M_CEE_PURE) template struct is_member_function_pointer : public true_type {}; -#ifndef __CLR_VER template - struct is_member_function_pointer : public true_type {}; + struct is_member_function_pointer : public true_type {}; #endif +#ifdef _MANAGED template - struct is_member_function_pointer : public true_type {}; + struct is_member_function_pointer : public true_type {}; +#else +#ifndef _M_AMD64 + template + struct is_member_function_pointer : public true_type {}; #endif -#if !defined(__CLR_VER) && (defined(_M_IX86_FP) && (_M_IX86_FP >= 2) || defined(_M_X64)) +#if defined(_M_IX86_FP) && (_M_IX86_FP >= 2) || defined(_M_X64) template struct is_member_function_pointer : public true_type {}; +#endif #endif // volatile: -#ifdef __CLR_VER - template - struct is_member_function_pointer : public true_type {}; -#endif -#ifndef _M_AMD64 +#if !defined(_M_X64) && !defined(_M_CEE_SAFE) && !defined(_M_CEE_PURE) template struct is_member_function_pointer : public true_type {}; -#ifndef __CLR_VER template - struct is_member_function_pointer : public true_type {}; + struct is_member_function_pointer : public true_type {}; #endif +#ifdef _MANAGED template - struct is_member_function_pointer : public true_type {}; + struct is_member_function_pointer : public true_type {}; +#else +#ifndef _M_AMD64 + template + struct is_member_function_pointer : public true_type {}; #endif -#if !defined(__CLR_VER) && (defined(_M_IX86_FP) && (_M_IX86_FP >= 2) || defined(_M_X64)) +#if defined(_M_IX86_FP) && (_M_IX86_FP >= 2) || defined(_M_X64) template struct is_member_function_pointer : public true_type {}; +#endif #endif // const volatile: -#ifdef __CLR_VER - template - struct is_member_function_pointer : public true_type {}; - -#endif -#ifndef _M_AMD64 +#if !defined(_M_X64) && !defined(_M_CEE_SAFE) && !defined(_M_CEE_PURE) template struct is_member_function_pointer : public true_type {}; -#ifndef __CLR_VER template - struct is_member_function_pointer : public true_type {}; + struct is_member_function_pointer : public true_type {}; #endif +#ifdef _MANAGED template - struct is_member_function_pointer : public true_type {}; + struct is_member_function_pointer : public true_type {}; +#else +#ifndef _M_AMD64 + template + struct is_member_function_pointer : public true_type {}; #endif -#if !defined(__CLR_VER) && (defined(_M_IX86_FP) && (_M_IX86_FP >= 2) || defined(_M_X64)) +#if defined(_M_IX86_FP) && (_M_IX86_FP >= 2) || defined(_M_X64) template struct is_member_function_pointer : public true_type {}; #endif #endif +#endif // defined(_MSC_VER) && !defined(_M_ARM) && !defined(_M_ARM64) + #endif diff --git a/include/boost/type_traits/detail/is_swappable_cxx_11.hpp b/include/boost/type_traits/detail/is_swappable_cxx_11.hpp new file mode 100644 index 000000000..390253ca3 --- /dev/null +++ b/include/boost/type_traits/detail/is_swappable_cxx_11.hpp @@ -0,0 +1,70 @@ +#ifndef BOOST_TYPE_TRAITS_DETAIL_IS_SWAPPABLE_CXX_11_HPP_INCLUDED +#define BOOST_TYPE_TRAITS_DETAIL_IS_SWAPPABLE_CXX_11_HPP_INCLUDED + +// Copyright 2017 Peter Dimov +// Copyright 2023 Andrey Semashev +// +// 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 + +#include +#include +#include +#include +#if __cplusplus >= 201103L || defined(BOOST_DINKUMWARE_STDLIB) +#include // for std::swap (C++11) +#else +#include // for std::swap (C++98) +#endif + +// Intentionally not within boost namespace to avoid implicitly pulling in boost::swap overloads other than through ADL +namespace boost_type_traits_swappable_detail +{ + +using std::swap; + +template(), boost::declval()))> boost::true_type is_swappable_with_impl( int ); +template boost::false_type is_swappable_with_impl( ... ); +template +struct is_swappable_with_helper { typedef decltype( boost_type_traits_swappable_detail::is_swappable_with_impl(0) ) type; }; + +template(), boost::declval()))> boost::true_type is_swappable_impl( int ); +template boost::false_type is_swappable_impl( ... ); +template +struct is_swappable_helper { typedef decltype( boost_type_traits_swappable_detail::is_swappable_impl(0) ) type; }; + +#if !defined(BOOST_NO_CXX11_NOEXCEPT) + +#if BOOST_WORKAROUND(BOOST_GCC, < 40700) + +// gcc 4.6 ICEs when noexcept operator is used on an invalid expression +template::type::value> +struct is_nothrow_swappable_with_helper { typedef boost::false_type type; }; +template +struct is_nothrow_swappable_with_helper { typedef boost::integral_constant(), boost::declval()))> type; }; + +template::type::value> +struct is_nothrow_swappable_helper { typedef boost::false_type type; }; +template +struct is_nothrow_swappable_helper { typedef boost::integral_constant(), boost::declval()))> type; }; + +#else // BOOST_WORKAROUND(BOOST_GCC, < 40700) + +template(), boost::declval()))> boost::integral_constant is_nothrow_swappable_with_impl( int ); +template boost::false_type is_nothrow_swappable_with_impl( ... ); +template +struct is_nothrow_swappable_with_helper { typedef decltype( boost_type_traits_swappable_detail::is_nothrow_swappable_with_impl(0) ) type; }; + +template(), boost::declval()))> boost::integral_constant is_nothrow_swappable_impl( int ); +template boost::false_type is_nothrow_swappable_impl( ... ); +template +struct is_nothrow_swappable_helper { typedef decltype( boost_type_traits_swappable_detail::is_nothrow_swappable_impl(0) ) type; }; + +#endif // BOOST_WORKAROUND(BOOST_GCC, < 40700) + +#endif // !defined(BOOST_NO_CXX11_NOEXCEPT) + +} // namespace boost_type_traits_swappable_detail + +#endif // #ifndef BOOST_TYPE_TRAITS_DETAIL_IS_SWAPPABLE_CXX_11_HPP_INCLUDED diff --git a/include/boost/type_traits/intrinsics.hpp b/include/boost/type_traits/intrinsics.hpp index 02f2a0315..3ab12d6e0 100644 --- a/include/boost/type_traits/intrinsics.hpp +++ b/include/boost/type_traits/intrinsics.hpp @@ -160,7 +160,7 @@ # define BOOST_HAS_TYPE_TRAITS_INTRINSICS #endif -#if defined(BOOST_CLANG) && defined(__has_feature) && !defined(__CUDACC__) +#if defined(BOOST_CLANG) && defined(__has_feature) && defined(__has_builtin) && (!(defined(__CUDACC__) && (__CUDACC_VER_MAJOR__ < 11)) || defined(__CUDA__)) // // Note that these intrinsics are disabled for the CUDA meta-compiler as it appears // to not support them, even though the underlying clang compiler does so. @@ -183,25 +183,39 @@ # if (!defined(__GLIBCXX__) || (__GLIBCXX__ >= 20080306 && __GLIBCXX__ != 20080519)) && __has_feature(is_empty) # define BOOST_IS_EMPTY(T) __is_empty(T) # endif -# if __has_feature(has_trivial_constructor) +# if __has_builtin(__is_trivially_constructible) +# define BOOST_HAS_TRIVIAL_CONSTRUCTOR(T) __is_trivially_constructible(T) +# elif __has_feature(has_trivial_constructor) # define BOOST_HAS_TRIVIAL_CONSTRUCTOR(T) __has_trivial_constructor(T) # endif -# if __has_feature(has_trivial_copy) +# if __has_builtin(__is_trivially_copyable) +# define BOOST_HAS_TRIVIAL_COPY(T) (__is_trivially_copyable(T) && !is_reference::value) +# elif __has_feature(has_trivial_copy) # define BOOST_HAS_TRIVIAL_COPY(T) (__has_trivial_copy(T) && !is_reference::value) # endif -# if __has_feature(has_trivial_assign) +# if __has_builtin(__is_trivially_assignable) +# define BOOST_HAS_TRIVIAL_ASSIGN(T) (__is_trivially_assignable(T&, const T&) && !is_volatile::value && is_assignable::value) +# elif __has_feature(has_trivial_assign) # define BOOST_HAS_TRIVIAL_ASSIGN(T) (__has_trivial_assign(T) && !is_volatile::value && is_assignable::value) # endif -# if __has_feature(has_trivial_destructor) +# if __has_builtin(__is_trivially_destructible) +# define BOOST_HAS_TRIVIAL_DESTRUCTOR(T) (__is_trivially_destructible(T) && is_destructible::value) +# elif __has_feature(has_trivial_destructor) # define BOOST_HAS_TRIVIAL_DESTRUCTOR(T) (__has_trivial_destructor(T) && is_destructible::value) # endif -# if __has_feature(has_nothrow_constructor) +# if __has_builtin(__is_nothrow_constructible) +# define BOOST_HAS_NOTHROW_CONSTRUCTOR(T) (__is_nothrow_constructible(T) && is_default_constructible::value) +# elif __has_feature(has_nothrow_constructor) # define BOOST_HAS_NOTHROW_CONSTRUCTOR(T) (__has_nothrow_constructor(T) && is_default_constructible::value) # endif -# if __has_feature(has_nothrow_copy) +# if __has_builtin(__is_nothrow_constructible) +# define BOOST_HAS_NOTHROW_COPY(T) (__is_nothrow_constructible(T, const T&) && !is_volatile::value && !is_reference::value && is_copy_constructible::value) +# elif __has_feature(has_nothrow_copy) # define BOOST_HAS_NOTHROW_COPY(T) (__has_nothrow_copy(T) && !is_volatile::value && !is_reference::value && is_copy_constructible::value) # endif -# if __has_feature(has_nothrow_assign) +# if __has_builtin(__is_nothrow_assignable) +# define BOOST_HAS_NOTHROW_ASSIGN(T) (__is_nothrow_assignable(T&, const T&) && !is_volatile::value && is_assignable::value) +# elif __has_feature(has_nothrow_assign) # define BOOST_HAS_NOTHROW_ASSIGN(T) (__has_nothrow_assign(T) && !is_volatile::value && is_assignable::value) # endif # if __has_feature(has_virtual_destructor) diff --git a/include/boost/type_traits/is_complete.hpp b/include/boost/type_traits/is_complete.hpp index 07cb89749..08f0e6277 100644 --- a/include/boost/type_traits/is_complete.hpp +++ b/include/boost/type_traits/is_complete.hpp @@ -15,6 +15,7 @@ #include #include #include +#include /* * CAUTION: @@ -40,7 +41,7 @@ namespace boost { namespace detail{ - template + template struct ok_tag { double d; char c[N]; }; template diff --git a/include/boost/type_traits/is_convertible.hpp b/include/boost/type_traits/is_convertible.hpp index 8e73d9bfa..f873ef6bf 100644 --- a/include/boost/type_traits/is_convertible.hpp +++ b/include/boost/type_traits/is_convertible.hpp @@ -489,7 +489,7 @@ struct is_convertible : public integral_constant struct is_convertible : public integral_constant { -#if BOOST_WORKAROUND(BOOST_MSVC, <= 1900) +#if defined(BOOST_MSVC) BOOST_STATIC_ASSERT_MSG(boost::is_complete::value || boost::is_void::value || boost::is_array::value || boost::is_reference::value, "From argument type to is_convertible must be a complete type"); #endif #if defined(__clang__) diff --git a/include/boost/type_traits/is_empty.hpp b/include/boost/type_traits/is_empty.hpp index db9ead091..ce623e35f 100644 --- a/include/boost/type_traits/is_empty.hpp +++ b/include/boost/type_traits/is_empty.hpp @@ -103,7 +103,7 @@ struct is_empty_impl cvt , ::boost::is_class::value , ::boost::is_convertible< r_type,int>::value - >::value || BOOST_INTERNAL_IS_EMPTY(cvt)); + >::value || BOOST_INTERNAL_IS_EMPTY(cvt))); }; #endif // BOOST_BORLANDC diff --git a/include/boost/type_traits/is_function.hpp b/include/boost/type_traits/is_function.hpp index 8556235a4..1518f7b8e 100644 --- a/include/boost/type_traits/is_function.hpp +++ b/include/boost/type_traits/is_function.hpp @@ -14,7 +14,7 @@ #include #include -#ifdef BOOST_TT_HAS_ASCCURATE_IS_FUNCTION +#ifdef BOOST_TT_HAS_ACCURATE_IS_FUNCTION #include diff --git a/include/boost/type_traits/is_integral.hpp b/include/boost/type_traits/is_integral.hpp index 6c6e239c3..97e5aba37 100644 --- a/include/boost/type_traits/is_integral.hpp +++ b/include/boost/type_traits/is_integral.hpp @@ -81,6 +81,9 @@ template<> struct is_integral : public true_type{}; #ifndef BOOST_NO_CXX11_CHAR32_T template<> struct is_integral : public true_type{}; #endif +#if defined(__cpp_char8_t) && __cpp_char8_t >= 201811L +template<> struct is_integral : public true_type{}; +#endif #endif // non-CodeGear implementation diff --git a/include/boost/type_traits/is_member_function_pointer.hpp b/include/boost/type_traits/is_member_function_pointer.hpp index 9b5dbbf22..dccd440a5 100644 --- a/include/boost/type_traits/is_member_function_pointer.hpp +++ b/include/boost/type_traits/is_member_function_pointer.hpp @@ -13,7 +13,7 @@ #include -#ifdef BOOST_TT_HAS_ASCCURATE_IS_FUNCTION +#ifdef BOOST_TT_HAS_ACCURATE_IS_FUNCTION #include diff --git a/include/boost/type_traits/is_nothrow_swappable.hpp b/include/boost/type_traits/is_nothrow_swappable.hpp index 10ad9239a..1ab3dcd14 100644 --- a/include/boost/type_traits/is_nothrow_swappable.hpp +++ b/include/boost/type_traits/is_nothrow_swappable.hpp @@ -8,10 +8,9 @@ // http://www.boost.org/LICENSE_1_0.txt #include -#include #if defined(BOOST_NO_SFINAE_EXPR) || defined(BOOST_NO_CXX11_NOEXCEPT) || defined(BOOST_NO_CXX11_DECLTYPE) \ - || defined(BOOST_NO_CXX11_FUNCTION_TEMPLATE_DEFAULT_ARGS) || BOOST_WORKAROUND(BOOST_GCC, < 40700) + || defined(BOOST_NO_CXX11_FUNCTION_TEMPLATE_DEFAULT_ARGS) #include #include @@ -28,35 +27,16 @@ template struct is_nothrow_swappable_with : is_nothrow_swappable #else -#include -#include -#include +#include namespace boost { -namespace type_traits_swappable_detail -{ - -using std::swap; - -template(), declval()))> integral_constant is_nothrow_swappable_with_impl( int ); -template false_type is_nothrow_swappable_with_impl( ... ); -template -struct is_nothrow_swappable_with_helper { typedef decltype( type_traits_swappable_detail::is_nothrow_swappable_with_impl(0) ) type; }; - -template(), declval()))> integral_constant is_nothrow_swappable_impl( int ); -template false_type is_nothrow_swappable_impl( ... ); -template -struct is_nothrow_swappable_helper { typedef decltype( type_traits_swappable_detail::is_nothrow_swappable_impl(0) ) type; }; - -} // namespace type_traits_swappable_detail - -template struct is_nothrow_swappable_with: type_traits_swappable_detail::is_nothrow_swappable_with_helper::type +template struct is_nothrow_swappable_with: boost_type_traits_swappable_detail::is_nothrow_swappable_with_helper::type { }; -template struct is_nothrow_swappable: type_traits_swappable_detail::is_nothrow_swappable_helper::type +template struct is_nothrow_swappable: boost_type_traits_swappable_detail::is_nothrow_swappable_helper::type { }; diff --git a/include/boost/type_traits/type_with_alignment.hpp b/include/boost/type_traits/type_with_alignment.hpp index e396349f7..e4860f9fd 100644 --- a/include/boost/type_traits/type_with_alignment.hpp +++ b/include/boost/type_traits/type_with_alignment.hpp @@ -120,7 +120,7 @@ template<> struct is_pod< ::boost::tt_align_ns::a128> : public true_type{}; // registers. Therefore we extend type_with_alignment<> to support // such types, however, we have to be careful to use a builtin type // whenever possible otherwise we break previously working code: -// see http://article.gmane.org/gmane.comp.lib.boost.devel/173011 +// see https://lists.boost.org/Archives/boost/2014/03/212391.php // for an example and test case. Thus types like a8 below will // be used *only* if the existing implementation can't provide a type // with suitable alignment. This does mean however, that type_with_alignment<> diff --git a/include/boost/unordered/detail/fca.hpp b/include/boost/unordered/detail/fca.hpp new file mode 100644 index 000000000..e88faab19 --- /dev/null +++ b/include/boost/unordered/detail/fca.hpp @@ -0,0 +1,849 @@ +// Copyright (C) 2022 Joaquin M Lopez Munoz. +// Copyright (C) 2022 Christian Mazakas +// +// 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_UNORDERED_DETAIL_FCA_HPP +#define BOOST_UNORDERED_DETAIL_FCA_HPP + +/* + +The general structure of the fast closed addressing implementation is that we +use straight-forward separate chaining (i.e. each bucket contains its own linked +list) and then improve iteration time by adding an array of "bucket groups". + +A bucket group is a constant-width view into a subsection of the buckets array, +containing a bitmask that indicates which one of the buckets in the subsection +contains a list of nodes. This allows the code to test N buckets for occupancy +in a single operation. Additional speed can be found by inter-linking occupied +bucket groups with one another in a doubly-linked list. To this end, large +swathes of the bucket groups array no longer need to be iterated and have their +bitmasks examined for occupancy. + +A bucket group iterator contains a pointer to a bucket group along with a +pointer into the buckets array. The iterator's bucket pointer is guaranteed to +point to a bucket within the bucket group's view of the array. To advance the +iterator, we need to determine if we need to skip to the next bucket group or +simply move to the next occupied bucket as denoted by the bitmask. + +To accomplish this, we perform something roughly equivalent to this: +``` +bucket_iterator itb = ... +bucket_pointer p = itb.p +bucket_group_pointer pbg = itb.pbg + +offset = p - pbg->buckets +// because we wish to see if the _next_ bit in the mask is occupied, we'll +// generate a testing mask from the current offset + 1 +// +testing_mask = reset_first_bits(offset + 1) +n = ctz(pbg->bitmask & testing_mask) + +if (n < N) { + p = pbg->buckets + n +} else { + pbg = pbg->next + p = pbg->buckets + ctz(pbg->bitmask) +} +``` + +`reset_first_bits` yields an unsigned integral with the first n bits set to 0 +and then by counting the number of trailing zeroes when AND'd against the bucket +group's bitmask, we can derive the offset into the buckets array. When the +calculated offset is equal to N, we know we've reached the end of a bucket group +and we can advance to the next one. + +This is a rough explanation for how iterator incrementation should work for a +fixed width size of N as 3 for the bucket groups +``` +N = 3 +p = buckets +pbg->bitmask = 0b101 +pbg->buckets = buckets + +offset = p - pbg->buckets // => 0 +testing_mask = reset_first_bits(offset + 1) // reset_first_bits(1) => 0b110 + +x = bitmask & testing_mask // => 0b101 & 0b110 => 0b100 +ctz(x) // ctz(0b100) => 2 +// 2 < 3 +=> p = pbg->buckets + 2 + +// increment again... +offset = p - pbg->buckets // => 2 +testing_mask = reset_first_bits(offset + 1) // reset_first_bits(3) => 0b000 + +bitmask & testing_mask // 0b101 & 0b000 => 0b000 +ctz(0b000) => 3 +// 3 < 3 is false now +pbg = pbg->next +initial_offset = ctz(pbg->bitmask) +p = pbg->buckets + initial_offset +``` + +For `size_` number of buckets, there are `1 + (size_ / N)` bucket groups where +`N` is the width of a bucket group, determined at compile-time. + +We allocate space for `size_ + 1` buckets, using the last one as a dummy bucket +which is kept permanently empty so it can act as a sentinel value in the +implementation of `iterator end();`. We set the last bucket group to act as a +sentinel. + +``` +num_groups = size_ / N + 1 +groups = allocate(num_groups) +pbg = groups + (num_groups - 1) + +// not guaranteed to point to exactly N buckets +pbg->buckets = buckets + N * (size_ / N) + +// this marks the true end of the bucket array +buckets pbg->bitmask = set_bit(size_ % N) + +// links in on itself +pbg->next = pbg->prev = pbg +``` + +To this end, we can devise a safe iteration scheme while also creating a useful +sentinel to use as the end iterator. + +Otherwise, usage of the data structure is relatively straight-forward compared +to normal separate chaining implementations. + +*/ + +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#include + +namespace boost { + namespace unordered { + namespace detail { + + template struct node + { + typedef ValueType value_type; + typedef typename boost::pointer_traits::template rebind_to< + node>::type node_pointer; + + node_pointer next; + typename boost::aligned_storage::value>::type buf; + + node() BOOST_NOEXCEPT : next(), buf() {} + + value_type* value_ptr() BOOST_NOEXCEPT + { + return reinterpret_cast(buf.address()); + } + + value_type& value() BOOST_NOEXCEPT + { + return *reinterpret_cast(buf.address()); + } + }; + + template struct bucket + { + typedef typename boost::pointer_traits::template rebind_to< + Node>::type node_pointer; + + typedef typename boost::pointer_traits::template rebind_to< + bucket>::type bucket_pointer; + + node_pointer next; + + bucket() BOOST_NOEXCEPT : next() {} + }; + + template struct bucket_group + { + typedef typename Bucket::bucket_pointer bucket_pointer; + typedef + typename boost::pointer_traits::template rebind_to< + bucket_group>::type bucket_group_pointer; + + BOOST_STATIC_CONSTANT(std::size_t, N = sizeof(std::size_t) * CHAR_BIT); + + bucket_pointer buckets; + std::size_t bitmask; + bucket_group_pointer next, prev; + + bucket_group() BOOST_NOEXCEPT : buckets(), bitmask(0), next(), prev() {} + ~bucket_group() {} + }; + + inline std::size_t set_bit(std::size_t n) { return std::size_t(1) << n; } + + inline std::size_t reset_bit(std::size_t n) + { + return ~(std::size_t(1) << n); + } + + inline std::size_t reset_first_bits(std::size_t n) // n>0 + { + return ~(~(std::size_t(0)) >> (sizeof(std::size_t) * 8 - n)); + } + + template struct grouped_bucket_iterator + { + public: + typedef typename Bucket::bucket_pointer bucket_pointer; + typedef + typename boost::pointer_traits::template rebind_to< + bucket_group >::type bucket_group_pointer; + + typedef Bucket value_type; + typedef typename boost::pointer_traits::difference_type + difference_type; + typedef Bucket& reference; + typedef Bucket* pointer; + typedef std::forward_iterator_tag iterator_category; + + private: + bucket_pointer p; + bucket_group_pointer pbg; + + public: + grouped_bucket_iterator() : p(), pbg() {} + + reference operator*() const BOOST_NOEXCEPT { return dereference(); } + pointer operator->() const BOOST_NOEXCEPT + { + return boost::to_address(p); + } + + grouped_bucket_iterator& operator++() BOOST_NOEXCEPT + { + increment(); + return *this; + } + + grouped_bucket_iterator operator++(int) BOOST_NOEXCEPT + { + grouped_bucket_iterator old = *this; + increment(); + return old; + } + + bool operator==( + grouped_bucket_iterator const& other) const BOOST_NOEXCEPT + { + return equal(other); + } + + bool operator!=( + grouped_bucket_iterator const& other) const BOOST_NOEXCEPT + { + return !equal(other); + } + + private: + template + friend class grouped_bucket_array; + + BOOST_STATIC_CONSTANT(std::size_t, N = bucket_group::N); + + grouped_bucket_iterator(bucket_pointer p_, bucket_group_pointer pbg_) + : p(p_), pbg(pbg_) + { + } + + Bucket& dereference() const BOOST_NOEXCEPT { return *p; } + + bool equal(const grouped_bucket_iterator& x) const BOOST_NOEXCEPT + { + return p == x.p; + } + + void increment() BOOST_NOEXCEPT + { + std::size_t const offset = static_cast(p - pbg->buckets); + + std::size_t n = std::size_t(boost::core::countr_zero( + pbg->bitmask & reset_first_bits(offset + 1))); + + if (n < N) { + p = pbg->buckets + static_cast(n); + } else { + pbg = pbg->next; + + std::ptrdiff_t x = boost::core::countr_zero(pbg->bitmask); + p = pbg->buckets + x; + } + } + }; + + template struct const_grouped_local_bucket_iterator; + + template struct grouped_local_bucket_iterator + { + typedef typename Node::node_pointer node_pointer; + + public: + typedef typename Node::value_type value_type; + typedef value_type element_type; + typedef value_type* pointer; + typedef value_type& reference; + typedef std::ptrdiff_t difference_type; + typedef std::forward_iterator_tag iterator_category; + + grouped_local_bucket_iterator() : p() {} + + reference operator*() const BOOST_NOEXCEPT { return dereference(); } + + pointer operator->() const BOOST_NOEXCEPT + { + return boost::to_address(p); + } + + grouped_local_bucket_iterator& operator++() BOOST_NOEXCEPT + { + increment(); + return *this; + } + + grouped_local_bucket_iterator operator++(int) BOOST_NOEXCEPT + { + grouped_local_bucket_iterator old = *this; + increment(); + return old; + } + + bool operator==( + grouped_local_bucket_iterator const& other) const BOOST_NOEXCEPT + { + return equal(other); + } + + bool operator!=( + grouped_local_bucket_iterator const& other) const BOOST_NOEXCEPT + { + return !equal(other); + } + + private: + template + friend class grouped_bucket_array; + + template friend struct const_grouped_local_bucket_iterator; + + grouped_local_bucket_iterator(node_pointer p_) : p(p_) {} + + value_type& dereference() const BOOST_NOEXCEPT { return p->value(); } + + bool equal(const grouped_local_bucket_iterator& x) const BOOST_NOEXCEPT + { + return p == x.p; + } + + void increment() BOOST_NOEXCEPT { p = p->next; } + + node_pointer p; + }; + + template struct const_grouped_local_bucket_iterator + { + typedef typename Node::node_pointer node_pointer; + + public: + typedef typename Node::value_type const value_type; + typedef value_type const element_type; + typedef value_type const* pointer; + typedef value_type const& reference; + typedef std::ptrdiff_t difference_type; + typedef std::forward_iterator_tag iterator_category; + + const_grouped_local_bucket_iterator() : p() {} + const_grouped_local_bucket_iterator( + grouped_local_bucket_iterator it) + : p(it.p) + { + } + + reference operator*() const BOOST_NOEXCEPT { return dereference(); } + + pointer operator->() const BOOST_NOEXCEPT + { + return boost::to_address(p); + } + + const_grouped_local_bucket_iterator& operator++() BOOST_NOEXCEPT + { + increment(); + return *this; + } + + const_grouped_local_bucket_iterator operator++(int) BOOST_NOEXCEPT + { + const_grouped_local_bucket_iterator old = *this; + increment(); + return old; + } + + bool operator==( + const_grouped_local_bucket_iterator const& other) const BOOST_NOEXCEPT + { + return equal(other); + } + + bool operator!=( + const_grouped_local_bucket_iterator const& other) const BOOST_NOEXCEPT + { + return !equal(other); + } + + private: + template + friend class grouped_bucket_array; + + const_grouped_local_bucket_iterator(node_pointer p_) : p(p_) {} + + value_type& dereference() const BOOST_NOEXCEPT { return p->value(); } + + bool equal( + const const_grouped_local_bucket_iterator& x) const BOOST_NOEXCEPT + { + return p == x.p; + } + + void increment() BOOST_NOEXCEPT { p = p->next; } + + node_pointer p; + }; + + template struct span + { + T* begin() const BOOST_NOEXCEPT { return data; } + T* end() const BOOST_NOEXCEPT { return data + size; } + + T* data; + std::size_t size; + + span(T* data_, std::size_t size_) : data(data_), size(size_) {} + }; + + template + class grouped_bucket_array + : boost::empty_value::type, + typename boost::allocator_void_pointer::type> >:: + type> + { + BOOST_MOVABLE_BUT_NOT_COPYABLE(grouped_bucket_array) + + typedef typename boost::allocator_value_type::type + allocator_value_type; + typedef + typename boost::allocator_void_pointer::type void_pointer; + typedef typename boost::allocator_difference_type::type + difference_type; + + public: + typedef typename boost::allocator_rebind >::type node_allocator_type; + + typedef node node_type; + typedef typename boost::allocator_pointer::type + node_pointer; + typedef SizePolicy size_policy; + + private: + typedef typename boost::allocator_rebind::type + bucket_allocator_type; + typedef typename boost::allocator_pointer::type + bucket_pointer; + typedef boost::pointer_traits bucket_pointer_traits; + + typedef bucket_group group; + typedef typename boost::allocator_rebind::type + group_allocator_type; + typedef typename boost::allocator_pointer::type + group_pointer; + typedef typename boost::pointer_traits + group_pointer_traits; + + public: + typedef Bucket value_type; + typedef Bucket bucket_type; + typedef std::size_t size_type; + typedef Allocator allocator_type; + typedef grouped_bucket_iterator iterator; + typedef grouped_local_bucket_iterator local_iterator; + typedef const_grouped_local_bucket_iterator + const_local_iterator; + + private: + std::size_t size_index_, size_; + bucket_pointer buckets; + group_pointer groups; + + public: + static std::size_t bucket_count_for(std::size_t num_buckets) + { + if (num_buckets == 0) { + return 0; + } + return size_policy::size(size_policy::size_index(num_buckets)); + } + + grouped_bucket_array() + : empty_value( + empty_init_t(), node_allocator_type()), + size_index_(0), size_(0), buckets(), groups() + { + } + + grouped_bucket_array(size_type n, const Allocator& al) + : empty_value(empty_init_t(), al), + size_index_(0), + size_(0), buckets(), groups() + { + if (n == 0) { + return; + } + + size_index_ = size_policy::size_index(n); + size_ = size_policy::size(size_index_); + + bucket_allocator_type bucket_alloc = this->get_bucket_allocator(); + group_allocator_type group_alloc = this->get_group_allocator(); + + size_type const num_buckets = buckets_len(); + size_type const num_groups = groups_len(); + + buckets = boost::allocator_allocate(bucket_alloc, num_buckets); + BOOST_TRY + { + groups = boost::allocator_allocate(group_alloc, num_groups); + + bucket_type* pb = boost::to_address(buckets); + for (size_type i = 0; i < num_buckets; ++i) { + new (pb + i) bucket_type(); + } + + group* pg = boost::to_address(groups); + for (size_type i = 0; i < num_groups; ++i) { + new (pg + i) group(); + } + } + BOOST_CATCH(...) + { + boost::allocator_deallocate(bucket_alloc, buckets, num_buckets); + BOOST_RETHROW + } + BOOST_CATCH_END + + size_type const N = group::N; + group_pointer pbg = + groups + static_cast(num_groups - 1); + + pbg->buckets = + buckets + static_cast(N * (size_ / N)); + pbg->bitmask = set_bit(size_ % N); + pbg->next = pbg->prev = pbg; + } + + ~grouped_bucket_array() { this->deallocate(); } + + grouped_bucket_array( + BOOST_RV_REF(grouped_bucket_array) other) BOOST_NOEXCEPT + : empty_value( + empty_init_t(), other.get_node_allocator()), + size_index_(other.size_index_), + size_(other.size_), + buckets(other.buckets), + groups(other.groups) + { + other.size_ = 0; + other.size_index_ = 0; + other.buckets = bucket_pointer(); + other.groups = group_pointer(); + } + + grouped_bucket_array& operator=( + BOOST_RV_REF(grouped_bucket_array) other) BOOST_NOEXCEPT + { + BOOST_ASSERT( + this->get_node_allocator() == other.get_node_allocator()); + + if (this == boost::addressof(other)) { + return *this; + } + + this->deallocate(); + size_index_ = other.size_index_; + size_ = other.size_; + + buckets = other.buckets; + groups = other.groups; + + other.size_index_ = 0; + other.size_ = 0; + other.buckets = bucket_pointer(); + other.groups = group_pointer(); + + return *this; + } + + void deallocate() BOOST_NOEXCEPT + { + if (buckets) { + bucket_allocator_type bucket_alloc = this->get_bucket_allocator(); + boost::allocator_deallocate( + bucket_alloc, buckets, this->buckets_len()); + + buckets = bucket_pointer(); + } + + if (groups) { + group_allocator_type group_alloc = this->get_group_allocator(); + boost::allocator_deallocate( + group_alloc, groups, this->groups_len()); + + groups = group_pointer(); + } + } + + void swap(grouped_bucket_array& other) + { + std::swap(size_index_, other.size_index_); + std::swap(size_, other.size_); + std::swap(buckets, other.buckets); + std::swap(groups, other.groups); + + bool b = boost::allocator_propagate_on_container_swap< + allocator_type>::type::value; + if (b) { + boost::swap(get_node_allocator(), other.get_node_allocator()); + } + } + + node_allocator_type const& get_node_allocator() const + { + return empty_value::get(); + } + + node_allocator_type& get_node_allocator() + { + return empty_value::get(); + } + + bucket_allocator_type get_bucket_allocator() const + { + return this->get_node_allocator(); + } + + group_allocator_type get_group_allocator() const + { + return this->get_node_allocator(); + } + + size_type buckets_len() const BOOST_NOEXCEPT { return size_ + 1; } + + size_type groups_len() const BOOST_NOEXCEPT + { + return size_ / group::N + 1; + } + + void reset_allocator(Allocator const& allocator_) + { + this->get_node_allocator() = node_allocator_type(allocator_); + } + + size_type bucket_count() const { return size_; } + + iterator begin() const { return size_ == 0 ? end() : ++at(size_); } + + iterator end() const + { + // micro optimization: no need to return the bucket group + // as end() is not incrementable + iterator pbg; + pbg.p = + buckets + static_cast(this->buckets_len() - 1); + return pbg; + } + + local_iterator begin(size_type n) const + { + if (size_ == 0) { + return this->end(n); + } + + return local_iterator( + (buckets + static_cast(n))->next); + } + + local_iterator end(size_type) const { return local_iterator(); } + + size_type capacity() const BOOST_NOEXCEPT { return size_; } + + iterator at(size_type n) const + { + if (size_ > 0) { + std::size_t const N = group::N; + + iterator pbg(buckets + static_cast(n), + groups + static_cast(n / N)); + + return pbg; + } else { + return this->end(); + } + } + + span raw() + { + BOOST_ASSERT(size_ == 0 || size_ < this->buckets_len()); + return span(boost::to_address(buckets), size_); + } + + size_type position(std::size_t hash) const + { + return size_policy::position(hash, size_index_); + } + + void clear() + { + this->deallocate(); + size_index_ = 0; + size_ = 0; + } + + void append_bucket_group(iterator itb) BOOST_NOEXCEPT + { + std::size_t const N = group::N; + + bool const is_empty_bucket = (!itb->next); + if (is_empty_bucket) { + bucket_pointer pb = itb.p; + group_pointer pbg = itb.pbg; + + std::size_t n = + static_cast(boost::to_address(pb) - &buckets[0]); + + bool const is_empty_group = (!pbg->bitmask); + if (is_empty_group) { + size_type const num_groups = this->groups_len(); + group_pointer last_group = + groups + static_cast(num_groups - 1); + + pbg->buckets = + buckets + static_cast(N * (n / N)); + pbg->next = last_group->next; + pbg->next->prev = pbg; + pbg->prev = last_group; + pbg->prev->next = pbg; + } + + pbg->bitmask |= set_bit(n % N); + } + } + + void insert_node(iterator itb, node_pointer p) BOOST_NOEXCEPT + { + this->append_bucket_group(itb); + + p->next = itb->next; + itb->next = p; + } + + void insert_node_hint( + iterator itb, node_pointer p, node_pointer hint) BOOST_NOEXCEPT + { + this->append_bucket_group(itb); + + if (hint) { + p->next = hint->next; + hint->next = p; + } else { + p->next = itb->next; + itb->next = p; + } + } + + void extract_node(iterator itb, node_pointer p) BOOST_NOEXCEPT + { + node_pointer* pp = boost::addressof(itb->next); + while ((*pp) != p) + pp = boost::addressof((*pp)->next); + *pp = p->next; + if (!itb->next) + unlink_bucket(itb); + } + + void extract_node_after(iterator itb, node_pointer* pp) BOOST_NOEXCEPT + { + *pp = (*pp)->next; + if (!itb->next) + unlink_bucket(itb); + } + + void unlink_empty_buckets() BOOST_NOEXCEPT + { + std::size_t const N = group::N; + + group_pointer pbg = groups, + last = groups + static_cast( + this->groups_len() - 1); + + for (; pbg != last; ++pbg) { + if (!pbg->buckets) { + continue; + } + + for (std::size_t n = 0; n < N; ++n) { + bucket_pointer bs = pbg->buckets; + bucket_type& b = bs[static_cast(n)]; + if (!b.next) + pbg->bitmask &= reset_bit(n); + } + if (!pbg->bitmask && pbg->next) + unlink_group(pbg); + } + + // do not check end bucket + for (std::size_t n = 0; n < size_ % N; ++n) { + if (!pbg->buckets[static_cast(n)].next) + pbg->bitmask &= reset_bit(n); + } + } + + void unlink_bucket(iterator itb) + { + typename iterator::bucket_pointer p = itb.p; + typename iterator::bucket_group_pointer pbg = itb.pbg; + if (!(pbg->bitmask &= + reset_bit(static_cast(p - pbg->buckets)))) + unlink_group(pbg); + } + + private: + void unlink_group(group_pointer pbg) + { + pbg->next->prev = pbg->prev; + pbg->prev->next = pbg->next; + pbg->prev = pbg->next = group_pointer(); + } + }; + } // namespace detail + } // namespace unordered +} // namespace boost + +#endif // BOOST_UNORDERED_DETAIL_FCA_HPP diff --git a/include/boost/unordered/detail/fwd.hpp b/include/boost/unordered/detail/fwd.hpp index e749ce67b..7fcb770e3 100644 --- a/include/boost/unordered/detail/fwd.hpp +++ b/include/boost/unordered/detail/fwd.hpp @@ -1,5 +1,6 @@ // Copyright (C) 2008-2016 Daniel James. +// Copyright (C) 2022 Christian Mazakas // 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) @@ -31,7 +32,7 @@ // 2012 = VC+11 = BOOST_MSVC 1700 Hopefully! // I have no idea when Dinkumware added it, probably a lot // earlier than this check. -#if BOOST_LIB_STD_DINKUMWARE >= BOOST_VERSION_NUMBER(6, 50, 0) || \ +#if BOOST_LIB_STD_DINKUMWARE >= BOOST_VERSION_NUMBER(6, 10, 0) || \ BOOST_COMP_MSVC >= BOOST_VERSION_NUMBER(17, 0, 0) #define BOOST_UNORDERED_HAVE_PIECEWISE_CONSTRUCT 1 #endif @@ -60,4 +61,90 @@ namespace boost { } } +// BOOST_UNORDERED_EMPLACE_LIMIT = The maximum number of parameters in +// emplace (not including things like hints). Don't set it to a lower value, as +// that might break something. + +#if !defined BOOST_UNORDERED_EMPLACE_LIMIT +#define BOOST_UNORDERED_EMPLACE_LIMIT 10 +#endif + +//////////////////////////////////////////////////////////////////////////////// +// Configuration +// +// Unless documented elsewhere these configuration macros should be considered +// an implementation detail, I'll try not to break them, but you never know. + +// Use Sun C++ workarounds +// I'm not sure which versions of the compiler require these workarounds, so +// I'm just using them of everything older than the current test compilers +// (as of May 2017). + +#if !defined(BOOST_UNORDERED_SUN_WORKAROUNDS1) +#if BOOST_COMP_SUNPRO && BOOST_COMP_SUNPRO < BOOST_VERSION_NUMBER(5, 20, 0) +#define BOOST_UNORDERED_SUN_WORKAROUNDS1 1 +#else +#define BOOST_UNORDERED_SUN_WORKAROUNDS1 0 +#endif +#endif + +// BOOST_UNORDERED_TUPLE_ARGS +// +// Maximum number of std::tuple members to support, or 0 if std::tuple +// isn't avaiable. More are supported when full C++11 is used. + +// Already defined, so do nothing +#if defined(BOOST_UNORDERED_TUPLE_ARGS) + +// Assume if we have C++11 tuple it's properly variadic, +// and just use a max number of 10 arguments. +#elif !defined(BOOST_NO_CXX11_HDR_TUPLE) +#define BOOST_UNORDERED_TUPLE_ARGS 10 + +// Visual C++ has a decent enough tuple for piecewise construction, +// so use that if available, using _VARIADIC_MAX for the maximum +// number of parameters. Note that this comes after the check +// for a full C++11 tuple. +#elif defined(BOOST_MSVC) +#if !BOOST_UNORDERED_HAVE_PIECEWISE_CONSTRUCT +#define BOOST_UNORDERED_TUPLE_ARGS 0 +#elif defined(_VARIADIC_MAX) +#define BOOST_UNORDERED_TUPLE_ARGS _VARIADIC_MAX +#else +#define BOOST_UNORDERED_TUPLE_ARGS 5 +#endif + +// Assume that we don't have std::tuple +#else +#define BOOST_UNORDERED_TUPLE_ARGS 0 +#endif + +#if BOOST_UNORDERED_TUPLE_ARGS +#include +#endif + +// BOOST_UNORDERED_CXX11_CONSTRUCTION +// +// Use C++11 construction, requires variadic arguments, good construct support +// in allocator_traits and piecewise construction of std::pair +// Otherwise allocators aren't used for construction/destruction + +#if BOOST_UNORDERED_HAVE_PIECEWISE_CONSTRUCT && \ + !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) && BOOST_UNORDERED_TUPLE_ARGS +#if BOOST_COMP_SUNPRO && BOOST_LIB_STD_GNU +// Sun C++ std::pair piecewise construction doesn't seem to be exception safe. +// (At least for Sun C++ 12.5 using libstdc++). +#define BOOST_UNORDERED_CXX11_CONSTRUCTION 0 +#elif BOOST_COMP_GNUC && BOOST_COMP_GNUC < BOOST_VERSION_NUMBER(4, 7, 0) +// Piecewise construction in GCC 4.6 doesn't work for uncopyable types. +#define BOOST_UNORDERED_CXX11_CONSTRUCTION 0 +#elif !defined(BOOST_NO_CXX11_ALLOCATOR) +#define BOOST_UNORDERED_CXX11_CONSTRUCTION 1 +#endif +#endif + +#if !defined(BOOST_UNORDERED_CXX11_CONSTRUCTION) +#define BOOST_UNORDERED_CXX11_CONSTRUCTION 0 +#endif + #endif diff --git a/include/boost/unordered/detail/implementation.hpp b/include/boost/unordered/detail/implementation.hpp index 9dffde159..1fffdc4a7 100644 --- a/include/boost/unordered/detail/implementation.hpp +++ b/include/boost/unordered/detail/implementation.hpp @@ -1,5 +1,7 @@ // Copyright (C) 2003-2004 Jeremy B. Maitin-Shepard. // Copyright (C) 2005-2016 Daniel James +// Copyright (C) 2022 Joaquin M Lopez Munoz. +// Copyright (C) 2022 Christian Mazakas // // 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) @@ -13,9 +15,10 @@ #endif #include +#include +#include #include #include -#include #include #include #include @@ -35,12 +38,16 @@ #include #include #include +#include #include #include #include #include #include +#include #include +#include +#include #include #include #include @@ -53,116 +60,9 @@ #include #endif -//////////////////////////////////////////////////////////////////////////////// -// Configuration -// -// Unless documented elsewhere these configuration macros should be considered -// an implementation detail, I'll try not to break them, but you never know. - -// Use Sun C++ workarounds -// I'm not sure which versions of the compiler require these workarounds, so -// I'm just using them of everything older than the current test compilers -// (as of May 2017). - -#if !defined(BOOST_UNORDERED_SUN_WORKAROUNDS1) -#if BOOST_COMP_SUNPRO && BOOST_COMP_SUNPRO < BOOST_VERSION_NUMBER(5, 20, 0) -#define BOOST_UNORDERED_SUN_WORKAROUNDS1 1 -#else -#define BOOST_UNORDERED_SUN_WORKAROUNDS1 0 -#endif -#endif - -// BOOST_UNORDERED_EMPLACE_LIMIT = The maximum number of parameters in -// emplace (not including things like hints). Don't set it to a lower value, as -// that might break something. - -#if !defined BOOST_UNORDERED_EMPLACE_LIMIT -#define BOOST_UNORDERED_EMPLACE_LIMIT 10 -#endif - -// BOOST_UNORDERED_USE_ALLOCATOR_TRAITS - Pick which version of -// allocator_traits to use. -// -// 0 = Own partial implementation -// 1 = std::allocator_traits -// 2 = boost::container::allocator_traits - -#if !defined(BOOST_UNORDERED_USE_ALLOCATOR_TRAITS) -#if !defined(BOOST_NO_CXX11_ALLOCATOR) -#define BOOST_UNORDERED_USE_ALLOCATOR_TRAITS 1 -#elif defined(BOOST_MSVC) -#if BOOST_MSVC < 1400 -// Use container's allocator_traits for older versions of Visual -// C++ as I don't test with them. -#define BOOST_UNORDERED_USE_ALLOCATOR_TRAITS 2 -#endif -#endif -#endif - -#if !defined(BOOST_UNORDERED_USE_ALLOCATOR_TRAITS) -#define BOOST_UNORDERED_USE_ALLOCATOR_TRAITS 0 -#endif - -// BOOST_UNORDERED_TUPLE_ARGS -// -// Maximum number of std::tuple members to support, or 0 if std::tuple -// isn't avaiable. More are supported when full C++11 is used. - -// Already defined, so do nothing -#if defined(BOOST_UNORDERED_TUPLE_ARGS) - -// Assume if we have C++11 tuple it's properly variadic, -// and just use a max number of 10 arguments. -#elif !defined(BOOST_NO_CXX11_HDR_TUPLE) -#define BOOST_UNORDERED_TUPLE_ARGS 10 - -// Visual C++ has a decent enough tuple for piecewise construction, -// so use that if available, using _VARIADIC_MAX for the maximum -// number of parameters. Note that this comes after the check -// for a full C++11 tuple. -#elif defined(BOOST_MSVC) -#if !BOOST_UNORDERED_HAVE_PIECEWISE_CONSTRUCT -#define BOOST_UNORDERED_TUPLE_ARGS 0 -#elif defined(_VARIADIC_MAX) -#define BOOST_UNORDERED_TUPLE_ARGS _VARIADIC_MAX -#else -#define BOOST_UNORDERED_TUPLE_ARGS 5 -#endif - -// Assume that we don't have std::tuple -#else -#define BOOST_UNORDERED_TUPLE_ARGS 0 -#endif - -#if BOOST_UNORDERED_TUPLE_ARGS -#include -#endif - -// BOOST_UNORDERED_CXX11_CONSTRUCTION -// -// Use C++11 construction, requires variadic arguments, good construct support -// in allocator_traits and piecewise construction of std::pair -// Otherwise allocators aren't used for construction/destruction - -#if BOOST_UNORDERED_HAVE_PIECEWISE_CONSTRUCT && \ - !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) && BOOST_UNORDERED_TUPLE_ARGS -#if BOOST_COMP_SUNPRO && BOOST_LIB_STD_GNU -// Sun C++ std::pair piecewise construction doesn't seem to be exception safe. -// (At least for Sun C++ 12.5 using libstdc++). -#define BOOST_UNORDERED_CXX11_CONSTRUCTION 0 -#elif BOOST_COMP_GNUC && BOOST_COMP_GNUC < BOOST_VERSION_NUMBER(4, 7, 0) -// Piecewise construction in GCC 4.6 doesn't work for uncopyable types. -#define BOOST_UNORDERED_CXX11_CONSTRUCTION 0 -#elif BOOST_UNORDERED_USE_ALLOCATOR_TRAITS == 0 && \ - !defined(BOOST_NO_SFINAE_EXPR) -#define BOOST_UNORDERED_CXX11_CONSTRUCTION 1 -#elif BOOST_UNORDERED_USE_ALLOCATOR_TRAITS == 1 -#define BOOST_UNORDERED_CXX11_CONSTRUCTION 1 -#endif -#endif - -#if !defined(BOOST_UNORDERED_CXX11_CONSTRUCTION) -#define BOOST_UNORDERED_CXX11_CONSTRUCTION 0 +#if BOOST_UNORDERED_CXX11_CONSTRUCTION +#include +#include #endif // BOOST_UNORDERED_SUPPRESS_DEPRECATED @@ -196,42 +96,14 @@ #endif #endif -// BOOST_UNORDERED_TEMPLATE_DEDUCTION_GUIDES - -#if !defined(BOOST_UNORDERED_TEMPLATE_DEDUCTION_GUIDES) -#if BOOST_COMP_CLANG && __cplusplus >= 201703 -#define BOOST_UNORDERED_TEMPLATE_DEDUCTION_GUIDES 1 -#endif -#endif - -#if !defined(BOOST_UNORDERED_TEMPLATE_DEDUCTION_GUIDES) -#define BOOST_UNORDERED_TEMPLATE_DEDUCTION_GUIDES 0 -#endif - -namespace boost { - namespace unordered { - namespace iterator_detail { - template struct iterator; - template struct c_iterator; - template struct l_iterator; - template struct cl_iterator; - } - } -} - namespace boost { namespace unordered { namespace detail { template struct table; - template struct bucket; - struct ptr_bucket; - - template struct node; - template struct ptr_node; static const float minimum_max_load_factor = 1e-3f; - static const std::size_t default_bucket_count = 11; + static const std::size_t default_bucket_count = 0; struct move_tag { @@ -279,90 +151,23 @@ namespace boost { } } -//////////////////////////////////////////////////////////////////////////////// -// primes - -// clang-format off -#define BOOST_UNORDERED_PRIMES \ - (17ul)(29ul)(37ul)(53ul)(67ul)(79ul) \ - (97ul)(131ul)(193ul)(257ul)(389ul)(521ul)(769ul) \ - (1031ul)(1543ul)(2053ul)(3079ul)(6151ul)(12289ul)(24593ul) \ - (49157ul)(98317ul)(196613ul)(393241ul)(786433ul) \ - (1572869ul)(3145739ul)(6291469ul)(12582917ul)(25165843ul) \ - (50331653ul)(100663319ul)(201326611ul)(402653189ul)(805306457ul) \ - (1610612741ul)(3221225473ul)(4294967291ul) -// clang-format on - namespace boost { namespace unordered { namespace detail { - template struct prime_list_template - { - static std::size_t const value[]; - -#if !BOOST_UNORDERED_SUN_WORKAROUNDS1 - static std::ptrdiff_t const length; -#else - static std::ptrdiff_t const length = - BOOST_PP_SEQ_SIZE(BOOST_UNORDERED_PRIMES); -#endif - }; - - template - std::size_t const prime_list_template::value[] = { - BOOST_PP_SEQ_ENUM(BOOST_UNORDERED_PRIMES)}; - -#if !BOOST_UNORDERED_SUN_WORKAROUNDS1 - template - std::ptrdiff_t const prime_list_template::length = BOOST_PP_SEQ_SIZE( - BOOST_UNORDERED_PRIMES); -#endif - -#undef BOOST_UNORDERED_PRIMES - - typedef prime_list_template prime_list; - - // no throw - inline std::size_t next_prime(std::size_t num) - { - std::size_t const* const prime_list_begin = prime_list::value; - std::size_t const* const prime_list_end = - prime_list_begin + prime_list::length; - std::size_t const* bound = - std::lower_bound(prime_list_begin, prime_list_end, num); - if (bound == prime_list_end) - bound--; - return *bound; - } - - // no throw - inline std::size_t prev_prime(std::size_t num) - { - std::size_t const* const prime_list_begin = prime_list::value; - std::size_t const* const prime_list_end = - prime_list_begin + prime_list::length; - std::size_t const* bound = - std::upper_bound(prime_list_begin, prime_list_end, num); - if (bound != prime_list_begin) - bound--; - return *bound; - } - ////////////////////////////////////////////////////////////////////////// // insert_size/initial_size template - inline std::size_t insert_size(I i, I j, - typename boost::unordered::detail::enable_if_forward::type = - 0) + inline typename boost::unordered::detail::enable_if_forward::type + insert_size(I i, I j) { return static_cast(std::distance(i, j)); } template - inline std::size_t insert_size(I, I, - typename boost::unordered::detail::disable_if_forward::type = - 0) + inline typename boost::unordered::detail::disable_if_forward::type insert_size(I, I) { return 1; } @@ -379,34 +184,27 @@ namespace boost { ////////////////////////////////////////////////////////////////////////// // compressed - template struct compressed_base : private T - { - compressed_base(T const& x) : T(x) {} - compressed_base(T& x, move_tag) : T(boost::move(x)) {} - - T& get() { return *this; } - T const& get() const { return *this; } - }; - - template struct uncompressed_base + template + struct compressed_base : boost::empty_value { - uncompressed_base(T const& x) : value_(x) {} - uncompressed_base(T& x, move_tag) : value_(boost::move(x)) {} - - T& get() { return value_; } - T const& get() const { return value_; } + compressed_base(T const& x) : empty_value(boost::empty_init_t(), x) + { + } + compressed_base(T& x, move_tag) + : empty_value(boost::empty_init_t(), boost::move(x)) + { + } - private: - T value_; + T& get() { return empty_value::get(); } + T const& get() const { return empty_value::get(); } }; template - struct generate_base - : boost::detail::if_true< - boost::is_empty::value>::BOOST_NESTED_TEMPLATE - then, - boost::unordered::detail::uncompressed_base > + struct generate_base : boost::unordered::detail::compressed_base { + typedef compressed_base type; + + generate_base() : type() {} }; template @@ -827,13 +625,13 @@ namespace boost { T* operator->() { return value_.value_ptr(); } T const* operator->() const { return value_.value_ptr(); } - bool operator==(optional const& x) + bool operator==(optional const& x) const { return has_value_ ? x.has_value_ && value_.value() == x.value_.value() : !x.has_value_; } - bool operator!=(optional const& x) { return !((*this) == x); } + bool operator!=(optional const& x) const { return !((*this) == x); } void swap(optional& x) { @@ -854,1611 +652,534 @@ namespace boost { } } -//////////////////////////////////////////////////////////////////////////// -// Expression test mechanism +//////////////////////////////////////////////////////////////////////////////// +// +// Allocator traits // -// When SFINAE expressions are available, define -// BOOST_UNORDERED_HAS_FUNCTION which can check if a function call is -// supported by a class, otherwise define BOOST_UNORDERED_HAS_MEMBER which -// can detect if a class has the specified member, but not that it has the -// correct type, this is good enough for a passable impression of -// allocator_traits. - -#if !defined(BOOST_NO_SFINAE_EXPR) namespace boost { namespace unordered { namespace detail { - template struct expr_test; - template struct expr_test : T + + template + struct allocator_traits : boost::allocator_traits + { + }; + + template + struct rebind_wrap : boost::allocator_rebind { }; } } } -#define BOOST_UNORDERED_CHECK_EXPRESSION(count, result, expression) \ - template \ - static \ - typename boost::unordered::detail::expr_test::type \ - test(BOOST_PP_CAT(choice, count)) +//////////////////////////////////////////////////////////////////////////// +// Functions used to construct nodes. Emulates variadic construction, +// piecewise construction etc. -#define BOOST_UNORDERED_DEFAULT_EXPRESSION(count, result) \ - template \ - static BOOST_PP_CAT(choice, result)::type test(BOOST_PP_CAT(choice, count)) +//////////////////////////////////////////////////////////////////////////// +// construct_value +// +// Only use allocator_traits::construct, allocator_traits::destroy when full +// C++11 support is available. -#define BOOST_UNORDERED_HAS_FUNCTION(name, thing, args, _) \ - struct BOOST_PP_CAT(has_, name) \ - { \ - template static char for_expr_test(U const&); \ - BOOST_UNORDERED_CHECK_EXPRESSION( \ - 1, 1, boost::unordered::detail::make().name args); \ - BOOST_UNORDERED_DEFAULT_EXPRESSION(2, 2); \ - \ - enum \ - { \ - value = sizeof(test(choose())) == sizeof(choice1::type) \ - }; \ - } +#if BOOST_UNORDERED_CXX11_CONSTRUCTION -#else +#elif !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) namespace boost { namespace unordered { namespace detail { - template struct identity - { - typedef T type; - }; + namespace func { + template + inline void construct_value(T* address, BOOST_FWD_REF(Args)... args) + { + new ((void*)address) T(boost::forward(args)...); + } + } } } } -#define BOOST_UNORDERED_CHECK_MEMBER(count, result, name, member) \ - \ - typedef \ - typename boost::unordered::detail::identity::type BOOST_PP_CAT( \ - check, count); \ - \ - template struct BOOST_PP_CAT(test, count) \ - { \ - typedef BOOST_PP_CAT(choice, result) type; \ - }; \ - \ - template \ - static typename BOOST_PP_CAT(test, count)<&U::name>::type test( \ - BOOST_PP_CAT(choice, count)) +#else -#define BOOST_UNORDERED_DEFAULT_MEMBER(count, result) \ - template \ - static BOOST_PP_CAT(choice, result)::type test(BOOST_PP_CAT(choice, count)) +namespace boost { + namespace unordered { + namespace detail { + namespace func { + template inline void construct_value(T* address) + { + new ((void*)address) T(); + } -#define BOOST_UNORDERED_HAS_MEMBER(name) \ - struct BOOST_PP_CAT(has_, name) \ - { \ - struct impl \ - { \ - struct base_mixin \ - { \ - int name; \ - }; \ - struct base : public T, public base_mixin \ - { \ - }; \ - \ - BOOST_UNORDERED_CHECK_MEMBER(1, 1, name, int base_mixin::*); \ - BOOST_UNORDERED_DEFAULT_MEMBER(2, 2); \ - \ - enum \ - { \ - value = sizeof(choice2::type) == sizeof(test(choose())) \ - }; \ - }; \ - \ - enum \ - { \ - value = impl::value \ - }; \ + template + inline void construct_value(T* address, BOOST_FWD_REF(A0) a0) + { + new ((void*)address) T(boost::forward(a0)); + } + } + } } +} #endif //////////////////////////////////////////////////////////////////////////// -// TRAITS TYPE DETECTION MECHANISM +// Construct from tuple // -// Used to implement traits that use a type if present, or a -// default otherwise. - -#if defined(BOOST_MSVC) && BOOST_MSVC <= 1400 +// Used to emulate piecewise construction. -#define BOOST_UNORDERED_DEFAULT_TYPE_TMPLT(tname) \ - template struct default_type_##tname \ +#define BOOST_UNORDERED_CONSTRUCT_FROM_TUPLE(z, n, namespace_) \ + template \ + void construct_from_tuple(Alloc&, T* ptr, \ + namespace_::tuple const& x) \ { \ - \ - template \ - static choice1::type test(choice1, typename X::tname* = 0); \ - \ - template static choice2::type test(choice2, void* = 0); \ - \ - struct DefaultWrap \ - { \ - typedef Default tname; \ - }; \ - \ - enum \ - { \ - value = (1 == sizeof(test(choose()))) \ - }; \ - \ - typedef typename boost::detail::if_true::BOOST_NESTED_TEMPLATE \ - then::type::tname type; \ + new ((void*)ptr) \ + T(BOOST_PP_ENUM_##z(n, BOOST_UNORDERED_GET_TUPLE_ARG, namespace_)); \ } -#else +#define BOOST_UNORDERED_GET_TUPLE_ARG(z, n, namespace_) namespace_::get(x) + +// construct_from_tuple for boost::tuple +// The workaround for old Sun compilers comes later in the file. + +#if !BOOST_UNORDERED_SUN_WORKAROUNDS1 namespace boost { namespace unordered { namespace detail { - template struct sfinae : T2 - { - }; + namespace func { + template + void construct_from_tuple(Alloc&, T* ptr, boost::tuple<>) + { + new ((void*)ptr) T(); + } + + BOOST_UNORDERED_CONSTRUCT_FROM_TUPLE(1, 1, boost) + BOOST_UNORDERED_CONSTRUCT_FROM_TUPLE(1, 2, boost) + BOOST_UNORDERED_CONSTRUCT_FROM_TUPLE(1, 3, boost) + BOOST_UNORDERED_CONSTRUCT_FROM_TUPLE(1, 4, boost) + BOOST_UNORDERED_CONSTRUCT_FROM_TUPLE(1, 5, boost) + BOOST_UNORDERED_CONSTRUCT_FROM_TUPLE(1, 6, boost) + BOOST_UNORDERED_CONSTRUCT_FROM_TUPLE(1, 7, boost) + BOOST_UNORDERED_CONSTRUCT_FROM_TUPLE(1, 8, boost) + BOOST_UNORDERED_CONSTRUCT_FROM_TUPLE(1, 9, boost) + BOOST_UNORDERED_CONSTRUCT_FROM_TUPLE(1, 10, boost) + } } } } -#define BOOST_UNORDERED_DEFAULT_TYPE_TMPLT(tname) \ - template struct default_type_##tname \ - { \ - \ - template \ - static typename boost::unordered::detail::sfinae::type test(choice1); \ - \ - template static choice2::type test(choice2); \ - \ - struct DefaultWrap \ - { \ - typedef Default tname; \ - }; \ - \ - enum \ - { \ - value = (1 == sizeof(test(choose()))) \ - }; \ - \ - typedef typename boost::detail::if_true::BOOST_NESTED_TEMPLATE \ - then::type::tname type; \ - } - #endif -#define BOOST_UNORDERED_DEFAULT_TYPE(T, tname, arg) \ - typename default_type_##tname::type - -//////////////////////////////////////////////////////////////////////////////// -// -// Allocator traits -// -// First our implementation, then later light wrappers around the alternatives - -#if BOOST_UNORDERED_USE_ALLOCATOR_TRAITS == 0 +// construct_from_tuple for std::tuple -#include -#include -#include +#if !BOOST_UNORDERED_CXX11_CONSTRUCTION && BOOST_UNORDERED_TUPLE_ARGS namespace boost { namespace unordered { namespace detail { - - template struct rebind_alloc; - -#if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) - - template