diff --git a/.appveyor.yml b/.appveyor.yml index c080596e..7ffc2fc6 100644 --- a/.appveyor.yml +++ b/.appveyor.yml @@ -31,25 +31,6 @@ environment: B2_VARIANT: debug,release matrix: - - FLAVOR: Visual Studio 2008 - APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2015 - B2_TOOLSET: msvc-9.0 - B2_ADDRESS_MODEL: 32 # No 64bit support - - - FLAVOR: Visual Studio 2010 - APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2015 - B2_TOOLSET: msvc-10.0 - B2_ADDRESS_MODEL: 32 # No 64bit support - - - FLAVOR: Visual Studio 2012 - APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2015 - B2_TOOLSET: msvc-11.0 - B2_ADDRESS_MODEL: 32 # No 64bit support - - - FLAVOR: Visual Studio 2013 - APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2015 - B2_TOOLSET: msvc-12.0 - - FLAVOR: Visual Studio 2015 APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2015 B2_TOOLSET: msvc-14.0 @@ -69,13 +50,6 @@ environment: B2_CXXSTD: latest B2_TOOLSET: msvc-14.1 - - FLAVOR: cygwin (32-bit, C++03) - APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2017 - ADDPATH: C:\cygwin\bin; - B2_ADDRESS_MODEL: 32 - B2_CXXSTD: 03 - B2_TOOLSET: gcc - - FLAVOR: cygwin (32-bit, C++11) APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2017 ADDPATH: C:\cygwin\bin; @@ -97,15 +71,6 @@ environment: B2_CXXSTD: 1z B2_TOOLSET: gcc - - FLAVOR: cygwin (64-bit, latest, C++03) - APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2022 - ADDPATH: C:\cygwin64\bin; - B2_ADDRESS_MODEL: 64 - B2_CXXSTD: 03 - B2_TOOLSET: gcc - B2_FLAGS: "include=libs/unordered/test/unordered include=libs/unordered/test/exception" - B2_VARIANT: release - - FLAVOR: cygwin (64-bit, latest, C++11) APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2022 ADDPATH: C:\cygwin64\bin; @@ -133,13 +98,6 @@ environment: B2_FLAGS: "include=libs/unordered/test/unordered include=libs/unordered/test/exception" B2_VARIANT: release - - FLAVOR: mingw-w64, 32 bit, C++03 - APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2019 - ADDPATH: C:\mingw-w64\i686-8.1.0-posix-dwarf-rt_v6-rev0\mingw32\bin; - B2_CXXSTD: 03 - B2_TOOLSET: gcc - B2_ADDRESS_MODEL: 32 - - FLAVOR: mingw-w64, 32 bit, C++11 APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2019 ADDPATH: C:\mingw-w64\i686-8.1.0-posix-dwarf-rt_v6-rev0\mingw32\bin; @@ -168,13 +126,6 @@ environment: B2_TOOLSET: gcc B2_ADDRESS_MODEL: 32 - - FLAVOR: mingw-w64, 64 bit, C++03 - APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2019 - ADDPATH: C:\mingw-w64\x86_64-8.1.0-posix-seh-rt_v6-rev0\mingw64\bin; - B2_CXXSTD: 03 - B2_TOOLSET: gcc - B2_ADDRESS_MODEL: 64 - - FLAVOR: mingw-w64, 64 bit, C++11 APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2019 ADDPATH: C:\mingw-w64\x86_64-8.1.0-posix-seh-rt_v6-rev0\mingw64\bin; diff --git a/.drone.jsonnet b/.drone.jsonnet index 7e3e7115..7386d337 100644 --- a/.drone.jsonnet +++ b/.drone.jsonnet @@ -100,40 +100,16 @@ local windows_pipeline(name, image, environment, arch = "amd64") = }; [ - linux_pipeline( - "Linux 14.04 GCC 4.4 32/64", - "cppalliance/droneubuntu1404:1", - { TOOLSET: 'gcc', COMPILER: 'g++-4.4', CXXSTD: '98,0x', ADDRMD: '32,64' }, - "g++-4.4-multilib", - [ "ppa:ubuntu-toolchain-r/test" ], - ), - - linux_pipeline( - "Linux 14.04 GCC 4.6 32/64", - "cppalliance/droneubuntu1404:1", - { TOOLSET: 'gcc', COMPILER: 'g++-4.6', CXXSTD: '98,0x', ADDRMD: '32,64' }, - "g++-4.6-multilib", - [ "ppa:ubuntu-toolchain-r/test" ], - ), - - linux_pipeline( - "Linux 14.04 GCC 4.7 32/64", - "cppalliance/droneubuntu1404:1", - { TOOLSET: 'gcc', COMPILER: 'g++-4.7', CXXSTD: '98,0x', ADDRMD: '32,64' }, - "g++-4.7-multilib", - [ "ppa:ubuntu-toolchain-r/test" ], - ), - linux_pipeline( "Linux 14.04 GCC 4.8* 32/64", "cppalliance/droneubuntu1404:1", - { TOOLSET: 'gcc', COMPILER: 'g++', CXXSTD: '03,11', ADDRMD: '32,64' }, + { TOOLSET: 'gcc', COMPILER: 'g++', CXXSTD: '11', ADDRMD: '32,64' }, ), linux_pipeline( "Linux 14.04 GCC 4.9 32/64", "cppalliance/droneubuntu1404:1", - { TOOLSET: 'gcc', COMPILER: 'g++-4.9', CXXSTD: '03,11', ADDRMD: '32,64' }, + { TOOLSET: 'gcc', COMPILER: 'g++-4.9', CXXSTD: '11', ADDRMD: '32,64' }, "g++-4.9-multilib", [ "ppa:ubuntu-toolchain-r/test" ], ), @@ -141,26 +117,26 @@ local windows_pipeline(name, image, environment, arch = "amd64") = linux_pipeline( "Linux 16.04 GCC 5* 32/64", "cppalliance/droneubuntu1604:1", - { TOOLSET: 'gcc', COMPILER: 'g++', CXXSTD: '03,11,14', ADDRMD: '32,64' }, + { TOOLSET: 'gcc', COMPILER: 'g++', CXXSTD: '11,14', ADDRMD: '32,64' }, ), linux_pipeline( "Linux 18.04 GCC 6 32/64", "cppalliance/droneubuntu1804:1", - { TOOLSET: 'gcc', COMPILER: 'g++-6', CXXSTD: '03,11,14', ADDRMD: '32,64' }, + { TOOLSET: 'gcc', COMPILER: 'g++-6', CXXSTD: '11,14', ADDRMD: '32,64' }, "g++-6-multilib", ), linux_pipeline( "Linux 18.04 GCC 7* 32/64", "cppalliance/droneubuntu1804:1", - { TOOLSET: 'gcc', COMPILER: 'g++', CXXSTD: '03,11,14,17', ADDRMD: '32,64' }, + { TOOLSET: 'gcc', COMPILER: 'g++', CXXSTD: '11,14,17', ADDRMD: '32,64' }, ), linux_pipeline( - "Linux 18.04 GCC 8 32/64 (03,11)", + "Linux 18.04 GCC 8 32/64 (11)", "cppalliance/droneubuntu1804:1", - { TOOLSET: 'gcc', COMPILER: 'g++-8', CXXSTD: '03,11', ADDRMD: '32,64' }, + { TOOLSET: 'gcc', COMPILER: 'g++-8', CXXSTD: '11', ADDRMD: '32,64' }, "g++-8-multilib", ), @@ -172,9 +148,9 @@ local windows_pipeline(name, image, environment, arch = "amd64") = ), linux_pipeline( - "Linux 20.04 GCC 9* 32/64 (03,11,14)", + "Linux 20.04 GCC 9* 32/64 (11,14)", "cppalliance/droneubuntu2004:1", - { TOOLSET: 'gcc', COMPILER: 'g++', CXXSTD: '03,11,14', ADDRMD: '32,64' }, + { TOOLSET: 'gcc', COMPILER: 'g++', CXXSTD: '11,14', ADDRMD: '32,64' }, ), linux_pipeline( @@ -186,14 +162,14 @@ local windows_pipeline(name, image, environment, arch = "amd64") = linux_pipeline( "Linux 20.04 GCC 9* ARM64", "cppalliance/droneubuntu2004:multiarch", - { TOOLSET: 'gcc', COMPILER: 'g++', CXXSTD: '03,11,14,17,2a' }, + { TOOLSET: 'gcc', COMPILER: 'g++', CXXSTD: '11,14,17,2a' }, arch="arm64", ), linux_pipeline( - "Linux 20.04 GCC 9* S390x (03,11,14)", + "Linux 20.04 GCC 9* S390x (11,14)", "cppalliance/droneubuntu2004:multiarch", - { TOOLSET: 'gcc', COMPILER: 'g++', CXXSTD: '03,11,14' }, + { TOOLSET: 'gcc', COMPILER: 'g++', CXXSTD: '11,14' }, arch="s390x", ), @@ -205,9 +181,9 @@ local windows_pipeline(name, image, environment, arch = "amd64") = ), linux_pipeline( - "Linux 20.04 GCC 10 32/64 (03,11,14)", + "Linux 20.04 GCC 10 32/64 (11,14)", "cppalliance/droneubuntu2004:1", - { TOOLSET: 'gcc', COMPILER: 'g++-10', CXXSTD: '03,11,14', ADDRMD: '32,64' }, + { TOOLSET: 'gcc', COMPILER: 'g++-10', CXXSTD: '11,14', ADDRMD: '32,64' }, "g++-10-multilib", ), @@ -219,9 +195,9 @@ local windows_pipeline(name, image, environment, arch = "amd64") = ), linux_pipeline( - "Linux 22.04 GCC 11* 32/64 (03,11,14)", + "Linux 22.04 GCC 11* 32/64 (11,14)", "cppalliance/droneubuntu2204:1", - { TOOLSET: 'gcc', COMPILER: 'g++', CXXSTD: '03,11,14', ADDRMD: '32,64' }, + { TOOLSET: 'gcc', COMPILER: 'g++', CXXSTD: '11,14', ADDRMD: '32,64' }, ), linux_pipeline( @@ -231,9 +207,9 @@ local windows_pipeline(name, image, environment, arch = "amd64") = ), linux_pipeline( - "Linux 22.04 GCC 12 32 ASAN (03,11,14)", + "Linux 22.04 GCC 12 32 ASAN (11,14)", "cppalliance/droneubuntu2204:1", - { TOOLSET: 'gcc', COMPILER: 'g++-12', CXXSTD: '03,11', ADDRMD: '32' } + asan, + { TOOLSET: 'gcc', COMPILER: 'g++-12', CXXSTD: '11', ADDRMD: '32' } + asan, "g++-12-multilib", ), @@ -266,9 +242,9 @@ local windows_pipeline(name, image, environment, arch = "amd64") = ), linux_pipeline( - "Linux 22.04 GCC 12 64 ASAN (03,11,14)", + "Linux 22.04 GCC 12 64 ASAN (11,14)", "cppalliance/droneubuntu2204:1", - { TOOLSET: 'gcc', COMPILER: 'g++-12', CXXSTD: '03,11,14', ADDRMD: '64' } + asan, + { TOOLSET: 'gcc', COMPILER: 'g++-12', CXXSTD: '11,14', ADDRMD: '64' } + asan, "g++-12-multilib", ), @@ -301,9 +277,9 @@ local windows_pipeline(name, image, environment, arch = "amd64") = ), linux_pipeline( - "Linux 23.04 GCC 13 32/64 (03,11,14)", + "Linux 23.04 GCC 13 32/64 (11,14)", "cppalliance/droneubuntu2304:1", - { TOOLSET: 'gcc', COMPILER: 'g++-13', CXXSTD: '03,11,14', ADDRMD: '32,64' }, + { TOOLSET: 'gcc', COMPILER: 'g++-13', CXXSTD: '11,14', ADDRMD: '32,64' }, "g++-13 g++-13-multilib", ), @@ -317,112 +293,112 @@ local windows_pipeline(name, image, environment, arch = "amd64") = linux_pipeline( "Linux 16.04 Clang 3.5", "cppalliance/droneubuntu1604:1", - { TOOLSET: 'clang', COMPILER: 'clang++-3.5', CXXSTD: '03,11' }, + { TOOLSET: 'clang', COMPILER: 'clang++-3.5', CXXSTD: '11' }, "clang-3.5", ), linux_pipeline( "Linux 16.04 Clang 3.6", "cppalliance/droneubuntu1604:1", - { TOOLSET: 'clang', COMPILER: 'clang++-3.6', CXXSTD: '03,11,14' }, + { TOOLSET: 'clang', COMPILER: 'clang++-3.6', CXXSTD: '11,14' }, "clang-3.6", ), linux_pipeline( "Linux 16.04 Clang 3.7", "cppalliance/droneubuntu1604:1", - { TOOLSET: 'clang', COMPILER: 'clang++-3.7', CXXSTD: '03,11,14' }, + { TOOLSET: 'clang', COMPILER: 'clang++-3.7', CXXSTD: '11,14' }, "clang-3.7", ), linux_pipeline( "Linux 16.04 Clang 3.8", "cppalliance/droneubuntu1604:1", - { TOOLSET: 'clang', COMPILER: 'clang++-3.8', CXXSTD: '03,11,14' }, + { TOOLSET: 'clang', COMPILER: 'clang++-3.8', CXXSTD: '11,14' }, "clang-3.8", ), linux_pipeline( "Linux 18.04 Clang 3.9", "cppalliance/droneubuntu1804:1", - { TOOLSET: 'clang', COMPILER: 'clang++-3.9', CXXSTD: '03,11,14' }, + { TOOLSET: 'clang', COMPILER: 'clang++-3.9', CXXSTD: '11,14' }, "clang-3.9", ), linux_pipeline( "Linux 18.04 Clang 4.0", "cppalliance/droneubuntu1804:1", - { TOOLSET: 'clang', COMPILER: 'clang++-4.0', CXXSTD: '03,11,14' }, + { TOOLSET: 'clang', COMPILER: 'clang++-4.0', CXXSTD: '11,14' }, "clang-4.0", ), linux_pipeline( "Linux 18.04 Clang 5.0", "cppalliance/droneubuntu1804:1", - { TOOLSET: 'clang', COMPILER: 'clang++-5.0', CXXSTD: '03,11,14,1z' }, + { TOOLSET: 'clang', COMPILER: 'clang++-5.0', CXXSTD: '11,14,1z' }, "clang-5.0", ), linux_pipeline( "Linux 18.04 Clang 6.0", "cppalliance/droneubuntu1804:1", - { TOOLSET: 'clang', COMPILER: 'clang++-6.0', CXXSTD: '03,11,14,17' }, + { TOOLSET: 'clang', COMPILER: 'clang++-6.0', CXXSTD: '11,14,17' }, "clang-6.0", ), linux_pipeline( "Linux 20.04 Clang 7", "cppalliance/droneubuntu2004:1", - { TOOLSET: 'clang', COMPILER: 'clang++-7', CXXSTD: '03,11,14,17' }, + { TOOLSET: 'clang', COMPILER: 'clang++-7', CXXSTD: '11,14,17' }, "clang-7", ), linux_pipeline( "Linux 20.04 Clang 8", "cppalliance/droneubuntu2004:1", - { TOOLSET: 'clang', COMPILER: 'clang++-8', CXXSTD: '03,11,14,17' }, + { TOOLSET: 'clang', COMPILER: 'clang++-8', CXXSTD: '11,14,17' }, "clang-8", ), linux_pipeline( "Linux 20.04 Clang 9", "cppalliance/droneubuntu2004:1", - { TOOLSET: 'clang', COMPILER: 'clang++-9', CXXSTD: '03,11,14,17,2a' }, + { TOOLSET: 'clang', COMPILER: 'clang++-9', CXXSTD: '11,14,17,2a' }, "clang-9", ), linux_pipeline( "Linux 20.04 Clang 10", "cppalliance/droneubuntu2004:1", - { TOOLSET: 'clang', COMPILER: 'clang++-10', CXXSTD: '03,11,14,17,2a' }, + { TOOLSET: 'clang', COMPILER: 'clang++-10', CXXSTD: '11,14,17,2a' }, "clang-10", ), linux_pipeline( "Linux 20.04 Clang 11", "cppalliance/droneubuntu2004:1", - { TOOLSET: 'clang', COMPILER: 'clang++-11', CXXSTD: '03,11,14,17,2a' }, + { TOOLSET: 'clang', COMPILER: 'clang++-11', CXXSTD: '11,14,17,2a' }, "clang-11", ), linux_pipeline( "Linux 20.04 Clang 12", "cppalliance/droneubuntu2004:1", - { TOOLSET: 'clang', COMPILER: 'clang++-12', CXXSTD: '03,11,14,17,2a' }, + { TOOLSET: 'clang', COMPILER: 'clang++-12', CXXSTD: '11,14,17,2a' }, "clang-12", ), linux_pipeline( "Linux 22.04 Clang 13", "cppalliance/droneubuntu2204:1", - { TOOLSET: 'clang', COMPILER: 'clang++-13', CXXSTD: '03,11,14,17,20' }, + { TOOLSET: 'clang', COMPILER: 'clang++-13', CXXSTD: '11,14,17,20' }, "clang-13", ), linux_pipeline( - "Linux 22.04 Clang 14 UBSAN (03,11,14)", + "Linux 22.04 Clang 14 UBSAN (11,14)", "cppalliance/droneubuntu2204:1", - { TOOLSET: 'clang', COMPILER: 'clang++-14', CXXSTD: '03,11,14' } + ubsan, + { TOOLSET: 'clang', COMPILER: 'clang++-14', CXXSTD: '11,14' } + ubsan, "clang-14", ), @@ -434,9 +410,9 @@ local windows_pipeline(name, image, environment, arch = "amd64") = ), linux_pipeline( - "Linux 22.04 Clang 14 ASAN (03,11,14)", + "Linux 22.04 Clang 14 ASAN (11,14)", "cppalliance/droneubuntu2204:1", - { TOOLSET: 'clang', COMPILER: 'clang++-14', CXXSTD: '03,11,14' } + asan, + { TOOLSET: 'clang', COMPILER: 'clang++-14', CXXSTD: '11,14' } + asan, "clang-14", ), @@ -457,14 +433,14 @@ local windows_pipeline(name, image, environment, arch = "amd64") = linux_pipeline( "Linux 22.04 Clang 15", "cppalliance/droneubuntu2204:1", - { TOOLSET: 'clang', COMPILER: 'clang++-15', CXXSTD: '03,11,14,17,20,2b' }, + { TOOLSET: 'clang', COMPILER: 'clang++-15', CXXSTD: '11,14,17,20,2b' }, "clang-15", ["deb http://apt.llvm.org/jammy/ llvm-toolchain-jammy-15 main"], ), macos_pipeline( - "MacOS 10.15 Xcode 12.2 UBSAN (03,11)", - { TOOLSET: 'clang', COMPILER: 'clang++', CXXSTD: '03,11' } + ubsan, + "MacOS 10.15 Xcode 12.2 UBSAN (11)", + { TOOLSET: 'clang', COMPILER: 'clang++', CXXSTD: '11' } + ubsan, ), macos_pipeline( @@ -479,7 +455,7 @@ local windows_pipeline(name, image, environment, arch = "amd64") = macos_pipeline( "MacOS 12.4 Xcode 13.4.1 ASAN", - { TOOLSET: 'clang', COMPILER: 'clang++', CXXSTD: '03,11,14,1z' } + asan, + { TOOLSET: 'clang', COMPILER: 'clang++', CXXSTD: '11,14,1z' } + asan, xcode_version = "13.4.1", osx_version = "monterey", arch = "arm64", ), diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 4f397169..19fd945a 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -52,49 +52,65 @@ jobs: matrix: include: # Linux, gcc - - { compiler: gcc-7, cxxstd: '03,11,14,17', os: 'ubuntu-20.04', install: 'g++-7' } - - { compiler: gcc-8, cxxstd: '03,11,14,17', os: 'ubuntu-20.04', install: 'g++-8' } - - { compiler: gcc-9, cxxstd: '03,11,14,17', os: 'ubuntu-22.04', install: 'g++-9' } - - { compiler: gcc-10, cxxstd: '03,11,14,17,20', os: 'ubuntu-22.04', install: 'g++-10' } - - { compiler: gcc-11, cxxstd: '03,11,14,17,20', os: 'ubuntu-22.04', install: 'g++-11' } - - { name: "gcc-12 w/ sanitizers (03,11,14)", sanitize: yes, - compiler: gcc-12, cxxstd: '03,11,14', os: 'ubuntu-22.04', ccache_key: "san1" } - - { name: "gcc-12 w/ sanitizers (17,20,2b)", sanitize: yes, - compiler: gcc-12, cxxstd: '17,20,2b', os: 'ubuntu-22.04', ccache_key: "san2" } + - { compiler: gcc-7, cxxstd: '11,14,17', os: 'ubuntu-20.04', install: 'g++-7' } + - { compiler: gcc-8, cxxstd: '11,14,17', os: 'ubuntu-20.04', install: 'g++-8' } + - { compiler: gcc-9, cxxstd: '11,14,17', os: 'ubuntu-22.04', install: 'g++-9' } + - { compiler: gcc-10, cxxstd: '11,14,17,20', os: 'ubuntu-22.04', install: 'g++-10' } + - { compiler: gcc-11, cxxstd: '11,14,17,20', os: 'ubuntu-22.04', install: 'g++-11' } + - { name: "gcc-12 w/ sanitizers (11)", sanitize: yes, + compiler: gcc-12, cxxstd: '11', os: 'ubuntu-22.04', ccache_key: "san1" } + - { name: "gcc-12 w/ sanitizers (14)", sanitize: yes, + compiler: gcc-12, cxxstd: '14', os: 'ubuntu-22.04', ccache_key: "san1" } + - { name: "gcc-12 w/ sanitizers (17)", sanitize: yes, + compiler: gcc-12, cxxstd: '17', os: 'ubuntu-22.04', ccache_key: "san2" } + - { name: "gcc-12 w/ sanitizers (20)", sanitize: yes, + compiler: gcc-12, cxxstd: '20', os: 'ubuntu-22.04', ccache_key: "san2" } + - { name: "gcc-12 w/ sanitizers (2b)", sanitize: yes, + compiler: gcc-12, cxxstd: '2b', os: 'ubuntu-22.04', ccache_key: "san2" } - { name: Collect coverage, coverage: yes, - compiler: gcc-12, cxxstd: '03,20', os: 'ubuntu-22.04', install: 'g++-12-multilib', address-model: '32,64', ccache_key: "cov" } + compiler: gcc-12, cxxstd: '20', os: 'ubuntu-22.04', install: 'g++-12-multilib', address-model: '32,64', ccache_key: "cov" } - { name: "cfoa tsan (gcc-12)", cxxstd: '11,14,17,20,2b', os: 'ubuntu-22.04', compiler: gcc-12, targets: 'libs/unordered/test//cfoa_tests', thread-sanitize: yes, ccache_key: "tsan" } # Linux, clang, libc++ - - { compiler: clang-7, cxxstd: '03,11,14,17', os: 'ubuntu-20.04', stdlib: libc++, install: 'clang-7 libc++-7-dev libc++abi-7-dev' } - - { compiler: clang-10, cxxstd: '03,11,14,17,20', os: 'ubuntu-20.04', stdlib: libc++, install: 'clang-10 libc++-10-dev libc++abi-10-dev' } - - { compiler: clang-11, cxxstd: '03,11,14,17,20', os: 'ubuntu-22.04', stdlib: libc++, install: 'clang-11 libc++-11-dev libc++abi-11-dev' } + - { compiler: clang-7, cxxstd: '11,14,17', os: 'ubuntu-20.04', stdlib: libc++, install: 'clang-7 libc++-7-dev libc++abi-7-dev' } + - { compiler: clang-10, cxxstd: '11,14,17,20', os: 'ubuntu-20.04', stdlib: libc++, install: 'clang-10 libc++-10-dev libc++abi-10-dev' } + - { compiler: clang-11, cxxstd: '11,14,17,20', os: 'ubuntu-22.04', stdlib: libc++, install: 'clang-11 libc++-11-dev libc++abi-11-dev' } # clang-12 doesn't work on 'ubuntu-22.04', the linker can't find -lunwind for some reason - - { name: "clang-12 w/ sanitizers (03,11,14)", sanitize: yes, - compiler: clang-12, cxxstd: '03,11,14', os: 'ubuntu-20.04', stdlib: libc++, install: 'clang-12 libc++-12-dev libc++abi-12-dev', ccache_key: "san1" } - - { name: "clang-12 w/ sanitizers (17,20,2b)", sanitize: yes, - compiler: clang-12, cxxstd: '17,20,2b', os: 'ubuntu-20.04', stdlib: libc++, install: 'clang-12 libc++-12-dev libc++abi-12-dev', ccache_key: "san2" } - - { compiler: clang-13, cxxstd: '03,11,14,17,20,2b', os: 'ubuntu-22.04', stdlib: libc++, install: 'clang-13 libc++-13-dev libc++abi-13-dev' } + - { name: "clang-12 w/ sanitizers (11,14)", sanitize: yes, + compiler: clang-12, cxxstd: '11,14', os: 'ubuntu-20.04', stdlib: libc++, install: 'clang-12 libc++-12-dev libc++abi-12-dev', ccache_key: "san1" } + - { name: "clang-12 w/ sanitizers (17)", sanitize: yes, + compiler: clang-12, cxxstd: '17', os: 'ubuntu-20.04', stdlib: libc++, install: 'clang-12 libc++-12-dev libc++abi-12-dev', ccache_key: "san2" } + - { name: "clang-12 w/ sanitizers (20)", sanitize: yes, + compiler: clang-12, cxxstd: '20', os: 'ubuntu-20.04', stdlib: libc++, install: 'clang-12 libc++-12-dev libc++abi-12-dev', ccache_key: "san2" } + - { name: "clang-12 w/ sanitizers (2b)", sanitize: yes, + compiler: clang-12, cxxstd: '2b', os: 'ubuntu-20.04', stdlib: libc++, install: 'clang-12 libc++-12-dev libc++abi-12-dev', ccache_key: "san2" } + - { compiler: 'clang-13', cxxstd: '11,14', os: 'ubuntu-22.04', stdlib: libc++, install: 'clang-13 libc++-13-dev libc++abi-13-dev' } + - { compiler: 'clang-13', cxxstd: '17,20,2b', os: 'ubuntu-22.04', stdlib: libc++, install: 'clang-13 libc++-13-dev libc++abi-13-dev' } # not using libc++ because of https://github.com/llvm/llvm-project/issues/52771 - - { name: "clang-14 w/ sanitizers (03,11,14)", sanitize: yes, - compiler: clang-14, cxxstd: '03,11,14', os: 'ubuntu-22.04', ccache_key: "san1" } - - { name: "clang-14 w/ sanitizers (17,20,2b)", sanitize: yes, - compiler: clang-14, cxxstd: '17,20,2b', os: 'ubuntu-22.04', ccache_key: "san2" } + - { name: "clang-14 w/ sanitizers (11,14)", sanitize: yes, + compiler: clang-14, cxxstd: '11,14', os: 'ubuntu-22.04', ccache_key: "san1" } + - { name: "clang-14 w/ sanitizers (17)", sanitize: yes, + compiler: clang-14, cxxstd: '17', os: 'ubuntu-22.04', ccache_key: "san2" } + - { name: "clang-14 w/ sanitizers (20)", sanitize: yes, + compiler: clang-14, cxxstd: '20', os: 'ubuntu-22.04', ccache_key: "san2" } + - { name: "clang-14 w/ sanitizers (2b)", sanitize: yes, + compiler: clang-14, cxxstd: '2b', os: 'ubuntu-22.04', ccache_key: "san2" } - { name: "cfoa tsan (clang-14)", cxxstd: '11,14,17,20,2b', os: 'ubuntu-22.04', compiler: clang-14, targets: 'libs/unordered/test//cfoa_tests', thread-sanitize: yes, stdlib: libc++, install: 'clang-14 libc++-14-dev libc++abi-14-dev', ccache_key: "tsan" } - - { compiler: clang-15, cxxstd: '03,11,14,17,20,2b', os: 'ubuntu-22.04', stdlib: libc++, install: 'clang-15 libc++-15-dev libc++abi-15-dev' } + - { compiler: 'clang-15', cxxstd: '11,14', os: 'ubuntu-22.04', stdlib: libc++, install: 'clang-15 libc++-15-dev libc++abi-15-dev' } + - { compiler: 'clang-15', cxxstd: '17,20,2b', os: 'ubuntu-22.04', stdlib: libc++, install: 'clang-15 libc++-15-dev libc++abi-15-dev' } # OSX, clang - - { compiler: clang, cxxstd: '03,11,14,17,2a', os: 'macos-11' } - - { compiler: clang, cxxstd: '03,11,14,17,2a', os: 'macos-12', sanitize: yes, ccache_key: "san1" } - - { compiler: clang, cxxstd: '11,14,17,2a', os: 'macos-12', thread-sanitize: yes, targets: 'libs/unordered/test//cfoa_tests', ccache_key: "tsan" } - - { compiler: clang, cxxstd: '03,11,14,17,20,2b', os: 'macos-13' } + - { compiler: clang, cxxstd: '11,14,17,2a', os: 'macos-11' } + - { compiler: clang, cxxstd: '11,14,17,2a', os: 'macos-12', sanitize: yes, ccache_key: "san1" } + - { compiler: clang, cxxstd: '11,14,17,2a', os: 'macos-12', thread-sanitize: yes, targets: 'libs/unordered/test//cfoa_tests', ccache_key: "tsan" } + - { compiler: clang, cxxstd: '11,14,17,20,2b', os: 'macos-13' } timeout-minutes: 360 # posix (gcc-12 w/ sanitizers is taking longer than 210 minutes @@ -250,7 +266,7 @@ jobs: - { toolset: msvc-14.3, cxxstd: '14', addrmd: '64', os: 'windows-2022', variant: 'debug', defines: '_ALLOW_RTCc_IN_STL', cxxflags: '/RTCc' } - { toolset: msvc-14.3, cxxstd: '14', addrmd: '32', os: 'windows-2022', variant: 'debug', defines: '_ALLOW_RTCc_IN_STL', cxxflags: '"/RTCc /arch:IA32"' } - { toolset: clang-win, cxxstd: '14,17,latest', addrmd: '32,64', os: 'windows-2022', variant: 'debug,release' } - - { toolset: gcc, cxxstd: '03,11,14,17,2a', addrmd: '64', os: 'windows-2019', variant: 'debug,release' } + - { toolset: gcc, cxxstd: '11,14,17,2a', addrmd: '64', os: 'windows-2019', variant: 'debug,release' } needs: [runner-selection] runs-on: ${{ fromJSON(needs.runner-selection.outputs.labelmatrix)[matrix.os] }} @@ -307,8 +323,8 @@ jobs: fail-fast: false matrix: include: - - { sys: MINGW32, compiler: gcc, cxxstd: '03,11,17,20' } - - { sys: MINGW64, compiler: gcc, cxxstd: '03,11,17,20' } + - { sys: MINGW32, compiler: gcc, cxxstd: '11,17,20' } + - { sys: MINGW64, compiler: gcc, cxxstd: '11,17,20' } needs: [runner-selection] runs-on: ${{ fromJSON(needs.runner-selection.outputs.labelmatrix)['windows-latest'] }} diff --git a/doc/unordered/changes.adoc b/doc/unordered/changes.adoc index f8074c2c..f99979c0 100644 --- a/doc/unordered/changes.adoc +++ b/doc/unordered/changes.adoc @@ -18,6 +18,8 @@ a concurrent container from user code. * Added Boost.Serialization support to all containers and their (non-local) iterator types. * Added support for fancy pointers to open-addressing and concurrent containers. This enables scenarios like the use of Boost.Interprocess allocators to construct containers in shared memory. +* Starting with this release, `boost::unordered_[multi]set` and `boost::unordered_[multi]map` + only work with C++11 onwards. == Release 1.83.0 - Major update diff --git a/doc/unordered/compliance.adoc b/doc/unordered/compliance.adoc index 897c7dfb..a299465a 100644 --- a/doc/unordered/compliance.adoc +++ b/doc/unordered/compliance.adoc @@ -7,116 +7,54 @@ == Closed-addressing Containers -`unordered_[multi]set` and `unordered_[multi]map` are intended to provide a conformant -implementation of the {cpp}20 standard that will work with {cpp}98 upwards. -This wide compatibility does mean some compromises have to be made. -With a compiler and library that fully support {cpp}11, the differences should -be minor. +`boost::unordered_[multi]set` and `boost::unordered_[multi]map` provide a conformant +implementation for {cpp}11 (or later) compilers of the latest standard revision of +{cpp} unordered associative containers, with very minor deviations as noted. +The containers are fully https://en.cppreference.com/w/cpp/named_req/AllocatorAwareContainer[AllocatorAware^] +and support https://en.cppreference.com/w/cpp/named_req/Allocator#Fancy_pointers[fancy pointers^]. -=== Move Emulation +=== Deduction Guides -Support for move semantics is implemented using Boost.Move. If rvalue -references are available it will use them, but if not it uses a close, -but imperfect emulation. On such compilers: +Deduction guides for +https://en.cppreference.com/w/cpp/language/class_template_argument_deduction[class template argument deduction (CTAD)^] +are only available on {cpp}17 (or later) compilers. -* Non-copyable objects can be stored in the containers. - They can be constructed in place using `emplace`, or if they support - Boost.Move, moved into place. -* The containers themselves are not movable. -* Argument forwarding is not perfect. +=== Piecewise Pair Emplacement -=== Use of Allocators - -{cpp}11 introduced a new allocator system. It's backwards compatible due to -the lax requirements for allocators in the old standard, but might need -some changes for allocators which worked with the old versions of the -unordered containers. -It uses a traits class, `allocator_traits` to handle the allocator -adding extra functionality, and making some methods and types optional. -During development a stable release of -`allocator_traits` wasn't available so an internal partial implementation -is always used in this version. Hopefully a future version will use the -standard implementation where available. - -The member functions `construct`, `destroy` and `max_size` are now -optional, if they're not available a fallback is used. -A full implementation of `allocator_traits` requires sophisticated -member function detection so that the fallback is used whenever the -member function call is not well formed. -This requires support for SFINAE expressions, which are available on -GCC from version 4.4 and Clang. - -On other compilers, there's just a test to see if the allocator has -a member, but no check that it can be called. So rather than using a -fallback there will just be a compile error. - -`propagate_on_container_copy_assignment`, -`propagate_on_container_move_assignment`, -`propagate_on_container_swap` and -`select_on_container_copy_construction` are also supported. -Due to imperfect move emulation, some assignments might check -`propagate_on_container_copy_assignment` on some compilers and -`propagate_on_container_move_assignment` on others. - -=== Construction/Destruction Using Allocators - -The following support is required for full use of {cpp}11 style -construction/destruction: - -* Variadic templates. -* Piecewise construction of `std::pair`. -* Either `std::allocator_traits` or expression SFINAE. - -This is detected using Boost.Config. The macro -`BOOST_UNORDERED_CXX11_CONSTRUCTION` will be set to 1 if it is found, or 0 -otherwise. - -When this is the case `allocator_traits::construct` and -`allocator_traits::destroy` will always be used, apart from when piecewise -constructing a `std::pair` using `boost::tuple` (see <>), but that should be easily avoided. - -When support is not available `allocator_traits::construct` and -`allocator_traits::destroy` are never called. - -=== Pointer Traits - -`pointer_traits` aren't used. Instead, pointer types are obtained from -rebound allocators, this can cause problems if the allocator can't be -used with incomplete types. If `const_pointer` is not defined in the -allocator, `boost::pointer_to_other::type` -is used to obtain a const pointer. - -=== Pairs - -Since the containers use `std::pair` they're limited to the version -from the current standard library. But since {cpp}11 ``std::pair``'s -`piecewise_construct` based constructor is very useful, `emplace` -emulates it with a `piecewise_construct` in the `boost::unordered` -namespace. So for example, the following will work: +In accordance with the standard specification, +`boost::unordered_[multi]map::emplace` supports piecewise pair construction: [source,c++] ---- boost::unordered_multimap x; +x.emplace( + std::piecewise_construct, + std::make_tuple("key"), std::make_tuple(1, 2)); +---- + +Additionally, the same +functionality is provided via non-standard `boost::unordered::piecewise_construct` +and Boost.Tuple: + +[source,c++] +---- x.emplace( boost::unordered::piecewise_construct, boost::make_tuple("key"), boost::make_tuple(1, 2)); ---- -Older drafts of the standard also supported variadic constructors -for `std::pair`, where the first argument would be used for the -first part of the pair, and the remaining for the second part. +This feature has been retained for backwards compatibility with +previous versions of Boost.Unordered: users are encouraged to +update their code to use `std::piecewise_construct` and +``std::tuple``s instead. -=== Miscellaneous +=== Swap When swapping, `Pred` and `Hash` are not currently swapped by calling -`swap`, their copy constructors are used. As a consequence when swapping +`swap`, their copy constructors are used. As a consequence, when swapping an exception may be thrown from their copy constructor. -Variadic constructor arguments for `emplace` are only used when both -rvalue references and variadic template parameters are available. -Otherwise `emplace` can only take up to 10 constructors arguments. - == Open-addressing Containers The C++ standard does not currently provide any open-addressing container @@ -129,7 +67,9 @@ radically different from that imposed by the standard (closed addressing). Open-addressing containers provided by Boost.Unordered only work with reasonably compliant C++11 (or later) compilers. Language-level features such as move semantics and variadic template parameters are then not emulated. -The containers are fully https://en.cppreference.com/w/cpp/named_req/AllocatorAwareContainer[AllocatorAware^]. +The containers are fully https://en.cppreference.com/w/cpp/named_req/AllocatorAwareContainer[AllocatorAware^] +and support https://en.cppreference.com/w/cpp/named_req/Allocator#Fancy_pointers[fancy pointers^]. + The main differences with C++ unordered associative containers are: @@ -156,7 +96,9 @@ due to their inherent problems in concurrent scenarios (high contention, prone t so, Boost.Unordered concurrent containers are technically not models of https://en.cppreference.com/w/cpp/named_req/Container[Container^], although they meet all the requirements of https://en.cppreference.com/w/cpp/named_req/AllocatorAwareContainer[AllocatorAware^] -containers except those implying iterators. +containers (including +https://en.cppreference.com/w/cpp/named_req/Allocator#Fancy_pointers[fancy pointer^] support) +except those implying iterators. In a non-concurrent unordered container, iterators serve two main purposes: diff --git a/doc/unordered/concurrent_flat_map.adoc b/doc/unordered/concurrent_flat_map.adoc index a2b28c9c..8dd00479 100644 --- a/doc/unordered/concurrent_flat_map.adoc +++ b/doc/unordered/concurrent_flat_map.adoc @@ -1045,13 +1045,13 @@ if there is an element with an equivalent key; otherwise, the construction is of ```c++ // first two overloads value_type(std::piecewise_construct, - std::forward_as_tuple(boost::forward(k)), - std::forward_as_tuple(boost::forward(args)...)) + std::forward_as_tuple(std::forward(k)), + std::forward_as_tuple(std::forward(args)...)) // third overload value_type(std::piecewise_construct, - std::forward_as_tuple(boost::forward(k)), - std::forward_as_tuple(boost::forward(args)...)) + std::forward_as_tuple(std::forward(k)), + std::forward_as_tuple(std::forward(args)...)) ``` unlike xref:#concurrent_flat_map_emplace[emplace], which simply forwards all arguments to ``value_type``'s constructor. @@ -1093,13 +1093,13 @@ if there is an element with an equivalent key; otherwise, the construction is of ```c++ // first four overloads value_type(std::piecewise_construct, - std::forward_as_tuple(boost::forward(k)), - std::forward_as_tuple(boost::forward(args)...)) + std::forward_as_tuple(std::forward(k)), + std::forward_as_tuple(std::forward(args)...)) // last two overloads value_type(std::piecewise_construct, - std::forward_as_tuple(boost::forward(k)), - std::forward_as_tuple(boost::forward(args)...)) + std::forward_as_tuple(std::forward(k)), + std::forward_as_tuple(std::forward(args)...)) ``` Invalidates pointers and references to elements if a rehashing is issued. @@ -1121,19 +1121,19 @@ template bool insert_or_assign(K&& k, M&& obj); Inserts a new element into the table or updates an existing one by assigning to the contained value. -If there is an element with key `k`, then it is updated by assigning `boost::forward(obj)`. +If there is an element with key `k`, then it is updated by assigning `std::forward(obj)`. If there is no such element, it is added to the table as: ```c++ // first two overloads value_type(std::piecewise_construct, - std::forward_as_tuple(boost::forward(k)), - std::forward_as_tuple(boost::forward(obj))) + std::forward_as_tuple(std::forward(k)), + std::forward_as_tuple(std::forward(obj))) // third overload value_type(std::piecewise_construct, - std::forward_as_tuple(boost::forward(k)), - std::forward_as_tuple(boost::forward(obj))) + std::forward_as_tuple(std::forward(k)), + std::forward_as_tuple(std::forward(obj))) ``` [horizontal] diff --git a/doc/unordered/unordered_flat_map.adoc b/doc/unordered/unordered_flat_map.adoc index 7518ba09..f637279d 100644 --- a/doc/unordered/unordered_flat_map.adoc +++ b/doc/unordered/unordered_flat_map.adoc @@ -909,13 +909,13 @@ if there is an element with an equivalent key; otherwise, the construction is of ```c++ // first two overloads value_type(std::piecewise_construct, - std::forward_as_tuple(boost::forward(k)), - std::forward_as_tuple(boost::forward(args)...)) + std::forward_as_tuple(std::forward(k)), + std::forward_as_tuple(std::forward(args)...)) // third overload value_type(std::piecewise_construct, - std::forward_as_tuple(boost::forward(k)), - std::forward_as_tuple(boost::forward(args)...)) + std::forward_as_tuple(std::forward(k)), + std::forward_as_tuple(std::forward(args)...)) ``` unlike xref:#unordered_flat_map_emplace[emplace], which simply forwards all arguments to ``value_type``'s constructor. @@ -954,13 +954,13 @@ if there is an element with an equivalent key; otherwise, the construction is of ```c++ // first two overloads value_type(std::piecewise_construct, - std::forward_as_tuple(boost::forward(k)), - std::forward_as_tuple(boost::forward(args)...)) + std::forward_as_tuple(std::forward(k)), + std::forward_as_tuple(std::forward(args)...)) // third overload value_type(std::piecewise_construct, - std::forward_as_tuple(boost::forward(k)), - std::forward_as_tuple(boost::forward(args)...)) + std::forward_as_tuple(std::forward(k)), + std::forward_as_tuple(std::forward(args)...)) ``` unlike xref:#unordered_flat_map_emplace_hint[emplace_hint], which simply forwards all arguments to ``value_type``'s constructor. @@ -985,19 +985,19 @@ template Inserts a new element into the container or updates an existing one by assigning to the contained value. -If there is an element with key `k`, then it is updated by assigning `boost::forward(obj)`. +If there is an element with key `k`, then it is updated by assigning `std::forward(obj)`. If there is no such element, it is added to the container as: ```c++ // first two overloads value_type(std::piecewise_construct, - std::forward_as_tuple(boost::forward(k)), - std::forward_as_tuple(boost::forward(obj))) + std::forward_as_tuple(std::forward(k)), + std::forward_as_tuple(std::forward(obj))) // third overload value_type(std::piecewise_construct, - std::forward_as_tuple(boost::forward(k)), - std::forward_as_tuple(boost::forward(obj))) + std::forward_as_tuple(std::forward(k)), + std::forward_as_tuple(std::forward(obj))) ``` [horizontal] @@ -1023,19 +1023,19 @@ template Inserts a new element into the container or updates an existing one by assigning to the contained value. -If there is an element with key `k`, then it is updated by assigning `boost::forward(obj)`. +If there is an element with key `k`, then it is updated by assigning `std::forward(obj)`. If there is no such element, it is added to the container as: ```c++ // first two overloads value_type(std::piecewise_construct, - std::forward_as_tuple(boost::forward(k)), - std::forward_as_tuple(boost::forward(obj))) + std::forward_as_tuple(std::forward(k)), + std::forward_as_tuple(std::forward(obj))) // third overload value_type(std::piecewise_construct, - std::forward_as_tuple(boost::forward(k)), - std::forward_as_tuple(boost::forward(obj))) + std::forward_as_tuple(std::forward(k)), + std::forward_as_tuple(std::forward(obj))) ``` `hint` is a suggestion to where the element should be inserted. This implementation ignores it. diff --git a/doc/unordered/unordered_map.adoc b/doc/unordered/unordered_map.adoc index d01944a0..5b70df80 100644 --- a/doc/unordered/unordered_map.adoc +++ b/doc/unordered/unordered_map.adoc @@ -26,12 +26,12 @@ namespace boost { using hasher = Hash; using key_equal = Pred; using allocator_type = Allocator; - using pointer = typename boost::allocator_traits::pointer; - using const_pointer = typename boost::allocator_traits::const_pointer; + using pointer = typename std::allocator_traits::pointer; + using const_pointer = typename std::allocator_traits::const_pointer; using reference = value_type&; using const_reference = const value_type&; - using size_type = _implementation-defined_; - using difference_type = _implementation-defined_; + using size_type = std::size_t; + using difference_type = std::ptrdiff_t; using iterator = _implementation-defined_; using const_iterator = _implementation-defined_; @@ -316,6 +316,7 @@ namespace boost { |_Allocator_ |An allocator whose value type is the same as the container's value type. +Allocators using https://en.cppreference.com/w/cpp/named_req/Allocator#Fancy_pointers[fancy pointers] are supported. |=== @@ -332,47 +333,6 @@ a Boost.Serialization archive with a version of Boost prior to Boost 1.84. === Typedefs -[source,c++,subs=+quotes] ----- -typedef typename allocator_type::pointer pointer; ----- - -`value_type*` if `allocator_type::pointer` is not defined. - ---- - -[source,c++,subs=+quotes] ----- -typedef typename allocator_type::const_pointer const_pointer; ----- - -`boost::pointer_to_other::type` if `allocator_type::const_pointer` is not defined. - - ---- - -[source,c++,subs=+quotes] ----- -typedef _implementation-defined_ size_type; ----- - -An unsigned integral type. - -`size_type` can represent any non-negative value of `difference_type`. - ---- - -[source,c++,subs=+quotes] ----- -typedef _implementation-defined_ difference_type; ----- - -A signed integral type. - -Is identical to the difference type of `iterator` and `const_iterator`. - ---- - [source,c++,subs=+quotes] ---- typedef _implementation-defined_ iterator; @@ -424,7 +384,8 @@ A const_local_iterator object can be used to iterate through a single bucket. typedef _implementation-defined_ node_type; ---- -See node_handle_map for details. +A class for holding extracted container elements, modelling +https://en.cppreference.com/w/cpp/container/node_handle[NodeHandle]. --- @@ -433,7 +394,20 @@ See node_handle_map for details. typedef _implementation-defined_ insert_return_type; ---- -Structure returned by inserting node_type. +A specialization of an internal class template: + +[source,c++,subs=+quotes] +---- +template +struct _insert_return_type_ // name is exposition only +{ + Iterator position; + bool inserted; + NodeType node; +}; +---- + +with `Iterator` = `iterator` and `NodeType` = `node_type`. --- @@ -513,10 +487,7 @@ The move constructor. [horizontal] Notes:;; This is implemented using Boost.Move. -Requires:;; `value_type` is move-constructible. + -+ -On compilers without rvalue reference support the emulation does not support moving without calling `boost::move` if `value_type` is not copyable. -So, for example, you can't return the container from a function. +Requires:;; `value_type` is move-constructible. --- @@ -716,7 +687,6 @@ The move assignment operator. If `Alloc::propagate_on_container_move_assignment` exists and `Alloc::propagate_on_container_move_assignment::value` is `true`, the allocator is overwritten, if not the moved elements are created using the existing allocator. [horizontal] -Notes:;; On compilers without rvalue references, this is emulated using Boost.Move. Note that on some compilers the copy assignment operator may be used in some circumstances. Requires:;; `value_type` is move constructible. --- @@ -827,11 +797,7 @@ If an insert took place, then the iterator points to the newly inserted element. Throws:;; If an exception is thrown by an operation other than a call to `hasher` the function has no effect. Notes:;; Can invalidate iterators, but only if the insert causes the load factor to be greater to or equal to the maximum load factor. + + -Pointers and references to elements are never invalidated. + -+ -If the compiler doesn't support variadic template arguments or rvalue references, this is emulated for up to `10` arguments, with no support for rvalue references or move semantics. + -+ -Since existing `std::pair` implementations don't support `std::piecewise_construct` this emulates it, but using `boost::unordered::piecewise_construct`. +Pointers and references to elements are never invalidated. --- @@ -852,11 +818,7 @@ Notes:;; The standard is fairly vague on the meaning of the hint. But the only p + Can invalidate iterators, but only if the insert causes the load factor to be greater to or equal to the maximum load factor. + + -Pointers and references to elements are never invalidated. + -+ -If the compiler doesn't support variadic template arguments or rvalue references, this is emulated for up to 10 arguments, with no support for rvalue references or move semantics. + -+ -Since existing `std::pair` implementations don't support `std::piecewise_construct` this emulates it, but using `boost::unordered::piecewise_construct`. +Pointers and references to elements are never invalidated. --- @@ -1034,13 +996,13 @@ Notes:;; This function is similiar to xref:#unordered_map_emplace[emplace] excep ```c++ // first two overloads value_type(std::piecewise_construct, - std::forward_as_tuple(boost::forward(k)), - std::forward_as_tuple(boost::forward(args)...)) + std::forward_as_tuple(std::forward(k)), + std::forward_as_tuple(std::forward(args)...)) // third overload value_type(std::piecewise_construct, - std::forward_as_tuple(boost::forward(k)), - std::forward_as_tuple(boost::forward(args)...)) + std::forward_as_tuple(std::forward(k)), + std::forward_as_tuple(std::forward(args)...)) ``` instead of xref:#unordered_map_emplace[emplace] which simply forwards all arguments to ``value_type``'s constructor. @@ -1050,10 +1012,6 @@ Can invalidate iterators, but only if the insert causes the load factor to be gr Pointers and references to elements are never invalidated. The `template` overload only participates in overload resolution if `Hash::is_transparent` and `Pred::is_transparent` are valid member typedefs and neither `iterator` nor `const_iterator` are implicitly convertible from `K`. The library assumes that `Hash` is callable with both `K` and `Key` and that `Pred` is transparent. This enables heterogeneous lookup which avoids the cost of instantiating an instance of the `Key` type. - -If the compiler doesn't support variadic template arguments or rvalue references, this is emulated for up to `10` arguments, with no support for rvalue references or move semantics. - -Since existing `std::pair` implementations don't support `std::piecewise_construct` this emulates it, but using `boost::unordered::piecewise_construct`. -- --- @@ -1083,13 +1041,13 @@ Notes:;; This function is similiar to xref:#unordered_map_emplace_hint[emplace_h ```c++ // first two overloads value_type(std::piecewise_construct, - std::forward_as_tuple(boost::forward(k)), - std::forward_as_tuple(boost::forward(args)...)) + std::forward_as_tuple(std::forward(k)), + std::forward_as_tuple(std::forward(args)...)) // third overload value_type(std::piecewise_construct, - std::forward_as_tuple(boost::forward(k)), - std::forward_as_tuple(boost::forward(args)...)) + std::forward_as_tuple(std::forward(k)), + std::forward_as_tuple(std::forward(args)...)) ``` instead of xref:#unordered_map_emplace_hint[emplace_hint] which simply forwards all arguments to ``value_type``'s constructor. @@ -1101,10 +1059,6 @@ Can invalidate iterators, but only if the insert causes the load factor to be gr Pointers and references to elements are never invalidated. The `template` overload only participates in overload resolution if `Hash::is_transparent` and `Pred::is_transparent` are valid member typedefs and neither `iterator` nor `const_iterator` are implicitly convertible from `K`. The library assumes that `Hash` is callable with both `K` and `Key` and that `Pred` is transparent. This enables heterogeneous lookup which avoids the cost of instantiating an instance of the `Key` type. - -If the compiler doesn't support variadic template arguments or rvalue references, this is emulated for up to `10` arguments, with no support for rvalue references or move semantics. - -Since existing `std::pair` implementations don't support `std::piecewise_construct` this emulates it, but using `boost::unordered::piecewise_construct`. -- --- @@ -1121,19 +1075,19 @@ template Inserts a new element into the container or updates an existing one by assigning to the contained value. -If there is an element with key `k`, then it is updated by assigning `boost::forward(obj)`. +If there is an element with key `k`, then it is updated by assigning `std::forward(obj)`. If there is no such element, it is added to the container as: ```c++ // first two overloads value_type(std::piecewise_construct, - std::forward_as_tuple(boost::forward(k)), - std::forward_as_tuple(boost::forward(obj))) + std::forward_as_tuple(std::forward(k)), + std::forward_as_tuple(std::forward(obj))) // third overload value_type(std::piecewise_construct, - std::forward_as_tuple(boost::forward(k)), - std::forward_as_tuple(boost::forward(obj))) + std::forward_as_tuple(std::forward(k)), + std::forward_as_tuple(std::forward(obj))) ``` [horizontal] @@ -1161,19 +1115,19 @@ template Inserts a new element into the container or updates an existing one by assigning to the contained value. -If there is an element with key `k`, then it is updated by assigning `boost::forward(obj)`. +If there is an element with key `k`, then it is updated by assigning `std::forward(obj)`. If there is no such element, it is added to the container as: ```c++ // first two overloads value_type(std::piecewise_construct, - std::forward_as_tuple(boost::forward(k)), - std::forward_as_tuple(boost::forward(obj))) + std::forward_as_tuple(std::forward(k)), + std::forward_as_tuple(std::forward(obj))) // third overload value_type(std::piecewise_construct, - std::forward_as_tuple(boost::forward(k)), - std::forward_as_tuple(boost::forward(obj))) + std::forward_as_tuple(std::forward(k)), + std::forward_as_tuple(std::forward(obj))) ``` `hint` is a suggestion to where the element should be inserted. @@ -1766,9 +1720,7 @@ template Return `true` if `x.size() == y.size()` and for every element in `x`, there is an element in `y` with the same key, with an equal value (using `operator==` to compare the value types). [horizontal] -Notes:;; The behavior of this function was changed to match the C++11 standard in Boost 1.48. + -+ -Behavior is undefined if the two containers don't have equivalent equality predicates. +Notes:;; Behavior is undefined if the two containers don't have equivalent equality predicates. --- @@ -1782,9 +1734,7 @@ template Return `false` if `x.size() == y.size()` and for every element in `x`, there is an element in `y` with the same key, with an equal value (using `operator==` to compare the value types). [horizontal] -Notes:;; The behavior of this function was changed to match the C++11 standard in Boost 1.48. + -+ -Behavior is undefined if the two containers don't have equivalent equality predicates. +Notes:;; Behavior is undefined if the two containers don't have equivalent equality predicates. === Swap ```c++ diff --git a/doc/unordered/unordered_multimap.adoc b/doc/unordered/unordered_multimap.adoc index 52b23d9a..6c50b857 100644 --- a/doc/unordered/unordered_multimap.adoc +++ b/doc/unordered/unordered_multimap.adoc @@ -26,12 +26,12 @@ namespace boost { using hasher = Hash; using key_equal = Pred; using allocator_type = Allocator; - using pointer = typename boost::allocator_traits::pointer; - using const_pointer = typename boost::allocator_traits::const_pointer; + using pointer = typename std::allocator_traits::pointer; + using const_pointer = typename std::allocator_traits::const_pointer; using reference = value_type&; using const_reference = const value_type&; - using size_type = _implementation-defined_; - using difference_type = _implementation-defined_; + using size_type = std::size_t; + using difference_type = std::ptrdiff_t; using iterator = _implementation-defined_; using const_iterator = _implementation-defined_; @@ -283,6 +283,7 @@ namespace boost { |_Allocator_ |An allocator whose value type is the same as the container's value type. +Allocators using https://en.cppreference.com/w/cpp/named_req/Allocator#Fancy_pointers[fancy pointers] are supported. |=== @@ -299,47 +300,6 @@ a Boost.Serialization archive with a version of Boost prior to Boost 1.84. === Typedefs -[source,c++,subs=+quotes] ----- -typedef typename allocator_type::pointer pointer; ----- - -`value_type*` if `allocator_type::pointer` is not defined. - ---- - -[source,c++,subs=+quotes] ----- -typedef typename allocator_type::const_pointer const_pointer; ----- - -`boost::pointer_to_other::type` if `allocator_type::const_pointer` is not defined. - - ---- - -[source,c++,subs=+quotes] ----- -typedef _implementation-defined_ size_type; ----- - -An unsigned integral type. - -`size_type` can represent any non-negative value of `difference_type`. - ---- - -[source,c++,subs=+quotes] ----- -typedef _implementation-defined_ difference_type; ----- - -A signed integral type. - -Is identical to the difference type of `iterator` and `const_iterator`. - ---- - [source,c++,subs=+quotes] ---- typedef _implementation-defined_ iterator; @@ -471,10 +431,7 @@ The move constructor. [horizontal] Notes:;; This is implemented using Boost.Move. -Requires:;; `value_type` is move-constructible. + -+ -On compilers without rvalue reference support the emulation does not support moving without calling `boost::move` if `value_type` is not copyable. -So, for example, you can't return the container from a function. +Requires:;; `value_type` is move-constructible. --- @@ -673,7 +630,6 @@ The move assignment operator. If `Alloc::propagate_on_container_move_assignment` exists and `Alloc::propagate_on_container_move_assignment::value` is `true`, the allocator is overwritten, if not the moved elements are created using the existing allocator. [horizontal] -Notes:;; On compilers without rvalue references, this is emulated using Boost.Move. Note that on some compilers the copy assignment operator may be used in some circumstances. Requires:;; `value_type` is move constructible. --- @@ -782,11 +738,7 @@ Returns:;; An iterator pointing to the inserted element. Throws:;; If an exception is thrown by an operation other than a call to `hasher` the function has no effect. Notes:;; Can invalidate iterators, but only if the insert causes the load factor to be greater to or equal to the maximum load factor. + + -Pointers and references to elements are never invalidated. + -+ -If the compiler doesn't support variadic template arguments or rvalue references, this is emulated for up to `10` arguments, with no support for rvalue references or move semantics. + -+ -Since existing `std::pair` implementations don't support `std::piecewise_construct` this emulates it, but using `boost::unordered::piecewise_construct`. +Pointers and references to elements are never invalidated. --- @@ -807,11 +759,7 @@ Notes:;; The standard is fairly vague on the meaning of the hint. But the only p + Can invalidate iterators, but only if the insert causes the load factor to be greater to or equal to the maximum load factor. + + -Pointers and references to elements are never invalidated. + -+ -If the compiler doesn't support variadic template arguments or rvalue references, this is emulated for up to 10 arguments, with no support for rvalue references or move semantics. + -+ -Since existing `std::pair` implementations don't support `std::piecewise_construct` this emulates it, but using `boost::unordered::piecewise_construct`. +Pointers and references to elements are never invalidated. --- @@ -1493,9 +1441,7 @@ template Return `true` if `x.size() == y.size()` and for every equivalent key group in `x`, there is a group in `y` for the same key, which is a permutation (using `operator==` to compare the value types). [horizontal] -Notes:;; The behavior of this function was changed to match the C++11 standard in Boost 1.48. + -+ -Behavior is undefined if the two containers don't have equivalent equality predicates. +Notes:;; Behavior is undefined if the two containers don't have equivalent equality predicates. --- @@ -1509,9 +1455,7 @@ template Return `false` if `x.size() == y.size()` and for every equivalent key group in `x`, there is a group in `y` for the same key, which is a permutation (using `operator==` to compare the value types). [horizontal] -Notes:;; The behavior of this function was changed to match the C++11 standard in Boost 1.48. + -+ -Behavior is undefined if the two containers don't have equivalent equality predicates. +Notes:;; Behavior is undefined if the two containers don't have equivalent equality predicates. --- diff --git a/doc/unordered/unordered_multiset.adoc b/doc/unordered/unordered_multiset.adoc index a1ee1a57..7fd265bc 100644 --- a/doc/unordered/unordered_multiset.adoc +++ b/doc/unordered/unordered_multiset.adoc @@ -24,12 +24,12 @@ namespace boost { using hasher = Hash; using key_equal = Pred; using allocator_type = Allocator; - using pointer = typename boost::allocator_traits::pointer; - using const_pointer = typename boost::allocator_traits::const_pointer; + using pointer = typename std::allocator_traits::pointer; + using const_pointer = typename std::allocator_traits::const_pointer; using reference = value_type&; using const_reference = const value_type&; - using size_type = _implementation-defined_; - using difference_type = _implementation-defined_; + using size_type = std::size_t; + using difference_type = std::ptrdiff_t; using iterator = _implementation-defined_; using const_iterator = _implementation-defined_; @@ -271,6 +271,7 @@ namespace boost { |_Allocator_ |An allocator whose value type is the same as the container's value type. +Allocators using https://en.cppreference.com/w/cpp/named_req/Allocator#Fancy_pointers[fancy pointers] are supported. |=== @@ -287,46 +288,6 @@ a Boost.Serialization archive with a version of Boost prior to Boost 1.84. === Typedefs -[source,c++,subs=+quotes] ----- -typedef typename allocator_type::pointer pointer; ----- - -`value_type*` if `allocator_type::pointer` is not defined. - ---- - -[source,c++,subs=+quotes] ----- -typedef typename allocator_type::const_pointer const_pointer; ----- - -`boost::pointer_to_other::type` if `allocator_type::const_pointer` is not defined. - ---- - -[source,c++,subs=+quotes] ----- -typedef _implementation-defined_ size_type; ----- - -An unsigned integral type. - -`size_type` can represent any non-negative value of `difference_type`. - ---- - -[source,c++,subs=+quotes] ----- -typedef _implementation-defined_ difference_type; ----- - -A signed integral type. - -Is identical to the difference type of `iterator` and `const_iterator`. - ---- - [source,c++,subs=+quotes] ---- typedef _implementation-defined_ iterator; @@ -458,10 +419,7 @@ The move constructor. [horizontal] Notes:;; This is implemented using Boost.Move. -Requires:;; `value_type` is move-constructible. + -+ -On compilers without rvalue reference support the emulation does not support moving without calling `boost::move` if `value_type` is not copyable. -So, for example, you can't return the container from a function. +Requires:;; `value_type` is move-constructible. --- @@ -661,7 +619,6 @@ The move assignment operator. If `Alloc::propagate_on_container_move_assignment` exists and `Alloc::propagate_on_container_move_assignment::value` is `true`, the allocator is overwritten, if not the moved elements are created using the existing allocator. [horizontal] -Notes:;; On compilers without rvalue references, this is emulated using Boost.Move. Note that on some compilers the copy assignment operator may be used in some circumstances. Requires:;; `value_type` is move constructible. --- @@ -772,11 +729,7 @@ Returns:;; An iterator pointing to the inserted element. Throws:;; If an exception is thrown by an operation other than a call to `hasher` the function has no effect. Notes:;; Can invalidate iterators, but only if the insert causes the load factor to be greater to or equal to the maximum load factor. + + -Pointers and references to elements are never invalidated. + -+ -If the compiler doesn't support variadic template arguments or rvalue references, this is emulated for up to `10` arguments, with no support for rvalue references or move semantics. + -+ -Since existing `std::pair` implementations don't support `std::piecewise_construct` this emulates it, but using `boost::unordered::piecewise_construct`. +Pointers and references to elements are never invalidated. --- @@ -797,11 +750,7 @@ Notes:;; The standard is fairly vague on the meaning of the hint. But the only p + Can invalidate iterators, but only if the insert causes the load factor to be greater to or equal to the maximum load factor. + + -Pointers and references to elements are never invalidated. + -+ -If the compiler doesn't support variadic template arguments or rvalue references, this is emulated for up to 10 arguments, with no support for rvalue references or move semantics. + -+ -Since existing `std::pair` implementations don't support `std::piecewise_construct` this emulates it, but using `boost::unordered::piecewise_construct`. +Pointers and references to elements are never invalidated. --- @@ -1424,9 +1373,7 @@ template Return `true` if `x.size() == y.size()` and for every element in `x`, there is an element in `y` with the same key, with an equal value (using `operator==` to compare the value types). [horizontal] -Notes:;; The behavior of this function was changed to match the C++11 standard in Boost 1.48. + -+ -Behavior is undefined if the two containers don't have equivalent equality predicates. +Notes:;; Behavior is undefined if the two containers don't have equivalent equality predicates. --- @@ -1440,9 +1387,7 @@ template Return `false` if `x.size() == y.size()` and for every element in `x`, there is an element in `y` with the same key, with an equal value (using `operator==` to compare the value types). [horizontal] -Notes:;; The behavior of this function was changed to match the C++11 standard in Boost 1.48. + -+ -Behavior is undefined if the two containers don't have equivalent equality predicates. +Notes:;; Behavior is undefined if the two containers don't have equivalent equality predicates. --- diff --git a/doc/unordered/unordered_node_map.adoc b/doc/unordered/unordered_node_map.adoc index 8e973e5a..d746261b 100644 --- a/doc/unordered/unordered_node_map.adoc +++ b/doc/unordered/unordered_node_map.adoc @@ -962,13 +962,13 @@ if there is an element with an equivalent key; otherwise, the construction is of ```c++ // first two overloads value_type(std::piecewise_construct, - std::forward_as_tuple(boost::forward(k)), - std::forward_as_tuple(boost::forward(args)...)) + std::forward_as_tuple(std::forward(k)), + std::forward_as_tuple(std::forward(args)...)) // third overload value_type(std::piecewise_construct, - std::forward_as_tuple(boost::forward(k)), - std::forward_as_tuple(boost::forward(args)...)) + std::forward_as_tuple(std::forward(k)), + std::forward_as_tuple(std::forward(args)...)) ``` unlike xref:#unordered_node_map_emplace[emplace], which simply forwards all arguments to ``value_type``'s constructor. @@ -1007,13 +1007,13 @@ if there is an element with an equivalent key; otherwise, the construction is of ```c++ // first two overloads value_type(std::piecewise_construct, - std::forward_as_tuple(boost::forward(k)), - std::forward_as_tuple(boost::forward(args)...)) + std::forward_as_tuple(std::forward(k)), + std::forward_as_tuple(std::forward(args)...)) // third overload value_type(std::piecewise_construct, - std::forward_as_tuple(boost::forward(k)), - std::forward_as_tuple(boost::forward(args)...)) + std::forward_as_tuple(std::forward(k)), + std::forward_as_tuple(std::forward(args)...)) ``` unlike xref:#unordered_node_map_emplace_hint[emplace_hint], which simply forwards all arguments to ``value_type``'s constructor. @@ -1038,19 +1038,19 @@ template Inserts a new element into the container or updates an existing one by assigning to the contained value. -If there is an element with key `k`, then it is updated by assigning `boost::forward(obj)`. +If there is an element with key `k`, then it is updated by assigning `std::forward(obj)`. If there is no such element, it is added to the container as: ```c++ // first two overloads value_type(std::piecewise_construct, - std::forward_as_tuple(boost::forward(k)), - std::forward_as_tuple(boost::forward(obj))) + std::forward_as_tuple(std::forward(k)), + std::forward_as_tuple(std::forward(obj))) // third overload value_type(std::piecewise_construct, - std::forward_as_tuple(boost::forward(k)), - std::forward_as_tuple(boost::forward(obj))) + std::forward_as_tuple(std::forward(k)), + std::forward_as_tuple(std::forward(obj))) ``` [horizontal] @@ -1076,19 +1076,19 @@ template Inserts a new element into the container or updates an existing one by assigning to the contained value. -If there is an element with key `k`, then it is updated by assigning `boost::forward(obj)`. +If there is an element with key `k`, then it is updated by assigning `std::forward(obj)`. If there is no such element, it is added to the container as: ```c++ // first two overloads value_type(std::piecewise_construct, - std::forward_as_tuple(boost::forward(k)), - std::forward_as_tuple(boost::forward(obj))) + std::forward_as_tuple(std::forward(k)), + std::forward_as_tuple(std::forward(obj))) // third overload value_type(std::piecewise_construct, - std::forward_as_tuple(boost::forward(k)), - std::forward_as_tuple(boost::forward(obj))) + std::forward_as_tuple(std::forward(k)), + std::forward_as_tuple(std::forward(obj))) ``` `hint` is a suggestion to where the element should be inserted. This implementation ignores it. diff --git a/doc/unordered/unordered_set.adoc b/doc/unordered/unordered_set.adoc index 4b50b21f..14b51eb9 100644 --- a/doc/unordered/unordered_set.adoc +++ b/doc/unordered/unordered_set.adoc @@ -24,12 +24,12 @@ namespace boost { using hasher = Hash; using key_equal = Pred; using allocator_type = Allocator; - using pointer = typename boost::allocator_traits::pointer; - using const_pointer = typename boost::allocator_traits::const_pointer; + using pointer = typename std::allocator_traits::pointer; + using const_pointer = typename std::allocator_traits::const_pointer; using reference = value_type&; using const_reference = const value_type&; - using size_type = _implementation-defined_; - using difference_type = _implementation-defined_; + using size_type = std::size_t; + using difference_type = std::ptrdiff_t; using iterator = _implementation-defined_; using const_iterator = _implementation-defined_; @@ -272,6 +272,7 @@ namespace boost { |_Allocator_ |An allocator whose value type is the same as the container's value type. +Allocators using https://en.cppreference.com/w/cpp/named_req/Allocator#Fancy_pointers[fancy pointers] are supported. |=== @@ -288,47 +289,6 @@ a Boost.Serialization archive with a version of Boost prior to Boost 1.84. === Typedefs -[source,c++,subs=+quotes] ----- -typedef typename allocator_type::pointer pointer; ----- - -`value_type*` if `allocator_type::pointer` is not defined. - ---- - -[source,c++,subs=+quotes] ----- -typedef typename allocator_type::const_pointer const_pointer; ----- - -`boost::pointer_to_other::type` if `allocator_type::const_pointer` is not defined. - - ---- - -[source,c++,subs=+quotes] ----- -typedef _implementation-defined_ size_type; ----- - -An unsigned integral type. - -`size_type` can represent any non-negative value of `difference_type`. - ---- - -[source,c++,subs=+quotes] ----- -typedef _implementation-defined_ difference_type; ----- - -A signed integral type. - -Is identical to the difference type of `iterator` and `const_iterator`. - ---- - [source,c++,subs=+quotes] ---- typedef _implementation-defined_ iterator; @@ -380,7 +340,8 @@ A const_local_iterator object can be used to iterate through a single bucket. typedef _implementation-defined_ node_type; ---- -See node_handle_set for details. +A class for holding extracted container elements, modelling +https://en.cppreference.com/w/cpp/container/node_handle[NodeHandle]. --- @@ -389,7 +350,20 @@ See node_handle_set for details. typedef _implementation-defined_ insert_return_type; ---- -Structure returned by inserting node_type. +A specialization of an internal class template: + +[source,c++,subs=+quotes] +---- +template +struct _insert_return_type_ // name is exposition only +{ + Iterator position; + bool inserted; + NodeType node; +}; +---- + +with `Iterator` = `iterator` and `NodeType` = `node_type`. --- @@ -469,10 +443,7 @@ The move constructor. [horizontal] Notes:;; This is implemented using Boost.Move. -Requires:;; `value_type` is move-constructible. + -+ -On compilers without rvalue reference support the emulation does not support moving without calling `boost::move` if `value_type` is not copyable. -So, for example, you can't return the container from a function. +Requires:;; `value_type` is move-constructible. --- @@ -672,7 +643,6 @@ The move assignment operator. If `Alloc::propagate_on_container_move_assignment` exists and `Alloc::propagate_on_container_move_assignment::value` is `true`, the allocator is overwritten, if not the moved elements are created using the existing allocator. [horizontal] -Notes:;; On compilers without rvalue references, this is emulated using Boost.Move. Note that on some compilers the copy assignment operator may be used in some circumstances. Requires:;; `value_type` is move constructible. --- @@ -785,11 +755,7 @@ If an insert took place, then the iterator points to the newly inserted element. Throws:;; If an exception is thrown by an operation other than a call to `hasher` the function has no effect. Notes:;; Can invalidate iterators, but only if the insert causes the load factor to be greater to or equal to the maximum load factor. + + -Pointers and references to elements are never invalidated. + -+ -If the compiler doesn't support variadic template arguments or rvalue references, this is emulated for up to `10` arguments, with no support for rvalue references or move semantics. + -+ -Since existing `std::pair` implementations don't support `std::piecewise_construct` this emulates it, but using `boost::unordered::piecewise_construct`. +Pointers and references to elements are never invalidated. --- @@ -810,11 +776,7 @@ Notes:;; The standard is fairly vague on the meaning of the hint. But the only p + Can invalidate iterators, but only if the insert causes the load factor to be greater to or equal to the maximum load factor. + + -Pointers and references to elements are never invalidated. + -+ -If the compiler doesn't support variadic template arguments or rvalue references, this is emulated for up to 10 arguments, with no support for rvalue references or move semantics. + -+ -Since existing `std::pair` implementations don't support `std::piecewise_construct` this emulates it, but using `boost::unordered::piecewise_construct`. +Pointers and references to elements are never invalidated. --- @@ -1489,9 +1451,7 @@ template Return `true` if `x.size() == y.size()` and for every element in `x`, there is an element in `y` with the same key, with an equal value (using `operator==` to compare the value types). [horizontal] -Notes:;; The behavior of this function was changed to match the C++11 standard in Boost 1.48. + -+ -Behavior is undefined if the two containers don't have equivalent equality predicates. +Notes:;; Behavior is undefined if the two containers don't have equivalent equality predicates. --- @@ -1505,9 +1465,7 @@ template Return `false` if `x.size() == y.size()` and for every element in `x`, there is an element in `y` with the same key, with an equal value (using `operator==` to compare the value types). [horizontal] -Notes:;; The behavior of this function was changed to match the C++11 standard in Boost 1.48. + -+ -Behavior is undefined if the two containers don't have equivalent equality predicates. +Notes:;; Behavior is undefined if the two containers don't have equivalent equality predicates. --- diff --git a/examples/case_insensitive.hpp b/examples/case_insensitive.hpp index 83a388d8..5818bff7 100644 --- a/examples/case_insensitive.hpp +++ b/examples/case_insensitive.hpp @@ -14,7 +14,7 @@ #define BOOST_HASH_EXAMPLES_CASE_INSENSITIVE_HEADER #include -#include +#include namespace hash_examples { diff --git a/include/boost/unordered/concurrent_flat_map.hpp b/include/boost/unordered/concurrent_flat_map.hpp index a06ec31f..8fb5ec2e 100644 --- a/include/boost/unordered/concurrent_flat_map.hpp +++ b/include/boost/unordered/concurrent_flat_map.hpp @@ -21,7 +21,6 @@ #include #include #include -#include #include @@ -65,9 +64,9 @@ namespace boost { using init_type = typename type_policy::init_type; using size_type = std::size_t; using difference_type = std::ptrdiff_t; - using hasher = typename boost::type_identity::type; - using key_equal = typename boost::type_identity::type; - using allocator_type = typename boost::type_identity::type; + using hasher = typename boost::unordered::detail::type_identity::type; + using key_equal = typename boost::unordered::detail::type_identity::type; + using allocator_type = typename boost::unordered::detail::type_identity::type; using reference = value_type&; using const_reference = value_type const&; using pointer = typename boost::allocator_pointer::type; @@ -757,8 +756,8 @@ namespace boost { Allocator>; template >, - class Pred = std::equal_to >, + class Hash = boost::hash >, + class Pred = std::equal_to >, class Allocator = std::allocator >, class = boost::enable_if_t >, class = boost::enable_if_t >, @@ -766,7 +765,7 @@ namespace boost { concurrent_flat_map(std::initializer_list >, std::size_t = boost::unordered::detail::foa::default_bucket_count, Hash = Hash(), Pred = Pred(), Allocator = Allocator()) - -> concurrent_flat_map, T, Hash, Pred, + -> concurrent_flat_map, T, Hash, Pred, Allocator>; template > > concurrent_flat_map(std::initializer_list >, std::size_t, - Allocator) -> concurrent_flat_map, T, - boost::hash >, - std::equal_to >, Allocator>; + Allocator) -> concurrent_flat_map, T, + boost::hash >, + std::equal_to >, Allocator>; template > > concurrent_flat_map(std::initializer_list >, Allocator) - -> concurrent_flat_map, T, - boost::hash >, - std::equal_to >, Allocator>; + -> concurrent_flat_map, T, + boost::hash >, + std::equal_to >, Allocator>; template >, class = boost::enable_if_t > > concurrent_flat_map(std::initializer_list >, std::size_t, - Hash, Allocator) -> concurrent_flat_map, T, - Hash, std::equal_to >, Allocator>; + Hash, Allocator) -> concurrent_flat_map, T, + Hash, std::equal_to >, Allocator>; #endif diff --git a/include/boost/unordered/concurrent_flat_set.hpp b/include/boost/unordered/concurrent_flat_set.hpp index 96ddd98b..fea086be 100644 --- a/include/boost/unordered/concurrent_flat_set.hpp +++ b/include/boost/unordered/concurrent_flat_set.hpp @@ -22,7 +22,6 @@ #include #include #include -#include #include @@ -60,9 +59,9 @@ namespace boost { using init_type = typename type_policy::init_type; using size_type = std::size_t; using difference_type = std::ptrdiff_t; - using hasher = typename boost::type_identity::type; - using key_equal = typename boost::type_identity::type; - using allocator_type = typename boost::type_identity::type; + using hasher = typename boost::unordered::detail::type_identity::type; + using key_equal = typename boost::unordered::detail::type_identity::type; + using allocator_type = typename boost::unordered::detail::type_identity::type; using reference = value_type&; using const_reference = value_type const&; using pointer = typename boost::allocator_pointer::type; diff --git a/include/boost/unordered/detail/archive_constructed.hpp b/include/boost/unordered/detail/archive_constructed.hpp index 8d01d5d4..341e2dbd 100644 --- a/include/boost/unordered/detail/archive_constructed.hpp +++ b/include/boost/unordered/detail/archive_constructed.hpp @@ -9,13 +9,12 @@ #ifndef BOOST_UNORDERED_DETAIL_ARCHIVE_CONSTRUCTED_HPP #define BOOST_UNORDERED_DETAIL_ARCHIVE_CONSTRUCTED_HPP +#include + #include -#include #include #include #include -#include -#include namespace boost{ namespace unordered{ @@ -29,7 +28,7 @@ struct archive_constructed:private noncopyable template archive_constructed(const char* name,Archive& ar,unsigned int version) { - core::load_construct_data_adl(ar,boost::addressof(get()),version); + core::load_construct_data_adl(ar,std::addressof(get()),version); BOOST_TRY{ ar>>core::make_nvp(name,get()); } @@ -54,7 +53,7 @@ struct archive_constructed:private noncopyable #pragma GCC diagnostic ignored "-Wstrict-aliasing" #endif - T& get(){return *reinterpret_cast(&space);} + T& get(){return *space.address();} #if defined(BOOST_UNORDERED_IGNORE_WSTRICT_ALIASING) #pragma GCC diagnostic pop @@ -62,7 +61,7 @@ struct archive_constructed:private noncopyable #endif private: - typename aligned_storage::value>::type space; + opt_storage space; }; } /* namespace detail */ diff --git a/include/boost/unordered/detail/fca.hpp b/include/boost/unordered/detail/fca.hpp index 2a4167dc..e7b60107 100644 --- a/include/boost/unordered/detail/fca.hpp +++ b/include/boost/unordered/detail/fca.hpp @@ -115,8 +115,9 @@ to normal separate chaining implementations. #include #include +#include -#include +#include #include #include #include @@ -124,10 +125,6 @@ to normal separate chaining implementations. #include #include #include -#include -#include -#include -#include #include @@ -144,19 +141,18 @@ namespace boost { node>::type node_pointer; node_pointer next; - typename boost::aligned_storage::value>::type buf; + opt_storage buf; - node() BOOST_NOEXCEPT : next(), buf() {} + node() noexcept : next(), buf() {} - value_type* value_ptr() BOOST_NOEXCEPT + value_type* value_ptr() noexcept { - return reinterpret_cast(buf.address()); + return buf.address(); } - value_type& value() BOOST_NOEXCEPT + value_type& value() noexcept { - return *reinterpret_cast(buf.address()); + return *buf.address(); } }; @@ -170,7 +166,7 @@ namespace boost { node_pointer next; - bucket() BOOST_NOEXCEPT : next() {} + bucket() noexcept : next() {} }; template struct bucket_group @@ -186,7 +182,7 @@ namespace boost { std::size_t bitmask; bucket_group_pointer next, prev; - bucket_group() BOOST_NOEXCEPT : buckets(), bitmask(0), next(), prev() {} + bucket_group() noexcept : buckets(), bitmask(0), next(), prev() {} ~bucket_group() {} }; @@ -224,33 +220,28 @@ namespace boost { public: grouped_bucket_iterator() : p(), pbg() {} - reference operator*() const BOOST_NOEXCEPT { return dereference(); } - pointer operator->() const BOOST_NOEXCEPT - { - return boost::to_address(p); - } + reference operator*() const noexcept { return dereference(); } + pointer operator->() const noexcept { return boost::to_address(p); } - grouped_bucket_iterator& operator++() BOOST_NOEXCEPT + grouped_bucket_iterator& operator++() noexcept { increment(); return *this; } - grouped_bucket_iterator operator++(int) BOOST_NOEXCEPT + grouped_bucket_iterator operator++(int) noexcept { grouped_bucket_iterator old = *this; increment(); return old; } - bool operator==( - grouped_bucket_iterator const& other) const BOOST_NOEXCEPT + bool operator==(grouped_bucket_iterator const& other) const noexcept { return equal(other); } - bool operator!=( - grouped_bucket_iterator const& other) const BOOST_NOEXCEPT + bool operator!=(grouped_bucket_iterator const& other) const noexcept { return !equal(other); } @@ -266,14 +257,14 @@ namespace boost { { } - Bucket& dereference() const BOOST_NOEXCEPT { return *p; } + Bucket& dereference() const noexcept { return *p; } - bool equal(const grouped_bucket_iterator& x) const BOOST_NOEXCEPT + bool equal(const grouped_bucket_iterator& x) const noexcept { return p == x.p; } - void increment() BOOST_NOEXCEPT + void increment() noexcept { std::size_t const offset = static_cast(p - pbg->buckets); @@ -290,7 +281,7 @@ namespace boost { } } - template + template friend void serialization_track( Archive& ar, grouped_bucket_iterator const& x) { @@ -301,8 +292,7 @@ namespace boost { friend class boost::serialization::access; - template - void serialize(Archive& ar,unsigned int) + template void serialize(Archive& ar, unsigned int) { // requires: not at end() position serialize_tracked_address(ar, p); @@ -326,20 +316,17 @@ namespace boost { grouped_local_bucket_iterator() : p() {} - reference operator*() const BOOST_NOEXCEPT { return dereference(); } + reference operator*() const noexcept { return dereference(); } - pointer operator->() const BOOST_NOEXCEPT - { - return boost::to_address(p); - } + pointer operator->() const noexcept { return boost::to_address(p); } - grouped_local_bucket_iterator& operator++() BOOST_NOEXCEPT + grouped_local_bucket_iterator& operator++() noexcept { increment(); return *this; } - grouped_local_bucket_iterator operator++(int) BOOST_NOEXCEPT + grouped_local_bucket_iterator operator++(int) noexcept { grouped_local_bucket_iterator old = *this; increment(); @@ -347,13 +334,13 @@ namespace boost { } bool operator==( - grouped_local_bucket_iterator const& other) const BOOST_NOEXCEPT + grouped_local_bucket_iterator const& other) const noexcept { return equal(other); } bool operator!=( - grouped_local_bucket_iterator const& other) const BOOST_NOEXCEPT + grouped_local_bucket_iterator const& other) const noexcept { return !equal(other); } @@ -366,14 +353,14 @@ namespace boost { grouped_local_bucket_iterator(node_pointer p_) : p(p_) {} - value_type& dereference() const BOOST_NOEXCEPT { return p->value(); } + value_type& dereference() const noexcept { return p->value(); } - bool equal(const grouped_local_bucket_iterator& x) const BOOST_NOEXCEPT + bool equal(const grouped_local_bucket_iterator& x) const noexcept { return p == x.p; } - void increment() BOOST_NOEXCEPT { p = p->next; } + void increment() noexcept { p = p->next; } node_pointer p; }; @@ -397,20 +384,17 @@ namespace boost { { } - reference operator*() const BOOST_NOEXCEPT { return dereference(); } + reference operator*() const noexcept { return dereference(); } - pointer operator->() const BOOST_NOEXCEPT - { - return boost::to_address(p); - } + pointer operator->() const noexcept { return boost::to_address(p); } - const_grouped_local_bucket_iterator& operator++() BOOST_NOEXCEPT + const_grouped_local_bucket_iterator& operator++() noexcept { increment(); return *this; } - const_grouped_local_bucket_iterator operator++(int) BOOST_NOEXCEPT + const_grouped_local_bucket_iterator operator++(int) noexcept { const_grouped_local_bucket_iterator old = *this; increment(); @@ -418,13 +402,13 @@ namespace boost { } bool operator==( - const_grouped_local_bucket_iterator const& other) const BOOST_NOEXCEPT + const_grouped_local_bucket_iterator const& other) const noexcept { return equal(other); } bool operator!=( - const_grouped_local_bucket_iterator const& other) const BOOST_NOEXCEPT + const_grouped_local_bucket_iterator const& other) const noexcept { return !equal(other); } @@ -435,23 +419,22 @@ namespace boost { const_grouped_local_bucket_iterator(node_pointer p_) : p(p_) {} - value_type& dereference() const BOOST_NOEXCEPT { return p->value(); } + value_type& dereference() const noexcept { return p->value(); } - bool equal( - const const_grouped_local_bucket_iterator& x) const BOOST_NOEXCEPT + bool equal(const const_grouped_local_bucket_iterator& x) const noexcept { return p == x.p; } - void increment() BOOST_NOEXCEPT { p = p->next; } + void increment() noexcept { p = p->next; } node_pointer p; }; template struct span { - T* begin() const BOOST_NOEXCEPT { return data; } - T* end() const BOOST_NOEXCEPT { return data + size; } + T* begin() const noexcept { return data; } + T* end() const noexcept { return data + size; } T* data; std::size_t size; @@ -466,8 +449,6 @@ namespace boost { typename boost::allocator_void_pointer::type> >:: type> { - BOOST_MOVABLE_BUT_NOT_COPYABLE(grouped_bucket_array) - typedef typename boost::allocator_value_type::type allocator_value_type; typedef @@ -532,8 +513,7 @@ namespace boost { grouped_bucket_array(size_type n, const Allocator& al) : empty_value(empty_init_t(), al), - size_index_(0), - size_(0), buckets(), groups() + size_index_(0), size_(0), buckets(), groups() { if (n == 0) { return; @@ -582,8 +562,10 @@ namespace boost { ~grouped_bucket_array() { this->deallocate(); } - grouped_bucket_array( - BOOST_RV_REF(grouped_bucket_array) other) BOOST_NOEXCEPT + grouped_bucket_array(grouped_bucket_array const&) = delete; + grouped_bucket_array& operator=(grouped_bucket_array const&) = delete; + + grouped_bucket_array(grouped_bucket_array&& other) noexcept : empty_value( empty_init_t(), other.get_node_allocator()), size_index_(other.size_index_), @@ -597,13 +579,12 @@ namespace boost { other.groups = group_pointer(); } - grouped_bucket_array& operator=( - BOOST_RV_REF(grouped_bucket_array) other) BOOST_NOEXCEPT + grouped_bucket_array& operator=(grouped_bucket_array&& other) noexcept { BOOST_ASSERT( this->get_node_allocator() == other.get_node_allocator()); - if (this == boost::addressof(other)) { + if (this == std::addressof(other)) { return *this; } @@ -622,7 +603,7 @@ namespace boost { return *this; } - void deallocate() BOOST_NOEXCEPT + void deallocate() noexcept { if (buckets) { bucket_allocator_type bucket_alloc = this->get_bucket_allocator(); @@ -651,7 +632,8 @@ namespace boost { bool b = boost::allocator_propagate_on_container_swap< allocator_type>::type::value; if (b) { - boost::core::invoke_swap(get_node_allocator(), other.get_node_allocator()); + boost::core::invoke_swap( + get_node_allocator(), other.get_node_allocator()); } } @@ -675,12 +657,9 @@ namespace boost { return this->get_node_allocator(); } - size_type buckets_len() const BOOST_NOEXCEPT { return size_ + 1; } + size_type buckets_len() const noexcept { return size_ + 1; } - size_type groups_len() const BOOST_NOEXCEPT - { - return size_ / group::N + 1; - } + size_type groups_len() const noexcept { return size_ / group::N + 1; } void reset_allocator(Allocator const& allocator_) { @@ -713,7 +692,7 @@ namespace boost { local_iterator end(size_type) const { return local_iterator(); } - size_type capacity() const BOOST_NOEXCEPT { return size_; } + size_type capacity() const noexcept { return size_; } iterator at(size_type n) const { @@ -747,7 +726,7 @@ namespace boost { size_ = 0; } - void append_bucket_group(iterator itb) BOOST_NOEXCEPT + void append_bucket_group(iterator itb) noexcept { std::size_t const N = group::N; @@ -777,7 +756,7 @@ namespace boost { } } - void insert_node(iterator itb, node_pointer p) BOOST_NOEXCEPT + void insert_node(iterator itb, node_pointer p) noexcept { this->append_bucket_group(itb); @@ -786,7 +765,7 @@ namespace boost { } void insert_node_hint( - iterator itb, node_pointer p, node_pointer hint) BOOST_NOEXCEPT + iterator itb, node_pointer p, node_pointer hint) noexcept { this->append_bucket_group(itb); @@ -799,24 +778,24 @@ namespace boost { } } - void extract_node(iterator itb, node_pointer p) BOOST_NOEXCEPT + void extract_node(iterator itb, node_pointer p) noexcept { - node_pointer* pp = boost::addressof(itb->next); + node_pointer* pp = std::addressof(itb->next); while ((*pp) != p) - pp = boost::addressof((*pp)->next); + pp = std::addressof((*pp)->next); *pp = p->next; if (!itb->next) unlink_bucket(itb); } - void extract_node_after(iterator itb, node_pointer* pp) BOOST_NOEXCEPT + void extract_node_after(iterator itb, node_pointer* pp) noexcept { *pp = (*pp)->next; if (!itb->next) unlink_bucket(itb); } - void unlink_empty_buckets() BOOST_NOEXCEPT + void unlink_empty_buckets() noexcept { std::size_t const N = group::N; @@ -864,7 +843,7 @@ namespace boost { } }; } // namespace detail - } // namespace unordered + } // namespace unordered } // namespace boost #endif // BOOST_UNORDERED_DETAIL_FCA_HPP diff --git a/include/boost/unordered/detail/foa/concurrent_table.hpp b/include/boost/unordered/detail/foa/concurrent_table.hpp index 11c7bb39..54341396 100644 --- a/include/boost/unordered/detail/foa/concurrent_table.hpp +++ b/include/boost/unordered/detail/foa/concurrent_table.hpp @@ -19,7 +19,6 @@ #include #include #include -#include #include #include #include @@ -28,6 +27,7 @@ #include #include #include +#include #include #include #include @@ -88,7 +88,7 @@ private: static constexpr std::size_t element_offset= (sizeof(T)+cacheline_size-1)/cacheline_size*cacheline_size; - BOOST_STATIC_ASSERT(alignof(T)<=cacheline_size); + BOOST_UNORDERED_STATIC_ASSERT(alignof(T)<=cacheline_size); T* data(std::size_t pos)noexcept { @@ -126,7 +126,7 @@ template class shared_lock { public: - shared_lock(Mutex& m_)noexcept:m{m_}{m.lock_shared();} + shared_lock(Mutex& m_)noexcept:m(m_){m.lock_shared();} ~shared_lock()noexcept{if(owns)m.unlock_shared();} /* not used but VS in pre-C++17 mode needs to see it for RVO */ @@ -148,7 +148,7 @@ template class lock_guard { public: - lock_guard(Mutex& m_)noexcept:m{m_}{m.lock();} + lock_guard(Mutex& m_)noexcept:m(m_){m.lock();} ~lock_guard()noexcept{m.unlock();} /* not used but VS in pre-C++17 mode needs to see it for RVO */ @@ -341,7 +341,7 @@ struct concurrent_table_arrays:table_arrays struct atomic_size_control { static constexpr auto atomic_size_t_size=sizeof(std::atomic); - BOOST_STATIC_ASSERT(atomic_size_t_size #include #include -#include -#include -#include -#include -#include #include #include +#include +#include #include #include #include @@ -133,10 +130,10 @@ #define BOOST_UNORDERED_THREAD_SANITIZER #endif -#define BOOST_UNORDERED_STATIC_ASSERT_HASH_PRED(Hash, Pred) \ - static_assert(boost::is_nothrow_swappable::value, \ - "Template parameter Hash is required to be nothrow Swappable."); \ - static_assert(boost::is_nothrow_swappable::value, \ +#define BOOST_UNORDERED_STATIC_ASSERT_HASH_PRED(Hash, Pred) \ + static_assert(boost::unordered::detail::is_nothrow_swappable::value, \ + "Template parameter Hash is required to be nothrow Swappable."); \ + static_assert(boost::unordered::detail::is_nothrow_swappable::value, \ "Template parameter Pred is required to be nothrow Swappable"); namespace boost{ @@ -311,7 +308,7 @@ struct group15 private: using slot_type=IntegralWrapper; - BOOST_STATIC_ASSERT(sizeof(slot_type)==1); + BOOST_UNORDERED_STATIC_ASSERT(sizeof(slot_type)==1); static constexpr unsigned char available_=0, sentinel_=1; @@ -514,7 +511,7 @@ struct group15 private: using slot_type=IntegralWrapper; - BOOST_STATIC_ASSERT(sizeof(slot_type)==1); + BOOST_UNORDERED_STATIC_ASSERT(sizeof(slot_type)==1); static constexpr unsigned char available_=0, sentinel_=1; @@ -707,7 +704,7 @@ struct group15 private: using word_type=IntegralWrapper; - BOOST_STATIC_ASSERT(sizeof(word_type)==8); + BOOST_UNORDERED_STATIC_ASSERT(sizeof(word_type)==8); static constexpr unsigned char available_=0, sentinel_=1; @@ -1045,15 +1042,7 @@ struct table_arrays initialize_groups( arrays.groups(),groups_size, - std::integral_constant< - bool, -#if BOOST_WORKAROUND(BOOST_LIBSTDCXX_VERSION,<50000) - /* std::is_trivially_constructible not provided */ - boost::has_trivial_constructor::value -#else - std::is_trivially_constructible::value -#endif - >{}); + is_trivially_default_constructible{}); arrays.groups()[groups_size-1].set_sentinel(); } @@ -2026,13 +2015,7 @@ private: x, std::integral_constant< bool, -#if BOOST_WORKAROUND(BOOST_LIBSTDCXX_VERSION,<50000) - /* std::is_trivially_copy_constructible not provided */ - boost::has_trivial_copy::value -#else - std::is_trivially_copy_constructible::value -#endif - &&( + is_trivially_copy_constructible::value&&( is_std_allocator::value|| !alloc_has_construct::value) >{} @@ -2074,15 +2057,7 @@ private: } void copy_groups_array_from(const table_core& x) { - copy_groups_array_from(x, std::integral_constant::value -#else - std::is_trivially_copy_assignable::value -#endif - >{} - ); + copy_groups_array_from(x,is_trivially_copy_assignable{}); } void copy_groups_array_from( diff --git a/include/boost/unordered/detail/foa/node_handle.hpp b/include/boost/unordered/detail/foa/node_handle.hpp index ddf34414..ae1600d8 100644 --- a/include/boost/unordered/detail/foa/node_handle.hpp +++ b/include/boost/unordered/detail/foa/node_handle.hpp @@ -9,6 +9,8 @@ #ifndef BOOST_UNORDERED_DETAIL_FOA_NODE_HANDLE_HPP #define BOOST_UNORDERED_DETAIL_FOA_NODE_HANDLE_HPP +#include + #include #include @@ -25,14 +27,6 @@ struct insert_return_type NodeType node; }; -template -union opt_storage { - BOOST_ATTRIBUTE_NO_UNIQUE_ADDRESS T t_; - - opt_storage(){} - ~opt_storage(){} -}; - template struct node_handle_base { diff --git a/include/boost/unordered/detail/foa/table.hpp b/include/boost/unordered/detail/foa/table.hpp index 78cfa3b1..7e14bc75 100644 --- a/include/boost/unordered/detail/foa/table.hpp +++ b/include/boost/unordered/detail/foa/table.hpp @@ -106,7 +106,7 @@ public: using element_type= typename std::conditional::type; - table_iterator()=default; + table_iterator():pc_{nullptr},p_{nullptr}{}; template::type* =nullptr> table_iterator(const table_iterator& x): pc_{x.pc_},p_{x.p_}{} @@ -133,10 +133,10 @@ private: template friend class table_erase_return_type; template friend class table; - table_iterator(group_type* pg,std::size_t n,const table_element_type* p): + table_iterator(group_type* pg,std::size_t n,const table_element_type* ptet): pc_{to_pointer( reinterpret_cast(const_cast(pg))+n)}, - p_{to_pointer(const_cast(p))} + p_{to_pointer(const_cast(ptet))} {} unsigned char* pc()const noexcept{return boost::to_address(pc_);} @@ -568,7 +568,7 @@ private: struct erase_on_exit { - erase_on_exit(table& x_,const_iterator it_):x{x_},it{it_}{} + erase_on_exit(table& x_,const_iterator it_):x(x_),it(it_){} ~erase_on_exit(){if(!rollback_)x.erase(it);} void rollback(){rollback_=true;} diff --git a/include/boost/unordered/detail/fwd.hpp b/include/boost/unordered/detail/fwd.hpp deleted file mode 100644 index 7fcb770e..00000000 --- a/include/boost/unordered/detail/fwd.hpp +++ /dev/null @@ -1,150 +0,0 @@ - -// Copyright (C) 2008-2016 Daniel James. -// Copyright (C) 2022 Christian Mazakas -// Distributed under the Boost Software License, Version 1.0. (See accompanying -// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) - -#ifndef BOOST_UNORDERED_FWD_HPP_INCLUDED -#define BOOST_UNORDERED_FWD_HPP_INCLUDED - -#include -#if defined(BOOST_HAS_PRAGMA_ONCE) -#pragma once -#endif - -#include - -#if defined(BOOST_UNORDERED_HAVE_PIECEWISE_CONSTRUCT) -// Already defined. -#elif defined(BOOST_LIBSTDCXX11) -// https://github.com/gcc-mirror/gcc/blob/gcc-4_6-branch/libstdc++-v3/include/bits/stl_pair.h#L70 -#if BOOST_LIBSTDCXX_VERSION > 40600 -#define BOOST_UNORDERED_HAVE_PIECEWISE_CONSTRUCT 1 -#endif -#elif BOOST_LIB_STD_CXX -// https://github.com/llvm-mirror/libcxx/blob/release_30/include/utility#L206 -#if BOOST_LIB_STD_CXX >= BOOST_VERSION_NUMBER(3, 0, 0) -#define BOOST_UNORDERED_HAVE_PIECEWISE_CONSTRUCT 1 -#endif -#elif defined(BOOST_LIB_STD_DINKUMWARE) -// Apparently C++11 standard supported in Visual Studio 2012 -// https://msdn.microsoft.com/en-us/library/hh567368.aspx#stl -// 2012 = VC+11 = BOOST_MSVC 1700 Hopefully! -// I have no idea when Dinkumware added it, probably a lot -// earlier than this check. -#if BOOST_LIB_STD_DINKUMWARE >= BOOST_VERSION_NUMBER(6, 10, 0) || \ - BOOST_COMP_MSVC >= BOOST_VERSION_NUMBER(17, 0, 0) -#define BOOST_UNORDERED_HAVE_PIECEWISE_CONSTRUCT 1 -#endif -#endif - -// Assume that an unknown library does not support piecewise construction. -#if !defined(BOOST_UNORDERED_HAVE_PIECEWISE_CONSTRUCT) -#define BOOST_UNORDERED_HAVE_PIECEWISE_CONSTRUCT 0 -#endif - -#if BOOST_UNORDERED_HAVE_PIECEWISE_CONSTRUCT -#include -#endif - -namespace boost { - namespace unordered { -#if BOOST_UNORDERED_HAVE_PIECEWISE_CONSTRUCT - using std::piecewise_construct_t; - using std::piecewise_construct; -#else - struct piecewise_construct_t - { - }; - const piecewise_construct_t piecewise_construct = piecewise_construct_t(); -#endif - } -} - -// BOOST_UNORDERED_EMPLACE_LIMIT = The maximum number of parameters in -// emplace (not including things like hints). Don't set it to a lower value, as -// that might break something. - -#if !defined BOOST_UNORDERED_EMPLACE_LIMIT -#define BOOST_UNORDERED_EMPLACE_LIMIT 10 -#endif - -//////////////////////////////////////////////////////////////////////////////// -// Configuration -// -// Unless documented elsewhere these configuration macros should be considered -// an implementation detail, I'll try not to break them, but you never know. - -// Use Sun C++ workarounds -// I'm not sure which versions of the compiler require these workarounds, so -// I'm just using them of everything older than the current test compilers -// (as of May 2017). - -#if !defined(BOOST_UNORDERED_SUN_WORKAROUNDS1) -#if BOOST_COMP_SUNPRO && BOOST_COMP_SUNPRO < BOOST_VERSION_NUMBER(5, 20, 0) -#define BOOST_UNORDERED_SUN_WORKAROUNDS1 1 -#else -#define BOOST_UNORDERED_SUN_WORKAROUNDS1 0 -#endif -#endif - -// BOOST_UNORDERED_TUPLE_ARGS -// -// Maximum number of std::tuple members to support, or 0 if std::tuple -// isn't avaiable. More are supported when full C++11 is used. - -// Already defined, so do nothing -#if defined(BOOST_UNORDERED_TUPLE_ARGS) - -// Assume if we have C++11 tuple it's properly variadic, -// and just use a max number of 10 arguments. -#elif !defined(BOOST_NO_CXX11_HDR_TUPLE) -#define BOOST_UNORDERED_TUPLE_ARGS 10 - -// Visual C++ has a decent enough tuple for piecewise construction, -// so use that if available, using _VARIADIC_MAX for the maximum -// number of parameters. Note that this comes after the check -// for a full C++11 tuple. -#elif defined(BOOST_MSVC) -#if !BOOST_UNORDERED_HAVE_PIECEWISE_CONSTRUCT -#define BOOST_UNORDERED_TUPLE_ARGS 0 -#elif defined(_VARIADIC_MAX) -#define BOOST_UNORDERED_TUPLE_ARGS _VARIADIC_MAX -#else -#define BOOST_UNORDERED_TUPLE_ARGS 5 -#endif - -// Assume that we don't have std::tuple -#else -#define BOOST_UNORDERED_TUPLE_ARGS 0 -#endif - -#if BOOST_UNORDERED_TUPLE_ARGS -#include -#endif - -// BOOST_UNORDERED_CXX11_CONSTRUCTION -// -// Use C++11 construction, requires variadic arguments, good construct support -// in allocator_traits and piecewise construction of std::pair -// Otherwise allocators aren't used for construction/destruction - -#if BOOST_UNORDERED_HAVE_PIECEWISE_CONSTRUCT && \ - !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) && BOOST_UNORDERED_TUPLE_ARGS -#if BOOST_COMP_SUNPRO && BOOST_LIB_STD_GNU -// Sun C++ std::pair piecewise construction doesn't seem to be exception safe. -// (At least for Sun C++ 12.5 using libstdc++). -#define BOOST_UNORDERED_CXX11_CONSTRUCTION 0 -#elif BOOST_COMP_GNUC && BOOST_COMP_GNUC < BOOST_VERSION_NUMBER(4, 7, 0) -// Piecewise construction in GCC 4.6 doesn't work for uncopyable types. -#define BOOST_UNORDERED_CXX11_CONSTRUCTION 0 -#elif !defined(BOOST_NO_CXX11_ALLOCATOR) -#define BOOST_UNORDERED_CXX11_CONSTRUCTION 1 -#endif -#endif - -#if !defined(BOOST_UNORDERED_CXX11_CONSTRUCTION) -#define BOOST_UNORDERED_CXX11_CONSTRUCTION 0 -#endif - -#endif diff --git a/include/boost/unordered/detail/implementation.hpp b/include/boost/unordered/detail/implementation.hpp index f353365c..2ca5cda6 100644 --- a/include/boost/unordered/detail/implementation.hpp +++ b/include/boost/unordered/detail/implementation.hpp @@ -1,7 +1,7 @@ // Copyright (C) 2003-2004 Jeremy B. Maitin-Shepard. // Copyright (C) 2005-2016 Daniel James // Copyright (C) 2022-2023 Joaquin M Lopez Munoz. -// Copyright (C) 2022 Christian Mazakas +// Copyright (C) 2022-2023 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) @@ -14,6 +14,12 @@ #pragma once #endif +#include +#include +#include +#include +#include + #include #include #include @@ -21,51 +27,23 @@ #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 -#include -#include -#include -#include -#include -#include + +#include #include #include +#include #include +#include #include -#if !defined(BOOST_NO_CXX11_HDR_TYPE_TRAITS) -#include -#endif - -#if BOOST_UNORDERED_CXX11_CONSTRUCTION -#include -#include -#endif +namespace boost { + namespace tuples { + struct null_type; + } +} // namespace boost // BOOST_UNORDERED_SUPPRESS_DEPRECATED // @@ -100,6 +78,10 @@ namespace boost { namespace unordered { + + using std::piecewise_construct; + using std::piecewise_construct_t; + namespace detail { template struct table; @@ -125,33 +107,33 @@ namespace boost { template inline void ignore_unused_variable_warning(T const&) { } - } + } // namespace func ////////////////////////////////////////////////////////////////////////// // iterator SFINAE template - struct is_forward : boost::is_base_of::iterator_category> { }; template struct enable_if_forward - : boost::enable_if_c::value, - ReturnType> + : std::enable_if::value, + ReturnType> { }; template struct disable_if_forward - : boost::disable_if_c::value, - ReturnType> + : std::enable_if::value, + ReturnType> { }; - } - } -} + } // namespace detail + } // namespace unordered +} // namespace boost namespace boost { namespace unordered { @@ -169,7 +151,8 @@ namespace boost { template inline typename boost::unordered::detail::disable_if_forward::type insert_size(I, I) + std::size_t>::type + insert_size(I, I) { return 1; } @@ -193,7 +176,7 @@ namespace boost { { } compressed_base(T& x, move_tag) - : empty_value(boost::empty_init_t(), boost::move(x)) + : empty_value(boost::empty_init_t(), std::move(x)) { } @@ -211,8 +194,8 @@ namespace boost { template struct compressed - : private boost::unordered::detail::generate_base::type, - private boost::unordered::detail::generate_base::type + : private boost::unordered::detail::generate_base::type, + private boost::unordered::detail::generate_base::type { typedef typename generate_base::type base1; typedef typename generate_base::type base2; @@ -254,8 +237,8 @@ namespace boost { void move_assign(compressed& x) { - first() = boost::move(x.first()); - second() = boost::move(x.second()); + first() = std::move(x.first()); + second() = std::move(x.second()); } void swap(compressed& x) @@ -298,37 +281,8 @@ namespace boost { ////////////////////////////////////////////////////////////////////////// // Bits and pieces for implementing traits - template - typename boost::add_lvalue_reference::type make(); - struct choice9 - { - typedef char (&type)[9]; - }; - struct choice8 : choice9 - { - typedef char (&type)[8]; - }; - struct choice7 : choice8 - { - typedef char (&type)[7]; - }; - struct choice6 : choice7 - { - typedef char (&type)[6]; - }; - struct choice5 : choice6 - { - typedef char (&type)[5]; - }; - struct choice4 : choice5 - { - typedef char (&type)[4]; - }; - struct choice3 : choice4 - { - typedef char (&type)[3]; - }; - struct choice2 : choice3 + template typename std::add_lvalue_reference::type make(); + struct choice2 { typedef char (&type)[2]; }; @@ -353,139 +307,9 @@ namespace boost { { template convert_from_anything(T const&); }; - } - } -} - -//////////////////////////////////////////////////////////////////////////// -// emplace_args -// -// Either forwarding variadic arguments, or storing the arguments in -// emplace_args##n - -#if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) - -#define BOOST_UNORDERED_EMPLACE_TEMPLATE typename... Args -#define BOOST_UNORDERED_EMPLACE_ARGS BOOST_FWD_REF(Args)... args -#define BOOST_UNORDERED_EMPLACE_FORWARD boost::forward(args)... - -#else - -#define BOOST_UNORDERED_EMPLACE_TEMPLATE typename Args -#define BOOST_UNORDERED_EMPLACE_ARGS Args const& args -#define BOOST_UNORDERED_EMPLACE_FORWARD args - -#if defined(BOOST_NO_CXX11_RVALUE_REFERENCES) - -#define BOOST_UNORDERED_EARGS_MEMBER(z, n, _) \ - typedef BOOST_FWD_REF(BOOST_PP_CAT(A, n)) BOOST_PP_CAT(Arg, n); \ - BOOST_PP_CAT(Arg, n) BOOST_PP_CAT(a, n); - -#else - -#define BOOST_UNORDERED_EARGS_MEMBER(z, n, _) \ - typedef typename boost::add_lvalue_reference::type \ - BOOST_PP_CAT(Arg, n); \ - BOOST_PP_CAT(Arg, n) BOOST_PP_CAT(a, n); - -#endif - -#define BOOST_UNORDERED_FWD_PARAM(z, n, a) \ - BOOST_FWD_REF(BOOST_PP_CAT(A, n)) BOOST_PP_CAT(a, n) - -#define BOOST_UNORDERED_CALL_FORWARD(z, i, a) \ - boost::forward(BOOST_PP_CAT(a, i)) - -#define BOOST_UNORDERED_EARGS_INIT(z, n, _) \ - BOOST_PP_CAT(a, n)(BOOST_PP_CAT(b, n)) - -#define BOOST_UNORDERED_EARGS(z, n, _) \ - template \ - struct BOOST_PP_CAT(emplace_args, n) \ - { \ - BOOST_PP_REPEAT_##z(n, BOOST_UNORDERED_EARGS_MEMBER, _) BOOST_PP_CAT( \ - emplace_args, n)(BOOST_PP_ENUM_BINARY_PARAMS_Z(z, n, Arg, b)) \ - : BOOST_PP_ENUM_##z(n, BOOST_UNORDERED_EARGS_INIT, _) \ - { \ - } \ - }; \ - \ - template \ - inline BOOST_PP_CAT(emplace_args, n) \ - create_emplace_args(BOOST_PP_ENUM_##z(n, BOOST_UNORDERED_FWD_PARAM, b)) \ - { \ - BOOST_PP_CAT(emplace_args, n) e( \ - BOOST_PP_ENUM_PARAMS_Z(z, n, b)); \ - return e; \ - } - -namespace boost { - namespace unordered { - namespace detail { - template struct emplace_args1 - { - BOOST_UNORDERED_EARGS_MEMBER(1, 0, _) - - explicit emplace_args1(Arg0 b0) : a0(b0) {} - }; - - template - inline emplace_args1 create_emplace_args(BOOST_FWD_REF(A0) b0) - { - emplace_args1 e(b0); - return e; - } - - template struct emplace_args2 - { - BOOST_UNORDERED_EARGS_MEMBER(1, 0, _) - BOOST_UNORDERED_EARGS_MEMBER(1, 1, _) - - emplace_args2(Arg0 b0, Arg1 b1) : a0(b0), a1(b1) {} - }; - - template - inline emplace_args2 create_emplace_args( - BOOST_FWD_REF(A0) b0, BOOST_FWD_REF(A1) b1) - { - emplace_args2 e(b0, b1); - return e; - } - - template struct emplace_args3 - { - BOOST_UNORDERED_EARGS_MEMBER(1, 0, _) - BOOST_UNORDERED_EARGS_MEMBER(1, 1, _) - BOOST_UNORDERED_EARGS_MEMBER(1, 2, _) - - emplace_args3(Arg0 b0, Arg1 b1, Arg2 b2) : a0(b0), a1(b1), a2(b2) {} - }; - - template - inline emplace_args3 create_emplace_args( - BOOST_FWD_REF(A0) b0, BOOST_FWD_REF(A1) b1, BOOST_FWD_REF(A2) b2) - { - emplace_args3 e(b0, b1, b2); - return e; - } - - BOOST_UNORDERED_EARGS(1, 4, _) - BOOST_UNORDERED_EARGS(1, 5, _) - BOOST_UNORDERED_EARGS(1, 6, _) - BOOST_UNORDERED_EARGS(1, 7, _) - BOOST_UNORDERED_EARGS(1, 8, _) - BOOST_UNORDERED_EARGS(1, 9, _) - BOOST_PP_REPEAT_FROM_TO(10, BOOST_PP_INC(BOOST_UNORDERED_EMPLACE_LIMIT), - BOOST_UNORDERED_EARGS, _) - } - } -} - -#undef BOOST_UNORDERED_DEFINE_EMPLACE_ARGS -#undef BOOST_UNORDERED_EARGS_MEMBER -#undef BOOST_UNORDERED_EARGS_INIT - -#endif + } // namespace detail + } // namespace unordered +} // namespace boost //////////////////////////////////////////////////////////////////////////////// // @@ -496,35 +320,8 @@ namespace boost { namespace unordered { namespace detail { -//////////////////////////////////////////////////////////////////////////// -// Integral_constrant, true_type, false_type -// -// Uses the standard versions if available. - -#if !defined(BOOST_NO_CXX11_HDR_TYPE_TRAITS) - - using std::integral_constant; - using std::true_type; - using std::false_type; - -#else - - template struct integral_constant - { - enum - { - value = Value - }; - }; - - typedef boost::unordered::detail::integral_constant true_type; - typedef boost::unordered::detail::integral_constant - false_type; - -#endif - -//////////////////////////////////////////////////////////////////////////// -// Explicitly call a destructor + //////////////////////////////////////////////////////////////////////////// + // Explicitly call a destructor #if defined(BOOST_MSVC) #pragma warning(push) @@ -533,7 +330,7 @@ namespace boost { namespace func { template inline void destroy(T* x) { x->~T(); } - } + } // namespace func #if defined(BOOST_MSVC) #pragma warning(pop) @@ -548,8 +345,7 @@ namespace boost { { typedef ValueType value_type; - typename boost::aligned_storage::value>::type data_; + opt_storage data_; value_base() : data_() {} @@ -573,8 +369,6 @@ namespace boost { template class optional { - BOOST_MOVABLE_BUT_NOT_COPYABLE(optional) - boost::unordered::detail::value_base value_; bool has_value_; @@ -589,16 +383,19 @@ namespace boost { void move(optional& x) { BOOST_ASSERT(!has_value_ && x.has_value_); - new (value_.value_ptr()) T(boost::move(x.value_.value())); + new (value_.value_ptr()) T(std::move(x.value_.value())); boost::unordered::detail::func::destroy(x.value_.value_ptr()); has_value_ = true; x.has_value_ = false; } public: - optional() BOOST_NOEXCEPT : has_value_(false) {} + optional() noexcept : has_value_(false) {} - optional(BOOST_RV_REF(optional) x) : has_value_(false) + optional(optional const&) = delete; + optional& operator=(optional const&) = delete; + + optional(optional&& x) : has_value_(false) { if (x.has_value_) { move(x); @@ -610,7 +407,7 @@ namespace boost { new (value_.value_ptr()) T(x); } - optional& operator=(BOOST_RV_REF(optional) x) + optional& operator=(optional&& x) { destroy(); if (x.has_value_) { @@ -650,9 +447,9 @@ namespace boost { friend void swap(optional& x, optional& y) { x.swap(y); } }; - } - } -} + } // namespace detail + } // namespace unordered +} // namespace boost //////////////////////////////////////////////////////////////////////////////// // @@ -672,209 +469,9 @@ namespace boost { struct rebind_wrap : boost::allocator_rebind { }; - } - } -} - -//////////////////////////////////////////////////////////////////////////// -// Functions used to construct nodes. Emulates variadic construction, -// piecewise construction etc. - -//////////////////////////////////////////////////////////////////////////// -// construct_value -// -// Only use allocator_traits::construct, allocator_traits::destroy when full -// C++11 support is available. - -#if BOOST_UNORDERED_CXX11_CONSTRUCTION - -#elif !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) - -namespace boost { - namespace unordered { - namespace detail { - namespace func { - template - inline void construct_value(T* address, BOOST_FWD_REF(Args)... args) - { - new ((void*)address) T(boost::forward(args)...); - } - } - } - } -} - -#else - -namespace boost { - namespace unordered { - namespace detail { - namespace func { - template inline void construct_value(T* address) - { - new ((void*)address) T(); - } - - template - inline void construct_value(T* address, BOOST_FWD_REF(A0) a0) - { - new ((void*)address) T(boost::forward(a0)); - } - } - } - } -} - -#endif - -//////////////////////////////////////////////////////////////////////////// -// Construct from tuple -// -// Used to emulate piecewise construction. - -#define BOOST_UNORDERED_CONSTRUCT_FROM_TUPLE(z, n, namespace_) \ - template \ - void construct_from_tuple(Alloc&, T* ptr, \ - namespace_::tuple const& x) \ - { \ - new ((void*)ptr) \ - T(BOOST_PP_ENUM_##z(n, BOOST_UNORDERED_GET_TUPLE_ARG, namespace_)); \ - } - -#define BOOST_UNORDERED_GET_TUPLE_ARG(z, n, namespace_) namespace_::get(x) - -// construct_from_tuple for boost::tuple -// The workaround for old Sun compilers comes later in the file. - -#if !BOOST_UNORDERED_SUN_WORKAROUNDS1 - -namespace boost { - namespace unordered { - namespace detail { - namespace func { - template - void construct_from_tuple(Alloc&, T* ptr, boost::tuple<>) - { - new ((void*)ptr) T(); - } - - BOOST_UNORDERED_CONSTRUCT_FROM_TUPLE(1, 1, boost) - BOOST_UNORDERED_CONSTRUCT_FROM_TUPLE(1, 2, boost) - BOOST_UNORDERED_CONSTRUCT_FROM_TUPLE(1, 3, boost) - BOOST_UNORDERED_CONSTRUCT_FROM_TUPLE(1, 4, boost) - BOOST_UNORDERED_CONSTRUCT_FROM_TUPLE(1, 5, boost) - BOOST_UNORDERED_CONSTRUCT_FROM_TUPLE(1, 6, boost) - BOOST_UNORDERED_CONSTRUCT_FROM_TUPLE(1, 7, boost) - BOOST_UNORDERED_CONSTRUCT_FROM_TUPLE(1, 8, boost) - BOOST_UNORDERED_CONSTRUCT_FROM_TUPLE(1, 9, boost) - BOOST_UNORDERED_CONSTRUCT_FROM_TUPLE(1, 10, boost) - } - } - } -} - -#endif - -// construct_from_tuple for std::tuple - -#if !BOOST_UNORDERED_CXX11_CONSTRUCTION && BOOST_UNORDERED_TUPLE_ARGS - -namespace boost { - namespace unordered { - namespace detail { - namespace func { - template - void construct_from_tuple(Alloc&, T* ptr, std::tuple<>) - { - new ((void*)ptr) T(); - } - - BOOST_UNORDERED_CONSTRUCT_FROM_TUPLE(1, 1, std) - BOOST_UNORDERED_CONSTRUCT_FROM_TUPLE(1, 2, std) - BOOST_UNORDERED_CONSTRUCT_FROM_TUPLE(1, 3, std) - BOOST_UNORDERED_CONSTRUCT_FROM_TUPLE(1, 4, std) - BOOST_UNORDERED_CONSTRUCT_FROM_TUPLE(1, 5, std) - -#if BOOST_UNORDERED_TUPLE_ARGS >= 6 - BOOST_PP_REPEAT_FROM_TO(6, BOOST_PP_INC(BOOST_UNORDERED_TUPLE_ARGS), - BOOST_UNORDERED_CONSTRUCT_FROM_TUPLE, std) -#endif - } - } - } -} - -#endif - -#undef BOOST_UNORDERED_CONSTRUCT_FROM_TUPLE -#undef BOOST_UNORDERED_GET_TUPLE_ARG - -// construct_from_tuple for boost::tuple on old versions of sunpro. -// -// Old versions of Sun C++ had problems with template overloads of -// boost::tuple, so to fix it I added a distinct type for each length to -// the overloads. That means there's no possible ambiguity between the -// different overloads, so that the compiler doesn't get confused - -#if BOOST_UNORDERED_SUN_WORKAROUNDS1 - -#define BOOST_UNORDERED_CONSTRUCT_FROM_TUPLE(z, n, namespace_) \ - template \ - void construct_from_tuple_impl(boost::unordered::detail::func::length, \ - Alloc&, T* ptr, \ - namespace_::tuple const& x) \ - { \ - new ((void*)ptr) \ - T(BOOST_PP_ENUM_##z(n, BOOST_UNORDERED_GET_TUPLE_ARG, namespace_)); \ - } - -#define BOOST_UNORDERED_GET_TUPLE_ARG(z, n, namespace_) namespace_::get(x) - -namespace boost { - namespace unordered { - namespace detail { - namespace func { - template struct length - { - }; - - template - void construct_from_tuple_impl( - boost::unordered::detail::func::length<0>, Alloc&, T* ptr, - boost::tuple<>) - { - new ((void*)ptr) T(); - } - - BOOST_UNORDERED_CONSTRUCT_FROM_TUPLE(1, 1, boost) - BOOST_UNORDERED_CONSTRUCT_FROM_TUPLE(1, 2, boost) - BOOST_UNORDERED_CONSTRUCT_FROM_TUPLE(1, 3, boost) - BOOST_UNORDERED_CONSTRUCT_FROM_TUPLE(1, 4, boost) - BOOST_UNORDERED_CONSTRUCT_FROM_TUPLE(1, 5, boost) - BOOST_UNORDERED_CONSTRUCT_FROM_TUPLE(1, 6, boost) - BOOST_UNORDERED_CONSTRUCT_FROM_TUPLE(1, 7, boost) - BOOST_UNORDERED_CONSTRUCT_FROM_TUPLE(1, 8, boost) - BOOST_UNORDERED_CONSTRUCT_FROM_TUPLE(1, 9, boost) - BOOST_UNORDERED_CONSTRUCT_FROM_TUPLE(1, 10, boost) - - template - void construct_from_tuple(Alloc& alloc, T* ptr, Tuple const& x) - { - construct_from_tuple_impl(boost::unordered::detail::func::length< - boost::tuples::length::value>(), - alloc, ptr, x); - } - } - } - } -} - -#undef BOOST_UNORDERED_CONSTRUCT_FROM_TUPLE -#undef BOOST_UNORDERED_GET_TUPLE_ARG - -#endif + } // namespace detail + } // namespace unordered +} // namespace boost namespace boost { namespace unordered { @@ -885,8 +482,7 @@ namespace boost { template struct use_piecewise { - static choice1::type test( - choice1, boost::unordered::piecewise_construct_t); + static choice1::type test(choice1, std::piecewise_construct_t); static choice2::type test(choice2, ...); @@ -897,29 +493,24 @@ namespace boost { }; }; -#if BOOST_UNORDERED_CXX11_CONSTRUCTION - //////////////////////////////////////////////////////////////////////// // Construct from variadic parameters template inline void construct_from_args( - Alloc& alloc, T* address, BOOST_FWD_REF(Args)... args) + Alloc& alloc, T* address, Args&&... args) { boost::allocator_construct( - alloc, address, boost::forward(args)...); + alloc, address, std::forward(args)...); } // For backwards compatibility, implement a special case for // piecewise_construct with boost::tuple - template struct detect_boost_tuple + template struct detect_std_tuple { - template - static choice1::type test(choice1, - boost::tuple const&); + template + static choice1::type test(choice1, std::tuple const&); static choice2::type test(choice2, ...); @@ -932,25 +523,27 @@ namespace boost { // Special case for piecewise_construct - template + template