Merge pull request #215 from cmazakas/cxx03_deprecation

cxx03 deprecation
This commit is contained in:
Christian Mazakas
2023-09-29 14:59:59 -07:00
committed by GitHub
77 changed files with 1670 additions and 4309 deletions

View File

@ -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;

View File

@ -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",
),

View File

@ -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'] }}

View File

@ -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

View File

@ -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 <<compliance_pairs,below>>), 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<pointer, const value_type>::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<std::string, std::complex> 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:

View File

@ -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<Key>(k)),
std::forward_as_tuple(boost::forward<Args>(args)...))
std::forward_as_tuple(std::forward<Key>(k)),
std::forward_as_tuple(std::forward<Args>(args)...))
// third overload
value_type(std::piecewise_construct,
std::forward_as_tuple(boost::forward<K>(k)),
std::forward_as_tuple(boost::forward<Args>(args)...))
std::forward_as_tuple(std::forward<K>(k)),
std::forward_as_tuple(std::forward<Args>(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<Key>(k)),
std::forward_as_tuple(boost::forward<Args>(args)...))
std::forward_as_tuple(std::forward<Key>(k)),
std::forward_as_tuple(std::forward<Args>(args)...))
// last two overloads
value_type(std::piecewise_construct,
std::forward_as_tuple(boost::forward<K>(k)),
std::forward_as_tuple(boost::forward<Args>(args)...))
std::forward_as_tuple(std::forward<K>(k)),
std::forward_as_tuple(std::forward<Args>(args)...))
```
Invalidates pointers and references to elements if a rehashing is issued.
@ -1121,19 +1121,19 @@ template<class K, class M> 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<M>(obj)`.
If there is an element with key `k`, then it is updated by assigning `std::forward<M>(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<Key>(k)),
std::forward_as_tuple(boost::forward<M>(obj)))
std::forward_as_tuple(std::forward<Key>(k)),
std::forward_as_tuple(std::forward<M>(obj)))
// third overload
value_type(std::piecewise_construct,
std::forward_as_tuple(boost::forward<K>(k)),
std::forward_as_tuple(boost::forward<M>(obj)))
std::forward_as_tuple(std::forward<K>(k)),
std::forward_as_tuple(std::forward<M>(obj)))
```
[horizontal]

View File

@ -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<Key>(k)),
std::forward_as_tuple(boost::forward<Args>(args)...))
std::forward_as_tuple(std::forward<Key>(k)),
std::forward_as_tuple(std::forward<Args>(args)...))
// third overload
value_type(std::piecewise_construct,
std::forward_as_tuple(boost::forward<K>(k)),
std::forward_as_tuple(boost::forward<Args>(args)...))
std::forward_as_tuple(std::forward<K>(k)),
std::forward_as_tuple(std::forward<Args>(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<Key>(k)),
std::forward_as_tuple(boost::forward<Args>(args)...))
std::forward_as_tuple(std::forward<Key>(k)),
std::forward_as_tuple(std::forward<Args>(args)...))
// third overload
value_type(std::piecewise_construct,
std::forward_as_tuple(boost::forward<K>(k)),
std::forward_as_tuple(boost::forward<Args>(args)...))
std::forward_as_tuple(std::forward<K>(k)),
std::forward_as_tuple(std::forward<Args>(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<class K, class M>
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<M>(obj)`.
If there is an element with key `k`, then it is updated by assigning `std::forward<M>(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<Key>(k)),
std::forward_as_tuple(boost::forward<M>(obj)))
std::forward_as_tuple(std::forward<Key>(k)),
std::forward_as_tuple(std::forward<M>(obj)))
// third overload
value_type(std::piecewise_construct,
std::forward_as_tuple(boost::forward<K>(k)),
std::forward_as_tuple(boost::forward<M>(obj)))
std::forward_as_tuple(std::forward<K>(k)),
std::forward_as_tuple(std::forward<M>(obj)))
```
[horizontal]
@ -1023,19 +1023,19 @@ template<class K, class M>
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<M>(obj)`.
If there is an element with key `k`, then it is updated by assigning `std::forward<M>(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<Key>(k)),
std::forward_as_tuple(boost::forward<M>(obj)))
std::forward_as_tuple(std::forward<Key>(k)),
std::forward_as_tuple(std::forward<M>(obj)))
// third overload
value_type(std::piecewise_construct,
std::forward_as_tuple(boost::forward<K>(k)),
std::forward_as_tuple(boost::forward<M>(obj)))
std::forward_as_tuple(std::forward<K>(k)),
std::forward_as_tuple(std::forward<M>(obj)))
```
`hint` is a suggestion to where the element should be inserted. This implementation ignores it.

View File

@ -26,12 +26,12 @@ namespace boost {
using hasher = Hash;
using key_equal = Pred;
using allocator_type = Allocator;
using pointer = typename boost::allocator_traits<Allocator>::pointer;
using const_pointer = typename boost::allocator_traits<Allocator>::const_pointer;
using pointer = typename std::allocator_traits<Allocator>::pointer;
using const_pointer = typename std::allocator_traits<Allocator>::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<pointer, value_type>::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<class Iterator, class NodeType>
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<Key>(k)),
std::forward_as_tuple(boost::forward<Args>(args)...))
std::forward_as_tuple(std::forward<Key>(k)),
std::forward_as_tuple(std::forward<Args>(args)...))
// third overload
value_type(std::piecewise_construct,
std::forward_as_tuple(boost::forward<K>(k)),
std::forward_as_tuple(boost::forward<Args>(args)...))
std::forward_as_tuple(std::forward<K>(k)),
std::forward_as_tuple(std::forward<Args>(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<class K, class\... Args>` 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<Key>(k)),
std::forward_as_tuple(boost::forward<Args>(args)...))
std::forward_as_tuple(std::forward<Key>(k)),
std::forward_as_tuple(std::forward<Args>(args)...))
// third overload
value_type(std::piecewise_construct,
std::forward_as_tuple(boost::forward<K>(k)),
std::forward_as_tuple(boost::forward<Args>(args)...))
std::forward_as_tuple(std::forward<K>(k)),
std::forward_as_tuple(std::forward<Args>(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<class K, class\... Args>` 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<class K, class M>
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<M>(obj)`.
If there is an element with key `k`, then it is updated by assigning `std::forward<M>(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<Key>(k)),
std::forward_as_tuple(boost::forward<M>(obj)))
std::forward_as_tuple(std::forward<Key>(k)),
std::forward_as_tuple(std::forward<M>(obj)))
// third overload
value_type(std::piecewise_construct,
std::forward_as_tuple(boost::forward<K>(k)),
std::forward_as_tuple(boost::forward<M>(obj)))
std::forward_as_tuple(std::forward<K>(k)),
std::forward_as_tuple(std::forward<M>(obj)))
```
[horizontal]
@ -1161,19 +1115,19 @@ template<class K, class M>
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<M>(obj)`.
If there is an element with key `k`, then it is updated by assigning `std::forward<M>(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<Key>(k)),
std::forward_as_tuple(boost::forward<M>(obj)))
std::forward_as_tuple(std::forward<Key>(k)),
std::forward_as_tuple(std::forward<M>(obj)))
// third overload
value_type(std::piecewise_construct,
std::forward_as_tuple(boost::forward<K>(k)),
std::forward_as_tuple(boost::forward<M>(obj)))
std::forward_as_tuple(std::forward<K>(k)),
std::forward_as_tuple(std::forward<M>(obj)))
```
`hint` is a suggestion to where the element should be inserted.
@ -1766,9 +1720,7 @@ template<class Key, class T, class Hash, class Pred, class Alloc>
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<class Key, class T, class Hash, class Pred, class Alloc>
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++

View File

@ -26,12 +26,12 @@ namespace boost {
using hasher = Hash;
using key_equal = Pred;
using allocator_type = Allocator;
using pointer = typename boost::allocator_traits<Allocator>::pointer;
using const_pointer = typename boost::allocator_traits<Allocator>::const_pointer;
using pointer = typename std::allocator_traits<Allocator>::pointer;
using const_pointer = typename std::allocator_traits<Allocator>::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<pointer, value_type>::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<class Key, class T, class Hash, class Pred, class Alloc>
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<class Key, class T, class Hash, class Pred, class Alloc>
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.
---

View File

@ -24,12 +24,12 @@ namespace boost {
using hasher = Hash;
using key_equal = Pred;
using allocator_type = Allocator;
using pointer = typename boost::allocator_traits<Allocator>::pointer;
using const_pointer = typename boost::allocator_traits<Allocator>::const_pointer;
using pointer = typename std::allocator_traits<Allocator>::pointer;
using const_pointer = typename std::allocator_traits<Allocator>::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<pointer, value_type>::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<class Key, class Hash, class Pred, class Alloc>
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<class Key, class Hash, class Pred, class Alloc>
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.
---

View File

@ -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<Key>(k)),
std::forward_as_tuple(boost::forward<Args>(args)...))
std::forward_as_tuple(std::forward<Key>(k)),
std::forward_as_tuple(std::forward<Args>(args)...))
// third overload
value_type(std::piecewise_construct,
std::forward_as_tuple(boost::forward<K>(k)),
std::forward_as_tuple(boost::forward<Args>(args)...))
std::forward_as_tuple(std::forward<K>(k)),
std::forward_as_tuple(std::forward<Args>(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<Key>(k)),
std::forward_as_tuple(boost::forward<Args>(args)...))
std::forward_as_tuple(std::forward<Key>(k)),
std::forward_as_tuple(std::forward<Args>(args)...))
// third overload
value_type(std::piecewise_construct,
std::forward_as_tuple(boost::forward<K>(k)),
std::forward_as_tuple(boost::forward<Args>(args)...))
std::forward_as_tuple(std::forward<K>(k)),
std::forward_as_tuple(std::forward<Args>(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<class K, class M>
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<M>(obj)`.
If there is an element with key `k`, then it is updated by assigning `std::forward<M>(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<Key>(k)),
std::forward_as_tuple(boost::forward<M>(obj)))
std::forward_as_tuple(std::forward<Key>(k)),
std::forward_as_tuple(std::forward<M>(obj)))
// third overload
value_type(std::piecewise_construct,
std::forward_as_tuple(boost::forward<K>(k)),
std::forward_as_tuple(boost::forward<M>(obj)))
std::forward_as_tuple(std::forward<K>(k)),
std::forward_as_tuple(std::forward<M>(obj)))
```
[horizontal]
@ -1076,19 +1076,19 @@ template<class K, class M>
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<M>(obj)`.
If there is an element with key `k`, then it is updated by assigning `std::forward<M>(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<Key>(k)),
std::forward_as_tuple(boost::forward<M>(obj)))
std::forward_as_tuple(std::forward<Key>(k)),
std::forward_as_tuple(std::forward<M>(obj)))
// third overload
value_type(std::piecewise_construct,
std::forward_as_tuple(boost::forward<K>(k)),
std::forward_as_tuple(boost::forward<M>(obj)))
std::forward_as_tuple(std::forward<K>(k)),
std::forward_as_tuple(std::forward<M>(obj)))
```
`hint` is a suggestion to where the element should be inserted. This implementation ignores it.

View File

@ -24,12 +24,12 @@ namespace boost {
using hasher = Hash;
using key_equal = Pred;
using allocator_type = Allocator;
using pointer = typename boost::allocator_traits<Allocator>::pointer;
using const_pointer = typename boost::allocator_traits<Allocator>::const_pointer;
using pointer = typename std::allocator_traits<Allocator>::pointer;
using const_pointer = typename std::allocator_traits<Allocator>::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<pointer, value_type>::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<class Iterator, class NodeType>
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<class Key, class Hash, class Pred, class Alloc>
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<class Key, class Hash, class Pred, class Alloc>
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.
---

View File

@ -14,7 +14,7 @@
#define BOOST_HASH_EXAMPLES_CASE_INSENSITIVE_HEADER
#include <boost/algorithm/string/predicate.hpp>
#include <boost/functional/hash.hpp>
#include <boost/container_hash/hash.hpp>
namespace hash_examples
{

View File

@ -21,7 +21,6 @@
#include <boost/container_hash/hash.hpp>
#include <boost/core/allocator_access.hpp>
#include <boost/core/serialization.hpp>
#include <boost/type_traits/type_identity.hpp>
#include <type_traits>
@ -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<Hash>::type;
using key_equal = typename boost::type_identity<Pred>::type;
using allocator_type = typename boost::type_identity<Allocator>::type;
using hasher = typename boost::unordered::detail::type_identity<Hash>::type;
using key_equal = typename boost::unordered::detail::type_identity<Pred>::type;
using allocator_type = typename boost::unordered::detail::type_identity<Allocator>::type;
using reference = value_type&;
using const_reference = value_type const&;
using pointer = typename boost::allocator_pointer<allocator_type>::type;
@ -757,8 +756,8 @@ namespace boost {
Allocator>;
template <class Key, class T,
class Hash = boost::hash<boost::remove_const_t<Key> >,
class Pred = std::equal_to<boost::remove_const_t<Key> >,
class Hash = boost::hash<std::remove_const_t<Key> >,
class Pred = std::equal_to<std::remove_const_t<Key> >,
class Allocator = std::allocator<std::pair<const Key, T> >,
class = boost::enable_if_t<detail::is_hash_v<Hash> >,
class = boost::enable_if_t<detail::is_pred_v<Pred> >,
@ -766,7 +765,7 @@ namespace boost {
concurrent_flat_map(std::initializer_list<std::pair<Key, T> >,
std::size_t = boost::unordered::detail::foa::default_bucket_count,
Hash = Hash(), Pred = Pred(), Allocator = Allocator())
-> concurrent_flat_map<boost::remove_const_t<Key>, T, Hash, Pred,
-> concurrent_flat_map<std::remove_const_t<Key>, T, Hash, Pred,
Allocator>;
template <class InputIterator, class Allocator,
@ -806,23 +805,23 @@ namespace boost {
template <class Key, class T, class Allocator,
class = boost::enable_if_t<detail::is_allocator_v<Allocator> > >
concurrent_flat_map(std::initializer_list<std::pair<Key, T> >, std::size_t,
Allocator) -> concurrent_flat_map<boost::remove_const_t<Key>, T,
boost::hash<boost::remove_const_t<Key> >,
std::equal_to<boost::remove_const_t<Key> >, Allocator>;
Allocator) -> concurrent_flat_map<std::remove_const_t<Key>, T,
boost::hash<std::remove_const_t<Key> >,
std::equal_to<std::remove_const_t<Key> >, Allocator>;
template <class Key, class T, class Allocator,
class = boost::enable_if_t<detail::is_allocator_v<Allocator> > >
concurrent_flat_map(std::initializer_list<std::pair<Key, T> >, Allocator)
-> concurrent_flat_map<boost::remove_const_t<Key>, T,
boost::hash<boost::remove_const_t<Key> >,
std::equal_to<boost::remove_const_t<Key> >, Allocator>;
-> concurrent_flat_map<std::remove_const_t<Key>, T,
boost::hash<std::remove_const_t<Key> >,
std::equal_to<std::remove_const_t<Key> >, Allocator>;
template <class Key, class T, class Hash, class Allocator,
class = boost::enable_if_t<detail::is_hash_v<Hash> >,
class = boost::enable_if_t<detail::is_allocator_v<Allocator> > >
concurrent_flat_map(std::initializer_list<std::pair<Key, T> >, std::size_t,
Hash, Allocator) -> concurrent_flat_map<boost::remove_const_t<Key>, T,
Hash, std::equal_to<boost::remove_const_t<Key> >, Allocator>;
Hash, Allocator) -> concurrent_flat_map<std::remove_const_t<Key>, T,
Hash, std::equal_to<std::remove_const_t<Key> >, Allocator>;
#endif

View File

@ -22,7 +22,6 @@
#include <boost/container_hash/hash.hpp>
#include <boost/core/allocator_access.hpp>
#include <boost/core/serialization.hpp>
#include <boost/type_traits/type_identity.hpp>
#include <utility>
@ -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<Hash>::type;
using key_equal = typename boost::type_identity<Pred>::type;
using allocator_type = typename boost::type_identity<Allocator>::type;
using hasher = typename boost::unordered::detail::type_identity<Hash>::type;
using key_equal = typename boost::unordered::detail::type_identity<Pred>::type;
using allocator_type = typename boost::unordered::detail::type_identity<Allocator>::type;
using reference = value_type&;
using const_reference = value_type const&;
using pointer = typename boost::allocator_pointer<allocator_type>::type;

View File

@ -9,13 +9,12 @@
#ifndef BOOST_UNORDERED_DETAIL_ARCHIVE_CONSTRUCTED_HPP
#define BOOST_UNORDERED_DETAIL_ARCHIVE_CONSTRUCTED_HPP
#include <boost/unordered/detail/opt_storage.hpp>
#include <boost/config.hpp>
#include <boost/core/addressof.hpp>
#include <boost/core/no_exceptions_support.hpp>
#include <boost/core/noncopyable.hpp>
#include <boost/core/serialization.hpp>
#include <boost/type_traits/aligned_storage.hpp>
#include <boost/type_traits/alignment_of.hpp>
namespace boost{
namespace unordered{
@ -29,7 +28,7 @@ struct archive_constructed:private noncopyable
template<class Archive>
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<T*>(&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<sizeof(T),alignment_of<T>::value>::type space;
opt_storage<T> space;
};
} /* namespace detail */

View File

@ -115,8 +115,9 @@ to normal separate chaining implementations.
#include <boost/unordered/detail/prime_fmod.hpp>
#include <boost/unordered/detail/serialize_tracked_address.hpp>
#include <boost/unordered/detail/opt_storage.hpp>
#include <boost/core/addressof.hpp>
#include <boost/assert.hpp>
#include <boost/core/allocator_access.hpp>
#include <boost/core/bit.hpp>
#include <boost/core/empty_value.hpp>
@ -124,10 +125,6 @@ to normal separate chaining implementations.
#include <boost/core/no_exceptions_support.hpp>
#include <boost/core/serialization.hpp>
#include <boost/cstdint.hpp>
#include <boost/move/core.hpp>
#include <boost/move/utility_core.hpp>
#include <boost/type_traits/aligned_storage.hpp>
#include <boost/type_traits/alignment_of.hpp>
#include <boost/config.hpp>
@ -144,19 +141,18 @@ namespace boost {
node>::type node_pointer;
node_pointer next;
typename boost::aligned_storage<sizeof(value_type),
boost::alignment_of<value_type>::value>::type buf;
opt_storage<value_type> buf;
node() BOOST_NOEXCEPT : next(), buf() {}
node() noexcept : next(), buf() {}
value_type* value_ptr() BOOST_NOEXCEPT
value_type* value_ptr() noexcept
{
return reinterpret_cast<value_type*>(buf.address());
return buf.address();
}
value_type& value() BOOST_NOEXCEPT
value_type& value() noexcept
{
return *reinterpret_cast<value_type*>(buf.address());
return *buf.address();
}
};
@ -170,7 +166,7 @@ namespace boost {
node_pointer next;
bucket() BOOST_NOEXCEPT : next() {}
bucket() noexcept : next() {}
};
template <class Bucket> 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<std::size_t>(p - pbg->buckets);
@ -290,7 +281,7 @@ namespace boost {
}
}
template<typename Archive>
template <typename Archive>
friend void serialization_track(
Archive& ar, grouped_bucket_iterator const& x)
{
@ -301,8 +292,7 @@ namespace boost {
friend class boost::serialization::access;
template<typename Archive>
void serialize(Archive& ar,unsigned int)
template <typename Archive> 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 <class T> 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<Allocator>::type> >::
type>
{
BOOST_MOVABLE_BUT_NOT_COPYABLE(grouped_bucket_array)
typedef typename boost::allocator_value_type<Allocator>::type
allocator_value_type;
typedef
@ -532,8 +513,7 @@ namespace boost {
grouped_bucket_array(size_type n, const Allocator& al)
: empty_value<node_allocator_type>(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<node_allocator_type>(
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

View File

@ -19,7 +19,6 @@
#include <boost/core/serialization.hpp>
#include <boost/cstdint.hpp>
#include <boost/mp11/tuple.hpp>
#include <boost/static_assert.hpp>
#include <boost/throw_exception.hpp>
#include <boost/unordered/detail/archive_constructed.hpp>
#include <boost/unordered/detail/bad_archive_exception.hpp>
@ -28,6 +27,7 @@
#include <boost/unordered/detail/foa/rw_spinlock.hpp>
#include <boost/unordered/detail/foa/tuple_rotate_right.hpp>
#include <boost/unordered/detail/serialization_version.hpp>
#include <boost/unordered/detail/static_assert.hpp>
#include <cstddef>
#include <functional>
#include <initializer_list>
@ -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<typename Mutex>
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<typename Mutex>
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<Value,Group,SizePolicy,Allocator>
struct atomic_size_control
{
static constexpr auto atomic_size_t_size=sizeof(std::atomic<std::size_t>);
BOOST_STATIC_ASSERT(atomic_size_t_size<cacheline_size);
BOOST_UNORDERED_STATIC_ASSERT(atomic_size_t_size<cacheline_size);
atomic_size_control(std::size_t ml_,std::size_t size_):
pad0_{},ml{ml_},pad1_{},size{size_}{}
@ -1029,7 +1029,7 @@ private:
erase_on_exit(
concurrent_table& x_,
group_type* pg_,unsigned int pos_,element_type* p_):
x{x_},pg{pg_},pos{pos_},p{p_}{}
x(x_),pg(pg_),pos(pos_),p(p_){}
~erase_on_exit(){if(!rollback_)x.super::erase(pg,pos,p);}
void rollback(){rollback_=true;}
@ -1283,7 +1283,7 @@ private:
struct reserve_size
{
reserve_size(concurrent_table& x_):x{x_}
reserve_size(concurrent_table& x_):x(x_)
{
size_=++x.size_ctrl.size;
}

View File

@ -22,13 +22,10 @@
#include <boost/core/pointer_traits.hpp>
#include <boost/cstdint.hpp>
#include <boost/predef.h>
#include <boost/static_assert.hpp>
#include <boost/type_traits/has_trivial_constructor.hpp>
#include <boost/type_traits/has_trivial_copy.hpp>
#include <boost/type_traits/has_trivial_assign.hpp>
#include <boost/type_traits/is_nothrow_swappable.hpp>
#include <boost/unordered/detail/narrow_cast.hpp>
#include <boost/unordered/detail/mulx.hpp>
#include <boost/unordered/detail/static_assert.hpp>
#include <boost/unordered/detail/type_traits.hpp>
#include <boost/unordered/hash_traits.hpp>
#include <climits>
#include <cmath>
@ -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<Hash>::value, \
"Template parameter Hash is required to be nothrow Swappable."); \
static_assert(boost::is_nothrow_swappable<Pred>::value, \
#define BOOST_UNORDERED_STATIC_ASSERT_HASH_PRED(Hash, Pred) \
static_assert(boost::unordered::detail::is_nothrow_swappable<Hash>::value, \
"Template parameter Hash is required to be nothrow Swappable."); \
static_assert(boost::unordered::detail::is_nothrow_swappable<Pred>::value, \
"Template parameter Pred is required to be nothrow Swappable");
namespace boost{
@ -311,7 +308,7 @@ struct group15
private:
using slot_type=IntegralWrapper<unsigned char>;
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<unsigned char>;
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<uint64_t>;
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<group_type>::value
#else
std::is_trivially_constructible<group_type>::value
#endif
>{});
is_trivially_default_constructible<group_type>{});
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<element_type>::value
#else
std::is_trivially_copy_constructible<element_type>::value
#endif
&&(
is_trivially_copy_constructible<element_type>::value&&(
is_std_allocator<Allocator>::value||
!alloc_has_construct<Allocator,value_type*,const value_type&>::value)
>{}
@ -2074,15 +2057,7 @@ private:
}
void copy_groups_array_from(const table_core& x) {
copy_groups_array_from(x, std::integral_constant<bool,
#if BOOST_WORKAROUND(BOOST_LIBSTDCXX_VERSION,<50000)
/* std::is_trivially_copy_assignable not provided */
boost::has_trivial_assign<group_type>::value
#else
std::is_trivially_copy_assignable<group_type>::value
#endif
>{}
);
copy_groups_array_from(x,is_trivially_copy_assignable<group_type>{});
}
void copy_groups_array_from(

View File

@ -9,6 +9,8 @@
#ifndef BOOST_UNORDERED_DETAIL_FOA_NODE_HANDLE_HPP
#define BOOST_UNORDERED_DETAIL_FOA_NODE_HANDLE_HPP
#include <boost/unordered/detail/opt_storage.hpp>
#include <boost/config.hpp>
#include <boost/core/allocator_access.hpp>
@ -25,14 +27,6 @@ struct insert_return_type
NodeType node;
};
template <class T>
union opt_storage {
BOOST_ATTRIBUTE_NO_UNIQUE_ADDRESS T t_;
opt_storage(){}
~opt_storage(){}
};
template <class TypePolicy,class Allocator>
struct node_handle_base
{

View File

@ -106,7 +106,7 @@ public:
using element_type=
typename std::conditional<Const,value_type const,value_type>::type;
table_iterator()=default;
table_iterator():pc_{nullptr},p_{nullptr}{};
template<bool Const2,typename std::enable_if<!Const2>::type* =nullptr>
table_iterator(const table_iterator<TypePolicy,GroupPtr,Const2>& x):
pc_{x.pc_},p_{x.p_}{}
@ -133,10 +133,10 @@ private:
template<typename> friend class table_erase_return_type;
template<typename,typename,typename,typename> 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<char_pointer>(
reinterpret_cast<unsigned char*>(const_cast<group_type*>(pg))+n)},
p_{to_pointer<table_element_pointer>(const_cast<table_element_type*>(p))}
p_{to_pointer<table_element_pointer>(const_cast<table_element_type*>(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;}

View File

@ -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 <boost/config.hpp>
#if defined(BOOST_HAS_PRAGMA_ONCE)
#pragma once
#endif
#include <boost/predef.h>
#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 <utility>
#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 <tuple>
#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

File diff suppressed because it is too large Load Diff

View File

@ -9,21 +9,21 @@
#ifndef BOOST_UNORDERED_DETAIL_NARROW_CAST_HPP
#define BOOST_UNORDERED_DETAIL_NARROW_CAST_HPP
#include <boost/unordered/detail/static_assert.hpp>
#include <boost/config.hpp>
#include <boost/static_assert.hpp>
#include <boost/type_traits/is_integral.hpp>
#include <boost/type_traits/make_unsigned.hpp>
#include <type_traits>
namespace boost{
namespace unordered{
namespace detail{
template<typename To,typename From>
BOOST_CONSTEXPR To narrow_cast(From x) BOOST_NOEXCEPT
constexpr To narrow_cast(From x) noexcept
{
BOOST_STATIC_ASSERT(boost::is_integral<From>::value);
BOOST_STATIC_ASSERT(boost::is_integral<To>::value);
BOOST_STATIC_ASSERT(sizeof(From)>=sizeof(To));
BOOST_UNORDERED_STATIC_ASSERT(std::is_integral<From>::value);
BOOST_UNORDERED_STATIC_ASSERT(std::is_integral<To>::value);
BOOST_UNORDERED_STATIC_ASSERT(sizeof(From)>=sizeof(To));
return static_cast<To>(
x
@ -32,7 +32,7 @@ BOOST_CONSTEXPR To narrow_cast(From x) BOOST_NOEXCEPT
/* Avoids VS's "Run-Time Check Failure #1 - A cast to a smaller data type
* has caused a loss of data."
*/
&static_cast<typename boost::make_unsigned<To>::type>(~static_cast<To>(0))
&static_cast<typename std::make_unsigned<To>::type>(~static_cast<To>(0))
#endif
);
}

View File

@ -0,0 +1,30 @@
// Copyright (C) 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)
#ifndef BOOST_UNORDERED_DETAIL_OPT_STORAGE_HPP
#define BOOST_UNORDERED_DETAIL_OPT_STORAGE_HPP
#include <boost/config.hpp>
#include <memory>
namespace boost {
namespace unordered {
namespace detail {
template <class T> union opt_storage
{
BOOST_ATTRIBUTE_NO_UNIQUE_ADDRESS T t_;
opt_storage() {}
~opt_storage() {}
T* address() noexcept { return std::addressof(t_); }
T const* address() const noexcept { return std::addressof(t_); }
};
} // namespace detail
} // namespace unordered
} // namespace boost
#endif // BOOST_UNORDERED_DETAIL_OPT_STORAGE_HPP

View File

@ -1,5 +1,5 @@
// Copyright (C) 2022 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)
@ -7,13 +7,10 @@
#ifndef BOOST_UNORDERED_DETAIL_PRIME_FMOD_HPP
#define BOOST_UNORDERED_DETAIL_PRIME_FMOD_HPP
#include <boost/cstdint.hpp>
#include <boost/preprocessor/seq/enum.hpp>
#include <boost/preprocessor/seq/for_each.hpp>
#include <boost/preprocessor/seq/size.hpp>
#include <boost/unordered/detail/narrow_cast.hpp>
#include <boost/config.hpp>
#include <boost/cstdint.hpp>
#include <climits>
#include <cstddef>
@ -37,21 +34,90 @@ namespace boost {
namespace detail {
template <class = void> struct prime_fmod_size
{
// Because we compile for C++03, we don't have access to any inline
// initialization for array data members so the definitions must exist
// out-of-line. To keep the library header-only, we introduce a dummy
// template parameter which permits the definition to be included in
// multiple TUs without conflict.
//
static std::size_t sizes[];
static std::size_t const sizes_len;
static std::size_t (*positions[])(std::size_t);
constexpr static std::size_t const sizes[] = {13ul, 29ul, 53ul, 97ul,
193ul, 389ul, 769ul, 1543ul, 3079ul, 6151ul, 12289ul, 24593ul,
49157ul, 98317ul, 196613ul, 393241ul, 786433ul, 1572869ul, 3145739ul,
6291469ul, 12582917ul, 25165843ul, 50331653ul, 100663319ul,
201326611ul, 402653189ul, 805306457ul, 1610612741ul, 3221225473ul,
#if !defined(BOOST_UNORDERED_FCA_HAS_64B_SIZE_T)
4294967291ul
#else
6442450939ull, 12884901893ull, 25769803751ull, 51539607551ull,
103079215111ull, 206158430209ull, 412316860441ull, 824633720831ull,
1649267441651ull
#endif
};
constexpr static std::size_t const sizes_len =
sizeof(sizes) / sizeof(sizes[0]);
#if defined(BOOST_UNORDERED_FCA_HAS_64B_SIZE_T)
static boost::uint64_t inv_sizes32[];
static std::size_t const inv_sizes32_len;
constexpr static boost::uint64_t const inv_sizes32[] = {
1418980313362273202ull, 636094623231363849ull, 348051774975651918ull,
190172619316593316ull, 95578984837873325ull, 47420935922132524ull,
23987963684927896ull, 11955116055547344ull, 5991147799191151ull,
2998982941588287ull, 1501077717772769ull, 750081082979285ull,
375261795343686ull, 187625172388393ull, 93822606204624ull,
46909513691883ull, 23456218233098ull, 11728086747027ull,
5864041509391ull, 2932024948977ull, 1466014921160ull, 733007198436ull,
366503839517ull, 183251896093ull, 91625960335ull, 45812983922ull,
22906489714ull, 11453246088ull, 5726623060ull};
constexpr static std::size_t const inv_sizes32_len =
sizeof(inv_sizes32) / sizeof(inv_sizes32[0]);
#endif /* defined(BOOST_UNORDERED_FCA_HAS_64B_SIZE_T) */
template <std::size_t SizeIndex, std::size_t Size = sizes[SizeIndex]>
static std::size_t position(std::size_t hash)
{
return hash % Size;
}
constexpr static std::size_t (*positions[])(std::size_t) = {
#if !defined(BOOST_UNORDERED_FCA_HAS_64B_SIZE_T)
position<0, sizes[0]>,
position<1, sizes[1]>,
position<2, sizes[2]>,
position<3, sizes[3]>,
position<4, sizes[4]>,
position<5, sizes[5]>,
position<6, sizes[6]>,
position<7, sizes[7]>,
position<8, sizes[8]>,
position<9, sizes[9]>,
position<10, sizes[10]>,
position<11, sizes[11]>,
position<12, sizes[12]>,
position<13, sizes[13]>,
position<14, sizes[14]>,
position<15, sizes[15]>,
position<16, sizes[16]>,
position<17, sizes[17]>,
position<18, sizes[18]>,
position<19, sizes[19]>,
position<20, sizes[20]>,
position<21, sizes[21]>,
position<22, sizes[22]>,
position<23, sizes[23]>,
position<24, sizes[24]>,
position<25, sizes[25]>,
position<26, sizes[26]>,
position<27, sizes[27]>,
position<28, sizes[28]>,
position<29, sizes[29]>,
#else
position<29, sizes[29]>,
position<30, sizes[30]>,
position<31, sizes[31]>,
position<32, sizes[32]>,
position<33, sizes[33]>,
position<34, sizes[34]>,
position<35, sizes[35]>,
position<36, sizes[36]>,
position<37, sizes[37]>,
#endif
};
static inline std::size_t size_index(std::size_t n)
{
std::size_t i = 0;
@ -68,11 +134,6 @@ namespace boost {
return sizes[size_index];
}
template <std::size_t Size> static std::size_t modulo(std::size_t hash)
{
return hash % Size;
}
#if defined(BOOST_UNORDERED_FCA_HAS_64B_SIZE_T)
// We emulate the techniques taken from:
// Faster Remainder by Direct Computation: Applications to Compilers and
@ -118,8 +179,8 @@ namespace boost {
#if defined(BOOST_UNORDERED_FCA_HAS_64B_SIZE_T)
std::size_t sizes_under_32bit = inv_sizes32_len;
if (BOOST_LIKELY(size_index < sizes_under_32bit)) {
return fast_modulo(
narrow_cast<boost::uint32_t>(hash) + narrow_cast<boost::uint32_t>(hash >> 32),
return fast_modulo(narrow_cast<boost::uint32_t>(hash) +
narrow_cast<boost::uint32_t>(hash >> 32),
inv_sizes32[size_index], boost::uint32_t(sizes[size_index]));
} else {
return positions[size_index - sizes_under_32bit](hash);
@ -130,134 +191,24 @@ namespace boost {
}
}; // prime_fmod_size
#define BOOST_UNORDERED_PRIME_FMOD_SIZES_32BIT_INCOMPLETE \
(13ul)(29ul)(53ul)(97ul)(193ul)(389ul)(769ul)(1543ul)(3079ul)(6151ul)( \
12289ul)(24593ul)(49157ul)(98317ul)(196613ul)(393241ul)(786433ul)( \
1572869ul)(3145739ul)(6291469ul)(12582917ul)(25165843ul)(50331653ul)( \
100663319ul)(201326611ul)(402653189ul)(805306457ul)(1610612741ul)( \
3221225473ul)
#if defined(BOOST_NO_CXX17_INLINE_VARIABLES)
// https://en.cppreference.com/w/cpp/language/static#Constant_static_members
// If a const non-inline (since C++17) static data member or a constexpr
// static data member (since C++11)(until C++17) is odr-used, a definition
// at namespace scope is still required, but it cannot have an
// initializer.
template <class T> constexpr std::size_t prime_fmod_size<T>::sizes[];
#if !defined(BOOST_UNORDERED_FCA_HAS_64B_SIZE_T)
#define BOOST_UNORDERED_PRIME_FMOD_SIZES_32BIT \
BOOST_UNORDERED_PRIME_FMOD_SIZES_32BIT_INCOMPLETE(4294967291ul)
#define BOOST_UNORDERED_PRIME_FMOD_SIZES_64BIT
#else
#define BOOST_UNORDERED_PRIME_FMOD_SIZES_32BIT \
BOOST_UNORDERED_PRIME_FMOD_SIZES_32BIT_INCOMPLETE
// The original sequence here is this:
// (6442450939ul)
// (12884901893ul)
// (25769803751ul)
// (51539607551ul)
// (103079215111ul)
// (206158430209ul)
// (412316860441ul)
// (824633720831ul)
// (1649267441651ul)
//
// but this causes problems on versions of mingw where the `long` type is 32
// bits, even for 64-bit targets. We work around this by replacing the literals
// with compile-time arithmetic, using bitshifts to reconstruct the number.
//
// clang-format off
#define BOOST_UNORDERED_PRIME_FMOD_SIZES_64BIT \
((boost::ulong_long_type(1ul) << 32) + boost::ulong_long_type(2147483643ul)) \
((boost::ulong_long_type(3ul) << 32) + boost::ulong_long_type(5ul)) \
((boost::ulong_long_type(5ul) << 32) + boost::ulong_long_type(4294967271ul)) \
((boost::ulong_long_type(11ul) << 32) + boost::ulong_long_type(4294967295ul)) \
((boost::ulong_long_type(24ul) << 32) + boost::ulong_long_type(7ul)) \
((boost::ulong_long_type(48ul) << 32) + boost::ulong_long_type(1ul)) \
((boost::ulong_long_type(96ul) << 32) + boost::ulong_long_type(25ul)) \
((boost::ulong_long_type(191ul) << 32) + boost::ulong_long_type(4294967295ul)) \
((boost::ulong_long_type(383ul) << 32) + boost::ulong_long_type(4294967283ul))
// clang-format on
#endif /* BOOST_UNORDERED_FCA_HAS_64B_SIZE_T */
#define BOOST_UNORDERED_PRIME_FMOD_SIZES \
BOOST_UNORDERED_PRIME_FMOD_SIZES_32BIT BOOST_UNORDERED_PRIME_FMOD_SIZES_64BIT
template <class T>
std::size_t prime_fmod_size<T>::sizes[] = {
BOOST_PP_SEQ_ENUM(BOOST_UNORDERED_PRIME_FMOD_SIZES)};
template <class T>
std::size_t const prime_fmod_size<T>::sizes_len = BOOST_PP_SEQ_SIZE(
BOOST_UNORDERED_PRIME_FMOD_SIZES);
// Similarly here, we have to re-express the integer initialization using
// arithmetic such that each literal can fit in a 32-bit value.
//
#if defined(BOOST_UNORDERED_FCA_HAS_64B_SIZE_T)
// clang-format off
template <class T>
boost::uint64_t prime_fmod_size<T>::inv_sizes32[] = {
(boost::ulong_long_type(330382099ul) << 32) + boost::ulong_long_type(2973438898ul) /* = 1418980313362273202 */,
(boost::ulong_long_type(148102320ul) << 32) + boost::ulong_long_type(2369637129ul) /* = 636094623231363849 */,
(boost::ulong_long_type(81037118ul) << 32) + boost::ulong_long_type(3403558990ul) /* = 348051774975651918 */,
(boost::ulong_long_type(44278013ul) << 32) + boost::ulong_long_type(1549730468ul) /* = 190172619316593316 */,
(boost::ulong_long_type(22253716ul) << 32) + boost::ulong_long_type(2403401389ul) /* = 95578984837873325 */,
(boost::ulong_long_type(11041047ul) << 32) + boost::ulong_long_type(143533612ul) /* = 47420935922132524 */,
(boost::ulong_long_type(5585133ul) << 32) + boost::ulong_long_type(106117528ul) /* = 23987963684927896 */,
(boost::ulong_long_type(2783517ul) << 32) + boost::ulong_long_type(1572687312ul) /* = 11955116055547344 */,
(boost::ulong_long_type(1394922ul) << 32) + boost::ulong_long_type(3428720239ul) /* = 5991147799191151 */,
(boost::ulong_long_type(698255ul) << 32) + boost::ulong_long_type(552319807ul) /* = 2998982941588287 */,
(boost::ulong_long_type(349496ul) << 32) + boost::ulong_long_type(3827689953ul) /* = 1501077717772769 */,
(boost::ulong_long_type(174641ul) << 32) + boost::ulong_long_type(3699438549ul) /* = 750081082979285 */,
(boost::ulong_long_type(87372ul) << 32) + boost::ulong_long_type(1912757574ul) /* = 375261795343686 */,
(boost::ulong_long_type(43684ul) << 32) + boost::ulong_long_type(3821029929ul) /* = 187625172388393 */,
(boost::ulong_long_type(21844ul) << 32) + boost::ulong_long_type(3340590800ul) /* = 93822606204624 */,
(boost::ulong_long_type(10921ul) << 32) + boost::ulong_long_type(4175852267ul) /* = 46909513691883 */,
(boost::ulong_long_type(5461ul) << 32) + boost::ulong_long_type(1401829642ul) /* = 23456218233098 */,
(boost::ulong_long_type(2730ul) << 32) + boost::ulong_long_type(2826028947ul) /* = 11728086747027 */,
(boost::ulong_long_type(1365ul) << 32) + boost::ulong_long_type(1411150351ul) /* = 5864041509391 */,
(boost::ulong_long_type(682ul) << 32) + boost::ulong_long_type(2857253105ul) /* = 2932024948977 */,
(boost::ulong_long_type(341ul) << 32) + boost::ulong_long_type(1431073224ul) /* = 1466014921160 */,
(boost::ulong_long_type(170ul) << 32) + boost::ulong_long_type(2862758116ul) /* = 733007198436 */,
(boost::ulong_long_type(85ul) << 32) + boost::ulong_long_type(1431619357ul) /* = 366503839517 */,
(boost::ulong_long_type(42ul) << 32) + boost::ulong_long_type(2863269661ul) /* = 183251896093 */,
(boost::ulong_long_type(21ul) << 32) + boost::ulong_long_type(1431647119ul) /* = 91625960335 */,
(boost::ulong_long_type(10ul) << 32) + boost::ulong_long_type(2863310962ul) /* = 45812983922 */,
(boost::ulong_long_type(5ul) << 32) + boost::ulong_long_type(1431653234ul) /* = 22906489714 */,
(boost::ulong_long_type(2ul) << 32) + boost::ulong_long_type(2863311496ul) /* = 11453246088 */,
(boost::ulong_long_type(1ul) << 32) + boost::ulong_long_type(1431655764ul) /* = 5726623060 */,
};
// clang-format on
template <class T>
std::size_t const
prime_fmod_size<T>::inv_sizes32_len = sizeof(inv_sizes32) /
sizeof(inv_sizes32[0]);
#endif /* defined(BOOST_UNORDERED_FCA_HAS_64B_SIZE_T) */
#define BOOST_UNORDERED_PRIME_FMOD_POSITIONS_ELEMENT(z, _, n) \
prime_fmod_size<T>::template modulo<n>,
template <class T>
std::size_t (*prime_fmod_size<T>::positions[])(std::size_t) = {
#if !defined(BOOST_UNORDERED_FCA_HAS_64B_SIZE_T)
BOOST_PP_SEQ_FOR_EACH(BOOST_UNORDERED_PRIME_FMOD_POSITIONS_ELEMENT, ~,
BOOST_UNORDERED_PRIME_FMOD_SIZES_32BIT)
#else
BOOST_PP_SEQ_FOR_EACH(BOOST_UNORDERED_PRIME_FMOD_POSITIONS_ELEMENT, ~,
BOOST_UNORDERED_PRIME_FMOD_SIZES_64BIT)
constexpr boost::uint64_t prime_fmod_size<T>::inv_sizes32[];
#endif
};
#undef BOOST_UNORDERED_PRIME_FMOD_POSITIONS_ELEMENT
#undef BOOST_UNORDERED_PRIME_FMOD_SIZES
#undef BOOST_UNORDERED_PRIME_FMOD_SIZES_64BIT
#undef BOOST_UNORDERED_PRIME_FMOD_SIZES_32BIT
#undef BOOST_UNORDERED_PRIME_FMOD_SIZES_32BIT_INCOMPLETE
template <class T>
constexpr std::size_t (*prime_fmod_size<T>::positions[])(std::size_t);
#endif
} // namespace detail
} // namespace unordered
} // namespace unordered
} // namespace boost
#endif // BOOST_UNORDERED_DETAIL_PRIME_FMOD_HPP

View File

@ -1,21 +0,0 @@
#ifndef BOOST_UNORDERED_DETAIL_REQUIRES_CXX11_HPP_INCLUDED
#define BOOST_UNORDERED_DETAIL_REQUIRES_CXX11_HPP_INCLUDED
// Copyright 2023 Peter Dimov
// Distributed under the Boost Software License, Version 1.0.
// https://www.boost.org/LICENSE_1_0.txt
#include <boost/config.hpp>
#include <boost/config/pragma_message.hpp>
#if defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) || \
defined(BOOST_NO_CXX11_RVALUE_REFERENCES) || \
defined(BOOST_NO_CXX11_DECLTYPE) || \
defined(BOOST_NO_CXX11_CONSTEXPR) || \
defined(BOOST_NO_CXX11_NOEXCEPT)
BOOST_PRAGMA_MESSAGE("C++03 support is deprecated in Boost.Unordered 1.82 and will be removed in Boost.Unordered 1.84.")
#endif
#endif // #ifndef BOOST_UNORDERED_DETAIL_REQUIRES_CXX11_HPP_INCLUDED

View File

@ -9,12 +9,8 @@
#ifndef BOOST_UNORDERED_DETAIL_SERIALIZE_CONTAINER_HPP
#define BOOST_UNORDERED_DETAIL_SERIALIZE_CONTAINER_HPP
#include <boost/core/addressof.hpp>
#include <boost/core/serialization.hpp>
#include <boost/move/move.hpp>
#include <boost/throw_exception.hpp>
#include <boost/type_traits/is_same.hpp>
#include <boost/type_traits/remove_const.hpp>
#include <boost/unordered/detail/archive_constructed.hpp>
#include <boost/unordered/detail/bad_archive_exception.hpp>
#include <boost/unordered/detail/serialization_version.hpp>
@ -66,7 +62,7 @@ template<typename Set> struct load_or_save_unordered_set<Set,true> /* save */
ar<<core::make_nvp("value_version",value_version);
for(const_iterator first=x.begin(),last=x.end();first!=last;++first){
core::save_construct_data_adl(ar,boost::addressof(*first),value_version);
core::save_construct_data_adl(ar,std::addressof(*first),value_version);
ar<<core::make_nvp("item",*first);
serialization_track(ar,first);
}
@ -94,10 +90,10 @@ template<typename Set> struct load_or_save_unordered_set<Set,false> /* load */
archive_constructed<value_type> value("item",ar,value_version);
std::pair<iterator,bool> p=adapt_insert_return_type(
x.insert(boost::move(value.get())));
x.insert(std::move(value.get())));
if(!p.second)throw_exception(bad_archive_exception());
ar.reset_object_address(
boost::addressof(*p.first),boost::addressof(value.get()));
std::addressof(*p.first),std::addressof(value.get()));
serialization_track(ar,p.first);
}
}
@ -110,9 +106,9 @@ template<typename Map> struct load_or_save_unordered_map<Map,true> /* save */
template<typename Archive>
void operator()(Archive& ar,const Map& x,unsigned int)const
{
typedef typename boost::remove_const<
typedef typename std::remove_const<
typename Map::key_type>::type key_type;
typedef typename boost::remove_const<
typedef typename std::remove_const<
typename Map::mapped_type>::type mapped_type;
typedef typename Map::const_iterator const_iterator;
@ -132,10 +128,10 @@ template<typename Map> struct load_or_save_unordered_map<Map,true> /* save */
*/
core::save_construct_data_adl(
ar,boost::addressof(first->first),key_version);
ar,std::addressof(first->first),key_version);
ar<<core::make_nvp("key",first->first);
core::save_construct_data_adl(
ar,boost::addressof(first->second),mapped_version);
ar,std::addressof(first->second),mapped_version);
ar<<core::make_nvp("mapped",first->second);
serialization_track(ar,first);
}
@ -147,9 +143,9 @@ template<typename Map> struct load_or_save_unordered_map<Map,false> /* load */
template<typename Archive>
void operator()(Archive& ar,Map& x,unsigned int)const
{
typedef typename boost::remove_const<
typedef typename std::remove_const<
typename Map::key_type>::type key_type;
typedef typename boost::remove_const<
typedef typename std::remove_const<
typename Map::mapped_type>::type mapped_type;
typedef typename Map::iterator iterator;
@ -169,12 +165,12 @@ template<typename Map> struct load_or_save_unordered_map<Map,false> /* load */
archive_constructed<mapped_type> mapped("mapped",ar,mapped_version);
std::pair<iterator,bool> p=adapt_insert_return_type(
x.emplace(boost::move(key.get()),boost::move(mapped.get())));
x.emplace(std::move(key.get()),std::move(mapped.get())));
if(!p.second)throw_exception(bad_archive_exception());
ar.reset_object_address(
boost::addressof(p.first->first),boost::addressof(key.get()));
std::addressof(p.first->first),std::addressof(key.get()));
ar.reset_object_address(
boost::addressof(p.first->second),boost::addressof(mapped.get()));
std::addressof(p.first->second),std::addressof(mapped.get()));
serialization_track(ar,p.first);
}
}
@ -196,7 +192,7 @@ void serialize_container(Archive& ar,Container& x,unsigned int version)
{
load_or_save_container<
Container,
boost::is_same<
std::is_same<
typename Container::key_type,typename Container::value_type>::value,
Archive::is_saving::value>()(ar,x,version);
}

View File

@ -9,12 +9,13 @@
#ifndef BOOST_UNORDERED_DETAIL_SERIALIZE_TRACKED_ADDRESS_HPP
#define BOOST_UNORDERED_DETAIL_SERIALIZE_TRACKED_ADDRESS_HPP
#include <boost/unordered/detail/bad_archive_exception.hpp>
#include <boost/core/pointer_traits.hpp>
#include <boost/core/serialization.hpp>
#include <boost/throw_exception.hpp>
#include <boost/type_traits/remove_const.hpp>
#include <boost/type_traits/integral_constant.hpp>
#include <boost/unordered/detail/bad_archive_exception.hpp>
#include <type_traits>
namespace boost{
namespace unordered{
@ -44,7 +45,7 @@ template<typename Archive,typename Ptr>
void track_address(Archive& ar,Ptr p)
{
typedef typename boost::pointer_traits<Ptr> ptr_traits;
typedef typename boost::remove_const<
typedef typename std::remove_const<
typename ptr_traits::element_type>::type element_type;
if(p){
@ -57,10 +58,10 @@ void track_address(Archive& ar,Ptr p)
}
template<typename Archive,typename Ptr>
void serialize_tracked_address(Archive& ar,Ptr& p,boost::true_type /* save */)
void serialize_tracked_address(Archive& ar,Ptr& p,std::true_type /* save */)
{
typedef typename boost::pointer_traits<Ptr> ptr_traits;
typedef typename boost::remove_const<
typedef typename std::remove_const<
typename ptr_traits::element_type>::type element_type;
typedef serialization_tracker<element_type> tracker;
@ -73,10 +74,10 @@ void serialize_tracked_address(Archive& ar,Ptr& p,boost::true_type /* save */)
}
template<typename Archive,typename Ptr>
void serialize_tracked_address(Archive& ar,Ptr& p,boost::false_type /* load */)
void serialize_tracked_address(Archive& ar,Ptr& p,std::false_type /* load */)
{
typedef typename boost::pointer_traits<Ptr> ptr_traits;
typedef typename boost::remove_const<
typedef typename std::remove_const<
typename ptr_traits::element_type>::type element_type;
typedef serialization_tracker<element_type> tracker;
@ -93,7 +94,7 @@ void serialize_tracked_address(Archive& ar,Ptr& p)
{
serialize_tracked_address(
ar,p,
boost::integral_constant<bool,Archive::is_saving::value>());
std::integral_constant<bool,Archive::is_saving::value>());
}
} /* namespace detail */

View File

@ -0,0 +1,16 @@
// Copyright 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)
#ifndef BOOST_UNORDERED_DETAIL_STATIC_ASSERT_HPP
#define BOOST_UNORDERED_DETAIL_STATIC_ASSERT_HPP
#include <boost/config.hpp>
#if defined(BOOST_HAS_PRAGMA_ONCE)
#pragma once
#endif
#define BOOST_UNORDERED_STATIC_ASSERT(...) \
static_assert(__VA_ARGS__, #__VA_ARGS__)
#endif // BOOST_UNORDERED_DETAIL_STATIC_ASSERT_HPP

View File

@ -1,4 +1,4 @@
// 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)
@ -11,20 +11,15 @@
#pragma once
#endif
#include <boost/type_traits/integral_constant.hpp>
#include <boost/type_traits/is_convertible.hpp>
#include <boost/type_traits/make_void.hpp>
#include <boost/type_traits/type_identity.hpp>
#include <boost/config/workaround.hpp>
#if !defined(BOOST_NO_CXX17_DEDUCTION_GUIDES)
#include <boost/type_traits/enable_if.hpp>
#include <boost/type_traits/is_integral.hpp>
#include <boost/type_traits/remove_const.hpp>
#include <iterator>
#include <utility>
#endif
#include <type_traits>
#include <utility>
// BOOST_UNORDERED_TEMPLATE_DEDUCTION_GUIDES
#if !defined(BOOST_UNORDERED_TEMPLATE_DEDUCTION_GUIDES)
@ -40,19 +35,96 @@
namespace boost {
namespace unordered {
namespace detail {
template <class T> struct type_identity
{
using type = T;
};
template <typename... Ts> struct make_void
{
typedef void type;
};
template <typename... Ts> using void_t = typename make_void<Ts...>::type;
#if BOOST_WORKAROUND(BOOST_LIBSTDCXX_VERSION, < 50000)
/* std::is_trivially_default_constructible not provided */
template <class T>
struct is_trivially_default_constructible
: public std::integral_constant<bool,
std::is_default_constructible<T>::value &&
std::has_trivial_default_constructor<T>::value>
{
};
#else
using std::is_trivially_default_constructible;
#endif
#if BOOST_WORKAROUND(BOOST_LIBSTDCXX_VERSION, < 50000)
/* std::is_trivially_copy_constructible not provided */
template <class T>
struct is_trivially_copy_constructible
: public std::integral_constant<bool,
std::is_copy_constructible<T>::value &&
std::has_trivial_copy_constructor<T>::value>
{
};
#else
using std::is_trivially_copy_constructible;
#endif
#if BOOST_WORKAROUND(BOOST_LIBSTDCXX_VERSION, < 50000)
/* std::is_trivially_copy_assignable not provided */
template <class T>
struct is_trivially_copy_assignable
: public std::integral_constant<bool,
std::is_copy_assignable<T>::value &&
std::has_trivial_copy_assign<T>::value>
{
};
#else
using std::is_trivially_copy_assignable;
#endif
namespace type_traits_detail {
using std::swap;
template <class T, class = void> struct is_nothrow_swappable_helper
{
constexpr static bool const value = false;
};
template <class T>
struct is_nothrow_swappable_helper<T,
void_t<decltype(swap(std::declval<T&>(), std::declval<T&>()))> >
{
constexpr static bool const value =
noexcept(swap(std::declval<T&>(), std::declval<T&>()));
};
} // namespace type_traits_detail
template <class T>
struct is_nothrow_swappable
: public std::integral_constant<bool,
type_traits_detail::is_nothrow_swappable_helper<T>::value>
{
};
////////////////////////////////////////////////////////////////////////////
// Type checkers used for the transparent member functions added by C++20
// and up
template <class, class = void>
struct is_transparent : public boost::false_type
struct is_transparent : public std::false_type
{
};
template <class T>
struct is_transparent<T,
typename boost::make_void<typename T::is_transparent>::type>
: public boost::true_type
boost::unordered::detail::void_t<typename T::is_transparent> >
: public std::true_type
{
};
@ -71,8 +143,8 @@ namespace boost {
static bool const value =
are_transparent<Key, hash, key_equal>::value &&
!boost::is_convertible<Key, iterator>::value &&
!boost::is_convertible<Key, const_iterator>::value;
!std::is_convertible<Key, iterator>::value &&
!std::is_convertible<Key, const_iterator>::value;
};
#if BOOST_UNORDERED_TEMPLATE_DEDUCTION_GUIDES
@ -81,7 +153,7 @@ namespace boost {
template <class InputIterator>
constexpr bool const is_input_iterator_v =
!boost::is_integral<InputIterator>::value;
!std::is_integral<InputIterator>::value;
template <class A, class = void> struct is_allocator
{
@ -90,7 +162,7 @@ namespace boost {
template <class A>
struct is_allocator<A,
boost::void_t<typename A::value_type,
boost::unordered::detail::void_t<typename A::value_type,
decltype(std::declval<A&>().allocate(std::size_t{}))> >
{
constexpr static bool const value = true;
@ -101,7 +173,7 @@ namespace boost {
template <class H>
constexpr bool const is_hash_v =
!boost::is_integral<H>::value && !is_allocator_v<H>;
!std::is_integral<H>::value && !is_allocator_v<H>;
template <class P> constexpr bool const is_pred_v = !is_allocator_v<P>;
@ -116,7 +188,7 @@ namespace boost {
typename std::pair<iter_key_t<T> const, iter_val_t<T> >;
#endif
} // namespace detail
} // namespace unordered
} // namespace unordered
} // namespace boost
#endif // BOOST_UNORDERED_DETAIL_TYPE_TRAITS_HPP

View File

@ -11,8 +11,7 @@
#ifndef BOOST_UNORDERED_HASH_TRAITS_HPP
#define BOOST_UNORDERED_HASH_TRAITS_HPP
#include <boost/type_traits/make_void.hpp>
#include <boost/type_traits/integral_constant.hpp>
#include <boost/unordered/detail/type_traits.hpp>
namespace boost{
namespace unordered{
@ -20,12 +19,12 @@ namespace unordered{
namespace detail{
template<typename Hash,typename=void>
struct hash_is_avalanching_impl: boost::false_type{};
struct hash_is_avalanching_impl: std::false_type{};
template<typename Hash>
struct hash_is_avalanching_impl<Hash,
typename boost::make_void<typename Hash::is_avalanching>::type>:
boost::true_type{};
boost::unordered::detail::void_t<typename Hash::is_avalanching> >:
std::true_type{};
} /* namespace detail */

View File

@ -18,7 +18,7 @@
#include <boost/unordered/unordered_flat_map_fwd.hpp>
#include <boost/core/allocator_access.hpp>
#include <boost/functional/hash.hpp>
#include <boost/container_hash/hash.hpp>
#include <boost/throw_exception.hpp>
#include <initializer_list>
@ -65,9 +65,9 @@ namespace boost {
using init_type = typename map_types::init_type;
using size_type = std::size_t;
using difference_type = std::ptrdiff_t;
using hasher = typename boost::type_identity<Hash>::type;
using key_equal = typename boost::type_identity<KeyEqual>::type;
using allocator_type = typename boost::type_identity<Allocator>::type;
using hasher = typename boost::unordered::detail::type_identity<Hash>::type;
using key_equal = typename boost::unordered::detail::type_identity<KeyEqual>::type;
using allocator_type = typename boost::unordered::detail::type_identity<Allocator>::type;
using reference = value_type&;
using const_reference = value_type const&;
using pointer = typename boost::allocator_pointer<allocator_type>::type;
@ -729,8 +729,8 @@ namespace boost {
Allocator>;
template <class Key, class T,
class Hash = boost::hash<boost::remove_const_t<Key> >,
class Pred = std::equal_to<boost::remove_const_t<Key> >,
class Hash = boost::hash<std::remove_const_t<Key> >,
class Pred = std::equal_to<std::remove_const_t<Key> >,
class Allocator = std::allocator<std::pair<const Key, T> >,
class = boost::enable_if_t<detail::is_hash_v<Hash> >,
class = boost::enable_if_t<detail::is_pred_v<Pred> >,
@ -738,7 +738,7 @@ namespace boost {
unordered_flat_map(std::initializer_list<std::pair<Key, T> >,
std::size_t = boost::unordered::detail::foa::default_bucket_count,
Hash = Hash(), Pred = Pred(), Allocator = Allocator())
-> unordered_flat_map<boost::remove_const_t<Key>, T, Hash, Pred,
-> unordered_flat_map<std::remove_const_t<Key>, T, Hash, Pred,
Allocator>;
template <class InputIterator, class Allocator,
@ -775,23 +775,23 @@ namespace boost {
template <class Key, class T, class Allocator,
class = boost::enable_if_t<detail::is_allocator_v<Allocator> > >
unordered_flat_map(std::initializer_list<std::pair<Key, T> >, std::size_t,
Allocator) -> unordered_flat_map<boost::remove_const_t<Key>, T,
boost::hash<boost::remove_const_t<Key> >,
std::equal_to<boost::remove_const_t<Key> >, Allocator>;
Allocator) -> unordered_flat_map<std::remove_const_t<Key>, T,
boost::hash<std::remove_const_t<Key> >,
std::equal_to<std::remove_const_t<Key> >, Allocator>;
template <class Key, class T, class Allocator,
class = boost::enable_if_t<detail::is_allocator_v<Allocator> > >
unordered_flat_map(std::initializer_list<std::pair<Key, T> >, Allocator)
-> unordered_flat_map<boost::remove_const_t<Key>, T,
boost::hash<boost::remove_const_t<Key> >,
std::equal_to<boost::remove_const_t<Key> >, Allocator>;
-> unordered_flat_map<std::remove_const_t<Key>, T,
boost::hash<std::remove_const_t<Key> >,
std::equal_to<std::remove_const_t<Key> >, Allocator>;
template <class Key, class T, class Hash, class Allocator,
class = boost::enable_if_t<detail::is_hash_v<Hash> >,
class = boost::enable_if_t<detail::is_allocator_v<Allocator> > >
unordered_flat_map(std::initializer_list<std::pair<Key, T> >, std::size_t,
Hash, Allocator) -> unordered_flat_map<boost::remove_const_t<Key>, T,
Hash, std::equal_to<boost::remove_const_t<Key> >, Allocator>;
Hash, Allocator) -> unordered_flat_map<std::remove_const_t<Key>, T,
Hash, std::equal_to<std::remove_const_t<Key> >, Allocator>;
#endif
} // namespace unordered

View File

@ -11,7 +11,7 @@
#pragma once
#endif
#include <boost/functional/hash_fwd.hpp>
#include <boost/container_hash/hash_fwd.hpp>
#include <functional>
#include <memory>

View File

@ -18,7 +18,7 @@
#include <boost/unordered/unordered_flat_set_fwd.hpp>
#include <boost/core/allocator_access.hpp>
#include <boost/functional/hash.hpp>
#include <boost/container_hash/hash.hpp>
#include <initializer_list>
#include <iterator>

View File

@ -11,7 +11,7 @@
#pragma once
#endif
#include <boost/functional/hash_fwd.hpp>
#include <boost/container_hash/hash_fwd.hpp>
#include <functional>
#include <memory>

File diff suppressed because it is too large Load Diff

View File

@ -1,6 +1,6 @@
// Copyright (C) 2008-2011 Daniel James.
// 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)
@ -12,7 +12,7 @@
#pragma once
#endif
#include <boost/functional/hash_fwd.hpp>
#include <boost/container_hash/hash_fwd.hpp>
#include <functional>
#include <memory>
@ -30,9 +30,8 @@ namespace boost {
inline bool operator!=(
unordered_map<K, T, H, P, A> const&, unordered_map<K, T, H, P, A> const&);
template <class K, class T, class H, class P, class A>
inline void swap(
unordered_map<K, T, H, P, A>& m1, unordered_map<K, T, H, P, A>& m2)
BOOST_NOEXCEPT_IF(BOOST_NOEXCEPT_EXPR(m1.swap(m2)));
inline void swap(unordered_map<K, T, H, P, A>& m1,
unordered_map<K, T, H, P, A>& m2) noexcept(noexcept(m1.swap(m2)));
template <class K, class T, class H, class P, class A, class Predicate>
typename unordered_map<K, T, H, P, A>::size_type erase_if(
@ -51,8 +50,7 @@ namespace boost {
unordered_multimap<K, T, H, P, A> const&);
template <class K, class T, class H, class P, class A>
inline void swap(unordered_multimap<K, T, H, P, A>& m1,
unordered_multimap<K, T, H, P, A>& m2)
BOOST_NOEXCEPT_IF(BOOST_NOEXCEPT_EXPR(m1.swap(m2)));
unordered_multimap<K, T, H, P, A>& m2) noexcept(noexcept(m1.swap(m2)));
template <class K, class T, class H, class P, class A, class Predicate>
typename unordered_multimap<K, T, H, P, A>::size_type erase_if(
@ -60,13 +58,13 @@ namespace boost {
template <class N, class K, class T, class A> class node_handle_map;
template <class Iter, class NodeType> struct insert_return_type_map;
}
} // namespace unordered
using boost::unordered::swap;
using boost::unordered::unordered_map;
using boost::unordered::unordered_multimap;
using boost::unordered::swap;
using boost::unordered::operator==;
using boost::unordered::operator!=;
}
} // namespace boost
#endif

View File

@ -19,7 +19,7 @@
#include <boost/unordered/unordered_node_map_fwd.hpp>
#include <boost/core/allocator_access.hpp>
#include <boost/functional/hash.hpp>
#include <boost/container_hash/hash.hpp>
#include <boost/throw_exception.hpp>
#include <initializer_list>
@ -99,9 +99,9 @@ namespace boost {
using init_type = typename map_types::init_type;
using size_type = std::size_t;
using difference_type = std::ptrdiff_t;
using hasher = typename boost::type_identity<Hash>::type;
using key_equal = typename boost::type_identity<KeyEqual>::type;
using allocator_type = typename boost::type_identity<Allocator>::type;
using hasher = typename boost::unordered::detail::type_identity<Hash>::type;
using key_equal = typename boost::unordered::detail::type_identity<KeyEqual>::type;
using allocator_type = typename boost::unordered::detail::type_identity<Allocator>::type;
using reference = value_type&;
using const_reference = value_type const&;
using pointer = typename boost::allocator_pointer<allocator_type>::type;
@ -822,8 +822,8 @@ namespace boost {
Allocator>;
template <class Key, class T,
class Hash = boost::hash<boost::remove_const_t<Key> >,
class Pred = std::equal_to<boost::remove_const_t<Key> >,
class Hash = boost::hash<std::remove_const_t<Key> >,
class Pred = std::equal_to<std::remove_const_t<Key> >,
class Allocator = std::allocator<std::pair<const Key, T> >,
class = boost::enable_if_t<detail::is_hash_v<Hash> >,
class = boost::enable_if_t<detail::is_pred_v<Pred> >,
@ -831,7 +831,7 @@ namespace boost {
unordered_node_map(std::initializer_list<std::pair<Key, T> >,
std::size_t = boost::unordered::detail::foa::default_bucket_count,
Hash = Hash(), Pred = Pred(), Allocator = Allocator())
-> unordered_node_map<boost::remove_const_t<Key>, T, Hash, Pred,
-> unordered_node_map<std::remove_const_t<Key>, T, Hash, Pred,
Allocator>;
template <class InputIterator, class Allocator,
@ -868,23 +868,23 @@ namespace boost {
template <class Key, class T, class Allocator,
class = boost::enable_if_t<detail::is_allocator_v<Allocator> > >
unordered_node_map(std::initializer_list<std::pair<Key, T> >, std::size_t,
Allocator) -> unordered_node_map<boost::remove_const_t<Key>, T,
boost::hash<boost::remove_const_t<Key> >,
std::equal_to<boost::remove_const_t<Key> >, Allocator>;
Allocator) -> unordered_node_map<std::remove_const_t<Key>, T,
boost::hash<std::remove_const_t<Key> >,
std::equal_to<std::remove_const_t<Key> >, Allocator>;
template <class Key, class T, class Allocator,
class = boost::enable_if_t<detail::is_allocator_v<Allocator> > >
unordered_node_map(std::initializer_list<std::pair<Key, T> >, Allocator)
-> unordered_node_map<boost::remove_const_t<Key>, T,
boost::hash<boost::remove_const_t<Key> >,
std::equal_to<boost::remove_const_t<Key> >, Allocator>;
-> unordered_node_map<std::remove_const_t<Key>, T,
boost::hash<std::remove_const_t<Key> >,
std::equal_to<std::remove_const_t<Key> >, Allocator>;
template <class Key, class T, class Hash, class Allocator,
class = boost::enable_if_t<detail::is_hash_v<Hash> >,
class = boost::enable_if_t<detail::is_allocator_v<Allocator> > >
unordered_node_map(std::initializer_list<std::pair<Key, T> >, std::size_t,
Hash, Allocator) -> unordered_node_map<boost::remove_const_t<Key>, T,
Hash, std::equal_to<boost::remove_const_t<Key> >, Allocator>;
Hash, Allocator) -> unordered_node_map<std::remove_const_t<Key>, T,
Hash, std::equal_to<std::remove_const_t<Key> >, Allocator>;
#endif
} // namespace unordered

View File

@ -11,7 +11,7 @@
#pragma once
#endif
#include <boost/functional/hash_fwd.hpp>
#include <boost/container_hash/hash_fwd.hpp>
#include <functional>
#include <memory>

View File

@ -19,7 +19,7 @@
#include <boost/unordered/unordered_node_set_fwd.hpp>
#include <boost/core/allocator_access.hpp>
#include <boost/functional/hash.hpp>
#include <boost/container_hash/hash.hpp>
#include <boost/throw_exception.hpp>
#include <initializer_list>

View File

@ -11,7 +11,7 @@
#pragma once
#endif
#include <boost/functional/hash_fwd.hpp>
#include <boost/container_hash/hash_fwd.hpp>
#include <functional>
#include <memory>

File diff suppressed because it is too large Load Diff

View File

@ -12,7 +12,7 @@
#pragma once
#endif
#include <boost/functional/hash_fwd.hpp>
#include <boost/container_hash/hash_fwd.hpp>
#include <functional>
#include <memory>
@ -29,9 +29,8 @@ namespace boost {
inline bool operator!=(
unordered_set<T, H, P, A> const&, unordered_set<T, H, P, A> const&);
template <class T, class H, class P, class A>
inline void swap(
unordered_set<T, H, P, A>& m1, unordered_set<T, H, P, A>& m2)
BOOST_NOEXCEPT_IF(BOOST_NOEXCEPT_EXPR(m1.swap(m2)));
inline void swap(unordered_set<T, H, P, A>& m1,
unordered_set<T, H, P, A>& m2) noexcept(noexcept(m1.swap(m2)));
template <class K, class H, class P, class A, class Predicate>
typename unordered_set<K, H, P, A>::size_type erase_if(
@ -48,9 +47,8 @@ namespace boost {
inline bool operator!=(unordered_multiset<T, H, P, A> const&,
unordered_multiset<T, H, P, A> const&);
template <class T, class H, class P, class A>
inline void swap(
unordered_multiset<T, H, P, A>& m1, unordered_multiset<T, H, P, A>& m2)
BOOST_NOEXCEPT_IF(BOOST_NOEXCEPT_EXPR(m1.swap(m2)));
inline void swap(unordered_multiset<T, H, P, A>& m1,
unordered_multiset<T, H, P, A>& m2) noexcept(noexcept(m1.swap(m2)));
template <class K, class H, class P, class A, class Predicate>
typename unordered_multiset<K, H, P, A>::size_type erase_if(
@ -58,13 +56,13 @@ namespace boost {
template <class N, class T, class A> class node_handle_set;
template <class Iter, class NodeType> struct insert_return_type_set;
}
} // namespace unordered
using boost::unordered::unordered_set;
using boost::unordered::unordered_multiset;
using boost::unordered::swap;
using boost::unordered::unordered_multiset;
using boost::unordered::unordered_set;
using boost::unordered::operator==;
using boost::unordered::operator!=;
}
} // namespace boost
#endif

View File

@ -5,14 +5,12 @@
"Daniel James"
],
"maintainers": [
"Daniel James <dnljms -at- gmail.com>"
"Christian Mazakas <christian.mazakas -at- gmail.com>",
"Joaquín M López Muñoz <joaquin.lopezmunoz -at- gmail.com>"
],
"description": "Unordered associative containers.",
"std": [
"tr1"
],
"category": [
"Containers"
],
"cxxstd": "03"
"cxxstd": "11"
}

View File

@ -77,11 +77,6 @@ fca_tests(SOURCES exception/swap_exception_tests.cpp COMPILE_DEFINITIONS BOOST_U
fca_tests(SOURCES exception/merge_exception_tests.cpp)
fca_tests(SOURCES exception/less_tests.cpp)
fca_tests(SOURCES unordered/narrow_cast_tests.cpp)
fca_tests(SOURCES unordered/compile_set.cpp COMPILE_DEFINITIONS BOOST_UNORDERED_USE_MOVE NAME bmove_compile_set)
fca_tests(SOURCES unordered/compile_map.cpp COMPILE_DEFINITIONS BOOST_UNORDERED_USE_MOVE NAME bmove_compile_map)
fca_tests(SOURCES unordered/copy_tests.cpp COMPILE_DEFINITIONS BOOST_UNORDERED_USE_MOVE NAME bmove_copy)
fca_tests(SOURCES unordered/move_tests.cpp COMPILE_DEFINITIONS BOOST_UNORDERED_USE_MOVE NAME bmove_move)
fca_tests(SOURCES unordered/assign_tests.cpp COMPILE_DEFINITIONS BOOST_UNORDERED_USE_MOVE NAME bmove_assign)
fca_tests(SOURCES quick.cpp)
fca_tests(TYPE compile-fail NAME insert_node_type_fail_map COMPILE_DEFINITIONS UNORDERED_TEST_MAP SOURCES unordered/insert_node_type_fail.cpp)

View File

@ -20,21 +20,6 @@ local msvc-flags = /wd4494 ;
project
: requirements
[ requires cxx11_rvalue_references
cxx11_auto_declarations
cxx11_nullptr
cxx11_defaulted_functions
cxx11_final
cxx11_hdr_type_traits
cxx11_hdr_initializer_list
cxx11_static_assert
cxx11_smart_ptr
cxx11_constexpr
cxx11_noexcept
cxx11_decltype
cxx11_alignas
]
<warnings>pedantic
<toolset>intel:<warnings>on
@ -146,12 +131,6 @@ for local test in $(FCA_TESTS)
run unordered/link_test_1.cpp unordered/link_test_2.cpp : : : : link_test ;
run unordered/compile_set.cpp : : : <define>BOOST_UNORDERED_USE_MOVE : bmove_compile_set ;
run unordered/compile_map.cpp : : : <define>BOOST_UNORDERED_USE_MOVE : bmove_compile_map ;
run unordered/copy_tests.cpp : : : <define>BOOST_UNORDERED_USE_MOVE : bmove_copy ;
run unordered/move_tests.cpp : : : <define>BOOST_UNORDERED_USE_MOVE : bmove_move ;
run unordered/assign_tests.cpp : : : <define>BOOST_UNORDERED_USE_MOVE : bmove_assign ;
run unordered/serialization_tests.cpp
: $(BOOST_UNORDERED_TEST_DIR)
:
@ -198,11 +177,6 @@ alias fca_tests :
$(FCA_TESTS)
$(FCA_EXCEPTION_TESTS)
link_test
bmove_compile_set
bmove_compile_map
bmove_copy
bmove_move
bmove_assign
insert_node_type_fail_map
insert_node_type_fail_multimap
insert_node_type_fail_set

View File

@ -536,7 +536,7 @@ public:
T& operator[](std::ptrdiff_t s) const { return ptr_[s]; }
bool operator!() const { return !ptr_; }
static ptr pointer_to(T& p) { return ptr(boost::addressof(p)); }
static ptr pointer_to(T& p) { return ptr(std::addressof(p)); }
// I'm not using the safe bool idiom because the containers should be
// able to cope with bool conversions.

View File

@ -10,6 +10,9 @@
#include "../helpers/random_values.hpp"
#include "../helpers/strong.hpp"
#include "../helpers/tracker.hpp"
#include <boost/tuple/tuple.hpp>
#include <cmath>
#include <string>

View File

@ -44,7 +44,7 @@ template <class T> struct move_assign_base : public test::exception_base
test::exceptions_enable disable_exceptions(false);
T y1 = y;
disable_exceptions.release();
x1 = boost::move(y1);
x1 = std::move(y1);
DISABLE_EXCEPTIONS;
test::check_container(x1, y_values);

View File

@ -6,11 +6,15 @@
#if !defined(BOOST_UNORDERED_TEST_TEST_HEADER)
#define BOOST_UNORDERED_TEST_TEST_HEADER
#include <boost/unordered/detail/fwd.hpp>
#include <boost/core/lightweight_test.hpp>
#include <boost/preprocessor/cat.hpp>
#include <boost/preprocessor/stringize.hpp>
#include <boost/type_traits/is_nothrow_move_assignable.hpp>
#include <boost/type_traits/is_nothrow_move_constructible.hpp>
#include <boost/type_traits/is_nothrow_swappable.hpp>
#include <boost/type_traits/make_void.hpp>
#define UNORDERED_AUTO_TEST(x) \
struct BOOST_PP_CAT(x, _type) : public ::test::registered_test_base \
{ \
@ -120,7 +124,7 @@ namespace test {
static state instance;
return instance;
}
}
} // namespace test
#if defined(__cplusplus)
#define BOOST_UNORDERED_CPLUSPLUS __cplusplus
@ -134,12 +138,6 @@ namespace test {
<< "Compiler: " << BOOST_COMPILER << "\n" \
<< "Library: " << BOOST_STDLIB << "\n" \
<< "__cplusplus: " << BOOST_UNORDERED_CPLUSPLUS << "\n\n" \
<< "BOOST_UNORDERED_HAVE_PIECEWISE_CONSTRUCT: " \
<< BOOST_UNORDERED_HAVE_PIECEWISE_CONSTRUCT << "\n" \
<< "BOOST_UNORDERED_EMPLACE_LIMIT: " << BOOST_UNORDERED_EMPLACE_LIMIT \
<< "\n" \
<< "BOOST_UNORDERED_CXX11_CONSTRUCTION: " \
<< BOOST_UNORDERED_CXX11_CONSTRUCTION << "\n\n" \
<< std::flush; \
}

View File

@ -14,7 +14,6 @@
#include <boost/unordered/unordered_node_map.hpp>
#include <boost/unordered/unordered_node_set.hpp>
#include <boost/unordered/detail/implementation.hpp>
#include <boost/unordered/detail/fwd.hpp>
#else
#include <boost/unordered_set.hpp>
#include <boost/unordered_map.hpp>

View File

@ -182,9 +182,7 @@ namespace test
~cxx11_allocator_base() { detail::tracker.allocator_unref(); }
#if !defined(BOOST_NO_CXX11_DEFAULTED_FUNCTIONS)
cxx11_allocator_base& operator=(cxx11_allocator_base const& x) = default;
#endif
pointer address(reference r) { return pointer(&r); }
@ -214,21 +212,12 @@ namespace test
::operator delete((void*)p);
}
#if defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
template <class U, class V>
void construct(U* p, V const& v)
{
detail::tracker.track_construct((void*)p, sizeof(U), tag_);
new (p) U(v);
}
#else
template <class U, typename... Args>
void construct(U* p, BOOST_FWD_REF(Args)... args)
void construct(U* p, Args&&... args)
{
detail::tracker.track_construct((void*)p, sizeof(U), tag_);
new (p) U(boost::forward<Args>(args)...);
new (p) U(std::forward<Args>(args)...);
}
#endif
template <class U>
void destroy(U* p)
@ -272,9 +261,7 @@ namespace test
cxx11_allocator(cxx11_allocator const& x) : cxx11_allocator_base<T>(x) {}
#if !defined(BOOST_NO_CXX11_DEFAULTED_FUNCTIONS)
cxx11_allocator& operator=(cxx11_allocator const& x) = default;
#endif
// When not propagating swap, allocators are always equal
// to avoid undefined behaviour.
@ -319,9 +306,7 @@ namespace test
cxx11_allocator(cxx11_allocator const& x) : cxx11_allocator_base<T>(x) {}
#if !defined(BOOST_NO_CXX11_DEFAULTED_FUNCTIONS)
cxx11_allocator& operator=(cxx11_allocator const& x) = default;
#endif
// When not propagating swap, allocators are always equal
// to avoid undefined behaviour.

View File

@ -501,28 +501,15 @@ namespace test {
}
}
#if defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
template <class U, class Arg>
void construct(U* p, Arg const& t)
template <class U, class... Args> void construct(U* p, Args&&... args)
{
UNORDERED_SCOPE(allocator::construct(U*, Arg))
UNORDERED_SCOPE(allocator::construct(U*, Args&&...))
{
UNORDERED_EPOINT("Mock allocator construct function.")
new (p) U(t);
new (p) U(std::forward<Args>(args)...);
}
test::detail::tracker.track_construct((void*)p, sizeof(U), tag_);
}
#else
template <class U, class... Args> void construct(U* p, BOOST_FWD_REF(Args)... args)
{
UNORDERED_SCOPE(allocator::construct(U*, BOOST_FWD_REF(Args)...))
{
UNORDERED_EPOINT("Mock allocator construct function.")
new (p) U(boost::forward<Args>(args)...);
}
test::detail::tracker.track_construct((void*)p, sizeof(U), tag_);
}
#endif
template <class U>
void destroy(U* p)
@ -682,29 +669,16 @@ namespace test {
}
}
#if defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
template <class U, class V>
void construct(U* p, V const& v)
{
UNORDERED_SCOPE(allocator2::construct(U*, V))
{
UNORDERED_EPOINT("Mock allocator2 construct function.")
new (p) U(v);
}
test::detail::tracker.track_construct((void*)p, sizeof(U), tag_);
}
#else
template <class U, class... Args>
void construct(U* p, BOOST_FWD_REF(Args)... args)
void construct(U* p, Args&&... args)
{
UNORDERED_SCOPE(allocator2::construct(U*, BOOST_FWD_REF(Args)...))
UNORDERED_SCOPE(allocator2::construct(U*, Args&&...))
{
UNORDERED_EPOINT("Mock allocator2 construct function.")
new (p) U(boost::forward<Args>(args)...);
new (p) U(std::forward<Args>(args)...);
}
test::detail::tracker.track_construct((void*)p, sizeof(U), tag_);
}
#endif
template <class U>
void destroy(U* p)

View File

@ -14,7 +14,6 @@
#include <boost/core/addressof.hpp>
#include <boost/core/lightweight_test.hpp>
#include <boost/core/pointer_traits.hpp>
#include <boost/move/move.hpp>
#include <cstddef>
#include <utility>
@ -165,19 +164,18 @@ namespace test {
class movable1
{
BOOST_MOVABLE_BUT_NOT_COPYABLE(movable1)
public:
movable1(constructor_param const&) {}
movable1() {}
explicit movable1(movable_init) {}
movable1(BOOST_RV_REF(movable1)) {}
movable1& operator=(BOOST_RV_REF(movable1)) { return *this; }
movable1(movable1 const&) = delete;
movable1& operator=(movable1 const&) = delete;
movable1(movable1&&) {}
movable1& operator=(movable1&&) { return *this; }
~movable1() {}
void dummy_member() const {}
};
#if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
class movable2
{
public:
@ -193,9 +191,6 @@ namespace test {
movable2(movable2 const&);
movable2& operator=(movable2 const&);
};
#else
typedef movable1 movable2;
#endif
template <class T> class hash
{
@ -344,7 +339,7 @@ namespace test {
bool operator!() const { return !ptr_; }
static ptr pointer_to(T& p) {
return ptr(boost::addressof(p));
return ptr(std::addressof(p));
}
// I'm not using the safe bool idiom because the containers should be
@ -461,18 +456,11 @@ namespace test {
::operator delete((void*)p.ptr_);
}
#if defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
template <class U, class V> void construct(U* p, V const& v)
{
new ((void*)p) U(v);
}
#else
template <class U, class... Args>
void construct(U* p, BOOST_FWD_REF(Args)... args)
void construct(U* p, Args&&... args)
{
new ((void*)p) U(boost::forward<Args>(args)...);
new ((void*)p) U(std::forward<Args>(args)...);
}
#endif
template <class U> void destroy(U* p) { p->~U(); }
@ -535,18 +523,11 @@ namespace test {
::operator delete((void*)p.ptr_);
}
#if defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
template <class U> void construct(U* p, U const& t)
{
new (p) U(t);
}
#else
template <class U, class... Args>
void construct(U* p, BOOST_FWD_REF(Args)... args)
void construct(U* p, Args&&... args)
{
new (p) U(boost::forward<Args>(args)...);
new (p) U(std::forward<Args>(args)...);
}
#endif
template <class U> void destroy(U* p) { p->~U(); }
@ -613,18 +594,11 @@ namespace test {
void deallocate(T* p, std::size_t) { ::operator delete((void*)p); }
#if defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
template <class U, class V> void construct(U* p, V const& v)
{
new ((void*)p) U(v);
}
#else
template <class U, class... Args>
void construct(U* p, BOOST_FWD_REF(Args)... args)
void construct(U* p, Args&&... args)
{
new ((void*)p) U(boost::forward<Args>(args)...);
new ((void*)p) U(std::forward<Args>(args)...);
}
#endif
template <class U> void destroy(U* p) { p->~U(); }

View File

@ -96,7 +96,6 @@ namespace test {
friend class less;
int tag1_, tag2_;
BOOST_COPYABLE_AND_MOVABLE(movable)
public:
explicit movable(int t1 = 0, int t2 = 0) : tag1_(t1), tag2_(t2) {}
@ -106,7 +105,7 @@ namespace test {
BOOST_TEST(x.tag1_ != -1);
}
movable(BOOST_RV_REF(movable) x)
movable(movable&& x)
: counted_object(x), tag1_(x.tag1_), tag2_(x.tag2_)
{
BOOST_TEST(x.tag1_ != -1);
@ -114,7 +113,7 @@ namespace test {
x.tag2_ = -1;
}
movable& operator=(BOOST_COPY_ASSIGN_REF(movable) x) // Copy assignment
movable& operator=(movable const& x) // Copy assignment
{
BOOST_TEST(x.tag1_ != -1);
tag1_ = x.tag1_;
@ -122,7 +121,7 @@ namespace test {
return *this;
}
movable& operator=(BOOST_RV_REF(movable) x) // Move assignment
movable& operator=(movable&& x) // Move assignment
{
BOOST_TEST(x.tag1_ != -1);
tag1_ = x.tag1_;
@ -410,11 +409,10 @@ namespace test {
::operator delete((void*)p);
}
#if BOOST_UNORDERED_CXX11_CONSTRUCTION
template <typename U, typename... Args> void construct(U* p, Args&&... args)
{
detail::tracker.track_construct((void*)p, sizeof(U), tag_);
new (p) U(boost::forward<Args>(args)...);
new (p) U(std::forward<Args>(args)...);
}
template <typename U> void destroy(U* p)
@ -425,22 +423,6 @@ namespace test {
// Work around MSVC buggy unused parameter warning.
ignore_variable(&p);
}
#else
private:
// I'm going to claim in the documentation that construct/destroy
// is never used when C++11 support isn't available, so might as
// well check that in the text.
// TODO: Or maybe just disallow them for values?
template <typename U> void construct(U* p);
template <typename U, typename A0> void construct(U* p, A0 const&);
template <typename U, typename A0, typename A1>
void construct(U* p, A0 const&, A1 const&);
template <typename U, typename A0, typename A1, typename A2>
void construct(U* p, A0 const&, A1 const&, A2 const&);
template <typename U> void destroy(U* p);
public:
#endif
bool operator==(allocator1 const& x) const { return tag_ == x.tag_; }
@ -674,20 +656,12 @@ namespace test {
::operator delete((void*)p.ptr_);
}
#if defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
template <class U, class V> void construct(U* p, V const& v)
{
detail::tracker.track_construct((void*)p, sizeof(U), tag_);
new (p) U(v);
}
#else
template <class U, class... Args>
void construct(U* p, BOOST_FWD_REF(Args)... args)
void construct(U* p, Args&&... args)
{
detail::tracker.track_construct((void*)p, sizeof(U), tag_);
new (p) U(boost::forward<Args>(args)...);
new (p) U(std::forward<Args>(args)...);
}
#endif
template <class U> void destroy(U* p)
{

View File

@ -111,12 +111,8 @@ void test_empty_allocator()
{
typedef empty_allocator<int> allocator;
typedef boost::unordered::detail::allocator_traits<allocator> traits;
#if !defined(BOOST_NO_CXX11_ALLOCATOR)
BOOST_STATIC_ASSERT((boost::is_same<traits::size_type,
std::make_unsigned<std::ptrdiff_t>::type>::value));
#else
BOOST_STATIC_ASSERT((boost::is_same<traits::size_type, std::size_t>::value));
#endif
BOOST_STATIC_ASSERT(
(boost::is_same<traits::difference_type, std::ptrdiff_t>::value));
BOOST_STATIC_ASSERT((boost::is_same<traits::pointer, int*>::value));
@ -153,12 +149,8 @@ void test_allocator1()
{
typedef allocator1<int> allocator;
typedef boost::unordered::detail::allocator_traits<allocator> traits;
#if !defined(BOOST_NO_CXX11_ALLOCATOR)
BOOST_STATIC_ASSERT((boost::is_same<traits::size_type,
std::make_unsigned<std::ptrdiff_t>::type>::value));
#else
BOOST_STATIC_ASSERT((boost::is_same<traits::size_type, std::size_t>::value));
#endif
BOOST_STATIC_ASSERT(
(boost::is_same<traits::difference_type, std::ptrdiff_t>::value));
BOOST_STATIC_ASSERT((boost::is_same<traits::pointer, int*>::value));
@ -213,15 +205,7 @@ void test_allocator2()
BOOST_TEST(!traits::propagate_on_container_move_assignment::value);
BOOST_TEST(!traits::propagate_on_container_swap::value);
BOOST_TEST(!traits::is_always_equal::value);
#if !defined(BOOST_NO_CXX11_ALLOCATOR)
// conditionally compile this assertion as all C++03 emulations of expression
// SFINAE are broken one way or another and the benefits of using Core's
// `allocator_traits` outweigh the costs of breaking this kind of code (i.e.
// inheriting SOCCC via a base)
//
BOOST_TEST(call_select<allocator>() == 1);
#endif
}
// allocator 3

View File

@ -436,8 +436,6 @@ namespace assign_tests {
(default_generator)(generate_collisions)(limited_range)))
#endif
#if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST)
UNORDERED_AUTO_TEST (assign_default_initializer_list) {
BOOST_LIGHTWEIGHT_TEST_OSTREAM << "Initializer List Tests\n";
std::initializer_list<std::pair<int const, int> > init;
@ -459,9 +457,6 @@ namespace assign_tests {
BOOST_TEST(x1.empty());
}
#endif
#if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST)
UNORDERED_AUTO_TEST (assign_initializer_list) {
BOOST_LIGHTWEIGHT_TEST_OSTREAM << "Initializer List Tests\n";
@ -482,8 +477,6 @@ namespace assign_tests {
BOOST_TEST(x.find(10) == x.end());
BOOST_TEST(x.find(-10) != x.end());
}
#endif
}
RUN_TESTS()

View File

@ -23,6 +23,7 @@
#include <boost/limits.hpp>
#include <boost/predef.h>
#include <boost/static_assert.hpp>
#include <boost/tuple/tuple.hpp>
#include <boost/type_traits/cv_traits.hpp>
#include <boost/type_traits/is_const.hpp>
#include <boost/type_traits/is_convertible.hpp>
@ -34,22 +35,9 @@ template <class T> void sink(T const&) {}
template <class T> T rvalue(T const& v) { return v; }
template <class T> T rvalue_default() { return T(); }
#if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST)
template <class T> T implicit_construct() { return {}; }
#else
template <class T> int implicit_construct()
{
T x;
sink(x);
return 0;
}
#endif
#if !defined(BOOST_NO_CXX11_NOEXCEPT)
#define TEST_NOEXCEPT_EXPR(x) BOOST_STATIC_ASSERT((BOOST_NOEXCEPT_EXPR(x)));
#else
#define TEST_NOEXCEPT_EXPR(x)
#endif
#define TEST_NOEXCEPT_EXPR(x) BOOST_STATIC_ASSERT((noexcept(x)));
template <class X, class T> void container_test(X& r, T const&)
{
@ -143,13 +131,11 @@ template <class X, class T> void container_test(X& r, T const&)
// I don't test the runtime post-conditions here.
#if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST)
// It isn't specified in the container requirements that the no argument
// constructor is implicit, but it is defined that way in the concrete
// container specification.
X u_implicit = {};
sink(u_implicit);
#endif
X u;
BOOST_TEST(u.size() == 0);
@ -191,10 +177,10 @@ template <class X, class T> void container_test(X& r, T const&)
node_type n1;
node_type n2(rvalue_default<node_type>());
#if !BOOST_COMP_GNUC || BOOST_COMP_GNUC >= BOOST_VERSION_NUMBER(4, 8, 0)
TEST_NOEXCEPT_EXPR(node_type(boost::move(n1)));
TEST_NOEXCEPT_EXPR(node_type(std::move(n1)));
#endif
node_type n3;
n3 = boost::move(n2);
n3 = std::move(n2);
n1.swap(n3);
swap(n1, n3);
// TODO: noexcept for swap?
@ -229,13 +215,11 @@ template <class X> void unordered_destructible_test(X&)
X x1;
#if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
X x2(rvalue_default<X>());
X x3 = rvalue_default<X>();
// This can only be done if propagate_on_container_move_assignment::value
// is true.
// x2 = rvalue_default<X>();
#endif
// This can only be done if propagate_on_container_move_assignment::value
// is true.
// x2 = rvalue_default<X>();
X* ptr = new X();
X& a1 = *ptr;
@ -350,7 +334,7 @@ template <class X, class Key> void unordered_set_test(X& r, Key const&)
test::minimal::constructor_param v;
Key k_lvalue(v);
r.emplace(boost::move(k_lvalue));
r.emplace(std::move(k_lvalue));
node_type n1 = r.extract(r.begin());
test::check_return_type<value_type>::equals_ref(n1.value());
#endif
@ -493,11 +477,11 @@ void unordered_map_test(X& r, Key const& k, T const& v)
test::check_return_type<key_type>::equals_ref(n1.key());
test::check_return_type<T>::equals_ref(n1.mapped());
node_type n2 = boost::move(n1);
r.insert(boost::move(n2));
node_type n2 = std::move(n1);
r.insert(std::move(n2));
r.insert(r.extract(r.begin()));
n2 = r.extract(r.begin());
r.insert(r.begin(), boost::move(n2));
r.insert(r.begin(), std::move(n2));
r.insert(r.end(), r.extract(r.begin()));
node_type n = r.extract(r.begin());
@ -530,11 +514,11 @@ template <class X, class T> void unordered_unique_test(X& r, T const& t)
// TODO;
// boost::function_requires<
// boost::MoveConstructibleConcept<insert_return_type>
// std::moveConstructibleConcept<insert_return_type>
// >();
// TODO;
// boost::function_requires<
// boost::MoveAssignableConcept<insert_return_type>
// std::moveAssignableConcept<insert_return_type>
// >();
boost::function_requires<
boost::DefaultConstructibleConcept<insert_return_type> >();
@ -738,9 +722,7 @@ void unordered_test(X& x, Key& k, Hash& hf, Pred& eq)
a.rehash(100);
a.merge(a2);
#if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
a.merge(rvalue_default<X>());
#endif
// Avoid unused variable warnings:
@ -793,7 +775,6 @@ void unordered_copyable_test(X& x, Key& k, T& t, Hash& hf, Pred& eq)
// X a8a(i, j, m);
// sink(a8a);
#if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST)
std::size_t min_buckets = 10;
X({t});
X({t}, min_buckets);
@ -803,7 +784,6 @@ void unordered_copyable_test(X& x, Key& k, T& t, Hash& hf, Pred& eq)
X({t}, min_buckets, m);
X({t}, min_buckets, hf, m);
X({t}, min_buckets, hf, eq, m);
#endif
X const b;
sink(X(b));
@ -826,7 +806,6 @@ void unordered_copyable_test(X& x, Key& k, T& t, Hash& hf, Pred& eq)
test::check_return_type<iterator>::equals(a.emplace_hint(q, t));
a.insert(i, j);
#if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST)
std::initializer_list<T> list = {t};
a.insert(list);
a.insert({t, t, t});
@ -837,7 +816,6 @@ void unordered_copyable_test(X& x, Key& k, T& t, Hash& hf, Pred& eq)
a.insert({});
a.insert({t});
a.insert({t, t});
#endif
#endif
X a10;
@ -879,12 +857,10 @@ void unordered_movable_test(X& x, Key& k, T& /* t */, Hash& hf, Pred& eq)
typedef typename X::const_iterator const_iterator;
typedef typename X::allocator_type allocator_type;
#if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
X x1(rvalue_default<X>());
X x2(boost::move(x1));
X x2(std::move(x1));
x1 = rvalue_default<X>();
x2 = boost::move(x1);
#endif
x2 = std::move(x1);
X a;
allocator_type m = a.get_allocator();
@ -922,19 +898,19 @@ void unordered_movable_test(X& x, Key& k, T& /* t */, Hash& hf, Pred& eq)
test::check_return_type<iterator>::equals(a.emplace_hint(q, v));
T v1(v);
a.emplace(boost::move(v1));
a.emplace(std::move(v1));
T v2(v);
a.insert(boost::move(v2));
a.insert(std::move(v2));
T v3(v);
test::check_return_type<iterator>::equals(a.emplace_hint(q, boost::move(v3)));
test::check_return_type<iterator>::equals(a.emplace_hint(q, std::move(v3)));
T v4(v);
test::check_return_type<iterator>::equals(a.insert(q, boost::move(v4)));
test::check_return_type<iterator>::equals(a.insert(q, std::move(v4)));
a.insert(i, j);
X a10;
T v5(v);
a10.insert(boost::move(v5));
a10.insert(std::move(v5));
q = a10.cbegin();
#ifdef BOOST_UNORDERED_FOA_TESTS
test::check_return_type<iterator>::convertible(a10.erase(q));

View File

@ -324,7 +324,6 @@ namespace constructor_tests {
test::check_equivalent_keys(x);
}
#if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST)
typedef typename T::value_type value_type;
std::initializer_list<value_type> list;
@ -525,7 +524,6 @@ namespace constructor_tests {
test::check_container(x, expected);
}
}
#endif
}
template <class T>
@ -608,7 +606,6 @@ namespace constructor_tests {
BOOST_TEST_EQ(test::detail::tracker.count_allocations, 0u);
}
#if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST)
UNORDERED_SUB_TEST("Initializer list 1")
{
std::initializer_list<typename T::value_type> list;
@ -633,7 +630,6 @@ namespace constructor_tests {
BOOST_TEST_GT(test::detail::tracker.count_allocations, 0u);
}
}
#endif
}
template <class T>
@ -721,8 +717,6 @@ namespace constructor_tests {
(default_generator)(generate_collisions)(limited_range)))
#endif
#if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST)
UNORDERED_AUTO_TEST (test_default_initializer_list) {
std::initializer_list<int> init;
#ifdef BOOST_UNORDERED_FOA_TESTS
@ -735,10 +729,6 @@ namespace constructor_tests {
BOOST_TEST(x1.empty());
}
#endif
#if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST)
UNORDERED_AUTO_TEST (test_initializer_list) {
#ifdef BOOST_UNORDERED_FOA_TESTS
boost::unordered_flat_set<int> x1 = {2, 10, 45, -5};
@ -752,8 +742,6 @@ namespace constructor_tests {
BOOST_TEST(x1.find(10) != x1.end());
BOOST_TEST(x1.find(46) == x1.end());
}
#endif
} // namespace constructor_tests
RUN_TESTS_QUIET()

View File

@ -35,8 +35,8 @@ template <typename T> struct test_allocator
typedef T value_type;
test_allocator() = default;
template <typename T2> test_allocator(test_allocator<T2> const&) {}
T* allocate(std::size_t n) const { return (T*)malloc(sizeof(T) * n); }
void deallocate(T* ptr, std::size_t) const { free(ptr); }
T* allocate(std::size_t n) const { return (T*)(::operator new(sizeof(T) * n)); }
void deallocate(T* ptr, std::size_t) const { ::operator delete(ptr); }
bool operator==(test_allocator const&) const { return true; }
bool operator!=(test_allocator const&) const { return false; }
};

View File

@ -6,14 +6,19 @@
#include "../helpers/unordered.hpp"
#include <boost/functional/hash/hash.hpp>
#include "../helpers/test.hpp"
#include "../helpers/count.hpp"
#include "../helpers/test.hpp"
#include <boost/container_hash/hash.hpp>
#include <boost/tuple/tuple.hpp>
#include <string>
#include <type_traits>
// Test that various emplace methods work with different numbers of
// arguments.
BOOST_UNORDERED_STATIC_ASSERT(std::is_same<std::piecewise_construct_t,
boost::unordered::piecewise_construct_t>::value);
namespace emplace_tests {
// Constructible with 2 to 10 arguments
struct emplace_value : private test::counted_object
@ -386,6 +391,7 @@ namespace emplace_tests {
template <class X> static void emplace_map(X*)
{
#ifdef BOOST_UNORDERED_FOA_TESTS
test::check_instances check_;
typedef X container;
@ -394,7 +400,6 @@ namespace emplace_tests {
container x(10);
return_type r1, r2;
#ifdef BOOST_UNORDERED_FOA_TESTS
// 5/8 args + duplicate
emplace_value k1(5, "", 'b', 4, 5);
BOOST_TEST_EQ(check_.constructions(), 1);
@ -450,63 +455,138 @@ namespace emplace_tests {
BOOST_TEST_EQ(check_.instances(), 8);
BOOST_TEST_EQ(check_.constructions(), 20);
#else
// 5/8 args + duplicate
emplace_value k1(5, "", 'b', 4, 5);
emplace_value m1(8, "xxx", 'z', 4, 5, 6, 7, 8);
r1 = x.emplace(boost::unordered::piecewise_construct,
boost::make_tuple(5, "", 'b', 4, 5),
boost::make_tuple(8, "xxx", 'z', 4, 5, 6, 7, 8));
BOOST_TEST_EQ(x.size(), 1u);
BOOST_TEST(r1.second);
BOOST_TEST(x.find(k1) == r1.first);
BOOST_TEST(x.find(k1)->second == m1);
BOOST_TEST_EQ(check_.instances(), 4);
BOOST_TEST_EQ(check_.constructions(), 4);
{
test::check_instances check_;
r2 = x.emplace(boost::unordered::piecewise_construct,
boost::make_tuple(5, "", 'b', 4, 5),
boost::make_tuple(8, "xxx", 'z', 4, 5, 6, 7, 8));
BOOST_TEST_EQ(x.size(), 1u);
BOOST_TEST(!r2.second);
BOOST_TEST(r1.first == r2.first);
BOOST_TEST(x.find(k1)->second == m1);
BOOST_TEST_EQ(check_.instances(), 4);
// constructions could possibly be 5 if the implementation only
// constructed the key.
BOOST_TEST_EQ(check_.constructions(), 6);
typedef X container;
typedef typename container::iterator iterator;
typedef std::pair<iterator, bool> return_type;
container x(10);
return_type r1, r2;
// 9/3 args + duplicates with hints, different mapped value.
// 5/8 args + duplicate
emplace_value k1(5, "", 'b', 4, 5);
emplace_value m1(8, "xxx", 'z', 4, 5, 6, 7, 8);
r1 =
x.emplace(std::piecewise_construct, std::make_tuple(5, "", 'b', 4, 5),
std::make_tuple(8, "xxx", 'z', 4, 5, 6, 7, 8));
BOOST_TEST_EQ(x.size(), 1u);
BOOST_TEST(r1.second);
BOOST_TEST(x.find(k1) == r1.first);
BOOST_TEST(x.find(k1)->second == m1);
BOOST_TEST_EQ(check_.instances(), 4);
BOOST_TEST_EQ(check_.constructions(), 4);
emplace_value k2(9, "", 'b', 4, 5, 6, 7, 8, 9);
emplace_value m2(3, "aaa", 'm');
r1 = x.emplace(boost::unordered::piecewise_construct,
boost::make_tuple(9, "", 'b', 4, 5, 6, 7, 8, 9),
boost::make_tuple(3, "aaa", 'm'));
BOOST_TEST_EQ(x.size(), 2u);
BOOST_TEST(r1.second);
BOOST_TEST(r1.first->first.arg_count == 9);
BOOST_TEST(r1.first->second.arg_count == 3);
BOOST_TEST(x.find(k2) == r1.first);
BOOST_TEST(x.find(k2)->second == m2);
BOOST_TEST_EQ(check_.instances(), 8);
BOOST_TEST_EQ(check_.constructions(), 10);
r2 =
x.emplace(std::piecewise_construct, std::make_tuple(5, "", 'b', 4, 5),
std::make_tuple(8, "xxx", 'z', 4, 5, 6, 7, 8));
BOOST_TEST_EQ(x.size(), 1u);
BOOST_TEST(!r2.second);
BOOST_TEST(r1.first == r2.first);
BOOST_TEST(x.find(k1)->second == m1);
BOOST_TEST_EQ(check_.instances(), 4);
// constructions could possibly be 5 if the implementation only
// constructed the key.
BOOST_TEST_EQ(check_.constructions(), 6);
BOOST_TEST(r1.first == x.emplace_hint(r1.first,
boost::unordered::piecewise_construct,
boost::make_tuple(9, "", 'b', 4, 5, 6, 7, 8, 9),
boost::make_tuple(15, "jkjk")));
BOOST_TEST(r1.first == x.emplace_hint(r2.first,
boost::unordered::piecewise_construct,
boost::make_tuple(9, "", 'b', 4, 5, 6, 7, 8, 9),
boost::make_tuple(275, "xxx", 'm', 6)));
BOOST_TEST(
r1.first == x.emplace_hint(x.end(), boost::unordered::piecewise_construct,
boost::make_tuple(9, "", 'b', 4, 5, 6, 7, 8, 9),
boost::make_tuple(-10, "blah blah", '\0')));
BOOST_TEST_EQ(x.size(), 2u);
BOOST_TEST(x.find(k2)->second == m2);
BOOST_TEST_EQ(check_.instances(), 8);
BOOST_TEST_EQ(check_.constructions(), 16);
// 9/3 args + duplicates with hints, different mapped value.
emplace_value k2(9, "", 'b', 4, 5, 6, 7, 8, 9);
emplace_value m2(3, "aaa", 'm');
r1 = x.emplace(std::piecewise_construct,
std::make_tuple(9, "", 'b', 4, 5, 6, 7, 8, 9),
std::make_tuple(3, "aaa", 'm'));
BOOST_TEST_EQ(x.size(), 2u);
BOOST_TEST(r1.second);
BOOST_TEST(r1.first->first.arg_count == 9);
BOOST_TEST(r1.first->second.arg_count == 3);
BOOST_TEST(x.find(k2) == r1.first);
BOOST_TEST(x.find(k2)->second == m2);
BOOST_TEST_EQ(check_.instances(), 8);
BOOST_TEST_EQ(check_.constructions(), 10);
BOOST_TEST(r1.first == x.emplace_hint(r1.first, std::piecewise_construct,
std::make_tuple(9, "", 'b', 4, 5, 6, 7, 8, 9),
std::make_tuple(15, "jkjk")));
BOOST_TEST(r1.first == x.emplace_hint(r2.first, std::piecewise_construct,
std::make_tuple(9, "", 'b', 4, 5, 6, 7, 8, 9),
std::make_tuple(275, "xxx", 'm', 6)));
BOOST_TEST(r1.first == x.emplace_hint(x.end(), std::piecewise_construct,
std::make_tuple(9, "", 'b', 4, 5, 6, 7, 8, 9),
std::make_tuple(-10, "blah blah", '\0')));
BOOST_TEST_EQ(x.size(), 2u);
BOOST_TEST(x.find(k2)->second == m2);
BOOST_TEST_EQ(check_.instances(), 8);
BOOST_TEST_EQ(check_.constructions(), 16);
}
{
test::check_instances check_;
typedef X container;
typedef typename container::iterator iterator;
typedef std::pair<iterator, bool> return_type;
container x(10);
return_type r1, r2;
// 5/8 args + duplicate
emplace_value k1(5, "", 'b', 4, 5);
emplace_value m1(8, "xxx", 'z', 4, 5, 6, 7, 8);
r1 =
x.emplace(boost::unordered::piecewise_construct, boost::make_tuple(5, "", 'b', 4, 5),
boost::make_tuple(8, "xxx", 'z', 4, 5, 6, 7, 8));
BOOST_TEST_EQ(x.size(), 1u);
BOOST_TEST(r1.second);
BOOST_TEST(x.find(k1) == r1.first);
BOOST_TEST(x.find(k1)->second == m1);
BOOST_TEST_EQ(check_.instances(), 4);
BOOST_TEST_EQ(check_.constructions(), 4);
r2 =
x.emplace(boost::unordered::piecewise_construct, boost::make_tuple(5, "", 'b', 4, 5),
boost::make_tuple(8, "xxx", 'z', 4, 5, 6, 7, 8));
BOOST_TEST_EQ(x.size(), 1u);
BOOST_TEST(!r2.second);
BOOST_TEST(r1.first == r2.first);
BOOST_TEST(x.find(k1)->second == m1);
BOOST_TEST_EQ(check_.instances(), 4);
// constructions could possibly be 5 if the implementation only
// constructed the key.
BOOST_TEST_EQ(check_.constructions(), 6);
// 9/3 args + duplicates with hints, different mapped value.
emplace_value k2(9, "", 'b', 4, 5, 6, 7, 8, 9);
emplace_value m2(3, "aaa", 'm');
r1 = x.emplace(boost::unordered::piecewise_construct,
boost::make_tuple(9, "", 'b', 4, 5, 6, 7, 8, 9),
boost::make_tuple(3, "aaa", 'm'));
BOOST_TEST_EQ(x.size(), 2u);
BOOST_TEST(r1.second);
BOOST_TEST(r1.first->first.arg_count == 9);
BOOST_TEST(r1.first->second.arg_count == 3);
BOOST_TEST(x.find(k2) == r1.first);
BOOST_TEST(x.find(k2)->second == m2);
BOOST_TEST_EQ(check_.instances(), 8);
BOOST_TEST_EQ(check_.constructions(), 10);
BOOST_TEST(r1.first == x.emplace_hint(r1.first,
boost::unordered::piecewise_construct,
boost::make_tuple(9, "", 'b', 4, 5, 6, 7, 8, 9),
boost::make_tuple(15, "jkjk")));
BOOST_TEST(r1.first == x.emplace_hint(r2.first,
boost::unordered::piecewise_construct,
boost::make_tuple(9, "", 'b', 4, 5, 6, 7, 8, 9),
boost::make_tuple(275, "xxx", 'm', 6)));
BOOST_TEST(r1.first == x.emplace_hint(x.end(),
boost::unordered::piecewise_construct,
boost::make_tuple(9, "", 'b', 4, 5, 6, 7, 8, 9),
boost::make_tuple(-10, "blah blah", '\0')));
BOOST_TEST_EQ(x.size(), 2u);
BOOST_TEST(x.find(k2)->second == m2);
BOOST_TEST_EQ(check_.instances(), 8);
BOOST_TEST_EQ(check_.constructions(), 16);
}
#endif
}

View File

@ -16,6 +16,7 @@
#include "../helpers/list.hpp"
#include "../helpers/invariants.hpp"
#include "../helpers/helpers.hpp"
#include <algorithm>
#include <set>
#include <iterator>
#include "../objects/test.hpp"

View File

@ -9,11 +9,7 @@
#include <boost/config.hpp>
#include <string>
#if !defined(BOOST_NO_CXX11_REF_QUALIFIERS)
#define UNORDERED_LVALUE_QUAL &
#else
#define UNORDERED_LVALUE_QUAL
#endif
namespace test {
struct is_even

View File

@ -17,7 +17,7 @@
#include "../helpers/input_iterator.hpp"
#include "../helpers/helpers.hpp"
#include <boost/move/core.hpp>
#include <boost/tuple/tuple.hpp>
#include <vector>
namespace insert_tests {
@ -75,7 +75,7 @@ namespace insert_tests {
float b = x.max_load_factor();
typename X::value_type value = *it;
std::pair<iterator, bool> r1 = x.insert(boost::move(value));
std::pair<iterator, bool> r1 = x.insert(std::move(value));
std::pair<typename ordered::iterator, bool> r2 = tracker.insert(*it);
BOOST_TEST(r1.second == r2.second);
@ -137,7 +137,7 @@ namespace insert_tests {
float b = x.max_load_factor();
typename X::value_type value = *it;
typename X::iterator r1 = x.insert(boost::move(value));
typename X::iterator r1 = x.insert(std::move(value));
typename test::ordered<X>::iterator r2 = tracker.insert(*it);
BOOST_TEST(*r1 == *r2);
@ -258,7 +258,7 @@ namespace insert_tests {
float b = x.max_load_factor();
typename X::value_type value = *it;
pos = x.insert(pos, boost::move(value));
pos = x.insert(pos, std::move(value));
tracker_iterator r2 = tracker.insert(tracker.begin(), *it);
BOOST_TEST(*pos == *r2);
tracker.compare_key(x, *it);
@ -484,7 +484,7 @@ namespace insert_tests {
float b = x.max_load_factor();
typename X::value_type value = *it;
x.emplace(boost::move(value));
x.emplace(std::move(value));
tracker.insert(*it);
tracker.compare_key(x, *it);
@ -499,7 +499,6 @@ namespace insert_tests {
template <class X> void default_emplace_tests(X*, test::random_generator)
{
#if !BOOST_UNORDERED_SUN_WORKAROUNDS1
bool is_unique = test::has_unique_keys<X>::value;
X x;
@ -529,7 +528,6 @@ namespace insert_tests {
BOOST_TEST(x.count(test::get_key<X>(y)) == (is_unique ? 1u : 2u));
BOOST_TEST(*x.equal_range(test::get_key<X>(y)).first == y);
#endif
}
template <class X> void map_tests(X*, test::random_generator generator)
@ -701,7 +699,7 @@ namespace insert_tests {
pointer_constructible(int x_) : x(x_) {}
pointer_constructible(pointer_constructible const& p) : x(p.x) {}
pointer_constructible(pointer_constructible* const&) : x(-1) {}
pointer_constructible(BOOST_RV_REF(pointer_constructible*)) : x(-1) {}
pointer_constructible(pointer_constructible*&&) : x(-1) {}
};
struct pointer_constructible_hash
@ -1079,8 +1077,6 @@ namespace insert_tests {
UNORDERED_TEST(set_tests2, ((test_pc_set)))
#endif
#if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST)
struct initialize_from_two_ints
{
int a, b;
@ -1201,8 +1197,6 @@ namespace insert_tests {
BOOST_TEST_EQ(multimap.size(), 3u);
BOOST_TEST_EQ(multimap.count("a"), 2u);
}
#endif
#endif
struct overloaded_constructor
@ -1233,11 +1227,9 @@ namespace insert_tests {
template <class X> static void map_emplace_test(X*)
{
X x;
#if !BOOST_UNORDERED_SUN_WORKAROUNDS1
x.emplace();
BOOST_TEST(
x.find(0) != x.end() && x.find(0)->second == overloaded_constructor());
#endif
x.emplace(2, 3);
BOOST_TEST(
@ -1252,11 +1244,9 @@ namespace insert_tests {
template <class X> static void multimap_emplace_test(X*)
{
X x;
#if !BOOST_UNORDERED_SUN_WORKAROUNDS1
x.emplace();
BOOST_TEST(
x.find(0) != x.end() && x.find(0)->second == overloaded_constructor());
#endif
x.emplace(2, 3);
BOOST_TEST(
@ -1296,10 +1286,8 @@ namespace insert_tests {
X x;
overloaded_constructor check;
#if !BOOST_UNORDERED_SUN_WORKAROUNDS1
x.emplace();
BOOST_TEST(x.find(check) != x.end() && *x.find(check) == check);
#endif
x.clear();
x.emplace(1);
@ -1354,10 +1342,6 @@ namespace insert_tests {
#ifndef BOOST_UNORDERED_FOA_TESTS
UNORDERED_AUTO_TEST (map_emplace_test2) {
// Emulating piecewise construction with boost::tuple bypasses the
// allocator's construct method, but still uses test destroy method.
test::detail::disable_construction_tracking _scoped;
{
boost::unordered_map<overloaded_constructor, overloaded_constructor,
boost::hash<overloaded_constructor>,
@ -1497,7 +1481,11 @@ namespace insert_tests {
#define EMULATING_PIECEWISE_CONSTRUCTION 1
#include "./insert_tests.cpp"
#if BOOST_UNORDERED_HAVE_PIECEWISE_CONSTRUCT
#define PIECEWISE_TEST_NAME std_tuple_boost_piecewise_tests
#define PIECEWISE_NAMESPACE boost::unordered
#define TUPLE_NAMESPACE std
#define EMULATING_PIECEWISE_CONSTRUCTION 0
#include "./insert_tests.cpp"
#define PIECEWISE_TEST_NAME boost_tuple_std_piecewise_tests
#define PIECEWISE_NAMESPACE std
@ -1507,21 +1495,6 @@ namespace insert_tests {
#endif
#if !defined(BOOST_NO_CXX11_HDR_TUPLE)
#define PIECEWISE_TEST_NAME std_tuple_boost_piecewise_tests
#define PIECEWISE_NAMESPACE boost::unordered
#define TUPLE_NAMESPACE std
#define EMULATING_PIECEWISE_CONSTRUCTION 0
#include "./insert_tests.cpp"
#endif
#endif
#if !defined(BOOST_NO_CXX11_HDR_TUPLE) && \
BOOST_UNORDERED_HAVE_PIECEWISE_CONSTRUCT
#ifdef BOOST_UNORDERED_FOA_TESTS
static boost::unordered_flat_set<std::pair<overloaded_constructor,
overloaded_constructor> >* test_pair_oc_set;
@ -1535,8 +1508,6 @@ namespace insert_tests {
#define TUPLE_NAMESPACE std
#define EMULATING_PIECEWISE_CONSTRUCTION 0
#include "./insert_tests.cpp"
#endif
}
RUN_TESTS_QUIET()
@ -1549,10 +1520,6 @@ RUN_TESTS_QUIET()
template <class X>
static void MAP_PIECEWISE_TEST(X*)
{
#if EMULATING_PIECEWISE_CONSTRUCTION
test::detail::disable_construction_tracking _scoped;
#endif
X x;
x.emplace(PIECEWISE_NAMESPACE::piecewise_construct,
@ -1601,10 +1568,6 @@ RUN_TESTS_QUIET()
template <class X>
static void SET_PIECEWISE_TEST(X*)
{
#if EMULATING_PIECEWISE_CONSTRUCTION
test::detail::disable_construction_tracking _scoped;
#endif
X x;
std::pair<overloaded_constructor, overloaded_constructor> check;
@ -1645,9 +1608,6 @@ RUN_TESTS_QUIET()
#ifndef BOOST_UNORDERED_FOA_TESTS
UNORDERED_AUTO_TEST (BOOST_PP_CAT(multimap_, PIECEWISE_TEST_NAME)) {
{
#if EMULATING_PIECEWISE_CONSTRUCTION
test::detail::disable_construction_tracking _scoped;
#endif
boost::unordered_multimap<overloaded_constructor, overloaded_constructor,
boost::hash<overloaded_constructor>,
std::equal_to<overloaded_constructor>,

View File

@ -48,13 +48,8 @@ template <typename T> void test_simple_allocator()
BOOST_STATIC_ASSERT(
(boost::is_same<typename traits::difference_type, std::ptrdiff_t>::value));
#if !defined(BOOST_NO_CXX11_ALLOCATOR)
BOOST_STATIC_ASSERT((boost::is_same<typename traits::size_type,
std::make_unsigned<std::ptrdiff_t>::type>::value));
#else
BOOST_STATIC_ASSERT(
(boost::is_same<typename traits::size_type, std::size_t>::value));
#endif
BOOST_TEST(!traits::propagate_on_container_copy_assignment::value);
BOOST_TEST(!traits::propagate_on_container_move_assignment::value);

View File

@ -23,12 +23,7 @@
namespace move_tests {
test::seed_t initialize_seed(98624);
#if defined(BOOST_UNORDERED_USE_MOVE) || \
!defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
#define BOOST_UNORDERED_TEST_MOVING 1
#else
#define BOOST_UNORDERED_TEST_MOVING 0
#endif
template <class T> T empty(T*) { return T(); }
@ -73,8 +68,6 @@ namespace move_tests {
BOOST_TEST(y.max_load_factor() == 1.0);
#endif
test::check_equivalent_keys(y);
#if defined(BOOST_UNORDERED_USE_MOVE) || \
!defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
#ifdef BOOST_UNORDERED_FOA_TESTS
using allocator_type = typename T::allocator_type;
@ -86,7 +79,6 @@ namespace move_tests {
}
#else
BOOST_TEST_EQ(test::detail::tracker.count_allocations, 0u);
#endif
#endif
}
@ -126,8 +118,7 @@ namespace move_tests {
T y;
y = empty(p);
#if defined(BOOST_UNORDERED_USE_MOVE) || \
!defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
#ifdef BOOST_UNORDERED_FOA_TESTS
using allocator_type = typename T::allocator_type;
using value_type =
@ -138,7 +129,6 @@ namespace move_tests {
}
#else
BOOST_TEST_EQ(test::detail::tracker.count_allocations, 0u);
#endif
#endif
test::check_container(y, v);
test::check_equivalent_keys(y);
@ -200,23 +190,8 @@ namespace move_tests {
test::random_values<T> v(25, generator);
T y(create(v, count, hf, eq, al, 1.0), al);
#if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
BOOST_TEST(count == test::global_object_count);
#elif defined(BOOST_HAS_NRVO)
BOOST_TEST(
static_cast<std::size_t>(
test::global_object_count.constructions - count.constructions) <=
(test::is_set<T>::value ? 1 : 2) *
(test::has_unique_keys<T>::value ? 25 : v.size()));
BOOST_TEST(count.instances == test::global_object_count.instances);
#else
BOOST_TEST(
static_cast<std::size_t>(
test::global_object_count.constructions - count.constructions) <=
(test::is_set<T>::value ? 2 : 4) *
(test::has_unique_keys<T>::value ? 25 : v.size()));
BOOST_TEST(count.instances == test::global_object_count.instances);
#endif
test::check_container(y, v);
BOOST_TEST(test::equivalent(y.hash_function(), hf));
BOOST_TEST(test::equivalent(y.key_eq(), eq));
@ -313,9 +288,8 @@ namespace move_tests {
BOOST_TEST_EQ(test::detail::tracker.count_allocations, 0u);
#endif
y = boost::move(x);
#if defined(BOOST_UNORDERED_USE_MOVE) || \
!defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
y = std::move(x);
#ifdef BOOST_UNORDERED_FOA_TESTS
{
using value_type =
@ -327,7 +301,6 @@ namespace move_tests {
}
#else
BOOST_TEST_EQ(test::detail::tracker.count_allocations, 0u);
#endif
#endif
test::check_container(y, v);
test::check_equivalent_keys(y);
@ -357,7 +330,7 @@ namespace move_tests {
x.insert(v.begin(), v.end());
test::object_count count = test::global_object_count;
y = boost::move(x);
y = std::move(x);
if (BOOST_UNORDERED_TEST_MOVING && allocator_type::is_propagate_on_move) {
BOOST_TEST(count == test::global_object_count);
}
@ -391,7 +364,7 @@ namespace move_tests {
test::object_count count1 = test::global_object_count;
T y(v1.begin(), v1.end(), 0, hf, eq, al1);
y = boost::move(x);
y = std::move(x);
test::object_count count2 = test::global_object_count;

View File

@ -4,6 +4,8 @@
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
#include <boost/config.hpp>
#include "../helpers/postfix.hpp"
#include "../helpers/prefix.hpp"
#include "../helpers/unordered.hpp"
@ -17,6 +19,11 @@
#include <set>
#include <string>
#if defined(BOOST_GCC) && BOOST_GCC >= 130000
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wself-move"
#endif
template <template <class Key, class T, class Hash = boost::hash<Key>,
class Pred = std::equal_to<Key>,
class Allocator = std::allocator<std::pair<Key const, T> > >
@ -119,12 +126,12 @@ static void failed_insertion_with_hint()
typename Set<int>::node_type nh = src.extract(10);
BOOST_TEST(dst.insert(dst.find(10), boost::move(nh)) == dst.find(10));
BOOST_TEST(dst.insert(dst.find(10), std::move(nh)) == dst.find(10));
BOOST_TEST(nh);
BOOST_TEST(!nh.empty());
BOOST_TEST(nh.value() == 10);
BOOST_TEST(dst.insert(dst.find(20), boost::move(nh)) == dst.find(10));
BOOST_TEST(dst.insert(dst.find(20), std::move(nh)) == dst.find(10));
BOOST_TEST(nh);
BOOST_TEST(!nh.empty());
BOOST_TEST(nh.value() == 10);
@ -144,14 +151,14 @@ static void failed_insertion_with_hint()
dst.emplace(20, 2);
typename Map<int, int>::node_type nh = src.extract(10);
BOOST_TEST(dst.insert(dst.find(10), boost::move(nh)) == dst.find(10));
BOOST_TEST(dst.insert(dst.find(10), std::move(nh)) == dst.find(10));
BOOST_TEST(nh);
BOOST_TEST(!nh.empty());
BOOST_TEST(nh.key() == 10);
BOOST_TEST(nh.mapped() == 30);
BOOST_TEST(dst[10] == 20);
BOOST_TEST(dst.insert(dst.find(20), boost::move(nh)) == dst.find(10));
BOOST_TEST(dst.insert(dst.find(20), std::move(nh)) == dst.find(10));
BOOST_TEST(nh);
BOOST_TEST(!nh.empty());
BOOST_TEST(nh.key() == 10);
@ -195,7 +202,7 @@ template <typename Container> void node_handle_tests_impl(Container& c)
BOOST_TEST(!n2.empty());
node_handle_compare(n2, value);
node_type n3 = boost::move(n2);
node_type n3 = std::move(n2);
BOOST_TEST(n3);
BOOST_TEST(!n2);
node_handle_compare(n3, value);
@ -203,16 +210,16 @@ template <typename Container> void node_handle_tests_impl(Container& c)
// Maybe by swapping and observing that the allocator is
// swapped rather than moved?
n1 = boost::move(n3);
n1 = std::move(n3);
BOOST_TEST(n1);
BOOST_TEST(!n3);
node_handle_compare(n1, value);
// Self move-assignment empties the node_handle.
n1 = boost::move(n1);
n1 = std::move(n1);
BOOST_TEST(!n1);
n3 = boost::move(n3);
n3 = std::move(n3);
BOOST_TEST(!n3);
typename Container::value_type value1 = *c.begin();

View File

@ -57,13 +57,10 @@ namespace noexcept_tests {
bool nothrow_swap>
class hash_nothrow : boost::hash<int>
{
BOOST_COPYABLE_AND_MOVABLE(hash_nothrow)
typedef boost::hash<int> base;
public:
hash_nothrow(BOOST_RV_REF(hash_nothrow))
BOOST_NOEXCEPT_IF(nothrow_move_construct)
hash_nothrow(hash_nothrow&&) noexcept(nothrow_move_construct)
{
if (!nothrow_move_construct) {
test_throw("Move Constructor");
@ -72,13 +69,13 @@ namespace noexcept_tests {
hash_nothrow() { test_throw("Constructor"); }
hash_nothrow(hash_nothrow const&) { test_throw("Copy"); }
hash_nothrow& operator=(BOOST_COPY_ASSIGN_REF(hash_nothrow))
hash_nothrow& operator=(hash_nothrow const&)
{
test_throw("Assign");
return *this;
}
hash_nothrow& operator=(BOOST_RV_REF(hash_nothrow))
BOOST_NOEXCEPT_IF(nothrow_move_assign)
hash_nothrow& operator=(hash_nothrow&&)
noexcept(nothrow_move_assign)
{
if (!nothrow_move_assign) {
test_throw("Move Assign");
@ -90,8 +87,7 @@ namespace noexcept_tests {
test_throw("Operator");
return static_cast<base const&>(*this)(x);
}
friend void swap(hash_nothrow&, hash_nothrow&)
BOOST_NOEXCEPT_IF(nothrow_swap)
friend void swap(hash_nothrow&, hash_nothrow&) noexcept(nothrow_swap)
{
if (!nothrow_swap) {
test_throw("Swap");
@ -107,13 +103,11 @@ namespace noexcept_tests {
bool nothrow_swap>
class equal_to_nothrow
{
BOOST_COPYABLE_AND_MOVABLE(equal_to_nothrow)
typedef boost::hash<int> base;
public:
equal_to_nothrow(BOOST_RV_REF(equal_to_nothrow))
BOOST_NOEXCEPT_IF(nothrow_move_construct)
equal_to_nothrow(equal_to_nothrow&&)
noexcept(nothrow_move_construct)
{
if (!nothrow_move_construct) {
test_throw("Move Constructor");
@ -122,13 +116,13 @@ namespace noexcept_tests {
equal_to_nothrow() { test_throw("Constructor"); }
equal_to_nothrow(equal_to_nothrow const&) { test_throw("Copy"); }
equal_to_nothrow& operator=(BOOST_COPY_ASSIGN_REF(equal_to_nothrow))
equal_to_nothrow& operator=(equal_to_nothrow const&)
{
test_throw("Assign");
return *this;
}
equal_to_nothrow& operator=(BOOST_RV_REF(equal_to_nothrow))
BOOST_NOEXCEPT_IF(nothrow_move_assign)
equal_to_nothrow& operator=(equal_to_nothrow&&)
noexcept(nothrow_move_assign)
{
if (!nothrow_move_assign) {
test_throw("Move Assign");
@ -141,7 +135,7 @@ namespace noexcept_tests {
return x == y;
}
friend void swap(equal_to_nothrow&, equal_to_nothrow&)
BOOST_NOEXCEPT_IF(nothrow_swap)
noexcept(nothrow_swap)
{
if (!nothrow_swap) {
test_throw("Swap");
@ -178,18 +172,9 @@ namespace noexcept_tests {
boost::is_nothrow_swappable<hash_nothrow_swap>::value;
// Check that the traits work when expected.
#if !defined(BOOST_NO_CXX11_NOEXCEPT) && !defined(BOOST_NO_SFINAE_EXPR) && \
!BOOST_WORKAROUND(BOOST_GCC_VERSION, < 40800)
BOOST_TEST(have_is_nothrow_move);
BOOST_TEST(have_is_nothrow_move_assign);
#endif
#if !defined(BOOST_NO_SFINAE_EXPR) && !defined(BOOST_NO_CXX11_NOEXCEPT) && \
!defined(BOOST_NO_CXX11_DECLTYPE) && \
!defined(BOOST_NO_CXX11_FUNCTION_TEMPLATE_DEFAULT_ARGS) && \
!BOOST_WORKAROUND(BOOST_GCC_VERSION, < 40700)
BOOST_TEST(have_is_nothrow_swap);
#endif
BOOST_LIGHTWEIGHT_TEST_OSTREAM
<< "have_is_nothrow_move: " << have_is_nothrow_move << std::endl
@ -257,7 +242,7 @@ namespace noexcept_tests {
try {
throwing_test_exception = true;
X x2 = boost::move(x1);
X x2 = std::move(x1);
BOOST_TEST(x2.size() == 2);
BOOST_TEST(*x2.begin() == 10 || *x2.begin() == 50);
BOOST_TEST(have_is_nothrow_move);
@ -289,7 +274,7 @@ namespace noexcept_tests {
try {
throwing_test_exception = true;
x2 = boost::move(x1);
x2 = std::move(x1);
BOOST_TEST(x2.size() == 2);
BOOST_TEST(*x2.begin() == 10 || *x2.begin() == 50);
BOOST_TEST(have_is_nothrow_move_assign);
@ -318,7 +303,7 @@ namespace noexcept_tests {
try {
throwing_test_exception = true;
x1 = boost::move(x2);
x1 = std::move(x2);
BOOST_TEST(x1.size() == 100);
BOOST_TEST(have_is_nothrow_move_assign);
} catch (test_exception) {
@ -367,9 +352,8 @@ namespace noexcept_tests {
template <class T> class allocator1
{
BOOST_COPYABLE_AND_MOVABLE(allocator1)
allocator1 operator=(BOOST_COPY_ASSIGN_REF(allocator1));
allocator1 operator=(BOOST_RV_REF(allocator1));
allocator1 operator=(allocator1 const&);
allocator1 operator=(allocator1&&);
public:
typedef T value_type;
@ -393,8 +377,7 @@ public:
template <class T> class allocator2
{
BOOST_COPYABLE_AND_MOVABLE(allocator2)
allocator2 operator=(BOOST_COPY_ASSIGN_REF(allocator2));
allocator2 operator=(allocator2 const&);
public:
typedef T value_type;
@ -405,7 +388,7 @@ public:
template <class U> allocator2(allocator2<U> const&) {}
allocator2& operator=(BOOST_RV_REF(allocator2)) { return *this; }
allocator2& operator=(allocator2&&) { return *this; }
T* allocate(std::size_t n)
{

View File

@ -21,12 +21,7 @@
namespace move_tests {
test::seed_t initialize_seed(98624);
#if defined(BOOST_UNORDERED_USE_MOVE) || \
!defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
#define BOOST_UNORDERED_TEST_MOVING 1
#else
#define BOOST_UNORDERED_TEST_MOVING 0
#endif
template <class T> T empty(T*) { return T(); }
@ -322,7 +317,7 @@ namespace move_tests {
{
T x(v.begin(), v.end());
std::size_t const size = x.size();
y = boost::move(x);
y = std::move(x);
BOOST_TEST_GE(y.size(), size);
BOOST_TEST_EQ(y.size(),
static_cast<typename T::size_type>(std::distance(y.begin(), y.end())));
@ -393,7 +388,7 @@ namespace move_tests {
template <class T>
static void double_move_construct(T& y, test::random_values<T> const&)
{
T x = boost::move(y);
T x = std::move(y);
x.clear();
BOOST_TEST_EQ(y.size(),
static_cast<typename T::size_type>(std::distance(y.begin(), y.end())));
@ -405,7 +400,7 @@ namespace move_tests {
static void double_move_assign(T& y, test::random_values<T> const&)
{
T x;
x = boost::move(y);
x = std::move(y);
x.clear();
BOOST_TEST_EQ(y.size(),
static_cast<typename T::size_type>(std::distance(y.begin(), y.end())));
@ -461,10 +456,8 @@ namespace move_tests {
unsigned num_allocs = test::detail::tracker.count_allocations;
(void)num_allocs;
T x(boost::move(y));
T x(std::move(y));
#if defined(BOOST_UNORDERED_USE_MOVE) || \
!defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
BOOST_TEST(y.empty());
BOOST_TEST(y.begin() == y.end());
@ -482,8 +475,6 @@ namespace move_tests {
#else
BOOST_TEST_EQ(y.bucket_count(), 0u);
BOOST_TEST_EQ(test::detail::tracker.count_allocations, num_allocs);
#endif
#endif
fps[i](y, v);
@ -503,7 +494,7 @@ namespace move_tests {
test::random_values<T> v(1000, generator);
test::object_count count;
T y(v.begin(), v.end(), 0, hf, eq, al1);
T x(boost::move(y), al2);
T x(std::move(y), al2);
#ifdef BOOST_UNORDERED_FOA_TESTS
BOOST_TEST(y.empty());
@ -530,10 +521,8 @@ namespace move_tests {
(void)num_allocs;
T x(empty(ptr));
x = boost::move(y);
x = std::move(y);
#if defined(BOOST_UNORDERED_USE_MOVE) || \
!defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
BOOST_TEST(y.empty());
BOOST_TEST(y.begin() == y.end());
@ -551,8 +540,6 @@ namespace move_tests {
#else
BOOST_TEST_EQ(y.bucket_count(), 0u);
BOOST_TEST_EQ(test::detail::tracker.count_allocations, num_allocs);
#endif
#endif
fps[i](y, v);
@ -577,22 +564,15 @@ namespace move_tests {
(void)num_allocs;
T x(al2);
x = boost::move(y);
x = std::move(y);
bool b = boost::allocator_propagate_on_container_move_assignment<
typename T::allocator_type>::type::value;
if (b) {
#if defined(BOOST_UNORDERED_USE_MOVE) || \
!defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
BOOST_TEST(y.empty());
BOOST_TEST(y.begin() == y.end());
BOOST_TEST_EQ(y.bucket_count(), 0u);
BOOST_TEST_EQ(test::detail::tracker.count_allocations, num_allocs);
#else
BOOST_TEST_NOT(y.empty());
BOOST_TEST(y.begin() != y.end());
#endif
} else {
#ifdef BOOST_UNORDERED_FOA_TESTS
BOOST_TEST(y.empty());

View File

@ -64,7 +64,7 @@ void prime_sizes_test()
BOOST_TEST(!is_prime(100));
BOOST_TEST(!is_prime(49));
std::size_t* sizes = boost::unordered::detail::prime_fmod_size<>::sizes;
std::size_t const* sizes = boost::unordered::detail::prime_fmod_size<>::sizes;
std::size_t sizes_len =
boost::unordered::detail::prime_fmod_size<>::sizes_len;
@ -88,7 +88,7 @@ void prime_sizes_test()
// correct amount of them, i.e. one for every entry in sizes[] that fits in 32
// bits
//
boost::uint64_t* inv_sizes32 =
boost::uint64_t const* inv_sizes32 =
boost::unordered::detail::prime_fmod_size<>::inv_sizes32;
std::size_t inv_sizes32_len =
@ -171,7 +171,7 @@ void get_remainder_test()
void modulo_test()
{
std::size_t* sizes = boost::unordered::detail::prime_fmod_size<>::sizes;
std::size_t const* sizes = boost::unordered::detail::prime_fmod_size<>::sizes;
std::size_t const sizes_len =
boost::unordered::detail::prime_fmod_size<>::sizes_len;

View File

@ -451,14 +451,14 @@ namespace rehash_tests {
typedef typename X::iterator iterator;
for (iterator pos = x.begin(); pos != x.end(); ++pos) {
elements.insert(boost::addressof(*pos));
elements.insert(std::addressof(*pos));
}
x.rehash(2 * x.bucket_count());
for (iterator pos = x.begin(); pos != x.end(); ++pos) {
if (!BOOST_TEST(
elements.find(boost::addressof(*pos)) != elements.end())) {
elements.find(std::addressof(*pos)) != elements.end())) {
break;
}
}

View File

@ -24,19 +24,19 @@ template <typename T> struct A
A() : i(++count) {}
template <class U> A(const A<U>& a) BOOST_NOEXCEPT : i(a.i) {}
template <class U> A(const A<U>& a) noexcept : i(a.i) {}
T* allocate(std::size_t n)
{
total_allocation += n * sizeof(T);
++num_allocations;
return (T*)std::calloc(n, sizeof(T));
return (T*)(::operator new(n * sizeof(T)));
}
void deallocate(T* p, std::size_t n) BOOST_NOEXCEPT
void deallocate(T* p, std::size_t n) noexcept
{
total_allocation -= n * sizeof(T);
std::free(p);
::operator delete(p);
}
bool operator==(A const& a) const { return i == a.i; }

View File

@ -87,15 +87,11 @@ public:
::operator delete((void*)p.operator->());
}
#if defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
template <class U, class V> void construct(U* p, V const& v) { new (p) U(v); }
#else
template <class U, class... Args>
void construct(U* p, BOOST_FWD_REF(Args)... args)
void construct(U* p, Args&&... args)
{
new (p) U(boost::forward<Args>(args)...);
new (p) U(std::forward<Args>(args)...);
}
#endif
// msvc-12.0 and msvc-14.0 seem to eliminate the destructor call as we're only
// ever using it with an int with has a trivial destructor so it eliminates
@ -171,15 +167,11 @@ public:
void deallocate(pointer p, size_type) { ::operator delete((void*)p.ptr_); }
#if defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
template <class U, class V> void construct(U* p, V const& v) { new (p) U(v); }
#else
template <class U, class... Args>
void construct(U* p, BOOST_FWD_REF(Args)... args)
void construct(U* p, Args&&... args)
{
new (p) U(boost::forward<Args>(args)...);
new (p) U(std::forward<Args>(args)...);
}
#endif
// msvc-12.0 and msvc-14.0 seem to eliminate the destructor call as we're only
// ever using it with an int with has a trivial destructor so it eliminates

View File

@ -27,13 +27,7 @@
#include <cstdio>
#include <fstream>
#if defined(BOOST_NO_CXX11_HDR_RANDOM) || BOOST_WORKAROUND(BOOST_MSVC, < 1700)
#define BOOST_UNORDERED_TEST_USE_STD_RANDOM_SHUFFLE
#endif
#ifndef BOOST_UNORDERED_TEST_USE_STD_RANDOM_SHUFFLE
#include <random>
#endif
namespace {

View File

@ -1845,7 +1845,7 @@ template <class UnorderedSet> void test_set_transparent_extract(UnorderedSet*)
BOOST_TEST_EQ(nh.value(), 0);
BOOST_TEST_EQ(count, set_size - 3);
set.insert(boost::move(nh));
set.insert(std::move(nh));
nh = set.extract(1);
count = set.count(1);
@ -1853,7 +1853,7 @@ template <class UnorderedSet> void test_set_transparent_extract(UnorderedSet*)
BOOST_TEST_EQ(nh.value(), 1);
BOOST_TEST_EQ(count, 0u);
set.insert(boost::move(nh));
set.insert(std::move(nh));
nh = set.extract(1337);
BOOST_TEST(nh.empty());
@ -1897,7 +1897,7 @@ void test_set_non_transparent_extract(UnorderedSet*)
BOOST_TEST_EQ(nh.value(), 0);
BOOST_TEST_EQ(count, set_size - 3);
set.insert(boost::move(nh));
set.insert(std::move(nh));
nh = set.extract(1);
++key_count;
@ -1909,7 +1909,7 @@ void test_set_non_transparent_extract(UnorderedSet*)
BOOST_TEST_EQ(nh.value(), 1);
BOOST_TEST_EQ(count, 0u);
set.insert(boost::move(nh));
set.insert(std::move(nh));
nh = set.extract(1337);
++key_count;

View File

@ -12,11 +12,11 @@
#include "../helpers/test.hpp"
#include <boost/tuple/tuple.hpp>
namespace unnecessary_copy_tests {
struct count_copies
{
private:
BOOST_COPYABLE_AND_MOVABLE(count_copies)
public:
static int copies;
static int moves;
@ -56,7 +56,7 @@ namespace unnecessary_copy_tests {
trace_op("Copy construct");
}
count_copies(BOOST_RV_REF(count_copies) x) : tag_(x.tag_), id_(++id_count)
count_copies(count_copies&& x) : tag_(x.tag_), id_(++id_count)
{
x.tag_ = -1;
++moves;
@ -64,7 +64,7 @@ namespace unnecessary_copy_tests {
}
count_copies& operator=(
BOOST_COPY_ASSIGN_REF(count_copies) p) // Copy assignment
count_copies const& p) // Copy assignment
{
tag_ = p.tag_;
++copies;
@ -72,7 +72,7 @@ namespace unnecessary_copy_tests {
return *this;
}
count_copies& operator=(BOOST_RV_REF(count_copies) p) // Move assignment
count_copies& operator=(count_copies&& p) // Move assignment
{
tag_ = p.tag_;
++moves;
@ -189,13 +189,13 @@ namespace unnecessary_copy_tests {
T x;
typename T::value_type a;
reset();
x.insert(boost::move(a));
x.insert(std::move(a));
COPY_COUNT(0);
MOVE_COUNT(1);
typename T::value_type a2;
reset();
x.insert(boost::move(a));
x.insert(std::move(a));
COPY_COUNT(0);
MOVE_COUNT((x.size() == 2 ? 1 : 0));
}
@ -209,25 +209,17 @@ namespace unnecessary_copy_tests {
T x;
typename T::value_type a;
reset();
x.insert(boost::move(a));
#if defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
COPY_COUNT(1);
MOVE_COUNT(0);
#else
x.insert(std::move(a));
COPY_COUNT(0);
MOVE_COUNT(1);
#endif
typename T::value_type a2;
reset();
x.insert(boost::move(a));
#if defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
COPY_COUNT((x.size() == 2 ? 1 : 0));
MOVE_COUNT(0);
#else
x.insert(std::move(a));
COPY_COUNT(0);
MOVE_COUNT((x.size() == 2 ? 1 : 0));
#endif
}
boost::unordered_set<count_copies>* set;
@ -254,11 +246,7 @@ namespace unnecessary_copy_tests {
reset();
T x;
x.emplace(source<typename T::value_type>());
#if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
COPY_COUNT(1);
#else
COPY_COUNT(2);
#endif
}
UNORDERED_TEST(
@ -266,7 +254,6 @@ namespace unnecessary_copy_tests {
UNORDERED_TEST(
unnecessary_copy_emplace_rvalue_test, ((set)(multiset)(map)(multimap)))
#if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
template <class T> void unnecessary_copy_emplace_std_move_test(T*)
{
reset();
@ -281,7 +268,6 @@ namespace unnecessary_copy_tests {
UNORDERED_TEST(
unnecessary_copy_emplace_std_move_test, ((set)(multiset)(map)(multimap)))
#endif
template <class T> void unnecessary_copy_emplace_boost_move_test(T*)
{
@ -290,15 +276,9 @@ namespace unnecessary_copy_tests {
typename T::value_type a;
COPY_COUNT(1);
MOVE_COUNT_EXTRA(0, 1);
x.emplace(boost::move(a));
#if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
x.emplace(std::move(a));
COPY_COUNT(1);
MOVE_COUNT(1);
#else
// Since std::pair isn't movable, move only works for sets.
COPY_COUNT_RANGE(1, 2);
MOVE_COUNT_RANGE(0, 1);
#endif
}
UNORDERED_TEST(
@ -311,7 +291,7 @@ namespace unnecessary_copy_tests {
typename T::value_type a;
COPY_COUNT(1);
MOVE_COUNT(0);
x.emplace(boost::move(a));
x.emplace(std::move(a));
COPY_COUNT(1);
MOVE_COUNT(1);
}
@ -328,14 +308,10 @@ namespace unnecessary_copy_tests {
typename T::value_type a;
COPY_COUNT(1);
MOVE_COUNT_EXTRA(0, 1);
x.emplace(boost::move(a));
#if defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
COPY_COUNT(2);
MOVE_COUNT_EXTRA(0, 1);
#else
x.emplace(std::move(a));
COPY_COUNT(1);
MOVE_COUNT(1);
#endif
}
UNORDERED_TEST(
@ -362,7 +338,6 @@ namespace unnecessary_copy_tests {
// 0 arguments
//
#if !BOOST_UNORDERED_SUN_WORKAROUNDS1
// The container will have to create a copy in order to compare with
// the existing element.
reset();
@ -371,7 +346,6 @@ namespace unnecessary_copy_tests {
// source_cost doesn't make much sense here, but it seems to fit.
COPY_COUNT(1);
MOVE_COUNT(source_cost);
#endif
//
// 1 argument
@ -393,7 +367,7 @@ namespace unnecessary_copy_tests {
// No move should take place.
reset();
x.emplace(boost::move(a));
x.emplace(std::move(a));
COPY_COUNT(0);
MOVE_COUNT(0);
@ -450,14 +424,13 @@ namespace unnecessary_copy_tests {
// 0 arguments
//
#if !BOOST_UNORDERED_SUN_WORKAROUNDS1
// COPY_COUNT(1) would be okay here.
reset();
x.emplace();
#if BOOST_WORKAROUND(BOOST_MSVC, == 1700)
// This is a little odd, Visual C++ 11 seems to move the pair, which
// results in one copy (for the const key) and one move (for the
// non-const mapped value). Since 'emplace(boost::move(a))' (see below)
// non-const mapped value). Since 'emplace(std::move(a))' (see below)
// has the normal result, it must be some odd consequence of how
// Visual C++ 11 handles calling move for default arguments.
COPY_COUNT(3);
@ -465,7 +438,6 @@ namespace unnecessary_copy_tests {
#else
COPY_COUNT_EXTRA(2, 1);
MOVE_COUNT_EXTRA(0, 1);
#endif
#endif
reset();
@ -504,7 +476,7 @@ namespace unnecessary_copy_tests {
// No move should take place.
// (since a is already in the container)
reset();
x.emplace(boost::move(a));
x.emplace(std::move(a));
COPY_COUNT(0);
MOVE_COUNT(0);
@ -542,10 +514,8 @@ namespace unnecessary_copy_tests {
COPY_COUNT(0);
MOVE_COUNT(0);
#if BOOST_UNORDERED_TUPLE_ARGS
reset();
x.emplace(boost::unordered::piecewise_construct,
x.emplace(std::piecewise_construct,
std::make_tuple(std::ref(b.first)), std::make_tuple(std::ref(b.second)));
COPY_COUNT(0);
MOVE_COUNT(0);
@ -559,23 +529,17 @@ namespace unnecessary_copy_tests {
std::pair<count_copies const, count_copies> move_source;
reset();
x.emplace(boost::unordered::piecewise_construct,
x.emplace(std::piecewise_construct,
std::make_tuple(std::move(move_source.first)),
std::make_tuple(std::move(move_source.second)));
COPY_COUNT(tuple_copy_cost);
MOVE_COUNT(tuple_move_cost);
#if !defined(BOOST_NO_CXX11_HDR_TUPLE) && \
!(defined(__GNUC__) && __GNUC__ == 4 && __GNUC_MINOR__ < 6) && \
!(defined(BOOST_MSVC) && BOOST_MSVC < 1700)
reset();
x.emplace(boost::unordered::piecewise_construct,
x.emplace(std::piecewise_construct,
std::forward_as_tuple(b.first), std::forward_as_tuple(b.second));
COPY_COUNT(0);
MOVE_COUNT(0);
#endif
#endif
}
}