Compare commits
163 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 57546ed7e3 | |||
| 6067d9e515 | |||
| ad4f00a825 | |||
| d1c166558a | |||
| d8a75accff | |||
| cdb31c8309 | |||
| f48ae7f7f4 | |||
| 843d6df58c | |||
| 95f36f334d | |||
| 3f4d5fc567 | |||
| 9a2483dd2c | |||
| cd9a592f00 | |||
| aa67315922 | |||
| 21937249c4 | |||
| 5dd2068b62 | |||
| 85098f0506 | |||
| 1b0037135c | |||
| f734e399e3 | |||
| 2afef71107 | |||
| 35bdabf259 | |||
| 1ebe692957 | |||
| 111a503195 | |||
| 5206ac46a3 | |||
| 0bca47c690 | |||
| 7f9aa8505f | |||
| ae364ea311 | |||
| f415d17e58 | |||
| 10fd6c8647 | |||
| 45e50f6cd2 | |||
| 600dd0a8e2 | |||
| a6a0cd0a13 | |||
| a39cf60e93 | |||
| a14b159665 | |||
| 793fad5620 | |||
| c117f4448f | |||
| 65f3ea60dd | |||
| 7645e4f20d | |||
| cd4c1f3713 | |||
| 32ce058ebe | |||
| 4c6d0211fb | |||
| 1edbe3fdbe | |||
| 42579dee10 | |||
| 0928b3d016 | |||
| 5d7786b47e | |||
| 228fede498 | |||
| 1d1f0d306d | |||
| 7ddd562532 | |||
| 3ad8ac4c34 | |||
| ac1a2b4d23 | |||
| e354fb432b | |||
| 88535dca1f | |||
| d61719a196 | |||
| e3818afd45 | |||
| 3d9b24019d | |||
| 0387791dc1 | |||
| a166a56401 | |||
| 4126a56528 | |||
| 3c53fe5db9 | |||
| cfa3cb2d1f | |||
| cffd0a413e | |||
| 8b40aef85f | |||
| 9995c9beb0 | |||
| 5827bf2574 | |||
| 38acf9c619 | |||
| a2f760f320 | |||
| 39d86cb896 | |||
| 317d4aa060 | |||
| 901f0a29b8 | |||
| 0a66c687fd | |||
| 763a862928 | |||
| 27ead86b36 | |||
| 485101db9b | |||
| 29521c3a77 | |||
| be1f493a6e | |||
| 401b06663f | |||
| 7e9032c703 | |||
| f77bdb9b67 | |||
| e5d89f1a15 | |||
| 8630a588bd | |||
| 6745d67d62 | |||
| 87e0e52cf7 | |||
| 475acdc351 | |||
| 93f33c336b | |||
| d46e83296c | |||
| a527745ff8 | |||
| 86f622240d | |||
| 4c0aea983e | |||
| 28fc689011 | |||
| 22d8cca03b | |||
| 390efc275f | |||
| c1317cb5be | |||
| 223f64752d | |||
| 37451ecc94 | |||
| 3868496ac9 | |||
| 8452b30608 | |||
| d121c91c88 | |||
| 6212f2642c | |||
| d5605671bd | |||
| 45c51840f7 | |||
| 90ca4fb07e | |||
| 83ab4b4b9f | |||
| 04006547a2 | |||
| 7b0e4da61e | |||
| 0c1b719945 | |||
| ee77a65fae | |||
| 3b2eae07d4 | |||
| b0c480839b | |||
| 6215406c02 | |||
| e588e04a1b | |||
| d01ae76074 | |||
| 5feb7459ee | |||
| 83abd9cc4e | |||
| 648f6fd23e | |||
| 2d8fd43cc4 | |||
| a0f86fc2d2 | |||
| 5800b0630d | |||
| 9806e75cc9 | |||
| 76c460a703 | |||
| 18797a3f32 | |||
| 1ecb92deb5 | |||
| 443113840d | |||
| b07cee08c4 | |||
| 05b66e1034 | |||
| e712c37e9f | |||
| a1f9097f2b | |||
| 73582be563 | |||
| f177f437b9 | |||
| fb41bdc82d | |||
| 7c84969249 | |||
| 553ce263fa | |||
| e63853d87d | |||
| e816ba511c | |||
| 82ba55e4a4 | |||
| 626db552ab | |||
| 5d16a36921 | |||
| 16732c5c4c | |||
| a3873dc19b | |||
| 5e6b9291de | |||
| ccf9a76ebe | |||
| 89515ee604 | |||
| 15cfef6967 | |||
| 7692065552 | |||
| bbad4735aa | |||
| 1d25c1c053 | |||
| 260418e4ee | |||
| aff242dbaf | |||
| 4e6d4ade6c | |||
| 4fbe450a65 | |||
| bd5c9fc740 | |||
| f411968ffd | |||
| be7c63e1bf | |||
| 1df37051ae | |||
| c4dbda0f78 | |||
| fa895edac2 | |||
| 43186b04d1 | |||
| 67c5cdb3a6 | |||
| 75a94781d5 | |||
| 76185abe80 | |||
| 0d2751c5e1 | |||
| f493603f5c | |||
| 74ca1b0e74 | |||
| 7b16324869 | |||
| 6680e86b38 |
@@ -31,123 +31,168 @@ environment:
|
||||
B2_VARIANT: debug,release
|
||||
|
||||
matrix:
|
||||
- FLAVOR: Visual Studio 2015
|
||||
- FLAVOR: VS2015 (32 bit)
|
||||
APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2015
|
||||
B2_TOOLSET: msvc-14.0
|
||||
B2_ADDRESS_MODEL: 32
|
||||
|
||||
- FLAVOR: Visual Studio 2017, C++14
|
||||
- FLAVOR: VS2015 (64 bit)
|
||||
APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2015
|
||||
B2_TOOLSET: msvc-14.0
|
||||
B2_ADDRESS_MODEL: 64
|
||||
|
||||
- FLAVOR: VS2017 (32 bit, C++14, Debug)
|
||||
APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2017
|
||||
B2_CXXSTD: 14
|
||||
B2_TOOLSET: msvc-14.1
|
||||
B2_ADDRESS_MODEL: 32
|
||||
B2_VARIANT: debug
|
||||
|
||||
- FLAVOR: Visual Studio 2017, C++17
|
||||
- FLAVOR: VS2017 (32 bit, C++17, Release)
|
||||
APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2017
|
||||
B2_CXXSTD: 17
|
||||
B2_TOOLSET: msvc-14.1
|
||||
B2_ADDRESS_MODEL: 32
|
||||
B2_VARIANT: release
|
||||
|
||||
- FLAVOR: Visual Studio 2017, C++latest
|
||||
- FLAVOR: VS2017 (32 bit, C++latest, Debug)
|
||||
APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2017
|
||||
B2_CXXSTD: latest
|
||||
B2_TOOLSET: msvc-14.1
|
||||
B2_ADDRESS_MODEL: 32
|
||||
B2_VARIANT: debug
|
||||
|
||||
- FLAVOR: cygwin (32-bit, C++11)
|
||||
- FLAVOR: VS2017 (64 bit, C++14, Release)
|
||||
APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2017
|
||||
B2_CXXSTD: 14
|
||||
B2_TOOLSET: msvc-14.1
|
||||
B2_ADDRESS_MODEL: 64
|
||||
B2_VARIANT: release
|
||||
|
||||
- FLAVOR: VS2017 (64 bit, C++17, Debug)
|
||||
APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2017
|
||||
B2_CXXSTD: 17
|
||||
B2_TOOLSET: msvc-14.1
|
||||
B2_ADDRESS_MODEL: 64
|
||||
B2_VARIANT: debug
|
||||
|
||||
- FLAVOR: VS2017 (64 bit, C++latest, Release)
|
||||
APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2017
|
||||
B2_CXXSTD: latest
|
||||
B2_TOOLSET: msvc-14.1
|
||||
B2_ADDRESS_MODEL: 64
|
||||
B2_VARIANT: release
|
||||
|
||||
- FLAVOR: Cygwin (32 bit, C++11, Release)
|
||||
APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2017
|
||||
ADDPATH: C:\cygwin\bin;
|
||||
B2_ADDRESS_MODEL: 32
|
||||
B2_CXXSTD: 11
|
||||
B2_TOOLSET: gcc
|
||||
B2_VARIANT: release
|
||||
|
||||
- FLAVOR: cygwin (32-bit, C++14)
|
||||
- FLAVOR: Cygwin (32 bit, C++14, Debug)
|
||||
APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2017
|
||||
ADDPATH: C:\cygwin\bin;
|
||||
B2_ADDRESS_MODEL: 32
|
||||
B2_CXXSTD: 14
|
||||
B2_TOOLSET: gcc
|
||||
B2_VARIANT: debug
|
||||
|
||||
- FLAVOR: cygwin (32-bit, C++1z)
|
||||
- FLAVOR: Cygwin (32 bit, C++1z, Release)
|
||||
APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2017
|
||||
ADDPATH: C:\cygwin\bin;
|
||||
B2_ADDRESS_MODEL: 32
|
||||
B2_CXXSTD: 1z
|
||||
B2_TOOLSET: gcc
|
||||
B2_VARIANT: release
|
||||
|
||||
- FLAVOR: cygwin (64-bit, latest, C++11)
|
||||
- FLAVOR: Cygwin (64 bit, C++11, Debug)
|
||||
APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2022
|
||||
ADDPATH: C:\cygwin64\bin;
|
||||
B2_ADDRESS_MODEL: 64
|
||||
B2_CXXSTD: 11
|
||||
B2_TOOLSET: gcc
|
||||
B2_FLAGS: "include=libs/unordered/test/unordered include=libs/unordered/test/exception"
|
||||
B2_VARIANT: release
|
||||
B2_VARIANT: debug
|
||||
|
||||
- FLAVOR: cygwin (64-bit, latest, C++14)
|
||||
- FLAVOR: Cygwin (64 bit, C++14, Debug)
|
||||
APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2022
|
||||
ADDPATH: C:\cygwin64\bin;
|
||||
B2_ADDRESS_MODEL: 64
|
||||
B2_CXXSTD: 14
|
||||
B2_TOOLSET: gcc
|
||||
B2_FLAGS: "include=libs/unordered/test/unordered include=libs/unordered/test/exception"
|
||||
B2_VARIANT: release
|
||||
B2_VARIANT: debug
|
||||
|
||||
- FLAVOR: cygwin (64-bit, latest, C++1z)
|
||||
- FLAVOR: Cygwin (64 bit, C++17, Debug)
|
||||
APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2022
|
||||
ADDPATH: C:\cygwin64\bin;
|
||||
B2_ADDRESS_MODEL: 64
|
||||
B2_CXXSTD: 1z
|
||||
B2_CXXSTD: 17
|
||||
B2_TOOLSET: gcc
|
||||
B2_FLAGS: "include=libs/unordered/test/unordered include=libs/unordered/test/exception"
|
||||
B2_VARIANT: release
|
||||
B2_VARIANT: debug
|
||||
|
||||
- FLAVOR: mingw-w64, 32 bit, C++11
|
||||
- FLAVOR: Cygwin (64 bit, C++2a, Debug)
|
||||
APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2022
|
||||
ADDPATH: C:\cygwin64\bin;
|
||||
B2_ADDRESS_MODEL: 64
|
||||
B2_CXXSTD: 2a
|
||||
B2_TOOLSET: gcc
|
||||
B2_FLAGS: "include=libs/unordered/test/unordered include=libs/unordered/test/exception"
|
||||
B2_VARIANT: debug
|
||||
|
||||
- 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;
|
||||
B2_CXXSTD: 11
|
||||
B2_TOOLSET: gcc
|
||||
B2_ADDRESS_MODEL: 32
|
||||
|
||||
- FLAVOR: mingw-w64, 32 bit, C++14
|
||||
- FLAVOR: MinGW-w64 (32 bit, C++14)
|
||||
APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2019
|
||||
ADDPATH: C:\mingw-w64\i686-8.1.0-posix-dwarf-rt_v6-rev0\mingw32\bin;
|
||||
B2_CXXSTD: 14
|
||||
B2_TOOLSET: gcc
|
||||
B2_ADDRESS_MODEL: 32
|
||||
|
||||
- FLAVOR: mingw-w64, 32 bit, C++17
|
||||
- FLAVOR: MinGW-w64 (32 bit, C++17)
|
||||
APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2019
|
||||
ADDPATH: C:\mingw-w64\i686-8.1.0-posix-dwarf-rt_v6-rev0\mingw32\bin;
|
||||
B2_CXXSTD: 17
|
||||
B2_TOOLSET: gcc
|
||||
B2_ADDRESS_MODEL: 32
|
||||
|
||||
- FLAVOR: mingw-w64, 32 bit, C++2a
|
||||
- FLAVOR: MinGW-w64 (32 bit, C++2a)
|
||||
APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2019
|
||||
ADDPATH: C:\mingw-w64\i686-8.1.0-posix-dwarf-rt_v6-rev0\mingw32\bin;
|
||||
B2_CXXSTD: 2a
|
||||
B2_TOOLSET: gcc
|
||||
B2_ADDRESS_MODEL: 32
|
||||
|
||||
- FLAVOR: mingw-w64, 64 bit, C++11
|
||||
- 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;
|
||||
B2_CXXSTD: 11
|
||||
B2_TOOLSET: gcc
|
||||
B2_ADDRESS_MODEL: 64
|
||||
|
||||
- FLAVOR: mingw-w64, 64 bit, C++14
|
||||
- FLAVOR: MinGW-w64 (64 bit, C++14)
|
||||
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: 14
|
||||
B2_TOOLSET: gcc
|
||||
B2_ADDRESS_MODEL: 64
|
||||
|
||||
- FLAVOR: mingw-w64, 64 bit, C++17
|
||||
- FLAVOR: MinGW-w64 (64 bit, C++17)
|
||||
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: 17
|
||||
B2_TOOLSET: gcc
|
||||
B2_ADDRESS_MODEL: 64
|
||||
|
||||
- FLAVOR: mingw-w64, 64 bit, C++2a
|
||||
- FLAVOR: MinGW-w64 (64 bit, C++2a)
|
||||
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: 2a
|
||||
|
||||
@@ -30,6 +30,7 @@ local linux_pipeline(name, image, environment, packages = "", sources = [], arch
|
||||
name: "everything",
|
||||
image: image,
|
||||
environment: environment,
|
||||
privileged: true,
|
||||
commands:
|
||||
[
|
||||
'set -e',
|
||||
@@ -102,16 +103,16 @@ local windows_pipeline(name, image, environment, arch = "amd64") =
|
||||
[
|
||||
linux_pipeline(
|
||||
"Linux 14.04 GCC 4.8* 32/64",
|
||||
"cppalliance/droneubuntu1404:1",
|
||||
{ TOOLSET: 'gcc', COMPILER: 'g++', CXXSTD: '11', ADDRMD: '32,64' },
|
||||
"cppalliance/droneubuntu1604:1",
|
||||
{ TOOLSET: 'gcc', COMPILER: 'g++-4.8', CXXSTD: '11', ADDRMD: '32,64' },
|
||||
"g++-4.8-multilib",
|
||||
),
|
||||
|
||||
linux_pipeline(
|
||||
"Linux 14.04 GCC 4.9 32/64",
|
||||
"cppalliance/droneubuntu1404:1",
|
||||
"cppalliance/droneubuntu1604:1",
|
||||
{ TOOLSET: 'gcc', COMPILER: 'g++-4.9', CXXSTD: '11', ADDRMD: '32,64' },
|
||||
"g++-4.9-multilib",
|
||||
[ "ppa:ubuntu-toolchain-r/test" ],
|
||||
),
|
||||
|
||||
linux_pipeline(
|
||||
@@ -468,7 +469,7 @@ local windows_pipeline(name, image, environment, arch = "amd64") =
|
||||
windows_pipeline(
|
||||
"Windows VS2015 msvc-14.0",
|
||||
"cppalliance/dronevs2015",
|
||||
{ TOOLSET: 'msvc-14.0', CXXSTD: '14,latest' },
|
||||
{ TOOLSET: 'msvc-14.0', CXXSTD: '14,latest', 'B2_DONT_EMBED_MANIFEST': 1 },
|
||||
),
|
||||
|
||||
windows_pipeline(
|
||||
@@ -477,15 +478,33 @@ local windows_pipeline(name, image, environment, arch = "amd64") =
|
||||
{ TOOLSET: 'msvc-14.1', CXXSTD: '14,17,latest' },
|
||||
),
|
||||
|
||||
windows_pipeline(
|
||||
"Windows VS2017 msvc-14.1 permissive-",
|
||||
"cppalliance/dronevs2017",
|
||||
{ TOOLSET: 'msvc-14.1', CXXSTD: '14,17', CXXFLAGS: '/permissive-' },
|
||||
),
|
||||
|
||||
windows_pipeline(
|
||||
"Windows VS2019 msvc-14.2",
|
||||
"cppalliance/dronevs2019",
|
||||
{ TOOLSET: 'msvc-14.2', CXXSTD: '14,17,20,latest' },
|
||||
),
|
||||
|
||||
windows_pipeline(
|
||||
"Windows VS2019 msvc-14.2 permissive-",
|
||||
"cppalliance/dronevs2019",
|
||||
{ TOOLSET: 'msvc-14.2', CXXSTD: '14,17', CXXFLAGS: '/permissive-' },
|
||||
),
|
||||
|
||||
windows_pipeline(
|
||||
"Windows VS2022 msvc-14.3",
|
||||
"cppalliance/dronevs2022:1",
|
||||
{ TOOLSET: 'msvc-14.3', CXXSTD: '14,17,20,latest' },
|
||||
),
|
||||
|
||||
windows_pipeline(
|
||||
"Windows VS2022 msvc-14.3 permissive-",
|
||||
"cppalliance/dronevs2022:1",
|
||||
{ TOOLSET: 'msvc-14.3', CXXSTD: '14,17', CXXFLAGS: '/permissive-' },
|
||||
),
|
||||
]
|
||||
|
||||
@@ -20,4 +20,5 @@ b2 -d0 headers
|
||||
|
||||
if not "%CXXSTD%" == "" set CXXSTD=cxxstd=%CXXSTD%
|
||||
if not "%ADDRMD%" == "" set ADDRMD=address-model=%ADDRMD%
|
||||
b2 --abbreviate-paths -j3 libs/%LIBRARY%/test toolset=%TOOLSET% %CXXSTD% %ADDRMD% variant=debug,release embed-manifest-via=linker
|
||||
if not "%CXXFLAGS%" == "" set CXXFLAGS=cxxflags=%CXXFLAGS%
|
||||
b2 --abbreviate-paths -j3 libs/%LIBRARY%/test toolset=%TOOLSET% %CXXSTD% %ADDRMD% %CXXFLAGS% variant=debug,release embed-manifest-via=linker
|
||||
|
||||
@@ -14,6 +14,11 @@ DRONE_BUILD_DIR=$(pwd)
|
||||
BOOST_BRANCH=develop
|
||||
if [ "$DRONE_BRANCH" = "master" ]; then BOOST_BRANCH=master; fi
|
||||
|
||||
if [[ $(uname) == "Linux" && ( "$TSAN" == 1 || "$ASAN" == 1 ) ]]; then
|
||||
echo 0 | sudo tee /proc/sys/kernel/randomize_va_space
|
||||
sudo sysctl vm.mmap_rnd_bits=28
|
||||
fi
|
||||
|
||||
cd ..
|
||||
git clone -b $BOOST_BRANCH --depth 1 https://github.com/boostorg/boost.git boost-root
|
||||
cd boost-root
|
||||
|
||||
@@ -107,10 +107,10 @@ jobs:
|
||||
- { 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: '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' }
|
||||
- { compiler: clang, cxxstd: '11,14,17,20,2b', os: 'macos-14' }
|
||||
|
||||
timeout-minutes: 360
|
||||
# posix (gcc-12 w/ sanitizers is taking longer than 210 minutes
|
||||
@@ -244,6 +244,8 @@ jobs:
|
||||
- name: Upload coverage
|
||||
if: matrix.coverage
|
||||
run: ci/codecov.sh "upload"
|
||||
env:
|
||||
CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }}
|
||||
|
||||
- name: Run coverity
|
||||
if: matrix.coverity && github.event_name == 'push' && (github.ref_name == 'develop' || github.ref_name == 'master')
|
||||
@@ -265,6 +267,7 @@ jobs:
|
||||
- { toolset: msvc-14.3, cxxstd: '14,17,20,latest', addrmd: '32,64', os: 'windows-2022', variant: 'debug,release' }
|
||||
- { 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: msvc-14.3, cxxstd: '14,17', addrmd: '32,64', os: 'windows-2022', variant: 'debug,release', cxxflags: '/permissive-' }
|
||||
- { toolset: clang-win, cxxstd: '14,17,latest', addrmd: '32,64', os: 'windows-2022', variant: 'debug,release' }
|
||||
- { toolset: gcc, cxxstd: '11,14,17,2a', addrmd: '64', os: 'windows-2019', variant: 'debug,release' }
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
# Distributed under the Boost Software License, Version 1.0.
|
||||
# https://www.boost.org/LICENSE_1_0.txt
|
||||
|
||||
cmake_minimum_required(VERSION 3.5...3.20)
|
||||
cmake_minimum_required(VERSION 3.8...3.20)
|
||||
|
||||
project(boost_unordered VERSION "${BOOST_SUPERPROJECT_VERSION}" LANGUAGES CXX)
|
||||
|
||||
@@ -18,16 +18,22 @@ target_link_libraries(boost_unordered
|
||||
Boost::config
|
||||
Boost::container_hash
|
||||
Boost::core
|
||||
Boost::move
|
||||
Boost::mp11
|
||||
Boost::predef
|
||||
Boost::preprocessor
|
||||
Boost::static_assert
|
||||
Boost::throw_exception
|
||||
Boost::tuple
|
||||
Boost::type_traits
|
||||
)
|
||||
|
||||
if(CMAKE_VERSION VERSION_GREATER 3.18 AND CMAKE_GENERATOR MATCHES "Visual Studio")
|
||||
|
||||
file(GLOB_RECURSE boost_unordered_IDEFILES CONFIGURE_DEPENDS include/*.hpp)
|
||||
source_group(TREE ${PROJECT_SOURCE_DIR}/include FILES ${boost_unordered_IDEFILES} PREFIX "Header Files")
|
||||
list(APPEND boost_unordered_IDEFILES extra/boost_unordered.natvis)
|
||||
target_sources(boost_unordered PRIVATE ${boost_unordered_IDEFILES})
|
||||
|
||||
endif()
|
||||
|
||||
target_compile_features(boost_unordered INTERFACE cxx_std_11)
|
||||
|
||||
if(BUILD_TESTING AND EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/test/CMakeLists.txt")
|
||||
|
||||
add_subdirectory(test)
|
||||
|
||||
@@ -25,6 +25,10 @@ deviate from the standard in exchange for top performance.</ul>
|
||||
|
||||
<ul>High performance for multithreaded scenarios. Introducing a new non-standard, iterator-free API.</ul>
|
||||
|
||||
**`boost::concurrent_node_set` `boost::concurrent_node_map`**
|
||||
|
||||
<ul>Variations of <code>boost::concurrent_flat_(set|map)</code> providing pointer stability.</ul>
|
||||
|
||||
## Learn about Boost.Unordered
|
||||
|
||||
* [Online documentation](https://boost.org/libs/unordered)
|
||||
@@ -34,16 +38,18 @@ deviate from the standard in exchange for top performance.</ul>
|
||||
* [Inside `boost::unordered_flat_map`](https://bannalia.blogspot.com/2022/11/inside-boostunorderedflatmap.html)
|
||||
* [Inside `boost::concurrent_flat_map`](https://bannalia.blogspot.com/2023/07/inside-boostconcurrentflatmap.html)
|
||||
* [Bulk visitation in `boost::concurrent_flat_map`](https://bannalia.blogspot.com/2023/10/bulk-visitation-in-boostconcurrentflatm.html)
|
||||
|
||||
## Get the library
|
||||
* Debugging visualizers for Boost.Unordered:
|
||||
* [Natvis for boost::unordered_map, and how to use <Intrinsic> elements](https://blog.ganets.ky/NatvisForUnordered/)
|
||||
* [Natvis for boost::concurrent_flat_map, and why fancy pointers are hard](https://blog.ganets.ky/NatvisForUnordered2/)
|
||||
* [Visualizing boost::unordered_map in GDB, with pretty-printer customization points](https://blog.ganets.ky/PrettyPrinter/)
|
||||
|
||||
Boost.Unordered can be installed in a number of ways:
|
||||
|
||||
* [Download Boost](https://www.boost.org/users/download/) and you're ready to go (this is a header-only library requiring no building).
|
||||
* Using Conan 2: In case you don't have it yet, add an entry for Boost in your `conanfile.txt` (the example requires at least Boost 1.83):
|
||||
* Using Conan 2: In case you don't have it yet, add an entry for Boost in your `conanfile.txt` (the example requires at least Boost 1.86):
|
||||
```
|
||||
[requires]
|
||||
boost/[>=1.83.0]
|
||||
boost/[>=1.86.0]
|
||||
```
|
||||
<ul>If you're not using any compiled Boost library, the following will skip building altogether:</ul>
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
// Copyright 2021 Peter Dimov.
|
||||
// Copyright 2023 Joaquin M Lopez Munoz.
|
||||
// Copyright 2023-2024 Joaquin M Lopez Munoz.
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// https://www.boost.org/LICENSE_1_0.txt
|
||||
|
||||
@@ -25,6 +25,7 @@
|
||||
#include <iostream>
|
||||
#include <iomanip>
|
||||
#include <chrono>
|
||||
#include <type_traits>
|
||||
|
||||
using namespace std::chrono_literals;
|
||||
|
||||
@@ -341,7 +342,7 @@ template<> struct fnv1a_hash_impl<64>
|
||||
|
||||
struct fnv1a_hash: fnv1a_hash_impl< std::numeric_limits<std::size_t>::digits >
|
||||
{
|
||||
using is_avalanching = void;
|
||||
using is_avalanching = std::true_type;
|
||||
};
|
||||
|
||||
template<class K, class V> using std_unordered_map_fnv1a =
|
||||
|
||||
@@ -0,0 +1,343 @@
|
||||
// Copyright 2021 Peter Dimov.
|
||||
// Copyright 2023-2024 Joaquin M Lopez Munoz.
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// https://www.boost.org/LICENSE_1_0.txt
|
||||
|
||||
#define _SILENCE_CXX17_OLD_ALLOCATOR_MEMBERS_DEPRECATION_WARNING
|
||||
#define _SILENCE_CXX20_CISO646_REMOVED_WARNING
|
||||
|
||||
#define BOOST_UNORDERED_ENABLE_STATS
|
||||
|
||||
#include <boost/unordered/unordered_flat_map.hpp>
|
||||
#include <boost/core/detail/splitmix64.hpp>
|
||||
#include <boost/config.hpp>
|
||||
#include <unordered_map>
|
||||
#include <vector>
|
||||
#include <memory>
|
||||
#include <cstdint>
|
||||
#include <iostream>
|
||||
#include <iomanip>
|
||||
#include <chrono>
|
||||
#include <type_traits>
|
||||
|
||||
using namespace std::chrono_literals;
|
||||
|
||||
static void print_time( std::chrono::steady_clock::time_point & t1, char const* label, std::uint32_t s, std::size_t size )
|
||||
{
|
||||
auto t2 = std::chrono::steady_clock::now();
|
||||
|
||||
std::cout << label << ": " << ( t2 - t1 ) / 1ms << " ms (s=" << s << ", size=" << size << ")\n";
|
||||
|
||||
t1 = t2;
|
||||
}
|
||||
|
||||
constexpr unsigned N = 50'000;
|
||||
constexpr int K = 10;
|
||||
|
||||
static std::vector<std::string> indices1, indices2;
|
||||
|
||||
static std::string make_index( unsigned x )
|
||||
{
|
||||
char buffer[ 64 ];
|
||||
std::snprintf( buffer, sizeof(buffer), "pfx_%u_sfx", x );
|
||||
|
||||
return buffer;
|
||||
}
|
||||
|
||||
static std::string make_random_index( unsigned x )
|
||||
{
|
||||
char buffer[ 64 ];
|
||||
std::snprintf( buffer, sizeof(buffer), "pfx_%0*d_%u_sfx", x % 8 + 1, 0, x );
|
||||
|
||||
return buffer;
|
||||
}
|
||||
|
||||
static void init_indices()
|
||||
{
|
||||
indices1.reserve( N*2+1 );
|
||||
indices1.push_back( make_index( 0 ) );
|
||||
|
||||
for( unsigned i = 1; i <= N*2; ++i )
|
||||
{
|
||||
indices1.push_back( make_index( i ) );
|
||||
}
|
||||
|
||||
indices2.reserve( N*2+1 );
|
||||
indices2.push_back( make_index( 0 ) );
|
||||
|
||||
{
|
||||
boost::detail::splitmix64 rng;
|
||||
|
||||
for( unsigned i = 1; i <= N*2; ++i )
|
||||
{
|
||||
indices2.push_back( make_random_index( static_cast<std::uint32_t>( rng() ) ) );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
template<class Map> BOOST_NOINLINE void test_insert( Map& map, std::chrono::steady_clock::time_point & t1 )
|
||||
{
|
||||
for( unsigned i = 1; i <= N; ++i )
|
||||
{
|
||||
map.insert( { indices1[ i ], i } );
|
||||
}
|
||||
|
||||
print_time( t1, "Consecutive insert", 0, map.size() );
|
||||
|
||||
for( unsigned i = 1; i <= N; ++i )
|
||||
{
|
||||
map.insert( { indices2[ i ], i } );
|
||||
}
|
||||
|
||||
print_time( t1, "Random insert", 0, map.size() );
|
||||
|
||||
std::cout << std::endl;
|
||||
}
|
||||
|
||||
template<class Map> BOOST_NOINLINE void test_lookup( Map& map, std::chrono::steady_clock::time_point & t1 )
|
||||
{
|
||||
std::uint32_t s;
|
||||
|
||||
s = 0;
|
||||
|
||||
for( int j = 0; j < K; ++j )
|
||||
{
|
||||
for( unsigned i = 1; i <= N * 2; ++i )
|
||||
{
|
||||
auto it = map.find( indices1[ i ] );
|
||||
if( it != map.end() ) s += it->second;
|
||||
}
|
||||
}
|
||||
|
||||
print_time( t1, "Consecutive lookup", s, map.size() );
|
||||
|
||||
s = 0;
|
||||
|
||||
for( int j = 0; j < K; ++j )
|
||||
{
|
||||
for( unsigned i = 1; i <= N * 2; ++i )
|
||||
{
|
||||
auto it = map.find( indices2[ i ] );
|
||||
if( it != map.end() ) s += it->second;
|
||||
}
|
||||
}
|
||||
|
||||
print_time( t1, "Random lookup", s, map.size() );
|
||||
|
||||
std::cout << std::endl;
|
||||
}
|
||||
|
||||
template<class Map> BOOST_NOINLINE void test_iteration( Map& map, std::chrono::steady_clock::time_point & t1 )
|
||||
{
|
||||
auto it = map.begin();
|
||||
|
||||
while( it != map.end() )
|
||||
{
|
||||
if( it->second & 1 )
|
||||
{
|
||||
if constexpr( std::is_void_v< decltype( map.erase( it ) ) > )
|
||||
{
|
||||
map.erase( it++ );
|
||||
}
|
||||
else
|
||||
{
|
||||
it = map.erase( it );
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
++it;
|
||||
}
|
||||
}
|
||||
|
||||
print_time( t1, "Iterate and erase odd elements", 0, map.size() );
|
||||
|
||||
std::cout << std::endl;
|
||||
}
|
||||
|
||||
template<class Map> BOOST_NOINLINE void test_erase( Map& map, std::chrono::steady_clock::time_point & t1 )
|
||||
{
|
||||
for( unsigned i = 1; i <= N; ++i )
|
||||
{
|
||||
map.erase( indices1[ i ] );
|
||||
}
|
||||
|
||||
print_time( t1, "Consecutive erase", 0, map.size() );
|
||||
|
||||
for( unsigned i = 1; i <= N; ++i )
|
||||
{
|
||||
map.erase( indices2[ i ] );
|
||||
}
|
||||
|
||||
print_time( t1, "Random erase", 0, map.size() );
|
||||
|
||||
std::cout << std::endl;
|
||||
}
|
||||
|
||||
//
|
||||
|
||||
// All Unordered container use the same struct
|
||||
using stats = boost::unordered_flat_map<int, int>::stats;
|
||||
|
||||
struct record
|
||||
{
|
||||
std::string label_;
|
||||
long long time_;
|
||||
stats stats_;
|
||||
};
|
||||
|
||||
static std::vector<record> records;
|
||||
|
||||
template<template<class...> class Map> BOOST_NOINLINE void test( char const* label )
|
||||
{
|
||||
std::cout << label << ":\n\n";
|
||||
|
||||
Map<std::string, std::uint32_t> map;
|
||||
|
||||
auto t0 = std::chrono::steady_clock::now();
|
||||
auto t1 = t0;
|
||||
|
||||
test_insert( map, t1 );
|
||||
|
||||
record rec = { label, 0 };
|
||||
|
||||
test_lookup( map, t1 );
|
||||
test_iteration( map, t1 );
|
||||
test_lookup( map, t1 );
|
||||
test_erase( map, t1 );
|
||||
|
||||
auto tN = std::chrono::steady_clock::now();
|
||||
std::cout << "Total: " << ( tN - t0 ) / 1ms << " ms\n\n";
|
||||
|
||||
rec.time_ = ( tN - t0 ) / 1ms;
|
||||
rec.stats_ = map.get_stats();
|
||||
records.push_back( rec );
|
||||
}
|
||||
|
||||
//
|
||||
|
||||
template<class K, class V> using boost_unordered_flat_map =
|
||||
boost::unordered_flat_map<K, V, boost::hash<K>, std::equal_to<K>>;
|
||||
|
||||
// fnv1a_hash
|
||||
|
||||
template<int Bits> struct fnv1a_hash_impl;
|
||||
|
||||
template<> struct fnv1a_hash_impl<32>
|
||||
{
|
||||
std::size_t operator()( std::string const& s ) const
|
||||
{
|
||||
std::size_t h = 0x811C9DC5u;
|
||||
|
||||
char const * first = s.data();
|
||||
char const * last = first + s.size();
|
||||
|
||||
for( ; first != last; ++first )
|
||||
{
|
||||
h ^= static_cast<unsigned char>( *first );
|
||||
h *= 0x01000193ul;
|
||||
}
|
||||
|
||||
return h;
|
||||
}
|
||||
};
|
||||
|
||||
template<> struct fnv1a_hash_impl<64>
|
||||
{
|
||||
std::size_t operator()( std::string const& s ) const
|
||||
{
|
||||
std::size_t h = 0xCBF29CE484222325ull;
|
||||
|
||||
char const * first = s.data();
|
||||
char const * last = first + s.size();
|
||||
|
||||
for( ; first != last; ++first )
|
||||
{
|
||||
h ^= static_cast<unsigned char>( *first );
|
||||
h *= 0x00000100000001B3ull;
|
||||
}
|
||||
|
||||
return h;
|
||||
}
|
||||
};
|
||||
|
||||
struct fnv1a_hash: fnv1a_hash_impl< std::numeric_limits<std::size_t>::digits >
|
||||
{
|
||||
using is_avalanching = std::true_type;
|
||||
};
|
||||
|
||||
template<class K, class V> using boost_unordered_flat_map_fnv1a =
|
||||
boost::unordered_flat_map<K, V, fnv1a_hash, std::equal_to<K>>;
|
||||
|
||||
// slightly bad hash
|
||||
|
||||
struct slightly_bad_hash
|
||||
{
|
||||
using is_avalanching = std::true_type;
|
||||
|
||||
std::size_t operator()( std::string const& s ) const
|
||||
{
|
||||
std::size_t h = s.size();
|
||||
|
||||
for( auto ch: s )
|
||||
{
|
||||
h *= 0x811C9DC4u; // multiplicative factor is even!
|
||||
h += static_cast<std::size_t>( ch );
|
||||
}
|
||||
|
||||
return h;
|
||||
}
|
||||
};
|
||||
|
||||
template<class K, class V> using boost_unordered_flat_map_slightly_bad_hash =
|
||||
boost::unordered_flat_map<K, V, slightly_bad_hash, std::equal_to<K>>;
|
||||
|
||||
// bad hash
|
||||
|
||||
struct bad_hash
|
||||
{
|
||||
using is_avalanching = std::true_type;
|
||||
|
||||
std::size_t operator()( std::string const& s ) const
|
||||
{
|
||||
std::size_t h = s.size();
|
||||
|
||||
for( auto ch: s )
|
||||
{
|
||||
h *= 31;
|
||||
h += static_cast<std::size_t>( ch );
|
||||
}
|
||||
|
||||
return h;
|
||||
}
|
||||
};
|
||||
|
||||
template<class K, class V> using boost_unordered_flat_map_bad_hash =
|
||||
boost::unordered_flat_map<K, V, bad_hash, std::equal_to<K>>;
|
||||
|
||||
//
|
||||
|
||||
int main()
|
||||
{
|
||||
init_indices();
|
||||
|
||||
test<boost_unordered_flat_map>( "boost::unordered_flat_map" );
|
||||
test<boost_unordered_flat_map_fnv1a>( "boost::unordered_flat_map, FNV-1a" );
|
||||
test<boost_unordered_flat_map_slightly_bad_hash>( "boost::unordered_flat_map, slightly_bad_hash" );
|
||||
test<boost_unordered_flat_map_bad_hash>( "boost::unordered_flat_map, bad_hash" );
|
||||
|
||||
std::cout << "---\n\n";
|
||||
|
||||
for( auto const& x: records )
|
||||
{
|
||||
std::cout << std::setw( 46 ) << ( x.label_ + ": " ) << std::setw( 5 ) << x.time_ << " ms\n"
|
||||
<< std::setw( 46 ) << "insertion: "
|
||||
<< "probe length " << x.stats_.insertion.probe_length.average << "\n"
|
||||
<< std::setw( 46 ) << "successful lookup: "
|
||||
<< "probe length " << x.stats_.successful_lookup.probe_length.average
|
||||
<< ", num comparisons " << x.stats_.successful_lookup.num_comparisons.average << "\n"
|
||||
<< std::setw( 46 ) << "unsuccessful lookup: "
|
||||
<< "probe length " << x.stats_.unsuccessful_lookup.probe_length.average
|
||||
<< ", num comparisons " << x.stats_.unsuccessful_lookup.num_comparisons.average << "\n\n";
|
||||
}
|
||||
}
|
||||
@@ -1,5 +1,5 @@
|
||||
// Copyright 2021 Peter Dimov.
|
||||
// Copyright 2023 Joaquin M Lopez Munoz.
|
||||
// Copyright 2023-2024 Joaquin M Lopez Munoz.
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// https://www.boost.org/LICENSE_1_0.txt
|
||||
|
||||
@@ -26,6 +26,7 @@
|
||||
#include <iostream>
|
||||
#include <iomanip>
|
||||
#include <chrono>
|
||||
#include <type_traits>
|
||||
|
||||
using namespace std::chrono_literals;
|
||||
|
||||
@@ -342,7 +343,7 @@ template<> struct fnv1a_hash_impl<64>
|
||||
|
||||
struct fnv1a_hash: fnv1a_hash_impl< std::numeric_limits<std::size_t>::digits >
|
||||
{
|
||||
using is_avalanching = void;
|
||||
using is_avalanching = std::true_type;
|
||||
};
|
||||
|
||||
template<class K, class V> using std_unordered_map_fnv1a =
|
||||
|
||||
@@ -0,0 +1,26 @@
|
||||
# Copyright 2023-2024 René Ferdinand Rivera Morell
|
||||
# Copyright 2024 Peter Dimov
|
||||
# Distributed under the Boost Software License, Version 1.0.
|
||||
# https://www.boost.org/LICENSE_1_0.txt
|
||||
|
||||
require-b2 5.2 ;
|
||||
|
||||
constant boost_dependencies :
|
||||
/boost/assert//boost_assert
|
||||
/boost/config//boost_config
|
||||
/boost/container_hash//boost_container_hash
|
||||
/boost/core//boost_core
|
||||
/boost/mp11//boost_mp11
|
||||
/boost/predef//boost_predef
|
||||
/boost/throw_exception//boost_throw_exception
|
||||
;
|
||||
|
||||
project /boost/unordered ;
|
||||
|
||||
explicit
|
||||
[ alias boost_unordered : : : : <include>include <library>$(boost_dependencies) ]
|
||||
[ alias all : boost_unordered test ]
|
||||
;
|
||||
|
||||
call-if : boost-library unordered
|
||||
;
|
||||
|
Before Width: | Height: | Size: 31 KiB After Width: | Height: | Size: 30 KiB |
|
Before Width: | Height: | Size: 30 KiB After Width: | Height: | Size: 30 KiB |
|
Before Width: | Height: | Size: 31 KiB After Width: | Height: | Size: 30 KiB |
|
Before Width: | Height: | Size: 26 KiB After Width: | Height: | Size: 26 KiB |
|
Before Width: | Height: | Size: 25 KiB After Width: | Height: | Size: 25 KiB |
|
Before Width: | Height: | Size: 26 KiB After Width: | Height: | Size: 26 KiB |
|
Before Width: | Height: | Size: 25 KiB After Width: | Height: | Size: 26 KiB |
|
Before Width: | Height: | Size: 25 KiB After Width: | Height: | Size: 25 KiB |
|
Before Width: | Height: | Size: 26 KiB After Width: | Height: | Size: 25 KiB |
|
Before Width: | Height: | Size: 25 KiB After Width: | Height: | Size: 26 KiB |
|
Before Width: | Height: | Size: 25 KiB After Width: | Height: | Size: 26 KiB |
|
Before Width: | Height: | Size: 25 KiB After Width: | Height: | Size: 25 KiB |
|
Before Width: | Height: | Size: 28 KiB After Width: | Height: | Size: 27 KiB |
|
Before Width: | Height: | Size: 26 KiB After Width: | Height: | Size: 25 KiB |
|
Before Width: | Height: | Size: 28 KiB After Width: | Height: | Size: 29 KiB |
|
Before Width: | Height: | Size: 27 KiB After Width: | Height: | Size: 26 KiB |
|
Before Width: | Height: | Size: 26 KiB After Width: | Height: | Size: 25 KiB |
|
Before Width: | Height: | Size: 28 KiB After Width: | Height: | Size: 27 KiB |
|
Before Width: | Height: | Size: 25 KiB After Width: | Height: | Size: 26 KiB |
|
Before Width: | Height: | Size: 26 KiB After Width: | Height: | Size: 25 KiB |
|
Before Width: | Height: | Size: 26 KiB After Width: | Height: | Size: 26 KiB |
|
Before Width: | Height: | Size: 26 KiB After Width: | Height: | Size: 26 KiB |
|
Before Width: | Height: | Size: 26 KiB After Width: | Height: | Size: 26 KiB |
|
Before Width: | Height: | Size: 26 KiB After Width: | Height: | Size: 25 KiB |
|
Before Width: | Height: | Size: 28 KiB After Width: | Height: | Size: 29 KiB |
|
Before Width: | Height: | Size: 29 KiB After Width: | Height: | Size: 27 KiB |
|
Before Width: | Height: | Size: 29 KiB After Width: | Height: | Size: 28 KiB |
|
Before Width: | Height: | Size: 27 KiB After Width: | Height: | Size: 26 KiB |
|
Before Width: | Height: | Size: 27 KiB After Width: | Height: | Size: 27 KiB |
|
Before Width: | Height: | Size: 27 KiB After Width: | Height: | Size: 27 KiB |
|
Before Width: | Height: | Size: 27 KiB After Width: | Height: | Size: 26 KiB |
|
Before Width: | Height: | Size: 27 KiB After Width: | Height: | Size: 27 KiB |
|
Before Width: | Height: | Size: 25 KiB After Width: | Height: | Size: 26 KiB |
|
Before Width: | Height: | Size: 26 KiB After Width: | Height: | Size: 26 KiB |
|
Before Width: | Height: | Size: 26 KiB After Width: | Height: | Size: 26 KiB |
|
Before Width: | Height: | Size: 25 KiB After Width: | Height: | Size: 26 KiB |
|
Before Width: | Height: | Size: 27 KiB After Width: | Height: | Size: 28 KiB |
|
Before Width: | Height: | Size: 27 KiB After Width: | Height: | Size: 28 KiB |
|
Before Width: | Height: | Size: 25 KiB After Width: | Height: | Size: 26 KiB |
|
Before Width: | Height: | Size: 26 KiB After Width: | Height: | Size: 26 KiB |
|
Before Width: | Height: | Size: 26 KiB After Width: | Height: | Size: 26 KiB |
|
Before Width: | Height: | Size: 25 KiB After Width: | Height: | Size: 25 KiB |
|
Before Width: | Height: | Size: 47 KiB After Width: | Height: | Size: 47 KiB |
|
Before Width: | Height: | Size: 45 KiB After Width: | Height: | Size: 45 KiB |
|
Before Width: | Height: | Size: 45 KiB After Width: | Height: | Size: 45 KiB |
|
Before Width: | Height: | Size: 62 KiB After Width: | Height: | Size: 62 KiB |
|
Before Width: | Height: | Size: 57 KiB After Width: | Height: | Size: 56 KiB |
|
Before Width: | Height: | Size: 46 KiB After Width: | Height: | Size: 47 KiB |
|
Before Width: | Height: | Size: 48 KiB After Width: | Height: | Size: 47 KiB |
|
Before Width: | Height: | Size: 55 KiB After Width: | Height: | Size: 56 KiB |
|
Before Width: | Height: | Size: 51 KiB After Width: | Height: | Size: 52 KiB |
|
Before Width: | Height: | Size: 51 KiB After Width: | Height: | Size: 52 KiB |
|
Before Width: | Height: | Size: 45 KiB After Width: | Height: | Size: 44 KiB |
|
Before Width: | Height: | Size: 52 KiB After Width: | Height: | Size: 52 KiB |
|
Before Width: | Height: | Size: 57 KiB After Width: | Height: | Size: 56 KiB |
|
Before Width: | Height: | Size: 46 KiB After Width: | Height: | Size: 48 KiB |
|
Before Width: | Height: | Size: 46 KiB After Width: | Height: | Size: 45 KiB |
|
Before Width: | Height: | Size: 56 KiB After Width: | Height: | Size: 57 KiB |
|
Before Width: | Height: | Size: 52 KiB After Width: | Height: | Size: 52 KiB |
|
Before Width: | Height: | Size: 54 KiB After Width: | Height: | Size: 54 KiB |
|
Before Width: | Height: | Size: 50 KiB After Width: | Height: | Size: 46 KiB |
|
Before Width: | Height: | Size: 56 KiB After Width: | Height: | Size: 56 KiB |
|
Before Width: | Height: | Size: 42 KiB After Width: | Height: | Size: 42 KiB |
|
Before Width: | Height: | Size: 47 KiB After Width: | Height: | Size: 47 KiB |
|
Before Width: | Height: | Size: 46 KiB After Width: | Height: | Size: 46 KiB |
|
Before Width: | Height: | Size: 59 KiB After Width: | Height: | Size: 59 KiB |
|
Before Width: | Height: | Size: 46 KiB After Width: | Height: | Size: 46 KiB |
|
Before Width: | Height: | Size: 48 KiB After Width: | Height: | Size: 48 KiB |
|
Before Width: | Height: | Size: 43 KiB After Width: | Height: | Size: 43 KiB |
|
Before Width: | Height: | Size: 51 KiB After Width: | Height: | Size: 52 KiB |
|
Before Width: | Height: | Size: 33 KiB After Width: | Height: | Size: 32 KiB |
|
Before Width: | Height: | Size: 32 KiB After Width: | Height: | Size: 32 KiB |
|
Before Width: | Height: | Size: 33 KiB After Width: | Height: | Size: 33 KiB |
|
Before Width: | Height: | Size: 31 KiB After Width: | Height: | Size: 31 KiB |
|
Before Width: | Height: | Size: 33 KiB After Width: | Height: | Size: 33 KiB |
|
Before Width: | Height: | Size: 35 KiB After Width: | Height: | Size: 35 KiB |
|
Before Width: | Height: | Size: 33 KiB After Width: | Height: | Size: 33 KiB |
|
Before Width: | Height: | Size: 32 KiB After Width: | Height: | Size: 32 KiB |
|
Before Width: | Height: | Size: 33 KiB After Width: | Height: | Size: 34 KiB |
|
Before Width: | Height: | Size: 32 KiB After Width: | Height: | Size: 32 KiB |
|
Before Width: | Height: | Size: 33 KiB After Width: | Height: | Size: 33 KiB |
|
Before Width: | Height: | Size: 41 KiB After Width: | Height: | Size: 41 KiB |
|
Before Width: | Height: | Size: 36 KiB After Width: | Height: | Size: 36 KiB |
|
Before Width: | Height: | Size: 35 KiB After Width: | Height: | Size: 35 KiB |
|
Before Width: | Height: | Size: 40 KiB After Width: | Height: | Size: 40 KiB |
|
Before Width: | Height: | Size: 36 KiB After Width: | Height: | Size: 36 KiB |
|
Before Width: | Height: | Size: 36 KiB After Width: | Height: | Size: 35 KiB |
|
Before Width: | Height: | Size: 35 KiB After Width: | Height: | Size: 35 KiB |
|
Before Width: | Height: | Size: 33 KiB After Width: | Height: | Size: 33 KiB |