From 7822f1b991df27bc1754b9875fe042c54be51c97 Mon Sep 17 00:00:00 2001 From: sdarwin Date: Thu, 10 Dec 2020 21:59:29 +0000 Subject: [PATCH 01/73] update CI fix #31, fix #20 --- .appveyor.yml | 119 ++-- .azure-pipelines.yml | 276 --------- .codecov.yml | 25 + .drone.star | 117 ++++ .drone/drone.bat | 31 ++ .drone/drone.sh | 236 ++++++++ .github/workflows/ci.yml | 522 ++++++++++++++++++ .travis.yml | 275 --------- include/boost/static_string/static_string.hpp | 32 +- meta/libraries.json | 2 +- test/static_string.cpp | 4 + 11 files changed, 1017 insertions(+), 622 deletions(-) delete mode 100644 .azure-pipelines.yml create mode 100644 .codecov.yml create mode 100644 .drone.star create mode 100644 .drone/drone.bat create mode 100755 .drone/drone.sh create mode 100644 .github/workflows/ci.yml delete mode 100644 .travis.yml diff --git a/.appveyor.yml b/.appveyor.yml index be1bdda..7361f87 100644 --- a/.appveyor.yml +++ b/.appveyor.yml @@ -1,5 +1,6 @@ # Copyright 2016, 2017 Peter Dimov -# Copyright (C) 2017 - 2019 James E. King III +# Copyright 2017 - 2019 James E. King III +# Copyright 2019 - 2021 Alexander Grund # Distributed under the Boost Software License, Version 1.0. # (See accompanying file LICENSE_1_0.txt or copy at http://boost.org/LICENSE_1_0.txt) @@ -21,7 +22,7 @@ version: 1.0.{build}-{branch} -shallow_clone: true +shallow_clone: false branches: only: @@ -33,115 +34,101 @@ branches: - /pr\/.*/ matrix: + fast_finish: false # Adding MAYFAIL to any matrix job allows it to fail but the build stays green: allow_failures: - MAYFAIL: true environment: global: + B2_CI_VERSION: 1 + GIT_FETCH_JOBS: 4 # see: http://www.boost.org/build/doc/html/bbv2/overview/invocation.html#bbv2.overview.invocation.properties # to use the default for a given environment, comment it out; recommend you build debug and release however: # on Windows it is important to exercise all the possibilities, especially shared vs static, however most # libraries that care about this exercise it in their Jamfiles... - # B2_ADDRESS_MODEL: address-model=64,32 - # B2_LINK: link=shared,static + B2_ADDRESS_MODEL: 32,64 + B2_LINK: shared,static # B2_THREADING: threading=multi,single - B2_VARIANT: variant=release + B2_VARIANT: release matrix: + - FLAVOR: Visual Studio 2022 + APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2022 + B2_CXXFLAGS: -permissive- + B2_CXXSTD: 14,17,20 + B2_TOOLSET: msvc-14.3 + - FLAVOR: Visual Studio 2019 APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2019 - B2_ADDRESS_MODEL: address-model=64 - B2_CXXFLAGS: cxxflags=-permissive- - B2_CXXSTD: 17 # 2a + B2_CXXFLAGS: -permissive- + B2_CXXSTD: 14,17,2a B2_TOOLSET: msvc-14.2 - FLAVOR: Visual Studio 2017 C++2a Strict APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2017 - B2_ADDRESS_MODEL: address-model=64 - B2_CXXFLAGS: cxxflags=-permissive- - B2_CXXSTD: 17 # 2a - B2_TOOLSET: msvc-14.1 - - - FLAVOR: Visual Studio 2017 C++17 - APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2017 - B2_ADDRESS_MODEL: address-model=64 - B2_CXXSTD: 17 + B2_CXXFLAGS: -permissive- + B2_CXXSTD: 2a B2_TOOLSET: msvc-14.1 - B2_VARIANT: variant=debug - - FLAVOR: Visual Studio 2017 C++14 (Default) + - FLAVOR: Visual Studio 2017 C++14/17 APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2017 - B2_ADDRESS_MODEL: address-model=64,32 + B2_CXXSTD: 14,17 B2_TOOLSET: msvc-14.1 - FLAVOR: clang-cl - APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2017 - B2_ADDRESS_MODEL: address-model=64 - B2_CXXSTD: 11 + APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2019 + ADDCOMMANDS: '"C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\VC\Auxiliary\Build\vcvars64.bat"' + B2_ADDRESS_MODEL: 64 + B2_CXXSTD: 11,14,17 B2_TOOLSET: clang-win - - FLAVOR: Visual Studio 2015 C++14 (Default) - APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2015 - B2_ADDRESS_MODEL: address-model=64,32 - B2_TOOLSET: msvc-14.0 - B2_VARIANT: variant=debug + # not supported + # - FLAVOR: Visual Studio 2015, 2013 + # APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2015 + # B2_TOOLSET: msvc-12.0,msvc-14.0 - - FLAVOR: Visual Studio 2010, 2012, 2013 - APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2015 - B2_TOOLSET: msvc-10.0,msvc-11.0,msvc-12.0 + # - FLAVOR: Visual Studio 2008, 2010, 2012 + # APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2015 + # B2_TOOLSET: msvc-9.0,msvc-10.0,msvc-11.0 + # B2_ADDRESS_MODEL: 32 # No 64bit support - FLAVOR: cygwin (32-bit) APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2017 ADDPATH: C:\cygwin\bin; - B2_ADDRESS_MODEL: address-model=32 - B2_CXXSTD: 03,11 - # https://github.com/boostorg/test/issues/144 - B2_DEFINES: define=_POSIX_C_SOURCE=200112L - B2_THREADING: threadapi=pthread + B2_ADDRESS_MODEL: 32 + B2_CXXSTD: 11,14,1z B2_TOOLSET: gcc - B2_VARIANT: variant=debug - FLAVOR: cygwin (64-bit) APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2017 ADDPATH: C:\cygwin64\bin; - B2_ADDRESS_MODEL: address-model=64 - B2_CXXSTD: 11,17 - # https://github.com/boostorg/test/issues/144 - B2_DEFINES: define=_POSIX_C_SOURCE=200112L define=__USE_ISOC99 - B2_THREADING: threadapi=pthread + B2_ADDRESS_MODEL: 64 + B2_CXXSTD: 11,14,1z B2_TOOLSET: gcc - FLAVOR: mingw32 - APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2017 - ARCH: i686 - B2_ADDRESS_MODEL: address-model=32 - B2_CXXSTD: 03,11 - SCRIPT: ci\appveyor\mingw.bat - B2_VARIANT: variant=debug + APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2019 + B2_ADDRESS_MODEL: 32 + ADDPATH: C:\mingw\bin; + B2_CXXSTD: 11,14,17,2a + B2_TOOLSET: gcc - FLAVOR: mingw64 - APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2017 - ARCH: x86_64 - B2_ADDRESS_MODEL: address-model=64 - B2_CXXSTD: 11,17 - B2_DEFINES: define=__USE_ISOC99 - SCRIPT: ci\appveyor\mingw.bat + APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2019 + ADDPATH: C:\mingw-w64\x86_64-8.1.0-posix-seh-rt_v6-rev0\mingw64\bin; + B2_ADDRESS_MODEL: 64 + B2_CXXSTD: 11,14,17,2a + B2_TOOLSET: gcc install: - - set SELF=%APPVEYOR_PROJECT_NAME:-=_% - - git clone https://github.com/boostorg/boost-ci.git C:\boost-ci - - xcopy /s /e /q /i C:\boost-ci\ci .\ci + - '%ADDCOMMANDS%' + - git clone --depth 1 https://github.com/boostorg/boost-ci.git C:\boost-ci-cloned + # Copy ci folder if not testing Boost.CI + - if NOT "%APPVEYOR_PROJECT_NAME%" == "boost-ci" xcopy /s /e /q /i /y C:\boost-ci-cloned\ci .\ci + - rmdir /s /q C:\boost-ci-cloned - ci\appveyor\install.bat build: off -test_script: - - set SELF=%APPVEYOR_PROJECT_NAME:-=_% - - PATH=%ADDPATH%%PATH% - # The definition of B2_TOOLCXX omits B2_CXXSTD= if it was not defined above - - IF NOT DEFINED B2_CXXSTD (SET B2_TOOLCXX=toolset=%B2_TOOLSET%) ELSE (SET B2_TOOLCXX=toolset=%B2_TOOLSET% cxxstd=%B2_CXXSTD%) - # Echo the complete build command to the build log - - IF NOT DEFINED SCRIPT (ECHO b2 libs/%SELF:\=/% %B2_TOOLCXX% %B2_CXXFLAGS% %B2_DEFINES% %B2_THREADING% %B2_ADDRESS_MODEL% %B2_LINK% %B2_THREADING% %B2_VARIANT% -j3) - # Now go build... - - IF DEFINED SCRIPT (call libs\%SELF%\%SCRIPT%) ELSE (b2 libs/%SELF:\=/% %B2_TOOLCXX% %B2_CXXFLAGS% %B2_DEFINES% %B2_THREADING% %B2_ADDRESS_MODEL% %B2_LINK% %B2_THREADING% %B2_VARIANT% -j3) +test_script: ci\build.bat diff --git a/.azure-pipelines.yml b/.azure-pipelines.yml deleted file mode 100644 index f976de3..0000000 --- a/.azure-pipelines.yml +++ /dev/null @@ -1,276 +0,0 @@ -# Copyright 2015-2019 Rene Rivera. -# Copyright 2019 Mateusz Loskot -# Distributed under the Boost Software License, Version 1.0. -# (See accompanying file LICENSE_1_0.txt or copy at http://boost.org/LICENSE_1_0.txt) - -# -# Generic Azure Pipelines build script for boostorg repositories -# See: https://github.com/boostorg/boost-ci/ -# -# Instructions for customizing this script for your library: -# -# 1. Customize the compilers and language levels you want. -# 2. If you have more than include/, src/, test/, example/, examples/, -# benchmark/ or tools/ directories, set the environment variable DEPINST. -# For example if your build uses code in "bench/" and "fog/" directories: -# - DEPINST: --include bench --include fog -# 3. Enable pull request builds in your boostorg/ account. -# -# That's it - the script will do everything else for you. - -trigger: - branches: - include: - - develop - - master - - bugfix/* - - feature/* - - fix/* - - pr/* - -pr: - branches: - include: - - develop - -variables: - - name: B2_VARIANT - value: variant=release,debug - -stages: - -- stage: Test - jobs: - - - job: 'Linux' - pool: - vmImage: 'ubuntu-16.04' - strategy: - matrix: - GCC 8: - B2_TOOLSET: gcc - B2_CXXSTD: 14,17 - CXX: g++-8 - PACKAGES: g++-8 - GCC 7: - B2_TOOLSET: gcc - B2_CXXSTD: 11,14,17 - CXX: g++-7 - PACKAGES: g++-7 - GCC 6: - B2_TOOLSET: gcc - B2_CXXSTD: 11,14 - CXX: g++-6 - PACKAGES: g++-6 - GCC 5: - B2_TOOLSET: gcc - B2_CXXSTD: 11 - CXX: g++-5 - PACKAGES: g++-5 - GCC 4.9: - B2_TOOLSET: gcc - B2_CXXSTD: 11 - CXX: g++-4.9 - PACKAGES: g++-4.9 - GCC 4.8: - B2_TOOLSET: gcc - B2_CXXSTD: 11 - CXX: g++-4.8 - PACKAGES: g++-4.8 - Clang 8: - B2_TOOLSET: clang - B2_CXXSTD: 14,17 - CXX: clang++-8 - PACKAGES: clang-8 - LLVM_REPO: llvm-toolchain-xenial-8 - Clang 7: - B2_TOOLSET: clang - B2_CXXSTD: 14,17 - CXX: clang++-7 - PACKAGES: clang-7 - LLVM_REPO: llvm-toolchain-xenial-7 - Clang 6: - B2_TOOLSET: clang - B2_CXXSTD: 14,17 - CXX: clang++-6.0 - PACKAGES: clang-6.0 - LLVM_REPO: llvm-toolchain-xenial-6.0 - Clang 5: - B2_TOOLSET: clang - B2_CXXSTD: 11,14,17 - PACKAGES: clang-5.0 - CXX: clang++-5.0 - LLVM_REPO: llvm-toolchain-xenial-5.0 - Clang 4: - B2_TOOLSET: clang - B2_CXXSTD: 11,14,17 - CXX: clang++-4.0 - PACKAGES: clang-4.0 - LLVM_REPO: llvm-toolchain-xenial-4.0 - Clang 3.9: - B2_TOOLSET: clang - B2_CXXSTD: 11,14 - CXX: clang++-3.9 - PACKAGES: clang-3.9 - Clang 3.8: - B2_TOOLSET: clang - CXX: clang++-3.8 - B2_CXXSTD: 11,14 - PACKAGES: clang-3.8 - Clang 3.7: - B2_TOOLSET: clang - B2_CXXSTD: 11 - CXX: clang++-3.7 - PACKAGES: clang-3.7 - Clang 3.6: - B2_TOOLSET: clang - B2_CXXSTD: 11 - CXX: clang++-3.6 - PACKAGES: clang-3.6 - Clang 3.5: - B2_TOOLSET: clang - B2_CXXSTD: 11 - CXX: clang++-3.5 - PACKAGES: clang-3.5 - steps: - - bash: | - set -e - uname -a - sudo -E apt-add-repository -y "ppa:ubuntu-toolchain-r/test" - if test -n "${LLVM_REPO}" ; then - wget -O - https://apt.llvm.org/llvm-snapshot.gpg.key | sudo apt-key add - - sudo -E apt-add-repository "deb http://apt.llvm.org/xenial/ ${LLVM_REPO} main" - fi - sudo -E apt-get update - sudo -E apt-get -yq --no-install-suggests --no-install-recommends install ${PACKAGES} - - git clone --branch master https://github.com/boostorg/boost-ci.git boost-ci - cp -pr boost-ci/ci boost-ci/.codecov.yml . - rm -rf boost-ci - source ci/azure-pipelines/install.sh - - # AzP requires to run special task in order to export - # SELF and BOOST_ROOT as job-scoped variable from a script. - # NOTE: Disable set -x is necessary, see the troubleshooting guide - # on "Variables having ' (single quote) appended": - # https://docs.microsoft.com/en-us/azure/devops/pipelines/troubleshooting - set +x - echo "##vso[task.setvariable variable=SELF]"$SELF - echo "##vso[task.setvariable variable=BOOST_ROOT]"$BOOST_ROOT - set -x - displayName: 'Install' - - bash: | - set -e - echo "SELF=$SELF" - echo "BOOST_ROOT=$BOOST_ROOT" - - cd $BOOST_ROOT/libs/$SELF - ci/azure-pipelines/build.sh --debug-configuration - displayName: 'Build' - - - job: 'Windows' - strategy: - matrix: - VS 2019 C++17 Strict: - B2_TOOLSET: msvc-14.2 - B2_CXXSTD: 17 - B2_CXXFLAGS: cxxflags=-permissive- - B2_ADDRESS_MODEL: address-model=64 - VM_IMAGE: 'windows-2019' - VS 2017 C++17 Strict: - B2_TOOLSET: msvc-14.1 - B2_CXXSTD: 17 - B2_CXXFLAGS: cxxflags=-permissive- - B2_ADDRESS_MODEL: address-model=64 - VM_IMAGE: 'vs2017-win2016' - VS 2017 C++17: - B2_TOOLSET: msvc-14.1 - B2_CXXSTD: 17 - B2_ADDRESS_MODEL: address-model=64,32 - VM_IMAGE: 'vs2017-win2016' - VS 2017 C++14: - B2_TOOLSET: msvc-14.1 - #B2_CXXSTD: 14 # default - B2_ADDRESS_MODEL: address-model=64,32 - VM_IMAGE: 'vs2017-win2016' - - pool: - vmImage: $(VM_IMAGE) - steps: - - script: | - set SELF=%BUILD_REPOSITORY_NAME:-=_% - for /f "tokens=2 delims=/" %%a in ("%SELF%") do set SELF=%%a - set BOOST_ROOT=%BUILD_SOURCESDIRECTORY%\boost-root - - git clone --branch master https://github.com/boostorg/boost-ci.git boost-ci - xcopy /s /e /q /i boost-ci\ci .\ci - cmd /k ci\azure-pipelines\install.bat - - echo ##vso[task.setvariable variable=SELF]%SELF% - echo ##vso[task.setvariable variable=BOOST_ROOT]%BOOST_ROOT% - displayName: 'Install' - - script: | - PATH=%ADDPATH%%PATH% - REM The definition of B2_TOOLCXX omits B2_CXXSTD= if it was not defined above - IF NOT DEFINED B2_CXXSTD (SET B2_TOOLCXX=toolset=%B2_TOOLSET%) ELSE (SET B2_TOOLCXX=toolset=%B2_TOOLSET% cxxstd=%B2_CXXSTD%) - cd %BOOST_ROOT% - ECHO b2 libs/%SELF:\=/% %B2_TOOLCXX% %B2_CXXFLAGS% %B2_DEFINES% %B2_THREADING% %B2_ADDRESS_MODEL% %B2_LINK% %B2_THREADING% %B2_VARIANT% -j3 - b2 libs/%SELF:\=/% %B2_TOOLCXX% %B2_CXXFLAGS% %B2_DEFINES% %B2_THREADING% %B2_ADDRESS_MODEL% %B2_LINK% %B2_THREADING% %B2_VARIANT% -j3 - displayName: 'Build' - - - job: 'macOS' - pool: - vmImage: 'macOS-10.14' - strategy: - matrix: - Xcode_11_3_1: - B2_TOOLSET: clang - B2_CXXSTD: 14,17,2a - XCODE_APP: /Applications/Xcode_11.3.1.app - Xcode_11_2_1: - B2_TOOLSET: clang - B2_CXXSTD: 14,17,2a - XCODE_APP: /Applications/Xcode_11.2.1.app - Xcode_11_2: - B2_TOOLSET: clang - B2_CXXSTD: 14,17,2a - XCODE_APP: /Applications/Xcode_11.2.app - Xcode_11_1: - B2_TOOLSET: clang - B2_CXXSTD: 14,17,2a - XCODE_APP: /Applications/Xcode_11.1.app - Xcode_10_3: - B2_TOOLSET: clang - B2_CXXSTD: 11,14,17,2a - XCODE_APP: /Applications/Xcode_10.3.app - Xcode_10_2_1: - B2_TOOLSET: clang - B2_CXXSTD: 11,14,17,2a - XCODE_APP: /Applications/Xcode_10.2.1.app - Xcode_10_2: - B2_TOOLSET: clang - B2_CXXSTD: 11,14,17,2a - XCODE_APP: /Applications/Xcode_10.2.app - Xcode_10_1: - B2_TOOLSET: clang - B2_CXXSTD: 11,14,17,2a - XCODE_APP: /Applications/Xcode_10.1.app - Xcode_10_0: - B2_TOOLSET: clang - B2_CXXSTD: 11,14,17,2a - XCODE_APP: /Applications/Xcode_10.app - steps: - - bash: | - set -e - git clone --branch master https://github.com/boostorg/boost-ci.git boost-ci-cloned - cp -prf boost-ci-cloned/ci . - rm -rf boost-ci-cloned - source ci/azure-pipelines/install.sh - displayName: Install - - bash: | - set -e - echo "SELF=$SELF" - echo "BOOST_ROOT=$BOOST_ROOT" - cd $BOOST_ROOT/libs/$SELF - ci/azure-pipelines/build.sh - displayName: 'Build' \ No newline at end of file diff --git a/.codecov.yml b/.codecov.yml new file mode 100644 index 0000000..4e80d1c --- /dev/null +++ b/.codecov.yml @@ -0,0 +1,25 @@ +# Copyright 2019 - 2021 Alexander Grund +# Distributed under the Boost Software License, Version 1.0. +# (See accompanying file LICENSE_1_0.txt or copy at http://boost.org/LICENSE_1_0.txt) +# +# Sample codecov configuration file. Edit as required + +codecov: + max_report_age: off + require_ci_to_pass: yes + notify: + # Increase this if you have multiple coverage collection jobs + after_n_builds: 1 + wait_for_ci: yes + +# Change how pull request comments look +comment: + layout: "reach,diff,flags,files,footer" + +# Ignore specific files or folders. Glob patterns are supported. +# See https://docs.codecov.com/docs/ignoring-paths +ignore: + - extra/* + - extra/**/* + - test/* + - test/**/* diff --git a/.drone.star b/.drone.star new file mode 100644 index 0000000..7cedae0 --- /dev/null +++ b/.drone.star @@ -0,0 +1,117 @@ +# Use, modification, and distribution are +# subject to the Boost Software License, Version 1.0. (See accompanying +# file LICENSE.txt) +# +# Copyright Rene Rivera 2020. +# Copyright Alan de Freitas 2022. + + +# For Drone CI we use the Starlark scripting language to reduce duplication. +# As the yaml syntax for Drone CI is rather limited. +# +# +globalenv={'B2_CI_VERSION': '1', 'B2_VARIANT': 'release'} +linuxglobalimage="cppalliance/droneubuntu1804:1" +windowsglobalimage="cppalliance/dronevs2019" + +def main(ctx): + return [ + # Priorities: (no 2a, no betas) + # + # coverage + # latest gcc: 17,20 + # latest clang: 17,20 + # oldest gcc: 11 + # oldest clang: 11 + # asan + # tsan + # ubsan + # valgrind + # arm64 + # s390x + # docs + # cmake superproject + # cmake install + # (...the rest) + + # Coverage + linux_cxx("Coverage", "g++-8", packages="g++-8", buildscript="drone", buildtype="codecov", image=linuxglobalimage, environment={'COMMENT': 'codecov.io', 'LCOV_BRANCH_COVERAGE': '0', 'B2_CXXSTD': '11', 'B2_TOOLSET': 'gcc-8', 'B2_DEFINES': 'BOOST_NO_STRESS_TEST=1', "CODECOV_TOKEN": {"from_secret": "codecov_token"}, "COVERALLS_REPO_TOKEN": {"from_secret": "coveralls_repo_token"}}, globalenv=globalenv), + + # Latest gcc + linux_cxx("GCC 12: C++17,20", "g++-12", packages="g++-12", buildscript="drone", buildtype="boost", image="cppalliance/droneubuntu2204:1", environment={'B2_TOOLSET': 'gcc-12', 'B2_CXXFLAGS': '-Werror -Wno-error=restrict', 'B2_CXXSTD': '17,20'}, globalenv=globalenv), + linux_cxx("GCC 12: C++17,20 Standalone", "g++-12", packages="g++-12", buildscript="drone", buildtype="boost", image="cppalliance/droneubuntu2204:1", environment={'B2_TOOLSET': 'gcc-12', 'B2_CXXFLAGS': '-Werror -Wno-error=restrict', 'B2_DEFINES': 'define=BOOST_STATIC_STRING_STANDALONE', 'B2_CXXSTD': '17,20'}, globalenv=globalenv), + + # Latest clang + linux_cxx("Clang 15: C++17,20", "clang++-15", packages="clang-15 libstdc++-10-dev", llvm_os="jammy", llvm_ver="15", buildscript="drone", buildtype="boost", image="cppalliance/droneubuntu2204:1", environment={'B2_TOOLSET': 'clang-15', 'B2_CXXFLAGS': '-Werror', 'B2_CXXSTD': '17,20'}, globalenv=globalenv), + linux_cxx("Clang 15: C++17,20 Standalone", "clang++-15", packages="clang-15 libstdc++-10-dev", llvm_os="jammy", llvm_ver="15", buildscript="drone", buildtype="boost", image="cppalliance/droneubuntu2204:1", environment={'B2_TOOLSET': 'clang-15', 'B2_CXXFLAGS': '-Werror', 'B2_DEFINES': 'define=BOOST_STATIC_STRING_STANDALONE', 'B2_CXXSTD': '17,20'}, globalenv=globalenv), + + # Oldest compilers + linux_cxx("GCC 4.8: C++11", "g++-4.8", packages="g++-4.8", buildscript="drone", buildtype="boost", image="cppalliance/droneubuntu1604:1", environment={'B2_TOOLSET': 'gcc-4.8', 'B2_CXXFLAGS': '-Werror', 'B2_CXXSTD': '11'}, globalenv=globalenv), + linux_cxx("GCC 4.8: C++11 Standalone", "g++-4.8", packages="g++-4.8", buildscript="drone", buildtype="boost", image="cppalliance/droneubuntu1604:1", environment={'B2_TOOLSET': 'gcc-4.8', 'B2_CXXFLAGS': '-Werror', 'B2_DEFINES': 'define=BOOST_STATIC_STRING_STANDALONE', 'B2_CXXSTD': '11'}, globalenv=globalenv), + linux_cxx("Clang 3.8: C++11", "clang++-3.8", packages="clang-3.8", buildscript="drone", buildtype="boost", image="cppalliance/droneubuntu1604:1", environment={'B2_VARIANT': 'debug', 'B2_CXXFLAGS': '-Werror', 'B2_TOOLSET': 'clang-3.8', 'B2_CXXSTD': '11'}, globalenv=globalenv), + linux_cxx("Clang 3.8: C++11 Standalone", "clang++-3.8", packages="clang-3.8", buildscript="drone", buildtype="boost", image="cppalliance/droneubuntu1604:1", environment={'B2_VARIANT': 'debug', 'B2_CXXFLAGS': '-Werror', 'B2_TOOLSET': 'clang-3.8', 'B2_DEFINES': 'define=BOOST_STATIC_STRING_STANDALONE', 'B2_CXXSTD': '11'}, globalenv=globalenv), + + # Sanitizers + Valgrind + linux_cxx("ASan", "g++-12", packages="g++-12", buildscript="drone", buildtype="boost", image="cppalliance/droneubuntu2204:1", environment={'COMMENT': 'asan', 'B2_VARIANT': 'debug', 'B2_TOOLSET': 'gcc-12', 'B2_CXXSTD': '11,14,17', 'B2_ASAN': '1', 'B2_DEFINES': 'BOOST_NO_STRESS_TEST=1', 'DRONE_EXTRA_PRIVILEGED': 'True'}, globalenv=globalenv, privileged=True), + linux_cxx("TSan", "g++-12", packages="g++-12", buildscript="drone", buildtype="boost", image="cppalliance/droneubuntu2204:1", environment={'COMMENT': 'tsan', 'B2_VARIANT': 'debug', 'B2_TOOLSET': 'gcc-12', 'B2_CXXSTD': '11,14,17', 'B2_TSAN': '1', 'B2_DEFINES': 'BOOST_NO_STRESS_TEST=1'}, globalenv=globalenv), + linux_cxx("UBSan", "g++-12", packages="g++-12", buildscript="drone", buildtype="boost", image="cppalliance/droneubuntu2204:1", environment={'COMMENT': 'ubsan', 'B2_VARIANT': 'debug', 'B2_TOOLSET': 'gcc-12', 'B2_CXXSTD': '11,14,17', 'B2_UBSAN': '1', 'B2_DEFINES': 'define=BOOST_NO_STRESS_TEST=1', 'B2_LINKFLAGS': '-fuse-ld=gold'}, globalenv=globalenv), + linux_cxx("Valgrind", "clang++-14", packages="clang-14 libc6-dbg libc++-dev libstdc++-9-dev", llvm_os="jammy", llvm_ver="14", buildscript="drone", buildtype="valgrind", image="cppalliance/droneubuntu2204:1", environment={'COMMENT': 'valgrind', 'B2_TOOLSET': 'clang-14', 'B2_CXXSTD': '11,14,17', 'B2_DEFINES': 'BOOST_NO_STRESS_TEST=1', 'B2_VARIANT': 'debug', 'B2_TESTFLAGS': 'testing.launcher=valgrind', 'VALGRIND_OPTS': '--error-exitcode=1'}, globalenv=globalenv), + + # arm64 (unsigned char) + linux_cxx("ARM64: GCC 11", "g++-11", packages="g++-11", buildscript="drone", buildtype="boost", image="cppalliance/droneubuntu2004:multiarch", environment={'B2_TOOLSET': 'gcc-11', 'B2_CXXFLAGS': '-Werror -Wno-error=array-bounds -Wno-error=restrict -Wno-error=stringop-overflow', 'B2_CXXSTD': '17,20'}, arch="arm64", globalenv=globalenv), + + # s390x + linux_cxx("S390x: Clang 12", "clang++-12", packages="clang-12 libstdc++-9-dev", llvm_os="focal", llvm_ver="12", buildtype="boost", buildscript="drone", image="cppalliance/droneubuntu2004:multiarch", environment={'B2_TOOLSET': 'clang-12', 'B2_CXXFLAGS': '-Werror', 'B2_CXXSTD': '17,20'}, arch="s390x", globalenv=globalenv), + + # Documentation + # linux_cxx("Docs", "g++", packages="docbook docbook-xml docbook-xsl xsltproc libsaxonhe-java default-jre-headless flex libfl-dev bison unzip rsync", buildtype="docs", buildscript="drone", image="cppalliance/droneubuntu1804:1", environment={'COMMENT': 'docs'}, globalenv=globalenv), + + # CMake tests (https://github.com/boostorg/boost-ci) + ## Compiling as part of the boost superproject + linux_cxx("CMake Superproject", "g++", packages="", buildscript="drone", buildtype="cmake-superproject", image="cppalliance/droneubuntu1804:1", globalenv=globalenv), + ## Installing + # linux_cxx("CMake Install", "g++", packages="", buildscript="drone", buildtype="cmake1", image="cppalliance/droneubuntu1804:1", environment={'CMAKE_INSTALL_TEST': '1'}, globalenv=globalenv), + + # ------------------------------------------------------------------ + + # OSX + osx_cxx("OSX: Clang", "g++", packages="", buildscript="drone", buildtype="boost", xcode_version="13.4.1", environment={'B2_TOOLSET': 'clang', 'B2_CXXFLAGS': '-Werror', 'B2_CXXSTD': '11,17'}, globalenv=globalenv), + + # GCC (All other versions) + linux_cxx("GCC 4.9: C++11", "g++-4.9", packages="g++-4.9", buildscript="drone", buildtype="boost", image="cppalliance/droneubuntu1604:1", environment={'B2_TOOLSET': 'gcc-4.9', 'B2_CXXFLAGS': '-Werror', 'B2_CXXSTD': '11'}, globalenv=globalenv), + linux_cxx("GCC 5: C++11", "g++-5", packages="g++-5", buildscript="drone", buildtype="boost", image=linuxglobalimage, environment={'B2_TOOLSET': 'gcc-5', 'B2_CXXFLAGS': '-Werror', 'B2_CXXSTD': '11'}, globalenv=globalenv), + linux_cxx("GCC 6: C++11,14", "g++-6", packages="g++-6", buildscript="drone", buildtype="boost", image=linuxglobalimage, environment={'B2_TOOLSET': 'gcc-6', 'B2_CXXFLAGS': '-Werror -Wno-error=unused-function', 'B2_CXXSTD': '11,14'}, globalenv=globalenv), + linux_cxx("GCC 7: C++14,17", "g++-7", packages="g++-7", buildscript="drone", buildtype="boost", image=linuxglobalimage, environment={'B2_TOOLSET': 'gcc-7', 'B2_CXXFLAGS': '-Werror -Wno-error=unused-function -Wno-error=noexcept-type', 'B2_CXXSTD': '14,17'}, globalenv=globalenv), + linux_cxx("GCC 8: C++17", "g++-8", packages="g++-8", buildscript="drone", buildtype="boost", image=linuxglobalimage, environment={'B2_TOOLSET': 'gcc-8', 'B2_CXXFLAGS': '-Werror -Wno-error=unused-function -Wno-error=array-bounds', 'B2_CXXSTD': '17'}, globalenv=globalenv), + linux_cxx("GCC 9: C++17", "g++-9", packages="g++-9", buildscript="drone", buildtype="boost", image=linuxglobalimage, environment={'B2_TOOLSET': 'gcc-9', 'B2_CXXFLAGS': '-Werror', 'B2_CXXSTD': '17'}, globalenv=globalenv), + linux_cxx("GCC 10: C++17", "g++-10", packages="g++-10", buildscript="drone", buildtype="boost", image=linuxglobalimage, environment={'B2_TOOLSET': 'gcc-10', 'B2_CXXFLAGS': '-Werror -funsigned-char -Wno-error=array-bounds', 'B2_CXXSTD': '17'}, globalenv=globalenv), + linux_cxx("GCC 11: C++17,20", "g++-11", packages="g++-11", buildscript="drone", buildtype="boost", image=linuxglobalimage, environment={'B2_TOOLSET': 'gcc-11', 'B2_CXXFLAGS': '-Werror -Wno-error=array-bounds -Wno-error=stringop-overflow', 'B2_CXXSTD': '17,20'}, globalenv=globalenv), + + # Clang (All other versions) + linux_cxx("Clang 4.0: C++11,14", "clang++-4.0", packages="clang-4.0 libstdc++-6-dev", llvm_os="xenial", llvm_ver="4.0", buildscript="drone", buildtype="boost", image="cppalliance/droneubuntu1804:1", environment={'B2_TOOLSET': 'clang-4.0', 'B2_CXXFLAGS': '', 'B2_CXXSTD': '11,14'}, globalenv=globalenv), + linux_cxx("Clang 5.0: C++11,14", "clang++-5.0", packages="clang-5.0 libstdc++-7-dev", llvm_os="bionic", llvm_ver="5.0", buildscript="drone", buildtype="boost", image=linuxglobalimage, environment={'B2_TOOLSET': 'clang-5.0', 'B2_CXXFLAGS': '', 'B2_CXXSTD': '11,14'}, globalenv=globalenv), + linux_cxx("Clang 6.0: C++11,14", "clang++-6.0", packages="clang-6.0 libc6-dbg libc++-dev libc++abi-dev libstdc++-8-dev", llvm_os="bionic", llvm_ver="6.0", buildscript="drone", buildtype="boost", image=linuxglobalimage, environment={'B2_TOOLSET': 'clang-6.0', 'B2_CXXFLAGS': '-Werror', 'B2_CXXSTD': '11,14', 'B2_STDLIB': 'libc++'}, globalenv=globalenv), + linux_cxx("Clang 6.0: C++14,17", "clang++-6.0", packages="clang-6.0 libc6-dbg libc++-dev libc++abi-dev libstdc++-8-dev", llvm_os="bionic", llvm_ver="6.0", buildscript="drone", buildtype="boost", image=linuxglobalimage, environment={'B2_TOOLSET': 'clang-6.0', 'B2_CXXFLAGS': '-Werror', 'B2_CXXSTD': '14,17'}, globalenv=globalenv), + linux_cxx("Clang 7: C++17", "clang++-7", packages="clang-7 libc6-dbg libc++-dev libstdc++-8-dev", llvm_os="bionic", llvm_ver="7", buildscript="drone", buildtype="boost", image=linuxglobalimage, environment={'B2_TOOLSET': 'clang-7', 'B2_CXXFLAGS': '-Werror', 'B2_CXXSTD': '17'}, globalenv=globalenv), + linux_cxx("Clang 8: C++17", "clang++-8", packages="clang-8 libc6-dbg libc++-dev libstdc++-8-dev", llvm_os="bionic", llvm_ver="8", buildscript="drone", buildtype="boost", image=linuxglobalimage, environment={'B2_TOOLSET': 'clang-8', 'B2_CXXFLAGS': '-Werror', 'B2_CXXSTD': '17'}, globalenv=globalenv), + linux_cxx("Clang 9: C++14,17", "clang++-9", packages="clang-9 libstdc++-9-dev", llvm_os="bionic", llvm_ver="9", buildscript="drone", buildtype="boost", image=linuxglobalimage, environment={'B2_TOOLSET': 'clang-9', 'B2_CXXFLAGS': '-Werror', 'B2_CXXSTD': '14,17'}, globalenv=globalenv), + linux_cxx("Clang 10: C++14,17", "clang++-10", packages="clang-10 libstdc++-9-dev", llvm_os="focal", llvm_ver="10", buildscript="drone", buildtype="boost", image="cppalliance/droneubuntu2004:1", environment={'B2_TOOLSET': 'clang-10', 'B2_CXXFLAGS': '-Werror -funsigned-char', 'B2_CXXSTD': '14,17'}, globalenv=globalenv), + linux_cxx("Clang 11: C++14,17", "clang++-11", packages="clang-11 libstdc++-9-dev", llvm_os="focal", llvm_ver="11", buildscript="drone", buildtype="boost", image="cppalliance/droneubuntu2004:1", environment={'B2_TOOLSET': 'clang-11', 'B2_CXXFLAGS': '-Werror', 'B2_CXXSTD': '14,17'}, globalenv=globalenv), + linux_cxx("Clang 12: C++17,20", "clang++-12", packages="clang-12 libstdc++-9-dev", llvm_os="focal", llvm_ver="12", buildscript="drone", buildtype="boost", image="cppalliance/droneubuntu2004:1", environment={'B2_TOOLSET': 'clang-12', 'B2_CXXFLAGS': '-Werror', 'B2_CXXSTD': '17,20'}, globalenv=globalenv), + linux_cxx("Clang 13: C++17,20", "clang++-13", packages="clang-13 libstdc++-10-dev", llvm_os="jammy", llvm_ver="13", buildscript="drone", buildtype="boost", image="cppalliance/droneubuntu2204:1", environment={'B2_TOOLSET': 'clang-13', 'B2_CXXFLAGS': '-Werror', 'B2_CXXSTD': '17,20'}, globalenv=globalenv), + linux_cxx("Clang 14: C++17,20", "clang++-14", packages="clang-14 libstdc++-10-dev", llvm_os="jammy", llvm_ver="14", buildscript="drone", buildtype="boost", image="cppalliance/droneubuntu2204:1", environment={'B2_TOOLSET': 'clang-14', 'B2_CXXFLAGS': '-Werror', 'B2_CXXSTD': '17,20'}, globalenv=globalenv), + + # arm64 (unsigned char) + linux_cxx("ARM64: Clang 12", "clang++-12", packages="clang-12 libstdc++-9-dev", llvm_os="focal", llvm_ver="12", buildscript="drone", buildtype="boost", image="cppalliance/droneubuntu2004:multiarch", environment={'B2_TOOLSET': 'clang-12', 'B2_CXXFLAGS': '-Werror', 'B2_CXXSTD': '11,14,17,20'}, arch="arm64", globalenv=globalenv), + + # s390x + linux_cxx("S390x: GCC 11", "g++-11", packages="g++-11", buildtype="boost", buildscript="drone", image="cppalliance/droneubuntu2004:multiarch", environment={'B2_TOOLSET': 'gcc-11', 'B2_CXXFLAGS': '-Werror -Wno-error=array-bounds', 'B2_CXXSTD': '17'}, arch="s390x", globalenv=globalenv), + + # MSVC + windows_cxx("MSVC 14.1", "", image="cppalliance/dronevs2017", buildtype="boost", buildscript="drone", environment={"B2_TOOLSET": "msvc-14.1", 'B2_CXXFLAGS': '/WX', "B2_CXXSTD": "11,14,17"},globalenv=globalenv), + windows_cxx("MSVC 14.2: C++14,17,latest", "", image="cppalliance/dronevs2019", buildtype="boost", buildscript="drone", environment={"B2_TOOLSET": "msvc-14.2", 'B2_CXXFLAGS': '/WX', "B2_CXXSTD": "14,17,latest"},globalenv=globalenv), + windows_cxx("MSVC 14.3: C++17,20", "", image="cppalliance/dronevs2022", buildtype="boost", buildscript="drone", environment={"B2_TOOLSET": "msvc-14.3", 'B2_CXXFLAGS': '/WX', "B2_CXXSTD": "17,20"},globalenv=globalenv), +] + +# from https://github.com/boostorg/boost-ci +load("@boost_ci//ci/drone/:functions.star", "linux_cxx","windows_cxx","osx_cxx","freebsd_cxx") diff --git a/.drone/drone.bat b/.drone/drone.bat new file mode 100644 index 0000000..0dc0d6c --- /dev/null +++ b/.drone/drone.bat @@ -0,0 +1,31 @@ + +@ECHO ON +setlocal enabledelayedexpansion + +if "%DRONE_JOB_BUILDTYPE%" == "boost" ( + +echo '==================================> INSTALL' + +git clone https://github.com/boostorg/boost-ci.git boost-ci-cloned --depth 1 +cp -prf boost-ci-cloned/ci . +rm -rf boost-ci-cloned +REM source ci/travis/install.sh +REM The contents of install.sh below: + +for /F %%i in ("%DRONE_REPO%") do @set SELF=%%~nxi +SET BOOST_CI_TARGET_BRANCH=%DRONE_COMMIT_BRANCH% +SET BOOST_CI_SRC_FOLDER=%cd% + +call ci\common_install.bat + +echo '==================================> COMPILE' + +REM set B2_TARGETS=libs/!SELF!/test libs/!SELF!/example +set B2_TARGETS=libs/!SELF!/test +call !BOOST_ROOT!\libs\!SELF!\ci\build.bat + +) else if "%DRONE_JOB_BUILDTYPE%" == "standalone-windows" ( + +REM not used + +) \ No newline at end of file diff --git a/.drone/drone.sh b/.drone/drone.sh new file mode 100755 index 0000000..05d7ecd --- /dev/null +++ b/.drone/drone.sh @@ -0,0 +1,236 @@ +#!/bin/bash + +# Copyright 2020 Rene Rivera, Sam Darwin +# Distributed under the Boost Software License, Version 1.0. +# (See accompanying file LICENSE.txt or copy at http://boost.org/LICENSE_1_0.txt) + +set -xe + +export TRAVIS_BUILD_DIR=$(pwd) +export DRONE_BUILD_DIR=$(pwd) +export TRAVIS_BRANCH=$DRONE_BRANCH +export TRAVIS_EVENT_TYPE=$DRONE_BUILD_EVENT +export VCS_COMMIT_ID=$DRONE_COMMIT +export GIT_COMMIT=$DRONE_COMMIT +export REPO_NAME=$DRONE_REPO +export USER=$(whoami) +export CC=${CC:-gcc} +export PATH=~/.local/bin:/usr/local/bin:$PATH + +common_install() { + git clone https://github.com/boostorg/boost-ci.git boost-ci-cloned --depth 1 + cp -prf boost-ci-cloned/ci . + rm -rf boost-ci-cloned + + if [ "$TRAVIS_OS_NAME" == "osx" ]; then + unset -f cd + fi + + export SELF=$(basename $REPO_NAME) + export BOOST_CI_TARGET_BRANCH="$TRAVIS_BRANCH" + export BOOST_CI_SRC_FOLDER=$(pwd) + + . ./ci/common_install.sh +} + +if [ "$DRONE_JOB_BUILDTYPE" == "boost" ]; then + + echo '==================================> INSTALL' + + common_install + + echo '==================================> SCRIPT' + + export B2_TARGETS=${B2_TARGETS:-"libs/$SELF/test"} + $BOOST_ROOT/libs/$SELF/ci/travis/build.sh + +elif [ "$DRONE_JOB_BUILDTYPE" == "docs" ]; then + + echo '==================================> INSTALL' + + export SELF=$(basename $REPO_NAME) + + pwd + cd .. + mkdir -p $HOME/cache && cd $HOME/cache + if [ ! -d doxygen ]; then git clone -b 'Release_1_8_15' --depth 1 https://github.com/doxygen/doxygen.git && echo "not-cached"; else echo "cached"; fi + cd doxygen + cmake -H. -Bbuild -DCMAKE_BUILD_TYPE=Release + cd build + sudo make install + cd ../.. + if [ ! -f saxonhe.zip ]; then wget -O saxonhe.zip https://sourceforge.net/projects/saxon/files/Saxon-HE/9.9/SaxonHE9-9-1-4J.zip/download && echo "not-cached"; else echo "cached"; fi + unzip -o saxonhe.zip + sudo rm /usr/share/java/Saxon-HE.jar + sudo cp saxon9he.jar /usr/share/java/Saxon-HE.jar + cd .. + BOOST_BRANCH=develop && [ "$TRAVIS_BRANCH" == "master" ] && BOOST_BRANCH=master || true + git clone -b $BOOST_BRANCH https://github.com/boostorg/boost.git boost-root --depth 1 + cd boost-root + export BOOST_ROOT=$(pwd) + git submodule update --init libs/context + git submodule update --init tools/boostbook + git submodule update --init tools/boostdep + git submodule update --init tools/docca + git submodule update --init tools/quickbook + rsync -av $TRAVIS_BUILD_DIR/ libs/$SELF + python tools/boostdep/depinst/depinst.py ../tools/quickbook + ./bootstrap.sh + ./b2 headers + + echo '==================================> SCRIPT' + + echo "using doxygen ; using boostbook ; using saxonhe ;" >tools/build/src/user-config.jam + ./b2 -j3 libs/$SELF/doc//boostrelease + +elif [ "$DRONE_JOB_BUILDTYPE" == "codecov" ]; then + + echo '==================================> INSTALL' + + common_install + + echo '==================================> SCRIPT' + + set +e + + cd $BOOST_ROOT/libs/$SELF + ci/travis/codecov.sh + + # coveralls + # uses multiple lcov steps from boost-ci codecov.sh script + if [ -n "${COVERALLS_REPO_TOKEN}" ]; then + echo "processing coveralls" + pip3 install --user cpp-coveralls + cd $BOOST_CI_SRC_FOLDER + + export PATH=/tmp/lcov/bin:$PATH + command -v lcov + lcov --version + + lcov --remove coverage.info -o coverage_filtered.info '*/test/*' '*/extra/*' + cpp-coveralls --verbose -l coverage_filtered.info + fi + +elif [ "$DRONE_JOB_BUILDTYPE" == "valgrind" ]; then + + echo '==================================> INSTALL' + + common_install + + echo '==================================> SCRIPT' + + cd $BOOST_ROOT/libs/$SELF + ci/travis/valgrind.sh + +elif [ "$DRONE_JOB_BUILDTYPE" == "standalone" ]; then + + echo '==================================> INSTALL' + + # Installing cmake with apt-get, so not required here: + # pip install --user cmake + + echo '==================================> SCRIPT' + + export CXXFLAGS="-Wall -Wextra -Werror -std=c++17" + mkdir __build_17 + cd __build_17 + cmake -DBOOST_JSON_STANDALONE=1 .. + cmake --build . + ctest -V . + export CXXFLAGS="-Wall -Wextra -Werror -std=c++2a" + mkdir ../__build_2a + cd ../__build_2a + cmake -DBOOST_JSON_STANDALONE=1 .. + cmake --build . + ctest -V . + +elif [ "$DRONE_JOB_BUILDTYPE" == "coverity" ]; then + + echo '==================================> INSTALL' + + common_install + + echo '==================================> SCRIPT' + + if [ -n "${COVERITY_SCAN_NOTIFICATION_EMAIL}" -a \( "$TRAVIS_BRANCH" = "develop" -o "$TRAVIS_BRANCH" = "master" \) -a \( "$DRONE_BUILD_EVENT" = "push" -o "$DRONE_BUILD_EVENT" = "cron" \) ]; then + cd $BOOST_ROOT/libs/$SELF + ci/travis/coverity.sh + fi + +elif [ "$DRONE_JOB_BUILDTYPE" == "cmake-superproject" ]; then + + echo '==================================> INSTALL' + + common_install + + echo '==================================> COMPILE' + + # May want to re-enable -Werror + # export CXXFLAGS="-Wall -Wextra -Werror" + export CXXFLAGS="-Wall -Wextra" + + mkdir __build_static + cd __build_static + cmake -DBOOST_ENABLE_CMAKE=1 -DBUILD_TESTING=ON -DBoost_VERBOSE=1 \ + -DBOOST_INCLUDE_LIBRARIES=$SELF .. + cmake --build . + ctest --output-on-failure -R boost_$SELF + + cd .. + + mkdir __build_shared + cd __build_shared + cmake -DBOOST_ENABLE_CMAKE=1 -DBUILD_TESTING=ON -DBoost_VERBOSE=1 \ + -DBOOST_INCLUDE_LIBRARIES=$SELF -DBUILD_SHARED_LIBS=ON .. + cmake --build . + ctest --output-on-failure -R boost_$SELF + +elif [ "$DRONE_JOB_BUILDTYPE" == "cmake1" ]; then + + echo '==================================> INSTALL' + + # https://github.com/opencv/opencv-python#frequently-asked-questions + pip install --upgrade pip + pip install --user cmake + + echo '==================================> SCRIPT' + + export SELF=$(basename $REPO_NAME) + BOOST_BRANCH=develop && [ "$DRONE_BRANCH" == "master" ] && BOOST_BRANCH=master || true + echo BOOST_BRANCH: $BOOST_BRANCH + cd .. + git clone -b $BOOST_BRANCH --depth 1 https://github.com/boostorg/boost.git boost-root + cd boost-root + # mkdir -p libs/$SELF + # cp -r $DRONE_BUILD_DIR/* libs/$SELF + # git submodule update --init tools/boostdep + git submodule update --init --recursive + mkdir -p libs/$SELF + cp -r $DRONE_BUILD_DIR/* libs/$SELF + + # CMake tests + cd libs/$SELF + mkdir __build__ && cd __build__ + cmake -DCMAKE_INSTALL_PREFIX=~/.local .. + cmake --build . --target install + ctest --output-on-failure + + # CMake subdir tests + cd ../test/cmake_test && mkdir __build__ && cd __build__ + cmake -DCMAKE_INSTALL_PREFIX=~/.local .. + cmake --build . + cmake --build . --target check + ctest --output-on-failure + + # Install Library + cd ../../../../.. && mkdir __build_cmake_install_test__ && cd __build_cmake_install_test__ + cmake -DBOOST_INCLUDE_LIBRARIES=$SELF -DCMAKE_INSTALL_PREFIX=~/.local -DBoost_VERBOSE=ON -DBoost_DEBUG=ON .. + cmake --build . --target install + + # CMake install tests + cd ../libs/$SELF/test/cmake_test && mkdir __build_cmake_install_test__ && cd __build_cmake_install_test__ + cmake -DBOOST_CI_INSTALL_TEST=ON -DCMAKE_PREFIX_PATH=~/.local .. + cmake --build . + ctest --output-on-failure + +fi diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml new file mode 100644 index 0000000..22551ae --- /dev/null +++ b/.github/workflows/ci.yml @@ -0,0 +1,522 @@ +# Copyright 2020-2021 Peter Dimov +# Copyright 2021 Andrey Semashev +# Copyright 2022 Alan de Freitas +# +# Distributed under the Boost Software License, Version 1.0. +# (See accompanying file LICENSE_1_0.txt or copy at http://boost.org/LICENSE_1_0.txt) + +name: CI + +on: + pull_request: + push: + branches: + - master + - develop + - feature/** + +concurrency: + group: ${{format('{0}:{1}', github.repository, github.ref)}} + cancel-in-progress: true + +env: + GIT_FETCH_JOBS: 8 + NET_RETRY_COUNT: 5 + DEFAULT_BUILD_VARIANT: debug,release + +jobs: + posix: + defaults: + run: + shell: bash + + strategy: + fail-fast: false + matrix: + include: + # Linux, gcc + - toolset: gcc-4.8 + cxxstd: "11" + os: ubuntu-22.04 + container: ubuntu:18.04 + install: + - g++-4.8 + - toolset: gcc-4.9 + cxxstd: "11" + os: ubuntu-22.04 + container: ubuntu:16.04 + install: + - g++-4.9 + - toolset: gcc-5 + cxxstd: "11,14" + os: ubuntu-22.04 + container: ubuntu:16.04 + install: + - g++-5 + - toolset: gcc-6 + cxxstd: "11,14" + os: ubuntu-22.04 + container: ubuntu:18.04 + install: + - g++-6 + - toolset: gcc-7 + cxxstd: "14,17" + os: ubuntu-22.04 + container: ubuntu:18.04 + install: + - g++-7 + - toolset: gcc-8 + cxxstd: "17" + os: ubuntu-22.04 + container: ubuntu:18.04 + install: + - g++-8 + - toolset: gcc-9 + cxxstd: "17" + os: ubuntu-22.04 + install: + - g++-9 + - toolset: gcc-10 + cxxstd: "17" + os: ubuntu-22.04 + install: + - g++-10 + - toolset: gcc-11 + cxxstd: "17,20" + os: ubuntu-22.04 + install: + - g++-11 + sources: + - "ppa:ubuntu-toolchain-r/test" + - name: UBSAN + toolset: gcc-11 + cxxstd: "17,20" + ubsan: 1 + os: ubuntu-22.04 + install: + - g++-11 + sources: + - "ppa:ubuntu-toolchain-r/test" + + # Linux, clang + - toolset: clang + compiler: clang++-3.8 + cxxstd: "11" + os: ubuntu-22.04 + container: ubuntu:16.04 + install: + - clang-3.8 + - toolset: clang + compiler: clang++-4.0 + cxxstd: "11,14" + os: ubuntu-22.04 + container: ubuntu:18.04 + install: + - clang-4.0 + - toolset: clang + compiler: clang++-5.0 + cxxstd: "11,14" + os: ubuntu-22.04 + container: ubuntu:18.04 + install: + - clang-5.0 + - toolset: clang + compiler: clang++-6.0 + cxxstd: "14,17" + os: ubuntu-22.04 + container: ubuntu:18.04 + install: + - clang-6.0 + - toolset: clang + compiler: clang++-7 + cxxstd: "17" + os: ubuntu-22.04 + container: ubuntu:18.04 + install: + - clang-7 + - toolset: clang + compiler: clang++-8 + cxxstd: "17" + os: ubuntu-22.04 + container: ubuntu:18.04 + install: + - clang-8 + - g++-7 + gcc_toolchain: 7 + - toolset: clang + compiler: clang++-9 + cxxstd: "14,17" + os: ubuntu-22.04 + container: ubuntu:18.04 + install: + - clang-9 + - toolset: clang + compiler: clang++-10 + cxxstd: "14,17" + os: ubuntu-20.04 + install: + - clang-10 + - toolset: clang + compiler: clang++-11 + cxxstd: "14,17" + os: ubuntu-20.04 + install: + - clang-11 +# clang 12 tested on drone +# - toolset: clang +# compiler: clang++-12 +# cxxstd: "17,20" +# os: ubuntu-22.04 +# install: +# - clang-12 +# - toolset: clang +# compiler: clang++-12 +# cxxstd: "17,20" +# cxxflags: -stdlib=libc++ +# linkflags: -stdlib=libc++ +# os: ubuntu-20.04 +# install: +# - clang-12 +# - libc++-12-dev +# - libc++abi-12-dev +# - name: UBSAN +# toolset: clang +# compiler: clang++-12 +# cxxstd: "17,20" +# cxxflags: -stdlib=libc++ +# linkflags: -stdlib=libc++ +# ubsan: 1 +# os: ubuntu-20.04 +# install: +# - clang-12 +# - libc++-12-dev +# - libc++abi-12-dev + + - toolset: clang + cxxstd: "11,14,17" + os: macos-11 + + - name: CMake tests + cmake_tests: 1 + os: ubuntu-22.04 + + timeout-minutes: 120 + runs-on: ${{matrix.os}} + container: ${{matrix.container}} + + steps: + - name: Setup environment + run: | + if [ -f "/etc/debian_version" ] + then + echo "DEBIAN_FRONTEND=noninteractive" >> $GITHUB_ENV + export DEBIAN_FRONTEND=noninteractive + fi + if [ -n "${{matrix.container}}" ] + then + echo "GHA_CONTAINER=${{matrix.container}}" >> $GITHUB_ENV + if [ -f "/etc/debian_version" ] + then + apt-get -o Acquire::Retries=$NET_RETRY_COUNT update + apt-get -o Acquire::Retries=$NET_RETRY_COUNT install -y sudo software-properties-common tzdata wget curl apt-transport-https make apt-file unzip libssl-dev build-essential autotools-dev autoconf automake g++ libc++-helpers python ruby cpio gcc-multilib g++-multilib pkgconf python3 ccache libpython-dev + + # install pip: + python_version=$(python3 -c 'import sys; print("{0.major}.{0.minor}".format(sys.version_info))') + if [[ ${python_version} =~ ^3\.[0-5]$ ]]; then + true + else + apt-get install -y python3-distutils + fi + wget https://bootstrap.pypa.io/pip/$python_version/get-pip.py + python3 get-pip.py + + # install git: + # apt-get install -y git + apt-add-repository ppa:git-core/ppa + apt-get -o Acquire::Retries=$NET_RETRY_COUNT update && apt-get -o Acquire::Retries=$NET_RETRY_COUNT install -y git + + # install cmake: + # apt-get -o Acquire::Retries=$NET_RETRY_COUNT install -y cmake + sudo pip3 install cmake + fi + fi + git config --global pack.threads 0 + + - uses: actions/checkout@v2 + + - name: Install packages + if: matrix.install + run: | + SOURCE_KEYS=(${{join(matrix.source_keys, ' ')}}) + SOURCES=(${{join(matrix.sources, ' ')}}) + for key in "${SOURCE_KEYS[@]}" + do + for i in {1..$NET_RETRY_COUNT} + do + wget -O - "$key" | sudo apt-key add - && break || sleep 2 + done + done + if [ ${#SOURCES[@]} -gt 0 ] + then + APT_ADD_REPO_COMMON_ARGS=("-y") + APT_ADD_REPO_HAS_SOURCE_ARGS=0 + SOFTWARE_PROPERTIES_VERSION="$(dpkg-query --showformat='${Version}' --show software-properties-common)" + if dpkg --compare-versions "$SOFTWARE_PROPERTIES_VERSION" ge "0.96.24.20" + then + APT_ADD_REPO_COMMON_ARGS+=("-n") + fi + if dpkg --compare-versions "$SOFTWARE_PROPERTIES_VERSION" ge "0.98.10" + then + APT_ADD_REPO_HAS_SOURCE_ARGS=1 + fi + for source in "${SOURCES[@]}" + do + for i in {1..$NET_RETRY_COUNT} + do + APT_ADD_REPO_ARGS=("${APT_ADD_REPO_COMMON_ARGS[@]}") + if [ $APT_ADD_REPO_HAS_SOURCE_ARGS -ne 0 ] + then + case "$source" in + "ppa:"*) + APT_ADD_REPO_ARGS+=("-P") + ;; + "deb "*) + APT_ADD_REPO_ARGS+=("-S") + ;; + *) + APT_ADD_REPO_ARGS+=("-U") + ;; + esac + fi + APT_ADD_REPO_ARGS+=("$source") + sudo -E apt-add-repository "${APT_ADD_REPO_ARGS[@]}" && break || sleep 2 + done + done + fi + sudo apt-get -o Acquire::Retries=$NET_RETRY_COUNT update + sudo apt-get -o Acquire::Retries=$NET_RETRY_COUNT install -y ${{join(matrix.install, ' ')}} + + - name: Setup GCC Toolchain + if: matrix.gcc_toolchain + run: | + GCC_TOOLCHAIN_ROOT="$HOME/gcc-toolchain" + echo "GCC_TOOLCHAIN_ROOT=\"$GCC_TOOLCHAIN_ROOT\"" >> $GITHUB_ENV + MULTIARCH_TRIPLET="$(dpkg-architecture -qDEB_HOST_MULTIARCH)" + mkdir -p "$GCC_TOOLCHAIN_ROOT" + ln -s /usr/include "$GCC_TOOLCHAIN_ROOT/include" + ln -s /usr/bin "$GCC_TOOLCHAIN_ROOT/bin" + mkdir -p "$GCC_TOOLCHAIN_ROOT/lib/gcc/$MULTIARCH_TRIPLET" + ln -s "/usr/lib/gcc/$MULTIARCH_TRIPLET/${{matrix.gcc_toolchain}}" "$GCC_TOOLCHAIN_ROOT/lib/gcc/$MULTIARCH_TRIPLET/${{matrix.gcc_toolchain}}" + + - name: Setup Boost + run: | + echo GITHUB_REPOSITORY: $GITHUB_REPOSITORY + LIBRARY=${GITHUB_REPOSITORY#*/} + echo LIBRARY: $LIBRARY + echo "LIBRARY=$LIBRARY" >> $GITHUB_ENV + echo GITHUB_BASE_REF: $GITHUB_BASE_REF + echo GITHUB_REF: $GITHUB_REF + REF=${GITHUB_BASE_REF:-$GITHUB_REF} + REF=${REF#refs/heads/} + echo REF: $REF + BOOST_BRANCH=develop && [ "$REF" == "master" ] && BOOST_BRANCH=master || true + echo BOOST_BRANCH: $BOOST_BRANCH + BUILD_JOBS=$((nproc || sysctl -n hw.ncpu) 2> /dev/null) + echo "BUILD_JOBS=$BUILD_JOBS" >> $GITHUB_ENV + echo "CMAKE_BUILD_PARALLEL_LEVEL=$BUILD_JOBS" >> $GITHUB_ENV + DEPINST_ARGS=() + GIT_VERSION="$(git --version | sed -e 's/git version //')" + if $(dpkg --compare-versions "$GIT_VERSION" ge 2.8.0) + then + DEPINST_ARGS+=("--git_args" "--jobs $GIT_FETCH_JOBS") + fi + cd .. + git clone -b "$BOOST_BRANCH" --depth 1 "https://github.com/boostorg/boost.git" "boost-root" + + cd boost-root + # mkdir -p libs/$LIBRARY + # cp -r $GITHUB_WORKSPACE/* libs/$LIBRARY + # git submodule update --init tools/boostdep + git submodule update --init --recursive + mkdir -p libs/$SELF + cp -r $GITHUB_WORKSPACE/* libs/$SELF + + DEPINST_ARGS+=("$LIBRARY") + python tools/boostdep/depinst/depinst.py "${DEPINST_ARGS[@]}" + if [ -z "${{matrix.cmake_tests}}" ] + then + ./bootstrap.sh + ./b2 headers + if [ -n "${{matrix.compiler}}" -o -n "$GCC_TOOLCHAIN_ROOT" ] + then + echo -n "using ${{matrix.toolset}} : : ${{matrix.compiler}}" > ~/user-config.jam + if [ -n "$GCC_TOOLCHAIN_ROOT" ] + then + echo -n " : \"--gcc-toolchain=$GCC_TOOLCHAIN_ROOT\" \"--gcc-toolchain=$GCC_TOOLCHAIN_ROOT\"" >> ~/user-config.jam + fi + echo " ;" >> ~/user-config.jam + fi + fi + + - name: Run tests + if: matrix.cmake_tests == '' + run: | + cd ../boost-root + B2_ARGS=("-j" "$BUILD_JOBS" "toolset=${{matrix.toolset}}" "cxxstd=${{matrix.cxxstd}}") + if [ -n "${{matrix.build_variant}}" ] + then + B2_ARGS+=("variant=${{matrix.build_variant}}") + else + B2_ARGS+=("variant=$DEFAULT_BUILD_VARIANT") + fi + if [ -n "${{matrix.threading}}" ] + then + B2_ARGS+=("threading=${{matrix.threading}}") + fi + if [ -n "${{matrix.ubsan}}" ] + then + export UBSAN_OPTIONS="print_stacktrace=1" + B2_ARGS+=("cxxflags=-fsanitize=undefined -fno-sanitize-recover=undefined" "linkflags=-fsanitize=undefined -fuse-ld=gold" "define=UBSAN=1" "debug-symbols=on" "visibility=global") + fi + if [ -n "${{matrix.cxxflags}}" ] + then + B2_ARGS+=("cxxflags=${{matrix.cxxflags}}") + fi + if [ -n "${{matrix.linkflags}}" ] + then + B2_ARGS+=("linkflags=${{matrix.linkflags}}") + fi + B2_ARGS+=("libs/$LIBRARY/test") + ./b2 "${B2_ARGS[@]}" + +# - name: Run CMake tests +# if: matrix.cmake_tests != '' +# run: | +# cd ../boost-root +# git submodule update --init --recursive +# cd libs/$LIBRARY +# mkdir __build__ && cd __build__ +# cmake -DCMAKE_INSTALL_PREFIX=~/.local .. +# cmake --build . --target install + + windows: + strategy: + fail-fast: false + matrix: + include: + #- toolset: msvc-14.1 + # cxxstd: "14,17,latest" + # addrmd: 32,64 + # os: windows-2016 + - toolset: msvc-14.2 + cxxstd: "14,17" + addrmd: 32,64 + os: windows-2019 + - toolset: msvc-14.3 + cxxstd: "17,20" + addrmd: 32,64 + os: windows-2022 + # - toolset: gcc + # cxxstd: "11,14,17" + # addrmd: 64 + # os: windows-2019 + + runs-on: ${{matrix.os}} + + steps: + - uses: actions/checkout@v2 + + - name: Setup Boost + shell: cmd + run: | + echo GITHUB_REPOSITORY: %GITHUB_REPOSITORY% + for /f %%i in ("%GITHUB_REPOSITORY%") do set LIBRARY=%%~nxi + echo LIBRARY: %LIBRARY% + echo LIBRARY=%LIBRARY%>>%GITHUB_ENV% + echo GITHUB_BASE_REF: %GITHUB_BASE_REF% + echo GITHUB_REF: %GITHUB_REF% + if "%GITHUB_BASE_REF%" == "" set GITHUB_BASE_REF=%GITHUB_REF% + set BOOST_BRANCH=develop + for /f %%i in ("%GITHUB_BASE_REF%") do if "%%~nxi" == "master" set BOOST_BRANCH=master + echo BOOST_BRANCH: %BOOST_BRANCH% + cd .. + git clone -b %BOOST_BRANCH% --depth 1 https://github.com/boostorg/boost.git boost-root + cd boost-root + xcopy /s /e /q %GITHUB_WORKSPACE% libs\%LIBRARY%\ + git submodule update --init tools/boostdep + python tools/boostdep/depinst/depinst.py --git_args "--jobs %GIT_FETCH_JOBS%" %LIBRARY% + cmd /c bootstrap + b2 -d0 headers + + - name: Run tests + shell: cmd + run: | + cd ../boost-root + b2 -j %NUMBER_OF_PROCESSORS% libs/%LIBRARY%/test toolset=${{matrix.toolset}} cxxstd=${{matrix.cxxstd}} address-model=${{matrix.addrmd}} variant=debug,release + + CMake: + defaults: + run: + shell: bash + + strategy: + fail-fast: false + matrix: + include: + - { os: ubuntu-22.04, build_shared: ON, build_type: Debug, generator: 'Unix Makefiles' } + - { os: ubuntu-22.04, build_shared: OFF, build_type: Debug, generator: 'Unix Makefiles' } + - { os: windows-2019, build_shared: ON, build_type: Debug, generator: 'Visual Studio 16 2019' } + - { os: windows-2019, build_shared: OFF, build_type: Debug, generator: 'Visual Studio 16 2019' } + + timeout-minutes: 120 + runs-on: ${{matrix.os}} + + steps: + - uses: actions/checkout@v2 + - name: Fetch Boost.CI + uses: actions/checkout@v2 + with: + repository: boostorg/boost-ci + ref: master + path: boost-ci-cloned + + - name: Get CI scripts folder + run: | + # Copy ci folder if not testing Boost.CI + [[ "$GITHUB_REPOSITORY" =~ "boost-ci" ]] || cp -r boost-ci-cloned/ci . + rm -rf boost-ci-cloned + - name: Setup Boost + env: {B2_DONT_BOOTSTRAP: 1} + run: source ci/github/install.sh + +# - name: Run CMake tests +# run: | +# cd "$BOOST_ROOT" +# mkdir __build_cmake_test__ && cd __build_cmake_test__ +# cmake -G "${{matrix.generator}}" -DCMAKE_BUILD_TYPE=${{matrix.build_type}} -DBOOST_INCLUDE_LIBRARIES=$SELF -DBUILD_SHARED_LIBS=${{matrix.build_shared}} -DBUILD_TESTING=ON -DBoost_VERBOSE=ON .. +# cmake --build . --target tests boost_url_tests boost_url_limits boost_url_extra --config ${{matrix.build_type}} +# ctest --output-on-failure --build-config ${{matrix.build_type}} +# - name: Run CMake subdir tests +# run: | +# cmake_test_folder="$BOOST_ROOT/libs/$SELF/test/cmake_test" # New unified folder +# [ -d "$cmake_test_folder" ] || cmake_test_folder="$BOOST_ROOT/libs/$SELF/test/cmake_subdir_test" +# cd "$cmake_test_folder" +# mkdir __build_cmake_subdir_test__ && cd __build_cmake_subdir_test__ +# cmake -G "${{matrix.generator}}" -DBOOST_CI_INSTALL_TEST=OFF -DCMAKE_BUILD_TYPE=${{matrix.build_type}} -DBUILD_SHARED_LIBS=${{matrix.build_shared}} .. +# cmake --build . --config ${{matrix.build_type}} +# ctest --output-on-failure --build-config ${{matrix.build_type}} +# - name: Install Library +# run: | +# cd "$BOOST_ROOT" +# mkdir __build_cmake_install_test__ && cd __build_cmake_install_test__ +# cmake -G "${{matrix.generator}}" -DCMAKE_BUILD_TYPE=${{matrix.build_type}} -DBOOST_INCLUDE_LIBRARIES=$SELF -DBUILD_SHARED_LIBS=${{matrix.build_shared}} -DCMAKE_INSTALL_PREFIX=~/.local -DBoost_VERBOSE=ON -DBoost_DEBUG=ON .. +# cmake --build . --target install --config ${{matrix.build_type}} +# - name: Run CMake install tests +# run: | +# cmake_test_folder="$BOOST_ROOT/libs/$SELF/test/cmake_test" # New unified folder +# [ -d "$cmake_test_folder" ] || cmake_test_folder="$BOOST_ROOT/libs/$SELF/test/cmake_install_test" +# cd "$cmake_test_folder" +# mkdir __build_cmake_install_test__ && cd __build_cmake_install_test__ +# cmake -G "${{matrix.generator}}" -DBOOST_CI_INSTALL_TEST=ON -DCMAKE_BUILD_TYPE=${{matrix.build_type}} -DBUILD_SHARED_LIBS=${{matrix.build_shared}} -DCMAKE_PREFIX_PATH=~/.local .. +# cmake --build . --config ${{matrix.build_type}} +# ctest --output-on-failure --build-config ${{matrix.build_type}} diff --git a/.travis.yml b/.travis.yml deleted file mode 100644 index 5d47642..0000000 --- a/.travis.yml +++ /dev/null @@ -1,275 +0,0 @@ -# Copyright 2016 Peter Dimov -# Copyright 2017 - 2019 James E. King III -# Copyright 2020 Krystian Stasiowski -# Distributed under the Boost Software License, Version 1.0. -# (See accompanying file LICENSE_1_0.txt or copy at http://boost.org/LICENSE_1_0.txt) - -# -# Generic Travis CI build script for boostorg repositories -# See: https://github.com/boostorg/boost-ci -# -# Instructions for customizing this script for your library: -# -# 1. Customize the compilers and language levels you want in the 'jobs'. -# 2. If you have more than include/, src/, test/, example/, examples/, or -# tools/ directories, modify your Travis CI project and add the environment -# variable DEPINST. For example if your build uses code in "bench/" and -# "fog/" directories, then set DEPINST to the following: -# --include bench --include fog -# 3. If you want to enable Coverity Scan, you need to provide the environment -# variables COVERITY_SCAN_TOKEN and COVERITY_SCAN_NOTIFICATION_EMAIL in -# your github settings. -# 4. If you want to enable a big-endian build, you need to uncomment the -# big-endian build job. -# 5. Enable pull request builds in your boostorg/ account. -# -# That's it - the scripts will do everything else for you. - -dist: xenial -language: cpp - -env: - global: - # see: http://www.boost.org/build/doc/html/bbv2/overview/invocation.html#bbv2.overview.invocation.properties - # - B2_ADDRESS_MODEL=address-model=64,32 - # - B2_LINK=link=shared,static - # - B2_THREADING=threading=multi,single - - B2_VARIANT=variant=release - -install: - - git clone https://github.com/boostorg/boost-ci.git boost-ci - - cp -pr boost-ci/ci boost-ci/.codecov.yml . - - source ci/travis/install.sh - -addons: - apt: - packages: - - binutils-gold - - gdb - - libc6-dbg - - qemu-user-static - -services: - - docker - -branches: - only: - - master - - develop - - /bugfix\/.*/ - - /feature\/.*/ - - /fix\/.*/ - - /pr\/.*/ - -script: - - cd $BOOST_ROOT/libs/$SELF - - ci/travis/build.sh - -# -# Default toolsets in Ubuntu -# -# trusty xenial bionic -# 14.04 16.04 18.04 -# ------ ------ ------ -# clang 3.4 3.8 6.0 -# gcc 4.8.2 5.3.1 7.3.0 -# - -anchors: - clang-38: &clang-38 { apt: { packages: [ "clang-3.8", - "libstdc++-6-dev" ], sources: [ "llvm-toolchain-xenial-3.8", - "ubuntu-toolchain-r-test" ] } } - clang-4: &clang-4 { apt: { packages: [ "clang-4.0", - "libstdc++-6-dev" ], sources: [ "llvm-toolchain-xenial-4.0", - "ubuntu-toolchain-r-test" ] } } - clang-5: &clang-5 { apt: { packages: [ "clang-5.0", - "libstdc++-7-dev" ], sources: [ "llvm-toolchain-xenial-5.0", - "ubuntu-toolchain-r-test" ] } } - clang-6: &clang-6 { apt: { packages: [ "clang-6.0", - "libc6-dbg", - "libc++-dev", - "libstdc++-8-dev" ], sources: [ "llvm-toolchain-xenial-6.0", - "ubuntu-toolchain-r-test" ] } } - clang-7: &clang-7 { apt: { packages: [ "clang-7", - "libc6-dbg", - "libc++-dev", - "libstdc++-8-dev" ], sources: [ "llvm-toolchain-xenial-7", - "ubuntu-toolchain-r-test" ] } } - clang-8: &clang-8 { apt: { packages: [ "clang-8", - "libc6-dbg", - "libc++-dev", - "libstdc++-8-dev" ], sources: [ "llvm-toolchain-xenial-8", - "ubuntu-toolchain-r-test" ] } } - - gcc-48: &gcc-48 { apt: { packages: [ "g++-4.8" ] } } - gcc-49: &gcc-49 { apt: { packages: [ "g++-4.9" ], sources: [ "ubuntu-toolchain-r-test" ] } } - gcc-5: &gcc-5 { apt: { packages: [ "g++-5" ] } } - gcc-6: &gcc-6 { apt: { packages: [ "g++-6" ], sources: [ "ubuntu-toolchain-r-test" ] } } - gcc-7: &gcc-7 { apt: { packages: [ "g++-7" ], sources: [ "ubuntu-toolchain-r-test" ] } } - gcc-8: &gcc-8 { apt: { packages: [ "g++-8" ], sources: [ "ubuntu-toolchain-r-test" ] } } - gcc-9: &gcc-9 { apt: { packages: [ "g++-9" ], sources: [ "ubuntu-toolchain-r-test" ] } } - -jobs: - allow_failures: - - env: - - COPY="all the environment settings from your job" - - include: - # coverage - - os: linux - env: - - COMMENT=codecov.io - - B2_CXXSTD=11 - - B2_TOOLSET=gcc-8 - - B2_DEFINES="define=BOOST_NO_STRESS_TEST=1" - addons: *gcc-8 - script: - - cd $BOOST_ROOT/libs/$SELF - - tools/codecov.sh - - - os: linux - env: - - COMMENT=asan - - B2_VARIANT=variant=debug - - B2_TOOLSET=gcc-8 - - B2_CXXSTD=11,14 - - B2_CXXFLAGS="address-sanitizer=norecover" - - B2_DEFINES="define=BOOST_NO_STRESS_TEST=1" - addons: *gcc-8 - - - os: linux - env: - - COMMENT=tsan - - B2_VARIANT=variant=debug - - B2_TOOLSET=gcc-8 - - B2_CXXSTD=11,14 - - B2_CXXFLAGS="thread-sanitizer=norecover" - - B2_DEFINES="define=BOOST_NO_STRESS_TEST=1" - addons: *gcc-8 - - - os: linux - env: - - COMMENT=ubsan - - B2_VARIANT=variant=debug - - B2_TOOLSET=gcc-8 - - B2_CXXSTD=11,14 - - B2_CXXFLAGS="undefined-sanitizer=norecover" - - B2_DEFINES="define=BOOST_NO_STRESS_TEST=1" - - B2_LINKFLAGS="linkflags=-fuse-ld=gold" - - UBSAN_OPTIONS=print_stacktrace=1 - addons: *gcc-8 - - - os: linux - env: - - COMMENT=valgrind - - B2_TOOLSET=clang-6.0 - - B2_CXXSTD=11,14 - - B2_DEFINES="define=BOOST_NO_STRESS_TEST=1" - - B2_VARIANT=variant=debug - - B2_TESTFLAGS=testing.launcher=valgrind - - VALGRIND_OPTS=--error-exitcode=1 - addons: *clang-6 - script: - - cd $BOOST_ROOT/libs/$SELF - - ci/travis/valgrind.sh - - # libstdc++ - - { os: "linux", dist: "trusty", # xenial has libstdc++ from gcc 5.4.0 with newer ABI - env: [ "B2_TOOLSET=gcc-4.8", "B2_CXXSTD=11" ], addons: *gcc-48 } - - { os: "linux", dist: "trusty", # xenial has libstdc++ from gcc 5.4.0 with newer ABI - env: [ "B2_TOOLSET=gcc-4.9", "B2_CXXSTD=11" ], addons: *gcc-49 } - - { os: "linux", env: [ "B2_TOOLSET=gcc-5", "B2_CXXSTD=11,14" ], addons: *gcc-5 } - - { os: "linux", env: [ "B2_TOOLSET=gcc-6", "B2_CXXSTD=11,14" ], addons: *gcc-6 } - - { os: "linux", env: [ "B2_TOOLSET=gcc-7", "B2_CXXSTD=14,17" ], addons: *gcc-7 } - - { os: "linux", env: [ "B2_TOOLSET=gcc-8", "B2_CXXSTD=17" ], addons: *gcc-8 } - - { os: "linux", env: [ "B2_TOOLSET=gcc-9", "B2_CXXSTD=17" ], addons: *gcc-9 } - - { os: "linux", dist: "trusty", # xenial has libstdc++ from gcc 5.4.0 with newer ABI - env: [ "B2_TOOLSET=clang-3.8", "B2_CXXSTD=11" ], addons: *clang-38 } - - { os: "linux", env: [ "B2_TOOLSET=clang-4.0", "B2_CXXSTD=11,14" ], addons: *clang-4 } - - { os: "linux", env: [ "B2_TOOLSET=clang-5.0", "B2_CXXSTD=11,14" ], addons: *clang-5 } - - { os: "linux", env: [ "B2_TOOLSET=clang-6.0", "B2_CXXSTD=14,17" ], addons: *clang-6 } - - { os: "linux", env: [ "B2_TOOLSET=clang-7", "B2_CXXSTD=17" ], addons: *clang-7 } - - { os: "linux", env: [ "B2_TOOLSET=clang-8", "B2_CXXSTD=17" ], addons: *clang-8 } - - - os: "linux" - env: ["B2_TOOLSET=clang-9", "B2_CXXSTD=11,14,17"] - addons: - apt: - sources: - - ubuntu-toolchain-r-test - - sourceline: 'deb https://apt.llvm.org/xenial/ llvm-toolchain-xenial-9 main' - key_url: 'https://apt.llvm.org/llvm-snapshot.gpg.key' - packages: - - clang-9 - - libc6-dbg - - libc++-dev - - libstdc++-8-dev - - # libc++ - - { os: "linux", env: [ "B2_TOOLSET=clang-6.0", "B2_CXXSTD=11,14", - "B2_CXXFLAGS=-stdlib=libc++" ], addons: *clang-6 } - - { os: "osx" , env: [ "B2_TOOLSET=clang", "B2_CXXSTD=11,17" ] } - - # to enable Intel ICC define INTEL_ICC_SERIAL_NUMBER and the following (under development): - # - { os: "linux", env: [ "B2_TOOLSET=intel-linux", "B2_CXXSTD=11,14,17" ], addons: *gcc-7, - # script: cd $BOOST_ROOT/libs/$SELF && ci/travis/intelicc.sh } - - # uncomment to enable a big-endian build job, just note that it is 5-10 times slower - # than a regular build and travis has a 50 minute time limit per job - # - os: linux - # env: - # - COMMENT=big-endian - # - B2_CXXSTD=03 - # - B2_TOOLSET=gcc - # - B2_DEFINES="define=BOOST_NO_STRESS_TEST=1" - # - BDDE_OS=red - # - BDDE_ARCH=ppc64 - # script: - # - cd $BOOST_ROOT/libs/$SELF - # - ci/travis/bdde.sh - - # - os: linux - # env: - # - COMMENT=cppcheck - # script: - # - cd $BOOST_ROOT/libs/$SELF - # - ci/travis/cppcheck.sh - - #################### Jobs to run on pushes to master, develop ################### - - # Coverity Scan - - os: linux - if: (env(COVERITY_SCAN_NOTIFICATION_EMAIL) IS present) AND (branch IN (develop, master)) AND (type IN (cron, push)) - env: - - COMMENT="Coverity Scan" - - B2_TOOLSET=clang - script: - - cd $BOOST_ROOT/libs/$SELF - - ci/travis/coverity.sh - - # Standalone tests for StaticString - - { os: "linux", env: [ "COMMENT=STANDALONE", "B2_TOOLSET=gcc-7", "B2_DEFINES=define=BOOST_STATIC_STRING_STANDALONE", "B2_CXXSTD=17" ], addons: *gcc-7 } - - { os: "linux", env: [ "COMMENT=STANDALONE", "B2_TOOLSET=gcc-8", "B2_DEFINES=define=BOOST_STATIC_STRING_STANDALONE", "B2_CXXSTD=17" ], addons: *gcc-8 } - - { os: "linux", env: [ "COMMENT=STANDALONE", "B2_TOOLSET=gcc-9", "B2_DEFINES=define=BOOST_STATIC_STRING_STANDALONE", "B2_CXXSTD=17" ], addons: *gcc-9 } - - { os: "linux", env: [ "COMMENT=STANDALONE", "B2_TOOLSET=clang-6.0", "B2_DEFINES=define=BOOST_STATIC_STRING_STANDALONE", "B2_CXXSTD=17" ], addons: *clang-6 } - - { os: "linux", env: [ "COMMENT=STANDALONE", "B2_TOOLSET=clang-7", "B2_DEFINES=define=BOOST_STATIC_STRING_STANDALONE", "B2_CXXSTD=17" ], addons: *clang-7 } - - { os: "linux", env: [ "COMMENT=STANDALONE", "B2_TOOLSET=clang-8", "B2_DEFINES=define=BOOST_STATIC_STRING_STANDALONE", "B2_CXXSTD=17" ], addons: *clang-8 } - - os: "linux" - env: ["COMMENT=STANDALONE", "B2_TOOLSET=clang-9", "B2_DEFINES=define=BOOST_STATIC_STRING_STANDALONE", "B2_CXXSTD=17"] - addons: - apt: - sources: - - ubuntu-toolchain-r-test - - sourceline: 'deb https://apt.llvm.org/xenial/ llvm-toolchain-xenial-9 main' - key_url: 'https://apt.llvm.org/llvm-snapshot.gpg.key' - packages: - - clang-9 - - libc6-dbg - - libc++-dev - - libstdc++-8-dev - - - { os: "osx" , env: [ "COMMENT=STANDALONE", "B2_TOOLSET=clang", "B2_DEFINES=define=BOOST_STATIC_STRING_STANDALONE", "B2_CXXSTD=17" ] } - -notifications: - email: - false diff --git a/include/boost/static_string/static_string.hpp b/include/boost/static_string/static_string.hpp index d1f4943..e69354c 100644 --- a/include/boost/static_string/static_string.hpp +++ b/include/boost/static_string/static_string.hpp @@ -257,11 +257,8 @@ class static_string_base } size_type size_ = 0; -#ifdef BOOST_STATIC_STRING_CPP20 - value_type data_[N + 1]; -#else + value_type data_[N + 1]{}; -#endif }; // Optimization for when the size is 0 @@ -1060,6 +1057,33 @@ class basic_static_string // //-------------------------------------------------------------------------- + /** Assign to the string. + + Replaces the contents with those of + the string `s`. + + @par Complexity + + Linear in `s.size()`. + + @par Exception Safety + + Strong guarantee. + + @return `*this` + + @param s The string to replace + the contents with. + + @throw std::length_error `s.size() > max_size()`. + */ + BOOST_STATIC_STRING_CPP14_CONSTEXPR + basic_static_string& + operator=(const basic_static_string& s) + { + return assign(s); + } + /** Assign to the string. Replaces the contents with those of diff --git a/meta/libraries.json b/meta/libraries.json index 8124b3f..db0db91 100644 --- a/meta/libraries.json +++ b/meta/libraries.json @@ -11,7 +11,7 @@ "String" ], "maintainers": [ - "Krystian Stasiowski ", + "Alan de Freitas ", "Vinnie Falco " ], "cxxstd": "11" diff --git a/test/static_string.cpp b/test/static_string.cpp index a23f25d..8ef6481 100644 --- a/test/static_string.cpp +++ b/test/static_string.cpp @@ -14,6 +14,7 @@ #include "compile_fail.hpp" #include +#include #include #include #include @@ -412,6 +413,7 @@ testAssignment() BOOST_TEST(static_string<4>{}.assign(cs.begin(), cs.end()) == "abcd"); BOOST_TEST(static_string<4>{"*"}.assign(cs.begin(), cs.end()) == "abcd"); BOOST_TEST_THROWS(static_string<2>{"*"}.assign(cs.begin(), cs.end()), std::length_error); + ignore_unused(s); } // assign(std::initializer_list ilist) @@ -1050,6 +1052,7 @@ testInsert() BOOST_TEST_THROWS( (s2.insert(6, "__")), std::out_of_range); + ignore_unused(s3); } { static_string<7> s1("12345"); @@ -2003,6 +2006,7 @@ testAppend() cs.begin() + 2, cs.begin() + 4) == "abcd"); BOOST_TEST_THROWS(static_string<2>{"ab"}.append( cs.begin() + 2, cs.begin() + 4), std::length_error); + ignore_unused(s); } // append(std::initializer_list ilist) From 3e9489a7af357b4ee5eb66adab106dc8798d6350 Mon Sep 17 00:00:00 2001 From: alandefreitas Date: Mon, 31 Oct 2022 21:35:37 -0300 Subject: [PATCH 02/73] update CMakeLists.txt fix #4 --- CMakeLists.txt | 260 +++++++++++++++++--------------------------- test/CMakeLists.txt | 29 +++-- 2 files changed, 119 insertions(+), 170 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index ecd71b8..fabfdfa 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,32 +1,5 @@ -# Generated by `boostdep --cmake static_string` -# Copyright 2020 Peter Dimov -# Distributed under the Boost Software License, Version 1.0. -# https://www.boost.org/LICENSE_1_0.txt - -cmake_minimum_required(VERSION 3.5...3.16) - -project(boost_static_string VERSION "${BOOST_SUPERPROJECT_VERSION}" LANGUAGES CXX) - -if(NOT CMAKE_SOURCE_DIR STREQUAL CMAKE_CURRENT_SOURCE_DIR) - -add_library(boost_static_string INTERFACE) -add_library(Boost::static_string ALIAS boost_static_string) - -target_include_directories(boost_static_string INTERFACE include) - -target_link_libraries(boost_static_string - INTERFACE - Boost::assert - Boost::container_hash - Boost::static_assert - Boost::throw_exception - Boost::utility -) - -else() - # -# Copyright (c) 2016-2017 Vinnie Falco (vinnie dot falco at gmail dot com) +# Copyright (c) 2022 Alan de Freitas (alandefreitas@gmail.com) # # 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) @@ -34,140 +7,111 @@ else() # Official repository: https://github.com/boostorg/static_string # -#------------------------------------------------------------------------------- - -function (DoGroupSources curdir rootdir folder) - file (GLOB children RELATIVE ${PROJECT_SOURCE_DIR}/${curdir} ${PROJECT_SOURCE_DIR}/${curdir}/*) - foreach (child ${children}) - if (IS_DIRECTORY ${PROJECT_SOURCE_DIR}/${curdir}/${child}) - DoGroupSources (${curdir}/${child} ${rootdir} ${folder}) - elseif (${child} STREQUAL "CMakeLists.txt") - source_group("" FILES ${PROJECT_SOURCE_DIR}/${curdir}/${child}) - else() - string (REGEX REPLACE ^${rootdir} ${folder} groupname ${curdir}) - string (REPLACE "/" "\\" groupname ${groupname}) - source_group (${groupname} FILES ${PROJECT_SOURCE_DIR}/${curdir}/${child}) - endif() - endforeach() -endfunction() - -function (GroupSources curdir folder) - DoGroupSources (${curdir} ${curdir} ${folder}) -endfunction() - -#------------------------------------------------------------------------------- -# -# StaticString -# -#------------------------------------------------------------------------------- - -set_property (GLOBAL PROPERTY USE_FOLDERS ON) - -if (MSVC) - set (CMAKE_VERBOSE_MAKEFILE FALSE) +cmake_minimum_required(VERSION 3.5...3.16) - add_definitions ( - -D_WIN32_WINNT=0x0601 - ) +project(boost_static_string VERSION "${BOOST_SUPERPROJECT_VERSION}" LANGUAGES CXX) - add_compile_options( - /permissive- # strict C++ - /W4 # enable all warnings - /MP # Multi-processor compilation +set(BOOST_STATIC_STRING_IS_ROOT OFF) +if (CMAKE_SOURCE_DIR STREQUAL CMAKE_CURRENT_SOURCE_DIR) + set(BOOST_STATIC_STRING_IS_ROOT ON) +endif () + +if (BOOST_STATIC_STRING_IS_ROOT) + include(CTest) +endif () + +# Options +if (NOT BOOST_SUPERPROJECT_VERSION) + option(BOOST_STATIC_STRING_INSTALL "Install boost::static_string files" ${BOOST_STATIC_STRING_IS_ROOT}) + option(BOOST_STATIC_STRING_BUILD_TESTS "Build boost::static_string tests" ${BUILD_TESTING}) +else () + set(BOOST_STATIC_STRING_BUILD_TESTS ${BUILD_TESTING}) +endif () + +# Find boost +if (BOOST_SUPERPROJECT_VERSION) + set(BOOST_STATIC_STRING_FIND_PACKAGE_BOOST OFF) +elseif (EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/../../CMakeLists.txt" AND + EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/../../Jamroot" AND + EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/../../boost-build.jam" AND + EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/../../bootstrap.sh" AND + EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/../../libs") + set(BOOST_STATIC_STRING_FIND_PACKAGE_BOOST OFF) +else () + set(BOOST_STATIC_STRING_FIND_PACKAGE_BOOST ON) +endif () + +if (BOOST_STATIC_STRING_FIND_PACKAGE_BOOST) + find_package(Boost 1.78.0 REQUIRED COMPONENTS container) +elseif (BOOST_STATIC_STRING_IS_ROOT) + set(BOOST_STATIC_STRING_UNIT_TEST_LIBRARIES core) + set(BOOST_INCLUDE_LIBRARIES static_string assert container_hash static_assert throw_exception utility ${BOOST_STATIC_STRING_UNIT_TEST_LIBRARIES}) + set(BOOST_EXCLUDE_LIBRARIES static_string) + set(CMAKE_FOLDER Dependencies) + add_subdirectory(../.. Dependencies/boost EXCLUDE_FROM_ALL) + unset(CMAKE_FOLDER) +endif () + +# Sources +include(GNUInstallDirs) +file(GLOB_RECURSE BOOST_STATIC_STRING_HEADERS CONFIGURE_DEPENDS + include/boost/*.hpp + include/boost/*.ipp + include/boost/*.natvis ) - set (Boost_USE_STATIC_LIBS ON) - set (Boost_USE_STATIC_RUNTIME ON) - - set (CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} /MTd") - set (CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} /Ob2 /Oi /Ot /GL /MT") - set (CMAKE_CXX_FLAGS_RELWITHDEBINFO "${CMAKE_CXX_FLAGS_RELWITHDEBINFO} /Oi /Ot /MT") - - set (CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} /SAFESEH:NO") - set (CMAKE_EXE_LINKER_FLAGS_RELEASE "${CMAKE_EXE_LINKER_FLAGS_RELEASE} /LTCG") - - # for RelWithDebInfo builds, disable incremental linking - # since CMake sets it ON by default for that build type and it - # causes warnings - # - string (REPLACE "/INCREMENTAL" "/INCREMENTAL:NO" replacement_flags - ${CMAKE_EXE_LINKER_FLAGS_RELWITHDEBINFO}) - set (CMAKE_EXE_LINKER_FLAGS_RELWITHDEBINFO ${replacement_flags}) - -else() - set (THREADS_PREFER_PTHREAD_FLAG ON) - find_package (Threads) - - set( CMAKE_CXX_FLAGS - "${CMAKE_CXX_FLAGS} -std=c++11 -Wall -Wextra -Wpedantic -Wno-unused-parameter") +set_property(GLOBAL PROPERTY USE_FOLDERS ON) +source_group(TREE ${CMAKE_CURRENT_SOURCE_DIR}/include/boost PREFIX "" FILES ${BOOST_STATIC_STRING_HEADERS}) +source_group(TREE ${CMAKE_CURRENT_SOURCE_DIR}/src PREFIX "" FILES ${BOOST_STATIC_STRING_SOURCES}) - if ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "Clang") - set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wrange-loop-analysis") - endif () -endif() - -# Must come before Boost includes, otherwise the -# IDE sees the wrong file due to boost/ symlinks. -include_directories (include) - -#------------------------------------------------------------------------------- -# -# Boost -# -#------------------------------------------------------------------------------- - -get_filename_component (BOOST_ROOT ../../ ABSOLUTE) - -# VFALCO I want static but "b2 stage" builds a minimal set which excludes static -add_definitions (-DBOOST_ALL_STATIC_LINK=1) - -include_directories (${BOOST_ROOT}) - -link_directories(${BOOST_ROOT}/stage/lib) - -#------------------------------------------------------------------------------- - -if ("${VARIANT}" STREQUAL "coverage") - if (MSVC) - else() - set (CMAKE_BUILD_TYPE DEBUG) - set (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -msse4.2 --coverage") - set (CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} --coverage") - endif() - -elseif ("${VARIANT}" STREQUAL "ubasan") - if (MSVC) - else() - set (CMAKE_BUILD_TYPE RELWITHDEBINFO) - set (CMAKE_CXX_FLAGS - "${CMAKE_CXX_FLAGS} -msse4.2 -funsigned-char -fno-omit-frame-pointer -fsanitize=address,undefined -fno-sanitize-recover=address,undefined -fsanitize-blacklist=${PROJECT_SOURCE_DIR}/tools/blacklist.supp") - set (CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -fsanitize=address,undefined -fno-sanitize-recover=address,undefined") - endif() - -elseif ("${VARIANT}" STREQUAL "debug") - set (CMAKE_BUILD_TYPE DEBUG) - -elseif ("${VARIANT}" STREQUAL "release") - set (CMAKE_BUILD_TYPE RELEASE) - -endif() - -#------------------------------------------------------------------------------- - -#GroupSources (test "/") - -#------------------------------------------------------------------------------- -# -# Tests and examples -# - -#include_directories (.) - -file (GLOB_RECURSE PROJECT_FILES - ${PROJECT_SOURCE_DIR}/include/boost/static_string/*.hpp - ${PROJECT_SOURCE_DIR}/include/boost/static_string/*.ipp -) +# Target +add_library(boost_static_string INTERFACE) +add_library(Boost::static_string ALIAS boost_static_string) -add_subdirectory (test) +target_compile_features(boost_static_string INTERFACE cxx_constexpr) +if (BOOST_SUPERPROJECT_VERSION) + target_include_directories(boost_static_string INTERFACE "${PROJECT_SOURCE_DIR}/include") +else () + target_include_directories(boost_static_string + INTERFACE + "$" + "$" + ) +endif () + +if (BOOST_STATIC_STRING_FIND_PACKAGE_BOOST) + target_link_libraries(boost_static_string + INTERFACE + Boost::headers + ) +else () + target_link_libraries(boost_static_string + INTERFACE + Boost::assert + Boost::container_hash + Boost::static_assert + Boost::throw_exception + Boost::utility + ) +endif () + +if (BOOST_STATIC_STRING_INSTALL AND NOT BOOST_SUPERPROJECT_VERSION) + install(TARGETS boost_static_string + RUNTIME DESTINATION "${CMAKE_INSTALL_BINDIR}" + LIBRARY DESTINATION "${CMAKE_INSTALL_LIBDIR}" + ARCHIVE DESTINATION "${CMAKE_INSTALL_LIBDIR}" + ) + + install(DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/include/boost + DESTINATION ${CMAKE_INSTALL_INCLUDEDIR} + FILES_MATCHING + PATTERN "*.hpp" + PATTERN "*.ipp" + ) +endif () + + +if (BOOST_STATIC_STRING_BUILD_TESTS) + add_subdirectory(test) +endif () -endif() diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index 844ed47..cee7ae2 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -1,5 +1,5 @@ # -# Copyright (c) 2016-2017 Vinnie Falco (vinnie dot falco at gmail dot com) +# Copyright (c) 2022 Alan de Freitas (alandefreitas@gmail.com) # # 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,16 +7,21 @@ # Official repository: https://github.com/boostorg/static_string # -GroupSources (include/boost/static_string static_string) -GroupSources (test "/") +set(BOOST_STATIC_STRING_TESTS_FILES + CMakeLists.txt + Jamfile + constexpr_tests.hpp + compile_fail.hpp + static_string.cpp + ) -add_executable (tests - ${PROJECT_FILES} - Jamfile - static_string.cpp -) +source_group(TREE ${CMAKE_CURRENT_SOURCE_DIR} FILES ${BOOST_STATIC_STRING_TESTS_FILES}) +add_executable(boost_static_string_tests ${BOOST_STATIC_STRING_TESTS_FILES}) -target_link_libraries(tests - ) - -set_property(TARGET tests PROPERTY FOLDER "tests") +# The include dependencies are found in the CMakeLists.txt +# of the root project directory. +# See: BOOST_STATIC_STRING_UNIT_TEST_LIBRARIES +target_link_libraries(boost_static_string_tests PRIVATE + Boost::static_string + Boost::core) +add_test(NAME boost_static_string_tests COMMAND boost_static_string_tests) From 25579e482f244e24183660e72194bd747c1bd5d0 Mon Sep 17 00:00:00 2001 From: alandefreitas Date: Tue, 1 Nov 2022 17:49:52 -0300 Subject: [PATCH 03/73] update jamfile fix #24 --- doc/Jamfile | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/doc/Jamfile b/doc/Jamfile index a513589..25c9a6f 100644 --- a/doc/Jamfile +++ b/doc/Jamfile @@ -1,6 +1,7 @@ # # Copyright (c) 2013-2017 Vinnie Falco (vinnie dot falco at gmail dot com) # Copyright (c) 2020 Krystian Stasiowski (sdkrystian at gmail dot com) +# Copyright (c) 2022 Alan de Freitas (alandefreitas@gmail.com) # # 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) @@ -9,16 +10,17 @@ project static_string/doc ; import boostbook ; +import type ; +import os ; import ../../../tools/docca/docca.jam ; - docca.reference reference.qbk : xsl/custom-overrides.xsl [ glob-tree-ex ../include/boost/static_string : *.hpp *.ipp : detail impl ] : PROJECT_NAME=StaticString - PROJECT_BRIEF="String Library" + PROJECT_BRIEF="Static String Library" ALIASES="esafe=\"@par Exception Safety\"" FILE_PATTERNS= EXAMPLE_PATTERNS= @@ -90,7 +92,7 @@ boostbook static_string chapter.autolabel=0 chunk.section.depth=8 # Depth to which sections should be chunked chunk.first.sections=1 # Chunk the first top-level section? - generate.toc="" + generate.toc="chapter toc,title section nop reference nop" ../../../tools/boostbook/dtd : images From c4f6491537f6ae45c56d04178aedd9377525443c Mon Sep 17 00:00:00 2001 From: alandefreitas Date: Tue, 1 Nov 2022 19:34:59 -0300 Subject: [PATCH 04/73] fix restrict warning --- .drone.star | 6 ++-- include/boost/static_string/static_string.hpp | 36 +++++++++++++------ 2 files changed, 29 insertions(+), 13 deletions(-) diff --git a/.drone.star b/.drone.star index 7cedae0..c2ac46a 100644 --- a/.drone.star +++ b/.drone.star @@ -38,8 +38,8 @@ def main(ctx): linux_cxx("Coverage", "g++-8", packages="g++-8", buildscript="drone", buildtype="codecov", image=linuxglobalimage, environment={'COMMENT': 'codecov.io', 'LCOV_BRANCH_COVERAGE': '0', 'B2_CXXSTD': '11', 'B2_TOOLSET': 'gcc-8', 'B2_DEFINES': 'BOOST_NO_STRESS_TEST=1', "CODECOV_TOKEN": {"from_secret": "codecov_token"}, "COVERALLS_REPO_TOKEN": {"from_secret": "coveralls_repo_token"}}, globalenv=globalenv), # Latest gcc - linux_cxx("GCC 12: C++17,20", "g++-12", packages="g++-12", buildscript="drone", buildtype="boost", image="cppalliance/droneubuntu2204:1", environment={'B2_TOOLSET': 'gcc-12', 'B2_CXXFLAGS': '-Werror -Wno-error=restrict', 'B2_CXXSTD': '17,20'}, globalenv=globalenv), - linux_cxx("GCC 12: C++17,20 Standalone", "g++-12", packages="g++-12", buildscript="drone", buildtype="boost", image="cppalliance/droneubuntu2204:1", environment={'B2_TOOLSET': 'gcc-12', 'B2_CXXFLAGS': '-Werror -Wno-error=restrict', 'B2_DEFINES': 'define=BOOST_STATIC_STRING_STANDALONE', 'B2_CXXSTD': '17,20'}, globalenv=globalenv), + linux_cxx("GCC 12: C++17,20", "g++-12", packages="g++-12", buildscript="drone", buildtype="boost", image="cppalliance/droneubuntu2204:1", environment={'B2_TOOLSET': 'gcc-12', 'B2_CXXFLAGS': '-Werror', 'B2_CXXSTD': '17,20'}, globalenv=globalenv), + linux_cxx("GCC 12: C++17,20 Standalone", "g++-12", packages="g++-12", buildscript="drone", buildtype="boost", image="cppalliance/droneubuntu2204:1", environment={'B2_TOOLSET': 'gcc-12', 'B2_CXXFLAGS': '-Werror', 'B2_DEFINES': 'define=BOOST_STATIC_STRING_STANDALONE', 'B2_CXXSTD': '17,20'}, globalenv=globalenv), # Latest clang linux_cxx("Clang 15: C++17,20", "clang++-15", packages="clang-15 libstdc++-10-dev", llvm_os="jammy", llvm_ver="15", buildscript="drone", buildtype="boost", image="cppalliance/droneubuntu2204:1", environment={'B2_TOOLSET': 'clang-15', 'B2_CXXFLAGS': '-Werror', 'B2_CXXSTD': '17,20'}, globalenv=globalenv), @@ -58,7 +58,7 @@ def main(ctx): linux_cxx("Valgrind", "clang++-14", packages="clang-14 libc6-dbg libc++-dev libstdc++-9-dev", llvm_os="jammy", llvm_ver="14", buildscript="drone", buildtype="valgrind", image="cppalliance/droneubuntu2204:1", environment={'COMMENT': 'valgrind', 'B2_TOOLSET': 'clang-14', 'B2_CXXSTD': '11,14,17', 'B2_DEFINES': 'BOOST_NO_STRESS_TEST=1', 'B2_VARIANT': 'debug', 'B2_TESTFLAGS': 'testing.launcher=valgrind', 'VALGRIND_OPTS': '--error-exitcode=1'}, globalenv=globalenv), # arm64 (unsigned char) - linux_cxx("ARM64: GCC 11", "g++-11", packages="g++-11", buildscript="drone", buildtype="boost", image="cppalliance/droneubuntu2004:multiarch", environment={'B2_TOOLSET': 'gcc-11', 'B2_CXXFLAGS': '-Werror -Wno-error=array-bounds -Wno-error=restrict -Wno-error=stringop-overflow', 'B2_CXXSTD': '17,20'}, arch="arm64", globalenv=globalenv), + linux_cxx("ARM64: GCC 11", "g++-11", packages="g++-11", buildscript="drone", buildtype="boost", image="cppalliance/droneubuntu2004:multiarch", environment={'B2_TOOLSET': 'gcc-11', 'B2_CXXFLAGS': '-Werror -Wno-error=array-bounds -Wno-error=stringop-overflow', 'B2_CXXSTD': '17,20'}, arch="arm64", globalenv=globalenv), # s390x linux_cxx("S390x: Clang 12", "clang++-12", packages="clang-12 libstdc++-9-dev", llvm_os="focal", llvm_ver="12", buildtype="boost", buildscript="drone", image="cppalliance/droneubuntu2004:multiarch", environment={'B2_TOOLSET': 'clang-12', 'B2_CXXFLAGS': '-Werror', 'B2_CXXSTD': '17,20'}, arch="s390x", globalenv=globalenv), diff --git a/include/boost/static_string/static_string.hpp b/include/boost/static_string/static_string.hpp index e69354c..71b345c 100644 --- a/include/boost/static_string/static_string.hpp +++ b/include/boost/static_string/static_string.hpp @@ -6063,33 +6063,49 @@ insert( detail::is_forward_iterator< ForwardIterator>::value, iterator>::type { + // input + const std::size_t count = detail::distance(first, last); + const auto first_addr = &*first; + const auto last_addr = first_addr + count; + + // output const auto curr_size = size(); const auto curr_data = data(); - const std::size_t count = detail::distance(first, last); const std::size_t index = pos - curr_data; - const auto first_addr = &*first; + auto dest = &curr_data[index]; + if (count > max_size() - curr_size) detail::throw_exception( "count > max_size() - curr_size"); + + traits_type::move(dest + count, dest, curr_size - index + 1); const bool inside = detail::ptr_in_range(curr_data, curr_data + curr_size, first_addr); - if (!inside || (inside && (first_addr + count <= pos))) + if (!inside || last_addr <= pos) { - traits_type::move(&curr_data[index + count], &curr_data[index], curr_size - index + 1); - detail::copy_with_traits(first, last, &curr_data[index]); + detail::copy_with_traits(first, last, dest); } - else + else /* if (inside) */ { const size_type offset = first_addr - curr_data; - traits_type::move(&curr_data[index + count], &curr_data[index], curr_size - index + 1); if (offset < index) { const size_type diff = index - offset; - traits_type::copy(&curr_data[index], &curr_data[offset], diff); - traits_type::copy(&curr_data[index + diff], &curr_data[index + count], count - diff); +#if BOOST_WORKAROUND( BOOST_GCC, >= 120000 ) + detail::copy_with_traits(&curr_data[offset], &curr_data[offset] + diff, dest); + detail::copy_with_traits(dest + count, dest + 2 * count - diff, &curr_data[index + diff]); +#else + traits_type::copy(dest, &curr_data[offset], diff); + traits_type::copy(&curr_data[index + diff], dest + count, count - diff); +#endif } else { - traits_type::copy(&curr_data[index], &curr_data[offset + count], count); + auto src = &curr_data[offset + count]; +#if BOOST_WORKAROUND( BOOST_GCC, >= 120000 ) + detail::copy_with_traits(src, src + count, dest); +#else + traits_type::copy(dest, src, count); +#endif } } this->set_size(curr_size + count); From ffce33d48335f7715a941d04ec83d61bce50eb70 Mon Sep 17 00:00:00 2001 From: alandefreitas Date: Wed, 2 Nov 2022 19:48:12 -0300 Subject: [PATCH 05/73] fix array-bounds warning --- .drone.star | 10 ++++----- CMakeLists.txt | 1 + include/boost/static_string/static_string.hpp | 22 +++++++++++-------- test/CMakeLists.txt | 4 +--- 4 files changed, 20 insertions(+), 17 deletions(-) diff --git a/.drone.star b/.drone.star index c2ac46a..6d3ba12 100644 --- a/.drone.star +++ b/.drone.star @@ -58,7 +58,7 @@ def main(ctx): linux_cxx("Valgrind", "clang++-14", packages="clang-14 libc6-dbg libc++-dev libstdc++-9-dev", llvm_os="jammy", llvm_ver="14", buildscript="drone", buildtype="valgrind", image="cppalliance/droneubuntu2204:1", environment={'COMMENT': 'valgrind', 'B2_TOOLSET': 'clang-14', 'B2_CXXSTD': '11,14,17', 'B2_DEFINES': 'BOOST_NO_STRESS_TEST=1', 'B2_VARIANT': 'debug', 'B2_TESTFLAGS': 'testing.launcher=valgrind', 'VALGRIND_OPTS': '--error-exitcode=1'}, globalenv=globalenv), # arm64 (unsigned char) - linux_cxx("ARM64: GCC 11", "g++-11", packages="g++-11", buildscript="drone", buildtype="boost", image="cppalliance/droneubuntu2004:multiarch", environment={'B2_TOOLSET': 'gcc-11', 'B2_CXXFLAGS': '-Werror -Wno-error=array-bounds -Wno-error=stringop-overflow', 'B2_CXXSTD': '17,20'}, arch="arm64", globalenv=globalenv), + linux_cxx("ARM64: GCC 11", "g++-11", packages="g++-11", buildscript="drone", buildtype="boost", image="cppalliance/droneubuntu2004:multiarch", environment={'B2_TOOLSET': 'gcc-11', 'B2_CXXFLAGS': '-Werror -Wno-error=stringop-overflow', 'B2_CXXSTD': '17,20'}, arch="arm64", globalenv=globalenv), # s390x linux_cxx("S390x: Clang 12", "clang++-12", packages="clang-12 libstdc++-9-dev", llvm_os="focal", llvm_ver="12", buildtype="boost", buildscript="drone", image="cppalliance/droneubuntu2004:multiarch", environment={'B2_TOOLSET': 'clang-12', 'B2_CXXFLAGS': '-Werror', 'B2_CXXSTD': '17,20'}, arch="s390x", globalenv=globalenv), @@ -82,10 +82,10 @@ def main(ctx): linux_cxx("GCC 5: C++11", "g++-5", packages="g++-5", buildscript="drone", buildtype="boost", image=linuxglobalimage, environment={'B2_TOOLSET': 'gcc-5', 'B2_CXXFLAGS': '-Werror', 'B2_CXXSTD': '11'}, globalenv=globalenv), linux_cxx("GCC 6: C++11,14", "g++-6", packages="g++-6", buildscript="drone", buildtype="boost", image=linuxglobalimage, environment={'B2_TOOLSET': 'gcc-6', 'B2_CXXFLAGS': '-Werror -Wno-error=unused-function', 'B2_CXXSTD': '11,14'}, globalenv=globalenv), linux_cxx("GCC 7: C++14,17", "g++-7", packages="g++-7", buildscript="drone", buildtype="boost", image=linuxglobalimage, environment={'B2_TOOLSET': 'gcc-7', 'B2_CXXFLAGS': '-Werror -Wno-error=unused-function -Wno-error=noexcept-type', 'B2_CXXSTD': '14,17'}, globalenv=globalenv), - linux_cxx("GCC 8: C++17", "g++-8", packages="g++-8", buildscript="drone", buildtype="boost", image=linuxglobalimage, environment={'B2_TOOLSET': 'gcc-8', 'B2_CXXFLAGS': '-Werror -Wno-error=unused-function -Wno-error=array-bounds', 'B2_CXXSTD': '17'}, globalenv=globalenv), + linux_cxx("GCC 8: C++17", "g++-8", packages="g++-8", buildscript="drone", buildtype="boost", image=linuxglobalimage, environment={'B2_TOOLSET': 'gcc-8', 'B2_CXXFLAGS': '-Werror -Wno-error=unused-function', 'B2_CXXSTD': '17'}, globalenv=globalenv), linux_cxx("GCC 9: C++17", "g++-9", packages="g++-9", buildscript="drone", buildtype="boost", image=linuxglobalimage, environment={'B2_TOOLSET': 'gcc-9', 'B2_CXXFLAGS': '-Werror', 'B2_CXXSTD': '17'}, globalenv=globalenv), - linux_cxx("GCC 10: C++17", "g++-10", packages="g++-10", buildscript="drone", buildtype="boost", image=linuxglobalimage, environment={'B2_TOOLSET': 'gcc-10', 'B2_CXXFLAGS': '-Werror -funsigned-char -Wno-error=array-bounds', 'B2_CXXSTD': '17'}, globalenv=globalenv), - linux_cxx("GCC 11: C++17,20", "g++-11", packages="g++-11", buildscript="drone", buildtype="boost", image=linuxglobalimage, environment={'B2_TOOLSET': 'gcc-11', 'B2_CXXFLAGS': '-Werror -Wno-error=array-bounds -Wno-error=stringop-overflow', 'B2_CXXSTD': '17,20'}, globalenv=globalenv), + linux_cxx("GCC 10: C++17", "g++-10", packages="g++-10", buildscript="drone", buildtype="boost", image=linuxglobalimage, environment={'B2_TOOLSET': 'gcc-10', 'B2_CXXFLAGS': '-Werror -funsigned-char', 'B2_CXXSTD': '17'}, globalenv=globalenv), + linux_cxx("GCC 11: C++17,20", "g++-11", packages="g++-11", buildscript="drone", buildtype="boost", image=linuxglobalimage, environment={'B2_TOOLSET': 'gcc-11', 'B2_CXXFLAGS': '-Werror -Wno-error=stringop-overflow', 'B2_CXXSTD': '17,20'}, globalenv=globalenv), # Clang (All other versions) linux_cxx("Clang 4.0: C++11,14", "clang++-4.0", packages="clang-4.0 libstdc++-6-dev", llvm_os="xenial", llvm_ver="4.0", buildscript="drone", buildtype="boost", image="cppalliance/droneubuntu1804:1", environment={'B2_TOOLSET': 'clang-4.0', 'B2_CXXFLAGS': '', 'B2_CXXSTD': '11,14'}, globalenv=globalenv), @@ -105,7 +105,7 @@ def main(ctx): linux_cxx("ARM64: Clang 12", "clang++-12", packages="clang-12 libstdc++-9-dev", llvm_os="focal", llvm_ver="12", buildscript="drone", buildtype="boost", image="cppalliance/droneubuntu2004:multiarch", environment={'B2_TOOLSET': 'clang-12', 'B2_CXXFLAGS': '-Werror', 'B2_CXXSTD': '11,14,17,20'}, arch="arm64", globalenv=globalenv), # s390x - linux_cxx("S390x: GCC 11", "g++-11", packages="g++-11", buildtype="boost", buildscript="drone", image="cppalliance/droneubuntu2004:multiarch", environment={'B2_TOOLSET': 'gcc-11', 'B2_CXXFLAGS': '-Werror -Wno-error=array-bounds', 'B2_CXXSTD': '17'}, arch="s390x", globalenv=globalenv), + linux_cxx("S390x: GCC 11", "g++-11", packages="g++-11", buildtype="boost", buildscript="drone", image="cppalliance/droneubuntu2004:multiarch", environment={'B2_TOOLSET': 'gcc-11', 'B2_CXXFLAGS': '-Werror', 'B2_CXXSTD': '17'}, arch="s390x", globalenv=globalenv), # MSVC windows_cxx("MSVC 14.1", "", image="cppalliance/dronevs2017", buildtype="boost", buildscript="drone", environment={"B2_TOOLSET": "msvc-14.1", 'B2_CXXFLAGS': '/WX', "B2_CXXSTD": "11,14,17"},globalenv=globalenv), diff --git a/CMakeLists.txt b/CMakeLists.txt index fabfdfa..4a0a639 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -89,6 +89,7 @@ else () INTERFACE Boost::assert Boost::container_hash + Boost::core Boost::static_assert Boost::throw_exception Boost::utility diff --git a/include/boost/static_string/static_string.hpp b/include/boost/static_string/static_string.hpp index 71b345c..c139d4e 100644 --- a/include/boost/static_string/static_string.hpp +++ b/include/boost/static_string/static_string.hpp @@ -14,6 +14,7 @@ // External include guard #ifndef BOOST_STATIC_STRING_CONFIG_HPP #include +#include #endif #include @@ -28,6 +29,13 @@ namespace boost { namespace static_strings { +#if BOOST_WORKAROUND(BOOST_GCC_VERSION, >= 80000) +#pragma GCC diagnostic push // false positives +#pragma GCC diagnostic ignored "-Warray-bounds" +#pragma GCC diagnostic ignored "-Wrestrict" +#pragma GCC diagnostic ignored "-Wstringop-overflow" +#endif + #ifndef BOOST_STATIC_STRING_DOCS template class basic_static_string; @@ -6090,22 +6098,13 @@ insert( if (offset < index) { const size_type diff = index - offset; -#if BOOST_WORKAROUND( BOOST_GCC, >= 120000 ) - detail::copy_with_traits(&curr_data[offset], &curr_data[offset] + diff, dest); - detail::copy_with_traits(dest + count, dest + 2 * count - diff, &curr_data[index + diff]); -#else traits_type::copy(dest, &curr_data[offset], diff); traits_type::copy(&curr_data[index + diff], dest + count, count - diff); -#endif } else { auto src = &curr_data[offset + count]; -#if BOOST_WORKAROUND( BOOST_GCC, >= 120000 ) - detail::copy_with_traits(src, src + count, dest); -#else traits_type::copy(dest, src, count); -#endif } } this->set_size(curr_size + count); @@ -6565,6 +6564,11 @@ insert_unchecked( this->set_size(curr_size + count); return curr_data + index; } + +#if BOOST_WORKAROUND(BOOST_GCC_VERSION, >= 80000) +#pragma GCC diagnostic pop +#endif + } // static_strings } // boost #endif diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index cee7ae2..9a9c727 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -21,7 +21,5 @@ add_executable(boost_static_string_tests ${BOOST_STATIC_STRING_TESTS_FILES}) # The include dependencies are found in the CMakeLists.txt # of the root project directory. # See: BOOST_STATIC_STRING_UNIT_TEST_LIBRARIES -target_link_libraries(boost_static_string_tests PRIVATE - Boost::static_string - Boost::core) +target_link_libraries(boost_static_string_tests PRIVATE Boost::static_string) add_test(NAME boost_static_string_tests COMMAND boost_static_string_tests) From bfce6eea90503484edf8a9b22dda01fa7ed26241 Mon Sep 17 00:00:00 2001 From: alandefreitas Date: Thu, 3 Nov 2022 18:10:59 -0300 Subject: [PATCH 06/73] fix unused-function warning --- .drone.star | 14 ++++++------ include/boost/static_string/static_string.hpp | 22 ++++++++++--------- test/static_string.cpp | 21 +++++++++++++++++- 3 files changed, 39 insertions(+), 18 deletions(-) diff --git a/.drone.star b/.drone.star index 6d3ba12..89603d1 100644 --- a/.drone.star +++ b/.drone.star @@ -58,7 +58,7 @@ def main(ctx): linux_cxx("Valgrind", "clang++-14", packages="clang-14 libc6-dbg libc++-dev libstdc++-9-dev", llvm_os="jammy", llvm_ver="14", buildscript="drone", buildtype="valgrind", image="cppalliance/droneubuntu2204:1", environment={'COMMENT': 'valgrind', 'B2_TOOLSET': 'clang-14', 'B2_CXXSTD': '11,14,17', 'B2_DEFINES': 'BOOST_NO_STRESS_TEST=1', 'B2_VARIANT': 'debug', 'B2_TESTFLAGS': 'testing.launcher=valgrind', 'VALGRIND_OPTS': '--error-exitcode=1'}, globalenv=globalenv), # arm64 (unsigned char) - linux_cxx("ARM64: GCC 11", "g++-11", packages="g++-11", buildscript="drone", buildtype="boost", image="cppalliance/droneubuntu2004:multiarch", environment={'B2_TOOLSET': 'gcc-11', 'B2_CXXFLAGS': '-Werror -Wno-error=stringop-overflow', 'B2_CXXSTD': '17,20'}, arch="arm64", globalenv=globalenv), + linux_cxx("ARM64: GCC 11", "g++-11", packages="g++-11", buildscript="drone", buildtype="boost", image="cppalliance/droneubuntu2004:multiarch", environment={'B2_TOOLSET': 'gcc-11', 'B2_CXXFLAGS': '-Werror', 'B2_CXXSTD': '17,20'}, arch="arm64", globalenv=globalenv), # s390x linux_cxx("S390x: Clang 12", "clang++-12", packages="clang-12 libstdc++-9-dev", llvm_os="focal", llvm_ver="12", buildtype="boost", buildscript="drone", image="cppalliance/droneubuntu2004:multiarch", environment={'B2_TOOLSET': 'clang-12', 'B2_CXXFLAGS': '-Werror', 'B2_CXXSTD': '17,20'}, arch="s390x", globalenv=globalenv), @@ -80,12 +80,12 @@ def main(ctx): # GCC (All other versions) linux_cxx("GCC 4.9: C++11", "g++-4.9", packages="g++-4.9", buildscript="drone", buildtype="boost", image="cppalliance/droneubuntu1604:1", environment={'B2_TOOLSET': 'gcc-4.9', 'B2_CXXFLAGS': '-Werror', 'B2_CXXSTD': '11'}, globalenv=globalenv), linux_cxx("GCC 5: C++11", "g++-5", packages="g++-5", buildscript="drone", buildtype="boost", image=linuxglobalimage, environment={'B2_TOOLSET': 'gcc-5', 'B2_CXXFLAGS': '-Werror', 'B2_CXXSTD': '11'}, globalenv=globalenv), - linux_cxx("GCC 6: C++11,14", "g++-6", packages="g++-6", buildscript="drone", buildtype="boost", image=linuxglobalimage, environment={'B2_TOOLSET': 'gcc-6', 'B2_CXXFLAGS': '-Werror -Wno-error=unused-function', 'B2_CXXSTD': '11,14'}, globalenv=globalenv), - linux_cxx("GCC 7: C++14,17", "g++-7", packages="g++-7", buildscript="drone", buildtype="boost", image=linuxglobalimage, environment={'B2_TOOLSET': 'gcc-7', 'B2_CXXFLAGS': '-Werror -Wno-error=unused-function -Wno-error=noexcept-type', 'B2_CXXSTD': '14,17'}, globalenv=globalenv), - linux_cxx("GCC 8: C++17", "g++-8", packages="g++-8", buildscript="drone", buildtype="boost", image=linuxglobalimage, environment={'B2_TOOLSET': 'gcc-8', 'B2_CXXFLAGS': '-Werror -Wno-error=unused-function', 'B2_CXXSTD': '17'}, globalenv=globalenv), + linux_cxx("GCC 6: C++11,14", "g++-6", packages="g++-6", buildscript="drone", buildtype="boost", image=linuxglobalimage, environment={'B2_TOOLSET': 'gcc-6', 'B2_CXXFLAGS': '-Werror', 'B2_CXXSTD': '11,14'}, globalenv=globalenv), + linux_cxx("GCC 7: C++14,17", "g++-7", packages="g++-7", buildscript="drone", buildtype="boost", image=linuxglobalimage, environment={'B2_TOOLSET': 'gcc-7', 'B2_CXXFLAGS': '-Werror -Wno-error=noexcept-type', 'B2_CXXSTD': '14,17'}, globalenv=globalenv), + linux_cxx("GCC 8: C++17", "g++-8", packages="g++-8", buildscript="drone", buildtype="boost", image=linuxglobalimage, environment={'B2_TOOLSET': 'gcc-8', 'B2_CXXFLAGS': '-Werror', 'B2_CXXSTD': '17'}, globalenv=globalenv), linux_cxx("GCC 9: C++17", "g++-9", packages="g++-9", buildscript="drone", buildtype="boost", image=linuxglobalimage, environment={'B2_TOOLSET': 'gcc-9', 'B2_CXXFLAGS': '-Werror', 'B2_CXXSTD': '17'}, globalenv=globalenv), - linux_cxx("GCC 10: C++17", "g++-10", packages="g++-10", buildscript="drone", buildtype="boost", image=linuxglobalimage, environment={'B2_TOOLSET': 'gcc-10', 'B2_CXXFLAGS': '-Werror -funsigned-char', 'B2_CXXSTD': '17'}, globalenv=globalenv), - linux_cxx("GCC 11: C++17,20", "g++-11", packages="g++-11", buildscript="drone", buildtype="boost", image=linuxglobalimage, environment={'B2_TOOLSET': 'gcc-11', 'B2_CXXFLAGS': '-Werror -Wno-error=stringop-overflow', 'B2_CXXSTD': '17,20'}, globalenv=globalenv), + linux_cxx("GCC 10: C++17", "g++-10", packages="g++-10", buildscript="drone", buildtype="boost", image=linuxglobalimage, environment={'B2_TOOLSET': 'gcc-10', 'B2_CXXFLAGS': '-Werror', 'B2_CXXSTD': '17'}, globalenv=globalenv), + linux_cxx("GCC 11: C++17,20", "g++-11", packages="g++-11", buildscript="drone", buildtype="boost", image=linuxglobalimage, environment={'B2_TOOLSET': 'gcc-11', 'B2_CXXFLAGS': '-Werror', 'B2_CXXSTD': '17,20'}, globalenv=globalenv), # Clang (All other versions) linux_cxx("Clang 4.0: C++11,14", "clang++-4.0", packages="clang-4.0 libstdc++-6-dev", llvm_os="xenial", llvm_ver="4.0", buildscript="drone", buildtype="boost", image="cppalliance/droneubuntu1804:1", environment={'B2_TOOLSET': 'clang-4.0', 'B2_CXXFLAGS': '', 'B2_CXXSTD': '11,14'}, globalenv=globalenv), @@ -95,7 +95,7 @@ def main(ctx): linux_cxx("Clang 7: C++17", "clang++-7", packages="clang-7 libc6-dbg libc++-dev libstdc++-8-dev", llvm_os="bionic", llvm_ver="7", buildscript="drone", buildtype="boost", image=linuxglobalimage, environment={'B2_TOOLSET': 'clang-7', 'B2_CXXFLAGS': '-Werror', 'B2_CXXSTD': '17'}, globalenv=globalenv), linux_cxx("Clang 8: C++17", "clang++-8", packages="clang-8 libc6-dbg libc++-dev libstdc++-8-dev", llvm_os="bionic", llvm_ver="8", buildscript="drone", buildtype="boost", image=linuxglobalimage, environment={'B2_TOOLSET': 'clang-8', 'B2_CXXFLAGS': '-Werror', 'B2_CXXSTD': '17'}, globalenv=globalenv), linux_cxx("Clang 9: C++14,17", "clang++-9", packages="clang-9 libstdc++-9-dev", llvm_os="bionic", llvm_ver="9", buildscript="drone", buildtype="boost", image=linuxglobalimage, environment={'B2_TOOLSET': 'clang-9', 'B2_CXXFLAGS': '-Werror', 'B2_CXXSTD': '14,17'}, globalenv=globalenv), - linux_cxx("Clang 10: C++14,17", "clang++-10", packages="clang-10 libstdc++-9-dev", llvm_os="focal", llvm_ver="10", buildscript="drone", buildtype="boost", image="cppalliance/droneubuntu2004:1", environment={'B2_TOOLSET': 'clang-10', 'B2_CXXFLAGS': '-Werror -funsigned-char', 'B2_CXXSTD': '14,17'}, globalenv=globalenv), + linux_cxx("Clang 10: C++14,17", "clang++-10", packages="clang-10 libstdc++-9-dev", llvm_os="focal", llvm_ver="10", buildscript="drone", buildtype="boost", image="cppalliance/droneubuntu2004:1", environment={'B2_TOOLSET': 'clang-10', 'B2_CXXFLAGS': '-Werror', 'B2_CXXSTD': '14,17'}, globalenv=globalenv), linux_cxx("Clang 11: C++14,17", "clang++-11", packages="clang-11 libstdc++-9-dev", llvm_os="focal", llvm_ver="11", buildscript="drone", buildtype="boost", image="cppalliance/droneubuntu2004:1", environment={'B2_TOOLSET': 'clang-11', 'B2_CXXFLAGS': '-Werror', 'B2_CXXSTD': '14,17'}, globalenv=globalenv), linux_cxx("Clang 12: C++17,20", "clang++-12", packages="clang-12 libstdc++-9-dev", llvm_os="focal", llvm_ver="12", buildscript="drone", buildtype="boost", image="cppalliance/droneubuntu2004:1", environment={'B2_TOOLSET': 'clang-12', 'B2_CXXFLAGS': '-Werror', 'B2_CXXSTD': '17,20'}, globalenv=globalenv), linux_cxx("Clang 13: C++17,20", "clang++-13", packages="clang-13 libstdc++-10-dev", llvm_os="jammy", llvm_ver="13", buildscript="drone", buildtype="boost", image="cppalliance/droneubuntu2204:1", environment={'B2_TOOLSET': 'clang-13', 'B2_CXXFLAGS': '-Werror', 'B2_CXXSTD': '17,20'}, globalenv=globalenv), diff --git a/include/boost/static_string/static_string.hpp b/include/boost/static_string/static_string.hpp index c139d4e..d558d9a 100644 --- a/include/boost/static_string/static_string.hpp +++ b/include/boost/static_string/static_string.hpp @@ -11,6 +11,14 @@ #ifndef BOOST_STATIC_STRING_STATIC_STRING_HPP #define BOOST_STATIC_STRING_STATIC_STRING_HPP +#if defined(__GNUC__) && __GNUC__ >= 8 +#pragma GCC diagnostic push // false positives +#pragma GCC system_header +#pragma GCC diagnostic ignored "-Warray-bounds" +#pragma GCC diagnostic ignored "-Wrestrict" +#pragma GCC diagnostic ignored "-Wstringop-overflow" +#endif + // External include guard #ifndef BOOST_STATIC_STRING_CONFIG_HPP #include @@ -29,13 +37,6 @@ namespace boost { namespace static_strings { -#if BOOST_WORKAROUND(BOOST_GCC_VERSION, >= 80000) -#pragma GCC diagnostic push // false positives -#pragma GCC diagnostic ignored "-Warray-bounds" -#pragma GCC diagnostic ignored "-Wrestrict" -#pragma GCC diagnostic ignored "-Wstringop-overflow" -#endif - #ifndef BOOST_STATIC_STRING_DOCS template class basic_static_string; @@ -6565,11 +6566,12 @@ insert_unchecked( return curr_data + index; } -#if BOOST_WORKAROUND(BOOST_GCC_VERSION, >= 80000) +} // static_strings +} // boost + +#if defined(__GNUC__) && __GNUC__ >= 8 #pragma GCC diagnostic pop #endif -} // static_strings -} // boost #endif #endif diff --git a/test/static_string.cpp b/test/static_string.cpp index 8ef6481..cfeb2a1 100644 --- a/test/static_string.cpp +++ b/test/static_string.cpp @@ -899,6 +899,11 @@ testClear() BOOST_TEST(*s.end() == 0); } +#if defined(__GNUC__) && __GNUC__ >= 8 +#pragma GCC diagnostic push // false positives +#pragma GCC diagnostic ignored "-Wstringop-overflow" +#endif + // done static void @@ -1642,6 +1647,10 @@ testInsert() BOOST_TEST(testI(S("abcdefghijklmnopqrst"), 21, "12345678901234567890", 20, S("can't happen"))); } +#if defined(__GNUC__) && __GNUC__ >= 8 +#pragma GCC diagnostic pop +#endif + // done static void @@ -5818,6 +5827,11 @@ testFind() #include +#if defined(__GNUC__) && __GNUC__ >= 8 +#pragma GCC diagnostic push // false positives +#pragma GCC diagnostic ignored "-Wstringop-overflow" +#endif + // done void testReplace() @@ -6822,6 +6836,10 @@ testReplace() BOOST_TEST_THROWS(T("aaaaa").replace(0, 1, S("bbbbbbbbbbbbb")), std::length_error); } +#if defined(__GNUC__) && __GNUC__ >= 8 +#pragma GCC diagnostic pop +#endif + // done void testSubstr() @@ -7253,4 +7271,5 @@ int main() { return boost::static_strings::runTests(); -} \ No newline at end of file +} + From 0c914ff05ba74358c4ac628e1e6fb98da93f32d0 Mon Sep 17 00:00:00 2001 From: alandefreitas Date: Fri, 4 Nov 2022 02:51:02 -0300 Subject: [PATCH 07/73] fix noexcept-type warning --- .drone.star | 2 +- include/boost/static_string/static_string.hpp | 13 ++++++++++++- 2 files changed, 13 insertions(+), 2 deletions(-) diff --git a/.drone.star b/.drone.star index 89603d1..e0e8f5e 100644 --- a/.drone.star +++ b/.drone.star @@ -81,7 +81,7 @@ def main(ctx): linux_cxx("GCC 4.9: C++11", "g++-4.9", packages="g++-4.9", buildscript="drone", buildtype="boost", image="cppalliance/droneubuntu1604:1", environment={'B2_TOOLSET': 'gcc-4.9', 'B2_CXXFLAGS': '-Werror', 'B2_CXXSTD': '11'}, globalenv=globalenv), linux_cxx("GCC 5: C++11", "g++-5", packages="g++-5", buildscript="drone", buildtype="boost", image=linuxglobalimage, environment={'B2_TOOLSET': 'gcc-5', 'B2_CXXFLAGS': '-Werror', 'B2_CXXSTD': '11'}, globalenv=globalenv), linux_cxx("GCC 6: C++11,14", "g++-6", packages="g++-6", buildscript="drone", buildtype="boost", image=linuxglobalimage, environment={'B2_TOOLSET': 'gcc-6', 'B2_CXXFLAGS': '-Werror', 'B2_CXXSTD': '11,14'}, globalenv=globalenv), - linux_cxx("GCC 7: C++14,17", "g++-7", packages="g++-7", buildscript="drone", buildtype="boost", image=linuxglobalimage, environment={'B2_TOOLSET': 'gcc-7', 'B2_CXXFLAGS': '-Werror -Wno-error=noexcept-type', 'B2_CXXSTD': '14,17'}, globalenv=globalenv), + linux_cxx("GCC 7: C++14,17", "g++-7", packages="g++-7", buildscript="drone", buildtype="boost", image=linuxglobalimage, environment={'B2_TOOLSET': 'gcc-7', 'B2_CXXFLAGS': '-Werror', 'B2_CXXSTD': '14,17'}, globalenv=globalenv), linux_cxx("GCC 8: C++17", "g++-8", packages="g++-8", buildscript="drone", buildtype="boost", image=linuxglobalimage, environment={'B2_TOOLSET': 'gcc-8', 'B2_CXXFLAGS': '-Werror', 'B2_CXXSTD': '17'}, globalenv=globalenv), linux_cxx("GCC 9: C++17", "g++-9", packages="g++-9", buildscript="drone", buildtype="boost", image=linuxglobalimage, environment={'B2_TOOLSET': 'gcc-9', 'B2_CXXFLAGS': '-Werror', 'B2_CXXSTD': '17'}, globalenv=globalenv), linux_cxx("GCC 10: C++17", "g++-10", packages="g++-10", buildscript="drone", buildtype="boost", image=linuxglobalimage, environment={'B2_TOOLSET': 'gcc-10', 'B2_CXXFLAGS': '-Werror', 'B2_CXXSTD': '17'}, globalenv=globalenv), diff --git a/include/boost/static_string/static_string.hpp b/include/boost/static_string/static_string.hpp index d558d9a..12a3ab1 100644 --- a/include/boost/static_string/static_string.hpp +++ b/include/boost/static_string/static_string.hpp @@ -12,13 +12,19 @@ #define BOOST_STATIC_STRING_STATIC_STRING_HPP #if defined(__GNUC__) && __GNUC__ >= 8 -#pragma GCC diagnostic push // false positives +#pragma GCC diagnostic push #pragma GCC system_header +// false positives #pragma GCC diagnostic ignored "-Warray-bounds" #pragma GCC diagnostic ignored "-Wrestrict" #pragma GCC diagnostic ignored "-Wstringop-overflow" #endif +#if defined(__GNUC__) && __GNUC__ >= 7 +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wnoexcept-type" +#endif + // External include guard #ifndef BOOST_STATIC_STRING_CONFIG_HPP #include @@ -6569,9 +6575,14 @@ insert_unchecked( } // static_strings } // boost +#if defined(__GNUC__) && __GNUC__ >= 7 +#pragma GCC diagnostic pop +#endif + #if defined(__GNUC__) && __GNUC__ >= 8 #pragma GCC diagnostic pop #endif + #endif #endif From 9c3d5febe76d92f86cdff68d2589e57ff50c850b Mon Sep 17 00:00:00 2001 From: alandefreitas Date: Thu, 12 Jan 2023 13:02:42 -0300 Subject: [PATCH 08/73] tests include main header --- test/static_string.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/static_string.cpp b/test/static_string.cpp index cfeb2a1..9f8541c 100644 --- a/test/static_string.cpp +++ b/test/static_string.cpp @@ -9,7 +9,7 @@ // // Test that header file is self-contained. -#include +#include #include "constexpr_tests.hpp" #include "compile_fail.hpp" From 82ff4e067964798886c6072e0be248aa3515489e Mon Sep 17 00:00:00 2001 From: alandefreitas Date: Wed, 11 Jan 2023 23:14:58 -0300 Subject: [PATCH 09/73] static_string<0> does not memcpy fix #41 --- include/boost/static_string/static_string.hpp | 2 +- test/static_string.cpp | 7 +++++++ 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/include/boost/static_string/static_string.hpp b/include/boost/static_string/static_string.hpp index 12a3ab1..60dae3b 100644 --- a/include/boost/static_string/static_string.hpp +++ b/include/boost/static_string/static_string.hpp @@ -1319,7 +1319,7 @@ class basic_static_string basic_static_string& assign(const basic_static_string& s) noexcept { - if (this == &s) + if (data() == s.data()) return *this; return assign_unchecked(s.data(), s.size()); } diff --git a/test/static_string.cpp b/test/static_string.cpp index 9f8541c..5288b45 100644 --- a/test/static_string.cpp +++ b/test/static_string.cpp @@ -674,6 +674,13 @@ testAssignment() s_long.assign(s_long.data() + 2, 8); BOOST_TEST(s_long == "rem ipsu"); + + // issue #41 + { + boost::static_strings::static_string<0> a; + auto b = a; + BOOST_TEST(b == ""); + } } // done From 269987446ed2e6e3b8ddac0d772bd2c8949a6a97 Mon Sep 17 00:00:00 2001 From: alandefreitas Date: Wed, 11 Jan 2023 23:21:00 -0300 Subject: [PATCH 10/73] check for char8_t directly fix #40 --- include/boost/static_string/static_string.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/boost/static_string/static_string.hpp b/include/boost/static_string/static_string.hpp index 60dae3b..6258b6e 100644 --- a/include/boost/static_string/static_string.hpp +++ b/include/boost/static_string/static_string.hpp @@ -69,7 +69,7 @@ template using static_u32string = basic_static_string>; -#ifdef BOOST_STATIC_STRING_CPP20 +#ifdef __cpp_char8_t template using static_u8string = basic_static_string>; From ac84c4f40ec38f7a7237255738e3e5259aa4a1a8 Mon Sep 17 00:00:00 2001 From: alandefreitas Date: Thu, 12 Jan 2023 18:16:06 -0300 Subject: [PATCH 11/73] string_view interoperability fix #26 --- include/boost/static_string/config.hpp | 44 ++ include/boost/static_string/static_string.hpp | 491 ++++++++++++++++-- test/constexpr_tests.hpp | 2 + test/static_string.cpp | 220 +++++++- 4 files changed, 692 insertions(+), 65 deletions(-) diff --git a/include/boost/static_string/config.hpp b/include/boost/static_string/config.hpp index 02b3ad5..2217fe8 100644 --- a/include/boost/static_string/config.hpp +++ b/include/boost/static_string/config.hpp @@ -147,15 +147,51 @@ #endif #ifndef BOOST_STATIC_STRING_STANDALONE +#include #include #include #include #include +#include #include + +#if !defined(BOOST_NO_CXX17_HDR_STRING_VIEW) || \ + defined(BOOST_STATIC_STRING_CXX17_STRING_VIEW) +#include +#define BOOST_STATIC_STRING_HAS_STD_STRING_VIEW +#endif #else #include #include + +/* + * Replicate the logic from Boost.Config + */ +// GNU libstdc++3: +#if defined(__GLIBCPP__) || defined(__GLIBCXX__) +#if (BOOST_LIBSTDCXX_VERSION < 70100) || (__cplusplus <= 201402L) +# define BOOST_STATIC_STRING_NO_CXX17_HDR_STRING_VIEW +#endif +// libc++: +#elif defined(_LIBCPP_VERSION) +#if (_LIBCPP_VERSION < 4000) || (__cplusplus <= 201402L) +# define BOOST_STATIC_STRING_NO_CXX17_HDR_STRING_VIEW +#endif +// MSVC uses logic from catch all for BOOST_NO_CXX17_HDR_STRING_VIEW +// catch all: +#elif !defined(_YVALS) && !defined(_CPPLIB_VER) +#if (!defined(__has_include) || (__cplusplus < 201700)) +# define BOOST_STATIC_STRING_NO_CXX17_HDR_STRING_VIEW +#elif !__has_include() +# define BOOST_STATIC_STRING_NO_CXX17_HDR_STRING_VIEW +#endif +#endif + +#if !defined(BOOST_STATIC_STRING_NO_CXX17_HDR_STRING_VIEW) || \ + defined(BOOST_STATIC_STRING_CXX17_STRING_VIEW) #include +#define BOOST_STATIC_STRING_HAS_STD_STRING_VIEW +#endif #endif // Compiler bug prevents constexpr from working with clang 4.x and 5.x @@ -192,6 +228,12 @@ defined(BOOST_STATIC_STRING_CPP14) #define BOOST_STATIC_STRING_GCC5_BAD_CONSTEXPR #endif +// Define the basic string_view type used by the library +// Conversions to and from other available string_view types +// are still defined. +#if !defined(BOOST_STATIC_STRING_STANDALONE) || \ + defined(BOOST_STATIC_STRING_HAS_STD_STRING_VIEW) +#define BOOST_STATIC_STRING_HAS_ANY_STRING_VIEW namespace boost { namespace static_strings { @@ -205,4 +247,6 @@ using basic_string_view = #endif } // static_strings } // boost +#endif + #endif \ No newline at end of file diff --git a/include/boost/static_string/static_string.hpp b/include/boost/static_string/static_string.hpp index 6258b6e..b899d54 100644 --- a/include/boost/static_string/static_string.hpp +++ b/include/boost/static_string/static_string.hpp @@ -37,6 +37,7 @@ #include #include #include +#include #include #include @@ -126,16 +127,43 @@ struct void_t_helper template using void_t = typename void_t_helper::type; +template +struct is_string_like : std::false_type {}; + +template +struct is_string_like< + T, CharT, + void_t< + decltype(std::declval() = std::declval().data()), + decltype(std::declval() = std::declval().size())>> + : std::true_type +{}; + // Check if a type can be used for templated // overloads string_view_type +// This will be used by overloads that accept the string_view types +// directly and other convertible types such as std::string. +// When no string_view type is available, then we check for the +// data and size member functions, and use them directly for assignments. template struct enable_if_viewable { }; template struct enable_if_viewable>::value && - !std::is_convertible::value>::type> + typename std::enable_if< +#if !defined(BOOST_STATIC_STRING_HAS_ANY_STRING_VIEW) + is_string_like::value +#elif defined(BOOST_STATIC_STRING_STANDALONE) + std::is_convertible>::value && + !std::is_convertible::value +#else + ( + std::is_convertible>::value || + std::is_convertible>::value + ) && + !std::is_convertible::value +#endif + >::type> { using type = void; }; @@ -143,6 +171,59 @@ struct enable_if_viewable using enable_if_viewable_t = typename enable_if_viewable::type; +// The common string_view type used in private operations with enable_if_viewable_t +// - T const& itself when no string_view type is available +// - basic_string_view (boost::string_view or std::string_view) when in +// standalone because core::detail::string_view is unavailable +// - core::detail::basic_string_view otherwise because it's convertible +// to and from most types, including std::string_view +// After converting a parameter to a common_string_view_type reference, we +// can use the data() and size() member functions. +#if !defined(BOOST_STATIC_STRING_HAS_ANY_STRING_VIEW) +template +using common_string_view_type = T const&; +#elif defined(BOOST_STATIC_STRING_STANDALONE) +template +using common_string_view_type = basic_string_view; +#else +template +struct common_string_view_type_impl {}; + +template +struct common_string_view_type_impl< + T, CharT, Traits, + typename std::enable_if< + is_string_like::value && + !std::is_convertible>::value && + !std::is_convertible>::value>::type> +{ + using type = T const&; +}; + +template +struct common_string_view_type_impl< + T, CharT, Traits, + typename std::enable_if< + std::is_convertible>::value && + !std::is_convertible>::value>::type> +{ + using type = basic_string_view; +}; + +template +struct common_string_view_type_impl< + T, CharT, Traits, + typename std::enable_if< + std::is_convertible>::value>::type> +{ + using type = core::basic_string_view; +}; + +template +using common_string_view_type = typename common_string_view_type_impl::type; +#endif + + // Simplified check for if a type is an iterator template struct is_iterator : std::false_type { }; @@ -879,9 +960,11 @@ class basic_static_string using const_reverse_iterator = std::reverse_iterator; +#ifdef BOOST_STATIC_STRING_HAS_ANY_STRING_VIEW /// The string view type. using string_view_type = basic_string_view; +#endif //-------------------------------------------------------------------------- // @@ -1538,7 +1621,7 @@ class basic_static_string basic_static_string& assign(const T& t) { - const string_view_type sv = t; + detail::common_string_view_type sv = t; return assign(sv.data(), sv.size()); } @@ -1590,8 +1673,12 @@ class basic_static_string size_type pos, size_type count = npos) { - const auto sv = string_view_type(t).substr(pos, count); - return assign(sv.data(), sv.size()); + detail::common_string_view_type sv = t; + if( pos > sv.size() ) + detail::throw_exception( + "pos >= t.size()"); + std::size_t rlen = (std::min)( count, sv.size() - pos ); + return assign(sv.data() + pos, rlen); } //-------------------------------------------------------------------------- @@ -1837,6 +1924,7 @@ class basic_static_string return data(); } +#ifdef BOOST_STATIC_STRING_DOCS /** Convert to a string view referring to the string. Returns a string view referring to the @@ -1851,6 +1939,28 @@ class basic_static_string { return string_view_type(data(), size()); } +#else +#ifdef BOOST_STATIC_STRING_HAS_STD_STRING_VIEW + BOOST_STATIC_STRING_CPP11_CONSTEXPR + operator std::basic_string_view() const noexcept + { + return std::basic_string_view(data(), size()); + } +#endif +#ifndef BOOST_STATIC_STRING_STANDALONE + BOOST_STATIC_STRING_CPP11_CONSTEXPR + operator ::boost::basic_string_view() const noexcept + { + return ::boost::basic_string_view(data(), size()); + } + + BOOST_STATIC_STRING_CPP11_CONSTEXPR + operator ::boost::core::basic_string_view() const noexcept + { + return ::boost::core::basic_string_view(data(), size()); + } +#endif +#endif //-------------------------------------------------------------------------- // @@ -2503,7 +2613,7 @@ class basic_static_string size_type index, const T& t) { - const string_view_type sv = t; + detail::common_string_view_type sv = t; return insert(index, sv.data(), sv.size()); } @@ -2552,8 +2662,10 @@ class basic_static_string size_type index_str, size_type count = npos) { - const auto sv = string_view_type(t).substr(index_str, count); - return insert(index, sv.data(), sv.size()); + detail::common_string_view_type sv(t); + if ( index_str > sv.size() ) + detail::throw_exception("index_str > t.size()"); + return insert(index, sv.data() + index_str, (std::min)(sv.size() - index_str, count)); } /** Erase from the string. @@ -2912,7 +3024,7 @@ class basic_static_string basic_static_string& append(const T& t) { - const string_view_type sv = t; + detail::common_string_view_type sv = t; return append(sv.data(), sv.size()); } @@ -2957,8 +3069,10 @@ class basic_static_string size_type pos, size_type count = npos) { - const auto sv = string_view_type(t).substr(pos, count); - return append(sv.data(), sv.size()); + detail::common_string_view_type sv = t; + if ( pos > sv.size() ) + detail::throw_exception("pos > t.size()"); + return append(sv.data() + pos, (std::min)(sv.size() - pos, count)); } /** Append to the string. @@ -3342,7 +3456,7 @@ class basic_static_string int compare(const T& t) const noexcept { - const string_view_type sv = t; + detail::common_string_view_type sv = t; return detail::lexicographical_compare( data(), size(), sv.data(), sv.size()); } @@ -3393,7 +3507,7 @@ class basic_static_string size_type count1, const T& t) const { - const string_view_type sv = t; + detail::common_string_view_type sv = t; return detail::lexicographical_compare( data() + pos1, capped_length(pos1, count1), sv.data(), sv.size()); } @@ -3450,9 +3564,12 @@ class basic_static_string size_type pos2, size_type count2 = npos) const { - const auto sv = string_view_type(t).substr(pos2, count2); - return compare(pos1, count1, - sv.data(), sv.size()); + detail::common_string_view_type sv = t; + if ( pos2 > sv.size()) + detail::throw_exception("pos2 > sv.size()"); + return compare( + pos1, count1, sv.data() + pos2, + (std::min)(sv.size() - pos2, count2)); } /** Return a substring. @@ -3485,6 +3602,7 @@ class basic_static_string data() + pos, capped_length(pos, count)); } +#ifdef BOOST_STATIC_STRING_HAS_ANY_STRING_VIEW /** Return a string view of a substring. Returns a view of a substring. @@ -3512,6 +3630,7 @@ class basic_static_string return string_view_type( data() + pos, capped_length(pos, count)); } +#endif /** Copy a substring to another string. @@ -3771,7 +3890,7 @@ class basic_static_string size_type n1, const T& t) { - const string_view_type sv = t; + detail::common_string_view_type sv = t; return replace(pos1, n1, sv.data(), sv.size()); } @@ -3823,8 +3942,12 @@ class basic_static_string size_type pos2, size_type n2 = npos) { - const string_view_type sv = t; - return replace(pos1, n1, sv.substr(pos2, n2)); + detail::common_string_view_type sv = t; + if ( pos2 > sv.size()) + detail::throw_exception("pos2 > t.size()"); + return replace( + pos1, n1, sv.data() + pos2, + (std::min)(sv.size() - pos2, n2)); } /** Replace a part of the string. @@ -4029,8 +4152,8 @@ class basic_static_string const_iterator i2, const T& t) { - const string_view_type sv = t; - return replace(i1, i2, sv.begin(), sv.end()); + detail::common_string_view_type sv = t; + return replace(i1, i2, sv.data(), sv.data() + sv.size()); } /** Replace a part of the string. @@ -4290,9 +4413,13 @@ class basic_static_string find( const T& t, size_type pos = 0) const +#ifdef BOOST_STATIC_STRING_DOCS noexcept(detail::is_nothrow_convertible::value) +#else + noexcept(detail::is_nothrow_convertible>::value) +#endif { - const string_view_type sv = t; + detail::common_string_view_type sv = t; return find(sv.data(), pos, sv.size()); } @@ -4443,9 +4570,13 @@ class basic_static_string rfind( const T& t, size_type pos = npos) const +#ifdef BOOST_STATIC_STRING_DOCS noexcept(detail::is_nothrow_convertible::value) +#else + noexcept(detail::is_nothrow_convertible>::value) +#endif { - const string_view_type sv = t; + detail::common_string_view_type sv = t; return rfind(sv.data(), pos, sv.size()); } @@ -4591,9 +4722,13 @@ class basic_static_string find_first_of( const T& t, size_type pos = 0) const +#ifdef BOOST_STATIC_STRING_DOCS noexcept(detail::is_nothrow_convertible::value) +#else + noexcept(detail::is_nothrow_convertible>::value) +#endif { - const string_view_type sv = t; + detail::common_string_view_type sv = t; return find_first_of(sv.data(), pos, sv.size()); } @@ -4734,9 +4869,13 @@ class basic_static_string find_last_of( const T& t, size_type pos = npos) const +#ifdef BOOST_STATIC_STRING_DOCS noexcept(detail::is_nothrow_convertible::value) +#else + noexcept(detail::is_nothrow_convertible>::value) +#endif { - const string_view_type sv = t; + detail::common_string_view_type sv = t; return find_last_of(sv.data(), pos, sv.size()); } @@ -4876,9 +5015,13 @@ class basic_static_string find_first_not_of( const T& t, size_type pos = 0) const +#ifdef BOOST_STATIC_STRING_DOCS noexcept(detail::is_nothrow_convertible::value) +#else + noexcept(detail::is_nothrow_convertible>::value) +#endif { - const string_view_type sv = t; + detail::common_string_view_type sv = t; return find_first_not_of(sv.data(), pos, sv.size()); } @@ -5017,9 +5160,13 @@ class basic_static_string find_last_not_of( const T& t, size_type pos = npos) const +#ifdef BOOST_STATIC_STRING_DOCS noexcept(detail::is_nothrow_convertible::value) +#else + noexcept(detail::is_nothrow_convertible>::value) +#endif { - const string_view_type sv = t; + detail::common_string_view_type sv = t; return find_last_not_of(sv.data(), pos, sv.size()); } @@ -5133,15 +5280,21 @@ class basic_static_string Linear. - @param s The string view to check for. + @param t The string view to check for. */ + template +#endif + > BOOST_STATIC_STRING_CPP14_CONSTEXPR bool starts_with( - string_view_type s) const noexcept + T const& t) const noexcept { - const size_type len = s.size(); - return size() >= len && !traits_type::compare(data(), s.data(), len); + detail::common_string_view_type sv = t; + const size_type len = sv.size(); + return size() >= len && !traits_type::compare(data(), sv.data(), len); } /** Return whether the string begins with a character. @@ -5191,15 +5344,21 @@ class basic_static_string Linear. - @param s The string view to check for. + @param t The string view to check for. */ + template +#endif + > BOOST_STATIC_STRING_CPP14_CONSTEXPR bool ends_with( - string_view_type s) const noexcept + T const& t) const noexcept { - const size_type len = s.size(); - return size() >= len && !traits_type::compare(data() + (size() - len), s.data(), len); + detail::common_string_view_type sv = t; + const size_type len = sv.size(); + return size() >= len && !traits_type::compare(data() + (size() - len), sv.data(), len); } /** Return whether the string ends with a character. @@ -5456,6 +5615,42 @@ operator==( rhs, Traits::length(rhs)) == 0; } +template +#endif + > +BOOST_STATIC_STRING_CPP14_CONSTEXPR +inline +bool +operator==( + const T& lhs, + const basic_static_string& rhs) +{ + detail::common_string_view_type lhsv = lhs; + return detail::lexicographical_compare( + lhsv.data(), lhsv.size(), + rhs.data(), rhs.size()) == 0; +} + +template +#endif + > +BOOST_STATIC_STRING_CPP14_CONSTEXPR +inline +bool +operator==( + const basic_static_string& lhs, + const T& rhs) +{ + detail::common_string_view_type rhsv = rhs; + return detail::lexicographical_compare( + lhs.data(), lhs.size(), + rhsv.data(), rhsv.size()) == 0; +} + template BOOST_STATIC_STRING_CPP14_CONSTEXPR inline @@ -5482,6 +5677,42 @@ operator!=( rhs, Traits::length(rhs)) != 0; } +template +#endif + > +BOOST_STATIC_STRING_CPP14_CONSTEXPR +inline +bool +operator!=( + const T& lhs, + const basic_static_string& rhs) +{ + detail::common_string_view_type lhsv = lhs; + return detail::lexicographical_compare( + lhsv.data(), lhsv.size(), + rhs.data(), rhs.size()) != 0; +} + +template +#endif + > +BOOST_STATIC_STRING_CPP14_CONSTEXPR +inline +bool +operator!=( + const basic_static_string& lhs, + const T& rhs) +{ + detail::common_string_view_type rhsv = rhs; + return detail::lexicographical_compare( + lhs.data(), lhs.size(), + rhsv.data(), rhsv.size()) != 0; +} + template BOOST_STATIC_STRING_CPP14_CONSTEXPR inline @@ -5508,6 +5739,42 @@ operator<( rhs, Traits::length(rhs)) < 0; } +template +#endif + > +BOOST_STATIC_STRING_CPP14_CONSTEXPR +inline +bool +operator<( + const T& lhs, + const basic_static_string& rhs) +{ + detail::common_string_view_type lhsv = lhs; + return detail::lexicographical_compare( + lhsv.data(), lhsv.size(), + rhs.data(), rhs.size()) < 0; +} + +template +#endif + > +BOOST_STATIC_STRING_CPP14_CONSTEXPR +inline +bool +operator<( + const basic_static_string& lhs, + const T& rhs) +{ + detail::common_string_view_type rhsv = rhs; + return detail::lexicographical_compare( + lhs.data(), lhs.size(), + rhsv.data(), rhsv.size()) < 0; +} + template BOOST_STATIC_STRING_CPP14_CONSTEXPR inline @@ -5534,6 +5801,42 @@ operator<=( rhs, Traits::length(rhs)) <= 0; } +template +#endif + > +BOOST_STATIC_STRING_CPP14_CONSTEXPR +inline +bool +operator<=( + const T& lhs, + const basic_static_string& rhs) +{ + detail::common_string_view_type lhsv = lhs; + return detail::lexicographical_compare( + lhsv.data(), lhsv.size(), + rhs.data(), rhs.size()) <= 0; +} + +template +#endif + > +BOOST_STATIC_STRING_CPP14_CONSTEXPR +inline +bool +operator<=( + const basic_static_string& lhs, + const T& rhs) +{ + detail::common_string_view_type rhsv = rhs; + return detail::lexicographical_compare( + lhs.data(), lhs.size(), + rhsv.data(), rhsv.size()) <= 0; +} + template BOOST_STATIC_STRING_CPP14_CONSTEXPR inline @@ -5560,6 +5863,43 @@ operator>( rhs, Traits::length(rhs)) > 0; } +template +#endif + > +BOOST_STATIC_STRING_CPP14_CONSTEXPR +inline +bool +operator>( + const T& lhs, + const basic_static_string& rhs) +{ + detail::common_string_view_type lhsv = lhs; + return detail::lexicographical_compare( + lhsv.data(), lhsv.size(), + rhs.data(), rhs.size()) > 0; +} + +template +#endif + > +BOOST_STATIC_STRING_CPP14_CONSTEXPR +inline +bool +operator>( + const basic_static_string& lhs, + const T& rhs) +{ + detail::common_string_view_type rhsv = rhs; + return detail::lexicographical_compare( + lhs.data(), lhs.size(), + rhsv.data(), rhsv.size()) > 0; +} + + template BOOST_STATIC_STRING_CPP14_CONSTEXPR inline @@ -5586,6 +5926,42 @@ operator>=( rhs, Traits::length(rhs)) >= 0; } +template +#endif + > +BOOST_STATIC_STRING_CPP14_CONSTEXPR +inline +bool +operator>=( + const T& lhs, + const basic_static_string& rhs) +{ + detail::common_string_view_type lhsv = lhs; + return detail::lexicographical_compare( + lhsv.data(), lhsv.size(), + rhs.data(), rhs.size()) >= 0; +} + +template +#endif + > +BOOST_STATIC_STRING_CPP14_CONSTEXPR +inline +bool +operator>=( + const basic_static_string& lhs, + const T& rhs) +{ + detail::common_string_view_type rhsv = rhs; + return detail::lexicographical_compare( + lhs.data(), lhs.size(), + rhsv.data(), rhsv.size()) >= 0; +} + template< std::size_t N, std::size_t M, typename CharT, typename Traits> @@ -5721,7 +6097,13 @@ operator<<( std::basic_ostream& os, const basic_static_string& s) { +#ifdef BOOST_STATIC_STRING_HAS_ANY_STRING_VIEW return os << basic_string_view(s.data(), s.size()); +#else + for (auto c: s) + os << c; + return os; +#endif } //------------------------------------------------------------------------------ @@ -5961,14 +6343,47 @@ struct hash< operator()( const boost::static_strings::basic_static_string& str) const noexcept { -#ifndef BOOST_STATIC_STRING_STANDALONE +#if !defined(BOOST_STATIC_STRING_STANDALONE) return boost::hash_range(str.begin(), str.end()); -#else +#elif defined(BOOST_STATIC_STRING_HAS_ANY_STRING_VIEW) using view_type = typename boost::static_strings::basic_string_view; return std::hash()(view_type(str.data(), str.size())); +#else + std::size_t seed = 0; + for (CharT const& c : str) { + mix_impl(std::integral_constant= 8>{}, seed, c); + } + return seed; #endif } + + static + void + mix_impl(std::true_type, std::size_t& seed, CharT c) + { + seed += 0x9e3779b9 + std::hash()( c ); + std::size_t const m = (std::size_t(0xe9846af) << 32) + 0x9b1a615d; + seed ^= seed >> 32; + seed *= m; + seed ^= seed >> 32; + seed *= m; + seed ^= seed >> 28; + } + + static + void + mix_impl(std::false_type, std::size_t& seed, CharT c) + { + seed += 0x9e3779b9 + std::hash()( c ); + std::size_t const m1 = 0x21f0aaad; + std::size_t const m2 = 0x735a2d97; + seed ^= seed >> 16; + seed *= m1; + seed ^= seed >> 15; + seed *= m2; + seed ^= seed >> 15; + } }; } // std diff --git a/test/constexpr_tests.hpp b/test/constexpr_tests.hpp index af6547f..9b2e83c 100644 --- a/test/constexpr_tests.hpp +++ b/test/constexpr_tests.hpp @@ -357,8 +357,10 @@ testConstantEvaluation() a.substr(0); #endif +#ifdef BOOST_STATIC_STRING_HAS_STRING_VIEW // subview a.subview(0); +#endif // copy char k[20]{}; diff --git a/test/static_string.cpp b/test/static_string.cpp index 5288b45..c818975 100644 --- a/test/static_string.cpp +++ b/test/static_string.cpp @@ -26,7 +26,15 @@ namespace static_strings { template class basic_static_string<420, char>; +#ifdef BOOST_STATIC_STRING_HAS_ANY_STRING_VIEW using string_view = basic_string_view>; +#endif + +#ifdef BOOST_STATIC_STRING_HAS_ANY_STRING_VIEW +using string_like = basic_string_view>; +#else +using string_like = std::string; +#endif template bool @@ -51,13 +59,21 @@ testSV(const S& s, typename S::size_type pos, typename S::size_type n) { if (pos <= s.size()) { +#ifdef BOOST_STATIC_STRING_HAS_ANY_STRING_VIEW typename S::string_view_type str = s.subview(pos, n); +#else + auto str = s.substr(pos, n); +#endif typename S::size_type rlen = (std::min)(n, s.size() - pos); return (S::traits_type::compare(s.data() + pos, str.data(), rlen) == 0); } else { +#ifdef BOOST_STATIC_STRING_HAS_ANY_STRING_VIEW BOOST_TEST_THROWS((s.subview(pos, n)), std::out_of_range); +#else + BOOST_TEST_THROWS((s.substr(pos, n)), std::out_of_range); +#endif return true; } } @@ -342,11 +358,11 @@ testConstruct() } { static_string<3> s1( - string_view("123")); + string_like("123")); BOOST_TEST(s1 == "123"); BOOST_TEST(*s1.end() == 0); BOOST_TEST_THROWS( - (static_string<2>(string_view("123"))), + (static_string<2>(string_like("123"))), std::length_error); } { @@ -424,6 +440,7 @@ testAssignment() // assign(T const& t) { +#ifdef BOOST_STATIC_STRING_HAS_ANY_STRING_VIEW struct T { operator string_view() const noexcept @@ -431,6 +448,21 @@ testAssignment() return "abc"; } }; +#else + struct T + { + char const* data() const noexcept + { + static char p[] = "abc"; + return p; + } + + std::size_t size() const noexcept + { + return 3; + } + }; +#endif BOOST_TEST(static_string<3>{}.assign(T{}) == "abc"); BOOST_TEST(static_string<3>{"*"}.assign(T{}) == "abc"); BOOST_TEST(static_string<3>{"***"}.assign(T{}) == "abc"); @@ -439,6 +471,7 @@ testAssignment() // assign(T const& t, size_type pos, size_type count = npos) { +#ifdef BOOST_STATIC_STRING_HAS_ANY_STRING_VIEW struct T { operator string_view() const noexcept @@ -446,6 +479,23 @@ testAssignment() return "abcde"; } }; +#else + struct T + { + char const* + data() const noexcept + { + static char p[] = "abcde"; + return p; + } + + std::size_t + size() const + { + return 5; + } + }; +#endif BOOST_TEST(static_string<5>{}.assign(T{}, 0) == "abcde"); BOOST_TEST(static_string<5>{}.assign(T{}, 0, 5) == "abcde"); BOOST_TEST(static_string<5>{}.assign(T{}, 1, 3) == "bcd"); @@ -507,15 +557,14 @@ testAssignment() } { static_string<3> s1; - s1 = string_view("123"); + s1 = string_like("123"); BOOST_TEST(s1 == "123"); BOOST_TEST(*s1.end() == 0); static_string<1> s2; BOOST_TEST_THROWS( - s2 = string_view("123"), + s2 = string_like("123"), std::length_error); } - { static_string<4> s1; s1.assign(3, 'x'); @@ -603,14 +652,14 @@ testAssignment() } { static_string<5> s1; - s1.assign(string_view("123")); + s1.assign(string_like("123")); BOOST_TEST(s1 == "123"); BOOST_TEST(*s1.end() == 0); - s1.assign(string_view("12345")); + s1.assign(string_like("12345")); BOOST_TEST(s1 == "12345"); BOOST_TEST(*s1.end() == 0); BOOST_TEST_THROWS( - s1.assign(string_view("1234567")), + s1.assign(string_like("1234567")), std::length_error); } { @@ -795,11 +844,20 @@ testElements() BOOST_TEST(std::memcmp( s.c_str(), "123\0", 4) == 0); } +#ifdef BOOST_STATIC_ASSERT_HAS_STRING_VIEW { static_string<3> s("123"); string_view sv = s; BOOST_TEST(static_string<5>(sv) == "123"); } +#endif +#ifdef BOOST_STATIC_ASSERT_HAS_STD_STRING_VIEW + { + static_string<3> s("123"); + std::string_view sv = s; + BOOST_TEST(static_string<5>(sv) == "123"); + } +#endif } // done @@ -916,7 +974,7 @@ static void testInsert() { - using sv = string_view; + using sv = string_like; using S = static_string<100>; // insert(size_type index, size_type count, CharT ch) @@ -997,6 +1055,7 @@ testInsert() // insert(size_type index, T const& t) { +#ifdef BOOST_STATIC_STRING_HAS_ANY_STRING_VIEW struct T { operator string_view() const noexcept @@ -1004,6 +1063,23 @@ testInsert() return "b"; } }; +#else + struct T + { + char const* + data() const noexcept + { + static char p[] = "b"; + return p; + } + + std::size_t + size() const + { + return 1; + } + }; +#endif BOOST_TEST(static_string<3>{"ac"}.insert(1, T{}) == "abc"); BOOST_TEST_THROWS(static_string<4>{"abc"}.insert(4, T{}), std::out_of_range); BOOST_TEST_THROWS(static_string<3>{"abc"}.insert(1, T{}), std::length_error); @@ -1011,6 +1087,7 @@ testInsert() // insert(size_type index, T const& t, size_type index_str, size_type count = npos) { +#ifdef BOOST_STATIC_STRING_HAS_ANY_STRING_VIEW struct T { operator string_view() const noexcept @@ -1018,6 +1095,23 @@ testInsert() return "abcd"; } }; +#else + struct T + { + char const* + data() const noexcept + { + static char p[] = "abcd"; + return p; + } + + std::size_t + size() const noexcept + { + return 4; + } + }; +#endif BOOST_TEST(static_string<6>{"ae"}.insert(1, T{}, 1) == "abcde"); BOOST_TEST(static_string<6>{"abe"}.insert(2, T{}, 2) == "abcde"); BOOST_TEST(static_string<4>{"ac"}.insert(1, T{}, 1, 1) == "abc"); @@ -1145,16 +1239,16 @@ testInsert() } { static_string<5> s1("123"); - s1.insert(1, string_view("UV")); + s1.insert(1, string_like("UV")); BOOST_TEST(s1 == "1UV23"); BOOST_TEST(*s1.end() == 0); static_string<4> s2("123"); BOOST_TEST_THROWS( - (s2.insert(1, string_view("UV"))), + (s2.insert(1, string_like("UV"))), std::length_error); static_string<5> s3("123"); BOOST_TEST_THROWS( - (s3.insert(5, string_view("UV"))), + (s3.insert(5, string_like("UV"))), std::out_of_range); } { @@ -1986,7 +2080,7 @@ void testAppend() { using S = static_string<400>; - using sv = string_view; + using sv = string_like; // append(size_type count, CharT ch) BOOST_TEST(static_string<1>{}.append(1, 'a') == "a"); @@ -2031,6 +2125,7 @@ testAppend() // append(T const& t) { +#ifdef BOOST_STATIC_STRING_HAS_ANY_STRING_VIEW struct T { operator string_view() const noexcept @@ -2038,12 +2133,29 @@ testAppend() return "c"; } }; +#else + struct T + { + char const* + data() const noexcept + { + return "c"; + } + + std::size_t + size() const noexcept + { + return 1; + } + }; +#endif BOOST_TEST(static_string<3>{"ab"}.append(T{}) == "abc"); BOOST_TEST_THROWS(static_string<3>{"abc"}.append(T{}), std::length_error); } // append(T const& t, size_type pos, size_type count = npos) { +#ifdef BOOST_STATIC_STRING_HAS_ANY_STRING_VIEW struct T { operator string_view() const noexcept @@ -2051,6 +2163,22 @@ testAppend() return "abcd"; } }; +#else + struct T + { + char const* + data() const noexcept + { + return "abcd"; + } + + std::size_t + size() const noexcept + { + return 4; + } + }; +#endif BOOST_TEST(static_string<4>{"ab"}.append(T{}, 2) == "abcd"); BOOST_TEST(static_string<3>{"a"}.append(T{}, 1, 2) == "abc"); BOOST_TEST_THROWS(static_string<4>{"abc"}.append(T{}, 5), std::out_of_range); @@ -2141,7 +2269,7 @@ testAppend() std::length_error); } { - string_view s1("XYZ"); + string_like s1("XYZ"); static_string<5> s2("12"); s2.append(s1); BOOST_TEST(s2 == "12XYZ"); @@ -2196,7 +2324,7 @@ static void testPlusEquals() { - using sv = string_view; + using sv = string_like; // operator+=(CharT ch) BOOST_TEST((static_string<3>{"ab"} += 'c') == "abc"); @@ -2252,7 +2380,7 @@ testPlusEquals() std::length_error); } { - string_view s1("34"); + string_like s1("34"); static_string<4> s2("12"); s2 += s1; BOOST_TEST(s2 == "1234"); @@ -2288,6 +2416,7 @@ testCompare() BOOST_TEST(s1.compare(0, 2, s2.data()) < 0); BOOST_TEST(s2.compare(0, 1, s1.data()) > 0); +#ifdef BOOST_STATIC_STRING_HAS_ANY_STRING_VIEW BOOST_TEST(s1.compare(s2.subview()) < 0); BOOST_TEST(s2.compare(s1.subview()) > 0); @@ -2296,6 +2425,7 @@ testCompare() BOOST_TEST(s1.compare(0, 2, s2.subview(), 0, 1) < 0); BOOST_TEST(s2.compare(0, 1, s1.subview(), 0, 2) > 0); +#endif BOOST_TEST(s1 < "10"); BOOST_TEST(s2 > "1"); @@ -2304,6 +2434,14 @@ testCompare() BOOST_TEST(s1 < "20"); BOOST_TEST(s2 > "1"); BOOST_TEST(s2 > "2"); + + BOOST_TEST(s1 < string_like("10")); + BOOST_TEST(s2 > string_like("1")); + BOOST_TEST(string_like("10") > s1); + BOOST_TEST(string_like("1") < s2); + BOOST_TEST(s1 < string_like("20")); + BOOST_TEST(s2 > string_like("1")); + BOOST_TEST(s2 > string_like("2")); } { str2 s1("x"); @@ -2339,6 +2477,19 @@ testCompare() BOOST_TEST(! ("x" < s)); BOOST_TEST(! ("x" > s)); BOOST_TEST(! ("x" != s)); + + BOOST_TEST(s == string_like("x")); + BOOST_TEST(s <= string_like("x")); + BOOST_TEST(s >= string_like("x")); + BOOST_TEST(! (s < string_like("x"))); + BOOST_TEST(! (s > string_like("x"))); + BOOST_TEST(! (s != string_like("x"))); + BOOST_TEST(string_like("x") == s); + BOOST_TEST(string_like("x") <= s); + BOOST_TEST(string_like("x") >= s); + BOOST_TEST(! (string_like("x") < s)); + BOOST_TEST(! (string_like("x") > s)); + BOOST_TEST(! (string_like("x") != s)); } { str2 s("x"); @@ -2354,6 +2505,19 @@ testCompare() BOOST_TEST(! ("y" == s)); BOOST_TEST(! ("y" <= s)); BOOST_TEST(! ("y" < s)); + + BOOST_TEST(s <= string_like("y")); + BOOST_TEST(s < string_like("y")); + BOOST_TEST(s != string_like("y")); + BOOST_TEST(! (s == string_like("y"))); + BOOST_TEST(! (s >= string_like("y"))); + BOOST_TEST(! (s > "x")); + BOOST_TEST(string_like("y") >= s); + BOOST_TEST(string_like("y") > s); + BOOST_TEST(string_like("y") != s); + BOOST_TEST(! (string_like("y") == s)); + BOOST_TEST(! (string_like("y") <= s)); + BOOST_TEST(! (string_like("y") < s)); } { str1 s1("x"); @@ -3815,8 +3979,8 @@ testFind() { const char* cs1 = "12345"; const char* cs2 = "2345"; - string_view v1 = cs1; - string_view v2 = cs2; + string_like v1 = cs1; + string_like v2 = cs2; static_string<5> fs1 = cs1; static_string<4> fs2 = cs2; using S = static_string<400>; @@ -5139,8 +5303,8 @@ testFind() const char* cs3 = "12456"; const char* cs4 = "2356"; - string_view v3 = cs3; - string_view v4 = cs4; + string_like v3 = cs3; + string_like v4 = cs4; static_string<5> fs3 = cs3; static_string<4> fs4 = cs4; @@ -5925,12 +6089,12 @@ testReplace() // replace(size_type pos1, size_type n1, const T& t); { static_string<20> fs1 = "helloworld"; - BOOST_TEST(fs1.replace(0, fs1.size(), string_view(fs1)) == "helloworld"); + BOOST_TEST(fs1.replace(0, fs1.size(), string_like(fs1.data(), fs1.size())) == "helloworld"); } // replace(size_type pos1, size_type n1, const T& t, size_type pos2, size_type n2 = npos); { static_string<20> fs1 = "helloworld"; - BOOST_TEST(fs1.replace(0, fs1.size(), string_view(fs1), 0, fs1.size()) == "helloworld"); + BOOST_TEST(fs1.replace(0, fs1.size(), string_like(fs1.data(), fs1.size()), 0, fs1.size()) == "helloworld"); } // replace(size_type pos, size_type n, const charT * s); { @@ -5956,7 +6120,7 @@ testReplace() // replace(const_iterator i1, const_iterator i2, const T& t); { static_string<20> fs1 = "helloworld"; - BOOST_TEST(fs1.replace(fs1.begin(), fs1.end(), string_view(fs1)) == "helloworld"); + BOOST_TEST(fs1.replace(fs1.begin(), fs1.end(), string_like(fs1.data(), fs1.size())) == "helloworld"); } // replace(const_iterator i1, const_iterator i2, const charT* s, size_type n); { @@ -7103,21 +7267,21 @@ testStartsEnds() BOOST_TEST(S("1234567890").starts_with("1234567890")); BOOST_TEST(!S("1234567890").starts_with("234")); BOOST_TEST(!S("1234567890").starts_with("12345678900")); - BOOST_TEST(S("1234567890").starts_with(string_view("1234567890"))); + BOOST_TEST(S("1234567890").starts_with(string_like("1234567890"))); BOOST_TEST(S("1234567890").ends_with('0')); BOOST_TEST(S("1234567890").ends_with("890")); BOOST_TEST(S("1234567890").ends_with("1234567890")); BOOST_TEST(!S("1234567890").ends_with("234")); BOOST_TEST(!S("1234567890").ends_with("12345678900")); - BOOST_TEST(S("1234567890").ends_with(string_view("1234567890"))); + BOOST_TEST(S("1234567890").ends_with(string_like("1234567890"))); BOOST_TEST(!S().starts_with('0')); BOOST_TEST(!S().starts_with("0")); - BOOST_TEST(!S().starts_with(string_view("0"))); + BOOST_TEST(!S().starts_with(string_like("0"))); BOOST_TEST(!S().ends_with('0')); BOOST_TEST(!S().ends_with("0")); - BOOST_TEST(!S().ends_with(string_view("0"))); + BOOST_TEST(!S().ends_with(string_like("0"))); } void @@ -7158,7 +7322,9 @@ testStream() static_string<10> b = "abcdefghij"; a << b; static_string<10> c(std::istream_iterator{a}, std::istream_iterator{}); +#ifdef BOOST_STATIC_STRING_HAS_ANY_STRING_VIEW BOOST_TEST(a.str() == b.subview()); +#endif BOOST_TEST(b == c); } From 6275cd7fe300a5e8a7cd0a8859d46ded62e79c71 Mon Sep 17 00:00:00 2001 From: Krystian Stasiowski Date: Mon, 29 May 2023 10:38:20 -0400 Subject: [PATCH 12/73] disable string_view overloads when type is convertible to basic_static_string fixes #47 --- include/boost/static_string/static_string.hpp | 153 ++++++++++-------- test/static_string.cpp | 9 ++ 2 files changed, 98 insertions(+), 64 deletions(-) diff --git a/include/boost/static_string/static_string.hpp b/include/boost/static_string/static_string.hpp index b899d54..fae3dea 100644 --- a/include/boost/static_string/static_string.hpp +++ b/include/boost/static_string/static_string.hpp @@ -145,31 +145,36 @@ struct is_string_like< // directly and other convertible types such as std::string. // When no string_view type is available, then we check for the // data and size member functions, and use them directly for assignments. -template +// Types convertible to basic_static_string are not considered viewable +// to prevent any ambiguity during overload resolution. +template struct enable_if_viewable { }; -template -struct enable_if_viewable +struct enable_if_viewable::value + is_string_like::value && + !std::is_convertible&>::value #elif defined(BOOST_STATIC_STRING_STANDALONE) std::is_convertible>::value && - !std::is_convertible::value + !std::is_convertible::value && + !std::is_convertible&>::value #else ( std::is_convertible>::value || std::is_convertible>::value ) && - !std::is_convertible::value + !std::is_convertible::value && + !std::is_convertible&>::value #endif >::type> { using type = void; }; -template -using enable_if_viewable_t = typename enable_if_viewable::type; +template +using enable_if_viewable_t = typename enable_if_viewable::type; // The common string_view type used in private operations with enable_if_viewable_t // - T const& itself when no string_view type is available @@ -1117,7 +1122,7 @@ class basic_static_string */ template + , typename = detail::enable_if_viewable_t #endif > explicit @@ -1137,7 +1142,7 @@ class basic_static_string */ template + , typename = detail::enable_if_viewable_t #endif > BOOST_STATIC_STRING_CPP14_CONSTEXPR @@ -1314,7 +1319,8 @@ class basic_static_string @code std::is_convertible::value && - !std::is_convertible::value + !std::is_convertible::value && + !std::is_convertible::value @endcode @return `*this` @@ -1325,7 +1331,7 @@ class basic_static_string */ template + , typename = detail::enable_if_viewable_t #endif > BOOST_STATIC_STRING_CPP14_CONSTEXPR @@ -1603,7 +1609,8 @@ class basic_static_string @code std::is_convertible::value && - !std::is_convertible::value + !std::is_convertible::value && + !std::is_convertible::value @endcode @return `*this` @@ -1614,7 +1621,7 @@ class basic_static_string */ template + , typename = detail::enable_if_viewable_t #endif > BOOST_STATIC_STRING_CPP14_CONSTEXPR @@ -1648,7 +1655,8 @@ class basic_static_string @code std::is_convertible::value && - !std::is_convertible::value + !std::is_convertible::value && + !std::is_convertible::value @endcode @return `*this` @@ -1664,7 +1672,7 @@ class basic_static_string */ template + , typename = detail::enable_if_viewable_t #endif > basic_static_string& @@ -2594,7 +2602,8 @@ class basic_static_string @par Constraints `std::is_convertible::value && - !std::is_convertible::value`. + !std::is_convertible::value && + !std::is_convertible::value`. @param index The index to insert at. @param t The string to insert from. @@ -2604,7 +2613,7 @@ class basic_static_string */ template + , typename = detail::enable_if_viewable_t #endif > BOOST_STATIC_STRING_CPP14_CONSTEXPR @@ -2635,7 +2644,8 @@ class basic_static_string @par Constraints `std::is_convertible::value && - !std::is_convertible::value`. + !std::is_convertible::value && + !std::is_convertible::value`. @return `*this` @@ -2651,7 +2661,7 @@ class basic_static_string */ template + , typename = detail::enable_if_viewable_t #endif > BOOST_STATIC_STRING_CPP14_CONSTEXPR @@ -3006,7 +3016,8 @@ class basic_static_string @code std::is_convertible::value && - !std::is_convertible::value + !std::is_convertible::value && + !std::is_convertible::value @endcode @return `*this` @@ -3017,7 +3028,7 @@ class basic_static_string */ template + , typename = detail::enable_if_viewable_t #endif > BOOST_STATIC_STRING_CPP14_CONSTEXPR @@ -3043,7 +3054,8 @@ class basic_static_string @code std::is_convertible::value && - !std::is_convertible::value + !std::is_convertible::value && + !std::is_convertible::value @endcode @return `*this` @@ -3059,7 +3071,7 @@ class basic_static_string */ template + , typename = detail::enable_if_viewable_t #endif > BOOST_STATIC_STRING_CPP14_CONSTEXPR @@ -3181,7 +3193,8 @@ class basic_static_string @code std::is_convertible::value && - !std::is_convertible::value + !std::is_convertible::value && + !std::is_convertible::value @endcode @return `*this` @@ -3192,7 +3205,7 @@ class basic_static_string */ template + , typename = detail::enable_if_viewable_t #endif > BOOST_STATIC_STRING_CPP14_CONSTEXPR @@ -3440,7 +3453,8 @@ class basic_static_string @code std::is_convertible::value && - !std::is_convertible::value. + !std::is_convertible::value && + !std::is_convertible::value. @endcode @return The result of lexicographically comparing `s` and the string. @@ -3449,7 +3463,7 @@ class basic_static_string */ template + , typename = detail::enable_if_viewable_t #endif > BOOST_STATIC_STRING_CPP14_CONSTEXPR @@ -3484,7 +3498,8 @@ class basic_static_string @code std::is_convertible::value && - !std::is_convertible::value. + !std::is_convertible::value && + !std::is_convertible::value. @endcode @return The result of lexicographically comparing `s` and `sub`. @@ -3497,7 +3512,7 @@ class basic_static_string */ template + , typename = detail::enable_if_viewable_t #endif > BOOST_STATIC_STRING_CPP14_CONSTEXPR @@ -3535,7 +3550,8 @@ class basic_static_string @code std::is_convertible::value && - !std::is_convertible::value. + !std::is_convertible::value && + !std::is_convertible::value. @endcode @return The result of lexicographically comparing `sub1` and `sub2`. @@ -3552,7 +3568,7 @@ class basic_static_string */ template + , typename = detail::enable_if_viewable_t #endif > BOOST_STATIC_STRING_CPP14_CONSTEXPR @@ -3867,7 +3883,8 @@ class basic_static_string @par Constraints `std::is_convertible::value && - !std::is_convertible::value`. + !std::is_convertible::value && + !std::is_convertible::value`. @return `*this` @@ -3880,7 +3897,7 @@ class basic_static_string */ template + , typename = detail::enable_if_viewable_t #endif > BOOST_STATIC_STRING_CPP14_CONSTEXPR @@ -3913,7 +3930,8 @@ class basic_static_string @par Constraints `std::is_convertible::value && - !std::is_convertible::value`. + !std::is_convertible::value && + !std::is_convertible::value`. @return `*this` @@ -3930,7 +3948,7 @@ class basic_static_string */ template + , typename = detail::enable_if_viewable_t #endif > BOOST_STATIC_STRING_CPP14_CONSTEXPR @@ -4129,7 +4147,8 @@ class basic_static_string @par Constraints `std::is_convertible::value && - !std::is_convertible::value`. + !std::is_convertible::value && + !std::is_convertible::value`. @return `*this` @@ -4142,7 +4161,7 @@ class basic_static_string */ template + , typename = detail::enable_if_viewable_t #endif > BOOST_STATIC_STRING_CPP14_CONSTEXPR @@ -4392,7 +4411,8 @@ class basic_static_string @par Constraints `std::is_convertible::value && - !std::is_convertible::value`. + !std::is_convertible::value && + !std::is_convertible::value`. @return The lowest index `idx` greater than or equal to `pos` where each element of `{sv.begin(), sv.end())` is equal to @@ -4405,7 +4425,7 @@ class basic_static_string */ template + , typename = detail::enable_if_viewable_t #endif > BOOST_STATIC_STRING_CPP14_CONSTEXPR @@ -4549,7 +4569,8 @@ class basic_static_string @par Constraints `std::is_convertible::value && - !std::is_convertible::value`. + !std::is_convertible::value && + !std::is_convertible::value`. @return The highest index `idx` less than or equal to `pos` where each element of `{sv.begin(), sv.end())` is equal to @@ -4562,7 +4583,7 @@ class basic_static_string */ template + , typename = detail::enable_if_viewable_t #endif > BOOST_STATIC_STRING_CPP14_CONSTEXPR @@ -4702,7 +4723,8 @@ class basic_static_string @par Constraints `std::is_convertible::value && - !std::is_convertible::value`. + !std::is_convertible::value && + !std::is_convertible::value`. @return The index corrosponding to the first occurrence of any of the characters in `{sv.begin(), sv.end())` within @@ -4714,7 +4736,7 @@ class basic_static_string */ template + , typename = detail::enable_if_viewable_t #endif > BOOST_STATIC_STRING_CPP14_CONSTEXPR @@ -4849,7 +4871,8 @@ class basic_static_string @par Constraints `std::is_convertible::value && - !std::is_convertible::value`. + !std::is_convertible::value && + !std::is_convertible::value`. @return The index corrosponding to the last occurrence of any of the characters in `{sv.begin(), sv.end())` within @@ -4861,7 +4884,7 @@ class basic_static_string */ template + , typename = detail::enable_if_viewable_t #endif > BOOST_STATIC_STRING_CPP14_CONSTEXPR @@ -4995,7 +5018,8 @@ class basic_static_string @par Constraints `std::is_convertible::value && - !std::is_convertible::value`. + !std::is_convertible::value && + !std::is_convertible::value`. @return The index corrosponding to the first occurrence of a character that is not in `{sv.begin(), sv.end())` within @@ -5007,7 +5031,7 @@ class basic_static_string */ template + , typename = detail::enable_if_viewable_t #endif > BOOST_STATIC_STRING_CPP14_CONSTEXPR @@ -5140,7 +5164,8 @@ class basic_static_string @par Constraints `std::is_convertible::value && - !std::is_convertible::value`. + !std::is_convertible::value && + !std::is_convertible::value`. @return The index corrosponding to the last occurrence of a character that is not in `{sv.begin(), sv.end())` within @@ -5152,7 +5177,7 @@ class basic_static_string */ template + , typename = detail::enable_if_viewable_t #endif > BOOST_STATIC_STRING_CPP14_CONSTEXPR @@ -5284,7 +5309,7 @@ class basic_static_string */ template + , typename = detail::enable_if_viewable_t #endif > BOOST_STATIC_STRING_CPP14_CONSTEXPR @@ -5348,7 +5373,7 @@ class basic_static_string */ template + , typename = detail::enable_if_viewable_t #endif > BOOST_STATIC_STRING_CPP14_CONSTEXPR @@ -5617,7 +5642,7 @@ operator==( template + , typename = detail::enable_if_viewable_t #endif > BOOST_STATIC_STRING_CPP14_CONSTEXPR @@ -5635,7 +5660,7 @@ operator==( template + , typename = detail::enable_if_viewable_t #endif > BOOST_STATIC_STRING_CPP14_CONSTEXPR @@ -5679,7 +5704,7 @@ operator!=( template + , typename = detail::enable_if_viewable_t #endif > BOOST_STATIC_STRING_CPP14_CONSTEXPR @@ -5697,7 +5722,7 @@ operator!=( template + , typename = detail::enable_if_viewable_t #endif > BOOST_STATIC_STRING_CPP14_CONSTEXPR @@ -5741,7 +5766,7 @@ operator<( template + , typename = detail::enable_if_viewable_t #endif > BOOST_STATIC_STRING_CPP14_CONSTEXPR @@ -5759,7 +5784,7 @@ operator<( template + , typename = detail::enable_if_viewable_t #endif > BOOST_STATIC_STRING_CPP14_CONSTEXPR @@ -5803,7 +5828,7 @@ operator<=( template + , typename = detail::enable_if_viewable_t #endif > BOOST_STATIC_STRING_CPP14_CONSTEXPR @@ -5821,7 +5846,7 @@ operator<=( template + , typename = detail::enable_if_viewable_t #endif > BOOST_STATIC_STRING_CPP14_CONSTEXPR @@ -5865,7 +5890,7 @@ operator>( template + , typename = detail::enable_if_viewable_t #endif > BOOST_STATIC_STRING_CPP14_CONSTEXPR @@ -5883,7 +5908,7 @@ operator>( template + , typename = detail::enable_if_viewable_t #endif > BOOST_STATIC_STRING_CPP14_CONSTEXPR @@ -5928,7 +5953,7 @@ operator>=( template + , typename = detail::enable_if_viewable_t #endif > BOOST_STATIC_STRING_CPP14_CONSTEXPR @@ -5946,7 +5971,7 @@ operator>=( template + , typename = detail::enable_if_viewable_t #endif > BOOST_STATIC_STRING_CPP14_CONSTEXPR diff --git a/test/static_string.cpp b/test/static_string.cpp index c818975..4a6ee99 100644 --- a/test/static_string.cpp +++ b/test/static_string.cpp @@ -7393,6 +7393,15 @@ testOperatorPlus() } } +// issue 47 +struct issue_47 : static_string<32> +{ + bool compare(const issue_47& other) const + { + return *this < other; + } +}; + int runTests() { From 175f467a03841662c0aac7442978245b977fecf9 Mon Sep 17 00:00:00 2001 From: Krystian Stasiowski Date: Mon, 29 May 2023 11:12:13 -0400 Subject: [PATCH 13/73] select hash implementation with macros based on word size fixes #46 --- include/boost/static_string/config.hpp | 11 +++++ include/boost/static_string/static_string.hpp | 49 ++++++++----------- 2 files changed, 31 insertions(+), 29 deletions(-) diff --git a/include/boost/static_string/config.hpp b/include/boost/static_string/config.hpp index 2217fe8..79861f7 100644 --- a/include/boost/static_string/config.hpp +++ b/include/boost/static_string/config.hpp @@ -14,6 +14,17 @@ // Are we dependent on Boost? // #define BOOST_STATIC_STRING_STANDALONE +#include + +// detect 32/64 bit +#if UINTPTR_MAX == UINT64_MAX +#define BOOST_STATIC_STRING_ARCH 64 +#elif UINTPTR_MAX == UINT32_MAX +#define BOOST_STATIC_STRING_ARCH 32 +#else +#error Unknown or unsupported architecture, please open an issue +#endif + // Can we have deduction guides? #if __cpp_deduction_guides >= 201703L #define BOOST_STATIC_STRING_USE_DEDUCT diff --git a/include/boost/static_string/static_string.hpp b/include/boost/static_string/static_string.hpp index fae3dea..7b36a93 100644 --- a/include/boost/static_string/static_string.hpp +++ b/include/boost/static_string/static_string.hpp @@ -6376,39 +6376,30 @@ struct hash< return std::hash()(view_type(str.data(), str.size())); #else std::size_t seed = 0; - for (CharT const& c : str) { - mix_impl(std::integral_constant= 8>{}, seed, c); + for (CharT const& c : str) + { +#if BOOST_STATIC_STRING_ARCH == 64 + seed += 0x9e3779b9 + std::hash()( c ); + std::size_t const m = (std::size_t(0xe9846af) << 32) + 0x9b1a615d; + seed ^= seed >> 32; + seed *= m; + seed ^= seed >> 32; + seed *= m; + seed ^= seed >> 28; +#elif BOOST_STATIC_STRING_ARCH == 32 + seed += 0x9e3779b9 + std::hash()( c ); + std::size_t const m1 = 0x21f0aaad; + std::size_t const m2 = 0x735a2d97; + seed ^= seed >> 16; + seed *= m1; + seed ^= seed >> 15; + seed *= m2; + seed ^= seed >> 15; +#endif } return seed; #endif } - - static - void - mix_impl(std::true_type, std::size_t& seed, CharT c) - { - seed += 0x9e3779b9 + std::hash()( c ); - std::size_t const m = (std::size_t(0xe9846af) << 32) + 0x9b1a615d; - seed ^= seed >> 32; - seed *= m; - seed ^= seed >> 32; - seed *= m; - seed ^= seed >> 28; - } - - static - void - mix_impl(std::false_type, std::size_t& seed, CharT c) - { - seed += 0x9e3779b9 + std::hash()( c ); - std::size_t const m1 = 0x21f0aaad; - std::size_t const m2 = 0x735a2d97; - seed ^= seed >> 16; - seed *= m1; - seed ^= seed >> 15; - seed *= m2; - seed ^= seed >> 15; - } }; } // std From 42bb99ed255846befdc5d85615c8feee1d4a5ca6 Mon Sep 17 00:00:00 2001 From: Krystian Stasiowski Date: Tue, 24 Oct 2023 11:09:29 -0400 Subject: [PATCH 14/73] support platforms without wchar_t closes #51 --- include/boost/static_string/config.hpp | 18 ++++ include/boost/static_string/static_string.hpp | 11 ++- test/static_string.cpp | 91 +++++++++++++++---- 3 files changed, 100 insertions(+), 20 deletions(-) diff --git a/include/boost/static_string/config.hpp b/include/boost/static_string/config.hpp index 79861f7..a0f0095 100644 --- a/include/boost/static_string/config.hpp +++ b/include/boost/static_string/config.hpp @@ -239,6 +239,24 @@ defined(BOOST_STATIC_STRING_CPP14) #define BOOST_STATIC_STRING_GCC5_BAD_CONSTEXPR #endif +#ifndef BOOST_STATIC_STRING_STANDALONE +#if ! defined(BOOST_NO_CWCHAR) && ! defined(BOOST_NO_SWPRINTF) +#define BOOST_STATIC_STRING_HAS_WCHAR +#endif +#else +#ifndef __has_include +// If we don't have __has_include in standalone, +// we will assume that exists. +#define BOOST_STATIC_STRING_HAS_WCHAR +#elif __has_include() +#define BOOST_STATIC_STRING_HAS_WCHAR +#endif +#endif + +#ifdef BOOST_STATIC_STRING_HAS_WCHAR +#include +#endif + // Define the basic string_view type used by the library // Conversions to and from other available string_view types // are still defined. diff --git a/include/boost/static_string/static_string.hpp b/include/boost/static_string/static_string.hpp index 7b36a93..fce1ddb 100644 --- a/include/boost/static_string/static_string.hpp +++ b/include/boost/static_string/static_string.hpp @@ -34,7 +34,6 @@ #include #include #include -#include #include #include #include @@ -58,9 +57,11 @@ template using static_string = basic_static_string>; +#ifdef BOOST_STATIC_STRING_HAS_WCHAR template using static_wstring = basic_static_string>; +#endif template using static_u16string = @@ -555,6 +556,7 @@ to_static_string_int_impl(Integer value) noexcept return static_string(digits_begin, std::distance(digits_begin, digits_end)); } +#ifdef BOOST_STATIC_STRING_HAS_WCHAR template inline static_wstring @@ -566,6 +568,7 @@ to_static_wstring_int_impl(Integer value) noexcept digits_end, value, std::is_signed{}); return static_wstring(digits_begin, std::distance(digits_begin, digits_end)); } +#endif BOOST_STATIC_STRING_CPP11_CONSTEXPR inline @@ -643,6 +646,7 @@ to_static_string_float_impl(long double value) noexcept return static_string(buffer); } +#ifdef BOOST_STATIC_STRING_HAS_WCHAR template inline static_wstring @@ -716,6 +720,7 @@ to_static_wstring_float_impl(long double value) noexcept // this will not throw return static_wstring(buffer); } +#endif #if defined(__GNUC__) && __GNUC__ >= 7 #pragma GCC diagnostic pop @@ -6227,6 +6232,7 @@ to_static_string(long double value) noexcept std::numeric_limits::max_digits10 + 4>(value); } +#ifdef BOOST_STATIC_STRING_HAS_WCHAR /// Converts `value` to a `static_wstring` static_wstring::digits10 + 2> inline @@ -6307,6 +6313,7 @@ to_static_wstring(long double value) noexcept return detail::to_static_wstring_float_impl< std::numeric_limits::max_digits10 + 4>(value); } +#endif //------------------------------------------------------------------------------ // @@ -6347,7 +6354,9 @@ hash_value( //------------------------------------------------------------------------------ using static_strings::static_string; +#ifdef BOOST_STATIC_STRING_HAS_WCHAR using static_strings::static_wstring; +#endif using static_strings::static_u16string; using static_strings::static_u32string; } // boost diff --git a/test/static_string.cpp b/test/static_string.cpp index 4a6ee99..db79c37 100644 --- a/test/static_string.cpp +++ b/test/static_string.cpp @@ -245,29 +245,52 @@ testR(S s, typename S::size_type pos, typename S::size_type n1, const typename S template bool -testTS(Arithmetic value, const char* str_expected = "", const wchar_t* wstr_expected = L"", bool test_expected = false) +testTS(Arithmetic value, const char* str_expected = "", bool test_expected = false) { const auto str = to_static_string(value); - const auto wstr = to_static_wstring(value); if (std::is_floating_point::value) { const auto std_res = std::to_string(value); + return str == std_res.data(); + } + else + { + if (std::is_signed::value) + { + return + Arithmetic(std::strtoll(str.begin(), nullptr, 10)) == value && + (! test_expected || str == str_expected); + } + else + { + return Arithmetic(std::strtoull(str.begin(), nullptr, 10)) == value && + (! test_expected || str == str_expected); + } + } +} + +template +bool +testTWS(Arithmetic value, const wchar_t* wstr_expected = L"", bool test_expected = false) +{ + const auto wstr = to_static_wstring(value); + if (std::is_floating_point::value) + { const auto wstd_res = std::to_wstring(value); - return str == std_res.data() && wstr == wstd_res.data(); + return wstr == wstd_res.data(); } else { if (std::is_signed::value) { - return Arithmetic(std::strtoll(str.begin(), nullptr, 10)) == value && + return Arithmetic(std::wcstoll(wstr.begin(), nullptr, 10)) == value && - (test_expected ? str == str_expected && wstr == wstr_expected : true); + (! test_expected || wstr == wstr_expected); } else { - return Arithmetic(std::strtoull(str.begin(), nullptr, 10)) == value && - Arithmetic(std::wcstoull(wstr.begin(), nullptr, 10)) == value && - (test_expected ? str == str_expected && wstr == wstr_expected : true); + return Arithmetic(std::wcstoull(wstr.begin(), nullptr, 10)) == value && + (! test_expected || wstr == wstr_expected); } } } @@ -3913,16 +3936,16 @@ testGeneral() void testToStaticString() { - BOOST_TEST(testTS(0, "0", L"0", true)); - BOOST_TEST(testTS(0u, "0", L"0", true)); - BOOST_TEST(testTS(0xffff, "65535", L"65535", true)); - BOOST_TEST(testTS(0x10000, "65536", L"65536", true)); - BOOST_TEST(testTS(0xffffffff, "4294967295", L"4294967295", true)); - BOOST_TEST(testTS(-65535, "-65535", L"-65535", true)); - BOOST_TEST(testTS(-65536, "-65536", L"-65536", true)); - BOOST_TEST(testTS(-4294967295ll, "-4294967295", L"-4294967295", true)); - BOOST_TEST(testTS(1, "1", L"1", true)); - BOOST_TEST(testTS(-1, "-1", L"-1", true)); + BOOST_TEST(testTS(0, "0", true)); + BOOST_TEST(testTS(0u, "0", true)); + BOOST_TEST(testTS(0xffff, "65535", true)); + BOOST_TEST(testTS(0x10000, "65536", true)); + BOOST_TEST(testTS(0xffffffff, "4294967295", true)); + BOOST_TEST(testTS(-65535, "-65535", true)); + BOOST_TEST(testTS(-65536, "-65536", true)); + BOOST_TEST(testTS(-4294967295ll, "-4294967295", true)); + BOOST_TEST(testTS(1, "1", true)); + BOOST_TEST(testTS(-1, "-1", true)); BOOST_TEST(testTS(0.1)); BOOST_TEST(testTS(0.0000001)); BOOST_TEST(testTS(-0.0000001)); @@ -3956,6 +3979,35 @@ testToStaticString() BOOST_TEST(str.find('e') != static_string<0>::npos || str.find('.') != static_string<0>::npos || str == "infinity" || str == "inf"); } + +#ifdef BOOST_STATIC_STRING_HAS_WCHAR + + BOOST_TEST(testTWS(0, L"0", true)); + BOOST_TEST(testTWS(0u, L"0", true)); + BOOST_TEST(testTWS(0xffff, L"65535", true)); + BOOST_TEST(testTWS(0x10000, L"65536", true)); + BOOST_TEST(testTWS(0xffffffff, L"4294967295", true)); + BOOST_TEST(testTWS(-65535, L"-65535", true)); + BOOST_TEST(testTWS(-65536, L"-65536", true)); + BOOST_TEST(testTWS(-4294967295ll, L"-4294967295", true)); + BOOST_TEST(testTWS(1, L"1", true)); + BOOST_TEST(testTWS(-1, L"-1", true)); + BOOST_TEST(testTWS(0.1)); + BOOST_TEST(testTWS(0.0000001)); + BOOST_TEST(testTWS(-0.0000001)); + BOOST_TEST(testTWS(-0.1)); + BOOST_TEST(testTWS(1234567890.0001)); + BOOST_TEST(testTWS(1.123456789012345)); + BOOST_TEST(testTWS(-1234567890.1234)); + BOOST_TEST(testTWS(-1.123456789012345)); + + BOOST_TEST(testTWS(std::numeric_limits::max())); + BOOST_TEST(testTWS(std::numeric_limits::min())); + BOOST_TEST(testTWS(std::numeric_limits::max())); + BOOST_TEST(testTWS(std::numeric_limits::max())); + BOOST_TEST(testTWS(std::numeric_limits::min())); + BOOST_TEST(testTWS(std::numeric_limits::min())); + { auto str = to_static_wstring(std::numeric_limits::max()); BOOST_TEST(str.find('e') != static_string<0>::npos || str.find('.') != @@ -3971,6 +4023,7 @@ testToStaticString() BOOST_TEST(str.find('e') != static_string<0>::npos || str.find('.') != static_string<0>::npos || str == L"infinity" || str == L"inf"); } +#endif } // done @@ -6007,7 +6060,7 @@ testFind() void testReplace() { - // replace(size_type pos1, size_type n1, const charT* s, size_type n2); + // replace(size_type pos1, size_type n1, const charT* s, size_type n2); { static_string<20> fs1 = "helloworld"; BOOST_TEST(fs1.replace(5, 2, fs1.data() + 1, 8) == "helloelloworlrld"); From bff5cb65a5cb9151aacaf56abe80125e0128f43a Mon Sep 17 00:00:00 2001 From: alandefreitas Date: Fri, 22 Dec 2023 17:12:34 -0300 Subject: [PATCH 15/73] Boost super-project tests target fix #53 --- CMakeLists.txt | 4 ++-- meta/libraries.json | 1 + test/CMakeLists.txt | 7 +++++++ 3 files changed, 10 insertions(+), 2 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 4a0a639..2a95039 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -23,7 +23,7 @@ endif () # Options if (NOT BOOST_SUPERPROJECT_VERSION) option(BOOST_STATIC_STRING_INSTALL "Install boost::static_string files" ${BOOST_STATIC_STRING_IS_ROOT}) - option(BOOST_STATIC_STRING_BUILD_TESTS "Build boost::static_string tests" ${BUILD_TESTING}) + option(BOOST_STATIC_STRING_BUILD_TESTS "Build boost::static_string tests" OFF) else () set(BOOST_STATIC_STRING_BUILD_TESTS ${BUILD_TESTING}) endif () @@ -112,7 +112,7 @@ if (BOOST_STATIC_STRING_INSTALL AND NOT BOOST_SUPERPROJECT_VERSION) endif () -if (BOOST_STATIC_STRING_BUILD_TESTS) +if (BUILD_TESTING OR BOOST_STATIC_STRING_BUILD_TESTS) add_subdirectory(test) endif () diff --git a/meta/libraries.json b/meta/libraries.json index db0db91..52a31c0 100644 --- a/meta/libraries.json +++ b/meta/libraries.json @@ -11,6 +11,7 @@ "String" ], "maintainers": [ + "Krystian Stasiowski ", "Alan de Freitas ", "Vinnie Falco " ], diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index 9a9c727..97a0994 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -7,6 +7,12 @@ # Official repository: https://github.com/boostorg/static_string # +# Custom target used by the boost super-project +if(NOT TARGET tests) + add_custom_target(tests) + set_property(TARGET tests PROPERTY FOLDER _deps) +endif() + set(BOOST_STATIC_STRING_TESTS_FILES CMakeLists.txt Jamfile @@ -23,3 +29,4 @@ add_executable(boost_static_string_tests ${BOOST_STATIC_STRING_TESTS_FILES}) # See: BOOST_STATIC_STRING_UNIT_TEST_LIBRARIES target_link_libraries(boost_static_string_tests PRIVATE Boost::static_string) add_test(NAME boost_static_string_tests COMMAND boost_static_string_tests) +add_dependencies(tests boost_static_string_tests) From 8f969a62f7af3ae163aa392e2e42090a3d6a7ec9 Mon Sep 17 00:00:00 2001 From: Rene Rivera Date: Mon, 11 Mar 2024 08:38:17 -0500 Subject: [PATCH 16/73] Make the library modular usable. --- Jamfile | 10 ---------- build.jam | 26 ++++++++++++++++++++++++++ test/Jamfile | 2 +- 3 files changed, 27 insertions(+), 11 deletions(-) delete mode 100644 Jamfile create mode 100644 build.jam diff --git a/Jamfile b/Jamfile deleted file mode 100644 index 306f0f6..0000000 --- a/Jamfile +++ /dev/null @@ -1,10 +0,0 @@ -# -# Copyright (c) 2019 Vinnie Falco (vinnie dot falco at gmail dot com) -# -# 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) -# -# Official repository: https://github.com/boostorg/static_string -# - -build-project test ; diff --git a/build.jam b/build.jam new file mode 100644 index 0000000..e9f9cda --- /dev/null +++ b/build.jam @@ -0,0 +1,26 @@ +# Copyright René Ferdinand Rivera Morell 2023 +# 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) + +import project ; + +project /boost/static_string + : common-requirements + /boost/assert//boost_assert + /boost/config//boost_config + /boost/container_hash//boost_container_hash + /boost/core//boost_core + /boost/static_assert//boost_static_assert + /boost/throw_exception//boost_throw_exception + /boost/utility//boost_utility + include + ; + +explicit + [ alias boost_static_string ] + [ alias all : boost_static_string test ] + ; + +call-if : boost-library static_string + ; diff --git a/test/Jamfile b/test/Jamfile index 17231a6..d9fa177 100644 --- a/test/Jamfile +++ b/test/Jamfile @@ -8,7 +8,7 @@ # import testing ; -import ../../config/checks/config : requires ; +import config : requires ; local defines = [ requires From 77d6a43dce9263d3234ef36497aac0842ae0ad3d Mon Sep 17 00:00:00 2001 From: Rene Rivera Date: Fri, 29 Mar 2024 21:15:59 -0500 Subject: [PATCH 17/73] Switch to library requirements instead of source. As source puts extra source in install targets. --- build.jam | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/build.jam b/build.jam index e9f9cda..9551451 100644 --- a/build.jam +++ b/build.jam @@ -7,13 +7,13 @@ import project ; project /boost/static_string : common-requirements - /boost/assert//boost_assert - /boost/config//boost_config - /boost/container_hash//boost_container_hash - /boost/core//boost_core - /boost/static_assert//boost_static_assert - /boost/throw_exception//boost_throw_exception - /boost/utility//boost_utility + /boost/assert//boost_assert + /boost/config//boost_config + /boost/container_hash//boost_container_hash + /boost/core//boost_core + /boost/static_assert//boost_static_assert + /boost/throw_exception//boost_throw_exception + /boost/utility//boost_utility include ; From cd5bc51e9ec2a0ea868fac9d24c34db0060489a6 Mon Sep 17 00:00:00 2001 From: Rene Rivera Date: Fri, 26 Apr 2024 22:16:24 -0500 Subject: [PATCH 18/73] Replace relative docca refs with project based. --- doc/Jamfile | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/doc/Jamfile b/doc/Jamfile index 25c9a6f..ac02fc8 100644 --- a/doc/Jamfile +++ b/doc/Jamfile @@ -12,7 +12,8 @@ project static_string/doc ; import boostbook ; import type ; import os ; -import ../../../tools/docca/docca.jam ; +import-search /boost/docca ; +import docca ; docca.reference reference.qbk : From f15a4d0586d7cfcb406db24a786c93a9efbb2dad Mon Sep 17 00:00:00 2001 From: Rene Rivera Date: Sat, 4 May 2024 23:33:08 -0500 Subject: [PATCH 19/73] Add missing import-search for cconfig/predef checks. --- test/Jamfile | 1 + 1 file changed, 1 insertion(+) diff --git a/test/Jamfile b/test/Jamfile index d9fa177..030839f 100644 --- a/test/Jamfile +++ b/test/Jamfile @@ -8,6 +8,7 @@ # import testing ; +import-search /boost/config/checks ; import config : requires ; local defines = From 32824bfa1deccefca5068c977adaba950c69deda Mon Sep 17 00:00:00 2001 From: Rene Rivera Date: Sun, 5 May 2024 09:00:01 -0500 Subject: [PATCH 20/73] Add requires-b2 check to top-level build file. --- build.jam | 2 ++ 1 file changed, 2 insertions(+) diff --git a/build.jam b/build.jam index 9551451..bfeb905 100644 --- a/build.jam +++ b/build.jam @@ -3,6 +3,8 @@ # (See accompanying file LICENSE_1_0.txt or copy at # http://www.boost.org/LICENSE_1_0.txt) +require-b2 5.1 ; + import project ; project /boost/static_string From 3fb22ed7698886b8d71544971c67b776542b14a0 Mon Sep 17 00:00:00 2001 From: Rene Rivera Date: Fri, 14 Jun 2024 11:33:56 -0500 Subject: [PATCH 21/73] Bump B2 require to 5.2 --- build.jam | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/build.jam b/build.jam index bfeb905..7e7ef25 100644 --- a/build.jam +++ b/build.jam @@ -3,9 +3,7 @@ # (See accompanying file LICENSE_1_0.txt or copy at # http://www.boost.org/LICENSE_1_0.txt) -require-b2 5.1 ; - -import project ; +require-b2 5.2 ; project /boost/static_string : common-requirements From 70578731e7726c2741751bc83a9d47b8fb88bf7b Mon Sep 17 00:00:00 2001 From: Rene Rivera Date: Sat, 20 Jul 2024 22:52:05 -0500 Subject: [PATCH 22/73] Update copyright dates. --- build.jam | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.jam b/build.jam index 7e7ef25..b1af38f 100644 --- a/build.jam +++ b/build.jam @@ -1,4 +1,4 @@ -# Copyright René Ferdinand Rivera Morell 2023 +# Copyright René Ferdinand Rivera Morell 2023-2024 # 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) From a3cc7bcf95725f58b9019452fa47dba5e6739613 Mon Sep 17 00:00:00 2001 From: Rene Rivera Date: Tue, 23 Jul 2024 22:34:24 -0500 Subject: [PATCH 23/73] Move inter-lib dependencies to a project variable and into the build targets. --- build.jam | 19 +++++++++++-------- 1 file changed, 11 insertions(+), 8 deletions(-) diff --git a/build.jam b/build.jam index b1af38f..9ab25d5 100644 --- a/build.jam +++ b/build.jam @@ -5,22 +5,25 @@ 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/static_assert//boost_static_assert + /boost/throw_exception//boost_throw_exception + /boost/utility//boost_utility ; + project /boost/static_string : common-requirements - /boost/assert//boost_assert - /boost/config//boost_config - /boost/container_hash//boost_container_hash - /boost/core//boost_core - /boost/static_assert//boost_static_assert - /boost/throw_exception//boost_throw_exception - /boost/utility//boost_utility include ; explicit - [ alias boost_static_string ] + [ alias boost_static_string : : : : $(boost_dependencies) ] [ alias all : boost_static_string test ] ; call-if : boost-library static_string ; + From d677c9436c9ee5a359f604e317ff8aaede639862 Mon Sep 17 00:00:00 2001 From: Rene Rivera Date: Thu, 8 Aug 2024 23:35:43 -0500 Subject: [PATCH 24/73] Update build deps. --- test/Jamfile | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/test/Jamfile b/test/Jamfile index 030839f..4819625 100644 --- a/test/Jamfile +++ b/test/Jamfile @@ -21,6 +21,7 @@ local defines = ] ; -project : requirements $(defines) ; +project : requirements $(defines) + /boost/static_string//boost_static_string ; run static_string.cpp ; From a8f671ea1e0bab0ef4a57358c16f45205bdc63a1 Mon Sep 17 00:00:00 2001 From: Rene Rivera Date: Sat, 10 Aug 2024 20:28:46 -0500 Subject: [PATCH 25/73] Attempt to fix GHA. --- .github/workflows/ci.yml | 16 +++++----------- 1 file changed, 5 insertions(+), 11 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 22551ae..d7f16f1 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -219,7 +219,7 @@ jobs: then apt-get -o Acquire::Retries=$NET_RETRY_COUNT update apt-get -o Acquire::Retries=$NET_RETRY_COUNT install -y sudo software-properties-common tzdata wget curl apt-transport-https make apt-file unzip libssl-dev build-essential autotools-dev autoconf automake g++ libc++-helpers python ruby cpio gcc-multilib g++-multilib pkgconf python3 ccache libpython-dev - + # install pip: python_version=$(python3 -c 'import sys; print("{0.major}.{0.minor}".format(sys.version_info))') if [[ ${python_version} =~ ^3\.[0-5]$ ]]; then @@ -229,12 +229,12 @@ jobs: fi wget https://bootstrap.pypa.io/pip/$python_version/get-pip.py python3 get-pip.py - + # install git: # apt-get install -y git apt-add-repository ppa:git-core/ppa apt-get -o Acquire::Retries=$NET_RETRY_COUNT update && apt-get -o Acquire::Retries=$NET_RETRY_COUNT install -y git - + # install cmake: # apt-get -o Acquire::Retries=$NET_RETRY_COUNT install -y cmake sudo pip3 install cmake @@ -332,15 +332,9 @@ jobs: fi cd .. git clone -b "$BOOST_BRANCH" --depth 1 "https://github.com/boostorg/boost.git" "boost-root" - cd boost-root - # mkdir -p libs/$LIBRARY - # cp -r $GITHUB_WORKSPACE/* libs/$LIBRARY - # git submodule update --init tools/boostdep - git submodule update --init --recursive - mkdir -p libs/$SELF - cp -r $GITHUB_WORKSPACE/* libs/$SELF - + cp -r $GITHUB_WORKSPACE/* libs/$LIBRARY + git submodule update --init tools/boostdep DEPINST_ARGS+=("$LIBRARY") python tools/boostdep/depinst/depinst.py "${DEPINST_ARGS[@]}" if [ -z "${{matrix.cmake_tests}}" ] From 24d62635a315bfb2e26acb8ec73b30d64116083c Mon Sep 17 00:00:00 2001 From: Rene Rivera Date: Sat, 17 Aug 2024 00:12:32 -0500 Subject: [PATCH 26/73] Put back whitespace. --- .github/workflows/ci.yml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index d7f16f1..5989dc9 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -219,7 +219,7 @@ jobs: then apt-get -o Acquire::Retries=$NET_RETRY_COUNT update apt-get -o Acquire::Retries=$NET_RETRY_COUNT install -y sudo software-properties-common tzdata wget curl apt-transport-https make apt-file unzip libssl-dev build-essential autotools-dev autoconf automake g++ libc++-helpers python ruby cpio gcc-multilib g++-multilib pkgconf python3 ccache libpython-dev - + # install pip: python_version=$(python3 -c 'import sys; print("{0.major}.{0.minor}".format(sys.version_info))') if [[ ${python_version} =~ ^3\.[0-5]$ ]]; then @@ -229,12 +229,12 @@ jobs: fi wget https://bootstrap.pypa.io/pip/$python_version/get-pip.py python3 get-pip.py - + # install git: # apt-get install -y git apt-add-repository ppa:git-core/ppa apt-get -o Acquire::Retries=$NET_RETRY_COUNT update && apt-get -o Acquire::Retries=$NET_RETRY_COUNT install -y git - + # install cmake: # apt-get -o Acquire::Retries=$NET_RETRY_COUNT install -y cmake sudo pip3 install cmake From 7a53b7ff2082c5c2b2ab38085936ced852bb77a3 Mon Sep 17 00:00:00 2001 From: Rene Rivera Date: Thu, 17 Apr 2025 09:16:08 -0500 Subject: [PATCH 27/73] Move include to target. --- build.jam | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/build.jam b/build.jam index 9ab25d5..632c0c4 100644 --- a/build.jam +++ b/build.jam @@ -15,12 +15,11 @@ constant boost_dependencies : /boost/utility//boost_utility ; project /boost/static_string - : common-requirements - include ; explicit - [ alias boost_static_string : : : : $(boost_dependencies) ] + [ alias boost_static_string : : : + : include $(boost_dependencies) ] [ alias all : boost_static_string test ] ; From a421cf742c5dd9b09d2b21da42319de568e65df0 Mon Sep 17 00:00:00 2001 From: Alexander Grund Date: Tue, 30 Sep 2025 19:44:35 +0200 Subject: [PATCH 28/73] Switch to reusable GHA workflow Avoid the current failures due to outdated CI configs --- .github/workflows/ci.yml | 530 +++------------------------------------ 1 file changed, 30 insertions(+), 500 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 5989dc9..f3c2026 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -1,10 +1,19 @@ +# # Copyright 2020-2021 Peter Dimov # Copyright 2021 Andrey Semashev -# Copyright 2022 Alan de Freitas +# Copyright 2021-2025 Alexander Grund +# Copyright 2022-2025 James E. King III # # Distributed under the Boost Software License, Version 1.0. # (See accompanying file LICENSE_1_0.txt or copy at http://boost.org/LICENSE_1_0.txt) - +# +# This workflow uses the Boost.CI reusable workflow which builds a variety of +# configurations of your project, runs tests, and generates code coverage reports. +# +# To use it, copy this file into your repository as `.github/workflows/ci.yml` and +# customize it appropriately. +# +--- name: CI on: @@ -13,504 +22,25 @@ on: branches: - master - develop + - bugfix/** - feature/** - -concurrency: - group: ${{format('{0}:{1}', github.repository, github.ref)}} - cancel-in-progress: true - -env: - GIT_FETCH_JOBS: 8 - NET_RETRY_COUNT: 5 - DEFAULT_BUILD_VARIANT: debug,release + - fix/** + - github/** + - pr/** + paths-ignore: + - LICENSE + - meta/** + - README.md jobs: - posix: - defaults: - run: - shell: bash - - strategy: - fail-fast: false - matrix: - include: - # Linux, gcc - - toolset: gcc-4.8 - cxxstd: "11" - os: ubuntu-22.04 - container: ubuntu:18.04 - install: - - g++-4.8 - - toolset: gcc-4.9 - cxxstd: "11" - os: ubuntu-22.04 - container: ubuntu:16.04 - install: - - g++-4.9 - - toolset: gcc-5 - cxxstd: "11,14" - os: ubuntu-22.04 - container: ubuntu:16.04 - install: - - g++-5 - - toolset: gcc-6 - cxxstd: "11,14" - os: ubuntu-22.04 - container: ubuntu:18.04 - install: - - g++-6 - - toolset: gcc-7 - cxxstd: "14,17" - os: ubuntu-22.04 - container: ubuntu:18.04 - install: - - g++-7 - - toolset: gcc-8 - cxxstd: "17" - os: ubuntu-22.04 - container: ubuntu:18.04 - install: - - g++-8 - - toolset: gcc-9 - cxxstd: "17" - os: ubuntu-22.04 - install: - - g++-9 - - toolset: gcc-10 - cxxstd: "17" - os: ubuntu-22.04 - install: - - g++-10 - - toolset: gcc-11 - cxxstd: "17,20" - os: ubuntu-22.04 - install: - - g++-11 - sources: - - "ppa:ubuntu-toolchain-r/test" - - name: UBSAN - toolset: gcc-11 - cxxstd: "17,20" - ubsan: 1 - os: ubuntu-22.04 - install: - - g++-11 - sources: - - "ppa:ubuntu-toolchain-r/test" - - # Linux, clang - - toolset: clang - compiler: clang++-3.8 - cxxstd: "11" - os: ubuntu-22.04 - container: ubuntu:16.04 - install: - - clang-3.8 - - toolset: clang - compiler: clang++-4.0 - cxxstd: "11,14" - os: ubuntu-22.04 - container: ubuntu:18.04 - install: - - clang-4.0 - - toolset: clang - compiler: clang++-5.0 - cxxstd: "11,14" - os: ubuntu-22.04 - container: ubuntu:18.04 - install: - - clang-5.0 - - toolset: clang - compiler: clang++-6.0 - cxxstd: "14,17" - os: ubuntu-22.04 - container: ubuntu:18.04 - install: - - clang-6.0 - - toolset: clang - compiler: clang++-7 - cxxstd: "17" - os: ubuntu-22.04 - container: ubuntu:18.04 - install: - - clang-7 - - toolset: clang - compiler: clang++-8 - cxxstd: "17" - os: ubuntu-22.04 - container: ubuntu:18.04 - install: - - clang-8 - - g++-7 - gcc_toolchain: 7 - - toolset: clang - compiler: clang++-9 - cxxstd: "14,17" - os: ubuntu-22.04 - container: ubuntu:18.04 - install: - - clang-9 - - toolset: clang - compiler: clang++-10 - cxxstd: "14,17" - os: ubuntu-20.04 - install: - - clang-10 - - toolset: clang - compiler: clang++-11 - cxxstd: "14,17" - os: ubuntu-20.04 - install: - - clang-11 -# clang 12 tested on drone -# - toolset: clang -# compiler: clang++-12 -# cxxstd: "17,20" -# os: ubuntu-22.04 -# install: -# - clang-12 -# - toolset: clang -# compiler: clang++-12 -# cxxstd: "17,20" -# cxxflags: -stdlib=libc++ -# linkflags: -stdlib=libc++ -# os: ubuntu-20.04 -# install: -# - clang-12 -# - libc++-12-dev -# - libc++abi-12-dev -# - name: UBSAN -# toolset: clang -# compiler: clang++-12 -# cxxstd: "17,20" -# cxxflags: -stdlib=libc++ -# linkflags: -stdlib=libc++ -# ubsan: 1 -# os: ubuntu-20.04 -# install: -# - clang-12 -# - libc++-12-dev -# - libc++abi-12-dev - - - toolset: clang - cxxstd: "11,14,17" - os: macos-11 - - - name: CMake tests - cmake_tests: 1 - os: ubuntu-22.04 - - timeout-minutes: 120 - runs-on: ${{matrix.os}} - container: ${{matrix.container}} - - steps: - - name: Setup environment - run: | - if [ -f "/etc/debian_version" ] - then - echo "DEBIAN_FRONTEND=noninteractive" >> $GITHUB_ENV - export DEBIAN_FRONTEND=noninteractive - fi - if [ -n "${{matrix.container}}" ] - then - echo "GHA_CONTAINER=${{matrix.container}}" >> $GITHUB_ENV - if [ -f "/etc/debian_version" ] - then - apt-get -o Acquire::Retries=$NET_RETRY_COUNT update - apt-get -o Acquire::Retries=$NET_RETRY_COUNT install -y sudo software-properties-common tzdata wget curl apt-transport-https make apt-file unzip libssl-dev build-essential autotools-dev autoconf automake g++ libc++-helpers python ruby cpio gcc-multilib g++-multilib pkgconf python3 ccache libpython-dev - - # install pip: - python_version=$(python3 -c 'import sys; print("{0.major}.{0.minor}".format(sys.version_info))') - if [[ ${python_version} =~ ^3\.[0-5]$ ]]; then - true - else - apt-get install -y python3-distutils - fi - wget https://bootstrap.pypa.io/pip/$python_version/get-pip.py - python3 get-pip.py - - # install git: - # apt-get install -y git - apt-add-repository ppa:git-core/ppa - apt-get -o Acquire::Retries=$NET_RETRY_COUNT update && apt-get -o Acquire::Retries=$NET_RETRY_COUNT install -y git - - # install cmake: - # apt-get -o Acquire::Retries=$NET_RETRY_COUNT install -y cmake - sudo pip3 install cmake - fi - fi - git config --global pack.threads 0 - - - uses: actions/checkout@v2 - - - name: Install packages - if: matrix.install - run: | - SOURCE_KEYS=(${{join(matrix.source_keys, ' ')}}) - SOURCES=(${{join(matrix.sources, ' ')}}) - for key in "${SOURCE_KEYS[@]}" - do - for i in {1..$NET_RETRY_COUNT} - do - wget -O - "$key" | sudo apt-key add - && break || sleep 2 - done - done - if [ ${#SOURCES[@]} -gt 0 ] - then - APT_ADD_REPO_COMMON_ARGS=("-y") - APT_ADD_REPO_HAS_SOURCE_ARGS=0 - SOFTWARE_PROPERTIES_VERSION="$(dpkg-query --showformat='${Version}' --show software-properties-common)" - if dpkg --compare-versions "$SOFTWARE_PROPERTIES_VERSION" ge "0.96.24.20" - then - APT_ADD_REPO_COMMON_ARGS+=("-n") - fi - if dpkg --compare-versions "$SOFTWARE_PROPERTIES_VERSION" ge "0.98.10" - then - APT_ADD_REPO_HAS_SOURCE_ARGS=1 - fi - for source in "${SOURCES[@]}" - do - for i in {1..$NET_RETRY_COUNT} - do - APT_ADD_REPO_ARGS=("${APT_ADD_REPO_COMMON_ARGS[@]}") - if [ $APT_ADD_REPO_HAS_SOURCE_ARGS -ne 0 ] - then - case "$source" in - "ppa:"*) - APT_ADD_REPO_ARGS+=("-P") - ;; - "deb "*) - APT_ADD_REPO_ARGS+=("-S") - ;; - *) - APT_ADD_REPO_ARGS+=("-U") - ;; - esac - fi - APT_ADD_REPO_ARGS+=("$source") - sudo -E apt-add-repository "${APT_ADD_REPO_ARGS[@]}" && break || sleep 2 - done - done - fi - sudo apt-get -o Acquire::Retries=$NET_RETRY_COUNT update - sudo apt-get -o Acquire::Retries=$NET_RETRY_COUNT install -y ${{join(matrix.install, ' ')}} - - - name: Setup GCC Toolchain - if: matrix.gcc_toolchain - run: | - GCC_TOOLCHAIN_ROOT="$HOME/gcc-toolchain" - echo "GCC_TOOLCHAIN_ROOT=\"$GCC_TOOLCHAIN_ROOT\"" >> $GITHUB_ENV - MULTIARCH_TRIPLET="$(dpkg-architecture -qDEB_HOST_MULTIARCH)" - mkdir -p "$GCC_TOOLCHAIN_ROOT" - ln -s /usr/include "$GCC_TOOLCHAIN_ROOT/include" - ln -s /usr/bin "$GCC_TOOLCHAIN_ROOT/bin" - mkdir -p "$GCC_TOOLCHAIN_ROOT/lib/gcc/$MULTIARCH_TRIPLET" - ln -s "/usr/lib/gcc/$MULTIARCH_TRIPLET/${{matrix.gcc_toolchain}}" "$GCC_TOOLCHAIN_ROOT/lib/gcc/$MULTIARCH_TRIPLET/${{matrix.gcc_toolchain}}" - - - name: Setup Boost - run: | - echo GITHUB_REPOSITORY: $GITHUB_REPOSITORY - LIBRARY=${GITHUB_REPOSITORY#*/} - echo LIBRARY: $LIBRARY - echo "LIBRARY=$LIBRARY" >> $GITHUB_ENV - echo GITHUB_BASE_REF: $GITHUB_BASE_REF - echo GITHUB_REF: $GITHUB_REF - REF=${GITHUB_BASE_REF:-$GITHUB_REF} - REF=${REF#refs/heads/} - echo REF: $REF - BOOST_BRANCH=develop && [ "$REF" == "master" ] && BOOST_BRANCH=master || true - echo BOOST_BRANCH: $BOOST_BRANCH - BUILD_JOBS=$((nproc || sysctl -n hw.ncpu) 2> /dev/null) - echo "BUILD_JOBS=$BUILD_JOBS" >> $GITHUB_ENV - echo "CMAKE_BUILD_PARALLEL_LEVEL=$BUILD_JOBS" >> $GITHUB_ENV - DEPINST_ARGS=() - GIT_VERSION="$(git --version | sed -e 's/git version //')" - if $(dpkg --compare-versions "$GIT_VERSION" ge 2.8.0) - then - DEPINST_ARGS+=("--git_args" "--jobs $GIT_FETCH_JOBS") - fi - cd .. - git clone -b "$BOOST_BRANCH" --depth 1 "https://github.com/boostorg/boost.git" "boost-root" - cd boost-root - cp -r $GITHUB_WORKSPACE/* libs/$LIBRARY - git submodule update --init tools/boostdep - DEPINST_ARGS+=("$LIBRARY") - python tools/boostdep/depinst/depinst.py "${DEPINST_ARGS[@]}" - if [ -z "${{matrix.cmake_tests}}" ] - then - ./bootstrap.sh - ./b2 headers - if [ -n "${{matrix.compiler}}" -o -n "$GCC_TOOLCHAIN_ROOT" ] - then - echo -n "using ${{matrix.toolset}} : : ${{matrix.compiler}}" > ~/user-config.jam - if [ -n "$GCC_TOOLCHAIN_ROOT" ] - then - echo -n " : \"--gcc-toolchain=$GCC_TOOLCHAIN_ROOT\" \"--gcc-toolchain=$GCC_TOOLCHAIN_ROOT\"" >> ~/user-config.jam - fi - echo " ;" >> ~/user-config.jam - fi - fi - - - name: Run tests - if: matrix.cmake_tests == '' - run: | - cd ../boost-root - B2_ARGS=("-j" "$BUILD_JOBS" "toolset=${{matrix.toolset}}" "cxxstd=${{matrix.cxxstd}}") - if [ -n "${{matrix.build_variant}}" ] - then - B2_ARGS+=("variant=${{matrix.build_variant}}") - else - B2_ARGS+=("variant=$DEFAULT_BUILD_VARIANT") - fi - if [ -n "${{matrix.threading}}" ] - then - B2_ARGS+=("threading=${{matrix.threading}}") - fi - if [ -n "${{matrix.ubsan}}" ] - then - export UBSAN_OPTIONS="print_stacktrace=1" - B2_ARGS+=("cxxflags=-fsanitize=undefined -fno-sanitize-recover=undefined" "linkflags=-fsanitize=undefined -fuse-ld=gold" "define=UBSAN=1" "debug-symbols=on" "visibility=global") - fi - if [ -n "${{matrix.cxxflags}}" ] - then - B2_ARGS+=("cxxflags=${{matrix.cxxflags}}") - fi - if [ -n "${{matrix.linkflags}}" ] - then - B2_ARGS+=("linkflags=${{matrix.linkflags}}") - fi - B2_ARGS+=("libs/$LIBRARY/test") - ./b2 "${B2_ARGS[@]}" - -# - name: Run CMake tests -# if: matrix.cmake_tests != '' -# run: | -# cd ../boost-root -# git submodule update --init --recursive -# cd libs/$LIBRARY -# mkdir __build__ && cd __build__ -# cmake -DCMAKE_INSTALL_PREFIX=~/.local .. -# cmake --build . --target install - - windows: - strategy: - fail-fast: false - matrix: - include: - #- toolset: msvc-14.1 - # cxxstd: "14,17,latest" - # addrmd: 32,64 - # os: windows-2016 - - toolset: msvc-14.2 - cxxstd: "14,17" - addrmd: 32,64 - os: windows-2019 - - toolset: msvc-14.3 - cxxstd: "17,20" - addrmd: 32,64 - os: windows-2022 - # - toolset: gcc - # cxxstd: "11,14,17" - # addrmd: 64 - # os: windows-2019 - - runs-on: ${{matrix.os}} - - steps: - - uses: actions/checkout@v2 - - - name: Setup Boost - shell: cmd - run: | - echo GITHUB_REPOSITORY: %GITHUB_REPOSITORY% - for /f %%i in ("%GITHUB_REPOSITORY%") do set LIBRARY=%%~nxi - echo LIBRARY: %LIBRARY% - echo LIBRARY=%LIBRARY%>>%GITHUB_ENV% - echo GITHUB_BASE_REF: %GITHUB_BASE_REF% - echo GITHUB_REF: %GITHUB_REF% - if "%GITHUB_BASE_REF%" == "" set GITHUB_BASE_REF=%GITHUB_REF% - set BOOST_BRANCH=develop - for /f %%i in ("%GITHUB_BASE_REF%") do if "%%~nxi" == "master" set BOOST_BRANCH=master - echo BOOST_BRANCH: %BOOST_BRANCH% - cd .. - git clone -b %BOOST_BRANCH% --depth 1 https://github.com/boostorg/boost.git boost-root - cd boost-root - xcopy /s /e /q %GITHUB_WORKSPACE% libs\%LIBRARY%\ - git submodule update --init tools/boostdep - python tools/boostdep/depinst/depinst.py --git_args "--jobs %GIT_FETCH_JOBS%" %LIBRARY% - cmd /c bootstrap - b2 -d0 headers - - - name: Run tests - shell: cmd - run: | - cd ../boost-root - b2 -j %NUMBER_OF_PROCESSORS% libs/%LIBRARY%/test toolset=${{matrix.toolset}} cxxstd=${{matrix.cxxstd}} address-model=${{matrix.addrmd}} variant=debug,release - - CMake: - defaults: - run: - shell: bash - - strategy: - fail-fast: false - matrix: - include: - - { os: ubuntu-22.04, build_shared: ON, build_type: Debug, generator: 'Unix Makefiles' } - - { os: ubuntu-22.04, build_shared: OFF, build_type: Debug, generator: 'Unix Makefiles' } - - { os: windows-2019, build_shared: ON, build_type: Debug, generator: 'Visual Studio 16 2019' } - - { os: windows-2019, build_shared: OFF, build_type: Debug, generator: 'Visual Studio 16 2019' } - - timeout-minutes: 120 - runs-on: ${{matrix.os}} - - steps: - - uses: actions/checkout@v2 - - name: Fetch Boost.CI - uses: actions/checkout@v2 - with: - repository: boostorg/boost-ci - ref: master - path: boost-ci-cloned - - - name: Get CI scripts folder - run: | - # Copy ci folder if not testing Boost.CI - [[ "$GITHUB_REPOSITORY" =~ "boost-ci" ]] || cp -r boost-ci-cloned/ci . - rm -rf boost-ci-cloned - - name: Setup Boost - env: {B2_DONT_BOOTSTRAP: 1} - run: source ci/github/install.sh - -# - name: Run CMake tests -# run: | -# cd "$BOOST_ROOT" -# mkdir __build_cmake_test__ && cd __build_cmake_test__ -# cmake -G "${{matrix.generator}}" -DCMAKE_BUILD_TYPE=${{matrix.build_type}} -DBOOST_INCLUDE_LIBRARIES=$SELF -DBUILD_SHARED_LIBS=${{matrix.build_shared}} -DBUILD_TESTING=ON -DBoost_VERBOSE=ON .. -# cmake --build . --target tests boost_url_tests boost_url_limits boost_url_extra --config ${{matrix.build_type}} -# ctest --output-on-failure --build-config ${{matrix.build_type}} -# - name: Run CMake subdir tests -# run: | -# cmake_test_folder="$BOOST_ROOT/libs/$SELF/test/cmake_test" # New unified folder -# [ -d "$cmake_test_folder" ] || cmake_test_folder="$BOOST_ROOT/libs/$SELF/test/cmake_subdir_test" -# cd "$cmake_test_folder" -# mkdir __build_cmake_subdir_test__ && cd __build_cmake_subdir_test__ -# cmake -G "${{matrix.generator}}" -DBOOST_CI_INSTALL_TEST=OFF -DCMAKE_BUILD_TYPE=${{matrix.build_type}} -DBUILD_SHARED_LIBS=${{matrix.build_shared}} .. -# cmake --build . --config ${{matrix.build_type}} -# ctest --output-on-failure --build-config ${{matrix.build_type}} -# - name: Install Library -# run: | -# cd "$BOOST_ROOT" -# mkdir __build_cmake_install_test__ && cd __build_cmake_install_test__ -# cmake -G "${{matrix.generator}}" -DCMAKE_BUILD_TYPE=${{matrix.build_type}} -DBOOST_INCLUDE_LIBRARIES=$SELF -DBUILD_SHARED_LIBS=${{matrix.build_shared}} -DCMAKE_INSTALL_PREFIX=~/.local -DBoost_VERBOSE=ON -DBoost_DEBUG=ON .. -# cmake --build . --target install --config ${{matrix.build_type}} -# - name: Run CMake install tests -# run: | -# cmake_test_folder="$BOOST_ROOT/libs/$SELF/test/cmake_test" # New unified folder -# [ -d "$cmake_test_folder" ] || cmake_test_folder="$BOOST_ROOT/libs/$SELF/test/cmake_install_test" -# cd "$cmake_test_folder" -# mkdir __build_cmake_install_test__ && cd __build_cmake_install_test__ -# cmake -G "${{matrix.generator}}" -DBOOST_CI_INSTALL_TEST=ON -DCMAKE_BUILD_TYPE=${{matrix.build_type}} -DBUILD_SHARED_LIBS=${{matrix.build_shared}} -DCMAKE_PREFIX_PATH=~/.local .. -# cmake --build . --config ${{matrix.build_type}} -# ctest --output-on-failure --build-config ${{matrix.build_type}} + call-boost-ci: + name: Run Boost.CI + uses: boostorg/boost-ci/.github/workflows/reusable.yml@master + # Example of customization: + # with: + # enable_reflection: true + # enable_windows: false + secrets: + CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }} + COVERITY_SCAN_NOTIFICATION_EMAIL: ${{ secrets.COVERITY_SCAN_NOTIFICATION_EMAIL }} + COVERITY_SCAN_TOKEN: ${{ secrets.COVERITY_SCAN_TOKEN }} From d37197d77388c77276138294888f167d796f5329 Mon Sep 17 00:00:00 2001 From: Alexander Grund Date: Tue, 30 Sep 2025 19:55:45 +0200 Subject: [PATCH 29/73] Add CMake subdir test for CI --- test/cmake_test/CMakeLists.txt | 24 ++++++++++++++++++++++++ test/cmake_test/main.cpp | 18 ++++++++++++++++++ 2 files changed, 42 insertions(+) create mode 100644 test/cmake_test/CMakeLists.txt create mode 100644 test/cmake_test/main.cpp diff --git a/test/cmake_test/CMakeLists.txt b/test/cmake_test/CMakeLists.txt new file mode 100644 index 0000000..a8d5589 --- /dev/null +++ b/test/cmake_test/CMakeLists.txt @@ -0,0 +1,24 @@ +# Copyright 2021-2025 Alexander Grund +# 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 + +cmake_minimum_required(VERSION 3.8...3.16) + +project(cmake_subdir_test LANGUAGES CXX) + +# Those 2 should work the same +# while using find_package for the installed Boost avoids the need to manually specify dependencies +if(BOOST_CI_INSTALL_TEST) + find_package(boost_static_string REQUIRED) +else() + set(BOOST_INCLUDE_LIBRARIES static_string) + add_subdirectory(../../../.. deps/boost EXCLUDE_FROM_ALL) +endif() + +add_executable(main main.cpp) +target_link_libraries(main Boost::static_string) + +enable_testing() +add_test(NAME main COMMAND main) + +add_custom_target(check COMMAND ${CMAKE_CTEST_COMMAND} --output-on-failure -C $) \ No newline at end of file diff --git a/test/cmake_test/main.cpp b/test/cmake_test/main.cpp new file mode 100644 index 0000000..18ecbfb --- /dev/null +++ b/test/cmake_test/main.cpp @@ -0,0 +1,18 @@ +// +// Copyright (c) 2025 Alexander Grund +// +// 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) +// +// Official repository: https://github.com/boostorg/static_string +// + +#include + +int main() +{ + // Smoke test only + boost::static_string<1> s_empty; + boost::static_string<4> s_3(3, 'x'); + return (s_empty.empty() && s_3.size() == 3) ? 0 : 1; +} From 5067dfce5faa285830d299f27d42686dcf912071 Mon Sep 17 00:00:00 2001 From: Alexander Grund Date: Wed, 1 Oct 2025 10:04:36 +0200 Subject: [PATCH 30/73] Use `BOOST_TEST_EQ` for `to_static_string` tests using floating point values --- test/static_string.cpp | 36 +++++++++++++++++++++--------------- 1 file changed, 21 insertions(+), 15 deletions(-) diff --git a/test/static_string.cpp b/test/static_string.cpp index db79c37..86abe76 100644 --- a/test/static_string.cpp +++ b/test/static_string.cpp @@ -269,6 +269,12 @@ testTS(Arithmetic value, const char* str_expected = "", bool test_expected = fal } } +#define TEST_TO_STATIC_STRING(value) do { \ + const auto str = to_static_string(value); \ + const auto std_res = std::to_string(value); \ + BOOST_TEST_EQ(str, std_res); \ +} while(0) + template bool testTWS(Arithmetic value, const wchar_t* wstr_expected = L"", bool test_expected = false) @@ -3946,21 +3952,21 @@ testToStaticString() BOOST_TEST(testTS(-4294967295ll, "-4294967295", true)); BOOST_TEST(testTS(1, "1", true)); BOOST_TEST(testTS(-1, "-1", true)); - BOOST_TEST(testTS(0.1)); - BOOST_TEST(testTS(0.0000001)); - BOOST_TEST(testTS(-0.0000001)); - BOOST_TEST(testTS(-0.1)); - BOOST_TEST(testTS(1234567890.0001)); - BOOST_TEST(testTS(1.123456789012345)); - BOOST_TEST(testTS(-1234567890.1234)); - BOOST_TEST(testTS(-1.123456789012345)); - - BOOST_TEST(testTS(std::numeric_limits::max())); - BOOST_TEST(testTS(std::numeric_limits::min())); - BOOST_TEST(testTS(std::numeric_limits::max())); - BOOST_TEST(testTS(std::numeric_limits::max())); - BOOST_TEST(testTS(std::numeric_limits::min())); - BOOST_TEST(testTS(std::numeric_limits::min())); + TEST_TO_STATIC_STRING(0.1); + TEST_TO_STATIC_STRING(0.0000001); + TEST_TO_STATIC_STRING(-0.0000001); + TEST_TO_STATIC_STRING(-0.1); + TEST_TO_STATIC_STRING(1234567890.0001); + TEST_TO_STATIC_STRING(1.123456789012345); + TEST_TO_STATIC_STRING(-1234567890.1234); + TEST_TO_STATIC_STRING(-1.123456789012345); + + TEST_TO_STATIC_STRING(std::numeric_limits::max()); + TEST_TO_STATIC_STRING(std::numeric_limits::min()); + TEST_TO_STATIC_STRING(std::numeric_limits::max()); + TEST_TO_STATIC_STRING(std::numeric_limits::max()); + TEST_TO_STATIC_STRING(std::numeric_limits::min()); + TEST_TO_STATIC_STRING(std::numeric_limits::min()); // these tests technically are not portable, but they will work // 99% of the time. From 645bf0a27d870fe57d005561c4dd09b6e5f141b9 Mon Sep 17 00:00:00 2001 From: Alexander Grund Date: Wed, 1 Oct 2025 13:40:21 +0200 Subject: [PATCH 31/73] Simplify `testTS` Replace boolean by check for defaulted nullptr --- test/static_string.cpp | 52 +++++++++++++++++++++--------------------- 1 file changed, 26 insertions(+), 26 deletions(-) diff --git a/test/static_string.cpp b/test/static_string.cpp index 86abe76..56825b9 100644 --- a/test/static_string.cpp +++ b/test/static_string.cpp @@ -245,7 +245,7 @@ testR(S s, typename S::size_type pos, typename S::size_type n1, const typename S template bool -testTS(Arithmetic value, const char* str_expected = "", bool test_expected = false) +testTS(Arithmetic value, const char* str_expected = nullptr) { const auto str = to_static_string(value); if (std::is_floating_point::value) @@ -259,12 +259,12 @@ testTS(Arithmetic value, const char* str_expected = "", bool test_expected = fal { return Arithmetic(std::strtoll(str.begin(), nullptr, 10)) == value && - (! test_expected || str == str_expected); + (! str_expected || str == str_expected); } else { return Arithmetic(std::strtoull(str.begin(), nullptr, 10)) == value && - (! test_expected || str == str_expected); + (! str_expected || str == str_expected); } } } @@ -277,7 +277,7 @@ testTS(Arithmetic value, const char* str_expected = "", bool test_expected = fal template bool -testTWS(Arithmetic value, const wchar_t* wstr_expected = L"", bool test_expected = false) +testTWS(Arithmetic value, const wchar_t* wstr_expected = nullptr) { const auto wstr = to_static_wstring(value); if (std::is_floating_point::value) @@ -291,12 +291,12 @@ testTWS(Arithmetic value, const wchar_t* wstr_expected = L"", bool test_expected { return Arithmetic(std::wcstoll(wstr.begin(), nullptr, 10)) == value && - (! test_expected || wstr == wstr_expected); + (! wstr_expected || wstr == wstr_expected); } else { return Arithmetic(std::wcstoull(wstr.begin(), nullptr, 10)) == value && - (! test_expected || wstr == wstr_expected); + (! wstr_expected || wstr == wstr_expected); } } } @@ -3942,16 +3942,16 @@ testGeneral() void testToStaticString() { - BOOST_TEST(testTS(0, "0", true)); - BOOST_TEST(testTS(0u, "0", true)); - BOOST_TEST(testTS(0xffff, "65535", true)); - BOOST_TEST(testTS(0x10000, "65536", true)); - BOOST_TEST(testTS(0xffffffff, "4294967295", true)); - BOOST_TEST(testTS(-65535, "-65535", true)); - BOOST_TEST(testTS(-65536, "-65536", true)); - BOOST_TEST(testTS(-4294967295ll, "-4294967295", true)); - BOOST_TEST(testTS(1, "1", true)); - BOOST_TEST(testTS(-1, "-1", true)); + BOOST_TEST(testTS(0, "0")); + BOOST_TEST(testTS(0u, "0")); + BOOST_TEST(testTS(0xffff, "65535")); + BOOST_TEST(testTS(0x10000, "65536")); + BOOST_TEST(testTS(0xffffffff, "4294967295")); + BOOST_TEST(testTS(-65535, "-65535")); + BOOST_TEST(testTS(-65536, "-65536")); + BOOST_TEST(testTS(-4294967295ll, "-4294967295")); + BOOST_TEST(testTS(1, "1")); + BOOST_TEST(testTS(-1, "-1")); TEST_TO_STATIC_STRING(0.1); TEST_TO_STATIC_STRING(0.0000001); TEST_TO_STATIC_STRING(-0.0000001); @@ -3988,16 +3988,16 @@ testToStaticString() #ifdef BOOST_STATIC_STRING_HAS_WCHAR - BOOST_TEST(testTWS(0, L"0", true)); - BOOST_TEST(testTWS(0u, L"0", true)); - BOOST_TEST(testTWS(0xffff, L"65535", true)); - BOOST_TEST(testTWS(0x10000, L"65536", true)); - BOOST_TEST(testTWS(0xffffffff, L"4294967295", true)); - BOOST_TEST(testTWS(-65535, L"-65535", true)); - BOOST_TEST(testTWS(-65536, L"-65536", true)); - BOOST_TEST(testTWS(-4294967295ll, L"-4294967295", true)); - BOOST_TEST(testTWS(1, L"1", true)); - BOOST_TEST(testTWS(-1, L"-1", true)); + BOOST_TEST(testTWS(0, L"0")); + BOOST_TEST(testTWS(0u, L"0")); + BOOST_TEST(testTWS(0xffff, L"65535")); + BOOST_TEST(testTWS(0x10000, L"65536")); + BOOST_TEST(testTWS(0xffffffff, L"4294967295")); + BOOST_TEST(testTWS(-65535, L"-65535")); + BOOST_TEST(testTWS(-65536, L"-65536")); + BOOST_TEST(testTWS(-4294967295ll, L"-4294967295")); + BOOST_TEST(testTWS(1, L"1")); + BOOST_TEST(testTWS(-1, L"-1")); BOOST_TEST(testTWS(0.1)); BOOST_TEST(testTWS(0.0000001)); BOOST_TEST(testTWS(-0.0000001)); From cd546285c48d1df6df231bea4b4c87e73c50ab42 Mon Sep 17 00:00:00 2001 From: Alexander Grund Date: Fri, 3 Oct 2025 12:03:44 +0200 Subject: [PATCH 32/73] CI: Don't test C++26/2c --- .github/workflows/ci.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index f3c2026..a218baf 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -36,6 +36,8 @@ jobs: call-boost-ci: name: Run Boost.CI uses: boostorg/boost-ci/.github/workflows/reusable.yml@master + with: + exclude_cxxstd: '98,03,0x,2c,26' # Example of customization: # with: # enable_reflection: true From 37a557d9370db224a274f4a5f41f910bc87feff0 Mon Sep 17 00:00:00 2001 From: Arthur O'Dwyer Date: Wed, 20 Mar 2024 16:42:01 -0400 Subject: [PATCH 33/73] Make static_string trivially copyable --- include/boost/static_string/static_string.hpp | 12 +---- test/static_string.cpp | 49 +++++++++++++++++++ 2 files changed, 51 insertions(+), 10 deletions(-) diff --git a/include/boost/static_string/static_string.hpp b/include/boost/static_string/static_string.hpp index fce1ddb..71952e6 100644 --- a/include/boost/static_string/static_string.hpp +++ b/include/boost/static_string/static_string.hpp @@ -1093,11 +1093,7 @@ class basic_static_string Copy constructor. */ - BOOST_STATIC_STRING_CPP14_CONSTEXPR - basic_static_string(const basic_static_string& other) noexcept - { - assign(other); - } + basic_static_string(const basic_static_string& other) = default; /** Constructor. @@ -1185,12 +1181,8 @@ class basic_static_string @throw std::length_error `s.size() > max_size()`. */ - BOOST_STATIC_STRING_CPP14_CONSTEXPR basic_static_string& - operator=(const basic_static_string& s) - { - return assign(s); - } + operator=(const basic_static_string& s) = default; /** Assign to the string. diff --git a/test/static_string.cpp b/test/static_string.cpp index 56825b9..aa44922 100644 --- a/test/static_string.cpp +++ b/test/static_string.cpp @@ -301,6 +301,53 @@ testTWS(Arithmetic value, const wchar_t* wstr_expected = nullptr) } } +// done +static +void +testTypeTraits() +{ + { + using S = static_string<0>; + static_assert(std::is_trivially_copyable::value, ""); + static_assert(!std::is_trivially_default_constructible::value, ""); + static_assert(std::is_trivially_copy_constructible::value, ""); + static_assert(std::is_trivially_move_constructible::value, ""); + static_assert(std::is_trivially_copy_assignable::value, ""); + static_assert(std::is_trivially_move_assignable::value, ""); + static_assert(std::is_trivially_destructible::value, ""); + } + { + using S = static_string<1>; + static_assert(std::is_trivially_copyable::value, ""); + static_assert(!std::is_trivially_default_constructible::value, ""); + static_assert(std::is_trivially_copy_constructible::value, ""); + static_assert(std::is_trivially_move_constructible::value, ""); + static_assert(std::is_trivially_copy_assignable::value, ""); + static_assert(std::is_trivially_move_assignable::value, ""); + static_assert(std::is_trivially_destructible::value, ""); + } + { + using S = static_string<20>; + static_assert(std::is_trivially_copyable::value, ""); + static_assert(!std::is_trivially_default_constructible::value, ""); + static_assert(std::is_trivially_copy_constructible::value, ""); + static_assert(std::is_trivially_move_constructible::value, ""); + static_assert(std::is_trivially_copy_assignable::value, ""); + static_assert(std::is_trivially_move_assignable::value, ""); + static_assert(std::is_trivially_destructible::value, ""); + } + { + using S = static_string<400>; + static_assert(std::is_trivially_copyable::value, ""); + static_assert(!std::is_trivially_default_constructible::value, ""); + static_assert(std::is_trivially_copy_constructible::value, ""); + static_assert(std::is_trivially_move_constructible::value, ""); + static_assert(std::is_trivially_copy_assignable::value, ""); + static_assert(std::is_trivially_move_assignable::value, ""); + static_assert(std::is_trivially_destructible::value, ""); + } +} + // done static void @@ -7467,6 +7514,8 @@ runTests() constexpr auto cxper = testConstantEvaluation(); static_cast(cxper); + testTypeTraits(); + testConstruct(); testAssignment(); From 5dfbb1f2b1b3b8930f292daacadd01a2246b9526 Mon Sep 17 00:00:00 2001 From: Alexander Grund Date: Mon, 6 Oct 2025 14:03:15 +0200 Subject: [PATCH 34/73] CI: Disable coverage and coverity jobs --- .github/workflows/ci.yml | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index a218baf..6eedc29 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -38,11 +38,12 @@ jobs: uses: boostorg/boost-ci/.github/workflows/reusable.yml@master with: exclude_cxxstd: '98,03,0x,2c,26' + enable_pr_coverage: false # Example of customization: # with: # enable_reflection: true # enable_windows: false - secrets: - CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }} - COVERITY_SCAN_NOTIFICATION_EMAIL: ${{ secrets.COVERITY_SCAN_NOTIFICATION_EMAIL }} - COVERITY_SCAN_TOKEN: ${{ secrets.COVERITY_SCAN_TOKEN }} + # secrets: + # CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }} + # COVERITY_SCAN_NOTIFICATION_EMAIL: ${{ secrets.COVERITY_SCAN_NOTIFICATION_EMAIL }} + # COVERITY_SCAN_TOKEN: ${{ secrets.COVERITY_SCAN_TOKEN }} From 7f903ef7cec2dd2ba39499d91eea7ab7db343718 Mon Sep 17 00:00:00 2001 From: Alexander Grund Date: Mon, 6 Oct 2025 14:07:59 +0200 Subject: [PATCH 35/73] Add cxx11_hdr_type_traits B2 requirement Avoid failures with GCC < 5 --- test/Jamfile | 1 + test/static_string.cpp | 1 - 2 files changed, 1 insertion(+), 1 deletion(-) diff --git a/test/Jamfile b/test/Jamfile index 4819625..8c394c0 100644 --- a/test/Jamfile +++ b/test/Jamfile @@ -16,6 +16,7 @@ local defines = cxx11_constexpr cxx11_decltype cxx11_hdr_tuple + cxx11_hdr_type_traits cxx11_template_aliases cxx11_variadic_templates ] diff --git a/test/static_string.cpp b/test/static_string.cpp index aa44922..7c77842 100644 --- a/test/static_string.cpp +++ b/test/static_string.cpp @@ -301,7 +301,6 @@ testTWS(Arithmetic value, const wchar_t* wstr_expected = nullptr) } } -// done static void testTypeTraits() From 20afd07676825fc77d068ad8161477695bb89ad7 Mon Sep 17 00:00:00 2001 From: Alexander Grund Date: Mon, 6 Oct 2025 14:34:37 +0200 Subject: [PATCH 36/73] Pass char arrays instead of static_string instances to `testR` Avoid stack overflow in MSVC caused by huge amount of static_string instances Fixes #70 --- test/static_string.cpp | 1688 ++++++++++++++++++++-------------------- 1 file changed, 844 insertions(+), 844 deletions(-) diff --git a/test/static_string.cpp b/test/static_string.cpp index 7c77842..091b74b 100644 --- a/test/static_string.cpp +++ b/test/static_string.cpp @@ -192,22 +192,24 @@ testFLN(const S& s, const typename S::value_type* str, typename S::size_type pos return s.find_last_not_of(str, pos, n) == x; } -template +template bool -testR(S s, typename S::size_type pos1, typename S::size_type n1, const typename S::value_type* str, S expected) +testR(const char (&s_in)[N1], std::size_t pos1, std::size_t n1, const char* str, const char (&expected)[N2]) { + using S = static_string<400>; + S s(s_in); typename S::const_iterator first = s.begin() + pos1; typename S::const_iterator last = s.begin() + pos1 + n1; s.replace(first, last, str); return s == expected; } -template +template bool -testR(S s, typename S::size_type pos, typename S::size_type n1, typename S::size_type n2, typename S::value_type c, S expected) +testR(const char (&s_in)[N1], std::size_t pos, std::size_t n1, std::size_t n2, char c, const char (&expected)[N2]) { - const typename S::size_type old_size = s.size(); - if (pos <= old_size) + static_string<400> s(s_in); + if (pos <= s.size()) { s.replace(pos, n1, n2, c); return s == expected; @@ -219,16 +221,14 @@ testR(S s, typename S::size_type pos, typename S::size_type n1, typename S::size } } -template +template bool -testR(S s, typename S::size_type pos, typename S::size_type n1, const typename S::value_type* str, typename S::size_type n2, S expected) +testR(const char (&s_in)[N1], std::size_t pos, std::size_t n1, const char* str, std::size_t n2, const char (&expected)[N2]) { - const typename S::size_type old_size = s.size(); - S s0 = s; - if (n1 > old_size) - s.size(); - if (pos <= old_size) + static_string<400> s(s_in); + if (pos <= s.size()) { + auto s0 = s; if (pos + n1 > s0.size()) // this is a precondition violation for the const_iterator overload return s.replace(pos, n1, str, n2) == expected; @@ -6271,837 +6271,837 @@ testReplace() BOOST_TEST(s_short.replace(s_short.begin(), s_short.begin(), s_short.begin(), s_short.end()) == "123/123/123/123/123/123/123/123/"); BOOST_TEST(s_long.replace(s_long.begin(), s_long.begin(), s_long.begin(), s_long.end()) == "Lorem ipsum dolor sit amet, consectetur/Lorem ipsum dolor sit amet, consectetur/"); - BOOST_TEST(testR(S(""), 0, 0, "", S(""))); - BOOST_TEST(testR(S(""), 0, 0, "12345", S("12345"))); - BOOST_TEST(testR(S(""), 0, 0, "1234567890", S("1234567890"))); - BOOST_TEST(testR(S(""), 0, 0, "12345678901234567890", S("12345678901234567890"))); - BOOST_TEST(testR(S("abcde"), 0, 0, "", S("abcde"))); - BOOST_TEST(testR(S("abcde"), 0, 0, "12345", S("12345abcde"))); - BOOST_TEST(testR(S("abcde"), 0, 0, "1234567890", S("1234567890abcde"))); - BOOST_TEST(testR(S("abcde"), 0, 0, "12345678901234567890", S("12345678901234567890abcde"))); - BOOST_TEST(testR(S("abcde"), 0, 1, "", S("bcde"))); - BOOST_TEST(testR(S("abcde"), 0, 1, "12345", S("12345bcde"))); - BOOST_TEST(testR(S("abcde"), 0, 1, "1234567890", S("1234567890bcde"))); - BOOST_TEST(testR(S("abcde"), 0, 1, "12345678901234567890", S("12345678901234567890bcde"))); - BOOST_TEST(testR(S("abcde"), 0, 2, "", S("cde"))); - BOOST_TEST(testR(S("abcde"), 0, 2, "12345", S("12345cde"))); - BOOST_TEST(testR(S("abcde"), 0, 2, "1234567890", S("1234567890cde"))); - BOOST_TEST(testR(S("abcde"), 0, 2, "12345678901234567890", S("12345678901234567890cde"))); - BOOST_TEST(testR(S("abcde"), 0, 4, "", S("e"))); - BOOST_TEST(testR(S("abcde"), 0, 4, "12345", S("12345e"))); - BOOST_TEST(testR(S("abcde"), 0, 4, "1234567890", S("1234567890e"))); - BOOST_TEST(testR(S("abcde"), 0, 4, "12345678901234567890", S("12345678901234567890e"))); - BOOST_TEST(testR(S("abcde"), 0, 5, "", S(""))); - BOOST_TEST(testR(S("abcde"), 0, 5, "12345", S("12345"))); - BOOST_TEST(testR(S("abcde"), 0, 5, "1234567890", S("1234567890"))); - BOOST_TEST(testR(S("abcde"), 0, 5, "12345678901234567890", S("12345678901234567890"))); - BOOST_TEST(testR(S("abcde"), 1, 0, "", S("abcde"))); - BOOST_TEST(testR(S("abcde"), 1, 0, "12345", S("a12345bcde"))); - BOOST_TEST(testR(S("abcde"), 1, 0, "1234567890", S("a1234567890bcde"))); - BOOST_TEST(testR(S("abcde"), 1, 0, "12345678901234567890", S("a12345678901234567890bcde"))); - BOOST_TEST(testR(S("abcde"), 1, 1, "", S("acde"))); - BOOST_TEST(testR(S("abcde"), 1, 1, "12345", S("a12345cde"))); - BOOST_TEST(testR(S("abcde"), 1, 1, "1234567890", S("a1234567890cde"))); - BOOST_TEST(testR(S("abcde"), 1, 1, "12345678901234567890", S("a12345678901234567890cde"))); - BOOST_TEST(testR(S("abcde"), 1, 2, "", S("ade"))); - BOOST_TEST(testR(S("abcde"), 1, 2, "12345", S("a12345de"))); - BOOST_TEST(testR(S("abcde"), 1, 2, "1234567890", S("a1234567890de"))); - BOOST_TEST(testR(S("abcde"), 1, 2, "12345678901234567890", S("a12345678901234567890de"))); - BOOST_TEST(testR(S("abcde"), 1, 3, "", S("ae"))); - BOOST_TEST(testR(S("abcde"), 1, 3, "12345", S("a12345e"))); - BOOST_TEST(testR(S("abcde"), 1, 3, "1234567890", S("a1234567890e"))); - BOOST_TEST(testR(S("abcde"), 1, 3, "12345678901234567890", S("a12345678901234567890e"))); - BOOST_TEST(testR(S("abcde"), 1, 4, "", S("a"))); - BOOST_TEST(testR(S("abcde"), 1, 4, "12345", S("a12345"))); - BOOST_TEST(testR(S("abcde"), 1, 4, "1234567890", S("a1234567890"))); - BOOST_TEST(testR(S("abcde"), 1, 4, "12345678901234567890", S("a12345678901234567890"))); - BOOST_TEST(testR(S("abcde"), 2, 0, "", S("abcde"))); - BOOST_TEST(testR(S("abcde"), 2, 0, "12345", S("ab12345cde"))); - BOOST_TEST(testR(S("abcde"), 2, 0, "1234567890", S("ab1234567890cde"))); - BOOST_TEST(testR(S("abcde"), 2, 0, "12345678901234567890", S("ab12345678901234567890cde"))); - BOOST_TEST(testR(S("abcde"), 2, 1, "", S("abde"))); - BOOST_TEST(testR(S("abcde"), 2, 1, "12345", S("ab12345de"))); - BOOST_TEST(testR(S("abcde"), 2, 1, "1234567890", S("ab1234567890de"))); - BOOST_TEST(testR(S("abcde"), 2, 1, "12345678901234567890", S("ab12345678901234567890de"))); - BOOST_TEST(testR(S("abcde"), 2, 2, "", S("abe"))); - BOOST_TEST(testR(S("abcde"), 2, 2, "12345", S("ab12345e"))); - BOOST_TEST(testR(S("abcde"), 2, 2, "1234567890", S("ab1234567890e"))); - BOOST_TEST(testR(S("abcde"), 2, 2, "12345678901234567890", S("ab12345678901234567890e"))); - BOOST_TEST(testR(S("abcde"), 2, 3, "", S("ab"))); - BOOST_TEST(testR(S("abcde"), 2, 3, "12345", S("ab12345"))); - BOOST_TEST(testR(S("abcde"), 2, 3, "1234567890", S("ab1234567890"))); - BOOST_TEST(testR(S("abcde"), 2, 3, "12345678901234567890", S("ab12345678901234567890"))); - BOOST_TEST(testR(S("abcde"), 4, 0, "", S("abcde"))); - BOOST_TEST(testR(S("abcde"), 4, 0, "12345", S("abcd12345e"))); - BOOST_TEST(testR(S("abcde"), 4, 0, "1234567890", S("abcd1234567890e"))); - BOOST_TEST(testR(S("abcde"), 4, 0, "12345678901234567890", S("abcd12345678901234567890e"))); - BOOST_TEST(testR(S("abcde"), 4, 1, "", S("abcd"))); - BOOST_TEST(testR(S("abcde"), 4, 1, "12345", S("abcd12345"))); - BOOST_TEST(testR(S("abcde"), 4, 1, "1234567890", S("abcd1234567890"))); - BOOST_TEST(testR(S("abcde"), 4, 1, "12345678901234567890", S("abcd12345678901234567890"))); - BOOST_TEST(testR(S("abcde"), 5, 0, "", S("abcde"))); - BOOST_TEST(testR(S("abcde"), 5, 0, "12345", S("abcde12345"))); - BOOST_TEST(testR(S("abcde"), 5, 0, "1234567890", S("abcde1234567890"))); - BOOST_TEST(testR(S("abcde"), 5, 0, "12345678901234567890", S("abcde12345678901234567890"))); - BOOST_TEST(testR(S("abcdefghij"), 0, 0, "", S("abcdefghij"))); - BOOST_TEST(testR(S("abcdefghij"), 0, 0, "12345", S("12345abcdefghij"))); - BOOST_TEST(testR(S("abcdefghij"), 0, 0, "1234567890", S("1234567890abcdefghij"))); - BOOST_TEST(testR(S("abcdefghij"), 0, 0, "12345678901234567890", S("12345678901234567890abcdefghij"))); - BOOST_TEST(testR(S("abcdefghij"), 0, 1, "", S("bcdefghij"))); - BOOST_TEST(testR(S("abcdefghij"), 0, 1, "12345", S("12345bcdefghij"))); - BOOST_TEST(testR(S("abcdefghij"), 0, 1, "1234567890", S("1234567890bcdefghij"))); - BOOST_TEST(testR(S("abcdefghij"), 0, 1, "12345678901234567890", S("12345678901234567890bcdefghij"))); - BOOST_TEST(testR(S("abcdefghij"), 0, 5, "", S("fghij"))); - BOOST_TEST(testR(S("abcdefghij"), 0, 5, "12345", S("12345fghij"))); - BOOST_TEST(testR(S("abcdefghij"), 0, 5, "1234567890", S("1234567890fghij"))); - BOOST_TEST(testR(S("abcdefghij"), 0, 5, "12345678901234567890", S("12345678901234567890fghij"))); - BOOST_TEST(testR(S("abcdefghij"), 0, 9, "", S("j"))); - BOOST_TEST(testR(S("abcdefghij"), 0, 9, "12345", S("12345j"))); - BOOST_TEST(testR(S("abcdefghij"), 0, 9, "1234567890", S("1234567890j"))); - BOOST_TEST(testR(S("abcdefghij"), 0, 9, "12345678901234567890", S("12345678901234567890j"))); - BOOST_TEST(testR(S("abcdefghij"), 0, 10, "", S(""))); - BOOST_TEST(testR(S("abcdefghij"), 0, 10, "12345", S("12345"))); - BOOST_TEST(testR(S("abcdefghij"), 0, 10, "1234567890", S("1234567890"))); - BOOST_TEST(testR(S("abcdefghij"), 0, 10, "12345678901234567890", S("12345678901234567890"))); - BOOST_TEST(testR(S("abcdefghij"), 1, 0, "", S("abcdefghij"))); - BOOST_TEST(testR(S("abcdefghij"), 1, 0, "12345", S("a12345bcdefghij"))); - BOOST_TEST(testR(S("abcdefghij"), 1, 0, "1234567890", S("a1234567890bcdefghij"))); - BOOST_TEST(testR(S("abcdefghij"), 1, 0, "12345678901234567890", S("a12345678901234567890bcdefghij"))); - BOOST_TEST(testR(S("abcdefghij"), 1, 1, "", S("acdefghij"))); - BOOST_TEST(testR(S("abcdefghij"), 1, 1, "12345", S("a12345cdefghij"))); - BOOST_TEST(testR(S("abcdefghij"), 1, 1, "1234567890", S("a1234567890cdefghij"))); - BOOST_TEST(testR(S("abcdefghij"), 1, 1, "12345678901234567890", S("a12345678901234567890cdefghij"))); - BOOST_TEST(testR(S(""), 0, 0, 0, '2', S(""))); - BOOST_TEST(testR(S(""), 0, 0, 5, '2', S("22222"))); - BOOST_TEST(testR(S(""), 0, 0, 10, '2', S("2222222222"))); - BOOST_TEST(testR(S(""), 0, 0, 20, '2', S("22222222222222222222"))); - BOOST_TEST(testR(S(""), 0, 1, 0, '2', S(""))); - BOOST_TEST(testR(S(""), 0, 1, 5, '2', S("22222"))); - BOOST_TEST(testR(S(""), 0, 1, 10, '2', S("2222222222"))); - BOOST_TEST(testR(S(""), 0, 1, 20, '2', S("22222222222222222222"))); - BOOST_TEST(testR(S("abcde"), 0, 0, 0, '2', S("abcde"))); - BOOST_TEST(testR(S("abcde"), 0, 0, 5, '2', S("22222abcde"))); - BOOST_TEST(testR(S("abcde"), 0, 0, 10, '2', S("2222222222abcde"))); - BOOST_TEST(testR(S("abcde"), 0, 0, 20, '2', S("22222222222222222222abcde"))); - BOOST_TEST(testR(S("abcde"), 0, 1, 0, '2', S("bcde"))); - BOOST_TEST(testR(S("abcde"), 0, 1, 5, '2', S("22222bcde"))); - BOOST_TEST(testR(S("abcde"), 0, 1, 10, '2', S("2222222222bcde"))); - BOOST_TEST(testR(S("abcde"), 0, 1, 20, '2', S("22222222222222222222bcde"))); - BOOST_TEST(testR(S("abcde"), 0, 2, 0, '2', S("cde"))); - BOOST_TEST(testR(S("abcde"), 0, 2, 5, '2', S("22222cde"))); - BOOST_TEST(testR(S("abcde"), 0, 2, 10, '2', S("2222222222cde"))); - BOOST_TEST(testR(S("abcde"), 0, 2, 20, '2', S("22222222222222222222cde"))); - BOOST_TEST(testR(S("abcde"), 0, 4, 0, '2', S("e"))); - BOOST_TEST(testR(S("abcde"), 0, 4, 5, '2', S("22222e"))); - BOOST_TEST(testR(S("abcde"), 0, 4, 10, '2', S("2222222222e"))); - BOOST_TEST(testR(S("abcde"), 0, 4, 20, '2', S("22222222222222222222e"))); - BOOST_TEST(testR(S("abcde"), 0, 5, 0, '2', S(""))); - BOOST_TEST(testR(S("abcde"), 0, 5, 5, '2', S("22222"))); - BOOST_TEST(testR(S("abcde"), 0, 5, 10, '2', S("2222222222"))); - BOOST_TEST(testR(S("abcde"), 0, 5, 20, '2', S("22222222222222222222"))); - BOOST_TEST(testR(S("abcde"), 0, 6, 0, '2', S(""))); - BOOST_TEST(testR(S("abcde"), 0, 6, 5, '2', S("22222"))); - BOOST_TEST(testR(S("abcde"), 0, 6, 10, '2', S("2222222222"))); - BOOST_TEST(testR(S("abcde"), 0, 6, 20, '2', S("22222222222222222222"))); - BOOST_TEST(testR(S("abcde"), 1, 0, 0, '2', S("abcde"))); - BOOST_TEST(testR(S("abcde"), 1, 0, 5, '2', S("a22222bcde"))); - BOOST_TEST(testR(S("abcde"), 1, 0, 10, '2', S("a2222222222bcde"))); - BOOST_TEST(testR(S("abcde"), 1, 0, 20, '2', S("a22222222222222222222bcde"))); - BOOST_TEST(testR(S("abcde"), 1, 1, 0, '2', S("acde"))); - BOOST_TEST(testR(S("abcde"), 1, 1, 5, '2', S("a22222cde"))); - BOOST_TEST(testR(S("abcde"), 1, 1, 10, '2', S("a2222222222cde"))); - BOOST_TEST(testR(S("abcde"), 1, 1, 20, '2', S("a22222222222222222222cde"))); - BOOST_TEST(testR(S("abcde"), 1, 2, 0, '2', S("ade"))); - BOOST_TEST(testR(S("abcde"), 1, 2, 5, '2', S("a22222de"))); - BOOST_TEST(testR(S("abcde"), 1, 2, 10, '2', S("a2222222222de"))); - BOOST_TEST(testR(S("abcde"), 1, 2, 20, '2', S("a22222222222222222222de"))); - BOOST_TEST(testR(S("abcde"), 1, 3, 0, '2', S("ae"))); - BOOST_TEST(testR(S("abcde"), 1, 3, 5, '2', S("a22222e"))); - BOOST_TEST(testR(S("abcde"), 1, 3, 10, '2', S("a2222222222e"))); - BOOST_TEST(testR(S("abcde"), 1, 3, 20, '2', S("a22222222222222222222e"))); - BOOST_TEST(testR(S("abcde"), 1, 4, 0, '2', S("a"))); - BOOST_TEST(testR(S("abcde"), 1, 4, 5, '2', S("a22222"))); - BOOST_TEST(testR(S("abcde"), 1, 4, 10, '2', S("a2222222222"))); - BOOST_TEST(testR(S("abcde"), 1, 4, 20, '2', S("a22222222222222222222"))); - BOOST_TEST(testR(S("abcde"), 1, 5, 0, '2', S("a"))); - BOOST_TEST(testR(S("abcde"), 1, 5, 5, '2', S("a22222"))); - BOOST_TEST(testR(S("abcde"), 1, 5, 10, '2', S("a2222222222"))); - BOOST_TEST(testR(S("abcde"), 1, 5, 20, '2', S("a22222222222222222222"))); - BOOST_TEST(testR(S("abcde"), 2, 0, 0, '2', S("abcde"))); - BOOST_TEST(testR(S("abcde"), 2, 0, 5, '2', S("ab22222cde"))); - BOOST_TEST(testR(S("abcde"), 2, 0, 10, '2', S("ab2222222222cde"))); - BOOST_TEST(testR(S("abcde"), 2, 0, 20, '2', S("ab22222222222222222222cde"))); - BOOST_TEST(testR(S("abcde"), 2, 1, 0, '2', S("abde"))); - BOOST_TEST(testR(S("abcde"), 2, 1, 5, '2', S("ab22222de"))); - BOOST_TEST(testR(S("abcde"), 2, 1, 10, '2', S("ab2222222222de"))); - BOOST_TEST(testR(S("abcde"), 2, 1, 20, '2', S("ab22222222222222222222de"))); - BOOST_TEST(testR(S("abcde"), 2, 2, 0, '2', S("abe"))); - BOOST_TEST(testR(S("abcde"), 2, 2, 5, '2', S("ab22222e"))); - BOOST_TEST(testR(S("abcde"), 2, 2, 10, '2', S("ab2222222222e"))); - BOOST_TEST(testR(S("abcde"), 2, 2, 20, '2', S("ab22222222222222222222e"))); - BOOST_TEST(testR(S("abcde"), 2, 3, 0, '2', S("ab"))); - BOOST_TEST(testR(S("abcde"), 2, 3, 5, '2', S("ab22222"))); - BOOST_TEST(testR(S("abcde"), 2, 3, 10, '2', S("ab2222222222"))); - BOOST_TEST(testR(S("abcde"), 2, 3, 20, '2', S("ab22222222222222222222"))); - BOOST_TEST(testR(S("abcde"), 2, 4, 0, '2', S("ab"))); - BOOST_TEST(testR(S("abcde"), 2, 4, 5, '2', S("ab22222"))); - BOOST_TEST(testR(S("abcde"), 2, 4, 10, '2', S("ab2222222222"))); - BOOST_TEST(testR(S("abcde"), 2, 4, 20, '2', S("ab22222222222222222222"))); - BOOST_TEST(testR(S("abcde"), 4, 0, 0, '2', S("abcde"))); - BOOST_TEST(testR(S("abcde"), 4, 0, 5, '2', S("abcd22222e"))); - BOOST_TEST(testR(S("abcde"), 4, 0, 10, '2', S("abcd2222222222e"))); - BOOST_TEST(testR(S("abcde"), 4, 0, 20, '2', S("abcd22222222222222222222e"))); - BOOST_TEST(testR(S("abcde"), 4, 1, 0, '2', S("abcd"))); - BOOST_TEST(testR(S("abcde"), 4, 1, 5, '2', S("abcd22222"))); - BOOST_TEST(testR(S("abcde"), 4, 1, 10, '2', S("abcd2222222222"))); - BOOST_TEST(testR(S("abcde"), 4, 1, 20, '2', S("abcd22222222222222222222"))); - BOOST_TEST(testR(S("abcde"), 4, 2, 0, '2', S("abcd"))); - - BOOST_TEST(testR(S("abcde"), 4, 2, 5, '2', S("abcd22222"))); - BOOST_TEST(testR(S("abcde"), 4, 2, 10, '2', S("abcd2222222222"))); - BOOST_TEST(testR(S("abcde"), 4, 2, 20, '2', S("abcd22222222222222222222"))); - - BOOST_TEST(testR(S("abcde"), 5, 0, 0, '2', S("abcde"))); - BOOST_TEST(testR(S("abcde"), 5, 0, 5, '2', S("abcde22222"))); - BOOST_TEST(testR(S("abcde"), 5, 0, 10, '2', S("abcde2222222222"))); - BOOST_TEST(testR(S("abcde"), 5, 0, 20, '2', S("abcde22222222222222222222"))); - - BOOST_TEST(testR(S("abcde"), 5, 1, 0, '2', S("abcde"))); - BOOST_TEST(testR(S("abcde"), 5, 1, 5, '2', S("abcde22222"))); - BOOST_TEST(testR(S("abcde"), 5, 1, 10, '2', S("abcde2222222222"))); - BOOST_TEST(testR(S("abcde"), 5, 1, 20, '2', S("abcde22222222222222222222"))); - - BOOST_TEST(testR(S("abcde"), 0, 4, "12345", 4, S("1234e"))); - BOOST_TEST(testR(S("abcde"), 0, 4, "12345", 5, S("12345e"))); - BOOST_TEST(testR(S("abcde"), 0, 4, "1234567890", 0, S("e"))); - BOOST_TEST(testR(S("abcde"), 0, 4, "1234567890", 1, S("1e"))); - BOOST_TEST(testR(S("abcde"), 0, 4, "1234567890", 5, S("12345e"))); - BOOST_TEST(testR(S("abcde"), 0, 4, "1234567890", 9, S("123456789e"))); - BOOST_TEST(testR(S("abcde"), 0, 4, "1234567890", 10, S("1234567890e"))); - BOOST_TEST(testR(S("abcde"), 0, 4, "12345678901234567890", 0, S("e"))); - BOOST_TEST(testR(S("abcde"), 0, 4, "12345678901234567890", 1, S("1e"))); - BOOST_TEST(testR(S("abcde"), 0, 4, "12345678901234567890", 10, S("1234567890e"))); - BOOST_TEST(testR(S("abcde"), 0, 4, "12345678901234567890", 19, S("1234567890123456789e"))); - BOOST_TEST(testR(S("abcde"), 0, 4, "12345678901234567890", 20, S("12345678901234567890e"))); - BOOST_TEST(testR(S("abcde"), 0, 5, "", 0, S(""))); - BOOST_TEST(testR(S("abcde"), 0, 5, "12345", 0, S(""))); - BOOST_TEST(testR(S("abcde"), 0, 5, "12345", 1, S("1"))); - BOOST_TEST(testR(S("abcde"), 0, 5, "12345", 2, S("12"))); - BOOST_TEST(testR(S("abcde"), 0, 5, "12345", 4, S("1234"))); - BOOST_TEST(testR(S("abcde"), 0, 5, "12345", 5, S("12345"))); - BOOST_TEST(testR(S("abcde"), 0, 5, "1234567890", 0, S(""))); - BOOST_TEST(testR(S("abcde"), 0, 5, "1234567890", 1, S("1"))); - BOOST_TEST(testR(S("abcde"), 0, 5, "1234567890", 5, S("12345"))); - BOOST_TEST(testR(S("abcde"), 0, 5, "1234567890", 9, S("123456789"))); - BOOST_TEST(testR(S("abcde"), 0, 5, "1234567890", 10, S("1234567890"))); - BOOST_TEST(testR(S("abcde"), 0, 5, "12345678901234567890", 0, S(""))); - BOOST_TEST(testR(S("abcde"), 0, 5, "12345678901234567890", 1, S("1"))); - BOOST_TEST(testR(S("abcde"), 0, 5, "12345678901234567890", 10, S("1234567890"))); - BOOST_TEST(testR(S("abcde"), 0, 5, "12345678901234567890", 19, S("1234567890123456789"))); - BOOST_TEST(testR(S("abcde"), 0, 5, "12345678901234567890", 20, S("12345678901234567890"))); - BOOST_TEST(testR(S("abcde"), 0, 6, "", 0, S(""))); - BOOST_TEST(testR(S("abcde"), 0, 6, "12345", 0, S(""))); - BOOST_TEST(testR(S("abcde"), 0, 6, "12345", 1, S("1"))); - BOOST_TEST(testR(S("abcde"), 0, 6, "12345", 2, S("12"))); - BOOST_TEST(testR(S("abcde"), 0, 6, "12345", 4, S("1234"))); - BOOST_TEST(testR(S("abcde"), 0, 6, "12345", 5, S("12345"))); - BOOST_TEST(testR(S("abcde"), 0, 6, "1234567890", 0, S(""))); - BOOST_TEST(testR(S("abcde"), 0, 6, "1234567890", 1, S("1"))); - BOOST_TEST(testR(S("abcde"), 0, 6, "1234567890", 5, S("12345"))); - BOOST_TEST(testR(S("abcde"), 0, 6, "1234567890", 9, S("123456789"))); - BOOST_TEST(testR(S("abcde"), 0, 6, "1234567890", 10, S("1234567890"))); - BOOST_TEST(testR(S("abcde"), 0, 6, "12345678901234567890", 0, S(""))); - BOOST_TEST(testR(S("abcde"), 0, 6, "12345678901234567890", 1, S("1"))); - BOOST_TEST(testR(S("abcde"), 0, 6, "12345678901234567890", 10, S("1234567890"))); - BOOST_TEST(testR(S("abcde"), 0, 6, "12345678901234567890", 19, S("1234567890123456789"))); - BOOST_TEST(testR(S("abcde"), 0, 6, "12345678901234567890", 20, S("12345678901234567890"))); - BOOST_TEST(testR(S("abcde"), 1, 0, "", 0, S("abcde"))); - BOOST_TEST(testR(S("abcde"), 1, 0, "12345", 0, S("abcde"))); - BOOST_TEST(testR(S("abcde"), 1, 0, "12345", 1, S("a1bcde"))); - BOOST_TEST(testR(S("abcde"), 1, 0, "12345", 2, S("a12bcde"))); - BOOST_TEST(testR(S("abcde"), 1, 0, "12345", 4, S("a1234bcde"))); - BOOST_TEST(testR(S("abcde"), 1, 0, "12345", 5, S("a12345bcde"))); - BOOST_TEST(testR(S("abcde"), 1, 0, "1234567890", 0, S("abcde"))); - BOOST_TEST(testR(S("abcde"), 1, 0, "1234567890", 1, S("a1bcde"))); - BOOST_TEST(testR(S("abcde"), 1, 0, "1234567890", 5, S("a12345bcde"))); - BOOST_TEST(testR(S("abcde"), 1, 0, "1234567890", 9, S("a123456789bcde"))); - BOOST_TEST(testR(S("abcde"), 1, 0, "1234567890", 10, S("a1234567890bcde"))); - BOOST_TEST(testR(S("abcde"), 1, 0, "12345678901234567890", 0, S("abcde"))); - BOOST_TEST(testR(S("abcde"), 1, 0, "12345678901234567890", 1, S("a1bcde"))); - BOOST_TEST(testR(S("abcde"), 1, 0, "12345678901234567890", 10, S("a1234567890bcde"))); - BOOST_TEST(testR(S("abcde"), 1, 0, "12345678901234567890", 19, S("a1234567890123456789bcde"))); - BOOST_TEST(testR(S("abcde"), 1, 0, "12345678901234567890", 20, S("a12345678901234567890bcde"))); - BOOST_TEST(testR(S("abcde"), 1, 1, "", 0, S("acde"))); - BOOST_TEST(testR(S("abcde"), 1, 1, "12345", 0, S("acde"))); - BOOST_TEST(testR(S("abcde"), 1, 1, "12345", 1, S("a1cde"))); - BOOST_TEST(testR(S("abcde"), 1, 1, "12345", 2, S("a12cde"))); - BOOST_TEST(testR(S("abcde"), 1, 1, "12345", 4, S("a1234cde"))); - BOOST_TEST(testR(S("abcde"), 1, 1, "12345", 5, S("a12345cde"))); - BOOST_TEST(testR(S("abcde"), 1, 1, "1234567890", 0, S("acde"))); - BOOST_TEST(testR(S("abcde"), 1, 1, "1234567890", 1, S("a1cde"))); - BOOST_TEST(testR(S("abcde"), 1, 1, "1234567890", 5, S("a12345cde"))); - BOOST_TEST(testR(S("abcde"), 1, 1, "1234567890", 9, S("a123456789cde"))); - BOOST_TEST(testR(S("abcde"), 1, 1, "1234567890", 10, S("a1234567890cde"))); - BOOST_TEST(testR(S("abcde"), 1, 1, "12345678901234567890", 0, S("acde"))); - BOOST_TEST(testR(S("abcde"), 1, 1, "12345678901234567890", 1, S("a1cde"))); - BOOST_TEST(testR(S("abcde"), 1, 1, "12345678901234567890", 10, S("a1234567890cde"))); - BOOST_TEST(testR(S("abcde"), 1, 1, "12345678901234567890", 19, S("a1234567890123456789cde"))); - BOOST_TEST(testR(S("abcde"), 1, 1, "12345678901234567890", 20, S("a12345678901234567890cde"))); - BOOST_TEST(testR(S("abcde"), 1, 2, "", 0, S("ade"))); - BOOST_TEST(testR(S("abcde"), 1, 2, "12345", 0, S("ade"))); - BOOST_TEST(testR(S("abcde"), 1, 2, "12345", 1, S("a1de"))); - BOOST_TEST(testR(S("abcde"), 1, 2, "12345", 2, S("a12de"))); - BOOST_TEST(testR(S("abcde"), 1, 2, "12345", 4, S("a1234de"))); - BOOST_TEST(testR(S("abcde"), 1, 2, "12345", 5, S("a12345de"))); - BOOST_TEST(testR(S("abcde"), 1, 2, "1234567890", 0, S("ade"))); - BOOST_TEST(testR(S("abcde"), 1, 2, "1234567890", 1, S("a1de"))); - BOOST_TEST(testR(S("abcde"), 1, 2, "1234567890", 5, S("a12345de"))); - BOOST_TEST(testR(S("abcde"), 1, 2, "1234567890", 9, S("a123456789de"))); - BOOST_TEST(testR(S("abcde"), 1, 2, "1234567890", 10, S("a1234567890de"))); - BOOST_TEST(testR(S("abcde"), 1, 2, "12345678901234567890", 0, S("ade"))); - BOOST_TEST(testR(S("abcde"), 1, 2, "12345678901234567890", 1, S("a1de"))); - BOOST_TEST(testR(S("abcde"), 1, 2, "12345678901234567890", 10, S("a1234567890de"))); - BOOST_TEST(testR(S("abcde"), 1, 2, "12345678901234567890", 19, S("a1234567890123456789de"))); - BOOST_TEST(testR(S("abcde"), 1, 2, "12345678901234567890", 20, S("a12345678901234567890de"))); - BOOST_TEST(testR(S("abcde"), 1, 3, "", 0, S("ae"))); - BOOST_TEST(testR(S("abcde"), 1, 3, "12345", 0, S("ae"))); - BOOST_TEST(testR(S("abcde"), 1, 3, "12345", 1, S("a1e"))); - BOOST_TEST(testR(S("abcde"), 1, 3, "12345", 2, S("a12e"))); - BOOST_TEST(testR(S("abcde"), 1, 3, "12345", 4, S("a1234e"))); - BOOST_TEST(testR(S("abcde"), 1, 3, "12345", 5, S("a12345e"))); - BOOST_TEST(testR(S("abcde"), 1, 3, "1234567890", 0, S("ae"))); - BOOST_TEST(testR(S("abcde"), 1, 3, "1234567890", 1, S("a1e"))); - BOOST_TEST(testR(S("abcdefghij"), 1, 10, "1234567890", 5, S("a12345"))); - BOOST_TEST(testR(S("abcdefghij"), 1, 10, "1234567890", 9, S("a123456789"))); - BOOST_TEST(testR(S("abcdefghij"), 1, 10, "1234567890", 10, S("a1234567890"))); - BOOST_TEST(testR(S("abcdefghij"), 1, 10, "12345678901234567890", 0, S("a"))); - BOOST_TEST(testR(S("abcdefghij"), 1, 10, "12345678901234567890", 1, S("a1"))); - BOOST_TEST(testR(S("abcdefghij"), 1, 10, "12345678901234567890", 10, S("a1234567890"))); - BOOST_TEST(testR(S("abcdefghij"), 1, 10, "12345678901234567890", 19, S("a1234567890123456789"))); - BOOST_TEST(testR(S("abcdefghij"), 1, 10, "12345678901234567890", 20, S("a12345678901234567890"))); - BOOST_TEST(testR(S("abcdefghij"), 5, 0, "", 0, S("abcdefghij"))); - BOOST_TEST(testR(S("abcdefghij"), 5, 0, "12345", 0, S("abcdefghij"))); - BOOST_TEST(testR(S("abcdefghij"), 5, 0, "12345", 1, S("abcde1fghij"))); - BOOST_TEST(testR(S("abcdefghij"), 5, 0, "12345", 2, S("abcde12fghij"))); - BOOST_TEST(testR(S("abcdefghij"), 5, 0, "12345", 4, S("abcde1234fghij"))); - BOOST_TEST(testR(S("abcdefghij"), 5, 0, "12345", 5, S("abcde12345fghij"))); - BOOST_TEST(testR(S("abcdefghij"), 5, 0, "1234567890", 0, S("abcdefghij"))); - BOOST_TEST(testR(S("abcdefghij"), 5, 0, "1234567890", 1, S("abcde1fghij"))); - BOOST_TEST(testR(S("abcdefghij"), 5, 0, "1234567890", 5, S("abcde12345fghij"))); - BOOST_TEST(testR(S("abcdefghij"), 5, 0, "1234567890", 9, S("abcde123456789fghij"))); - BOOST_TEST(testR(S("abcdefghij"), 5, 0, "1234567890", 10, S("abcde1234567890fghij"))); - BOOST_TEST(testR(S("abcdefghij"), 5, 0, "12345678901234567890", 0, S("abcdefghij"))); - BOOST_TEST(testR(S("abcdefghij"), 5, 0, "12345678901234567890", 1, S("abcde1fghij"))); - BOOST_TEST(testR(S("abcdefghij"), 5, 0, "12345678901234567890", 10, S("abcde1234567890fghij"))); - BOOST_TEST(testR(S("abcdefghij"), 5, 0, "12345678901234567890", 19, S("abcde1234567890123456789fghij"))); - BOOST_TEST(testR(S("abcdefghij"), 5, 0, "12345678901234567890", 20, S("abcde12345678901234567890fghij"))); - BOOST_TEST(testR(S("abcdefghij"), 5, 1, "", 0, S("abcdeghij"))); - BOOST_TEST(testR(S("abcdefghij"), 5, 1, "12345", 0, S("abcdeghij"))); - BOOST_TEST(testR(S("abcdefghij"), 5, 1, "12345", 1, S("abcde1ghij"))); - BOOST_TEST(testR(S("abcdefghij"), 5, 1, "12345", 2, S("abcde12ghij"))); - BOOST_TEST(testR(S("abcdefghij"), 5, 1, "12345", 4, S("abcde1234ghij"))); - BOOST_TEST(testR(S("abcdefghij"), 5, 1, "12345", 5, S("abcde12345ghij"))); - BOOST_TEST(testR(S("abcdefghij"), 5, 1, "1234567890", 0, S("abcdeghij"))); - BOOST_TEST(testR(S("abcdefghij"), 5, 1, "1234567890", 1, S("abcde1ghij"))); - BOOST_TEST(testR(S("abcdefghij"), 5, 1, "1234567890", 5, S("abcde12345ghij"))); - BOOST_TEST(testR(S("abcdefghij"), 5, 1, "1234567890", 9, S("abcde123456789ghij"))); - BOOST_TEST(testR(S("abcdefghij"), 5, 1, "1234567890", 10, S("abcde1234567890ghij"))); - BOOST_TEST(testR(S("abcdefghij"), 5, 1, "12345678901234567890", 0, S("abcdeghij"))); - BOOST_TEST(testR(S("abcdefghij"), 5, 1, "12345678901234567890", 1, S("abcde1ghij"))); - BOOST_TEST(testR(S("abcdefghij"), 5, 1, "12345678901234567890", 10, S("abcde1234567890ghij"))); - BOOST_TEST(testR(S("abcdefghij"), 5, 1, "12345678901234567890", 19, S("abcde1234567890123456789ghij"))); - BOOST_TEST(testR(S("abcdefghij"), 5, 1, "12345678901234567890", 20, S("abcde12345678901234567890ghij"))); - BOOST_TEST(testR(S("abcdefghij"), 5, 2, "", 0, S("abcdehij"))); - BOOST_TEST(testR(S("abcdefghij"), 5, 2, "12345", 0, S("abcdehij"))); - BOOST_TEST(testR(S("abcdefghij"), 5, 2, "12345", 1, S("abcde1hij"))); - BOOST_TEST(testR(S("abcdefghij"), 5, 2, "12345", 2, S("abcde12hij"))); - BOOST_TEST(testR(S("abcdefghij"), 5, 2, "12345", 4, S("abcde1234hij"))); - BOOST_TEST(testR(S("abcdefghij"), 5, 2, "12345", 5, S("abcde12345hij"))); - BOOST_TEST(testR(S("abcdefghij"), 5, 2, "1234567890", 0, S("abcdehij"))); - BOOST_TEST(testR(S("abcdefghij"), 5, 2, "1234567890", 1, S("abcde1hij"))); - BOOST_TEST(testR(S("abcdefghij"), 5, 2, "1234567890", 5, S("abcde12345hij"))); - BOOST_TEST(testR(S("abcdefghij"), 5, 2, "1234567890", 9, S("abcde123456789hij"))); - BOOST_TEST(testR(S("abcdefghij"), 5, 2, "1234567890", 10, S("abcde1234567890hij"))); - BOOST_TEST(testR(S("abcdefghij"), 5, 2, "12345678901234567890", 0, S("abcdehij"))); - BOOST_TEST(testR(S("abcdefghij"), 5, 2, "12345678901234567890", 1, S("abcde1hij"))); - BOOST_TEST(testR(S("abcdefghij"), 5, 2, "12345678901234567890", 10, S("abcde1234567890hij"))); - BOOST_TEST(testR(S("abcdefghij"), 5, 2, "12345678901234567890", 19, S("abcde1234567890123456789hij"))); - BOOST_TEST(testR(S("abcdefghij"), 5, 2, "12345678901234567890", 20, S("abcde12345678901234567890hij"))); - BOOST_TEST(testR(S("abcdefghij"), 5, 4, "", 0, S("abcdej"))); - BOOST_TEST(testR(S("abcdefghij"), 5, 4, "12345", 0, S("abcdej"))); - BOOST_TEST(testR(S("abcdefghij"), 5, 4, "12345", 1, S("abcde1j"))); - BOOST_TEST(testR(S("abcdefghij"), 5, 4, "12345", 2, S("abcde12j"))); - BOOST_TEST(testR(S("abcdefghij"), 5, 4, "12345", 4, S("abcde1234j"))); - BOOST_TEST(testR(S("abcdefghij"), 5, 4, "12345", 5, S("abcde12345j"))); - BOOST_TEST(testR(S("abcdefghij"), 5, 4, "1234567890", 0, S("abcdej"))); - BOOST_TEST(testR(S("abcdefghij"), 5, 4, "1234567890", 1, S("abcde1j"))); - BOOST_TEST(testR(S("abcdefghij"), 5, 4, "1234567890", 5, S("abcde12345j"))); - BOOST_TEST(testR(S("abcdefghij"), 5, 4, "1234567890", 9, S("abcde123456789j"))); - BOOST_TEST(testR(S("abcdefghij"), 5, 4, "1234567890", 10, S("abcde1234567890j"))); - BOOST_TEST(testR(S("abcdefghij"), 5, 4, "12345678901234567890", 0, S("abcdej"))); - BOOST_TEST(testR(S("abcdefghij"), 5, 4, "12345678901234567890", 1, S("abcde1j"))); - BOOST_TEST(testR(S("abcdefghij"), 5, 4, "12345678901234567890", 10, S("abcde1234567890j"))); - BOOST_TEST(testR(S("abcdefghij"), 5, 4, "12345678901234567890", 19, S("abcde1234567890123456789j"))); - BOOST_TEST(testR(S("abcdefghij"), 5, 4, "12345678901234567890", 20, S("abcde12345678901234567890j"))); - BOOST_TEST(testR(S("abcdefghij"), 5, 5, "", 0, S("abcde"))); - BOOST_TEST(testR(S("abcdefghij"), 5, 5, "12345", 0, S("abcde"))); - BOOST_TEST(testR(S("abcdefghij"), 5, 5, "12345", 1, S("abcde1"))); - BOOST_TEST(testR(S("abcdefghij"), 5, 5, "12345", 2, S("abcde12"))); - BOOST_TEST(testR(S("abcdefghij"), 5, 5, "12345", 4, S("abcde1234"))); - BOOST_TEST(testR(S("abcdefghij"), 5, 5, "12345", 5, S("abcde12345"))); - BOOST_TEST(testR(S("abcdefghij"), 5, 5, "1234567890", 0, S("abcde"))); - BOOST_TEST(testR(S("abcdefghij"), 5, 5, "1234567890", 1, S("abcde1"))); - BOOST_TEST(testR(S("abcdefghij"), 5, 5, "1234567890", 5, S("abcde12345"))); - BOOST_TEST(testR(S("abcdefghij"), 5, 5, "1234567890", 9, S("abcde123456789"))); - BOOST_TEST(testR(S("abcdefghij"), 5, 5, "1234567890", 10, S("abcde1234567890"))); - BOOST_TEST(testR(S("abcdefghij"), 5, 5, "12345678901234567890", 0, S("abcde"))); - BOOST_TEST(testR(S("abcdefghij"), 5, 5, "12345678901234567890", 1, S("abcde1"))); - BOOST_TEST(testR(S("abcdefghij"), 5, 5, "12345678901234567890", 10, S("abcde1234567890"))); - BOOST_TEST(testR(S("abcdefghij"), 5, 5, "12345678901234567890", 19, S("abcde1234567890123456789"))); - BOOST_TEST(testR(S("abcdefghij"), 5, 5, "12345678901234567890", 20, S("abcde12345678901234567890"))); - BOOST_TEST(testR(S("abcdefghij"), 5, 6, "", 0, S("abcde"))); - BOOST_TEST(testR(S("abcdefghij"), 5, 6, "12345", 0, S("abcde"))); - BOOST_TEST(testR(S("abcdefghij"), 5, 6, "12345", 1, S("abcde1"))); - BOOST_TEST(testR(S("abcdefghij"), 5, 6, "12345", 2, S("abcde12"))); - BOOST_TEST(testR(S("abcdefghij"), 5, 6, "12345", 4, S("abcde1234"))); - BOOST_TEST(testR(S("abcdefghij"), 5, 6, "12345", 5, S("abcde12345"))); - BOOST_TEST(testR(S("abcdefghij"), 5, 6, "1234567890", 0, S("abcde"))); - BOOST_TEST(testR(S("abcdefghij"), 5, 6, "1234567890", 1, S("abcde1"))); - BOOST_TEST(testR(S("abcdefghij"), 5, 6, "1234567890", 5, S("abcde12345"))); - BOOST_TEST(testR(S("abcdefghij"), 5, 6, "1234567890", 9, S("abcde123456789"))); - BOOST_TEST(testR(S("abcdefghij"), 5, 6, "1234567890", 10, S("abcde1234567890"))); - BOOST_TEST(testR(S("abcdefghij"), 5, 6, "12345678901234567890", 0, S("abcde"))); - BOOST_TEST(testR(S("abcdefghijklmnopqrst"), 0, 0, "", 0, S("abcdefghijklmnopqrst"))); - BOOST_TEST(testR(S("abcdefghijklmnopqrst"), 0, 0, "12345", 0, S("abcdefghijklmnopqrst"))); - BOOST_TEST(testR(S("abcdefghijklmnopqrst"), 0, 0, "12345", 1, S("1abcdefghijklmnopqrst"))); - BOOST_TEST(testR(S("abcdefghijklmnopqrst"), 0, 0, "12345", 2, S("12abcdefghijklmnopqrst"))); - BOOST_TEST(testR(S("abcdefghijklmnopqrst"), 0, 0, "12345", 4, S("1234abcdefghijklmnopqrst"))); - BOOST_TEST(testR(S("abcdefghijklmnopqrst"), 0, 0, "12345", 5, S("12345abcdefghijklmnopqrst"))); - BOOST_TEST(testR(S("abcdefghijklmnopqrst"), 0, 0, "1234567890", 0, S("abcdefghijklmnopqrst"))); - BOOST_TEST(testR(S("abcdefghijklmnopqrst"), 0, 0, "1234567890", 1, S("1abcdefghijklmnopqrst"))); - BOOST_TEST(testR(S("abcdefghijklmnopqrst"), 0, 0, "1234567890", 5, S("12345abcdefghijklmnopqrst"))); - BOOST_TEST(testR(S("abcdefghijklmnopqrst"), 0, 0, "1234567890", 9, S("123456789abcdefghijklmnopqrst"))); - BOOST_TEST(testR(S("abcdefghijklmnopqrst"), 0, 0, "1234567890", 10, S("1234567890abcdefghijklmnopqrst"))); - BOOST_TEST(testR(S("abcdefghijklmnopqrst"), 0, 0, "12345678901234567890", 0, S("abcdefghijklmnopqrst"))); - BOOST_TEST(testR(S("abcdefghijklmnopqrst"), 0, 0, "12345678901234567890", 1, S("1abcdefghijklmnopqrst"))); - BOOST_TEST(testR(S("abcdefghijklmnopqrst"), 0, 0, "12345678901234567890", 10, S("1234567890abcdefghijklmnopqrst"))); - BOOST_TEST(testR(S("abcdefghijklmnopqrst"), 0, 0, "12345678901234567890", 19, S("1234567890123456789abcdefghijklmnopqrst"))); - BOOST_TEST(testR(S("abcdefghijklmnopqrst"), 0, 0, "12345678901234567890", 20, S("12345678901234567890abcdefghijklmnopqrst"))); - BOOST_TEST(testR(S("abcdefghijklmnopqrst"), 0, 1, "", 0, S("bcdefghijklmnopqrst"))); - BOOST_TEST(testR(S("abcdefghijklmnopqrst"), 0, 1, "12345", 0, S("bcdefghijklmnopqrst"))); - BOOST_TEST(testR(S("abcdefghijklmnopqrst"), 0, 1, "12345", 1, S("1bcdefghijklmnopqrst"))); - BOOST_TEST(testR(S("abcdefghijklmnopqrst"), 0, 1, "12345", 2, S("12bcdefghijklmnopqrst"))); - BOOST_TEST(testR(S("abcdefghijklmnopqrst"), 0, 1, "12345", 4, S("1234bcdefghijklmnopqrst"))); - BOOST_TEST(testR(S("abcdefghijklmnopqrst"), 0, 1, "12345", 5, S("12345bcdefghijklmnopqrst"))); - BOOST_TEST(testR(S("abcdefghijklmnopqrst"), 0, 1, "1234567890", 0, S("bcdefghijklmnopqrst"))); - BOOST_TEST(testR(S("abcdefghijklmnopqrst"), 0, 1, "1234567890", 1, S("1bcdefghijklmnopqrst"))); - BOOST_TEST(testR(S("abcdefghijklmnopqrst"), 0, 1, "1234567890", 5, S("12345bcdefghijklmnopqrst"))); - BOOST_TEST(testR(S("abcdefghijklmnopqrst"), 0, 1, "1234567890", 9, S("123456789bcdefghijklmnopqrst"))); - BOOST_TEST(testR(S("abcdefghijklmnopqrst"), 0, 1, "1234567890", 10, S("1234567890bcdefghijklmnopqrst"))); - BOOST_TEST(testR(S("abcdefghijklmnopqrst"), 0, 1, "12345678901234567890", 0, S("bcdefghijklmnopqrst"))); - BOOST_TEST(testR(S("abcdefghijklmnopqrst"), 0, 1, "12345678901234567890", 1, S("1bcdefghijklmnopqrst"))); - BOOST_TEST(testR(S("abcdefghijklmnopqrst"), 0, 1, "12345678901234567890", 10, S("1234567890bcdefghijklmnopqrst"))); - BOOST_TEST(testR(S("abcdefghijklmnopqrst"), 0, 1, "12345678901234567890", 19, S("1234567890123456789bcdefghijklmnopqrst"))); - BOOST_TEST(testR(S("abcdefghijklmnopqrst"), 0, 1, "12345678901234567890", 20, S("12345678901234567890bcdefghijklmnopqrst"))); - BOOST_TEST(testR(S("abcdefghijklmnopqrst"), 0, 10, "", 0, S("klmnopqrst"))); - BOOST_TEST(testR(S("abcdefghijklmnopqrst"), 0, 10, "12345", 0, S("klmnopqrst"))); - BOOST_TEST(testR(S("abcdefghijklmnopqrst"), 0, 10, "12345", 1, S("1klmnopqrst"))); - BOOST_TEST(testR(S("abcdefghijklmnopqrst"), 0, 10, "12345", 2, S("12klmnopqrst"))); - BOOST_TEST(testR(S("abcdefghijklmnopqrst"), 0, 10, "12345", 4, S("1234klmnopqrst"))); - BOOST_TEST(testR(S("abcdefghijklmnopqrst"), 0, 10, "12345", 5, S("12345klmnopqrst"))); - BOOST_TEST(testR(S("abcdefghijklmnopqrst"), 0, 10, "1234567890", 0, S("klmnopqrst"))); - BOOST_TEST(testR(S("abcdefghijklmnopqrst"), 0, 10, "1234567890", 1, S("1klmnopqrst"))); - BOOST_TEST(testR(S("abcdefghijklmnopqrst"), 0, 10, "1234567890", 5, S("12345klmnopqrst"))); - BOOST_TEST(testR(S("abcdefghijklmnopqrst"), 0, 10, "1234567890", 9, S("123456789klmnopqrst"))); - BOOST_TEST(testR(S("abcdefghijklmnopqrst"), 0, 10, "1234567890", 10, S("1234567890klmnopqrst"))); - BOOST_TEST(testR(S("abcdefghijklmnopqrst"), 0, 10, "12345678901234567890", 0, S("klmnopqrst"))); - BOOST_TEST(testR(S("abcdefghijklmnopqrst"), 0, 10, "12345678901234567890", 1, S("1klmnopqrst"))); - BOOST_TEST(testR(S("abcdefghijklmnopqrst"), 0, 10, "12345678901234567890", 10, S("1234567890klmnopqrst"))); - BOOST_TEST(testR(S("abcdefghijklmnopqrst"), 0, 10, "12345678901234567890", 19, S("1234567890123456789klmnopqrst"))); - BOOST_TEST(testR(S("abcdefghijklmnopqrst"), 0, 10, "12345678901234567890", 20, S("12345678901234567890klmnopqrst"))); - BOOST_TEST(testR(S("abcdefghijklmnopqrst"), 0, 19, "", 0, S("t"))); - BOOST_TEST(testR(S("abcdefghijklmnopqrst"), 0, 19, "12345", 0, S("t"))); - BOOST_TEST(testR(S("abcdefghijklmnopqrst"), 0, 19, "12345", 1, S("1t"))); - BOOST_TEST(testR(S("abcdefghijklmnopqrst"), 0, 19, "12345", 2, S("12t"))); - BOOST_TEST(testR(S("abcdefghijklmnopqrst"), 0, 19, "12345", 4, S("1234t"))); - BOOST_TEST(testR(S("abcdefghijklmnopqrst"), 0, 19, "12345", 5, S("12345t"))); - BOOST_TEST(testR(S("abcdefghijklmnopqrst"), 0, 19, "1234567890", 0, S("t"))); - BOOST_TEST(testR(S("abcdefghijklmnopqrst"), 0, 19, "1234567890", 1, S("1t"))); - BOOST_TEST(testR(S("abcdefghijklmnopqrst"), 0, 19, "1234567890", 5, S("12345t"))); - BOOST_TEST(testR(S("abcdefghijklmnopqrst"), 0, 19, "1234567890", 9, S("123456789t"))); - BOOST_TEST(testR(S("abcdefghijklmnopqrst"), 0, 19, "1234567890", 10, S("1234567890t"))); - BOOST_TEST(testR(S("abcdefghijklmnopqrst"), 0, 19, "12345678901234567890", 0, S("t"))); - BOOST_TEST(testR(S("abcdefghijklmnopqrst"), 0, 19, "12345678901234567890", 1, S("1t"))); - BOOST_TEST(testR(S("abcdefghijklmnopqrst"), 0, 19, "12345678901234567890", 10, S("1234567890t"))); - BOOST_TEST(testR(S("abcdefghijklmnopqrst"), 0, 19, "12345678901234567890", 19, S("1234567890123456789t"))); - BOOST_TEST(testR(S("abcdefghijklmnopqrst"), 0, 19, "12345678901234567890", 20, S("12345678901234567890t"))); - BOOST_TEST(testR(S("abcdefghijklmnopqrst"), 0, 20, "", 0, S(""))); - BOOST_TEST(testR(S("abcdefghijklmnopqrst"), 0, 20, "12345", 0, S(""))); - BOOST_TEST(testR(S("abcdefghijklmnopqrst"), 0, 20, "12345", 1, S("1"))); - BOOST_TEST(testR(S("abcdefghijklmnopqrst"), 0, 20, "12345", 2, S("12"))); - BOOST_TEST(testR(S("abcdefghijklmnopqrst"), 0, 20, "12345", 4, S("1234"))); - BOOST_TEST(testR(S("abcdefghijklmnopqrst"), 0, 20, "12345", 5, S("12345"))); - BOOST_TEST(testR(S("abcdefghijklmnopqrst"), 0, 20, "1234567890", 0, S(""))); - BOOST_TEST(testR(S("abcdefghijklmnopqrst"), 0, 20, "1234567890", 1, S("1"))); - BOOST_TEST(testR(S("abcdefghijklmnopqrst"), 0, 20, "1234567890", 5, S("12345"))); - BOOST_TEST(testR(S("abcdefghijklmnopqrst"), 0, 20, "1234567890", 9, S("123456789"))); - BOOST_TEST(testR(S("abcdefghijklmnopqrst"), 0, 20, "1234567890", 10, S("1234567890"))); - BOOST_TEST(testR(S("abcdefghijklmnopqrst"), 0, 20, "12345678901234567890", 0, S(""))); - BOOST_TEST(testR(S("abcdefghijklmnopqrst"), 0, 20, "12345678901234567890", 1, S("1"))); - BOOST_TEST(testR(S("abcdefghijklmnopqrst"), 0, 20, "12345678901234567890", 10, S("1234567890"))); - BOOST_TEST(testR(S("abcdefghijklmnopqrst"), 0, 20, "12345678901234567890", 19, S("1234567890123456789"))); - BOOST_TEST(testR(S("abcdefghijklmnopqrst"), 0, 20, "12345678901234567890", 20, S("12345678901234567890"))); - BOOST_TEST(testR(S("abcdefghijklmnopqrst"), 0, 21, "", 0, S(""))); - BOOST_TEST(testR(S("abcdefghijklmnopqrst"), 0, 21, "12345", 0, S(""))); - BOOST_TEST(testR(S("abcdefghijklmnopqrst"), 0, 21, "12345", 1, S("1"))); - BOOST_TEST(testR(S("abcdefghijklmnopqrst"), 0, 21, "12345", 2, S("12"))); - BOOST_TEST(testR(S("abcdefghijklmnopqrst"), 0, 21, "12345", 4, S("1234"))); - BOOST_TEST(testR(S("abcdefghijklmnopqrst"), 0, 21, "12345", 5, S("12345"))); - BOOST_TEST(testR(S("abcdefghijklmnopqrst"), 0, 21, "1234567890", 0, S(""))); - BOOST_TEST(testR(S("abcdefghijklmnopqrst"), 0, 21, "1234567890", 1, S("1"))); - BOOST_TEST(testR(S("abcdefghijklmnopqrst"), 0, 21, "1234567890", 5, S("12345"))); - BOOST_TEST(testR(S("abcdefghijklmnopqrst"), 0, 21, "1234567890", 9, S("123456789"))); - BOOST_TEST(testR(S("abcdefghijklmnopqrst"), 0, 21, "1234567890", 10, S("1234567890"))); - BOOST_TEST(testR(S("abcdefghijklmnopqrst"), 0, 21, "12345678901234567890", 0, S(""))); - BOOST_TEST(testR(S("abcdefghijklmnopqrst"), 0, 21, "12345678901234567890", 1, S("1"))); - BOOST_TEST(testR(S("abcdefghijklmnopqrst"), 0, 21, "12345678901234567890", 10, S("1234567890"))); - BOOST_TEST(testR(S("abcdefghijklmnopqrst"), 0, 21, "12345678901234567890", 19, S("1234567890123456789"))); - BOOST_TEST(testR(S("abcdefghijklmnopqrst"), 0, 21, "12345678901234567890", 20, S("12345678901234567890"))); - BOOST_TEST(testR(S("abcdefghijklmnopqrst"), 1, 0, "", 0, S("abcdefghijklmnopqrst"))); - BOOST_TEST(testR(S("abcdefghijklmnopqrst"), 1, 0, "12345", 0, S("abcdefghijklmnopqrst"))); - BOOST_TEST(testR(S("abcdefghijklmnopqrst"), 1, 0, "12345", 1, S("a1bcdefghijklmnopqrst"))); - BOOST_TEST(testR(S("abcdefghijklmnopqrst"), 1, 0, "12345", 2, S("a12bcdefghijklmnopqrst"))); - BOOST_TEST(testR(S("abcdefghijklmnopqrst"), 1, 0, "12345", 4, S("a1234bcdefghijklmnopqrst"))); - BOOST_TEST(testR(S("abcdefghijklmnopqrst"), 1, 0, "12345", 5, S("a12345bcdefghijklmnopqrst"))); - BOOST_TEST(testR(S("abcdefghijklmnopqrst"), 1, 0, "1234567890", 0, S("abcdefghijklmnopqrst"))); - BOOST_TEST(testR(S("abcdefghijklmnopqrst"), 1, 0, "1234567890", 1, S("a1bcdefghijklmnopqrst"))); - BOOST_TEST(testR(S("abcdefghijklmnopqrst"), 1, 0, "1234567890", 5, S("a12345bcdefghijklmnopqrst"))); - BOOST_TEST(testR(S("abcdefghijklmnopqrst"), 1, 0, "1234567890", 9, S("a123456789bcdefghijklmnopqrst"))); - BOOST_TEST(testR(S("abcdefghijklmnopqrst"), 1, 0, "1234567890", 10, S("a1234567890bcdefghijklmnopqrst"))); - BOOST_TEST(testR(S("abcdefghijklmnopqrst"), 1, 0, "12345678901234567890", 0, S("abcdefghijklmnopqrst"))); - BOOST_TEST(testR(S("abcdefghijklmnopqrst"), 1, 0, "12345678901234567890", 1, S("a1bcdefghijklmnopqrst"))); - BOOST_TEST(testR(S("abcdefghijklmnopqrst"), 1, 0, "12345678901234567890", 10, S("a1234567890bcdefghijklmnopqrst"))); - BOOST_TEST(testR(S("abcdefghijklmnopqrst"), 1, 0, "12345678901234567890", 19, S("a1234567890123456789bcdefghijklmnopqrst"))); - BOOST_TEST(testR(S("abcdefghijklmnopqrst"), 1, 0, "12345678901234567890", 20, S("a12345678901234567890bcdefghijklmnopqrst"))); - BOOST_TEST(testR(S("abcdefghijklmnopqrst"), 1, 1, "", 0, S("acdefghijklmnopqrst"))); - BOOST_TEST(testR(S("abcdefghijklmnopqrst"), 1, 1, "12345", 0, S("acdefghijklmnopqrst"))); - BOOST_TEST(testR(S("abcdefghijklmnopqrst"), 1, 1, "12345", 1, S("a1cdefghijklmnopqrst"))); - BOOST_TEST(testR(S("abcdefghijklmnopqrst"), 1, 1, "12345", 2, S("a12cdefghijklmnopqrst"))); - BOOST_TEST(testR(S("abcdefghijklmnopqrst"), 1, 1, "12345", 4, S("a1234cdefghijklmnopqrst"))); - BOOST_TEST(testR(S("abcdefghijklmnopqrst"), 1, 1, "12345", 5, S("a12345cdefghijklmnopqrst"))); - BOOST_TEST(testR(S("abcdefghijklmnopqrst"), 1, 1, "1234567890", 0, S("acdefghijklmnopqrst"))); - BOOST_TEST(testR(S("abcdefghijklmnopqrst"), 1, 1, "1234567890", 1, S("a1cdefghijklmnopqrst"))); - BOOST_TEST(testR(S("abcdefghijklmnopqrst"), 1, 1, "1234567890", 5, S("a12345cdefghijklmnopqrst"))); - BOOST_TEST(testR(S("abcdefghijklmnopqrst"), 1, 1, "1234567890", 9, S("a123456789cdefghijklmnopqrst"))); - BOOST_TEST(testR(S("abcdefghijklmnopqrst"), 1, 1, "1234567890", 10, S("a1234567890cdefghijklmnopqrst"))); - BOOST_TEST(testR(S("abcdefghijklmnopqrst"), 1, 1, "12345678901234567890", 0, S("acdefghijklmnopqrst"))); - BOOST_TEST(testR(S("abcdefghijklmnopqrst"), 1, 1, "12345678901234567890", 1, S("a1cdefghijklmnopqrst"))); - BOOST_TEST(testR(S("abcdefghijklmnopqrst"), 1, 1, "12345678901234567890", 10, S("a1234567890cdefghijklmnopqrst"))); - BOOST_TEST(testR(S("abcdefghijklmnopqrst"), 1, 1, "12345678901234567890", 19, S("a1234567890123456789cdefghijklmnopqrst"))); - BOOST_TEST(testR(S("abcdefghijklmnopqrst"), 1, 1, "12345678901234567890", 20, S("a12345678901234567890cdefghijklmnopqrst"))); - BOOST_TEST(testR(S("abcdefghijklmnopqrst"), 1, 9, "", 0, S("aklmnopqrst"))); - BOOST_TEST(testR(S("abcdefghijklmnopqrst"), 1, 9, "12345", 0, S("aklmnopqrst"))); - BOOST_TEST(testR(S("abcdefghijklmnopqrst"), 1, 9, "12345", 1, S("a1klmnopqrst"))); - BOOST_TEST(testR(S("abcdefghijklmnopqrst"), 1, 9, "12345", 2, S("a12klmnopqrst"))); - BOOST_TEST(testR(S("abcdefghijklmnopqrst"), 1, 9, "12345", 4, S("a1234klmnopqrst"))); - BOOST_TEST(testR(S("abcdefghijklmnopqrst"), 1, 9, "12345", 5, S("a12345klmnopqrst"))); - BOOST_TEST(testR(S("abcdefghijklmnopqrst"), 1, 9, "1234567890", 0, S("aklmnopqrst"))); - BOOST_TEST(testR(S("abcdefghijklmnopqrst"), 1, 9, "1234567890", 1, S("a1klmnopqrst"))); - BOOST_TEST(testR(S("abcdefghijklmnopqrst"), 1, 9, "1234567890", 5, S("a12345klmnopqrst"))); - BOOST_TEST(testR(S("abcdefghijklmnopqrst"), 1, 9, "1234567890", 9, S("a123456789klmnopqrst"))); - BOOST_TEST(testR(S("abcdefghijklmnopqrst"), 1, 9, "1234567890", 10, S("a1234567890klmnopqrst"))); - BOOST_TEST(testR(S("abcdefghijklmnopqrst"), 1, 9, "12345678901234567890", 0, S("aklmnopqrst"))); - BOOST_TEST(testR(S("abcdefghijklmnopqrst"), 1, 9, "12345678901234567890", 1, S("a1klmnopqrst"))); - BOOST_TEST(testR(S("abcdefghijklmnopqrst"), 1, 9, "12345678901234567890", 10, S("a1234567890klmnopqrst"))); - BOOST_TEST(testR(S("abcdefghijklmnopqrst"), 1, 9, "12345678901234567890", 19, S("a1234567890123456789klmnopqrst"))); - BOOST_TEST(testR(S("abcdefghijklmnopqrst"), 1, 9, "12345678901234567890", 20, S("a12345678901234567890klmnopqrst"))); - BOOST_TEST(testR(S("abcdefghijklmnopqrst"), 1, 18, "", 0, S("at"))); - BOOST_TEST(testR(S("abcdefghijklmnopqrst"), 1, 18, "12345", 0, S("at"))); - BOOST_TEST(testR(S("abcdefghijklmnopqrst"), 1, 18, "12345", 1, S("a1t"))); - BOOST_TEST(testR(S("abcdefghijklmnopqrst"), 1, 18, "12345", 2, S("a12t"))); - BOOST_TEST(testR(S("abcdefghijklmnopqrst"), 1, 18, "12345", 4, S("a1234t"))); - BOOST_TEST(testR(S("abcdefghijklmnopqrst"), 1, 18, "12345", 5, S("a12345t"))); - BOOST_TEST(testR(S("abcdefghijklmnopqrst"), 1, 18, "1234567890", 0, S("at"))); - BOOST_TEST(testR(S("abcdefghijklmnopqrst"), 1, 18, "1234567890", 1, S("a1t"))); - BOOST_TEST(testR(S("abcdefghijklmnopqrst"), 1, 18, "1234567890", 5, S("a12345t"))); - BOOST_TEST(testR(S("abcdefghijklmnopqrst"), 1, 18, "1234567890", 9, S("a123456789t"))); - BOOST_TEST(testR(S("abcdefghijklmnopqrst"), 1, 18, "1234567890", 10, S("a1234567890t"))); - BOOST_TEST(testR(S("abcdefghijklmnopqrst"), 1, 18, "12345678901234567890", 0, S("at"))); - BOOST_TEST(testR(S("abcdefghijklmnopqrst"), 1, 18, "12345678901234567890", 1, S("a1t"))); - BOOST_TEST(testR(S("abcdefghijklmnopqrst"), 1, 18, "12345678901234567890", 10, S("a1234567890t"))); - BOOST_TEST(testR(S("abcdefghijklmnopqrst"), 1, 18, "12345678901234567890", 19, S("a1234567890123456789t"))); - BOOST_TEST(testR(S("abcdefghijklmnopqrst"), 1, 18, "12345678901234567890", 20, S("a12345678901234567890t"))); - BOOST_TEST(testR(S("abcdefghijklmnopqrst"), 1, 19, "", 0, S("a"))); - BOOST_TEST(testR(S("abcdefghijklmnopqrst"), 1, 19, "12345", 0, S("a"))); - BOOST_TEST(testR(S("abcdefghijklmnopqrst"), 1, 19, "12345", 1, S("a1"))); - BOOST_TEST(testR(S("abcdefghijklmnopqrst"), 1, 19, "12345", 2, S("a12"))); - BOOST_TEST(testR(S("abcdefghijklmnopqrst"), 1, 19, "12345", 4, S("a1234"))); - BOOST_TEST(testR(S("abcdefghijklmnopqrst"), 1, 19, "12345", 5, S("a12345"))); - BOOST_TEST(testR(S("abcdefghijklmnopqrst"), 1, 19, "1234567890", 0, S("a"))); - BOOST_TEST(testR(S("abcdefghijklmnopqrst"), 1, 19, "1234567890", 1, S("a1"))); - BOOST_TEST(testR(S("abcdefghijklmnopqrst"), 1, 19, "1234567890", 5, S("a12345"))); - BOOST_TEST(testR(S("abcdefghijklmnopqrst"), 1, 19, "1234567890", 9, S("a123456789"))); - BOOST_TEST(testR(S("abcdefghijklmnopqrst"), 1, 19, "1234567890", 10, S("a1234567890"))); - BOOST_TEST(testR(S("abcdefghijklmnopqrst"), 1, 19, "12345678901234567890", 0, S("a"))); - BOOST_TEST(testR(S("abcdefghijklmnopqrst"), 1, 19, "12345678901234567890", 1, S("a1"))); - BOOST_TEST(testR(S("abcdefghijklmnopqrst"), 1, 19, "12345678901234567890", 10, S("a1234567890"))); - BOOST_TEST(testR(S("abcdefghijklmnopqrst"), 1, 19, "12345678901234567890", 19, S("a1234567890123456789"))); - BOOST_TEST(testR(S("abcdefghijklmnopqrst"), 1, 19, "12345678901234567890", 20, S("a12345678901234567890"))); - BOOST_TEST(testR(S("abcdefghijklmnopqrst"), 1, 20, "", 0, S("a"))); - BOOST_TEST(testR(S("abcdefghijklmnopqrst"), 1, 20, "12345", 0, S("a"))); - BOOST_TEST(testR(S("abcdefghijklmnopqrst"), 1, 20, "12345", 1, S("a1"))); - BOOST_TEST(testR(S("abcdefghijklmnopqrst"), 1, 20, "12345", 2, S("a12"))); - BOOST_TEST(testR(S("abcdefghijklmnopqrst"), 1, 20, "12345", 4, S("a1234"))); - BOOST_TEST(testR(S("abcdefghijklmnopqrst"), 1, 20, "12345", 5, S("a12345"))); - BOOST_TEST(testR(S("abcdefghijklmnopqrst"), 1, 20, "1234567890", 0, S("a"))); - BOOST_TEST(testR(S("abcdefghijklmnopqrst"), 1, 20, "1234567890", 1, S("a1"))); - BOOST_TEST(testR(S("abcdefghijklmnopqrst"), 1, 20, "1234567890", 5, S("a12345"))); - BOOST_TEST(testR(S("abcdefghijklmnopqrst"), 1, 20, "1234567890", 9, S("a123456789"))); - BOOST_TEST(testR(S("abcdefghijklmnopqrst"), 1, 20, "1234567890", 10, S("a1234567890"))); - BOOST_TEST(testR(S("abcdefghijklmnopqrst"), 1, 20, "12345678901234567890", 0, S("a"))); - BOOST_TEST(testR(S("abcdefghijklmnopqrst"), 1, 20, "12345678901234567890", 1, S("a1"))); - BOOST_TEST(testR(S("abcdefghijklmnopqrst"), 1, 20, "12345678901234567890", 10, S("a1234567890"))); - BOOST_TEST(testR(S("abcdefghijklmnopqrst"), 1, 20, "12345678901234567890", 19, S("a1234567890123456789"))); - BOOST_TEST(testR(S("abcdefghijklmnopqrst"), 1, 20, "12345678901234567890", 20, S("a12345678901234567890"))); - BOOST_TEST(testR(S("abcdefghijklmnopqrst"), 10, 0, "", 0, S("abcdefghijklmnopqrst"))); - BOOST_TEST(testR(S("abcdefghijklmnopqrst"), 10, 0, "12345", 0, S("abcdefghijklmnopqrst"))); - BOOST_TEST(testR(S("abcdefghijklmnopqrst"), 10, 0, "12345", 1, S("abcdefghij1klmnopqrst"))); - BOOST_TEST(testR(S("abcdefghijklmnopqrst"), 10, 0, "12345", 2, S("abcdefghij12klmnopqrst"))); - BOOST_TEST(testR(S("abcdefghijklmnopqrst"), 10, 0, "12345", 4, S("abcdefghij1234klmnopqrst"))); - BOOST_TEST(testR(S("abcdefghijklmnopqrst"), 10, 0, "12345", 5, S("abcdefghij12345klmnopqrst"))); - BOOST_TEST(testR(S("abcdefghijklmnopqrst"), 10, 0, "1234567890", 0, S("abcdefghijklmnopqrst"))); - BOOST_TEST(testR(S("abcdefghijklmnopqrst"), 10, 0, "1234567890", 1, S("abcdefghij1klmnopqrst"))); - BOOST_TEST(testR(S("abcdefghijklmnopqrst"), 10, 0, "1234567890", 5, S("abcdefghij12345klmnopqrst"))); - BOOST_TEST(testR(S("abcdefghijklmnopqrst"), 10, 0, "1234567890", 9, S("abcdefghij123456789klmnopqrst"))); - BOOST_TEST(testR(S("abcdefghijklmnopqrst"), 10, 0, "1234567890", 10, S("abcdefghij1234567890klmnopqrst"))); - BOOST_TEST(testR(S("abcdefghijklmnopqrst"), 10, 0, "12345678901234567890", 0, S("abcdefghijklmnopqrst"))); - BOOST_TEST(testR(S("abcdefghijklmnopqrst"), 10, 0, "12345678901234567890", 1, S("abcdefghij1klmnopqrst"))); - BOOST_TEST(testR(S("abcdefghijklmnopqrst"), 10, 0, "12345678901234567890", 10, S("abcdefghij1234567890klmnopqrst"))); - BOOST_TEST(testR(S("abcdefghijklmnopqrst"), 10, 0, "12345678901234567890", 19, S("abcdefghij1234567890123456789klmnopqrst"))); - BOOST_TEST(testR(S("abcdefghijklmnopqrst"), 10, 0, "12345678901234567890", 20, S("abcdefghij12345678901234567890klmnopqrst"))); - BOOST_TEST(testR(S("abcdefghijklmnopqrst"), 10, 1, "", 0, S("abcdefghijlmnopqrst"))); - BOOST_TEST(testR(S("abcdefghijklmnopqrst"), 10, 1, "12345", 0, S("abcdefghijlmnopqrst"))); - BOOST_TEST(testR(S("abcdefghijklmnopqrst"), 10, 1, "12345", 1, S("abcdefghij1lmnopqrst"))); - BOOST_TEST(testR(S("abcdefghijklmnopqrst"), 10, 1, "12345", 2, S("abcdefghij12lmnopqrst"))); - BOOST_TEST(testR(S("abcdefghijklmnopqrst"), 10, 1, "12345", 4, S("abcdefghij1234lmnopqrst"))); - BOOST_TEST(testR(S("abcdefghijklmnopqrst"), 10, 1, "12345", 5, S("abcdefghij12345lmnopqrst"))); - BOOST_TEST(testR(S("abcdefghijklmnopqrst"), 10, 1, "1234567890", 0, S("abcdefghijlmnopqrst"))); - BOOST_TEST(testR(S("abcdefghijklmnopqrst"), 10, 1, "1234567890", 1, S("abcdefghij1lmnopqrst"))); - BOOST_TEST(testR(S("abcdefghijklmnopqrst"), 10, 1, "1234567890", 5, S("abcdefghij12345lmnopqrst"))); - BOOST_TEST(testR(S("abcdefghijklmnopqrst"), 10, 1, "1234567890", 9, S("abcdefghij123456789lmnopqrst"))); - BOOST_TEST(testR(S("abcdefghijklmnopqrst"), 10, 1, "1234567890", 10, S("abcdefghij1234567890lmnopqrst"))); - BOOST_TEST(testR(S("abcdefghijklmnopqrst"), 10, 1, "12345678901234567890", 0, S("abcdefghijlmnopqrst"))); - BOOST_TEST(testR(S("abcdefghijklmnopqrst"), 10, 1, "12345678901234567890", 1, S("abcdefghij1lmnopqrst"))); - BOOST_TEST(testR(S("abcdefghijklmnopqrst"), 10, 1, "12345678901234567890", 10, S("abcdefghij1234567890lmnopqrst"))); - BOOST_TEST(testR(S("abcdefghijklmnopqrst"), 10, 1, "12345678901234567890", 19, S("abcdefghij1234567890123456789lmnopqrst"))); - BOOST_TEST(testR(S("abcdefghijklmnopqrst"), 10, 1, "12345678901234567890", 20, S("abcdefghij12345678901234567890lmnopqrst"))); - BOOST_TEST(testR(S("abcdefghijklmnopqrst"), 10, 5, "", 0, S("abcdefghijpqrst"))); - BOOST_TEST(testR(S("abcdefghijklmnopqrst"), 10, 5, "12345", 0, S("abcdefghijpqrst"))); - BOOST_TEST(testR(S("abcdefghijklmnopqrst"), 10, 5, "12345", 1, S("abcdefghij1pqrst"))); - BOOST_TEST(testR(S("abcdefghijklmnopqrst"), 10, 5, "12345", 2, S("abcdefghij12pqrst"))); - BOOST_TEST(testR(S("abcdefghijklmnopqrst"), 10, 5, "12345", 4, S("abcdefghij1234pqrst"))); - BOOST_TEST(testR(S("abcdefghijklmnopqrst"), 10, 5, "12345", 5, S("abcdefghij12345pqrst"))); - BOOST_TEST(testR(S("abcdefghijklmnopqrst"), 10, 5, "1234567890", 0, S("abcdefghijpqrst"))); - BOOST_TEST(testR(S("abcdefghijklmnopqrst"), 10, 5, "1234567890", 1, S("abcdefghij1pqrst"))); - BOOST_TEST(testR(S("abcdefghijklmnopqrst"), 10, 5, "1234567890", 5, S("abcdefghij12345pqrst"))); - BOOST_TEST(testR(S("abcdefghijklmnopqrst"), 10, 5, "1234567890", 9, S("abcdefghij123456789pqrst"))); - BOOST_TEST(testR(S("abcdefghijklmnopqrst"), 10, 5, "1234567890", 10, S("abcdefghij1234567890pqrst"))); - BOOST_TEST(testR(S("abcdefghijklmnopqrst"), 10, 5, "12345678901234567890", 0, S("abcdefghijpqrst"))); - BOOST_TEST(testR(S("abcdefghijklmnopqrst"), 10, 5, "12345678901234567890", 1, S("abcdefghij1pqrst"))); - BOOST_TEST(testR(S("abcdefghijklmnopqrst"), 10, 5, "12345678901234567890", 10, S("abcdefghij1234567890pqrst"))); - BOOST_TEST(testR(S("abcdefghijklmnopqrst"), 10, 5, "12345678901234567890", 19, S("abcdefghij1234567890123456789pqrst"))); - BOOST_TEST(testR(S("abcdefghijklmnopqrst"), 10, 5, "12345678901234567890", 20, S("abcdefghij12345678901234567890pqrst"))); - BOOST_TEST(testR(S("abcdefghijklmnopqrst"), 10, 9, "", 0, S("abcdefghijt"))); - BOOST_TEST(testR(S("abcdefghijklmnopqrst"), 10, 9, "12345", 0, S("abcdefghijt"))); - BOOST_TEST(testR(S("abcdefghijklmnopqrst"), 10, 9, "12345", 1, S("abcdefghij1t"))); - BOOST_TEST(testR(S("abcdefghijklmnopqrst"), 10, 9, "12345", 2, S("abcdefghij12t"))); - BOOST_TEST(testR(S("abcdefghijklmnopqrst"), 10, 9, "12345", 4, S("abcdefghij1234t"))); - BOOST_TEST(testR(S("abcdefghijklmnopqrst"), 10, 9, "12345", 5, S("abcdefghij12345t"))); - BOOST_TEST(testR(S("abcdefghijklmnopqrst"), 10, 9, "1234567890", 0, S("abcdefghijt"))); - BOOST_TEST(testR(S("abcdefghijklmnopqrst"), 10, 9, "1234567890", 1, S("abcdefghij1t"))); - BOOST_TEST(testR(S("abcdefghijklmnopqrst"), 10, 9, "1234567890", 5, S("abcdefghij12345t"))); - BOOST_TEST(testR(S("abcdefghijklmnopqrst"), 10, 9, "1234567890", 9, S("abcdefghij123456789t"))); - BOOST_TEST(testR(S("abcdefghijklmnopqrst"), 10, 9, "1234567890", 10, S("abcdefghij1234567890t"))); - BOOST_TEST(testR(S("abcdefghijklmnopqrst"), 10, 9, "12345678901234567890", 0, S("abcdefghijt"))); - BOOST_TEST(testR(S("abcdefghijklmnopqrst"), 10, 9, "12345678901234567890", 1, S("abcdefghij1t"))); - BOOST_TEST(testR(S("abcdefghijklmnopqrst"), 10, 9, "12345678901234567890", 10, S("abcdefghij1234567890t"))); - BOOST_TEST(testR(S("abcdefghijklmnopqrst"), 10, 9, "12345678901234567890", 19, S("abcdefghij1234567890123456789t"))); - BOOST_TEST(testR(S("abcdefghijklmnopqrst"), 10, 9, "12345678901234567890", 20, S("abcdefghij12345678901234567890t"))); - BOOST_TEST(testR(S("abcdefghijklmnopqrst"), 10, 10, "", 0, S("abcdefghij"))); - BOOST_TEST(testR(S("abcdefghijklmnopqrst"), 10, 10, "12345", 0, S("abcdefghij"))); - BOOST_TEST(testR(S("abcdefghijklmnopqrst"), 10, 10, "12345", 1, S("abcdefghij1"))); - BOOST_TEST(testR(S("abcdefghijklmnopqrst"), 10, 10, "12345", 2, S("abcdefghij12"))); - BOOST_TEST(testR(S("abcdefghijklmnopqrst"), 10, 10, "12345", 4, S("abcdefghij1234"))); - BOOST_TEST(testR(S("abcdefghijklmnopqrst"), 10, 10, "12345", 5, S("abcdefghij12345"))); - BOOST_TEST(testR(S("abcdefghijklmnopqrst"), 10, 10, "1234567890", 0, S("abcdefghij"))); - BOOST_TEST(testR(S("abcdefghijklmnopqrst"), 10, 10, "1234567890", 1, S("abcdefghij1"))); - BOOST_TEST(testR(S("abcdefghijklmnopqrst"), 10, 10, "1234567890", 5, S("abcdefghij12345"))); - BOOST_TEST(testR(S("abcdefghijklmnopqrst"), 10, 10, "1234567890", 9, S("abcdefghij123456789"))); - BOOST_TEST(testR(S("abcdefghijklmnopqrst"), 10, 10, "1234567890", 10, S("abcdefghij1234567890"))); - BOOST_TEST(testR(S("abcdefghijklmnopqrst"), 10, 10, "12345678901234567890", 0, S("abcdefghij"))); - BOOST_TEST(testR(S("abcdefghijklmnopqrst"), 10, 10, "12345678901234567890", 1, S("abcdefghij1"))); - BOOST_TEST(testR(S("abcdefghijklmnopqrst"), 10, 10, "12345678901234567890", 10, S("abcdefghij1234567890"))); - BOOST_TEST(testR(S("abcdefghijklmnopqrst"), 10, 10, "12345678901234567890", 19, S("abcdefghij1234567890123456789"))); - BOOST_TEST(testR(S("abcdefghijklmnopqrst"), 10, 10, "12345678901234567890", 20, S("abcdefghij12345678901234567890"))); - BOOST_TEST(testR(S("abcdefghijklmnopqrst"), 10, 11, "", 0, S("abcdefghij"))); - BOOST_TEST(testR(S("abcdefghijklmnopqrst"), 10, 11, "12345", 0, S("abcdefghij"))); - BOOST_TEST(testR(S("abcdefghijklmnopqrst"), 10, 11, "12345", 1, S("abcdefghij1"))); - BOOST_TEST(testR(S("abcdefghijklmnopqrst"), 10, 11, "12345", 2, S("abcdefghij12"))); - BOOST_TEST(testR(S("abcdefghijklmnopqrst"), 10, 11, "12345", 4, S("abcdefghij1234"))); - BOOST_TEST(testR(S("abcdefghijklmnopqrst"), 10, 11, "12345", 5, S("abcdefghij12345"))); - BOOST_TEST(testR(S("abcdefghijklmnopqrst"), 10, 11, "1234567890", 0, S("abcdefghij"))); - BOOST_TEST(testR(S("abcdefghijklmnopqrst"), 10, 11, "1234567890", 1, S("abcdefghij1"))); - BOOST_TEST(testR(S("abcdefghijklmnopqrst"), 10, 11, "1234567890", 5, S("abcdefghij12345"))); - BOOST_TEST(testR(S("abcdefghijklmnopqrst"), 10, 11, "1234567890", 9, S("abcdefghij123456789"))); - BOOST_TEST(testR(S("abcdefghijklmnopqrst"), 10, 11, "1234567890", 10, S("abcdefghij1234567890"))); - BOOST_TEST(testR(S("abcdefghijklmnopqrst"), 10, 11, "12345678901234567890", 0, S("abcdefghij"))); - BOOST_TEST(testR(S("abcdefghijklmnopqrst"), 10, 11, "12345678901234567890", 1, S("abcdefghij1"))); - BOOST_TEST(testR(S("abcdefghijklmnopqrst"), 10, 11, "12345678901234567890", 10, S("abcdefghij1234567890"))); - BOOST_TEST(testR(S("abcdefghijklmnopqrst"), 10, 11, "12345678901234567890", 19, S("abcdefghij1234567890123456789"))); - BOOST_TEST(testR(S("abcdefghijklmnopqrst"), 10, 11, "12345678901234567890", 20, S("abcdefghij12345678901234567890"))); - BOOST_TEST(testR(S("abcdefghijklmnopqrst"), 19, 0, "", 0, S("abcdefghijklmnopqrst"))); - BOOST_TEST(testR(S("abcdefghijklmnopqrst"), 19, 0, "12345", 0, S("abcdefghijklmnopqrst"))); - BOOST_TEST(testR(S("abcdefghijklmnopqrst"), 19, 0, "12345", 1, S("abcdefghijklmnopqrs1t"))); - BOOST_TEST(testR(S("abcdefghijklmnopqrst"), 19, 0, "12345", 2, S("abcdefghijklmnopqrs12t"))); - BOOST_TEST(testR(S("abcdefghijklmnopqrst"), 19, 0, "12345", 4, S("abcdefghijklmnopqrs1234t"))); - BOOST_TEST(testR(S("abcdefghijklmnopqrst"), 19, 0, "12345", 5, S("abcdefghijklmnopqrs12345t"))); - BOOST_TEST(testR(S("abcdefghijklmnopqrst"), 19, 0, "1234567890", 0, S("abcdefghijklmnopqrst"))); - BOOST_TEST(testR(S("abcdefghijklmnopqrst"), 19, 0, "1234567890", 1, S("abcdefghijklmnopqrs1t"))); - BOOST_TEST(testR(S("abcdefghijklmnopqrst"), 19, 0, "1234567890", 5, S("abcdefghijklmnopqrs12345t"))); - BOOST_TEST(testR(S("abcdefghijklmnopqrst"), 19, 0, "1234567890", 9, S("abcdefghijklmnopqrs123456789t"))); - BOOST_TEST(testR(S("abcdefghijklmnopqrst"), 19, 0, "1234567890", 10, S("abcdefghijklmnopqrs1234567890t"))); - BOOST_TEST(testR(S("abcdefghijklmnopqrst"), 19, 0, "12345678901234567890", 0, S("abcdefghijklmnopqrst"))); - BOOST_TEST(testR(S(""), 1, 0, "12345", 0, S("can't happen"))); - BOOST_TEST(testR(S(""), 1, 0, "12345", 1, S("can't happen"))); - BOOST_TEST(testR(S(""), 1, 0, "12345", 2, S("can't happen"))); - BOOST_TEST(testR(S(""), 1, 0, "12345", 4, S("can't happen"))); - BOOST_TEST(testR(S(""), 1, 0, "12345", 5, S("can't happen"))); - BOOST_TEST(testR(S(""), 1, 0, "1234567890", 0, S("can't happen"))); - BOOST_TEST(testR(S(""), 1, 0, "1234567890", 1, S("can't happen"))); - BOOST_TEST(testR(S(""), 1, 0, "1234567890", 5, S("can't happen"))); - BOOST_TEST(testR(S(""), 1, 0, "1234567890", 9, S("can't happen"))); - BOOST_TEST(testR(S(""), 1, 0, "1234567890", 10, S("can't happen"))); - BOOST_TEST(testR(S(""), 1, 0, "12345678901234567890", 0, S("can't happen"))); - BOOST_TEST(testR(S(""), 1, 0, "12345678901234567890", 1, S("can't happen"))); - BOOST_TEST(testR(S(""), 1, 0, "12345678901234567890", 10, S("can't happen"))); - BOOST_TEST(testR(S(""), 1, 0, "12345678901234567890", 19, S("can't happen"))); - BOOST_TEST(testR(S(""), 1, 0, "12345678901234567890", 20, S("can't happen"))); - BOOST_TEST(testR(S("abcde"), 6, 0, "", 0, S("can't happen"))); - BOOST_TEST(testR(S("abcde"), 6, 0, "12345", 0, S("can't happen"))); - BOOST_TEST(testR(S("abcde"), 6, 0, "12345", 1, S("can't happen"))); - BOOST_TEST(testR(S("abcde"), 6, 0, "12345", 2, S("can't happen"))); - BOOST_TEST(testR(S("abcde"), 6, 0, "12345", 4, S("can't happen"))); - BOOST_TEST(testR(S("abcde"), 6, 0, "12345", 5, S("can't happen"))); - BOOST_TEST(testR(S("abcde"), 6, 0, "1234567890", 0, S("can't happen"))); - BOOST_TEST(testR(S("abcde"), 6, 0, "1234567890", 1, S("can't happen"))); - BOOST_TEST(testR(S("abcde"), 6, 0, "1234567890", 5, S("can't happen"))); - BOOST_TEST(testR(S("abcde"), 6, 0, "1234567890", 9, S("can't happen"))); - BOOST_TEST(testR(S("abcde"), 6, 0, "1234567890", 10, S("can't happen"))); - BOOST_TEST(testR(S("abcde"), 6, 0, "12345678901234567890", 0, S("can't happen"))); - BOOST_TEST(testR(S("abcde"), 6, 0, "12345678901234567890", 1, S("can't happen"))); - BOOST_TEST(testR(S("abcde"), 6, 0, "12345678901234567890", 10, S("can't happen"))); - BOOST_TEST(testR(S("abcde"), 6, 0, "12345678901234567890", 19, S("can't happen"))); - BOOST_TEST(testR(S("abcde"), 6, 0, "12345678901234567890", 20, S("can't happen"))); - BOOST_TEST(testR(S("abcdefghij"), 11, 0, "", 0, S("can't happen"))); - BOOST_TEST(testR(S("abcdefghij"), 11, 0, "12345", 0, S("can't happen"))); - BOOST_TEST(testR(S("abcdefghij"), 11, 0, "12345", 1, S("can't happen"))); - BOOST_TEST(testR(S("abcdefghij"), 11, 0, "12345", 2, S("can't happen"))); - BOOST_TEST(testR(S("abcdefghij"), 11, 0, "12345", 4, S("can't happen"))); - BOOST_TEST(testR(S("abcdefghij"), 11, 0, "12345", 5, S("can't happen"))); - BOOST_TEST(testR(S("abcdefghij"), 11, 0, "1234567890", 0, S("can't happen"))); - BOOST_TEST(testR(S("abcdefghij"), 11, 0, "1234567890", 1, S("can't happen"))); - BOOST_TEST(testR(S("abcdefghij"), 11, 0, "1234567890", 5, S("can't happen"))); - BOOST_TEST(testR(S("abcdefghij"), 11, 0, "1234567890", 9, S("can't happen"))); - BOOST_TEST(testR(S("abcdefghij"), 11, 0, "1234567890", 10, S("can't happen"))); - BOOST_TEST(testR(S("abcdefghij"), 11, 0, "12345678901234567890", 0, S("can't happen"))); - BOOST_TEST(testR(S("abcdefghij"), 11, 0, "12345678901234567890", 1, S("can't happen"))); - BOOST_TEST(testR(S("abcdefghij"), 11, 0, "12345678901234567890", 10, S("can't happen"))); - BOOST_TEST(testR(S("abcdefghij"), 11, 0, "12345678901234567890", 19, S("can't happen"))); - BOOST_TEST(testR(S("abcdefghij"), 11, 0, "12345678901234567890", 20, S("can't happen"))); - BOOST_TEST(testR(S("abcdefghijklmnopqrst"), 21, 0, "", 0, S("can't happen"))); - BOOST_TEST(testR(S("abcdefghijklmnopqrst"), 21, 0, "12345", 0, S("can't happen"))); - BOOST_TEST(testR(S("abcdefghijklmnopqrst"), 21, 0, "12345", 1, S("can't happen"))); - BOOST_TEST(testR(S("abcdefghijklmnopqrst"), 21, 0, "12345", 2, S("can't happen"))); - BOOST_TEST(testR(S("abcdefghijklmnopqrst"), 21, 0, "12345", 4, S("can't happen"))); - BOOST_TEST(testR(S("abcdefghijklmnopqrst"), 21, 0, "12345", 5, S("can't happen"))); - BOOST_TEST(testR(S("abcdefghijklmnopqrst"), 21, 0, "1234567890", 0, S("can't happen"))); - BOOST_TEST(testR(S("abcdefghijklmnopqrst"), 21, 0, "1234567890", 1, S("can't happen"))); - BOOST_TEST(testR(S("abcdefghijklmnopqrst"), 21, 0, "1234567890", 5, S("can't happen"))); - BOOST_TEST(testR(S("abcdefghijklmnopqrst"), 21, 0, "1234567890", 9, S("can't happen"))); - BOOST_TEST(testR(S("abcdefghijklmnopqrst"), 21, 0, "1234567890", 10, S("can't happen"))); - BOOST_TEST(testR(S("abcdefghijklmnopqrst"), 21, 0, "12345678901234567890", 0, S("can't happen"))); - BOOST_TEST(testR(S("abcdefghijklmnopqrst"), 21, 0, "12345678901234567890", 1, S("can't happen"))); - BOOST_TEST(testR(S("abcdefghijklmnopqrst"), 21, 0, "12345678901234567890", 10, S("can't happen"))); - BOOST_TEST(testR(S("abcdefghijklmnopqrst"), 21, 0, "12345678901234567890", 19, S("can't happen"))); - BOOST_TEST(testR(S("abcdefghijklmnopqrst"), 21, 0, "12345678901234567890", 20, S("can't happen"))); - BOOST_TEST(testR(S("abcdefghijklmnopqrst"), 19, 0, "12345678901234567890", 1, S("abcdefghijklmnopqrs1t"))); - BOOST_TEST(testR(S("abcdefghijklmnopqrst"), 19, 0, "12345678901234567890", 10, S("abcdefghijklmnopqrs1234567890t"))); - BOOST_TEST(testR(S("abcdefghijklmnopqrst"), 19, 0, "12345678901234567890", 19, S("abcdefghijklmnopqrs1234567890123456789t"))); - BOOST_TEST(testR(S("abcdefghijklmnopqrst"), 19, 0, "12345678901234567890", 20, S("abcdefghijklmnopqrs12345678901234567890t"))); - BOOST_TEST(testR(S("abcdefghijklmnopqrst"), 19, 1, "", 0, S("abcdefghijklmnopqrs"))); - BOOST_TEST(testR(S("abcdefghijklmnopqrst"), 19, 1, "12345", 0, S("abcdefghijklmnopqrs"))); - BOOST_TEST(testR(S("abcdefghijklmnopqrst"), 19, 1, "12345", 1, S("abcdefghijklmnopqrs1"))); - BOOST_TEST(testR(S("abcdefghijklmnopqrst"), 19, 1, "12345", 2, S("abcdefghijklmnopqrs12"))); - BOOST_TEST(testR(S("abcdefghijklmnopqrst"), 19, 1, "12345", 4, S("abcdefghijklmnopqrs1234"))); - BOOST_TEST(testR(S("abcdefghijklmnopqrst"), 19, 1, "12345", 5, S("abcdefghijklmnopqrs12345"))); - BOOST_TEST(testR(S("abcdefghijklmnopqrst"), 19, 1, "1234567890", 0, S("abcdefghijklmnopqrs"))); - BOOST_TEST(testR(S("abcdefghijklmnopqrst"), 19, 1, "1234567890", 1, S("abcdefghijklmnopqrs1"))); - BOOST_TEST(testR(S("abcdefghijklmnopqrst"), 19, 1, "1234567890", 5, S("abcdefghijklmnopqrs12345"))); - BOOST_TEST(testR(S("abcdefghijklmnopqrst"), 19, 1, "1234567890", 9, S("abcdefghijklmnopqrs123456789"))); - BOOST_TEST(testR(S("abcdefghijklmnopqrst"), 19, 1, "1234567890", 10, S("abcdefghijklmnopqrs1234567890"))); - BOOST_TEST(testR(S("abcdefghijklmnopqrst"), 19, 1, "12345678901234567890", 0, S("abcdefghijklmnopqrs"))); - BOOST_TEST(testR(S("abcdefghijklmnopqrst"), 19, 1, "12345678901234567890", 1, S("abcdefghijklmnopqrs1"))); - BOOST_TEST(testR(S("abcdefghijklmnopqrst"), 19, 1, "12345678901234567890", 10, S("abcdefghijklmnopqrs1234567890"))); - BOOST_TEST(testR(S("abcdefghijklmnopqrst"), 19, 1, "12345678901234567890", 19, S("abcdefghijklmnopqrs1234567890123456789"))); - BOOST_TEST(testR(S("abcdefghijklmnopqrst"), 19, 1, "12345678901234567890", 20, S("abcdefghijklmnopqrs12345678901234567890"))); - BOOST_TEST(testR(S("abcdefghijklmnopqrst"), 19, 2, "", 0, S("abcdefghijklmnopqrs"))); - BOOST_TEST(testR(S("abcdefghijklmnopqrst"), 19, 2, "12345", 0, S("abcdefghijklmnopqrs"))); - BOOST_TEST(testR(S("abcdefghijklmnopqrst"), 19, 2, "12345", 1, S("abcdefghijklmnopqrs1"))); - BOOST_TEST(testR(S("abcdefghijklmnopqrst"), 19, 2, "12345", 2, S("abcdefghijklmnopqrs12"))); - BOOST_TEST(testR(S("abcdefghijklmnopqrst"), 19, 2, "12345", 4, S("abcdefghijklmnopqrs1234"))); - BOOST_TEST(testR(S("abcdefghijklmnopqrst"), 19, 2, "12345", 5, S("abcdefghijklmnopqrs12345"))); - BOOST_TEST(testR(S("abcdefghijklmnopqrst"), 19, 2, "1234567890", 0, S("abcdefghijklmnopqrs"))); - BOOST_TEST(testR(S("abcdefghijklmnopqrst"), 19, 2, "1234567890", 1, S("abcdefghijklmnopqrs1"))); - BOOST_TEST(testR(S("abcdefghijklmnopqrst"), 19, 2, "1234567890", 5, S("abcdefghijklmnopqrs12345"))); - BOOST_TEST(testR(S("abcdefghijklmnopqrst"), 19, 2, "1234567890", 9, S("abcdefghijklmnopqrs123456789"))); - BOOST_TEST(testR(S("abcdefghijklmnopqrst"), 19, 2, "1234567890", 10, S("abcdefghijklmnopqrs1234567890"))); - BOOST_TEST(testR(S("abcdefghijklmnopqrst"), 19, 2, "12345678901234567890", 0, S("abcdefghijklmnopqrs"))); - BOOST_TEST(testR(S("abcdefghijklmnopqrst"), 19, 2, "12345678901234567890", 1, S("abcdefghijklmnopqrs1"))); - BOOST_TEST(testR(S("abcdefghijklmnopqrst"), 19, 2, "12345678901234567890", 10, S("abcdefghijklmnopqrs1234567890"))); - BOOST_TEST(testR(S("abcdefghijklmnopqrst"), 19, 2, "12345678901234567890", 19, S("abcdefghijklmnopqrs1234567890123456789"))); - BOOST_TEST(testR(S("abcdefghijklmnopqrst"), 19, 2, "12345678901234567890", 20, S("abcdefghijklmnopqrs12345678901234567890"))); - BOOST_TEST(testR(S("abcdefghijklmnopqrst"), 20, 0, "", 0, S("abcdefghijklmnopqrst"))); - BOOST_TEST(testR(S("abcdefghijklmnopqrst"), 20, 0, "12345", 0, S("abcdefghijklmnopqrst"))); - BOOST_TEST(testR(S("abcdefghijklmnopqrst"), 20, 0, "12345", 1, S("abcdefghijklmnopqrst1"))); - BOOST_TEST(testR(S("abcdefghijklmnopqrst"), 20, 0, "12345", 2, S("abcdefghijklmnopqrst12"))); - BOOST_TEST(testR(S("abcdefghijklmnopqrst"), 20, 0, "12345", 4, S("abcdefghijklmnopqrst1234"))); - BOOST_TEST(testR(S("abcdefghijklmnopqrst"), 20, 0, "12345", 5, S("abcdefghijklmnopqrst12345"))); - BOOST_TEST(testR(S("abcdefghijklmnopqrst"), 20, 0, "1234567890", 0, S("abcdefghijklmnopqrst"))); - BOOST_TEST(testR(S("abcdefghijklmnopqrst"), 20, 0, "1234567890", 1, S("abcdefghijklmnopqrst1"))); - BOOST_TEST(testR(S("abcdefghijklmnopqrst"), 20, 0, "1234567890", 5, S("abcdefghijklmnopqrst12345"))); - BOOST_TEST(testR(S("abcdefghijklmnopqrst"), 20, 0, "1234567890", 9, S("abcdefghijklmnopqrst123456789"))); - BOOST_TEST(testR(S("abcdefghijklmnopqrst"), 20, 0, "1234567890", 10, S("abcdefghijklmnopqrst1234567890"))); - BOOST_TEST(testR(S("abcdefghijklmnopqrst"), 20, 0, "12345678901234567890", 0, S("abcdefghijklmnopqrst"))); - BOOST_TEST(testR(S("abcdefghijklmnopqrst"), 20, 0, "12345678901234567890", 1, S("abcdefghijklmnopqrst1"))); - BOOST_TEST(testR(S("abcdefghijklmnopqrst"), 20, 0, "12345678901234567890", 10, S("abcdefghijklmnopqrst1234567890"))); - BOOST_TEST(testR(S("abcdefghijklmnopqrst"), 20, 0, "12345678901234567890", 19, S("abcdefghijklmnopqrst1234567890123456789"))); - BOOST_TEST(testR(S("abcdefghijklmnopqrst"), 20, 0, "12345678901234567890", 20, S("abcdefghijklmnopqrst12345678901234567890"))); - BOOST_TEST(testR(S("abcdefghijklmnopqrst"), 20, 1, "", 0, S("abcdefghijklmnopqrst"))); - BOOST_TEST(testR(S("abcdefghijklmnopqrst"), 20, 1, "12345", 0, S("abcdefghijklmnopqrst"))); - BOOST_TEST(testR(S("abcdefghijklmnopqrst"), 20, 1, "12345", 1, S("abcdefghijklmnopqrst1"))); - BOOST_TEST(testR(S("abcdefghijklmnopqrst"), 20, 1, "12345", 2, S("abcdefghijklmnopqrst12"))); - BOOST_TEST(testR(S("abcdefghijklmnopqrst"), 20, 1, "12345", 4, S("abcdefghijklmnopqrst1234"))); - BOOST_TEST(testR(S("abcdefghijklmnopqrst"), 20, 1, "12345", 5, S("abcdefghijklmnopqrst12345"))); - BOOST_TEST(testR(S("abcdefghijklmnopqrst"), 20, 1, "1234567890", 0, S("abcdefghijklmnopqrst"))); - BOOST_TEST(testR(S("abcdefghijklmnopqrst"), 20, 1, "1234567890", 1, S("abcdefghijklmnopqrst1"))); - BOOST_TEST(testR(S("abcdefghijklmnopqrst"), 20, 1, "1234567890", 5, S("abcdefghijklmnopqrst12345"))); - BOOST_TEST(testR(S("abcdefghijklmnopqrst"), 20, 1, "1234567890", 9, S("abcdefghijklmnopqrst123456789"))); - BOOST_TEST(testR(S("abcdefghijklmnopqrst"), 20, 1, "1234567890", 10, S("abcdefghijklmnopqrst1234567890"))); - BOOST_TEST(testR(S("abcdefghijklmnopqrst"), 20, 1, "12345678901234567890", 0, S("abcdefghijklmnopqrst"))); - BOOST_TEST(testR(S("abcdefghijklmnopqrst"), 20, 1, "12345678901234567890", 1, S("abcdefghijklmnopqrst1"))); - BOOST_TEST(testR(S("abcdefghijklmnopqrst"), 20, 1, "12345678901234567890", 10, S("abcdefghijklmnopqrst1234567890"))); - BOOST_TEST(testR(S("abcdefghijklmnopqrst"), 20, 1, "12345678901234567890", 19, S("abcdefghijklmnopqrst1234567890123456789"))); - BOOST_TEST(testR(S("abcdefghijklmnopqrst"), 20, 1, "12345678901234567890", 20, S("abcdefghijklmnopqrst12345678901234567890"))); + BOOST_TEST(testR("", 0, 0, "", "")); + BOOST_TEST(testR("", 0, 0, "12345", "12345")); + BOOST_TEST(testR("", 0, 0, "1234567890", "1234567890")); + BOOST_TEST(testR("", 0, 0, "12345678901234567890", "12345678901234567890")); + BOOST_TEST(testR("abcde", 0, 0, "", "abcde")); + BOOST_TEST(testR("abcde", 0, 0, "12345", "12345abcde")); + BOOST_TEST(testR("abcde", 0, 0, "1234567890", "1234567890abcde")); + BOOST_TEST(testR("abcde", 0, 0, "12345678901234567890", "12345678901234567890abcde")); + BOOST_TEST(testR("abcde", 0, 1, "", "bcde")); + BOOST_TEST(testR("abcde", 0, 1, "12345", "12345bcde")); + BOOST_TEST(testR("abcde", 0, 1, "1234567890", "1234567890bcde")); + BOOST_TEST(testR("abcde", 0, 1, "12345678901234567890", "12345678901234567890bcde")); + BOOST_TEST(testR("abcde", 0, 2, "", "cde")); + BOOST_TEST(testR("abcde", 0, 2, "12345", "12345cde")); + BOOST_TEST(testR("abcde", 0, 2, "1234567890", "1234567890cde")); + BOOST_TEST(testR("abcde", 0, 2, "12345678901234567890", "12345678901234567890cde")); + BOOST_TEST(testR("abcde", 0, 4, "", "e")); + BOOST_TEST(testR("abcde", 0, 4, "12345", "12345e")); + BOOST_TEST(testR("abcde", 0, 4, "1234567890", "1234567890e")); + BOOST_TEST(testR("abcde", 0, 4, "12345678901234567890", "12345678901234567890e")); + BOOST_TEST(testR("abcde", 0, 5, "", "")); + BOOST_TEST(testR("abcde", 0, 5, "12345", "12345")); + BOOST_TEST(testR("abcde", 0, 5, "1234567890", "1234567890")); + BOOST_TEST(testR("abcde", 0, 5, "12345678901234567890", "12345678901234567890")); + BOOST_TEST(testR("abcde", 1, 0, "", "abcde")); + BOOST_TEST(testR("abcde", 1, 0, "12345", "a12345bcde")); + BOOST_TEST(testR("abcde", 1, 0, "1234567890", "a1234567890bcde")); + BOOST_TEST(testR("abcde", 1, 0, "12345678901234567890", "a12345678901234567890bcde")); + BOOST_TEST(testR("abcde", 1, 1, "", "acde")); + BOOST_TEST(testR("abcde", 1, 1, "12345", "a12345cde")); + BOOST_TEST(testR("abcde", 1, 1, "1234567890", "a1234567890cde")); + BOOST_TEST(testR("abcde", 1, 1, "12345678901234567890", "a12345678901234567890cde")); + BOOST_TEST(testR("abcde", 1, 2, "", "ade")); + BOOST_TEST(testR("abcde", 1, 2, "12345", "a12345de")); + BOOST_TEST(testR("abcde", 1, 2, "1234567890", "a1234567890de")); + BOOST_TEST(testR("abcde", 1, 2, "12345678901234567890", "a12345678901234567890de")); + BOOST_TEST(testR("abcde", 1, 3, "", "ae")); + BOOST_TEST(testR("abcde", 1, 3, "12345", "a12345e")); + BOOST_TEST(testR("abcde", 1, 3, "1234567890", "a1234567890e")); + BOOST_TEST(testR("abcde", 1, 3, "12345678901234567890", "a12345678901234567890e")); + BOOST_TEST(testR("abcde", 1, 4, "", "a")); + BOOST_TEST(testR("abcde", 1, 4, "12345", "a12345")); + BOOST_TEST(testR("abcde", 1, 4, "1234567890", "a1234567890")); + BOOST_TEST(testR("abcde", 1, 4, "12345678901234567890", "a12345678901234567890")); + BOOST_TEST(testR("abcde", 2, 0, "", "abcde")); + BOOST_TEST(testR("abcde", 2, 0, "12345", "ab12345cde")); + BOOST_TEST(testR("abcde", 2, 0, "1234567890", "ab1234567890cde")); + BOOST_TEST(testR("abcde", 2, 0, "12345678901234567890", "ab12345678901234567890cde")); + BOOST_TEST(testR("abcde", 2, 1, "", "abde")); + BOOST_TEST(testR("abcde", 2, 1, "12345", "ab12345de")); + BOOST_TEST(testR("abcde", 2, 1, "1234567890", "ab1234567890de")); + BOOST_TEST(testR("abcde", 2, 1, "12345678901234567890", "ab12345678901234567890de")); + BOOST_TEST(testR("abcde", 2, 2, "", "abe")); + BOOST_TEST(testR("abcde", 2, 2, "12345", "ab12345e")); + BOOST_TEST(testR("abcde", 2, 2, "1234567890", "ab1234567890e")); + BOOST_TEST(testR("abcde", 2, 2, "12345678901234567890", "ab12345678901234567890e")); + BOOST_TEST(testR("abcde", 2, 3, "", "ab")); + BOOST_TEST(testR("abcde", 2, 3, "12345", "ab12345")); + BOOST_TEST(testR("abcde", 2, 3, "1234567890", "ab1234567890")); + BOOST_TEST(testR("abcde", 2, 3, "12345678901234567890", "ab12345678901234567890")); + BOOST_TEST(testR("abcde", 4, 0, "", "abcde")); + BOOST_TEST(testR("abcde", 4, 0, "12345", "abcd12345e")); + BOOST_TEST(testR("abcde", 4, 0, "1234567890", "abcd1234567890e")); + BOOST_TEST(testR("abcde", 4, 0, "12345678901234567890", "abcd12345678901234567890e")); + BOOST_TEST(testR("abcde", 4, 1, "", "abcd")); + BOOST_TEST(testR("abcde", 4, 1, "12345", "abcd12345")); + BOOST_TEST(testR("abcde", 4, 1, "1234567890", "abcd1234567890")); + BOOST_TEST(testR("abcde", 4, 1, "12345678901234567890", "abcd12345678901234567890")); + BOOST_TEST(testR("abcde", 5, 0, "", "abcde")); + BOOST_TEST(testR("abcde", 5, 0, "12345", "abcde12345")); + BOOST_TEST(testR("abcde", 5, 0, "1234567890", "abcde1234567890")); + BOOST_TEST(testR("abcde", 5, 0, "12345678901234567890", "abcde12345678901234567890")); + BOOST_TEST(testR("abcdefghij", 0, 0, "", "abcdefghij")); + BOOST_TEST(testR("abcdefghij", 0, 0, "12345", "12345abcdefghij")); + BOOST_TEST(testR("abcdefghij", 0, 0, "1234567890", "1234567890abcdefghij")); + BOOST_TEST(testR("abcdefghij", 0, 0, "12345678901234567890", "12345678901234567890abcdefghij")); + BOOST_TEST(testR("abcdefghij", 0, 1, "", "bcdefghij")); + BOOST_TEST(testR("abcdefghij", 0, 1, "12345", "12345bcdefghij")); + BOOST_TEST(testR("abcdefghij", 0, 1, "1234567890", "1234567890bcdefghij")); + BOOST_TEST(testR("abcdefghij", 0, 1, "12345678901234567890", "12345678901234567890bcdefghij")); + BOOST_TEST(testR("abcdefghij", 0, 5, "", "fghij")); + BOOST_TEST(testR("abcdefghij", 0, 5, "12345", "12345fghij")); + BOOST_TEST(testR("abcdefghij", 0, 5, "1234567890", "1234567890fghij")); + BOOST_TEST(testR("abcdefghij", 0, 5, "12345678901234567890", "12345678901234567890fghij")); + BOOST_TEST(testR("abcdefghij", 0, 9, "", "j")); + BOOST_TEST(testR("abcdefghij", 0, 9, "12345", "12345j")); + BOOST_TEST(testR("abcdefghij", 0, 9, "1234567890", "1234567890j")); + BOOST_TEST(testR("abcdefghij", 0, 9, "12345678901234567890", "12345678901234567890j")); + BOOST_TEST(testR("abcdefghij", 0, 10, "", "")); + BOOST_TEST(testR("abcdefghij", 0, 10, "12345", "12345")); + BOOST_TEST(testR("abcdefghij", 0, 10, "1234567890", "1234567890")); + BOOST_TEST(testR("abcdefghij", 0, 10, "12345678901234567890", "12345678901234567890")); + BOOST_TEST(testR("abcdefghij", 1, 0, "", "abcdefghij")); + BOOST_TEST(testR("abcdefghij", 1, 0, "12345", "a12345bcdefghij")); + BOOST_TEST(testR("abcdefghij", 1, 0, "1234567890", "a1234567890bcdefghij")); + BOOST_TEST(testR("abcdefghij", 1, 0, "12345678901234567890", "a12345678901234567890bcdefghij")); + BOOST_TEST(testR("abcdefghij", 1, 1, "", "acdefghij")); + BOOST_TEST(testR("abcdefghij", 1, 1, "12345", "a12345cdefghij")); + BOOST_TEST(testR("abcdefghij", 1, 1, "1234567890", "a1234567890cdefghij")); + BOOST_TEST(testR("abcdefghij", 1, 1, "12345678901234567890", "a12345678901234567890cdefghij")); + BOOST_TEST(testR("", 0, 0, 0, '2', "")); + BOOST_TEST(testR("", 0, 0, 5, '2', "22222")); + BOOST_TEST(testR("", 0, 0, 10, '2', "2222222222")); + BOOST_TEST(testR("", 0, 0, 20, '2', "22222222222222222222")); + BOOST_TEST(testR("", 0, 1, 0, '2', "")); + BOOST_TEST(testR("", 0, 1, 5, '2', "22222")); + BOOST_TEST(testR("", 0, 1, 10, '2', "2222222222")); + BOOST_TEST(testR("", 0, 1, 20, '2', "22222222222222222222")); + BOOST_TEST(testR("abcde", 0, 0, 0, '2', "abcde")); + BOOST_TEST(testR("abcde", 0, 0, 5, '2', "22222abcde")); + BOOST_TEST(testR("abcde", 0, 0, 10, '2', "2222222222abcde")); + BOOST_TEST(testR("abcde", 0, 0, 20, '2', "22222222222222222222abcde")); + BOOST_TEST(testR("abcde", 0, 1, 0, '2', "bcde")); + BOOST_TEST(testR("abcde", 0, 1, 5, '2', "22222bcde")); + BOOST_TEST(testR("abcde", 0, 1, 10, '2', "2222222222bcde")); + BOOST_TEST(testR("abcde", 0, 1, 20, '2', "22222222222222222222bcde")); + BOOST_TEST(testR("abcde", 0, 2, 0, '2', "cde")); + BOOST_TEST(testR("abcde", 0, 2, 5, '2', "22222cde")); + BOOST_TEST(testR("abcde", 0, 2, 10, '2', "2222222222cde")); + BOOST_TEST(testR("abcde", 0, 2, 20, '2', "22222222222222222222cde")); + BOOST_TEST(testR("abcde", 0, 4, 0, '2', "e")); + BOOST_TEST(testR("abcde", 0, 4, 5, '2', "22222e")); + BOOST_TEST(testR("abcde", 0, 4, 10, '2', "2222222222e")); + BOOST_TEST(testR("abcde", 0, 4, 20, '2', "22222222222222222222e")); + BOOST_TEST(testR("abcde", 0, 5, 0, '2', "")); + BOOST_TEST(testR("abcde", 0, 5, 5, '2', "22222")); + BOOST_TEST(testR("abcde", 0, 5, 10, '2', "2222222222")); + BOOST_TEST(testR("abcde", 0, 5, 20, '2', "22222222222222222222")); + BOOST_TEST(testR("abcde", 0, 6, 0, '2', "")); + BOOST_TEST(testR("abcde", 0, 6, 5, '2', "22222")); + BOOST_TEST(testR("abcde", 0, 6, 10, '2', "2222222222")); + BOOST_TEST(testR("abcde", 0, 6, 20, '2', "22222222222222222222")); + BOOST_TEST(testR("abcde", 1, 0, 0, '2', "abcde")); + BOOST_TEST(testR("abcde", 1, 0, 5, '2', "a22222bcde")); + BOOST_TEST(testR("abcde", 1, 0, 10, '2', "a2222222222bcde")); + BOOST_TEST(testR("abcde", 1, 0, 20, '2', "a22222222222222222222bcde")); + BOOST_TEST(testR("abcde", 1, 1, 0, '2', "acde")); + BOOST_TEST(testR("abcde", 1, 1, 5, '2', "a22222cde")); + BOOST_TEST(testR("abcde", 1, 1, 10, '2', "a2222222222cde")); + BOOST_TEST(testR("abcde", 1, 1, 20, '2', "a22222222222222222222cde")); + BOOST_TEST(testR("abcde", 1, 2, 0, '2', "ade")); + BOOST_TEST(testR("abcde", 1, 2, 5, '2', "a22222de")); + BOOST_TEST(testR("abcde", 1, 2, 10, '2', "a2222222222de")); + BOOST_TEST(testR("abcde", 1, 2, 20, '2', "a22222222222222222222de")); + BOOST_TEST(testR("abcde", 1, 3, 0, '2', "ae")); + BOOST_TEST(testR("abcde", 1, 3, 5, '2', "a22222e")); + BOOST_TEST(testR("abcde", 1, 3, 10, '2', "a2222222222e")); + BOOST_TEST(testR("abcde", 1, 3, 20, '2', "a22222222222222222222e")); + BOOST_TEST(testR("abcde", 1, 4, 0, '2', "a")); + BOOST_TEST(testR("abcde", 1, 4, 5, '2', "a22222")); + BOOST_TEST(testR("abcde", 1, 4, 10, '2', "a2222222222")); + BOOST_TEST(testR("abcde", 1, 4, 20, '2', "a22222222222222222222")); + BOOST_TEST(testR("abcde", 1, 5, 0, '2', "a")); + BOOST_TEST(testR("abcde", 1, 5, 5, '2', "a22222")); + BOOST_TEST(testR("abcde", 1, 5, 10, '2', "a2222222222")); + BOOST_TEST(testR("abcde", 1, 5, 20, '2', "a22222222222222222222")); + BOOST_TEST(testR("abcde", 2, 0, 0, '2', "abcde")); + BOOST_TEST(testR("abcde", 2, 0, 5, '2', "ab22222cde")); + BOOST_TEST(testR("abcde", 2, 0, 10, '2', "ab2222222222cde")); + BOOST_TEST(testR("abcde", 2, 0, 20, '2', "ab22222222222222222222cde")); + BOOST_TEST(testR("abcde", 2, 1, 0, '2', "abde")); + BOOST_TEST(testR("abcde", 2, 1, 5, '2', "ab22222de")); + BOOST_TEST(testR("abcde", 2, 1, 10, '2', "ab2222222222de")); + BOOST_TEST(testR("abcde", 2, 1, 20, '2', "ab22222222222222222222de")); + BOOST_TEST(testR("abcde", 2, 2, 0, '2', "abe")); + BOOST_TEST(testR("abcde", 2, 2, 5, '2', "ab22222e")); + BOOST_TEST(testR("abcde", 2, 2, 10, '2', "ab2222222222e")); + BOOST_TEST(testR("abcde", 2, 2, 20, '2', "ab22222222222222222222e")); + BOOST_TEST(testR("abcde", 2, 3, 0, '2', "ab")); + BOOST_TEST(testR("abcde", 2, 3, 5, '2', "ab22222")); + BOOST_TEST(testR("abcde", 2, 3, 10, '2', "ab2222222222")); + BOOST_TEST(testR("abcde", 2, 3, 20, '2', "ab22222222222222222222")); + BOOST_TEST(testR("abcde", 2, 4, 0, '2', "ab")); + BOOST_TEST(testR("abcde", 2, 4, 5, '2', "ab22222")); + BOOST_TEST(testR("abcde", 2, 4, 10, '2', "ab2222222222")); + BOOST_TEST(testR("abcde", 2, 4, 20, '2', "ab22222222222222222222")); + BOOST_TEST(testR("abcde", 4, 0, 0, '2', "abcde")); + BOOST_TEST(testR("abcde", 4, 0, 5, '2', "abcd22222e")); + BOOST_TEST(testR("abcde", 4, 0, 10, '2', "abcd2222222222e")); + BOOST_TEST(testR("abcde", 4, 0, 20, '2', "abcd22222222222222222222e")); + BOOST_TEST(testR("abcde", 4, 1, 0, '2', "abcd")); + BOOST_TEST(testR("abcde", 4, 1, 5, '2', "abcd22222")); + BOOST_TEST(testR("abcde", 4, 1, 10, '2', "abcd2222222222")); + BOOST_TEST(testR("abcde", 4, 1, 20, '2', "abcd22222222222222222222")); + BOOST_TEST(testR("abcde", 4, 2, 0, '2', "abcd")); + + BOOST_TEST(testR("abcde", 4, 2, 5, '2', "abcd22222")); + BOOST_TEST(testR("abcde", 4, 2, 10, '2', "abcd2222222222")); + BOOST_TEST(testR("abcde", 4, 2, 20, '2', "abcd22222222222222222222")); + + BOOST_TEST(testR("abcde", 5, 0, 0, '2', "abcde")); + BOOST_TEST(testR("abcde", 5, 0, 5, '2', "abcde22222")); + BOOST_TEST(testR("abcde", 5, 0, 10, '2', "abcde2222222222")); + BOOST_TEST(testR("abcde", 5, 0, 20, '2', "abcde22222222222222222222")); + + BOOST_TEST(testR("abcde", 5, 1, 0, '2', "abcde")); + BOOST_TEST(testR("abcde", 5, 1, 5, '2', "abcde22222")); + BOOST_TEST(testR("abcde", 5, 1, 10, '2', "abcde2222222222")); + BOOST_TEST(testR("abcde", 5, 1, 20, '2', "abcde22222222222222222222")); + + BOOST_TEST(testR("abcde", 0, 4, "12345", 4, "1234e")); + BOOST_TEST(testR("abcde", 0, 4, "12345", 5, "12345e")); + BOOST_TEST(testR("abcde", 0, 4, "1234567890", 0, "e")); + BOOST_TEST(testR("abcde", 0, 4, "1234567890", 1, "1e")); + BOOST_TEST(testR("abcde", 0, 4, "1234567890", 5, "12345e")); + BOOST_TEST(testR("abcde", 0, 4, "1234567890", 9, "123456789e")); + BOOST_TEST(testR("abcde", 0, 4, "1234567890", 10, "1234567890e")); + BOOST_TEST(testR("abcde", 0, 4, "12345678901234567890", 0, "e")); + BOOST_TEST(testR("abcde", 0, 4, "12345678901234567890", 1, "1e")); + BOOST_TEST(testR("abcde", 0, 4, "12345678901234567890", 10, "1234567890e")); + BOOST_TEST(testR("abcde", 0, 4, "12345678901234567890", 19, "1234567890123456789e")); + BOOST_TEST(testR("abcde", 0, 4, "12345678901234567890", 20, "12345678901234567890e")); + BOOST_TEST(testR("abcde", 0, 5, "", 0, "")); + BOOST_TEST(testR("abcde", 0, 5, "12345", 0, "")); + BOOST_TEST(testR("abcde", 0, 5, "12345", 1, "1")); + BOOST_TEST(testR("abcde", 0, 5, "12345", 2, "12")); + BOOST_TEST(testR("abcde", 0, 5, "12345", 4, "1234")); + BOOST_TEST(testR("abcde", 0, 5, "12345", 5, "12345")); + BOOST_TEST(testR("abcde", 0, 5, "1234567890", 0, "")); + BOOST_TEST(testR("abcde", 0, 5, "1234567890", 1, "1")); + BOOST_TEST(testR("abcde", 0, 5, "1234567890", 5, "12345")); + BOOST_TEST(testR("abcde", 0, 5, "1234567890", 9, "123456789")); + BOOST_TEST(testR("abcde", 0, 5, "1234567890", 10, "1234567890")); + BOOST_TEST(testR("abcde", 0, 5, "12345678901234567890", 0, "")); + BOOST_TEST(testR("abcde", 0, 5, "12345678901234567890", 1, "1")); + BOOST_TEST(testR("abcde", 0, 5, "12345678901234567890", 10, "1234567890")); + BOOST_TEST(testR("abcde", 0, 5, "12345678901234567890", 19, "1234567890123456789")); + BOOST_TEST(testR("abcde", 0, 5, "12345678901234567890", 20, "12345678901234567890")); + BOOST_TEST(testR("abcde", 0, 6, "", 0, "")); + BOOST_TEST(testR("abcde", 0, 6, "12345", 0, "")); + BOOST_TEST(testR("abcde", 0, 6, "12345", 1, "1")); + BOOST_TEST(testR("abcde", 0, 6, "12345", 2, "12")); + BOOST_TEST(testR("abcde", 0, 6, "12345", 4, "1234")); + BOOST_TEST(testR("abcde", 0, 6, "12345", 5, "12345")); + BOOST_TEST(testR("abcde", 0, 6, "1234567890", 0, "")); + BOOST_TEST(testR("abcde", 0, 6, "1234567890", 1, "1")); + BOOST_TEST(testR("abcde", 0, 6, "1234567890", 5, "12345")); + BOOST_TEST(testR("abcde", 0, 6, "1234567890", 9, "123456789")); + BOOST_TEST(testR("abcde", 0, 6, "1234567890", 10, "1234567890")); + BOOST_TEST(testR("abcde", 0, 6, "12345678901234567890", 0, "")); + BOOST_TEST(testR("abcde", 0, 6, "12345678901234567890", 1, "1")); + BOOST_TEST(testR("abcde", 0, 6, "12345678901234567890", 10, "1234567890")); + BOOST_TEST(testR("abcde", 0, 6, "12345678901234567890", 19, "1234567890123456789")); + BOOST_TEST(testR("abcde", 0, 6, "12345678901234567890", 20, "12345678901234567890")); + BOOST_TEST(testR("abcde", 1, 0, "", 0, "abcde")); + BOOST_TEST(testR("abcde", 1, 0, "12345", 0, "abcde")); + BOOST_TEST(testR("abcde", 1, 0, "12345", 1, "a1bcde")); + BOOST_TEST(testR("abcde", 1, 0, "12345", 2, "a12bcde")); + BOOST_TEST(testR("abcde", 1, 0, "12345", 4, "a1234bcde")); + BOOST_TEST(testR("abcde", 1, 0, "12345", 5, "a12345bcde")); + BOOST_TEST(testR("abcde", 1, 0, "1234567890", 0, "abcde")); + BOOST_TEST(testR("abcde", 1, 0, "1234567890", 1, "a1bcde")); + BOOST_TEST(testR("abcde", 1, 0, "1234567890", 5, "a12345bcde")); + BOOST_TEST(testR("abcde", 1, 0, "1234567890", 9, "a123456789bcde")); + BOOST_TEST(testR("abcde", 1, 0, "1234567890", 10, "a1234567890bcde")); + BOOST_TEST(testR("abcde", 1, 0, "12345678901234567890", 0, "abcde")); + BOOST_TEST(testR("abcde", 1, 0, "12345678901234567890", 1, "a1bcde")); + BOOST_TEST(testR("abcde", 1, 0, "12345678901234567890", 10, "a1234567890bcde")); + BOOST_TEST(testR("abcde", 1, 0, "12345678901234567890", 19, "a1234567890123456789bcde")); + BOOST_TEST(testR("abcde", 1, 0, "12345678901234567890", 20, "a12345678901234567890bcde")); + BOOST_TEST(testR("abcde", 1, 1, "", 0, "acde")); + BOOST_TEST(testR("abcde", 1, 1, "12345", 0, "acde")); + BOOST_TEST(testR("abcde", 1, 1, "12345", 1, "a1cde")); + BOOST_TEST(testR("abcde", 1, 1, "12345", 2, "a12cde")); + BOOST_TEST(testR("abcde", 1, 1, "12345", 4, "a1234cde")); + BOOST_TEST(testR("abcde", 1, 1, "12345", 5, "a12345cde")); + BOOST_TEST(testR("abcde", 1, 1, "1234567890", 0, "acde")); + BOOST_TEST(testR("abcde", 1, 1, "1234567890", 1, "a1cde")); + BOOST_TEST(testR("abcde", 1, 1, "1234567890", 5, "a12345cde")); + BOOST_TEST(testR("abcde", 1, 1, "1234567890", 9, "a123456789cde")); + BOOST_TEST(testR("abcde", 1, 1, "1234567890", 10, "a1234567890cde")); + BOOST_TEST(testR("abcde", 1, 1, "12345678901234567890", 0, "acde")); + BOOST_TEST(testR("abcde", 1, 1, "12345678901234567890", 1, "a1cde")); + BOOST_TEST(testR("abcde", 1, 1, "12345678901234567890", 10, "a1234567890cde")); + BOOST_TEST(testR("abcde", 1, 1, "12345678901234567890", 19, "a1234567890123456789cde")); + BOOST_TEST(testR("abcde", 1, 1, "12345678901234567890", 20, "a12345678901234567890cde")); + BOOST_TEST(testR("abcde", 1, 2, "", 0, "ade")); + BOOST_TEST(testR("abcde", 1, 2, "12345", 0, "ade")); + BOOST_TEST(testR("abcde", 1, 2, "12345", 1, "a1de")); + BOOST_TEST(testR("abcde", 1, 2, "12345", 2, "a12de")); + BOOST_TEST(testR("abcde", 1, 2, "12345", 4, "a1234de")); + BOOST_TEST(testR("abcde", 1, 2, "12345", 5, "a12345de")); + BOOST_TEST(testR("abcde", 1, 2, "1234567890", 0, "ade")); + BOOST_TEST(testR("abcde", 1, 2, "1234567890", 1, "a1de")); + BOOST_TEST(testR("abcde", 1, 2, "1234567890", 5, "a12345de")); + BOOST_TEST(testR("abcde", 1, 2, "1234567890", 9, "a123456789de")); + BOOST_TEST(testR("abcde", 1, 2, "1234567890", 10, "a1234567890de")); + BOOST_TEST(testR("abcde", 1, 2, "12345678901234567890", 0, "ade")); + BOOST_TEST(testR("abcde", 1, 2, "12345678901234567890", 1, "a1de")); + BOOST_TEST(testR("abcde", 1, 2, "12345678901234567890", 10, "a1234567890de")); + BOOST_TEST(testR("abcde", 1, 2, "12345678901234567890", 19, "a1234567890123456789de")); + BOOST_TEST(testR("abcde", 1, 2, "12345678901234567890", 20, "a12345678901234567890de")); + BOOST_TEST(testR("abcde", 1, 3, "", 0, "ae")); + BOOST_TEST(testR("abcde", 1, 3, "12345", 0, "ae")); + BOOST_TEST(testR("abcde", 1, 3, "12345", 1, "a1e")); + BOOST_TEST(testR("abcde", 1, 3, "12345", 2, "a12e")); + BOOST_TEST(testR("abcde", 1, 3, "12345", 4, "a1234e")); + BOOST_TEST(testR("abcde", 1, 3, "12345", 5, "a12345e")); + BOOST_TEST(testR("abcde", 1, 3, "1234567890", 0, "ae")); + BOOST_TEST(testR("abcde", 1, 3, "1234567890", 1, "a1e")); + BOOST_TEST(testR("abcdefghij", 1, 10, "1234567890", 5, "a12345")); + BOOST_TEST(testR("abcdefghij", 1, 10, "1234567890", 9, "a123456789")); + BOOST_TEST(testR("abcdefghij", 1, 10, "1234567890", 10, "a1234567890")); + BOOST_TEST(testR("abcdefghij", 1, 10, "12345678901234567890", 0, "a")); + BOOST_TEST(testR("abcdefghij", 1, 10, "12345678901234567890", 1, "a1")); + BOOST_TEST(testR("abcdefghij", 1, 10, "12345678901234567890", 10, "a1234567890")); + BOOST_TEST(testR("abcdefghij", 1, 10, "12345678901234567890", 19, "a1234567890123456789")); + BOOST_TEST(testR("abcdefghij", 1, 10, "12345678901234567890", 20, "a12345678901234567890")); + BOOST_TEST(testR("abcdefghij", 5, 0, "", 0, "abcdefghij")); + BOOST_TEST(testR("abcdefghij", 5, 0, "12345", 0, "abcdefghij")); + BOOST_TEST(testR("abcdefghij", 5, 0, "12345", 1, "abcde1fghij")); + BOOST_TEST(testR("abcdefghij", 5, 0, "12345", 2, "abcde12fghij")); + BOOST_TEST(testR("abcdefghij", 5, 0, "12345", 4, "abcde1234fghij")); + BOOST_TEST(testR("abcdefghij", 5, 0, "12345", 5, "abcde12345fghij")); + BOOST_TEST(testR("abcdefghij", 5, 0, "1234567890", 0, "abcdefghij")); + BOOST_TEST(testR("abcdefghij", 5, 0, "1234567890", 1, "abcde1fghij")); + BOOST_TEST(testR("abcdefghij", 5, 0, "1234567890", 5, "abcde12345fghij")); + BOOST_TEST(testR("abcdefghij", 5, 0, "1234567890", 9, "abcde123456789fghij")); + BOOST_TEST(testR("abcdefghij", 5, 0, "1234567890", 10, "abcde1234567890fghij")); + BOOST_TEST(testR("abcdefghij", 5, 0, "12345678901234567890", 0, "abcdefghij")); + BOOST_TEST(testR("abcdefghij", 5, 0, "12345678901234567890", 1, "abcde1fghij")); + BOOST_TEST(testR("abcdefghij", 5, 0, "12345678901234567890", 10, "abcde1234567890fghij")); + BOOST_TEST(testR("abcdefghij", 5, 0, "12345678901234567890", 19, "abcde1234567890123456789fghij")); + BOOST_TEST(testR("abcdefghij", 5, 0, "12345678901234567890", 20, "abcde12345678901234567890fghij")); + BOOST_TEST(testR("abcdefghij", 5, 1, "", 0, "abcdeghij")); + BOOST_TEST(testR("abcdefghij", 5, 1, "12345", 0, "abcdeghij")); + BOOST_TEST(testR("abcdefghij", 5, 1, "12345", 1, "abcde1ghij")); + BOOST_TEST(testR("abcdefghij", 5, 1, "12345", 2, "abcde12ghij")); + BOOST_TEST(testR("abcdefghij", 5, 1, "12345", 4, "abcde1234ghij")); + BOOST_TEST(testR("abcdefghij", 5, 1, "12345", 5, "abcde12345ghij")); + BOOST_TEST(testR("abcdefghij", 5, 1, "1234567890", 0, "abcdeghij")); + BOOST_TEST(testR("abcdefghij", 5, 1, "1234567890", 1, "abcde1ghij")); + BOOST_TEST(testR("abcdefghij", 5, 1, "1234567890", 5, "abcde12345ghij")); + BOOST_TEST(testR("abcdefghij", 5, 1, "1234567890", 9, "abcde123456789ghij")); + BOOST_TEST(testR("abcdefghij", 5, 1, "1234567890", 10, "abcde1234567890ghij")); + BOOST_TEST(testR("abcdefghij", 5, 1, "12345678901234567890", 0, "abcdeghij")); + BOOST_TEST(testR("abcdefghij", 5, 1, "12345678901234567890", 1, "abcde1ghij")); + BOOST_TEST(testR("abcdefghij", 5, 1, "12345678901234567890", 10, "abcde1234567890ghij")); + BOOST_TEST(testR("abcdefghij", 5, 1, "12345678901234567890", 19, "abcde1234567890123456789ghij")); + BOOST_TEST(testR("abcdefghij", 5, 1, "12345678901234567890", 20, "abcde12345678901234567890ghij")); + BOOST_TEST(testR("abcdefghij", 5, 2, "", 0, "abcdehij")); + BOOST_TEST(testR("abcdefghij", 5, 2, "12345", 0, "abcdehij")); + BOOST_TEST(testR("abcdefghij", 5, 2, "12345", 1, "abcde1hij")); + BOOST_TEST(testR("abcdefghij", 5, 2, "12345", 2, "abcde12hij")); + BOOST_TEST(testR("abcdefghij", 5, 2, "12345", 4, "abcde1234hij")); + BOOST_TEST(testR("abcdefghij", 5, 2, "12345", 5, "abcde12345hij")); + BOOST_TEST(testR("abcdefghij", 5, 2, "1234567890", 0, "abcdehij")); + BOOST_TEST(testR("abcdefghij", 5, 2, "1234567890", 1, "abcde1hij")); + BOOST_TEST(testR("abcdefghij", 5, 2, "1234567890", 5, "abcde12345hij")); + BOOST_TEST(testR("abcdefghij", 5, 2, "1234567890", 9, "abcde123456789hij")); + BOOST_TEST(testR("abcdefghij", 5, 2, "1234567890", 10, "abcde1234567890hij")); + BOOST_TEST(testR("abcdefghij", 5, 2, "12345678901234567890", 0, "abcdehij")); + BOOST_TEST(testR("abcdefghij", 5, 2, "12345678901234567890", 1, "abcde1hij")); + BOOST_TEST(testR("abcdefghij", 5, 2, "12345678901234567890", 10, "abcde1234567890hij")); + BOOST_TEST(testR("abcdefghij", 5, 2, "12345678901234567890", 19, "abcde1234567890123456789hij")); + BOOST_TEST(testR("abcdefghij", 5, 2, "12345678901234567890", 20, "abcde12345678901234567890hij")); + BOOST_TEST(testR("abcdefghij", 5, 4, "", 0, "abcdej")); + BOOST_TEST(testR("abcdefghij", 5, 4, "12345", 0, "abcdej")); + BOOST_TEST(testR("abcdefghij", 5, 4, "12345", 1, "abcde1j")); + BOOST_TEST(testR("abcdefghij", 5, 4, "12345", 2, "abcde12j")); + BOOST_TEST(testR("abcdefghij", 5, 4, "12345", 4, "abcde1234j")); + BOOST_TEST(testR("abcdefghij", 5, 4, "12345", 5, "abcde12345j")); + BOOST_TEST(testR("abcdefghij", 5, 4, "1234567890", 0, "abcdej")); + BOOST_TEST(testR("abcdefghij", 5, 4, "1234567890", 1, "abcde1j")); + BOOST_TEST(testR("abcdefghij", 5, 4, "1234567890", 5, "abcde12345j")); + BOOST_TEST(testR("abcdefghij", 5, 4, "1234567890", 9, "abcde123456789j")); + BOOST_TEST(testR("abcdefghij", 5, 4, "1234567890", 10, "abcde1234567890j")); + BOOST_TEST(testR("abcdefghij", 5, 4, "12345678901234567890", 0, "abcdej")); + BOOST_TEST(testR("abcdefghij", 5, 4, "12345678901234567890", 1, "abcde1j")); + BOOST_TEST(testR("abcdefghij", 5, 4, "12345678901234567890", 10, "abcde1234567890j")); + BOOST_TEST(testR("abcdefghij", 5, 4, "12345678901234567890", 19, "abcde1234567890123456789j")); + BOOST_TEST(testR("abcdefghij", 5, 4, "12345678901234567890", 20, "abcde12345678901234567890j")); + BOOST_TEST(testR("abcdefghij", 5, 5, "", 0, "abcde")); + BOOST_TEST(testR("abcdefghij", 5, 5, "12345", 0, "abcde")); + BOOST_TEST(testR("abcdefghij", 5, 5, "12345", 1, "abcde1")); + BOOST_TEST(testR("abcdefghij", 5, 5, "12345", 2, "abcde12")); + BOOST_TEST(testR("abcdefghij", 5, 5, "12345", 4, "abcde1234")); + BOOST_TEST(testR("abcdefghij", 5, 5, "12345", 5, "abcde12345")); + BOOST_TEST(testR("abcdefghij", 5, 5, "1234567890", 0, "abcde")); + BOOST_TEST(testR("abcdefghij", 5, 5, "1234567890", 1, "abcde1")); + BOOST_TEST(testR("abcdefghij", 5, 5, "1234567890", 5, "abcde12345")); + BOOST_TEST(testR("abcdefghij", 5, 5, "1234567890", 9, "abcde123456789")); + BOOST_TEST(testR("abcdefghij", 5, 5, "1234567890", 10, "abcde1234567890")); + BOOST_TEST(testR("abcdefghij", 5, 5, "12345678901234567890", 0, "abcde")); + BOOST_TEST(testR("abcdefghij", 5, 5, "12345678901234567890", 1, "abcde1")); + BOOST_TEST(testR("abcdefghij", 5, 5, "12345678901234567890", 10, "abcde1234567890")); + BOOST_TEST(testR("abcdefghij", 5, 5, "12345678901234567890", 19, "abcde1234567890123456789")); + BOOST_TEST(testR("abcdefghij", 5, 5, "12345678901234567890", 20, "abcde12345678901234567890")); + BOOST_TEST(testR("abcdefghij", 5, 6, "", 0, "abcde")); + BOOST_TEST(testR("abcdefghij", 5, 6, "12345", 0, "abcde")); + BOOST_TEST(testR("abcdefghij", 5, 6, "12345", 1, "abcde1")); + BOOST_TEST(testR("abcdefghij", 5, 6, "12345", 2, "abcde12")); + BOOST_TEST(testR("abcdefghij", 5, 6, "12345", 4, "abcde1234")); + BOOST_TEST(testR("abcdefghij", 5, 6, "12345", 5, "abcde12345")); + BOOST_TEST(testR("abcdefghij", 5, 6, "1234567890", 0, "abcde")); + BOOST_TEST(testR("abcdefghij", 5, 6, "1234567890", 1, "abcde1")); + BOOST_TEST(testR("abcdefghij", 5, 6, "1234567890", 5, "abcde12345")); + BOOST_TEST(testR("abcdefghij", 5, 6, "1234567890", 9, "abcde123456789")); + BOOST_TEST(testR("abcdefghij", 5, 6, "1234567890", 10, "abcde1234567890")); + BOOST_TEST(testR("abcdefghij", 5, 6, "12345678901234567890", 0, "abcde")); + BOOST_TEST(testR("abcdefghijklmnopqrst", 0, 0, "", 0, "abcdefghijklmnopqrst")); + BOOST_TEST(testR("abcdefghijklmnopqrst", 0, 0, "12345", 0, "abcdefghijklmnopqrst")); + BOOST_TEST(testR("abcdefghijklmnopqrst", 0, 0, "12345", 1, "1abcdefghijklmnopqrst")); + BOOST_TEST(testR("abcdefghijklmnopqrst", 0, 0, "12345", 2, "12abcdefghijklmnopqrst")); + BOOST_TEST(testR("abcdefghijklmnopqrst", 0, 0, "12345", 4, "1234abcdefghijklmnopqrst")); + BOOST_TEST(testR("abcdefghijklmnopqrst", 0, 0, "12345", 5, "12345abcdefghijklmnopqrst")); + BOOST_TEST(testR("abcdefghijklmnopqrst", 0, 0, "1234567890", 0, "abcdefghijklmnopqrst")); + BOOST_TEST(testR("abcdefghijklmnopqrst", 0, 0, "1234567890", 1, "1abcdefghijklmnopqrst")); + BOOST_TEST(testR("abcdefghijklmnopqrst", 0, 0, "1234567890", 5, "12345abcdefghijklmnopqrst")); + BOOST_TEST(testR("abcdefghijklmnopqrst", 0, 0, "1234567890", 9, "123456789abcdefghijklmnopqrst")); + BOOST_TEST(testR("abcdefghijklmnopqrst", 0, 0, "1234567890", 10, "1234567890abcdefghijklmnopqrst")); + BOOST_TEST(testR("abcdefghijklmnopqrst", 0, 0, "12345678901234567890", 0, "abcdefghijklmnopqrst")); + BOOST_TEST(testR("abcdefghijklmnopqrst", 0, 0, "12345678901234567890", 1, "1abcdefghijklmnopqrst")); + BOOST_TEST(testR("abcdefghijklmnopqrst", 0, 0, "12345678901234567890", 10, "1234567890abcdefghijklmnopqrst")); + BOOST_TEST(testR("abcdefghijklmnopqrst", 0, 0, "12345678901234567890", 19, "1234567890123456789abcdefghijklmnopqrst")); + BOOST_TEST(testR("abcdefghijklmnopqrst", 0, 0, "12345678901234567890", 20, "12345678901234567890abcdefghijklmnopqrst")); + BOOST_TEST(testR("abcdefghijklmnopqrst", 0, 1, "", 0, "bcdefghijklmnopqrst")); + BOOST_TEST(testR("abcdefghijklmnopqrst", 0, 1, "12345", 0, "bcdefghijklmnopqrst")); + BOOST_TEST(testR("abcdefghijklmnopqrst", 0, 1, "12345", 1, "1bcdefghijklmnopqrst")); + BOOST_TEST(testR("abcdefghijklmnopqrst", 0, 1, "12345", 2, "12bcdefghijklmnopqrst")); + BOOST_TEST(testR("abcdefghijklmnopqrst", 0, 1, "12345", 4, "1234bcdefghijklmnopqrst")); + BOOST_TEST(testR("abcdefghijklmnopqrst", 0, 1, "12345", 5, "12345bcdefghijklmnopqrst")); + BOOST_TEST(testR("abcdefghijklmnopqrst", 0, 1, "1234567890", 0, "bcdefghijklmnopqrst")); + BOOST_TEST(testR("abcdefghijklmnopqrst", 0, 1, "1234567890", 1, "1bcdefghijklmnopqrst")); + BOOST_TEST(testR("abcdefghijklmnopqrst", 0, 1, "1234567890", 5, "12345bcdefghijklmnopqrst")); + BOOST_TEST(testR("abcdefghijklmnopqrst", 0, 1, "1234567890", 9, "123456789bcdefghijklmnopqrst")); + BOOST_TEST(testR("abcdefghijklmnopqrst", 0, 1, "1234567890", 10, "1234567890bcdefghijklmnopqrst")); + BOOST_TEST(testR("abcdefghijklmnopqrst", 0, 1, "12345678901234567890", 0, "bcdefghijklmnopqrst")); + BOOST_TEST(testR("abcdefghijklmnopqrst", 0, 1, "12345678901234567890", 1, "1bcdefghijklmnopqrst")); + BOOST_TEST(testR("abcdefghijklmnopqrst", 0, 1, "12345678901234567890", 10, "1234567890bcdefghijklmnopqrst")); + BOOST_TEST(testR("abcdefghijklmnopqrst", 0, 1, "12345678901234567890", 19, "1234567890123456789bcdefghijklmnopqrst")); + BOOST_TEST(testR("abcdefghijklmnopqrst", 0, 1, "12345678901234567890", 20, "12345678901234567890bcdefghijklmnopqrst")); + BOOST_TEST(testR("abcdefghijklmnopqrst", 0, 10, "", 0, "klmnopqrst")); + BOOST_TEST(testR("abcdefghijklmnopqrst", 0, 10, "12345", 0, "klmnopqrst")); + BOOST_TEST(testR("abcdefghijklmnopqrst", 0, 10, "12345", 1, "1klmnopqrst")); + BOOST_TEST(testR("abcdefghijklmnopqrst", 0, 10, "12345", 2, "12klmnopqrst")); + BOOST_TEST(testR("abcdefghijklmnopqrst", 0, 10, "12345", 4, "1234klmnopqrst")); + BOOST_TEST(testR("abcdefghijklmnopqrst", 0, 10, "12345", 5, "12345klmnopqrst")); + BOOST_TEST(testR("abcdefghijklmnopqrst", 0, 10, "1234567890", 0, "klmnopqrst")); + BOOST_TEST(testR("abcdefghijklmnopqrst", 0, 10, "1234567890", 1, "1klmnopqrst")); + BOOST_TEST(testR("abcdefghijklmnopqrst", 0, 10, "1234567890", 5, "12345klmnopqrst")); + BOOST_TEST(testR("abcdefghijklmnopqrst", 0, 10, "1234567890", 9, "123456789klmnopqrst")); + BOOST_TEST(testR("abcdefghijklmnopqrst", 0, 10, "1234567890", 10, "1234567890klmnopqrst")); + BOOST_TEST(testR("abcdefghijklmnopqrst", 0, 10, "12345678901234567890", 0, "klmnopqrst")); + BOOST_TEST(testR("abcdefghijklmnopqrst", 0, 10, "12345678901234567890", 1, "1klmnopqrst")); + BOOST_TEST(testR("abcdefghijklmnopqrst", 0, 10, "12345678901234567890", 10, "1234567890klmnopqrst")); + BOOST_TEST(testR("abcdefghijklmnopqrst", 0, 10, "12345678901234567890", 19, "1234567890123456789klmnopqrst")); + BOOST_TEST(testR("abcdefghijklmnopqrst", 0, 10, "12345678901234567890", 20, "12345678901234567890klmnopqrst")); + BOOST_TEST(testR("abcdefghijklmnopqrst", 0, 19, "", 0, "t")); + BOOST_TEST(testR("abcdefghijklmnopqrst", 0, 19, "12345", 0, "t")); + BOOST_TEST(testR("abcdefghijklmnopqrst", 0, 19, "12345", 1, "1t")); + BOOST_TEST(testR("abcdefghijklmnopqrst", 0, 19, "12345", 2, "12t")); + BOOST_TEST(testR("abcdefghijklmnopqrst", 0, 19, "12345", 4, "1234t")); + BOOST_TEST(testR("abcdefghijklmnopqrst", 0, 19, "12345", 5, "12345t")); + BOOST_TEST(testR("abcdefghijklmnopqrst", 0, 19, "1234567890", 0, "t")); + BOOST_TEST(testR("abcdefghijklmnopqrst", 0, 19, "1234567890", 1, "1t")); + BOOST_TEST(testR("abcdefghijklmnopqrst", 0, 19, "1234567890", 5, "12345t")); + BOOST_TEST(testR("abcdefghijklmnopqrst", 0, 19, "1234567890", 9, "123456789t")); + BOOST_TEST(testR("abcdefghijklmnopqrst", 0, 19, "1234567890", 10, "1234567890t")); + BOOST_TEST(testR("abcdefghijklmnopqrst", 0, 19, "12345678901234567890", 0, "t")); + BOOST_TEST(testR("abcdefghijklmnopqrst", 0, 19, "12345678901234567890", 1, "1t")); + BOOST_TEST(testR("abcdefghijklmnopqrst", 0, 19, "12345678901234567890", 10, "1234567890t")); + BOOST_TEST(testR("abcdefghijklmnopqrst", 0, 19, "12345678901234567890", 19, "1234567890123456789t")); + BOOST_TEST(testR("abcdefghijklmnopqrst", 0, 19, "12345678901234567890", 20, "12345678901234567890t")); + BOOST_TEST(testR("abcdefghijklmnopqrst", 0, 20, "", 0, "")); + BOOST_TEST(testR("abcdefghijklmnopqrst", 0, 20, "12345", 0, "")); + BOOST_TEST(testR("abcdefghijklmnopqrst", 0, 20, "12345", 1, "1")); + BOOST_TEST(testR("abcdefghijklmnopqrst", 0, 20, "12345", 2, "12")); + BOOST_TEST(testR("abcdefghijklmnopqrst", 0, 20, "12345", 4, "1234")); + BOOST_TEST(testR("abcdefghijklmnopqrst", 0, 20, "12345", 5, "12345")); + BOOST_TEST(testR("abcdefghijklmnopqrst", 0, 20, "1234567890", 0, "")); + BOOST_TEST(testR("abcdefghijklmnopqrst", 0, 20, "1234567890", 1, "1")); + BOOST_TEST(testR("abcdefghijklmnopqrst", 0, 20, "1234567890", 5, "12345")); + BOOST_TEST(testR("abcdefghijklmnopqrst", 0, 20, "1234567890", 9, "123456789")); + BOOST_TEST(testR("abcdefghijklmnopqrst", 0, 20, "1234567890", 10, "1234567890")); + BOOST_TEST(testR("abcdefghijklmnopqrst", 0, 20, "12345678901234567890", 0, "")); + BOOST_TEST(testR("abcdefghijklmnopqrst", 0, 20, "12345678901234567890", 1, "1")); + BOOST_TEST(testR("abcdefghijklmnopqrst", 0, 20, "12345678901234567890", 10, "1234567890")); + BOOST_TEST(testR("abcdefghijklmnopqrst", 0, 20, "12345678901234567890", 19, "1234567890123456789")); + BOOST_TEST(testR("abcdefghijklmnopqrst", 0, 20, "12345678901234567890", 20, "12345678901234567890")); + BOOST_TEST(testR("abcdefghijklmnopqrst", 0, 21, "", 0, "")); + BOOST_TEST(testR("abcdefghijklmnopqrst", 0, 21, "12345", 0, "")); + BOOST_TEST(testR("abcdefghijklmnopqrst", 0, 21, "12345", 1, "1")); + BOOST_TEST(testR("abcdefghijklmnopqrst", 0, 21, "12345", 2, "12")); + BOOST_TEST(testR("abcdefghijklmnopqrst", 0, 21, "12345", 4, "1234")); + BOOST_TEST(testR("abcdefghijklmnopqrst", 0, 21, "12345", 5, "12345")); + BOOST_TEST(testR("abcdefghijklmnopqrst", 0, 21, "1234567890", 0, "")); + BOOST_TEST(testR("abcdefghijklmnopqrst", 0, 21, "1234567890", 1, "1")); + BOOST_TEST(testR("abcdefghijklmnopqrst", 0, 21, "1234567890", 5, "12345")); + BOOST_TEST(testR("abcdefghijklmnopqrst", 0, 21, "1234567890", 9, "123456789")); + BOOST_TEST(testR("abcdefghijklmnopqrst", 0, 21, "1234567890", 10, "1234567890")); + BOOST_TEST(testR("abcdefghijklmnopqrst", 0, 21, "12345678901234567890", 0, "")); + BOOST_TEST(testR("abcdefghijklmnopqrst", 0, 21, "12345678901234567890", 1, "1")); + BOOST_TEST(testR("abcdefghijklmnopqrst", 0, 21, "12345678901234567890", 10, "1234567890")); + BOOST_TEST(testR("abcdefghijklmnopqrst", 0, 21, "12345678901234567890", 19, "1234567890123456789")); + BOOST_TEST(testR("abcdefghijklmnopqrst", 0, 21, "12345678901234567890", 20, "12345678901234567890")); + BOOST_TEST(testR("abcdefghijklmnopqrst", 1, 0, "", 0, "abcdefghijklmnopqrst")); + BOOST_TEST(testR("abcdefghijklmnopqrst", 1, 0, "12345", 0, "abcdefghijklmnopqrst")); + BOOST_TEST(testR("abcdefghijklmnopqrst", 1, 0, "12345", 1, "a1bcdefghijklmnopqrst")); + BOOST_TEST(testR("abcdefghijklmnopqrst", 1, 0, "12345", 2, "a12bcdefghijklmnopqrst")); + BOOST_TEST(testR("abcdefghijklmnopqrst", 1, 0, "12345", 4, "a1234bcdefghijklmnopqrst")); + BOOST_TEST(testR("abcdefghijklmnopqrst", 1, 0, "12345", 5, "a12345bcdefghijklmnopqrst")); + BOOST_TEST(testR("abcdefghijklmnopqrst", 1, 0, "1234567890", 0, "abcdefghijklmnopqrst")); + BOOST_TEST(testR("abcdefghijklmnopqrst", 1, 0, "1234567890", 1, "a1bcdefghijklmnopqrst")); + BOOST_TEST(testR("abcdefghijklmnopqrst", 1, 0, "1234567890", 5, "a12345bcdefghijklmnopqrst")); + BOOST_TEST(testR("abcdefghijklmnopqrst", 1, 0, "1234567890", 9, "a123456789bcdefghijklmnopqrst")); + BOOST_TEST(testR("abcdefghijklmnopqrst", 1, 0, "1234567890", 10, "a1234567890bcdefghijklmnopqrst")); + BOOST_TEST(testR("abcdefghijklmnopqrst", 1, 0, "12345678901234567890", 0, "abcdefghijklmnopqrst")); + BOOST_TEST(testR("abcdefghijklmnopqrst", 1, 0, "12345678901234567890", 1, "a1bcdefghijklmnopqrst")); + BOOST_TEST(testR("abcdefghijklmnopqrst", 1, 0, "12345678901234567890", 10, "a1234567890bcdefghijklmnopqrst")); + BOOST_TEST(testR("abcdefghijklmnopqrst", 1, 0, "12345678901234567890", 19, "a1234567890123456789bcdefghijklmnopqrst")); + BOOST_TEST(testR("abcdefghijklmnopqrst", 1, 0, "12345678901234567890", 20, "a12345678901234567890bcdefghijklmnopqrst")); + BOOST_TEST(testR("abcdefghijklmnopqrst", 1, 1, "", 0, "acdefghijklmnopqrst")); + BOOST_TEST(testR("abcdefghijklmnopqrst", 1, 1, "12345", 0, "acdefghijklmnopqrst")); + BOOST_TEST(testR("abcdefghijklmnopqrst", 1, 1, "12345", 1, "a1cdefghijklmnopqrst")); + BOOST_TEST(testR("abcdefghijklmnopqrst", 1, 1, "12345", 2, "a12cdefghijklmnopqrst")); + BOOST_TEST(testR("abcdefghijklmnopqrst", 1, 1, "12345", 4, "a1234cdefghijklmnopqrst")); + BOOST_TEST(testR("abcdefghijklmnopqrst", 1, 1, "12345", 5, "a12345cdefghijklmnopqrst")); + BOOST_TEST(testR("abcdefghijklmnopqrst", 1, 1, "1234567890", 0, "acdefghijklmnopqrst")); + BOOST_TEST(testR("abcdefghijklmnopqrst", 1, 1, "1234567890", 1, "a1cdefghijklmnopqrst")); + BOOST_TEST(testR("abcdefghijklmnopqrst", 1, 1, "1234567890", 5, "a12345cdefghijklmnopqrst")); + BOOST_TEST(testR("abcdefghijklmnopqrst", 1, 1, "1234567890", 9, "a123456789cdefghijklmnopqrst")); + BOOST_TEST(testR("abcdefghijklmnopqrst", 1, 1, "1234567890", 10, "a1234567890cdefghijklmnopqrst")); + BOOST_TEST(testR("abcdefghijklmnopqrst", 1, 1, "12345678901234567890", 0, "acdefghijklmnopqrst")); + BOOST_TEST(testR("abcdefghijklmnopqrst", 1, 1, "12345678901234567890", 1, "a1cdefghijklmnopqrst")); + BOOST_TEST(testR("abcdefghijklmnopqrst", 1, 1, "12345678901234567890", 10, "a1234567890cdefghijklmnopqrst")); + BOOST_TEST(testR("abcdefghijklmnopqrst", 1, 1, "12345678901234567890", 19, "a1234567890123456789cdefghijklmnopqrst")); + BOOST_TEST(testR("abcdefghijklmnopqrst", 1, 1, "12345678901234567890", 20, "a12345678901234567890cdefghijklmnopqrst")); + BOOST_TEST(testR("abcdefghijklmnopqrst", 1, 9, "", 0, "aklmnopqrst")); + BOOST_TEST(testR("abcdefghijklmnopqrst", 1, 9, "12345", 0, "aklmnopqrst")); + BOOST_TEST(testR("abcdefghijklmnopqrst", 1, 9, "12345", 1, "a1klmnopqrst")); + BOOST_TEST(testR("abcdefghijklmnopqrst", 1, 9, "12345", 2, "a12klmnopqrst")); + BOOST_TEST(testR("abcdefghijklmnopqrst", 1, 9, "12345", 4, "a1234klmnopqrst")); + BOOST_TEST(testR("abcdefghijklmnopqrst", 1, 9, "12345", 5, "a12345klmnopqrst")); + BOOST_TEST(testR("abcdefghijklmnopqrst", 1, 9, "1234567890", 0, "aklmnopqrst")); + BOOST_TEST(testR("abcdefghijklmnopqrst", 1, 9, "1234567890", 1, "a1klmnopqrst")); + BOOST_TEST(testR("abcdefghijklmnopqrst", 1, 9, "1234567890", 5, "a12345klmnopqrst")); + BOOST_TEST(testR("abcdefghijklmnopqrst", 1, 9, "1234567890", 9, "a123456789klmnopqrst")); + BOOST_TEST(testR("abcdefghijklmnopqrst", 1, 9, "1234567890", 10, "a1234567890klmnopqrst")); + BOOST_TEST(testR("abcdefghijklmnopqrst", 1, 9, "12345678901234567890", 0, "aklmnopqrst")); + BOOST_TEST(testR("abcdefghijklmnopqrst", 1, 9, "12345678901234567890", 1, "a1klmnopqrst")); + BOOST_TEST(testR("abcdefghijklmnopqrst", 1, 9, "12345678901234567890", 10, "a1234567890klmnopqrst")); + BOOST_TEST(testR("abcdefghijklmnopqrst", 1, 9, "12345678901234567890", 19, "a1234567890123456789klmnopqrst")); + BOOST_TEST(testR("abcdefghijklmnopqrst", 1, 9, "12345678901234567890", 20, "a12345678901234567890klmnopqrst")); + BOOST_TEST(testR("abcdefghijklmnopqrst", 1, 18, "", 0, "at")); + BOOST_TEST(testR("abcdefghijklmnopqrst", 1, 18, "12345", 0, "at")); + BOOST_TEST(testR("abcdefghijklmnopqrst", 1, 18, "12345", 1, "a1t")); + BOOST_TEST(testR("abcdefghijklmnopqrst", 1, 18, "12345", 2, "a12t")); + BOOST_TEST(testR("abcdefghijklmnopqrst", 1, 18, "12345", 4, "a1234t")); + BOOST_TEST(testR("abcdefghijklmnopqrst", 1, 18, "12345", 5, "a12345t")); + BOOST_TEST(testR("abcdefghijklmnopqrst", 1, 18, "1234567890", 0, "at")); + BOOST_TEST(testR("abcdefghijklmnopqrst", 1, 18, "1234567890", 1, "a1t")); + BOOST_TEST(testR("abcdefghijklmnopqrst", 1, 18, "1234567890", 5, "a12345t")); + BOOST_TEST(testR("abcdefghijklmnopqrst", 1, 18, "1234567890", 9, "a123456789t")); + BOOST_TEST(testR("abcdefghijklmnopqrst", 1, 18, "1234567890", 10, "a1234567890t")); + BOOST_TEST(testR("abcdefghijklmnopqrst", 1, 18, "12345678901234567890", 0, "at")); + BOOST_TEST(testR("abcdefghijklmnopqrst", 1, 18, "12345678901234567890", 1, "a1t")); + BOOST_TEST(testR("abcdefghijklmnopqrst", 1, 18, "12345678901234567890", 10, "a1234567890t")); + BOOST_TEST(testR("abcdefghijklmnopqrst", 1, 18, "12345678901234567890", 19, "a1234567890123456789t")); + BOOST_TEST(testR("abcdefghijklmnopqrst", 1, 18, "12345678901234567890", 20, "a12345678901234567890t")); + BOOST_TEST(testR("abcdefghijklmnopqrst", 1, 19, "", 0, "a")); + BOOST_TEST(testR("abcdefghijklmnopqrst", 1, 19, "12345", 0, "a")); + BOOST_TEST(testR("abcdefghijklmnopqrst", 1, 19, "12345", 1, "a1")); + BOOST_TEST(testR("abcdefghijklmnopqrst", 1, 19, "12345", 2, "a12")); + BOOST_TEST(testR("abcdefghijklmnopqrst", 1, 19, "12345", 4, "a1234")); + BOOST_TEST(testR("abcdefghijklmnopqrst", 1, 19, "12345", 5, "a12345")); + BOOST_TEST(testR("abcdefghijklmnopqrst", 1, 19, "1234567890", 0, "a")); + BOOST_TEST(testR("abcdefghijklmnopqrst", 1, 19, "1234567890", 1, "a1")); + BOOST_TEST(testR("abcdefghijklmnopqrst", 1, 19, "1234567890", 5, "a12345")); + BOOST_TEST(testR("abcdefghijklmnopqrst", 1, 19, "1234567890", 9, "a123456789")); + BOOST_TEST(testR("abcdefghijklmnopqrst", 1, 19, "1234567890", 10, "a1234567890")); + BOOST_TEST(testR("abcdefghijklmnopqrst", 1, 19, "12345678901234567890", 0, "a")); + BOOST_TEST(testR("abcdefghijklmnopqrst", 1, 19, "12345678901234567890", 1, "a1")); + BOOST_TEST(testR("abcdefghijklmnopqrst", 1, 19, "12345678901234567890", 10, "a1234567890")); + BOOST_TEST(testR("abcdefghijklmnopqrst", 1, 19, "12345678901234567890", 19, "a1234567890123456789")); + BOOST_TEST(testR("abcdefghijklmnopqrst", 1, 19, "12345678901234567890", 20, "a12345678901234567890")); + BOOST_TEST(testR("abcdefghijklmnopqrst", 1, 20, "", 0, "a")); + BOOST_TEST(testR("abcdefghijklmnopqrst", 1, 20, "12345", 0, "a")); + BOOST_TEST(testR("abcdefghijklmnopqrst", 1, 20, "12345", 1, "a1")); + BOOST_TEST(testR("abcdefghijklmnopqrst", 1, 20, "12345", 2, "a12")); + BOOST_TEST(testR("abcdefghijklmnopqrst", 1, 20, "12345", 4, "a1234")); + BOOST_TEST(testR("abcdefghijklmnopqrst", 1, 20, "12345", 5, "a12345")); + BOOST_TEST(testR("abcdefghijklmnopqrst", 1, 20, "1234567890", 0, "a")); + BOOST_TEST(testR("abcdefghijklmnopqrst", 1, 20, "1234567890", 1, "a1")); + BOOST_TEST(testR("abcdefghijklmnopqrst", 1, 20, "1234567890", 5, "a12345")); + BOOST_TEST(testR("abcdefghijklmnopqrst", 1, 20, "1234567890", 9, "a123456789")); + BOOST_TEST(testR("abcdefghijklmnopqrst", 1, 20, "1234567890", 10, "a1234567890")); + BOOST_TEST(testR("abcdefghijklmnopqrst", 1, 20, "12345678901234567890", 0, "a")); + BOOST_TEST(testR("abcdefghijklmnopqrst", 1, 20, "12345678901234567890", 1, "a1")); + BOOST_TEST(testR("abcdefghijklmnopqrst", 1, 20, "12345678901234567890", 10, "a1234567890")); + BOOST_TEST(testR("abcdefghijklmnopqrst", 1, 20, "12345678901234567890", 19, "a1234567890123456789")); + BOOST_TEST(testR("abcdefghijklmnopqrst", 1, 20, "12345678901234567890", 20, "a12345678901234567890")); + BOOST_TEST(testR("abcdefghijklmnopqrst", 10, 0, "", 0, "abcdefghijklmnopqrst")); + BOOST_TEST(testR("abcdefghijklmnopqrst", 10, 0, "12345", 0, "abcdefghijklmnopqrst")); + BOOST_TEST(testR("abcdefghijklmnopqrst", 10, 0, "12345", 1, "abcdefghij1klmnopqrst")); + BOOST_TEST(testR("abcdefghijklmnopqrst", 10, 0, "12345", 2, "abcdefghij12klmnopqrst")); + BOOST_TEST(testR("abcdefghijklmnopqrst", 10, 0, "12345", 4, "abcdefghij1234klmnopqrst")); + BOOST_TEST(testR("abcdefghijklmnopqrst", 10, 0, "12345", 5, "abcdefghij12345klmnopqrst")); + BOOST_TEST(testR("abcdefghijklmnopqrst", 10, 0, "1234567890", 0, "abcdefghijklmnopqrst")); + BOOST_TEST(testR("abcdefghijklmnopqrst", 10, 0, "1234567890", 1, "abcdefghij1klmnopqrst")); + BOOST_TEST(testR("abcdefghijklmnopqrst", 10, 0, "1234567890", 5, "abcdefghij12345klmnopqrst")); + BOOST_TEST(testR("abcdefghijklmnopqrst", 10, 0, "1234567890", 9, "abcdefghij123456789klmnopqrst")); + BOOST_TEST(testR("abcdefghijklmnopqrst", 10, 0, "1234567890", 10, "abcdefghij1234567890klmnopqrst")); + BOOST_TEST(testR("abcdefghijklmnopqrst", 10, 0, "12345678901234567890", 0, "abcdefghijklmnopqrst")); + BOOST_TEST(testR("abcdefghijklmnopqrst", 10, 0, "12345678901234567890", 1, "abcdefghij1klmnopqrst")); + BOOST_TEST(testR("abcdefghijklmnopqrst", 10, 0, "12345678901234567890", 10, "abcdefghij1234567890klmnopqrst")); + BOOST_TEST(testR("abcdefghijklmnopqrst", 10, 0, "12345678901234567890", 19, "abcdefghij1234567890123456789klmnopqrst")); + BOOST_TEST(testR("abcdefghijklmnopqrst", 10, 0, "12345678901234567890", 20, "abcdefghij12345678901234567890klmnopqrst")); + BOOST_TEST(testR("abcdefghijklmnopqrst", 10, 1, "", 0, "abcdefghijlmnopqrst")); + BOOST_TEST(testR("abcdefghijklmnopqrst", 10, 1, "12345", 0, "abcdefghijlmnopqrst")); + BOOST_TEST(testR("abcdefghijklmnopqrst", 10, 1, "12345", 1, "abcdefghij1lmnopqrst")); + BOOST_TEST(testR("abcdefghijklmnopqrst", 10, 1, "12345", 2, "abcdefghij12lmnopqrst")); + BOOST_TEST(testR("abcdefghijklmnopqrst", 10, 1, "12345", 4, "abcdefghij1234lmnopqrst")); + BOOST_TEST(testR("abcdefghijklmnopqrst", 10, 1, "12345", 5, "abcdefghij12345lmnopqrst")); + BOOST_TEST(testR("abcdefghijklmnopqrst", 10, 1, "1234567890", 0, "abcdefghijlmnopqrst")); + BOOST_TEST(testR("abcdefghijklmnopqrst", 10, 1, "1234567890", 1, "abcdefghij1lmnopqrst")); + BOOST_TEST(testR("abcdefghijklmnopqrst", 10, 1, "1234567890", 5, "abcdefghij12345lmnopqrst")); + BOOST_TEST(testR("abcdefghijklmnopqrst", 10, 1, "1234567890", 9, "abcdefghij123456789lmnopqrst")); + BOOST_TEST(testR("abcdefghijklmnopqrst", 10, 1, "1234567890", 10, "abcdefghij1234567890lmnopqrst")); + BOOST_TEST(testR("abcdefghijklmnopqrst", 10, 1, "12345678901234567890", 0, "abcdefghijlmnopqrst")); + BOOST_TEST(testR("abcdefghijklmnopqrst", 10, 1, "12345678901234567890", 1, "abcdefghij1lmnopqrst")); + BOOST_TEST(testR("abcdefghijklmnopqrst", 10, 1, "12345678901234567890", 10, "abcdefghij1234567890lmnopqrst")); + BOOST_TEST(testR("abcdefghijklmnopqrst", 10, 1, "12345678901234567890", 19, "abcdefghij1234567890123456789lmnopqrst")); + BOOST_TEST(testR("abcdefghijklmnopqrst", 10, 1, "12345678901234567890", 20, "abcdefghij12345678901234567890lmnopqrst")); + BOOST_TEST(testR("abcdefghijklmnopqrst", 10, 5, "", 0, "abcdefghijpqrst")); + BOOST_TEST(testR("abcdefghijklmnopqrst", 10, 5, "12345", 0, "abcdefghijpqrst")); + BOOST_TEST(testR("abcdefghijklmnopqrst", 10, 5, "12345", 1, "abcdefghij1pqrst")); + BOOST_TEST(testR("abcdefghijklmnopqrst", 10, 5, "12345", 2, "abcdefghij12pqrst")); + BOOST_TEST(testR("abcdefghijklmnopqrst", 10, 5, "12345", 4, "abcdefghij1234pqrst")); + BOOST_TEST(testR("abcdefghijklmnopqrst", 10, 5, "12345", 5, "abcdefghij12345pqrst")); + BOOST_TEST(testR("abcdefghijklmnopqrst", 10, 5, "1234567890", 0, "abcdefghijpqrst")); + BOOST_TEST(testR("abcdefghijklmnopqrst", 10, 5, "1234567890", 1, "abcdefghij1pqrst")); + BOOST_TEST(testR("abcdefghijklmnopqrst", 10, 5, "1234567890", 5, "abcdefghij12345pqrst")); + BOOST_TEST(testR("abcdefghijklmnopqrst", 10, 5, "1234567890", 9, "abcdefghij123456789pqrst")); + BOOST_TEST(testR("abcdefghijklmnopqrst", 10, 5, "1234567890", 10, "abcdefghij1234567890pqrst")); + BOOST_TEST(testR("abcdefghijklmnopqrst", 10, 5, "12345678901234567890", 0, "abcdefghijpqrst")); + BOOST_TEST(testR("abcdefghijklmnopqrst", 10, 5, "12345678901234567890", 1, "abcdefghij1pqrst")); + BOOST_TEST(testR("abcdefghijklmnopqrst", 10, 5, "12345678901234567890", 10, "abcdefghij1234567890pqrst")); + BOOST_TEST(testR("abcdefghijklmnopqrst", 10, 5, "12345678901234567890", 19, "abcdefghij1234567890123456789pqrst")); + BOOST_TEST(testR("abcdefghijklmnopqrst", 10, 5, "12345678901234567890", 20, "abcdefghij12345678901234567890pqrst")); + BOOST_TEST(testR("abcdefghijklmnopqrst", 10, 9, "", 0, "abcdefghijt")); + BOOST_TEST(testR("abcdefghijklmnopqrst", 10, 9, "12345", 0, "abcdefghijt")); + BOOST_TEST(testR("abcdefghijklmnopqrst", 10, 9, "12345", 1, "abcdefghij1t")); + BOOST_TEST(testR("abcdefghijklmnopqrst", 10, 9, "12345", 2, "abcdefghij12t")); + BOOST_TEST(testR("abcdefghijklmnopqrst", 10, 9, "12345", 4, "abcdefghij1234t")); + BOOST_TEST(testR("abcdefghijklmnopqrst", 10, 9, "12345", 5, "abcdefghij12345t")); + BOOST_TEST(testR("abcdefghijklmnopqrst", 10, 9, "1234567890", 0, "abcdefghijt")); + BOOST_TEST(testR("abcdefghijklmnopqrst", 10, 9, "1234567890", 1, "abcdefghij1t")); + BOOST_TEST(testR("abcdefghijklmnopqrst", 10, 9, "1234567890", 5, "abcdefghij12345t")); + BOOST_TEST(testR("abcdefghijklmnopqrst", 10, 9, "1234567890", 9, "abcdefghij123456789t")); + BOOST_TEST(testR("abcdefghijklmnopqrst", 10, 9, "1234567890", 10, "abcdefghij1234567890t")); + BOOST_TEST(testR("abcdefghijklmnopqrst", 10, 9, "12345678901234567890", 0, "abcdefghijt")); + BOOST_TEST(testR("abcdefghijklmnopqrst", 10, 9, "12345678901234567890", 1, "abcdefghij1t")); + BOOST_TEST(testR("abcdefghijklmnopqrst", 10, 9, "12345678901234567890", 10, "abcdefghij1234567890t")); + BOOST_TEST(testR("abcdefghijklmnopqrst", 10, 9, "12345678901234567890", 19, "abcdefghij1234567890123456789t")); + BOOST_TEST(testR("abcdefghijklmnopqrst", 10, 9, "12345678901234567890", 20, "abcdefghij12345678901234567890t")); + BOOST_TEST(testR("abcdefghijklmnopqrst", 10, 10, "", 0, "abcdefghij")); + BOOST_TEST(testR("abcdefghijklmnopqrst", 10, 10, "12345", 0, "abcdefghij")); + BOOST_TEST(testR("abcdefghijklmnopqrst", 10, 10, "12345", 1, "abcdefghij1")); + BOOST_TEST(testR("abcdefghijklmnopqrst", 10, 10, "12345", 2, "abcdefghij12")); + BOOST_TEST(testR("abcdefghijklmnopqrst", 10, 10, "12345", 4, "abcdefghij1234")); + BOOST_TEST(testR("abcdefghijklmnopqrst", 10, 10, "12345", 5, "abcdefghij12345")); + BOOST_TEST(testR("abcdefghijklmnopqrst", 10, 10, "1234567890", 0, "abcdefghij")); + BOOST_TEST(testR("abcdefghijklmnopqrst", 10, 10, "1234567890", 1, "abcdefghij1")); + BOOST_TEST(testR("abcdefghijklmnopqrst", 10, 10, "1234567890", 5, "abcdefghij12345")); + BOOST_TEST(testR("abcdefghijklmnopqrst", 10, 10, "1234567890", 9, "abcdefghij123456789")); + BOOST_TEST(testR("abcdefghijklmnopqrst", 10, 10, "1234567890", 10, "abcdefghij1234567890")); + BOOST_TEST(testR("abcdefghijklmnopqrst", 10, 10, "12345678901234567890", 0, "abcdefghij")); + BOOST_TEST(testR("abcdefghijklmnopqrst", 10, 10, "12345678901234567890", 1, "abcdefghij1")); + BOOST_TEST(testR("abcdefghijklmnopqrst", 10, 10, "12345678901234567890", 10, "abcdefghij1234567890")); + BOOST_TEST(testR("abcdefghijklmnopqrst", 10, 10, "12345678901234567890", 19, "abcdefghij1234567890123456789")); + BOOST_TEST(testR("abcdefghijklmnopqrst", 10, 10, "12345678901234567890", 20, "abcdefghij12345678901234567890")); + BOOST_TEST(testR("abcdefghijklmnopqrst", 10, 11, "", 0, "abcdefghij")); + BOOST_TEST(testR("abcdefghijklmnopqrst", 10, 11, "12345", 0, "abcdefghij")); + BOOST_TEST(testR("abcdefghijklmnopqrst", 10, 11, "12345", 1, "abcdefghij1")); + BOOST_TEST(testR("abcdefghijklmnopqrst", 10, 11, "12345", 2, "abcdefghij12")); + BOOST_TEST(testR("abcdefghijklmnopqrst", 10, 11, "12345", 4, "abcdefghij1234")); + BOOST_TEST(testR("abcdefghijklmnopqrst", 10, 11, "12345", 5, "abcdefghij12345")); + BOOST_TEST(testR("abcdefghijklmnopqrst", 10, 11, "1234567890", 0, "abcdefghij")); + BOOST_TEST(testR("abcdefghijklmnopqrst", 10, 11, "1234567890", 1, "abcdefghij1")); + BOOST_TEST(testR("abcdefghijklmnopqrst", 10, 11, "1234567890", 5, "abcdefghij12345")); + BOOST_TEST(testR("abcdefghijklmnopqrst", 10, 11, "1234567890", 9, "abcdefghij123456789")); + BOOST_TEST(testR("abcdefghijklmnopqrst", 10, 11, "1234567890", 10, "abcdefghij1234567890")); + BOOST_TEST(testR("abcdefghijklmnopqrst", 10, 11, "12345678901234567890", 0, "abcdefghij")); + BOOST_TEST(testR("abcdefghijklmnopqrst", 10, 11, "12345678901234567890", 1, "abcdefghij1")); + BOOST_TEST(testR("abcdefghijklmnopqrst", 10, 11, "12345678901234567890", 10, "abcdefghij1234567890")); + BOOST_TEST(testR("abcdefghijklmnopqrst", 10, 11, "12345678901234567890", 19, "abcdefghij1234567890123456789")); + BOOST_TEST(testR("abcdefghijklmnopqrst", 10, 11, "12345678901234567890", 20, "abcdefghij12345678901234567890")); + BOOST_TEST(testR("abcdefghijklmnopqrst", 19, 0, "", 0, "abcdefghijklmnopqrst")); + BOOST_TEST(testR("abcdefghijklmnopqrst", 19, 0, "12345", 0, "abcdefghijklmnopqrst")); + BOOST_TEST(testR("abcdefghijklmnopqrst", 19, 0, "12345", 1, "abcdefghijklmnopqrs1t")); + BOOST_TEST(testR("abcdefghijklmnopqrst", 19, 0, "12345", 2, "abcdefghijklmnopqrs12t")); + BOOST_TEST(testR("abcdefghijklmnopqrst", 19, 0, "12345", 4, "abcdefghijklmnopqrs1234t")); + BOOST_TEST(testR("abcdefghijklmnopqrst", 19, 0, "12345", 5, "abcdefghijklmnopqrs12345t")); + BOOST_TEST(testR("abcdefghijklmnopqrst", 19, 0, "1234567890", 0, "abcdefghijklmnopqrst")); + BOOST_TEST(testR("abcdefghijklmnopqrst", 19, 0, "1234567890", 1, "abcdefghijklmnopqrs1t")); + BOOST_TEST(testR("abcdefghijklmnopqrst", 19, 0, "1234567890", 5, "abcdefghijklmnopqrs12345t")); + BOOST_TEST(testR("abcdefghijklmnopqrst", 19, 0, "1234567890", 9, "abcdefghijklmnopqrs123456789t")); + BOOST_TEST(testR("abcdefghijklmnopqrst", 19, 0, "1234567890", 10, "abcdefghijklmnopqrs1234567890t")); + BOOST_TEST(testR("abcdefghijklmnopqrst", 19, 0, "12345678901234567890", 0, "abcdefghijklmnopqrst")); + BOOST_TEST(testR("", 1, 0, "12345", 0, "can't happen")); + BOOST_TEST(testR("", 1, 0, "12345", 1, "can't happen")); + BOOST_TEST(testR("", 1, 0, "12345", 2, "can't happen")); + BOOST_TEST(testR("", 1, 0, "12345", 4, "can't happen")); + BOOST_TEST(testR("", 1, 0, "12345", 5, "can't happen")); + BOOST_TEST(testR("", 1, 0, "1234567890", 0, "can't happen")); + BOOST_TEST(testR("", 1, 0, "1234567890", 1, "can't happen")); + BOOST_TEST(testR("", 1, 0, "1234567890", 5, "can't happen")); + BOOST_TEST(testR("", 1, 0, "1234567890", 9, "can't happen")); + BOOST_TEST(testR("", 1, 0, "1234567890", 10, "can't happen")); + BOOST_TEST(testR("", 1, 0, "12345678901234567890", 0, "can't happen")); + BOOST_TEST(testR("", 1, 0, "12345678901234567890", 1, "can't happen")); + BOOST_TEST(testR("", 1, 0, "12345678901234567890", 10, "can't happen")); + BOOST_TEST(testR("", 1, 0, "12345678901234567890", 19, "can't happen")); + BOOST_TEST(testR("", 1, 0, "12345678901234567890", 20, "can't happen")); + BOOST_TEST(testR("abcde", 6, 0, "", 0, "can't happen")); + BOOST_TEST(testR("abcde", 6, 0, "12345", 0, "can't happen")); + BOOST_TEST(testR("abcde", 6, 0, "12345", 1, "can't happen")); + BOOST_TEST(testR("abcde", 6, 0, "12345", 2, "can't happen")); + BOOST_TEST(testR("abcde", 6, 0, "12345", 4, "can't happen")); + BOOST_TEST(testR("abcde", 6, 0, "12345", 5, "can't happen")); + BOOST_TEST(testR("abcde", 6, 0, "1234567890", 0, "can't happen")); + BOOST_TEST(testR("abcde", 6, 0, "1234567890", 1, "can't happen")); + BOOST_TEST(testR("abcde", 6, 0, "1234567890", 5, "can't happen")); + BOOST_TEST(testR("abcde", 6, 0, "1234567890", 9, "can't happen")); + BOOST_TEST(testR("abcde", 6, 0, "1234567890", 10, "can't happen")); + BOOST_TEST(testR("abcde", 6, 0, "12345678901234567890", 0, "can't happen")); + BOOST_TEST(testR("abcde", 6, 0, "12345678901234567890", 1, "can't happen")); + BOOST_TEST(testR("abcde", 6, 0, "12345678901234567890", 10, "can't happen")); + BOOST_TEST(testR("abcde", 6, 0, "12345678901234567890", 19, "can't happen")); + BOOST_TEST(testR("abcde", 6, 0, "12345678901234567890", 20, "can't happen")); + BOOST_TEST(testR("abcdefghij", 11, 0, "", 0, "can't happen")); + BOOST_TEST(testR("abcdefghij", 11, 0, "12345", 0, "can't happen")); + BOOST_TEST(testR("abcdefghij", 11, 0, "12345", 1, "can't happen")); + BOOST_TEST(testR("abcdefghij", 11, 0, "12345", 2, "can't happen")); + BOOST_TEST(testR("abcdefghij", 11, 0, "12345", 4, "can't happen")); + BOOST_TEST(testR("abcdefghij", 11, 0, "12345", 5, "can't happen")); + BOOST_TEST(testR("abcdefghij", 11, 0, "1234567890", 0, "can't happen")); + BOOST_TEST(testR("abcdefghij", 11, 0, "1234567890", 1, "can't happen")); + BOOST_TEST(testR("abcdefghij", 11, 0, "1234567890", 5, "can't happen")); + BOOST_TEST(testR("abcdefghij", 11, 0, "1234567890", 9, "can't happen")); + BOOST_TEST(testR("abcdefghij", 11, 0, "1234567890", 10, "can't happen")); + BOOST_TEST(testR("abcdefghij", 11, 0, "12345678901234567890", 0, "can't happen")); + BOOST_TEST(testR("abcdefghij", 11, 0, "12345678901234567890", 1, "can't happen")); + BOOST_TEST(testR("abcdefghij", 11, 0, "12345678901234567890", 10, "can't happen")); + BOOST_TEST(testR("abcdefghij", 11, 0, "12345678901234567890", 19, "can't happen")); + BOOST_TEST(testR("abcdefghij", 11, 0, "12345678901234567890", 20, "can't happen")); + BOOST_TEST(testR("abcdefghijklmnopqrst", 21, 0, "", 0, "can't happen")); + BOOST_TEST(testR("abcdefghijklmnopqrst", 21, 0, "12345", 0, "can't happen")); + BOOST_TEST(testR("abcdefghijklmnopqrst", 21, 0, "12345", 1, "can't happen")); + BOOST_TEST(testR("abcdefghijklmnopqrst", 21, 0, "12345", 2, "can't happen")); + BOOST_TEST(testR("abcdefghijklmnopqrst", 21, 0, "12345", 4, "can't happen")); + BOOST_TEST(testR("abcdefghijklmnopqrst", 21, 0, "12345", 5, "can't happen")); + BOOST_TEST(testR("abcdefghijklmnopqrst", 21, 0, "1234567890", 0, "can't happen")); + BOOST_TEST(testR("abcdefghijklmnopqrst", 21, 0, "1234567890", 1, "can't happen")); + BOOST_TEST(testR("abcdefghijklmnopqrst", 21, 0, "1234567890", 5, "can't happen")); + BOOST_TEST(testR("abcdefghijklmnopqrst", 21, 0, "1234567890", 9, "can't happen")); + BOOST_TEST(testR("abcdefghijklmnopqrst", 21, 0, "1234567890", 10, "can't happen")); + BOOST_TEST(testR("abcdefghijklmnopqrst", 21, 0, "12345678901234567890", 0, "can't happen")); + BOOST_TEST(testR("abcdefghijklmnopqrst", 21, 0, "12345678901234567890", 1, "can't happen")); + BOOST_TEST(testR("abcdefghijklmnopqrst", 21, 0, "12345678901234567890", 10, "can't happen")); + BOOST_TEST(testR("abcdefghijklmnopqrst", 21, 0, "12345678901234567890", 19, "can't happen")); + BOOST_TEST(testR("abcdefghijklmnopqrst", 21, 0, "12345678901234567890", 20, "can't happen")); + BOOST_TEST(testR("abcdefghijklmnopqrst", 19, 0, "12345678901234567890", 1, "abcdefghijklmnopqrs1t")); + BOOST_TEST(testR("abcdefghijklmnopqrst", 19, 0, "12345678901234567890", 10, "abcdefghijklmnopqrs1234567890t")); + BOOST_TEST(testR("abcdefghijklmnopqrst", 19, 0, "12345678901234567890", 19, "abcdefghijklmnopqrs1234567890123456789t")); + BOOST_TEST(testR("abcdefghijklmnopqrst", 19, 0, "12345678901234567890", 20, "abcdefghijklmnopqrs12345678901234567890t")); + BOOST_TEST(testR("abcdefghijklmnopqrst", 19, 1, "", 0, "abcdefghijklmnopqrs")); + BOOST_TEST(testR("abcdefghijklmnopqrst", 19, 1, "12345", 0, "abcdefghijklmnopqrs")); + BOOST_TEST(testR("abcdefghijklmnopqrst", 19, 1, "12345", 1, "abcdefghijklmnopqrs1")); + BOOST_TEST(testR("abcdefghijklmnopqrst", 19, 1, "12345", 2, "abcdefghijklmnopqrs12")); + BOOST_TEST(testR("abcdefghijklmnopqrst", 19, 1, "12345", 4, "abcdefghijklmnopqrs1234")); + BOOST_TEST(testR("abcdefghijklmnopqrst", 19, 1, "12345", 5, "abcdefghijklmnopqrs12345")); + BOOST_TEST(testR("abcdefghijklmnopqrst", 19, 1, "1234567890", 0, "abcdefghijklmnopqrs")); + BOOST_TEST(testR("abcdefghijklmnopqrst", 19, 1, "1234567890", 1, "abcdefghijklmnopqrs1")); + BOOST_TEST(testR("abcdefghijklmnopqrst", 19, 1, "1234567890", 5, "abcdefghijklmnopqrs12345")); + BOOST_TEST(testR("abcdefghijklmnopqrst", 19, 1, "1234567890", 9, "abcdefghijklmnopqrs123456789")); + BOOST_TEST(testR("abcdefghijklmnopqrst", 19, 1, "1234567890", 10, "abcdefghijklmnopqrs1234567890")); + BOOST_TEST(testR("abcdefghijklmnopqrst", 19, 1, "12345678901234567890", 0, "abcdefghijklmnopqrs")); + BOOST_TEST(testR("abcdefghijklmnopqrst", 19, 1, "12345678901234567890", 1, "abcdefghijklmnopqrs1")); + BOOST_TEST(testR("abcdefghijklmnopqrst", 19, 1, "12345678901234567890", 10, "abcdefghijklmnopqrs1234567890")); + BOOST_TEST(testR("abcdefghijklmnopqrst", 19, 1, "12345678901234567890", 19, "abcdefghijklmnopqrs1234567890123456789")); + BOOST_TEST(testR("abcdefghijklmnopqrst", 19, 1, "12345678901234567890", 20, "abcdefghijklmnopqrs12345678901234567890")); + BOOST_TEST(testR("abcdefghijklmnopqrst", 19, 2, "", 0, "abcdefghijklmnopqrs")); + BOOST_TEST(testR("abcdefghijklmnopqrst", 19, 2, "12345", 0, "abcdefghijklmnopqrs")); + BOOST_TEST(testR("abcdefghijklmnopqrst", 19, 2, "12345", 1, "abcdefghijklmnopqrs1")); + BOOST_TEST(testR("abcdefghijklmnopqrst", 19, 2, "12345", 2, "abcdefghijklmnopqrs12")); + BOOST_TEST(testR("abcdefghijklmnopqrst", 19, 2, "12345", 4, "abcdefghijklmnopqrs1234")); + BOOST_TEST(testR("abcdefghijklmnopqrst", 19, 2, "12345", 5, "abcdefghijklmnopqrs12345")); + BOOST_TEST(testR("abcdefghijklmnopqrst", 19, 2, "1234567890", 0, "abcdefghijklmnopqrs")); + BOOST_TEST(testR("abcdefghijklmnopqrst", 19, 2, "1234567890", 1, "abcdefghijklmnopqrs1")); + BOOST_TEST(testR("abcdefghijklmnopqrst", 19, 2, "1234567890", 5, "abcdefghijklmnopqrs12345")); + BOOST_TEST(testR("abcdefghijklmnopqrst", 19, 2, "1234567890", 9, "abcdefghijklmnopqrs123456789")); + BOOST_TEST(testR("abcdefghijklmnopqrst", 19, 2, "1234567890", 10, "abcdefghijklmnopqrs1234567890")); + BOOST_TEST(testR("abcdefghijklmnopqrst", 19, 2, "12345678901234567890", 0, "abcdefghijklmnopqrs")); + BOOST_TEST(testR("abcdefghijklmnopqrst", 19, 2, "12345678901234567890", 1, "abcdefghijklmnopqrs1")); + BOOST_TEST(testR("abcdefghijklmnopqrst", 19, 2, "12345678901234567890", 10, "abcdefghijklmnopqrs1234567890")); + BOOST_TEST(testR("abcdefghijklmnopqrst", 19, 2, "12345678901234567890", 19, "abcdefghijklmnopqrs1234567890123456789")); + BOOST_TEST(testR("abcdefghijklmnopqrst", 19, 2, "12345678901234567890", 20, "abcdefghijklmnopqrs12345678901234567890")); + BOOST_TEST(testR("abcdefghijklmnopqrst", 20, 0, "", 0, "abcdefghijklmnopqrst")); + BOOST_TEST(testR("abcdefghijklmnopqrst", 20, 0, "12345", 0, "abcdefghijklmnopqrst")); + BOOST_TEST(testR("abcdefghijklmnopqrst", 20, 0, "12345", 1, "abcdefghijklmnopqrst1")); + BOOST_TEST(testR("abcdefghijklmnopqrst", 20, 0, "12345", 2, "abcdefghijklmnopqrst12")); + BOOST_TEST(testR("abcdefghijklmnopqrst", 20, 0, "12345", 4, "abcdefghijklmnopqrst1234")); + BOOST_TEST(testR("abcdefghijklmnopqrst", 20, 0, "12345", 5, "abcdefghijklmnopqrst12345")); + BOOST_TEST(testR("abcdefghijklmnopqrst", 20, 0, "1234567890", 0, "abcdefghijklmnopqrst")); + BOOST_TEST(testR("abcdefghijklmnopqrst", 20, 0, "1234567890", 1, "abcdefghijklmnopqrst1")); + BOOST_TEST(testR("abcdefghijklmnopqrst", 20, 0, "1234567890", 5, "abcdefghijklmnopqrst12345")); + BOOST_TEST(testR("abcdefghijklmnopqrst", 20, 0, "1234567890", 9, "abcdefghijklmnopqrst123456789")); + BOOST_TEST(testR("abcdefghijklmnopqrst", 20, 0, "1234567890", 10, "abcdefghijklmnopqrst1234567890")); + BOOST_TEST(testR("abcdefghijklmnopqrst", 20, 0, "12345678901234567890", 0, "abcdefghijklmnopqrst")); + BOOST_TEST(testR("abcdefghijklmnopqrst", 20, 0, "12345678901234567890", 1, "abcdefghijklmnopqrst1")); + BOOST_TEST(testR("abcdefghijklmnopqrst", 20, 0, "12345678901234567890", 10, "abcdefghijklmnopqrst1234567890")); + BOOST_TEST(testR("abcdefghijklmnopqrst", 20, 0, "12345678901234567890", 19, "abcdefghijklmnopqrst1234567890123456789")); + BOOST_TEST(testR("abcdefghijklmnopqrst", 20, 0, "12345678901234567890", 20, "abcdefghijklmnopqrst12345678901234567890")); + BOOST_TEST(testR("abcdefghijklmnopqrst", 20, 1, "", 0, "abcdefghijklmnopqrst")); + BOOST_TEST(testR("abcdefghijklmnopqrst", 20, 1, "12345", 0, "abcdefghijklmnopqrst")); + BOOST_TEST(testR("abcdefghijklmnopqrst", 20, 1, "12345", 1, "abcdefghijklmnopqrst1")); + BOOST_TEST(testR("abcdefghijklmnopqrst", 20, 1, "12345", 2, "abcdefghijklmnopqrst12")); + BOOST_TEST(testR("abcdefghijklmnopqrst", 20, 1, "12345", 4, "abcdefghijklmnopqrst1234")); + BOOST_TEST(testR("abcdefghijklmnopqrst", 20, 1, "12345", 5, "abcdefghijklmnopqrst12345")); + BOOST_TEST(testR("abcdefghijklmnopqrst", 20, 1, "1234567890", 0, "abcdefghijklmnopqrst")); + BOOST_TEST(testR("abcdefghijklmnopqrst", 20, 1, "1234567890", 1, "abcdefghijklmnopqrst1")); + BOOST_TEST(testR("abcdefghijklmnopqrst", 20, 1, "1234567890", 5, "abcdefghijklmnopqrst12345")); + BOOST_TEST(testR("abcdefghijklmnopqrst", 20, 1, "1234567890", 9, "abcdefghijklmnopqrst123456789")); + BOOST_TEST(testR("abcdefghijklmnopqrst", 20, 1, "1234567890", 10, "abcdefghijklmnopqrst1234567890")); + BOOST_TEST(testR("abcdefghijklmnopqrst", 20, 1, "12345678901234567890", 0, "abcdefghijklmnopqrst")); + BOOST_TEST(testR("abcdefghijklmnopqrst", 20, 1, "12345678901234567890", 1, "abcdefghijklmnopqrst1")); + BOOST_TEST(testR("abcdefghijklmnopqrst", 20, 1, "12345678901234567890", 10, "abcdefghijklmnopqrst1234567890")); + BOOST_TEST(testR("abcdefghijklmnopqrst", 20, 1, "12345678901234567890", 19, "abcdefghijklmnopqrst1234567890123456789")); + BOOST_TEST(testR("abcdefghijklmnopqrst", 20, 1, "12345678901234567890", 20, "abcdefghijklmnopqrst12345678901234567890")); using T = static_string<10>; BOOST_TEST_THROWS(T("12345").replace(0, 1, 500, 'a'), std::length_error); From 17d77ef5bb091ac2cca6827b24f694cfede798eb Mon Sep 17 00:00:00 2001 From: Alexander Grund Date: Mon, 6 Oct 2025 15:12:23 +0200 Subject: [PATCH 37/73] Disable multi-arch CI job --- .github/workflows/ci.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 6eedc29..1765253 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -39,6 +39,7 @@ jobs: with: exclude_cxxstd: '98,03,0x,2c,26' enable_pr_coverage: false + enable_multiarch: false # Example of customization: # with: # enable_reflection: true From 0d255f74386a895df08acda33333b17e806fdc6d Mon Sep 17 00:00:00 2001 From: Alexander Grund Date: Sat, 4 Oct 2025 12:08:58 +0200 Subject: [PATCH 38/73] Appveyor: Update MinGW 32bit job Use the variant from Boost.CI Fixes #68 --- .appveyor.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.appveyor.yml b/.appveyor.yml index 7361f87..24bd7ab 100644 --- a/.appveyor.yml +++ b/.appveyor.yml @@ -107,10 +107,10 @@ environment: B2_CXXSTD: 11,14,1z B2_TOOLSET: gcc - - FLAVOR: mingw32 + - FLAVOR: mingw64 (32-bit) APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2019 + ADDPATH: C:\mingw-w64\i686-8.1.0-posix-dwarf-rt_v6-rev0\mingw32\bin; B2_ADDRESS_MODEL: 32 - ADDPATH: C:\mingw\bin; B2_CXXSTD: 11,14,17,2a B2_TOOLSET: gcc From cd1a1a41c39888c74a0b1e228508e95048d92e5f Mon Sep 17 00:00:00 2001 From: Gennaro Prota Date: Thu, 2 Oct 2025 19:07:16 +0200 Subject: [PATCH 39/73] Don't use an additional buffer in the arithmetic conversions In the case of the floating point conversions, this effectively avoids a copy of the buffer contents. In the case of the integer conversions, it doesn't eliminate the copy, but still removes the extra buffer. This fixes issue #65. --- include/boost/static_string/static_string.hpp | 103 ++++++++++++------ 1 file changed, 69 insertions(+), 34 deletions(-) diff --git a/include/boost/static_string/static_string.hpp b/include/boost/static_string/static_string.hpp index 71952e6..9ad7240 100644 --- a/include/boost/static_string/static_string.hpp +++ b/include/boost/static_string/static_string.hpp @@ -549,11 +549,14 @@ inline static_string to_static_string_int_impl(Integer value) noexcept { - char buffer[N]; - const auto digits_end = std::end(buffer); - const auto digits_begin = integer_to_string, Integer>( + static_string result; + char * const digits_end = result.data() + N; + char * const digits_begin = integer_to_string, Integer>( digits_end, value, std::is_signed{}); - return static_string(digits_begin, std::distance(digits_begin, digits_end)); + result.set_size(digits_end - digits_begin); + std::char_traits::move(result.data(), digits_begin, result.size()); + result.term(); + return result; } #ifdef BOOST_STATIC_STRING_HAS_WCHAR @@ -562,11 +565,14 @@ inline static_wstring to_static_wstring_int_impl(Integer value) noexcept { - wchar_t buffer[N]; - const auto digits_end = std::end(buffer); - const auto digits_begin = integer_to_wstring, Integer>( + static_wstring result; + wchar_t * const digits_end = result.data() + N; + wchar_t * const digits_begin = integer_to_wstring, Integer>( digits_end, value, std::is_signed{}); - return static_wstring(digits_begin, std::distance(digits_begin, digits_end)); + result.set_size(digits_end - digits_begin); + std::char_traits::move(result.data(), digits_begin, result.size()); + result.term(); + return result; } #endif @@ -595,11 +601,11 @@ to_static_string_float_impl(double value) noexcept // will require more than 2^63 chars to represent a float value. const long long narrow = static_cast(N); - // extra one needed for null terminator - char buffer[N + 1]; + static_string result; // we know that a formatting error will not occur, so // we assume that the result is always positive - if (std::size_t(std::snprintf(buffer, N + 1, "%f", value)) > N) + std::size_t length = std::snprintf(result.data(), N + 1, "%f", value); + if (length > N) { // the + 4 is for the decimal, 'e', // its sign, and the sign of the integral portion @@ -609,10 +615,10 @@ to_static_string_float_impl(double value) noexcept const int precision = narrow > reserved_count ? N - reserved_count : 0; // switch to scientific notation - std::snprintf(buffer, N + 1, "%.*e", precision, value); + length = std::snprintf(result.data(), N + 1, "%.*e", precision, value); } - // this will not throw - return static_string(buffer); + result.set_size(length); + return result; } template @@ -624,13 +630,13 @@ to_static_string_float_impl(long double value) noexcept // will require more than 2^63 chars to represent a float value. const long long narrow = static_cast(N); - // extra one needed for null terminator - char buffer[N + 1]; + static_string result; // snprintf returns the number of characters // that would have been written // we know that a formatting error will not occur, so // we assume that the result is always positive - if (std::size_t(std::snprintf(buffer, N + 1, "%Lf", value)) > N) + std::size_t length = std::snprintf(result.data(), N + 1, "%Lf", value); + if (length > N) { // the + 4 is for the decimal, 'e', // its sign, and the sign of the integral portion @@ -640,10 +646,10 @@ to_static_string_float_impl(long double value) noexcept const int precision = narrow > reserved_count ? N - reserved_count : 0; // switch to scientific notation - std::snprintf(buffer, N + 1, "%.*Le", precision, value); + length = std::snprintf(result.data(), N + 1, "%.*Le", precision, value); } - // this will not throw - return static_string(buffer); + result.set_size(length); + return result; } #ifdef BOOST_STATIC_STRING_HAS_WCHAR @@ -656,8 +662,7 @@ to_static_wstring_float_impl(double value) noexcept // will require more than 2^63 chars to represent a float value. const long long narrow = static_cast(N); - // extra one needed for null terminator - wchar_t buffer[N + 1]; + static_wstring result; // swprintf returns a negative number if it can't // fit all the characters in the buffer. // mingw has a non-standard swprintf, so @@ -665,8 +670,8 @@ to_static_wstring_float_impl(double value) noexcept // circuit evaluation will ensure that the // second operand is not evaluated on conforming // implementations. - const long long num_written = - std::swprintf(buffer, N + 1, L"%f", value); + long long num_written = + std::swprintf(result.data(), N + 1, L"%f", value); if (num_written < 0 || num_written > narrow) { @@ -678,10 +683,10 @@ to_static_wstring_float_impl(double value) noexcept const int precision = narrow > reserved_count ? N - reserved_count : 0; // switch to scientific notation - std::swprintf(buffer, N + 1, L"%.*e", precision, value); + num_written = std::swprintf(result.data(), N + 1, L"%.*e", precision, value); } - // this will not throw - return static_wstring(buffer); + result.set_size(static_cast(num_written)); + return result; } template @@ -693,8 +698,7 @@ to_static_wstring_float_impl(long double value) noexcept // will require more than 2^63 chars to represent a float value. const long long narrow = static_cast(N); - // extra one needed for null terminator - wchar_t buffer[N + 1]; + static_wstring result; // swprintf returns a negative number if it can't // fit all the characters in the buffer. // mingw has a non-standard swprintf, so @@ -702,8 +706,8 @@ to_static_wstring_float_impl(long double value) noexcept // circuit evaluation will ensure that the // second operand is not evaluated on conforming // implementations. - const long long num_written = - std::swprintf(buffer, N + 1, L"%Lf", value); + long long num_written = + std::swprintf(result.data(), N + 1, L"%Lf", value); if (num_written < 0 || num_written > narrow) { @@ -715,10 +719,10 @@ to_static_wstring_float_impl(long double value) noexcept const int precision = narrow > reserved_count ? N - reserved_count : 0; // switch to scientific notation - std::swprintf(buffer, N + 1, L"%.*Le", precision, value); + num_written = std::swprintf(result.data(), N + 1, L"%.*Le", precision, value); } - // this will not throw - return static_wstring(buffer); + result.set_size(static_cast(num_written)); + return result; } #endif @@ -925,6 +929,37 @@ class basic_static_string private: template friend class basic_static_string; + + template + friend + static_string

+ detail::to_static_string_int_impl(Integer value) noexcept; + + template + friend + static_string

+ detail::to_static_string_float_impl(double value) noexcept; + + template + friend + static_string

+ detail::to_static_string_float_impl(long double value) noexcept; + +#ifdef BOOST_STATIC_STRING_HAS_WCHAR + template + friend static_wstring

+ detail::to_static_wstring_int_impl(Integer value) noexcept; + + template + friend + static_wstring

+ detail::to_static_wstring_float_impl(double value) noexcept; + + template + friend + static_wstring

+ detail::to_static_wstring_float_impl(long double value) noexcept; +#endif public: //-------------------------------------------------------------------------- // From 300781d9542f6cded7298981195d67535c9807ad Mon Sep 17 00:00:00 2001 From: Gennaro Prota Date: Tue, 7 Oct 2025 17:03:03 +0200 Subject: [PATCH 40/73] Add a resize_and_overwrite() member Reason: This is in preparation of the next commit. See its commit message. --- include/boost/static_string/static_string.hpp | 46 ++++++++++++++ test/static_string.cpp | 63 +++++++++++++++++++ 2 files changed, 109 insertions(+) diff --git a/include/boost/static_string/static_string.hpp b/include/boost/static_string/static_string.hpp index 9ad7240..d2cfa52 100644 --- a/include/boost/static_string/static_string.hpp +++ b/include/boost/static_string/static_string.hpp @@ -39,6 +39,7 @@ #include #include #include +#include namespace boost { namespace static_strings { @@ -3743,6 +3744,31 @@ class basic_static_string size_type n, value_type c); + /** + Resize the string and overwrite its contents. + + Resizes the string to contain `n` characters, and uses the + provided function object `op` to overwrite the string contents. + The function object is called with two arguments: a pointer to + the string internal buffer, and the size of the string. The + function object shall return the number of characters written to + the buffer, which shall be less than or equal to `n`. The string + size is set to the value returned by the function object. + + @par Exception Safety + + Strong guarantee. However, if an exception is thrown by + `std::move(op)(p, count)`, the behavior is undefined. + + @throw std::length_error `n > max_size()` + */ + template + BOOST_STATIC_STRING_CPP14_CONSTEXPR + void + resize_and_overwrite( + size_type n, + Operation op); + /** Swap two strings. Swaps the contents of the string and `s`. @@ -6693,6 +6719,26 @@ resize(size_type n, value_type c) term(); } +template +template +BOOST_STATIC_STRING_CPP14_CONSTEXPR +void +basic_static_string:: +resize_and_overwrite( + size_type n, + Operation op) +{ + if (n > max_size()) { + detail::throw_exception("n > max_size() in resize_and_overwrite()"); + } + + CharT* p = data(); + const auto new_size = std::move(op)(p, n); + BOOST_STATIC_STRING_ASSERT(new_size >= 0 && size_type(new_size) <= n); + this->set_size(size_type(new_size)); + term(); +} + template BOOST_STATIC_STRING_CPP14_CONSTEXPR void diff --git a/test/static_string.cpp b/test/static_string.cpp index 091b74b..c3ebae8 100644 --- a/test/static_string.cpp +++ b/test/static_string.cpp @@ -7420,6 +7420,68 @@ testResize() BOOST_TEST(b.size() == 2); } +void +testResizeAndOverwrite() +{ + { + // Basic overwrite + static_string<16> s; + s.resize_and_overwrite( + 5, + [](char* buf, std::size_t) -> std::size_t + { + std::strcpy(buf, "Hello"); + return 5; + } + ); + BOOST_TEST(s.size() == 5); + BOOST_TEST(s == "Hello"); + } + { + // Zero overwrite + static_string<16> s; + s.resize_and_overwrite( + 8, + [](char*, std::size_t) -> std::size_t + { + return 0; + } + ); + BOOST_TEST(s.empty()); + } + { + // Maximum size overwrite + constexpr std::size_t N = 16; + static_string s; + s.resize_and_overwrite( + N, + [](char* buf, std::size_t n) -> std::size_t + { + for (std::size_t i = 0; i < n; ++i) { + buf[i] = 'x'; + } + return n; + } + ); + BOOST_TEST(s.size() == N); + BOOST_TEST(s == std::string(N, 'x')); + } + { + // Oversize overwrite + static_string<16> s; + BOOST_TEST_THROWS( + s.resize_and_overwrite( + 17, + [](char*, std::size_t n) -> std::size_t + { + return n; + } + ), + std::length_error + ); + } +} + void testStream() { @@ -7539,6 +7601,7 @@ runTests() testGeneral(); testToStaticString(); testResize(); + testResizeAndOverwrite(); testFind(); From 9c5d69475dd52886e94518dc5b9b9e58f2a9bfd4 Mon Sep 17 00:00:00 2001 From: Gennaro Prota Date: Wed, 8 Oct 2025 16:46:31 +0200 Subject: [PATCH 41/73] Implement the arithmetic conversions in terms of resize_and_overwrite() Reason: Performing the conversions without accessing private members, providing a model for users to implement their own with comparable efficiency. --- include/boost/static_string/static_string.hpp | 257 +++++++++--------- 1 file changed, 135 insertions(+), 122 deletions(-) diff --git a/include/boost/static_string/static_string.hpp b/include/boost/static_string/static_string.hpp index d2cfa52..6bbc26c 100644 --- a/include/boost/static_string/static_string.hpp +++ b/include/boost/static_string/static_string.hpp @@ -550,13 +550,21 @@ inline static_string to_static_string_int_impl(Integer value) noexcept { + using size_type = typename static_string::size_type; static_string result; - char * const digits_end = result.data() + N; - char * const digits_begin = integer_to_string, Integer>( - digits_end, value, std::is_signed{}); - result.set_size(digits_end - digits_begin); - std::char_traits::move(result.data(), digits_begin, result.size()); - result.term(); + result.resize_and_overwrite( + N, + [&](char* buffer, size_type) -> size_type + { + char* const digits_end = buffer + N; + char* const digits_begin = integer_to_string, Integer>( + digits_end, value, std::is_signed{}); + const size_type len = digits_end - digits_begin; + std::char_traits::move(buffer, digits_begin, len); + return len; + } + ); + return result; } @@ -566,13 +574,20 @@ inline static_wstring to_static_wstring_int_impl(Integer value) noexcept { + using size_type = typename static_wstring::size_type; static_wstring result; - wchar_t * const digits_end = result.data() + N; - wchar_t * const digits_begin = integer_to_wstring, Integer>( - digits_end, value, std::is_signed{}); - result.set_size(digits_end - digits_begin); - std::char_traits::move(result.data(), digits_begin, result.size()); - result.term(); + result.resize_and_overwrite( + N, + [&](wchar_t* buffer, size_type) -> size_type + { + wchar_t* const digits_end = buffer + N; + wchar_t* const digits_begin = integer_to_wstring, Integer>( + digits_end, value, std::is_signed{}); + const size_type len = digits_end - digits_begin; + std::char_traits::move(buffer, digits_begin, len); + return len; + } + ); return result; } #endif @@ -598,27 +613,34 @@ inline static_string to_static_string_float_impl(double value) noexcept { + using size_type = typename static_string::size_type; // we have to assume here that no reasonable implementation // will require more than 2^63 chars to represent a float value. const long long narrow = static_cast(N); static_string result; - // we know that a formatting error will not occur, so - // we assume that the result is always positive - std::size_t length = std::snprintf(result.data(), N + 1, "%f", value); - if (length > N) - { - // the + 4 is for the decimal, 'e', - // its sign, and the sign of the integral portion - const int reserved_count = - (std::max)(2, count_digits( - std::numeric_limits::max_exponent10)) + 4; - const int precision = narrow > reserved_count ? - N - reserved_count : 0; - // switch to scientific notation - length = std::snprintf(result.data(), N + 1, "%.*e", precision, value); - } - result.set_size(length); + result.resize_and_overwrite( + N, + [&](char* buffer, size_type) -> size_type + { + // we know that a formatting error will not occur, so + // we assume that the result is always positive + std::size_t length = std::snprintf(buffer, N + 1, "%f", value); + if (length > N) + { + // the + 4 is for the decimal, 'e', + // its sign, and the sign of the integral portion + const int reserved_count = + (std::max)(2, count_digits( + std::numeric_limits::max_exponent10)) + 4; + const int precision = narrow > reserved_count ? + N - reserved_count : 0; + // switch to scientific notation + length = std::snprintf(buffer, N + 1, "%.*e", precision, value); + } + return length; + } + ); return result; } @@ -627,29 +649,36 @@ inline static_string to_static_string_float_impl(long double value) noexcept { + using size_type = typename static_string::size_type; // we have to assume here that no reasonable implementation // will require more than 2^63 chars to represent a float value. const long long narrow = static_cast(N); static_string result; - // snprintf returns the number of characters - // that would have been written - // we know that a formatting error will not occur, so - // we assume that the result is always positive - std::size_t length = std::snprintf(result.data(), N + 1, "%Lf", value); - if (length > N) - { - // the + 4 is for the decimal, 'e', - // its sign, and the sign of the integral portion - const int reserved_count = - (std::max)(2, count_digits( - std::numeric_limits::max_exponent10)) + 4; - const int precision = narrow > reserved_count ? - N - reserved_count : 0; - // switch to scientific notation - length = std::snprintf(result.data(), N + 1, "%.*Le", precision, value); - } - result.set_size(length); + result.resize_and_overwrite( + N, + [&](char* buffer, size_type)->size_type + { + // snprintf returns the number of characters + // that would have been written + // we know that a formatting error will not occur, so + // we assume that the result is always positive + std::size_t length = std::snprintf(buffer, N + 1, "%Lf", value); + if (length > N) + { + // the + 4 is for the decimal, 'e', + // its sign, and the sign of the integral portion + const int reserved_count = + (std::max)(2, count_digits( + std::numeric_limits::max_exponent10)) + 4; + const int precision = narrow > reserved_count ? + N - reserved_count : 0; + // switch to scientific notation + length = std::snprintf(buffer, N + 1, "%.*Le", precision, value); + } + return length; + } + ); return result; } @@ -659,34 +688,41 @@ inline static_wstring to_static_wstring_float_impl(double value) noexcept { + using size_type = typename static_wstring::size_type; // we have to assume here that no reasonable implementation // will require more than 2^63 chars to represent a float value. const long long narrow = static_cast(N); static_wstring result; - // swprintf returns a negative number if it can't - // fit all the characters in the buffer. - // mingw has a non-standard swprintf, so - // this just covers all the bases. short - // circuit evaluation will ensure that the - // second operand is not evaluated on conforming - // implementations. - long long num_written = - std::swprintf(result.data(), N + 1, L"%f", value); - if (num_written < 0 || - num_written > narrow) - { - // the + 4 is for the decimal, 'e', - // its sign, and the sign of the integral portion - const int reserved_count = - (std::max)(2, count_digits( - std::numeric_limits::max_exponent10)) + 4; - const int precision = narrow > reserved_count ? - N - reserved_count : 0; - // switch to scientific notation - num_written = std::swprintf(result.data(), N + 1, L"%.*e", precision, value); - } - result.set_size(static_cast(num_written)); + result.resize_and_overwrite( + N, + [&](wchar_t* buffer, size_type) -> size_type + { + // swprintf returns a negative number if it can't + // fit all the characters in the buffer. + // mingw has a non-standard swprintf, so + // this just covers all the bases. short + // circuit evaluation will ensure that the + // second operand is not evaluated on conforming + // implementations. + long long num_written = + std::swprintf(buffer, N + 1, L"%f", value); + if (num_written < 0 || + num_written > narrow) + { + // the + 4 is for the decimal, 'e', + // its sign, and the sign of the integral portion + const int reserved_count = + (std::max)(2, count_digits( + std::numeric_limits::max_exponent10)) + 4; + const int precision = narrow > reserved_count ? + N - reserved_count : 0; + // switch to scientific notation + num_written = std::swprintf(buffer, N + 1, L"%.*e", precision, value); + } + return num_written; + } + ); return result; } @@ -695,34 +731,41 @@ inline static_wstring to_static_wstring_float_impl(long double value) noexcept { + using size_type = typename static_wstring::size_type; // we have to assume here that no reasonable implementation // will require more than 2^63 chars to represent a float value. const long long narrow = static_cast(N); static_wstring result; - // swprintf returns a negative number if it can't - // fit all the characters in the buffer. - // mingw has a non-standard swprintf, so - // this just covers all the bases. short - // circuit evaluation will ensure that the - // second operand is not evaluated on conforming - // implementations. - long long num_written = - std::swprintf(result.data(), N + 1, L"%Lf", value); - if (num_written < 0 || - num_written > narrow) - { - // the + 4 is for the decimal, 'e', - // its sign, and the sign of the integral portion - const int reserved_count = - (std::max)(2, count_digits( - std::numeric_limits::max_exponent10)) + 4; - const int precision = narrow > reserved_count ? - N - reserved_count : 0; - // switch to scientific notation - num_written = std::swprintf(result.data(), N + 1, L"%.*Le", precision, value); - } - result.set_size(static_cast(num_written)); + result.resize_and_overwrite( + N, + [&](wchar_t* buffer, size_type) -> size_type + { + // swprintf returns a negative number if it can't + // fit all the characters in the buffer. + // mingw has a non-standard swprintf, so + // this just covers all the bases. short + // circuit evaluation will ensure that the + // second operand is not evaluated on conforming + // implementations. + long long num_written = + std::swprintf(buffer, N + 1, L"%Lf", value); + if (num_written < 0 || + num_written > narrow) + { + // the + 4 is for the decimal, 'e', + // its sign, and the sign of the integral portion + const int reserved_count = + (std::max)(2, count_digits( + std::numeric_limits::max_exponent10)) + 4; + const int precision = narrow > reserved_count ? + N - reserved_count : 0; + // switch to scientific notation + num_written = std::swprintf(buffer, N + 1, L"%.*Le", precision, value); + } + return num_written; + } + ); return result; } #endif @@ -931,36 +974,6 @@ class basic_static_string template friend class basic_static_string; - template - friend - static_string

- detail::to_static_string_int_impl(Integer value) noexcept; - - template - friend - static_string

- detail::to_static_string_float_impl(double value) noexcept; - - template - friend - static_string

- detail::to_static_string_float_impl(long double value) noexcept; - -#ifdef BOOST_STATIC_STRING_HAS_WCHAR - template - friend static_wstring

- detail::to_static_wstring_int_impl(Integer value) noexcept; - - template - friend - static_wstring

- detail::to_static_wstring_float_impl(double value) noexcept; - - template - friend - static_wstring

- detail::to_static_wstring_float_impl(long double value) noexcept; -#endif public: //-------------------------------------------------------------------------- // From 4c27826548966a5de665d47e0441ef03d15e11a6 Mon Sep 17 00:00:00 2001 From: Dmitry Arkhipov Date: Fri, 2 May 2025 13:55:56 +0300 Subject: [PATCH 42/73] use Python version of Docca --- .drone.star | 2 +- .drone/drone.sh | 9 +-- doc/Jamfile | 25 ++++---- doc/config.json | 12 ++++ doc/externals.hpp | 64 +++++++++++++++++++ doc/xsl/custom-overrides.xsl | 11 ---- include/boost/static_string/static_string.hpp | 2 +- 7 files changed, 91 insertions(+), 34 deletions(-) create mode 100644 doc/config.json create mode 100644 doc/externals.hpp delete mode 100644 doc/xsl/custom-overrides.xsl diff --git a/.drone.star b/.drone.star index e0e8f5e..e1a381d 100644 --- a/.drone.star +++ b/.drone.star @@ -64,7 +64,7 @@ def main(ctx): linux_cxx("S390x: Clang 12", "clang++-12", packages="clang-12 libstdc++-9-dev", llvm_os="focal", llvm_ver="12", buildtype="boost", buildscript="drone", image="cppalliance/droneubuntu2004:multiarch", environment={'B2_TOOLSET': 'clang-12', 'B2_CXXFLAGS': '-Werror', 'B2_CXXSTD': '17,20'}, arch="s390x", globalenv=globalenv), # Documentation - # linux_cxx("Docs", "g++", packages="docbook docbook-xml docbook-xsl xsltproc libsaxonhe-java default-jre-headless flex libfl-dev bison unzip rsync", buildtype="docs", buildscript="drone", image="cppalliance/droneubuntu1804:1", environment={'COMMENT': 'docs'}, globalenv=globalenv), + # linux_cxx("Docs", "g++", packages="docbook docbook-xml docbook-xsl python3-jinja2 xsltproc flex libfl-dev bison unzip rsync", buildtype="docs", buildscript="drone", image="cppalliance/droneubuntu1804:1", environment={'COMMENT': 'docs'}, globalenv=globalenv), # CMake tests (https://github.com/boostorg/boost-ci) ## Compiling as part of the boost superproject diff --git a/.drone/drone.sh b/.drone/drone.sh index 05d7ecd..0affbfd 100755 --- a/.drone/drone.sh +++ b/.drone/drone.sh @@ -58,12 +58,7 @@ elif [ "$DRONE_JOB_BUILDTYPE" == "docs" ]; then cmake -H. -Bbuild -DCMAKE_BUILD_TYPE=Release cd build sudo make install - cd ../.. - if [ ! -f saxonhe.zip ]; then wget -O saxonhe.zip https://sourceforge.net/projects/saxon/files/Saxon-HE/9.9/SaxonHE9-9-1-4J.zip/download && echo "not-cached"; else echo "cached"; fi - unzip -o saxonhe.zip - sudo rm /usr/share/java/Saxon-HE.jar - sudo cp saxon9he.jar /usr/share/java/Saxon-HE.jar - cd .. + cd ../../.. BOOST_BRANCH=develop && [ "$TRAVIS_BRANCH" == "master" ] && BOOST_BRANCH=master || true git clone -b $BOOST_BRANCH https://github.com/boostorg/boost.git boost-root --depth 1 cd boost-root @@ -80,7 +75,7 @@ elif [ "$DRONE_JOB_BUILDTYPE" == "docs" ]; then echo '==================================> SCRIPT' - echo "using doxygen ; using boostbook ; using saxonhe ;" >tools/build/src/user-config.jam + echo "using doxygen ; using boostbook ; using python : : python3 ;" >tools/build/src/user-config.jam ./b2 -j3 libs/$SELF/doc//boostrelease elif [ "$DRONE_JOB_BUILDTYPE" == "codecov" ]; then diff --git a/doc/Jamfile b/doc/Jamfile index ac02fc8..4b13c3a 100644 --- a/doc/Jamfile +++ b/doc/Jamfile @@ -9,22 +9,21 @@ project static_string/doc ; -import boostbook ; -import type ; -import os ; import-search /boost/docca ; + import docca ; +import path ; +import os ; -docca.reference reference.qbk +local include-prefix = [ path.root $(__file__:D) [ path.pwd ] ] ; +include-prefix = [ path.native $(include-prefix:D)/include ] ; + +docca.pyreference reference.qbk : - xsl/custom-overrides.xsl [ glob-tree-ex ../include/boost/static_string : *.hpp *.ipp : detail impl ] + externals.hpp : - PROJECT_NAME=StaticString - PROJECT_BRIEF="Static String Library" ALIASES="esafe=\"@par Exception Safety\"" - FILE_PATTERNS= - EXAMPLE_PATTERNS= DISTRIBUTE_GROUP_DOC=YES MACRO_EXPANSION=YES EXPAND_ONLY_PREDEF=YES @@ -41,19 +40,17 @@ docca.reference reference.qbk EXTRACT_ALL=YES EXTRACT_PRIVATE=YES EXTRACT_LOCAL_CLASSES=NO - SHOW_INCLUDE_FILES=NO INLINE_INFO=NO SORT_MEMBER_DOCS=NO SORT_MEMBERS_CTORS_1ST=YES - SHOW_USED_FILES=NO - SHOW_FILES=NO - SHOW_NAMESPACES=NO - CLASS_DIAGRAMS=NO + STRIP_FROM_PATH=$(include-prefix) # ALLOW_UNICODE_NAMES=NO # GROUP_NESTED_COMPOUNDS=NO # HIDE_COMPOUND_REFERENCE=NO # WARN_AS_ERROR=NO + + config.json ; #------------------------------------------------------------------------------- diff --git a/doc/config.json b/doc/config.json new file mode 100644 index 0000000..47ff971 --- /dev/null +++ b/doc/config.json @@ -0,0 +1,12 @@ +{ + "include_private": false, + "legacy_behavior": false, + "external_marker": "!EXTERNAL!", + "link_prefix": "static_string.ref.", + "default_namespace": "boost::static_strings", + "allowed_prefixes": ["boost::static_strings::", "std::"], + "convenience_header": "boost/static_string.hpp", + "replace_strings": { + "__see_below__": "``['see-below]``" + } +} diff --git a/doc/externals.hpp b/doc/externals.hpp new file mode 100644 index 0000000..ca3ef2d --- /dev/null +++ b/doc/externals.hpp @@ -0,0 +1,64 @@ +#pragma once + +namespace boost { + +/// !EXTERNAL! +/// +/// @see https://www.boost.org/doc/libs/release/libs/utility/doc/html/utility/utilities/string_view.html +template +struct basic_string_view {}; + +} // namespace boost + +namespace std { + +/// !EXTERNAL! +/// +/// @see https://en.cppreference.com/w/cpp/iterator/reverse_iterator +template +struct reverse_iterator {}; + +/// !EXTERNAL! +/// +/// @see https://en.cppreference.com/w/cpp/types/size_t +struct size_t {}; + +/// !EXTERNAL! +/// +/// @see https://en.cppreference.com/w/cpp/types/integer +struct uint64_t {}; + +/// !EXTERNAL! +/// +/// @see https://en.cppreference.com/w/cpp/types/integer +struct int64_t {}; + +/// !EXTERNAL! +/// +/// @see https://en.cppreference.com/w/cpp/types/nullptr_t +struct nullptr_t {}; + +/// !EXTERNAL! +/// +/// @see https://en.cppreference.com/w/cpp/types/ptrdiff_t +struct ptrdiff_t {}; + +/// !EXTERNAL! +/// +/// @see https://en.cppreference.com/w/cpp/utility/initializer_list +template +struct initializer_list {}; + +/// !EXTERNAL! +/// +/// @see https://en.cppreference.com/w/cpp/io/basic_ostream +template +struct basic_ostream {}; + +/// !EXTERNAL! +/// +/// @see https://en.cppreference.com/w/cpp/types/numeric_limits +template +struct numeric_limits {}; + +} // namespace std diff --git a/doc/xsl/custom-overrides.xsl b/doc/xsl/custom-overrides.xsl deleted file mode 100644 index 28ff3e4..0000000 --- a/doc/xsl/custom-overrides.xsl +++ /dev/null @@ -1,11 +0,0 @@ - - - - - - - diff --git a/include/boost/static_string/static_string.hpp b/include/boost/static_string/static_string.hpp index 6bbc26c..09ef1c9 100644 --- a/include/boost/static_string/static_string.hpp +++ b/include/boost/static_string/static_string.hpp @@ -961,7 +961,7 @@ throw_exception(const char* msg) basic_static_string>; @endcode - @see to_static_string + @see @ref to_static_string. */ template> From 0f346444886c320f25c57e3da98f5af93985b5e6 Mon Sep 17 00:00:00 2001 From: Kenneth Reitz Date: Thu, 4 Apr 2024 10:49:41 -0400 Subject: [PATCH 43/73] Update libraries.json /s/container/containers The other libraries reference "containers" instead of "container" --- meta/libraries.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/meta/libraries.json b/meta/libraries.json index 52a31c0..f7ce4af 100644 --- a/meta/libraries.json +++ b/meta/libraries.json @@ -7,7 +7,7 @@ ], "description": "A fixed capacity dynamically sized string.", "category": [ - "Container", + "Containers", "String" ], "maintainers": [ From 34ef5c45be2fc59fe7aa9233b8a1b27ac1bee391 Mon Sep 17 00:00:00 2001 From: Gennaro Prota Date: Wed, 22 Oct 2025 18:59:52 +0200 Subject: [PATCH 44/73] Remove an unused dependency on Boost.StaticAssert This closes issue #73. --- CMakeLists.txt | 3 +-- include/boost/static_string/config.hpp | 7 ------- 2 files changed, 1 insertion(+), 9 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 2a95039..6bf922d 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -45,7 +45,7 @@ if (BOOST_STATIC_STRING_FIND_PACKAGE_BOOST) find_package(Boost 1.78.0 REQUIRED COMPONENTS container) elseif (BOOST_STATIC_STRING_IS_ROOT) set(BOOST_STATIC_STRING_UNIT_TEST_LIBRARIES core) - set(BOOST_INCLUDE_LIBRARIES static_string assert container_hash static_assert throw_exception utility ${BOOST_STATIC_STRING_UNIT_TEST_LIBRARIES}) + set(BOOST_INCLUDE_LIBRARIES static_string assert container_hash throw_exception utility ${BOOST_STATIC_STRING_UNIT_TEST_LIBRARIES}) set(BOOST_EXCLUDE_LIBRARIES static_string) set(CMAKE_FOLDER Dependencies) add_subdirectory(../.. Dependencies/boost EXCLUDE_FROM_ALL) @@ -90,7 +90,6 @@ else () Boost::assert Boost::container_hash Boost::core - Boost::static_assert Boost::throw_exception Boost::utility ) diff --git a/include/boost/static_string/config.hpp b/include/boost/static_string/config.hpp index a0f0095..0c7353e 100644 --- a/include/boost/static_string/config.hpp +++ b/include/boost/static_string/config.hpp @@ -139,9 +139,6 @@ #ifndef BOOST_STATIC_STRING_THROW #define BOOST_STATIC_STRING_THROW(ex) BOOST_THROW_EXCEPTION(ex) #endif -#ifndef BOOST_STATIC_STRING_STATIC_ASSERT -#define BOOST_STATIC_STRING_STATIC_ASSERT(cond, msg) BOOST_STATIC_ASSERT_MSG(cond, msg) -#endif #ifndef BOOST_STATIC_STRING_ASSERT #define BOOST_STATIC_STRING_ASSERT(cond) BOOST_ASSERT(cond) #endif @@ -149,9 +146,6 @@ #ifndef BOOST_STATIC_STRING_THROW #define BOOST_STATIC_STRING_THROW(ex) throw ex #endif -#ifndef BOOST_STATIC_STRING_STATIC_ASSERT -#define BOOST_STATIC_STRING_STATIC_ASSERT(cond, msg) static_assert(cond, msg) -#endif #ifndef BOOST_STATIC_STRING_ASSERT #define BOOST_STATIC_STRING_ASSERT(cond) assert(cond) #endif @@ -161,7 +155,6 @@ #include #include #include -#include #include #include #include From 3c37deed99a5a70c7751077e2c39263b91130d9e Mon Sep 17 00:00:00 2001 From: Gennaro Prota Date: Wed, 22 Oct 2025 19:11:09 +0200 Subject: [PATCH 45/73] Fix the previous commit --- build.jam | 1 - 1 file changed, 1 deletion(-) diff --git a/build.jam b/build.jam index 632c0c4..87faeb1 100644 --- a/build.jam +++ b/build.jam @@ -10,7 +10,6 @@ constant boost_dependencies : /boost/config//boost_config /boost/container_hash//boost_container_hash /boost/core//boost_core - /boost/static_assert//boost_static_assert /boost/throw_exception//boost_throw_exception /boost/utility//boost_utility ; From 7b564d8d267c3ebdf069ab732126f602c28c70a0 Mon Sep 17 00:00:00 2001 From: Gennaro Prota Date: Wed, 22 Oct 2025 19:18:39 +0200 Subject: [PATCH 46/73] Fix two macro names in the unit tests --- test/static_string.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/test/static_string.cpp b/test/static_string.cpp index c3ebae8..b79d0a7 100644 --- a/test/static_string.cpp +++ b/test/static_string.cpp @@ -919,14 +919,14 @@ testElements() BOOST_TEST(std::memcmp( s.c_str(), "123\0", 4) == 0); } -#ifdef BOOST_STATIC_ASSERT_HAS_STRING_VIEW +#ifdef BOOST_STATIC_STRING_HAS_STRING_VIEW { static_string<3> s("123"); string_view sv = s; BOOST_TEST(static_string<5>(sv) == "123"); } #endif -#ifdef BOOST_STATIC_ASSERT_HAS_STD_STRING_VIEW +#ifdef BOOST_STATIC_STRING_HAS_STD_STRING_VIEW { static_string<3> s("123"); std::string_view sv = s; From d6f976a7df144559f1f4b4ff42fb51a332cad4f6 Mon Sep 17 00:00:00 2001 From: Gennaro Prota Date: Mon, 20 Oct 2025 16:04:51 +0200 Subject: [PATCH 47/73] Fix the sizes of the strings returned by to_static_string() and to_static_wstring() for floating point values --- include/boost/static_string/static_string.hpp | 32 ++++++++++--------- 1 file changed, 17 insertions(+), 15 deletions(-) diff --git a/include/boost/static_string/static_string.hpp b/include/boost/static_string/static_string.hpp index 09ef1c9..cb8876e 100644 --- a/include/boost/static_string/static_string.hpp +++ b/include/boost/static_string/static_string.hpp @@ -6213,9 +6213,11 @@ operator<<( // Unsigned overloads have a + 1, for the missing digit. -// Floating point overloads have a + 4, for the sign -// of the integral part, sign of the exponent, the 'e', -// and the decimal. +// Floating point overloads have a +7 (for float), + 8 +// (for double), and +10 for long double (that accounts +// for the sign of the integral part, the missing digit, +// the decimal point, the sign of the exponent, the 'e' +// and up to two, three or five digits of exponent). /// Converts `value` to a `static_string` static_string::digits10 + 2> @@ -6272,30 +6274,30 @@ to_static_string(unsigned long long value) noexcept } /// Converts `value` to a `static_string` -static_string::max_digits10 + 4> +static_string::max_digits10 + 7> inline to_static_string(float value) noexcept { return detail::to_static_string_float_impl< - std::numeric_limits::max_digits10 + 4>(value); + std::numeric_limits::max_digits10 + 7>(value); } /// Converts `value` to a `static_string` -static_string::max_digits10 + 4> +static_string::max_digits10 + 8> inline to_static_string(double value) noexcept { return detail::to_static_string_float_impl< - std::numeric_limits::max_digits10 + 4>(value); + std::numeric_limits::max_digits10 + 8>(value); } /// Converts `value` to a `static_string` -static_string::max_digits10 + 4> +static_string::max_digits10 + 10> inline to_static_string(long double value) noexcept { return detail::to_static_string_float_impl< - std::numeric_limits::max_digits10 + 4>(value); + std::numeric_limits::max_digits10 + 10>(value); } #ifdef BOOST_STATIC_STRING_HAS_WCHAR @@ -6354,30 +6356,30 @@ to_static_wstring(unsigned long long value) noexcept } /// Converts `value` to a `static_wstring` -static_wstring::max_digits10 + 4> +static_wstring::max_digits10 + 7> inline to_static_wstring(float value) noexcept { return detail::to_static_wstring_float_impl< - std::numeric_limits::max_digits10 + 4>(value); + std::numeric_limits::max_digits10 + 7>(value); } /// Converts `value` to a `static_wstring` -static_wstring::max_digits10 + 4> +static_wstring::max_digits10 + 8> inline to_static_wstring(double value) noexcept { return detail::to_static_wstring_float_impl< - std::numeric_limits::max_digits10 + 4>(value); + std::numeric_limits::max_digits10 + 8>(value); } /// Converts `value` to a `static_wstring` -static_wstring::max_digits10 + 4> +static_wstring::max_digits10 + 10> inline to_static_wstring(long double value) noexcept { return detail::to_static_wstring_float_impl< - std::numeric_limits::max_digits10 + 4>(value); + std::numeric_limits::max_digits10 + 10>(value); } #endif From 2cc22bf5a80196965a0b62e76c802ace2ee953ca Mon Sep 17 00:00:00 2001 From: Gennaro Prota Date: Mon, 20 Oct 2025 16:47:46 +0200 Subject: [PATCH 48/73] Align to_static_[w]string() with C++26 std::to_[w]string() C++26 specifies that std::to_string() and std::to_wstring() format floating point values as if using std::format(). This commit updates the internal conversion helpers to match that behavior, using std::format_to_n() for efficient, allocation-free formatting directly into the static_string/static_wstring buffer. Fallbacks using snprintf()/swprintf() remain active for pre-C++26 builds. This ensures consistent formatting across standard and Boost APIs. --- include/boost/static_string/config.hpp | 4 + include/boost/static_string/static_string.hpp | 109 ++++++++++++++++-- 2 files changed, 103 insertions(+), 10 deletions(-) diff --git a/include/boost/static_string/config.hpp b/include/boost/static_string/config.hpp index 0c7353e..67dface 100644 --- a/include/boost/static_string/config.hpp +++ b/include/boost/static_string/config.hpp @@ -271,4 +271,8 @@ using basic_string_view = } // boost #endif +#if defined(__cpp_lib_to_string) && __cpp_lib_to_string >= 202306L // std::to_[w]string() redefined in terms of std::format() +#define BOOST_STATIC_STRING_USE_STD_FORMAT +#endif + #endif \ No newline at end of file diff --git a/include/boost/static_string/static_string.hpp b/include/boost/static_string/static_string.hpp index cb8876e..33c0ae6 100644 --- a/include/boost/static_string/static_string.hpp +++ b/include/boost/static_string/static_string.hpp @@ -34,6 +34,9 @@ #include #include #include +#if defined(BOOST_STATIC_STRING_USE_STD_FORMAT) +#include +#endif #include #include #include @@ -608,17 +611,42 @@ count_digits(std::size_t value) #pragma GCC diagnostic ignored "-Wformat-truncation" #endif +#if defined(BOOST_STATIC_STRING_USE_STD_FORMAT) + +template +inline +static_string +cpp26_to_static_string(FloatingPoint value) noexcept +{ + using size_type = typename static_string::size_type; + static_string result; + result.resize_and_overwrite( + N, + [&](char* buffer, size_type) -> size_type + { + const auto formatted = std::format_to_n(buffer, N, "{}", value); + return formatted.size; + } + ); + return result; +} + +#endif + template inline static_string to_static_string_float_impl(double value) noexcept { +#if defined(BOOST_STATIC_STRING_USE_STD_FORMAT) + return cpp26_to_static_string(value); +#else using size_type = typename static_string::size_type; + static_string result; // we have to assume here that no reasonable implementation // will require more than 2^63 chars to represent a float value. const long long narrow = static_cast(N); - static_string result; result.resize_and_overwrite( N, [&](char* buffer, size_type) -> size_type @@ -642,6 +670,19 @@ to_static_string_float_impl(double value) noexcept } ); return result; +#endif +} + +template +inline +static_string +to_static_string_float_impl(float value) noexcept +{ +#if defined(BOOST_STATIC_STRING_USE_STD_FORMAT) + return cpp26_to_static_string(value); +#else + return to_static_string_float_impl(static_cast(value)); +#endif } template @@ -649,12 +690,15 @@ inline static_string to_static_string_float_impl(long double value) noexcept { +#if defined(BOOST_STATIC_STRING_USE_STD_FORMAT) + return cpp26_to_static_string(value); +#else using size_type = typename static_string::size_type; + static_string result; // we have to assume here that no reasonable implementation // will require more than 2^63 chars to represent a float value. const long long narrow = static_cast(N); - static_string result; result.resize_and_overwrite( N, [&](char* buffer, size_type)->size_type @@ -680,20 +724,46 @@ to_static_string_float_impl(long double value) noexcept } ); return result; +#endif } #ifdef BOOST_STATIC_STRING_HAS_WCHAR + +#if defined(BOOST_STATIC_STRING_USE_STD_FORMAT) +template +inline +static_wstring +cpp26_to_static_wstring(FloatingPoint value) noexcept +{ + using size_type = typename static_wstring::size_type; + static_wstring result; + result.resize_and_overwrite( + N, + [&](wchar_t* buffer, size_type) -> size_type + { + const auto formatted = std::format_to_n(buffer, N, L"{}", value); + return formatted.size; + } + ); + return result; +} + +#endif + template inline static_wstring to_static_wstring_float_impl(double value) noexcept { +#if defined(BOOST_STATIC_STRING_USE_STD_FORMAT) + return cpp26_to_static_wstring(value); +#else using size_type = typename static_wstring::size_type; + static_wstring result; // we have to assume here that no reasonable implementation // will require more than 2^63 chars to represent a float value. const long long narrow = static_cast(N); - static_wstring result; result.resize_and_overwrite( N, [&](wchar_t* buffer, size_type) -> size_type @@ -724,6 +794,19 @@ to_static_wstring_float_impl(double value) noexcept } ); return result; +#endif +} + +template +inline +static_wstring +to_static_wstring_float_impl(float value) noexcept +{ +#if defined(BOOST_STATIC_STRING_USE_STD_FORMAT) + return cpp26_to_static_wstring(value); +#else + return to_static_wstring_float_impl(static_cast(value)); +#endif } template @@ -731,12 +814,15 @@ inline static_wstring to_static_wstring_float_impl(long double value) noexcept { +#if defined(BOOST_STATIC_STRING_USE_STD_FORMAT) + return cpp26_to_static_wstring(value); +#else using size_type = typename static_wstring::size_type; + static_wstring result; // we have to assume here that no reasonable implementation // will require more than 2^63 chars to represent a float value. const long long narrow = static_cast(N); - static_wstring result; result.resize_and_overwrite( N, [&](wchar_t* buffer, size_type) -> size_type @@ -767,6 +853,7 @@ to_static_wstring_float_impl(long double value) noexcept } ); return result; +#endif } #endif @@ -6213,11 +6300,13 @@ operator<<( // Unsigned overloads have a + 1, for the missing digit. -// Floating point overloads have a +7 (for float), + 8 +// Floating point overloads have a +8 (for float), + 8 // (for double), and +10 for long double (that accounts // for the sign of the integral part, the missing digit, // the decimal point, the sign of the exponent, the 'e' -// and up to two, three or five digits of exponent). +// and up to two, three or five digits of exponent---float +// uses the same value as double, because we sometimes +// reuse the conversion from double for floats). /// Converts `value` to a `static_string` static_string::digits10 + 2> @@ -6274,12 +6363,12 @@ to_static_string(unsigned long long value) noexcept } /// Converts `value` to a `static_string` -static_string::max_digits10 + 7> +static_string::max_digits10 + 8> inline to_static_string(float value) noexcept { return detail::to_static_string_float_impl< - std::numeric_limits::max_digits10 + 7>(value); + std::numeric_limits::max_digits10 + 8>(value); } /// Converts `value` to a `static_string` @@ -6356,12 +6445,12 @@ to_static_wstring(unsigned long long value) noexcept } /// Converts `value` to a `static_wstring` -static_wstring::max_digits10 + 7> +static_wstring::max_digits10 + 8> inline to_static_wstring(float value) noexcept { return detail::to_static_wstring_float_impl< - std::numeric_limits::max_digits10 + 7>(value); + std::numeric_limits::max_digits10 + 8>(value); } /// Converts `value` to a `static_wstring` From 815678e1e72c46fa350134121babdccef1849d0e Mon Sep 17 00:00:00 2001 From: Gennaro Prota Date: Mon, 20 Oct 2025 16:50:42 +0200 Subject: [PATCH 49/73] CI: Test C++26/2c again --- .github/workflows/ci.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 1765253..8ea485e 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -37,7 +37,7 @@ jobs: name: Run Boost.CI uses: boostorg/boost-ci/.github/workflows/reusable.yml@master with: - exclude_cxxstd: '98,03,0x,2c,26' + exclude_cxxstd: '98,03,0x' enable_pr_coverage: false enable_multiarch: false # Example of customization: From 6f17b603778fca08c3f18deca5cbd436a88c3fa4 Mon Sep 17 00:00:00 2001 From: Alexander Grund Date: Thu, 23 Oct 2025 18:46:59 +0200 Subject: [PATCH 50/73] Guard test requiring string_view --- test/constexpr_tests.hpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/test/constexpr_tests.hpp b/test/constexpr_tests.hpp index 9b2e83c..3517488 100644 --- a/test/constexpr_tests.hpp +++ b/test/constexpr_tests.hpp @@ -171,8 +171,10 @@ testConstantEvaluation() a.substr(0); +#ifdef BOOST_STATIC_STRING_HAS_ANY_STRING_VIEW // subview a.subview(0); +#endif // copy char k[20]{}; @@ -606,4 +608,4 @@ testConstantEvaluation() #endif } } // static_strings -} // boost \ No newline at end of file +} // boost From 3613e9578da7bb5937460d08e7bc5cdc9d7c4353 Mon Sep 17 00:00:00 2001 From: Alexander Grund Date: Thu, 23 Oct 2025 18:44:08 +0200 Subject: [PATCH 51/73] Fix standalone build with Clang The config.hpp uses `BOOST_LIBSTDCXX_VERSION` which isn't defined in standalone mode so `BOOST_STATIC_STRING_NO_CXX17_HDR_STRING_VIEW` will be defined. This then causes build failures for code expecting the availability of string_view. --- include/boost/static_string/config.hpp | 30 +++++++++++++++----------- 1 file changed, 17 insertions(+), 13 deletions(-) diff --git a/include/boost/static_string/config.hpp b/include/boost/static_string/config.hpp index 67dface..5af2b13 100644 --- a/include/boost/static_string/config.hpp +++ b/include/boost/static_string/config.hpp @@ -168,27 +168,31 @@ #include #include +#if defined(__has_include) +# if !__has_include() +# define BOOST_STATIC_STRING_NO_CXX17_HDR_STRING_VIEW +# endif /* * Replicate the logic from Boost.Config */ // GNU libstdc++3: -#if defined(__GLIBCPP__) || defined(__GLIBCXX__) -#if (BOOST_LIBSTDCXX_VERSION < 70100) || (__cplusplus <= 201402L) -# define BOOST_STATIC_STRING_NO_CXX17_HDR_STRING_VIEW -#endif +#elif defined(__GLIBCPP__) || defined(__GLIBCXX__) +# if ((__GNUC__ * 10000 + __GNUC_MINOR__ * 100 + __GNUC_PATCHLEVEL__) < 70100) || (__cplusplus <= 201402L) +# define BOOST_STATIC_STRING_NO_CXX17_HDR_STRING_VIEW +# endif // libc++: #elif defined(_LIBCPP_VERSION) -#if (_LIBCPP_VERSION < 4000) || (__cplusplus <= 201402L) -# define BOOST_STATIC_STRING_NO_CXX17_HDR_STRING_VIEW -#endif +# if (_LIBCPP_VERSION < 4000) || (__cplusplus <= 201402L) +# define BOOST_STATIC_STRING_NO_CXX17_HDR_STRING_VIEW +# endif // MSVC uses logic from catch all for BOOST_NO_CXX17_HDR_STRING_VIEW // catch all: #elif !defined(_YVALS) && !defined(_CPPLIB_VER) -#if (!defined(__has_include) || (__cplusplus < 201700)) -# define BOOST_STATIC_STRING_NO_CXX17_HDR_STRING_VIEW -#elif !__has_include() -# define BOOST_STATIC_STRING_NO_CXX17_HDR_STRING_VIEW -#endif +# if (!defined(__has_include) || (__cplusplus < 201700)) +# define BOOST_STATIC_STRING_NO_CXX17_HDR_STRING_VIEW +# elif !__has_include() +# define BOOST_STATIC_STRING_NO_CXX17_HDR_STRING_VIEW +# endif #endif #if !defined(BOOST_STATIC_STRING_NO_CXX17_HDR_STRING_VIEW) || \ @@ -275,4 +279,4 @@ using basic_string_view = #define BOOST_STATIC_STRING_USE_STD_FORMAT #endif -#endif \ No newline at end of file +#endif From a841869405dd70045b280f9210d03c005be7ef74 Mon Sep 17 00:00:00 2001 From: Gennaro Prota Date: Fri, 24 Oct 2025 10:54:02 +0200 Subject: [PATCH 52/73] Remove a use of std::strcpy() to avoid a C4996 warning from MSVC --- test/static_string.cpp | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/test/static_string.cpp b/test/static_string.cpp index b79d0a7..6bbaee9 100644 --- a/test/static_string.cpp +++ b/test/static_string.cpp @@ -7430,7 +7430,12 @@ testResizeAndOverwrite() 5, [](char* buf, std::size_t) -> std::size_t { - std::strcpy(buf, "Hello"); + // Don't use std::strcpy() to avoid a MSVC C4996 warning. + buf[0] = 'H'; + buf[1] = 'e'; + buf[2] = 'l'; + buf[3] = 'l'; + buf[4] = 'o'; return 5; } ); From bd3dd012594faa4caf66bf0e1fd0c912b7fbab9c Mon Sep 17 00:00:00 2001 From: Alexander Grund Date: Thu, 23 Oct 2025 15:52:31 +0200 Subject: [PATCH 53/73] Update Drone from Boost.CI --- .drone.star | 210 ++++++++++++++++---------------- .drone/codecov_coveralls.sh | 28 +++++ .drone/drone.bat | 31 ----- .drone/drone.sh | 231 ------------------------------------ 4 files changed, 133 insertions(+), 367 deletions(-) create mode 100644 .drone/codecov_coveralls.sh delete mode 100644 .drone/drone.bat delete mode 100755 .drone/drone.sh diff --git a/.drone.star b/.drone.star index e1a381d..8b74829 100644 --- a/.drone.star +++ b/.drone.star @@ -2,116 +2,116 @@ # subject to the Boost Software License, Version 1.0. (See accompanying # file LICENSE.txt) # -# Copyright Rene Rivera 2020. -# Copyright Alan de Freitas 2022. - +# Copyright (c) 2020 Rene Rivera +# Copyright (c) 2022 Alan de Freitas +# Copyright (c) 2022-2025 Alexander Grund # For Drone CI we use the Starlark scripting language to reduce duplication. # As the yaml syntax for Drone CI is rather limited. -# -# -globalenv={'B2_CI_VERSION': '1', 'B2_VARIANT': 'release'} -linuxglobalimage="cppalliance/droneubuntu1804:1" -windowsglobalimage="cppalliance/dronevs2019" - -def main(ctx): - return [ - # Priorities: (no 2a, no betas) - # - # coverage - # latest gcc: 17,20 - # latest clang: 17,20 - # oldest gcc: 11 - # oldest clang: 11 - # asan - # tsan - # ubsan - # valgrind - # arm64 - # s390x - # docs - # cmake superproject - # cmake install - # (...the rest) - - # Coverage - linux_cxx("Coverage", "g++-8", packages="g++-8", buildscript="drone", buildtype="codecov", image=linuxglobalimage, environment={'COMMENT': 'codecov.io', 'LCOV_BRANCH_COVERAGE': '0', 'B2_CXXSTD': '11', 'B2_TOOLSET': 'gcc-8', 'B2_DEFINES': 'BOOST_NO_STRESS_TEST=1', "CODECOV_TOKEN": {"from_secret": "codecov_token"}, "COVERALLS_REPO_TOKEN": {"from_secret": "coveralls_repo_token"}}, globalenv=globalenv), - - # Latest gcc - linux_cxx("GCC 12: C++17,20", "g++-12", packages="g++-12", buildscript="drone", buildtype="boost", image="cppalliance/droneubuntu2204:1", environment={'B2_TOOLSET': 'gcc-12', 'B2_CXXFLAGS': '-Werror', 'B2_CXXSTD': '17,20'}, globalenv=globalenv), - linux_cxx("GCC 12: C++17,20 Standalone", "g++-12", packages="g++-12", buildscript="drone", buildtype="boost", image="cppalliance/droneubuntu2204:1", environment={'B2_TOOLSET': 'gcc-12', 'B2_CXXFLAGS': '-Werror', 'B2_DEFINES': 'define=BOOST_STATIC_STRING_STANDALONE', 'B2_CXXSTD': '17,20'}, globalenv=globalenv), - - # Latest clang - linux_cxx("Clang 15: C++17,20", "clang++-15", packages="clang-15 libstdc++-10-dev", llvm_os="jammy", llvm_ver="15", buildscript="drone", buildtype="boost", image="cppalliance/droneubuntu2204:1", environment={'B2_TOOLSET': 'clang-15', 'B2_CXXFLAGS': '-Werror', 'B2_CXXSTD': '17,20'}, globalenv=globalenv), - linux_cxx("Clang 15: C++17,20 Standalone", "clang++-15", packages="clang-15 libstdc++-10-dev", llvm_os="jammy", llvm_ver="15", buildscript="drone", buildtype="boost", image="cppalliance/droneubuntu2204:1", environment={'B2_TOOLSET': 'clang-15', 'B2_CXXFLAGS': '-Werror', 'B2_DEFINES': 'define=BOOST_STATIC_STRING_STANDALONE', 'B2_CXXSTD': '17,20'}, globalenv=globalenv), - - # Oldest compilers - linux_cxx("GCC 4.8: C++11", "g++-4.8", packages="g++-4.8", buildscript="drone", buildtype="boost", image="cppalliance/droneubuntu1604:1", environment={'B2_TOOLSET': 'gcc-4.8', 'B2_CXXFLAGS': '-Werror', 'B2_CXXSTD': '11'}, globalenv=globalenv), - linux_cxx("GCC 4.8: C++11 Standalone", "g++-4.8", packages="g++-4.8", buildscript="drone", buildtype="boost", image="cppalliance/droneubuntu1604:1", environment={'B2_TOOLSET': 'gcc-4.8', 'B2_CXXFLAGS': '-Werror', 'B2_DEFINES': 'define=BOOST_STATIC_STRING_STANDALONE', 'B2_CXXSTD': '11'}, globalenv=globalenv), - linux_cxx("Clang 3.8: C++11", "clang++-3.8", packages="clang-3.8", buildscript="drone", buildtype="boost", image="cppalliance/droneubuntu1604:1", environment={'B2_VARIANT': 'debug', 'B2_CXXFLAGS': '-Werror', 'B2_TOOLSET': 'clang-3.8', 'B2_CXXSTD': '11'}, globalenv=globalenv), - linux_cxx("Clang 3.8: C++11 Standalone", "clang++-3.8", packages="clang-3.8", buildscript="drone", buildtype="boost", image="cppalliance/droneubuntu1604:1", environment={'B2_VARIANT': 'debug', 'B2_CXXFLAGS': '-Werror', 'B2_TOOLSET': 'clang-3.8', 'B2_DEFINES': 'define=BOOST_STATIC_STRING_STANDALONE', 'B2_CXXSTD': '11'}, globalenv=globalenv), - - # Sanitizers + Valgrind - linux_cxx("ASan", "g++-12", packages="g++-12", buildscript="drone", buildtype="boost", image="cppalliance/droneubuntu2204:1", environment={'COMMENT': 'asan', 'B2_VARIANT': 'debug', 'B2_TOOLSET': 'gcc-12', 'B2_CXXSTD': '11,14,17', 'B2_ASAN': '1', 'B2_DEFINES': 'BOOST_NO_STRESS_TEST=1', 'DRONE_EXTRA_PRIVILEGED': 'True'}, globalenv=globalenv, privileged=True), - linux_cxx("TSan", "g++-12", packages="g++-12", buildscript="drone", buildtype="boost", image="cppalliance/droneubuntu2204:1", environment={'COMMENT': 'tsan', 'B2_VARIANT': 'debug', 'B2_TOOLSET': 'gcc-12', 'B2_CXXSTD': '11,14,17', 'B2_TSAN': '1', 'B2_DEFINES': 'BOOST_NO_STRESS_TEST=1'}, globalenv=globalenv), - linux_cxx("UBSan", "g++-12", packages="g++-12", buildscript="drone", buildtype="boost", image="cppalliance/droneubuntu2204:1", environment={'COMMENT': 'ubsan', 'B2_VARIANT': 'debug', 'B2_TOOLSET': 'gcc-12', 'B2_CXXSTD': '11,14,17', 'B2_UBSAN': '1', 'B2_DEFINES': 'define=BOOST_NO_STRESS_TEST=1', 'B2_LINKFLAGS': '-fuse-ld=gold'}, globalenv=globalenv), - linux_cxx("Valgrind", "clang++-14", packages="clang-14 libc6-dbg libc++-dev libstdc++-9-dev", llvm_os="jammy", llvm_ver="14", buildscript="drone", buildtype="valgrind", image="cppalliance/droneubuntu2204:1", environment={'COMMENT': 'valgrind', 'B2_TOOLSET': 'clang-14', 'B2_CXXSTD': '11,14,17', 'B2_DEFINES': 'BOOST_NO_STRESS_TEST=1', 'B2_VARIANT': 'debug', 'B2_TESTFLAGS': 'testing.launcher=valgrind', 'VALGRIND_OPTS': '--error-exitcode=1'}, globalenv=globalenv), - # arm64 (unsigned char) - linux_cxx("ARM64: GCC 11", "g++-11", packages="g++-11", buildscript="drone", buildtype="boost", image="cppalliance/droneubuntu2004:multiarch", environment={'B2_TOOLSET': 'gcc-11', 'B2_CXXFLAGS': '-Werror', 'B2_CXXSTD': '17,20'}, arch="arm64", globalenv=globalenv), +# Base environment for all jobs +globalenv={'B2_VARIANT': 'release'} - # s390x - linux_cxx("S390x: Clang 12", "clang++-12", packages="clang-12 libstdc++-9-dev", llvm_os="focal", llvm_ver="12", buildtype="boost", buildscript="drone", image="cppalliance/droneubuntu2004:multiarch", environment={'B2_TOOLSET': 'clang-12', 'B2_CXXFLAGS': '-Werror', 'B2_CXXSTD': '17,20'}, arch="s390x", globalenv=globalenv), +# Wrapper function to apply the globalenv to all jobs +def job( + # job specific environment options + env={}, + **kwargs): + real_env = dict(globalenv) + real_env.update(env) + return job_impl(env=real_env, **kwargs) - # Documentation - # linux_cxx("Docs", "g++", packages="docbook docbook-xml docbook-xsl python3-jinja2 xsltproc flex libfl-dev bison unzip rsync", buildtype="docs", buildscript="drone", image="cppalliance/droneubuntu1804:1", environment={'COMMENT': 'docs'}, globalenv=globalenv), - - # CMake tests (https://github.com/boostorg/boost-ci) - ## Compiling as part of the boost superproject - linux_cxx("CMake Superproject", "g++", packages="", buildscript="drone", buildtype="cmake-superproject", image="cppalliance/droneubuntu1804:1", globalenv=globalenv), - ## Installing - # linux_cxx("CMake Install", "g++", packages="", buildscript="drone", buildtype="cmake1", image="cppalliance/droneubuntu1804:1", environment={'CMAKE_INSTALL_TEST': '1'}, globalenv=globalenv), - - # ------------------------------------------------------------------ - - # OSX - osx_cxx("OSX: Clang", "g++", packages="", buildscript="drone", buildtype="boost", xcode_version="13.4.1", environment={'B2_TOOLSET': 'clang', 'B2_CXXFLAGS': '-Werror', 'B2_CXXSTD': '11,17'}, globalenv=globalenv), - - # GCC (All other versions) - linux_cxx("GCC 4.9: C++11", "g++-4.9", packages="g++-4.9", buildscript="drone", buildtype="boost", image="cppalliance/droneubuntu1604:1", environment={'B2_TOOLSET': 'gcc-4.9', 'B2_CXXFLAGS': '-Werror', 'B2_CXXSTD': '11'}, globalenv=globalenv), - linux_cxx("GCC 5: C++11", "g++-5", packages="g++-5", buildscript="drone", buildtype="boost", image=linuxglobalimage, environment={'B2_TOOLSET': 'gcc-5', 'B2_CXXFLAGS': '-Werror', 'B2_CXXSTD': '11'}, globalenv=globalenv), - linux_cxx("GCC 6: C++11,14", "g++-6", packages="g++-6", buildscript="drone", buildtype="boost", image=linuxglobalimage, environment={'B2_TOOLSET': 'gcc-6', 'B2_CXXFLAGS': '-Werror', 'B2_CXXSTD': '11,14'}, globalenv=globalenv), - linux_cxx("GCC 7: C++14,17", "g++-7", packages="g++-7", buildscript="drone", buildtype="boost", image=linuxglobalimage, environment={'B2_TOOLSET': 'gcc-7', 'B2_CXXFLAGS': '-Werror', 'B2_CXXSTD': '14,17'}, globalenv=globalenv), - linux_cxx("GCC 8: C++17", "g++-8", packages="g++-8", buildscript="drone", buildtype="boost", image=linuxglobalimage, environment={'B2_TOOLSET': 'gcc-8', 'B2_CXXFLAGS': '-Werror', 'B2_CXXSTD': '17'}, globalenv=globalenv), - linux_cxx("GCC 9: C++17", "g++-9", packages="g++-9", buildscript="drone", buildtype="boost", image=linuxglobalimage, environment={'B2_TOOLSET': 'gcc-9', 'B2_CXXFLAGS': '-Werror', 'B2_CXXSTD': '17'}, globalenv=globalenv), - linux_cxx("GCC 10: C++17", "g++-10", packages="g++-10", buildscript="drone", buildtype="boost", image=linuxglobalimage, environment={'B2_TOOLSET': 'gcc-10', 'B2_CXXFLAGS': '-Werror', 'B2_CXXSTD': '17'}, globalenv=globalenv), - linux_cxx("GCC 11: C++17,20", "g++-11", packages="g++-11", buildscript="drone", buildtype="boost", image=linuxglobalimage, environment={'B2_TOOLSET': 'gcc-11', 'B2_CXXFLAGS': '-Werror', 'B2_CXXSTD': '17,20'}, globalenv=globalenv), - - # Clang (All other versions) - linux_cxx("Clang 4.0: C++11,14", "clang++-4.0", packages="clang-4.0 libstdc++-6-dev", llvm_os="xenial", llvm_ver="4.0", buildscript="drone", buildtype="boost", image="cppalliance/droneubuntu1804:1", environment={'B2_TOOLSET': 'clang-4.0', 'B2_CXXFLAGS': '', 'B2_CXXSTD': '11,14'}, globalenv=globalenv), - linux_cxx("Clang 5.0: C++11,14", "clang++-5.0", packages="clang-5.0 libstdc++-7-dev", llvm_os="bionic", llvm_ver="5.0", buildscript="drone", buildtype="boost", image=linuxglobalimage, environment={'B2_TOOLSET': 'clang-5.0', 'B2_CXXFLAGS': '', 'B2_CXXSTD': '11,14'}, globalenv=globalenv), - linux_cxx("Clang 6.0: C++11,14", "clang++-6.0", packages="clang-6.0 libc6-dbg libc++-dev libc++abi-dev libstdc++-8-dev", llvm_os="bionic", llvm_ver="6.0", buildscript="drone", buildtype="boost", image=linuxglobalimage, environment={'B2_TOOLSET': 'clang-6.0', 'B2_CXXFLAGS': '-Werror', 'B2_CXXSTD': '11,14', 'B2_STDLIB': 'libc++'}, globalenv=globalenv), - linux_cxx("Clang 6.0: C++14,17", "clang++-6.0", packages="clang-6.0 libc6-dbg libc++-dev libc++abi-dev libstdc++-8-dev", llvm_os="bionic", llvm_ver="6.0", buildscript="drone", buildtype="boost", image=linuxglobalimage, environment={'B2_TOOLSET': 'clang-6.0', 'B2_CXXFLAGS': '-Werror', 'B2_CXXSTD': '14,17'}, globalenv=globalenv), - linux_cxx("Clang 7: C++17", "clang++-7", packages="clang-7 libc6-dbg libc++-dev libstdc++-8-dev", llvm_os="bionic", llvm_ver="7", buildscript="drone", buildtype="boost", image=linuxglobalimage, environment={'B2_TOOLSET': 'clang-7', 'B2_CXXFLAGS': '-Werror', 'B2_CXXSTD': '17'}, globalenv=globalenv), - linux_cxx("Clang 8: C++17", "clang++-8", packages="clang-8 libc6-dbg libc++-dev libstdc++-8-dev", llvm_os="bionic", llvm_ver="8", buildscript="drone", buildtype="boost", image=linuxglobalimage, environment={'B2_TOOLSET': 'clang-8', 'B2_CXXFLAGS': '-Werror', 'B2_CXXSTD': '17'}, globalenv=globalenv), - linux_cxx("Clang 9: C++14,17", "clang++-9", packages="clang-9 libstdc++-9-dev", llvm_os="bionic", llvm_ver="9", buildscript="drone", buildtype="boost", image=linuxglobalimage, environment={'B2_TOOLSET': 'clang-9', 'B2_CXXFLAGS': '-Werror', 'B2_CXXSTD': '14,17'}, globalenv=globalenv), - linux_cxx("Clang 10: C++14,17", "clang++-10", packages="clang-10 libstdc++-9-dev", llvm_os="focal", llvm_ver="10", buildscript="drone", buildtype="boost", image="cppalliance/droneubuntu2004:1", environment={'B2_TOOLSET': 'clang-10', 'B2_CXXFLAGS': '-Werror', 'B2_CXXSTD': '14,17'}, globalenv=globalenv), - linux_cxx("Clang 11: C++14,17", "clang++-11", packages="clang-11 libstdc++-9-dev", llvm_os="focal", llvm_ver="11", buildscript="drone", buildtype="boost", image="cppalliance/droneubuntu2004:1", environment={'B2_TOOLSET': 'clang-11', 'B2_CXXFLAGS': '-Werror', 'B2_CXXSTD': '14,17'}, globalenv=globalenv), - linux_cxx("Clang 12: C++17,20", "clang++-12", packages="clang-12 libstdc++-9-dev", llvm_os="focal", llvm_ver="12", buildscript="drone", buildtype="boost", image="cppalliance/droneubuntu2004:1", environment={'B2_TOOLSET': 'clang-12', 'B2_CXXFLAGS': '-Werror', 'B2_CXXSTD': '17,20'}, globalenv=globalenv), - linux_cxx("Clang 13: C++17,20", "clang++-13", packages="clang-13 libstdc++-10-dev", llvm_os="jammy", llvm_ver="13", buildscript="drone", buildtype="boost", image="cppalliance/droneubuntu2204:1", environment={'B2_TOOLSET': 'clang-13', 'B2_CXXFLAGS': '-Werror', 'B2_CXXSTD': '17,20'}, globalenv=globalenv), - linux_cxx("Clang 14: C++17,20", "clang++-14", packages="clang-14 libstdc++-10-dev", llvm_os="jammy", llvm_ver="14", buildscript="drone", buildtype="boost", image="cppalliance/droneubuntu2204:1", environment={'B2_TOOLSET': 'clang-14', 'B2_CXXFLAGS': '-Werror', 'B2_CXXSTD': '17,20'}, globalenv=globalenv), - - # arm64 (unsigned char) - linux_cxx("ARM64: Clang 12", "clang++-12", packages="clang-12 libstdc++-9-dev", llvm_os="focal", llvm_ver="12", buildscript="drone", buildtype="boost", image="cppalliance/droneubuntu2004:multiarch", environment={'B2_TOOLSET': 'clang-12', 'B2_CXXFLAGS': '-Werror', 'B2_CXXSTD': '11,14,17,20'}, arch="arm64", globalenv=globalenv), - - # s390x - linux_cxx("S390x: GCC 11", "g++-11", packages="g++-11", buildtype="boost", buildscript="drone", image="cppalliance/droneubuntu2004:multiarch", environment={'B2_TOOLSET': 'gcc-11', 'B2_CXXFLAGS': '-Werror', 'B2_CXXSTD': '17'}, arch="s390x", globalenv=globalenv), - - # MSVC - windows_cxx("MSVC 14.1", "", image="cppalliance/dronevs2017", buildtype="boost", buildscript="drone", environment={"B2_TOOLSET": "msvc-14.1", 'B2_CXXFLAGS': '/WX', "B2_CXXSTD": "11,14,17"},globalenv=globalenv), - windows_cxx("MSVC 14.2: C++14,17,latest", "", image="cppalliance/dronevs2019", buildtype="boost", buildscript="drone", environment={"B2_TOOLSET": "msvc-14.2", 'B2_CXXFLAGS': '/WX', "B2_CXXSTD": "14,17,latest"},globalenv=globalenv), - windows_cxx("MSVC 14.3: C++17,20", "", image="cppalliance/dronevs2022", buildtype="boost", buildscript="drone", environment={"B2_TOOLSET": "msvc-14.3", 'B2_CXXFLAGS': '/WX', "B2_CXXSTD": "17,20"},globalenv=globalenv), -] +def main(ctx): + return [ + job(compiler='clang-3.8', cxxstd='11,14', os='ubuntu-16.04'), + job(compiler='clang-3.9', cxxstd='11,14', os='ubuntu-18.04'), + job(compiler='clang-4.0', cxxstd='11,14', os='ubuntu-18.04'), + job(compiler='clang-5.0', cxxstd='11,14,1z', os='ubuntu-18.04'), + job(compiler='clang-6.0', cxxstd='11,14,17', os='ubuntu-18.04'), + job(compiler='clang-7', cxxstd='11,14,17', os='ubuntu-18.04'), + job(compiler='clang-8', cxxstd='11,14,17,2a', os='ubuntu-18.04'), + job(compiler='clang-9', cxxstd='11,14,17,2a', os='ubuntu-18.04'), + job(compiler='clang-10', cxxstd='11,14,17,2a', os='ubuntu-18.04'), + job(compiler='clang-11', cxxstd='11,14,17,2a', os='ubuntu-22.04'), + job(compiler='clang-12', cxxstd='11,14,17,20', os='ubuntu-22.04'), + job(compiler='clang-13', cxxstd='11,14,17,20,2b', os='ubuntu-22.04'), + job(compiler='clang-14', cxxstd='11,14,17,20,2b', os='ubuntu-22.04'), + job(compiler='clang-15', cxxstd='11,14,17,20,2b', os='ubuntu-22.04', add_llvm=True, + env={'B2_CXXFLAGS': '-Werror'}), + job(name='Clang 15 standalone', compiler='clang-15', cxxstd='11,14,17,20,2b', os='ubuntu-22.04', add_llvm=True, + env={'B2_CXXFLAGS': '-Werror', 'B2_DEFINES': 'BOOST_STATIC_STRING_STANDALONE'}), + + job(compiler='gcc-4.8', cxxstd='11', os='ubuntu-16.04'), + job(compiler='gcc-4.9', cxxstd='11', os='ubuntu-16.04'), + job(compiler='gcc-5', cxxstd='11,14,1z', os='ubuntu-18.04'), + job(compiler='gcc-6', cxxstd='11,14,1z', os='ubuntu-18.04'), + job(compiler='gcc-7', cxxstd='11,14,1z', os='ubuntu-18.04'), + job(compiler='gcc-8', cxxstd='11,14,17,2a', os='ubuntu-18.04'), + job(compiler='gcc-9', cxxstd='11,14,17,2a', os='ubuntu-18.04'), + job(compiler='gcc-10', cxxstd='11,14,17,20', os='ubuntu-22.04'), + job(compiler='gcc-11', cxxstd='11,14,17,20,2b', os='ubuntu-22.04'), + job(compiler='gcc-12', cxxstd='11,14,17,20,2b', os='ubuntu-22.04'), + + job(name='Coverage', buildtype='codecov', buildscript='codecov_coveralls', env={'LCOV_BRANCH_COVERAGE': 1, "COVERALLS_REPO_TOKEN": {"from_secret": "coveralls_repo_token"}}, + compiler='gcc-8', cxxstd='11,14,17,2a', os='ubuntu-18.04'), + # Sanitizers + job(name='ASAN', asan=True, + compiler='gcc-12', cxxstd='11,14,17,20', os='ubuntu-22.04'), + job(name='UBSAN', ubsan=True, + compiler='gcc-12', cxxstd='11,14,17,20', os='ubuntu-22.04'), + job(name='TSAN', tsan=True, + compiler='gcc-12', cxxstd='11,14,17,20', os='ubuntu-22.04'), + job(name='Clang 14 w/ sanitizers', asan=True, ubsan=True, + compiler='clang-14', cxxstd='11,14,17,20', os='ubuntu-22.04'), + job(name='Clang 11 libc++ w/ sanitizers', asan=True, ubsan=True, # libc++-11 is the latest working with ASAN: https://github.com/llvm/llvm-project/issues/59432 + compiler='clang-11', cxxstd='11,14,17,20', os='ubuntu-20.04', stdlib='libc++', install='libc++-11-dev libc++abi-11-dev'), + job(name='Valgrind', valgrind=True, + compiler='clang-6.0', cxxstd='11,14,1z', os='ubuntu-18.04', install='libc6-dbg libc++-dev libstdc++-8-dev'), + + # libc++ + job(compiler='clang-6.0', cxxstd='11,14,17,2a', os='ubuntu-18.04', stdlib='libc++', install='libc++-dev libc++abi-dev'), + job(compiler='clang-7', cxxstd='11,14,17,2a', os='ubuntu-20.04', stdlib='libc++', install='libc++-7-dev libc++abi-7-dev'), + job(compiler='clang-8', cxxstd='11,14,17,2a', os='ubuntu-20.04', stdlib='libc++', install='libc++-8-dev libc++abi-8-dev'), + job(compiler='clang-9', cxxstd='11,14,17,2a', os='ubuntu-20.04', stdlib='libc++', install='libc++-9-dev libc++abi-9-dev'), + job(compiler='clang-10', cxxstd='11,14,17,20', os='ubuntu-20.04', stdlib='libc++', install='libc++-10-dev libc++abi-10-dev'), + job(compiler='clang-11', cxxstd='11,14,17,20', os='ubuntu-20.04', stdlib='libc++', install='libc++-11-dev libc++abi-11-dev'), + job(compiler='clang-12', cxxstd='11,14,17,20', os='ubuntu-22.04', stdlib='libc++', install='libc++-12-dev libc++abi-12-dev libunwind-12-dev'), + job(compiler='clang-13', cxxstd='11,14,17,20', os='ubuntu-22.04', stdlib='libc++', install='libc++-13-dev libc++abi-13-dev'), + job(compiler='clang-14', cxxstd='11,14,17,20', os='ubuntu-22.04', stdlib='libc++', install='libc++-14-dev libc++abi-14-dev'), + job(compiler='clang-15', cxxstd='11,14,17,20', os='ubuntu-22.04', stdlib='libc++', install='libc++-15-dev libc++abi-15-dev', add_llvm=True), + + # FreeBSD + job(compiler='clang-10', cxxstd='11,14,17,20', os='freebsd-13.1'), + job(compiler='clang-15', cxxstd='11,14,17,20', os='freebsd-13.1'), + job(compiler='gcc-11', cxxstd='11,14,17,20', os='freebsd-13.1', linkflags='-Wl,-rpath=/usr/local/lib/gcc11'), + # OSX + job(compiler='clang', cxxstd='11,14,17,2a', os='osx-xcode-10.1'), + job(compiler='clang', cxxstd='11,14,17,2a', os='osx-xcode-10.3'), + job(compiler='clang', cxxstd='11,14,17,2a', os='osx-xcode-11.1'), + job(compiler='clang', cxxstd='11,14,17,2a', os='osx-xcode-11.7'), + job(compiler='clang', cxxstd='11,14,17,2a', os='osx-xcode-12'), + job(compiler='clang', cxxstd='11,14,17,20', os='osx-xcode-12.5.1'), + job(compiler='clang', cxxstd='11,14,17,20', os='osx-xcode-13.0'), + job(compiler='clang', cxxstd='11,14,17,20', os='osx-xcode-13.4.1'), + job(compiler='clang', cxxstd='11,14,17,20,2b', os='osx-xcode-14.0'), + job(compiler='clang', cxxstd='11,14,17,20,2b', os='osx-xcode-14.3.1'), + job(compiler='clang', cxxstd='11,14,17,20,2b', os='osx-xcode-15.0.1'), + # ARM64 + job(compiler='clang-12', cxxstd='11,14,17,20', os='ubuntu-20.04', arch='arm64', add_llvm=True), + job(compiler='gcc-11', cxxstd='11,14,17,20', os='ubuntu-20.04', arch='arm64'), + # S390x + job(compiler='clang-12', cxxstd='11,14,17,20', os='ubuntu-20.04', arch='s390x', add_llvm=True), + job(compiler='gcc-11', cxxstd='11,14,17,20', os='ubuntu-20.04', arch='s390x'), + # Windows + job(compiler='msvc-14.0', cxxstd=None, os='windows', env={'B2_DONT_EMBED_MANIFEST': 1}), + job(compiler='msvc-14.1', cxxstd=None, os='windows'), + job(compiler='msvc-14.2', cxxstd=None, os='windows'), + job(compiler='msvc-14.3', cxxstd=None, os='windows'), + job(compiler='msvc-14.0', cxxstd='14,17,20', os='windows', env={'B2_DONT_EMBED_MANIFEST': 1}), + job(compiler='msvc-14.1', cxxstd='14,17,20', os='windows'), + job(compiler='msvc-14.2', cxxstd='14,17,20', os='windows'), + job(compiler='msvc-14.3', cxxstd='14,17,20,latest', os='windows'), + ] # from https://github.com/boostorg/boost-ci -load("@boost_ci//ci/drone/:functions.star", "linux_cxx","windows_cxx","osx_cxx","freebsd_cxx") +load("@boost_ci//ci/drone/:functions.star", "linux_cxx", "windows_cxx", "osx_cxx", "freebsd_cxx", "job_impl") diff --git a/.drone/codecov_coveralls.sh b/.drone/codecov_coveralls.sh new file mode 100644 index 0000000..1cb8314 --- /dev/null +++ b/.drone/codecov_coveralls.sh @@ -0,0 +1,28 @@ +#!/bin/bash + +# Copyright 2020 Rene Rivera, Sam Darwin +# Copyright 2025 Alexander Grund +# Distributed under the Boost Software License, Version 1.0. +# (See accompanying file LICENSE.txt or copy at http://boost.org/LICENSE_1_0.txt) + + +set -xe + +# Run the regular Boost CI script which does the test & upload to codecov.io +wget https://github.com/boostorg/boost-ci/raw/refs/heads/master/.drone/drone.sh +. drone.sh + +# coveralls +# uses multiple lcov steps from boost-ci codecov.sh script +if [ -n "${COVERALLS_REPO_TOKEN}" ]; then + echo "processing coveralls" + pip3 install --user cpp-coveralls + cd "$BOOST_CI_SRC_FOLDER" + + export PATH=/tmp/lcov/bin:$PATH + command -v lcov + lcov --version + + lcov --remove coverage.info -o coverage_filtered.info '*/test/*' '*/extra/*' + cpp-coveralls --verbose -l coverage_filtered.info +fi diff --git a/.drone/drone.bat b/.drone/drone.bat deleted file mode 100644 index 0dc0d6c..0000000 --- a/.drone/drone.bat +++ /dev/null @@ -1,31 +0,0 @@ - -@ECHO ON -setlocal enabledelayedexpansion - -if "%DRONE_JOB_BUILDTYPE%" == "boost" ( - -echo '==================================> INSTALL' - -git clone https://github.com/boostorg/boost-ci.git boost-ci-cloned --depth 1 -cp -prf boost-ci-cloned/ci . -rm -rf boost-ci-cloned -REM source ci/travis/install.sh -REM The contents of install.sh below: - -for /F %%i in ("%DRONE_REPO%") do @set SELF=%%~nxi -SET BOOST_CI_TARGET_BRANCH=%DRONE_COMMIT_BRANCH% -SET BOOST_CI_SRC_FOLDER=%cd% - -call ci\common_install.bat - -echo '==================================> COMPILE' - -REM set B2_TARGETS=libs/!SELF!/test libs/!SELF!/example -set B2_TARGETS=libs/!SELF!/test -call !BOOST_ROOT!\libs\!SELF!\ci\build.bat - -) else if "%DRONE_JOB_BUILDTYPE%" == "standalone-windows" ( - -REM not used - -) \ No newline at end of file diff --git a/.drone/drone.sh b/.drone/drone.sh deleted file mode 100755 index 0affbfd..0000000 --- a/.drone/drone.sh +++ /dev/null @@ -1,231 +0,0 @@ -#!/bin/bash - -# Copyright 2020 Rene Rivera, Sam Darwin -# Distributed under the Boost Software License, Version 1.0. -# (See accompanying file LICENSE.txt or copy at http://boost.org/LICENSE_1_0.txt) - -set -xe - -export TRAVIS_BUILD_DIR=$(pwd) -export DRONE_BUILD_DIR=$(pwd) -export TRAVIS_BRANCH=$DRONE_BRANCH -export TRAVIS_EVENT_TYPE=$DRONE_BUILD_EVENT -export VCS_COMMIT_ID=$DRONE_COMMIT -export GIT_COMMIT=$DRONE_COMMIT -export REPO_NAME=$DRONE_REPO -export USER=$(whoami) -export CC=${CC:-gcc} -export PATH=~/.local/bin:/usr/local/bin:$PATH - -common_install() { - git clone https://github.com/boostorg/boost-ci.git boost-ci-cloned --depth 1 - cp -prf boost-ci-cloned/ci . - rm -rf boost-ci-cloned - - if [ "$TRAVIS_OS_NAME" == "osx" ]; then - unset -f cd - fi - - export SELF=$(basename $REPO_NAME) - export BOOST_CI_TARGET_BRANCH="$TRAVIS_BRANCH" - export BOOST_CI_SRC_FOLDER=$(pwd) - - . ./ci/common_install.sh -} - -if [ "$DRONE_JOB_BUILDTYPE" == "boost" ]; then - - echo '==================================> INSTALL' - - common_install - - echo '==================================> SCRIPT' - - export B2_TARGETS=${B2_TARGETS:-"libs/$SELF/test"} - $BOOST_ROOT/libs/$SELF/ci/travis/build.sh - -elif [ "$DRONE_JOB_BUILDTYPE" == "docs" ]; then - - echo '==================================> INSTALL' - - export SELF=$(basename $REPO_NAME) - - pwd - cd .. - mkdir -p $HOME/cache && cd $HOME/cache - if [ ! -d doxygen ]; then git clone -b 'Release_1_8_15' --depth 1 https://github.com/doxygen/doxygen.git && echo "not-cached"; else echo "cached"; fi - cd doxygen - cmake -H. -Bbuild -DCMAKE_BUILD_TYPE=Release - cd build - sudo make install - cd ../../.. - BOOST_BRANCH=develop && [ "$TRAVIS_BRANCH" == "master" ] && BOOST_BRANCH=master || true - git clone -b $BOOST_BRANCH https://github.com/boostorg/boost.git boost-root --depth 1 - cd boost-root - export BOOST_ROOT=$(pwd) - git submodule update --init libs/context - git submodule update --init tools/boostbook - git submodule update --init tools/boostdep - git submodule update --init tools/docca - git submodule update --init tools/quickbook - rsync -av $TRAVIS_BUILD_DIR/ libs/$SELF - python tools/boostdep/depinst/depinst.py ../tools/quickbook - ./bootstrap.sh - ./b2 headers - - echo '==================================> SCRIPT' - - echo "using doxygen ; using boostbook ; using python : : python3 ;" >tools/build/src/user-config.jam - ./b2 -j3 libs/$SELF/doc//boostrelease - -elif [ "$DRONE_JOB_BUILDTYPE" == "codecov" ]; then - - echo '==================================> INSTALL' - - common_install - - echo '==================================> SCRIPT' - - set +e - - cd $BOOST_ROOT/libs/$SELF - ci/travis/codecov.sh - - # coveralls - # uses multiple lcov steps from boost-ci codecov.sh script - if [ -n "${COVERALLS_REPO_TOKEN}" ]; then - echo "processing coveralls" - pip3 install --user cpp-coveralls - cd $BOOST_CI_SRC_FOLDER - - export PATH=/tmp/lcov/bin:$PATH - command -v lcov - lcov --version - - lcov --remove coverage.info -o coverage_filtered.info '*/test/*' '*/extra/*' - cpp-coveralls --verbose -l coverage_filtered.info - fi - -elif [ "$DRONE_JOB_BUILDTYPE" == "valgrind" ]; then - - echo '==================================> INSTALL' - - common_install - - echo '==================================> SCRIPT' - - cd $BOOST_ROOT/libs/$SELF - ci/travis/valgrind.sh - -elif [ "$DRONE_JOB_BUILDTYPE" == "standalone" ]; then - - echo '==================================> INSTALL' - - # Installing cmake with apt-get, so not required here: - # pip install --user cmake - - echo '==================================> SCRIPT' - - export CXXFLAGS="-Wall -Wextra -Werror -std=c++17" - mkdir __build_17 - cd __build_17 - cmake -DBOOST_JSON_STANDALONE=1 .. - cmake --build . - ctest -V . - export CXXFLAGS="-Wall -Wextra -Werror -std=c++2a" - mkdir ../__build_2a - cd ../__build_2a - cmake -DBOOST_JSON_STANDALONE=1 .. - cmake --build . - ctest -V . - -elif [ "$DRONE_JOB_BUILDTYPE" == "coverity" ]; then - - echo '==================================> INSTALL' - - common_install - - echo '==================================> SCRIPT' - - if [ -n "${COVERITY_SCAN_NOTIFICATION_EMAIL}" -a \( "$TRAVIS_BRANCH" = "develop" -o "$TRAVIS_BRANCH" = "master" \) -a \( "$DRONE_BUILD_EVENT" = "push" -o "$DRONE_BUILD_EVENT" = "cron" \) ]; then - cd $BOOST_ROOT/libs/$SELF - ci/travis/coverity.sh - fi - -elif [ "$DRONE_JOB_BUILDTYPE" == "cmake-superproject" ]; then - - echo '==================================> INSTALL' - - common_install - - echo '==================================> COMPILE' - - # May want to re-enable -Werror - # export CXXFLAGS="-Wall -Wextra -Werror" - export CXXFLAGS="-Wall -Wextra" - - mkdir __build_static - cd __build_static - cmake -DBOOST_ENABLE_CMAKE=1 -DBUILD_TESTING=ON -DBoost_VERBOSE=1 \ - -DBOOST_INCLUDE_LIBRARIES=$SELF .. - cmake --build . - ctest --output-on-failure -R boost_$SELF - - cd .. - - mkdir __build_shared - cd __build_shared - cmake -DBOOST_ENABLE_CMAKE=1 -DBUILD_TESTING=ON -DBoost_VERBOSE=1 \ - -DBOOST_INCLUDE_LIBRARIES=$SELF -DBUILD_SHARED_LIBS=ON .. - cmake --build . - ctest --output-on-failure -R boost_$SELF - -elif [ "$DRONE_JOB_BUILDTYPE" == "cmake1" ]; then - - echo '==================================> INSTALL' - - # https://github.com/opencv/opencv-python#frequently-asked-questions - pip install --upgrade pip - pip install --user cmake - - echo '==================================> SCRIPT' - - export SELF=$(basename $REPO_NAME) - BOOST_BRANCH=develop && [ "$DRONE_BRANCH" == "master" ] && BOOST_BRANCH=master || true - echo BOOST_BRANCH: $BOOST_BRANCH - cd .. - git clone -b $BOOST_BRANCH --depth 1 https://github.com/boostorg/boost.git boost-root - cd boost-root - # mkdir -p libs/$SELF - # cp -r $DRONE_BUILD_DIR/* libs/$SELF - # git submodule update --init tools/boostdep - git submodule update --init --recursive - mkdir -p libs/$SELF - cp -r $DRONE_BUILD_DIR/* libs/$SELF - - # CMake tests - cd libs/$SELF - mkdir __build__ && cd __build__ - cmake -DCMAKE_INSTALL_PREFIX=~/.local .. - cmake --build . --target install - ctest --output-on-failure - - # CMake subdir tests - cd ../test/cmake_test && mkdir __build__ && cd __build__ - cmake -DCMAKE_INSTALL_PREFIX=~/.local .. - cmake --build . - cmake --build . --target check - ctest --output-on-failure - - # Install Library - cd ../../../../.. && mkdir __build_cmake_install_test__ && cd __build_cmake_install_test__ - cmake -DBOOST_INCLUDE_LIBRARIES=$SELF -DCMAKE_INSTALL_PREFIX=~/.local -DBoost_VERBOSE=ON -DBoost_DEBUG=ON .. - cmake --build . --target install - - # CMake install tests - cd ../libs/$SELF/test/cmake_test && mkdir __build_cmake_install_test__ && cd __build_cmake_install_test__ - cmake -DBOOST_CI_INSTALL_TEST=ON -DCMAKE_PREFIX_PATH=~/.local .. - cmake --build . - ctest --output-on-failure - -fi From ee172b86fd4de9ae7e409e1b6d7c0c4c53f6d385 Mon Sep 17 00:00:00 2001 From: Alexander Grund Date: Thu, 23 Oct 2025 17:11:04 +0200 Subject: [PATCH 54/73] Try standalone only with >=C++17 --- .drone.star | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.drone.star b/.drone.star index 8b74829..78105c0 100644 --- a/.drone.star +++ b/.drone.star @@ -38,7 +38,7 @@ def main(ctx): job(compiler='clang-14', cxxstd='11,14,17,20,2b', os='ubuntu-22.04'), job(compiler='clang-15', cxxstd='11,14,17,20,2b', os='ubuntu-22.04', add_llvm=True, env={'B2_CXXFLAGS': '-Werror'}), - job(name='Clang 15 standalone', compiler='clang-15', cxxstd='11,14,17,20,2b', os='ubuntu-22.04', add_llvm=True, + job(name='Clang 15 standalone', compiler='clang-15', cxxstd='17,20,2b', os='ubuntu-22.04', add_llvm=True, env={'B2_CXXFLAGS': '-Werror', 'B2_DEFINES': 'BOOST_STATIC_STRING_STANDALONE'}), job(compiler='gcc-4.8', cxxstd='11', os='ubuntu-16.04'), From db1ea76a17799b0ca6fe3c25db8cc856567334b7 Mon Sep 17 00:00:00 2001 From: Alexander Grund Date: Tue, 30 Sep 2025 19:37:27 +0200 Subject: [PATCH 55/73] Fix required CMake version `source_group(TREE` requires CMake 3.8 --- CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 6bf922d..bace101 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -7,7 +7,7 @@ # Official repository: https://github.com/boostorg/static_string # -cmake_minimum_required(VERSION 3.5...3.16) +cmake_minimum_required(VERSION 3.8...3.16) project(boost_static_string VERSION "${BOOST_SUPERPROJECT_VERSION}" LANGUAGES CXX) From fbd6051165543a4a4ff1f7a03f30761a9064f678 Mon Sep 17 00:00:00 2001 From: Alexander Grund Date: Mon, 25 Aug 2025 17:26:42 +0200 Subject: [PATCH 56/73] Update Link to regression test matrix in README --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 46166ce..bddf063 100644 --- a/README.md +++ b/README.md @@ -2,8 +2,8 @@ Branch | Travis | Appveyor | Azure Pipelines | codecov.io | Docs | Matrix | :-------------: | ------ | -------- | --------------- | ---------- | ---- | ------ | -[`master`](https://github.com/boostorg/static_string/tree/master) | [![Build Status](https://travis-ci.org/boostorg/static_string.svg?branch=master)](https://travis-ci.org/boostorg/static_string) | [![Build status](https://ci.appveyor.com/api/projects/status/64es4wg4w7mc5wn2/branch/master?svg=true)](https://ci.appveyor.com/project/sdkrystian/static-string/branch/master) | [![Build Status](https://krystiands.visualstudio.com/static_string/_apis/build/status/Boost.StaticString?branchName=master)](https://krystiands.visualstudio.com/static_string/_build/latest?definitionId=3&branchName=master) | [![codecov](https://codecov.io/gh/boostorg/static_string/branch/master/graph/badge.svg)](https://codecov.io/gh/boostorg/static_string/branch/master) | [![Documentation](https://img.shields.io/badge/docs-master-brightgreen.svg)](http://www.boost.org/doc/libs/release/libs/static_string) | [![Matrix](https://img.shields.io/badge/matrix-master-brightgreen.svg)](http://www.boost.org/development/tests/master/developer/static_string.html) -[`develop`](https://github.com/boostorg/static_string/tree/develop) | [![Build Status](https://travis-ci.org/boostorg/static_string.svg?branch=develop)](https://travis-ci.org/boostorg/static_string) | [![Build status](https://ci.appveyor.com/api/projects/status/64es4wg4w7mc5wn2/branch/develop?svg=true)](https://ci.appveyor.com/project/sdkrystian/static-string/branch/develop) | [![Build Status](https://krystiands.visualstudio.com/static_string/_apis/build/status/Boost.StaticString?branchName=develop)](https://krystiands.visualstudio.com/static_string/_build/latest?definitionId=3&branchName=develop) | [![codecov](https://codecov.io/gh/boostorg/static_string/branch/develop/graph/badge.svg)](https://codecov.io/gh/boostorg/static_string/branch/develop) | [![Documentation](https://img.shields.io/badge/docs-develop-brightgreen.svg)](http://www.boost.org/doc/libs/develop/libs/static_string) | [![Matrix](https://img.shields.io/badge/matrix-develop-brightgreen.svg)](http://www.boost.org/development/tests/develop/developer/static_string.html) +[`master`](https://github.com/boostorg/static_string/tree/master) | [![Build Status](https://travis-ci.org/boostorg/static_string.svg?branch=master)](https://travis-ci.org/boostorg/static_string) | [![Build status](https://ci.appveyor.com/api/projects/status/64es4wg4w7mc5wn2/branch/master?svg=true)](https://ci.appveyor.com/project/sdkrystian/static-string/branch/master) | [![Build Status](https://krystiands.visualstudio.com/static_string/_apis/build/status/Boost.StaticString?branchName=master)](https://krystiands.visualstudio.com/static_string/_build/latest?definitionId=3&branchName=master) | [![codecov](https://codecov.io/gh/boostorg/static_string/branch/master/graph/badge.svg)](https://codecov.io/gh/boostorg/static_string/branch/master) | [![Documentation](https://img.shields.io/badge/docs-master-brightgreen.svg)](http://www.boost.org/doc/libs/release/libs/static_string) | [![Matrix](https://img.shields.io/badge/matrix-master-brightgreen.svg)](https://regression.boost.io/master/developer/static_string.html) +[`develop`](https://github.com/boostorg/static_string/tree/develop) | [![Build Status](https://travis-ci.org/boostorg/static_string.svg?branch=develop)](https://travis-ci.org/boostorg/static_string) | [![Build status](https://ci.appveyor.com/api/projects/status/64es4wg4w7mc5wn2/branch/develop?svg=true)](https://ci.appveyor.com/project/sdkrystian/static-string/branch/develop) | [![Build Status](https://krystiands.visualstudio.com/static_string/_apis/build/status/Boost.StaticString?branchName=develop)](https://krystiands.visualstudio.com/static_string/_build/latest?definitionId=3&branchName=develop) | [![codecov](https://codecov.io/gh/boostorg/static_string/branch/develop/graph/badge.svg)](https://codecov.io/gh/boostorg/static_string/branch/develop) | [![Documentation](https://img.shields.io/badge/docs-develop-brightgreen.svg)](http://www.boost.org/doc/libs/develop/libs/static_string) | [![Matrix](https://img.shields.io/badge/matrix-develop-brightgreen.svg)](https://regression.boost.io/develop/developer/static_string.html) ## Introduction From 4c84b6197538133a25c587a50dd2ecd7ff7b5154 Mon Sep 17 00:00:00 2001 From: Alexander Grund Date: Fri, 3 Oct 2025 12:21:54 +0200 Subject: [PATCH 57/73] README: Replace travis badges by GHA badges --- README.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index bddf063..e72d03d 100644 --- a/README.md +++ b/README.md @@ -1,9 +1,9 @@ # Boost.StaticString -Branch | Travis | Appveyor | Azure Pipelines | codecov.io | Docs | Matrix | +Branch | GHA CI | Appveyor | Azure Pipelines | codecov.io | Docs | Matrix | :-------------: | ------ | -------- | --------------- | ---------- | ---- | ------ | -[`master`](https://github.com/boostorg/static_string/tree/master) | [![Build Status](https://travis-ci.org/boostorg/static_string.svg?branch=master)](https://travis-ci.org/boostorg/static_string) | [![Build status](https://ci.appveyor.com/api/projects/status/64es4wg4w7mc5wn2/branch/master?svg=true)](https://ci.appveyor.com/project/sdkrystian/static-string/branch/master) | [![Build Status](https://krystiands.visualstudio.com/static_string/_apis/build/status/Boost.StaticString?branchName=master)](https://krystiands.visualstudio.com/static_string/_build/latest?definitionId=3&branchName=master) | [![codecov](https://codecov.io/gh/boostorg/static_string/branch/master/graph/badge.svg)](https://codecov.io/gh/boostorg/static_string/branch/master) | [![Documentation](https://img.shields.io/badge/docs-master-brightgreen.svg)](http://www.boost.org/doc/libs/release/libs/static_string) | [![Matrix](https://img.shields.io/badge/matrix-master-brightgreen.svg)](https://regression.boost.io/master/developer/static_string.html) -[`develop`](https://github.com/boostorg/static_string/tree/develop) | [![Build Status](https://travis-ci.org/boostorg/static_string.svg?branch=develop)](https://travis-ci.org/boostorg/static_string) | [![Build status](https://ci.appveyor.com/api/projects/status/64es4wg4w7mc5wn2/branch/develop?svg=true)](https://ci.appveyor.com/project/sdkrystian/static-string/branch/develop) | [![Build Status](https://krystiands.visualstudio.com/static_string/_apis/build/status/Boost.StaticString?branchName=develop)](https://krystiands.visualstudio.com/static_string/_build/latest?definitionId=3&branchName=develop) | [![codecov](https://codecov.io/gh/boostorg/static_string/branch/develop/graph/badge.svg)](https://codecov.io/gh/boostorg/static_string/branch/develop) | [![Documentation](https://img.shields.io/badge/docs-develop-brightgreen.svg)](http://www.boost.org/doc/libs/develop/libs/static_string) | [![Matrix](https://img.shields.io/badge/matrix-develop-brightgreen.svg)](https://regression.boost.io/develop/developer/static_string.html) +[`master`](https://github.com/boostorg/static_string/tree/master) | [![Build Status](https://github.com/boostorg/static_string/actions/workflows/ci.yml/badge.svg?branch=master)](https://github.com/boostorg/static_string/actions?query=branch:master) | [![Build status](https://ci.appveyor.com/api/projects/status/64es4wg4w7mc5wn2/branch/master?svg=true)](https://ci.appveyor.com/project/sdkrystian/static-string/branch/master) | [![Build Status](https://krystiands.visualstudio.com/static_string/_apis/build/status/Boost.StaticString?branchName=master)](https://krystiands.visualstudio.com/static_string/_build/latest?definitionId=3&branchName=master) | [![codecov](https://codecov.io/gh/boostorg/static_string/branch/master/graph/badge.svg)](https://codecov.io/gh/boostorg/static_string/branch/master) | [![Documentation](https://img.shields.io/badge/docs-master-brightgreen.svg)](http://www.boost.org/doc/libs/release/libs/static_string) | [![Matrix](https://img.shields.io/badge/matrix-master-brightgreen.svg)](https://regression.boost.io/master/developer/static_string.html) +[`develop`](https://github.com/boostorg/static_string/tree/develop) | [![Build Status](https://github.com/boostorg/static_string/actions/workflows/ci.yml/badge.svg?branch=develop)](https://github.com/boostorg/static_string/actions?query=branch:develop) | [![Build status](https://ci.appveyor.com/api/projects/status/64es4wg4w7mc5wn2/branch/develop?svg=true)](https://ci.appveyor.com/project/sdkrystian/static-string/branch/develop) | [![Build Status](https://krystiands.visualstudio.com/static_string/_apis/build/status/Boost.StaticString?branchName=develop)](https://krystiands.visualstudio.com/static_string/_build/latest?definitionId=3&branchName=develop) | [![codecov](https://codecov.io/gh/boostorg/static_string/branch/develop/graph/badge.svg)](https://codecov.io/gh/boostorg/static_string/branch/develop) | [![Documentation](https://img.shields.io/badge/docs-develop-brightgreen.svg)](http://www.boost.org/doc/libs/develop/libs/static_string) | [![Matrix](https://img.shields.io/badge/matrix-develop-brightgreen.svg)](https://regression.boost.io/develop/developer/static_string.html) ## Introduction From a58319dbdd1b3c326bef3210e43732d60f2559d6 Mon Sep 17 00:00:00 2001 From: Alexander Grund Date: Fri, 3 Oct 2025 12:26:45 +0200 Subject: [PATCH 58/73] Switch boost.io to boost.org --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index e72d03d..cb4b34d 100644 --- a/README.md +++ b/README.md @@ -2,8 +2,8 @@ Branch | GHA CI | Appveyor | Azure Pipelines | codecov.io | Docs | Matrix | :-------------: | ------ | -------- | --------------- | ---------- | ---- | ------ | -[`master`](https://github.com/boostorg/static_string/tree/master) | [![Build Status](https://github.com/boostorg/static_string/actions/workflows/ci.yml/badge.svg?branch=master)](https://github.com/boostorg/static_string/actions?query=branch:master) | [![Build status](https://ci.appveyor.com/api/projects/status/64es4wg4w7mc5wn2/branch/master?svg=true)](https://ci.appveyor.com/project/sdkrystian/static-string/branch/master) | [![Build Status](https://krystiands.visualstudio.com/static_string/_apis/build/status/Boost.StaticString?branchName=master)](https://krystiands.visualstudio.com/static_string/_build/latest?definitionId=3&branchName=master) | [![codecov](https://codecov.io/gh/boostorg/static_string/branch/master/graph/badge.svg)](https://codecov.io/gh/boostorg/static_string/branch/master) | [![Documentation](https://img.shields.io/badge/docs-master-brightgreen.svg)](http://www.boost.org/doc/libs/release/libs/static_string) | [![Matrix](https://img.shields.io/badge/matrix-master-brightgreen.svg)](https://regression.boost.io/master/developer/static_string.html) -[`develop`](https://github.com/boostorg/static_string/tree/develop) | [![Build Status](https://github.com/boostorg/static_string/actions/workflows/ci.yml/badge.svg?branch=develop)](https://github.com/boostorg/static_string/actions?query=branch:develop) | [![Build status](https://ci.appveyor.com/api/projects/status/64es4wg4w7mc5wn2/branch/develop?svg=true)](https://ci.appveyor.com/project/sdkrystian/static-string/branch/develop) | [![Build Status](https://krystiands.visualstudio.com/static_string/_apis/build/status/Boost.StaticString?branchName=develop)](https://krystiands.visualstudio.com/static_string/_build/latest?definitionId=3&branchName=develop) | [![codecov](https://codecov.io/gh/boostorg/static_string/branch/develop/graph/badge.svg)](https://codecov.io/gh/boostorg/static_string/branch/develop) | [![Documentation](https://img.shields.io/badge/docs-develop-brightgreen.svg)](http://www.boost.org/doc/libs/develop/libs/static_string) | [![Matrix](https://img.shields.io/badge/matrix-develop-brightgreen.svg)](https://regression.boost.io/develop/developer/static_string.html) +[`master`](https://github.com/boostorg/static_string/tree/master) | [![Build Status](https://github.com/boostorg/static_string/actions/workflows/ci.yml/badge.svg?branch=master)](https://github.com/boostorg/static_string/actions?query=branch:master) | [![Build status](https://ci.appveyor.com/api/projects/status/64es4wg4w7mc5wn2/branch/master?svg=true)](https://ci.appveyor.com/project/sdkrystian/static-string/branch/master) | [![Build Status](https://krystiands.visualstudio.com/static_string/_apis/build/status/Boost.StaticString?branchName=master)](https://krystiands.visualstudio.com/static_string/_build/latest?definitionId=3&branchName=master) | [![codecov](https://codecov.io/gh/boostorg/static_string/branch/master/graph/badge.svg)](https://codecov.io/gh/boostorg/static_string/branch/master) | [![Documentation](https://img.shields.io/badge/docs-master-brightgreen.svg)](http://www.boost.org/doc/libs/release/libs/static_string) | [![Matrix](https://img.shields.io/badge/matrix-master-brightgreen.svg)](https://regression.boost.org/master/developer/static_string.html) +[`develop`](https://github.com/boostorg/static_string/tree/develop) | [![Build Status](https://github.com/boostorg/static_string/actions/workflows/ci.yml/badge.svg?branch=develop)](https://github.com/boostorg/static_string/actions?query=branch:develop) | [![Build status](https://ci.appveyor.com/api/projects/status/64es4wg4w7mc5wn2/branch/develop?svg=true)](https://ci.appveyor.com/project/sdkrystian/static-string/branch/develop) | [![Build Status](https://krystiands.visualstudio.com/static_string/_apis/build/status/Boost.StaticString?branchName=develop)](https://krystiands.visualstudio.com/static_string/_build/latest?definitionId=3&branchName=develop) | [![codecov](https://codecov.io/gh/boostorg/static_string/branch/develop/graph/badge.svg)](https://codecov.io/gh/boostorg/static_string/branch/develop) | [![Documentation](https://img.shields.io/badge/docs-develop-brightgreen.svg)](http://www.boost.org/doc/libs/develop/libs/static_string) | [![Matrix](https://img.shields.io/badge/matrix-develop-brightgreen.svg)](https://regression.boost.org/develop/developer/static_string.html) ## Introduction From 10b5491104a08fc4dfa7e6d20e8d174601c9e873 Mon Sep 17 00:00:00 2001 From: Gennaro Prota Date: Wed, 5 Nov 2025 11:30:41 +0100 Subject: [PATCH 59/73] Avoid two C4244 warnings from MSVC --- include/boost/static_string/static_string.hpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/include/boost/static_string/static_string.hpp b/include/boost/static_string/static_string.hpp index 33c0ae6..ccb28e0 100644 --- a/include/boost/static_string/static_string.hpp +++ b/include/boost/static_string/static_string.hpp @@ -775,7 +775,7 @@ to_static_wstring_float_impl(double value) noexcept // circuit evaluation will ensure that the // second operand is not evaluated on conforming // implementations. - long long num_written = + int num_written = std::swprintf(buffer, N + 1, L"%f", value); if (num_written < 0 || num_written > narrow) @@ -834,7 +834,7 @@ to_static_wstring_float_impl(long double value) noexcept // circuit evaluation will ensure that the // second operand is not evaluated on conforming // implementations. - long long num_written = + int num_written = std::swprintf(buffer, N + 1, L"%Lf", value); if (num_written < 0 || num_written > narrow) From c91593452944680bb02752890f750e1884da5b02 Mon Sep 17 00:00:00 2001 From: Gennaro Prota Date: Fri, 14 Nov 2025 12:03:00 +0100 Subject: [PATCH 60/73] Fix four occorrences of a typo ("arugment") in the Javadoc comments --- include/boost/static_string/static_string.hpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/include/boost/static_string/static_string.hpp b/include/boost/static_string/static_string.hpp index ccb28e0..762a9f4 100644 --- a/include/boost/static_string/static_string.hpp +++ b/include/boost/static_string/static_string.hpp @@ -3733,8 +3733,8 @@ class basic_static_string `{data() + pos, std::min(count, size() - pos))`. @param pos The index to being the substring at. The - default arugment for this parameter is `0`. - @param count The length of the substring. The default arugment + default argument for this parameter is `0`. + @param count The length of the substring. The default argument for this parameter is @ref npos. @throw std::out_of_range `pos > size()` @@ -3764,8 +3764,8 @@ class basic_static_string to `{data() + pos, std::min(count, size() - pos))`. @param pos The index to being the substring at. The - default arugment for this parameter is `0`. - @param count The length of the substring. The default arugment + default argument for this parameter is `0`. + @param count The length of the substring. The default argument for this parameter is @ref npos. @throw std::out_of_range `pos > size()` From 2f8c7a69eaf9e471bf58ea587e1b43c644a9a530 Mon Sep 17 00:00:00 2001 From: Gennaro Prota Date: Mon, 15 Dec 2025 14:25:26 +0100 Subject: [PATCH 61/73] Update the library metadata: Remove Krystian, add myself as a maintainer --- meta/libraries.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/meta/libraries.json b/meta/libraries.json index f7ce4af..1e4dad2 100644 --- a/meta/libraries.json +++ b/meta/libraries.json @@ -11,9 +11,9 @@ "String" ], "maintainers": [ - "Krystian Stasiowski ", "Alan de Freitas ", - "Vinnie Falco " + "Vinnie Falco ", + "Gennaro Prota " ], "cxxstd": "11" } From a526ebd1f680d347ddaa672c71034347f265eed0 Mon Sep 17 00:00:00 2001 From: Gennaro Prota Date: Mon, 15 Dec 2025 16:26:53 +0100 Subject: [PATCH 62/73] Check that basic_static_string can be constructed and assigned from a C-style string in a constexpr context This triggers a libstdc++ issue which was fixed in GCC 12.4 and 13.3: . If our CI shows we bump into that bug, we'll add a workaround. --- test/constexpr_tests.hpp | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/test/constexpr_tests.hpp b/test/constexpr_tests.hpp index 3517488..7c6ab12 100644 --- a/test/constexpr_tests.hpp +++ b/test/constexpr_tests.hpp @@ -67,6 +67,22 @@ bool testConstantEvaluation() { #ifdef BOOST_STATIC_STRING_CPP20 + + // Check construction in a constexpr context + constexpr basic_static_string s("hello"); + static_assert(s.size() == 5); + static_assert(s == "hello"); + + // Check assignment in a constexpr context + constexpr auto s2 = + []() + { + basic_static_string s("hello"); + s = "world"; + return s; + }(); + static_assert(s2 == "world"); + // c++20 constexpr tests cstatic_string a; cstatic_string b(1, 'a'); From bf988466f80cace6db8124c7a706317a6cb9f2b8 Mon Sep 17 00:00:00 2001 From: Gennaro Prota Date: Mon, 15 Dec 2025 18:23:05 +0100 Subject: [PATCH 63/73] Work around GCC (libstdc++) bug #113200 See the previous commit. This simple fix avoids calling Traits::move(), which is where the bug resides. This closes issue #55. --- include/boost/static_string/static_string.hpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/include/boost/static_string/static_string.hpp b/include/boost/static_string/static_string.hpp index 762a9f4..bde7b7a 100644 --- a/include/boost/static_string/static_string.hpp +++ b/include/boost/static_string/static_string.hpp @@ -1202,7 +1202,7 @@ class basic_static_string BOOST_STATIC_STRING_CPP14_CONSTEXPR basic_static_string(const_pointer s) { - assign(s); + assign(s, s + traits_type::length(s)); } /** Constructor. @@ -1373,7 +1373,7 @@ class basic_static_string basic_static_string& operator=(const_pointer s) { - return assign(s); + return assign(s, s + traits_type::length(s)); } /** Assign to the string. From 3a410b847215d0383d43c5fd73e525bf1328ecaa Mon Sep 17 00:00:00 2001 From: Krystian Stasiowski Date: Wed, 10 Jan 2024 04:28:25 -0500 Subject: [PATCH 64/73] Add build directory and CMake preset files to .gitignore --- .gitignore | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/.gitignore b/.gitignore index 74f33d3..9006ccd 100644 --- a/.gitignore +++ b/.gitignore @@ -1,8 +1,15 @@ bin/ bin64/ +build/ # Because of CMake and VS2017 Win32/ x64/ .vs/ -out/ \ No newline at end of file +out/ + +# VS CMake settings +/CMakeSettings.json +# CMake presets +/CMakePresets.json +/CMakeUserPresets.json From 67efdf6a9b6b43681495b4d46057d45f2192b8df Mon Sep 17 00:00:00 2001 From: Krystian Stasiowski Date: Wed, 10 Jan 2024 07:29:27 -0500 Subject: [PATCH 65/73] Make basic_static_string usable as a NTTP --- include/boost/static_string/static_string.hpp | 232 +++++++++++------- test/compile_fail.hpp | 10 - test/constexpr_tests.hpp | 99 ++++++-- 3 files changed, 216 insertions(+), 125 deletions(-) diff --git a/include/boost/static_string/static_string.hpp b/include/boost/static_string/static_string.hpp index bde7b7a..b350a98 100644 --- a/include/boost/static_string/static_string.hpp +++ b/include/boost/static_string/static_string.hpp @@ -314,103 +314,125 @@ copy_with_traits( template class static_string_base { -private: + using derived_type = basic_static_string; + friend derived_type; + using size_type = smallest_width; using value_type = typename Traits::char_type; using pointer = value_type*; using const_pointer = const value_type*; -public: - BOOST_STATIC_STRING_CPP11_CONSTEXPR - static_string_base() noexcept { }; - BOOST_STATIC_STRING_CPP14_CONSTEXPR - pointer - data_impl() noexcept + struct size { - return data_; - } + class basic_static_string + { + friend derived_type; - BOOST_STATIC_STRING_CPP14_CONSTEXPR - const_pointer - data_impl() const noexcept - { - return data_; - } + BOOST_STATIC_STRING_CPP11_CONSTEXPR + size_type + size_impl() const noexcept + { + return size; + } - BOOST_STATIC_STRING_CPP11_CONSTEXPR - std::size_t - size_impl() const noexcept - { - return size_; - } + BOOST_STATIC_STRING_CPP14_CONSTEXPR + size_type + size_impl(std::size_t n) noexcept + { + // Functions that set size will throw + // if the new size would exceed max_size() + // therefore we can guarantee that this will + // not lose data. + return size = static_cast(n); + } - BOOST_STATIC_STRING_CPP14_CONSTEXPR - std::size_t - set_size(std::size_t n) noexcept - { - // Functions that set size will throw - // if the new size would exceed max_size() - // therefore we can guarantee that this will - // not lose data. - return size_ = size_type(n); - } + public: + size_type size = 0; + }; + }; - BOOST_STATIC_STRING_CPP14_CONSTEXPR - void - term_impl() noexcept + struct data { - Traits::assign(data_[size_], value_type()); - } + class basic_static_string + { + friend derived_type; - size_type size_ = 0; + BOOST_STATIC_STRING_CPP14_CONSTEXPR + pointer + data_impl() noexcept + { + return data; + } - value_type data_[N + 1]{}; + BOOST_STATIC_STRING_CPP11_CONSTEXPR + const_pointer + data_impl() const noexcept + { + return data; + } + + public: + value_type data[N + 1]{}; + }; + }; }; // Optimization for when the size is 0 template class static_string_base<0, CharT, Traits> { -private: + using derived_type = basic_static_string<0, CharT, Traits>; + friend derived_type; + + using size_type = std::size_t; using value_type = typename Traits::char_type; using pointer = value_type*; -public: - BOOST_STATIC_STRING_CPP11_CONSTEXPR - static_string_base() noexcept { } - // Modifying the null terminator is UB - BOOST_STATIC_STRING_CPP11_CONSTEXPR - pointer - data_impl() const noexcept + struct size { - return const_cast(&null_); - } + class basic_static_string + { + friend derived_type; - BOOST_STATIC_STRING_CPP11_CONSTEXPR - std::size_t - size_impl() const noexcept - { - return 0; - } + BOOST_STATIC_STRING_CPP11_CONSTEXPR + size_type + size_impl() const noexcept + { + return 0; + } - BOOST_STATIC_STRING_CPP11_CONSTEXPR - std::size_t - set_size(std::size_t) const noexcept + BOOST_STATIC_STRING_CPP11_CONSTEXPR + size_type + size_impl(std::size_t) const noexcept + { + return 0; + } + }; + }; + + struct data { - return 0; - } + class basic_static_string + { + friend derived_type; - BOOST_STATIC_STRING_CPP14_CONSTEXPR - void - term_impl() const noexcept { } + BOOST_STATIC_STRING_CPP11_CONSTEXPR + pointer + data_impl() const noexcept + { + return const_cast(&data); + } -private: - static constexpr const value_type null_{}; + public: + static constexpr value_type data{}; + }; + }; }; // This is only needed in C++14 and lower. // see http://eel.is/c++draft/depr.static.constexpr #ifndef BOOST_STATIC_STRING_CPP17 +#if 0 template constexpr const @@ -419,6 +441,13 @@ static_string_base<0, CharT, Traits>:: null_; #endif +template +constexpr +typename static_string_base<0, CharT, Traits>::value_type +static_string_base<0, CharT, Traits>::data::basic_static_string::data; +#endif + + template BOOST_STATIC_STRING_CPP14_CONSTEXPR inline @@ -1054,7 +1083,11 @@ template> class basic_static_string #ifndef BOOST_STATIC_STRING_DOCS - : private detail::static_string_base + // : public detail::static_string_base + : public detail::static_string_base< + N, CharT, Traits>::size::basic_static_string + , public detail::static_string_base< + N, CharT, Traits>::data::basic_static_string #endif { private: @@ -2339,7 +2372,7 @@ class basic_static_string void clear() noexcept { - this->set_size(0); + this->size_impl(0); term(); } @@ -2931,7 +2964,7 @@ class basic_static_string pop_back() noexcept { BOOST_STATIC_STRING_ASSERT(!empty()); - this->set_size(size() - 1); + this->size_impl(size() - 1); term(); } @@ -3107,7 +3140,7 @@ class basic_static_string InputIterator first, InputIterator last) { - this->set_size(size() + read_back(true, first, last)); + this->size_impl(size() + read_back(true, first, last)); return term(); } @@ -5584,11 +5617,22 @@ class basic_static_string } private: + BOOST_STATIC_STRING_CPP14_CONSTEXPR + void term_impl(std::true_type) noexcept + { + traits_type::assign(data()[size()], value_type()); + } + + BOOST_STATIC_STRING_CPP14_CONSTEXPR + void term_impl(std::false_type) noexcept + { + } + BOOST_STATIC_STRING_CPP14_CONSTEXPR basic_static_string& term() noexcept { - this->term_impl(); + term_impl(std::integral_constant()); return *this; } @@ -5596,7 +5640,7 @@ class basic_static_string basic_static_string& assign_char(value_type ch, std::true_type) noexcept { - this->set_size(1); + this->size_impl(1); traits_type::assign(data()[0], ch); return term(); } @@ -5670,7 +5714,7 @@ class basic_static_string const_pointer s, size_type count) noexcept { - this->set_size(count); + this->size_impl(count); traits_type::copy(data(), s, size() + 1); return *this; } @@ -6591,7 +6635,7 @@ assign( if (count > max_size()) detail::throw_exception( "count > max_size()"); - this->set_size(count); + this->size_impl(count); traits_type::assign(data(), size(), ch); return term(); } @@ -6608,7 +6652,7 @@ assign( if (count > max_size()) detail::throw_exception( "count > max_size()"); - this->set_size(count); + this->size_impl(count); traits_type::move(data(), s, size()); return term(); } @@ -6630,13 +6674,13 @@ assign( { if (i >= max_size()) { - this->set_size(i); + this->size_impl(i); term(); detail::throw_exception("n > max_size()"); } traits_type::assign(*ptr, *first); } - this->set_size(ptr - data()); + this->size_impl(ptr - data()); return term(); } @@ -6658,7 +6702,7 @@ insert( const auto index = pos - curr_data; traits_type::move(&curr_data[index + count], &curr_data[index], curr_size - index + 1); traits_type::assign(&curr_data[index], count, ch); - this->set_size(curr_size + count); + this->size_impl(curr_size + count); return &curr_data[index]; } @@ -6711,7 +6755,7 @@ insert( traits_type::copy(dest, src, count); } } - this->set_size(curr_size + count); + this->size_impl(curr_size + count); return curr_data + index; } @@ -6735,7 +6779,7 @@ insert( const auto count = read_back(false, first, last); const std::size_t index = pos - curr_data; std::rotate(&curr_data[index], &curr_data[curr_size + 1], &curr_data[curr_size + count + 1]); - this->set_size(curr_size + count); + this->size_impl(curr_size + count); return curr_data + index; } @@ -6751,7 +6795,7 @@ erase( const auto curr_data = data(); const std::size_t index = first - curr_data; traits_type::move(&curr_data[index], last, (end() - last) + 1); - this->set_size(size() - std::size_t(last - first)); + this->size_impl(size() - std::size_t(last - first)); return curr_data + index; } @@ -6767,7 +6811,7 @@ push_back( detail::throw_exception( "curr_size >= max_size()"); traits_type::assign(data()[curr_size], ch); - this->set_size(curr_size + 1); + this->size_impl(curr_size + 1); term(); } @@ -6785,7 +6829,7 @@ append( detail::throw_exception( "count > max_size() - size()"); traits_type::assign(end(), count, ch); - this->set_size(curr_size + count); + this->size_impl(curr_size + count); return term(); } @@ -6803,7 +6847,7 @@ append( detail::throw_exception( "count > max_size() - size()"); traits_type::copy(end(), s, count); - this->set_size(curr_size + count); + this->size_impl(curr_size + count); return term(); } @@ -6819,7 +6863,7 @@ resize(size_type n, value_type c) const auto curr_size = size(); if(n > curr_size) traits_type::assign(data() + curr_size, n - curr_size, c); - this->set_size(n); + this->size_impl(n); term(); } @@ -6839,7 +6883,7 @@ resize_and_overwrite( CharT* p = data(); const auto new_size = std::move(op)(p, n); BOOST_STATIC_STRING_ASSERT(new_size >= 0 && size_type(new_size) <= n); - this->set_size(size_type(new_size)); + this->size_impl(size_type(new_size)); term(); } @@ -6851,9 +6895,9 @@ swap(basic_static_string& s) noexcept { const auto curr_size = size(); basic_static_string tmp(s); - s.set_size(curr_size); + s.size_impl(curr_size); traits_type::copy(&s.data()[0], data(), curr_size + 1); - this->set_size(tmp.size()); + this->size_impl(tmp.size()); traits_type::copy(data(), tmp.data(), size() + 1); } @@ -6872,10 +6916,8 @@ swap(basic_static_string& s) detail::throw_exception( "s.size() > max_size()"); basic_static_string tmp(s); - s.set_size(curr_size); - traits_type::copy(&s.data()[0], data(), curr_size + 1); - this->set_size(tmp.size()); - traits_type::copy(data(), &tmp.data()[0], size() + 1); + s.assign_unchecked(data(), curr_size); + assign_unchecked(tmp.data(), tmp.size()); } template @@ -6898,7 +6940,7 @@ replace( const auto pos = i1 - curr_data; traits_type::move(&curr_data[pos + n], i2, (end() - i2) + 1); traits_type::assign(&curr_data[pos], n, c); - this->set_size((curr_size - n1) + n); + this->size_impl((curr_size - n1) + n); return *this; } @@ -6959,7 +7001,7 @@ replace( traits_type::move(&curr_data[pos + n2], &curr_data[pos + n1], curr_size - pos - n1 + 1); } } - this->set_size((curr_size - n1) + n2); + this->size_impl((curr_size - n1) + n2); return *this; } @@ -6991,7 +7033,7 @@ replace( // Move everything from the end of the splice point to the end of the rotated string to // the begining of the splice point traits_type::move(&curr_data[pos + n2], &curr_data[pos + n2 + n1], ((curr_size - n1) + n2) - pos); - this->set_size((curr_size - n1) + n2); + this->size_impl((curr_size - n1) + n2); return *this; } @@ -7163,7 +7205,7 @@ replace_unchecked( "replaced string exceeds max_size()"); traits_type::move(&curr_data[pos + n2], i2, (end() - i2) + 1); traits_type::copy(&curr_data[pos], s, n2); - this->set_size((curr_size - n1) + n2); + this->size_impl((curr_size - n1) + n2); return *this; } @@ -7185,7 +7227,7 @@ insert_unchecked( const std::size_t index = pos - curr_data; traits_type::move(&curr_data[index + count], pos, (end() - pos) + 1); traits_type::copy(&curr_data[index], s, count); - this->set_size(curr_size + count); + this->size_impl(curr_size + count); return curr_data + index; } diff --git a/test/compile_fail.hpp b/test/compile_fail.hpp index d0d0dfd..03510f1 100644 --- a/test/compile_fail.hpp +++ b/test/compile_fail.hpp @@ -4,16 +4,6 @@ namespace boost { namespace static_strings { -static_assert(std::is_base_of< - detail::static_string_base<0, char, std::char_traits>, - static_string<0>>::value, - "the zero size optimization shall be used for N = 0"); - -static_assert(std::is_base_of< - detail::static_string_base<(std::numeric_limits::max)() + 1, char, std::char_traits>, - static_string<(std::numeric_limits::max)() + 1>>::value, - "the minimum size type optimization shall be used for N > 0"); - static_assert(!detail::is_input_iterator::value, "is_input_iterator is incorrect"); static_assert(!detail::is_input_iterator::value, "is_input_iterator is incorrect"); static_assert(detail::is_input_iterator::value, "is_input_iterator is incorrect"); diff --git a/test/constexpr_tests.hpp b/test/constexpr_tests.hpp index 7c6ab12..c748ec7 100644 --- a/test/constexpr_tests.hpp +++ b/test/constexpr_tests.hpp @@ -22,38 +22,74 @@ struct cxper_char_traits using int_type = int; using state_type = std::mbstate_t; - static constexpr void assign(char_type& a, const char_type& b) noexcept { a = b; } - static constexpr bool eq(char_type a, char_type b) noexcept { return a == b; } - static constexpr bool lt(char_type a, char_type b) noexcept { return a < b; } + static constexpr void assign(char_type& a, const char_type& b) noexcept + { + a = b; + } + + static constexpr bool eq(char_type a, char_type b) noexcept + { + return a == b; + } + + static constexpr bool lt(char_type a, char_type b) noexcept + { + return a < b; + } + + static constexpr int compare(const char_type* a, const char_type* b, std::size_t n) + { + for (; n--; ++a, ++b) + { + if(lt(*a, *b)) + return 1; + else if(lt(*b, *a)) + return -1; + } + return 0; + } - static constexpr int compare(const char_type*, const char_type*, std::size_t) { return 0; } static constexpr std::size_t length(const char_type* s) { - std::size_t n = 0; - while (*(s++)); - return n; + auto ptr = s; + while (!eq(*ptr, char_type())) + ++ptr; + return ptr - s; } - static constexpr const char_type* find(const char_type*, std::size_t, const char_type&){ return 0; } + + static constexpr const char_type* find(const char_type* s, std::size_t n, const char_type& ch) + { + for (; n--; ++s) + { + if (eq(*s, ch)) + return s; + } + return nullptr; + } + static constexpr char_type* move(char_type* dest, const char_type* src, std::size_t n) { - const auto temp = dest; - while (n--) - *(dest++) = *(src++); - return temp; + if (detail::ptr_in_range(src, src + n, dest)) + { + while (n--) + assign(dest[n], src[n]); + return dest; + } + return copy(dest, src, n); } + static constexpr char_type* copy(char_type* dest, const char_type* src, std::size_t n) { - const auto temp = dest; - while (n--) - *(dest++) = *(src++); - return temp; + for (auto ptr = dest; n--;) + assign(*ptr++, *src++); + return dest; } + static constexpr char_type* assign(char_type* dest, std::size_t n, char_type ch) { - const auto temp = dest; - while (n--) - *(dest++) = ch; - return temp; + for (auto ptr = dest; n--;) + assign(*ptr++, ch); + return dest; } }; #else @@ -623,5 +659,28 @@ testConstantEvaluation() cstatic_string().empty(); #endif } + +#ifdef BOOST_STATIC_STRING_CPP20 + +template X> +struct nttp_primary +{ + static constexpr bool value = false; +}; + +template<> +struct nttp_primary<"test string"> +{ + static constexpr bool value = true; +}; + +static_assert(!nttp_primary<"random string">::value, + "structural equality broken"); + +static_assert(nttp_primary<"test string">::value, + "structural equality broken"); + +#endif + } // static_strings } // boost From 4bf6461ca1a5928f8f6c8f4551396bfe2a1e6002 Mon Sep 17 00:00:00 2001 From: Gennaro Prota Date: Wed, 17 Dec 2025 12:21:18 +0100 Subject: [PATCH 66/73] Work around a bug in GCC 5-10 GCC 5-10 incorrectly complain about our nested classes being private. So, make them public. --- include/boost/static_string/config.hpp | 7 +++++++ include/boost/static_string/static_string.hpp | 4 ++++ 2 files changed, 11 insertions(+) diff --git a/include/boost/static_string/config.hpp b/include/boost/static_string/config.hpp index 5af2b13..35dcdec 100644 --- a/include/boost/static_string/config.hpp +++ b/include/boost/static_string/config.hpp @@ -279,4 +279,11 @@ using basic_string_view = #define BOOST_STATIC_STRING_USE_STD_FORMAT #endif +#if defined(__GNUC__) && (__GNUC__ >= 5) && (__GNUC__ <= 10) && !defined(__clang__) +// Workaround for GCC complaining about nested classes being private. +#define BOOST_STATIC_STRING_GCC_NESTED_CLASS_WORKAROUND public: +#else +#define BOOST_STATIC_STRING_GCC_NESTED_CLASS_WORKAROUND +#endif + #endif diff --git a/include/boost/static_string/static_string.hpp b/include/boost/static_string/static_string.hpp index b350a98..75556d3 100644 --- a/include/boost/static_string/static_string.hpp +++ b/include/boost/static_string/static_string.hpp @@ -322,6 +322,8 @@ class static_string_base using pointer = value_type*; using const_pointer = const value_type*; +BOOST_STATIC_STRING_GCC_NESTED_CLASS_WORKAROUND + struct size { class basic_static_string @@ -388,6 +390,8 @@ class static_string_base<0, CharT, Traits> using value_type = typename Traits::char_type; using pointer = value_type*; +BOOST_STATIC_STRING_GCC_NESTED_CLASS_WORKAROUND + struct size { class basic_static_string From 4dcfb3949416643b592e686f74964c8f90fda03f Mon Sep 17 00:00:00 2001 From: Gennaro Prota Date: Wed, 17 Dec 2025 12:47:20 +0100 Subject: [PATCH 67/73] Replace the implementation of cxper_char_traits::move() with a simpler one Reason: See the new code comment. --- test/constexpr_tests.hpp | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/test/constexpr_tests.hpp b/test/constexpr_tests.hpp index c748ec7..ca72ccc 100644 --- a/test/constexpr_tests.hpp +++ b/test/constexpr_tests.hpp @@ -69,12 +69,15 @@ struct cxper_char_traits static constexpr char_type* move(char_type* dest, const char_type* src, std::size_t n) { - if (detail::ptr_in_range(src, src + n, dest)) - { - while (n--) - assign(dest[n], src[n]); - return dest; - } + // This implementation does not handle overlapping ranges where + // dest > src. A correct implementation would need to detect this + // case and copy backwards, but detecting overlap requires pointer + // comparisons that many of the tested compiles (incorrectly) refuse + // in constant expressions. + // + // Since cxper_char_traits is only used for testing constexpr + // functionality and the tests do not exercise overlapping moves + // where dest > src, this simple forward copy is sufficient. return copy(dest, src, n); } From 0e28b358dca91c7de19a1980fb067b7e7ba48da9 Mon Sep 17 00:00:00 2001 From: Gennaro Prota Date: Wed, 17 Dec 2025 14:51:19 +0100 Subject: [PATCH 68/73] Work around GCC 9 rejecting a legitimate pointer comparison in a constexpr context --- include/boost/static_string/config.hpp | 7 +++++++ test/constexpr_tests.hpp | 6 ++++-- 2 files changed, 11 insertions(+), 2 deletions(-) diff --git a/include/boost/static_string/config.hpp b/include/boost/static_string/config.hpp index 35dcdec..c9570cb 100644 --- a/include/boost/static_string/config.hpp +++ b/include/boost/static_string/config.hpp @@ -286,4 +286,11 @@ using basic_string_view = #define BOOST_STATIC_STRING_GCC_NESTED_CLASS_WORKAROUND #endif +// GCC 9 incorrectly rejects the pointer equality comparison in +// ptr_in_range() in constant expressions. GCC 10 and later handle +// it correctly. +#if defined(__GNUC__) && !defined(__clang__) && (__GNUC__ == 9) +#define BOOST_STATIC_STRING_CONSTEXPR_PTR_CMP_BROKEN +#endif + #endif diff --git a/test/constexpr_tests.hpp b/test/constexpr_tests.hpp index ca72ccc..f541183 100644 --- a/test/constexpr_tests.hpp +++ b/test/constexpr_tests.hpp @@ -255,7 +255,8 @@ testConstantEvaluation() a.replace(a.begin(), a.end(), a.begin(), a.end()); a.replace(a.begin(), a.end(), {'a'}); -#ifdef BOOST_STATIC_STRING_IS_CONST_EVAL +#if defined(BOOST_STATIC_STRING_IS_CONST_EVAL) \ + && !defined(BOOST_STATIC_STRING_CONSTEXPR_PTR_CMP_BROKEN) a.clear(); a.replace(a.begin(), a.end(), "a"); a.replace(a.begin(), a.end(), "a", 1); @@ -443,7 +444,8 @@ testConstantEvaluation() a.replace(a.begin(), a.end(), a.begin(), a.end()); a.replace(a.begin(), a.end(), {'a'}); -#ifdef BOOST_STATIC_STRING_IS_CONST_EVAL +#if defined(BOOST_STATIC_STRING_IS_CONST_EVAL) \ + && !defined(BOOST_STATIC_STRING_CONSTEXPR_PTR_CMP_BROKEN) a.clear(); a.replace(a.begin(), a.end(), "a"); a.replace(a.begin(), a.end(), "a", 1); From aee3c62957ecdae385728c5cd49c7db967c5b82f Mon Sep 17 00:00:00 2001 From: Gennaro Prota Date: Wed, 17 Dec 2025 16:05:21 +0100 Subject: [PATCH 69/73] Apply the workaround in the previous commit to Clang 3.7 and 9-19, too Reason: They have the same issue as GCC 9. --- include/boost/static_string/config.hpp | 5 ++++- test/constexpr_tests.hpp | 3 ++- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/include/boost/static_string/config.hpp b/include/boost/static_string/config.hpp index c9570cb..e7c155a 100644 --- a/include/boost/static_string/config.hpp +++ b/include/boost/static_string/config.hpp @@ -289,7 +289,10 @@ using basic_string_view = // GCC 9 incorrectly rejects the pointer equality comparison in // ptr_in_range() in constant expressions. GCC 10 and later handle // it correctly. -#if defined(__GNUC__) && !defined(__clang__) && (__GNUC__ == 9) +// +// Clang 3.7 and 9-19 have the same issue. +#if (defined(__GNUC__) && !defined(__clang__) && (__GNUC__ == 9)) \ + || (defined(__clang__) && ((__clang_major__ == 3 && __clang_minor__ == 7) || ((__clang_major__ >= 9) && (__clang_major__ <= 19)))) #define BOOST_STATIC_STRING_CONSTEXPR_PTR_CMP_BROKEN #endif diff --git a/test/constexpr_tests.hpp b/test/constexpr_tests.hpp index f541183..536a463 100644 --- a/test/constexpr_tests.hpp +++ b/test/constexpr_tests.hpp @@ -617,7 +617,8 @@ testConstantEvaluation() a.replace(a.begin(), a.end(), a.begin(), a.end()); a.replace(a.begin(), a.end(), {'a'}); -#ifdef BOOST_STATIC_STRING_IS_CONST_EVAL +#if defined(BOOST_STATIC_STRING_IS_CONST_EVAL) \ + && !defined(BOOST_STATIC_STRING_CONSTEXPR_PTR_CMP_BROKEN) a.clear(); a.replace(a.begin(), a.end(), "a"); a.replace(a.begin(), a.end(), "a", 1); From 2175496c5535b7f3d21389c63c97c5f03b1e3361 Mon Sep 17 00:00:00 2001 From: Gennaro Prota Date: Wed, 17 Dec 2025 19:30:59 +0100 Subject: [PATCH 70/73] Condition the NTTP tests on __cpp_nontype_template_args They were conditioned on detection of C++20 via __cplusplus, but Clang 10 and 11 don't support class types as NTTP, even though they report C++20 via __cplusplus when -std=c++20 is used. --- test/constexpr_tests.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/constexpr_tests.hpp b/test/constexpr_tests.hpp index 536a463..71ca3af 100644 --- a/test/constexpr_tests.hpp +++ b/test/constexpr_tests.hpp @@ -666,7 +666,7 @@ testConstantEvaluation() #endif } -#ifdef BOOST_STATIC_STRING_CPP20 +#if __cpp_nontype_template_args >= 201911L template X> struct nttp_primary From 6f0c00b2687f252b4a1e9f5712013de97688516a Mon Sep 17 00:00:00 2001 From: Gennaro Prota Date: Thu, 18 Dec 2025 10:35:43 +0100 Subject: [PATCH 71/73] Work around a Clang 3.7 bug affecting constexpr insert() The iterator-based insert(const_iterator, size_type, value_type) function relies on traits_type::move() to shift the existing null terminator to its new position. Clang 3.7's constexpr evaluator does not handle this correctly, causing the following test to fail: static_string<3>{"ab"}.insert(2, 1, 'c') == "abc" Add an explicit term() call, guarded by a preprocessor conditional for Clang 3.7, to ensure proper null termination. --- include/boost/static_string/static_string.hpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/include/boost/static_string/static_string.hpp b/include/boost/static_string/static_string.hpp index 75556d3..6b4d3d0 100644 --- a/include/boost/static_string/static_string.hpp +++ b/include/boost/static_string/static_string.hpp @@ -6707,6 +6707,9 @@ insert( traits_type::move(&curr_data[index + count], &curr_data[index], curr_size - index + 1); traits_type::assign(&curr_data[index], count, ch); this->size_impl(curr_size + count); +#if defined(__clang__) && __clang_major__ == 3 && __clang_minor__ == 7 + term(); +#endif return &curr_data[index]; } From 0c5e5b8e584be1806a046385d447a13755bf6cb1 Mon Sep 17 00:00:00 2001 From: Gennaro Prota Date: Thu, 18 Dec 2025 16:44:07 +0100 Subject: [PATCH 72/73] Fix our deduction guide --- include/boost/static_string/static_string.hpp | 2 +- test/constexpr_tests.hpp | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/include/boost/static_string/static_string.hpp b/include/boost/static_string/static_string.hpp index 6b4d3d0..f82425a 100644 --- a/include/boost/static_string/static_string.hpp +++ b/include/boost/static_string/static_string.hpp @@ -6529,7 +6529,7 @@ to_static_wstring(long double value) noexcept #ifdef BOOST_STATIC_STRING_USE_DEDUCT template basic_static_string(const CharT(&)[N]) -> - basic_static_string>; + basic_static_string>; #endif //------------------------------------------------------------------------------ diff --git a/test/constexpr_tests.hpp b/test/constexpr_tests.hpp index 71ca3af..018741e 100644 --- a/test/constexpr_tests.hpp +++ b/test/constexpr_tests.hpp @@ -110,6 +110,7 @@ testConstantEvaluation() // Check construction in a constexpr context constexpr basic_static_string s("hello"); static_assert(s.size() == 5); + static_assert(s.static_capacity == 5); static_assert(s == "hello"); // Check assignment in a constexpr context From e9313dc331e2e863f41c21d06c56557801305d54 Mon Sep 17 00:00:00 2001 From: Gennaro Prota Date: Fri, 19 Dec 2025 12:32:50 +0100 Subject: [PATCH 73/73] Add an experimental basic_static_cstring template in example/ This introduces an alternative to basic_static_string designed for use in POD types: Trivially copyable, having a sizeof == N + 1, with no embedded NULs. Placed in example/ to gather user feedback before committing to a public API. See issue #23. --- .github/workflows/example.yml | 156 ++++ example/static_cstring/Jamfile | 19 + example/static_cstring/README.md | 13 + example/static_cstring/static_cstring.hpp | 441 ++++++++++++ .../static_cstring/static_cstring_test.cpp | 671 ++++++++++++++++++ 5 files changed, 1300 insertions(+) create mode 100644 .github/workflows/example.yml create mode 100644 example/static_cstring/Jamfile create mode 100644 example/static_cstring/README.md create mode 100644 example/static_cstring/static_cstring.hpp create mode 100644 example/static_cstring/static_cstring_test.cpp diff --git a/.github/workflows/example.yml b/.github/workflows/example.yml new file mode 100644 index 0000000..75c5c68 --- /dev/null +++ b/.github/workflows/example.yml @@ -0,0 +1,156 @@ +# +# Copyright (c) 2025 Gennaro Prota (gennaro dot prota at gmail dot com) +# +# Distributed under the Boost Software License, Version 1.0. (See accompanying +# file LICENSE_1_0.txt or copy at https://www.boost.org/LICENSE_1_0.txt) +# +# Official repository: https://github.com/boostorg/static_string +# + +name: Example (basic_static_cstring) + +on: + pull_request: + push: + branches: + - master + - develop + - bugfix/** + - feature/** + - fix/** + - github/** + - pr/** + paths-ignore: + - LICENSE + - meta/** + - README.md + +jobs: + linux: + runs-on: ubuntu-24.04 + strategy: + fail-fast: false + matrix: + include: + - { toolset: gcc-13, cxxstd: '20,23' } + - { toolset: gcc-14, cxxstd: '20,23,26' } + - { toolset: clang-17, cxxstd: '20,23' } + - { toolset: clang-18, cxxstd: '20,23,26' } + + steps: + - name: Checkout Boost super-project + uses: actions/checkout@v4 + with: + repository: boostorg/boost + ref: develop + fetch-depth: 0 + + - name: Checkout this library + uses: actions/checkout@v4 + with: + path: libs/static_string + fetch-depth: 0 + + - name: Initialize Boost submodules + run: | + git submodule update --init tools/boostdep + python tools/boostdep/depinst/depinst.py --git_args '--jobs 4' static_string + + - name: Bootstrap b2 + run: ./bootstrap.sh + + - name: Generate Boost headers + run: ./b2 headers + + - name: Build and run example tests + run: | + ./b2 libs/static_string/example/static_cstring \ + toolset=${{ matrix.toolset }} \ + cxxstd=${{ matrix.cxxstd }} \ + variant=debug,release \ + -j$(nproc) + + macos: + runs-on: macos-14 + strategy: + fail-fast: false + matrix: + include: + - { toolset: clang, cxxstd: '20,23' } + + steps: + - name: Checkout Boost super-project + uses: actions/checkout@v4 + with: + repository: boostorg/boost + ref: develop + fetch-depth: 0 + + - name: Checkout this library + uses: actions/checkout@v4 + with: + path: libs/static_string + fetch-depth: 0 + + - name: Initialize Boost submodules + run: | + git submodule update --init tools/boostdep + python3 tools/boostdep/depinst/depinst.py --git_args '--jobs 4' static_string + + - name: Bootstrap b2 + run: ./bootstrap.sh + + - name: Generate Boost headers + run: ./b2 headers + + - name: Build and run example tests + run: | + ./b2 libs/static_string/example/static_cstring \ + toolset=${{ matrix.toolset }} \ + cxxstd=${{ matrix.cxxstd }} \ + variant=debug,release \ + -j$(sysctl -n hw.ncpu) + + windows: + runs-on: windows-2022 + strategy: + fail-fast: false + matrix: + include: + - { toolset: msvc-14.3, cxxstd: '20,latest' } + + steps: + - name: Checkout Boost super-project + uses: actions/checkout@v4 + with: + repository: boostorg/boost + ref: develop + fetch-depth: 0 + + - name: Checkout this library + uses: actions/checkout@v4 + with: + path: libs/static_string + fetch-depth: 0 + + - name: Initialize Boost submodules + run: | + git submodule update --init tools/boostdep + python tools/boostdep/depinst/depinst.py --git_args '--jobs 4' static_string + + - name: Bootstrap b2 + run: .\bootstrap.bat + shell: cmd + + - name: Generate Boost headers + run: .\b2 headers + shell: cmd + + - name: Build and run example tests + run: | + .\b2 libs/static_string/example/static_cstring ^ + toolset=${{ matrix.toolset }} ^ + cxxstd=${{ matrix.cxxstd }} ^ + variant=debug,release ^ + address-model=64 + shell: cmd diff --git a/example/static_cstring/Jamfile b/example/static_cstring/Jamfile new file mode 100644 index 0000000..c858d59 --- /dev/null +++ b/example/static_cstring/Jamfile @@ -0,0 +1,19 @@ +# +# Copyright (c) 2025 Gennaro Prota (gennaro dot prota at gmail dot com) +# +# Distributed under the Boost Software License, Version 1.0. (See accompanying +# file LICENSE_1_0.txt or copy at https://www.boost.org/LICENSE_1_0.txt) +# +# Official repository: https://github.com/boostorg/static_string +# + +import testing ; + +project + : requirements + ../../include + extra + 20 + ; + +run static_cstring_test.cpp ; diff --git a/example/static_cstring/README.md b/example/static_cstring/README.md new file mode 100644 index 0000000..ebf965e --- /dev/null +++ b/example/static_cstring/README.md @@ -0,0 +1,13 @@ +This directory contains an experimental implementation of `basic_static_cstring`, which differs from `basic_static_string` in the following ways: + +| | `basic_static_cstring` | `basic_static_string` | +|---------------------|------------------------|-----------------------| +| Layout | `sizeof == N + 1` | Has size member | +| Embedded NULs | Not supported | Supported | +| Trivially copyable | Yes | No | + +Additionally, when `N <= UCHAR_MAX`, `basic_static_cstring` employs an optimization that avoids calling `std::strlen()` to compute the size. + +This work stems from [boostorg/static_string#23](https://github.com/boostorg/static_string/issues/23). + +If you believe `basic_static_cstring` should become part of the public API, please share your feedback on the Boost mailing list. \ No newline at end of file diff --git a/example/static_cstring/static_cstring.hpp b/example/static_cstring/static_cstring.hpp new file mode 100644 index 0000000..1552fd8 --- /dev/null +++ b/example/static_cstring/static_cstring.hpp @@ -0,0 +1,441 @@ +// +// Copyright (c) 2025 Gennaro Prota (gennaro dot prota at gmail dot com) +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at https://www.boost.org/LICENSE_1_0.txt) +// +// Official repository: https://github.com/boostorg/static_string +// + +#ifndef BOOST_STATIC_STRING_STATIC_CSTRING_HPP +#define BOOST_STATIC_STRING_STATIC_CSTRING_HPP + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +namespace boost { +namespace static_strings { + +namespace detail { + +// Primary template: No remaining-capacity trick; uses traits::length() for length. +template +class static_cstring_base +{ +public: + using traits_type = Traits; + using value_type = CharT; + using size_type = std::size_t; + + value_type data_[N + 1]{}; + + constexpr size_type get_size() const noexcept + { + return traits_type::length(data_); + } + + constexpr void set_size(size_type sz) noexcept + { + data_[sz] = value_type{}; + } + + // Defaulted comparisons for structural type support. + constexpr bool operator==(const static_cstring_base&) const noexcept = default; + constexpr auto operator<=>(const static_cstring_base&) const noexcept = default; +}; + +// Specialization for N <= UCHAR_MAX: Uses remaining-capacity trick. +template +class static_cstring_base +{ +public: + using traits_type = Traits; + using value_type = CharT; + using size_type = std::size_t; + + value_type data_[N + 1]{}; + + constexpr size_type get_size() const noexcept + { + return N - static_cast(data_[N]); + } + + constexpr void set_size(size_type sz) noexcept + { + data_[sz] = value_type{}; + data_[N] = static_cast(N - sz); + } + + // Defaulted comparisons for structural type support. + constexpr bool operator==(const static_cstring_base&) const noexcept = default; + constexpr auto operator<=>(const static_cstring_base&) const noexcept = default; +}; + +} // namespace detail + +template> +class basic_static_cstring + : public detail::static_cstring_base +{ +public: + using base = detail::static_cstring_base; + using base::data_; + using base::get_size; + using base::set_size; + + // Member types + using traits_type = Traits; + using value_type = CharT; + using size_type = std::size_t; + using difference_type = std::ptrdiff_t; + using reference = value_type&; + using const_reference = const value_type&; + using pointer = value_type*; + using const_pointer = const value_type*; + using iterator = pointer; + using const_iterator = const_pointer; + + static constexpr size_type npos = static_cast(-1); + static constexpr size_type static_capacity = N; + + // Constructors. + constexpr basic_static_cstring() noexcept + { + set_size(0); + } + + constexpr basic_static_cstring(const CharT* s) + { + assign(s); + } + + constexpr basic_static_cstring(const CharT* s, size_type count) + { + assign(s, count); + } + + constexpr basic_static_cstring(size_type count, CharT ch) + { + assign(count, ch); + } + + template + constexpr basic_static_cstring(const CharT (&arr)[M]) + { + static_assert(M <= N + 1, "String literal too long for static_cstring"); + assign(arr, M - 1); + } + + constexpr size_type size() const noexcept + { + return get_size(); + } + + constexpr size_type length() const noexcept + { + return size(); + } + + constexpr bool empty() const noexcept + { + return data_[0] == value_type{}; + } + + static constexpr size_type max_size() noexcept + { + return N; + } + + static constexpr size_type capacity() noexcept + { + return N; + } + + // Element access. + constexpr reference operator[](size_type pos) noexcept + { + return data_[pos]; + } + + constexpr const_reference operator[](size_type pos) const noexcept + { + return data_[pos]; + } + + constexpr reference at(size_type pos) + { + if (pos >= size()) + { + throw std::out_of_range("static_cstring::at"); + } + return data_[pos]; + } + + constexpr const_reference at(size_type pos) const + { + if (pos >= size()) + { + throw std::out_of_range("static_cstring::at"); + } + return data_[pos]; + } + + constexpr reference front() noexcept + { + BOOST_STATIC_STRING_ASSERT(!empty()); + return data_[0]; + } + + constexpr const_reference front() const noexcept + { + BOOST_STATIC_STRING_ASSERT(!empty()); + return data_[0]; + } + + constexpr reference back() noexcept + { + BOOST_STATIC_STRING_ASSERT(!empty()); + return data_[size() - 1]; + } + + constexpr const_reference back() const noexcept + { + BOOST_STATIC_STRING_ASSERT(!empty()); + return data_[size() - 1]; + } + + constexpr pointer data() noexcept + { + return data_; + } + + constexpr const_pointer data() const noexcept + { + return data_; + } + + constexpr const_pointer c_str() const noexcept + { + return data_; + } + + // Iterators. + constexpr iterator begin() noexcept + { + return data_; + } + + constexpr const_iterator begin() const noexcept + { + return data_; + } + + constexpr const_iterator cbegin() const noexcept + { + return data_; + } + + constexpr iterator end() noexcept + { + return data_ + size(); + } + + constexpr const_iterator end() const noexcept + { + return data_ + size(); + } + + constexpr const_iterator cend() const noexcept + { + return data_ + size(); + } + + // Modifiers. + constexpr void clear() noexcept + { + set_size(0); + } + + constexpr basic_static_cstring& assign(const CharT* s) + { + return assign(s, traits_type::length(s)); + } + + constexpr basic_static_cstring& assign(const CharT* s, size_type count) + { + if (count > N) + { + throw std::length_error("static_cstring::assign"); + } + traits_type::copy(data_, s, count); + set_size(count); + return *this; + } + + constexpr basic_static_cstring& assign(size_type count, CharT ch) + { + if (count > N) + { + throw std::length_error("static_cstring::assign"); + } + traits_type::assign(data_, count, ch); + set_size(count); + return *this; + } + + constexpr basic_static_cstring& operator=(const CharT* s) + { + return assign(s); + } + + constexpr void push_back(CharT ch) + { + const size_type sz = size(); + if (sz >= N) + { + throw std::length_error("static_cstring::push_back"); + } + data_[sz] = ch; + set_size(sz + 1); + } + + constexpr void pop_back() noexcept + { + BOOST_STATIC_STRING_ASSERT(!empty()); + set_size(size() - 1); + } + + constexpr basic_static_cstring& append(const CharT* s) + { + return append(s, traits_type::length(s)); + } + + constexpr basic_static_cstring& append(const CharT* s, size_type count) + { + const size_type sz = size(); + if (sz + count > N) + { + throw std::length_error("static_cstring::append"); + } + traits_type::copy(data_ + sz, s, count); + set_size(sz + count); + return *this; + } + + constexpr basic_static_cstring& append(size_type count, CharT ch) + { + const size_type sz = size(); + if (sz + count > N) + { + throw std::length_error("static_cstring::append"); + } + traits_type::assign(data_ + sz, count, ch); + set_size(sz + count); + return *this; + } + + constexpr basic_static_cstring& operator+=(const CharT* s) + { + return append(s); + } + + constexpr basic_static_cstring& operator+=(CharT ch) + { + push_back(ch); + return *this; + } + + // Comparisons. + constexpr int compare(const basic_static_cstring& other) const noexcept + { + const size_type lhs_sz = size(); + const size_type rhs_sz = other.size(); + const int result = traits_type::compare(data_, other.data_, (std::min)(lhs_sz, rhs_sz)); + + return result != 0 + ? result + : lhs_sz < rhs_sz + ? -1 + : lhs_sz > rhs_sz + ? 1 + : 0; + } + + constexpr int compare(const CharT* s) const noexcept + { + return compare(basic_static_cstring(s)); + } + + // Conversions. + constexpr operator std::basic_string_view() const noexcept + { + return {data_, size()}; + } + + std::basic_string str() const + { + return {data_, size()}; + } + + // Swap. + constexpr void swap(basic_static_cstring& other) noexcept + { + basic_static_cstring tmp = *this; + *this = other; + other = tmp; + } + + // Defaulted comparisons for structural type (C++20). + constexpr bool operator==(const basic_static_cstring&) const noexcept = default; + constexpr auto operator<=>(const basic_static_cstring&) const noexcept = default; +}; + +#if defined(BOOST_STATIC_STRING_USE_DEDUCT) + +// Deduction guide. +template +basic_static_cstring(const CharT(&)[N]) -> basic_static_cstring; + +#endif + +// Comparison with const CharT*. +template +constexpr bool operator==(const basic_static_cstring& lhs, + const CharT* rhs) noexcept +{ + return lhs.compare(rhs) == 0; +} + +template +constexpr bool operator==(const CharT* lhs, + const basic_static_cstring& rhs) noexcept +{ + return rhs.compare(lhs) == 0; +} + +// Stream output. +template +std::basic_ostream& operator<<(std::basic_ostream& os, + const basic_static_cstring& str) +{ + return os << str.c_str(); +} + +// Alias templates. +template +using static_cstring = basic_static_cstring; + +template +using static_wcstring = basic_static_cstring; + +} +} + +#endif diff --git a/example/static_cstring/static_cstring_test.cpp b/example/static_cstring/static_cstring_test.cpp new file mode 100644 index 0000000..40dd4ce --- /dev/null +++ b/example/static_cstring/static_cstring_test.cpp @@ -0,0 +1,671 @@ +// +// Copyright (c) 2025 Gennaro Prota (gennaro dot prota at gmail dot com) +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at https://www.boost.org/LICENSE_1_0.txt) +// +// Official repository: https://github.com/boostorg/static_string +// + +#include "static_cstring.hpp" + +#include +#include +#include +#include +#include +#include +#include + +namespace boost { +namespace static_strings { + +static +void +testCStringSizeGuarantee() +{ + // Core guarantee: sizeof is exactly N + 1 (no size member). + static_assert(sizeof(static_cstring<0>) == 1, ""); + static_assert(sizeof(static_cstring<1>) == 2, ""); + static_assert(sizeof(static_cstring<10>) == 11, ""); + static_assert(sizeof(static_cstring<63>) == 64, ""); + static_assert(sizeof(static_cstring<64>) == 65, ""); + static_assert(sizeof(static_cstring<127>) == 128, ""); + static_assert(sizeof(static_cstring) == (UCHAR_MAX + 1), ""); + static_assert(sizeof(static_cstring) == (UCHAR_MAX + 2), ""); + static_assert(sizeof(static_cstring<1000>) == 1001, ""); +} + +static +void +testCStringRemainingCapacityTrick() +{ + // Test the remaining-capacity optimization for N <= UCHAR_MAX. + + // Full capacity: Last byte is both null terminator AND remaining == 0. + { + static_cstring<5> full("12345"); + BOOST_TEST(full.size() == 5); + BOOST_TEST(full.capacity() == 5); + BOOST_TEST(full.data()[5] == '\0'); + BOOST_TEST(std::strcmp(full.c_str(), "12345") == 0); + } + + // Partial fill: Null terminator at position size, remaining at position N. + { + static_cstring<10> partial("Hi"); + BOOST_TEST(partial.size() == 2); + BOOST_TEST(partial.capacity() == 10); + BOOST_TEST(partial.data()[2] == '\0'); + BOOST_TEST(static_cast(partial.data()[10]) == 8); + } + + // Empty string. + { + static_cstring<10> empty; + BOOST_TEST(empty.size() == 0); + BOOST_TEST(empty.capacity() == 10); + BOOST_TEST(empty.data()[0] == '\0'); + BOOST_TEST(static_cast(empty.data()[10]) == 10); + } + + // Edge case: N == UCHAR_MAX (max for our trick). + { + static_cstring large; + large.assign(100, 'x'); + BOOST_TEST(large.size() == 100); + BOOST_TEST(large.capacity() == UCHAR_MAX); + BOOST_TEST(static_cast(large.data()[UCHAR_MAX]) == (UCHAR_MAX - large.size())); + } +} + +template +struct CStringTypeTraits +{ + static_assert(std::is_trivially_copyable::value); + static_assert(std::is_trivially_copy_constructible::value); + static_assert(std::is_trivially_move_constructible::value); + static_assert(std::is_trivially_copy_assignable::value); + static_assert(std::is_trivially_move_assignable::value); + static_assert(std::is_trivially_destructible::value); +}; + +static +void +testCStringTypeTraits() +{ + { + using S = static_cstring<0>; + CStringTypeTraits< S > check; + static_cast(check); + } + { + using S = static_cstring<63>; + CStringTypeTraits< S > check; + static_cast(check); + } + { + using S = static_cstring<300>; + CStringTypeTraits< S > check; + static_cast(check); + } +} + +static +void +testCStringConstruct() +{ + // Default construction. + { + static_cstring<1> s; + BOOST_TEST(s.empty()); + BOOST_TEST(s.size() == 0); + BOOST_TEST(s == ""); + BOOST_TEST(*s.end() == 0); + } + + // Construct with count and char. + { + static_cstring<4> s1(3, 'x'); + BOOST_TEST(!s1.empty()); + BOOST_TEST(s1.size() == 3); + BOOST_TEST(s1 == "xxx"); + BOOST_TEST(*s1.end() == 0); + BOOST_TEST_THROWS( + (static_cstring<2>(3, 'x')), + std::length_error); + } + + // Construct from a C string. + { + static_cstring<5> s1("12345"); + BOOST_TEST(s1.size() == 5); + BOOST_TEST(s1 == "12345"); + BOOST_TEST(*s1.end() == 0); + BOOST_TEST_THROWS( + (static_cstring<4>("12345")), + std::length_error); + } + + // Construct from a C string with count. + { + static_cstring<5> s1("UVXYZ", 3); + BOOST_TEST(s1 == "UVX"); + BOOST_TEST(*s1.end() == 0); + } + + // Copy construction. + { + static_cstring<5> s1("12345"); + static_cstring<5> s2(s1); + BOOST_TEST(s2 == "12345"); + BOOST_TEST(*s2.end() == 0); + } +} + +static +void +testCStringAssignment() +{ + // assign(size_type count, CharT ch). + BOOST_TEST(static_cstring<3>{}.assign(1, '*') == "*"); + BOOST_TEST(static_cstring<3>{}.assign(3, '*') == "***"); + BOOST_TEST(static_cstring<3>{"abc"}.assign(3, '*') == "***"); + BOOST_TEST_THROWS(static_cstring<1>{"a"}.assign(2, '*'), std::length_error); + + // assign(CharT const* s, size_type count). + BOOST_TEST(static_cstring<3>{}.assign("abc", 3) == "abc"); + BOOST_TEST(static_cstring<3>{"*"}.assign("abc", 3) == "abc"); + BOOST_TEST_THROWS(static_cstring<1>{}.assign("abc", 3), std::length_error); + + // assign(CharT const* s). + BOOST_TEST(static_cstring<3>{}.assign("abc") == "abc"); + BOOST_TEST(static_cstring<3>{"*"}.assign("abc") == "abc"); + BOOST_TEST_THROWS(static_cstring<1>{}.assign("abc"), std::length_error); + + // operator=(const CharT* s). + { + static_cstring<3> s1; + s1 = "123"; + BOOST_TEST(s1 == "123"); + BOOST_TEST(*s1.end() == 0); + static_cstring<1> s2; + BOOST_TEST_THROWS( + s2 = "123", + std::length_error); + } + + // Copy assignment. + { + static_cstring<3> s1("123"); + static_cstring<3> s2; + s2 = s1; + BOOST_TEST(s2 == "123"); + BOOST_TEST(*s2.end() == 0); + } +} + +static +void +testCStringElements() +{ + using ccs3 = static_cstring<3> const; + + // at(size_type pos). + BOOST_TEST(static_cstring<3>{"abc"}.at(0) == 'a'); + BOOST_TEST(static_cstring<3>{"abc"}.at(2) == 'c'); + BOOST_TEST_THROWS(static_cstring<3>{""}.at(0), std::out_of_range); + BOOST_TEST_THROWS(static_cstring<3>{"abc"}.at(4), std::out_of_range); + + // at(size_type pos) const. + BOOST_TEST(ccs3{"abc"}.at(0) == 'a'); + BOOST_TEST(ccs3{"abc"}.at(2) == 'c'); + BOOST_TEST_THROWS(ccs3{""}.at(0), std::out_of_range); + + // operator[](size_type pos). + BOOST_TEST(static_cstring<3>{"abc"}[0] == 'a'); + BOOST_TEST(static_cstring<3>{"abc"}[2] == 'c'); + BOOST_TEST(static_cstring<3>{"abc"}[3] == 0); + BOOST_TEST(static_cstring<3>{""}[0] == 0); + + // front() / back(). + BOOST_TEST(static_cstring<3>{"abc"}.front() == 'a'); + BOOST_TEST(static_cstring<3>{"abc"}.back() == 'c'); + + // data() / c_str(). + { + static_cstring<3> s("123"); + BOOST_TEST(std::memcmp(s.data(), "123", 3) == 0); + BOOST_TEST(std::memcmp(s.c_str(), "123\0", 4) == 0); + } + + // Modification through element access. + { + static_cstring<5> s("12345"); + s[1] = '_'; + BOOST_TEST(s == "1_345"); + s.front() = 'A'; + BOOST_TEST(s == "A_345"); + s.back() = 'Z'; + BOOST_TEST(s == "A_34Z"); + } +} + +static +void +testCStringIterators() +{ + { + static_cstring<3> s; + BOOST_TEST(std::distance(s.begin(), s.end()) == 0); + s = "123"; + BOOST_TEST(std::distance(s.begin(), s.end()) == 3); + } + { + static_cstring<3> const s("123"); + BOOST_TEST(std::distance(s.begin(), s.end()) == 3); + BOOST_TEST(std::distance(s.cbegin(), s.cend()) == 3); + } + + // Iteration. + { + static_cstring<5> s("hello"); + std::string result; + for (const char c : s) + { + result += c; + } + BOOST_TEST(result == "hello"); + } +} + +static +void +testCStringCapacity() +{ + // empty(). + BOOST_TEST(static_cstring<0>{}.empty()); + BOOST_TEST(static_cstring<1>{}.empty()); + BOOST_TEST(!static_cstring<1>{"a"}.empty()); + + // size(). + BOOST_TEST(static_cstring<0>{}.size() == 0); + BOOST_TEST(static_cstring<1>{"a"}.size() == 1); + BOOST_TEST(static_cstring<5>{"abc"}.size() == 3); + + // length(). + BOOST_TEST(static_cstring<0>{}.length() == 0); + BOOST_TEST(static_cstring<3>{"abc"}.length() == 3); + + // max_size(). + BOOST_TEST(static_cstring<0>{}.max_size() == 0); + BOOST_TEST(static_cstring<5>{"abc"}.max_size() == 5); + + // capacity(). + BOOST_TEST(static_cstring<0>{}.capacity() == 0); + BOOST_TEST(static_cstring<5>{"abc"}.capacity() == 5); +} + +static +void +testCStringClear() +{ + static_cstring<3> s("123"); + BOOST_TEST(!s.empty()); + s.clear(); + BOOST_TEST(s.empty()); + BOOST_TEST(s.size() == 0); + BOOST_TEST(*s.end() == 0); + BOOST_TEST(s == ""); +} + +static +void +testCStringPushPop() +{ + // push_back(). + { + static_cstring<5> s("abc"); + s.push_back('d'); + BOOST_TEST(s == "abcd"); + BOOST_TEST(s.size() == 4); + BOOST_TEST(*s.end() == 0); + + s.push_back('e'); + BOOST_TEST(s == "abcde"); + BOOST_TEST(s.size() == 5); + + BOOST_TEST_THROWS(s.push_back('f'), std::length_error); + } + + // pop_back(). + { + static_cstring<5> s("abcde"); + s.pop_back(); + BOOST_TEST(s == "abcd"); + BOOST_TEST(s.size() == 4); + BOOST_TEST(*s.end() == 0); + + s.pop_back(); + s.pop_back(); + s.pop_back(); + s.pop_back(); + BOOST_TEST(s.empty()); + } +} + +static +void +testCStringAppend() +{ + // append(const CharT* s). + { + static_cstring<12> s("Hello"); + s.append(", World"); + BOOST_TEST(s == "Hello, World"); + BOOST_TEST(*s.end() == 0); + } + { + static_cstring<5> s("abc"); + BOOST_TEST_THROWS(s.append("def"), std::length_error); + } + + // append(const CharT* s, size_type count) + { + static_cstring<10> s("abc"); + s.append("defgh", 3); + BOOST_TEST(s == "abcdef"); + BOOST_TEST(*s.end() == 0); + } + + // append(size_type count, CharT ch) + { + static_cstring<10> s("abc"); + s.append(3, 'x'); + BOOST_TEST(s == "abcxxx"); + BOOST_TEST(*s.end() == 0); + BOOST_TEST_THROWS(s.append(5, 'y'), std::length_error); + } + + // operator+=() + { + static_cstring<10> s("abc"); + s += "def"; + BOOST_TEST(s == "abcdef"); + s += 'g'; + BOOST_TEST(s == "abcdefg"); + BOOST_TEST(*s.end() == 0); + } +} + +static +void +testCStringComparison() +{ + // operator==() / operator!=(). + { + static_cstring<10> a("abc"); + static_cstring<10> b("abc"); + static_cstring<10> c("abd"); + + BOOST_TEST(a == b); + BOOST_TEST(!(a == c)); + BOOST_TEST(a != c); + BOOST_TEST(!(a != b)); + } + + // operator<(), <=(), >(), >=(). + { + static_cstring<10> a("abc"); + static_cstring<10> b("abd"); + + BOOST_TEST(a < b); + BOOST_TEST(a <= b); + BOOST_TEST(a <= a); + BOOST_TEST(b > a); + BOOST_TEST(b >= a); + BOOST_TEST(b >= b); + } + + // Comparison with CharT const*. + { + static_cstring<10> s("hello"); + BOOST_TEST(s == "hello"); + BOOST_TEST("hello" == s); + BOOST_TEST(s != "world"); + BOOST_TEST("world" != s); + } + + // compare(). + { + static_cstring<10> s("abc"); + BOOST_TEST(s.compare("abc") == 0); + BOOST_TEST(s.compare("abd") < 0); + BOOST_TEST(s.compare("abb") > 0); + } +} + +static +void +testCStringConversion() +{ + // operator string_view(). + { + static_cstring<10> s("hello"); + std::string_view sv = s; + BOOST_TEST(sv == "hello"); + BOOST_TEST(sv.size() == 5); + } + + // str(). + { + static_cstring<10> s("hello"); + std::string str = s.str(); + BOOST_TEST(str == "hello"); + BOOST_TEST(str.size() == 5); + } +} + +static +void +testCStringStream() +{ + static_cstring<10> s("hello"); + std::ostringstream oss; + oss << s; + BOOST_TEST(oss.str() == "hello"); +} + +static +void +testCStringSwap() +{ + static_cstring<10> a("hello"); + static_cstring<10> b("world"); + + a.swap(b); + + BOOST_TEST(a == "world"); + BOOST_TEST(b == "hello"); +} + +static +void +testCStringConstexpr() +{ + // constexpr construction and operations. + constexpr static_cstring<10> ce("test"); + static_assert(ce.size() == 4, ""); + static_assert(ce[0] == 't', ""); + static_assert(ce[1] == 'e', ""); + static_assert(ce[2] == 's', ""); + static_assert(ce[3] == 't', ""); + static_assert(!ce.empty(), ""); + static_assert(ce.max_size() == 10, ""); + static_assert(ce.capacity() == 10, ""); + + constexpr static_cstring<5> ce_empty; + static_assert(ce_empty.empty(), ""); + static_assert(ce_empty.size() == 0, ""); +} + +// Helper struct to test NTTP. +template +struct NTTPHelper +{ + static constexpr std::size_t size() noexcept + { + return S.size(); + } + + static constexpr const char* c_str() noexcept + { + return S.c_str(); + } +}; + +static +void +testCStringNTTP() +{ + // Test non-type template parameter usage (C++20). + + // Test size deduction from string literals. + BOOST_TEST(NTTPHelper<"hello">::size() == 5); + BOOST_TEST(NTTPHelper<"">::size() == 0); + BOOST_TEST(NTTPHelper<"test">::size() == 4); + + // Test that different strings create different types + constexpr bool same_type = std::is_same_v< + NTTPHelper<"hello">, + NTTPHelper<"hello">>; + BOOST_TEST(same_type); + + constexpr bool different_type = !std::is_same_v< + NTTPHelper<"hello">, + NTTPHelper<"world">>; + BOOST_TEST(different_type); + + // Test constexpr access. + constexpr std::size_t len = NTTPHelper<"constexpr">::size(); + static_assert(len == 9, ""); +} + +static +void +testCStringPODUsage() +{ + // Test usage in POD types (the original motivation). + struct UserRecord + { + int id; + static_cstring<63> name; + unsigned int flags; + }; + + static_assert(sizeof(static_cstring<63>) == 64, ""); + static_assert(std::is_trivially_copyable::value, ""); + + UserRecord user{}; + user.id = 42; + user.name = "Alice"; + user.flags = 0xFF; + + BOOST_TEST(user.id == 42); + BOOST_TEST(user.name.size() == 5); + BOOST_TEST(user.name == "Alice"); + BOOST_TEST(user.flags == 0xFF); + + // Copy the struct. + UserRecord copy = user; + BOOST_TEST(copy.name == "Alice"); + + // memcpy() should work. + UserRecord memcpy_dest; + std::memcpy(&memcpy_dest, &user, sizeof(UserRecord)); + BOOST_TEST(memcpy_dest.name == "Alice"); +} + +static +void +testCStringLargeCapacity() +{ + // Test strings with N > UCHAR_MAX (no remaining-capacity trick). + { + static_cstring<300> s; + BOOST_TEST(s.empty()); + BOOST_TEST(s.size() == 0); + + s = "This is a test string"; + BOOST_TEST(s.size() == 21); + BOOST_TEST(s == "This is a test string"); + + s.clear(); + BOOST_TEST(s.empty()); + } + + // Large string operations. + { + static_cstring<500> s; + s.assign(400, 'x'); + BOOST_TEST(s.size() == 400); + BOOST_TEST(s[0] == 'x'); + BOOST_TEST(s[399] == 'x'); + BOOST_TEST(*s.end() == 0); + } +} + +static +void +testCStringWideChar() +{ + // Test with wchar_t. + { + static_wcstring<10> ws; + BOOST_TEST(ws.empty()); + BOOST_TEST(ws.size() == 0); + } + + { + static_wcstring<10> ws(L"hello"); + BOOST_TEST(ws.size() == 5); + BOOST_TEST(ws[0] == L'h'); + BOOST_TEST(ws[4] == L'o'); + BOOST_TEST(*ws.end() == 0); + } +} + +int +runTests() +{ + testCStringSizeGuarantee(); + testCStringRemainingCapacityTrick(); + testCStringTypeTraits(); + testCStringConstruct(); + testCStringAssignment(); + testCStringElements(); + testCStringIterators(); + testCStringCapacity(); + testCStringClear(); + testCStringPushPop(); + testCStringAppend(); + testCStringComparison(); + testCStringConversion(); + testCStringStream(); + testCStringSwap(); + testCStringConstexpr(); + testCStringNTTP(); + testCStringPODUsage(); + testCStringLargeCapacity(); + testCStringWideChar(); + + return report_errors(); +} +} +} + +int +main() +{ + return boost::static_strings::runTests(); +}