From 324a6fab7412b5826c521f9296a33a3450ff989e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henri=20Hyyryl=C3=A4inen?= Date: Tue, 30 May 2023 17:04:13 +0300 Subject: [PATCH 01/79] Started working on a native code side of things to prototype this Setup a version for the native library and tweaked its build Made the FeatureInformation.cs clearer for different platforms by using specific named constants for the platform names Added calling native methods setup and cleanup Non-working native method call interface, it doesn't find the library probably needs to do a mono specific search path hack Trying to override the mono load directory still doesn't work as mono tries to resolve the attributes way too early Kind of working native lib setup when it is put in a very specific folder Added JoltPhysics as a submodule Customized more and added missing clang format options Just one blank line to keep --- .clang-format | 212 +++++++++++++++++++-------- .clang-tidy | 3 + .gitignore | 1 + .gitmodules | 3 + CMakeLists.txt | 46 ++++++ Scripts/Scripts.csproj | 6 + Thrive.csproj | 2 + Thrive.sln.DotSettings | 2 + src/engine/FeatureInformation.cs | 10 +- src/engine/PostShutdownActions.cs | 5 + src/engine/StartupActions.cs | 4 + src/native/CMakeLists.txt | 42 ++++++ src/native/Include.h.in | 22 +++ src/native/NativeConstants.cs | 4 + src/native/interop/CInterop.cpp | 39 +++++ src/native/interop/CInterop.h | 28 ++++ src/native/interop/CStructures.h | 13 ++ src/native/interop/NativeInterop.cs | 84 +++++++++++ src/native/physics/PhysicalWorld.cpp | 9 ++ src/native/physics/PhysicalWorld.hpp | 15 ++ third_party/CMakeLists.txt | 7 + third_party/JoltPhysics | 1 + 22 files changed, 492 insertions(+), 66 deletions(-) create mode 100644 .clang-tidy create mode 100644 CMakeLists.txt create mode 100644 src/native/CMakeLists.txt create mode 100644 src/native/Include.h.in create mode 100644 src/native/NativeConstants.cs create mode 100644 src/native/interop/CInterop.cpp create mode 100644 src/native/interop/CInterop.h create mode 100644 src/native/interop/CStructures.h create mode 100644 src/native/interop/NativeInterop.cs create mode 100644 src/native/physics/PhysicalWorld.cpp create mode 100644 src/native/physics/PhysicalWorld.hpp create mode 100644 third_party/CMakeLists.txt create mode 160000 third_party/JoltPhysics diff --git a/.clang-format b/.clang-format index d7f5caf8cc6..19aca05a10c 100644 --- a/.clang-format +++ b/.clang-format @@ -1,75 +1,161 @@ --- Language: Cpp -AccessModifierOffset: '-4' +AccessModifierOffset: -4 AlignAfterOpenBracket: DontAlign -AlignConsecutiveAssignments: 'false' -AlignConsecutiveDeclarations: 'false' -AlignEscapedNewlinesLeft: Left -AlignTrailingComments: 'false' -AllowAllParametersOfDeclarationOnNextLine: 'false' -AllowShortBlocksOnASingleLine: 'false' -AllowShortCaseLabelsOnASingleLine: 'true' -AllowShortFunctionsOnASingleLine: Empty -AllowShortIfStatementsOnASingleLine: 'false' -AllowShortLoopsOnASingleLine: 'false' -AlwaysBreakAfterReturnType: All -AlwaysBreakBeforeMultilineStrings: 'false' -AlwaysBreakTemplateDeclarations: 'false' -BinPackArguments: 'true' -BinPackParameters: 'false' +AlignArrayOfStructures: None +AlignConsecutiveAssignments: None +AlignConsecutiveBitFields: None +AlignConsecutiveDeclarations: None +AlignConsecutiveMacros: None +AlignEscapedNewlines: Right +AlignOperands: DontAlign +AlignTrailingComments: false +AllowAllArgumentsOnNextLine: true +AllowAllParametersOfDeclarationOnNextLine: true +AllowShortBlocksOnASingleLine: Never +AllowShortCaseLabelsOnASingleLine: false +AllowShortEnumsOnASingleLine: false +AllowShortFunctionsOnASingleLine: None +AllowShortIfStatementsOnASingleLine: false +AllowShortLambdasOnASingleLine: All +AllowShortLoopsOnASingleLine: false +AlwaysBreakAfterDefinitionReturnType: None +AlwaysBreakAfterReturnType: None +AlwaysBreakBeforeMultilineStrings: false +AlwaysBreakTemplateDeclarations: Yes +BinPackArguments: true +BinPackParameters: true +BitFieldColonSpacing: Both +BreakBeforeBraces: Allman +#BreakBeforeBraces: Custom +#BraceWrapping: +# AfterClass: false +# AfterControlStatement: false +# AfterEnum: false +# AfterFunction: true +# AfterNamespace: false +# AfterStruct: false +# AfterUnion: false +# # AfterExternBlock: false +# BeforeCatch: false +# BeforeElse: false +# IndentBraces: false +# SplitEmptyFunction: true +# SplitEmptyRecord: false +# SplitEmptyNamespace: true +BreakAfterAttributes: Never BreakBeforeBinaryOperators: None -# BreakBeforeBraces: Attach -BreakBeforeBraces: Custom -BraceWrapping: - AfterClass: false - AfterControlStatement: false - AfterEnum: false - AfterFunction: true - AfterNamespace: false - AfterStruct: false - AfterUnion: false - # AfterExternBlock: false - BeforeCatch: false - BeforeElse: false - IndentBraces: false - SplitEmptyFunction: true - SplitEmptyRecord: false - SplitEmptyNamespace: true -BreakBeforeInheritanceComma: 'false' -BreakBeforeTernaryOperators: 'false' +BreakBeforeConceptDeclarations: Never +BreakBeforeInlineASMColon: OnlyMultiline +BreakBeforeTernaryOperators: false BreakConstructorInitializers: AfterColon +BreakInheritanceList: AfterComma +BreakStringLiterals: false +ColumnLimit: 120 # Works fine even without this # CommentPragmas: '^! \\' -CompactNamespaces: 'true' -ConstructorInitializerAllOnOneLineOrOnePerLine: 'false' -Cpp11BracedListStyle: 'true' -DerivePointerAlignment: 'false' -IndentCaseLabels: 'false' -IndentWidth: '4' -IndentWrappedFunctionNames: 'true' -KeepEmptyLinesAtTheStartOfBlocks: 'true' -MaxEmptyLinesToKeep: '3' +CompactNamespaces: true +ConstructorInitializerIndentWidth: 4 +ContinuationIndentWidth: 4 +Cpp11BracedListStyle: true +DerivePointerAlignment: false +EmptyLineAfterAccessModifier: Never +EmptyLineBeforeAccessModifier: LogicalBlock +FixNamespaceComments: true +IncludeBlocks: Regroup +IncludeCategories: + - Regex: "<(Jolt|boost).*>" + Priority: 2 + - Regex: "<.*>" + Priority: 1 + - Regex: "\"(Include.h).*" + Priority: 3 + SortPriority: 3 + - Regex: "\"(core\/ForwardDefinitions.hpp).*" + Priority: 3 + SortPriority: 4 + - Regex: "\".*\/" + Priority: 5 + - Regex: ".*" + Priority: 6 +IndentAccessModifiers: false +IndentCaseLabels: false +IndentCaseBlocks: false +IndentExternBlock: AfterExternBlock +IndentGotoLabels: false +IndentPPDirectives: None +IndentRequiresClause: false +IndentWidth: 4 +IndentWrappedFunctionNames: true +InsertBraces: false +InsertNewlineAtEOF: true +KeepEmptyLinesAtTheStartOfBlocks: false +LambdaBodyIndentation: Signature +LineEnding: DeriveLF +# MacroBlockBegin: +# MacroBlockEnd: +# Macros: +MaxEmptyLinesToKeep: 1 NamespaceIndentation: None +# NamespaceMacros: +# - +PPIndentWidth: 1 +PackConstructorInitializers: BinPack PointerAlignment: Left -ReflowComments: 'true' -SortIncludes: 'true' -SortUsingDeclarations: 'true' -SpaceAfterCStyleCast: 'false' -SpaceAfterTemplateKeyword: 'false' -SpaceBeforeAssignmentOperators: 'true' -SpaceBeforeParens: Never -# This is also a new setting not yet available -# SpaceBeforeRangeBasedForLoopColon: 'true' -SpaceInEmptyParentheses: 'false' -SpacesBeforeTrailingComments: '1' -SpacesInAngles: 'false' -SpacesInCStyleCastParentheses: 'false' -SpacesInParentheses: 'false' -SpacesInContainerLiterals: 'false' -SpacesInParentheses: 'false' -SpacesInSquareBrackets: 'false' -Standard: Cpp11 -TabWidth: '4' +QualifierAlignment: Custom +QualifierOrder: + - static + - constexpr + - const + - inline + - volatile + - restrict + - friend + - type +# This needs to be left as otherwise functions will look ugly +ReferenceAlignment: Left +ReflowComments: true +RemoveSemicolon: true +RequiresClausePosition: OwnLine +RequiresExpressionIndentation: OuterScope +SeparateDefinitionBlocks: Always +ShortNamespaceLines: 0 +SortIncludes: CaseInsensitive +SortUsingDeclarations: Lexicographic +SpaceAfterCStyleCast: false +SpaceAfterLogicalNot: false +SpaceAfterTemplateKeyword: false +SpaceAroundPointerQualifiers: Before +SpaceBeforeAssignmentOperators: true +SpaceBeforeCaseColon: false +SpaceBeforeCpp11BracedList: false +SpaceBeforeCtorInitializerColon: true +SpaceBeforeInheritanceColon: true +SpaceBeforeParens: ControlStatementsExceptControlMacros +SpaceBeforeRangeBasedForLoopColon: true +SpaceBeforeSquareBrackets: false +SpaceInEmptyBlock: false +SpaceInEmptyParentheses: false +SpacesBeforeTrailingComments: 1 +SpacesInAngles: false +SpacesInCStyleCastParentheses: false +SpacesInConditionalStatement: false +SpacesInContainerLiterals: false +SpacesInLineCommentPrefix: + Minimum: 1 + Maximum: 1 +SpacesInParentheses: false +SpacesInSquareBrackets: false +Standard: c++17 +# StatementAttributeLikeMacros: +# - +# StatementMacros: +# - +TabWidth: 4 +# TypenameMacros: +# - UseTab: Never +# WhitespaceSensitiveMacros: +# - ... diff --git a/.clang-tidy b/.clang-tidy new file mode 100644 index 00000000000..2d41dba1d80 --- /dev/null +++ b/.clang-tidy @@ -0,0 +1,3 @@ +--- +Checks: '*,-llvmlibc-implementation-in-namespace,-llvm-header-guard,-modernize-use-trailing-return-type' +ShortStatementLines: 1 diff --git a/.gitignore b/.gitignore index c5f24895d6d..0ed88e8a3c7 100644 --- a/.gitignore +++ b/.gitignore @@ -2,6 +2,7 @@ /.import export.cfg /builds +/cmake-build* /inspect_results.xml /files_to_check.txt diff --git a/.gitmodules b/.gitmodules index ab8334e749f..f322f71cb79 100644 --- a/.gitmodules +++ b/.gitmodules @@ -1,3 +1,6 @@ [submodule "RevolutionaryGamesCommon"] path = RevolutionaryGamesCommon url = https://github.com/Revolutionary-Games/RevolutionaryGamesCommon.git +[submodule "third_party/JoltPhysics"] + path = third_party/JoltPhysics + url = https://github.com/jrouwe/JoltPhysics.git diff --git a/CMakeLists.txt b/CMakeLists.txt new file mode 100644 index 00000000000..a82a31c4c80 --- /dev/null +++ b/CMakeLists.txt @@ -0,0 +1,46 @@ +# Native code side of Thrive +cmake_minimum_required(VERSION 3.10) + +project(Thrive) + +# If you want to get compile commands run cmake with +# "-DCMAKE_EXPORT_COMPILE_COMMANDS=ON" + +# set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${PROJECT_SOURCE_DIR}/CMake") + +# static building +SET(CMAKE_FIND_LIBRARY_SUFFIXES ".a") +SET(BUILD_SHARED_LIBS OFF) + +# Common options +if(CMAKE_BUILD_TYPE STREQUAL "") + set(CMAKE_BUILD_TYPE Release CACHE STRING + "Set the build type, usually Release or RelWithDebInfo" FORCE) +endif(CMAKE_BUILD_TYPE STREQUAL "") + +if(CMAKE_BUILD_TYPE STREQUAL "Debug") + set(CMAKE_INSTALL_PREFIX "${CMAKE_INSTALL_PREFIX}/debug") +else() + set(CMAKE_INSTALL_PREFIX "${CMAKE_INSTALL_PREFIX}/release") +endif() + +# Detect library version +file(READ "src/native/NativeConstants.cs" versionFile) + +string(REGEX MATCH "Version = ([0-9]+);" _ "${versionFile}") +set(NATIVE_LIBRARY_VERSION ${CMAKE_MATCH_1}) + +if(NOT NATIVE_LIBRARY_VERSION) + message(FATAL_ERROR "Failed to parse native library version") +endif() + +message(STATUS "Configured native library version ${NATIVE_LIBRARY_VERSION}") + +# Configure include file +configure_file("src/native/Include.h.in" "${PROJECT_BINARY_DIR}/Include.h") +include_directories(${PROJECT_BINARY_DIR}) + +# Add the subfolders that define the actual things to build +add_subdirectory(third_party) + +add_subdirectory(src/native) diff --git a/Scripts/Scripts.csproj b/Scripts/Scripts.csproj index d39709b0008..2ae916141fa 100644 --- a/Scripts/Scripts.csproj +++ b/Scripts/Scripts.csproj @@ -21,4 +21,10 @@ + + + NativeConstants.cs + + + diff --git a/Thrive.csproj b/Thrive.csproj index 9f99db6b2f9..b1131ecfd50 100644 --- a/Thrive.csproj +++ b/Thrive.csproj @@ -619,6 +619,8 @@ + + diff --git a/Thrive.sln.DotSettings b/Thrive.sln.DotSettings index e0a2d455816..6d4d17e0697 100644 --- a/Thrive.sln.DotSettings +++ b/Thrive.sln.DotSettings @@ -603,6 +603,7 @@ True True True + True True True True @@ -666,6 +667,7 @@ True True True + True True True True diff --git a/src/engine/FeatureInformation.cs b/src/engine/FeatureInformation.cs index d622c72b298..15033c3d8f9 100644 --- a/src/engine/FeatureInformation.cs +++ b/src/engine/FeatureInformation.cs @@ -6,19 +6,23 @@ /// public static class FeatureInformation { + public const string PlatformWindows = "Windows"; + public const string PlatformLinux = "Linux"; + public const string PlatformMac = "OSX"; + private static readonly string[] SimpleFeaturePlatforms = { "Android", "HTML5", - "Windows", - "OSX", + PlatformWindows, + PlatformMac, "iOS", }; public static string GetOS() { if (OS.HasFeature("X11")) - return "Linux"; + return PlatformLinux; foreach (var feature in SimpleFeaturePlatforms) { diff --git a/src/engine/PostShutdownActions.cs b/src/engine/PostShutdownActions.cs index da7ea3e09d4..0aa1ae68360 100644 --- a/src/engine/PostShutdownActions.cs +++ b/src/engine/PostShutdownActions.cs @@ -46,5 +46,10 @@ private void OnAfterGameShutdown() { GD.PrintErr("Some tooltips have not been unregistered on game shutdown"); } + + GD.Print("Shutting down native library"); + NativeInterop.Shutdown(); + + GD.Print("Shutdown actions complete"); } } diff --git a/src/engine/StartupActions.cs b/src/engine/StartupActions.cs index 7c1f5e3f177..0c5262739a7 100644 --- a/src/engine/StartupActions.cs +++ b/src/engine/StartupActions.cs @@ -34,6 +34,8 @@ private StartupActions() GD.Print("Game logs are written to: ", Path.Combine(userDir, Constants.LOGS_FOLDER_NAME), " latest log is 'log.txt'"); + NativeInterop.Load(); + // Load settings here, to make sure locales etc. are applied to the main loaded and autoloaded scenes try { @@ -45,5 +47,7 @@ private StartupActions() { GD.PrintErr("Failed to initialize settings: ", e); } + + NativeInterop.Init(Settings.Instance); } } diff --git a/src/native/CMakeLists.txt b/src/native/CMakeLists.txt new file mode 100644 index 00000000000..63bdaba35f2 --- /dev/null +++ b/src/native/CMakeLists.txt @@ -0,0 +1,42 @@ +# Main library of the native side of things (non-Godot using) +add_library(thrive_native SHARED + interop/CInterop.h interop/CInterop.cpp + interop/CStructures.h + physics/PhysicalWorld.hpp physics/PhysicalWorld.cpp + "${PROJECT_BINARY_DIR}/Include.h" + ) + +target_compile_definitions(thrive_native PRIVATE THRIVE_NATIVE_BUILD) + +target_link_libraries(thrive_native PRIVATE Jolt) +# target_link_libraries(thrive_native PRIVATE stuff) + +target_include_directories(thrive_native PUBLIC ${CMAKE_CURRENT_LIST_DIR}) + +# target_include_directories(thrive_native PUBLIC "../../third_party/JoltPhysics/") + +target_precompile_headers(thrive_native PUBLIC "${PROJECT_BINARY_DIR}/Include.h" + PRIVATE "../../third_party/JoltPhysics/Jolt/Jolt.h") + +set_target_properties(thrive_native PROPERTIES + CXX_STANDARD 17 + CXX_EXTENSIONS OFF + INTERPROCEDURAL_OPTIMIZATION ON + ) + +message(STATUS "TODO: static standard lib for easier distributing") +# # Static standard lib +# target_link_libraries(thrive_native PRIVATE -static-libgcc -static-libstdc++) + +# # Fully static executable +# if(CMAKE_SYSTEM_NAME STREQUAL "Windows") +# target_link_libraries(thrive_native PRIVATE -static) +# endif() + +if(NOT WIN32) + set_target_properties(thrive_native PROPERTIES LINK_FLAGS_RELEASE "-fuse-ld=gold") +else() + set_target_properties(thrive_native PROPERTIES LINK_FLAGS_RELEASE "") +endif() + +install(TARGETS thrive_native) diff --git a/src/native/Include.h.in b/src/native/Include.h.in new file mode 100644 index 00000000000..c0ae75f4fe1 --- /dev/null +++ b/src/native/Include.h.in @@ -0,0 +1,22 @@ +#pragma once + +// +// File configured by CMake do not edit Include.h (you can edit Include.h.in) +// + +// clang-format off +#define THRIVE_LIBRARY_VERSION @NATIVE_LIBRARY_VERSION@ +// clang-format on + +#ifdef THRIVE_NATIVE_BUILD +#ifdef WIN32 +#define THRIVE_NATIVE_API __declspec(dllexport) +#else +#define THRIVE_NATIVE_API __attribute__((visibility("default"))) +#endif // WIN32 +#else +#ifdef WIN32 +#define THRIVE_NATIVE_API __declspec(dllimport) +#else +#endif // WIN32 +#endif // THRIVE_NATIVE_BUILD diff --git a/src/native/NativeConstants.cs b/src/native/NativeConstants.cs new file mode 100644 index 00000000000..1e71c75424c --- /dev/null +++ b/src/native/NativeConstants.cs @@ -0,0 +1,4 @@ +public class NativeConstants +{ + public const int Version = 1; +} diff --git a/src/native/interop/CInterop.cpp b/src/native/interop/CInterop.cpp new file mode 100644 index 00000000000..16d92df17b0 --- /dev/null +++ b/src/native/interop/CInterop.cpp @@ -0,0 +1,39 @@ +// ------------------------------------ // +#include "CInterop.h" + +#include "physics/PhysicalWorld.hpp" + +#pragma clang diagnostic push +#pragma ide diagnostic ignored "cppcoreguidelines-pro-type-reinterpret-cast" +// ------------------------------------ // +int32_t CheckAPIVersion() +{ + return THRIVE_LIBRARY_VERSION; +} + +int32_t InitThriveLibrary() +{ + // TODO: any startup actions needed + return 0; +} + +void ShutdownThriveLibrary() +{ + // TODO: shutdown actions +} +// ------------------------------------ // +PhysicalWorld* CreatePhysicalWorld() +{ + return reinterpret_cast(new Thrive::Physics::PhysicalWorld()); +} + +void DestroyPhysicalWorld(PhysicalWorld* physicalWorld) +{ + if (physicalWorld == nullptr) + return; + + delete reinterpret_cast(physicalWorld); +} + + +#pragma clang diagnostic pop diff --git a/src/native/interop/CInterop.h b/src/native/interop/CInterop.h new file mode 100644 index 00000000000..98aa0c2bb81 --- /dev/null +++ b/src/native/interop/CInterop.h @@ -0,0 +1,28 @@ +#pragma once + +#include + +#include "Include.h" +#include "interop/CStructures.h" + +/// \file Defines all of the API methods that can be called from C# + +extern "C" +{ + /// \returns The API version the native library was compiled with, if different from C# the library should not be + /// used + [[maybe_unused]] THRIVE_NATIVE_API int32_t CheckAPIVersion(); + + /// \summary Prepares the native library for use, must be called first (right after the version check) + [[maybe_unused]] THRIVE_NATIVE_API int32_t InitThriveLibrary(); + + /// \summary Prepares the native library for shutdown should be called before the process is ended and after all + /// other calls to the library have been performed + [[maybe_unused]] THRIVE_NATIVE_API void ShutdownThriveLibrary(); + + // ------------------------------------ // + + [[maybe_unused]] THRIVE_NATIVE_API PhysicalWorld* CreatePhysicalWorld(); + + [[maybe_unused]] THRIVE_NATIVE_API void DestroyPhysicalWorld(PhysicalWorld* physicalWorld); +} diff --git a/src/native/interop/CStructures.h b/src/native/interop/CStructures.h new file mode 100644 index 00000000000..98d0114b4dd --- /dev/null +++ b/src/native/interop/CStructures.h @@ -0,0 +1,13 @@ +#pragma once + +#include "Include.h" + +#pragma clang diagnostic push +#pragma ide diagnostic ignored "modernize-use-using" + +extern "C" +{ + typedef struct PhysicalWorld PhysicalWorld; +} + +#pragma clang diagnostic pop diff --git a/src/native/interop/NativeInterop.cs b/src/native/interop/NativeInterop.cs new file mode 100644 index 00000000000..3d81e2528c4 --- /dev/null +++ b/src/native/interop/NativeInterop.cs @@ -0,0 +1,84 @@ +using System; +using System.Collections.Generic; +using System.Reflection; +using System.Runtime.InteropServices; +using Godot; +using Directory = System.IO.Directory; +using File = System.IO.File; +using Path = System.IO.Path; + +/// +/// Calling interface from C# to the native code side of things for the native module +/// +public static class NativeInterop +{ + private static bool loadCalled; + + /// + /// Loads and checks the native library is good to use + /// + /// If the library is not fine (wrong version) + /// If finding the library failed + public static void Load() + { + if (loadCalled) + throw new InvalidOperationException("Load has been called already"); + + loadCalled = true; + + // ReSharper disable once CommentTypo + // TODO: come up with some approach for putting the native library to a sensible folder, + // approach trying to manually load the library doesn't work (unless we manually look up all the methods + // instead of using DllImportAttribute, also mono_dllmap_insert doesn't work as still the attributes load + // before that can be used to set. With .NET 7 it should be possible to finally cleanly fix this: + // https://learn.microsoft.com/en-us/dotnet/standard/native-interop/cross-platform#custom-import-resolver + + int version = NativeMethods.CheckAPIVersion(); + + if (version != NativeConstants.Version) + { + throw new Exception($"Failed to initialize Thrive native library, unexpected version {version} " + + $"is not required: {NativeConstants.Version}"); + } + + GD.Print("Loaded native Thrive library version ", version); + } + + /// + /// Performs any initialization needed by the native library + /// + /// Current game settings + public static void Init(Settings settings) + { + // Settings are passed as probably in the future something needs to be setup right in the native side of + // things for the initial settings + _ = settings; + + var result = NativeMethods.InitThriveLibrary(); + + if (result != 0) + { + throw new InvalidOperationException($"Failed to initialize Thrive native library, code: {result}"); + } + } + + /// + /// Releases all native resources and prepares the library for process exit + /// + public static void Shutdown() + { + NativeMethods.ShutdownThriveLibrary(); + } +} + +internal static class NativeMethods +{ + [DllImport("thrive_native")] + internal static extern int CheckAPIVersion(); + + [DllImport("thrive_native")] + internal static extern int InitThriveLibrary(); + + [DllImport("thrive_native")] + internal static extern void ShutdownThriveLibrary(); +} diff --git a/src/native/physics/PhysicalWorld.cpp b/src/native/physics/PhysicalWorld.cpp new file mode 100644 index 00000000000..dd46fa116b9 --- /dev/null +++ b/src/native/physics/PhysicalWorld.cpp @@ -0,0 +1,9 @@ +// ------------------------------------ // +#include "PhysicalWorld.hpp" + +using namespace Thrive::Physics; +// ------------------------------------ // +PhysicalWorld::PhysicalWorld() {} + +PhysicalWorld::~PhysicalWorld() {} +// ------------------------------------ // diff --git a/src/native/physics/PhysicalWorld.hpp b/src/native/physics/PhysicalWorld.hpp new file mode 100644 index 00000000000..344996b7670 --- /dev/null +++ b/src/native/physics/PhysicalWorld.hpp @@ -0,0 +1,15 @@ +#pragma once + +namespace Thrive::Physics +{ + +class PhysicalWorld +{ +public: + PhysicalWorld(); + ~PhysicalWorld(); + +private: +}; + +} // namespace Thrive::Physics diff --git a/third_party/CMakeLists.txt b/third_party/CMakeLists.txt new file mode 100644 index 00000000000..a460f5d2cf5 --- /dev/null +++ b/third_party/CMakeLists.txt @@ -0,0 +1,7 @@ +# Native third party module references +message(STATUS "TODO: do these native third party modules") + +# TODO: do we need to turn this off (requiring too new AMD CPUs)? +set(USE_AVX2 ON) + +add_subdirectory(JoltPhysics/Build) diff --git a/third_party/JoltPhysics b/third_party/JoltPhysics new file mode 160000 index 00000000000..8d3008e21ba --- /dev/null +++ b/third_party/JoltPhysics @@ -0,0 +1 @@ +Subproject commit 8d3008e21baff6ce774b821adc73618bb3b891af From 4edd0320a4116c45a47a13ac53b7aa580d346b3c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henri=20Hyyryl=C3=A4inen?= Date: Thu, 1 Jun 2023 14:21:19 +0300 Subject: [PATCH 02/79] Implemented a basic collision listener class Made sure API import also defines default visibility and added pool setting Tweaked Jolt build settings and warning options for the thrive lib Started on a few various files, tweaked some stuff, setup clang tidy rules more sensibly --- .clang-tidy | 4 +- CMakeLists.txt | 11 +++- src/native/CMakeLists.txt | 32 ++++++++--- src/native/Include.h.in | 3 ++ src/native/core/ForwardDefinitions.hpp | 13 +++++ src/native/core/Mutex.hpp | 14 +++++ src/native/interop/CInterop.cpp | 3 +- src/native/interop/CInterop.h | 5 +- src/native/physics/ContactListener.cpp | 74 ++++++++++++++++++++++++++ src/native/physics/ContactListener.hpp | 40 ++++++++++++++ third_party/CMakeLists.txt | 9 +++- 11 files changed, 194 insertions(+), 14 deletions(-) create mode 100644 src/native/core/ForwardDefinitions.hpp create mode 100644 src/native/core/Mutex.hpp create mode 100644 src/native/physics/ContactListener.cpp create mode 100644 src/native/physics/ContactListener.hpp diff --git a/.clang-tidy b/.clang-tidy index 2d41dba1d80..b690a22139a 100644 --- a/.clang-tidy +++ b/.clang-tidy @@ -1,3 +1,5 @@ --- -Checks: '*,-llvmlibc-implementation-in-namespace,-llvm-header-guard,-modernize-use-trailing-return-type' +Checks: '-*,boost-*,bugprone-*,cert-*,clang-analyzer-*,concurrency-*,cppcoreguidelines-*,hicpp-*, + llvm-*,-llvm-header-guard,misc-*,-misc-no-recursion,modernize-*,-modernize-use-trailing-return-type, + performance-*,portability-*,readability-*' ShortStatementLines: 1 diff --git a/CMakeLists.txt b/CMakeLists.txt index a82a31c4c80..5e4ad988858 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -6,11 +6,18 @@ project(Thrive) # If you want to get compile commands run cmake with # "-DCMAKE_EXPORT_COMPILE_COMMANDS=ON" +# Options +option(USE_OBJECT_POOLS + "Use object pools instead of direct memory allocation (can be turned off for memory debugging)" + ON) + +option(WARNINGS_AS_ERRORS "When on treat compiler warnings as errors" ON) + # set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${PROJECT_SOURCE_DIR}/CMake") # static building -SET(CMAKE_FIND_LIBRARY_SUFFIXES ".a") -SET(BUILD_SHARED_LIBS OFF) +set(CMAKE_FIND_LIBRARY_SUFFIXES ".a") +set(BUILD_SHARED_LIBS OFF) # Common options if(CMAKE_BUILD_TYPE STREQUAL "") diff --git a/src/native/CMakeLists.txt b/src/native/CMakeLists.txt index 63bdaba35f2..dbcff143eb4 100644 --- a/src/native/CMakeLists.txt +++ b/src/native/CMakeLists.txt @@ -1,10 +1,29 @@ # Main library of the native side of things (non-Godot using) add_library(thrive_native SHARED - interop/CInterop.h interop/CInterop.cpp + "${PROJECT_BINARY_DIR}/Include.h" core/ForwardDefinitions.hpp + interop/CInterop.cpp interop/CInterop.h interop/CStructures.h - physics/PhysicalWorld.hpp physics/PhysicalWorld.cpp - "${PROJECT_BINARY_DIR}/Include.h" - ) + physics/PhysicalWorld.cpp physics/PhysicalWorld.hpp + physics/Layers.hpp + core/TaskSystem.cpp core/TaskSystem.hpp + physics/ContactListener.cpp physics/ContactListener.hpp + core/Mutex.hpp) + +if("${CMAKE_CXX_COMPILER_ID}" STREQUAL "MSVC") + target_compile_options(thrive_native PRIVATE /W4 /wd4068) + + if(WARNINGS_AS_ERRORS) + target_compile_options(thrive_native PRIVATE /WX) + endif() +else() + target_compile_options(thrive_native PRIVATE -Wall -Wextra -Wpedantic -Werror + -Wno-unknown-pragmas) + + if(WARNINGS_AS_ERRORS) + target_compile_options(thrive_native PRIVATE -Werror) + endif() +endif() + target_compile_definitions(thrive_native PRIVATE THRIVE_NATIVE_BUILD) @@ -16,13 +35,12 @@ target_include_directories(thrive_native PUBLIC ${CMAKE_CURRENT_LIST_DIR}) # target_include_directories(thrive_native PUBLIC "../../third_party/JoltPhysics/") target_precompile_headers(thrive_native PUBLIC "${PROJECT_BINARY_DIR}/Include.h" - PRIVATE "../../third_party/JoltPhysics/Jolt/Jolt.h") + PRIVATE "../../third_party/JoltPhysics/Jolt/Jolt.h" "core/ForwardDefinitions.hpp") set_target_properties(thrive_native PROPERTIES CXX_STANDARD 17 CXX_EXTENSIONS OFF - INTERPROCEDURAL_OPTIMIZATION ON - ) + INTERPROCEDURAL_OPTIMIZATION ON) message(STATUS "TODO: static standard lib for easier distributing") # # Static standard lib diff --git a/src/native/Include.h.in b/src/native/Include.h.in index c0ae75f4fe1..014ea75f0aa 100644 --- a/src/native/Include.h.in +++ b/src/native/Include.h.in @@ -18,5 +18,8 @@ #ifdef WIN32 #define THRIVE_NATIVE_API __declspec(dllimport) #else +#define THRIVE_NATIVE_API __attribute__((visibility("default"))) #endif // WIN32 #endif // THRIVE_NATIVE_BUILD + +#cmakedefine USE_OBJECT_POOLS diff --git a/src/native/core/ForwardDefinitions.hpp b/src/native/core/ForwardDefinitions.hpp new file mode 100644 index 00000000000..c490fb5cb47 --- /dev/null +++ b/src/native/core/ForwardDefinitions.hpp @@ -0,0 +1,13 @@ +#pragma once + +/// \file Forward definitions for various important classes in this library for reducing header include amounts + +namespace Thrive +{ +class TaskSystem; + +namespace Physics +{ +class ContactListener; +} // namespace Physics +} // namespace Thrive diff --git a/src/native/core/Mutex.hpp b/src/native/core/Mutex.hpp new file mode 100644 index 00000000000..ba94a6b6526 --- /dev/null +++ b/src/native/core/Mutex.hpp @@ -0,0 +1,14 @@ +#pragma once + +#include +#include + +// Jolt says the mutex is not fast for all platforms so here's some flexibility to allow redefining it + +namespace Thrive +{ +using Mutex = std::mutex; +using SharedMutex = std::shared_mutex; +using Lock = std::lock_guard; +using SharedLock = std::lock_guard; +} // namespace Thrive diff --git a/src/native/interop/CInterop.cpp b/src/native/interop/CInterop.cpp index 16d92df17b0..30d1f94e0e8 100644 --- a/src/native/interop/CInterop.cpp +++ b/src/native/interop/CInterop.cpp @@ -5,6 +5,7 @@ #pragma clang diagnostic push #pragma ide diagnostic ignored "cppcoreguidelines-pro-type-reinterpret-cast" + // ------------------------------------ // int32_t CheckAPIVersion() { @@ -21,6 +22,7 @@ void ShutdownThriveLibrary() { // TODO: shutdown actions } + // ------------------------------------ // PhysicalWorld* CreatePhysicalWorld() { @@ -35,5 +37,4 @@ void DestroyPhysicalWorld(PhysicalWorld* physicalWorld) delete reinterpret_cast(physicalWorld); } - #pragma clang diagnostic pop diff --git a/src/native/interop/CInterop.h b/src/native/interop/CInterop.h index 98aa0c2bb81..02deaad3ccc 100644 --- a/src/native/interop/CInterop.h +++ b/src/native/interop/CInterop.h @@ -3,6 +3,7 @@ #include #include "Include.h" + #include "interop/CStructures.h" /// \file Defines all of the API methods that can be called from C# @@ -13,10 +14,10 @@ extern "C" /// used [[maybe_unused]] THRIVE_NATIVE_API int32_t CheckAPIVersion(); - /// \summary Prepares the native library for use, must be called first (right after the version check) + /// \brief Prepares the native library for use, must be called first (right after the version check) [[maybe_unused]] THRIVE_NATIVE_API int32_t InitThriveLibrary(); - /// \summary Prepares the native library for shutdown should be called before the process is ended and after all + /// \brief Prepares the native library for shutdown should be called before the process is ended and after all /// other calls to the library have been performed [[maybe_unused]] THRIVE_NATIVE_API void ShutdownThriveLibrary(); diff --git a/src/native/physics/ContactListener.cpp b/src/native/physics/ContactListener.cpp new file mode 100644 index 00000000000..006d2be9a4e --- /dev/null +++ b/src/native/physics/ContactListener.cpp @@ -0,0 +1,74 @@ +// ------------------------------------ // +#include "ContactListener.hpp" + +#include +// ------------------------------------ // +using namespace Thrive::Physics; + +JPH::ValidateResult ContactListener::OnContactValidate(const JPH::Body& body1, const JPH::Body& body2, + JPH::RVec3Arg baseOffset, const JPH::CollideShapeResult& collisionResult) +{ + JPH::ValidateResult result; + if (chainedListener != nullptr) + { + result = chainedListener->OnContactValidate(body1, body2, baseOffset, collisionResult); + } + else + { + result = JPH::ContactListener::OnContactValidate(body1, body2, baseOffset, collisionResult); + } + + return result; +} + +void ContactListener::OnContactAdded(const JPH::Body& body1, const JPH::Body& body2, + const JPH::ContactManifold& manifold, JPH::ContactSettings& settings) +{ + // Note the bodies are sorted (at least the sample Jolt code has asserts to verify it, so we can probably safely + // always assume that) `body1.GetID() < body2.GetID()` + + // Add the new collision + { + Lock lock(currentCollisionsMutex); + JPH::SubShapeIDPair key(body1.GetID(), manifold.mSubShapeID1, body2.GetID(), manifold.mSubShapeID2); + currentCollisions[key] = CollisionPair(manifold.mBaseOffset, manifold.mRelativeContactPointsOn1); + } + + if (chainedListener != nullptr) + chainedListener->OnContactAdded(body1, body2, manifold, settings); +} + +void ContactListener::OnContactPersisted(const JPH::Body& body1, const JPH::Body& body2, + const JPH::ContactManifold& manifold, JPH::ContactSettings& settings) +{ + // Update existing collision info + { + Lock lock(currentCollisionsMutex); + + JPH::SubShapeIDPair key(body1.GetID(), manifold.mSubShapeID1, body2.GetID(), manifold.mSubShapeID2); + + const auto iter = currentCollisions.find(key); + if (iter != currentCollisions.end()) + { + iter->second = CollisionPair(manifold.mBaseOffset, manifold.mRelativeContactPointsOn1); + } + } + + if (chainedListener != nullptr) + chainedListener->OnContactPersisted(body1, body2, manifold, settings); +} + +void ContactListener::OnContactRemoved(const JPH::SubShapeIDPair& subShapePair) +{ + // Remove the contact + { + Lock lock(currentCollisionsMutex); + + const auto iter = currentCollisions.find(subShapePair); + if (iter != currentCollisions.end()) + currentCollisions.erase(iter); + } + + if (chainedListener != nullptr) + chainedListener->OnContactRemoved(subShapePair); +} diff --git a/src/native/physics/ContactListener.hpp b/src/native/physics/ContactListener.hpp new file mode 100644 index 00000000000..9ee0078ab9b --- /dev/null +++ b/src/native/physics/ContactListener.hpp @@ -0,0 +1,40 @@ +#pragma once + +#include + +#include "core/Mutex.hpp" + +namespace Thrive::Physics +{ +/// \brief Contact listener implementation +class ContactListener : public JPH::ContactListener +{ + using CollisionPair = std::pair; + +public: + JPH::ValidateResult OnContactValidate(const JPH::Body& body1, const JPH::Body& body2, JPH::RVec3Arg baseOffset, + const JPH::CollideShapeResult& collisionResult) override; + + void OnContactAdded(const JPH::Body& body1, const JPH::Body& body2, const JPH::ContactManifold& manifold, + JPH::ContactSettings& settings) override; + + void OnContactPersisted(const JPH::Body& body1, const JPH::Body& body2, const JPH::ContactManifold& manifold, + JPH::ContactSettings& settings) override; + + void OnContactRemoved(const JPH::SubShapeIDPair& subShapePair) override; + + inline void SetNextListener(JPH::ContactListener* listener) + { + chainedListener = listener; + } + +private: + Mutex currentCollisionsMutex; + + // TODO: JPH seems to use a custom allocator here so we might need to do so as well (for performance) + std::unordered_map currentCollisions; + + JPH::ContactListener* chainedListener = nullptr; +}; + +} // namespace Thrive::Physics diff --git a/third_party/CMakeLists.txt b/third_party/CMakeLists.txt index a460f5d2cf5..2f5d8eda8f4 100644 --- a/third_party/CMakeLists.txt +++ b/third_party/CMakeLists.txt @@ -1,7 +1,14 @@ # Native third party module references -message(STATUS "TODO: do these native third party modules") + +# JoltPhysics + +# Might as well get used to double precision impact now as we'll want that eventually anyway +set(DOUBLE_PRECISION ON) # TODO: do we need to turn this off (requiring too new AMD CPUs)? set(USE_AVX2 ON) +# This is way too unsupported to enable in a general build +set(USE_AVX512 OFF) + add_subdirectory(JoltPhysics/Build) From a3c271492ca85a38279124c86886f5686a69caa6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henri=20Hyyryl=C3=A4inen?= Date: Thu, 1 Jun 2023 15:00:00 +0300 Subject: [PATCH 03/79] Wrote a basic layers implementation based on the Jolt sample approach added really basic logger interface Switch to normal quotes for Jolt imports probably better to do it that way and not fight my IDE all the time Added some shape creation helpers Added the new files to compile Finished setting up some basic physical world stuff Got jolt to combine into the shared library Cleaned up the native interop file a bit Setup native log message forwarding Add mesh creation helper method Add new libraries to LICENSE.txt --- .clang-format | 8 +- CMakeLists.txt | 12 ++- LICENSE.txt | 3 + src/native/CMakeLists.txt | 9 +- src/native/core/Logger.cpp | 43 ++++++++ src/native/core/Logger.hpp | 79 ++++++++++++++ src/native/interop/CInterop.cpp | 30 +++++- src/native/interop/CInterop.h | 10 +- src/native/interop/NativeInterop.cs | 48 ++++++++- src/native/physics/ContactListener.cpp | 2 +- src/native/physics/ContactListener.hpp | 2 +- src/native/physics/Layers.hpp | 143 +++++++++++++++++++++++++ src/native/physics/PhysicalWorld.cpp | 136 ++++++++++++++++++++++- src/native/physics/PhysicalWorld.hpp | 76 +++++++++++++ src/native/physics/ShapeCreator.cpp | 57 ++++++++++ src/native/physics/ShapeCreator.hpp | 41 +++++++ src/native/physics/SimpleShapes.cpp | 46 ++++++++ src/native/physics/SimpleShapes.hpp | 36 +++++++ third_party/CMakeLists.txt | 4 + 19 files changed, 765 insertions(+), 20 deletions(-) create mode 100644 src/native/core/Logger.cpp create mode 100644 src/native/core/Logger.hpp create mode 100644 src/native/physics/Layers.hpp create mode 100644 src/native/physics/ShapeCreator.cpp create mode 100644 src/native/physics/ShapeCreator.hpp create mode 100644 src/native/physics/SimpleShapes.cpp create mode 100644 src/native/physics/SimpleShapes.hpp diff --git a/.clang-format b/.clang-format index 19aca05a10c..734a68c46f4 100644 --- a/.clang-format +++ b/.clang-format @@ -64,14 +64,14 @@ EmptyLineBeforeAccessModifier: LogicalBlock FixNamespaceComments: true IncludeBlocks: Regroup IncludeCategories: - - Regex: "<(Jolt|boost).*>" + - Regex: "(<|\")(Jolt|boost).*" Priority: 2 - Regex: "<.*>" Priority: 1 - - Regex: "\"(Include.h).*" + - Regex: "\"Include\\.h.*" Priority: 3 SortPriority: 3 - - Regex: "\"(core\/ForwardDefinitions.hpp).*" + - Regex: "\"(core\/ForwardDefinitions\\.hpp).*" Priority: 3 SortPriority: 4 - Regex: "\".*\/" @@ -79,7 +79,7 @@ IncludeCategories: - Regex: ".*" Priority: 6 IndentAccessModifiers: false -IndentCaseLabels: false +IndentCaseLabels: true IndentCaseBlocks: false IndentExternBlock: AfterExternBlock IndentGotoLabels: false diff --git a/CMakeLists.txt b/CMakeLists.txt index 5e4ad988858..ed107facc02 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -22,8 +22,16 @@ set(BUILD_SHARED_LIBS OFF) # Common options if(CMAKE_BUILD_TYPE STREQUAL "") set(CMAKE_BUILD_TYPE Release CACHE STRING - "Set the build type, usually Release or RelWithDebInfo" FORCE) -endif(CMAKE_BUILD_TYPE STREQUAL "") + "Set the build type, usually Debug or Distribution" FORCE) +endif() + +# A bit unneeded Jolt hack +# # This and the following hack is required due to Jolt being very debug-y in +# # release mode +# elseif(CMAKE_BUILD_TYPE STREQUAL "Release") +# set(CMAKE_BUILD_TYPE Distribution) +# elseif(CMAKE_BUILD_TYPE STREQUAL "RelWithDebInfo") +# set(CMAKE_BUILD_TYPE Distribution) if(CMAKE_BUILD_TYPE STREQUAL "Debug") set(CMAKE_INSTALL_PREFIX "${CMAKE_INSTALL_PREFIX}/debug") diff --git a/LICENSE.txt b/LICENSE.txt index 8b031e024b6..7847dd9ca36 100644 --- a/LICENSE.txt +++ b/LICENSE.txt @@ -55,3 +55,6 @@ AngleSharp: The MIT License (MIT) Copyright (c) 2013 - 2023 AngleSharp YamlDotNet: MIT License Copyright (c) 2008, 2009, 2010, 2011, 2012, 2013, 2014 Antoine Aubry and contributors +JoltPhysics: MIT License Copyright 2021 Jorrit Rouwe + +Boost C++ Libraries: Boost Software License - Version 1.0 diff --git a/src/native/CMakeLists.txt b/src/native/CMakeLists.txt index dbcff143eb4..3d19444cc9f 100644 --- a/src/native/CMakeLists.txt +++ b/src/native/CMakeLists.txt @@ -3,11 +3,14 @@ add_library(thrive_native SHARED "${PROJECT_BINARY_DIR}/Include.h" core/ForwardDefinitions.hpp interop/CInterop.cpp interop/CInterop.h interop/CStructures.h - physics/PhysicalWorld.cpp physics/PhysicalWorld.hpp - physics/Layers.hpp + core/Logger.cpp core/Logger.hpp + core/Mutex.hpp core/TaskSystem.cpp core/TaskSystem.hpp physics/ContactListener.cpp physics/ContactListener.hpp - core/Mutex.hpp) + physics/Layers.hpp + physics/PhysicalWorld.cpp physics/PhysicalWorld.hpp + physics/ShapeCreator.cpp physics/ShapeCreator.hpp + physics/SimpleShapes.cpp physics/SimpleShapes.hpp) if("${CMAKE_CXX_COMPILER_ID}" STREQUAL "MSVC") target_compile_options(thrive_native PRIVATE /W4 /wd4068) diff --git a/src/native/core/Logger.cpp b/src/native/core/Logger.cpp new file mode 100644 index 00000000000..92acf704cc2 --- /dev/null +++ b/src/native/core/Logger.cpp @@ -0,0 +1,43 @@ +// ------------------------------------ // +#include "Logger.hpp" + +#include +// ------------------------------------ // +using namespace Thrive; + +void Logger::Log(std::string_view message, LogLevel level) +{ + // Drop logs that are not important enough with current level + if (level < currentLoggingLevel) + return; + + // TODO: should we have a mutex to lock before outputting? + + if (isRedirected) + { + redirectedLogReceiver(message, level); + return; + } + + std::cout << message << "\n"; + + if (level >= LogLevel::Error && flushOnError) + { + std::cout.flush(); + } +} + +// ------------------------------------ // +void Logger::SetLogTargetOverride(std::function&& logReceiver) +{ + if (!logReceiver) + { + isRedirected = false; + redirectedLogReceiver = nullptr; + } + else + { + redirectedLogReceiver = std::move(logReceiver); + isRedirected = true; + } +} diff --git a/src/native/core/Logger.hpp b/src/native/core/Logger.hpp new file mode 100644 index 00000000000..c29e8dd06bb --- /dev/null +++ b/src/native/core/Logger.hpp @@ -0,0 +1,79 @@ +#pragma once + +#include "Include.h" + +namespace Thrive +{ + +enum class LogLevel : int8_t +{ + Debug = 0, + Info = 1, + Warning = 2, + Error = 3 +}; + +/// \brief Provides native side logging support. Forwards logging to the usual Godot log +/// \todo For Visual Studio debugging implement the Windows debugger output writing when outputting to std::cout +class Logger +{ +public: + THRIVE_NATIVE_API static Logger& Get() + { + static Logger instance; + return instance; + } + + THRIVE_NATIVE_API inline void LogDebug(std::string_view message) + { + Log(message, LogLevel::Debug); + } + + THRIVE_NATIVE_API inline void LogInfo(std::string_view message) + { + Log(message, LogLevel::Info); + } + + THRIVE_NATIVE_API inline void LogWarning(std::string_view message) + { + Log(message, LogLevel::Warning); + } + + THRIVE_NATIVE_API inline void LogError(std::string_view message) + { + Log(message, LogLevel::Error); + } + + THRIVE_NATIVE_API void Log(std::string_view message, LogLevel level); + + /// \brief Sets the log level which controls what log messages actually get passed + THRIVE_NATIVE_API void SetLogLevel(LogLevel level){ + currentLoggingLevel = level; + } + + /// \brief Overrides the log output from standard to the given methods + /// + /// This is used by the managed side of things to setup logging + /// \see CInterop.h + THRIVE_NATIVE_API void SetLogTargetOverride(std::function&& logReceiver); + + /// \brief When flush on error is on, the output is flushed on each error message + THRIVE_NATIVE_API void SetFlushOnError(bool flush){ + flushOnError = flush; + } + +private: + bool flushOnError = true; + + bool isRedirected = false; + std::function redirectedLogReceiver; + + LogLevel currentLoggingLevel = LogLevel::Info; +}; + +}; // namespace Thrive + +#define LOG_DEBUG(x) Thrive::Logger::Get().LogDebug(x) +#define LOG_INFO(x) Thrive::Logger::Get().LogInfo(x) +#define LOG_WARNING(x) Thrive::Logger::Get().LogWarning(x) +#define LOG_ERROR(x) Thrive::Logger::Get().LogError(x) diff --git a/src/native/interop/CInterop.cpp b/src/native/interop/CInterop.cpp index 30d1f94e0e8..04708d8400a 100644 --- a/src/native/interop/CInterop.cpp +++ b/src/native/interop/CInterop.cpp @@ -15,12 +15,35 @@ int32_t CheckAPIVersion() int32_t InitThriveLibrary() { // TODO: any startup actions needed + + LOG_DEBUG("Native library init succeeded"); return 0; } void ShutdownThriveLibrary() { - // TODO: shutdown actions + SetLogForwardingCallback(nullptr); +} + +// ------------------------------------ // +void SetLogLevel(int8_t level) +{ + Thrive::Logger::Get().SetLogLevel(static_cast(level)); +} + +void SetLogForwardingCallback(OnLogMessage callback) +{ + if (callback == nullptr) + { + Thrive::Logger::Get().SetLogTargetOverride(nullptr); + } + else + { + Thrive::Logger::Get().SetLogTargetOverride([callback](std::string_view message, Thrive::LogLevel level) + { callback(message.data(), static_cast(message.length()), static_cast(level)); }); + + LOG_DEBUG("Native log message forwarding setup"); + } } // ------------------------------------ // @@ -37,4 +60,9 @@ void DestroyPhysicalWorld(PhysicalWorld* physicalWorld) delete reinterpret_cast(physicalWorld); } +bool ProcessPhysicalWorld(PhysicalWorld* physicalWorld, float delta) +{ + return reinterpret_cast(physicalWorld)->Process(delta); +} + #pragma clang diagnostic pop diff --git a/src/native/interop/CInterop.h b/src/native/interop/CInterop.h index 02deaad3ccc..90b96ad2af1 100644 --- a/src/native/interop/CInterop.h +++ b/src/native/interop/CInterop.h @@ -10,6 +10,8 @@ extern "C" { + typedef void (*OnLogMessage)(const char* message, int32_t messageLength, int8_t logLevel); + /// \returns The API version the native library was compiled with, if different from C# the library should not be /// used [[maybe_unused]] THRIVE_NATIVE_API int32_t CheckAPIVersion(); @@ -23,7 +25,13 @@ extern "C" // ------------------------------------ // - [[maybe_unused]] THRIVE_NATIVE_API PhysicalWorld* CreatePhysicalWorld(); + [[maybe_unused]] THRIVE_NATIVE_API void SetLogLevel(int8_t level); + [[maybe_unused]] THRIVE_NATIVE_API void SetLogForwardingCallback(OnLogMessage callback); + + // ------------------------------------ // + [[maybe_unused]] THRIVE_NATIVE_API PhysicalWorld* CreatePhysicalWorld(); [[maybe_unused]] THRIVE_NATIVE_API void DestroyPhysicalWorld(PhysicalWorld* physicalWorld); + + [[maybe_unused]] THRIVE_NATIVE_API bool ProcessPhysicalWorld(PhysicalWorld* physicalWorld, float delta); } diff --git a/src/native/interop/NativeInterop.cs b/src/native/interop/NativeInterop.cs index 3d81e2528c4..b448b130e59 100644 --- a/src/native/interop/NativeInterop.cs +++ b/src/native/interop/NativeInterop.cs @@ -1,11 +1,6 @@ using System; -using System.Collections.Generic; -using System.Reflection; using System.Runtime.InteropServices; using Godot; -using Directory = System.IO.Directory; -using File = System.IO.File; -using Path = System.IO.Path; /// /// Calling interface from C# to the native code side of things for the native module @@ -32,6 +27,7 @@ public static void Load() // instead of using DllImportAttribute, also mono_dllmap_insert doesn't work as still the attributes load // before that can be used to set. With .NET 7 it should be possible to finally cleanly fix this: // https://learn.microsoft.com/en-us/dotnet/standard/native-interop/cross-platform#custom-import-resolver + // `NativeLibrary.Load` would probably also be a good way to do something int version = NativeMethods.CheckAPIVersion(); @@ -42,6 +38,11 @@ public static void Load() } GD.Print("Loaded native Thrive library version ", version); + + // Enable debug logging if this is being debugged +#if DEBUG + NativeMethods.SetLogLevel(NativeMethods.LogLevel.Debug); +#endif } /// @@ -54,6 +55,8 @@ public static void Init(Settings settings) // things for the initial settings _ = settings; + NativeMethods.SetLogForwardingCallback(ForwardMessage); + var result = NativeMethods.InitThriveLibrary(); if (result != 0) @@ -69,10 +72,39 @@ public static void Shutdown() { NativeMethods.ShutdownThriveLibrary(); } + + private static void ForwardMessage(IntPtr messageData, int messageLength, NativeMethods.LogLevel level) + { + var message = Marshal.PtrToStringAnsi(messageData, messageLength); + + if (level <= NativeMethods.LogLevel.Info) + { + GD.Print("[NATIVE] ", message); + } + else if (level <= NativeMethods.LogLevel.Warning) + { + // TODO: something different for warning level? + GD.Print("[NATIVE] WARNING:", message); + } + else + { + GD.PrintErr("[NATIVE] ", message); + } + } } internal static class NativeMethods { + internal delegate void OnLogMessage(IntPtr messageData, int messageLength, LogLevel level); + + internal enum LogLevel : byte + { + Debug = 0, + Info = 1, + Warning = 2, + Error = 3, + } + [DllImport("thrive_native")] internal static extern int CheckAPIVersion(); @@ -81,4 +113,10 @@ internal static class NativeMethods [DllImport("thrive_native")] internal static extern void ShutdownThriveLibrary(); + + [DllImport("thrive_native")] + internal static extern void SetLogLevel(LogLevel level); + + [DllImport("thrive_native")] + internal static extern void SetLogForwardingCallback(OnLogMessage callback); } diff --git a/src/native/physics/ContactListener.cpp b/src/native/physics/ContactListener.cpp index 006d2be9a4e..5ada9feac70 100644 --- a/src/native/physics/ContactListener.cpp +++ b/src/native/physics/ContactListener.cpp @@ -1,7 +1,7 @@ // ------------------------------------ // #include "ContactListener.hpp" -#include +#include "Jolt/Physics/Body/Body.h" // ------------------------------------ // using namespace Thrive::Physics; diff --git a/src/native/physics/ContactListener.hpp b/src/native/physics/ContactListener.hpp index 9ee0078ab9b..2ec3652054c 100644 --- a/src/native/physics/ContactListener.hpp +++ b/src/native/physics/ContactListener.hpp @@ -1,6 +1,6 @@ #pragma once -#include +#include "Jolt/Physics/Collision/ContactListener.h" #include "core/Mutex.hpp" diff --git a/src/native/physics/Layers.hpp b/src/native/physics/Layers.hpp new file mode 100644 index 00000000000..b4d72ccfdc2 --- /dev/null +++ b/src/native/physics/Layers.hpp @@ -0,0 +1,143 @@ +#pragma once + +#include "Jolt/Jolt.h" +#include "Jolt/Physics/Collision/BroadPhase/BroadPhaseLayer.h" +#include "Jolt/Physics/Collision/ObjectLayer.h" + +#include "core/Logger.hpp" + +namespace Thrive::Physics +{ + +/// \brief Overall layer configuration, note that in Jolt these are not meant to be gameplay categories and there +/// should only exist a couple of these +namespace Layers +{ +static constexpr JPH::ObjectLayer NON_MOVING = 0; +static constexpr JPH::ObjectLayer MOVING = 1; +static constexpr JPH::ObjectLayer DEBRIS = 2; +static constexpr JPH::ObjectLayer SENSOR = 3; +static constexpr JPH::ObjectLayer PROJECTILE = 4; +static constexpr JPH::ObjectLayer NUM_LAYERS = 8; +}; // namespace Layers + +/// \brief Configuration for which object layer types can collide with each other +class ObjectLayerPairFilter : public JPH::ObjectLayerPairFilter +{ +public: + [[nodiscard]] bool ShouldCollide(JPH::ObjectLayer object1, JPH::ObjectLayer object2) const override + { + switch (object1) + { + case Layers::NON_MOVING: + return object2 == Layers::MOVING || object2 == Layers::DEBRIS || object2 == Layers::PROJECTILE; + case Layers::MOVING: + return object2 == Layers::NON_MOVING || object2 == Layers::MOVING || object2 == Layers::SENSOR || + object2 == Layers::PROJECTILE; + case Layers::DEBRIS: + return object2 == Layers::NON_MOVING; + case Layers::SENSOR: + return object2 == Layers::MOVING; + case Layers::PROJECTILE: + return object2 == Layers::NON_MOVING || object2 == Layers::MOVING; + default: + LOG_ERROR("Invalid object layer checked for collision"); + return false; + } + } +}; + +/// \brief Broadphase layers (there needs to be a mapping from each object layer to a broadphase layer) +namespace BroadPhaseLayers +{ +static constexpr JPH::BroadPhaseLayer NON_MOVING(0); +static constexpr JPH::BroadPhaseLayer MOVING(1); +static constexpr JPH::BroadPhaseLayer DEBRIS(2); +static constexpr JPH::BroadPhaseLayer SENSOR(3); +static constexpr JPH::BroadPhaseLayer PROJECTILE(4); +static constexpr uint NUM_LAYERS(5); +}; // namespace BroadPhaseLayers + +/// \brief Broadphase layer handling, converts object layers to broadphase layers +class BroadPhaseLayerInterface final : public JPH::BroadPhaseLayerInterface +{ +public: + [[nodiscard]] uint GetNumBroadPhaseLayers() const override + { + return BroadPhaseLayers::NUM_LAYERS; + } + + [[nodiscard]] JPH::BroadPhaseLayer GetBroadPhaseLayer(JPH::ObjectLayer layer) const override + { + // This is where the layer mapping is defined + // Hopefully this gets optimized very well by the compiler (the samples used a map but that was probably worse + // approach than this for performance) + + switch (layer) + { + case Layers::NON_MOVING: + return BroadPhaseLayers::NON_MOVING; + case Layers::MOVING: + return BroadPhaseLayers::MOVING; + case Layers::DEBRIS: + return BroadPhaseLayers::DEBRIS; + case Layers::SENSOR: + return BroadPhaseLayers::SENSOR; + case Layers::PROJECTILE: + return BroadPhaseLayers::PROJECTILE; + case Layers::NUM_LAYERS: + default: + LOG_ERROR("Attempt to get broadphase layer that doesn't exist"); + std::abort(); + } + } + +#if defined(JPH_EXTERNAL_PROFILE) || defined(JPH_PROFILE_ENABLED) + const char* GetBroadPhaseLayerName(JPH::BroadPhaseLayer layer) const override + { + switch ((JPH::BroadPhaseLayer::Type)layer) + { + case (JPH::BroadPhaseLayer::Type)BroadPhaseLayers::NON_MOVING: + return "NON_MOVING"; + case (JPH::BroadPhaseLayer::Type)BroadPhaseLayers::MOVING: + return "MOVING"; + case (JPH::BroadPhaseLayer::Type)BroadPhaseLayers::DEBRIS: + return "DEBRIS"; + case (JPH::BroadPhaseLayer::Type)BroadPhaseLayers::SENSOR: + return "SENSOR"; + case (JPH::BroadPhaseLayer::Type)BroadPhaseLayers::PROJECTILE: + return "PROJECTILE"; + default: + return "INVALID"; + } + } +#endif // JPH_EXTERNAL_PROFILE || JPH_PROFILE_ENABLED +}; + +/// \brief Specifies which object layers can collide with which broadphase layers +class ObjectToBroadPhaseLayerFilter : public JPH::ObjectVsBroadPhaseLayerFilter +{ +public: + [[nodiscard]] bool ShouldCollide(JPH::ObjectLayer objectLayer, JPH::BroadPhaseLayer broadPhaseLayer) const override + { + switch (objectLayer) + { + case Layers::NON_MOVING: + return broadPhaseLayer == BroadPhaseLayers::MOVING || broadPhaseLayer == BroadPhaseLayers::PROJECTILE; + case Layers::MOVING: + return broadPhaseLayer == BroadPhaseLayers::NON_MOVING || broadPhaseLayer == BroadPhaseLayers::MOVING || + broadPhaseLayer == BroadPhaseLayers::SENSOR || broadPhaseLayer == BroadPhaseLayers::PROJECTILE; + case Layers::DEBRIS: + return broadPhaseLayer == BroadPhaseLayers::NON_MOVING; + case Layers::SENSOR: + return broadPhaseLayer == BroadPhaseLayers::MOVING; + case Layers::PROJECTILE: + return broadPhaseLayer == BroadPhaseLayers::NON_MOVING || broadPhaseLayer == BroadPhaseLayers::MOVING; + default: + LOG_ERROR("Invalid object layer checked for collision against broadphase layers"); + return false; + } + } +}; + +} // namespace Thrive::Physics diff --git a/src/native/physics/PhysicalWorld.cpp b/src/native/physics/PhysicalWorld.cpp index dd46fa116b9..6670214484e 100644 --- a/src/native/physics/PhysicalWorld.cpp +++ b/src/native/physics/PhysicalWorld.cpp @@ -1,9 +1,141 @@ // ------------------------------------ // #include "PhysicalWorld.hpp" +// TODO: switch to a custom thread pool +#include "Jolt/Core/JobSystemThreadPool.h" +#include "Jolt/Physics/Collision/CastResult.h" +#include "Jolt/Physics/Collision/RayCast.h" +#include "Jolt/Physics/PhysicsSettings.h" +#include "Jolt/Physics/PhysicsSystem.h" + +// #include "core/TaskSystem.hpp" + +#include "ContactListener.hpp" +// ------------------------------------ // using namespace Thrive::Physics; + +PhysicalWorld::PhysicalWorld() +{ +#ifdef USE_OBJECT_POOLS + tempAllocator = std::make_unique(32 * 1024 * 1024); +#else + tempAllocator = std::make_unique(); +#endif + + // Create job system + // TODO: configurable threads + int physicsThreads = 2; + jobSystem = + std::make_unique(JPH::cMaxPhysicsJobs, JPH::cMaxPhysicsBarriers, physicsThreads); + + InitPhysicsWorld(); +} + +PhysicalWorld::~PhysicalWorld() = default; + +// ------------------------------------ // +void PhysicalWorld::InitPhysicsWorld() +{ + physicsSystem = std::make_unique(); + physicsSystem->Init(maxBodies, maxBodyMutexes, maxBodyPairs, maxContactConstraints, broadPhaseLayer, + objectToBroadPhaseLayer, objectToObjectPair); + physicsSystem->SetPhysicsSettings(physicsSettings); + + physicsSystem->SetGravity(gravity); + + contactListener = std::make_unique(); + + // contactListener->SetNextListener(something); + physicsSystem->SetContactListener(contactListener.get()); +} + +// ------------------------------------ // +bool PhysicalWorld::Process(float delta) +{ + // TODO: update thread count if changed (we won't need this when we have the custom job system done) + + elapsedSinceUpdate += delta; + + const auto singlePhysicsFrame = 1 / physicsFrameRate; + + bool simulatedPhysics = false; + + while (elapsedSinceUpdate > singlePhysicsFrame) + { + elapsedSinceUpdate -= singlePhysicsFrame; + StepPhysics(*jobSystem, singlePhysicsFrame); + simulatedPhysics = true; + } + + if (!simulatedPhysics) + return false; + + // TODO: Trigger stuff from the collision detection + + return true; +} + // ------------------------------------ // -PhysicalWorld::PhysicalWorld() {} +std::optional> PhysicalWorld::CastRay(JPH::RVec3 start, JPH::Vec3 endOffset) +{ + // The Jolt samples app has some really nice alternative cast modes that could be added in the future + + JPH::RRayCast ray{start, endOffset}; + + // Cast ray + JPH::RayCastResult hit; + + // TODO: could ignore certain groups + bool hitSomething = physicsSystem->GetNarrowPhaseQuery().CastRay(ray, hit); + + if (!hitSomething) + return {}; + + const auto resultPosition = ray.GetPointOnRay(hit.mFraction); + const auto resultFraction = hit.mFraction; + const auto resultID = hit.mBodyID; + + // Could do something with the hit sub-shape + // hit.mSubShapeID2 + + // Or material + // JPH::BodyLockRead lock(physicsSystem->GetBodyLockInterface(), hit.mBodyID); + // if (lock.Succeeded()) + // { + // const JPH::Body& resultBody = lock.GetBody(); + // const JPH::PhysicsMaterial* material = resultBody.GetShape()->GetMaterial(hit.mSubShapeID2); + // } + // else + // { + // LOG_ERROR("Failed to get body read lock for ray cast"); + // } + + return std::tuple(resultFraction, resultPosition, resultID); +} -PhysicalWorld::~PhysicalWorld() {} // ------------------------------------ // +void PhysicalWorld::StepPhysics(JPH::JobSystemThreadPool& jobs, float time) +{ + // TODO: physics processing time tracking with a high resolution timer (should get the average time over the last + // second) + + const auto result = + physicsSystem->Update(time, collisionStepsPerUpdate, integrationSubSteps, tempAllocator.get(), &jobs); + + switch (result) + { + case JPH::EPhysicsUpdateError::None: + break; + case JPH::EPhysicsUpdateError::ManifoldCacheFull: + LOG_ERROR("Physics update error: manifold cache full"); + break; + case JPH::EPhysicsUpdateError::BodyPairCacheFull: + LOG_ERROR("Physics update error: body pair cache full"); + break; + case JPH::EPhysicsUpdateError::ContactConstraintsFull: + LOG_ERROR("Physics update error: contact constraints full"); + break; + default: + LOG_ERROR("Physics update error: unknown"); + } +} diff --git a/src/native/physics/PhysicalWorld.hpp b/src/native/physics/PhysicalWorld.hpp index 344996b7670..84bce447a50 100644 --- a/src/native/physics/PhysicalWorld.hpp +++ b/src/native/physics/PhysicalWorld.hpp @@ -1,15 +1,91 @@ #pragma once +#include +#include + +#include "Jolt/Physics/PhysicsSettings.h" + +#include "Include.h" +#include "core/ForwardDefinitions.hpp" + +#include "Layers.hpp" + +namespace JPH +{ +class PhysicsSystem; +class TempAllocator; +class JobSystemThreadPool; +class BodyID; +} // namespace JPH + namespace Thrive::Physics { +/// \brief Main handling class of the physics simulation class PhysicalWorld { public: PhysicalWorld(); ~PhysicalWorld(); + /// \brief Process physics + /// \returns True when enough time has passed and physics was stepped + bool Process(float delta); + + // TODO: physics debug drawing + + /// \brief Cast a ray from start point to endOffset (i.e. end = start + endOffset) + /// \returns When hit something a tuple of the fraction from start to end, the hit position, and the ID of the hit + // body + std::optional> CastRay(JPH::RVec3 start, JPH::Vec3 endOffset); + +private: + /// \brief Creates the physics system + void InitPhysicsWorld(); + + void StepPhysics(JPH::JobSystemThreadPool& jobs, float time); + private: + float elapsedSinceUpdate = 0; + + // TODO: rename all the following fields + + /// \brief The main part, the physics system that simulates this world + std::unique_ptr physicsSystem; + + // Note the following variables are in a specific order for destruction + + BroadPhaseLayerInterface broadPhaseLayer; + ObjectToBroadPhaseLayerFilter objectToBroadPhaseLayer; + ObjectLayerPairFilter objectToObjectPair; + + std::unique_ptr contactListener; + + // TODO: switch to this custom one + // std::unique_ptr jobSystem; + std::unique_ptr jobSystem; + + std::unique_ptr tempAllocator; + + // Simulation configuration + float physicsFrameRate = 60; + int collisionStepsPerUpdate = 1; + int integrationSubSteps = 1; + + JPH::PhysicsSettings physicsSettings; + + // TODO: update this when changed + JPH::Vec3 gravity = JPH::Vec3(0, -9.81f, 0); + + // Settings that only apply when creating a new physics system + + uint maxBodies = 10240; + + /// \details Jolt documentation says that 0 means automatic + uint maxBodyMutexes = 0; + + uint maxBodyPairs = 65536; + uint maxContactConstraints = 20480; }; } // namespace Thrive::Physics diff --git a/src/native/physics/ShapeCreator.cpp b/src/native/physics/ShapeCreator.cpp new file mode 100644 index 00000000000..36b759871e7 --- /dev/null +++ b/src/native/physics/ShapeCreator.cpp @@ -0,0 +1,57 @@ +// ------------------------------------ // +#include "ShapeCreator.hpp" + +#include "Jolt/Math/Trigonometry.h" +#include "Jolt/Physics/Collision/Shape/ConvexHullShape.h" +#include "Jolt/Physics/Collision/Shape/MeshShape.h" +#include "Jolt/Physics/Collision/Shape/MutableCompoundShape.h" +#include "Jolt/Physics/Collision/Shape/StaticCompoundShape.h" +// ------------------------------------ // +using namespace Thrive::Physics; + +JPH::RefConst ShapeCreator::CreateConvex(const JPH::Array& points, + float convexRadius /*= 0.01f*/, const JPH::PhysicsMaterial* material /*= nullptr*/) +{ + return JPH::ConvexHullShapeSettings(points, convexRadius, material).Create().Get(); +} + +JPH::RefConst ShapeCreator::CreateStaticCompound( + const std::vector, JPH::Vec3, JPH::Quat, uint32_t>>& subShapes) +{ + JPH::StaticCompoundShapeSettings settings; + + for (const auto& shape : subShapes) + { + settings.AddShape(std::get<1>(shape), std::get<2>(shape), std::get<0>(shape), std::get<3>(shape)); + } + + return settings.Create().Get(); +} + +JPH::RefConst ShapeCreator::CreateMutableCompound( + const std::vector, JPH::Vec3, JPH::Quat, uint32_t>>& subShapes) +{ + JPH::MutableCompoundShapeSettings settings; + + for (const auto& shape : subShapes) + { + settings.AddShape(std::get<1>(shape), std::get<2>(shape), std::get<0>(shape), std::get<3>(shape)); + } + + return settings.Create().Get(); +} + +JPH::RefConst ShapeCreator::CreateMesh( + JPH::Array&& vertices, JPH::Array&& triangles) +{ + // Create torus + JPH::MeshShapeSettings mesh; + + // TODO: materials support (each triangle can have a different one) + // mesh.mMaterials + + mesh.mTriangleVertices = std::move(vertices); + mesh.mIndexedTriangles = std::move(triangles); + + return mesh.Create().Get(); +} diff --git a/src/native/physics/ShapeCreator.hpp b/src/native/physics/ShapeCreator.hpp new file mode 100644 index 00000000000..0f37cc4ffc2 --- /dev/null +++ b/src/native/physics/ShapeCreator.hpp @@ -0,0 +1,41 @@ +#pragma once + +#include "SimpleShapes.hpp" + +namespace JPH +{ +class IndexedTriangle; +} // namespace JPH + +namespace Thrive::Physics +{ + +/// \brief More advanced shape creation helper class than SimpleShapes +class ShapeCreator +{ +public: + ShapeCreator() = delete; + + /// \brief Create a convex shape from a list of points + /// \param convexRadius Used convex radius for this shape, should be lower than the default value used for other + /// shapes + static JPH::RefConst CreateConvex(const JPH::Array& points, float convexRadius = 0.01f, + const JPH::PhysicsMaterial* material = nullptr); + + /// \brief Creates a shape composed of multiple other shapes that cannot change after creation + /// \todo Figure out how to use physics materials here + static JPH::RefConst CreateStaticCompound( + const std::vector, JPH::Vec3, JPH::Quat, uint32_t>>& subShapes); + + /// \brief Variant of the compound shape that is allowed to be modified (but has lower performance than static) + static JPH::RefConst CreateMutableCompound( + const std::vector, JPH::Vec3, JPH::Quat, uint32_t>>& subShapes); + + /// \brief Creates a mesh collision (note that the performance is worse and this can't collide with everything even + /// when movable) + /// \todo Materials support, each triangle can have its own so this is a bit complicated to setup + static JPH::RefConst CreateMesh( + JPH::Array&& vertices, JPH::Array&& triangles); +}; + +} // namespace Thrive::Physics diff --git a/src/native/physics/SimpleShapes.cpp b/src/native/physics/SimpleShapes.cpp new file mode 100644 index 00000000000..8ce51d9a979 --- /dev/null +++ b/src/native/physics/SimpleShapes.cpp @@ -0,0 +1,46 @@ +// ------------------------------------ // +#include "SimpleShapes.hpp" + +#include "Jolt/Physics/Collision/Shape/BoxShape.h" +#include "Jolt/Physics/Collision/Shape/CapsuleShape.h" +#include "Jolt/Physics/Collision/Shape/CylinderShape.h" +#include "Jolt/Physics/Collision/Shape/ScaledShape.h" +#include "Jolt/Physics/Collision/Shape/Shape.h" +#include "Jolt/Physics/Collision/Shape/SphereShape.h" +// ------------------------------------ // +using namespace Thrive::Physics; + +JPH::RefConst SimpleShapes::CreateSphere(float radius, const JPH::PhysicsMaterial* material /*= nullptr*/) +{ + return new JPH::SphereShape(radius, material); +} + +JPH::RefConst SimpleShapes::CreateBox( + float halfSideLength, const JPH::PhysicsMaterial* material /*= nullptr*/) +{ + return CreateBox(JPH::Vec3(halfSideLength, halfSideLength, halfSideLength), material); +} + +JPH::RefConst SimpleShapes::CreateBox( + JPH::Vec3 halfExtends, const JPH::PhysicsMaterial* material /*= nullptr*/) +{ + return new JPH::BoxShape(halfExtends, JPH::cDefaultConvexRadius, material); +} + +JPH::RefConst SimpleShapes::CreateCylinder( + float halfHeight, float radius, const JPH::PhysicsMaterial* material /*= nullptr*/) +{ + return new JPH::CylinderShape(halfHeight, radius, JPH::cDefaultConvexRadius, material); +} + +JPH::RefConst SimpleShapes::CreateCapsule( + float halfHeight, float radius, const JPH::PhysicsMaterial* material /*= nullptr*/) +{ + return new JPH::CapsuleShape(halfHeight, radius, material); +} + +// ------------------------------------ // +JPH::RefConst SimpleShapes::Scale(const JPH::RefConst& shape, float scale) +{ + return new JPH::ScaledShape(shape, JPH::Vec3(scale, scale, scale)); +} diff --git a/src/native/physics/SimpleShapes.hpp b/src/native/physics/SimpleShapes.hpp new file mode 100644 index 00000000000..7e07159ace0 --- /dev/null +++ b/src/native/physics/SimpleShapes.hpp @@ -0,0 +1,36 @@ +#pragma once + +#include "Jolt/Core/Reference.h" + +#include "Include.h" + +namespace JPH +{ +class Shape; +class PhysicsMaterial; +} // namespace JPH + +namespace Thrive::Physics +{ + +/// \brief Helpers for creating simple shapes +class SimpleShapes +{ +public: + SimpleShapes() = delete; + + static JPH::RefConst CreateSphere(float radius, const JPH::PhysicsMaterial* material = nullptr); + + static JPH::RefConst CreateBox(float halfSideLength, const JPH::PhysicsMaterial* material = nullptr); + static JPH::RefConst CreateBox(JPH::Vec3 halfExtends, const JPH::PhysicsMaterial* material = nullptr); + + static JPH::RefConst CreateCylinder( + float halfHeight, float radius, const JPH::PhysicsMaterial* material = nullptr); + + static JPH::RefConst CreateCapsule( + float halfHeight, float radius, const JPH::PhysicsMaterial* material = nullptr); + + static JPH::RefConst Scale(const JPH::RefConst& shape, float scale); +}; + +} // namespace Thrive::Physics diff --git a/third_party/CMakeLists.txt b/third_party/CMakeLists.txt index 2f5d8eda8f4..77cad0309c8 100644 --- a/third_party/CMakeLists.txt +++ b/third_party/CMakeLists.txt @@ -11,4 +11,8 @@ set(USE_AVX2 ON) # This is way too unsupported to enable in a general build set(USE_AVX512 OFF) +# Need to force Jolt to be position independent to allow linking into shared +# libraries +set(CMAKE_POSITION_INDEPENDENT_CODE ON) + add_subdirectory(JoltPhysics/Build) From b9a8fd648231a84007fa87fb5228a41f08bca574 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henri=20Hyyryl=C3=A4inen?= Date: Fri, 2 Jun 2023 16:12:38 +0300 Subject: [PATCH 04/79] Added needed boost libs just for intrusive_ptr --- third_party/CMakeLists.txt | 5 +- third_party/boost/CMakeLists.txt | 30 + third_party/boost/LICENSE_1_0.txt | 23 + third_party/boost/libs/assert/CMakeLists.txt | 35 + third_party/boost/libs/assert/README.md | 13 + .../libs/assert/include/boost/assert.hpp | 85 + .../include/boost/assert/source_location.hpp | 189 + .../assert/include/boost/current_function.hpp | 75 + third_party/boost/libs/config/CMakeLists.txt | 14 + third_party/boost/libs/config/README.md | 43 + .../libs/config/include/boost/config.hpp | 67 + .../boost/config/abi/borland_prefix.hpp | 27 + .../boost/config/abi/borland_suffix.hpp | 12 + .../include/boost/config/abi/msvc_prefix.hpp | 22 + .../include/boost/config/abi/msvc_suffix.hpp | 8 + .../include/boost/config/abi_prefix.hpp | 25 + .../include/boost/config/abi_suffix.hpp | 25 + .../include/boost/config/assert_cxx03.hpp | 211 + .../include/boost/config/assert_cxx11.hpp | 209 + .../include/boost/config/assert_cxx14.hpp | 47 + .../include/boost/config/assert_cxx17.hpp | 62 + .../include/boost/config/assert_cxx20.hpp | 59 + .../include/boost/config/assert_cxx98.hpp | 23 + .../config/include/boost/config/auto_link.hpp | 525 ++ .../include/boost/config/compiler/borland.hpp | 339 ++ .../include/boost/config/compiler/clang.hpp | 366 ++ .../boost/config/compiler/clang_version.hpp | 83 + .../boost/config/compiler/codegear.hpp | 385 ++ .../include/boost/config/compiler/comeau.hpp | 59 + .../boost/config/compiler/common_edg.hpp | 183 + .../boost/config/compiler/compaq_cxx.hpp | 19 + .../include/boost/config/compiler/cray.hpp | 446 ++ .../include/boost/config/compiler/diab.hpp | 26 + .../boost/config/compiler/digitalmars.hpp | 143 + .../include/boost/config/compiler/gcc.hpp | 383 ++ .../include/boost/config/compiler/gcc_xml.hpp | 114 + .../boost/config/compiler/greenhills.hpp | 28 + .../include/boost/config/compiler/hp_acc.hpp | 149 + .../include/boost/config/compiler/intel.hpp | 577 +++ .../include/boost/config/compiler/kai.hpp | 33 + .../boost/config/compiler/metrowerks.hpp | 198 + .../include/boost/config/compiler/mpw.hpp | 140 + .../include/boost/config/compiler/nvcc.hpp | 61 + .../boost/config/compiler/pathscale.hpp | 138 + .../include/boost/config/compiler/pgi.hpp | 23 + .../boost/config/compiler/sgi_mipspro.hpp | 29 + .../boost/config/compiler/sunpro_cc.hpp | 222 + .../include/boost/config/compiler/vacpp.hpp | 186 + .../include/boost/config/compiler/visualc.hpp | 391 ++ .../include/boost/config/compiler/xlcpp.hpp | 299 ++ .../boost/config/compiler/xlcpp_zos.hpp | 173 + .../boost/config/detail/cxx_composite.hpp | 203 + .../boost/config/detail/posix_features.hpp | 95 + .../config/detail/select_compiler_config.hpp | 157 + .../config/detail/select_platform_config.hpp | 147 + .../config/detail/select_stdlib_config.hpp | 121 + .../include/boost/config/detail/suffix.hpp | 1294 +++++ .../boost/config/header_deprecated.hpp | 26 + .../include/boost/config/helper_macros.hpp | 37 + .../include/boost/config/no_tr1/cmath.hpp | 28 + .../include/boost/config/no_tr1/complex.hpp | 28 + .../boost/config/no_tr1/functional.hpp | 28 + .../include/boost/config/no_tr1/memory.hpp | 28 + .../include/boost/config/no_tr1/utility.hpp | 28 + .../include/boost/config/platform/aix.hpp | 33 + .../include/boost/config/platform/amigaos.hpp | 15 + .../include/boost/config/platform/beos.hpp | 26 + .../include/boost/config/platform/bsd.hpp | 83 + .../boost/config/platform/cloudabi.hpp | 18 + .../include/boost/config/platform/cray.hpp | 18 + .../include/boost/config/platform/cygwin.hpp | 71 + .../include/boost/config/platform/haiku.hpp | 31 + .../include/boost/config/platform/hpux.hpp | 87 + .../include/boost/config/platform/irix.hpp | 31 + .../include/boost/config/platform/linux.hpp | 106 + .../include/boost/config/platform/macos.hpp | 87 + .../include/boost/config/platform/qnxnto.hpp | 31 + .../include/boost/config/platform/solaris.hpp | 31 + .../include/boost/config/platform/symbian.hpp | 97 + .../include/boost/config/platform/vms.hpp | 25 + .../include/boost/config/platform/vxworks.hpp | 422 ++ .../include/boost/config/platform/wasm.hpp | 23 + .../include/boost/config/platform/win32.hpp | 90 + .../include/boost/config/platform/zos.hpp | 32 + .../include/boost/config/pragma_message.hpp | 31 + .../include/boost/config/requires_threads.hpp | 92 + .../boost/config/stdlib/dinkumware.hpp | 324 ++ .../include/boost/config/stdlib/libcomo.hpp | 93 + .../include/boost/config/stdlib/libcpp.hpp | 180 + .../boost/config/stdlib/libstdcpp3.hpp | 482 ++ .../include/boost/config/stdlib/modena.hpp | 79 + .../include/boost/config/stdlib/msl.hpp | 98 + .../include/boost/config/stdlib/roguewave.hpp | 208 + .../include/boost/config/stdlib/sgi.hpp | 168 + .../include/boost/config/stdlib/stlport.hpp | 258 + .../include/boost/config/stdlib/vacpp.hpp | 74 + .../include/boost/config/stdlib/xlcpp_zos.hpp | 61 + .../libs/config/include/boost/config/user.hpp | 133 + .../include/boost/config/warning_disable.hpp | 47 + .../include/boost/config/workaround.hpp | 305 ++ .../libs/config/include/boost/cstdint.hpp | 556 +++ .../config/include/boost/cxx11_char_types.hpp | 70 + .../include/boost/detail/workaround.hpp | 10 + .../libs/config/include/boost/limits.hpp | 146 + .../libs/config/include/boost/version.hpp | 32 + .../boost/libs/container_hash/CMakeLists.txt | 27 + .../boost/libs/container_hash/README.md | 20 + .../boost/container_hash/detail/hash_mix.hpp | 113 + .../container_hash/detail/hash_range.hpp | 410 ++ .../container_hash/detail/hash_tuple_like.hpp | 156 + .../boost/container_hash/detail/limits.hpp | 19 + .../boost/container_hash/detail/mulx.hpp | 79 + .../container_hash/detail/requires_cxx11.hpp | 22 + .../boost/container_hash/extensions.hpp | 10 + .../include/boost/container_hash/hash.hpp | 677 +++ .../include/boost/container_hash/hash_fwd.hpp | 37 + .../container_hash/is_contiguous_range.hpp | 92 + .../container_hash/is_described_class.hpp | 38 + .../include/boost/container_hash/is_range.hpp | 74 + .../boost/container_hash/is_tuple_like.hpp | 42 + .../container_hash/is_unordered_range.hpp | 39 + .../include/boost/functional/hash.hpp | 6 + .../boost/functional/hash/extensions.hpp | 6 + .../include/boost/functional/hash/hash.hpp | 6 + .../boost/functional/hash/hash_fwd.hpp | 6 + .../include/boost/functional/hash_fwd.hpp | 6 + .../boost/libs/describe/CMakeLists.txt | 25 + third_party/boost/libs/describe/README.md | 20 + .../libs/describe/include/boost/describe.hpp | 21 + .../describe/include/boost/describe/bases.hpp | 50 + .../describe/include/boost/describe/class.hpp | 76 + .../boost/describe/descriptor_by_name.hpp | 41 + .../boost/describe/descriptor_by_pointer.hpp | 48 + .../include/boost/describe/detail/bases.hpp | 54 + .../detail/compute_base_modifiers.hpp | 73 + .../include/boost/describe/detail/config.hpp | 40 + .../boost/describe/detail/cx_streq.hpp | 30 + .../include/boost/describe/detail/list.hpp | 27 + .../include/boost/describe/detail/members.hpp | 82 + .../boost/describe/detail/pp_for_each.hpp | 122 + .../boost/describe/detail/pp_utilities.hpp | 92 + .../include/boost/describe/detail/void_t.hpp | 32 + .../describe/include/boost/describe/enum.hpp | 111 + .../boost/describe/enum_from_string.hpp | 53 + .../include/boost/describe/enum_to_string.hpp | 48 + .../include/boost/describe/enumerators.hpp | 46 + .../include/boost/describe/members.hpp | 159 + .../boost/describe/modifier_description.hpp | 30 + .../include/boost/describe/modifiers.hpp | 33 + .../include/boost/describe/operators.hpp | 179 + .../boost/libs/intrusive/CMakeLists.txt | 22 + third_party/boost/libs/intrusive/README.md | 40 + .../include/boost/intrusive/any_hook.hpp | 338 ++ .../include/boost/intrusive/avl_set.hpp | 1073 ++++ .../include/boost/intrusive/avl_set_hook.hpp | 293 ++ .../include/boost/intrusive/avltree.hpp | 588 +++ .../boost/intrusive/avltree_algorithms.hpp | 727 +++ .../include/boost/intrusive/bs_set.hpp | 1069 ++++ .../include/boost/intrusive/bs_set_hook.hpp | 288 ++ .../include/boost/intrusive/bstree.hpp | 2238 +++++++++ .../boost/intrusive/bstree_algorithms.hpp | 2103 ++++++++ .../intrusive/circular_list_algorithms.hpp | 476 ++ .../intrusive/circular_slist_algorithms.hpp | 475 ++ .../intrusive/derivation_value_traits.hpp | 77 + .../boost/intrusive/detail/algo_type.hpp | 53 + .../boost/intrusive/detail/algorithm.hpp | 90 + .../detail/any_node_and_algorithms.hpp | 297 ++ .../intrusive/detail/array_initializer.hpp | 97 + .../include/boost/intrusive/detail/assert.hpp | 45 + .../boost/intrusive/detail/avltree_node.hpp | 193 + .../detail/bstree_algorithms_base.hpp | 182 + .../detail/common_slist_algorithms.hpp | 267 + .../boost/intrusive/detail/config_begin.hpp | 44 + .../boost/intrusive/detail/config_end.hpp | 15 + .../detail/default_header_holder.hpp | 70 + .../intrusive/detail/ebo_functor_holder.hpp | 292 ++ .../intrusive/detail/empty_node_checker.hpp | 44 + .../boost/intrusive/detail/equal_to_value.hpp | 50 + .../intrusive/detail/exception_disposer.hpp | 59 + .../intrusive/detail/function_detector.hpp | 92 + .../boost/intrusive/detail/generic_hook.hpp | 223 + .../intrusive/detail/get_value_traits.hpp | 222 + .../has_member_function_callable_with.hpp | 366 ++ .../boost/intrusive/detail/hash_combine.hpp | 92 + .../boost/intrusive/detail/hashtable_node.hpp | 375 ++ .../boost/intrusive/detail/hook_traits.hpp | 196 + .../boost/intrusive/detail/iiterator.hpp | 122 + .../detail/is_stateful_value_traits.hpp | 81 + .../boost/intrusive/detail/iterator.hpp | 308 ++ .../intrusive/detail/key_nodeptr_comp.hpp | 125 + .../boost/intrusive/detail/list_iterator.hpp | 146 + .../boost/intrusive/detail/list_node.hpp | 72 + .../include/boost/intrusive/detail/math.hpp | 242 + .../detail/minimal_less_equal_header.hpp | 30 + .../intrusive/detail/minimal_pair_header.hpp | 30 + .../include/boost/intrusive/detail/mpl.hpp | 217 + .../intrusive/detail/node_cloner_disposer.hpp | 105 + .../boost/intrusive/detail/node_holder.hpp | 35 + .../boost/intrusive/detail/node_to_value.hpp | 130 + .../intrusive/detail/parent_from_member.hpp | 121 + .../boost/intrusive/detail/rbtree_node.hpp | 205 + .../intrusive/detail/reverse_iterator.hpp | 28 + .../intrusive/detail/simple_disposers.hpp | 52 + .../boost/intrusive/detail/size_holder.hpp | 91 + .../boost/intrusive/detail/slist_iterator.hpp | 145 + .../boost/intrusive/detail/slist_node.hpp | 64 + .../boost/intrusive/detail/std_fwd.hpp | 43 + .../intrusive/detail/transform_iterator.hpp | 172 + .../boost/intrusive/detail/tree_iterator.hpp | 184 + .../boost/intrusive/detail/tree_node.hpp | 80 + .../intrusive/detail/tree_value_compare.hpp | 186 + .../include/boost/intrusive/detail/twin.hpp | 49 + .../include/boost/intrusive/detail/uncast.hpp | 55 + .../boost/intrusive/detail/value_functors.hpp | 52 + .../boost/intrusive/detail/workaround.hpp | 84 + .../include/boost/intrusive/hashtable.hpp | 4363 +++++++++++++++++ .../include/boost/intrusive/intrusive_fwd.hpp | 768 +++ .../intrusive/linear_slist_algorithms.hpp | 422 ++ .../include/boost/intrusive/link_mode.hpp | 63 + .../include/boost/intrusive/list.hpp | 1519 ++++++ .../include/boost/intrusive/list_hook.hpp | 289 ++ .../boost/intrusive/member_value_traits.hpp | 85 + .../include/boost/intrusive/options.hpp | 278 ++ .../include/boost/intrusive/pack_options.hpp | 384 ++ .../boost/intrusive/parent_from_member.hpp | 49 + .../boost/intrusive/pointer_plus_bits.hpp | 112 + .../boost/intrusive/pointer_rebind.hpp | 188 + .../boost/intrusive/pointer_traits.hpp | 326 ++ .../boost/intrusive/priority_compare.hpp | 89 + .../include/boost/intrusive/rbtree.hpp | 591 +++ .../boost/intrusive/rbtree_algorithms.hpp | 622 +++ .../intrusive/include/boost/intrusive/set.hpp | 1073 ++++ .../include/boost/intrusive/set_hook.hpp | 296 ++ .../include/boost/intrusive/sg_set.hpp | 1094 +++++ .../include/boost/intrusive/sgtree.hpp | 1073 ++++ .../boost/intrusive/sgtree_algorithms.hpp | 420 ++ .../include/boost/intrusive/slist.hpp | 2247 +++++++++ .../include/boost/intrusive/slist_hook.hpp | 298 ++ .../include/boost/intrusive/splay_set.hpp | 1110 +++++ .../include/boost/intrusive/splaytree.hpp | 666 +++ .../boost/intrusive/splaytree_algorithms.hpp | 756 +++ .../include/boost/intrusive/treap.hpp | 1371 ++++++ .../boost/intrusive/treap_algorithms.hpp | 700 +++ .../include/boost/intrusive/treap_set.hpp | 1113 +++++ .../boost/intrusive/trivial_value_traits.hpp | 61 + .../include/boost/intrusive/unordered_set.hpp | 1001 ++++ .../boost/intrusive/unordered_set_hook.hpp | 459 ++ third_party/boost/libs/move/CMakeLists.txt | 25 + third_party/boost/libs/move/LICENSE | 23 + third_party/boost/libs/move/README.md | 35 + .../move/include/boost/move/adl_move_swap.hpp | 272 + .../boost/move/algo/adaptive_merge.hpp | 364 ++ .../include/boost/move/algo/adaptive_sort.hpp | 654 +++ .../move/algo/detail/adaptive_sort_merge.hpp | 1537 ++++++ .../boost/move/algo/detail/basic_op.hpp | 122 + .../boost/move/algo/detail/heap_sort.hpp | 122 + .../boost/move/algo/detail/insertion_sort.hpp | 137 + .../boost/move/algo/detail/is_sorted.hpp | 55 + .../include/boost/move/algo/detail/merge.hpp | 896 ++++ .../boost/move/algo/detail/merge_sort.hpp | 216 + .../boost/move/algo/detail/pdqsort.hpp | 345 ++ .../include/boost/move/algo/detail/search.hpp | 79 + .../boost/move/algo/detail/set_difference.hpp | 213 + .../move/include/boost/move/algo/move.hpp | 159 + .../include/boost/move/algo/predicate.hpp | 101 + .../move/include/boost/move/algo/unique.hpp | 55 + .../move/include/boost/move/algorithm.hpp | 166 + .../libs/move/include/boost/move/core.hpp | 515 ++ .../include/boost/move/default_delete.hpp | 243 + .../include/boost/move/detail/addressof.hpp | 61 + .../boost/move/detail/config_begin.hpp | 22 + .../include/boost/move/detail/config_end.hpp | 12 + .../include/boost/move/detail/destruct_n.hpp | 66 + .../include/boost/move/detail/force_ptr.hpp | 36 + .../include/boost/move/detail/fwd_macros.hpp | 893 ++++ .../move/detail/iterator_to_raw_pointer.hpp | 59 + .../boost/move/detail/iterator_traits.hpp | 177 + .../include/boost/move/detail/meta_utils.hpp | 563 +++ .../boost/move/detail/meta_utils_core.hpp | 137 + .../boost/move/detail/move_helpers.hpp | 256 + .../include/boost/move/detail/nsec_clock.hpp | 268 + .../boost/move/detail/placement_new.hpp | 30 + .../boost/move/detail/pointer_element.hpp | 168 + .../boost/move/detail/reverse_iterator.hpp | 178 + .../boost/move/detail/std_ns_begin.hpp | 34 + .../include/boost/move/detail/std_ns_end.hpp | 16 + .../boost/move/detail/to_raw_pointer.hpp | 45 + .../include/boost/move/detail/type_traits.hpp | 1299 +++++ .../move/detail/unique_ptr_meta_utils.hpp | 565 +++ .../include/boost/move/detail/workaround.hpp | 148 + .../libs/move/include/boost/move/iterator.hpp | 311 ++ .../move/include/boost/move/make_unique.hpp | 248 + .../libs/move/include/boost/move/move.hpp | 35 + .../libs/move/include/boost/move/traits.hpp | 77 + .../move/include/boost/move/unique_ptr.hpp | 870 ++++ .../libs/move/include/boost/move/utility.hpp | 150 + .../move/include/boost/move/utility_core.hpp | 323 ++ third_party/boost/libs/mp11/CMakeLists.txt | 66 + third_party/boost/libs/mp11/README.md | 23 + .../boost/libs/mp11/include/boost/mp11.hpp | 22 + .../mp11/include/boost/mp11/algorithm.hpp | 1306 +++++ .../libs/mp11/include/boost/mp11/bind.hpp | 111 + .../mp11/include/boost/mp11/detail/config.hpp | 138 + .../include/boost/mp11/detail/mp_append.hpp | 185 + .../include/boost/mp11/detail/mp_copy_if.hpp | 48 + .../include/boost/mp11/detail/mp_count.hpp | 147 + .../include/boost/mp11/detail/mp_fold.hpp | 62 + .../include/boost/mp11/detail/mp_front.hpp | 38 + .../include/boost/mp11/detail/mp_is_list.hpp | 39 + .../include/boost/mp11/detail/mp_list.hpp | 24 + .../include/boost/mp11/detail/mp_map_find.hpp | 87 + .../boost/mp11/detail/mp_min_element.hpp | 51 + .../include/boost/mp11/detail/mp_plus.hpp | 81 + .../boost/mp11/detail/mp_remove_if.hpp | 48 + .../include/boost/mp11/detail/mp_rename.hpp | 41 + .../include/boost/mp11/detail/mp_void.hpp | 32 + .../boost/mp11/detail/mp_with_index.hpp | 385 ++ .../include/boost/mp11/detail/mpl_common.hpp | 160 + .../libs/mp11/include/boost/mp11/function.hpp | 222 + .../include/boost/mp11/integer_sequence.hpp | 112 + .../libs/mp11/include/boost/mp11/integral.hpp | 41 + .../libs/mp11/include/boost/mp11/list.hpp | 304 ++ .../libs/mp11/include/boost/mp11/map.hpp | 119 + .../libs/mp11/include/boost/mp11/mpl.hpp | 14 + .../libs/mp11/include/boost/mp11/mpl_list.hpp | 28 + .../mp11/include/boost/mp11/mpl_tuple.hpp | 29 + .../libs/mp11/include/boost/mp11/set.hpp | 188 + .../libs/mp11/include/boost/mp11/tuple.hpp | 183 + .../libs/mp11/include/boost/mp11/utility.hpp | 263 + .../libs/mp11/include/boost/mp11/version.hpp | 16 + .../boost/libs/static_assert/CMakeLists.txt | 28 + .../boost/libs/static_assert/README.md | 36 + .../include/boost/static_assert.hpp | 181 + .../boost/libs/type_traits/CMakeLists.txt | 20 + third_party/boost/libs/type_traits/README.md | 47 + .../include/boost/aligned_storage.hpp | 18 + .../type_traits/include/boost/type_traits.hpp | 164 + .../include/boost/type_traits/add_const.hpp | 52 + .../include/boost/type_traits/add_cv.hpp | 47 + .../type_traits/add_lvalue_reference.hpp | 33 + .../include/boost/type_traits/add_pointer.hpp | 67 + .../boost/type_traits/add_reference.hpp | 66 + .../type_traits/add_rvalue_reference.hpp | 70 + .../boost/type_traits/add_volatile.hpp | 46 + .../boost/type_traits/aligned_storage.hpp | 138 + .../boost/type_traits/alignment_of.hpp | 119 + .../boost/type_traits/alignment_traits.hpp | 15 + .../boost/type_traits/arithmetic_traits.hpp | 20 + .../boost/type_traits/array_traits.hpp | 15 + .../type_traits/broken_compiler_spec.hpp | 21 + .../include/boost/type_traits/common_type.hpp | 152 + .../boost/type_traits/composite_traits.hpp | 29 + .../include/boost/type_traits/conditional.hpp | 28 + .../include/boost/type_traits/config.hpp | 21 + .../include/boost/type_traits/conjunction.hpp | 40 + .../boost/type_traits/conversion_traits.hpp | 17 + .../include/boost/type_traits/copy_cv.hpp | 40 + .../include/boost/type_traits/copy_cv_ref.hpp | 31 + .../boost/type_traits/copy_reference.hpp | 35 + .../include/boost/type_traits/cv_traits.hpp | 24 + .../include/boost/type_traits/decay.hpp | 49 + .../include/boost/type_traits/declval.hpp | 44 + .../type_traits/detail/bool_trait_def.hpp | 179 + .../type_traits/detail/bool_trait_undef.hpp | 28 + .../detail/common_arithmetic_type.hpp | 220 + .../type_traits/detail/common_type_impl.hpp | 107 + .../detail/composite_member_pointer_type.hpp | 113 + .../detail/composite_pointer_type.hpp | 153 + .../boost/type_traits/detail/config.hpp | 116 + .../boost/type_traits/detail/detector.hpp | 37 + .../detail/has_binary_operator.hpp | 279 ++ .../detail/has_postfix_operator.hpp | 250 + .../detail/has_prefix_operator.hpp | 280 ++ .../boost/type_traits/detail/ice_and.hpp | 42 + .../boost/type_traits/detail/ice_eq.hpp | 43 + .../boost/type_traits/detail/ice_not.hpp | 38 + .../boost/type_traits/detail/ice_or.hpp | 41 + .../type_traits/detail/is_function_cxx_03.hpp | 108 + .../type_traits/detail/is_function_cxx_11.hpp | 676 +++ .../detail/is_function_msvc10_fix.hpp | 30 + .../detail/is_function_ptr_helper.hpp | 444 ++ .../detail/is_function_ptr_tester.hpp | 609 +++ .../type_traits/detail/is_likely_lambda.hpp | 95 + .../detail/is_mem_fun_pointer_impl.hpp | 1328 +++++ .../detail/is_mem_fun_pointer_tester.hpp | 1603 ++++++ .../is_member_function_pointer_cxx_03.hpp | 117 + .../is_member_function_pointer_cxx_11.hpp | 697 +++ .../detail/is_rvalue_reference_msvc10_fix.hpp | 43 + .../detail/is_swappable_cxx_11.hpp | 70 + .../boost/type_traits/detail/mp_defer.hpp | 56 + .../detail/template_arity_spec.hpp | 16 + .../boost/type_traits/detail/yes_no_type.hpp | 26 + .../include/boost/type_traits/detected.hpp | 24 + .../include/boost/type_traits/detected_or.hpp | 25 + .../include/boost/type_traits/disjunction.hpp | 40 + .../include/boost/type_traits/enable_if.hpp | 37 + .../include/boost/type_traits/extent.hpp | 139 + .../type_traits/floating_point_promotion.hpp | 28 + .../boost/type_traits/function_traits.hpp | 174 + .../include/boost/type_traits/has_bit_and.hpp | 49 + .../boost/type_traits/has_bit_and_assign.hpp | 55 + .../include/boost/type_traits/has_bit_or.hpp | 49 + .../boost/type_traits/has_bit_or_assign.hpp | 55 + .../include/boost/type_traits/has_bit_xor.hpp | 49 + .../boost/type_traits/has_bit_xor_assign.hpp | 55 + .../boost/type_traits/has_complement.hpp | 32 + .../boost/type_traits/has_dereference.hpp | 375 ++ .../include/boost/type_traits/has_divides.hpp | 40 + .../boost/type_traits/has_divides_assign.hpp | 47 + .../boost/type_traits/has_equal_to.hpp | 52 + .../include/boost/type_traits/has_greater.hpp | 52 + .../boost/type_traits/has_greater_equal.hpp | 52 + .../boost/type_traits/has_left_shift.hpp | 49 + .../type_traits/has_left_shift_assign.hpp | 55 + .../include/boost/type_traits/has_less.hpp | 52 + .../boost/type_traits/has_less_equal.hpp | 52 + .../boost/type_traits/has_logical_and.hpp | 40 + .../boost/type_traits/has_logical_not.hpp | 32 + .../boost/type_traits/has_logical_or.hpp | 40 + .../include/boost/type_traits/has_minus.hpp | 158 + .../boost/type_traits/has_minus_assign.hpp | 163 + .../include/boost/type_traits/has_modulus.hpp | 49 + .../boost/type_traits/has_modulus_assign.hpp | 55 + .../boost/type_traits/has_multiplies.hpp | 40 + .../type_traits/has_multiplies_assign.hpp | 47 + .../include/boost/type_traits/has_negate.hpp | 25 + .../boost/type_traits/has_new_operator.hpp | 147 + .../boost/type_traits/has_not_equal_to.hpp | 52 + .../boost/type_traits/has_nothrow_assign.hpp | 84 + .../type_traits/has_nothrow_constructor.hpp | 73 + .../boost/type_traits/has_nothrow_copy.hpp | 82 + .../type_traits/has_nothrow_destructor.hpp | 56 + .../boost/type_traits/has_operator.hpp | 51 + .../include/boost/type_traits/has_plus.hpp | 54 + .../boost/type_traits/has_plus_assign.hpp | 161 + .../boost/type_traits/has_post_decrement.hpp | 65 + .../boost/type_traits/has_post_increment.hpp | 65 + .../boost/type_traits/has_pre_decrement.hpp | 65 + .../boost/type_traits/has_pre_increment.hpp | 66 + .../boost/type_traits/has_right_shift.hpp | 49 + .../type_traits/has_right_shift_assign.hpp | 55 + .../boost/type_traits/has_trivial_assign.hpp | 52 + .../type_traits/has_trivial_constructor.hpp | 57 + .../boost/type_traits/has_trivial_copy.hpp | 63 + .../type_traits/has_trivial_destructor.hpp | 48 + .../type_traits/has_trivial_move_assign.hpp | 73 + .../has_trivial_move_constructor.hpp | 79 + .../boost/type_traits/has_unary_minus.hpp | 25 + .../boost/type_traits/has_unary_plus.hpp | 23 + .../type_traits/has_virtual_destructor.hpp | 26 + .../include/boost/type_traits/ice.hpp | 20 + .../boost/type_traits/integral_constant.hpp | 97 + .../boost/type_traits/integral_promotion.hpp | 187 + .../include/boost/type_traits/intrinsics.hpp | 405 ++ .../include/boost/type_traits/is_abstract.hpp | 150 + .../boost/type_traits/is_arithmetic.hpp | 22 + .../include/boost/type_traits/is_array.hpp | 43 + .../boost/type_traits/is_assignable.hpp | 85 + .../boost/type_traits/is_base_and_derived.hpp | 244 + .../include/boost/type_traits/is_base_of.hpp | 39 + .../boost/type_traits/is_base_of_tr1.hpp | 37 + .../boost/type_traits/is_bounded_array.hpp | 42 + .../include/boost/type_traits/is_class.hpp | 114 + .../include/boost/type_traits/is_complete.hpp | 93 + .../include/boost/type_traits/is_complex.hpp | 25 + .../include/boost/type_traits/is_compound.hpp | 24 + .../include/boost/type_traits/is_const.hpp | 47 + .../boost/type_traits/is_constructible.hpp | 90 + .../boost/type_traits/is_convertible.hpp | 506 ++ .../boost/type_traits/is_copy_assignable.hpp | 140 + .../type_traits/is_copy_constructible.hpp | 185 + .../type_traits/is_default_constructible.hpp | 98 + .../boost/type_traits/is_destructible.hpp | 69 + .../include/boost/type_traits/is_detected.hpp | 29 + .../type_traits/is_detected_convertible.hpp | 29 + .../boost/type_traits/is_detected_exact.hpp | 29 + .../include/boost/type_traits/is_empty.hpp | 120 + .../include/boost/type_traits/is_enum.hpp | 166 + .../include/boost/type_traits/is_final.hpp | 30 + .../include/boost/type_traits/is_float.hpp | 20 + .../boost/type_traits/is_floating_point.hpp | 30 + .../include/boost/type_traits/is_function.hpp | 27 + .../boost/type_traits/is_fundamental.hpp | 26 + .../include/boost/type_traits/is_integral.hpp | 92 + .../type_traits/is_list_constructible.hpp | 48 + .../boost/type_traits/is_lvalue_reference.hpp | 50 + .../is_member_function_pointer.hpp | 26 + .../type_traits/is_member_object_pointer.hpp | 24 + .../boost/type_traits/is_member_pointer.hpp | 45 + .../boost/type_traits/is_noncopyable.hpp | 39 + .../is_nothrow_move_assignable.hpp | 92 + .../is_nothrow_move_constructible.hpp | 97 + .../type_traits/is_nothrow_swappable.hpp | 47 + .../include/boost/type_traits/is_object.hpp | 28 + .../include/boost/type_traits/is_pod.hpp | 59 + .../include/boost/type_traits/is_pointer.hpp | 47 + .../boost/type_traits/is_polymorphic.hpp | 122 + .../boost/type_traits/is_reference.hpp | 30 + .../boost/type_traits/is_rvalue_reference.hpp | 29 + .../include/boost/type_traits/is_same.hpp | 41 + .../include/boost/type_traits/is_scalar.hpp | 27 + .../boost/type_traits/is_scoped_enum.hpp | 26 + .../include/boost/type_traits/is_signed.hpp | 163 + .../boost/type_traits/is_stateless.hpp | 33 + .../boost/type_traits/is_swappable.hpp | 92 + .../type_traits/is_trivially_copyable.hpp | 31 + .../boost/type_traits/is_unbounded_array.hpp | 41 + .../include/boost/type_traits/is_union.hpp | 31 + .../boost/type_traits/is_unscoped_enum.hpp | 25 + .../include/boost/type_traits/is_unsigned.hpp | 163 + .../boost/type_traits/is_virtual_base_of.hpp | 146 + .../include/boost/type_traits/is_void.hpp | 26 + .../include/boost/type_traits/is_volatile.hpp | 46 + .../include/boost/type_traits/make_signed.hpp | 137 + .../boost/type_traits/make_unsigned.hpp | 136 + .../include/boost/type_traits/make_void.hpp | 52 + .../include/boost/type_traits/negation.hpp | 23 + .../include/boost/type_traits/nonesuch.hpp | 35 + .../boost/type_traits/object_traits.hpp | 33 + .../include/boost/type_traits/promote.hpp | 26 + .../include/boost/type_traits/rank.hpp | 87 + .../boost/type_traits/reference_traits.hpp | 15 + .../boost/type_traits/remove_all_extents.hpp | 41 + .../boost/type_traits/remove_bounds.hpp | 28 + .../boost/type_traits/remove_const.hpp | 39 + .../include/boost/type_traits/remove_cv.hpp | 45 + .../boost/type_traits/remove_cv_ref.hpp | 30 + .../boost/type_traits/remove_extent.hpp | 41 + .../boost/type_traits/remove_pointer.hpp | 84 + .../boost/type_traits/remove_reference.hpp | 59 + .../boost/type_traits/remove_volatile.hpp | 39 + .../include/boost/type_traits/same_traits.hpp | 15 + .../boost/type_traits/transform_traits.hpp | 21 + .../boost/type_traits/type_identity.hpp | 31 + .../boost/type_traits/type_with_alignment.hpp | 260 + .../include/boost/utility/declval.hpp | 13 + 536 files changed, 95470 insertions(+), 1 deletion(-) create mode 100644 third_party/boost/CMakeLists.txt create mode 100644 third_party/boost/LICENSE_1_0.txt create mode 100644 third_party/boost/libs/assert/CMakeLists.txt create mode 100644 third_party/boost/libs/assert/README.md create mode 100644 third_party/boost/libs/assert/include/boost/assert.hpp create mode 100644 third_party/boost/libs/assert/include/boost/assert/source_location.hpp create mode 100644 third_party/boost/libs/assert/include/boost/current_function.hpp create mode 100644 third_party/boost/libs/config/CMakeLists.txt create mode 100644 third_party/boost/libs/config/README.md create mode 100644 third_party/boost/libs/config/include/boost/config.hpp create mode 100644 third_party/boost/libs/config/include/boost/config/abi/borland_prefix.hpp create mode 100644 third_party/boost/libs/config/include/boost/config/abi/borland_suffix.hpp create mode 100644 third_party/boost/libs/config/include/boost/config/abi/msvc_prefix.hpp create mode 100644 third_party/boost/libs/config/include/boost/config/abi/msvc_suffix.hpp create mode 100644 third_party/boost/libs/config/include/boost/config/abi_prefix.hpp create mode 100644 third_party/boost/libs/config/include/boost/config/abi_suffix.hpp create mode 100644 third_party/boost/libs/config/include/boost/config/assert_cxx03.hpp create mode 100644 third_party/boost/libs/config/include/boost/config/assert_cxx11.hpp create mode 100644 third_party/boost/libs/config/include/boost/config/assert_cxx14.hpp create mode 100644 third_party/boost/libs/config/include/boost/config/assert_cxx17.hpp create mode 100644 third_party/boost/libs/config/include/boost/config/assert_cxx20.hpp create mode 100644 third_party/boost/libs/config/include/boost/config/assert_cxx98.hpp create mode 100644 third_party/boost/libs/config/include/boost/config/auto_link.hpp create mode 100644 third_party/boost/libs/config/include/boost/config/compiler/borland.hpp create mode 100644 third_party/boost/libs/config/include/boost/config/compiler/clang.hpp create mode 100644 third_party/boost/libs/config/include/boost/config/compiler/clang_version.hpp create mode 100644 third_party/boost/libs/config/include/boost/config/compiler/codegear.hpp create mode 100644 third_party/boost/libs/config/include/boost/config/compiler/comeau.hpp create mode 100644 third_party/boost/libs/config/include/boost/config/compiler/common_edg.hpp create mode 100644 third_party/boost/libs/config/include/boost/config/compiler/compaq_cxx.hpp create mode 100644 third_party/boost/libs/config/include/boost/config/compiler/cray.hpp create mode 100644 third_party/boost/libs/config/include/boost/config/compiler/diab.hpp create mode 100644 third_party/boost/libs/config/include/boost/config/compiler/digitalmars.hpp create mode 100644 third_party/boost/libs/config/include/boost/config/compiler/gcc.hpp create mode 100644 third_party/boost/libs/config/include/boost/config/compiler/gcc_xml.hpp create mode 100644 third_party/boost/libs/config/include/boost/config/compiler/greenhills.hpp create mode 100644 third_party/boost/libs/config/include/boost/config/compiler/hp_acc.hpp create mode 100644 third_party/boost/libs/config/include/boost/config/compiler/intel.hpp create mode 100644 third_party/boost/libs/config/include/boost/config/compiler/kai.hpp create mode 100644 third_party/boost/libs/config/include/boost/config/compiler/metrowerks.hpp create mode 100644 third_party/boost/libs/config/include/boost/config/compiler/mpw.hpp create mode 100644 third_party/boost/libs/config/include/boost/config/compiler/nvcc.hpp create mode 100644 third_party/boost/libs/config/include/boost/config/compiler/pathscale.hpp create mode 100644 third_party/boost/libs/config/include/boost/config/compiler/pgi.hpp create mode 100644 third_party/boost/libs/config/include/boost/config/compiler/sgi_mipspro.hpp create mode 100644 third_party/boost/libs/config/include/boost/config/compiler/sunpro_cc.hpp create mode 100644 third_party/boost/libs/config/include/boost/config/compiler/vacpp.hpp create mode 100644 third_party/boost/libs/config/include/boost/config/compiler/visualc.hpp create mode 100644 third_party/boost/libs/config/include/boost/config/compiler/xlcpp.hpp create mode 100644 third_party/boost/libs/config/include/boost/config/compiler/xlcpp_zos.hpp create mode 100644 third_party/boost/libs/config/include/boost/config/detail/cxx_composite.hpp create mode 100644 third_party/boost/libs/config/include/boost/config/detail/posix_features.hpp create mode 100644 third_party/boost/libs/config/include/boost/config/detail/select_compiler_config.hpp create mode 100644 third_party/boost/libs/config/include/boost/config/detail/select_platform_config.hpp create mode 100644 third_party/boost/libs/config/include/boost/config/detail/select_stdlib_config.hpp create mode 100644 third_party/boost/libs/config/include/boost/config/detail/suffix.hpp create mode 100644 third_party/boost/libs/config/include/boost/config/header_deprecated.hpp create mode 100644 third_party/boost/libs/config/include/boost/config/helper_macros.hpp create mode 100644 third_party/boost/libs/config/include/boost/config/no_tr1/cmath.hpp create mode 100644 third_party/boost/libs/config/include/boost/config/no_tr1/complex.hpp create mode 100644 third_party/boost/libs/config/include/boost/config/no_tr1/functional.hpp create mode 100644 third_party/boost/libs/config/include/boost/config/no_tr1/memory.hpp create mode 100644 third_party/boost/libs/config/include/boost/config/no_tr1/utility.hpp create mode 100644 third_party/boost/libs/config/include/boost/config/platform/aix.hpp create mode 100644 third_party/boost/libs/config/include/boost/config/platform/amigaos.hpp create mode 100644 third_party/boost/libs/config/include/boost/config/platform/beos.hpp create mode 100644 third_party/boost/libs/config/include/boost/config/platform/bsd.hpp create mode 100644 third_party/boost/libs/config/include/boost/config/platform/cloudabi.hpp create mode 100644 third_party/boost/libs/config/include/boost/config/platform/cray.hpp create mode 100644 third_party/boost/libs/config/include/boost/config/platform/cygwin.hpp create mode 100644 third_party/boost/libs/config/include/boost/config/platform/haiku.hpp create mode 100644 third_party/boost/libs/config/include/boost/config/platform/hpux.hpp create mode 100644 third_party/boost/libs/config/include/boost/config/platform/irix.hpp create mode 100644 third_party/boost/libs/config/include/boost/config/platform/linux.hpp create mode 100644 third_party/boost/libs/config/include/boost/config/platform/macos.hpp create mode 100644 third_party/boost/libs/config/include/boost/config/platform/qnxnto.hpp create mode 100644 third_party/boost/libs/config/include/boost/config/platform/solaris.hpp create mode 100644 third_party/boost/libs/config/include/boost/config/platform/symbian.hpp create mode 100644 third_party/boost/libs/config/include/boost/config/platform/vms.hpp create mode 100644 third_party/boost/libs/config/include/boost/config/platform/vxworks.hpp create mode 100644 third_party/boost/libs/config/include/boost/config/platform/wasm.hpp create mode 100644 third_party/boost/libs/config/include/boost/config/platform/win32.hpp create mode 100644 third_party/boost/libs/config/include/boost/config/platform/zos.hpp create mode 100644 third_party/boost/libs/config/include/boost/config/pragma_message.hpp create mode 100644 third_party/boost/libs/config/include/boost/config/requires_threads.hpp create mode 100644 third_party/boost/libs/config/include/boost/config/stdlib/dinkumware.hpp create mode 100644 third_party/boost/libs/config/include/boost/config/stdlib/libcomo.hpp create mode 100644 third_party/boost/libs/config/include/boost/config/stdlib/libcpp.hpp create mode 100644 third_party/boost/libs/config/include/boost/config/stdlib/libstdcpp3.hpp create mode 100644 third_party/boost/libs/config/include/boost/config/stdlib/modena.hpp create mode 100644 third_party/boost/libs/config/include/boost/config/stdlib/msl.hpp create mode 100644 third_party/boost/libs/config/include/boost/config/stdlib/roguewave.hpp create mode 100644 third_party/boost/libs/config/include/boost/config/stdlib/sgi.hpp create mode 100644 third_party/boost/libs/config/include/boost/config/stdlib/stlport.hpp create mode 100644 third_party/boost/libs/config/include/boost/config/stdlib/vacpp.hpp create mode 100644 third_party/boost/libs/config/include/boost/config/stdlib/xlcpp_zos.hpp create mode 100644 third_party/boost/libs/config/include/boost/config/user.hpp create mode 100644 third_party/boost/libs/config/include/boost/config/warning_disable.hpp create mode 100644 third_party/boost/libs/config/include/boost/config/workaround.hpp create mode 100644 third_party/boost/libs/config/include/boost/cstdint.hpp create mode 100644 third_party/boost/libs/config/include/boost/cxx11_char_types.hpp create mode 100644 third_party/boost/libs/config/include/boost/detail/workaround.hpp create mode 100644 third_party/boost/libs/config/include/boost/limits.hpp create mode 100644 third_party/boost/libs/config/include/boost/version.hpp create mode 100644 third_party/boost/libs/container_hash/CMakeLists.txt create mode 100644 third_party/boost/libs/container_hash/README.md create mode 100644 third_party/boost/libs/container_hash/include/boost/container_hash/detail/hash_mix.hpp create mode 100644 third_party/boost/libs/container_hash/include/boost/container_hash/detail/hash_range.hpp create mode 100644 third_party/boost/libs/container_hash/include/boost/container_hash/detail/hash_tuple_like.hpp create mode 100644 third_party/boost/libs/container_hash/include/boost/container_hash/detail/limits.hpp create mode 100644 third_party/boost/libs/container_hash/include/boost/container_hash/detail/mulx.hpp create mode 100644 third_party/boost/libs/container_hash/include/boost/container_hash/detail/requires_cxx11.hpp create mode 100644 third_party/boost/libs/container_hash/include/boost/container_hash/extensions.hpp create mode 100644 third_party/boost/libs/container_hash/include/boost/container_hash/hash.hpp create mode 100644 third_party/boost/libs/container_hash/include/boost/container_hash/hash_fwd.hpp create mode 100644 third_party/boost/libs/container_hash/include/boost/container_hash/is_contiguous_range.hpp create mode 100644 third_party/boost/libs/container_hash/include/boost/container_hash/is_described_class.hpp create mode 100644 third_party/boost/libs/container_hash/include/boost/container_hash/is_range.hpp create mode 100644 third_party/boost/libs/container_hash/include/boost/container_hash/is_tuple_like.hpp create mode 100644 third_party/boost/libs/container_hash/include/boost/container_hash/is_unordered_range.hpp create mode 100644 third_party/boost/libs/container_hash/include/boost/functional/hash.hpp create mode 100644 third_party/boost/libs/container_hash/include/boost/functional/hash/extensions.hpp create mode 100644 third_party/boost/libs/container_hash/include/boost/functional/hash/hash.hpp create mode 100644 third_party/boost/libs/container_hash/include/boost/functional/hash/hash_fwd.hpp create mode 100644 third_party/boost/libs/container_hash/include/boost/functional/hash_fwd.hpp create mode 100644 third_party/boost/libs/describe/CMakeLists.txt create mode 100644 third_party/boost/libs/describe/README.md create mode 100644 third_party/boost/libs/describe/include/boost/describe.hpp create mode 100644 third_party/boost/libs/describe/include/boost/describe/bases.hpp create mode 100644 third_party/boost/libs/describe/include/boost/describe/class.hpp create mode 100644 third_party/boost/libs/describe/include/boost/describe/descriptor_by_name.hpp create mode 100644 third_party/boost/libs/describe/include/boost/describe/descriptor_by_pointer.hpp create mode 100644 third_party/boost/libs/describe/include/boost/describe/detail/bases.hpp create mode 100644 third_party/boost/libs/describe/include/boost/describe/detail/compute_base_modifiers.hpp create mode 100644 third_party/boost/libs/describe/include/boost/describe/detail/config.hpp create mode 100644 third_party/boost/libs/describe/include/boost/describe/detail/cx_streq.hpp create mode 100644 third_party/boost/libs/describe/include/boost/describe/detail/list.hpp create mode 100644 third_party/boost/libs/describe/include/boost/describe/detail/members.hpp create mode 100644 third_party/boost/libs/describe/include/boost/describe/detail/pp_for_each.hpp create mode 100644 third_party/boost/libs/describe/include/boost/describe/detail/pp_utilities.hpp create mode 100644 third_party/boost/libs/describe/include/boost/describe/detail/void_t.hpp create mode 100644 third_party/boost/libs/describe/include/boost/describe/enum.hpp create mode 100644 third_party/boost/libs/describe/include/boost/describe/enum_from_string.hpp create mode 100644 third_party/boost/libs/describe/include/boost/describe/enum_to_string.hpp create mode 100644 third_party/boost/libs/describe/include/boost/describe/enumerators.hpp create mode 100644 third_party/boost/libs/describe/include/boost/describe/members.hpp create mode 100644 third_party/boost/libs/describe/include/boost/describe/modifier_description.hpp create mode 100644 third_party/boost/libs/describe/include/boost/describe/modifiers.hpp create mode 100644 third_party/boost/libs/describe/include/boost/describe/operators.hpp create mode 100644 third_party/boost/libs/intrusive/CMakeLists.txt create mode 100644 third_party/boost/libs/intrusive/README.md create mode 100644 third_party/boost/libs/intrusive/include/boost/intrusive/any_hook.hpp create mode 100644 third_party/boost/libs/intrusive/include/boost/intrusive/avl_set.hpp create mode 100644 third_party/boost/libs/intrusive/include/boost/intrusive/avl_set_hook.hpp create mode 100644 third_party/boost/libs/intrusive/include/boost/intrusive/avltree.hpp create mode 100644 third_party/boost/libs/intrusive/include/boost/intrusive/avltree_algorithms.hpp create mode 100644 third_party/boost/libs/intrusive/include/boost/intrusive/bs_set.hpp create mode 100644 third_party/boost/libs/intrusive/include/boost/intrusive/bs_set_hook.hpp create mode 100644 third_party/boost/libs/intrusive/include/boost/intrusive/bstree.hpp create mode 100644 third_party/boost/libs/intrusive/include/boost/intrusive/bstree_algorithms.hpp create mode 100644 third_party/boost/libs/intrusive/include/boost/intrusive/circular_list_algorithms.hpp create mode 100644 third_party/boost/libs/intrusive/include/boost/intrusive/circular_slist_algorithms.hpp create mode 100644 third_party/boost/libs/intrusive/include/boost/intrusive/derivation_value_traits.hpp create mode 100644 third_party/boost/libs/intrusive/include/boost/intrusive/detail/algo_type.hpp create mode 100644 third_party/boost/libs/intrusive/include/boost/intrusive/detail/algorithm.hpp create mode 100644 third_party/boost/libs/intrusive/include/boost/intrusive/detail/any_node_and_algorithms.hpp create mode 100644 third_party/boost/libs/intrusive/include/boost/intrusive/detail/array_initializer.hpp create mode 100644 third_party/boost/libs/intrusive/include/boost/intrusive/detail/assert.hpp create mode 100644 third_party/boost/libs/intrusive/include/boost/intrusive/detail/avltree_node.hpp create mode 100644 third_party/boost/libs/intrusive/include/boost/intrusive/detail/bstree_algorithms_base.hpp create mode 100644 third_party/boost/libs/intrusive/include/boost/intrusive/detail/common_slist_algorithms.hpp create mode 100644 third_party/boost/libs/intrusive/include/boost/intrusive/detail/config_begin.hpp create mode 100644 third_party/boost/libs/intrusive/include/boost/intrusive/detail/config_end.hpp create mode 100644 third_party/boost/libs/intrusive/include/boost/intrusive/detail/default_header_holder.hpp create mode 100644 third_party/boost/libs/intrusive/include/boost/intrusive/detail/ebo_functor_holder.hpp create mode 100644 third_party/boost/libs/intrusive/include/boost/intrusive/detail/empty_node_checker.hpp create mode 100644 third_party/boost/libs/intrusive/include/boost/intrusive/detail/equal_to_value.hpp create mode 100644 third_party/boost/libs/intrusive/include/boost/intrusive/detail/exception_disposer.hpp create mode 100644 third_party/boost/libs/intrusive/include/boost/intrusive/detail/function_detector.hpp create mode 100644 third_party/boost/libs/intrusive/include/boost/intrusive/detail/generic_hook.hpp create mode 100644 third_party/boost/libs/intrusive/include/boost/intrusive/detail/get_value_traits.hpp create mode 100644 third_party/boost/libs/intrusive/include/boost/intrusive/detail/has_member_function_callable_with.hpp create mode 100644 third_party/boost/libs/intrusive/include/boost/intrusive/detail/hash_combine.hpp create mode 100644 third_party/boost/libs/intrusive/include/boost/intrusive/detail/hashtable_node.hpp create mode 100644 third_party/boost/libs/intrusive/include/boost/intrusive/detail/hook_traits.hpp create mode 100644 third_party/boost/libs/intrusive/include/boost/intrusive/detail/iiterator.hpp create mode 100644 third_party/boost/libs/intrusive/include/boost/intrusive/detail/is_stateful_value_traits.hpp create mode 100644 third_party/boost/libs/intrusive/include/boost/intrusive/detail/iterator.hpp create mode 100644 third_party/boost/libs/intrusive/include/boost/intrusive/detail/key_nodeptr_comp.hpp create mode 100644 third_party/boost/libs/intrusive/include/boost/intrusive/detail/list_iterator.hpp create mode 100644 third_party/boost/libs/intrusive/include/boost/intrusive/detail/list_node.hpp create mode 100644 third_party/boost/libs/intrusive/include/boost/intrusive/detail/math.hpp create mode 100644 third_party/boost/libs/intrusive/include/boost/intrusive/detail/minimal_less_equal_header.hpp create mode 100644 third_party/boost/libs/intrusive/include/boost/intrusive/detail/minimal_pair_header.hpp create mode 100644 third_party/boost/libs/intrusive/include/boost/intrusive/detail/mpl.hpp create mode 100644 third_party/boost/libs/intrusive/include/boost/intrusive/detail/node_cloner_disposer.hpp create mode 100644 third_party/boost/libs/intrusive/include/boost/intrusive/detail/node_holder.hpp create mode 100644 third_party/boost/libs/intrusive/include/boost/intrusive/detail/node_to_value.hpp create mode 100644 third_party/boost/libs/intrusive/include/boost/intrusive/detail/parent_from_member.hpp create mode 100644 third_party/boost/libs/intrusive/include/boost/intrusive/detail/rbtree_node.hpp create mode 100644 third_party/boost/libs/intrusive/include/boost/intrusive/detail/reverse_iterator.hpp create mode 100644 third_party/boost/libs/intrusive/include/boost/intrusive/detail/simple_disposers.hpp create mode 100644 third_party/boost/libs/intrusive/include/boost/intrusive/detail/size_holder.hpp create mode 100644 third_party/boost/libs/intrusive/include/boost/intrusive/detail/slist_iterator.hpp create mode 100644 third_party/boost/libs/intrusive/include/boost/intrusive/detail/slist_node.hpp create mode 100644 third_party/boost/libs/intrusive/include/boost/intrusive/detail/std_fwd.hpp create mode 100644 third_party/boost/libs/intrusive/include/boost/intrusive/detail/transform_iterator.hpp create mode 100644 third_party/boost/libs/intrusive/include/boost/intrusive/detail/tree_iterator.hpp create mode 100644 third_party/boost/libs/intrusive/include/boost/intrusive/detail/tree_node.hpp create mode 100644 third_party/boost/libs/intrusive/include/boost/intrusive/detail/tree_value_compare.hpp create mode 100644 third_party/boost/libs/intrusive/include/boost/intrusive/detail/twin.hpp create mode 100644 third_party/boost/libs/intrusive/include/boost/intrusive/detail/uncast.hpp create mode 100644 third_party/boost/libs/intrusive/include/boost/intrusive/detail/value_functors.hpp create mode 100644 third_party/boost/libs/intrusive/include/boost/intrusive/detail/workaround.hpp create mode 100644 third_party/boost/libs/intrusive/include/boost/intrusive/hashtable.hpp create mode 100644 third_party/boost/libs/intrusive/include/boost/intrusive/intrusive_fwd.hpp create mode 100644 third_party/boost/libs/intrusive/include/boost/intrusive/linear_slist_algorithms.hpp create mode 100644 third_party/boost/libs/intrusive/include/boost/intrusive/link_mode.hpp create mode 100644 third_party/boost/libs/intrusive/include/boost/intrusive/list.hpp create mode 100644 third_party/boost/libs/intrusive/include/boost/intrusive/list_hook.hpp create mode 100644 third_party/boost/libs/intrusive/include/boost/intrusive/member_value_traits.hpp create mode 100644 third_party/boost/libs/intrusive/include/boost/intrusive/options.hpp create mode 100644 third_party/boost/libs/intrusive/include/boost/intrusive/pack_options.hpp create mode 100644 third_party/boost/libs/intrusive/include/boost/intrusive/parent_from_member.hpp create mode 100644 third_party/boost/libs/intrusive/include/boost/intrusive/pointer_plus_bits.hpp create mode 100644 third_party/boost/libs/intrusive/include/boost/intrusive/pointer_rebind.hpp create mode 100644 third_party/boost/libs/intrusive/include/boost/intrusive/pointer_traits.hpp create mode 100644 third_party/boost/libs/intrusive/include/boost/intrusive/priority_compare.hpp create mode 100644 third_party/boost/libs/intrusive/include/boost/intrusive/rbtree.hpp create mode 100644 third_party/boost/libs/intrusive/include/boost/intrusive/rbtree_algorithms.hpp create mode 100644 third_party/boost/libs/intrusive/include/boost/intrusive/set.hpp create mode 100644 third_party/boost/libs/intrusive/include/boost/intrusive/set_hook.hpp create mode 100644 third_party/boost/libs/intrusive/include/boost/intrusive/sg_set.hpp create mode 100644 third_party/boost/libs/intrusive/include/boost/intrusive/sgtree.hpp create mode 100644 third_party/boost/libs/intrusive/include/boost/intrusive/sgtree_algorithms.hpp create mode 100644 third_party/boost/libs/intrusive/include/boost/intrusive/slist.hpp create mode 100644 third_party/boost/libs/intrusive/include/boost/intrusive/slist_hook.hpp create mode 100644 third_party/boost/libs/intrusive/include/boost/intrusive/splay_set.hpp create mode 100644 third_party/boost/libs/intrusive/include/boost/intrusive/splaytree.hpp create mode 100644 third_party/boost/libs/intrusive/include/boost/intrusive/splaytree_algorithms.hpp create mode 100644 third_party/boost/libs/intrusive/include/boost/intrusive/treap.hpp create mode 100644 third_party/boost/libs/intrusive/include/boost/intrusive/treap_algorithms.hpp create mode 100644 third_party/boost/libs/intrusive/include/boost/intrusive/treap_set.hpp create mode 100644 third_party/boost/libs/intrusive/include/boost/intrusive/trivial_value_traits.hpp create mode 100644 third_party/boost/libs/intrusive/include/boost/intrusive/unordered_set.hpp create mode 100644 third_party/boost/libs/intrusive/include/boost/intrusive/unordered_set_hook.hpp create mode 100644 third_party/boost/libs/move/CMakeLists.txt create mode 100644 third_party/boost/libs/move/LICENSE create mode 100644 third_party/boost/libs/move/README.md create mode 100644 third_party/boost/libs/move/include/boost/move/adl_move_swap.hpp create mode 100644 third_party/boost/libs/move/include/boost/move/algo/adaptive_merge.hpp create mode 100644 third_party/boost/libs/move/include/boost/move/algo/adaptive_sort.hpp create mode 100644 third_party/boost/libs/move/include/boost/move/algo/detail/adaptive_sort_merge.hpp create mode 100644 third_party/boost/libs/move/include/boost/move/algo/detail/basic_op.hpp create mode 100644 third_party/boost/libs/move/include/boost/move/algo/detail/heap_sort.hpp create mode 100644 third_party/boost/libs/move/include/boost/move/algo/detail/insertion_sort.hpp create mode 100644 third_party/boost/libs/move/include/boost/move/algo/detail/is_sorted.hpp create mode 100644 third_party/boost/libs/move/include/boost/move/algo/detail/merge.hpp create mode 100644 third_party/boost/libs/move/include/boost/move/algo/detail/merge_sort.hpp create mode 100644 third_party/boost/libs/move/include/boost/move/algo/detail/pdqsort.hpp create mode 100644 third_party/boost/libs/move/include/boost/move/algo/detail/search.hpp create mode 100644 third_party/boost/libs/move/include/boost/move/algo/detail/set_difference.hpp create mode 100644 third_party/boost/libs/move/include/boost/move/algo/move.hpp create mode 100644 third_party/boost/libs/move/include/boost/move/algo/predicate.hpp create mode 100644 third_party/boost/libs/move/include/boost/move/algo/unique.hpp create mode 100644 third_party/boost/libs/move/include/boost/move/algorithm.hpp create mode 100644 third_party/boost/libs/move/include/boost/move/core.hpp create mode 100644 third_party/boost/libs/move/include/boost/move/default_delete.hpp create mode 100644 third_party/boost/libs/move/include/boost/move/detail/addressof.hpp create mode 100644 third_party/boost/libs/move/include/boost/move/detail/config_begin.hpp create mode 100644 third_party/boost/libs/move/include/boost/move/detail/config_end.hpp create mode 100644 third_party/boost/libs/move/include/boost/move/detail/destruct_n.hpp create mode 100644 third_party/boost/libs/move/include/boost/move/detail/force_ptr.hpp create mode 100644 third_party/boost/libs/move/include/boost/move/detail/fwd_macros.hpp create mode 100644 third_party/boost/libs/move/include/boost/move/detail/iterator_to_raw_pointer.hpp create mode 100644 third_party/boost/libs/move/include/boost/move/detail/iterator_traits.hpp create mode 100644 third_party/boost/libs/move/include/boost/move/detail/meta_utils.hpp create mode 100644 third_party/boost/libs/move/include/boost/move/detail/meta_utils_core.hpp create mode 100644 third_party/boost/libs/move/include/boost/move/detail/move_helpers.hpp create mode 100644 third_party/boost/libs/move/include/boost/move/detail/nsec_clock.hpp create mode 100644 third_party/boost/libs/move/include/boost/move/detail/placement_new.hpp create mode 100644 third_party/boost/libs/move/include/boost/move/detail/pointer_element.hpp create mode 100644 third_party/boost/libs/move/include/boost/move/detail/reverse_iterator.hpp create mode 100644 third_party/boost/libs/move/include/boost/move/detail/std_ns_begin.hpp create mode 100644 third_party/boost/libs/move/include/boost/move/detail/std_ns_end.hpp create mode 100644 third_party/boost/libs/move/include/boost/move/detail/to_raw_pointer.hpp create mode 100644 third_party/boost/libs/move/include/boost/move/detail/type_traits.hpp create mode 100644 third_party/boost/libs/move/include/boost/move/detail/unique_ptr_meta_utils.hpp create mode 100644 third_party/boost/libs/move/include/boost/move/detail/workaround.hpp create mode 100644 third_party/boost/libs/move/include/boost/move/iterator.hpp create mode 100644 third_party/boost/libs/move/include/boost/move/make_unique.hpp create mode 100644 third_party/boost/libs/move/include/boost/move/move.hpp create mode 100644 third_party/boost/libs/move/include/boost/move/traits.hpp create mode 100644 third_party/boost/libs/move/include/boost/move/unique_ptr.hpp create mode 100644 third_party/boost/libs/move/include/boost/move/utility.hpp create mode 100644 third_party/boost/libs/move/include/boost/move/utility_core.hpp create mode 100644 third_party/boost/libs/mp11/CMakeLists.txt create mode 100644 third_party/boost/libs/mp11/README.md create mode 100644 third_party/boost/libs/mp11/include/boost/mp11.hpp create mode 100644 third_party/boost/libs/mp11/include/boost/mp11/algorithm.hpp create mode 100644 third_party/boost/libs/mp11/include/boost/mp11/bind.hpp create mode 100644 third_party/boost/libs/mp11/include/boost/mp11/detail/config.hpp create mode 100644 third_party/boost/libs/mp11/include/boost/mp11/detail/mp_append.hpp create mode 100644 third_party/boost/libs/mp11/include/boost/mp11/detail/mp_copy_if.hpp create mode 100644 third_party/boost/libs/mp11/include/boost/mp11/detail/mp_count.hpp create mode 100644 third_party/boost/libs/mp11/include/boost/mp11/detail/mp_fold.hpp create mode 100644 third_party/boost/libs/mp11/include/boost/mp11/detail/mp_front.hpp create mode 100644 third_party/boost/libs/mp11/include/boost/mp11/detail/mp_is_list.hpp create mode 100644 third_party/boost/libs/mp11/include/boost/mp11/detail/mp_list.hpp create mode 100644 third_party/boost/libs/mp11/include/boost/mp11/detail/mp_map_find.hpp create mode 100644 third_party/boost/libs/mp11/include/boost/mp11/detail/mp_min_element.hpp create mode 100644 third_party/boost/libs/mp11/include/boost/mp11/detail/mp_plus.hpp create mode 100644 third_party/boost/libs/mp11/include/boost/mp11/detail/mp_remove_if.hpp create mode 100644 third_party/boost/libs/mp11/include/boost/mp11/detail/mp_rename.hpp create mode 100644 third_party/boost/libs/mp11/include/boost/mp11/detail/mp_void.hpp create mode 100644 third_party/boost/libs/mp11/include/boost/mp11/detail/mp_with_index.hpp create mode 100644 third_party/boost/libs/mp11/include/boost/mp11/detail/mpl_common.hpp create mode 100644 third_party/boost/libs/mp11/include/boost/mp11/function.hpp create mode 100644 third_party/boost/libs/mp11/include/boost/mp11/integer_sequence.hpp create mode 100644 third_party/boost/libs/mp11/include/boost/mp11/integral.hpp create mode 100644 third_party/boost/libs/mp11/include/boost/mp11/list.hpp create mode 100644 third_party/boost/libs/mp11/include/boost/mp11/map.hpp create mode 100644 third_party/boost/libs/mp11/include/boost/mp11/mpl.hpp create mode 100644 third_party/boost/libs/mp11/include/boost/mp11/mpl_list.hpp create mode 100644 third_party/boost/libs/mp11/include/boost/mp11/mpl_tuple.hpp create mode 100644 third_party/boost/libs/mp11/include/boost/mp11/set.hpp create mode 100644 third_party/boost/libs/mp11/include/boost/mp11/tuple.hpp create mode 100644 third_party/boost/libs/mp11/include/boost/mp11/utility.hpp create mode 100644 third_party/boost/libs/mp11/include/boost/mp11/version.hpp create mode 100644 third_party/boost/libs/static_assert/CMakeLists.txt create mode 100644 third_party/boost/libs/static_assert/README.md create mode 100644 third_party/boost/libs/static_assert/include/boost/static_assert.hpp create mode 100644 third_party/boost/libs/type_traits/CMakeLists.txt create mode 100644 third_party/boost/libs/type_traits/README.md create mode 100644 third_party/boost/libs/type_traits/include/boost/aligned_storage.hpp create mode 100644 third_party/boost/libs/type_traits/include/boost/type_traits.hpp create mode 100644 third_party/boost/libs/type_traits/include/boost/type_traits/add_const.hpp create mode 100644 third_party/boost/libs/type_traits/include/boost/type_traits/add_cv.hpp create mode 100644 third_party/boost/libs/type_traits/include/boost/type_traits/add_lvalue_reference.hpp create mode 100644 third_party/boost/libs/type_traits/include/boost/type_traits/add_pointer.hpp create mode 100644 third_party/boost/libs/type_traits/include/boost/type_traits/add_reference.hpp create mode 100644 third_party/boost/libs/type_traits/include/boost/type_traits/add_rvalue_reference.hpp create mode 100644 third_party/boost/libs/type_traits/include/boost/type_traits/add_volatile.hpp create mode 100644 third_party/boost/libs/type_traits/include/boost/type_traits/aligned_storage.hpp create mode 100644 third_party/boost/libs/type_traits/include/boost/type_traits/alignment_of.hpp create mode 100644 third_party/boost/libs/type_traits/include/boost/type_traits/alignment_traits.hpp create mode 100644 third_party/boost/libs/type_traits/include/boost/type_traits/arithmetic_traits.hpp create mode 100644 third_party/boost/libs/type_traits/include/boost/type_traits/array_traits.hpp create mode 100644 third_party/boost/libs/type_traits/include/boost/type_traits/broken_compiler_spec.hpp create mode 100644 third_party/boost/libs/type_traits/include/boost/type_traits/common_type.hpp create mode 100644 third_party/boost/libs/type_traits/include/boost/type_traits/composite_traits.hpp create mode 100644 third_party/boost/libs/type_traits/include/boost/type_traits/conditional.hpp create mode 100644 third_party/boost/libs/type_traits/include/boost/type_traits/config.hpp create mode 100644 third_party/boost/libs/type_traits/include/boost/type_traits/conjunction.hpp create mode 100644 third_party/boost/libs/type_traits/include/boost/type_traits/conversion_traits.hpp create mode 100644 third_party/boost/libs/type_traits/include/boost/type_traits/copy_cv.hpp create mode 100644 third_party/boost/libs/type_traits/include/boost/type_traits/copy_cv_ref.hpp create mode 100644 third_party/boost/libs/type_traits/include/boost/type_traits/copy_reference.hpp create mode 100644 third_party/boost/libs/type_traits/include/boost/type_traits/cv_traits.hpp create mode 100644 third_party/boost/libs/type_traits/include/boost/type_traits/decay.hpp create mode 100644 third_party/boost/libs/type_traits/include/boost/type_traits/declval.hpp create mode 100644 third_party/boost/libs/type_traits/include/boost/type_traits/detail/bool_trait_def.hpp create mode 100644 third_party/boost/libs/type_traits/include/boost/type_traits/detail/bool_trait_undef.hpp create mode 100644 third_party/boost/libs/type_traits/include/boost/type_traits/detail/common_arithmetic_type.hpp create mode 100644 third_party/boost/libs/type_traits/include/boost/type_traits/detail/common_type_impl.hpp create mode 100644 third_party/boost/libs/type_traits/include/boost/type_traits/detail/composite_member_pointer_type.hpp create mode 100644 third_party/boost/libs/type_traits/include/boost/type_traits/detail/composite_pointer_type.hpp create mode 100644 third_party/boost/libs/type_traits/include/boost/type_traits/detail/config.hpp create mode 100644 third_party/boost/libs/type_traits/include/boost/type_traits/detail/detector.hpp create mode 100644 third_party/boost/libs/type_traits/include/boost/type_traits/detail/has_binary_operator.hpp create mode 100644 third_party/boost/libs/type_traits/include/boost/type_traits/detail/has_postfix_operator.hpp create mode 100644 third_party/boost/libs/type_traits/include/boost/type_traits/detail/has_prefix_operator.hpp create mode 100644 third_party/boost/libs/type_traits/include/boost/type_traits/detail/ice_and.hpp create mode 100644 third_party/boost/libs/type_traits/include/boost/type_traits/detail/ice_eq.hpp create mode 100644 third_party/boost/libs/type_traits/include/boost/type_traits/detail/ice_not.hpp create mode 100644 third_party/boost/libs/type_traits/include/boost/type_traits/detail/ice_or.hpp create mode 100644 third_party/boost/libs/type_traits/include/boost/type_traits/detail/is_function_cxx_03.hpp create mode 100644 third_party/boost/libs/type_traits/include/boost/type_traits/detail/is_function_cxx_11.hpp create mode 100644 third_party/boost/libs/type_traits/include/boost/type_traits/detail/is_function_msvc10_fix.hpp create mode 100644 third_party/boost/libs/type_traits/include/boost/type_traits/detail/is_function_ptr_helper.hpp create mode 100644 third_party/boost/libs/type_traits/include/boost/type_traits/detail/is_function_ptr_tester.hpp create mode 100644 third_party/boost/libs/type_traits/include/boost/type_traits/detail/is_likely_lambda.hpp create mode 100644 third_party/boost/libs/type_traits/include/boost/type_traits/detail/is_mem_fun_pointer_impl.hpp create mode 100644 third_party/boost/libs/type_traits/include/boost/type_traits/detail/is_mem_fun_pointer_tester.hpp create mode 100644 third_party/boost/libs/type_traits/include/boost/type_traits/detail/is_member_function_pointer_cxx_03.hpp create mode 100644 third_party/boost/libs/type_traits/include/boost/type_traits/detail/is_member_function_pointer_cxx_11.hpp create mode 100644 third_party/boost/libs/type_traits/include/boost/type_traits/detail/is_rvalue_reference_msvc10_fix.hpp create mode 100644 third_party/boost/libs/type_traits/include/boost/type_traits/detail/is_swappable_cxx_11.hpp create mode 100644 third_party/boost/libs/type_traits/include/boost/type_traits/detail/mp_defer.hpp create mode 100644 third_party/boost/libs/type_traits/include/boost/type_traits/detail/template_arity_spec.hpp create mode 100644 third_party/boost/libs/type_traits/include/boost/type_traits/detail/yes_no_type.hpp create mode 100644 third_party/boost/libs/type_traits/include/boost/type_traits/detected.hpp create mode 100644 third_party/boost/libs/type_traits/include/boost/type_traits/detected_or.hpp create mode 100644 third_party/boost/libs/type_traits/include/boost/type_traits/disjunction.hpp create mode 100644 third_party/boost/libs/type_traits/include/boost/type_traits/enable_if.hpp create mode 100644 third_party/boost/libs/type_traits/include/boost/type_traits/extent.hpp create mode 100644 third_party/boost/libs/type_traits/include/boost/type_traits/floating_point_promotion.hpp create mode 100644 third_party/boost/libs/type_traits/include/boost/type_traits/function_traits.hpp create mode 100644 third_party/boost/libs/type_traits/include/boost/type_traits/has_bit_and.hpp create mode 100644 third_party/boost/libs/type_traits/include/boost/type_traits/has_bit_and_assign.hpp create mode 100644 third_party/boost/libs/type_traits/include/boost/type_traits/has_bit_or.hpp create mode 100644 third_party/boost/libs/type_traits/include/boost/type_traits/has_bit_or_assign.hpp create mode 100644 third_party/boost/libs/type_traits/include/boost/type_traits/has_bit_xor.hpp create mode 100644 third_party/boost/libs/type_traits/include/boost/type_traits/has_bit_xor_assign.hpp create mode 100644 third_party/boost/libs/type_traits/include/boost/type_traits/has_complement.hpp create mode 100644 third_party/boost/libs/type_traits/include/boost/type_traits/has_dereference.hpp create mode 100644 third_party/boost/libs/type_traits/include/boost/type_traits/has_divides.hpp create mode 100644 third_party/boost/libs/type_traits/include/boost/type_traits/has_divides_assign.hpp create mode 100644 third_party/boost/libs/type_traits/include/boost/type_traits/has_equal_to.hpp create mode 100644 third_party/boost/libs/type_traits/include/boost/type_traits/has_greater.hpp create mode 100644 third_party/boost/libs/type_traits/include/boost/type_traits/has_greater_equal.hpp create mode 100644 third_party/boost/libs/type_traits/include/boost/type_traits/has_left_shift.hpp create mode 100644 third_party/boost/libs/type_traits/include/boost/type_traits/has_left_shift_assign.hpp create mode 100644 third_party/boost/libs/type_traits/include/boost/type_traits/has_less.hpp create mode 100644 third_party/boost/libs/type_traits/include/boost/type_traits/has_less_equal.hpp create mode 100644 third_party/boost/libs/type_traits/include/boost/type_traits/has_logical_and.hpp create mode 100644 third_party/boost/libs/type_traits/include/boost/type_traits/has_logical_not.hpp create mode 100644 third_party/boost/libs/type_traits/include/boost/type_traits/has_logical_or.hpp create mode 100644 third_party/boost/libs/type_traits/include/boost/type_traits/has_minus.hpp create mode 100644 third_party/boost/libs/type_traits/include/boost/type_traits/has_minus_assign.hpp create mode 100644 third_party/boost/libs/type_traits/include/boost/type_traits/has_modulus.hpp create mode 100644 third_party/boost/libs/type_traits/include/boost/type_traits/has_modulus_assign.hpp create mode 100644 third_party/boost/libs/type_traits/include/boost/type_traits/has_multiplies.hpp create mode 100644 third_party/boost/libs/type_traits/include/boost/type_traits/has_multiplies_assign.hpp create mode 100644 third_party/boost/libs/type_traits/include/boost/type_traits/has_negate.hpp create mode 100644 third_party/boost/libs/type_traits/include/boost/type_traits/has_new_operator.hpp create mode 100644 third_party/boost/libs/type_traits/include/boost/type_traits/has_not_equal_to.hpp create mode 100644 third_party/boost/libs/type_traits/include/boost/type_traits/has_nothrow_assign.hpp create mode 100644 third_party/boost/libs/type_traits/include/boost/type_traits/has_nothrow_constructor.hpp create mode 100644 third_party/boost/libs/type_traits/include/boost/type_traits/has_nothrow_copy.hpp create mode 100644 third_party/boost/libs/type_traits/include/boost/type_traits/has_nothrow_destructor.hpp create mode 100644 third_party/boost/libs/type_traits/include/boost/type_traits/has_operator.hpp create mode 100644 third_party/boost/libs/type_traits/include/boost/type_traits/has_plus.hpp create mode 100644 third_party/boost/libs/type_traits/include/boost/type_traits/has_plus_assign.hpp create mode 100644 third_party/boost/libs/type_traits/include/boost/type_traits/has_post_decrement.hpp create mode 100644 third_party/boost/libs/type_traits/include/boost/type_traits/has_post_increment.hpp create mode 100644 third_party/boost/libs/type_traits/include/boost/type_traits/has_pre_decrement.hpp create mode 100644 third_party/boost/libs/type_traits/include/boost/type_traits/has_pre_increment.hpp create mode 100644 third_party/boost/libs/type_traits/include/boost/type_traits/has_right_shift.hpp create mode 100644 third_party/boost/libs/type_traits/include/boost/type_traits/has_right_shift_assign.hpp create mode 100644 third_party/boost/libs/type_traits/include/boost/type_traits/has_trivial_assign.hpp create mode 100644 third_party/boost/libs/type_traits/include/boost/type_traits/has_trivial_constructor.hpp create mode 100644 third_party/boost/libs/type_traits/include/boost/type_traits/has_trivial_copy.hpp create mode 100644 third_party/boost/libs/type_traits/include/boost/type_traits/has_trivial_destructor.hpp create mode 100644 third_party/boost/libs/type_traits/include/boost/type_traits/has_trivial_move_assign.hpp create mode 100644 third_party/boost/libs/type_traits/include/boost/type_traits/has_trivial_move_constructor.hpp create mode 100644 third_party/boost/libs/type_traits/include/boost/type_traits/has_unary_minus.hpp create mode 100644 third_party/boost/libs/type_traits/include/boost/type_traits/has_unary_plus.hpp create mode 100644 third_party/boost/libs/type_traits/include/boost/type_traits/has_virtual_destructor.hpp create mode 100644 third_party/boost/libs/type_traits/include/boost/type_traits/ice.hpp create mode 100644 third_party/boost/libs/type_traits/include/boost/type_traits/integral_constant.hpp create mode 100644 third_party/boost/libs/type_traits/include/boost/type_traits/integral_promotion.hpp create mode 100644 third_party/boost/libs/type_traits/include/boost/type_traits/intrinsics.hpp create mode 100644 third_party/boost/libs/type_traits/include/boost/type_traits/is_abstract.hpp create mode 100644 third_party/boost/libs/type_traits/include/boost/type_traits/is_arithmetic.hpp create mode 100644 third_party/boost/libs/type_traits/include/boost/type_traits/is_array.hpp create mode 100644 third_party/boost/libs/type_traits/include/boost/type_traits/is_assignable.hpp create mode 100644 third_party/boost/libs/type_traits/include/boost/type_traits/is_base_and_derived.hpp create mode 100644 third_party/boost/libs/type_traits/include/boost/type_traits/is_base_of.hpp create mode 100644 third_party/boost/libs/type_traits/include/boost/type_traits/is_base_of_tr1.hpp create mode 100644 third_party/boost/libs/type_traits/include/boost/type_traits/is_bounded_array.hpp create mode 100644 third_party/boost/libs/type_traits/include/boost/type_traits/is_class.hpp create mode 100644 third_party/boost/libs/type_traits/include/boost/type_traits/is_complete.hpp create mode 100644 third_party/boost/libs/type_traits/include/boost/type_traits/is_complex.hpp create mode 100644 third_party/boost/libs/type_traits/include/boost/type_traits/is_compound.hpp create mode 100644 third_party/boost/libs/type_traits/include/boost/type_traits/is_const.hpp create mode 100644 third_party/boost/libs/type_traits/include/boost/type_traits/is_constructible.hpp create mode 100644 third_party/boost/libs/type_traits/include/boost/type_traits/is_convertible.hpp create mode 100644 third_party/boost/libs/type_traits/include/boost/type_traits/is_copy_assignable.hpp create mode 100644 third_party/boost/libs/type_traits/include/boost/type_traits/is_copy_constructible.hpp create mode 100644 third_party/boost/libs/type_traits/include/boost/type_traits/is_default_constructible.hpp create mode 100644 third_party/boost/libs/type_traits/include/boost/type_traits/is_destructible.hpp create mode 100644 third_party/boost/libs/type_traits/include/boost/type_traits/is_detected.hpp create mode 100644 third_party/boost/libs/type_traits/include/boost/type_traits/is_detected_convertible.hpp create mode 100644 third_party/boost/libs/type_traits/include/boost/type_traits/is_detected_exact.hpp create mode 100644 third_party/boost/libs/type_traits/include/boost/type_traits/is_empty.hpp create mode 100644 third_party/boost/libs/type_traits/include/boost/type_traits/is_enum.hpp create mode 100644 third_party/boost/libs/type_traits/include/boost/type_traits/is_final.hpp create mode 100644 third_party/boost/libs/type_traits/include/boost/type_traits/is_float.hpp create mode 100644 third_party/boost/libs/type_traits/include/boost/type_traits/is_floating_point.hpp create mode 100644 third_party/boost/libs/type_traits/include/boost/type_traits/is_function.hpp create mode 100644 third_party/boost/libs/type_traits/include/boost/type_traits/is_fundamental.hpp create mode 100644 third_party/boost/libs/type_traits/include/boost/type_traits/is_integral.hpp create mode 100644 third_party/boost/libs/type_traits/include/boost/type_traits/is_list_constructible.hpp create mode 100644 third_party/boost/libs/type_traits/include/boost/type_traits/is_lvalue_reference.hpp create mode 100644 third_party/boost/libs/type_traits/include/boost/type_traits/is_member_function_pointer.hpp create mode 100644 third_party/boost/libs/type_traits/include/boost/type_traits/is_member_object_pointer.hpp create mode 100644 third_party/boost/libs/type_traits/include/boost/type_traits/is_member_pointer.hpp create mode 100644 third_party/boost/libs/type_traits/include/boost/type_traits/is_noncopyable.hpp create mode 100644 third_party/boost/libs/type_traits/include/boost/type_traits/is_nothrow_move_assignable.hpp create mode 100644 third_party/boost/libs/type_traits/include/boost/type_traits/is_nothrow_move_constructible.hpp create mode 100644 third_party/boost/libs/type_traits/include/boost/type_traits/is_nothrow_swappable.hpp create mode 100644 third_party/boost/libs/type_traits/include/boost/type_traits/is_object.hpp create mode 100644 third_party/boost/libs/type_traits/include/boost/type_traits/is_pod.hpp create mode 100644 third_party/boost/libs/type_traits/include/boost/type_traits/is_pointer.hpp create mode 100644 third_party/boost/libs/type_traits/include/boost/type_traits/is_polymorphic.hpp create mode 100644 third_party/boost/libs/type_traits/include/boost/type_traits/is_reference.hpp create mode 100644 third_party/boost/libs/type_traits/include/boost/type_traits/is_rvalue_reference.hpp create mode 100644 third_party/boost/libs/type_traits/include/boost/type_traits/is_same.hpp create mode 100644 third_party/boost/libs/type_traits/include/boost/type_traits/is_scalar.hpp create mode 100644 third_party/boost/libs/type_traits/include/boost/type_traits/is_scoped_enum.hpp create mode 100644 third_party/boost/libs/type_traits/include/boost/type_traits/is_signed.hpp create mode 100644 third_party/boost/libs/type_traits/include/boost/type_traits/is_stateless.hpp create mode 100644 third_party/boost/libs/type_traits/include/boost/type_traits/is_swappable.hpp create mode 100644 third_party/boost/libs/type_traits/include/boost/type_traits/is_trivially_copyable.hpp create mode 100644 third_party/boost/libs/type_traits/include/boost/type_traits/is_unbounded_array.hpp create mode 100644 third_party/boost/libs/type_traits/include/boost/type_traits/is_union.hpp create mode 100644 third_party/boost/libs/type_traits/include/boost/type_traits/is_unscoped_enum.hpp create mode 100644 third_party/boost/libs/type_traits/include/boost/type_traits/is_unsigned.hpp create mode 100644 third_party/boost/libs/type_traits/include/boost/type_traits/is_virtual_base_of.hpp create mode 100644 third_party/boost/libs/type_traits/include/boost/type_traits/is_void.hpp create mode 100644 third_party/boost/libs/type_traits/include/boost/type_traits/is_volatile.hpp create mode 100644 third_party/boost/libs/type_traits/include/boost/type_traits/make_signed.hpp create mode 100644 third_party/boost/libs/type_traits/include/boost/type_traits/make_unsigned.hpp create mode 100644 third_party/boost/libs/type_traits/include/boost/type_traits/make_void.hpp create mode 100644 third_party/boost/libs/type_traits/include/boost/type_traits/negation.hpp create mode 100644 third_party/boost/libs/type_traits/include/boost/type_traits/nonesuch.hpp create mode 100644 third_party/boost/libs/type_traits/include/boost/type_traits/object_traits.hpp create mode 100644 third_party/boost/libs/type_traits/include/boost/type_traits/promote.hpp create mode 100644 third_party/boost/libs/type_traits/include/boost/type_traits/rank.hpp create mode 100644 third_party/boost/libs/type_traits/include/boost/type_traits/reference_traits.hpp create mode 100644 third_party/boost/libs/type_traits/include/boost/type_traits/remove_all_extents.hpp create mode 100644 third_party/boost/libs/type_traits/include/boost/type_traits/remove_bounds.hpp create mode 100644 third_party/boost/libs/type_traits/include/boost/type_traits/remove_const.hpp create mode 100644 third_party/boost/libs/type_traits/include/boost/type_traits/remove_cv.hpp create mode 100644 third_party/boost/libs/type_traits/include/boost/type_traits/remove_cv_ref.hpp create mode 100644 third_party/boost/libs/type_traits/include/boost/type_traits/remove_extent.hpp create mode 100644 third_party/boost/libs/type_traits/include/boost/type_traits/remove_pointer.hpp create mode 100644 third_party/boost/libs/type_traits/include/boost/type_traits/remove_reference.hpp create mode 100644 third_party/boost/libs/type_traits/include/boost/type_traits/remove_volatile.hpp create mode 100644 third_party/boost/libs/type_traits/include/boost/type_traits/same_traits.hpp create mode 100644 third_party/boost/libs/type_traits/include/boost/type_traits/transform_traits.hpp create mode 100644 third_party/boost/libs/type_traits/include/boost/type_traits/type_identity.hpp create mode 100644 third_party/boost/libs/type_traits/include/boost/type_traits/type_with_alignment.hpp create mode 100644 third_party/boost/libs/type_traits/include/boost/utility/declval.hpp diff --git a/third_party/CMakeLists.txt b/third_party/CMakeLists.txt index 77cad0309c8..a2cf8f1a271 100644 --- a/third_party/CMakeLists.txt +++ b/third_party/CMakeLists.txt @@ -15,4 +15,7 @@ set(USE_AVX512 OFF) # libraries set(CMAKE_POSITION_INDEPENDENT_CODE ON) -add_subdirectory(JoltPhysics/Build) +add_subdirectory(JoltPhysics/Build EXCLUDE_FROM_ALL) + +# Boost libraries +add_subdirectory(boost EXCLUDE_FROM_ALL) diff --git a/third_party/boost/CMakeLists.txt b/third_party/boost/CMakeLists.txt new file mode 100644 index 00000000000..9fbe5f0fc01 --- /dev/null +++ b/third_party/boost/CMakeLists.txt @@ -0,0 +1,30 @@ +# Copyright 2019, 2021 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 + +# Customized for Thrive to just include the needed info + +cmake_minimum_required(VERSION 3.5...3.16) + +# The default build type must be set before project() +if(CMAKE_SOURCE_DIR STREQUAL CMAKE_CURRENT_SOURCE_DIR AND NOT CMAKE_BUILD_TYPE AND NOT CMAKE_CONFIGURATION_TYPES) + set(CMAKE_BUILD_TYPE Release CACHE STRING "Build type" FORCE) + set_property(CACHE CMAKE_BUILD_TYPE PROPERTY STRINGS "Debug" "Release" "MinSizeRel" "RelWithDebInfo") +endif() + +project(Boost VERSION 1.82.0 LANGUAGES CXX) + +set(BOOST_SUPERPROJECT_VERSION ${PROJECT_VERSION}) +set(BOOST_SUPERPROJECT_SOURCE_DIR ${PROJECT_SOURCE_DIR}) + +list(APPEND CMAKE_MODULE_PATH ${PROJECT_SOURCE_DIR}/tools/cmake/include) + +add_subdirectory(libs/assert) +add_subdirectory(libs/config) +add_subdirectory(libs/container_hash) +add_subdirectory(libs/describe) +add_subdirectory(libs/intrusive) +add_subdirectory(libs/move) +add_subdirectory(libs/mp11) +add_subdirectory(libs/static_assert) +add_subdirectory(libs/type_traits) diff --git a/third_party/boost/LICENSE_1_0.txt b/third_party/boost/LICENSE_1_0.txt new file mode 100644 index 00000000000..36b7cd93cdf --- /dev/null +++ b/third_party/boost/LICENSE_1_0.txt @@ -0,0 +1,23 @@ +Boost Software License - Version 1.0 - August 17th, 2003 + +Permission is hereby granted, free of charge, to any person or organization +obtaining a copy of the software and accompanying documentation covered by +this license (the "Software") to use, reproduce, display, distribute, +execute, and transmit the Software, and to prepare derivative works of the +Software, and to permit third-parties to whom the Software is furnished to +do so, all subject to the following: + +The copyright notices in the Software and this entire statement, including +the above license grant, this restriction and the following disclaimer, +must be included in all copies of the Software, in whole or in part, and +all derivative works of the Software, unless such copies or derivative +works are solely in the form of machine-executable object code generated by +a source language processor. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT +SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE +FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, +ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +DEALINGS IN THE SOFTWARE. diff --git a/third_party/boost/libs/assert/CMakeLists.txt b/third_party/boost/libs/assert/CMakeLists.txt new file mode 100644 index 00000000000..6cfd4f44b36 --- /dev/null +++ b/third_party/boost/libs/assert/CMakeLists.txt @@ -0,0 +1,35 @@ +# Copyright 2018-2023 Peter Dimov +# Distributed under the Boost Software License, Version 1.0. +# https://www.boost.org/LICENSE_1_0.txt + +# We support CMake 3.5, but prefer 3.20 policies and behavior +cmake_minimum_required(VERSION 3.5...3.20) + +project(boost_assert VERSION "${BOOST_SUPERPROJECT_VERSION}" LANGUAGES CXX) + +add_library(boost_assert INTERFACE) +add_library(Boost::assert ALIAS boost_assert) + +target_include_directories(boost_assert INTERFACE include) + +target_link_libraries(boost_assert + INTERFACE + Boost::config +) + +if(CMAKE_VERSION VERSION_GREATER 3.18 AND CMAKE_GENERATOR MATCHES "Visual Studio") + + file(GLOB_RECURSE boost_assert_IDEFILES CONFIGURE_DEPENDS include/*.hpp) + source_group(TREE ${PROJECT_SOURCE_DIR}/include FILES ${boost_assert_IDEFILES} PREFIX "Header Files") + list(APPEND boost_assert_IDEFILES extra/boost_assert.natvis) + target_sources(boost_assert PRIVATE ${boost_assert_IDEFILES}) + +endif() + +# BUILD_TESTING is the standard CTest variable that enables testing + +if(BUILD_TESTING) + + add_subdirectory(test) + +endif() diff --git a/third_party/boost/libs/assert/README.md b/third_party/boost/libs/assert/README.md new file mode 100644 index 00000000000..271c5a688a7 --- /dev/null +++ b/third_party/boost/libs/assert/README.md @@ -0,0 +1,13 @@ +# Boost.Assert + +The Boost.Assert library, part of the collection of [Boost C++ Libraries](http://github.com/boostorg), +provides several configurable diagnostic macros similar in behavior and purpose to the standard macro +`assert` from ``. + +## Documentation + +See [the documentation](https://boost.org/libs/assert) for more information. + +## License + +Distributed under the [Boost Software License, Version 1.0](http://boost.org/LICENSE_1_0.txt). diff --git a/third_party/boost/libs/assert/include/boost/assert.hpp b/third_party/boost/libs/assert/include/boost/assert.hpp new file mode 100644 index 00000000000..9650d7a2908 --- /dev/null +++ b/third_party/boost/libs/assert/include/boost/assert.hpp @@ -0,0 +1,85 @@ +// +// boost/assert.hpp - BOOST_ASSERT(expr) +// BOOST_ASSERT_MSG(expr, msg) +// BOOST_VERIFY(expr) +// BOOST_VERIFY_MSG(expr, msg) +// BOOST_ASSERT_IS_VOID +// +// Copyright (c) 2001, 2002 Peter Dimov and Multi Media Ltd. +// Copyright (c) 2007, 2014 Peter Dimov +// Copyright (c) Beman Dawes 2011 +// Copyright (c) 2015 Ion Gaztanaga +// +// 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 +// +// Note: There are no include guards. This is intentional. +// +// See http://www.boost.org/libs/assert/assert.html for documentation. +// + +// +// Stop inspect complaining about use of 'assert': +// +// boostinspect:naassert_macro +// + +// +// BOOST_ASSERT, BOOST_ASSERT_MSG, BOOST_ASSERT_IS_VOID +// + +#undef BOOST_ASSERT +#undef BOOST_ASSERT_MSG +#undef BOOST_ASSERT_IS_VOID + +#if defined(BOOST_DISABLE_ASSERTS) || ( defined(BOOST_ENABLE_ASSERT_DEBUG_HANDLER) && defined(NDEBUG) ) + +# define BOOST_ASSERT(expr) ((void)0) +# define BOOST_ASSERT_MSG(expr, msg) ((void)0) +# define BOOST_ASSERT_IS_VOID + +#elif defined(BOOST_ENABLE_ASSERT_HANDLER) || ( defined(BOOST_ENABLE_ASSERT_DEBUG_HANDLER) && !defined(NDEBUG) ) + +#include // for BOOST_LIKELY +#include + +namespace boost +{ + void assertion_failed(char const * expr, char const * function, char const * file, long line); // user defined + void assertion_failed_msg(char const * expr, char const * msg, char const * function, char const * file, long line); // user defined +} // namespace boost + +#define BOOST_ASSERT(expr) (BOOST_LIKELY(!!(expr))? ((void)0): ::boost::assertion_failed(#expr, BOOST_CURRENT_FUNCTION, __FILE__, __LINE__)) +#define BOOST_ASSERT_MSG(expr, msg) (BOOST_LIKELY(!!(expr))? ((void)0): ::boost::assertion_failed_msg(#expr, msg, BOOST_CURRENT_FUNCTION, __FILE__, __LINE__)) + +#else + +# include // .h to support old libraries w/o - effect is the same + +# define BOOST_ASSERT(expr) assert(expr) +# define BOOST_ASSERT_MSG(expr, msg) assert((expr)&&(msg)) +#if defined(NDEBUG) +# define BOOST_ASSERT_IS_VOID +#endif + +#endif + +// +// BOOST_VERIFY, BOOST_VERIFY_MSG +// + +#undef BOOST_VERIFY +#undef BOOST_VERIFY_MSG + +#if defined(BOOST_DISABLE_ASSERTS) || ( !defined(BOOST_ENABLE_ASSERT_HANDLER) && defined(NDEBUG) ) + +# define BOOST_VERIFY(expr) ((void)(expr)) +# define BOOST_VERIFY_MSG(expr, msg) ((void)(expr)) + +#else + +# define BOOST_VERIFY(expr) BOOST_ASSERT(expr) +# define BOOST_VERIFY_MSG(expr, msg) BOOST_ASSERT_MSG(expr,msg) + +#endif diff --git a/third_party/boost/libs/assert/include/boost/assert/source_location.hpp b/third_party/boost/libs/assert/include/boost/assert/source_location.hpp new file mode 100644 index 00000000000..0d768582884 --- /dev/null +++ b/third_party/boost/libs/assert/include/boost/assert/source_location.hpp @@ -0,0 +1,189 @@ +#ifndef BOOST_ASSERT_SOURCE_LOCATION_HPP_INCLUDED +#define BOOST_ASSERT_SOURCE_LOCATION_HPP_INCLUDED + +// http://www.boost.org/libs/assert +// +// 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 +{ + +struct source_location +{ +private: + + char const * file_; + char const * function_; + boost::uint_least32_t line_; + boost::uint_least32_t column_; + +public: + + BOOST_CONSTEXPR source_location() BOOST_NOEXCEPT: file_( "" ), function_( "" ), line_( 0 ), column_( 0 ) + { + } + + BOOST_CONSTEXPR source_location( char const * file, boost::uint_least32_t ln, char const * function, boost::uint_least32_t col = 0 ) BOOST_NOEXCEPT: file_( file ), function_( function ), line_( ln ), column_( col ) + { + } + +#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_; + } + + BOOST_CONSTEXPR char const * function_name() const BOOST_NOEXCEPT + { + return function_; + } + + BOOST_CONSTEXPR boost::uint_least32_t line() const BOOST_NOEXCEPT + { + return line_; + } + + BOOST_CONSTEXPR boost::uint_least32_t column() const BOOST_NOEXCEPT + { + return column_; + } + +#if defined(BOOST_MSVC) +# pragma warning( push ) +# pragma warning( disable: 4996 ) +#endif + +#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 + { + 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( *fn != 0 ) + { + r += " in function '"; + r += fn; + r += '\''; + } + + 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) + +# 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 + +# 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 + +// __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 + +// __func__ macros aren't allowed outside functions, but BOOST_CURRENT_LOCATION is +# define BOOST_CURRENT_LOCATION ::boost::source_location(__FILE__, __LINE__, "") + +#endif + +#endif // #ifndef BOOST_ASSERT_SOURCE_LOCATION_HPP_INCLUDED diff --git a/third_party/boost/libs/assert/include/boost/current_function.hpp b/third_party/boost/libs/assert/include/boost/current_function.hpp new file mode 100644 index 00000000000..731d1b13e55 --- /dev/null +++ b/third_party/boost/libs/assert/include/boost/current_function.hpp @@ -0,0 +1,75 @@ +#ifndef BOOST_CURRENT_FUNCTION_HPP_INCLUDED +#define BOOST_CURRENT_FUNCTION_HPP_INCLUDED + +// MS compatible compilers support #pragma once + +#if defined(_MSC_VER) && (_MSC_VER >= 1020) +# pragma once +#endif + +// +// boost/current_function.hpp - BOOST_CURRENT_FUNCTION +// +// Copyright 2002-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 +// +// http://www.boost.org/libs/assert +// + +namespace boost +{ + +namespace detail +{ + +inline void current_function_helper() +{ + +#if defined( BOOST_DISABLE_CURRENT_FUNCTION ) + +# define BOOST_CURRENT_FUNCTION "(unknown)" + +#elif defined(__GNUC__) || (defined(__MWERKS__) && (__MWERKS__ >= 0x3000)) || (defined(__ICC) && (__ICC >= 600)) || defined(__ghs__) || defined(__clang__) + +# define BOOST_CURRENT_FUNCTION __PRETTY_FUNCTION__ + +#elif defined(__DMC__) && (__DMC__ >= 0x810) + +# define BOOST_CURRENT_FUNCTION __PRETTY_FUNCTION__ + +#elif defined(__FUNCSIG__) + +# define BOOST_CURRENT_FUNCTION __FUNCSIG__ + +#elif (defined(__INTEL_COMPILER) && (__INTEL_COMPILER >= 600)) || (defined(__IBMCPP__) && (__IBMCPP__ >= 500)) + +# define BOOST_CURRENT_FUNCTION __FUNCTION__ + +#elif defined(__BORLANDC__) && (__BORLANDC__ >= 0x550) + +# define BOOST_CURRENT_FUNCTION __FUNC__ + +#elif defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901) + +# define BOOST_CURRENT_FUNCTION __func__ + +#elif defined(__cplusplus) && (__cplusplus >= 201103) + +# define BOOST_CURRENT_FUNCTION __func__ + +#else + +# define BOOST_CURRENT_FUNCTION "(unknown)" + +#endif + +} + +} // namespace detail + +} // namespace boost + +#endif // #ifndef BOOST_CURRENT_FUNCTION_HPP_INCLUDED diff --git a/third_party/boost/libs/config/CMakeLists.txt b/third_party/boost/libs/config/CMakeLists.txt new file mode 100644 index 00000000000..cae8bfd0343 --- /dev/null +++ b/third_party/boost/libs/config/CMakeLists.txt @@ -0,0 +1,14 @@ +# Copyright 2018 Mike Dev +# 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 + +# We support CMake 3.5, but prefer 3.16 policies and behavior +cmake_minimum_required(VERSION 3.5...3.16) + +project(boost_config VERSION "${BOOST_SUPERPROJECT_VERSION}" LANGUAGES CXX) + +add_library(boost_config INTERFACE) +add_library(Boost::config ALIAS boost_config) + +target_include_directories(boost_config INTERFACE include) diff --git a/third_party/boost/libs/config/README.md b/third_party/boost/libs/config/README.md new file mode 100644 index 00000000000..228b0962014 --- /dev/null +++ b/third_party/boost/libs/config/README.md @@ -0,0 +1,43 @@ +Boost Config Library +============================ + +This library provides configuration support for the Boost C++ libraries. + +The full documentation is available on [boost.org](http://www.boost.org/doc/libs/release/libs/config/index.html). + +| | Master | Develop | +|------------------|----------|-------------| +| Drone | [![Build Status](https://drone.cpp.al/api/badges/boostorg/config/status.svg?ref=refs/heads/master)](https://drone.cpp.al/boostorg/config) | [![Build Status](https://drone.cpp.al/api/badges/boostorg/config/status.svg)](https://drone.cpp.al/boostorg/config) | +| Travis | [![Build Status](https://travis-ci.org/boostorg/config.svg?branch=master)](https://travis-ci.org/boostorg/config) | [![Build Status](https://travis-ci.org/boostorg/config.png)](https://travis-ci.org/boostorg/config) | +| Appveyor | [![Build status](https://ci.appveyor.com/api/projects/status/wo2n2mhoy8vegmuo/branch/master?svg=true)](https://ci.appveyor.com/project/jzmaddock/config/branch/master) | [![Build status](https://ci.appveyor.com/api/projects/status/wo2n2mhoy8vegmuo/branch/develop?svg=true)](https://ci.appveyor.com/project/jzmaddock/config/branch/develop) | + +## Support, bugs and feature requests ## + +Bugs and feature requests can be reported through the [Gitub issue tracker](https://github.com/boostorg/config/issues) +(see [open issues](https://github.com/boostorg/config/issues) and +[closed issues](https://github.com/boostorg/config/issues?utf8=%E2%9C%93&q=is%3Aissue+is%3Aclosed)). + +You can submit your changes through a [pull request](https://github.com/boostorg/config/pulls). + +There is no mailing-list specific to Boost Config, although you can use the general-purpose Boost [mailing-list](http://lists.boost.org/mailman/listinfo.cgi/boost-users) using the tag [config]. + + +## Development ## + +Clone the whole boost project, which includes the individual Boost projects as submodules ([see boost+git doc](https://github.com/boostorg/boost/wiki/Getting-Started)): + + git clone https://github.com/boostorg/boost + cd boost + git submodule update --init + +The Boost Config Library is located in `libs/config/`. + +### Running tests ### +First, make sure you are in `libs/config/test`. +You can either run all the tests listed in `Jamfile.v2` or run a single test: + + ../../../b2 <- run all tests + ../../../b2 config_info <- single test + +### For developers ### +Please check the [Guidelines for Boost Authors](http://www.boost.org/doc/libs/release/libs/config/doc/html/boost_config/guidelines_for_boost_authors.html). from the full documentation. diff --git a/third_party/boost/libs/config/include/boost/config.hpp b/third_party/boost/libs/config/include/boost/config.hpp new file mode 100644 index 00000000000..f00a9805790 --- /dev/null +++ b/third_party/boost/libs/config/include/boost/config.hpp @@ -0,0 +1,67 @@ +// Boost config.hpp configuration header file ------------------------------// + +// (C) Copyright John Maddock 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/libs/config for most recent version. + +// Boost config.hpp policy and rationale documentation has been moved to +// http://www.boost.org/libs/config +// +// CAUTION: This file is intended to be completely stable - +// DO NOT MODIFY THIS FILE! +// + +#ifndef BOOST_CONFIG_HPP +#define BOOST_CONFIG_HPP + +// if we don't have a user config, then use the default location: +#if !defined(BOOST_USER_CONFIG) && !defined(BOOST_NO_USER_CONFIG) +# define BOOST_USER_CONFIG +#if 0 +// For dependency trackers: +# include +#endif +#endif +// include it first: +#ifdef BOOST_USER_CONFIG +# include BOOST_USER_CONFIG +#endif + +// if we don't have a compiler config set, try and find one: +#if !defined(BOOST_COMPILER_CONFIG) && !defined(BOOST_NO_COMPILER_CONFIG) && !defined(BOOST_NO_CONFIG) +# include +#endif +// if we have a compiler config, include it now: +#ifdef BOOST_COMPILER_CONFIG +# include BOOST_COMPILER_CONFIG +#endif + +// if we don't have a std library config set, try and find one: +#if !defined(BOOST_STDLIB_CONFIG) && !defined(BOOST_NO_STDLIB_CONFIG) && !defined(BOOST_NO_CONFIG) && defined(__cplusplus) +# include +#endif +// if we have a std library config, include it now: +#ifdef BOOST_STDLIB_CONFIG +# include BOOST_STDLIB_CONFIG +#endif + +// if we don't have a platform config set, try and find one: +#if !defined(BOOST_PLATFORM_CONFIG) && !defined(BOOST_NO_PLATFORM_CONFIG) && !defined(BOOST_NO_CONFIG) +# include +#endif +// if we have a platform config, include it now: +#ifdef BOOST_PLATFORM_CONFIG +# include BOOST_PLATFORM_CONFIG +#endif + +// get config suffix code: +#include + +#ifdef BOOST_HAS_PRAGMA_ONCE +#pragma once +#endif + +#endif // BOOST_CONFIG_HPP diff --git a/third_party/boost/libs/config/include/boost/config/abi/borland_prefix.hpp b/third_party/boost/libs/config/include/boost/config/abi/borland_prefix.hpp new file mode 100644 index 00000000000..3a0e5ae2d77 --- /dev/null +++ b/third_party/boost/libs/config/include/boost/config/abi/borland_prefix.hpp @@ -0,0 +1,27 @@ +// (C) Copyright John Maddock 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) + +// for C++ Builder the following options effect the ABI: +// +// -b (on or off - effect emum sizes) +// -Vx (on or off - empty members) +// -Ve (on or off - empty base classes) +// -aX (alignment - 5 options). +// -pX (Calling convention - 4 options) +// -VmX (member pointer size and layout - 5 options) +// -VC (on or off, changes name mangling) +// -Vl (on or off, changes struct layout). + +// In addition the following warnings are sufficiently annoying (and +// unfixable) to have them turned off by default: +// +// 8027 - functions containing [for|while] loops are not expanded inline +// 8026 - functions taking class by value arguments are not expanded inline + +#pragma nopushoptwarn +# pragma option push -a8 -Vx- -Ve- -b- -pc -Vmv -VC- -Vl- -w-8027 -w-8026 + + + diff --git a/third_party/boost/libs/config/include/boost/config/abi/borland_suffix.hpp b/third_party/boost/libs/config/include/boost/config/abi/borland_suffix.hpp new file mode 100644 index 00000000000..940535f3819 --- /dev/null +++ b/third_party/boost/libs/config/include/boost/config/abi/borland_suffix.hpp @@ -0,0 +1,12 @@ +// (C) Copyright John Maddock 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) + +# pragma option pop +#pragma nopushoptwarn + + + + + diff --git a/third_party/boost/libs/config/include/boost/config/abi/msvc_prefix.hpp b/third_party/boost/libs/config/include/boost/config/abi/msvc_prefix.hpp new file mode 100644 index 00000000000..97f06cdc0c2 --- /dev/null +++ b/third_party/boost/libs/config/include/boost/config/abi/msvc_prefix.hpp @@ -0,0 +1,22 @@ +// (C) Copyright John Maddock 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) + +// +// Boost binaries are built with the compiler's default ABI settings, +// if the user changes their default alignment in the VS IDE then their +// code will no longer be binary compatible with the bjam built binaries +// unless this header is included to force Boost code into a consistent ABI. +// +// Note that inclusion of this header is only necessary for libraries with +// separate source, header only libraries DO NOT need this as long as all +// translation units are built with the same options. +// +#if defined(_M_X64) +# pragma pack(push,16) +#else +# pragma pack(push,8) +#endif + + diff --git a/third_party/boost/libs/config/include/boost/config/abi/msvc_suffix.hpp b/third_party/boost/libs/config/include/boost/config/abi/msvc_suffix.hpp new file mode 100644 index 00000000000..a64d783eb0f --- /dev/null +++ b/third_party/boost/libs/config/include/boost/config/abi/msvc_suffix.hpp @@ -0,0 +1,8 @@ +// (C) Copyright John Maddock 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) + +#pragma pack(pop) + + diff --git a/third_party/boost/libs/config/include/boost/config/abi_prefix.hpp b/third_party/boost/libs/config/include/boost/config/abi_prefix.hpp new file mode 100644 index 00000000000..bcdc26d9dc8 --- /dev/null +++ b/third_party/boost/libs/config/include/boost/config/abi_prefix.hpp @@ -0,0 +1,25 @@ +// abi_prefix header -------------------------------------------------------// + +// (c) Copyright John Maddock 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). + +#ifndef BOOST_CONFIG_ABI_PREFIX_HPP +# define BOOST_CONFIG_ABI_PREFIX_HPP +#else +# error double inclusion of header boost/config/abi_prefix.hpp is an error +#endif + +#include + +// this must occur after all other includes and before any code appears: +#ifdef BOOST_HAS_ABI_HEADERS +# include BOOST_ABI_PREFIX +#endif + +#if defined( BOOST_BORLANDC ) +#pragma nopushoptwarn +#endif + diff --git a/third_party/boost/libs/config/include/boost/config/abi_suffix.hpp b/third_party/boost/libs/config/include/boost/config/abi_suffix.hpp new file mode 100644 index 00000000000..a1eb78db90a --- /dev/null +++ b/third_party/boost/libs/config/include/boost/config/abi_suffix.hpp @@ -0,0 +1,25 @@ +// abi_sufffix header -------------------------------------------------------// + +// (c) Copyright John Maddock 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). + +// This header should be #included AFTER code that was preceded by a #include +// . + +#ifndef BOOST_CONFIG_ABI_PREFIX_HPP +# error Header boost/config/abi_suffix.hpp must only be used after boost/config/abi_prefix.hpp +#else +# undef BOOST_CONFIG_ABI_PREFIX_HPP +#endif + +// the suffix header occurs after all of our code: +#ifdef BOOST_HAS_ABI_HEADERS +# include BOOST_ABI_SUFFIX +#endif + +#if defined( BOOST_BORLANDC ) +#pragma nopushoptwarn +#endif diff --git a/third_party/boost/libs/config/include/boost/config/assert_cxx03.hpp b/third_party/boost/libs/config/include/boost/config/assert_cxx03.hpp new file mode 100644 index 00000000000..03360a93225 --- /dev/null +++ b/third_party/boost/libs/config/include/boost/config/assert_cxx03.hpp @@ -0,0 +1,211 @@ +// 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$ +// + +#include + +#ifdef BOOST_NO_ADL_BARRIER +# error "Your compiler appears not to be fully C++03 compliant. Detected via defect macro BOOST_NO_ADL_BARRIER." +#endif +#ifdef BOOST_NO_ARGUMENT_DEPENDENT_LOOKUP +# error "Your compiler appears not to be fully C++03 compliant. Detected via defect macro BOOST_NO_ARGUMENT_DEPENDENT_LOOKUP." +#endif +#ifdef BOOST_NO_ARRAY_TYPE_SPECIALIZATIONS +# error "Your compiler appears not to be fully C++03 compliant. Detected via defect macro BOOST_NO_ARRAY_TYPE_SPECIALIZATIONS." +#endif +#ifdef BOOST_NO_COMPLETE_VALUE_INITIALIZATION +# error "Your compiler appears not to be fully C++03 compliant. Detected via defect macro BOOST_NO_COMPLETE_VALUE_INITIALIZATION." +#endif +#ifdef BOOST_NO_CTYPE_FUNCTIONS +# error "Your compiler appears not to be fully C++03 compliant. Detected via defect macro BOOST_NO_CTYPE_FUNCTIONS." +#endif +#ifdef BOOST_NO_CV_SPECIALIZATIONS +# error "Your compiler appears not to be fully C++03 compliant. Detected via defect macro BOOST_NO_CV_SPECIALIZATIONS." +#endif +#ifdef BOOST_NO_CV_VOID_SPECIALIZATIONS +# error "Your compiler appears not to be fully C++03 compliant. Detected via defect macro BOOST_NO_CV_VOID_SPECIALIZATIONS." +#endif +#ifdef BOOST_NO_CWCHAR +# error "Your compiler appears not to be fully C++03 compliant. Detected via defect macro BOOST_NO_CWCHAR." +#endif +#ifdef BOOST_NO_CWCTYPE +# error "Your compiler appears not to be fully C++03 compliant. Detected via defect macro BOOST_NO_CWCTYPE." +#endif +#ifdef BOOST_NO_DEPENDENT_NESTED_DERIVATIONS +# error "Your compiler appears not to be fully C++03 compliant. Detected via defect macro BOOST_NO_DEPENDENT_NESTED_DERIVATIONS." +#endif +#ifdef BOOST_NO_DEPENDENT_TYPES_IN_TEMPLATE_VALUE_PARAMETERS +# error "Your compiler appears not to be fully C++03 compliant. Detected via defect macro BOOST_NO_DEPENDENT_TYPES_IN_TEMPLATE_VALUE_PARAMETERS." +#endif +#ifdef BOOST_NO_EXCEPTIONS +# error "Your compiler appears not to be fully C++03 compliant. Detected via defect macro BOOST_NO_EXCEPTIONS." +#endif +#ifdef BOOST_NO_EXCEPTION_STD_NAMESPACE +# error "Your compiler appears not to be fully C++03 compliant. Detected via defect macro BOOST_NO_EXCEPTION_STD_NAMESPACE." +#endif +#ifdef BOOST_NO_EXPLICIT_FUNCTION_TEMPLATE_ARGUMENTS +# error "Your compiler appears not to be fully C++03 compliant. Detected via defect macro BOOST_NO_EXPLICIT_FUNCTION_TEMPLATE_ARGUMENTS." +#endif +#ifdef BOOST_NO_FENV_H +# error "Your compiler appears not to be fully C++03 compliant. Detected via defect macro BOOST_NO_FENV_H." +#endif +#ifdef BOOST_NO_FUNCTION_TEMPLATE_ORDERING +# error "Your compiler appears not to be fully C++03 compliant. Detected via defect macro BOOST_NO_FUNCTION_TEMPLATE_ORDERING." +#endif +#ifdef BOOST_NO_FUNCTION_TYPE_SPECIALIZATIONS +# error "Your compiler appears not to be fully C++03 compliant. Detected via defect macro BOOST_NO_FUNCTION_TYPE_SPECIALIZATIONS." +#endif +#ifdef BOOST_NO_INCLASS_MEMBER_INITIALIZATION +# error "Your compiler appears not to be fully C++03 compliant. Detected via defect macro BOOST_NO_INCLASS_MEMBER_INITIALIZATION." +#endif +#ifdef BOOST_NO_INTEGRAL_INT64_T +# error "Your compiler appears not to be fully C++03 compliant. Detected via defect macro BOOST_NO_INTEGRAL_INT64_T." +#endif +#ifdef BOOST_NO_INTRINSIC_WCHAR_T +# error "Your compiler appears not to be fully C++03 compliant. Detected via defect macro BOOST_NO_INTRINSIC_WCHAR_T." +#endif +#ifdef BOOST_NO_IOSFWD +# error "Your compiler appears not to be fully C++03 compliant. Detected via defect macro BOOST_NO_IOSFWD." +#endif +#ifdef BOOST_NO_IOSTREAM +# error "Your compiler appears not to be fully C++03 compliant. Detected via defect macro BOOST_NO_IOSTREAM." +#endif +#ifdef BOOST_NO_IS_ABSTRACT +# error "Your compiler appears not to be fully C++03 compliant. Detected via defect macro BOOST_NO_IS_ABSTRACT." +#endif +#ifdef BOOST_NO_LIMITS +# error "Your compiler appears not to be fully C++03 compliant. Detected via defect macro BOOST_NO_LIMITS." +#endif +#ifdef BOOST_NO_LIMITS_COMPILE_TIME_CONSTANTS +# error "Your compiler appears not to be fully C++03 compliant. Detected via defect macro BOOST_NO_LIMITS_COMPILE_TIME_CONSTANTS." +#endif +#ifdef BOOST_NO_LONG_LONG +# error "Your compiler appears not to be fully C++03 compliant. Detected via defect macro BOOST_NO_LONG_LONG." +#endif +#ifdef BOOST_NO_LONG_LONG_NUMERIC_LIMITS +# error "Your compiler appears not to be fully C++03 compliant. Detected via defect macro BOOST_NO_LONG_LONG_NUMERIC_LIMITS." +#endif +#ifdef BOOST_NO_MEMBER_FUNCTION_SPECIALIZATIONS +# error "Your compiler appears not to be fully C++03 compliant. Detected via defect macro BOOST_NO_MEMBER_FUNCTION_SPECIALIZATIONS." +#endif +#ifdef BOOST_NO_MEMBER_TEMPLATES +# error "Your compiler appears not to be fully C++03 compliant. Detected via defect macro BOOST_NO_MEMBER_TEMPLATES." +#endif +#ifdef BOOST_NO_MEMBER_TEMPLATE_FRIENDS +# error "Your compiler appears not to be fully C++03 compliant. Detected via defect macro BOOST_NO_MEMBER_TEMPLATE_FRIENDS." +#endif +#ifdef BOOST_NO_MEMBER_TEMPLATE_KEYWORD +# error "Your compiler appears not to be fully C++03 compliant. Detected via defect macro BOOST_NO_MEMBER_TEMPLATE_KEYWORD." +#endif +#ifdef BOOST_NO_NESTED_FRIENDSHIP +# error "Your compiler appears not to be fully C++03 compliant. Detected via defect macro BOOST_NO_NESTED_FRIENDSHIP." +#endif +#ifdef BOOST_NO_OPERATORS_IN_NAMESPACE +# error "Your compiler appears not to be fully C++03 compliant. Detected via defect macro BOOST_NO_OPERATORS_IN_NAMESPACE." +#endif +#ifdef BOOST_NO_PARTIAL_SPECIALIZATION_IMPLICIT_DEFAULT_ARGS +# error "Your compiler appears not to be fully C++03 compliant. Detected via defect macro BOOST_NO_PARTIAL_SPECIALIZATION_IMPLICIT_DEFAULT_ARGS." +#endif +#ifdef BOOST_NO_POINTER_TO_MEMBER_CONST +# error "Your compiler appears not to be fully C++03 compliant. Detected via defect macro BOOST_NO_POINTER_TO_MEMBER_CONST." +#endif +#ifdef BOOST_NO_POINTER_TO_MEMBER_TEMPLATE_PARAMETERS +# error "Your compiler appears not to be fully C++03 compliant. Detected via defect macro BOOST_NO_POINTER_TO_MEMBER_TEMPLATE_PARAMETERS." +#endif +#ifdef BOOST_NO_PRIVATE_IN_AGGREGATE +# error "Your compiler appears not to be fully C++03 compliant. Detected via defect macro BOOST_NO_PRIVATE_IN_AGGREGATE." +#endif +#ifdef BOOST_NO_RESTRICT_REFERENCES +# error "Your compiler appears not to be fully C++03 compliant. Detected via defect macro BOOST_NO_RESTRICT_REFERENCES." +#endif +#ifdef BOOST_NO_RTTI +# error "Your compiler appears not to be fully C++03 compliant. Detected via defect macro BOOST_NO_RTTI." +#endif +#ifdef BOOST_NO_SFINAE +# error "Your compiler appears not to be fully C++03 compliant. Detected via defect macro BOOST_NO_SFINAE." +#endif +#ifdef BOOST_NO_SFINAE_EXPR +# error "Your compiler appears not to be fully C++03 compliant. Detected via defect macro BOOST_NO_SFINAE_EXPR." +#endif +#ifdef BOOST_NO_STDC_NAMESPACE +# error "Your compiler appears not to be fully C++03 compliant. Detected via defect macro BOOST_NO_STDC_NAMESPACE." +#endif +#ifdef BOOST_NO_STD_ALLOCATOR +# error "Your compiler appears not to be fully C++03 compliant. Detected via defect macro BOOST_NO_STD_ALLOCATOR." +#endif +#ifdef BOOST_NO_STD_DISTANCE +# error "Your compiler appears not to be fully C++03 compliant. Detected via defect macro BOOST_NO_STD_DISTANCE." +#endif +#ifdef BOOST_NO_STD_ITERATOR +# error "Your compiler appears not to be fully C++03 compliant. Detected via defect macro BOOST_NO_STD_ITERATOR." +#endif +#ifdef BOOST_NO_STD_ITERATOR_TRAITS +# error "Your compiler appears not to be fully C++03 compliant. Detected via defect macro BOOST_NO_STD_ITERATOR_TRAITS." +#endif +#ifdef BOOST_NO_STD_LOCALE +# error "Your compiler appears not to be fully C++03 compliant. Detected via defect macro BOOST_NO_STD_LOCALE." +#endif +#ifdef BOOST_NO_STD_MESSAGES +# error "Your compiler appears not to be fully C++03 compliant. Detected via defect macro BOOST_NO_STD_MESSAGES." +#endif +#ifdef BOOST_NO_STD_MIN_MAX +# error "Your compiler appears not to be fully C++03 compliant. Detected via defect macro BOOST_NO_STD_MIN_MAX." +#endif +#ifdef BOOST_NO_STD_OUTPUT_ITERATOR_ASSIGN +# error "Your compiler appears not to be fully C++03 compliant. Detected via defect macro BOOST_NO_STD_OUTPUT_ITERATOR_ASSIGN." +#endif +#ifdef BOOST_NO_STD_TYPEINFO +# error "Your compiler appears not to be fully C++03 compliant. Detected via defect macro BOOST_NO_STD_TYPEINFO." +#endif +#ifdef BOOST_NO_STD_USE_FACET +# error "Your compiler appears not to be fully C++03 compliant. Detected via defect macro BOOST_NO_STD_USE_FACET." +#endif +#ifdef BOOST_NO_STD_WSTREAMBUF +# error "Your compiler appears not to be fully C++03 compliant. Detected via defect macro BOOST_NO_STD_WSTREAMBUF." +#endif +#ifdef BOOST_NO_STD_WSTRING +# error "Your compiler appears not to be fully C++03 compliant. Detected via defect macro BOOST_NO_STD_WSTRING." +#endif +#ifdef BOOST_NO_STRINGSTREAM +# error "Your compiler appears not to be fully C++03 compliant. Detected via defect macro BOOST_NO_STRINGSTREAM." +#endif +#ifdef BOOST_NO_TEMPLATED_IOSTREAMS +# error "Your compiler appears not to be fully C++03 compliant. Detected via defect macro BOOST_NO_TEMPLATED_IOSTREAMS." +#endif +#ifdef BOOST_NO_TEMPLATED_ITERATOR_CONSTRUCTORS +# error "Your compiler appears not to be fully C++03 compliant. Detected via defect macro BOOST_NO_TEMPLATED_ITERATOR_CONSTRUCTORS." +#endif +#ifdef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION +# error "Your compiler appears not to be fully C++03 compliant. Detected via defect macro BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION." +#endif +#ifdef BOOST_NO_TEMPLATE_TEMPLATES +# error "Your compiler appears not to be fully C++03 compliant. Detected via defect macro BOOST_NO_TEMPLATE_TEMPLATES." +#endif +#ifdef BOOST_NO_TWO_PHASE_NAME_LOOKUP +# error "Your compiler appears not to be fully C++03 compliant. Detected via defect macro BOOST_NO_TWO_PHASE_NAME_LOOKUP." +#endif +#ifdef BOOST_NO_TYPEID +# error "Your compiler appears not to be fully C++03 compliant. Detected via defect macro BOOST_NO_TYPEID." +#endif +#ifdef BOOST_NO_TYPENAME_WITH_CTOR +# error "Your compiler appears not to be fully C++03 compliant. Detected via defect macro BOOST_NO_TYPENAME_WITH_CTOR." +#endif +#ifdef BOOST_NO_UNREACHABLE_RETURN_DETECTION +# error "Your compiler appears not to be fully C++03 compliant. Detected via defect macro BOOST_NO_UNREACHABLE_RETURN_DETECTION." +#endif +#ifdef BOOST_NO_USING_DECLARATION_OVERLOADS_FROM_TYPENAME_BASE +# error "Your compiler appears not to be fully C++03 compliant. Detected via defect macro BOOST_NO_USING_DECLARATION_OVERLOADS_FROM_TYPENAME_BASE." +#endif +#ifdef BOOST_NO_USING_TEMPLATE +# error "Your compiler appears not to be fully C++03 compliant. Detected via defect macro BOOST_NO_USING_TEMPLATE." +#endif +#ifdef BOOST_NO_VOID_RETURNS +# error "Your compiler appears not to be fully C++03 compliant. Detected via defect macro BOOST_NO_VOID_RETURNS." +#endif diff --git a/third_party/boost/libs/config/include/boost/config/assert_cxx11.hpp b/third_party/boost/libs/config/include/boost/config/assert_cxx11.hpp new file mode 100644 index 00000000000..b029a274850 --- /dev/null +++ b/third_party/boost/libs/config/include/boost/config/assert_cxx11.hpp @@ -0,0 +1,209 @@ +// 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$ +// + +#include +#include + +#ifdef BOOST_NO_CXX11_ADDRESSOF +# error "Your compiler appears not to be fully C++11 compliant. Detected via defect macro BOOST_NO_CXX11_ADDRESSOF." +#endif +#ifdef BOOST_NO_CXX11_ALIGNAS +# error "Your compiler appears not to be fully C++11 compliant. Detected via defect macro BOOST_NO_CXX11_ALIGNAS." +#endif +#ifdef BOOST_NO_CXX11_ALLOCATOR +# error "Your compiler appears not to be fully C++11 compliant. Detected via defect macro BOOST_NO_CXX11_ALLOCATOR." +#endif +#ifdef BOOST_NO_CXX11_AUTO_DECLARATIONS +# error "Your compiler appears not to be fully C++11 compliant. Detected via defect macro BOOST_NO_CXX11_AUTO_DECLARATIONS." +#endif +#ifdef BOOST_NO_CXX11_AUTO_MULTIDECLARATIONS +# error "Your compiler appears not to be fully C++11 compliant. Detected via defect macro BOOST_NO_CXX11_AUTO_MULTIDECLARATIONS." +#endif +#ifdef BOOST_NO_CXX11_CHAR16_T +# error "Your compiler appears not to be fully C++11 compliant. Detected via defect macro BOOST_NO_CXX11_CHAR16_T." +#endif +#ifdef BOOST_NO_CXX11_CHAR32_T +# error "Your compiler appears not to be fully C++11 compliant. Detected via defect macro BOOST_NO_CXX11_CHAR32_T." +#endif +#ifdef BOOST_NO_CXX11_CONSTEXPR +# error "Your compiler appears not to be fully C++11 compliant. Detected via defect macro BOOST_NO_CXX11_CONSTEXPR." +#endif +#ifdef BOOST_NO_CXX11_DECLTYPE +# error "Your compiler appears not to be fully C++11 compliant. Detected via defect macro BOOST_NO_CXX11_DECLTYPE." +#endif +#ifdef BOOST_NO_CXX11_DECLTYPE_N3276 +# error "Your compiler appears not to be fully C++11 compliant. Detected via defect macro BOOST_NO_CXX11_DECLTYPE_N3276." +#endif +#ifdef BOOST_NO_CXX11_DEFAULTED_FUNCTIONS +# error "Your compiler appears not to be fully C++11 compliant. Detected via defect macro BOOST_NO_CXX11_DEFAULTED_FUNCTIONS." +#endif +#ifdef BOOST_NO_CXX11_DEFAULTED_MOVES +# error "Your compiler appears not to be fully C++11 compliant. Detected via defect macro BOOST_NO_CXX11_DEFAULTED_MOVES." +#endif +#ifdef BOOST_NO_CXX11_DELETED_FUNCTIONS +# error "Your compiler appears not to be fully C++11 compliant. Detected via defect macro BOOST_NO_CXX11_DELETED_FUNCTIONS." +#endif +#ifdef BOOST_NO_CXX11_EXPLICIT_CONVERSION_OPERATORS +# error "Your compiler appears not to be fully C++11 compliant. Detected via defect macro BOOST_NO_CXX11_EXPLICIT_CONVERSION_OPERATORS." +#endif +#ifdef BOOST_NO_CXX11_EXTERN_TEMPLATE +# error "Your compiler appears not to be fully C++11 compliant. Detected via defect macro BOOST_NO_CXX11_EXTERN_TEMPLATE." +#endif +#ifdef BOOST_NO_CXX11_FINAL +# error "Your compiler appears not to be fully C++11 compliant. Detected via defect macro BOOST_NO_CXX11_FINAL." +#endif +#ifdef BOOST_NO_CXX11_FIXED_LENGTH_VARIADIC_TEMPLATE_EXPANSION_PACKS +# error "Your compiler appears not to be fully C++11 compliant. Detected via defect macro BOOST_NO_CXX11_FIXED_LENGTH_VARIADIC_TEMPLATE_EXPANSION_PACKS." +#endif +#ifdef BOOST_NO_CXX11_FUNCTION_TEMPLATE_DEFAULT_ARGS +# error "Your compiler appears not to be fully C++11 compliant. Detected via defect macro BOOST_NO_CXX11_FUNCTION_TEMPLATE_DEFAULT_ARGS." +#endif +#ifdef BOOST_NO_CXX11_HDR_ARRAY +# error "Your compiler appears not to be fully C++11 compliant. Detected via defect macro BOOST_NO_CXX11_HDR_ARRAY." +#endif +#ifdef BOOST_NO_CXX11_HDR_ATOMIC +# error "Your compiler appears not to be fully C++11 compliant. Detected via defect macro BOOST_NO_CXX11_HDR_ATOMIC." +#endif +#ifdef BOOST_NO_CXX11_HDR_CHRONO +# error "Your compiler appears not to be fully C++11 compliant. Detected via defect macro BOOST_NO_CXX11_HDR_CHRONO." +#endif +#ifdef BOOST_NO_CXX11_HDR_CONDITION_VARIABLE +# error "Your compiler appears not to be fully C++11 compliant. Detected via defect macro BOOST_NO_CXX11_HDR_CONDITION_VARIABLE." +#endif +#ifdef BOOST_NO_CXX11_HDR_EXCEPTION +# error "Your compiler appears not to be fully C++11 compliant. Detected via defect macro BOOST_NO_CXX11_HDR_EXCEPTION." +#endif +#ifdef BOOST_NO_CXX11_HDR_FORWARD_LIST +# error "Your compiler appears not to be fully C++11 compliant. Detected via defect macro BOOST_NO_CXX11_HDR_FORWARD_LIST." +#endif +#ifdef BOOST_NO_CXX11_HDR_FUNCTIONAL +# error "Your compiler appears not to be fully C++11 compliant. Detected via defect macro BOOST_NO_CXX11_HDR_FUNCTIONAL." +#endif +#ifdef BOOST_NO_CXX11_HDR_FUTURE +# error "Your compiler appears not to be fully C++11 compliant. Detected via defect macro BOOST_NO_CXX11_HDR_FUTURE." +#endif +#ifdef BOOST_NO_CXX11_HDR_INITIALIZER_LIST +# error "Your compiler appears not to be fully C++11 compliant. Detected via defect macro BOOST_NO_CXX11_HDR_INITIALIZER_LIST." +#endif +#ifdef BOOST_NO_CXX11_HDR_MUTEX +# error "Your compiler appears not to be fully C++11 compliant. Detected via defect macro BOOST_NO_CXX11_HDR_MUTEX." +#endif +#ifdef BOOST_NO_CXX11_HDR_RANDOM +# error "Your compiler appears not to be fully C++11 compliant. Detected via defect macro BOOST_NO_CXX11_HDR_RANDOM." +#endif +#ifdef BOOST_NO_CXX11_HDR_RATIO +# error "Your compiler appears not to be fully C++11 compliant. Detected via defect macro BOOST_NO_CXX11_HDR_RATIO." +#endif +#ifdef BOOST_NO_CXX11_HDR_REGEX +# error "Your compiler appears not to be fully C++11 compliant. Detected via defect macro BOOST_NO_CXX11_HDR_REGEX." +#endif +#ifdef BOOST_NO_CXX11_HDR_SYSTEM_ERROR +# error "Your compiler appears not to be fully C++11 compliant. Detected via defect macro BOOST_NO_CXX11_HDR_SYSTEM_ERROR." +#endif +#ifdef BOOST_NO_CXX11_HDR_THREAD +# error "Your compiler appears not to be fully C++11 compliant. Detected via defect macro BOOST_NO_CXX11_HDR_THREAD." +#endif +#ifdef BOOST_NO_CXX11_HDR_TUPLE +# error "Your compiler appears not to be fully C++11 compliant. Detected via defect macro BOOST_NO_CXX11_HDR_TUPLE." +#endif +#ifdef BOOST_NO_CXX11_HDR_TYPEINDEX +# error "Your compiler appears not to be fully C++11 compliant. Detected via defect macro BOOST_NO_CXX11_HDR_TYPEINDEX." +#endif +#ifdef BOOST_NO_CXX11_HDR_TYPE_TRAITS +# error "Your compiler appears not to be fully C++11 compliant. Detected via defect macro BOOST_NO_CXX11_HDR_TYPE_TRAITS." +#endif +#ifdef BOOST_NO_CXX11_HDR_UNORDERED_MAP +# error "Your compiler appears not to be fully C++11 compliant. Detected via defect macro BOOST_NO_CXX11_HDR_UNORDERED_MAP." +#endif +#ifdef BOOST_NO_CXX11_HDR_UNORDERED_SET +# error "Your compiler appears not to be fully C++11 compliant. Detected via defect macro BOOST_NO_CXX11_HDR_UNORDERED_SET." +#endif +#ifdef BOOST_NO_CXX11_INLINE_NAMESPACES +# error "Your compiler appears not to be fully C++11 compliant. Detected via defect macro BOOST_NO_CXX11_INLINE_NAMESPACES." +#endif +#ifdef BOOST_NO_CXX11_LAMBDAS +# error "Your compiler appears not to be fully C++11 compliant. Detected via defect macro BOOST_NO_CXX11_LAMBDAS." +#endif +#ifdef BOOST_NO_CXX11_LOCAL_CLASS_TEMPLATE_PARAMETERS +# error "Your compiler appears not to be fully C++11 compliant. Detected via defect macro BOOST_NO_CXX11_LOCAL_CLASS_TEMPLATE_PARAMETERS." +#endif +#ifdef BOOST_NO_CXX11_NOEXCEPT +# error "Your compiler appears not to be fully C++11 compliant. Detected via defect macro BOOST_NO_CXX11_NOEXCEPT." +#endif +#ifdef BOOST_NO_CXX11_NON_PUBLIC_DEFAULTED_FUNCTIONS +# error "Your compiler appears not to be fully C++11 compliant. Detected via defect macro BOOST_NO_CXX11_NON_PUBLIC_DEFAULTED_FUNCTIONS." +#endif +#ifdef BOOST_NO_CXX11_NULLPTR +# error "Your compiler appears not to be fully C++11 compliant. Detected via defect macro BOOST_NO_CXX11_NULLPTR." +#endif +#ifdef BOOST_NO_CXX11_NUMERIC_LIMITS +# error "Your compiler appears not to be fully C++11 compliant. Detected via defect macro BOOST_NO_CXX11_NUMERIC_LIMITS." +#endif +#ifdef BOOST_NO_CXX11_OVERRIDE +# error "Your compiler appears not to be fully C++11 compliant. Detected via defect macro BOOST_NO_CXX11_OVERRIDE." +#endif +#ifdef BOOST_NO_CXX11_POINTER_TRAITS +# error "Your compiler appears not to be fully C++11 compliant. Detected via defect macro BOOST_NO_CXX11_POINTER_TRAITS." +#endif +#ifdef BOOST_NO_CXX11_RANGE_BASED_FOR +# error "Your compiler appears not to be fully C++11 compliant. Detected via defect macro BOOST_NO_CXX11_RANGE_BASED_FOR." +#endif +#ifdef BOOST_NO_CXX11_RAW_LITERALS +# error "Your compiler appears not to be fully C++11 compliant. Detected via defect macro BOOST_NO_CXX11_RAW_LITERALS." +#endif +#ifdef BOOST_NO_CXX11_REF_QUALIFIERS +# error "Your compiler appears not to be fully C++11 compliant. Detected via defect macro BOOST_NO_CXX11_REF_QUALIFIERS." +#endif +#ifdef BOOST_NO_CXX11_RVALUE_REFERENCES +# error "Your compiler appears not to be fully C++11 compliant. Detected via defect macro BOOST_NO_CXX11_RVALUE_REFERENCES." +#endif +#ifdef BOOST_NO_CXX11_SCOPED_ENUMS +# error "Your compiler appears not to be fully C++11 compliant. Detected via defect macro BOOST_NO_CXX11_SCOPED_ENUMS." +#endif +#ifdef BOOST_NO_CXX11_SFINAE_EXPR +# error "Your compiler appears not to be fully C++11 compliant. Detected via defect macro BOOST_NO_CXX11_SFINAE_EXPR." +#endif +#ifdef BOOST_NO_CXX11_SMART_PTR +# error "Your compiler appears not to be fully C++11 compliant. Detected via defect macro BOOST_NO_CXX11_SMART_PTR." +#endif +#ifdef BOOST_NO_CXX11_STATIC_ASSERT +# error "Your compiler appears not to be fully C++11 compliant. Detected via defect macro BOOST_NO_CXX11_STATIC_ASSERT." +#endif +#ifdef BOOST_NO_CXX11_STD_ALIGN +# error "Your compiler appears not to be fully C++11 compliant. Detected via defect macro BOOST_NO_CXX11_STD_ALIGN." +#endif +#ifdef BOOST_NO_CXX11_TEMPLATE_ALIASES +# error "Your compiler appears not to be fully C++11 compliant. Detected via defect macro BOOST_NO_CXX11_TEMPLATE_ALIASES." +#endif +#ifdef BOOST_NO_CXX11_THREAD_LOCAL +# error "Your compiler appears not to be fully C++11 compliant. Detected via defect macro BOOST_NO_CXX11_THREAD_LOCAL." +#endif +#ifdef BOOST_NO_CXX11_TRAILING_RESULT_TYPES +# error "Your compiler appears not to be fully C++11 compliant. Detected via defect macro BOOST_NO_CXX11_TRAILING_RESULT_TYPES." +#endif +#ifdef BOOST_NO_CXX11_UNICODE_LITERALS +# error "Your compiler appears not to be fully C++11 compliant. Detected via defect macro BOOST_NO_CXX11_UNICODE_LITERALS." +#endif +#ifdef BOOST_NO_CXX11_UNIFIED_INITIALIZATION_SYNTAX +# error "Your compiler appears not to be fully C++11 compliant. Detected via defect macro BOOST_NO_CXX11_UNIFIED_INITIALIZATION_SYNTAX." +#endif +#ifdef BOOST_NO_CXX11_UNRESTRICTED_UNION +# error "Your compiler appears not to be fully C++11 compliant. Detected via defect macro BOOST_NO_CXX11_UNRESTRICTED_UNION." +#endif +#ifdef BOOST_NO_CXX11_USER_DEFINED_LITERALS +# error "Your compiler appears not to be fully C++11 compliant. Detected via defect macro BOOST_NO_CXX11_USER_DEFINED_LITERALS." +#endif +#ifdef BOOST_NO_CXX11_VARIADIC_MACROS +# error "Your compiler appears not to be fully C++11 compliant. Detected via defect macro BOOST_NO_CXX11_VARIADIC_MACROS." +#endif +#ifdef BOOST_NO_CXX11_VARIADIC_TEMPLATES +# error "Your compiler appears not to be fully C++11 compliant. Detected via defect macro BOOST_NO_CXX11_VARIADIC_TEMPLATES." +#endif diff --git a/third_party/boost/libs/config/include/boost/config/assert_cxx14.hpp b/third_party/boost/libs/config/include/boost/config/assert_cxx14.hpp new file mode 100644 index 00000000000..1d3132a1d31 --- /dev/null +++ b/third_party/boost/libs/config/include/boost/config/assert_cxx14.hpp @@ -0,0 +1,47 @@ +// 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$ +// + +#include +#include + +#ifdef BOOST_NO_CXX14_AGGREGATE_NSDMI +# error "Your compiler appears not to be fully C++14 compliant. Detected via defect macro BOOST_NO_CXX14_AGGREGATE_NSDMI." +#endif +#ifdef BOOST_NO_CXX14_BINARY_LITERALS +# error "Your compiler appears not to be fully C++14 compliant. Detected via defect macro BOOST_NO_CXX14_BINARY_LITERALS." +#endif +#ifdef BOOST_NO_CXX14_CONSTEXPR +# error "Your compiler appears not to be fully C++14 compliant. Detected via defect macro BOOST_NO_CXX14_CONSTEXPR." +#endif +#ifdef BOOST_NO_CXX14_DECLTYPE_AUTO +# error "Your compiler appears not to be fully C++14 compliant. Detected via defect macro BOOST_NO_CXX14_DECLTYPE_AUTO." +#endif +#ifdef BOOST_NO_CXX14_DIGIT_SEPARATORS +# error "Your compiler appears not to be fully C++14 compliant. Detected via defect macro BOOST_NO_CXX14_DIGIT_SEPARATORS." +#endif +#ifdef BOOST_NO_CXX14_GENERIC_LAMBDAS +# error "Your compiler appears not to be fully C++14 compliant. Detected via defect macro BOOST_NO_CXX14_GENERIC_LAMBDAS." +#endif +#ifdef BOOST_NO_CXX14_HDR_SHARED_MUTEX +# error "Your compiler appears not to be fully C++14 compliant. Detected via defect macro BOOST_NO_CXX14_HDR_SHARED_MUTEX." +#endif +#ifdef BOOST_NO_CXX14_INITIALIZED_LAMBDA_CAPTURES +# error "Your compiler appears not to be fully C++14 compliant. Detected via defect macro BOOST_NO_CXX14_INITIALIZED_LAMBDA_CAPTURES." +#endif +#ifdef BOOST_NO_CXX14_RETURN_TYPE_DEDUCTION +# error "Your compiler appears not to be fully C++14 compliant. Detected via defect macro BOOST_NO_CXX14_RETURN_TYPE_DEDUCTION." +#endif +#ifdef BOOST_NO_CXX14_STD_EXCHANGE +# error "Your compiler appears not to be fully C++14 compliant. Detected via defect macro BOOST_NO_CXX14_STD_EXCHANGE." +#endif +#ifdef BOOST_NO_CXX14_VARIABLE_TEMPLATES +# error "Your compiler appears not to be fully C++14 compliant. Detected via defect macro BOOST_NO_CXX14_VARIABLE_TEMPLATES." +#endif diff --git a/third_party/boost/libs/config/include/boost/config/assert_cxx17.hpp b/third_party/boost/libs/config/include/boost/config/assert_cxx17.hpp new file mode 100644 index 00000000000..cd41be61b44 --- /dev/null +++ b/third_party/boost/libs/config/include/boost/config/assert_cxx17.hpp @@ -0,0 +1,62 @@ +// 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$ +// + +#include +#include + +#ifdef BOOST_NO_CXX17_DEDUCTION_GUIDES +# error "Your compiler appears not to be fully C++17 compliant. Detected via defect macro BOOST_NO_CXX17_DEDUCTION_GUIDES." +#endif +#ifdef BOOST_NO_CXX17_FOLD_EXPRESSIONS +# error "Your compiler appears not to be fully C++17 compliant. Detected via defect macro BOOST_NO_CXX17_FOLD_EXPRESSIONS." +#endif +#ifdef BOOST_NO_CXX17_HDR_ANY +# error "Your compiler appears not to be fully C++17 compliant. Detected via defect macro BOOST_NO_CXX17_HDR_ANY." +#endif +#ifdef BOOST_NO_CXX17_HDR_CHARCONV +# error "Your compiler appears not to be fully C++17 compliant. Detected via defect macro BOOST_NO_CXX17_HDR_CHARCONV." +#endif +#ifdef BOOST_NO_CXX17_HDR_EXECUTION +# error "Your compiler appears not to be fully C++17 compliant. Detected via defect macro BOOST_NO_CXX17_HDR_EXECUTION." +#endif +#ifdef BOOST_NO_CXX17_HDR_FILESYSTEM +# error "Your compiler appears not to be fully C++17 compliant. Detected via defect macro BOOST_NO_CXX17_HDR_FILESYSTEM." +#endif +#ifdef BOOST_NO_CXX17_HDR_MEMORY_RESOURCE +# error "Your compiler appears not to be fully C++17 compliant. Detected via defect macro BOOST_NO_CXX17_HDR_MEMORY_RESOURCE." +#endif +#ifdef BOOST_NO_CXX17_HDR_OPTIONAL +# error "Your compiler appears not to be fully C++17 compliant. Detected via defect macro BOOST_NO_CXX17_HDR_OPTIONAL." +#endif +#ifdef BOOST_NO_CXX17_HDR_STRING_VIEW +# error "Your compiler appears not to be fully C++17 compliant. Detected via defect macro BOOST_NO_CXX17_HDR_STRING_VIEW." +#endif +#ifdef BOOST_NO_CXX17_HDR_VARIANT +# error "Your compiler appears not to be fully C++17 compliant. Detected via defect macro BOOST_NO_CXX17_HDR_VARIANT." +#endif +#ifdef BOOST_NO_CXX17_IF_CONSTEXPR +# error "Your compiler appears not to be fully C++17 compliant. Detected via defect macro BOOST_NO_CXX17_IF_CONSTEXPR." +#endif +#ifdef BOOST_NO_CXX17_INLINE_VARIABLES +# error "Your compiler appears not to be fully C++17 compliant. Detected via defect macro BOOST_NO_CXX17_INLINE_VARIABLES." +#endif +#ifdef BOOST_NO_CXX17_ITERATOR_TRAITS +# error "Your compiler appears not to be fully C++17 compliant. Detected via defect macro BOOST_NO_CXX17_ITERATOR_TRAITS." +#endif +#ifdef BOOST_NO_CXX17_STD_APPLY +# error "Your compiler appears not to be fully C++17 compliant. Detected via defect macro BOOST_NO_CXX17_STD_APPLY." +#endif +#ifdef BOOST_NO_CXX17_STD_INVOKE +# error "Your compiler appears not to be fully C++17 compliant. Detected via defect macro BOOST_NO_CXX17_STD_INVOKE." +#endif +#ifdef BOOST_NO_CXX17_STRUCTURED_BINDINGS +# error "Your compiler appears not to be fully C++17 compliant. Detected via defect macro BOOST_NO_CXX17_STRUCTURED_BINDINGS." +#endif diff --git a/third_party/boost/libs/config/include/boost/config/assert_cxx20.hpp b/third_party/boost/libs/config/include/boost/config/assert_cxx20.hpp new file mode 100644 index 00000000000..c148277856a --- /dev/null +++ b/third_party/boost/libs/config/include/boost/config/assert_cxx20.hpp @@ -0,0 +1,59 @@ +// 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$ +// + +#include +#include + +#ifdef BOOST_NO_CXX20_HDR_BARRIER +# error "Your compiler appears not to be fully C++20 compliant. Detected via defect macro BOOST_NO_CXX20_HDR_BARRIER." +#endif +#ifdef BOOST_NO_CXX20_HDR_BIT +# error "Your compiler appears not to be fully C++20 compliant. Detected via defect macro BOOST_NO_CXX20_HDR_BIT." +#endif +#ifdef BOOST_NO_CXX20_HDR_COMPARE +# error "Your compiler appears not to be fully C++20 compliant. Detected via defect macro BOOST_NO_CXX20_HDR_COMPARE." +#endif +#ifdef BOOST_NO_CXX20_HDR_CONCEPTS +# error "Your compiler appears not to be fully C++20 compliant. Detected via defect macro BOOST_NO_CXX20_HDR_CONCEPTS." +#endif +#ifdef BOOST_NO_CXX20_HDR_COROUTINE +# error "Your compiler appears not to be fully C++20 compliant. Detected via defect macro BOOST_NO_CXX20_HDR_COROUTINE." +#endif +#ifdef BOOST_NO_CXX20_HDR_FORMAT +# error "Your compiler appears not to be fully C++20 compliant. Detected via defect macro BOOST_NO_CXX20_HDR_FORMAT." +#endif +#ifdef BOOST_NO_CXX20_HDR_LATCH +# error "Your compiler appears not to be fully C++20 compliant. Detected via defect macro BOOST_NO_CXX20_HDR_LATCH." +#endif +#ifdef BOOST_NO_CXX20_HDR_NUMBERS +# error "Your compiler appears not to be fully C++20 compliant. Detected via defect macro BOOST_NO_CXX20_HDR_NUMBERS." +#endif +#ifdef BOOST_NO_CXX20_HDR_RANGES +# error "Your compiler appears not to be fully C++20 compliant. Detected via defect macro BOOST_NO_CXX20_HDR_RANGES." +#endif +#ifdef BOOST_NO_CXX20_HDR_SEMAPHORE +# error "Your compiler appears not to be fully C++20 compliant. Detected via defect macro BOOST_NO_CXX20_HDR_SEMAPHORE." +#endif +#ifdef BOOST_NO_CXX20_HDR_SOURCE_LOCATION +# error "Your compiler appears not to be fully C++20 compliant. Detected via defect macro BOOST_NO_CXX20_HDR_SOURCE_LOCATION." +#endif +#ifdef BOOST_NO_CXX20_HDR_SPAN +# error "Your compiler appears not to be fully C++20 compliant. Detected via defect macro BOOST_NO_CXX20_HDR_SPAN." +#endif +#ifdef BOOST_NO_CXX20_HDR_STOP_TOKEN +# error "Your compiler appears not to be fully C++20 compliant. Detected via defect macro BOOST_NO_CXX20_HDR_STOP_TOKEN." +#endif +#ifdef BOOST_NO_CXX20_HDR_SYNCSTREAM +# error "Your compiler appears not to be fully C++20 compliant. Detected via defect macro BOOST_NO_CXX20_HDR_SYNCSTREAM." +#endif +#ifdef BOOST_NO_CXX20_HDR_VERSION +# error "Your compiler appears not to be fully C++20 compliant. Detected via defect macro BOOST_NO_CXX20_HDR_VERSION." +#endif diff --git a/third_party/boost/libs/config/include/boost/config/assert_cxx98.hpp b/third_party/boost/libs/config/include/boost/config/assert_cxx98.hpp new file mode 100644 index 00000000000..aa745d43f98 --- /dev/null +++ b/third_party/boost/libs/config/include/boost/config/assert_cxx98.hpp @@ -0,0 +1,23 @@ +// This file was automatically generated on Wed Mar 3 08:46:11 2021 +// by libs/config/tools/generate.cpp +// Copyright John Maddock 2002-4. +// 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$ +// + +#include +#include + +#ifdef BOOST_NO_CXX98_BINDERS +# error "Your compiler appears not to be fully C++98 compliant. Detected via defect macro BOOST_NO_CXX98_BINDERS." +#endif +#ifdef BOOST_NO_CXX98_FUNCTION_BASE +# error "Your compiler appears not to be fully C++98 compliant. Detected via defect macro BOOST_NO_CXX98_FUNCTION_BASE." +#endif +#ifdef BOOST_NO_CXX98_RANDOM_SHUFFLE +# error "Your compiler appears not to be fully C++98 compliant. Detected via defect macro BOOST_NO_CXX98_RANDOM_SHUFFLE." +#endif diff --git a/third_party/boost/libs/config/include/boost/config/auto_link.hpp b/third_party/boost/libs/config/include/boost/config/auto_link.hpp new file mode 100644 index 00000000000..64dee1ef16f --- /dev/null +++ b/third_party/boost/libs/config/include/boost/config/auto_link.hpp @@ -0,0 +1,525 @@ +// (C) Copyright John Maddock 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) + + /* + * LOCATION: see http://www.boost.org for most recent version. + * FILE auto_link.hpp + * VERSION see + * DESCRIPTION: Automatic library inclusion for Borland/Microsoft compilers. + */ + +/************************************************************************* + +USAGE: +~~~~~~ + +Before including this header you must define one or more of define the following macros: + +BOOST_LIB_NAME: Required: A string containing the basename of the library, + for example boost_regex. +BOOST_LIB_TOOLSET: Optional: the base name of the toolset. +BOOST_DYN_LINK: Optional: when set link to dll rather than static library. +BOOST_LIB_DIAGNOSTIC: Optional: when set the header will print out the name + of the library selected (useful for debugging). +BOOST_AUTO_LINK_NOMANGLE: Specifies that we should link to BOOST_LIB_NAME.lib, + rather than a mangled-name version. +BOOST_AUTO_LINK_TAGGED: Specifies that we link to libraries built with the --layout=tagged option. + This is essentially the same as the default name-mangled version, but without + the compiler name and version, or the Boost version. Just the build options. +BOOST_AUTO_LINK_SYSTEM: Specifies that we link to libraries built with the --layout=system option. + This is essentially the same as the non-name-mangled version, but with + the prefix to differentiate static and dll builds + +These macros will be undef'ed at the end of the header, further this header +has no include guards - so be sure to include it only once from your library! + +Algorithm: +~~~~~~~~~~ + +Libraries for Borland and Microsoft compilers are automatically +selected here, the name of the lib is selected according to the following +formula: + +BOOST_LIB_PREFIX + + BOOST_LIB_NAME + + "_" + + BOOST_LIB_TOOLSET + + BOOST_LIB_THREAD_OPT + + BOOST_LIB_RT_OPT + + BOOST_LIB_ARCH_AND_MODEL_OPT + "-" + + BOOST_LIB_VERSION + + BOOST_LIB_SUFFIX + +These are defined as: + +BOOST_LIB_PREFIX: "lib" for static libraries otherwise "". + +BOOST_LIB_NAME: The base name of the lib ( for example boost_regex). + +BOOST_LIB_TOOLSET: The compiler toolset name (vc6, vc7, bcb5 etc). + +BOOST_LIB_THREAD_OPT: "-mt" for multithread builds, otherwise nothing. + +BOOST_LIB_RT_OPT: A suffix that indicates the runtime library used, + contains one or more of the following letters after + a hyphen: + + s static runtime (dynamic if not present). + g debug/diagnostic runtime (release if not present). + y Python debug/diagnostic runtime (release if not present). + d debug build (release if not present). + p STLport build. + n STLport build without its IOStreams. + +BOOST_LIB_ARCH_AND_MODEL_OPT: The architecture and address model + (-x32 or -x64 for x86/32 and x86/64 respectively) + +BOOST_LIB_VERSION: The Boost version, in the form x_y, for Boost version x.y. + +BOOST_LIB_SUFFIX: Static/import libraries extension (".lib", ".a") for the compiler. + +***************************************************************************/ + +#ifdef __cplusplus +# ifndef BOOST_CONFIG_HPP +# include +# endif +#elif defined(_MSC_VER) && !defined(__MWERKS__) && !defined(__EDG_VERSION__) +// +// C language compatability (no, honestly) +// +# define BOOST_MSVC _MSC_VER +# define BOOST_STRINGIZE(X) BOOST_DO_STRINGIZE(X) +# define BOOST_DO_STRINGIZE(X) #X +#endif +// +// Only include what follows for known and supported compilers: +// +#if defined(BOOST_MSVC) \ + || defined(BOOST_EMBTC_WINDOWS) \ + || defined(BOOST_BORLANDC) \ + || (defined(__MWERKS__) && defined(_WIN32) && (__MWERKS__ >= 0x3000)) \ + || (defined(__ICL) && defined(_MSC_EXTENSIONS) && (_MSC_VER >= 1200)) \ + || (defined(BOOST_CLANG) && defined(BOOST_WINDOWS) && defined(_MSC_VER) && (__clang_major__ >= 4)) + +#ifndef BOOST_VERSION_HPP +# include +#endif + +#ifndef BOOST_LIB_NAME +# error "Macro BOOST_LIB_NAME not set (internal error)" +#endif + +// +// error check: +// +#if defined(__MSVC_RUNTIME_CHECKS) && !defined(_DEBUG) +# pragma message("Using the /RTC option without specifying a debug runtime will lead to linker errors") +# pragma message("Hint: go to the code generation options and switch to one of the debugging runtimes") +# error "Incompatible build options" +#endif +// +// select toolset if not defined already: +// +#ifndef BOOST_LIB_TOOLSET +# if defined(BOOST_MSVC) && (BOOST_MSVC < 1200) + // Note: no compilers before 1200 are supported +# elif defined(BOOST_MSVC) && (BOOST_MSVC < 1300) + +# ifdef UNDER_CE + // eVC4: +# define BOOST_LIB_TOOLSET "evc4" +# else + // vc6: +# define BOOST_LIB_TOOLSET "vc6" +# endif + +# elif defined(BOOST_MSVC) && (BOOST_MSVC < 1310) + + // vc7: +# define BOOST_LIB_TOOLSET "vc7" + +# elif defined(BOOST_MSVC) && (BOOST_MSVC < 1400) + + // vc71: +# define BOOST_LIB_TOOLSET "vc71" + +# elif defined(BOOST_MSVC) && (BOOST_MSVC < 1500) + + // vc80: +# define BOOST_LIB_TOOLSET "vc80" + +# elif defined(BOOST_MSVC) && (BOOST_MSVC < 1600) + + // vc90: +# define BOOST_LIB_TOOLSET "vc90" + +# elif defined(BOOST_MSVC) && (BOOST_MSVC < 1700) + + // vc10: +# define BOOST_LIB_TOOLSET "vc100" + +# elif defined(BOOST_MSVC) && (BOOST_MSVC < 1800) + + // vc11: +# define BOOST_LIB_TOOLSET "vc110" + +# elif defined(BOOST_MSVC) && (BOOST_MSVC < 1900) + + // vc12: +# define BOOST_LIB_TOOLSET "vc120" + +# elif defined(BOOST_MSVC) && (BOOST_MSVC < 1910) + + // vc14: +# define BOOST_LIB_TOOLSET "vc140" + +# elif defined(BOOST_MSVC) && (BOOST_MSVC < 1920) + + // vc14.1: +# define BOOST_LIB_TOOLSET "vc141" + +# elif defined(BOOST_MSVC) && (BOOST_MSVC < 1930) + + // vc14.2: +# define BOOST_LIB_TOOLSET "vc142" + +# elif defined(BOOST_MSVC) + + // vc14.3: +# define BOOST_LIB_TOOLSET "vc143" + +# elif defined(BOOST_EMBTC_WINDOWS) + + // Embarcadero Clang based compilers: +# define BOOST_LIB_TOOLSET "embtc" + +# elif defined(BOOST_BORLANDC) + + // CBuilder 6: +# define BOOST_LIB_TOOLSET "bcb" + +# elif defined(__ICL) + + // Intel C++, no version number: +# define BOOST_LIB_TOOLSET "iw" + +# elif defined(__MWERKS__) && (__MWERKS__ <= 0x31FF ) + + // Metrowerks CodeWarrior 8.x +# define BOOST_LIB_TOOLSET "cw8" + +# elif defined(__MWERKS__) && (__MWERKS__ <= 0x32FF ) + + // Metrowerks CodeWarrior 9.x +# define BOOST_LIB_TOOLSET "cw9" + +# elif defined(BOOST_CLANG) && defined(BOOST_WINDOWS) && defined(_MSC_VER) && (__clang_major__ >= 4) + + // Clang on Windows +# define BOOST_LIB_TOOLSET "clangw" BOOST_STRINGIZE(__clang_major__) + +# endif +#endif // BOOST_LIB_TOOLSET + +// +// select thread opt: +// +#if defined(_MT) || defined(__MT__) +# define BOOST_LIB_THREAD_OPT "-mt" +#else +# define BOOST_LIB_THREAD_OPT +#endif + +#if defined(_MSC_VER) || defined(__MWERKS__) + +# ifdef _DLL + +# if (defined(__SGI_STL_PORT) || defined(_STLPORT_VERSION)) && (defined(_STLP_OWN_IOSTREAMS) || defined(__STL_OWN_IOSTREAMS)) + +# if defined(_DEBUG) && (defined(__STL_DEBUG) || defined(_STLP_DEBUG))\ + && defined(BOOST_DEBUG_PYTHON) && defined(BOOST_LINKING_PYTHON) +# define BOOST_LIB_RT_OPT "-gydp" +# elif defined(_DEBUG) && (defined(__STL_DEBUG) || defined(_STLP_DEBUG)) +# define BOOST_LIB_RT_OPT "-gdp" +# elif defined(_DEBUG)\ + && defined(BOOST_DEBUG_PYTHON) && defined(BOOST_LINKING_PYTHON) +# define BOOST_LIB_RT_OPT "-gydp" +# pragma message("warning: STLport debug versions are built with /D_STLP_DEBUG=1") +# error "Build options aren't compatible with pre-built libraries" +# elif defined(_DEBUG) +# define BOOST_LIB_RT_OPT "-gdp" +# pragma message("warning: STLport debug versions are built with /D_STLP_DEBUG=1") +# error "Build options aren't compatible with pre-built libraries" +# else +# define BOOST_LIB_RT_OPT "-p" +# endif + +# elif defined(__SGI_STL_PORT) || defined(_STLPORT_VERSION) + +# if defined(_DEBUG) && (defined(__STL_DEBUG) || defined(_STLP_DEBUG))\ + && defined(BOOST_DEBUG_PYTHON) && defined(BOOST_LINKING_PYTHON) +# define BOOST_LIB_RT_OPT "-gydpn" +# elif defined(_DEBUG) && (defined(__STL_DEBUG) || defined(_STLP_DEBUG)) +# define BOOST_LIB_RT_OPT "-gdpn" +# elif defined(_DEBUG)\ + && defined(BOOST_DEBUG_PYTHON) && defined(BOOST_LINKING_PYTHON) +# define BOOST_LIB_RT_OPT "-gydpn" +# pragma message("warning: STLport debug versions are built with /D_STLP_DEBUG=1") +# error "Build options aren't compatible with pre-built libraries" +# elif defined(_DEBUG) +# define BOOST_LIB_RT_OPT "-gdpn" +# pragma message("warning: STLport debug versions are built with /D_STLP_DEBUG=1") +# error "Build options aren't compatible with pre-built libraries" +# else +# define BOOST_LIB_RT_OPT "-pn" +# endif + +# else + +# if defined(_DEBUG) && defined(BOOST_DEBUG_PYTHON) && defined(BOOST_LINKING_PYTHON) +# define BOOST_LIB_RT_OPT "-gyd" +# elif defined(_DEBUG) +# define BOOST_LIB_RT_OPT "-gd" +# else +# define BOOST_LIB_RT_OPT +# endif + +# endif + +# else + +# if (defined(__SGI_STL_PORT) || defined(_STLPORT_VERSION)) && (defined(_STLP_OWN_IOSTREAMS) || defined(__STL_OWN_IOSTREAMS)) + +# if defined(_DEBUG) && (defined(__STL_DEBUG) || defined(_STLP_DEBUG))\ + && defined(BOOST_DEBUG_PYTHON) && defined(BOOST_LINKING_PYTHON) +# define BOOST_LIB_RT_OPT "-sgydp" +# elif defined(_DEBUG) && (defined(__STL_DEBUG) || defined(_STLP_DEBUG)) +# define BOOST_LIB_RT_OPT "-sgdp" +# elif defined(_DEBUG)\ + && defined(BOOST_DEBUG_PYTHON) && defined(BOOST_LINKING_PYTHON) +# define BOOST_LIB_RT_OPT "-sgydp" +# pragma message("warning: STLport debug versions are built with /D_STLP_DEBUG=1") +# error "Build options aren't compatible with pre-built libraries" +# elif defined(_DEBUG) +# define BOOST_LIB_RT_OPT "-sgdp" +# pragma message("warning: STLport debug versions are built with /D_STLP_DEBUG=1") +# error "Build options aren't compatible with pre-built libraries" +# else +# define BOOST_LIB_RT_OPT "-sp" +# endif + +# elif defined(__SGI_STL_PORT) || defined(_STLPORT_VERSION) + +# if defined(_DEBUG) && (defined(__STL_DEBUG) || defined(_STLP_DEBUG))\ + && defined(BOOST_DEBUG_PYTHON) && defined(BOOST_LINKING_PYTHON) +# define BOOST_LIB_RT_OPT "-sgydpn" +# elif defined(_DEBUG) && (defined(__STL_DEBUG) || defined(_STLP_DEBUG)) +# define BOOST_LIB_RT_OPT "-sgdpn" +# elif defined(_DEBUG)\ + && defined(BOOST_DEBUG_PYTHON) && defined(BOOST_LINKING_PYTHON) +# define BOOST_LIB_RT_OPT "-sgydpn" +# pragma message("warning: STLport debug versions are built with /D_STLP_DEBUG=1") +# error "Build options aren't compatible with pre-built libraries" +# elif defined(_DEBUG) +# define BOOST_LIB_RT_OPT "-sgdpn" +# pragma message("warning: STLport debug versions are built with /D_STLP_DEBUG=1") +# error "Build options aren't compatible with pre-built libraries" +# else +# define BOOST_LIB_RT_OPT "-spn" +# endif + +# else + +# if defined(_DEBUG)\ + && defined(BOOST_DEBUG_PYTHON) && defined(BOOST_LINKING_PYTHON) +# define BOOST_LIB_RT_OPT "-sgyd" +# elif defined(_DEBUG) +# define BOOST_LIB_RT_OPT "-sgd" +# else +# define BOOST_LIB_RT_OPT "-s" +# endif + +# endif + +# endif + +#elif defined(BOOST_EMBTC_WINDOWS) + +# ifdef _RTLDLL + +# if defined(_DEBUG) +# define BOOST_LIB_RT_OPT "-d" +# else +# define BOOST_LIB_RT_OPT +# endif + +# else + +# if defined(_DEBUG) +# define BOOST_LIB_RT_OPT "-sd" +# else +# define BOOST_LIB_RT_OPT "-s" +# endif + +# endif + +#elif defined(BOOST_BORLANDC) + +// +// figure out whether we want the debug builds or not: +// +#if BOOST_BORLANDC > 0x561 +#pragma defineonoption BOOST_BORLAND_DEBUG -v +#endif +// +// sanity check: +// +#if defined(__STL_DEBUG) || defined(_STLP_DEBUG) +#error "Pre-built versions of the Boost libraries are not provided in STLport-debug form" +#endif + +# ifdef _RTLDLL + +# if defined(BOOST_BORLAND_DEBUG)\ + && defined(BOOST_DEBUG_PYTHON) && defined(BOOST_LINKING_PYTHON) +# define BOOST_LIB_RT_OPT "-yd" +# elif defined(BOOST_BORLAND_DEBUG) +# define BOOST_LIB_RT_OPT "-d" +# elif defined(BOOST_DEBUG_PYTHON) && defined(BOOST_LINKING_PYTHON) +# define BOOST_LIB_RT_OPT "-y" +# else +# define BOOST_LIB_RT_OPT +# endif + +# else + +# if defined(BOOST_BORLAND_DEBUG)\ + && defined(BOOST_DEBUG_PYTHON) && defined(BOOST_LINKING_PYTHON) +# define BOOST_LIB_RT_OPT "-syd" +# elif defined(BOOST_BORLAND_DEBUG) +# define BOOST_LIB_RT_OPT "-sd" +# elif defined(BOOST_DEBUG_PYTHON) && defined(BOOST_LINKING_PYTHON) +# define BOOST_LIB_RT_OPT "-sy" +# else +# define BOOST_LIB_RT_OPT "-s" +# endif + +# endif + +#endif + +// +// BOOST_LIB_ARCH_AND_MODEL_OPT +// + +#if defined( _M_IX86 ) +# define BOOST_LIB_ARCH_AND_MODEL_OPT "-x32" +#elif defined( _M_X64 ) +# define BOOST_LIB_ARCH_AND_MODEL_OPT "-x64" +#elif defined( _M_ARM ) +# define BOOST_LIB_ARCH_AND_MODEL_OPT "-a32" +#elif defined( _M_ARM64 ) +# define BOOST_LIB_ARCH_AND_MODEL_OPT "-a64" +#endif + +// +// select linkage opt: +// +#if (defined(_DLL) || defined(_RTLDLL)) && defined(BOOST_DYN_LINK) +# define BOOST_LIB_PREFIX +#elif defined(BOOST_DYN_LINK) +# error "Mixing a dll boost library with a static runtime is a really bad idea..." +#else +# define BOOST_LIB_PREFIX "lib" +#endif + +// +// now include the lib: +// +#if defined(BOOST_LIB_NAME) \ + && defined(BOOST_LIB_PREFIX) \ + && defined(BOOST_LIB_TOOLSET) \ + && defined(BOOST_LIB_THREAD_OPT) \ + && defined(BOOST_LIB_RT_OPT) \ + && defined(BOOST_LIB_ARCH_AND_MODEL_OPT) \ + && defined(BOOST_LIB_VERSION) + +#if defined(BOOST_EMBTC_WIN64) +# define BOOST_LIB_SUFFIX ".a" +#else +# define BOOST_LIB_SUFFIX ".lib" +#endif + +#ifdef BOOST_AUTO_LINK_NOMANGLE +# pragma comment(lib, BOOST_STRINGIZE(BOOST_LIB_NAME) BOOST_LIB_SUFFIX) +# ifdef BOOST_LIB_DIAGNOSTIC +# pragma message ("Linking to lib file: " BOOST_STRINGIZE(BOOST_LIB_NAME) BOOST_LIB_SUFFIX) +# endif +#elif defined(BOOST_AUTO_LINK_TAGGED) +# pragma comment(lib, BOOST_LIB_PREFIX BOOST_STRINGIZE(BOOST_LIB_NAME) BOOST_LIB_THREAD_OPT BOOST_LIB_RT_OPT BOOST_LIB_ARCH_AND_MODEL_OPT BOOST_LIB_SUFFIX) +# ifdef BOOST_LIB_DIAGNOSTIC +# pragma message ("Linking to lib file: " BOOST_LIB_PREFIX BOOST_STRINGIZE(BOOST_LIB_NAME) BOOST_LIB_THREAD_OPT BOOST_LIB_RT_OPT BOOST_LIB_ARCH_AND_MODEL_OPT BOOST_LIB_SUFFIX) +# endif +#elif defined(BOOST_AUTO_LINK_SYSTEM) +# pragma comment(lib, BOOST_LIB_PREFIX BOOST_STRINGIZE(BOOST_LIB_NAME) BOOST_LIB_SUFFIX) +# ifdef BOOST_LIB_DIAGNOSTIC +# pragma message ("Linking to lib file: " BOOST_LIB_PREFIX BOOST_STRINGIZE(BOOST_LIB_NAME) BOOST_LIB_SUFFIX) +# endif +#elif defined(BOOST_LIB_BUILDID) +# pragma comment(lib, BOOST_LIB_PREFIX BOOST_STRINGIZE(BOOST_LIB_NAME) "-" BOOST_LIB_TOOLSET BOOST_LIB_THREAD_OPT BOOST_LIB_RT_OPT BOOST_LIB_ARCH_AND_MODEL_OPT "-" BOOST_LIB_VERSION "-" BOOST_STRINGIZE(BOOST_LIB_BUILDID) BOOST_LIB_SUFFIX) +# ifdef BOOST_LIB_DIAGNOSTIC +# pragma message ("Linking to lib file: " BOOST_LIB_PREFIX BOOST_STRINGIZE(BOOST_LIB_NAME) "-" BOOST_LIB_TOOLSET BOOST_LIB_THREAD_OPT BOOST_LIB_RT_OPT BOOST_LIB_ARCH_AND_MODEL_OPT "-" BOOST_LIB_VERSION "-" BOOST_STRINGIZE(BOOST_LIB_BUILDID) BOOST_LIB_SUFFIX) +# endif +#else +# pragma comment(lib, BOOST_LIB_PREFIX BOOST_STRINGIZE(BOOST_LIB_NAME) "-" BOOST_LIB_TOOLSET BOOST_LIB_THREAD_OPT BOOST_LIB_RT_OPT BOOST_LIB_ARCH_AND_MODEL_OPT "-" BOOST_LIB_VERSION BOOST_LIB_SUFFIX) +# ifdef BOOST_LIB_DIAGNOSTIC +# pragma message ("Linking to lib file: " BOOST_LIB_PREFIX BOOST_STRINGIZE(BOOST_LIB_NAME) "-" BOOST_LIB_TOOLSET BOOST_LIB_THREAD_OPT BOOST_LIB_RT_OPT BOOST_LIB_ARCH_AND_MODEL_OPT "-" BOOST_LIB_VERSION BOOST_LIB_SUFFIX) +# endif +#endif + +#else +# error "some required macros where not defined (internal logic error)." +#endif + + +#endif // _MSC_VER || __BORLANDC__ + +// +// finally undef any macros we may have set: +// +#ifdef BOOST_LIB_PREFIX +# undef BOOST_LIB_PREFIX +#endif +#if defined(BOOST_LIB_NAME) +# undef BOOST_LIB_NAME +#endif +// Don't undef this one: it can be set by the user and should be the +// same for all libraries: +//#if defined(BOOST_LIB_TOOLSET) +//# undef BOOST_LIB_TOOLSET +//#endif +#if defined(BOOST_LIB_THREAD_OPT) +# undef BOOST_LIB_THREAD_OPT +#endif +#if defined(BOOST_LIB_RT_OPT) +# undef BOOST_LIB_RT_OPT +#endif +#if defined(BOOST_LIB_ARCH_AND_MODEL_OPT) +# undef BOOST_LIB_ARCH_AND_MODEL_OPT +#endif +#if defined(BOOST_LIB_LINK_OPT) +# undef BOOST_LIB_LINK_OPT +#endif +#if defined(BOOST_LIB_DEBUG_OPT) +# undef BOOST_LIB_DEBUG_OPT +#endif +#if defined(BOOST_DYN_LINK) +# undef BOOST_DYN_LINK +#endif +#if defined(BOOST_LIB_SUFFIX) +# undef BOOST_LIB_SUFFIX +#endif diff --git a/third_party/boost/libs/config/include/boost/config/compiler/borland.hpp b/third_party/boost/libs/config/include/boost/config/compiler/borland.hpp new file mode 100644 index 00000000000..567636c5b87 --- /dev/null +++ b/third_party/boost/libs/config/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/third_party/boost/libs/config/include/boost/config/compiler/clang.hpp b/third_party/boost/libs/config/include/boost/config/compiler/clang.hpp new file mode 100644 index 00000000000..1eeed315d6b --- /dev/null +++ b/third_party/boost/libs/config/include/boost/config/compiler/clang.hpp @@ -0,0 +1,366 @@ +// (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. + +// Clang compiler setup. + +#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_attribute +#define __has_attribute(x) 0 +#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 !__has_feature(cxx_thread_local) +# define BOOST_NO_CXX11_THREAD_LOCAL +#endif + +#ifdef __is_identifier +#if !__is_identifier(__int64) && !defined(__GNUC__) +# define BOOST_HAS_MS_INT64 +#endif +#endif + +#if __has_include() +# define BOOST_HAS_STDINT_H +#endif + +#if (defined(linux) || defined(__linux) || defined(__linux__) || defined(__GNU__) || defined(__GLIBC__)) && !defined(_CRAYC) +#if (__clang_major__ >= 4) && defined(__has_include) +#if __has_include() +# define BOOST_HAS_FLOAT128 +#endif +#endif +#endif + + +#define BOOST_HAS_NRVO + +// Branch prediction hints +#if !defined (__c2__) && 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 + +// +// We disable this if the compiler is really nvcc with C++03 as it +// doesn't actually support __int128 as of CUDA_VERSION=7500 +// even though it defines __SIZEOF_INT128__. +// See https://svn.boost.org/trac/boost/ticket/10418 +// https://svn.boost.org/trac/boost/ticket/11852 +// Only re-enable this for nvcc if you're absolutely sure +// of the circumstances under which it's supported. +// Similarly __SIZEOF_INT128__ is defined when targetting msvc +// compatibility even though the required support functions are absent. +// +#if defined(__CUDACC__) +# if defined(BOOST_GCC_CXX11) +# define BOOST_NVCC_CXX11 +# else +# define BOOST_NVCC_CXX03 +# endif +#endif + +#if defined(__SIZEOF_INT128__) && !defined(BOOST_NVCC_CXX03) && !defined(_MSC_VER) +# define BOOST_HAS_INT128 +#endif + + +// +// Dynamic shared object (DSO) and dynamic-link library (DLL) support +// +#if defined(_WIN32) || defined(__WIN32__) || defined(WIN32) || defined(__CYGWIN__) +# define BOOST_HAS_DECLSPEC +# define BOOST_SYMBOL_EXPORT __attribute__((__dllexport__)) +# define BOOST_SYMBOL_IMPORT __attribute__((__dllimport__)) +#else +# define BOOST_SYMBOL_EXPORT __attribute__((__visibility__("default"))) +# define BOOST_SYMBOL_VISIBLE __attribute__((__visibility__("default"))) +# define BOOST_SYMBOL_IMPORT +#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) && (_MSC_VER < 1900)) || !(defined(__GXX_EXPERIMENTAL_CXX0X__) || __cplusplus >= 201103L) +# define BOOST_NO_CXX11_CHAR16_T +# define BOOST_NO_CXX11_CHAR32_T +#endif + +#if defined(_MSC_VER) && (_MSC_VER >= 1800) && !defined(__GNUC__) +#define BOOST_HAS_EXPM1 +#define BOOST_HAS_LOG1P +#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 __cplusplus < 201103L +#define BOOST_NO_CXX11_SFINAE_EXPR +#endif + +#if __cplusplus < 201400 +// All versions with __cplusplus above this value seem to support this: +# define BOOST_NO_CXX14_DIGIT_SEPARATORS +#endif + +// 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: +# define BOOST_NO_CXX11_FIXED_LENGTH_VARIADIC_TEMPLATE_EXPANSION_PACKS +#endif + +// Clang has supported the 'unused' attribute since the first release. +#define BOOST_ATTRIBUTE_UNUSED __attribute__((__unused__)) + +// 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 + +// BOOST_CLANG_VERSION +#include diff --git a/third_party/boost/libs/config/include/boost/config/compiler/clang_version.hpp b/third_party/boost/libs/config/include/boost/config/compiler/clang_version.hpp new file mode 100644 index 00000000000..70c5507c43e --- /dev/null +++ b/third_party/boost/libs/config/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/third_party/boost/libs/config/include/boost/config/compiler/codegear.hpp b/third_party/boost/libs/config/include/boost/config/compiler/codegear.hpp new file mode 100644 index 00000000000..4d3f42aefb1 --- /dev/null +++ b/third_party/boost/libs/config/include/boost/config/compiler/codegear.hpp @@ -0,0 +1,385 @@ +// (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. + +// CodeGear C++ compiler setup: + +// +// versions check: +// last known and checked version is 0x740 +#if (__CODEGEARC__ > 0x740) +# 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 +#endif + +#ifdef __clang__ // Clang enhanced Windows compiler + +# include "clang.hpp" +# define BOOST_NO_CXX11_THREAD_LOCAL +# define BOOST_NO_CXX11_ATOMIC_SMART_PTR + +// This bug has been reported to Embarcadero + +#if defined(BOOST_HAS_INT128) +#undef BOOST_HAS_INT128 +#endif +#if defined(BOOST_HAS_FLOAT128) +#undef BOOST_HAS_FLOAT128 +#endif + +// The clang-based compilers can not do 128 atomic exchanges + +#define BOOST_ATOMIC_NO_CMPXCHG16B + +// 32 functions are missing from the current RTL in cwchar, so it really can not be used even if it exists + +# define BOOST_NO_CWCHAR + +# ifndef __MT__ /* If compiling in single-threaded mode, assume there is no CXX11_HDR_ATOMIC */ +# define BOOST_NO_CXX11_HDR_ATOMIC +# endif + +/* temporarily disable this until we can link against fegetround fesetround feholdexcept */ + +#define BOOST_NO_FENV_H + +/* Reported this bug to Embarcadero with the latest C++ Builder Rio release */ + +#define BOOST_NO_CXX11_HDR_EXCEPTION + +// +// check for exception handling support: +// +#if !defined(_CPPUNWIND) && !defined(__EXCEPTIONS) && !defined(BOOST_NO_EXCEPTIONS) +# define BOOST_NO_EXCEPTIONS +#endif + +/* + +// On non-Win32 platforms let the platform config figure this out: +#ifdef _WIN32 +# define BOOST_HAS_STDINT_H +#endif + +// +// __int64: +// +#if !defined(__STRICT_ANSI__) +# define BOOST_HAS_MS_INT64 +#endif +// +// all versions have a : +// +#if !defined(__STRICT_ANSI__) +# define BOOST_HAS_DIRENT_H +#endif +// +// Disable Win32 support in ANSI mode: +// +# pragma defineonoption BOOST_DISABLE_WIN32 -A +// +// 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 +// + +*/ + +// Specific settings for Embarcadero drivers +# define BOOST_EMBTC __CODEGEARC__ +# define BOOST_EMBTC_FULL_VER ((__clang_major__ << 16) | \ + (__clang_minor__ << 8) | \ + __clang_patchlevel__ ) + +// Detecting which Embarcadero driver is being used +#if defined(BOOST_EMBTC) +# if defined(_WIN64) +# define BOOST_EMBTC_WIN64 1 +# define BOOST_EMBTC_WINDOWS 1 +# ifndef BOOST_USE_WINDOWS_H +# define BOOST_USE_WINDOWS_H +# endif +# elif defined(_WIN32) +# define BOOST_EMBTC_WIN32C 1 +# define BOOST_EMBTC_WINDOWS 1 +# ifndef BOOST_USE_WINDOWS_H +# define BOOST_USE_WINDOWS_H +# endif +# elif defined(__APPLE__) && defined(__arm__) +# define BOOST_EMBTC_IOSARM 1 +# define BOOST_EMBTC_IOS 1 +# elif defined(__APPLE__) && defined(__aarch64__) +# define BOOST_EMBTC_IOSARM64 1 +# define BOOST_EMBTC_IOS 1 +# elif defined(__ANDROID__) && defined(__arm__) +# define BOOST_EMBTC_AARM 1 +# define BOOST_EMBTC_ANDROID 1 +# elif +# if defined(BOOST_ASSERT_CONFIG) +# error "Unknown Embarcadero driver" +# else +# warning "Unknown Embarcadero driver" +# endif /* defined(BOOST_ASSERT_CONFIG) */ +# endif +#endif /* defined(BOOST_EMBTC) */ + +#if defined(BOOST_EMBTC_WINDOWS) + +#if !defined(_chdir) +#define _chdir(x) chdir(x) +#endif + +#if !defined(_dup2) +#define _dup2(x,y) dup2(x,y) +#endif + +#endif + +# undef BOOST_COMPILER +# define BOOST_COMPILER "Embarcadero-Clang C++ version " BOOST_STRINGIZE(__CODEGEARC__) " clang: " __clang_version__ +// # define __CODEGEARC_CLANG__ __CODEGEARC__ +// # define __EMBARCADERO_CLANG__ __CODEGEARC__ +// # define __BORLANDC_CLANG__ __BORLANDC__ + +#else // #if !defined(__clang__) + +# define BOOST_CODEGEARC __CODEGEARC__ +# define BOOST_BORLANDC __BORLANDC__ + +#if !defined( BOOST_WITH_CODEGEAR_WARNINGS ) +// these warnings occur frequently in optimized template code +# pragma warn -8004 // var assigned value, but never used +# pragma warn -8008 // condition always true/false +# pragma warn -8066 // dead code can never execute +# pragma warn -8104 // static members with ctors not threadsafe +# pragma warn -8105 // reference member in class without ctors +#endif + +// CodeGear C++ Builder 2009 +#if (__CODEGEARC__ <= 0x613) +# define BOOST_NO_INTEGRAL_INT64_T +# define BOOST_NO_DEPENDENT_NESTED_DERIVATIONS +# define BOOST_NO_PRIVATE_IN_AGGREGATE +# define BOOST_NO_USING_DECLARATION_OVERLOADS_FROM_TYPENAME_BASE + // 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_SP_NO_SP_CONVERTIBLE +#endif + +// CodeGear C++ Builder 2010 +#if (__CODEGEARC__ <= 0x621) +# define BOOST_NO_TYPENAME_WITH_CTOR // Cannot use typename keyword when making temporaries of a dependant type +# define BOOST_FUNCTION_SCOPE_USING_DECLARATION_BREAKS_ADL +# define BOOST_NO_MEMBER_TEMPLATE_FRIENDS +# define BOOST_NO_NESTED_FRIENDSHIP // TC1 gives nested classes access rights as any other member +# define BOOST_NO_USING_TEMPLATE +# define BOOST_NO_TWO_PHASE_NAME_LOOKUP +// Temporary hack, until specific MPL preprocessed headers are generated +# define BOOST_MPL_CFG_NO_PREPROCESSED_HEADERS + +// CodeGear has not yet completely implemented value-initialization, for +// example for array types, as I reported in 2010: Embarcadero Report 83751, +// "Value-initialization: arrays should have each element value-initialized", +// http://qc.embarcadero.com/wc/qcmain.aspx?d=83751 +// Last checked version: Embarcadero C++ 6.21 +// See also: http://www.boost.org/libs/utility/value_init.htm#compiler_issues +// (Niels Dekker, LKEB, April 2010) +# define BOOST_NO_COMPLETE_VALUE_INITIALIZATION + +# 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 + +// Reportedly, #pragma once is supported since C++ Builder 2010 +#if (__CODEGEARC__ >= 0x620) +# define BOOST_HAS_PRAGMA_ONCE +#endif + +#define BOOST_NO_FENV_H + +// +// C++0x macros: +// +#if (__CODEGEARC__ <= 0x620) +#define BOOST_NO_CXX11_STATIC_ASSERT +#else +#define BOOST_HAS_STATIC_ASSERT +#endif +#define BOOST_HAS_CHAR16_T +#define BOOST_HAS_CHAR32_T +#define BOOST_HAS_LONG_LONG +// #define BOOST_HAS_ALIGNOF +#define BOOST_HAS_DECLTYPE +#define BOOST_HAS_EXPLICIT_CONVERSION_OPS +// #define BOOST_HAS_RVALUE_REFS +#define BOOST_HAS_SCOPED_ENUM +// #define BOOST_HAS_STATIC_ASSERT +#define BOOST_HAS_STD_TYPE_TRAITS + +#define BOOST_NO_CXX11_AUTO_DECLARATIONS +#define BOOST_NO_CXX11_AUTO_MULTIDECLARATIONS +#define BOOST_NO_CXX11_CONSTEXPR +#define BOOST_NO_CXX11_DEFAULTED_FUNCTIONS +#define BOOST_NO_CXX11_DELETED_FUNCTIONS +#define BOOST_NO_CXX11_EXTERN_TEMPLATE +#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_SFINAE_EXPR +#define BOOST_NO_CXX11_SFINAE_EXPR +#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_DECLTYPE_N3276 +#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 + +// +// TR1 macros: +// +#define BOOST_HAS_TR1_HASH +#define BOOST_HAS_TR1_TYPE_TRAITS +#define BOOST_HAS_TR1_UNORDERED_MAP +#define BOOST_HAS_TR1_UNORDERED_SET + +#define BOOST_HAS_MACRO_USE_FACET + +#define BOOST_NO_CXX11_HDR_INITIALIZER_LIST + +// On non-Win32 platforms let the platform config figure this out: +#ifdef _WIN32 +# define BOOST_HAS_STDINT_H +#endif + +// +// __int64: +// +#if !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 : +// +#if !defined(__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: +// +#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 +// +// Disable Win32 support in ANSI mode: +// +# pragma defineonoption BOOST_DISABLE_WIN32 -A +// +// 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 + +#define BOOST_COMPILER "CodeGear C++ version " BOOST_STRINGIZE(__CODEGEARC__) + +#endif // #if !defined(__clang__) diff --git a/third_party/boost/libs/config/include/boost/config/compiler/comeau.hpp b/third_party/boost/libs/config/include/boost/config/compiler/comeau.hpp new file mode 100644 index 00000000000..ca80fac37a2 --- /dev/null +++ b/third_party/boost/libs/config/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/third_party/boost/libs/config/include/boost/config/compiler/common_edg.hpp b/third_party/boost/libs/config/include/boost/config/compiler/common_edg.hpp new file mode 100644 index 00000000000..dc049893cd2 --- /dev/null +++ b/third_party/boost/libs/config/include/boost/config/compiler/common_edg.hpp @@ -0,0 +1,183 @@ +// (C) Copyright John Maddock 2001 - 2002. +// (C) Copyright Jens Maurer 2001. +// (C) Copyright David Abrahams 2002. +// (C) Copyright Aleksey Gurtovoy 2002. +// (C) Copyright Markus Schoepflin 2005. +// 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. + +// +// Options common to all edg based compilers. +// +// This is included from within the individual compiler mini-configs. + +#ifndef __EDG_VERSION__ +# error This file requires that __EDG_VERSION__ be defined. +#endif + +#if (__EDG_VERSION__ <= 238) +# define BOOST_NO_INTEGRAL_INT64_T +# define BOOST_NO_SFINAE +#endif + +#if (__EDG_VERSION__ <= 240) +# define BOOST_NO_VOID_RETURNS +#endif + +#if (__EDG_VERSION__ <= 241) && !defined(BOOST_NO_ARGUMENT_DEPENDENT_LOOKUP) +# define BOOST_NO_ARGUMENT_DEPENDENT_LOOKUP +#endif + +#if (__EDG_VERSION__ <= 244) && !defined(BOOST_NO_TEMPLATE_TEMPLATES) +# define BOOST_NO_TEMPLATE_TEMPLATES +#endif + +#if (__EDG_VERSION__ < 300) && !defined(BOOST_NO_IS_ABSTRACT) +# define BOOST_NO_IS_ABSTRACT +#endif + +#if (__EDG_VERSION__ <= 303) && !defined(BOOST_FUNCTION_SCOPE_USING_DECLARATION_BREAKS_ADL) +# define BOOST_FUNCTION_SCOPE_USING_DECLARATION_BREAKS_ADL +#endif + +// See also kai.hpp which checks a Kai-specific symbol for EH +# if !defined(__KCC) && !defined(__EXCEPTIONS) && !defined(BOOST_NO_EXCEPTIONS) +# define BOOST_NO_EXCEPTIONS +# endif + +# if !defined(__NO_LONG_LONG) +# define BOOST_HAS_LONG_LONG +# else +# define BOOST_NO_LONG_LONG +# endif + +// Not sure what version was the first to support #pragma once, but +// different EDG-based compilers (e.g. Intel) supported it for ages. +// Add a proper version check if it causes problems. +#define BOOST_HAS_PRAGMA_ONCE + +// +// C++0x features +// +// See above for BOOST_NO_LONG_LONG +// +#if (__EDG_VERSION__ < 310) +# define BOOST_NO_CXX11_EXTERN_TEMPLATE +#endif +#if (__EDG_VERSION__ <= 310) +// No support for initializer lists +# define BOOST_NO_CXX11_HDR_INITIALIZER_LIST +#endif +#if (__EDG_VERSION__ < 400) +# define BOOST_NO_CXX11_VARIADIC_MACROS +#endif + +#define BOOST_NO_CXX11_AUTO_DECLARATIONS +#define BOOST_NO_CXX11_AUTO_MULTIDECLARATIONS +#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_LOCAL_CLASS_TEMPLATE_PARAMETERS +#define BOOST_NO_CXX11_NOEXCEPT +#define BOOST_NO_CXX11_NULLPTR +#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_UNIFIED_INITIALIZATION_SYNTAX +#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 + +//__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 +#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 + +#ifdef c_plusplus +// EDG has "long long" in non-strict mode +// However, some libraries have insufficient "long long" support +// #define BOOST_HAS_LONG_LONG +#endif diff --git a/third_party/boost/libs/config/include/boost/config/compiler/compaq_cxx.hpp b/third_party/boost/libs/config/include/boost/config/compiler/compaq_cxx.hpp new file mode 100644 index 00000000000..4d6b8ab3ac7 --- /dev/null +++ b/third_party/boost/libs/config/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/third_party/boost/libs/config/include/boost/config/compiler/cray.hpp b/third_party/boost/libs/config/include/boost/config/compiler/cray.hpp new file mode 100644 index 00000000000..e40fd05acf9 --- /dev/null +++ b/third_party/boost/libs/config/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/third_party/boost/libs/config/include/boost/config/compiler/diab.hpp b/third_party/boost/libs/config/include/boost/config/compiler/diab.hpp new file mode 100644 index 00000000000..943db83fd6e --- /dev/null +++ b/third_party/boost/libs/config/include/boost/config/compiler/diab.hpp @@ -0,0 +1,26 @@ +// (C) Copyright Brian Kuhl 2016. +// 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) + +// Check this is a recent EDG based compiler, otherwise we don't support it here: + + +#ifndef __EDG_VERSION__ +# error "Unknown Diab compiler version - please run the configure tests and report the results" +#endif + +#include "boost/config/compiler/common_edg.hpp" + +#define BOOST_NO_TWO_PHASE_NAME_LOOKUP +#define BOOST_BUGGY_INTEGRAL_CONSTANT_EXPRESSIONS + +#define BOOST_MPL_CFG_NO_HAS_XXX_TEMPLATE +#define BOOST_LOG_NO_MEMBER_TEMPLATE_FRIENDS +#define BOOST_REGEX_NO_EXTERNAL_TEMPLATES + +#define BOOST_NO_CXX11_HDR_INITIALIZER_LIST +#define BOOST_NO_CXX11_HDR_CODECVT +#define BOOST_NO_CXX11_NUMERIC_LIMITS + +#define BOOST_COMPILER "Wind River Diab " BOOST_STRINGIZE(__VERSION_NUMBER__) diff --git a/third_party/boost/libs/config/include/boost/config/compiler/digitalmars.hpp b/third_party/boost/libs/config/include/boost/config/compiler/digitalmars.hpp new file mode 100644 index 00000000000..bb56ff6c064 --- /dev/null +++ b/third_party/boost/libs/config/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/third_party/boost/libs/config/include/boost/config/compiler/gcc.hpp b/third_party/boost/libs/config/include/boost/config/compiler/gcc.hpp new file mode 100644 index 00000000000..2f1fe5508bc --- /dev/null +++ b/third_party/boost/libs/config/include/boost/config/compiler/gcc.hpp @@ -0,0 +1,383 @@ +// (C) Copyright John Maddock 2001 - 2003. +// (C) Copyright Darin Adler 2001 - 2002. +// (C) Copyright Jens Maurer 2001 - 2002. +// (C) Copyright Beman Dawes 2001 - 2003. +// (C) Copyright Douglas Gregor 2002. +// (C) Copyright David Abrahams 2002 - 2003. +// (C) Copyright Synge Todo 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. + +// GNU C++ compiler setup. + +// +// Define BOOST_GCC so we know this is "real" GCC and not some pretender: +// +#define BOOST_GCC_VERSION (__GNUC__ * 10000 + __GNUC_MINOR__ * 100 + __GNUC_PATCHLEVEL__) +#if !defined(__CUDACC__) +#define BOOST_GCC BOOST_GCC_VERSION +#endif + +#if defined(__GXX_EXPERIMENTAL_CXX0X__) || (__cplusplus >= 201103L) +# define BOOST_GCC_CXX11 +#endif + +#if __GNUC__ == 3 +# if defined (__PATHSCALE__) +# define BOOST_NO_TWO_PHASE_NAME_LOOKUP +# define BOOST_NO_IS_ABSTRACT +# endif + +# if __GNUC_MINOR__ < 4 +# define BOOST_NO_IS_ABSTRACT +# endif +# define BOOST_NO_CXX11_EXTERN_TEMPLATE +#endif +#if __GNUC__ < 4 +// +// All problems to gcc-3.x and earlier here: +// +#define BOOST_NO_TWO_PHASE_NAME_LOOKUP +# ifdef __OPEN64__ +# define BOOST_NO_IS_ABSTRACT +# endif +#endif + +// GCC prior to 3.4 had #pragma once too but it didn't work well with filesystem links +#if BOOST_GCC_VERSION >= 30400 +#define BOOST_HAS_PRAGMA_ONCE +#endif + +#if BOOST_GCC_VERSION < 40400 +// Previous versions of GCC did not completely implement value-initialization: +// GCC Bug 30111, "Value-initialization of POD base class doesn't initialize +// members", reported by Jonathan Wakely in 2006, +// http://gcc.gnu.org/bugzilla/show_bug.cgi?id=30111 (fixed for GCC 4.4) +// GCC Bug 33916, "Default constructor fails to initialize array members", +// reported by Michael Elizabeth Chastain in 2007, +// http://gcc.gnu.org/bugzilla/show_bug.cgi?id=33916 (fixed for GCC 4.2.4) +// See also: http://www.boost.org/libs/utility/value_init.htm#compiler_issues +#define BOOST_NO_COMPLETE_VALUE_INITIALIZATION +#endif + +#if !defined(__EXCEPTIONS) && !defined(BOOST_NO_EXCEPTIONS) +# define BOOST_NO_EXCEPTIONS +#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(linux) && !defined(__linux) && !defined(__linux__) +# define BOOST_HAS_THREADS +#endif + +// +// gcc has "long long" +// Except on Darwin with standard compliance enabled (-pedantic) +// Apple gcc helpfully defines this macro we can query +// +#if !defined(__DARWIN_NO_LONG_LONG) +# define BOOST_HAS_LONG_LONG +#endif + +// +// gcc implements the named return value optimization since version 3.1 +// +#define BOOST_HAS_NRVO + +// Branch prediction hints +#define BOOST_LIKELY(x) __builtin_expect(x, 1) +#define BOOST_UNLIKELY(x) __builtin_expect(x, 0) + +// +// Dynamic shared object (DSO) and dynamic-link library (DLL) support +// +#if __GNUC__ >= 4 +# if defined(_WIN32) || defined(__WIN32__) || defined(WIN32) || defined(__CYGWIN__) + // All Win32 development environments, including 64-bit Windows and MinGW, define + // _WIN32 or one of its variant spellings. Note that Cygwin is a POSIX environment, + // so does not define _WIN32 or its variants, but still supports dllexport/dllimport. +# define BOOST_HAS_DECLSPEC +# define BOOST_SYMBOL_EXPORT __attribute__((__dllexport__)) +# define BOOST_SYMBOL_IMPORT __attribute__((__dllimport__)) +# else +# define BOOST_SYMBOL_EXPORT __attribute__((__visibility__("default"))) +# define BOOST_SYMBOL_IMPORT +# endif +# define BOOST_SYMBOL_VISIBLE __attribute__((__visibility__("default"))) +#else +// config/platform/win32.hpp will define BOOST_SYMBOL_EXPORT, etc., unless already defined +# define BOOST_SYMBOL_EXPORT +#endif + +// +// RTTI and typeinfo detection is possible post gcc-4.3: +// +#if BOOST_GCC_VERSION > 40300 +# ifndef __GXX_RTTI +# ifndef BOOST_NO_TYPEID +# define BOOST_NO_TYPEID +# endif +# ifndef BOOST_NO_RTTI +# define BOOST_NO_RTTI +# endif +# endif +#endif + +// +// Recent GCC versions have __int128 when in 64-bit mode. +// +// We disable this if the compiler is really nvcc with C++03 as it +// doesn't actually support __int128 as of CUDA_VERSION=7500 +// even though it defines __SIZEOF_INT128__. +// See https://svn.boost.org/trac/boost/ticket/8048 +// https://svn.boost.org/trac/boost/ticket/11852 +// Only re-enable this for nvcc if you're absolutely sure +// of the circumstances under which it's supported: +// +#if defined(__CUDACC__) +# if defined(BOOST_GCC_CXX11) +# define BOOST_NVCC_CXX11 +# else +# define BOOST_NVCC_CXX03 +# endif +#endif + +#if defined(__SIZEOF_INT128__) && !defined(BOOST_NVCC_CXX03) +# define BOOST_HAS_INT128 +#endif +// +// Recent GCC versions have a __float128 native type, we need to +// include a std lib header to detect this - not ideal, but we'll +// be including later anyway when we select the std lib. +// +// Nevertheless, as of CUDA 7.5, using __float128 with the host +// compiler in pre-C++11 mode is still not supported. +// See https://svn.boost.org/trac/boost/ticket/11852 +// +#ifdef __cplusplus +#include +#else +#include +#endif +#if defined(_GLIBCXX_USE_FLOAT128) && !defined(__STRICT_ANSI__) && !defined(BOOST_NVCC_CXX03) +# define BOOST_HAS_FLOAT128 +#endif + +// C++0x features in 4.3.n and later +// +#if (BOOST_GCC_VERSION >= 40300) && defined(BOOST_GCC_CXX11) +// C++0x features are only enabled when -std=c++0x or -std=gnu++0x are +// passed on the command line, which in turn defines +// __GXX_EXPERIMENTAL_CXX0X__. +# define BOOST_HAS_DECLTYPE +# define BOOST_HAS_RVALUE_REFS +# define BOOST_HAS_STATIC_ASSERT +# define BOOST_HAS_VARIADIC_TMPL +#else +# define BOOST_NO_CXX11_DECLTYPE +# define BOOST_NO_CXX11_FUNCTION_TEMPLATE_DEFAULT_ARGS +# define BOOST_NO_CXX11_RVALUE_REFERENCES +# define BOOST_NO_CXX11_STATIC_ASSERT +#endif + +// C++0x features in 4.4.n and later +// +#if (BOOST_GCC_VERSION < 40400) || !defined(BOOST_GCC_CXX11) +# 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_HDR_INITIALIZER_LIST +# define BOOST_NO_CXX11_DEFAULTED_FUNCTIONS +# define BOOST_NO_CXX11_DELETED_FUNCTIONS +# define BOOST_NO_CXX11_TRAILING_RESULT_TYPES +# define BOOST_NO_CXX11_INLINE_NAMESPACES +# define BOOST_NO_CXX11_VARIADIC_TEMPLATES +#endif + +#if BOOST_GCC_VERSION < 40500 +# define BOOST_NO_SFINAE_EXPR +#endif + +// GCC 4.5 forbids declaration of defaulted functions in private or protected sections +#if __GNUC__ < 4 || (__GNUC__ == 4 && __GNUC_MINOR__ == 5) || !defined(BOOST_GCC_CXX11) +# define BOOST_NO_CXX11_NON_PUBLIC_DEFAULTED_FUNCTIONS +#endif + +// C++0x features in 4.5.0 and later +// +#if (BOOST_GCC_VERSION < 40500) || !defined(BOOST_GCC_CXX11) +# define BOOST_NO_CXX11_EXPLICIT_CONVERSION_OPERATORS +# define BOOST_NO_CXX11_LAMBDAS +# 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 +// +#if (BOOST_GCC_VERSION < 40501) || !defined(BOOST_GCC_CXX11) +// scoped enums have a serious bug in 4.4.0, so define BOOST_NO_CXX11_SCOPED_ENUMS before 4.5.1 +// See http://gcc.gnu.org/bugzilla/show_bug.cgi?id=38064 +# define BOOST_NO_CXX11_SCOPED_ENUMS +#endif + +// C++0x features in 4.6.n and later +// +#if (BOOST_GCC_VERSION < 40600) || !defined(BOOST_GCC_CXX11) +#define BOOST_NO_CXX11_DEFAULTED_MOVES +#define BOOST_NO_CXX11_NOEXCEPT +#define BOOST_NO_CXX11_NULLPTR +#define BOOST_NO_CXX11_RANGE_BASED_FOR +#define BOOST_NO_CXX11_UNIFIED_INITIALIZATION_SYNTAX +#endif + +// C++0x features in 4.7.n and later +// +#if (BOOST_GCC_VERSION < 40700) || !defined(BOOST_GCC_CXX11) +// Note that while constexpr is partly supported in gcc-4.6 it's a +// pre-std version with several bugs: +# define BOOST_NO_CXX11_CONSTEXPR +# define BOOST_NO_CXX11_FINAL +# define BOOST_NO_CXX11_TEMPLATE_ALIASES +# define BOOST_NO_CXX11_USER_DEFINED_LITERALS +# define BOOST_NO_CXX11_FIXED_LENGTH_VARIADIC_TEMPLATE_EXPANSION_PACKS +# define BOOST_NO_CXX11_OVERRIDE +#endif + +// C++0x features in 4.8.n and later +// +#if (BOOST_GCC_VERSION < 40800) || !defined(BOOST_GCC_CXX11) +# define BOOST_NO_CXX11_THREAD_LOCAL +# define BOOST_NO_CXX11_SFINAE_EXPR +#endif + +// C++0x features in 4.8.1 and later +// +#if (BOOST_GCC_VERSION < 40801) || !defined(BOOST_GCC_CXX11) +# define BOOST_NO_CXX11_DECLTYPE_N3276 +# define BOOST_NO_CXX11_REF_QUALIFIERS +# define BOOST_NO_CXX14_BINARY_LITERALS +#endif + +// C++0x features in 4.9.n and later +// +#if (BOOST_GCC_VERSION < 40900) || !defined(BOOST_GCC_CXX11) +// Although alignas support is added in gcc 4.8, it does not accept +// dependent constant expressions as an argument until gcc 4.9. +# define BOOST_NO_CXX11_ALIGNAS +#endif + +// C++0x features in 5.1 and later +// +#if (BOOST_GCC_VERSION < 50100) || !defined(BOOST_GCC_CXX11) +# define BOOST_NO_CXX11_UNRESTRICTED_UNION +#endif + +// C++14 features in 4.9.0 and later +// +#if (BOOST_GCC_VERSION < 40900) || (__cplusplus < 201300) +# define BOOST_NO_CXX14_RETURN_TYPE_DEDUCTION +# define BOOST_NO_CXX14_GENERIC_LAMBDAS +# define BOOST_NO_CXX14_DIGIT_SEPARATORS +# define BOOST_NO_CXX14_DECLTYPE_AUTO +# if !((BOOST_GCC_VERSION >= 40801) && (BOOST_GCC_VERSION < 40900) && defined(BOOST_GCC_CXX11)) +# define BOOST_NO_CXX14_INITIALIZED_LAMBDA_CAPTURES +# endif +#endif + + +// C++ 14: +#if !defined(__cpp_aggregate_nsdmi) || (__cpp_aggregate_nsdmi < 201304) +# define BOOST_NO_CXX14_AGGREGATE_NSDMI +#endif +#if !defined(__cpp_constexpr) || (__cpp_constexpr < 201304) +# define BOOST_NO_CXX14_CONSTEXPR +#endif +#if (BOOST_GCC_VERSION < 50200) || !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 __GNUC__ >= 7 +# define BOOST_FALLTHROUGH __attribute__((fallthrough)) +#endif + +#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 + +// +// Unused attribute: +#if __GNUC__ >= 4 +# define BOOST_ATTRIBUTE_UNUSED __attribute__((__unused__)) +#endif + +// Type aliasing hint. Supported since gcc 3.3. +#define BOOST_MAY_ALIAS __attribute__((__may_alias__)) + +// 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 + +// ConceptGCC compiler: +// http://www.generic-programming.org/software/ConceptGCC/ +#ifdef __GXX_CONCEPTS__ +# define BOOST_HAS_CONCEPTS +# define BOOST_COMPILER "ConceptGCC version " __VERSION__ +#endif + +// versions check: +// we don't know gcc prior to version 3.30: +#if (BOOST_GCC_VERSION < 30300) +# error "Compiler not configured - please reconfigure" +#endif +// +// last known and checked version is 8.1: +#if (BOOST_GCC_VERSION > 80100) +# if defined(BOOST_ASSERT_CONFIG) +# error "Boost.Config is older than your compiler - please check for an updated Boost release." +# else +// we don't emit warnings here anymore since there are no defect macros defined for +// gcc post 3.4, so any failures are gcc regressions... +//# warning "boost: Unknown compiler version - please run the configure tests and report the results" +# endif +#endif + diff --git a/third_party/boost/libs/config/include/boost/config/compiler/gcc_xml.hpp b/third_party/boost/libs/config/include/boost/config/compiler/gcc_xml.hpp new file mode 100644 index 00000000000..75cac44e9f0 --- /dev/null +++ b/third_party/boost/libs/config/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/third_party/boost/libs/config/include/boost/config/compiler/greenhills.hpp b/third_party/boost/libs/config/include/boost/config/compiler/greenhills.hpp new file mode 100644 index 00000000000..39112c2c1cf --- /dev/null +++ b/third_party/boost/libs/config/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/third_party/boost/libs/config/include/boost/config/compiler/hp_acc.hpp b/third_party/boost/libs/config/include/boost/config/compiler/hp_acc.hpp new file mode 100644 index 00000000000..25636324bf3 --- /dev/null +++ b/third_party/boost/libs/config/include/boost/config/compiler/hp_acc.hpp @@ -0,0 +1,149 @@ +// (C) Copyright John Maddock 2001 - 2003. +// (C) Copyright Jens Maurer 2001 - 2003. +// (C) Copyright Aleksey Gurtovoy 2002. +// (C) Copyright David Abrahams 2002 - 2003. +// (C) Copyright Toon Knapen 2003. +// (C) Copyright Boris Gubenko 2006 - 2007. +// 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. + +// HP aCC C++ compiler setup: + +#if defined(__EDG__) +#include +#endif + +#if (__HP_aCC <= 33100) +# define BOOST_NO_INTEGRAL_INT64_T +# define BOOST_NO_OPERATORS_IN_NAMESPACE +# if !defined(_NAMESPACE_STD) +# define BOOST_NO_STD_LOCALE +# define BOOST_NO_STRINGSTREAM +# endif +#endif + +#if (__HP_aCC <= 33300) +// member templates are sufficiently broken that we disable them for now +# define BOOST_NO_MEMBER_TEMPLATES +# define BOOST_NO_DEPENDENT_NESTED_DERIVATIONS +# define BOOST_NO_USING_DECLARATION_OVERLOADS_FROM_TYPENAME_BASE +#endif + +#if (__HP_aCC <= 38000) +# define BOOST_NO_TWO_PHASE_NAME_LOOKUP +#endif + +#if (__HP_aCC > 50000) && (__HP_aCC < 60000) +# define BOOST_NO_UNREACHABLE_RETURN_DETECTION +# define BOOST_NO_TEMPLATE_TEMPLATES +# define BOOST_NO_SWPRINTF +# define BOOST_NO_DEPENDENT_TYPES_IN_TEMPLATE_VALUE_PARAMETERS +# define BOOST_NO_IS_ABSTRACT +# define BOOST_NO_MEMBER_TEMPLATE_FRIENDS +#endif + +// optional features rather than defects: +#if (__HP_aCC >= 33900) +# define BOOST_HAS_LONG_LONG +# define BOOST_HAS_PARTIAL_STD_ALLOCATOR +#endif + +#if (__HP_aCC >= 50000 ) && (__HP_aCC <= 53800 ) || (__HP_aCC < 31300 ) +# define BOOST_NO_MEMBER_TEMPLATE_KEYWORD +#endif + +// This macro should not be defined when compiling in strict ansi +// mode, but, currently, we don't have the ability to determine +// what standard mode we are compiling with. Some future version +// of aCC6 compiler will provide predefined macros reflecting the +// compilation options, including the standard mode. +#if (__HP_aCC >= 60000) || ((__HP_aCC > 38000) && defined(__hpxstd98)) +# define BOOST_NO_TWO_PHASE_NAME_LOOKUP +#endif + +#define BOOST_COMPILER "HP aCC version " BOOST_STRINGIZE(__HP_aCC) + +// +// versions check: +// we don't support HP aCC prior to version 33000: +#if __HP_aCC < 33000 +# error "Compiler not supported or configured - please reconfigure" +#endif + +// +// Extended checks for supporting aCC on PA-RISC +#if __HP_aCC > 30000 && __HP_aCC < 50000 +# if __HP_aCC < 38000 + // versions prior to version A.03.80 not supported +# error "Compiler version not supported - version A.03.80 or higher is required" +# elif !defined(__hpxstd98) + // must compile using the option +hpxstd98 with version A.03.80 and above +# error "Compiler option '+hpxstd98' is required for proper support" +# endif //PA-RISC +#endif + +// +// C++0x features +// +// See boost\config\suffix.hpp for BOOST_NO_LONG_LONG +// +#if !defined(__EDG__) + +#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_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_THREAD_LOCAL +#define BOOST_NO_CXX11_UNRESTRICTED_UNION + +/* + See https://forums13.itrc.hp.com/service/forums/questionanswer.do?threadId=1443331 and + https://forums13.itrc.hp.com/service/forums/questionanswer.do?threadId=1443436 +*/ + +#if (__HP_aCC < 62500) || !defined(HP_CXX0x_SOURCE) + #define BOOST_NO_CXX11_VARIADIC_MACROS +#endif + +#endif + +// +// last known and checked version for HP-UX/ia64 is 61300 +// last known and checked version for PA-RISC is 38000 +#if ((__HP_aCC > 61300) || ((__HP_aCC > 38000) && defined(__hpxstd98))) +# if defined(BOOST_ASSERT_CONFIG) +# error "boost: Unknown compiler version - please run the configure tests and report the results" +# endif +#endif diff --git a/third_party/boost/libs/config/include/boost/config/compiler/intel.hpp b/third_party/boost/libs/config/include/boost/config/compiler/intel.hpp new file mode 100644 index 00000000000..6a343972e2e --- /dev/null +++ b/third_party/boost/libs/config/include/boost/config/compiler/intel.hpp @@ -0,0 +1,577 @@ +// (C) Copyright John Maddock 2001-8. +// (C) Copyright Peter Dimov 2001. +// (C) Copyright Jens Maurer 2001. +// (C) Copyright David Abrahams 2002 - 2003. +// (C) Copyright Aleksey Gurtovoy 2002 - 2003. +// (C) Copyright Guillaume Melquiond 2002 - 2003. +// (C) Copyright Beman Dawes 2003. +// (C) Copyright Martin Wille 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. + +// Intel compiler setup: + +#if defined(__INTEL_COMPILER) && (__INTEL_COMPILER >= 1500) && (defined(_MSC_VER) || defined(__GNUC__)) + +#ifdef _MSC_VER + +#include + +#undef BOOST_MSVC +#undef BOOST_MSVC_FULL_VER + +#if (__INTEL_COMPILER >= 1500) && (_MSC_VER >= 1900) +// +// These appear to be supported, even though VC++ may not support them: +// +#define BOOST_HAS_EXPM1 +#define BOOST_HAS_LOG1P +#undef BOOST_NO_CXX14_BINARY_LITERALS +// This one may be a little risky to enable?? +#undef BOOST_NO_SFINAE_EXPR + +#endif + +#if (__INTEL_COMPILER <= 1600) && !defined(BOOST_NO_CXX14_VARIABLE_TEMPLATES) +# define BOOST_NO_CXX14_VARIABLE_TEMPLATES +#endif + +#else // defined(_MSC_VER) + +#include + +#undef BOOST_GCC_VERSION +#undef BOOST_GCC_CXX11 +#undef BOOST_GCC +#undef BOOST_FALLTHROUGH + +// Broken in all versions up to 17 (newer versions not tested) +#if (__INTEL_COMPILER <= 1700) && !defined(BOOST_NO_CXX14_CONSTEXPR) +# define BOOST_NO_CXX14_CONSTEXPR +#endif + +#if (__INTEL_COMPILER >= 1800) && (__cplusplus >= 201703) +# define BOOST_FALLTHROUGH [[fallthrough]] +#endif + +#endif // defined(_MSC_VER) + +#undef BOOST_COMPILER + +#if defined(__INTEL_COMPILER) +#if __INTEL_COMPILER == 9999 +# define BOOST_INTEL_CXX_VERSION 1200 // Intel bug in 12.1. +#else +# define BOOST_INTEL_CXX_VERSION __INTEL_COMPILER +#endif +#elif defined(__ICL) +# define BOOST_INTEL_CXX_VERSION __ICL +#elif defined(__ICC) +# define BOOST_INTEL_CXX_VERSION __ICC +#elif defined(__ECC) +# define BOOST_INTEL_CXX_VERSION __ECC +#endif + +// Flags determined by comparing output of 'icpc -dM -E' with and without '-std=c++0x' +#if (!(defined(_WIN32) || defined(_WIN64)) && defined(__STDC_HOSTED__) && (__STDC_HOSTED__ && (BOOST_INTEL_CXX_VERSION <= 1200))) || defined(__GXX_EXPERIMENTAL_CPP0X__) || defined(__GXX_EXPERIMENTAL_CXX0X__) +# define BOOST_INTEL_STDCXX0X +#endif +#if defined(_MSC_VER) && (_MSC_VER >= 1600) +# define BOOST_INTEL_STDCXX0X +#endif + +#ifdef __GNUC__ +# define BOOST_INTEL_GCC_VERSION (__GNUC__ * 10000 + __GNUC_MINOR__ * 100 + __GNUC_PATCHLEVEL__) +#endif + +#if !defined(BOOST_COMPILER) +# if defined(BOOST_INTEL_STDCXX0X) +# define BOOST_COMPILER "Intel C++ C++0x mode version " BOOST_STRINGIZE(BOOST_INTEL_CXX_VERSION) +# else +# define BOOST_COMPILER "Intel C++ version " BOOST_STRINGIZE(BOOST_INTEL_CXX_VERSION) +# endif +#endif + +#define BOOST_INTEL BOOST_INTEL_CXX_VERSION + +#if defined(_WIN32) || defined(_WIN64) +# define BOOST_INTEL_WIN BOOST_INTEL +#else +# define BOOST_INTEL_LINUX BOOST_INTEL +#endif + +#else // defined(__INTEL_COMPILER) && (__INTEL_COMPILER >= 1500) && (defined(_MSC_VER) || defined(__GNUC__)) + +#include + +#if defined(__INTEL_COMPILER) +#if __INTEL_COMPILER == 9999 +# define BOOST_INTEL_CXX_VERSION 1200 // Intel bug in 12.1. +#else +# define BOOST_INTEL_CXX_VERSION __INTEL_COMPILER +#endif +#elif defined(__ICL) +# define BOOST_INTEL_CXX_VERSION __ICL +#elif defined(__ICC) +# define BOOST_INTEL_CXX_VERSION __ICC +#elif defined(__ECC) +# define BOOST_INTEL_CXX_VERSION __ECC +#endif + +// Flags determined by comparing output of 'icpc -dM -E' with and without '-std=c++0x' +#if (!(defined(_WIN32) || defined(_WIN64)) && defined(__STDC_HOSTED__) && (__STDC_HOSTED__ && (BOOST_INTEL_CXX_VERSION <= 1200))) || defined(__GXX_EXPERIMENTAL_CPP0X__) || defined(__GXX_EXPERIMENTAL_CXX0X__) +# define BOOST_INTEL_STDCXX0X +#endif +#if defined(_MSC_VER) && (_MSC_VER >= 1600) +# define BOOST_INTEL_STDCXX0X +#endif + +#ifdef __GNUC__ +# define BOOST_INTEL_GCC_VERSION (__GNUC__ * 10000 + __GNUC_MINOR__ * 100 + __GNUC_PATCHLEVEL__) +#endif + +#if !defined(BOOST_COMPILER) +# if defined(BOOST_INTEL_STDCXX0X) +# define BOOST_COMPILER "Intel C++ C++0x mode version " BOOST_STRINGIZE(BOOST_INTEL_CXX_VERSION) +# else +# define BOOST_COMPILER "Intel C++ version " BOOST_STRINGIZE(BOOST_INTEL_CXX_VERSION) +# endif +#endif + +#define BOOST_INTEL BOOST_INTEL_CXX_VERSION + +#if defined(_WIN32) || defined(_WIN64) +# define BOOST_INTEL_WIN BOOST_INTEL +#else +# define BOOST_INTEL_LINUX BOOST_INTEL +#endif + +#if (BOOST_INTEL_CXX_VERSION <= 600) + +# if defined(_MSC_VER) && (_MSC_VER <= 1300) // added check for <= VC 7 (Peter Dimov) + +// Boost libraries assume strong standard conformance unless otherwise +// indicated by a config macro. As configured by Intel, the EDG front-end +// requires certain compiler options be set to achieve that strong conformance. +// Particularly /Qoption,c,--arg_dep_lookup (reported by Kirk Klobe & Thomas Witt) +// and /Zc:wchar_t,forScope. See boost-root/tools/build/intel-win32-tools.jam for +// details as they apply to particular versions of the compiler. When the +// compiler does not predefine a macro indicating if an option has been set, +// this config file simply assumes the option has been set. +// Thus BOOST_NO_ARGUMENT_DEPENDENT_LOOKUP will not be defined, even if +// the compiler option is not enabled. + +# define BOOST_NO_SWPRINTF +# endif + +// Void returns, 64 bit integrals don't work when emulating VC 6 (Peter Dimov) + +# if defined(_MSC_VER) && (_MSC_VER <= 1200) +# define BOOST_NO_VOID_RETURNS +# define BOOST_NO_INTEGRAL_INT64_T +# endif + +#endif + +#if (BOOST_INTEL_CXX_VERSION <= 710) && defined(_WIN32) +# define BOOST_NO_POINTER_TO_MEMBER_TEMPLATE_PARAMETERS +#endif + +// See http://aspn.activestate.com/ASPN/Mail/Message/boost/1614864 +#if BOOST_INTEL_CXX_VERSION < 600 +# define BOOST_NO_INTRINSIC_WCHAR_T +#else +// We should test the macro _WCHAR_T_DEFINED to check if the compiler +// supports wchar_t natively. *BUT* there is a problem here: the standard +// headers define this macro if they typedef wchar_t. Anyway, we're lucky +// because they define it without a value, while Intel C++ defines it +// to 1. So we can check its value to see if the macro was defined natively +// or not. +// Under UNIX, the situation is exactly the same, but the macro _WCHAR_T +// is used instead. +# if ((_WCHAR_T_DEFINED + 0) == 0) && ((_WCHAR_T + 0) == 0) +# define BOOST_NO_INTRINSIC_WCHAR_T +# endif +#endif + +#if defined(__GNUC__) && !defined(BOOST_FUNCTION_SCOPE_USING_DECLARATION_BREAKS_ADL) +// +// Figure out when Intel is emulating this gcc bug +// (All Intel versions prior to 9.0.26, and versions +// later than that if they are set up to emulate gcc 3.2 +// or earlier): +// +# if ((__GNUC__ == 3) && (__GNUC_MINOR__ <= 2)) || (BOOST_INTEL < 900) || (__INTEL_COMPILER_BUILD_DATE < 20050912) +# define BOOST_FUNCTION_SCOPE_USING_DECLARATION_BREAKS_ADL +# endif +#endif +#if (defined(__GNUC__) && (__GNUC__ < 4)) || (defined(_WIN32) && (BOOST_INTEL_CXX_VERSION <= 1200)) || (BOOST_INTEL_CXX_VERSION <= 1200) +// GCC or VC emulation: +#define BOOST_NO_TWO_PHASE_NAME_LOOKUP +#endif +// +// Verify that we have actually got BOOST_NO_INTRINSIC_WCHAR_T +// set correctly, if we don't do this now, we will get errors later +// in type_traits code among other things, getting this correct +// for the Intel compiler is actually remarkably fragile and tricky: +// +#ifdef __cplusplus +#if defined(BOOST_NO_INTRINSIC_WCHAR_T) +#include +template< typename T > struct assert_no_intrinsic_wchar_t; +template<> struct assert_no_intrinsic_wchar_t { typedef void type; }; +// if you see an error here then you need to unset BOOST_NO_INTRINSIC_WCHAR_T +// where it is defined above: +typedef assert_no_intrinsic_wchar_t::type assert_no_intrinsic_wchar_t_; +#else +template< typename T > struct assert_intrinsic_wchar_t; +template<> struct assert_intrinsic_wchar_t {}; +// if you see an error here then define BOOST_NO_INTRINSIC_WCHAR_T on the command line: +template<> struct assert_intrinsic_wchar_t {}; +#endif +#endif + +#if defined(_MSC_VER) && (_MSC_VER+0 >= 1000) +# if _MSC_VER >= 1200 +# define BOOST_HAS_MS_INT64 +# endif +# define BOOST_NO_SWPRINTF +# define BOOST_NO_TWO_PHASE_NAME_LOOKUP +#elif defined(_WIN32) +# define BOOST_DISABLE_WIN32 +#endif + +// I checked version 6.0 build 020312Z, it implements the NRVO. +// Correct this as you find out which version of the compiler +// implemented the NRVO first. (Daniel Frey) +#if (BOOST_INTEL_CXX_VERSION >= 600) +# define BOOST_HAS_NRVO +#endif + +// Branch prediction hints +// I'm not sure 8.0 was the first version to support these builtins, +// update the condition if the version is not accurate. (Andrey Semashev) +#if defined(__GNUC__) && BOOST_INTEL_CXX_VERSION >= 800 +#define BOOST_LIKELY(x) __builtin_expect(x, 1) +#define BOOST_UNLIKELY(x) __builtin_expect(x, 0) +#endif + +// RTTI +// __RTTI is the EDG macro +// __INTEL_RTTI__ is the Intel macro +// __GXX_RTTI is the g++ macro +// _CPPRTTI is the MSVC++ macro +#if !defined(__RTTI) && !defined(__INTEL_RTTI__) && !defined(__GXX_RTTI) && !defined(_CPPRTTI) + +#if !defined(BOOST_NO_RTTI) +# define BOOST_NO_RTTI +#endif + +// in MS mode, static typeid works even when RTTI is off +#if !defined(_MSC_VER) && !defined(BOOST_NO_TYPEID) +# define BOOST_NO_TYPEID +#endif + +#endif + +// +// versions check: +// we don't support Intel prior to version 6.0: +#if BOOST_INTEL_CXX_VERSION < 600 +# error "Compiler not supported or configured - please reconfigure" +#endif + +// Intel on MacOS requires +#if defined(__APPLE__) && defined(__INTEL_COMPILER) +# define BOOST_NO_TWO_PHASE_NAME_LOOKUP +#endif + +// Intel on Altix Itanium +#if defined(__itanium__) && defined(__INTEL_COMPILER) +# define BOOST_NO_TWO_PHASE_NAME_LOOKUP +#endif + +// +// An attempt to value-initialize a pointer-to-member may trigger an +// internal error on Intel <= 11.1 (last checked version), as was +// reported by John Maddock, Intel support issue 589832, May 2010. +// Moreover, according to test results from Huang-Vista-x86_32_intel, +// intel-vc9-win-11.1 may leave a non-POD array uninitialized, in some +// cases when it should be value-initialized. +// (Niels Dekker, LKEB, May 2010) +// Apparently Intel 12.1 (compiler version number 9999 !!) has the same issue (compiler regression). +#if defined(__INTEL_COMPILER) +# if (__INTEL_COMPILER <= 1110) || (__INTEL_COMPILER == 9999) || (defined(_WIN32) && (__INTEL_COMPILER < 1600)) +# define BOOST_NO_COMPLETE_VALUE_INITIALIZATION +# endif +#endif + +// +// Dynamic shared object (DSO) and dynamic-link library (DLL) support +// +#if defined(__GNUC__) && (__GNUC__ >= 4) +# define BOOST_SYMBOL_EXPORT __attribute__((visibility("default"))) +# define BOOST_SYMBOL_IMPORT +# define BOOST_SYMBOL_VISIBLE __attribute__((visibility("default"))) +#endif + +// Type aliasing hint +#if defined(__GNUC__) && (BOOST_INTEL_CXX_VERSION >= 1300) +# define BOOST_MAY_ALIAS __attribute__((__may_alias__)) +#endif + +// +// C++0x features +// For each feature we need to check both the Intel compiler version, +// and the version of MSVC or GCC that we are emulating. +// See http://software.intel.com/en-us/articles/c0x-features-supported-by-intel-c-compiler/ +// for a list of which features were implemented in which Intel releases. +// +#if defined(BOOST_INTEL_STDCXX0X) +// BOOST_NO_CXX11_CONSTEXPR: +#if (BOOST_INTEL_CXX_VERSION >= 1500) && (!defined(BOOST_INTEL_GCC_VERSION) || (BOOST_INTEL_GCC_VERSION >= 40600)) && !defined(_MSC_VER) +// Available in earlier Intel versions, but fail our tests: +# undef BOOST_NO_CXX11_CONSTEXPR +#endif +// BOOST_NO_CXX11_NULLPTR: +#if (BOOST_INTEL_CXX_VERSION >= 1210) && (!defined(BOOST_INTEL_GCC_VERSION) || (BOOST_INTEL_GCC_VERSION >= 40600)) && (!defined(_MSC_VER) || (_MSC_VER >= 1600)) +# undef BOOST_NO_CXX11_NULLPTR +#endif +// BOOST_NO_CXX11_TEMPLATE_ALIASES +#if (BOOST_INTEL_CXX_VERSION >= 1210) && (!defined(BOOST_INTEL_GCC_VERSION) || (BOOST_INTEL_GCC_VERSION >= 40700)) && (!defined(_MSC_VER) || (_MSC_FULL_VER >= 180020827)) +# undef BOOST_NO_CXX11_TEMPLATE_ALIASES +#endif + +// BOOST_NO_CXX11_DECLTYPE +#if (BOOST_INTEL_CXX_VERSION >= 1200) && (!defined(BOOST_INTEL_GCC_VERSION) || (BOOST_INTEL_GCC_VERSION >= 40300)) && (!defined(_MSC_VER) || (_MSC_VER >= 1600)) +# undef BOOST_NO_CXX11_DECLTYPE +#endif + +// BOOST_NO_CXX11_DECLTYPE_N3276 +#if (BOOST_INTEL_CXX_VERSION >= 1500) && (!defined(BOOST_INTEL_GCC_VERSION) || (BOOST_INTEL_GCC_VERSION >= 40800)) && (!defined(_MSC_VER) || (_MSC_FULL_VER >= 180020827)) +# undef BOOST_NO_CXX11_DECLTYPE_N3276 +#endif + +// BOOST_NO_CXX11_FUNCTION_TEMPLATE_DEFAULT_ARGS +#if (BOOST_INTEL_CXX_VERSION >= 1200) && (!defined(BOOST_INTEL_GCC_VERSION) || (BOOST_INTEL_GCC_VERSION >= 40300)) && (!defined(_MSC_VER) || (_MSC_FULL_VER >= 180020827)) +# undef BOOST_NO_CXX11_FUNCTION_TEMPLATE_DEFAULT_ARGS +#endif + +// BOOST_NO_CXX11_RVALUE_REFERENCES +#if (BOOST_INTEL_CXX_VERSION >= 1300) && (!defined(BOOST_INTEL_GCC_VERSION) || (BOOST_INTEL_GCC_VERSION >= 40300)) && (!defined(_MSC_VER) || (_MSC_VER >= 1600)) +// This is available from earlier Intel versions, but breaks Filesystem and other libraries: +# undef BOOST_NO_CXX11_RVALUE_REFERENCES +#endif + +// BOOST_NO_CXX11_STATIC_ASSERT +#if (BOOST_INTEL_CXX_VERSION >= 1110) && (!defined(BOOST_INTEL_GCC_VERSION) || (BOOST_INTEL_GCC_VERSION >= 40300)) && (!defined(_MSC_VER) || (_MSC_VER >= 1600)) +# undef BOOST_NO_CXX11_STATIC_ASSERT +#endif + +// BOOST_NO_CXX11_VARIADIC_TEMPLATES +#if (BOOST_INTEL_CXX_VERSION >= 1200) && (!defined(BOOST_INTEL_GCC_VERSION) || (BOOST_INTEL_GCC_VERSION >= 40400)) && (!defined(_MSC_VER) || (_MSC_FULL_VER >= 180020827)) +# undef BOOST_NO_CXX11_VARIADIC_TEMPLATES +#endif + +// BOOST_NO_CXX11_VARIADIC_MACROS +#if (BOOST_INTEL_CXX_VERSION >= 1200) && (!defined(BOOST_INTEL_GCC_VERSION) || (BOOST_INTEL_GCC_VERSION >= 40200)) && (!defined(_MSC_VER) || (_MSC_VER >= 1400)) +# undef BOOST_NO_CXX11_VARIADIC_MACROS +#endif + +// BOOST_NO_CXX11_AUTO_DECLARATIONS +#if (BOOST_INTEL_CXX_VERSION >= 1200) && (!defined(BOOST_INTEL_GCC_VERSION) || (BOOST_INTEL_GCC_VERSION >= 40400)) && (!defined(_MSC_VER) || (_MSC_VER >= 1600)) +# undef BOOST_NO_CXX11_AUTO_DECLARATIONS +#endif + +// BOOST_NO_CXX11_AUTO_MULTIDECLARATIONS +#if (BOOST_INTEL_CXX_VERSION >= 1200) && (!defined(BOOST_INTEL_GCC_VERSION) || (BOOST_INTEL_GCC_VERSION >= 40400)) && (!defined(_MSC_VER) || (_MSC_VER >= 1600)) +# undef BOOST_NO_CXX11_AUTO_MULTIDECLARATIONS +#endif + +// BOOST_NO_CXX11_CHAR16_T +#if (BOOST_INTEL_CXX_VERSION >= 1400) && (!defined(BOOST_INTEL_GCC_VERSION) || (BOOST_INTEL_GCC_VERSION >= 40400)) && (!defined(_MSC_VER) || (_MSC_VER >= 9999)) +# undef BOOST_NO_CXX11_CHAR16_T +#endif + +// BOOST_NO_CXX11_CHAR32_T +#if (BOOST_INTEL_CXX_VERSION >= 1400) && (!defined(BOOST_INTEL_GCC_VERSION) || (BOOST_INTEL_GCC_VERSION >= 40400)) && (!defined(_MSC_VER) || (_MSC_VER >= 9999)) +# undef BOOST_NO_CXX11_CHAR32_T +#endif + +// BOOST_NO_CXX11_DEFAULTED_FUNCTIONS +#if (BOOST_INTEL_CXX_VERSION >= 1200) && (!defined(BOOST_INTEL_GCC_VERSION) || (BOOST_INTEL_GCC_VERSION >= 40400)) && (!defined(_MSC_VER) || (_MSC_FULL_VER >= 180020827)) +# undef BOOST_NO_CXX11_DEFAULTED_FUNCTIONS +#endif + +// BOOST_NO_CXX11_DELETED_FUNCTIONS +#if (BOOST_INTEL_CXX_VERSION >= 1200) && (!defined(BOOST_INTEL_GCC_VERSION) || (BOOST_INTEL_GCC_VERSION >= 40400)) && (!defined(_MSC_VER) || (_MSC_FULL_VER >= 180020827)) +# undef BOOST_NO_CXX11_DELETED_FUNCTIONS +#endif + +// BOOST_NO_CXX11_HDR_INITIALIZER_LIST +#if (BOOST_INTEL_CXX_VERSION >= 1400) && (!defined(BOOST_INTEL_GCC_VERSION) || (BOOST_INTEL_GCC_VERSION >= 40400)) && (!defined(_MSC_VER) || (_MSC_VER >= 1700)) +# undef BOOST_NO_CXX11_HDR_INITIALIZER_LIST +#endif + +// BOOST_NO_CXX11_SCOPED_ENUMS +#if (BOOST_INTEL_CXX_VERSION >= 1400) && (!defined(BOOST_INTEL_GCC_VERSION) || (BOOST_INTEL_GCC_VERSION >= 40501)) && (!defined(_MSC_VER) || (_MSC_VER >= 1700)) +// This is available but broken in earlier Intel releases. +# undef BOOST_NO_CXX11_SCOPED_ENUMS +#endif + +// BOOST_NO_SFINAE_EXPR +#if (BOOST_INTEL_CXX_VERSION >= 1200) && (!defined(BOOST_INTEL_GCC_VERSION) || (BOOST_INTEL_GCC_VERSION >= 40500)) && (!defined(_MSC_VER) || (_MSC_VER >= 9999)) +# undef BOOST_NO_SFINAE_EXPR +#endif + +// BOOST_NO_CXX11_SFINAE_EXPR +#if (BOOST_INTEL_CXX_VERSION >= 1500) && (!defined(BOOST_INTEL_GCC_VERSION) || (BOOST_INTEL_GCC_VERSION >= 40800)) && !defined(_MSC_VER) +# undef BOOST_NO_CXX11_SFINAE_EXPR +#endif + +// BOOST_NO_CXX11_EXPLICIT_CONVERSION_OPERATORS +#if (BOOST_INTEL_CXX_VERSION >= 1500) && (!defined(BOOST_INTEL_GCC_VERSION) || (BOOST_INTEL_GCC_VERSION >= 40500)) && (!defined(_MSC_VER) || (_MSC_FULL_VER >= 180020827)) +// This is available in earlier Intel releases, but breaks Multiprecision: +# undef BOOST_NO_CXX11_EXPLICIT_CONVERSION_OPERATORS +#endif + +// BOOST_NO_CXX11_LAMBDAS +#if (BOOST_INTEL_CXX_VERSION >= 1200) && (!defined(BOOST_INTEL_GCC_VERSION) || (BOOST_INTEL_GCC_VERSION >= 40500)) && (!defined(_MSC_VER) || (_MSC_VER >= 1600)) +# undef BOOST_NO_CXX11_LAMBDAS +#endif + +// BOOST_NO_CXX11_LOCAL_CLASS_TEMPLATE_PARAMETERS +#if (BOOST_INTEL_CXX_VERSION >= 1200) && (!defined(BOOST_INTEL_GCC_VERSION) || (BOOST_INTEL_GCC_VERSION >= 40500)) +# undef BOOST_NO_CXX11_LOCAL_CLASS_TEMPLATE_PARAMETERS +#endif + +// BOOST_NO_CXX11_RANGE_BASED_FOR +#if (BOOST_INTEL_CXX_VERSION >= 1400) && (!defined(BOOST_INTEL_GCC_VERSION) || (BOOST_INTEL_GCC_VERSION >= 40600)) && (!defined(_MSC_VER) || (_MSC_VER >= 1700)) +# undef BOOST_NO_CXX11_RANGE_BASED_FOR +#endif + +// BOOST_NO_CXX11_RAW_LITERALS +#if (BOOST_INTEL_CXX_VERSION >= 1400) && (!defined(BOOST_INTEL_GCC_VERSION) || (BOOST_INTEL_GCC_VERSION >= 40500)) && (!defined(_MSC_VER) || (_MSC_FULL_VER >= 180020827)) +# undef BOOST_NO_CXX11_RAW_LITERALS +#endif + +// BOOST_NO_CXX11_UNICODE_LITERALS +#if (BOOST_INTEL_CXX_VERSION >= 1400) && (!defined(BOOST_INTEL_GCC_VERSION) || (BOOST_INTEL_GCC_VERSION >= 40500)) && (!defined(_MSC_VER) || (_MSC_VER >= 9999)) +# undef BOOST_NO_CXX11_UNICODE_LITERALS +#endif + +// BOOST_NO_CXX11_NOEXCEPT +#if (BOOST_INTEL_CXX_VERSION >= 1500) && (!defined(BOOST_INTEL_GCC_VERSION) || (BOOST_INTEL_GCC_VERSION >= 40600)) && (!defined(_MSC_VER) || (_MSC_VER >= 9999)) +// Available in earlier Intel release, but generates errors when used with +// conditional exception specifications, for example in multiprecision: +# undef BOOST_NO_CXX11_NOEXCEPT +#endif + +// BOOST_NO_CXX11_UNIFIED_INITIALIZATION_SYNTAX +#if (BOOST_INTEL_CXX_VERSION >= 1400) && (!defined(BOOST_INTEL_GCC_VERSION) || (BOOST_INTEL_GCC_VERSION >= 40600)) && (!defined(_MSC_VER) || (_MSC_VER >= 9999)) +# undef BOOST_NO_CXX11_UNIFIED_INITIALIZATION_SYNTAX +#endif + +// BOOST_NO_CXX11_USER_DEFINED_LITERALS +#if (BOOST_INTEL_CXX_VERSION >= 1500) && (!defined(BOOST_INTEL_GCC_VERSION) || (BOOST_INTEL_GCC_VERSION >= 40700)) && (!defined(_MSC_VER) || (_MSC_FULL_VER >= 190021730)) +# undef BOOST_NO_CXX11_USER_DEFINED_LITERALS +#endif + +// 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 +#if (BOOST_INTEL_CXX_VERSION >= 1200) && (!defined(BOOST_INTEL_GCC_VERSION) || (BOOST_INTEL_GCC_VERSION >= 40400)) && (!defined(_MSC_VER) || (_MSC_FULL_VER >= 180020827)) +# undef BOOST_NO_CXX11_TRAILING_RESULT_TYPES +#endif + +// BOOST_NO_CXX11_INLINE_NAMESPACES +#if (BOOST_INTEL_CXX_VERSION >= 1400) && (!defined(BOOST_INTEL_GCC_VERSION) || (BOOST_INTEL_GCC_VERSION >= 40400)) && (!defined(_MSC_VER) || (_MSC_FULL_VER >= 190021730)) +# undef BOOST_NO_CXX11_INLINE_NAMESPACES +#endif + +// BOOST_NO_CXX11_REF_QUALIFIERS +#if (BOOST_INTEL_CXX_VERSION >= 1400) && (!defined(BOOST_INTEL_GCC_VERSION) || (BOOST_INTEL_GCC_VERSION >= 40800)) && (!defined(_MSC_VER) || (_MSC_FULL_VER >= 190021730)) +# undef BOOST_NO_CXX11_REF_QUALIFIERS +#endif + +// BOOST_NO_CXX11_FINAL +// BOOST_NO_CXX11_OVERRIDE +#if (BOOST_INTEL_CXX_VERSION >= 1400) && (!defined(BOOST_INTEL_GCC_VERSION) || (BOOST_INTEL_GCC_VERSION >= 40700)) && (!defined(_MSC_VER) || (_MSC_VER >= 1700)) +# undef BOOST_NO_CXX11_FINAL +# undef BOOST_NO_CXX11_OVERRIDE +#endif + +// BOOST_NO_CXX11_UNRESTRICTED_UNION +#if (BOOST_INTEL_CXX_VERSION >= 1400) && (!defined(BOOST_INTEL_GCC_VERSION) || (BOOST_INTEL_GCC_VERSION >= 50100)) && (!defined(_MSC_VER)) +# undef BOOST_NO_CXX11_UNRESTRICTED_UNION +#endif + +#endif // defined(BOOST_INTEL_STDCXX0X) + +// +// Broken in all versions up to 15: +#define BOOST_NO_CXX11_FIXED_LENGTH_VARIADIC_TEMPLATE_EXPANSION_PACKS + +#if defined(BOOST_INTEL_STDCXX0X) && (BOOST_INTEL_CXX_VERSION <= 1310) +# define BOOST_NO_CXX11_HDR_FUTURE +# define BOOST_NO_CXX11_HDR_INITIALIZER_LIST +#endif + +#if defined(BOOST_INTEL_STDCXX0X) && (BOOST_INTEL_CXX_VERSION == 1400) +// A regression in Intel's compiler means that seems to be broken in this release as well as : +# define BOOST_NO_CXX11_HDR_FUTURE +# define BOOST_NO_CXX11_HDR_TUPLE +#endif + +#if (BOOST_INTEL_CXX_VERSION < 1200) +// +// fenv.h appears not to work with Intel prior to 12.0: +// +# define BOOST_NO_FENV_H +#endif + +// Intel 13.10 fails to access defaulted functions of a base class declared in private or protected sections, +// producing the following errors: +// error #453: protected function "..." (declared at ...") is not accessible through a "..." pointer or object +#if (BOOST_INTEL_CXX_VERSION <= 1310) +# define BOOST_NO_CXX11_NON_PUBLIC_DEFAULTED_FUNCTIONS +#endif + +#if defined(_MSC_VER) && (_MSC_VER >= 1600) +# define BOOST_HAS_STDINT_H +#endif + +#if defined(__CUDACC__) +# if defined(BOOST_GCC_CXX11) +# define BOOST_NVCC_CXX11 +# else +# define BOOST_NVCC_CXX03 +# endif +#endif + +#if defined(__LP64__) && defined(__GNUC__) && (BOOST_INTEL_CXX_VERSION >= 1310) && !defined(BOOST_NVCC_CXX03) +# define BOOST_HAS_INT128 +#endif + +#endif // defined(__INTEL_COMPILER) && (__INTEL_COMPILER >= 1500) && (defined(_MSC_VER) || defined(__GNUC__)) +// +// last known and checked version: +#if (BOOST_INTEL_CXX_VERSION > 1700) +# if defined(BOOST_ASSERT_CONFIG) +# error "Boost.Config is older than your compiler - please check for an updated Boost release." +# elif defined(_MSC_VER) +// +// We don't emit this warning any more, since we have so few +// defect macros set anyway (just the one). +// +//# pragma message("boost: Unknown compiler version - please run the configure tests and report the results") +# endif +#endif + diff --git a/third_party/boost/libs/config/include/boost/config/compiler/kai.hpp b/third_party/boost/libs/config/include/boost/config/compiler/kai.hpp new file mode 100644 index 00000000000..0b22ec1d6c5 --- /dev/null +++ b/third_party/boost/libs/config/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/third_party/boost/libs/config/include/boost/config/compiler/metrowerks.hpp b/third_party/boost/libs/config/include/boost/config/compiler/metrowerks.hpp new file mode 100644 index 00000000000..448ab67bc35 --- /dev/null +++ b/third_party/boost/libs/config/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/third_party/boost/libs/config/include/boost/config/compiler/mpw.hpp b/third_party/boost/libs/config/include/boost/config/compiler/mpw.hpp new file mode 100644 index 00000000000..8433f371952 --- /dev/null +++ b/third_party/boost/libs/config/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/third_party/boost/libs/config/include/boost/config/compiler/nvcc.hpp b/third_party/boost/libs/config/include/boost/config/compiler/nvcc.hpp new file mode 100644 index 00000000000..419dd724ac1 --- /dev/null +++ b/third_party/boost/libs/config/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/third_party/boost/libs/config/include/boost/config/compiler/pathscale.hpp b/third_party/boost/libs/config/include/boost/config/compiler/pathscale.hpp new file mode 100644 index 00000000000..5348cf7f723 --- /dev/null +++ b/third_party/boost/libs/config/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/third_party/boost/libs/config/include/boost/config/compiler/pgi.hpp b/third_party/boost/libs/config/include/boost/config/compiler/pgi.hpp new file mode 100644 index 00000000000..4e909d8a17e --- /dev/null +++ b/third_party/boost/libs/config/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/third_party/boost/libs/config/include/boost/config/compiler/sgi_mipspro.hpp b/third_party/boost/libs/config/include/boost/config/compiler/sgi_mipspro.hpp new file mode 100644 index 00000000000..54433c99789 --- /dev/null +++ b/third_party/boost/libs/config/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/third_party/boost/libs/config/include/boost/config/compiler/sunpro_cc.hpp b/third_party/boost/libs/config/include/boost/config/compiler/sunpro_cc.hpp new file mode 100644 index 00000000000..490dc76dc84 --- /dev/null +++ b/third_party/boost/libs/config/include/boost/config/compiler/sunpro_cc.hpp @@ -0,0 +1,222 @@ +// (C) Copyright John Maddock 2001. +// (C) Copyright Jens Maurer 2001 - 2003. +// (C) Copyright Peter Dimov 2002. +// (C) Copyright Aleksey Gurtovoy 2002 - 2003. +// (C) Copyright David Abrahams 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. + +// Sun C++ compiler setup: + +# if __SUNPRO_CC <= 0x500 +# define BOOST_NO_MEMBER_TEMPLATES +# define BOOST_NO_FUNCTION_TEMPLATE_ORDERING +# endif + +# if (__SUNPRO_CC <= 0x520) + // + // Sunpro 5.2 and earler: + // + // although sunpro 5.2 supports the syntax for + // inline initialization it often gets the value + // wrong, especially where the value is computed + // from other constants (J Maddock 6th May 2001) +# define BOOST_NO_INCLASS_MEMBER_INITIALIZATION + + // Although sunpro 5.2 supports the syntax for + // partial specialization, it often seems to + // bind to the wrong specialization. Better + // to disable it until suppport becomes more stable + // (J Maddock 6th May 2001). +# define BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION +# endif + +# if (__SUNPRO_CC <= 0x530) + // Requesting debug info (-g) with Boost.Python results + // in an internal compiler error for "static const" + // initialized in-class. + // >> Assertion: (../links/dbg_cstabs.cc, line 611) + // while processing ../test.cpp at line 0. + // (Jens Maurer according to Gottfried Ganssauge 04 Mar 2002) +# define BOOST_NO_INCLASS_MEMBER_INITIALIZATION + + // SunPro 5.3 has better support for partial specialization, + // but breaks when compiling std::less > + // (Jens Maurer 4 Nov 2001). + + // std::less specialization fixed as reported by George + // Heintzelman; partial specialization re-enabled + // (Peter Dimov 17 Jan 2002) + +//# define BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION + + // integral constant expressions with 64 bit numbers fail +# define BOOST_NO_INTEGRAL_INT64_T +# endif + +# if (__SUNPRO_CC < 0x570) +# define BOOST_NO_TEMPLATE_TEMPLATES + // see http://lists.boost.org/MailArchives/boost/msg47184.php + // and http://lists.boost.org/MailArchives/boost/msg47220.php +# define BOOST_NO_INCLASS_MEMBER_INITIALIZATION +# define BOOST_NO_SFINAE +# define BOOST_NO_ARRAY_TYPE_SPECIALIZATIONS +# endif +# if (__SUNPRO_CC <= 0x580) +# define BOOST_NO_IS_ABSTRACT +# endif + +# if (__SUNPRO_CC <= 0x5100) + // Sun 5.10 may not correctly value-initialize objects of + // some user defined types, as was reported in April 2010 + // (CR 6947016), and confirmed by Steve Clamage. + // (Niels Dekker, LKEB, May 2010). +# define BOOST_NO_COMPLETE_VALUE_INITIALIZATION +# endif + +// +// Dynamic shared object (DSO) and dynamic-link library (DLL) support +// +#if __SUNPRO_CC > 0x500 +# define BOOST_SYMBOL_EXPORT __global +# define BOOST_SYMBOL_IMPORT __global +# 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 +#define BOOST_NO_SFINAE_EXPR +#define BOOST_NO_ADL_BARRIER +#define BOOST_NO_CXX11_VARIADIC_MACROS +#endif + +#if (__SUNPRO_CC < 0x5130) || (__cplusplus < 201100) +// C++11 only featuires in 12.4: +#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_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_CXX11_STATIC_ASSERT +#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 +#define BOOST_NO_CXX11_OVERRIDE +#define BOOST_NO_CXX11_UNRESTRICTED_UNION +#endif + +#if (__SUNPRO_CC < 0x5140) || (__cplusplus < 201103) +#define BOOST_NO_CXX11_VARIADIC_TEMPLATES +#define BOOST_NO_CXX11_UNIFIED_INITIALIZATION_SYNTAX +#define BOOST_NO_CXX11_FIXED_LENGTH_VARIADIC_TEMPLATE_EXPANSION_PACKS +#define BOOST_NO_CXX11_DECLTYPE_N3276 +#define BOOST_NO_CXX11_USER_DEFINED_LITERALS +#define BOOST_NO_CXX11_REF_QUALIFIERS +#define BOOST_NO_CXX11_THREAD_LOCAL +#endif + +#define BOOST_NO_COMPLETE_VALUE_INITIALIZATION +// +// C++0x features +// +# define BOOST_HAS_LONG_LONG + +#define BOOST_NO_CXX11_SFINAE_EXPR + +// 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) || (__cplusplus < 201402L) +# 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 + +// Turn on threading support for Solaris 12. +// Ticket #11972 +#if (__SUNPRO_CC >= 0x5140) && defined(__SunOS_5_12) && !defined(BOOST_HAS_THREADS) +# define BOOST_HAS_THREADS +#endif + +// +// Version +// + +#define BOOST_COMPILER "Sun compiler version " BOOST_STRINGIZE(__SUNPRO_CC) + +// +// versions check: +// we don't support sunpro prior to version 4: +#if __SUNPRO_CC < 0x400 +#error "Compiler not supported or configured - please reconfigure" +#endif +// +// last known and checked version: +#if (__SUNPRO_CC > 0x5150) +# if defined(BOOST_ASSERT_CONFIG) +# error "Boost.Config is older than your compiler - please check for an updated Boost release." +# endif +#endif diff --git a/third_party/boost/libs/config/include/boost/config/compiler/vacpp.hpp b/third_party/boost/libs/config/include/boost/config/compiler/vacpp.hpp new file mode 100644 index 00000000000..9cfa1adf85b --- /dev/null +++ b/third_party/boost/libs/config/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/third_party/boost/libs/config/include/boost/config/compiler/visualc.hpp b/third_party/boost/libs/config/include/boost/config/compiler/visualc.hpp new file mode 100644 index 00000000000..ae631219a63 --- /dev/null +++ b/third_party/boost/libs/config/include/boost/config/compiler/visualc.hpp @@ -0,0 +1,391 @@ +// (C) Copyright John Maddock 2001 - 2003. +// (C) Copyright Darin Adler 2001 - 2002. +// (C) Copyright Peter Dimov 2001. +// (C) Copyright Aleksey Gurtovoy 2002. +// (C) Copyright David Abrahams 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. +// +// Microsoft Visual C++ compiler setup: +// +// We need to be careful with the checks in this file, as contrary +// to popular belief there are versions with _MSC_VER with the final +// digit non-zero (mainly the MIPS cross compiler). +// +// So we either test _MSC_VER >= XXXX or else _MSC_VER < XXXX. +// No other comparisons (==, >, or <=) are safe. +// + +#define BOOST_MSVC _MSC_VER + +// +// Helper macro BOOST_MSVC_FULL_VER for use in Boost code: +// +#if _MSC_FULL_VER > 100000000 +# define BOOST_MSVC_FULL_VER _MSC_FULL_VER +#else +# define BOOST_MSVC_FULL_VER (_MSC_FULL_VER * 10) +#endif + +// Attempt to suppress VC6 warnings about the length of decorated names (obsolete): +#pragma warning( disable : 4503 ) // warning: decorated name length exceeded + +#define BOOST_HAS_PRAGMA_ONCE + +// +// versions check: +// we don't support Visual C++ prior to version 7.1: +#if _MSC_VER < 1310 +# error "Compiler not supported or configured - please reconfigure" +#endif + +// VS2005 (VC8) docs: __assume has been in Visual C++ for multiple releases +#define BOOST_UNREACHABLE_RETURN(x) __assume(0); + +#if _MSC_FULL_VER < 180020827 +# define BOOST_NO_FENV_H +#endif + +#if _MSC_VER < 1400 +// although a conforming signature for swprint exists in VC7.1 +// it appears not to actually work: +# define BOOST_NO_SWPRINTF +// Our extern template tests also fail for this compiler: +# define BOOST_NO_CXX11_EXTERN_TEMPLATE +// Variadic macros do not exist for VC7.1 and lower +# define BOOST_NO_CXX11_VARIADIC_MACROS +# define BOOST_NO_CXX11_LOCAL_CLASS_TEMPLATE_PARAMETERS +#endif + +#if _MSC_VER < 1500 // 140X == VC++ 8.0 +# define BOOST_NO_MEMBER_TEMPLATE_FRIENDS +#endif + +#if _MSC_VER < 1600 // 150X == VC++ 9.0 + // A bug in VC9: +# define BOOST_NO_ADL_BARRIER +#endif + + +#ifndef _NATIVE_WCHAR_T_DEFINED +# define BOOST_NO_INTRINSIC_WCHAR_T +#endif + +// +// check for exception handling support: +#if !defined(_CPPUNWIND) && !defined(BOOST_NO_EXCEPTIONS) +# define BOOST_NO_EXCEPTIONS +#endif + +// +// __int64 support: +// +#define BOOST_HAS_MS_INT64 +#if defined(_MSC_EXTENSIONS) || (_MSC_VER >= 1400) +# define BOOST_HAS_LONG_LONG +#else +# define BOOST_NO_LONG_LONG +#endif +#if (_MSC_VER >= 1400) && !defined(_DEBUG) +# define BOOST_HAS_NRVO +#endif +#if _MSC_VER >= 1600 // 160X == VC++ 10.0 +# define BOOST_HAS_PRAGMA_DETECT_MISMATCH +#endif +// +// disable Win32 API's if compiler extensions are +// turned off: +// +#if !defined(_MSC_EXTENSIONS) && !defined(BOOST_DISABLE_WIN32) +# define BOOST_DISABLE_WIN32 +#endif +#if !defined(_CPPRTTI) && !defined(BOOST_NO_RTTI) +# 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: +// +#if (_MSC_VER >= 1700) && defined(_HAS_CXX17) && (_HAS_CXX17 > 0) +// # define BOOST_HAS_TR1_HASH // don't know if this is true yet. +// # define BOOST_HAS_TR1_TYPE_TRAITS // don't know if this is true yet. +# define BOOST_HAS_TR1_UNORDERED_MAP +# define BOOST_HAS_TR1_UNORDERED_SET +#endif + +// +// C++0x features +// +// See above for BOOST_NO_LONG_LONG + +// C++ features supported by VC++ 10 (aka 2010) +// +#if _MSC_VER < 1600 +# define BOOST_NO_CXX11_AUTO_DECLARATIONS +# define BOOST_NO_CXX11_AUTO_MULTIDECLARATIONS +# define BOOST_NO_CXX11_LAMBDAS +# define BOOST_NO_CXX11_RVALUE_REFERENCES +# define BOOST_NO_CXX11_STATIC_ASSERT +# define BOOST_NO_CXX11_NULLPTR +# define BOOST_NO_CXX11_DECLTYPE +#endif // _MSC_VER < 1600 + +#if _MSC_VER >= 1600 +# define BOOST_HAS_STDINT_H +#endif + +// C++11 features supported by VC++ 11 (aka 2012) +// +#if _MSC_VER < 1700 +# define BOOST_NO_CXX11_FINAL +# define BOOST_NO_CXX11_RANGE_BASED_FOR +# define BOOST_NO_CXX11_SCOPED_ENUMS +# define BOOST_NO_CXX11_OVERRIDE +#endif // _MSC_VER < 1700 + +// C++11 features supported by VC++ 12 (aka 2013). +// +#if _MSC_FULL_VER < 180020827 +# 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_RAW_LITERALS +# define BOOST_NO_CXX11_TEMPLATE_ALIASES +# define BOOST_NO_CXX11_TRAILING_RESULT_TYPES +# define BOOST_NO_CXX11_VARIADIC_TEMPLATES +# define BOOST_NO_CXX11_UNIFIED_INITIALIZATION_SYNTAX +# define BOOST_NO_CXX11_DECLTYPE_N3276 +#endif + +#if _MSC_FULL_VER >= 180020827 +#define BOOST_HAS_EXPM1 +#define BOOST_HAS_LOG1P +#endif + +// C++11 features supported by VC++ 14 (aka 2015) +// +#if (_MSC_FULL_VER < 190023026) +# define BOOST_NO_CXX11_NOEXCEPT +# define BOOST_NO_CXX11_DEFAULTED_MOVES +# 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 +# define BOOST_NO_CXX11_UNICODE_LITERALS +# define BOOST_NO_CXX14_DECLTYPE_AUTO +# define BOOST_NO_CXX14_INITIALIZED_LAMBDA_CAPTURES +# define BOOST_NO_CXX14_RETURN_TYPE_DEDUCTION +# define BOOST_NO_CXX14_BINARY_LITERALS +# define BOOST_NO_CXX14_GENERIC_LAMBDAS +# define BOOST_NO_CXX14_DIGIT_SEPARATORS +# define BOOST_NO_CXX11_THREAD_LOCAL +# define BOOST_NO_CXX11_UNRESTRICTED_UNION +#endif +// C++11 features supported by VC++ 14 update 3 (aka 2015) +// +#if (_MSC_FULL_VER < 190024210) +# define BOOST_NO_CXX14_VARIABLE_TEMPLATES +# define BOOST_NO_SFINAE_EXPR +# define BOOST_NO_CXX11_CONSTEXPR +#endif + +// C++14 features supported by VC++ 14.1 (Visual Studio 2017) +// +#if (_MSC_VER < 1910) +# define BOOST_NO_CXX14_AGGREGATE_NSDMI +#endif + +// C++17 features supported by VC++ 14.1 (Visual Studio 2017) Update 3 +// +#if (_MSC_VER < 1911) || (_MSVC_LANG < 201703) +# define BOOST_NO_CXX17_STRUCTURED_BINDINGS +# define BOOST_NO_CXX17_IF_CONSTEXPR +// Let the defaults handle these now: +//# define BOOST_NO_CXX17_HDR_OPTIONAL +//# define BOOST_NO_CXX17_HDR_STRING_VIEW +#endif + +// MSVC including version 14 has not yet completely +// implemented value-initialization, as is reported: +// "VC++ does not value-initialize members of derived classes without +// user-declared constructor", reported in 2009 by Sylvester Hesp: +// https://connect.microsoft.com/VisualStudio/feedback/details/484295 +// "Presence of copy constructor breaks member class initialization", +// reported in 2009 by Alex Vakulenko: +// https://connect.microsoft.com/VisualStudio/feedback/details/499606 +// "Value-initialization in new-expression", reported in 2005 by +// Pavel Kuznetsov (MetaCommunications Engineering): +// https://connect.microsoft.com/VisualStudio/feedback/details/100744 +// Reported again by John Maddock in 2015 for VC14: +// https://connect.microsoft.com/VisualStudio/feedback/details/1582233/c-subobjects-still-not-value-initialized-correctly +// See also: http://www.boost.org/libs/utility/value_init.htm#compiler_issues +// (Niels Dekker, LKEB, May 2010) +// Still present in VC15.5, Dec 2017. +#define BOOST_NO_COMPLETE_VALUE_INITIALIZATION +// +// C++ 11: +// +// This is supported with /permissive- for 15.5 onwards, unfortunately we appear to have no way to tell +// 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: +#define BOOST_NO_CXX11_SFINAE_EXPR +#endif +#if (_MSC_VER < 1915) || (_MSVC_LANG < 201402) +// C++ 14: +// Still gives internal compiler error for msvc-15.5: +# define BOOST_NO_CXX14_CONSTEXPR +#endif +// C++ 17: +#if (_MSC_VER < 1912) || (_MSVC_LANG < 201703) +#define BOOST_NO_CXX17_INLINE_VARIABLES +#define BOOST_NO_CXX17_FOLD_EXPRESSIONS +#endif + +// +// Things that don't work in clr mode: +// +#ifdef _M_CEE +#ifndef BOOST_NO_CXX11_THREAD_LOCAL +# define BOOST_NO_CXX11_THREAD_LOCAL +#endif +#if !defined(BOOST_NO_SFINAE_EXPR) && !defined(_MSVC_LANG) +# define BOOST_NO_SFINAE_EXPR +#endif +#ifndef BOOST_NO_CXX11_REF_QUALIFIERS +# define BOOST_NO_CXX11_REF_QUALIFIERS +#endif +#endif +#ifdef _M_CEE_PURE +#ifndef BOOST_NO_CXX11_CONSTEXPR +# define BOOST_NO_CXX11_CONSTEXPR +#endif +#endif + +// +// prefix and suffix headers: +// +#ifndef BOOST_ABI_PREFIX +# define BOOST_ABI_PREFIX "boost/config/abi/msvc_prefix.hpp" +#endif +#ifndef BOOST_ABI_SUFFIX +# 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 +// artificial versions assigned to them only refer to the versions of some IDE +// these compilers have been shipped with, and even that is not all of it. Some +// were shipped with freely downloadable SDKs, others as crosscompilers in eVC. +// IOW, you can't use these 'versions' in any sensible way. Sorry. +# if defined(UNDER_CE) +# if _MSC_VER < 1400 + // Note: I'm not aware of any CE compiler with version 13xx +# if defined(BOOST_ASSERT_CONFIG) +# error "boost: Unknown EVC++ compiler version - please run the configure tests and report the results" +# else +# pragma message("boost: Unknown EVC++ compiler version - please run the configure tests and report the results") +# endif +# elif _MSC_VER < 1500 +# define BOOST_COMPILER_VERSION evc8 +# elif _MSC_VER < 1600 +# define BOOST_COMPILER_VERSION evc9 +# elif _MSC_VER < 1700 +# define BOOST_COMPILER_VERSION evc10 +# elif _MSC_VER < 1800 +# define BOOST_COMPILER_VERSION evc11 +# elif _MSC_VER < 1900 +# define BOOST_COMPILER_VERSION evc12 +# elif _MSC_VER < 2000 +# define BOOST_COMPILER_VERSION evc14 +# else +# if defined(BOOST_ASSERT_CONFIG) +# error "boost: Unknown EVC++ compiler version - please run the configure tests and report the results" +# else +# pragma message("boost: Unknown EVC++ compiler version - please run the configure tests and report the results") +# endif +# endif +# else +# if _MSC_VER < 1200 + // Note: Versions up to 10.0 aren't supported. +# define BOOST_COMPILER_VERSION 5.0 +# elif _MSC_VER < 1300 +# define BOOST_COMPILER_VERSION 6.0 +# elif _MSC_VER < 1310 +# define BOOST_COMPILER_VERSION 7.0 +# elif _MSC_VER < 1400 +# define BOOST_COMPILER_VERSION 7.1 +# elif _MSC_VER < 1500 +# define BOOST_COMPILER_VERSION 8.0 +# elif _MSC_VER < 1600 +# define BOOST_COMPILER_VERSION 9.0 +# elif _MSC_VER < 1700 +# define BOOST_COMPILER_VERSION 10.0 +# elif _MSC_VER < 1800 +# define BOOST_COMPILER_VERSION 11.0 +# elif _MSC_VER < 1900 +# define BOOST_COMPILER_VERSION 12.0 +# elif _MSC_VER < 1910 +# define BOOST_COMPILER_VERSION 14.0 +# elif _MSC_VER < 1920 +# 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 +# endif + +# define BOOST_COMPILER "Microsoft Visual C++ version " BOOST_STRINGIZE(BOOST_COMPILER_VERSION) +#endif + +#include + +// +// 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) + // + // Disabled as of March 2018 - the pace of VS releases is hard to keep up with + // and in any case, we have relatively few defect macros defined now. + // BOOST_PRAGMA_MESSAGE("Info: Boost.Config is older than your compiler version - probably nothing bad will happen - but you may wish to look for an updated Boost version. Define BOOST_CONFIG_SUPPRESS_OUTDATED_MESSAGE to suppress this message.") +# endif +#endif diff --git a/third_party/boost/libs/config/include/boost/config/compiler/xlcpp.hpp b/third_party/boost/libs/config/include/boost/config/compiler/xlcpp.hpp new file mode 100644 index 00000000000..99b8b245583 --- /dev/null +++ b/third_party/boost/libs/config/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/third_party/boost/libs/config/include/boost/config/compiler/xlcpp_zos.hpp b/third_party/boost/libs/config/include/boost/config/compiler/xlcpp_zos.hpp new file mode 100644 index 00000000000..9a177f1bb96 --- /dev/null +++ b/third_party/boost/libs/config/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/third_party/boost/libs/config/include/boost/config/detail/cxx_composite.hpp b/third_party/boost/libs/config/include/boost/config/detail/cxx_composite.hpp new file mode 100644 index 00000000000..a243d41f8e7 --- /dev/null +++ b/third_party/boost/libs/config/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/third_party/boost/libs/config/include/boost/config/detail/posix_features.hpp b/third_party/boost/libs/config/include/boost/config/detail/posix_features.hpp new file mode 100644 index 00000000000..d12954797f9 --- /dev/null +++ b/third_party/boost/libs/config/include/boost/config/detail/posix_features.hpp @@ -0,0 +1,95 @@ +// (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. + +// All POSIX feature tests go in this file, +// Note that we test _POSIX_C_SOURCE and _XOPEN_SOURCE as well +// _POSIX_VERSION and _XOPEN_VERSION: on some systems POSIX API's +// may be present but none-functional unless _POSIX_C_SOURCE and +// _XOPEN_SOURCE have been defined to the right value (it's up +// to the user to do this *before* including any header, although +// in most cases the compiler will do this for you). + +# if defined(BOOST_HAS_UNISTD_H) +# include + + // XOpen has , but is this the correct version check? +# if defined(_XOPEN_VERSION) && (_XOPEN_VERSION >= 3) +# define BOOST_HAS_NL_TYPES_H +# endif + + // POSIX version 6 requires +# if defined(_POSIX_VERSION) && (_POSIX_VERSION >= 200100) +# define BOOST_HAS_STDINT_H +# endif + + // POSIX version 2 requires +# if defined(_POSIX_VERSION) && (_POSIX_VERSION >= 199009L) +# define BOOST_HAS_DIRENT_H +# endif + + // POSIX version 3 requires to have sigaction: +# if defined(_POSIX_VERSION) && (_POSIX_VERSION >= 199506L) +# define BOOST_HAS_SIGACTION +# endif + // POSIX defines _POSIX_THREADS > 0 for pthread support, + // however some platforms define _POSIX_THREADS without + // a value, hence the (_POSIX_THREADS+0 >= 0) check. + // Strictly speaking this may catch platforms with a + // non-functioning stub , but such occurrences should + // occur very rarely if at all. +# if defined(_POSIX_THREADS) && (_POSIX_THREADS+0 >= 0) && !defined(BOOST_HAS_WINTHREADS) && !defined(BOOST_HAS_MPTASKS) +# define BOOST_HAS_PTHREADS +# endif + + // BOOST_HAS_NANOSLEEP: + // This is predicated on _POSIX_TIMERS or _XOPEN_REALTIME: +# if (defined(_POSIX_TIMERS) && (_POSIX_TIMERS+0 >= 0)) \ + || (defined(_XOPEN_REALTIME) && (_XOPEN_REALTIME+0 >= 0)) +# define BOOST_HAS_NANOSLEEP +# endif + + // BOOST_HAS_CLOCK_GETTIME: + // This is predicated on _POSIX_TIMERS (also on _XOPEN_REALTIME + // but at least one platform - linux - defines that flag without + // defining clock_gettime): +# if (defined(_POSIX_TIMERS) && (_POSIX_TIMERS+0 >= 0)) +# define BOOST_HAS_CLOCK_GETTIME +# endif + + // BOOST_HAS_SCHED_YIELD: + // This is predicated on _POSIX_PRIORITY_SCHEDULING or + // on _POSIX_THREAD_PRIORITY_SCHEDULING or on _XOPEN_REALTIME. +# if defined(_POSIX_PRIORITY_SCHEDULING) && (_POSIX_PRIORITY_SCHEDULING+0 > 0)\ + || (defined(_POSIX_THREAD_PRIORITY_SCHEDULING) && (_POSIX_THREAD_PRIORITY_SCHEDULING+0 > 0))\ + || (defined(_XOPEN_REALTIME) && (_XOPEN_REALTIME+0 >= 0)) +# define BOOST_HAS_SCHED_YIELD +# endif + + // BOOST_HAS_GETTIMEOFDAY: + // BOOST_HAS_PTHREAD_MUTEXATTR_SETTYPE: + // These are predicated on _XOPEN_VERSION, and appears to be first released + // in issue 4, version 2 (_XOPEN_VERSION > 500). + // Likewise for the functions log1p and expm1. +# if defined(_XOPEN_VERSION) && (_XOPEN_VERSION+0 >= 500) +# define BOOST_HAS_GETTIMEOFDAY +# if defined(_XOPEN_SOURCE) && (_XOPEN_SOURCE+0 >= 500) +# define BOOST_HAS_PTHREAD_MUTEXATTR_SETTYPE +# endif +# ifndef BOOST_HAS_LOG1P +# define BOOST_HAS_LOG1P +# endif +# ifndef BOOST_HAS_EXPM1 +# define BOOST_HAS_EXPM1 +# endif +# endif + +# endif + + + + diff --git a/third_party/boost/libs/config/include/boost/config/detail/select_compiler_config.hpp b/third_party/boost/libs/config/include/boost/config/detail/select_compiler_config.hpp new file mode 100644 index 00000000000..c3d99e1a43a --- /dev/null +++ b/third_party/boost/libs/config/include/boost/config/detail/select_compiler_config.hpp @@ -0,0 +1,157 @@ +// Boost compiler configuration selection header file + +// (C) Copyright John Maddock 2001 - 2003. +// (C) Copyright Martin Wille 2003. +// (C) Copyright Guillaume Melquiond 2003. +// +// 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. + +// locate which compiler we are using and define +// BOOST_COMPILER_CONFIG as needed: + +#if defined __CUDACC__ +// NVIDIA CUDA C++ compiler for GPU +# include "boost/config/compiler/nvcc.hpp" + +#endif + +#if defined(__GCCXML__) +// GCC-XML emulates other compilers, it has to appear first here! +# define BOOST_COMPILER_CONFIG "boost/config/compiler/gcc_xml.hpp" + +#elif defined(_CRAYC) +// EDG based Cray compiler: +# define BOOST_COMPILER_CONFIG "boost/config/compiler/cray.hpp" + +#elif defined __COMO__ +// Comeau C++ +# define BOOST_COMPILER_CONFIG "boost/config/compiler/comeau.hpp" + +#elif defined(__PATHSCALE__) && (__PATHCC__ >= 4) +// PathScale EKOPath compiler (has to come before clang and gcc) +# define BOOST_COMPILER_CONFIG "boost/config/compiler/pathscale.hpp" + +#elif defined(__INTEL_COMPILER) || defined(__ICL) || defined(__ICC) || defined(__ECC) +// Intel +# define BOOST_COMPILER_CONFIG "boost/config/compiler/intel.hpp" + +#elif defined __clang__ && !defined(__ibmxl__) && !defined(__CODEGEARC__) +// Clang C++ emulates GCC, so it has to appear early. +# define BOOST_COMPILER_CONFIG "boost/config/compiler/clang.hpp" + +#elif defined __DMC__ +// Digital Mars C++ +# define BOOST_COMPILER_CONFIG "boost/config/compiler/digitalmars.hpp" + +#elif defined __DCC__ +// Wind River Diab C++ +# define BOOST_COMPILER_CONFIG "boost/config/compiler/diab.hpp" + +#elif defined(__PGI) +// Portland Group Inc. +# define BOOST_COMPILER_CONFIG "boost/config/compiler/pgi.hpp" + +# elif defined(__GNUC__) && !defined(__ibmxl__) +// GNU C++: +# define BOOST_COMPILER_CONFIG "boost/config/compiler/gcc.hpp" + +#elif defined __KCC +// Kai C++ +# define BOOST_COMPILER_CONFIG "boost/config/compiler/kai.hpp" + +#elif defined __sgi +// SGI MIPSpro C++ +# define BOOST_COMPILER_CONFIG "boost/config/compiler/sgi_mipspro.hpp" + +#elif defined __DECCXX +// Compaq Tru64 Unix cxx +# define BOOST_COMPILER_CONFIG "boost/config/compiler/compaq_cxx.hpp" + +#elif defined __ghs +// Greenhills C++ +# define BOOST_COMPILER_CONFIG "boost/config/compiler/greenhills.hpp" + +#elif defined __CODEGEARC__ +// CodeGear - must be checked for before Borland +# define BOOST_COMPILER_CONFIG "boost/config/compiler/codegear.hpp" + +#elif defined __BORLANDC__ +// Borland +# define BOOST_COMPILER_CONFIG "boost/config/compiler/borland.hpp" + +#elif defined __MWERKS__ +// Metrowerks CodeWarrior +# define BOOST_COMPILER_CONFIG "boost/config/compiler/metrowerks.hpp" + +#elif defined __SUNPRO_CC +// Sun Workshop Compiler C++ +# define BOOST_COMPILER_CONFIG "boost/config/compiler/sunpro_cc.hpp" + +#elif defined __HP_aCC +// HP aCC +# define BOOST_COMPILER_CONFIG "boost/config/compiler/hp_acc.hpp" + +#elif defined(__MRC__) || defined(__SC__) +// MPW MrCpp or SCpp +# define BOOST_COMPILER_CONFIG "boost/config/compiler/mpw.hpp" + +#elif defined(__IBMCPP__) && defined(__COMPILER_VER__) && defined(__MVS__) +// IBM z/OS XL C/C++ +# define BOOST_COMPILER_CONFIG "boost/config/compiler/xlcpp_zos.hpp" + +#elif defined(__ibmxl__) +// IBM XL C/C++ for Linux (Little Endian) +# define BOOST_COMPILER_CONFIG "boost/config/compiler/xlcpp.hpp" + +#elif defined(__IBMCPP__) +// IBM Visual Age or IBM XL C/C++ for Linux (Big Endian) +# define BOOST_COMPILER_CONFIG "boost/config/compiler/vacpp.hpp" + +#elif defined _MSC_VER +// Microsoft Visual C++ +// +// Must remain the last #elif since some other vendors (Metrowerks, for +// example) also #define _MSC_VER +# define BOOST_COMPILER_CONFIG "boost/config/compiler/visualc.hpp" + +#elif defined (BOOST_ASSERT_CONFIG) +// this must come last - generate an error if we don't +// recognise the compiler: +# error "Unknown compiler - please configure (http://www.boost.org/libs/config/config.htm#configuring) and report the results to the main boost mailing list (http://www.boost.org/more/mailing_lists.htm#main)" + +#endif + +#if 0 +// +// This section allows dependency scanners to find all the headers we *might* include: +// +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#endif + diff --git a/third_party/boost/libs/config/include/boost/config/detail/select_platform_config.hpp b/third_party/boost/libs/config/include/boost/config/detail/select_platform_config.hpp new file mode 100644 index 00000000000..dbff74aaf74 --- /dev/null +++ b/third_party/boost/libs/config/include/boost/config/detail/select_platform_config.hpp @@ -0,0 +1,147 @@ +// Boost compiler configuration selection header file + +// (C) Copyright John Maddock 2001 - 2002. +// (C) Copyright Jens Maurer 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. + +// locate which platform we are on and define BOOST_PLATFORM_CONFIG as needed. +// Note that we define the headers to include using "header_name" not +// in order to prevent macro expansion within the header +// name (for example "linux" is a macro on linux systems). + +#if (defined(linux) || defined(__linux) || defined(__linux__) || defined(__GNU__) || defined(__GLIBC__)) && !defined(_CRAYC) +// linux, also other platforms (Hurd etc) that use GLIBC, should these really have their own config headers though? +# define BOOST_PLATFORM_CONFIG "boost/config/platform/linux.hpp" + +#elif defined(__FreeBSD__) || defined(__NetBSD__) || defined(__OpenBSD__) || defined(__DragonFly__) +// BSD: +# define BOOST_PLATFORM_CONFIG "boost/config/platform/bsd.hpp" + +#elif defined(sun) || defined(__sun) +// solaris: +# define BOOST_PLATFORM_CONFIG "boost/config/platform/solaris.hpp" + +#elif defined(__sgi) +// SGI Irix: +# define BOOST_PLATFORM_CONFIG "boost/config/platform/irix.hpp" + +#elif defined(__hpux) +// hp unix: +# define BOOST_PLATFORM_CONFIG "boost/config/platform/hpux.hpp" + +#elif defined(__CYGWIN__) +// cygwin is not win32: +# define BOOST_PLATFORM_CONFIG "boost/config/platform/cygwin.hpp" + +#elif defined(_WIN32) || defined(__WIN32__) || defined(WIN32) +// win32: +# define BOOST_PLATFORM_CONFIG "boost/config/platform/win32.hpp" + +#elif defined(__HAIKU__) +// Haiku +# define BOOST_PLATFORM_CONFIG "boost/config/platform/haiku.hpp" + +#elif defined(__BEOS__) +// BeOS +# define BOOST_PLATFORM_CONFIG "boost/config/platform/beos.hpp" + +#elif defined(macintosh) || defined(__APPLE__) || defined(__APPLE_CC__) +// MacOS +# define BOOST_PLATFORM_CONFIG "boost/config/platform/macos.hpp" + +#elif defined(__TOS_MVS__) +// IBM z/OS +# define BOOST_PLATFORM_CONFIG "boost/config/platform/zos.hpp" + +#elif defined(__IBMCPP__) || defined(_AIX) +// IBM AIX +# define BOOST_PLATFORM_CONFIG "boost/config/platform/aix.hpp" + +#elif defined(__amigaos__) +// AmigaOS +# define BOOST_PLATFORM_CONFIG "boost/config/platform/amigaos.hpp" + +#elif defined(__QNXNTO__) +// QNX: +# define BOOST_PLATFORM_CONFIG "boost/config/platform/qnxnto.hpp" + +#elif defined(__VXWORKS__) +// vxWorks: +# define BOOST_PLATFORM_CONFIG "boost/config/platform/vxworks.hpp" + +#elif defined(__SYMBIAN32__) +// Symbian: +# define BOOST_PLATFORM_CONFIG "boost/config/platform/symbian.hpp" + +#elif defined(_CRAYC) +// Cray: +# define BOOST_PLATFORM_CONFIG "boost/config/platform/cray.hpp" + +#elif defined(__VMS) +// VMS: +# define BOOST_PLATFORM_CONFIG "boost/config/platform/vms.hpp" + +#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) \ + || defined(__unix) \ + || defined(_XOPEN_SOURCE) \ + || defined(_POSIX_SOURCE) + + // generic unix platform: + +# ifndef BOOST_HAS_UNISTD_H +# define BOOST_HAS_UNISTD_H +# endif + +# include + +# endif + +# if defined (BOOST_ASSERT_CONFIG) + // this must come last - generate an error if we don't + // recognise the platform: +# error "Unknown platform - please configure and report the results to boost.org" +# endif + +#endif + +#if 0 +// +// This section allows dependency scanners to find all the files we *might* include: +// +# include "boost/config/platform/linux.hpp" +# include "boost/config/platform/bsd.hpp" +# include "boost/config/platform/solaris.hpp" +# include "boost/config/platform/irix.hpp" +# include "boost/config/platform/hpux.hpp" +# include "boost/config/platform/cygwin.hpp" +# include "boost/config/platform/win32.hpp" +# include "boost/config/platform/beos.hpp" +# include "boost/config/platform/macos.hpp" +# include "boost/config/platform/zos.hpp" +# include "boost/config/platform/aix.hpp" +# include "boost/config/platform/amigaos.hpp" +# include "boost/config/platform/qnxnto.hpp" +# include "boost/config/platform/vxworks.hpp" +# include "boost/config/platform/symbian.hpp" +# include "boost/config/platform/cray.hpp" +# include "boost/config/platform/vms.hpp" +# include + + + +#endif + diff --git a/third_party/boost/libs/config/include/boost/config/detail/select_stdlib_config.hpp b/third_party/boost/libs/config/include/boost/config/detail/select_stdlib_config.hpp new file mode 100644 index 00000000000..1a09dda1261 --- /dev/null +++ b/third_party/boost/libs/config/include/boost/config/detail/select_stdlib_config.hpp @@ -0,0 +1,121 @@ +// Boost compiler configuration selection header file + +// (C) Copyright John Maddock 2001 - 2003. +// (C) Copyright Jens Maurer 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. + +// locate which std lib we are using and define BOOST_STDLIB_CONFIG as needed: + +// First, check if __has_include is available and include can be located, +// otherwise include to determine if some version of STLport is in use as the std lib +// (do not rely on this header being included since users can short-circuit this header +// if they know whose std lib they are using.) +#if defined(__cplusplus) && defined(__has_include) +# if __has_include() +// It should be safe to include `` when it is present without checking +// the actual C++ language version as it consists solely of macro definitions. +// [version.syn] p1: The header supplies implementation-dependent +// information about the C++ standard library (e.g., version number and release date). +# include +# else +# include +# endif +#elif defined(__cplusplus) +# include +#else +# include +#endif + +#if defined(__SGI_STL_PORT) || defined(_STLPORT_VERSION) +// STLPort library; this _must_ come first, otherwise since +// STLport typically sits on top of some other library, we +// can end up detecting that first rather than STLport: +# define BOOST_STDLIB_CONFIG "boost/config/stdlib/stlport.hpp" + +#else + +// If our std lib was not some version of STLport, and has not otherwise +// been detected, then include as it is about +// the smallest of the std lib headers that includes real C++ stuff. +// Some std libs do not include their C++-related macros in +// so this additional include makes sure we get those definitions. +// Note: do not rely on this header being included since users can short-circuit this +// #include if they know whose std lib they are using. +#if !defined(__LIBCOMO__) && !defined(__STD_RWCOMPILER_H__) && !defined(_RWSTD_VER)\ + && !defined(_LIBCPP_VERSION) && !defined(__GLIBCPP__) && !defined(__GLIBCXX__)\ + && !defined(__STL_CONFIG_H) && !defined(__MSL_CPP__) && !defined(__IBMCPP__)\ + && !defined(MSIPL_COMPILE_H) && !defined(_YVALS) && !defined(_CPPLIB_VER) +#include +#endif + +#if defined(__LIBCOMO__) +// Comeau STL: +#define BOOST_STDLIB_CONFIG "boost/config/stdlib/libcomo.hpp" + +#elif defined(__STD_RWCOMPILER_H__) || defined(_RWSTD_VER) +// Rogue Wave library: +# define BOOST_STDLIB_CONFIG "boost/config/stdlib/roguewave.hpp" + +#elif defined(_LIBCPP_VERSION) +// libc++ +# define BOOST_STDLIB_CONFIG "boost/config/stdlib/libcpp.hpp" + +#elif defined(__GLIBCPP__) || defined(__GLIBCXX__) +// GNU libstdc++ 3 +# define BOOST_STDLIB_CONFIG "boost/config/stdlib/libstdcpp3.hpp" + +#elif defined(__STL_CONFIG_H) +// generic SGI STL +# define BOOST_STDLIB_CONFIG "boost/config/stdlib/sgi.hpp" + +#elif defined(__MSL_CPP__) +// MSL standard lib: +# define BOOST_STDLIB_CONFIG "boost/config/stdlib/msl.hpp" + +#elif defined(__IBMCPP__) && defined(__COMPILER_VER__) && defined(__MVS__) +// IBM z/OS XL C/C++ +# define BOOST_STDLIB_CONFIG "boost/config/stdlib/xlcpp_zos.hpp" + +#elif defined(__IBMCPP__) +// take the default VACPP std lib +# define BOOST_STDLIB_CONFIG "boost/config/stdlib/vacpp.hpp" + +#elif defined(MSIPL_COMPILE_H) +// Modena C++ standard library +# define BOOST_STDLIB_CONFIG "boost/config/stdlib/modena.hpp" + +#elif (defined(_YVALS) && !defined(__IBMCPP__)) || defined(_CPPLIB_VER) +// Dinkumware Library (this has to appear after any possible replacement libraries): +# define BOOST_STDLIB_CONFIG "boost/config/stdlib/dinkumware.hpp" + +#elif defined (BOOST_ASSERT_CONFIG) +// this must come last - generate an error if we don't +// recognise the library: +# error "Unknown standard library - please configure and report the results to boost.org" + +#endif + +#endif + +#if 0 +// +// This section allows dependency scanners to find all the files we *might* include: +// +# include "boost/config/stdlib/stlport.hpp" +# include "boost/config/stdlib/libcomo.hpp" +# include "boost/config/stdlib/roguewave.hpp" +# include "boost/config/stdlib/libcpp.hpp" +# include "boost/config/stdlib/libstdcpp3.hpp" +# include "boost/config/stdlib/sgi.hpp" +# include "boost/config/stdlib/msl.hpp" +# include "boost/config/stdlib/xlcpp_zos.hpp" +# include "boost/config/stdlib/vacpp.hpp" +# include "boost/config/stdlib/modena.hpp" +# include "boost/config/stdlib/dinkumware.hpp" +#endif + diff --git a/third_party/boost/libs/config/include/boost/config/detail/suffix.hpp b/third_party/boost/libs/config/include/boost/config/detail/suffix.hpp new file mode 100644 index 00000000000..b28d46f1846 --- /dev/null +++ b/third_party/boost/libs/config/include/boost/config/detail/suffix.hpp @@ -0,0 +1,1294 @@ +// Boost config.hpp configuration header file ------------------------------// +// boostinspect:ndprecated_macros -- tell the inspect tool to ignore this file + +// Copyright (c) 2001-2003 John Maddock +// Copyright (c) 2001 Darin Adler +// Copyright (c) 2001 Peter Dimov +// Copyright (c) 2002 Bill Kempf +// Copyright (c) 2002 Jens Maurer +// Copyright (c) 2002-2003 David Abrahams +// Copyright (c) 2003 Gennaro Prota +// Copyright (c) 2003 Eric Friedman +// Copyright (c) 2010 Eric Jourdanneau, Joel Falcou +// 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. + +// Boost config.hpp policy and rationale documentation has been moved to +// http://www.boost.org/libs/config/ +// +// This file is intended to be stable, and relatively unchanging. +// It should contain boilerplate code only - no compiler specific +// code unless it is unavoidable - no changes unless unavoidable. + +#ifndef BOOST_CONFIG_SUFFIX_HPP +#define BOOST_CONFIG_SUFFIX_HPP + +#if defined(__GNUC__) && (__GNUC__ >= 4) +// +// Some GCC-4.x versions issue warnings even when __extension__ is used, +// so use this as a workaround: +// +#pragma GCC system_header +#endif + +// +// ensure that visibility macros are always defined, thus simplifying use +// +#ifndef BOOST_SYMBOL_EXPORT +# define BOOST_SYMBOL_EXPORT +#endif +#ifndef BOOST_SYMBOL_IMPORT +# define BOOST_SYMBOL_IMPORT +#endif +#ifndef BOOST_SYMBOL_VISIBLE +# 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, +// remember that since these just declare a bunch of macros, there should be +// no namespace issues from this. +// +#if !defined(BOOST_HAS_LONG_LONG) && !defined(BOOST_NO_LONG_LONG) \ + && !defined(BOOST_MSVC) && !defined(BOOST_BORLANDC) +# include +# if (defined(ULLONG_MAX) || defined(ULONG_LONG_MAX) || defined(ULONGLONG_MAX)) +# define BOOST_HAS_LONG_LONG +# else +# define BOOST_NO_LONG_LONG +# endif +#endif + +// GCC 3.x will clean up all of those nasty macro definitions that +// BOOST_NO_CTYPE_FUNCTIONS is intended to help work around, so undefine +// it under GCC 3.x. +#if defined(__GNUC__) && (__GNUC__ >= 3) && defined(BOOST_NO_CTYPE_FUNCTIONS) +# undef BOOST_NO_CTYPE_FUNCTIONS +#endif + +// +// Assume any extensions are in namespace std:: unless stated otherwise: +// +# ifndef BOOST_STD_EXTENSION_NAMESPACE +# define BOOST_STD_EXTENSION_NAMESPACE std +# endif + +// +// If cv-qualified specializations are not allowed, then neither are cv-void ones: +// +# if defined(BOOST_NO_CV_SPECIALIZATIONS) \ + && !defined(BOOST_NO_CV_VOID_SPECIALIZATIONS) +# define BOOST_NO_CV_VOID_SPECIALIZATIONS +# endif + +// +// If there is no numeric_limits template, then it can't have any compile time +// constants either! +// +# if defined(BOOST_NO_LIMITS) \ + && !defined(BOOST_NO_LIMITS_COMPILE_TIME_CONSTANTS) +# define BOOST_NO_LIMITS_COMPILE_TIME_CONSTANTS +# define BOOST_NO_MS_INT64_NUMERIC_LIMITS +# define BOOST_NO_LONG_LONG_NUMERIC_LIMITS +# endif + +// +// if there is no long long then there is no specialisation +// for numeric_limits either: +// +#if !defined(BOOST_HAS_LONG_LONG) && !defined(BOOST_NO_LONG_LONG_NUMERIC_LIMITS) +# define BOOST_NO_LONG_LONG_NUMERIC_LIMITS +#endif + +// +// if there is no __int64 then there is no specialisation +// for numeric_limits<__int64> either: +// +#if !defined(BOOST_HAS_MS_INT64) && !defined(BOOST_NO_MS_INT64_NUMERIC_LIMITS) +# define BOOST_NO_MS_INT64_NUMERIC_LIMITS +#endif + +// +// if member templates are supported then so is the +// VC6 subset of member templates: +// +# if !defined(BOOST_NO_MEMBER_TEMPLATES) \ + && !defined(BOOST_MSVC6_MEMBER_TEMPLATES) +# define BOOST_MSVC6_MEMBER_TEMPLATES +# endif + +// +// Without partial specialization, can't test for partial specialisation bugs: +// +# if defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION) \ + && !defined(BOOST_BCB_PARTIAL_SPECIALIZATION_BUG) +# define BOOST_BCB_PARTIAL_SPECIALIZATION_BUG +# endif + +// +// Without partial specialization, we can't have array-type partial specialisations: +// +# if defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION) \ + && !defined(BOOST_NO_ARRAY_TYPE_SPECIALIZATIONS) +# define BOOST_NO_ARRAY_TYPE_SPECIALIZATIONS +# endif + +// +// Without partial specialization, std::iterator_traits can't work: +// +# if defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION) \ + && !defined(BOOST_NO_STD_ITERATOR_TRAITS) +# define BOOST_NO_STD_ITERATOR_TRAITS +# endif + +// +// Without partial specialization, partial +// specialization with default args won't work either: +// +# if defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION) \ + && !defined(BOOST_NO_PARTIAL_SPECIALIZATION_IMPLICIT_DEFAULT_ARGS) +# define BOOST_NO_PARTIAL_SPECIALIZATION_IMPLICIT_DEFAULT_ARGS +# endif + +// +// Without member template support, we can't have template constructors +// in the standard library either: +// +# if defined(BOOST_NO_MEMBER_TEMPLATES) \ + && !defined(BOOST_MSVC6_MEMBER_TEMPLATES) \ + && !defined(BOOST_NO_TEMPLATED_ITERATOR_CONSTRUCTORS) +# define BOOST_NO_TEMPLATED_ITERATOR_CONSTRUCTORS +# endif + +// +// Without member template support, we can't have a conforming +// std::allocator template either: +// +# if defined(BOOST_NO_MEMBER_TEMPLATES) \ + && !defined(BOOST_MSVC6_MEMBER_TEMPLATES) \ + && !defined(BOOST_NO_STD_ALLOCATOR) +# define BOOST_NO_STD_ALLOCATOR +# endif + +// +// without ADL support then using declarations will break ADL as well: +// +#if defined(BOOST_NO_ARGUMENT_DEPENDENT_LOOKUP) && !defined(BOOST_FUNCTION_SCOPE_USING_DECLARATION_BREAKS_ADL) +# define BOOST_FUNCTION_SCOPE_USING_DECLARATION_BREAKS_ADL +#endif + +// +// Without typeid support we have no dynamic RTTI either: +// +#if defined(BOOST_NO_TYPEID) && !defined(BOOST_NO_RTTI) +# define BOOST_NO_RTTI +#endif + +// +// If we have a standard allocator, then we have a partial one as well: +// +#if !defined(BOOST_NO_STD_ALLOCATOR) +# define BOOST_HAS_PARTIAL_STD_ALLOCATOR +#endif + +// +// We can't have a working std::use_facet if there is no std::locale: +// +# if defined(BOOST_NO_STD_LOCALE) && !defined(BOOST_NO_STD_USE_FACET) +# define BOOST_NO_STD_USE_FACET +# endif + +// +// We can't have a std::messages facet if there is no std::locale: +// +# if defined(BOOST_NO_STD_LOCALE) && !defined(BOOST_NO_STD_MESSAGES) +# define BOOST_NO_STD_MESSAGES +# endif + +// +// We can't have a working std::wstreambuf if there is no std::locale: +// +# if defined(BOOST_NO_STD_LOCALE) && !defined(BOOST_NO_STD_WSTREAMBUF) +# define BOOST_NO_STD_WSTREAMBUF +# endif + +// +// We can't have a if there is no : +// +# if defined(BOOST_NO_CWCHAR) && !defined(BOOST_NO_CWCTYPE) +# define BOOST_NO_CWCTYPE +# endif + +// +// We can't have a swprintf if there is no : +// +# if defined(BOOST_NO_CWCHAR) && !defined(BOOST_NO_SWPRINTF) +# define BOOST_NO_SWPRINTF +# endif + +// +// If Win32 support is turned off, then we must turn off +// threading support also, unless there is some other +// thread API enabled: +// +#if defined(BOOST_DISABLE_WIN32) && defined(_WIN32) \ + && !defined(BOOST_DISABLE_THREADS) && !defined(BOOST_HAS_PTHREADS) +# define BOOST_DISABLE_THREADS +#endif + +// +// Turn on threading support if the compiler thinks that it's in +// multithreaded mode. We put this here because there are only a +// limited number of macros that identify this (if there's any missing +// from here then add to the appropriate compiler section): +// +#if (defined(__MT__) || defined(_MT) || defined(_REENTRANT) \ + || defined(_PTHREADS) || defined(__APPLE__) || defined(__DragonFly__)) \ + && !defined(BOOST_HAS_THREADS) +# define BOOST_HAS_THREADS +#endif + +// +// Turn threading support off if BOOST_DISABLE_THREADS is defined: +// +#if defined(BOOST_DISABLE_THREADS) && defined(BOOST_HAS_THREADS) +# undef BOOST_HAS_THREADS +#endif + +// +// Turn threading support off if we don't recognise the threading API: +// +#if defined(BOOST_HAS_THREADS) && !defined(BOOST_HAS_PTHREADS)\ + && !defined(BOOST_HAS_WINTHREADS) && !defined(BOOST_HAS_BETHREADS)\ + && !defined(BOOST_HAS_MPTASKS) +# undef BOOST_HAS_THREADS +#endif + +// +// Turn threading detail macros off if we don't (want to) use threading +// +#ifndef BOOST_HAS_THREADS +# undef BOOST_HAS_PTHREADS +# undef BOOST_HAS_PTHREAD_MUTEXATTR_SETTYPE +# undef BOOST_HAS_PTHREAD_YIELD +# undef BOOST_HAS_PTHREAD_DELAY_NP +# undef BOOST_HAS_WINTHREADS +# undef BOOST_HAS_BETHREADS +# undef BOOST_HAS_MPTASKS +#endif + +// +// If the compiler claims to be C99 conformant, then it had better +// have a : +// +# if defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901) +# define BOOST_HAS_STDINT_H +# ifndef BOOST_HAS_LOG1P +# define BOOST_HAS_LOG1P +# endif +# ifndef BOOST_HAS_EXPM1 +# define BOOST_HAS_EXPM1 +# endif +# endif + +// +// Define BOOST_NO_SLIST and BOOST_NO_HASH if required. +// Note that this is for backwards compatibility only. +// +# if !defined(BOOST_HAS_SLIST) && !defined(BOOST_NO_SLIST) +# define BOOST_NO_SLIST +# endif + +# if !defined(BOOST_HAS_HASH) && !defined(BOOST_NO_HASH) +# define BOOST_NO_HASH +# endif + +// +// Set BOOST_SLIST_HEADER if not set already: +// +#if defined(BOOST_HAS_SLIST) && !defined(BOOST_SLIST_HEADER) +# define BOOST_SLIST_HEADER +#endif + +// +// Set BOOST_HASH_SET_HEADER if not set already: +// +#if defined(BOOST_HAS_HASH) && !defined(BOOST_HASH_SET_HEADER) +# define BOOST_HASH_SET_HEADER +#endif + +// +// Set BOOST_HASH_MAP_HEADER if not set already: +// +#if defined(BOOST_HAS_HASH) && !defined(BOOST_HASH_MAP_HEADER) +# define BOOST_HASH_MAP_HEADER +#endif + +// BOOST_HAS_ABI_HEADERS +// This macro gets set if we have headers that fix the ABI, +// and prevent ODR violations when linking to external libraries: +#if defined(BOOST_ABI_PREFIX) && defined(BOOST_ABI_SUFFIX) && !defined(BOOST_HAS_ABI_HEADERS) +# define BOOST_HAS_ABI_HEADERS +#endif + +#if defined(BOOST_HAS_ABI_HEADERS) && defined(BOOST_DISABLE_ABI_HEADERS) +# undef BOOST_HAS_ABI_HEADERS +#endif + +// BOOST_NO_STDC_NAMESPACE workaround --------------------------------------// +// Because std::size_t usage is so common, even in boost headers which do not +// otherwise use the C library, the workaround is included here so +// that ugly workaround code need not appear in many other boost headers. +// NOTE WELL: This is a workaround for non-conforming compilers; +// must still be #included in the usual places so that inclusion +// works as expected with standard conforming compilers. The resulting +// double inclusion of is harmless. + +# if defined(BOOST_NO_STDC_NAMESPACE) && defined(__cplusplus) +# include + namespace std { using ::ptrdiff_t; using ::size_t; } +# endif + +// Workaround for the unfortunate min/max macros defined by some platform headers + +#define BOOST_PREVENT_MACRO_SUBSTITUTION + +#ifndef BOOST_USING_STD_MIN +# define BOOST_USING_STD_MIN() using std::min +#endif + +#ifndef BOOST_USING_STD_MAX +# define BOOST_USING_STD_MAX() using std::max +#endif + +// BOOST_NO_STD_MIN_MAX workaround -----------------------------------------// + +# if defined(BOOST_NO_STD_MIN_MAX) && defined(__cplusplus) + +namespace std { + template + inline const _Tp& min BOOST_PREVENT_MACRO_SUBSTITUTION (const _Tp& __a, const _Tp& __b) { + return __b < __a ? __b : __a; + } + template + inline const _Tp& max BOOST_PREVENT_MACRO_SUBSTITUTION (const _Tp& __a, const _Tp& __b) { + return __a < __b ? __b : __a; + } +} + +# endif + +// BOOST_STATIC_CONSTANT workaround --------------------------------------- // +// On compilers which don't allow in-class initialization of static integral +// constant members, we must use enums as a workaround if we want the constants +// to be available at compile-time. This macro gives us a convenient way to +// declare such constants. + +# ifdef BOOST_NO_INCLASS_MEMBER_INITIALIZATION +# define BOOST_STATIC_CONSTANT(type, assignment) enum { assignment } +# else +# define BOOST_STATIC_CONSTANT(type, assignment) static const type assignment +# endif + +// BOOST_USE_FACET / HAS_FACET workaround ----------------------------------// +// When the standard library does not have a conforming std::use_facet there +// are various workarounds available, but they differ from library to library. +// The same problem occurs with has_facet. +// These macros provide a consistent way to access a locale's facets. +// Usage: +// replace +// std::use_facet(loc); +// with +// BOOST_USE_FACET(Type, loc); +// Note do not add a std:: prefix to the front of BOOST_USE_FACET! +// Use for BOOST_HAS_FACET is analogous. + +#if defined(BOOST_NO_STD_USE_FACET) +# ifdef BOOST_HAS_TWO_ARG_USE_FACET +# define BOOST_USE_FACET(Type, loc) std::use_facet(loc, static_cast(0)) +# define BOOST_HAS_FACET(Type, loc) std::has_facet(loc, static_cast(0)) +# elif defined(BOOST_HAS_MACRO_USE_FACET) +# define BOOST_USE_FACET(Type, loc) std::_USE(loc, Type) +# define BOOST_HAS_FACET(Type, loc) std::_HAS(loc, Type) +# elif defined(BOOST_HAS_STLP_USE_FACET) +# define BOOST_USE_FACET(Type, loc) (*std::_Use_facet(loc)) +# define BOOST_HAS_FACET(Type, loc) std::has_facet< Type >(loc) +# endif +#else +# define BOOST_USE_FACET(Type, loc) std::use_facet< Type >(loc) +# define BOOST_HAS_FACET(Type, loc) std::has_facet< Type >(loc) +#endif + +// BOOST_NESTED_TEMPLATE workaround ------------------------------------------// +// Member templates are supported by some compilers even though they can't use +// the A::template member syntax, as a workaround replace: +// +// typedef typename A::template rebind binder; +// +// with: +// +// typedef typename A::BOOST_NESTED_TEMPLATE rebind binder; + +#ifndef BOOST_NO_MEMBER_TEMPLATE_KEYWORD +# define BOOST_NESTED_TEMPLATE template +#else +# define BOOST_NESTED_TEMPLATE +#endif + +// BOOST_UNREACHABLE_RETURN(x) workaround -------------------------------------// +// Normally evaluates to nothing, unless BOOST_NO_UNREACHABLE_RETURN_DETECTION +// is defined, in which case it evaluates to return x; Use when you have a return +// statement that can never be reached. + +#ifndef BOOST_UNREACHABLE_RETURN +# ifdef BOOST_NO_UNREACHABLE_RETURN_DETECTION +# define BOOST_UNREACHABLE_RETURN(x) return x; +# else +# define BOOST_UNREACHABLE_RETURN(x) +# endif +#endif + +// BOOST_DEDUCED_TYPENAME workaround ------------------------------------------// +// +// Some compilers don't support the use of `typename' for dependent +// types in deduced contexts, e.g. +// +// template void f(T, typename T::type); +// ^^^^^^^^ +// Replace these declarations with: +// +// template void f(T, BOOST_DEDUCED_TYPENAME T::type); + +#ifndef BOOST_NO_DEDUCED_TYPENAME +# define BOOST_DEDUCED_TYPENAME typename +#else +# define BOOST_DEDUCED_TYPENAME +#endif + +#ifndef BOOST_NO_TYPENAME_WITH_CTOR +# define BOOST_CTOR_TYPENAME typename +#else +# 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 +// (with -pedantic -ansi) unless it's use is prefixed by __extension__ +// +#if defined(BOOST_HAS_LONG_LONG) && defined(__cplusplus) +namespace boost{ +# ifdef __GNUC__ + __extension__ typedef long long long_long_type; + __extension__ typedef unsigned long long ulong_long_type; +# else + typedef long long long_long_type; + typedef unsigned long long ulong_long_type; +# endif +} +#endif +// same again for __int128: +#if defined(BOOST_HAS_INT128) && defined(__cplusplus) +namespace boost{ +# ifdef __GNUC__ + __extension__ typedef __int128 int128_type; + __extension__ typedef unsigned __int128 uint128_type; +# else + typedef __int128 int128_type; + typedef unsigned __int128 uint128_type; +# endif +} +#endif +// same again for __float128: +#if defined(BOOST_HAS_FLOAT128) && defined(__cplusplus) +namespace boost { +# ifdef __GNUC__ + __extension__ typedef __float128 float128_type; +# else + typedef __float128 float128_type; +# endif +} +#endif + +// BOOST_[APPEND_]EXPLICIT_TEMPLATE_[NON_]TYPE macros --------------------------// + +// These macros are obsolete. Port away and remove. + +# define BOOST_EXPLICIT_TEMPLATE_TYPE(t) +# define BOOST_EXPLICIT_TEMPLATE_TYPE_SPEC(t) +# define BOOST_EXPLICIT_TEMPLATE_NON_TYPE(t, v) +# define BOOST_EXPLICIT_TEMPLATE_NON_TYPE_SPEC(t, v) + +# define BOOST_APPEND_EXPLICIT_TEMPLATE_TYPE(t) +# define BOOST_APPEND_EXPLICIT_TEMPLATE_TYPE_SPEC(t) +# define BOOST_APPEND_EXPLICIT_TEMPLATE_NON_TYPE(t, v) +# define BOOST_APPEND_EXPLICIT_TEMPLATE_NON_TYPE_SPEC(t, v) + +// When BOOST_NO_STD_TYPEINFO is defined, we can just import +// the global definition into std namespace, +// see https://svn.boost.org/trac10/ticket/4115 +#if defined(BOOST_NO_STD_TYPEINFO) && defined(__cplusplus) && defined(BOOST_MSVC) +#include +namespace std{ using ::type_info; } +// Since we do now have typeinfo, undef the macro: +#undef BOOST_NO_STD_TYPEINFO +#endif + +// ---------------------------------------------------------------------------// + +// Helper macro BOOST_STRINGIZE: +// Helper macro BOOST_JOIN: + +#include + +// +// Set some default values for compiler/library/platform names. +// These are for debugging config setup only: +// +# ifndef BOOST_COMPILER +# define BOOST_COMPILER "Unknown ISO C++ Compiler" +# endif +# ifndef BOOST_STDLIB +# define BOOST_STDLIB "Unknown ISO standard library" +# endif +# ifndef BOOST_PLATFORM +# if defined(unix) || defined(__unix) || defined(_XOPEN_SOURCE) \ + || defined(_POSIX_SOURCE) +# define BOOST_PLATFORM "Generic Unix" +# else +# define BOOST_PLATFORM "Unknown" +# endif +# endif + +// +// Set some default values GPU support +// +# ifndef BOOST_GPU_ENABLED +# define BOOST_GPU_ENABLED +# endif + +// BOOST_RESTRICT ---------------------------------------------// +// Macro to use in place of 'restrict' keyword variants +#if !defined(BOOST_RESTRICT) +# if defined(_MSC_VER) +# define BOOST_RESTRICT __restrict +# if !defined(BOOST_NO_RESTRICT_REFERENCES) && (_MSC_FULL_VER < 190023026) +# define BOOST_NO_RESTRICT_REFERENCES +# endif +# elif defined(__GNUC__) && __GNUC__ > 3 + // Clang also defines __GNUC__ (as 4) +# define BOOST_RESTRICT __restrict__ +# else +# define BOOST_RESTRICT +# if !defined(BOOST_NO_RESTRICT_REFERENCES) +# define BOOST_NO_RESTRICT_REFERENCES +# endif +# endif +#endif + +// BOOST_MAY_ALIAS -----------------------------------------------// +// The macro expands to an attribute to mark a type that is allowed to alias other types. +// The macro is defined in the compiler-specific headers. +#if !defined(BOOST_MAY_ALIAS) +# define BOOST_NO_MAY_ALIAS +# define BOOST_MAY_ALIAS +#endif + +// BOOST_FORCEINLINE ---------------------------------------------// +// Macro to use in place of 'inline' to force a function to be inline +#if !defined(BOOST_FORCEINLINE) +# if defined(_MSC_VER) +# define BOOST_FORCEINLINE __forceinline +# elif defined(__GNUC__) && __GNUC__ > 3 + // Clang also defines __GNUC__ (as 4) +# define BOOST_FORCEINLINE inline __attribute__ ((__always_inline__)) +# else +# define BOOST_FORCEINLINE inline +# endif +#endif + +// BOOST_NOINLINE ---------------------------------------------// +// Macro to use in place of 'inline' to prevent a function to be inlined +#if !defined(BOOST_NOINLINE) +# if defined(_MSC_VER) +# define BOOST_NOINLINE __declspec(noinline) +# elif defined(__GNUC__) && __GNUC__ > 3 + // Clang also defines __GNUC__ (as 4) +# if defined(__CUDACC__) + // 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 +# else +# define BOOST_NOINLINE +# endif +#endif + +// BOOST_NORETURN ---------------------------------------------// +// Macro to use before a function declaration/definition to designate +// the function as not returning normally (i.e. with a return statement +// or by leaving the function scope, if the function return type is void). +#if !defined(BOOST_NORETURN) +# if defined(_MSC_VER) +# define BOOST_NORETURN __declspec(noreturn) +# elif defined(__GNUC__) || defined(__CODEGEARC__) && defined(__clang__) +# define BOOST_NORETURN __attribute__ ((__noreturn__)) +# elif defined(__has_attribute) && defined(__SUNPRO_CC) && (__SUNPRO_CC > 0x5130) +# if __has_attribute(noreturn) +# define BOOST_NORETURN [[noreturn]] +# endif +# elif defined(__has_cpp_attribute) +# if __has_cpp_attribute(noreturn) +# define BOOST_NORETURN [[noreturn]] +# endif +# endif +#endif + +#if !defined(BOOST_NORETURN) +# define BOOST_NO_NORETURN +# 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 +// +// if (BOOST_LIKELY(var == 10)) +// { +// // the most probable code here +// } +// +#if !defined(BOOST_LIKELY) +# define BOOST_LIKELY(x) x +#endif +#if !defined(BOOST_UNLIKELY) +# define BOOST_UNLIKELY(x) x +#endif + +#if !defined(BOOST_NO_CXX11_OVERRIDE) +# define BOOST_OVERRIDE override +#else +# define BOOST_OVERRIDE +#endif + +// Type and data alignment specification +// +#if !defined(BOOST_ALIGNMENT) +# if !defined(BOOST_NO_CXX11_ALIGNAS) +# define BOOST_ALIGNMENT(x) alignas(x) +# elif defined(_MSC_VER) +# define BOOST_ALIGNMENT(x) __declspec(align(x)) +# elif defined(__GNUC__) +# define BOOST_ALIGNMENT(x) __attribute__ ((__aligned__(x))) +# else +# define BOOST_NO_ALIGNMENT +# define BOOST_ALIGNMENT(x) +# endif +#endif + +// Lack of non-public defaulted functions is implied by the lack of any defaulted functions +#if !defined(BOOST_NO_CXX11_NON_PUBLIC_DEFAULTED_FUNCTIONS) && defined(BOOST_NO_CXX11_DEFAULTED_FUNCTIONS) +# define BOOST_NO_CXX11_NON_PUBLIC_DEFAULTED_FUNCTIONS +#endif + +// Lack of defaulted moves is implied by the lack of either rvalue references or any defaulted functions +#if !defined(BOOST_NO_CXX11_DEFAULTED_MOVES) && (defined(BOOST_NO_CXX11_DEFAULTED_FUNCTIONS) || defined(BOOST_NO_CXX11_RVALUE_REFERENCES)) +# define BOOST_NO_CXX11_DEFAULTED_MOVES +#endif + +// Defaulted and deleted function declaration helpers +// These macros are intended to be inside a class definition. +// BOOST_DEFAULTED_FUNCTION accepts the function declaration and its +// body, which will be used if the compiler doesn't support defaulted functions. +// BOOST_DELETED_FUNCTION only accepts the function declaration. It +// will expand to a private function declaration, if the compiler doesn't support +// deleted functions. Because of this it is recommended to use BOOST_DELETED_FUNCTION +// in the end of the class definition. +// +// class my_class +// { +// public: +// // Default-constructible +// BOOST_DEFAULTED_FUNCTION(my_class(), {}) +// // Copying prohibited +// BOOST_DELETED_FUNCTION(my_class(my_class const&)) +// BOOST_DELETED_FUNCTION(my_class& operator= (my_class const&)) +// }; +// +#if !(defined(BOOST_NO_CXX11_DEFAULTED_FUNCTIONS) || defined(BOOST_NO_CXX11_NON_PUBLIC_DEFAULTED_FUNCTIONS)) +# define BOOST_DEFAULTED_FUNCTION(fun, body) fun = default; +#else +# define BOOST_DEFAULTED_FUNCTION(fun, body) fun body +#endif + +#if !defined(BOOST_NO_CXX11_DELETED_FUNCTIONS) +# define BOOST_DELETED_FUNCTION(fun) fun = delete; +#else +# define BOOST_DELETED_FUNCTION(fun) private: fun; +#endif + +// +// Set BOOST_NO_DECLTYPE_N3276 when BOOST_NO_DECLTYPE is defined +// +#if defined(BOOST_NO_CXX11_DECLTYPE) && !defined(BOOST_NO_CXX11_DECLTYPE_N3276) +#define BOOST_NO_CXX11_DECLTYPE_N3276 BOOST_NO_CXX11_DECLTYPE +#endif + +// -------------------- Deprecated macros for 1.50 --------------------------- +// These will go away in a future release + +// Use BOOST_NO_CXX11_HDR_UNORDERED_SET or BOOST_NO_CXX11_HDR_UNORDERED_MAP +// instead of BOOST_NO_STD_UNORDERED +#if defined(BOOST_NO_CXX11_HDR_UNORDERED_MAP) || defined (BOOST_NO_CXX11_HDR_UNORDERED_SET) +# ifndef BOOST_NO_CXX11_STD_UNORDERED +# define BOOST_NO_CXX11_STD_UNORDERED +# endif +#endif + +// Use BOOST_NO_CXX11_HDR_INITIALIZER_LIST instead of BOOST_NO_INITIALIZER_LISTS +#if defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST) && !defined(BOOST_NO_INITIALIZER_LISTS) +# define BOOST_NO_INITIALIZER_LISTS +#endif + +// Use BOOST_NO_CXX11_HDR_ARRAY instead of BOOST_NO_0X_HDR_ARRAY +#if defined(BOOST_NO_CXX11_HDR_ARRAY) && !defined(BOOST_NO_0X_HDR_ARRAY) +# define BOOST_NO_0X_HDR_ARRAY +#endif +// Use BOOST_NO_CXX11_HDR_CHRONO instead of BOOST_NO_0X_HDR_CHRONO +#if defined(BOOST_NO_CXX11_HDR_CHRONO) && !defined(BOOST_NO_0X_HDR_CHRONO) +# define BOOST_NO_0X_HDR_CHRONO +#endif +// Use BOOST_NO_CXX11_HDR_CODECVT instead of BOOST_NO_0X_HDR_CODECVT +#if defined(BOOST_NO_CXX11_HDR_CODECVT) && !defined(BOOST_NO_0X_HDR_CODECVT) +# define BOOST_NO_0X_HDR_CODECVT +#endif +// Use BOOST_NO_CXX11_HDR_CONDITION_VARIABLE instead of BOOST_NO_0X_HDR_CONDITION_VARIABLE +#if defined(BOOST_NO_CXX11_HDR_CONDITION_VARIABLE) && !defined(BOOST_NO_0X_HDR_CONDITION_VARIABLE) +# define BOOST_NO_0X_HDR_CONDITION_VARIABLE +#endif +// Use BOOST_NO_CXX11_HDR_FORWARD_LIST instead of BOOST_NO_0X_HDR_FORWARD_LIST +#if defined(BOOST_NO_CXX11_HDR_FORWARD_LIST) && !defined(BOOST_NO_0X_HDR_FORWARD_LIST) +# define BOOST_NO_0X_HDR_FORWARD_LIST +#endif +// Use BOOST_NO_CXX11_HDR_FUTURE instead of BOOST_NO_0X_HDR_FUTURE +#if defined(BOOST_NO_CXX11_HDR_FUTURE) && !defined(BOOST_NO_0X_HDR_FUTURE) +# define BOOST_NO_0X_HDR_FUTURE +#endif + +// Use BOOST_NO_CXX11_HDR_INITIALIZER_LIST +// instead of BOOST_NO_0X_HDR_INITIALIZER_LIST or BOOST_NO_INITIALIZER_LISTS +#ifdef BOOST_NO_CXX11_HDR_INITIALIZER_LIST +# ifndef BOOST_NO_0X_HDR_INITIALIZER_LIST +# define BOOST_NO_0X_HDR_INITIALIZER_LIST +# endif +# ifndef BOOST_NO_INITIALIZER_LISTS +# define BOOST_NO_INITIALIZER_LISTS +# endif +#endif + +// Use BOOST_NO_CXX11_HDR_MUTEX instead of BOOST_NO_0X_HDR_MUTEX +#if defined(BOOST_NO_CXX11_HDR_MUTEX) && !defined(BOOST_NO_0X_HDR_MUTEX) +# define BOOST_NO_0X_HDR_MUTEX +#endif +// Use BOOST_NO_CXX11_HDR_RANDOM instead of BOOST_NO_0X_HDR_RANDOM +#if defined(BOOST_NO_CXX11_HDR_RANDOM) && !defined(BOOST_NO_0X_HDR_RANDOM) +# define BOOST_NO_0X_HDR_RANDOM +#endif +// Use BOOST_NO_CXX11_HDR_RATIO instead of BOOST_NO_0X_HDR_RATIO +#if defined(BOOST_NO_CXX11_HDR_RATIO) && !defined(BOOST_NO_0X_HDR_RATIO) +# define BOOST_NO_0X_HDR_RATIO +#endif +// Use BOOST_NO_CXX11_HDR_REGEX instead of BOOST_NO_0X_HDR_REGEX +#if defined(BOOST_NO_CXX11_HDR_REGEX) && !defined(BOOST_NO_0X_HDR_REGEX) +# define BOOST_NO_0X_HDR_REGEX +#endif +// Use BOOST_NO_CXX11_HDR_SYSTEM_ERROR instead of BOOST_NO_0X_HDR_SYSTEM_ERROR +#if defined(BOOST_NO_CXX11_HDR_SYSTEM_ERROR) && !defined(BOOST_NO_0X_HDR_SYSTEM_ERROR) +# define BOOST_NO_0X_HDR_SYSTEM_ERROR +#endif +// Use BOOST_NO_CXX11_HDR_THREAD instead of BOOST_NO_0X_HDR_THREAD +#if defined(BOOST_NO_CXX11_HDR_THREAD) && !defined(BOOST_NO_0X_HDR_THREAD) +# define BOOST_NO_0X_HDR_THREAD +#endif +// Use BOOST_NO_CXX11_HDR_TUPLE instead of BOOST_NO_0X_HDR_TUPLE +#if defined(BOOST_NO_CXX11_HDR_TUPLE) && !defined(BOOST_NO_0X_HDR_TUPLE) +# define BOOST_NO_0X_HDR_TUPLE +#endif +// Use BOOST_NO_CXX11_HDR_TYPE_TRAITS instead of BOOST_NO_0X_HDR_TYPE_TRAITS +#if defined(BOOST_NO_CXX11_HDR_TYPE_TRAITS) && !defined(BOOST_NO_0X_HDR_TYPE_TRAITS) +# define BOOST_NO_0X_HDR_TYPE_TRAITS +#endif +// Use BOOST_NO_CXX11_HDR_TYPEINDEX instead of BOOST_NO_0X_HDR_TYPEINDEX +#if defined(BOOST_NO_CXX11_HDR_TYPEINDEX) && !defined(BOOST_NO_0X_HDR_TYPEINDEX) +# define BOOST_NO_0X_HDR_TYPEINDEX +#endif +// Use BOOST_NO_CXX11_HDR_UNORDERED_MAP instead of BOOST_NO_0X_HDR_UNORDERED_MAP +#if defined(BOOST_NO_CXX11_HDR_UNORDERED_MAP) && !defined(BOOST_NO_0X_HDR_UNORDERED_MAP) +# define BOOST_NO_0X_HDR_UNORDERED_MAP +#endif +// Use BOOST_NO_CXX11_HDR_UNORDERED_SET instead of BOOST_NO_0X_HDR_UNORDERED_SET +#if defined(BOOST_NO_CXX11_HDR_UNORDERED_SET) && !defined(BOOST_NO_0X_HDR_UNORDERED_SET) +# define BOOST_NO_0X_HDR_UNORDERED_SET +#endif + +// ------------------ End of deprecated macros for 1.50 --------------------------- + +// -------------------- Deprecated macros for 1.51 --------------------------- +// These will go away in a future release + +// Use BOOST_NO_CXX11_AUTO_DECLARATIONS instead of BOOST_NO_AUTO_DECLARATIONS +#if defined(BOOST_NO_CXX11_AUTO_DECLARATIONS) && !defined(BOOST_NO_AUTO_DECLARATIONS) +# define BOOST_NO_AUTO_DECLARATIONS +#endif +// Use BOOST_NO_CXX11_AUTO_MULTIDECLARATIONS instead of BOOST_NO_AUTO_MULTIDECLARATIONS +#if defined(BOOST_NO_CXX11_AUTO_MULTIDECLARATIONS) && !defined(BOOST_NO_AUTO_MULTIDECLARATIONS) +# define BOOST_NO_AUTO_MULTIDECLARATIONS +#endif +// Use BOOST_NO_CXX11_CHAR16_T instead of BOOST_NO_CHAR16_T +#if defined(BOOST_NO_CXX11_CHAR16_T) && !defined(BOOST_NO_CHAR16_T) +# define BOOST_NO_CHAR16_T +#endif +// Use BOOST_NO_CXX11_CHAR32_T instead of BOOST_NO_CHAR32_T +#if defined(BOOST_NO_CXX11_CHAR32_T) && !defined(BOOST_NO_CHAR32_T) +# define BOOST_NO_CHAR32_T +#endif +// Use BOOST_NO_CXX11_TEMPLATE_ALIASES instead of BOOST_NO_TEMPLATE_ALIASES +#if defined(BOOST_NO_CXX11_TEMPLATE_ALIASES) && !defined(BOOST_NO_TEMPLATE_ALIASES) +# define BOOST_NO_TEMPLATE_ALIASES +#endif +// Use BOOST_NO_CXX11_CONSTEXPR instead of BOOST_NO_CONSTEXPR +#if defined(BOOST_NO_CXX11_CONSTEXPR) && !defined(BOOST_NO_CONSTEXPR) +# define BOOST_NO_CONSTEXPR +#endif +// Use BOOST_NO_CXX11_DECLTYPE_N3276 instead of BOOST_NO_DECLTYPE_N3276 +#if defined(BOOST_NO_CXX11_DECLTYPE_N3276) && !defined(BOOST_NO_DECLTYPE_N3276) +# define BOOST_NO_DECLTYPE_N3276 +#endif +// Use BOOST_NO_CXX11_DECLTYPE instead of BOOST_NO_DECLTYPE +#if defined(BOOST_NO_CXX11_DECLTYPE) && !defined(BOOST_NO_DECLTYPE) +# define BOOST_NO_DECLTYPE +#endif +// Use BOOST_NO_CXX11_DEFAULTED_FUNCTIONS instead of BOOST_NO_DEFAULTED_FUNCTIONS +#if defined(BOOST_NO_CXX11_DEFAULTED_FUNCTIONS) && !defined(BOOST_NO_DEFAULTED_FUNCTIONS) +# define BOOST_NO_DEFAULTED_FUNCTIONS +#endif +// Use BOOST_NO_CXX11_DELETED_FUNCTIONS instead of BOOST_NO_DELETED_FUNCTIONS +#if defined(BOOST_NO_CXX11_DELETED_FUNCTIONS) && !defined(BOOST_NO_DELETED_FUNCTIONS) +# define BOOST_NO_DELETED_FUNCTIONS +#endif +// Use BOOST_NO_CXX11_EXPLICIT_CONVERSION_OPERATORS instead of BOOST_NO_EXPLICIT_CONVERSION_OPERATORS +#if defined(BOOST_NO_CXX11_EXPLICIT_CONVERSION_OPERATORS) && !defined(BOOST_NO_EXPLICIT_CONVERSION_OPERATORS) +# define BOOST_NO_EXPLICIT_CONVERSION_OPERATORS +#endif +// Use BOOST_NO_CXX11_EXTERN_TEMPLATE instead of BOOST_NO_EXTERN_TEMPLATE +#if defined(BOOST_NO_CXX11_EXTERN_TEMPLATE) && !defined(BOOST_NO_EXTERN_TEMPLATE) +# define BOOST_NO_EXTERN_TEMPLATE +#endif +// Use BOOST_NO_CXX11_FUNCTION_TEMPLATE_DEFAULT_ARGS instead of BOOST_NO_FUNCTION_TEMPLATE_DEFAULT_ARGS +#if defined(BOOST_NO_CXX11_FUNCTION_TEMPLATE_DEFAULT_ARGS) && !defined(BOOST_NO_FUNCTION_TEMPLATE_DEFAULT_ARGS) +# define BOOST_NO_FUNCTION_TEMPLATE_DEFAULT_ARGS +#endif +// Use BOOST_NO_CXX11_LAMBDAS instead of BOOST_NO_LAMBDAS +#if defined(BOOST_NO_CXX11_LAMBDAS) && !defined(BOOST_NO_LAMBDAS) +# define BOOST_NO_LAMBDAS +#endif +// Use BOOST_NO_CXX11_LOCAL_CLASS_TEMPLATE_PARAMETERS instead of BOOST_NO_LOCAL_CLASS_TEMPLATE_PARAMETERS +#if defined(BOOST_NO_CXX11_LOCAL_CLASS_TEMPLATE_PARAMETERS) && !defined(BOOST_NO_LOCAL_CLASS_TEMPLATE_PARAMETERS) +# define BOOST_NO_LOCAL_CLASS_TEMPLATE_PARAMETERS +#endif +// Use BOOST_NO_CXX11_NOEXCEPT instead of BOOST_NO_NOEXCEPT +#if defined(BOOST_NO_CXX11_NOEXCEPT) && !defined(BOOST_NO_NOEXCEPT) +# define BOOST_NO_NOEXCEPT +#endif +// Use BOOST_NO_CXX11_NULLPTR instead of BOOST_NO_NULLPTR +#if defined(BOOST_NO_CXX11_NULLPTR) && !defined(BOOST_NO_NULLPTR) +# define BOOST_NO_NULLPTR +#endif +// Use BOOST_NO_CXX11_RAW_LITERALS instead of BOOST_NO_RAW_LITERALS +#if defined(BOOST_NO_CXX11_RAW_LITERALS) && !defined(BOOST_NO_RAW_LITERALS) +# define BOOST_NO_RAW_LITERALS +#endif +// Use BOOST_NO_CXX11_RVALUE_REFERENCES instead of BOOST_NO_RVALUE_REFERENCES +#if defined(BOOST_NO_CXX11_RVALUE_REFERENCES) && !defined(BOOST_NO_RVALUE_REFERENCES) +# define BOOST_NO_RVALUE_REFERENCES +#endif +// Use BOOST_NO_CXX11_SCOPED_ENUMS instead of BOOST_NO_SCOPED_ENUMS +#if defined(BOOST_NO_CXX11_SCOPED_ENUMS) && !defined(BOOST_NO_SCOPED_ENUMS) +# define BOOST_NO_SCOPED_ENUMS +#endif +// Use BOOST_NO_CXX11_STATIC_ASSERT instead of BOOST_NO_STATIC_ASSERT +#if defined(BOOST_NO_CXX11_STATIC_ASSERT) && !defined(BOOST_NO_STATIC_ASSERT) +# define BOOST_NO_STATIC_ASSERT +#endif +// Use BOOST_NO_CXX11_STD_UNORDERED instead of BOOST_NO_STD_UNORDERED +#if defined(BOOST_NO_CXX11_STD_UNORDERED) && !defined(BOOST_NO_STD_UNORDERED) +# define BOOST_NO_STD_UNORDERED +#endif +// Use BOOST_NO_CXX11_UNICODE_LITERALS instead of BOOST_NO_UNICODE_LITERALS +#if defined(BOOST_NO_CXX11_UNICODE_LITERALS) && !defined(BOOST_NO_UNICODE_LITERALS) +# define BOOST_NO_UNICODE_LITERALS +#endif +// Use BOOST_NO_CXX11_UNIFIED_INITIALIZATION_SYNTAX instead of BOOST_NO_UNIFIED_INITIALIZATION_SYNTAX +#if defined(BOOST_NO_CXX11_UNIFIED_INITIALIZATION_SYNTAX) && !defined(BOOST_NO_UNIFIED_INITIALIZATION_SYNTAX) +# define BOOST_NO_UNIFIED_INITIALIZATION_SYNTAX +#endif +// Use BOOST_NO_CXX11_VARIADIC_TEMPLATES instead of BOOST_NO_VARIADIC_TEMPLATES +#if defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) && !defined(BOOST_NO_VARIADIC_TEMPLATES) +# define BOOST_NO_VARIADIC_TEMPLATES +#endif +// Use BOOST_NO_CXX11_VARIADIC_MACROS instead of BOOST_NO_VARIADIC_MACROS +#if defined(BOOST_NO_CXX11_VARIADIC_MACROS) && !defined(BOOST_NO_VARIADIC_MACROS) +# define BOOST_NO_VARIADIC_MACROS +#endif +// Use BOOST_NO_CXX11_NUMERIC_LIMITS instead of BOOST_NO_NUMERIC_LIMITS_LOWEST +#if defined(BOOST_NO_CXX11_NUMERIC_LIMITS) && !defined(BOOST_NO_NUMERIC_LIMITS_LOWEST) +# define BOOST_NO_NUMERIC_LIMITS_LOWEST +#endif +// ------------------ End of deprecated macros for 1.51 --------------------------- + + +// +// Helper macro for marking types and methods final +// +#if !defined(BOOST_NO_CXX11_FINAL) +# define BOOST_FINAL final +#else +# define BOOST_FINAL +#endif + +// +// Helper macros BOOST_NOEXCEPT, BOOST_NOEXCEPT_IF, BOOST_NOEXCEPT_EXPR +// These aid the transition to C++11 while still supporting C++03 compilers +// +#ifdef BOOST_NO_CXX11_NOEXCEPT +# define BOOST_NOEXCEPT +# define BOOST_NOEXCEPT_OR_NOTHROW throw() +# define BOOST_NOEXCEPT_IF(Predicate) +# define BOOST_NOEXCEPT_EXPR(Expression) false +#else +# define BOOST_NOEXCEPT noexcept +# define BOOST_NOEXCEPT_OR_NOTHROW noexcept +# define BOOST_NOEXCEPT_IF(Predicate) noexcept((Predicate)) +# define BOOST_NOEXCEPT_EXPR(Expression) noexcept((Expression)) +#endif +// +// Helper macro BOOST_FALLTHROUGH +// Fallback definition of BOOST_FALLTHROUGH macro used to mark intended +// fall-through between case labels in a switch statement. We use a definition +// that requires a semicolon after it to avoid at least one type of misuse even +// on unsupported compilers. +// +#ifndef BOOST_FALLTHROUGH +# define BOOST_FALLTHROUGH ((void)0) +#endif + +// +// constexpr workarounds +// +#if defined(BOOST_NO_CXX11_CONSTEXPR) +#define BOOST_CONSTEXPR +#define BOOST_CONSTEXPR_OR_CONST const +#else +#define BOOST_CONSTEXPR constexpr +#define BOOST_CONSTEXPR_OR_CONST constexpr +#endif +#if defined(BOOST_NO_CXX14_CONSTEXPR) +#define BOOST_CXX14_CONSTEXPR +#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 +// +#if !defined(BOOST_NO_CXX17_INLINE_VARIABLES) +#define BOOST_INLINE_VARIABLE inline +#else +#define BOOST_INLINE_VARIABLE +#endif +// +// C++17 if constexpr +// +#if !defined(BOOST_NO_CXX17_IF_CONSTEXPR) +# define BOOST_IF_CONSTEXPR if constexpr +#else +# define BOOST_IF_CONSTEXPR if +#endif + +#define BOOST_INLINE_CONSTEXPR BOOST_INLINE_VARIABLE BOOST_CONSTEXPR_OR_CONST + +// +// 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]]: +// +#if defined(__has_attribute) && defined(__SUNPRO_CC) && (__SUNPRO_CC > 0x5130) +#if __has_attribute(nodiscard) +# define BOOST_ATTRIBUTE_NODISCARD [[nodiscard]] +#endif +#if __has_attribute(no_unique_address) +# define BOOST_ATTRIBUTE_NO_UNIQUE_ADDRESS [[no_unique_address]] +#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)) && !(defined(__GNUC__) && (__cplusplus < 201100)) +# define BOOST_ATTRIBUTE_NODISCARD [[nodiscard]] +#endif +#if __has_cpp_attribute(no_unique_address) && !(defined(__GNUC__) && (__cplusplus < 201100)) +# define BOOST_ATTRIBUTE_NO_UNIQUE_ADDRESS [[no_unique_address]] +#endif +#endif +#ifndef BOOST_ATTRIBUTE_NODISCARD +# define BOOST_ATTRIBUTE_NODISCARD +#endif +#ifndef BOOST_ATTRIBUTE_NO_UNIQUE_ADDRESS +# define BOOST_ATTRIBUTE_NO_UNIQUE_ADDRESS +#endif + +#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 +// +#if !defined(BOOST_NO_CXX11_STATIC_ASSERT) && !defined(BOOST_HAS_STATIC_ASSERT) +# define BOOST_HAS_STATIC_ASSERT +#endif + +// +// Set BOOST_HAS_RVALUE_REFS when BOOST_NO_CXX11_RVALUE_REFERENCES is not defined +// +#if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES) && !defined(BOOST_HAS_RVALUE_REFS) +#define BOOST_HAS_RVALUE_REFS +#endif + +// +// Set BOOST_HAS_VARIADIC_TMPL when BOOST_NO_CXX11_VARIADIC_TEMPLATES is not defined +// +#if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) && !defined(BOOST_HAS_VARIADIC_TMPL) +#define BOOST_HAS_VARIADIC_TMPL +#endif +// +// Set BOOST_NO_CXX11_FIXED_LENGTH_VARIADIC_TEMPLATE_EXPANSION_PACKS when +// BOOST_NO_CXX11_VARIADIC_TEMPLATES is set: +// +#if defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) && !defined(BOOST_NO_CXX11_FIXED_LENGTH_VARIADIC_TEMPLATE_EXPANSION_PACKS) +# define BOOST_NO_CXX11_FIXED_LENGTH_VARIADIC_TEMPLATE_EXPANSION_PACKS +#endif + +// This is a catch all case for obsolete compilers / std libs: +#if !defined(_YVALS) && !defined(_CPPLIB_VER) // msvc std lib already configured +#if (!defined(__has_include) || (__cplusplus < 201700)) +# 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 +#endif +#if !__has_include() +# define BOOST_NO_CXX17_HDR_STRING_VIEW +#endif +#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, +// if any of these are set then it's very likely that much of Boost will no +// longer work. So stop with a #error for now, but give the user a chance +// to continue at their own risk if they really want to: +// +#if defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION) && !defined(BOOST_CONFIG_ALLOW_DEPRECATED) +# error "You are using a compiler which lacks features which are now a minimum requirement in order to use Boost, define BOOST_CONFIG_ALLOW_DEPRECATED if you want to continue at your own risk!!!" +#endif + +#endif diff --git a/third_party/boost/libs/config/include/boost/config/header_deprecated.hpp b/third_party/boost/libs/config/include/boost/config/header_deprecated.hpp new file mode 100644 index 00000000000..120b4b3a92f --- /dev/null +++ b/third_party/boost/libs/config/include/boost/config/header_deprecated.hpp @@ -0,0 +1,26 @@ +#ifndef BOOST_CONFIG_HEADER_DEPRECATED_HPP_INCLUDED +#define BOOST_CONFIG_HEADER_DEPRECATED_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 +// +// BOOST_HEADER_DEPRECATED("") +// +// Expands to the equivalent of +// BOOST_PRAGMA_MESSAGE("This header is deprecated. Use instead.") +// +// Note that this header is C compatible. + +#include + +#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.") +#endif + +#endif // BOOST_CONFIG_HEADER_DEPRECATED_HPP_INCLUDED diff --git a/third_party/boost/libs/config/include/boost/config/helper_macros.hpp b/third_party/boost/libs/config/include/boost/config/helper_macros.hpp new file mode 100644 index 00000000000..3e79526df65 --- /dev/null +++ b/third_party/boost/libs/config/include/boost/config/helper_macros.hpp @@ -0,0 +1,37 @@ +#ifndef BOOST_CONFIG_HELPER_MACROS_HPP_INCLUDED +#define BOOST_CONFIG_HELPER_MACROS_HPP_INCLUDED + +// Copyright 2001 John Maddock. +// 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 +// +// BOOST_STRINGIZE(X) +// BOOST_JOIN(X, Y) +// +// Note that this header is C compatible. + +// +// Helper macro BOOST_STRINGIZE: +// Converts the parameter X to a string after macro replacement +// on X has been performed. +// +#define BOOST_STRINGIZE(X) BOOST_DO_STRINGIZE(X) +#define BOOST_DO_STRINGIZE(X) #X + +// +// Helper macro BOOST_JOIN: +// The following piece of macro magic joins the two +// arguments together, even when one of the arguments is +// itself a macro (see 16.3.1 in C++ standard). The key +// is that macro expansion of macro arguments does not +// occur in BOOST_DO_JOIN2 but does in BOOST_DO_JOIN. +// +#define BOOST_JOIN(X, Y) BOOST_DO_JOIN(X, Y) +#define BOOST_DO_JOIN(X, Y) BOOST_DO_JOIN2(X,Y) +#define BOOST_DO_JOIN2(X, Y) X##Y + +#endif // BOOST_CONFIG_HELPER_MACROS_HPP_INCLUDED diff --git a/third_party/boost/libs/config/include/boost/config/no_tr1/cmath.hpp b/third_party/boost/libs/config/include/boost/config/no_tr1/cmath.hpp new file mode 100644 index 00000000000..d8268d842a7 --- /dev/null +++ b/third_party/boost/libs/config/include/boost/config/no_tr1/cmath.hpp @@ -0,0 +1,28 @@ +// (C) Copyright John Maddock 2008. +// 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) +// +// The aim of this header is just to include but to do +// so in a way that does not result in recursive inclusion of +// the Boost TR1 components if boost/tr1/tr1/cmath is in the +// include search path. We have to do this to avoid circular +// dependencies: +// + +#ifndef BOOST_CONFIG_CMATH +# define BOOST_CONFIG_CMATH + +# ifndef BOOST_TR1_NO_RECURSION +# define BOOST_TR1_NO_RECURSION +# define BOOST_CONFIG_NO_CMATH_RECURSION +# endif + +# include + +# ifdef BOOST_CONFIG_NO_CMATH_RECURSION +# undef BOOST_TR1_NO_RECURSION +# undef BOOST_CONFIG_NO_CMATH_RECURSION +# endif + +#endif diff --git a/third_party/boost/libs/config/include/boost/config/no_tr1/complex.hpp b/third_party/boost/libs/config/include/boost/config/no_tr1/complex.hpp new file mode 100644 index 00000000000..ca200922b3c --- /dev/null +++ b/third_party/boost/libs/config/include/boost/config/no_tr1/complex.hpp @@ -0,0 +1,28 @@ +// (C) Copyright John Maddock 2005. +// 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) +// +// The aim of this header is just to include but to do +// so in a way that does not result in recursive inclusion of +// the Boost TR1 components if boost/tr1/tr1/complex is in the +// include search path. We have to do this to avoid circular +// dependencies: +// + +#ifndef BOOST_CONFIG_COMPLEX +# define BOOST_CONFIG_COMPLEX + +# ifndef BOOST_TR1_NO_RECURSION +# define BOOST_TR1_NO_RECURSION +# define BOOST_CONFIG_NO_COMPLEX_RECURSION +# endif + +# include + +# ifdef BOOST_CONFIG_NO_COMPLEX_RECURSION +# undef BOOST_TR1_NO_RECURSION +# undef BOOST_CONFIG_NO_COMPLEX_RECURSION +# endif + +#endif diff --git a/third_party/boost/libs/config/include/boost/config/no_tr1/functional.hpp b/third_party/boost/libs/config/include/boost/config/no_tr1/functional.hpp new file mode 100644 index 00000000000..e395efc1977 --- /dev/null +++ b/third_party/boost/libs/config/include/boost/config/no_tr1/functional.hpp @@ -0,0 +1,28 @@ +// (C) Copyright John Maddock 2005. +// 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) +// +// The aim of this header is just to include but to do +// so in a way that does not result in recursive inclusion of +// the Boost TR1 components if boost/tr1/tr1/functional is in the +// include search path. We have to do this to avoid circular +// dependencies: +// + +#ifndef BOOST_CONFIG_FUNCTIONAL +# define BOOST_CONFIG_FUNCTIONAL + +# ifndef BOOST_TR1_NO_RECURSION +# define BOOST_TR1_NO_RECURSION +# define BOOST_CONFIG_NO_FUNCTIONAL_RECURSION +# endif + +# include + +# ifdef BOOST_CONFIG_NO_FUNCTIONAL_RECURSION +# undef BOOST_TR1_NO_RECURSION +# undef BOOST_CONFIG_NO_FUNCTIONAL_RECURSION +# endif + +#endif diff --git a/third_party/boost/libs/config/include/boost/config/no_tr1/memory.hpp b/third_party/boost/libs/config/include/boost/config/no_tr1/memory.hpp new file mode 100644 index 00000000000..2b5d2080272 --- /dev/null +++ b/third_party/boost/libs/config/include/boost/config/no_tr1/memory.hpp @@ -0,0 +1,28 @@ +// (C) Copyright John Maddock 2005. +// 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) +// +// The aim of this header is just to include but to do +// so in a way that does not result in recursive inclusion of +// the Boost TR1 components if boost/tr1/tr1/memory is in the +// include search path. We have to do this to avoid circular +// dependencies: +// + +#ifndef BOOST_CONFIG_MEMORY +# define BOOST_CONFIG_MEMORY + +# ifndef BOOST_TR1_NO_RECURSION +# define BOOST_TR1_NO_RECURSION +# define BOOST_CONFIG_NO_MEMORY_RECURSION +# endif + +# include + +# ifdef BOOST_CONFIG_NO_MEMORY_RECURSION +# undef BOOST_TR1_NO_RECURSION +# undef BOOST_CONFIG_NO_MEMORY_RECURSION +# endif + +#endif diff --git a/third_party/boost/libs/config/include/boost/config/no_tr1/utility.hpp b/third_party/boost/libs/config/include/boost/config/no_tr1/utility.hpp new file mode 100644 index 00000000000..dea8f115bce --- /dev/null +++ b/third_party/boost/libs/config/include/boost/config/no_tr1/utility.hpp @@ -0,0 +1,28 @@ +// (C) Copyright John Maddock 2005. +// 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) +// +// The aim of this header is just to include but to do +// so in a way that does not result in recursive inclusion of +// the Boost TR1 components if boost/tr1/tr1/utility is in the +// include search path. We have to do this to avoid circular +// dependencies: +// + +#ifndef BOOST_CONFIG_UTILITY +# define BOOST_CONFIG_UTILITY + +# ifndef BOOST_TR1_NO_RECURSION +# define BOOST_TR1_NO_RECURSION +# define BOOST_CONFIG_NO_UTILITY_RECURSION +# endif + +# include + +# ifdef BOOST_CONFIG_NO_UTILITY_RECURSION +# undef BOOST_TR1_NO_RECURSION +# undef BOOST_CONFIG_NO_UTILITY_RECURSION +# endif + +#endif diff --git a/third_party/boost/libs/config/include/boost/config/platform/aix.hpp b/third_party/boost/libs/config/include/boost/config/platform/aix.hpp new file mode 100644 index 00000000000..a48e2320618 --- /dev/null +++ b/third_party/boost/libs/config/include/boost/config/platform/aix.hpp @@ -0,0 +1,33 @@ +// (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. + +// IBM/Aix specific config options: + +#define BOOST_PLATFORM "IBM Aix" + +#define BOOST_HAS_UNISTD_H +#define BOOST_HAS_NL_TYPES_H +#define BOOST_HAS_NANOSLEEP +#define BOOST_HAS_CLOCK_GETTIME + +// This needs support in "boost/cstdint.hpp" exactly like FreeBSD. +// This platform has header named which includes all +// the things needed. +#define BOOST_HAS_STDINT_H + +// Threading API's: +#define BOOST_HAS_PTHREADS +#define BOOST_HAS_PTHREAD_DELAY_NP +#define BOOST_HAS_SCHED_YIELD +//#define BOOST_HAS_PTHREAD_YIELD + +// boilerplate code: +#include + + + + diff --git a/third_party/boost/libs/config/include/boost/config/platform/amigaos.hpp b/third_party/boost/libs/config/include/boost/config/platform/amigaos.hpp new file mode 100644 index 00000000000..34bcf4128b7 --- /dev/null +++ b/third_party/boost/libs/config/include/boost/config/platform/amigaos.hpp @@ -0,0 +1,15 @@ +// (C) Copyright John Maddock 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. + +#define BOOST_PLATFORM "AmigaOS" + +#define BOOST_DISABLE_THREADS +#define BOOST_NO_CWCHAR +#define BOOST_NO_STD_WSTRING +#define BOOST_NO_INTRINSIC_WCHAR_T + + diff --git a/third_party/boost/libs/config/include/boost/config/platform/beos.hpp b/third_party/boost/libs/config/include/boost/config/platform/beos.hpp new file mode 100644 index 00000000000..6158c1c20be --- /dev/null +++ b/third_party/boost/libs/config/include/boost/config/platform/beos.hpp @@ -0,0 +1,26 @@ +// (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. + +// BeOS specific config options: + +#define BOOST_PLATFORM "BeOS" + +#define BOOST_NO_CWCHAR +#define BOOST_NO_CWCTYPE +#define BOOST_HAS_UNISTD_H + +#define BOOST_HAS_BETHREADS + +#ifndef BOOST_DISABLE_THREADS +# define BOOST_HAS_THREADS +#endif + +// boilerplate code: +#include + + + diff --git a/third_party/boost/libs/config/include/boost/config/platform/bsd.hpp b/third_party/boost/libs/config/include/boost/config/platform/bsd.hpp new file mode 100644 index 00000000000..ccc7eb05ad2 --- /dev/null +++ b/third_party/boost/libs/config/include/boost/config/platform/bsd.hpp @@ -0,0 +1,83 @@ +// (C) Copyright John Maddock 2001 - 2003. +// (C) Copyright Darin Adler 2001. +// (C) Copyright Douglas Gregor 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. + +// generic BSD config options: + +#if !defined(__FreeBSD__) && !defined(__NetBSD__) && !defined(__OpenBSD__) && !defined(__DragonFly__) +#error "This platform is not BSD" +#endif + +#ifdef __FreeBSD__ +#define BOOST_PLATFORM "FreeBSD " BOOST_STRINGIZE(__FreeBSD__) +#elif defined(__NetBSD__) +#define BOOST_PLATFORM "NetBSD " BOOST_STRINGIZE(__NetBSD__) +#elif defined(__OpenBSD__) +#define BOOST_PLATFORM "OpenBSD " BOOST_STRINGIZE(__OpenBSD__) +#elif defined(__DragonFly__) +#define BOOST_PLATFORM "DragonFly " BOOST_STRINGIZE(__DragonFly__) +#endif + +// +// is this the correct version check? +// FreeBSD has but does not +// advertise the fact in : +// +#if (defined(__FreeBSD__) && (__FreeBSD__ >= 3)) \ + || defined(__OpenBSD__) || defined(__DragonFly__) +# define BOOST_HAS_NL_TYPES_H +#endif + +// +// FreeBSD 3.x has pthreads support, but defines _POSIX_THREADS in +// and not in +// +#if (defined(__FreeBSD__) && (__FreeBSD__ <= 3))\ + || defined(__OpenBSD__) || defined(__DragonFly__) +# define BOOST_HAS_PTHREADS +#endif + +// +// No wide character support in the BSD header files: +// +#if defined(__NetBSD__) +#define __NetBSD_GCC__ (__GNUC__ * 1000000 \ + + __GNUC_MINOR__ * 1000 \ + + __GNUC_PATCHLEVEL__) +// XXX - the following is required until c++config.h +// defines _GLIBCXX_HAVE_SWPRINTF and friends +// or the preprocessor conditionals are removed +// from the cwchar header. +#define _GLIBCXX_HAVE_SWPRINTF 1 +#endif + +#if !((defined(__FreeBSD__) && (__FreeBSD__ >= 5)) \ + || (defined(__NetBSD_GCC__) && (__NetBSD_GCC__ >= 2095003)) \ + || defined(__OpenBSD__) || defined(__DragonFly__)) +# define BOOST_NO_CWCHAR +#endif +// +// The BSD has macros only, no functions: +// +#if !defined(__OpenBSD__) || defined(__DragonFly__) +# define BOOST_NO_CTYPE_FUNCTIONS +#endif + +// +// thread API's not auto detected: +// +#define BOOST_HAS_SCHED_YIELD +#define BOOST_HAS_NANOSLEEP +#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/third_party/boost/libs/config/include/boost/config/platform/cloudabi.hpp b/third_party/boost/libs/config/include/boost/config/platform/cloudabi.hpp new file mode 100644 index 00000000000..bed7b6318dc --- /dev/null +++ b/third_party/boost/libs/config/include/boost/config/platform/cloudabi.hpp @@ -0,0 +1,18 @@ +// Copyright Nuxi, https://nuxi.nl/ 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) + +#define BOOST_PLATFORM "CloudABI" + +#define BOOST_HAS_DIRENT_H +#define BOOST_HAS_STDINT_H +#define BOOST_HAS_UNISTD_H + +#define BOOST_HAS_CLOCK_GETTIME +#define BOOST_HAS_EXPM1 +#define BOOST_HAS_GETTIMEOFDAY +#define BOOST_HAS_LOG1P +#define BOOST_HAS_NANOSLEEP +#define BOOST_HAS_PTHREADS +#define BOOST_HAS_SCHED_YIELD diff --git a/third_party/boost/libs/config/include/boost/config/platform/cray.hpp b/third_party/boost/libs/config/include/boost/config/platform/cray.hpp new file mode 100644 index 00000000000..103e9c06204 --- /dev/null +++ b/third_party/boost/libs/config/include/boost/config/platform/cray.hpp @@ -0,0 +1,18 @@ +// (C) Copyright John Maddock 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. + +// SGI Irix specific config options: + +#define BOOST_PLATFORM "Cray" + +// boilerplate code: +#define BOOST_HAS_UNISTD_H +#include + + + diff --git a/third_party/boost/libs/config/include/boost/config/platform/cygwin.hpp b/third_party/boost/libs/config/include/boost/config/platform/cygwin.hpp new file mode 100644 index 00000000000..d0052d8b45f --- /dev/null +++ b/third_party/boost/libs/config/include/boost/config/platform/cygwin.hpp @@ -0,0 +1,71 @@ +// (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. + +// cygwin specific config options: + +#define BOOST_PLATFORM "Cygwin" +#define BOOST_HAS_DIRENT_H +#define BOOST_HAS_LOG1P +#define BOOST_HAS_EXPM1 + +// +// Threading API: +// See if we have POSIX threads, if we do use them, otherwise +// revert to native Win threads. +#define BOOST_HAS_UNISTD_H +#include +#if defined(_POSIX_THREADS) && (_POSIX_THREADS+0 >= 0) && !defined(BOOST_HAS_WINTHREADS) +# define BOOST_HAS_PTHREADS +# define BOOST_HAS_SCHED_YIELD +# define BOOST_HAS_GETTIMEOFDAY +# define BOOST_HAS_PTHREAD_MUTEXATTR_SETTYPE +//# define BOOST_HAS_SIGACTION +#else +# if !defined(BOOST_HAS_WINTHREADS) +# define BOOST_HAS_WINTHREADS +# endif +# define BOOST_HAS_FTIME +#endif + +// +// find out if we have a stdint.h, there should be a better way to do this: +// +#include +#ifdef _STDINT_H +#define BOOST_HAS_STDINT_H +#endif +#if __GNUC__ > 5 && !defined(BOOST_HAS_STDINT_H) +# define BOOST_HAS_STDINT_H +#endif + +#include +#if (CYGWIN_VERSION_API_MAJOR == 0 && CYGWIN_VERSION_API_MINOR < 231) +/// Cygwin has no fenv.h +#define BOOST_NO_FENV_H +#endif + +// Cygwin has it's own which breaks unless the correct compiler flags are used: +#ifndef BOOST_NO_CXX14_HDR_SHARED_MUTEX +#include +#if !(__XSI_VISIBLE >= 500 || __POSIX_VISIBLE >= 200112) +# define BOOST_NO_CXX14_HDR_SHARED_MUTEX +#endif +#endif + +// boilerplate code: +#include + +// +// Cygwin lies about XSI conformance, there is no nl_types.h: +// +#ifdef BOOST_HAS_NL_TYPES_H +# undef BOOST_HAS_NL_TYPES_H +#endif + + + + diff --git a/third_party/boost/libs/config/include/boost/config/platform/haiku.hpp b/third_party/boost/libs/config/include/boost/config/platform/haiku.hpp new file mode 100644 index 00000000000..04244c5677f --- /dev/null +++ b/third_party/boost/libs/config/include/boost/config/platform/haiku.hpp @@ -0,0 +1,31 @@ +// (C) Copyright Jessica Hamilton 2014. +// 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. + +// Haiku specific config options: + +#define BOOST_PLATFORM "Haiku" + +#define BOOST_HAS_UNISTD_H +#define BOOST_HAS_STDINT_H + +#ifndef BOOST_DISABLE_THREADS +# define BOOST_HAS_THREADS +#endif + +#define BOOST_NO_CXX11_HDR_TYPE_TRAITS +#define BOOST_NO_CXX11_ATOMIC_SMART_PTR +#define BOOST_NO_CXX11_STATIC_ASSERT +#define BOOST_NO_CXX11_VARIADIC_MACROS + +// +// thread API's not auto detected: +// +#define BOOST_HAS_SCHED_YIELD +#define BOOST_HAS_GETTIMEOFDAY + +// boilerplate code: +#include diff --git a/third_party/boost/libs/config/include/boost/config/platform/hpux.hpp b/third_party/boost/libs/config/include/boost/config/platform/hpux.hpp new file mode 100644 index 00000000000..222622e7ee5 --- /dev/null +++ b/third_party/boost/libs/config/include/boost/config/platform/hpux.hpp @@ -0,0 +1,87 @@ +// (C) Copyright John Maddock 2001 - 2003. +// (C) Copyright Jens Maurer 2001 - 2003. +// (C) Copyright David Abrahams 2002. +// (C) Copyright Toon Knapen 2003. +// (C) Copyright Boris Gubenko 2006 - 2007. +// 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. + +// hpux specific config options: + +#define BOOST_PLATFORM "HP-UX" + +// In principle, HP-UX has a nice under the name +// However, it has the following problem: +// Use of UINT32_C(0) results in "0u l" for the preprocessed source +// (verifyable with gcc 2.95.3) +#if (defined(__GNUC__) && (__GNUC__ >= 3)) || defined(__HP_aCC) +# define BOOST_HAS_STDINT_H +#endif + +#if !(defined(__HP_aCC) || !defined(_INCLUDE__STDC_A1_SOURCE)) +# define BOOST_NO_SWPRINTF +#endif +#if defined(__HP_aCC) && !defined(_INCLUDE__STDC_A1_SOURCE) +# define BOOST_NO_CWCTYPE +#endif + +#if defined(__GNUC__) +# if (__GNUC__ < 3) || ((__GNUC__ == 3) && (__GNUC_MINOR__ < 3)) + // GNU C on HP-UX does not support threads (checked up to gcc 3.3) +# define BOOST_DISABLE_THREADS +# elif !defined(BOOST_DISABLE_THREADS) + // threads supported from gcc-3.3 onwards: +# define BOOST_HAS_THREADS +# define BOOST_HAS_PTHREADS +# endif +#elif defined(__HP_aCC) && !defined(BOOST_DISABLE_THREADS) +# define BOOST_HAS_PTHREADS +#endif + +// boilerplate code: +#define BOOST_HAS_UNISTD_H +#include + +// the following are always available: +#ifndef BOOST_HAS_GETTIMEOFDAY +# define BOOST_HAS_GETTIMEOFDAY +#endif +#ifndef BOOST_HAS_SCHED_YIELD +# define BOOST_HAS_SCHED_YIELD +#endif +#ifndef BOOST_HAS_PTHREAD_MUTEXATTR_SETTYPE +# define BOOST_HAS_PTHREAD_MUTEXATTR_SETTYPE +#endif +#ifndef BOOST_HAS_NL_TYPES_H +# define BOOST_HAS_NL_TYPES_H +#endif +#ifndef BOOST_HAS_NANOSLEEP +# define BOOST_HAS_NANOSLEEP +#endif +#ifndef BOOST_HAS_GETTIMEOFDAY +# define BOOST_HAS_GETTIMEOFDAY +#endif +#ifndef BOOST_HAS_DIRENT_H +# define BOOST_HAS_DIRENT_H +#endif +#ifndef BOOST_HAS_CLOCK_GETTIME +# define BOOST_HAS_CLOCK_GETTIME +#endif +#ifndef BOOST_HAS_SIGACTION +# define BOOST_HAS_SIGACTION +#endif +#ifndef BOOST_HAS_NRVO +# ifndef __parisc +# define BOOST_HAS_NRVO +# endif +#endif +#ifndef BOOST_HAS_LOG1P +# define BOOST_HAS_LOG1P +#endif +#ifndef BOOST_HAS_EXPM1 +# define BOOST_HAS_EXPM1 +#endif + diff --git a/third_party/boost/libs/config/include/boost/config/platform/irix.hpp b/third_party/boost/libs/config/include/boost/config/platform/irix.hpp new file mode 100644 index 00000000000..0acb651552e --- /dev/null +++ b/third_party/boost/libs/config/include/boost/config/platform/irix.hpp @@ -0,0 +1,31 @@ +// (C) Copyright John Maddock 2001 - 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. + +// SGI Irix specific config options: + +#define BOOST_PLATFORM "SGI Irix" + +#define BOOST_NO_SWPRINTF +// +// these are not auto detected by POSIX feature tests: +// +#define BOOST_HAS_GETTIMEOFDAY +#define BOOST_HAS_PTHREAD_MUTEXATTR_SETTYPE + +#ifdef __GNUC__ + // GNU C on IRIX does not support threads (checked up to gcc 3.3) +# define BOOST_DISABLE_THREADS +#endif + +// boilerplate code: +#define BOOST_HAS_UNISTD_H +#include + + + diff --git a/third_party/boost/libs/config/include/boost/config/platform/linux.hpp b/third_party/boost/libs/config/include/boost/config/platform/linux.hpp new file mode 100644 index 00000000000..c4eef8f80cb --- /dev/null +++ b/third_party/boost/libs/config/include/boost/config/platform/linux.hpp @@ -0,0 +1,106 @@ +// (C) Copyright John Maddock 2001 - 2003. +// (C) Copyright Jens Maurer 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. + +// linux specific config options: + +#define BOOST_PLATFORM "linux" + +// make sure we have __GLIBC_PREREQ if available at all +#ifdef __cplusplus +#include +#else +#include +#endif + +// +// added to glibc 2.1.1 +// We can only test for 2.1 though: +// +#if defined(__GLIBC__) && ((__GLIBC__ > 2) || ((__GLIBC__ == 2) && (__GLIBC_MINOR__ >= 1))) + // defines int64_t unconditionally, but defines + // int64_t only if __GNUC__. Thus, assume a fully usable + // only when using GCC. Update 2017: this appears not to be the case for + // recent glibc releases, see bug report: https://svn.boost.org/trac/boost/ticket/13045 +# if defined(__GNUC__) || ((__GLIBC__ > 2) || ((__GLIBC__ == 2) && (__GLIBC_MINOR__ >= 5))) +# define BOOST_HAS_STDINT_H +# endif +#endif + +#if defined(__LIBCOMO__) + // + // como on linux doesn't have std:: c functions: + // NOTE: versions of libcomo prior to beta28 have octal version numbering, + // e.g. version 25 is 21 (dec) + // +# if __LIBCOMO_VERSION__ <= 20 +# define BOOST_NO_STDC_NAMESPACE +# endif + +# if __LIBCOMO_VERSION__ <= 21 +# define BOOST_NO_SWPRINTF +# endif + +#endif + +// +// If glibc is past version 2 then we definitely have +// gettimeofday, earlier versions may or may not have it: +// +#if defined(__GLIBC__) && (__GLIBC__ >= 2) +# define BOOST_HAS_GETTIMEOFDAY +#endif + +#ifdef __USE_POSIX199309 +# define BOOST_HAS_NANOSLEEP +#endif + +#if defined(__GLIBC__) && defined(__GLIBC_PREREQ) +// __GLIBC_PREREQ is available since 2.1.2 + + // swprintf is available since glibc 2.2.0 +# if !__GLIBC_PREREQ(2,2) || (!defined(__USE_ISOC99) && !defined(__USE_UNIX98)) +# define BOOST_NO_SWPRINTF +# endif +#else +# define BOOST_NO_SWPRINTF +#endif + +// boilerplate code: +#define BOOST_HAS_UNISTD_H +#include +#if defined(__USE_GNU) && !defined(__ANDROID__) && !defined(ANDROID) +#define BOOST_HAS_PTHREAD_YIELD +#endif + +#ifndef __GNUC__ +// +// if the compiler is not gcc we still need to be able to parse +// the GNU system headers, some of which (mainly ) +// use GNU specific extensions: +// +# ifndef __extension__ +# define __extension__ +# endif +# ifndef __const__ +# define __const__ const +# endif +# ifndef __volatile__ +# define __volatile__ volatile +# endif +# ifndef __signed__ +# define __signed__ signed +# endif +# ifndef __typeof__ +# define __typeof__ typeof +# endif +# ifndef __inline__ +# define __inline__ inline +# endif +#endif + + diff --git a/third_party/boost/libs/config/include/boost/config/platform/macos.hpp b/third_party/boost/libs/config/include/boost/config/platform/macos.hpp new file mode 100644 index 00000000000..ed7dc15f282 --- /dev/null +++ b/third_party/boost/libs/config/include/boost/config/platform/macos.hpp @@ -0,0 +1,87 @@ +// (C) Copyright John Maddock 2001 - 2003. +// (C) Copyright Darin Adler 2001 - 2002. +// (C) Copyright Bill Kempf 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. + +// Mac OS specific config options: + +#define BOOST_PLATFORM "Mac OS" + +#if __MACH__ && !defined(_MSL_USING_MSL_C) + +// Using the Mac OS X system BSD-style C library. + +# ifndef BOOST_HAS_UNISTD_H +# define BOOST_HAS_UNISTD_H +# endif +// +// Begin by including our boilerplate code for POSIX +// feature detection, this is safe even when using +// the MSL as Metrowerks supply their own +// to replace the platform-native BSD one. G++ users +// should also always be able to do this on MaxOS X. +// +# include +# ifndef BOOST_HAS_STDINT_H +# define BOOST_HAS_STDINT_H +# endif + +// +// BSD runtime has pthreads, sigaction, sched_yield and gettimeofday, +// of these only pthreads are advertised in , so set the +// other options explicitly: +// +# define BOOST_HAS_SCHED_YIELD +# define BOOST_HAS_GETTIMEOFDAY +# define BOOST_HAS_SIGACTION + +# if (__GNUC__ < 3) && !defined( __APPLE_CC__) + +// GCC strange "ignore std" mode works better if you pretend everything +// is in the std namespace, for the most part. + +# define BOOST_NO_STDC_NAMESPACE +# endif + +# if (__GNUC__ >= 4) + +// Both gcc and intel require these. +# define BOOST_HAS_PTHREAD_MUTEXATTR_SETTYPE +# define BOOST_HAS_NANOSLEEP + +# endif + +#else + +// Using the MSL C library. + +// We will eventually support threads in non-Carbon builds, but we do +// not support this yet. +# if ( defined(TARGET_API_MAC_CARBON) && TARGET_API_MAC_CARBON ) || ( defined(TARGET_CARBON) && TARGET_CARBON ) + +# if !defined(BOOST_HAS_PTHREADS) +// MPTasks support is deprecated/removed from Boost: +//# define BOOST_HAS_MPTASKS +# elif ( __dest_os == __mac_os_x ) +// We are doing a Carbon/Mach-O/MSL build which has pthreads, but only the +// gettimeofday and no posix. +# define BOOST_HAS_GETTIMEOFDAY +# endif + +#ifdef BOOST_HAS_PTHREADS +# define BOOST_HAS_THREADS +#endif + +// The remote call manager depends on this. +# define BOOST_BIND_ENABLE_PASCAL + +# endif + +#endif + + + diff --git a/third_party/boost/libs/config/include/boost/config/platform/qnxnto.hpp b/third_party/boost/libs/config/include/boost/config/platform/qnxnto.hpp new file mode 100644 index 00000000000..d0298cb4ecb --- /dev/null +++ b/third_party/boost/libs/config/include/boost/config/platform/qnxnto.hpp @@ -0,0 +1,31 @@ +// (C) Copyright Jim Douglas 2005. +// 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. + +// QNX specific config options: + +#define BOOST_PLATFORM "QNX" + +#define BOOST_HAS_UNISTD_H +#include + +// QNX claims XOpen version 5 compatibility, but doesn't have an nl_types.h +// or log1p and expm1: +#undef BOOST_HAS_NL_TYPES_H +#undef BOOST_HAS_LOG1P +#undef BOOST_HAS_EXPM1 + +#define BOOST_HAS_PTHREADS +#define BOOST_HAS_PTHREAD_MUTEXATTR_SETTYPE + +#define BOOST_HAS_GETTIMEOFDAY +#define BOOST_HAS_CLOCK_GETTIME +#define BOOST_HAS_NANOSLEEP + + + + + diff --git a/third_party/boost/libs/config/include/boost/config/platform/solaris.hpp b/third_party/boost/libs/config/include/boost/config/platform/solaris.hpp new file mode 100644 index 00000000000..51ffe67f331 --- /dev/null +++ b/third_party/boost/libs/config/include/boost/config/platform/solaris.hpp @@ -0,0 +1,31 @@ +// (C) Copyright John Maddock 2001 - 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. + +// sun specific config options: + +#define BOOST_PLATFORM "Sun Solaris" + +#define BOOST_HAS_GETTIMEOFDAY + +// boilerplate code: +#define BOOST_HAS_UNISTD_H +#include + +// +// pthreads don't actually work with gcc unless _PTHREADS is defined: +// +#if defined(__GNUC__) && defined(_POSIX_THREADS) && !defined(_PTHREADS) +# undef BOOST_HAS_PTHREADS +#endif + +#define BOOST_HAS_STDINT_H +#define BOOST_HAS_PTHREAD_MUTEXATTR_SETTYPE +#define BOOST_HAS_LOG1P +#define BOOST_HAS_EXPM1 + + diff --git a/third_party/boost/libs/config/include/boost/config/platform/symbian.hpp b/third_party/boost/libs/config/include/boost/config/platform/symbian.hpp new file mode 100644 index 00000000000..f814d00b5b7 --- /dev/null +++ b/third_party/boost/libs/config/include/boost/config/platform/symbian.hpp @@ -0,0 +1,97 @@ +// (C) Copyright Yuriy Krasnoschek 2009. +// (C) Copyright John Maddock 2001 - 2003. +// (C) Copyright Jens Maurer 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. + +// symbian specific config options: + + +#define BOOST_PLATFORM "Symbian" +#define BOOST_SYMBIAN 1 + + +#if defined(__S60_3X__) +// Open C / C++ plugin was introdused in this SDK, earlier versions don't have CRT / STL +# define BOOST_S60_3rd_EDITION_FP2_OR_LATER_SDK +// make sure we have __GLIBC_PREREQ if available at all +#ifdef __cplusplus +#include +#else +#include +#endif// boilerplate code: +# define BOOST_HAS_UNISTD_H +# include +// S60 SDK defines _POSIX_VERSION as POSIX.1 +# ifndef BOOST_HAS_STDINT_H +# define BOOST_HAS_STDINT_H +# endif +# ifndef BOOST_HAS_GETTIMEOFDAY +# define BOOST_HAS_GETTIMEOFDAY +# endif +# ifndef BOOST_HAS_DIRENT_H +# define BOOST_HAS_DIRENT_H +# endif +# ifndef BOOST_HAS_SIGACTION +# define BOOST_HAS_SIGACTION +# endif +# ifndef BOOST_HAS_PTHREADS +# define BOOST_HAS_PTHREADS +# endif +# ifndef BOOST_HAS_NANOSLEEP +# define BOOST_HAS_NANOSLEEP +# endif +# ifndef BOOST_HAS_SCHED_YIELD +# define BOOST_HAS_SCHED_YIELD +# endif +# ifndef BOOST_HAS_PTHREAD_MUTEXATTR_SETTYPE +# define BOOST_HAS_PTHREAD_MUTEXATTR_SETTYPE +# endif +# ifndef BOOST_HAS_LOG1P +# define BOOST_HAS_LOG1P +# endif +# ifndef BOOST_HAS_EXPM1 +# define BOOST_HAS_EXPM1 +# endif +# ifndef BOOST_POSIX_API +# define BOOST_POSIX_API +# endif +// endianess support +# include +// Symbian SDK provides _BYTE_ORDER instead of __BYTE_ORDER +# ifndef __LITTLE_ENDIAN +# ifdef _LITTLE_ENDIAN +# define __LITTLE_ENDIAN _LITTLE_ENDIAN +# else +# define __LITTLE_ENDIAN 1234 +# endif +# endif +# ifndef __BIG_ENDIAN +# ifdef _BIG_ENDIAN +# define __BIG_ENDIAN _BIG_ENDIAN +# else +# define __BIG_ENDIAN 4321 +# endif +# endif +# ifndef __BYTE_ORDER +# define __BYTE_ORDER __LITTLE_ENDIAN // Symbian is LE +# endif +// Known limitations +# define BOOST_ASIO_DISABLE_SERIAL_PORT +# define BOOST_DATE_TIME_NO_LOCALE +# define BOOST_NO_STD_WSTRING +# define BOOST_EXCEPTION_DISABLE +# define BOOST_NO_EXCEPTIONS + +#else // TODO: More platform support e.g. UIQ +# error "Unsuppoted Symbian SDK" +#endif + +#if defined(__WINSCW__) && !defined(BOOST_DISABLE_WIN32) +# define BOOST_DISABLE_WIN32 // winscw defines WIN32 macro +#endif + + diff --git a/third_party/boost/libs/config/include/boost/config/platform/vms.hpp b/third_party/boost/libs/config/include/boost/config/platform/vms.hpp new file mode 100644 index 00000000000..f70efcfb8ef --- /dev/null +++ b/third_party/boost/libs/config/include/boost/config/platform/vms.hpp @@ -0,0 +1,25 @@ +// (C) Copyright Artyom Beilis 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) + +#ifndef BOOST_CONFIG_PLATFORM_VMS_HPP +#define BOOST_CONFIG_PLATFORM_VMS_HPP + +#define BOOST_PLATFORM "OpenVMS" + +#undef BOOST_HAS_STDINT_H +#define BOOST_HAS_UNISTD_H +#define BOOST_HAS_NL_TYPES_H +#define BOOST_HAS_GETTIMEOFDAY +#define BOOST_HAS_DIRENT_H +#define BOOST_HAS_PTHREADS +#define BOOST_HAS_NANOSLEEP +#define BOOST_HAS_CLOCK_GETTIME +#define BOOST_HAS_PTHREAD_MUTEXATTR_SETTYPE +#define BOOST_HAS_LOG1P +#define BOOST_HAS_EXPM1 +#define BOOST_HAS_THREADS +#undef BOOST_HAS_SCHED_YIELD + +#endif diff --git a/third_party/boost/libs/config/include/boost/config/platform/vxworks.hpp b/third_party/boost/libs/config/include/boost/config/platform/vxworks.hpp new file mode 100644 index 00000000000..0564b9443f8 --- /dev/null +++ b/third_party/boost/libs/config/include/boost/config/platform/vxworks.hpp @@ -0,0 +1,422 @@ +// (C) Copyright Dustin Spicuzza 2009. +// Adapted to vxWorks 6.9 by Peter Brockamp 2012. +// Updated for VxWorks 7 by Brian Kuhl 2016 +// 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. + +// Old versions of vxWorks (namely everything below 6.x) are +// absolutely unable to use boost. Old STLs and compilers +// like (GCC 2.96) . Do not even think of getting this to work, +// a miserable failure will be guaranteed! +// +// VxWorks supports C++ linkage in the kernel with +// DKMs (Downloadable Kernel Modules). But, until recently +// the kernel used a C89 library with no +// wide character support and no guarantee of ANSI C. +// Regardless of the C library the same Dinkum +// STL library is used in both contexts. +// +// Similarly the Dinkum abridged STL that supports the loosely specified +// embedded C++ standard has not been tested and is unlikely to work +// on anything but the simplest library. +// ==================================================================== +// +// Some important information regarding the usage of POSIX semaphores: +// ------------------------------------------------------------------- +// +// VxWorks as a real time operating system handles threads somewhat +// different from what "normal" OSes do, regarding their scheduling! +// This could lead to a scenario called "priority inversion" when using +// semaphores, see http://en.wikipedia.org/wiki/Priority_inversion. +// +// Now, VxWorks POSIX-semaphores for DKM's default to the usage of +// priority inverting semaphores, which is fine. On the other hand, +// for RTP's it defaults to using non priority inverting semaphores, +// which could easily pose a serious problem for a real time process. +// +// To change the default properties for POSIX-semaphores in VxWorks 7 +// enable core > CORE_USER Menu > DEFAULT_PTHREAD_PRIO_INHERIT +// +// In VxWorks 6.x so as to integrate with boost. +// - Edit the file +// installDir/vxworks-6.x/target/usr/src/posix/pthreadLib.c +// - Around line 917 there should be the definition of the default +// mutex attributes: +// +// LOCAL pthread_mutexattr_t defaultMutexAttr = +// { +// PTHREAD_INITIALIZED_OBJ, PTHREAD_PRIO_NONE, 0, +// PTHREAD_MUTEX_DEFAULT +// }; +// +// Here, replace PTHREAD_PRIO_NONE by PTHREAD_PRIO_INHERIT. +// - Around line 1236 there should be a definition for the function +// pthread_mutexattr_init(). A couple of lines below you should +// find a block of code like this: +// +// pAttr->mutexAttrStatus = PTHREAD_INITIALIZED_OBJ; +// pAttr->mutexAttrProtocol = PTHREAD_PRIO_NONE; +// pAttr->mutexAttrPrioceiling = 0; +// pAttr->mutexAttrType = PTHREAD_MUTEX_DEFAULT; +// +// Here again, replace PTHREAD_PRIO_NONE by PTHREAD_PRIO_INHERIT. +// - Finally, rebuild your VSB. This will rebuild the libraries +// with the changed properties. That's it! Now, using boost should +// no longer cause any problems with task deadlocks! +// +// ==================================================================== + +// Block out all versions before vxWorks 6.x, as these don't work: +// Include header with the vxWorks version information and query them +#include +#if !defined(_WRS_VXWORKS_MAJOR) || (_WRS_VXWORKS_MAJOR < 6) +# error "The vxWorks version you're using is so badly outdated,\ + it doesn't work at all with boost, sorry, no chance!" +#endif + +// Handle versions above 5.X but below 6.9 +#if (_WRS_VXWORKS_MAJOR == 6) && (_WRS_VXWORKS_MINOR < 9) +// TODO: Starting from what version does vxWorks work with boost? +// We can't reasonably insert a #warning "" as a user hint here, +// as this will show up with every file including some boost header, +// badly bugging the user... So for the time being we just leave it. +#endif + +// vxWorks specific config options: +// -------------------------------- +#define BOOST_PLATFORM "vxWorks" + + +// Generally available headers: +#define BOOST_HAS_UNISTD_H +#define BOOST_HAS_STDINT_H +#define BOOST_HAS_DIRENT_H +//#define BOOST_HAS_SLIST + +// vxWorks does not have installed an iconv-library by default, +// so unfortunately no Unicode support from scratch is available! +// Thus, instead it is suggested to switch to ICU, as this seems +// to be the most complete and portable option... +#ifndef BOOST_LOCALE_WITH_ICU + #define BOOST_LOCALE_WITH_ICU +#endif + +// Generally available functionality: +#define BOOST_HAS_THREADS +#define BOOST_HAS_NANOSLEEP +#define BOOST_HAS_GETTIMEOFDAY +#define BOOST_HAS_CLOCK_GETTIME +#define BOOST_HAS_MACRO_USE_FACET + +// Generally available threading API's: +#define BOOST_HAS_PTHREADS +#define BOOST_HAS_SCHED_YIELD +#define BOOST_HAS_SIGACTION + +// Functionality available for RTPs only: +#ifdef __RTP__ +# define BOOST_HAS_PTHREAD_MUTEXATTR_SETTYPE +# define BOOST_HAS_LOG1P +# define BOOST_HAS_EXPM1 +#endif + +// Functionality available for DKMs only: +#ifdef _WRS_KERNEL + // Luckily, at the moment there seems to be none! +#endif + +// These #defines allow detail/posix_features to work, since vxWorks doesn't +// #define them itself for DKMs (for RTPs on the contrary it does): +#ifdef _WRS_KERNEL +# ifndef _POSIX_TIMERS +# define _POSIX_TIMERS 1 +# endif +# ifndef _POSIX_THREADS +# define _POSIX_THREADS 1 +# endif +// no sysconf( _SC_PAGESIZE) in kernel +# define BOOST_THREAD_USES_GETPAGESIZE +#endif + +#if (_WRS_VXWORKS_MAJOR < 7) +// vxWorks-around: #defines CLOCKS_PER_SEC as sysClkRateGet() but +// miserably fails to #include the required to make +// sysClkRateGet() available! So we manually include it here. +# ifdef __RTP__ +# include +# include +# endif + +// vxWorks-around: In the macros INT32_C(), UINT32_C(), INT64_C() and +// UINT64_C() are defined erroneously, yielding not a signed/ +// unsigned long/long long type, but a signed/unsigned int/long +// type. Eventually this leads to compile errors in ratio_fwd.hpp, +// when trying to define several constants which do not fit into a +// long type! We correct them here by redefining. + +# include + +// Special behaviour for DKMs: + +// Some macro-magic to do the job +# define VX_JOIN(X, Y) VX_DO_JOIN(X, Y) +# define VX_DO_JOIN(X, Y) VX_DO_JOIN2(X, Y) +# define VX_DO_JOIN2(X, Y) X##Y + +// Correctly setup the macros +# undef INT32_C +# undef UINT32_C +# undef INT64_C +# undef UINT64_C +# define INT32_C(x) VX_JOIN(x, L) +# define UINT32_C(x) VX_JOIN(x, UL) +# define INT64_C(x) VX_JOIN(x, LL) +# define UINT64_C(x) VX_JOIN(x, ULL) + +// #include Libraries required for the following function adaption +# include +#endif // _WRS_VXWORKS_MAJOR < 7 + +#include +#include + +#if defined(_WRS_KERNEL) && (_CPPLIB_VER < 700) + // recent kernels use Dinkum clib v7.00+ + // with widechar but older kernels + // do not have the -header, + // but apparently they do have an intrinsic wchar_t meanwhile! +# define BOOST_NO_CWCHAR + + // Lots of wide-functions and -headers are unavailable for DKMs as well: +# define BOOST_NO_CWCTYPE +# define BOOST_NO_SWPRINTF +# define BOOST_NO_STD_WSTRING +# define BOOST_NO_STD_WSTREAMBUF +#endif + + +// Use C-linkage for the following helper functions +#ifdef __cplusplus +extern "C" { +#endif + +// vxWorks-around: The required functions getrlimit() and getrlimit() are missing. +// But we have the similar functions getprlimit() and setprlimit(), +// which may serve the purpose. +// Problem: The vxWorks-documentation regarding these functions +// doesn't deserve its name! It isn't documented what the first two +// parameters idtype and id mean, so we must fall back to an educated +// guess - null, argh... :-/ + +// TODO: getprlimit() and setprlimit() do exist for RTPs only, for whatever reason. +// Thus for DKMs there would have to be another implementation. +#if defined ( __RTP__) && (_WRS_VXWORKS_MAJOR < 7) + inline int getrlimit(int resource, struct rlimit *rlp){ + return getprlimit(0, 0, resource, rlp); + } + + inline int setrlimit(int resource, const struct rlimit *rlp){ + return setprlimit(0, 0, resource, const_cast(rlp)); + } +#endif + +// vxWorks has ftruncate() only, so we do simulate truncate(): +inline int truncate(const char *p, off_t l){ + int fd = open(p, O_WRONLY); + if (fd == -1){ + errno = EACCES; + return -1; + } + if (ftruncate(fd, l) == -1){ + close(fd); + errno = EACCES; + return -1; + } + return close(fd); +} + +#ifdef __GNUC__ +# define ___unused __attribute__((unused)) +#else +# define ___unused +#endif + +// Fake symlink handling by dummy functions: +inline int symlink(const char* path1 ___unused, const char* path2 ___unused){ + // vxWorks has no symlinks -> always return an error! + errno = EACCES; + return -1; +} + +inline ssize_t readlink(const char* path1 ___unused, char* path2 ___unused, size_t size ___unused){ + // vxWorks has no symlinks -> always return an error! + errno = EACCES; + return -1; +} + +#if (_WRS_VXWORKS_MAJOR < 7) + +inline int gettimeofday(struct timeval *tv, void * /*tzv*/) { + struct timespec ts; + clock_gettime(CLOCK_MONOTONIC, &ts); + tv->tv_sec = ts.tv_sec; + tv->tv_usec = ts.tv_nsec / 1000; + return 0; +} +#endif + +#ifdef __cplusplus +} // extern "C" +#endif + +/* + * moved to os/utils/unix/freind_h/times.h in VxWorks 7 + * to avoid conflict with MPL operator times + */ +#if (_WRS_VXWORKS_MAJOR < 7) +# ifdef __cplusplus + +// vxWorks provides neither struct tms nor function times()! +// We implement an empty dummy-function, simply setting the user +// and system time to the half of thew actual system ticks-value +// and the child user and system time to 0. +// Rather ugly but at least it suppresses compiler errors... +// Unfortunately, this of course *does* have an severe impact on +// dependant libraries, actually this is chrono only! Here it will +// not be possible to correctly use user and system times! But +// as vxWorks is lacking the ability to calculate user and system +// process times there seems to be no other possible solution. +struct tms{ + clock_t tms_utime; // User CPU time + clock_t tms_stime; // System CPU time + clock_t tms_cutime; // User CPU time of terminated child processes + clock_t tms_cstime; // System CPU time of terminated child processes +}; + + + inline clock_t times(struct tms *t){ + struct timespec ts; + clock_gettime(CLOCK_THREAD_CPUTIME_ID, &ts); + clock_t ticks(static_cast(static_cast(ts.tv_sec) * CLOCKS_PER_SEC + + static_cast(ts.tv_nsec) * CLOCKS_PER_SEC / 1000000.0)); + t->tms_utime = ticks/2U; + t->tms_stime = ticks/2U; + t->tms_cutime = 0; // vxWorks is lacking the concept of a child process! + t->tms_cstime = 0; // -> Set the wait times for childs to 0 + return ticks; +} + + +namespace std { + using ::times; +} +# endif // __cplusplus +#endif // _WRS_VXWORKS_MAJOR < 7 + + +#ifdef __cplusplus +extern "C" void bzero (void *, size_t); // FD_ZERO uses bzero() but doesn't include strings.h + +// Put the selfmade functions into the std-namespace, just in case +namespace std { +# ifdef __RTP__ + using ::getrlimit; + using ::setrlimit; +# endif + using ::truncate; + using ::symlink; + using ::readlink; +# if (_WRS_VXWORKS_MAJOR < 7) + using ::gettimeofday; +# endif +} +#endif // __cplusplus + +// Some more macro-magic: +// vxWorks-around: Some functions are not present or broken in vxWorks +// but may be patched to life via helper macros... + +// Include signal.h which might contain a typo to be corrected here +#include + +#if (_WRS_VXWORKS_MAJOR < 7) +# define getpagesize() sysconf(_SC_PAGESIZE) // getpagesize is deprecated anyway! +inline int lstat(p, b) { return stat(p, b); } // lstat() == stat(), as vxWorks has no symlinks! +#endif + +#ifndef S_ISSOCK +# define S_ISSOCK(mode) ((mode & S_IFMT) == S_IFSOCK) // Is file a socket? +#endif +#ifndef FPE_FLTINV +# define FPE_FLTINV (FPE_FLTSUB+1) // vxWorks has no FPE_FLTINV, so define one as a dummy +#endif +#if !defined(BUS_ADRALN) && defined(BUS_ADRALNR) +# define BUS_ADRALN BUS_ADRALNR // Correct a supposed typo in vxWorks' +#endif +typedef int locale_t; // locale_t is a POSIX-extension, currently not present in vxWorks! + +// #include boilerplate code: +#include + +// vxWorks lies about XSI conformance, there is no nl_types.h: +#undef BOOST_HAS_NL_TYPES_H + +// vxWorks 7 adds C++11 support +// however it is optional, and does not match exactly the support determined +// by examining the Dinkum STL version and GCC version (or ICC and DCC) +#if !( defined( _WRS_CONFIG_LANG_LIB_CPLUS_CPLUS_USER_2011) || defined(_WRS_CONFIG_LIBCPLUS_STD)) +# define BOOST_NO_CXX11_ADDRESSOF // C11 addressof operator on memory location +# define BOOST_NO_CXX11_ALLOCATOR +# define BOOST_NO_CXX11_ATOMIC_SMART_PTR +# define BOOST_NO_CXX11_NUMERIC_LIMITS // max_digits10 in test/../print_helper.hpp +# define BOOST_NO_CXX11_SMART_PTR +# define BOOST_NO_CXX11_STD_ALIGN + + +# define BOOST_NO_CXX11_HDR_ARRAY +# define BOOST_NO_CXX11_HDR_ATOMIC +# define BOOST_NO_CXX11_HDR_CHRONO +# define BOOST_NO_CXX11_HDR_CONDITION_VARIABLE +# define BOOST_NO_CXX11_HDR_FORWARD_LIST //serialization/test/test_list.cpp +# define BOOST_NO_CXX11_HDR_FUNCTIONAL +# define BOOST_NO_CXX11_HDR_FUTURE +# define BOOST_NO_CXX11_HDR_MUTEX +# define BOOST_NO_CXX11_HDR_RANDOM //math/../test_data.hpp +# define BOOST_NO_CXX11_HDR_RATIO +# define BOOST_NO_CXX11_HDR_REGEX +# define BOOST_NO_CXX14_HDR_SHARED_MUTEX +# define BOOST_NO_CXX11_HDR_SYSTEM_ERROR +# define BOOST_NO_CXX11_HDR_THREAD +# define BOOST_NO_CXX11_HDR_TYPEINDEX +# define BOOST_NO_CXX11_HDR_TYPE_TRAITS +# define BOOST_NO_CXX11_HDR_TUPLE +# define BOOST_NO_CXX11_HDR_UNORDERED_MAP +# define BOOST_NO_CXX11_HDR_UNORDERED_SET +#else +# ifndef BOOST_SYSTEM_NO_DEPRECATED +# define BOOST_SYSTEM_NO_DEPRECATED // workaround link error in spirit +# endif +#endif + + +// NONE is used in enums in lamda and other libraries +#undef NONE +// restrict is an iostreams class +#undef restrict +// affects some typeof tests +#undef V7 + +// use fake poll() from Unix layer in ASIO to get full functionality +// most libraries will use select() but this define allows 'iostream' functionality +// which is based on poll() only +#if (_WRS_VXWORKS_MAJOR > 6) +# ifndef BOOST_ASIO_HAS_POSIX_STREAM_DESCRIPTOR +# define BOOST_ASIO_HAS_POSIX_STREAM_DESCRIPTOR +# endif +#else +# define BOOST_ASIO_DISABLE_SERIAL_PORT +#endif + diff --git a/third_party/boost/libs/config/include/boost/config/platform/wasm.hpp b/third_party/boost/libs/config/include/boost/config/platform/wasm.hpp new file mode 100644 index 00000000000..682b84859a0 --- /dev/null +++ b/third_party/boost/libs/config/include/boost/config/platform/wasm.hpp @@ -0,0 +1,23 @@ +// (C) Copyright John Maddock 2020. +// 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. + +// WASM specific config options: + +#define BOOST_PLATFORM "Wasm" + +#ifdef __has_include +#if __has_include() +# define BOOST_HAS_UNISTD_H +#endif +#endif + +// boilerplate code: +#include +// +// fenv lacks the C++11 macros: +// +#define BOOST_NO_FENV_H diff --git a/third_party/boost/libs/config/include/boost/config/platform/win32.hpp b/third_party/boost/libs/config/include/boost/config/platform/win32.hpp new file mode 100644 index 00000000000..450158fbaab --- /dev/null +++ b/third_party/boost/libs/config/include/boost/config/platform/win32.hpp @@ -0,0 +1,90 @@ +// (C) Copyright John Maddock 2001 - 2003. +// (C) Copyright Bill Kempf 2001. +// (C) Copyright Aleksey Gurtovoy 2003. +// (C) Copyright Rene Rivera 2005. +// 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. + +// Win32 specific config options: + +#define BOOST_PLATFORM "Win32" + +// Get the information about the MinGW runtime, i.e. __MINGW32_*VERSION. +#if defined(__MINGW32__) +# include <_mingw.h> +#endif + +#if defined(__GNUC__) && !defined(BOOST_NO_SWPRINTF) +# define BOOST_NO_SWPRINTF +#endif + +// Default defines for BOOST_SYMBOL_EXPORT and BOOST_SYMBOL_IMPORT +// If a compiler doesn't support __declspec(dllexport)/__declspec(dllimport), +// its boost/config/compiler/ file must define BOOST_SYMBOL_EXPORT and +// BOOST_SYMBOL_IMPORT +#ifndef BOOST_SYMBOL_EXPORT +# define BOOST_HAS_DECLSPEC +# define BOOST_SYMBOL_EXPORT __declspec(dllexport) +# define BOOST_SYMBOL_IMPORT __declspec(dllimport) +#endif + +#if defined(__MINGW32__) && ((__MINGW32_MAJOR_VERSION > 2) || ((__MINGW32_MAJOR_VERSION == 2) && (__MINGW32_MINOR_VERSION >= 0))) +# define BOOST_HAS_STDINT_H +# ifndef __STDC_LIMIT_MACROS +# define __STDC_LIMIT_MACROS +# endif +# define BOOST_HAS_DIRENT_H +# define BOOST_HAS_UNISTD_H +#endif + +#if defined(__MINGW32__) && (__GNUC__ >= 4) +// Mingw has these functions but there are persistent problems +// with calls to these crashing, so disable for now: +//# define BOOST_HAS_EXPM1 +//# define BOOST_HAS_LOG1P +# define BOOST_HAS_GETTIMEOFDAY +#endif +// +// Win32 will normally be using native Win32 threads, +// but there is a pthread library avaliable as an option, +// we used to disable this when BOOST_DISABLE_WIN32 was +// defined but no longer - this should allow some +// files to be compiled in strict mode - while maintaining +// a consistent setting of BOOST_HAS_THREADS across +// all translation units (needed for shared_ptr etc). +// + +#ifndef BOOST_HAS_PTHREADS +# define BOOST_HAS_WINTHREADS +#endif + +// +// WinCE configuration: +// +#if defined(_WIN32_WCE) || defined(UNDER_CE) +# define BOOST_NO_ANSI_APIS +// Windows CE does not have a conforming signature for swprintf +# define BOOST_NO_SWPRINTF +#else +# define BOOST_HAS_GETSYSTEMTIMEASFILETIME +# define BOOST_HAS_THREADEX +# define BOOST_HAS_GETSYSTEMTIMEASFILETIME +#endif + +// +// Windows Runtime +// +#if defined(WINAPI_FAMILY) && \ + (WINAPI_FAMILY == WINAPI_FAMILY_APP || WINAPI_FAMILY == WINAPI_FAMILY_PHONE_APP) +# define BOOST_NO_ANSI_APIS +#endif + +#ifndef BOOST_DISABLE_WIN32 +// WEK: Added +#define BOOST_HAS_FTIME +#define BOOST_WINDOWS 1 + +#endif diff --git a/third_party/boost/libs/config/include/boost/config/platform/zos.hpp b/third_party/boost/libs/config/include/boost/config/platform/zos.hpp new file mode 100644 index 00000000000..fa77999edc7 --- /dev/null +++ b/third_party/boost/libs/config/include/boost/config/platform/zos.hpp @@ -0,0 +1,32 @@ +// 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. + +// Platform setup for IBM z/OS. + +#define BOOST_PLATFORM "IBM z/OS" + +#include // For __UU, __C99, __TR1, ... + +#if defined(__UU) +# define BOOST_HAS_GETTIMEOFDAY +#endif + +#if defined(_OPEN_THREADS) || defined(__SUSV3_THR) +# define BOOST_HAS_PTHREADS +# define BOOST_HAS_PTHREAD_MUTEXATTR_SETTYPE +# define BOOST_HAS_THREADS +#endif + +#if defined(__SUSV3) || defined(__SUSV3_THR) +# define BOOST_HAS_SCHED_YIELD +#endif + +#define BOOST_HAS_SIGACTION +#define BOOST_HAS_UNISTD_H +#define BOOST_HAS_DIRENT_H +#define BOOST_HAS_NL_TYPES_H diff --git a/third_party/boost/libs/config/include/boost/config/pragma_message.hpp b/third_party/boost/libs/config/include/boost/config/pragma_message.hpp new file mode 100644 index 00000000000..b2c5ff2e868 --- /dev/null +++ b/third_party/boost/libs/config/include/boost/config/pragma_message.hpp @@ -0,0 +1,31 @@ +#ifndef BOOST_CONFIG_PRAGMA_MESSAGE_HPP_INCLUDED +#define BOOST_CONFIG_PRAGMA_MESSAGE_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 +// +// BOOST_PRAGMA_MESSAGE("message") +// +// Expands to the equivalent of #pragma message("message") +// +// Note that this header is C compatible. + +#include + +#if defined(BOOST_DISABLE_PRAGMA_MESSAGE) +# define BOOST_PRAGMA_MESSAGE(x) +#elif defined(__INTEL_COMPILER) +# define BOOST_PRAGMA_MESSAGE(x) __pragma(message(__FILE__ "(" BOOST_STRINGIZE(__LINE__) "): note: " x)) +#elif defined(__GNUC__) +# define BOOST_PRAGMA_MESSAGE(x) _Pragma(BOOST_STRINGIZE(message(x))) +#elif defined(_MSC_VER) +# define BOOST_PRAGMA_MESSAGE(x) __pragma(message(__FILE__ "(" BOOST_STRINGIZE(__LINE__) "): note: " x)) +#else +# define BOOST_PRAGMA_MESSAGE(x) +#endif + +#endif // BOOST_CONFIG_PRAGMA_MESSAGE_HPP_INCLUDED diff --git a/third_party/boost/libs/config/include/boost/config/requires_threads.hpp b/third_party/boost/libs/config/include/boost/config/requires_threads.hpp new file mode 100644 index 00000000000..c23a2ce3c9e --- /dev/null +++ b/third_party/boost/libs/config/include/boost/config/requires_threads.hpp @@ -0,0 +1,92 @@ +// (C) Copyright John Maddock 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) + + +#ifndef BOOST_CONFIG_REQUIRES_THREADS_HPP +#define BOOST_CONFIG_REQUIRES_THREADS_HPP + +#ifndef BOOST_CONFIG_HPP +# include +#endif + +#if defined(BOOST_DISABLE_THREADS) + +// +// special case to handle versions of gcc which don't currently support threads: +// +#if defined(__GNUC__) && ((__GNUC__ < 3) || (__GNUC_MINOR__ <= 3) || !defined(BOOST_STRICT_CONFIG)) +// +// this is checked up to gcc 3.3: +// +#if defined(__sgi) || defined(__hpux) +# error "Multi-threaded programs are not supported by gcc on HPUX or Irix (last checked with gcc 3.3)" +#endif + +#endif + +# error "Threading support unavaliable: it has been explicitly disabled with BOOST_DISABLE_THREADS" + +#elif !defined(BOOST_HAS_THREADS) + +# if defined __COMO__ +// Comeau C++ +# error "Compiler threading support is not turned on. Please set the correct command line options for threading: -D_MT (Windows) or -D_REENTRANT (Unix)" + +#elif defined(__INTEL_COMPILER) || defined(__ICL) || defined(__ICC) || defined(__ECC) +// Intel +#ifdef _WIN32 +# error "Compiler threading support is not turned on. Please set the correct command line options for threading: either /MT /MTd /MD or /MDd" +#else +# error "Compiler threading support is not turned on. Please set the correct command line options for threading: -openmp" +#endif + +# elif defined __GNUC__ +// GNU C++: +# error "Compiler threading support is not turned on. Please set the correct command line options for threading: -pthread (Linux), -pthreads (Solaris) or -mthreads (Mingw32)" + +#elif defined __sgi +// SGI MIPSpro C++ +# error "Compiler threading support is not turned on. Please set the correct command line options for threading: -D_SGI_MP_SOURCE" + +#elif defined __DECCXX +// Compaq Tru64 Unix cxx +# error "Compiler threading support is not turned on. Please set the correct command line options for threading: -pthread" + +#elif defined BOOST_BORLANDC +// Borland +# error "Compiler threading support is not turned on. Please set the correct command line options for threading: -tWM" + +#elif defined __MWERKS__ +// Metrowerks CodeWarrior +# error "Compiler threading support is not turned on. Please set the correct command line options for threading: either -runtime sm, -runtime smd, -runtime dm, or -runtime dmd" + +#elif defined __SUNPRO_CC +// Sun Workshop Compiler C++ +# error "Compiler threading support is not turned on. Please set the correct command line options for threading: -mt" + +#elif defined __HP_aCC +// HP aCC +# error "Compiler threading support is not turned on. Please set the correct command line options for threading: -mt" + +#elif defined(__IBMCPP__) +// IBM Visual Age +# error "Compiler threading support is not turned on. Please compile the code with the xlC_r compiler" + +#elif defined _MSC_VER +// Microsoft Visual C++ +// +// Must remain the last #elif since some other vendors (Metrowerks, for +// example) also #define _MSC_VER +# error "Compiler threading support is not turned on. Please set the correct command line options for threading: either /MT /MTd /MD or /MDd" + +#else + +# error "Compiler threading support is not turned on. Please consult your compiler's documentation for the appropriate options to use" + +#endif // compilers + +#endif // BOOST_HAS_THREADS + +#endif // BOOST_CONFIG_REQUIRES_THREADS_HPP diff --git a/third_party/boost/libs/config/include/boost/config/stdlib/dinkumware.hpp b/third_party/boost/libs/config/include/boost/config/stdlib/dinkumware.hpp new file mode 100644 index 00000000000..46ffe093ee4 --- /dev/null +++ b/third_party/boost/libs/config/include/boost/config/stdlib/dinkumware.hpp @@ -0,0 +1,324 @@ +// (C) Copyright John Maddock 2001 - 2003. +// (C) Copyright Jens Maurer 2001. +// (C) Copyright Peter Dimov 2001. +// (C) Copyright David Abrahams 2002. +// (C) Copyright Guillaume Melquiond 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. + +// Dinkumware standard library config: + +#if !defined(_YVALS) && !defined(_CPPLIB_VER) +#include +#if !defined(_YVALS) && !defined(_CPPLIB_VER) +#error This is not the Dinkumware lib! +#endif +#endif + + +#if defined(_CPPLIB_VER) && (_CPPLIB_VER >= 306) + // full dinkumware 3.06 and above + // fully conforming provided the compiler supports it: +# if !(defined(_GLOBAL_USING) && (_GLOBAL_USING+0 > 0)) && !defined(BOOST_BORLANDC) && !defined(_STD) && !(defined(__ICC) && (__ICC >= 700)) // can be defined in yvals.h +# define BOOST_NO_STDC_NAMESPACE +# endif +# if !(defined(_HAS_MEMBER_TEMPLATES_REBIND) && (_HAS_MEMBER_TEMPLATES_REBIND+0 > 0)) && !(defined(_MSC_VER) && (_MSC_VER > 1300)) && defined(BOOST_MSVC) +# define BOOST_NO_STD_ALLOCATOR +# endif +# define BOOST_HAS_PARTIAL_STD_ALLOCATOR +# if defined(BOOST_MSVC) && (BOOST_MSVC < 1300) + // if this lib version is set up for vc6 then there is no std::use_facet: +# define BOOST_NO_STD_USE_FACET +# define BOOST_HAS_TWO_ARG_USE_FACET + // C lib functions aren't in namespace std either: +# define BOOST_NO_STDC_NAMESPACE + // and nor is +# define BOOST_NO_EXCEPTION_STD_NAMESPACE +# endif +// There's no numeric_limits support unless _LONGLONG is defined: +# if !defined(_LONGLONG) && (_CPPLIB_VER <= 310) +# define BOOST_NO_MS_INT64_NUMERIC_LIMITS +# endif +// 3.06 appears to have (non-sgi versions of) & , +// and no at all +#else +# define BOOST_MSVC_STD_ITERATOR 1 +# define BOOST_NO_STD_ITERATOR +# define BOOST_NO_TEMPLATED_ITERATOR_CONSTRUCTORS +# define BOOST_NO_STD_ALLOCATOR +# define BOOST_NO_STDC_NAMESPACE +# define BOOST_NO_STD_USE_FACET +# define BOOST_NO_STD_OUTPUT_ITERATOR_ASSIGN +# define BOOST_HAS_MACRO_USE_FACET +# ifndef _CPPLIB_VER + // Updated Dinkum library defines this, and provides + // its own min and max definitions, as does MTA version. +# ifndef __MTA__ +# define BOOST_NO_STD_MIN_MAX +# endif +# define BOOST_NO_MS_INT64_NUMERIC_LIMITS +# endif +#endif + +// +// std extension namespace is stdext for vc7.1 and later, +// the same applies to other compilers that sit on top +// of vc7.1 (Intel and Comeau): +// +#if defined(_MSC_VER) && (_MSC_VER >= 1310) && !defined(BOOST_BORLANDC) +# define BOOST_STD_EXTENSION_NAMESPACE stdext +#endif + + +#if (defined(_MSC_VER) && (_MSC_VER <= 1300) && !defined(BOOST_BORLANDC)) || !defined(_CPPLIB_VER) || (_CPPLIB_VER < 306) + // if we're using a dinkum lib that's + // been configured for VC6/7 then there is + // no iterator traits (true even for icl) +# define BOOST_NO_STD_ITERATOR_TRAITS +#endif + +#if defined(__ICL) && (__ICL < 800) && defined(_CPPLIB_VER) && (_CPPLIB_VER <= 310) +// Intel C++ chokes over any non-trivial use of +// this may be an overly restrictive define, but regex fails without it: +# define BOOST_NO_STD_LOCALE +#endif + +#if ((defined(BOOST_MSVC) && BOOST_MSVC >= 1400) || (defined(__clang__) && defined(_MSC_VER))) && (_MSC_VER < 1800) +// Fix for VC++ 8.0 on up ( I do not have a previous version to test ) +// or clang-cl. If exceptions are off you must manually include the +// header before including the header. Admittedly +// trying to use Boost libraries or the standard C++ libraries without +// exception support is not suggested but currently clang-cl ( v 3.4 ) +// does not support exceptions and must be compiled with exceptions off. +#if !_HAS_EXCEPTIONS +#include +#endif +#include +#if !_HAS_EXCEPTIONS +# define BOOST_NO_STD_TYPEINFO +#endif +#endif +#if defined(__ghs__) && !_HAS_NAMESPACE +# define BOOST_NO_STD_TYPEINFO +#endif + +// C++0x headers implemented in 520 (as shipped by Microsoft) +// +#if !defined(_CPPLIB_VER) || _CPPLIB_VER < 520 +# define BOOST_NO_CXX11_HDR_ARRAY +# define BOOST_NO_CXX11_HDR_CODECVT +# define BOOST_NO_CXX11_HDR_FORWARD_LIST +# define BOOST_NO_CXX11_HDR_INITIALIZER_LIST +# define BOOST_NO_CXX11_HDR_RANDOM +# define BOOST_NO_CXX11_HDR_REGEX +# define BOOST_NO_CXX11_HDR_SYSTEM_ERROR +# define BOOST_NO_CXX11_HDR_UNORDERED_MAP +# define BOOST_NO_CXX11_HDR_UNORDERED_SET +# define BOOST_NO_CXX11_HDR_TUPLE +# define BOOST_NO_CXX11_HDR_TYPEINDEX +# define BOOST_NO_CXX11_HDR_FUNCTIONAL +# define BOOST_NO_CXX11_NUMERIC_LIMITS +# define BOOST_NO_CXX11_SMART_PTR +#endif + +#if ((!defined(_HAS_TR1_IMPORTS) || (_HAS_TR1_IMPORTS+0 == 0)) && !defined(BOOST_NO_CXX11_HDR_TUPLE)) \ + && (!defined(_CPPLIB_VER) || _CPPLIB_VER < 610) +# define BOOST_NO_CXX11_HDR_TUPLE +#endif + +// C++0x headers implemented in 540 (as shipped by Microsoft) +// +#if !defined(_CPPLIB_VER) || _CPPLIB_VER < 540 +# define BOOST_NO_CXX11_HDR_TYPE_TRAITS +# define BOOST_NO_CXX11_HDR_CHRONO +# define BOOST_NO_CXX11_HDR_CONDITION_VARIABLE +# define BOOST_NO_CXX11_HDR_FUTURE +# define BOOST_NO_CXX11_HDR_MUTEX +# define BOOST_NO_CXX11_HDR_RATIO +# define BOOST_NO_CXX11_HDR_THREAD +# define BOOST_NO_CXX11_ATOMIC_SMART_PTR +# define BOOST_NO_CXX11_HDR_EXCEPTION +#endif + +// C++0x headers implemented in 610 (as shipped by Microsoft) +// +#if !defined(_CPPLIB_VER) || _CPPLIB_VER < 610 +# define BOOST_NO_CXX11_HDR_INITIALIZER_LIST +# define BOOST_NO_CXX11_HDR_ATOMIC +# define BOOST_NO_CXX11_ALLOCATOR +// 540 has std::align but it is not a conforming implementation +# define BOOST_NO_CXX11_STD_ALIGN +#endif + +// Before 650 std::pointer_traits has a broken rebind template +#if !defined(_CPPLIB_VER) || _CPPLIB_VER < 650 +# define BOOST_NO_CXX11_POINTER_TRAITS +#elif defined(BOOST_MSVC) && BOOST_MSVC < 1910 +# define BOOST_NO_CXX11_POINTER_TRAITS +#endif + +#if defined(__has_include) +#if !__has_include() +# define BOOST_NO_CXX14_HDR_SHARED_MUTEX +#elif (__cplusplus < 201402) && !defined(_MSC_VER) +# define BOOST_NO_CXX14_HDR_SHARED_MUTEX +#endif +#elif !defined(_CPPLIB_VER) || (_CPPLIB_VER < 650) +# define BOOST_NO_CXX14_HDR_SHARED_MUTEX +#endif + +// C++14 features +#if !defined(_CPPLIB_VER) || (_CPPLIB_VER < 650) +# define BOOST_NO_CXX14_STD_EXCHANGE +#endif + +// C++17 features +#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 +#endif + +#if defined(BOOST_INTEL) && (BOOST_INTEL <= 1400) +// Intel's compiler can't handle this header yet: +# define BOOST_NO_CXX11_HDR_ATOMIC +#endif + + +// 520..610 have std::addressof, but it doesn't support functions +// +#if !defined(_CPPLIB_VER) || _CPPLIB_VER < 650 +# define BOOST_NO_CXX11_ADDRESSOF +#endif + +// 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) && (!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 + +#if defined(_CPPLIB_VER) && (_CPPLIB_VER >= 650) +// If _HAS_AUTO_PTR_ETC is defined to 0, std::auto_ptr and std::random_shuffle are not available. +// See https://www.visualstudio.com/en-us/news/vs2015-vs.aspx#C++ +// and http://blogs.msdn.com/b/vcblog/archive/2015/06/19/c-11-14-17-features-in-vs-2015-rtm.aspx +# if defined(_HAS_AUTO_PTR_ETC) && (_HAS_AUTO_PTR_ETC == 0) +# define BOOST_NO_AUTO_PTR +# 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 + + +// +// Things not supported by the CLR: +#ifdef _M_CEE +#ifndef BOOST_NO_CXX11_HDR_MUTEX +# define BOOST_NO_CXX11_HDR_MUTEX +#endif +#ifndef BOOST_NO_CXX11_HDR_ATOMIC +# define BOOST_NO_CXX11_HDR_ATOMIC +#endif +#ifndef BOOST_NO_CXX11_HDR_FUTURE +# define BOOST_NO_CXX11_HDR_FUTURE +#endif +#ifndef BOOST_NO_CXX11_HDR_CONDITION_VARIABLE +# define BOOST_NO_CXX11_HDR_CONDITION_VARIABLE +#endif +#ifndef BOOST_NO_CXX11_HDR_THREAD +# define BOOST_NO_CXX11_HDR_THREAD +#endif +#ifndef BOOST_NO_CXX14_HDR_SHARED_MUTEX +# define BOOST_NO_CXX14_HDR_SHARED_MUTEX +#endif +#ifndef BOOST_NO_CXX14_STD_EXCHANGE +# define BOOST_NO_CXX14_STD_EXCHANGE +#endif +#ifndef BOOST_NO_FENV_H +# define BOOST_NO_FENV_H +#endif +#endif + +#ifdef _CPPLIB_VER +# define BOOST_DINKUMWARE_STDLIB _CPPLIB_VER +#else +# 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 +# define BOOST_STDLIB "Dinkumware standard library version 1.x" +#endif diff --git a/third_party/boost/libs/config/include/boost/config/stdlib/libcomo.hpp b/third_party/boost/libs/config/include/boost/config/stdlib/libcomo.hpp new file mode 100644 index 00000000000..6a8a1619625 --- /dev/null +++ b/third_party/boost/libs/config/include/boost/config/stdlib/libcomo.hpp @@ -0,0 +1,93 @@ +// (C) Copyright John Maddock 2002 - 2003. +// (C) Copyright Jens Maurer 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. + +// Comeau STL: + +#if !defined(__LIBCOMO__) +# include +# if !defined(__LIBCOMO__) +# error "This is not the Comeau STL!" +# endif +#endif + +// +// std::streambuf is non-standard +// NOTE: versions of libcomo prior to beta28 have octal version numbering, +// e.g. version 25 is 21 (dec) +#if __LIBCOMO_VERSION__ <= 22 +# define BOOST_NO_STD_WSTREAMBUF +#endif + +#if (__LIBCOMO_VERSION__ <= 31) && defined(_WIN32) +#define BOOST_NO_SWPRINTF +#endif + +#if __LIBCOMO_VERSION__ >= 31 +# define BOOST_HAS_HASH +# define BOOST_HAS_SLIST +#endif + +// C++0x headers not yet implemented +// +# define BOOST_NO_CXX11_HDR_ARRAY +# define BOOST_NO_CXX11_HDR_CHRONO +# define BOOST_NO_CXX11_HDR_CODECVT +# define BOOST_NO_CXX11_HDR_CONDITION_VARIABLE +# define BOOST_NO_CXX11_HDR_EXCEPTION +# define BOOST_NO_CXX11_HDR_FORWARD_LIST +# define BOOST_NO_CXX11_HDR_FUTURE +# define BOOST_NO_CXX11_HDR_INITIALIZER_LIST +# define BOOST_NO_CXX11_HDR_MUTEX +# define BOOST_NO_CXX11_HDR_RANDOM +# define BOOST_NO_CXX11_HDR_RATIO +# define BOOST_NO_CXX11_HDR_REGEX +# define BOOST_NO_CXX11_HDR_SYSTEM_ERROR +# define BOOST_NO_CXX11_HDR_THREAD +# define BOOST_NO_CXX11_HDR_TUPLE +# define BOOST_NO_CXX11_HDR_TYPE_TRAITS +# define BOOST_NO_CXX11_HDR_TYPEINDEX +# define BOOST_NO_CXX11_HDR_UNORDERED_MAP +# define BOOST_NO_CXX11_HDR_UNORDERED_SET +# define BOOST_NO_CXX11_NUMERIC_LIMITS +# define BOOST_NO_CXX11_ALLOCATOR +# define BOOST_NO_CXX11_POINTER_TRAITS +# define BOOST_NO_CXX11_ATOMIC_SMART_PTR +# define BOOST_NO_CXX11_SMART_PTR +# define BOOST_NO_CXX11_HDR_FUNCTIONAL +# define BOOST_NO_CXX11_HDR_ATOMIC +# define BOOST_NO_CXX11_STD_ALIGN +# define BOOST_NO_CXX11_ADDRESSOF + +#if defined(__has_include) +#if !__has_include() +# define BOOST_NO_CXX14_HDR_SHARED_MUTEX +#elif __cplusplus < 201402 +# define BOOST_NO_CXX14_HDR_SHARED_MUTEX +#endif +#else +# define BOOST_NO_CXX14_HDR_SHARED_MUTEX +#endif + +// C++14 features +# define BOOST_NO_CXX14_STD_EXCHANGE + +// C++17 features +# define BOOST_NO_CXX17_STD_APPLY +# define BOOST_NO_CXX17_STD_INVOKE +# define BOOST_NO_CXX17_ITERATOR_TRAITS + +// +// Intrinsic type_traits support. +// The SGI STL has it's own __type_traits class, which +// has intrinsic compiler support with SGI's compilers. +// Whatever map SGI style type traits to boost equivalents: +// +#define BOOST_HAS_SGI_TYPE_TRAITS + +#define BOOST_STDLIB "Comeau standard library " BOOST_STRINGIZE(__LIBCOMO_VERSION__) diff --git a/third_party/boost/libs/config/include/boost/config/stdlib/libcpp.hpp b/third_party/boost/libs/config/include/boost/config/stdlib/libcpp.hpp new file mode 100644 index 00000000000..0e9f2445ed0 --- /dev/null +++ b/third_party/boost/libs/config/include/boost/config/stdlib/libcpp.hpp @@ -0,0 +1,180 @@ +// (C) Copyright Christopher Jefferson 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. + +// config for libc++ +// Might need more in here later. + +#if !defined(_LIBCPP_VERSION) +# include +# if !defined(_LIBCPP_VERSION) +# error "This is not libc++!" +# endif +#endif + +#define BOOST_STDLIB "libc++ version " BOOST_STRINGIZE(_LIBCPP_VERSION) + +#define BOOST_HAS_THREADS + +#ifdef _LIBCPP_HAS_NO_VARIADICS +# define BOOST_NO_CXX11_HDR_TUPLE +#endif + +// BOOST_NO_CXX11_ALLOCATOR should imply no support for the C++11 +// allocator model. The C++11 allocator model requires a conforming +// std::allocator_traits which is only possible with C++11 template +// aliases since members rebind_alloc and rebind_traits require it. +#if defined(_LIBCPP_HAS_NO_TEMPLATE_ALIASES) +# define BOOST_NO_CXX11_ALLOCATOR +# define BOOST_NO_CXX11_POINTER_TRAITS +#endif + +#if __cplusplus < 201103 +// +// These two appear to be somewhat useable in C++03 mode, there may be others... +// +//# define BOOST_NO_CXX11_HDR_ARRAY +//# define BOOST_NO_CXX11_HDR_FORWARD_LIST + +# define BOOST_NO_CXX11_HDR_CODECVT +# define BOOST_NO_CXX11_HDR_CONDITION_VARIABLE +# define BOOST_NO_CXX11_HDR_EXCEPTION +# define BOOST_NO_CXX11_HDR_INITIALIZER_LIST +# define BOOST_NO_CXX11_HDR_MUTEX +# define BOOST_NO_CXX11_HDR_RANDOM +# define BOOST_NO_CXX11_HDR_RATIO +# define BOOST_NO_CXX11_HDR_REGEX +# define BOOST_NO_CXX11_HDR_SYSTEM_ERROR +# define BOOST_NO_CXX11_HDR_THREAD +# define BOOST_NO_CXX11_HDR_TUPLE +# define BOOST_NO_CXX11_HDR_TYPEINDEX +# define BOOST_NO_CXX11_HDR_UNORDERED_MAP +# define BOOST_NO_CXX11_HDR_UNORDERED_SET +# define BOOST_NO_CXX11_NUMERIC_LIMITS +# define BOOST_NO_CXX11_ALLOCATOR +# define BOOST_NO_CXX11_POINTER_TRAITS +# define BOOST_NO_CXX11_SMART_PTR +# define BOOST_NO_CXX11_HDR_FUNCTIONAL +# define BOOST_NO_CXX11_STD_ALIGN +# define BOOST_NO_CXX11_ADDRESSOF +# define BOOST_NO_CXX11_HDR_ATOMIC +# define BOOST_NO_CXX11_ATOMIC_SMART_PTR +# define BOOST_NO_CXX11_HDR_CHRONO +# define BOOST_NO_CXX11_HDR_TYPE_TRAITS +# define BOOST_NO_CXX11_HDR_FUTURE +#elif _LIBCPP_VERSION < 3700 +// +// These appear to be unusable/incomplete so far: +// +# define BOOST_NO_CXX11_HDR_ATOMIC +# define BOOST_NO_CXX11_ATOMIC_SMART_PTR +# define BOOST_NO_CXX11_HDR_CHRONO +# define BOOST_NO_CXX11_HDR_TYPE_TRAITS +# define BOOST_NO_CXX11_HDR_FUTURE +#endif + + +#if _LIBCPP_VERSION < 3700 +// libc++ uses a non-standard messages_base +#define BOOST_NO_STD_MESSAGES +#endif + +// C++14 features +#if (_LIBCPP_VERSION < 3700) || (__cplusplus <= 201402L) +# define BOOST_NO_CXX14_STD_EXCHANGE +#endif + +// C++17 features +#if (_LIBCPP_VERSION < 4000) || (__cplusplus <= 201402L) +# define BOOST_NO_CXX17_STD_APPLY +# define BOOST_NO_CXX17_HDR_OPTIONAL +# define BOOST_NO_CXX17_HDR_STRING_VIEW +# define BOOST_NO_CXX17_HDR_VARIANT +#endif +#if (_LIBCPP_VERSION > 4000) && (__cplusplus > 201402L) && !defined(_LIBCPP_ENABLE_CXX17_REMOVED_AUTO_PTR) +# define BOOST_NO_AUTO_PTR +#endif +#if (_LIBCPP_VERSION > 4000) && (__cplusplus > 201402L) && !defined(_LIBCPP_ENABLE_CXX17_REMOVED_RANDOM_SHUFFLE) +# define BOOST_NO_CXX98_RANDOM_SHUFFLE +#endif +#if (_LIBCPP_VERSION > 4000) && (__cplusplus > 201402L) && !defined(_LIBCPP_ENABLE_CXX17_REMOVED_BINDERS) +# define BOOST_NO_CXX98_BINDERS +#endif + +#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 +// support for thread_local, leading to linker errors such as +// "undefined reference to `__cxa_thread_atexit'". It is fixed in the +// most recent releases of libc++abi though... +# define BOOST_NO_CXX11_THREAD_LOCAL +#endif + +#if defined(__linux__) && (_LIBCPP_VERSION < 6000) && !defined(BOOST_NO_CXX11_THREAD_LOCAL) +// After libc++-dev is installed on Trusty, clang++-libc++ almost works, +// except uses of `thread_local` fail with undefined reference to +// `__cxa_thread_atexit`. +// +// clang's libc++abi provides an implementation by deferring to the glibc +// implementation, which may or may not be available (it is not on Trusty). +// clang 4's libc++abi will provide an implementation if one is not in glibc +// though, so thread local support should work with clang 4 and above as long +// as libc++abi is linked in. +# define BOOST_NO_CXX11_THREAD_LOCAL +#endif + +#if defined(__has_include) +#if !__has_include() +# define BOOST_NO_CXX14_HDR_SHARED_MUTEX +#elif __cplusplus <= 201103 +# define BOOST_NO_CXX14_HDR_SHARED_MUTEX +#endif +#elif __cplusplus < 201402 +# define BOOST_NO_CXX14_HDR_SHARED_MUTEX +#endif + +#if !defined(BOOST_NO_CXX14_HDR_SHARED_MUTEX) && (_LIBCPP_VERSION < 5000) +# 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/third_party/boost/libs/config/include/boost/config/stdlib/libstdcpp3.hpp b/third_party/boost/libs/config/include/boost/config/stdlib/libstdcpp3.hpp new file mode 100644 index 00000000000..ad70936deae --- /dev/null +++ b/third_party/boost/libs/config/include/boost/config/stdlib/libstdcpp3.hpp @@ -0,0 +1,482 @@ +// (C) Copyright John Maddock 2001. +// (C) Copyright Jens Maurer 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. + +// config for libstdc++ v3 +// not much to go in here: + +#define BOOST_GNU_STDLIB 1 + +#ifdef __GLIBCXX__ +#define BOOST_STDLIB "GNU libstdc++ version " BOOST_STRINGIZE(__GLIBCXX__) +#else +#define BOOST_STDLIB "GNU libstdc++ version " BOOST_STRINGIZE(__GLIBCPP__) +#endif + +#if !defined(_GLIBCPP_USE_WCHAR_T) && !defined(_GLIBCXX_USE_WCHAR_T) +# define BOOST_NO_CWCHAR +# define BOOST_NO_CWCTYPE +# define BOOST_NO_STD_WSTRING +# define BOOST_NO_STD_WSTREAMBUF +#endif + +#if defined(__osf__) && !defined(_REENTRANT) \ + && ( defined(_GLIBCXX_HAVE_GTHR_DEFAULT) || defined(_GLIBCPP_HAVE_GTHR_DEFAULT) ) +// GCC 3 on Tru64 forces the definition of _REENTRANT when any std lib header +// file is included, therefore for consistency we define it here as well. +# define _REENTRANT +#endif + +#ifdef __GLIBCXX__ // gcc 3.4 and greater: +# if defined(_GLIBCXX_HAVE_GTHR_DEFAULT) \ + || defined(_GLIBCXX__PTHREADS) \ + || defined(_GLIBCXX_HAS_GTHREADS) \ + || defined(_WIN32) \ + || defined(_AIX) \ + || defined(__HAIKU__) + // + // If the std lib has thread support turned on, then turn it on in Boost + // as well. We do this because some gcc-3.4 std lib headers define _REENTANT + // while others do not... + // +# define BOOST_HAS_THREADS +# else +# define BOOST_DISABLE_THREADS +# endif +#elif defined(__GLIBCPP__) \ + && !defined(_GLIBCPP_HAVE_GTHR_DEFAULT) \ + && !defined(_GLIBCPP__PTHREADS) + // disable thread support if the std lib was built single threaded: +# define BOOST_DISABLE_THREADS +#endif + +#if (defined(linux) || defined(__linux) || defined(__linux__)) && defined(__arm__) && defined(_GLIBCPP_HAVE_GTHR_DEFAULT) +// linux on arm apparently doesn't define _REENTRANT +// so just turn on threading support whenever the std lib is thread safe: +# define BOOST_HAS_THREADS +#endif + +#if !defined(_GLIBCPP_USE_LONG_LONG) \ + && !defined(_GLIBCXX_USE_LONG_LONG)\ + && defined(BOOST_HAS_LONG_LONG) +// May have been set by compiler/*.hpp, but "long long" without library +// support is useless. +# undef BOOST_HAS_LONG_LONG +#endif + +// Apple doesn't seem to reliably defined a *unix* macro +#if !defined(CYGWIN) && ( defined(__unix__) \ + || defined(__unix) \ + || defined(unix) \ + || defined(__APPLE__) \ + || defined(__APPLE) \ + || defined(APPLE)) +# include +#endif + +#ifndef __VXWORKS__ // VxWorks uses Dinkum, not GNU STL with GCC +#if defined(__GLIBCXX__) || (defined(__GLIBCPP__) && __GLIBCPP__>=20020514) // GCC >= 3.1.0 +# define BOOST_STD_EXTENSION_NAMESPACE __gnu_cxx +# define BOOST_HAS_SLIST +# define BOOST_HAS_HASH +# define BOOST_SLIST_HEADER +# if !defined(__GNUC__) || __GNUC__ < 4 || (__GNUC__ == 4 && __GNUC_MINOR__ < 3) +# define BOOST_HASH_SET_HEADER +# define BOOST_HASH_MAP_HEADER +# else +# define BOOST_HASH_SET_HEADER +# define BOOST_HASH_MAP_HEADER +# endif +#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: +// +#if defined(__GXX_EXPERIMENTAL_CXX0X__) || (__cplusplus >= 201103) +# define BOOST_LIBSTDCXX11 +#endif + +// +// Decide which version of libstdc++ we have, normally +// libstdc++ C++0x support is detected via __GNUC__, __GNUC_MINOR__, and possibly +// __GNUC_PATCHLEVEL__ at the suggestion of Jonathan Wakely, one of the libstdc++ +// developers. He also commented: +// +// "I'm not sure how useful __GLIBCXX__ is for your purposes, for instance in +// GCC 4.2.4 it is set to 20080519 but in GCC 4.3.0 it is set to 20080305. +// Although 4.3.0 was released earlier than 4.2.4, it has better C++0x support +// than any release in the 4.2 series." +// +// Another resource for understanding libstdc++ features is: +// http://gcc.gnu.org/onlinedocs/libstdc++/manual/status.html#manual.intro.status.standard.200x +// +// However, using the GCC version number fails when the compiler is clang since this +// only ever claims to emulate GCC-4.2, see https://svn.boost.org/trac/boost/ticket/7473 +// for a long discussion on this issue. What we can do though is use clang's __has_include +// to detect the presence of a C++11 header that was introduced with a specific GCC release. +// We still have to be careful though as many such headers were buggy and/or incomplete when +// first introduced, so we only check for headers that were fully featured from day 1, and then +// use that to infer the underlying GCC version: +// +#ifdef __clang__ + +#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 +#elif __has_include() +# define BOOST_LIBSTDCXX_VERSION 80100 +#elif __has_include() +# define BOOST_LIBSTDCXX_VERSION 70100 +#elif __has_include() +# define BOOST_LIBSTDCXX_VERSION 60100 +#elif __has_include() +# define BOOST_LIBSTDCXX_VERSION 50100 +#elif __has_include() +# define BOOST_LIBSTDCXX_VERSION 40900 +#elif __has_include() +# define BOOST_LIBSTDCXX_VERSION 40800 +#elif __has_include() +# define BOOST_LIBSTDCXX_VERSION 40700 +#elif __has_include() +# define BOOST_LIBSTDCXX_VERSION 40600 +#elif __has_include() +# define BOOST_LIBSTDCXX_VERSION 40500 +#elif __has_include() +# define BOOST_LIBSTDCXX_VERSION 40400 +#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, +// defining it here is a terrible cludge, but should get things working: +extern "C" char *gets (char *__s); +#endif +// +// clang is unable to parse some GCC headers, add those workarounds here: +// +#if BOOST_LIBSTDCXX_VERSION < 50000 +# define BOOST_NO_CXX11_HDR_REGEX +#endif +// +// GCC 4.7.x has no __cxa_thread_atexit which +// thread_local objects require for cleanup: +// +#if BOOST_LIBSTDCXX_VERSION < 40800 +# define BOOST_NO_CXX11_THREAD_LOCAL +#endif +// +// Early clang versions can handle , not exactly sure which versions +// but certainly up to clang-3.8 and gcc-4.6: +// +#if (__clang_major__ < 5) +# if BOOST_LIBSTDCXX_VERSION < 40800 +# define BOOST_NO_CXX11_HDR_FUTURE +# define BOOST_NO_CXX11_HDR_MUTEX +# define BOOST_NO_CXX11_HDR_CONDITION_VARIABLE +# define BOOST_NO_CXX11_HDR_CHRONO +# endif +#endif + +// +// GCC 4.8 and 9 add working versions of and respectively. +// However, we have no test for these as the headers were present but broken +// in early GCC versions. +// +#endif + +#if defined(__SUNPRO_CC) && (__SUNPRO_CC >= 0x5130) && (__cplusplus >= 201103L) +// +// Oracle Solaris compiler uses it's own verison of libstdc++ but doesn't +// set __GNUC__ +// +#if __SUNPRO_CC >= 0x5140 +#define BOOST_LIBSTDCXX_VERSION 50100 +#else +#define BOOST_LIBSTDCXX_VERSION 40800 +#endif +#endif + +#if !defined(BOOST_LIBSTDCXX_VERSION) +# define BOOST_LIBSTDCXX_VERSION (__GNUC__ * 10000 + __GNUC_MINOR__ * 100 + __GNUC_PATCHLEVEL__) +#endif + +// std::auto_ptr isn't provided with _GLIBCXX_DEPRECATED=0 (GCC 4.5 and earlier) +// or _GLIBCXX_USE_DEPRECATED=0 (GCC 4.6 and later). +#if defined(BOOST_LIBSTDCXX11) +# if BOOST_LIBSTDCXX_VERSION < 40600 +# if !_GLIBCXX_DEPRECATED +# define BOOST_NO_AUTO_PTR +# endif +# elif !defined(_GLIBCXX_USE_DEPRECATED) || !_GLIBCXX_USE_DEPRECATED +# define BOOST_NO_AUTO_PTR +# define BOOST_NO_CXX98_BINDERS +# endif +#endif + +// C++0x headers in GCC 4.3.0 and later +// +#if (BOOST_LIBSTDCXX_VERSION < 40300) || !defined(BOOST_LIBSTDCXX11) +# define BOOST_NO_CXX11_HDR_ARRAY +# define BOOST_NO_CXX11_HDR_TUPLE +# define BOOST_NO_CXX11_HDR_UNORDERED_MAP +# define BOOST_NO_CXX11_HDR_UNORDERED_SET +# define BOOST_NO_CXX11_HDR_FUNCTIONAL +#endif + +// C++0x headers in GCC 4.4.0 and later +// +#if (BOOST_LIBSTDCXX_VERSION < 40400) || !defined(BOOST_LIBSTDCXX11) +# define BOOST_NO_CXX11_HDR_CONDITION_VARIABLE +# define BOOST_NO_CXX11_HDR_FORWARD_LIST +# define BOOST_NO_CXX11_HDR_INITIALIZER_LIST +# define BOOST_NO_CXX11_HDR_MUTEX +# define BOOST_NO_CXX11_HDR_RATIO +# define BOOST_NO_CXX11_HDR_SYSTEM_ERROR +# define BOOST_NO_CXX11_SMART_PTR +# define BOOST_NO_CXX11_HDR_EXCEPTION +#else +# define BOOST_HAS_TR1_COMPLEX_INVERSE_TRIG +# define BOOST_HAS_TR1_COMPLEX_OVERLOADS +#endif + +// C++0x features in GCC 4.5.0 and later +// +#if (BOOST_LIBSTDCXX_VERSION < 40500) || !defined(BOOST_LIBSTDCXX11) +# define BOOST_NO_CXX11_NUMERIC_LIMITS +# define BOOST_NO_CXX11_HDR_FUTURE +# define BOOST_NO_CXX11_HDR_RANDOM +#endif + +// C++0x features in GCC 4.6.0 and later +// +#if (BOOST_LIBSTDCXX_VERSION < 40600) || !defined(BOOST_LIBSTDCXX11) +# define BOOST_NO_CXX11_HDR_TYPEINDEX +# define BOOST_NO_CXX11_ADDRESSOF +# define BOOST_NO_CXX17_ITERATOR_TRAITS +#endif + +// C++0x features in GCC 4.7.0 and later +// +#if (BOOST_LIBSTDCXX_VERSION < 40700) || !defined(BOOST_LIBSTDCXX11) +// Note that although existed prior to 4.7, "steady_clock" is spelled "monotonic_clock" +// so 4.7.0 is the first truly conforming one. +# define BOOST_NO_CXX11_HDR_CHRONO +# define BOOST_NO_CXX11_ALLOCATOR +# define BOOST_NO_CXX11_POINTER_TRAITS +#endif +// C++0x features in GCC 4.8.0 and later +// +#if (BOOST_LIBSTDCXX_VERSION < 40800) || !defined(BOOST_LIBSTDCXX11) +// Note that although existed prior to gcc 4.8 it was largely unimplemented for many types: +# define BOOST_NO_CXX11_HDR_ATOMIC +# define BOOST_NO_CXX11_HDR_THREAD +#endif +// C++0x features in GCC 4.9.0 and later +// +#if (BOOST_LIBSTDCXX_VERSION < 40900) || !defined(BOOST_LIBSTDCXX11) +// Although is present and compilable against, the actual implementation is not functional +// even for the simplest patterns such as "\d" or "[0-9]". This is the case at least in gcc up to 4.8, inclusively. +# define BOOST_NO_CXX11_HDR_REGEX +#endif +#if (BOOST_LIBSTDCXX_VERSION < 40900) || (__cplusplus <= 201103) +# define BOOST_NO_CXX14_STD_EXCHANGE +#endif + +// +// C++0x features in GCC 5.1 and later +// +#if (BOOST_LIBSTDCXX_VERSION < 50100) || !defined(BOOST_LIBSTDCXX11) +# define BOOST_NO_CXX11_HDR_TYPE_TRAITS +# define BOOST_NO_CXX11_HDR_CODECVT +# define BOOST_NO_CXX11_ATOMIC_SMART_PTR +# define BOOST_NO_CXX11_STD_ALIGN +#endif + +// +// C++17 features in GCC 7.1 and later +// +#if (BOOST_LIBSTDCXX_VERSION < 70100) || (__cplusplus <= 201402L) +# define BOOST_NO_CXX17_STD_INVOKE +# define BOOST_NO_CXX17_STD_APPLY +# define BOOST_NO_CXX17_HDR_OPTIONAL +# define BOOST_NO_CXX17_HDR_STRING_VIEW +# define BOOST_NO_CXX17_HDR_VARIANT +#endif + +#if defined(__has_include) +#if !__has_include() +# define BOOST_NO_CXX14_HDR_SHARED_MUTEX +#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) +#define BOOST_NO_CXX11_HDR_FUTURE +#define BOOST_NO_CXX11_HDR_FORWARD_LIST +#define BOOST_NO_CXX11_HDR_ATOMIC +// shared_ptr is present, but is not convertible to bool +// which causes all kinds of problems especially in Boost.Thread +// but probably elsewhere as well. +#define BOOST_NO_CXX11_SMART_PTR +#endif + +#if (!defined(_GLIBCXX_HAS_GTHREADS) || !defined(_GLIBCXX_USE_C99_STDINT_TR1)) + // Headers not always available: +# ifndef BOOST_NO_CXX11_HDR_CONDITION_VARIABLE +# define BOOST_NO_CXX11_HDR_CONDITION_VARIABLE +# endif +# ifndef BOOST_NO_CXX11_HDR_MUTEX +# define BOOST_NO_CXX11_HDR_MUTEX +# endif +# ifndef BOOST_NO_CXX11_HDR_THREAD +# define BOOST_NO_CXX11_HDR_THREAD +# endif +# ifndef BOOST_NO_CXX14_HDR_SHARED_MUTEX +# define BOOST_NO_CXX14_HDR_SHARED_MUTEX +# endif +#endif + +#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 + +// --- end --- diff --git a/third_party/boost/libs/config/include/boost/config/stdlib/modena.hpp b/third_party/boost/libs/config/include/boost/config/stdlib/modena.hpp new file mode 100644 index 00000000000..31a26c856a2 --- /dev/null +++ b/third_party/boost/libs/config/include/boost/config/stdlib/modena.hpp @@ -0,0 +1,79 @@ +// (C) Copyright Jens Maurer 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. + +// Modena C++ standard library (comes with KAI C++) + +#if !defined(MSIPL_COMPILE_H) +# include +# if !defined(__MSIPL_COMPILE_H) +# error "This is not the Modena C++ library!" +# endif +#endif + +#ifndef MSIPL_NL_TYPES +#define BOOST_NO_STD_MESSAGES +#endif + +#ifndef MSIPL_WCHART +#define BOOST_NO_STD_WSTRING +#endif + +// C++0x headers not yet implemented +// +# define BOOST_NO_CXX11_HDR_ARRAY +# define BOOST_NO_CXX11_HDR_CHRONO +# define BOOST_NO_CXX11_HDR_CODECVT +# define BOOST_NO_CXX11_HDR_CONDITION_VARIABLE +# define BOOST_NO_CXX11_HDR_FORWARD_LIST +# define BOOST_NO_CXX11_HDR_FUTURE +# define BOOST_NO_CXX11_HDR_INITIALIZER_LIST +# define BOOST_NO_CXX11_HDR_MUTEX +# define BOOST_NO_CXX11_HDR_RANDOM +# define BOOST_NO_CXX11_HDR_RATIO +# define BOOST_NO_CXX11_HDR_REGEX +# define BOOST_NO_CXX11_HDR_SYSTEM_ERROR +# define BOOST_NO_CXX11_HDR_THREAD +# define BOOST_NO_CXX11_HDR_TUPLE +# define BOOST_NO_CXX11_HDR_TYPE_TRAITS +# define BOOST_NO_CXX11_HDR_TYPEINDEX +# define BOOST_NO_CXX11_HDR_UNORDERED_MAP +# define BOOST_NO_CXX11_HDR_UNORDERED_SET +# define BOOST_NO_CXX11_NUMERIC_LIMITS +# define BOOST_NO_CXX11_ALLOCATOR +# define BOOST_NO_CXX11_POINTER_TRAITS +# define BOOST_NO_CXX11_ATOMIC_SMART_PTR +# define BOOST_NO_CXX11_SMART_PTR +# define BOOST_NO_CXX11_HDR_FUNCTIONAL +# define BOOST_NO_CXX11_HDR_ATOMIC +# define BOOST_NO_CXX11_STD_ALIGN +# define BOOST_NO_CXX11_ADDRESSOF +# define BOOST_NO_CXX11_HDR_EXCEPTION + +#if defined(__has_include) +#if !__has_include() +# define BOOST_NO_CXX14_HDR_SHARED_MUTEX +#elif __cplusplus < 201402 +# define BOOST_NO_CXX14_HDR_SHARED_MUTEX +#endif +#else +# define BOOST_NO_CXX14_HDR_SHARED_MUTEX +#endif + +// C++14 features +# define BOOST_NO_CXX14_STD_EXCHANGE + +// C++17 features +# define BOOST_NO_CXX17_STD_APPLY +# define BOOST_NO_CXX17_STD_INVOKE +# define BOOST_NO_CXX17_ITERATOR_TRAITS + +#define BOOST_STDLIB "Modena C++ standard library" + + + + + diff --git a/third_party/boost/libs/config/include/boost/config/stdlib/msl.hpp b/third_party/boost/libs/config/include/boost/config/stdlib/msl.hpp new file mode 100644 index 00000000000..f2f825983be --- /dev/null +++ b/third_party/boost/libs/config/include/boost/config/stdlib/msl.hpp @@ -0,0 +1,98 @@ +// (C) Copyright John Maddock 2001. +// (C) Copyright Darin Adler 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. + +// Metrowerks standard library: + +#ifndef __MSL_CPP__ +# include +# ifndef __MSL_CPP__ +# error This is not the MSL standard library! +# endif +#endif + +#if __MSL_CPP__ >= 0x6000 // Pro 6 +# define BOOST_HAS_HASH +# define BOOST_STD_EXTENSION_NAMESPACE Metrowerks +#endif +#define BOOST_HAS_SLIST + +#if __MSL_CPP__ < 0x6209 +# define BOOST_NO_STD_MESSAGES +#endif + +// check C lib version for +#include + +#if defined(__MSL__) && (__MSL__ >= 0x5000) +# define BOOST_HAS_STDINT_H +# if !defined(__PALMOS_TRAPS__) +# define BOOST_HAS_UNISTD_H +# endif + // boilerplate code: +# include +#endif + +#if defined(_MWMT) || _MSL_THREADSAFE +# define BOOST_HAS_THREADS +#endif + +#ifdef _MSL_NO_EXPLICIT_FUNC_TEMPLATE_ARG +# define BOOST_NO_STD_USE_FACET +# define BOOST_HAS_TWO_ARG_USE_FACET +#endif + +// C++0x headers not yet implemented +// +# define BOOST_NO_CXX11_HDR_ARRAY +# define BOOST_NO_CXX11_HDR_CHRONO +# define BOOST_NO_CXX11_HDR_CODECVT +# define BOOST_NO_CXX11_HDR_CONDITION_VARIABLE +# define BOOST_NO_CXX11_HDR_FORWARD_LIST +# define BOOST_NO_CXX11_HDR_FUTURE +# define BOOST_NO_CXX11_HDR_INITIALIZER_LIST +# define BOOST_NO_CXX11_HDR_MUTEX +# define BOOST_NO_CXX11_HDR_RANDOM +# define BOOST_NO_CXX11_HDR_RATIO +# define BOOST_NO_CXX11_HDR_REGEX +# define BOOST_NO_CXX11_HDR_SYSTEM_ERROR +# define BOOST_NO_CXX11_HDR_THREAD +# define BOOST_NO_CXX11_HDR_TUPLE +# define BOOST_NO_CXX11_HDR_TYPE_TRAITS +# define BOOST_NO_CXX11_HDR_TYPEINDEX +# define BOOST_NO_CXX11_HDR_UNORDERED_MAP +# define BOOST_NO_CXX11_HDR_UNORDERED_SET +# define BOOST_NO_CXX11_NUMERIC_LIMITS +# define BOOST_NO_CXX11_ALLOCATOR +# define BOOST_NO_CXX11_POINTER_TRAITS +# define BOOST_NO_CXX11_ATOMIC_SMART_PTR +# define BOOST_NO_CXX11_SMART_PTR +# define BOOST_NO_CXX11_HDR_FUNCTIONAL +# define BOOST_NO_CXX11_HDR_ATOMIC +# define BOOST_NO_CXX11_STD_ALIGN +# define BOOST_NO_CXX11_ADDRESSOF +# define BOOST_NO_CXX11_HDR_EXCEPTION + +#if defined(__has_include) +#if !__has_include() +# define BOOST_NO_CXX14_HDR_SHARED_MUTEX +#elif __cplusplus < 201402 +# define BOOST_NO_CXX14_HDR_SHARED_MUTEX +#endif +#else +# define BOOST_NO_CXX14_HDR_SHARED_MUTEX +#endif + +// C++14 features +# define BOOST_NO_CXX14_STD_EXCHANGE + +// C++17 features +# define BOOST_NO_CXX17_STD_APPLY +# define BOOST_NO_CXX17_STD_INVOKE +# define BOOST_NO_CXX17_ITERATOR_TRAITS + +#define BOOST_STDLIB "Metrowerks Standard Library version " BOOST_STRINGIZE(__MSL_CPP__) diff --git a/third_party/boost/libs/config/include/boost/config/stdlib/roguewave.hpp b/third_party/boost/libs/config/include/boost/config/stdlib/roguewave.hpp new file mode 100644 index 00000000000..03a65768c0e --- /dev/null +++ b/third_party/boost/libs/config/include/boost/config/stdlib/roguewave.hpp @@ -0,0 +1,208 @@ +// (C) Copyright John Maddock 2001 - 2003. +// (C) Copyright Jens Maurer 2001. +// (C) Copyright David Abrahams 2003. +// (C) Copyright Boris Gubenko 2007. +// 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. + +// Rogue Wave std lib: + +#define BOOST_RW_STDLIB 1 + +#if !defined(__STD_RWCOMPILER_H__) && !defined(_RWSTD_VER) +# include +# if !defined(__STD_RWCOMPILER_H__) && !defined(_RWSTD_VER) +# error This is not the Rogue Wave standard library +# endif +#endif +// +// figure out a consistent version number: +// +#ifndef _RWSTD_VER +# define BOOST_RWSTD_VER 0x010000 +#elif _RWSTD_VER < 0x010000 +# define BOOST_RWSTD_VER (_RWSTD_VER << 8) +#else +# define BOOST_RWSTD_VER _RWSTD_VER +#endif + +#ifndef _RWSTD_VER +# define BOOST_STDLIB "Rogue Wave standard library version (Unknown version)" +#elif _RWSTD_VER < 0x04010200 + # define BOOST_STDLIB "Rogue Wave standard library version " BOOST_STRINGIZE(_RWSTD_VER) +#else +# ifdef _RWSTD_VER_STR +# define BOOST_STDLIB "Apache STDCXX standard library version " _RWSTD_VER_STR +# else +# define BOOST_STDLIB "Apache STDCXX standard library version " BOOST_STRINGIZE(_RWSTD_VER) +# endif +#endif + +// +// Prior to version 2.2.0 the primary template for std::numeric_limits +// does not have compile time constants, even though specializations of that +// template do: +// +#if BOOST_RWSTD_VER < 0x020200 +# define BOOST_NO_LIMITS_COMPILE_TIME_CONSTANTS +#endif + +// Sun CC 5.5 patch 113817-07 adds long long specialization, but does not change the +// library version number (http://sunsolve6.sun.com/search/document.do?assetkey=1-21-113817): +#if BOOST_RWSTD_VER <= 0x020101 && (!defined(__SUNPRO_CC) || (__SUNPRO_CC < 0x550)) +# define BOOST_NO_LONG_LONG_NUMERIC_LIMITS +# endif + +// +// Borland version of numeric_limits lacks __int64 specialisation: +// +#ifdef BOOST_BORLANDC +# define BOOST_NO_MS_INT64_NUMERIC_LIMITS +#endif + +// +// No std::iterator if it can't figure out default template args: +// +#if defined(_RWSTD_NO_SIMPLE_DEFAULT_TEMPLATES) || defined(RWSTD_NO_SIMPLE_DEFAULT_TEMPLATES) || (BOOST_RWSTD_VER < 0x020000) +# define BOOST_NO_STD_ITERATOR +#endif + +// +// No iterator traits without partial specialization: +// +#if defined(_RWSTD_NO_CLASS_PARTIAL_SPEC) || defined(RWSTD_NO_CLASS_PARTIAL_SPEC) +# define BOOST_NO_STD_ITERATOR_TRAITS +#endif + +// +// Prior to version 2.0, std::auto_ptr was buggy, and there were no +// new-style iostreams, and no conformant std::allocator: +// +#if (BOOST_RWSTD_VER < 0x020000) +# define BOOST_NO_AUTO_PTR +# define BOOST_NO_STRINGSTREAM +# define BOOST_NO_STD_ALLOCATOR +# define BOOST_NO_STD_LOCALE +#endif + +// +// No template iterator constructors without member template support: +// +#if defined(RWSTD_NO_MEMBER_TEMPLATES) || defined(_RWSTD_NO_MEMBER_TEMPLATES) +# define BOOST_NO_TEMPLATED_ITERATOR_CONSTRUCTORS +#endif + +// +// RW defines _RWSTD_ALLOCATOR if the allocator is conformant and in use +// (the or _HPACC_ part is a hack - the library seems to define _RWSTD_ALLOCATOR +// on HP aCC systems even though the allocator is in fact broken): +// +#if !defined(_RWSTD_ALLOCATOR) || (defined(__HP_aCC) && __HP_aCC <= 33100) +# define BOOST_NO_STD_ALLOCATOR +#endif + +// +// If we have a std::locale, we still may not have std::use_facet: +// +#if defined(_RWSTD_NO_TEMPLATE_ON_RETURN_TYPE) && !defined(BOOST_NO_STD_LOCALE) +# define BOOST_NO_STD_USE_FACET +# define BOOST_HAS_TWO_ARG_USE_FACET +#endif + +// +// There's no std::distance prior to version 2, or without +// partial specialization support: +// +#if (BOOST_RWSTD_VER < 0x020000) || defined(_RWSTD_NO_CLASS_PARTIAL_SPEC) + #define BOOST_NO_STD_DISTANCE +#endif + +// +// Some versions of the rogue wave library don't have assignable +// OutputIterators: +// +#if BOOST_RWSTD_VER < 0x020100 +# define BOOST_NO_STD_OUTPUT_ITERATOR_ASSIGN +#endif + +// +// Disable BOOST_HAS_LONG_LONG when the library has no support for it. +// +#if !defined(_RWSTD_LONG_LONG) && defined(BOOST_HAS_LONG_LONG) +# undef BOOST_HAS_LONG_LONG +#endif + +// +// check that on HP-UX, the proper RW library is used +// +#if defined(__HP_aCC) && !defined(_HP_NAMESPACE_STD) +# error "Boost requires Standard RW library. Please compile and link with -AA" +#endif + +// +// Define macros specific to RW V2.2 on HP-UX +// +#if defined(__HP_aCC) && (BOOST_RWSTD_VER == 0x02020100) +# ifndef __HP_TC1_MAKE_PAIR +# define __HP_TC1_MAKE_PAIR +# endif +# ifndef _HP_INSTANTIATE_STD2_VL +# define _HP_INSTANTIATE_STD2_VL +# endif +#endif + +#if _RWSTD_VER < 0x05000000 +# define BOOST_NO_CXX11_HDR_ARRAY +#endif +// type_traits header is incomplete: +# define BOOST_NO_CXX11_HDR_TYPE_TRAITS +// +// C++0x headers not yet implemented +// +# define BOOST_NO_CXX11_HDR_CHRONO +# define BOOST_NO_CXX11_HDR_CODECVT +# define BOOST_NO_CXX11_HDR_CONDITION_VARIABLE +# define BOOST_NO_CXX11_HDR_FORWARD_LIST +# define BOOST_NO_CXX11_HDR_FUTURE +# define BOOST_NO_CXX11_HDR_INITIALIZER_LIST +# define BOOST_NO_CXX11_HDR_MUTEX +# define BOOST_NO_CXX11_HDR_RANDOM +# define BOOST_NO_CXX11_HDR_RATIO +# define BOOST_NO_CXX11_HDR_REGEX +# define BOOST_NO_CXX11_HDR_SYSTEM_ERROR +# define BOOST_NO_CXX11_HDR_THREAD +# define BOOST_NO_CXX11_HDR_TUPLE +# define BOOST_NO_CXX11_HDR_TYPEINDEX +# define BOOST_NO_CXX11_HDR_UNORDERED_MAP +# define BOOST_NO_CXX11_HDR_UNORDERED_SET +# define BOOST_NO_CXX11_NUMERIC_LIMITS +# define BOOST_NO_CXX11_ALLOCATOR +# define BOOST_NO_CXX11_POINTER_TRAITS +# define BOOST_NO_CXX11_ATOMIC_SMART_PTR +# define BOOST_NO_CXX11_SMART_PTR +# define BOOST_NO_CXX11_HDR_FUNCTIONAL +# define BOOST_NO_CXX11_HDR_ATOMIC +# define BOOST_NO_CXX11_STD_ALIGN +# define BOOST_NO_CXX11_ADDRESSOF +# define BOOST_NO_CXX11_HDR_EXCEPTION + +#if defined(__has_include) +#if !__has_include() +# define BOOST_NO_CXX14_HDR_SHARED_MUTEX +#elif __cplusplus < 201402 +# define BOOST_NO_CXX14_HDR_SHARED_MUTEX +#endif +#else +# define BOOST_NO_CXX14_HDR_SHARED_MUTEX +#endif + +// C++14 features +# define BOOST_NO_CXX14_STD_EXCHANGE + +// C++17 features +# define BOOST_NO_CXX17_STD_APPLY +# define BOOST_NO_CXX17_STD_INVOKE +# define BOOST_NO_CXX17_ITERATOR_TRAITS diff --git a/third_party/boost/libs/config/include/boost/config/stdlib/sgi.hpp b/third_party/boost/libs/config/include/boost/config/stdlib/sgi.hpp new file mode 100644 index 00000000000..c49957cef8b --- /dev/null +++ b/third_party/boost/libs/config/include/boost/config/stdlib/sgi.hpp @@ -0,0 +1,168 @@ +// (C) Copyright John Maddock 2001 - 2003. +// (C) Copyright Darin Adler 2001. +// (C) Copyright Jens Maurer 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. + +// generic SGI STL: + +#if !defined(__STL_CONFIG_H) +# include +# if !defined(__STL_CONFIG_H) +# error "This is not the SGI STL!" +# endif +#endif + +// +// No std::iterator traits without partial specialisation: +// +#if !defined(__STL_CLASS_PARTIAL_SPECIALIZATION) +# define BOOST_NO_STD_ITERATOR_TRAITS +#endif + +// +// No std::stringstream with gcc < 3 +// +#if defined(__GNUC__) && (__GNUC__ < 3) && \ + ((__GNUC_MINOR__ < 95) || (__GNUC_MINOR__ == 96)) && \ + !defined(__STL_USE_NEW_IOSTREAMS) || \ + defined(__APPLE_CC__) + // Note that we only set this for GNU C++ prior to 2.95 since the + // latest patches for that release do contain a minimal + // If you are running a 2.95 release prior to 2.95.3 then this will need + // setting, but there is no way to detect that automatically (other + // than by running the configure script). + // Also, the unofficial GNU C++ 2.96 included in RedHat 7.1 doesn't + // have . +# define BOOST_NO_STRINGSTREAM +#endif + +// Apple doesn't seem to reliably defined a *unix* macro +#if !defined(CYGWIN) && ( defined(__unix__) \ + || defined(__unix) \ + || defined(unix) \ + || defined(__APPLE__) \ + || defined(__APPLE) \ + || defined(APPLE)) +# include +#endif + + +// +// Assume no std::locale without own iostreams (this may be an +// incorrect assumption in some cases): +// +#if !defined(__SGI_STL_OWN_IOSTREAMS) && !defined(__STL_USE_NEW_IOSTREAMS) +# define BOOST_NO_STD_LOCALE +#endif + +// +// Original native SGI streams have non-standard std::messages facet: +// +#if defined(__sgi) && (_COMPILER_VERSION <= 650) && !defined(__SGI_STL_OWN_IOSTREAMS) +# define BOOST_NO_STD_LOCALE +#endif + +// +// SGI's new iostreams have missing "const" in messages<>::open +// +#if defined(__sgi) && (_COMPILER_VERSION <= 740) && defined(__STL_USE_NEW_IOSTREAMS) +# define BOOST_NO_STD_MESSAGES +#endif + +// +// No template iterator constructors, or std::allocator +// without member templates: +// +#if !defined(__STL_MEMBER_TEMPLATES) +# define BOOST_NO_TEMPLATED_ITERATOR_CONSTRUCTORS +# define BOOST_NO_STD_ALLOCATOR +#endif + +// +// We always have SGI style hash_set, hash_map, and slist: +// +#define BOOST_HAS_HASH +#define BOOST_HAS_SLIST + +// +// If this is GNU libstdc++2, then no and no std::wstring: +// +#if (defined(__GNUC__) && (__GNUC__ < 3)) +# include +# if defined(__BASTRING__) +# define BOOST_NO_LIMITS +// Note: will provide compile-time constants +# undef BOOST_NO_LIMITS_COMPILE_TIME_CONSTANTS +# define BOOST_NO_STD_WSTRING +# endif +#endif + +// +// There is no standard iterator unless we have namespace support: +// +#if !defined(__STL_USE_NAMESPACES) +# define BOOST_NO_STD_ITERATOR +#endif + +// +// Intrinsic type_traits support. +// The SGI STL has it's own __type_traits class, which +// has intrinsic compiler support with SGI's compilers. +// Whatever map SGI style type traits to boost equivalents: +// +#define BOOST_HAS_SGI_TYPE_TRAITS + +// C++0x headers not yet implemented +// +# define BOOST_NO_CXX11_HDR_ARRAY +# define BOOST_NO_CXX11_HDR_CHRONO +# define BOOST_NO_CXX11_HDR_CODECVT +# define BOOST_NO_CXX11_HDR_CONDITION_VARIABLE +# define BOOST_NO_CXX11_HDR_FORWARD_LIST +# define BOOST_NO_CXX11_HDR_FUTURE +# define BOOST_NO_CXX11_HDR_INITIALIZER_LIST +# define BOOST_NO_CXX11_HDR_MUTEX +# define BOOST_NO_CXX11_HDR_RANDOM +# define BOOST_NO_CXX11_HDR_RATIO +# define BOOST_NO_CXX11_HDR_REGEX +# define BOOST_NO_CXX11_HDR_SYSTEM_ERROR +# define BOOST_NO_CXX11_HDR_THREAD +# define BOOST_NO_CXX11_HDR_TUPLE +# define BOOST_NO_CXX11_HDR_TYPE_TRAITS +# define BOOST_NO_CXX11_HDR_TYPEINDEX +# define BOOST_NO_CXX11_HDR_UNORDERED_MAP +# define BOOST_NO_CXX11_HDR_UNORDERED_SET +# define BOOST_NO_CXX11_NUMERIC_LIMITS +# define BOOST_NO_CXX11_ALLOCATOR +# define BOOST_NO_CXX11_POINTER_TRAITS +# define BOOST_NO_CXX11_ATOMIC_SMART_PTR +# define BOOST_NO_CXX11_SMART_PTR +# define BOOST_NO_CXX11_HDR_FUNCTIONAL +# define BOOST_NO_CXX11_HDR_ATOMIC +# define BOOST_NO_CXX11_STD_ALIGN +# define BOOST_NO_CXX11_ADDRESSOF +# define BOOST_NO_CXX11_HDR_EXCEPTION + +#if defined(__has_include) +#if !__has_include() +# define BOOST_NO_CXX14_HDR_SHARED_MUTEX +#elif __cplusplus < 201402 +# define BOOST_NO_CXX14_HDR_SHARED_MUTEX +#endif +#else +# define BOOST_NO_CXX14_HDR_SHARED_MUTEX +#endif + +// C++14 features +# define BOOST_NO_CXX14_STD_EXCHANGE + +// C++17 features +# define BOOST_NO_CXX17_STD_APPLY +# define BOOST_NO_CXX17_STD_INVOKE +# define BOOST_NO_CXX17_ITERATOR_TRAITS + +#define BOOST_STDLIB "SGI standard library" diff --git a/third_party/boost/libs/config/include/boost/config/stdlib/stlport.hpp b/third_party/boost/libs/config/include/boost/config/stdlib/stlport.hpp new file mode 100644 index 00000000000..38bc763f95f --- /dev/null +++ b/third_party/boost/libs/config/include/boost/config/stdlib/stlport.hpp @@ -0,0 +1,258 @@ +// (C) Copyright John Maddock 2001 - 2002. +// (C) Copyright Darin Adler 2001. +// (C) Copyright Jens Maurer 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. + +// STLPort standard library config: + +#if !defined(__SGI_STL_PORT) && !defined(_STLPORT_VERSION) +# include +# if !defined(__SGI_STL_PORT) && !defined(_STLPORT_VERSION) +# error "This is not STLPort!" +# endif +#endif + +// Apple doesn't seem to reliably defined a *unix* macro +#if !defined(CYGWIN) && ( defined(__unix__) \ + || defined(__unix) \ + || defined(unix) \ + || defined(__APPLE__) \ + || defined(__APPLE) \ + || defined(APPLE)) +# include +#endif + +// +// __STL_STATIC_CONST_INIT_BUG implies BOOST_NO_LIMITS_COMPILE_TIME_CONSTANTS +// for versions prior to 4.1(beta) +// +#if (defined(__STL_STATIC_CONST_INIT_BUG) || defined(_STLP_STATIC_CONST_INIT_BUG)) && (__SGI_STL_PORT <= 0x400) +# define BOOST_NO_LIMITS_COMPILE_TIME_CONSTANTS +#endif + +// +// If STLport thinks that there is no partial specialisation, then there is no +// std::iterator traits: +// +#if !(defined(_STLP_CLASS_PARTIAL_SPECIALIZATION) || defined(__STL_CLASS_PARTIAL_SPECIALIZATION)) +# define BOOST_NO_STD_ITERATOR_TRAITS +#endif + +// +// No new style iostreams on GCC without STLport's iostreams enabled: +// +#if (defined(__GNUC__) && (__GNUC__ < 3)) && !(defined(__SGI_STL_OWN_IOSTREAMS) || defined(_STLP_OWN_IOSTREAMS)) +# define BOOST_NO_STRINGSTREAM +#endif + +// +// No new iostreams implies no std::locale, and no std::stringstream: +// +#if defined(__STL_NO_IOSTREAMS) || defined(__STL_NO_NEW_IOSTREAMS) || defined(_STLP_NO_IOSTREAMS) || defined(_STLP_NO_NEW_IOSTREAMS) +# define BOOST_NO_STD_LOCALE +# define BOOST_NO_STRINGSTREAM +#endif + +// +// If the streams are not native, and we have a "using ::x" compiler bug +// then the io stream facets are not available in namespace std:: +// +#ifdef _STLPORT_VERSION +# if !(_STLPORT_VERSION >= 0x500) && !defined(_STLP_OWN_IOSTREAMS) && defined(_STLP_USE_NAMESPACES) && defined(BOOST_NO_USING_TEMPLATE) && !defined(BOOST_BORLANDC) +# define BOOST_NO_STD_LOCALE +# endif +#else +# if !defined(__SGI_STL_OWN_IOSTREAMS) && defined(__STL_USE_NAMESPACES) && defined(BOOST_NO_USING_TEMPLATE) && !defined(BOOST_BORLANDC) +# define BOOST_NO_STD_LOCALE +# endif +#endif + +#if defined(_STLPORT_VERSION) && (_STLPORT_VERSION >= 0x520) +# define BOOST_HAS_TR1_UNORDERED_SET +# define BOOST_HAS_TR1_UNORDERED_MAP +#endif +// +// Without member template support enabled, their are no template +// iterate constructors, and no std::allocator: +// +#if !(defined(__STL_MEMBER_TEMPLATES) || defined(_STLP_MEMBER_TEMPLATES)) +# define BOOST_NO_TEMPLATED_ITERATOR_CONSTRUCTORS +# define BOOST_NO_STD_ALLOCATOR +#endif +// +// however we always have at least a partial allocator: +// +#define BOOST_HAS_PARTIAL_STD_ALLOCATOR + +#if !defined(_STLP_MEMBER_TEMPLATE_CLASSES) || defined(_STLP_DONT_SUPPORT_REBIND_MEMBER_TEMPLATE) +# define BOOST_NO_STD_ALLOCATOR +#endif + +#if defined(_STLP_NO_MEMBER_TEMPLATE_KEYWORD) && defined(BOOST_MSVC) && (BOOST_MSVC <= 1300) +# define BOOST_NO_STD_ALLOCATOR +#endif + +// +// If STLport thinks there is no wchar_t at all, then we have to disable +// the support for the relevant specilazations of std:: templates. +// +#if !defined(_STLP_HAS_WCHAR_T) && !defined(_STLP_WCHAR_T_IS_USHORT) +# ifndef BOOST_NO_STD_WSTRING +# define BOOST_NO_STD_WSTRING +# endif +# ifndef BOOST_NO_STD_WSTREAMBUF +# define BOOST_NO_STD_WSTREAMBUF +# endif +#endif + +// +// We always have SGI style hash_set, hash_map, and slist: +// +#ifndef _STLP_NO_EXTENSIONS +#define BOOST_HAS_HASH +#define BOOST_HAS_SLIST +#endif + +// +// STLport does a good job of importing names into namespace std::, +// but doesn't always get them all, define BOOST_NO_STDC_NAMESPACE, since our +// workaround does not conflict with STLports: +// +// +// Harold Howe says: +// Borland switched to STLport in BCB6. Defining BOOST_NO_STDC_NAMESPACE with +// BCB6 does cause problems. If we detect C++ Builder, then don't define +// BOOST_NO_STDC_NAMESPACE +// +#if !defined(BOOST_BORLANDC) && !defined(__DMC__) +// +// If STLport is using it's own namespace, and the real names are in +// the global namespace, then we duplicate STLport's using declarations +// (by defining BOOST_NO_STDC_NAMESPACE), we do this because STLport doesn't +// necessarily import all the names we need into namespace std:: +// +# if (defined(__STL_IMPORT_VENDOR_CSTD) \ + || defined(__STL_USE_OWN_NAMESPACE) \ + || defined(_STLP_IMPORT_VENDOR_CSTD) \ + || defined(_STLP_USE_OWN_NAMESPACE)) \ + && (defined(__STL_VENDOR_GLOBAL_CSTD) || defined (_STLP_VENDOR_GLOBAL_CSTD)) +# define BOOST_NO_STDC_NAMESPACE +# define BOOST_NO_EXCEPTION_STD_NAMESPACE +# endif +#elif defined(BOOST_BORLANDC) && BOOST_BORLANDC < 0x560 +// STLport doesn't import std::abs correctly: +#include +namespace std { using ::abs; } +// and strcmp/strcpy don't get imported either ('cos they are macros) +#include +#ifdef strcpy +# undef strcpy +#endif +#ifdef strcmp +# undef strcmp +#endif +#ifdef _STLP_VENDOR_CSTD +namespace std{ using _STLP_VENDOR_CSTD::strcmp; using _STLP_VENDOR_CSTD::strcpy; } +#endif +#endif + +// +// std::use_facet may be non-standard, uses a class instead: +// +#if defined(__STL_NO_EXPLICIT_FUNCTION_TMPL_ARGS) || defined(_STLP_NO_EXPLICIT_FUNCTION_TMPL_ARGS) +# define BOOST_NO_STD_USE_FACET +# define BOOST_HAS_STLP_USE_FACET +#endif + +// +// If STLport thinks there are no wide functions, etc. is not working; but +// only if BOOST_NO_STDC_NAMESPACE is not defined (if it is then we do the import +// into std:: ourselves). +// +#if defined(_STLP_NO_NATIVE_WIDE_FUNCTIONS) && !defined(BOOST_NO_STDC_NAMESPACE) +# define BOOST_NO_CWCHAR +# define BOOST_NO_CWCTYPE +#endif + +// +// If STLport for some reason was configured so that it thinks that wchar_t +// is not an intrinsic type, then we have to disable the support for it as +// well (we would be missing required specializations otherwise). +// +#if !defined( _STLP_HAS_WCHAR_T) || defined(_STLP_WCHAR_T_IS_USHORT) +# undef BOOST_NO_INTRINSIC_WCHAR_T +# define BOOST_NO_INTRINSIC_WCHAR_T +#endif + +// +// Borland ships a version of STLport with C++ Builder 6 that lacks +// hashtables and the like: +// +#if defined(BOOST_BORLANDC) && (BOOST_BORLANDC == 0x560) +# undef BOOST_HAS_HASH +#endif + +// +// gcc-2.95.3/STLPort does not like the using declarations we use to get ADL with std::min/max +// +#if defined(__GNUC__) && (__GNUC__ < 3) +# include // for std::min and std::max +# define BOOST_USING_STD_MIN() ((void)0) +# define BOOST_USING_STD_MAX() ((void)0) +namespace boost { using std::min; using std::max; } +#endif + +// C++0x headers not yet implemented +// +# define BOOST_NO_CXX11_HDR_ARRAY +# define BOOST_NO_CXX11_HDR_CHRONO +# define BOOST_NO_CXX11_HDR_CODECVT +# define BOOST_NO_CXX11_HDR_CONDITION_VARIABLE +# define BOOST_NO_CXX11_HDR_FORWARD_LIST +# define BOOST_NO_CXX11_HDR_FUTURE +# define BOOST_NO_CXX11_HDR_INITIALIZER_LIST +# define BOOST_NO_CXX11_HDR_MUTEX +# define BOOST_NO_CXX11_HDR_RANDOM +# define BOOST_NO_CXX11_HDR_RATIO +# define BOOST_NO_CXX11_HDR_REGEX +# define BOOST_NO_CXX11_HDR_SYSTEM_ERROR +# define BOOST_NO_CXX11_HDR_THREAD +# define BOOST_NO_CXX11_HDR_TUPLE +# define BOOST_NO_CXX11_HDR_TYPE_TRAITS +# define BOOST_NO_CXX11_HDR_TYPEINDEX +# define BOOST_NO_CXX11_HDR_UNORDERED_MAP +# define BOOST_NO_CXX11_HDR_UNORDERED_SET +# define BOOST_NO_CXX11_NUMERIC_LIMITS +# define BOOST_NO_CXX11_ALLOCATOR +# define BOOST_NO_CXX11_POINTER_TRAITS +# define BOOST_NO_CXX11_ATOMIC_SMART_PTR +# define BOOST_NO_CXX11_SMART_PTR +# define BOOST_NO_CXX11_HDR_FUNCTIONAL +# define BOOST_NO_CXX11_HDR_ATOMIC +# define BOOST_NO_CXX11_STD_ALIGN +# define BOOST_NO_CXX11_ADDRESSOF +# define BOOST_NO_CXX11_HDR_EXCEPTION + +#if defined(__has_include) +#if !__has_include() +# define BOOST_NO_CXX14_HDR_SHARED_MUTEX +#elif __cplusplus < 201402 +# define BOOST_NO_CXX14_HDR_SHARED_MUTEX +#endif +#else +# define BOOST_NO_CXX14_HDR_SHARED_MUTEX +#endif + +// C++14 features +# define BOOST_NO_CXX14_STD_EXCHANGE + +// C++17 features +# define BOOST_NO_CXX17_STD_APPLY +# define BOOST_NO_CXX17_STD_INVOKE +# define BOOST_NO_CXX17_ITERATOR_TRAITS + +#define BOOST_STDLIB "STLPort standard library version " BOOST_STRINGIZE(__SGI_STL_PORT) diff --git a/third_party/boost/libs/config/include/boost/config/stdlib/vacpp.hpp b/third_party/boost/libs/config/include/boost/config/stdlib/vacpp.hpp new file mode 100644 index 00000000000..b14dd65576e --- /dev/null +++ b/third_party/boost/libs/config/include/boost/config/stdlib/vacpp.hpp @@ -0,0 +1,74 @@ +// (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. + +#if __IBMCPP__ <= 501 +# define BOOST_NO_STD_ALLOCATOR +#endif + +#define BOOST_HAS_MACRO_USE_FACET +#define BOOST_NO_STD_MESSAGES + +// Apple doesn't seem to reliably defined a *unix* macro +#if !defined(CYGWIN) && ( defined(__unix__) \ + || defined(__unix) \ + || defined(unix) \ + || defined(__APPLE__) \ + || defined(__APPLE) \ + || defined(APPLE)) +# include +#endif + +// C++0x headers not yet implemented +// +# define BOOST_NO_CXX11_HDR_ARRAY +# define BOOST_NO_CXX11_HDR_CHRONO +# define BOOST_NO_CXX11_HDR_CODECVT +# define BOOST_NO_CXX11_HDR_CONDITION_VARIABLE +# define BOOST_NO_CXX11_HDR_FORWARD_LIST +# define BOOST_NO_CXX11_HDR_FUTURE +# define BOOST_NO_CXX11_HDR_INITIALIZER_LIST +# define BOOST_NO_CXX11_HDR_MUTEX +# define BOOST_NO_CXX11_HDR_RANDOM +# define BOOST_NO_CXX11_HDR_RATIO +# define BOOST_NO_CXX11_HDR_REGEX +# define BOOST_NO_CXX11_HDR_SYSTEM_ERROR +# define BOOST_NO_CXX11_HDR_THREAD +# define BOOST_NO_CXX11_HDR_TUPLE +# define BOOST_NO_CXX11_HDR_TYPE_TRAITS +# define BOOST_NO_CXX11_HDR_TYPEINDEX +# define BOOST_NO_CXX11_HDR_UNORDERED_MAP +# define BOOST_NO_CXX11_HDR_UNORDERED_SET +# define BOOST_NO_CXX11_NUMERIC_LIMITS +# define BOOST_NO_CXX11_ALLOCATOR +# define BOOST_NO_CXX11_POINTER_TRAITS +# define BOOST_NO_CXX11_ATOMIC_SMART_PTR +# define BOOST_NO_CXX11_SMART_PTR +# define BOOST_NO_CXX11_HDR_FUNCTIONAL +# define BOOST_NO_CXX11_HDR_ATOMIC +# define BOOST_NO_CXX11_STD_ALIGN +# define BOOST_NO_CXX11_ADDRESSOF +# define BOOST_NO_CXX11_HDR_EXCEPTION + +#if defined(__has_include) +#if !__has_include() +# define BOOST_NO_CXX14_HDR_SHARED_MUTEX +#elif __cplusplus < 201402 +# define BOOST_NO_CXX14_HDR_SHARED_MUTEX +#endif +#else +# define BOOST_NO_CXX14_HDR_SHARED_MUTEX +#endif + +// C++14 features +# define BOOST_NO_CXX14_STD_EXCHANGE + +// C++17 features +# define BOOST_NO_CXX17_STD_APPLY +# define BOOST_NO_CXX17_STD_INVOKE +# define BOOST_NO_CXX17_ITERATOR_TRAITS + +#define BOOST_STDLIB "Visual Age default standard library" diff --git a/third_party/boost/libs/config/include/boost/config/stdlib/xlcpp_zos.hpp b/third_party/boost/libs/config/include/boost/config/stdlib/xlcpp_zos.hpp new file mode 100644 index 00000000000..a5e02fd8b83 --- /dev/null +++ b/third_party/boost/libs/config/include/boost/config/stdlib/xlcpp_zos.hpp @@ -0,0 +1,61 @@ +// 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. + +// Standard library setup for IBM z/OS XL C/C++ compiler. + +// Oldest library version currently supported is 2.1 (V2R1) +#if __TARGET_LIB__ < 0x42010000 +# error "Library version not supported or configured - please reconfigure" +#endif + +#if __TARGET_LIB__ > 0x42010000 +# if defined(BOOST_ASSERT_CONFIG) +# error "Unknown library version - please run the configure tests and report the results" +# endif +#endif + +#define BOOST_STDLIB "IBM z/OS XL C/C++ standard library" + +#define BOOST_HAS_MACRO_USE_FACET + +#define BOOST_NO_CXX11_HDR_TYPE_TRAITS +#define BOOST_NO_CXX11_HDR_INITIALIZER_LIST + +#define BOOST_NO_CXX11_ADDRESSOF +#define BOOST_NO_CXX11_SMART_PTR +#define BOOST_NO_CXX11_ATOMIC_SMART_PTR +#define BOOST_NO_CXX11_NUMERIC_LIMITS +#define BOOST_NO_CXX11_ALLOCATOR +#define BOOST_NO_CXX11_POINTER_TRAITS +#define BOOST_NO_CXX11_HDR_FUNCTIONAL +#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_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_HDR_ATOMIC +#define BOOST_NO_CXX11_HDR_ARRAY +#define BOOST_NO_CXX11_HDR_EXCEPTION +#define BOOST_NO_CXX11_STD_ALIGN + +#define BOOST_NO_CXX14_STD_EXCHANGE +#define BOOST_NO_CXX14_HDR_SHARED_MUTEX + +#define BOOST_NO_CXX17_STD_INVOKE +#define BOOST_NO_CXX17_STD_APPLY +#define BOOST_NO_CXX17_ITERATOR_TRAITS diff --git a/third_party/boost/libs/config/include/boost/config/user.hpp b/third_party/boost/libs/config/include/boost/config/user.hpp new file mode 100644 index 00000000000..8160fcae25c --- /dev/null +++ b/third_party/boost/libs/config/include/boost/config/user.hpp @@ -0,0 +1,133 @@ +// boost/config/user.hpp ---------------------------------------------------// + +// (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) + +// Do not check in modified versions of this file, +// This file may be customized by the end user, but not by boost. + +// +// Use this file to define a site and compiler specific +// configuration policy: +// + +// define this to locate a compiler config file: +// #define BOOST_COMPILER_CONFIG + +// define this to locate a stdlib config file: +// #define BOOST_STDLIB_CONFIG + +// define this to locate a platform config file: +// #define BOOST_PLATFORM_CONFIG + +// define this to disable compiler config, +// use if your compiler config has nothing to set: +// #define BOOST_NO_COMPILER_CONFIG + +// define this to disable stdlib config, +// use if your stdlib config has nothing to set: +// #define BOOST_NO_STDLIB_CONFIG + +// define this to disable platform config, +// use if your platform config has nothing to set: +// #define BOOST_NO_PLATFORM_CONFIG + +// define this to disable all config options, +// excluding the user config. Use if your +// setup is fully ISO compliant, and has no +// useful extensions, or for autoconf generated +// setups: +// #define BOOST_NO_CONFIG + +// define this to make the config "optimistic" +// about unknown compiler versions. Normally +// unknown compiler versions are assumed to have +// all the defects of the last known version, however +// setting this flag, causes the config to assume +// that unknown compiler versions are fully conformant +// with the standard: +// #define BOOST_STRICT_CONFIG + +// define this to cause the config to halt compilation +// with an #error if it encounters anything unknown -- +// either an unknown compiler version or an unknown +// compiler/platform/library: +// #define BOOST_ASSERT_CONFIG + + +// define if you want to disable threading support, even +// when available: +// #define BOOST_DISABLE_THREADS + +// define when you want to disable Win32 specific features +// even when available: +// #define BOOST_DISABLE_WIN32 + +// BOOST_DISABLE_ABI_HEADERS: Stops boost headers from including any +// prefix/suffix headers that normally control things like struct +// packing and alignment. +// #define BOOST_DISABLE_ABI_HEADERS + +// BOOST_ABI_PREFIX: A prefix header to include in place of whatever +// boost.config would normally select, any replacement should set up +// struct packing and alignment options as required. +// #define BOOST_ABI_PREFIX my-header-name + +// BOOST_ABI_SUFFIX: A suffix header to include in place of whatever +// boost.config would normally select, any replacement should undo +// the effects of the prefix header. +// #define BOOST_ABI_SUFFIX my-header-name + +// BOOST_ALL_DYN_LINK: Forces all libraries that have separate source, +// to be linked as dll's rather than static libraries on Microsoft Windows +// (this macro is used to turn on __declspec(dllimport) modifiers, so that +// the compiler knows which symbols to look for in a dll rather than in a +// static library). Note that there may be some libraries that can only +// be linked in one way (statically or dynamically), in these cases this +// macro has no effect. +// #define BOOST_ALL_DYN_LINK + +// BOOST_WHATEVER_DYN_LINK: Forces library "whatever" to be linked as a dll +// rather than a static library on Microsoft Windows: replace the WHATEVER +// part of the macro name with the name of the library that you want to +// dynamically link to, for example use BOOST_DATE_TIME_DYN_LINK or +// BOOST_REGEX_DYN_LINK etc (this macro is used to turn on __declspec(dllimport) +// modifiers, so that the compiler knows which symbols to look for in a dll +// rather than in a static library). +// Note that there may be some libraries that can only +// be linked in one way (statically or dynamically), +// in these cases this macro is unsupported. +// #define BOOST_WHATEVER_DYN_LINK + +// BOOST_ALL_NO_LIB: Tells the config system not to automatically select +// which libraries to link against. +// Normally if a compiler supports #pragma lib, then the correct library +// build variant will be automatically selected and linked against, +// simply by the act of including one of that library's headers. +// This macro turns that feature off. +// #define BOOST_ALL_NO_LIB + +// BOOST_WHATEVER_NO_LIB: Tells the config system not to automatically +// select which library to link against for library "whatever", +// replace WHATEVER in the macro name with the name of the library; +// for example BOOST_DATE_TIME_NO_LIB or BOOST_REGEX_NO_LIB. +// Normally if a compiler supports #pragma lib, then the correct library +// build variant will be automatically selected and linked against, simply +// by the act of including one of that library's headers. This macro turns +// that feature off. +// #define BOOST_WHATEVER_NO_LIB + +// BOOST_LIB_BUILDID: Set to the same value as the value passed to Boost.Build's +// --buildid command line option. For example if you built using: +// +// bjam address-model=64 --buildid=amd64 +// +// then compile your code with: +// +// -DBOOST_LIB_BUILDID = amd64 +// +// to ensure the correct libraries are selected at link time. +// #define BOOST_LIB_BUILDID amd64 + diff --git a/third_party/boost/libs/config/include/boost/config/warning_disable.hpp b/third_party/boost/libs/config/include/boost/config/warning_disable.hpp new file mode 100644 index 00000000000..fea8e829f14 --- /dev/null +++ b/third_party/boost/libs/config/include/boost/config/warning_disable.hpp @@ -0,0 +1,47 @@ +// Copyright John Maddock 2008 +// Use, modification, and distribution is 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) +// +// This file exists to turn off some overly-pedantic warning emitted +// by certain compilers. You should include this header only in: +// +// * A test case, before any other headers, or, +// * A library source file before any other headers. +// +// IT SHOULD NOT BE INCLUDED BY ANY BOOST HEADER. +// +// YOU SHOULD NOT INCLUDE IT IF YOU CAN REASONABLY FIX THE WARNING. +// +// The only warnings disabled here are those that are: +// +// * Quite unreasonably pedantic. +// * Generally only emitted by a single compiler. +// * Can't easily be fixed: for example if the vendors own std lib +// code emits these warnings! +// +// Note that THIS HEADER MUST NOT INCLUDE ANY OTHER HEADERS: +// not even std library ones! Doing so may turn the warning +// off too late to be of any use. For example the VC++ C4996 +// warning can be emitted from if that header is included +// before or by this one :-( +// + +#ifndef BOOST_CONFIG_WARNING_DISABLE_HPP +#define BOOST_CONFIG_WARNING_DISABLE_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1400) + // Error 'function': was declared deprecated + // http://msdn2.microsoft.com/en-us/library/ttcz0bys(VS.80).aspx + // This error is emitted when you use some perfectly conforming + // std lib functions in a perfectly correct way, and also by + // some of Microsoft's own std lib code ! +# pragma warning(disable:4996) +#endif +#if defined(__INTEL_COMPILER) || defined(__ICL) + // As above: gives warning when a "deprecated" + // std library function is encountered. +# pragma warning(disable:1786) +#endif + +#endif // BOOST_CONFIG_WARNING_DISABLE_HPP diff --git a/third_party/boost/libs/config/include/boost/config/workaround.hpp b/third_party/boost/libs/config/include/boost/config/workaround.hpp new file mode 100644 index 00000000000..688f9636609 --- /dev/null +++ b/third_party/boost/libs/config/include/boost/config/workaround.hpp @@ -0,0 +1,305 @@ +// Copyright David Abrahams 2002. +// 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_CONFIG_WORKAROUND_HPP +#define BOOST_CONFIG_WORKAROUND_HPP + +// Compiler/library version workaround macro +// +// Usage: +// +// #if BOOST_WORKAROUND(BOOST_MSVC, < 1300) +// // workaround for eVC4 and VC6 +// ... // workaround code here +// #endif +// +// When BOOST_STRICT_CONFIG is defined, expands to 0. Otherwise, the +// first argument must be undefined or expand to a numeric +// value. The above expands to: +// +// (BOOST_MSVC) != 0 && (BOOST_MSVC) < 1300 +// +// When used for workarounds that apply to the latest known version +// and all earlier versions of a compiler, the following convention +// should be observed: +// +// #if BOOST_WORKAROUND(BOOST_MSVC, BOOST_TESTED_AT(1301)) +// +// The version number in this case corresponds to the last version in +// which the workaround was known to have been required. When +// BOOST_DETECT_OUTDATED_WORKAROUNDS is not the defined, the macro +// BOOST_TESTED_AT(x) expands to "!= 0", which effectively activates +// the workaround for any version of the compiler. When +// BOOST_DETECT_OUTDATED_WORKAROUNDS is defined, a compiler warning or +// error will be issued if the compiler version exceeds the argument +// to BOOST_TESTED_AT(). This can be used to locate workarounds which +// may be obsoleted by newer versions. + +#ifndef BOOST_STRICT_CONFIG + +#include + +#ifndef __BORLANDC__ +#define __BORLANDC___WORKAROUND_GUARD 1 +#else +#define __BORLANDC___WORKAROUND_GUARD 0 +#endif +#ifndef __CODEGEARC__ +#define __CODEGEARC___WORKAROUND_GUARD 1 +#else +#define __CODEGEARC___WORKAROUND_GUARD 0 +#endif +#ifndef BOOST_BORLANDC +#define BOOST_BORLANDC_WORKAROUND_GUARD 1 +#else +#define BOOST_BORLANDC_WORKAROUND_GUARD 0 +#endif +#ifndef BOOST_CODEGEARC +#define BOOST_CODEGEARC_WORKAROUND_GUARD 1 +#else +#define BOOST_CODEGEARC_WORKAROUND_GUARD 0 +#endif +#ifndef BOOST_EMBTC +#define BOOST_EMBTC_WORKAROUND_GUARD 1 +#else +#define BOOST_EMBTC_WORKAROUND_GUARD 0 +#endif +#ifndef _MSC_VER +#define _MSC_VER_WORKAROUND_GUARD 1 +#else +#define _MSC_VER_WORKAROUND_GUARD 0 +#endif +#ifndef _MSC_FULL_VER +#define _MSC_FULL_VER_WORKAROUND_GUARD 1 +#else +#define _MSC_FULL_VER_WORKAROUND_GUARD 0 +#endif +#ifndef BOOST_MSVC +#define BOOST_MSVC_WORKAROUND_GUARD 1 +#else +#define BOOST_MSVC_WORKAROUND_GUARD 0 +#endif +#ifndef BOOST_MSVC_FULL_VER +#define BOOST_MSVC_FULL_VER_WORKAROUND_GUARD 1 +#else +#define BOOST_MSVC_FULL_VER_WORKAROUND_GUARD 0 +#endif +#ifndef __GNUC__ +#define __GNUC___WORKAROUND_GUARD 1 +#else +#define __GNUC___WORKAROUND_GUARD 0 +#endif +#ifndef __GNUC_MINOR__ +#define __GNUC_MINOR___WORKAROUND_GUARD 1 +#else +#define __GNUC_MINOR___WORKAROUND_GUARD 0 +#endif +#ifndef __GNUC_PATCHLEVEL__ +#define __GNUC_PATCHLEVEL___WORKAROUND_GUARD 1 +#else +#define __GNUC_PATCHLEVEL___WORKAROUND_GUARD 0 +#endif +#ifndef BOOST_GCC +#define BOOST_GCC_WORKAROUND_GUARD 1 +#define BOOST_GCC_VERSION_WORKAROUND_GUARD 1 +#else +#define BOOST_GCC_WORKAROUND_GUARD 0 +#define BOOST_GCC_VERSION_WORKAROUND_GUARD 0 +#endif +#ifndef BOOST_XLCPP_ZOS +#define BOOST_XLCPP_ZOS_WORKAROUND_GUARD 1 +#else +#define BOOST_XLCPP_ZOS_WORKAROUND_GUARD 0 +#endif +#ifndef __IBMCPP__ +#define __IBMCPP___WORKAROUND_GUARD 1 +#else +#define __IBMCPP___WORKAROUND_GUARD 0 +#endif +#ifndef __SUNPRO_CC +#define __SUNPRO_CC_WORKAROUND_GUARD 1 +#else +#define __SUNPRO_CC_WORKAROUND_GUARD 0 +#endif +#ifndef __DECCXX_VER +#define __DECCXX_VER_WORKAROUND_GUARD 1 +#else +#define __DECCXX_VER_WORKAROUND_GUARD 0 +#endif +#ifndef __MWERKS__ +#define __MWERKS___WORKAROUND_GUARD 1 +#else +#define __MWERKS___WORKAROUND_GUARD 0 +#endif +#ifndef __EDG__ +#define __EDG___WORKAROUND_GUARD 1 +#else +#define __EDG___WORKAROUND_GUARD 0 +#endif +#ifndef __EDG_VERSION__ +#define __EDG_VERSION___WORKAROUND_GUARD 1 +#else +#define __EDG_VERSION___WORKAROUND_GUARD 0 +#endif +#ifndef __HP_aCC +#define __HP_aCC_WORKAROUND_GUARD 1 +#else +#define __HP_aCC_WORKAROUND_GUARD 0 +#endif +#ifndef __hpxstd98 +#define __hpxstd98_WORKAROUND_GUARD 1 +#else +#define __hpxstd98_WORKAROUND_GUARD 0 +#endif +#ifndef _CRAYC +#define _CRAYC_WORKAROUND_GUARD 1 +#else +#define _CRAYC_WORKAROUND_GUARD 0 +#endif +#ifndef __DMC__ +#define __DMC___WORKAROUND_GUARD 1 +#else +#define __DMC___WORKAROUND_GUARD 0 +#endif +#ifndef MPW_CPLUS +#define MPW_CPLUS_WORKAROUND_GUARD 1 +#else +#define MPW_CPLUS_WORKAROUND_GUARD 0 +#endif +#ifndef __COMO__ +#define __COMO___WORKAROUND_GUARD 1 +#else +#define __COMO___WORKAROUND_GUARD 0 +#endif +#ifndef __COMO_VERSION__ +#define __COMO_VERSION___WORKAROUND_GUARD 1 +#else +#define __COMO_VERSION___WORKAROUND_GUARD 0 +#endif +#ifndef __INTEL_COMPILER +#define __INTEL_COMPILER_WORKAROUND_GUARD 1 +#else +#define __INTEL_COMPILER_WORKAROUND_GUARD 0 +#endif +#ifndef __ICL +#define __ICL_WORKAROUND_GUARD 1 +#else +#define __ICL_WORKAROUND_GUARD 0 +#endif +#ifndef _COMPILER_VERSION +#define _COMPILER_VERSION_WORKAROUND_GUARD 1 +#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 +#else +#define _RWSTD_VER_WORKAROUND_GUARD 0 +#endif +#ifndef BOOST_RWSTD_VER +#define BOOST_RWSTD_VER_WORKAROUND_GUARD 1 +#else +#define BOOST_RWSTD_VER_WORKAROUND_GUARD 0 +#endif +#ifndef __GLIBCPP__ +#define __GLIBCPP___WORKAROUND_GUARD 1 +#else +#define __GLIBCPP___WORKAROUND_GUARD 0 +#endif +#ifndef _GLIBCXX_USE_C99_FP_MACROS_DYNAMIC +#define _GLIBCXX_USE_C99_FP_MACROS_DYNAMIC_WORKAROUND_GUARD 1 +#else +#define _GLIBCXX_USE_C99_FP_MACROS_DYNAMIC_WORKAROUND_GUARD 0 +#endif +#ifndef __SGI_STL_PORT +#define __SGI_STL_PORT_WORKAROUND_GUARD 1 +#else +#define __SGI_STL_PORT_WORKAROUND_GUARD 0 +#endif +#ifndef _STLPORT_VERSION +#define _STLPORT_VERSION_WORKAROUND_GUARD 1 +#else +#define _STLPORT_VERSION_WORKAROUND_GUARD 0 +#endif +#ifndef __LIBCOMO_VERSION__ +#define __LIBCOMO_VERSION___WORKAROUND_GUARD 1 +#else +#define __LIBCOMO_VERSION___WORKAROUND_GUARD 0 +#endif +#ifndef _CPPLIB_VER +#define _CPPLIB_VER_WORKAROUND_GUARD 1 +#else +#define _CPPLIB_VER_WORKAROUND_GUARD 0 +#endif + +#ifndef BOOST_INTEL_CXX_VERSION +#define BOOST_INTEL_CXX_VERSION_WORKAROUND_GUARD 1 +#else +#define BOOST_INTEL_CXX_VERSION_WORKAROUND_GUARD 0 +#endif +#ifndef BOOST_INTEL_WIN +#define BOOST_INTEL_WIN_WORKAROUND_GUARD 1 +#else +#define BOOST_INTEL_WIN_WORKAROUND_GUARD 0 +#endif +#ifndef BOOST_DINKUMWARE_STDLIB +#define BOOST_DINKUMWARE_STDLIB_WORKAROUND_GUARD 1 +#else +#define BOOST_DINKUMWARE_STDLIB_WORKAROUND_GUARD 0 +#endif +#ifndef BOOST_INTEL +#define BOOST_INTEL_WORKAROUND_GUARD 1 +#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 + +#define BOOST_WORKAROUND(symbol, test) \ + ((symbol ## _WORKAROUND_GUARD + 0 == 0) && \ + (symbol != 0) && (1 % (( (symbol test) ) + 1))) +// ^ ^ ^ ^ +// The extra level of parenthesis nesting above, along with the +// BOOST_OPEN_PAREN indirection below, is required to satisfy the +// broken preprocessor in MWCW 8.3 and earlier. +// +// The basic mechanism works as follows: +// (symbol test) + 1 => if (symbol test) then 2 else 1 +// 1 % ((symbol test) + 1) => if (symbol test) then 1 else 0 +// +// The complication with % is for cooperation with BOOST_TESTED_AT(). +// When "test" is BOOST_TESTED_AT(x) and +// BOOST_DETECT_OUTDATED_WORKAROUNDS is #defined, +// +// symbol test => if (symbol <= x) then 1 else -1 +// (symbol test) + 1 => if (symbol <= x) then 2 else 0 +// 1 % ((symbol test) + 1) => if (symbol <= x) then 1 else divide-by-zero +// + +#ifdef BOOST_DETECT_OUTDATED_WORKAROUNDS +# define BOOST_OPEN_PAREN ( +# define BOOST_TESTED_AT(value) > value) ?(-1): BOOST_OPEN_PAREN 1 +#else +# define BOOST_TESTED_AT(value) != ((value)-(value)) +#endif + +#else + +#define BOOST_WORKAROUND(symbol, test) 0 + +#endif + +#endif // BOOST_CONFIG_WORKAROUND_HPP diff --git a/third_party/boost/libs/config/include/boost/cstdint.hpp b/third_party/boost/libs/config/include/boost/cstdint.hpp new file mode 100644 index 00000000000..967aacfd3e1 --- /dev/null +++ b/third_party/boost/libs/config/include/boost/cstdint.hpp @@ -0,0 +1,556 @@ +// boost cstdint.hpp header file ------------------------------------------// + +// (C) Copyright Beman Dawes 1999. +// (C) Copyright Jens Mauer 2001 +// (C) Copyright John Maddock 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) + +// See http://www.boost.org/libs/integer for documentation. + +// Revision History +// 31 Oct 01 use BOOST_HAS_LONG_LONG to check for "long long" (Jens M.) +// 16 Apr 01 check LONGLONG_MAX when looking for "long long" (Jens Maurer) +// 23 Jan 01 prefer "long" over "int" for int32_t and intmax_t (Jens Maurer) +// 12 Nov 00 Merged (Jens Maurer) +// 23 Sep 00 Added INTXX_C macro support (John Maddock). +// 22 Sep 00 Better 64-bit support (John Maddock) +// 29 Jun 00 Reimplement to avoid including stdint.h within namespace boost +// 8 Aug 99 Initial version (Beman Dawes) + + +#ifndef BOOST_CSTDINT_HPP +#define BOOST_CSTDINT_HPP + +// +// Since we always define the INT#_C macros as per C++0x, +// define __STDC_CONSTANT_MACROS so that does the right +// thing if possible, and so that the user knows that the macros +// are actually defined as per C99. +// +#ifndef __STDC_CONSTANT_MACROS +# define __STDC_CONSTANT_MACROS +#endif + +#include +// +// For the following code we get several warnings along the lines of: +// +// boost/cstdint.hpp:428:35: error: use of C99 long long integer constant +// +// So we declare this a system header to suppress these warnings. +// See also https://github.com/boostorg/config/issues/190 +// +#if defined(__GNUC__) && (__GNUC__ >= 4) +#pragma GCC system_header +#endif + +// +// Note that GLIBC is a bit inconsistent about whether int64_t is defined or not +// depending upon what headers happen to have been included first... +// so we disable use of stdint.h when GLIBC does not define __GLIBC_HAVE_LONG_LONG. +// See https://svn.boost.org/trac/boost/ticket/3548 and http://sources.redhat.com/bugzilla/show_bug.cgi?id=10990 +// +#if defined(BOOST_HAS_STDINT_H) \ + && (!defined(__GLIBC__) \ + || defined(__GLIBC_HAVE_LONG_LONG) \ + || (defined(__GLIBC__) && ((__GLIBC__ > 2) || ((__GLIBC__ == 2) && (__GLIBC_MINOR__ >= 17))))) + +// The following #include is an implementation artifact; not part of interface. +# ifdef __hpux +// HP-UX has a vaguely nice in a non-standard location +# include +# ifdef __STDC_32_MODE__ + // this is triggered with GCC, because it defines __cplusplus < 199707L +# define BOOST_NO_INT64_T +# endif +# elif defined(__FreeBSD__) || defined(__IBMCPP__) || defined(_AIX) +# include +# else +# include + +// There is a bug in Cygwin two _C macros +# if defined(INTMAX_C) && defined(__CYGWIN__) +# undef INTMAX_C +# undef UINTMAX_C +# define INTMAX_C(c) c##LL +# define UINTMAX_C(c) c##ULL +# endif + +# endif + +#if defined(__QNX__) && defined(__EXT_QNX) + +// QNX (Dinkumware stdlib) defines these as non-standard names. +// Reflect to the standard names. + +typedef ::intleast8_t int_least8_t; +typedef ::intfast8_t int_fast8_t; +typedef ::uintleast8_t uint_least8_t; +typedef ::uintfast8_t uint_fast8_t; + +typedef ::intleast16_t int_least16_t; +typedef ::intfast16_t int_fast16_t; +typedef ::uintleast16_t uint_least16_t; +typedef ::uintfast16_t uint_fast16_t; + +typedef ::intleast32_t int_least32_t; +typedef ::intfast32_t int_fast32_t; +typedef ::uintleast32_t uint_least32_t; +typedef ::uintfast32_t uint_fast32_t; + +# ifndef BOOST_NO_INT64_T + +typedef ::intleast64_t int_least64_t; +typedef ::intfast64_t int_fast64_t; +typedef ::uintleast64_t uint_least64_t; +typedef ::uintfast64_t uint_fast64_t; + +# endif + +#endif + +namespace boost +{ + + using ::int8_t; + using ::int_least8_t; + using ::int_fast8_t; + using ::uint8_t; + using ::uint_least8_t; + using ::uint_fast8_t; + + using ::int16_t; + using ::int_least16_t; + using ::int_fast16_t; + using ::uint16_t; + using ::uint_least16_t; + using ::uint_fast16_t; + + using ::int32_t; + using ::int_least32_t; + using ::int_fast32_t; + using ::uint32_t; + using ::uint_least32_t; + using ::uint_fast32_t; + +# ifndef BOOST_NO_INT64_T + + using ::int64_t; + using ::int_least64_t; + using ::int_fast64_t; + using ::uint64_t; + using ::uint_least64_t; + using ::uint_fast64_t; + +# endif + + using ::intmax_t; + using ::uintmax_t; + +} // namespace boost + +#elif defined(__FreeBSD__) && (__FreeBSD__ <= 4) || defined(__osf__) || defined(__VMS) || defined(__SOLARIS9__) || defined(__NetBSD__) +// FreeBSD and Tru64 have an that contains much of what we need. +# include + +namespace boost { + + using ::int8_t; + typedef int8_t int_least8_t; + typedef int8_t int_fast8_t; + using ::uint8_t; + typedef uint8_t uint_least8_t; + typedef uint8_t uint_fast8_t; + + using ::int16_t; + typedef int16_t int_least16_t; + typedef int16_t int_fast16_t; + using ::uint16_t; + typedef uint16_t uint_least16_t; + typedef uint16_t uint_fast16_t; + + using ::int32_t; + typedef int32_t int_least32_t; + typedef int32_t int_fast32_t; + using ::uint32_t; + typedef uint32_t uint_least32_t; + typedef uint32_t uint_fast32_t; + +# ifndef BOOST_NO_INT64_T + + using ::int64_t; + typedef int64_t int_least64_t; + typedef int64_t int_fast64_t; + using ::uint64_t; + typedef uint64_t uint_least64_t; + typedef uint64_t uint_fast64_t; + + typedef int64_t intmax_t; + typedef uint64_t uintmax_t; + +# else + + typedef int32_t intmax_t; + typedef uint32_t uintmax_t; + +# endif + +} // namespace boost + +#else // BOOST_HAS_STDINT_H + +# include // implementation artifact; not part of interface +# include // needed for limits macros + + +namespace boost +{ + +// These are fairly safe guesses for some 16-bit, and most 32-bit and 64-bit +// platforms. For other systems, they will have to be hand tailored. +// +// Because the fast types are assumed to be the same as the undecorated types, +// it may be possible to hand tailor a more efficient implementation. Such +// an optimization may be illusionary; on the Intel x86-family 386 on, for +// example, byte arithmetic and load/stores are as fast as "int" sized ones. + +// 8-bit types ------------------------------------------------------------// + +# if UCHAR_MAX == 0xff + typedef signed char int8_t; + typedef signed char int_least8_t; + typedef signed char int_fast8_t; + typedef unsigned char uint8_t; + typedef unsigned char uint_least8_t; + typedef unsigned char uint_fast8_t; +# else +# error defaults not correct; you must hand modify boost/cstdint.hpp +# endif + +// 16-bit types -----------------------------------------------------------// + +# if USHRT_MAX == 0xffff +# if defined(__crayx1) + // The Cray X1 has a 16-bit short, however it is not recommend + // for use in performance critical code. + typedef short int16_t; + typedef short int_least16_t; + typedef int int_fast16_t; + typedef unsigned short uint16_t; + typedef unsigned short uint_least16_t; + typedef unsigned int uint_fast16_t; +# else + typedef short int16_t; + typedef short int_least16_t; + typedef short int_fast16_t; + typedef unsigned short uint16_t; + typedef unsigned short uint_least16_t; + typedef unsigned short uint_fast16_t; +# endif +# elif (USHRT_MAX == 0xffffffff) && defined(__MTA__) + // On MTA / XMT short is 32 bits unless the -short16 compiler flag is specified + // MTA / XMT does support the following non-standard integer types + typedef __short16 int16_t; + typedef __short16 int_least16_t; + typedef __short16 int_fast16_t; + typedef unsigned __short16 uint16_t; + typedef unsigned __short16 uint_least16_t; + typedef unsigned __short16 uint_fast16_t; +# elif (USHRT_MAX == 0xffffffff) && defined(CRAY) + // no 16-bit types on Cray: + typedef short int_least16_t; + typedef short int_fast16_t; + typedef unsigned short uint_least16_t; + typedef unsigned short uint_fast16_t; +# else +# error defaults not correct; you must hand modify boost/cstdint.hpp +# endif + +// 32-bit types -----------------------------------------------------------// + +# if UINT_MAX == 0xffffffff + typedef int int32_t; + typedef int int_least32_t; + typedef int int_fast32_t; + typedef unsigned int uint32_t; + typedef unsigned int uint_least32_t; + typedef unsigned int uint_fast32_t; +# elif (USHRT_MAX == 0xffffffff) + typedef short int32_t; + typedef short int_least32_t; + typedef short int_fast32_t; + typedef unsigned short uint32_t; + typedef unsigned short uint_least32_t; + typedef unsigned short uint_fast32_t; +# elif ULONG_MAX == 0xffffffff + typedef long int32_t; + typedef long int_least32_t; + typedef long int_fast32_t; + typedef unsigned long uint32_t; + typedef unsigned long uint_least32_t; + typedef unsigned long uint_fast32_t; +# elif (UINT_MAX == 0xffffffffffffffff) && defined(__MTA__) + // Integers are 64 bits on the MTA / XMT + typedef __int32 int32_t; + typedef __int32 int_least32_t; + typedef __int32 int_fast32_t; + typedef unsigned __int32 uint32_t; + typedef unsigned __int32 uint_least32_t; + typedef unsigned __int32 uint_fast32_t; +# else +# error defaults not correct; you must hand modify boost/cstdint.hpp +# endif + +// 64-bit types + intmax_t and uintmax_t ----------------------------------// + +# if defined(BOOST_HAS_LONG_LONG) && \ + !defined(BOOST_MSVC) && !defined(BOOST_BORLANDC) && \ + (!defined(__GLIBCPP__) || defined(_GLIBCPP_USE_LONG_LONG)) && \ + (defined(ULLONG_MAX) || defined(ULONG_LONG_MAX) || defined(ULONGLONG_MAX)) +# if defined(__hpux) + // HP-UX's value of ULONG_LONG_MAX is unusable in preprocessor expressions +# elif (defined(ULLONG_MAX) && ULLONG_MAX == 18446744073709551615ULL) || (defined(ULONG_LONG_MAX) && ULONG_LONG_MAX == 18446744073709551615ULL) || (defined(ULONGLONG_MAX) && ULONGLONG_MAX == 18446744073709551615ULL) + // 2**64 - 1 +# else +# error defaults not correct; you must hand modify boost/cstdint.hpp +# endif + + typedef ::boost::long_long_type intmax_t; + typedef ::boost::ulong_long_type uintmax_t; + typedef ::boost::long_long_type int64_t; + typedef ::boost::long_long_type int_least64_t; + typedef ::boost::long_long_type int_fast64_t; + typedef ::boost::ulong_long_type uint64_t; + typedef ::boost::ulong_long_type uint_least64_t; + typedef ::boost::ulong_long_type uint_fast64_t; + +# elif ULONG_MAX != 0xffffffff + +# if ULONG_MAX == 18446744073709551615 // 2**64 - 1 + typedef long intmax_t; + typedef unsigned long uintmax_t; + typedef long int64_t; + typedef long int_least64_t; + typedef long int_fast64_t; + typedef unsigned long uint64_t; + typedef unsigned long uint_least64_t; + typedef unsigned long uint_fast64_t; +# else +# error defaults not correct; you must hand modify boost/cstdint.hpp +# endif +# elif defined(__GNUC__) && defined(BOOST_HAS_LONG_LONG) + __extension__ typedef long long intmax_t; + __extension__ typedef unsigned long long uintmax_t; + __extension__ typedef long long int64_t; + __extension__ typedef long long int_least64_t; + __extension__ typedef long long int_fast64_t; + __extension__ typedef unsigned long long uint64_t; + __extension__ typedef unsigned long long uint_least64_t; + __extension__ typedef unsigned long long uint_fast64_t; +# elif defined(BOOST_HAS_MS_INT64) + // + // we have Borland/Intel/Microsoft __int64: + // + typedef __int64 intmax_t; + typedef unsigned __int64 uintmax_t; + typedef __int64 int64_t; + typedef __int64 int_least64_t; + typedef __int64 int_fast64_t; + typedef unsigned __int64 uint64_t; + typedef unsigned __int64 uint_least64_t; + typedef unsigned __int64 uint_fast64_t; +# else // assume no 64-bit integers +# define BOOST_NO_INT64_T + typedef int32_t intmax_t; + typedef uint32_t uintmax_t; +# endif + +} // namespace boost + + +#endif // BOOST_HAS_STDINT_H + +// intptr_t/uintptr_t are defined separately because they are optional and not universally available +#if defined(BOOST_WINDOWS) && !defined(_WIN32_WCE) && !defined(BOOST_HAS_STDINT_H) +// Older MSVC don't have stdint.h and have intptr_t/uintptr_t defined in stddef.h +#include +#endif + +#if (defined(BOOST_WINDOWS) && !defined(_WIN32_WCE)) \ + || (defined(_XOPEN_UNIX) && (_XOPEN_UNIX+0 > 0) && !defined(__UCLIBC__)) \ + || defined(__CYGWIN__) || defined(__VXWORKS__) \ + || defined(macintosh) || defined(__APPLE__) || defined(__APPLE_CC__) \ + || defined(__FreeBSD__) || defined(__NetBSD__) || defined(__OpenBSD__) || defined(__DragonFly__) || (defined(sun) && !defined(BOOST_HAS_STDINT_H)) || defined(INTPTR_MAX) + +namespace boost { + using ::intptr_t; + using ::uintptr_t; +} +#define BOOST_HAS_INTPTR_T + +// Clang pretends to be GCC, so it'll match this condition +#elif defined(__GNUC__) && defined(__INTPTR_TYPE__) && defined(__UINTPTR_TYPE__) + +namespace boost { + typedef __INTPTR_TYPE__ intptr_t; + typedef __UINTPTR_TYPE__ uintptr_t; +} +#define BOOST_HAS_INTPTR_T + +#endif + +#endif // BOOST_CSTDINT_HPP + + +/**************************************************** + +Macro definition section: + +Added 23rd September 2000 (John Maddock). +Modified 11th September 2001 to be excluded when +BOOST_HAS_STDINT_H is defined (John Maddock). +Modified 11th Dec 2009 to always define the +INT#_C macros if they're not already defined (John Maddock). + +******************************************************/ + +#if !defined(BOOST__STDC_CONSTANT_MACROS_DEFINED) && \ + (!defined(INT8_C) || !defined(INT16_C) || !defined(INT32_C) || !defined(INT64_C)) +// +// Undef the macros as a precaution, since we may get here if has failed +// to define them all, see https://svn.boost.org/trac/boost/ticket/12786 +// +#undef INT8_C +#undef INT16_C +#undef INT32_C +#undef INT64_C +#undef INTMAX_C +#undef UINT8_C +#undef UINT16_C +#undef UINT32_C +#undef UINT64_C +#undef UINTMAX_C + +#include +# define BOOST__STDC_CONSTANT_MACROS_DEFINED +# if defined(BOOST_HAS_MS_INT64) +// +// Borland/Intel/Microsoft compilers have width specific suffixes: +// +#ifndef INT8_C +# define INT8_C(value) value##i8 +#endif +#ifndef INT16_C +# define INT16_C(value) value##i16 +#endif +#ifndef INT32_C +# define INT32_C(value) value##i32 +#endif +#ifndef INT64_C +# define INT64_C(value) value##i64 +#endif +# ifdef BOOST_BORLANDC + // Borland bug: appending ui8 makes the type a signed char +# define UINT8_C(value) static_cast(value##u) +# else +# define UINT8_C(value) value##ui8 +# endif +#ifndef UINT16_C +# define UINT16_C(value) value##ui16 +#endif +#ifndef UINT32_C +# define UINT32_C(value) value##ui32 +#endif +#ifndef UINT64_C +# define UINT64_C(value) value##ui64 +#endif +#ifndef INTMAX_C +# define INTMAX_C(value) value##i64 +# define UINTMAX_C(value) value##ui64 +#endif + +# else +// do it the old fashioned way: + +// 8-bit types ------------------------------------------------------------// + +# if (UCHAR_MAX == 0xff) && !defined(INT8_C) +# define INT8_C(value) static_cast(value) +# define UINT8_C(value) static_cast(value##u) +# endif + +// 16-bit types -----------------------------------------------------------// + +# if (USHRT_MAX == 0xffff) && !defined(INT16_C) +# define INT16_C(value) static_cast(value) +# define UINT16_C(value) static_cast(value##u) +# endif + +// 32-bit types -----------------------------------------------------------// +#ifndef INT32_C +# if (UINT_MAX == 0xffffffff) +# define INT32_C(value) value +# define UINT32_C(value) value##u +# elif ULONG_MAX == 0xffffffff +# define INT32_C(value) value##L +# define UINT32_C(value) value##uL +# endif +#endif + +// 64-bit types + intmax_t and uintmax_t ----------------------------------// +#ifndef INT64_C +# if defined(BOOST_HAS_LONG_LONG) && \ + (defined(ULLONG_MAX) || defined(ULONG_LONG_MAX) || defined(ULONGLONG_MAX) || defined(_ULLONG_MAX) || defined(_LLONG_MAX)) + +# if defined(__hpux) + // HP-UX's value of ULONG_LONG_MAX is unusable in preprocessor expressions +# define INT64_C(value) value##LL +# define UINT64_C(value) value##uLL +# elif (defined(ULLONG_MAX) && ULLONG_MAX == 18446744073709551615ULL) || \ + (defined(ULONG_LONG_MAX) && ULONG_LONG_MAX == 18446744073709551615ULL) || \ + (defined(ULONGLONG_MAX) && ULONGLONG_MAX == 18446744073709551615ULL) || \ + (defined(_ULLONG_MAX) && _ULLONG_MAX == 18446744073709551615ULL) || \ + (defined(_LLONG_MAX) && _LLONG_MAX == 9223372036854775807LL) + +# define INT64_C(value) value##LL +# define UINT64_C(value) value##uLL +# else +# error defaults not correct; you must hand modify boost/cstdint.hpp +# endif +# elif ULONG_MAX != 0xffffffff + +# if ULONG_MAX == 18446744073709551615U // 2**64 - 1 +# define INT64_C(value) value##L +# define UINT64_C(value) value##uL +# else +# error defaults not correct; you must hand modify boost/cstdint.hpp +# endif +# elif defined(BOOST_HAS_LONG_LONG) + // Usual macros not defined, work things out for ourselves: +# if(~0uLL == 18446744073709551615ULL) +# define INT64_C(value) value##LL +# define UINT64_C(value) value##uLL +# else +# error defaults not correct; you must hand modify boost/cstdint.hpp +# endif +# else +# error defaults not correct; you must hand modify boost/cstdint.hpp +# endif + +# ifdef BOOST_NO_INT64_T +# define INTMAX_C(value) INT32_C(value) +# define UINTMAX_C(value) UINT32_C(value) +# else +# define INTMAX_C(value) INT64_C(value) +# define UINTMAX_C(value) UINT64_C(value) +# endif +#endif +# endif // Borland/Microsoft specific width suffixes + +#endif // INT#_C macros. + + + + diff --git a/third_party/boost/libs/config/include/boost/cxx11_char_types.hpp b/third_party/boost/libs/config/include/boost/cxx11_char_types.hpp new file mode 100644 index 00000000000..71b9b70d772 --- /dev/null +++ b/third_party/boost/libs/config/include/boost/cxx11_char_types.hpp @@ -0,0 +1,70 @@ +// boost cxx11_char_types.hpp --------------------------------------------------------// + +// Copyright Beman Dawes 2011 + +// Distributed under the Boost Software License, Version 1.0. +// See http://www.boost.org/LICENSE_1_0.txt + +//--------------------------------------------------------------------------------------// +// // +// The purpose of this header is to emulate the C++11 char16_t and char32_t // +// character and string types so that they can be used in both C++11 and C++03 // +// programs. // +// // +// The emulation names use char16/char32 rather than char16_t/char32_t to avoid use // +// of names that are keywords in C++11. // +// // +// The emulation names are placed in namespace boost, as is usual for Boost C++11 // +// emulation names such as those in header . // +// // +// An alternative would would have been to place the C++11 emulation names at global // +// scope, and put the C++11 string types in namespace std. That is the approach taken // +// by Microsoft Visual Studio 2010, but is controversion with some Boost users and // +// developers, and runs counter to usual Boost practice. // +// // +// Thanks to Mathias Gaunard and others for discussions leading to the final form // +// of these typedefs. // +// // +// Boost C++11 C++03 // +// ---------------- -------------- -------------------------------- // +// boost::char16 char16_t uint16_t // +// boost::char32 char32_t uint32_t // +// boost::u16string std::u16string std::basic_string // +// boost::u32string std::u32string std::basic_string // +// // +// Uses the typedefs provided by Microsoft Visual C++ 2010 if present // +// // +// Thanks to Mathias Gaunard and others for discussions leading to the final form // +// of these typedefs. // +// // +//--------------------------------------------------------------------------------------// + +#if !defined(BOOST_CXX11_CHAR_TYPES_HPP) +# define BOOST_CXX11_CHAR_TYPES_HPP + +# include +# include +# include + +namespace boost +{ + +# if defined(BOOST_NO_CXX11_CHAR16_T) && (!defined(_MSC_VER) || _MSC_VER < 1600) // 1600 == VC++10 + typedef boost::uint_least16_t char16; + typedef std::basic_string u16string; +# else + typedef char16_t char16; + typedef std::u16string u16string; +# endif + +# if defined(BOOST_NO_CXX11_CHAR32_T) && (!defined(_MSC_VER) || _MSC_VER < 1600) // 1600 == VC++10 + typedef boost::uint_least32_t char32; + typedef std::basic_string u32string; +# else + typedef char32_t char32; + typedef std::u32string u32string; +# endif + +} // namespace boost + +#endif // !defined(BOOST_CXX11_CHAR_TYPES_HPP) diff --git a/third_party/boost/libs/config/include/boost/detail/workaround.hpp b/third_party/boost/libs/config/include/boost/detail/workaround.hpp new file mode 100644 index 00000000000..9c392182a06 --- /dev/null +++ b/third_party/boost/libs/config/include/boost/detail/workaround.hpp @@ -0,0 +1,10 @@ +// Copyright David Abrahams 2002. +// 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_WORKAROUND_DWA2002126_HPP +#define BOOST_WORKAROUND_DWA2002126_HPP + +#include + +#endif // BOOST_WORKAROUND_DWA2002126_HPP diff --git a/third_party/boost/libs/config/include/boost/limits.hpp b/third_party/boost/libs/config/include/boost/limits.hpp new file mode 100644 index 00000000000..1b54477ecd8 --- /dev/null +++ b/third_party/boost/libs/config/include/boost/limits.hpp @@ -0,0 +1,146 @@ + +// (C) Copyright John maddock 1999. +// (C) David Abrahams 2002. 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) +// +// use this header as a workaround for missing + +// See http://www.boost.org/libs/compatibility/index.html for documentation. + +#ifndef BOOST_LIMITS +#define BOOST_LIMITS + +#include + +#ifdef BOOST_NO_LIMITS +# error "There is no std::numeric_limits suppport available." +#else +# include +#endif + +#if (defined(BOOST_HAS_LONG_LONG) && defined(BOOST_NO_LONG_LONG_NUMERIC_LIMITS)) \ + || (defined(BOOST_HAS_MS_INT64) && defined(BOOST_NO_MS_INT64_NUMERIC_LIMITS)) +// Add missing specializations for numeric_limits: +#ifdef BOOST_HAS_MS_INT64 +# define BOOST_LLT __int64 +# define BOOST_ULLT unsigned __int64 +#else +# define BOOST_LLT ::boost::long_long_type +# define BOOST_ULLT ::boost::ulong_long_type +#endif + +#include // for CHAR_BIT + +namespace std +{ + template<> + class numeric_limits + { + public: + + BOOST_STATIC_CONSTANT(bool, is_specialized = true); +#ifdef BOOST_HAS_MS_INT64 + static BOOST_LLT min BOOST_PREVENT_MACRO_SUBSTITUTION (){ return 0x8000000000000000i64; } + static BOOST_LLT max BOOST_PREVENT_MACRO_SUBSTITUTION (){ return 0x7FFFFFFFFFFFFFFFi64; } +#elif defined(LLONG_MAX) + static BOOST_LLT min BOOST_PREVENT_MACRO_SUBSTITUTION (){ return LLONG_MIN; } + static BOOST_LLT max BOOST_PREVENT_MACRO_SUBSTITUTION (){ return LLONG_MAX; } +#elif defined(LONGLONG_MAX) + static BOOST_LLT min BOOST_PREVENT_MACRO_SUBSTITUTION (){ return LONGLONG_MIN; } + static BOOST_LLT max BOOST_PREVENT_MACRO_SUBSTITUTION (){ return LONGLONG_MAX; } +#else + static BOOST_LLT min BOOST_PREVENT_MACRO_SUBSTITUTION (){ return 1LL << (sizeof(BOOST_LLT) * CHAR_BIT - 1); } + static BOOST_LLT max BOOST_PREVENT_MACRO_SUBSTITUTION (){ return ~(min)(); } +#endif + BOOST_STATIC_CONSTANT(int, digits = sizeof(BOOST_LLT) * CHAR_BIT -1); + BOOST_STATIC_CONSTANT(int, digits10 = (CHAR_BIT * sizeof (BOOST_LLT) - 1) * 301L / 1000); + BOOST_STATIC_CONSTANT(bool, is_signed = true); + BOOST_STATIC_CONSTANT(bool, is_integer = true); + BOOST_STATIC_CONSTANT(bool, is_exact = true); + BOOST_STATIC_CONSTANT(int, radix = 2); + 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); + BOOST_STATIC_CONSTANT(int, max_exponent = 0); + BOOST_STATIC_CONSTANT(int, max_exponent10 = 0); + + BOOST_STATIC_CONSTANT(bool, has_infinity = false); + BOOST_STATIC_CONSTANT(bool, has_quiet_NaN = false); + 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() 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); + BOOST_STATIC_CONSTANT(bool, is_modulo = true); + + BOOST_STATIC_CONSTANT(bool, traps = false); + BOOST_STATIC_CONSTANT(bool, tinyness_before = false); + BOOST_STATIC_CONSTANT(float_round_style, round_style = round_toward_zero); + + }; + + template<> + class numeric_limits + { + public: + + BOOST_STATIC_CONSTANT(bool, is_specialized = true); +#ifdef BOOST_HAS_MS_INT64 + static BOOST_ULLT min BOOST_PREVENT_MACRO_SUBSTITUTION (){ return 0ui64; } + static BOOST_ULLT max BOOST_PREVENT_MACRO_SUBSTITUTION (){ return 0xFFFFFFFFFFFFFFFFui64; } +#elif defined(ULLONG_MAX) && defined(ULLONG_MIN) + static BOOST_ULLT min BOOST_PREVENT_MACRO_SUBSTITUTION (){ return ULLONG_MIN; } + static BOOST_ULLT max BOOST_PREVENT_MACRO_SUBSTITUTION (){ return ULLONG_MAX; } +#elif defined(ULONGLONG_MAX) && defined(ULONGLONG_MIN) + static BOOST_ULLT min BOOST_PREVENT_MACRO_SUBSTITUTION (){ return ULONGLONG_MIN; } + static BOOST_ULLT max BOOST_PREVENT_MACRO_SUBSTITUTION (){ return ULONGLONG_MAX; } +#else + static BOOST_ULLT min BOOST_PREVENT_MACRO_SUBSTITUTION (){ return 0uLL; } + static BOOST_ULLT max BOOST_PREVENT_MACRO_SUBSTITUTION (){ return ~0uLL; } +#endif + BOOST_STATIC_CONSTANT(int, digits = sizeof(BOOST_LLT) * CHAR_BIT); + BOOST_STATIC_CONSTANT(int, digits10 = (CHAR_BIT * sizeof (BOOST_LLT)) * 301L / 1000); + BOOST_STATIC_CONSTANT(bool, is_signed = false); + BOOST_STATIC_CONSTANT(bool, is_integer = true); + BOOST_STATIC_CONSTANT(bool, is_exact = true); + BOOST_STATIC_CONSTANT(int, radix = 2); + 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); + BOOST_STATIC_CONSTANT(int, max_exponent = 0); + BOOST_STATIC_CONSTANT(int, max_exponent10 = 0); + + BOOST_STATIC_CONSTANT(bool, has_infinity = false); + BOOST_STATIC_CONSTANT(bool, has_quiet_NaN = false); + 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() 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); + BOOST_STATIC_CONSTANT(bool, is_modulo = true); + + BOOST_STATIC_CONSTANT(bool, traps = false); + BOOST_STATIC_CONSTANT(bool, tinyness_before = false); + BOOST_STATIC_CONSTANT(float_round_style, round_style = round_toward_zero); + + }; +} +#endif + +#endif + diff --git a/third_party/boost/libs/config/include/boost/version.hpp b/third_party/boost/libs/config/include/boost/version.hpp new file mode 100644 index 00000000000..02bd3fc6fa3 --- /dev/null +++ b/third_party/boost/libs/config/include/boost/version.hpp @@ -0,0 +1,32 @@ +// Boost version.hpp configuration header file ------------------------------// + +// (C) Copyright John maddock 1999. 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/config for documentation + +#ifndef BOOST_VERSION_HPP +#define BOOST_VERSION_HPP + +// +// Caution: this is the only Boost header that is guaranteed +// to change with every Boost release. Including this header +// will cause a recompile every time a new Boost version is +// used. +// +// BOOST_VERSION % 100 is the patch level +// BOOST_VERSION / 100 % 1000 is the minor version +// BOOST_VERSION / 100000 is the major version + +#define BOOST_VERSION 108200 + +// +// BOOST_LIB_VERSION must be defined to be the same as BOOST_VERSION +// but as a *string* in the form "x_y[_z]" where x is the major version +// number, y is the minor version number, and z is the patch level if not 0. +// This is used by to select which library version to link to. + +#define BOOST_LIB_VERSION "1_82" + +#endif diff --git a/third_party/boost/libs/container_hash/CMakeLists.txt b/third_party/boost/libs/container_hash/CMakeLists.txt new file mode 100644 index 00000000000..606e894fc62 --- /dev/null +++ b/third_party/boost/libs/container_hash/CMakeLists.txt @@ -0,0 +1,27 @@ +# Generated by `boostdep --cmake container_hash` +# Copyright 2020, 2021 Peter Dimov +# Distributed under the Boost Software License, Version 1.0. +# https://www.boost.org/LICENSE_1_0.txt + +cmake_minimum_required(VERSION 3.5...3.20) + +project(boost_container_hash VERSION "${BOOST_SUPERPROJECT_VERSION}" LANGUAGES CXX) + +add_library(boost_container_hash INTERFACE) +add_library(Boost::container_hash ALIAS boost_container_hash) + +target_include_directories(boost_container_hash INTERFACE include) + +target_link_libraries(boost_container_hash + INTERFACE + Boost::config + Boost::describe + Boost::mp11 + Boost::type_traits +) + +if(BUILD_TESTING AND EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/test/CMakeLists.txt") + + add_subdirectory(test) + +endif() diff --git a/third_party/boost/libs/container_hash/README.md b/third_party/boost/libs/container_hash/README.md new file mode 100644 index 00000000000..aaaf577be7c --- /dev/null +++ b/third_party/boost/libs/container_hash/README.md @@ -0,0 +1,20 @@ +# Boost.ContainerHash + +The Boost.ContainerHash library, part of [Boost C++ Libraries](https://boost.org), +provides `boost::hash`, an enhanced implementation of the +[hash function](https://en.wikipedia.org/wiki/Hash_function) object specified +by C++11 as `std::hash`, and several support facilities (`hash_combine`, +`hash_range`, `hash_unordered_range`). + +`boost::hash` supports most standard types and some user-defined types out of +the box, and is extensible; it's possible for a user-defined type `X` to make +iself hashable via `boost::hash` by defining an appropriate overload of the +function `hash_value`. + +See [the documentation of the library](https://www.boost.org/libs/container_hash) +for more information. + +## License + +Distributed under the +[Boost Software License, Version 1.0](http://boost.org/LICENSE_1_0.txt). diff --git a/third_party/boost/libs/container_hash/include/boost/container_hash/detail/hash_mix.hpp b/third_party/boost/libs/container_hash/include/boost/container_hash/detail/hash_mix.hpp new file mode 100644 index 00000000000..327da9e51c3 --- /dev/null +++ b/third_party/boost/libs/container_hash/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/third_party/boost/libs/container_hash/include/boost/container_hash/detail/hash_range.hpp b/third_party/boost/libs/container_hash/include/boost/container_hash/detail/hash_range.hpp new file mode 100644 index 00000000000..84ec97da58f --- /dev/null +++ b/third_party/boost/libs/container_hash/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/third_party/boost/libs/container_hash/include/boost/container_hash/detail/hash_tuple_like.hpp b/third_party/boost/libs/container_hash/include/boost/container_hash/detail/hash_tuple_like.hpp new file mode 100644 index 00000000000..f9f5a5bae80 --- /dev/null +++ b/third_party/boost/libs/container_hash/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/third_party/boost/libs/container_hash/include/boost/container_hash/detail/limits.hpp b/third_party/boost/libs/container_hash/include/boost/container_hash/detail/limits.hpp new file mode 100644 index 00000000000..78903095506 --- /dev/null +++ b/third_party/boost/libs/container_hash/include/boost/container_hash/detail/limits.hpp @@ -0,0 +1,19 @@ +// 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) + +#ifndef BOOST_FUNCTIONAL_HASH_DETAIL_LIMITS_HEADER +#define BOOST_FUNCTIONAL_HASH_DETAIL_LIMITS_HEADER + +#include + +namespace boost +{ + namespace hash_detail + { + template + struct limits : std::numeric_limits {}; + } +} + +#endif // #ifndef BOOST_FUNCTIONAL_HASH_DETAIL_LIMITS_HEADER diff --git a/third_party/boost/libs/container_hash/include/boost/container_hash/detail/mulx.hpp b/third_party/boost/libs/container_hash/include/boost/container_hash/detail/mulx.hpp new file mode 100644 index 00000000000..da6f21a2458 --- /dev/null +++ b/third_party/boost/libs/container_hash/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/third_party/boost/libs/container_hash/include/boost/container_hash/detail/requires_cxx11.hpp b/third_party/boost/libs/container_hash/include/boost/container_hash/detail/requires_cxx11.hpp new file mode 100644 index 00000000000..61db135bc27 --- /dev/null +++ b/third_party/boost/libs/container_hash/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 is deprecated in Boost.ContainerHash 1.82 and will be removed in Boost.ContainerHash 1.84.") + +#endif + +#endif // #ifndef BOOST_HASH_DETAIL_REQUIRES_CXX11_HPP_INCLUDED diff --git a/third_party/boost/libs/container_hash/include/boost/container_hash/extensions.hpp b/third_party/boost/libs/container_hash/include/boost/container_hash/extensions.hpp new file mode 100644 index 00000000000..809d39783e4 --- /dev/null +++ b/third_party/boost/libs/container_hash/include/boost/container_hash/extensions.hpp @@ -0,0 +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) + +#ifndef BOOST_FUNCTIONAL_HASH_EXTENSIONS_HPP +#define BOOST_FUNCTIONAL_HASH_EXTENSIONS_HPP + +#include + +#endif // #ifndef BOOST_FUNCTIONAL_HASH_EXTENSIONS_HPP diff --git a/third_party/boost/libs/container_hash/include/boost/container_hash/hash.hpp b/third_party/boost/libs/container_hash/include/boost/container_hash/hash.hpp new file mode 100644 index 00000000000..605644b35d1 --- /dev/null +++ b/third_party/boost/libs/container_hash/include/boost/container_hash/hash.hpp @@ -0,0 +1,677 @@ +// Copyright 2005-2014 Daniel James. +// Copyright 2021, 2022 Peter Dimov. +// Distributed under the Boost Software License, Version 1.0. +// https://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. + +#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 + +#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) +#include +#endif + +#if !defined(BOOST_NO_CXX11_HDR_SYSTEM_ERROR) +#include +#endif + +#if !defined(BOOST_NO_CXX17_HDR_OPTIONAL) +#include +#endif + +#if !defined(BOOST_NO_CXX17_HDR_VARIANT) +#include +#endif + +#if !defined(BOOST_NO_CXX17_HDR_STRING_VIEW) +# include +#endif + +namespace boost +{ + + // + // boost::hash_value + // + + // integral types + + namespace hash_detail + { + 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 + { + static std::size_t fn( T v ) + { + return static_cast( v ); + } + }; + + template struct hash_integral_impl + { + static std::size_t fn( T v ) + { + typedef typename boost::make_unsigned::type U; + + if( v >= 0 ) + { + return hash_integral_impl::fn( static_cast( v ) ); + } + else + { + return ~hash_integral_impl::fn( static_cast( ~static_cast( v ) ) ); + } + } + }; + + template struct hash_integral_impl + { + static std::size_t fn( T v ) + { + std::size_t seed = 0; + + seed = static_cast( v >> 32 ) + hash_detail::hash_mix( seed ); + seed = static_cast( v & 0xFFFFFFFF ) + hash_detail::hash_mix( seed ); + + return seed; + } + }; + + template struct hash_integral_impl + { + static std::size_t fn( T v ) + { + std::size_t seed = 0; + + 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 ); + + return seed; + } + }; + + template struct hash_integral_impl + { + static std::size_t fn( T v ) + { + std::size_t seed = 0; + + seed = static_cast( v >> 64 ) + hash_detail::hash_mix( seed ); + seed = static_cast( v ) + hash_detail::hash_mix( seed ); + + return seed; + } + }; + + } // namespace hash_detail + + template + typename boost::enable_if_::value, std::size_t>::type + hash_value( T v ) + { + return hash_detail::hash_integral_impl::fn( v ); + } + + // enumeration types + + template + 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 ); + } + + // floating point types + + namespace hash_detail + { + template::digits> + struct hash_float_impl; + + // float + template struct hash_float_impl + { + static std::size_t fn( T v ) + { + boost::uint32_t w; + std::memcpy( &w, &v, sizeof( v ) ); + + return w; + } + }; + + // double + template struct hash_float_impl + { + static std::size_t fn( T v ) + { + boost::uint64_t w; + std::memcpy( &w, &v, sizeof( v ) ); + + return hash_value( w ); + } + }; + + // 80 bit long double in 12 bytes + template struct hash_float_impl + { + static std::size_t fn( T v ) + { + boost::uint64_t w[ 2 ] = {}; + std::memcpy( &w, &v, 80 / CHAR_BIT ); + + std::size_t seed = 0; + + seed = hash_value( w[0] ) + hash_detail::hash_mix( seed ); + seed = hash_value( w[1] ) + hash_detail::hash_mix( seed ); + + return seed; + } + }; + + // 80 bit long double in 16 bytes + template struct hash_float_impl + { + static std::size_t fn( T v ) + { + boost::uint64_t w[ 2 ] = {}; + std::memcpy( &w, &v, 80 / CHAR_BIT ); + + std::size_t seed = 0; + + seed = hash_value( w[0] ) + hash_detail::hash_mix( seed ); + seed = hash_value( w[1] ) + hash_detail::hash_mix( seed ); + + 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 ) ); + + std::size_t seed = 0; + +#if defined(__FLOAT_WORD_ORDER__) && defined(__ORDER_BIG_ENDIAN__) && __FLOAT_WORD_ORDER__ == __ORDER_BIG_ENDIAN__ + + seed = hash_value( w[1] ) + hash_detail::hash_mix( seed ); + seed = hash_value( w[0] ) + hash_detail::hash_mix( seed ); + +#else + + seed = hash_value( w[0] ) + hash_detail::hash_mix( seed ); + seed = hash_value( w[1] ) + hash_detail::hash_mix( seed ); + +#endif + return seed; + } + }; + + } // namespace hash_detail + + template + typename boost::enable_if_::value, std::size_t>::type + hash_value( T v ) + { + return boost::hash_detail::hash_float_impl::fn( v + 0 ); + } + + // pointer types + + // `x + (x >> 3)` adjustment by Alberto Barbati and Dave Harris. + template std::size_t hash_value( T* const& v ) + { + boost::uintptr_t x = reinterpret_cast( v ); + return boost::hash_value( x + (x >> 3) ); + } + + // array types + + template + inline std::size_t hash_value( T const (&x)[ N ] ) + { + return boost::hash_range( x, x + N ); + } + + template + inline std::size_t hash_value( T (&x)[ N ] ) + { + return boost::hash_range( x, x + N ); + } + + // complex + + template + std::size_t hash_value( std::complex const& v ) + { + std::size_t re = boost::hash()( v.real() ); + std::size_t im = boost::hash()( v.imag() ); + + return re + hash_detail::hash_mix( im ); + } + + // pair + + 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; + } + + // ranges (list, set, deque...) + + 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 ) + { + return boost::hash_range( v.begin(), v.end() ); + } + + // contiguous ranges (string, vector, array) + + 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() ); + } + + // unordered ranges (unordered_set, unordered_map) + + template + typename boost::enable_if_::value, std::size_t>::type + hash_value( T const& v ) + { + return boost::hash_unordered_range( v.begin(), v.end() ); + } + +#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 boost::hash_range( v.begin(), v.end() ); + } + + // 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 boost::hash_range( v.data(), v.data() + v.size() ); + } + + template class L, class T, std::size_t N> + typename boost::enable_if_>::value, std::size_t>::type + hash_value( L const& v ) + { + return boost::hash_range( v.data(), v.data() + v.size() ); + } + + // 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 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::enable_if_::value, std::size_t>::type + hash_value( T const& v ) + { + static_assert( !boost::is_union::value, "described unions are not supported" ); + + 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 + +#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 + 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 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 ) + { + 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 ) + { + std::size_t seed = 0; + + boost::hash_combine( seed, v.value() ); + boost::hash_combine( seed, &v.category() ); + + return seed; + } + +#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.index() ); + std::visit( [&seed](auto&& x) { hash_combine(seed, x); }, v ); + + return seed; + } + +#endif + + // + // boost::hash_combine + // + + 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_range + // + + template + inline void hash_range( std::size_t& seed, It first, It last ) + { + seed = hash_detail::hash_range( seed, first, last ); + } + + template + inline std::size_t hash_range( It first, It last ) + { + std::size_t seed = 0; + + hash_range( seed, first, last ); + + return seed; + } + + // + // boost::hash_unordered_range + // + + 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 ); + + for( ; first != last; ++first ) + { + std::size_t s3( s2 ); + + hash_combine::value_type>( s3, *first ); + + r += s3; + } + + seed += r; + } + + template + inline std::size_t hash_unordered_range( It first, It last ) + { + std::size_t seed = 0; + + hash_unordered_range( seed, first, last ); + + return seed; + } + + // + // boost::hash + // + + template struct hash + { + typedef T argument_type; + typedef std::size_t result_type; + + std::size_t operator()( T const& val ) const + { + return hash_value( val ); + } + }; + +#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 ) ) + + // Dinkumware has stdext::hash_value for basic_string in :-/ + + template struct hash< std::basic_string > + { + typedef std::basic_string argument_type; + typedef std::size_t result_type; + + std::size_t operator()( std::basic_string const& val ) const + { + return boost::hash_value( val ); + } + }; + +#endif + + // 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 + +#if !defined(BOOST_NO_CXX17_HDR_STRING_VIEW) + + template struct hash_is_avalanching< boost::hash< std::basic_string_view > >: boost::is_integral {}; + +#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 + } // namespace unordered + +} // namespace boost + +#endif // #ifndef BOOST_FUNCTIONAL_HASH_HASH_HPP diff --git a/third_party/boost/libs/container_hash/include/boost/container_hash/hash_fwd.hpp b/third_party/boost/libs/container_hash/include/boost/container_hash/hash_fwd.hpp new file mode 100644 index 00000000000..32388ac5450 --- /dev/null +++ b/third_party/boost/libs/container_hash/include/boost/container_hash/hash_fwd.hpp @@ -0,0 +1,37 @@ +// Copyright 2005-2009 Daniel James. +// Copyright 2021, 2022 Peter Dimov. +// Distributed under the Boost Software License, Version 1.0. +// https://www.boost.org/LICENSE_1_0.txt + +#ifndef BOOST_FUNCTIONAL_HASH_FWD_HPP +#define BOOST_FUNCTIONAL_HASH_FWD_HPP + +#include + +namespace boost +{ + +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 void hash_unordered_range( std::size_t&, It, It ); +template std::size_t hash_unordered_range( It, It ); + +} // namespace boost + +#endif // #ifndef BOOST_FUNCTIONAL_HASH_FWD_HPP diff --git a/third_party/boost/libs/container_hash/include/boost/container_hash/is_contiguous_range.hpp b/third_party/boost/libs/container_hash/include/boost/container_hash/is_contiguous_range.hpp new file mode 100644 index 00000000000..96043ccd5fa --- /dev/null +++ b/third_party/boost/libs/container_hash/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/third_party/boost/libs/container_hash/include/boost/container_hash/is_described_class.hpp b/third_party/boost/libs/container_hash/include/boost/container_hash/is_described_class.hpp new file mode 100644 index 00000000000..cd2e1db4d03 --- /dev/null +++ b/third_party/boost/libs/container_hash/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/third_party/boost/libs/container_hash/include/boost/container_hash/is_range.hpp b/third_party/boost/libs/container_hash/include/boost/container_hash/is_range.hpp new file mode 100644 index 00000000000..2d3746cd2b6 --- /dev/null +++ b/third_party/boost/libs/container_hash/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/third_party/boost/libs/container_hash/include/boost/container_hash/is_tuple_like.hpp b/third_party/boost/libs/container_hash/include/boost/container_hash/is_tuple_like.hpp new file mode 100644 index 00000000000..8f57364e298 --- /dev/null +++ b/third_party/boost/libs/container_hash/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/third_party/boost/libs/container_hash/include/boost/container_hash/is_unordered_range.hpp b/third_party/boost/libs/container_hash/include/boost/container_hash/is_unordered_range.hpp new file mode 100644 index 00000000000..11ee386cd22 --- /dev/null +++ b/third_party/boost/libs/container_hash/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/third_party/boost/libs/container_hash/include/boost/functional/hash.hpp b/third_party/boost/libs/container_hash/include/boost/functional/hash.hpp new file mode 100644 index 00000000000..327a3ecae76 --- /dev/null +++ b/third_party/boost/libs/container_hash/include/boost/functional/hash.hpp @@ -0,0 +1,6 @@ + +// 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) + +#include diff --git a/third_party/boost/libs/container_hash/include/boost/functional/hash/extensions.hpp b/third_party/boost/libs/container_hash/include/boost/functional/hash/extensions.hpp new file mode 100644 index 00000000000..ab14211d749 --- /dev/null +++ b/third_party/boost/libs/container_hash/include/boost/functional/hash/extensions.hpp @@ -0,0 +1,6 @@ + +// Copyright 2017 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) + +#include diff --git a/third_party/boost/libs/container_hash/include/boost/functional/hash/hash.hpp b/third_party/boost/libs/container_hash/include/boost/functional/hash/hash.hpp new file mode 100644 index 00000000000..327a3ecae76 --- /dev/null +++ b/third_party/boost/libs/container_hash/include/boost/functional/hash/hash.hpp @@ -0,0 +1,6 @@ + +// 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) + +#include diff --git a/third_party/boost/libs/container_hash/include/boost/functional/hash/hash_fwd.hpp b/third_party/boost/libs/container_hash/include/boost/functional/hash/hash_fwd.hpp new file mode 100644 index 00000000000..62bc23c73b9 --- /dev/null +++ b/third_party/boost/libs/container_hash/include/boost/functional/hash/hash_fwd.hpp @@ -0,0 +1,6 @@ + +// 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) + +#include diff --git a/third_party/boost/libs/container_hash/include/boost/functional/hash_fwd.hpp b/third_party/boost/libs/container_hash/include/boost/functional/hash_fwd.hpp new file mode 100644 index 00000000000..62bc23c73b9 --- /dev/null +++ b/third_party/boost/libs/container_hash/include/boost/functional/hash_fwd.hpp @@ -0,0 +1,6 @@ + +// 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) + +#include diff --git a/third_party/boost/libs/describe/CMakeLists.txt b/third_party/boost/libs/describe/CMakeLists.txt new file mode 100644 index 00000000000..87bb415c130 --- /dev/null +++ b/third_party/boost/libs/describe/CMakeLists.txt @@ -0,0 +1,25 @@ +# Generated by `boostdep --cmake describe` +# Copyright 2020 Peter Dimov +# Distributed under the Boost Software License, Version 1.0. +# https://www.boost.org/LICENSE_1_0.txt + +cmake_minimum_required(VERSION 3.5...3.16) + +project(boost_describe VERSION "${BOOST_SUPERPROJECT_VERSION}" LANGUAGES CXX) + +add_library(boost_describe INTERFACE) +add_library(Boost::describe ALIAS boost_describe) + +target_include_directories(boost_describe INTERFACE include) + +target_link_libraries(boost_describe + INTERFACE + Boost::mp11 +) + +if(BUILD_TESTING AND EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/test/CMakeLists.txt") + + add_subdirectory(test) + +endif() + diff --git a/third_party/boost/libs/describe/README.md b/third_party/boost/libs/describe/README.md new file mode 100644 index 00000000000..228acc95a62 --- /dev/null +++ b/third_party/boost/libs/describe/README.md @@ -0,0 +1,20 @@ +# Describe + +A C++14 reflection library. Provides macros for describing enumerators and +struct/class members, and primitives for querying this information. See +[the documentation](https://www.boost.org/doc/libs/develop/libs/describe/) +for more information and usage examples. + +## Supported Compilers + +* GCC 5 or later with `-std=c++14` or above +* Clang 3.9 or later with `-std=c++14` or above +* Visual Studio 2015 or later + +Tested on [Github Actions](https://github.com/boostorg/describe/actions) and +[Appveyor](https://ci.appveyor.com/project/pdimov/describe). + +## License + +Distributed under the +[Boost Software License, Version 1.0](http://boost.org/LICENSE_1_0.txt). diff --git a/third_party/boost/libs/describe/include/boost/describe.hpp b/third_party/boost/libs/describe/include/boost/describe.hpp new file mode 100644 index 00000000000..de3c8835c17 --- /dev/null +++ b/third_party/boost/libs/describe/include/boost/describe.hpp @@ -0,0 +1,21 @@ +#ifndef BOOST_DESCRIBE_HPP_INCLUDED +#define BOOST_DESCRIBE_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 +#include +#include +#include +#include +#include +#include +#include + +#endif // #ifndef BOOST_DESCRIBE_HPP_INCLUDED diff --git a/third_party/boost/libs/describe/include/boost/describe/bases.hpp b/third_party/boost/libs/describe/include/boost/describe/bases.hpp new file mode 100644 index 00000000000..b01313e046a --- /dev/null +++ b/third_party/boost/libs/describe/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/third_party/boost/libs/describe/include/boost/describe/class.hpp b/third_party/boost/libs/describe/include/boost/describe/class.hpp new file mode 100644 index 00000000000..8d3fdcbd830 --- /dev/null +++ b/third_party/boost/libs/describe/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/third_party/boost/libs/describe/include/boost/describe/descriptor_by_name.hpp b/third_party/boost/libs/describe/include/boost/describe/descriptor_by_name.hpp new file mode 100644 index 00000000000..141f4649ec0 --- /dev/null +++ b/third_party/boost/libs/describe/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/third_party/boost/libs/describe/include/boost/describe/descriptor_by_pointer.hpp b/third_party/boost/libs/describe/include/boost/describe/descriptor_by_pointer.hpp new file mode 100644 index 00000000000..9ef31a1912a --- /dev/null +++ b/third_party/boost/libs/describe/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/third_party/boost/libs/describe/include/boost/describe/detail/bases.hpp b/third_party/boost/libs/describe/include/boost/describe/detail/bases.hpp new file mode 100644 index 00000000000..04c82524818 --- /dev/null +++ b/third_party/boost/libs/describe/include/boost/describe/detail/bases.hpp @@ -0,0 +1,54 @@ +#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(); +}; + +template constexpr unsigned base_descriptor::modifiers; + +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/third_party/boost/libs/describe/include/boost/describe/detail/compute_base_modifiers.hpp b/third_party/boost/libs/describe/include/boost/describe/detail/compute_base_modifiers.hpp new file mode 100644 index 00000000000..7da2cf2457b --- /dev/null +++ b/third_party/boost/libs/describe/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/third_party/boost/libs/describe/include/boost/describe/detail/config.hpp b/third_party/boost/libs/describe/include/boost/describe/detail/config.hpp new file mode 100644 index 00000000000..c24a070e322 --- /dev/null +++ b/third_party/boost/libs/describe/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/third_party/boost/libs/describe/include/boost/describe/detail/cx_streq.hpp b/third_party/boost/libs/describe/include/boost/describe/detail/cx_streq.hpp new file mode 100644 index 00000000000..15e87dc2705 --- /dev/null +++ b/third_party/boost/libs/describe/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/third_party/boost/libs/describe/include/boost/describe/detail/list.hpp b/third_party/boost/libs/describe/include/boost/describe/detail/list.hpp new file mode 100644 index 00000000000..0b20892217e --- /dev/null +++ b/third_party/boost/libs/describe/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/third_party/boost/libs/describe/include/boost/describe/detail/members.hpp b/third_party/boost/libs/describe/include/boost/describe/detail/members.hpp new file mode 100644 index 00000000000..2509acf26ad --- /dev/null +++ b/third_party/boost/libs/describe/include/boost/describe/detail/members.hpp @@ -0,0 +1,82 @@ +#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() ); +}; + +template constexpr decltype(D::pointer()) member_descriptor::pointer; +template constexpr decltype(D::name()) member_descriptor::name; +template constexpr unsigned member_descriptor::modifiers; + +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/third_party/boost/libs/describe/include/boost/describe/detail/pp_for_each.hpp b/third_party/boost/libs/describe/include/boost/describe/detail/pp_for_each.hpp new file mode 100644 index 00000000000..ab1287f820b --- /dev/null +++ b/third_party/boost/libs/describe/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/third_party/boost/libs/describe/include/boost/describe/detail/pp_utilities.hpp b/third_party/boost/libs/describe/include/boost/describe/detail/pp_utilities.hpp new file mode 100644 index 00000000000..860f4812d22 --- /dev/null +++ b/third_party/boost/libs/describe/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/third_party/boost/libs/describe/include/boost/describe/detail/void_t.hpp b/third_party/boost/libs/describe/include/boost/describe/detail/void_t.hpp new file mode 100644 index 00000000000..f304250d853 --- /dev/null +++ b/third_party/boost/libs/describe/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/third_party/boost/libs/describe/include/boost/describe/enum.hpp b/third_party/boost/libs/describe/include/boost/describe/enum.hpp new file mode 100644 index 00000000000..e679c95e21a --- /dev/null +++ b/third_party/boost/libs/describe/include/boost/describe/enum.hpp @@ -0,0 +1,111 @@ +#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(); +}; + +// GCC requires these definitions +template constexpr decltype(D::value()) enum_descriptor::value; +template constexpr decltype(D::name()) enum_descriptor::name; + +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/third_party/boost/libs/describe/include/boost/describe/enum_from_string.hpp b/third_party/boost/libs/describe/include/boost/describe/enum_from_string.hpp new file mode 100644 index 00000000000..3bdc4cf23fb --- /dev/null +++ b/third_party/boost/libs/describe/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/third_party/boost/libs/describe/include/boost/describe/enum_to_string.hpp b/third_party/boost/libs/describe/include/boost/describe/enum_to_string.hpp new file mode 100644 index 00000000000..b06e3ac484a --- /dev/null +++ b/third_party/boost/libs/describe/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/third_party/boost/libs/describe/include/boost/describe/enumerators.hpp b/third_party/boost/libs/describe/include/boost/describe/enumerators.hpp new file mode 100644 index 00000000000..f50c47084a3 --- /dev/null +++ b/third_party/boost/libs/describe/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/third_party/boost/libs/describe/include/boost/describe/members.hpp b/third_party/boost/libs/describe/include/boost/describe/members.hpp new file mode 100644 index 00000000000..bce49db77d4 --- /dev/null +++ b/third_party/boost/libs/describe/include/boost/describe/members.hpp @@ -0,0 +1,159 @@ +#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; + }; +}; + +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; + +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/third_party/boost/libs/describe/include/boost/describe/modifier_description.hpp b/third_party/boost/libs/describe/include/boost/describe/modifier_description.hpp new file mode 100644 index 00000000000..8429665bfca --- /dev/null +++ b/third_party/boost/libs/describe/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/third_party/boost/libs/describe/include/boost/describe/modifiers.hpp b/third_party/boost/libs/describe/include/boost/describe/modifiers.hpp new file mode 100644 index 00000000000..06650ea1d36 --- /dev/null +++ b/third_party/boost/libs/describe/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/third_party/boost/libs/describe/include/boost/describe/operators.hpp b/third_party/boost/libs/describe/include/boost/describe/operators.hpp new file mode 100644 index 00000000000..780ce94cf3c --- /dev/null +++ b/third_party/boost/libs/describe/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/third_party/boost/libs/intrusive/CMakeLists.txt b/third_party/boost/libs/intrusive/CMakeLists.txt new file mode 100644 index 00000000000..08d8abccc29 --- /dev/null +++ b/third_party/boost/libs/intrusive/CMakeLists.txt @@ -0,0 +1,22 @@ +# Copyright 2019 Mike Dev +# Copyright 2023 Ion Gaztanaga +# Distributed under the Boost Software License, Version 1.0. +# See accompanying file LICENSE_1_0.txt or copy at https://www.boost.org/LICENSE_1_0.txt + +cmake_minimum_required( VERSION 3.5...3.20 ) + +project( boost_intrusive VERSION "${BOOST_SUPERPROJECT_VERSION}" LANGUAGES CXX ) + +add_library( boost_intrusive INTERFACE ) +add_library( Boost::intrusive ALIAS boost_intrusive ) + +target_include_directories( boost_intrusive INTERFACE include ) + +target_link_libraries( boost_intrusive + INTERFACE + Boost::assert + Boost::config + Boost::container_hash + Boost::move + Boost::static_assert +) diff --git a/third_party/boost/libs/intrusive/README.md b/third_party/boost/libs/intrusive/README.md new file mode 100644 index 00000000000..e14bd38c87a --- /dev/null +++ b/third_party/boost/libs/intrusive/README.md @@ -0,0 +1,40 @@ +Boost.Intrusive +========== + +Boost.Intrusive, part of collection of the [Boost C++ Libraries](http://github.com/boostorg), is a library presenting intrusive containers to the world of C++. Intrusive containers are special containers that offer better performance and exception safety guarantees than non-intrusive containers (like STL containers). The performance benefits of intrusive containers makes them ideal as a building block to efficiently construct complex data structures like multi-index containers or to design high performance code like memory allocation algorithms. + +While intrusive containers were and are widely used in C, they became more and more forgotten in C++ due to the presence of the standard containers which don't support intrusive techniques.Boost.Intrusive wants to push intrusive containers usage encapsulating the implementation in STL-like interfaces. Hence anyone familiar with standard containers can easily use Boost.Intrusive. + +### License + +Distributed under the [Boost Software License, Version 1.0](http://www.boost.org/LICENSE_1_0.txt). + +### Properties + +* C++03 +* Header-Only + +### Build Status + +Branch | Travis | Appveyor | Coverity Scan | codecov.io | Deps | Docs | Tests | +:-------------: | ------ | -------- | ------------- | ---------- | ---- | ---- | ----- | +[`master`](https://github.com/boostorg/intrusive/tree/master) | [![Build Status](https://travis-ci.org/boostorg/intrusive.svg?branch=master)](https://travis-ci.org/boostorg/intrusive) | [![Build status](https://ci.appveyor.com/api/projects/status/9ckrveolxsonxfnb/branch/master?svg=true)](https://ci.appveyor.com/project/jeking3/intrusive-0k1xg/branch/master) | [![Coverity Scan Build Status](https://scan.coverity.com/projects/16048/badge.svg)](https://scan.coverity.com/projects/boostorg-intrusive) | [![codecov](https://codecov.io/gh/boostorg/intrusive/branch/master/graph/badge.svg)](https://codecov.io/gh/boostorg/intrusive/branch/master)| [![Deps](https://img.shields.io/badge/deps-master-brightgreen.svg)](https://pdimov.github.io/boostdep-report/master/intrusive.html) | [![Documentation](https://img.shields.io/badge/docs-master-brightgreen.svg)](http://www.boost.org/doc/libs/master/doc/html/intrusive.html) | [![Enter the Matrix](https://img.shields.io/badge/matrix-master-brightgreen.svg)](http://www.boost.org/development/tests/master/developer/intrusive.html) +[`develop`](https://github.com/boostorg/intrusive/tree/develop) | [![Build Status](https://travis-ci.org/boostorg/intrusive.svg?branch=develop)](https://travis-ci.org/boostorg/intrusive) | [![Build status](https://ci.appveyor.com/api/projects/status/9ckrveolxsonxfnb/branch/develop?svg=true)](https://ci.appveyor.com/project/jeking3/intrusive-0k1xg/branch/develop) | [![Coverity Scan Build Status](https://scan.coverity.com/projects/16048/badge.svg)](https://scan.coverity.com/projects/boostorg-intrusive) | [![codecov](https://codecov.io/gh/boostorg/intrusive/branch/develop/graph/badge.svg)](https://codecov.io/gh/boostorg/intrusive/branch/develop) | [![Deps](https://img.shields.io/badge/deps-develop-brightgreen.svg)](https://pdimov.github.io/boostdep-report/develop/intrusive.html) | [![Documentation](https://img.shields.io/badge/docs-develop-brightgreen.svg)](http://www.boost.org/doc/libs/develop/doc/html/intrusive.html) | [![Enter the Matrix](https://img.shields.io/badge/matrix-develop-brightgreen.svg)](http://www.boost.org/development/tests/develop/developer/intrusive.html) + +### Directories + +| Name | Purpose | +| ----------- | ------------------------------ | +| `doc` | documentation | +| `example` | examples | +| `include` | headers | +| `proj` | ide projects | +| `test` | unit tests | + +### More information + +* [Ask questions](http://stackoverflow.com/questions/ask?tags=c%2B%2B,boost,boost-intrusive) +* [Report bugs](https://github.com/boostorg/intrusive/issues): Be sure to mention Boost version, platform and compiler you're using. A small compilable code sample to reproduce the problem is always good as well. +* Submit your patches as pull requests against **develop** branch. Note that by submitting patches you agree to license your modifications under the [Boost Software License, Version 1.0](http://www.boost.org/LICENSE_1_0.txt). +* Discussions about the library are held on the [Boost developers mailing list](http://www.boost.org/community/groups.html#main). Be sure to read the [discussion policy](http://www.boost.org/community/policy.html) before posting and add the `[intrusive]` tag at the beginning of the subject line. + diff --git a/third_party/boost/libs/intrusive/include/boost/intrusive/any_hook.hpp b/third_party/boost/libs/intrusive/include/boost/intrusive/any_hook.hpp new file mode 100644 index 00000000000..72abc9ee2ee --- /dev/null +++ b/third_party/boost/libs/intrusive/include/boost/intrusive/any_hook.hpp @@ -0,0 +1,338 @@ +///////////////////////////////////////////////////////////////////////////// +// +// (C) Copyright Ion Gaztanaga 2006-2013 +// +// 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_ANY_HOOK_HPP +#define BOOST_INTRUSIVE_ANY_HOOK_HPP + +#include +#include +#include +#include +#include +#include +#include + +#if defined(BOOST_HAS_PRAGMA_ONCE) +# pragma once +#endif + +namespace boost { +namespace intrusive { + +//! Helper metafunction to define a \c \c any_base_hook that yields to the same +//! type when the same options (either explicitly or implicitly) are used. +#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED) || defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES) +template +#else +template +#endif +struct make_any_base_hook +{ + /// @cond + typedef typename pack_options + < hook_defaults, + #if !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES) + O1, O2, O3 + #else + Options... + #endif + >::type packed_options; + + typedef generic_hook + < AnyAlgorithm + , any_node_traits + , typename packed_options::tag + , packed_options::link_mode + , AnyBaseHookId + > implementation_defined; + /// @endcond + typedef implementation_defined type; +}; + +//! Derive a class from this hook in order to store objects of that class +//! in an intrusive container. +//! +//! The hook admits the following options: \c tag<>, \c void_pointer<> and +//! \c link_mode<>. +//! +//! \c tag<> defines a tag to identify the node. +//! The same tag value can be used in different classes, but if a class is +//! derived from more than one \c any_base_hook, then each \c any_base_hook needs its +//! unique tag. +//! +//! \c link_mode<> will specify the linking mode of the hook (\c normal_link, \c safe_link). +//! +//! \c void_pointer<> is the pointer type that will be used internally in the hook +//! and the container configured to use this hook. +#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED) || defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES) +template +#else +template +#endif +class any_base_hook + : public make_any_base_hook + #if !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES) + + #else + + #endif + ::type +{ + #if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED) + public: + //! Effects: If link_mode is or \c safe_link + //! initializes the node to an unlinked state. + //! + //! Throws: Nothing. + any_base_hook(); + + //! Effects: If link_mode is or \c safe_link + //! initializes the node to an unlinked state. The argument is ignored. + //! + //! Throws: Nothing. + //! + //! Rationale: Providing a copy-constructor + //! 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_base_hook(const any_base_hook& ); + + //! Effects: Empty function. The argument is ignored. + //! + //! Throws: Nothing. + //! + //! Rationale: Providing an assignment operator + //! 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_base_hook& operator=(const any_base_hook& ); + + //! 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 + //! object is stored in a container an assertion is raised. + //! + //! Throws: Nothing. + ~any_base_hook(); + + //! Precondition: link_mode must be \c safe_link. + //! + //! Returns: true, if the node belongs to a container, false + //! otherwise. This function can be used to test whether \c container::iterator_to + //! will return a valid iterator. + //! + //! Complexity: Constant + bool is_linked() const; + #endif +}; + +//! Helper metafunction to define a \c \c any_member_hook that yields to the same +//! type when the same options (either explicitly or implicitly) are used. +#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED) || defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES) +template +#else +template +#endif +struct make_any_member_hook +{ + /// @cond + typedef typename pack_options + < hook_defaults, + #if !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES) + O1, O2, O3 + #else + Options... + #endif + >::type packed_options; + + typedef generic_hook + < AnyAlgorithm + , any_node_traits + , member_tag + , packed_options::link_mode + , NoBaseHookId + > implementation_defined; + /// @endcond + typedef implementation_defined type; +}; + +//! Store this hook in a class to be inserted +//! in an intrusive container. +//! +//! The hook admits the following options: \c void_pointer<> and +//! \c link_mode<>. +//! +//! \c link_mode<> will specify the linking mode of the hook (\c normal_link or \c safe_link). +//! +//! \c void_pointer<> is the pointer type that will be used internally in the hook +//! and the container configured to use this hook. +#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED) || defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES) +template +#else +template +#endif +class any_member_hook + : public make_any_member_hook + #if !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES) + + #else + + #endif + ::type +{ + #if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED) + public: + //! Effects: If link_mode is or \c safe_link + //! initializes the node to an unlinked state. + //! + //! Throws: Nothing. + 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. + //! + //! Throws: Nothing. + //! + //! Rationale: Providing a copy-constructor + //! 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&) BOOST_NOEXCEPT; + + //! Effects: Empty function. The argument is ignored. + //! + //! Throws: Nothing. + //! + //! Rationale: Providing an assignment operator + //! 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&) 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 + //! object is stored in a container an assertion is raised. + //! + //! Throws: Nothing. + ~any_member_hook(); + + //! Precondition: link_mode must be \c safe_link. + //! + //! Returns: true, if the node belongs to a container, false + //! otherwise. This function can be used to test whether \c container::iterator_to + //! will return a valid iterator. + //! + //! Complexity: Constant + bool is_linked() const BOOST_NOEXCEPT; + #endif +}; + +/// @cond + +namespace detail{ + +BOOST_INTRUSIVE_INTERNAL_STATIC_BOOL_IS_TRUE(old_proto_value_traits_base_hook, hooktags::is_base_hook) + +//!This option setter specifies that the container +//!must use the specified base hook +template class NodeTraits> +struct any_to_some_hook +{ + typedef typename BasicHook::template pack::proto_value_traits old_proto_value_traits; + + template + struct pack : public Base + { + struct proto_value_traits + { + //proto_value_traits::hooktags::is_base_hook is used by get_value_traits + //to detect base hooks, so mark it in case BasicHook has it. + struct hooktags + { + static const bool is_base_hook = old_proto_value_traits_base_hook_bool_is_true + ::value; + }; + + typedef old_proto_value_traits basic_hook_t; + static const bool is_any_hook = true; + + template + struct node_traits_from_voidptr + { typedef NodeTraits type; }; + }; + }; +}; + +} //namespace detail{ + +/// @endcond + +//!This option setter specifies that +//!any hook should behave as an slist hook +template +struct any_to_slist_hook +/// @cond + : public detail::any_to_some_hook +/// @endcond +{}; + +//!This option setter specifies that +//!any hook should behave as an list hook +template +struct any_to_list_hook +/// @cond + : public detail::any_to_some_hook +/// @endcond +{}; + +//!This option setter specifies that +//!any hook should behave as a set hook +template +struct any_to_set_hook +/// @cond + : public detail::any_to_some_hook +/// @endcond +{}; + +//!This option setter specifies that +//!any hook should behave as an avl_set hook +template +struct any_to_avl_set_hook +/// @cond + : public detail::any_to_some_hook +/// @endcond +{}; + +//!This option setter specifies that any +//!hook should behave as a bs_set hook +template +struct any_to_bs_set_hook +/// @cond + : public detail::any_to_some_hook +/// @endcond +{}; + +//!This option setter specifies that any hook +//!should behave as an unordered set hook +template +struct any_to_unordered_set_hook +/// @cond + : public detail::any_to_some_hook +/// @endcond +{}; + + +} //namespace intrusive +} //namespace boost + +#include + +#endif //BOOST_INTRUSIVE_ANY_HOOK_HPP diff --git a/third_party/boost/libs/intrusive/include/boost/intrusive/avl_set.hpp b/third_party/boost/libs/intrusive/include/boost/intrusive/avl_set.hpp new file mode 100644 index 00000000000..b03d304590c --- /dev/null +++ b/third_party/boost/libs/intrusive/include/boost/intrusive/avl_set.hpp @@ -0,0 +1,1073 @@ +///////////////////////////////////////////////////////////////////////////// +// +// (C) Copyright Ion Gaztanaga 2007-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_AVL_SET_HPP +#define BOOST_INTRUSIVE_AVL_SET_HPP + +#include +#include +#include +#include +#include +#include + +#if defined(BOOST_HAS_PRAGMA_ONCE) +# pragma once +#endif + +namespace boost { +namespace intrusive { + +#if !defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED) +template +class avl_multiset_impl; +#endif + +//! The class template avl_set is an intrusive container, that mimics most of +//! the interface of std::set as described in the C++ standard. +//! +//! The template parameter \c T is the type to be managed by the container. +//! The user can specify additional options and if no options are provided +//! default options are used. +//! +//! The container supports the following options: +//! \c base_hook<>/member_hook<>/value_traits<>, +//! \c constant_time_size<>, \c size_type<> and +//! \c compare<>. +#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED) +template +#else +template +#endif +class avl_set_impl +#ifndef BOOST_INTRUSIVE_DOXYGEN_INVOKED + : public bstree_impl +#endif +{ + /// @cond + typedef bstree_impl tree_type; + BOOST_MOVABLE_BUT_NOT_COPYABLE(avl_set_impl) + + typedef tree_type implementation_defined; + /// @endcond + + public: + typedef typename implementation_defined::value_type value_type; + typedef typename implementation_defined::key_type key_type; + typedef typename implementation_defined::key_of_value key_of_value; + typedef typename implementation_defined::value_traits value_traits; + typedef typename implementation_defined::pointer pointer; + typedef typename implementation_defined::const_pointer const_pointer; + typedef typename implementation_defined::reference reference; + typedef typename implementation_defined::const_reference const_reference; + typedef typename implementation_defined::difference_type difference_type; + typedef typename implementation_defined::size_type size_type; + typedef typename implementation_defined::value_compare value_compare; + typedef typename implementation_defined::key_compare key_compare; + typedef typename implementation_defined::iterator iterator; + typedef typename implementation_defined::const_iterator const_iterator; + typedef typename implementation_defined::reverse_iterator reverse_iterator; + typedef typename implementation_defined::const_reverse_iterator const_reverse_iterator; + typedef typename implementation_defined::insert_commit_data insert_commit_data; + typedef typename implementation_defined::node_traits node_traits; + 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; + + static const bool constant_time_size = tree_type::constant_time_size; + + public: + + //! @copydoc ::boost::intrusive::avltree::avltree() + avl_set_impl() + : tree_type() + {} + + //! @copydoc ::boost::intrusive::avltree::avltree(const key_compare &,const value_traits &) + explicit avl_set_impl( const key_compare &cmp, const value_traits &v_traits = value_traits()) + : tree_type(cmp, v_traits) + {} + + //! @copydoc ::boost::intrusive::avltree::avltree(bool,Iterator,Iterator,const key_compare &,const value_traits &) + template + avl_set_impl( Iterator b, Iterator e + , const key_compare &cmp = key_compare() + , const value_traits &v_traits = value_traits()) + : tree_type(true, b, e, cmp, v_traits) + {} + + //! @copydoc ::boost::intrusive::avltree::avltree(avltree &&) + avl_set_impl(BOOST_RV_REF(avl_set_impl) x) + : tree_type(BOOST_MOVE_BASE(tree_type, x)) + {} + + //! @copydoc ::boost::intrusive::avltree::operator=(avltree &&) + avl_set_impl& operator=(BOOST_RV_REF(avl_set_impl) x) + { return static_cast(tree_type::operator=(BOOST_MOVE_BASE(tree_type, x))); } + + #ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED + + //! @copydoc ::boost::intrusive::avltree::~avltree() + ~avl_set_impl(); + + //! @copydoc ::boost::intrusive::avltree::begin() + iterator begin() BOOST_NOEXCEPT; + + //! @copydoc ::boost::intrusive::avltree::begin()const + const_iterator begin() const BOOST_NOEXCEPT; + + //! @copydoc ::boost::intrusive::avltree::cbegin()const + const_iterator cbegin() const BOOST_NOEXCEPT; + + //! @copydoc ::boost::intrusive::avltree::end() + iterator end() BOOST_NOEXCEPT; + + //! @copydoc ::boost::intrusive::avltree::end()const + const_iterator end() const BOOST_NOEXCEPT; + + //! @copydoc ::boost::intrusive::avltree::cend()const + const_iterator cend() const BOOST_NOEXCEPT; + + //! @copydoc ::boost::intrusive::avltree::begin() + reverse_iterator avlegin(); + + //! @copydoc ::boost::intrusive::avltree::begin()const + const_reverse_iterator avlegin() const; + + //! @copydoc ::boost::intrusive::avltree::crbegin()const + const_reverse_iterator crbegin() const BOOST_NOEXCEPT; + + //! @copydoc ::boost::intrusive::avltree::rend() + reverse_iterator rend() BOOST_NOEXCEPT; + + //! @copydoc ::boost::intrusive::avltree::rend()const + const_reverse_iterator rend() const BOOST_NOEXCEPT; + + //! @copydoc ::boost::intrusive::avltree::crend()const + const_reverse_iterator crend() const BOOST_NOEXCEPT; + + //! @copydoc ::boost::intrusive::avltree::root() + iterator root() BOOST_NOEXCEPT; + + //! @copydoc ::boost::intrusive::avltree::root()const + const_iterator root() const BOOST_NOEXCEPT; + + //! @copydoc ::boost::intrusive::avltree::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) 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) BOOST_NOEXCEPT; + + //! @copydoc ::boost::intrusive::avltree::container_from_iterator(iterator) + 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) BOOST_NOEXCEPT; + + //! @copydoc ::boost::intrusive::avltree::key_comp()const + key_compare key_comp() const; + + //! @copydoc ::boost::intrusive::avltree::value_comp()const + value_compare value_comp() const; + + //! @copydoc ::boost::intrusive::avltree::empty()const + bool empty() const BOOST_NOEXCEPT; + + //! @copydoc ::boost::intrusive::avltree::size()const + size_type size() const BOOST_NOEXCEPT; + + //! @copydoc ::boost::intrusive::avltree::swap + void swap(avl_set_impl& other); + + //! @copydoc ::boost::intrusive::avltree::clone_from(const avltree&,Cloner,Disposer) + template + void clone_from(const avl_set_impl &src, Cloner cloner, Disposer disposer); + + #else + + using tree_type::clone_from; + + #endif //#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED + + //! @copydoc ::boost::intrusive::avltree::clone_from(avltree&&,Cloner,Disposer) + template + void clone_from(BOOST_RV_REF(avl_set_impl) src, Cloner cloner, Disposer disposer) + { tree_type::clone_from(BOOST_MOVE_BASE(tree_type, src), cloner, disposer); } + + //! @copydoc ::boost::intrusive::avltree::insert_unique(reference) + std::pair insert(reference value) + { return tree_type::insert_unique(value); } + + //! @copydoc ::boost::intrusive::avltree::insert_unique(const_iterator,reference) + iterator insert(const_iterator hint, reference value) + { return tree_type::insert_unique(hint, value); } + + //! @copydoc ::boost::intrusive::avltree::insert_unique_check(const key_type&,insert_commit_data&) + std::pair insert_check + (const key_type &key, insert_commit_data &commit_data) + { return tree_type::insert_unique_check(key, commit_data); } + + //! @copydoc ::boost::intrusive::avltree::insert_unique_check(const_iterator,const key_type&,insert_commit_data&) + std::pair insert_check + (const_iterator hint, const key_type &key + ,insert_commit_data &commit_data) + { return tree_type::insert_unique_check(hint, key, commit_data); } + + //! @copydoc ::boost::intrusive::avltree::insert_unique_check(const KeyType&,KeyTypeKeyCompare,insert_commit_data&) + template + std::pair insert_check + (const KeyType &key, KeyTypeKeyCompare comp, insert_commit_data &commit_data) + { return tree_type::insert_unique_check(key, comp, commit_data); } + + //! @copydoc ::boost::intrusive::avltree::insert_unique_check(const_iterator,const KeyType&,KeyTypeKeyCompare,insert_commit_data&) + template + std::pair insert_check + (const_iterator hint, const KeyType &key + ,KeyTypeKeyCompare comp, insert_commit_data &commit_data) + { return tree_type::insert_unique_check(hint, key, comp, commit_data); } + + //! @copydoc ::boost::intrusive::avltree::insert_unique(Iterator,Iterator) + template + void insert(Iterator b, Iterator e) + { tree_type::insert_unique(b, e); } + + //! @copydoc ::boost::intrusive::avltree::insert_unique_commit + 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) BOOST_NOEXCEPT; + + //! @copydoc ::boost::intrusive::avltree::push_back + void push_back(reference value) BOOST_NOEXCEPT; + + //! @copydoc ::boost::intrusive::avltree::push_front + void push_front(reference value) BOOST_NOEXCEPT; + + //! @copydoc ::boost::intrusive::avltree::erase(const_iterator) + iterator erase(const_iterator i) BOOST_NOEXCEPT; + + //! @copydoc ::boost::intrusive::avltree::erase(const_iterator,const_iterator) + 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); + + //! @copydoc ::boost::intrusive::avltree::erase(const KeyType&,KeyTypeKeyCompare) + template + size_type erase(const KeyType& key, KeyTypeKeyCompare comp); + + //! @copydoc ::boost::intrusive::avltree::erase_and_dispose(const_iterator,Disposer) + template + 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) BOOST_NOEXCEPT; + + //! @copydoc ::boost::intrusive::avltree::erase_and_dispose(const key_type &, Disposer) + template + size_type erase_and_dispose(const key_type &key, Disposer disposer); + + //! @copydoc ::boost::intrusive::avltree::erase_and_dispose(const KeyType&,KeyTypeKeyCompare,Disposer) + template + size_type erase_and_dispose(const KeyType& key, KeyTypeKeyCompare comp, Disposer disposer); + + //! @copydoc ::boost::intrusive::avltree::clear + void clear() BOOST_NOEXCEPT; + + //! @copydoc ::boost::intrusive::avltree::clear_and_dispose + template + void clear_and_dispose(Disposer disposer) BOOST_NOEXCEPT; + + #endif // #ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED + + //! @copydoc ::boost::intrusive::avltree::count(const key_type &)const + size_type count(const key_type &key) const + { return static_cast(this->tree_type::find(key) != this->tree_type::cend()); } + + //! @copydoc ::boost::intrusive::avltree::count(const KeyType&,KeyTypeKeyCompare)const + template + size_type count(const KeyType& key, KeyTypeKeyCompare comp) const + { return static_cast(this->tree_type::find(key, comp) != this->tree_type::cend()); } + + #ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED + + //! @copydoc ::boost::intrusive::avltree::lower_bound(const key_type &) + iterator lower_bound(const key_type &key); + + //! @copydoc ::boost::intrusive::avltree::lower_bound(const KeyType&,KeyTypeKeyCompare) + template + iterator lower_bound(const KeyType& key, KeyTypeKeyCompare comp); + + //! @copydoc ::boost::intrusive::avltree::lower_bound(const key_type &)const + const_iterator lower_bound(const key_type &key) const; + + //! @copydoc ::boost::intrusive::avltree::lower_bound(const KeyType&,KeyTypeKeyCompare)const + template + const_iterator lower_bound(const KeyType& key, KeyTypeKeyCompare comp) const; + + //! @copydoc ::boost::intrusive::avltree::upper_bound(const key_type &) + iterator upper_bound(const key_type &key); + + //! @copydoc ::boost::intrusive::avltree::upper_bound(const KeyType&,KeyTypeKeyCompare) + template + iterator upper_bound(const KeyType& key, KeyTypeKeyCompare comp); + + //! @copydoc ::boost::intrusive::avltree::upper_bound(const key_type &)const + const_iterator upper_bound(const key_type &key) const; + + //! @copydoc ::boost::intrusive::avltree::upper_bound(const KeyType&,KeyTypeKeyCompare)const + template + const_iterator upper_bound(const KeyType& key, KeyTypeKeyCompare comp) const; + + //! @copydoc ::boost::intrusive::avltree::find(const key_type &) + iterator find(const key_type &key); + + //! @copydoc ::boost::intrusive::avltree::find(const KeyType&,KeyTypeKeyCompare) + template + iterator find(const KeyType& key, KeyTypeKeyCompare comp); + + //! @copydoc ::boost::intrusive::avltree::find(const key_type &)const + const_iterator find(const key_type &key) const; + + //! @copydoc ::boost::intrusive::avltree::find(const KeyType&,KeyTypeKeyCompare)const + template + const_iterator find(const KeyType& key, KeyTypeKeyCompare comp) const; + + #endif // #ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED + + //! @copydoc ::boost::intrusive::avltree::equal_range(const key_type &) + std::pair equal_range(const key_type &key) + { return this->tree_type::lower_bound_range(key); } + + //! @copydoc ::boost::intrusive::avltree::equal_range(const KeyType&,KeyTypeKeyCompare) + template + std::pair equal_range(const KeyType& key, KeyTypeKeyCompare comp) + { return this->tree_type::equal_range(key, comp); } + + //! @copydoc ::boost::intrusive::avltree::equal_range(const key_type &)const + std::pair + equal_range(const key_type &key) const + { return this->tree_type::lower_bound_range(key); } + + //! @copydoc ::boost::intrusive::avltree::equal_range(const KeyType&,KeyTypeKeyCompare)const + template + std::pair + equal_range(const KeyType& key, KeyTypeKeyCompare comp) const + { return this->tree_type::equal_range(key, comp); } + + #ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED + + //! @copydoc ::boost::intrusive::avltree::bounded_range(const key_type &,const key_type &,bool,bool) + std::pair bounded_range + (const key_type &lower_key, const key_type &upper_key, bool left_closed, bool right_closed); + + //! @copydoc ::boost::intrusive::avltree::bounded_range(const KeyType&,const KeyType&,KeyTypeKeyCompare,bool,bool) + template + std::pair bounded_range + (const KeyType& lower_key, const KeyType& upper_key, KeyTypeKeyCompare comp, bool left_closed, bool right_closed); + + //! @copydoc ::boost::intrusive::avltree::bounded_range(const key_type &,const key_type &,bool,bool)const + std::pair + bounded_range(const key_type &lower_key, const key_type &upper_key, bool left_closed, bool right_closed) const; + + //! @copydoc ::boost::intrusive::avltree::bounded_range(const KeyType&,const KeyType&,KeyTypeKeyCompare,bool,bool)const + template + std::pair bounded_range + (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) BOOST_NOEXCEPT; + + //! @copydoc ::boost::intrusive::avltree::s_iterator_to(const_reference) + static const_iterator s_iterator_to(const_reference value) BOOST_NOEXCEPT; + + //! @copydoc ::boost::intrusive::avltree::iterator_to(reference) + iterator iterator_to(reference value) BOOST_NOEXCEPT; + + //! @copydoc ::boost::intrusive::avltree::iterator_to(const_reference)const + const_iterator iterator_to(const_reference value) const BOOST_NOEXCEPT; + + //! @copydoc ::boost::intrusive::avltree::init_node(reference) + static void init_node(reference value) BOOST_NOEXCEPT; + + //! @copydoc ::boost::intrusive::avltree::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) BOOST_NOEXCEPT; + + //! @copydoc ::boost::intrusive::avltree::remove_node + void remove_node(reference value) BOOST_NOEXCEPT; + + //! @copydoc ::boost::intrusive::avltree::merge_unique + template + void merge(avl_set &source); + + //! @copydoc ::boost::intrusive::avltree::merge_unique + template + void merge(avl_multiset &source); + + #else + + template + void merge(avl_set_impl &source) + { return tree_type::merge_unique(source); } + + + template + void merge(avl_multiset_impl &source) + { return tree_type::merge_unique(source); } + + #endif //#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED +}; + +#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED) + +template +bool operator!= (const avl_set_impl &x, const avl_set_impl &y); + +template +bool operator>(const avl_set_impl &x, const avl_set_impl &y); + +template +bool operator<=(const avl_set_impl &x, const avl_set_impl &y); + +template +bool operator>=(const avl_set_impl &x, const avl_set_impl &y); + +template +void swap(avl_set_impl &x, avl_set_impl &y); + +#endif //#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED) + +//! Helper metafunction to define a \c set that yields to the same type when the +//! same options (either explicitly or implicitly) are used. +#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED) || defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES) +template +#else +template +#endif +struct make_avl_set +{ + /// @cond + typedef typename pack_options + < avltree_defaults, + #if !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES) + O1, O2, O3, O4, O5, O6 + #else + Options... + #endif + >::type packed_options; + + typedef typename detail::get_value_traits + ::type value_traits; + + typedef avl_set_impl + < value_traits + , typename packed_options::key_of_value + , typename packed_options::compare + , typename packed_options::size_type + , packed_options::constant_time_size + , typename packed_options::header_holder_type + > implementation_defined; + /// @endcond + typedef implementation_defined type; +}; + +#ifndef BOOST_INTRUSIVE_DOXYGEN_INVOKED +#if !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES) +template +#else +template +#endif +class avl_set + : public make_avl_set::type +{ + typedef typename make_avl_set + ::type Base; + + BOOST_MOVABLE_BUT_NOT_COPYABLE(avl_set) + public: + typedef typename Base::key_compare key_compare; + typedef typename Base::value_traits value_traits; + typedef typename Base::iterator iterator; + typedef typename Base::const_iterator const_iterator; + + //Assert if passed value traits are compatible with the type + BOOST_STATIC_ASSERT((detail::is_same::value)); + + BOOST_INTRUSIVE_FORCEINLINE avl_set() + : Base() + {} + + BOOST_INTRUSIVE_FORCEINLINE explicit avl_set( const key_compare &cmp, const value_traits &v_traits = value_traits()) + : Base(cmp, v_traits) + {} + + template + BOOST_INTRUSIVE_FORCEINLINE avl_set( Iterator b, Iterator e + , const key_compare &cmp = key_compare() + , const value_traits &v_traits = value_traits()) + : Base(b, e, cmp, v_traits) + {} + + BOOST_INTRUSIVE_FORCEINLINE avl_set(BOOST_RV_REF(avl_set) x) + : Base(BOOST_MOVE_BASE(Base, x)) + {} + + BOOST_INTRUSIVE_FORCEINLINE avl_set& operator=(BOOST_RV_REF(avl_set) x) + { return static_cast(this->Base::operator=(BOOST_MOVE_BASE(Base, x))); } + + template + BOOST_INTRUSIVE_FORCEINLINE void clone_from(const avl_set &src, Cloner cloner, Disposer disposer) + { Base::clone_from(src, cloner, disposer); } + + template + 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_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_NOEXCEPT + { return static_cast(Base::container_from_end_iterator(end_iterator)); } + + 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_NOEXCEPT + { return static_cast(Base::container_from_iterator(it)); } +}; + +#endif + +//! The class template avl_multiset is an intrusive container, that mimics most of +//! the interface of std::_multiset as described in the C++ standard. +//! +//! The template parameter \c T is the type to be managed by the container. +//! The user can specify additional options and if no options are provided +//! default options are used. +//! +//! The container supports the following options: +//! \c base_hook<>/member_hook<>/value_traits<>, +//! \c constant_time_size<>, \c size_type<> and +//! \c compare<>. +#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED) +template +#else +template +#endif +class avl_multiset_impl +#ifndef BOOST_INTRUSIVE_DOXYGEN_INVOKED + : public bstree_impl +#endif +{ + /// @cond + typedef bstree_impl tree_type; + + BOOST_MOVABLE_BUT_NOT_COPYABLE(avl_multiset_impl) + typedef tree_type implementation_defined; + /// @endcond + + public: + typedef typename implementation_defined::value_type value_type; + typedef typename implementation_defined::key_type key_type; + typedef typename implementation_defined::key_of_value key_of_value; + typedef typename implementation_defined::value_traits value_traits; + typedef typename implementation_defined::pointer pointer; + typedef typename implementation_defined::const_pointer const_pointer; + typedef typename implementation_defined::reference reference; + typedef typename implementation_defined::const_reference const_reference; + typedef typename implementation_defined::difference_type difference_type; + typedef typename implementation_defined::size_type size_type; + typedef typename implementation_defined::value_compare value_compare; + typedef typename implementation_defined::key_compare key_compare; + typedef typename implementation_defined::iterator iterator; + typedef typename implementation_defined::const_iterator const_iterator; + typedef typename implementation_defined::reverse_iterator reverse_iterator; + typedef typename implementation_defined::const_reverse_iterator const_reverse_iterator; + typedef typename implementation_defined::insert_commit_data insert_commit_data; + typedef typename implementation_defined::node_traits node_traits; + 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; + + static const bool constant_time_size = tree_type::constant_time_size; + + public: + //! @copydoc ::boost::intrusive::avltree::avltree() + avl_multiset_impl() + : tree_type() + {} + + //! @copydoc ::boost::intrusive::avltree::avltree(const key_compare &,const value_traits &) + explicit avl_multiset_impl( const key_compare &cmp, const value_traits &v_traits = value_traits()) + : tree_type(cmp, v_traits) + {} + + //! @copydoc ::boost::intrusive::avltree::avltree(bool,Iterator,Iterator,const key_compare &,const value_traits &) + template + avl_multiset_impl( Iterator b, Iterator e + , const key_compare &cmp = key_compare() + , const value_traits &v_traits = value_traits()) + : tree_type(false, b, e, cmp, v_traits) + {} + + //! @copydoc ::boost::intrusive::avltree::avltree(avltree &&) + avl_multiset_impl(BOOST_RV_REF(avl_multiset_impl) x) + : tree_type(BOOST_MOVE_BASE(tree_type, x)) + {} + + //! @copydoc ::boost::intrusive::avltree::operator=(avltree &&) + avl_multiset_impl& operator=(BOOST_RV_REF(avl_multiset_impl) x) + { return static_cast(tree_type::operator=(BOOST_MOVE_BASE(tree_type, x))); } + + #ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED + //! @copydoc ::boost::intrusive::avltree::~avltree() + ~avl_multiset_impl(); + + //! @copydoc ::boost::intrusive::avltree::begin() + iterator begin() BOOST_NOEXCEPT; + + //! @copydoc ::boost::intrusive::avltree::begin()const + const_iterator begin() const BOOST_NOEXCEPT; + + //! @copydoc ::boost::intrusive::avltree::cbegin()const + const_iterator cbegin() const BOOST_NOEXCEPT; + + //! @copydoc ::boost::intrusive::avltree::end() + iterator end() BOOST_NOEXCEPT; + + //! @copydoc ::boost::intrusive::avltree::end()const + const_iterator end() const BOOST_NOEXCEPT; + + //! @copydoc ::boost::intrusive::avltree::cend()const + const_iterator cend() const BOOST_NOEXCEPT; + + //! @copydoc ::boost::intrusive::avltree::rbegin() + reverse_iterator rbegin() BOOST_NOEXCEPT; + + //! @copydoc ::boost::intrusive::avltree::rbegin()const + const_reverse_iterator rbegin() const BOOST_NOEXCEPT; + + //! @copydoc ::boost::intrusive::avltree::crbegin()const + const_reverse_iterator crbegin() const BOOST_NOEXCEPT; + + //! @copydoc ::boost::intrusive::avltree::rend() + reverse_iterator rend() BOOST_NOEXCEPT; + + //! @copydoc ::boost::intrusive::avltree::rend()const + const_reverse_iterator rend() const BOOST_NOEXCEPT; + + //! @copydoc ::boost::intrusive::avltree::crend()const + const_reverse_iterator crend() const BOOST_NOEXCEPT; + + //! @copydoc ::boost::intrusive::avltree::root() + iterator root() BOOST_NOEXCEPT; + + //! @copydoc ::boost::intrusive::avltree::root()const + const_iterator root() const BOOST_NOEXCEPT; + + //! @copydoc ::boost::intrusive::avltree::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) 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) BOOST_NOEXCEPT; + + //! @copydoc ::boost::intrusive::avltree::container_from_iterator(iterator) + 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) BOOST_NOEXCEPT; + + //! @copydoc ::boost::intrusive::avltree::key_comp()const + key_compare key_comp() const; + + //! @copydoc ::boost::intrusive::avltree::value_comp()const + value_compare value_comp() const; + + //! @copydoc ::boost::intrusive::avltree::empty()const + bool empty() const BOOST_NOEXCEPT; + + //! @copydoc ::boost::intrusive::avltree::size()const + size_type size() const BOOST_NOEXCEPT; + + //! @copydoc ::boost::intrusive::avltree::swap + void swap(avl_multiset_impl& other); + + //! @copydoc ::boost::intrusive::avltree::clone_from(const avltree&,Cloner,Disposer) + template + void clone_from(const avl_multiset_impl &src, Cloner cloner, Disposer disposer); + + #else + + using tree_type::clone_from; + + #endif //#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED + + //! @copydoc ::boost::intrusive::avltree::clone_from(avltree&&,Cloner,Disposer) + template + void clone_from(BOOST_RV_REF(avl_multiset_impl) src, Cloner cloner, Disposer disposer) + { tree_type::clone_from(BOOST_MOVE_BASE(tree_type, src), cloner, disposer); } + + //! @copydoc ::boost::intrusive::avltree::insert_equal(reference) + iterator insert(reference value) + { return tree_type::insert_equal(value); } + + //! @copydoc ::boost::intrusive::avltree::insert_equal(const_iterator,reference) + iterator insert(const_iterator hint, reference value) + { return tree_type::insert_equal(hint, value); } + + //! @copydoc ::boost::intrusive::avltree::insert_equal(Iterator,Iterator) + template + void insert(Iterator b, Iterator e) + { tree_type::insert_equal(b, e); } + + #ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED + //! @copydoc ::boost::intrusive::avltree::insert_before + iterator insert_before(const_iterator pos, reference value) BOOST_NOEXCEPT; + + //! @copydoc ::boost::intrusive::avltree::push_back + void push_back(reference value) BOOST_NOEXCEPT; + + //! @copydoc ::boost::intrusive::avltree::push_front + void push_front(reference value) BOOST_NOEXCEPT; + + //! @copydoc ::boost::intrusive::avltree::erase(const_iterator) + iterator erase(const_iterator i) BOOST_NOEXCEPT; + + //! @copydoc ::boost::intrusive::avltree::erase(const_iterator,const_iterator) + 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); + + //! @copydoc ::boost::intrusive::avltree::erase(const KeyType&,KeyTypeKeyCompare) + template + size_type erase(const KeyType& key, KeyTypeKeyCompare comp); + + //! @copydoc ::boost::intrusive::avltree::erase_and_dispose(const_iterator,Disposer) + template + 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) BOOST_NOEXCEPT; + + //! @copydoc ::boost::intrusive::avltree::erase_and_dispose(const key_type &, Disposer) + template + size_type erase_and_dispose(const key_type &key, Disposer disposer); + + //! @copydoc ::boost::intrusive::avltree::erase_and_dispose(const KeyType&,KeyTypeKeyCompare,Disposer) + template + size_type erase_and_dispose(const KeyType& key, KeyTypeKeyCompare comp, Disposer disposer); + + //! @copydoc ::boost::intrusive::avltree::clear + void clear() BOOST_NOEXCEPT; + + //! @copydoc ::boost::intrusive::avltree::clear_and_dispose + template + 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; + + //! @copydoc ::boost::intrusive::avltree::count(const KeyType&,KeyTypeKeyCompare)const + template + size_type count(const KeyType& key, KeyTypeKeyCompare comp) const; + + //! @copydoc ::boost::intrusive::avltree::lower_bound(const key_type &) + iterator lower_bound(const key_type &key); + + //! @copydoc ::boost::intrusive::avltree::lower_bound(const KeyType&,KeyTypeKeyCompare) + template + iterator lower_bound(const KeyType& key, KeyTypeKeyCompare comp); + + //! @copydoc ::boost::intrusive::avltree::lower_bound(const key_type &)const + const_iterator lower_bound(const key_type &key) const; + + //! @copydoc ::boost::intrusive::avltree::lower_bound(const KeyType&,KeyTypeKeyCompare)const + template + const_iterator lower_bound(const KeyType& key, KeyTypeKeyCompare comp) const; + + //! @copydoc ::boost::intrusive::avltree::upper_bound(const key_type &) + iterator upper_bound(const key_type &key); + + //! @copydoc ::boost::intrusive::avltree::upper_bound(const KeyType&,KeyTypeKeyCompare) + template + iterator upper_bound(const KeyType& key, KeyTypeKeyCompare comp); + + //! @copydoc ::boost::intrusive::avltree::upper_bound(const key_type &)const + const_iterator upper_bound(const key_type &key) const; + + //! @copydoc ::boost::intrusive::avltree::upper_bound(const KeyType&,KeyTypeKeyCompare)const + template + const_iterator upper_bound(const KeyType& key, KeyTypeKeyCompare comp) const; + + //! @copydoc ::boost::intrusive::avltree::find(const key_type &) + iterator find(const key_type &key); + + //! @copydoc ::boost::intrusive::avltree::find(const KeyType&,KeyTypeKeyCompare) + template + iterator find(const KeyType& key, KeyTypeKeyCompare comp); + + //! @copydoc ::boost::intrusive::avltree::find(const key_type &)const + const_iterator find(const key_type &key) const; + + //! @copydoc ::boost::intrusive::avltree::find(const KeyType&,KeyTypeKeyCompare)const + template + const_iterator find(const KeyType& key, KeyTypeKeyCompare comp) const; + + //! @copydoc ::boost::intrusive::avltree::equal_range(const key_type &) + std::pair equal_range(const key_type &key); + + //! @copydoc ::boost::intrusive::avltree::equal_range(const KeyType&,KeyTypeKeyCompare) + template + std::pair equal_range(const KeyType& key, KeyTypeKeyCompare comp); + + //! @copydoc ::boost::intrusive::avltree::equal_range(const key_type &)const + std::pair + equal_range(const key_type &key) const; + + //! @copydoc ::boost::intrusive::avltree::equal_range(const KeyType&,KeyTypeKeyCompare)const + template + std::pair + equal_range(const KeyType& key, KeyTypeKeyCompare comp) const; + + //! @copydoc ::boost::intrusive::avltree::bounded_range(const key_type &,const key_type &,bool,bool) + std::pair bounded_range + (const key_type &lower_key, const key_type &upper_key, bool left_closed, bool right_closed); + + //! @copydoc ::boost::intrusive::avltree::bounded_range(const KeyType&,const KeyType&,KeyTypeKeyCompare,bool,bool) + template + std::pair bounded_range + (const KeyType& lower_key, const KeyType& upper_key, KeyTypeKeyCompare comp, bool left_closed, bool right_closed); + + //! @copydoc ::boost::intrusive::avltree::bounded_range(const key_type &,const key_type &,bool,bool)const + std::pair + bounded_range(const key_type &lower_key, const key_type &key upper_key, bool left_closed, bool right_closed) const; + + //! @copydoc ::boost::intrusive::avltree::bounded_range(const KeyType&,const KeyType&,KeyTypeKeyCompare,bool,bool)const + template + std::pair bounded_range + (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) BOOST_NOEXCEPT; + + //! @copydoc ::boost::intrusive::avltree::s_iterator_to(const_reference) + static const_iterator s_iterator_to(const_reference value) BOOST_NOEXCEPT; + + //! @copydoc ::boost::intrusive::avltree::iterator_to(reference) + iterator iterator_to(reference value) BOOST_NOEXCEPT; + + //! @copydoc ::boost::intrusive::avltree::iterator_to(const_reference)const + const_iterator iterator_to(const_reference value) const BOOST_NOEXCEPT; + + //! @copydoc ::boost::intrusive::avltree::init_node(reference) + static void init_node(reference value) BOOST_NOEXCEPT; + + //! @copydoc ::boost::intrusive::avltree::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) BOOST_NOEXCEPT; + + //! @copydoc ::boost::intrusive::avltree::remove_node + void remove_node(reference value) BOOST_NOEXCEPT; + + //! @copydoc ::boost::intrusive::avltree::merge_equal + template + void merge(avl_multiset &source); + + //! @copydoc ::boost::intrusive::avltree::merge_equal + template + void merge(avl_set &source); + + #else + + template + void merge(avl_multiset_impl &source) + { return tree_type::merge_equal(source); } + + template + void merge(avl_set_impl &source) + { return tree_type::merge_equal(source); } + + #endif //#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED +}; + +#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED) + +template +bool operator!= (const avl_multiset_impl &x, const avl_multiset_impl &y); + +template +bool operator>(const avl_multiset_impl &x, const avl_multiset_impl &y); + +template +bool operator<=(const avl_multiset_impl &x, const avl_multiset_impl &y); + +template +bool operator>=(const avl_multiset_impl &x, const avl_multiset_impl &y); + +template +void swap(avl_multiset_impl &x, avl_multiset_impl &y); + +#endif //#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED) + +//! Helper metafunction to define a \c avl_multiset that yields to the same type when the +//! same options (either explicitly or implicitly) are used. +#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED) || defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES) +template +#else +template +#endif +struct make_avl_multiset +{ + /// @cond + typedef typename pack_options + < avltree_defaults, + #if !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES) + O1, O2, O3, O4, O5, O6 + #else + Options... + #endif + >::type packed_options; + + typedef typename detail::get_value_traits + ::type value_traits; + + typedef avl_multiset_impl + < value_traits + , typename packed_options::key_of_value + , typename packed_options::compare + , typename packed_options::size_type + , packed_options::constant_time_size + , typename packed_options::header_holder_type + > implementation_defined; + /// @endcond + typedef implementation_defined type; +}; + +#ifndef BOOST_INTRUSIVE_DOXYGEN_INVOKED + +#if !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES) +template +#else +template +#endif +class avl_multiset + : public make_avl_multiset::type +{ + typedef typename make_avl_multiset::type Base; + + BOOST_MOVABLE_BUT_NOT_COPYABLE(avl_multiset) + + public: + typedef typename Base::key_compare key_compare; + typedef typename Base::value_traits value_traits; + typedef typename Base::iterator iterator; + typedef typename Base::const_iterator const_iterator; + + //Assert if passed value traits are compatible with the type + BOOST_STATIC_ASSERT((detail::is_same::value)); + + BOOST_INTRUSIVE_FORCEINLINE avl_multiset() + : Base() + {} + + BOOST_INTRUSIVE_FORCEINLINE explicit avl_multiset( const key_compare &cmp, const value_traits &v_traits = value_traits()) + : Base(cmp, v_traits) + {} + + template + BOOST_INTRUSIVE_FORCEINLINE avl_multiset( Iterator b, Iterator e + , const key_compare &cmp = key_compare() + , const value_traits &v_traits = value_traits()) + : Base(b, e, cmp, v_traits) + {} + + BOOST_INTRUSIVE_FORCEINLINE avl_multiset(BOOST_RV_REF(avl_multiset) x) + : Base(BOOST_MOVE_BASE(Base, x)) + {} + + BOOST_INTRUSIVE_FORCEINLINE avl_multiset& operator=(BOOST_RV_REF(avl_multiset) x) + { return static_cast(this->Base::operator=(BOOST_MOVE_BASE(Base, x))); } + + template + BOOST_INTRUSIVE_FORCEINLINE void clone_from(const avl_multiset &src, Cloner cloner, Disposer disposer) + { Base::clone_from(src, cloner, disposer); } + + template + 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_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_NOEXCEPT + { return static_cast(Base::container_from_end_iterator(end_iterator)); } + + 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_NOEXCEPT + { return static_cast(Base::container_from_iterator(it)); } +}; + +#endif + +} //namespace intrusive +} //namespace boost + +#include + +#endif //BOOST_INTRUSIVE_AVL_SET_HPP diff --git a/third_party/boost/libs/intrusive/include/boost/intrusive/avl_set_hook.hpp b/third_party/boost/libs/intrusive/include/boost/intrusive/avl_set_hook.hpp new file mode 100644 index 00000000000..187130365b9 --- /dev/null +++ b/third_party/boost/libs/intrusive/include/boost/intrusive/avl_set_hook.hpp @@ -0,0 +1,293 @@ +///////////////////////////////////////////////////////////////////////////// +// +// (C) Copyright Ion Gaztanaga 2007-2013 +// +// 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_AVL_SET_HOOK_HPP +#define BOOST_INTRUSIVE_AVL_SET_HOOK_HPP + +#include +#include + +#include +#include +#include +#include + +#if defined(BOOST_HAS_PRAGMA_ONCE) +# pragma once +#endif + +namespace boost { +namespace intrusive { + +//! Helper metafunction to define a \c avl_set_base_hook that yields to the same +//! type when the same options (either explicitly or implicitly) are used. +#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED) || defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES) +template +#else +template +#endif +struct make_avl_set_base_hook +{ + /// @cond + typedef typename pack_options + #if !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES) + + #else + + #endif + ::type packed_options; + + typedef generic_hook + < AvlTreeAlgorithms + , avltree_node_traits + , typename packed_options::tag + , packed_options::link_mode + , AvlTreeBaseHookId + > implementation_defined; + /// @endcond + typedef implementation_defined type; +}; + +//! Derive a class from avl_set_base_hook in order to store objects in +//! in an avl_set/avl_multiset. avl_set_base_hook holds the data necessary to maintain +//! the avl_set/avl_multiset and provides an appropriate value_traits class for avl_set/avl_multiset. +//! +//! The hook admits the following options: \c tag<>, \c void_pointer<>, +//! \c link_mode<> and \c optimize_size<>. +//! +//! \c tag<> defines a tag to identify the node. +//! The same tag value can be used in different classes, but if a class is +//! derived from more than one \c list_base_hook, then each \c list_base_hook needs its +//! unique tag. +//! +//! \c void_pointer<> is the pointer type that will be used internally in the hook +//! and the container configured to use this hook. +//! +//! \c link_mode<> will specify the linking mode of the hook (\c normal_link, +//! \c auto_unlink or \c safe_link). +//! +//! \c optimize_size<> will tell the hook to optimize the hook for size instead +//! of speed. +#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED) || defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES) +template +#else +template +#endif +class avl_set_base_hook + : public make_avl_set_base_hook + #if !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES) + + #else + + #endif + ::type +{ + #if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED) + public: + //! Effects: If link_mode is \c auto_unlink or \c safe_link + //! initializes the node to an unlinked state. + //! + //! Throws: Nothing. + avl_set_base_hook(); + + //! Effects: If link_mode is \c auto_unlink or \c safe_link + //! initializes the node to an unlinked state. The argument is ignored. + //! + //! Throws: Nothing. + //! + //! Rationale: Providing a copy-constructor + //! 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. + avl_set_base_hook(const avl_set_base_hook& ); + + //! Effects: Empty function. The argument is ignored. + //! + //! Throws: Nothing. + //! + //! Rationale: Providing an assignment operator + //! 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. + avl_set_base_hook& operator=(const avl_set_base_hook& ); + + //! 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 + //! object is stored in a set an assertion is raised. If link_mode is + //! \c auto_unlink and \c is_linked() is true, the node is unlinked. + //! + //! Throws: Nothing. + ~avl_set_base_hook(); + + //! Effects: Swapping two nodes swaps the position of the elements + //! related to those nodes in one or two containers. That is, if the node + //! this is part of the element e1, the node x is part of the element e2 + //! and both elements are included in the containers s1 and s2, then after + //! the swap-operation e1 is in s2 at the position of e2 and e2 is in s1 + //! at the position of e1. If one element is not in a container, then + //! after the swap-operation the other element is not in a container. + //! Iterators to e1 and e2 related to those nodes are invalidated. + //! + //! Complexity: Constant + //! + //! Throws: Nothing. + void swap_nodes(avl_set_base_hook &other); + + //! Precondition: link_mode must be \c safe_link or \c auto_unlink. + //! + //! Returns: true, if the node belongs to a container, false + //! otherwise. This function can be used to test whether \c set::iterator_to + //! will return a valid iterator. + //! + //! Complexity: Constant + bool is_linked() const; + + //! 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(); + #endif +}; + +//! Helper metafunction to define a \c avl_set_member_hook that yields to the same +//! type when the same options (either explicitly or implicitly) are used. +#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED) || defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES) +template +#else +template +#endif +struct make_avl_set_member_hook +{ + /// @cond + typedef typename pack_options + #if !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES) + + #else + + #endif + ::type packed_options; + + typedef generic_hook + < AvlTreeAlgorithms + , avltree_node_traits + , member_tag + , packed_options::link_mode + , NoBaseHookId + > implementation_defined; + /// @endcond + typedef implementation_defined type; +}; + +//! Put a public data member avl_set_member_hook in order to store objects of this class in +//! an avl_set/avl_multiset. avl_set_member_hook holds the data necessary for maintaining the +//! avl_set/avl_multiset and provides an appropriate value_traits class for avl_set/avl_multiset. +//! +//! The hook admits the following options: \c void_pointer<>, +//! \c link_mode<> and \c optimize_size<>. +//! +//! \c void_pointer<> is the pointer type that will be used internally in the hook +//! and the container configured to use this hook. +//! +//! \c link_mode<> will specify the linking mode of the hook (\c normal_link, +//! \c auto_unlink or \c safe_link). +//! +//! \c optimize_size<> will tell the hook to optimize the hook for size instead +//! of speed. +#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED) || defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES) +template +#else +template +#endif +class avl_set_member_hook + : public make_avl_set_member_hook + #if !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES) + + #else + + #endif + ::type +{ + #if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED) + public: + //! Effects: If link_mode is \c auto_unlink or \c safe_link + //! initializes the node to an unlinked state. + //! + //! Throws: Nothing. + avl_set_member_hook(); + + //! Effects: If link_mode is \c auto_unlink or \c safe_link + //! initializes the node to an unlinked state. The argument is ignored. + //! + //! Throws: Nothing. + //! + //! Rationale: Providing a copy-constructor + //! 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. + avl_set_member_hook(const avl_set_member_hook& ); + + //! Effects: Empty function. The argument is ignored. + //! + //! Throws: Nothing. + //! + //! Rationale: Providing an assignment operator + //! 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. + avl_set_member_hook& operator=(const avl_set_member_hook& ); + + //! 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 + //! object is stored in a set an assertion is raised. If link_mode is + //! \c auto_unlink and \c is_linked() is true, the node is unlinked. + //! + //! Throws: Nothing. + ~avl_set_member_hook(); + + //! Effects: Swapping two nodes swaps the position of the elements + //! related to those nodes in one or two containers. That is, if the node + //! this is part of the element e1, the node x is part of the element e2 + //! and both elements are included in the containers s1 and s2, then after + //! the swap-operation e1 is in s2 at the position of e2 and e2 is in s1 + //! at the position of e1. If one element is not in a container, then + //! after the swap-operation the other element is not in a container. + //! Iterators to e1 and e2 related to those nodes are invalidated. + //! + //! Complexity: Constant + //! + //! Throws: Nothing. + void swap_nodes(avl_set_member_hook &other); + + //! Precondition: link_mode must be \c safe_link or \c auto_unlink. + //! + //! Returns: true, if the node belongs to a container, false + //! otherwise. This function can be used to test whether \c set::iterator_to + //! will return a valid iterator. + //! + //! Complexity: Constant + bool is_linked() const; + + //! 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(); + #endif +}; + +} //namespace intrusive +} //namespace boost + +#include + +#endif //BOOST_INTRUSIVE_AVL_SET_HOOK_HPP diff --git a/third_party/boost/libs/intrusive/include/boost/intrusive/avltree.hpp b/third_party/boost/libs/intrusive/include/boost/intrusive/avltree.hpp new file mode 100644 index 00000000000..747d41cc38c --- /dev/null +++ b/third_party/boost/libs/intrusive/include/boost/intrusive/avltree.hpp @@ -0,0 +1,588 @@ +///////////////////////////////////////////////////////////////////////////// +// +// (C) Copyright Ion Gaztanaga 2007-2013 +// +// 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_AVLTREE_HPP +#define BOOST_INTRUSIVE_AVLTREE_HPP + +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#if defined(BOOST_HAS_PRAGMA_ONCE) +# pragma once +#endif + +namespace boost { +namespace intrusive { + +/// @cond + +struct default_avltree_hook_applier +{ template struct apply{ typedef typename T::default_avltree_hook type; }; }; + +template<> +struct is_default_hook_tag +{ static const bool value = true; }; + +struct avltree_defaults + : bstree_defaults +{ + typedef default_avltree_hook_applier proto_value_traits; +}; + +/// @endcond + +//! The class template avltree is an intrusive AVL tree container, that +//! is used to construct intrusive avl_set and avl_multiset containers. +//! The no-throw guarantee holds only, if the key_compare object +//! doesn't throw. +//! +//! The template parameter \c T is the type to be managed by the container. +//! The user can specify additional options and if no options are provided +//! default options are used. +//! +//! The container supports the following options: +//! \c base_hook<>/member_hook<>/value_traits<>, +//! \c constant_time_size<>, \c size_type<> and +//! \c compare<>. +#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED) +template +#else +template +#endif +class avltree_impl + /// @cond + : public bstree_impl + /// @endcond +{ + public: + typedef ValueTraits value_traits; + /// @cond + typedef bstree_impl< ValueTraits, VoidOrKeyOfValue, VoidOrKeyComp, SizeType + , ConstantTimeSize, AvlTreeAlgorithms + , HeaderHolder> tree_type; + typedef tree_type implementation_defined; + /// @endcond + + typedef typename implementation_defined::pointer pointer; + typedef typename implementation_defined::const_pointer const_pointer; + typedef typename implementation_defined::value_type value_type; + typedef typename implementation_defined::key_type key_type; + typedef typename implementation_defined::key_of_value key_of_value; + typedef typename implementation_defined::reference reference; + typedef typename implementation_defined::const_reference const_reference; + typedef typename implementation_defined::difference_type difference_type; + typedef typename implementation_defined::size_type size_type; + typedef typename implementation_defined::value_compare value_compare; + typedef typename implementation_defined::key_compare key_compare; + typedef typename implementation_defined::iterator iterator; + typedef typename implementation_defined::const_iterator const_iterator; + typedef typename implementation_defined::reverse_iterator reverse_iterator; + typedef typename implementation_defined::const_reverse_iterator const_reverse_iterator; + typedef typename implementation_defined::node_traits node_traits; + 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; + + static const bool constant_time_size = implementation_defined::constant_time_size; + /// @cond + private: + + //noncopyable + BOOST_MOVABLE_BUT_NOT_COPYABLE(avltree_impl) + + /// @endcond + + public: + + typedef typename implementation_defined::insert_commit_data insert_commit_data; + + //! @copydoc ::boost::intrusive::bstree::bstree() + avltree_impl() + : tree_type() + {} + + //! @copydoc ::boost::intrusive::bstree::bstree(const key_compare &,const value_traits &) + explicit avltree_impl( const key_compare &cmp, const value_traits &v_traits = value_traits()) + : tree_type(cmp, v_traits) + {} + + //! @copydoc ::boost::intrusive::bstree::bstree(bool,Iterator,Iterator,const key_compare &,const value_traits &) + template + avltree_impl( bool unique, Iterator b, Iterator e + , const key_compare &cmp = key_compare() + , const value_traits &v_traits = value_traits()) + : tree_type(unique, b, e, cmp, v_traits) + {} + + //! @copydoc ::boost::intrusive::bstree::bstree(bstree &&) + avltree_impl(BOOST_RV_REF(avltree_impl) x) + : tree_type(BOOST_MOVE_BASE(tree_type, x)) + {} + + //! @copydoc ::boost::intrusive::bstree::operator=(bstree &&) + avltree_impl& operator=(BOOST_RV_REF(avltree_impl) x) + { return static_cast(tree_type::operator=(BOOST_MOVE_BASE(tree_type, x))); } + + #ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED + + //! @copydoc ::boost::intrusive::bstree::~bstree() + ~avltree_impl(); + + //! @copydoc ::boost::intrusive::bstree::begin() + iterator begin() BOOST_NOEXCEPT; + + //! @copydoc ::boost::intrusive::bstree::begin()const + const_iterator begin() const BOOST_NOEXCEPT; + + //! @copydoc ::boost::intrusive::bstree::cbegin()const + const_iterator cbegin() const BOOST_NOEXCEPT; + + //! @copydoc ::boost::intrusive::bstree::end() + iterator end() BOOST_NOEXCEPT; + + //! @copydoc ::boost::intrusive::bstree::end()const + const_iterator end() const BOOST_NOEXCEPT; + + //! @copydoc ::boost::intrusive::bstree::cend()const + const_iterator cend() const BOOST_NOEXCEPT; + + //! @copydoc ::boost::intrusive::bstree::rbegin() + reverse_iterator rbegin() BOOST_NOEXCEPT; + + //! @copydoc ::boost::intrusive::bstree::rbegin()const + const_reverse_iterator rbegin() const BOOST_NOEXCEPT; + + //! @copydoc ::boost::intrusive::bstree::crbegin()const + const_reverse_iterator crbegin() const BOOST_NOEXCEPT; + + //! @copydoc ::boost::intrusive::bstree::rend() + reverse_iterator rend() BOOST_NOEXCEPT; + + //! @copydoc ::boost::intrusive::bstree::rend()const + const_reverse_iterator rend() const BOOST_NOEXCEPT; + + //! @copydoc ::boost::intrusive::bstree::crend()const + const_reverse_iterator crend() const BOOST_NOEXCEPT; + + //! @copydoc ::boost::intrusive::bstree::root() + iterator root() BOOST_NOEXCEPT; + + //! @copydoc ::boost::intrusive::bstree::root()const + const_iterator root() const BOOST_NOEXCEPT; + + //! @copydoc ::boost::intrusive::bstree::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) BOOST_NOEXCEPT; + + //! @copydoc ::boost::intrusive::bstree::container_from_end_iterator(const_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) BOOST_NOEXCEPT; + + //! @copydoc ::boost::intrusive::bstree::container_from_iterator(const_iterator) + static const avltree_impl &container_from_iterator(const_iterator it) BOOST_NOEXCEPT; + + //! @copydoc ::boost::intrusive::bstree::key_comp()const + key_compare key_comp() const; + + //! @copydoc ::boost::intrusive::bstree::value_comp()const + value_compare value_comp() const; + + //! @copydoc ::boost::intrusive::bstree::empty()const + bool empty() const BOOST_NOEXCEPT; + + //! @copydoc ::boost::intrusive::bstree::size()const + size_type size() const BOOST_NOEXCEPT; + + //! @copydoc ::boost::intrusive::bstree::swap + void swap(avltree_impl& other); + + //! @copydoc ::boost::intrusive::bstree::clone_from(const bstree&,Cloner,Disposer) + template + void clone_from(const avltree_impl &src, Cloner cloner, Disposer disposer); + + #else //BOOST_INTRUSIVE_DOXYGEN_INVOKED + + using tree_type::clone_from; + + #endif //#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED + + //! @copydoc ::boost::intrusive::bstree::clone_from(bstree&&,Cloner,Disposer) + template + void clone_from(BOOST_RV_REF(avltree_impl) src, Cloner cloner, Disposer disposer) + { tree_type::clone_from(BOOST_MOVE_BASE(tree_type, src), cloner, disposer); } + + #ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED + + //! @copydoc ::boost::intrusive::bstree::insert_equal(reference) + iterator insert_equal(reference value); + + //! @copydoc ::boost::intrusive::bstree::insert_equal(const_iterator,reference) + iterator insert_equal(const_iterator hint, reference value); + + //! @copydoc ::boost::intrusive::bstree::insert_equal(Iterator,Iterator) + template + void insert_equal(Iterator b, Iterator e); + + //! @copydoc ::boost::intrusive::bstree::insert_unique(reference) + std::pair insert_unique(reference value); + + //! @copydoc ::boost::intrusive::bstree::insert_unique(const_iterator,reference) + iterator insert_unique(const_iterator hint, reference value); + + //! @copydoc ::boost::intrusive::bstree::insert_unique_check(const KeyType&,KeyTypeKeyCompare,insert_commit_data&) + template + std::pair insert_unique_check + (const KeyType &key, KeyTypeKeyCompare comp, insert_commit_data &commit_data); + + //! @copydoc ::boost::intrusive::bstree::insert_unique_check(const_iterator,const KeyType&,KeyTypeKeyCompare,insert_commit_data&) + template + std::pair insert_unique_check + (const_iterator hint, const KeyType &key + ,KeyTypeKeyCompare comp, insert_commit_data &commit_data); + + //! @copydoc ::boost::intrusive::bstree::insert_unique_check(const key_type&,insert_commit_data&) + std::pair insert_unique_check + (const key_type &key, insert_commit_data &commit_data); + + //! @copydoc ::boost::intrusive::bstree::insert_unique_check(const_iterator,const key_type&,insert_commit_data&) + std::pair insert_unique_check + (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) 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) BOOST_NOEXCEPT; + + //! @copydoc ::boost::intrusive::bstree::push_back + void push_back(reference value) BOOST_NOEXCEPT; + + //! @copydoc ::boost::intrusive::bstree::push_front + void push_front(reference value) BOOST_NOEXCEPT; + + //! @copydoc ::boost::intrusive::bstree::erase(const_iterator) + iterator erase(const_iterator i) BOOST_NOEXCEPT; + + //! @copydoc ::boost::intrusive::bstree::erase(const_iterator,const_iterator) + 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); + + //! @copydoc ::boost::intrusive::bstree::erase(const KeyType&,KeyTypeKeyCompare) + template + size_type erase(const KeyType& key, KeyTypeKeyCompare comp); + + //! @copydoc ::boost::intrusive::bstree::erase_and_dispose(const_iterator,Disposer) + template + 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) BOOST_NOEXCEPT; + + //! @copydoc ::boost::intrusive::bstree::erase_and_dispose(const key_type &, Disposer) + template + size_type erase_and_dispose(const key_type &key, Disposer disposer); + + //! @copydoc ::boost::intrusive::bstree::erase_and_dispose(const KeyType&,KeyTypeKeyCompare,Disposer) + template + size_type erase_and_dispose(const KeyType& key, KeyTypeKeyCompare comp, Disposer disposer); + + //! @copydoc ::boost::intrusive::bstree::clear + void clear() BOOST_NOEXCEPT; + + //! @copydoc ::boost::intrusive::bstree::clear_and_dispose + template + 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; + + //! @copydoc ::boost::intrusive::bstree::count(const KeyType&,KeyTypeKeyCompare)const + template + size_type count(const KeyType& key, KeyTypeKeyCompare comp) const; + + //! @copydoc ::boost::intrusive::bstree::lower_bound(const key_type &) + iterator lower_bound(const key_type &key); + + //! @copydoc ::boost::intrusive::bstree::lower_bound(const KeyType&,KeyTypeKeyCompare) + template + iterator lower_bound(const KeyType& key, KeyTypeKeyCompare comp); + + //! @copydoc ::boost::intrusive::bstree::lower_bound(const key_type &)const + const_iterator lower_bound(const key_type &key) const; + + //! @copydoc ::boost::intrusive::bstree::lower_bound(const KeyType&,KeyTypeKeyCompare)const + template + const_iterator lower_bound(const KeyType& key, KeyTypeKeyCompare comp) const; + + //! @copydoc ::boost::intrusive::bstree::upper_bound(const key_type &key) + iterator upper_bound(const key_type &key); + + //! @copydoc ::boost::intrusive::bstree::upper_bound(const KeyType&,KeyTypeKeyCompare) + template + iterator upper_bound(const KeyType& key, KeyTypeKeyCompare comp); + + //! @copydoc ::boost::intrusive::bstree::upper_bound(const key_type &)const + const_iterator upper_bound(const key_type &key) const; + + //! @copydoc ::boost::intrusive::bstree::upper_bound(const KeyType&,KeyTypeKeyCompare)const + template + const_iterator upper_bound(const KeyType& key, KeyTypeKeyCompare comp) const; + + //! @copydoc ::boost::intrusive::bstree::find(const key_type &) + iterator find(const key_type &key); + + //! @copydoc ::boost::intrusive::bstree::find(const KeyType&,KeyTypeKeyCompare) + template + iterator find(const KeyType& key, KeyTypeKeyCompare comp); + + //! @copydoc ::boost::intrusive::bstree::find(const key_type &)const + const_iterator find(const key_type &key) const; + + //! @copydoc ::boost::intrusive::bstree::find(const KeyType&,KeyTypeKeyCompare)const + template + const_iterator find(const KeyType& key, KeyTypeKeyCompare comp) const; + + //! @copydoc ::boost::intrusive::bstree::equal_range(const key_type &) + std::pair equal_range(const key_type &key); + + //! @copydoc ::boost::intrusive::bstree::equal_range(const KeyType&,KeyTypeKeyCompare) + template + std::pair equal_range(const KeyType& key, KeyTypeKeyCompare comp); + + //! @copydoc ::boost::intrusive::bstree::equal_range(const key_type &)const + std::pair + equal_range(const key_type &key) const; + + //! @copydoc ::boost::intrusive::bstree::equal_range(const KeyType&,KeyTypeKeyCompare)const + template + std::pair + equal_range(const KeyType& key, KeyTypeKeyCompare comp) const; + + //! @copydoc ::boost::intrusive::bstree::bounded_range(const key_type &,const key_type &,bool,bool) + std::pair bounded_range + (const key_type &lower, const key_type &upper_key, bool left_closed, bool right_closed); + + //! @copydoc ::boost::intrusive::bstree::bounded_range(const KeyType&,const KeyType&,KeyTypeKeyCompare,bool,bool) + template + std::pair bounded_range + (const KeyType& lower_key, const KeyType& upper_key, KeyTypeKeyCompare comp, bool left_closed, bool right_closed); + + //! @copydoc ::boost::intrusive::bstree::bounded_range(const key_type &,const key_type &,bool,bool)const + std::pair + bounded_range(const key_type &lower_key, const key_type &upper_key, bool left_closed, bool right_closed) const; + + //! @copydoc ::boost::intrusive::bstree::bounded_range(const KeyType&,const KeyType&,KeyTypeKeyCompare,bool,bool)const + template + std::pair bounded_range + (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) BOOST_NOEXCEPT; + + //! @copydoc ::boost::intrusive::bstree::s_iterator_to(const_reference) + static const_iterator s_iterator_to(const_reference value) BOOST_NOEXCEPT; + + //! @copydoc ::boost::intrusive::bstree::iterator_to(reference) + iterator iterator_to(reference value) BOOST_NOEXCEPT; + + //! @copydoc ::boost::intrusive::bstree::iterator_to(const_reference)const + const_iterator iterator_to(const_reference value) const BOOST_NOEXCEPT; + + //! @copydoc ::boost::intrusive::bstree::init_node(reference) + static void init_node(reference value) BOOST_NOEXCEPT; + + //! @copydoc ::boost::intrusive::bstree::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) BOOST_NOEXCEPT; + + //! @copydoc ::boost::intrusive::bstree::remove_node + void remove_node(reference value) BOOST_NOEXCEPT; + + //! @copydoc ::boost::intrusive::bstree::merge_unique(bstree&) + template + void merge_unique(avltree &); + + //! @copydoc ::boost::intrusive::bstree::merge_equal(bstree&) + template + void merge_equal(avltree &); + + friend bool operator< (const avltree_impl &x, const avltree_impl &y); + + friend bool operator==(const avltree_impl &x, const avltree_impl &y); + + friend bool operator!= (const avltree_impl &x, const avltree_impl &y); + + friend bool operator>(const avltree_impl &x, const avltree_impl &y); + + friend bool operator<=(const avltree_impl &x, const avltree_impl &y); + + friend bool operator>=(const avltree_impl &x, const avltree_impl &y); + + friend void swap(avltree_impl &x, avltree_impl &y); + #endif //#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED +}; + + +//! Helper metafunction to define a \c avltree that yields to the same type when the +//! same options (either explicitly or implicitly) are used. +#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED) || defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES) +template +#else +template +#endif +struct make_avltree +{ + /// @cond + typedef typename pack_options + < avltree_defaults, + #if !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES) + O1, O2, O3, O4, O5, O6 + #else + Options... + #endif + >::type packed_options; + + typedef typename detail::get_value_traits + ::type value_traits; + + typedef avltree_impl + < value_traits + , typename packed_options::key_of_value + , typename packed_options::compare + , typename packed_options::size_type + , packed_options::constant_time_size + , typename packed_options::header_holder_type + > implementation_defined; + /// @endcond + typedef implementation_defined type; +}; + + +#ifndef BOOST_INTRUSIVE_DOXYGEN_INVOKED + +#if !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES) +template +#else +template +#endif +class avltree + : public make_avltree::type +{ + typedef typename make_avltree + ::type Base; + BOOST_MOVABLE_BUT_NOT_COPYABLE(avltree) + + public: + typedef typename Base::key_compare key_compare; + typedef typename Base::value_traits value_traits; + typedef typename Base::iterator iterator; + typedef typename Base::const_iterator const_iterator; + typedef typename Base::reverse_iterator reverse_iterator; + typedef typename Base::const_reverse_iterator const_reverse_iterator; + + //Assert if passed value traits are compatible with the type + BOOST_STATIC_ASSERT((detail::is_same::value)); + + BOOST_INTRUSIVE_FORCEINLINE avltree() + : Base() + {} + + BOOST_INTRUSIVE_FORCEINLINE explicit avltree( const key_compare &cmp, const value_traits &v_traits = value_traits()) + : Base(cmp, v_traits) + {} + + template + BOOST_INTRUSIVE_FORCEINLINE avltree( bool unique, Iterator b, Iterator e + , const key_compare &cmp = key_compare() + , const value_traits &v_traits = value_traits()) + : Base(unique, b, e, cmp, v_traits) + {} + + BOOST_INTRUSIVE_FORCEINLINE avltree(BOOST_RV_REF(avltree) x) + : Base(BOOST_MOVE_BASE(Base, x)) + {} + + BOOST_INTRUSIVE_FORCEINLINE avltree& operator=(BOOST_RV_REF(avltree) x) + { return static_cast(this->Base::operator=(BOOST_MOVE_BASE(Base, x))); } + + template + BOOST_INTRUSIVE_FORCEINLINE void clone_from(const avltree &src, Cloner cloner, Disposer disposer) + { Base::clone_from(src, cloner, disposer); } + + template + 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_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_NOEXCEPT + { return static_cast(Base::container_from_end_iterator(end_iterator)); } + + 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_NOEXCEPT + { return static_cast(Base::container_from_iterator(it)); } +}; + +#endif + +} //namespace intrusive +} //namespace boost + +#include + +#endif //BOOST_INTRUSIVE_AVLTREE_HPP diff --git a/third_party/boost/libs/intrusive/include/boost/intrusive/avltree_algorithms.hpp b/third_party/boost/libs/intrusive/include/boost/intrusive/avltree_algorithms.hpp new file mode 100644 index 00000000000..0fd158d595e --- /dev/null +++ b/third_party/boost/libs/intrusive/include/boost/intrusive/avltree_algorithms.hpp @@ -0,0 +1,727 @@ +///////////////////////////////////////////////////////////////////////////// +// +// (C) Copyright Daniel K. O. 2005. +// (C) Copyright Ion Gaztanaga 2007-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_AVLTREE_ALGORITHMS_HPP +#define BOOST_INTRUSIVE_AVLTREE_ALGORITHMS_HPP + +#include +#include + +#include + +#include +#include +#include +#include + +#if defined(BOOST_HAS_PRAGMA_ONCE) +# pragma once +#endif + + +namespace boost { +namespace intrusive { + +/// @cond + +template +struct avltree_node_cloner + //Use public inheritance to avoid MSVC bugs with closures + : public detail::ebo_functor_holder +{ + typedef typename NodeTraits::node_ptr node_ptr; + typedef detail::ebo_functor_holder base_t; + + BOOST_INTRUSIVE_FORCEINLINE avltree_node_cloner(F f) + : base_t(f) + {} + + node_ptr operator()(node_ptr p) + { + node_ptr n = base_t::get()(p); + NodeTraits::set_balance(n, NodeTraits::get_balance(p)); + return n; + } + + node_ptr operator()(node_ptr p) const + { + node_ptr n = base_t::get()(p); + NodeTraits::set_balance(n, NodeTraits::get_balance(p)); + return n; + } +}; + +namespace detail { + +template +struct avltree_node_checker + : public bstree_node_checker +{ + typedef bstree_node_checker base_checker_t; + typedef ValueTraits value_traits; + typedef typename value_traits::node_traits node_traits; + typedef typename node_traits::const_node_ptr const_node_ptr; + + struct return_type + : public base_checker_t::return_type + { + return_type() : height(0) {} + int height; + }; + + avltree_node_checker(const NodePtrCompare& comp, ExtraChecker extra_checker) + : base_checker_t(comp, extra_checker) + {} + + void operator () (const_node_ptr p, + const return_type& check_return_left, const return_type& check_return_right, + return_type& check_return) + { + const int height_diff = check_return_right.height - check_return_left.height; (void)height_diff; + BOOST_INTRUSIVE_INVARIANT_ASSERT( + (height_diff == -1 && node_traits::get_balance(p) == node_traits::negative()) || + (height_diff == 0 && node_traits::get_balance(p) == node_traits::zero()) || + (height_diff == 1 && node_traits::get_balance(p) == node_traits::positive()) + ); + check_return.height = 1 + + (check_return_left.height > check_return_right.height ? check_return_left.height : check_return_right.height); + base_checker_t::operator()(p, check_return_left, check_return_right, check_return); + } +}; + +} // namespace detail + +/// @endcond + +//! avltree_algorithms is configured with a NodeTraits class, which encapsulates the +//! information about the node to be manipulated. NodeTraits must support the +//! following interface: +//! +//! Typedefs: +//! +//! node: The type of the node that forms the binary search tree +//! +//! node_ptr: A pointer to a node +//! +//! const_node_ptr: A pointer to a const node +//! +//! balance: The type of the balance factor +//! +//! Static functions: +//! +//! static node_ptr get_parent(const_node_ptr n); +//! +//! static void set_parent(node_ptr n, node_ptr parent); +//! +//! static node_ptr get_left(const_node_ptr n); +//! +//! static void set_left(node_ptr n, node_ptr left); +//! +//! static node_ptr get_right(const_node_ptr n); +//! +//! static void set_right(node_ptr n, node_ptr right); +//! +//! static balance get_balance(const_node_ptr n); +//! +//! static void set_balance(node_ptr n, balance b); +//! +//! static balance negative(); +//! +//! static balance zero(); +//! +//! static balance positive(); +template +class avltree_algorithms + #ifndef BOOST_INTRUSIVE_DOXYGEN_INVOKED + : public bstree_algorithms + #endif +{ + public: + typedef typename NodeTraits::node node; + typedef NodeTraits node_traits; + typedef typename NodeTraits::node_ptr node_ptr; + typedef typename NodeTraits::const_node_ptr const_node_ptr; + typedef typename NodeTraits::balance balance; + + /// @cond + private: + typedef bstree_algorithms bstree_algo; + + /// @endcond + + public: + //! This type is the information that will be + //! filled by insert_unique_check + typedef typename bstree_algo::insert_commit_data insert_commit_data; + + #ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED + + //! @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) BOOST_NOEXCEPT; + + //! @copydoc ::boost::intrusive::bstree_algorithms::end_node + 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) 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) BOOST_NOEXCEPT + { + if(node1 == node2) + return; + + node_ptr header1(bstree_algo::get_header(node1)), header2(bstree_algo::get_header(node2)); + swap_nodes(node1, header1, node2, header2); + } + + //! @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) BOOST_NOEXCEPT + { + if(node1 == node2) return; + + bstree_algo::swap_nodes(node1, header1, node2, header2); + //Swap balance + balance c = NodeTraits::get_balance(node1); + NodeTraits::set_balance(node1, NodeTraits::get_balance(node2)); + NodeTraits::set_balance(node2, c); + } + + //! @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) BOOST_NOEXCEPT + { + if(node_to_be_replaced == new_node) + return; + replace_node(node_to_be_replaced, bstree_algo::get_header(node_to_be_replaced), new_node); + } + + //! @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) 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 n) BOOST_NOEXCEPT + { + node_ptr x = NodeTraits::get_parent(n); + if(x){ + while(!is_header(x)) + x = NodeTraits::get_parent(x); + erase(x, n); + } + } + + #ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED + //! @copydoc ::boost::intrusive::bstree_algorithms::unlink_leftmost_without_rebalance + static node_ptr unlink_leftmost_without_rebalance(node_ptr header) BOOST_NOEXCEPT; + + //! @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_node_ptr) + static std::size_t size(const_node_ptr header) BOOST_NOEXCEPT; + + //! @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(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 n) BOOST_NOEXCEPT; + #endif //#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED + + //! Requires: header must not be part of any tree. + //! + //! Effects: Initializes the header to represent an empty tree. + //! unique(header) == true. + //! + //! Complexity: Constant. + //! + //! Throws: Nothing. + //! + //! 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) BOOST_NOEXCEPT + { + typename bstree_algo::data_for_rebalance info; + bstree_algo::erase(header, z, info); + rebalance_after_erasure(header, z, info); + return z; + } + + //! @copydoc ::boost::intrusive::bstree_algorithms::transfer_unique + template + static bool transfer_unique + (node_ptr header1, NodePtrCompare comp, node_ptr header2, node_ptr z) + { + typename bstree_algo::data_for_rebalance info; + bool const transferred = bstree_algo::transfer_unique(header1, comp, header2, z, info); + if(transferred){ + rebalance_after_erasure(header2, z, info); + rebalance_after_insertion(header1, z); + } + return transferred; + } + + //! @copydoc ::boost::intrusive::bstree_algorithms::transfer_equal + template + static void transfer_equal + (node_ptr header1, NodePtrCompare comp, node_ptr header2, node_ptr z) + { + typename bstree_algo::data_for_rebalance info; + bstree_algo::transfer_equal(header1, comp, header2, z, info); + rebalance_after_erasure(header2, z, info); + rebalance_after_insertion(header1, z); + } + + //! @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) + { + 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(node_ptr,Disposer) + template + static void clear_and_dispose(node_ptr header, Disposer disposer) BOOST_NOEXCEPT; + + //! @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_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_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_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_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_node_ptr,const KeyType&,KeyNodePtrCompare) + template + static std::size_t count(const_node_ptr header, const KeyType &key, KeyNodePtrCompare comp); + + #endif //#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED + + //! @copydoc ::boost::intrusive::bstree_algorithms::insert_equal_upper_bound(node_ptr,node_ptr,NodePtrCompare) + template + static node_ptr insert_equal_upper_bound + (node_ptr h, node_ptr new_node, NodePtrCompare comp) + { + bstree_algo::insert_equal_upper_bound(h, new_node, comp); + rebalance_after_insertion(h, new_node); + return new_node; + } + + //! @copydoc ::boost::intrusive::bstree_algorithms::insert_equal_lower_bound(node_ptr,node_ptr,NodePtrCompare) + template + static node_ptr insert_equal_lower_bound + (node_ptr h, node_ptr new_node, NodePtrCompare comp) + { + bstree_algo::insert_equal_lower_bound(h, new_node, comp); + rebalance_after_insertion(h, new_node); + return new_node; + } + + //! @copydoc ::boost::intrusive::bstree_algorithms::insert_equal(node_ptr,node_ptr,node_ptr,NodePtrCompare) + template + static node_ptr insert_equal + (node_ptr header, node_ptr hint, node_ptr new_node, NodePtrCompare comp) + { + bstree_algo::insert_equal(header, hint, new_node, comp); + rebalance_after_insertion(header, new_node); + return new_node; + } + + //! @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) BOOST_NOEXCEPT + { + bstree_algo::insert_before(header, pos, new_node); + rebalance_after_insertion(header, new_node); + return new_node; + } + + //! @copydoc ::boost::intrusive::bstree_algorithms::push_back(node_ptr,node_ptr) + 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) 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_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_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 + ,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) 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_node_ptr p) BOOST_NOEXCEPT + { return NodeTraits::get_balance(p) == NodeTraits::zero() && bstree_algo::is_header(p); } + + + /// @cond + static bool verify(node_ptr header) + { + std::size_t height; + std::size_t count; + return verify_recursion(NodeTraits::get_parent(header), count, height); + } + + private: + + static bool verify_recursion(node_ptr n, std::size_t &count, std::size_t &height) + { + if (!n){ + count = 0; + height = 0; + return true; + } + std::size_t leftcount, rightcount; + std::size_t leftheight, rightheight; + if(!verify_recursion(NodeTraits::get_left (n), leftcount, leftheight) || + !verify_recursion(NodeTraits::get_right(n), rightcount, rightheight) ){ + return false; + } + count = 1u + leftcount + rightcount; + height = 1u + (leftheight > rightheight ? leftheight : rightheight); + + //If equal height, balance must be zero + if(rightheight == leftheight){ + if(NodeTraits::get_balance(n) != NodeTraits::zero()){ + BOOST_ASSERT(0); + return false; + } + } + //If right is taller than left, then the difference must be at least 1 and the balance positive + else if(rightheight > leftheight){ + if(rightheight - leftheight > 1 ){ + BOOST_ASSERT(0); + return false; + } + else if(NodeTraits::get_balance(n) != NodeTraits::positive()){ + BOOST_ASSERT(0); + return false; + } + } + //If left is taller than right, then the difference must be at least 1 and the balance negative + else{ + if(leftheight - rightheight > 1 ){ + BOOST_ASSERT(0); + return false; + } + else if(NodeTraits::get_balance(n) != NodeTraits::negative()){ + BOOST_ASSERT(0); + return false; + } + } + return true; + } + + static void rebalance_after_erasure + ( 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)); + } + //Rebalance avltree + 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) BOOST_NOEXCEPT + { + for ( node_ptr root = NodeTraits::get_parent(header) + ; x != root + ; root = NodeTraits::get_parent(header), x_parent = NodeTraits::get_parent(x)) { + const balance x_parent_balance = NodeTraits::get_balance(x_parent); + //Don't cache x_is_leftchild or similar because x can be null and + //equal to both x_parent_left and x_parent_right + const node_ptr x_parent_left (NodeTraits::get_left(x_parent)); + const node_ptr x_parent_right(NodeTraits::get_right(x_parent)); + + if(x_parent_balance == NodeTraits::zero()){ + NodeTraits::set_balance( x_parent, x == x_parent_right ? NodeTraits::negative() : NodeTraits::positive() ); + break; // the height didn't change, let's stop here + } + else if(x_parent_balance == NodeTraits::negative()){ + if (x == x_parent_left) { ////x is left child or x and sibling are null + NodeTraits::set_balance(x_parent, NodeTraits::zero()); // balanced + x = x_parent; + } + else { + // x is right child (x_parent_left is the left child) + BOOST_INTRUSIVE_INVARIANT_ASSERT(x_parent_left); + if (NodeTraits::get_balance(x_parent_left) == NodeTraits::positive()) { + // x_parent_left MUST have a right child + BOOST_INTRUSIVE_INVARIANT_ASSERT(NodeTraits::get_right(x_parent_left)); + x = avl_rotate_left_right(x_parent, x_parent_left, header); + } + else { + avl_rotate_right(x_parent, x_parent_left, header); + x = x_parent_left; + } + + // if changed from negative to NodeTraits::positive(), no need to check above + if (NodeTraits::get_balance(x) == NodeTraits::positive()){ + break; + } + } + } + else if(x_parent_balance == NodeTraits::positive()){ + if (x == x_parent_right) { //x is right child or x and sibling are null + NodeTraits::set_balance(x_parent, NodeTraits::zero()); // balanced + x = x_parent; + } + else { + // x is left child (x_parent_right is the right child) + BOOST_INTRUSIVE_INVARIANT_ASSERT(x_parent_right); + if (NodeTraits::get_balance(x_parent_right) == NodeTraits::negative()) { + // x_parent_right MUST have then a left child + BOOST_INTRUSIVE_INVARIANT_ASSERT(NodeTraits::get_left(x_parent_right)); + x = avl_rotate_right_left(x_parent, x_parent_right, header); + } + else { + avl_rotate_left(x_parent, x_parent_right, header); + x = x_parent_right; + } + // if changed from NodeTraits::positive() to negative, no need to check above + if (NodeTraits::get_balance(x) == NodeTraits::negative()){ + break; + } + } + } + else{ + BOOST_INTRUSIVE_INVARIANT_ASSERT(false); // never reached + } + } + } + + static void rebalance_after_insertion(node_ptr header, node_ptr x) BOOST_NOEXCEPT + { + NodeTraits::set_balance(x, NodeTraits::zero()); + // Rebalance. + for(node_ptr root = NodeTraits::get_parent(header); x != root; root = NodeTraits::get_parent(header)){ + node_ptr const x_parent(NodeTraits::get_parent(x)); + node_ptr const x_parent_left(NodeTraits::get_left(x_parent)); + const balance x_parent_balance = NodeTraits::get_balance(x_parent); + const bool x_is_leftchild(x == x_parent_left); + if(x_parent_balance == NodeTraits::zero()){ + // if x is left, parent will have parent->bal_factor = negative + // else, parent->bal_factor = NodeTraits::positive() + NodeTraits::set_balance( x_parent, x_is_leftchild ? NodeTraits::negative() : NodeTraits::positive() ); + x = x_parent; + } + else if(x_parent_balance == NodeTraits::positive()){ + // if x is a left child, parent->bal_factor = zero + if (x_is_leftchild) + NodeTraits::set_balance(x_parent, NodeTraits::zero()); + else{ // x is a right child, needs rebalancing + if (NodeTraits::get_balance(x) == NodeTraits::negative()) + avl_rotate_right_left(x_parent, x, header); + else + avl_rotate_left(x_parent, x, header); + } + break; + } + else if(x_parent_balance == NodeTraits::negative()){ + // if x is a left child, needs rebalancing + if (x_is_leftchild) { + if (NodeTraits::get_balance(x) == NodeTraits::positive()) + avl_rotate_left_right(x_parent, x, header); + else + avl_rotate_right(x_parent, x, header); + } + else + NodeTraits::set_balance(x_parent, NodeTraits::zero()); + break; + } + else{ + BOOST_INTRUSIVE_INVARIANT_ASSERT(false); // never reached + } + } + } + + 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); + const balance zero_balance = NodeTraits::zero(); + const balance posi_balance = NodeTraits::positive(); + const balance nega_balance = NodeTraits::negative(); + NodeTraits::set_balance(c, zero_balance); + if(c_balance == nega_balance){ + NodeTraits::set_balance(a, posi_balance); + NodeTraits::set_balance(b, zero_balance); + } + else if(c_balance == zero_balance){ + NodeTraits::set_balance(a, zero_balance); + NodeTraits::set_balance(b, zero_balance); + } + else if(c_balance == posi_balance){ + NodeTraits::set_balance(a, zero_balance); + NodeTraits::set_balance(b, nega_balance); + } + else{ + BOOST_INTRUSIVE_INVARIANT_ASSERT(false); // never reached + } + } + + 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 // + // / \ / \ // + // / \ ==> / \ // + // (pos)b [g] b a // + // / \ / \ / \ // + // [d] c [d] e f [g] // + // / \ // + // e f // + const node_ptr c = NodeTraits::get_right(a_oldleft); + bstree_algo::rotate_left_no_parent_fix(a_oldleft, c); + //No need to link c with a [NodeTraits::set_parent(c, a) + NodeTraits::set_left(a, c)] + //as c is not root and another rotation is coming + bstree_algo::rotate_right(a, c, NodeTraits::get_parent(a), hdr); + left_right_balancing(a, a_oldleft, c); + return c; + } + + 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 // + // / \ / \ // + // / \ / \ // + // [d] b(neg) ==> a b // + // / \ / \ / \ // + // c [g] [d] e f [g] // + // / \ // + // e f // + const node_ptr c (NodeTraits::get_left(a_oldright)); + bstree_algo::rotate_right_no_parent_fix(a_oldright, c); + //No need to link c with a [NodeTraits::set_parent(c, a) + NodeTraits::set_right(a, c)] + //as c is not root and another rotation is coming. + bstree_algo::rotate_left(a, c, NodeTraits::get_parent(a), hdr); + left_right_balancing(a_oldright, a, c); + return c; + } + + 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); + + // reset the balancing factor + if (NodeTraits::get_balance(x_oldright) == NodeTraits::positive()) { + NodeTraits::set_balance(x, NodeTraits::zero()); + NodeTraits::set_balance(x_oldright, NodeTraits::zero()); + } + else { // this doesn't happen during insertions + NodeTraits::set_balance(x, NodeTraits::positive()); + NodeTraits::set_balance(x_oldright, NodeTraits::negative()); + } + } + + 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); + + // reset the balancing factor + if (NodeTraits::get_balance(x_oldleft) == NodeTraits::negative()) { + NodeTraits::set_balance(x, NodeTraits::zero()); + NodeTraits::set_balance(x_oldleft, NodeTraits::zero()); + } + else { // this doesn't happen during insertions + NodeTraits::set_balance(x, NodeTraits::negative()); + NodeTraits::set_balance(x_oldleft, NodeTraits::positive()); + } + } + + /// @endcond +}; + +/// @cond + +template +struct get_algo +{ + typedef avltree_algorithms type; +}; + +template +struct get_node_checker +{ + typedef detail::avltree_node_checker type; +}; + +/// @endcond + +} //namespace intrusive +} //namespace boost + +#include + +#endif //BOOST_INTRUSIVE_AVLTREE_ALGORITHMS_HPP diff --git a/third_party/boost/libs/intrusive/include/boost/intrusive/bs_set.hpp b/third_party/boost/libs/intrusive/include/boost/intrusive/bs_set.hpp new file mode 100644 index 00000000000..1755decf155 --- /dev/null +++ b/third_party/boost/libs/intrusive/include/boost/intrusive/bs_set.hpp @@ -0,0 +1,1069 @@ +///////////////////////////////////////////////////////////////////////////// +// +// (C) Copyright Ion Gaztanaga 2013-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_BS_SET_HPP +#define BOOST_INTRUSIVE_BS_SET_HPP + +#include +#include +#include +#include +#include +#include + +#if defined(BOOST_HAS_PRAGMA_ONCE) +# pragma once +#endif + +#if !defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED) +template +class bs_multiset_impl; +#endif + +namespace boost { +namespace intrusive { + +//! The class template bs_set is an intrusive container, that mimics most of +//! the interface of std::set as described in the C++ standard. +//! +//! The template parameter \c T is the type to be managed by the container. +//! The user can specify additional options and if no options are provided +//! default options are used. +//! +//! The container supports the following options: +//! \c base_hook<>/member_hook<>/value_traits<>, +//! \c constant_time_size<>, \c size_type<> and +//! \c compare<>. +#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED) +template +#else +template +#endif +class bs_set_impl +#ifndef BOOST_INTRUSIVE_DOXYGEN_INVOKED + : public bstree_impl +#endif +{ + /// @cond + typedef bstree_impl tree_type; + BOOST_MOVABLE_BUT_NOT_COPYABLE(bs_set_impl) + + typedef tree_type implementation_defined; + /// @endcond + + public: + typedef typename implementation_defined::value_type value_type; + typedef typename implementation_defined::key_type key_type; + typedef typename implementation_defined::value_traits value_traits; + typedef typename implementation_defined::pointer pointer; + typedef typename implementation_defined::const_pointer const_pointer; + typedef typename implementation_defined::reference reference; + typedef typename implementation_defined::const_reference const_reference; + typedef typename implementation_defined::difference_type difference_type; + typedef typename implementation_defined::size_type size_type; + typedef typename implementation_defined::value_compare value_compare; + typedef typename implementation_defined::key_compare key_compare; + typedef typename implementation_defined::iterator iterator; + typedef typename implementation_defined::const_iterator const_iterator; + typedef typename implementation_defined::reverse_iterator reverse_iterator; + typedef typename implementation_defined::const_reverse_iterator const_reverse_iterator; + typedef typename implementation_defined::insert_commit_data insert_commit_data; + typedef typename implementation_defined::node_traits node_traits; + 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; + + static const bool constant_time_size = tree_type::constant_time_size; + + public: + //! @copydoc ::boost::intrusive::bstree::bstree() + bs_set_impl() + : tree_type() + {} + + //! @copydoc ::boost::intrusive::bstree::bstree(const key_compare &,const value_traits &) + explicit bs_set_impl( const key_compare &cmp, const value_traits &v_traits = value_traits()) + : tree_type(cmp, v_traits) + {} + + //! @copydoc ::boost::intrusive::bstree::bstree(bool,Iterator,Iterator,const key_compare &,const value_traits &) + template + bs_set_impl( Iterator b, Iterator e + , const key_compare &cmp = key_compare() + , const value_traits &v_traits = value_traits()) + : tree_type(true, b, e, cmp, v_traits) + {} + + //! @copydoc ::boost::intrusive::bstree::bstree(bstree &&) + bs_set_impl(BOOST_RV_REF(bs_set_impl) x) + : tree_type(BOOST_MOVE_BASE(tree_type, x)) + {} + + //! @copydoc ::boost::intrusive::bstree::operator=(bstree &&) + bs_set_impl& operator=(BOOST_RV_REF(bs_set_impl) x) + { return static_cast(tree_type::operator=(BOOST_MOVE_BASE(tree_type, x))); } + + #ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED + //! @copydoc ::boost::intrusive::bstree::~bstree() + ~bs_set_impl(); + + //! @copydoc ::boost::intrusive::bstree::begin() + iterator begin() BOOST_NOEXCEPT; + + //! @copydoc ::boost::intrusive::bstree::begin()const + const_iterator begin() const BOOST_NOEXCEPT; + + //! @copydoc ::boost::intrusive::bstree::cbegin()const + const_iterator cbegin() const BOOST_NOEXCEPT; + + //! @copydoc ::boost::intrusive::bstree::end() + iterator end() BOOST_NOEXCEPT; + + //! @copydoc ::boost::intrusive::bstree::end()const + const_iterator end() const BOOST_NOEXCEPT; + + //! @copydoc ::boost::intrusive::bstree::cend()const + const_iterator cend() const BOOST_NOEXCEPT; + + //! @copydoc ::boost::intrusive::bstree::rbegin() + reverse_iterator rbegin() BOOST_NOEXCEPT; + + //! @copydoc ::boost::intrusive::bstree::rbegin()const + const_reverse_iterator rbegin() const BOOST_NOEXCEPT; + + //! @copydoc ::boost::intrusive::bstree::crbegin()const + const_reverse_iterator crbegin() const BOOST_NOEXCEPT; + + //! @copydoc ::boost::intrusive::bstree::rend() + reverse_iterator rend() BOOST_NOEXCEPT; + + //! @copydoc ::boost::intrusive::bstree::rend()const + const_reverse_iterator rend() const BOOST_NOEXCEPT; + + //! @copydoc ::boost::intrusive::bstree::crend()const + const_reverse_iterator crend() const BOOST_NOEXCEPT; + + //! @copydoc ::boost::intrusive::bstree::root() + iterator root() BOOST_NOEXCEPT; + + //! @copydoc ::boost::intrusive::bstree::root()const + const_iterator root() const BOOST_NOEXCEPT; + + //! @copydoc ::boost::intrusive::bstree::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) 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) BOOST_NOEXCEPT; + + //! @copydoc ::boost::intrusive::bstree::container_from_iterator(iterator) + 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) BOOST_NOEXCEPT; + + //! @copydoc ::boost::intrusive::bstree::key_comp()const + key_compare key_comp() const; + + //! @copydoc ::boost::intrusive::bstree::value_comp()const + value_compare value_comp() const; + + //! @copydoc ::boost::intrusive::bstree::empty()const + bool empty() const BOOST_NOEXCEPT; + + //! @copydoc ::boost::intrusive::bstree::size()const + size_type size() const BOOST_NOEXCEPT; + + //! @copydoc ::boost::intrusive::bstree::swap + void swap(bs_set_impl& other); + + //! @copydoc ::boost::intrusive::bstree::clone_from(const bstree&,Cloner,Disposer) + template + void clone_from(const bs_set_impl &src, Cloner cloner, Disposer disposer); + + #else + + using tree_type::clone_from; + + #endif //#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED + + //! @copydoc ::boost::intrusive::bstree::clone_from(bstree&&,Cloner,Disposer) + template + void clone_from(BOOST_RV_REF(bs_set_impl) src, Cloner cloner, Disposer disposer) + { tree_type::clone_from(BOOST_MOVE_BASE(tree_type, src), cloner, disposer); } + + //! @copydoc ::boost::intrusive::bstree::insert_unique(reference) + std::pair insert(reference value) + { return tree_type::insert_unique(value); } + + //! @copydoc ::boost::intrusive::bstree::insert_unique(const_iterator,reference) + iterator insert(const_iterator hint, reference value) + { return tree_type::insert_unique(hint, value); } + + //! @copydoc ::boost::intrusive::bstree::insert_unique_check(const key_type&,insert_commit_data&) + std::pair insert_check + (const key_type &key, insert_commit_data &commit_data) + { return tree_type::insert_unique_check(key, commit_data); } + + //! @copydoc ::boost::intrusive::bstree::insert_unique_check(const_iterator,const key_type&,insert_commit_data&) + std::pair insert_check + (const_iterator hint, const key_type &key + ,insert_commit_data &commit_data) + { return tree_type::insert_unique_check(hint, key, commit_data); } + + //! @copydoc ::boost::intrusive::bstree::insert_unique_check(const KeyType&,KeyTypeKeyCompare,insert_commit_data&) + template + std::pair insert_check + (const KeyType &key, KeyTypeKeyCompare comp, insert_commit_data &commit_data) + { return tree_type::insert_unique_check(key, comp, commit_data); } + + //! @copydoc ::boost::intrusive::bstree::insert_unique_check(const_iterator,const KeyType&,KeyTypeKeyCompare,insert_commit_data&) + template + std::pair insert_check + (const_iterator hint, const KeyType &key + ,KeyTypeKeyCompare comp, insert_commit_data &commit_data) + { return tree_type::insert_unique_check(hint, key, comp, commit_data); } + + //! @copydoc ::boost::intrusive::bstree::insert_unique(Iterator,Iterator) + template + void insert(Iterator b, Iterator e) + { tree_type::insert_unique(b, e); } + + //! @copydoc ::boost::intrusive::bstree::insert_unique_commit + 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) BOOST_NOEXCEPT; + + //! @copydoc ::boost::intrusive::bstree::push_back + void push_back(reference value) BOOST_NOEXCEPT; + + //! @copydoc ::boost::intrusive::bstree::push_front + void push_front(reference value) BOOST_NOEXCEPT; + + //! @copydoc ::boost::intrusive::bstree::erase(const_iterator) + iterator erase(const_iterator i) BOOST_NOEXCEPT; + + //! @copydoc ::boost::intrusive::bstree::erase(const_iterator,const_iterator) + 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); + + //! @copydoc ::boost::intrusive::bstree::erase(const KeyType&,KeyTypeKeyCompare) + template + size_type erase(const KeyType& key, KeyTypeKeyCompare comp); + + //! @copydoc ::boost::intrusive::bstree::erase_and_dispose(const_iterator,Disposer) + template + 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) BOOST_NOEXCEPT; + + //! @copydoc ::boost::intrusive::bstree::erase_and_dispose(const key_type &, Disposer) + template + size_type erase_and_dispose(const key_type &key, Disposer disposer); + + //! @copydoc ::boost::intrusive::bstree::erase_and_dispose(const KeyType&,KeyTypeKeyCompare,Disposer) + template + size_type erase_and_dispose(const KeyType& key, KeyTypeKeyCompare comp, Disposer disposer); + + //! @copydoc ::boost::intrusive::bstree::clear + void clear() BOOST_NOEXCEPT; + + //! @copydoc ::boost::intrusive::bstree::clear_and_dispose + template + void clear_and_dispose(Disposer disposer) BOOST_NOEXCEPT; + + #endif // #ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED + + //! @copydoc ::boost::intrusive::bstree::count(const key_type &)const + size_type count(const key_type &key) const + { return static_cast(this->tree_type::find(key) != this->tree_type::cend()); } + + //! @copydoc ::boost::intrusive::bstree::count(const KeyType&,KeyTypeKeyCompare)const + template + size_type count(const KeyType& key, KeyTypeKeyCompare comp) const + { return static_cast(this->tree_type::find(key, comp) != this->tree_type::cend()); } + + #ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED + + //! @copydoc ::boost::intrusive::bstree::lower_bound(const key_type &) + iterator lower_bound(const key_type &); + + //! @copydoc ::boost::intrusive::bstree::lower_bound(const KeyType&,KeyTypeKeyCompare) + template + iterator lower_bound(const KeyType& key, KeyTypeKeyCompare comp); + + //! @copydoc ::boost::intrusive::bstree::lower_bound(const key_type &)const + const_iterator lower_bound(const key_type &key) const; + + //! @copydoc ::boost::intrusive::bstree::lower_bound(const KeyType&,KeyTypeKeyCompare)const + template + const_iterator lower_bound(const KeyType& key, KeyTypeKeyCompare comp) const; + + //! @copydoc ::boost::intrusive::bstree::upper_bound(const key_type &) + iterator upper_bound(const key_type &key); + + //! @copydoc ::boost::intrusive::bstree::upper_bound(const KeyType&,KeyTypeKeyCompare) + template + iterator upper_bound(const KeyType& key, KeyTypeKeyCompare comp); + + //! @copydoc ::boost::intrusive::bstree::upper_bound(const key_type &)const + const_iterator upper_bound(const key_type &key) const; + + //! @copydoc ::boost::intrusive::bstree::upper_bound(const KeyType&,KeyTypeKeyCompare)const + template + const_iterator upper_bound(const KeyType& key, KeyTypeKeyCompare comp) const; + + //! @copydoc ::boost::intrusive::bstree::find(const key_type &) + iterator find(const key_type &key); + + //! @copydoc ::boost::intrusive::bstree::find(const KeyType&,KeyTypeKeyCompare) + template + iterator find(const KeyType& key, KeyTypeKeyCompare comp); + + //! @copydoc ::boost::intrusive::bstree::find(const key_type &)const + const_iterator find(const key_type &key) const; + + //! @copydoc ::boost::intrusive::bstree::find(const KeyType&,KeyTypeKeyCompare)const + template + const_iterator find(const KeyType& key, KeyTypeKeyCompare comp) const; + + #endif // #ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED + + //! @copydoc ::boost::intrusive::bstree::equal_range(const key_type &) + std::pair equal_range(const key_type &key) + { return this->tree_type::lower_bound_range(key); } + + //! @copydoc ::boost::intrusive::bstree::equal_range(const KeyType&,KeyTypeKeyCompare) + template + std::pair equal_range(const KeyType& key, KeyTypeKeyCompare comp) + { return this->tree_type::equal_range(key, comp); } + + //! @copydoc ::boost::intrusive::bstree::equal_range(const key_type &)const + std::pair + equal_range(const key_type &key) const + { return this->tree_type::lower_bound_range(key); } + + //! @copydoc ::boost::intrusive::bstree::equal_range(const KeyType&,KeyTypeKeyCompare)const + template + std::pair + equal_range(const KeyType& key, KeyTypeKeyCompare comp) const + { return this->tree_type::equal_range(key, comp); } + + #ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED + + //! @copydoc ::boost::intrusive::bstree::bounded_range(const key_type&,const key_type&,bool,bool) + std::pair bounded_range + (const key_type& lower_key, const key_type& upper_key, bool left_closed, bool right_closed); + + //! @copydoc ::boost::intrusive::bstree::bounded_range(const KeyType&,const KeyType&,KeyTypeKeyCompare,bool,bool) + template + std::pair bounded_range + (const KeyType& lower_key, const KeyType& upper_key, KeyTypeKeyCompare comp, bool left_closed, bool right_closed); + + //! @copydoc ::boost::intrusive::bstree::bounded_range(const key_type&,const key_type&,bool,bool)const + std::pair + bounded_range(const key_type& lower_key, const key_type& upper_key, bool left_closed, bool right_closed) const; + + //! @copydoc ::boost::intrusive::bstree::bounded_range(const KeyType&,const KeyType&,KeyTypeKeyCompare,bool,bool)const + template + std::pair bounded_range + (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) BOOST_NOEXCEPT; + + //! @copydoc ::boost::intrusive::bstree::s_iterator_to(const_reference) + static const_iterator s_iterator_to(const_reference value) BOOST_NOEXCEPT; + + //! @copydoc ::boost::intrusive::bstree::iterator_to(reference) + iterator iterator_to(reference value) BOOST_NOEXCEPT; + + //! @copydoc ::boost::intrusive::bstree::iterator_to(const_reference)const + const_iterator iterator_to(const_reference value) const BOOST_NOEXCEPT; + + //! @copydoc ::boost::intrusive::bstree::init_node(reference) + static void init_node(reference value) BOOST_NOEXCEPT; + + //! @copydoc ::boost::intrusive::bstree::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) BOOST_NOEXCEPT; + + //! @copydoc ::boost::intrusive::bstree::remove_node + void remove_node(reference value) BOOST_NOEXCEPT; + + //! @copydoc ::boost::intrusive::bstree::merge_unique + template + void merge(bs_set &source); + + //! @copydoc ::boost::intrusive::bstree::merge_unique + template + void merge(bs_multiset &source); + + #else + + template + void merge(bs_set_impl &source) + { return tree_type::merge_unique(source); } + + + template + void merge(bs_multiset_impl &source) + { return tree_type::merge_unique(source); } + + #endif //#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED +}; + +#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED) + +template +bool operator!= (const bs_set_impl &x, const bs_set_impl &y); + +template +bool operator>(const bs_set_impl &x, const bs_set_impl &y); + +template +bool operator<=(const bs_set_impl &x, const bs_set_impl &y); + +template +bool operator>=(const bs_set_impl &x, const bs_set_impl &y); + +template +void swap(bs_set_impl &x, bs_set_impl &y); + +#endif //#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED) + +//! Helper metafunction to define a \c bs_set that yields to the same type when the +//! same options (either explicitly or implicitly) are used. +#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED) || defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES) +template +#else +template +#endif +struct make_bs_set +{ + /// @cond + typedef typename pack_options + < bstree_defaults, + #if !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES) + O1, O2, O3, O4, O5, O6 + #else + Options... + #endif + >::type packed_options; + + typedef typename detail::get_value_traits + ::type value_traits; + + typedef bs_set_impl + < value_traits + , typename packed_options::key_of_value + , typename packed_options::compare + , typename packed_options::size_type + , packed_options::constant_time_size + , typename packed_options::header_holder_type + > implementation_defined; + /// @endcond + typedef implementation_defined type; +}; + +#ifndef BOOST_INTRUSIVE_DOXYGEN_INVOKED +#if !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES) +template +#else +template +#endif +class bs_set + : public make_bs_set::type +{ + typedef typename make_bs_set + ::type Base; + + BOOST_MOVABLE_BUT_NOT_COPYABLE(bs_set) + public: + typedef typename Base::value_traits value_traits; + typedef typename Base::key_compare key_compare; + typedef typename Base::iterator iterator; + typedef typename Base::const_iterator const_iterator; + + //Assert if passed value traits are compatible with the type + BOOST_STATIC_ASSERT((detail::is_same::value)); + + BOOST_INTRUSIVE_FORCEINLINE bs_set() + : Base() + {} + + BOOST_INTRUSIVE_FORCEINLINE explicit bs_set( const key_compare &cmp, const value_traits &v_traits = value_traits()) + : Base(cmp, v_traits) + {} + + template + BOOST_INTRUSIVE_FORCEINLINE bs_set( Iterator b, Iterator e + , const key_compare &cmp = key_compare() + , const value_traits &v_traits = value_traits()) + : Base(b, e, cmp, v_traits) + {} + + BOOST_INTRUSIVE_FORCEINLINE bs_set(BOOST_RV_REF(bs_set) x) + : Base(BOOST_MOVE_BASE(Base, x)) + {} + + BOOST_INTRUSIVE_FORCEINLINE bs_set& operator=(BOOST_RV_REF(bs_set) x) + { return static_cast(this->Base::operator=(BOOST_MOVE_BASE(Base, x))); } + + template + BOOST_INTRUSIVE_FORCEINLINE void clone_from(const bs_set &src, Cloner cloner, Disposer disposer) + { Base::clone_from(src, cloner, disposer); } + + template + 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_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_NOEXCEPT + { return static_cast(Base::container_from_end_iterator(end_iterator)); } + + 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_NOEXCEPT + { return static_cast(Base::container_from_iterator(it)); } +}; + +#endif + +//! The class template bs_multiset is an intrusive container, that mimics most of +//! the interface of std::multiset as described in the C++ standard. +//! +//! The template parameter \c T is the type to be managed by the container. +//! The user can specify additional options and if no options are provided +//! default options are used. +//! +//! The container supports the following options: +//! \c base_hook<>/member_hook<>/value_traits<>, +//! \c constant_time_size<>, \c size_type<> and +//! \c compare<>. +#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED) +template +#else +template +#endif +class bs_multiset_impl +#ifndef BOOST_INTRUSIVE_DOXYGEN_INVOKED + : public bstree_impl +#endif +{ + /// @cond + typedef bstree_impl tree_type; + + BOOST_MOVABLE_BUT_NOT_COPYABLE(bs_multiset_impl) + typedef tree_type implementation_defined; + /// @endcond + + public: + typedef typename implementation_defined::value_type value_type; + typedef typename implementation_defined::key_type key_type; + typedef typename implementation_defined::value_traits value_traits; + typedef typename implementation_defined::pointer pointer; + typedef typename implementation_defined::const_pointer const_pointer; + typedef typename implementation_defined::reference reference; + typedef typename implementation_defined::const_reference const_reference; + typedef typename implementation_defined::difference_type difference_type; + typedef typename implementation_defined::size_type size_type; + typedef typename implementation_defined::value_compare value_compare; + typedef typename implementation_defined::key_compare key_compare; + typedef typename implementation_defined::iterator iterator; + typedef typename implementation_defined::const_iterator const_iterator; + typedef typename implementation_defined::reverse_iterator reverse_iterator; + typedef typename implementation_defined::const_reverse_iterator const_reverse_iterator; + typedef typename implementation_defined::insert_commit_data insert_commit_data; + typedef typename implementation_defined::node_traits node_traits; + 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; + + static const bool constant_time_size = tree_type::constant_time_size; + + public: + //! @copydoc ::boost::intrusive::bstree::bstree() + bs_multiset_impl() + : tree_type() + {} + + //! @copydoc ::boost::intrusive::bstree::bstree(const key_compare &,const value_traits &) + explicit bs_multiset_impl( const key_compare &cmp, const value_traits &v_traits = value_traits()) + : tree_type(cmp, v_traits) + {} + + //! @copydoc ::boost::intrusive::bstree::bstree(bool,Iterator,Iterator,const key_compare &,const value_traits &) + template + bs_multiset_impl( Iterator b, Iterator e + , const key_compare &cmp = key_compare() + , const value_traits &v_traits = value_traits()) + : tree_type(false, b, e, cmp, v_traits) + {} + + //! @copydoc ::boost::intrusive::bstree::bstree(bstree &&) + bs_multiset_impl(BOOST_RV_REF(bs_multiset_impl) x) + : tree_type(BOOST_MOVE_BASE(tree_type, x)) + {} + + //! @copydoc ::boost::intrusive::bstree::operator=(bstree &&) + bs_multiset_impl& operator=(BOOST_RV_REF(bs_multiset_impl) x) + { return static_cast(tree_type::operator=(BOOST_MOVE_BASE(tree_type, x))); } + + #ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED + //! @copydoc ::boost::intrusive::bstree::~bstree() + ~bs_multiset_impl(); + + //! @copydoc ::boost::intrusive::bstree::begin() + iterator begin() BOOST_NOEXCEPT; + + //! @copydoc ::boost::intrusive::bstree::begin()const + const_iterator begin() const BOOST_NOEXCEPT; + + //! @copydoc ::boost::intrusive::bstree::cbegin()const + const_iterator cbegin() const BOOST_NOEXCEPT; + + //! @copydoc ::boost::intrusive::bstree::end() + iterator end() BOOST_NOEXCEPT; + + //! @copydoc ::boost::intrusive::bstree::end()const + const_iterator end() const BOOST_NOEXCEPT; + + //! @copydoc ::boost::intrusive::bstree::cend()const + const_iterator cend() const BOOST_NOEXCEPT; + + //! @copydoc ::boost::intrusive::bstree::rbegin() + reverse_iterator rbegin() BOOST_NOEXCEPT; + + //! @copydoc ::boost::intrusive::bstree::rbegin()const + const_reverse_iterator rbegin() const BOOST_NOEXCEPT; + + //! @copydoc ::boost::intrusive::bstree::crbegin()const + const_reverse_iterator crbegin() const BOOST_NOEXCEPT; + + //! @copydoc ::boost::intrusive::bstree::rend() + reverse_iterator rend() BOOST_NOEXCEPT; + + //! @copydoc ::boost::intrusive::bstree::rend()const + const_reverse_iterator rend() const BOOST_NOEXCEPT; + + //! @copydoc ::boost::intrusive::bstree::crend()const + const_reverse_iterator crend() const BOOST_NOEXCEPT; + + //! @copydoc ::boost::intrusive::bstree::root() + iterator root() BOOST_NOEXCEPT; + + //! @copydoc ::boost::intrusive::bstree::root()const + const_iterator root() const BOOST_NOEXCEPT; + + //! @copydoc ::boost::intrusive::bstree::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) 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) BOOST_NOEXCEPT; + + //! @copydoc ::boost::intrusive::bstree::container_from_iterator(iterator) + 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) BOOST_NOEXCEPT; + + //! @copydoc ::boost::intrusive::bstree::key_comp()const + key_compare key_comp() const; + + //! @copydoc ::boost::intrusive::bstree::value_comp()const + value_compare value_comp() const; + + //! @copydoc ::boost::intrusive::bstree::empty()const + bool empty() const BOOST_NOEXCEPT; + + //! @copydoc ::boost::intrusive::bstree::size()const + size_type size() const BOOST_NOEXCEPT; + + //! @copydoc ::boost::intrusive::bstree::swap + void swap(bs_multiset_impl& other); + + //! @copydoc ::boost::intrusive::bstree::clone_from(const bstree&,Cloner,Disposer) + template + void clone_from(const bs_multiset_impl &src, Cloner cloner, Disposer disposer); + + #else + + using tree_type::clone_from; + + #endif //#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED + + //! @copydoc ::boost::intrusive::bstree::clone_from(bstree&&,Cloner,Disposer) + template + void clone_from(BOOST_RV_REF(bs_multiset_impl) src, Cloner cloner, Disposer disposer) + { tree_type::clone_from(BOOST_MOVE_BASE(tree_type, src), cloner, disposer); } + + //! @copydoc ::boost::intrusive::bstree::insert_equal(reference) + iterator insert(reference value) + { return tree_type::insert_equal(value); } + + //! @copydoc ::boost::intrusive::bstree::insert_equal(const_iterator,reference) + iterator insert(const_iterator hint, reference value) + { return tree_type::insert_equal(hint, value); } + + //! @copydoc ::boost::intrusive::bstree::insert_equal(Iterator,Iterator) + template + void insert(Iterator b, Iterator e) + { tree_type::insert_equal(b, e); } + + #ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED + //! @copydoc ::boost::intrusive::bstree::insert_before + iterator insert_before(const_iterator pos, reference value) BOOST_NOEXCEPT; + + //! @copydoc ::boost::intrusive::bstree::push_back + void push_back(reference value) BOOST_NOEXCEPT; + + //! @copydoc ::boost::intrusive::bstree::push_front + void push_front(reference value) BOOST_NOEXCEPT; + + //! @copydoc ::boost::intrusive::bstree::erase(const_iterator) + iterator erase(const_iterator i) BOOST_NOEXCEPT; + + //! @copydoc ::boost::intrusive::bstree::erase(const_iterator,const_iterator) + 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); + + //! @copydoc ::boost::intrusive::bstree::erase(const KeyType&,KeyTypeKeyCompare) + template + size_type erase(const KeyType& key, KeyTypeKeyCompare comp); + + //! @copydoc ::boost::intrusive::bstree::erase_and_dispose(const_iterator,Disposer) + template + 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) BOOST_NOEXCEPT; + + //! @copydoc ::boost::intrusive::bstree::erase_and_dispose(const key_type &, Disposer) + template + size_type erase_and_dispose(const key_type &key, Disposer disposer); + + //! @copydoc ::boost::intrusive::bstree::erase_and_dispose(const KeyType&,KeyTypeKeyCompare,Disposer) + template + size_type erase_and_dispose(const KeyType& key, KeyTypeKeyCompare comp, Disposer disposer); + + //! @copydoc ::boost::intrusive::bstree::clear + void clear() BOOST_NOEXCEPT; + + //! @copydoc ::boost::intrusive::bstree::clear_and_dispose + template + 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; + + //! @copydoc ::boost::intrusive::bstree::count(const KeyType&,KeyTypeKeyCompare)const + template + size_type count(const KeyType& key, KeyTypeKeyCompare comp) const; + + //! @copydoc ::boost::intrusive::bstree::lower_bound(const key_type &) + iterator lower_bound(const key_type &key); + + //! @copydoc ::boost::intrusive::bstree::lower_bound(const KeyType&,KeyTypeKeyCompare) + template + iterator lower_bound(const KeyType& key, KeyTypeKeyCompare comp); + + //! @copydoc ::boost::intrusive::bstree::lower_bound(const key_type &)const + const_iterator lower_bound(const key_type &key) const; + + //! @copydoc ::boost::intrusive::bstree::lower_bound(const KeyType&,KeyTypeKeyCompare)const + template + const_iterator lower_bound(const KeyType& key, KeyTypeKeyCompare comp) const; + + //! @copydoc ::boost::intrusive::bstree::upper_bound(const key_type &) + iterator upper_bound(const key_type &key); + + //! @copydoc ::boost::intrusive::bstree::upper_bound(const KeyType&,KeyTypeKeyCompare) + template + iterator upper_bound(const KeyType& key, KeyTypeKeyCompare comp); + + //! @copydoc ::boost::intrusive::bstree::upper_bound(const key_type &)const + const_iterator upper_bound(const key_type &key) const; + + //! @copydoc ::boost::intrusive::bstree::upper_bound(const KeyType&,KeyTypeKeyCompare)const + template + const_iterator upper_bound(const KeyType& key, KeyTypeKeyCompare comp) const; + + //! @copydoc ::boost::intrusive::bstree::find(const key_type &) + iterator find(const key_type &key); + + //! @copydoc ::boost::intrusive::bstree::find(const KeyType&,KeyTypeKeyCompare) + template + iterator find(const KeyType& key, KeyTypeKeyCompare comp); + + //! @copydoc ::boost::intrusive::bstree::find(const key_type &)const + const_iterator find(const key_type &key) const; + + //! @copydoc ::boost::intrusive::bstree::find(const KeyType&,KeyTypeKeyCompare)const + template + const_iterator find(const KeyType& key, KeyTypeKeyCompare comp) const; + + //! @copydoc ::boost::intrusive::bstree::equal_range(const key_type &) + std::pair equal_range(const key_type &key); + + //! @copydoc ::boost::intrusive::bstree::equal_range(const KeyType&,KeyTypeKeyCompare) + template + std::pair equal_range(const KeyType& key, KeyTypeKeyCompare comp); + + //! @copydoc ::boost::intrusive::bstree::equal_range(const key_type &)const + std::pair + equal_range(const key_type &key) const; + + //! @copydoc ::boost::intrusive::bstree::equal_range(const KeyType&,KeyTypeKeyCompare)const + template + std::pair + equal_range(const KeyType& key, KeyTypeKeyCompare comp) const; + + //! @copydoc ::boost::intrusive::bstree::bounded_range(const key_type &,const key_type &,bool,bool) + std::pair bounded_range + (const key_type & lower_key, const key_type & upper_key, bool left_closed, bool right_closed); + + //! @copydoc ::boost::intrusive::bstree::bounded_range(const KeyType&,const KeyType&,KeyTypeKeyCompare,bool,bool) + template + std::pair bounded_range + (const KeyType& lower_key, const KeyType& upper_key, KeyTypeKeyCompare comp, bool left_closed, bool right_closed); + + //! @copydoc ::boost::intrusive::bstree::bounded_range(const key_type &,const key_type &,bool,bool)const + std::pair + bounded_range(const key_type & lower_key, const key_type & upper_key, bool left_closed, bool right_closed) const; + + //! @copydoc ::boost::intrusive::bstree::bounded_range(const KeyType&,const KeyType&,KeyTypeKeyCompare,bool,bool)const + template + std::pair bounded_range + (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) BOOST_NOEXCEPT; + + //! @copydoc ::boost::intrusive::bstree::s_iterator_to(const_reference) + static const_iterator s_iterator_to(const_reference value) BOOST_NOEXCEPT; + + //! @copydoc ::boost::intrusive::bstree::iterator_to(reference) + iterator iterator_to(reference value) BOOST_NOEXCEPT; + + //! @copydoc ::boost::intrusive::bstree::iterator_to(const_reference)const + const_iterator iterator_to(const_reference value) const BOOST_NOEXCEPT; + + //! @copydoc ::boost::intrusive::bstree::init_node(reference) + static void init_node(reference value) BOOST_NOEXCEPT; + + //! @copydoc ::boost::intrusive::bstree::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) BOOST_NOEXCEPT; + + //! @copydoc ::boost::intrusive::bstree::remove_node + void remove_node(reference value) BOOST_NOEXCEPT; + + //! @copydoc ::boost::intrusive::bstree::merge_equal + template + void merge(bs_multiset &source); + + //! @copydoc ::boost::intrusive::bstree::merge_equal + template + void merge(bs_set &source); + + #else + + template + void merge(bs_multiset_impl &source) + { return tree_type::merge_equal(source); } + + template + void merge(bs_set_impl &source) + { return tree_type::merge_equal(source); } + + #endif //#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED +}; + +#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED) + +template +bool operator!= (const bs_multiset_impl &x, const bs_multiset_impl &y); + +template +bool operator>(const bs_multiset_impl &x, const bs_multiset_impl &y); + +template +bool operator<=(const bs_multiset_impl &x, const bs_multiset_impl &y); + +template +bool operator>=(const bs_multiset_impl &x, const bs_multiset_impl &y); + +template +void swap(bs_multiset_impl &x, bs_multiset_impl &y); + +#endif //#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED) + +//! Helper metafunction to define a \c bs_multiset that yields to the same type when the +//! same options (either explicitly or implicitly) are used. +#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED) || defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES) +template +#else +template +#endif +struct make_bs_multiset +{ + /// @cond + typedef typename pack_options + < bstree_defaults, + #if !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES) + O1, O2, O3, O4, O5, O6 + #else + Options... + #endif + >::type packed_options; + + typedef typename detail::get_value_traits + ::type value_traits; + + typedef bs_multiset_impl + < value_traits + , typename packed_options::key_of_value + , typename packed_options::compare + , typename packed_options::size_type + , packed_options::constant_time_size + , typename packed_options::header_holder_type + > implementation_defined; + /// @endcond + typedef implementation_defined type; +}; + +#ifndef BOOST_INTRUSIVE_DOXYGEN_INVOKED + +#if !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES) +template +#else +template +#endif +class bs_multiset + : public make_bs_multiset::type +{ + typedef typename make_bs_multiset::type Base; + + BOOST_MOVABLE_BUT_NOT_COPYABLE(bs_multiset) + + public: + typedef typename Base::key_compare key_compare; + typedef typename Base::value_traits value_traits; + typedef typename Base::iterator iterator; + typedef typename Base::const_iterator const_iterator; + + //Assert if passed value traits are compatible with the type + BOOST_STATIC_ASSERT((detail::is_same::value)); + + BOOST_INTRUSIVE_FORCEINLINE bs_multiset() + : Base() + {} + + BOOST_INTRUSIVE_FORCEINLINE explicit bs_multiset( const key_compare &cmp, const value_traits &v_traits = value_traits()) + : Base(cmp, v_traits) + {} + + template + BOOST_INTRUSIVE_FORCEINLINE bs_multiset( Iterator b, Iterator e + , const key_compare &cmp = key_compare() + , const value_traits &v_traits = value_traits()) + : Base(b, e, cmp, v_traits) + {} + + BOOST_INTRUSIVE_FORCEINLINE bs_multiset(BOOST_RV_REF(bs_multiset) x) + : Base(BOOST_MOVE_BASE(Base, x)) + {} + + BOOST_INTRUSIVE_FORCEINLINE bs_multiset& operator=(BOOST_RV_REF(bs_multiset) x) + { return static_cast(this->Base::operator=(BOOST_MOVE_BASE(Base, x))); } + + template + BOOST_INTRUSIVE_FORCEINLINE void clone_from(const bs_multiset &src, Cloner cloner, Disposer disposer) + { Base::clone_from(src, cloner, disposer); } + + template + 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_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_NOEXCEPT + { return static_cast(Base::container_from_end_iterator(end_iterator)); } + + 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_NOEXCEPT + { return static_cast(Base::container_from_iterator(it)); } +}; + +#endif + +} //namespace intrusive +} //namespace boost + +#include + +#endif //BOOST_INTRUSIVE_BS_SET_HPP diff --git a/third_party/boost/libs/intrusive/include/boost/intrusive/bs_set_hook.hpp b/third_party/boost/libs/intrusive/include/boost/intrusive/bs_set_hook.hpp new file mode 100644 index 00000000000..a64c15ace59 --- /dev/null +++ b/third_party/boost/libs/intrusive/include/boost/intrusive/bs_set_hook.hpp @@ -0,0 +1,288 @@ +///////////////////////////////////////////////////////////////////////////// +// +// (C) Copyright Ion Gaztanaga 2007-2013 +// +// 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_BS_SET_HOOK_HPP +#define BOOST_INTRUSIVE_BS_SET_HOOK_HPP + +#include +#include + +#include +#include +#include +#include + +#if defined(BOOST_HAS_PRAGMA_ONCE) +# pragma once +#endif + +namespace boost { +namespace intrusive { + +//! Helper metafunction to define a \c bs_set_base_hook that yields to the same +//! type when the same options (either explicitly or implicitly) are used. +#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED) || defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES) +template +#else +template +#endif +struct make_bs_set_base_hook +{ + /// @cond + typedef typename pack_options + #if !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES) + < hook_defaults, O1, O2, O3> + #else + < hook_defaults, Options...> + #endif + ::type packed_options; + + typedef generic_hook + < BsTreeAlgorithms + , tree_node_traits + , typename packed_options::tag + , packed_options::link_mode + , BsTreeBaseHookId + > implementation_defined; + /// @endcond + typedef implementation_defined type; +}; + +//! Derive a class from bs_set_base_hook in order to store objects in +//! in a bs_set/bs_multiset. bs_set_base_hook holds the data necessary to maintain +//! the bs_set/bs_multiset and provides an appropriate value_traits class for bs_set/bs_multiset. +//! +//! The hook admits the following options: \c tag<>, \c void_pointer<>, +//! \c link_mode<>. +//! +//! \c tag<> defines a tag to identify the node. +//! The same tag value can be used in different classes, but if a class is +//! derived from more than one \c list_base_hook, then each \c list_base_hook needs its +//! unique tag. +//! +//! \c void_pointer<> is the pointer type that will be used internally in the hook +//! and the container configured to use this hook. +//! +//! \c link_mode<> will specify the linking mode of the hook (\c normal_link, +//! \c auto_unlink or \c safe_link). +#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED) || defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES) +template +#else +template +#endif +class bs_set_base_hook + : public make_bs_set_base_hook + #if !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES) + + #else + + #endif + ::type + +{ + #if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED) + public: + //! Effects: If link_mode is \c auto_unlink or \c safe_link + //! initializes the node to an unlinked state. + //! + //! Throws: Nothing. + bs_set_base_hook(); + + //! Effects: If link_mode is \c auto_unlink or \c safe_link + //! initializes the node to an unlinked state. The argument is ignored. + //! + //! Throws: Nothing. + //! + //! Rationale: Providing a copy-constructor + //! 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. + bs_set_base_hook(const bs_set_base_hook& ); + + //! Effects: Empty function. The argument is ignored. + //! + //! Throws: Nothing. + //! + //! Rationale: Providing an assignment operator + //! 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. + bs_set_base_hook& operator=(const bs_set_base_hook& ); + + //! 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 + //! object is stored in a set an assertion is raised. If link_mode is + //! \c auto_unlink and \c is_linked() is true, the node is unlinked. + //! + //! Throws: Nothing. + ~bs_set_base_hook(); + + //! Effects: Swapping two nodes swaps the position of the elements + //! related to those nodes in one or two containers. That is, if the node + //! this is part of the element e1, the node x is part of the element e2 + //! and both elements are included in the containers s1 and s2, then after + //! the swap-operation e1 is in s2 at the position of e2 and e2 is in s1 + //! at the position of e1. If one element is not in a container, then + //! after the swap-operation the other element is not in a container. + //! Iterators to e1 and e2 related to those nodes are invalidated. + //! + //! Complexity: Constant + //! + //! Throws: Nothing. + void swap_nodes(bs_set_base_hook &other); + + //! Precondition: link_mode must be \c safe_link or \c auto_unlink. + //! + //! Returns: true, if the node belongs to a container, false + //! otherwise. This function can be used to test whether \c set::iterator_to + //! will return a valid iterator. + //! + //! Complexity: Constant + bool is_linked() const; + + //! 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(); + #endif +}; + +//! Helper metafunction to define a \c bs_set_member_hook that yields to the same +//! type when the same options (either explicitly or implicitly) are used. +#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED) || defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES) +template +#else +template +#endif +struct make_bs_set_member_hook +{ + /// @cond + typedef typename pack_options + #if !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES) + < hook_defaults, O1, O2, O3> + #else + < hook_defaults, Options...> + #endif + + ::type packed_options; + + typedef generic_hook + < BsTreeAlgorithms + , tree_node_traits + , member_tag + , packed_options::link_mode + , NoBaseHookId + > implementation_defined; + /// @endcond + typedef implementation_defined type; +}; + +//! Put a public data member bs_set_member_hook in order to store objects of this class in +//! a bs_set/bs_multiset. bs_set_member_hook holds the data necessary for maintaining the +//! bs_set/bs_multiset and provides an appropriate value_traits class for bs_set/bs_multiset. +//! +//! The hook admits the following options: \c void_pointer<>, \c link_mode<>. +//! +//! \c void_pointer<> is the pointer type that will be used internally in the hook +//! and the container configured to use this hook. +//! +//! \c link_mode<> will specify the linking mode of the hook (\c normal_link, +//! \c auto_unlink or \c safe_link). +#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED) || defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES) +template +#else +template +#endif +class bs_set_member_hook + : public make_bs_set_member_hook + #if !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES) + + #else + + #endif + ::type +{ + #if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED) + public: + //! Effects: If link_mode is \c auto_unlink or \c safe_link + //! initializes the node to an unlinked state. + //! + //! Throws: Nothing. + bs_set_member_hook(); + + //! Effects: If link_mode is \c auto_unlink or \c safe_link + //! initializes the node to an unlinked state. The argument is ignored. + //! + //! Throws: Nothing. + //! + //! Rationale: Providing a copy-constructor + //! 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. + bs_set_member_hook(const bs_set_member_hook& ); + + //! Effects: Empty function. The argument is ignored. + //! + //! Throws: Nothing. + //! + //! Rationale: Providing an assignment operator + //! 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. + bs_set_member_hook& operator=(const bs_set_member_hook& ); + + //! 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 + //! object is stored in a set an assertion is raised. If link_mode is + //! \c auto_unlink and \c is_linked() is true, the node is unlinked. + //! + //! Throws: Nothing. + ~bs_set_member_hook(); + + //! Effects: Swapping two nodes swaps the position of the elements + //! related to those nodes in one or two containers. That is, if the node + //! this is part of the element e1, the node x is part of the element e2 + //! and both elements are included in the containers s1 and s2, then after + //! the swap-operation e1 is in s2 at the position of e2 and e2 is in s1 + //! at the position of e1. If one element is not in a container, then + //! after the swap-operation the other element is not in a container. + //! Iterators to e1 and e2 related to those nodes are invalidated. + //! + //! Complexity: Constant + //! + //! Throws: Nothing. + void swap_nodes(bs_set_member_hook &other); + + //! Precondition: link_mode must be \c safe_link or \c auto_unlink. + //! + //! Returns: true, if the node belongs to a container, false + //! otherwise. This function can be used to test whether \c set::iterator_to + //! will return a valid iterator. + //! + //! Complexity: Constant + bool is_linked() const; + + //! 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(); + #endif +}; + +} //namespace intrusive +} //namespace boost + +#include + +#endif //BOOST_INTRUSIVE_BS_SET_HOOK_HPP diff --git a/third_party/boost/libs/intrusive/include/boost/intrusive/bstree.hpp b/third_party/boost/libs/intrusive/include/boost/intrusive/bstree.hpp new file mode 100644 index 00000000000..51687ebd27f --- /dev/null +++ b/third_party/boost/libs/intrusive/include/boost/intrusive/bstree.hpp @@ -0,0 +1,2238 @@ +///////////////////////////////////////////////////////////////////////////// +// +// (C) Copyright Ion Gaztanaga 2013-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_BSTREE_HPP +#define BOOST_INTRUSIVE_BSTREE_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 +#include + +#include +#include //size_t... +#include //less, equal_to + +#if defined(BOOST_HAS_PRAGMA_ONCE) +# pragma once +#endif + +namespace boost { +namespace intrusive { + +/// @cond + +struct default_bstree_hook_applier +{ template struct apply{ typedef typename T::default_bstree_hook type; }; }; + +template<> +struct is_default_hook_tag +{ static const bool value = true; }; + +struct bstree_defaults +{ + typedef default_bstree_hook_applier proto_value_traits; + static const bool constant_time_size = true; + typedef std::size_t size_type; + typedef void compare; + typedef void key_of_value; + static const bool floating_point = true; //For sgtree + typedef void priority; //For treap + typedef void header_holder_type; +}; + +template +struct bstbase3 +{ + typedef ValueTraits value_traits; + typedef typename value_traits::node_traits node_traits; + typedef typename node_traits::node node_type; + typedef typename get_algo::type node_algorithms; + typedef typename node_traits::node_ptr node_ptr; + typedef typename node_traits::const_node_ptr const_node_ptr; + typedef tree_iterator iterator; + typedef tree_iterator const_iterator; + typedef boost::intrusive::reverse_iterator reverse_iterator; + typedef boost::intrusive::reverse_iterator const_reverse_iterator; + typedef BOOST_INTRUSIVE_IMPDEF(typename value_traits::pointer) pointer; + typedef BOOST_INTRUSIVE_IMPDEF(typename value_traits::const_pointer) const_pointer; + typedef BOOST_INTRUSIVE_IMPDEF(typename pointer_traits::element_type) value_type; + typedef BOOST_INTRUSIVE_IMPDEF(typename pointer_traits::reference) reference; + typedef BOOST_INTRUSIVE_IMPDEF(typename pointer_traits::reference) const_reference; + typedef BOOST_INTRUSIVE_IMPDEF(typename pointer_traits::difference_type) difference_type; + typedef typename detail::get_header_holder_type + < value_traits,HeaderHolder >::type header_holder_type; + + static const bool safemode_or_autounlink = is_safe_autounlink::value; + static const bool stateful_value_traits = detail::is_stateful_value_traits::value; + static const bool has_container_from_iterator = + detail::is_same< header_holder_type, detail::default_header_holder< node_traits > >::value; + + struct holder_t : public ValueTraits + { + BOOST_INTRUSIVE_FORCEINLINE explicit holder_t(const ValueTraits &vtraits) + : ValueTraits(vtraits) + {} + header_holder_type root; + } holder; + + static bstbase3 &get_tree_base_from_end_iterator(const const_iterator &end_iterator) + { + BOOST_STATIC_ASSERT(has_container_from_iterator); + node_ptr p = end_iterator.pointed_node(); + header_holder_type* h = header_holder_type::get_holder(p); + holder_t *holder = get_parent_from_member(h, &holder_t::root); + bstbase3 *base = get_parent_from_member (holder, &bstbase3::holder); + return *base; + } + + BOOST_INTRUSIVE_FORCEINLINE bstbase3(const ValueTraits &vtraits) + : holder(vtraits) + { + node_algorithms::init_header(this->header_ptr()); + } + + BOOST_INTRUSIVE_FORCEINLINE node_ptr header_ptr() + { return holder.root.get_node(); } + + BOOST_INTRUSIVE_FORCEINLINE const_node_ptr header_ptr() const + { return holder.root.get_node(); } + + BOOST_INTRUSIVE_FORCEINLINE const value_traits &get_value_traits() const + { return this->holder; } + + BOOST_INTRUSIVE_FORCEINLINE value_traits &get_value_traits() + { return this->holder; } + + typedef typename boost::intrusive::value_traits_pointers + ::const_value_traits_ptr const_value_traits_ptr; + + BOOST_INTRUSIVE_FORCEINLINE const_value_traits_ptr priv_value_traits_ptr() const + { return pointer_traits::pointer_to(this->get_value_traits()); } + + 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_NOEXCEPT + { return cbegin(); } + + BOOST_INTRUSIVE_FORCEINLINE const_iterator cbegin() const BOOST_NOEXCEPT + { return const_iterator(node_algorithms::begin_node(this->header_ptr()), this->priv_value_traits_ptr()); } + + 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_NOEXCEPT + { return cend(); } + + 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() + { return iterator(node_algorithms::root_node(this->header_ptr()), this->priv_value_traits_ptr()); } + + BOOST_INTRUSIVE_FORCEINLINE const_iterator root() const + { return croot(); } + + BOOST_INTRUSIVE_FORCEINLINE const_iterator croot() const + { return const_iterator(node_algorithms::root_node(this->header_ptr()), this->priv_value_traits_ptr()); } + + BOOST_INTRUSIVE_FORCEINLINE reverse_iterator rbegin() + { return reverse_iterator(end()); } + + BOOST_INTRUSIVE_FORCEINLINE const_reverse_iterator rbegin() const + { return const_reverse_iterator(end()); } + + BOOST_INTRUSIVE_FORCEINLINE const_reverse_iterator crbegin() const + { return const_reverse_iterator(end()); } + + BOOST_INTRUSIVE_FORCEINLINE reverse_iterator rend() + { return reverse_iterator(begin()); } + + BOOST_INTRUSIVE_FORCEINLINE const_reverse_iterator rend() const + { return const_reverse_iterator(begin()); } + + BOOST_INTRUSIVE_FORCEINLINE const_reverse_iterator crend() const + { return const_reverse_iterator(begin()); } + + void replace_node(iterator replace_this, reference with_this) + { + node_algorithms::replace_node( get_value_traits().to_node_ptr(*replace_this) + , this->header_ptr() + , get_value_traits().to_node_ptr(with_this)); + BOOST_IF_CONSTEXPR(safemode_or_autounlink) + node_algorithms::init(replace_this.pointed_node()); + } + + BOOST_INTRUSIVE_FORCEINLINE void rebalance() BOOST_NOEXCEPT + { node_algorithms::rebalance(this->header_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) 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) 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) 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 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) + { node_algorithms::init(value_traits::to_node_ptr(value)); } + +}; + +template +struct get_compare +{ + typedef Less type; +}; + +template +struct get_compare +{ + typedef ::std::less type; +}; + +template +struct get_key_of_value +{ + typedef KeyOfValue type; +}; + +template +struct get_key_of_value +{ + typedef ::boost::intrusive::detail::identity type; +}; + +template +struct bst_key_types +{ + typedef typename + boost::movelib::pointer_element::type value_type; + typedef typename get_key_of_value + < VoidOrKeyOfValue, value_type>::type key_of_value; + typedef typename key_of_value::type key_type; + typedef typename get_compare< VoidOrKeyComp + , key_type + >::type key_compare; + typedef tree_value_compare + value_compare; +}; + +template +struct bstbase2 + //Put the (possibly empty) functor in the first position to get EBO in MSVC + //Use public inheritance to avoid MSVC bugs with closures + : public detail::ebo_functor_holder + < typename bst_key_types + < typename ValueTraits::pointer + , VoidOrKeyOfValue + , VoidOrKeyComp + + >::value_compare + > + , public bstbase3 +{ + typedef bstbase3 treeheader_t; + typedef bst_key_types< typename ValueTraits::pointer + , VoidOrKeyOfValue + , VoidOrKeyComp> key_types; + typedef typename treeheader_t::value_traits value_traits; + typedef typename treeheader_t::node_algorithms node_algorithms; + typedef typename ValueTraits::value_type value_type; + typedef typename key_types::key_type key_type; + typedef typename key_types::key_of_value key_of_value; + typedef typename key_types::key_compare key_compare; + typedef typename key_types::value_compare value_compare; + typedef typename treeheader_t::iterator iterator; + typedef typename treeheader_t::const_iterator const_iterator; + typedef typename treeheader_t::node_ptr node_ptr; + typedef typename treeheader_t::const_node_ptr const_node_ptr; + + bstbase2(const key_compare &comp, const ValueTraits &vtraits) + : detail::ebo_functor_holder(value_compare(comp)), treeheader_t(vtraits) + {} + + const value_compare &get_comp() const + { return this->get(); } + + value_compare &get_comp() + { return this->get(); } + + typedef BOOST_INTRUSIVE_IMPDEF(typename value_traits::pointer) pointer; + typedef BOOST_INTRUSIVE_IMPDEF(typename value_traits::const_pointer) const_pointer; + typedef BOOST_INTRUSIVE_IMPDEF(typename pointer_traits::reference) reference; + typedef BOOST_INTRUSIVE_IMPDEF(typename pointer_traits::reference) const_reference; + typedef BOOST_INTRUSIVE_IMPDEF(typename pointer_traits::difference_type) difference_type; + typedef typename node_algorithms::insert_commit_data insert_commit_data; + + BOOST_INTRUSIVE_FORCEINLINE value_compare value_comp() const + { return this->get_comp(); } + + BOOST_INTRUSIVE_FORCEINLINE key_compare key_comp() const + { return this->get_comp().key_comp(); } + + //lower_bound + BOOST_INTRUSIVE_FORCEINLINE iterator lower_bound(const key_type &key) + { return this->lower_bound(key, this->key_comp()); } + + BOOST_INTRUSIVE_FORCEINLINE const_iterator lower_bound(const key_type &key) const + { return this->lower_bound(key, this->key_comp()); } + + template + iterator lower_bound(const KeyType &key, KeyTypeKeyCompare comp) + { + return iterator(node_algorithms::lower_bound + (this->header_ptr(), key, this->key_node_comp(comp)), this->priv_value_traits_ptr()); + } + + template + const_iterator lower_bound(const KeyType &key, KeyTypeKeyCompare comp) const + { + return const_iterator(node_algorithms::lower_bound + (this->header_ptr(), key, this->key_node_comp(comp)), this->priv_value_traits_ptr()); + } + + //upper_bound + BOOST_INTRUSIVE_FORCEINLINE iterator upper_bound(const key_type &key) + { return this->upper_bound(key, this->key_comp()); } + + template + iterator upper_bound(const KeyType &key, KeyTypeKeyCompare comp) + { + return iterator(node_algorithms::upper_bound + (this->header_ptr(), key, this->key_node_comp(comp)), this->priv_value_traits_ptr()); + } + + BOOST_INTRUSIVE_FORCEINLINE const_iterator upper_bound(const key_type &key) const + { return this->upper_bound(key, this->key_comp()); } + + template + const_iterator upper_bound(const KeyType &key, KeyTypeKeyCompare comp) const + { + return const_iterator(node_algorithms::upper_bound + (this->header_ptr(), key, this->key_node_comp(comp)), this->priv_value_traits_ptr()); + } + + template + struct key_node_comp_ret + { typedef detail::key_nodeptr_comp type; }; + + template + BOOST_INTRUSIVE_FORCEINLINE typename key_node_comp_ret::type key_node_comp(KeyTypeKeyCompare comp) const + { + return detail::key_nodeptr_comp(comp, &this->get_value_traits()); + } + + //find + BOOST_INTRUSIVE_FORCEINLINE iterator find(const key_type &key) + { return this->find(key, this->key_comp()); } + + template + iterator find(const KeyType &key, KeyTypeKeyCompare comp) + { + return iterator + (node_algorithms::find(this->header_ptr(), key, this->key_node_comp(comp)), this->priv_value_traits_ptr()); + } + + BOOST_INTRUSIVE_FORCEINLINE const_iterator find(const key_type &key) const + { return this->find(key, this->key_comp()); } + + template + const_iterator find(const KeyType &key, KeyTypeKeyCompare comp) const + { + return const_iterator + (node_algorithms::find(this->header_ptr(), key, this->key_node_comp(comp)), this->priv_value_traits_ptr()); + } + + //equal_range + BOOST_INTRUSIVE_FORCEINLINE std::pair equal_range(const key_type &key) + { return this->equal_range(key, this->key_comp()); } + + 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)); + return std::pair( iterator(ret.first, this->priv_value_traits_ptr()) + , iterator(ret.second, this->priv_value_traits_ptr())); + } + + BOOST_INTRUSIVE_FORCEINLINE std::pair + equal_range(const key_type &key) const + { return this->equal_range(key, this->key_comp()); } + + template + 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)); + return std::pair( const_iterator(ret.first, this->priv_value_traits_ptr()) + , const_iterator(ret.second, this->priv_value_traits_ptr())); + } + + //lower_bound_range + BOOST_INTRUSIVE_FORCEINLINE std::pair lower_bound_range(const key_type &key) + { return this->lower_bound_range(key, this->key_comp()); } + + 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)); + return std::pair( iterator(ret.first, this->priv_value_traits_ptr()) + , iterator(ret.second, this->priv_value_traits_ptr())); + } + + BOOST_INTRUSIVE_FORCEINLINE std::pair + lower_bound_range(const key_type &key) const + { return this->lower_bound_range(key, this->key_comp()); } + + template + 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)); + return std::pair( const_iterator(ret.first, this->priv_value_traits_ptr()) + , const_iterator(ret.second, this->priv_value_traits_ptr())); + } + + //bounded_range + BOOST_INTRUSIVE_FORCEINLINE std::pair bounded_range + (const key_type &lower_key, const key_type &upper_key, bool left_closed, bool right_closed) + { return this->bounded_range(lower_key, upper_key, this->key_comp(), left_closed, right_closed); } + + template + 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); + return std::pair( iterator(ret.first, this->priv_value_traits_ptr()) + , iterator(ret.second, this->priv_value_traits_ptr())); + } + + BOOST_INTRUSIVE_FORCEINLINE std::pair bounded_range + (const key_type &lower_key, const key_type &upper_key, bool left_closed, bool right_closed) const + { return this->bounded_range(lower_key, upper_key, this->key_comp(), left_closed, right_closed); } + + template + 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); + return std::pair( const_iterator(ret.first, this->priv_value_traits_ptr()) + , const_iterator(ret.second, this->priv_value_traits_ptr())); + } + + //insert_unique_check + BOOST_INTRUSIVE_FORCEINLINE std::pair insert_unique_check + (const key_type &key, insert_commit_data &commit_data) + { return this->insert_unique_check(key, this->key_comp(), commit_data); } + + BOOST_INTRUSIVE_FORCEINLINE std::pair insert_unique_check + (const_iterator hint, const key_type &key, insert_commit_data &commit_data) + { return this->insert_unique_check(hint, key, this->key_comp(), commit_data); } + + template + BOOST_INTRUSIVE_DOC1ST(std::pair + , typename detail::disable_if_convertible + >::type) + insert_unique_check + (const KeyType &key, KeyTypeKeyCompare comp, insert_commit_data &commit_data) + { + std::pair ret = + (node_algorithms::insert_unique_check + (this->header_ptr(), key, this->key_node_comp(comp), commit_data)); + return std::pair(iterator(ret.first, this->priv_value_traits_ptr()), ret.second); + } + + template + std::pair insert_unique_check + (const_iterator hint, const KeyType &key, KeyTypeKeyCompare comp, insert_commit_data &commit_data) + { + std::pair ret = + (node_algorithms::insert_unique_check + (this->header_ptr(), hint.pointed_node(), key, this->key_node_comp(comp), commit_data)); + return std::pair(iterator(ret.first, this->priv_value_traits_ptr()), ret.second); + } +}; + +//Due to MSVC's EBO implementation, to save space and maintain the ABI, we must put the non-empty size member +//in the first position, but if size is not going to be stored then we'll use an specialization +//that doesn't inherit from size_holder +template +struct bstbase_hack + : public detail::size_holder + , public bstbase2 < ValueTraits, VoidOrKeyOfValue, VoidOrKeyComp, AlgoType, HeaderHolder> +{ + typedef bstbase2< ValueTraits, VoidOrKeyOfValue, VoidOrKeyComp, AlgoType, HeaderHolder> base_type; + typedef typename base_type::key_compare key_compare; + typedef typename base_type::value_compare value_compare; + typedef SizeType size_type; + typedef typename base_type::node_traits node_traits; + typedef typename get_algo + ::type algo_type; + + BOOST_INTRUSIVE_FORCEINLINE bstbase_hack(const key_compare & comp, const ValueTraits &vtraits) + : base_type(comp, vtraits) + { + this->sz_traits().set_size(size_type(0)); + } + + typedef detail::size_holder size_traits; + + BOOST_INTRUSIVE_FORCEINLINE size_traits &sz_traits() + { return static_cast(*this); } + + BOOST_INTRUSIVE_FORCEINLINE const size_traits &sz_traits() const + { return static_cast(*this); } +}; + +//Specialization for ConstantTimeSize == false +template +struct bstbase_hack + : public bstbase2 < ValueTraits, VoidOrKeyOfValue, VoidOrKeyComp, AlgoType, HeaderHolder> +{ + typedef bstbase2< ValueTraits, VoidOrKeyOfValue, VoidOrKeyComp, AlgoType, HeaderHolder> base_type; + typedef typename base_type::value_compare value_compare; + typedef typename base_type::key_compare key_compare; + BOOST_INTRUSIVE_FORCEINLINE bstbase_hack(const key_compare & comp, const ValueTraits &vtraits) + : base_type(comp, vtraits) + {} + + typedef detail::size_holder size_traits; + + BOOST_INTRUSIVE_FORCEINLINE size_traits sz_traits() const + { return size_traits(); } +}; + +//This class will +template +struct bstbase + : public bstbase_hack< ValueTraits, VoidOrKeyOfValue, VoidOrKeyComp, ConstantTimeSize, SizeType, AlgoType, HeaderHolder> +{ + typedef bstbase_hack< ValueTraits, VoidOrKeyOfValue, VoidOrKeyComp, ConstantTimeSize, SizeType, AlgoType, HeaderHolder> base_type; + typedef ValueTraits value_traits; + typedef typename base_type::value_compare value_compare; + typedef typename base_type::key_compare key_compare; + typedef typename base_type::const_reference const_reference; + typedef typename base_type::reference reference; + typedef typename base_type::iterator iterator; + typedef typename base_type::const_iterator const_iterator; + typedef typename base_type::node_traits node_traits; + typedef typename get_algo + ::type node_algorithms; + typedef SizeType size_type; + + BOOST_INTRUSIVE_FORCEINLINE bstbase(const key_compare & comp, const ValueTraits &vtraits) + : base_type(comp, vtraits) + {} + + //Detach all inserted nodes. This will add exception safety to bstree_impl + //constructors inserting elements. + ~bstbase() + { + if(is_safe_autounlink::value){ + node_algorithms::clear_and_dispose + ( this->header_ptr() + , detail::node_disposer + (detail::null_disposer(), &this->get_value_traits())); + node_algorithms::init(this->header_ptr()); + } + } +}; + + +/// @endcond + +//! The class template bstree is an unbalanced intrusive binary search tree +//! container. The no-throw guarantee holds only, if the key_compare object +//! doesn't throw. +//! +//! The complexity guarantees only hold if the tree is balanced, logarithmic +//! complexity would increase to linear if the tree is totally unbalanced. +//! +//! The template parameter \c T is the type to be managed by the container. +//! The user can specify additional options and if no options are provided +//! default options are used. +//! +//! The container supports the following options: +//! \c base_hook<>/member_hook<>/value_traits<>, +//! \c constant_time_size<>, \c size_type<> and +//! \c compare<>. +#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED) +template +#else +template +#endif +class bstree_impl + : public bstbase +{ + public: + /// @cond + typedef bstbase data_type; + typedef tree_iterator iterator_type; + typedef tree_iterator const_iterator_type; + /// @endcond + + typedef BOOST_INTRUSIVE_IMPDEF(ValueTraits) value_traits; + typedef BOOST_INTRUSIVE_IMPDEF(typename value_traits::pointer) pointer; + typedef BOOST_INTRUSIVE_IMPDEF(typename value_traits::const_pointer) const_pointer; + typedef BOOST_INTRUSIVE_IMPDEF(typename pointer_traits::element_type) value_type; + typedef BOOST_INTRUSIVE_IMPDEF(typename data_type::key_type) key_type; + typedef BOOST_INTRUSIVE_IMPDEF(typename data_type::key_of_value) key_of_value; + typedef BOOST_INTRUSIVE_IMPDEF(typename pointer_traits::reference) reference; + typedef BOOST_INTRUSIVE_IMPDEF(typename pointer_traits::reference) const_reference; + typedef BOOST_INTRUSIVE_IMPDEF(typename pointer_traits::difference_type) difference_type; + typedef BOOST_INTRUSIVE_IMPDEF(SizeType) size_type; + typedef BOOST_INTRUSIVE_IMPDEF(typename data_type::value_compare) value_compare; + typedef BOOST_INTRUSIVE_IMPDEF(typename data_type::key_compare) key_compare; + typedef BOOST_INTRUSIVE_IMPDEF(iterator_type) iterator; + typedef BOOST_INTRUSIVE_IMPDEF(const_iterator_type) const_iterator; + typedef BOOST_INTRUSIVE_IMPDEF(boost::intrusive::reverse_iterator) reverse_iterator; + typedef BOOST_INTRUSIVE_IMPDEF(boost::intrusive::reverse_iterator) const_reverse_iterator; + typedef BOOST_INTRUSIVE_IMPDEF(typename value_traits::node_traits) node_traits; + typedef BOOST_INTRUSIVE_IMPDEF(typename node_traits::node) node; + typedef BOOST_INTRUSIVE_IMPDEF(typename node_traits::node_ptr) node_ptr; + typedef BOOST_INTRUSIVE_IMPDEF(typename node_traits::const_node_ptr) const_node_ptr; + /// @cond + typedef typename get_algo::type algo_type; + /// @endcond + typedef BOOST_INTRUSIVE_IMPDEF(algo_type) node_algorithms; + + static const bool constant_time_size = ConstantTimeSize; + static const bool stateful_value_traits = detail::is_stateful_value_traits::value; + /// @cond + private: + + //noncopyable + BOOST_MOVABLE_BUT_NOT_COPYABLE(bstree_impl) + + static const bool safemode_or_autounlink = is_safe_autounlink::value; + + //Constant-time size is incompatible with auto-unlink hooks! + BOOST_STATIC_ASSERT(!(constant_time_size && ((int)value_traits::link_mode == (int)auto_unlink))); + + + protected: + + + /// @endcond + + public: + + typedef typename node_algorithms::insert_commit_data insert_commit_data; + + //! Effects: Constructs an empty container. + //! + //! Complexity: Constant. + //! + //! Throws: If value_traits::node_traits::node + //! constructor throws (this does not happen with predefined Boost.Intrusive hooks) + //! or the copy constructor of the key_compare object throws. Basic guarantee. + bstree_impl() + : data_type(key_compare(), value_traits()) + {} + + //! Effects: Constructs an empty container with given comparison and traits. + //! + //! Complexity: Constant. + //! + //! Throws: If value_traits::node_traits::node + //! constructor throws (this does not happen with predefined Boost.Intrusive hooks) + //! or the copy constructor of the key_compare object throws. Basic guarantee. + explicit bstree_impl( const key_compare &cmp, const value_traits &v_traits = value_traits()) + : data_type(cmp, v_traits) + {} + + //! Requires: Dereferencing iterator must yield an lvalue of type value_type. + //! cmp must be a comparison function that induces a strict weak ordering. + //! + //! Effects: Constructs an empty container and inserts elements from + //! [b, e). + //! + //! Complexity: Linear in N if [b, e) is already sorted using + //! comp and otherwise N * log N, where N is the distance between first and last. + //! + //! Throws: If value_traits::node_traits::node + //! constructor throws (this does not happen with predefined Boost.Intrusive hooks) + //! or the copy constructor/operator() of the key_compare object throws. Basic guarantee. + template + bstree_impl( bool unique, Iterator b, Iterator e + , const key_compare &cmp = key_compare() + , const value_traits &v_traits = value_traits()) + : data_type(cmp, v_traits) + { + //bstbase releases elements in case of exceptions + if(unique) + this->insert_unique(b, e); + else + this->insert_equal(b, e); + } + + //! Effects: Constructs a container moving resources from another container. + //! Internal comparison object and value traits are move constructed and + //! nodes belonging to x (except the node representing the "end") are linked to *this. + //! + //! Complexity: Constant. + //! + //! Throws: If value_traits::node_traits::node's + //! 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.get_comp()), ::boost::move(x.get_value_traits())) + { + this->swap(x); + } + + //! Effects: Equivalent to swap + //! + BOOST_INTRUSIVE_FORCEINLINE bstree_impl& operator=(BOOST_RV_REF(bstree_impl) x) + { this->swap(x); return *this; } + + #ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED + //! Effects: Detaches all elements from this. The objects in the set + //! are not deleted (i.e. no destructors are called), but the nodes according to + //! the value_traits template parameter are reinitialized and thus can be reused. + //! + //! Complexity: Linear to elements contained in *this. + //! + //! Throws: Nothing. + ~bstree_impl() + {} + + //! Effects: Returns an iterator pointing to the beginning of the container. + //! + //! Complexity: Constant. + //! + //! Throws: Nothing. + iterator begin() BOOST_NOEXCEPT; + + //! Effects: Returns a const_iterator pointing to the beginning of the container. + //! + //! Complexity: Constant. + //! + //! Throws: Nothing. + 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 BOOST_NOEXCEPT; + + //! Effects: Returns an iterator pointing to the end of the container. + //! + //! Complexity: Constant. + //! + //! Throws: Nothing. + iterator end() BOOST_NOEXCEPT; + + //! Effects: Returns a const_iterator pointing to the end of the container. + //! + //! Complexity: Constant. + //! + //! Throws: Nothing. + 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 BOOST_NOEXCEPT; + + //! Effects: Returns a reverse_iterator pointing to the beginning of the + //! reversed container. + //! + //! Complexity: Constant. + //! + //! Throws: Nothing. + reverse_iterator rbegin() BOOST_NOEXCEPT; + + //! Effects: Returns a const_reverse_iterator pointing to the beginning + //! of the reversed container. + //! + //! Complexity: Constant. + //! + //! Throws: Nothing. + const_reverse_iterator rbegin() const BOOST_NOEXCEPT; + + //! Effects: Returns a const_reverse_iterator pointing to the beginning + //! of the reversed container. + //! + //! Complexity: Constant. + //! + //! Throws: Nothing. + const_reverse_iterator crbegin() const BOOST_NOEXCEPT; + + //! Effects: Returns a reverse_iterator pointing to the end + //! of the reversed container. + //! + //! Complexity: Constant. + //! + //! Throws: Nothing. + reverse_iterator rend() BOOST_NOEXCEPT; + + //! Effects: Returns a const_reverse_iterator pointing to the end + //! of the reversed container. + //! + //! Complexity: Constant. + //! + //! Throws: Nothing. + const_reverse_iterator rend() const BOOST_NOEXCEPT; + + //! Effects: Returns a const_reverse_iterator pointing to the end + //! of the reversed container. + //! + //! Complexity: Constant. + //! + //! Throws: Nothing. + 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() 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 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 BOOST_NOEXCEPT; + + #endif //#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED + + //! Precondition: end_iterator must be a valid end iterator + //! of the container. + //! + //! Effects: Returns a const reference to the container associated to the end iterator + //! + //! Throws: Nothing. + //! + //! Complexity: Constant. + 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)); + } + + //! Precondition: end_iterator must be a valid end const_iterator + //! of the container. + //! + //! Effects: Returns a const reference to the container associated to the iterator + //! + //! Throws: Nothing. + //! + //! Complexity: Constant. + 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)); + } + + //! Precondition: it must be a valid iterator + //! of the container. + //! + //! Effects: Returns a const reference to the container associated to the iterator + //! + //! Throws: Nothing. + //! + //! Complexity: Logarithmic. + 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 + //! of container. + //! + //! Effects: Returns a const reference to the container associated to the end iterator + //! + //! Throws: Nothing. + //! + //! Complexity: Logarithmic. + 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 + + //! Effects: Returns the key_compare object used by the container. + //! + //! Complexity: Constant. + //! + //! Throws: If key_compare copy-constructor throws. + key_compare key_comp() const; + + //! Effects: Returns the value_compare object used by the container. + //! + //! Complexity: Constant. + //! + //! Throws: If value_compare copy-constructor throws. + value_compare value_comp() const; + + #endif //#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED + + //! Effects: Returns true if the container is empty. + //! + //! Complexity: Constant. + //! + //! Throws: Nothing. + bool empty() const BOOST_NOEXCEPT + { + if(ConstantTimeSize){ + return !this->data_type::sz_traits().get_size(); + } + else{ + return algo_type::unique(this->header_ptr()); + } + } + + //! Effects: Returns the number of elements stored in the container. + //! + //! Complexity: Linear to elements contained in *this + //! if constant-time size option is disabled. Constant time otherwise. + //! + //! Throws: Nothing. + size_type size() const BOOST_NOEXCEPT + { + BOOST_IF_CONSTEXPR(constant_time_size) + return this->sz_traits().get_size(); + else{ + return (size_type)node_algorithms::size(this->header_ptr()); + } + } + + //! Effects: Swaps the contents of two containers. + //! + //! Complexity: Constant. + //! + //! Throws: If the comparison functor's swap call throws. + void swap(bstree_impl& other) + { + //This can throw + ::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()); + } + + //! Requires: Disposer::operator()(pointer) shouldn't throw. + //! Cloner should yield to nodes equivalent to the original nodes. + //! + //! Effects: Erases all the elements from *this + //! calling Disposer::operator()(pointer), clones all the + //! elements from src calling Cloner::operator()(const_reference ) + //! and inserts them on *this. Copies the predicate from the source container. + //! + //! If cloner throws, all cloned elements are unlinked and disposed + //! calling Disposer::operator()(pointer). + //! + //! Complexity: Linear to erased plus inserted elements. + //! + //! Throws: If cloner throws or predicate copy assignment throws. Basic guarantee. + template + void clone_from(const bstree_impl &src, Cloner cloner, Disposer disposer) + { + this->clear_and_dispose(disposer); + if(!src.empty()){ + detail::exception_disposer + rollback(*this, disposer); + node_algorithms::clone + (src.header_ptr() + ,this->header_ptr() + ,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->get_comp() = src.get_comp(); + rollback.release(); + } + } + + //! Requires: Disposer::operator()(pointer) shouldn't throw. + //! Cloner should yield to nodes equivalent to the original nodes. + //! + //! Effects: Erases all the elements from *this + //! calling Disposer::operator()(pointer), clones all the + //! elements from src calling Cloner::operator()(reference) + //! and inserts them on *this. Copies the predicate from the source container. + //! + //! If cloner throws, all cloned elements are unlinked and disposed + //! calling Disposer::operator()(pointer). + //! + //! Complexity: Linear to erased plus inserted elements. + //! + //! Throws: If cloner throws or predicate copy assignment throws. Basic guarantee. + //! + //! Note: This version can modify the source container, useful to implement + //! move semantics. + template + void clone_from(BOOST_RV_REF(bstree_impl) src, Cloner cloner, Disposer disposer) + { + this->clear_and_dispose(disposer); + if(!src.empty()){ + detail::exception_disposer + rollback(*this, disposer); + node_algorithms::clone + (src.header_ptr() + ,this->header_ptr() + ,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->get_comp() = src.get_comp(); + rollback.release(); + } + } + + //! Requires: value must be an lvalue + //! + //! Effects: Inserts value into the container before the upper bound. + //! + //! Complexity: Average complexity for insert element is at + //! most logarithmic. + //! + //! Throws: If the internal key_compare ordering function throws. Strong guarantee. + //! + //! Note: Does not affect the validity of iterators and references. + //! No copy-constructors are called. + iterator insert_equal(reference value) + { + 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)); + iterator ret(node_algorithms::insert_equal_upper_bound + (this->header_ptr(), to_insert, this->key_node_comp(this->key_comp())), this->priv_value_traits_ptr()); + this->sz_traits().increment(); + return ret; + } + + //! Requires: value must be an lvalue, and "hint" must be + //! a valid iterator. + //! + //! Effects: Inserts x into the container, using "hint" as a hint to + //! where it will be inserted. If "hint" is the upper_bound + //! the insertion takes constant time (two comparisons in the worst case) + //! + //! Complexity: Logarithmic in general, but it is amortized + //! constant time if t is inserted immediately before hint. + //! + //! Throws: If the internal key_compare ordering function throws. Strong guarantee. + //! + //! Note: Does not affect the validity of iterators and references. + //! No copy-constructors are called. + iterator insert_equal(const_iterator hint, reference value) + { + 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)); + iterator ret(node_algorithms::insert_equal + (this->header_ptr(), hint.pointed_node(), to_insert, this->key_node_comp(this->key_comp())), this->priv_value_traits_ptr()); + this->sz_traits().increment(); + return ret; + } + + //! Requires: Dereferencing iterator must yield an lvalue + //! of type value_type. + //! + //! Effects: Inserts a each element of a range into the container + //! before the upper bound of the key of each element. + //! + //! Complexity: Insert range is in general O(N * log(N)), where N is the + //! size of the range. However, it is linear in N if the range is already sorted + //! by value_comp(). + //! + //! Throws: If the comparison functor call throws. + //! + //! Note: Does not affect the validity of iterators and references. + //! No copy-constructors are called. + template + void insert_equal(Iterator b, Iterator e) + { + iterator iend(this->end()); + for (; b != e; ++b) + this->insert_equal(iend, *b); + } + + //! Requires: value must be an lvalue + //! + //! Effects: Inserts value into the container if the value + //! is not already present. + //! + //! Complexity: Average complexity for insert element is at + //! most logarithmic. + //! + //! Throws: If the comparison functor call throws. + //! + //! Note: Does not affect the validity of iterators and references. + //! No copy-constructors are called. + std::pair insert_unique(reference value) + { + insert_commit_data commit_data; + std::pair ret = + (node_algorithms::insert_unique_check + (this->header_ptr(), key_of_value()(value), this->key_node_comp(this->key_comp()), commit_data)); + return std::pair + ( ret.second ? this->insert_unique_commit(value, commit_data) + : iterator(ret.first, this->priv_value_traits_ptr()) + , ret.second); + } + + //! Requires: value must be an lvalue, and "hint" must be + //! a valid iterator + //! + //! Effects: Tries to insert x into the container, using "hint" as a hint + //! to where it will be inserted. + //! + //! Complexity: Logarithmic in general, but it is amortized + //! constant time (two comparisons in the worst case) + //! if t is inserted immediately before hint. + //! + //! Throws: If the comparison functor call throws. + //! + //! Note: Does not affect the validity of iterators and references. + //! No copy-constructors are called. + iterator insert_unique(const_iterator hint, reference value) + { + insert_commit_data commit_data; + std::pair ret = + (node_algorithms::insert_unique_check + (this->header_ptr(), hint.pointed_node(), key_of_value()(value), this->key_node_comp(this->key_comp()), commit_data)); + return ret.second ? this->insert_unique_commit(value, commit_data) + : iterator(ret.first, this->priv_value_traits_ptr()); + } + + //! Requires: Dereferencing iterator must yield an lvalue + //! of type value_type. + //! + //! Effects: Tries to insert each element of a range into the container. + //! + //! Complexity: Insert range is in general O(N * log(N)), where N is the + //! size of the range. However, it is linear in N if the range is already sorted + //! by value_comp(). + //! + //! Throws: If the comparison functor call throws. + //! + //! Note: Does not affect the validity of iterators and references. + //! No copy-constructors are called. + template + void insert_unique(Iterator b, Iterator e) + { + if(this->empty()){ + iterator iend(this->end()); + for (; b != e; ++b) + this->insert_unique(iend, *b); + } + else{ + for (; b != e; ++b) + this->insert_unique(*b); + } + } + + #ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED + + //! Effects: Checks if a value can be inserted in the container, using + //! a user provided key instead of the value itself. + //! + //! Returns: If there is an equivalent value + //! returns a pair containing an iterator to the already present value + //! and false. If the value can be inserted returns true in the returned + //! pair boolean and fills "commit_data" that is meant to be used with + //! the "insert_commit" function. + //! + //! Complexity: Average complexity is at most logarithmic. + //! + //! Throws: If the comp ordering function throws. Strong guarantee. + std::pair insert_unique_check(const key_type &key, insert_commit_data &commit_data); + + //! Effects: Checks if a value can be inserted in the container, using + //! a user provided key instead of the value itself, using "hint" + //! as a hint to where it will be inserted. + //! + //! Returns: If there is an equivalent value + //! returns a pair containing an iterator to the already present value + //! and false. If the value can be inserted returns true in the returned + //! pair boolean and fills "commit_data" that is meant to be used with + //! the "insert_commit" function. + //! + //! Complexity: Logarithmic in general, but it's amortized + //! constant time if t is inserted immediately before hint. + //! + //! Throws: If the comp ordering function throws. Strong guarantee. + std::pair insert_unique_check(const_iterator hint, const key_type &key, insert_commit_data &commit_data); + + //! Requires: comp must be a comparison function that induces + //! the same strict weak ordering as key_compare. The difference is that + //! comp compares an arbitrary key with the contained values. + //! + //! Effects: Checks if a value can be inserted in the container, using + //! a user provided key instead of the value itself. + //! + //! Returns: If there is an equivalent value + //! returns a pair containing an iterator to the already present value + //! and false. If the value can be inserted returns true in the returned + //! pair boolean and fills "commit_data" that is meant to be used with + //! the "insert_commit" function. + //! + //! Complexity: Average complexity is at most logarithmic. + //! + //! Throws: If the comp ordering function throws. Strong guarantee. + //! + //! Notes: This function is used to improve performance when constructing + //! a value_type is expensive: if there is an equivalent value + //! the constructed object must be discarded. Many times, the part of the + //! node that is used to impose the order is much cheaper to construct + //! than the value_type and this function offers the possibility to use that + //! part to check if the insertion will be successful. + //! + //! If the check is successful, the user can construct the value_type and use + //! "insert_commit" to insert the object in constant-time. This gives a total + //! logarithmic complexity to the insertion: check(O(log(N)) + commit(O(1)). + //! + //! "commit_data" remains valid for a subsequent "insert_commit" only if no more + //! objects are inserted or erased from the container. + template + std::pair insert_unique_check + (const KeyType &key, KeyTypeKeyCompare comp, insert_commit_data &commit_data); + + //! Requires: comp must be a comparison function that induces + //! the same strict weak ordering as key_compare. The difference is that + //! comp compares an arbitrary key with the contained values. + //! + //! Effects: Checks if a value can be inserted in the container, using + //! a user provided key instead of the value itself, using "hint" + //! as a hint to where it will be inserted. + //! + //! Returns: If there is an equivalent value + //! returns a pair containing an iterator to the already present value + //! and false. If the value can be inserted returns true in the returned + //! pair boolean and fills "commit_data" that is meant to be used with + //! the "insert_commit" function. + //! + //! Complexity: Logarithmic in general, but it's amortized + //! constant time if t is inserted immediately before hint. + //! + //! Throws: If the comp ordering function throws. Strong guarantee. + //! + //! Notes: This function is used to improve performance when constructing + //! a value_type is expensive: if there is an equivalent value + //! the constructed object must be discarded. Many times, the part of the + //! constructing that is used to impose the order is much cheaper to construct + //! than the value_type and this function offers the possibility to use that key + //! to check if the insertion will be successful. + //! + //! If the check is successful, the user can construct the value_type and use + //! "insert_commit" to insert the object in constant-time. This can give a total + //! constant-time complexity to the insertion: check(O(1)) + commit(O(1)). + //! + //! "commit_data" remains valid for a subsequent "insert_commit" only if no more + //! objects are inserted or erased from the container. + template + std::pair insert_unique_check + (const_iterator hint, const KeyType &key + ,KeyTypeKeyCompare comp, insert_commit_data &commit_data); + + #endif //#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED + + //! Requires: value must be an lvalue of type value_type. commit_data + //! must have been obtained from a previous call to "insert_check". + //! No objects should have been inserted or erased from the container between + //! the "insert_check" that filled "commit_data" and the call to "insert_commit". + //! + //! Effects: Inserts the value in the container using the information obtained + //! from the "commit_data" that a previous "insert_check" filled. + //! + //! Returns: An iterator to the newly inserted object. + //! + //! Complexity: Constant time. + //! + //! Throws: Nothing. + //! + //! 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) 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)); + + #if !(defined(BOOST_DISABLE_ASSERTS) || ( defined(BOOST_ENABLE_ASSERT_DEBUG_HANDLER) && defined(NDEBUG) )) + //Test insertion position is correct + iterator p(commit_data.node, this->priv_value_traits_ptr()); + if(!commit_data.link_left){ + ++p; + } + //Check if the insertion point is correct to detect wrong + //uses insert_unique_check + 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 + (this->header_ptr(), to_insert, commit_data); + this->sz_traits().increment(); + return iterator(to_insert, this->priv_value_traits_ptr()); + } + + //! Requires: value must be an lvalue, "pos" must be + //! a valid iterator (or end) and must be the succesor of value + //! once inserted according to the predicate + //! + //! Effects: Inserts x into the container before "pos". + //! + //! Complexity: Constant time. + //! + //! Throws: Nothing. + //! + //! Note: This function does not check preconditions so if "pos" is not + //! 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) 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)); + this->sz_traits().increment(); + return iterator(node_algorithms::insert_before + (this->header_ptr(), pos.pointed_node(), to_insert), this->priv_value_traits_ptr()); + } + + //! Requires: value must be an lvalue, and it must be no less + //! than the greatest inserted key + //! + //! Effects: Inserts x into the container in the last position. + //! + //! Complexity: Constant time. + //! + //! Throws: Nothing. + //! + //! Note: This function does not check preconditions so if value is + //! less than the greatest inserted key container ordering invariant will be broken. + //! 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) 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)); + this->sz_traits().increment(); + node_algorithms::push_back(this->header_ptr(), to_insert); + } + + //! Requires: value must be an lvalue, and it must be no greater + //! than the minimum inserted key + //! + //! Effects: Inserts x into the container in the first position. + //! + //! Complexity: Constant time. + //! + //! Throws: Nothing. + //! + //! Note: This function does not check preconditions so if value is + //! greater than the minimum inserted key container ordering invariant will be broken. + //! 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) 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)); + this->sz_traits().increment(); + node_algorithms::push_front(this->header_ptr(), to_insert); + } + + //! Effects: Erases the element pointed to by i. + //! + //! Complexity: Average complexity for erase element is constant time. + //! + //! Throws: Nothing. + //! + //! Note: Invalidates the iterators (but not the references) + //! to the erased elements. No destructors are called. + iterator erase(const_iterator i) BOOST_NOEXCEPT + { + const_iterator ret(i); + ++ret; + node_ptr to_erase(i.pointed_node()); + 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(); + BOOST_IF_CONSTEXPR(safemode_or_autounlink) + node_algorithms::init(to_erase); + return ret.unconst(); + } + + //! Effects: Erases the range pointed to by b end e. + //! + //! Complexity: Average complexity for erase range is at most + //! O(log(size() + N)), where N is the number of elements in the range. + //! + //! Throws: Nothing. + //! + //! Note: Invalidates the iterators (but not the references) + //! to the erased elements. No destructors are called. + 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. + //! + //! Returns: The number of erased elements. + //! + //! Complexity: O(log(size() + N). + //! + //! Throws: Nothing. + //! + //! Note: Invalidates the iterators (but not the references) + //! to the erased elements. No destructors are called. + 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 + //! comp(nk, key) and !comp(key, nk), with comp(nk, key) implying !comp(key, nk), + //! with nk the key_type of a value_type inserted into `*this`. + //! + //! Effects: Erases all the elements with the given key. + //! according to the comparison functor "comp". + //! + //! Returns: The number of erased elements. + //! + //! Complexity: O(log(size() + N). + //! + //! Throws: Nothing. + //! + //! Note: Invalidates the iterators (but not the references) + //! to the erased elements. No destructors are called. + template + BOOST_INTRUSIVE_DOC1ST(size_type + , typename detail::disable_if_convertible::type) + erase(const KeyType& key, KeyTypeKeyCompare comp) + { + std::pair p = this->equal_range(key, comp); + size_type n; + this->private_erase(p.first, p.second, n); + return n; + } + + //! Requires: Disposer::operator()(pointer) shouldn't throw. + //! + //! Effects: Erases the element pointed to by i. + //! Disposer::operator()(pointer) is called for the removed element. + //! + //! Complexity: Average complexity for erase element is constant time. + //! + //! Throws: Nothing. + //! + //! Note: Invalidates the iterators + //! to the erased elements. + template + iterator erase_and_dispose(const_iterator i, Disposer disposer) BOOST_NOEXCEPT + { + node_ptr to_erase(i.pointed_node()); + iterator ret(this->erase(i)); + disposer(this->get_value_traits().to_value_ptr(to_erase)); + return ret; + } + + //! Requires: Disposer::operator()(pointer) shouldn't throw. + //! + //! Effects: Erases all the elements with the given value. + //! Disposer::operator()(pointer) is called for the removed elements. + //! + //! Returns: The number of erased elements. + //! + //! Complexity: O(log(size() + N). + //! + //! Throws: Nothing. + //! + //! Note: Invalidates the iterators (but not the references) + //! to the erased elements. No destructors are called. + template + size_type erase_and_dispose(const key_type &key, Disposer disposer) + { + std::pair p = this->equal_range(key); + size_type n; + this->private_erase(p.first, p.second, n, disposer); + return n; + } + + //! Requires: Disposer::operator()(pointer) shouldn't throw. + //! + //! Effects: Erases the range pointed to by b end e. + //! Disposer::operator()(pointer) is called for the removed elements. + //! + //! Complexity: Average complexity for erase range is at most + //! O(log(size() + N)), where N is the number of elements in the range. + //! + //! Throws: Nothing. + //! + //! Note: Invalidates the iterators + //! to the erased elements. + template + 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 + //! comp(nk, key) and !comp(key, nk), with comp(nk, key) implying !comp(key, nk) + //! and nk the key_type of a value_type inserted into `*this`. + //! + //! Requires: Disposer::operator()(pointer) shouldn't throw. + //! + //! Effects: Erases all the elements with the given key. + //! according to the comparison functor "comp". + //! Disposer::operator()(pointer) is called for the removed elements. + //! + //! Returns: The number of erased elements. + //! + //! Complexity: O(log(size() + N). + //! + //! Throws: Nothing. + //! + //! Note: Invalidates the iterators + //! to the erased elements. + template + BOOST_INTRUSIVE_DOC1ST(size_type + , typename detail::disable_if_convertible::type) + erase_and_dispose(const KeyType& key, KeyTypeKeyCompare comp, Disposer disposer) + { + std::pair p = this->equal_range(key, comp); + size_type n; + this->private_erase(p.first, p.second, n, disposer); + return n; + } + + //! Effects: Erases all of the elements. + //! + //! Complexity: Linear to the number of elements on the container. + //! if it's a safe-mode or auto-unlink value_type. Constant time otherwise. + //! + //! Throws: Nothing. + //! + //! Note: Invalidates the iterators (but not the references) + //! to the erased elements. No destructors are called. + void clear() BOOST_NOEXCEPT + { + BOOST_IF_CONSTEXPR(safemode_or_autounlink){ + this->clear_and_dispose(detail::null_disposer()); + } + else{ + node_algorithms::init_header(this->header_ptr()); + this->sz_traits().set_size(0); + } + } + + //! Effects: Erases all of the elements calling disposer(p) for + //! each node to be erased. + //! Complexity: Average complexity for is at most O(log(size() + N)), + //! where N is the number of elements in the container. + //! + //! Throws: Nothing. + //! + //! 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) BOOST_NOEXCEPT + { + node_algorithms::clear_and_dispose(this->header_ptr() + , detail::node_disposer(disposer, &this->get_value_traits())); + node_algorithms::init_header(this->header_ptr()); + this->sz_traits().set_size(0); + } + + //! Effects: Returns the number of contained elements with the given value + //! + //! Complexity: Logarithmic to the number of elements contained plus lineal + //! to number of objects with the given value. + //! + //! Throws: If `key_compare` throws. + size_type count(const key_type &key) const + { return size_type(this->count(key, this->key_comp())); } + + //! Requires: key is a value such that `*this` is partitioned with respect to + //! comp(nk, key) and !comp(key, nk), with comp(nk, key) implying !comp(key, nk), + //! and nk the key_type of a value_type inserted into `*this`. + //! + //! Effects: Returns the number of contained elements with the given key + //! + //! Complexity: Logarithmic to the number of elements contained plus lineal + //! to number of objects with the given key. + //! + //! Throws: If `comp` throws. + template + size_type count(const KeyType &key, KeyTypeKeyCompare comp) const + { + std::pair ret = this->equal_range(key, comp); + size_type n = 0; + for(; ret.first != ret.second; ++ret.first){ ++n; } + return n; + } + + #if !defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED) + + //Add non-const overloads to theoretically const members + //as some algorithms have different behavior when non-const versions are used (like splay trees). + size_type count(const key_type &key) + { return size_type(this->count(key, this->key_comp())); } + + template + size_type count(const KeyType &key, KeyTypeKeyCompare comp) + { + std::pair ret = this->equal_range(key, comp); + size_type n = 0; + for(; ret.first != ret.second; ++ret.first){ ++n; } + return n; + } + + #else //defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED) + + //! Effects: Returns an iterator to the first element whose + //! key is not less than k or end() if that element does not exist. + //! + //! Complexity: Logarithmic. + //! + //! Throws: If `key_compare` throws. + iterator lower_bound(const key_type &key); + + //! Effects: Returns an iterator to the first element whose + //! key is not less than k or end() if that element does not exist. + //! + //! Complexity: Logarithmic. + //! + //! Throws: If `key_compare` throws. + const_iterator lower_bound(const key_type &key) const; + + //! @copydoc ::boost::intrusive::bstree::lower_bound(const key_type &) + template + iterator lower_bound(const KeyType &key, KeyTypeKeyCompare comp); + + //! @copydoc ::boost::intrusive::bstree::lower_bound(const KeyType&,KeyTypeKeyCompare) + template + const_iterator lower_bound(const KeyType &key, KeyTypeKeyCompare comp) const; + + //! Effects: Returns an iterator to the first element whose + //! key is greater than k or end() if that element does not exist. + //! + //! Complexity: Logarithmic. + //! + //! Throws: If `key_compare` throws. + iterator upper_bound(const key_type &key); + + //! Requires: key is a value such that `*this` is partitioned with respect to + //! !comp(key, nk), with nk the key_type of a value_type inserted into `*this`. + //! + //! Effects: Returns an iterator to the first element whose + //! key is greater than k according to comp or end() if that element + //! does not exist. + //! + //! Complexity: Logarithmic. + //! + //! Throws: If `comp` throws. + template + iterator upper_bound(const KeyType &key, KeyTypeKeyCompare comp); + + //! @copydoc ::boost::intrusive::bstree::upper_bound(const key_type &) + const_iterator upper_bound(const key_type &key) const; + + //! @copydoc ::boost::intrusive::bstree::upper_bound(const KeyType&,KeyTypeKeyCompare) + template + const_iterator upper_bound(const KeyType &key, KeyTypeKeyCompare comp) const; + + //! Effects: Finds an iterator to the first element whose key is + //! k or end() if that element does not exist. + //! + //! Complexity: Logarithmic. + //! + //! Throws: If `key_compare` throws. + iterator find(const key_type &key); + + //! Requires: key is a value such that `*this` is partitioned with respect to + //! comp(nk, key) and !comp(key, nk), with comp(nk, key) implying !comp(key, nk), + //! and nk the key_type of a value_type inserted into `*this`. + //! + //! Effects: Finds an iterator to the first element whose key is + //! k or end() if that element does not exist. + //! + //! Complexity: Logarithmic. + //! + //! Throws: If `comp` throws. + template + iterator find(const KeyType &key, KeyTypeKeyCompare comp); + + //! @copydoc ::boost::intrusive::bstree::find(const key_type &) + const_iterator find(const key_type &key) const; + + //! @copydoc ::boost::intrusive::bstree::find(const KeyType&,KeyTypeKeyCompare) + template + const_iterator find(const KeyType &key, KeyTypeKeyCompare comp) const; + + //! Effects: Finds a range containing all elements whose key is k or + //! an empty range that indicates the position where those elements would be + //! if they there is no elements with key k. + //! + //! Complexity: Logarithmic. + //! + //! Throws: If `key_compare` throws. + std::pair equal_range(const key_type &key); + + //! Requires: key is a value such that `*this` is partitioned with respect to + //! comp(nk, key) and !comp(key, nk), with comp(nk, key) implying !comp(key, nk), + //! with nk the key_type of a value_type inserted into `*this`. + //! + //! Effects: Finds a range containing all elements whose key is k or + //! an empty range that indicates the position where those elements would be + //! if they there is no elements with key k. + //! + //! Complexity: Logarithmic. + //! + //! Throws: If `comp` throws. + template + std::pair equal_range(const KeyType &key, KeyTypeKeyCompare comp); + + //! @copydoc ::boost::intrusive::bstree::equal_range(const key_type &) + std::pair equal_range(const key_type &key) const; + + //! @copydoc ::boost::intrusive::bstree::equal_range(const KeyType&,KeyTypeKeyCompare) + template + std::pair + equal_range(const KeyType &key, KeyTypeKeyCompare comp) const; + + //! Requires: + //! `upper_key` shall not precede `lower_key` according to key_compare. + //! [key_comp()(upper_key, lower_key) shall be false] + //! + //! If `lower_key` is equivalent to `upper_key` + //! [!key_comp()(upper_key, lower_key) && !key_comp()(lower_key, upper_key)] then + //! ('left_closed' || 'right_closed') must be false. + //! + //! Effects: Returns an a pair with the following criteria: + //! + //! first = lower_bound(lower_key) if left_closed, upper_bound(lower_key) otherwise + //! + //! second = upper_bound(upper_key) if right_closed, lower_bound(upper_key) otherwise + //! + //! Complexity: Logarithmic. + //! + //! Throws: If `key_compare` throws. + //! + //! Note: This function can be more efficient than calling upper_bound + //! and lower_bound for lower_value and upper_value. + //! + //! Note: Experimental function, the interface might change in future releases. + std::pair bounded_range + (const key_type &lower_key, const key_type &upper_value, bool left_closed, bool right_closed); + + //! Requires: + //! `lower_key` is a value such that `*this` is partitioned with respect to + //! comp(nk, lower_key) if left_closed is true, with respect to !comp(lower_key, nk) otherwise. + //! + //! `upper_key` is a value such that `*this` is partitioned with respect to + //! !comp(upper_key, nk) if right_closed is true, with respect to comp(nk, upper_key) otherwise. + //! + //! `upper_key` shall not precede `lower_key` according to comp + //! [comp(upper_key, lower_key) shall be false] + //! + //! If `lower_key` is equivalent to `upper_key` + //! [!comp(upper_key, lower_key) && !comp(lower_key, upper_key)] then + //! ('left_closed' || 'right_closed') must be false. + //! + //! Effects: Returns an a pair with the following criteria: + //! + //! first = lower_bound(lower_key, comp) if left_closed, upper_bound(lower_key, comp) otherwise + //! + //! second = upper_bound(upper_key, comp) if right_closed, lower_bound(upper_key, comp) otherwise + //! + //! Complexity: Logarithmic. + //! + //! Throws: If `comp` throws. + //! + //! Note: This function can be more efficient than calling upper_bound + //! and lower_bound for lower_key and upper_key. + //! + //! Note: Experimental function, the interface might change in future releases. + template + std::pair bounded_range + (const KeyType &lower_key, const KeyType &upper_key, KeyTypeKeyCompare comp, bool left_closed, bool right_closed); + + //! @copydoc ::boost::intrusive::bstree::bounded_range(const key_type &,const key_type &,bool,bool) + std::pair bounded_range + (const key_type &lower_key, const key_type &upper_key, bool left_closed, bool right_closed) const; + + //! @copydoc ::boost::intrusive::bstree::bounded_range(const KeyType&,const KeyType&,KeyTypeKeyCompare,bool,bool) + template + std::pair bounded_range + (const KeyType &lower_key, const KeyType &upper_key, KeyTypeKeyCompare comp, bool left_closed, bool right_closed) const; + + //! Requires: value must be an lvalue and shall be in a set of + //! appropriate type. Otherwise the behavior is undefined. + //! + //! Effects: Returns: a valid iterator i belonging to the set + //! that points to the value + //! + //! Complexity: Constant. + //! + //! Throws: Nothing. + //! + //! Note: This static function is available only if the value traits + //! is stateless. + 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. + //! + //! Effects: Returns: a valid const_iterator i belonging to the + //! set that points to the value + //! + //! Complexity: Constant. + //! + //! Throws: Nothing. + //! + //! Note: This static function is available only if the value traits + //! is stateless. + 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. + //! + //! Effects: Returns: a valid iterator i belonging to the set + //! that points to the value + //! + //! Complexity: Constant. + //! + //! Throws: Nothing. + 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. + //! + //! Effects: Returns: a valid const_iterator i belonging to the + //! set that points to the value + //! + //! Complexity: Constant. + //! + //! Throws: Nothing. + const_iterator iterator_to(const_reference value) const BOOST_NOEXCEPT; + + //! Requires: value shall not be in a container. + //! + //! Effects: init_node puts the hook of a value in a well-known default + //! state. + //! + //! Throws: Nothing. + //! + //! Complexity: Constant time. + //! + //! 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) BOOST_NOEXCEPT; + + #endif //#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED) + + //! Effects: Unlinks the leftmost node from the container. + //! + //! Complexity: Average complexity is constant time. + //! + //! Throws: Nothing. + //! + //! Notes: This function breaks the container and the container can + //! 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() 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(); + 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); + } + + #if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED) + + //! Requires: replace_this must be a valid iterator of *this + //! and with_this must not be inserted in any container. + //! + //! Effects: Replaces replace_this in its position in the + //! container with with_this. The container does not need to be rebalanced. + //! + //! Complexity: Constant. + //! + //! Throws: Nothing. + //! + //! Note: This function will break container ordering invariants if + //! 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) BOOST_NOEXCEPT; + + //! Effects: Rebalances the tree. + //! + //! Throws: Nothing. + //! + //! Complexity: Linear. + void rebalance() BOOST_NOEXCEPT; + + //! Requires: old_root is a node of a tree. + //! + //! Effects: Rebalances the subtree rooted at old_root. + //! + //! Returns: The new root of the subtree. + //! + //! Throws: Nothing. + //! + //! Complexity: Linear to the elements in the subtree. + iterator rebalance_subtree(iterator r) BOOST_NOEXCEPT; + + #endif //#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED) + + //! Effects: removes "value" from the container. + //! + //! Throws: Nothing. + //! + //! Complexity: Logarithmic time. + //! + //! Note: This static function is only usable with non-constant + //! time size containers that have stateless comparison functors. + //! + //! 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) BOOST_NOEXCEPT + { + BOOST_STATIC_ASSERT((!constant_time_size)); + node_ptr to_remove(value_traits::to_node_ptr(value)); + node_algorithms::unlink(to_remove); + BOOST_IF_CONSTEXPR(safemode_or_autounlink) + node_algorithms::init(to_remove); + } + + //! Requires: "source" container's Options can only can differ in the comparison + //! function from *this. + //! + //! Effects: Attempts to extract each element in source and insert it into a using + //! the comparison object of *this. If there is an element in a with key equivalent to the + //! key of an element from source, then that element is not extracted from source. + //! + //! Postcondition: Pointers and references to the transferred elements of source refer + //! to those same elements but as members of *this. Iterators referring to the transferred + //! elements will continue to refer to their elements, but they now behave as iterators into *this, + //! not into source. + //! + //! Throws: Nothing unless the comparison object throws. + //! + //! Complexity: N log(a.size() + N) (N has the value source.size()) + #if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED) + template void merge_unique(bstree &); + #else + template + void merge_unique(bstree_impl + &source) + #endif + { + node_ptr it (node_algorithms::begin_node(source.header_ptr())) + , itend(node_algorithms::end_node (source.header_ptr())); + + while(it != itend){ + node_ptr const p(it); + BOOST_INTRUSIVE_SAFE_HOOK_DEFAULT_ASSERT(!safemode_or_autounlink || !node_algorithms::unique(p)); + it = node_algorithms::next_node(it); + if( node_algorithms::transfer_unique(this->header_ptr(), this->key_node_comp(this->key_comp()), source.header_ptr(), p) ){ + source.sz_traits().decrement(); + this->sz_traits().increment(); + } + } + } + + //! Requires: "source" container's Options can only can differ in the comparison + //! function from *this. + //! + //! Effects: Extracts each element in source and insert it into a using + //! the comparison object of *this. + //! + //! Postcondition: Pointers and references to the transferred elements of source refer + //! to those same elements but as members of *this. Iterators referring to the transferred + //! elements will continue to refer to their elements, but they now behave as iterators into *this, + //! not into source. + //! + //! Throws: Nothing unless the comparison object throws. + //! + //! Complexity: N log(a.size() + N) (N has the value source.size()) + #if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED) + template void merge_equal(bstree &); + #else + template + void merge_equal(bstree_impl + &source) + #endif + { + node_ptr it (node_algorithms::begin_node(source.header_ptr())) + , itend(node_algorithms::end_node (source.header_ptr())); + + while(it != itend){ + node_ptr const p(it); + BOOST_INTRUSIVE_SAFE_HOOK_DEFAULT_ASSERT(!safemode_or_autounlink || !node_algorithms::unique(p)); + it = node_algorithms::next_node(it); + node_algorithms::transfer_equal(this->header_ptr(), this->key_node_comp(this->key_comp()), source.header_ptr(), p); + source.sz_traits().decrement(); + this->sz_traits().increment(); + } + } + + //! Effects: Asserts the integrity of the container with additional checks provided by the user. + //! + //! Complexity: Linear time. + //! + //! 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 + void check(ExtraChecker extra_checker) const + { + typedef detail::key_nodeptr_comp nodeptr_comp_t; + nodeptr_comp_t nodeptr_comp(this->key_comp(), &this->get_value_traits()); + typedef typename get_node_checker::type node_checker_t; + typename node_checker_t::return_type checker_return; + node_algorithms::check(this->header_ptr(), node_checker_t(nodeptr_comp, extra_checker), checker_return); + BOOST_INTRUSIVE_INVARIANT_ASSERT(!constant_time_size || this->sz_traits().get_size() == checker_return.node_count); + } + + //! Effects: Asserts the integrity of the container. + //! + //! Complexity: Linear time. + //! + //! Note: The method has no effect when asserts are turned off (e.g., with NDEBUG). + //! Experimental function, interface might change in future versions. + void check() const + { + check(detail::empty_node_checker()); + } + + friend bool operator==(const bstree_impl &x, const bstree_impl &y) + { + if(constant_time_size && x.size() != y.size()){ + return false; + } + return boost::intrusive::algo_equal(x.cbegin(), x.cend(), y.cbegin(), y.cend()); + } + + friend bool operator!=(const bstree_impl &x, const bstree_impl &y) + { return !(x == y); } + + friend bool operator<(const bstree_impl &x, const bstree_impl &y) + { return ::boost::intrusive::algo_lexicographical_compare(x.begin(), x.end(), y.begin(), y.end()); } + + friend bool operator>(const bstree_impl &x, const bstree_impl &y) + { return y < x; } + + friend bool operator<=(const bstree_impl &x, const bstree_impl &y) + { return !(x > y); } + + friend bool operator>=(const bstree_impl &x, const bstree_impl &y) + { return !(x < y); } + + friend void swap(bstree_impl &x, bstree_impl &y) + { x.swap(y); } + + /// @cond + private: + template + iterator private_erase(const_iterator b, const_iterator e, size_type &n, Disposer disposer) + { + 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) + { + for(n = 0; b != e; ++n) + this->erase(b++); + return b.unconst(); + } + /// @endcond +}; + +//! Helper metafunction to define a \c bstree that yields to the same type when the +//! same options (either explicitly or implicitly) are used. +#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED) || defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES) +template +#else +template +#endif +struct make_bstree +{ + /// @cond + typedef typename pack_options + < bstree_defaults, + #if !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES) + O1, O2, O3, O4, O5, O6 + #else + Options... + #endif + >::type packed_options; + + typedef typename detail::get_value_traits + ::type value_traits; + + typedef bstree_impl + < value_traits + , typename packed_options::key_of_value + , typename packed_options::compare + , typename packed_options::size_type + , packed_options::constant_time_size + , BsTreeAlgorithms + , typename packed_options::header_holder_type + > implementation_defined; + /// @endcond + typedef implementation_defined type; +}; + + +#ifndef BOOST_INTRUSIVE_DOXYGEN_INVOKED + +#if !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES) +template +#else +template +#endif +class bstree + : public make_bstree::type +{ + typedef typename make_bstree + ::type Base; + BOOST_MOVABLE_BUT_NOT_COPYABLE(bstree) + + public: + typedef typename Base::key_compare key_compare; + typedef typename Base::value_traits value_traits; + typedef typename Base::iterator iterator; + typedef typename Base::const_iterator const_iterator; + + //Assert if passed value traits are compatible with the type + BOOST_STATIC_ASSERT((detail::is_same::value)); + + BOOST_INTRUSIVE_FORCEINLINE bstree() + : Base() + {} + + BOOST_INTRUSIVE_FORCEINLINE explicit bstree( const key_compare &cmp, const value_traits &v_traits = value_traits()) + : Base(cmp, v_traits) + {} + + template + BOOST_INTRUSIVE_FORCEINLINE bstree( bool unique, Iterator b, Iterator e + , const key_compare &cmp = key_compare() + , const value_traits &v_traits = value_traits()) + : Base(unique, b, e, cmp, v_traits) + {} + + BOOST_INTRUSIVE_FORCEINLINE bstree(BOOST_RV_REF(bstree) x) + : Base(BOOST_MOVE_BASE(Base, x)) + {} + + BOOST_INTRUSIVE_FORCEINLINE bstree& operator=(BOOST_RV_REF(bstree) x) + { return static_cast(this->Base::operator=(BOOST_MOVE_BASE(Base, x))); } + + template + BOOST_INTRUSIVE_FORCEINLINE void clone_from(const bstree &src, Cloner cloner, Disposer disposer) + { Base::clone_from(src, cloner, disposer); } + + template + 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_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_NOEXCEPT + { return static_cast(Base::container_from_end_iterator(end_iterator)); } + + 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_NOEXCEPT + { return static_cast(Base::container_from_iterator(it)); } +}; + +#endif +} //namespace intrusive +} //namespace boost + +#include + +#endif //BOOST_INTRUSIVE_BSTREE_HPP diff --git a/third_party/boost/libs/intrusive/include/boost/intrusive/bstree_algorithms.hpp b/third_party/boost/libs/intrusive/include/boost/intrusive/bstree_algorithms.hpp new file mode 100644 index 00000000000..5113a584b8c --- /dev/null +++ b/third_party/boost/libs/intrusive/include/boost/intrusive/bstree_algorithms.hpp @@ -0,0 +1,2103 @@ +///////////////////////////////////////////////////////////////////////////// +// +// (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 +// http://www.boost.org/LICENSE_1_0.txt) +// +// See http://www.boost.org/libs/intrusive for documentation. +// +///////////////////////////////////////////////////////////////////////////// + +#ifndef BOOST_INTRUSIVE_BSTREE_ALGORITHMS_HPP +#define BOOST_INTRUSIVE_BSTREE_ALGORITHMS_HPP + +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#if defined(BOOST_HAS_PRAGMA_ONCE) +# pragma once +#endif + +namespace boost { +namespace intrusive { + +/// @cond + +//! This type is the information that will be filled by insert_unique_check +template +struct insert_commit_data_t +{ + BOOST_INTRUSIVE_FORCEINLINE insert_commit_data_t() + : link_left(false), node() + {} + bool link_left; + NodePtr node; +}; + +template +struct data_for_rebalance_t +{ + NodePtr x; + NodePtr x_parent; + NodePtr y; +}; + +namespace detail { + +template +struct bstree_node_checker + : public ExtraChecker +{ + typedef ExtraChecker base_checker_t; + typedef ValueTraits value_traits; + typedef typename value_traits::node_traits node_traits; + typedef typename node_traits::const_node_ptr const_node_ptr; + + struct return_type + : public base_checker_t::return_type + { + BOOST_INTRUSIVE_FORCEINLINE return_type() + : min_key_node_ptr(const_node_ptr()), max_key_node_ptr(const_node_ptr()), node_count(0) + {} + + const_node_ptr min_key_node_ptr; + const_node_ptr max_key_node_ptr; + size_t node_count; + }; + + BOOST_INTRUSIVE_FORCEINLINE bstree_node_checker(const NodePtrCompare& comp, ExtraChecker extra_checker) + : base_checker_t(extra_checker), comp_(comp) + {} + + void operator () (const_node_ptr p, + const return_type& check_return_left, const return_type& check_return_right, + return_type& check_return) + { + BOOST_INTRUSIVE_INVARIANT_ASSERT(!check_return_left.max_key_node_ptr || !comp_(p, check_return_left.max_key_node_ptr)); + BOOST_INTRUSIVE_INVARIANT_ASSERT(!check_return_right.min_key_node_ptr || !comp_(check_return_right.min_key_node_ptr, p)); + check_return.min_key_node_ptr = node_traits::get_left(p)? check_return_left.min_key_node_ptr : p; + check_return.max_key_node_ptr = node_traits::get_right(p)? check_return_right.max_key_node_ptr : p; + check_return.node_count = check_return_left.node_count + check_return_right.node_count + 1; + base_checker_t::operator()(p, check_return_left, check_return_right, check_return); + } + + const NodePtrCompare comp_; +}; + +} // namespace detail + +/// @endcond + + + +//! This is an implementation of a binary search tree. +//! A node in the search tree has references to its children and its parent. This +//! is to allow traversal of the whole tree from a given node making the +//! implementation of iterator a pointer to a node. +//! At the top of the tree a node is used specially. This node's parent pointer +//! is pointing to the root of the tree. Its left pointer points to the +//! leftmost node in the tree and the right pointer to the rightmost one. +//! This node is used to represent the end-iterator. +//! +//! +---------+ +//! header------------------------------>| | +//! | | +//! +----------(left)--------| |--------(right)---------+ +//! | +---------+ | +//! | | | +//! | | (parent) | +//! | | | +//! | | | +//! | +---------+ | +//! root of tree ..|......................> | | | +//! | | D | | +//! | | | | +//! | +-------+---------+-------+ | +//! | | | | +//! | | | | +//! | | | | +//! | | | | +//! | | | | +//! | +---------+ +---------+ | +//! | | | | | | +//! | | B | | F | | +//! | | | | | | +//! | +--+---------+--+ +--+---------+--+ | +//! | | | | | | +//! | | | | | | +//! | | | | | | +//! | +---+-----+ +-----+---+ +---+-----+ +-----+---+ | +//! +-->| | | | | | | |<--+ +//! | A | | C | | E | | G | +//! | | | | | | | | +//! +---------+ +---------+ +---------+ +---------+ +//! +//! bstree_algorithms is configured with a NodeTraits class, which encapsulates the +//! information about the node to be manipulated. NodeTraits must support the +//! following interface: +//! +//! Typedefs: +//! +//! node: The type of the node that forms the binary search tree +//! +//! node_ptr: A pointer to a node +//! +//! const_node_ptr: A pointer to a const node +//! +//! Static functions: +//! +//! static node_ptr get_parent(const_node_ptr n); +//! +//! static void set_parent(node_ptr n, node_ptr parent); +//! +//! static node_ptr get_left(const_node_ptr n); +//! +//! static void set_left(node_ptr n, node_ptr left); +//! +//! static node_ptr get_right(const_node_ptr n); +//! +//! static void set_right(node_ptr n, node_ptr right); +template +class bstree_algorithms : public bstree_algorithms_base +{ + public: + typedef typename NodeTraits::node node; + typedef NodeTraits node_traits; + typedef typename NodeTraits::node_ptr node_ptr; + typedef typename NodeTraits::const_node_ptr const_node_ptr; + typedef insert_commit_data_t insert_commit_data; + typedef data_for_rebalance_t data_for_rebalance; + + /// @cond + typedef bstree_algorithms this_type; + typedef bstree_algorithms_base base_type; + private: + template + struct dispose_subtree_disposer + { + BOOST_INTRUSIVE_FORCEINLINE dispose_subtree_disposer(Disposer &disp, node_ptr subtree) + : disposer_(&disp), subtree_(subtree) + {} + + BOOST_INTRUSIVE_FORCEINLINE void release() + { disposer_ = 0; } + + BOOST_INTRUSIVE_FORCEINLINE ~dispose_subtree_disposer() + { + if(disposer_){ + dispose_subtree(subtree_, *disposer_); + } + } + Disposer *disposer_; + const node_ptr subtree_; + }; + + /// @endcond + + public: + //! Requires: 'header' is the header node of a tree. + //! + //! Effects: Returns the first node of the tree, the header if the tree is empty. + //! + //! Complexity: Constant time. + //! + //! Throws: Nothing. + 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. + //! + //! Effects: Returns the header of the tree. + //! + //! Complexity: Constant time. + //! + //! Throws: Nothing. + 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. + //! + //! Effects: Returns the root of the tree if any, header otherwise + //! + //! Complexity: Constant time. + //! + //! Throws: Nothing. + 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: '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(). + //! + //! Complexity: Constant time. + //! + //! Throws: Nothing. + BOOST_INTRUSIVE_FORCEINLINE static bool unique(const_node_ptr n) BOOST_NOEXCEPT + { return !NodeTraits::get_parent(n); } + + #if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED) + //! 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_node_ptr n); + #endif + + //! Requires: node1 and node2 can't be header nodes + //! of two trees. + //! + //! Effects: Swaps two nodes. After the function node1 will be inserted + //! in the position node2 before the function. node2 will be inserted in the + //! position node1 had before the function. + //! + //! Complexity: Logarithmic. + //! + //! Throws: Nothing. + //! + //! Note: This function will break container ordering invariants if + //! node1 and node2 are not equivalent according to the ordering rules. + //! + //!Experimental function + static void swap_nodes(node_ptr node1, node_ptr node2) BOOST_NOEXCEPT + { + if(node1 == node2) + return; + + node_ptr header1(base_type::get_header(node1)), header2(base_type::get_header(node2)); + swap_nodes(node1, header1, node2, header2); + } + + //! Requires: node1 and node2 can't be header nodes + //! of two trees with header header1 and header2. + //! + //! Effects: Swaps two nodes. After the function node1 will be inserted + //! in the position node2 before the function. node2 will be inserted in the + //! position node1 had before the function. + //! + //! Complexity: Constant. + //! + //! Throws: Nothing. + //! + //! Note: This function will break container ordering invariants if + //! 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) BOOST_NOEXCEPT + { + if(node1 == node2) + return; + + //node1 and node2 must not be header nodes + //BOOST_INTRUSIVE_INVARIANT_ASSERT((header1 != node1 && header2 != node2)); + if(header1 != header2){ + //Update header1 if necessary + if(node1 == NodeTraits::get_left(header1)){ + NodeTraits::set_left(header1, node2); + } + + if(node1 == NodeTraits::get_right(header1)){ + NodeTraits::set_right(header1, node2); + } + + if(node1 == NodeTraits::get_parent(header1)){ + NodeTraits::set_parent(header1, node2); + } + + //Update header2 if necessary + if(node2 == NodeTraits::get_left(header2)){ + NodeTraits::set_left(header2, node1); + } + + if(node2 == NodeTraits::get_right(header2)){ + NodeTraits::set_right(header2, node1); + } + + if(node2 == NodeTraits::get_parent(header2)){ + NodeTraits::set_parent(header2, node1); + } + } + else{ + //If both nodes are from the same tree + //Update header if necessary + if(node1 == NodeTraits::get_left(header1)){ + NodeTraits::set_left(header1, node2); + } + else if(node2 == NodeTraits::get_left(header2)){ + NodeTraits::set_left(header2, node1); + } + + if(node1 == NodeTraits::get_right(header1)){ + NodeTraits::set_right(header1, node2); + } + else if(node2 == NodeTraits::get_right(header2)){ + NodeTraits::set_right(header2, node1); + } + + if(node1 == NodeTraits::get_parent(header1)){ + NodeTraits::set_parent(header1, node2); + } + else if(node2 == NodeTraits::get_parent(header2)){ + NodeTraits::set_parent(header2, node1); + } + + //Adjust data in nodes to be swapped + //so that final link swap works as expected + if(node1 == NodeTraits::get_parent(node2)){ + NodeTraits::set_parent(node2, node2); + + if(node2 == NodeTraits::get_right(node1)){ + NodeTraits::set_right(node1, node1); + } + else{ + NodeTraits::set_left(node1, node1); + } + } + else if(node2 == NodeTraits::get_parent(node1)){ + NodeTraits::set_parent(node1, node1); + + if(node1 == NodeTraits::get_right(node2)){ + NodeTraits::set_right(node2, node2); + } + else{ + NodeTraits::set_left(node2, node2); + } + } + } + + //Now swap all the links + node_ptr temp; + //swap left link + temp = NodeTraits::get_left(node1); + NodeTraits::set_left(node1, NodeTraits::get_left(node2)); + NodeTraits::set_left(node2, temp); + //swap right link + temp = NodeTraits::get_right(node1); + NodeTraits::set_right(node1, NodeTraits::get_right(node2)); + NodeTraits::set_right(node2, temp); + //swap parent link + temp = NodeTraits::get_parent(node1); + NodeTraits::set_parent(node1, NodeTraits::get_parent(node2)); + NodeTraits::set_parent(node2, temp); + + //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); + } + //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); + } + + //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 ((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); + } + } + } + } + + //! Requires: node_to_be_replaced must be inserted in a tree + //! and new_node must not be inserted in a tree. + //! + //! Effects: Replaces node_to_be_replaced in its position in the + //! tree with new_node. The tree does not need to be rebalanced + //! + //! Complexity: Logarithmic. + //! + //! Throws: Nothing. + //! + //! Note: This function will break container ordering invariants if + //! 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_NOEXCEPT + { + replace_node(node_to_be_replaced, base_type::get_header(node_to_be_replaced), new_node); + } + + //! Requires: node_to_be_replaced must be inserted in a tree + //! with header "header" and new_node must not be inserted in a tree. + //! + //! Effects: Replaces node_to_be_replaced in its position in the + //! tree with new_node. The tree does not need to be rebalanced + //! + //! Complexity: Constant. + //! + //! Throws: Nothing. + //! + //! Note: This function will break container ordering invariants if + //! 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) BOOST_NOEXCEPT + { + BOOST_ASSERT(node_to_be_replaced != new_node); + + //Update header if necessary + if(node_to_be_replaced == NodeTraits::get_left(header)){ + NodeTraits::set_left(header, new_node); + } + + if(node_to_be_replaced == NodeTraits::get_right(header)){ + NodeTraits::set_right(header, new_node); + } + + if(node_to_be_replaced == NodeTraits::get_parent(header)){ + NodeTraits::set_parent(header, new_node); + } + + //Now set data from the original node + node_ptr temp; + NodeTraits::set_left(new_node, NodeTraits::get_left(node_to_be_replaced)); + NodeTraits::set_right(new_node, NodeTraits::get_right(node_to_be_replaced)); + NodeTraits::set_parent(new_node, NodeTraits::get_parent(node_to_be_replaced)); + + //Now adjust adjacent nodes for newly inserted node + if((temp = NodeTraits::get_left(new_node))){ + NodeTraits::set_parent(temp, new_node); + } + if((temp = NodeTraits::get_right(new_node))){ + NodeTraits::set_parent(temp, new_node); + } + if((temp = NodeTraits::get_parent(new_node)) && + //The header has been already updated so avoid it + temp != header){ + if(NodeTraits::get_left(temp) == node_to_be_replaced){ + NodeTraits::set_left(temp, new_node); + } + if(NodeTraits::get_right(temp) == node_to_be_replaced){ + NodeTraits::set_right(temp, new_node); + } + } + } + + #if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED) + //! 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(node_ptr n) BOOST_NOEXCEPT; + + //! 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(node_ptr n) BOOST_NOEXCEPT; + + //! 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 n); + + //! 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 n); + #endif + + //! Requires: 'n' must not be part of any tree. + //! + //! Effects: After the function unique(node) == true. + //! + //! Complexity: Constant. + //! + //! Throws: Nothing. + //! + //! Nodes: If node is inserted in a tree, this function corrupts the tree. + static void init(node_ptr n) BOOST_NOEXCEPT + { + 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) + //! + //! Complexity: Constant. + //! + //! Throws: Nothing. + static bool inited(const_node_ptr n) + { + return !NodeTraits::get_parent(n) && + !NodeTraits::get_left(n) && + !NodeTraits::get_right(n) ; + } + + //! Requires: header must not be part of any tree. + //! + //! Effects: Initializes the header to represent an empty tree. + //! unique(header) == true. + //! + //! Complexity: Constant. + //! + //! Throws: Nothing. + //! + //! 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); + NodeTraits::set_right(header, header); + } + + //! Requires: "disposer" must be an object function + //! taking a node_ptr parameter and shouldn't throw. + //! + //! Effects: Empties the target tree calling + //! 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: Nothing. + template + static void clear_and_dispose(node_ptr header, Disposer disposer) BOOST_NOEXCEPT + { + node_ptr source_root = NodeTraits::get_parent(header); + if(!source_root) + return; + dispose_subtree(source_root, disposer); + init_header(header); + } + + //! Requires: header is the header of a tree. + //! + //! Effects: Unlinks the leftmost node from the tree, and + //! updates the header link to the new leftmost node. + //! + //! Complexity: Average complexity is constant time. + //! + //! Throws: Nothing. + //! + //! Notes: This function breaks the tree and the tree can + //! 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) BOOST_NOEXCEPT + { + node_ptr leftmost = NodeTraits::get_left(header); + if (leftmost == header) + return node_ptr(); + node_ptr leftmost_parent(NodeTraits::get_parent(leftmost)); + node_ptr leftmost_right (NodeTraits::get_right(leftmost)); + bool is_root = leftmost_parent == header; + + if (leftmost_right){ + NodeTraits::set_parent(leftmost_right, leftmost_parent); + NodeTraits::set_left(header, base_type::minimum(leftmost_right)); + + if (is_root) + NodeTraits::set_parent(header, leftmost_right); + else + NodeTraits::set_left(NodeTraits::get_parent(header), leftmost_right); + } + else if (is_root){ + NodeTraits::set_parent(header, node_ptr()); + NodeTraits::set_left(header, header); + NodeTraits::set_right(header, header); + } + else{ + NodeTraits::set_left(leftmost_parent, node_ptr()); + NodeTraits::set_left(header, leftmost_parent); + } + return leftmost; + } + + //! Requires: 'header' the header of the tree. + //! + //! Effects: Returns the number of nodes of the tree. + //! + //! Complexity: Linear time. + //! + //! Throws: Nothing. + static std::size_t size(const_node_ptr header) BOOST_NOEXCEPT + { + node_ptr beg(begin_node(header)); + node_ptr end(end_node(header)); + std::size_t i = 0; + for(;beg != end; beg = base_type::next_node(beg)) ++i; + return i; + } + + //! Requires: header1 and header2 must be the header nodes + //! of two trees. + //! + //! Effects: Swaps two trees. After the function header1 will contain + //! links to the second tree and header2 will have links to the first tree. + //! + //! Complexity: Constant. + //! + //! Throws: Nothing. + static void swap_tree(node_ptr header1, node_ptr header2) BOOST_NOEXCEPT + { + if(header1 == header2) + return; + + node_ptr tmp; + + //Parent swap + tmp = NodeTraits::get_parent(header1); + NodeTraits::set_parent(header1, NodeTraits::get_parent(header2)); + NodeTraits::set_parent(header2, tmp); + //Left swap + tmp = NodeTraits::get_left(header1); + NodeTraits::set_left(header1, NodeTraits::get_left(header2)); + NodeTraits::set_left(header2, tmp); + //Right swap + tmp = NodeTraits::get_right(header1); + NodeTraits::set_right(header1, NodeTraits::get_right(header2)); + NodeTraits::set_right(header2, tmp); + + //Now test parent + node_ptr h1_parent(NodeTraits::get_parent(header1)); + if(h1_parent){ + NodeTraits::set_parent(h1_parent, header1); + } + else{ + NodeTraits::set_left(header1, header1); + NodeTraits::set_right(header1, header1); + } + + node_ptr h2_parent(NodeTraits::get_parent(header2)); + if(h2_parent){ + NodeTraits::set_parent(h2_parent, header2); + } + else{ + NodeTraits::set_left(header2, header2); + NodeTraits::set_right(header2, header2); + } + } + + #if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED) + //! Requires: p is a node of a tree. + //! + //! Effects: Returns true if p is the header of the tree. + //! + //! Complexity: Constant. + //! + //! Throws: Nothing. + static bool is_header(const_node_ptr p) BOOST_NOEXCEPT; + #endif + + //! Requires: "header" must be the header node of a tree. + //! KeyNodePtrCompare is a function object that induces a strict weak + //! ordering compatible with the strict weak ordering used to create the + //! the tree. KeyNodePtrCompare can compare KeyType with tree's node_ptrs. + //! + //! Effects: Returns a node_ptr to the first element that is equivalent to + //! "key" according to "comp" or "header" if that element does not exist. + //! + //! Complexity: Logarithmic. + //! + //! Throws: If "comp" throws. + template + static node_ptr find + (const_node_ptr header, const KeyType &key, KeyNodePtrCompare comp) + { + node_ptr end = detail::uncast(header); + node_ptr y = lower_bound(header, key, comp); + return (y == end || comp(key, y)) ? end : y; + } + + //! Requires: "header" must be the header node of a tree. + //! KeyNodePtrCompare is a function object that induces a strict weak + //! ordering compatible with the strict weak ordering used to create the + //! the tree. KeyNodePtrCompare can compare KeyType with tree's node_ptrs. + //! 'lower_key' must not be greater than 'upper_key' according to 'comp'. If + //! 'lower_key' == 'upper_key', ('left_closed' || 'right_closed') must be true. + //! + //! Effects: Returns an a pair with the following criteria: + //! + //! first = lower_bound(lower_key) if left_closed, upper_bound(lower_key) otherwise + //! + //! second = upper_bound(upper_key) if right_closed, lower_bound(upper_key) otherwise + //! + //! Complexity: Logarithmic. + //! + //! Throws: If "comp" throws. + //! + //! Note: This function can be more efficient than calling upper_bound + //! and lower_bound for lower_key and upper_key. + //! + //! Note: Experimental function, the interface might change. + template< class KeyType, class KeyNodePtrCompare> + 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) + { + node_ptr y = detail::uncast(header); + node_ptr x = NodeTraits::get_parent(header); + + while(x){ + //If x is less than lower_key the target + //range is on the right part + if(comp(x, lower_key)){ + //Check for invalid input range + BOOST_INTRUSIVE_INVARIANT_ASSERT(comp(x, upper_key)); + x = NodeTraits::get_right(x); + } + //If the upper_key is less than x, the target + //range is on the left part + else if(comp(upper_key, x)){ + y = x; + x = NodeTraits::get_left(x); + } + else{ + //x is inside the bounded range(lower_key <= x <= upper_key), + //so we must split lower and upper searches + // + //Sanity check: if lower_key and upper_key are equal, then both left_closed and right_closed can't be false + BOOST_INTRUSIVE_INVARIANT_ASSERT(left_closed || right_closed || comp(lower_key, x) || comp(x, upper_key)); + return std::pair( + left_closed + //If left_closed, then comp(x, lower_key) is already the lower_bound + //condition so we save one comparison and go to the next level + //following traditional lower_bound algo + ? lower_bound_loop(NodeTraits::get_left(x), x, lower_key, comp) + //If left-open, comp(x, lower_key) is not the upper_bound algo + //condition so we must recheck current 'x' node with upper_bound algo + : upper_bound_loop(x, y, lower_key, comp) + , + right_closed + //If right_closed, then comp(upper_key, x) is already the upper_bound + //condition so we can save one comparison and go to the next level + //following lower_bound algo + ? upper_bound_loop(NodeTraits::get_right(x), y, upper_key, comp) + //If right-open, comp(upper_key, x) is not the lower_bound algo + //condition so we must recheck current 'x' node with lower_bound algo + : lower_bound_loop(x, y, upper_key, comp) + ); + } + } + return std::pair (y, y); + } + + //! Requires: "header" must be the header node of a tree. + //! KeyNodePtrCompare is a function object that induces a strict weak + //! ordering compatible with the strict weak ordering used to create the + //! the tree. KeyNodePtrCompare can compare KeyType with tree's node_ptrs. + //! + //! Effects: Returns the number of elements with a key equivalent to "key" + //! according to "comp". + //! + //! Complexity: Logarithmic. + //! + //! Throws: If "comp" throws. + template + static std::size_t count + (const_node_ptr header, const KeyType &key, KeyNodePtrCompare comp) + { + std::pair ret = equal_range(header, key, comp); + std::size_t n = 0; + while(ret.first != ret.second){ + ++n; + ret.first = base_type::next_node(ret.first); + } + return n; + } + + //! Requires: "header" must be the header node of a tree. + //! KeyNodePtrCompare is a function object that induces a strict weak + //! ordering compatible with the strict weak ordering used to create the + //! the tree. KeyNodePtrCompare can compare KeyType with tree's node_ptrs. + //! + //! Effects: Returns an a pair of node_ptr delimiting a range containing + //! all elements that are equivalent to "key" according to "comp" or an + //! empty range that indicates the position where those elements would be + //! if there are no equivalent elements. + //! + //! Complexity: Logarithmic. + //! + //! Throws: If "comp" throws. + template + BOOST_INTRUSIVE_FORCEINLINE static std::pair equal_range + (const_node_ptr header, const KeyType &key, KeyNodePtrCompare comp) + { + return bounded_range(header, key, key, comp, true, true); + } + + //! Requires: "header" must be the header node of a tree. + //! KeyNodePtrCompare is a function object that induces a strict weak + //! ordering compatible with the strict weak ordering used to create the + //! the tree. KeyNodePtrCompare can compare KeyType with tree's node_ptrs. + //! + //! Effects: Returns an a pair of node_ptr delimiting a range containing + //! the first element that is equivalent to "key" according to "comp" or an + //! empty range that indicates the position where that element would be + //! if there are no equivalent elements. + //! + //! Complexity: Logarithmic. + //! + //! Throws: If "comp" throws. + template + static std::pair lower_bound_range + (const_node_ptr header, const KeyType &key, KeyNodePtrCompare comp) + { + node_ptr const lb(lower_bound(header, key, comp)); + std::pair ret_ii(lb, lb); + if(lb != header && !comp(key, lb)){ + ret_ii.second = base_type::next_node(ret_ii.second); + } + return ret_ii; + } + + //! Requires: "header" must be the header node of a tree. + //! KeyNodePtrCompare is a function object that induces a strict weak + //! ordering compatible with the strict weak ordering used to create the + //! the tree. KeyNodePtrCompare can compare KeyType with tree's node_ptrs. + //! + //! Effects: Returns a node_ptr to the first element that is + //! not less than "key" according to "comp" or "header" if that element does + //! not exist. + //! + //! Complexity: Logarithmic. + //! + //! Throws: If "comp" throws. + template + BOOST_INTRUSIVE_FORCEINLINE static node_ptr lower_bound + (const_node_ptr header, const KeyType &key, KeyNodePtrCompare comp) + { + return lower_bound_loop(NodeTraits::get_parent(header), detail::uncast(header), key, comp); + } + + //! Requires: "header" must be the header node of a tree. + //! KeyNodePtrCompare is a function object that induces a strict weak + //! ordering compatible with the strict weak ordering used to create the + //! the tree. KeyNodePtrCompare can compare KeyType with tree's node_ptrs. + //! + //! Effects: Returns a node_ptr to the first element that is greater + //! than "key" according to "comp" or "header" if that element does not exist. + //! + //! Complexity: Logarithmic. + //! + //! Throws: If "comp" throws. + template + BOOST_INTRUSIVE_FORCEINLINE static node_ptr upper_bound + (const_node_ptr header, const KeyType &key, KeyNodePtrCompare comp) + { + return upper_bound_loop(NodeTraits::get_parent(header), detail::uncast(header), key, comp); + } + + //! Requires: "header" must be the header node of a tree. + //! "commit_data" must have been obtained from a previous call to + //! "insert_unique_check". No objects should have been inserted or erased + //! from the set between the "insert_unique_check" that filled "commit_data" + //! and the call to "insert_commit". + //! + //! + //! Effects: Inserts new_node in the set using the information obtained + //! from the "commit_data" that a previous "insert_check" filled. + //! + //! Complexity: Constant time. + //! + //! Throws: Nothing. + //! + //! Notes: This function has only sense if a "insert_unique_check" has been + //! 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) BOOST_NOEXCEPT + { return insert_commit(header, new_value, commit_data); } + + //! Requires: "header" must be the header node of a tree. + //! KeyNodePtrCompare is a function object that induces a strict weak + //! ordering compatible with the strict weak ordering used to create the + //! the tree. NodePtrCompare compares KeyType with a node_ptr. + //! + //! Effects: Checks if there is an equivalent node to "key" in the + //! tree according to "comp" and obtains the needed information to realize + //! a constant-time node insertion if there is no equivalent node. + //! + //! Returns: If there is an equivalent value + //! returns a pair containing a node_ptr to the already present node + //! and false. If there is not equivalent key can be inserted returns true + //! in the returned pair's boolean and fills "commit_data" that is meant to + //! be used with the "insert_commit" function to achieve a constant-time + //! insertion function. + //! + //! Complexity: Average complexity is at most logarithmic. + //! + //! Throws: If "comp" throws. + //! + //! Notes: This function is used to improve performance when constructing + //! a node is expensive and the user does not want to have two equivalent nodes + //! in the tree: if there is an equivalent value + //! the constructed object must be discarded. Many times, the part of the + //! node that is used to impose the order is much cheaper to construct + //! than the node and this function offers the possibility to use that part + //! to check if the insertion will be successful. + //! + //! If the check is successful, the user can construct the node and use + //! "insert_commit" to insert the node in constant-time. This gives a total + //! logarithmic complexity to the insertion: check(O(log(N)) + commit(O(1)). + //! + //! "commit_data" remains valid for a subsequent "insert_unique_commit" only + //! if no more objects are inserted or erased from the set. + template + static std::pair insert_unique_check + (const_node_ptr header, const KeyType &key + ,KeyNodePtrCompare comp, insert_commit_data &commit_data + #ifndef BOOST_INTRUSIVE_DOXYGEN_INVOKED + , std::size_t *pdepth = 0 + #endif + ) + { + std::size_t depth = 0; + node_ptr h(detail::uncast(header)); + node_ptr y(h); + node_ptr x(NodeTraits::get_parent(y)); + node_ptr prev = node_ptr(); + + //Find the upper bound, cache the previous value and if we should + //store it in the left or right node + bool left_child = true; + while(x){ + ++depth; + y = x; + left_child = comp(key, x); + x = left_child ? + NodeTraits::get_left(x) : (prev = y, NodeTraits::get_right(x)); + } + + if(pdepth) *pdepth = depth; + + //Since we've found the upper bound there is no other value with the same key if: + // - There is no previous node + // - The previous node is less than the key + const bool not_present = !prev || comp(prev, key); + if(not_present){ + commit_data.link_left = left_child; + commit_data.node = y; + } + return std::pair(prev, not_present); + } + + //! Requires: "header" must be the header node of a tree. + //! KeyNodePtrCompare is a function object that induces a strict weak + //! ordering compatible with the strict weak ordering used to create the + //! the tree. NodePtrCompare compares KeyType with a node_ptr. + //! "hint" is node from the "header"'s tree. + //! + //! Effects: Checks if there is an equivalent node to "key" in the + //! tree according to "comp" using "hint" as a hint to where it should be + //! inserted and obtains the needed information to realize + //! a constant-time node insertion if there is no equivalent node. + //! If "hint" is the upper_bound the function has constant time + //! complexity (two comparisons in the worst case). + //! + //! Returns: If there is an equivalent value + //! returns a pair containing a node_ptr to the already present node + //! and false. If there is not equivalent key can be inserted returns true + //! in the returned pair's boolean and fills "commit_data" that is meant to + //! be used with the "insert_commit" function to achieve a constant-time + //! insertion function. + //! + //! Complexity: Average complexity is at most logarithmic, but it is + //! amortized constant time if new_node should be inserted immediately before "hint". + //! + //! Throws: If "comp" throws. + //! + //! Notes: This function is used to improve performance when constructing + //! a node is expensive and the user does not want to have two equivalent nodes + //! in the tree: if there is an equivalent value + //! the constructed object must be discarded. Many times, the part of the + //! node that is used to impose the order is much cheaper to construct + //! than the node and this function offers the possibility to use that part + //! to check if the insertion will be successful. + //! + //! If the check is successful, the user can construct the node and use + //! "insert_commit" to insert the node in constant-time. This gives a total + //! logarithmic complexity to the insertion: check(O(log(N)) + commit(O(1)). + //! + //! "commit_data" remains valid for a subsequent "insert_unique_commit" only + //! if no more objects are inserted or erased from the set. + template + static std::pair insert_unique_check + (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 + #endif + ) + { + //hint must be bigger than the key + if(hint == header || comp(key, hint)){ + node_ptr prev(hint); + //Previous value should be less than the key + if(hint == begin_node(header) || comp((prev = base_type::prev_node(hint)), key)){ + commit_data.link_left = unique(header) || !NodeTraits::get_left(hint); + commit_data.node = commit_data.link_left ? hint : prev; + if(pdepth){ + *pdepth = commit_data.node == header ? 0 : depth(commit_data.node) + 1; + } + return std::pair(node_ptr(), true); + } + } + //Hint was wrong, use hintless insertion + return insert_unique_check(header, key, comp, commit_data, pdepth); + } + + //! Requires: "header" must be the header node of a tree. + //! NodePtrCompare is a function object that induces a strict weak + //! ordering compatible with the strict weak ordering used to create the + //! the tree. NodePtrCompare compares two node_ptrs. "hint" is node from + //! the "header"'s tree. + //! + //! Effects: Inserts new_node into the tree, using "hint" as a hint to + //! where it will be inserted. If "hint" is the upper_bound + //! the insertion takes constant time (two comparisons in the worst case). + //! + //! Complexity: Logarithmic in general, but it is amortized + //! constant time if new_node is inserted immediately before "hint". + //! + //! Throws: If "comp" throws. + template + static node_ptr insert_equal + (node_ptr h, node_ptr hint, node_ptr new_node, NodePtrCompare comp + #ifndef BOOST_INTRUSIVE_DOXYGEN_INVOKED + , std::size_t *pdepth = 0 + #endif + ) + { + insert_commit_data commit_data; + insert_equal_check(h, hint, new_node, comp, commit_data, pdepth); + insert_commit(h, new_node, commit_data); + return new_node; + } + + //! Requires: "h" must be the header node of a tree. + //! NodePtrCompare is a function object that induces a strict weak + //! ordering compatible with the strict weak ordering used to create the + //! the tree. NodePtrCompare compares two node_ptrs. + //! + //! Effects: Inserts new_node into the tree before the upper bound + //! according to "comp". + //! + //! Complexity: Average complexity for insert element is at + //! most logarithmic. + //! + //! Throws: If "comp" throws. + template + static node_ptr insert_equal_upper_bound + (node_ptr h, node_ptr new_node, NodePtrCompare comp + #ifndef BOOST_INTRUSIVE_DOXYGEN_INVOKED + , std::size_t *pdepth = 0 + #endif + ) + { + insert_commit_data commit_data; + insert_equal_upper_bound_check(h, new_node, comp, commit_data, pdepth); + insert_commit(h, new_node, commit_data); + return new_node; + } + + //! Requires: "h" must be the header node of a tree. + //! NodePtrCompare is a function object that induces a strict weak + //! ordering compatible with the strict weak ordering used to create the + //! the tree. NodePtrCompare compares two node_ptrs. + //! + //! Effects: Inserts new_node into the tree before the lower bound + //! according to "comp". + //! + //! Complexity: Average complexity for insert element is at + //! most logarithmic. + //! + //! Throws: If "comp" throws. + template + static node_ptr insert_equal_lower_bound + (node_ptr h, node_ptr new_node, NodePtrCompare comp + #ifndef BOOST_INTRUSIVE_DOXYGEN_INVOKED + , std::size_t *pdepth = 0 + #endif + ) + { + insert_commit_data commit_data; + insert_equal_lower_bound_check(h, new_node, comp, commit_data, pdepth); + insert_commit(h, new_node, commit_data); + return new_node; + } + + //! Requires: "header" must be the header node of a tree. + //! "pos" must be a valid iterator or header (end) node. + //! "pos" must be an iterator pointing to the successor to "new_node" + //! once inserted according to the order of already inserted nodes. This function does not + //! check "pos" and this precondition must be guaranteed by the caller. + //! + //! Effects: Inserts new_node into the tree before "pos". + //! + //! Complexity: Constant-time. + //! + //! Throws: Nothing. + //! + //! Note: If "pos" is not the successor of the newly inserted "new_node" + //! tree invariants might be broken. + static node_ptr insert_before + (node_ptr header, node_ptr pos, node_ptr new_node + #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); + insert_commit(header, new_node, commit_data); + return new_node; + } + + //! Requires: "header" must be the header node of a tree. + //! "new_node" must be, according to the used ordering no less than the + //! greatest inserted key. + //! + //! Effects: Inserts new_node into the tree before "pos". + //! + //! Complexity: Constant-time. + //! + //! Throws: Nothing. + //! + //! Note: If "new_node" is less than the greatest inserted key + //! tree invariants are broken. This function is slightly faster than + //! using "insert_before". + static void push_back + (node_ptr header, node_ptr new_node + #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); + insert_commit(header, new_node, commit_data); + } + + //! Requires: "header" must be the header node of a tree. + //! "new_node" must be, according to the used ordering, no greater than the + //! lowest inserted key. + //! + //! Effects: Inserts new_node into the tree before "pos". + //! + //! Complexity: Constant-time. + //! + //! Throws: Nothing. + //! + //! Note: If "new_node" is greater than the lowest inserted key + //! tree invariants are broken. This function is slightly faster than + //! using "insert_before". + static void push_front + (node_ptr header, node_ptr new_node + #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: '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 + //! to that node. (The root node is at depth 0.) + //! + //! Complexity: Logarithmic to the number of nodes in the tree. + //! + //! Throws: Nothing. + static std::size_t depth(const_node_ptr n) BOOST_NOEXCEPT + { + std::size_t depth = 0; + node_ptr p_parent; + while(n != NodeTraits::get_parent(p_parent = NodeTraits::get_parent(n))){ + ++depth; + n = p_parent; + } + return depth; + } + + //! Requires: "cloner" must be a function + //! object taking a node_ptr and returning a new cloned node of it. "disposer" must + //! take a node_ptr and shouldn't throw. + //! + //! Effects: First empties target tree calling + //! 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()(node_ptr) to obtain + //! the nodes of the target tree. If "cloner" throws, the cloned target nodes + //! 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. + //! + //! Throws: If cloner functor throws. If this happens target nodes are disposed. + template + static void clone + (const_node_ptr source_header, node_ptr target_header, Cloner cloner, Disposer disposer) + { + if(!unique(target_header)){ + clear_and_dispose(target_header, disposer); + } + + node_ptr leftmost, rightmost; + node_ptr new_root = clone_subtree + (source_header, target_header, cloner, disposer, leftmost, rightmost); + + //Now update header node + NodeTraits::set_parent(target_header, new_root); + NodeTraits::set_left (target_header, leftmost); + NodeTraits::set_right (target_header, rightmost); + } + + //! Requires: header must be the header of a tree, z a node + //! of that tree and z != header. + //! + //! Effects: Erases node "z" from the tree with header "header". + //! + //! Complexity: Amortized constant time. + //! + //! Throws: Nothing. + BOOST_INTRUSIVE_FORCEINLINE static void erase(node_ptr header, node_ptr z) BOOST_NOEXCEPT + { + data_for_rebalance ignored; + erase(header, z, ignored); + } + + //! Requires: header1 and header2 must be the headers of trees tree1 and tree2 + //! respectively, z a non-header node of tree1. NodePtrCompare is the comparison + //! function of tree1.. + //! + //! Effects: Transfers node "z" from tree1 to tree2 if tree1 does not contain + //! a node that is equivalent to z. + //! + //! Returns: True if the node was trasferred, false otherwise. + //! + //! Complexity: Logarithmic. + //! + //! Throws: If the comparison throws. + template + BOOST_INTRUSIVE_FORCEINLINE static bool transfer_unique + (node_ptr header1, NodePtrCompare comp, node_ptr header2, node_ptr z) + { + data_for_rebalance ignored; + return transfer_unique(header1, comp, header2, z, ignored); + } + + //! Requires: header1 and header2 must be the headers of trees tree1 and tree2 + //! respectively, z a non-header node of tree1. NodePtrCompare is the comparison + //! function of tree1.. + //! + //! Effects: Transfers node "z" from tree1 to tree2. + //! + //! Complexity: Logarithmic. + //! + //! Throws: If the comparison throws. + template + BOOST_INTRUSIVE_FORCEINLINE static void transfer_equal + (node_ptr header1, NodePtrCompare comp, node_ptr header2, node_ptr z) + { + data_for_rebalance ignored; + transfer_equal(header1, comp, header2, z, ignored); + } + + //! 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 n) BOOST_NOEXCEPT + { + node_ptr x = NodeTraits::get_parent(n); + if(x){ + while(!base_type::is_header(x)) + x = NodeTraits::get_parent(x); + erase(x, n); + } + } + + //! Requires: header must be the header of a tree. + //! + //! Effects: Rebalances the tree. + //! + //! Throws: Nothing. + //! + //! Complexity: Linear. + static void rebalance(node_ptr header) BOOST_NOEXCEPT + { + node_ptr root = NodeTraits::get_parent(header); + if(root){ + rebalance_subtree(root); + } + } + + //! Requires: old_root is a node of a tree. It shall not be null. + //! + //! Effects: Rebalances the subtree rooted at old_root. + //! + //! Returns: The new root of the subtree. + //! + //! Throws: Nothing. + //! + //! Complexity: Linear. + static node_ptr rebalance_subtree(node_ptr old_root) BOOST_NOEXCEPT + { + //Taken from: + //"Tree rebalancing in optimal time and space" + //Quentin F. Stout and Bette L. Warren + + //To avoid irregularities in the algorithm (old_root can be a + //left or right child or even the root of the tree) just put the + //root as the right child of its parent. Before doing this backup + //information to restore the original relationship after + //the algorithm is applied. + node_ptr super_root = NodeTraits::get_parent(old_root); + BOOST_INTRUSIVE_INVARIANT_ASSERT(super_root); + + //Get root info + node_ptr super_root_right_backup = NodeTraits::get_right(super_root); + bool super_root_is_header = NodeTraits::get_parent(super_root) == old_root; + bool old_root_is_right = is_right_child(old_root); + NodeTraits::set_right(super_root, old_root); + + std::size_t size; + subtree_to_vine(super_root, size); + vine_to_subtree(super_root, size); + node_ptr new_root = NodeTraits::get_right(super_root); + + //Recover root + if(super_root_is_header){ + NodeTraits::set_right(super_root, super_root_right_backup); + NodeTraits::set_parent(super_root, new_root); + } + else if(old_root_is_right){ + NodeTraits::set_right(super_root, new_root); + } + else{ + NodeTraits::set_right(super_root, super_root_right_backup); + NodeTraits::set_left(super_root, new_root); + } + return new_root; + } + + //! Effects: Asserts the integrity of the container with additional checks provided by the user. + //! + //! Requires: header must be the header of a tree. + //! + //! Complexity: Linear time. + //! + //! 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_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){ + // check left&right header pointers + BOOST_INTRUSIVE_INVARIANT_ASSERT(NodeTraits::get_left(header) == header); + BOOST_INTRUSIVE_INVARIANT_ASSERT(NodeTraits::get_right(header) == header); + } + else{ + // check parent pointer of root node + BOOST_INTRUSIVE_INVARIANT_ASSERT(NodeTraits::get_parent(root_node_ptr) == header); + // check subtree from root + check_subtree(root_node_ptr, checker, checker_return); + // check left&right header pointers + const_node_ptr p = root_node_ptr; + while (NodeTraits::get_left(p)) { p = NodeTraits::get_left(p); } + BOOST_INTRUSIVE_INVARIANT_ASSERT(NodeTraits::get_left(header) == p); + p = root_node_ptr; + while (NodeTraits::get_right(p)) { p = NodeTraits::get_right(p); } + BOOST_INTRUSIVE_INVARIANT_ASSERT(NodeTraits::get_right(header) == p); + } + } + + protected: + + template + static bool transfer_unique + (node_ptr header1, NodePtrCompare comp, node_ptr header2, node_ptr z, data_for_rebalance &info) + { + insert_commit_data commit_data; + bool const transferable = insert_unique_check(header1, z, comp, commit_data).second; + if(transferable){ + erase(header2, z, info); + insert_commit(header1, z, commit_data); + } + return transferable; + } + + template + static void transfer_equal + (node_ptr header1, NodePtrCompare comp, node_ptr header2, node_ptr z, data_for_rebalance &info) + { + insert_commit_data commit_data; + insert_equal_upper_bound_check(header1, z, comp, commit_data); + erase(header2, z, info); + insert_commit(header1, z, commit_data); + } + + static void erase(node_ptr header, node_ptr z, data_for_rebalance &info) + { + node_ptr y(z); + node_ptr x; + const node_ptr z_left(NodeTraits::get_left(z)); + const node_ptr z_right(NodeTraits::get_right(z)); + + if(!z_left){ + x = z_right; // x might be null. + } + else if(!z_right){ // z has exactly one non-null child. y == z. + x = z_left; // x is not null. + BOOST_ASSERT(x); + } + else{ //make y != z + // y = find z's successor + y = base_type::minimum(z_right); + x = NodeTraits::get_right(y); // x might be null. + } + + node_ptr x_parent; + const node_ptr z_parent(NodeTraits::get_parent(z)); + const bool z_is_leftchild(NodeTraits::get_left(z_parent) == z); + + if(y != z){ //has two children and y is the minimum of z + //y is z's successor and it has a null left child. + //x is the right child of y (it can be null) + //Relink y in place of z and link x with y's old parent + NodeTraits::set_parent(z_left, y); + NodeTraits::set_left(y, z_left); + if(y != z_right){ + //Link y with the right tree of z + NodeTraits::set_right(y, z_right); + NodeTraits::set_parent(z_right, y); + //Link x with y's old parent (y must be a left child) + x_parent = NodeTraits::get_parent(y); + BOOST_ASSERT(NodeTraits::get_left(x_parent) == y); + if(x) + NodeTraits::set_parent(x, x_parent); + //Since y was the successor and not the right child of z, it must be a left child + NodeTraits::set_left(x_parent, x); + } + else{ //y was the right child of y so no need to fix x's position + x_parent = y; + } + NodeTraits::set_parent(y, z_parent); + this_type::set_child(header, y, z_parent, z_is_leftchild); + } + else { // z has zero or one child, x is one child (it can be null) + //Just link x to z's parent + x_parent = z_parent; + if(x) + NodeTraits::set_parent(x, z_parent); + this_type::set_child(header, x, z_parent, z_is_leftchild); + + //Now update leftmost/rightmost in case z was one of them + if(NodeTraits::get_left(header) == z){ + //z_left must be null because z is the leftmost + BOOST_ASSERT(!z_left); + NodeTraits::set_left(header, !z_right ? + z_parent : // makes leftmost == header if z == root + base_type::minimum(z_right)); + } + if(NodeTraits::get_right(header) == z){ + //z_right must be null because z is the rightmost + BOOST_ASSERT(!z_right); + NodeTraits::set_right(header, !z_left ? + z_parent : // makes rightmost == header if z == root + base_type::maximum(z_left)); + } + } + + //If z had 0/1 child, y == z and one of its children (and maybe null) + //If z had 2 children, y is the successor of z and x is the right child of y + info.x = x; + info.y = y; + //If z had 0/1 child, x_parent is the new parent of the old right child of y (z's successor) + //If z had 2 children, x_parent is the new parent of y (z_parent) + BOOST_ASSERT(!x || NodeTraits::get_parent(x) == x_parent); + info.x_parent = x_parent; + } + + //! 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_node_ptr subtree) BOOST_NOEXCEPT + { + std::size_t count = 0; + if (subtree){ + node_ptr n = detail::uncast(subtree); + node_ptr m = NodeTraits::get_left(n); + while(m){ + n = m; + m = NodeTraits::get_left(n); + } + + while(1){ + ++count; + node_ptr n_right(NodeTraits::get_right(n)); + if(n_right){ + n = n_right; + m = NodeTraits::get_left(n); + while(m){ + n = m; + m = NodeTraits::get_left(n); + } + } + else { + do{ + if (n == subtree){ + return count; + } + m = n; + n = NodeTraits::get_parent(n); + }while(NodeTraits::get_left(n) != m); + } + } + } + return count; + } + + //! Requires: p is a node of a tree. + //! + //! Effects: Returns true if p is a left child. + //! + //! Complexity: Constant. + //! + //! Throws: Nothing. + 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. + //! + //! Effects: Returns true if p is a right child. + //! + //! Complexity: Constant. + //! + //! Throws: Nothing. + 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 + (node_ptr header, node_ptr pos + , insert_commit_data &commit_data + #ifndef BOOST_INTRUSIVE_DOXYGEN_INVOKED + , std::size_t *pdepth = 0 + #endif + ) + { + node_ptr prev(pos); + if(pos != NodeTraits::get_left(header)) + prev = base_type::prev_node(pos); + bool link_left = unique(header) || !NodeTraits::get_left(pos); + commit_data.link_left = link_left; + commit_data.node = link_left ? pos : prev; + if(pdepth){ + *pdepth = commit_data.node == header ? 0 : depth(commit_data.node) + 1; + } + } + + static void push_back_check + (node_ptr header, insert_commit_data &commit_data + #ifndef BOOST_INTRUSIVE_DOXYGEN_INVOKED + , std::size_t *pdepth = 0 + #endif + ) BOOST_NOEXCEPT + { + node_ptr prev(NodeTraits::get_right(header)); + if(pdepth){ + *pdepth = prev == header ? 0 : depth(prev) + 1; + } + commit_data.link_left = false; + commit_data.node = prev; + } + + static void push_front_check + (node_ptr header, insert_commit_data &commit_data + #ifndef BOOST_INTRUSIVE_DOXYGEN_INVOKED + , std::size_t *pdepth = 0 + #endif + ) BOOST_NOEXCEPT + { + node_ptr pos(NodeTraits::get_left(header)); + if(pdepth){ + *pdepth = pos == header ? 0 : depth(pos) + 1; + } + commit_data.link_left = true; + commit_data.node = pos; + } + + template + static void insert_equal_check + (node_ptr header, node_ptr hint, node_ptr new_node, NodePtrCompare comp + , insert_commit_data &commit_data + /// @cond + , std::size_t *pdepth = 0 + /// @endcond + ) + { + if(hint == header || !comp(hint, new_node)){ + node_ptr prev(hint); + if(hint == NodeTraits::get_left(header) || + !comp(new_node, (prev = base_type::prev_node(hint)))){ + bool link_left = unique(header) || !NodeTraits::get_left(hint); + commit_data.link_left = link_left; + commit_data.node = link_left ? hint : prev; + if(pdepth){ + *pdepth = commit_data.node == header ? 0 : depth(commit_data.node) + 1; + } + } + else{ + insert_equal_upper_bound_check(header, new_node, comp, commit_data, pdepth); + } + } + else{ + insert_equal_lower_bound_check(header, new_node, comp, commit_data, pdepth); + } + } + + template + static void insert_equal_upper_bound_check + (node_ptr h, node_ptr new_node, NodePtrCompare comp, insert_commit_data & commit_data, std::size_t *pdepth = 0) + { + std::size_t depth = 0; + node_ptr y(h); + node_ptr x(NodeTraits::get_parent(y)); + + while(x){ + ++depth; + y = x; + x = comp(new_node, x) ? + NodeTraits::get_left(x) : NodeTraits::get_right(x); + } + if(pdepth) *pdepth = depth; + commit_data.link_left = (y == h) || comp(new_node, y); + commit_data.node = y; + } + + template + static void insert_equal_lower_bound_check + (node_ptr h, node_ptr new_node, NodePtrCompare comp, insert_commit_data & commit_data, std::size_t *pdepth = 0) + { + std::size_t depth = 0; + node_ptr y(h); + node_ptr x(NodeTraits::get_parent(y)); + + while(x){ + ++depth; + y = x; + x = !comp(x, new_node) ? + NodeTraits::get_left(x) : NodeTraits::get_right(x); + } + if(pdepth) *pdepth = depth; + commit_data.link_left = (y == h) || !comp(y, new_node); + commit_data.node = y; + } + + static void insert_commit + (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()); + node_ptr parent_node(commit_data.node); + if(parent_node == header){ + NodeTraits::set_parent(header, new_node); + NodeTraits::set_right(header, new_node); + NodeTraits::set_left(header, new_node); + } + else if(commit_data.link_left){ + NodeTraits::set_left(parent_node, new_node); + if(parent_node == NodeTraits::get_left(header)) + NodeTraits::set_left(header, new_node); + } + else{ + NodeTraits::set_right(parent_node, new_node); + if(parent_node == NodeTraits::get_right(header)) + NodeTraits::set_right(header, new_node); + } + NodeTraits::set_parent(new_node, parent_node); + NodeTraits::set_right(new_node, node_ptr()); + NodeTraits::set_left(new_node, node_ptr()); + } + + //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) BOOST_NOEXCEPT + { + if(new_parent == header) + NodeTraits::set_parent(header, new_child); + else if(link_left) + NodeTraits::set_left(new_parent, new_child); + else + NodeTraits::set_right(new_parent, new_child); + } + + // 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) BOOST_NOEXCEPT + { + node_ptr p_right_left(NodeTraits::get_left(p_right)); + NodeTraits::set_right(p, p_right_left); + if(p_right_left){ + NodeTraits::set_parent(p_right_left, p); + } + NodeTraits::set_left(p_right, p); + NodeTraits::set_parent(p, p_right); + } + + // 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) BOOST_NOEXCEPT + { + const bool p_was_left(NodeTraits::get_left(p_parent) == p); + rotate_left_no_parent_fix(p, p_right); + NodeTraits::set_parent(p_right, p_parent); + set_child(header, p_right, p_parent, p_was_left); + } + + // 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) BOOST_NOEXCEPT + { + node_ptr p_left_right(NodeTraits::get_right(p_left)); + NodeTraits::set_left(p, p_left_right); + if(p_left_right){ + NodeTraits::set_parent(p_left_right, p); + } + NodeTraits::set_right(p_left, p); + NodeTraits::set_parent(p, p_left); + } + + // 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) BOOST_NOEXCEPT + { + const bool p_was_left(NodeTraits::get_left(p_parent) == p); + rotate_right_no_parent_fix(p, p_left); + NodeTraits::set_parent(p_left, p_parent); + set_child(header, p_left, p_parent, p_was_left); + } + + private: + + 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. + //No parent pointer is updated when transforming a tree to a vine as + //most of them will be overriten during compression rotations. + //A final pass must be made after the rebalancing to updated those + //pointers not updated by tree_to_vine + compression calls + std::size_t len = 0; + node_ptr remainder = NodeTraits::get_right(vine_tail); + while(remainder){ + node_ptr tempptr = NodeTraits::get_left(remainder); + if(!tempptr){ //move vine-tail down one + vine_tail = remainder; + remainder = NodeTraits::get_right(remainder); + ++len; + } + else{ //rotate + NodeTraits::set_left(remainder, NodeTraits::get_right(tempptr)); + NodeTraits::set_right(tempptr, remainder); + remainder = tempptr; + NodeTraits::set_right(vine_tail, tempptr); + } + } + size = len; + } + + 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); + node_ptr child_right = NodeTraits::get_right(child); + NodeTraits::set_right(scanner, child_right); + //Avoid setting the parent of child_right + scanner = child_right; + node_ptr scanner_left = NodeTraits::get_left(scanner); + NodeTraits::set_right(child, scanner_left); + if(scanner_left) + NodeTraits::set_parent(scanner_left, child); + NodeTraits::set_left(scanner, child); + NodeTraits::set_parent(child, scanner); + } + } + + 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)); + compress_subtree(super_root, leaf_nodes); //create deepest leaves + std::size_t vine_nodes = count - leaf_nodes; + while(vine_nodes > 1){ + vine_nodes /= 2; + compress_subtree(super_root, vine_nodes); + } + + //Update parents of nodes still in the in the original vine line + //as those have not been updated by subtree_to_vine or compress_subtree + for ( node_ptr q = super_root, p = NodeTraits::get_right(super_root) + ; p + ; q = p, p = NodeTraits::get_right(p)){ + NodeTraits::set_parent(p, q); + } + } + + //! Requires: "n" must be a node inserted in a tree. + //! + //! Effects: Returns a pointer to the header node of the tree. + //! + //! Complexity: Logarithmic. + //! + //! Throws: Nothing. + static node_ptr get_root(node_ptr n) BOOST_NOEXCEPT + { + 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); + } + return x; + } + else{ + return n; + } + } + + template + static node_ptr clone_subtree + (const_node_ptr source_parent, node_ptr target_parent + , Cloner cloner, Disposer disposer + , node_ptr &leftmost_out, node_ptr &rightmost_out + ) + { + node_ptr target_sub_root = target_parent; + node_ptr source_root = NodeTraits::get_parent(source_parent); + if(!source_root){ + leftmost_out = rightmost_out = source_root; + } + else{ + //We'll calculate leftmost and rightmost nodes while iterating + node_ptr current = source_root; + node_ptr insertion_point = target_sub_root = cloner(current); + + //We'll calculate leftmost and rightmost nodes while iterating + node_ptr leftmost = target_sub_root; + node_ptr rightmost = target_sub_root; + + //First set the subroot + NodeTraits::set_left(target_sub_root, node_ptr()); + NodeTraits::set_right(target_sub_root, node_ptr()); + NodeTraits::set_parent(target_sub_root, target_parent); + + dispose_subtree_disposer rollback(disposer, target_sub_root); + while(true) { + //First clone left nodes + if( NodeTraits::get_left(current) && + !NodeTraits::get_left(insertion_point)) { + current = NodeTraits::get_left(current); + node_ptr temp = insertion_point; + //Clone and mark as leaf + insertion_point = cloner(current); + NodeTraits::set_left (insertion_point, node_ptr()); + NodeTraits::set_right (insertion_point, node_ptr()); + //Insert left + NodeTraits::set_parent(insertion_point, temp); + NodeTraits::set_left (temp, insertion_point); + //Update leftmost + if(rightmost == target_sub_root) + leftmost = insertion_point; + } + //Then clone right nodes + else if( NodeTraits::get_right(current) && + !NodeTraits::get_right(insertion_point)){ + current = NodeTraits::get_right(current); + node_ptr temp = insertion_point; + //Clone and mark as leaf + insertion_point = cloner(current); + NodeTraits::set_left (insertion_point, node_ptr()); + NodeTraits::set_right (insertion_point, node_ptr()); + //Insert right + NodeTraits::set_parent(insertion_point, temp); + NodeTraits::set_right (temp, insertion_point); + //Update rightmost + rightmost = insertion_point; + } + //If not, go up + else if(current == source_root){ + break; + } + else{ + //Branch completed, go up searching more nodes to clone + current = NodeTraits::get_parent(current); + insertion_point = NodeTraits::get_parent(insertion_point); + } + } + rollback.release(); + leftmost_out = leftmost; + rightmost_out = rightmost; + } + return target_sub_root; + } + + template + static void dispose_subtree(node_ptr x, Disposer disposer) BOOST_NOEXCEPT + { + while (x){ + node_ptr save(NodeTraits::get_left(x)); + if (save) { + // Right rotation + NodeTraits::set_left(x, NodeTraits::get_right(save)); + NodeTraits::set_right(save, x); + } + else { + save = NodeTraits::get_right(x); + init(x); + disposer(x); + } + x = save; + } + } + + template + static node_ptr lower_bound_loop + (node_ptr x, node_ptr y, const KeyType &key, KeyNodePtrCompare comp) + { + while(x){ + if(comp(x, key)){ + x = NodeTraits::get_right(x); + } + else{ + y = x; + x = NodeTraits::get_left(x); + } + } + return y; + } + + template + static node_ptr upper_bound_loop + (node_ptr x, node_ptr y, const KeyType &key, KeyNodePtrCompare comp) + { + while(x){ + if(comp(key, x)){ + y = x; + x = NodeTraits::get_left(x); + } + else{ + x = NodeTraits::get_right(x); + } + } + return y; + } + + template + static void check_subtree(const_node_ptr n, Checker checker, typename Checker::return_type& check_return) + { + 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) == n); + check_subtree(left, checker, check_return_left); + } + if (right) + { + BOOST_INTRUSIVE_INVARIANT_ASSERT(NodeTraits::get_parent(right) == n); + check_subtree(right, checker, check_return_right); + } + checker(n, check_return_left, check_return_right, check_return); + } +}; + +/// @cond + +template +struct get_algo +{ + typedef bstree_algorithms type; +}; + +template +struct get_node_checker +{ + typedef detail::bstree_node_checker type; +}; + +/// @endcond + +} //namespace intrusive +} //namespace boost + +#include + +#endif //BOOST_INTRUSIVE_BSTREE_ALGORITHMS_HPP diff --git a/third_party/boost/libs/intrusive/include/boost/intrusive/circular_list_algorithms.hpp b/third_party/boost/libs/intrusive/include/boost/intrusive/circular_list_algorithms.hpp new file mode 100644 index 00000000000..ab34c7e3091 --- /dev/null +++ b/third_party/boost/libs/intrusive/include/boost/intrusive/circular_list_algorithms.hpp @@ -0,0 +1,476 @@ +///////////////////////////////////////////////////////////////////////////// +// +// (C) Copyright Olaf Krzikalla 2004-2006. +// (C) Copyright Ion Gaztanaga 2006-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_CIRCULAR_LIST_ALGORITHMS_HPP +#define BOOST_INTRUSIVE_CIRCULAR_LIST_ALGORITHMS_HPP + +#include +#include +#include +#include +#include + +#if defined(BOOST_HAS_PRAGMA_ONCE) +# pragma once +#endif + +namespace boost { +namespace intrusive { + +//! circular_list_algorithms provides basic algorithms to manipulate nodes +//! forming a circular doubly linked list. An empty circular list is formed by a node +//! whose pointers point to itself. +//! +//! circular_list_algorithms is configured with a NodeTraits class, which encapsulates the +//! information about the node to be manipulated. NodeTraits must support the +//! following interface: +//! +//! Typedefs: +//! +//! node: The type of the node that forms the circular list +//! +//! node_ptr: A pointer to a node +//! +//! const_node_ptr: A pointer to a const node +//! +//! Static functions: +//! +//! static node_ptr get_previous(const_node_ptr n); +//! +//! static void set_previous(node_ptr n, node_ptr prev); +//! +//! static node_ptr get_next(const_node_ptr n); +//! +//! static void set_next(node_ptr n, node_ptr next); +template +class circular_list_algorithms +{ + public: + typedef typename NodeTraits::node node; + typedef typename NodeTraits::node_ptr node_ptr; + typedef typename NodeTraits::const_node_ptr const_node_ptr; + typedef NodeTraits node_traits; + + //! Effects: Constructs an non-used list element, so that + //! inited(this_node) == true + //! + //! Complexity: Constant + //! + //! Throws: Nothing. + static void init(node_ptr this_node) BOOST_NOEXCEPT + { + const node_ptr null_node = node_ptr(); + NodeTraits::set_next(this_node, null_node); + NodeTraits::set_previous(this_node, null_node); + } + + //! Effects: Returns true is "this_node" is in a non-used state + //! as if it was initialized by the "init" function. + //! + //! Complexity: Constant + //! + //! Throws: Nothing. + 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 + //! node of the circular list: + //! NodeTraits::get_next(this_node) == NodeTraits::get_previous(this_node) + //! == this_node. + //! + //! Complexity: Constant + //! + //! Throws: Nothing. + 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. + //! + //! Effects: Returns true is "this_node" is the only node of a circular list: + //! return NodeTraits::get_next(this_node) == this_node + //! + //! Complexity: Constant + //! + //! Throws: Nothing. + static bool unique(const_node_ptr this_node) BOOST_NOEXCEPT + { + node_ptr next = NodeTraits::get_next(this_node); + return !next || next == this_node; + } + + //! Requires: this_node must be in a circular list or be an empty circular list. + //! + //! Effects: Returns the number of nodes in a circular list. If the circular list + //! is empty, returns 1. + //! + //! Complexity: Linear + //! + //! Throws: Nothing. + static std::size_t count(const_node_ptr this_node) BOOST_NOEXCEPT + { + std::size_t result = 0; + const_node_ptr p = this_node; + do{ + p = NodeTraits::get_next(p); + ++result; + }while (p != this_node); + return result; + } + + //! Requires: this_node must be in a circular list or be an empty circular list. + //! + //! Effects: Unlinks the node from the circular list. + //! + //! Complexity: Constant + //! + //! Throws: Nothing. + 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)); + NodeTraits::set_next(prev, next); + NodeTraits::set_previous(next, prev); + return next; + } + + //! Requires: b and e must be nodes of the same circular list or an empty range. + //! + //! Effects: Unlinks the node [b, e) from the circular list. + //! + //! Complexity: Constant + //! + //! Throws: Nothing. + static void unlink(node_ptr b, node_ptr e) BOOST_NOEXCEPT + { + if (b != e) { + node_ptr prevb(NodeTraits::get_previous(b)); + NodeTraits::set_previous(e, prevb); + NodeTraits::set_next(prevb, e); + } + } + + //! Requires: nxt_node must be a node of a circular list. + //! + //! Effects: Links this_node before nxt_node in the circular list. + //! + //! Complexity: Constant + //! + //! Throws: Nothing. + 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); + NodeTraits::set_next(this_node, nxt_node); + //nxt_node might be an alias for prev->next_ + //so use it before NodeTraits::set_next(prev, ...) + //is called and the reference changes its value + NodeTraits::set_previous(nxt_node, this_node); + NodeTraits::set_next(prev, this_node); + } + + //! Requires: prev_node must be a node of a circular list. + //! + //! Effects: Links this_node after prev_node in the circular list. + //! + //! Complexity: Constant + //! + //! Throws: Nothing. + 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); + NodeTraits::set_next(this_node, next); + //prev_node might be an alias for next->next_ + //so use it before update it before NodeTraits::set_previous(next, ...) + //is called and the reference changes it's value + NodeTraits::set_next(prev_node, this_node); + NodeTraits::set_previous(next, this_node); + } + + //! Requires: this_node and other_node must be nodes inserted + //! in circular lists or be empty circular lists. + //! + //! Effects: Swaps the position of the nodes: this_node is inserted in + //! other_nodes position in the second circular list and the other_node is inserted + //! in this_node's position in the first circular list. + //! + //! Complexity: Constant + //! + //! Throws: Nothing. + static void swap_nodes(node_ptr this_node, node_ptr other_node) BOOST_NOEXCEPT + { + if (other_node == this_node) + return; + bool this_inited = inited(this_node); + bool other_inited = inited(other_node); + if(this_inited){ + init_header(this_node); + } + if(other_inited){ + init_header(other_node); + } + + node_ptr next_this(NodeTraits::get_next(this_node)); + node_ptr prev_this(NodeTraits::get_previous(this_node)); + node_ptr next_other(NodeTraits::get_next(other_node)); + node_ptr prev_other(NodeTraits::get_previous(other_node)); + //these first two swaps must happen before the other two + swap_prev(next_this, next_other); + swap_next(prev_this, prev_other); + swap_next(this_node, other_node); + swap_prev(this_node, other_node); + + if(this_inited){ + init(other_node); + } + if(other_inited){ + init(this_node); + } + } + + //! 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 or may not be an iterator in + // [b, e). + //! + //! Effects: Removes the nodes from [b, e) range from their circular list and inserts + //! them before p in p's circular list. + //! + //! Complexity: Constant + //! + //! Throws: Nothing. + static void transfer(node_ptr p, node_ptr b, node_ptr e) BOOST_NOEXCEPT + { + 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)); + NodeTraits::set_next(prev_e, p); + NodeTraits::set_previous(p, prev_e); + NodeTraits::set_next(prev_b, e); + NodeTraits::set_previous(e, prev_b); + NodeTraits::set_next(prev_p, b); + NodeTraits::set_previous(b, prev_p); + } + } + + //! Requires: i must a node of a circular list + //! and p must be a node of a different circular list. + //! + //! Effects: Removes the node i from its circular list and inserts + //! it before p in p's circular list. + //! If p == i or p == NodeTraits::get_next(i), this function is a null operation. + //! + //! Complexity: Constant + //! + //! Throws: Nothing. + static void transfer(node_ptr p, node_ptr i) BOOST_NOEXCEPT + { + node_ptr n(NodeTraits::get_next(i)); + if(n != p && i != p){ + node_ptr prev_p(NodeTraits::get_previous(p)); + node_ptr prev_i(NodeTraits::get_previous(i)); + NodeTraits::set_next(prev_p, i); + NodeTraits::set_previous(i, prev_p); + NodeTraits::set_next(i, p); + NodeTraits::set_previous(p, i); + NodeTraits::set_previous(n, prev_i); + NodeTraits::set_next(prev_i, n); + + } + } + + //! Effects: Reverses the order of elements in the list. + //! + //! Throws: Nothing. + //! + //! Complexity: This function is linear time. + static void reverse(node_ptr p) BOOST_NOEXCEPT + { + node_ptr f(NodeTraits::get_next(p)); + node_ptr i(NodeTraits::get_next(f)), e(p); + + while(i != e) { + node_ptr n = i; + i = NodeTraits::get_next(i); + transfer(f, n, i); + f = n; + } + } + + //! Effects: Moves the node p n positions towards the end of the list. + //! + //! Throws: Nothing. + //! + //! Complexity: Linear to the number of moved positions. + static void move_backwards(node_ptr p, std::size_t n) BOOST_NOEXCEPT + { + //Null shift, nothing to do + if(!n) return; + node_ptr first = NodeTraits::get_next(p); + //size() == 0 or 1, nothing to do + if(first == NodeTraits::get_previous(p)) return; + unlink(p); + //Now get the new first node + while(n--){ + first = NodeTraits::get_next(first); + } + link_before(first, p); + } + + //! Effects: Moves the node p n positions towards the beginning of the list. + //! + //! Throws: Nothing. + //! + //! Complexity: Linear to the number of moved positions. + static void move_forward(node_ptr p, std::size_t n) BOOST_NOEXCEPT + { + //Null shift, nothing to do + if(!n) return; + node_ptr last = NodeTraits::get_previous(p); + //size() == 0 or 1, nothing to do + if(last == NodeTraits::get_next(p)) return; + + unlink(p); + //Now get the new last node + while(n--){ + last = NodeTraits::get_previous(last); + } + link_after(last, p); + } + + //! Requires: f and l must be in a circular list. + //! + //! Effects: Returns the number of nodes in the range [f, l). + //! + //! Complexity: Linear + //! + //! Throws: Nothing. + static std::size_t distance(const_node_ptr f, const_node_ptr l) BOOST_NOEXCEPT + { + std::size_t result = 0; + while(f != l){ + f = NodeTraits::get_next(f); + ++result; + } + return result; + } + + struct stable_partition_info + { + std::size_t num_1st_partition; + std::size_t num_2nd_partition; + node_ptr beg_2st_partition; + }; + + template + static void stable_partition(node_ptr beg, node_ptr end, Pred pred, stable_partition_info &info) + { + node_ptr bcur = node_traits::get_previous(beg); + node_ptr cur = beg; + node_ptr new_f = end; + + std::size_t num1 = 0, num2 = 0; + while(cur != end){ + if(pred(cur)){ + ++num1; + bcur = cur; + cur = node_traits::get_next(cur); + } + else{ + ++num2; + node_ptr last_to_remove = bcur; + new_f = cur; + bcur = cur; + cur = node_traits::get_next(cur); + BOOST_INTRUSIVE_TRY{ + //Main loop + while(cur != end){ + if(pred(cur)){ //Might throw + ++num1; + //Process current node + node_traits::set_next (last_to_remove, cur); + node_traits::set_previous(cur, last_to_remove); + last_to_remove = cur; + node_ptr nxt = node_traits::get_next(cur); + node_traits::set_next (bcur, nxt); + node_traits::set_previous(nxt, bcur); + cur = nxt; + } + else{ + ++num2; + bcur = cur; + cur = node_traits::get_next(cur); + } + } + } + BOOST_INTRUSIVE_CATCH(...){ + node_traits::set_next (last_to_remove, new_f); + node_traits::set_previous(new_f, last_to_remove); + BOOST_INTRUSIVE_RETHROW; + } + BOOST_INTRUSIVE_CATCH_END + node_traits::set_next(last_to_remove, new_f); + node_traits::set_previous(new_f, last_to_remove); + break; + } + } + info.num_1st_partition = num1; + info.num_2nd_partition = num2; + info.beg_2st_partition = new_f; + } + + private: + 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); + } + + 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)); + NodeTraits::set_next(other_node, temp); + } +}; + +/// @cond + +template +struct get_algo +{ + typedef circular_list_algorithms type; +}; + +/// @endcond + +} //namespace intrusive +} //namespace boost + +#include + +#endif //BOOST_INTRUSIVE_CIRCULAR_LIST_ALGORITHMS_HPP diff --git a/third_party/boost/libs/intrusive/include/boost/intrusive/circular_slist_algorithms.hpp b/third_party/boost/libs/intrusive/include/boost/intrusive/circular_slist_algorithms.hpp new file mode 100644 index 00000000000..5ce4e8cdba1 --- /dev/null +++ b/third_party/boost/libs/intrusive/include/boost/intrusive/circular_slist_algorithms.hpp @@ -0,0 +1,475 @@ +///////////////////////////////////////////////////////////////////////////// +// +// (C) Copyright Olaf Krzikalla 2004-2006. +// (C) Copyright Ion Gaztanaga 2006-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_CIRCULAR_SLIST_ALGORITHMS_HPP +#define BOOST_INTRUSIVE_CIRCULAR_SLIST_ALGORITHMS_HPP + +#include +#include +#include +#include +#include +#include + +#if defined(BOOST_HAS_PRAGMA_ONCE) +# pragma once +#endif + +namespace boost { +namespace intrusive { + +//! circular_slist_algorithms provides basic algorithms to manipulate nodes +//! forming a circular singly linked list. An empty circular list is formed by a node +//! whose pointer to the next node points to itself. +//! +//! circular_slist_algorithms is configured with a NodeTraits class, which encapsulates the +//! information about the node to be manipulated. NodeTraits must support the +//! following interface: +//! +//! Typedefs: +//! +//! node: The type of the node that forms the circular list +//! +//! node_ptr: A pointer to a node +//! +//! const_node_ptr: A pointer to a const node +//! +//! Static functions: +//! +//! static node_ptr get_next(const_node_ptr n); +//! +//! static void set_next(node_ptr n, node_ptr next); +template +class circular_slist_algorithms + /// @cond + : public detail::common_slist_algorithms + /// @endcond +{ + /// @cond + typedef detail::common_slist_algorithms base_t; + /// @endcond + public: + typedef typename NodeTraits::node node; + typedef typename NodeTraits::node_ptr node_ptr; + typedef typename NodeTraits::const_node_ptr const_node_ptr; + typedef NodeTraits node_traits; + + #if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED) + + //! Effects: Constructs an non-used list element, putting the next + //! pointer to null: + //! NodeTraits::get_next(this_node) == node_ptr() + //! + //! Complexity: Constant + //! + //! Throws: Nothing. + static void init(node_ptr this_node) BOOST_NOEXCEPT; + + //! Requires: this_node must be in a circular list or be an empty circular list. + //! + //! Effects: Returns true is "this_node" is the only node of a circular list: + //! or it's a not inserted node: + //! return node_ptr() == NodeTraits::get_next(this_node) || NodeTraits::get_next(this_node) == this_node + //! + //! Complexity: Constant + //! + //! Throws: Nothing. + 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)" + //! + //! Complexity: Constant + //! + //! Throws: Nothing. + 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. + //! + //! Effects: Unlinks the next node of prev_node from the circular list. + //! + //! Complexity: Constant + //! + //! Throws: Nothing. + 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. + //! + //! Effects: Unlinks the range (prev_node, last_node) from the circular list. + //! + //! Complexity: Constant + //! + //! Throws: Nothing. + 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. + //! + //! Effects: Links this_node after prev_node in the circular list. + //! + //! Complexity: Constant + //! + //! Throws: Nothing. + 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. + //! + //! Effects: Removes the nodes from (b, e] range from their circular list and inserts + //! them after p in p's circular list. + //! + //! Complexity: Constant + //! + //! Throws: Nothing. + 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) + + //! Effects: Constructs an empty list, making this_node the only + //! node of the circular list: + //! NodeTraits::get_next(this_node) == this_node. + //! + //! Complexity: Constant + //! + //! Throws: Nothing. + 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. + //! the search from prev_init_node. The first node checked for equality + //! is NodeTraits::get_next(prev_init_node). + //! + //! 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(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. + //! + //! Effects: Returns the previous node of this_node in the circular list. + //! + //! Complexity: Linear to the number of elements in the circular list. + //! + //! Throws: Nothing. + 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. + //! + //! Effects: Returns the previous node of the previous node of this_node in the circular list. + //! + //! Complexity: Linear to the number of elements in the circular list. + //! + //! Throws: Nothing. + 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. + //! + //! Effects: Returns the previous node of the previous node of this_node in the + //! circular list starting. the search from p. The first node checked + //! for equality is NodeTraits::get_next((NodeTraits::get_next(p)). + //! + //! Complexity: Linear to the number of elements in the circular list. + //! + //! Throws: Nothing. + 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); + while (this_node != p_next_next){ + p = p_next; + p_next = p_next_next; + p_next_next = NodeTraits::get_next(p_next); + } + return p; + } + + //! Requires: this_node must be in a circular list or be an empty circular list. + //! + //! Effects: Returns the number of nodes in a circular list. If the circular list + //! is empty, returns 1. + //! + //! Complexity: Linear + //! + //! Throws: Nothing. + static std::size_t count(const_node_ptr this_node) BOOST_NOEXCEPT + { + std::size_t result = 0; + const_node_ptr p = this_node; + do{ + p = NodeTraits::get_next(p); + ++result; + } while (p != this_node); + return result; + } + + //! Requires: this_node must be in a circular list, be an empty circular list or be inited. + //! + //! Effects: Unlinks the node from the circular list. + //! + //! Complexity: Linear to the number of elements in the circular list + //! + //! Throws: Nothing. + static void unlink(node_ptr this_node) BOOST_NOEXCEPT + { + if(NodeTraits::get_next(this_node)) + base_t::unlink_after(get_previous_node(this_node)); + } + + //! Requires: nxt_node must be a node of a circular list. + //! + //! Effects: Links this_node before nxt_node in the circular list. + //! + //! 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_NOEXCEPT + { base_t::link_after(get_previous_node(nxt_node), this_node); } + + //! Requires: this_node and other_node must be nodes inserted + //! in circular lists or be empty circular lists. + //! + //! Effects: Swaps the position of the nodes: this_node is inserted in + //! other_nodes position in the second circular list and the other_node is inserted + //! in this_node's position in the first circular list. + //! + //! Complexity: Linear to number of elements of both lists + //! + //! Throws: Nothing. + static void swap_nodes(node_ptr this_node, node_ptr other_node) BOOST_NOEXCEPT + { + if (other_node == this_node) + return; + const node_ptr this_next = NodeTraits::get_next(this_node); + const node_ptr other_next = NodeTraits::get_next(other_node); + const bool this_null = !this_next; + const bool other_null = !other_next; + const bool this_empty = this_next == this_node; + const bool other_empty = other_next == other_node; + + if(!(other_null || other_empty)){ + NodeTraits::set_next(this_next == other_node ? other_node : get_previous_node(other_node), this_node ); + } + if(!(this_null | this_empty)){ + NodeTraits::set_next(other_next == this_node ? this_node : get_previous_node(this_node), other_node ); + } + NodeTraits::set_next(this_node, other_empty ? this_node : (other_next == this_node ? other_node : other_next) ); + NodeTraits::set_next(other_node, this_empty ? other_node : (this_next == other_node ? this_node : this_next ) ); + } + + //! Effects: Reverses the order of elements in the list. + //! + //! Throws: Nothing. + //! + //! Complexity: This function is linear to the contained elements. + static void reverse(node_ptr p) BOOST_NOEXCEPT + { + node_ptr i = NodeTraits::get_next(p), e(p); + for (;;) { + node_ptr nxt(NodeTraits::get_next(i)); + if (nxt == e) + break; + base_t::transfer_after(e, i, nxt); + } + } + + //! Effects: Moves the node p n positions towards the end of the list. + //! + //! Returns: The previous node of p after the function if there has been any movement, + //! Null if n leads to no movement. + //! + //! 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) BOOST_NOEXCEPT + { + //Null shift, nothing to do + if(!n) return node_ptr(); + node_ptr first = NodeTraits::get_next(p); + + //count() == 1 or 2, nothing to do + if(NodeTraits::get_next(first) == p) + return node_ptr(); + + bool end_found = false; + node_ptr new_last = node_ptr(); + + //Now find the new last node according to the shift count. + //If we find p before finding the new last node + //unlink p, shortcut the search now that we know the size of the list + //and continue. + for(std::size_t i = 1; i <= n; ++i){ + new_last = first; + first = NodeTraits::get_next(first); + if(first == p){ + //Shortcut the shift with the modulo of the size of the list + n %= i; + if(!n) + return node_ptr(); + i = 0; + //Unlink p and continue the new first node search + first = NodeTraits::get_next(p); + base_t::unlink_after(new_last); + end_found = true; + } + } + + //If the p has not been found in the previous loop, find it + //starting in the new first node and unlink it + if(!end_found){ + base_t::unlink_after(base_t::get_previous_node(first, p)); + } + + //Now link p after the new last node + base_t::link_after(new_last, p); + return new_last; + } + + //! Effects: Moves the node p n positions towards the beginning of the list. + //! + //! Returns: The previous node of p after the function if there has been any movement, + //! Null if n leads equals to no movement. + //! + //! 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) BOOST_NOEXCEPT + { + //Null shift, nothing to do + if(!n) return node_ptr(); + node_ptr first = node_traits::get_next(p); + + //count() == 1 or 2, nothing to do + if(node_traits::get_next(first) == p) return node_ptr(); + + //Iterate until p is found to know where the current last node is. + //If the shift count is less than the size of the list, we can also obtain + //the position of the new last node after the shift. + node_ptr old_last(first), next_to_it, new_last(p); + std::size_t distance = 1; + while(p != (next_to_it = node_traits::get_next(old_last))){ + if(++distance > n) + new_last = node_traits::get_next(new_last); + old_last = next_to_it; + } + //If the shift was bigger or equal than the size, obtain the equivalent + //forward shifts and find the new last node. + if(distance <= n){ + //Now find the equivalent forward shifts. + //Shortcut the shift with the modulo of the size of the list + std::size_t new_before_last_pos = (distance - (n % distance))% distance; + //If the shift is a multiple of the size there is nothing to do + if(!new_before_last_pos) return node_ptr(); + + for( new_last = p + ; new_before_last_pos-- + ; new_last = node_traits::get_next(new_last)){ + //empty + } + } + + //Now unlink p and link it after the new last node + base_t::unlink_after(old_last); + 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 + +template +struct get_algo +{ + typedef circular_slist_algorithms type; +}; + +/// @endcond + +} //namespace intrusive +} //namespace boost + +#include + +#endif //BOOST_INTRUSIVE_CIRCULAR_SLIST_ALGORITHMS_HPP diff --git a/third_party/boost/libs/intrusive/include/boost/intrusive/derivation_value_traits.hpp b/third_party/boost/libs/intrusive/include/boost/intrusive/derivation_value_traits.hpp new file mode 100644 index 00000000000..626031257c5 --- /dev/null +++ b/third_party/boost/libs/intrusive/include/boost/intrusive/derivation_value_traits.hpp @@ -0,0 +1,77 @@ +///////////////////////////////////////////////////////////////////////////// +// +// (C) Copyright Ion Gaztanaga 2006-2013 +// +// 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_DERIVATION_VALUE_TRAITS_HPP +#define BOOST_INTRUSIVE_DERIVATION_VALUE_TRAITS_HPP + +#include +#include +#include +#include + +#if defined(BOOST_HAS_PRAGMA_ONCE) +# pragma once +#endif + +namespace boost { +namespace intrusive { + +//!This value traits template is used to create value traits +//!from user defined node traits where value_traits::value_type will +//!derive from node_traits::node + +template +struct derivation_value_traits +{ + public: + typedef NodeTraits node_traits; + typedef T value_type; + 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 typename pointer_traits:: + template rebind_pointer::type pointer; + typedef typename pointer_traits:: + template rebind_pointer::type const_pointer; + typedef typename boost::intrusive:: + pointer_traits::reference reference; + typedef typename boost::intrusive:: + pointer_traits::reference const_reference; + static const link_mode_type link_mode = LinkMode; + + BOOST_INTRUSIVE_FORCEINLINE static node_ptr to_node_ptr(reference value) BOOST_NOEXCEPT + { return node_ptr(&value); } + + BOOST_INTRUSIVE_FORCEINLINE static const_node_ptr to_node_ptr(const_reference value) BOOST_NOEXCEPT + { return node_ptr(&value); } + + BOOST_INTRUSIVE_FORCEINLINE static pointer to_value_ptr(node_ptr n) BOOST_NOEXCEPT + { + return pointer_traits::pointer_to(static_cast(*n)); + } + + BOOST_INTRUSIVE_FORCEINLINE static const_pointer to_value_ptr(const_node_ptr n) BOOST_NOEXCEPT + { + return pointer_traits::pointer_to(static_cast(*n)); + } +}; + +} //namespace intrusive +} //namespace boost + +#include + +#endif //BOOST_INTRUSIVE_DERIVATION_VALUE_TRAITS_HPP diff --git a/third_party/boost/libs/intrusive/include/boost/intrusive/detail/algo_type.hpp b/third_party/boost/libs/intrusive/include/boost/intrusive/detail/algo_type.hpp new file mode 100644 index 00000000000..70ec63f5740 --- /dev/null +++ b/third_party/boost/libs/intrusive/include/boost/intrusive/detail/algo_type.hpp @@ -0,0 +1,53 @@ +///////////////////////////////////////////////////////////////////////////// +// +// (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_ALGO_TYPE_HPP +#define BOOST_INTRUSIVE_DETAIL_ALGO_TYPE_HPP + +#ifndef BOOST_CONFIG_HPP +# include +#endif + +#if defined(BOOST_HAS_PRAGMA_ONCE) +# pragma once +#endif + +namespace boost { +namespace intrusive { + +enum algo_types +{ + CircularListAlgorithms, + CircularSListAlgorithms, + LinearSListAlgorithms, + CommonSListAlgorithms, + BsTreeAlgorithms, + RbTreeAlgorithms, + AvlTreeAlgorithms, + SgTreeAlgorithms, + SplayTreeAlgorithms, + TreapAlgorithms, + UnorderedAlgorithms, + UnorderedCircularSlistAlgorithms, + AnyAlgorithm +}; + +template +struct get_algo; + +template +struct get_node_checker; + +} //namespace intrusive +} //namespace boost + +#endif //BOOST_INTRUSIVE_DETAIL_ALGO_TYPE_HPP diff --git a/third_party/boost/libs/intrusive/include/boost/intrusive/detail/algorithm.hpp b/third_party/boost/libs/intrusive/include/boost/intrusive/detail/algorithm.hpp new file mode 100644 index 00000000000..d2421ffaad6 --- /dev/null +++ b/third_party/boost/libs/intrusive/include/boost/intrusive/detail/algorithm.hpp @@ -0,0 +1,90 @@ +////////////////////////////////////////////////////////////////////////////// +// +// (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_ALGORITHM_HPP +#define BOOST_INTRUSIVE_DETAIL_ALGORITHM_HPP + +#ifndef BOOST_CONFIG_HPP +# include +#endif + +#if defined(BOOST_HAS_PRAGMA_ONCE) +# pragma once +#endif + +namespace boost { +namespace intrusive { + +struct algo_pred_equal +{ + template + bool operator()(const T &x, const T &y) const + { return x == y; } +}; + +struct algo_pred_less +{ + template + bool operator()(const T &x, const T &y) const + { return x < y; } +}; + +template +bool algo_equal(InputIt1 first1, InputIt1 last1, InputIt2 first2, BinaryPredicate p) +{ + for (; first1 != last1; ++first1, ++first2) { + if (!p(*first1, *first2)) { + return false; + } + } + return true; +} + +template +bool algo_equal(InputIt1 first1, InputIt1 last1, InputIt2 first2) +{ return (algo_equal)(first1, last1, first2, algo_pred_equal()); } + +template +bool algo_equal(InputIt1 first1, InputIt1 last1, InputIt2 first2, InputIt2 last2, BinaryPredicate pred) +{ + for (; first1 != last1 && first2 != last2; ++first1, ++first2) + if (!pred(*first1, *first2)) + return false; + return first1 == last1 && first2 == last2; +} + +template +bool algo_equal(InputIt1 first1, InputIt1 last1, InputIt2 first2, InputIt2 last2) +{ return (algo_equal)(first1, last1, first2, last2, algo_pred_equal()); } + +template + bool algo_lexicographical_compare (InputIterator1 first1, InputIterator1 last1, + InputIterator2 first2, InputIterator2 last2, + BinaryPredicate pred) +{ + while (first1 != last1){ + if (first2 == last2 || *first2 < *first1) return false; + else if (pred(*first1, *first2)) return true; + ++first1; ++first2; + } + return (first2 != last2); +} + +template + bool algo_lexicographical_compare (InputIterator1 first1, InputIterator1 last1, + InputIterator2 first2, InputIterator2 last2) +{ return (algo_lexicographical_compare)(first1, last1, first2, last2, algo_pred_less()); } + +} //namespace intrusive { +} //namespace boost { + +#endif //#ifndef BOOST_INTRUSIVE_DETAIL_ALGORITHM_HPP diff --git a/third_party/boost/libs/intrusive/include/boost/intrusive/detail/any_node_and_algorithms.hpp b/third_party/boost/libs/intrusive/include/boost/intrusive/detail/any_node_and_algorithms.hpp new file mode 100644 index 00000000000..7949eecdb7a --- /dev/null +++ b/third_party/boost/libs/intrusive/include/boost/intrusive/detail/any_node_and_algorithms.hpp @@ -0,0 +1,297 @@ +///////////////////////////////////////////////////////////////////////////// +// +// (C) Copyright Ion Gaztanaga 2006-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_ANY_NODE_HPP +#define BOOST_INTRUSIVE_ANY_NODE_HPP + +#ifndef BOOST_CONFIG_HPP +# include +#endif + +#if defined(BOOST_HAS_PRAGMA_ONCE) +# pragma once +#endif + +#include +#include +#include +#include +#include + +namespace boost { +namespace intrusive { + +template +struct any_node +{ + typedef any_node node; + typedef typename pointer_rebind::type node_ptr; + typedef typename pointer_rebind::type const_node_ptr; + node_ptr node_ptr_1; + node_ptr node_ptr_2; + node_ptr node_ptr_3; + std::size_t size_t_1; +}; + +template +struct any_list_node_traits +{ + typedef any_node node; + 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_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_node_ptr n) + { return n->node_ptr_2; } + + BOOST_INTRUSIVE_FORCEINLINE static void set_previous(node_ptr n, node_ptr prev) + { n->node_ptr_2 = prev; } +}; + + +template +struct any_slist_node_traits +{ + typedef any_node node; + 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_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; } +}; + + +template +struct any_unordered_node_traits + : public any_slist_node_traits +{ + typedef any_slist_node_traits reduced_slist_node_traits; + typedef typename reduced_slist_node_traits::node node; + typedef typename reduced_slist_node_traits::node_ptr node_ptr; + typedef typename reduced_slist_node_traits::const_node_ptr const_node_ptr; + + static const bool store_hash = true; + static const bool optimize_multikey = true; + + 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_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_node_ptr n) + { return n->size_t_1; } + + BOOST_INTRUSIVE_FORCEINLINE static void set_hash(node_ptr n, std::size_t h) + { n->size_t_1 = h; } +}; + + +template +struct any_rbtree_node_traits +{ + typedef any_node node; + typedef typename node::node_ptr node_ptr; + typedef typename node::const_node_ptr const_node_ptr; + + typedef std::size_t color; + + 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_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_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_node_ptr n) + { return n->size_t_1; } + + BOOST_INTRUSIVE_FORCEINLINE static void set_color(node_ptr n, color c) + { n->size_t_1 = c; } + + BOOST_INTRUSIVE_FORCEINLINE static color black() + { return 0u; } + + BOOST_INTRUSIVE_FORCEINLINE static color red() + { return 1u; } +}; + + +template +struct any_avltree_node_traits +{ + typedef any_node node; + typedef typename node::node_ptr node_ptr; + typedef typename node::const_node_ptr const_node_ptr; + + typedef std::size_t balance; + + 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_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_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_node_ptr n) + { return n->size_t_1; } + + BOOST_INTRUSIVE_FORCEINLINE static void set_balance(node_ptr n, balance b) + { n->size_t_1 = b; } + + BOOST_INTRUSIVE_FORCEINLINE static balance negative() + { return 0u; } + + BOOST_INTRUSIVE_FORCEINLINE static balance zero() + { return 1u; } + + BOOST_INTRUSIVE_FORCEINLINE static balance positive() + { return 2u; } +}; + + +template +struct any_tree_node_traits +{ + typedef any_node node; + 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_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_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_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; } +}; + +template +class any_node_traits +{ + public: + typedef any_node node; + typedef typename node::node_ptr node_ptr; + typedef typename node::const_node_ptr const_node_ptr; +}; + +template +class any_algorithms +{ + template + static void function_not_available_for_any_hooks(typename detail::enable_if >::type) + {} + + public: + typedef any_node node; + typedef typename node::node_ptr node_ptr; + typedef typename node::const_node_ptr const_node_ptr; + typedef any_node_traits node_traits; + + //! Requires: 'n' must not be part of any tree. + //! + //! Effects: After the function unique(node) == true. + //! + //! Complexity: Constant. + //! + //! Throws: Nothing. + //! + //! Nodes: If node is inserted in a tree, this function corrupts the tree. + BOOST_INTRUSIVE_FORCEINLINE static void init(node_ptr n) BOOST_NOEXCEPT + { n->node_ptr_1 = node_ptr(); }; + + //! 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_node_ptr n) + { return !n->node_ptr_1; }; + + BOOST_INTRUSIVE_FORCEINLINE static bool unique(const_node_ptr n) BOOST_NOEXCEPT + { return !n->node_ptr_1; } + + 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(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 + any_algorithms::template function_not_available_for_any_hooks(); + } +}; + +///@cond + +template +struct get_algo +{ + typedef typename pointer_rebind::type void_pointer; + typedef any_algorithms type; +}; + +///@endcond + +} //namespace intrusive +} //namespace boost + +#endif //BOOST_INTRUSIVE_ANY_NODE_HPP diff --git a/third_party/boost/libs/intrusive/include/boost/intrusive/detail/array_initializer.hpp b/third_party/boost/libs/intrusive/include/boost/intrusive/detail/array_initializer.hpp new file mode 100644 index 00000000000..554edadfa4c --- /dev/null +++ b/third_party/boost/libs/intrusive/include/boost/intrusive/detail/array_initializer.hpp @@ -0,0 +1,97 @@ +///////////////////////////////////////////////////////////////////////////// +// +// (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_ARRAY_INITIALIZER_HPP +#define BOOST_INTRUSIVE_DETAIL_ARRAY_INITIALIZER_HPP + +#ifndef BOOST_CONFIG_HPP +# include +#endif + +#if defined(BOOST_HAS_PRAGMA_ONCE) +# pragma once +#endif + +#include +#include +#include +#include + +namespace boost { +namespace intrusive { +namespace detail { + +//This is not standard, but should work with all compilers +union max_align +{ + char char_; + short short_; + int int_; + long long_; + #ifdef BOOST_HAS_LONG_LONG + ::boost::long_long_type long_long_; + #endif + float float_; + double double_; + long double long_double_; + void * void_ptr_; +}; + +template +class array_initializer +{ + public: + template + array_initializer(const CommonInitializer &init) + { + char *init_buf = (char*)rawbuf; + std::size_t i = 0; + BOOST_INTRUSIVE_TRY{ + for(; i != N; ++i){ + ::new(init_buf, boost_move_new_t()) T(init); + init_buf += sizeof(T); + } + } + BOOST_INTRUSIVE_CATCH(...){ + while(i--){ + init_buf -= sizeof(T); + move_detail::force_ptr(init_buf)->~T(); + } + BOOST_INTRUSIVE_RETHROW; + } + BOOST_INTRUSIVE_CATCH_END + } + + operator T* () + { return (T*)(rawbuf); } + + operator const T*() const + { return (const T*)(rawbuf); } + + ~array_initializer() + { + char *init_buf = (char*)rawbuf + N*sizeof(T); + for(std::size_t i = 0; i != N; ++i){ + init_buf -= sizeof(T); + move_detail::force_ptr(init_buf)->~T(); + } + } + + private: + detail::max_align rawbuf[(N*sizeof(T)-1)/sizeof(detail::max_align)+1]; +}; + +} //namespace detail{ +} //namespace intrusive{ +} //namespace boost{ + +#endif //BOOST_INTRUSIVE_DETAIL_ARRAY_INITIALIZER_HPP diff --git a/third_party/boost/libs/intrusive/include/boost/intrusive/detail/assert.hpp b/third_party/boost/libs/intrusive/include/boost/intrusive/detail/assert.hpp new file mode 100644 index 00000000000..7199eb240c9 --- /dev/null +++ b/third_party/boost/libs/intrusive/include/boost/intrusive/detail/assert.hpp @@ -0,0 +1,45 @@ +///////////////////////////////////////////////////////////////////////////// +// +// (C) Copyright Ion Gaztanaga 2006-2013 +// +// 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_ASSERT_HPP +#define BOOST_INTRUSIVE_DETAIL_ASSERT_HPP + +#ifndef BOOST_CONFIG_HPP +# include +#endif + +#if defined(BOOST_HAS_PRAGMA_ONCE) +#pragma once +#endif + +#if !defined(BOOST_INTRUSIVE_INVARIANT_ASSERT) + #include + #define BOOST_INTRUSIVE_INVARIANT_ASSERT BOOST_ASSERT +#elif defined(BOOST_INTRUSIVE_INVARIANT_ASSERT_INCLUDE) + #include BOOST_INTRUSIVE_INVARIANT_ASSERT_INCLUDE +#endif + +#if !defined(BOOST_INTRUSIVE_SAFE_HOOK_DEFAULT_ASSERT) + #include + #define BOOST_INTRUSIVE_SAFE_HOOK_DEFAULT_ASSERT BOOST_ASSERT +#elif defined(BOOST_INTRUSIVE_SAFE_HOOK_DEFAULT_ASSERT_INCLUDE) + #include BOOST_INTRUSIVE_SAFE_HOOK_DEFAULT_ASSERT_INCLUDE +#endif + +#if !defined(BOOST_INTRUSIVE_SAFE_HOOK_DESTRUCTOR_ASSERT) + #include + #define BOOST_INTRUSIVE_SAFE_HOOK_DESTRUCTOR_ASSERT BOOST_ASSERT +#elif defined(BOOST_INTRUSIVE_SAFE_HOOK_DESTRUCTOR_ASSERT_INCLUDE) + #include BOOST_INTRUSIVE_SAFE_HOOK_DESTRUCTOR_ASSERT_INCLUDE +#endif + +#endif //BOOST_INTRUSIVE_DETAIL_ASSERT_HPP diff --git a/third_party/boost/libs/intrusive/include/boost/intrusive/detail/avltree_node.hpp b/third_party/boost/libs/intrusive/include/boost/intrusive/detail/avltree_node.hpp new file mode 100644 index 00000000000..b9c52dcaab9 --- /dev/null +++ b/third_party/boost/libs/intrusive/include/boost/intrusive/detail/avltree_node.hpp @@ -0,0 +1,193 @@ +///////////////////////////////////////////////////////////////////////////// +// +// (C) Copyright Ion Gaztanaga 2007-2013 +// +// 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_AVLTREE_NODE_HPP +#define BOOST_INTRUSIVE_AVLTREE_NODE_HPP + +#ifndef BOOST_CONFIG_HPP +# include +#endif + +#if defined(BOOST_HAS_PRAGMA_ONCE) +# pragma once +#endif + +#include +#include +#include +#include +#include +#include + +namespace boost { +namespace intrusive { + +///////////////////////////////////////////////////////////////////////////// +// // +// Generic node_traits for any pointer type // +// // +///////////////////////////////////////////////////////////////////////////// + +//This is the compact representation: 3 pointers +template +struct compact_avltree_node +{ + typedef typename pointer_rebind >::type node_ptr; + typedef typename pointer_rebind >::type const_node_ptr; + enum balance { negative_t, zero_t, positive_t }; + node_ptr parent_, left_, right_; +}; + +//This is the normal representation: 3 pointers + enum +template +struct avltree_node +{ + typedef typename pointer_rebind >::type node_ptr; + typedef typename pointer_rebind >::type const_node_ptr; + enum balance { negative_t, zero_t, positive_t }; + node_ptr parent_, left_, right_; + balance balance_; +}; + +//This is the default node traits implementation +//using a node with 3 generic pointers plus an enum +template +struct default_avltree_node_traits_impl +{ + typedef avltree_node node; + typedef typename node::node_ptr node_ptr; + typedef typename node::const_node_ptr const_node_ptr; + + typedef typename node::balance balance; + + BOOST_INTRUSIVE_FORCEINLINE static node_ptr get_parent(const_node_ptr n) + { return n->parent_; } + + 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_node_ptr n) + { return n->left_; } + + 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_node_ptr n) + { return n->right_; } + + 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_node_ptr n) + { return n->balance_; } + + BOOST_INTRUSIVE_FORCEINLINE static balance get_balance(node_ptr n) + { return n->balance_; } + + BOOST_INTRUSIVE_FORCEINLINE static void set_balance(node_ptr n, balance b) + { n->balance_ = b; } + + BOOST_INTRUSIVE_FORCEINLINE static balance negative() + { return node::negative_t; } + + BOOST_INTRUSIVE_FORCEINLINE static balance zero() + { return node::zero_t; } + + BOOST_INTRUSIVE_FORCEINLINE static balance positive() + { return node::positive_t; } +}; + +//This is the compact node traits implementation +//using a node with 3 generic pointers +template +struct compact_avltree_node_traits_impl +{ + typedef compact_avltree_node node; + typedef typename node::node_ptr node_ptr; + typedef typename node::const_node_ptr const_node_ptr; + typedef typename node::balance balance; + + typedef pointer_plus_bits ptr_bit; + + 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_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_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_node_ptr n) + { return (balance)ptr_bit::get_bits(n->parent_); } + + 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() + { return node::negative_t; } + + BOOST_INTRUSIVE_FORCEINLINE static balance zero() + { return node::zero_t; } + + BOOST_INTRUSIVE_FORCEINLINE static balance positive() + { return node::positive_t; } +}; + +//Dispatches the implementation based on the boolean +template +struct avltree_node_traits_dispatch + : public default_avltree_node_traits_impl +{}; + +template +struct avltree_node_traits_dispatch + : public compact_avltree_node_traits_impl +{}; + +//Inherit from rbtree_node_traits_dispatch depending on the embedding capabilities +template +struct avltree_node_traits + : public avltree_node_traits_dispatch + < VoidPointer + , OptimizeSize && + max_pointer_plus_bits + < VoidPointer + , detail::alignment_of >::value + >::value >= 2u + > +{}; + +} //namespace intrusive +} //namespace boost + +#include + +#endif //BOOST_INTRUSIVE_AVLTREE_NODE_HPP diff --git a/third_party/boost/libs/intrusive/include/boost/intrusive/detail/bstree_algorithms_base.hpp b/third_party/boost/libs/intrusive/include/boost/intrusive/detail/bstree_algorithms_base.hpp new file mode 100644 index 00000000000..1dbd491ed92 --- /dev/null +++ b/third_party/boost/libs/intrusive/include/boost/intrusive/detail/bstree_algorithms_base.hpp @@ -0,0 +1,182 @@ +///////////////////////////////////////////////////////////////////////////// +// +// (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_BSTREE_ALGORITHMS_BASE_HPP +#define BOOST_INTRUSIVE_BSTREE_ALGORITHMS_BASE_HPP + +#ifndef BOOST_CONFIG_HPP +# include +#endif + +#if defined(BOOST_HAS_PRAGMA_ONCE) +# pragma once +#endif + +#include + +namespace boost { +namespace intrusive { + +template +class bstree_algorithms_base +{ + public: + typedef typename NodeTraits::node node; + typedef NodeTraits node_traits; + typedef typename NodeTraits::node_ptr node_ptr; + typedef typename NodeTraits::const_node_ptr const_node_ptr; + + //! 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(node_ptr n) BOOST_NOEXCEPT + { + node_ptr const n_right(NodeTraits::get_right(n)); + if(n_right){ + return minimum(n_right); + } + else { + node_ptr p(NodeTraits::get_parent(n)); + while(n == NodeTraits::get_right(p)){ + n = p; + p = NodeTraits::get_parent(p); + } + return NodeTraits::get_right(n) != p ? p : n; + } + } + + //! 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(node_ptr n) BOOST_NOEXCEPT + { + if(is_header(n)){ + return NodeTraits::get_right(n); + } + else if(NodeTraits::get_left(n)){ + return maximum(NodeTraits::get_left(n)); + } + else { + node_ptr p(n); + node_ptr x = NodeTraits::get_parent(p); + while(p == NodeTraits::get_left(x)){ + p = x; + x = NodeTraits::get_parent(x); + } + return x; + } + } + + //! 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 n) + { + for(node_ptr p_left = NodeTraits::get_left(n) + ;p_left + ;p_left = NodeTraits::get_left(n)){ + n = p_left; + } + return n; + } + + //! 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 n) + { + for(node_ptr p_right = NodeTraits::get_right(n) + ;p_right + ;p_right = NodeTraits::get_right(n)){ + n = p_right; + } + return n; + } + + //! Requires: p is a node of a tree. + //! + //! Effects: Returns true if p is the header of the tree. + //! + //! Complexity: Constant. + //! + //! Throws: Nothing. + 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)); + if(!NodeTraits::get_parent(p) || //Header condition when empty tree + (p_left && p_right && //Header always has leftmost and rightmost + (p_left == p_right || //Header condition when only node + (NodeTraits::get_parent(p_left) != p || + NodeTraits::get_parent(p_right) != p )) + //When tree size > 1 headers can't be leftmost's + //and rightmost's parent + )){ + return true; + } + return false; + } + + //! 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_node_ptr n) + { + 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 nn is neither root nor header + node_ptr pp(NodeTraits::get_parent(p)); + //If granparent is not equal to nn, then nn is neither root nor header, + //the try the fast path + if(nn != pp){ + do{ + nn = p; + p = pp; + pp = NodeTraits::get_parent(pp); + }while(nn != pp); + nn = p; + } + //Check if nn is root or header when size() > 0 + else if(!bstree_algorithms_base::is_header(nn)){ + nn = p; + } + } + return nn; + } +}; + +} //namespace intrusive +} //namespace boost + +#endif //BOOST_INTRUSIVE_BSTREE_ALGORITHMS_BASE_HPP diff --git a/third_party/boost/libs/intrusive/include/boost/intrusive/detail/common_slist_algorithms.hpp b/third_party/boost/libs/intrusive/include/boost/intrusive/detail/common_slist_algorithms.hpp new file mode 100644 index 00000000000..8310231e319 --- /dev/null +++ b/third_party/boost/libs/intrusive/include/boost/intrusive/detail/common_slist_algorithms.hpp @@ -0,0 +1,267 @@ +///////////////////////////////////////////////////////////////////////////// +// +// (C) Copyright Ion Gaztanaga 2007-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_COMMON_SLIST_ALGORITHMS_HPP +#define BOOST_INTRUSIVE_COMMON_SLIST_ALGORITHMS_HPP + +#ifndef BOOST_CONFIG_HPP +# include +#endif + +#if defined(BOOST_HAS_PRAGMA_ONCE) +# pragma once +#endif + +#include +#include +#include +#include +#include + +namespace boost { +namespace intrusive { +namespace detail { + +template +class common_slist_algorithms +{ + public: + typedef typename NodeTraits::node node; + typedef typename NodeTraits::node_ptr node_ptr; + typedef typename NodeTraits::const_node_ptr const_node_ptr; + typedef NodeTraits node_traits; + + 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)) + ; p = p_next){ + //Logic error: possible use of linear lists with + //operations only permitted with circular lists + BOOST_INTRUSIVE_INVARIANT_ASSERT(p); + } + return p; + } + + BOOST_INTRUSIVE_FORCEINLINE static void init(node_ptr this_node) BOOST_NOEXCEPT + { NodeTraits::set_next(this_node, node_ptr()); } + + 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_node_ptr this_node) BOOST_NOEXCEPT + { return !NodeTraits::get_next(this_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_NOEXCEPT + { NodeTraits::set_next(prev_node, last_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); + } + + 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) BOOST_NOEXCEPT + { + if (bp != bb && bp != be && bb != be) { + node_ptr next_b = NodeTraits::get_next(bb); + node_ptr next_e = NodeTraits::get_next(be); + node_ptr next_p = NodeTraits::get_next(bp); + NodeTraits::set_next(bb, next_e); + NodeTraits::set_next(be, next_p); + NodeTraits::set_next(bp, next_b); + } + } + + struct stable_partition_info + { + std::size_t num_1st_partition; + std::size_t num_2nd_partition; + node_ptr beg_2st_partition; + node_ptr new_last_node; + }; + + template + static void stable_partition(node_ptr before_beg, node_ptr end, Pred pred, stable_partition_info &info) + { + node_ptr bcur = before_beg; + node_ptr cur = node_traits::get_next(bcur); + node_ptr new_f = end; + + std::size_t num1 = 0, num2 = 0; + while(cur != end){ + if(pred(cur)){ + ++num1; + bcur = cur; + cur = node_traits::get_next(cur); + } + else{ + ++num2; + node_ptr last_to_remove = bcur; + new_f = cur; + bcur = cur; + cur = node_traits::get_next(cur); + BOOST_INTRUSIVE_TRY{ + //Main loop + while(cur != end){ + if(pred(cur)){ //Might throw + ++num1; + //Process current node + node_traits::set_next(last_to_remove, cur); + last_to_remove = cur; + node_ptr nxt = node_traits::get_next(cur); + node_traits::set_next(bcur, nxt); + cur = nxt; + } + else{ + ++num2; + bcur = cur; + cur = node_traits::get_next(cur); + } + } + } + BOOST_INTRUSIVE_CATCH(...){ + node_traits::set_next(last_to_remove, new_f); + BOOST_INTRUSIVE_RETHROW; + } + BOOST_INTRUSIVE_CATCH_END + node_traits::set_next(last_to_remove, new_f); + break; + } + } + info.num_1st_partition = num1; + info.num_2nd_partition = num2; + info.beg_2st_partition = new_f; + info.new_last_node = bcur; + } + + //! Requires: f and l must be in a circular list. + //! + //! Effects: Returns the number of nodes in the range [f, l). + //! + //! Complexity: Linear + //! + //! Throws: Nothing. + 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); + ++result; + } + 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 + +} //namespace detail + +/// @cond + +template +struct get_algo +{ + typedef detail::common_slist_algorithms type; +}; + + +} //namespace intrusive +} //namespace boost + +#endif //BOOST_INTRUSIVE_COMMON_SLIST_ALGORITHMS_HPP diff --git a/third_party/boost/libs/intrusive/include/boost/intrusive/detail/config_begin.hpp b/third_party/boost/libs/intrusive/include/boost/intrusive/detail/config_begin.hpp new file mode 100644 index 00000000000..b261ca91d3d --- /dev/null +++ b/third_party/boost/libs/intrusive/include/boost/intrusive/detail/config_begin.hpp @@ -0,0 +1,44 @@ +///////////////////////////////////////////////////////////////////////////// +// +// (C) Copyright Ion Gaztanaga 2006-2013 +// +// 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 + +#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 + #pragma warning (disable : 4996) // "function": was declared deprecated + #pragma warning (disable : 4503) // "identifier" : decorated name length exceeded, name was truncated + #pragma warning (disable : 4284) // odd return type for operator-> + #pragma warning (disable : 4244) // possible loss of data + #pragma warning (disable : 4521) ////Disable "multiple copy constructors specified" + #pragma warning (disable : 4127) //conditional expression is constant + #pragma warning (disable : 4146) // unary minus operator applied to unsigned type, result still unsigned + #pragma warning (disable : 4267) //conversion from 'X' to 'Y', possible loss of data + #pragma warning (disable : 4541) //'typeid' used on polymorphic type 'boost::exception' with /GR- + #pragma warning (disable : 4512) //'typeid' used on polymorphic type 'boost::exception' with /GR- + #pragma warning (disable : 4522) // "class" : multiple assignment operators specified + #pragma warning (disable : 4706) //assignment within conditional expression + #pragma warning (disable : 4710) // function not inlined + #pragma warning (disable : 4714) // "function": marked as __forceinline not inlined + #pragma warning (disable : 4711) // function selected for automatic inline expansion + #pragma warning (disable : 4786) // identifier truncated in debug info + #pragma warning (disable : 4996) // "function": was declared deprecated +#endif + +//#define BOOST_INTRUSIVE_USE_ITERATOR_FACADE +//#define BOOST_INTRUSIVE_USE_ITERATOR_ENABLE_IF_CONVERTIBLE diff --git a/third_party/boost/libs/intrusive/include/boost/intrusive/detail/config_end.hpp b/third_party/boost/libs/intrusive/include/boost/intrusive/detail/config_end.hpp new file mode 100644 index 00000000000..a081443e69e --- /dev/null +++ b/third_party/boost/libs/intrusive/include/boost/intrusive/detail/config_end.hpp @@ -0,0 +1,15 @@ +///////////////////////////////////////////////////////////////////////////// +// +// (C) Copyright Ion Gaztanaga 2006-2013 +// +// 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. +// +///////////////////////////////////////////////////////////////////////////// + +#if defined BOOST_MSVC + #pragma warning (pop) +#endif diff --git a/third_party/boost/libs/intrusive/include/boost/intrusive/detail/default_header_holder.hpp b/third_party/boost/libs/intrusive/include/boost/intrusive/detail/default_header_holder.hpp new file mode 100644 index 00000000000..42f35d2be73 --- /dev/null +++ b/third_party/boost/libs/intrusive/include/boost/intrusive/detail/default_header_holder.hpp @@ -0,0 +1,70 @@ +///////////////////////////////////////////////////////////////////////////// +// +// (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_DEFAULT_HEADER_HOLDER_HPP +#define BOOST_INTRUSIVE_DETAIL_DEFAULT_HEADER_HOLDER_HPP + +#ifndef BOOST_CONFIG_HPP +# include +#endif + +#if defined(BOOST_HAS_PRAGMA_ONCE) +# pragma once +#endif + +#include +#include +#include + +namespace boost { +namespace intrusive { +namespace detail { + +// trivial header node holder +template < typename NodeTraits > +struct default_header_holder : public NodeTraits::node +{ + typedef NodeTraits 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; + + default_header_holder() : node() {} + + BOOST_INTRUSIVE_FORCEINLINE const_node_ptr get_node() const + { return pointer_traits< const_node_ptr >::pointer_to(*static_cast< const node* >(this)); } + + BOOST_INTRUSIVE_FORCEINLINE node_ptr get_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(node_ptr p) + { return static_cast< default_header_holder* >(boost::movelib::to_raw_pointer(p)); } +}; + +// type function producing the header node holder +template < typename ValueTraits, typename HeaderHolder > +struct get_header_holder_type +{ + typedef HeaderHolder type; +}; +template < typename ValueTraits > +struct get_header_holder_type< ValueTraits, void > +{ + typedef default_header_holder< typename ValueTraits::node_traits > type; +}; + +} //namespace detail +} //namespace intrusive +} //namespace boost + +#endif //BOOST_INTRUSIVE_DETAIL_DEFAULT_HEADER_HOLDER_HPP diff --git a/third_party/boost/libs/intrusive/include/boost/intrusive/detail/ebo_functor_holder.hpp b/third_party/boost/libs/intrusive/include/boost/intrusive/detail/ebo_functor_holder.hpp new file mode 100644 index 00000000000..88831667838 --- /dev/null +++ b/third_party/boost/libs/intrusive/include/boost/intrusive/detail/ebo_functor_holder.hpp @@ -0,0 +1,292 @@ +///////////////////////////////////////////////////////////////////////////// +// +// (C) Copyright Joaquin M Lopez Munoz 2006-2013 +// (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_EBO_HOLDER_HPP +#define BOOST_INTRUSIVE_DETAIL_EBO_HOLDER_HPP + +#ifndef BOOST_CONFIG_HPP +# include +#endif + +#if defined(BOOST_HAS_PRAGMA_ONCE) +# pragma once +#endif + +#include +#include + +namespace boost { +namespace intrusive { +namespace detail { + +#if defined(BOOST_MSVC) || defined(__BORLANDC_) +#define BOOST_INTRUSIVE_TT_DECL __cdecl +#else +#define BOOST_INTRUSIVE_TT_DECL +#endif + +#if defined(_MSC_EXTENSIONS) && !defined(__BORLAND__) && !defined(_WIN64) && !defined(_M_ARM) && !defined(_M_ARM64) && !defined(UNDER_CE) +#define BOOST_INTRUSIVE_TT_TEST_MSC_FUNC_SIGS +#endif + +template +struct is_unary_or_binary_function_impl +{ static const bool value = false; }; + +// see boost ticket #4094 +// avoid duplicate definitions of is_unary_or_binary_function_impl +#ifndef BOOST_INTRUSIVE_TT_TEST_MSC_FUNC_SIGS + +template +struct is_unary_or_binary_function_impl +{ static const bool value = true; }; + +template +struct is_unary_or_binary_function_impl +{ static const bool value = true; }; + +#else // BOOST_INTRUSIVE_TT_TEST_MSC_FUNC_SIGS + +template +struct is_unary_or_binary_function_impl +{ static const bool value = true; }; + +#ifndef _MANAGED + +template +struct is_unary_or_binary_function_impl +{ static const bool value = true; }; + +#endif + +template +struct is_unary_or_binary_function_impl +{ static const bool value = true; }; + +template +struct is_unary_or_binary_function_impl +{ static const bool value = true; }; + +#endif + +// see boost ticket #4094 +// avoid duplicate definitions of is_unary_or_binary_function_impl +#ifndef BOOST_INTRUSIVE_TT_TEST_MSC_FUNC_SIGS + +template +struct is_unary_or_binary_function_impl +{ static const bool value = true; }; + +template +struct is_unary_or_binary_function_impl +{ static const bool value = true; }; + +#else // BOOST_INTRUSIVE_TT_TEST_MSC_FUNC_SIGS + +template +struct is_unary_or_binary_function_impl +{ static const bool value = true; }; + +#ifndef _MANAGED + +template +struct is_unary_or_binary_function_impl +{ static const bool value = true; }; + +#endif + +template +struct is_unary_or_binary_function_impl +{ static const bool value = true; }; + +template +struct is_unary_or_binary_function_impl +{ static const bool value = true; }; + +#endif + +// see boost ticket #4094 +// avoid duplicate definitions of is_unary_or_binary_function_impl +#ifndef BOOST_INTRUSIVE_TT_TEST_MSC_FUNC_SIGS + +template +struct is_unary_or_binary_function_impl +{ static const bool value = true; }; + +template +struct is_unary_or_binary_function_impl +{ static const bool value = true; }; + +#else // BOOST_INTRUSIVE_TT_TEST_MSC_FUNC_SIGS + +template +struct is_unary_or_binary_function_impl +{ static const bool value = true; }; + +#ifndef _MANAGED + +template +struct is_unary_or_binary_function_impl +{ static const bool value = true; }; + +#endif + +template +struct is_unary_or_binary_function_impl +{ static const bool value = true; }; + +template +struct is_unary_or_binary_function_impl +{ static const bool value = true; }; +#endif + +template +struct is_unary_or_binary_function_impl +{ static const bool value = false; }; + +template +struct is_unary_or_binary_function : is_unary_or_binary_function_impl +{}; + +template::value> +class ebo_functor_holder +{ + BOOST_COPYABLE_AND_MOVABLE(ebo_functor_holder) + + public: + typedef T functor_type; + + BOOST_INTRUSIVE_FORCEINLINE ebo_functor_holder() + : t_() + {} + + BOOST_INTRUSIVE_FORCEINLINE explicit ebo_functor_holder(const T &t) + : t_(t) + {} + + BOOST_INTRUSIVE_FORCEINLINE explicit ebo_functor_holder(BOOST_RV_REF(T) t) + : t_(::boost::move(t)) + {} + + template + BOOST_INTRUSIVE_FORCEINLINE ebo_functor_holder(BOOST_FWD_REF(Arg1) arg1, BOOST_FWD_REF(Arg2) arg2) + : t_(::boost::forward(arg1), ::boost::forward(arg2)) + {} + + BOOST_INTRUSIVE_FORCEINLINE ebo_functor_holder(const ebo_functor_holder &x) + : t_(x.t_) + {} + + BOOST_INTRUSIVE_FORCEINLINE ebo_functor_holder(BOOST_RV_REF(ebo_functor_holder) x) + : t_(x.t_) + {} + + BOOST_INTRUSIVE_FORCEINLINE ebo_functor_holder& operator=(BOOST_COPY_ASSIGN_REF(ebo_functor_holder) x) + { + this->get() = x.get(); + return *this; + } + + BOOST_INTRUSIVE_FORCEINLINE ebo_functor_holder& operator=(BOOST_RV_REF(ebo_functor_holder) x) + { + this->get() = ::boost::move(x.get()); + return *this; + } + + BOOST_INTRUSIVE_FORCEINLINE ebo_functor_holder& operator=(const T &x) + { + this->get() = x; + return *this; + } + + BOOST_INTRUSIVE_FORCEINLINE ebo_functor_holder& operator=(BOOST_RV_REF(T) x) + { + this->get() = ::boost::move(x); + return *this; + } + + BOOST_INTRUSIVE_FORCEINLINE T& get(){return t_;} + BOOST_INTRUSIVE_FORCEINLINE const T& get()const{return t_;} + + private: + T t_; +}; + +template +class ebo_functor_holder + : public T +{ + BOOST_COPYABLE_AND_MOVABLE(ebo_functor_holder) + + public: + typedef T functor_type; + + BOOST_INTRUSIVE_FORCEINLINE ebo_functor_holder() + : T() + {} + + BOOST_INTRUSIVE_FORCEINLINE explicit ebo_functor_holder(const T &t) + : T(t) + {} + + BOOST_INTRUSIVE_FORCEINLINE explicit ebo_functor_holder(BOOST_RV_REF(T) t) + : T(::boost::move(t)) + {} + + template + BOOST_INTRUSIVE_FORCEINLINE ebo_functor_holder(BOOST_FWD_REF(Arg1) arg1, BOOST_FWD_REF(Arg2) arg2) + : T(::boost::forward(arg1), ::boost::forward(arg2)) + {} + + BOOST_INTRUSIVE_FORCEINLINE ebo_functor_holder(const ebo_functor_holder &x) + : T(static_cast(x)) + {} + + BOOST_INTRUSIVE_FORCEINLINE ebo_functor_holder(BOOST_RV_REF(ebo_functor_holder) x) + : T(BOOST_MOVE_BASE(T, x)) + {} + + BOOST_INTRUSIVE_FORCEINLINE ebo_functor_holder& operator=(BOOST_COPY_ASSIGN_REF(ebo_functor_holder) x) + { + const ebo_functor_holder&r = x; + this->get() = r; + return *this; + } + + BOOST_INTRUSIVE_FORCEINLINE ebo_functor_holder& operator=(BOOST_RV_REF(ebo_functor_holder) x) + { + this->get() = ::boost::move(x.get()); + return *this; + } + + BOOST_INTRUSIVE_FORCEINLINE ebo_functor_holder& operator=(const T &x) + { + this->get() = x; + return *this; + } + + BOOST_INTRUSIVE_FORCEINLINE ebo_functor_holder& operator=(BOOST_RV_REF(T) x) + { + this->get() = ::boost::move(x); + return *this; + } + + BOOST_INTRUSIVE_FORCEINLINE T& get(){return *this;} + BOOST_INTRUSIVE_FORCEINLINE const T& get()const{return *this;} +}; + +} //namespace detail { +} //namespace intrusive { +} //namespace boost { + +#endif //#ifndef BOOST_INTRUSIVE_DETAIL_EBO_HOLDER_HPP diff --git a/third_party/boost/libs/intrusive/include/boost/intrusive/detail/empty_node_checker.hpp b/third_party/boost/libs/intrusive/include/boost/intrusive/detail/empty_node_checker.hpp new file mode 100644 index 00000000000..fbff4b67366 --- /dev/null +++ b/third_party/boost/libs/intrusive/include/boost/intrusive/detail/empty_node_checker.hpp @@ -0,0 +1,44 @@ +///////////////////////////////////////////////////////////////////////////// +// +// (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_EMPTY_NODE_CHECKER_HPP +#define BOOST_INTRUSIVE_DETAIL_EMPTY_NODE_CHECKER_HPP + +#ifndef BOOST_CONFIG_HPP +# include +#endif + +#if defined(BOOST_HAS_PRAGMA_ONCE) +# pragma once +#endif + +namespace boost { +namespace intrusive { +namespace detail { + +template +struct empty_node_checker +{ + typedef ValueTraits value_traits; + typedef typename value_traits::node_traits node_traits; + typedef typename node_traits::const_node_ptr const_node_ptr; + + struct return_type {}; + + void operator () (const_node_ptr, const return_type&, const return_type&, return_type&) {} +}; + +} //namespace detail{ +} //namespace intrusive{ +} //namespace boost{ + +#endif //BOOST_INTRUSIVE_DETAIL_EMPTY_NODE_CHECKER_HPP diff --git a/third_party/boost/libs/intrusive/include/boost/intrusive/detail/equal_to_value.hpp b/third_party/boost/libs/intrusive/include/boost/intrusive/detail/equal_to_value.hpp new file mode 100644 index 00000000000..c5d9e5305c1 --- /dev/null +++ b/third_party/boost/libs/intrusive/include/boost/intrusive/detail/equal_to_value.hpp @@ -0,0 +1,50 @@ +///////////////////////////////////////////////////////////////////////////// +// +// (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_EQUAL_TO_VALUE_HPP +#define BOOST_INTRUSIVE_DETAIL_EQUAL_TO_VALUE_HPP + +#ifndef BOOST_CONFIG_HPP +# include +#endif + +#if defined(BOOST_HAS_PRAGMA_ONCE) +# pragma once +#endif + +#include + +namespace boost { +namespace intrusive { +namespace detail { + +//This functor compares a stored value +//and the one passed as an argument +template +class equal_to_value +{ + ConstReference t_; + + public: + equal_to_value(ConstReference t) + : t_(t) + {} + + BOOST_INTRUSIVE_FORCEINLINE bool operator()(ConstReference t)const + { return t_ == t; } +}; + +} //namespace detail{ +} //namespace intrusive{ +} //namespace boost{ + +#endif //BOOST_INTRUSIVE_DETAIL_EQUAL_TO_VALUE_HPP diff --git a/third_party/boost/libs/intrusive/include/boost/intrusive/detail/exception_disposer.hpp b/third_party/boost/libs/intrusive/include/boost/intrusive/detail/exception_disposer.hpp new file mode 100644 index 00000000000..0e21faebaa0 --- /dev/null +++ b/third_party/boost/libs/intrusive/include/boost/intrusive/detail/exception_disposer.hpp @@ -0,0 +1,59 @@ +///////////////////////////////////////////////////////////////////////////// +// +// (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_EXCEPTION_DISPOSER_HPP +#define BOOST_INTRUSIVE_DETAIL_EXCEPTION_DISPOSER_HPP + +#ifndef BOOST_CONFIG_HPP +# include +#endif + +#if defined(BOOST_HAS_PRAGMA_ONCE) +# pragma once +#endif + +#include + +namespace boost { +namespace intrusive { +namespace detail { + +template +class exception_disposer +{ + Container *cont_; + Disposer &disp_; + + exception_disposer(const exception_disposer&); + exception_disposer &operator=(const exception_disposer&); + + public: + exception_disposer(Container &cont, Disposer &disp) + : cont_(&cont), disp_(disp) + {} + + BOOST_INTRUSIVE_FORCEINLINE void release() + { cont_ = 0; } + + ~exception_disposer() + { + if(cont_){ + cont_->clear_and_dispose(disp_); + } + } +}; + +} //namespace detail{ +} //namespace intrusive{ +} //namespace boost{ + +#endif //BOOST_INTRUSIVE_DETAIL_EXCEPTION_DISPOSER_HPP diff --git a/third_party/boost/libs/intrusive/include/boost/intrusive/detail/function_detector.hpp b/third_party/boost/libs/intrusive/include/boost/intrusive/detail/function_detector.hpp new file mode 100644 index 00000000000..5ecaeaf0731 --- /dev/null +++ b/third_party/boost/libs/intrusive/include/boost/intrusive/detail/function_detector.hpp @@ -0,0 +1,92 @@ +///////////////////////////////////////////////////////////////////////////// +// +// (C) Copyright Ion Gaztanaga 2009-2013. +// +// 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. +// +///////////////////////////////////////////////////////////////////////////// +// This code was modified from the code posted by Alexandre Courpron in his +// article "Interface Detection" in The Code Project: +// http://www.codeproject.com/KB/architecture/Detector.aspx +/////////////////////////////////////////////////////////////////////////////// +// Copyright 2007 Alexandre Courpron +// +// Permission to use, copy, modify, redistribute and sell this software, +// provided that this copyright notice appears on all copies of the software. +/////////////////////////////////////////////////////////////////////////////// + +#ifndef BOOST_INTRUSIVE_DETAIL_FUNCTION_DETECTOR_HPP +#define BOOST_INTRUSIVE_DETAIL_FUNCTION_DETECTOR_HPP + +#ifndef BOOST_CONFIG_HPP +# include +#endif + +#if defined(BOOST_HAS_PRAGMA_ONCE) +# pragma once +#endif + +namespace boost { +namespace intrusive { +namespace function_detector { + + typedef char NotFoundType; + struct StaticFunctionType { NotFoundType x [2]; }; + struct NonStaticFunctionType { NotFoundType x [3]; }; + + enum + { NotFound = 0, + StaticFunction = sizeof( StaticFunctionType ) - sizeof( NotFoundType ), + NonStaticFunction = sizeof( NonStaticFunctionType ) - sizeof( NotFoundType ) + }; + +} //namespace boost { +} //namespace intrusive { +} //namespace function_detector { + +#define BOOST_INTRUSIVE_CREATE_FUNCTION_DETECTOR(Identifier, InstantiationKey) \ + namespace boost { \ + namespace intrusive { \ + namespace function_detector { \ + template < class T, \ + class NonStaticType, \ + class NonStaticConstType, \ + class StaticType > \ + class DetectMember_##InstantiationKey_##Identifier { \ + template < NonStaticType > \ + struct TestNonStaticNonConst ; \ + \ + template < NonStaticConstType > \ + struct TestNonStaticConst ; \ + \ + template < StaticType > \ + struct TestStatic ; \ + \ + template \ + static NonStaticFunctionType Test( TestNonStaticNonConst<&U::Identifier>*, int ); \ + \ + template \ + static NonStaticFunctionType Test( TestNonStaticConst<&U::Identifier>*, int ); \ + \ + template \ + static StaticFunctionType Test( TestStatic<&U::Identifier>*, int ); \ + \ + template \ + static NotFoundType Test( ... ); \ + public : \ + static const int check = NotFound + (sizeof(Test(0, 0)) - sizeof(NotFoundType));\ + };\ +}}} //namespace boost::intrusive::function_detector { + +#define BOOST_INTRUSIVE_DETECT_FUNCTION(Class, InstantiationKey, ReturnType, Identifier, Params) \ + ::boost::intrusive::function_detector::DetectMember_##InstantiationKey_##Identifier< Class,\ + ReturnType (Class::*)Params,\ + ReturnType (Class::*)Params const,\ + ReturnType (*)Params \ + >::check + +#endif //@ifndef BOOST_INTRUSIVE_DETAIL_FUNCTION_DETECTOR_HPP diff --git a/third_party/boost/libs/intrusive/include/boost/intrusive/detail/generic_hook.hpp b/third_party/boost/libs/intrusive/include/boost/intrusive/detail/generic_hook.hpp new file mode 100644 index 00000000000..6e43f90d9c5 --- /dev/null +++ b/third_party/boost/libs/intrusive/include/boost/intrusive/detail/generic_hook.hpp @@ -0,0 +1,223 @@ +///////////////////////////////////////////////////////////////////////////// +// +// (C) Copyright Ion Gaztanaga 2007-2013 +// +// 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_GENERIC_HOOK_HPP +#define BOOST_INTRUSIVE_GENERIC_HOOK_HPP + +#ifndef BOOST_CONFIG_HPP +# include +#endif + +#if defined(BOOST_HAS_PRAGMA_ONCE) +# pragma once +#endif + +#include +#include +#include +#include +#include +#include +#include + +namespace boost { +namespace intrusive { + +/// @cond + +namespace detail { + +template +struct link_dispatch +{}; + +template +BOOST_INTRUSIVE_FORCEINLINE void destructor_impl(Hook &hook, detail::link_dispatch) +{ //If this assertion raises, you might have destroyed an object + //while it was still inserted in a container that is alive. + //If so, remove the object from the container before destroying it. + (void)hook; BOOST_INTRUSIVE_SAFE_HOOK_DESTRUCTOR_ASSERT(!hook.is_linked()); +} + +template +BOOST_INTRUSIVE_FORCEINLINE void destructor_impl(Hook &hook, detail::link_dispatch) +{ hook.unlink(); } + +template +BOOST_INTRUSIVE_FORCEINLINE void destructor_impl(Hook &, detail::link_dispatch) +{} + +} //namespace detail { + +enum base_hook_type +{ NoBaseHookId +, ListBaseHookId +, SlistBaseHookId +, RbTreeBaseHookId +, HashBaseHookId +, AvlTreeBaseHookId +, BsTreeBaseHookId +, TreapTreeBaseHookId +, AnyBaseHookId +}; + + +template +struct hook_tags_definer{}; + +template +struct hook_tags_definer +{ typedef HookTags default_list_hook; }; + +template +struct hook_tags_definer +{ typedef HookTags default_slist_hook; }; + +template +struct hook_tags_definer +{ typedef HookTags default_rbtree_hook; }; + +template +struct hook_tags_definer +{ typedef HookTags default_hashtable_hook; }; + +template +struct hook_tags_definer +{ typedef HookTags default_avltree_hook; }; + +template +struct hook_tags_definer +{ typedef HookTags default_bstree_hook; }; + +template +struct hook_tags_definer +{ typedef HookTags default_any_hook; }; + +template + < class NodeTraits + , class Tag + , link_mode_type LinkMode + , base_hook_type BaseHookType + > +struct hooktags_impl +{ + static const link_mode_type link_mode = LinkMode; + typedef Tag tag; + typedef NodeTraits node_traits; + static const bool is_base_hook = !detail::is_same::value; + static const bool safemode_or_autounlink = is_safe_autounlink::value; + static const unsigned int type = BaseHookType; +}; + +/// @endcond + +template + < boost::intrusive::algo_types Algo + , class NodeTraits + , class Tag + , link_mode_type LinkMode + , base_hook_type BaseHookType + > +class generic_hook + /// @cond + //If the hook is a base hook, derive generic hook from node_holder + //so that a unique base class is created to convert from the node + //to the type. This mechanism will be used by bhtraits. + // + //If the hook is a member hook, generic hook will directly derive + //from the hook. + : public detail::if_c + < detail::is_same::value + , typename NodeTraits::node + , node_holder + >::type + //If this is the a default-tagged base hook derive from a class that + //will define an special internal typedef. Containers will be able to detect this + //special typedef and obtain generic_hook's internal types in order to deduce + //value_traits for this hook. + , public hook_tags_definer + < generic_hook + , detail::is_same::value ? BaseHookType : NoBaseHookId> + /// @endcond +{ + /// @cond + typedef typename get_algo::type node_algorithms; + typedef typename node_algorithms::node node; + typedef typename node_algorithms::node_ptr node_ptr; + typedef typename node_algorithms::const_node_ptr const_node_ptr; + + public: + + typedef hooktags_impl + < NodeTraits + , Tag, LinkMode, BaseHookType> hooktags; + + 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_NOEXCEPT + { return pointer_traits::pointer_to(static_cast(*this)); } + + public: + /// @endcond + + 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_NOEXCEPT + { + if(hooktags::safemode_or_autounlink){ + node_algorithms::init(this->this_ptr()); + } + } + + BOOST_INTRUSIVE_FORCEINLINE generic_hook& operator=(const generic_hook& ) BOOST_NOEXCEPT + { return *this; } + + BOOST_INTRUSIVE_FORCEINLINE ~generic_hook() + { + destructor_impl + (*this, detail::link_dispatch()); + } + + 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_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_NOEXCEPT + { + BOOST_STATIC_ASSERT(( (int)hooktags::link_mode == (int)auto_unlink )); + node_ptr n(this->this_ptr()); + if(!node_algorithms::inited(n)){ + node_algorithms::unlink(n); + node_algorithms::init(n); + } + } +}; + +} //namespace intrusive +} //namespace boost + +#endif //BOOST_INTRUSIVE_GENERIC_HOOK_HPP diff --git a/third_party/boost/libs/intrusive/include/boost/intrusive/detail/get_value_traits.hpp b/third_party/boost/libs/intrusive/include/boost/intrusive/detail/get_value_traits.hpp new file mode 100644 index 00000000000..222f8078a64 --- /dev/null +++ b/third_party/boost/libs/intrusive/include/boost/intrusive/detail/get_value_traits.hpp @@ -0,0 +1,222 @@ +///////////////////////////////////////////////////////////////////////////// +// +// (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_GET_VALUE_TRAITS_HPP +#define BOOST_INTRUSIVE_DETAIL_GET_VALUE_TRAITS_HPP + +#ifndef BOOST_CONFIG_HPP +# include +#endif + +#if defined(BOOST_HAS_PRAGMA_ONCE) +# pragma once +#endif + +#include +#include +#include + +namespace boost { +namespace intrusive { + +#ifndef BOOST_INTRUSIVE_DOXYGEN_INVOKED + +template +struct is_default_hook_tag +{ static const bool value = false; }; + +namespace detail{ + +template +struct concrete_hook_base_value_traits +{ + typedef typename BaseHook::hooktags tags; + typedef bhtraits + < T + , typename tags::node_traits + , tags::link_mode + , typename tags::tag + , tags::type> type; +}; + +template +struct concrete_hook_base_value_traits +{ + typedef typename BaseHook::hooktags type; +}; + +template +struct any_hook_base_value_traits +{ + //AnyToSomeHook value_traits derive from a generic_hook + //The generic_hook is configured with any_node_traits + //and AnyToSomeHook::value_traits with the correct + //node traits for the container, so use node_traits + //from AnyToSomeHook_ProtoValueTraits and the rest of + //elements from the hooktags member of the generic_hook + + typedef typename AnyToSomeHook_ProtoValueTraits::basic_hook_t basic_hook_t; + typedef typename pointer_rebind + < typename basic_hook_t::hooktags::node_traits::node_ptr + , void>::type void_pointer; + typedef typename AnyToSomeHook_ProtoValueTraits::template + node_traits_from_voidptr::type node_traits; + + typedef bhtraits + < T + , node_traits + , basic_hook_t::hooktags::link_mode + , typename basic_hook_t::hooktags::tag + , basic_hook_t::hooktags::type + > type; +}; + +template +struct any_hook_base_value_traits +{ + typedef typename AnyToSomeHook_ProtoValueTraits::basic_hook_t basic_hook_t; + typedef typename pointer_rebind + < typename basic_hook_t::hooktags::node_traits::node_ptr + , void>::type void_pointer; + + struct type + { + typedef typename AnyToSomeHook_ProtoValueTraits::template + node_traits_from_voidptr::type node_traits; + }; +}; + +template +struct get_member_value_traits +{ + typedef typename MemberHook::member_value_traits type; +}; + +BOOST_INTRUSIVE_INTERNAL_STATIC_BOOL_IS_TRUE(internal_any_hook, is_any_hook) +BOOST_INTRUSIVE_INTERNAL_STATIC_BOOL_IS_TRUE(internal_base_hook, hooktags::is_base_hook) + +template +struct internal_member_value_traits +{ + template static yes_type test(...); + template static no_type test(typename U::member_value_traits* = 0); + static const bool value = sizeof(test(0)) == sizeof(no_type); +}; + +template::value> +struct supposed_value_traits; + +template::value> +struct get_base_value_traits; + +template::value> +struct supposed_base_value_traits; + +template::value> +struct supposed_member_value_traits; + +template::value> +struct any_or_concrete_value_traits; + +//Base any hook +template +struct get_base_value_traits + : any_hook_base_value_traits +{}; + +//Non-any base hook +template +struct get_base_value_traits + : concrete_hook_base_value_traits +{}; + +//...It's a default hook +template +struct supposed_value_traits +{ typedef typename SupposedValueTraits::template apply::type type; }; + +//...Not a default hook +template +struct supposed_value_traits +{ typedef SupposedValueTraits type; }; + +//...It's a base hook +template +struct supposed_base_value_traits + : get_base_value_traits +{}; + +//...Not a base hook, try if it's a member or value_traits +template +struct supposed_base_value_traits + : supposed_member_value_traits +{}; + +//...It's a member hook +template +struct supposed_member_value_traits + : get_member_value_traits +{}; + +//...Not a member hook +template +struct supposed_member_value_traits + : any_or_concrete_value_traits +{}; + +template +struct any_or_concrete_value_traits +{ + //A hook node (non-base, e.g.: member or other value traits + typedef typename AnyToSomeHook_ProtoValueTraits::basic_hook_t basic_hook_t; + typedef typename pointer_rebind + ::type void_pointer; + typedef typename AnyToSomeHook_ProtoValueTraits::template + node_traits_from_voidptr::type any_node_traits; + + struct type : basic_hook_t + { + typedef any_node_traits node_traits; + }; +}; + +template +struct any_or_concrete_value_traits +{ + typedef SupposedValueTraits type; +}; + +//////////////////////////////////////// +// get_value_traits / get_node_traits +//////////////////////////////////////// + +template +struct get_value_traits + : supposed_base_value_traits::type, T> +{}; + +template +struct get_node_traits +{ + typedef typename get_value_traits::type::node_traits type; +}; + +} //namespace detail{ + +#endif //BOOST_INTRUSIVE_DOXYGEN_INVOKED + +} //namespace intrusive { +} //namespace boost { + +#include + +#endif //#ifndef BOOST_INTRUSIVE_DETAIL_GET_VALUE_TRAITS_HPP diff --git a/third_party/boost/libs/intrusive/include/boost/intrusive/detail/has_member_function_callable_with.hpp b/third_party/boost/libs/intrusive/include/boost/intrusive/detail/has_member_function_callable_with.hpp new file mode 100644 index 00000000000..92ef60ee6df --- /dev/null +++ b/third_party/boost/libs/intrusive/include/boost/intrusive/detail/has_member_function_callable_with.hpp @@ -0,0 +1,366 @@ +////////////////////////////////////////////////////////////////////////////// +// +// (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/container for documentation. +// +////////////////////////////////////////////////////////////////////////////// + +#ifndef BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_CALLABLE_WITH_HPP +#define BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_CALLABLE_WITH_HPP + +#ifndef BOOST_CONFIG_HPP +# include +#endif + +//In case no decltype and no variadics, mark that we don't support 0 arg calls due to +//compiler ICE in GCC 3.4/4.0/4.1 and, wrong SFINAE for GCC 4.2/4.3/MSVC10/MSVC11 +#if defined(BOOST_NO_CXX11_DECLTYPE) && defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) +# if defined(BOOST_GCC) && (BOOST_GCC < 40400) +# define BOOST_INTRUSIVE_DETAIL_HAS_MEMBER_FUNCTION_CALLABLE_WITH_0_ARGS_UNSUPPORTED +# elif defined(BOOST_INTEL) && (BOOST_INTEL < 1200) +# define BOOST_INTRUSIVE_DETAIL_HAS_MEMBER_FUNCTION_CALLABLE_WITH_0_ARGS_UNSUPPORTED +# elif defined(BOOST_MSVC) && (BOOST_MSVC < 1800) +# define BOOST_INTRUSIVE_DETAIL_HAS_MEMBER_FUNCTION_CALLABLE_WITH_0_ARGS_UNSUPPORTED +# endif +#endif //#if defined(BOOST_NO_CXX11_DECLTYPE) && defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) + +#include +#include +#include + +namespace boost_intrusive_hmfcw { + +typedef char yes_type; +struct no_type{ char dummy[2]; }; + +struct dont_care +{ + dont_care(...); +}; + +#if defined(BOOST_NO_CXX11_DECLTYPE) + +#if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) + +template +struct make_dontcare +{ + typedef dont_care type; +}; + +#endif + +struct private_type +{ + static private_type p; + private_type const &operator,(int) const; +}; + +template +no_type is_private_type(T const &); +yes_type is_private_type(private_type const &); + +#endif //#if defined(BOOST_NO_CXX11_DECLTYPE) + +#if defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) || defined(BOOST_NO_CXX11_DECLTYPE) + +template struct remove_cv { typedef T type; }; +template struct remove_cv { typedef T type; }; +template struct remove_cv { typedef T type; }; +template struct remove_cv { typedef T type; }; + +#endif + +} //namespace boost_intrusive_hmfcw { + +#endif //BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_CALLABLE_WITH_HPP + +#ifndef BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_FUNCNAME + #error "You MUST define BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_FUNCNAME before including this header!" +#endif + +#ifndef BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_MIN + #error "You MUST define BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_MIN before including this header!" +#endif + +#ifndef BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_MAX + #error "You MUST define BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_MAX before including this header!" +#endif + +#if BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_MAX < BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_MIN + #error "BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_MAX value MUST be greater or equal than BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_MIN!" +#endif + +#if BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_MAX == 0 + #define BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_COMMA_IF +#else + #define BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_COMMA_IF , +#endif + +#ifndef BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_NS_BEG + #error "BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_NS_BEG not defined!" +#endif + +#ifndef BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_NS_END + #error "BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_NS_END not defined!" +#endif + +BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_NS_BEG + +#if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) && !defined(BOOST_NO_CXX11_DECLTYPE) + //With decltype and variadic templaes, things are pretty easy + template + struct BOOST_MOVE_CAT(has_member_function_callable_with_,BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_FUNCNAME) + { + template + static decltype(boost::move_detail::declval(). + BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_FUNCNAME(::boost::move_detail::declval()...) + , boost_intrusive_hmfcw::yes_type()) Test(U* f); + template + static boost_intrusive_hmfcw::no_type Test(...); + static const bool value = sizeof(Test((Fun*)0)) == sizeof(boost_intrusive_hmfcw::yes_type); + }; + +#else //defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) || defined(BOOST_NO_CXX11_DECLTYPE) + + ///////////////////////////////////////////////////////// + ///////////////////////////////////////////////////////// + // + // has_member_function_callable_with_impl_XXX + // declaration, special case and 0 arg specializaton + // + ///////////////////////////////////////////////////////// + + template + class BOOST_MOVE_CAT(has_member_function_named_, BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_FUNCNAME) + { + struct BaseMixin + { + void BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_FUNCNAME() + {} //Some compilers require the definition or linker errors happen + }; + + struct Base + : public boost_intrusive_hmfcw::remove_cv::type, public BaseMixin + { //Declare the unneeded default constructor as some old compilers wrongly require it with is_convertible + Base(){} + }; + template class Helper{}; + + template + static boost_intrusive_hmfcw::no_type deduce + (U*, Helper* = 0); + static boost_intrusive_hmfcw::yes_type deduce(...); + + public: + static const bool value = sizeof(boost_intrusive_hmfcw::yes_type) == sizeof(deduce((Base*)0)); + }; + + #if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) + ///////////////////////////////////////////////////////// + ///////////////////////////////////////////////////////// + // + // has_member_function_callable_with_impl_XXX for 1 to N arguments + // + ///////////////////////////////////////////////////////// + ///////////////////////////////////////////////////////// + + //defined(BOOST_NO_CXX11_DECLTYPE) must be true + template + struct FunWrapTmpl : Fun + { + using Fun::BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_FUNCNAME; + FunWrapTmpl(); + template + boost_intrusive_hmfcw::private_type BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_FUNCNAME(DontCares...) const; + }; + + template + struct BOOST_MOVE_CAT(has_member_function_callable_with_impl_, BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_FUNCNAME); + + //No BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_FUNCNAME member specialization + template + struct BOOST_MOVE_CAT(has_member_function_callable_with_impl_, BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_FUNCNAME) + + { + static const bool value = false; + }; + + template + struct BOOST_MOVE_CAT(has_member_function_callable_with_impl_,BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_FUNCNAME) + { + static bool const value = (sizeof(boost_intrusive_hmfcw::no_type) == sizeof(boost_intrusive_hmfcw::is_private_type + ( (::boost::move_detail::declval + < FunWrapTmpl >(). + BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_FUNCNAME(::boost::move_detail::declval()...), 0) ) + ) + ); + }; + + template + struct BOOST_MOVE_CAT(has_member_function_callable_with_, BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_FUNCNAME) + : public BOOST_MOVE_CAT(has_member_function_callable_with_impl_, BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_FUNCNAME) + ::value + , Args...> + {}; + #else //defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) + + ///////////////////////////////////////////////////////// + ///////////////////////////////////////////////////////// + // + // has_member_function_callable_with_impl_XXX specializations + // + ///////////////////////////////////////////////////////// + + template + struct BOOST_MOVE_CAT(has_member_function_callable_with_impl_, BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_FUNCNAME); + + //No BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_FUNCNAME member specialization + template + struct BOOST_MOVE_CAT(has_member_function_callable_with_impl_, BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_FUNCNAME) + + { + static const bool value = false; + }; + + #if BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_MIN == 0 + //0 arg specialization when BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_FUNCNAME is present + #if !defined(BOOST_NO_CXX11_DECLTYPE) + + template + struct BOOST_MOVE_CAT(has_member_function_callable_with_impl_, BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_FUNCNAME) + { + template + static decltype(boost::move_detail::declval().BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_FUNCNAME() + , boost_intrusive_hmfcw::yes_type()) Test(U* f); + + template + static boost_intrusive_hmfcw::no_type Test(...); + static const bool value = sizeof(Test((Fun*)0)) == sizeof(boost_intrusive_hmfcw::yes_type); + }; + + #else //defined(BOOST_NO_CXX11_DECLTYPE) + + #if !defined(BOOST_INTRUSIVE_DETAIL_HAS_MEMBER_FUNCTION_CALLABLE_WITH_0_ARGS_UNSUPPORTED) + + template().BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_FUNCNAME(), 0)> + struct BOOST_MOVE_CAT(zeroarg_checker_, BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_FUNCNAME) + { boost_intrusive_hmfcw::yes_type dummy[N ? 1 : 2]; }; + + template + struct BOOST_MOVE_CAT(has_member_function_callable_with_impl_, BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_FUNCNAME) + { + template static BOOST_MOVE_CAT(zeroarg_checker_, BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_FUNCNAME) + Test(BOOST_MOVE_CAT(zeroarg_checker_, BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_FUNCNAME)*); + template static boost_intrusive_hmfcw::no_type Test(...); + static const bool value = sizeof(Test< Fun >(0)) == sizeof(boost_intrusive_hmfcw::yes_type); + }; + + #else //defined(BOOST_INTRUSIVE_DETAIL_HAS_MEMBER_FUNCTION_CALLABLE_WITH_0_ARGS_UNSUPPORTED) + + template + struct BOOST_MOVE_CAT(has_member_function_callable_with_impl_, BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_FUNCNAME) + { //Some compilers gives ICE when instantiating the 0 arg version so it is not supported. + static const bool value = true; + }; + + #endif//!defined(BOOST_INTRUSIVE_DETAIL_HAS_MEMBER_FUNCTION_CALLABLE_WITH_0_ARGS_UNSUPPORTED) + #endif //!defined(BOOST_NO_CXX11_DECLTYPE) + #endif //#if BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_MIN == 0 + + #if BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_MAX > 0 + //1 to N arg specialization when BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_FUNCNAME is present + //Declare some unneeded default constructor as some old compilers wrongly require it with is_convertible + #if defined(BOOST_NO_CXX11_DECLTYPE) + #define BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_ITERATION(N)\ + \ + template\ + struct BOOST_MOVE_CAT(FunWrap##N, BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_FUNCNAME)\ + : Fun\ + {\ + using Fun::BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_FUNCNAME;\ + BOOST_MOVE_CAT(FunWrap##N, BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_FUNCNAME)();\ + boost_intrusive_hmfcw::private_type BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_FUNCNAME\ + (BOOST_MOVE_REPEAT##N(boost_intrusive_hmfcw::dont_care)) const;\ + };\ + \ + template\ + struct BOOST_MOVE_CAT(has_member_function_callable_with_impl_, BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_FUNCNAME)\ + {\ + static bool const value = (sizeof(boost_intrusive_hmfcw::no_type) == sizeof(boost_intrusive_hmfcw::is_private_type\ + ( (::boost::move_detail::declval\ + < BOOST_MOVE_CAT(FunWrap##N, BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_FUNCNAME) >().\ + BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_FUNCNAME(BOOST_MOVE_DECLVAL##N), 0) )\ + )\ + );\ + };\ + // + #else + #define BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_ITERATION(N)\ + template\ + struct BOOST_MOVE_CAT(has_member_function_callable_with_impl_, BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_FUNCNAME)\ + \ + {\ + template\ + static decltype(boost::move_detail::declval().\ + BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_FUNCNAME(BOOST_MOVE_DECLVAL##N)\ + , boost_intrusive_hmfcw::yes_type()) Test(U* f);\ + template\ + static boost_intrusive_hmfcw::no_type Test(...);\ + static const bool value = sizeof(Test((Fun*)0)) == sizeof(boost_intrusive_hmfcw::yes_type);\ + };\ + // + #endif + //////////////////////////////////// + // Build and invoke BOOST_MOVE_ITERATE_NTOM macrofunction, note that N has to be at least 1 + //////////////////////////////////// + #if BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_MIN == 0 + #define BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_ITERATE_MIN 1 + #else + #define BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_ITERATE_MIN BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_MIN + #endif + BOOST_MOVE_CAT + (BOOST_MOVE_CAT(BOOST_MOVE_CAT(BOOST_MOVE_ITERATE_, BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_ITERATE_MIN), TO) + ,BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_MAX) + (BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_ITERATION) + #undef BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_ITERATION + #undef BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_ITERATE_MIN + //////////////////////////////////// + // End of BOOST_MOVE_ITERATE_NTOM + //////////////////////////////////// + #endif //BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_MAX > 0 + + ///////////////////////////////////////////////////////// + ///////////////////////////////////////////////////////// + // + // has_member_function_callable_with_FUNC + // + ///////////////////////////////////////////////////////// + ///////////////////////////////////////////////////////// + + //Otherwise use the preprocessor + template + struct BOOST_MOVE_CAT(has_member_function_callable_with_, BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_FUNCNAME) + : public BOOST_MOVE_CAT(has_member_function_callable_with_impl_, BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_FUNCNAME) + ::value + BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_COMMA_IF BOOST_MOVE_CAT(BOOST_MOVE_TARG,BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_MAX)> + {}; + #endif //defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) +#endif + +BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_NS_END + +//Undef local macros +#undef BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_COMMA_IF + +//Undef user defined macros +#undef BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_FUNCNAME +#undef BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_MIN +#undef BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_MAX +#undef BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_NS_BEG +#undef BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_NS_END diff --git a/third_party/boost/libs/intrusive/include/boost/intrusive/detail/hash_combine.hpp b/third_party/boost/libs/intrusive/include/boost/intrusive/detail/hash_combine.hpp new file mode 100644 index 00000000000..f089fb0cc00 --- /dev/null +++ b/third_party/boost/libs/intrusive/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/third_party/boost/libs/intrusive/include/boost/intrusive/detail/hashtable_node.hpp b/third_party/boost/libs/intrusive/include/boost/intrusive/detail/hashtable_node.hpp new file mode 100644 index 00000000000..8e9a06258a7 --- /dev/null +++ b/third_party/boost/libs/intrusive/include/boost/intrusive/detail/hashtable_node.hpp @@ -0,0 +1,375 @@ +///////////////////////////////////////////////////////////////////////////// +// +// (C) Copyright Ion Gaztanaga 2007-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_HASHTABLE_NODE_HPP +#define BOOST_INTRUSIVE_HASHTABLE_NODE_HPP + +#ifndef BOOST_CONFIG_HPP +# include +#endif + +#if defined(BOOST_HAS_PRAGMA_ONCE) +# pragma once +#endif + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + + +namespace boost { +namespace intrusive { + +template +struct bucket_impl + : public NodeTraits::node +{ + public: + typedef NodeTraits node_traits; + + private: + 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: + BOOST_INTRUSIVE_FORCEINLINE bucket_impl() + {} + + BOOST_INTRUSIVE_FORCEINLINE bucket_impl(const bucket_impl &) + {} + + BOOST_INTRUSIVE_FORCEINLINE ~bucket_impl() + {} + + BOOST_INTRUSIVE_FORCEINLINE bucket_impl &operator=(const bucket_impl&) + { return *this; } + + BOOST_INTRUSIVE_FORCEINLINE node_ptr get_node_ptr() + { return pointer_traits::pointer_to(*this); } + + BOOST_INTRUSIVE_FORCEINLINE const_node_ptr get_node_ptr() const + { return pointer_traits::pointer_to(*this); } + + BOOST_INTRUSIVE_FORCEINLINE node_ptr begin_ptr() + { return node_traits::get_next(get_node_ptr()); } +}; + + + +template +struct hash_reduced_slist_node_traits +{ + template static detail::no_type test(...); + template static detail::yes_type test(typename U::reduced_slist_node_traits*); + static const bool value = sizeof(test(0)) == sizeof(detail::yes_type); +}; + +template +struct apply_reduced_slist_node_traits +{ + typedef typename NodeTraits::reduced_slist_node_traits type; +}; + +template +struct reduced_slist_node_traits +{ + typedef typename detail::eval_if_c + < hash_reduced_slist_node_traits::value + , apply_reduced_slist_node_traits + , detail::identity + >::type type; +}; + +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 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; + class nat; + typedef typename + detail::if_c< IsConst + , hashtable_iterator + , nat>::type nonconst_iterator; + + BOOST_INTRUSIVE_FORCEINLINE static node_ptr downcast_bucket(typename bucket_type::node_traits::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) + {} + + BOOST_INTRUSIVE_FORCEINLINE explicit hashtable_iterator(siterator ptr, const BucketValueTraits *cont) + : slist_it_ (ptr) + , traitsptr_ (cont ? pointer_traits::pointer_to(*cont) : const_bucketvaltraits_ptr() ) + {} + + BOOST_INTRUSIVE_FORCEINLINE hashtable_iterator(const hashtable_iterator &other) + : slist_it_(other.slist_it()), traitsptr_(other.get_bucket_value_traits()) + {} + + BOOST_INTRUSIVE_FORCEINLINE hashtable_iterator(const nonconst_iterator &other) + : slist_it_(other.slist_it()), traitsptr_(other.get_bucket_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(), this->get_bucket_value_traits()); } + + 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(); traitsptr_ = other.get_bucket_value_traits(); 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 == i2); } + + BOOST_INTRUSIVE_FORCEINLINE reference operator*() const + { return *this->operator ->(); } + + BOOST_INTRUSIVE_FORCEINLINE pointer operator->() const + { + return this->priv_value_traits().to_value_ptr + (downcast_bucket(slist_it_.pointed_node())); + } + + 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(); } + + private: + + void increment() + { + 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 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(*n); + + //2. Now just calculate the index b has in the bucket array + 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_ = first_bucket_bbegin; + return; + } + bucket_nodeptr = buckets[n_bucket].get_node_ptr(); + } + while (slist_node_algorithms::is_empty(bucket_nodeptr)); + slist_it_ = siterator(bucket_nodeptr); + ++slist_it_; + } + else{ + //++slist_it_ yield to a valid object + } + } + + siterator slist_it_; + 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 { + +#endif diff --git a/third_party/boost/libs/intrusive/include/boost/intrusive/detail/hook_traits.hpp b/third_party/boost/libs/intrusive/include/boost/intrusive/detail/hook_traits.hpp new file mode 100644 index 00000000000..06713487fc3 --- /dev/null +++ b/third_party/boost/libs/intrusive/include/boost/intrusive/detail/hook_traits.hpp @@ -0,0 +1,196 @@ +///////////////////////////////////////////////////////////////////////////// +// +// (C) Copyright Ion Gaztanaga 2006-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_HOOK_TRAITS_HPP +#define BOOST_INTRUSIVE_DETAIL_HOOK_TRAITS_HPP + +#ifndef BOOST_CONFIG_HPP +# include +#endif + +#if defined(BOOST_HAS_PRAGMA_ONCE) +# pragma once +#endif + +#include +#include +#include +#include +#include +#include +#include +#include + +namespace boost { +namespace intrusive { + +template +struct bhtraits_base +{ + public: + typedef NodePtr node_ptr; + typedef typename pointer_traits::element_type node; + typedef node_holder node_holder_type; + typedef T value_type; + typedef typename pointer_traits:: + template rebind_pointer::type const_node_ptr; + typedef typename pointer_traits:: + template rebind_pointer::type pointer; + typedef typename pointer_traits:: + template rebind_pointer::type const_pointer; + //typedef typename pointer_traits::reference reference; + //typedef typename pointer_traits::reference const_reference; + typedef T & reference; + typedef const T & const_reference; + typedef node_holder_type & node_holder_reference; + typedef const node_holder_type & const_node_holder_reference; + typedef node& node_reference; + typedef const node & const_node_reference; + + BOOST_INTRUSIVE_FORCEINLINE static pointer to_value_ptr(node_ptr n) + { + pointer p = pointer_traits::pointer_to + (static_cast(static_cast(*n))); + BOOST_ASSERT(!!p); + return p; + } + + 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))); + BOOST_ASSERT(!!p); + return p; + } + + BOOST_INTRUSIVE_FORCEINLINE static node_ptr to_node_ptr(reference value) + { + node_ptr p = pointer_traits::pointer_to + (static_cast(static_cast(value))); + BOOST_ASSERT(!!p); + return p; + } + + BOOST_INTRUSIVE_FORCEINLINE static const_node_ptr to_node_ptr(const_reference value) + { + const_node_ptr p = pointer_traits::pointer_to + (static_cast(static_cast(value))); + BOOST_ASSERT(!!p); + return p; + } +}; + +template +struct bhtraits + : public bhtraits_base +{ + static const link_mode_type link_mode = LinkMode; + typedef NodeTraits node_traits; +}; + + +template +struct mhtraits +{ + public: + typedef Hook hook_type; + typedef typename hook_type::hooktags::node_traits node_traits; + typedef typename node_traits::node node; + typedef T value_type; + typedef typename node_traits::node_ptr node_ptr; + typedef typename node_traits::const_node_ptr const_node_ptr; + typedef typename pointer_traits:: + template rebind_pointer::type pointer; + typedef typename pointer_traits:: + template rebind_pointer::type const_pointer; + typedef T & reference; + typedef const T & const_reference; + typedef node& node_reference; + typedef const node & const_node_reference; + typedef hook_type& hook_reference; + typedef const hook_type & const_hook_reference; + + static const link_mode_type link_mode = Hook::hooktags::link_mode; + + BOOST_INTRUSIVE_FORCEINLINE static node_ptr to_node_ptr(reference value) + { + return pointer_traits::pointer_to + (static_cast(static_cast(value.*P))); + } + + BOOST_INTRUSIVE_FORCEINLINE static const_node_ptr to_node_ptr(const_reference value) + { + return pointer_traits::pointer_to + (static_cast(static_cast(value.*P))); + } + + 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_node_ptr n) + { + return pointer_traits::pointer_to + (*detail::parent_from_member + (static_cast(boost::movelib::to_raw_pointer(n)), P)); + } +}; + + +template +struct fhtraits +{ + public: + typedef typename Functor::hook_type hook_type; + typedef typename Functor::hook_ptr hook_ptr; + typedef typename Functor::const_hook_ptr const_hook_ptr; + typedef typename hook_type::hooktags::node_traits node_traits; + typedef typename node_traits::node node; + typedef typename Functor::value_type value_type; + typedef typename node_traits::node_ptr node_ptr; + typedef typename node_traits::const_node_ptr const_node_ptr; + typedef typename pointer_traits:: + template rebind_pointer::type pointer; + typedef typename pointer_traits:: + template rebind_pointer::type const_pointer; + typedef value_type & reference; + typedef const value_type & const_reference; + static const link_mode_type link_mode = hook_type::hooktags::link_mode; + + static node_ptr to_node_ptr(reference value) + { return static_cast(boost::movelib::to_raw_pointer(Functor::to_hook_ptr(value))); } + + 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(node_ptr n) + { return Functor::to_value_ptr(to_hook_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(node_ptr n) + { return hook_ptr(&*static_cast(&*n)); } + + static const_hook_ptr to_hook_ptr(const_node_ptr n) + { return const_hook_ptr(&*static_cast(&*n)); } +}; + + +} //namespace intrusive +} //namespace boost + +#endif //BOOST_INTRUSIVE_DETAIL_HOOK_TRAITS_HPP diff --git a/third_party/boost/libs/intrusive/include/boost/intrusive/detail/iiterator.hpp b/third_party/boost/libs/intrusive/include/boost/intrusive/detail/iiterator.hpp new file mode 100644 index 00000000000..5ab1de2bb12 --- /dev/null +++ b/third_party/boost/libs/intrusive/include/boost/intrusive/detail/iiterator.hpp @@ -0,0 +1,122 @@ +///////////////////////////////////////////////////////////////////////////// +// +// (C) Copyright Ion Gaztanaga 2006-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_IITERATOR_HPP +#define BOOST_INTRUSIVE_DETAIL_IITERATOR_HPP + +#ifndef BOOST_CONFIG_HPP +# include +#endif + +#if defined(BOOST_HAS_PRAGMA_ONCE) +# pragma once +#endif + +#include +#include +#include +#include +#include + +namespace boost { +namespace intrusive { + +template +struct value_traits_pointers +{ + typedef BOOST_INTRUSIVE_OBTAIN_TYPE_WITH_DEFAULT + (boost::intrusive::detail:: + , ValueTraits, value_traits_ptr + , typename boost::intrusive::pointer_traits::template + rebind_pointer::type) value_traits_ptr; + + typedef typename boost::intrusive::pointer_traits::template + rebind_pointer::type const_value_traits_ptr; +}; + +template +struct iiterator +{ + typedef ValueTraits value_traits; + typedef typename value_traits::node_traits node_traits; + typedef typename node_traits::node node; + typedef typename node_traits::node_ptr node_ptr; + typedef ::boost::intrusive::pointer_traits nodepointer_traits_t; + typedef typename nodepointer_traits_t::template + rebind_pointer::type void_pointer; + typedef typename ValueTraits::value_type value_type; + typedef typename ValueTraits::pointer nonconst_pointer; + typedef typename ValueTraits::const_pointer yesconst_pointer; + typedef typename ::boost::intrusive::pointer_traits + ::reference nonconst_reference; + typedef typename ::boost::intrusive::pointer_traits + ::reference yesconst_reference; + typedef typename nodepointer_traits_t::difference_type difference_type; + typedef typename detail::if_c + ::type pointer; + typedef typename detail::if_c + ::type reference; + typedef iterator + < Category + , value_type + , difference_type + , pointer + , reference + > iterator_type; + typedef typename value_traits_pointers + ::value_traits_ptr value_traits_ptr; + typedef typename value_traits_pointers + ::const_value_traits_ptr const_value_traits_ptr; + static const bool stateful_value_traits = + detail::is_stateful_value_traits::value; +}; + +template +struct iiterator_members +{ + + BOOST_INTRUSIVE_FORCEINLINE iiterator_members() + : nodeptr_()//Value initialization to achieve "null iterators" (N3644) + {} + + BOOST_INTRUSIVE_FORCEINLINE iiterator_members(const NodePtr &n_ptr, const StoredPointer &data) + : nodeptr_(n_ptr), ptr_(data) + {} + + BOOST_INTRUSIVE_FORCEINLINE StoredPointer get_ptr() const + { return ptr_; } + + NodePtr nodeptr_; + StoredPointer ptr_; +}; + +template +struct iiterator_members +{ + BOOST_INTRUSIVE_FORCEINLINE iiterator_members() + : nodeptr_()//Value initialization to achieve "null iterators" (N3644) + {} + + BOOST_INTRUSIVE_FORCEINLINE iiterator_members(const NodePtr &n_ptr, const StoredPointer &) + : nodeptr_(n_ptr) + {} + + BOOST_INTRUSIVE_FORCEINLINE StoredPointer get_ptr() const + { return StoredPointer(); } + + NodePtr nodeptr_; +}; + +} //namespace intrusive +} //namespace boost + +#endif //BOOST_INTRUSIVE_DETAIL_IITERATOR_HPP diff --git a/third_party/boost/libs/intrusive/include/boost/intrusive/detail/is_stateful_value_traits.hpp b/third_party/boost/libs/intrusive/include/boost/intrusive/detail/is_stateful_value_traits.hpp new file mode 100644 index 00000000000..e43f6d340ac --- /dev/null +++ b/third_party/boost/libs/intrusive/include/boost/intrusive/detail/is_stateful_value_traits.hpp @@ -0,0 +1,81 @@ +///////////////////////////////////////////////////////////////////////////// +// +// (C) Copyright Ion Gaztanaga 2009-2013. +// +// 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_IS_STATEFUL_VALUE_TRAITS_HPP +#define BOOST_INTRUSIVE_DETAIL_IS_STATEFUL_VALUE_TRAITS_HPP + +#ifndef BOOST_CONFIG_HPP +# include +#endif + +#if defined(BOOST_HAS_PRAGMA_ONCE) +# pragma once +#endif + +#if defined(_MSC_VER) && (_MSC_VER <= 1310) + +#include + +namespace boost { +namespace intrusive { +namespace detail { + +template +struct is_stateful_value_traits +{ + static const bool value = !detail::is_empty::value; +}; + +}}} + +#else + +#include + +BOOST_INTRUSIVE_CREATE_FUNCTION_DETECTOR(to_node_ptr, boost_intrusive) +BOOST_INTRUSIVE_CREATE_FUNCTION_DETECTOR(to_value_ptr, boost_intrusive) + +namespace boost { +namespace intrusive { +namespace detail { + +template +struct is_stateful_value_traits +{ + typedef typename ValueTraits::node_ptr node_ptr; + typedef typename ValueTraits::pointer pointer; + typedef typename ValueTraits::value_type value_type; + typedef typename ValueTraits::const_node_ptr const_node_ptr; + typedef typename ValueTraits::const_pointer const_pointer; + + typedef ValueTraits value_traits; + + static const bool value = + (boost::intrusive::function_detector::NonStaticFunction == + (BOOST_INTRUSIVE_DETECT_FUNCTION(ValueTraits, boost_intrusive, node_ptr, to_node_ptr, (value_type&) ))) + || + (boost::intrusive::function_detector::NonStaticFunction == + (BOOST_INTRUSIVE_DETECT_FUNCTION(ValueTraits, boost_intrusive, pointer, to_value_ptr, (node_ptr) ))) + || + (boost::intrusive::function_detector::NonStaticFunction == + (BOOST_INTRUSIVE_DETECT_FUNCTION(ValueTraits, boost_intrusive, const_node_ptr, to_node_ptr, (const value_type&) ))) + || + (boost::intrusive::function_detector::NonStaticFunction == + (BOOST_INTRUSIVE_DETECT_FUNCTION(ValueTraits, boost_intrusive, const_pointer, to_value_ptr, (const_node_ptr) ))) + ; +}; + +}}} + +#endif + +#endif //@ifndef BOOST_INTRUSIVE_DETAIL_IS_STATEFUL_VALUE_TRAITS_HPP diff --git a/third_party/boost/libs/intrusive/include/boost/intrusive/detail/iterator.hpp b/third_party/boost/libs/intrusive/include/boost/intrusive/detail/iterator.hpp new file mode 100644 index 00000000000..ec91cd4f2cf --- /dev/null +++ b/third_party/boost/libs/intrusive/include/boost/intrusive/detail/iterator.hpp @@ -0,0 +1,308 @@ +///////////////////////////////////////////////////////////////////////////// +// +// (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_ITERATOR_HPP +#define BOOST_INTRUSIVE_DETAIL_ITERATOR_HPP + +#ifndef BOOST_CONFIG_HPP +# include +#endif + +#if defined(BOOST_HAS_PRAGMA_ONCE) +# pragma once +#endif + +#include +#include +#include +#include +#include + +namespace boost{ +namespace iterators{ + +struct incrementable_traversal_tag; +struct single_pass_traversal_tag; +struct forward_traversal_tag; +struct bidirectional_traversal_tag; +struct random_access_traversal_tag; + +namespace detail{ + +template +struct iterator_category_with_traversal; + +} //namespace boost{ +} //namespace iterators{ +} //namespace detail{ + +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 +//////////////////// +template +struct iterator +{ + typedef Category iterator_category; + typedef T value_type; + typedef Difference difference_type; + typedef Pointer pointer; + typedef Reference reference; +}; + +//////////////////////////////////////////////////////////////////////////////// +// Conversion from boost::iterator traversals to std tags +//////////////////////////////////////////////////////////////////////////////// + +template +struct get_std_category_from_tag +{ + typedef Tag type; +}; + +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::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 > +{}; + +//////////////////////////////////////// +// iterator_[dis|en]able_if_tag +//////////////////////////////////////// +template +struct iterator_enable_if_tag + : ::boost::move_detail::enable_if_c + < ::boost::move_detail::is_same + < typename get_std_category_from_it::type + , Tag + >::value + , R> +{}; + +template +struct iterator_disable_if_tag + : ::boost::move_detail::enable_if_c + < !::boost::move_detail::is_same + < typename get_std_category_from_it::type + , Tag + >::value + , R> +{}; + +//////////////////////////////////////// +// iterator_[dis|en]able_if_tag +//////////////////////////////////////// +template +struct iterator_enable_if_convertible_tag + : ::boost::move_detail::enable_if_c + < ::boost::move_detail::is_same_or_convertible + < typename get_std_category_from_it::type + , Tag + >::value && + !::boost::move_detail::is_same_or_convertible + < typename get_std_category_from_it::type + , Tag2 + >::value + , R> +{}; + +//////////////////////////////////////// +// iterator_[dis|en]able_if_tag_difference_type +//////////////////////////////////////// +template +struct iterator_enable_if_tag_difference_type + : iterator_enable_if_tag::type> +{}; + +template +struct iterator_disable_if_tag_difference_type + : iterator_disable_if_tag::type> +{}; + +//////////////////// +// advance +//////////////////// + +template +BOOST_INTRUSIVE_FORCEINLINE typename iterator_enable_if_tag::type + iterator_advance(InputIt& it, typename iter_difference::type n) +{ + while(n--) + ++it; +} + +template +typename iterator_enable_if_tag::type + iterator_advance(InputIt& it, typename iter_difference::type n) +{ + while(n--) + ++it; +} + +template +BOOST_INTRUSIVE_FORCEINLINE typename iterator_enable_if_tag::type + iterator_advance(InputIt& it, typename iter_difference::type n) +{ + for (; 0 < n; --n) + ++it; + for (; n < 0; ++n) + --it; +} + +template +BOOST_INTRUSIVE_FORCEINLINE typename iterator_enable_if_tag::type + iterator_advance(InputIt& it, Distance n) +{ + it += n; +} + +template +BOOST_INTRUSIVE_FORCEINLINE typename iterator_enable_if_tag::type + make_iterator_advance(InputIt it, Distance n) +{ + (iterator_advance)(it, n); + return it; +} + +template +BOOST_INTRUSIVE_FORCEINLINE + void iterator_uadvance(It& it, typename iter_size::type n) +{ + (iterator_advance)(it, (typename iterator_traits::difference_type)n); +} + +template +BOOST_INTRUSIVE_FORCEINLINE +It make_iterator_uadvance(It it, typename iter_size::type n) +{ + (iterator_uadvance)(it, n); + return it; +} + +//////////////////////////////////////// +// iterator_distance +//////////////////////////////////////// +template inline +typename iterator_disable_if_tag_difference_type + ::type + iterator_distance(InputIt first, InputIt last) +{ + typename iter_difference::type off = 0; + while(first != last){ + ++off; + ++first; + } + return off; +} + +template +BOOST_INTRUSIVE_FORCEINLINE typename iterator_enable_if_tag_difference_type + ::type + iterator_distance(InputIt first, InputIt last) +{ + 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->(); } + +template +BOOST_INTRUSIVE_FORCEINLINE T * iterator_arrow_result(T *p) +{ return p; } + +} //namespace intrusive +} //namespace boost + +#endif //BOOST_INTRUSIVE_DETAIL_ITERATOR_HPP diff --git a/third_party/boost/libs/intrusive/include/boost/intrusive/detail/key_nodeptr_comp.hpp b/third_party/boost/libs/intrusive/include/boost/intrusive/detail/key_nodeptr_comp.hpp new file mode 100644 index 00000000000..1029a3404a0 --- /dev/null +++ b/third_party/boost/libs/intrusive/include/boost/intrusive/detail/key_nodeptr_comp.hpp @@ -0,0 +1,125 @@ +///////////////////////////////////////////////////////////////////////////// +// +// (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_KEY_NODEPTR_COMP_HPP +#define BOOST_INTRUSIVE_DETAIL_KEY_NODEPTR_COMP_HPP + +#ifndef BOOST_CONFIG_HPP +# include +#endif + +#if defined(BOOST_HAS_PRAGMA_ONCE) +# pragma once +#endif + +#include +#include +#include + + +namespace boost { +namespace intrusive { +namespace detail { + +template < class KeyTypeKeyCompare + , class ValueTraits + , class KeyOfValue + > +struct key_nodeptr_comp_types +{ + typedef ValueTraits value_traits; + typedef typename value_traits::value_type value_type; + typedef typename value_traits::node_ptr node_ptr; + typedef typename value_traits::const_node_ptr const_node_ptr; + typedef typename detail::if_c + < detail::is_same::value + , detail::identity + , KeyOfValue + >::type key_of_value; + typedef tree_value_compare + base_t; +}; + +//This function object transforms a key comparison type to +//a function that can compare nodes or nodes with nodes or keys. +template < class KeyTypeKeyCompare + , class ValueTraits + , class KeyOfValue = void + > +struct key_nodeptr_comp + //Use public inheritance to avoid MSVC bugs with closures + : public key_nodeptr_comp_types::base_t +{ +private: + struct sfinae_type; + +public: + typedef key_nodeptr_comp_types types_t; + typedef typename types_t::value_traits value_traits; + typedef typename types_t::value_type value_type; + typedef typename types_t::node_ptr node_ptr; + typedef typename types_t::const_node_ptr const_node_ptr; + typedef typename types_t::base_t base_t; + typedef typename types_t::key_of_value key_of_value; + + template + struct is_same_or_nodeptr_convertible + { + static const bool same_type = is_same::value || is_same::value; + static const bool value = same_type || is_convertible::value; + }; + + BOOST_INTRUSIVE_FORCEINLINE base_t base() const + { return static_cast(*this); } + + BOOST_INTRUSIVE_FORCEINLINE key_nodeptr_comp(KeyTypeKeyCompare kcomp, const ValueTraits *traits) + : base_t(kcomp), traits_(traits) + {} + + //pred(pnode) + template + BOOST_INTRUSIVE_FORCEINLINE bool operator()(const T1 &t1, typename enable_if_c< is_same_or_nodeptr_convertible::value, sfinae_type* >::type = 0) const + { return base().get()(key_of_value()(*traits_->to_value_ptr(t1))); } + + //operator() 2 arg + //pred(pnode, pnode) + template + BOOST_INTRUSIVE_FORCEINLINE bool operator() + (const T1 &t1, const T2 &t2, typename enable_if_c< is_same_or_nodeptr_convertible::value && is_same_or_nodeptr_convertible::value, sfinae_type* >::type = 0) const + { return base()(*traits_->to_value_ptr(t1), *traits_->to_value_ptr(t2)); } + + //pred(pnode, key) + template + BOOST_INTRUSIVE_FORCEINLINE bool operator() + (const T1 &t1, const T2 &t2, typename enable_if_c< is_same_or_nodeptr_convertible::value && !is_same_or_nodeptr_convertible::value, sfinae_type* >::type = 0) const + { return base()(*traits_->to_value_ptr(t1), t2); } + + //pred(key, pnode) + template + BOOST_INTRUSIVE_FORCEINLINE bool operator() + (const T1 &t1, const T2 &t2, typename enable_if_c< !is_same_or_nodeptr_convertible::value && is_same_or_nodeptr_convertible::value, sfinae_type* >::type = 0) const + { return base()(t1, *traits_->to_value_ptr(t2)); } + + //pred(key, key) + template + BOOST_INTRUSIVE_FORCEINLINE bool operator() + (const T1 &t1, const T2 &t2, typename enable_if_c< !is_same_or_nodeptr_convertible::value && !is_same_or_nodeptr_convertible::value, sfinae_type* >::type = 0) const + { return base()(t1, t2); } + + const ValueTraits *const traits_; +}; + +} //namespace detail{ +} //namespace intrusive{ +} //namespace boost{ + +#endif //BOOST_INTRUSIVE_DETAIL_KEY_NODEPTR_COMP_HPP diff --git a/third_party/boost/libs/intrusive/include/boost/intrusive/detail/list_iterator.hpp b/third_party/boost/libs/intrusive/include/boost/intrusive/detail/list_iterator.hpp new file mode 100644 index 00000000000..f301a4b8e77 --- /dev/null +++ b/third_party/boost/libs/intrusive/include/boost/intrusive/detail/list_iterator.hpp @@ -0,0 +1,146 @@ +///////////////////////////////////////////////////////////////////////////// +// +// (C) Copyright Olaf Krzikalla 2004-2006. +// (C) Copyright Ion Gaztanaga 2006-2013 +// +// 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_LIST_ITERATOR_HPP +#define BOOST_INTRUSIVE_LIST_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 { + +// list_iterator provides some basic functions for a +// node oriented bidirectional iterator: +template +class list_iterator +{ + private: + typedef iiterator + types_t; + + static const bool stateful_value_traits = types_t::stateful_value_traits; + + typedef ValueTraits value_traits; + typedef typename types_t::node_traits node_traits; + + typedef typename types_t::node node; + typedef typename types_t::node_ptr node_ptr; + typedef typename types_t::const_value_traits_ptr const_value_traits_ptr; + class nat; + typedef typename + detail::if_c< IsConst + , list_iterator + , nat>::type nonconst_iterator; + + 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; + + BOOST_INTRUSIVE_FORCEINLINE list_iterator() + {} + + BOOST_INTRUSIVE_FORCEINLINE explicit list_iterator(node_ptr nodeptr, const_value_traits_ptr traits_ptr) + : members_(nodeptr, traits_ptr) + {} + + BOOST_INTRUSIVE_FORCEINLINE list_iterator(const list_iterator &other) + : members_(other.pointed_node(), other.get_value_traits()) + {} + + BOOST_INTRUSIVE_FORCEINLINE list_iterator(const nonconst_iterator &other) + : members_(other.pointed_node(), other.get_value_traits()) + {} + + BOOST_INTRUSIVE_FORCEINLINE list_iterator &operator=(const list_iterator &other) + { members_.nodeptr_ = other.members_.nodeptr_; return *this; } + + BOOST_INTRUSIVE_FORCEINLINE node_ptr pointed_node() const + { return members_.nodeptr_; } + + 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(); } + + public: + BOOST_INTRUSIVE_FORCEINLINE list_iterator& operator++() + { + node_ptr p = node_traits::get_next(members_.nodeptr_); + members_.nodeptr_ = p; + return static_cast (*this); + } + + BOOST_INTRUSIVE_FORCEINLINE list_iterator operator++(int) + { + list_iterator result (*this); + members_.nodeptr_ = node_traits::get_next(members_.nodeptr_); + return result; + } + + BOOST_INTRUSIVE_FORCEINLINE list_iterator& operator--() + { + members_.nodeptr_ = node_traits::get_previous(members_.nodeptr_); + return static_cast (*this); + } + + BOOST_INTRUSIVE_FORCEINLINE list_iterator operator--(int) + { + list_iterator result (*this); + members_.nodeptr_ = node_traits::get_previous(members_.nodeptr_); + return result; + } + + BOOST_INTRUSIVE_FORCEINLINE friend bool operator== (const list_iterator& l, const list_iterator& r) + { return l.pointed_node() == r.pointed_node(); } + + BOOST_INTRUSIVE_FORCEINLINE friend bool operator!= (const list_iterator& l, const list_iterator& r) + { return !(l == r); } + + BOOST_INTRUSIVE_FORCEINLINE reference operator*() const + { return *operator->(); } + + BOOST_INTRUSIVE_FORCEINLINE pointer operator->() const + { return this->operator_arrow(detail::bool_()); } + + BOOST_INTRUSIVE_FORCEINLINE list_iterator unconst() const + { return list_iterator(this->pointed_node(), this->get_value_traits()); } + + private: + BOOST_INTRUSIVE_FORCEINLINE pointer operator_arrow(detail::false_) const + { return ValueTraits::to_value_ptr(members_.nodeptr_); } + + BOOST_INTRUSIVE_FORCEINLINE pointer operator_arrow(detail::true_) const + { return this->get_value_traits()->to_value_ptr(members_.nodeptr_); } + + iiterator_members members_; +}; + +} //namespace intrusive +} //namespace boost + +#endif //BOOST_INTRUSIVE_LIST_ITERATOR_HPP diff --git a/third_party/boost/libs/intrusive/include/boost/intrusive/detail/list_node.hpp b/third_party/boost/libs/intrusive/include/boost/intrusive/detail/list_node.hpp new file mode 100644 index 00000000000..eac56f6d4a2 --- /dev/null +++ b/third_party/boost/libs/intrusive/include/boost/intrusive/detail/list_node.hpp @@ -0,0 +1,72 @@ +///////////////////////////////////////////////////////////////////////////// +// +// (C) Copyright Olaf Krzikalla 2004-2006. +// (C) Copyright Ion Gaztanaga 2006-2013 +// +// 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_LIST_NODE_HPP +#define BOOST_INTRUSIVE_LIST_NODE_HPP + +#ifndef BOOST_CONFIG_HPP +# include +#endif + +#if defined(BOOST_HAS_PRAGMA_ONCE) +# pragma once +#endif + +#include +#include + +namespace boost { +namespace intrusive { + +// list_node_traits can be used with circular_list_algorithms and supplies +// a list_node holding the pointers needed for a double-linked list +// it is used by list_derived_node and list_member_node + +template +struct list_node +{ + typedef typename pointer_rebind::type node_ptr; + node_ptr next_; + node_ptr prev_; +}; + +template +struct list_node_traits +{ + typedef list_node node; + typedef typename node::node_ptr node_ptr; + typedef typename pointer_rebind::type const_node_ptr; + + BOOST_INTRUSIVE_FORCEINLINE static node_ptr get_previous(const_node_ptr n) + { return n->prev_; } + + 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_node_ptr n) + { return n->next_; } + + 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) + { n->next_ = next; } +}; + +} //namespace intrusive +} //namespace boost + +#endif //BOOST_INTRUSIVE_LIST_NODE_HPP diff --git a/third_party/boost/libs/intrusive/include/boost/intrusive/detail/math.hpp b/third_party/boost/libs/intrusive/include/boost/intrusive/detail/math.hpp new file mode 100644 index 00000000000..ff379f65897 --- /dev/null +++ b/third_party/boost/libs/intrusive/include/boost/intrusive/detail/math.hpp @@ -0,0 +1,242 @@ +///////////////////////////////////////////////////////////////////////////// +// +// (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_MATH_HPP +#define BOOST_INTRUSIVE_DETAIL_MATH_HPP + +#ifndef BOOST_CONFIG_HPP +# include +#endif + +#if defined(BOOST_HAS_PRAGMA_ONCE) +# pragma once +#endif + +#include +#include +#include +#include + +namespace boost { +namespace intrusive { +namespace detail { + +/////////////////////////// +// floor_log2 Dispatcher +//////////////////////////// + +#if defined(_MSC_VER) && (_MSC_VER >= 1300) + + }}} //namespace boost::intrusive::detail + + //Use _BitScanReverseXX intrinsics + + #if defined(_M_X64) || defined(_M_AMD64) || defined(_M_IA64) //64 bit target + #define BOOST_INTRUSIVE_BSR_INTRINSIC_64_BIT + #endif + + #ifndef __INTRIN_H_ // Avoid including any windows system header + #ifdef __cplusplus + extern "C" { + #endif // __cplusplus + + #if defined(BOOST_INTRUSIVE_BSR_INTRINSIC_64_BIT) //64 bit target + unsigned char _BitScanReverse64(unsigned long *index, unsigned __int64 mask); + #pragma intrinsic(_BitScanReverse64) + #else //32 bit target + unsigned char _BitScanReverse(unsigned long *index, unsigned long mask); + #pragma intrinsic(_BitScanReverse) + #endif + + #ifdef __cplusplus + } + #endif // __cplusplus + #endif // __INTRIN_H_ + + #ifdef BOOST_INTRUSIVE_BSR_INTRINSIC_64_BIT + #define BOOST_INTRUSIVE_BSR_INTRINSIC _BitScanReverse64 + #undef BOOST_INTRUSIVE_BSR_INTRINSIC_64_BIT + #else + #define BOOST_INTRUSIVE_BSR_INTRINSIC _BitScanReverse + #endif + + namespace boost { + namespace intrusive { + namespace detail { + + inline std::size_t floor_log2 (std::size_t x) + { + unsigned long log2; + BOOST_INTRUSIVE_BSR_INTRINSIC( &log2, x ); + return static_cast(log2); + } + + #undef BOOST_INTRUSIVE_BSR_INTRINSIC + +#elif defined(__GNUC__) && ((__GNUC__ >= 4) || (__GNUC__ == 3 && __GNUC_MINOR__ >= 4)) //GCC >=3.4 + + //Compile-time error in case of missing specialization + template + struct builtin_clz_dispatch; + + #if defined(BOOST_HAS_LONG_LONG) + template<> + struct builtin_clz_dispatch< ::boost::ulong_long_type > + { + static ::boost::ulong_long_type call(::boost::ulong_long_type n) + { return (::boost::ulong_long_type)__builtin_clzll(n); } + }; + #endif + + template<> + struct builtin_clz_dispatch + { + static unsigned long call(unsigned long n) + { return (unsigned long)__builtin_clzl(n); } + }; + + template<> + struct builtin_clz_dispatch + { + static unsigned int call(unsigned int n) + { return (unsigned int)__builtin_clz(n); } + }; + + inline std::size_t floor_log2(std::size_t n) + { + return sizeof(std::size_t)*CHAR_BIT - std::size_t(1) - builtin_clz_dispatch::call(n); + } + +#else //Portable methods + +//////////////////////////// +// Generic method +//////////////////////////// + + inline std::size_t floor_log2_get_shift(std::size_t n, true_ )//power of two size_t + { return n >> 1; } + + inline std::size_t floor_log2_get_shift(std::size_t n, false_ )//non-power of two size_t + { return (n >> 1) + ((n & 1u) & (n != 1)); } + + template + inline std::size_t floor_log2 (std::size_t x, integral_constant) + { + const std::size_t Bits = N; + const bool Size_t_Bits_Power_2= !(Bits & (Bits-1)); + + std::size_t n = x; + std::size_t log2 = 0; + + std::size_t remaining_bits = Bits; + std::size_t shift = floor_log2_get_shift(remaining_bits, bool_()); + while(shift){ + std::size_t tmp = n >> shift; + if (tmp){ + log2 += shift, n = tmp; + } + shift = floor_log2_get_shift(shift, bool_()); + } + + return log2; + } + + inline std::size_t floor_log2 (std::size_t x) + { + const std::size_t Bits = sizeof(std::size_t)*CHAR_BIT; + return floor_log2(x, integral_constant()); + } + +#endif + +//Thanks to Laurent de Soras in +//http://www.flipcode.com/archives/Fast_log_Function.shtml +inline float fast_log2 (float val) +{ + unsigned x; + 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(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 + val = ((-1.f/3.f) * val + 2.f) * val - (2.f/3.f); + return val + static_cast(log_2); +} + +inline bool is_pow2(std::size_t x) +{ return (x & (x-1)) == 0; } + +template +struct static_is_pow2 +{ + static const bool value = (N & (N-1)) == 0; +}; + +inline std::size_t ceil_log2 (std::size_t x) +{ + return static_cast(!(is_pow2)(x)) + floor_log2(x); +} + +inline std::size_t ceil_pow2 (std::size_t x) +{ + return std::size_t(1u) << (ceil_log2)(x); +} + +inline std::size_t previous_or_equal_pow2(std::size_t x) +{ + return std::size_t(1u) << floor_log2(x); +} + +template +struct numbits_eq +{ + static const bool value = sizeof(SizeType)*CHAR_BIT == N; +}; + +template +struct sqrt2_pow_max; + +template +struct sqrt2_pow_max >::type>::type> +{ + static const SizeType value = 0xb504f334; + static const std::size_t pow = 31; +}; + +#ifndef BOOST_NO_INT64_T + +template +struct sqrt2_pow_max >::type>::type> +{ + static const SizeType value = 0xb504f333f9de6484ull; + static const std::size_t pow = 63; +}; + +#endif //BOOST_NO_INT64_T + +// Returns floor(pow(sqrt(2), x * 2 + 1)). +// Defined for X from 0 up to the number of bits in size_t minus 1. +inline std::size_t sqrt2_pow_2xplus1 (std::size_t x) +{ + const std::size_t value = (std::size_t)sqrt2_pow_max::value; + const std::size_t pow = (std::size_t)sqrt2_pow_max::pow; + return (value >> (pow - x)) + 1; +} + +} //namespace detail +} //namespace intrusive +} //namespace boost + +#endif //BOOST_INTRUSIVE_DETAIL_MATH_HPP diff --git a/third_party/boost/libs/intrusive/include/boost/intrusive/detail/minimal_less_equal_header.hpp b/third_party/boost/libs/intrusive/include/boost/intrusive/detail/minimal_less_equal_header.hpp new file mode 100644 index 00000000000..5e8a19debf9 --- /dev/null +++ b/third_party/boost/libs/intrusive/include/boost/intrusive/detail/minimal_less_equal_header.hpp @@ -0,0 +1,30 @@ +///////////////////////////////////////////////////////////////////////////// +// +// (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/intrusive for documentation. +// +///////////////////////////////////////////////////////////////////////////// +#ifndef BOOST_INTRUSIVE_DETAIL_MINIMAL_LESS_EQUAL_HEADER_HPP +#define BOOST_INTRUSIVE_DETAIL_MINIMAL_LESS_EQUAL_HEADER_HPP +# +#ifndef BOOST_CONFIG_HPP +# include +#endif +# +#if defined(BOOST_HAS_PRAGMA_ONCE) +# pragma once +#endif +# +#//Try to avoid including , as it's quite big in C++11 +#if defined(BOOST_GNU_STDLIB) +# include +#else +# include //Fallback +#endif +# +#endif //BOOST_INTRUSIVE_DETAIL_MINIMAL_LESS_EQUAL_HEADER_HPP diff --git a/third_party/boost/libs/intrusive/include/boost/intrusive/detail/minimal_pair_header.hpp b/third_party/boost/libs/intrusive/include/boost/intrusive/detail/minimal_pair_header.hpp new file mode 100644 index 00000000000..1358a085881 --- /dev/null +++ b/third_party/boost/libs/intrusive/include/boost/intrusive/detail/minimal_pair_header.hpp @@ -0,0 +1,30 @@ +///////////////////////////////////////////////////////////////////////////// +// +// (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/intrusive for documentation. +// +///////////////////////////////////////////////////////////////////////////// +#ifndef BOOST_INTRUSIVE_DETAIL_MINIMAL_PAIR_HEADER_HPP +#define BOOST_INTRUSIVE_DETAIL_MINIMAL_PAIR_HEADER_HPP +# +#if defined(BOOST_HAS_PRAGMA_ONCE) +# pragma once +#endif +# +#ifndef BOOST_CONFIG_HPP +# include +#endif +# +#//Try to avoid including , as it's quite big in C++11 +#if defined(BOOST_GNU_STDLIB) +# include +#else +# include //Fallback +#endif +# +#endif //BOOST_INTRUSIVE_DETAIL_MINIMAL_PAIR_HEADER_HPP diff --git a/third_party/boost/libs/intrusive/include/boost/intrusive/detail/mpl.hpp b/third_party/boost/libs/intrusive/include/boost/intrusive/detail/mpl.hpp new file mode 100644 index 00000000000..d86fa4f3c96 --- /dev/null +++ b/third_party/boost/libs/intrusive/include/boost/intrusive/detail/mpl.hpp @@ -0,0 +1,217 @@ +///////////////////////////////////////////////////////////////////////////// +// +// (C) Copyright Ion Gaztanaga 2006-2014 +// (C) Copyright Microsoft Corporation 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_MPL_HPP +#define BOOST_INTRUSIVE_DETAIL_MPL_HPP + +#ifndef BOOST_CONFIG_HPP +# include +#endif + +#if defined(BOOST_HAS_PRAGMA_ONCE) +# pragma once +#endif + +#include +#include +#include + +namespace boost { +namespace intrusive { +namespace detail { + +using boost::move_detail::is_same; +using boost::move_detail::add_const; +using boost::move_detail::remove_const; +using boost::move_detail::remove_cv; +using boost::move_detail::remove_reference; +using boost::move_detail::add_reference; +using boost::move_detail::remove_pointer; +using boost::move_detail::add_pointer; +using boost::move_detail::true_type; +using boost::move_detail::false_type; +using boost::move_detail::voider; +using boost::move_detail::enable_if_c; +using boost::move_detail::enable_if; +using boost::move_detail::disable_if_c; +using boost::move_detail::disable_if; +using boost::move_detail::is_convertible; +using boost::move_detail::if_c; +using boost::move_detail::if_; +using boost::move_detail::is_const; +using boost::move_detail::identity; +using boost::move_detail::alignment_of; +using boost::move_detail::is_empty; +using boost::move_detail::addressof; +using boost::move_detail::integral_constant; +using boost::move_detail::enable_if_convertible; +using boost::move_detail::disable_if_convertible; +using boost::move_detail::bool_; +using boost::move_detail::true_; +using boost::move_detail::false_; +using boost::move_detail::yes_type; +using boost::move_detail::no_type; +using boost::move_detail::apply; +using boost::move_detail::eval_if_c; +using boost::move_detail::eval_if; +using boost::move_detail::unvoid_ref; +using boost::move_detail::add_const_if_c; + +template +struct ls_zeros +{ + static const std::size_t value = (S & std::size_t(1)) ? 0 : (1 + ls_zeros<(S>>1u)>::value); +}; + +template<> +struct ls_zeros<0> +{ + static const std::size_t value = 0; +}; + +template<> +struct ls_zeros<1> +{ + static const std::size_t value = 0; +}; + +// Infrastructure for providing a default type for T::TNAME if absent. +#define BOOST_INTRUSIVE_INSTANTIATE_DEFAULT_TYPE_TMPLT(TNAME) \ + template \ + struct boost_intrusive_has_type_ ## TNAME \ + { \ + template \ + static char test(int, typename X::TNAME*); \ + \ + template \ + static int test(...); \ + \ + static const bool value = (1 == sizeof(test(0, 0))); \ + }; \ + \ + template \ + struct boost_intrusive_default_type_ ## TNAME \ + { \ + struct DefaultWrap { typedef DefaultType TNAME; }; \ + \ + typedef typename \ + ::boost::intrusive::detail::if_c \ + < boost_intrusive_has_type_ ## TNAME::value \ + , T, DefaultWrap>::type::TNAME type; \ + }; \ + // + +#define BOOST_INTRUSIVE_OBTAIN_TYPE_WITH_DEFAULT(INSTANTIATION_NS_PREFIX, T, TNAME, TIMPL) \ + typename INSTANTIATION_NS_PREFIX \ + boost_intrusive_default_type_ ## TNAME< T, TIMPL >::type \ +// + +#define BOOST_INTRUSIVE_HAS_TYPE(INSTANTIATION_NS_PREFIX, T, TNAME) \ + INSTANTIATION_NS_PREFIX \ + boost_intrusive_has_type_ ## TNAME< T >::value \ +// + +#define BOOST_INTRUSIVE_INSTANTIATE_EVAL_DEFAULT_TYPE_TMPLT(TNAME)\ + template \ + struct boost_intrusive_eval_default_type_ ## TNAME \ + { \ + template \ + static char test(int, typename X::TNAME*); \ + \ + template \ + static int test(...); \ + \ + struct DefaultWrap \ + { typedef typename DefaultType::type TNAME; }; \ + \ + static const bool value = (1 == sizeof(test(0, 0))); \ + \ + typedef typename \ + ::boost::intrusive::detail::eval_if_c \ + < value \ + , ::boost::intrusive::detail::identity \ + , ::boost::intrusive::detail::identity \ + >::type::TNAME type; \ + }; \ +// + +#define BOOST_INTRUSIVE_OBTAIN_TYPE_WITH_EVAL_DEFAULT(INSTANTIATION_NS_PREFIX, T, TNAME, TIMPL) \ + typename INSTANTIATION_NS_PREFIX \ + boost_intrusive_eval_default_type_ ## TNAME< T, TIMPL >::type \ +// + +#define BOOST_INTRUSIVE_INTERNAL_STATIC_BOOL_IS_TRUE(TRAITS_PREFIX, TYPEDEF_TO_FIND) \ +template \ +struct TRAITS_PREFIX##_bool\ +{\ + template\ + 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));\ +};\ +\ +template \ +struct TRAITS_PREFIX##_bool_is_true\ +{\ + static const bool value = TRAITS_PREFIX##_bool::value > sizeof(yes_type)*2;\ +};\ +// + +#define BOOST_INTRUSIVE_HAS_STATIC_MEMBER_FUNC_SIGNATURE(TRAITS_NAME, FUNC_NAME) \ + template \ + class TRAITS_NAME \ + { \ + private: \ + template struct helper;\ + template \ + static ::boost::intrusive::detail::yes_type test(helper<&T::FUNC_NAME>*); \ + template static ::boost::intrusive::detail::no_type test(...); \ + public: \ + static const bool value = sizeof(test(0)) == sizeof(::boost::intrusive::detail::yes_type); \ + }; \ +// + +#define BOOST_INTRUSIVE_HAS_MEMBER_FUNC_CALLED(TRAITS_NAME, FUNC_NAME) \ +template \ +struct TRAITS_NAME \ +{ \ + struct BaseMixin \ + { \ + void FUNC_NAME(); \ + }; \ + struct Base : public Type, public BaseMixin { Base(); }; \ + template class Helper{}; \ + template \ + static ::boost::intrusive::detail::no_type test(U*, Helper* = 0); \ + static ::boost::intrusive::detail::yes_type test(...); \ + static const bool value = sizeof(::boost::intrusive::detail::yes_type) == sizeof(test((Base*)(0))); \ +};\ +// + +#define BOOST_INTRUSIVE_HAS_MEMBER_FUNC_CALLED_IGNORE_SIGNATURE(TRAITS_NAME, FUNC_NAME) \ +BOOST_INTRUSIVE_HAS_MEMBER_FUNC_CALLED(TRAITS_NAME##_ignore_signature, FUNC_NAME) \ +\ +template \ +struct TRAITS_NAME \ + : public TRAITS_NAME##_ignore_signature \ +{};\ +// + +} //namespace detail +} //namespace intrusive +} //namespace boost + +#include + +#endif //BOOST_INTRUSIVE_DETAIL_MPL_HPP diff --git a/third_party/boost/libs/intrusive/include/boost/intrusive/detail/node_cloner_disposer.hpp b/third_party/boost/libs/intrusive/include/boost/intrusive/detail/node_cloner_disposer.hpp new file mode 100644 index 00000000000..97e8d153261 --- /dev/null +++ b/third_party/boost/libs/intrusive/include/boost/intrusive/detail/node_cloner_disposer.hpp @@ -0,0 +1,105 @@ +///////////////////////////////////////////////////////////////////////////// +// +// (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_NODE_CLONER_DISPOSER_HPP +#define BOOST_INTRUSIVE_DETAIL_NODE_CLONER_DISPOSER_HPP + +#ifndef BOOST_CONFIG_HPP +# include +#endif + +#if defined(BOOST_HAS_PRAGMA_ONCE) +# pragma once +#endif + +#include +#include +#include +#include +#include + +namespace boost { +namespace intrusive { +namespace detail { + +template +struct node_cloner + //Use public inheritance to avoid MSVC bugs with closures + : public ebo_functor_holder +{ + typedef ValueTraits value_traits; + typedef typename value_traits::node_traits node_traits; + typedef typename node_traits::node_ptr node_ptr; + typedef ebo_functor_holder base_t; + typedef typename get_algo< AlgoType + , node_traits>::type node_algorithms; + static const bool safemode_or_autounlink = + is_safe_autounlink::value; + typedef typename value_traits::value_type value_type; + typedef typename value_traits::pointer pointer; + typedef typename value_traits::const_pointer const_pointer; + typedef typename node_traits::node node; + typedef typename value_traits::const_node_ptr const_node_ptr; + typedef typename pointer_traits::reference reference; + typedef typename pointer_traits + ::reference const_reference; + typedef typename if_c::type reference_type; + + node_cloner(F f, const ValueTraits *traits) + : base_t(f), traits_(traits) + {} + + // tree-based containers use this method, which is proxy-reference friendly + 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)); + //Cloned node must be in default mode if the linking mode requires it + BOOST_INTRUSIVE_SAFE_HOOK_DEFAULT_ASSERT(!safemode_or_autounlink || node_algorithms::unique(n)); + return n; + } + + const ValueTraits * const traits_; +}; + +template +struct node_disposer + //Use public inheritance to avoid MSVC bugs with closures + : public ebo_functor_holder +{ + typedef ValueTraits value_traits; + typedef typename value_traits::node_traits node_traits; + typedef typename node_traits::node_ptr node_ptr; + typedef ebo_functor_holder base_t; + typedef typename get_algo< AlgoType + , node_traits>::type node_algorithms; + static const bool safemode_or_autounlink = + is_safe_autounlink::value; + + BOOST_INTRUSIVE_FORCEINLINE node_disposer(F f, const ValueTraits *cont) + : base_t(f), traits_(cont) + {} + + BOOST_INTRUSIVE_FORCEINLINE void operator()(node_ptr p) + { + BOOST_IF_CONSTEXPR(safemode_or_autounlink) + node_algorithms::init(p); + base_t::get()(traits_->to_value_ptr(p)); + } + const ValueTraits * const traits_; +}; + +} //namespace detail{ +} //namespace intrusive{ +} //namespace boost{ + +#endif //BOOST_INTRUSIVE_DETAIL_NODE_CLONER_DISPOSER_HPP diff --git a/third_party/boost/libs/intrusive/include/boost/intrusive/detail/node_holder.hpp b/third_party/boost/libs/intrusive/include/boost/intrusive/detail/node_holder.hpp new file mode 100644 index 00000000000..b8dabef2dfa --- /dev/null +++ b/third_party/boost/libs/intrusive/include/boost/intrusive/detail/node_holder.hpp @@ -0,0 +1,35 @@ +///////////////////////////////////////////////////////////////////////////// +// +// (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_NODE_HOLDER_HPP +#define BOOST_INTRUSIVE_DETAIL_NODE_HOLDER_HPP + +#ifndef BOOST_CONFIG_HPP +# include +#endif + +#if defined(BOOST_HAS_PRAGMA_ONCE) +# pragma once +#endif + +namespace boost { +namespace intrusive { + +template +struct node_holder + : public Node +{}; + +} //namespace intrusive{ +} //namespace boost{ + +#endif //BOOST_INTRUSIVE_DETAIL_NODE_HOLDER_HPP diff --git a/third_party/boost/libs/intrusive/include/boost/intrusive/detail/node_to_value.hpp b/third_party/boost/libs/intrusive/include/boost/intrusive/detail/node_to_value.hpp new file mode 100644 index 00000000000..3085e0c3a62 --- /dev/null +++ b/third_party/boost/libs/intrusive/include/boost/intrusive/detail/node_to_value.hpp @@ -0,0 +1,130 @@ +///////////////////////////////////////////////////////////////////////////// +// +// (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_NODE_TO_VALUE_HPP +#define BOOST_INTRUSIVE_DETAIL_NODE_TO_VALUE_HPP + +#ifndef BOOST_CONFIG_HPP +# include +#endif + +#if defined(BOOST_HAS_PRAGMA_ONCE) +# pragma once +#endif + +#include +#include +#include + +namespace boost { +namespace intrusive { +namespace detail { + +template +struct dummy_constptr +{ + typedef typename boost::intrusive::pointer_traits:: + template rebind_pointer::type ConstVoidPtr; + + explicit dummy_constptr(ConstVoidPtr) + {} + + dummy_constptr() + {} + + ConstVoidPtr get_ptr() const + { return ConstVoidPtr(); } +}; + +template +struct constptr +{ + typedef typename boost::intrusive::pointer_traits:: + template rebind_pointer::type ConstVoidPtr; + + constptr() + {} + + explicit constptr(const ConstVoidPtr &ptr) + : const_void_ptr_(ptr) + {} + + const void *get_ptr() const + { return boost::movelib::to_raw_pointer(const_void_ptr_); } + + ConstVoidPtr const_void_ptr_; +}; + +template +struct select_constptr +{ + typedef typename if_c + < store_ptr + , constptr + , dummy_constptr + >::type type; +}; + + +template +struct node_to_value + : public select_constptr + < typename pointer_traits + ::template rebind_pointer::type + , is_stateful_value_traits::value + >::type +{ + static const bool stateful_value_traits = is_stateful_value_traits::value; + typedef typename select_constptr + < typename pointer_traits + :: + template rebind_pointer::type + , stateful_value_traits >::type Base; + + typedef ValueTraits value_traits; + typedef typename value_traits::value_type value_type; + typedef typename value_traits::node_traits::node node; + typedef typename add_const_if_c + ::type vtype; + typedef typename add_const_if_c + ::type ntype; + typedef typename pointer_traits + :: + template rebind_pointer::type npointer; + typedef typename pointer_traits:: + template rebind_pointer::type const_value_traits_ptr; + + node_to_value(const_value_traits_ptr ptr) + : Base(ptr) + {} + + typedef vtype & result_type; + typedef ntype & first_argument_type; + + const_value_traits_ptr get_value_traits() const + { return pointer_traits::static_cast_from(Base::get_ptr()); } + + result_type to_value(first_argument_type arg, false_) const + { return *(value_traits::to_value_ptr(pointer_traits::pointer_to(arg))); } + + result_type to_value(first_argument_type arg, true_) const + { return *(this->get_value_traits()->to_value_ptr(pointer_traits::pointer_to(arg))); } + + result_type operator()(first_argument_type arg) const + { return this->to_value(arg, bool_()); } +}; + +} //namespace detail{ +} //namespace intrusive{ +} //namespace boost{ + +#endif //BOOST_INTRUSIVE_DETAIL_NODE_TO_VALUE_HPP diff --git a/third_party/boost/libs/intrusive/include/boost/intrusive/detail/parent_from_member.hpp b/third_party/boost/libs/intrusive/include/boost/intrusive/detail/parent_from_member.hpp new file mode 100644 index 00000000000..275229ab474 --- /dev/null +++ b/third_party/boost/libs/intrusive/include/boost/intrusive/detail/parent_from_member.hpp @@ -0,0 +1,121 @@ +///////////////////////////////////////////////////////////////////////////// +// +// (C) Copyright Ion Gaztanaga 2007-2013 +// +// 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_PARENT_FROM_MEMBER_HPP +#define BOOST_INTRUSIVE_DETAIL_PARENT_FROM_MEMBER_HPP + +#ifndef BOOST_CONFIG_HPP +# include +#endif + +#if defined(BOOST_HAS_PRAGMA_ONCE) +# pragma once +#endif + +#include +#include +#include + +#if defined(_MSC_VER) + #define BOOST_INTRUSIVE_MSVC_ABI_PTR_TO_MEMBER + #include +#endif + +namespace boost { +namespace intrusive { +namespace detail { + +template +BOOST_INTRUSIVE_FORCEINLINE std::ptrdiff_t offset_from_pointer_to_member(const Member Parent::* ptr_to_member) +{ + //The implementation of a pointer to member is compiler dependent. + #if defined(BOOST_INTRUSIVE_MSVC_ABI_PTR_TO_MEMBER) + + //MSVC compliant compilers use their the first 32 bits as offset (even in 64 bit mode) + union caster_union + { + const Member Parent::* ptr_to_member; + int offset; + } caster; + + //MSVC ABI can use up to 3 int32 to represent pointer to member data + //with virtual base classes, in those cases there is no simple to + //obtain the address of the parent. So static assert to avoid runtime errors + BOOST_STATIC_ASSERT( sizeof(caster) == sizeof(int) ); + + caster.ptr_to_member = ptr_to_member; + return std::ptrdiff_t(caster.offset); + //Additional info on MSVC behaviour for the future. For 2/3 int ptr-to-member + //types dereference seems to be: + // + // vboffset = [compile_time_offset if 2-int ptr2memb] / + // [ptr2memb.i32[2] if 3-int ptr2memb]. + // vbtable = *(this + vboffset); + // adj = vbtable[ptr2memb.i32[1]]; + // var = adj + (this + vboffset) + ptr2memb.i32[0]; + // + //To reverse the operation we need to + // - obtain vboffset (in 2-int ptr2memb implementation only) + // - Go to Parent's vbtable and obtain adjustment at index ptr2memb.i32[1] + // - parent = member - adj - vboffset - ptr2memb.i32[0] + // + //Even accessing to RTTI we might not be able to obtain this information + //so anyone who thinks it's possible, please send a patch. + + //This works with gcc, msvc, ac++, ibmcpp + #elif defined(__GNUC__) || defined(__HP_aCC) || defined(BOOST_INTEL) || \ + defined(__IBMCPP__) || defined(__DECCXX) + const Parent * const parent = 0; + const char *const member = static_cast(static_cast(&(parent->*ptr_to_member))); + return std::ptrdiff_t(member - static_cast(static_cast(parent))); + #else + //This is the traditional C-front approach: __MWERKS__, __DMC__, __SUNPRO_CC + union caster_union + { + const Member Parent::* ptr_to_member; + std::ptrdiff_t offset; + } caster; + caster.ptr_to_member = ptr_to_member; + return caster.offset - 1; + #endif +} + +template +BOOST_INTRUSIVE_FORCEINLINE Parent *parent_from_member(Member *member, const Member Parent::* ptr_to_member) +{ + return static_cast + ( + static_cast + ( + static_cast(static_cast(member)) - offset_from_pointer_to_member(ptr_to_member) + ) + ); +} + +template +BOOST_INTRUSIVE_FORCEINLINE const Parent *parent_from_member(const Member *member, const Member Parent::* ptr_to_member) +{ + return static_cast + ( + static_cast + ( + static_cast(static_cast(member)) - offset_from_pointer_to_member(ptr_to_member) + ) + ); +} + +} //namespace detail { +} //namespace intrusive { +} //namespace boost { + +#include + +#endif //#ifndef BOOST_INTRUSIVE_DETAIL_PARENT_FROM_MEMBER_HPP diff --git a/third_party/boost/libs/intrusive/include/boost/intrusive/detail/rbtree_node.hpp b/third_party/boost/libs/intrusive/include/boost/intrusive/detail/rbtree_node.hpp new file mode 100644 index 00000000000..07811991cb4 --- /dev/null +++ b/third_party/boost/libs/intrusive/include/boost/intrusive/detail/rbtree_node.hpp @@ -0,0 +1,205 @@ +///////////////////////////////////////////////////////////////////////////// +// +// (C) Copyright Olaf Krzikalla 2004-2006. +// (C) Copyright Ion Gaztanaga 2006-2013. +// +// 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_RBTREE_NODE_HPP +#define BOOST_INTRUSIVE_RBTREE_NODE_HPP + +#ifndef BOOST_CONFIG_HPP +# include +#endif + +#if defined(BOOST_HAS_PRAGMA_ONCE) +# pragma once +#endif + +#include +#include +#include +#include +#include +#include +#include + +namespace boost { +namespace intrusive { + +///////////////////////////////////////////////////////////////////////////// +// // +// Generic node_traits for any pointer type // +// // +///////////////////////////////////////////////////////////////////////////// + +//This is the compact representation: 3 pointers +template +struct compact_rbtree_node +{ + typedef compact_rbtree_node node; + typedef typename pointer_rebind::type node_ptr; + typedef typename pointer_rebind::type const_node_ptr; + enum color { red_t, black_t }; + node_ptr parent_, left_, right_; +}; + +//This is the normal representation: 3 pointers + enum +template +struct rbtree_node +{ + typedef rbtree_node node; + typedef typename pointer_rebind::type node_ptr; + typedef typename pointer_rebind::type const_node_ptr; + + enum color { red_t, black_t }; + node_ptr parent_, left_, right_; + color color_; +}; + +//This is the default node traits implementation +//using a node with 3 generic pointers plus an enum +template +struct default_rbtree_node_traits_impl +{ + typedef rbtree_node node; + typedef typename node::node_ptr node_ptr; + typedef typename node::const_node_ptr const_node_ptr; + + typedef typename node::color color; + + BOOST_INTRUSIVE_FORCEINLINE static node_ptr get_parent(const_node_ptr n) + { return n->parent_; } + + 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_node_ptr n) + { return n->left_; } + + 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_node_ptr n) + { return n->right_; } + + 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_node_ptr n) + { return n->color_; } + + BOOST_INTRUSIVE_FORCEINLINE static color get_color(node_ptr n) + { return n->color_; } + + BOOST_INTRUSIVE_FORCEINLINE static void set_color(node_ptr n, color c) + { n->color_ = c; } + + BOOST_INTRUSIVE_FORCEINLINE static color black() + { return node::black_t; } + + BOOST_INTRUSIVE_FORCEINLINE static color red() + { return node::red_t; } +}; + +//This is the compact node traits implementation +//using a node with 3 generic pointers +template +struct compact_rbtree_node_traits_impl +{ + typedef compact_rbtree_node node; + typedef typename node::node_ptr node_ptr; + typedef typename node::const_node_ptr const_node_ptr; + + typedef pointer_plus_bits ptr_bit; + + typedef typename node::color color; + + 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(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_node_ptr n) + { return n->left_; } + + 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_node_ptr n) + { return n->right_; } + + 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_node_ptr n) + { return (color)ptr_bit::get_bits(n->parent_); } + + 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(node_ptr n, color c) + { ptr_bit::set_bits(n->parent_, c != 0); } + + BOOST_INTRUSIVE_FORCEINLINE static color black() + { return node::black_t; } + + BOOST_INTRUSIVE_FORCEINLINE static color red() + { return node::red_t; } +}; + +//Dispatches the implementation based on the boolean +template +struct rbtree_node_traits_dispatch + : public default_rbtree_node_traits_impl +{}; + +template +struct rbtree_node_traits_dispatch + : public compact_rbtree_node_traits_impl +{}; + +//Inherit from rbtree_node_traits_dispatch depending on the embedding capabilities +template +struct rbtree_node_traits + : public rbtree_node_traits_dispatch + < VoidPointer + , OptimizeSize && + (max_pointer_plus_bits + < VoidPointer + , detail::alignment_of >::value + >::value >= 1) + > +{}; + +} //namespace intrusive +} //namespace boost + +#include + +#endif //BOOST_INTRUSIVE_RBTREE_NODE_HPP diff --git a/third_party/boost/libs/intrusive/include/boost/intrusive/detail/reverse_iterator.hpp b/third_party/boost/libs/intrusive/include/boost/intrusive/detail/reverse_iterator.hpp new file mode 100644 index 00000000000..00b0e5f3535 --- /dev/null +++ b/third_party/boost/libs/intrusive/include/boost/intrusive/detail/reverse_iterator.hpp @@ -0,0 +1,28 @@ +///////////////////////////////////////////////////////////////////////////// +// +// (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_REVERSE_ITERATOR_HPP +#define BOOST_INTRUSIVE_DETAIL_REVERSE_ITERATOR_HPP + +#include + +namespace boost { +namespace intrusive { + +using boost::movelib::reverse_iterator; +using boost::movelib::make_reverse_iterator; + +} //namespace intrusive { +} //namespace boost { + + +#endif //BOOST_INTRUSIVE_DETAIL_REVERSE_ITERATOR_HPP diff --git a/third_party/boost/libs/intrusive/include/boost/intrusive/detail/simple_disposers.hpp b/third_party/boost/libs/intrusive/include/boost/intrusive/detail/simple_disposers.hpp new file mode 100644 index 00000000000..6b9bd4bc637 --- /dev/null +++ b/third_party/boost/libs/intrusive/include/boost/intrusive/detail/simple_disposers.hpp @@ -0,0 +1,52 @@ +///////////////////////////////////////////////////////////////////////////// +// +// (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_SIMPLE_DISPOSERS_HPP +#define BOOST_INTRUSIVE_DETAIL_SIMPLE_DISPOSERS_HPP + +#include + +#ifndef BOOST_CONFIG_HPP +# include +#endif + +#if defined(BOOST_HAS_PRAGMA_ONCE) +# pragma once +#endif + +namespace boost { +namespace intrusive { +namespace detail { + +class null_disposer +{ + public: + template + void operator()(Pointer) + {} +}; + +template +class init_disposer +{ + typedef typename NodeAlgorithms::node_ptr node_ptr; + + public: + BOOST_INTRUSIVE_FORCEINLINE void operator()(node_ptr p) + { NodeAlgorithms::init(p); } +}; + +} //namespace detail{ +} //namespace intrusive{ +} //namespace boost{ + +#endif //BOOST_INTRUSIVE_DETAIL_SIMPLE_DISPOSERS_HPP diff --git a/third_party/boost/libs/intrusive/include/boost/intrusive/detail/size_holder.hpp b/third_party/boost/libs/intrusive/include/boost/intrusive/detail/size_holder.hpp new file mode 100644 index 00000000000..bd14dc50499 --- /dev/null +++ b/third_party/boost/libs/intrusive/include/boost/intrusive/detail/size_holder.hpp @@ -0,0 +1,91 @@ +///////////////////////////////////////////////////////////////////////////// +// +// (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_SIZE_HOLDER_HPP +#define BOOST_INTRUSIVE_DETAIL_SIZE_HOLDER_HPP + +#ifndef BOOST_CONFIG_HPP +# include +#endif + +#if defined(BOOST_HAS_PRAGMA_ONCE) +# pragma once +#endif + +#include + +namespace boost { +namespace intrusive { +namespace detail { + +template +struct size_holder +{ + static const bool constant_time_size = ConstantSize; + typedef SizeType size_type; + + BOOST_INTRUSIVE_FORCEINLINE SizeType get_size() const + { return size_; } + + BOOST_INTRUSIVE_FORCEINLINE void set_size(SizeType size) + { size_ = size; } + + BOOST_INTRUSIVE_FORCEINLINE void decrement() + { --size_; } + + BOOST_INTRUSIVE_FORCEINLINE void increment() + { ++size_; } + + BOOST_INTRUSIVE_FORCEINLINE void increase(SizeType n) + { size_ += n; } + + BOOST_INTRUSIVE_FORCEINLINE void decrease(SizeType n) + { size_ -= n; } + + BOOST_INTRUSIVE_FORCEINLINE void swap(size_holder &other) + { SizeType tmp(size_); size_ = other.size_; other.size_ = tmp; } + + SizeType size_; +}; + +template +struct size_holder +{ + static const bool constant_time_size = false; + typedef SizeType size_type; + + BOOST_INTRUSIVE_FORCEINLINE size_type get_size() const + { return 0; } + + BOOST_INTRUSIVE_FORCEINLINE void set_size(size_type) + {} + + BOOST_INTRUSIVE_FORCEINLINE void decrement() + {} + + BOOST_INTRUSIVE_FORCEINLINE void increment() + {} + + BOOST_INTRUSIVE_FORCEINLINE void increase(SizeType) + {} + + BOOST_INTRUSIVE_FORCEINLINE void decrease(SizeType) + {} + + BOOST_INTRUSIVE_FORCEINLINE void swap(size_holder){} +}; + +} //namespace detail{ +} //namespace intrusive{ +} //namespace boost{ + +#endif //BOOST_INTRUSIVE_DETAIL_SIZE_HOLDER_HPP diff --git a/third_party/boost/libs/intrusive/include/boost/intrusive/detail/slist_iterator.hpp b/third_party/boost/libs/intrusive/include/boost/intrusive/detail/slist_iterator.hpp new file mode 100644 index 00000000000..9c5ee274708 --- /dev/null +++ b/third_party/boost/libs/intrusive/include/boost/intrusive/detail/slist_iterator.hpp @@ -0,0 +1,145 @@ +///////////////////////////////////////////////////////////////////////////// +// +// (C) Copyright Olaf Krzikalla 2004-2006. +// (C) Copyright Ion Gaztanaga 2006-2013 +// +// 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_SLIST_ITERATOR_HPP +#define BOOST_INTRUSIVE_SLIST_ITERATOR_HPP + +#ifndef BOOST_CONFIG_HPP +# include +#endif + +#if defined(BOOST_HAS_PRAGMA_ONCE) +# pragma once +#endif + +#include +#include +#include +#include +#include +#include + +namespace boost { +namespace intrusive { + + +// slist_iterator provides some basic functions for a +// node oriented bidirectional iterator: +template +class slist_iterator +{ + private: + typedef iiterator + types_t; + + static const bool stateful_value_traits = types_t::stateful_value_traits; + + typedef ValueTraits value_traits; + typedef typename types_t::node_traits node_traits; + + typedef typename types_t::node node; + typedef typename types_t::node_ptr node_ptr; + typedef typename types_t::const_value_traits_ptr const_value_traits_ptr; + class nat; + typedef typename + detail::if_c< IsConst + , slist_iterator + , nat>::type nonconst_iterator; + + 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; + + BOOST_INTRUSIVE_FORCEINLINE slist_iterator() + {} + + 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()) + {} + + BOOST_INTRUSIVE_FORCEINLINE slist_iterator(const nonconst_iterator &other) + : members_(other.pointed_node(), other.get_value_traits()) + {} + + BOOST_INTRUSIVE_FORCEINLINE slist_iterator &operator=(const slist_iterator &other) + { members_.nodeptr_ = other.members_.nodeptr_; return *this; } + + BOOST_INTRUSIVE_FORCEINLINE node_ptr pointed_node() const + { return members_.nodeptr_; } + + 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++() + { + members_.nodeptr_ = node_traits::get_next(members_.nodeptr_); + return static_cast (*this); + } + + BOOST_INTRUSIVE_FORCEINLINE slist_iterator operator++(int) + { + slist_iterator result (*this); + members_.nodeptr_ = node_traits::get_next(members_.nodeptr_); + return result; + } + + BOOST_INTRUSIVE_FORCEINLINE friend bool operator== (const slist_iterator& l, const slist_iterator& r) + { return l.pointed_node() == r.pointed_node(); } + + BOOST_INTRUSIVE_FORCEINLINE friend bool operator!= (const slist_iterator& l, const slist_iterator& r) + { return l.pointed_node() != r.pointed_node(); } + + BOOST_INTRUSIVE_FORCEINLINE reference operator*() const + { return *operator->(); } + + BOOST_INTRUSIVE_FORCEINLINE pointer operator->() const + { return this->operator_arrow(detail::bool_()); } + + BOOST_INTRUSIVE_FORCEINLINE slist_iterator unconst() const + { return slist_iterator(this->pointed_node(), this->get_value_traits()); } + + private: + + BOOST_INTRUSIVE_FORCEINLINE pointer operator_arrow(detail::false_) const + { return ValueTraits::to_value_ptr(members_.nodeptr_); } + + BOOST_INTRUSIVE_FORCEINLINE pointer operator_arrow(detail::true_) const + { return this->get_value_traits()->to_value_ptr(members_.nodeptr_); } + + iiterator_members members_; +}; + +} //namespace intrusive +} //namespace boost + +#include + +#endif //BOOST_INTRUSIVE_SLIST_ITERATOR_HPP diff --git a/third_party/boost/libs/intrusive/include/boost/intrusive/detail/slist_node.hpp b/third_party/boost/libs/intrusive/include/boost/intrusive/detail/slist_node.hpp new file mode 100644 index 00000000000..d209f76ade5 --- /dev/null +++ b/third_party/boost/libs/intrusive/include/boost/intrusive/detail/slist_node.hpp @@ -0,0 +1,64 @@ +///////////////////////////////////////////////////////////////////////////// +// +// (C) Copyright Olaf Krzikalla 2004-2006. +// (C) Copyright Ion Gaztanaga 2006-2013 +// +// 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_SLIST_NODE_HPP +#define BOOST_INTRUSIVE_SLIST_NODE_HPP + +#ifndef BOOST_CONFIG_HPP +# include +#endif + +#if defined(BOOST_HAS_PRAGMA_ONCE) +# pragma once +#endif + +#include +#include +#include + +namespace boost { +namespace intrusive { + +template +struct slist_node +{ + typedef typename pointer_rebind::type node_ptr; + node_ptr next_; +}; + +// slist_node_traits can be used with circular_slist_algorithms and supplies +// a slist_node holding the pointers needed for a singly-linked list +// it is used by slist_base_hook and slist_member_hook +template +struct slist_node_traits +{ + typedef slist_node node; + typedef typename node::node_ptr node_ptr; + typedef typename pointer_rebind::type const_node_ptr; + + BOOST_INTRUSIVE_FORCEINLINE static node_ptr get_next(const_node_ptr n) + { return n->next_; } + + 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) + { n->next_ = next; } +}; + +} //namespace intrusive +} //namespace boost + +#include + +#endif //BOOST_INTRUSIVE_SLIST_NODE_HPP diff --git a/third_party/boost/libs/intrusive/include/boost/intrusive/detail/std_fwd.hpp b/third_party/boost/libs/intrusive/include/boost/intrusive/detail/std_fwd.hpp new file mode 100644 index 00000000000..8193ea8ed1f --- /dev/null +++ b/third_party/boost/libs/intrusive/include/boost/intrusive/detail/std_fwd.hpp @@ -0,0 +1,43 @@ +////////////////////////////////////////////////////////////////////////////// +// +// (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/container for documentation. +// +////////////////////////////////////////////////////////////////////////////// + +#ifndef BOOST_INTRUSIVE_DETAIL_STD_FWD_HPP +#define BOOST_INTRUSIVE_DETAIL_STD_FWD_HPP + +#ifndef BOOST_CONFIG_HPP +# include +#endif + +#if defined(BOOST_HAS_PRAGMA_ONCE) +# pragma once +#endif + +////////////////////////////////////////////////////////////////////////////// +// Standard predeclarations +////////////////////////////////////////////////////////////////////////////// + +#include +BOOST_MOVE_STD_NS_BEG + +template +struct less; + +template +struct equal_to; + +struct input_iterator_tag; +struct forward_iterator_tag; +struct bidirectional_iterator_tag; +struct random_access_iterator_tag; + +BOOST_MOVE_STD_NS_END +#include + +#endif //#ifndef BOOST_INTRUSIVE_DETAIL_STD_FWD_HPP diff --git a/third_party/boost/libs/intrusive/include/boost/intrusive/detail/transform_iterator.hpp b/third_party/boost/libs/intrusive/include/boost/intrusive/detail/transform_iterator.hpp new file mode 100644 index 00000000000..0a715754d71 --- /dev/null +++ b/third_party/boost/libs/intrusive/include/boost/intrusive/detail/transform_iterator.hpp @@ -0,0 +1,172 @@ +///////////////////////////////////////////////////////////////////////////// +// +// (C) Copyright Ion Gaztanaga 2007-2013 +// +// 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_TRANSFORM_ITERATOR_HPP +#define BOOST_INTRUSIVE_DETAIL_TRANSFORM_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 { +namespace detail { + +template +struct operator_arrow_proxy +{ + BOOST_INTRUSIVE_FORCEINLINE operator_arrow_proxy(const PseudoReference &px) + : m_value(px) + {} + + BOOST_INTRUSIVE_FORCEINLINE PseudoReference* operator->() const { return &m_value; } + // This function is needed for MWCW and BCC, which won't call operator-> + // again automatically per 13.3.1.2 para 8 +// operator T*() const { return &m_value; } + mutable PseudoReference m_value; +}; + +template +struct operator_arrow_proxy +{ + BOOST_INTRUSIVE_FORCEINLINE operator_arrow_proxy(T &px) + : m_value(px) + {} + + BOOST_INTRUSIVE_FORCEINLINE T* operator->() const { return &m_value; } + // This function is needed for MWCW and BCC, which won't call operator-> + // again automatically per 13.3.1.2 para 8 +// operator T*() const { return &m_value; } + T &m_value; +}; + +template +class transform_iterator +{ + public: + typedef typename Iterator::iterator_category iterator_category; + typedef typename detail::remove_reference::type value_type; + typedef typename Iterator::difference_type difference_type; + typedef operator_arrow_proxy pointer; + typedef typename UnaryFunction::result_type reference; + + explicit transform_iterator(const Iterator &it, const UnaryFunction &f = UnaryFunction()) + : members_(it, f) + {} + + explicit transform_iterator() + : members_() + {} + + BOOST_INTRUSIVE_FORCEINLINE Iterator get_it() const + { return members_.m_it; } + + //Constructors + BOOST_INTRUSIVE_FORCEINLINE transform_iterator& operator++() + { increment(); return *this; } + + BOOST_INTRUSIVE_FORCEINLINE transform_iterator operator++(int) + { + transform_iterator result (*this); + increment(); + return result; + } + + BOOST_INTRUSIVE_FORCEINLINE friend bool operator== (const transform_iterator& i, const transform_iterator& i2) + { return i.equal(i2); } + + BOOST_INTRUSIVE_FORCEINLINE friend bool operator!= (const transform_iterator& i, const transform_iterator& i2) + { return !(i == i2); } + + BOOST_INTRUSIVE_FORCEINLINE friend typename Iterator::difference_type operator- (const transform_iterator& i, const transform_iterator& i2) + { return i2.distance_to(i); } + + //Arithmetic + transform_iterator& operator+=(typename Iterator::difference_type off) + { this->advance(off); return *this; } + + BOOST_INTRUSIVE_FORCEINLINE transform_iterator operator+(typename Iterator::difference_type off) const + { + transform_iterator other(*this); + other.advance(off); + return other; + } + + BOOST_INTRUSIVE_FORCEINLINE friend transform_iterator operator+(typename Iterator::difference_type off, const transform_iterator& right) + { return right + off; } + + BOOST_INTRUSIVE_FORCEINLINE transform_iterator& operator-=(typename Iterator::difference_type off) + { this->advance(-off); return *this; } + + BOOST_INTRUSIVE_FORCEINLINE transform_iterator operator-(typename Iterator::difference_type off) const + { return *this + (-off); } + + BOOST_INTRUSIVE_FORCEINLINE typename UnaryFunction::result_type operator*() const + { return dereference(); } + + BOOST_INTRUSIVE_FORCEINLINE operator_arrow_proxy + operator->() const + { return operator_arrow_proxy(dereference()); } + + private: + struct members + : UnaryFunction + { + BOOST_INTRUSIVE_FORCEINLINE members(const Iterator &it, const UnaryFunction &f) + : UnaryFunction(f), m_it(it) + {} + + BOOST_INTRUSIVE_FORCEINLINE members() + {} + + Iterator m_it; + } members_; + + + BOOST_INTRUSIVE_FORCEINLINE void increment() + { ++members_.m_it; } + + BOOST_INTRUSIVE_FORCEINLINE void decrement() + { --members_.m_it; } + + BOOST_INTRUSIVE_FORCEINLINE bool equal(const transform_iterator &other) const + { return members_.m_it == other.members_.m_it; } + + BOOST_INTRUSIVE_FORCEINLINE bool less(const transform_iterator &other) const + { return other.members_.m_it < members_.m_it; } + + typename UnaryFunction::result_type dereference() const + { return members_(*members_.m_it); } + + void advance(typename Iterator::difference_type n) + { boost::intrusive::iterator_advance(members_.m_it, n); } + + typename Iterator::difference_type distance_to(const transform_iterator &other)const + { return boost::intrusive::iterator_distance(other.members_.m_it, members_.m_it); } +}; + +} //namespace detail +} //namespace intrusive +} //namespace boost + +#include + +#endif //BOOST_INTRUSIVE_DETAIL_TRANSFORM_ITERATOR_HPP diff --git a/third_party/boost/libs/intrusive/include/boost/intrusive/detail/tree_iterator.hpp b/third_party/boost/libs/intrusive/include/boost/intrusive/detail/tree_iterator.hpp new file mode 100644 index 00000000000..ba1375f8c8e --- /dev/null +++ b/third_party/boost/libs/intrusive/include/boost/intrusive/detail/tree_iterator.hpp @@ -0,0 +1,184 @@ +///////////////////////////////////////////////////////////////////////////// +// +// (C) Copyright Ion Gaztanaga 2007-2013 +// +// 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_TREE_ITERATOR_HPP +#define BOOST_INTRUSIVE_TREE_ITERATOR_HPP + +#ifndef BOOST_CONFIG_HPP +# include +#endif + +#if defined(BOOST_HAS_PRAGMA_ONCE) +# pragma once +#endif + +#include +#include +#include +#include +#include + +namespace boost { +namespace intrusive { + +///////////////////////////////////////////////////////////////////////////// +// // +// Implementation of the tree iterator // +// // +///////////////////////////////////////////////////////////////////////////// + +// tree_iterator provides some basic functions for a +// node oriented bidirectional iterator: +template +class tree_iterator +{ + private: + typedef iiterator< ValueTraits, IsConst + , std::bidirectional_iterator_tag> types_t; + typedef typename types_t::value_traits value_traits; + typedef typename types_t::node_traits node_traits; + typedef typename types_t::node node; + typedef typename types_t::node_ptr node_ptr; + typedef typename types_t::const_value_traits_ptr const_value_traits_ptr; + typedef bstree_algorithms_base node_algorithms; + + static const bool stateful_value_traits = types_t::stateful_value_traits; + + void unspecified_bool_type_func() const {} + typedef void (tree_iterator::*unspecified_bool_type)() const; + class nat; + typedef typename + detail::if_c< IsConst + , tree_iterator + , nat>::type nonconst_iterator; + + 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; + + BOOST_INTRUSIVE_FORCEINLINE tree_iterator() + {} + + BOOST_INTRUSIVE_FORCEINLINE explicit tree_iterator(node_ptr nodeptr, const_value_traits_ptr traits_ptr) + : members_(nodeptr, traits_ptr) + {} + + BOOST_INTRUSIVE_FORCEINLINE tree_iterator(const tree_iterator &other) + : members_(other.pointed_node(), other.get_value_traits()) + {} + + BOOST_INTRUSIVE_FORCEINLINE tree_iterator(const nonconst_iterator &other) + : members_(other.pointed_node(), other.get_value_traits()) + {} + + BOOST_INTRUSIVE_FORCEINLINE tree_iterator &operator=(const tree_iterator &other) + { members_.nodeptr_ = other.members_.nodeptr_; return *this; } + + BOOST_INTRUSIVE_FORCEINLINE tree_iterator &operator=(node_ptr nodeptr) + { members_.nodeptr_ = nodeptr; return *this; } + + BOOST_INTRUSIVE_FORCEINLINE node_ptr pointed_node() const + { return members_.nodeptr_; } + + public: + BOOST_INTRUSIVE_FORCEINLINE tree_iterator& operator++() + { + members_.nodeptr_ = node_algorithms::next_node(members_.nodeptr_); + return *this; + } + + tree_iterator operator++(int) + { + tree_iterator result (*this); + members_.nodeptr_ = node_algorithms::next_node(members_.nodeptr_); + return result; + } + + BOOST_INTRUSIVE_FORCEINLINE tree_iterator& operator--() + { + members_.nodeptr_ = node_algorithms::prev_node(members_.nodeptr_); + return *this; + } + + tree_iterator operator--(int) + { + tree_iterator result (*this); + members_.nodeptr_ = node_algorithms::prev_node(members_.nodeptr_); + return result; + } + + BOOST_INTRUSIVE_FORCEINLINE tree_iterator& go_left() + { + members_.nodeptr_ = node_traits::get_left(members_.nodeptr_); + return *this; + } + + BOOST_INTRUSIVE_FORCEINLINE tree_iterator& go_right() + { + members_.nodeptr_ = node_traits::get_right(members_.nodeptr_); + return *this; + } + + BOOST_INTRUSIVE_FORCEINLINE tree_iterator& go_parent() + { + members_.nodeptr_ = node_traits::get_parent(members_.nodeptr_); + return *this; + } + + BOOST_INTRUSIVE_FORCEINLINE operator unspecified_bool_type() const + { return members_.nodeptr_ ? &tree_iterator::unspecified_bool_type_func : 0; } + + BOOST_INTRUSIVE_FORCEINLINE bool operator! () const + { return !members_.nodeptr_; } + + BOOST_INTRUSIVE_FORCEINLINE friend bool operator== (const tree_iterator& l, const tree_iterator& r) + { return l.pointed_node() == r.pointed_node(); } + + BOOST_INTRUSIVE_FORCEINLINE friend bool operator!= (const tree_iterator& l, const tree_iterator& r) + { return !(l == r); } + + BOOST_INTRUSIVE_FORCEINLINE reference operator*() const + { return *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(); } + + tree_iterator end_iterator_from_it() const + { + return tree_iterator(node_algorithms::get_header(this->pointed_node()), this->get_value_traits()); + } + + tree_iterator unconst() const + { return tree_iterator(this->pointed_node(), this->get_value_traits()); } + + private: + BOOST_INTRUSIVE_FORCEINLINE pointer operator_arrow(detail::false_) const + { return ValueTraits::to_value_ptr(members_.nodeptr_); } + + BOOST_INTRUSIVE_FORCEINLINE pointer operator_arrow(detail::true_) const + { return this->get_value_traits()->to_value_ptr(members_.nodeptr_); } + + iiterator_members members_; +}; + +} //namespace intrusive +} //namespace boost + +#include + +#endif //BOOST_INTRUSIVE_TREE_ITERATOR_HPP diff --git a/third_party/boost/libs/intrusive/include/boost/intrusive/detail/tree_node.hpp b/third_party/boost/libs/intrusive/include/boost/intrusive/detail/tree_node.hpp new file mode 100644 index 00000000000..949d2d913b2 --- /dev/null +++ b/third_party/boost/libs/intrusive/include/boost/intrusive/detail/tree_node.hpp @@ -0,0 +1,80 @@ +///////////////////////////////////////////////////////////////////////////// +// +// (C) Copyright Ion Gaztanaga 2007-2013 +// +// 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_TREE_NODE_HPP +#define BOOST_INTRUSIVE_TREE_NODE_HPP + +#ifndef BOOST_CONFIG_HPP +# include +#endif + +#if defined(BOOST_HAS_PRAGMA_ONCE) +# pragma once +#endif + +#include +#include +#include + +namespace boost { +namespace intrusive { + +template +struct tree_node +{ + typedef typename pointer_rebind::type node_ptr; + + node_ptr parent_, left_, right_; +}; + +template +struct tree_node_traits +{ + typedef tree_node node; + + typedef typename node::node_ptr node_ptr; + typedef typename pointer_rebind::type const_node_ptr; + + BOOST_INTRUSIVE_FORCEINLINE static node_ptr get_parent(const_node_ptr n) + { return n->parent_; } + + 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_node_ptr n) + { return n->left_; } + + 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_node_ptr n) + { return n->right_; } + + 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; } +}; + +} //namespace intrusive +} //namespace boost + +#include + +#endif //BOOST_INTRUSIVE_TREE_NODE_HPP diff --git a/third_party/boost/libs/intrusive/include/boost/intrusive/detail/tree_value_compare.hpp b/third_party/boost/libs/intrusive/include/boost/intrusive/detail/tree_value_compare.hpp new file mode 100644 index 00000000000..c78da0acd6c --- /dev/null +++ b/third_party/boost/libs/intrusive/include/boost/intrusive/detail/tree_value_compare.hpp @@ -0,0 +1,186 @@ +////////////////////////////////////////////////////////////////////////////// +// +// (C) Copyright Ion Gaztanaga 2015-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_INTRUSIVE_DETAIL_TREE_VALUE_COMPARE_HPP +#define BOOST_INTRUSIVE_DETAIL_TREE_VALUE_COMPARE_HPP + +#ifndef BOOST_CONFIG_HPP +# include +#endif + +#if defined(BOOST_HAS_PRAGMA_ONCE) +# pragma once +#endif + +#include +#include +#include +#include + +namespace boost{ +namespace intrusive{ + +//Needed to support smart references to value types +template +struct disable_if_smartref_to + : detail::disable_if_c + < detail::is_same + + ::reference>::value + || detail::is_same + ::type>::type> + ::reference>::value + > +{}; + +//This function object takes a KeyCompare function object +//and compares values that contains keys using KeyOfValue +template< class ValuePtr, class KeyCompare, class KeyOfValue, class Ret = bool + , bool = boost::intrusive::detail::is_same + ::type, typename KeyOfValue::type>::value > +struct tree_value_compare + : public boost::intrusive::detail::ebo_functor_holder +{ + typedef typename + boost::movelib::pointer_element::type value_type; + typedef KeyCompare key_compare; + typedef KeyOfValue key_of_value; + typedef typename KeyOfValue::type key_type; + + typedef boost::intrusive::detail::ebo_functor_holder base_t; + + BOOST_INTRUSIVE_FORCEINLINE tree_value_compare() + : base_t() + {} + + BOOST_INTRUSIVE_FORCEINLINE explicit tree_value_compare(const key_compare &kcomp) + : base_t(kcomp) + {} + + BOOST_INTRUSIVE_FORCEINLINE tree_value_compare (const tree_value_compare &x) + : base_t(x.base_t::get()) + {} + + BOOST_INTRUSIVE_FORCEINLINE tree_value_compare &operator=(const tree_value_compare &x) + { this->base_t::get() = x.base_t::get(); return *this; } + + BOOST_INTRUSIVE_FORCEINLINE tree_value_compare &operator=(const key_compare &x) + { this->base_t::get() = x; return *this; } + + BOOST_INTRUSIVE_FORCEINLINE const key_compare &key_comp() const + { return static_cast(*this); } + + BOOST_INTRUSIVE_FORCEINLINE Ret operator()(const key_type &key) const + { return this->key_comp()(key); } + + BOOST_INTRUSIVE_FORCEINLINE Ret operator()(const value_type &value) const + { return this->key_comp()(KeyOfValue()(value)); } + + template + BOOST_INTRUSIVE_FORCEINLINE Ret operator()( const U &nonkey + , typename disable_if_smartref_to::type* = 0) const + { return this->key_comp()(nonkey); } + + BOOST_INTRUSIVE_FORCEINLINE Ret operator()(const key_type &key1, const key_type &key2) const + { return this->key_comp()(key1, key2); } + + BOOST_INTRUSIVE_FORCEINLINE Ret operator()(const value_type &value1, const value_type &value2) const + { return this->key_comp()(KeyOfValue()(value1), KeyOfValue()(value2)); } + + BOOST_INTRUSIVE_FORCEINLINE Ret operator()(const key_type &key1, const value_type &value2) const + { return this->key_comp()(key1, KeyOfValue()(value2)); } + + BOOST_INTRUSIVE_FORCEINLINE Ret operator()(const value_type &value1, const key_type &key2) const + { return this->key_comp()(KeyOfValue()(value1), key2); } + + template + BOOST_INTRUSIVE_FORCEINLINE Ret operator()( const key_type &key1, const U &nonkey2 + , typename disable_if_smartref_to::type* = 0) const + { return this->key_comp()(key1, nonkey2); } + + template + BOOST_INTRUSIVE_FORCEINLINE Ret operator()( const U &nonkey1, const key_type &key2 + , typename disable_if_smartref_to::type* = 0) const + { return this->key_comp()(nonkey1, key2); } + + template + BOOST_INTRUSIVE_FORCEINLINE Ret operator()( const value_type &value1, const U &nonvalue2 + , typename disable_if_smartref_to::type* = 0) const + { return this->key_comp()(KeyOfValue()(value1), nonvalue2); } + + template + BOOST_INTRUSIVE_FORCEINLINE Ret operator()( const U &nonvalue1, const value_type &value2 + , typename disable_if_smartref_to::type* = 0) const + { return this->key_comp()(nonvalue1, KeyOfValue()(value2)); } +}; + +template +struct tree_value_compare + : public boost::intrusive::detail::ebo_functor_holder +{ + typedef typename + boost::movelib::pointer_element::type value_type; + typedef KeyCompare key_compare; + typedef KeyOfValue key_of_value; + typedef typename KeyOfValue::type key_type; + + typedef boost::intrusive::detail::ebo_functor_holder base_t; + + + BOOST_INTRUSIVE_FORCEINLINE tree_value_compare() + : base_t() + {} + + BOOST_INTRUSIVE_FORCEINLINE explicit tree_value_compare(const key_compare &kcomp) + : base_t(kcomp) + {} + + BOOST_INTRUSIVE_FORCEINLINE tree_value_compare (const tree_value_compare &x) + : base_t(x.base_t::get()) + {} + + BOOST_INTRUSIVE_FORCEINLINE tree_value_compare &operator=(const tree_value_compare &x) + { this->base_t::get() = x.base_t::get(); return *this; } + + BOOST_INTRUSIVE_FORCEINLINE tree_value_compare &operator=(const key_compare &x) + { this->base_t::get() = x; return *this; } + + BOOST_INTRUSIVE_FORCEINLINE const key_compare &key_comp() const + { return static_cast(*this); } + + BOOST_INTRUSIVE_FORCEINLINE Ret operator()(const key_type &key) const + { return this->key_comp()(key); } + + template + BOOST_INTRUSIVE_FORCEINLINE Ret operator()( const U &nonkey + , typename disable_if_smartref_to::type* = 0) const + { return this->key_comp()(nonkey); } + + BOOST_INTRUSIVE_FORCEINLINE Ret operator()(const key_type &key1, const key_type &key2) const + { return this->key_comp()(key1, key2); } + + template + BOOST_INTRUSIVE_FORCEINLINE Ret operator()( const key_type &key1, const U &nonkey2 + , typename disable_if_smartref_to::type* = 0) const + { return this->key_comp()(key1, nonkey2); } + + template + BOOST_INTRUSIVE_FORCEINLINE Ret operator()(const U &nonkey1, const key_type &key2 + , typename disable_if_smartref_to::type* = 0) const + { return this->key_comp()(nonkey1, key2); } +}; + +} //namespace intrusive{ +} //namespace boost{ + +#endif //#ifdef BOOST_INTRUSIVE_DETAIL_TREE_VALUE_COMPARE_HPP diff --git a/third_party/boost/libs/intrusive/include/boost/intrusive/detail/twin.hpp b/third_party/boost/libs/intrusive/include/boost/intrusive/detail/twin.hpp new file mode 100644 index 00000000000..b778732f4ef --- /dev/null +++ b/third_party/boost/libs/intrusive/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/third_party/boost/libs/intrusive/include/boost/intrusive/detail/uncast.hpp b/third_party/boost/libs/intrusive/include/boost/intrusive/detail/uncast.hpp new file mode 100644 index 00000000000..7db97b74571 --- /dev/null +++ b/third_party/boost/libs/intrusive/include/boost/intrusive/detail/uncast.hpp @@ -0,0 +1,55 @@ +///////////////////////////////////////////////////////////////////////////// +// +// (C) Copyright Ion Gaztanaga 2006-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_UNCAST_HPP +#define BOOST_INTRUSIVE_DETAIL_UNCAST_HPP + +#ifndef BOOST_CONFIG_HPP +# include +#endif + +#if defined(BOOST_HAS_PRAGMA_ONCE) +# pragma once +#endif + +#include +#include +#include + +namespace boost { +namespace intrusive { +namespace detail { + +template +struct uncast_types +{ + typedef typename pointer_traits::element_type element_type; + typedef typename remove_const::type non_const_type; + typedef typename pointer_traits:: + template rebind_pointer::type non_const_pointer; + typedef pointer_traits non_const_traits; +}; + +template +static typename uncast_types::non_const_pointer + uncast(const ConstNodePtr & ptr) +{ + return uncast_types::non_const_traits::const_cast_from(ptr); +} + +} //namespace detail { +} //namespace intrusive +} //namespace boost + +#include + +#endif //BOOST_INTRUSIVE_DETAIL_UTILITIES_HPP diff --git a/third_party/boost/libs/intrusive/include/boost/intrusive/detail/value_functors.hpp b/third_party/boost/libs/intrusive/include/boost/intrusive/detail/value_functors.hpp new file mode 100644 index 00000000000..7e220ebefb2 --- /dev/null +++ b/third_party/boost/libs/intrusive/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/third_party/boost/libs/intrusive/include/boost/intrusive/detail/workaround.hpp b/third_party/boost/libs/intrusive/include/boost/intrusive/detail/workaround.hpp new file mode 100644 index 00000000000..0011fb5bfbe --- /dev/null +++ b/third_party/boost/libs/intrusive/include/boost/intrusive/detail/workaround.hpp @@ -0,0 +1,84 @@ +////////////////////////////////////////////////////////////////////////////// +// +// (C) Copyright Ion Gaztanaga 2005-2013. 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/interprocess for documentation. +// +////////////////////////////////////////////////////////////////////////////// + +#ifndef BOOST_INTRUSIVE_DETAIL_WORKAROUND_HPP +#define BOOST_INTRUSIVE_DETAIL_WORKAROUND_HPP + +#ifndef BOOST_CONFIG_HPP +# include +#endif + +#if defined(BOOST_HAS_PRAGMA_ONCE) +# pragma once +#endif + +#ifndef BOOST_CONFIG_HPP +#include +#endif + +// MSVC-12 ICEs when variadic templates are enabled. +#if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) && (!defined(BOOST_MSVC) || BOOST_MSVC >= 1900) + #define BOOST_INTRUSIVE_VARIADIC_TEMPLATES +#endif + +#if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES) && !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) + #define BOOST_INTRUSIVE_PERFECT_FORWARDING +#endif + +//Macros for documentation purposes. For code, expands to the argument +#define BOOST_INTRUSIVE_IMPDEF(TYPE) TYPE +#define BOOST_INTRUSIVE_SEEDOC(TYPE) TYPE +#define BOOST_INTRUSIVE_DOC1ST(TYPE1, TYPE2) TYPE2 +#define BOOST_INTRUSIVE_I , +#define BOOST_INTRUSIVE_DOCIGN(T1) T1 + +//#define BOOST_INTRUSIVE_DISABLE_FORCEINLINE + +#if defined(BOOST_INTRUSIVE_DISABLE_FORCEINLINE) + #define BOOST_INTRUSIVE_FORCEINLINE inline +#elif defined(BOOST_INTRUSIVE_FORCEINLINE_IS_BOOST_FORCELINE) + #define BOOST_INTRUSIVE_FORCEINLINE BOOST_FORCEINLINE +#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(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/third_party/boost/libs/intrusive/include/boost/intrusive/hashtable.hpp b/third_party/boost/libs/intrusive/include/boost/intrusive/hashtable.hpp new file mode 100644 index 00000000000..688fb9b228c --- /dev/null +++ b/third_party/boost/libs/intrusive/include/boost/intrusive/hashtable.hpp @@ -0,0 +1,4363 @@ +///////////////////////////////////////////////////////////////////////////// +// +// (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 +// http://www.boost.org/LICENSE_1_0.txt) +// +// 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 + +#include +#include + +//General intrusive utilities +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +//Implementation utilities +#include +#include +#include +#include +#include +#include + +//boost +#include +#include +#include +#include +#include +#include + +//std C++ +#include //std::pair +#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 last; +} + +template +typename boost::intrusive::iterator_traits::difference_type + priv_algo_count(InputIt first, InputIt last, const T& value) +{ + typename boost::intrusive::iterator_traits::difference_type ret = 0; + for (; first != last; ++first) { + if (*first == value) { + ret++; + } + } + return ret; +} + +template +bool priv_algo_is_permutation(ForwardIterator1 first1, ForwardIterator1 last1, ForwardIterator2 first2) +{ + typedef typename + boost::intrusive::iterator_traits::difference_type + distance_type; + //Efficiently compare identical prefixes: O(N) if sequences + //have the same elements in the same order. + for ( ; first1 != last1; ++first1, ++first2){ + if (! (*first1 == *first2)) + break; + } + if (first1 == last1){ + return true; + } + + //Establish last2 assuming equal ranges by iterating over the + //rest of the list. + ForwardIterator2 last2 = first2; + boost::intrusive::iterator_advance(last2, boost::intrusive::iterator_distance(first1, last1)); + for(ForwardIterator1 scan = first1; scan != last1; ++scan){ + if (scan != (priv_algo_find)(first1, scan, *scan)){ + 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){ + return false; + } + } + return true; +} + +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; + static const std::size_t linear_buckets_pos = 64u; + static const std::size_t fastmod_buckets_pos = 128u; +}; + +template +class exception_bucket_disposer +{ + Bucket *cont_; + Disposer &disp_; + const SizeType &constructed_; + + exception_bucket_disposer(const exception_bucket_disposer&); + exception_bucket_disposer &operator=(const exception_bucket_disposer&); + + public: + + exception_bucket_disposer + (Bucket &cont, Disposer &disp, const SizeType &constructed) + : cont_(&cont), disp_(disp), constructed_(constructed) + {} + + BOOST_INTRUSIVE_FORCEINLINE void release() + { cont_ = 0; } + + ~exception_bucket_disposer() + { + SizeType n = constructed_; + if(cont_){ + while(n--){ + Algo::detach_and_dispose(cont_[n].get_node_ptr(), disp_); + } + } + } +}; + +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; + + typedef typename pointer_traits + + ::template rebind_pointer::type pointer; +}; + +template +struct unordered_bucket_ptr_impl +{ + typedef typename unordered_bucket_impl::pointer type; +}; + + +template +struct bucket_traits_impl +{ +private: + BOOST_COPYABLE_AND_MOVABLE(bucket_traits_impl) + +public: + /// @cond + + typedef BucketPtr bucket_ptr; + typedef SizeType size_type; + + /// @endcond + + BOOST_INTRUSIVE_FORCEINLINE bucket_traits_impl(bucket_ptr buckets, size_type len) + : buckets_(buckets), buckets_len_(len) + {} + + BOOST_INTRUSIVE_FORCEINLINE bucket_traits_impl(const bucket_traits_impl& x) + : buckets_(x.buckets_), buckets_len_(x.buckets_len_) + {} + + 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; + } + + 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; + } + + 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 bucket_ptr bucket_begin() const + { + return buckets_; + } + + BOOST_INTRUSIVE_FORCEINLINE size_type bucket_count() const BOOST_NOEXCEPT + { + return buckets_len_; + } + +private: + bucket_ptr buckets_; + size_type buckets_len_; +}; + + +template +struct store_hash_is_true +{ + template + 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(detail::yes_type)*2u; +}; + +template +struct optimize_multikey_is_true +{ + template + 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(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 +BOOST_INTRUSIVE_FORCEINLINE typename pointer_traits::template rebind_pointer::type + dcast_bucket_ptr(const SlistNodePtr &p) +{ + typedef typename pointer_traits::template rebind_pointer::type node_ptr; + return pointer_traits::pointer_to(static_cast(*p)); +} + +template +struct group_functions +{ + // A group is reverse-linked + // + // A is "first in group" + // C is "last in group" + // __________________ + // | _____ _____ | + // | | | | | | <- Group links + // ^ V ^ V ^ V + // _ _ _ _ + // A|_| B|_| C|_| D|_| + // + // ^ | ^ | ^ | ^ V <- Bucket links + // _ _____| |_____| |______| |____| | + // |B| | + // ^________________________________| + // + + typedef NodeTraits node_traits; + typedef unordered_group_adapter group_traits; + typedef typename node_traits::node_ptr node_ptr; + typedef typename node_traits::node node; + typedef typename reduced_slist_node_traits + ::type reduced_node_traits; + typedef typename reduced_node_traits::node_ptr slist_node_ptr; + typedef typename reduced_node_traits::node slist_node; + typedef circular_slist_algorithms group_algorithms; + typedef circular_slist_algorithms node_algorithms; + + static slist_node_ptr get_bucket_before_begin + (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_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_last){ + return nxt; + } + + //Otherwise, iterate using group links until the bucket node + node_ptr first_node_of_group = nxt; + 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_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 = 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 + } + return nb; + } + + static void erase_from_group(slist_node_ptr end_ptr, node_ptr to_erase_ptr, detail::true_) + { + node_ptr const nxt_ptr(node_traits::get_next(to_erase_ptr)); + //Check if the next node is in the group (not end node) and reverse linked to + //'to_erase_ptr'. Erase if that's the case. + if(nxt_ptr != end_ptr && to_erase_ptr == group_traits::get_next(nxt_ptr)){ + group_algorithms::unlink_after(nxt_ptr); + } + } + + 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_) + { return group_traits::get_next(first_in_group); } + + BOOST_INTRUSIVE_FORCEINLINE static node_ptr get_last_in_group(node_ptr n, detail::false_) + { return n; } + + static node_ptr get_first_in_group(node_ptr n, detail::true_) + { + node_ptr ng; + while(n == node_traits::get_next((ng = group_traits::get_next(n)))){ + n = ng; + } + return n; + } + + BOOST_INTRUSIVE_FORCEINLINE static node_ptr get_first_in_group(node_ptr n, detail::false_) + { return n; } + + 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); } + + BOOST_INTRUSIVE_FORCEINLINE static void insert_in_group(node_ptr, node_ptr, detail::false_) + {} + + //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 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 old_first; + } +}; + +template +class incremental_rehash_rollback +{ + private: + typedef BucketType bucket_type; + typedef SplitTraits split_traits; + + incremental_rehash_rollback(); + incremental_rehash_rollback & operator=(const incremental_rehash_rollback &); + incremental_rehash_rollback (const incremental_rehash_rollback &); + + public: + incremental_rehash_rollback + (bucket_type &source_bucket, bucket_type &destiny_bucket, split_traits &split_tr) + : source_bucket_(source_bucket), destiny_bucket_(destiny_bucket) + , split_traits_(split_tr), released_(false) + {} + + BOOST_INTRUSIVE_FORCEINLINE void release() + { released_ = true; } + + ~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. + SlistNodeAlgorithms::transfer_after(destiny_bucket_.get_node_ptr(), source_bucket_.get_node_ptr()); + split_traits_.decrement(); + } + } + + private: + bucket_type &source_bucket_; + bucket_type &destiny_bucket_; + split_traits &split_traits_; + bool released_; +}; + +template +struct node_functions +{ + 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, detail::false_) + {} +}; + +BOOST_INTRUSIVE_FORCEINLINE std::size_t hash_to_bucket(std::size_t hash_value, std::size_t bucket_cnt, detail::false_) +{ return hash_value % bucket_cnt; } + +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 //!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 = 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; +} + +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 unordered_bucket_impl + < typename ValueTraitsOrHookOption:: + template pack::proto_value_traits> +{}; + +//!This metafunction will obtain the type of a bucket pointer +//!from the value_traits or hook option to be used with +//!a hash container. +template +struct unordered_bucket_ptr + : public unordered_bucket_ptr_impl + < typename ValueTraitsOrHookOption:: + template pack::proto_value_traits> +{}; + +//!This metafunction will obtain the type of the default bucket traits +//!(when the user does not specify the bucket_traits<> option) from the +//!value_traits or hook option to be used with +//!a hash container. +template +struct unordered_default_bucket_traits +{ + typedef typename ValueTraitsOrHookOption:: + template pack::proto_value_traits supposed_value_traits; + + typedef bucket_traits_impl + < typename unordered_bucket_ptr_impl + ::type + , std::size_t> type; +}; + +struct default_bucket_traits; + +//hashtable default hook traits +struct default_hashtable_hook_applier +{ template struct apply{ typedef typename T::default_hashtable_hook type; }; }; + +template<> +struct is_default_hook_tag +{ static const bool value = true; }; + +struct hashtable_defaults +{ + typedef default_hashtable_hook_applier proto_value_traits; + typedef std::size_t size_type; + typedef void key_of_value; + typedef void equal; + typedef void hash; + typedef default_bucket_traits bucket_traits; + static const bool constant_time_size = true; + static const bool power_2_buckets = false; + 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 unordered_bucket_impl + ::type::node_traits::node node; + typedef typename detail::add_const_if_c + ::type &first_argument_type; + typedef typename detail::add_const_if_c + < typename ValueTraits::node_traits::node + , 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_value_traits_ptr ptr) + : base_t(ptr) + {} + + BOOST_INTRUSIVE_FORCEINLINE result_type operator()(first_argument_type arg) const + { return this->base_t::operator()(static_cast(arg)); } +}; + +template +struct node_cast_adaptor + //Use public inheritance to avoid MSVC bugs with closures + : public detail::ebo_functor_holder +{ + typedef detail::ebo_functor_holder base_t; + + typedef typename pointer_traits::element_type slist_node; + typedef typename pointer_traits::element_type node; + + template + BOOST_INTRUSIVE_FORCEINLINE node_cast_adaptor(const ConvertibleToF &c2f, const RealValuTraits *traits) + : base_t(base_t(c2f, traits)) + {} + + BOOST_INTRUSIVE_FORCEINLINE typename base_t::node_ptr operator()(const slist_node &to_clone) + { return base_t::operator()(static_cast(to_clone)); } + + BOOST_INTRUSIVE_FORCEINLINE void operator()(SlistNodePtr to_clone) + { + base_t::operator()(pointer_traits::pointer_to(static_cast(*to_clone))); + } +}; + +//bucket_plus_vtraits stores ValueTraits + BucketTraits +//this data is needed by iterators to obtain the +//value from the iterator and detect the bucket +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 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 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; + typedef typename value_traits::const_pointer const_pointer; + typedef typename pointer_traits::reference reference; + typedef typename pointer_traits + ::reference const_reference; + typedef circular_slist_algorithms group_algorithms; + typedef typename pointer_traits + :: + template rebind_pointer + ::type const_value_traits_ptr; + typedef typename pointer_traits + :: + template rebind_pointer + ::type const_bucket_value_traits_ptr; + typedef detail::bool_ linear_buckets_t; + typedef bucket_plus_vtraits& this_ref; + + static const std::size_t bucket_overhead = LinearBuckets ? 1u : 0u; + + 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(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()); } + + //bucket_value_traits + // + BOOST_INTRUSIVE_FORCEINLINE const bucket_plus_vtraits &get_bucket_value_traits() const + { return *this; } + + BOOST_INTRUSIVE_FORCEINLINE bucket_plus_vtraits &get_bucket_value_traits() + { return *this; } + + BOOST_INTRUSIVE_FORCEINLINE const_bucket_value_traits_ptr bucket_value_traits_ptr() const + { return pointer_traits::pointer_to(this->get_bucket_value_traits()); } + + //value traits + // + BOOST_INTRUSIVE_FORCEINLINE const value_traits &priv_value_traits() const + { return static_cast(this->m_data); } + + BOOST_INTRUSIVE_FORCEINLINE value_traits &priv_value_traits() + { return static_cast(this->m_data); } + + //value traits + // + BOOST_INTRUSIVE_FORCEINLINE const bucket_traits &priv_bucket_traits() const + { return static_cast(this->m_data); } + + 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_NOEXCEPT + { return this->priv_bucket_traits().bucket_begin(); } + + 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_type &priv_bucket(std::size_t n) const BOOST_NOEXCEPT + { + BOOST_INTRUSIVE_INVARIANT_ASSERT(n < this->priv_usable_bucket_count()); + return this->priv_bucket_pointer()[std::ptrdiff_t(n)]; + } + + 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 + { + std::size_t n = 0; + siterator const sfirst(++siterator(sbefore_first)); + if(sfirst != slast){ + 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::is_first_in_group(nf)) { + // The first node is at the beginning of a group. + if(nl != ne){ + group_functions_t::split_group(nl); + } + } + else { + node_ptr const group1 = group_functions_t::split_group(nf); + if(nl != 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(nl, end1); + } + } + } + + 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 &, siterator sbefore_first, siterator slast, NodeDisposer node_disposer, detail::false_) //optimize multikey + { + 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 + { + 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(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){ + group_algorithms::unlink_after(nn); + } + } + else if(nn != ne && group_traits::get_next(nn) == n){ + //Node is not the end of the group + bn = group_traits::get_next(n); + group_algorithms::unlink_after(nn); + } + else{ + //Node is the end of the group + bn = group_traits::get_next(n); + node_ptr const x(group_algorithms::get_previous_node(n)); + group_algorithms::unlink_after(x); + } + 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 + { + 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 + , siterator const &last_it, std::size_t const last_bucket + , NodeDisposer node_disposer, detail::bool_ optimize_multikey_tag) + { + std::size_t num_erased(0); + siterator last_step_before_it; + if(first_bucket != last_bucket){ + bucket_type *b = &this->priv_bucket(0); + num_erased += this->priv_erase_from_single_bucket + (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 = 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(last_bucket), last_step_before_it, last_it, node_disposer, optimize_multikey_tag); + return num_erased; + } + + static siterator priv_get_last(bucket_type &b, detail::true_) //optimize multikey + { + //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(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(dcast_bucket_ptr(possible_end)); + possible_end = slist_node_traits::get_next(last_node_group); + } + return siterator(last_node_group); + } + + 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))); + } + + 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(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; + 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 siterator(n); + } + + BOOST_INTRUSIVE_FORCEINLINE static siterator priv_get_previous(bucket_type &b, siterator i, detail::false_) //NOT optimize multikey + { return siterator(slist_node_algorithms::get_previous_node(b.get_node_ptr(), i.pointed_node())); } + + template + struct typeof_node_disposer + { + typedef node_cast_adaptor + < detail::node_disposer< Disposer, value_traits, CommonSListAlgorithms> + , slist_node_ptr, node_ptr > type; + }; + + template + BOOST_INTRUSIVE_FORCEINLINE typename typeof_node_disposer::type + make_node_disposer(const Disposer &disposer) const + { + typedef typename typeof_node_disposer::type return_t; + return return_t(disposer, &this->priv_value_traits()); + } + + static BOOST_INTRUSIVE_FORCEINLINE bucket_ptr to_ptr(bucket_type &b) + { return pointer_traits::pointer_to(b); } + + 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()); } + + 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(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) + { return *this->priv_value_traits().to_node_ptr(v); } + + 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 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 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){ + 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{ + slist_node_algorithms::init_header(b.get_node_ptr()); + } + } + } + + 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; + + BOOST_INTRUSIVE_FORCEINLINE iterator end() BOOST_NOEXCEPT + { return this->build_iterator(this->priv_end_sit(), bucket_ptr()); } + + BOOST_INTRUSIVE_FORCEINLINE const_iterator end() const BOOST_NOEXCEPT + { return this->cend(); } + + BOOST_INTRUSIVE_FORCEINLINE const_iterator cend() const BOOST_NOEXCEPT + { return this->build_const_iterator(this->priv_end_sit(), bucket_ptr()); } + + 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()); } + + 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 +struct get_hash +{ + typedef Hash type; +}; + +template +struct get_hash +{ + typedef ::boost::hash type; +}; + +template +struct get_equal_to +{ + typedef EqualTo type; +}; + +template +struct get_equal_to +{ + typedef value_equal type; +}; + +template +struct get_hash_key_of_value +{ + typedef KeyOfValue type; +}; + +template +struct get_hash_key_of_value +{ + typedef ::boost::intrusive::detail::identity type; +}; + +template +struct hash_key_types_base +{ + typedef typename get_hash_key_of_value + < VoidOrKeyOfValue, T>::type key_of_value; + typedef typename key_of_value::type key_type; +}; + +template +struct hash_key_hash + : get_hash + < VoidOrKeyHash + , typename hash_key_types_base::key_type + > +{}; + +template +struct hash_key_equal + : get_equal_to + < VoidOrKeyEqual + , typename hash_key_types_base::key_type + > + +{}; + +//bucket_hash_t +//Stores bucket_plus_vtraits plust the hash function +template +struct bucket_hash_t + //Use public inheritance to avoid MSVC bugs with closures + : public detail::ebo_functor_holder + ::value_traits::value_type + , VoidOrKeyOfValue + , VoidOrKeyHash + >::type + > + , bucket_plus_vtraits //4 +{ + 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 + < value_type, VoidOrKeyOfValue, VoidOrKeyHash> hash_key_hash_t; + typedef typename hash_key_hash_t::type hasher; + 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 detail::ebo_functor_holder base_t; + + 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(); } + + 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 + + BOOST_INTRUSIVE_FORCEINLINE std::size_t priv_stored_or_compute_hash(const value_type &v, detail::false_) const //For store_hash == false + { return this->priv_hasher()(key_of_value()(v)); } +}; + +template +struct hashtable_equal_holder +{ + typedef detail::ebo_functor_holder + < typename hash_key_equal < typename bucket_plus_vtraits + ::value_traits::value_type + , VoidOrKeyOfValue + , VoidOrKeyEqual + >::type + > type; +}; + + +//bucket_hash_equal_t +//Stores bucket_hash_t and the equality function when the first +//non-empty bucket shall not be cached. +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 +{ + private: + BOOST_MOVABLE_BUT_NOT_COPYABLE(bucket_hash_equal_t) + + public: + typedef typename hashtable_equal_holder + < 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->priv_bucket_pointer(); } + + 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_init_cache() + {} + + BOOST_INTRUSIVE_FORCEINLINE void priv_swap_cache(bucket_hash_equal_t &) + {} + + siterator priv_begin(bucket_ptr &pbucketptr) const + { + std::size_t n = 0; + std::size_t bucket_cnt = this->priv_usable_bucket_count(); + for (n = 0; n < bucket_cnt; ++n){ + 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()); + } + } + pbucketptr = this->priv_invalid_bucket_ptr(); + return this->priv_end_sit(); + } + + BOOST_INTRUSIVE_FORCEINLINE void priv_insertion_update_cache(std::size_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() + {} + + BOOST_INTRUSIVE_FORCEINLINE const key_equal &priv_equal() const + { return this->equal_holder_t::get(); } + + BOOST_INTRUSIVE_FORCEINLINE key_equal &priv_equal() + { return this->equal_holder_t::get(); } +}; + +//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 + //Use public inheritance to avoid MSVC bugs with closures + : 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 + < ValueTraits, BucketTraits + , VoidOrKeyOfValue, VoidOrKeyEqual, LinearBuckets>::type equal_holder_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 + < 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::siterator siterator; + typedef typename bucket_plus_vtraits_t::slist_node_algorithms slist_node_algorithms; + + 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)) + {} + + typedef typename unordered_bucket_ptr_impl + ::type bucket_ptr; + + BOOST_INTRUSIVE_FORCEINLINE bucket_ptr priv_get_cache() const + { return cached_begin_; } + + 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 std::size_t(this->cached_begin_ - this->priv_bucket_pointer()); } + + 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_); } + + siterator priv_begin(bucket_ptr& pbucketptr) const + { + pbucketptr = this->cached_begin_; + if(this->cached_begin_ == this->priv_past_usable_bucket_ptr()){ + return this->priv_end_sit(); + } + else{ + return siterator(cached_begin_->begin_ptr()); + } + } + + void priv_insertion_update_cache(std::size_t 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; + } + } + + BOOST_INTRUSIVE_FORCEINLINE const key_equal &priv_equal() const + { return this->equal_holder_t::get(); } + + BOOST_INTRUSIVE_FORCEINLINE key_equal &priv_equal() + { return this->equal_holder_t::get(); } + + void priv_erasure_update_cache_range(std::size_t first_bucket_num, std::size_t last_bucket_num) + { + //If the last bucket is the end, the cache must be updated + //to the last position if all + if(this->priv_get_cache_bucket_num() == first_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() + { + 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; + } + ++cached_begin_; + } + } + + bucket_ptr cached_begin_; +}; + +//This wrapper around size_traits is used +//to maintain minimal container size with compilers like MSVC +//that have problems with EBO and multiple empty base classes +template +struct hashtable_size_wrapper + : public DeriveFrom +{ + private: + BOOST_MOVABLE_BUT_NOT_COPYABLE(hashtable_size_wrapper) + + public: + template + 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 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_wrapper + : public DeriveFrom +{ + private: + BOOST_MOVABLE_BUT_NOT_COPYABLE(hashtable_size_wrapper) + + public: + template + 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; + + typedef size_traits size_traits_const_t; + typedef size_traits size_traits_t; + + 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(); } +}; + +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_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 || + (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 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; + typedef typename bucket_plus_vtraits_t::bucket_traits bucket_traits; + typedef typename bucket_plus_vtraits_t::value_traits value_traits; + typedef typename bucket_plus_vtraits_t::bucket_type bucket_type; + typedef typename value_traits::value_type value_type; + typedef typename value_traits::pointer pointer; + typedef typename value_traits::const_pointer const_pointer; + typedef typename pointer_traits::reference reference; + typedef typename pointer_traits + ::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 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 + , VoidOrKeyOfValue + > hash_types_base; + typedef typename hash_types_base::key_of_value key_of_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 + < siterator + , downcast_node_to_value_t > local_iterator; + + typedef detail::transform_iterator + < siterator + , downcast_node_to_value_t > const_local_iterator; + + typedef detail::bool_ linear_buckets_t; + + hashdata_internal( const ValueTraits &val_traits, const bucket_traits &b_traits + , const hasher & h, const key_equal &e) + : split_bucket_hash_equal_t(val_traits, b_traits, h, e) + {} + + 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 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() + { + 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_init_cache(); + } + + void priv_init_buckets_and_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; + + //public functions + BOOST_INTRUSIVE_FORCEINLINE SizeType split_count() const BOOST_NOEXCEPT + { return this->split_bucket_hash_equal_t::get_hashtable_size_wrapper_size(); } + + 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 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 + { + 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_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 + { + 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, detail::true_) const //linear_buckets + { + 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) BOOST_NOEXCEPT + { + BOOST_STATIC_ASSERT((!stateful_value_traits)); + 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) BOOST_NOEXCEPT + { + BOOST_STATIC_ASSERT((!stateful_value_traits)); + 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) BOOST_NOEXCEPT + { + 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 BOOST_NOEXCEPT + { + 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 BOOST_NOEXCEPT + { return size_type(this->priv_usable_bucket_count()); } + + 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_NOEXCEPT + { return this->priv_bucket_pointer(); } + + 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_NOEXCEPT + { return this->cbegin(n); } + + static BOOST_INTRUSIVE_FORCEINLINE size_type suggested_upper_bucket_count(size_type n) BOOST_NOEXCEPT + { + 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) BOOST_NOEXCEPT + { + 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 BOOST_NOEXCEPT + { + return const_local_iterator + (this->priv_bucket_lbegin(n) + , this->priv_value_traits_ptr()); + } + + using split_bucket_hash_equal_t::end; + using split_bucket_hash_equal_t::cend; + + 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_NOEXCEPT + { return this->cend(n); } + + const_local_iterator cend(size_type n) const BOOST_NOEXCEPT + { + return const_local_iterator + ( this->priv_bucket_lend(n) + , this->priv_value_traits_ptr()); + } + + //Public functions for hashtable_impl + + 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_NOEXCEPT + { return this->cbegin(); } + + 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(); } + + BOOST_INTRUSIVE_FORCEINLINE key_equal key_eq() const + { 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 +//! is used to construct intrusive unordered_set and unordered_multiset containers. The +//! no-throw guarantee holds only, if the VoidOrKeyEqual object and Hasher don't throw. +//! +//! hashtable is a semi-intrusive container: each object to be stored in the +//! container must contain a proper hook, but the container also needs +//! additional auxiliary memory to work: hashtable needs a pointer to an array +//! of type `bucket_type` to be passed in the constructor. This bucket array must +//! have at least the same lifetime as the container. This makes the use of +//! hashtable more complicated than purely intrusive containers. +//! `bucket_type` is default-constructible, copyable and assignable +//! +//! The template parameter \c T is the type to be managed by the container. +//! The user can specify additional options and if no options are provided +//! default options are used. +//! +//! The container supports the following options: +//! \c base_hook<>/member_hook<>/value_traits<>, +//! \c constant_time_size<>, \c size_type<>, \c hash<> and \c equal<> +//! \c bucket_traits<>, power_2_buckets<>, cache_begin<> and incremental<>. +//! +//! hashtable only provides forward iterators but it provides 4 iterator types: +//! iterator and const_iterator to navigate through the whole container and +//! local_iterator and const_local_iterator to navigate through the values +//! stored in a single bucket. Local iterators are faster and smaller. +//! +//! It's not recommended to use non constant-time size hashtables because several +//! key functions, like "empty()", become non-constant time functions. Non +//! constant_time size hashtables are mainly provided to support auto-unlink hooks. +//! +//! hashtables, does not make automatic rehashings nor +//! offers functions related to a load factor. Rehashing can be explicitly requested +//! and the user must provide a new bucket array that will be used from that moment. +//! +//! Since no automatic rehashing is done, iterators are never invalidated when +//! inserting or erasing elements. Iterators are only invalidated when rehashing. +#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED) +template +#else +template +#endif +class hashtable_impl + : private get_hashtable_size_wrapper_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 + , VoidOrKeyOfValue + > hash_types_base; + public: + typedef ValueTraits value_traits; + + /// @cond + typedef BucketTraits bucket_traits; + + 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; + using internal_type::cend; + using internal_type::hash_function; + using internal_type::key_eq; + using internal_type::bucket_size; + using internal_type::bucket_count; + using internal_type::local_iterator_to; + using internal_type::s_local_iterator_to; + using internal_type::iterator_to; + using internal_type::bucket_pointer; + using internal_type::suggested_upper_bucket_count; + using internal_type::suggested_lower_bucket_count; + using internal_type::split_count; + + /// @endcond + + typedef typename value_traits::pointer pointer; + typedef typename value_traits::const_pointer const_pointer; + typedef typename value_traits::value_type value_type; + typedef typename hash_types_base::key_type key_type; + typedef typename hash_types_base::key_of_value key_of_value; + typedef typename pointer_traits::reference reference; + typedef typename pointer_traits::reference const_reference; + typedef typename pointer_traits::difference_type difference_type; + typedef SizeType size_type; + typedef typename internal_type::key_equal key_equal; + typedef typename internal_type::hasher hasher; + typedef typename internal_type::bucket_type bucket_type; + typedef typename internal_type::bucket_ptr bucket_ptr; + typedef typename internal_type::iterator iterator; + typedef typename internal_type::const_iterator const_iterator; + typedef typename internal_type::local_iterator local_iterator; + typedef typename internal_type::const_local_iterator const_local_iterator; + typedef typename value_traits::node_traits node_traits; + typedef typename node_traits::node node; + typedef typename pointer_traits + ::template rebind_pointer + < node >::type node_ptr; + typedef typename pointer_traits + ::template rebind_pointer + < const node >::type const_node_ptr; + typedef typename pointer_traits + ::reference node_reference; + typedef typename pointer_traits + ::reference const_node_reference; + 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; + + static const bool unique_keys = 0 != (BoolFlags & hash_bool_flags::unique_keys_pos); + static const bool constant_time_size = 0 != (BoolFlags & hash_bool_flags::constant_time_size_pos); + static const bool cache_begin = 0 != (BoolFlags & hash_bool_flags::cache_begin_pos); + 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 = 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; + private: + + //Configuration error: compare_hash<> can't be specified without store_hash<> + //See documentation for more explanations + BOOST_STATIC_ASSERT((!compare_hash || store_hash)); + + //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; + //We'll define group traits, but these won't be instantiated if + //optimize_multikey is not true + typedef unordered_group_adapter group_traits; + typedef circular_slist_algorithms group_algorithms; + typedef typename internal_type::store_hash_t store_hash_t; + 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 group_functions group_functions_t; + typedef node_functions node_functions_t; + + private: + //noncopyable, movable + BOOST_MOVABLE_BUT_NOT_COPYABLE(hashtable_impl) + + static const bool safemode_or_autounlink = internal_type::safemode_or_autounlink; + + //Constant-time size is incompatible with auto-unlink hooks! + BOOST_STATIC_ASSERT(!(constant_time_size && ((int)value_traits::link_mode == (int)auto_unlink))); + //Cache begin is incompatible with auto-unlink hooks! + BOOST_STATIC_ASSERT(!(cache_begin && ((int)value_traits::link_mode == (int)auto_unlink))); + + + /// @endcond + + public: + typedef insert_commit_data_impl insert_commit_data; + + private: + void default_init_actions() + { + 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)); + } + + BOOST_INTRUSIVE_FORCEINLINE SizeType priv_size_count() const BOOST_NOEXCEPT + { return this->internal_type::get_hashtable_size_wrapper_size(); } + + 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: + + //! Requires: buckets must not be being used by any other resource. + //! + //! Effects: Constructs an empty unordered_set, storing a reference + //! to the bucket array and copies of the key_hasher and equal_func functors. + //! + //! Complexity: Constant. + //! + //! Throws: If value_traits::node_traits::node + //! constructor throws (this does not happen with predefined Boost.Intrusive hooks) + //! or the copy constructor or invocation of hash_func or equal_func throws. + //! + //! Notes: buckets array must be disposed only after + //! *this is disposed. + explicit hashtable_impl ( const bucket_traits &b_traits + , const hasher & hash_func = hasher() + , 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->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. + //! + //! Effects: Constructs an empty container and inserts elements from + //! [b, e). + //! + //! Complexity: If N is distance(b, e): Average case is O(N) + //! (with a good hash function and with buckets_len >= N),worst case O(N^2). + //! + //! Throws: If value_traits::node_traits::node + //! constructor throws (this does not happen with predefined Boost.Intrusive hooks) + //! or the copy constructor or invocation of hasher or key_equal throws. + //! + //! Notes: buckets array must be disposed only after + //! *this is disposed. + template + hashtable_impl ( bool unique, Iterator b, Iterator e + , const bucket_traits &b_traits + , const hasher & hash_func = hasher() + , 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->default_init_actions(); + + //Now insert + if(unique) + this->insert_unique(b, e); + else + this->insert_equal(b, e); + } + + //! Effects: Constructs a container moving resources from another container. + //! Internal value traits, bucket traits, hasher and comparison are move constructed and + //! nodes belonging to x are linked to *this. + //! + //! Complexity: Constant. + //! + //! Throws: If value_traits::node_traits::node's + //! 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_BASE(internal_type, x)) + { + this->priv_swap_cache(x); + 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. + //! + hashtable_impl& operator=(BOOST_RV_REF(hashtable_impl) x) + { this->swap(x); return *this; } + + //! Effects: Detaches all elements from this. The objects in the unordered_set + //! are not deleted (i.e. no destructors are called). + //! + //! Complexity: Linear to the number of elements in the unordered_set, if + //! it's a safe-mode or auto-unlink value. Otherwise constant. + //! + //! Throws: Nothing. + ~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() BOOST_NOEXCEPT; + + //! Effects: Returns a const_iterator pointing to the beginning + //! of the unordered_set. + //! + //! Complexity: Amortized constant time. + //! Worst case (empty unordered_set): O(this->bucket_count()) + //! + //! Throws: Nothing. + const_iterator begin() const BOOST_NOEXCEPT; + + //! Effects: Returns a const_iterator pointing to the beginning + //! of the unordered_set. + //! + //! Complexity: Amortized constant time. + //! Worst case (empty unordered_set): O(this->bucket_count()) + //! + //! Throws: Nothing. + const_iterator cbegin() const BOOST_NOEXCEPT; + + //! Effects: Returns an iterator pointing to the end of the unordered_set. + //! + //! Complexity: Constant. + //! + //! Throws: Nothing. + 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 BOOST_NOEXCEPT; + + //! Effects: Returns a const_iterator pointing to the end of the unordered_set. + //! + //! Complexity: Constant. + //! + //! Throws: Nothing. + const_iterator cend() const BOOST_NOEXCEPT; + + //! Effects: Returns the hasher object used by the unordered_set. + //! + //! Complexity: Constant. + //! + //! Throws: If hasher copy-constructor throws. + hasher hash_function() const; + + //! Effects: Returns the key_equal object used by the unordered_set. + //! + //! Complexity: Constant. + //! + //! Throws: If key_equal copy-constructor throws. + key_equal key_eq() const; + + #endif + + //! Effects: Returns true if the container is empty. + //! + //! Complexity: if constant-time size and cache_begin options are disabled, + //! average constant time (worst case, with empty() == true: O(this->bucket_count()). + //! Otherwise constant. + //! + //! Throws: Nothing. + bool empty() const BOOST_NOEXCEPT + { + BOOST_IF_CONSTEXPR(constant_time_size){ + return !this->size(); + } + else if(cache_begin){ + return this->begin() == this->end(); + } + else{ + 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(!slist_node_algorithms::is_empty(b->get_node_ptr())){ + return false; + } + } + return true; + } + } + + //! Effects: Returns the number of elements stored in the unordered_set. + //! + //! Complexity: Linear to elements contained in *this if + //! constant_time_size is false. Constant-time otherwise. + //! + //! Throws: Nothing. + size_type size() const BOOST_NOEXCEPT + { + BOOST_IF_CONSTEXPR(constant_time_size) + return this->priv_size_count(); + else{ + 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 (std::size_t n = 0; n < bucket_cnt; ++n, ++b){ + len += slist_node_algorithms::count(b->get_node_ptr()) - 1u; + } + BOOST_INTRUSIVE_INVARIANT_ASSERT((len <= SizeType(-1))); + return size_type(len); + } + } + + //! Requires: the hasher and the equality function unqualified swap + //! call should not throw. + //! + //! Effects: Swaps the contents of two unordered_sets. + //! Swaps also the contained bucket array and equality and hasher functors. + //! + //! Complexity: Constant. + //! + //! Throws: If the swap() call for the comparison or hash functors + //! found using ADL throw. Basic guarantee. + void swap(hashtable_impl& other) + { + //These can throw + ::boost::adl_move_swap(this->priv_equal(), other.priv_equal()); + ::boost::adl_move_swap(this->priv_hasher(), other.priv_hasher()); + //These can't throw + ::boost::adl_move_swap(this->priv_bucket_traits(), other.priv_bucket_traits()); + ::boost::adl_move_swap(this->priv_value_traits(), other.priv_value_traits()); + this->priv_swap_cache(other); + this->priv_size_traits().swap(other.priv_size_traits()); + this->priv_split_traits().swap(other.priv_split_traits()); + } + + //! Requires: Disposer::operator()(pointer) shouldn't throw + //! Cloner should yield to nodes that compare equal and produce the same + //! hash than the original node. + //! + //! Effects: Erases all the elements from *this + //! calling Disposer::operator()(pointer), clones all the + //! elements from src calling Cloner::operator()(const_reference ) + //! and inserts them on *this. The hash function and the equality + //! predicate are copied from the source. + //! + //! If store_hash option is true, this method does not use the hash function. + //! + //! If any operation throws, all cloned elements are unlinked and disposed + //! calling Disposer::operator()(pointer). + //! + //! Complexity: Linear to erased plus inserted elements. + //! + //! Throws: If cloner or hasher throw or hash or equality predicate copying + //! throws. Basic guarantee. + template + BOOST_INTRUSIVE_FORCEINLINE void clone_from(const hashtable_impl &src, Cloner cloner, Disposer disposer) + { this->priv_clone_from(src, cloner, disposer); } + + //! Requires: Disposer::operator()(pointer) shouldn't throw + //! Cloner should yield to nodes that compare equal and produce the same + //! hash than the original node. + //! + //! Effects: Erases all the elements from *this + //! calling Disposer::operator()(pointer), clones all the + //! elements from src calling Cloner::operator()(reference) + //! and inserts them on *this. The hash function and the equality + //! predicate are copied from the source. + //! + //! If store_hash option is true, this method does not use the hash function. + //! + //! If any operation throws, all cloned elements are unlinked and disposed + //! calling Disposer::operator()(pointer). + //! + //! Complexity: Linear to erased plus inserted elements. + //! + //! Throws: If cloner or hasher throw or hash or equality predicate copying + //! throws. Basic guarantee. + template + BOOST_INTRUSIVE_FORCEINLINE void clone_from(BOOST_RV_REF(hashtable_impl) src, Cloner cloner, Disposer disposer) + { this->priv_clone_from(static_cast(src), cloner, disposer); } + + //! Requires: value must be an lvalue + //! + //! Effects: Inserts the value into the unordered_set. + //! + //! Returns: An iterator to the inserted value. + //! + //! Complexity: Average case O(1), worst case O(this->size()). + //! + //! Throws: If the internal hasher or the equality functor throws. Strong guarantee. + //! + //! Note: Does not affect the validity of iterators and references. + //! No copy-constructors are called. + iterator insert_equal(reference value) + { + size_type bucket_num; + std::size_t hash_value; + 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_end_sit(); + return this->priv_insert_equal_after_find(value, bucket_num, hash_value, prev, next_is_in_group); + } + + //! Requires: Dereferencing iterator must yield an lvalue + //! of type value_type. + //! + //! Effects: Equivalent to this->insert_equal(t) for each element in [b, e). + //! + //! Complexity: Average case O(N), where N is distance(b, e). + //! Worst case O(N*this->size()). + //! + //! Throws: If the internal hasher or the equality functor throws. Basic guarantee. + //! + //! Note: Does not affect the validity of iterators and references. + //! No copy-constructors are called. + template + void insert_equal(Iterator b, Iterator e) + { + for (; b != e; ++b) + this->insert_equal(*b); + } + + //! Requires: value must be an lvalue + //! + //! Effects: Tries to inserts value into the unordered_set. + //! + //! Returns: If the value + //! is not already present inserts it and returns a pair containing the + //! iterator to the new value and true. If there is an equivalent value + //! returns a pair containing an iterator to the already present value + //! and false. + //! + //! Complexity: Average case O(1), worst case O(this->size()). + //! + //! Throws: If the internal hasher or the equality functor throws. Strong guarantee. + //! + //! Note: Does not affect the validity of iterators and references. + //! No copy-constructors are called. + std::pair insert_unique(reference value) + { + insert_commit_data commit_data; + std::pair ret = this->insert_unique_check(key_of_value()(value), commit_data); + if(ret.second){ + ret.first = this->insert_unique_commit(value, commit_data); + } + return ret; + } + + //! Requires: Dereferencing iterator must yield an lvalue + //! of type value_type. + //! + //! Effects: Equivalent to this->insert_unique(t) for each element in [b, e). + //! + //! Complexity: Average case O(N), where N is distance(b, e). + //! Worst case O(N*this->size()). + //! + //! Throws: If the internal hasher or the equality functor throws. Basic guarantee. + //! + //! Note: Does not affect the validity of iterators and references. + //! No copy-constructors are called. + template + void insert_unique(Iterator b, Iterator e) + { + for (; b != e; ++b) + this->insert_unique(*b); + } + + //! Requires: "hash_func" must be a hash function that induces + //! the same hash values as the stored hasher. The difference is that + //! "hash_func" hashes the given key instead of the value_type. + //! + //! "equal_func" must be a equality function that induces + //! the same equality as key_equal. The difference is that + //! "equal_func" compares an arbitrary key with the contained values. + //! + //! Effects: Checks if a value can be inserted in the unordered_set, using + //! a user provided key instead of the value itself. + //! + //! Returns: If there is an equivalent value + //! returns a pair containing an iterator to the already present value + //! and false. If the value can be inserted returns true in the returned + //! pair boolean and fills "commit_data" that is meant to be used with + //! the "insert_commit" function. + //! + //! Complexity: Average case O(1), worst case O(this->size()). + //! + //! Throws: If hash_func or equal_func throw. Strong guarantee. + //! + //! Notes: This function is used to improve performance when constructing + //! a value_type is expensive: if there is an equivalent value + //! the constructed object must be discarded. Many times, the part of the + //! node that is used to impose the hash or the equality is much cheaper to + //! construct than the value_type and this function offers the possibility to + //! use that the part to check if the insertion will be successful. + //! + //! If the check is successful, the user can construct the value_type and use + //! "insert_commit" to insert the object in constant-time. + //! + //! "commit_data" remains valid for a subsequent "insert_commit" only if no more + //! objects are inserted or erased from the unordered_set. + //! + //! After a successful rehashing insert_commit_data remains valid. + template + std::pair insert_unique_check + ( const KeyType &key + , KeyHasher hash_func + , KeyEqual equal_func + , insert_commit_data &commit_data) + { + 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 + //! a user provided key instead of the value itself. + //! + //! Returns: If there is an equivalent value + //! returns a pair containing an iterator to the already present value + //! and false. If the value can be inserted returns true in the returned + //! pair boolean and fills "commit_data" that is meant to be used with + //! the "insert_commit" function. + //! + //! Complexity: Average case O(1), worst case O(this->size()). + //! + //! Throws: If hasher or key_compare throw. Strong guarantee. + //! + //! Notes: This function is used to improve performance when constructing + //! a value_type is expensive: if there is an equivalent value + //! the constructed object must be discarded. Many times, the part of the + //! node that is used to impose the hash or the equality is much cheaper to + //! construct than the value_type and this function offers the possibility to + //! use that the part to check if the insertion will be successful. + //! + //! If the check is successful, the user can construct the value_type and use + //! "insert_commit" to insert the object in constant-time. + //! + //! "commit_data" remains valid for a subsequent "insert_commit" only if no more + //! objects are inserted or erased from the unordered_set. + //! + //! After a successful rehashing insert_commit_data remains valid. + BOOST_INTRUSIVE_FORCEINLINE std::pair insert_unique_check + ( const key_type &key, insert_commit_data &commit_data) + { return this->insert_unique_check(key, this->priv_hasher(), this->priv_equal(), commit_data); } + + //! Requires: value must be an lvalue of type value_type. commit_data + //! must have been obtained from a previous call to "insert_check". + //! No objects should have been inserted or erased from the unordered_set between + //! the "insert_check" that filled "commit_data" and the call to "insert_commit". + //! + //! Effects: Inserts the value in the unordered_set using the information obtained + //! from the "commit_data" that a previous "insert_check" filled. + //! + //! Returns: An iterator to the newly inserted object. + //! + //! Complexity: Constant time. + //! + //! Throws: Nothing. + //! + //! 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. + //! + //! After a successful rehashing insert_commit_data remains valid. + 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()); + 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. + //! + //! Complexity: Average case O(1), worst case O(this->size()). + //! + //! Throws: Nothing. + //! + //! 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_NOEXCEPT + { this->erase_and_dispose(i, detail::null_disposer()); } + + //! Effects: Erases the range pointed to by b end e. + //! + //! Complexity: Average case O(distance(b, e)), + //! worst case O(this->size()). + //! + //! Throws: Nothing. + //! + //! 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_NOEXCEPT + { this->erase_and_dispose(b, e, detail::null_disposer()); } + + //! Effects: Erases all the elements with the given value. + //! + //! Returns: The number of erased elements. + //! + //! Complexity: Average case O(this->count(value)). + //! Worst case O(this->size()). + //! + //! Throws: If the internal hasher or the equality functor throws. + //! Basic guarantee. + //! + //! Note: Invalidates the iterators (but not the references) + //! to the erased elements. No destructors are called. + BOOST_INTRUSIVE_FORCEINLINE size_type erase(const key_type &key) + { return this->erase(key, this->priv_hasher(), this->priv_equal()); } + + //! Requires: "hash_func" must be a hash function that induces + //! the same hash values as the stored hasher. The difference is that + //! "hash_func" hashes the given key instead of the value_type. + //! + //! "equal_func" must be a equality function that induces + //! the same equality as key_equal. The difference is that + //! "equal_func" compares an arbitrary key with the contained values. + //! + //! Effects: Erases all the elements that have the same hash and + //! compare equal with the given key. + //! + //! Returns: The number of erased elements. + //! + //! Complexity: Average case O(this->count(value)). + //! Worst case O(this->size()). + //! + //! Throws: If hash_func or equal_func throw. Basic guarantee. + //! + //! Note: Invalidates the iterators (but not the references) + //! to the erased elements. No destructors are called. + template + BOOST_INTRUSIVE_FORCEINLINE size_type erase(const KeyType& key, KeyHasher hash_func, KeyEqual equal_func) + { return this->erase_and_dispose(key, hash_func, equal_func, detail::null_disposer()); } + + //! Requires: Disposer::operator()(pointer) shouldn't throw. + //! + //! Effects: Erases the element pointed to by i. + //! Disposer::operator()(pointer) is called for the removed element. + //! + //! Complexity: Average case O(1), worst case O(this->size()). + //! + //! Throws: Nothing. + //! + //! Note: Invalidates the iterators + //! to the erased elements. + template + BOOST_INTRUSIVE_DOC1ST(void + , typename detail::disable_if_convertible::type) + erase_and_dispose(const_iterator i, Disposer disposer) BOOST_NOEXCEPT + { + //Get the bucket number and local iterator for both iterators + 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. + //! + //! Effects: Erases the range pointed to by b end e. + //! Disposer::operator()(pointer) is called for the removed elements. + //! + //! Complexity: Average case O(distance(b, e)), + //! worst case O(this->size()). + //! + //! Throws: Nothing. + //! + //! Note: Invalidates the iterators + //! to the erased elements. + template + 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 + size_type first_bucket_num = this->priv_get_bucket_num(b); + + siterator before_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 = 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(e); + } + 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 + , 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); + } + } + + //! Requires: Disposer::operator()(pointer) shouldn't throw. + //! + //! Effects: Erases all the elements with the given value. + //! Disposer::operator()(pointer) is called for the removed elements. + //! + //! Returns: The number of erased elements. + //! + //! Complexity: Average case O(this->count(value)). + //! Worst case O(this->size()). + //! + //! Throws: If the internal hasher or the equality functor throws. + //! Basic guarantee. + //! + //! Note: Invalidates the iterators (but not the references) + //! to the erased elements. No destructors are called. + template + BOOST_INTRUSIVE_FORCEINLINE size_type erase_and_dispose(const key_type &key, Disposer disposer) + { return this->erase_and_dispose(key, this->priv_hasher(), this->priv_equal(), disposer); } + + //! Requires: Disposer::operator()(pointer) shouldn't throw. + //! + //! Effects: Erases all the elements with the given key. + //! according to the comparison functor "equal_func". + //! Disposer::operator()(pointer) is called for the removed elements. + //! + //! Returns: The number of erased elements. + //! + //! Complexity: Average case O(this->count(value)). + //! Worst case O(this->size()). + //! + //! Throws: If hash_func or equal_func throw. Basic guarantee. + //! + //! Note: Invalidates the iterators + //! to the erased elements. + template + size_type erase_and_dispose(const KeyType& key, KeyHasher hash_func + ,KeyEqual equal_func, Disposer disposer) + { + size_type bucket_num; + 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_end_sit(); + + 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(bucket_num), prev + , past_last_in_group + , this->make_node_disposer(disposer), optimize_multikey_t()); + } + else{ + 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_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_count(size_type(this->priv_size_count()-cnt)); + this->priv_erasure_update_cache(); + } + + return static_cast(cnt); + } + + //! Effects: Erases all of the elements. + //! + //! Complexity: Linear to the number of elements on the container. + //! if it's a safe-mode or auto-unlink value_type. Constant time otherwise. + //! + //! Throws: Nothing. + //! + //! Note: Invalidates the iterators (but not the references) + //! to the erased elements. No destructors are called. + void clear() BOOST_NOEXCEPT + { + this->priv_clear_buckets_and_cache(); + this->priv_size_count(size_type(0)); + } + + //! Requires: Disposer::operator()(pointer) shouldn't throw. + //! + //! Effects: Erases all of the elements. + //! + //! Complexity: Linear to the number of elements on the container. + //! Disposer::operator()(pointer) is called for the removed elements. + //! + //! Throws: Nothing. + //! + //! Note: Invalidates the iterators (but not the references) + //! to the erased elements. No destructors are called. + template + 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 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_count(size_type(0)); + } + this->priv_init_cache(); + } + + //! Effects: Returns the number of contained elements with the given value + //! + //! Complexity: Average case O(1), worst case O(this->size()). + //! + //! Throws: If the internal hasher or the equality functor throws. + BOOST_INTRUSIVE_FORCEINLINE size_type count(const key_type &key) const + { return this->count(key, this->priv_hasher(), this->priv_equal()); } + + //! Requires: "hash_func" must be a hash function that induces + //! the same hash values as the stored hasher. The difference is that + //! "hash_func" hashes the given key instead of the value_type. + //! + //! "equal_func" must be a equality function that induces + //! the same equality as key_equal. The difference is that + //! "equal_func" compares an arbitrary key with the contained values. + //! + //! Effects: Returns the number of contained elements with the given key + //! + //! Complexity: Average case O(1), worst case O(this->size()). + //! + //! Throws: If hash_func or equal throw. + template + size_type count(const KeyType &key, KeyHasher hash_func, KeyEqual equal_func) const + { + size_type cnt; + size_type n_bucket; + this->priv_local_equal_range(key, hash_func, equal_func, n_bucket, cnt); + return cnt; + } + + //! Effects: Finds an iterator to the first element is equal to + //! "value" or end() if that element does not exist. + //! + //! Complexity: Average case O(1), worst case O(this->size()). + //! + //! Throws: If the internal hasher or the equality functor throws. + BOOST_INTRUSIVE_FORCEINLINE iterator find(const key_type &key) + { return this->find(key, this->priv_hasher(), this->priv_equal()); } + + //! Requires: "hash_func" must be a hash function that induces + //! the same hash values as the stored hasher. The difference is that + //! "hash_func" hashes the given key instead of the value_type. + //! + //! "equal_func" must be a equality function that induces + //! the same equality as key_equal. The difference is that + //! "equal_func" compares an arbitrary key with the contained values. + //! + //! Effects: Finds an iterator to the first element whose key is + //! "key" according to the given hash and equality functor or end() if + //! that element does not exist. + //! + //! Complexity: Average case O(1), worst case O(this->size()). + //! + //! Throws: If hash_func or equal_func throw. + //! + //! Note: This function is used when constructing a value_type + //! is expensive and the value_type can be compared with a cheaper + //! key type. Usually this key is part of the value_type. + template + iterator find(const KeyType &key, KeyHasher hash_func, KeyEqual equal_func) + { + 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 + //! "key" or end() if that element does not exist. + //! + //! Complexity: Average case O(1), worst case O(this->size()). + //! + //! Throws: If the internal hasher or the equality functor throws. + BOOST_INTRUSIVE_FORCEINLINE const_iterator find(const key_type &key) const + { return this->find(key, this->priv_hasher(), this->priv_equal()); } + + //! Requires: "hash_func" must be a hash function that induces + //! the same hash values as the stored hasher. The difference is that + //! "hash_func" hashes the given key instead of the value_type. + //! + //! "equal_func" must be a equality function that induces + //! the same equality as key_equal. The difference is that + //! "equal_func" compares an arbitrary key with the contained values. + //! + //! Effects: Finds an iterator to the first element whose key is + //! "key" according to the given hasher and equality functor or end() if + //! that element does not exist. + //! + //! Complexity: Average case O(1), worst case O(this->size()). + //! + //! Throws: If hash_func or equal_func throw. + //! + //! Note: This function is used when constructing a value_type + //! is expensive and the value_type can be compared with a cheaper + //! key type. Usually this key is part of the value_type. + template + const_iterator find + (const KeyType &key, KeyHasher hash_func, KeyEqual equal_func) const + { + 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 + //! to value. Returns std::make_pair(this->end(), this->end()) if no such + //! elements exist. + //! + //! Complexity: Average case O(this->count(value)). Worst case O(this->size()). + //! + //! Throws: If the internal hasher or the equality functor throws. + BOOST_INTRUSIVE_FORCEINLINE std::pair equal_range(const key_type &key) + { return this->equal_range(key, this->priv_hasher(), this->priv_equal()); } + + //! Requires: "hash_func" must be a hash function that induces + //! the same hash values as the stored hasher. The difference is that + //! "hash_func" hashes the given key instead of the value_type. + //! + //! "equal_func" must be a equality function that induces + //! the same equality as key_equal. The difference is that + //! "equal_func" compares an arbitrary key with the contained values. + //! + //! Effects: Returns a range containing all elements with equivalent + //! keys. Returns std::make_pair(this->end(), this->end()) if no such + //! elements exist. + //! + //! Complexity: Average case O(this->count(key, hash_func, equal_func)). + //! Worst case O(this->size()). + //! + //! Throws: If hash_func or the equal_func throw. + //! + //! Note: This function is used when constructing a value_type + //! is expensive and the value_type can be compared with a cheaper + //! key type. Usually this key is part of the value_type. + template + std::pair equal_range + (const KeyType &key, KeyHasher hash_func, KeyEqual equal_func) + { + priv_equal_range_result ret = + this->priv_equal_range(key, hash_func, equal_func); + return std::pair + ( 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 + //! to value. Returns std::make_pair(this->end(), this->end()) if no such + //! elements exist. + //! + //! Complexity: Average case O(this->count(value)). Worst case O(this->size()). + //! + //! Throws: If the internal hasher or the equality functor throws. + BOOST_INTRUSIVE_FORCEINLINE std::pair + equal_range(const key_type &key) const + { return this->equal_range(key, this->priv_hasher(), this->priv_equal()); } + + //! Requires: "hash_func" must be a hash function that induces + //! the same hash values as the stored hasher. The difference is that + //! "hash_func" hashes the given key instead of the value_type. + //! + //! "equal_func" must be a equality function that induces + //! the same equality as key_equal. The difference is that + //! "equal_func" compares an arbitrary key with the contained values. + //! + //! Effects: Returns a range containing all elements with equivalent + //! keys. Returns std::make_pair(this->end(), this->end()) if no such + //! elements exist. + //! + //! Complexity: Average case O(this->count(key, hash_func, equal_func)). + //! Worst case O(this->size()). + //! + //! Throws: If the hasher or equal_func throw. + //! + //! Note: This function is used when constructing a value_type + //! is expensive and the value_type can be compared with a cheaper + //! key type. Usually this key is part of the value_type. + template + std::pair equal_range + (const KeyType &key, KeyHasher hash_func, KeyEqual equal_func) const + { + priv_equal_range_result ret = + this->priv_equal_range(key, hash_func, equal_func); + return std::pair + ( this->build_const_iterator(ret.first, ret.bucket_first) + , this->build_const_iterator(ret.second, ret.bucket_second)); + } + + #if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED) + + //! Requires: value must be an lvalue and shall be in a unordered_set of + //! appropriate type. Otherwise the behavior is undefined. + //! + //! Effects: Returns: a valid iterator belonging to the unordered_set + //! that points to the value + //! + //! Complexity: Constant. + //! + //! Throws: If the internal hash function throws. + 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. + //! + //! Effects: Returns: a valid const_iterator belonging to the + //! unordered_set that points to the value + //! + //! Complexity: Constant. + //! + //! Throws: If the internal hash function throws. + 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. + //! + //! Effects: Returns: a valid local_iterator belonging to the unordered_set + //! that points to the value + //! + //! Complexity: Constant. + //! + //! Throws: Nothing. + //! + //! Note: This static function is available only if the value traits + //! is stateless. + 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. + //! + //! Effects: Returns: a valid const_local_iterator belonging to + //! the unordered_set that points to the value + //! + //! Complexity: Constant. + //! + //! Throws: Nothing. + //! + //! Note: This static function is available only if the value traits + //! is stateless. + 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. + //! + //! Effects: Returns: a valid local_iterator belonging to the unordered_set + //! that points to the value + //! + //! Complexity: Constant. + //! + //! Throws: Nothing. + 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. + //! + //! Effects: Returns: a valid const_local_iterator belonging to + //! the unordered_set that points to the value + //! + //! Complexity: Constant. + //! + //! Throws: Nothing. + 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. + //! + //! Complexity: Constant. + //! + //! Throws: Nothing. + size_type bucket_count() const BOOST_NOEXCEPT; + + //! Requires: n is in the range [0, this->bucket_count()). + //! + //! Effects: Returns the number of elements in the nth bucket. + //! + //! Complexity: Constant. + //! + //! Throws: Nothing. + 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 + //! with keys equivalent to k would be found, if any such element existed. + //! + //! Complexity: Constant. + //! + //! 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->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 + //! "hash_func" hashes the given key instead of the value_type. + //! + //! Effects: Returns the index of the bucket in which elements + //! with keys equivalent to k would be found, if any such element existed. + //! + //! Complexity: Constant. + //! + //! Throws: If hash_func throws. + //! + //! 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_nbucket(hash_func(k)); } + + #if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED) + //! Effects: Returns the bucket array pointer passed in the constructor + //! or the last rehash function. + //! + //! Complexity: Constant. + //! + //! Throws: Nothing. + bucket_ptr bucket_pointer() const BOOST_NOEXCEPT; + + //! Requires: n is in the range [0, this->bucket_count()). + //! + //! Effects: Returns a local_iterator pointing to the beginning + //! of the sequence stored in the bucket n. + //! + //! Complexity: Constant. + //! + //! Throws: Nothing. + //! + //! 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) BOOST_NOEXCEPT; + + //! Requires: n is in the range [0, this->bucket_count()). + //! + //! Effects: Returns a const_local_iterator pointing to the beginning + //! of the sequence stored in the bucket n. + //! + //! Complexity: Constant. + //! + //! Throws: Nothing. + //! + //! 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 BOOST_NOEXCEPT; + + //! Requires: n is in the range [0, this->bucket_count()). + //! + //! Effects: Returns a const_local_iterator pointing to the beginning + //! of the sequence stored in the bucket n. + //! + //! Complexity: Constant. + //! + //! Throws: Nothing. + //! + //! 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 BOOST_NOEXCEPT; + + //! Requires: n is in the range [0, this->bucket_count()). + //! + //! Effects: Returns a local_iterator pointing to the end + //! of the sequence stored in the bucket n. + //! + //! Complexity: Constant. + //! + //! Throws: Nothing. + //! + //! 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) BOOST_NOEXCEPT; + + //! Requires: n is in the range [0, this->bucket_count()). + //! + //! Effects: Returns a const_local_iterator pointing to the end + //! of the sequence stored in the bucket n. + //! + //! Complexity: Constant. + //! + //! Throws: Nothing. + //! + //! 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 BOOST_NOEXCEPT; + + //! Requires: n is in the range [0, this->bucket_count()). + //! + //! Effects: Returns a const_local_iterator pointing to the end + //! of the sequence stored in the bucket n. + //! + //! Complexity: Constant. + //! + //! Throws: Nothing. + //! + //! 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 BOOST_NOEXCEPT; + #endif //#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED) + + //! Requires: new_bucket_traits can hold a pointer to a new bucket array + //! or the same as the old bucket array with a different length. new_size is the length of the + //! the array pointed by new_buckets. If new_bucket_traits.bucket_begin() == this->bucket_pointer() + //! new_bucket_traits.bucket_count() can be bigger or smaller than this->bucket_count(). + //! 'new_bucket_traits' copy constructor should not throw. + //! + //! Effects: + //! If `new_bucket_traits.bucket_begin() == this->bucket_pointer()` is false, + //! unlinks values from the old bucket and inserts then in the new one according + //! to the hash value of values. + //! + //! If `new_bucket_traits.bucket_begin() == this->bucket_pointer()` is true, + //! the implementations avoids moving values as much as possible. + //! + //! Bucket traits hold by *this is assigned from new_bucket_traits. + //! If the container is configured as incremental<>, the split bucket is set + //! to the new bucket_count(). + //! + //! If store_hash option is true, this method does not use the hash function. + //! If false, the implementation tries to minimize calls to the hash function + //! (e.g. once for equivalent values if optimize_multikey is true). + //! + //! If rehash is successful updates the internal bucket_traits with new_bucket_traits. + //! + //! Complexity: Average case linear in this->size(), worst case quadratic. + //! + //! Throws: If the hasher functor throws. Basic guarantee. + BOOST_INTRUSIVE_FORCEINLINE void rehash(const bucket_traits &new_bucket_traits) + { 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 + //! preserved so a fast full rehash recovers invariants for *this without extracting and + //! reinserting all elements again. + //! + //! Requires: Calls produced to the hash function should not alter the value uniqueness + //! properties of already inserted elements. If hasher(key1) == hasher(key2) was true when + //! elements were inserted, it shall be true during calls produced in the execution of this function. + //! + //! key_equal is not called inside this function so it is assumed that key_equal(value1, value2) + //! should produce the same results as before for inserted elements. + //! + //! Effects: Reprocesses all values hold by *this, recalculating their hash values + //! and redistributing them though the buckets. + //! + //! If store_hash option is true, this method uses the hash function and updates the stored hash value. + //! + //! Complexity: Average case linear in this->size(), worst case quadratic. + //! + //! Throws: If the hasher functor throws. Basic guarantee. + BOOST_INTRUSIVE_FORCEINLINE void full_rehash() + { this->priv_rehash_impl(this->priv_bucket_traits(), true); } + + //! Requires: + //! + //! Effects: + //! + //! Complexity: + //! + //! Throws: + //! + //! Note: this method is only available if incremental option is activated. + bool incremental_rehash(bool grow = true) + { + //This function is only available for containers with incremental hashing + BOOST_STATIC_ASSERT(( incremental && power_2_buckets )); + 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 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. + 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 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 = 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/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; + } + + //! Effects: If new_bucket_traits.bucket_count() is not + //! this->bucket_count()/2 or this->bucket_count()*2, or + //! this->split_bucket() != new_bucket_traits.bucket_count() returns false + //! and does nothing. + //! + //! Otherwise, copy assigns new_bucket_traits to the internal bucket_traits + //! and transfers all the objects from old buckets to the new ones. + //! + //! Complexity: Linear to size(). + //! + //! Throws: Nothing + //! + //! Note: this method is only available if incremental option is activated. + 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 )); + 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_count/2 == old_bucket_count){ + if(!(split_idx >= old_bucket_count)) + return false; + } + 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 = (size_type)this->priv_get_cache_bucket_num(); + const bucket_ptr old_buckets = this->priv_bucket_pointer(); + + + 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){ + 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); + } + //Reset cache to safe position + this->priv_set_cache_bucket_num(ini_n); + } + + this->priv_set_sentinel_bucket(); + return true; + } + + #if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED) + + //! Requires: incremental<> option must be set + //! + //! Effects: returns the current split count + //! + //! Complexity: Constant + //! + //! Throws: Nothing + 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 + //! used to create bucket arrays with a size that will usually improve + //! container's performance. If such value does not exist, the + //! higher possible value is returned. + //! + //! Complexity: Amortized constant time. + //! + //! Throws: Nothing. + 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 + //! used to create bucket arrays with a size that will usually improve + //! container's performance. If such value does not exist, the + //! lowest possible value is returned. + //! + //! Complexity: Amortized constant time. + //! + //! Throws: Nothing. + static size_type suggested_lower_bucket_count(size_type n) BOOST_NOEXCEPT; + #endif //#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED) + + + friend bool operator==(const hashtable_impl &x, const hashtable_impl &y) + { + //Taken from N3068 + 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))); + if (boost::intrusive::iterator_distance(eqx.first, eqx.second) != + boost::intrusive::iterator_distance(eqy.first, eqy.second) || + !(priv_algo_is_permutation)(eqx.first, eqx.second, eqy.first) ){ + return false; + } + ix = eqx.second; + } + return true; + } + + friend bool operator!=(const hashtable_impl &x, const hashtable_impl &y) + { return !(x == y); } + + friend bool operator<(const hashtable_impl &x, const hashtable_impl &y) + { return ::boost::intrusive::algo_lexicographical_compare(x.begin(), x.end(), y.begin(), y.end()); } + + friend bool operator>(const hashtable_impl &x, const hashtable_impl &y) + { return y < x; } + + friend bool operator<=(const hashtable_impl &x, const hashtable_impl &y) + { return !(y < x); } + + friend bool operator>=(const hashtable_impl &x, const hashtable_impl &y) + { return !(x < y); } + + /// @cond + BOOST_INTRUSIVE_FORCEINLINE void check() const {} + private: + + 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(); + const size_type new_bucket_count = static_cast(nbc); + const bucket_ptr old_buckets = this->priv_bucket_pointer(); + 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)))); + + 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. + const bool fast_shrink = (!do_full_rehash) && (!incremental) && (old_bucket_count >= new_bucket_count) && + (power_2_buckets || (old_bucket_count % new_bucket_count) == 0); + //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; + 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 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_count(); + this->priv_size_count(0); + //Put cache to safe position + 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(size_type n = old_bucket_cache; n < old_bucket_count; ++n){ + bucket_type &old_bucket = old_buckets[difference_type(n)]; + if(!fast_shrink){ + 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_siterator(i); + hash_value = this->priv_hasher()(key_of_value()(v)); + 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_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 = (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 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[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 = (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[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_count(size_backup); + this->split_count(split); + if(&new_bucket_traits != &this->priv_bucket_traits()) + this->priv_bucket_traits() = new_bucket_traits; + this->priv_set_sentinel_bucket(); + this->priv_set_cache_bucket_num(new_first_bucket_num); + rollback1.release(); + rollback2.release(); + } + + template + void priv_clone_from(MaybeConstHashtableImpl &src, Cloner cloner, Disposer disposer) + { + this->clear_and_dispose(disposer); + if(!constant_time_size || !src.empty()){ + const size_type src_bucket_count = src.bucket_count(); + const size_type dst_bucket_count = this->bucket_count(); + //Check power of two bucket array if the option is activated + BOOST_INTRUSIVE_INVARIANT_ASSERT + (!power_2_buckets || (0 == (src_bucket_count & (src_bucket_count-1)))); + BOOST_INTRUSIVE_INVARIANT_ASSERT + (!power_2_buckets || (0 == (dst_bucket_count & (dst_bucket_count-1)))); + //If src bucket count is bigger or equal, structural copy is possible + const bool structural_copy = (!incremental) && (src_bucket_count >= dst_bucket_count) && + (power_2_buckets || (src_bucket_count % dst_bucket_count) == 0); + if(structural_copy){ + this->priv_structural_clone_from(src, cloner, disposer); + } + else{ + //Unlike previous cloning algorithm, this can throw + //if cloner, hasher or comparison functor throw + typedef typename detail::if_c< detail::is_const::value + , typename MaybeConstHashtableImpl::const_iterator + , typename MaybeConstHashtableImpl::iterator + >::type clone_iterator; + clone_iterator b(src.begin()), e(src.end()); + detail::exception_disposer rollback(*this, disposer); + 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_nbucket(hash_to_store); + typedef typename detail::if_c + ::value, const_reference, reference>::type reference_type; + reference_type r = *b; + this->priv_clone_front_in_bucket(bucket_number, r, hash_to_store, cloner); + } + rollback.release(); + } + } + } + + template + void priv_clone_front_in_bucket( size_type const bucket_number + , typename detail::identity::type src_ref + , std::size_t const hash_to_store, Cloner cloner) + { + //No need to check for duplicates and insert it in the first position + //as this is an unordered container. So use minimal insertion code + 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 && !this->priv_bucket_empty(bucket_number) && + this->priv_equal()( key_of_value()(src_ref) + , 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); + } + + template + void priv_structural_clone_from(MaybeConstHashtableImpl &src, Cloner cloner, Disposer disposer) + { + //First clone the first ones + const size_type src_bucket_count = src.bucket_count(); + const size_type dst_bucket_count = this->bucket_count(); + size_type constructed = 0; + typedef typename internal_type::template typeof_node_disposer::type NodeDisposer; + NodeDisposer node_disp(disposer, &this->priv_value_traits()); + + 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){ + + 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_siterator(b); + this->priv_clone_front_in_bucket + (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_count(src.priv_size_count()); + this->split_count(dst_bucket_count); + this->priv_set_cache_bucket_num(0u); + this->priv_erasure_update_cache(); + } + + 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 = 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 || slist_node_algorithms::unique(n)); + //Shortcut to optimize_multikey cases + group_functions_t::insert_in_group + ( 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_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 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); + + 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); + + 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_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 + { + siterator it(this->sit_begin(b)); + siterator const endit(this->sit_end(b)); + + 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; + } + } + 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 + , KeyHasher hash_func + , KeyEqual equal_func + , size_type &found_bucket + , size_type &cnt) const + { + std::size_t internal_cnt = 0; + //Let's see if the element is present + + siterator prev; + size_type n_bucket; + std::size_t h; + std::pair to_return + ( this->priv_find(key, hash_func, equal_func, n_bucket, h, prev) + , 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 + siterator it = to_return.first; + 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{ + 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 = 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 + priv_equal_range_result priv_equal_range + ( const KeyType &key + , KeyHasher hash_func + , KeyEqual equal_func) const + { + size_type n_bucket; + size_type cnt; + + //Let's see if the element is present + 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. + 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 r; + } + + 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())); } + + size_type priv_get_bucket_num_hash_dispatch(siterator it, detail::false_) BOOST_NOEXCEPT //NO store_hash + { + 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); + } + + + 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 + , class PackedOptions + > +struct make_bucket_traits +{ + //Real value traits must be calculated from options + typedef typename detail::get_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 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_t + , specified_bucket_traits + >::type type; +}; +/// @endcond + +//! Helper metafunction to define a \c hashtable that yields to the same type when the +//! same options (either explicitly or implicitly) are used. +#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED) || defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES) +template +#else +template +#endif +struct make_hashtable +{ + /// @cond + typedef typename pack_options + < hashtable_defaults, + #if !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES) + O1, O2, O3, O4, O5, O6, O7, O8, O9, O10, O11 + #else + Options... + #endif + >::type packed_options; + + typedef typename detail::get_value_traits + ::type value_traits; + + typedef typename make_bucket_traits + ::type bucket_traits; + + typedef hashtable_impl + < value_traits + , typename packed_options::key_of_value + , typename packed_options::hash + , typename packed_options::equal + , bucket_traits + , typename packed_options::size_type + , (std::size_t(false)*hash_bool_flags::unique_keys_pos) + |(std::size_t(packed_options::constant_time_size)*hash_bool_flags::constant_time_size_pos) + |(std::size_t(packed_options::power_2_buckets)*hash_bool_flags::power_2_buckets_pos) + |(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 + typedef implementation_defined type; +}; + +#if !defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED) + +#if defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES) +template +#else +template +#endif +class hashtable + : public make_hashtable::type +{ + typedef typename make_hashtable::type Base; + BOOST_MOVABLE_BUT_NOT_COPYABLE(hashtable) + + public: + typedef typename Base::value_traits value_traits; + typedef typename Base::iterator iterator; + typedef typename Base::const_iterator const_iterator; + typedef typename Base::bucket_ptr bucket_ptr; + typedef typename Base::size_type size_type; + typedef typename Base::hasher hasher; + typedef typename Base::bucket_traits bucket_traits; + typedef typename Base::key_equal key_equal; + + //Assert if passed value traits are compatible with the type + BOOST_STATIC_ASSERT((detail::is_same::value)); + + BOOST_INTRUSIVE_FORCEINLINE explicit hashtable ( const bucket_traits &b_traits + , const hasher & hash_func = hasher() + , const key_equal &equal_func = key_equal() + , const value_traits &v_traits = value_traits()) + : Base(b_traits, hash_func, equal_func, v_traits) + {} + + BOOST_INTRUSIVE_FORCEINLINE hashtable(BOOST_RV_REF(hashtable) x) + : Base(BOOST_MOVE_BASE(Base, x)) + {} + + BOOST_INTRUSIVE_FORCEINLINE hashtable& operator=(BOOST_RV_REF(hashtable) x) + { return static_cast(this->Base::operator=(BOOST_MOVE_BASE(Base, x))); } + + template + BOOST_INTRUSIVE_FORCEINLINE void clone_from(const hashtable &src, Cloner cloner, Disposer disposer) + { Base::clone_from(src, cloner, disposer); } + + template + BOOST_INTRUSIVE_FORCEINLINE void clone_from(BOOST_RV_REF(hashtable) src, Cloner cloner, Disposer disposer) + { Base::clone_from(BOOST_MOVE_BASE(Base, src), cloner, disposer); } +}; + +#endif + +} //namespace intrusive +} //namespace boost + +#include + +#endif //BOOST_INTRUSIVE_HASHTABLE_HPP diff --git a/third_party/boost/libs/intrusive/include/boost/intrusive/intrusive_fwd.hpp b/third_party/boost/libs/intrusive/include/boost/intrusive/intrusive_fwd.hpp new file mode 100644 index 00000000000..127dbc9e8ea --- /dev/null +++ b/third_party/boost/libs/intrusive/include/boost/intrusive/intrusive_fwd.hpp @@ -0,0 +1,768 @@ +///////////////////////////////////////////////////////////////////////////// +// +// (C) Copyright Ion Gaztanaga 2007-2013 +// +// 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_FWD_HPP +#define BOOST_INTRUSIVE_FWD_HPP + +#ifndef BOOST_CONFIG_HPP +# include +#endif +# +#ifndef BOOST_CSTDINT_HPP +# include +#endif +# +#if defined(BOOST_HAS_PRAGMA_ONCE) +# pragma once +#endif + +//! \file +//! This header file forward declares most Intrusive classes. +//! +//! It forward declares the following containers and hooks: +//! - boost::intrusive::slist / boost::intrusive::slist_base_hook / boost::intrusive::slist_member_hook +//! - boost::intrusive::list / boost::intrusive::list_base_hook / boost::intrusive::list_member_hook +//! - boost::intrusive::bstree / boost::intrusive::bs_set / boost::intrusive::bs_multiset / +//! boost::intrusive::bs_set_base_hook / boost::intrusive::bs_set_member_hook +//! - boost::intrusive::rbtree / boost::intrusive::set / boost::intrusive::multiset / +//! boost::intrusive::set_base_hook / boost::intrusive::set_member_hook +//! - boost::intrusive::avltree / boost::intrusive::avl_set / boost::intrusive::avl_multiset / +//! boost::intrusive::avl_set_base_hook / boost::intrusive::avl_set_member_hook +//! - boost::intrusive::splaytree / boost::intrusive::splay_set / boost::intrusive::splay_multiset +//! - boost::intrusive::sgtree / boost::intrusive::sg_set / boost::intrusive::sg_multiset +//! - boost::intrusive::treap / boost::intrusive::treap_set / boost::intrusive::treap_multiset +//! - boost::intrusive::hashtable / boost::intrusive::unordered_set / boost::intrusive::unordered_multiset / +//! boost::intrusive::unordered_set_base_hook / boost::intrusive::unordered_set_member_hook / +//! - boost::intrusive::any_base_hook / boost::intrusive::any_member_hook +//! +//! It forward declares the following container or hook options: +//! - boost::intrusive::constant_time_size / boost::intrusive::size_type / boost::intrusive::compare / boost::intrusive::equal +//! - boost::intrusive::floating_point / boost::intrusive::priority / boost::intrusive::hash +//! - boost::intrusive::value_traits / boost::intrusive::member_hook / boost::intrusive::function_hook / boost::intrusive::base_hook +//! - boost::intrusive::void_pointer / boost::intrusive::tag / boost::intrusive::link_mode +//! - boost::intrusive::optimize_size / boost::intrusive::linear / boost::intrusive::cache_last +//! - boost::intrusive::bucket_traits / boost::intrusive::store_hash / boost::intrusive::optimize_multikey +//! - boost::intrusive::power_2_buckets / boost::intrusive::cache_begin / boost::intrusive::compare_hash / boost::intrusive::incremental +//! +//! It forward declares the following value traits utilities: +//! - boost::intrusive::value_traits / boost::intrusive::derivation_value_traits / +//! boost::intrusive::trivial_value_traits +//! +//! Finally it forward declares the following general purpose utilities: +//! - boost::intrusive::pointer_plus_bits / boost::intrusive::priority_compare. + +#if !defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED) + +#include +#include +#include + +namespace boost { +namespace intrusive { + +#if !defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED) +# ifdef BOOST_HAS_INTPTR_T + using ::boost::uintptr_t; +# else + typedef std::size_t uintptr_t; +# endif +#endif + +//////////////////////////// +// Node algorithms +//////////////////////////// + +//Algorithms predeclarations +template +class circular_list_algorithms; + +template +class circular_slist_algorithms; + +template +class linear_slist_algorithms; + +template +class bstree_algorithms; + +template +class rbtree_algorithms; + +template +class avltree_algorithms; + +template +class sgtree_algorithms; + +template +class splaytree_algorithms; + +template +class treap_algorithms; + +//////////////////////////// +// Containers +//////////////////////////// + +//slist +#if !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES) +template + < class T + , class O1 = void + , class O2 = void + , class O3 = void + , class O4 = void + , class O5 = void + , class O6 = void + > +#else +template +#endif +class slist; + +#if !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES) +template + < class O1 = void + , class O2 = void + , class O3 = void + > +#else +template +#endif +class slist_base_hook; + +#if !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES) +template + < class O1 = void + , class O2 = void + , class O3 = void + > +#else +template +#endif +class slist_member_hook; + +//list +#if !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES) +template + < class T + , class O1 = void + , class O2 = void + , class O3 = void + , class O4 = void + > +#else +template +#endif +class list; + +#if !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES) +template + < class O1 = void + , class O2 = void + , class O3 = void + > +#else +template +#endif +class list_base_hook; + +#if !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES) +template + < class O1 = void + , class O2 = void + , class O3 = void + > +#else +template +#endif +class list_member_hook; + +//rbtree/set/multiset +#if !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES) +template + < class T + , class O1 = void + , class O2 = void + , class O3 = void + , class O4 = void + , class O5 = void + , class O6 = void + > +#else +template +#endif +class rbtree; + +#if !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES) +template + < class T + , class O1 = void + , class O2 = void + , class O3 = void + , class O4 = void + , class O5 = void + , class O6 = void + > +#else +template +#endif +class set; + +#if !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES) +template + < class T + , class O1 = void + , class O2 = void + , class O3 = void + , class O4 = void + , class O5 = void + , class O6 = void + > +#else +template +#endif +class multiset; + +#if !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES) +template + < class O1 = void + , class O2 = void + , class O3 = void + , class O4 = void + > +#else +template +#endif +class set_base_hook; + +#if !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES) +template + < class O1 = void + , class O2 = void + , class O3 = void + , class O4 = void + > +#else +template +#endif +class set_member_hook; + +//splaytree/splay_set/splay_multiset +#if !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES) +template + < class T + , class O1 = void + , class O2 = void + , class O3 = void + , class O4 = void + , class O5 = void + , class O6 = void + > +#else +template +#endif +class splaytree; + +#if !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES) +template + < class T + , class O1 = void + , class O2 = void + , class O3 = void + , class O4 = void + , class O5 = void + , class O6 = void + > +#else +template +#endif +class splay_set; + +#if !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES) +template + < class T + , class O1 = void + , class O2 = void + , class O3 = void + , class O4 = void + , class O5 = void + , class O6 = void + > +#else +template +#endif +class splay_multiset; + +//avltree/avl_set/avl_multiset +#if !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES) +template + < class T + , class O1 = void + , class O2 = void + , class O3 = void + , class O4 = void + , class O5 = void + , class O6 = void + > +#else +template +#endif +class avltree; + +#if !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES) +template + < class T + , class O1 = void + , class O2 = void + , class O3 = void + , class O4 = void + , class O5 = void + , class O6 = void + > +#else +template +#endif +class avl_set; + +#if !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES) +template + < class T + , class O1 = void + , class O2 = void + , class O3 = void + , class O4 = void + , class O5 = void + , class O6 = void + > +#else +template +#endif +class avl_multiset; + +#if !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES) +template + < class O1 = void + , class O2 = void + , class O3 = void + , class O4 = void + > +#else +template +#endif +class avl_set_base_hook; + +#if !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES) +template + < class O1 = void + , class O2 = void + , class O3 = void + , class O4 = void + > +#else +template +#endif +class avl_set_member_hook; + + +//treap/treap_set/treap_multiset +#if !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES) +template + < class T + , class O1 = void + , class O2 = void + , class O3 = void + , class O4 = void + , class O5 = void + , class O6 = void + , class O7 = void + > +#else +template +#endif +class treap; + +#if !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES) +template + < class T + , class O1 = void + , class O2 = void + , class O3 = void + , class O4 = void + , class O5 = void + , class O6 = void + , class O7 = void + > +#else +template +#endif +class treap_set; + +#if !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES) +template + < class T + , class O1 = void + , class O2 = void + , class O3 = void + , class O4 = void + , class O5 = void + , class O6 = void + , class O7 = void + > +#else +template +#endif +class treap_multiset; + +//sgtree/sg_set/sg_multiset +#if !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES) +template + < class T + , class O1 = void + , class O2 = void + , class O3 = void + , class O4 = void + , class O5 = void + , class O6 = void + > +#else +template +#endif +class sgtree; + +#if !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES) +template + < class T + , class O1 = void + , class O2 = void + , class O3 = void + , class O4 = void + , class O5 = void + , class O6 = void + > +#else +template +#endif +class sg_set; + +#if !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES) +template + < class T + , class O1 = void + , class O2 = void + , class O3 = void + , class O4 = void + , class O5 = void + , class O6 = void + > +#else +template +#endif +class sg_multiset; + +#if !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES) +template + < class T + , class O1 = void + , class O2 = void + , class O3 = void + , class O4 = void + , class O5 = void + , class O6 = void + > +#else +template +#endif +class bstree; + +#if !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES) +template + < class T + , class O1 = void + , class O2 = void + , class O3 = void + , class O4 = void + , class O5 = void + , class O6 = void + > +#else +template +#endif +class bs_set; + +#if !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES) +template + < class T + , class O1 = void + , class O2 = void + , class O3 = void + , class O4 = void + , class O5 = void + , class O6 = void + > +#else +template +#endif +class bs_multiset; + +#if !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES) +template + < class O1 = void + , class O2 = void + , class O3 = void + > +#else +template +#endif +class bs_set_base_hook; + +#if !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES) +template + < class O1 = void + , class O2 = void + , class O3 = void + > +#else +template +#endif +class bs_set_member_hook; + +//hashtable/unordered_set/unordered_multiset + +#if !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES) +template + < class T + , class O1 = void + , class O2 = void + , class O3 = void + , class O4 = void + , class O5 = void + , class O6 = void + , class O7 = void + , class O8 = void + , class O9 = void + , class O10 = void + > +#else +template +#endif +class hashtable; + +#if !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES) +template + < class T + , class O1 = void + , class O2 = void + , class O3 = void + , class O4 = void + , class O5 = void + , class O6 = void + , class O7 = void + , class O8 = void + , class O9 = void + , class O10 = void + , class O11 = void + > +#else +template +#endif +class unordered_set; + +#if !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES) +template + < class T + , class O1 = void + , class O2 = void + , class O3 = void + , class O4 = void + , class O5 = void + , class O6 = void + , class O7 = void + , class O8 = void + , class O9 = void + , class O10 = void + , class O11 = void + > +#else +template +#endif +class unordered_multiset; + +#if !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES) +template + < class O1 = void + , class O2 = void + , class O3 = void + , class O4 = void + > +#else +template +#endif +class unordered_set_base_hook; + +#if !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES) +template + < class O1 = void + , class O2 = void + , class O3 = void + , class O4 = void + > +#else +template +#endif +class unordered_set_member_hook; + +#if !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES) +template + < class O1 = void + , class O2 = void + , class O3 = void + > +#else +template +#endif +class any_base_hook; + +#if !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES) +template + < class O1 = void + , class O2 = void + , class O3 = void + > +#else +template +#endif +class any_member_hook; + +//Options + +template +struct constant_time_size; + +template +struct size_type; + +template +struct compare; + +template +struct floating_point; + +template +struct equal; + +template +struct priority; + +template +struct hash; + +template struct value_traits; + +template< typename Parent + , typename MemberHook + , MemberHook Parent::* PtrToMember> +struct member_hook; + +template +struct function_hook; + +template +struct base_hook; + +template +struct void_pointer; + +template +struct tag; + +template +struct link_mode; + +template struct +optimize_size; + +template +struct linear; + +template +struct cache_last; + +template +struct bucket_traits; + +template +struct store_hash; + +template +struct optimize_multikey; + +template +struct power_2_buckets; + +template +struct cache_begin; + +template +struct compare_hash; + +template +struct incremental; + +//Value traits + +template +struct value_traits; + +template< typename Parent + , typename MemberHook + , MemberHook Parent::* PtrToMember> +struct member_hook; + +template< typename Functor> +struct function_hook; + +template +struct base_hook; + +template +struct derivation_value_traits; + +template +struct trivial_value_traits; + +//Additional utilities + +template +struct max_pointer_plus_bits; + +template +struct max_pointer_plus_bits; + +template +struct pointer_plus_bits; + +template +struct pointer_plus_bits; + +template +struct pointer_traits; + +template +struct pointer_traits; + +} //namespace intrusive { +} //namespace boost { + +#endif //#if !defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED) + +#endif //#ifndef BOOST_INTRUSIVE_FWD_HPP diff --git a/third_party/boost/libs/intrusive/include/boost/intrusive/linear_slist_algorithms.hpp b/third_party/boost/libs/intrusive/include/boost/intrusive/linear_slist_algorithms.hpp new file mode 100644 index 00000000000..a616d7ed710 --- /dev/null +++ b/third_party/boost/libs/intrusive/include/boost/intrusive/linear_slist_algorithms.hpp @@ -0,0 +1,422 @@ +///////////////////////////////////////////////////////////////////////////// +// +// (C) Copyright Olaf Krzikalla 2004-2006. +// (C) Copyright Ion Gaztanaga 2006-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_LINEAR_SLIST_ALGORITHMS_HPP +#define BOOST_INTRUSIVE_LINEAR_SLIST_ALGORITHMS_HPP + +#include +#include +#include +#include +#include +#include //for node_pair + +#if defined(BOOST_HAS_PRAGMA_ONCE) +# pragma once +#endif + +namespace boost { +namespace intrusive { + +//! linear_slist_algorithms provides basic algorithms to manipulate nodes +//! forming a linear singly linked list. +//! +//! linear_slist_algorithms is configured with a NodeTraits class, which encapsulates the +//! information about the node to be manipulated. NodeTraits must support the +//! following interface: +//! +//! Typedefs: +//! +//! node: The type of the node that forms the linear list +//! +//! node_ptr: A pointer to a node +//! +//! const_node_ptr: A pointer to a const node +//! +//! Static functions: +//! +//! static node_ptr get_next(const_node_ptr n); +//! +//! static void set_next(node_ptr n, node_ptr next); +template +class linear_slist_algorithms + /// @cond + : public detail::common_slist_algorithms + /// @endcond +{ + /// @cond + typedef detail::common_slist_algorithms base_t; + /// @endcond + public: + typedef typename NodeTraits::node node; + 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) + + //! Effects: Constructs an non-used list element, putting the next + //! pointer to null: + //! NodeTraits::get_next(this_node) == node_ptr() + //! + //! Complexity: Constant + //! + //! Throws: Nothing. + static void init(node_ptr this_node) BOOST_NOEXCEPT; + + //! Requires: this_node must be in a circular list or be an empty circular list. + //! + //! Effects: Returns true is "this_node" is the only node of a circular list: + //! or it's a not inserted node: + //! return node_ptr() == NodeTraits::get_next(this_node) || NodeTraits::get_next(this_node) == this_node + //! + //! Complexity: Constant + //! + //! Throws: Nothing. + 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)" + //! + //! Complexity: Constant + //! + //! Throws: Nothing. + 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. + //! + //! Effects: Unlinks the next node of prev_node from the circular list. + //! + //! Complexity: Constant + //! + //! Throws: Nothing. + 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. + //! + //! Effects: Unlinks the range (prev_node, last_node) from the linear list. + //! + //! Complexity: Constant + //! + //! Throws: Nothing. + 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. + //! + //! Effects: Links this_node after prev_node in the linear list. + //! + //! Complexity: Constant + //! + //! Throws: Nothing. + 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. + //! + //! Effects: Removes the nodes from (b, e] range from their linear list and inserts + //! them after p in p's linear list. + //! + //! Complexity: Constant + //! + //! Throws: Nothing. + 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) + + //! Effects: Constructs an empty list, making this_node the only + //! node of the circular list: + //! NodeTraits::get_next(this_node) == this_node. + //! + //! Complexity: Constant + //! + //! Throws: Nothing. + 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. + //! the search from prev_init_node. The first node checked for equality + //! is NodeTraits::get_next(prev_init_node). + //! + //! 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(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. + //! + //! Effects: Returns the number of nodes in a linear list. If the linear list + //! is empty, returns 1. + //! + //! Complexity: Linear + //! + //! Throws: Nothing. + static std::size_t count(const_node_ptr this_node) BOOST_NOEXCEPT + { + std::size_t result = 0; + const_node_ptr p = this_node; + do{ + p = NodeTraits::get_next(p); + ++result; + } while (p); + return result; + } + + //! Requires: this_node and other_node must be nodes inserted + //! in linear lists or be empty linear lists. + //! + //! Effects: Moves all the nodes previously chained after this_node after other_node + //! and vice-versa. + //! + //! Complexity: Constant + //! + //! Throws: Nothing. + 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); + NodeTraits::set_next(this_node, other_nxt); + NodeTraits::set_next(other_node, this_nxt); + } + + //! Effects: Reverses the order of elements in the list. + //! + //! Returns: The new first node of the list. + //! + //! Throws: Nothing. + //! + //! Complexity: This function is linear to the contained elements. + static node_ptr reverse(node_ptr p) BOOST_NOEXCEPT + { + if(!p) return node_ptr(); + node_ptr i = NodeTraits::get_next(p); + node_ptr first(p); + while(i){ + node_ptr nxti(NodeTraits::get_next(i)); + base_t::unlink_after(p); + NodeTraits::set_next(i, first); + first = i; + i = nxti; + } + return first; + } + + //! Effects: Moves the first n nodes starting at p to the end of the list. + //! + //! Returns: A pair containing the new first and last node of the list or + //! if there has been any movement, a null pair if n leads to no movement. + //! + //! Throws: Nothing. + //! + //! Complexity: Linear to the number of elements plus the number moved positions. + static node_pair move_first_n_backwards(node_ptr p, std::size_t n) BOOST_NOEXCEPT + { + node_pair ret; + //Null shift, or count() == 0 or 1, nothing to do + if(!n || !p || !NodeTraits::get_next(p)){ + return ret; + } + + node_ptr first = p; + bool end_found = false; + node_ptr new_last = node_ptr(); + node_ptr old_last = node_ptr(); + + //Now find the new last node according to the shift count. + //If we find 0 before finding the new last node + //unlink p, shortcut the search now that we know the size of the list + //and continue. + for(std::size_t i = 1; i <= n; ++i){ + new_last = first; + first = NodeTraits::get_next(first); + if(first == node_ptr()){ + //Shortcut the shift with the modulo of the size of the list + n %= i; + if(!n) return ret; + old_last = new_last; + i = 0; + //Unlink p and continue the new first node search + first = p; + //unlink_after(new_last); + end_found = true; + } + } + + //If the p has not been found in the previous loop, find it + //starting in the new first node and unlink it + if(!end_found){ + old_last = base_t::get_previous_node(first, node_ptr()); + } + + //Now link p after the new last node + NodeTraits::set_next(old_last, p); + NodeTraits::set_next(new_last, node_ptr()); + ret.first = first; + ret.second = new_last; + return ret; + } + + //! Effects: Moves the first n nodes starting at p to the beginning of the list. + //! + //! Returns: A pair containing the new first and last node of the list or + //! if there has been any movement, a null pair if n leads to no movement. + //! + //! Throws: Nothing. + //! + //! Complexity: Linear to the number of elements plus the number moved positions. + static node_pair move_first_n_forward(node_ptr p, std::size_t n) BOOST_NOEXCEPT + { + node_pair ret; + //Null shift, or count() == 0 or 1, nothing to do + if(!n || !p || !NodeTraits::get_next(p)) + return ret; + + node_ptr first = p; + + //Iterate until p is found to know where the current last node is. + //If the shift count is less than the size of the list, we can also obtain + //the position of the new last node after the shift. + node_ptr old_last(first), next_to_it, new_last(p); + std::size_t distance = 1; + while(!!(next_to_it = node_traits::get_next(old_last))){ + if(distance++ > n) + new_last = node_traits::get_next(new_last); + old_last = next_to_it; + } + //If the shift was bigger or equal than the size, obtain the equivalent + //forward shifts and find the new last node. + if(distance <= n){ + //Now find the equivalent forward shifts. + //Shortcut the shift with the modulo of the size of the list + std::size_t new_before_last_pos = (distance - (n % distance))% distance; + //If the shift is a multiple of the size there is nothing to do + if(!new_before_last_pos) + return ret; + + for( new_last = p + ; --new_before_last_pos + ; new_last = node_traits::get_next(new_last)){ + //empty + } + } + + //Get the first new node + node_ptr new_first(node_traits::get_next(new_last)); + //Now put the old beginning after the old end + NodeTraits::set_next(old_last, p); + NodeTraits::set_next(new_last, node_ptr()); + ret.first = new_first; + 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 + +template +struct get_algo +{ + typedef linear_slist_algorithms type; +}; + +/// @endcond + +} //namespace intrusive +} //namespace boost + +#include + +#endif //BOOST_INTRUSIVE_LINEAR_SLIST_ALGORITHMS_HPP diff --git a/third_party/boost/libs/intrusive/include/boost/intrusive/link_mode.hpp b/third_party/boost/libs/intrusive/include/boost/intrusive/link_mode.hpp new file mode 100644 index 00000000000..4ba4daff7d7 --- /dev/null +++ b/third_party/boost/libs/intrusive/include/boost/intrusive/link_mode.hpp @@ -0,0 +1,63 @@ +///////////////////////////////////////////////////////////////////////////// +// +// (C) Copyright Ion Gaztanaga 2006-2013 +// +// 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_LINK_MODE_HPP +#define BOOST_INTRUSIVE_LINK_MODE_HPP + +#if defined(BOOST_HAS_PRAGMA_ONCE) +# pragma once +#endif + +namespace boost { +namespace intrusive { + +//!This enumeration defines the type of value_traits that can be defined +//!for Boost.Intrusive containers +enum link_mode_type{ + //!If this linking policy is specified in a value_traits class + //!as the link_mode, containers + //!configured with such value_traits won't set the hooks + //!of the erased values to a default state. Containers also won't + //!check that the hooks of the new values are default initialized. + normal_link, + + //!If this linking policy is specified in a value_traits class + //!as the link_mode, containers + //!configured with such value_traits will set the hooks + //!of the erased values to a default state. Containers also will + //!check that the hooks of the new values are default initialized. + safe_link, + + //!Same as "safe_link" but the user type is an auto-unlink + //!type, so the containers with constant-time size features won't be + //!compatible with value_traits configured with this policy. + //!Containers also know that the a value can be silently erased from + //!the container without using any function provided by the containers. + auto_unlink +}; + +#ifndef BOOST_INTRUSIVE_DOXYGEN_INVOKED + +template +struct is_safe_autounlink +{ + static const bool value = + (int)link_mode == (int)auto_unlink || + (int)link_mode == (int)safe_link; +}; + +#endif //BOOST_INTRUSIVE_DOXYGEN_INVOKED + +} //namespace intrusive +} //namespace boost + +#endif //BOOST_INTRUSIVE_LINK_MODE_HPP diff --git a/third_party/boost/libs/intrusive/include/boost/intrusive/list.hpp b/third_party/boost/libs/intrusive/include/boost/intrusive/list.hpp new file mode 100644 index 00000000000..62291b4809f --- /dev/null +++ b/third_party/boost/libs/intrusive/include/boost/intrusive/list.hpp @@ -0,0 +1,1519 @@ +///////////////////////////////////////////////////////////////////////////// +// +// (C) Copyright Olaf Krzikalla 2004-2006. +// (C) Copyright Ion Gaztanaga 2006-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_LIST_HPP +#define BOOST_INTRUSIVE_LIST_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 //std::size_t, etc. + +#if defined(BOOST_HAS_PRAGMA_ONCE) +# pragma once +#endif + +namespace boost { +namespace intrusive { + +/// @cond + +struct default_list_hook_applier +{ template struct apply{ typedef typename T::default_list_hook type; }; }; + +template<> +struct is_default_hook_tag +{ static const bool value = true; }; + +struct list_defaults +{ + typedef default_list_hook_applier proto_value_traits; + static const bool constant_time_size = true; + typedef std::size_t size_type; + typedef void header_holder_type; +}; + +/// @endcond + +//! The class template list is an intrusive container that mimics most of the +//! interface of std::list as described in the C++ standard. +//! +//! The template parameter \c T is the type to be managed by the container. +//! The user can specify additional options and if no options are provided +//! default options are used. +//! +//! The container supports the following options: +//! \c base_hook<>/member_hook<>/value_traits<>, +//! \c constant_time_size<> and \c size_type<>. +#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED) +template +#else +template +#endif +class list_impl +{ + //Public typedefs + public: + typedef ValueTraits value_traits; + typedef typename value_traits::pointer pointer; + typedef typename value_traits::const_pointer const_pointer; + typedef typename pointer_traits::element_type value_type; + typedef typename pointer_traits::reference reference; + typedef typename pointer_traits::reference const_reference; + typedef typename pointer_traits::difference_type difference_type; + typedef SizeType size_type; + typedef list_iterator iterator; + typedef list_iterator const_iterator; + typedef boost::intrusive::reverse_iterator reverse_iterator; + typedef boost::intrusive::reverse_iterator const_reverse_iterator; + 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 circular_list_algorithms node_algorithms; + typedef typename detail::get_header_holder_type + < value_traits, HeaderHolder >::type header_holder_type; + + static const bool constant_time_size = ConstantTimeSize; + static const bool stateful_value_traits = detail::is_stateful_value_traits::value; + static const bool has_container_from_iterator = + detail::is_same< header_holder_type, detail::default_header_holder< node_traits > >::value; + + /// @cond + + private: + typedef detail::size_holder size_traits; + + //noncopyable + BOOST_MOVABLE_BUT_NOT_COPYABLE(list_impl) + + static const bool safemode_or_autounlink = is_safe_autounlink::value; + + //Constant-time size is incompatible with auto-unlink hooks! + BOOST_STATIC_ASSERT(!(constant_time_size && + ((int)value_traits::link_mode == (int)auto_unlink) + )); + + BOOST_INTRUSIVE_FORCEINLINE node_ptr get_root_node() + { return data_.root_plus_size_.m_header.get_node(); } + + 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 + { + header_holder_type m_header; + }; + + struct data_t : public value_traits + { + typedef typename list_impl::value_traits value_traits; + BOOST_INTRUSIVE_FORCEINLINE explicit data_t(const value_traits &val_traits) + : value_traits(val_traits) + {} + + root_plus_size root_plus_size_; + } data_; + + BOOST_INTRUSIVE_FORCEINLINE size_traits &priv_size_traits() BOOST_NOEXCEPT + { return data_.root_plus_size_; } + + BOOST_INTRUSIVE_FORCEINLINE const size_traits &priv_size_traits() const BOOST_NOEXCEPT + { return data_.root_plus_size_; } + + BOOST_INTRUSIVE_FORCEINLINE const value_traits &priv_value_traits() const BOOST_NOEXCEPT + { return data_; } + + 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; + + BOOST_INTRUSIVE_FORCEINLINE const_value_traits_ptr priv_value_traits_ptr() const BOOST_NOEXCEPT + { return pointer_traits::pointer_to(this->priv_value_traits()); } + + /// @endcond + + public: + + //! Effects: constructs an empty list. + //! + //! Complexity: Constant + //! + //! Throws: If value_traits::node_traits::node + //! constructor throws (this does not happen with predefined Boost.Intrusive hooks). + list_impl() + : data_(value_traits()) + { + this->priv_size_traits().set_size(size_type(0)); + node_algorithms::init_header(this->get_root_node()); + } + + //! Effects: constructs an empty list. + //! + //! Complexity: Constant + //! + //! Throws: If value_traits::node_traits::node + //! constructor throws (this does not happen with predefined Boost.Intrusive hooks). + explicit list_impl(const value_traits &v_traits) + : data_(v_traits) + { + this->priv_size_traits().set_size(size_type(0)); + node_algorithms::init_header(this->get_root_node()); + } + + //! Requires: Dereferencing iterator must yield an lvalue of type value_type. + //! + //! Effects: Constructs a list equal to the range [first,last). + //! + //! Complexity: Linear in distance(b, e). No copy constructors are called. + //! + //! Throws: If value_traits::node_traits::node + //! constructor throws (this does not happen with predefined Boost.Intrusive hooks). + template + list_impl(Iterator b, Iterator e, const value_traits &v_traits = value_traits()) + : data_(v_traits) + { + //nothrow, no need to rollback to release elements on exception + this->priv_size_traits().set_size(size_type(0)); + node_algorithms::init_header(this->get_root_node()); + //nothrow, no need to rollback to release elements on exception + this->insert(this->cend(), b, e); + } + + //! Effects: Constructs a container moving resources from another container. + //! Internal value traits are move constructed and + //! nodes belonging to x (except the node representing the "end") are linked to *this. + //! + //! Complexity: Constant. + //! + //! Throws: If value_traits::node_traits::node's + //! move constructor throws (this does not happen with predefined Boost.Intrusive hooks) + //! or the move constructor of value traits throws. + list_impl(BOOST_RV_REF(list_impl) x) + : data_(::boost::move(x.priv_value_traits())) + { + this->priv_size_traits().set_size(size_type(0)); + node_algorithms::init_header(this->get_root_node()); + //nothrow, no need to rollback to release elements on exception + this->swap(x); + } + + //! Effects: Equivalent to swap + //! + list_impl& operator=(BOOST_RV_REF(list_impl) x) + { this->swap(x); return *this; } + + //! Effects: If it's not a safe-mode or an auto-unlink value_type + //! the destructor does nothing + //! (ie. no code is generated). Otherwise it detaches all elements from this. + //! In this case the objects in the list are not deleted (i.e. no destructors + //! 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() + { + BOOST_IF_CONSTEXPR(is_safe_autounlink::value){ + this->clear(); + node_algorithms::init(this->get_root_node()); + } + } + + //! Requires: value must be an lvalue. + //! + //! Effects: Inserts the value in the back of the list. + //! No copy constructors are called. + //! + //! Throws: Nothing. + //! + //! Complexity: Constant. + //! + //! Note: Does not affect the validity of iterators and references. + 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)); + node_algorithms::link_before(this->get_root_node(), to_insert); + this->priv_size_traits().increment(); + } + + //! Requires: value must be an lvalue. + //! + //! Effects: Inserts the value in the front of the list. + //! No copy constructors are called. + //! + //! Throws: Nothing. + //! + //! Complexity: Constant. + //! + //! Note: Does not affect the validity of iterators and references. + 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)); + node_algorithms::link_before(node_traits::get_next(this->get_root_node()), to_insert); + this->priv_size_traits().increment(); + } + + //! Effects: Erases the last element of the list. + //! No destructors are called. + //! + //! Throws: Nothing. + //! + //! Complexity: Constant. + //! + //! Note: Invalidates the iterators (but not the references) to the erased element. + void pop_back() BOOST_NOEXCEPT + { return this->pop_back_and_dispose(detail::null_disposer()); } + + //! Requires: Disposer::operator()(pointer) shouldn't throw. + //! + //! Effects: Erases the last element of the list. + //! No destructors are called. + //! Disposer::operator()(pointer) is called for the removed element. + //! + //! Throws: Nothing. + //! + //! Complexity: Constant. + //! + //! Note: Invalidates the iterators to the erased element. + template + 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(); + BOOST_IF_CONSTEXPR(safemode_or_autounlink) + node_algorithms::init(to_erase); + disposer(priv_value_traits().to_value_ptr(to_erase)); + } + + //! Effects: Erases the first element of the list. + //! No destructors are called. + //! + //! Throws: Nothing. + //! + //! Complexity: Constant. + //! + //! Note: Invalidates the iterators (but not the references) to the erased element. + void pop_front() BOOST_NOEXCEPT + { return this->pop_front_and_dispose(detail::null_disposer()); } + + //! Requires: Disposer::operator()(pointer) shouldn't throw. + //! + //! Effects: Erases the first element of the list. + //! No destructors are called. + //! Disposer::operator()(pointer) is called for the removed element. + //! + //! Throws: Nothing. + //! + //! Complexity: Constant. + //! + //! Note: Invalidates the iterators to the erased element. + template + 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(); + BOOST_IF_CONSTEXPR(safemode_or_autounlink) + node_algorithms::init(to_erase); + disposer(priv_value_traits().to_value_ptr(to_erase)); + } + + //! Effects: Returns a reference to the first element of the list. + //! + //! Throws: Nothing. + //! + //! Complexity: Constant. + 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. + //! + //! Throws: Nothing. + //! + //! Complexity: Constant. + 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. + //! + //! Throws: Nothing. + //! + //! Complexity: Constant. + 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. + //! + //! Throws: Nothing. + //! + //! Complexity: Constant. + 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. + //! + //! Throws: Nothing. + //! + //! Complexity: Constant. + 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. + //! + //! Throws: Nothing. + //! + //! Complexity: Constant. + 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. + //! + //! Throws: Nothing. + //! + //! Complexity: Constant. + 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. + //! + //! Throws: Nothing. + //! + //! Complexity: Constant. + 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. + //! + //! Throws: Nothing. + //! + //! Complexity: Constant. + BOOST_INTRUSIVE_FORCEINLINE const_iterator end() const BOOST_NOEXCEPT + { return this->cend(); } + + //! Effects: Returns a constant iterator to the end of the list. + //! + //! Throws: Nothing. + //! + //! Complexity: Constant. + 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 + //! of the reversed list. + //! + //! Throws: Nothing. + //! + //! Complexity: Constant. + BOOST_INTRUSIVE_FORCEINLINE reverse_iterator rbegin() BOOST_NOEXCEPT + { return reverse_iterator(this->end()); } + + //! Effects: Returns a const_reverse_iterator pointing to the beginning + //! of the reversed list. + //! + //! Throws: Nothing. + //! + //! Complexity: Constant. + BOOST_INTRUSIVE_FORCEINLINE const_reverse_iterator rbegin() const BOOST_NOEXCEPT + { return this->crbegin(); } + + //! Effects: Returns a const_reverse_iterator pointing to the beginning + //! of the reversed list. + //! + //! Throws: Nothing. + //! + //! Complexity: Constant. + BOOST_INTRUSIVE_FORCEINLINE const_reverse_iterator crbegin() const BOOST_NOEXCEPT + { return const_reverse_iterator(end()); } + + //! Effects: Returns a reverse_iterator pointing to the end + //! of the reversed list. + //! + //! Throws: Nothing. + //! + //! Complexity: Constant. + BOOST_INTRUSIVE_FORCEINLINE reverse_iterator rend() BOOST_NOEXCEPT + { return reverse_iterator(begin()); } + + //! Effects: Returns a const_reverse_iterator pointing to the end + //! of the reversed list. + //! + //! Throws: Nothing. + //! + //! Complexity: Constant. + BOOST_INTRUSIVE_FORCEINLINE const_reverse_iterator rend() const BOOST_NOEXCEPT + { return this->crend(); } + + //! Effects: Returns a const_reverse_iterator pointing to the end + //! of the reversed list. + //! + //! Throws: Nothing. + //! + //! Complexity: Constant. + 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 + //! of list. + //! + //! Effects: Returns a const reference to the list associated to the end iterator + //! + //! Throws: Nothing. + //! + //! Complexity: Constant. + 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 + //! of list. + //! + //! Effects: Returns a const reference to the list associated to the end iterator + //! + //! Throws: Nothing. + //! + //! Complexity: Constant. + 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. + //! + //! Throws: Nothing. + //! + //! Complexity: Linear to the number of elements contained in the list. + //! if constant-time size option is disabled. Constant time otherwise. + //! + //! Note: Does not affect the validity of iterators and references. + BOOST_INTRUSIVE_FORCEINLINE size_type size() const BOOST_NOEXCEPT + { + BOOST_IF_CONSTEXPR(constant_time_size) + return this->priv_size_traits().get_size(); + else + return node_algorithms::count(this->get_root_node()) - 1; + } + + //! Effects: Returns true if the list contains no elements. + //! + //! Throws: Nothing. + //! + //! Complexity: Constant. + //! + //! Note: Does not affect the validity of iterators and references. + BOOST_INTRUSIVE_FORCEINLINE bool empty() const BOOST_NOEXCEPT + { return node_algorithms::unique(this->get_root_node()); } + + //! Effects: Swaps the elements of x and *this. + //! + //! Throws: Nothing. + //! + //! Complexity: Constant. + //! + //! Note: Does not affect the validity of iterators and references. + 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()); + } + + //! Effects: Moves backwards all the elements, so that the first + //! element becomes the second, the second becomes the third... + //! the last element becomes the first one. + //! + //! Throws: Nothing. + //! + //! Complexity: Linear to the number of shifts. + //! + //! Note: Does not affect the validity of iterators and references. + 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 + //! element becomes the first, the third becomes the second... + //! the first element becomes the last one. + //! + //! Throws: Nothing. + //! + //! Complexity: Linear to the number of shifts. + //! + //! Note: Does not affect the validity of iterators and references. + 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. + //! No destructors are called. + //! + //! Returns: the first element remaining beyond the removed element, + //! or end() if no such element exists. + //! + //! Throws: Nothing. + //! + //! Complexity: Constant. + //! + //! Note: Invalidates the iterators (but not the references) to the + //! erased element. + 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. + //! + //! Effects: Erases the element range pointed by b and e + //! No destructors are called. + //! + //! Returns: the first element remaining beyond the removed elements, + //! or end() if no such element exists. + //! + //! Throws: Nothing. + //! + //! Complexity: Linear to the number of erased elements if it's a safe-mode + //! or auto-unlink value, or constant-time size is enabled. Constant-time otherwise. + //! + //! Note: Invalidates the iterators (but not the references) to the + //! erased elements. + BOOST_INTRUSIVE_FORCEINLINE iterator erase(const_iterator b, const_iterator e) BOOST_NOEXCEPT + { + BOOST_IF_CONSTEXPR(safemode_or_autounlink || constant_time_size){ + return this->erase_and_dispose(b, e, detail::null_disposer()); + } + else{ + node_algorithms::unlink(b.pointed_node(), e.pointed_node()); + return e.unconst(); + } + } + + //! Requires: b and e must be valid iterators to elements in *this. + //! n must be distance(b, e). + //! + //! Effects: Erases the element range pointed by b and e + //! No destructors are called. + //! + //! Returns: the first element remaining beyond the removed elements, + //! or end() if no such element exists. + //! + //! Throws: Nothing. + //! + //! Complexity: Linear to the number of erased elements if it's a safe-mode + //! or auto-unlink value is enabled. Constant-time otherwise. + //! + //! Note: Invalidates the iterators (but not the references) to the + //! erased elements. + 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); + (void)n; + BOOST_IF_CONSTEXPR(safemode_or_autounlink){ + return this->erase_and_dispose(b, e, detail::null_disposer()); + } + else{ + BOOST_IF_CONSTEXPR(constant_time_size){ + this->priv_size_traits().decrease(n); + } + node_algorithms::unlink(b.pointed_node(), e.pointed_node()); + return e.unconst(); + } + } + + //! Requires: Disposer::operator()(pointer) shouldn't throw. + //! + //! Effects: Erases the element pointed by i of the list. + //! No destructors are called. + //! Disposer::operator()(pointer) is called for the removed element. + //! + //! Returns: the first element remaining beyond the removed element, + //! or end() if no such element exists. + //! + //! Throws: Nothing. + //! + //! Complexity: Constant. + //! + //! Note: Invalidates the iterators to the erased element. + template + 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(); + BOOST_IF_CONSTEXPR(safemode_or_autounlink) + node_algorithms::init(to_erase); + disposer(this->priv_value_traits().to_value_ptr(to_erase)); + return i.unconst(); + } + + #if !defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED) + template + iterator erase_and_dispose(iterator i, Disposer disposer) BOOST_NOEXCEPT + { return this->erase_and_dispose(const_iterator(i), disposer); } + #endif + + //! Requires: Disposer::operator()(pointer) shouldn't throw. + //! + //! Effects: Erases the element range pointed by b and e + //! No destructors are called. + //! Disposer::operator()(pointer) is called for the removed elements. + //! + //! Returns: the first element remaining beyond the removed elements, + //! or end() if no such element exists. + //! + //! Throws: Nothing. + //! + //! Complexity: Linear to the number of elements erased. + //! + //! Note: Invalidates the iterators to the erased elements. + template + 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); + 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(); + } + return e.unconst(); + } + + //! Effects: Erases all the elements of the container. + //! No destructors are called. + //! + //! Throws: Nothing. + //! + //! Complexity: Linear to the number of elements of the list. + //! 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() BOOST_NOEXCEPT + { + BOOST_IF_CONSTEXPR(safemode_or_autounlink){ + this->clear_and_dispose(detail::null_disposer()); + } + else{ + node_algorithms::init_header(this->get_root_node()); + this->priv_size_traits().set_size(size_type(0)); + } + } + + //! Requires: Disposer::operator()(pointer) shouldn't throw. + //! + //! Effects: Erases all the elements of the container. + //! No destructors are called. + //! Disposer::operator()(pointer) is called for the removed elements. + //! + //! Throws: Nothing. + //! + //! Complexity: Linear to the number of elements of the list. + //! + //! Note: Invalidates the iterators to the erased elements. + template + 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; + BOOST_IF_CONSTEXPR(safemode_or_autounlink) + node_algorithms::init(to_erase); + disposer(priv_value_traits().to_value_ptr(to_erase)); + } + node_algorithms::init_header(this->get_root_node()); + this->priv_size_traits().set_size(0); + } + + //! Requires: Disposer::operator()(pointer) shouldn't throw. + //! Cloner should yield to nodes equivalent to the original nodes. + //! + //! Effects: Erases all the elements from *this + //! calling Disposer::operator()(pointer), clones all the + //! elements from src calling Cloner::operator()(const_reference ) + //! and inserts them on *this. + //! + //! If cloner throws, all cloned elements are unlinked and disposed + //! calling Disposer::operator()(pointer). + //! + //! Complexity: Linear to erased plus inserted elements. + //! + //! Throws: If cloner throws. Basic guarantee. + template + void clone_from(const list_impl &src, Cloner cloner, Disposer disposer) + { + this->clear_and_dispose(disposer); + detail::exception_disposer + rollback(*this, disposer); + const_iterator b(src.begin()), e(src.end()); + for(; b != e; ++b){ + this->push_back(*cloner(*b)); + } + rollback.release(); + } + + //! Requires: Disposer::operator()(pointer) shouldn't throw. + //! Cloner should yield to nodes equivalent to the original nodes. + //! + //! Effects: Erases all the elements from *this + //! calling Disposer::operator()(pointer), clones all the + //! elements from src calling Cloner::operator()(reference) + //! and inserts them on *this. + //! + //! If cloner throws, all cloned elements are unlinked and disposed + //! calling Disposer::operator()(pointer). + //! + //! Complexity: Linear to erased plus inserted elements. + //! + //! Throws: If cloner throws. Basic guarantee. + template + void clone_from(BOOST_RV_REF(list_impl) src, Cloner cloner, Disposer disposer) + { + this->clear_and_dispose(disposer); + detail::exception_disposer + rollback(*this, disposer); + iterator b(src.begin()), e(src.end()); + for(; b != e; ++b){ + this->push_back(*cloner(*b)); + } + rollback.release(); + } + + //! Requires: value must be an lvalue and p must be a valid iterator of *this. + //! + //! Effects: Inserts the value before the position pointed by p. + //! + //! Returns: An iterator to the inserted element. + //! + //! Throws: Nothing. + //! + //! 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) 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)); + node_algorithms::link_before(p.pointed_node(), to_insert); + this->priv_size_traits().increment(); + return iterator(to_insert, this->priv_value_traits_ptr()); + } + + //! Requires: Dereferencing iterator must yield + //! an lvalue of type value_type and p must be a valid iterator of *this. + //! + //! Effects: Inserts the range pointed by b and e before the position p. + //! No copy constructors are called. + //! + //! Throws: Nothing. + //! + //! Complexity: Linear to the number of elements inserted. + //! + //! Note: Does not affect the validity of iterators and references. + template + void insert(const_iterator p, Iterator b, Iterator e) BOOST_NOEXCEPT + { + for (; b != e; ++b) + this->insert(p, *b); + } + + //! Requires: Dereferencing iterator must yield + //! an lvalue of type value_type. + //! + //! Effects: Clears the list and inserts the range pointed by b and e. + //! No destructors or copy constructors are called. + //! + //! Throws: Nothing. + //! + //! Complexity: Linear to the number of elements inserted plus + //! linear to the elements contained in the list if it's a safe-mode + //! or auto-unlink value. + //! Linear to the number of elements inserted in the list otherwise. + //! + //! Note: Invalidates the iterators (but not the references) + //! to the erased elements. + template + void assign(Iterator b, Iterator e) BOOST_NOEXCEPT + { + this->clear(); + this->insert(this->cend(), b, e); + } + + //! Requires: Disposer::operator()(pointer) shouldn't throw. + //! + //! Requires: Dereferencing iterator must yield + //! an lvalue of type value_type. + //! + //! Effects: Clears the list and inserts the range pointed by b and e. + //! No destructors or copy constructors are called. + //! Disposer::operator()(pointer) is called for the removed elements. + //! + //! Throws: Nothing. + //! + //! Complexity: Linear to the number of elements inserted plus + //! linear to the elements contained in the list. + //! + //! Note: Invalidates the iterators (but not the references) + //! to the erased elements. + template + void dispose_and_assign(Disposer disposer, Iterator b, Iterator e) BOOST_NOEXCEPT + { + this->clear_and_dispose(disposer); + this->insert(this->cend(), b, e); + } + + //! Requires: p must be a valid iterator of *this. + //! + //! Effects: Transfers all the elements of list x to this list, before the + //! the element pointed by p. No destructors or copy constructors are called. + //! + //! Throws: Nothing. + //! + //! Complexity: Constant. + //! + //! 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) BOOST_NOEXCEPT + { + if(!x.empty()){ + node_algorithms::transfer + (p.pointed_node(), x.begin().pointed_node(), x.end().pointed_node()); + size_traits &thist = this->priv_size_traits(); + size_traits &xt = x.priv_size_traits(); + thist.increase(xt.get_size()); + xt.set_size(size_type(0)); + } + } + + //! Requires: p must be a valid iterator of *this. + //! new_ele must point to an element contained in list x. + //! + //! Effects: Transfers the value pointed by new_ele, from list x to this list, + //! before the element pointed by p. No destructors or copy constructors are called. + //! If p == new_ele or p == ++new_ele, this function is a null operation. + //! + //! Throws: Nothing. + //! + //! Complexity: Constant. + //! + //! 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) BOOST_NOEXCEPT + { + node_algorithms::transfer(p.pointed_node(), new_ele.pointed_node()); + x.priv_size_traits().decrement(); + this->priv_size_traits().increment(); + } + + //! Requires: p must be a valid iterator of *this. + //! f and e must point to elements contained in list x. + //! + //! Effects: Transfers the range pointed by f and e from list x to this list, + //! before the element pointed by p. No destructors or copy constructors are called. + //! + //! Throws: Nothing. + //! + //! Complexity: Linear to the number of elements transferred + //! if constant-time size option is enabled. Constant-time otherwise. + //! + //! 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) BOOST_NOEXCEPT + { + 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 + } + + //! Requires: p must be a valid iterator of *this. + //! f and e must point to elements contained in list x. + //! n == distance(f, e) + //! + //! Effects: Transfers the range pointed by f and e from list x to this list, + //! before the element pointed by p. No destructors or copy constructors are called. + //! + //! Throws: Nothing. + //! + //! Complexity: Constant. + //! + //! 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) BOOST_NOEXCEPT + { + if(n){ + 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(); + size_traits &xt = x.priv_size_traits(); + thist.increase(n); + xt.decrease(n); + } + else{ + node_algorithms::transfer(p.pointed_node(), f.pointed_node(), e.pointed_node()); + } + } + } + + //! 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 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(value_less()); } + + //! Requires: p must be a comparison function that induces a strict weak ordering + //! + //! Effects: This function sorts the list *this according to p. 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 the predicate throws. Basic guarantee. + //! + //! Notes: This won't throw if list_base_hook<> or + //! list_member_hook are used. + //! Iterators and references are not invalidated. + //! + //! Complexity: The number of comparisons is approximately N log N, where N + //! is the list's size. + template + void sort(Predicate p) + { + if(node_traits::get_next(this->get_root_node()) + != node_traits::get_previous(this->get_root_node())){ + list_impl carry(this->priv_value_traits()); + detail::array_initializer counter(this->priv_value_traits()); + int fill = 0; + while(!this->empty()){ + carry.splice(carry.cbegin(), *this, this->cbegin()); + int i = 0; + while(i < fill && !counter[i].empty()) { + counter[i].merge(carry, p); + carry.swap(counter[i++]); + } + carry.swap(counter[i]); + if(i == fill) + ++fill; + } + for (int i = 1; i < fill; ++i) + counter[i].merge(counter[i-1], p); + this->swap(counter[fill-1]); + } + } + + //! Effects: This function removes all of x's elements and inserts them + //! 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 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, 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 + //! The lists x and *this must be distinct. + //! + //! Effects: This function removes all of x's elements and inserts them + //! in order into *this. 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 the predicate 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. + template + void merge(list_impl& x, Predicate p) + { + const_iterator e(this->cend()), ex(x.cend()); + const_iterator b(this->cbegin()); + while(!x.empty()){ + const_iterator ix(x.cbegin()); + while (b != e && !p(*ix, *b)){ + ++b; + } + if(b == e){ + //Now transfer the rest to the end of the container + this->splice(e, x); + break; + } + else{ + size_type n(0); + do{ + ++ix; ++n; + } while(ix != ex && p(*ix, *b)); + this->splice(b, x, x.begin(), ix, n); + } + } + } + + //! Effects: Reverses the order of elements in the list. + //! + //! Throws: Nothing. + //! + //! Complexity: This function is linear time. + //! + //! Note: Iterators and references are not invalidated + 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 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) BOOST_NOEXCEPT + { this->remove_if(detail::equal_to_value(value)); } + + //! Requires: Disposer::operator()(pointer) shouldn't throw. + //! + //! Effects: Removes all the elements that compare equal to value. + //! Disposer::operator()(pointer) is called for every removed element. + //! + //! 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) BOOST_NOEXCEPT + { this->remove_and_dispose_if(detail::equal_to_value(value), disposer); } + + //! Effects: Removes all the elements for which a specified + //! predicate is satisfied. No destructors are called. + //! + //! Throws: If pred throws. Basic guarantee. + //! + //! Complexity: Linear time. It performs exactly size() calls to the predicate. + //! + //! 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_if(Pred pred) + { + const node_ptr root_node = this->get_root_node(); + typename node_algorithms::stable_partition_info info; + node_algorithms::stable_partition + (node_traits::get_next(root_node), root_node, detail::key_nodeptr_comp(pred, &this->priv_value_traits()), info); + //Invariants preserved by stable_partition so erase can be safely called + //The first element might have changed so calculate it again + this->erase( const_iterator(node_traits::get_next(root_node), this->priv_value_traits_ptr()) + , const_iterator(info.beg_2st_partition, this->priv_value_traits_ptr()) + , info.num_1st_partition); + } + + //! Requires: Disposer::operator()(pointer) shouldn't throw. + //! + //! Effects: Removes all the elements for which a specified + //! predicate is satisfied. + //! Disposer::operator()(pointer) is called for every removed element. + //! + //! Throws: If pred 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_if(Pred pred, Disposer disposer) + { + const node_ptr root_node = this->get_root_node(); + typename node_algorithms::stable_partition_info info; + node_algorithms::stable_partition + (node_traits::get_next(root_node), root_node, detail::key_nodeptr_comp(pred, &this->priv_value_traits()), info); + //Invariants preserved by stable_partition so erase can be safely called + //The first element might have changed so calculate it again + this->erase_and_dispose( const_iterator(node_traits::get_next(root_node), this->priv_value_traits_ptr()) + , const_iterator(info.beg_2st_partition, this->priv_value_traits_ptr()) + , disposer); + } + + //! Effects: Removes adjacent duplicate elements or adjacent + //! elements that are equal from the list. No destructors are called. + //! + //! Throws: If std::equal_toComplexity: 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()); } + + //! Effects: Removes adjacent duplicate elements or adjacent + //! elements that satisfy some binary predicate from the list. + //! No destructors are called. + //! + //! Throws: If pred throws. Basic guarantee. + //! + //! Complexity: Linear time (size()-1 comparisons equality comparisons). + //! + //! Note: The relative order of elements that are not removed is unchanged, + //! and iterators to elements that are not removed remain valid. + template + void unique(BinaryPredicate pred) + { this->unique_and_dispose(pred, detail::null_disposer()); } + + //! Requires: Disposer::operator()(pointer) shouldn't throw. + //! + //! Effects: Removes adjacent duplicate elements or adjacent + //! elements that are equal from the list. + //! Disposer::operator()(pointer) is called for every removed element. + //! + //! Throws: If std::equal_toComplexity: Linear time (size()-1) comparisons equality comparisons. + //! + //! Note: The relative order of elements that are not removed is unchanged, + //! and iterators to elements that are not removed remain valid. + template + void unique_and_dispose(Disposer disposer) + { this->unique_and_dispose(std::equal_to(), disposer); } + + //! Requires: Disposer::operator()(pointer) shouldn't throw. + //! + //! Effects: Removes adjacent duplicate elements or adjacent + //! elements that satisfy some binary predicate from the list. + //! Disposer::operator()(pointer) is called for every removed element. + //! + //! Throws: If pred throws. Basic guarantee. + //! + //! Complexity: Linear time (size()-1) comparisons equality comparisons. + //! + //! Note: The relative order of elements that are not removed is unchanged, + //! and iterators to elements that are not removed remain valid. + template + void unique_and_dispose(BinaryPredicate pred, Disposer disposer) + { + const_iterator itend(this->cend()); + const_iterator cur(this->cbegin()); + + if(cur != itend){ + const_iterator after(cur); + ++after; + while(after != itend){ + if(pred(*cur, *after)){ + after = this->erase_and_dispose(after, disposer); + } + else{ + cur = after; + ++after; + } + } + } + } + + //! Requires: value must be a reference to a value inserted in a list. + //! + //! Effects: This function returns a const_iterator pointing to the element + //! + //! Throws: Nothing. + //! + //! Complexity: Constant time. + //! + //! 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) BOOST_NOEXCEPT + { + BOOST_STATIC_ASSERT((!stateful_value_traits)); + BOOST_INTRUSIVE_INVARIANT_ASSERT(!node_algorithms::inited(value_traits::to_node_ptr(value))); + return iterator(value_traits::to_node_ptr(value), const_value_traits_ptr()); + } + + //! Requires: value must be a const reference to a value inserted in a list. + //! + //! Effects: This function returns an iterator pointing to the element. + //! + //! Throws: Nothing. + //! + //! Complexity: Constant time. + //! + //! 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) BOOST_NOEXCEPT + { + BOOST_STATIC_ASSERT((!stateful_value_traits)); + reference r =*detail::uncast(pointer_traits::pointer_to(value)); + BOOST_INTRUSIVE_INVARIANT_ASSERT(!node_algorithms::inited(value_traits::to_node_ptr(r))); + return const_iterator(value_traits::to_node_ptr(r), const_value_traits_ptr()); + } + + //! Requires: value must be a reference to a value inserted in a list. + //! + //! Effects: This function returns a const_iterator pointing to the element + //! + //! Throws: Nothing. + //! + //! Complexity: Constant time. + //! + //! Note: Iterators and references are not invalidated. + 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()); + } + + //! Requires: value must be a const reference to a value inserted in a list. + //! + //! Effects: This function returns an iterator pointing to the element. + //! + //! Throws: Nothing. + //! + //! Complexity: Constant time. + //! + //! Note: Iterators and references are not invalidated. + 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))); + return const_iterator(this->priv_value_traits().to_node_ptr(r), this->priv_value_traits_ptr()); + } + + //! Effects: Asserts the integrity of the container. + //! + //! Complexity: Linear time. + //! + //! Note: The method has no effect when asserts are turned off (e.g., with NDEBUG). + //! Experimental function, interface might change in future versions. + void check() const + { + const_node_ptr header_ptr = get_root_node(); + // header's next and prev are never null + BOOST_INTRUSIVE_INVARIANT_ASSERT(node_traits::get_next(header_ptr)); + BOOST_INTRUSIVE_INVARIANT_ASSERT(node_traits::get_previous(header_ptr)); + // header's next and prev either both point to header (empty list) or neither does + BOOST_INTRUSIVE_INVARIANT_ASSERT((node_traits::get_next(header_ptr) == header_ptr) + == (node_traits::get_previous(header_ptr) == header_ptr)); + if (node_traits::get_next(header_ptr) == header_ptr) + { + BOOST_IF_CONSTEXPR(constant_time_size) + BOOST_INTRUSIVE_INVARIANT_ASSERT(this->priv_size_traits().get_size() == 0); + return; + } + 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); + BOOST_INTRUSIVE_INVARIANT_ASSERT(next_p); + BOOST_INTRUSIVE_INVARIANT_ASSERT(node_traits::get_previous(next_p) == p); + p = next_p; + if (p == header_ptr) break; + ++node_count; + } + BOOST_IF_CONSTEXPR(constant_time_size) + BOOST_INTRUSIVE_INVARIANT_ASSERT(this->priv_size_traits().get_size() == node_count); + } + + friend bool operator==(const list_impl &x, const list_impl &y) + { + if(constant_time_size && x.size() != y.size()){ + return false; + } + return ::boost::intrusive::algo_equal(x.cbegin(), x.cend(), y.cbegin(), y.cend()); + } + + BOOST_INTRUSIVE_FORCEINLINE friend bool operator!=(const list_impl &x, const list_impl &y) + { return !(x == 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()); } + + BOOST_INTRUSIVE_FORCEINLINE friend bool operator>(const list_impl &x, const list_impl &y) + { return y < x; } + + BOOST_INTRUSIVE_FORCEINLINE friend bool operator<=(const list_impl &x, const list_impl &y) + { return !(y < x); } + + BOOST_INTRUSIVE_FORCEINLINE friend bool operator>=(const list_impl &x, const list_impl &y) + { return !(x < 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) BOOST_NOEXCEPT + { + BOOST_STATIC_ASSERT((has_container_from_iterator)); + node_ptr p = end_iterator.pointed_node(); + header_holder_type* h = header_holder_type::get_holder(p); + root_plus_size* r = detail::parent_from_member + < root_plus_size, header_holder_type>(h, &root_plus_size::m_header); + data_t *d = detail::parent_from_member + ( r, &data_t::root_plus_size_); + list_impl *s = detail::parent_from_member(d, &list_impl::data_); + return *s; + } + /// @endcond +}; + + +//! Helper metafunction to define a \c list that yields to the same type when the +//! same options (either explicitly or implicitly) are used. +#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED) || defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES) +template +#else +template +#endif +struct make_list +{ + /// @cond + typedef typename pack_options + < list_defaults, + #if !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES) + O1, O2, O3, O4 + #else + Options... + #endif + >::type packed_options; + + typedef typename detail::get_value_traits + ::type value_traits; + typedef list_impl + < + value_traits, + typename packed_options::size_type, + packed_options::constant_time_size, + typename packed_options::header_holder_type + > implementation_defined; + /// @endcond + typedef implementation_defined type; +}; + + +#ifndef BOOST_INTRUSIVE_DOXYGEN_INVOKED + +#if !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES) +template +#else +template +#endif +class list + : public make_list::type +{ + typedef typename make_list + ::type Base; + //Assert if passed value traits are compatible with the type + BOOST_STATIC_ASSERT((detail::is_same::value)); + BOOST_MOVABLE_BUT_NOT_COPYABLE(list) + + public: + typedef typename Base::value_traits value_traits; + typedef typename Base::iterator iterator; + typedef typename Base::const_iterator const_iterator; + + BOOST_INTRUSIVE_FORCEINLINE list() + : Base() + {} + + BOOST_INTRUSIVE_FORCEINLINE explicit list(const value_traits &v_traits) + : Base(v_traits) + {} + + template + BOOST_INTRUSIVE_FORCEINLINE list(Iterator b, Iterator e, const value_traits &v_traits = value_traits()) + : Base(b, e, v_traits) + {} + + BOOST_INTRUSIVE_FORCEINLINE list(BOOST_RV_REF(list) x) + : Base(BOOST_MOVE_BASE(Base, x)) + {} + + BOOST_INTRUSIVE_FORCEINLINE list& operator=(BOOST_RV_REF(list) x) + { return static_cast(this->Base::operator=(BOOST_MOVE_BASE(Base, x))); } + + template + BOOST_INTRUSIVE_FORCEINLINE void clone_from(const list &src, Cloner cloner, Disposer disposer) + { Base::clone_from(src, cloner, disposer); } + + template + 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_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_NOEXCEPT + { return static_cast(Base::container_from_end_iterator(end_iterator)); } +}; + +#endif + +} //namespace intrusive +} //namespace boost + +#include + +#endif //BOOST_INTRUSIVE_LIST_HPP diff --git a/third_party/boost/libs/intrusive/include/boost/intrusive/list_hook.hpp b/third_party/boost/libs/intrusive/include/boost/intrusive/list_hook.hpp new file mode 100644 index 00000000000..03cf9a563a9 --- /dev/null +++ b/third_party/boost/libs/intrusive/include/boost/intrusive/list_hook.hpp @@ -0,0 +1,289 @@ +///////////////////////////////////////////////////////////////////////////// +// +// (C) Copyright Olaf Krzikalla 2004-2006. +// (C) Copyright Ion Gaztanaga 2006-2013 +// +// 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_LIST_HOOK_HPP +#define BOOST_INTRUSIVE_LIST_HOOK_HPP + +#include +#include + +#include +#include +#include +#include + +#if defined(BOOST_HAS_PRAGMA_ONCE) +# pragma once +#endif + + +namespace boost { +namespace intrusive { + +//! Helper metafunction to define a \c \c list_base_hook that yields to the same +//! type when the same options (either explicitly or implicitly) are used. +#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED) || defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES) +template +#else +template +#endif +struct make_list_base_hook +{ + /// @cond + typedef typename pack_options + < hook_defaults, + #if !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES) + O1, O2, O3 + #else + Options... + #endif + >::type packed_options; + + typedef generic_hook + < CircularListAlgorithms + , list_node_traits + , typename packed_options::tag + , packed_options::link_mode + , ListBaseHookId + > implementation_defined; + /// @endcond + typedef implementation_defined type; +}; + +//! Derive a class from this hook in order to store objects of that class +//! in an list. +//! +//! The hook admits the following options: \c tag<>, \c void_pointer<> and +//! \c link_mode<>. +//! +//! \c tag<> defines a tag to identify the node. +//! The same tag value can be used in different classes, but if a class is +//! derived from more than one \c list_base_hook, then each \c list_base_hook needs its +//! unique tag. +//! +//! \c link_mode<> will specify the linking mode of the hook (\c normal_link, +//! \c auto_unlink or \c safe_link). +//! +//! \c void_pointer<> is the pointer type that will be used internally in the hook +//! and the container configured to use this hook. +#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED) || defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES) +template +#else +template +#endif +class list_base_hook + : public make_list_base_hook + #if !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES) + + #else + + #endif + ::type +{ + #if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED) + public: + //! Effects: If link_mode is \c auto_unlink or \c safe_link + //! initializes the node to an unlinked state. + //! + //! Throws: Nothing. + 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. + //! + //! Throws: Nothing. + //! + //! Rationale: Providing a copy-constructor + //! 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& ) BOOST_NOEXCEPT; + + //! Effects: Empty function. The argument is ignored. + //! + //! Throws: Nothing. + //! + //! Rationale: Providing an assignment operator + //! 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& ) 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 + //! object is stored in an list an assertion is raised. If link_mode is + //! \c auto_unlink and \c is_linked() is true, the node is unlinked. + //! + //! Throws: Nothing. + ~list_base_hook(); + + //! Effects: Swapping two nodes swaps the position of the elements + //! related to those nodes in one or two containers. That is, if the node + //! this is part of the element e1, the node x is part of the element e2 + //! and both elements are included in the containers s1 and s2, then after + //! the swap-operation e1 is in s2 at the position of e2 and e2 is in s1 + //! at the position of e1. If one element is not in a container, then + //! after the swap-operation the other element is not in a container. + //! Iterators to e1 and e2 related to those nodes are invalidated. + //! + //! Complexity: Constant + //! + //! Throws: Nothing. + void swap_nodes(list_base_hook &other) BOOST_NOEXCEPT; + + //! Precondition: link_mode must be \c safe_link or \c auto_unlink. + //! + //! Returns: true, if the node belongs to a container, false + //! otherwise. This function can be used to test whether \c list::iterator_to + //! will return a valid iterator. + //! + //! Complexity: Constant + bool is_linked() const; + + //! 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() BOOST_NOEXCEPT; + #endif +}; + +//! Helper metafunction to define a \c \c list_member_hook that yields to the same +//! type when the same options (either explicitly or implicitly) are used. +#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED) || defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES) +template +#else +template +#endif +struct make_list_member_hook +{ + /// @cond + typedef typename pack_options + < hook_defaults, + #if !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES) + O1, O2, O3 + #else + Options... + #endif + >::type packed_options; + + typedef generic_hook + < CircularListAlgorithms + , list_node_traits + , member_tag + , packed_options::link_mode + , NoBaseHookId + > implementation_defined; + /// @endcond + typedef implementation_defined type; +}; + +//! Store this hook in a class to be inserted +//! in an list. +//! +//! The hook admits the following options: \c void_pointer<> and +//! \c link_mode<>. +//! +//! \c link_mode<> will specify the linking mode of the hook (\c normal_link, +//! \c auto_unlink or \c safe_link). +//! +//! \c void_pointer<> is the pointer type that will be used internally in the hook +//! and the container configured to use this hook. +#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED) || defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES) +template +#else +template +#endif +class list_member_hook + : public make_list_member_hook + #if !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES) + + #else + + #endif + ::type +{ + #if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED) + public: + //! Effects: If link_mode is \c auto_unlink or \c safe_link + //! initializes the node to an unlinked state. + //! + //! Throws: Nothing. + 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. + //! + //! Throws: Nothing. + //! + //! Rationale: Providing a copy-constructor + //! 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& ) BOOST_NOEXCEPT; + + //! Effects: Empty function. The argument is ignored. + //! + //! Throws: Nothing. + //! + //! Rationale: Providing an assignment operator + //! 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& ) 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 + //! object is stored in an list an assertion is raised. If link_mode is + //! \c auto_unlink and \c is_linked() is true, the node is unlinked. + //! + //! Throws: Nothing. + ~list_member_hook(); + + //! Effects: Swapping two nodes swaps the position of the elements + //! related to those nodes in one or two containers. That is, if the node + //! this is part of the element e1, the node x is part of the element e2 + //! and both elements are included in the containers s1 and s2, then after + //! the swap-operation e1 is in s2 at the position of e2 and e2 is in s1 + //! at the position of e1. If one element is not in a container, then + //! after the swap-operation the other element is not in a container. + //! Iterators to e1 and e2 related to those nodes are invalidated. + //! + //! Complexity: Constant + //! + //! Throws: Nothing. + void swap_nodes(list_member_hook &other) BOOST_NOEXCEPT; + + //! Precondition: link_mode must be \c safe_link or \c auto_unlink. + //! + //! Returns: true, if the node belongs to a container, false + //! otherwise. This function can be used to test whether \c list::iterator_to + //! will return a valid iterator. + //! + //! Complexity: Constant + bool is_linked() const; + + //! 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() BOOST_NOEXCEPT; + #endif +}; + +} //namespace intrusive +} //namespace boost + +#include + +#endif //BOOST_INTRUSIVE_LIST_HOOK_HPP diff --git a/third_party/boost/libs/intrusive/include/boost/intrusive/member_value_traits.hpp b/third_party/boost/libs/intrusive/include/boost/intrusive/member_value_traits.hpp new file mode 100644 index 00000000000..f673b6417aa --- /dev/null +++ b/third_party/boost/libs/intrusive/include/boost/intrusive/member_value_traits.hpp @@ -0,0 +1,85 @@ +///////////////////////////////////////////////////////////////////////////// +// +// (C) Copyright Ion Gaztanaga 2006-2013 +// +// 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_MEMBER_VALUE_TRAITS_HPP +#define BOOST_INTRUSIVE_MEMBER_VALUE_TRAITS_HPP + +#include +#include + +#include +#include +#include +#include + +#if defined(BOOST_HAS_PRAGMA_ONCE) +# pragma once +#endif + +namespace boost { +namespace intrusive { + +//!This value traits template is used to create value traits +//!from user defined node traits where value_traits::value_type will +//!store a node_traits::node +template< class T, class NodeTraits + , typename NodeTraits::node T::* PtrToMember + , link_mode_type LinkMode + #ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED + = safe_link + #endif +> +struct member_value_traits +{ + public: + typedef NodeTraits node_traits; + typedef T value_type; + 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 pointer_traits node_ptr_traits; + typedef typename pointer_traits::template + rebind_pointer::type pointer; + typedef typename pointer_traits::template + rebind_pointer::type const_pointer; + //typedef typename pointer_traits::reference reference; + //typedef typename pointer_traits::reference const_reference; + typedef value_type & reference; + 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_NOEXCEPT + { return pointer_traits::pointer_to(value.*PtrToMember); } + + 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(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_node_ptr n) BOOST_NOEXCEPT + { + return pointer_traits::pointer_to(*detail::parent_from_member + (boost::movelib::to_raw_pointer(n), PtrToMember)); + + } +}; + +} //namespace intrusive +} //namespace boost + +#include + +#endif //BOOST_INTRUSIVE_MEMBER_VALUE_TRAITS_HPP diff --git a/third_party/boost/libs/intrusive/include/boost/intrusive/options.hpp b/third_party/boost/libs/intrusive/include/boost/intrusive/options.hpp new file mode 100644 index 00000000000..ff6902e8f87 --- /dev/null +++ b/third_party/boost/libs/intrusive/include/boost/intrusive/options.hpp @@ -0,0 +1,278 @@ +///////////////////////////////////////////////////////////////////////////// +// +// (C) Copyright Ion Gaztanaga 2007-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_OPTIONS_HPP +#define BOOST_INTRUSIVE_OPTIONS_HPP + +#include +#include +#include +#include + +#if defined(BOOST_HAS_PRAGMA_ONCE) +# pragma once +#endif + +namespace boost { +namespace intrusive { + +#ifndef BOOST_INTRUSIVE_DOXYGEN_INVOKED + +struct empty +{}; + +template +struct fhtraits; + +template +struct mhtraits; + +struct dft_tag; +struct member_tag; + +template +struct is_default_hook_tag; + +#endif //#ifndef BOOST_INTRUSIVE_DOXYGEN_INVOKED + +//!This option setter specifies if the intrusive +//!container stores its size as a member to +//!obtain constant-time size() member. +BOOST_INTRUSIVE_OPTION_CONSTANT(constant_time_size, bool, Enabled, constant_time_size) + +//!This option setter specifies a container header holder type +BOOST_INTRUSIVE_OPTION_TYPE(header_holder_type, HeaderHolder, HeaderHolder, header_holder_type) + +//!This option setter specifies the type that +//!the container will use to store its size. +BOOST_INTRUSIVE_OPTION_TYPE(size_type, SizeType, SizeType, size_type) + +//!This option setter specifies the strict weak ordering +//!comparison functor for the value type +BOOST_INTRUSIVE_OPTION_TYPE(compare, Compare, Compare, compare) + +//!This option setter specifies a function object +//!that specifies the type of the key of an associative +//!container and an operator to obtain it from a value type. +//! +//!This function object must the define a `type` member typedef and +//!a member with signature `type [const&] operator()(const value_type &) const` +//!that will return the key from a value_type of an associative container +BOOST_INTRUSIVE_OPTION_TYPE(key_of_value, KeyOfValue, KeyOfValue, key_of_value) + +//!This option setter specifies a function object +//!that specifies the type of the priority of a treap +//!container and an operator to obtain it from a value type. +//! +//!This function object must the define a `type` member typedef and +//!a member with signature `type [const&] operator()(const value_type &) const` +//!that will return the priority from a value_type of a treap container +BOOST_INTRUSIVE_OPTION_TYPE(priority_of_value, PrioOfValue, PrioOfValue, priority_of_value) + +//!This option setter for scapegoat containers specifies if +//!the intrusive scapegoat container should use a non-variable +//!alpha value that does not need floating-point operations. +//! +//!If activated, the fixed alpha value is 1/sqrt(2). This +//!option also saves some space in the container since +//!the alpha value and some additional data does not need +//!to be stored in the container. +//! +//!If the user only needs an alpha value near 1/sqrt(2), this +//!option also improves performance since avoids logarithm +//!and division operations when rebalancing the tree. +BOOST_INTRUSIVE_OPTION_CONSTANT(floating_point, bool, Enabled, floating_point) + +//!This option setter specifies the equality +//!functor for the value type +BOOST_INTRUSIVE_OPTION_TYPE(equal, Equal, Equal, equal) + +//!This option setter specifies the priority comparison +//!functor for the value type +BOOST_INTRUSIVE_OPTION_TYPE(priority, Priority, Priority, priority) + +//!This option setter specifies the hash +//!functor for the value type +BOOST_INTRUSIVE_OPTION_TYPE(hash, Hash, Hash, hash) + +//!This option setter specifies the relationship between the type +//!to be managed by the container (the value type) and the node to be +//!used in the node algorithms. It also specifies the linking policy. +BOOST_INTRUSIVE_OPTION_TYPE(value_traits, ValueTraits, ValueTraits, proto_value_traits) + +//#define BOOST_INTRUSIVE_COMMA , +//#define BOOST_INTRUSIVE_LESS < +//#define BOOST_INTRUSIVE_MORE > +//BOOST_INTRUSIVE_OPTION_TYPE (member_hook, Parent BOOST_INTRUSIVE_COMMA class MemberHook BOOST_INTRUSIVE_COMMA MemberHook Parent::* PtrToMember , mhtraits BOOST_INTRUSIVE_LESS Parent BOOST_INTRUSIVE_COMMA MemberHook BOOST_INTRUSIVE_COMMA PtrToMember BOOST_INTRUSIVE_MORE , proto_value_traits) +//template< class Parent , class MemberHook , MemberHook Parent::* PtrToMember> +//struct member_hook { +// template struct pack : Base { +// typedef mhtraits < Parent , MemberHook , PtrToMember > proto_value_traits; +// }; +//}; +// +//#undef BOOST_INTRUSIVE_COMMA +//#undef BOOST_INTRUSIVE_LESS +//#undef BOOST_INTRUSIVE_MORE + +//!This option setter specifies the member hook the +//!container must use. +template< typename Parent + , typename MemberHook + , MemberHook Parent::* PtrToMember> +struct member_hook +{ +// @cond +// typedef typename MemberHook::hooktags::node_traits node_traits; +// typedef typename node_traits::node node_type; +// typedef node_type Parent::* Ptr2MemNode; +// typedef mhtraits +// < Parent +// , node_traits +// //This cast is really ugly but necessary to reduce template bloat. +// //Since we control the layout between the hook and the node, and there is +// //always single inheritance, the offset of the node is exactly the offset of +// //the hook. Since the node type is shared between all member hooks, this saves +// //quite a lot of symbol stuff. +// , (Ptr2MemNode)PtrToMember +// , MemberHook::hooktags::link_mode> member_value_traits; + typedef mhtraits member_value_traits; + template + struct pack : Base + { + typedef member_value_traits proto_value_traits; + }; +/// @endcond +}; + +//!This option setter specifies the function object that will +//!be used to convert between values to be inserted in a container +//!and the hook to be used for that purpose. +BOOST_INTRUSIVE_OPTION_TYPE(function_hook, Functor, fhtraits, proto_value_traits) + +//!This option setter specifies that the container +//!must use the specified base hook +BOOST_INTRUSIVE_OPTION_TYPE(base_hook, BaseHook, BaseHook, proto_value_traits) + +//!This option setter specifies the type of +//!a void pointer. This will instruct the hook +//!to use this type of pointer instead of the +//!default one +BOOST_INTRUSIVE_OPTION_TYPE(void_pointer, VoidPointer, VoidPointer, void_pointer) + +//!This option setter specifies the type of +//!the tag of a base hook. A type cannot have two +//!base hooks of the same type, so a tag can be used +//!to differentiate two base hooks with otherwise same type +BOOST_INTRUSIVE_OPTION_TYPE(tag, Tag, Tag, tag) + +//!This option setter specifies the link mode +//!(normal_link, safe_link or auto_unlink) +BOOST_INTRUSIVE_OPTION_CONSTANT(link_mode, link_mode_type, LinkType, link_mode) + +//!This option setter specifies if the hook +//!should be optimized for size instead of for speed. +BOOST_INTRUSIVE_OPTION_CONSTANT(optimize_size, bool, Enabled, optimize_size) + +//!This option setter specifies if the slist container should +//!use a linear implementation instead of a circular one. +BOOST_INTRUSIVE_OPTION_CONSTANT(linear, bool, Enabled, linear) + +//!If true, slist also stores a pointer to the last element of the singly linked list. +//!This allows O(1) swap and splice_after(iterator, slist &) for circular slists and makes +//!possible new functions like push_back(reference) and back(). +BOOST_INTRUSIVE_OPTION_CONSTANT(cache_last, bool, Enabled, cache_last) + +//!This option setter specifies the bucket traits +//!class for unordered associative containers. When this option is specified, +//!instead of using the default bucket traits, a user defined holder will be defined +BOOST_INTRUSIVE_OPTION_TYPE(bucket_traits, BucketTraits, BucketTraits, bucket_traits) + +//!This option setter specifies if the unordered hook +//!should offer room to store the hash value. +//!Storing the hash in the hook will speed up rehashing +//!processes in applications where rehashing is frequent, +//!rehashing might throw or the value is heavy to hash. +BOOST_INTRUSIVE_OPTION_CONSTANT(store_hash, bool, Enabled, store_hash) + +//!This option setter specifies if the unordered hook +//!should offer room to store another link to another node +//!with the same key. +//!Storing this link will speed up lookups and insertions on +//!unordered_multiset containers with a great number of elements +//!with the same key. +BOOST_INTRUSIVE_OPTION_CONSTANT(optimize_multikey, bool, Enabled, optimize_multikey) + +//!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, 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 +//!but with big bucket arrays (that is, hashtables with low load factors). +BOOST_INTRUSIVE_OPTION_CONSTANT(cache_begin, bool, Enabled, cache_begin) + +//!This option setter specifies if the container will compare the hash value +//!before comparing objects. This option can't be specified if store_hash<> +//!is not true. +//!This is specially helpful when we have containers with a high load factor. +//!and the comparison function is much more expensive that comparing already +//!stored hash values. +BOOST_INTRUSIVE_OPTION_CONSTANT(compare_hash, bool, Enabled, compare_hash) + +//!This option setter specifies if the hash container will use incremental +//!hashing. With incremental hashing the cost of hash table expansion is spread +//!out across each hash table insertion operation, as opposed to be incurred all at once. +//!Therefore linear hashing is well suited for interactive applications or real-time +//!appplications where the worst-case insertion time of non-incremental hash containers +//!(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 +{ + typedef void* void_pointer; + static const link_mode_type link_mode = safe_link; + typedef dft_tag tag; + static const bool optimize_size = false; + static const bool store_hash = false; + static const bool linear = false; + static const bool optimize_multikey = false; +}; + +/// @endcond + +} //namespace intrusive { +} //namespace boost { + +#include + +#endif //#ifndef BOOST_INTRUSIVE_OPTIONS_HPP diff --git a/third_party/boost/libs/intrusive/include/boost/intrusive/pack_options.hpp b/third_party/boost/libs/intrusive/include/boost/intrusive/pack_options.hpp new file mode 100644 index 00000000000..66761d7625e --- /dev/null +++ b/third_party/boost/libs/intrusive/include/boost/intrusive/pack_options.hpp @@ -0,0 +1,384 @@ +///////////////////////////////////////////////////////////////////////////// +// +// (C) Copyright Ion Gaztanaga 2013-2013 +// +// 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_PACK_OPTIONS_HPP +#define BOOST_INTRUSIVE_PACK_OPTIONS_HPP + +#include + +#if defined(BOOST_HAS_PRAGMA_ONCE) +# pragma once +#endif + +#include + +namespace boost { +namespace intrusive { + +#ifndef BOOST_INTRUSIVE_DOXYGEN_INVOKED + +#if !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES) + +template +struct do_pack +{ + //Use "pack" member template to pack options + typedef typename Next::template pack type; +}; + +template +struct do_pack +{ + //Avoid packing "void" to shorten template names + typedef Prev type; +}; + +template + < class DefaultOptions + , class O1 = void + , class O2 = void + , class O3 = void + , class O4 = void + , class O5 = void + , class O6 = void + , class O7 = void + , class O8 = void + , class O9 = void + , class O10 = void + , class O11 = void + > +struct pack_options +{ + // join options + typedef + typename do_pack + < typename do_pack + < typename do_pack + < typename do_pack + < typename do_pack + < typename do_pack + < typename do_pack + < typename do_pack + < typename do_pack + < typename do_pack + < typename do_pack + < DefaultOptions + , O1 + >::type + , O2 + >::type + , O3 + >::type + , O4 + >::type + , O5 + >::type + , O6 + >::type + , O7 + >::type + , O8 + >::type + , O9 + >::type + , O10 + >::type + , O11 + >::type + type; +}; +#else + +//index_tuple +template +struct index_tuple{}; + +//build_number_seq +template > +struct build_number_seq; + +template +struct build_number_seq > + : build_number_seq > +{}; + +template +struct build_number_seq<0, index_tuple > +{ typedef index_tuple type; }; + +template +struct typelist +{}; + +//invert_typelist +template +struct invert_typelist; + +template +struct typelist_element; + +template +struct typelist_element > +{ + typedef typename typelist_element >::type type; +}; + +template +struct typelist_element<0, typelist > +{ + typedef Head type; +}; + +template +typelist >::type...> + inverted_typelist(index_tuple, typelist) +{ + return typelist >::type...>(); +} + +//sizeof_typelist +template +struct sizeof_typelist; + +template +struct sizeof_typelist< typelist > +{ + static const std::size_t value = sizeof...(Types); +}; + +//invert_typelist_impl +template +struct invert_typelist_impl; + + +template +struct invert_typelist_impl< Typelist, index_tuple > +{ + static const std::size_t last_idx = sizeof_typelist::value - 1; + typedef typelist + ::type...> type; +}; + +template +struct invert_typelist_impl< Typelist, index_tuple > +{ + typedef Typelist type; +}; + +template +struct invert_typelist_impl< Typelist, index_tuple<> > +{ + typedef Typelist type; +}; + +//invert_typelist +template +struct invert_typelist; + +template +struct invert_typelist< typelist > +{ + typedef typelist typelist_t; + typedef typename build_number_seq::type indexes_t; + typedef typename invert_typelist_impl::type type; +}; + +//Do pack +template +struct do_pack; + +template<> +struct do_pack >; + +template +struct do_pack > +{ + typedef Prev type; +}; + +template +struct do_pack > +{ + typedef typename Prev::template pack type; +}; + +template +struct do_pack > +{ + typedef typename do_pack >::type type; +}; + +template +struct do_pack > +{ + typedef typename Prev::template pack + >::type> type; +}; + + +template +struct pack_options +{ + typedef typelist typelist_t; + typedef typename invert_typelist::type inverted_typelist; + typedef typename do_pack::type type; +}; + +#endif //!defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES) + +#define BOOST_INTRUSIVE_OPTION_TYPE(OPTION_NAME, TYPE, TYPEDEF_EXPR, TYPEDEF_NAME) \ +template< class TYPE> \ +struct OPTION_NAME \ +{ \ + template \ + struct pack : Base \ + { \ + typedef TYPEDEF_EXPR TYPEDEF_NAME; \ + }; \ +}; \ +// + +#define BOOST_INTRUSIVE_OPTION_CONSTANT(OPTION_NAME, TYPE, VALUE, CONSTANT_NAME) \ +template< TYPE VALUE> \ +struct OPTION_NAME \ +{ \ + static const TYPE value = VALUE; \ + \ + template \ + struct pack : Base \ + { \ + static const TYPE CONSTANT_NAME = VALUE; \ + }; \ +}; \ +// + +#else //#ifndef BOOST_INTRUSIVE_DOXYGEN_INVOKED + +//! This class is a utility that takes: +//! - a default options class defining initial static constant +//! and typedefs +//! - several options defined with BOOST_INTRUSIVE_OPTION_CONSTANT and +//! BOOST_INTRUSIVE_OPTION_TYPE +//! +//! and packs them together in a new type that defines all options as +//! member typedefs or static constant values. Given options of form: +//! +//! \code +//! BOOST_INTRUSIVE_OPTION_TYPE(my_pointer, VoidPointer, VoidPointer, my_pointer_type) +//! BOOST_INTRUSIVE_OPTION_CONSTANT(incremental, bool, Enabled, is_incremental) +//! \endcode +//! +//! the following expression +//! +//! \code +//! +//! struct default_options +//! { +//! typedef long int_type; +//! static const int int_constant = -1; +//! }; +//! +//! pack_options< default_options, my_pointer, incremental >::type +//! \endcode +//! +//! will create a type that will contain the following typedefs/constants +//! +//! \code +//! struct unspecified_type +//! { +//! //Default options +//! typedef long int_type; +//! static const int int_constant = -1; +//! +//! //Packed options (will ovewrite any default option) +//! typedef void* my_pointer_type; +//! static const bool is_incremental = true; +//! }; +//! \endcode +//! +//! If an option is specified in the default options argument and later +//! redefined as an option, the last definition will prevail. +template +struct pack_options +{ + typedef unspecified_type type; +}; + +//! Defines an option class of name OPTION_NAME that can be used to specify a type +//! of type TYPE... +//! +//! \code +//! struct OPTION_NAME +//! { unspecified_content }; +//! \endcode +//! +//! ...that after being combined with +//! boost::intrusive::pack_options, +//! will typedef TYPE as a typedef of name TYPEDEF_NAME. Example: +//! +//! \code +//! //[includes and namespaces omitted for brevity] +//! +//! //This macro will create the following class: +//! // template +//! // struct my_pointer +//! // { unspecified_content }; +//! BOOST_INTRUSIVE_OPTION_TYPE(my_pointer, VoidPointer, boost::remove_pointer::type, my_pointer_type) +//! +//! struct empty_default{}; +//! +//! typedef pack_options< empty_default, typename my_pointer >::type::my_pointer_type type; +//! +//! BOOST_STATIC_ASSERT(( boost::is_same::value )); +//! +//! \endcode +#define BOOST_INTRUSIVE_OPTION_TYPE(OPTION_NAME, TYPE, TYPEDEF_EXPR, TYPEDEF_NAME) + +//! Defines an option class of name OPTION_NAME that can be used to specify a constant +//! of type TYPE with value VALUE... +//! +//! \code +//! struct OPTION_NAME +//! { unspecified_content }; +//! \endcode +//! +//! ...that after being combined with +//! boost::intrusive::pack_options, +//! will contain a CONSTANT_NAME static constant of value VALUE. Example: +//! +//! \code +//! //[includes and namespaces omitted for brevity] +//! +//! //This macro will create the following class: +//! // template +//! // struct incremental +//! // { unspecified_content }; +//! BOOST_INTRUSIVE_OPTION_CONSTANT(incremental, bool, Enabled, is_incremental) +//! +//! struct empty_default{}; +//! +//! const bool is_incremental = pack_options< empty_default, incremental >::type::is_incremental; +//! +//! BOOST_STATIC_ASSERT(( is_incremental == true )); +//! +//! \endcode +#define BOOST_INTRUSIVE_OPTION_CONSTANT(OPTION_NAME, TYPE, VALUE, CONSTANT_NAME) + +#endif //#ifndef BOOST_INTRUSIVE_DOXYGEN_INVOKED + + +} //namespace intrusive { +} //namespace boost { + +#include + +#endif //#ifndef BOOST_INTRUSIVE_PACK_OPTIONS_HPP diff --git a/third_party/boost/libs/intrusive/include/boost/intrusive/parent_from_member.hpp b/third_party/boost/libs/intrusive/include/boost/intrusive/parent_from_member.hpp new file mode 100644 index 00000000000..9c8f167dad7 --- /dev/null +++ b/third_party/boost/libs/intrusive/include/boost/intrusive/parent_from_member.hpp @@ -0,0 +1,49 @@ +///////////////////////////////////////////////////////////////////////////// +// +// (C) Copyright Ion Gaztanaga 2010-2013 +// +// 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_PARENT_FROM_MEMBER_HPP +#define BOOST_INTRUSIVE_PARENT_FROM_MEMBER_HPP + +#include +#include +#include + +#include + +#if defined(BOOST_HAS_PRAGMA_ONCE) +# pragma once +#endif + +namespace boost { +namespace intrusive { + +//! Given a pointer to a member and its corresponding pointer to data member, +//! this function returns the pointer of the parent containing that member. +//! 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_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, +//! this function returns the const pointer of the parent containing that member. +//! 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_NOEXCEPT +{ return ::boost::intrusive::detail::parent_from_member(member, ptr_to_member); } + +} //namespace intrusive { +} //namespace boost { + +#include + +#endif //#ifndef BOOST_INTRUSIVE_PARENT_FROM_MEMBER_HPP diff --git a/third_party/boost/libs/intrusive/include/boost/intrusive/pointer_plus_bits.hpp b/third_party/boost/libs/intrusive/include/boost/intrusive/pointer_plus_bits.hpp new file mode 100644 index 00000000000..b967bb636d7 --- /dev/null +++ b/third_party/boost/libs/intrusive/include/boost/intrusive/pointer_plus_bits.hpp @@ -0,0 +1,112 @@ +///////////////////////////////////////////////////////////////////////////// +// +// (C) Copyright Ion Gaztanaga 2007-2013 +// +// 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_POINTER_PLUS_BITS_HPP +#define BOOST_INTRUSIVE_POINTER_PLUS_BITS_HPP + +#include +#include +#include //ls_zeros +#include //BOOST_INTRUSIVE_INVARIANT_ASSERT + +#if defined(BOOST_HAS_PRAGMA_ONCE) +# pragma once +#endif + + +//GCC reports uninitialized values when an uninitialized pointer plus bits type +//is asigned some bits or some pointer value, but that's ok, because we don't want +//to default initialize parts that are not being updated. +#if defined(BOOST_GCC) +# if (BOOST_GCC >= 40600) +# pragma GCC diagnostic push +# pragma GCC diagnostic ignored "-Wuninitialized" +# if (BOOST_GCC >= 40700) +# pragma GCC diagnostic ignored "-Wmaybe-uninitialized" +# endif +# endif +#endif + +namespace boost { +namespace intrusive { + +//!This trait class is used to know if a pointer +//!can embed extra bits of information if +//!it's going to be used to point to objects +//!with an alignment of "Alignment" bytes. +template +struct max_pointer_plus_bits +{ + static const std::size_t value = 0; +}; + +//!This is a specialization for raw pointers. +//!Raw pointers can embed extra bits in the lower bits +//!if the alignment is multiple of 2pow(NumBits). +template +struct max_pointer_plus_bits +{ + static const std::size_t value = detail::ls_zeros::value; +}; + +//!This is class that is supposed to have static methods +//!to embed extra bits of information in a pointer. +//!This is a declaration and there is no default implementation, +//!because operations to embed the bits change with every pointer type. +//! +//!An implementation that detects that a pointer type whose +//!has_pointer_plus_bits<>::value is non-zero can make use of these +//!operations to embed the bits in the pointer. +template +struct pointer_plus_bits + #ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED + {} + #endif +; + +//!This is the specialization to embed extra bits of information +//!in a raw pointer. The extra bits are stored in the lower bits of the pointer. +template +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_NOEXCEPT + { return pointer(uintptr_t(n) & uintptr_t(~Mask)); } + + 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_NOEXCEPT + { return std::size_t(uintptr_t(n) & Mask); } + + 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)); + } +}; + +} //namespace intrusive +} //namespace boost + +#if defined(BOOST_GCC) && (BOOST_GCC >= 40600) +# pragma GCC diagnostic pop +#endif + +#include + +#endif //BOOST_INTRUSIVE_POINTER_PLUS_BITS_HPP diff --git a/third_party/boost/libs/intrusive/include/boost/intrusive/pointer_rebind.hpp b/third_party/boost/libs/intrusive/include/boost/intrusive/pointer_rebind.hpp new file mode 100644 index 00000000000..9592e06e1de --- /dev/null +++ b/third_party/boost/libs/intrusive/include/boost/intrusive/pointer_rebind.hpp @@ -0,0 +1,188 @@ +////////////////////////////////////////////////////////////////////////////// +// +// (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_POINTER_REBIND_HPP +#define BOOST_INTRUSIVE_POINTER_REBIND_HPP + +#ifndef BOOST_INTRUSIVE_DETAIL_WORKAROUND_HPP +#include +#endif //BOOST_INTRUSIVE_DETAIL_WORKAROUND_HPP + +#ifndef BOOST_CONFIG_HPP +# include +#endif + +#if defined(BOOST_HAS_PRAGMA_ONCE) +# pragma once +#endif + +namespace boost { +namespace intrusive { + +/////////////////////////// +//struct pointer_rebind_mode +/////////////////////////// +template +struct pointer_has_rebind +{ + template struct any + { any(const V&) { } }; + + template + static char test(int, typename X::template rebind*); + + template + static int test(any, void*); + + static const bool value = (1 == sizeof(test(0, 0))); +}; + +template +struct pointer_has_rebind_other +{ + template struct any + { any(const V&) { } }; + + template + static char test(int, typename X::template rebind::other*); + + template + static int test(any, void*); + + static const bool value = (1 == sizeof(test(0, 0))); +}; + +template +struct pointer_rebind_mode +{ + static const unsigned int rebind = (unsigned int)pointer_has_rebind::value; + static const unsigned int rebind_other = (unsigned int)pointer_has_rebind_other::value; + static const unsigned int mode = rebind + rebind*rebind_other; +}; + +//////////////////////// +//struct pointer_rebinder +//////////////////////// +template +struct pointer_rebinder; + +// Implementation of pointer_rebinder::type if Ptr has +// its own rebind::other type (C++03) +template +struct pointer_rebinder< Ptr, U, 2u > +{ + typedef typename Ptr::template rebind::other type; +}; + +// Implementation of pointer_rebinder::type if Ptr has +// its own rebind template. +template +struct pointer_rebinder< Ptr, U, 1u > +{ + typedef typename Ptr::template rebind type; +}; + +// Specialization of pointer_rebinder if Ptr does not +// have its own rebind template but has a the form Ptr, +// where An... comprises zero or more type parameters. +// Many types fit this form, hence many pointers will get a +// reasonable default for rebind. +#if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) + +template