From 6cdd497a1c3cb5e2cbf1e4566901bb8df2f77913 Mon Sep 17 00:00:00 2001 From: Packit Date: Sep 29 2020 10:48:36 +0000 Subject: libpmemobj-cpp-1.6 base --- diff --git a/.clang-format b/.clang-format new file mode 100644 index 0000000..9cc487a --- /dev/null +++ b/.clang-format @@ -0,0 +1,34 @@ +AccessModifierOffset: -8 +AlignOperands: false +AllowShortBlocksOnASingleLine: false +AllowShortFunctionsOnASingleLine: false +AllowShortIfStatementsOnASingleLine: false +AlwaysBreakAfterDefinitionReturnType: true +AlwaysBreakTemplateDeclarations: true +BasedOnStyle: LLVM +BraceWrapping: + AfterClass: false + AfterControlStatement: false + AfterEnum: false + AfterFunction: true + AfterNamespace: true + AfterObjCDeclaration: false + AfterStruct: false + AfterUnion: false + BeforeCatch: false + BeforeElse: false + IndentBraces: false +BreakBeforeBraces: Custom +BreakStringLiterals: false +ConstructorInitializerAllOnOneLineOrOnePerLine: true +ContinuationIndentWidth: 8 +FixNamespaceComments: false +IndentCaseLabels: false +IndentCaseLabels: true +IndentWidth: 8 +PointerAlignment: Right +SpaceBeforeParens: ControlStatements +SpacesBeforeTrailingComments: 1 +SpacesInContainerLiterals: false +SpacesInCStyleCastParentheses: false +UseTab: Always diff --git a/.gitattributes b/.gitattributes new file mode 100644 index 0000000..0164a00 --- /dev/null +++ b/.gitattributes @@ -0,0 +1,5 @@ +* text=auto eol=lf +*.jpg binary +*.png binary +*.gif binary +*.ico binary diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..34f7268 --- /dev/null +++ b/.gitignore @@ -0,0 +1,13 @@ +.* +!.gitignore +!.gitattributes +!.clang-format +!.travis.yml +!.mailmap +!.version +build/ +*~ +*.swp +~* +tags +include/libpmemobj++/version.hpp diff --git a/.travis.yml b/.travis.yml new file mode 120000 index 0000000..95c89cf --- /dev/null +++ b/.travis.yml @@ -0,0 +1 @@ +travis.yml \ No newline at end of file diff --git a/.version b/.version new file mode 100644 index 0000000..810ee4e --- /dev/null +++ b/.version @@ -0,0 +1 @@ +1.6 diff --git a/CMakeLists.txt b/CMakeLists.txt new file mode 100644 index 0000000..e6fb9a4 --- /dev/null +++ b/CMakeLists.txt @@ -0,0 +1,366 @@ +# +# Copyright 2018-2019, Intel Corporation +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# +# * Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# +# * Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in +# the documentation and/or other materials provided with the +# distribution. +# +# * Neither the name of the copyright holder nor the names of its +# contributors may be used to endorse or promote products derived +# from this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +cmake_minimum_required(VERSION 3.3) +project(libpmemobj-cpp C CXX) + +set(VERSION_MAJOR 1) +set(VERSION_MINOR 6) +set(VERSION_PATCH 0) +#set(VERSION_PRERELEASE rc1) + +set(VERSION ${VERSION_MAJOR}.${VERSION_MINOR}) +if (VERSION_PATCH GREATER 0) + set(VERSION ${VERSION}.${VERSION_PATCH}) +endif() +if (VERSION_PRERELEASE) + set(VERSION ${VERSION}-${VERSION_PRERELEASE}) +endif() + +set(LIBPMEMOBJ_REQUIRED_VERSION 1.4) + +set(CMAKE_DISABLE_IN_SOURCE_BUILD ON) + +# Treat CMAKE_CXX_STANDARD as a requirement +set(CXX_STANDARD_REQUIRED ON) + +set(CXX_STANDARD 11 CACHE STRING "C++ language standard") +set(CMAKE_CXX_STANDARD ${CXX_STANDARD}) + +include(FindPerl) +include(FindThreads) +include(CMakeDependentOption) +include(CMakePackageConfigHelpers) +include(CheckCXXSourceCompiles) +include(CheckCXXCompilerFlag) +include(GNUInstallDirs) +include(${CMAKE_SOURCE_DIR}/cmake/functions.cmake) + +option(BUILD_EXAMPLES "build examples" ON) +option(BUILD_TESTS "build tests" ON) +option(BUILD_DOC "build documentation" ON) +option(COVERAGE "run coverage test" OFF) +option(DEVELOPER_MODE "enable developer checks" OFF) +option(TRACE_TESTS "more verbose test outputs" OFF) +option(USE_ASAN "enable AddressSanitizer (debugging)" OFF) +option(USE_UBSAN "enable UndefinedBehaviorSanitizer (debugging)" OFF) +option(TESTS_USE_FORCED_PMEM "run tests with PMEM_IS_PMEM_FORCE=1" OFF) +option(TESTS_USE_VALGRIND "enable tests with valgrind (if found)" ON) +option(ENABLE_ARRAY "enable installation and testing of pmem::obj::experimental::array" ON) +option(ENABLE_VECTOR "enable installation and testing of pmem::obj::experimental::vector" ON) +option(ENABLE_STRING "enable installation and testing of pmem::obj::experimental::string (depends on ENABLE_VECTOR)" ON) + +# Required for MSVC to correctly define __cplusplus +add_flag("/Zc:__cplusplus") + +set(TEST_DIR ${CMAKE_CURRENT_BINARY_DIR}/test + CACHE STRING "working directory for tests") + +if(NOT CMAKE_BUILD_TYPE) + set(CMAKE_BUILD_TYPE "Debug") +endif (NOT CMAKE_BUILD_TYPE) + +if(EXISTS "${CMAKE_SOURCE_DIR}/.git") + execute_process(COMMAND git describe + OUTPUT_VARIABLE SRCVERSION + WORKING_DIRECTORY ${CMAKE_SOURCE_DIR} + OUTPUT_STRIP_TRAILING_WHITESPACE + ERROR_QUIET) + if(NOT SRCVERSION) + execute_process(COMMAND git log -1 --format=%h + OUTPUT_VARIABLE SRCVERSION + WORKING_DIRECTORY ${CMAKE_SOURCE_DIR} + OUTPUT_STRIP_TRAILING_WHITESPACE) + endif() +else() + execute_process(COMMAND cat .version + OUTPUT_VARIABLE SRCVERSION + WORKING_DIRECTORY ${CMAKE_SOURCE_DIR} + OUTPUT_STRIP_TRAILING_WHITESPACE) +endif() + +if(NOT WIN32) + find_package(PkgConfig QUIET) +endif() + +set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} ${CMAKE_SOURCE_DIR}/cmake) + +if(NOT PERL_FOUND) + message(FATAL_ERROR "Perl not found") +endif() +if (PERL_VERSION_STRING VERSION_LESS 5.16) + message(FATAL_ERROR "Too old Perl (<5.16)") +endif() + +if(BUILD_TESTS OR BUILD_EXAMPLES) + if(PKG_CONFIG_FOUND) + pkg_check_modules(LIBPMEMOBJ REQUIRED libpmemobj>=1.4) + else() + find_package(LIBPMEMOBJ REQUIRED 1.4) + endif() + + if (LIBPMEMOBJ_VERSION) + string(REGEX REPLACE "\\+git.*" "" LIBPMEMOBJ_VERSION_SHORT ${LIBPMEMOBJ_VERSION}) + string(REGEX REPLACE "-rc.*" "" LIBPMEMOBJ_VERSION_SHORT ${LIBPMEMOBJ_VERSION_SHORT}) + string(REPLACE "." ";" VERSION_LIST ${LIBPMEMOBJ_VERSION_SHORT}) + list(GET VERSION_LIST 0 LIBPMEMOBJ_VERSION_MAJOR) + list(GET VERSION_LIST 1 LIBPMEMOBJ_VERSION_MINOR) + list(LENGTH VERSION_LIST OBJ_VER_COMPS) + if (${OBJ_VER_COMPS} LESS 3) + list(APPEND VERSION_LIST "0") + endif() + list(GET VERSION_LIST 2 LIBPMEMOBJ_VERSION_PATCH) + else() + message(WARNING "cannot detect libpmemobj version, some tests will be skipped") + # assume 0.0.0 + set(LIBPMEMOBJ_VERSION_MAJOR 0) + set(LIBPMEMOBJ_VERSION_MINOR 0) + set(LIBPMEMOBJ_VERSION_PATCH 0) + endif() + + math(EXPR LIBPMEMOBJ_VERSION_NUM "${LIBPMEMOBJ_VERSION_PATCH} + ${LIBPMEMOBJ_VERSION_MINOR} * 100 + ${LIBPMEMOBJ_VERSION_MAJOR} * 10000") +endif() + +add_executable(check_license EXCLUDE_FROM_ALL utils/check_license/check-license.c) + +add_custom_target(checkers ALL) +add_custom_target(cppstyle) +add_custom_target(cppformat) +add_custom_target(check-whitespace) +add_custom_target(check-license + COMMAND ${CMAKE_SOURCE_DIR}/utils/check_license/check-headers.sh + ${CMAKE_SOURCE_DIR} + ${CMAKE_BINARY_DIR}/check_license + ${CMAKE_SOURCE_DIR}/LICENSE + -a) +add_dependencies(check-license check_license) + +add_custom_target(check-whitespace-main + COMMAND ${PERL_EXECUTABLE} + ${CMAKE_SOURCE_DIR}/utils/check_whitespace + ${CMAKE_SOURCE_DIR}/utils/check_license/*.sh + ${CMAKE_SOURCE_DIR}/README.md) + +add_dependencies(check-whitespace check-whitespace-main) + +add_custom_target(tests) + +if(DEVELOPER_MODE) + add_flag(-Werror) # XXX: WX for windows + find_program(CLANG_FORMAT NAMES clang-format clang-format-6.0) + set(CLANG_FORMAT_REQUIRED "6.0") + if(CLANG_FORMAT) + get_program_version(${CLANG_FORMAT} CLANG_FORMAT_VERSION) + if(NOT (CLANG_FORMAT_VERSION VERSION_EQUAL CLANG_FORMAT_REQUIRED)) + message(WARNING "required clang-format version is ${CLANG_FORMAT_REQUIRED}") + unset(CLANG_FORMAT) + endif() + else() + message(WARNING "clang-format not found - C++ sources will not be checked (needed version: ${CLANG_FORMAT_REQUIRED})") + endif() + + execute_process(COMMAND ${PERL_EXECUTABLE} -MText::Diff -e "" + ERROR_QUIET + RESULT_VARIABLE PERL_TEXT_DIFF_STATUS) + if (PERL_TEXT_DIFF_STATUS) + message(FATAL_ERROR "Text::Diff Perl module not found (install libtext-diff-perl or perl-Text-Diff)") + endif() + + add_dependencies(checkers cppstyle) + add_dependencies(checkers check-whitespace) + add_dependencies(checkers check-license) +endif(DEVELOPER_MODE) + +add_cppstyle(include ${CMAKE_CURRENT_SOURCE_DIR}/include/libpmemobj++/*.hpp) +add_cppstyle(include-detail ${CMAKE_CURRENT_SOURCE_DIR}/include/libpmemobj++/detail/*.hpp) +add_cppstyle(include-experimental ${CMAKE_CURRENT_SOURCE_DIR}/include/libpmemobj++/experimental/*.hpp) +add_check_whitespace(include ${CMAKE_CURRENT_SOURCE_DIR}/include/libpmemobj++/*.hpp) +add_check_whitespace(include-detail ${CMAKE_CURRENT_SOURCE_DIR}/include/libpmemobj++/detail/*.hpp) +add_check_whitespace(include-experimental ${CMAKE_CURRENT_SOURCE_DIR}/include/libpmemobj++/experimental/*.hpp) +add_check_whitespace(cmake-main ${CMAKE_CURRENT_SOURCE_DIR}/CMakeLists.txt) +add_check_whitespace(cmake-helpers ${CMAKE_CURRENT_SOURCE_DIR}/cmake/*.cmake) + +# Check for existence of pmemvlt (introduced after 1.4 release) +set(SAVED_CMAKE_REQUIRED_INCLUDES ${CMAKE_REQUIRED_INCLUDES}) +set(CMAKE_REQUIRED_INCLUDES ${LIBPMEMOBJ_INCLUDE_DIRS}) +CHECK_CXX_SOURCE_COMPILES( + "#include + struct pmemvlt vlt; + int main() {}" + PMEMVLT_PRESENT) +set(CMAKE_REQUIRED_INCLUDES ${SAVED_CMAKE_REQUIRED_INCLUDES}) + +if(NOT PMEMVLT_PRESENT) + message(WARNING "pmemvlt support in libpmemobj not found (to enable - use libpmemobj version > 1.4") +endif() + +configure_file(${CMAKE_SOURCE_DIR}/cmake/version.hpp.in + ${CMAKE_SOURCE_DIR}/include/libpmemobj++/version.hpp @ONLY) + +install(DIRECTORY include/ DESTINATION ${CMAKE_INSTALL_INCLUDEDIR} + FILES_MATCHING PATTERN "*.hpp" + PATTERN "array.hpp" EXCLUDE + PATTERN "vector.hpp" EXCLUDE + PATTERN "string.hpp" EXCLUDE + PATTERN "basic_string.hpp" EXCLUDE + PATTERN "contiguous_iterator.hpp" EXCLUDE + PATTERN "slice.hpp" EXCLUDE) + +if (ENABLE_ARRAY) + install(DIRECTORY include/ DESTINATION ${CMAKE_INSTALL_INCLUDEDIR} FILES_MATCHING PATTERN "array.hpp") +endif() + +if (ENABLE_VECTOR) + install(DIRECTORY include/ DESTINATION ${CMAKE_INSTALL_INCLUDEDIR} FILES_MATCHING PATTERN "vector.hpp") +endif() + +if (ENABLE_STRING) + install(DIRECTORY include/ DESTINATION ${CMAKE_INSTALL_INCLUDEDIR} FILES_MATCHING PATTERN "basic_string.hpp") + install(DIRECTORY include/ DESTINATION ${CMAKE_INSTALL_INCLUDEDIR} FILES_MATCHING PATTERN "string.hpp") +endif() + +if (ENABLE_ARRAY OR ENABLE_VECTOR OR ENABLE_STRING) + install(DIRECTORY include/ DESTINATION ${CMAKE_INSTALL_INCLUDEDIR} FILES_MATCHING PATTERN "contiguous_iterator.hpp") + install(DIRECTORY include/ DESTINATION ${CMAKE_INSTALL_INCLUDEDIR} FILES_MATCHING PATTERN "slice.hpp") +endif() + +install(DIRECTORY examples/ DESTINATION ${CMAKE_INSTALL_DOCDIR}/examples + FILES_MATCHING PATTERN "*.*pp") + +configure_file(${CMAKE_SOURCE_DIR}/cmake/libpmemobj++.pc.in + ${CMAKE_CURRENT_BINARY_DIR}/libpmemobj++.pc @ONLY) + +install(FILES ${CMAKE_CURRENT_BINARY_DIR}/libpmemobj++.pc + CONFIGURATIONS Release Debug + DESTINATION ${CMAKE_INSTALL_LIBDIR}/pkgconfig) + +configure_file( + "${CMAKE_SOURCE_DIR}/cmake/cmake_uninstall.cmake.in" + "${CMAKE_CURRENT_BINARY_DIR}/cmake_uninstall.cmake" + IMMEDIATE @ONLY) + +add_custom_target(uninstall + COMMAND ${CMAKE_COMMAND} -P ${CMAKE_CURRENT_BINARY_DIR}/cmake_uninstall.cmake) + +configure_package_config_file(${CMAKE_SOURCE_DIR}/cmake/libpmemobj++-config.cmake.in + ${CMAKE_CURRENT_BINARY_DIR}/libpmemobj++-config.cmake + INSTALL_DESTINATION ${CMAKE_INSTALL_LIBDIR}/libpmemobj++/cmake + PATH_VARS CMAKE_INSTALL_LIBDIR CMAKE_INSTALL_INCLUDEDIR) + +write_basic_package_version_file(libpmemobj++-config-version.cmake + VERSION ${VERSION} + COMPATIBILITY AnyNewerVersion) + +install(FILES ${CMAKE_CURRENT_BINARY_DIR}/libpmemobj++-config.cmake ${CMAKE_CURRENT_BINARY_DIR}/libpmemobj++-config-version.cmake + DESTINATION ${CMAKE_INSTALL_LIBDIR}/libpmemobj++/cmake) + +if(NOT MSVC_VERSION) + set(SAVED_CMAKE_REQUIRED_FLAGS ${CMAKE_REQUIRED_FLAGS}) + + # Check for issues with older gcc compilers which do not expand variadic template + # variables in lambda expressions. + set(CMAKE_REQUIRED_FLAGS "--std=c++11 -Wno-error -c") + CHECK_CXX_SOURCE_COMPILES( + "void print() {} + template + void print(const T&, const Args &...arg) { + auto f = [&]{ print(arg...);}; + } + int main() { + print(1, 2, 3); + return 0; + }" + NO_GCC_VARIADIC_TEMPLATE_BUG) + + # Check for issues with older gcc compilers if "inline" aggregate initialization + # works for array class members https://gcc.gnu.org/bugzilla/show_bug.cgi?id=65815 + CHECK_CXX_SOURCE_COMPILES( + "struct array { + int data[2]; + }; + struct X { + array a = { 1, 2 }; + }; + int main() { + return 0; + }" + NO_GCC_AGGREGATE_INITIALIZATION_BUG) + + # Check for issues related to agregate initialization in new expression. + # Following code will fail for LLVM compiler https://bugs.llvm.org/show_bug.cgi?id=39988 + set(CMAKE_REQUIRED_FLAGS "--std=c++11 -Wno-error") + CHECK_CXX_SOURCE_COMPILES( + "template + struct A { + A() {}; + ~A() {}; + }; + struct B { + A a; + A b; + }; + int main() { + new B{}; + return 0; + }" + NO_CLANG_BRACE_INITIALIZATION_NEWEXPR_BUG) + set(CMAKE_REQUIRED_FLAGS ${SAVED_CMAKE_REQUIRED_FLAGS}) +else() + set(NO_GCC_VARIADIC_TEMPLATE_BUG TRUE) + set(NO_GCC_AGGREGATE_INITIALIZATION_BUG TRUE) + set(NO_CLANG_BRACE_INITIALIZATION_NEWEXPR_BUG TRUE) +endif() + +include_directories(include) + +if(BUILD_TESTS) + if(TEST_DIR) + enable_testing() + else() + message(WARNING "TEST_DIR is empty - 'make test' will not work") + endif() + + add_subdirectory(tests) +endif() + +if(BUILD_DOC) + add_subdirectory(doc) +endif() + +if(BUILD_EXAMPLES AND NO_GCC_VARIADIC_TEMPLATE_BUG) + add_subdirectory(examples) +elseif(BUILD_EXAMPLES) + message(WARNING "Skipping build of examples because of compiler issue") +endif() + +if(NOT "${CPACK_GENERATOR}" STREQUAL "") + include(${CMAKE_SOURCE_DIR}/cmake/packages.cmake) +endif() diff --git a/ChangeLog b/ChangeLog new file mode 100644 index 0000000..4e97af7 --- /dev/null +++ b/ChangeLog @@ -0,0 +1,61 @@ +Fri Mar 15 2019 Igor Chorążewicz + + * Version 1.6 + + This release introduces ctl support, allocation flags, snapshot + method and new experimental persistent container - vector. + + New features: + - add support for pmemobj_ctl_set/get/exec + - expose allocation flags in make_persistent(_atomic) + - transaction: add snapshot method + + Experimental features: + - persistent vector container + + Other changes: + - automatically start transaction inside pmem::obj::experimental::array + modifier methods (assignment operators, swap and fill) + - add const methods for pmem::obj::experimental::array + - add Valgrind instrumentation support + - remove experimental const_contiguous_iterator + - add get with arguments method overload for v + + Bug fixes: + - throw an exception when dropping pmem lock failed + - fix crash when previous transaction failed to start + - fix forwarding parameters to constructor in make_persistent_atomic + + Optimizations: + - decrease number of persistent_ptr dereferences in + make_persistent_array + +Tue Feb 19 2018 Marcin Ślusarz + + * Version 1.5.1 + + This release fixes minor bugs and improves documentation. + + Notable changes: + - fix v swap, assignment operators and constructors + - change conversion operator from T() to T&() in v<> + - fix range_snapshotting initialization in array.hpp. + - fix range_snapshotting_iterator bahaviour for snapshot_size == 0. + +Fri Oct 26 2018 Marcin Ślusarz + + * Version 1.5 + + This is the first release of libpmemobj-cpp as a separate project. + + It introduces one persistent container - array, which has std::array + like interface. Currently it is considered experimental and lives + in experimental namespace. + + We have also cleaned up some function names that, in retrospect, were + chosen poorly. Functions with old names are still there but are + deprecated. + + Experimental features: + - volatile resides on pmem class + - persistent array container diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..9d82122 --- /dev/null +++ b/LICENSE @@ -0,0 +1,36 @@ +Copyright 2018, Intel Corporation + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions +are met: + + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + * Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in + the documentation and/or other materials provided with the + distribution. + + * Neither the name of the copyright holder nor the names of its + contributors may be used to endorse or promote products derived + from this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + +Everything in this source tree is covered by the previous license +with the following exceptions: + +* tests/external/libcxx which contain tests adapted from llvm + libcxx, and is covered by license contained in that directory. diff --git a/README.md b/README.md new file mode 100644 index 0000000..34a1bdb --- /dev/null +++ b/README.md @@ -0,0 +1,75 @@ +libpmemobj-cpp +=============== + +[![Build Status](https://travis-ci.org/pmem/libpmemobj-cpp.svg?branch=master)](https://travis-ci.org/pmem/libpmemobj-cpp) +[![Build status](https://ci.appveyor.com/api/projects/status/github/pmem/libpmemobj-cpp?branch/master?svg=true&pr=false)](https://ci.appveyor.com/project/pmem/libpmemobj-cpp/branch/master) +[![Coverity Scan Build Status](https://scan.coverity.com/projects/15911/badge.svg)](https://scan.coverity.com/projects/pmem-libpmemobj-cpp) +[![Coverage Status](https://codecov.io/github/pmem/libpmemobj-cpp/coverage.svg?branch=master)](https://codecov.io/gh/pmem/libpmemobj-cpp/branch/master) + +C++ bindings for libpmemobj (https://github.com/pmem/pmdk) +More informations in include/libpmemobj++/README.md + +# How to build # + +## Requirements: ## +- cmake >= 3.3 +- libpmemobj-dev(el) >= 1.4 (http://pmem.io/pmdk/) + +## On Linux ## + +```sh +$ mkdir build +$ cd build +$ cmake .. +$ make +$ make install +``` + +#### When developing: #### +```sh +$ ... +$ cmake .. -DCMAKE_BUILD_TYPE=Debug -DDEVELOPER_MODE=1 +$ ... +$ ctest --output-on-failure +``` + +#### To build packages #### +```sh +... +cmake .. -DCPACK_GENERATOR="$GEN" -DCMAKE_INSTALL_PREFIX=/usr +make package +``` + +$GEN is type of package generator and can be RPM or DEB + +CMAKE_INSTALL_PREFIX must be set to a destination were packages will be installed + +#### To use with Valgrind #### + +In order to build your application with libpmemobj-cpp and +[pmemcheck](https://github.com/pmem/valgrind) / memcheck / helgrind / drd, +Valgrind instrumentation must be enabled during compilation by adding flags: +- LIBPMEMOBJ_CPP_VG_PMEMCHECK_ENABLED=1 for pmemcheck instrumentation, +- LIBPMEMOBJ_CPP_VG_MEMCHECK_ENABLED=1 for memcheck instrumentation, +- LIBPMEMOBJ_CPP_VG_HELGRIND_ENABLED=1 for helgrind instrumentation, +- LIBPMEMOBJ_CPP_VG_DRD_ENABLED=1 for drd instrumentation, or +- LIBPMEMOBJ_CPP_VG_ENABLED=1 for all Valgrind instrumentations (including pmemcheck). + +If there are no memcheck / helgrind / drd / pmemcheck headers installed on your +system, build will fail. + +## On Windows ## + +#### Install libpmemobj via vcpkg #### +```sh +vcpkg install pmdk:x64-windows +vcpkg integrate install +``` + +```sh +... +cmake . -Bbuild -G "Visual Studio 14 2015 Win64" + -DCMAKE_TOOLCHAIN_FILE=c:/tools/vcpkg/scripts/buildsystems/vcpkg.cmake + +msbuild build/ALL_BUILD.vcxproj +``` diff --git a/appveyor.yml b/appveyor.yml new file mode 100644 index 0000000..2766dd6 --- /dev/null +++ b/appveyor.yml @@ -0,0 +1,41 @@ +version: 1.4.{build} +os: Visual Studio 2015 +platform: x64 + +environment: + VCPKG_DEFAULT_TRIPLET: x64-windows + GENERATOR: "Visual Studio 14 2015 Win64" + +install: +- vcpkg install pmdk:x64-windows +- vcpkg install sfml:x64-windows +- vcpkg integrate install + +cache: c:\tools\vcpkg\installed + +configuration: +- Debug +- Release + +matrix: + fast_finish: true + +before_build: +- cmake . -Bbuild -G "%GENERATOR%" + -DCMAKE_TOOLCHAIN_FILE=c:/tools/vcpkg/scripts/buildsystems/vcpkg.cmake + -DCMAKE_INSTALL_PREFIX=c:/install/libpmemobj-cpp + +build_script: +- msbuild build/ALL_BUILD.vcxproj /property:Configuration=%CONFIGURATION% + +test_script: +- cd build +- ctest -C %CONFIGURATION% --output-on-failure --timeout 540 +- msbuild INSTALL.vcxproj +- cd .. +# build standalone example +- cd examples/map_cli +- cmake . -G "%GENERATOR%" + -DCMAKE_TOOLCHAIN_FILE=c:/tools/vcpkg/scripts/buildsystems/vcpkg.cmake + -DCMAKE_PREFIX_PATH=c:/install/libpmemobj-cpp +- msbuild ALL_BUILD.vcxproj diff --git a/cmake/FindLIBPMEMOBJ.cmake b/cmake/FindLIBPMEMOBJ.cmake new file mode 100644 index 0000000..becdfea --- /dev/null +++ b/cmake/FindLIBPMEMOBJ.cmake @@ -0,0 +1,39 @@ +# +# Copyright 2018, Intel Corporation +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# +# * Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# +# * Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in +# the documentation and/or other materials provided with the +# distribution. +# +# * Neither the name of the copyright holder nor the names of its +# contributors may be used to endorse or promote products derived +# from this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +find_path(LIBPMEMOBJ_INCLUDE_DIR libpmemobj.h) +find_library(LIBPMEMOBJ_LIBRARY NAMES pmemobj libpmemobj) +find_library(LIBPMEM_LIBRARY NAMES pmem libpmem) + +set(LIBPMEMOBJ_LIBRARIES ${LIBPMEMOBJ_LIBRARY} ${LIBPMEM_LIBRARY}) +set(LIBPMEMOBJ_INCLUDE_DIRS ${LIBPMEMOBJ_INCLUDE_DIR}) + +mark_as_advanced(LIBPMEMOBJ_LIBRARY LIBPMEM_LIBRARY LIBPMEMOBJ_INCLUDE_DIR) diff --git a/cmake/cmake_uninstall.cmake.in b/cmake/cmake_uninstall.cmake.in new file mode 100644 index 0000000..9dd59db --- /dev/null +++ b/cmake/cmake_uninstall.cmake.in @@ -0,0 +1,22 @@ +# From: https://cmake.org/Wiki/CMake_FAQ + +if(NOT EXISTS "@CMAKE_CURRENT_BINARY_DIR@/install_manifest.txt") + message(FATAL_ERROR "Cannot find install manifest: @CMAKE_CURRENT_BINARY_DIR@/install_manifest.txt") +endif(NOT EXISTS "@CMAKE_CURRENT_BINARY_DIR@/install_manifest.txt") + +file(READ "@CMAKE_CURRENT_BINARY_DIR@/install_manifest.txt" files) +string(REGEX REPLACE "\n" ";" files "${files}") +foreach(file ${files}) + message(STATUS "Uninstalling $ENV{DESTDIR}${file}") + if(IS_SYMLINK "$ENV{DESTDIR}${file}" OR EXISTS "$ENV{DESTDIR}${file}") + exec_program("@CMAKE_COMMAND@" ARGS "-E remove \"$ENV{DESTDIR}${file}\"" + OUTPUT_VARIABLE rm_out + RETURN_VALUE rm_retval + ) + if(NOT "${rm_retval}" STREQUAL 0) + message(FATAL_ERROR "Problem when removing $ENV{DESTDIR}${file}") + endif(NOT "${rm_retval}" STREQUAL 0) + else(IS_SYMLINK "$ENV{DESTDIR}${file}" OR EXISTS "$ENV{DESTDIR}${file}") + message(STATUS "File $ENV{DESTDIR}${file} does not exist.") + endif(IS_SYMLINK "$ENV{DESTDIR}${file}" OR EXISTS "$ENV{DESTDIR}${file}") +endforeach(file) diff --git a/cmake/functions.cmake b/cmake/functions.cmake new file mode 100644 index 0000000..6e26662 --- /dev/null +++ b/cmake/functions.cmake @@ -0,0 +1,154 @@ +# +# Copyright 2018, Intel Corporation +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# +# * Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# +# * Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in +# the documentation and/or other materials provided with the +# distribution. +# +# * Neither the name of the copyright holder nor the names of its +# contributors may be used to endorse or promote products derived +# from this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +# +# functions.cmake - helper functions for CMakeLists.txt +# + +function(join SEP OUT VALUES) + string(REPLACE ";" "${SEP}" JOIN_TMP "${VALUES}") + set(${OUT} "${JOIN_TMP}" PARENT_SCOPE) +endfunction() + +# prepends prefix to list of strings +function(prepend var prefix) + set(listVar "") + foreach(f ${ARGN}) + list(APPEND listVar "${prefix}/${f}") + endforeach(f) + set(${var} "${listVar}" PARENT_SCOPE) +endfunction() + +# Checks whether flag is supported by current C++ compiler and appends +# it to the relevant cmake variable. +# 1st argument is a flag +# 2nd (optional) argument is a build type (debug, release) +macro(add_flag flag) + string(REPLACE - _ flag2 ${flag}) + string(REPLACE " " _ flag2 ${flag2}) + string(REPLACE = "_" flag2 ${flag2}) + set(check_name "CXX_HAS_${flag2}") + + check_cxx_compiler_flag(${flag} ${check_name}) + + if (${${check_name}}) + if (${ARGC} EQUAL 1) + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${flag}") + else() + set(CMAKE_CXX_FLAGS_${ARGV1} "${CMAKE_CXX_FLAGS_${ARGV1}} ${flag}") + endif() + endif() +endmacro() + +macro(add_sanitizer_flag flag) + set(SAVED_CMAKE_REQUIRED_LIBRARIES ${CMAKE_REQUIRED_LIBRARIES}) + set(CMAKE_REQUIRED_LIBRARIES "${CMAKE_REQUIRED_LIBRARIES} -fsanitize=${flag}") + + check_cxx_compiler_flag("-fsanitize=${flag}" CXX_HAS_ASAN_UBSAN) + if(CXX_HAS_ASAN_UBSAN) + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fsanitize=${flag}") + set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -fsanitize=${flag}") + else() + message("${flag} sanitizer not supported") + endif() + + set(CMAKE_REQUIRED_LIBRARIES ${SAVED_CMAKE_REQUIRED_LIBRARIES}) +endmacro() + +# Generates cppstyle-$name and cppformat-$name targets and attaches them +# as dependencies of global "cppformat" target. +# cppstyle-$name target verifies C++ style of files in current source dir. +# cppformat-$name target reformats files in current source dir. +# If more arguments are used, then they are used as files to be checked +# instead. +# ${name} must be unique. +function(add_cppstyle name) + if(NOT CLANG_FORMAT) + return() + endif() + + if(${ARGC} EQUAL 1) + add_custom_target(cppstyle-${name} + COMMAND ${PERL_EXECUTABLE} + ${CMAKE_SOURCE_DIR}/utils/cppstyle + ${CLANG_FORMAT} + check + ${CMAKE_CURRENT_SOURCE_DIR}/*.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/*.hpp + ) + add_custom_target(cppformat-${name} + COMMAND ${PERL_EXECUTABLE} + ${CMAKE_SOURCE_DIR}/utils/cppstyle + ${CLANG_FORMAT} + format + ${CMAKE_CURRENT_SOURCE_DIR}/*.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/*.hpp + ) + else() + add_custom_target(cppstyle-${name} + COMMAND ${PERL_EXECUTABLE} + ${CMAKE_SOURCE_DIR}/utils/cppstyle + ${CLANG_FORMAT} + check + ${ARGN} + ) + add_custom_target(cppformat-${name} + COMMAND ${PERL_EXECUTABLE} + ${CMAKE_SOURCE_DIR}/utils/cppstyle + ${CLANG_FORMAT} + format + ${ARGN} + ) + endif() + + add_dependencies(cppstyle cppstyle-${name}) + add_dependencies(cppformat cppformat-${name}) +endfunction() + +# Generates check-whitespace-$name target and attaches it as a dependency +# of global "check-whitespace" target. +# ${name} must be unique. +function(add_check_whitespace name) + add_custom_target(check-whitespace-${name} + COMMAND ${PERL_EXECUTABLE} + ${CMAKE_SOURCE_DIR}/utils/check_whitespace ${ARGN}) + + add_dependencies(check-whitespace check-whitespace-${name}) +endfunction() + +# Sets ${ret} to version of program specified by ${name} in major.minor.patch format +function(get_program_version name ret) + execute_process(COMMAND ${name} --version + OUTPUT_VARIABLE cmd_ret + ERROR_QUIET) + STRING(REGEX MATCH "([0-9]+.)([0-9]+.)([0-9]+)" VERSION ${cmd_ret}) + SET(${ret} ${VERSION} PARENT_SCOPE) +endfunction() diff --git a/cmake/libpmemobj++-config.cmake.in b/cmake/libpmemobj++-config.cmake.in new file mode 100644 index 0000000..a830858 --- /dev/null +++ b/cmake/libpmemobj++-config.cmake.in @@ -0,0 +1,41 @@ +# +# Copyright 2018, Intel Corporation +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# +# * Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# +# * Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in +# the documentation and/or other materials provided with the +# distribution. +# +# * Neither the name of the copyright holder nor the names of its +# contributors may be used to endorse or promote products derived +# from this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +@PACKAGE_INIT@ + +find_path(LIBPMEMOBJ_INCLUDE_DIR libpmemobj.h) +find_library(LIBPMEMOBJ_LIBRARY NAMES pmemobj libpmemobj) +find_library(LIBPMEM_LIBRARY NAMES pmem libpmem) + +set_and_check(LIBPMEMOBJ++_INCLUDE "@PACKAGE_CMAKE_INSTALL_INCLUDEDIR@") + +set(LIBPMEMOBJ++_LIBRARIES ${LIBPMEMOBJ_LIBRARY} ${LIBPMEM_LIBRARY}) +set(LIBPMEMOBJ++_INCLUDE_DIRS ${LIBPMEMOBJ++_INCLUDE} ${LIBPMEMOBJ_INCLUDE_DIR}) diff --git a/cmake/libpmemobj++.pc.in b/cmake/libpmemobj++.pc.in new file mode 100644 index 0000000..1ab169a --- /dev/null +++ b/cmake/libpmemobj++.pc.in @@ -0,0 +1,10 @@ +prefix=@CMAKE_INSTALL_PREFIX@ +libdir=${prefix}/@CMAKE_INSTALL_LIBDIR@ +includedir=${prefix}/@CMAKE_INSTALL_INCLUDEDIR@ + +Name: libpmemobj++ +Description: libpmemobj++ - c++ bindings for libpmemobj library +Version: @VERSION@ +URL: http://github.com/pmem/libpmemobj-cpp +Requires: libpmemobj >= @LIBPMEMOBJ_REQUIRED_VERSION@ +Cflags: -I${includedir} diff --git a/cmake/packages.cmake b/cmake/packages.cmake new file mode 100644 index 0000000..097ba53 --- /dev/null +++ b/cmake/packages.cmake @@ -0,0 +1,91 @@ +# +# Copyright 2018-2019, Intel Corporation +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# +# * Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# +# * Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in +# the documentation and/or other materials provided with the +# distribution. +# +# * Neither the name of the copyright holder nor the names of its +# contributors may be used to endorse or promote products derived +# from this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +# +# packages.cmake - CPack configuration for rpm and deb generation +# + +string(TOUPPER "${CPACK_GENERATOR}" CPACK_GENERATOR) + +if(NOT ("${CPACK_GENERATOR}" STREQUAL "DEB" OR + "${CPACK_GENERATOR}" STREQUAL "RPM")) + message(FATAL_ERROR "Wrong CPACK_GENERATOR value, valid generators are: DEB, RPM") +endif() + +set(CPACK_PACKAGING_INSTALL_PREFIX "${CMAKE_INSTALL_PREFIX}") +set(CMAKE_INSTALL_TMPDIR /tmp CACHE PATH "Output dir for tmp") +set(CPACK_COMPONENTS_ALL_IN_ONE) + +# Filter out some of directories from %dir section, which are expected +# to exist in filesystem. Leaving them might lead to conflicts with other +# packages (for example with 'filesystem' package on fedora which specify +# /usr, /usr/local, etc.) +set(CPACK_RPM_EXCLUDE_FROM_AUTO_FILELIST_ADDITION + ${CPACK_PACKAGING_INSTALL_PREFIX} + ${CPACK_PACKAGING_INSTALL_PREFIX}/${CMAKE_INSTALL_LIBDIR} + ${CPACK_PACKAGING_INSTALL_PREFIX}/${CMAKE_INSTALL_LIBDIR}/pkgconfig + ${CPACK_PACKAGING_INSTALL_PREFIX}/${CMAKE_INSTALL_INCDIR} + ${CPACK_PACKAGING_INSTALL_PREFIX}/share + ${CPACK_PACKAGING_INSTALL_PREFIX}/share/doc) + +set(CPACK_PACKAGE_NAME "libpmemobj++") +set(CPACK_PACKAGE_VERSION ${VERSION}) +set(CPACK_PACKAGE_VERSION_MAJOR ${VERSION_MAJOR}) +set(CPACK_PACKAGE_VERSION_MINOR ${VERSION_MINOR}) +set(CPACK_PACKAGE_DESCRIPTION_SUMMARY "c++ bindings to libpmemobj") +set(CPACK_PACKAGE_VENDOR "Intel") + +set(CPACK_RPM_PACKAGE_NAME "libpmemobj++-devel") +set(CPACK_RPM_PACKAGE_GROUP "Development/Libraries") +set(CPACK_RPM_PACKAGE_LICENSE "BSD") +set(CPACK_RPM_PACKAGE_ARCHITECTURE x86_64) +set(CPACK_RPM_PACKAGE_REQUIRES "libpmemobj-devel >= ${LIBPMEMOBJ_REQUIRED_VERSION}") +#set(CPACK_RPM_CHANGELOG_FILE ${CMAKE_SOURCE_DIR}/ChangeLog) + +set(CPACK_DEBIAN_PACKAGE_NAME "libpmemobj++-dev") +set(CPACK_DEBIAN_PACKAGE_VERSION ${CPACK_PACKAGE_VERSION}) +set(CPACK_DEBIAN_PACKAGE_ARCHITECTURE amd64) +set(CPACK_DEBIAN_PACKAGE_DEPENDS "libpmemobj-dev (>= ${LIBPMEMOBJ_REQUIRED_VERSION})") +set(CPACK_DEBIAN_PACKAGE_MAINTAINER "marcin.slusarz@intel.com") + +if("${CPACK_GENERATOR}" STREQUAL "RPM") + set(CPACK_PACKAGE_FILE_NAME + ${CPACK_RPM_PACKAGE_NAME}-${CPACK_PACKAGE_VERSION}.${CPACK_RPM_PACKAGE_ARCHITECTURE}) +elseif("${CPACK_GENERATOR}" STREQUAL "DEB") + # We are using "gnutar" to avoid this bug: + # https://gitlab.kitware.com/cmake/cmake/issues/14332 + set(CPACK_DEBIAN_ARCHIVE_TYPE "gnutar") + set(CPACK_PACKAGE_FILE_NAME + ${CPACK_DEBIAN_PACKAGE_NAME}-${CPACK_PACKAGE_VERSION}_${CPACK_DEBIAN_PACKAGE_ARCHITECTURE}) +endif() + +set(targetDestDir ${CMAKE_INSTALL_TMPDIR}) +include(CPack) diff --git a/cmake/version.hpp.in b/cmake/version.hpp.in new file mode 100644 index 0000000..5739588 --- /dev/null +++ b/cmake/version.hpp.in @@ -0,0 +1,47 @@ +/* + * Copyright 2018, Intel Corporation + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * * Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +/** + * @file + * Auto-generated file containing source version + */ + +#ifndef LIBPMEMOBJ_CPP_VERSION_HPP +#define LIBPMEMOBJ_CPP_VERSION_HPP + +#define LIBPMEMOBJ_CPP_VERSION_MAJOR @VERSION_MAJOR@ +#define LIBPMEMOBJ_CPP_VERSION_MINOR @VERSION_MINOR@ +#define LIBPMEMOBJ_CPP_VERSION_PATCH @VERSION_PATCH@ + +#define LIBPMEMOBJ_CPP_VERSION "@VERSION@" + +#endif /* LIBPMEMOBJ_CPP_VERSION_HPP */ diff --git a/codecov.yml b/codecov.yml new file mode 100644 index 0000000..aee2bc6 --- /dev/null +++ b/codecov.yml @@ -0,0 +1,11 @@ +coverage: + status: + project: + default: + threshold: 0.2 + + ignore: + - utils/ + - tests/ + - doc/ + - examples/ diff --git a/doc/CMakeLists.txt b/doc/CMakeLists.txt new file mode 100644 index 0000000..cdad12e --- /dev/null +++ b/doc/CMakeLists.txt @@ -0,0 +1,45 @@ +# +# Copyright 2018-2019, Intel Corporation +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# +# * Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# +# * Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in +# the documentation and/or other materials provided with the +# distribution. +# +# * Neither the name of the copyright holder nor the names of its +# contributors may be used to endorse or promote products derived +# from this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +include(FindDoxygen) +if(DOXYGEN_FOUND AND DOXYGEN_DOT_FOUND) + configure_file("${CMAKE_CURRENT_SOURCE_DIR}/libpmemobj++.Doxyfile.in" + "${CMAKE_CURRENT_BINARY_DIR}/libpmemobj++.Doxyfile" @ONLY) + + add_custom_target(doc ALL ${DOXYGEN_EXECUTABLE} "${CMAKE_CURRENT_BINARY_DIR}/libpmemobj++.Doxyfile" + WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}) + + install(DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/cpp_html/ DESTINATION ${CMAKE_INSTALL_DOCDIR}) +elseif(NOT DOXYGEN_FOUND) + message(WARNING "Doxygen not found - documentation will not be generated") +else() + message(WARNING "Dot tool not found - documentation will not be generated") +endif() diff --git a/doc/libpmemobj++.Doxyfile.in b/doc/libpmemobj++.Doxyfile.in new file mode 100644 index 0000000..cc4103f --- /dev/null +++ b/doc/libpmemobj++.Doxyfile.in @@ -0,0 +1,225 @@ +#--------------------------------------------------------------------------- +# Project related configuration options +#--------------------------------------------------------------------------- + +# This tag specifies the encoding used for all characters in the config file +# that follow. The default is UTF-8 which is also the encoding used for all text +# before the first occurrence of this tag. Doxygen uses libiconv (or the iconv +# built into libc) for the transcoding. See http://www.gnu.org/software/libiconv +# for the list of possible encodings. +# The default value is: UTF-8. + +DOXYFILE_ENCODING = UTF-8 + +# The PROJECT_NAME tag is a single word (or a sequence of words surrounded by +# double-quotes, unless you are using Doxywizard) that should identify the +# project for which the documentation is generated. This name is used in the +# title of most generated pages and in a few other places. +# The default value is: My Project. + +PROJECT_NAME = "PMDK C++ bindings" + +# The PROJECT_NUMBER tag can be used to enter a project or revision number. This +# could be handy for archiving the generated documentation or if some version +# control system is used. + +PROJECT_NUMBER = "1.2.0" + +# Using the PROJECT_BRIEF tag one can provide an optional one line description +# for a project that appears at the top of each page and should give viewer a +# quick idea about the purpose of the project. Keep the description short. + +PROJECT_BRIEF = "This is the C++ bindings documentation for PMDK's libpmemobj." + +# With the PROJECT_LOGO tag one can specify an logo or icon that is included in +# the documentation. The maximum height of the logo should not exceed 55 pixels +# and the maximum width should not exceed 200 pixels. Doxygen will copy the logo +# to the output directory. + +PROJECT_LOGO = + +# If the JAVADOC_AUTOBRIEF tag is set to YES then doxygen will interpret the +# first line (until the first dot) of a Javadoc-style comment as the brief +# description. If set to NO, the Javadoc-style will behave just like regular Qt- +# style comments (thus requiring an explicit @brief command for a brief +# description.) +# The default value is: NO. + +JAVADOC_AUTOBRIEF = YES + +# If the EXTRACT_PRIVATE tag is set to YES all private members of a class will +# be included in the documentation. +# The default value is: NO. + +EXTRACT_PRIVATE = YES + +# If the HIDE_UNDOC_MEMBERS tag is set to YES, doxygen will hide all +# undocumented members inside documented classes or files. If set to NO these +# members will be included in the various overviews, but no documentation +# section is generated. This option has no effect if EXTRACT_ALL is enabled. +# The default value is: NO. + +HIDE_UNDOC_MEMBERS = YES + +# If the HIDE_UNDOC_CLASSES tag is set to YES, doxygen will hide all +# undocumented classes that are normally visible in the class hierarchy. If set +# to NO these classes will be included in the various overviews. This option has +# no effect if EXTRACT_ALL is enabled. +# The default value is: NO. + +HIDE_UNDOC_CLASSES = YES + +# The QUIET tag can be used to turn on/off the messages that are generated to +# standard output by doxygen. If QUIET is set to YES this implies that the +# messages are off. + +QUIET = YES + +#--------------------------------------------------------------------------- +# Configuration options related to the input files +#--------------------------------------------------------------------------- + +# The INPUT tag is used to specify the files and/or directories that contain +# documented source files. You may enter file names like myfile.cpp or +# directories like /usr/src/myproject. Separate the files or directories with +# spaces. +# Note: If this tag is empty the current directory is searched. + +INPUT = @CMAKE_SOURCE_DIR@/include/libpmemobj++ +INPUT += @CMAKE_SOURCE_DIR@/include/libpmemobj++/README.md + +# This tag can be used to specify the character encoding of the source files +# that doxygen parses. Internally doxygen uses the UTF-8 encoding. Doxygen uses +# libiconv (or the iconv built into libc) for the transcoding. See the libiconv +# documentation (see: http://www.gnu.org/software/libiconv) for the list of +# possible encodings. +# The default value is: UTF-8. + +INPUT_ENCODING = UTF-8 + +# If the value of the INPUT tag contains directories, you can use the +# FILE_PATTERNS tag to specify one or more wildcard patterns (like *.cpp and +# *.h) to filter out the source-files in the directories. If left blank the +# following patterns are tested:*.c, *.cc, *.cxx, *.cpp, *.c++, *.java, *.ii, +# *.ixx, *.ipp, *.i++, *.inl, *.idl, *.ddl, *.odl, *.h, *.hh, *.hxx, *.hpp, +# *.h++, *.cs, *.d, *.php, *.php4, *.php5, *.phtml, *.inc, *.m, *.markdown, +# *.md, *.mm, *.dox, *.py, *.f90, *.f, *.for, *.tcl, *.vhd, *.vhdl, *.ucf, +# *.qsf, *.as and *.js. + +FILE_PATTERNS = *.hpp + +# The RECURSIVE tag can be used to specify whether or not subdirectories should +# be searched for input files as well. +# The default value is: NO. + +RECURSIVE = YES + +# The EXCLUDE tag can be used to specify files and/or directories that should be +# excluded from the INPUT source files. This way you can easily exclude a +# subdirectory from a directory tree whose root is specified with the INPUT tag. +# +# Note that relative paths are relative to the directory from which doxygen is +# run. + +EXCLUDE = + +# The EXAMPLE_PATH tag can be used to specify one or more files or directories +# that contain example code fragments that are included (see the \include +# command). + +EXAMPLE_PATH = @CMAKE_SOURCE_DIR@/examples/doc_snippets + +# If the value of the EXAMPLE_PATH tag contains directories, you can use the +# EXAMPLE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp and +# *.h) to filter out the source-files in the directories. If left blank all +# files are included. + +EXAMPLE_PATTERNS = + +# If the EXAMPLE_RECURSIVE tag is set to YES then subdirectories will be +# searched for input files to be used with the \include or \dontinclude commands +# irrespective of the value of the RECURSIVE tag. +# The default value is: NO. + +EXAMPLE_RECURSIVE = NO + +# The IMAGE_PATH tag can be used to specify one or more files or directories +# that contain images that are to be included in the documentation (see the +# \image command). + +IMAGE_PATH = + +# The STRIP_FROM_PATH tag can be used to strip a user-defined part of the path. +# Stripping is only done if one of the specified strings matches the left-hand +# part of the path. The tag can be used to show relative paths in the file list. +# If left blank the directory from which doxygen is run is used as the path to strip. +# Note that you can specify absolute paths here, but also relative paths, which will +# be relative from the directory where doxygen is started. +# This tag requires that the tag FULL_PATH_NAMES is set to YES. + +FULL_PATH_NAMES = YES +STRIP_FROM_PATH = @CMAKE_SOURCE_DIR@/include/ + +# The STRIP_FROM_INC_PATH tag can be used to strip a user-defined part of the +# path mentioned in the documentation of a class, which tells the reader which +# header file to include in order to use a class. If left blank only the name +# of the header file containing the class definition is used. Otherwise one +# should specify the list of include paths that are normally passed to the +# compiler using the -I flag. + +STRIP_FROM_INC_PATH = @CMAKE_SOURCE_DIR@/include/ + +#--------------------------------------------------------------------------- +# Configuration options related to the LATEX output +#--------------------------------------------------------------------------- + +# If the GENERATE_LATEX tag is set to YES doxygen will generate LATEX output +# The default value is: YES. + +GENERATE_LATEX = NO + +#--------------------------------------------------------------------------- +# Configuration options related to the HTML output +#--------------------------------------------------------------------------- + +# If the GENERATE_HTML tag is set to YES doxygen will generate HTML output +# The default value is: YES. + +GENERATE_HTML = YES + +# The HTML_OUTPUT tag is used to specify where the HTML docs will be put. If a +# relative path is entered the value of OUTPUT_DIRECTORY will be put in front of +# it. +# The default directory is: html. +# This tag requires that the tag GENERATE_HTML is set to YES. + +HTML_OUTPUT = cpp_html + +# The HTML_FILE_EXTENSION tag can be used to specify the file extension for each +# generated HTML page (for example: .htm, .php, .asp). +# The default value is: .html. +# This tag requires that the tag GENERATE_HTML is set to YES. + +HTML_FILE_EXTENSION = .html + +# If the HTML_TIMESTAMP tag is set to YES then the footer of each generated HTML +# page will contain the date and time when the page was generated. Setting this +# to NO can help when comparing the output of multiple runs. +# The default value is: YES. +# This tag requires that the tag GENERATE_HTML is set to YES. + +HTML_TIMESTAMP = NO + +#--------------------------------------------------------------------------- +# Configuration options related to the preprocessor +#--------------------------------------------------------------------------- + +# The PREDEFINED tag can be used to specify one or more macro names that are +# defined before the preprocessor is started (similar to the -D option of e.g. +# gcc). The argument of the tag is a list of macros of the form: name or +# name=definition (no spaces). If the definition and the "=" are omitted, "=1" +# is assumed. To prevent a macro definition from being undefined via #undef or +# recursively expanded use the := operator instead of the = operator. +# This tag requires that the tag ENABLE_PREPROCESSING is set to YES. + +PREDEFINED = __cpp_lib_uncaught_exceptions _WIN32 diff --git a/examples/CMakeLists.txt b/examples/CMakeLists.txt new file mode 100644 index 0000000..f3f9d6c --- /dev/null +++ b/examples/CMakeLists.txt @@ -0,0 +1,167 @@ +# +# Copyright 2018, Intel Corporation +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# +# * Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# +# * Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in +# the documentation and/or other materials provided with the +# distribution. +# +# * Neither the name of the copyright holder nor the names of its +# contributors may be used to endorse or promote products derived +# from this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +if(MSVC_VERSION) + add_flag(-W4) +else() + add_flag(-Wall) +endif() +add_flag(-Wpointer-arith) +add_flag(-Wsign-compare) +add_flag(-Wunreachable-code-return) +add_flag(-Wmissing-variable-declarations) +add_flag(-fno-common) +#add_flag(-Wunused-macros) +#add_flag(-Wsign-conversion) + +add_flag(-ggdb DEBUG) +add_flag(-DDEBUG DEBUG) + +add_flag("-U_FORTIFY_SOURCE -D_FORTIFY_SOURCE=2" RELEASE) + +if(USE_ASAN) + add_sanitizer_flag(address) +endif() +if(USE_UBSAN) + add_sanitizer_flag(undefined) +endif() + +if(COVERAGE) + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -coverage") +endif() + +include_directories(${LIBPMEMOBJ_INCLUDE_DIRS} .) +link_directories(${LIBPMEMOBJ_LIBRARY_DIRS}) + +add_cppstyle(examples-common ${CMAKE_CURRENT_SOURCE_DIR}/*.hpp) +add_check_whitespace(examples-common ${CMAKE_CURRENT_SOURCE_DIR}/*.hpp) +add_check_whitespace(examples-cmake ${CMAKE_CURRENT_SOURCE_DIR}/CMakeLists.txt) + +add_cppstyle(examples-array ${CMAKE_CURRENT_SOURCE_DIR}/array/*.*pp) +add_check_whitespace(examples-array ${CMAKE_CURRENT_SOURCE_DIR}/array/*.*pp) + +add_cppstyle(examples-doc_snippets ${CMAKE_CURRENT_SOURCE_DIR}/doc_snippets/*.*pp) +add_check_whitespace(examples-doc_snippets ${CMAKE_CURRENT_SOURCE_DIR}/doc_snippets/*.*pp) + +add_cppstyle(examples-map_cli ${CMAKE_CURRENT_SOURCE_DIR}/map_cli/*.*pp) +add_check_whitespace(examples-map_cli ${CMAKE_CURRENT_SOURCE_DIR}/map_cli/*.*pp) + +add_cppstyle(examples-panaconda ${CMAKE_CURRENT_SOURCE_DIR}/panaconda/*.*pp) +add_check_whitespace(examples-panaconda ${CMAKE_CURRENT_SOURCE_DIR}/panaconda/*.*pp) + +add_cppstyle(examples-pman ${CMAKE_CURRENT_SOURCE_DIR}/pman/*.*pp) +add_check_whitespace(examples-pman ${CMAKE_CURRENT_SOURCE_DIR}/pman/*.*pp) + +add_cppstyle(examples-pmpong ${CMAKE_CURRENT_SOURCE_DIR}/pmpong/*.*pp) +add_check_whitespace(examples-pmpong ${CMAKE_CURRENT_SOURCE_DIR}/pmpong/*.*pp) + +add_cppstyle(examples-queue ${CMAKE_CURRENT_SOURCE_DIR}/queue/*.*pp) +add_check_whitespace(examples-queue ${CMAKE_CURRENT_SOURCE_DIR}/queue/*.*pp) + +function(add_example name) + set(srcs ${ARGN}) + prepend(srcs ${CMAKE_CURRENT_SOURCE_DIR} ${srcs}) + add_executable(example-${name} ${srcs}) +endfunction() + +if(PKG_CONFIG_FOUND) + pkg_check_modules(CURSES QUIET ncurses) +else() + # Specifies that we want FindCurses to find ncurses and not just any + # curses library + set(CURSES_NEED_NCURSES TRUE) + find_package(Curses QUIET) +endif() + +if(PKG_CONFIG_FOUND) + pkg_check_modules(SFML QUIET sfml-all>=2.4) +else() + # SFML 2.5 has different cmake interface than <= 2.4 so previous versions are not supported + find_package(SFML 2.5 QUIET COMPONENTS graphics window system) + set(SFML_LIBRARIES sfml-graphics sfml-window sfml-system) +endif() + +add_example(queue queue/queue.cpp) +target_link_libraries(example-queue ${LIBPMEMOBJ_LIBRARIES} ${CMAKE_THREAD_LIBS_INIT}) + +if(CURSES_FOUND) + add_example(pman pman/pman.cpp) + target_include_directories(example-pman PUBLIC ${CURSES_INCLUDE_DIR}) + target_link_libraries(example-pman ${LIBPMEMOBJ_LIBRARIES} ${CMAKE_THREAD_LIBS_INIT} ${CURSES_LIBRARIES}) +else() + message(WARNING "ncurses not found - pman won't be build") +endif() + +if(SFML_FOUND) + # XXX: this can only be run in Release mode - in Debug SFML doesn't add all dependencies automatically + add_example(pmpong pmpong/Ball.cpp pmpong/GameController.cpp pmpong/GameOverView.cpp + pmpong/GameView.cpp pmpong/MainGame.cpp pmpong/MenuView.cpp pmpong/Paddle.cpp + pmpong/PongGameStatus.cpp pmpong/Pool.cpp) + target_include_directories(example-pmpong PUBLIC ${SFML_INCLUDE_DIR}) + target_link_libraries(example-pmpong ${LIBPMEMOBJ_LIBRARIES} ${CMAKE_THREAD_LIBS_INIT} ${SFML_LIBRARIES}) + + if(NOT WIN32) + execute_process(COMMAND uname -s OUTPUT_VARIABLE SYSTEM_TYPE) + if(SYSTEM_TYPE STREQUAL "FreeBSD") + set(FONTDIR "/usr/local/share/fonts") + else() + set(FONTDIR "/usr/share/fonts") + endif() + file(GLOB_RECURSE fonts ${FONTDIR}/*.ttf) + list(GET fonts 0 font) + file(WRITE ${CMAKE_CURRENT_BINARY_DIR}/fontConf ${font}) + endif() +else() + message(WARNING "SFML 2.4 or newer not found - pmpong won't be build") +endif() + +if(CURSES_FOUND) + add_example(panaconda panaconda/panaconda.cpp) + target_include_directories(example-panaconda PUBLIC ${CURSES_INCLUDE_DIR}) + target_link_libraries(example-panaconda ${LIBPMEMOBJ_LIBRARIES} ${CMAKE_THREAD_LIBS_INIT} ${CURSES_LIBRARIES}) +else() + message(WARNING "ncurses not found - panaconda won't be build") +endif() + +add_example(map_cli map_cli/map_cli.cpp) +target_link_libraries(example-map_cli ${LIBPMEMOBJ_LIBRARIES} ${CMAKE_THREAD_LIBS_INIT}) + +add_example(array array/array.cpp) +target_link_libraries(example-array ${LIBPMEMOBJ_LIBRARIES} ${CMAKE_THREAD_LIBS_INIT}) + +if(PMEMVLT_PRESENT) + add_library(doc_snippets_v OBJECT doc_snippets/v.cpp) +endif() +add_library(doc_snippets_persistent OBJECT doc_snippets/persistent.cpp) +add_library(doc_snippets_make_persistent OBJECT doc_snippets/make_persistent.cpp) +add_library(doc_snippets_mutex OBJECT doc_snippets/mutex.cpp) +add_library(doc_snippets_pool OBJECT doc_snippets/pool.cpp) +add_library(doc_snippets_transaction OBJECT doc_snippets/transaction.cpp) diff --git a/examples/README b/examples/README new file mode 100644 index 0000000..f616436 --- /dev/null +++ b/examples/README @@ -0,0 +1,7 @@ +This directory contains examples for libpmemobj-cpp, the library providing +a transactional object store for pmem. Some of these examples are explained +in more detail here: http://pmem.io/pmdk/cpp_obj/ + +If you're looking for documentation to get you started using PMDK, +start here: http://pmem.io/pmdk and follow the links to examples and +man pages. diff --git a/examples/array/CMakeLists.txt b/examples/array/CMakeLists.txt new file mode 100644 index 0000000..e1a4df2 --- /dev/null +++ b/examples/array/CMakeLists.txt @@ -0,0 +1,52 @@ +# +# Copyright 2018, Intel Corporation +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# +# * Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# +# * Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in +# the documentation and/or other materials provided with the +# distribution. +# +# * Neither the name of the copyright holder nor the names of its +# contributors may be used to endorse or promote products derived +# from this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +cmake_minimum_required(VERSION 3.3) +project(array CXX) + +set(CXX_STANDARD_REQUIRED ON) +set(CMAKE_CXX_STANDARD 11) + +include(FindThreads) + +find_package(PkgConfig QUIET) +if(PKG_CONFIG_FOUND) + pkg_check_modules(LIBPMEMOBJ++ REQUIRED libpmemobj++) +else() + find_package(LIBPMEMOBJ++ REQUIRED) +endif() + +link_directories(${LIBPMEMOBJ++_LIBRARY_DIRS}) + +add_executable(array array.cpp) +target_include_directories(array PUBLIC ${LIBPMEMOBJ++_INCLUDE_DIRS} . ..) +target_link_libraries(array ${LIBPMEMOBJ++_LIBRARIES} ${CMAKE_THREAD_LIBS_INIT}) + diff --git a/examples/array/README.md b/examples/array/README.md new file mode 100644 index 0000000..f4a66d5 --- /dev/null +++ b/examples/array/README.md @@ -0,0 +1,47 @@ +## Basic usage: + +After [building](https://github.com/pmem/libpmemobj-cpp#how-to-build) the source, navigate to the `/build/examples/` directory. Operations include: `alloc`, `realloc`, `free`, and `print`. + + `$ ./example-array [print|alloc|free|realloc] ` + +## Options: + +### Alloc: + +`$ ./example-array alloc ` + +Example: +``` +$ ./example-array file alloc myArray 4 +$ ./example-array file print myArray + myArray = [0, 1, 2, 3] +``` + +### Realloc: + +`$ ./example-array realloc ` + +Example: +``` +$ ./example-array file realloc myArray 7 +$ ./example-array file print myArray + myArray = [0, 1, 2, 3, 0, 0, 0] +``` + +### Free: + +`$ ./example-array free ` + +Example: +``` +$ ./example-array file free myArray +$ ./example-array file print myArray + No array found with name: myArray +``` + +### Print: + +`$ ./example-array print ` + +Example output can be seen in above example sections. + diff --git a/examples/array/array.cpp b/examples/array/array.cpp new file mode 100644 index 0000000..c552a3e --- /dev/null +++ b/examples/array/array.cpp @@ -0,0 +1,367 @@ +/* + * Copyright 2018, Intel Corporation + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * * Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +/* + * array.cpp -- array example implemented using libpmemobj C++ bindings + */ + +#include "libpmemobj_cpp_examples_common.hpp" +#include +#include +#include +#include +#include +#include +#include +#include + +using namespace pmem; +using namespace pmem::obj; + +namespace +{ +// array_op: available array operations +enum class array_op { + UNKNOWN, + PRINT, + FREE, + REALLOC, + ALLOC, + + MAX_ARRAY_OP +}; + +const int POOLSIZE = 1024 * 1024 * 64; +const int MAX_BUFFLEN = 30; +const std::string LAYOUT = ""; +std::string prog_name; + +// parse_array_op: parses the operation string and returns the matching array_op +array_op +parse_array_op(const char *str) +{ + if (strcmp(str, "print") == 0) + return array_op::PRINT; + else if (strcmp(str, "free") == 0) + return array_op::FREE; + else if (strcmp(str, "realloc") == 0) + return array_op::REALLOC; + else if (strcmp(str, "alloc") == 0) + return array_op::ALLOC; + else + return array_op::UNKNOWN; +} +} + +namespace examples +{ + +class pmem_array { + // array_list: struct to hold name, size, array and pointer to next + struct array_list { + char name[MAX_BUFFLEN]; + p size; + persistent_ptr array; + persistent_ptr next; + }; + + persistent_ptr head = nullptr; + +public: + // add_array: allocate space on heap for new array and add it to head + void + add_array(pool_base &pop, const char *name, int size) + { + if (find_array(name) != nullptr) { + std::cout << "Array with name: " << name + << " already exists. "; + std::cout + << "If you prefer, you can reallocate this array " + << std::endl; + print_usage(array_op::REALLOC, "./example-array"); + } else if (size < 1) { + std::cout << "size must be a non-negative integer" + << std::endl; + print_usage(array_op::ALLOC, "./example-array"); + } else { + transaction::run(pop, [&] { + auto new_array = make_persistent(); + + strcpy(new_array->name, name); + + new_array->size = (size_t)size; + new_array->array = make_persistent(size); + new_array->next = nullptr; + + // assign values to newArray->array + for (size_t i = 0; i < new_array->size; i++) + new_array->array[i] = i; + + new_array->next = head; + head = new_array; + }); + } + } + + // delete_array: deletes array from the array_list and removes + // previously allocated space on heap + void + delete_array(pool_base &pop, const char *name) + { + // prevArr will equal head if array wanted is either first OR + // second element + persistent_ptr prev_arr = find_array(name, true); + + // if array_list length = 0 OR array not found in list + if (prev_arr == nullptr) { + std::cout << "No array found with name: " << name + << std::endl; + return; + } + + persistent_ptr cur_arr; + if (strcmp(prev_arr->name, name) == 0) { + // cur = prev= head, either only one element in list or + // array is first element + cur_arr = head; + } else { + cur_arr = prev_arr->next; + } + + transaction::run(pop, [&] { + if (head == cur_arr) + head = cur_arr->next; + else + prev_arr->next = cur_arr->next; + + delete_persistent(cur_arr->array, cur_arr->size); + delete_persistent(cur_arr); + }); + } + + // print_array: prints array_list contents to cout + void + print_array(const char *name) + { + persistent_ptr arr = find_array(name); + if (arr == nullptr) { + std::cout << "No array found with name: " << name + << std::endl; + } else { + std::cout << arr->name << " = ["; + + for (size_t i = 0; i < arr->size - 1; i++) + std::cout << arr->array[i] << ", "; + + std::cout << arr->array[arr->size - 1] << "]" + << std::endl; + } + } + + // resize: reallocate space on heap to change the size of the array + void + resize(pool_base &pop, const char *name, int size) + { + persistent_ptr arr = find_array(name); + if (arr == nullptr) { + std::cout << "No array found with name: " << name + << std::endl; + } else if (size < 1) { + std::cout << "size must be a non-negative integer" + << std::endl; + print_usage(array_op::REALLOC, prog_name); + } else { + transaction::run(pop, [&] { + persistent_ptr new_array = + make_persistent(size); + + size_t copy_size = arr->size; + + if ((size_t)size < arr->size) + copy_size = (size_t)size; + + for (size_t i = 0; i < copy_size; i++) + new_array[i] = arr->array[i]; + + delete_persistent(arr->array, arr->size); + + arr->size = (size_t)size; + arr->array = new_array; + }); + } + } + + // print_usage: prints usage for each type of array operation + void + print_usage(array_op op, std::string arg_zero) + { + switch (op) { + case array_op::PRINT: + std::cerr << "print array usage: " << arg_zero + << " print " + << std::endl; + break; + case array_op::FREE: + std::cerr << "free array usage: " << arg_zero + << " free " + << std::endl; + break; + case array_op::REALLOC: + std::cerr + << "realloc array usage: " << arg_zero + << " realloc " + << std::endl; + break; + case array_op::ALLOC: + std::cerr + << "alloc array usage: " << arg_zero + << " alloc " + << std::endl; + break; + default: + std::cerr + << "usage: " << arg_zero + << " " + << std::endl; + } + } + +private: + // find_array: loops through head to find array with specified name + persistent_ptr + find_array(const char *name, bool find_prev = false) + { + if (head == nullptr) + return head; + + persistent_ptr cur = head; + persistent_ptr prev = head; + + while (cur) { + if (strcmp(cur->name, name) == 0) { + if (find_prev) + return prev; + else + return cur; + } + + prev = cur; + cur = cur->next; + } + + return nullptr; + } +}; +} + +int +main(int argc, char *argv[]) +{ + /* + * Inputs should be one of: + * ./example-array print + * ./example-array free + * ./example-array realloc + * ./example-array alloc + * // currently only enabled for arrays of int + */ + + prog_name = argv[0]; + if (argc < 4) { + std::cerr + << "usage: " << prog_name + << " " + << std::endl; + + return 1; + } + + // check length of array name to ensure doesn't exceed buffer. + const char *name = argv[3]; + if (strlen(name) > MAX_BUFFLEN) { + std::cout + << "Name exceeds buffer length of 30 characters. Please shorten and try again." + << std::endl; + + return 1; + } + + const char *file = argv[1]; + pool pop; + + if (file_exists(file) != 0) + pop = pool::create(file, LAYOUT, POOLSIZE, + CREATE_MODE_RW); + else + pop = pool::open(file, LAYOUT); + + persistent_ptr arr = pop.root(); + + array_op op = parse_array_op(argv[2]); + + switch (op) { + case array_op::PRINT: + if (argc == 4) + arr->print_array(name); + else + arr->print_usage(op, prog_name); + break; + case array_op::FREE: + if (argc == 4) + arr->delete_array(pop, name); + else + arr->print_usage(op, prog_name); + break; + case array_op::REALLOC: + if (argc == 5) + arr->resize(pop, name, atoi(argv[4])); + else + arr->print_usage(op, prog_name); + break; + case array_op::ALLOC: + if (argc == 5) + arr->add_array(pop, name, atoi(argv[4])); + else + arr->print_usage(op, prog_name); + break; + default: + std::cout << "Ruh roh! You passed an invalid operation!" + << std::endl; + + arr->print_usage(op, prog_name); + break; + } + + pop.close(); + + return 0; +} diff --git a/examples/doc_snippets/make_persistent.cpp b/examples/doc_snippets/make_persistent.cpp new file mode 100644 index 0000000..ec1083a --- /dev/null +++ b/examples/doc_snippets/make_persistent.cpp @@ -0,0 +1,266 @@ +/* + * Copyright 2016-2018, Intel Corporation + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * * Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +/* + * make_persistent.cpp -- C++ documentation snippets. + */ + +//! [make_example] +#include +#include +#include +#include +#include +#include + +using namespace pmem::obj; + +void +make_persistent_example() +{ + + struct compound_type { + + compound_type(int val, double dval) + : some_variable(val), some_other_variable(dval) + { + } + + void + set_some_variable(int val) + { + some_variable = val; + } + + p some_variable; + p some_other_variable; + }; + + // pool root structure + struct root { + persistent_ptr comp; // + }; + + // create a pmemobj pool + auto pop = pool::create("poolfile", "layout", PMEMOBJ_MIN_POOL); + auto proot = pop.root(); + + // typical usage schemes + transaction::run(pop, [&] { + // allocation with constructor argument passing + proot->comp = make_persistent(1, 2.0); + + // transactionally delete the object, ~compound_type() is called + delete_persistent(proot->comp); + }); + + // throws an transaction_scope_error exception + auto arr1 = make_persistent(2, 15.0); + delete_persistent(arr1); +} +//! [make_example] + +//! [make_array_example] +#include +#include +#include +#include +#include +#include + +using namespace pmem::obj; + +void +make_persistent_array_example() +{ + + struct compound_type { + + compound_type() : some_variable(0), some_other_variable(0) + { + } + + void + set_some_variable(int val) + { + some_variable = val; + } + + p some_variable; + p some_other_variable; + }; + + // pool root structure + struct root { + persistent_ptr comp; // + }; + + // create a pmemobj pool + auto pop = pool::create("poolfile", "layout", PMEMOBJ_MIN_POOL); + auto proot = pop.root(); + + // typical usage schemes + transaction::run(pop, [&] { + // allocate an array of 20 objects - compound_type must be + // default constructible + proot->comp = make_persistent(20); + // another allocation method + auto arr1 = make_persistent(); + + // transactionally delete arrays , ~compound_type() is called + delete_persistent(proot->comp, 20); + delete_persistent(arr1); + }); + + // throws an transaction_scope_error exception + auto arr1 = make_persistent(); + delete_persistent(arr1); +} +//! [make_array_example] + +//! [make_atomic_example] +#include +#include +#include +#include +#include +#include + +using namespace pmem::obj; + +void +make_persistent_atomic_example() +{ + + struct compound_type { + + compound_type(int val, double dval) + : some_variable(val), some_other_variable(dval) + { + } + + void + set_some_variable(int val) + { + some_variable = val; + } + + p some_variable; + p some_other_variable; + }; + + // pool root structure + struct root { + persistent_ptr comp; // + }; + + // create a pmemobj pool + auto pop = pool::create("poolfile", "layout", PMEMOBJ_MIN_POOL); + auto proot = pop.root(); + + // typical usage schemes + + // atomic allocation and construction with arguments passing + make_persistent_atomic(pop, proot->comp, 1, 2.0); + + // atomic object deallocation, ~compound_type() is not called + delete_persistent(proot->comp); + + // error prone cases + transaction::run(pop, [&] { + // possible invalid state in case of transaction abort + make_persistent_atomic(pop, proot->comp, 1, 1.3); + delete_persistent_atomic(proot->comp); + }); +} +//! [make_atomic_example] + +//! [make_array_atomic_example] +#include +#include +#include +#include +#include +#include + +using namespace pmem::obj; + +void +make_persistent_array_atomic_example() +{ + + struct compound_type { + + compound_type() : some_variable(0), some_other_variable(0) + { + } + + void + set_some_variable(int val) + { + some_variable = val; + } + + p some_variable; + p some_other_variable; + }; + + // pool root structure + struct root { + persistent_ptr comp; // + }; + + // create a pmemobj pool + auto pop = pool::create("poolfile", "layout", PMEMOBJ_MIN_POOL); + auto proot = pop.root(); + + // typical usage schemes + + // atomic array allocation and construction - the compound_type has to + // be default constructible + make_persistent_atomic(pop, proot->comp, 20); + + persistent_ptr arr; + make_persistent_atomic(pop, arr); + + // atomic array deallocation, no destructor being called + delete_persistent_atomic(proot->comp, 20); + delete_persistent_atomic(arr); + + // error prone cases + transaction::run(pop, [&] { + // possible invalid state in case of transaction abort + make_persistent_atomic(pop, proot->comp, 30); + delete_persistent_atomic(proot->comp, 30); + }); +} +//! [make_array_atomic_example] diff --git a/examples/doc_snippets/mutex.cpp b/examples/doc_snippets/mutex.cpp new file mode 100644 index 0000000..4374922 --- /dev/null +++ b/examples/doc_snippets/mutex.cpp @@ -0,0 +1,167 @@ +/* + * Copyright 2016-2018, Intel Corporation + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * * Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +/* + * mutex.cpp -- C++ documentation snippets. + */ + +//! [unique_guard_example] +#include +#include +#include +#include + +namespace nvobj = pmem::obj; + +void +unique_guard_example() +{ + // pool root structure + struct root { + nvobj::mutex pmutex; + }; + + // create a pmemobj pool + auto pop = nvobj::pool::create("poolfile", "layout", + PMEMOBJ_MIN_POOL); + auto proot = pop.root(); + + // typical usage schemes + std::lock_guard guard(proot->pmutex); + + std::unique_lock other_guard(proot->pmutex); +} +//! [unique_guard_example] + +//! [shared_mutex_example] +#include +#include +#include +#include + +namespace nvobj = pmem::obj; + +void +shared_mutex_example() +{ + // pool root structure + struct root { + nvobj::shared_mutex pmutex; + }; + + // create a pmemobj pool + auto pop = nvobj::pool::create("poolfile", "layout", + PMEMOBJ_MIN_POOL); + auto proot = pop.root(); + + // typical usage schemes + proot->pmutex.lock_shared(); + + std::unique_lock guard(proot->pmutex); +} +//! [shared_mutex_example] + +//! [timed_mutex_example] +#include +#include +#include +#include + +namespace nvobj = pmem::obj; + +void +timed_mutex_example() +{ + // pool root structure + struct root { + nvobj::timed_mutex pmutex; + }; + + // create a pmemobj pool + auto pop = nvobj::pool::create("poolfile", "layout", + PMEMOBJ_MIN_POOL); + auto proot = pop.root(); + + const auto timeout = std::chrono::milliseconds(100); + + // typical usage schemes + proot->pmutex.try_lock_for(timeout); + + proot->pmutex.try_lock_until(std::chrono::steady_clock::now() + + timeout); +} +//! [timed_mutex_example] + +//! [cond_var_example] +#include +#include +#include +#include +#include +#include + +namespace nvobj = pmem::obj; + +void +cond_var_example() +{ + // pool root structure + struct root { + nvobj::mutex pmutex; + nvobj::condition_variable cond; + int counter; + }; + + // create a pmemobj pool + auto pop = nvobj::pool::create("poolfile", "layout", + PMEMOBJ_MIN_POOL); + + auto proot = pop.root(); + + // run worker to bump up the counter + std::thread worker([&] { + std::unique_lock lock(proot->pmutex); + while (proot->counter < 1000) + ++proot->counter; + // unlock before notifying to avoid blocking on waiting thread + lock.unlock(); + // notify the waiting thread + proot->cond.notify_one(); + }); + + std::unique_lock lock(proot->pmutex); + // wait on condition variable + proot->cond.wait(lock, [&] { return proot->counter >= 1000; }); + + worker.join(); +} +//! [cond_var_example] diff --git a/examples/doc_snippets/persistent.cpp b/examples/doc_snippets/persistent.cpp new file mode 100644 index 0000000..18eccc0 --- /dev/null +++ b/examples/doc_snippets/persistent.cpp @@ -0,0 +1,133 @@ +/* + * Copyright 2016-2018, Intel Corporation + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * * Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +/* + * persistent.cpp -- C++ documentation snippets. + */ + +//! [p_property_example] +#include +#include +#include +#include + +using namespace pmem::obj; + +void +p_property_example() +{ + + struct compound_type { + + void + set_some_variable(int val) + { + some_variable = val; + } + + int some_variable; + double some_other_variable; + }; + + // pool root structure + static struct root { + p counter; // this is OK + p whoops; // this is hard to use + } proot; + + // create a pmemobj pool + auto pop = pool::create("poolfile", "layout", PMEMOBJ_MIN_POOL); + + // typical usage schemes + transaction::run(pop, [&] { + proot.counter = 12; // atomic + // one way to change `whoops` + proot.whoops.get_rw().set_some_variable(2); + proot.whoops.get_rw().some_other_variable = 3.0; + }); + + // Changing a p<> variable outside of a transaction is a volatile + // modification. No way to ensure persistence in case of power failure. + proot.counter = 12; +} +//! [p_property_example] + +//! [persistent_ptr_example] +#include +#include +#include +#include +#include + +using namespace pmem::obj; + +void +persistent_ptr_example() +{ + + struct compound_type { + + void + set_some_variable(int val) + { + some_variable = val; + } + + int some_variable; + double some_other_variable; + }; + + // pool root structure + struct root { + persistent_ptr comp; + } proot; + + // create a pmemobj pool + auto pop = pool::create("poolfile", "layout", PMEMOBJ_MIN_POOL); + + // typical usage schemes + transaction::run(pop, [&] { + proot.comp = make_persistent(); // allocation + proot.comp->set_some_variable(12); // call function + proot.comp->some_other_variable = 2.3; // set variable + }); + + // reading from the persistent_ptr + compound_type tmp = *proot.comp; + (void)tmp; + + // Changing a persistent_ptr<> variable outside of a transaction is a + // volatile modification. No way to ensure persistence in case of power + // failure. + proot.comp->some_variable = 12; +} +//! [persistent_ptr_example] diff --git a/examples/doc_snippets/pool.cpp b/examples/doc_snippets/pool.cpp new file mode 100644 index 0000000..b076af4 --- /dev/null +++ b/examples/doc_snippets/pool.cpp @@ -0,0 +1,130 @@ +/* + * Copyright 2016-2018, Intel Corporation + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * * Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +/* + * pool.cpp -- C++ documentation snippets. + */ + +//! [pool_example] +#include +#include +#include +#include + +using namespace pmem::obj; + +void +pool_example() +{ + + // pool root structure + struct root { + p some_array[42]; + p some_other_array[42]; + p some_variable; + }; + + // create a pmemobj pool + auto pop = pool::create("poolfile", "layout", PMEMOBJ_MIN_POOL); + + // close a pmemobj pool + pop.close(); + + // or open a pmemobj pool + pop = pool::open("poolfile", "layout"); + + // typical usage schemes + auto root_obj = pop.root(); + + // low-level memory manipulation + root_obj->some_variable = 3.2; + pop.persist(root_obj->some_variable); + + pop.memset_persist(root_obj->some_array, 2, + sizeof(root_obj->some_array)); + + pop.memcpy_persist(root_obj->some_other_array, root_obj->some_array, + sizeof(root_obj->some_array)); + + pop.close(); + + // check pool consistency + pool::check("poolfile", "layout"); +} +//! [pool_example] + +//! [pool_base_example] +#include +#include +#include +#include + +using namespace pmem::obj; + +void +pool_base_example() +{ + + struct some_struct { + p some_array[42]; + p some_other_array[42]; + p some_variable; + }; + + // create a pmemobj pool + auto pop = pool_base::create("poolfile", "", PMEMOBJ_MIN_POOL); + + // close a pmemobj pool + pop.close(); + + // or open a pmemobj pool + pop = pool_base::open("poolfile", ""); + + // no "root" object available in pool_base + persistent_ptr pval; + make_persistent_atomic(pop, pval); + + // low-level memory manipulation + pval->some_variable = 3; + pop.persist(pval->some_variable); + + pop.memset_persist(pval->some_array, 2, sizeof(pval->some_array)); + + pop.memcpy_persist(pval->some_other_array, pval->some_array, + sizeof(pval->some_array)); + + pop.close(); + + // check pool consistency + pool_base::check("poolfile", ""); +} +//! [pool_base_example] diff --git a/examples/doc_snippets/transaction.cpp b/examples/doc_snippets/transaction.cpp new file mode 100644 index 0000000..66e4233 --- /dev/null +++ b/examples/doc_snippets/transaction.cpp @@ -0,0 +1,208 @@ +/* + * Copyright 2016-2018, Intel Corporation + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * * Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +/* + * transaction.cpp -- C++ documentation snippets. + */ + +/* + * The following might be necessary to compile the examples on older compilers. + */ +#if !defined(__cpp_lib_uncaught_exceptions) && !defined(_MSC_VER) || \ + (_MSC_VER < 1900) + +#define __cpp_lib_uncaught_exceptions 201411 +namespace std +{ + +int +uncaught_exceptions() noexcept +{ + return 0; +} + +} /* namespace std */ +#endif /* __cpp_lib_uncaught_exceptions */ + +//! [general_tx_example] +#include +#include +#include +#include +#include +#include +#include + +using namespace pmem::obj; + +void +general_tx_example() +{ + // pool root structure + struct root { + mutex pmutex; + shared_mutex shared_pmutex; + p count; + persistent_ptr another_root; + }; + + // create a pmemobj pool + auto pop = pool::create("poolfile", "layout", PMEMOBJ_MIN_POOL); + auto proot = pop.root(); + + // typical usage schemes + try { + // take locks and start a transaction + transaction::run(pop, + [&]() { + // atomically allocate objects + proot->another_root = + make_persistent(); + + // atomically modify objects + proot->count++; + }, + proot->pmutex, proot->shared_pmutex); + } catch (pmem::transaction_error &) { + // a transaction error occurred, transaction got aborted + // reacquire locks if necessary + } catch (...) { + // some other exception got propagated from within the tx + // reacquire locks if necessary + } +} +//! [general_tx_example] + +//! [manual_tx_example] +#include +#include +#include +#include +#include +#include +#include + +using namespace pmem::obj; + +int +manual_tx_example() +{ + // pool root structure + struct root { + mutex pmutex; + shared_mutex shared_pmutex; + p count; + persistent_ptr another_root; + }; + + // create a pmemobj pool + auto pop = pool::create("poolfile", "layout", PMEMOBJ_MIN_POOL); + + auto proot = pop.root(); + + try { + transaction::manual tx(pop, proot->pmutex, + proot->shared_pmutex); + + // atomically allocate objects + proot->another_root = make_persistent(); + + // atomically modify objects + proot->count++; + + // It's necessary to commit the transaction manually and + // it has to be the last operation in the transaction. + transaction::commit(); + } catch (pmem::transaction_error &) { + // an internal transaction error occurred, tx aborted + // reacquire locks if necessary + } catch (...) { + // some other exception thrown, tx aborted + // reacquire locks if necessary + } + + // In complex cases with library calls, remember to check the status of + // the previous transaction. + return transaction::error(); +} +//! [manual_tx_example] + +//! [automatic_tx_example] +#include +#include +#include +#include +#include +#include +#include + +using namespace pmem::obj; + +int +automatic_tx_example() +{ + // pool root structure + struct root { + mutex pmutex; + shared_mutex shared_pmutex; + p count; + persistent_ptr another_root; + }; + + // create a pmemobj pool + auto pop = pool::create("poolfile", "layout", PMEMOBJ_MIN_POOL); + auto proot = pop.root(); + + try { + transaction::automatic tx(pop, proot->pmutex, + proot->shared_pmutex); + + // atomically allocate objects + proot->another_root = make_persistent(); + + // atomically modify objects + proot->count++; + + // manual transaction commit is no longer necessary + } catch (pmem::transaction_error &) { + // an internal transaction error occurred, tx aborted + // reacquire locks if necessary + } catch (...) { + // some other exception thrown, tx aborted + // reacquire locks if necessary + } + + // In complex cases with library calls, remember to check the status of + // the previous transaction. + return transaction::error(); +} +//! [automatic_tx_example] diff --git a/examples/doc_snippets/v.cpp b/examples/doc_snippets/v.cpp new file mode 100644 index 0000000..65326e4 --- /dev/null +++ b/examples/doc_snippets/v.cpp @@ -0,0 +1,71 @@ +/* + * Copyright 2018, Intel Corporation + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * * Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +/* + * v.cpp -- C++ documentation snippets. + */ + +//! [v_property_example] +#include +#include +#include +#include + +using namespace pmem::obj; +using namespace pmem::obj::experimental; + +void +v_property_example() +{ + struct foo { + foo() : counter(10) + { + } + int counter; + }; + + // pool root structure + struct root { + v f; + }; + + // create a pmemobj pool + auto pop = pool::create("poolfile", "layout", PMEMOBJ_MIN_POOL); + auto proot = pop.root(); + + assert(proot->f.get().counter == 10); + + proot->f.get().counter++; + + assert(proot->f.get().counter == 11); +} +//! [v_property_example] diff --git a/examples/libpmemobj_cpp_examples_common.hpp b/examples/libpmemobj_cpp_examples_common.hpp new file mode 100644 index 0000000..7d82d51 --- /dev/null +++ b/examples/libpmemobj_cpp_examples_common.hpp @@ -0,0 +1,95 @@ +/* + * Copyright 2018, Intel Corporation + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * * Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef LIBPMEMOBJ_CPP_EXAMPLES_COMMON_HPP +#define LIBPMEMOBJ_CPP_EXAMPLES_COMMON_HPP + +#include + +#ifndef _WIN32 + +#include + +#define CREATE_MODE_RW (S_IWUSR | S_IRUSR) + +/* + * file_exists -- checks if file exists + */ +static inline int +file_exists(char const *file) +{ + return access(file, F_OK); +} + +/* + * find_last_set_64 -- returns last set bit position or -1 if set bit not found + */ +static inline int +find_last_set_64(uint64_t val) +{ + return 64 - __builtin_clzll(val) - 1; +} + +#else + +#include +#include +#include + +#define CREATE_MODE_RW (S_IWRITE | S_IREAD) + +/* + * file_exists -- checks if file exists + */ +static inline int +file_exists(char const *file) +{ + return _access(file, 0); +} + +/* + * find_last_set_64 -- returns last set bit position or -1 if set bit not found + */ +static inline int +find_last_set_64(uint64_t val) +{ + DWORD lz = 0; + + if (BitScanReverse64(&lz, val)) + return (int)lz; + else + return -1; +} + +#endif + +#endif /* LIBPMEMOBJ_CPP_EXAMPLES_COMMON_HPP */ diff --git a/examples/libpmemobj_cpp_examples_list.hpp b/examples/libpmemobj_cpp_examples_list.hpp new file mode 100644 index 0000000..1204f08 --- /dev/null +++ b/examples/libpmemobj_cpp_examples_list.hpp @@ -0,0 +1,188 @@ +/* + * Copyright 2016-2018, Intel Corporation + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * * Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +/* + * list.hpp -- Implementation of list + */ + +#ifndef LIBPMEMOBJ_CPP_EXAMPLES_LIST_HPP +#define LIBPMEMOBJ_CPP_EXAMPLES_LIST_HPP + +#include +#include +#include +#include + +namespace examples +{ + +template +class list { + class list_entry { + public: + list_entry() = delete; + list_entry(pmem::obj::persistent_ptr previous, + pmem::obj::persistent_ptr value) + { + val = value; + next = nullptr; + prev = previous; + } + + pmem::obj::persistent_ptr prev; + pmem::obj::persistent_ptr next; + pmem::obj::persistent_ptr val; + }; + +public: + list() + { + head = nullptr; + tail = head; + len = 0; + } + + /** + * Push back the new element. + */ + void + push_back(pmem::obj::persistent_ptr val) + { + auto tmp = pmem::obj::make_persistent(tail, val); + if (head == nullptr) + head = tmp; + else + tail->next = tmp; + tail = tmp; + ++len; + } + + /** + * Pop the last element out from the list and return + * the pointer to it + */ + pmem::obj::persistent_ptr + pop_back() + { + assert(head != nullptr); + auto tmp = tail; + tail = tmp->prev; + if (tail == nullptr) + head = tail; + else + tail->next = nullptr; + return tmp->val; + } + + /** + * Return the pointer to the next element + */ + pmem::obj::persistent_ptr + erase(unsigned id) + { + return remove_elm(get_elm(id)); + } + + /* clear - clear the whole list */ + void + clear() + { + while (head != nullptr) { + auto e = head; + head = remove_elm(e); + } + } + + /** + * Get element with given id in list + */ + pmem::obj::persistent_ptr + get(unsigned id) + { + auto elm = get_elm(id); + if (elm == nullptr) + return nullptr; + return elm->val; + } + + /** + * Return number of elements in list + */ + unsigned + size() const + { + return len; + } + +private: + pmem::obj::persistent_ptr + get_elm(unsigned id) + { + if (id >= len) + return nullptr; + auto tmp = head; + for (unsigned i = 0; i < id; i++) + tmp = tmp->next; + return tmp; + } + + pmem::obj::persistent_ptr + remove_elm(pmem::obj::persistent_ptr elm) + { + assert(elm != nullptr); + auto tmp = elm->next; + pmem::obj::delete_persistent(elm->val); + + /* removing item is head */ + if (elm == head) + head = elm->next; + else + elm->prev->next = elm->next; + + /* removing item is tail */ + if (elm == tail) + tail = elm->prev; + else + elm->next->prev = elm->prev; + + --len; + pmem::obj::delete_persistent(elm); + return tmp; + } + + pmem::obj::p len; + pmem::obj::persistent_ptr head; + pmem::obj::persistent_ptr tail; +}; +}; + +#endif /* LIBPMEMOBJ_CPP_EXAMPLES_LIST_HPP */ diff --git a/examples/map_cli/CMakeLists.txt b/examples/map_cli/CMakeLists.txt new file mode 100644 index 0000000..9b4d93a --- /dev/null +++ b/examples/map_cli/CMakeLists.txt @@ -0,0 +1,51 @@ +# +# Copyright 2018, Intel Corporation +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# +# * Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# +# * Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in +# the documentation and/or other materials provided with the +# distribution. +# +# * Neither the name of the copyright holder nor the names of its +# contributors may be used to endorse or promote products derived +# from this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +cmake_minimum_required(VERSION 3.3) +project(map_cli CXX) + +set(CXX_STANDARD_REQUIRED ON) +set(CMAKE_CXX_STANDARD 11) + +include(FindThreads) + +find_package(PkgConfig QUIET) +if(PKG_CONFIG_FOUND) + pkg_check_modules(LIBPMEMOBJ++ REQUIRED libpmemobj++) +else() + find_package(LIBPMEMOBJ++ REQUIRED) +endif() + +link_directories(${LIBPMEMOBJ++_LIBRARY_DIRS}) + +add_executable(map_cli map_cli.cpp) +target_include_directories(map_cli PUBLIC ${LIBPMEMOBJ++_INCLUDE_DIRS} . ..) +target_link_libraries(map_cli ${LIBPMEMOBJ++_LIBRARIES} ${CMAKE_THREAD_LIBS_INIT}) diff --git a/examples/map_cli/ctree_map_persistent.hpp b/examples/map_cli/ctree_map_persistent.hpp new file mode 100644 index 0000000..9f554f7 --- /dev/null +++ b/examples/map_cli/ctree_map_persistent.hpp @@ -0,0 +1,451 @@ +/* + * Copyright 2016-2018, Intel Corporation + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * * Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef LIBPMEMOBJ_CPP_EXAMPLES_CTREE_MAP_PERSISTENT_HPP +#define LIBPMEMOBJ_CPP_EXAMPLES_CTREE_MAP_PERSISTENT_HPP + +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +#define BIT_IS_SET(n, i) (!!((n) & (1ULL << (i)))) + +namespace nvobj = pmem::obj; + +namespace examples +{ + +/** + * C++ implementation of a persistent ctree. + * + * Based on the volatile version. This version was implemented to show how much + * effort is needed to convert a volatile structure into a persistent one using + * C++ obj bindings. All API functions are atomic in respect to persistency. + */ +template +class ctree_map_p { +public: + /** Convenience typedef for the key type. */ + typedef K key_type; + + /** Convenience typedef for the value type. */ + typedef nvobj::persistent_ptr value_type; + + /** Convenience typedef for the callback function. */ + typedef std::function callback; + + /** + * Default constructor. + */ + ctree_map_p() + { + auto pop = nvobj::pool_by_vptr(this); + + nvobj::transaction::run(pop, [&] { + this->root = nvobj::make_persistent(); + }); + } + + ctree_map_p(const ctree_map_p &other) = delete; + + ctree_map_p &operator=(const ctree_map_p &other) = delete; + + /** + * Insert or update the given value under the given key. + * + * The map takes ownership of the value. + * + * @param key The key to insert under. + * @param value The value to be inserted. + * + * @return 0 on success, negative values on error. + */ + int + insert(key_type key, value_type value) + { + auto dest_entry = root; + while (dest_entry->inode != nullptr) { + auto n = dest_entry->inode; + dest_entry = n->entries[BIT_IS_SET(key, n->diff)]; + } + + entry e(key, value); + auto pop = nvobj::pool_by_vptr(this); + nvobj::transaction::run(pop, [&] { + if (dest_entry->key == 0 || dest_entry->key == key) { + nvobj::delete_persistent(dest_entry->value); + *dest_entry = e; + } else { + insert_leaf( + &e, + find_crit_bit(dest_entry->key, key)); + } + }); + + return 0; + } + + /** + * Allocating insert. + * + * Creates a new value_type instance and inserts it into the tree. + * + * @param key The key to insert under. + * @param args variadic template parameter for object construction + * arguments. + * + * @return 0 on success, negative values on error. + */ + template + int + insert_new(key_type key, const Args &... args) + { + auto pop = nvobj::pool_by_vptr(this); + nvobj::transaction::run(pop, [&] { + return insert(key, nvobj::make_persistent(args...)); + }); + + return -1; + } + + /** + * Remove a value from the tree. + * + * The tree no longer owns the value. + * + * @param key The key for which the value will be removed. + * + * @return The value if it is in the tree, nullptr otherwise. + */ + value_type + remove(key_type key) + { + nvobj::persistent_ptr parent = nullptr; + auto leaf = get_leaf(key, &parent); + + if (leaf == nullptr) + return nullptr; + + auto ret = leaf->value; + + auto pop = nvobj::pool_by_vptr(this); + nvobj::transaction::run(pop, [&] { + if (parent == nullptr) { + leaf->key = 0; + leaf->value = nullptr; + } else { + auto n = parent->inode; + *parent = *( + n->entries[parent->inode->entries[0] + ->key == leaf->key]); + + /* cleanup entries and the unnecessary node */ + nvobj::delete_persistent(n->entries[0]); + nvobj::delete_persistent(n->entries[1]); + nvobj::delete_persistent(n); + } + }); + + return ret; + } + + /** + * Remove entry from tree and deallocate it. + * + * @param key The key denoting the entry to be removed. + * + * @return 0 on success, negative values on error. + */ + int + remove_free(key_type key) + { + auto pop = nvobj::pool_by_vptr(this); + nvobj::transaction::run( + pop, [&] { nvobj::delete_persistent(remove(key)); }); + return 0; + } + + /** + * Clear the tree and deallocate all entries. + */ + int + clear() + { + auto pop = nvobj::pool_by_vptr(this); + nvobj::transaction::run(pop, [&] { + if (this->root->inode) { + this->root->inode->clear(); + nvobj::delete_persistent( + this->root->inode); + this->root->inode = nullptr; + } + + nvobj::delete_persistent(this->root->value); + this->root->value = nullptr; + this->root->key = 0; + }); + return 0; + } + + /** + * Return the value from the tree for the given key. + * + * @param key The key for which the value will be returned. + * + * @return The value if it is in the tree, nullptr otherwise. + */ + value_type + get(key_type key) + { + auto ret = get_leaf(key, nullptr); + + return ret ? ret->value : nullptr; + } + + /** + * Check if an entry for the given key is in the tree. + * + * @param key The key to check. + * + * @return 0 on + */ + int + lookup(key_type key) const + { + return get(key) != nullptr; + } + + /** + * Call clb for each element in the tree. + * + * @param clb The callback to be called. + * @param args The arguments forwarded to the callback. + * + * @return 0 if tree empty, clb return value otherwise. + */ + int foreach (callback clb, void *args) + { + if (is_empty()) + return 0; + + return foreach_node(root, clb, args); + } + + /** + * Check if tree is empty. + * + * @return 1 if empty, 0 otherwise. + */ + int + is_empty() const + { + return root->value == nullptr && root->inode == nullptr; + } + + /** + * Check tree consistency. + * + * @return 0 on success, negative values on error. + */ + int + check() const + { + return 0; + } + + /** + * Destructor. + */ + ~ctree_map_p() + { + clear(); + } + +private: + struct node; + + /* + * Entry holding the value. + */ + struct entry { + entry() : key(0), inode(nullptr), value(nullptr) + { + } + + entry(key_type _key, value_type _value) + : key(_key), inode(nullptr), value(_value) + { + } + + nvobj::p key; + nvobj::persistent_ptr inode; + value_type value; + + void + clear() + { + if (inode) { + inode->clear(); + nvobj::delete_persistent(inode); + inode = nullptr; + } + nvobj::delete_persistent(value); + value = nullptr; + } + }; + + /* + * Internal node pointing to two entries. + */ + struct node { + node() : diff(0) + { + entries[0] = nullptr; + entries[1] = nullptr; + } + + nvobj::p diff; /* most significant differing bit */ + nvobj::persistent_ptr entries[2]; + + void + clear() + { + if (entries[0]) { + entries[0]->clear(); + nvobj::delete_persistent(entries[0]); + entries[0] = nullptr; + } + if (entries[1]) { + entries[1]->clear(); + nvobj::delete_persistent(entries[1]); + entries[1] = nullptr; + } + } + }; + + /* + * Find critical bit. + */ + static int + find_crit_bit(key_type lhs, key_type rhs) + { + return find_last_set_64(lhs ^ rhs); + } + + /* + * Insert leaf into the tree. + */ + void + insert_leaf(const entry *e, int diff) + { + auto new_node = nvobj::make_persistent(); + new_node->diff = diff; + + int d = BIT_IS_SET(e->key, new_node->diff); + new_node->entries[d] = nvobj::make_persistent(*e); + + auto dest_entry = root; + while (dest_entry->inode != nullptr) { + auto n = dest_entry->inode; + if (n->diff < new_node->diff) + break; + + dest_entry = n->entries[BIT_IS_SET(e->key, n->diff)]; + } + + new_node->entries[!d] = + nvobj::make_persistent(*dest_entry); + dest_entry->key = 0; + dest_entry->inode = new_node; + dest_entry->value = nullptr; + } + + /* + * Fetch leaf from the tree. + */ + nvobj::persistent_ptr + get_leaf(key_type key, nvobj::persistent_ptr *parent) + { + auto n = root; + nvobj::persistent_ptr p = nullptr; + + while (n->inode != nullptr) { + p = n; + n = n->inode->entries[BIT_IS_SET(key, n->inode->diff)]; + } + + if (n->key == key) { + if (parent) + *parent = p; + + return n; + } + + return nullptr; + } + + /* + * Recursive foreach on nodes. + */ + int + foreach_node(const nvobj::persistent_ptr e, callback clb, + void *arg) + { + int ret = 0; + + if (e->inode != nullptr) { + auto n = e->inode; + if (foreach_node(n->entries[0], clb, arg) == 0) + foreach_node(n->entries[1], clb, arg); + } else { + ret = clb(e->key, e->value, arg); + } + + return ret; + } + + /* Tree root */ + nvobj::persistent_ptr root; +}; + +} /* namespace examples */ + +#endif /* LIBPMEMOBJ_CPP_EXAMPLES_CTREE_MAP_PERSISTENT_HPP */ diff --git a/examples/map_cli/ctree_map_transient.hpp b/examples/map_cli/ctree_map_transient.hpp new file mode 100644 index 0000000..ffff61a --- /dev/null +++ b/examples/map_cli/ctree_map_transient.hpp @@ -0,0 +1,421 @@ +/* + * Copyright 2016-2018, Intel Corporation + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * * Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef LIBPMEMOBJ_CPP_EXAMPLES_CTREE_MAP_VOLATILE_HPP +#define LIBPMEMOBJ_CPP_EXAMPLES_CTREE_MAP_VOLATILE_HPP + +#include +#include +#include +#include +#ifdef _WIN32 +#include +#endif + +#define BIT_IS_SET(n, i) (!!((n) & (1ULL << (i)))) + +namespace examples +{ + +/** + * C++ implementation of a volatile ctree. + * + * Based on the C implementation. + */ +template +class ctree_map_transient { +public: + /** Convenience typedef for the key type. */ + typedef K key_type; + + /** Convenience typedef for the value type. */ + typedef T *value_type; + + /** Convenience typedef for the callback function. */ + typedef std::function callback; + + /** + * Default constructor. + */ + ctree_map_transient() : root(new entry()) + { + } + + ctree_map_transient(const ctree_map_transient &other) = delete; + + ctree_map_transient & + operator=(const ctree_map_transient &other) = delete; + + /** + * Insert or update the given value under the given key. + * + * The map takes ownership of the value. + * + * @param key The key to insert under. + * @param value The value to be inserted. + * + * @return 0 on success, negative values on error. + */ + int + insert(uint64_t key, value_type value) + { + auto dest_entry = root; + while (dest_entry->inode != nullptr) { + auto n = dest_entry->inode; + dest_entry = n->entries[BIT_IS_SET(key, n->diff)]; + } + + entry e(key, value); + if (dest_entry->key == 0 || dest_entry->key == key) { + delete dest_entry->value; + *dest_entry = e; + } else { + insert_leaf(&e, + ctree_map_transient::find_crit_bit( + dest_entry->key, key)); + } + + return 0; + } + + /** + * Allocating insert. + * + * Creates a new value_type instance and inserts it into the tree. + * + * @param key The key to insert under. + * @param args variadic template parameter for object construction + * arguments. + * + * @return 0 on success, negative values on error. + */ + template + int + insert_new(key_type key, const Args &... args) + { + return insert(key, new T(args...)); + } + + /** + * Remove a value from the tree. + * + * The tree no longer owns the value. + * + * @param key The key for which the value will be removed. + * + * @return The value if it is in the tree, nullptr otherwise. + */ + value_type + remove(key_type key) + { + entry *parent = nullptr; + auto leaf = get_leaf(key, &parent); + + if (leaf == nullptr) + return nullptr; + + auto ret = leaf->value; + + if (parent == nullptr) { + leaf->key = 0; + leaf->value = nullptr; + } else { + auto n = parent->inode; + *parent = *(n->entries[parent->inode->entries[0]->key == + leaf->key]); + + /* cleanup both entries and the unnecessary node */ + delete n->entries[0]; + delete n->entries[1]; + delete n; + } + + return ret; + } + + /** + * Remove entry from tree and deallocate it. + * + * @param key The key denoting the entry to be removed. + * + * @return 0 on success, negative values on error. + */ + int + remove_free(key_type key) + { + delete remove(key); + return 0; + } + + /** + * Clear the tree and deallocate all entries. + */ + int + clear() + { + if (root->inode) { + root->inode->clear(); + delete root->inode; + root->inode = nullptr; + } + + delete root->value; + root->value = nullptr; + root->key = 0; + return 0; + } + + /** + * Return the value from the tree for the given key. + * + * @param key The key for which the value will be returned. + * + * @return The value if it is in the tree, nullptr otherwise. + */ + value_type + get(key_type key) + { + auto ret = get_leaf(key, nullptr); + + return ret ? ret->value : nullptr; + } + + /** + * Check if an entry for the given key is in the tree. + * + * @param key The key to check. + * + * @return 0 on + */ + int + lookup(key_type key) const + { + return get(key) != nullptr; + } + + /** + * Call clb for each element in the tree. + * + * @param clb The callback to be called. + * @param args The arguments forwarded to the callback. + * + * @return 0 if tree empty, clb return value otherwise. + */ + int foreach (callback clb, void *args) + { + if (is_empty()) + return 0; + + return foreach_node(root, clb, args); + } + + /** + * Check if tree is empty. + * + * @return 1 if empty, 0 otherwise. + */ + int + is_empty() const + { + return root->value == nullptr && root->inode == nullptr; + } + + /** + * Check tree consistency. + * + * @return 0 on success, negative values on error. + */ + int + check() const + { + return 0; + } + + /** + * Destructor. + */ + ~ctree_map_transient() + { + clear(); + delete root; + } + +private: + struct node; + + /* + * Entry holding the value. + */ + struct entry { + entry() : key(0), inode(nullptr), value(nullptr) + { + } + + entry(key_type _key, value_type _value) + : key(_key), inode(nullptr), value(_value) + { + } + + key_type key; + node *inode; + value_type value; + + /* + * Clear the entry. + */ + void + clear() + { + if (inode) { + inode->clear(); + delete inode; + } + delete value; + } + }; + + /* + * Internal node pointing to two entries. + */ + struct node { + node() : diff(0) + { + entries[0] = nullptr; + entries[1] = nullptr; + } + + int diff; /* most significant differing bit */ + entry *entries[2]; + + /* + * Clear the node. + */ + void + clear() + { + if (entries[0]) { + entries[0]->clear(); + delete entries[0]; + } + if (entries[1]) { + entries[1]->clear(); + delete entries[1]; + } + } + }; + + /* + * Find critical bit. + */ + static int + find_crit_bit(key_type lhs, key_type rhs) + { + return find_last_set_64(lhs ^ rhs); + } + + /* + * Insert leaf into the tree. + */ + void + insert_leaf(const entry *e, int diff) + { + auto new_node = new node(); + new_node->diff = diff; + + int d = BIT_IS_SET(e->key, new_node->diff); + new_node->entries[d] = new entry(*e); + + auto dest_entry = root; + while (dest_entry->inode != nullptr) { + auto n = dest_entry->inode; + if (n->diff < new_node->diff) + break; + + dest_entry = n->entries[BIT_IS_SET(e->key, n->diff)]; + } + + new_node->entries[!d] = new entry(*dest_entry); + dest_entry->key = 0; + dest_entry->inode = new_node; + dest_entry->value = nullptr; + } + + /* + * Fetch leaf from the tree. + */ + entry * + get_leaf(uint64_t key, entry **parent) + { + auto n = root; + entry *p = nullptr; + + while (n->inode != nullptr) { + p = n; + n = n->inode->entries[BIT_IS_SET(key, n->inode->diff)]; + } + + if (n->key == key) { + if (parent) + *parent = p; + + return n; + } + + return nullptr; + } + + /* + * Recursive foreach on nodes. + */ + int + foreach_node(const entry *e, callback clb, void *arg) + { + int ret = 0; + + if (e->inode != nullptr) { + auto n = e->inode; + if (foreach_node(n->entries[0], clb, arg) == 0) + foreach_node(n->entries[1], clb, arg); + } else { + ret = clb(e->key, e->value, arg); + } + + return ret; + } + + /* Tree root */ + entry *root; +}; + +} /* namespace examples */ + +#endif /* LIBPMEMOBJ_CPP_EXAMPLES_CTREE_MAP_VOLATILE_HPP */ diff --git a/examples/map_cli/map_cli.cpp b/examples/map_cli/map_cli.cpp new file mode 100644 index 0000000..faf0476 --- /dev/null +++ b/examples/map_cli/map_cli.cpp @@ -0,0 +1,274 @@ +/* + * Copyright 2016-2019, Intel Corporation + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * * Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "ctree_map_persistent.hpp" +#include "ctree_map_transient.hpp" +#include +#include +#include +#include +#include + +namespace +{ + +using pmem::obj::delete_persistent; +using pmem::obj::make_persistent; +using pmem::obj::persistent_ptr; +using pmem::obj::pool; +using pmem::obj::pool_base; +using pmem::obj::transaction; + +/* convenience typedefs */ +typedef long long value_t; +typedef uint64_t key_type; +typedef examples::ctree_map_p pmap; +typedef examples::ctree_map_transient vmap; + +const std::string LAYOUT = ""; + +/* available map operations */ +enum queue_op { + UNKNOWN_QUEUE_OP, + MAP_INSERT, + MAP_INSERT_NEW, + MAP_GET, + MAP_REMOVE, + MAP_REMOVE_FREE, + MAP_CLEAR, + MAP_PRINT, + + MAX_QUEUE_OP +}; + +/* queue operations strings */ +const char *ops_str[MAX_QUEUE_OP] = {"", "insert", "insert_new", + "get", "remove", "remove_free", + "clear", "print"}; + +/* + * parse_queue_op -- parses the operation string and returns matching queue_op + */ +queue_op +parse_queue_op(const char *str) +{ + for (int i = 0; i < MAX_QUEUE_OP; ++i) + if (strcmp(str, ops_str[i]) == 0) + return (queue_op)i; + + return UNKNOWN_QUEUE_OP; +} + +struct root { + persistent_ptr ptree; +}; + +/* + * printer -- (internal) print the value for the given key + */ +template +int +printer(key_type key, T value, void *) +{ + std::cout << "map[" << key << "] = " << *value << std::endl; + return 0; +} + +/* + * insert -- (internal) insert value into the map + */ +template +void +insert(pool_base pop, T &map, char *argv[], int &argn) +{ + map->insert(atoll(argv[argn]), new value_t(atoll(argv[argn + 1]))); + argn += 2; +} + +/* + * remove -- (internal) remove value from map + */ +template +void +remove(pool_base pop, T &map, char *argv[], int &argn) +{ + auto val = map->remove(atoll(argv[argn++])); + if (val) { + std::cout << *val << std::endl; + delete val; + } else { + std::cout << "Entry not found\n"; + } +} + +/* + * remove -- (internal) remove specialization for persistent ctree + */ +template <> +void +remove>(pool_base pop, persistent_ptr &map, + char *argv[], int &argn) +{ + auto val = map->remove(atoll(argv[argn++])); + if (val) { + std::cout << *val << std::endl; + transaction::run(pop, [&] { delete_persistent(val); }); + } else { + std::cout << "Entry not found\n"; + } +} + +/* + * insert -- (internal) insert specialization for persistent ctree + */ +template <> +void +insert>(pool_base pop, persistent_ptr &map, + char *argv[], int &argn) +{ + transaction::run(pop, [&] { + map->insert(atoll(argv[argn]), + make_persistent(atoll(argv[argn + 1]))); + }); + argn += 2; +} + +/* + * exec_op -- (internal) execute single operation + */ +template +void +exec_op(pool_base pop, T &map, queue_op op, char *argv[], int &argn) +{ + switch (op) { + case MAP_INSERT_NEW: + map->insert_new(atoll(argv[argn]), + atoll(argv[argn + 1])); + argn += 2; + break; + case MAP_INSERT: + insert(pop, map, argv, argn); + break; + case MAP_GET: { + auto val = map->get(atoll(argv[argn++])); + if (val) + std::cout << *val << std::endl; + else + std::cout << "key not found\n"; + break; + } + case MAP_REMOVE: + remove(pop, map, argv, argn); + break; + case MAP_REMOVE_FREE: + map->remove_free(atoll(argv[argn++])); + break; + case MAP_CLEAR: + map->clear(); + break; + case MAP_PRINT: + map->foreach (printer, nullptr); + break; + default: + throw std::invalid_argument("invalid queue operation"); + } +} +} + +int +main(int argc, char *argv[]) +{ + if (argc < 4) { + std::cerr + << "usage: " << argv[0] + << " file-name [insert |insert_new |get |remove | remove_free ]" + << std::endl; + return 1; + } + + std::string path = argv[1]; + std::string type = argv[2]; + + pool pop; + + try { + if (file_exists(path.c_str()) != 0) { + pop = pool::create(path, LAYOUT, PMEMOBJ_MIN_POOL, + CREATE_MODE_RW); + } else { + pop = pool::open(path, LAYOUT); + } + } catch (pmem::pool_error &e) { + std::cerr << e.what() << std::endl; + return 1; + } + + persistent_ptr q; + try { + q = pop.root(); + } catch (std::exception &e) { + std::cerr << e.what() << std::endl; + pop.close(); + return 1; + } + + if (!q->ptree) { + try { + transaction::run(pop, [&] { + q->ptree = make_persistent(); + }); + } catch (pmem::transaction_error &e) { + std::cerr << e.what() << std::endl; + pop.close(); + return 1; + } + } + + auto vtree = std::make_shared(); + + for (int i = 3; i < argc;) { + queue_op op = parse_queue_op(argv[i++]); + try { + if (type == "volatile") + exec_op(pop, vtree, op, argv, i); + else + exec_op(pop, q->ptree, op, argv, i); + } catch (std::exception &e) { + std::cerr << e.what() << std::endl; + break; + } + } + + pop.close(); + + return 0; +} diff --git a/examples/panaconda/CMakeLists.txt b/examples/panaconda/CMakeLists.txt new file mode 100644 index 0000000..e533faf --- /dev/null +++ b/examples/panaconda/CMakeLists.txt @@ -0,0 +1,58 @@ +# +# Copyright 2018, Intel Corporation +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# +# * Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# +# * Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in +# the documentation and/or other materials provided with the +# distribution. +# +# * Neither the name of the copyright holder nor the names of its +# contributors may be used to endorse or promote products derived +# from this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +cmake_minimum_required(VERSION 3.3) +project(panaconda CXX) + +set(CXX_STANDARD_REQUIRED ON) +set(CMAKE_CXX_STANDARD 11) + +include(FindThreads) + +find_package(PkgConfig QUIET) +if(PKG_CONFIG_FOUND) + pkg_check_modules(LIBPMEMOBJ++ REQUIRED libpmemobj++) + + pkg_check_modules(CURSES REQUIRED ncurses) +else() + find_package(LIBPMEMOBJ++ REQUIRED) + + # Specifies that we want FindCurses to find ncurses and not just any + # curses library + set(CURSES_NEED_NCURSES TRUE) + find_package(Curses REQUIRED) +endif() + +link_directories(${LIBPMEMOBJ++_LIBRARY_DIRS}) + +add_executable(panaconda panaconda.cpp) +target_include_directories(panaconda PUBLIC ${CURSES_INCLUDE_DIR} ${LIBPMEMOBJ++_INCLUDE_DIRS} . ..) +target_link_libraries(panaconda ${LIBPMEMOBJ++_LIBRARIES} ${CMAKE_THREAD_LIBS_INIT} ${CURSES_LIBRARIES}) diff --git a/examples/panaconda/README b/examples/panaconda/README new file mode 100644 index 0000000..bbd7a24 --- /dev/null +++ b/examples/panaconda/README @@ -0,0 +1,31 @@ +This directory contains an example application implemented using libpmemobj, +it's a game in which all the objects are stored on persistent memory. +This means that the game process can be safely killed and then resumed. + +To launch the game: + ./panaconda /path/game/session/file + or + ./panaconda /path/game/session/file -m /path/config/file/conf/cfg + +The second option allow you to define your own maze. +Meaning of symbols in config file is given below: + '1' - wall + '0' - space +conf.cfg contains example of predefined maze. + +The file with the game session will either be created if it doesn't exist +or opened if it contains a valid pool. + +Controls: + move - arrow keys + quit - 'q' + new game - 'n' + +This game demonstrates the usage of the very basics of the libpmemobj C++ +bindings. It demonstrates pool management, persistent pointers and transactions. + +** DEPENDENCIES: ** +In order to build the game you need to install ncurses development package. + +rpm-based systems : ncurses-devel +dpkg-based systems: libncursesX-dev (where X is the API/ABI version) diff --git a/examples/panaconda/conf.cfg b/examples/panaconda/conf.cfg new file mode 100644 index 0000000..8f19bed --- /dev/null +++ b/examples/panaconda/conf.cfg @@ -0,0 +1,30 @@ +11111111111111111111111111111111 +10000000000000000000000000000001 +10000000000000000000000000000001 +10000000000000000000000000000001 +10000000000000000000000000000001 +10000000000000000000000000000001 +10000000000000000000000000000001 +10000000000000000000000000000001 +10000000000000000000000000000001 +10000000000000000000000000000001 +10000000000000000000000000000001 +10000000000000000000000000000001 +10000000111000000000111000000001 +10000000111000010000111000000001 +10000000000000111000000000000001 +10000000000001111100000000000001 +10000000000000000000000000000001 +10000011111111111111111111000001 +10000000011111111111111000000001 +10000000000000111100000000000001 +10000000000000000000000000000001 +10000000000000000000000000000001 +10000000000000000000000000000001 +10000000000000000000000000000001 +10000000000000000000000000000001 +10000000000000000000000000000001 +10000000000000000000000000000001 +10000000000000000000000000000001 +10000000000000000000000000000001 +11111111111111111111111111111111 \ No newline at end of file diff --git a/examples/panaconda/panaconda.cpp b/examples/panaconda/panaconda.cpp new file mode 100644 index 0000000..59ccb1d --- /dev/null +++ b/examples/panaconda/panaconda.cpp @@ -0,0 +1,996 @@ +/* + * Copyright 2016-2018, Intel Corporation + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * * Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +/* + * panaconda.cpp -- example usage of libpmemobj C++ bindings + */ +#ifdef __FreeBSD__ +#define _WITH_GETLINE +#endif +#include +#include +#include +#include +#include +#ifdef __FreeBSD__ +#include /* Need pkg, not system, version */ +#else +#include +#endif + +#include "panaconda.hpp" + +#define LAYOUT_NAME "panaconda" +#define DEFAULT_DELAY 120000 + +#define SNAKE_START_POS_X 5 +#define SNAKE_START_POS_Y 5 +#define SNAKE_START_DIR (direction::RIGHT) +#define SNAKE_STAR_SEG_NO 5 + +#define BOARD_STATIC_SIZE_ROW 40 +#define BOARD_STATIC_SIZE_COL 30 + +#define PLAYER_POINTS_PER_HIT 10 + +using examples::list; +using pmem::pool_error; +using pmem::transaction_error; +using pmem::transaction_scope_error; +using pmem::obj::delete_persistent; +using pmem::obj::make_persistent; +using pmem::obj::persistent_ptr; +using pmem::obj::pool; +using pmem::obj::transaction; + +/* + * Color_pair + */ +color_pair::color_pair() : color_bg(COLOR_BLACK), color_fg(COLOR_BLACK) +{ +} +color_pair::color_pair(const int col_fg, const int col_bg) + : color_bg(col_bg), color_fg(col_fg) +{ +} + +/* + * Helper + */ +struct color_pair +helper::get_color(const object_type obj_type) +{ + struct color_pair res; + switch (obj_type) { + case SNAKE_SEGMENT: + res = color_pair(COLOR_WHITE, COLOR_BLACK); + break; + case WALL: + res = color_pair(COLOR_BLUE, COLOR_BLUE); + break; + case FOOD: + res = color_pair(COLOR_RED, COLOR_BLACK); + break; + default: + std::cout << "Error: get_color - wrong value passed!" + << std::endl; + assert(0); + } + return res; +} + +int +helper::parse_params(int argc, char *argv[], struct parameters *par) +{ + int opt; + std::string app = argv[0]; + while ((opt = getopt(argc, argv, "m:")) != -1) { + switch (opt) { + case 'm': + par->use_maze = true; + par->maze_path = optarg; + break; + default: + helper::print_usage(app); + return -1; + } + } + + if (optind < argc) { + par->name = argv[optind]; + } else { + helper::print_usage(app); + return -1; + } + return 0; +} + +inline void +helper::sleep(int time) +{ + clock_t curr_time = clock(); + while (clock() < (curr_time + time)) { + } +} + +inline void +helper::print_usage(std::string &name) +{ + std::cout << "Usage: " << name << " [-m ] \n"; +} + +/* + * Point + */ +point::point() : x(0), y(0) +{ +} + +point::point(int x, int y) : x(x), y(y) +{ +} + +bool +operator==(point &point1, point &point2) +{ + return point1.x == point2.x && point1.y == point2.y; +} +/* + * Shape + */ +element_shape::element_shape(int shape) +{ + int n_curves_symbol = get_symbol(shape); + val = COLOR_PAIR(shape) | n_curves_symbol; +} + +int +element_shape::get_val() +{ + return val; +} + +int +element_shape::get_symbol(int shape) +{ + int symbol = 0; + switch (shape) { + case SNAKE_SEGMENT: + symbol = ACS_DIAMOND; + break; + case WALL: + symbol = ACS_BLOCK; + break; + case FOOD: + symbol = ACS_CKBOARD; + break; + + default: + symbol = ACS_DIAMOND; + break; + } + return symbol; +} + +/* + * Element + */ +board_element::board_element() + : position(make_persistent(0, 0)), + shape(make_persistent(SNAKE_SEGMENT)), + element_dir(direction::LEFT) +{ +} + +board_element::board_element(int px, int py, + pmem::obj::persistent_ptr shape, + direction dir) + : position(make_persistent(px, py)), shape(shape), element_dir(dir) +{ +} + +board_element::board_element(point p, + pmem::obj::persistent_ptr shape, + direction dir) + : position(make_persistent(p.x, p.y)), shape(shape), element_dir(dir) +{ +} + +board_element::board_element(const board_element &element) + : position( + make_persistent(element.position->x, element.position->y)), + shape(element.shape), + element_dir(UNDEFINED) +{ +} + +board_element::~board_element() +{ + pmem::obj::delete_persistent(position); + position = nullptr; + pmem::obj::delete_persistent(shape); + shape = nullptr; +} + +persistent_ptr +board_element::calc_new_position(const direction dir) +{ + persistent_ptr pt = + make_persistent(position->x, position->y); + + switch (dir) { + case direction::DOWN: + pt->y = pt->y + 1; + break; + case direction::LEFT: + pt->x = pt->x - 1; + break; + case direction::RIGHT: + pt->x = pt->x + 1; + break; + case direction::UP: + pt->y = pt->y - 1; + break; + default: + break; + } + + return pt; +} + +void +board_element::set_position(const persistent_ptr new_point) +{ + position = new_point; +} + +persistent_ptr +board_element::get_position(void) +{ + return position; +} + +void +board_element::print(void) +{ + mvaddch(position->y, position->x, shape->get_val()); +} + +void +board_element::print_double_col(void) +{ + mvaddch(position->y, (2 * position->x), shape->get_val()); +} + +void +board_element::print_single_double_col(void) +{ + mvaddch(position->y, (2 * position->x), shape->get_val()); + mvaddch(position->y, (2 * position->x - 1), shape->get_val()); +} + +direction +board_element::get_direction(void) +{ + return element_dir; +} +void +board_element::set_direction(const direction dir) +{ + element_dir = dir; +} + +/* + * Snake + */ +snake::snake() +{ + snake_segments = make_persistent>(); + for (unsigned i = 0; i < SNAKE_STAR_SEG_NO; ++i) { + persistent_ptr shape = + make_persistent(SNAKE_SEGMENT); + persistent_ptr element = + make_persistent(SNAKE_START_POS_X - i, + SNAKE_START_POS_Y, shape, + SNAKE_START_DIR); + snake_segments->push_back(element); + } + + last_seg_position = point(); + last_seg_dir = direction::RIGHT; +} + +snake::~snake() +{ + snake_segments->clear(); + delete_persistent>(snake_segments); +} + +void +snake::move(const direction dir) +{ + int snake_size = snake_segments->size(); + persistent_ptr new_position_point; + + last_seg_position = + *(snake_segments->get(snake_size - 1)->get_position().get()); + last_seg_dir = snake_segments->get(snake_size - 1)->get_direction(); + + for (int i = (snake_size - 1); i >= 0; --i) { + if (i == 0) { + new_position_point = + snake_segments->get(i)->calc_new_position(dir); + snake_segments->get(i)->set_direction(dir); + } else { + new_position_point = + snake_segments->get(i)->calc_new_position( + snake_segments->get(i - 1) + ->get_direction()); + snake_segments->get(i)->set_direction( + snake_segments->get(i - 1)->get_direction()); + } + snake_segments->get(i)->set_position(new_position_point); + } +} + +void +snake::print(void) +{ + int i = 0; + persistent_ptr segp; + + while ((segp = snake_segments->get(i++)) != nullptr) + segp->print_double_col(); +} + +void +snake::add_segment(void) +{ + persistent_ptr shape = + make_persistent(SNAKE_SEGMENT); + persistent_ptr segp = make_persistent( + last_seg_position, shape, last_seg_dir); + snake_segments->push_back(segp); +} + +bool +snake::check_point_against_segments(point point) +{ + int i = 0; + bool result = false; + persistent_ptr segp; + + while ((segp = snake_segments->get(i++)) != nullptr) { + if (point == *(segp->get_position().get())) { + result = true; + break; + } + } + return result; +} + +point +snake::get_head_point(void) +{ + return *(snake_segments->get(0)->get_position().get()); +} + +direction +snake::get_direction(void) +{ + return snake_segments->get(0)->get_direction(); +} + +point +snake::get_next_point(const direction dir) +{ + return *(snake_segments->get(0)->calc_new_position(dir).get()); +} + +/* + * Board + */ + +game_board::game_board() +{ + persistent_ptr shape = + make_persistent(FOOD); + food = make_persistent(0, 0, shape, + direction::UNDEFINED); + layout = make_persistent>(); + anaconda = make_persistent(); + size_row = 20; + size_col = 20; +} + +game_board::~game_board() +{ + layout->clear(); + delete_persistent>(layout); + delete_persistent(anaconda); + delete_persistent(food); +} + +void +game_board::print(const int score) +{ + const int offset_y = 2 * size_col + 5; + const int offset_x = 2; + + int i = 0; + persistent_ptr elmp; + + while ((elmp = layout->get(i++)) != nullptr) + elmp->print_single_double_col(); + + anaconda->print(); + food->print_double_col(); + + mvprintw((offset_x + 0), offset_y, " ##### panaconda ##### "); + mvprintw((offset_x + 1), offset_y, " # # "); + mvprintw((offset_x + 2), offset_y, " # q - quit # "); + mvprintw((offset_x + 3), offset_y, " # n - new game # "); + mvprintw((offset_x + 4), offset_y, " # # "); + mvprintw((offset_x + 5), offset_y, " ##################### "); + + mvprintw((offset_x + 7), offset_y, " Score: %d ", score); +} + +void +game_board::print_game_over(const int score) +{ + int x = size_col / 3; + int y = size_row / 6; + mvprintw(y + 0, x, "####### ####### # # #######"); + mvprintw(y + 1, x, "# # # ## ## # "); + mvprintw(y + 2, x, "# ### ####### # # # # #### "); + mvprintw(y + 3, x, "# # # # # # # # "); + mvprintw(y + 4, x, "####### # # # # #######"); + + mvprintw(y + 6, x, "####### # # ####### #######"); + mvprintw(y + 7, x, "# # # # # # #"); + mvprintw(y + 8, x, "# # # # #### #######"); + mvprintw(y + 9, x, "# # # # # # # "); + mvprintw(y + 10, x, "####### # ####### # #"); + + mvprintw(y + 12, x, " Last score: %d ", score); + mvprintw(y + 14, x, " q - quit"); + mvprintw(y + 15, x, " n - new game"); +} + +int +game_board::creat_dynamic_layout(const unsigned row_no, char *const buffer) +{ + persistent_ptr element; + persistent_ptr shape; + + for (unsigned i = 0; i < size_col; ++i) { + if (buffer[i] == config_file_symbol::SYM_WALL) { + shape = make_persistent(WALL); + element = make_persistent( + i, row_no, shape, direction::UNDEFINED); + layout->push_back(element); + } + } + return 0; +} + +int +game_board::creat_static_layout(void) +{ + persistent_ptr element; + persistent_ptr shape; + + size_row = BOARD_STATIC_SIZE_ROW; + size_col = BOARD_STATIC_SIZE_COL; + + // first and last row + for (unsigned i = 0; i < size_col; ++i) { + shape = make_persistent(WALL); + element = make_persistent(i, 0, shape, + direction::UNDEFINED); + layout->push_back(element); + shape = make_persistent(WALL); + element = make_persistent( + i, (size_row - 1), shape, direction::UNDEFINED); + layout->push_back(element); + } + + // middle rows + for (unsigned i = 1; i < size_row; ++i) { + shape = make_persistent(WALL); + element = make_persistent(0, i, shape, + direction::UNDEFINED); + layout->push_back(element); + shape = make_persistent(WALL); + element = make_persistent( + (size_col - 1), i, shape, direction::UNDEFINED); + layout->push_back(element); + } + return 0; +} + +bool +game_board::is_snake_collision(point point) +{ + return anaconda->check_point_against_segments(point); +} + +bool +game_board::is_wall_collision(point point) +{ + int i = 0; + bool result = false; + persistent_ptr wallp; + + while ((wallp = layout->get(i++)) != nullptr) { + if (point == *(wallp->get_position().get())) { + result = true; + break; + } + } + return result; +} + +bool +game_board::is_collision(point point) +{ + return is_snake_collision(point) || is_wall_collision(point); +} + +bool +game_board::is_snake_head_food_hit(void) +{ + bool result = false; + point head_point = anaconda->get_head_point(); + + if (head_point == *(food->get_position().get())) { + result = true; + } + return result; +} + +void +game_board::set_new_food(const point point) +{ + persistent_ptr shape = + make_persistent(FOOD); + delete_persistent(food); + food = make_persistent(point, shape, + direction::UNDEFINED); +} + +void +game_board::create_new_food(void) +{ + const int max_repeat = 50; + int count = 0; + int rand_row = 0; + int rand_col = 0; + + while (count < max_repeat) { + rand_row = 1 + rand() % (get_size_row() - 2); + rand_col = 1 + rand() % (get_size_col() - 2); + + point food_point(rand_col, rand_row); + if (!is_collision(food_point)) { + set_new_food(food_point); + break; + } + count++; + } +} + +snake_event +game_board::move_snake(const direction dir) +{ + snake_event event = snake_event::EV_OK; + point next_pt = anaconda->get_next_point(dir); + + if (is_collision(next_pt)) { + event = snake_event::EV_COLLISION; + } else { + anaconda->move(dir); + } + + return event; +} + +void +game_board::add_snake_segment(void) +{ + anaconda->add_segment(); +} + +unsigned +game_board::get_size_row(void) +{ + return size_row; +} + +void +game_board::set_size_row(const unsigned size_r) +{ + size_row = size_r; +} + +unsigned +game_board::get_size_col(void) +{ + return size_col; +} + +void +game_board::set_size_col(const unsigned size_c) +{ + size_col = size_c; +} + +direction +game_board::get_snake_dir(void) +{ + return anaconda->get_direction(); +} + +/* + * Game_state + */ +game_state::game_state() +{ +} + +game_state::~game_state() +{ +} + +pmem::obj::persistent_ptr +game_state::get_board() +{ + return board; +} + +pmem::obj::persistent_ptr +game_state::get_player() +{ + return player; +} + +void +game_state::init(void) +{ + board = make_persistent(); + player = make_persistent(); +} + +void +game_state::clean_pool(void) +{ + delete_persistent(board); + board = nullptr; + + delete_persistent(player); + player = nullptr; +} + +/* + * Player + */ +game_player::game_player() : score(0), state(STATE_PLAY) +{ +} + +game_player::~game_player() +{ +} + +int +game_player::get_score(void) +{ + return score; +} + +play_state +game_player::get_state(void) +{ + return state; +} +void +game_player::set_state(const play_state st) +{ + state = st; +} + +void +game_player::update_score(void) +{ + score = score + PLAYER_POINTS_PER_HIT; +} +/* + * Game + */ +game::game(struct parameters *par) +{ + pool pop; + + initscr(); + start_color(); + nodelay(stdscr, true); + curs_set(0); + keypad(stdscr, true); + + params = par; + if (pool::check(params->name, LAYOUT_NAME) == 1) + pop = pool::open(params->name, LAYOUT_NAME); + else + pop = pool::create(params->name, LAYOUT_NAME, + PMEMOBJ_MIN_POOL * 10, 0666); + + state = pop; + direction_key = direction::UNDEFINED; + last_key = KEY_CLEAR; + delay = DEFAULT_DELAY; + + init_colors(); + + srand(time(nullptr)); +} + +game::~game() +{ +} + +void +game::init_colors(void) +{ + struct color_pair color_pair = helper::get_color(SNAKE_SEGMENT); + init_pair(SNAKE_SEGMENT, color_pair.color_fg, color_pair.color_bg); + + color_pair = helper::get_color(WALL); + init_pair(WALL, color_pair.color_fg, color_pair.color_bg); + + color_pair = helper::get_color(FOOD); + init_pair(FOOD, color_pair.color_fg, color_pair.color_bg); +} + +void +game::init(void) +{ + int ret = 0; + persistent_ptr r = state.root(); + + if (r->get_board() == nullptr) { + + transaction::run(state, [&r, &ret, this]() { + r->init(); + if (params->use_maze) + ret = parse_conf_create_dynamic_layout(); + else + ret = r->get_board()->creat_static_layout(); + + r->get_board()->create_new_food(); + }); + + if (ret) { + clean_pool(); + clear_prog(); + throw std::runtime_error("Error: Config file error!"); + } + } + direction_key = r->get_board()->get_snake_dir(); +} + +void +game::process_step(void) +{ + snake_event ret_event = EV_OK; + persistent_ptr r = state.root(); + transaction::run(state, [&]() { + ret_event = r->get_board()->move_snake(direction_key); + if (EV_COLLISION == ret_event) { + r->get_player()->set_state(play_state::STATE_GAMEOVER); + return; + } else { + if (r->get_board()->is_snake_head_food_hit()) { + r->get_board()->create_new_food(); + r->get_board()->add_snake_segment(); + r->get_player()->update_score(); + } + } + }); + + r->get_board()->print(r->get_player()->get_score()); +} + +inline bool +game::is_stopped(void) +{ + return action::ACTION_QUIT == last_key; +} + +void +game::set_direction_key(void) +{ + switch (last_key) { + case KEY_LEFT: + if (direction::RIGHT != direction_key) + direction_key = direction::LEFT; + break; + case KEY_RIGHT: + if (direction::LEFT != direction_key) + direction_key = direction::RIGHT; + break; + case KEY_UP: + if (direction::DOWN != direction_key) + direction_key = direction::UP; + break; + case KEY_DOWN: + if (direction::UP != direction_key) + direction_key = direction::DOWN; + break; + default: + break; + } +} + +void +game::process_key(const int lastkey) +{ + last_key = lastkey; + set_direction_key(); + + if (action::ACTION_NEW_GAME == last_key) { + clean_pool(); + init(); + } +} + +void +game::clean_pool(void) +{ + persistent_ptr r = state.root(); + transaction::run(state, [&]() { r->clean_pool(); }); +} + +void +game::process_delay(void) +{ + helper::sleep(delay); +} + +void +game::clear_screen(void) +{ + erase(); +} + +void +game::game_over(void) +{ + persistent_ptr r = state.root(); + r->get_board()->print_game_over(r->get_player()->get_score()); +} + +bool +game::is_game_over(void) +{ + persistent_ptr r = state.root(); + return (r->get_player()->get_state() == play_state::STATE_GAMEOVER); +} + +void +game::clear_prog(void) +{ + state.close(); + endwin(); +} + +int +game::parse_conf_create_dynamic_layout(void) +{ + FILE *cfg_file; + char *line = nullptr; + size_t len = 0; + unsigned i = 0; + ssize_t col_no = 0; + + cfg_file = fopen(params->maze_path.c_str(), "r"); + if (cfg_file == nullptr) + return -1; + + persistent_ptr r = state.root(); + while ((col_no = getline(&line, &len, cfg_file)) != -1) { + if (i == 0) + r->get_board()->set_size_col(col_no - 1); + + try { + transaction::run(state, [&]() { + r->get_board()->creat_dynamic_layout(i, line); + }); + } catch (transaction_error &err) { + std::cout << err.what() << std::endl; + } catch (transaction_scope_error &tse) { + std::cout << tse.what() << std::endl; + } + i++; + } + r->get_board()->set_size_row(i); + + free(line); + fclose(cfg_file); + return 0; +} + +/* + * main + */ +int +main(int argc, char *argv[]) +{ + struct parameters params; + params.use_maze = false; + + if (helper::parse_params(argc, argv, ¶ms)) + return -1; + + int ret = -1; + try { + std::unique_ptr snake_game{new game(¶ms)}; + snake_game->init(); + + while (!snake_game->is_stopped()) { + int input = getch(); + snake_game->process_key(input); + if (snake_game->is_game_over()) { + snake_game->game_over(); + } else { + snake_game->process_delay(); + snake_game->clear_screen(); + snake_game->process_step(); + } + } + + snake_game->clear_prog(); + ret = 0; + } catch (transaction_error &err) { + std::cout << err.what() << std::endl; + } catch (transaction_scope_error &tse) { + std::cout << tse.what() << std::endl; + } catch (pool_error &pe) { + std::cout << pe.what() << std::endl; + } catch (std::logic_error &le) { + std::cout << le.what() << std::endl; + } catch (std::runtime_error &re) { + std::cout << re.what() << std::endl; + } + + return ret; +} diff --git a/examples/panaconda/panaconda.hpp b/examples/panaconda/panaconda.hpp new file mode 100644 index 0000000..640dcfc --- /dev/null +++ b/examples/panaconda/panaconda.hpp @@ -0,0 +1,236 @@ +/* + * Copyright 2016-2018, Intel Corporation + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * * Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +/* + * panaconda.hpp -- example usage of libpmemobj C++ bindings + */ + +#ifndef LIBPMEMOBJ_CPP_EXAMPLES_PANACONDA_HPP +#define LIBPMEMOBJ_CPP_EXAMPLES_PANACONDA_HPP + +#include +#include +#include +#include +#include + +class board_element; + +enum direction { UNDEFINED, DOWN, RIGHT, UP, LEFT }; +enum object_type { SNAKE_SEGMENT, WALL, FOOD }; +enum config_file_symbol { SYM_NOTHING = '0', SYM_WALL = '1' }; +enum play_state { STATE_NEW, STATE_PLAY, STATE_GAMEOVER }; + +enum snake_event { EV_OK, EV_COLLISION }; + +enum action { ACTION_NEW_GAME = 'n', ACTION_QUIT = 'q' }; + +typedef pmem::obj::persistent_ptr> element_list; + +struct color_pair { + color_pair(); + color_pair(const int col_fg, const int col_bg); + int color_bg; + int color_fg; +}; + +struct parameters { + bool use_maze; + std::string name; + std::string maze_path; +}; + +class helper { +public: + static color_pair get_color(const object_type obj_type); + static int parse_params(int argc, char *argv[], + struct parameters *params); + static inline void sleep(int time); + static inline void print_usage(std::string &name); +}; + +class point { +public: + pmem::obj::p x; + pmem::obj::p y; + + point(); + point(int x, int y); + friend bool operator==(point &point1, point &point2); +}; + +bool operator==(point &point1, point &point2); + +class element_shape { +public: + element_shape() = default; + element_shape(int shape); + int get_val(); + +private: + pmem::obj::p val; + int get_symbol(int shape); +}; + +class board_element { +public: + board_element(); + board_element(int px, int py, + pmem::obj::persistent_ptr shape, + direction dir); + board_element(point p, pmem::obj::persistent_ptr shape, + direction dir); + board_element(const board_element &element); + ~board_element(); + + pmem::obj::persistent_ptr calc_new_position(const direction dir); + void print(void); + void print_double_col(void); + void print_single_double_col(void); + pmem::obj::persistent_ptr get_position(void); + void set_position(const pmem::obj::persistent_ptr new_point); + direction get_direction(void); + void set_direction(const direction dir); + +private: + pmem::obj::persistent_ptr position; + pmem::obj::persistent_ptr shape; + pmem::obj::p element_dir; +}; + +class snake { +public: + snake(); + ~snake(); + + void move(const direction dir); + void print(void); + void add_segment(void); + bool check_point_against_segments(point point); + point get_head_point(void); + direction get_direction(void); + point get_next_point(const direction dir); + +private: + element_list snake_segments; + pmem::obj::p last_seg_position; + pmem::obj::p last_seg_dir; +}; + +class game_board { +public: + game_board(); + ~game_board(); + void print(const int score); + void print_game_over(const int score); + unsigned get_size_row(void); + void set_size_row(const unsigned size_r); + unsigned get_size_col(void); + void set_size_col(const unsigned size_c); + int creat_dynamic_layout(const unsigned row_no, char *const buffer); + int creat_static_layout(void); + bool is_snake_head_food_hit(void); + void create_new_food(void); + bool is_collision(point point); + snake_event move_snake(const direction dir); + direction get_snake_dir(void); + void add_snake_segment(void); + +private: + pmem::obj::persistent_ptr anaconda; + pmem::obj::persistent_ptr food; + element_list layout; + + pmem::obj::p size_row; + pmem::obj::p size_col; + + void set_new_food(const point point); + bool is_snake_collision(point point); + bool is_wall_collision(point point); +}; + +class game_player { +public: + game_player(); + ~game_player(); + int get_score(void); + void update_score(void); + play_state get_state(void); + void set_state(const play_state st); + +private: + pmem::obj::p score; + pmem::obj::p state; +}; + +class game_state { +public: + game_state(); + ~game_state(); + pmem::obj::persistent_ptr get_board(); + pmem::obj::persistent_ptr get_player(); + void init(void); + void clean_pool(void); + +private: + pmem::obj::persistent_ptr board; + pmem::obj::persistent_ptr player; +}; + +class game { +public: + game(struct parameters *par); + ~game(); + void init(void); + void init_colors(void); + void process_step(void); + void process_key(const int lastkey); + inline bool is_stopped(void); + void process_delay(void); + void clear_screen(void); + bool is_game_over(void); + void game_over(void); + void clear_prog(void); + +private: + pmem::obj::pool state; + int last_key; + int delay; + struct parameters *params; + direction direction_key; + + void clean_pool(void); + void set_direction_key(void); + int parse_conf_create_dynamic_layout(void); +}; + +#endif /* LIBPMEMOBJ_CPP_EXAMPLES_PANACONDA_HPP */ diff --git a/examples/pman/CMakeLists.txt b/examples/pman/CMakeLists.txt new file mode 100644 index 0000000..819d46a --- /dev/null +++ b/examples/pman/CMakeLists.txt @@ -0,0 +1,58 @@ +# +# Copyright 2018, Intel Corporation +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# +# * Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# +# * Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in +# the documentation and/or other materials provided with the +# distribution. +# +# * Neither the name of the copyright holder nor the names of its +# contributors may be used to endorse or promote products derived +# from this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +cmake_minimum_required(VERSION 3.3) +project(pman CXX) + +set(CXX_STANDARD_REQUIRED ON) +set(CMAKE_CXX_STANDARD 11) + +include(FindThreads) + +find_package(PkgConfig QUIET) +if(PKG_CONFIG_FOUND) + pkg_check_modules(LIBPMEMOBJ++ REQUIRED libpmemobj++) + + pkg_check_modules(CURSES REQUIRED ncurses) +else() + find_package(LIBPMEMOBJ++ REQUIRED) + + # Specifies that we want FindCurses to find ncurses and not just any + # curses library + set(CURSES_NEED_NCURSES TRUE) + find_package(Curses REQUIRED) +endif() + +link_directories(${LIBPMEMOBJ++_LIBRARY_DIRS}) + +add_executable(pman pman.cpp) +target_include_directories(pman PUBLIC ${CURSES_INCLUDE_DIR} ${LIBPMEMOBJ++_INCLUDE_DIRS} . ..) +target_link_libraries(pman ${LIBPMEMOBJ++_LIBRARIES} ${CMAKE_THREAD_LIBS_INIT} ${CURSES_LIBRARIES}) diff --git a/examples/pman/README b/examples/pman/README new file mode 100644 index 0000000..adb598a --- /dev/null +++ b/examples/pman/README @@ -0,0 +1,24 @@ +This directory contains an example application implemented using libpmemobj, +it's a game in which all the objects are stored on persistent memory. +This means that the game process can be safely killed and then resumed. + +To launch the game: + ./pman [map file] + +The file with the game session will either be created if it doesn't exist +or opened if it contains a valid pool. + +Controls: + move - arrow keys, jkli + place bomb - spacebar, b + quit - 'q' + resume - 'r' + +This game demonstrates the usage of the very basics of the libpmemobj C++ +bindings. It demonstrates pool management, persistent pointers and transactions. + +** DEPENDENCIES: ** +In order to build the game you need to install ncurses development package. + +rpm-based systems : ncurses-devel +dpkg-based systems: libncursesX-dev (where X is the API/ABI version) diff --git a/examples/pman/map b/examples/pman/map new file mode 100644 index 0000000..dc40294 --- /dev/null +++ b/examples/pman/map @@ -0,0 +1,40 @@ +######################################## +# # ## # # +# # ############ # ## # ############ # # +# # # # ## # # # # +# # ###### # # ###### # # +# # # # # # ## # # # # # +# ##### #### ## #### ##### # +# # # # ## # # # # +# # # ############ ############ # # # +# # # # # # # # +# # # # ######## ###### ######## # # # # +# # +# ####### ### ########### ### ######## # +# # ## # # +# ####### ######## ## ####### ######## # +# # ## # # +# # ############ # ## # ############ # # +# # # # # +# # ########## ##### #### ########## # # +# # # # . # # # # +# # # # # # # +# # ########## ########## ########## # # +# # # # # +# # ############ # ## # ############ # # +# # ## # # +# ####### ######## ## ####### ######## # +# # ## # # +# ####### ### ########### ### ######## # +# # +# # # # ######## ###### ######## # # # # +# # # # # # # # +# # # ############ ############ # # # +# # # # ## # # # # +# ##### #### ## #### ##### # +# # # # # # ## # # # # # +# # ###### # # ###### # # +# # # # ## # # # # +# # ############ # ## # ############ # # +# # ## # # +######################################## diff --git a/examples/pman/pman.cpp b/examples/pman/pman.cpp new file mode 100644 index 0000000..c001e21 --- /dev/null +++ b/examples/pman/pman.cpp @@ -0,0 +1,1240 @@ +/* + * Copyright 2016-2018, Intel Corporation + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * * Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +/* + * pman.cpp -- example usage of libpmemobj C++ bindings + */ + +#include +#include +#include +#include +#include +#ifdef __FreeBSD__ +#include /* Need pkg, not system, version */ +#else +#include +#endif +#include + +#define LAYOUT_NAME "pman" +#define SIZE 40 +#define MAX_SIZE 38 +#define MAX_BOMBS 5 +#define KEY_SPACE 32 +#define RAND_FIELD() (rand() % (SIZE - 2) + 1) +#define EXPLOSION_TIME 20 +#define EXPLOSION_COUNTER 80 +#define GAME_DELAY 40000 +#define SLEEP(t) \ + do { \ + struct timespec req = {0, (t)*1000}; \ + while (nanosleep(&req, &req) == -1 && errno == EINTR) \ + ; \ + } while (0) + +using pmem::obj::delete_persistent; +using pmem::obj::make_persistent; +using pmem::obj::p; +using pmem::obj::persistent_ptr; +using pmem::obj::pool; +using pmem::obj::pool_base; +using pmem::obj::transaction; + +namespace examples +{ + +class state; + +} /* namespace examples */ + +namespace +{ + +pool pop; +} + +namespace examples +{ + +enum position { + UP_LEFT, + UP_RIGHT, + DOWN_LEFT, + DOWN_RIGHT, + POS_MIDDLE, + POS_MAX, +}; + +enum direction { + DOWN, + RIGHT, + UP, + LEFT, + STOP, +}; + +enum field { + FREE, + FOOD, + WALL, + PLAYER, + ALIEN, + EXPLOSION, + BONUS, + LIFE, + BOMB, +}; + +class point { +public: + point() = default; + point(int xf, int yf); + point(position cor); + void move_back(); + void move_home(); + /* x component of object's position */ + p x; + /* y component of object's position */ + p y; + /* x component of object's previous position */ + p prev_x; + /* y component of object's previous position */ + p prev_y; + /* type of field of object */ + p cur_field; + /* type of field where object stood before */ + p prev_field; + +protected: + void move(); + /* direction in which object is moving */ + p dir; + +private: + /* starting position of the object */ + p home; +}; + +class bomb : public point { +public: + bomb(int xf, int yf); + void progress(); + void explosion(); + void print_time(); + /* flag determining is bomb exploded */ + p exploded; + /* flag determining is bomb used */ + p used; + +private: + /* counter determining where change of bomb state is necessary*/ + p timer; +}; + +typedef persistent_ptr> bomb_vec; + +class player : public point { +public: + player(position cor); + void progress(int in, bomb_vec *bombs); +}; + +class alien : public point { +public: + alien(position cor); + void progress(); + void move_back_alien(); + +private: + p rand_pos; +}; + +class intro : public point { +public: + intro(int x, int y, direction d); + void progress(); + +private: + /* random color in which object will be displayed*/ + p color; + /* number determining object's path on the board*/ + p num; +}; + +class board_state { +public: + board_state(const std::string &map_file); + ~board_state(); + void reset_params(); + void reset_board(); + void print(unsigned hs); + void reset(); + void dead(); + bool is_free(int x, int y); + void set_board_elm(persistent_ptr p); + void add_points(int x, int y); + bool is_last_alien_killed(int x, int y); + void set_explosion(int x, int y, field f); + void explosion(int x, int y, field f); + inline field + get_board_elm(int x, int y) + { + return board[y * SIZE + x]; + } + inline void + set_board_elm(int x, int y, field f) + { + board[y * SIZE + x] = f; + } + p level; /* number of level */ + p timer; /* measure time since game start */ + p n_aliens; /* number of not killed aliens */ + p highscore; /* score of the best game */ + p score; /* current score */ + p game_over; /* set true if game is over */ +private: + unsigned long shape(field f); + void set_bonus(field f); + void set_board(const std::string &map_file); + int find_wall(int x, int y, direction dir); + p life; /* number of lives left for player */ + persistent_ptr board; /* current state of board */ + persistent_ptr board_tmpl; /* board template loaded from file*/ +}; + +class state { +public: + state(); + bool init(const std::string &map_file); + void game(); + +private: + bool intro_loop(); + void print_start(); + void print_game_over(); + void new_game(const std::string &map_file); + void reset_game(); + void resume(); + void one_move(int in); + void collision(); + void reset(); + void next_level(); + void reset_bombs(); + bool is_collision(persistent_ptr p1, persistent_ptr p2); + /* pointer to player type object */ + persistent_ptr pl; + /* pointer to board state */ + persistent_ptr board; + /* pointer to vector of alien type objects */ + persistent_ptr> aliens; + /* pointer to vector of intro type objects */ + persistent_ptr> intro_p; + /* pointer to vector of bomb type objects */ + bomb_vec bombs; + /* the best score player has ever achieved */ + p highscore; +}; + +/* + * point::point -- overloaded constructor for point class + */ +point::point(int xf, int yf) + : x{xf}, + y{yf}, + prev_x{xf}, + prev_y{yf}, + cur_field{FREE}, + prev_field{FREE}, + dir{DOWN}, + home{UP_LEFT} {}; + +/* + * point::point -- overloaded constructor for point class + */ +point::point(position cor) + : x{0}, + y{0}, + prev_x{0}, + prev_y{0}, + cur_field{FREE}, + prev_field{FREE}, + dir{DOWN}, + home{cor} +{ + move_home(); +} + +/* + * point::move_home -- move object to it's home position + */ +void +point::move_home() +{ + prev_x = x; + prev_y = y; + + switch (home) { + case UP_LEFT: + x = 1; + y = 1; + break; + case UP_RIGHT: + x = MAX_SIZE; + y = 1; + break; + case DOWN_LEFT: + x = 1; + y = MAX_SIZE; + break; + case DOWN_RIGHT: + x = MAX_SIZE; + y = MAX_SIZE; + break; + case POS_MIDDLE: + x = MAX_SIZE / 2; + y = MAX_SIZE / 2; + break; + default: + break; + } +} + +/* + * point::move_back -- move object to it's previous position + */ +void +point::move_back() +{ + x = prev_x; + y = prev_y; +} + +/* + * point::move -- move object in proper direction + */ +void +point::move() +{ + int tmp_x = 0, tmp_y = 0; + switch (dir) { + case LEFT: + tmp_x = -1; + break; + case RIGHT: + tmp_x = 1; + break; + case UP: + tmp_y = -1; + break; + case DOWN: + tmp_y = 1; + break; + default: + break; + } + prev_x = x; + prev_y = y; + x = x + tmp_x; + y = y + tmp_y; +} + +/* + * intro::intro -- overloaded constructor for intro class + */ +intro::intro(int x, int y, direction d) : point(x, y) +{ + color = (field)(rand() % BOMB); + if (d == DOWN || d == LEFT) + num = y; + else + num = SIZE - y; + dir = d; +} + +/* + * intro::progress -- perform one move + */ +void +intro::progress() +{ + move(); + mvaddch(y, x * 2, COLOR_PAIR(color) | ACS_DIAMOND); + int max_size = SIZE - num; + if ((x == num && y == num) || (x == num && y == max_size) || + (x == max_size && y == num) || (x == max_size && y == max_size)) + dir = (direction)((dir + 1) % STOP); +} + +/* + * bomb::bomb -- overloaded constructor for bomb class + */ +bomb::bomb(int xf, int yf) : point(xf, yf) +{ + cur_field = BOMB; + exploded = false; + used = false; + timer = EXPLOSION_COUNTER; +} + +/* + * bomb::progress -- checks in which board_state is bomb + */ +void +bomb::progress() +{ + timer = timer - 1; + if (exploded == false && timer == 0) + explosion(); + else if (timer == 0) + used = true; +} + +/* + * bomb::explosion -- change board_state of bomb on exploded + */ +void +bomb::explosion() +{ + exploded = true; + timer = EXPLOSION_TIME; +} + +/* + * bomb::print_time -- print time to explosion + */ +void +bomb::print_time() +{ + if (!exploded) + mvprintw(y, x * 2, "%u", timer / 10); +} + +/* + * player::player -- overloaded constructor for player class + */ +player::player(position cor) : point(cor) +{ + cur_field = PLAYER; +} + +/* + * player::progress -- checks input from keyboard and sets proper direction + */ +void +player::progress(int in, bomb_vec *bombs) +{ + switch (in) { + case KEY_LEFT: + case 'j': + dir = LEFT; + break; + case KEY_RIGHT: + case 'l': + dir = RIGHT; + break; + case KEY_UP: + case 'i': + dir = UP; + break; + case KEY_DOWN: + case 'k': + dir = DOWN; + break; + case KEY_SPACE: + case 'b': + dir = STOP; + if ((*bombs)->size() <= MAX_BOMBS) + (*bombs)->push_back( + make_persistent(x, y)); + break; + } + move(); + dir = STOP; +} + +/* + * alien::alien -- overloaded constructor for alien class + */ +alien::alien(position cor) : point(cor), rand_pos(false) +{ + cur_field = ALIEN; + prev_field = FOOD; +} + +/* + * alien::progress -- rand and set direction and move alien + */ +void +alien::progress() +{ + if (rand_pos || rand() % 10 == 0) + dir = (direction)(rand() % STOP); + rand_pos = false; + move(); +} + +/* + * alien::move_back_alien -- move alien to previous position + */ +void +alien::move_back_alien() +{ + rand_pos = true; + move_back(); +} + +/* + * board_state -- constructor for class board_state initializes boards and + * needed variables + */ +board_state::board_state(const std::string &map_file) : highscore(0) +{ + reset_params(); + board = make_persistent(SIZE * SIZE); + board_tmpl = make_persistent(SIZE * SIZE); + for (int i = 0; i < SIZE * SIZE; ++i) + set_board_elm(i, 0, FREE); + set_board(map_file); +} + +board_state::~board_state() +{ + delete_persistent(board, SIZE * SIZE); + delete_persistent(board_tmpl, SIZE * SIZE); +} + +/* board_state::reset_params -- reset game parameters */ +void +board_state::reset_params() +{ + life = 3; + level = 1; + n_aliens = 1; + score = 0; + timer = 0; + game_over = false; +} + +/* board_state::reset_board -- reset board state from template */ +void +board_state::reset_board() +{ + for (auto i = 0; i < SIZE * SIZE; i++) + board[i] = board_tmpl[i]; + + set_bonus(BONUS); + set_bonus(LIFE); +} + +/* + * board_state::print -- print current board and information about game + */ +void +board_state::print(unsigned hs) +{ + for (int i = 0; i < SIZE; i++) { + for (int j = 0; j < SIZE; j++) { + if (get_board_elm(j, i) != FREE) + mvaddch(i, j * 2, shape(get_board_elm(j, i))); + } + } + if (score > hs) + highscore = score; + mvprintw(SIZE + 1, 0, + "Score: %d\t\tHighscore: %u\t\tLevel: %u\t Timer: %u", + (unsigned)score, (unsigned)highscore, (unsigned)level, + (unsigned)timer); + mvaddch(8, SIZE * 2 + 5, shape(FOOD)); + mvprintw(8, SIZE * 2 + 10, " +1 point"); + mvaddch(16, SIZE * 2 + 5, shape(BONUS)); + mvprintw(16, SIZE * 2 + 10, " +50 point"); + mvaddch(24, SIZE * 2 + 5, shape(ALIEN)); + mvprintw(24, SIZE * 2 + 10, " +100 point"); + mvaddch(32, SIZE * 2 + 5, shape(LIFE)); + mvprintw(32, SIZE * 2 + 10, " +1 life"); + + for (unsigned i = 0; i < life; i++) + mvaddch(SIZE + 3, static_cast(SIZE + life - i * 2), + shape(PLAYER)); +} + +/* + * board_state::dead -- executed when player lose life + */ +void +board_state::dead() +{ + life = life - 1; + if (life <= 0) { + game_over = true; + } +} + +/* + * board_state::reset -- clean board to start new level + */ +void +board_state::reset() +{ + reset_board(); + n_aliens = level; + timer = 0; +} + +/* + * board_state::is_free -- check whether field is free + */ +bool +board_state::is_free(int x, int y) +{ + return !(get_board_elm(x, y) == WALL || get_board_elm(x, y) == BOMB); +} + +/* + * board_state::add_points -- check type of field and give proper number of + * points + */ +void +board_state::add_points(int x, int y) +{ + switch (get_board_elm(x, y)) { + case FOOD: + score = score + 1; + break; + case BONUS: + score = score + 50; + set_bonus(BONUS); + break; + case LIFE: + if (life < 3) + life = life + 1; + set_bonus(LIFE); + break; + default: + break; + } +} + +/* + * board_state::is_last_alien_killed -- remove alien from board and check + * whether any other alien stayed on the board + */ +bool +board_state::is_last_alien_killed(int x, int y) +{ + set_board_elm(x, y, FREE); + n_aliens = n_aliens - 1; + score = score + 100; + if (n_aliens != 0) + return false; + level = level + 1; + return true; +} + +/* + * board_state::set_board_elm -- set object on its current position on the board + * and clean previous position + */ +void +board_state::set_board_elm(persistent_ptr p) +{ + set_board_elm(p->x, p->y, p->cur_field); + if (!(p->x == p->prev_x && p->y == p->prev_y)) + set_board_elm(p->prev_x, p->prev_y, p->prev_field); +} + +/* + * board_state::set_explosion --set exploded fields in proper way + */ +void +board_state::set_explosion(int x, int y, field f) +{ + field prev_f = get_board_elm(x, y); + if (prev_f == BONUS || prev_f == LIFE) + set_bonus(prev_f); + set_board_elm(x, y, f); +} + +/* + * board_state::explosion -- mark exploded fields as exploded or free + */ +void +board_state::explosion(int x, int y, field f) +{ + for (int i = find_wall(x, y, UP); i < find_wall(x, y, DOWN); i++) + set_explosion(x, i, f); + + for (int i = find_wall(x, y, LEFT); i < find_wall(x, y, RIGHT); i++) + set_explosion(i, y, f); +} + +/* + * board_state::shape -- assign proper shape to different types of fields + */ +unsigned long +board_state::shape(field f) +{ + auto color = COLOR_PAIR(f); + if (f == FOOD) + return color | ACS_BULLET; + else if (f == WALL || f == EXPLOSION) + return color | ACS_CKBOARD; + else + return color | ACS_DIAMOND; +} + +/* + * board_state::set_bonus -- find free field and set the bonus there + */ +void +board_state::set_bonus(field f) +{ + + int x, y; + x = RAND_FIELD(); + y = RAND_FIELD(); + while (get_board_elm(x, y) != FOOD && get_board_elm(x, y) != FREE) { + x = RAND_FIELD(); + y = RAND_FIELD(); + } + set_board_elm(x, y, f); +} + +/* + * board_state::set_board -- set board with initial values from file + */ +void +board_state::set_board(const std::string &map_file) +{ + std::ifstream board_file; + board_file.open(map_file.c_str()); + if (board_file.fail()) + assert(0); + char num; + for (int i = 0; i < SIZE; i++) { + for (int j = 0; j < SIZE; j++) { + board_file.get(num); + if (num == '#') + set_board_elm(j, i, WALL); + else if (num == ' ') + set_board_elm(j, i, FOOD); + else + set_board_elm(j, i, FREE); + } + board_file.get(num); + } + for (auto i = 0; i < SIZE * SIZE; i++) + board_tmpl[i] = board[i]; + + board_file.close(); + set_bonus(BONUS); + set_bonus(LIFE); +} + +/* + * board_state::find_wall -- finds first wall from given point in given + * direction + */ +int +board_state::find_wall(int x, int y, direction dir) +{ + switch (dir) { + case LEFT: { + for (int i = x; i >= 0; i--) { + if (get_board_elm(i, y) == WALL) + return i + 1; + } + break; + } + case RIGHT: { + for (int i = x; i <= SIZE; i++) { + if (get_board_elm(i, y) == WALL) + return i; + } + break; + } + case UP: { + for (int i = y; i >= 0; i--) { + if (get_board_elm(x, i) == WALL) + return i + 1; + } + break; + } + case DOWN: { + for (int i = y; i <= SIZE; i++) { + if (get_board_elm(x, i) == WALL) + return i; + } + break; + } + default: + break; + } + return 0; +} + +/* + * state::init -- initialize game + */ +bool +state::init(const std::string &map_file) +{ + int in; + if (board == nullptr || pl == nullptr) + new_game(map_file); + else { + while ((in = getch()) != 'y') { + mvprintw(SIZE / 4, SIZE / 4, + "Do you want to continue the game? [y/n]"); + if (in == 'n') { + resume(); + break; + } + } + if (in == 'y' && intro_p->size() == 0) + return false; + } + + { + transaction::manual tx(pop); + if (intro_p->size() == 0) { + for (int i = 0; i < SIZE / 4; i++) { + intro_p->push_back( + make_persistent(i, i, DOWN)); + intro_p->push_back(make_persistent( + SIZE - i, i, LEFT)); + intro_p->push_back(make_persistent( + i, SIZE - i, RIGHT)); + intro_p->push_back(make_persistent( + SIZE - i, SIZE - i, UP)); + } + } + transaction::commit(); + } + + if (intro_loop()) + return true; + + { + transaction::manual tx(pop); + intro_p->clear(); + transaction::commit(); + } + + return false; +} + +/* + * state::game -- process game loop + */ +void +state::game() +{ + int in; + while ((in = getch()) != 'q') { + SLEEP(GAME_DELAY); + erase(); + if (in == 'r') + resume(); + + if (!board->game_over) + one_move(in); + else + print_game_over(); + } +} + +/* + * state::intro_loop -- display intro an wait for user's reaction + */ +bool +state::intro_loop() +{ + int in; + while ((in = getch()) != 'q') { + print_start(); + unsigned i = 0; + persistent_ptr p; + { + transaction::manual tx(pop); + while ((p = intro_p->get(i++)) != nullptr) + p->progress(); + transaction::commit(); + } + SLEEP(GAME_DELAY); + if (in == 's') + return true; + } + return false; +} + +/* + * state::print_start -- print intro inscription + */ +void +state::print_start() +{ + erase(); + int x = static_cast(SIZE / 1.8); + int y = static_cast(SIZE / 2.5); + mvprintw(y + 0, x, "####### # # ####### # #"); + mvprintw(y + 1, x, "# # ## ## # # ## #"); + mvprintw(y + 2, x, "####### # # # # ####### # # #"); + mvprintw(y + 3, x, "# # # # # # # # #"); + mvprintw(y + 4, x, "# # # # # # ##"); + mvprintw(y + 8, x, " Press 's' to start "); + mvprintw(y + 9, x, " Press 'q' to quit "); +} + +/* + * state::print_game_over -- print game over inscription + */ +void +state::print_game_over() +{ + erase(); + int x = SIZE / 3; + int y = SIZE / 6; + mvprintw(y + 0, x, "####### ####### # # #######"); + mvprintw(y + 1, x, "# # # ## ## # "); + mvprintw(y + 2, x, "# ### ####### # # # # #### "); + mvprintw(y + 3, x, "# # # # # # # # "); + mvprintw(y + 4, x, "####### # # # # #######"); + + mvprintw(y + 6, x, "####### # # ####### #######"); + mvprintw(y + 7, x, "# # # # # # #"); + mvprintw(y + 8, x, "# # # # #### #######"); + mvprintw(y + 9, x, "# # # # # # # "); + mvprintw(y + 10, x, "####### # ####### # #"); + + mvprintw(y + 13, x, " Your final score is %u ", + (unsigned)board->score); + if (board->score == highscore) + mvprintw(y + 14, x, " YOU BET YOUR BEST SCORE! "); + mvprintw(y + 16, x, " Press 'q' to quit "); + mvprintw(y + 17, x, " Press 'r' to resume "); +} +/* + * state::new_game -- allocate board_state, player and aliens if root is empty + */ +void +state::new_game(const std::string &map_file) +{ + transaction::manual tx(pop); + + board = make_persistent(map_file); + pl = make_persistent(POS_MIDDLE); + intro_p = make_persistent>(); + bombs = make_persistent>(); + aliens = make_persistent>(); + aliens->push_back(make_persistent(UP_LEFT)); + + transaction::commit(); +} + +/* + * state::reset_game -- reset the game from the board template + */ +void +state::reset_game() +{ + transaction::manual tx(pop); + + board->reset_params(); + board->reset_board(); + pl = make_persistent(POS_MIDDLE); + intro_p = make_persistent>(); + bombs = make_persistent>(); + aliens = make_persistent>(); + aliens->push_back(make_persistent(UP_LEFT)); + + transaction::commit(); +} + +/* + * state::resume -- clean root pointer and start a new game + */ +void +state::resume() +{ + { + transaction::manual tx(pop); + delete_persistent(pl); + pl = nullptr; + + aliens->clear(); + delete_persistent>(aliens); + + bombs->clear(); + delete_persistent>(bombs); + + intro_p->clear(); + delete_persistent>(intro_p); + transaction::commit(); + } + + reset_game(); +} + +/* + * state::one_move -- process one round where every object moves one time + */ +void +state::one_move(int in) +{ + unsigned i = 0; + persistent_ptr a; + persistent_ptr b; + + transaction::manual tx(pop); + board->timer = board->timer + 1; + pl->progress(in, &bombs); + while ((a = aliens->get(i++)) != nullptr) + a->progress(); + i = 0; + while ((b = bombs->get(i++)) != nullptr) { + b->progress(); + if (b->exploded) + board->explosion(b->x, b->y, EXPLOSION); + if (b->used) { + board->explosion(b->x, b->y, FREE); + bombs->erase(--i); + } + } + collision(); + board->print(highscore); + highscore = board->highscore; + i = 0; + while ((b = bombs->get(i++)) != nullptr) + b->print_time(); + transaction::commit(); +} + +/* + * state::collision -- check for collisions between any two objects + */ +void +state::collision() +{ + unsigned i = 0; + persistent_ptr a; + persistent_ptr b; + while ((b = bombs->get(i++)) != nullptr) { + if (!b->exploded) { + if (board->get_board_elm(b->x, b->y) == EXPLOSION) + b->explosion(); + board->set_board_elm(b); + } + } + i = 0; + while ((a = aliens->get(i++)) != nullptr) { + if (board->get_board_elm(a->x, a->y) == EXPLOSION) { + bool is_over = board->is_last_alien_killed(a->prev_x, + a->prev_y); + aliens->erase(--i); + if (is_over) { + if (board->get_board_elm(pl->x, pl->y) == + EXPLOSION) + board->dead(); + next_level(); + return; + } + } + } + bool dead = false; + i = 0; + while ((a = aliens->get(i++)) != nullptr) { + + /*check collision alien with wall or bomb */ + if (!board->is_free(a->x, a->y)) + a->move_back_alien(); + + /*check collision alien with player */ + if (is_collision(pl, a)) + dead = true; + + /*check collision alien with alien */ + unsigned j = 0; + persistent_ptr a2; + while ((a2 = aliens->get(j++)) != nullptr) { + if (a != a2 && is_collision(a, a2)) { + a->move_back_alien(); + break; + } + } + field prev_f = board->get_board_elm(a->x, a->y); + board->set_board_elm(a); + if (prev_f != ALIEN && prev_f != PLAYER) + a->prev_field = prev_f; + } + if (!board->is_free(pl->x, pl->y)) + pl->move_back(); + + if (board->get_board_elm(pl->x, pl->y) == EXPLOSION || dead) { + board->dead(); + reset(); + return; + } + board->add_points(pl->x, pl->y); + board->set_board_elm(pl); + SLEEP(10000); +} + +/* + * state::reset -- move objects on their home positions + */ +void +state::reset() +{ + unsigned i = 0; + persistent_ptr a; + while ((a = aliens->get(i++)) != nullptr) { + a->move_home(); + board->set_board_elm(a); + } + pl->move_back(); + pl->move_home(); + board->set_board_elm(pl); + reset_bombs(); +} + +/* + * state::next_level -- clean board, create proper number of aliens and + * start new level + */ +void +state::next_level() +{ + reset_bombs(); + board->reset(); + for (unsigned i = 0; i < board->n_aliens; i++) + aliens->push_back(make_persistent( + (position)((UP_LEFT + i) % (POS_MAX - 1)))); + pl->move_home(); +} + +/* + * state::reset_bombs -- remove all bombs + */ +void +state::reset_bombs() +{ + unsigned i = 0; + persistent_ptr b; + while ((b = bombs->get(i++)) != nullptr) { + if (b->exploded) + board->explosion(b->x, b->y, FREE); + } + bombs->clear(); +} + +/* + * state::is_collision -- check if there is collision between given objects + */ +bool +state::is_collision(persistent_ptr p1, persistent_ptr p2) +{ + if (p1->x == p2->x && p1->y == p2->y) + return true; + else if (p1->prev_x == p2->x && p1->prev_y == p2->y && + p1->x == p2->prev_x && p1->y == p2->prev_y) + return true; + return false; +} + +} /* namespace examples */ + +namespace +{ + +void +print_usage(const std::string &binary) +{ + std::cout << "Usage:\n" << binary << " [map_file]\n"; +} +} + +int +main(int argc, char *argv[]) +{ + if (argc < 2 || argc > 3) { + print_usage(argv[0]); + return 1; + } + + std::string name = argv[1]; + std::string map_path = "map"; + + if (argc == 3) + map_path = argv[2]; + + int ret = -1; + try { + if (pool::check(name, LAYOUT_NAME) == 1) + pop = pool::open(name, LAYOUT_NAME); + else + pop = pool::create( + name, LAYOUT_NAME, PMEMOBJ_MIN_POOL * 2); + + initscr(); + start_color(); + init_pair(examples::FOOD, COLOR_YELLOW, COLOR_BLACK); + init_pair(examples::WALL, COLOR_WHITE, COLOR_BLACK); + init_pair(examples::PLAYER, COLOR_CYAN, COLOR_BLACK); + init_pair(examples::ALIEN, COLOR_RED, COLOR_BLACK); + init_pair(examples::EXPLOSION, COLOR_CYAN, COLOR_BLACK); + init_pair(examples::BONUS, COLOR_YELLOW, COLOR_BLACK); + init_pair(examples::LIFE, COLOR_MAGENTA, COLOR_BLACK); + nodelay(stdscr, true); + curs_set(0); + keypad(stdscr, true); + persistent_ptr r = pop.root(); + + if ((r != nullptr) && (r->init(map_path) != false)) + r->game(); + + endwin(); + pop.close(); + ret = 0; + } catch (pmem::transaction_error &err) { + std::cerr << err.what() << std::endl; + } catch (pmem::transaction_scope_error &tse) { + std::cerr << tse.what() << std::endl; + } catch (pmem::pool_error &pe) { + std::cerr << pe.what() << std::endl; + } catch (std::logic_error &le) { + std::cerr << le.what() << std::endl; + } + + return ret; +} diff --git a/examples/pmpong/Ball.cpp b/examples/pmpong/Ball.cpp new file mode 100644 index 0000000..db3a35d --- /dev/null +++ b/examples/pmpong/Ball.cpp @@ -0,0 +1,156 @@ +/* + * Copyright 2017-2018, Intel Corporation + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * * Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "Ball.hpp" +#include "Pool.hpp" + +Ball::Ball(int x, int y) +{ + this->x = x; + this->y = y; + velocity = pmem::obj::make_persistent(); + this->velocity->x = 0; + this->velocity->y = 0; +} + +Ball::~Ball() +{ + pmem::obj::transaction::run( + Pool::getGamePool()->getPoolToTransaction(), + [&] { pmem::obj::delete_persistent(velocity); }); +} + +void +Ball::move() +{ + setXY(this->x + (int)this->velocity->x, + this->y + (int)this->velocity->y); +} + +void +Ball::collisionWithWindow() +{ + if (this->y <= SCORE_VIEW_OFFSET + HORIZONAL_LINE_OFFSET || + this->y + getBallShape().getRadius() * 2 >= + WINDOW_HEIGHT - HORIZONAL_LINE_OFFSET) { + setVelocityY(velocity->y * -1); + } +} + +void +Ball::increaseVelocity() +{ + if (velocity->x < 0) { + setVelocityX(velocity->x - BALL_VELOCITY_INCREMENTING); + } else { + setVelocityX(velocity->x + BALL_VELOCITY_INCREMENTING); + } + if (velocity->y < 0) { + setVelocityY(velocity->y - BALL_VELOCITY_INCREMENTING); + + } else { + setVelocityY(velocity->y + BALL_VELOCITY_INCREMENTING); + } +} + +void +Ball::setX(int xArg) +{ + pmem::obj::transaction::run(Pool::getGamePool()->getPoolToTransaction(), + [&] { x = xArg; }); +} + +void +Ball::setY(int yArg) +{ + pmem::obj::transaction::run(Pool::getGamePool()->getPoolToTransaction(), + [&] { y = yArg; }); +} + +void +Ball::setVelocityX(float xArg) +{ + pmem::obj::transaction::run(Pool::getGamePool()->getPoolToTransaction(), + [&] { velocity->x = xArg; }); +} + +void +Ball::setVelocityY(float yArg) +{ + pmem::obj::transaction::run(Pool::getGamePool()->getPoolToTransaction(), + [&] { velocity->y = yArg; }); +} + +void +Ball::setXY(int xArg, int yArg) +{ + pmem::obj::transaction::run(Pool::getGamePool()->getPoolToTransaction(), + [&] { + x = xArg; + y = yArg; + }); +} + +void +Ball::init() +{ + setXY(WINDOW_WIDTH / 2, WINDOW_HEIGHT / 2); + setVelocityX(0); + setVelocityY(0); +} + +int +Ball::getX() +{ + return this->x; +} + +int +Ball::getY() +{ + return this->y; +} + +pmem::obj::persistent_ptr +Ball::getVelocity() +{ + return this->velocity; +} + +sf::CircleShape +Ball::getBallShape() +{ + sf::CircleShape shapeToRet; + shapeToRet.setRadius(BALL_SIZE); + shapeToRet.setPosition(sf::Vector2f((float)this->x, (float)this->y)); + return shapeToRet; +} diff --git a/examples/pmpong/Ball.hpp b/examples/pmpong/Ball.hpp new file mode 100644 index 0000000..56fa1e1 --- /dev/null +++ b/examples/pmpong/Ball.hpp @@ -0,0 +1,67 @@ +/* + * Copyright 2017-2018, Intel Corporation + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * * Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef LIBPMEMOBJ_CPP_EXAMPLES_PMPONG_BALL_HPP +#define LIBPMEMOBJ_CPP_EXAMPLES_PMPONG_BALL_HPP + +#include "GameConstants.hpp" +#include +#include +#include +#include + +class Ball { +public: + Ball(int x, int y); + ~Ball(); + + void move(); + void collisionWithWindow(); + void increaseVelocity(); + void setX(int xArg); + void setY(int yArg); + void setVelocityX(float xArg); + void setVelocityY(float yArg); + void setXY(int xArg, int yArg); + void init(); + int getX(); + int getY(); + pmem::obj::persistent_ptr getVelocity(); + sf::CircleShape getBallShape(); + +private: + pmem::obj::p x; + pmem::obj::p y; + pmem::obj::persistent_ptr velocity; +}; + +#endif /* LIBPMEMOBJ_CPP_EXAMPLES_PMPONG_BALL_HPP */ diff --git a/examples/pmpong/CMakeLists.txt b/examples/pmpong/CMakeLists.txt new file mode 100644 index 0000000..e79df8d --- /dev/null +++ b/examples/pmpong/CMakeLists.txt @@ -0,0 +1,59 @@ +# +# Copyright 2018, Intel Corporation +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# +# * Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# +# * Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in +# the documentation and/or other materials provided with the +# distribution. +# +# * Neither the name of the copyright holder nor the names of its +# contributors may be used to endorse or promote products derived +# from this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +cmake_minimum_required(VERSION 3.3) +project(pmpong CXX) + +set(CXX_STANDARD_REQUIRED ON) +set(CMAKE_CXX_STANDARD 11) + +include(FindThreads) + +find_package(PkgConfig QUIET) +if(PKG_CONFIG_FOUND) + pkg_check_modules(LIBPMEMOBJ++ REQUIRED libpmemobj++) + + pkg_check_modules(SFML REQUIRED sfml-all>=2.4) +else() + find_package(LIBPMEMOBJ++ REQUIRED) + + # SFML 2.5 has different cmake interface than <= 2.4 so previous versions are not supported + find_package(SFML 2.5 REQUIRED COMPONENTS graphics window system) + set(SFML_LIBRARIES sfml-graphics sfml-window sfml-system) +endif() + +link_directories(${LIBPMEMOBJ++_LIBRARY_DIRS}) + +add_executable(pmpong Ball.cpp GameController.cpp GameOverView.cpp + GameView.cpp MainGame.cpp MenuView.cpp Paddle.cpp + PongGameStatus.cpp Pool.cpp) +target_include_directories(pmpong PUBLIC ${SFML_INCLUDE_DIR} ${LIBPMEMOBJ++_INCLUDE_DIRS} .) +target_link_libraries(pmpong ${LIBPMEMOBJ++_LIBRARIES} ${CMAKE_THREAD_LIBS_INIT} ${SFML_LIBRARIES}) diff --git a/examples/pmpong/GameConstants.hpp b/examples/pmpong/GameConstants.hpp new file mode 100644 index 0000000..129788c --- /dev/null +++ b/examples/pmpong/GameConstants.hpp @@ -0,0 +1,87 @@ +/* + * Copyright 2017-2018, Intel Corporation + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * * Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef LIBPMEMOBJ_CPP_EXAMPLES_PMPONG_GAMECONSTANTS_HPP +#define LIBPMEMOBJ_CPP_EXAMPLES_PMPONG_GAMECONSTANTS_HPP + +#include +#include +#include +#include +#include +#include +#include +#include + +#define PADDLE_VELOCITY_PLAYER 4 +#define PADDLE_VELOCITY_COMPUTER 20 +#define WINDOW_HEIGHT 500 +#define WINDOW_WIDTH 700 +#define BALL_VELOCITY_INCREMENTING 0.2f +#define FRAMERATE_LIMIT 70 +#define PADDLE_HEIGHT 100 +#define PADDLE_WIDTH 12 +#define BALL_SIZE 7 +#define MENU_ITEMS 4 +#define POINTS_TO_WIN 10 +#define BALL_PLAYERS_SPEED 4.0f +#define BALL_COMPUTER_SPEED 11.0f +#define VERTICAL_LINE_OFFSET 15 +#define HORIZONAL_LINE_OFFSET 30 +#define LINE_THICKNESS 3 +#define SCORE_VIEW_OFFSET 20 +#define GAME_NAME "pmpong" +#define GAMEVIEW_SCORE_FONTSIZE 20 +#define MENUVIEW_ITEMS_FONTSIZE 30 +#define GAMEOVER_FONTSIZE 45 +#define MENUITEM_OFFSET 100 +#define GAMOVERVIEW_OFFSET 50 +#define LAYOUT_NAME "DEFAULT_LAYOUT_NAME" +#define DEFAULT_POOLFILE_NAME "DEFAULT_FILENAME" + +static inline std::string +readFontConf() +{ + static std::string path = ""; + std::ifstream file("fontConf"); + if (file.is_open()) { + getline(file, path); + } + return path; +} + +#ifndef _WIN32 +#define FONT_PATH readFontConf() +#else +#define FONT_PATH "C:/Windows/Fonts/Arial.ttf" +#endif +#endif /* LIBPMEMOBJ_CPP_EXAMPLES_PMPONG_GAMECONSTANTS_HPP */ diff --git a/examples/pmpong/GameController.cpp b/examples/pmpong/GameController.cpp new file mode 100644 index 0000000..2290d11 --- /dev/null +++ b/examples/pmpong/GameController.cpp @@ -0,0 +1,231 @@ +/* + * Copyright 2017-2018, Intel Corporation + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * * Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "GameController.hpp" +#include "Pool.hpp" + +GameController::GameController() +{ + gameStatus = pmem::obj::make_persistent(); +} + +GameController::~GameController() +{ + pmem::obj::transaction::run( + Pool::getGamePool()->getPoolToTransaction(), [&] { + pmem::obj::delete_persistent( + gameStatus); + }); +} + +void +GameController::gameLoop(bool isSimulation) +{ + sf::RenderWindow *gameWindow = new sf::RenderWindow( + sf::VideoMode(WINDOW_WIDTH, WINDOW_HEIGHT), GAME_NAME); + gameWindow->setFramerateLimit(FRAMERATE_LIMIT); + + sf::Font font; + if (!font.loadFromFile(FONT_PATH)) { + throw std::runtime_error("Cannot load font from file"); + } + + View *menuView = new MenuView(font); + View *gameView = new GameView(font); + View *gameOverView = new GameOverView(font); + + while (gameWindow->isOpen()) { + sf::Event event; + while (gameWindow->pollEvent(event)) { + if (event.type == sf::Event::Closed) + gameWindow->close(); + } + gameWindow->clear(); + if (isSimulation) { + if (gameStatus->getGameState() != + game_state::SIMULATE) { + resetGameStatus(); + gameStatus->setIsGameToResume(false); + gameStatus->setGameState(game_state::SIMULATE); + } + gameMatchSimulation(gameWindow, gameView); + } else { + if (gameStatus->getGameState() == game_state::MATCH) { + gameMatch(gameWindow, gameView); + } else if (gameStatus->getGameState() == + game_state::MENU) { + menu(gameWindow, menuView); + } else if (gameStatus->getGameState() == + game_state::SIMULATE) { + gameMatchSimulation(gameWindow, gameView); + } else if (gameStatus->getGameState() == + game_state::GAME_OVER) { + gameOver(gameWindow, gameOverView); + } + } + } + delete menuView; + delete gameView; + delete gameOverView; + delete gameWindow; +} + +void +GameController::gameOver(sf::RenderWindow *gameWindow, View *view) +{ + view->prepareView(*gameStatus); + view->displayView(gameWindow); + + sf::Event event; + while (gameWindow->pollEvent(event)) { + if (event.type == sf::Event::KeyPressed) { + switch (event.key.code) { + case sf::Keyboard::Return: + gameStatus->setIsGameToResume(false); + gameStatus->setGameState( + game_state::MENU); + break; + default: + break; + } + } + if (event.type == sf::Event::Closed) + gameWindow->close(); + } +} + +void +GameController::menu(sf::RenderWindow *gameWindow, View *view) +{ + view->prepareView(*gameStatus); + view->displayView(gameWindow); + + sf::Event event; + while (gameWindow->pollEvent(event)) { + if (event.type == sf::Event::KeyPressed) { + handleEventKeypress(event, gameWindow); + } + if (event.type == sf::Event::Closed) + gameWindow->close(); + } +} + +void +GameController::handleEventKeypress(sf::Event &event, + sf::RenderWindow *gameWindow) +{ + switch (event.key.code) { + case sf::Keyboard::Up: + gameStatus->setMenuItem( + gameStatus->getMenuItem() == 0 + ? MENU_ITEMS - 1 + : gameStatus->getMenuItem() - 1); + break; + case sf::Keyboard::Down: + gameStatus->setMenuItem( + (gameStatus->getMenuItem() + 1) % MENU_ITEMS); + break; + case sf::Keyboard::Return: + if (gameStatus->getMenuItem() == NEW_GAME) { + resetGameStatus(); + gameStatus->setIsGameToResume(true); + gameStatus->setGameState(game_state::MATCH); + } else if (gameStatus->getMenuItem() == RESUME && + gameStatus->getIsGameToResume()) { + gameStatus->setGameState(game_state::MATCH); + } else if (gameStatus->getMenuItem() == SIMULATION) { + resetGameStatus(); + gameStatus->setIsGameToResume(false); + gameStatus->setGameState(game_state::SIMULATE); + } else if (gameStatus->getMenuItem() == EXIT) { + gameWindow->close(); + } + break; + default: + break; + } +} + +void +GameController::gameMatch(sf::RenderWindow *gameWindow, View *view) +{ + if (sf::Keyboard::isKeyPressed(sf::Keyboard::Key::Space)) + gameStatus->startBall(BALL_PLAYERS_SPEED); + gameStatus->movePaddles(); + gameStatus->lookForCollisions(true); + gameStatus->actualizeStatus(); + + view->prepareView(*gameStatus); + view->displayView(gameWindow); + + if (gameStatus->score()) { + if (sf::Keyboard::isKeyPressed(sf::Keyboard::Key::Space)) + gameStatus->startBall(BALL_PLAYERS_SPEED); + } + if (gameStatus->checkIfAnyPlayerWon()) { + gameStatus->setGameState(game_state::GAME_OVER); + } else if (sf::Keyboard::isKeyPressed(sf::Keyboard::Key::Escape)) { + gameStatus->setGameState(game_state::MENU); + } +} + +void +GameController::gameMatchSimulation(sf::RenderWindow *gameWindow, View *view) +{ + gameStatus->startBall(BALL_COMPUTER_SPEED); + gameStatus->simulate(); + gameStatus->lookForCollisions(false); + gameStatus->actualizeStatus(); + if (gameStatus->score()) + gameStatus->startBall(BALL_COMPUTER_SPEED); + + view->prepareView(*gameStatus); + view->displayView(gameWindow); + + if (gameStatus->checkIfAnyPlayerWon()) { + gameStatus->setGameState(game_state::GAME_OVER); + } else if (sf::Keyboard::isKeyPressed(sf::Keyboard::Key::Escape)) { + gameStatus->setGameState(game_state::MENU); + } +} + +void +GameController::resetGameStatus() +{ + pmem::obj::transaction::run( + Pool::getGamePool()->getPoolToTransaction(), [&] { + pmem::obj::delete_persistent( + gameStatus); + gameStatus = + pmem::obj::make_persistent(); + }); +} diff --git a/examples/pmpong/GameController.hpp b/examples/pmpong/GameController.hpp new file mode 100644 index 0000000..dc4aa77 --- /dev/null +++ b/examples/pmpong/GameController.hpp @@ -0,0 +1,67 @@ +/* + * Copyright 2017-2018, Intel Corporation + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * * Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef LIBPMEMOBJ_CPP_EXAMPLES_PMPONG_GAMECONTROLLER_HPP +#define LIBPMEMOBJ_CPP_EXAMPLES_PMPONG_GAMECONTROLLER_HPP + +#include "GameConstants.hpp" +#include "GameOverView.hpp" +#include "GameView.hpp" +#include "MenuView.hpp" +#include "PongGameStatus.hpp" +#include +#include +#include +#include +#include + +class GameController { +public: + GameController(); + ~GameController(); + + void gameLoop(bool isSimulation = false); + +private: + pmem::obj::persistent_ptr gameStatus; + + void gameOver(sf::RenderWindow *gameWindow, View *view); + void menu(sf::RenderWindow *gameWindow, View *view); + void handleEventKeypress(sf::Event &event, + sf::RenderWindow *gameWindow); + void gameMatch(sf::RenderWindow *gameWindow, View *view); + void gameMatchSimulation(sf::RenderWindow *gameWindow, View *view); + + void resetGameStatus(); +}; + +#endif /* LIBPMEMOBJ_CPP_EXAMPLES_PMPONG_GAMECONTROLLER_HPP */ diff --git a/examples/pmpong/GameOverView.cpp b/examples/pmpong/GameOverView.cpp new file mode 100644 index 0000000..b788f46 --- /dev/null +++ b/examples/pmpong/GameOverView.cpp @@ -0,0 +1,80 @@ +/* + * Copyright 2017, Intel Corporation + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * * Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "GameOverView.hpp" + +GameOverView::GameOverView(sf::Font &font) +{ + gameOver.setString("GAME OVER"); + entContinue.setString("press ENTER to continue"); + playerWinner.setString(""); + gameOver.setFont(font); + playerWinner.setFont(font); + entContinue.setFont(font); + gameOver.setCharacterSize(GAMEOVER_FONTSIZE); + playerWinner.setCharacterSize(MENUVIEW_ITEMS_FONTSIZE); + entContinue.setCharacterSize(MENUVIEW_ITEMS_FONTSIZE); + gameOver.setPosition( + WINDOW_WIDTH / 2 - gameOver.getGlobalBounds().width / 2, 0); + playerWinner.setPosition( + WINDOW_WIDTH / 2 - playerWinner.getGlobalBounds().width / 2, + GAMOVERVIEW_OFFSET * 2); + entContinue.setPosition(WINDOW_WIDTH / 2 - + entContinue.getGlobalBounds().width / 2, + WINDOW_HEIGHT - GAMOVERVIEW_OFFSET); + gameOver.setFillColor(sf::Color::Red); + playerWinner.setFillColor(sf::Color::Green); + entContinue.setFillColor(sf::Color::White); +} + +GameOverView::~GameOverView() +{ +} + +void +GameOverView::prepareView(PongGameStatus &gameStatus) +{ + if (gameStatus.getPlayer1()->getPoints() == POINTS_TO_WIN) + playerWinner.setString("LEFT PLAYER WON!"); + else + playerWinner.setString("RIGHT PLAYER WON!"); +} + +void +GameOverView::displayView(sf::RenderWindow *gameWindow) +{ + gameWindow->clear(); + gameWindow->draw(gameOver); + gameWindow->draw(playerWinner); + gameWindow->draw(entContinue); + gameWindow->display(); +} diff --git a/examples/pmpong/GameOverView.hpp b/examples/pmpong/GameOverView.hpp new file mode 100644 index 0000000..f209c35 --- /dev/null +++ b/examples/pmpong/GameOverView.hpp @@ -0,0 +1,55 @@ +/* + * Copyright 2017-2018, Intel Corporation + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * * Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef LIBPMEMOBJ_CPP_EXAMPLES_PMPONG_GAMEOVERVIEW_HPP +#define LIBPMEMOBJ_CPP_EXAMPLES_PMPONG_GAMEOVERVIEW_HPP + +#include "GameConstants.hpp" +#include "PongGameStatus.hpp" +#include "View.hpp" +#include + +class GameOverView : public View { +public: + GameOverView(sf::Font &font); + ~GameOverView(); + + virtual void prepareView(PongGameStatus &gameStatus); + virtual void displayView(sf::RenderWindow *gameWindow); + +private: + sf::Text gameOver; + sf::Text playerWinner; + sf::Text entContinue; +}; + +#endif /* LIBPMEMOBJ_CPP_EXAMPLES_PMPONG_GAMEOVERVIEW_HPP */ diff --git a/examples/pmpong/GameView.cpp b/examples/pmpong/GameView.cpp new file mode 100644 index 0000000..edd3097 --- /dev/null +++ b/examples/pmpong/GameView.cpp @@ -0,0 +1,138 @@ +/* + * Copyright 2017-2018, Intel Corporation + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * * Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "GameView.hpp" + +GameView::GameView(sf::Font &font) +{ + sf::Color elementsColor(224, 224, 224); + scoreP1.setFont(font); + scoreP2.setFont(font); + scoreP1.setCharacterSize(GAMEVIEW_SCORE_FONTSIZE); + scoreP2.setCharacterSize(GAMEVIEW_SCORE_FONTSIZE); + + scoreP1.setPosition(WINDOW_WIDTH / 2 - SCORE_VIEW_OFFSET, + SCORE_VIEW_OFFSET); + scoreP2.setPosition(WINDOW_WIDTH / 2 + SCORE_VIEW_OFFSET - + scoreP2.getGlobalBounds().width, + SCORE_VIEW_OFFSET); + scoreP1.setFillColor(sf::Color::Green); + scoreP2.setFillColor(sf::Color::Green); + + upperLine.setPosition(VERTICAL_LINE_OFFSET, + scoreP1.getPosition().y + HORIZONAL_LINE_OFFSET); + upperLine.setSize(sf::Vector2f(WINDOW_WIDTH - 2 * VERTICAL_LINE_OFFSET, + LINE_THICKNESS)); + upperLine.setFillColor(elementsColor); + + downLine.setPosition(VERTICAL_LINE_OFFSET, + WINDOW_HEIGHT - HORIZONAL_LINE_OFFSET); + downLine.setSize(sf::Vector2f(WINDOW_WIDTH - 2 * VERTICAL_LINE_OFFSET + + LINE_THICKNESS, + LINE_THICKNESS)); + downLine.setFillColor(elementsColor); + + leftLine.setPosition(VERTICAL_LINE_OFFSET, + scoreP1.getPosition().y + HORIZONAL_LINE_OFFSET); + leftLine.setSize(sf::Vector2f( + LINE_THICKNESS, + WINDOW_HEIGHT - + (scoreP1.getPosition().y + 2 * HORIZONAL_LINE_OFFSET))); + leftLine.setFillColor(elementsColor); + + rightLine.setPosition(WINDOW_WIDTH - VERTICAL_LINE_OFFSET, + scoreP1.getPosition().y + HORIZONAL_LINE_OFFSET); + rightLine.setSize(sf::Vector2f( + LINE_THICKNESS, + WINDOW_HEIGHT - + (scoreP1.getPosition().y + 2 * HORIZONAL_LINE_OFFSET))); + rightLine.setFillColor(elementsColor); + + court.setPosition(VERTICAL_LINE_OFFSET + LINE_THICKNESS, + scoreP1.getPosition().y + HORIZONAL_LINE_OFFSET); + court.setSize(sf::Vector2f( + WINDOW_WIDTH - 2 * VERTICAL_LINE_OFFSET, + WINDOW_HEIGHT - + (scoreP1.getPosition().y + 2 * HORIZONAL_LINE_OFFSET))); + court.setFillColor(sf::Color(60, 132, 48)); + + ballShape.setRadius(BALL_SIZE); + ballShape.setPosition(sf::Vector2f(0, 0)); + ballShape.setFillColor(elementsColor); + + rightPaddleShape.setSize(sf::Vector2f(PADDLE_WIDTH, PADDLE_HEIGHT)); + leftPaddleShape.setSize(sf::Vector2f(PADDLE_WIDTH, PADDLE_HEIGHT)); + leftPaddleShape.setPosition(sf::Vector2f(0, 0)); + rightPaddleShape.setPosition(sf::Vector2f(0, 0)); + leftPaddleShape.setFillColor(sf::Color::Red); + rightPaddleShape.setFillColor(sf::Color::Red); +} + +GameView::~GameView() +{ +} + +void +GameView::prepareView(PongGameStatus &gameStatus) +{ + scoreP1.setString(std::to_string(gameStatus.getPlayer1()->getPoints())); + scoreP2.setString(std::to_string(gameStatus.getPlayer2()->getPoints())); + + ballShape.setPosition( + sf::Vector2f((float)gameStatus.getBall()->getX(), + (float)gameStatus.getBall()->getY())); + leftPaddleShape.setPosition( + sf::Vector2f((float)gameStatus.getPlayer1()->getX(), + (float)gameStatus.getPlayer1()->getY())); + rightPaddleShape.setPosition( + sf::Vector2f((float)gameStatus.getPlayer2()->getX(), + (float)gameStatus.getPlayer2()->getY())); +} + +void +GameView::displayView(sf::RenderWindow *gameWindow) +{ + gameWindow->clear(); + + gameWindow->draw(court); + gameWindow->draw(upperLine); + gameWindow->draw(leftLine); + gameWindow->draw(downLine); + gameWindow->draw(rightLine); + gameWindow->draw(scoreP1); + gameWindow->draw(scoreP2); + gameWindow->draw(ballShape); + gameWindow->draw(leftPaddleShape); + gameWindow->draw(rightPaddleShape); + + gameWindow->display(); +} diff --git a/examples/pmpong/GameView.hpp b/examples/pmpong/GameView.hpp new file mode 100644 index 0000000..047d78e --- /dev/null +++ b/examples/pmpong/GameView.hpp @@ -0,0 +1,65 @@ +/* + * Copyright 2017-2018, Intel Corporation + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * * Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef LIBPMEMOBJ_CPP_EXAMPLES_PMPONG_GAMEVIEW_HPP +#define LIBPMEMOBJ_CPP_EXAMPLES_PMPONG_GAMEVIEW_HPP + +#include "GameConstants.hpp" +#include "PongGameStatus.hpp" +#include "View.hpp" +#include +#include + +class GameView : public View { +public: + GameView(sf::Font &font); + ~GameView(); + + virtual void prepareView(PongGameStatus &gameStatus); + virtual void displayView(sf::RenderWindow *gameWindow); + +private: + sf::Text scoreP1; + sf::Text scoreP2; + + sf::RectangleShape upperLine; + sf::RectangleShape downLine; + sf::RectangleShape leftLine; + sf::RectangleShape rightLine; + sf::RectangleShape court; + + sf::CircleShape ballShape; + sf::RectangleShape leftPaddleShape; + sf::RectangleShape rightPaddleShape; +}; + +#endif /* LIBPMEMOBJ_CPP_EXAMPLES_PMPONG_GAMEVIEW_HPP */ diff --git a/examples/pmpong/MainGame.cpp b/examples/pmpong/MainGame.cpp new file mode 100644 index 0000000..42fc0a1 --- /dev/null +++ b/examples/pmpong/MainGame.cpp @@ -0,0 +1,80 @@ +/* + * Copyright 2017-2018, Intel Corporation + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * * Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "Pool.hpp" +#include +#include +#include +#include +#include + +int +main(int argc, char *argv[]) +{ + int exitCode = EXIT_FAILURE; + std::string mode = ""; + if (argc == 3) { + mode = argv[2]; + } + if (argc < 2 || argc > 3 || (argc == 3 && mode != "-s")) { + std::cout << "Usage: ./pmpong [options]" + << std::endl + << "Options: " << std::endl + << "-s, simulates game between 2 AI players" + << std::endl; + return exitCode; + } + std::string fileName = argv[1]; + try { + Pool *pool = Pool::getGamePoolFromFile(fileName); + pmem::obj::persistent_ptr gameController = + pool->getGameController(); + if (mode == "-s") + gameController->gameLoop(true); + else + gameController->gameLoop(); + delete pool; + exitCode = EXIT_SUCCESS; + } catch (pmem::transaction_error &err) { + std::cerr << err.what() << std::endl; + } catch (pmem::transaction_scope_error &tse) { + std::cerr << tse.what() << std::endl; + } catch (pmem::pool_error &pe) { + std::cerr << pe.what() << std::endl; + } catch (std::logic_error &le) { + std::cerr << le.what() << std::endl; + } catch (std::exception &exc) { + std::cerr << exc.what() << std::endl; + } + + return exitCode; +} diff --git a/examples/pmpong/MenuView.cpp b/examples/pmpong/MenuView.cpp new file mode 100644 index 0000000..160bf8c --- /dev/null +++ b/examples/pmpong/MenuView.cpp @@ -0,0 +1,78 @@ +/* + * Copyright 2017, Intel Corporation + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * * Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "MenuView.hpp" + +MenuView::MenuView(sf::Font &font) +{ + menuItems[NEW_GAME].setString("NEW GAME"); + menuItems[RESUME].setString("RESUME"); + menuItems[SIMULATION].setString("SIMULATION"); + menuItems[EXIT].setString("EXIT"); + for (int i = 0; i < MENU_ITEMS; i++) { + menuItems[i].setFont(font); + menuItems[i].setCharacterSize(MENUVIEW_ITEMS_FONTSIZE); + menuItems[i].setPosition( + WINDOW_WIDTH / 2 - + (float)menuItems[i].getGlobalBounds().width / 2, + (float)(i + 1) * MENUITEM_OFFSET - + MENUVIEW_ITEMS_FONTSIZE); + } +} + +MenuView::~MenuView() +{ +} + +void +MenuView::prepareView(PongGameStatus &gameStatus) +{ + for (int i = 0; i < MENU_ITEMS; i++) { + if (i == gameStatus.getMenuItem()) { + menuItems[i].setFillColor(sf::Color::Green); + } else if (i == RESUME && !gameStatus.getIsGameToResume()) { + menuItems[RESUME].setFillColor(sf::Color::White); + } else { + menuItems[i].setFillColor(sf::Color::Red); + } + } +} + +void +MenuView::displayView(sf::RenderWindow *gameWindow) +{ + gameWindow->clear(); + for (int i = 0; i < MENU_ITEMS; i++) { + gameWindow->draw(menuItems[i]); + } + gameWindow->display(); +} diff --git a/examples/pmpong/MenuView.hpp b/examples/pmpong/MenuView.hpp new file mode 100644 index 0000000..e93869b --- /dev/null +++ b/examples/pmpong/MenuView.hpp @@ -0,0 +1,55 @@ +/* + * Copyright 2017-2018, Intel Corporation + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * * Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef LIBPMEMOBJ_CPP_EXAMPLES_PMPONG_MENUVIEW_HPP +#define LIBPMEMOBJ_CPP_EXAMPLES_PMPONG_MENUVIEW_HPP + +#include "GameConstants.hpp" +#include "PongGameStatus.hpp" +#include "View.hpp" +#include + +enum menu_items { NEW_GAME, RESUME, SIMULATION, EXIT }; + +class MenuView : public View { +public: + MenuView(sf::Font &font); + ~MenuView(); + + virtual void prepareView(PongGameStatus &gameStatus); + virtual void displayView(sf::RenderWindow *gameWindow); + +private: + sf::Text menuItems[MENU_ITEMS]; +}; + +#endif /* LIBPMEMOBJ_CPP_EXAMPLES_PMPONG_MENUVIEW_HPP */ diff --git a/examples/pmpong/Paddle.cpp b/examples/pmpong/Paddle.cpp new file mode 100644 index 0000000..66a246c --- /dev/null +++ b/examples/pmpong/Paddle.cpp @@ -0,0 +1,153 @@ +/* + * Copyright 2017-2018, Intel Corporation + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * * Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "Paddle.hpp" +#include "Pool.hpp" + +Paddle::Paddle(int x, int y) +{ + this->x = x; + this->y = y; + this->points = 0; + init(); +} + +Paddle::~Paddle() +{ +} + +void +Paddle::moveUp(int velocity) +{ + if (!(this->y - velocity < + SCORE_VIEW_OFFSET + HORIZONAL_LINE_OFFSET + LINE_THICKNESS)) { + setY(this->y - velocity); + } else if (this->y - velocity < + SCORE_VIEW_OFFSET + HORIZONAL_LINE_OFFSET + LINE_THICKNESS) { + setY(SCORE_VIEW_OFFSET + HORIZONAL_LINE_OFFSET + + LINE_THICKNESS); + } +} + +void +Paddle::moveDown(int velocity) +{ + if (!(this->y + PADDLE_HEIGHT + velocity > + WINDOW_HEIGHT - HORIZONAL_LINE_OFFSET - LINE_THICKNESS)) { + setY(this->y + velocity); + } else if (this->y + PADDLE_HEIGHT + velocity > + WINDOW_HEIGHT - HORIZONAL_LINE_OFFSET - LINE_THICKNESS) { + setY(WINDOW_HEIGHT - HORIZONAL_LINE_OFFSET - PADDLE_HEIGHT); + } +} + +void +Paddle::addPoint() +{ + setPoints(points + 1); +} + +void +Paddle::init() +{ + setY(WINDOW_HEIGHT / 2 - (int)getPaddleShape().getSize().y / 2); +} + +void +Paddle::adjustPaddleYtoBall(Ball &ball) +{ + if (this->y > ball.getY()) + moveUp(PADDLE_VELOCITY_COMPUTER); + if (this->y + getPaddleShape().getGlobalBounds().height - + ball.getBallShape().getRadius() * 4 < + ball.getY()) + moveDown(PADDLE_VELOCITY_COMPUTER); +} + +void +Paddle::collisionWithBall(Ball &ball, bool increaseBallSpeed) +{ + if (ball.getBallShape().getGlobalBounds().intersects( + getPaddleShape().getGlobalBounds())) { + ball.setVelocityX(ball.getVelocity()->x * (-1)); + if (increaseBallSpeed) + ball.increaseVelocity(); + } +} + +int +Paddle::getX() +{ + return this->x; +} + +int +Paddle::getY() +{ + return this->y; +} + +int +Paddle::getPoints() +{ + return this->points; +} + +sf::RectangleShape +Paddle::getPaddleShape() +{ + sf::RectangleShape shapeToRet; + shapeToRet.setSize(sf::Vector2f(PADDLE_WIDTH, PADDLE_HEIGHT)); + shapeToRet.setPosition(sf::Vector2f((float)this->x, (float)this->y)); + return shapeToRet; +} + +void +Paddle::setPoints(int pointsArg) +{ + pmem::obj::transaction::run(Pool::getGamePool()->getPoolToTransaction(), + [&] { points = pointsArg; }); +} + +void +Paddle::setY(int yArg) +{ + pmem::obj::transaction::run(Pool::getGamePool()->getPoolToTransaction(), + [&] { y = yArg; }); +} + +void +Paddle::setX(int xArg) +{ + pmem::obj::transaction::run(Pool::getGamePool()->getPoolToTransaction(), + [&] { x = xArg; }); +} diff --git a/examples/pmpong/Paddle.hpp b/examples/pmpong/Paddle.hpp new file mode 100644 index 0000000..4755741 --- /dev/null +++ b/examples/pmpong/Paddle.hpp @@ -0,0 +1,73 @@ +/* + * Copyright 2017-2018, Intel Corporation + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * * Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef LIBPMEMOBJ_CPP_EXAMPLES_PMPONG_PADDLE_HPP +#define LIBPMEMOBJ_CPP_EXAMPLES_PMPONG_PADDLE_HPP + +#include "Ball.hpp" +#include "GameConstants.hpp" +#include +#include +#include +#include + +class Paddle { + +public: + Paddle(); + Paddle(int x, int y); + ~Paddle(); + + void moveUp(int velocity); + void moveDown(int velocity); + void addPoint(); + void init(); + void adjustPaddleYtoBall(Ball &ball); + void collisionWithBall(Ball &ball, bool increaseBallSpeed); + + int getX(); + int getY(); + int getPoints(); + + sf::RectangleShape getPaddleShape(); + +private: + pmem::obj::p y; + pmem::obj::p x; + pmem::obj::p points; + + void setPoints(int pointsArg); + void setY(int yArg); + void setX(int xArg); +}; + +#endif /* LIBPMEMOBJ_CPP_EXAMPLES_PMPONG_PADDLE_HPP */ diff --git a/examples/pmpong/PongGameStatus.cpp b/examples/pmpong/PongGameStatus.cpp new file mode 100644 index 0000000..3fdd951 --- /dev/null +++ b/examples/pmpong/PongGameStatus.cpp @@ -0,0 +1,216 @@ +/* + * Copyright 2017-2018, Intel Corporation + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * * Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "PongGameStatus.hpp" +#include "Pool.hpp" + +PongGameStatus::PongGameStatus() +{ + player1 = pmem::obj::make_persistent( + VERTICAL_LINE_OFFSET + LINE_THICKNESS, WINDOW_HEIGHT / 2); + player2 = pmem::obj::make_persistent( + WINDOW_WIDTH - VERTICAL_LINE_OFFSET - PADDLE_WIDTH, + WINDOW_HEIGHT / 2); + ball = pmem::obj::make_persistent(WINDOW_WIDTH / 2, + WINDOW_HEIGHT / 2); + menuItem = 0; + isGameToResume = false; + actualGameState = game_state::MENU; +} + +PongGameStatus::~PongGameStatus() +{ + pmem::obj::transaction::run( + Pool::getGamePool()->getPoolToTransaction(), [&] { + pmem::obj::delete_persistent(player1); + pmem::obj::delete_persistent(player2); + pmem::obj::delete_persistent(ball); + }); +} + +void +PongGameStatus::startBall(float ballSpeed) +{ + if (ball->getVelocity()->x == 0 && ball->getVelocity()->y == 0) { + float x = randomizeFloatValue(1.5, 2.0); + ball->setVelocityX(randomizeDirection() ? ballSpeed + : -ballSpeed); + ball->setVelocityY(randomizeDirection() ? x : -1 * x); + } +} + +void +PongGameStatus::reset() +{ + ball->init(); + player1->init(); + player2->init(); +} + +void +PongGameStatus::movePaddles() +{ + if (sf::Keyboard::isKeyPressed(sf::Keyboard::Key::W)) { + player1->moveUp(PADDLE_VELOCITY_PLAYER); + } + if (sf::Keyboard::isKeyPressed(sf::Keyboard::Key::S)) { + player1->moveDown(PADDLE_VELOCITY_PLAYER); + } + if (sf::Keyboard::isKeyPressed(sf::Keyboard::Key::Up)) { + player2->moveUp(PADDLE_VELOCITY_PLAYER); + } + if (sf::Keyboard::isKeyPressed(sf::Keyboard::Key::Down)) { + player2->moveDown(PADDLE_VELOCITY_PLAYER); + } +} + +void +PongGameStatus::lookForCollisions(bool increaseBallVelocity) +{ + player1->collisionWithBall(*ball, increaseBallVelocity); + player2->collisionWithBall(*ball, increaseBallVelocity); + ball->collisionWithWindow(); +} + +void +PongGameStatus::actualizeStatus() +{ + ball->move(); +} + +void +PongGameStatus::simulate() +{ + if (ball->getVelocity()->x > 0) + player2->adjustPaddleYtoBall(*ball); + if (ball->getVelocity()->x < 0) + player1->adjustPaddleYtoBall(*ball); +} + +void +PongGameStatus::setMenuItem(int numb) +{ + pmem::obj::transaction::run(Pool::getGamePool()->getPoolToTransaction(), + [&] { this->menuItem = numb; }); +} + +void +PongGameStatus::setIsGameToResume(bool isGameToRes) +{ + pmem::obj::transaction::run(Pool::getGamePool()->getPoolToTransaction(), + [&] { isGameToResume = isGameToRes; }); +} + +void +PongGameStatus::setGameState(game_state state) +{ + pmem::obj::transaction::run(Pool::getGamePool()->getPoolToTransaction(), + [&] { this->actualGameState = state; }); +} + +int +PongGameStatus::getMenuItem() +{ + return this->menuItem; +} + +float +PongGameStatus::randomizeFloatValue(float min, float max) +{ + return (min + 1) + + (((float)rand()) / (float)RAND_MAX) * (max - (min + 1)); +} + +bool +PongGameStatus::score() +{ + if (ball->getBallShape().getPosition().x > WINDOW_WIDTH - + VERTICAL_LINE_OFFSET + LINE_THICKNESS - + ball->getBallShape().getRadius() * 2) { + player1->addPoint(); + reset(); + return true; + } + if (ball->getBallShape().getPosition().x < + VERTICAL_LINE_OFFSET - LINE_THICKNESS) { + player2->addPoint(); + reset(); + return true; + } + return false; +} + +bool +PongGameStatus::checkIfAnyPlayerWon() +{ + if (getPlayer1()->getPoints() == POINTS_TO_WIN || + getPlayer2()->getPoints() == POINTS_TO_WIN) + return true; + return false; +} + +bool +PongGameStatus::randomizeDirection() +{ + static const int shift = static_cast(std::log2(RAND_MAX)); + return (rand() >> shift) & 1; +} + +bool +PongGameStatus::getIsGameToResume() +{ + return this->isGameToResume; +} + +pmem::obj::persistent_ptr +PongGameStatus::getPlayer1() +{ + return this->player1; +} + +pmem::obj::persistent_ptr +PongGameStatus::getPlayer2() +{ + return this->player2; +} + +pmem::obj::persistent_ptr +PongGameStatus::getBall() +{ + return this->ball; +} + +game_state +PongGameStatus::getGameState() +{ + return this->actualGameState; +} diff --git a/examples/pmpong/PongGameStatus.hpp b/examples/pmpong/PongGameStatus.hpp new file mode 100644 index 0000000..3d38b05 --- /dev/null +++ b/examples/pmpong/PongGameStatus.hpp @@ -0,0 +1,85 @@ +/* + * Copyright 2017-2018, Intel Corporation + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * * Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef LIBPMEMOBJ_CPP_EXAMPLES_PMPONG_PONGGAMESTATUS_HPP +#define LIBPMEMOBJ_CPP_EXAMPLES_PMPONG_PONGGAMESTATUS_HPP + +#include "Ball.hpp" +#include "GameConstants.hpp" +#include "Paddle.hpp" +#include +#include +#include +#include + +enum game_state { MATCH, MENU, GAME_OVER, SIMULATE }; + +class PongGameStatus { +public: + PongGameStatus(); + ~PongGameStatus(); + + void startBall(float ballSpeed); + void reset(); + void movePaddles(); + void lookForCollisions(bool increaseBallVelocity); + void actualizeStatus(); + void simulate(); + void setMenuItem(int numb); + void setIsGameToResume(bool isGameToRes); + void setGameState(game_state state); + + int getMenuItem(); + + float randomizeFloatValue(float min, float max); + + bool score(); + bool checkIfAnyPlayerWon(); + bool randomizeDirection(); + bool getIsGameToResume(); + + pmem::obj::persistent_ptr getPlayer1(); + pmem::obj::persistent_ptr getPlayer2(); + pmem::obj::persistent_ptr getBall(); + + game_state getGameState(); + +private: + pmem::obj::persistent_ptr player1; + pmem::obj::persistent_ptr player2; + pmem::obj::persistent_ptr ball; + + pmem::obj::p menuItem; + pmem::obj::p isGameToResume; + pmem::obj::p actualGameState; +}; +#endif /* LIBPMEMOBJ_CPP_EXAMPLES_PMPONG_PONGGAMESTATUS_HPP */ diff --git a/examples/pmpong/Pool.cpp b/examples/pmpong/Pool.cpp new file mode 100644 index 0000000..8f2c8b7 --- /dev/null +++ b/examples/pmpong/Pool.cpp @@ -0,0 +1,87 @@ +/* + * Copyright 2017-2018, Intel Corporation + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * * Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "Pool.hpp" + +Pool *Pool::pongPool = nullptr; + +Pool::Pool(const std::string &fileName) +{ + if (pmem::obj::pool::check(fileName, LAYOUT_NAME) == 1) { + pool = pmem::obj::pool::open(fileName, LAYOUT_NAME); + } else { + pool = pmem::obj::pool::create( + fileName, LAYOUT_NAME, PMEMOBJ_MIN_POOL * 6); + } +} + +Pool::~Pool() +{ + pool.close(); +} + +Pool * +Pool::getGamePoolFromFile(const std::string &fileName) +{ + if (pongPool == nullptr) + pongPool = new Pool(fileName); + return pongPool; +} + +Pool * +Pool::getGamePool() +{ + if (pongPool == nullptr) { + return getGamePoolFromFile(DEFAULT_POOLFILE_NAME); + } + return pongPool; +} + +pmem::obj::persistent_ptr +Pool::getGameController() +{ + pmem::obj::persistent_ptr root = pool.root(); + if (root != nullptr) { + if (root->gam == nullptr) + pmem::obj::transaction::run(pool, [&] { + root->gam = pmem::obj::make_persistent< + GameController>(); + }); + } + return root->gam; +} + +pmem::obj::pool & +Pool::getPoolToTransaction() +{ + return pool; +} diff --git a/examples/pmpong/Pool.hpp b/examples/pmpong/Pool.hpp new file mode 100644 index 0000000..1b02d6d --- /dev/null +++ b/examples/pmpong/Pool.hpp @@ -0,0 +1,66 @@ +/* + * Copyright 2017-2018, Intel Corporation + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * * Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef LIBPMEMOBJ_CPP_EXAMPLES_PMPONG_POOL_HPP +#define LIBPMEMOBJ_CPP_EXAMPLES_PMPONG_POOL_HPP + +#include "GameController.hpp" +#include +#include +#include +#include + +struct GameStruct { +public: + pmem::obj::persistent_ptr gam; +}; + +class Pool { + +public: + ~Pool(); + static Pool *getGamePoolFromFile(const std::string &fileName); + static Pool *getGamePool(); + pmem::obj::persistent_ptr getGameController(); + pmem::obj::pool &getPoolToTransaction(); + +private: + Pool(const std::string &name); + static Pool *pongPool; + + pmem::obj::pool pool; + + Pool(const Pool &); + Pool &operator=(const Pool &); +}; + +#endif /* LIBPMEMOBJ_CPP_EXAMPLES_PMPONG_POOL_HPP */ diff --git a/examples/pmpong/README b/examples/pmpong/README new file mode 100644 index 0000000..bad7f1f --- /dev/null +++ b/examples/pmpong/README @@ -0,0 +1,28 @@ +This directory contains an example application implemented using libpmemobj, +it's a game in which all the objects are stored on persistent memory. +This means that the game process can be safely killed and then resumed. + +To launch the game: + ./pmpong [mode] + +Mode option might be skipped if you want to run game with GUI or use + -s +to run game simulation. + +The file with the game session will either be created if it doesn't exist +or opened if it contains a valid pool. + +Controls: + move left paddle - up and down arrow keys + move right paddle - 'w' and 's' + pause - esc + start ball - space + +This game demonstrates the usage of the very basics of the libpmemobj C++ +bindings. It demonstrates pool management, persistent pointers and transactions. + +** DEPENDENCIES: ** +In order to build the game you need to have SFML 2.4+ installed. +rpm-based systems : sudo dnf install SFML-devel +dpkg-based systems: sudo apt-get install libsfml-dev + diff --git a/examples/pmpong/View.hpp b/examples/pmpong/View.hpp new file mode 100644 index 0000000..504fd3c --- /dev/null +++ b/examples/pmpong/View.hpp @@ -0,0 +1,47 @@ +/* + * Copyright 2017-2018, Intel Corporation + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * * Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef LIBPMEMOBJ_CPP_EXAMPLES_PMPONG_VIEW_HPP +#define LIBPMEMOBJ_CPP_EXAMPLES_PMPONG_VIEW_HPP + +#include "GameConstants.hpp" +#include "PongGameStatus.hpp" +#include + +class View { +public: + virtual ~View(){}; + virtual void prepareView(PongGameStatus &gameStatus) = 0; + virtual void displayView(sf::RenderWindow *gameWindow) = 0; +}; + +#endif /* LIBPMEMOBJ_CPP_EXAMPLES_PMPONG_VIEW_HPP */ diff --git a/examples/queue/CMakeLists.txt b/examples/queue/CMakeLists.txt new file mode 100644 index 0000000..a7d7f6d --- /dev/null +++ b/examples/queue/CMakeLists.txt @@ -0,0 +1,51 @@ +# +# Copyright 2018, Intel Corporation +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# +# * Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# +# * Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in +# the documentation and/or other materials provided with the +# distribution. +# +# * Neither the name of the copyright holder nor the names of its +# contributors may be used to endorse or promote products derived +# from this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +cmake_minimum_required(VERSION 3.3) +project(queue CXX) + +set(CXX_STANDARD_REQUIRED ON) +set(CMAKE_CXX_STANDARD 11) + +include(FindThreads) + +find_package(PkgConfig QUIET) +if(PKG_CONFIG_FOUND) + pkg_check_modules(LIBPMEMOBJ++ REQUIRED libpmemobj++) +else() + find_package(LIBPMEMOBJ++ REQUIRED) +endif() + +link_directories(${LIBPMEMOBJ++_LIBRARY_DIRS}) + +add_executable(queue queue.cpp) +target_include_directories(queue PUBLIC ${LIBPMEMOBJ++_INCLUDE_DIRS} . ..) +target_link_libraries(queue ${LIBPMEMOBJ++_LIBRARIES} ${CMAKE_THREAD_LIBS_INIT}) diff --git a/examples/queue/queue.cpp b/examples/queue/queue.cpp new file mode 100644 index 0000000..21d2bd2 --- /dev/null +++ b/examples/queue/queue.cpp @@ -0,0 +1,214 @@ +/* + * Copyright 2015-2018, Intel Corporation + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * * Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +/* + * queue.cpp -- queue example implemented using pmemobj cpp bindings + * + * Please see pmem.io blog posts for more details. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define LAYOUT "queue" + +namespace +{ + +/* available queue operations */ +enum queue_op { + UNKNOWN_QUEUE_OP, + QUEUE_PUSH, + QUEUE_POP, + QUEUE_SHOW, + + MAX_QUEUE_OP, +}; + +/* queue operations strings */ +const char *ops_str[MAX_QUEUE_OP] = {"", "push", "pop", "show"}; + +/* + * parse_queue_op -- parses the operation string and returns matching queue_op + */ +queue_op +parse_queue_op(const char *str) +{ + for (int i = 0; i < MAX_QUEUE_OP; ++i) + if (strcmp(str, ops_str[i]) == 0) + return (queue_op)i; + + return UNKNOWN_QUEUE_OP; +} +} + +using pmem::obj::delete_persistent; +using pmem::obj::make_persistent; +using pmem::obj::p; +using pmem::obj::persistent_ptr; +using pmem::obj::pool; +using pmem::obj::pool_base; +using pmem::obj::transaction; + +namespace examples +{ + +/* + * Persistent memory list-based queue + * + * A simple, not template based, implementation of queue using + * libpmemobj C++ API. It demonstrates the basic features of persistent_ptr<> + * and p<> classes. + */ +class pmem_queue { + + /* entry in the list */ + struct pmem_entry { + persistent_ptr next; + p value; + }; + +public: + /* + * Inserts a new element at the end of the queue. + */ + void + push(pool_base &pop, uint64_t value) + { + transaction::run(pop, [&] { + auto n = make_persistent(); + + n->value = value; + n->next = nullptr; + + if (head == nullptr && tail == nullptr) { + head = tail = n; + } else { + tail->next = n; + tail = n; + } + }); + } + + /* + * Removes the first element in the queue. + */ + uint64_t + pop(pool_base &pop) + { + uint64_t ret = 0; + transaction::run(pop, [&] { + if (head == nullptr) + transaction::abort(EINVAL); + + ret = head->value; + auto n = head->next; + + delete_persistent(head); + head = n; + + if (head == nullptr) + tail = nullptr; + }); + + return ret; + } + + /* + * Prints the entire contents of the queue. + */ + void + show(void) const + { + for (auto n = head; n != nullptr; n = n->next) + std::cout << n->value << std::endl; + } + +private: + persistent_ptr head; + persistent_ptr tail; +}; + +} /* namespace examples */ + +int +main(int argc, char *argv[]) +{ + if (argc < 3) { + std::cerr << "usage: " << argv[0] + << " file-name [push [value]|pop|show]" << std::endl; + return 1; + } + + const char *path = argv[1]; + + queue_op op = parse_queue_op(argv[2]); + + pool pop; + + if (file_exists(path) != 0) { + pop = pool::create( + path, LAYOUT, PMEMOBJ_MIN_POOL, CREATE_MODE_RW); + } else { + pop = pool::open(path, LAYOUT); + } + + auto q = pop.root(); + switch (op) { + case QUEUE_PUSH: + q->push(pop, std::stoull(argv[3])); + break; + case QUEUE_POP: + std::cout << q->pop(pop) << std::endl; + break; + case QUEUE_SHOW: + q->show(); + break; + default: + throw std::invalid_argument("invalid queue operation"); + } + + pop.close(); + + return 0; +} diff --git a/include/libpmemobj++/README.md b/include/libpmemobj++/README.md new file mode 100644 index 0000000..1dd83e7 --- /dev/null +++ b/include/libpmemobj++/README.md @@ -0,0 +1,82 @@ +C++ Bindings For libpmemobj {#mainpage} +=========================== + +This is the C++ API for libpmemobj. + +During the development of libpmemobj, many difficulties were encountered and +compromises were made to make the C API as much user-friendly as possible. This +is mostly due to the semantics of the C language. Since C++ is a more expressive +language, it was natural to try and bridge the gap using native C++ features. + +There are three main features of the C++ bindings: + - the `persistent_ptr<>` smart pointer, + - the `transaction`, which comes in two flavours - scoped and closure, + - the `p<>` property. + +The main issue with the C API is the generic PMEMoid and its typed counterpart, +the TOID. For them to be conveniently used in transactions, a large set of +macros has been defined. This made using the generic pointer easier, yet still +unintuitive. In C++, the `persistent_ptr<>` template makes it a lot easier +providing well known smart pointer semantics and built-in transactions support. + +The other drawback of the C API is the transaction semantics. Manual usage of +`setjmp` and `jmpbuf` is error prone, so they were once again wrapped in +macros. They themselves have issues with undefined values of automatic +variables (see the libpmemobj manpage for more details). The transactions +defined in the C++ bindings try to fix the inadequacies of their C counterparts. + +The `p<>`, which is called the _persistent property_, was designed with +seamless persistent memory integration in mind. It is designed to be used with +basic types within classes, to signify that these members in fact reside in +persistent memory and need to be handled appropriately. + +Please remember to take extra care when using _static class members_. They are +not stored in persistent memory, therefore their value will _not_ always be +consistent across subsequent executions or compilations of user applications. + +If you find any issues or have suggestion about these bindings please file an +issue in https://github.com/pmem/issues. There are also blog articles in +http://pmem.io/blog/ which you might find helpful. + +Have fun! +The PMDK team + +### Compiler notice ### +The C++ bindings require a C++11 compliant compiler, therefore the minimal +versions of GCC and Clang are 4.8.1 and 3.3 respectively. However the +pmem::obj::transaction::automatic class requires C++17, so +you need a more recent version for this to be available(GCC 6.1/Clang 3.7). +It is recommended to use these or newer versions of GCC or Clang. + +### Standard notice ### +Please note that the C++11 standard, section 3.8, states that a valid +non-trivially default constructible object (in other words, not plain old data) +must be properly constructed in the lifetime of the application. +Libpmemobj, or any shared memory solution for that matter, does not +strictly adhere to that constraint. + +We believe that in the future, languages that wish to support persistent memory +will need to alter their semantics to establish a defined behavior for objects +whose lifetimes exceed that of the application. In the meantime, the programs +that wish to use persistent memory will need to rely on compiler-defined +behavior. + +Our library, and by extension these bindings, have been extensively tested in +g++, clang++ and MSVC++ to make sure that our solution is safe to use and +practically speaking implementation defined. The only exception to this rule is +the use of polymorphic types, which are notably forbidden when using C++ +bindings. + +### Important classes/functions ### + + * Transactional allocations - make_persistent.hpp + * Transactional array allocations - make_persistent_array.hpp + * Atomic allocations - make_persistent_atomic.hpp + * Atomic array allocations - make_persistent_array_atomic.hpp + * Resides on persistent memory property - [p](@ref pmem::obj::p) + * Persistent smart pointer - [persistent_ptr](@ref pmem::obj::persistent_ptr) + * Persistent memory transactions - [transaction](@ref pmem::obj::transaction) + * Persistent memory resident mutex - [mutex](@ref pmem::obj::mutex) + * Persistent memory pool - [pool](@ref pmem::obj::pool) + * Persistent memory allocator - [allocator](@ref pmem::obj::allocator) + * Volatile resides on pmem property - [v](@ref pmem::obj::experimental::v) diff --git a/include/libpmemobj++/allocation_flag.hpp b/include/libpmemobj++/allocation_flag.hpp new file mode 100644 index 0000000..689268e --- /dev/null +++ b/include/libpmemobj++/allocation_flag.hpp @@ -0,0 +1,171 @@ +/* + * Copyright 2019, Intel Corporation + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * * Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +/** + * @file + * allocation_flag - defines flags which can be passed to make_persistent + */ + +#ifndef LIBPMEMOBJ_CPP_ALLOCATION_FLAG_HPP +#define LIBPMEMOBJ_CPP_ALLOCATION_FLAG_HPP + +#include + +namespace pmem +{ + +namespace obj +{ + +/** + * Type of flag which can be passed to make_persistent. + * + * Allowed flags are: + * - allocation_flag::class_id(id) - allocate the object from the allocation + * class with id equal to id. + * - allocation_flag::no_flush() - skip flush on commit. + * - allocation_flag::none() - do not change allocator behaviour. + * + * Flags can be combined with each other using operator|() + */ +struct allocation_flag { + /** + * Emplace constructor. + */ + allocation_flag(uint64_t val) : value(val) + { + } + + /** + * Allocate the object from the allocation class with id equal to id. + */ + static allocation_flag + class_id(uint64_t id) + { + return allocation_flag(POBJ_CLASS_ID(id)); + } + + /** + * Skip flush on commit. + */ + static allocation_flag + no_flush() + { + return allocation_flag(POBJ_XALLOC_NO_FLUSH); + } + + /** + * Do not change allocator behaviour. + */ + static allocation_flag + none() + { + return allocation_flag(0); + } + + /** + * Check if flag is set. + */ + bool + is_set(const allocation_flag &rhs) + { + return value & rhs.value; + } + + allocation_flag + operator|(const allocation_flag &rhs) + { + return allocation_flag(value | rhs.value); + } + + uint64_t value; +}; + +/** + * Type of flag which can be passed to make_persistent_atomic. + * + * Allowed flags are: + * - allocation_flag_atomic::class_id(id) - allocate the object from the + * allocation class with id equal to id. + * - allocation_flag_atomic::none() - do not change allocator behaviour. + * + * Flags can be combined with each other using operator|() + */ +struct allocation_flag_atomic { + /** + * Emplace constructor. + */ + allocation_flag_atomic(uint64_t val) : value(val) + { + } + + /** + * Allocate the object from the allocation class with id equal to id. + */ + static allocation_flag_atomic + class_id(uint64_t id) + { + return allocation_flag_atomic(POBJ_CLASS_ID(id)); + } + + /** + * Do not change allocator behaviour. + */ + static allocation_flag_atomic + none() + { + return allocation_flag_atomic(0); + } + + /** + * Check if flag is set. + */ + bool + is_set(const allocation_flag_atomic &rhs) + { + return value & rhs.value; + } + + allocation_flag_atomic + operator|(const allocation_flag_atomic &rhs) + { + return allocation_flag_atomic(value | rhs.value); + } + + uint64_t value; +}; + +} /* namespace obj */ + +} /* namespace pmem */ + +#endif /* LIBPMEMOBJ_CPP_ALLOCATION_FLAG_HPP */ diff --git a/include/libpmemobj++/allocator.hpp b/include/libpmemobj++/allocator.hpp new file mode 100644 index 0000000..7b4e19d --- /dev/null +++ b/include/libpmemobj++/allocator.hpp @@ -0,0 +1,525 @@ +/* + * Copyright 2016-2018, Intel Corporation + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * * Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +/** + * @file + * Persistent memory aware allocator. (EXPERIMENTAL) + */ + +#ifndef LIBPMEMOBJ_CPP_ALLOCATOR_HPP +#define LIBPMEMOBJ_CPP_ALLOCATOR_HPP + +#include +#include +#include +#include +#include +#include + +namespace pmem +{ + +namespace obj +{ + +/** + * Encapsulates object specific allocator functionality. Designed to be used + * with C++ allocators. Can be specialized if necessary. + */ +template +class object_traits { +public: + /* + * Important typedefs. + */ + using value_type = T; + using pointer = persistent_ptr; + using const_pointer = persistent_ptr; + using reference = value_type &; + using const_reference = const value_type &; + + /** + * Rebind to a different type. + */ + template + struct rebind { + using other = object_traits; + }; + + /** + * Defaulted constructor. + */ + object_traits() = default; + + /** + * Defaulted destructor. + */ + ~object_traits() = default; + + /** + * Type converting constructor. + */ + template ::value>::type> + explicit object_traits(object_traits const &) + { + } + + /** + * Create an object at a specific address. + * + * This should be called only within a transaction. + * + * @param[in] p the pointer to where the object will be constructed. + * @param[in] t the object reference for copy construction. + */ + void + construct(pointer p, const_reference t) + { + /* construct called on newly allocated objects */ + detail::conditional_add_to_tx(p.get()); + new (static_cast(p.get())) value_type(t); + } + + /** + * Create an object at a specific address. + * + * This should be called only within a transaction. + * + * @param[in] p the pointer to where the object will be constructed. + * @param[in] args parameters passed to the object's constructor. + */ + template + void + construct(pointer p, Args &&... args) + { + detail::conditional_add_to_tx(p.get()); + new (static_cast(p.get())) + value_type(std::forward(args)...); + } + + /** + * Destroy an object based on a pointer. + * + * This should be called only within a transaction. + * + * @param[in] p the pointer to the object to be destroyed. + */ + void + destroy(pointer p) + { + /* XXX should we allow modifications outside of tx? */ + if (pmemobj_tx_stage() == TX_STAGE_WORK) { + pmemobj_tx_add_range_direct((void *)p.get(), sizeof(p)); + } + + detail::destroy(*p); + } +}; + +/** + * Object traits specialization for the void type. Designed to be used + * with C++ allocators. Can be specialized if necessary. + */ +template <> +class object_traits { +public: + /* + * Important typedefs. + */ + using value_type = void; + using pointer = persistent_ptr; + + /** + * Rebind to a different type. + */ + template + struct rebind { + using other = object_traits; + }; + + /** + * Defaulted constructor. + */ + object_traits() = default; + + /** + * Defaulted destructor. + */ + ~object_traits() = default; + + /** + * Type converting constructor. + */ + template + explicit object_traits(object_traits const &) + { + } +}; + +/** + * The allocation policy template for a given type. + * + * Can be specialized for a given type. Designed to be used with C++ allocators. + * Can be specialized if necessary. + */ +template +class standard_alloc_policy { +public: + /* + * Important typedefs. + */ + using value_type = T; + using pointer = persistent_ptr; + using const_void_pointer = persistent_ptr; + using size_type = std::size_t; + using bool_type = bool; + + /** + * Rebind to a different type. + */ + template + struct rebind { + using other = standard_alloc_policy; + }; + + /** + * Defaulted constructor. + */ + standard_alloc_policy() = default; + + /** + * Defaulted destructor. + */ + ~standard_alloc_policy() = default; + + /** + * Explicit copy constructor. + */ + explicit standard_alloc_policy(standard_alloc_policy const &) + { + } + + /** + * Type converting constructor. + */ + template ::value>::type> + explicit standard_alloc_policy(standard_alloc_policy const &) + { + } + + /** + * Allocate storage for cnt objects of type T. Does not construct the + * objects. + * + * @param[in] cnt the number of objects to allocate memory for. + * + * @throw transaction_scope_error if called outside of a transaction. + */ + pointer + allocate(size_type cnt, const_void_pointer = 0) + { + if (pmemobj_tx_stage() != TX_STAGE_WORK) + throw transaction_scope_error( + "refusing to allocate memory outside of transaction scope"); + + /* allocate raw memory, no object construction */ + return pmemobj_tx_alloc(sizeof(value_type) * cnt, + detail::type_num()); + } + + /** + * Deallocates storage pointed to p, which must be a value returned by + * a previous call to allocate that has not been invalidated by an + * intervening call to deallocate. + * + * @param[in] p pointer to the memory to be deallocated. + */ + void + deallocate(pointer p, size_type = 0) + { + if (pmemobj_tx_stage() != TX_STAGE_WORK) + throw transaction_scope_error( + "refusing to free memory outside of transaction scope"); + + if (pmemobj_tx_free(*p.raw_ptr()) != 0) + throw transaction_free_error( + "failed to delete persistent memory object"); + } + + /** + * The largest value that can meaningfully be passed to allocate(). + * + * @return largest value that can be passed to allocate. + */ + size_type + max_size() const + { + return PMEMOBJ_MAX_ALLOC_SIZE / sizeof(value_type); + } +}; + +/** + * Void specialization of the standard allocation policy. + */ +template <> +class standard_alloc_policy { +public: + /* + * Important typedefs. + */ + using value_type = void; + using pointer = persistent_ptr; + using const_pointer = persistent_ptr; + using reference = value_type; + using const_reference = const value_type; + using size_type = std::size_t; + using bool_type = bool; + + /** + * Rebind to a different type. + */ + template + struct rebind { + using other = standard_alloc_policy; + }; + + /** + * Defaulted constructor. + */ + standard_alloc_policy() = default; + + /** + * Defaulted destructor. + */ + ~standard_alloc_policy() = default; + + /** + * Explicit copy constructor. + */ + explicit standard_alloc_policy(standard_alloc_policy const &) + { + } + + /** + * Type converting constructor. + */ + template + explicit standard_alloc_policy(standard_alloc_policy const &) + { + } + + /** + * Allocate storage for cnt bytes. Assumes sizeof(void) = 1. + * + * @param[in] cnt the number of bytes to be allocated. + * + * @throw transaction_scope_error if called outside of a transaction. + */ + pointer + allocate(size_type cnt, const_pointer = 0) + { + if (pmemobj_tx_stage() != TX_STAGE_WORK) + throw transaction_scope_error( + "refusing to allocate memory outside of transaction scope"); + + /* allocate raw memory, no object construction */ + return pmemobj_tx_alloc(1 /* void size */ * cnt, 0); + } + + /** + * Deallocates storage pointed to p, which must be a value returned by + * a previous call to allocate that has not been invalidated by an + * intervening call to deallocate. + * + * @param[in] p pointer to the memory to be deallocated. + */ + void + deallocate(pointer p, size_type = 0) + { + if (pmemobj_tx_stage() != TX_STAGE_WORK) + throw transaction_scope_error( + "refusing to free memory outside of transaction scope"); + + if (pmemobj_tx_free(p.raw()) != 0) + throw transaction_free_error( + "failed to delete persistent memory object"); + } + + /** + * The largest value that can meaningfully be passed to allocate(). + * + * @return largest value that can be passed to allocate. + */ + size_type + max_size() const + { + return PMEMOBJ_MAX_ALLOC_SIZE; + } +}; + +/** + * Determines if memory from another allocator can be deallocated from this one. + * + * @return true. + */ +template +inline bool +operator==(standard_alloc_policy const &, standard_alloc_policy const &) +{ + return true; +} + +/** + * Determines if memory from another allocator can be deallocated from this one. + * + * @return false. + */ +template +inline bool +operator==(standard_alloc_policy const &, OtherAllocator const &) +{ + return false; +} + +/** + * (EXPERIMENTAL) Encapsulates the information about the persistent + * memory allocation model using PMDK's libpmemobj. This information includes + * the knowledge of the pointer type, their difference type, the type of the + * size of objects in this allocation model as well as memory allocation and + * deallocation primitives. + */ +template , + typename Traits = object_traits> +class allocator : public Policy, public Traits { +private: + /* + * private typedefs + */ + using AllocationPolicy = Policy; + using TTraits = Traits; + +public: + /* + * Important typedefs. + */ + using size_type = typename AllocationPolicy::size_type; + using pointer = typename AllocationPolicy::pointer; + using value_type = typename AllocationPolicy::value_type; + + /** + * Rebind to a different type. + */ + template + struct rebind { + using other = allocator< + U, typename AllocationPolicy::template rebind::other, + typename TTraits::template rebind::other>; + }; + + /** + * Defaulted constructor. + */ + allocator() = default; + + /** + * Defaulted destructor. + */ + ~allocator() = default; + + /** + * Explicit copy constructor. + */ + explicit allocator(allocator const &rhs) : Policy(rhs), Traits(rhs) + { + } + + /** + * Type converting constructor. + */ + template + explicit allocator(allocator const &) + { + } + + /** + * Type converting constructor. + */ + template + explicit allocator(allocator const &rhs) + : Policy(rhs), Traits(rhs) + { + } +}; + +/** + * Determines if memory from another allocator can be deallocated from this one. + * + * @param[in] lhs left hand side allocator. + * @param[in] rhs right hand side allocator. + * + * @return true if allocators are equivalent in terms of deallocation, false + * otherwise. + */ +template +inline bool +operator==(const allocator &lhs, const allocator &rhs) +{ + return operator==(static_cast(lhs), + static_cast(rhs)); +} + +/** + * Determines if memory from another allocator can be deallocated from this one. + * + * @param[in] lhs left hand side allocator. + * @param[in] rhs right hand side allocator. + * + * @return false if allocators are equivalent in terms of deallocation, true + * otherwise. + */ +template +inline bool +operator!=(const allocator &lhs, const OtherAllocator &rhs) +{ + return !operator==(lhs, rhs); +} + +} /* namespace obj */ + +} /* namespace pmem */ + +#endif /* LIBPMEMOBJ_CPP_ALLOCATOR_HPP */ diff --git a/include/libpmemobj++/condition_variable.hpp b/include/libpmemobj++/condition_variable.hpp new file mode 100644 index 0000000..8c8ea9f --- /dev/null +++ b/include/libpmemobj++/condition_variable.hpp @@ -0,0 +1,581 @@ +/* + * Copyright 2016-2018, Intel Corporation + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * * Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +/** + * @file + * Pmem-resident condition variable. + */ + +#ifndef LIBPMEMOBJ_CPP_CONDVARIABLE_HPP +#define LIBPMEMOBJ_CPP_CONDVARIABLE_HPP + +#include +#include + +#include +#include +#include + +namespace pmem +{ + +namespace obj +{ + +/** + * Persistent memory resident condition variable. + * + * This class is an implementation of a PMEM-resident condition + * variable which mimics in behavior the C++11 std::condition_variable. The + * typical usage example would be: + * @snippet doc_snippets/mutex.cpp cond_var_example + */ +class condition_variable { + typedef std::chrono::system_clock clock_type; + +public: + /** The handle typedef to the underlying basic type. */ + typedef PMEMcond *native_handle_type; + + /** + * Default constructor. + * + * @throw lock_error when the condition_variable is not from persistent + * memory. + */ + condition_variable() + { + PMEMobjpool *pop; + if ((pop = pmemobj_pool_by_ptr(&pcond)) == nullptr) + throw lock_error( + 1, std::generic_category(), + "Persistent condition variable not from persistent memory."); + + pmemobj_cond_zero(pop, &pcond); + } + + /** + * Defaulted destructor. + */ + ~condition_variable() = default; + + /** + * Notify and unblock one thread waiting on `*this` condition. + * + * Does nothing when no threads are waiting. It is unspecified + * which thread is selected for unblocking. + * + * @throw lock_error when the signal fails on the #pcond. + */ + void + notify_one() + { + PMEMobjpool *pop = pmemobj_pool_by_ptr(this); + if (int ret = pmemobj_cond_signal(pop, &this->pcond)) + throw lock_error( + ret, std::system_category(), + "Error notifying one on a condition variable."); + } + + /** + * Notify and unblock all threads waiting on `*this` condition. + * + * Does nothing when no threads are waiting. + */ + void + notify_all() + { + PMEMobjpool *pop = pmemobj_pool_by_ptr(this); + if (int ret = pmemobj_cond_broadcast(pop, &this->pcond)) + throw lock_error( + ret, std::system_category(), + "Error notifying all on a condition variable."); + } + + /** + * Makes the current thread block until the condition variable + * is notified or it is woken up by some other measure. + * + * This releases the lock, blocks the current thread and adds + * it to the list of threads waiting on `*this` condition + * variable. The lock needs to be acquired and owned by the + * calling thread. The lock is automatically reacquired after + * the call to wait. + * + * @param[in,out] lock a PMEM-resident obj::mutex. + * + * @throw lock_error when unlocking the lock or waiting on + * #pcond fails. + */ + void + wait(mutex &lock) + { + this->wait_impl(lock); + } + + /** + * Makes the current thread block until the condition variable + * is notified or it is woken up by some other measure. + * + * This releases the lock, blocks the current thread and adds + * it to the list of threads waiting on `*this` condition + * variable. The lock needs to be acquired and owned by the + * calling thread. The lock is automatically reacquired after + * the call to wait. + * + * @param[in,out] lock a Lock object which meets the + * BasicLockableConcept. Needs to be based on a PMEM-resident + * obj::mutex. + * + * @throw lock_error when unlocking the lock or waiting + * on #pcond fails. + */ + template + void + wait(Lock &lock) + { + this->wait_impl(*lock.mutex()); + } + + /** + * Makes the current thread block until the condition variable + * is notified. + * + * This releases the lock, blocks the current thread and adds + * it to the list of threads waiting on `*this` condition + * variable. The lock needs to be acquired and owned by the + * calling thread. The lock is automatically reacquired after + * the call to wait. + * This version is immune to spurious wake ups due to the + * provided predicate. + * + * @param[in,out] lock a PMEM-resident obj::mutex. + * @param[in] pred predicate which returns `false` if waiting is + * to be continued. + * + * @throw lock_error when unlocking the lock or waiting on + * #pcond fails. + */ + template + void + wait(mutex &lock, Predicate pred) + { + this->wait_impl(lock, std::move(pred)); + } + + /** + * Makes the current thread block until the condition variable + * is notified. + * + * This releases the lock, blocks the current thread and adds + * it to the list of threads waiting on `*this` condition + * variable. The lock needs to be acquired and owned by the + * calling thread. The lock is automatically reacquired after + * the call to wait. + * This version is immune to spurious wake ups due to the + * provided predicate. + * + * @param[in,out] lock a Lock object which meets the + * BasicLockableConcept. Needs to be based on a PMEM-resident + * obj::mutex. + * @param[in] pred predicate which returns `false` if waiting is + * to be continued. + * + * @throw lock_error when unlocking the lock or waiting on + * #pcond fails. + */ + template + void + wait(Lock &lock, Predicate pred) + { + this->wait_impl(*lock.mutex(), std::move(pred)); + } + + /** + * Makes the current thread block until the condition variable + * is notified, a specific time is reached or it is woken up by + * some other measure. + * + * This releases the lock, blocks the current thread and adds + * it to the list of threads waiting on `*this` condition + * variable. The lock needs to be acquired and owned by the + * calling thread. The lock is automatically reacquired after + * the call to wait. + * + * @param[in,out] lock a PMEM-resident obj::mutex. + * @param[in] timeout a specific point in time, which when + * reached unblocks the thread. + * + * @return std::cv_status::timeout on timeout, + * std::cv_status::no_timeout otherwise. + * + * @throw lock_error when unlocking the lock or waiting on + * #pcond fails. + */ + template + std::cv_status + wait_until(mutex &lock, + const std::chrono::time_point &timeout) + { + return this->wait_until_impl(lock, timeout); + } + + /** + * Makes the current thread block until the condition variable + * is notified, a specific time is reached or it is woken up by + * some other measure. + * + * This releases the lock, blocks the current thread and adds + * it to the list of threads waiting on `*this` condition + * variable. The lock needs to be acquired and owned by the + * calling thread. The lock is automatically reacquired after + * the call to wait. + * + * @param[in,out] lock a Lock object which meets the + * BasicLockableConcept. Needs to be based on a PMEM-resident + * obj::mutex. + * @param[in] timeout a specific point in time, which when + * reached unblocks the thread. + * + * @return std::cv_status::timeout on timeout, + * std::cv_status::no_timeout otherwise. + * + * @throw lock_error when unlocking the lock or waiting on + * #pcond fails. + */ + template + std::cv_status + wait_until(Lock &lock, + const std::chrono::time_point &timeout) + { + return this->wait_until_impl(*lock.mutex(), timeout); + } + + /** + * Makes the current thread block until the condition variable + * is notified or a specific time is reached. + * + * This releases the lock, blocks the current thread and adds + * it to the list of threads waiting on `*this` condition + * variable. The lock needs to be acquired and owned by the + * calling thread. The lock is automatically reacquired after + * the call to wait. + * + * @param[in,out] lock a PMEM-resident obj::mutex. + * @param[in] timeout a specific point in time, which when + * reached unblocks the thread. + * @param[in] pred predicate which returns `false` if waiting is + * to be continued. + * + * @return `false` if pred evaluates to `false` after timeout + * expired, otherwise `true`. + * + * @throw lock_error when unlocking the lock or waiting on + * #pcond fails. + */ + template + bool + wait_until(mutex &lock, + const std::chrono::time_point &timeout, + Predicate pred) + { + return this->wait_until_impl(lock, timeout, std::move(pred)); + } + + /** + * Makes the current thread block until the condition variable + * is notified or a specific time is reached. + * + * This releases the lock, blocks the current thread and adds + * it to the list of threads waiting on `*this` condition + * variable. The lock needs to be acquired and owned by the + * calling thread. The lock is automatically reacquired after + * the call to wait. + * + * @param[in,out] lock a Lock object which meets the + * BasicLockableConcept. Needs to be based on a PMEM-resident + * obj::mutex. + * @param[in] timeout a specific point in time, which when + * reached unblocks the thread. + * @param[in] pred predicate which returns `false` if waiting is + * to be continued. + * + * @return `false` if pred evaluates to `false` after timeout + * expired, otherwise `true`. + * + * @throw lock_error when unlocking the lock or waiting on + * #pcond fails. + */ + template + bool + wait_until(Lock &lock, + const std::chrono::time_point &timeout, + Predicate pred) + { + return this->wait_until_impl(*lock.mutex(), timeout, + std::move(pred)); + } + + /** + * Makes the current thread block until the condition variable + * is notified, the specified amount of time passes or it is + * woken up by some other measure. + * + * This releases the lock, blocks the current thread and adds + * it to the list of threads waiting on `*this` condition + * variable. The lock needs to be acquired and owned by the + * calling thread. The lock is automatically reacquired after + * the call to wait. + * + * @param[in,out] lock a Lock object which meets the + * BasicLockableConcept. Needs to be based on a PMEM-resident + * obj::mutex. + * @param[in] rel_time a specific duration, which when + * expired unblocks the thread. + * + * @return std::cv_status::timeout on timeout, + * std::cv_status::no_timeout otherwise. + * + * @throw lock_error when unlocking the lock or waiting on + * #pcond fails. + */ + template + std::cv_status + wait_for(Lock &lock, const std::chrono::duration &rel_time) + { + return this->wait_until_impl(*lock.mutex(), + clock_type::now() + rel_time); + } + + /** + * Makes the current thread block until the condition variable + * is notified or the specified amount of time passes. + * + * This releases the lock, blocks the current thread and adds + * it to the list of threads waiting on `*this` condition + * variable. The lock needs to be acquired and owned by the + * calling thread. The lock is automatically reacquired after + * the call to wait. + * + * @param[in,out] lock a Lock object which meets the + * BasicLockableConcept. Needs to be based on a PMEM-resident + * obj::mutex. + * @param[in] rel_time a specific duration, which when + * expired unblocks the thread. + * @param[in] pred predicate which returns `false` if waiting is + * to be continued. + * + * @return `false` if pred evaluates to `false` after timeout + * expired, otherwise `true`. + * + * @throw lock_error when unlocking the lock or waiting on + * #pcond fails. + */ + template + bool + wait_for(Lock &lock, const std::chrono::duration &rel_time, + Predicate pred) + { + return this->wait_until_impl(*lock.mutex(), + clock_type::now() + rel_time, + std::move(pred)); + } + + /** + * Makes the current thread block until the condition variable + * is notified, the specified amount of time passes or it is + * woken up by some other measure. + * + * This releases the lock, blocks the current thread and adds + * it to the list of threads waiting on `*this` condition + * variable. The lock needs to be acquired and owned by the + * calling thread. The lock is automatically reacquired after + * the call to wait. + * + * @param[in,out] lock a PMEM-resident obj::mutex. + * @param[in] rel_time a specific duration, which when + * expired unblocks the thread. + * + * @return std::cv_status::timeout on timeout, + * std::cv_status::no_timeout otherwise. + * + * @throw lock_error when unlocking the lock or waiting on + * #pcond fails. + */ + template + std::cv_status + wait_for(mutex &lock, + const std::chrono::duration &rel_time) + { + return this->wait_until_impl(lock, + clock_type::now() + rel_time); + } + + /** + * Makes the current thread block until the condition variable + * is notified or the specified amount of time passes. + * + * This releases the lock, blocks the current thread and adds + * it to the list of threads waiting on `*this` condition + * variable. The lock needs to be acquired and owned by the + * calling thread. The lock is automatically reacquired after + * the call to wait. + * + * @param[in,out] lock a PMEM-resident obj::mutex. + * @param[in] rel_time a specific duration, which when + * expired unblocks the thread. + * @param[in] pred predicate which returns `false` if waiting is + * to be continued. + * + * @return `false` if pred evaluates to `false` after timeout + * expired, otherwise `true`. + * + * @throw lock_error when unlocking the lock or waiting on + * #pcond fails. + */ + template + bool + wait_for(mutex &lock, + const std::chrono::duration &rel_time, + Predicate pred) + { + return this->wait_until_impl(lock, clock_type::now() + rel_time, + std::move(pred)); + } + + /** + * Access a native handle to this condition variable. + * + * @return a pointer to PMEMcond. + */ + native_handle_type + native_handle() noexcept + { + return &this->pcond; + } + + /** + * Deleted assignment operator. + */ + condition_variable &operator=(const condition_variable &) = delete; + + /** + * Deleted copy constructor. + */ + condition_variable(const condition_variable &) = delete; + +private: + /** + * Internal implementation of the wait call. + */ + void + wait_impl(mutex &lock) + { + PMEMobjpool *pop = pmemobj_pool_by_ptr(this); + if (int ret = pmemobj_cond_wait(pop, &this->pcond, + lock.native_handle())) + throw lock_error( + ret, std::system_category(), + "Error waiting on a condition variable."); + } + + /** + * Internal implementation of the wait call. + */ + template + void + wait_impl(mutex &lock, Predicate pred) + { + while (!pred()) + this->wait(lock); + } + + /** + * Internal implementation of the wait_until call. + */ + template + std::cv_status + wait_until_impl( + mutex &lock, + const std::chrono::time_point &abs_timeout) + { + PMEMobjpool *pop = pmemobj_pool_by_ptr(this); + + /* convert to my clock */ + const typename Clock::time_point their_now = Clock::now(); + const clock_type::time_point my_now = clock_type::now(); + const auto delta = abs_timeout - their_now; + const auto my_rel = my_now + delta; + + struct timespec ts = detail::timepoint_to_timespec(my_rel); + + auto ret = pmemobj_cond_timedwait(pop, &this->pcond, + lock.native_handle(), &ts); + + if (ret == 0) + return std::cv_status::no_timeout; + else if (ret == ETIMEDOUT) + return std::cv_status::timeout; + else + throw lock_error( + ret, std::system_category(), + "Error waiting on a condition variable."); + } + + /** + * Internal implementation of the wait_until call. + */ + template + bool + wait_until_impl( + mutex &lock, + const std::chrono::time_point &abs_timeout, + Predicate pred) + { + while (!pred()) + if (this->wait_until_impl(lock, abs_timeout) == + std::cv_status::timeout) + return pred(); + return true; + } + + /** A POSIX style PMEM-resident condition variable.*/ + PMEMcond pcond; +}; + +} /* namespace obj */ + +} /* namespace pmem */ + +#endif /* LIBPMEMOBJ_CPP_CONDVARIABLE_HPP */ diff --git a/include/libpmemobj++/detail/array_traits.hpp b/include/libpmemobj++/detail/array_traits.hpp new file mode 100644 index 0000000..eb02e73 --- /dev/null +++ b/include/libpmemobj++/detail/array_traits.hpp @@ -0,0 +1,91 @@ +/* + * Copyright 2016-2018, Intel Corporation + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * * Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +/** + * @file + * Common array traits. + */ + +#ifndef LIBPMEMOBJ_CPP_ARRAY_TRAITS_HPP +#define LIBPMEMOBJ_CPP_ARRAY_TRAITS_HPP + +#include + +namespace pmem +{ + +namespace detail +{ + +/* + * Returns the number of array elements. + */ +template +struct pp_array_elems { + enum { elems = 1 }; +}; + +/* + * Returns the number of array elements. + */ +template +struct pp_array_elems { + enum { elems = N }; +}; + +/* + * Returns the type of elements in an array. + */ +template +struct pp_array_type; + +/* + * Returns the type of elements in an array. + */ +template +struct pp_array_type { + typedef T type; +}; + +/* + * Returns the type of elements in an array. + */ +template +struct pp_array_type { + typedef T type; +}; + +} /* namespace detail */ + +} /* namespace pmem */ + +#endif /* LIBPMEMOBJ_CPP_ARRAY_TRAITS_HPP */ diff --git a/include/libpmemobj++/detail/check_persistent_ptr_array.hpp b/include/libpmemobj++/detail/check_persistent_ptr_array.hpp new file mode 100644 index 0000000..54582dd --- /dev/null +++ b/include/libpmemobj++/detail/check_persistent_ptr_array.hpp @@ -0,0 +1,105 @@ +/* + * Copyright 2016-2018, Intel Corporation + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * * Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +/** + * @file + * Compile time type check for make_persistent. + */ + +#ifndef LIBPMEMOBJ_CPP_CHECK_PERSISTENT_PTR_ARRAY_HPP +#define LIBPMEMOBJ_CPP_CHECK_PERSISTENT_PTR_ARRAY_HPP + +#include + +#include + +namespace pmem +{ + +namespace detail +{ + +/* + * Typedef checking if given type is not an array. + */ +template +struct pp_if_not_array { + typedef obj::persistent_ptr type; +}; + +/* + * Typedef checking if given type is not an array. + */ +template +struct pp_if_not_array { +}; + +/* + * Typedef checking if given type is not an array. + */ +template +struct pp_if_not_array { +}; + +/* + * Typedef checking if given type is an array. + */ +template +struct pp_if_array; + +/* + * Typedef checking if given type is an array. + */ +template +struct pp_if_array { + typedef obj::persistent_ptr type; +}; + +/* + * Typedef checking if given type is an array. + */ +template +struct pp_if_size_array; + +/* + * Typedef checking if given type is an array. + */ +template +struct pp_if_size_array { + typedef obj::persistent_ptr type; +}; + +} /* namespace detail */ + +} /* namespace pmem */ + +#endif /* LIBPMEMOBJ_CPP_CHECK_PERSISTENT_PTR_ARRAY_HPP */ diff --git a/include/libpmemobj++/detail/common.hpp b/include/libpmemobj++/detail/common.hpp new file mode 100644 index 0000000..d570464 --- /dev/null +++ b/include/libpmemobj++/detail/common.hpp @@ -0,0 +1,192 @@ +/* + * Copyright 2016-2019, Intel Corporation + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * * Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +/** + * @file + * Commonly used functionality. + */ + +#ifndef LIBPMEMOBJ_CPP_COMMON_HPP +#define LIBPMEMOBJ_CPP_COMMON_HPP + +#include +#include +#include + +#if defined(__GNUC__) || defined(__clang__) +#define POBJ_CPP_DEPRECATED __attribute__((deprecated)) +#elif defined(_MSC_VER) +#define POBJ_CPP_DEPRECATED __declspec(deprecated) +#else +#define POBJ_CPP_DEPRECATED +#endif + +#if LIBPMEMOBJ_CPP_VG_ENABLED +#undef LIBPMEMOBJ_CPP_VG_PMEMCHECK_ENABLED +#undef LIBPMEMOBJ_CPP_VG_MEMCHECK_ENABLED +#undef LIBPMEMOBJ_CPP_VG_HELGRIND_ENABLED +#undef LIBPMEMOBJ_CPP_VG_DRD_ENABLED + +#define LIBPMEMOBJ_CPP_VG_PMEMCHECK_ENABLED 1 +#define LIBPMEMOBJ_CPP_VG_MEMCHECK_ENABLED 1 +#define LIBPMEMOBJ_CPP_VG_HELGRIND_ENABLED 1 +#define LIBPMEMOBJ_CPP_VG_DRD_ENABLED 1 +#endif + +#if LIBPMEMOBJ_CPP_VG_PMEMCHECK_ENABLED || \ + LIBPMEMOBJ_CPP_VG_MEMCHECK_ENABLED || \ + LIBPMEMOBJ_CPP_VG_HELGRIND_ENABLED || LIBPMEMOBJ_CPP_VG_DRD_ENABLED +#define LIBPMEMOBJ_CPP_ANY_VG_TOOL_ENABLED 1 +#endif + +#if LIBPMEMOBJ_CPP_ANY_VG_TOOL_ENABLED +#include +#endif + +#if LIBPMEMOBJ_CPP_VG_PMEMCHECK_ENABLED +#include +#endif + +#if LIBPMEMOBJ_CPP_VG_MEMCHECK_ENABLED +#include +#endif + +#if LIBPMEMOBJ_CPP_VG_HELGRIND_ENABLED +#include +#endif + +#if LIBPMEMOBJ_CPP_VG_DRD_ENABLED +#include +#endif + +/* + * Workaround for missing "is_trivially_copyable" in gcc < 5.0. + * Be aware of a difference between __has_trivial_copy and is_trivially_copyable + * e.g. for deleted copy constructors __has_trivial_copy(A) returns 1 in clang + * and 0 in gcc. It means that for gcc < 5 IS_TRIVIALLY_COPYABLE is more + * restrictive than is_trivially_copyable. + */ +#if !defined(__clang__) && defined(__GNUG__) && __GNUC__ < 5 +#define IS_TRIVIALLY_COPYABLE(T) __has_trivial_copy(T) +#else +#define IS_TRIVIALLY_COPYABLE(T) std::is_trivially_copyable::value +#endif + +namespace pmem +{ + +namespace obj +{ +template +class persistent_ptr; +} + +namespace detail +{ + +/* + * Conditionally add 'count' objects to a transaction. + * + * Adds count objects starting from `that` to the transaction if '*that' is + * within a pmemobj pool and there is an active transaction. + * Does nothing otherwise. + * + * @param[in] that pointer to the first object being added to the transaction. + * @param[in] count number of elements to be added to the transaction. + */ +template +inline void +conditional_add_to_tx(const T *that, std::size_t count = 1) +{ + if (count == 0) + return; + + if (pmemobj_tx_stage() != TX_STAGE_WORK) + return; + + /* 'that' is not in any open pool */ + if (!pmemobj_pool_by_ptr(that)) + return; + + if (pmemobj_tx_add_range_direct(that, sizeof(*that) * count)) + throw transaction_error( + "Could not add object(s) to the transaction."); +} + +/* + * Return type number for given type. + */ +template +uint64_t +type_num() +{ + return typeid(T).hash_code(); +} + +/** + * Round up to the next lowest power of 2. Overload for uint64_t argument. + */ +inline uint64_t +next_pow_2(uint64_t v) +{ + v--; + v |= v >> 1; + v |= v >> 2; + v |= v >> 4; + v |= v >> 8; + v |= v >> 16; + v |= v >> 32; + ++v; + return v + (v == 0); +} + +/** + * Round up to the next lowest power of 2. Overload for uint32_t argument. + */ +inline uint64_t +next_pow_2(uint32_t v) +{ + v--; + v |= v >> 1; + v |= v >> 2; + v |= v >> 4; + v |= v >> 8; + v |= v >> 16; + ++v; + return v + (v == 0); +} + +} /* namespace detail */ + +} /* namespace pmem */ + +#endif /* LIBPMEMOBJ_CPP_COMMON_HPP */ diff --git a/include/libpmemobj++/detail/conversions.hpp b/include/libpmemobj++/detail/conversions.hpp new file mode 100644 index 0000000..f343c9e --- /dev/null +++ b/include/libpmemobj++/detail/conversions.hpp @@ -0,0 +1,79 @@ +/* + * Copyright 2016-2018, Intel Corporation + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * * Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +/** + * @file + * Commonly used conversions. + */ + +#ifndef LIBPMEMOBJ_CPP_CONVERSIONS_HPP +#define LIBPMEMOBJ_CPP_CONVERSIONS_HPP + +#include +#include + +namespace pmem +{ + +namespace detail +{ + +/** + * Convert std::chrono::time_point to posix timespec. + * + * @param[in] timepoint point in time to be converted. + * + * @return converted timespec structure. + */ +template +timespec +timepoint_to_timespec(const std::chrono::time_point &timepoint) +{ + timespec ts; + auto rel_duration = timepoint.time_since_epoch(); + const auto sec = + std::chrono::duration_cast(rel_duration); + + ts.tv_sec = sec.count(); + ts.tv_nsec = static_cast( + std::chrono::duration_cast( + rel_duration - sec) + .count()); + + return ts; +} + +} /* namespace detail */ + +} /* namespace pmem */ + +#endif /* LIBPMEMOBJ_CPP_CONVERSIONS_HPP */ diff --git a/include/libpmemobj++/detail/ctl.hpp b/include/libpmemobj++/detail/ctl.hpp new file mode 100644 index 0000000..3971a44 --- /dev/null +++ b/include/libpmemobj++/detail/ctl.hpp @@ -0,0 +1,143 @@ +/* + * Copyright 2018, Intel Corporation + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * * Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +/** + * @file + * C++ ctl api. + */ + +#ifndef LIBPMEMOBJ_CPP_CTL_HPP +#define LIBPMEMOBJ_CPP_CTL_HPP + +#include +#include + +#include +#include + +#include + +namespace pmem +{ + +namespace obj +{ + +template +T +ctl_get_detail(PMEMobjpool *pool, const std::string &name) +{ + T tmp; + +#ifdef _WIN32 + int ret = pmemobj_ctl_getU(pool, name.c_str(), &tmp); +#else + int ret = pmemobj_ctl_get(pool, name.c_str(), &tmp); +#endif + if (ret) + throw ctl_error(strerror(errno)); + + return tmp; +} + +template +T +ctl_set_detail(PMEMobjpool *pool, const std::string &name, T arg) +{ +#ifdef _WIN32 + int ret = pmemobj_ctl_setU(pool, name.c_str(), &arg); +#else + int ret = pmemobj_ctl_set(pool, name.c_str(), &arg); +#endif + if (ret) + throw ctl_error(strerror(errno)); + + return arg; +} + +template +T +ctl_exec_detail(PMEMobjpool *pool, const std::string &name, T arg) +{ +#ifdef _WIN32 + int ret = pmemobj_ctl_execU(pool, name.c_str(), &arg); +#else + int ret = pmemobj_ctl_exec(pool, name.c_str(), &arg); +#endif + if (ret) + throw ctl_error(strerror(errno)); + + return arg; +} + +#ifdef _WIN32 +template +T +ctl_get_detail(PMEMobjpool *pool, const std::wstring &name) +{ + T tmp; + + int ret = pmemobj_ctl_getW(pool, name.c_str(), &tmp); + if (ret) + throw ctl_error(strerror(errno)); + + return tmp; +} + +template +T +ctl_set_detail(PMEMobjpool *pool, const std::wstring &name, T arg) +{ + int ret = pmemobj_ctl_setW(pool, name.c_str(), &arg); + if (ret) + throw ctl_error(strerror(errno)); + + return arg; +} + +template +T +ctl_exec_detail(PMEMobjpool *pool, const std::wstring &name, T arg) +{ + int ret = pmemobj_ctl_execW(pool, name.c_str(), &arg); + if (ret) + throw ctl_error(strerror(errno)); + + return arg; +} +#endif + +} /* namespace obj */ + +} /* namespace pmem */ + +#endif /* LIBPMEMOBJ_CPP_CTL_HPP */ diff --git a/include/libpmemobj++/detail/integer_sequence.hpp b/include/libpmemobj++/detail/integer_sequence.hpp new file mode 100644 index 0000000..2e37f1b --- /dev/null +++ b/include/libpmemobj++/detail/integer_sequence.hpp @@ -0,0 +1,100 @@ +/* + * Copyright 2016-2018, Intel Corporation + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * * Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +/** + * @file + * Create c++14 style index sequence. + */ + +#ifndef LIBPMEMOBJ_CPP_INTEGER_SEQUENCE_HPP +#define LIBPMEMOBJ_CPP_INTEGER_SEQUENCE_HPP + +#include + +namespace pmem +{ + +namespace detail +{ + +/* + * Base index type template. + */ +template +struct integer_sequence { +}; + +/* + * Size_t specialization of the integer sequence. + */ +template +using index_sequence = integer_sequence; + +/* + * Empty base class. + * + * Subject of empty base optimization. + */ +template +struct make_integer_seq_impl; + +/* + * Class ending recursive variadic template peeling. + */ +template +struct make_integer_seq_impl> { + typedef integer_sequence type; +}; + +/* + * Recursively create index while peeling off the types. + */ +template +struct make_integer_seq_impl, T, + Types...> { + typedef typename make_integer_seq_impl< + N, I + 1, integer_sequence, Types...>::type + type; +}; + +/* + * Make index sequence entry point. + */ +template +using make_index_sequence = + make_integer_seq_impl, Types...>; + +} /* namespace detail */ + +} /* namespace pmem */ + +#endif /* LIBPMEMOBJ_CPP_INTEGER_SEQUENCE_HPP */ diff --git a/include/libpmemobj++/detail/iterator_traits.hpp b/include/libpmemobj++/detail/iterator_traits.hpp new file mode 100644 index 0000000..a8a0166 --- /dev/null +++ b/include/libpmemobj++/detail/iterator_traits.hpp @@ -0,0 +1,111 @@ +/* + * Copyright 2018, Intel Corporation + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * * Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +/** + * @file + * Common iterator traits. + */ + +#ifndef LIBPMEMOBJ_CPP_ITERATOR_TRAITS_HPP +#define LIBPMEMOBJ_CPP_ITERATOR_TRAITS_HPP + +#include + +namespace pmem +{ + +namespace detail +{ + +template +struct has_iterator_category_convertible_to : std::false_type { +}; + +template +struct has_iterator_category_convertible_to< + T, U, + typename std::enable_if::iterator_category, + U>::value>::type> : std::true_type { +}; + +/** + * Type trait to determine if a given parameter type satisfies requirements of + * OutputIterator. + */ +template +struct is_output_iterator + : public has_iterator_category_convertible_to { +}; + +/** + * Type trait to determine if a given parameter type satisfies requirements of + * InputIterator. + */ +template +struct is_input_iterator + : public has_iterator_category_convertible_to { +}; + +/** + * Type trait to determine if a given parameter type satisfies requirements of + * ForwardIterator. + */ +template +struct is_forward_iterator + : public has_iterator_category_convertible_to { +}; + +/** + * Type trait to determine if a given parameter type satisfies requirements of + * BidirectionalIterator. + */ +template +struct is_bidirectional_iterator : public has_iterator_category_convertible_to< + T, std::bidirectional_iterator_tag> { +}; + +/** + * Type trait to determine if a given parameter type satisfies requirements of + * RandomAccessIterator. + */ +template +struct is_random_access_iterator : public has_iterator_category_convertible_to< + T, std::random_access_iterator_tag> { +}; + +} /* namespace detail */ + +} /* namespace pmem */ + +#endif /* LIBPMEMOBJ_CPP_ITERATOR_TRAITS_HPP */ diff --git a/include/libpmemobj++/detail/life.hpp b/include/libpmemobj++/detail/life.hpp new file mode 100644 index 0000000..ce2f8a7 --- /dev/null +++ b/include/libpmemobj++/detail/life.hpp @@ -0,0 +1,199 @@ +/* + * Copyright 2016-2019, Intel Corporation + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * * Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +/** + * @file + * Functions for destroying arrays. + */ + +#ifndef LIBPMEMOBJ_CPP_DESTROYER_HPP +#define LIBPMEMOBJ_CPP_DESTROYER_HPP + +#include +#include +#include + +#include +#include + +namespace pmem +{ + +namespace detail +{ + +/* + * Template for checking if T is not an array. + */ +template +struct if_not_array { + typedef T type; +}; + +/* + * Template for checking if T is not an array. + */ +template +struct if_not_array; + +/* + * Template for checking if T is not an array. + */ +template +struct if_not_array; + +/* + * Template for checking if T is an array. + */ +template +struct if_size_array; + +/* + * Template for checking if T is an array. + */ +template +struct if_size_array; + +/* + * Template for checking if T is an array. + */ +template +struct if_size_array { + typedef T type[N]; +}; + +/* + * Calls object's constructor. + * + * Supports aggregate initialization since C++17 + */ +template +void +create(typename if_not_array::type *ptr, Args &&... args) +{ +#if __cpp_lib_is_aggregate + if constexpr (std::is_aggregate_v) + new (static_cast(ptr)) T{std::forward(args)...}; + else + new (static_cast(ptr)) T(std::forward(args)...); +#else + new (static_cast(ptr)) T(std::forward(args)...); +#endif +} + +/* + * Recursively calls array's elements' constructors. + */ +template +void +create(typename if_size_array::type *ptr, Args &&... args) +{ + typedef typename detail::pp_array_type::type I; + enum { N = pp_array_elems::elems }; + + for (std::size_t i = 0; i < N; ++i) + create(&(*ptr)[i], std::forward(args)...); +} + +/* + * Calls the objects constructor. + * + * Unpacks the tuple to get constructor's parameters. + */ +template +void +create_from_tuple(void *ptr, index_sequence, Tuple tuple) +{ + new (ptr) T(std::get(std::move(tuple))...); +} + +/* + * C-style function which calls T constructor with arguments packed in a tuple. + * + * The arg is a tuple containing constructor parameters. + */ +template +int +c_style_construct(void *ptr, void *arg) +{ + auto *arg_pack = static_cast(arg); + + typedef typename make_index_sequence::type index; + try { + create_from_tuple(ptr, index(), std::move(*arg_pack)); + } catch (...) { + return -1; + } + + return 0; +} + +/* + * Calls object's destructor. + */ +template ::value>::type> +void +destroy(typename if_not_array::type &arg) +{ + arg.~T(); +} + +/* + * Don't call destructors for POD types. + */ +template ::value>::type> +void +destroy(typename if_not_array::type &) +{ +} + +/* + * Recursively calls array's elements' destructors. + */ +template +void +destroy(typename if_size_array::type &arg) +{ + typedef typename detail::pp_array_type::type I; + enum { N = pp_array_elems::elems }; + + for (std::size_t i = 0; i < N; ++i) + destroy(arg[N - 1 - i]); +} + +} /* namespace detail */ + +} /* namespace pmem */ + +#endif /* LIBPMEMOBJ_CPP_DESTROYER_HPP */ diff --git a/include/libpmemobj++/detail/make_atomic_impl.hpp b/include/libpmemobj++/detail/make_atomic_impl.hpp new file mode 100644 index 0000000..f5325a5 --- /dev/null +++ b/include/libpmemobj++/detail/make_atomic_impl.hpp @@ -0,0 +1,102 @@ +/* + * Copyright 2016-2019, Intel Corporation + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * * Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +/** + * @file + * Implementation details of atomic allocation and construction. + */ + +#ifndef LIBPMEMOBJ_CPP_MAKE_ATOMIC_IMPL_HPP +#define LIBPMEMOBJ_CPP_MAKE_ATOMIC_IMPL_HPP + +#include +#include + +#include +#include +#include + +namespace pmem +{ + +namespace detail +{ + +/* + * C-style function called by the allocator. + * + * The arg is a tuple containing constructor parameters. + */ +template +int +obj_constructor(PMEMobjpool *pop, void *ptr, void *arg) +{ + auto ret = c_style_construct(ptr, arg); + + if (ret != 0) + return -1; + + pmemobj_persist(pop, ptr, sizeof(T)); + + return 0; +} + +/* + * Constructor used for atomic array allocations. + * + * Returns -1 if an exception was thrown during T's construction, + * 0 otherwise. + */ +template +int +array_constructor(PMEMobjpool *pop, void *ptr, void *arg) +{ + std::size_t N = *static_cast(arg); + + T *tptr = static_cast(ptr); + try { + for (std::size_t i = 0; i < N; ++i) + detail::create(tptr + i); + } catch (...) { + return -1; + } + + pmemobj_persist(pop, ptr, sizeof(T) * N); + + return 0; +} + +} /* namespace detail */ + +} /* namespace pmem */ + +#endif /* LIBPMEMOBJ_CPP_MAKE_ATOMIC_IMPL_HPP */ diff --git a/include/libpmemobj++/detail/persistent_ptr_base.hpp b/include/libpmemobj++/detail/persistent_ptr_base.hpp new file mode 100644 index 0000000..8425c5f --- /dev/null +++ b/include/libpmemobj++/detail/persistent_ptr_base.hpp @@ -0,0 +1,388 @@ +/* + * Copyright 2016-2018, Intel Corporation + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * * Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +/** + * @file + * Base class for persistent_ptr. + */ + +#ifndef LIBPMEMOBJ_CPP_PERSISTENT_PTR_BASE_HPP +#define LIBPMEMOBJ_CPP_PERSISTENT_PTR_BASE_HPP + +#include +#include + +#include +#include +#include + +/* Windows has a max macro which collides with std::numeric_limits::max */ +#if defined(max) && defined(_WIN32) +#undef max +#endif + +namespace pmem +{ + +namespace detail +{ + +/** + * Persistent_ptr base class + * + * Implements some of the functionality of the persistent_ptr class. It defines + * all applicable conversions from and to a persistent_ptr_base. This class is + * an implementation detail and is not to be instantiated. It cannot be declared + * as virtual due to the problem with rebuilding the vtable. + */ +template +class persistent_ptr_base { + typedef persistent_ptr_base this_type; + + template + friend class persistent_ptr_base; + +public: + /** + * Type of an actual object with all qualifier removed, + * used for easy underlying type access + */ + typedef typename pmem::detail::sp_element::type element_type; + + /** + * Default constructor, zeroes the PMEMoid. + */ + persistent_ptr_base() : oid(OID_NULL) + { + verify_type(); + } + + /* + * Curly braces initialization is not used because the + * PMEMoid is a plain C (POD) type and we can't add a default + * constructor in there. + */ + + /** + * PMEMoid constructor. + * + * Provided for easy interoperability between C++ and C API's. + * + * @param oid C-style persistent pointer + */ + persistent_ptr_base(PMEMoid oid) noexcept : oid(oid) + { + verify_type(); + } + + /** + * Volatile pointer constructor. + * + * If ptr does not point to an address from a valid pool, the persistent + * pointer will evaluate to nullptr. + * + * @param ptr volatile pointer, pointing to persistent memory. + */ + persistent_ptr_base(element_type *ptr) : oid(pmemobj_oid(ptr)) + { + verify_type(); + } + + /** + * Copy constructor from a different persistent_ptr<>. + * + * Available only for convertible types. + */ + template ::value && + std::is_same::type, + U>::value>::type> + persistent_ptr_base(persistent_ptr_base const &r) noexcept + : oid(r.oid) + { + this->oid.off += + static_cast(calculate_offset()); + verify_type(); + } + + /** + * Copy constructor from a different persistent_ptr<>. + * + * Available only for convertible, non-void types. + */ + template < + typename U, typename Dummy = void, + typename = typename std::enable_if< + !std::is_same< + typename std::remove_cv::type, + typename std::remove_cv::type>::value && + !std::is_void::value, + decltype(static_cast(std::declval()))>::type> + persistent_ptr_base(persistent_ptr_base const &r) noexcept + : oid(r.oid) + { + this->oid.off += + static_cast(calculate_offset()); + verify_type(); + } + + /** + * Conversion operator to a different persistent_ptr<>. + * + * Available only for convertible, non-void types. + */ + template < + typename Y, + typename = typename std::enable_if< + !std::is_same< + typename std::remove_cv::type, + typename std::remove_cv::type>::value && + !std::is_void::value, + decltype(static_cast(std::declval()))>::type> + operator persistent_ptr_base() noexcept + { + /* + * The offset conversion should not be required here. + */ + return persistent_ptr_base(this->oid); + } + + /* + * Copy constructor. + * + * @param r Persistent pointer to the same type. + */ + persistent_ptr_base(persistent_ptr_base const &r) noexcept : oid(r.oid) + { + verify_type(); + } + + /** + * Defaulted move constructor. + */ + persistent_ptr_base(persistent_ptr_base &&r) noexcept + : oid(std::move(r.oid)) + { + verify_type(); + } + + /** + * Defaulted move assignment operator. + */ + persistent_ptr_base & + operator=(persistent_ptr_base &&r) + { + detail::conditional_add_to_tx(this); + this->oid = std::move(r.oid); + + return *this; + } + + /** + * Assignment operator. + * + * Persistent pointer assignment within a transaction + * automatically registers this operation so that a rollback + * is possible. + * + * @throw pmem::transaction_error when adding the object to the + * transaction failed. + */ + persistent_ptr_base & + operator=(persistent_ptr_base const &r) + { + this_type(r).swap(*this); + + return *this; + } + + /** + * Nullptr move assignment operator. + * + * @throw pmem::transaction_error when adding the object to the + * transaction failed. + */ + persistent_ptr_base & + operator=(std::nullptr_t &&) + { + detail::conditional_add_to_tx(this); + this->oid = {0, 0}; + return *this; + } + + /** + * Converting assignment operator from a different + * persistent_ptr<>. + * + * Available only for convertible types. + * Just like regular assignment, also automatically registers + * itself in a transaction. + * + * @throw pmem::transaction_error when adding the object to the + * transaction failed. + */ + template ::value>::type> + persistent_ptr_base & + operator=(persistent_ptr_base const &r) + { + this_type(r).swap(*this); + + return *this; + } + + /** + * Swaps two persistent_ptr objects of the same type. + * + * @param[in,out] other the other persistent_ptr to swap. + */ + void + swap(persistent_ptr_base &other) + { + detail::conditional_add_to_tx(this); + detail::conditional_add_to_tx(&other); + std::swap(this->oid, other.oid); + } + + /** + * Get a direct pointer. + * + * Performs a calculations on the underlying C-style pointer. + * + * @return a direct pointer to the object. + */ + element_type * + get() const noexcept + { + if (this->oid.pool_uuid_lo == + std::numeric_limits::max()) + return reinterpret_cast(oid.off); + else + return static_cast( + pmemobj_direct(this->oid)); + } + + /** + * Get PMEMoid encapsulated by this object. + * + * For C API compatibility. + * + * @return const reference to the PMEMoid + */ + const PMEMoid & + raw() const noexcept + { + return this->oid; + } + + /** + * Get pointer to PMEMoid encapsulated by this object. + * + * For C API compatibility. + * + * @return pointer to the PMEMoid + */ + PMEMoid * + raw_ptr() noexcept + { + return &(this->oid); + } + + /* + * Bool conversion operator. + */ + explicit operator bool() const noexcept + { + return get() != nullptr; + } + +protected: + /* The underlying PMEMoid of the held object. */ + PMEMoid oid; + + void + verify_type() + { + static_assert(!std::is_polymorphic::value, + "Polymorphic types are not supported"); + } + + /** + * Private constructor enabling persistent_ptrs to volatile objects. + * + * This is internal implementation only needed for the + * pointer_traits::pointer_to to be able to create + * valid pointers. This is used in libstdc++'s std::vector::insert(). + */ + persistent_ptr_base(element_type *vptr, int) : persistent_ptr_base(vptr) + { + if (OID_IS_NULL(oid)) { + oid.pool_uuid_lo = std::numeric_limits::max(); + oid.off = reinterpret_cast(vptr); + } + } + + /** + * Calculate in-object offset for structures with inheritance. + * + * In case of the given inheritance: + * + * A B + * \ / + * C + * + * A pointer to B *ptr = &C should be offset by sizeof(A). This function + * calculates that offset. + * + * @return offset between to compatible pointer types to the same object + */ + template + inline ptrdiff_t + calculate_offset() const + { + static const ptrdiff_t ptr_offset_magic = 0xDEADBEEF; + + U *tmp{reinterpret_cast(ptr_offset_magic)}; + T *diff = static_cast(tmp); + return reinterpret_cast(diff) - + reinterpret_cast(tmp); + } +}; + +} /* namespace detail */ + +} /* namespace pmem */ + +#endif /* LIBPMEMOBJ_CPP_PERSISTENT_PTR_BASE_HPP */ diff --git a/include/libpmemobj++/detail/pexceptions.hpp b/include/libpmemobj++/detail/pexceptions.hpp new file mode 100644 index 0000000..3eb195e --- /dev/null +++ b/include/libpmemobj++/detail/pexceptions.hpp @@ -0,0 +1,131 @@ +/* + * Copyright 2016-2018, Intel Corporation + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * * Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +/** + * @file + * Custom exceptions. + */ + +#ifndef LIBPMEMOBJ_CPP_PEXCEPTIONS_HPP +#define LIBPMEMOBJ_CPP_PEXCEPTIONS_HPP + +#include +#include + +namespace pmem +{ + +/** + * Custom pool error class. + * + * Thrown when there is a runtime problem with some action on the + * pool. + */ +class pool_error : public std::runtime_error { +public: + using std::runtime_error::runtime_error; +}; + +/** + * Custom transaction error class. + * + * Thrown when there is a runtime problem with a transaction. + */ +class transaction_error : public std::runtime_error { +public: + using std::runtime_error::runtime_error; +}; + +/** + * Custom lock error class. + * + * Thrown when there is a runtime system error with an operation + * on a lock. + */ +class lock_error : public std::system_error { +public: + using std::system_error::system_error; +}; + +/** + * Custom transaction error class. + * + * Thrown when there is a transactional allocation error. + */ +class transaction_alloc_error : public transaction_error { +public: + using transaction_error::transaction_error; +}; + +/** + * Custom transaction error class. + * + * Thrown when there is a transactional free error. + */ +class transaction_free_error : public transaction_alloc_error { +public: + using transaction_alloc_error::transaction_alloc_error; +}; + +/** + * Custom transaction error class. + * + * Thrown when there is an error with the scope of the transaction. + */ +class transaction_scope_error : public std::logic_error { +public: + using std::logic_error::logic_error; +}; + +/** + * Custom transaction error class. + * + * Thrown on manual transaction abort. + */ +class manual_tx_abort : public std::runtime_error { +public: + using std::runtime_error::runtime_error; +}; + +/** + * Custom ctl error class. + * + * Thrown on ctl_[get|set|exec] failure. + */ +class ctl_error : public std::runtime_error { +public: + using std::runtime_error::runtime_error; +}; + +} /* namespace pmem */ + +#endif /* LIBPMEMOBJ_CPP_PEXCEPTIONS_HPP */ diff --git a/include/libpmemobj++/detail/specialization.hpp b/include/libpmemobj++/detail/specialization.hpp new file mode 100644 index 0000000..1e1301d --- /dev/null +++ b/include/libpmemobj++/detail/specialization.hpp @@ -0,0 +1,160 @@ +/* + * Copyright 2015-2018, Intel Corporation + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * * Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +/** + * @file + * Helper template for persistent ptr specialization. + * + * Based on Boost library smart_ptr implementation. + */ + +#ifndef LIBPMEMOBJ_CPP_SPECIALIZATION_HPP +#define LIBPMEMOBJ_CPP_SPECIALIZATION_HPP + +#include + +namespace pmem +{ + +namespace detail +{ +/* smart pointer specialization */ + +template +struct sp_element { + typedef T type; +}; + +template +struct sp_element { + typedef T type; +}; + +template +struct sp_element { + typedef T type; +}; + +/* sp_dereference is a return type of operator* */ + +template +struct sp_dereference { + typedef T &type; +}; + +template <> +struct sp_dereference { + typedef void type; +}; + +template <> +struct sp_dereference { + typedef void type; +}; + +template <> +struct sp_dereference { + typedef void type; +}; + +template <> +struct sp_dereference { + typedef void type; +}; + +template +struct sp_dereference { + typedef void type; +}; + +template +struct sp_dereference { + typedef void type; +}; + +/* sp_member_access is a return type of operator-> */ + +template +struct sp_member_access { + typedef T *type; +}; + +template +struct sp_member_access { + typedef void type; +}; + +template +struct sp_member_access { + typedef void type; +}; + +/* sp_array_access is a return type of operator[] */ + +template +struct sp_array_access { + typedef T &type; +}; + +template <> +struct sp_array_access { + typedef struct does_not_exist { + } & type; +}; + +template +struct sp_array_access { + typedef T &type; +}; + +template +struct sp_array_access { + typedef T &type; +}; + +/* sp_extent is used for operator[] index checking */ + +template +struct sp_extent { + enum _vt { value = 0 }; +}; + +template +struct sp_extent { + enum _vt { value = N }; +}; + +} /* namespace detail */ + +} /* namespace pmem */ + +#endif /* LIBPMEMOBJ_CPP_SPECIALIZATION_HPP */ diff --git a/include/libpmemobj++/detail/temp_value.hpp b/include/libpmemobj++/detail/temp_value.hpp new file mode 100644 index 0000000..f22ec2d --- /dev/null +++ b/include/libpmemobj++/detail/temp_value.hpp @@ -0,0 +1,127 @@ +/* + * Copyright 2019, Intel Corporation + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * * Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +/** + * @file + * temp_value template class for caching objects. + */ + +#ifndef LIBPMEMOBJ_CPP_TEMP_VALUE_HPP +#define LIBPMEMOBJ_CPP_TEMP_VALUE_HPP + +#include + +namespace pmem +{ + +namespace detail +{ + +/** + * Suggested maximum size of stack allocation for caching objects is 64kB. + * It can be changed by user by setting LIBPMEMOBJ_CPP_MAX_STACK_ALLOC_SIZE to + * custom value. + */ +#ifndef LIBPMEMOBJ_CPP_MAX_STACK_ALLOC_SIZE +#define LIBPMEMOBJ_CPP_MAX_STACK_ALLOC_SIZE 64 * (1 << 10) +#endif + +/** + * Template class for caching objects based on constructor's variadic template + * arguments and LIBPMEMOBJ_CPP_MAX_STACK_ALLOC_SIZE. It has two + * specializations: for noexcept constructors and for throwing constructors. + */ +template +struct temp_value; + +/** + * Specialization for non-throwing constructors and objects smaller than + * LIBPMEMOBJ_CPP_MAX_STACK_ALLOC_SIZE bytes. Constructs and stores value in + * underlying field. + */ +template +struct temp_value< + T, NoExcept, + typename std::enable_if::type> { + template + temp_value(Args &&... args) noexcept : t(std::forward(args)...) + { + } + + T & + get() noexcept + { + return t; + } + + T t; +}; + +/** + * Specialization for throwing constructors or objects greater than or equal to + * LIBPMEMOBJ_CPP_MAX_STACK_ALLOC_SIZE bytes. Constructs and stores value in + * underlying field in pmem. + */ +template +struct temp_value< + T, NoExcept, + typename std::enable_if= + LIBPMEMOBJ_CPP_MAX_STACK_ALLOC_SIZE)>::type> { + template + temp_value(Args &&... args) + { + ptr = pmem::obj::make_persistent( + std::forward(args)...); + } + + ~temp_value() + { + pmem::obj::delete_persistent(ptr); + } + + T & + get() + { + return *ptr; + } + + pmem::obj::persistent_ptr ptr; +}; + +} /* namespace detail */ + +} /* namespace pmem */ + +#endif /* LIBPMEMOBJ_CPP_TEMP_VALUE_HPP */ diff --git a/include/libpmemobj++/detail/variadic.hpp b/include/libpmemobj++/detail/variadic.hpp new file mode 100644 index 0000000..7fc4311 --- /dev/null +++ b/include/libpmemobj++/detail/variadic.hpp @@ -0,0 +1,69 @@ +/* + * Copyright 2019, Intel Corporation + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * * Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +/** + * @file + * Helper functionality for handling variadic templates. + */ + +#ifndef LIBPMEMOBJ_CPP_VARIADIC_HPP +#define LIBPMEMOBJ_CPP_VARIADIC_HPP + +namespace pmem +{ + +namespace detail +{ + +/* + * Checks if T is the same type as first type in Args. + * General case (for sizeof...(Args) == 0). + */ +template +struct is_first_arg_same { + static constexpr bool value = false; +}; + +/* + * Checks if T is the same type as first type in Args. + * Specialization (for sizeof...(Args) > 0). + */ +template +struct is_first_arg_same { + static constexpr bool value = std::is_same::value; +}; + +} /* namespace detail */ + +} /* namespace pmem */ + +#endif /* LIBPMEMOBJ_CPP_VARIADIC_HPP */ diff --git a/include/libpmemobj++/experimental/array.hpp b/include/libpmemobj++/experimental/array.hpp new file mode 100644 index 0000000..7f7c5a3 --- /dev/null +++ b/include/libpmemobj++/experimental/array.hpp @@ -0,0 +1,957 @@ +/* + * Copyright 2018-2019, Intel Corporation + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * * Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +/** + * @file + * Array container with std::array compatible interface. + */ + +#ifndef LIBPMEMOBJ_CPP_ARRAY_HPP +#define LIBPMEMOBJ_CPP_ARRAY_HPP + +#include +#include + +#include +#include +#include +#include +#include +#include +#include + +namespace pmem +{ + +namespace obj +{ + +namespace experimental +{ + +/** + * pmem::obj::experimental::array - EXPERIMENTAL persistent container + * with std::array compatible interface. + * + * pmem::obj::experimental::array can only be stored on pmem. Creating array on + * stack will result with "pool_error" exception. + * + * All methods which allow write access to specific element will add it to an + * active transaction. + * + * All methods which return non-const pointer to raw data add entire array + * to a transaction. + * + * When a non-const iterator is returned it adds part of the array + * to a transaction while traversing. + */ +template +struct array { + + template + struct standard_array_traits { + using type = Y[N]; + }; + + /* zero-sized array support */ + template + struct standard_array_traits { + struct _alignment_struct { + Y _data[1]; + }; + + struct alignas(_alignment_struct) type { + char _data[sizeof(_alignment_struct)]; + }; + }; + + /* Member types */ + using value_type = T; + using pointer = value_type *; + using const_pointer = const value_type *; + using reference = value_type &; + using const_reference = const value_type &; + using iterator = basic_contiguous_iterator; + using const_iterator = const_pointer; + using size_type = std::size_t; + using difference_type = std::ptrdiff_t; + using reverse_iterator = std::reverse_iterator; + using const_reverse_iterator = std::reverse_iterator; + + /* Underlying array */ + typename standard_array_traits::type _data; + + /** + * Defaulted constructor. + */ + array() = default; + + /** + * Defaulted copy constructor. + */ + array(const array &) = default; + + /** + * Defaulted move constructor. + */ + array(array &&) = default; + + /** + * Copy assignment operator - perform assignment from other + * pmem::obj::experimental::array. + * + * This function creates a transaction internally. + * + * @throw transaction_error when adding the object to the + * transaction failed. + * @throw pmem::pool_error if an object is not in persistent memory. + */ + array & + operator=(const array &other) + { + /* + * _get_pool should be called before self assignment check to + * maintain the same behaviour for all arguments. + */ + auto pop = _get_pool(); + + if (this == &other) + return *this; + + transaction::run(pop, [&] { + detail::conditional_add_to_tx(this); + std::copy(other.cbegin(), other.cend(), _get_data()); + }); + + return *this; + } + + /** + * Move assignment operator - perform move assignment from other + * pmem::obj::experimental::array. + * + * This function creates a transaction internally. + * + * @throw transaction_error when adding the object to the + * transaction failed. + * @throw pmem::pool_error if an object is not in persistent memory. + */ + array & + operator=(array &&other) + { + /* + * _get_pool should be called before self assignment check to + * maintain the same behaviour for all arguments. + */ + auto pop = _get_pool(); + + if (this == &other) + return *this; + + transaction::run(pop, [&] { + detail::conditional_add_to_tx(this); + std::copy(other.cbegin(), other.cend(), _get_data()); + }); + + return *this; + } + + /** + * Access element at specific index and add it to a transaction. + * + * @throw std::out_of_range if index is out of bound. + * @throw transaction_error when adding the object to the + * transaction failed. + */ + reference + at(size_type n) + { + if (n >= N) + throw std::out_of_range("array::at"); + + detail::conditional_add_to_tx(_get_data() + n); + + return _get_data()[n]; + } + + /** + * Access element at specific index. + * + * @throw std::out_of_range if index is out of bound. + */ + const_reference + at(size_type n) const + { + if (n >= N) + throw std::out_of_range("array::at"); + + return _get_data()[n]; + } + + /** + * Access element at specific index. + * + * @throw std::out_of_range if index is out of bound. + */ + const_reference + const_at(size_type n) const + { + if (n >= N) + throw std::out_of_range("array::const_at"); + + return _get_data()[n]; + } + + /** + * Access element at specific index and add it to a transaction. + * No bounds checking is performed. + * + * @throw transaction_error when adding the object to the + * transaction failed. + */ + reference operator[](size_type n) + { + detail::conditional_add_to_tx(_get_data() + n); + + return _get_data()[n]; + } + + /** + * Access element at specific index. + * No bounds checking is performed. + */ + const_reference operator[](size_type n) const + { + return _get_data()[n]; + } + + /** + * Returns raw pointer to the underlying data + * and adds entire array to a transaction. + * + * @throw transaction_error when adding the object to the + * transaction failed. + */ + T * + data() + { + detail::conditional_add_to_tx(this); + return _get_data(); + } + + /** + * Returns const raw pointer to the underlying data. + */ + const T * + data() const noexcept + { + return _get_data(); + } + + /** + * Returns const raw pointer to the underlying data. + */ + const T * + cdata() const noexcept + { + return _get_data(); + } + + /** + * Returns an iterator to the beginning. + * + * @throw transaction_error when adding the object to the + * transaction failed. + */ + iterator + begin() + { + return iterator(_get_data()); + } + + /** + * Returns an iterator to the end. + * + * @throw transaction_error when adding the object to the + * transaction failed. + */ + iterator + end() + { + return iterator(_get_data() + size()); + } + + /** + * Returns const iterator to the beginning. + */ + const_iterator + begin() const noexcept + { + return const_iterator(_get_data()); + } + + /** + * Returns const iterator to the beginning. + */ + const_iterator + cbegin() const noexcept + { + return const_iterator(_get_data()); + } + + /** + * Returns a const iterator to the end. + */ + const_iterator + end() const noexcept + { + return const_iterator(_get_data() + size()); + } + + /** + * Returns a const iterator to the end. + */ + const_iterator + cend() const noexcept + { + return const_iterator(_get_data() + size()); + } + + /** + * Returns a reverse iterator to the beginning. + * + * @throw transaction_error when adding the object to the + * transaction failed. + */ + reverse_iterator + rbegin() + { + return reverse_iterator(iterator(_get_data() + size())); + } + + /** + * Returns a reverse iterator to the end. + * + * @throw transaction_error when adding the object to the + * transaction failed. + */ + reverse_iterator + rend() + { + return reverse_iterator(iterator(_get_data())); + } + + /** + * Returns a const reverse iterator to the beginning. + */ + const_reverse_iterator + rbegin() const noexcept + { + return const_reverse_iterator(cend()); + } + + /** + * Returns a const reverse iterator to the beginning. + */ + const_reverse_iterator + crbegin() const noexcept + { + return const_reverse_iterator(cend()); + } + + /** + * Returns a const reverse iterator to the end. + */ + const_reverse_iterator + rend() const noexcept + { + return const_reverse_iterator(cbegin()); + } + + /** + * Returns a const reverse iterator to the beginning. + */ + const_reverse_iterator + crend() const noexcept + { + return const_reverse_iterator(cbegin()); + } + + /** + * Access the first element and add this element to a transaction. + * + * @throw transaction_error when adding the object to the + * transaction failed. + */ + reference + front() + { + detail::conditional_add_to_tx(_get_data()); + return _get_data()[0]; + } + + /** + * Access the last element and add this element to a transaction. + * + * @throw transaction_error when adding the object to the + * transaction failed. + */ + reference + back() + { + detail::conditional_add_to_tx(&_get_data()[size() - 1]); + return _get_data()[size() - 1]; + } + + /** + * Access the first element. + */ + const_reference + front() const + { + return _get_data()[0]; + } + + /** + * Access the first element. + */ + const_reference + cfront() const + { + return _get_data()[0]; + } + + /** + * Access the last element. + */ + const_reference + back() const + { + return _get_data()[size() - 1]; + } + + /** + * Access the last element. + */ + const_reference + cback() const + { + return _get_data()[size() - 1]; + } + + /** + * Returns slice and snapshots requested range. + * + * @param[in] start start index of requested range. + * @param[in] n number of elements in range. + * + * @return slice from start to start + n. + * + * @throw std::out_of_range if any element of the range would be + * outside of the array. + */ + slice + range(size_type start, size_type n) + { + if (start + n > N) + throw std::out_of_range("array::range"); + + detail::conditional_add_to_tx(_get_data() + start, n); + + return {_get_data() + start, _get_data() + start + n}; + } + + /** + * Returns slice. + * + * @param[in] start start index of requested range. + * @param[in] n number of elements in range. + * @param[in] snapshot_size number of elements which should be + * snapshotted in a bulk while traversing this slice. + * If provided value is larger or equal to n, entire range is + * added to a transaction. If value is equal to 0 no snapshotting + * happens. + * + * @return slice from start to start + n. + * + * @throw std::out_of_range if any element of the range would be + * outside of the array. + */ + slice> + range(size_type start, size_type n, size_type snapshot_size) + { + if (start + n > N) + throw std::out_of_range("array::range"); + + if (snapshot_size > n) + snapshot_size = n; + + return {range_snapshotting_iterator(_get_data() + start, + _get_data() + start, n, + snapshot_size), + range_snapshotting_iterator(_get_data() + start + n, + _get_data() + start, n, + snapshot_size)}; + } + + /** + * Returns const slice. + * + * @param[in] start start index of requested range. + * @param[in] n number of elements in range. + * + * @return slice from start to start + n. + * + * @throw std::out_of_range if any element of the range would be + * outside of the array. + */ + slice + range(size_type start, size_type n) const + { + if (start + n > N) + throw std::out_of_range("array::range"); + + return {const_iterator(_get_data() + start), + const_iterator(_get_data() + start + n)}; + } + + /** + * Returns const slice. + * + * @param[in] start start index of requested range. + * @param[in] n number of elements in range. + * + * @return slice from start to start + n. + * + * @throw std::out_of_range if any element of the range would be + * outside of the array. + */ + slice + crange(size_type start, size_type n) const + { + if (start + n > N) + throw std::out_of_range("array::crange"); + + return {const_iterator(_get_data() + start), + const_iterator(_get_data() + start + n)}; + } + + /** + * Returns size of the array. + */ + constexpr size_type + size() const noexcept + { + return N; + } + + /** + * Returns the maximum size of the array. + */ + constexpr size_type + max_size() const noexcept + { + return N; + } + + /** + * Checks whether array is empty. + */ + constexpr bool + empty() const noexcept + { + return size() == 0; + } + + /** + * Fills array with specified value inside internal transaction. + * + * @throw transaction_error when adding the object to the + * transaction failed. + * @throw pmem::pool_error if an object is not in persistent memory. + */ + void + fill(const_reference value) + { + auto pop = _get_pool(); + + transaction::run(pop, [&] { + detail::conditional_add_to_tx(this); + std::fill(_get_data(), _get_data() + size(), value); + }); + } + + /** + * Swaps content with other array's content inside internal transaction. + * + * @throw transaction_error when adding the object to the + * transaction failed. + * @throw pmem::pool_error if an object is not in persistent memory. + */ + template + typename std::enable_if::type + swap(array &other) + { + /* + * _get_pool should be called before self assignment check to + * maintain the same behaviour for all arguments. + */ + auto pop = _get_pool(); + + if (this == &other) + return; + + transaction::run(pop, [&] { + detail::conditional_add_to_tx(this); + detail::conditional_add_to_tx(&other); + + std::swap_ranges(_get_data(), _get_data() + size(), + other._get_data()); + }); + } + + /** + * Swap for zero-sized array. + */ + template + typename std::enable_if::type + swap(array &other) + { + static_assert(!std::is_const::value, + "cannot swap zero-sized array of type 'const T'"); + } + +private: + /** + * Support for non-zero sized array. + */ + template + typename std::enable_if::type + _get_data() + { + return this->_data; + } + + /** + * Support for non-zero sized array. + */ + template + typename std::enable_if::type + _get_data() const + { + return this->_data; + } + + /** + * Support for zero sized array. + * Return value is a unique address (address of the array itself); + */ + template + typename std::enable_if::type + _get_data() + { + return reinterpret_cast(&this->_data); + } + + /** + * Support for zero sized array. + */ + template + typename std::enable_if::type + _get_data() const + { + return reinterpret_cast(&this->_data); + } + + /** + * Check whether object is on pmem and return pool_base instance. + * + * @throw pmem::pool_error if an object is not in persistent memory. + */ + pool_base + _get_pool() const + { + auto pop = pmemobj_pool_by_ptr(this); + if (pop == nullptr) + throw pool_error("Object outside of pmemobj pool."); + + return pool_base(pop); + } +}; + +/** + * Non-member equal operator. + */ +template +inline bool +operator==(const array &lhs, const array &rhs) +{ + return std::equal(lhs.cbegin(), lhs.cend(), rhs.cbegin()); +} + +/** + * Non-member not-equal operator. + */ +template +inline bool +operator!=(const array &lhs, const array &rhs) +{ + return !(lhs == rhs); +} + +/** + * Non-member less than operator. + */ +template +inline bool +operator<(const array &lhs, const array &rhs) +{ + return std::lexicographical_compare(lhs.cbegin(), lhs.cend(), + rhs.cbegin(), rhs.cend()); +} + +/** + * Non-member greater than operator. + */ +template +inline bool +operator>(const array &lhs, const array &rhs) +{ + return rhs < lhs; +} + +/** + * Non-member greater or equal operator. + */ +template +inline bool +operator>=(const array &lhs, const array &rhs) +{ + return !(lhs < rhs); +} + +/** + * Non-member less or equal operator. + */ +template +inline bool +operator<=(const array &lhs, const array &rhs) +{ + return !(lhs > rhs); +} + +/** + * Non-member cbegin. + */ +template +typename pmem::obj::experimental::array::const_iterator +cbegin(const pmem::obj::experimental::array &a) +{ + return a.cbegin(); +} + +/** + * Non-member cend. + */ +template +typename pmem::obj::experimental::array::const_iterator +cend(const pmem::obj::experimental::array &a) +{ + return a.cend(); +} + +/** + * Non-member crbegin. + */ +template +typename pmem::obj::experimental::array::const_reverse_iterator +crbegin(const pmem::obj::experimental::array &a) +{ + return a.crbegin(); +} + +/** + * Non-member crend. + */ +template +typename pmem::obj::experimental::array::const_reverse_iterator +crend(const pmem::obj::experimental::array &a) +{ + return a.crend(); +} + +/** + * Non-member begin. + */ +template +typename pmem::obj::experimental::array::iterator +begin(pmem::obj::experimental::array &a) +{ + return a.begin(); +} + +/** + * Non-member begin. + */ +template +typename pmem::obj::experimental::array::const_iterator +begin(const pmem::obj::experimental::array &a) +{ + return a.begin(); +} + +/** + * Non-member end. + */ +template +typename pmem::obj::experimental::array::iterator +end(pmem::obj::experimental::array &a) +{ + return a.end(); +} + +/** + * Non-member end. + */ +template +typename pmem::obj::experimental::array::const_iterator +end(const pmem::obj::experimental::array &a) +{ + return a.end(); +} + +/** + * Non-member rbegin. + */ +template +typename pmem::obj::experimental::array::reverse_iterator +rbegin(pmem::obj::experimental::array &a) +{ + return a.rbegin(); +} + +/** + * Non-member rbegin. + */ +template +typename pmem::obj::experimental::array::const_reverse_iterator +rbegin(const pmem::obj::experimental::array &a) +{ + return a.rbegin(); +} + +/** + * Non-member rend. + */ +template +typename pmem::obj::experimental::array::reverse_iterator +rend(pmem::obj::experimental::array &a) +{ + return a.rend(); +} + +/** + * Non-member rend. + */ +template +typename pmem::obj::experimental::array::const_reverse_iterator +rend(const pmem::obj::experimental::array &a) +{ + return a.rend(); +} + +/** + * Non-member swap function. + */ +template +inline void +swap(pmem::obj::experimental::array &lhs, + pmem::obj::experimental::array &rhs) +{ + lhs.swap(rhs); +} + +/** + * Non-member get function. + */ +template +T & +get(pmem::obj::experimental::array &a) +{ + static_assert(I < N, + "Index out of bounds in std::get<> (pmem::obj::array)"); + return a.at(I); +} + +/** + * Non-member get function. + */ +template +T && +get(pmem::obj::experimental::array &&a) +{ + static_assert(I < N, + "Index out of bounds in std::get<> (pmem::obj::array)"); + return std::move(a.at(I)); +} + +/** + * Non-member get function. + */ +template +const T & +get(const pmem::obj::experimental::array &a) noexcept +{ + static_assert(I < N, + "Index out of bounds in std::get<> (pmem::obj::array)"); + return a.at(I); +} + +/** + * Non-member get function. + */ +template +const T && +get(const pmem::obj::experimental::array &&a) noexcept +{ + static_assert(I < N, + "Index out of bounds in std::get<> (pmem::obj::array)"); + return std::move(a.at(I)); +} + +} /* namespace experimental */ + +} /* namespace obj */ + +} /* namespace pmem */ + +#endif /* LIBPMEMOBJ_CPP_ARRAY_HPP */ diff --git a/include/libpmemobj++/experimental/basic_string.hpp b/include/libpmemobj++/experimental/basic_string.hpp new file mode 100644 index 0000000..814b7d4 --- /dev/null +++ b/include/libpmemobj++/experimental/basic_string.hpp @@ -0,0 +1,1603 @@ +/* + * Copyright 2019, Intel Corporation + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * * Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +/** + * @file + * String container with std::basic_string compatible interface. + */ + +#ifndef LIBPMEMOBJ_CPP_BASIC_STRING_HPP +#define LIBPMEMOBJ_CPP_BASIC_STRING_HPP + +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +namespace pmem +{ + +namespace obj +{ + +namespace experimental +{ + +/** + * pmem::obj::experimental::string - EXPERIMENTAL persistent container + * with std::basic_string compatible interface. + * + * The implementation is NOT complete. + */ +template > +class basic_string { +public: + /* 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 = basic_contiguous_iterator; + using const_iterator = const_pointer; + using reverse_iterator = std::reverse_iterator; + using const_reverse_iterator = std::reverse_iterator; + + /* Number of characters which can be stored using sso */ + static constexpr size_type sso_capacity = 64 - sizeof('\0'); + + /** + * Default constructor. Construct an empty container. + * + * @pre must be called in transaction scope. + * + * @throw pmem::pool_error if an object is not in persistent memory. + * @throw pmem::transaction_error if constructor wasn't called in + * transaction. + */ + basic_string() + { + check_pmem_tx(); + + initialize(0U, value_type('\0')); + } + + /** + * Construct the container with count copies of elements with value ch. + * + * @param[in] count number of elements to construct. + * @param[in] ch value of all constructed elements. + * + * @pre must be called in transaction scope. + * + * @throw pmem::pool_error if an object is not in persistent memory. + * @throw pmem::transaction_alloc_error when allocating memory for + * underlying storage in transaction failed. + * @throw pmem::transaction_error if constructor wasn't called in + * transaction. + */ + basic_string(size_type count, CharT ch) + { + check_pmem_tx(); + + initialize(count, ch); + } + + /** + * Construct the string with a substring + * [pos, min(pos+count, other.size()) of other. + * + * @param[in] other string from which substring will be copied. + * @param[in] pos start position of substring in other. + * @param[in] count length of substring. + * + * @pre must be called in transaction scope. + * + * @throw std::out_of_range is pos > other.size() + * @throw pmem::pool_error if an object is not in persistent memory. + * @throw pmem::transaction_alloc_error when allocating memory for + * underlying storage in transaction failed. + * @throw pmem::transaction_error if constructor wasn't called in + * transaction. + */ + basic_string(const basic_string &other, size_type pos, + size_type count = npos) + { + check_pmem_tx(); + + if (pos > other.size()) + throw std::out_of_range("Index out of range."); + + if (count == npos || pos + count > other.size()) + count = other.size() - pos; + + auto first = static_cast(pos); + auto last = first + static_cast(count); + + initialize(other.cbegin() + first, other.cbegin() + last); + } + + /** + * Construct the string with the first count elements of C-style + * string s. + * + * @param[in] s pointer to source string. + * @param[in] count length of the resulting string. + * + * @pre must be called in transaction scope. + * + * @throw pmem::pool_error if an object is not in persistent memory. + * @throw pmem::transaction_alloc_error when allocating memory for + * underlying storage in transaction failed. + * @throw pmem::transaction_error if constructor wasn't called in + * transaction. + */ + basic_string(const CharT *s, size_type count) + { + check_pmem_tx(); + + initialize(s, s + count); + } + + /** + * Construct the string with the contents of s. + * + * @param[in] s pointer to source string. + * + * @pre must be called in transaction scope. + * + * @throw pmem::pool_error if an object is not in persistent memory. + * @throw pmem::transaction_alloc_error when allocating memory for + * underlying storage in transaction failed. + * @throw pmem::transaction_error if constructor wasn't called in + * transaction. + */ + basic_string(const CharT *s) + { + check_pmem_tx(); + + auto length = traits_type::length(s); + + initialize(s, s + length); + } + + /** + * Construct the string with the contents of the range [first, last). + * This constructor only participates in overload resolution if InputIt + * satisfies InputIterator. + * + * @param[in] first iterator to beginning of the range. + * @param[in] last iterator to end of the range. + * + * @pre must be called in transaction scope. + * + * @throw pmem::pool_error if an object is not in persistent memory. + * @throw pmem::transaction_alloc_error when allocating memory for + * underlying storage in transaction failed. + * @throw pmem::transaction_error if constructor wasn't called in + * transaction. + */ + template < + typename InputIt, + typename Enable = typename std::enable_if< + pmem::detail::is_input_iterator::value>::type> + basic_string(InputIt first, InputIt last) + { + assert(std::distance(first, last) >= 0); + + check_pmem_tx(); + + initialize(first, last); + } + + /** + * Copy constructor. Construct the string with the copy of the contents + * of other. + * + * @param[in] other reference to the string to be copied. + * + * @pre must be called in transaction scope. + * + * @throw pmem::pool_error if an object is not in persistent memory. + * @throw pmem::transaction_alloc_error when allocating memory for + * underlying storage in transaction failed. + * @throw pmem::transaction_error if constructor wasn't called in + * transaction. + */ + basic_string(const basic_string &other) + { + check_pmem_tx(); + + initialize(other.cbegin(), other.cend()); + } + + /** + * Move constructor. Construct the string with the contents of other + * using move semantics. + * + * @param[in] other rvalue reference to the string to be moved from. + * + * @pre must be called in transaction scope. + * + * @throw pmem::pool_error if an object is not in persistent memory. + * @throw pmem::transaction_alloc_error when allocating memory for + * underlying storage in transaction failed. + * @throw pmem::transaction_error if constructor wasn't called in + * transaction. + */ + basic_string(basic_string &&other) + { + check_pmem_tx(); + + initialize(std::move(other)); + + if (other.is_sso_used()) + other.initialize(0U, value_type('\0')); + } + + /** + * Construct the container with the contents of the initializer list + * init. + * + * @param[in] ilist initializer list with content to be constructed. + * + * @pre must be called in transaction scope. + * + * @throw pmem::pool_error if an object is not in persistent memory. + * @throw pmem::transaction_alloc_error when allocating memory for + * underlying storage in transaction failed. + * @throw pmem::transaction_error if constructor wasn't called in + * transaction. + */ + basic_string(std::initializer_list ilist) + { + check_pmem_tx(); + + initialize(ilist.begin(), ilist.end()); + } + + /** + * Destructor. + * + * XXX: implement free_data() + */ + ~basic_string() + { + if (!is_sso_used()) + detail::destroy(data_large); + } + + /** + * Copy assignment operator. Replace the string with contents of other + * transactionally. + * + * @param[in] other reference to the string to be copied. + * + * @throw pmem::transaction_alloc_error when allocating memory for + * underlying storage in transaction failed. + */ + basic_string & + operator=(const basic_string &other) + { + return assign(other); + } + + /** + * Move assignment operator. Replace the string with the contents of + * other using move semantics transactionally. + * + * @param[in] other rvalue reference to the string to be moved from. + * + * @throw pmem::transaction_alloc_error when allocating memory for + * underlying storage in transaction failed. + */ + basic_string & + operator=(basic_string &&other) + { + return assign(std::move(other)); + } + + /** + * Replace the contents with copy of C-style string s transactionally. + * + * @param[in] s pointer to source string. + * + * @throw pmem::transaction_alloc_error when allocating memory for + * underlying storage in transaction failed. + */ + basic_string & + operator=(const CharT *s) + { + return assign(s); + } + + /** + * Replace the contents with character ch transactionally. + * + * @param[in] ch character. + * + * @throw pmem::transaction_alloc_error when allocating memory for + * underlying storage in transaction failed. + */ + basic_string & + operator=(CharT ch) + { + return assign(1, ch); + } + + /** + * Replace the contents with those of the initializer list ilist + * transactionally. + * + * @param[in] ilist initializer_list of characters. + * + * @throw pmem::transaction_alloc_error when allocating memory for + * underlying storage in transaction failed. + */ + basic_string & + operator=(std::initializer_list ilist) + { + return assign(ilist); + } + + /** + * Replace the contents with count copies of character ch + * transactionally. + * + * @param[in] count number of characters. + * @param[in] ch character. + * + * @throw pmem::transaction_alloc_error when allocating memory for + * underlying storage in transaction failed. + */ + basic_string & + assign(size_type count, CharT ch) + { + auto pop = get_pool(); + + transaction::run(pop, [&] { replace(count, ch); }); + + return *this; + } + + /** + * Replace the string with the copy of the contents of other + * transactionally. + * + * @param[in] other reference to the string to be copied. + * + * @throw pmem::transaction_alloc_error when allocating memory for + * underlying storage in transaction failed. + */ + basic_string & + assign(const basic_string &other) + { + if (&other == this) + return *this; + + auto pop = get_pool(); + + transaction::run( + pop, [&] { replace(other.cbegin(), other.cend()); }); + + return *this; + } + + /** + * Replace the contents with a substring + * [pos, std::min(pos+count, other.size()) of other transactionally. + * + * @param[in] other string from which substring will be copied. + * @param[in] pos start position of substring in other. + * @param[in] count length of substring. + * + * @throw std::out_of_range is pos > other.size() + * @throw pmem::transaction_alloc_error when allocating memory for + * underlying storage in transaction failed. + */ + basic_string & + assign(const basic_string &other, size_type pos, size_type count = npos) + { + if (pos > other.size()) + throw std::out_of_range("Index out of range."); + + if (count == npos || pos + count > other.size()) + count = other.size() - pos; + + auto pop = get_pool(); + auto first = static_cast(pos); + auto last = first + static_cast(count); + + transaction::run(pop, [&] { + replace(other.cbegin() + first, other.cbegin() + last); + }); + + return *this; + } + + /** + * Replace the contents with the first count elements of C-style string + * s transactionally. + * + * @param[in] s pointer to source string. + * @param[in] count length of the string. + * + * @throw pmem::transaction_alloc_error when allocating memory for + * underlying storage in transaction failed. + */ + basic_string & + assign(const CharT *s, size_type count) + { + auto pop = get_pool(); + + transaction::run(pop, [&] { replace(s, s + count); }); + + return *this; + } + + /** + * Replace the contents with copy of C-style string s transactionally. + * + * @param[in] s pointer to source string. + * + * @throw pmem::transaction_alloc_error when allocating memory for + * underlying storage in transaction failed. + */ + basic_string & + assign(const CharT *s) + { + auto pop = get_pool(); + + auto length = traits_type::length(s); + + transaction::run(pop, [&] { replace(s, s + length); }); + + return *this; + } + + /** + * Replace the contents with copies of elements in the range [first, + * last) transactionally. This function participates in overload + * resolution only if InputIt satisfies InputIterator. + * + * @param[in] first iterator to beginning of the range. + * @param[in] last iterator to end of the range. + * + * @throw pmem::transaction_alloc_error when allocating memory for + * underlying storage in transaction failed. + */ + template ::type> + basic_string & + assign(InputIt first, InputIt last) + { + auto pop = get_pool(); + + transaction::run(pop, [&] { replace(first, last); }); + + return *this; + } + + /** + * Replace the string with the contents of other using move semantics + * transactionally. Other is left in valid state with size equal to 0. + * + * @param[in] other rvalue reference to the string to be moved from. + * + * @throw pmem::transaction_alloc_error when allocating memory for + * underlying storage in transaction failed. + */ + basic_string & + assign(basic_string &&other) + { + if (&other == this) + return *this; + + auto pop = get_pool(); + + transaction::run(pop, [&] { + replace(std::move(other)); + + if (other.is_sso_used()) + other.initialize(0U, value_type('\0')); + }); + + return *this; + } + + /** + * Replaces the contents with those of the initializer list ilist + * transactionally. + * + * @param[in] ilist initializer_list of characters. + * + * @throw pmem::transaction_alloc_error when allocating memory for + * underlying storage in transaction failed. + */ + basic_string & + assign(std::initializer_list ilist) + { + return assign(ilist.begin(), ilist.end()); + } + + /** + * Return an iterator to the beginning. + * + * @return an iterator pointing to the first element in the string. + */ + iterator + begin() + { + return is_sso_used() ? iterator(&*data_sso.begin()) + : iterator(&*data_large.begin()); + } + + /** + * Return const iterator to the beginning. + * + * @return const iterator pointing to the first element in the string. + */ + const_iterator + begin() const noexcept + { + return cbegin(); + } + + /** + * Return const iterator to the beginning. + * + * @return const iterator pointing to the first element in the string. + */ + const_iterator + cbegin() const noexcept + { + return is_sso_used() ? const_iterator(&*data_sso.cbegin()) + : const_iterator(&*data_large.cbegin()); + } + + /** + * Return an iterator to past the end. + * + * @return iterator referring to the past-the-end element in the string. + */ + iterator + end() + { + return begin() + static_cast(size()); + } + + /** + * Return const iterator to past the end. + * + * @return const_iterator referring to the past-the-end element in the + * string. + */ + const_iterator + end() const noexcept + { + return cbegin() + static_cast(size()); + } + + /** + * Return const iterator to past the end. + * + * @return const_iterator referring to the past-the-end element in the + * string. + */ + const_iterator + cend() const noexcept + { + return cbegin() + static_cast(size()); + } + + /** + * Return a reverse iterator to the beginning. + * + * @return a reverse iterator pointing to the last element in + * non-reversed string. + */ + reverse_iterator + rbegin() + { + return reverse_iterator(end()); + } + + /** + * Return a const reverse iterator to the beginning. + * + * @return a const reverse iterator pointing to the last element in + * non-reversed string. + */ + const_reverse_iterator + rbegin() const noexcept + { + return crbegin(); + } + + /** + * Return a const reverse iterator to the beginning. + * + * @return a const reverse iterator pointing to the last element in + * non-reversed string. + */ + const_reverse_iterator + crbegin() const noexcept + { + return const_reverse_iterator(cend()); + } + + /** + * Return a reverse iterator to the end. + * + * @return reverse iterator referring to character preceding first + * character in the non-reversed string. + */ + reverse_iterator + rend() + { + return reverse_iterator(begin()); + } + + /** + * Return a const reverse iterator to the end. + * + * @return const reverse iterator referring to character preceding + * first character in the non-reversed string. + */ + const_reverse_iterator + rend() const noexcept + { + return crend(); + } + + /** + * Return a const reverse iterator to the end. + * + * @return const reverse iterator referring to character preceding + * first character in the non-reversed string. + */ + const_reverse_iterator + crend() const noexcept + { + return const_reverse_iterator(cbegin()); + } + + /** + * Access element at specific index with bounds checking and snapshot it + * if there is an active transaction. + * + * @param[in] n index number. + * + * @return reference to element number n in underlying array. + * + * @throw std::out_of_range if n is not within the range of the + * container. + * @throw pmem::transaction_error when adding the object to the + * transaction failed. + */ + reference + at(size_type n) + { + if (n >= size()) + throw std::out_of_range("string::at"); + + return is_sso_used() ? data_sso[n] : data_large[n]; + } + + /** + * Access element at specific index with bounds checking. + * + * @param[in] n index number. + * + * @return const_reference to element number n in underlying array. + * + * @throw std::out_of_range if n is not within the range of the + * container. + */ + const_reference + at(size_type n) const + { + return const_at(n); + } + + /** + * Access element at specific index with bounds checking. In + * contradiction to at(), const_at() will return const_reference not + * depending on the const-qualification of the object it is called on. + * std::basic_string doesn't provide const_at() method. + * + * @param[in] n index number. + * + * @return const_reference to element number n in underlying array. + * + * @throw std::out_of_range if n is not within the range of the + * container. + */ + const_reference + const_at(size_type n) const + { + if (n >= size()) + throw std::out_of_range("string::const_at"); + + return is_sso_used() + ? static_cast(data_sso)[n] + : static_cast(data_large)[n]; + } + + /** + * Access element at specific index and snapshot it if there is an + * active transaction. No bounds checking is performed. + * + * @param[in] n index number. + * + * @return reference to element number n in underlying array. + * + * @throw pmem::transaction_error when adding the object to the + * transaction failed. + */ + reference operator[](size_type n) + { + return is_sso_used() ? data_sso[n] : data_large[n]; + } + + /** + * Access element at specific index. No bounds checking is performed. + * + * @param[in] n index number. + * + * @return const_reference to element number n in underlying array. + */ + const_reference operator[](size_type n) const + { + return is_sso_used() ? data_sso[n] : data_large[n]; + } + + /** + * Access first element and snapshot it if there is an + * active transaction. + * + * @return reference to first element in string. + * + * @throw pmem::transaction_error when adding the object to the + * transaction failed. + */ + CharT & + front() + { + return (*this)[0]; + } + + /** + * Access first element. + * + * @return const reference to first element in string. + */ + const CharT & + front() const + { + return cfront(); + } + + /** + * Access first element. In contradiction to front(), cfront() will + * return const_reference not depending on the const-qualification of + * the object it is called on. std::basic_string doesn't provide + * cfront() method. + * + * @return const reference to first element in string. + */ + const CharT & + cfront() const + { + return static_cast(*this)[0]; + } + + /** + * Access last element and snapshot it if there is an + * active transaction. + * + * @return reference to last element in string. + * + * @throw pmem::transaction_error when adding the object to the + * transaction failed. + */ + CharT & + back() + { + return (*this)[size() - 1]; + } + + /** + * Access last element. + * + * @return const reference to last element in string. + */ + const CharT & + back() const + { + return cback(); + } + + /** + * Access last element. In contradiction to back(), cback() will return + * const_reference not depending on the const-qualification of the + * object it is called on. std::basic_string doesn't provide + * cback() method. + * + * @return const reference to last element in string. + */ + const CharT & + cback() const + { + return static_cast(*this)[size() - 1]; + } + + /** + * @return number of CharT elements in the string. + */ + size_type + size() const noexcept + { + if (is_sso_used()) + return _size; + else if (data_large.size() == 0) + return 0; + else + return data_large.size() - sizeof('\0'); + } + + /** + * @return pointer to underlying data. + * + * @throw transaction_error when adding data to the + * transaction failed. + */ + CharT * + data() + { + return is_sso_used() + ? data_sso.range(0, size() + sizeof('\0')).begin() + : data_large.data(); + } + + /** + * Compares [pos, pos + count1) substring of this to + * [s, s + count2) substring of s. + * + * If count > size() - pos, substring is equal to [pos, size()). + * + * @param[in] pos beginning of substring of this. + * @param[in] count1 length of substring of this. + * @param[in] s C-style string to compare to. + * @param[in] count2 length of substring of s. + * + * @return negative value if substring of *this < substring of s in + * lexicographical order, zero if substring of *this == substring of + * s and positive value if substring of *this > substring of s. + * + * @throw std::out_of_range is pos > size() + */ + int + compare(size_type pos, size_type count1, const CharT *s, + size_type count2) const + { + if (pos > size()) + throw std::out_of_range("Index out of range."); + + if (count1 > size() - pos) + count1 = size() - pos; + + auto ret = traits_type::compare( + cdata() + pos, s, std::min(count1, count2)); + + if (ret != 0) + return ret; + + if (count1 < count2) + return -1; + else if (count1 == count2) + return 0; + else + return 1; + } + + /** + * Compares this string to other. + * + * @param[in] other string to compare to. + * + * @return negative value if *this < other in lexicographical order, + * zero if *this == other and positive value if *this > other. + */ + int + compare(const basic_string &other) const + { + return compare(0, size(), other.cdata(), other.size()); + } + + /** + * Compares [pos, pos + count) substring of this to other. + * If count > size() - pos, substring is equal to [pos, size()). + * + * @param[in] pos beginning of the substring. + * @param[in] count length of the substring. + * @param[in] other string to compare to. + * + * @return negative value if substring < other in lexicographical order, + * zero if substring == other and positive value if substring > other. + * + * @throw std::out_of_range is pos > size() + */ + int + compare(size_type pos, size_type count, const basic_string &other) const + { + return compare(pos, count, other.cdata(), other.size()); + } + + /** + * Compares [pos1, pos1 + count1) substring of this to + * [pos2, pos2 + count2) substring of other. + * + * If count1 > size() - pos, substring is equal to [pos1, size()). + * + * @param[in] pos1 beginning of substring of this. + * @param[in] count1 length of substring of this. + * @param[in] other string to compare to. + * @param[in] pos2 beginning of substring of other. + * @param[in] count2 length of substring of other. + * + * @return negative value if substring of *this < substring of other in + * lexicographical order, zero if substring of *this == substring of + * other and positive value if substring of *this > substring of other. + * + * @throw std::out_of_range is pos1 > size() or pos2 > other.size() + */ + int + compare(size_type pos1, size_type count1, const basic_string &other, + size_type pos2, size_type count2 = npos) const + { + if (pos2 > other.size()) + throw std::out_of_range("Index out of range."); + + if (count2 > other.size() - pos2) + count2 = other.size() - pos2; + + return compare(pos1, count1, other.cdata() + pos2, count2); + } + + /** + * Compares this string to s. + * + * @param[in] s C-style string to compare to. + * + * @return negative value if *this < s in lexicographical order, + * zero if *this == s and positive value if *this > s. + */ + int + compare(const CharT *s) const + { + return compare(0, size(), s, traits_type::length(s)); + } + + /** + * Compares [pos, pos + count) substring of this to s. + * If count > size() - pos, substring is equal to [pos, size()). + * + * @param[in] pos beginning of the substring. + * @param[in] count length of the substring. + * @param[in] s C-style string to compare to. + * + * @return negative value if substring < s in lexicographical order, + * zero if substring == s and positive value if substring > s. + * + * @throw std::out_of_range is pos > size() + */ + int + compare(size_type pos, size_type count, const CharT *s) const + { + return compare(pos, count, s, traits_type::length(s)); + } + + /** + * @return const pointer to underlying data. + */ + const CharT * + cdata() const noexcept + { + return is_sso_used() ? data_sso.cdata() : data_large.cdata(); + } + + /** + * @return pointer to underlying data. + */ + const CharT * + data() const noexcept + { + return cdata(); + } + + /** + * @return pointer to underlying data. + */ + const CharT * + c_str() const noexcept + { + return cdata(); + } + + /** + * @return number of CharT elements in the string. + */ + size_type + length() const noexcept + { + return size(); + } + + /** + * @return maximum number of elements the string is able to hold. + */ + size_type + max_size() const noexcept + { + return PMEMOBJ_MAX_ALLOC_SIZE / sizeof(CharT); + } + + /** + * @return number of characters that can be held in currently allocated + * storage. + */ + size_type + capacity() const noexcept + { + return is_sso_used() ? sso_capacity + : data_large.capacity() - sizeof('\0'); + } + + /** + * @return true if string is empty, false otherwise. + */ + bool + empty() const noexcept + { + return size() == 0; + } + + /* Special value. The exact meaning depends on the context. */ + static const size_type npos = static_cast(-1); + +private: + using sso_type = array; + using non_sso_type = vector; + + /** + * This union holds sso data inside of an array and non sso data inside + * a vector. If vector is used, it must be manually created and + * destroyed. + */ + union { + sso_type data_sso; + + non_sso_type data_large; + }; + + /* Holds size if sso is used, std::numeric_limits::max() + * otherwise */ + p _size; + + bool + is_sso_used() const + { + assert(_size <= sso_capacity || + _size == std::numeric_limits::max()); + + return _size <= sso_capacity; + } + + void + destroy_data() + { + assert(pmemobj_tx_stage() == TX_STAGE_WORK); + + /* + * XXX: this can be optimized - only snapshot length() elements. + */ +#if LIBPMEMOBJ_CPP_VG_MEMCHECK_ENABLED + VALGRIND_MAKE_MEM_DEFINED(&data_sso, sizeof(data_sso)); +#endif + + if (is_sso_used()) { + data_sso.data(); + /* data_sso constructor does not have to be called */ + } else { + data_large.free_data(); + detail::destroy(data_large); + } + } + + /** + * Overload of generic get_size method used to calculate size + * based on provided parameters. + * + * Return std::distance(first, last) for pair of iterators. + */ + template < + typename InputIt, + typename Enable = typename std::enable_if< + pmem::detail::is_input_iterator::value>::type> + size_type + get_size(InputIt first, InputIt last) const + { + return static_cast(std::distance(first, last)); + } + + /** + * Overload of generic get_size method used to calculate size + * based on provided parameters. + * + * Return count for (count, value) + */ + size_type + get_size(size_type count, value_type ch) const + { + return count; + } + + /** + * Overload of generic get_size method used to calculate size + * based on provided parameters. + * + * Return size of other basic_string + */ + size_type + get_size(const basic_string &other) const + { + return other.size(); + } + + /** + * Generic function which replaces current content based on provided + * parameters. Allowed parameters are: + * - size_type count, CharT value + * - InputIt first, InputIt last + * - basic_string && + */ + template + pointer + replace(Args &&... args) + { + assert(pmemobj_tx_stage() == TX_STAGE_WORK); + + auto new_size = get_size(std::forward(args)...); + + /* If data_large is used and there is enough capacity */ + if (!is_sso_used() && new_size <= capacity()) + return assign_large_data(std::forward(args)...); + + destroy_data(); + + return initialize(std::forward(args)...); + } + + /** + * Generic function which initializes memory based on provided + * parameters - forwards parameters to initialize function of either + * data_large or data_sso. Allowed parameters are: + * - size_type count, CharT value + * - InputIt first, InputIt last + * - basic_string && + * + * @pre must be called in transaction scope. + */ + template + pointer + initialize(Args &&... args) + { + assert(pmemobj_tx_stage() == TX_STAGE_WORK); + + auto new_size = get_size(std::forward(args)...); + + if (new_size <= sso_capacity) + _size = new_size; + else + _size = std::numeric_limits::max(); + + if (is_sso_used()) { + /* + * array is aggregate type so it's not required to call + * a constructor. + */ + return assign_sso_data(std::forward(args)...); + } else { + detail::create(&data_large); + return assign_large_data(std::forward(args)...); + } + } + + /** + * Initialize sso data. Overload for pair of iterators + */ + template < + typename InputIt, + typename Enable = typename std::enable_if< + pmem::detail::is_input_iterator::value>::type> + pointer + assign_sso_data(InputIt first, InputIt last) + { + auto size = static_cast(std::distance(first, last)); + + assert(pmemobj_tx_stage() == TX_STAGE_WORK); + assert(size <= sso_capacity); + + auto dest = data_sso.range(0, size + sizeof('\0')).begin(); + std::copy(first, last, dest); + + dest[size] = value_type('\0'); + + return dest; + } + + /** + * Initialize sso data. Overload for (count, value). + */ + pointer + assign_sso_data(size_type count, value_type ch) + { + assert(pmemobj_tx_stage() == TX_STAGE_WORK); + assert(count <= sso_capacity); + + auto dest = data_sso.range(0, count + sizeof('\0')).begin(); + traits_type::assign(dest, count, ch); + + dest[count] = value_type('\0'); + + return dest; + } + + /** + * Initialize sso data. Overload for rvalue reference of basic_string. + */ + pointer + assign_sso_data(basic_string &&other) + { + assert(pmemobj_tx_stage() == TX_STAGE_WORK); + + return assign_sso_data(other.cbegin(), other.cend()); + } + + /** + * Initialize data_large - call constructor of data_large. + * Overload for pair of iterators. + */ + template < + typename InputIt, + typename Enable = typename std::enable_if< + pmem::detail::is_input_iterator::value>::type> + pointer + assign_large_data(InputIt first, InputIt last) + { + assert(pmemobj_tx_stage() == TX_STAGE_WORK); + + auto size = static_cast(std::distance(first, last)); + + data_large.reserve(size + sizeof('\0')); + data_large.assign(first, last); + data_large.push_back(value_type('\0')); + + return data_large.data(); + } + + /** + * Initialize data_large - call constructor of data_large. + * Overload for (count, value). + */ + pointer + assign_large_data(size_type count, value_type ch) + { + assert(pmemobj_tx_stage() == TX_STAGE_WORK); + + data_large.reserve(count + sizeof('\0')); + data_large.assign(count, ch); + data_large.push_back(value_type('\0')); + + return data_large.data(); + } + + /** + * Initialize data_large - call constructor of data_large. + * Overload for rvalue reference of basic_string. + */ + pointer + assign_large_data(basic_string &&other) + { + assert(pmemobj_tx_stage() == TX_STAGE_WORK); + + if (other.is_sso_used()) + return assign_large_data(other.cbegin(), other.cend()); + + data_large = std::move(other.data_large); + + return data_large.data(); + } + + /** + * Return pool_base instance and assert that object is on pmem. + */ + pool_base + get_pool() const + { + auto pop = pmemobj_pool_by_ptr(this); + assert(pop != nullptr); + + return pool_base(pop); + } + + /** + * @throw pmem::pool_error if an object is not in persistent memory. + */ + void + check_pmem() const + { + if (pmemobj_pool_by_ptr(this) == nullptr) + throw pool_error("Object is not on pmem."); + } + + /** + * @throw pmem::transaction_error if called outside of a transaction. + */ + void + check_tx_stage_work() const + { + if (pmemobj_tx_stage() != TX_STAGE_WORK) + throw transaction_error( + "Call made out of transaction scope."); + } + + /** + * @throw pmem::pool_error if an object is not in persistent memory. + * @throw pmem::transaction_error if called outside of a transaction. + */ + void + check_pmem_tx() const + { + check_pmem(); + check_tx_stage_work(); + } +}; + +/** + * Non-member equal operator. + */ +template +bool +operator==(const basic_string &lhs, + const basic_string &rhs) +{ + return lhs.compare(rhs) == 0; +} + +/** + * Non-member not equal operator. + */ +template +bool +operator!=(const basic_string &lhs, + const basic_string &rhs) +{ + return lhs.compare(rhs) != 0; +} + +/** + * Non-member less than operator. + */ +template +bool +operator<(const basic_string &lhs, + const basic_string &rhs) +{ + return lhs.compare(rhs) < 0; +} + +/** + * Non-member less or equal operator. + */ +template +bool +operator<=(const basic_string &lhs, + const basic_string &rhs) +{ + return lhs.compare(rhs) <= 0; +} + +/** + * Non-member greater than operator. + */ +template +bool +operator>(const basic_string &lhs, + const basic_string &rhs) +{ + return lhs.compare(rhs) > 0; +} + +/** + * Non-member greater or equal operator. + */ +template +bool +operator>=(const basic_string &lhs, + const basic_string &rhs) +{ + return lhs.compare(rhs) >= 0; +} + +/** + * Non-member equal operator. + */ +template +bool +operator==(const CharT *lhs, const basic_string &rhs) +{ + return rhs.compare(lhs) == 0; +} + +/** + * Non-member not equal operator. + */ +template +bool +operator!=(const CharT *lhs, const basic_string &rhs) +{ + return rhs.compare(lhs) != 0; +} + +/** + * Non-member less than operator. + */ +template +bool +operator<(const CharT *lhs, const basic_string &rhs) +{ + return rhs.compare(lhs) > 0; +} + +/** + * Non-member less or equal operator. + */ +template +bool +operator<=(const CharT *lhs, const basic_string &rhs) +{ + return rhs.compare(lhs) >= 0; +} + +/** + * Non-member greater than operator. + */ +template +bool +operator>(const CharT *lhs, const basic_string &rhs) +{ + return rhs.compare(lhs) < 0; +} + +/** + * Non-member greater or equal operator. + */ +template +bool +operator>=(const CharT *lhs, const basic_string &rhs) +{ + return rhs.compare(lhs) <= 0; +} + +/** + * Non-member equal operator. + */ +template +bool +operator==(const basic_string &lhs, const CharT *rhs) +{ + return lhs.compare(rhs) == 0; +} + +/** + * Non-member not equal operator. + */ +template +bool +operator!=(const basic_string &lhs, const CharT *rhs) +{ + return lhs.compare(rhs) != 0; +} + +/** + * Non-member less than operator. + */ +template +bool +operator<(const basic_string &lhs, const CharT *rhs) +{ + return lhs.compare(rhs) < 0; +} + +/** + * Non-member less or equal operator. + */ +template +bool +operator<=(const basic_string &lhs, const CharT *rhs) +{ + return lhs.compare(rhs) <= 0; +} + +/** + * Non-member greater than operator. + */ +template +bool +operator>(const basic_string &lhs, const CharT *rhs) +{ + return lhs.compare(rhs) > 0; +} + +/** + * Non-member greater or equal operator. + */ +template +bool +operator>=(const basic_string &lhs, const CharT *rhs) +{ + return lhs.compare(rhs) >= 0; +} + +} /* namespace experimental */ + +} /* namespace obj */ + +} /* namespace pmem */ + +#endif /* LIBPMEMOBJ_CPP_BASIC_STRING_HPP */ diff --git a/include/libpmemobj++/experimental/contiguous_iterator.hpp b/include/libpmemobj++/experimental/contiguous_iterator.hpp new file mode 100644 index 0000000..f89251a --- /dev/null +++ b/include/libpmemobj++/experimental/contiguous_iterator.hpp @@ -0,0 +1,433 @@ +/* + * Copyright 2018-2019, Intel Corporation + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * * Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +/** + * @file + * Iterators for pmem::obj::array + */ + +#ifndef LIBPMEMOBJ_CPP_ARRAY_ITERATOR_HPP +#define LIBPMEMOBJ_CPP_ARRAY_ITERATOR_HPP + +#include +#include +#include + +#include + +namespace pmem +{ + +namespace obj +{ + +namespace experimental +{ + +/** + * Base class for iterators which satisfies RandomAccessIterator + * and operate on contiguous memory. + */ +template +struct contiguous_iterator { + /** + * Constructor taking a pointer. + */ + constexpr contiguous_iterator(Pointer begin) : ptr(begin) + { + } + + /** + * Dereference operator. + */ + Reference operator*() const + { + return *ptr; + } + + /** + * Arrow operator. + */ + Pointer operator->() const + { + return ptr; + } + + /** + * Prefix increment operator. + */ + Iterator & + operator++() + { + static_cast(this)->change_by(1); + return *static_cast(this); + } + + /** + * Postfix increment operator. + */ + Iterator + operator++(int) + { + Iterator tmp(*static_cast(this)); + static_cast(this)->change_by(1); + return tmp; + } + + /** + * Prefix decrement operator. + */ + Iterator & + operator--() + { + static_cast(this)->change_by(-1); + return *static_cast(this); + } + + /** + * Postfix decrement operator. + */ + Iterator + operator--(int) + { + Iterator tmp(*static_cast(this)); + static_cast(this)->change_by(-1); + return tmp; + } + + /** + * Addition assignment operator. + */ + Iterator & + operator+=(std::ptrdiff_t n) + { + static_cast(this)->change_by(n); + return *static_cast(this); + } + + /** + * Subtraction assignment operator. + */ + Iterator & + operator-=(std::ptrdiff_t n) + { + static_cast(this)->change_by(-n); + return *static_cast(this); + } + + /** + * Addition operator. + */ + Iterator + operator+(std::ptrdiff_t n) const + { + Iterator tmp(*static_cast(this)); + tmp += n; + return tmp; + } + + /** + * Subtraction operator overload for integral type. + */ + Iterator + operator-(std::ptrdiff_t n) const + { + Iterator tmp(*static_cast(this)); + tmp -= n; + return tmp; + } + + /** + * Subtraction operator overload Iterator type. + */ + friend std::ptrdiff_t + operator-(const Iterator &lhs, const Iterator &rhs) + { + return lhs.ptr - rhs.ptr; + } + + /** + * Element access operator. + */ + Reference operator[](std::size_t n) + { + return ptr[n]; + } + + Pointer + get_ptr() const + { + return ptr; + } + +protected: + /** + * Function for changing underlying pointer. + * This is where static polymorphism is used. Derived classes + * can override this method and snapshot data if necessary. + */ + void + change_by(std::ptrdiff_t n) + { + ptr += n; + } + + Pointer ptr; +}; + +/** + * Non-const iterator which adds elements to a transaction in a bulk. + * + * This is done by dividing underlying array into ranges of specified + * (snapshot_size) size. If iterator is incremented/decremented/etc. + * so that it is moved to another range, this new range is added to + * a transaction. + * + * For example, let's assume snapshot_size = 2, N = 6. This gives us: + * 0 1 | 2 3 | 4 5 + * + * If iterator is moved from 1 to 3, that means it is now in another + * range, and that range must be added to a transaction + * (elements 2 and 3). + */ +template +struct range_snapshotting_iterator + : public contiguous_iterator, T &, T *> { + using iterator_category = std::random_access_iterator_tag; + using value_type = T; + using difference_type = std::ptrdiff_t; + using reference = T &; + using pointer = T *; + using base_type = contiguous_iterator, + reference, pointer>; + + /** + * Constructor taking pointer to data, pointer to the beginning + * of the array and snapshot_size. + */ + range_snapshotting_iterator(pointer ptr = nullptr, + pointer data = nullptr, + std::size_t size = 0, + std::size_t snapshot_size = 1) + : base_type(ptr), + data(data), + size(size), + snapshot_size(snapshot_size) + { + assert(data <= ptr); + + if (snapshot_size > 0) + snapshot_range(ptr); + } + + /** + * Conversion operator to const T*. + */ + operator const T *() + { + return this->ptr; + } + + /** + * Element access operator. + * + * Adds element to a transaction. + */ + reference operator[](std::size_t n) + { + detail::conditional_add_to_tx(&this->ptr[n]); + return base_type::operator[](n); + } + + /** + * Non-member swap function. + */ + friend void + swap(range_snapshotting_iterator &lhs, range_snapshotting_iterator &rhs) + { + std::swap(lhs.ptr, rhs.ptr); + std::swap(lhs.data, rhs.data); + std::swap(lhs.size, rhs.size); + std::swap(lhs.snapshot_size, rhs.snapshot_size); + } + + template + friend struct contiguous_iterator; + +protected: + void + change_by(std::ptrdiff_t n) + { + conditional_snapshot_range(this->ptr, n); + base_type::change_by(n); + } + +private: + /* + * Conditionally snapshot range of length snapshot_size, + * which contain address equal to ptr + diff. + */ + void + conditional_snapshot_range(pointer ptr, difference_type diff) + { + if (snapshot_size == 0) + return; + + auto new_ptr = ptr + diff; + + /* if new pointer is outside of the array */ + if (new_ptr < data || new_ptr >= data + size) + return; + + /* if new pointer is in the same range */ + if (static_cast(ptr - data) / snapshot_size == + static_cast(new_ptr - data) / snapshot_size) + return; + + snapshot_range(new_ptr); + } + + void + snapshot_range(pointer ptr) + { + /* align index to snapshot_size */ + auto range_begin = + ptr - static_cast(ptr - data) % snapshot_size; + auto range_size = snapshot_size; + + if (range_begin + range_size > data + size) + range_size = static_cast(data + size - + range_begin); +#ifndef NDEBUG + verify_range(range_begin, range_size); +#endif + + detail::conditional_add_to_tx(range_begin, range_size); + } + +#ifndef NDEBUG + void + verify_range(pointer range_begin, uint64_t range_size) + { + auto range_offset = static_cast(range_begin - data); + + assert(range_begin >= data); + assert(range_offset % snapshot_size == 0); + assert((range_offset + range_size) % snapshot_size == 0 || + range_begin + range_size == data + size); + } +#endif + + pointer data; + std::size_t size; + std::size_t snapshot_size; +}; + +/** + * Default non-const iterator which adds element to a transaction + * on every access. + */ +template +struct basic_contiguous_iterator + : public contiguous_iterator, T &, T *> { + using iterator_category = std::random_access_iterator_tag; + using value_type = T; + using difference_type = std::ptrdiff_t; + using reference = T &; + using pointer = T *; + using base_type = contiguous_iterator, + reference, pointer>; + + /** + * Constructor taking pointer and snapshotting function as + * arguments. + */ + basic_contiguous_iterator(pointer ptr = nullptr) : base_type(ptr) + { + } + + /** + * Conversion operator to const T*. + */ + operator const T *() + { + return this->ptr; + } + + /** + * Dereference operator which adds dereferenced element to + * a transaction. + */ + reference operator*() const + { + detail::conditional_add_to_tx(this->ptr); + return base_type::operator*(); + } + + /** + * Arrow operator which adds underlying element to + * a transactions. + */ + pointer operator->() const + { + detail::conditional_add_to_tx(this->ptr); + return base_type::operator->(); + } + + /** + * Element access operator. + * + * Adds range containing specified element to a transaction. + */ + reference operator[](std::size_t n) + { + detail::conditional_add_to_tx(&this->ptr[n]); + return base_type::operator[](n); + } + + /** + * Non-member swap function. + */ + friend void + swap(basic_contiguous_iterator &lhs, basic_contiguous_iterator &rhs) + { + std::swap(lhs.ptr, rhs.ptr); + } +}; + +} /* namespace experimental */ + +} /* namespace obj */ + +} /* namespace pmem */ + +#endif /* LIBPMEMOBJ_CPP_ARRAY_ITERATOR_HPP */ diff --git a/include/libpmemobj++/experimental/slice.hpp b/include/libpmemobj++/experimental/slice.hpp new file mode 100644 index 0000000..d0e3720 --- /dev/null +++ b/include/libpmemobj++/experimental/slice.hpp @@ -0,0 +1,167 @@ +/* + * Copyright 2018, Intel Corporation + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * * Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +/** + * @file + * Iterface to access sequence of objects. + */ + +#ifndef LIBPMEMOBJ_CPP_SLICE_HPP +#define LIBPMEMOBJ_CPP_SLICE_HPP + +#include +#include + +namespace pmem +{ + +namespace obj +{ + +namespace experimental +{ + +/** + * pmem::obj::experimental::slice - provides interface to access + * sequence of objects. + */ +template +class slice { +public: + using size_type = std::size_t; + using iterator = Iterator; + using reverse_iterator = std::reverse_iterator; + using reference = typename std::iterator_traits::reference; + + /** + * Constructor taking two RandomAccess iterators which define a range. + * + * @throw std::out_of_range if it_end < it_begin. + */ + slice(Iterator begin, Iterator end) : it_begin(begin), it_end(end) + { + static_assert( + std::is_same::iterator_category, + std::random_access_iterator_tag>::value, + "Iterator should have RandomAccessIterator tag"); + + if (it_end < it_begin) + throw std::out_of_range("pmem::obj::slice"); + } + + /** + * Defaulted copy constructor. + */ + slice(const slice &other) noexcept = default; + + /** + * Defaulted assignment operator. + */ + slice &operator=(const slice &other) noexcept = default; + + /** + * Returns iterator to the beginning of the range. + */ + iterator + begin() const noexcept + { + return it_begin; + } + + /** + * Returns iterator to the end of the range. + */ + iterator + end() const noexcept + { + return it_end; + } + + /** + * Returns reverse iterator to the end. + */ + reverse_iterator + rend() const noexcept + { + return reverse_iterator(it_begin); + } + + /** + * Returns reverse iterator to the beginning. + */ + reverse_iterator + rbegin() const noexcept + { + return reverse_iterator(it_end); + } + + /** + * Element access operator. + * + * @throw std::out_of_range if idx is greater or equal to size. + */ + reference + at(size_type idx) + { + if (idx >= size()) + throw std::out_of_range("pmem::obj::slice"); + + return it_begin[idx]; + } + + /** + * Element access operator. + * No bounds checking is performed. + */ + reference operator[](size_type idx) + { + return it_begin[idx]; + } + + size_type + size() const + { + return static_cast(it_end - it_begin); + } + +private: + iterator it_begin, it_end; +}; + +} /* namespace experimental */ + +} /* namespace obj */ + +} /* namespace pmem */ + +#endif /* LIBPMEMOBJ_CPP_SLICE_HPP */ diff --git a/include/libpmemobj++/experimental/string.hpp b/include/libpmemobj++/experimental/string.hpp new file mode 100644 index 0000000..0f90909 --- /dev/null +++ b/include/libpmemobj++/experimental/string.hpp @@ -0,0 +1,63 @@ +/* + * Copyright 2019, Intel Corporation + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * * Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +/** + * @file + * String typedefs for common character types. + */ + +#ifndef LIBPMEMOBJ_CPP_STRING_HPP +#define LIBPMEMOBJ_CPP_STRING_HPP + +#include + +namespace pmem +{ + +namespace obj +{ + +namespace experimental +{ + +using string = basic_string; +using wstring = basic_string; +using u16string = basic_string; +using u32string = basic_string; + +} /* namespace experimental */ + +} /* namespace obj */ + +} /* namespace pmem */ + +#endif /* LIBPMEMOBJ_CPP_STRING_HPP */ diff --git a/include/libpmemobj++/experimental/v.hpp b/include/libpmemobj++/experimental/v.hpp new file mode 100644 index 0000000..6e3b50c --- /dev/null +++ b/include/libpmemobj++/experimental/v.hpp @@ -0,0 +1,216 @@ +/* + * Copyright 2018-2019, Intel Corporation + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * * Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +/** + * @file + * Volatile resides on pmem property template. + */ + +#ifndef LIBPMEMOBJ_CPP_V_HPP +#define LIBPMEMOBJ_CPP_V_HPP + +#include + +#include +#include + +namespace pmem +{ + +namespace obj +{ + +namespace experimental +{ + +/** + * pmem::obj::experimental::v - volatile resides on pmem class. + * + * v class is a property-like template class that has to be used for all + * volatile variables that reside on persistent memory. + * This class ensures that the enclosed type is always properly initialized by + * always calling the class default constructor exactly once per instance of the + * application. + * This class has 8 bytes of storage overhead. + * @snippet doc_snippets/v.cpp v_property_example + */ +template +class v { +public: + static_assert(std::is_default_constructible::value, + "Type T must be default constructible"); + + /** + * Defaulted constructor. + */ + v() noexcept : vlt{0} + { + } + + /** + * Destructor. + */ + ~v() + { + /* Destructor of val should NOT be called */ + } + + /** + * Assignment operator. + */ + v & + operator=(const T &rhs) + { + /* make sure object is initialized */ + (void)get(); + + val = rhs; + + return *this; + } + + /** + * Assignment operator. + */ + v & + operator=(v &rhs) + { + return *this = rhs.get(); + } + + /** + * Converting assignment operator from a different v<>. + * + * Available only for convertible types. + */ + template ::value>::type> + v & + operator=(v &rhs) + { + return *this = rhs.get(); + } + + /** + * Retrieves reference to the object. + * + * @param[in] args forwarded to objects constructor. If object was + * constructed earlier during application lifetime (even with different + * arguments) no constructor is called. + * + * @return a reference to the object. + */ + template + T & + get(Args &&... args) noexcept + { + auto arg_pack = + std::forward_as_tuple(std::forward(args)...); + + PMEMobjpool *pop = pmemobj_pool_by_ptr(this); + if (pop == NULL) + return this->val; + + T *value = static_cast(pmemobj_volatile( + pop, &this->vlt, &this->val, sizeof(T), + pmem::detail::c_style_construct, + static_cast(&arg_pack))); + + return *value; + } + + /** + * Retrieves reference to the object. + * + * If object was not constructed (e.g. using get()) return value is + * unspecified. + * + * @return a reference to the object. + */ + T & + unsafe_get() + { + return val; + } + + /** + * Conversion operator back to the underlying type. + */ + operator T &() noexcept + { + return this->get(); + } + + /** + * Swaps two v objects of the same type. + */ + void + swap(v &other) + { + std::swap(get(), other.get()); + } + +private: + struct pmemvlt vlt; + + /* + * Normally C++ requires all class members to be constructed during + * enclosing type construction. Holding a value inside of a union allows + * to bypass this requirement. val is only constructed by call to get(). + */ + union { + T val; + }; +}; + +/** + * Swaps two v objects of the same type. + * + * Non-member swap function as required by Swappable concept. + * en.cppreference.com/w/cpp/concept/Swappable + */ +template +inline void +swap(v &a, v &b) +{ + a.swap(b); +} + +} /* namespace experimental */ + +} /* namespace obj */ + +} /* namespace pmem */ + +#endif /* LIBPMEMOBJ_CPP_V_HPP */ diff --git a/include/libpmemobj++/experimental/vector.hpp b/include/libpmemobj++/experimental/vector.hpp new file mode 100644 index 0000000..f0ede86 --- /dev/null +++ b/include/libpmemobj++/experimental/vector.hpp @@ -0,0 +1,2789 @@ +/* + * Copyright 2018-2019, Intel Corporation + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * * Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +/** + * @file + * Vector container with std::vector compatible interface. + */ + +#ifndef LIBPMEMOBJ_CPP_VECTOR_HPP +#define LIBPMEMOBJ_CPP_VECTOR_HPP + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +namespace pmem +{ + +namespace obj +{ + +namespace experimental +{ + +/** + * pmem::obj::experimental::vector - EXPERIMENTAL persistent container + * with std::vector compatible interface. + */ +template +class vector { +public: + /* Member types */ + using value_type = T; + 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 = basic_contiguous_iterator; + using const_iterator = const_pointer; + using reverse_iterator = std::reverse_iterator; + using const_reverse_iterator = std::reverse_iterator; + + /* Constructors */ + vector(); + vector(size_type count, const value_type &value); + explicit vector(size_type count); + template ::value, + InputIt>::type * = nullptr> + vector(InputIt first, InputIt last); + vector(const vector &other); + vector(vector &&other); + vector(std::initializer_list init); + vector(const std::vector &other); + + /* Assign operators */ + vector &operator=(const vector &other); + vector &operator=(vector &&other); + vector &operator=(std::initializer_list ilist); + vector &operator=(const std::vector &other); + + /* Assign methods */ + void assign(size_type count, const T &value); + template ::value, + InputIt>::type * = nullptr> + void assign(InputIt first, InputIt last); + void assign(std::initializer_list ilist); + void assign(const vector &other); + void assign(vector &&other); + void assign(const std::vector &other); + + /* Destructor */ + ~vector(); + + /* Element access */ + reference at(size_type n); + const_reference at(size_type n) const; + const_reference const_at(size_type n) const; + reference operator[](size_type n); + const_reference operator[](size_type n) const; + reference front(); + const_reference front() const; + const_reference cfront() const; + reference back(); + const_reference back() const; + const_reference cback() const; + value_type *data(); + const value_type *data() const noexcept; + const value_type *cdata() const noexcept; + + /* Iterators */ + iterator begin(); + const_iterator begin() const noexcept; + const_iterator cbegin() const noexcept; + iterator end(); + const_iterator end() const noexcept; + const_iterator cend() const noexcept; + reverse_iterator rbegin(); + const_reverse_iterator rbegin() const noexcept; + const_reverse_iterator crbegin() const noexcept; + reverse_iterator rend(); + const_reverse_iterator rend() const noexcept; + const_reverse_iterator crend() const noexcept; + + /* Range */ + slice range(size_type start, size_type n); + slice> + range(size_type start, size_type n, size_type snapshot_size); + slice range(size_type start, size_type n) const; + slice crange(size_type start, size_type n) const; + + /* Capacity */ + constexpr bool empty() const noexcept; + size_type size() const noexcept; + constexpr size_type max_size() const noexcept; + void reserve(size_type capacity_new); + size_type capacity() const noexcept; + void shrink_to_fit(); + + /* Modifiers */ + void clear(); + void free_data(); + iterator insert(const_iterator pos, const T &value); + iterator insert(const_iterator pos, T &&value); + iterator insert(const_iterator pos, size_type count, const T &value); + template ::value, + InputIt>::type * = nullptr> + iterator insert(const_iterator pos, InputIt first, InputIt last); + iterator insert(const_iterator pos, std::initializer_list ilist); + template + iterator emplace(const_iterator pos, Args &&... args); + template + reference emplace_back(Args &&... args); + iterator erase(const_iterator pos); + iterator erase(const_iterator first, const_iterator last); + void push_back(const T &value); + void push_back(T &&value); + void pop_back(); + void resize(size_type count); + void resize(size_type count, const value_type &value); + void swap(vector &other); + +private: + /* helper functions */ + void alloc(size_type size); + void check_pmem(); + void check_tx_stage_work(); + template + void construct(size_type idx, size_type count, Args &&... args); + template ::value, + InputIt>::type * = nullptr> + void construct_range(size_type idx, InputIt first, InputIt last); + template ::value, + InputIt>::type * = nullptr> + void construct_range_copy(size_type idx, InputIt first, InputIt last); + void dealloc(); + pool_base get_pool() const noexcept; + void insert_gap(size_type idx, size_type count); + void realloc(size_type size); + size_type get_recommended_capacity(size_type at_least) const; + void shrink(size_type size_new); + void snapshot_data(size_type idx_first, size_type idx_last); + + /* Underlying array */ + persistent_ptr _data; + + p _size; + p _capacity; +}; + +/* Non-member swap */ +template +void swap(vector &lhs, vector &rhs); + +/* + * Comparison operators between pmem::obj::experimental::vector and + * pmem::obj::experimental::vector + */ +template +bool operator==(const vector &lhs, const vector &rhs); +template +bool operator!=(const vector &lhs, const vector &rhs); +template +bool operator<(const vector &lhs, const vector &rhs); +template +bool operator<=(const vector &lhs, const vector &rhs); +template +bool operator>(const vector &lhs, const vector &rhs); +template +bool operator>=(const vector &lhs, const vector &rhs); + +/* + * Comparison operators between pmem::obj::experimental::vector and + * std::vector + */ +template +bool operator==(const vector &lhs, const std::vector &rhs); +template +bool operator!=(const vector &lhs, const std::vector &rhs); +template +bool operator<(const vector &lhs, const std::vector &rhs); +template +bool operator<=(const vector &lhs, const std::vector &rhs); +template +bool operator>(const vector &lhs, const std::vector &rhs); +template +bool operator>=(const vector &lhs, const std::vector &rhs); + +/* + * Comparison operators between std::vector and + * pmem::obj::experimental::vector + */ +template +bool operator==(const std::vector &lhs, const vector &rhs); +template +bool operator!=(const std::vector &lhs, const vector &rhs); +template +bool operator<(const std::vector &lhs, const vector &rhs); +template +bool operator<=(const std::vector &lhs, const vector &rhs); +template +bool operator>(const std::vector &lhs, const vector &rhs); +template +bool operator>=(const std::vector &lhs, const vector &rhs); + +/** + * Default constructor. Constructs an empty container. + * + * @pre must be called in transaction scope. + * + * @throw pmem::pool_error if an object is not in persistent memory. + * @throw pmem::transaction_error if constructor wasn't called in transaction. + */ +template +vector::vector() +{ + check_pmem(); + check_tx_stage_work(); + + _data = nullptr; + _size = 0; + _capacity = 0; +} + +/** + * Constructs the container with count copies of elements with value value. + * + * @param[in] count number of elements to construct. + * @param[in] value value of all constructed elements. + * + * @pre must be called in transaction scope. + * + * @post size() == count + * @post capacity() == size() + * + * @throw pmem::pool_error if an object is not in persistent memory. + * @throw pmem::transaction_alloc_error when allocating memory for underlying + * array in transaction failed. + * @throw pmem::transaction_error if constructor wasn't called in transaction. + * @throw rethrows element constructor exception. + */ +template +vector::vector(size_type count, const value_type &value) +{ + check_pmem(); + check_tx_stage_work(); + + _data = nullptr; + _size = 0; + alloc(count); + construct(0, count, value); +} + +/** + * Constructs the container with count copies of T default constructed values. + * + * @param[in] count number of elements to construct. + * + * @pre must be called in transaction scope. + * + * @post size() == count + * @post capacity() == size() + * + * @throw pmem::pool_error if an object is not in persistent memory. + * @throw pmem::transaction_alloc_error when allocating memory for underlying + * array in transaction failed. + * @throw pmem::transaction_error if constructor wasn't called in transaction. + * @throw rethrows element constructor exception. + */ +template +vector::vector(size_type count) +{ + check_pmem(); + check_tx_stage_work(); + + _data = nullptr; + _size = 0; + alloc(count); + construct(0, count); +} + +/** + * Constructs the container with the contents of the range [first, last). The + * first and last arguments must satisfy InputIterator requirements. This + * overload only participates in overload resolution if InputIt satisfies + * InputIterator, to avoid ambiguity with the overload of count-value + * constructor. + * + * @param[in] first first iterator. + * @param[in] last last iterator. + * + * @pre must be called in transaction scope. + * + * @post size() == std::distance(first, last) + * @post capacity() == size() + * + * @throw pmem::pool_error if an object is not in persistent memory. + * @throw pmem::transaction_alloc_error when allocating memory for underlying + * array in transaction failed. + * @throw pmem::transaction_error if constructor wasn't called in transaction. + * @throw rethrows element constructor exception. + */ +template +template ::value, + InputIt>::type *> +vector::vector(InputIt first, InputIt last) +{ + check_pmem(); + check_tx_stage_work(); + + _data = nullptr; + _size = 0; + alloc(static_cast(std::distance(first, last))); + construct_range_copy(0, first, last); +} + +/** + * Copy constructor. Constructs the container with the copy of the + * contents of other. + * + * @param[in] other reference to the vector to be copied. + * + * @pre must be called in transaction scope. + * + * @post size() == other.size() + * @post capacity() == other.capacity() + * + * @throw pmem::pool_error if an object is not in persistent memory. + * @throw pmem::transaction_alloc_error when allocating memory for underlying + * array in transaction failed. + * @throw pmem::transaction_error if constructor wasn't called in transaction. + * @throw rethrows element constructor exception. + */ +template +vector::vector(const vector &other) +{ + check_pmem(); + check_tx_stage_work(); + + _data = nullptr; + _size = 0; + alloc(other.capacity()); + construct_range_copy(0, other.cbegin(), other.cend()); +} + +/** + * Move constructor. Constructs the container with the contents of other using + * move semantics. After the move, other is guaranteed to be empty(). + * + * @param[in] other rvalue reference to the vector to be moved from. + * + * @pre must be called in transaction scope. + * + * @post size() == other.size() + * @post capacity() == other.capacity() + * @post data() == other.data() + * @post other.data() == nullptr + * @post other.capacity() == 0 + * @post other.size() == 0 + * + * @throw pmem::pool_error if an object is not in persistent memory. + * @throw pmem::transaction_error if constructor wasn't called in transaction. + */ +template +vector::vector(vector &&other) +{ + check_pmem(); + check_tx_stage_work(); + + _data = other._data; + _capacity = other.capacity(); + _size = other.size(); + other._data = nullptr; + other._capacity = other._size = 0; +} + +/** + * Constructs the container with the contents of the initializer list init. + * + * @param[in] init initializer list with content to be constructed. + * + * @pre must be called in transaction scope. + * + * @post size() == init.size() + * @post capacity() == size() + * + * @throw pmem::pool_error if an object is not in persistent memory. + * @throw pmem::transaction_alloc_error when allocating memory for underlying + * array in transaction failed. + * @throw pmem::transaction_error if constructor wasn't called in transaction. + * @throw rethrows element constructor exception. + */ +template +vector::vector(std::initializer_list init) + : vector(init.begin(), init.end()) +{ +} + +/** + * Copy constructor. Constructs the container with the copy of the contents of + * std::vector other. This constructor is not specified by STL standards. + * + * @param[in] other reference to the vector to be copied. + * + * @pre must be called in transaction scope. + * + * @post size() == other.size() + * @post capacity() == other.capacity() + * + * @throw pmem::pool_error if an object is not in persistent memory. + * @throw pmem::transaction_alloc_error when allocating memory for underlying + * array in transaction failed. + * @throw pmem::transaction_error if constructor wasn't called in transaction. + * @throw rethrows element constructor exception. + */ +template +vector::vector(const std::vector &other) + : vector(other.cbegin(), other.cend()) +{ +} + +/** + * Copy assignment operator. Replaces the contents with a copy of the contents + * of other transactionally. + * + * @post size() == other.size() + * @post capacity() == max(size(), other.capacity()) + * + * @throw pmem::transaction_alloc_error when allocating new memory failed. + * @throw pmem::transaction_free_error when freeing old underlying array failed. + * @throw rethrows constructor exception. + */ +template +vector & +vector::operator=(const vector &other) +{ + assign(other); + + return *this; +} + +/** + * Move assignment operator. Replaces the contents with those of other using + * move semantics (i.e. the data in other is moved from other into this + * container) transactionally. Other is in a valid but empty state afterwards. + * + * @post size() == other.size() + * @post capacity() == other.capacity() + * + * @throw pmem::transaction_free_error when freeing underlying array failed. + */ +template +vector & +vector::operator=(vector &&other) +{ + assign(std::move(other)); + + return *this; +} + +/** + * Replaces the contents with those identified by initializer list ilist + * transactionally. + * + * @throw std::length_error if ilist.size() > max_size(). + * @throw pmem::transaction_alloc_error when allocating new memory failed. + * @throw pmem::transaction_free_error when freeing old underlying array failed. + * @throw rethrows constructor exception. + */ +template +vector & +vector::operator=(std::initializer_list ilist) +{ + assign(ilist.begin(), ilist.end()); + + return *this; +} + +/** + * Copy assignment operator. Replaces the contents with a copy of the contents + * of std::vector other transactionally. This method is not specified by STL + * standards. + * + * @post size() == other.size() + * @post capacity() == max(size(), other.capacity()) + * + * @throw pmem::transaction_alloc_error when allocating new memory failed. + * @throw pmem::transaction_free_error when freeing old underlying array failed. + * @throw rethrows constructor exception. + */ +template +vector & +vector::operator=(const std::vector &other) +{ + assign(other); + + return *this; +} + +/** + * Replaces the contents with count copies of value value transactionally. All + * iterators, pointers and references to the elements of the container are + * invalidated. The past-the-end iterator is also invalidated. + * + * @param[in] count number of elements to construct. + * @param[in] value value of all constructed elements. + * + * @post size() == count + * @post capacity() == max(size(), count) + * + * @throw std::length_error if count > max_size(). + * @throw pmem::transaction_alloc_error when allocating new memory failed. + * @throw pmem::transaction_free_error when freeing old underlying array failed. + * @throw rethrows constructor exception. + */ +template +void +vector::assign(size_type count, const_reference value) +{ + pool_base pb = get_pool(); + + transaction::run(pb, [&] { + if (count <= capacity()) { + /* + * Reallocation is not needed. First, replace old + * elements with new ones in range [0, size()). + * Depending on count, either call remaining old + * elements destructors, or append more new elements. + */ + size_type size_old = _size; + snapshot_data(0, size_old); + + std::fill_n( + &_data[0], + (std::min)(count, + static_cast(size_old)), + value); + + if (count > size_old) { +#if LIBPMEMOBJ_CPP_VG_PMEMCHECK_ENABLED + /* + * Range of memory: + * [&_data[size_old], &_data[count]) + * is undefined, there is no need to snapshot + * and eventually rollback old data. + */ + VALGRIND_PMC_ADD_TO_TX( + &_data[static_cast( + size_old)], + sizeof(T) * (count - size_old)); +#endif + + construct(size_old, count - size_old, value); + /* + * XXX: explicit persist is required here + * because given range wasn't snapshotted and + * won't be persisted automatically on tx + * commit. This can be changed once we will have + * implemented "uninitialized" flag for + * pmemobj_tx_xadd in libpmemobj. + */ + pb.persist(&_data[static_cast( + size_old)], + sizeof(T) * (count - size_old)); + } else { + shrink(count); + } + } else { + dealloc(); + alloc(count); + construct(0, count, value); + } + }); +} + +/** + * Replaces the contents with copies of those in the range [first, last) + * transactionally. This overload participates in overload resolution only if + * InputIt satisfies InputIterator. All iterators, pointers and references to + * the elements of the container are invalidated. The past-the-end iterator is + * also invalidated. + * + * @param[in] first first iterator. + * @param[in] last last iterator. + * + * @post size() == std::distance(first, last) + * @post capacity() == max(size(), std::distance(first, last)) + * + * @throw std::length_error if std::distance(first, last) > max_size(). + * @throw pmem::transaction_alloc_error when allocating new memory failed. + * @throw pmem::transaction_free_error when freeing old underlying array failed. + * @throw rethrows constructor exception. + */ +template +template ::value, + InputIt>::type *> +void +vector::assign(InputIt first, InputIt last) +{ + pool_base pb = get_pool(); + + size_type size_new = static_cast(std::distance(first, last)); + + transaction::run(pb, [&] { + if (size_new <= capacity()) { + /* + * Reallocation is not needed. First, replace old + * elements with new ones in range [0, size()). + * Depending on size_new, either call remaining old + * elements destructors, or append more new elements. + */ + size_type size_old = _size; + snapshot_data(0, size_old); + + InputIt mid = last; + bool growing = size_new > size_old; + + if (growing) { +#if LIBPMEMOBJ_CPP_VG_PMEMCHECK_ENABLED + /* + * Range of memory: + * [&_data[size_old], &_data[size_new]) + * is undefined, there is no need to snapshot + * and eventually rollback old data. + */ + VALGRIND_PMC_ADD_TO_TX( + &_data[static_cast( + size_old)], + sizeof(T) * (size_new - size_old)); +#endif + + mid = first; + std::advance(mid, size_old); + } + + iterator shrink_to = std::copy(first, mid, &_data[0]); + + if (growing) { + construct_range_copy(size_old, mid, last); + /* + * XXX: explicit persist is required here + * because given range wasn't snapshotted and + * won't be persisted automatically on tx + * commit. This can be changed once we will have + * implemented "uninitialized" flag for + * pmemobj_tx_xadd in libpmemobj. + */ + pb.persist(&_data[static_cast( + size_old)], + sizeof(T) * (size_new - size_old)); + } else { + shrink(static_cast(std::distance( + iterator(&_data[0]), shrink_to))); + } + } else { + dealloc(); + alloc(size_new); + construct_range_copy(0, first, last); + } + }); +} + +/** + * Replaces the contents with the elements from the initializer list ilist + * transactionally. All iterators, pointers and references to the elements of + * the container are invalidated. The past-the-end iterator is also invalidated. + * + * @param[in] ilist initializer list with content to be constructed. + * + * @post size() == std::distance(ilist.begin(), ilist.end()) + * @post capacity() == max(size(), capacity()) + * + * @throw std::length_error if std::distance(first, last) > max_size(). + * @throw pmem::transaction_alloc_error when allocating new memory failed. + * @throw pmem::transaction_free_error when freeing old underlying array failed. + * @throw rethrows constructor exception. + */ +template +void +vector::assign(std::initializer_list ilist) +{ + assign(ilist.begin(), ilist.end()); +} + +/** + * Copy assignment method. Replaces the contents with a copy of the contents + * of other transactionally. This method is not specified by STL standards. + * + * @post size() == other.size() + * @post capacity() == max(size(), other.capacity()) + * + * @throw pmem::transaction_alloc_error when allocating new memory failed. + * @throw pmem::transaction_free_error when freeing old underlying array failed. + * @throw rethrows constructor exception. + */ +template +void +vector::assign(const vector &other) +{ + if (this != &other) + assign(other.cbegin(), other.cend()); +} + +/** + * Move assignment method. Replaces the contents with those of other using + * move semantics (i.e. the data in other is moved from other into this + * container) transactionally. Other is in a valid but empty state afterwards. + * This method is not specified by STL standards. + * + * @post size() == other.size() + * @post capacity() == other.capacity() + * + * @throw pmem::transaction_free_error when freeing underlying array failed. + */ +template +void +vector::assign(vector &&other) +{ + if (this == &other) + return; + + pool_base pb = get_pool(); + + transaction::run(pb, [&] { + dealloc(); + + _data = other._data; + _capacity = other._capacity; + _size = other._size; + + other._data = nullptr; + other._capacity = other._size = 0; + }); +} + +/** + * Copy assignment method. Replaces the contents with a copy of the contents + * of std::vector other transactionally. This method is not specified by STL + * standards. + * + * @post size() == other.size() + * @post capacity() == max(size(), other.capacity()) + * + * @throw pmem::transaction_alloc_error when allocating new memory failed. + * @throw pmem::transaction_free_error when freeing old underlying array failed. + * @throw rethrows constructor exception. + */ +template +void +vector::assign(const std::vector &other) +{ + assign(other.cbegin(), other.cend()); +} + +/** + * Destructor. + * Note that free_data may throw an transaction_free_error when freeing + * underlying array failed. It is recommended to call free_data manually before + * object destruction. + * + * @throw rethrows destructor exception. + * @throw transaction_free_error when freeing underlying array failed. + */ +template +vector::~vector() +{ + free_data(); +} + +/** + * Access element at specific index with bounds checking and add it to a + * transaction. + * + * @param[in] n index number. + * + * @return reference to element number n in underlying array. + * + * @throw std::out_of_range if n is not within the range of the container. + * @throw pmem::transaction_error when adding the object to the transaction + * failed. + */ +template +typename vector::reference +vector::at(size_type n) +{ + if (n >= _size) + throw std::out_of_range("vector::at"); + + detail::conditional_add_to_tx(&_data[static_cast(n)]); + + return _data[static_cast(n)]; +} + +/** + * Access element at specific index with bounds checking. + * + * @param[in] n index number. + * + * @return const_reference to element number n in underlying array. + * + * @throw std::out_of_range if n is not within the range of the container. + */ +template +typename vector::const_reference +vector::at(size_type n) const +{ + if (n >= _size) + throw std::out_of_range("vector::at"); + + return _data[static_cast(n)]; +} + +/** + * Access element at specific index with bounds checking. In contradiction to + * at(), const_at() will return const_reference not depending on the + * const-qualification of the object it is called on. std::vector doesn't + * provide const_at() method. + * + * @param[in] n index number. + * + * @return const_reference to element number n in underlying array. + * + * @throw std::out_of_range if n is not within the range of the container. + */ +template +typename vector::const_reference +vector::const_at(size_type n) const +{ + if (n >= _size) + throw std::out_of_range("vector::const_at"); + + return _data[static_cast(n)]; +} + +/** + * Access element at specific index and add it to a transaction. No bounds + * checking is performed. + * + * @param[in] n index number. + * + * @return reference to element number n in underlying array. + * + * @throw pmem::transaction_error when adding the object to the transaction + * failed. + */ +template +typename vector::reference vector::operator[](size_type n) +{ + detail::conditional_add_to_tx(&_data[static_cast(n)]); + + return _data[static_cast(n)]; +} + +/** + * Access element at specific index. No bounds checking is performed. + * + * @param[in] n index number. + * + * @return const_reference to element number n in underlying array. + */ +template +typename vector::const_reference vector::operator[](size_type n) const +{ + return _data[static_cast(n)]; +} + +/** + * Access the first element and add this element to a transaction. + * + * @return reference to first element in underlying array. + * + * @throw pmem::transaction_error when adding the object to the transaction + * failed. + */ +template +typename vector::reference +vector::front() +{ + detail::conditional_add_to_tx(&_data[0]); + + return _data[0]; +} + +/** + * Access the first element. + * + * @return const_reference to first element in underlying array. + */ +template +typename vector::const_reference +vector::front() const +{ + return _data[0]; +} + +/** + * Access the first element. In contradiction to front(), cfront() will return + * const_reference not depending on the const-qualification of the object it is + * called on. std::vector doesn't provide cfront() method. + * + * @return reference to first element in underlying array. + */ +template +typename vector::const_reference +vector::cfront() const +{ + return _data[0]; +} + +/** + * Access the last element and add this element to a transaction. + * + * @return reference to the last element in underlying array. + * + * @throw pmem::transaction_error when adding the object to the transaction + * failed. + */ +template +typename vector::reference +vector::back() +{ + detail::conditional_add_to_tx( + &_data[static_cast(size() - 1)]); + + return _data[static_cast(size() - 1)]; +} + +/** + * Access the last element. + * + * @return const_reference to the last element in underlying array. + */ +template +typename vector::const_reference +vector::back() const +{ + return _data[static_cast(size() - 1)]; +} + +/** + * Access the last element. In contradiction to back(), cback() will return + * const_reference not depending on the const-qualification of the object it is + * called on. std::vector doesn't provide cback() method. + * + * @return const_reference to the last element in underlying array. + */ +template +typename vector::const_reference +vector::cback() const +{ + return _data[static_cast(size() - 1)]; +} + +/** + * Returns raw pointer to the underlying data and adds entire array to a + * transaction. + * + * @return pointer to the underlying data. + * + * @throw pmem::transaction_error when adding the object to the transaction + * failed. + */ +template +typename vector::value_type * +vector::data() +{ + snapshot_data(0, _size); + + return _data.get(); +} + +/** + * Returns const raw pointer to the underlying data. + * + * @return const_pointer to the underlying data. + */ +template +const typename vector::value_type * +vector::data() const noexcept +{ + return _data.get(); +} + +/** + * Returns const raw pointer to the underlying data. In contradiction to data(), + * cdata() will return const_pointer not depending on the const-qualification of + * the object it is called on. std::vector doesn't provide cdata() method. + * + * @return const_pointer to the underlying data. + */ +template +const typename vector::value_type * +vector::cdata() const noexcept +{ + return _data.get(); +} + +/** + * Returns an iterator to the beginning. + * + * @return iterator pointing to the first element in the vector. + */ +template +typename vector::iterator +vector::begin() +{ + return iterator(_data.get()); +} + +/** + * Returns const iterator to the beginning. + * + * @return const_iterator pointing to the first element in the vector. + */ +template +typename vector::const_iterator +vector::begin() const noexcept +{ + return const_iterator(_data.get()); +} + +/** + * Returns const iterator to the beginning. In contradiction to begin(), + * cbegin() will return const_iterator not depending on the const-qualification + * of the object it is called on. + * + * @return const_iterator pointing to the first element in the vector. + */ +template +typename vector::const_iterator +vector::cbegin() const noexcept +{ + return const_iterator(_data.get()); +} + +/** + * Returns an iterator to past the end. + * + * @return iterator referring to the past-the-end element in the vector. + */ +template +typename vector::iterator +vector::end() +{ + return iterator(_data.get() + static_cast(_size)); +} + +/** + * Returns a const iterator to past the end. + * + * @return const_iterator referring to the past-the-end element in the vector. + */ +template +typename vector::const_iterator +vector::end() const noexcept +{ + return const_iterator(_data.get() + static_cast(_size)); +} + +/** + * Returns a const iterator to the end. In contradiction to end(), cend() will + * return const_iterator not depending on the const-qualification of the object + * it is called on. + * + * @return const_iterator referring to the past-the-end element in the vector. + */ +template +typename vector::const_iterator +vector::cend() const noexcept +{ + return const_iterator(_data.get() + static_cast(_size)); +} + +/** + * Returns a reverse iterator to the beginning. + * + * @return reverse_iterator pointing to the last element in the vector. + */ +template +typename vector::reverse_iterator +vector::rbegin() +{ + return reverse_iterator(end()); +} + +/** + * Returns a const reverse iterator to the beginning. + * + * @return const_reverse_iterator pointing to the last element in the vector. + */ +template +typename vector::const_reverse_iterator +vector::rbegin() const noexcept +{ + return const_reverse_iterator(cend()); +} + +/** + * Returns a const reverse iterator to the beginning. In contradiction to + * rbegin(), crbegin() will return const_reverse_iterator not depending on the + * const-qualification of the object it is called on. + * + * @return const_reverse_iterator pointing to the last element in the vector. + */ +template +typename vector::const_reverse_iterator +vector::crbegin() const noexcept +{ + return const_reverse_iterator(cend()); +} + +/** + * Returns a reverse iterator to the end. + * + * @return reverse_iterator pointing to the theoretical element preceding the + * first element in the vector. + */ +template +typename vector::reverse_iterator +vector::rend() +{ + return reverse_iterator(begin()); +} + +/** + * Returns a const reverse iterator to the end. + * + * @return const_reverse_iterator pointing to the theoretical element preceding + * the first element in the vector. + */ +template +typename vector::const_reverse_iterator +vector::rend() const noexcept +{ + return const_reverse_iterator(cbegin()); +} + +/** + * Returns a const reverse iterator to the beginning. In contradiction to + * rend(), crend() will return const_reverse_iterator not depending on the + * const-qualification of the object it is called on. + * + * @return const_reverse_iterator pointing to the theoretical element preceding + * the first element in the vector. + */ +template +typename vector::const_reverse_iterator +vector::crend() const noexcept +{ + return const_reverse_iterator(cbegin()); +} + +/** + * Returns slice and snapshots requested range. This method is not specified by + * STL standards. + * + * @param[in] start start index of requested range. + * @param[in] n number of elements in range. + * + * @return slice from start to start + n. + * + * @throw std::out_of_range if any element of the range would be outside of the + * vector. + * @throw pmem::transaction_error when snapshotting failed. + */ +template +slice::pointer> +vector::range(size_type start, size_type n) +{ + if (start + n > size()) + throw std::out_of_range("vector::range"); + + detail::conditional_add_to_tx(cdata() + start, n); + + return {_data.get() + start, _data.get() + start + n}; +} + +/** + * Returns slice. This method is not specified by STL standards. + * + * @param[in] start start index of requested range. + * @param[in] n number of elements in range. + * @param[in] snapshot_size number of elements which should be snapshotted in a + * bulk while traversing this slice. If provided value is larger or equal to n, + * entire range is added to a transaction. If value is equal to 0 no + * snapshotting happens. + * + * @return slice from start to start + n. + * + * @throw std::out_of_range if any element of the range would be outside of the + * vector. + */ +template +slice> +vector::range(size_type start, size_type n, size_type snapshot_size) +{ + if (start + n > size()) + throw std::out_of_range("vector::range"); + + if (snapshot_size > n) + snapshot_size = n; + + return {range_snapshotting_iterator(_data.get() + start, + _data.get() + start, n, + snapshot_size), + range_snapshotting_iterator(_data.get() + start + n, + _data.get() + start, n, + snapshot_size)}; +} + +/** + * Returns const slice. This method is not specified by STL standards. + * + * @param[in] start start index of requested range. + * @param[in] n number of elements in range. + * + * @return slice from start to start + n. + * + * @throw std::out_of_range if any element of the range would be outside of the + * vector. + */ +template +slice::const_iterator> +vector::range(size_type start, size_type n) const +{ + if (start + n > size()) + throw std::out_of_range("vector::range"); + + return {const_iterator(cdata() + start), + const_iterator(cdata() + start + n)}; +} + +/** + * Returns const slice. This method is not specified by STL standards. + * + * @param[in] start start index of requested range. + * @param[in] n number of elements in range. + * + * @return slice from start to start + n. + * + * @throw std::out_of_range if any element of the range would be outside of the + * vector. + */ +template +slice::const_iterator> +vector::crange(size_type start, size_type n) const +{ + if (start + n > size()) + throw std::out_of_range("vector::crange"); + + return {const_iterator(cdata() + start), + const_iterator(cdata() + start + n)}; +} + +/** + * Checks whether the container is empty. + * + * @return true if container is empty, false otherwise. + */ +template +constexpr bool +vector::empty() const noexcept +{ + return _size == 0; +} + +/** + * @return number of elements. + */ +template +typename vector::size_type +vector::size() const noexcept +{ + return _size; +} + +/** + * @return maximum number of elements the container is able to hold due to PMDK + * limitations. + */ +template +constexpr typename vector::size_type +vector::max_size() const noexcept +{ + return PMEMOBJ_MAX_ALLOC_SIZE / sizeof(value_type); +} + +/** + * Increases the capacity of the vector to capacity_new transactionally. If + * capacity_new is greater than the current capacity(), new storage is + * allocated, otherwise the method does nothing. If capacity_new is greater than + * capacity(), all iterators, including the past-the-end iterator, and all + * references to the elements are invalidated. Otherwise, no iterators or + * references are invalidated. + * + * @param[in] capacity_new new capacity. + * + * @post capacity() == max(capacity(), capacity_new) + * + * @throw rethrows destructor exception. + * @throw std::length_error if new_cap > max_size(). + * @throw pmem::transaction_error when snapshotting failed. + * @throw pmem::transaction_alloc_error when allocating new memory failed. + * @throw pmem::transaction_free_error when freeing old underlying array failed. + */ +template +void +vector::reserve(size_type capacity_new) +{ + if (capacity_new <= _capacity) + return; + + pool_base pb = get_pool(); + transaction::run(pb, [&] { realloc(capacity_new); }); +} + +/** + * @return number of elements that can be held in currently allocated storage + */ +template +typename vector::size_type +vector::capacity() const noexcept +{ + return _capacity; +} + +/** + * Requests transactional removal of unused capacity. New capacity will be set + * to current vector size. If reallocation occurs, all iterators, including the + * past the end iterator, and all references to the elements are invalidated. + * If no reallocation takes place, no iterators or references are invalidated. + * + * @post capacity() == size() + * + * @throw pmem::transaction_error when snapshotting failed + * @throw pmem::transaction_alloc_error when reallocating failed. + * @throw pmem::transaction_free_error when freeing old underlying array failed. + * @throw rethrows constructor exception. + * @throw rethrows destructor exception. + */ +template +void +vector::shrink_to_fit() +{ + size_type capacity_new = size(); + if (capacity() == capacity_new) + return; + + pool_base pb = get_pool(); + transaction::run(pb, [&] { realloc(capacity_new); }); +} + +/** + * Clears the content of a vector transactionally. + * + * @post size() == 0 + * + * @throw pmem::transaction_error when snapshotting failed. + * @throw rethrows destructor exception. + */ +template +void +vector::clear() +{ + pool_base pb = get_pool(); + transaction::run(pb, [&] { shrink(0); }); +} + +/** + * Clears the content of a vector and frees all allocated persistent memory for + * data transactionally. + * + * @post size() == 0 + * @post capacity() == 0 + * @post data() == nullptr + * + * @throw pmem::transaction_error when snapshotting failed. + * @throw rethrows destructor exception. + * @throw pmem::transaction_free_error when freeing underlying array failed. + */ +template +void +vector::free_data() +{ + if (_data == nullptr) + return; + + pool_base pb = get_pool(); + transaction::run(pb, [&] { dealloc(); }); +} + +/** + * Inserts value before pos in the container transactionally. Causes + * reallocation if the new size() is greater than the old capacity(). If the new + * size() is greater than capacity(), all iterators and references are + * invalidated. Otherwise, only the iterators and references before the + * insertion point remain valid. The past-the-end iterator is also invalidated. + * + * @param[in] pos iterator before which the content will be inserted. pos may be + * the end() iterator. + * @param[in] value element value to be inserted. + * + * @return Iterator pointing to the inserted value. + * + * @pre value_type must meet the requirements of CopyAssignable and + * CopyInsertable. + * + * @post capacity() is equal to the smallest next power of 2, bigger than old + * capacity, or remains the same if there is enough space to add single element. + * + * @throw pmem::transaction_error when snapshotting failed. + * @throw rethrows constructor exception. + * @throw rethrows destructor exception. + * @throw pmem::transaction_free_error when freeing old underlying array failed. + */ +template +typename vector::iterator +vector::insert(const_iterator pos, const value_type &value) +{ + return insert(pos, 1, value); +} + +/** + * Moves value before pos in the container transactionally. Causes reallocation + * if the new size() is greater than the old capacity(). If the new size() is + * greater than capacity(), all iterators and references are invalidated. + * Otherwise, only the iterators and references before the insertion point + * remain valid. The past-the-end iterator is also invalidated. + * + * @param[in] pos iterator before which the content will be inserted. pos may be + * the end() iterator. + * @param[in] value element value to be inserted. + * + * @return Iterator pointing to the inserted value. + * + * @pre value_type must meet the requirements of MoveAssignable and + * MoveInsertable. + * + * @post capacity() is equal to the smallest next power of 2, bigger than old + * capacity, or remains the same if there is enough space to add single element. + * + * @throw pmem::transaction_error when snapshotting failed. + * @throw rethrows constructor exception. + * @throw rethrows destructor exception. + * @throw pmem::transaction_free_error when freeing old underlying array failed. + */ +template +typename vector::iterator +vector::insert(const_iterator pos, value_type &&value) +{ + pool_base pb = get_pool(); + + size_type idx = static_cast(std::distance(cbegin(), pos)); + + transaction::run(pb, [&] { + insert_gap(idx, 1); + construct(idx, 1, std::move(value)); + }); + + return iterator(&_data[static_cast(idx)]); +} + +/** + * Inserts count copies of the value before pos in the container + * transactionally. Causes reallocation if the new size() is greater than the + * old capacity(). If the new size() is greater than capacity(), all iterators + * and references are invalidated. Otherwise, only the iterators and references + * before the insertion point remain valid. The past-the-end iterator is also + * invalidated. + * + * @param[in] pos iterator before which the content will be inserted. pos may be + * the end() iterator. + * @param[in] count number of copies to be inserted. + * @param[in] value element value to be inserted. + * + * @return Iterator pointing to the first element inserted, or pos if count == + * 0. + * + * @pre value_type must meet the requirements of CopyAssignable and + * CopyInsertable. + * + * @post capacity() is equal to the smallest next power of 2, bigger than old + * capacity + count, or remains the same if there is enough space to add count + * elements. + * + * @throw pmem::transaction_error when snapshotting failed. + * @throw rethrows constructor exception. + * @throw rethrows destructor exception. + * @throw pmem::transaction_free_error when freeing old underlying array failed. + */ +template +typename vector::iterator +vector::insert(const_iterator pos, size_type count, const value_type &value) +{ + pool_base pb = get_pool(); + + size_type idx = static_cast(std::distance(cbegin(), pos)); + + transaction::run(pb, [&] { + insert_gap(idx, count); + construct(idx, count, value); + }); + + return iterator(&_data[static_cast(idx)]); +} + +/** + * Inserts elements from range [first, last) before pos in the container + * transactionally. Causes reallocation if the new size() is greater than the + * old capacity(). If the new size() is greater than capacity(), all iterators + * and references are invalidated. Otherwise, only the iterators and references + * before the insertion point remain valid. The past-the-end iterator is also + * invalidated. This overload participates in overload resolution only if + * InputIt qualifies as InputIterator, to avoid ambiguity with the + * pos-count-value overload. The behavior is undefined if first and last are + * iterators into *this. + * + * @param[in] pos iterator before which the content will be inserted. pos may be + * the end() iterator. + * @param[in] first begin of the range of elements to insert, can't be iterator + * into container for which insert is called. + * @param[in] last end of the range of elements to insert, can't be iterator + * into container for which insert is called. + * + * @return Iterator pointing to the first element inserted or pos if first == + * last. + * + * @pre value_type must meet the requirements of EmplaceConstructible, + * Swappable, CopyAssignable, CopyConstructible and CopyInsertable. + * @pre InputIt must satisfies requirements of InputIterator. + * + * @post capacity() is equal to the smallest next power of 2, bigger than old + * capacity + std::distance(first, last), or remains the same if there is enough + * space to add std::distance(first, last) elements. + * + * @throw pmem::transaction_error when snapshotting failed. + * @throw rethrows constructor exception. + * @throw rethrows destructor exception. + * @throw pmem::transaction_free_error when freeing old underlying array failed. + */ +template +template ::value, + InputIt>::type *> +typename vector::iterator +vector::insert(const_iterator pos, InputIt first, InputIt last) +{ + pool_base pb = get_pool(); + + size_type idx = static_cast(std::distance(cbegin(), pos)); + size_type gap_size = static_cast(std::distance(first, last)); + + transaction::run(pb, [&] { + insert_gap(idx, gap_size); + construct_range_copy(idx, first, last); + }); + + return iterator(&_data[static_cast(idx)]); +} + +/** + * Inserts elements from initializer list ilist before pos in the container + * transactionally. Causes reallocation if the new size() is greater than the + * old capacity(). If the new size() is greater than capacity(), all iterators + * and references are invalidated. Otherwise, only the iterators and references + * before the insertion point remain valid. The past-the-end iterator is also + * invalidated. + * + * @param[in] pos iterator before which the content will be inserted. pos may be + * the end() iterator. + * @param[in] ilist initializer list to insert the values from. + * + * @return Iterator pointing to the first element inserted, or pos if ilist is + * empty. + * + * @pre value_type must meet the requirements of EmplaceConstructible, + * Swappable, CopyAssignable, CopyConstructible and CopyInsertable. + * + * @post capacity() is equal to the smallest next power of 2, bigger than old + * capacity + std::distance(ilist.begin(), ilist.end()), or remains the same if + * there is enough space to add std::distance(ilist.begin(), ilist.end()) + * elements. + * + * @throw pmem::transaction_error when snapshotting failed. + * @throw rethrows constructor exception. + * @throw rethrows destructor exception. + * @throw pmem::transaction_free_error when freeing old underlying array failed. + */ +template +typename vector::iterator +vector::insert(const_iterator pos, std::initializer_list ilist) +{ + return insert(pos, ilist.begin(), ilist.end()); +} + +/** + * Inserts a new element into the container directly before pos. The element is + * constructed in-place. The arguments args... are forwarded to the constructor + * as std::forward(args).... If the new size() is greater than capacity(), + * all iterators and references are invalidated. Otherwise, only the iterators + * and references before the insertion point remain valid. The past-the-end + * iterator is also invalidated. Note that standard allows args to be a self + * reference and internal emplace implementation handles this case by creating + * temporary element_type object. This object is being stored either on stack or + * on pmem, see pmem::detail::temp_value for details. + * + * @param[in] pos iterator before which the new element will be constructed. + * @param[in] args arguments to forward to the constructor of the element. + * + * @return Iterator pointing to the emplaced element. + * + * @pre value_type must meet the requirements of MoveAssignable, MoveInsertable + * and EmplaceConstructible. + * + * @post capacity() is equal to the smallest next power of 2, bigger than old + * capacity, or remains the same if there is enough space to add single element. + * + * @throw pmem::transaction_error when snapshotting failed. + * @throw rethrows constructor exception. + * @throw rethrows destructor exception. + * @throw pmem::transaction_free_error when freeing old underlying array failed. + */ +template +template +typename vector::iterator +vector::emplace(const_iterator pos, Args &&... args) +{ + pool_base pb = get_pool(); + + size_type idx = static_cast(std::distance(cbegin(), pos)); + + transaction::run(pb, [&] { + /* + * args might be a reference to underlying array element. This + * reference can be invalidated after insert_gap() call. Hence, + * we must cache value_type object in temp_value. + */ + detail::temp_value(args)...))> + tmp(std::forward(args)...); + + insert_gap(idx, 1); + construct(idx, 1, std::move(tmp.get())); + }); + + return iterator(&_data[static_cast(idx)]); +} + +/** + * Appends a new element to the end of the container. The element is constructed + * in-place. The arguments args... are forwarded to the constructor as + * std::forward(args).... If the new size() is greater than capacity() + * then all iterators and references (including the past-the-end iterator) are + * invalidated. Otherwise only the past-the-end iterator is invalidated. + * + * @param[in] args arguments to forward to the constructor of the element. + * + * @return Iterator pointing to the emplaced element. + * + * @pre value_type must meet the requirements of MoveInsertable and + * EmplaceConstructible. + * + * @post capacity() is equal to the smallest next power of 2, bigger than old + * capacity, or remains the same if there is enough space to add single element. + * + * @throw pmem::transaction_error when snapshotting failed. + * @throw rethrows constructor exception. + * @throw rethrows destructor exception. + * @throw pmem::transaction_free_error when freeing old underlying array failed. + */ +template +template +typename vector::reference +vector::emplace_back(Args &&... args) +{ + /* + * emplace() cannot be used here, because emplace_back() doesn't require + * element_type to be MoveAssignable and emplace() uses + * std::move_backward() function. + */ + pool_base pb = get_pool(); + + transaction::run(pb, [&] { + if (_size == _capacity) { + realloc(get_recommended_capacity(_size + 1)); + } else { +#if LIBPMEMOBJ_CPP_VG_PMEMCHECK_ENABLED + /* + * Range of memory: [&_data[_size], &_data[_size + 1]) + * is undefined, there is no need to snapshot and + * eventually rollback old data. + */ + VALGRIND_PMC_ADD_TO_TX( + &_data[static_cast(size())], + sizeof(T)); +#endif + } + + construct(size(), 1, std::forward(args)...); + /* + * XXX: explicit persist is required here because given range + * wasn't snapshotted and won't be persisted automatically on tx + * commit. This can be changed once we will have implemented + * "uninitialized" flag for pmemobj_tx_xadd in libpmemobj. + */ + pb.persist(&_data[static_cast(size() - 1)], + sizeof(T)); + }); + + return back(); +} + +/** + * Removes the element at pos. Invalidates iterators and references at or after + * the point of the erase, including the end() iterator. The iterator pos must + * be valid and dereferenceable. Thus the end() iterator (which is valid, but is + * not dereferenceable) cannot be used as a value for pos. + * + * @param[in] pos iterator to the element to be removed. + * + * @return Iterator following the last removed element. If the iterator pos + * refers to the last element, the end() iterator is returned. + * + * @pre value_type must meet the requirements of MoveAssignable. + * + * @post size() = size() - 1. + * + * @throw pmem::transaction_error when snapshotting failed. + * @throw rethrows constructor exception. + * @throw rethrows destructor exception. + */ +template +typename vector::iterator +vector::erase(const_iterator pos) +{ + return erase(pos, pos + 1); +} + +/** + * Removes the elements in the range [first, last). Invalidates iterators and + * references at or after the point of the erase, including the end() iterator. + * The iterator pos must be valid and dereferenceable. Thus the end() iterator + * (which is valid, but is not dereferenceable) cannot be used as a value for + * pos. + * + * @param[in] first beginning of the range of elements to be removed. + * @param[in] last end of range of elements to be removed. + * + * @return Iterator following the last removed element. If the iterator pos + * refers to the last element, the end() iterator is returned. If first and last + * refer to the same element, iterator to this element is returned. + * + * @pre value_type must meet the requirements of MoveAssignable. + * + * @post size() = size() - std::distance(first, last). + * + * @throw pmem::transaction_error when snapshotting failed. + * @throw rethrows constructor exception. + * @throw rethrows destructor exception. + */ +template +typename vector::iterator +vector::erase(const_iterator first, const_iterator last) +{ + size_type idx = static_cast( + std::distance(const_iterator(&_data[0]), first)); + size_type count = static_cast(std::distance(first, last)); + + if (count == 0) + return iterator(&_data[static_cast(idx)]); + + pool_base pb = get_pool(); + + transaction::run(pb, [&] { + /* + * XXX: future optimization: no need to snapshot trivial types, + * if idx + count = _size + */ + snapshot_data(idx, _size); + + pointer move_begin = + &_data[static_cast(idx + count)]; + pointer move_end = &_data[static_cast(size())]; + pointer dest = &_data[static_cast(idx)]; + + std::move(move_begin, move_end, dest); + + _size -= count; + }); + + return iterator(&_data[static_cast(idx)]); +} + +/** + * Appends the given element value to the end of the container transactionally. + * The new element is initialized as a copy of value. + * + * @param[in] value the value of the element to be appended. + * + * @pre value_type must meet the requirements of CopyInsertable. + * + * @post capacity() is equal to the smallest next power of 2, bigger than old + * capacity, or remains the same if there is enough space to add single element. + * + * @throw transaction_error when snapshotting failed. + * @throw rethrows constructor exception. + * @throw pmem::transaction_free_error when freeing old underlying array failed. + */ +template +void +vector::push_back(const value_type &value) +{ + emplace_back(value); +} + +/** + * Appends the given element value to the end of the container transactionally. + * value is moved into the new element. + * + * @param[in] value the value of the element to be appended. + * + * @pre value_type must meet the requirements of MoveInsertable. + * + * @post size() == size() + 1 + * @post capacity() is equal to the smallest next power of 2, bigger than old + * capacity, or remains the same if there is enough space to add single element. + * + * @throw transaction_error when snapshotting failed. + * @throw rethrows constructor exception. + * @throw pmem::transaction_free_error when freeing old underlying array failed. + */ +template +void +vector::push_back(value_type &&value) +{ + emplace_back(std::move(value)); +} + +/** + * Removes the last element of the container transactionally. Calling pop_back + * on an empty container does nothing. No iterators or references except for + * back() and end() are invalidated. + * + * @post size() == std::max(0, size() - 1) + * + * @throw transaction_error when snapshotting failed. + * @throw rethrows desctructor exception. + */ +template +void +vector::pop_back() +{ + if (empty()) + return; + + pool_base pb = get_pool(); + transaction::run(pb, [&] { shrink(size() - 1); }); +} + +/** + * Resizes the container to count elements transactionally. If the current size + * is greater than count, the container is reduced to its first count elements. + * If the current size is less than count, additional default-inserted elements + * are appended. + * + * @param[in] count new size of the container + * + * @post capacity() == std::max(count, capacity()) + * @post size() == count + * + * @throw rethrows constructor exception. + * @throw rethrows destructor exception. + * @throw pmem::transaction_error when snapshotting failed. + * @throw pmem::transaction_free_error when freeing old underlying array failed. + */ +template +void +vector::resize(size_type count) +{ + pool_base pb = get_pool(); + transaction::run(pb, [&] { + if (count <= _size) + shrink(count); + else { + if (_capacity < count) + realloc(count); + construct(_size, count - _size); + } + }); +} + +/** + * Resizes the container to contain count elements transactionally. If the + * current size is greater than count, the container is reduced to its first + * count elements. If the current size is less than count, additional copies of + * value are appended. + * + * @param[in] count new size of the container. + * @param[in] value the value to initialize the new elements with. + * + * @post capacity() == count + * @post size() == std::min(_size, count) + * + * @throw rethrows constructor exception. + * @throw rethrows destructor exception. + * @throw pmem::transaction_error when snapshotting failed. + * @throw pmem::transaction_free_error when freeing old underlying array failed. + */ +template +void +vector::resize(size_type count, const value_type &value) +{ + if (_capacity == count) + return; + + pool_base pb = get_pool(); + transaction::run(pb, [&] { + if (count <= _size) + shrink(count); + else { + if (_capacity < count) + realloc(count); + construct(_size, count - _size, value); + } + }); +} + +/** + * Exchanges the contents of the container with other transactionally. + */ +template +void +vector::swap(vector &other) +{ + pool_base pb = get_pool(); + transaction::run(pb, [&] { + std::swap(this->_data, other._data); + std::swap(this->_size, other._size); + std::swap(this->_capacity, other._capacity); + }); +} + +/** + * Private helper function. Must be called during transaction. Allocates memory + * for given number of elements. + * + * @param[in] capacity_new capacity of new underlying array. + * + * @pre must be called in transaction scope. + * @pre data() == nullptr + * @pre size() == 0 + * + * @post capacity() == capacity_new + * + * @throw std::length_error if new size exceeds biggest possible pmem + * allocation. + * @throw pmem::transaction_alloc_error when allocating memory for underlying + * array in transaction failed. + */ +template +void +vector::alloc(size_type capacity_new) +{ + assert(pmemobj_tx_stage() == TX_STAGE_WORK); + assert(_data == nullptr); + assert(_size == 0); + + if (capacity_new > max_size()) + throw std::length_error("New capacity exceeds max size."); + + _capacity = capacity_new; + + if (capacity_new == 0) + return; + + /* + * We need to cache pmemobj_tx_alloc return value and only after that + * assign it to _data, because when pmemobj_tx_alloc fails, it aborts + * transaction. + */ + persistent_ptr res = + pmemobj_tx_alloc(sizeof(value_type) * capacity_new, + detail::type_num()); + + if (res == nullptr) + throw transaction_alloc_error( + "Failed to allocate persistent memory object"); + + _data = res; +} + +/** + * Private helper function. Checks if vector resides on pmem and throws an + * exception if not. + * + * @throw pool_error if vector doesn't reside on pmem. + */ +template +void +vector::check_pmem() +{ + if (nullptr == pmemobj_pool_by_ptr(this)) + throw pool_error("Invalid pool handle."); +} + +/** + * Private helper function. Checks if current transaction stage is equal to + * TX_STAGE_WORK and throws an exception otherwise. + * + * @throw pmem::transaction_error if current transaction stage is not equal to + * TX_STAGE_WORK. + */ +template +void +vector::check_tx_stage_work() +{ + if (pmemobj_tx_stage() != TX_STAGE_WORK) + throw transaction_error( + "Function called out of transaction scope."); +} + +/** + * Private helper function. Must be called during transaction. Assumes that + * there is free space for additional elements. Constructs elements at given + * index in underlying array based on given parameters. + * + * @param[in] idx underyling array index where new elements will be constructed. + * @param[in] count number of elements to be constructed. + * @param[in] args variadic template arguments for value_type constructor. + * + * @pre must be called in transaction scope. + * @pre if initialized, range [end(), end() + count) must be snapshotted in + * current transaction. + * @pre capacity() >= count + size() + * @pre args is valid argument for value_type constructor. + * + * @post size() == size() + count + * + * @throw rethrows constructor exception. + */ +template +template +void +vector::construct(size_type idx, size_type count, Args &&... args) +{ + assert(pmemobj_tx_stage() == TX_STAGE_WORK); + assert(_capacity >= count + _size); + + pointer dest = _data.get() + idx; + const_pointer end = dest + count; + for (; dest != end; ++dest) + detail::create( + dest, std::forward(args)...); + _size += count; +} + +/** + * Private helper function. Must be called during transaction. Assumes that + * there is free space for additional elements and input arguments satisfy + * InputIterator requirements. Moves elements at index idx in underlying array + * with the contents of the range [first, last). This overload participates in + * overload resolution only if InputIt satisfies InputIterator. + * + * @param[in] idx underyling array index where new elements will be moved. + * @param[in] first first iterator. + * @param[in] last last iterator. + * + * @pre must be called in transaction scope. + * @pre if initialized, range [end(), end() + std::distance(first, last)) must + * be snapshotted in current transaction. + * @pre capacity() >= std::distance(first, last) + size() + * @pre InputIt is InputIterator. + * @pre std::move(InputIt::reference) is valid argument for value_type + * constructor. + * + * @post size() == size() + std::distance(first, last) + * + * @throw rethrows constructor exception. + */ +template +template ::value, + InputIt>::type *> +void +vector::construct_range(size_type idx, InputIt first, InputIt last) +{ + assert(pmemobj_tx_stage() == TX_STAGE_WORK); + difference_type range_size = std::distance(first, last); + assert(range_size >= 0); + assert(_capacity >= static_cast(range_size) + _size); + + pointer dest = _data.get() + idx; + _size += static_cast(range_size); + while (first != last) + detail::create(dest++, std::move(*first++)); +} + +/** + * Private helper function. Must be called during transaction. Assumes that + * there is free space for additional elements and input arguments satisfy + * InputIterator requirements. Copy-constructs elements before pos in underlying + * array with the contents of the range [first, last). + * + * @param[in] idx underyling array index where new elements will be constructed. + * @param[in] first first iterator. + * @param[in] last last iterator. + * + * @pre must be called in transaction scope. + * @pre if initialized, range [end(), end() + std::distance(first, last)) must + * be snapshotted in current transaction. + * @pre capacity() >= std::distance(first, last) + size() + * @pre InputIt is InputIterator. + * @pre InputIt::reference is valid argument for value_type copy constructor. + * + * @post size() == size() + std::distance(first, last) + * + * @throw rethrows constructor exception. + */ +template +template ::value, + InputIt>::type *> +void +vector::construct_range_copy(size_type idx, InputIt first, InputIt last) +{ + assert(pmemobj_tx_stage() == TX_STAGE_WORK); + difference_type diff = std::distance(first, last); + assert(diff >= 0); + assert(_capacity >= static_cast(diff) + _size); + + pointer dest = _data.get() + idx; + _size += static_cast(diff); + while (first != last) + detail::create(dest++, *first++); +} + +/** + * Private helper function. Must be called during transaction. Deallocates + * underlying array. + * + * @pre must be called in transaction scope. + * + * @post size() == 0 + * @post capacity() == 0 + * @post data() == nullptr + * + * @throw pmem::transaction_error when snapshotting failed. + * @throw rethrows destructor exception. + * @throw pmem::transaction_free_error when freeing old underlying array + * failed. + */ +template +void +vector::dealloc() +{ + assert(pmemobj_tx_stage() == TX_STAGE_WORK); + + if (_data != nullptr) { + shrink(0); + if (pmemobj_tx_free(*_data.raw_ptr()) != 0) + throw transaction_free_error( + "failed to delete persistent memory object"); + _data = nullptr; + _capacity = 0; + } +} + +/** + * Private helper function. + * + * @return reference to pool_base object where vector resides. + * + * @pre underlying array must reside in persistent memory pool. + */ +template +pool_base +vector::get_pool() const noexcept +{ + auto pop = pmemobj_pool_by_ptr(this); + assert(pop != nullptr); + return pool_base(pop); +} + +/** + * Private helper function. Must be called during transaction. Inserts a gap for + * count elements starting at index idx. If there is not enough space available, + * reallocation occurs with new recommended size. + * + * param[in] idx index number where gap should be made. + * param[in] count length (expressed in number of elements) of the gap. + * + * @pre must be called in transaction scope. + * + * @post if there is not enough space for additional gap, capacity changes to + * get_recommended_capacity(). + * + * @throw pmem::transaction_error when snapshotting failed. + * @throw rethrows constructor exception. + * @throw rethrows destructor exception. + * @throw pmem::transaction_free_error when freeing old underlying array failed. + */ +template +void +vector::insert_gap(size_type idx, size_type count) +{ + assert(pmemobj_tx_stage() == TX_STAGE_WORK); + + if (_capacity >= _size + count) { + pointer dest = + &_data[static_cast(size() + count)]; + pointer begin = &_data[static_cast(idx)]; + pointer end = &_data[static_cast(size())]; + + /* + * XXX: There is no necessity to snapshot uninitialized data, so + * we can optimize it by calling: + * transaction::snapshot(begin, size() - idx). + * However, we need libpmemobj support for that, because right + * now pmemcheck will report an error (uninitialized part of + * data not added to tx). + * + * XXX: future optimization: we don't have to snapshot data + * which we will not overwrite + */ +#if LIBPMEMOBJ_CPP_VG_MEMCHECK_ENABLED + VALGRIND_MAKE_MEM_DEFINED(end, sizeof(T) * count); +#endif + snapshot_data(idx, _size + count); + + std::move_backward(begin, end, dest); + } else { + /* + * XXX: future optimization: we don't have to snapshot data + * which we will not overwrite + */ + snapshot_data(0, _size); + + auto old_data = _data; + auto old_size = _size; + pointer old_begin = &_data[0]; + pointer old_mid = &_data[static_cast(idx)]; + pointer old_end = &_data[static_cast(size())]; + + _data = nullptr; + _size = _capacity = 0; + + alloc(get_recommended_capacity(old_size + count)); + + construct_range(0, old_begin, old_mid); + construct_range(idx + count, old_mid, old_end); + + /* destroy and free old data */ + for (size_type i = 0; i < old_size; ++i) + detail::destroy( + old_data[static_cast(i)]); + if (pmemobj_tx_free(old_data.raw()) != 0) + throw transaction_free_error( + "failed to delete persistent memory object"); + } +} + +/** + * Private helper function. Must be called during transaction. Allocates new + * memory for capacity_new number of elements and copies or moves old elements + * to new memory area. If the current size is greater than capacity_new, the + * container is reduced to its first capacity_new elements. + * + * param[in] capacity_new new capacity. + * + * @pre must be called in transaction scope. + * + * @post capacity() == capacity_new + * + * @throw pmem::transaction_error when snapshotting failed. + * @throw rethrows constructor exception. + * @throw rethrows destructor exception. + * @throw pmem::transaction_free_error when freeing old underlying array failed. + */ +template +void +vector::realloc(size_type capacity_new) +{ + assert(pmemobj_tx_stage() == TX_STAGE_WORK); + + /* + * XXX: future optimization: we don't have to snapshot data + * which we will not overwrite + */ + snapshot_data(0, _size); + + auto old_data = _data; + auto old_size = _size; + pointer old_begin = &_data[0]; + pointer old_end = capacity_new < _size + ? &_data[static_cast(capacity_new)] + : &_data[static_cast(size())]; + + _data = nullptr; + _size = _capacity = 0; + + alloc(capacity_new); + + construct_range(0, old_begin, old_end); + + /* destroy and free old data */ + for (size_type i = 0; i < old_size; ++i) + detail::destroy( + old_data[static_cast(i)]); + if (pmemobj_tx_free(old_data.raw()) != 0) + throw transaction_free_error( + "failed to delete persistent memory object"); +} + +/** + * Private helper function. Returns recommended capacity for at least at_least + * elements. + * + * @return recommended new capacity. + */ +template +typename vector::size_type +vector::get_recommended_capacity(size_type at_least) const +{ + return detail::next_pow_2(at_least); +} + +/** + * Private helper function. Must be called during transaction. Destroys + * elements in underlying array beginning from position size_new. + * + * @param[in] size_new new size + * + * @pre must be called in transaction scope. + * @pre if initialized, range [begin(), end()) must be snapshotted in current + * transaction. + * @pre size_new <= size() + * + * @post size() == size_new + * + * @throw pmem::transaction_error when snapshotting failed. + * @throw rethrows destructor exception. + */ +template +void +vector::shrink(size_type size_new) +{ + assert(pmemobj_tx_stage() == TX_STAGE_WORK); + assert(size_new <= _size); + + snapshot_data(size_new, _size); + + for (size_type i = size_new; i < _size; ++i) + detail::destroy( + _data[static_cast(i)]); + _size = size_new; +} + +/** + * Private helper function. Takes a “snapshot” of data in range + * [&_data[idx_first], &_data[idx_last]) + * + * @param[in] idx_first first index. + * @param[in] idx_last last index. + * + * @throw pmem::transaction_error when snapshotting failed. + */ +template +void +vector::snapshot_data(size_type idx_first, size_type idx_last) +{ + detail::conditional_add_to_tx(_data.get() + idx_first, + idx_last - idx_first); +} + +/** + * Comparison operator. Compares the contents of two containers. + * + * Checks if containers have the same number of elements and each element in lhs + * is equal to element in rhs at the same position. + * + * @param[in] lhs first vector of type pmem::obj::experimental::vector + * @param[in] rhs second vector of type pmem::obj::experimental::vector + * + * @return true if contents of the containers are equal, false otherwise + */ +template +bool +operator==(const vector &lhs, const vector &rhs) +{ + return lhs.size() == rhs.size() && + std::equal(lhs.begin(), lhs.end(), rhs.begin()); +} + +/** + * Comparison operator. Compares the contents of two containers. + * + * Checks if containers have the same number of elements and each element in lhs + * is equal to element in rhs at the same position. + * + * @param[in] lhs first vector of type pmem::obj::experimental::vector + * @param[in] rhs second vector of type pmem::obj::experimental::vector + * + * @return true if contents of the containers are not equal, false otherwise + */ +template +bool +operator!=(const vector &lhs, const vector &rhs) +{ + return !(lhs == rhs); +} + +/** + * Comparison operator. Compares the contents of two containers + * lexicographically. + * + * @param[in] lhs first vector of type pmem::obj::experimental::vector + * @param[in] rhs second vector of type pmem::obj::experimental::vector + * + * @return true if contents of lhs are lexicographically less than contents of + * rhs, false otherwise + */ +template +bool +operator<(const vector &lhs, const vector &rhs) +{ + return std::lexicographical_compare(lhs.begin(), lhs.end(), rhs.begin(), + rhs.end()); +} + +/** + * Comparison operator. Compares the contents of two containers + * lexicographically. + * + * @param[in] lhs first vector of type pmem::obj::experimental::vector + * @param[in] rhs second vector of type pmem::obj::experimental::vector + * + * @return true if contents of lhs are lexicographically lesser than or equal to + * contents of rhs, false otherwise + */ +template +bool +operator<=(const vector &lhs, const vector &rhs) +{ + return !(rhs < lhs); +} + +/** + * Comparison operator. Compares the contents of two containers + * lexicographically. + * + * @param[in] lhs first vector of type pmem::obj::experimental::vector + * @param[in] rhs second vector of type pmem::obj::experimental::vector + * + * @return true if contents of lhs are lexicographically greater than contents + * of rhs, false otherwise + */ + +template +bool +operator>(const vector &lhs, const vector &rhs) +{ + return rhs < lhs; +} + +/** + * Comparison operator. Compares the contents of two containers + * lexicographically. + * + * @param[in] lhs first vector of type pmem::obj::experimental::vector + * @param[in] rhs second vector of type pmem::obj::experimental::vector + * + * @return true if contents of lhs are lexicographically greater than or equal + * to contents of rhs, false otherwise + */ +template +bool +operator>=(const vector &lhs, const vector &rhs) +{ + return !(lhs < rhs); +} + +/** + * Comparison operator. Compares the contents of two containers. + * + * Checks if containers have the same number of elements and each element in lhs + * is equal to element in rhs at the same position. + * + * @param[in] lhs first vector of type pmem::obj::experimental::vector + * @param[in] rhs second vector of type std::vector + * + * @return true if contents of the containers are equal, false otherwise + */ +template +bool +operator==(const vector &lhs, const std::vector &rhs) +{ + return lhs.size() == rhs.size() && + std::equal(lhs.begin(), lhs.end(), rhs.begin()); +} + +/** + * Comparison operator. Compares the contents of two containers. + * + * Checks if containers have the same number of elements and each element in lhs + * is equal to element in rhs at the same position. + * + * @param[in] lhs first vector of type pmem::obj::experimental::vector + * @param[in] rhs second vector of type std::vector + * + * @return true if contents of the containers are not equal, false otherwise + */ +template +bool +operator!=(const vector &lhs, const std::vector &rhs) +{ + return !(lhs == rhs); +} + +/** + * Comparison operator. Compares the contents of two containers + * lexicographically. + * + * @param[in] lhs first vector of type pmem::obj::experimental::vector + * @param[in] rhs second vector of type std::vector + * + * @return true if contents of lhs are lexicographically less than contents of + * rhs, false otherwise + */ +template +bool +operator<(const vector &lhs, const std::vector &rhs) +{ + return std::lexicographical_compare(lhs.begin(), lhs.end(), rhs.begin(), + rhs.end()); +} + +/** + * Comparison operator. Compares the contents of two containers + * lexicographically. + * + * @param[in] lhs first vector of type pmem::obj::experimental::vector + * @param[in] rhs second vector of ype std::vector + * + * @return true if contents of lhs are lexicographically lesser than or equal to + * contents of rhs, false otherwise + */ +template +bool +operator<=(const vector &lhs, const std::vector &rhs) +{ + return !(std::lexicographical_compare(rhs.begin(), rhs.end(), + lhs.begin(), lhs.end())); +} + +/** + * Comparison operator. Compares the contents of two containers + * lexicographically. + * + * @param[in] lhs first vector of type pmem::obj::experimental::vector + * @param[in] rhs second vector of type std::vector + * + * @return true if contents of lhs are lexicographically greater than contents + * of rhs, false otherwise + */ + +template +bool +operator>(const vector &lhs, const std::vector &rhs) +{ + return !(lhs <= rhs); +} + +/** + * Comparison operator. Compares the contents of two containers + * lexicographically. + * + * @param[in] lhs first vector of type pmem::obj::experimental::vector + * @param[in] rhs second vector of type std::vector + * + * @return true if contents of lhs are lexicographically greater than or equal + * to contents of rhs, false otherwise + */ +template +bool +operator>=(const vector &lhs, const std::vector &rhs) +{ + return !(lhs < rhs); +} + +/** + * Comparison operator. Compares the contents of two containers. + * + * Checks if containers have the same number of elements and each element in lhs + * is equal to element in rhs at the same position. + * + * @param[in] lhs first vector of type std::vector + * @param[in] rhs second vector of type pmem::obj::experimental::vector + * + * @return true if contents of the containers are equal, false otherwise + */ +template +bool +operator==(const std::vector &lhs, const vector &rhs) +{ + return rhs == lhs; +} + +/** + * Comparison operator. Compares the contents of two containers. + * + * Checks if containers have the same number of elements and each element in lhs + * is equal to element in rhs at the same position. + * + * @param[in] lhs first vector of type std::vector + * @param[in] rhs second vector of type pmem::obj::experimental::vector + * + * @return true if contents of the containers are not equal, false otherwise + */ +template +bool +operator!=(const std::vector &lhs, const vector &rhs) +{ + return !(lhs == rhs); +} + +/** + * Comparison operator. Compares the contents of two containers + * lexicographically. + * + * @param[in] lhs first vector of type std::vector + * @param[in] rhs second vector of type pmem::obj::experimental::vector + * + * @return true if contents of lhs are lexicographically less than contents of + * rhs, false otherwise + */ +template +bool +operator<(const std::vector &lhs, const vector &rhs) +{ + return rhs > lhs; +} + +/** + * Comparison operator. Compares the contents of two containers + * lexicographically. + * + * @param[in] lhs first vector of ype std::vector + * @param[in] rhs second vector of type pmem::obj::experimental::vector + * + * @return true if contents of lhs are lexicographically lesser than or equal to + * contents of rhs, false otherwise + */ +template +bool +operator<=(const std::vector &lhs, const vector &rhs) +{ + return !(rhs < lhs); +} + +/** + * Comparison operator. Compares the contents of two containers + * lexicographically. + * + * @param[in] lhs first vector of type std::vector + * @param[in] rhs second vector of type pmem::obj::experimental::vector + * + * @return true if contents of lhs are lexicographically greater than contents + * of rhs, false otherwise + */ + +template +bool +operator>(const std::vector &lhs, const vector &rhs) +{ + return rhs < lhs; +} + +/** + * Comparison operator. Compares the contents of two containers + * lexicographically. + * + * @param[in] lhs first vector of type std::vector + * @param[in] rhs second vector of type pmem::obj::experimental::vector + * + * @return true if contents of lhs are lexicographically greater than or equal + * to contents of rhs, false otherwise + */ +template +bool +operator>=(const std::vector &lhs, const vector &rhs) +{ + return !(lhs < rhs); +} + +/** + * Swaps the contents of lhs and rhs. + * + * @param[in] lhs first vector + * @param[in] rhs second vector + */ +template +void +swap(vector &lhs, vector &rhs) +{ + lhs.swap(rhs); +} + +} /* namespace experimental */ + +} /* namespace obj */ + +} /* namespace pmem */ + +#endif /* LIBPMEMOBJ_CPP_VECTOR_HPP */ diff --git a/include/libpmemobj++/make_persistent.hpp b/include/libpmemobj++/make_persistent.hpp new file mode 100644 index 0000000..c312acd --- /dev/null +++ b/include/libpmemobj++/make_persistent.hpp @@ -0,0 +1,161 @@ +/* + * Copyright 2016-2019, Intel Corporation + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * * Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +/** + * @file + * Persistent_ptr transactional allocation functions for objects. The typical + * usage examples would be: + * @snippet doc_snippets/make_persistent.cpp make_example + */ + +#ifndef LIBPMEMOBJ_CPP_MAKE_PERSISTENT_HPP +#define LIBPMEMOBJ_CPP_MAKE_PERSISTENT_HPP + +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +namespace pmem +{ + +namespace obj +{ + +/** + * Transactionally allocate and construct an object of type T. + * + * This function can be used to *transactionally* allocate an object. + * Cannot be used for array types. + * + * @param[in] flag affects behaviour of allocator + * @param[in,out] args a list of parameters passed to the constructor. + * + * @return persistent_ptr on success + * + * @throw transaction_scope_error if called outside of an active + * transaction + * @throw transaction_alloc_error on transactional allocation failure. + * @throw rethrow exception from T constructor + */ +template +typename detail::pp_if_not_array::type +make_persistent(allocation_flag flag, Args &&... args) +{ + if (pmemobj_tx_stage() != TX_STAGE_WORK) + throw transaction_scope_error( + "refusing to allocate memory outside of transaction scope"); + + persistent_ptr ptr = + pmemobj_tx_xalloc(sizeof(T), detail::type_num(), flag.value); + + if (ptr == nullptr) + throw transaction_alloc_error( + "failed to allocate persistent memory object"); + + detail::create(ptr.get(), std::forward(args)...); + + return ptr; +} + +/** + * Transactionally allocate and construct an object of type T. + * + * This function can be used to *transactionally* allocate an object. + * Cannot be used for array types. + * + * @param[in,out] args a list of parameters passed to the constructor. + * + * @return persistent_ptr on success + * + * @throw transaction_scope_error if called outside of an active + * transaction + * @throw transaction_alloc_error on transactional allocation failure. + * @throw rethrow exception from T constructor + */ +template +typename std::enable_if< + !detail::is_first_arg_same::value, + typename detail::pp_if_not_array::type>::type +make_persistent(Args &&... args) +{ + return make_persistent(allocation_flag::none(), + std::forward(args)...); +} + +/** + * Transactionally free an object of type T held in a persistent_ptr. + * + * This function can be used to *transactionally* free an object. Calls the + * object's destructor before freeing memory. Cannot be used for array + * types. + * + * @param[in,out] ptr persistent pointer to an object that is not an + * array. + * + * @throw transaction_scope_error if called outside of an active + * transaction + * @throw transaction_free_error on transactional free failure. + */ +template +void +delete_persistent(typename detail::pp_if_not_array::type ptr) +{ + if (pmemobj_tx_stage() != TX_STAGE_WORK) + throw transaction_scope_error( + "refusing to free memory outside of transaction scope"); + + if (ptr == nullptr) + return; + + /* + * At this point, everything in the object should be tracked + * and reverted on transaction abort. + */ + detail::destroy(*ptr); + + if (pmemobj_tx_free(*ptr.raw_ptr()) != 0) + throw transaction_free_error( + "failed to delete persistent memory object"); +} + +} /* namespace obj */ + +} /* namespace pmem */ + +#endif /* LIBPMEMOBJ_CPP_MAKE_PERSISTENT_HPP */ diff --git a/include/libpmemobj++/make_persistent_array.hpp b/include/libpmemobj++/make_persistent_array.hpp new file mode 100644 index 0000000..296c967 --- /dev/null +++ b/include/libpmemobj++/make_persistent_array.hpp @@ -0,0 +1,265 @@ +/* + * Copyright 2016-2019, Intel Corporation + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * * Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +/** + * @file + * Persistent_ptr allocation functions for arrays. The typical usage examples + * would be: + * @snippet doc_snippets/make_persistent.cpp make_array_example + */ + +#ifndef LIBPMEMOBJ_CPP_MAKE_PERSISTENT_ARRAY_HPP +#define LIBPMEMOBJ_CPP_MAKE_PERSISTENT_ARRAY_HPP + +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +namespace pmem +{ + +namespace obj +{ + +/** + * Transactionally allocate and construct an array of objects of type T. + * + * This function can be used to *transactionally* allocate an array. + * This overload only participates in overload resolution if T is an array. + * + * @param[in] N the number of array elements. + * @param[in] flag affects behaviour of allocator + * + * @return persistent_ptr on success + * + * @throw transaction_scope_error if called outside of an active + * transaction + * @throw transaction_alloc_error on transactional allocation failure. + * @throw rethrow exception from T constructor + */ +template +typename detail::pp_if_array::type +make_persistent(std::size_t N, allocation_flag flag = allocation_flag::none()) +{ + typedef typename detail::pp_array_type::type I; + + /* + * Allowing N greater than ptrdiff_t max value would cause problems + * with accessing array and calculating address difference between two + * elements placed further apart than ptrdiff_t max value + */ + assert(N <= + static_cast(std::numeric_limits::max())); + + if (pmemobj_tx_stage() != TX_STAGE_WORK) + throw transaction_scope_error( + "refusing to allocate memory outside of transaction scope"); + + persistent_ptr ptr = pmemobj_tx_xalloc( + sizeof(I) * N, detail::type_num(), flag.value); + + if (ptr == nullptr) + throw transaction_alloc_error( + "failed to allocate persistent memory array"); + + /* + * cache raw pointer to data - using persistent_ptr.get() in a loop + * is expensive. + */ + auto data = ptr.get(); + + /* + * When an exception is thrown from one of the constructors + * we don't perform any cleanup - i.e. we don't call destructors + * (unlike new[] operator), we only rely on transaction abort. + * This approach was taken to ensure consistent behaviour for + * case when transaction is aborted after make_persistent completes and + * we have no way to call destructors. + */ + for (std::ptrdiff_t i = 0; i < static_cast(N); ++i) + detail::create(data + i); + + return ptr; +} + +/** + * Transactionally allocate and construct an array of objects of type T. + * + * This function can be used to *transactionally* allocate an array. + * This overload only participates in overload resolution if T is an array. + * + * @param[in] flag affects behaviour of allocator + * + * @return persistent_ptr on success + * + * @throw transaction_scope_error if called outside of an active + * transaction + * @throw transaction_alloc_error on transactional allocation failure. + * @throw rethrow exception from T constructor + */ +template +typename detail::pp_if_size_array::type +make_persistent(allocation_flag flag = allocation_flag::none()) +{ + typedef typename detail::pp_array_type::type I; + enum { N = detail::pp_array_elems::elems }; + + if (pmemobj_tx_stage() != TX_STAGE_WORK) + throw transaction_scope_error( + "refusing to allocate memory outside of transaction scope"); + + persistent_ptr ptr = pmemobj_tx_xalloc( + sizeof(I) * N, detail::type_num(), flag.value); + + if (ptr == nullptr) + throw transaction_alloc_error( + "failed to allocate persistent memory array"); + + /* + * cache raw pointer to data - using persistent_ptr.get() in a loop + * is expensive. + */ + auto data = ptr.get(); + + /* + * When an exception is thrown from one of the constructors + * we don't perform any cleanup - i.e. we don't call destructors + * (unlike new[] operator), we only rely on transaction abort. + * This approach was taken to ensure consistent behaviour for + * case when transaction is aborted after make_persistent completes and + * we have no way to call destructors. + */ + for (std::ptrdiff_t i = 0; i < static_cast(N); ++i) + detail::create(data + i); + + return ptr; +} + +/** + * Transactionally free an array of objects of type T held + * in a persistent_ptr. + * + * This function can be used to *transactionally* free an array of + * objects. Calls the objects' destructors before freeing memory. + * This overload only participates in overload resolution if T is an array. + * + * @param[in,out] ptr persistent pointer to an array of objects. + * @param[in] N the size of the array. + * + * @throw transaction_scope_error if called outside of an active + * transaction + * @throw transaction_free_error on transactional free failure. + */ +template +void +delete_persistent(typename detail::pp_if_array::type ptr, std::size_t N) +{ + typedef typename detail::pp_array_type::type I; + + if (pmemobj_tx_stage() != TX_STAGE_WORK) + throw transaction_scope_error( + "refusing to free memory outside of transaction scope"); + + if (ptr == nullptr) + return; + + /* + * cache raw pointer to data - using persistent_ptr.get() in a loop + * is expensive. + */ + auto data = ptr.get(); + + for (std::ptrdiff_t i = 0; i < static_cast(N); ++i) + detail::destroy( + data[static_cast(N) - 1 - i]); + + if (pmemobj_tx_free(*ptr.raw_ptr()) != 0) + throw transaction_free_error( + "failed to delete persistent memory object"); +} + +/** + * Transactionally free an array of objects of type T held + * in a persistent_ptr. + * + * This function can be used to *transactionally* free an array of + * objects. Calls the objects' destructors before freeing memory. + * This overload only participates in overload resolution if T is an array. + * + * @param[in,out] ptr persistent pointer to an array of objects. + * + * @throw transaction_scope_error if called outside of an active + * transaction + * @throw transaction_free_error on transactional free failure. + */ +template +void +delete_persistent(typename detail::pp_if_size_array::type ptr) +{ + typedef typename detail::pp_array_type::type I; + enum { N = detail::pp_array_elems::elems }; + + if (pmemobj_tx_stage() != TX_STAGE_WORK) + throw transaction_scope_error( + "refusing to free memory outside of transaction scope"); + + if (ptr == nullptr) + return; + + /* + * cache raw pointer to data - using persistent_ptr.get() in a loop + * is expensive. + */ + auto data = ptr.get(); + + for (std::ptrdiff_t i = 0; i < static_cast(N); ++i) + detail::destroy( + data[static_cast(N) - 1 - i]); + + if (pmemobj_tx_free(*ptr.raw_ptr()) != 0) + throw transaction_free_error( + "failed to delete persistent memory object"); +} + +} /* namespace obj */ + +} /* namespace pmem */ + +#endif /* LIBPMEMOBJ_CPP_MAKE_PERSISTENT_ARRAY_HPP */ diff --git a/include/libpmemobj++/make_persistent_array_atomic.hpp b/include/libpmemobj++/make_persistent_array_atomic.hpp new file mode 100644 index 0000000..a6837bf --- /dev/null +++ b/include/libpmemobj++/make_persistent_array_atomic.hpp @@ -0,0 +1,169 @@ +/* + * Copyright 2016-2019, Intel Corporation + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * * Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +/** + * @file + * Atomic persistent_ptr allocation functions for arrays. The typical usage + * examples would be: + * @snippet doc_snippets/make_persistent.cpp make_array_atomic_example + */ + +#ifndef LIBPMEMOBJ_CPP_MAKE_PERSISTENT_ARRAY_ATOMIC_HPP +#define LIBPMEMOBJ_CPP_MAKE_PERSISTENT_ARRAY_ATOMIC_HPP + +#include +#include +#include +#include +#include +#include +#include +#include + +namespace pmem +{ + +namespace obj +{ + +/** + * Atomically allocate an array of objects. + * + * This function can be used to atomically allocate an array of objects. + * Cannot be used for simple objects. Do *NOT* use this inside transactions, as + * it might lead to undefined behavior in the presence of transaction aborts. + * + * @param[in,out] pool the pool from which the object will be allocated. + * @param[in,out] ptr the persistent pointer to which the allocation + * will take place. + * @param[in] N the number of array elements. + * @param[in] flag affects behaviour of allocator + * + * @throw std::bad_alloc on allocation failure. + */ +template +void +make_persistent_atomic( + pool_base &pool, typename detail::pp_if_array::type &ptr, + std::size_t N, + allocation_flag_atomic flag = allocation_flag_atomic::none()) +{ + typedef typename detail::pp_array_type::type I; + + auto ret = pmemobj_xalloc(pool.handle(), ptr.raw_ptr(), sizeof(I) * N, + detail::type_num(), flag.value, + &detail::array_constructor, + static_cast(&N)); + + if (ret != 0) + throw std::bad_alloc(); +} + +/** + * Atomically allocate an array of objects. + * + * This function can be used to atomically allocate an array of objects. + * Cannot be used for simple objects. Do *NOT* use this inside transactions, as + * it might lead to undefined behavior in the presence of transaction aborts. + * + * @param[in,out] pool the pool from which the object will be allocated. + * @param[in,out] ptr the persistent pointer to which the allocation + * will take place. + * @param[in] flag affects behaviour of allocator + * + * @throw std::bad_alloc on allocation failure. + */ +template +void +make_persistent_atomic( + pool_base &pool, typename detail::pp_if_size_array::type &ptr, + allocation_flag_atomic flag = allocation_flag_atomic::none()) +{ + typedef typename detail::pp_array_type::type I; + std::size_t N = detail::pp_array_elems::elems; + + auto ret = pmemobj_xalloc(pool.handle(), ptr.raw_ptr(), sizeof(I) * N, + detail::type_num(), flag.value, + &detail::array_constructor, + static_cast(&N)); + + if (ret != 0) + throw std::bad_alloc(); +} + +/** + * Atomically deallocate an array of objects. + * + * There is no way to atomically destroy an object. Any object specific + * cleanup must be performed elsewhere. Do *NOT* use this inside transactions, + * as it might lead to undefined behavior in the presence of transaction aborts. + * + * param[in,out] ptr the persistent_ptr whose pointee is to be + * deallocated. + */ +template +void +delete_persistent_atomic(typename detail::pp_if_array::type &ptr, + std::size_t) +{ + if (ptr == nullptr) + return; + + /* we CAN'T call destructor */ + pmemobj_free(ptr.raw_ptr()); +} + +/** + * Atomically deallocate an array of objects. + * + * There is no way to atomically destroy an object. Any object specific + * cleanup must be performed elsewhere. Do *NOT* use this inside transactions, + * as it might lead to undefined behavior in the presence of transaction aborts. + * + * param[in,out] ptr the persistent_ptr whose pointee is to be deallocated. + */ +template +void +delete_persistent_atomic(typename detail::pp_if_size_array::type &ptr) +{ + if (ptr == nullptr) + return; + + /* we CAN'T call destructor */ + pmemobj_free(ptr.raw_ptr()); +} + +} /* namespace obj */ + +} /* namespace pmem */ + +#endif /* LIBPMEMOBJ_CPP_MAKE_PERSISTENT_ARRAY_ATOMIC_HPP */ diff --git a/include/libpmemobj++/make_persistent_atomic.hpp b/include/libpmemobj++/make_persistent_atomic.hpp new file mode 100644 index 0000000..91f3046 --- /dev/null +++ b/include/libpmemobj++/make_persistent_atomic.hpp @@ -0,0 +1,145 @@ +/* + * Copyright 2016-2019, Intel Corporation + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * * Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +/** + * @file + * Persistent_ptr atomic allocation functions for objects. The typical usage + * examples would be: + * @snippet doc_snippets/make_persistent.cpp make_atomic_example + */ + +#ifndef LIBPMEMOBJ_CPP_MAKE_PERSISTENT_ATOMIC_HPP +#define LIBPMEMOBJ_CPP_MAKE_PERSISTENT_ATOMIC_HPP + +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +namespace pmem +{ + +namespace obj +{ + +/** + * Atomically allocate and construct an object. + * + * Constructor parameters are passed through variadic parameters. Do *NOT* use + * this inside transactions, as it might lead to undefined behavior in the + * presence of transaction aborts. + * + * @param[in,out] pool the pool from which the object will be allocated. + * @param[in,out] ptr the persistent pointer to which the allocation + * will take place. + * @param[in] flag affects behaviour of allocator + * @param[in] args variadic function parameter containing all parameters + * passed to the objects constructor. + * + * @throw std::bad_alloc on allocation failure. + */ +template +void +make_persistent_atomic(pool_base &pool, + typename detail::pp_if_not_array::type &ptr, + allocation_flag_atomic flag, Args &&... args) +{ + auto arg_pack = std::forward_as_tuple(std::forward(args)...); + auto ret = pmemobj_xalloc( + pool.handle(), ptr.raw_ptr(), sizeof(T), detail::type_num(), + flag.value, + &detail::obj_constructor, + static_cast(&arg_pack)); + + if (ret != 0) + throw std::bad_alloc(); +} + +/** + * Atomically allocate and construct an object. + * + * Constructor parameters are passed through variadic parameters. Do *NOT* use + * this inside transactions, as it might lead to undefined behavior in the + * presence of transaction aborts. + * + * @param[in,out] pool the pool from which the object will be allocated. + * @param[in,out] ptr the persistent pointer to which the allocation + * will take place. + * @param[in] args variadic function parameter containing all parameters + * passed to the objects constructor. + * + * @throw std::bad_alloc on allocation failure. + */ +template +typename std::enable_if::value>::type +make_persistent_atomic(pool_base &pool, + typename detail::pp_if_not_array::type &ptr, + Args &&... args) +{ + make_persistent_atomic(pool, ptr, allocation_flag_atomic::none(), + std::forward(args)...); +} + +/** + * Atomically deallocate an object. + * + * There is no way to atomically destroy an object. Any object specific + * cleanup must be performed elsewhere. Do *NOT* use this inside transactions, + * as it might lead to undefined behavior in the presence of transaction aborts. + * + * param[in,out] ptr the persistent_ptr whose pointee is to be + * deallocated. + */ +template +void +delete_persistent_atomic( + typename detail::pp_if_not_array::type &ptr) noexcept +{ + if (ptr == nullptr) + return; + + /* we CAN'T call the destructor */ + pmemobj_free(ptr.raw_ptr()); +} + +} /* namespace obj */ + +} /* namespace pmem */ + +#endif /* LIBPMEMOBJ_CPP_MAKE_PERSISTENT_ATOMIC_HPP */ diff --git a/include/libpmemobj++/mutex.hpp b/include/libpmemobj++/mutex.hpp new file mode 100644 index 0000000..9ad31e6 --- /dev/null +++ b/include/libpmemobj++/mutex.hpp @@ -0,0 +1,193 @@ +/* + * Copyright 2016-2018, Intel Corporation + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * * Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +/** + * @file + * Pmem-resident mutex. + */ + +#ifndef LIBPMEMOBJ_CPP_MUTEX_HPP +#define LIBPMEMOBJ_CPP_MUTEX_HPP + +#include +#include +#include + +namespace pmem +{ + +namespace obj +{ + +/** + * Persistent memory resident mutex implementation. + * + * This class is an implementation of a PMEM-resident mutex + * which mimics in behavior the C++11 std::mutex. This class + * satisfies all requirements of the Mutex and StandardLayoutType + * concepts. The typical usage example would be: + * @snippet doc_snippets/mutex.cpp unique_guard_example + */ +class mutex { +public: + /** Implementation defined handle to the native type. */ + typedef PMEMmutex *native_handle_type; + + /** + * Default constructor. + * + * @throw lock_error when the mutex is not from persistent memory. + */ + mutex() + { + PMEMobjpool *pop; + if ((pop = pmemobj_pool_by_ptr(&plock)) == nullptr) + throw lock_error( + 1, std::generic_category(), + "Persistent mutex not from persistent memory."); + + pmemobj_mutex_zero(pop, &plock); + } + + /** + * Defaulted destructor. + */ + ~mutex() = default; + + /** + * Locks the mutex, blocks if already locked. + * + * If a different thread already locked this mutex, the calling + * thread will block. If the same thread tries to lock a mutex + * it already owns, the behavior is undefined. + * + * @throw lock_error when an error occurs, this includes all + * system related errors with the underlying implementation of + * the mutex. + */ + void + lock() + { + PMEMobjpool *pop = pmemobj_pool_by_ptr(this); + if (int ret = pmemobj_mutex_lock(pop, &this->plock)) + throw lock_error(ret, std::system_category(), + "Failed to lock a mutex."); + } + + /** + * Tries to lock the mutex, returns regardless if the lock + * succeeds. + * + * If the same thread tries to lock a mutex it already owns, + * the behavior is undefined. + * + * @return `true` on successful lock acquisition, `false` + * otherwise. + * + * @throw lock_error when an error occurs, this includes all + * system related errors with the underlying implementation of + * the mutex. + */ + bool + try_lock() + { + PMEMobjpool *pop = pmemobj_pool_by_ptr(this); + int ret = pmemobj_mutex_trylock(pop, &this->plock); + + if (ret == 0) + return true; + else if (ret == EBUSY) + return false; + else + throw lock_error(ret, std::system_category(), + "Failed to lock a mutex."); + } + + /** + * Unlocks a previously locked mutex. + * + * Unlocking a mutex that has not been locked by the current + * thread results in undefined behavior. Unlocking a mutex that + * has not been lock also results in undefined behavior. + */ + void + unlock() + { + PMEMobjpool *pop = pmemobj_pool_by_ptr(this); + int ret = pmemobj_mutex_unlock(pop, &this->plock); + if (ret) + throw lock_error(ret, std::system_category(), + "Failed to unlock a mutex."); + } + + /** + * Access a native handle to this condition variable. + * + * @return a pointer to PMEMmutex. + */ + native_handle_type + native_handle() noexcept + { + return &this->plock; + } + + /** + * The type of lock needed for the transaction API. + * + * @return TX_PARAM_MUTEX + */ + enum pobj_tx_param + lock_type() const noexcept + { + return TX_PARAM_MUTEX; + } + + /** + * Deleted assignment operator. + */ + mutex &operator=(const mutex &) = delete; + + /** + * Deleted copy constructor. + */ + mutex(const mutex &) = delete; + +private: + /** A POSIX style PMEM-resident mutex.*/ + PMEMmutex plock; +}; + +} /* namespace obj */ + +} /* namespace pmem */ + +#endif /* LIBPMEMOBJ_CPP_MUTEX_HPP */ diff --git a/include/libpmemobj++/p.hpp b/include/libpmemobj++/p.hpp new file mode 100644 index 0000000..0462923 --- /dev/null +++ b/include/libpmemobj++/p.hpp @@ -0,0 +1,197 @@ +/* + * Copyright 2015-2018, Intel Corporation + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * * Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +/** + * @file + * Resides on pmem property template. + */ + +#ifndef LIBPMEMOBJ_CPP_P_HPP +#define LIBPMEMOBJ_CPP_P_HPP + +#include + +#include +#include + +namespace pmem +{ + +namespace obj +{ +/** + * Resides on pmem class. + * + * p class is a property-like template class that has to be used for all + * variables (excluding persistent pointers), which are used in pmemobj + * transactions. The p property makes sure that changes to a variable within + * a transaction are made atomically with respect to persistence. It does it by + * creating a snapshot of the variable when modified in the transaction scope. + * The p class is not designed to be used with compound types. For that see the + * persistent_ptr. + * @snippet doc_snippets/persistent.cpp p_property_example + */ +template +class p { + typedef p this_type; + +public: + /** + * Value constructor. + * + * Directly assigns a value to the underlying storage. + * + * @param _val const reference to the value to be assigned. + */ + p(const T &_val) noexcept : val{_val} + { + } + + /** + * Defaulted constructor. + */ + p() = default; + + /** + * Assignment operator. + * + * The p<> class property assignment within a transaction + * automatically registers this operation so that a rollback + * is possible. + * + * @throw pmem::transaction_error when adding the object to the + * transaction failed. + */ + p & + operator=(const p &rhs) + { + this_type(rhs).swap(*this); + + return *this; + } + + /** + * Converting assignment operator from a different p<>. + * + * Available only for convertible types. + * Just like regular assignment, also automatically registers + * itself in a transaction. + * + * @throw pmem::transaction_error when adding the object to the + * transaction failed. + */ + template ::value>::type> + p & + operator=(const p &rhs) + { + this_type(rhs).swap(*this); + + return *this; + } + + /** + * Conversion operator back to the underlying type. + */ + operator T() const noexcept + { + return this->val; + } + + /** + * Retrieves read-write reference of the object. + * + * The entire object is automatically added to the transaction. + * + * @return a reference to the object. + * + * @throw pmem::transaction_error when adding the object to the + * transaction failed. + */ + T & + get_rw() + { + detail::conditional_add_to_tx(this); + + return this->val; + } + + /** + * Retrieves read-only const reference of the object. + * + * This method has no transaction side effects. + * + * @return a const reference to the object. + */ + const T & + get_ro() const noexcept + { + return this->val; + } + + /** + * Swaps two p objects of the same type. + * + * @throw pmem::transaction_error when adding the object to the + * transaction failed. + */ + void + swap(p &other) + { + detail::conditional_add_to_tx(this); + detail::conditional_add_to_tx(&other); + std::swap(this->val, other.val); + } + +private: + T val; +}; + +/** + * Swaps two p objects of the same type. + * + * Non-member swap function as required by Swappable concept. + * en.cppreference.com/w/cpp/concept/Swappable + */ +template +inline void +swap(p &a, p &b) +{ + a.swap(b); +} + +} /* namespace obj */ + +} /* namespace pmem */ + +#endif /* LIBPMEMOBJ_CPP_P_HPP */ diff --git a/include/libpmemobj++/persistent_ptr.hpp b/include/libpmemobj++/persistent_ptr.hpp new file mode 100644 index 0000000..b04d944 --- /dev/null +++ b/include/libpmemobj++/persistent_ptr.hpp @@ -0,0 +1,667 @@ +/* + * Copyright 2015-2019, Intel Corporation + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * * Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +/** + * @file + * Persistent smart pointer. + */ + +#ifndef LIBPMEMOBJ_CPP_PERSISTENT_PTR_HPP +#define LIBPMEMOBJ_CPP_PERSISTENT_PTR_HPP + +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +namespace pmem +{ + +namespace obj +{ + +template +class pool; + +template +class persistent_ptr; + +/* + * persistent_ptr void specialization. + */ +template <> +class persistent_ptr : public detail::persistent_ptr_base { +public: + persistent_ptr() = default; + using detail::persistent_ptr_base::persistent_ptr_base; + using detail::persistent_ptr_base::operator=; +}; + +/* + * persistent_ptr const void specialization. + */ +template <> +class persistent_ptr + : public detail::persistent_ptr_base { +public: + persistent_ptr() = default; + using detail::persistent_ptr_base::persistent_ptr_base; + using detail::persistent_ptr_base::operator=; +}; + +/** + * Persistent pointer class. + * + * persistent_ptr implements a smart ptr. It encapsulates the PMEMoid + * fat pointer and provides member access, dereference and array + * access operators. + * + * Template parameter type has following requirements: + * - Is not polymorphic + * - Has no non-static data members of reference type + * - Satisfies Destructible requirement: + * https://en.cppreference.com/w/cpp/named_req/Destructible + * - All non-static data members and base classes follows the same requirements + * + * Even if all of the above requirements are met, type representation may vary + * depending on ABI and compiler optimizations (as stated in [class.mem]: "the + * order of allocation of non-static data members with different access control + * is unspecified"). To enforce the same layout for all ABIs and optimization + * levels type should satisfy StandardLayoutType requirement. + * + * If persistent_ptr is used with array type, additional requirement is: + * - Element type must be default constructible + * + * The persistent_ptr is not designed to work with polymorphic + * types, as they have runtime RTTI info embedded, which is implementation + * specific and thus not consistently rebuildable. Such constructs as + * polymorphic members or members of a union defined within a class held in + * a persistent_ptr will also yield undefined behavior. + * + * C++ standard states that lifetime of an object is a runtime property + * [basic.lifetime]. Conditions which must be fulfilled for object's lifetime + * to begin, imply that using any non-trivially constructible object with + * persistent_ptr is undefined behaviour. This is being partially addressed by + * the following proposal: + * https://groups.google.com/a/isocpp.org/forum/#!topic/std-proposals/bk8esqk-Qoo + * + * Another caveat is that snapshotting elements in a transaction and performing + * rollback uses memcpy internally. Using memcpy on an object in C++ is allowed + * by the standard only if the type satisfies TriviallyCopyable requirement. + * + * This type does NOT manage the life-cycle of the object. The typical usage + * example would be: + * @snippet doc_snippets/persistent.cpp persistent_ptr_example + */ +template +class persistent_ptr : public detail::persistent_ptr_base { +public: + persistent_ptr() = default; + using detail::persistent_ptr_base::persistent_ptr_base; + + /** + * Explicit void specialization of the converting constructor. + */ + explicit persistent_ptr(persistent_ptr const &rhs) noexcept + : detail::persistent_ptr_base(rhs.raw()) + { + } + + /** + * Explicit const void specialization of the converting constructor. + */ + explicit persistent_ptr(persistent_ptr const &rhs) noexcept + : detail::persistent_ptr_base(rhs.raw()) + { + } + + /** + * Persistent pointer to void conversion operator. + */ + operator persistent_ptr() const noexcept + { + return this->get(); + } + + /** + * Dereference operator. + */ + typename pmem::detail::sp_dereference::type operator*() const + noexcept + { + return *this->get(); + } + + /** + * Member access operator. + */ + typename pmem::detail::sp_member_access::type operator->() const + noexcept + { + return this->get(); + } + + /** + * Array access operator. + * + * Contains run-time bounds checking for static arrays. + */ + template ::value>> + typename pmem::detail::sp_array_access::type + operator[](std::ptrdiff_t i) const noexcept + { + assert(i >= 0 && + (i < pmem::detail::sp_extent::value || + pmem::detail::sp_extent::value == 0) && + "persistent array index out of bounds"); + + return this->get()[i]; + } + + /** + * Prefix increment operator. + */ + inline persistent_ptr & + operator++() + { + detail::conditional_add_to_tx(this); + this->oid.off += sizeof(T); + + return *this; + } + + /** + * Postfix increment operator. + */ + inline persistent_ptr + operator++(int) + { + PMEMoid noid = this->oid; + ++(*this); + + return persistent_ptr(noid); + } + + /** + * Prefix decrement operator. + */ + inline persistent_ptr & + operator--() + { + detail::conditional_add_to_tx(this); + this->oid.off -= sizeof(T); + + return *this; + } + + /** + * Postfix decrement operator. + */ + inline persistent_ptr + operator--(int) + { + PMEMoid noid = this->oid; + --(*this); + + return persistent_ptr(noid); + } + + /** + * Addition assignment operator. + */ + inline persistent_ptr & + operator+=(std::ptrdiff_t s) + { + detail::conditional_add_to_tx(this); + this->oid.off += static_cast(s) * sizeof(T); + + return *this; + } + + /** + * Subtraction assignment operator. + */ + inline persistent_ptr & + operator-=(std::ptrdiff_t s) + { + detail::conditional_add_to_tx(this); + this->oid.off -= static_cast(s) * sizeof(T); + + return *this; + } + + /** + * Persists the content of the underlying object. + * + * @param[in] pop Pmemobj pool + */ + void + persist(pool_base &pop) + { + pop.persist(this->get(), sizeof(T)); + } + + /** + * Persists what the persistent pointer points to. + * + * @throw pool_error when cannot get pool from persistent + * pointer + */ + void + persist(void) + { + pmemobjpool *pop = pmemobj_pool_by_oid(this->raw()); + + if (pop == nullptr) + throw pool_error( + "Cannot get pool from persistent pointer"); + + pmemobj_persist(pop, this->get(), sizeof(T)); + } + + /** + * Flushes what the persistent pointer points to. + * + * @param[in] pop Pmemobj pool + */ + void + flush(pool_base &pop) + { + pop.flush(this->get(), sizeof(T)); + } + + /** + * Flushes what the persistent pointer points to. + * + * @throw pool_error when cannot get pool from persistent + * pointer + */ + void + flush(void) + { + pmemobjpool *pop = pmemobj_pool_by_oid(this->raw()); + + if (pop == nullptr) + throw pool_error( + "Cannot get pool from persistent pointer"); + + pmemobj_flush(pop, this->get(), sizeof(T)); + } + + /* + * Pointer traits related. + */ + + /** + * Create a persistent pointer from a given reference. + * + * This can create a persistent_ptr to a volatile object, use with + * extreme caution. + * + * @param ref reference to an object. + */ + static persistent_ptr + pointer_to(T &ref) + { + return persistent_ptr(std::addressof(ref), 0); + } + + /** + * Rebind to a different type of pointer. + */ + template + using rebind = pmem::obj::persistent_ptr; + + /** + * The persistency type to be used with this pointer. + */ + using persistency_type = p; + + /** + * The used bool_type. + */ + using bool_type = bool; + + /* + * Random access iterator requirements (members) + */ + + /** + * The persistent_ptr iterator category. + */ + using iterator_category = std::random_access_iterator_tag; + + /** + * The persistent_ptr difference type. + */ + using difference_type = std::ptrdiff_t; + + /** + * The type of the value pointed to by the persistent_ptr. + */ + using value_type = T; + + /** + * The reference type of the value pointed to by the persistent_ptr. + */ + using reference = T &; + + /** + * The pointer type. + */ + using pointer = persistent_ptr; +}; + +/** + * Swaps two persistent_ptr objects of the same type. + * + * Non-member swap function as required by Swappable concept. + * en.cppreference.com/w/cpp/concept/Swappable + */ +template +inline void +swap(persistent_ptr &a, persistent_ptr &b) +{ + a.swap(b); +} + +/** + * Equality operator. + * + * This checks if underlying PMEMoids are equal. + */ +template +inline bool +operator==(persistent_ptr const &lhs, persistent_ptr const &rhs) noexcept +{ + return OID_EQUALS(lhs.raw(), rhs.raw()); +} + +/** + * Inequality operator. + */ +template +inline bool +operator!=(persistent_ptr const &lhs, persistent_ptr const &rhs) noexcept +{ + return !(lhs == rhs); +} + +/** + * Equality operator with nullptr. + */ +template +inline bool +operator==(persistent_ptr const &lhs, std::nullptr_t) noexcept +{ + return lhs.get() == nullptr; +} + +/** + * Equality operator with nullptr. + */ +template +inline bool +operator==(std::nullptr_t, persistent_ptr const &lhs) noexcept +{ + return lhs.get() == nullptr; +} + +/** + * Inequality operator with nullptr. + */ +template +inline bool +operator!=(persistent_ptr const &lhs, std::nullptr_t) noexcept +{ + return lhs.get() != nullptr; +} + +/** + * Inequality operator with nullptr. + */ +template +inline bool +operator!=(std::nullptr_t, persistent_ptr const &lhs) noexcept +{ + return lhs.get() != nullptr; +} + +/** + * Less than operator. + * + * @return true if the uuid_lo of lhs is less than the uuid_lo of rhs, + * should they be equal, the offsets are compared. Returns false + * otherwise. + */ +template +inline bool +operator<(persistent_ptr const &lhs, persistent_ptr const &rhs) noexcept +{ + if (lhs.raw().pool_uuid_lo == rhs.raw().pool_uuid_lo) + return lhs.raw().off < rhs.raw().off; + else + return lhs.raw().pool_uuid_lo < rhs.raw().pool_uuid_lo; +} + +/** + * Less or equal than operator. + * + * See less than operator for comparison rules. + */ +template +inline bool +operator<=(persistent_ptr const &lhs, persistent_ptr const &rhs) noexcept +{ + return !(rhs < lhs); +} + +/** + * Greater than operator. + * + * See less than operator for comparison rules. + */ +template +inline bool +operator>(persistent_ptr const &lhs, persistent_ptr const &rhs) noexcept +{ + return (rhs < lhs); +} + +/** + * Greater or equal than operator. + * + * See less than operator for comparison rules. + */ +template +inline bool +operator>=(persistent_ptr const &lhs, persistent_ptr const &rhs) noexcept +{ + return !(lhs < rhs); +} + +/* nullptr comparisons */ + +/** + * Compare a persistent_ptr with a null pointer. + */ +template +inline bool +operator<(persistent_ptr const &lhs, std::nullptr_t) noexcept +{ + return std::less::element_type *>()( + lhs.get(), nullptr); +} + +/** + * Compare a persistent_ptr with a null pointer. + */ +template +inline bool +operator<(std::nullptr_t, persistent_ptr const &rhs) noexcept +{ + return std::less::element_type *>()( + nullptr, rhs.get()); +} + +/** + * Compare a persistent_ptr with a null pointer. + */ +template +inline bool +operator<=(persistent_ptr const &lhs, std::nullptr_t) noexcept +{ + return !(nullptr < lhs); +} + +/** + * Compare a persistent_ptr with a null pointer. + */ +template +inline bool +operator<=(std::nullptr_t, persistent_ptr const &rhs) noexcept +{ + return !(rhs < nullptr); +} + +/** + * Compare a persistent_ptr with a null pointer. + */ +template +inline bool +operator>(persistent_ptr const &lhs, std::nullptr_t) noexcept +{ + return nullptr < lhs; +} + +/** + * Compare a persistent_ptr with a null pointer. + */ +template +inline bool +operator>(std::nullptr_t, persistent_ptr const &rhs) noexcept +{ + return rhs < nullptr; +} + +/** + * Compare a persistent_ptr with a null pointer. + */ +template +inline bool +operator>=(persistent_ptr const &lhs, std::nullptr_t) noexcept +{ + return !(lhs < nullptr); +} + +/** + * Compare a persistent_ptr with a null pointer. + */ +template +inline bool +operator>=(std::nullptr_t, persistent_ptr const &rhs) noexcept +{ + return !(nullptr < rhs); +} + +/** + * Addition operator for persistent pointers. + */ +template +inline persistent_ptr +operator+(persistent_ptr const &lhs, std::ptrdiff_t s) +{ + PMEMoid noid; + noid.pool_uuid_lo = lhs.raw().pool_uuid_lo; + noid.off = lhs.raw().off + static_cast(s) * sizeof(T); + + return persistent_ptr(noid); +} + +/** + * Subtraction operator for persistent pointers. + */ +template +inline persistent_ptr +operator-(persistent_ptr const &lhs, std::ptrdiff_t s) +{ + PMEMoid noid; + noid.pool_uuid_lo = lhs.raw().pool_uuid_lo; + noid.off = lhs.raw().off - static_cast(s) * sizeof(T); + + return persistent_ptr(noid); +} + +/** + * Subtraction operator for persistent pointers of identical type. + * + * Calculates the offset difference of PMEMoids in terms of represented + * objects. Calculating the difference of pointers from objects of + * different pools is not allowed. + */ +template ::type, + typename std::remove_cv::type>::value>> +inline ptrdiff_t +operator-(persistent_ptr const &lhs, persistent_ptr const &rhs) +{ + assert(lhs.raw().pool_uuid_lo == rhs.raw().pool_uuid_lo); + auto d = static_cast(lhs.raw().off - rhs.raw().off); + + return d / static_cast(sizeof(T)); +} + +/** + * Ostream operator for the persistent pointer. + */ +template +std::ostream & +operator<<(std::ostream &os, persistent_ptr const &pptr) +{ + PMEMoid raw_oid = pptr.raw(); + os << std::hex << "0x" << raw_oid.pool_uuid_lo << ", 0x" << raw_oid.off + << std::dec; + return os; +} + +} /* namespace obj */ + +} /* namespace pmem */ + +#endif /* LIBPMEMOBJ_CPP_PERSISTENT_PTR_HPP */ diff --git a/include/libpmemobj++/pext.hpp b/include/libpmemobj++/pext.hpp new file mode 100644 index 0000000..2dc9a5f --- /dev/null +++ b/include/libpmemobj++/pext.hpp @@ -0,0 +1,353 @@ +/* + * Copyright 2016-2018, Intel Corporation + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * * Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +/** + * @file + * Convenience extensions for the resides on pmem property template. + */ + +#ifndef LIBPMEMOBJ_CPP_PEXT_HPP +#define LIBPMEMOBJ_CPP_PEXT_HPP + +#include +#include +#include + +namespace pmem +{ + +namespace obj +{ + +/** + * Ostream operator overload. + */ +template +std::ostream & +operator<<(std::ostream &os, const p &pp) +{ + return os << pp.get_ro(); +} + +/** + * Istream operator overload. + */ +template +std::istream & +operator>>(std::istream &is, p &pp) +{ + is >> pp.get_rw(); + return is; +} + +/** + * Prefix increment operator overload. + */ +template +p & +operator++(p &pp) +{ + ++(pp.get_rw()); + return pp; +} + +/** + * Prefix decrement operator overload. + */ +template +p & +operator--(p &pp) +{ + --(pp.get_rw()); + return pp; +} + +/** + * Postfix increment operator overload. + */ +template +p +operator++(p &pp, int) +{ + p temp = pp; + ++pp; + return temp; +} + +/** + * Postfix decrement operator overload. + */ +template +p +operator--(p &pp, int) +{ + p temp = pp; + --pp; + return temp; +} + +/** + * Addition assignment operator overload. + */ +template +p & +operator+=(p &lhs, const p &rhs) +{ + lhs.get_rw() += rhs.get_ro(); + return lhs; +} + +/** + * Addition assignment operator overload. + */ +template +p & +operator+=(p &lhs, const Y &rhs) +{ + lhs.get_rw() += rhs; + return lhs; +} + +/** + * Subtraction assignment operator overload. + */ +template +p & +operator-=(p &lhs, const p &rhs) +{ + lhs.get_rw() -= rhs.get_ro(); + return lhs; +} + +/** + * Subtraction assignment operator overload. + */ +template +p & +operator-=(p &lhs, const Y &rhs) +{ + lhs.get_rw() -= rhs; + return lhs; +} + +/** + * Multiplication assignment operator overload. + */ +template +p & +operator*=(p &lhs, const p &rhs) +{ + lhs.get_rw() *= rhs.get_ro(); + return lhs; +} + +/** + * Multiplication assignment operator overload. + */ +template +p & +operator*=(p &lhs, const Y &rhs) +{ + lhs.get_rw() *= rhs; + return lhs; +} + +/** + * Division assignment operator overload. + */ +template +p & +operator/=(p &lhs, const p &rhs) +{ + lhs.get_rw() /= rhs.get_ro(); + return lhs; +} + +/** + * Division assignment operator overload. + */ +template +p & +operator/=(p &lhs, const Y &rhs) +{ + lhs.get_rw() /= rhs; + return lhs; +} + +/** + * Modulo assignment operator overload. + */ +template +p & +operator%=(p &lhs, const p &rhs) +{ + lhs.get_rw() %= rhs.get_ro(); + return lhs; +} + +/** + * Modulo assignment operator overload. + */ +template +p & +operator%=(p &lhs, const Y &rhs) +{ + lhs.get_rw() %= rhs; + return lhs; +} + +/** + * Bitwise AND assignment operator overload. + */ +template +p & +operator&=(p &lhs, const p &rhs) +{ + lhs.get_rw() &= rhs.get_ro(); + return lhs; +} + +/** + * Bitwise AND assignment operator overload. + */ +template +p & +operator&=(p &lhs, const Y &rhs) +{ + lhs.get_rw() &= rhs; + return lhs; +} + +/** + * Bitwise OR assignment operator overload. + */ +template +p & +operator|=(p &lhs, const p &rhs) +{ + lhs.get_rw() |= rhs.get_ro(); + return lhs; +} + +/** + * Bitwise OR assignment operator overload. + */ +template +p & +operator|=(p &lhs, const Y &rhs) +{ + lhs.get_rw() |= rhs; + return lhs; +} + +/** + * Bitwise XOR assignment operator overload. + */ +template +p & +operator^=(p &lhs, const p &rhs) +{ + lhs.get_rw() ^= rhs.get_ro(); + return lhs; +} + +/** + * Bitwise XOR assignment operator overload. + */ +template +p & +operator^=(p &lhs, const Y &rhs) +{ + lhs.get_rw() ^= rhs; + return lhs; +} + +/** + * Bitwise left shift assignment operator overload. + */ +template +p & +operator<<=(p &lhs, const p &rhs) +{ + lhs.get_rw() = lhs.get_ro() << rhs.get_ro(); + return lhs; +} + +/** + * Bitwise left shift assignment operator overload. + */ +template +p & +operator<<=(p &lhs, const Y &rhs) +{ + lhs.get_rw() = lhs.get_ro() << rhs; + return lhs; +} + +/** + * Bitwise right shift assignment operator overload. + */ +template +p & +operator>>=(p &lhs, const p &rhs) +{ + lhs.get_rw() = lhs.get_ro() >> rhs.get_ro(); + return lhs; +} + +/** + * Bitwise right shift assignment operator overload. + */ +template +p & +operator>>=(p &lhs, const Y &rhs) +{ + lhs.get_rw() = lhs.get_ro() >> rhs; + return lhs; +} + +} /* namespace obj */ + +} /* namespace pmem */ + +namespace std +{ + +template +struct numeric_limits> : public numeric_limits { + + static constexpr bool is_specialized = true; +}; + +} /* namespace std */ + +#endif /* LIBPMEMOBJ_CPP_PEXT_HPP */ diff --git a/include/libpmemobj++/pool.hpp b/include/libpmemobj++/pool.hpp new file mode 100644 index 0000000..6ff7343 --- /dev/null +++ b/include/libpmemobj++/pool.hpp @@ -0,0 +1,838 @@ +/* + * Copyright 2016-2018, Intel Corporation + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * * Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +/** + * @file + * C++ pmemobj pool. + */ + +#ifndef LIBPMEMOBJ_CPP_POOL_HPP +#define LIBPMEMOBJ_CPP_POOL_HPP + +#include +#include +#include + +#include +#include +#include +#include +#include + +namespace pmem +{ + +namespace obj +{ +template +class persistent_ptr; + +/** + * The non-template pool base class. + * + * This class is a non-template version of pool. It is useful for places + * where providing pool template argument is undesirable. The typical usage + * example would be: + * @snippet doc_snippets/pool.cpp pool_base_example + */ +class pool_base { +public: + /** + * Defaulted constructor. + */ + pool_base() noexcept : pop(nullptr) + { + } + + /** + * Explicit constructor. + * + * Create pool_base object based on C-style pool handle. + * + * @param cpop C-style pool handle. + */ + explicit pool_base(pmemobjpool *cpop) noexcept : pop(cpop) + { + } + + /** + * Defaulted copy constructor. + */ + pool_base(const pool_base &) noexcept = default; + + /** + * Defaulted move constructor. + */ + pool_base(pool_base &&) noexcept = default; + + /** + * Defaulted copy assignment operator. + */ + pool_base &operator=(const pool_base &) noexcept = default; + + /** + * Defaulted move assignment operator. + */ + pool_base &operator=(pool_base &&) noexcept = default; + + /** + * Default virtual destructor. + */ + virtual ~pool_base() noexcept = default; + + /** + * Opens an existing object store memory pool. + * + * @param path System path to the file containing the memory + * pool or a pool set. + * @param layout Unique identifier of the pool as specified at + * pool creation time. + * + * @return handle to the opened pool. + * + * @throw pmem::pool_error when an error during opening occurs. + */ + static pool_base + open(const std::string &path, const std::string &layout) + { +#ifdef _WIN32 + pmemobjpool *pop = pmemobj_openU(path.c_str(), layout.c_str()); +#else + pmemobjpool *pop = pmemobj_open(path.c_str(), layout.c_str()); +#endif + if (pop == nullptr) + throw pool_error("Failed opening pool"); + + return pool_base(pop); + } + + /** + * Creates a new transactional object store pool. + * + * @param path System path to the file to be created. If exists + * the pool can be created in-place depending on the size + * parameter. Existing file must be zeroed. + * @param layout Unique identifier of the pool, can be a + * null-terminated string. + * @param size Size of the pool in bytes. If zero and the file + * exists the pool is created in-place. + * @param mode File mode for the new file. + * + * @return handle to the created pool. + * + * @throw pmem::pool_error when an error during creation occurs. + */ + static pool_base + create(const std::string &path, const std::string &layout, + std::size_t size = PMEMOBJ_MIN_POOL, mode_t mode = DEFAULT_MODE) + { +#ifdef _WIN32 + pmemobjpool *pop = pmemobj_createU(path.c_str(), layout.c_str(), + size, mode); +#else + pmemobjpool *pop = pmemobj_create(path.c_str(), layout.c_str(), + size, mode); +#endif + if (pop == nullptr) + throw pool_error("Failed creating pool"); + + return pool_base(pop); + } + + /** + * Checks if a given pool is consistent. + * + * @param path System path to the file containing the memory + * pool or a pool set. + * @param layout Unique identifier of the pool as specified at + * pool creation time. + * + * @return -1 on error, 1 if file is consistent, 0 otherwise. + */ + static int + check(const std::string &path, const std::string &layout) noexcept + { +#ifdef _WIN32 + return pmemobj_checkU(path.c_str(), layout.c_str()); +#else + return pmemobj_check(path.c_str(), layout.c_str()); +#endif + } + +#ifdef _WIN32 + /** + * Opens an existing object store memory pool. Wide string variant. + * Available only on Windows. + * + * @param path System path to the file containing the memory + * pool or a pool set. + * @param layout Unique identifier of the pool as specified at + * pool creation time. + * + * @return handle to the opened pool. + * + * @throw pmem::pool_error when an error during opening occurs. + */ + static pool_base + open(const std::wstring &path, const std::wstring &layout) + { + pmemobjpool *pop = pmemobj_openW(path.c_str(), layout.c_str()); + if (pop == nullptr) + throw pool_error("Failed opening pool"); + + return pool_base(pop); + } + + /** + * Creates a new transactional object store pool. Wide string variant. + * Available only on Windows. + * + * @param path System path to the file to be created. If exists + * the pool can be created in-place depending on the size + * parameter. Existing file must be zeroed. + * @param layout Unique identifier of the pool, can be a + * null-terminated string. + * @param size Size of the pool in bytes. If zero and the file + * exists the pool is created in-place. + * @param mode File mode for the new file. + * + * @return handle to the created pool. + * + * @throw pmem::pool_error when an error during creation occurs. + */ + static pool_base + create(const std::wstring &path, const std::wstring &layout, + std::size_t size = PMEMOBJ_MIN_POOL, mode_t mode = DEFAULT_MODE) + { + pmemobjpool *pop = pmemobj_createW(path.c_str(), layout.c_str(), + size, mode); + if (pop == nullptr) + throw pool_error("Failed creating pool"); + + return pool_base(pop); + } + + /** + * Checks if a given pool is consistent. Wide string variant. + * Available only on Windows. + * + * @param path System path to the file containing the memory + * pool or a pool set. + * @param layout Unique identifier of the pool as specified at + * pool creation time. + * + * @return -1 on error, 1 if file is consistent, 0 otherwise. + */ + static int + check(const std::wstring &path, const std::wstring &layout) noexcept + { + return pmemobj_checkW(path.c_str(), layout.c_str()); + } +#endif + + /** + * Closes the pool. + * + * @throw std::logic_error if the pool has already been closed. + */ + void + close() + { + if (this->pop == nullptr) + throw std::logic_error("Pool already closed"); + + pmemobj_close(this->pop); + this->pop = nullptr; + } + + /** + * Performs persist operation on a given chunk of memory. + * + * @param[in] addr address of memory chunk + * @param[in] len size of memory chunk + */ + void + persist(const void *addr, size_t len) noexcept + { + pmemobj_persist(this->pop, addr, len); + } + + /** + * Performs persist operation on a given pmem property. + * + * @param[in] prop Resides on pmem property + */ + template + void + persist(const p &prop) noexcept + { + pmemobj_persist(this->pop, &prop, sizeof(Y)); + } + + /** + * Performs persist operation on a given persistent object. + * + * @param[in] ptr Persistent pointer to object + */ + template + void + persist(const persistent_ptr &ptr) noexcept + { + pmemobj_persist(this->pop, &ptr, sizeof(ptr)); + } + + /** + * Performs flush operation on a given chunk of memory. + * + * @param[in] addr address of memory chunk + * @param[in] len size of memory chunk + */ + void + flush(const void *addr, size_t len) noexcept + { + pmemobj_flush(this->pop, addr, len); + } + + /** + * Performs flush operation on a given pmem property. + * + * @param[in] prop Resides on pmem property + */ + template + void + flush(const p &prop) noexcept + { + pmemobj_flush(this->pop, &prop, sizeof(Y)); + } + + /** + * Performs flush operation on a given persistent object. + * + * @param[in] ptr Persistent pointer to object + */ + template + void + flush(const persistent_ptr &ptr) noexcept + { + pmemobj_flush(this->pop, &ptr, sizeof(ptr)); + } + + /** + * Performs drain operation. + */ + void + drain(void) noexcept + { + pmemobj_drain(this->pop); + } + + /** + * Performs memcpy and persist operation on a given chunk of + * memory. + * + * @param[in] dest destination memory address + * @param[in] src source memory address + * @param[in] len size of memory chunk + * + * @return A pointer to dest + */ + void * + memcpy_persist(void *dest, const void *src, size_t len) noexcept + { + return pmemobj_memcpy_persist(this->pop, dest, src, len); + } + + /** + * Performs memset and persist operation on a given chunk of + * memory. + * + * @param[in] dest destination memory address + * @param[in] c constant value to fill the memory + * @param[in] len size of memory chunk + * + * @return A pointer to dest + */ + void * + memset_persist(void *dest, int c, size_t len) noexcept + { + return pmemobj_memset_persist(this->pop, dest, c, len); + } + + /** + * Gets the C style handle to the pool. + * + * Necessary to be able to use the pool with the C API. + * + * @return pool opaque handle. + */ + PMEMobjpool * + handle() noexcept + { + return this->pop; + } + + POBJ_CPP_DEPRECATED PMEMobjpool * + get_handle() noexcept + { + return pool_base::handle(); + } + +protected: + /* The pool opaque handle */ + PMEMobjpool *pop; + +#ifndef _WIN32 + /* Default create mode */ + static const int DEFAULT_MODE = S_IWUSR | S_IRUSR; +#else + /* Default create mode */ + static const int DEFAULT_MODE = S_IWRITE | S_IREAD; +#endif +}; + +/** + * PMEMobj pool class + * + * This class is the pmemobj pool handler. It provides basic primitives + * for operations on pmemobj pools. The template parameter defines the + * type of the root object within the pool. The typical usage example would be: + * @snippet doc_snippets/pool.cpp pool_example + */ +template +class pool : public pool_base { +public: + /** + * Defaulted constructor. + */ + pool() noexcept = default; + + /** + * Defaulted copy constructor. + */ + pool(const pool &) noexcept = default; + + /** + * Defaulted move constructor. + */ + pool(pool &&) noexcept = default; + + /** + * Defaulted copy assignment operator. + */ + pool &operator=(const pool &) noexcept = default; + + /** + * Defaulted move assignment operator. + */ + pool &operator=(pool &&) noexcept = default; + + /** + * Default destructor. + */ + ~pool() noexcept = default; + + /** + * Defaulted copy constructor. + */ + explicit pool(const pool_base &pb) noexcept : pool_base(pb) + { + } + + /** + * Defaulted move constructor. + */ + explicit pool(pool_base &&pb) noexcept : pool_base(pb) + { + } + + /** + * Query libpmemobj state at pool scope. + * + * @param[in] name name of entry point + * + * @returns variable representing internal state + * + * For more details, see: + * http://pmem.io/pmdk/manpages/linux/master/libpmemobj/pmemobj_ctl_get.3 + */ + template + M + ctl_get(const std::string &name) + { + return ctl_get_detail(pop, name); + } + + /** + * Modify libpmemobj state at pool scope. + * + * @param[in] name name of entry point + * @param[in] arg extra argument + * + * @returns copy of arg, possibly modified by query + * + * For more details, see: + * http://pmem.io/pmdk/manpages/linux/master/libpmemobj/pmemobj_ctl_get.3 + */ + template + M + ctl_set(const std::string &name, M arg) + { + return ctl_set_detail(pop, name, arg); + } + + /** + * Execute function at pool scope. + * + * @param[in] name name of entry point + * @param[in] arg extra argument + * + * @returns copy of arg, possibly modified by query + * + * For more details, see: + * http://pmem.io/pmdk/manpages/linux/master/libpmemobj/pmemobj_ctl_get.3 + */ + template + M + ctl_exec(const std::string &name, M arg) + { + return ctl_exec_detail(pop, name, arg); + } + +#ifdef _WIN32 + /** + * Query libpmemobj state at pool scope. + * + * @param[in] name name of entry point + * + * @returns variable representing internal state + * + * For more details, see: + * http://pmem.io/pmdk/manpages/linux/master/libpmemobj/pmemobj_ctl_get.3 + */ + template + M + ctl_get(const std::wstring &name) + { + return ctl_get_detail(pop, name); + } + + /** + * Modify libpmemobj state at pool scope. + * + * @param[in] name name of entry point + * @param[in] arg extra argument + * + * @returns copy of arg, possibly modified by query + * + * For more details, see: + * http://pmem.io/pmdk/manpages/linux/master/libpmemobj/pmemobj_ctl_get.3 + */ + template + M + ctl_set(const std::wstring &name, M arg) + { + return ctl_set_detail(pop, name, arg); + } + + /** + * Execute function at pool scope. + * + * @param[in] name name of entry point + * @param[in] arg extra argument + * + * @returns copy of arg, possibly modified by query + * + * For more details, see: + * http://pmem.io/pmdk/manpages/linux/master/libpmemobj/pmemobj_ctl_get.3 + */ + template + M + ctl_exec(const std::wstring &name, M arg) + { + return ctl_exec_detail(pop, name, arg); + } +#endif + + /** + * Retrieves pool's root object. + * + * @return persistent pointer to the root object. + */ + persistent_ptr + root() + { + if (pop == nullptr) + throw pool_error("Invalid pool handle"); + + persistent_ptr root = pmemobj_root(this->pop, sizeof(T)); + return root; + } + + POBJ_CPP_DEPRECATED persistent_ptr + get_root() + { + return pool::root(); + } + + /** + * Opens an existing object store memory pool. + * + * @param path System path to the file containing the memory + * pool or a pool set. + * @param layout Unique identifier of the pool as specified at + * pool creation time. + * + * @return handle to the opened pool. + * + * @throw pmem::pool_error when an error during opening occurs. + */ + static pool + open(const std::string &path, const std::string &layout) + { + return pool(pool_base::open(path, layout)); + } + + /** + * Creates a new transactional object store pool. + * + * @param path System path to the file to be created. If exists + * the pool can be created in-place depending on the size + * parameter. Existing file must be zeroed. + * @param layout Unique identifier of the pool, can be a + * null-terminated string. + * @param size Size of the pool in bytes. If zero and the file + * exists the pool is created in-place. + * @param mode File mode for the new file. + * + * @return handle to the created pool. + * + * @throw pmem::pool_error when an error during creation occurs. + */ + static pool + create(const std::string &path, const std::string &layout, + std::size_t size = PMEMOBJ_MIN_POOL, mode_t mode = DEFAULT_MODE) + { + return pool(pool_base::create(path, layout, size, mode)); + } + + /** + * Checks if a given pool is consistent. + * + * @param path System path to the file containing the memory + * pool or a pool set. + * @param layout Unique identifier of the pool as specified at + * pool creation time. + * + * @return -1 on error, 1 if file is consistent, 0 otherwise. + */ + static int + check(const std::string &path, const std::string &layout) + { + return pool_base::check(path, layout); + } + +#ifdef _WIN32 + /** + * Opens an existing object store memory pool. Wide string variant. + * Available only on Windows. + * + * @param path System path to the file containing the memory + * pool or a pool set. + * @param layout Unique identifier of the pool as specified at + * pool creation time. + * + * @return handle to the opened pool. + * + * @throw pmem::pool_error when an error during opening occurs. + */ + static pool + open(const std::wstring &path, const std::wstring &layout) + { + return pool(pool_base::open(path, layout)); + } + + /** + * Creates a new transactional object store pool. Wide string variant. + * Available only on Windows. + * + * @param path System path to the file to be created. If exists + * the pool can be created in-place depending on the size + * parameter. Existing file must be zeroed. + * @param layout Unique identifier of the pool, can be a + * null-terminated string. + * @param size Size of the pool in bytes. If zero and the file + * exists the pool is created in-place. + * @param mode File mode for the new file. + * + * @return handle to the created pool. + * + * @throw pmem::pool_error when an error during creation occurs. + */ + static pool + create(const std::wstring &path, const std::wstring &layout, + std::size_t size = PMEMOBJ_MIN_POOL, mode_t mode = DEFAULT_MODE) + { + return pool(pool_base::create(path, layout, size, mode)); + } + + /** + * Checks if a given pool is consistent. Wide string variant. + * Available only on Windows. + * + * @param path System path to the file containing the memory + * pool or a pool set. + * @param layout Unique identifier of the pool as specified at + * pool creation time. + * + * @return -1 on error, 1 if file is consistent, 0 otherwise. + */ + static int + check(const std::wstring &path, const std::wstring &layout) + { + return pool_base::check(path, layout); + } +#endif +}; + +/** + * Query libpmemobj state at global scope. + * + * @param[in] name name of entry point + * + * @returns variable representing internal state + * + * For more details, see: + * http://pmem.io/pmdk/manpages/linux/master/libpmemobj/pmemobj_ctl_get.3 + */ +template +T +ctl_get(const std::string &name) +{ + return ctl_get_detail(nullptr, name); +} + +/** + * Modify libpmemobj state at global scope. + * + * @param[in] name name of entry point + * @param[in] arg extra argument + * + * @returns copy of arg, possibly modified by query + * + * For more details, see: + * http://pmem.io/pmdk/manpages/linux/master/libpmemobj/pmemobj_ctl_get.3 + */ +template +T +ctl_set(const std::string &name, T arg) +{ + return ctl_set_detail(nullptr, name, arg); +} + +/** + * Execute function at global scope. + * + * @param[in] name name of entry point + * @param[in] arg extra argument + * + * @returns copy of arg, possibly modified by query + * + * For more details, see: + * http://pmem.io/pmdk/manpages/linux/master/libpmemobj/pmemobj_ctl_get.3 + */ +template +T +ctl_exec(const std::string &name, T arg) +{ + return ctl_exec_detail(nullptr, name, arg); +} + +#ifdef _WIN32 +/** + * Query libpmemobj state at global scope. + * + * @param[in] name name of entry point + * + * @returns variable representing internal state + * + * For more details, see: + * http://pmem.io/pmdk/manpages/linux/master/libpmemobj/pmemobj_ctl_get.3 + */ +template +T +ctl_get(const std::wstring &name) +{ + return ctl_get_detail(nullptr, name); +} + +/** + * Modify libpmemobj state at global scope. + * + * @param[in] name name of entry point + * @param[in] arg extra argument + * + * @returns copy of arg, possibly modified by query + * + * For more details, see: + * http://pmem.io/pmdk/manpages/linux/master/libpmemobj/pmemobj_ctl_get.3 + */ +template +T +ctl_set(const std::wstring &name, T arg) +{ + return ctl_set_detail(nullptr, name, arg); +} + +/** + * Execute function at global scope. + * + * @param[in] name name of entry point + * @param[in] arg extra argument + * + * @returns copy of arg, possibly modified by query + * + * For more details, see: + * http://pmem.io/pmdk/manpages/linux/master/libpmemobj/pmemobj_ctl_get.3 + */ +template +T +ctl_exec(const std::wstring &name, T arg) +{ + return ctl_exec_detail(nullptr, name, arg); +} +#endif + +} /* namespace obj */ + +} /* namespace pmem */ + +#endif /* LIBPMEMOBJ_CPP_POOL_HPP */ diff --git a/include/libpmemobj++/shared_mutex.hpp b/include/libpmemobj++/shared_mutex.hpp new file mode 100644 index 0000000..6b5dc90 --- /dev/null +++ b/include/libpmemobj++/shared_mutex.hpp @@ -0,0 +1,261 @@ +/* + * Copyright 2016-2018, Intel Corporation + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * * Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +/** + * @file + * Pmem-resident shared mutex. + */ + +#ifndef LIBPMEMOBJ_CPP_SHARED_MUTEX_HPP +#define LIBPMEMOBJ_CPP_SHARED_MUTEX_HPP + +#include +#include + +namespace pmem +{ + +namespace obj +{ + +/** + * Persistent memory resident shared_mutex implementation. + * + * This class is an implementation of a PMEM-resident share_mutex + * which mimics in behavior the C++11 std::mutex. This class + * satisfies all requirements of the SharedMutex and StandardLayoutType + * concepts. The typical usage would be: + * @snippet doc_snippets/mutex.cpp shared_mutex_example + */ +class shared_mutex { +public: + /** Implementation defined handle to the native type. */ + typedef PMEMrwlock *native_handle_type; + + /** + * Default constructor. + * + * @throw lock_error when the shared_mutex is not from persistent + * memory. + */ + shared_mutex() + { + PMEMobjpool *pop; + if ((pop = pmemobj_pool_by_ptr(&plock)) == nullptr) + throw lock_error( + 1, std::generic_category(), + "Persistent shared mutex not from persistent memory."); + + pmemobj_rwlock_zero(pop, &plock); + } + + /** + * Defaulted destructor. + */ + ~shared_mutex() = default; + + /** + * Lock the mutex for exclusive access. + * + * If a different thread already locked this mutex, the calling + * thread will block. If the same thread tries to lock a mutex + * it already owns, either in exclusive or shared mode, + * the behavior is undefined. + * + * @throw lock_error when an error occurs, this includes all + * system related errors with the underlying implementation of + * the mutex. + */ + void + lock() + { + PMEMobjpool *pop = pmemobj_pool_by_ptr(this); + if (int ret = pmemobj_rwlock_wrlock(pop, &this->plock)) + throw lock_error(ret, std::system_category(), + "Failed to lock a shared mutex."); + } + + /** + * Lock the mutex for shared access. + * + * If a different thread already locked this mutex for exclusive + * access, the calling thread will block. If it was locked for + * shared access by a different thread, the lock will succeed. + * + * The mutex can be locked for shared access multiple times + * by the same thread. If so, the same number of unlocks must be + * made to unlock the mutex. + * + * @throw lock_error when an error occurs, this includes all + * system related errors with the underlying implementation of + * the mutex. + */ + void + lock_shared() + { + PMEMobjpool *pop = pmemobj_pool_by_ptr(this); + if (int ret = pmemobj_rwlock_rdlock(pop, &this->plock)) + throw lock_error( + ret, std::system_category(), + "Failed to shared lock a shared mutex."); + } + + /** + * Try to lock the mutex for exclusive access, returns + * regardless if the lock succeeds. + * + * If the same thread tries to lock a mutex it already owns + * either in exclusive or shared mode, the behavior is undefined. + * + * @return `true` on successful lock acquisition, `false` + * otherwise. + * + * @throw lock_error when an error occurs, this includes all + * system related errors with the underlying implementation of + * the mutex. + */ + bool + try_lock() + { + PMEMobjpool *pop = pmemobj_pool_by_ptr(this); + int ret = pmemobj_rwlock_trywrlock(pop, &this->plock); + + if (ret == 0) + return true; + else if (ret == EBUSY) + return false; + else + throw lock_error(ret, std::system_category(), + "Failed to lock a shared mutex."); + } + + /** + * Try to lock the mutex for shared access, returns + * regardless if the lock succeeds. + * + * The mutex can be locked for shared access multiple times + * by the same thread. If so, the same number of unlocks must be + * made to unlock the mutex. If the calling thread already owns + * the mutex in any mode, the behavior is undefined. + * + * @return `false` if a different thread already locked the + * mutex for exclusive access, `true` otherwise. + * + * @throw lock_error when an error occurs, this includes all + * system related errors with the underlying implementation of + * the mutex. + */ + bool + try_lock_shared() + { + PMEMobjpool *pop = pmemobj_pool_by_ptr(this); + int ret = pmemobj_rwlock_tryrdlock(pop, &this->plock); + + if (ret == 0) + return true; + else if (ret == EBUSY) + return false; + else + throw lock_error(ret, std::system_category(), + "Failed to lock a shared mutex."); + } + + /** + * Unlocks the mutex. + * + * The mutex must be locked for exclusive access by the calling + * thread, otherwise results in undefined behavior. + */ + void + unlock() + { + PMEMobjpool *pop = pmemobj_pool_by_ptr(this); + int ret = pmemobj_rwlock_unlock(pop, &this->plock); + if (ret) + throw lock_error(ret, std::system_category(), + "Failed to unlock a shared mutex."); + } + + /** + * Unlocks the mutex. + * + * The mutex must be locked for shared access by the calling + * thread, otherwise results in undefined behavior. + */ + void + unlock_shared() + { + this->unlock(); + } + + /** + * Access a native handle to this shared mutex. + * + * @return a pointer to PMEMmutex. + */ + native_handle_type + native_handle() noexcept + { + return &this->plock; + } + + /** + * The type of lock needed for the transaction API. + * + * @return TX_PARAM_RWLOCK + */ + enum pobj_tx_param + lock_type() const noexcept + { + return TX_PARAM_RWLOCK; + } + + /** + * Deleted assignment operator. + */ + shared_mutex &operator=(const shared_mutex &) = delete; + + /** + * Deleted copy constructor. + */ + shared_mutex(const shared_mutex &) = delete; + +private: + /** A POSIX style PMEM-resident shared_mutex.*/ + PMEMrwlock plock; +}; + +} /* namespace obj */ + +} /* namespace pmem */ + +#endif /* LIBPMEMOBJ_CPP_SHARED_MUTEX_HPP */ diff --git a/include/libpmemobj++/timed_mutex.hpp b/include/libpmemobj++/timed_mutex.hpp new file mode 100644 index 0000000..8256a9a --- /dev/null +++ b/include/libpmemobj++/timed_mutex.hpp @@ -0,0 +1,262 @@ +/* + * Copyright 2016-2018, Intel Corporation + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * * Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +/** + * @file + * Pmem-resident timed_mutex. + */ + +#ifndef LIBPMEMOBJ_CPP_TIMED_MUTEX_HPP +#define LIBPMEMOBJ_CPP_TIMED_MUTEX_HPP + +#include + +#include +#include + +namespace pmem +{ + +namespace obj +{ + +/** + * Persistent memory resident timed_mutex implementation. + * + * This class is an implementation of a PMEM-resident timed_mutex + * which mimics in behavior the C++11 std::timed_mutex. This class + * satisfies all requirements of the TimedMutex and StandardLayoutType + * concepts. The typical usage example would be: + * @snippet doc_snippets/mutex.cpp timed_mutex_example + */ +class timed_mutex { + typedef std::chrono::system_clock clock_type; + +public: + /** Implementation defined handle to the native type. */ + typedef PMEMmutex *native_handle_type; + + /** + * Default constructor. + * + * @throw lock_error when the timed_mutex is not from persistent memory. + */ + timed_mutex() + { + PMEMobjpool *pop; + if ((pop = pmemobj_pool_by_ptr(&plock)) == nullptr) + throw lock_error( + 1, std::generic_category(), + "Persistent mutex not from persistent memory."); + + pmemobj_mutex_zero(pop, &plock); + } + + /** + * Defaulted destructor. + */ + ~timed_mutex() = default; + + /** + * Locks the mutex, blocks if already locked. + * + * If a different thread already locked this mutex, the calling + * thread will block. If the same thread tries to lock a mutex + * it already owns, the behavior is undefined. + * + * @throw lock_error when an error occurs, this includes all + * system related errors with the underlying implementation of + * the mutex. + */ + void + lock() + { + PMEMobjpool *pop = pmemobj_pool_by_ptr(this); + if (int ret = pmemobj_mutex_lock(pop, &this->plock)) + throw lock_error(ret, std::system_category(), + "Failed to lock a mutex."); + } + + /** + * Tries to lock the mutex, returns regardless if the lock + * succeeds. + * + * If the same thread tries to lock a mutex it already owns, + * the behavior is undefined. + * + * @return `true` on successful lock acquisition, `false` + * otherwise. + * + * @throw lock_error when an error occurs, this includes all + * system related errors with the underlying implementation of + * the mutex. + */ + bool + try_lock() + { + PMEMobjpool *pop = pmemobj_pool_by_ptr(this); + int ret = pmemobj_mutex_trylock(pop, &this->plock); + + if (ret == 0) + return true; + else if (ret == EBUSY) + return false; + else + throw lock_error(ret, std::system_category(), + "Failed to lock a mutex."); + } + + /** + * Makes the current thread block until the lock is acquired or a + * specific time is reached. + * + * If the same thread tries to lock a mutex it already owns, + * the behavior is undefined. + * + * @param[in] timeout_time a specific point in time, which when + * reached unblocks the thread. + * + * @return `true` on successful lock acquisition, `false` + * otherwise. + * + * @throw lock_error when an error occurs, this includes all + * system related errors with the underlying implementation of + * the mutex. + */ + template + bool + try_lock_until( + const std::chrono::time_point &timeout_time) + { + return timedlock_impl(timeout_time); + } + + /** + * Makes the current thread block until the lock is acquired or a + * specified amount of time passes. + * + * If the same thread tries to lock a mutex it already owns, + * the behavior is undefined. + * + * @param[in] timeout_duration a specific duration, which when + * expired unblocks the thread. + * + * @return `true` on successful lock acquisition, `false` + * otherwise. + * + * @throw lock_error when an error occurs, this includes all + * system related errors with the underlying implementation of + * the mutex. + */ + template + bool + try_lock_for(const std::chrono::duration &timeout_duration) + { + return timedlock_impl(clock_type::now() + timeout_duration); + } + + /** + * Unlocks a previously locked mutex. + * + * Unlocking a mutex that has not been locked by the current + * thread results in undefined behavior. Unlocking a mutex that + * has not been lock also results in undefined behavior. + */ + void + unlock() + { + PMEMobjpool *pop = pmemobj_pool_by_ptr(this); + int ret = pmemobj_mutex_unlock(pop, &this->plock); + if (ret) + throw lock_error(ret, std::system_category(), + "Failed to unlock a mutex."); + } + + /** + * Access a native handle to this condition variable. + * + * @return a pointer to PMEMmutex. + */ + native_handle_type + native_handle() noexcept + { + return &this->plock; + } + + /** + * Deleted assignment operator. + */ + timed_mutex &operator=(const timed_mutex &) = delete; + + /** + * Deleted copy constructor. + */ + timed_mutex(const timed_mutex &) = delete; + +private: + /** + * Internal implementation of the timed lock call. + */ + template + bool + timedlock_impl(const std::chrono::time_point &abs_time) + { + PMEMobjpool *pop = pmemobj_pool_by_ptr(this); + + /* convert to my clock */ + const typename Clock::time_point their_now = Clock::now(); + const clock_type::time_point my_now = clock_type::now(); + const auto delta = abs_time - their_now; + const auto my_abs = my_now + delta; + + struct timespec ts = detail::timepoint_to_timespec(my_abs); + + auto ret = pmemobj_mutex_timedlock(pop, &this->plock, &ts); + + if (ret == 0) + return true; + else if (ret == ETIMEDOUT) + return false; + else + throw lock_error(ret, std::system_category(), + "Failed to lock a mutex"); + } + + /** A POSIX style PMEM-resident timed_mutex.*/ + PMEMmutex plock; +}; + +} /* namespace obj */ + +} /* namespace pmem */ + +#endif /* LIBPMEMOBJ_CPP_TIMED_MUTEX_HPP */ diff --git a/include/libpmemobj++/transaction.hpp b/include/libpmemobj++/transaction.hpp new file mode 100644 index 0000000..c0e7d4d --- /dev/null +++ b/include/libpmemobj++/transaction.hpp @@ -0,0 +1,524 @@ +/* + * Copyright 2016-2019, Intel Corporation + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * * Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +/** + * @file + * C++ pmemobj transactions. + */ + +#ifndef LIBPMEMOBJ_CPP_TRANSACTION_HPP +#define LIBPMEMOBJ_CPP_TRANSACTION_HPP + +#include +#include + +#include +#include +#include +#include + +namespace pmem +{ + +namespace obj +{ + +/** + * C++ transaction handler class. + * + * This class is the pmemobj transaction handler. Scoped transactions + * are handled through two internal classes: @ref manual and + * @ref automatic. + * - @ref manual transactions need to be committed manually, otherwise + * they will be aborted on object destruction.\n + * - @ref automatic transactions are only available in C++17. They + * handle transaction commit/abort automatically. + * + * This class also exposes a closure-like transaction API, which is the + * preferred way of handling transactions. + * + * The typical usage example would be: + * @snippet doc_snippets/transaction.cpp general_tx_example + */ +class transaction { +public: + /** + * C++ manual scope transaction class. + * + * This class is one of pmemobj transaction handlers. All + * operations between creating and destroying the transaction + * object are treated as performed in a transaction block and + * can be rolled back. The manual transaction has to be + * committed explicitly otherwise it will abort. + * + * The locks are held for the entire duration of the transaction. They + * are released at the end of the scope, so within the `catch` block, + * they are already unlocked. If the cleanup action requires access to + * data within a critical section, the locks have to be manually + * acquired once again. + * + *The typical usage example would be: + * @snippet doc_snippets/transaction.cpp manual_tx_example + */ + class manual { + public: + /** + * RAII constructor with pmem resident locks. + * + * Start pmemobj transaction and add list of locks to + * new transaction. The list of locks may be empty. + * + * @param[in,out] pop pool object. + * @param[in,out] locks locks of obj::mutex or + * obj::shared_mutex type. + * + * @throw pmem::transaction_error when pmemobj_tx_begin + * function or locks adding failed. + */ + template + manual(obj::pool_base &pop, L &... locks) + { + if (pmemobj_tx_begin(pop.handle(), nullptr, + TX_PARAM_NONE) != 0) + throw transaction_error( + "failed to start transaction"); + + auto err = add_lock(locks...); + + if (err) { + pmemobj_tx_abort(EINVAL); + (void)pmemobj_tx_end(); + throw transaction_error("failed to add lock"); + } + } + + /** + * Destructor. + * + * End pmemobj transaction. If the transaction has not + * been committed before object destruction, an abort + * will be issued. + */ + ~manual() noexcept + { + /* normal exit or with an active exception */ + if (pmemobj_tx_stage() == TX_STAGE_WORK) + pmemobj_tx_abort(ECANCELED); + + (void)pmemobj_tx_end(); + } + + /** + * Deleted copy constructor. + */ + manual(const manual &p) = delete; + + /** + * Deleted move constructor. + */ + manual(const manual &&p) = delete; + + /** + * Deleted assignment operator. + */ + manual &operator=(const manual &p) = delete; + + /** + * Deleted move assignment operator. + */ + manual &operator=(manual &&p) = delete; + }; + +/* + * XXX The Microsoft compiler does not follow the ISO SD-6: SG10 Feature + * Test Recommendations. "|| _MSC_VER >= 1900" is a workaround. + */ +#if __cpp_lib_uncaught_exceptions || _MSC_VER >= 1900 + /** + * C++ automatic scope transaction class. + * + * This class is one of pmemobj transaction handlers. All + * operations between creating and destroying the transaction + * object are treated as performed in a transaction block and + * can be rolled back. If you have a C++17 compliant compiler, + * the automatic transaction will commit and abort + * automatically depending on the context of object destruction. + * + * The locks are held for the entire duration of the transaction. They + * are released at the end of the scope, so within the `catch` block, + * they are already unlocked. If the cleanup action requires access to + * data within a critical section, the locks have to be manually + * acquired once again. + * + * The typical usage example would be: + * @snippet doc_snippets/transaction.cpp automatic_tx_example + */ + class automatic { + public: + /** + * RAII constructor with pmem resident locks. + * + * Start pmemobj transaction and add list of locks to + * new transaction. The list of locks may be empty. + * + * This class is only available if the + * `__cpp_lib_uncaught_exceptions` feature macro is + * defined. This is a C++17 feature. + * + * @param[in,out] pop pool object. + * @param[in,out] locks locks of obj::mutex or + * obj::shared_mutex type. + * + * @throw pmem::transaction_error when pmemobj_tx_begin + * function or locks adding failed. + */ + template + automatic(obj::pool_base &pop, L &... locks) + : tx_worker(pop, locks...) + { + } + + /** + * Destructor. + * + * End pmemobj transaction. Depending on the context + * of object destruction, the transaction will + * automatically be either committed or aborted. + * + * @throw pmem::transaction_error if the transaction got aborted + * without an active exception. + */ + ~automatic() noexcept(false) + { + /* active exception, abort handled by tx_worker */ + if (exceptions.new_uncaught_exception()) + return; + + /* transaction ended normally */ + if (pmemobj_tx_stage() == TX_STAGE_WORK) + pmemobj_tx_commit(); + /* transaction aborted, throw an exception */ + else if (pmemobj_tx_stage() == TX_STAGE_ONABORT || + (pmemobj_tx_stage() == TX_STAGE_FINALLY && + pmemobj_tx_errno() != 0)) + throw transaction_error("Transaction aborted"); + } + + /** + * Deleted copy constructor. + */ + automatic(const automatic &p) = delete; + + /** + * Deleted move constructor. + */ + automatic(const automatic &&p) = delete; + + /** + * Deleted assignment operator. + */ + automatic &operator=(const automatic &p) = delete; + + /** + * Deleted move assignment operator. + */ + automatic &operator=(automatic &&p) = delete; + + private: + /** + * Internal class for counting active exceptions. + */ + class uncaught_exception_counter { + public: + /** + * Default constructor. + * + * Sets the number of active exceptions on + * object creation. + */ + uncaught_exception_counter() + : count(std::uncaught_exceptions()) + { + } + + /** + * Notifies is a new exception is being handled. + * + * @return true if a new exception was throw + * in the scope of the object, false + * otherwise. + */ + bool + new_uncaught_exception() + { + return std::uncaught_exceptions() > this->count; + } + + private: + /** + * The number of active exceptions. + */ + int count; + } exceptions; + + transaction::manual tx_worker; + }; +#endif /* __cpp_lib_uncaught_exceptions */ + + /* + * Deleted default constructor. + */ + transaction() = delete; + + /** + * Default destructor. + * + * End pmemobj transaction. If the transaction has not been + * committed before object destruction, an abort will be issued. + */ + ~transaction() noexcept = delete; + + /** + * Manually abort the current transaction. + * + * If called within an inner transaction, the outer transactions + * will also be aborted. + * + * @param[in] err the error to be reported as the reason of the + * abort. + * + * @throw transaction_error if the transaction is in an invalid + * state. + * @throw manual_tx_abort this exception is thrown to + * signify a transaction abort. + */ + static void + abort(int err) + { + if (pmemobj_tx_stage() != TX_STAGE_WORK) + throw transaction_error("wrong stage for abort"); + + pmemobj_tx_abort(err); + throw manual_tx_abort("explicit abort " + std::to_string(err)); + } + + /** + * Manually commit a transaction. + * + * It is the sole responsibility of the caller, that after the + * call to transaction::commit() no other operations are done + * within the transaction. + * + * @throw transaction_error on any errors with ending the + * transaction. + */ + static void + commit() + { + if (pmemobj_tx_stage() != TX_STAGE_WORK) + throw transaction_error("wrong stage for commit"); + + pmemobj_tx_commit(); + } + + static int + error() noexcept + { + return pmemobj_tx_errno(); + } + + POBJ_CPP_DEPRECATED static int + get_last_tx_error() noexcept + { + return transaction::error(); + } + + /** + * Execute a closure-like transaction and lock `locks`. + * + * The locks have to be persistent memory resident locks. An + * attempt to lock the locks will be made. If any of the + * specified locks is already locked, the method will block. + * The locks are held until the end of the transaction. The + * transaction does not have to be committed manually. Manual + * aborts will end the transaction with an active exception. + * + * If an exception is thrown within the transaction, it gets aborted + * and the exception is rethrown. Therefore extra care has to be taken + * with proper error handling. + * + * The locks are held for the entire duration of the transaction. They + * are released at the end of the scope, so within the `catch` block, + * they are already unlocked. If the cleanup action requires access to + * data within a critical section, the locks have to be manually + * acquired once again. + * + * @param[in,out] pool the pool in which the transaction will take + * place. + * @param[in] tx an std::function which will perform + * operations within this transaction. + * @param[in,out] locks locks to be taken for the duration of + * the transaction. + * + * @throw transaction_error on any error pertaining the execution + * of the transaction. + * @throw manual_tx_abort on manual transaction abort. + */ + template + static void + run(pool_base &pool, std::function tx, Locks &... locks) + { + if (pmemobj_tx_begin(pool.handle(), nullptr, TX_PARAM_NONE) != + 0) + throw transaction_error("failed to start transaction"); + + auto err = add_lock(locks...); + + if (err) { + pmemobj_tx_abort(err); + (void)pmemobj_tx_end(); + throw transaction_error( + "failed to add a lock to the transaction"); + } + + try { + tx(); + } catch (manual_tx_abort &) { + (void)pmemobj_tx_end(); + throw; + } catch (...) { + /* first exception caught */ + if (pmemobj_tx_stage() == TX_STAGE_WORK) + pmemobj_tx_abort(ECANCELED); + + /* waterfall tx_end for outer tx */ + (void)pmemobj_tx_end(); + throw; + } + + auto stage = pmemobj_tx_stage(); + + if (stage == TX_STAGE_WORK) { + pmemobj_tx_commit(); + } else if (stage == TX_STAGE_ONABORT) { + (void)pmemobj_tx_end(); + throw transaction_error("transaction aborted"); + } else if (stage == TX_STAGE_NONE) { + throw transaction_error( + "transaction ended prematurely"); + } + + (void)pmemobj_tx_end(); + } + + template + POBJ_CPP_DEPRECATED static void + exec_tx(pool_base &pool, std::function tx, Locks &... locks) + { + transaction::run(pool, tx, locks...); + } + + /** + * Takes a “snapshot” of given elements of type T number (1 by default), + * located at the given address ptr in the virtual memory space and + * saves it to the undo log. The application is then free to directly + * modify the object in that memory range. In case of a failure or + * abort, all the changes within this range will be rolled back. The + * supplied block of memory has to be within the pool registered in the + * transaction. This function must be called during transaction. This + * overload only participates in overload resolution of function + * template if T satisfies requirements of IS_TRIVIALLY_COPYABLE macro. + * + * @param[in] addr pointer to the first object to be snapshotted. + * @param[in] num number of elements to be snapshotted. + * + * @pre this function must be called during transaction. + * + * @throw transaction_error when snapshotting failed or if function + * wasn't called during transaction. + */ + template ::type * = + nullptr> + static void + snapshot(const T *addr, size_t num = 1) + { + if (TX_STAGE_WORK != pmemobj_tx_stage()) + throw transaction_error( + "wrong stage for taking a snapshot."); + + if (pmemobj_tx_add_range_direct(addr, sizeof(*addr) * num)) + throw transaction_error( + "Could not take a snapshot of given memory range."); + } + +private: + /** + * Recursively add locks to the active transaction. + * + * The locks are taken in the provided order. + * + * @param[in,out] lock the lock to add. + * @param[in,out] locks the rest of the locks to be added to the + * active transaction. + * + * @return error number if adding any of the locks failed, + * 0 otherwise. + */ + template + static int + add_lock(L &lock, Locks &... locks) noexcept + { + auto err = + pmemobj_tx_lock(lock.lock_type(), lock.native_handle()); + + if (err) + return err; + + return add_lock(locks...); + } + + /** + * Method ending the recursive algorithm. + */ + static inline int + add_lock() noexcept + { + return 0; + } +}; + +} /* namespace obj */ + +} /* namespace pmem */ + +#endif /* LIBPMEMOBJ_CPP_TRANSACTION_HPP */ diff --git a/include/libpmemobj++/utils.hpp b/include/libpmemobj++/utils.hpp new file mode 100644 index 0000000..6af146e --- /dev/null +++ b/include/libpmemobj++/utils.hpp @@ -0,0 +1,94 @@ +/* + * Copyright 2016-2018, Intel Corporation + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * * Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +/** + * @file + * Libpmemobj C++ utils. + */ +#ifndef LIBPMEMOBJ_CPP_UTILS_HPP +#define LIBPMEMOBJ_CPP_UTILS_HPP + +#include +#include +#include + +namespace pmem +{ + +namespace obj +{ + +/** + * Retrieve pool handle for the given pointer. + * + * @param[in] that pointer to an object from a persistent memory pool. + * + * @return handle to the pool containing the object. + * + * @throw pool_error if the given pointer does not belong to an open pool. + */ +template +inline pool_base +pool_by_vptr(const T *that) +{ + auto pop = pmemobj_pool_by_ptr(that); + if (!pop) + throw pool_error("Object not in an open pool."); + + return pool_base(pop); +} + +/** + * Retrieve pool handle for the given persistent_ptr. + * + * @param[in] ptr pointer to an object from a persistent memory pool. + * + * @return handle to the pool containing the object. + * + * @throw pool_error if the given pointer does not belong to an open pool. + */ +template +inline pool_base +pool_by_pptr(const persistent_ptr ptr) +{ + auto pop = pmemobj_pool_by_oid(ptr.raw()); + if (!pop) + throw pool_error("Object not in an open pool."); + + return pool_base(pop); +} + +} /* namespace obj */ + +} /* namespace pmem */ + +#endif /* LIBPMEMOBJ_CPP_UTILS_HPP */ diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt new file mode 100644 index 0000000..b13b390 --- /dev/null +++ b/tests/CMakeLists.txt @@ -0,0 +1,327 @@ +# +# Copyright 2018-2019, Intel Corporation +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# +# * Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# +# * Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in +# the documentation and/or other materials provided with the +# distribution. +# +# * Neither the name of the copyright holder nor the names of its +# contributors may be used to endorse or promote products derived +# from this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +include(ctest_helpers.cmake) + +add_cppstyle(tests-common ${CMAKE_CURRENT_SOURCE_DIR}/common/*.*pp ${CMAKE_CURRENT_SOURCE_DIR}/*.c ${CMAKE_CURRENT_SOURCE_DIR}/*.h ${CMAKE_CURRENT_SOURCE_DIR}/*.cpp ${CMAKE_CURRENT_SOURCE_DIR}/*.hpp) +add_cppstyle(tests-pmemobj_cow ${CMAKE_CURRENT_SOURCE_DIR}/pmemobj_check_cow/*.*cpp) +add_check_whitespace(tests-pmemobj_cow ${CMAKE_CURRENT_SOURCE_DIR}/pmemobj_check_cow/*.*cpp) +add_check_whitespace(tests-common ${CMAKE_CURRENT_SOURCE_DIR}/common/*.*pp ${CMAKE_CURRENT_SOURCE_DIR}/*.c ${CMAKE_CURRENT_SOURCE_DIR}/*.h ${CMAKE_CURRENT_SOURCE_DIR}/*.cpp ${CMAKE_CURRENT_SOURCE_DIR}/*.hpp) +add_check_whitespace(tests-cmake ${CMAKE_CURRENT_SOURCE_DIR}/CMakeLists.txt) + +if(MSVC_VERSION) + add_flag(-W4) + add_flag(-bigobj) # fix C1128 raised for some test binaries +else() + add_flag(-Wall) +endif() +add_flag(-Wpointer-arith) +add_flag(-Wunused-macros) +add_flag(-Wsign-conversion) +add_flag(-Wsign-compare) +add_flag(-Wunreachable-code-return) +add_flag(-Wmissing-variable-declarations) +add_flag(-fno-common) + +add_flag(-ggdb DEBUG) +add_flag(-DDEBUG DEBUG) + +add_flag("-U_FORTIFY_SOURCE -D_FORTIFY_SOURCE=2" RELEASE) + +if(USE_ASAN) + add_sanitizer_flag(address) +endif() +if(USE_UBSAN) + add_sanitizer_flag(undefined) +endif() + +if(COVERAGE) + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -coverage") +endif() + +add_library(test_backtrace STATIC test_backtrace.c) +add_library(valgrind_internal STATIC valgrind_internal.cpp) + +function(build_example_queue) + add_executable(ex-queue ../examples/queue/queue.cpp) + target_include_directories(ex-queue PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/../examples) + target_link_libraries(ex-queue ${LIBPMEMOBJ_LIBRARIES} ${CMAKE_THREAD_LIBS_INIT}) +endfunction() + +function(build_example_pman) + if(CURSES_FOUND AND NOT WIN32) + add_executable(ex-pman ../examples/pman/pman.cpp) + target_include_directories(ex-pman PUBLIC ${CURSES_INCLUDE_DIR} ${CMAKE_CURRENT_SOURCE_DIR}/../examples) + target_link_libraries(ex-pman ${LIBPMEMOBJ_LIBRARIES} ${CMAKE_THREAD_LIBS_INIT} ${CURSES_LIBRARIES}) + else() + message(WARNING "ncurses not found - pman test won't be build") + endif() +endfunction() + +find_packages() + +if(VALGRIND_FOUND) + add_flag(-DLIBPMEMOBJ_CPP_VG_MEMCHECK_ENABLED=1) + add_flag(-DLIBPMEMOBJ_CPP_VG_DRD_ENABLED=1) + add_flag(-DLIBPMEMOBJ_CPP_VG_HELGRIND_ENABLED=1) + + if(VALGRIND_PMEMCHECK_FOUND) + add_flag(-DLIBPMEMOBJ_CPP_VG_PMEMCHECK_ENABLED=1) + endif() +endif() + +if(NO_GCC_VARIADIC_TEMPLATE_BUG) + build_example_queue() + add_test_generic(NAME ex-queue CASE 0 TRACERS none) + + build_example_pman() + add_test_generic(NAME ex-pman CASE 0 TRACERS none) +else() + message(WARNING "Skipping examples tests because of gcc variadic template bug") + skip_test("examples_tests" "SKIPPED_BECAUSE_OF_GCC_VARIADIC_TEMPLATE_BUG") +endif() + +if(AGGREGATE_INITIALIZATION_AVAILABLE) + build_test(aggregate_initialization aggregate_initialization/aggregate_initialization.cpp) + add_test_generic(NAME aggregate_initialization TRACERS none pmemcheck) +else() + message(WARNING "Skipping aggregate initialization test because of no compiler support") + skip_test("aggregate_initialization" "SKIPPED_BECAUSE_OF_NO_COMPILER_SUPPORT") +endif() + +build_test(allocator allocator/allocator.cpp) +add_test_generic(NAME allocator TRACERS none memcheck pmemcheck) + +build_test(detail_common detail_common/detail_common.cpp) +add_test_generic(NAME detail_common TRACERS none) + +build_test(make_persistent make_persistent/make_persistent.cpp) +add_test_generic(NAME make_persistent TRACERS none pmemcheck) + +build_test(make_persistent_atomic make_persistent_atomic/make_persistent_atomic.cpp) +add_test_generic(NAME make_persistent_atomic TRACERS none pmemcheck) + +build_test(mutex_posix mutex_posix/mutex_posix.cpp) +add_test_generic(NAME mutex_posix TRACERS drd helgrind pmemcheck) + +build_test(pool pool/pool.cpp) +add_test_generic(NAME pool CASE 0 TRACERS none) +add_test_generic(NAME pool CASE 1 TRACERS none) +add_test_generic(NAME pool CASE 2 TRACERS none) +add_test_generic(NAME pool CASE 3 TRACERS none) +add_test_generic(NAME pool CASE 4 TRACERS none) +add_test_generic(NAME pool CASE 5 TRACERS none) + +build_test(pool_primitives pool_primitives/pool_primitives.cpp) +add_test_generic(NAME pool_primitives CASE 0 TRACERS none pmemcheck) + +build_test(ptr ptr/ptr.cpp) +add_test_generic(NAME ptr CASE 0 TRACERS none pmemcheck) + +build_test(ptr_arith ptr_arith/ptr_arith.cpp) +add_test_generic(NAME ptr_arith TRACERS memcheck pmemcheck) +# XXX Bug: incompatibility between asan and custom library +if (NOT USE_ASAN) + add_test_generic(NAME ptr_arith TRACERS none) +endif() + +build_test(p_ext p_ext/p_ext.cpp) +add_test_generic(NAME p_ext TRACERS none pmemcheck) + +build_test(shared_mutex_posix shared_mutex_posix/shared_mutex_posix.cpp) +add_test_generic(NAME shared_mutex_posix TRACERS drd helgrind pmemcheck) + +build_test(transaction transaction/transaction.cpp) +add_test_generic(NAME transaction TRACERS none pmemcheck) + +if(WIN32) + build_test(pool_win pool_win/pool_win.cpp) + add_test_generic(NAME pool_win CASE 0 TRACERS none) + add_test_generic(NAME pool_win CASE 1 TRACERS none) + add_test_generic(NAME pool_win CASE 2 TRACERS none) + add_test_generic(NAME pool_win CASE 3 TRACERS none) +endif() + +if(PMEMVLT_PRESENT) + build_test(v v/v.cpp) + add_test_generic(NAME v CASE 0 TRACERS none memcheck) +else() + message(WARNING "Skipping v test because no pmemvlt support found") + skip_test("v" "SKIPPED_BECAUSE_OF_MISSING_PMEMVLT") +endif() + +if(NO_CHRONO_BUG) + build_test(cond_var cond_var/cond_var.cpp) + add_test_generic(NAME cond_var TRACERS none) + + build_test(cond_var_posix cond_var_posix/cond_var_posix.cpp) + add_test_generic(NAME cond_var_posix TRACERS drd helgrind pmemcheck) + + build_test(mutex mutex/mutex.cpp) + add_test_generic(NAME mutex TRACERS none) + + build_test(shared_mutex shared_mutex/shared_mutex.cpp) + add_test_generic(NAME shared_mutex TRACERS none) + + build_test(timed_mtx_posix timed_mtx_posix/timed_mtx_posix.cpp) + add_test_generic(NAME timed_mtx_posix TRACERS drd helgrind pmemcheck) + + build_test(timed_mtx timed_mtx/timed_mtx.cpp) + add_test_generic(NAME timed_mtx TRACERS none) +else() + message(WARNING "Skipping chrono tests because of compiler/stdc++ issues") + skip_test("chrono_tests" "SKIPPED_BECAUSE_OF_COMPILER_CHRONO_BUG") +endif() + +if(NO_CLANG_TEMPLATE_BUG) + build_test(make_persistent_array make_persistent_array/make_persistent_array.cpp) + add_test_generic(NAME make_persistent_array TRACERS none pmemcheck) + + build_test(make_persistent_array_atomic make_persistent_array_atomic/make_persistent_array_atomic.cpp) + add_test_generic(NAME make_persistent_array_atomic TRACERS none pmemcheck) +else() + message(WARNING "Skipping array tests because of clang template bug") + skip_test("make_persistent_array" "SKIPPED_BECAUSE_OF_CLANG_TEMPLATE_BUG") +endif() + +build_test(iterator_traits iterator_traits/iterator_traits.cpp) +add_test_generic(NAME iterator_traits TRACERS none) + +build_test(ctl ctl/ctl.cpp) +add_test_generic(NAME ctl CASE 0 TRACERS none) + +if(WIN32) + build_test(ctl_win ctl_win/ctl_win.cpp) + add_test_generic(NAME ctl_win CASE 0 TRACERS none) +endif() + +if (ENABLE_ARRAY) + build_test(array_algorithms array_algorithms/array_algorithms.cpp) + add_test_generic(NAME array_algorithms TRACERS none pmemcheck) + + build_test(array_slice array_slice/array_slice.cpp) + add_test_generic(NAME array_slice CASE 0 TRACERS none pmemcheck memcheck) + + build_test(array_iterator array_iterator/array_iterator.cpp) + add_test_generic(NAME array_iterator TRACERS none pmemcheck) + + build_test(array_modifiers array_modifiers/array_modifiers.cpp) + add_test_generic(NAME array_modifiers TRACERS none pmemcheck memcheck) + + if(PMREORDER_SUPPORTED) + build_test(array_slice_pmreorder array_slice_pmreorder/array_slice_pmreorder.cpp) + add_test_generic(NAME array_slice_pmreorder CASE 0 TRACERS none) + add_test_generic(NAME array_slice_pmreorder CASE 1 TRACERS none) + else() + message(WARNING "Skipping pmreorder tests because of no pmreorder support") + endif() +endif() + +if (ENABLE_VECTOR) + build_test(temp_value temp_value/temp_value.cpp) + add_test_generic(NAME temp_value TRACERS none pmemcheck memcheck) + + build_test(vector_assign_exceptions_length vector_assign_exceptions_length/vector_assign_exceptions_length.cpp) + add_test_generic(NAME vector_assign_exceptions_length TRACERS none memcheck pmemcheck) + + build_test(vector_assign_exceptions_oom vector_assign_exceptions_oom/vector_assign_exceptions_oom.cpp) + add_test_generic(NAME vector_assign_exceptions_oom TRACERS none memcheck pmemcheck) + + build_test(vector_assign_txabort vector_assign_txabort/vector_assign_txabort.cpp) + add_test_generic(NAME vector_assign_txabort TRACERS none memcheck pmemcheck) + + build_test(vector_comp_operators vector_comp_operators/vector_comp_operators.cpp) + add_test_generic(NAME vector_comp_operators TRACERS none memcheck pmemcheck) + + build_test(vector_capacity_exceptions_length vector_capacity_exceptions_length/vector_capacity_exceptions_length.cpp) + add_test_generic(NAME vector_capacity_exceptions_length TRACERS none memcheck pmemcheck) + + build_test(vector_capacity_exceptions_oom vector_capacity_exceptions_oom/vector_capacity_exceptions_oom.cpp) + add_test_generic(NAME vector_capacity_exceptions_oom TRACERS none memcheck pmemcheck) + + build_test(vector_capacity_txabort vector_capacity_txabort/vector_capacity_txabort.cpp) + add_test_generic(NAME vector_capacity_txabort TRACERS none memcheck pmemcheck) + + build_test(vector_ctor_exceptions_nopmem vector_ctor_exceptions_nopmem/vector_ctor_exceptions_nopmem.cpp) + add_test_generic(NAME vector_ctor_exceptions_nopmem TRACERS none memcheck ) + + build_test(vector_ctor_exceptions_notx vector_ctor_exceptions_notx/vector_ctor_exceptions_notx.cpp) + add_test_generic(NAME vector_ctor_exceptions_notx TRACERS none memcheck) + + build_test(vector_ctor_exceptions_oom vector_ctor_exceptions_oom/vector_ctor_exceptions_oom.cpp) + add_test_generic(NAME vector_ctor_exceptions_oom TRACERS none memcheck pmemcheck) + + build_test(vector_ctor_move vector_ctor_move/vector_ctor_move.cpp) + add_test_generic(NAME vector_ctor_move TRACERS none memcheck pmemcheck) + + build_test(vector_ctor_capacity vector_ctor_capacity/vector_ctor_capacity.cpp) + add_test_generic(NAME vector_ctor_capacity TRACERS none memcheck pmemcheck) + + build_test(vector_dtor vector_dtor/vector_dtor.cpp) + add_test_generic(NAME vector_dtor TRACERS none memcheck pmemcheck) + + build_test(vector_iterators_access vector_iterators_access/vector_iterators_access.cpp) + add_test_generic(NAME vector_iterators_access TRACERS none memcheck pmemcheck) + + build_test(vector_ctor_check_copy vector_ctor_check_copy/vector_ctor_check_copy.cpp) + add_test_generic(NAME vector_ctor_check_copy TRACERS none memcheck pmemcheck) + + build_test(vector_modifiers_exceptions_oom vector_modifiers_exceptions_oom/vector_modifiers_exceptions_oom.cpp) + add_test_generic(NAME vector_modifiers_exceptions_oom TRACERS none memcheck pmemcheck) + + build_test(vector_modifiers_txabort vector_modifiers_txabort/vector_modifiers_txabort.cpp) + add_test_generic(NAME vector_modifiers_txabort TRACERS none memcheck pmemcheck) + + build_test(vector_modifiers_type_requirements vector_modifiers_type_requirements/vector_modifiers_type_requirements.cpp) + add_test_generic(NAME vector_modifiers_type_requirements TRACERS none memcheck pmemcheck) + + build_test(vector_std_arg vector_std_arg/vector_std_arg.cpp) + add_test_generic(NAME vector_std_arg TRACERS none memcheck pmemcheck) + + build_test(vector_range vector_range/vector_range.cpp) + add_test_generic(NAME vector_range TRACERS none memcheck pmemcheck) +endif() + +if (ENABLE_STRING) + build_test(string_access string_access/string_access.cpp) + add_test_generic(NAME string_access TRACERS none memcheck pmemcheck) + + build_test(string_exceptions string_exceptions/string_exceptions.cpp) + add_test_generic(NAME string_exceptions TRACERS none memcheck pmemcheck) + + build_test(string_snapshot string_snapshot/string_snapshot.cpp) + add_test_generic(NAME string_snapshot TRACERS none memcheck pmemcheck) + + build_test(string_assign_tx_abort string_assign_tx_abort/string_assign_tx_abort.cpp) + add_test_generic(NAME string_assign_tx_abort TRACERS none memcheck pmemcheck) +endif() + +add_subdirectory(external) diff --git a/tests/aggregate_initialization/aggregate_initialization.cpp b/tests/aggregate_initialization/aggregate_initialization.cpp new file mode 100644 index 0000000..9277d5d --- /dev/null +++ b/tests/aggregate_initialization/aggregate_initialization.cpp @@ -0,0 +1,104 @@ +/* + * Copyright 2018, Intel Corporation + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * * Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "unittest.hpp" + +#include +#include +#include +#include +#include + +#include + +#define LAYOUT "cpp" + +namespace nvobj = pmem::obj; + +struct foo { + nvobj::p a; + nvobj::p b; +}; + +struct root { + nvobj::persistent_ptr pfoo; +}; + +void +test_aggregate(nvobj::pool &pop) +{ + nvobj::persistent_ptr r = pop.root(); + +#if !__cpp_lib_is_aggregate + /* make sure aggregate initialization is available */ + UT_ASSERT(0); +#endif + + try { + nvobj::transaction::run(pop, [&] { + r->pfoo = nvobj::make_persistent(2, 3); + + UT_ASSERTeq(r->pfoo->a, 2); + UT_ASSERTeq(r->pfoo->b, 3); + + nvobj::delete_persistent(r->pfoo); + }); + } catch (...) { + UT_ASSERT(0); + } +} + +int +main(int argc, char *argv[]) +{ + START(); + + if (argc != 2) + UT_FATAL("usage: %s file-name", argv[0]); + + const char *path = argv[1]; + + nvobj::pool pop; + + try { + pop = nvobj::pool::create(path, LAYOUT, PMEMOBJ_MIN_POOL, + S_IWUSR | S_IRUSR); + } catch (pmem::pool_error &pe) { + UT_FATAL("!pool::create: %s %s", pe.what(), path); + } + + test_aggregate(pop); + + pop.close(); + + return 0; +} diff --git a/tests/allocator/allocator.cpp b/tests/allocator/allocator.cpp new file mode 100644 index 0000000..067315a --- /dev/null +++ b/tests/allocator/allocator.cpp @@ -0,0 +1,186 @@ +/* + * Copyright 2016-2018, Intel Corporation + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * * Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +/* + * allocator.cpp -- cpp bindings test + * + */ +#include "unittest.hpp" + +#include +#include +#include +#include +#include + +#define LAYOUT "cpp" + +namespace nvobj = pmem::obj; + +namespace +{ + +const int TEST_ARR_SIZE = 10; + +struct foo { + + /* + * Default constructor. + */ + foo() + { + bar = 1; + for (int i = 0; i < TEST_ARR_SIZE; ++i) + arr[i] = static_cast(i); + } + + /* + * Copy constructible. + */ + foo(const foo &rhs) = default; + + /* + * Check foo values. + */ + void + test_foo() + { + UT_ASSERTeq(bar, 1); + for (int i = 0; i < TEST_ARR_SIZE; ++i) + UT_ASSERTeq(arr[i], i); + } + + nvobj::p bar; + nvobj::p arr[TEST_ARR_SIZE]; +}; + +/* + * test_alloc_valid -- (internal) test an allocation within a transaction + */ +void +test_alloc_valid(nvobj::pool_base &pop) +{ + nvobj::allocator al; + + try { + nvobj::transaction::run(pop, [&] { + auto fooptr = al.allocate(1); + UT_ASSERT(pmemobj_alloc_usable_size(fooptr.raw()) >= + sizeof(foo)); + al.construct(fooptr, foo()); + fooptr->test_foo(); + al.destroy(fooptr); + al.deallocate(fooptr); + }); + } catch (...) { + UT_ASSERT(0); + } +} + +/* + * test_alloc_invalid -- (internal) test an allocation outside of a transaction + */ +void +test_alloc_invalid() +{ + nvobj::allocator al; + bool thrown = false; + try { + auto fooptr = al.allocate(1); + al.construct(fooptr, foo()); + } catch (pmem::transaction_scope_error &) { + thrown = true; + } catch (...) { + UT_ASSERT(0); + } + + UT_ASSERT(thrown); +} + +/* + * test_alloc_equal -- (internal) test allocator equality/inequality operators + */ +void +test_alloc_equal() +{ + nvobj::allocator fooal; + nvobj::allocator intal; + std::allocator stdfooal; + std::allocator stdintal; + std::allocator stddblal; + + UT_ASSERT(fooal == fooal); + UT_ASSERT(intal == fooal); + UT_ASSERT(!(fooal != fooal)); + UT_ASSERT(!(intal != fooal)); + UT_ASSERT(fooal != stdfooal); + UT_ASSERT(fooal != stdintal); + UT_ASSERT(fooal != stddblal); + UT_ASSERT(intal != stdfooal); + UT_ASSERT(intal != stdintal); + UT_ASSERT(intal != stddblal); + UT_ASSERT(!(fooal == stdfooal)); + UT_ASSERT(!(fooal == stdintal)); + UT_ASSERT(!(fooal == stddblal)); + UT_ASSERT(!(intal == stdfooal)); + UT_ASSERT(!(intal == stdintal)); + UT_ASSERT(!(intal == stddblal)); +} +} + +int +main(int argc, char *argv[]) +{ + START(); + + if (argc != 2) + UT_FATAL("usage: %s file-name", argv[0]); + + const char *path = argv[1]; + + nvobj::pool_base pop; + + try { + pop = nvobj::pool_base::create(path, LAYOUT, PMEMOBJ_MIN_POOL, + S_IWUSR | S_IRUSR); + } catch (pmem::pool_error &pe) { + UT_FATAL("!pool::create: %s %s", pe.what(), path); + } + + test_alloc_valid(pop); + test_alloc_invalid(); + test_alloc_equal(); + + pop.close(); + + return 0; +} diff --git a/tests/array_algorithms/array_algorithms.cpp b/tests/array_algorithms/array_algorithms.cpp new file mode 100644 index 0000000..31ed46a --- /dev/null +++ b/tests/array_algorithms/array_algorithms.cpp @@ -0,0 +1,175 @@ +/* + * Copyright 2018, Intel Corporation + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * * Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "unittest.hpp" + +#include +#include + +#include +#include +#include +#include + +namespace pmemobj_exp = pmem::obj::experimental; + +struct TestSort { +#ifdef NO_GCC_AGGREGATE_INITIALIZATION_BUG + pmemobj_exp::array c = {10, 9, 8, 7, 6, 5, 4, 3, 2, 1}; +#else + pmemobj_exp::array c = {{10, 9, 8, 7, 6, 5, 4, 3, 2, 1}}; +#endif + void + sort_single_element_snapshot() + { + std::sort(c.begin(), c.end()); + + pmemobj_exp::array expected = {1, 2, 3, 4, 5, + 6, 7, 8, 9, 10}; + + UT_ASSERT(c == expected); + } + + void + sort_range_snapshot() + { + auto slice = c.range(0, c.size(), 2); + + std::sort(slice.begin(), slice.end()); + + pmemobj_exp::array expected = {1, 2, 3, 4, 5, + 6, 7, 8, 9, 10}; + + UT_ASSERT(c == expected); + } +}; + +struct root { + pmem::obj::persistent_ptr test_sort; +}; + +void +test_sort_single_element(pmem::obj::pool &pop) +{ + auto r = pop.root(); + + try { + pmem::obj::transaction::run(pop, [&] { + r->test_sort = pmem::obj::make_persistent(); + }); + } catch (...) { + UT_ASSERT(0); + } + + try { + pmem::obj::transaction::run(pop, [&] { + r->test_sort->sort_single_element_snapshot(); + + pmem::obj::transaction::abort(0); + UT_ASSERT(0); + }); + } catch (pmem::manual_tx_abort &) { + pmemobj_exp::array expected = {10, 9, 8, 7, 6, + 5, 4, 3, 2, 1}; + UT_ASSERT(r->test_sort->c == expected); + } catch (...) { + UT_ASSERT(0); + } + + try { + pmem::obj::transaction::run(pop, [&] { + pmem::obj::delete_persistent(r->test_sort); + }); + } catch (...) { + UT_ASSERT(0); + } +} + +void +test_sort_range(pmem::obj::pool &pop) +{ + auto r = pop.root(); + + try { + pmem::obj::transaction::run(pop, [&] { + r->test_sort = pmem::obj::make_persistent(); + }); + } catch (...) { + UT_ASSERT(0); + } + + try { + pmem::obj::transaction::run(pop, [&] { + r->test_sort->sort_range_snapshot(); + + pmem::obj::transaction::abort(0); + UT_ASSERT(0); + }); + } catch (pmem::manual_tx_abort &) { + pmemobj_exp::array expected = {10, 9, 8, 7, 6, + 5, 4, 3, 2, 1}; + UT_ASSERT(r->test_sort->c == expected); + } catch (...) { + UT_ASSERT(0); + } + + try { + pmem::obj::transaction::run(pop, [&] { + pmem::obj::delete_persistent(r->test_sort); + }); + } catch (...) { + UT_ASSERT(0); + } +} + +int +main(int argc, char *argv[]) +{ + START(); + + if (argc < 2) { + std::cerr << "usage: " << argv[0] << " file-name" << std::endl; + return 1; + } + + auto path = argv[1]; + + auto pop = pmem::obj::pool::create( + path, "ArrayTest", PMEMOBJ_MIN_POOL, S_IWUSR | S_IRUSR); + + test_sort_single_element(pop); + test_sort_range(pop); + + pop.close(); + + return 0; +} diff --git a/tests/array_iterator/array_iterator.cpp b/tests/array_iterator/array_iterator.cpp new file mode 100644 index 0000000..bb374e6 --- /dev/null +++ b/tests/array_iterator/array_iterator.cpp @@ -0,0 +1,262 @@ +/* + * Copyright 2018-2019, Intel Corporation + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * * Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "unittest.hpp" + +#include + +#include +#include +#include +#include + +namespace pmemobj_exp = pmem::obj::experimental; + +struct Test1 { + pmemobj_exp::array c; + + void + iterator_pass() + { + for (auto it = c.begin(); it != c.end(); it++) + *it = 1; + } + + void + check_pass() + { + for (auto &e : c) + UT_ASSERT(e == 1); + } + + void + iterator_access() + { + auto it = c.begin(); + auto it2 = it + 20; + + swap(it, it2); + + it2[c.size() - 1] = 10; + it[20] = 20; + + UT_ASSERT(c[c.size() - 1] == 10); + UT_ASSERT(c[20 + 20] == 20); + } +}; + +struct Test2 { + pmemobj_exp::array c; + + void + reverse_iterator_pass() + { + for (auto it = c.rbegin(); it != c.rend(); it++) + *it = 1; + } + + void + check_pass() + { + for (auto &e : c) + UT_ASSERT(e == 1); + } +}; + +struct Test3 { + using C = pmemobj_exp::array; + C c; + + void + iterator_operators() + { + auto slice = c.range(0, c.size()); + auto sub_slice = c.range(1, c.size() - 2); + auto cslice = c.crange(0, c.size()); + + UT_ASSERT(c.begin() == c.cbegin()); + UT_ASSERT(c.begin() == slice.begin()); + UT_ASSERT(c.begin() == sub_slice.begin() - 1); + UT_ASSERT(c.begin() == cslice.begin()); + + UT_ASSERT(c.cbegin() == slice.begin()); + UT_ASSERT(c.cbegin() == sub_slice.begin() - 1); + UT_ASSERT(c.cbegin() == cslice.begin()); + + UT_ASSERT(sub_slice.begin() - 1 == slice.begin()); + UT_ASSERT(sub_slice.begin() - 1 == cslice.begin()); + UT_ASSERT(slice.begin() == cslice.begin()); + UT_ASSERT(cslice.begin() == slice.begin()); + + UT_ASSERT(c.end() == c.cend()); + UT_ASSERT(c.end() == slice.end()); + UT_ASSERT(c.end() == sub_slice.end() + 1); + UT_ASSERT(c.end() == cslice.end()); + + UT_ASSERT(c.cend() == slice.end()); + UT_ASSERT(c.cend() == sub_slice.end() + 1); + UT_ASSERT(c.cend() == cslice.end()); + + UT_ASSERT(sub_slice.end() + 1 == slice.end()); + UT_ASSERT(sub_slice.end() + 1 == cslice.end()); + UT_ASSERT(slice.end() == cslice.end()); + UT_ASSERT(cslice.end() == slice.end()); + + UT_ASSERT(c.end() > c.begin()); + UT_ASSERT(c.end() > slice.begin()); + UT_ASSERT(c.end() > sub_slice.begin() + 1); + UT_ASSERT(c.end() > cslice.begin()); + + UT_ASSERT(slice.begin() < c.cend()); + UT_ASSERT(sub_slice.begin() + 1 < c.cend()); + UT_ASSERT(cslice.begin() < c.cend()); + + UT_ASSERT(sub_slice.end() + 1 != slice.begin()); + UT_ASSERT(sub_slice.end() + 1 != cslice.begin()); + UT_ASSERT(slice.end() != cslice.begin()); + UT_ASSERT(cslice.end() != slice.begin()); + + UT_ASSERT(C::size_type(c.end() - c.cbegin()) == c.size()); + } +}; + +struct root { + pmem::obj::persistent_ptr test1; + pmem::obj::persistent_ptr test2; + pmem::obj::persistent_ptr test3; +}; + +void +run_test1(pmem::obj::pool &pop) +{ + auto r = pop.root(); + + try { + pmem::obj::transaction::run(pop, [&] { + r->test1 = pmem::obj::make_persistent(); + }); + } catch (...) { + UT_ASSERT(0); + } + + try { + pmem::obj::transaction::run(pop, [&] { + r->test1->iterator_pass(); + r->test1->check_pass(); + }); + } catch (...) { + UT_ASSERT(0); + } + + try { + pmem::obj::transaction::run(pop, [&] { + r->test1->iterator_access(); + + pmem::obj::delete_persistent(r->test1); + }); + } catch (...) { + UT_ASSERT(0); + } +} + +void +run_test2(pmem::obj::pool &pop) +{ + auto r = pop.root(); + + try { + pmem::obj::transaction::run(pop, [&] { + r->test2 = pmem::obj::make_persistent(); + }); + } catch (...) { + UT_ASSERT(0); + } + + try { + pmem::obj::transaction::run(pop, [&] { + r->test2->reverse_iterator_pass(); + r->test2->check_pass(); + + pmem::obj::delete_persistent(r->test2); + }); + } catch (...) { + UT_ASSERT(0); + } +} + +void +run_test3(pmem::obj::pool &pop) +{ + auto r = pop.root(); + + try { + pmem::obj::transaction::run(pop, [&] { + r->test3 = pmem::obj::make_persistent(); + }); + } catch (...) { + UT_ASSERT(0); + } + + try { + pmem::obj::transaction::run(pop, [&] { + r->test3->iterator_operators(); + + pmem::obj::delete_persistent(r->test3); + }); + } catch (...) { + UT_ASSERT(0); + } +} + +int +main(int argc, char *argv[]) +{ + START(); + + if (argc < 2) { + std::cerr << "usage: " << argv[0] << " file-name" << std::endl; + return 1; + } + + auto path = argv[1]; + + auto pop = pmem::obj::pool::create( + path, "ArrayTest", PMEMOBJ_MIN_POOL, S_IWUSR | S_IRUSR); + + run_test1(pop); + run_test2(pop); + run_test3(pop); + + pop.close(); + + return 0; +} diff --git a/tests/array_modifiers/array_modifiers.cpp b/tests/array_modifiers/array_modifiers.cpp new file mode 100644 index 0000000..59eaeba --- /dev/null +++ b/tests/array_modifiers/array_modifiers.cpp @@ -0,0 +1,182 @@ +/* + * Copyright 2019, Intel Corporation + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * * Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "unittest.hpp" + +#include +#include + +#include +#include +#include +#include + +namespace pmemobj_exp = pmem::obj::experimental; + +using array_type = pmemobj_exp::array; + +struct root { + pmem::obj::persistent_ptr ptr_a; + pmem::obj::persistent_ptr ptr_b; +}; + +void +test_modifiers(pmem::obj::pool &pop) +{ + auto r = pop.root(); + + try { + pmem::obj::transaction::run(pop, [&] { + r->ptr_a = pmem::obj::make_persistent(); + r->ptr_b = pmem::obj::make_persistent(); + }); + } catch (std::exception &e) { + UT_FATALexc(e); + } + + r->ptr_a->fill(2.4); + r->ptr_b->fill(1.0); + + r->ptr_a->swap(*(r->ptr_b)); + + *(r->ptr_a) = *(r->ptr_b); + *(r->ptr_b) = std::move(*(r->ptr_a)); + + *(r->ptr_a) = *(r->ptr_b); + + *(r->ptr_b) = *(r->ptr_b); + UT_ASSERT(*(r->ptr_a) == *(r->ptr_b)); + + *(r->ptr_b) = std::move(*(r->ptr_b)); + UT_ASSERT(*(r->ptr_a) == *(r->ptr_b)); + + r->ptr_b->swap(*(r->ptr_b)); + UT_ASSERT(*(r->ptr_a) == *(r->ptr_b)); + + try { + pmem::obj::transaction::run(pop, [&] { + pmem::obj::delete_persistent(r->ptr_a); + pmem::obj::delete_persistent(r->ptr_b); + }); + } catch (std::exception &e) { + UT_FATALexc(e); + } + + /* + * All of following tests should fail - calling any array 'modifier' + * on object which is not on pmem should throw exception. + */ + array_type stack_array; + + try { + stack_array.fill(1.0); + UT_ASSERT(0); + } catch (pmem::pool_error &) { + } catch (std::exception &e) { + UT_FATALexc(e); + } + + try { + stack_array.swap(*(r->ptr_a)); + UT_ASSERT(0); + } catch (pmem::pool_error &) { + } catch (std::exception &e) { + UT_FATALexc(e); + } + + try { + stack_array = *(r->ptr_a); + UT_ASSERT(0); + } catch (pmem::pool_error &) { + } catch (std::exception &e) { + UT_FATALexc(e); + } + + try { + stack_array = std::move(*(r->ptr_a)); + UT_ASSERT(0); + } catch (pmem::pool_error &) { + } catch (std::exception &e) { + UT_FATALexc(e); + } + + try { + stack_array.swap(stack_array); + UT_ASSERT(0); + } catch (pmem::pool_error &) { + } catch (std::exception &e) { + UT_FATALexc(e); + } + + try { + /* Workaround for -Wself-assign-overloaded compile error */ + auto &ref = stack_array; + + stack_array = ref; + UT_ASSERT(0); + } catch (pmem::pool_error &) { + } catch (std::exception &e) { + UT_FATALexc(e); + } + + try { + array_type &ref = stack_array; + + stack_array = std::move(ref); + UT_ASSERT(0); + } catch (pmem::pool_error &) { + } catch (std::exception &e) { + UT_FATALexc(e); + } +} + +int +main(int argc, char *argv[]) +{ + START(); + + if (argc < 2) { + std::cerr << "usage: " << argv[0] << " file-name" << std::endl; + return 1; + } + + auto path = argv[1]; + + auto pop = pmem::obj::pool::create( + path, "ArrayTest", PMEMOBJ_MIN_POOL, S_IWUSR | S_IRUSR); + + test_modifiers(pop); + + pop.close(); + + return 0; +} diff --git a/tests/array_slice/array_slice.cpp b/tests/array_slice/array_slice.cpp new file mode 100644 index 0000000..fb2d7f3 --- /dev/null +++ b/tests/array_slice/array_slice.cpp @@ -0,0 +1,606 @@ +/* + * Copyright 2018-2019, Intel Corporation + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * * Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "unittest.hpp" + +#include +#include +#include +#include +#include + +namespace pmemobj_exp = pmem::obj::experimental; + +static bool Is_pmemcheck_enabled = false; + +struct TestSuccess { + void + run() + { + auto slice = c.range(2, 2); + + UT_ASSERT(slice.size() == 2); + UT_ASSERT(slice[0] == 3); + UT_ASSERT(slice[1] == 4); + UT_ASSERT(slice[0] == slice.at(0)); + UT_ASSERT(slice[1] == slice.at(1)); + + UT_ASSERT(slice.begin() == c.begin() + 2); + UT_ASSERT(slice.end() == c.begin() + 4); + + for (auto &it : slice) { + it = 0; + } + + UT_ASSERT(c[2] == 0); + UT_ASSERT(c[3] == 0); + + auto zero_slice = c.range(0, 0); + UT_ASSERT(zero_slice.begin() == zero_slice.end()); + + try { + /* Out of range */ + slice.at(2) = 2; + UT_ASSERT(0); + } catch (...) { + } + + try { + /* Out of range */ + c.range(100, 2); + UT_ASSERT(0); + } catch (...) { + } + + try { + /* Out of range */ + c.range(5, 2); + UT_ASSERT(0); + } catch (...) { + } + + try { + /* Out of range */ + c.crange(5, 2); + UT_ASSERT(0); + } catch (...) { + } + + try { + /* Out of range */ + c.range(5, 2, 1); + UT_ASSERT(0); + } catch (...) { + } + + try { + /* Out of range */ + c.range(5, 2, 999); + UT_ASSERT(0); + } catch (...) { + } + + try { + /* Out of range */ + c.range(5, 2, std::numeric_limits::max()); + UT_ASSERT(0); + } catch (...) { + } + + try { + /* Out of range */ + static_cast(c).range(5, 2); + UT_ASSERT(0); + } catch (...) { + } + + try { + c.range(4, 2); + } catch (...) { + UT_ASSERT(0); + } + + try { + c.crange(4, 2); + } catch (...) { + UT_ASSERT(0); + } + + try { + c.range(4, 2, 1); + } catch (...) { + UT_ASSERT(0); + } + + try { + c.range(4, 2, 999); + } catch (...) { + UT_ASSERT(0); + } + + try { + c.range(4, 2, std::numeric_limits::max()); + } catch (...) { + UT_ASSERT(0); + } + + try { + static_cast(c).range(4, 2); + } catch (...) { + UT_ASSERT(0); + } + + char data[10]; + try { + pmemobj_exp::slice good_slice(data, data); + } catch (...) { + UT_ASSERT(0); + } + + try { + pmemobj_exp::slice bad_slice(data + 1, data); + UT_ASSERT(0); + } catch (...) { + } + + { + auto ptr_s = c.range(0, 0); + auto it_s = c.range(0, 0, 0); + UT_ASSERT(ptr_s.size() == 0); + UT_ASSERT(ptr_s.size() == it_s.size()); + UT_ASSERT(ptr_s.begin() == it_s.begin()); + UT_ASSERT(ptr_s.end() == it_s.end()); + } + { + auto ptr_s = c.range(0, 5); + auto it_s = c.range(0, 5, 1); + UT_ASSERT(ptr_s.size() == 5); + UT_ASSERT(ptr_s.size() == it_s.size()); + UT_ASSERT(ptr_s.begin() == it_s.begin()); + UT_ASSERT(ptr_s.end() == it_s.end()); + } + { + auto ptr_s = c.range(1, 3); + auto it_s = c.range(1, 3, 3); + UT_ASSERT(ptr_s.size() == 3); + UT_ASSERT(ptr_s.size() == it_s.size()); + UT_ASSERT(ptr_s.begin() == it_s.begin()); + UT_ASSERT(ptr_s.end() == it_s.end()); + } + } + + void + run_reverse() + { + auto slice = c.range(1, 5, 2); + UT_ASSERT(slice.size() == 5); + + int i = 0; + for (auto it = slice.rbegin(); it != slice.rend(); it++, i++) + *it = i; + + UT_ASSERT(c[5] == 0); + UT_ASSERT(c[4] == 1); + UT_ASSERT(c[3] == 2); + UT_ASSERT(c[2] == 3); + UT_ASSERT(c[1] == 4); + } + + using C = pmemobj_exp::array; + C c = {{1, 2, 3, 4, 5, 6}}; +}; + +struct TestAbort { + void + run() + { + /* slice from 2 to 12 with snapshot_size = 3 + * snapshotting ranges are: <2,4>, <5,7>, <8,10>, <11> */ + auto slice = c.range(2, 10, 3); + UT_ASSERT(slice.size() == 10); + + auto it = slice.begin(); + + /* it points to c[2], + * <2,4> should be added to a transaction */ + *it = 99; + + it += 9; + + /* it points to c[11] + * <11> should be snapshotted */ + *it = 102; + + it--; + it--; + + /* it points to c[9], + * <8,10> should be added to a transaction */ + *it = 100; + + C expected = { + {1, 2, 99, 4, 5, 6, 7, 8, 9, 100, 11, 102, 13, 14, 15}}; + UT_ASSERT(c == expected); + + if (!Is_pmemcheck_enabled) { + it = slice.begin() + 10; + /* it points to c[12] (outside of range) + * no snapshotting */ + *it = 101; + + /* zero <5,7> range not adding it to a transaction */ + c._data[5] = 0; + c._data[6] = 0; + c._data[7] = 0; + + C expected = {{1, 2, 99, 4, 5, 0, 0, 0, 9, 100, 11, 102, + 101, 14, 15}}; + UT_ASSERT(c == expected); + + auto ptr_slice = c2.range(1, 4); + for (auto &e : ptr_slice) + e = 1; + + c2._data[0] = 0; + c2._data[5] = 0; + + C expected2 = {{0, 1, 1, 1, 1, 0, 7, 8, 9, 10, 11, 12, + 13, 14, 15}}; + UT_ASSERT(c2 == expected2); + } + } + + void + run_zero() + { + auto slice = c.range(0, c.size(), 0); + + for (auto &e : slice) + e = 0; + } + + using C = pmemobj_exp::array; + C c = {{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15}}; + C c2 = {{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15}}; +}; + +struct TestRanges { + template + void + run() + { + int ex1[] = {1, 1, 1, 1, 1}; + int ex2[] = {2, 2, 2, 2, 2}; + + auto slice = c.range(0, 7, snapshot_size); + auto cslice = static_cast(c).range(0, 7); + + UT_ASSERT(slice.begin() == cslice.begin()); + UT_ASSERT(slice.end() == cslice.end()); + + for (auto &e : slice) { + std::fill(e.data, e.data + 5, 1); + } + + for (auto &e : c.range(7, c.size() - 7)) { + std::fill(e.data, e.data + 5, 2); + } + + for (auto it = c.cbegin(); it < c.cbegin() + 7; it++) { + UT_ASSERT(std::equal(it->data, it->data + 5, ex1)); + } + + for (auto it = c.cbegin() + 7; it < c.cend(); it++) { + UT_ASSERT(std::equal(it->data, it->data + 5, ex2)); + } + + auto ptr_slice = c2.range(0, 5); + for (auto &e : ptr_slice) + std::fill(e.data, e.data + 5, 1); + + for (auto it = c2.cbegin(); it < c2.cbegin() + 5; it++) + UT_ASSERT(std::equal(it->data, it->data + 5, ex1)); + } + + struct DataStruct { + int data[5] = {1, 2, 3, 4, 5}; + }; + + using C = pmemobj_exp::array; + C c; + C c2; +}; + +struct TestAt { + void + run() + { + auto slice = c.range(0, c.size(), 1); + + slice[2] = 1; + slice.begin()[3] = 2; + + auto rit = slice.rbegin(); + *rit = 2.5; + + rit++; + *rit = 3; + + C excpected = {{0, 0, 1, 2, 3, 2.5}}; + UT_ASSERT(c == excpected); + } + + using C = pmemobj_exp::array; + C c = {{0, 0, 0, 0, 0, 0}}; +}; + +struct root { + pmem::obj::persistent_ptr ptr_s; + pmem::obj::persistent_ptr ptr_a; + pmem::obj::persistent_ptr ptr_r; + pmem::obj::persistent_ptr ptr_at; +}; + +void +run_test_success(pmem::obj::pool &pop) +{ + auto r = pop.root(); + + try { + pmem::obj::transaction::run(pop, [&] { + r->ptr_s = pmem::obj::make_persistent(); + }); + } catch (...) { + UT_ASSERT(0); + } + + try { + pmem::obj::transaction::run(pop, [&] { + r->ptr_s->run(); + r->ptr_s->run_reverse(); + + pmem::obj::delete_persistent(r->ptr_s); + }); + } catch (...) { + UT_ASSERT(0); + } +} + +void +run_test_abort(pmem::obj::pool &pop) +{ + auto r = pop.root(); + + try { + pmem::obj::transaction::run(pop, [&] { + r->ptr_a = pmem::obj::make_persistent(); + }); + } catch (...) { + UT_ASSERT(0); + } + + /* Run TestAbort expecting success */ + try { + pmem::obj::transaction::run(pop, [&] { + r->ptr_a->run(); + + pmem::obj::delete_persistent(r->ptr_a); + }); + } catch (...) { + UT_ASSERT(0); + } +} + +void +run_test_abort_with_revert(pmem::obj::pool &pop) +{ + auto r = pop.root(); + + try { + pmem::obj::transaction::run(pop, [&] { + r->ptr_a = pmem::obj::make_persistent(); + }); + } catch (...) { + UT_ASSERT(0); + } + + /* Run TestAbort expecting transaction abort */ + try { + pmem::obj::transaction::run(pop, [&] { + r->ptr_a->run(); + + pmem::obj::transaction::abort(0); + UT_ASSERT(0); + }); + } catch (pmem::manual_tx_abort &) { + if (Is_pmemcheck_enabled) { + TestAbort::C expected = {{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, + 11, 12, 13, 14, 15}}; + UT_ASSERT(r->ptr_a->c == expected); + } else { + /* Ensure that changes not added to the transaction were + * not reverted */ + TestAbort::C expected = {{1, 2, 3, 4, 5, 0, 0, 0, 9, 10, + 11, 12, 101, 14, 15}}; + UT_ASSERT(r->ptr_a->c == expected); + + /* Ensure that changes not added to the transaction were + * not reverted */ + TestAbort::C expected2 = {{0, 2, 3, 4, 5, 0, 7, 8, 9, + 10, 11, 12, 13, 14, 15}}; + UT_ASSERT(r->ptr_a->c2 == expected2); + } + } catch (...) { + UT_ASSERT(0); + } + + if (!Is_pmemcheck_enabled) { + /* Run TestAbort expecting transaction abort */ + try { + pmem::obj::transaction::run(pop, [&] { + r->ptr_a->run_zero(); + + pmem::obj::transaction::abort(0); + UT_ASSERT(0); + }); + } catch (pmem::manual_tx_abort &) { + /* Ensure that changes not added to the transaction were + * not reverted */ + TestAbort::C expected = { + {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}}; + UT_ASSERT(r->ptr_a->c == expected); + } catch (...) { + UT_ASSERT(0); + } + } + + try { + pmem::obj::transaction::run(pop, [&] { + pmem::obj::delete_persistent(r->ptr_a); + }); + } catch (...) { + UT_ASSERT(0); + } +} + +void +run_test_ranges(pmem::obj::pool &pop) +{ + auto r = pop.root(); + + try { + pmem::obj::transaction::run(pop, [&] { + r->ptr_r = pmem::obj::make_persistent(); + }); + } catch (...) { + UT_ASSERT(0); + } + + try { + pmem::obj::transaction::run(pop, [&] { + r->ptr_r->run<1>(); + + pmem::obj::delete_persistent(r->ptr_r); + }); + } catch (...) { + UT_ASSERT(0); + } + + try { + pmem::obj::transaction::run(pop, [&] { + r->ptr_r = pmem::obj::make_persistent(); + }); + } catch (...) { + UT_ASSERT(0); + } + + try { + pmem::obj::transaction::run(pop, [&] { + r->ptr_r->run< + std::numeric_limits::max()>(); + + pmem::obj::delete_persistent(r->ptr_r); + }); + } catch (...) { + UT_ASSERT(0); + } + + try { + pmem::obj::transaction::run(pop, [&] { + r->ptr_r = pmem::obj::make_persistent(); + }); + } catch (...) { + UT_ASSERT(0); + } + + try { + pmem::obj::transaction::run(pop, [&] { + r->ptr_r->run<999>(); + + pmem::obj::delete_persistent(r->ptr_r); + }); + } catch (...) { + UT_ASSERT(0); + } +} + +void +run_test_at(pmem::obj::pool &pop) +{ + auto r = pop.root(); + + try { + pmem::obj::transaction::run(pop, [&] { + r->ptr_at = pmem::obj::make_persistent(); + }); + } catch (...) { + UT_ASSERT(0); + } + + try { + pmem::obj::transaction::run(pop, [&] { + r->ptr_at->run(); + + pmem::obj::delete_persistent(r->ptr_at); + }); + } catch (...) { + UT_ASSERT(0); + } +} + +int +main(int argc, char *argv[]) +{ + START(); + + if (argc < 3) { + std::cerr << "usage: " << argv[0] << " file-name " + << "is-pmemcheck-enabled " << std::endl; + return 1; + } + + Is_pmemcheck_enabled = std::stoi(argv[2]); + + auto path = argv[1]; + auto pop = pmem::obj::pool::create( + path, "ArrayTest", PMEMOBJ_MIN_POOL, S_IWUSR | S_IRUSR); + + run_test_success(pop); + run_test_abort(pop); + run_test_abort_with_revert(pop); + run_test_ranges(pop); + run_test_at(pop); + + pop.close(); + + return 0; +} diff --git a/tests/array_slice/array_slice_0.cmake b/tests/array_slice/array_slice_0.cmake new file mode 100644 index 0000000..11ff614 --- /dev/null +++ b/tests/array_slice/array_slice_0.cmake @@ -0,0 +1,44 @@ +# +# Copyright 2018, Intel Corporation +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# +# * Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# +# * Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in +# the documentation and/or other materials provided with the +# distribution. +# +# * Neither the name of the copyright holder nor the names of its +# contributors may be used to endorse or promote products derived +# from this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +include(${SRC_DIR}/../helpers.cmake) + +setup() + +if(${TRACER} STREQUAL pmemcheck) + set(IS_PMEMCHECK "1") +else() + set(IS_PMEMCHECK "0") +endif() + +execute(${TEST_EXECUTABLE} ${DIR}/testfile "${IS_PMEMCHECK}") + +finish() diff --git a/tests/array_slice_pmreorder/array_slice_pmreorder.cpp b/tests/array_slice_pmreorder/array_slice_pmreorder.cpp new file mode 100644 index 0000000..5f03520 --- /dev/null +++ b/tests/array_slice_pmreorder/array_slice_pmreorder.cpp @@ -0,0 +1,162 @@ +/* + * Copyright 2018-2019, Intel Corporation + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * * Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +/* + * array_slice_pmreorder.cpp -- pmem::obj::experimental::array test under + * pmreorder + * + */ + +#include "unittest.hpp" + +#include +#include +#include +#include +#include +#include + +#include + +#define LAYOUT "pmreorder" + +namespace nvobj = pmem::obj; + +struct Data { + void + increase_elements() + { + auto slice = array.range(0, array.size()); + + for (auto &e : slice) { + e++; + } + } + + nvobj::experimental::array array = {{1, 2, 3, 4, 5}}; +}; + +struct root { + nvobj::persistent_ptr ptr; +}; + +void +init(nvobj::pool &pop) +{ + auto r = pop.root(); + + try { + nvobj::transaction::run( + pop, [&] { r->ptr = nvobj::make_persistent(); }); + } catch (...) { + UT_ASSERT(0); + } +} + +void +run_consistent(nvobj::pool &pop) +{ + auto r = pop.root(); + + try { + nvobj::transaction::run(pop, + [&] { r->ptr->increase_elements(); }); + } catch (...) { + UT_ASSERT(0); + } +} + +void +run_inconsistent(nvobj::pool &pop) +{ + auto r = pop.root(); + + r->ptr->increase_elements(); + r->ptr.persist(); +} + +void +check_consistency(nvobj::pool &pop) +{ + auto r = pop.root(); + + if (r->ptr->array[0] == 1) { + auto i = 1; + for (auto e : r->ptr->array) + UT_ASSERT(e == i++); + } else { + auto i = 2; + for (auto e : r->ptr->array) + UT_ASSERT(e == i++); + } +} + +int +main(int argc, char *argv[]) +{ + START(); + + if (argc != 3 || strchr("coxi", argv[1][0]) == nullptr) + UT_FATAL("usage: %s file-name", argv[0]); + + const char *path = argv[2]; + + nvobj::pool pop; + + try { + if (argv[1][0] == 'o') { + pop = nvobj::pool::open(path, LAYOUT); + + check_consistency(pop); + } else if (argv[1][0] == 'c') { + pop = nvobj::pool::create(path, LAYOUT, + PMEMOBJ_MIN_POOL * 20, + S_IWUSR | S_IRUSR); + + init(pop); + } else if (argv[1][0] == 'i') { + pop = nvobj::pool::open(path, LAYOUT); + + run_inconsistent(pop); + } else if (argv[1][0] == 'x') { + pop = nvobj::pool::open(path, LAYOUT); + + run_consistent(pop); + } + } catch (pmem::pool_error &pe) { + UT_FATAL("!pool::create: %s %s", pe.what(), path); + } + + pop.close(); + + return 0; +} diff --git a/tests/array_slice_pmreorder/array_slice_pmreorder_0.cmake b/tests/array_slice_pmreorder/array_slice_pmreorder_0.cmake new file mode 100644 index 0000000..167d034 --- /dev/null +++ b/tests/array_slice_pmreorder/array_slice_pmreorder_0.cmake @@ -0,0 +1,40 @@ +# +# Copyright 2018, Intel Corporation +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# +# * Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# +# * Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in +# the documentation and/or other materials provided with the +# distribution. +# +# * Neither the name of the copyright holder nor the names of its +# contributors may be used to endorse or promote products derived +# from this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +include(${SRC_DIR}/../helpers.cmake) + +setup() + +execute(${TEST_EXECUTABLE} c ${DIR}/testfile) +pmreorder_create_store_log(${DIR}/testfile ${TEST_EXECUTABLE} x ${DIR}/testfile) +pmreorder_execute(true ReorderAccumulative ${SRC_DIR}/pmreorder.conf ${TEST_EXECUTABLE} o) + +finish() diff --git a/tests/array_slice_pmreorder/array_slice_pmreorder_1.cmake b/tests/array_slice_pmreorder/array_slice_pmreorder_1.cmake new file mode 100644 index 0000000..141ca8b --- /dev/null +++ b/tests/array_slice_pmreorder/array_slice_pmreorder_1.cmake @@ -0,0 +1,40 @@ +# +# Copyright 2018, Intel Corporation +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# +# * Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# +# * Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in +# the documentation and/or other materials provided with the +# distribution. +# +# * Neither the name of the copyright holder nor the names of its +# contributors may be used to endorse or promote products derived +# from this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +include(${SRC_DIR}/../helpers.cmake) + +setup() + +execute(${TEST_EXECUTABLE} c ${DIR}/testfile) +pmreorder_create_store_log(${DIR}/testfile ${TEST_EXECUTABLE} i ${DIR}/testfile) +pmreorder_execute(false ReorderAccumulative ${SRC_DIR}/pmreorder.conf ${TEST_EXECUTABLE} o) + +finish() diff --git a/tests/array_slice_pmreorder/pmreorder.conf b/tests/array_slice_pmreorder/pmreorder.conf new file mode 100644 index 0000000..83c4b9a --- /dev/null +++ b/tests/array_slice_pmreorder/pmreorder.conf @@ -0,0 +1,3 @@ +{ + "libpmemobj_open" : "NoReorderNoCheck" +} diff --git a/tests/common/helper_classes.hpp b/tests/common/helper_classes.hpp new file mode 100644 index 0000000..978e984 --- /dev/null +++ b/tests/common/helper_classes.hpp @@ -0,0 +1,336 @@ +/* + * Copyright 2019, Intel Corporation + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * * Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +/** + * Helper classes that represent C++ concepts + */ + +#ifndef HELPER_CLASSES_HPP +#define HELPER_CLASSES_HPP + +#include "unittest.hpp" + +#include + +/** + * default_constructible_only - helper class + * Instance of that type can be only default constructed + */ + +class default_constructible_only { +public: + static int count; + + default_constructible_only() : _val(1) + { + ++count; + } + + ~default_constructible_only() + { + --count; + }; + + default_constructible_only(const default_constructible_only &) = delete; + + default_constructible_only & + operator=(const default_constructible_only &) = delete; + + bool + operator==(const default_constructible_only &other) const + { + return _val == other._val; + } + +private: + int _val; +}; + +int default_constructible_only::count = 0; + +/** + * copy_assignable_copy_insertable + * Instance of that type satisfies requirements of CopyAssignable and + * CopyInsertable concepts. + */ +template +struct copy_assignable_copy_insertable { + T value; + int copied = 0; + int copied_assigned = 0; + + /* emplace ctor is needed to create first object */ + copy_assignable_copy_insertable(const T &val) : value(val){}; + + copy_assignable_copy_insertable( + const copy_assignable_copy_insertable &other) + : value(other.value), copied(other.copied + 1){}; + + copy_assignable_copy_insertable & + operator=(const copy_assignable_copy_insertable &other) + { + copied = other.copied; + copied_assigned = other.copied_assigned + 1; + value = other.value; + return *this; + } +}; + +/** + * emplace_constructible - helper class + * Instance of that type can be constructed in uninitialized storage + */ +template +struct emplace_constructible { + T value; + + emplace_constructible(T val) : value(val) + { + } + + emplace_constructible(const emplace_constructible &) = delete; +}; + +/** + * emplace_constructible_and_move_insertable - helper class + * Satisfies requirements: + * - instance of that type can be constructed in uninitialized storage + * - rvalue of the type can be copied in uninitialized storage + */ +template +struct emplace_constructible_and_move_insertable { + T value; + int moved = 0; + + emplace_constructible_and_move_insertable(T val) : value(val) + { + } + + emplace_constructible_and_move_insertable( + emplace_constructible_and_move_insertable &&other) + : value(other.value), moved(other.moved + 1) + { + } + + /* Since move constructor is user-declared, copy constructor and copy + * assignment operator are not implicitly declared by compiler */ +}; + +/** + * emplace_constructible_copy_insertable_and_move_insertable - helper class + * Satisfies requirements: + * - instance of that type can be copy-constructed in uninitialized storage + * - rvalue of the type can be copied in uninitialized storage + */ +template +struct emplace_constructible_copy_insertable_move_insertable { + T value; + int copied = 0; + int moved = 0; + + emplace_constructible_copy_insertable_move_insertable(T val) + : value(val) + { + } + + emplace_constructible_copy_insertable_move_insertable( + const emplace_constructible_copy_insertable_move_insertable + &other) + : value(other.value), copied(other.copied + 1) + { + } + + emplace_constructible_copy_insertable_move_insertable( + emplace_constructible_copy_insertable_move_insertable &&other) + : value(other.value), moved(other.moved + 1) + { + } +}; + +/** + * emplace_constructible_moveable_and_assignable - helper class + * Satisfies requirements: + * - instance of that type can be constructed in uninitialized storage + * - instance of the type can be constructed from an rvalue argument + * - instance of the type can be copy-assigned from an lvalue expression + */ +template +struct emplace_constructible_moveable_and_assignable { + T value; + int moved = 0; + int assigned = 0; + + emplace_constructible_moveable_and_assignable(T val) : value(val) + { + } + + emplace_constructible_moveable_and_assignable( + emplace_constructible_moveable_and_assignable &&other) + : value(std::move(other.value)), moved(other.moved + 1) + { + } + + emplace_constructible_moveable_and_assignable & + operator=(emplace_constructible_moveable_and_assignable &&other) + { + moved = other.moved; + assigned = other.assigned + 1; + value = std::move(other.value); + return *this; + } + + emplace_constructible_moveable_and_assignable & + operator=(T val) + { + value = std::move(val); + ++assigned; + return *this; + } +}; + +/** + * failing_reference_operator - helper structure + * Instance of that type cannot use reference operator + */ +struct failing_reference_operator { + failing_reference_operator() : val(0) + { + } + + failing_reference_operator(int i) : val(i) + { + } + + ~failing_reference_operator() + { + } + + failing_reference_operator *operator&() const + { + UT_ASSERT(0); + return nullptr; + } + + int val; +}; + +/** + * move_only - helper class + * Instance of that type can be constructed from an rvalue argument only + */ +struct move_only { + int value; + + move_only(int val = 1) : value(val) + { + } + + move_only(const move_only &) = delete; + + move_only &operator=(const move_only &) = delete; + + move_only & + operator=(move_only &&other) + { + value = other.value; + other.value = 0; + return *this; + } + + move_only(move_only &&other) : value(other.value) + { + other.value = 0; + } + + bool + operator==(const move_only &other) const + { + return value == other.value; + } +}; + +/** + * move_assignable - helper class + * Instance of that type satisfies MoveAssignable concept requirements. + */ +struct move_assignable { + int value; + + /* emplace ctor is needed to create first object */ + move_assignable(int val = 0) : value(val) + { + } + + move_assignable & + operator=(move_assignable &&other) + { + value = other.value; + other.value = 0; + return *this; + } +}; + +/** + * copy_insertable - helper class + * Instance of that type satisfies CopyInsertable concept requirements. + */ +struct copy_insertable { + int value; + + /* emplace ctor is needed to create first object */ + copy_insertable(int val) : value(val) + { + } + + copy_insertable(const copy_insertable &other) : value(other.value) + { + } +}; + +/** + * move_insertable - helper class + * Instance of that type satisfies MoveInsertable concept requirements. + */ +struct move_insertable { + int value; + + /* emplace ctor is needed to create first object */ + move_insertable(int val) : value(val) + { + } + + move_insertable(const copy_insertable &&other) : value(other.value) + { + } +}; + +#endif /* HELPER_CLASSES_HPP */ diff --git a/tests/common/iterators_support.hpp b/tests/common/iterators_support.hpp new file mode 100644 index 0000000..883a372 --- /dev/null +++ b/tests/common/iterators_support.hpp @@ -0,0 +1,506 @@ +/* + * Copyright 2018-2019, Intel Corporation + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * * Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +/** + * Canonical implementations of standard category iterators. + */ + +#ifndef ITERATORS_COMMON_HPP +#define ITERATORS_COMMON_HPP + +#include + +namespace test_support +{ + +/** + * Canonical implementation of OutputIterator. Satisfy requirements: + * - copy-constructible + * - copy-assignable + * - destructible + * - can be incremented + * - can be dereferenced as an lvalue + */ +template +class output_it { +public: + using iterator_category = std::output_iterator_tag; + using value_type = typename std::iterator_traits::value_type; + using difference_type = + typename std::iterator_traits::difference_type; + using pointer = typename std::iterator_traits::pointer; + using reference = typename std::iterator_traits::reference; + + output_it() = delete; + + explicit output_it(It it) : _it(it) + { + } + + output_it(const output_it &t) : _it(t._it) + { + } + + reference operator*() const + { + return *_it; + } + + output_it & + operator++() + { + ++_it; + return *this; + } + + output_it + operator++(int) + { + output_it tmp(*this); + ++(*this); + return tmp; + } + +private: + It _it; +}; + +/** + * Canonical implementation of InputIterator. Satisfy requirements: + * - copy-constructible + * - copy-assignable + * - destructible + * - can be incremented + * - can be dereferenced as an rvalue + * - supports equality/inequality comparisons + */ +template +class input_it { +public: + using iterator_category = std::input_iterator_tag; + using value_type = typename std::iterator_traits::value_type; + using difference_type = + typename std::iterator_traits::difference_type; + using pointer = typename std::iterator_traits::pointer; + using reference = typename std::iterator_traits::reference; + + input_it() = delete; + + explicit input_it(It it) : _it(it) + { + } + + input_it(const input_it &t) : _it(t._it) + { + } + + reference operator*() const + { + return *_it; + } + + const pointer operator->() const + { + return _it; + } + + input_it & + operator++() + { + ++_it; + return *this; + } + + input_it + operator++(int) + { + input_it tmp(*this); + ++(*this); + return tmp; + } + + friend bool + operator==(const input_it &x, const input_it &y) + { + return x._it == y._it; + } + + friend bool + operator!=(const input_it &x, const input_it &y) + { + return !(x == y); + } + +private: + It _it; +}; + +/** + * Canonical implementation of ForwardIterator. Satisfy requirements: + * - copy-constructible + * - copy-assignable + * - default-constructible + * - destructible + * - can be incremented + * - can be dereferenced as an rvalue + * - can be dereferenced as an lvalue + * - supports equality/inequality comparisons + * - multi-pass: neither dereferencing nor incrementing affects + * dereferenceability + */ +template +class forward_it { +public: + using iterator_category = std::forward_iterator_tag; + using value_type = typename std::iterator_traits::value_type; + using difference_type = + typename std::iterator_traits::difference_type; + using pointer = typename std::iterator_traits::pointer; + using reference = typename std::iterator_traits::reference; + + forward_it() : _it() + { + } + + explicit forward_it(It it) : _it(it) + { + } + + forward_it(const forward_it &t) : _it(t._it) + { + } + + reference operator*() const + { + return *_it; + } + + pointer operator->() const + { + return _it; + } + + forward_it & + operator++() + { + ++_it; + return *this; + } + + forward_it + operator++(int) + { + forward_it tmp(*this); + ++(*this); + return tmp; + } + + friend bool + operator==(const forward_it &x, const forward_it &y) + { + return x._it == y._it; + } + + friend bool + operator!=(const forward_it &x, const forward_it &y) + { + return !(x == y); + } + +private: + It _it; +}; + +/** + * Canonical implementation of BidirectionalIterator. Satisfy requirements: + * - copy-constructible + * - copy-assignable + * - default-constructible + * - destructible + * - can be incremented + * - can be decremented + * - can be dereferenced as an rvalue + * - can be dereferenced as an lvalue + * - supports equality/inequality comparisons + * - multi-pass: neither dereferencing nor incrementing affects + * dereferenceability + */ +template +class bidirectional_it { +public: + using iterator_category = std::bidirectional_iterator_tag; + using value_type = typename std::iterator_traits::value_type; + using difference_type = + typename std::iterator_traits::difference_type; + using pointer = typename std::iterator_traits::pointer; + using reference = typename std::iterator_traits::reference; + + bidirectional_it() : _it() + { + } + + explicit bidirectional_it(It it) : _it(it) + { + } + + bidirectional_it(const bidirectional_it &t) : _it(t._it) + { + } + + reference operator*() const + { + return *_it; + } + + pointer operator->() const + { + return _it; + } + + bidirectional_it & + operator++() + { + ++_it; + return *this; + } + + bidirectional_it + operator++(int) + { + bidirectional_it tmp(*this); + ++(*this); + return tmp; + } + + bidirectional_it & + operator--() + { + --_it; + return *this; + } + + bidirectional_it + operator--(int) + { + bidirectional_it tmp(*this); + --(*this); + return tmp; + } + + friend bool + operator==(const bidirectional_it &x, const bidirectional_it &y) + { + return x._it == y._it; + } + + friend bool + operator!=(const bidirectional_it &x, const bidirectional_it &y) + { + return !(x == y); + } + +private: + It _it; +}; + +/** + * Canonical implementation of RandomAccessIterator. Satisfy requirements: + * - copy-constructible + * - copy-assignable + * - default-constructible + * - destructible + * - can be incremented + * - can be decremented + * - supports arithmetic operators + and - between iterator and integer value + * - supports subtracting between iterators + * - supports inequality comparisons (<, >, <= and >=) between iterators + * - supports compound assignment operations += and -= + * - supports offset dereference operator ([]) + * - can be dereferenced as an rvalue + * - can be dereferenced as an lvalue + * - supports equality/inequality comparisons + * - multi-pass: neither dereferencing nor incrementing affects + * dereferenceability + */ +template +class random_access_it { +public: + using iterator_category = std::random_access_iterator_tag; + using value_type = typename std::iterator_traits::value_type; + using difference_type = + typename std::iterator_traits::difference_type; + using pointer = typename std::iterator_traits::pointer; + using reference = typename std::iterator_traits::reference; + + random_access_it() : _it() + { + } + + explicit random_access_it(It it) : _it(it) + { + } + + random_access_it(const random_access_it &t) : _it(t._it) + { + } + + reference operator*() const + { + return *_it; + } + + pointer operator->() const + { + return _it; + } + + random_access_it & + operator++() + { + ++_it; + return *this; + } + + random_access_it + operator++(int) + { + random_access_it tmp(*this); + ++(*this); + return tmp; + } + + random_access_it & + operator--() + { + --_it; + return *this; + } + + random_access_it + operator--(int) + { + random_access_it tmp(*this); + --(*this); + return tmp; + } + + random_access_it & + operator+=(difference_type n) + { + _it += n; + return *this; + } + + random_access_it + operator+(difference_type n) const + { + random_access_it tmp(*this); + tmp += n; + return tmp; + } + + friend random_access_it + operator+(difference_type n, random_access_it x) + { + x += n; + return x; + } + + random_access_it & + operator-=(difference_type n) + { + return *this += -n; + } + + random_access_it + operator-(difference_type n) const + { + random_access_it tmp(*this); + tmp -= n; + return tmp; + } + + difference_type + operator-(random_access_it x) const + { + difference_type n = this->_it - x._it; + return n; + } + + reference operator[](difference_type n) const + { + return _it[n]; + } + + friend bool + operator==(const random_access_it &x, const random_access_it &y) + { + return x._it == y._it; + } + + friend bool + operator!=(const random_access_it &x, const random_access_it &y) + { + return !(x == y); + } + + friend bool + operator<(const random_access_it &x, const random_access_it &y) + { + return x._it() < y._it(); + } + + friend bool + operator<=(const random_access_it &x, const random_access_it &y) + { + return !(y < x); + } + + friend bool + operator>(const random_access_it &x, const random_access_it &y) + { + return y < x; + } + + friend bool + operator>=(const random_access_it &x, const random_access_it &y) + { + return !(x < y); + } + +private: + It _it; +}; + +} /* namespace test_common */ + +#endif /* ITERATORS_COMMON_HPP */ diff --git a/tests/common/pthread_common.hpp b/tests/common/pthread_common.hpp new file mode 100644 index 0000000..89a7a49 --- /dev/null +++ b/tests/common/pthread_common.hpp @@ -0,0 +1,53 @@ +/* + * Copyright 2018, Intel Corporation + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * * Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#ifndef PTHREAD_COMMON_HPP +#define PTHREAD_COMMON_HPP + +#include "unittest.hpp" +#include + +void +ut_pthread_create(pthread_t *thread, const pthread_attr_t *attr, + void *(*start_routine)(void *), void *arg) +{ + if (pthread_create(thread, attr, start_routine, arg) != 0) + UT_FATAL("pthread_create failed"); +} + +void +ut_pthread_join(pthread_t *thread, void **value) +{ + if (pthread_join(*thread, value) != 0) + UT_FATAL("pthread_join failed"); +} + +#endif /* PTHREAD_COMMON_HPP */ diff --git a/tests/common/unittest.hpp b/tests/common/unittest.hpp new file mode 100644 index 0000000..8fbf036 --- /dev/null +++ b/tests/common/unittest.hpp @@ -0,0 +1,163 @@ +/* + * Copyright 2018-2019, Intel Corporation + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * * Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef LIBPMEMOBJ_CPP_UNITTEST_HPP +#define LIBPMEMOBJ_CPP_UNITTEST_HPP + +#include "../test_backtrace.h" +#include "../valgrind_internal.hpp" +#include "iterators_support.hpp" +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define START() \ + do { \ + test_register_sighandlers(); \ + set_valgrind_internals(); \ + } while (0) + +#ifndef _WIN32 +#define os_stat_t struct stat +#define os_stat stat +#else +#define os_stat_t struct _stat64 +#define os_stat _stat64 +#endif + +static inline void +UT_OUT(const char *format, ...) +{ + va_list args_list; + va_start(args_list, format); + std::vfprintf(stdout, format, args_list); + va_end(args_list); + + fprintf(stdout, "\n"); +} + +static inline void +UT_EXCEPTION(std::exception &e) +{ + std::cerr << e.what() << std::endl; +} + +static inline void +UT_FATAL(const char *format, ...) +{ + va_list args_list; + va_start(args_list, format); + std::vfprintf(stderr, format, args_list); + va_end(args_list); + + fprintf(stderr, "\n"); + + abort(); +} + +#ifdef _WIN32 +#include "unittest_windows.hpp" +#endif + +/* + * ut_stat -- stat that never returns -1 + */ +int +ut_stat(const char *file, int line, const char *func, const char *path, + os_stat_t *st) +{ + int ret = os_stat(path, st); + + if (ret < 0) + UT_FATAL("%s:%d %s - !stat: %s", file, line, func, path); + +#ifdef _WIN32 + /* clear unused bits to avoid confusion */ + st->st_mode &= 0600; +#endif + + return ret; +} + +#define STAT(path, st) ut_stat(__FILE__, __LINE__, __func__, path, st) + +/* assert a condition is true at runtime */ +#define UT_ASSERT(cnd) \ + ((void)((cnd) || \ + (UT_FATAL("%s:%d %s - assertion failure: %s", __FILE__, \ + __LINE__, __func__, #cnd), \ + 0))) + +/* assertion with exception related string printed */ +#define UT_FATALexc(exception) \ + ((void)(UT_EXCEPTION(exception), \ + (UT_FATAL("%s:%d %s - assertion failure", __FILE__, __LINE__, \ + __func__), \ + 0))) + +/* assertion with extra info printed if assertion fails at runtime */ +#define UT_ASSERTinfo(cnd, info) \ + ((void)((cnd) || \ + (UT_FATAL("%s:%d %s - assertion failure: %s (%s = %s)", \ + __FILE__, __LINE__, __func__, #cnd, #info, info), \ + 0))) + +/* assert two integer values are equal at runtime */ +#define UT_ASSERTeq(lhs, rhs) \ + ((void)(((lhs) == (rhs)) || \ + (UT_FATAL("%s:%d %s - assertion failure: %s (0x%llx) == %s " \ + "(0x%llx)", \ + __FILE__, __LINE__, __func__, #lhs, \ + (unsigned long long)(lhs), #rhs, \ + (unsigned long long)(rhs)), \ + 0))) + +/* assert two integer values are not equal at runtime */ +#define UT_ASSERTne(lhs, rhs) \ + ((void)(((lhs) != (rhs)) || \ + (UT_FATAL("%s:%d %s - assertion failure: %s (0x%llx) != %s " \ + "(0x%llx)", \ + __FILE__, __LINE__, __func__, #lhs, \ + (unsigned long long)(lhs), #rhs, \ + (unsigned long long)(rhs)), \ + 0))) + +#define UT_ASSERT_NOEXCEPT(...) \ + static_assert(noexcept(__VA_ARGS__), "Operation must be noexcept") + +#endif /* LIBPMEMOBJ_CPP_UNITTEST_HPP */ diff --git a/tests/common/unittest_windows.hpp b/tests/common/unittest_windows.hpp new file mode 100644 index 0000000..c29152f --- /dev/null +++ b/tests/common/unittest_windows.hpp @@ -0,0 +1,85 @@ +/* + * Copyright 2018, Intel Corporation + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * * Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef UNITTEST_WINDOWS_HPP +#define UNITTEST_WINDOWS_HPP + +#include + +#define S_IRUSR S_IREAD +#define S_IWUSR S_IWRITE +#define S_IRGRP S_IRUSR +#define S_IWGRP S_IWUSR + +/* + * ut_toUTF8 -- convert WCS to UTF-8 string + */ +char * +ut_toUTF8(const wchar_t *wstr) +{ + int size = WideCharToMultiByte(CP_UTF8, WC_ERR_INVALID_CHARS, wstr, -1, + nullptr, 0, nullptr, nullptr); + if (size == 0) { + UT_FATAL("!ut_toUTF8"); + } + + char *str = new char[size]; + + if (WideCharToMultiByte(CP_UTF8, WC_ERR_INVALID_CHARS, wstr, -1, str, + size, nullptr, nullptr) == 0) { + UT_FATAL("!ut_toUTF8"); + } + + return str; +} + +/* + * ut_statw -- statw that never returns -1 + */ +int +ut_statw(const char *file, int line, const char *func, const wchar_t *path, + os_stat_t *st) +{ + int ret = _wstat64(path, st); + + if (ret < 0) + UT_FATAL("%s:%d %s - !stat: %S", file, line, func, path); + + /* clear unused bits to avoid confusion */ + st->st_mode &= 0600; + + return ret; +} + +#define STATW(path, st) ut_statw(__FILE__, __LINE__, __func__, path, st) + +#endif /* UNITTEST_WINDOWS_HPP */ diff --git a/tests/cond_var/cond_var.cpp b/tests/cond_var/cond_var.cpp new file mode 100644 index 0000000..fbfecd9 --- /dev/null +++ b/tests/cond_var/cond_var.cpp @@ -0,0 +1,463 @@ +/* + * Copyright 2016-2018, Intel Corporation + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * * Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +/* + * obj_cpp_cond_var.cpp -- cpp condition variable test + */ + +#include "unittest.hpp" + +#include +#include +#include + +#include +#include +#include +#include + +#define LAYOUT "cpp" + +namespace nvobj = pmem::obj; + +namespace +{ + +/* + * Due to premature wake-ups with the TIMEDOUT status on the Windows platform, + * an "epsilon" tolerance has been introduced where appropriate. + */ + +/* convenience typedef */ +typedef std::function)> reader_type; + +/* pool root structure */ +struct root { + nvobj::mutex pmutex; + nvobj::condition_variable cond; + unsigned counter; +}; + +/* the number of threads */ +const unsigned num_threads = 30; + +/* notification limit */ +const unsigned limit = 7000; + +/* cond wait time in milliseconds */ +const std::chrono::milliseconds wait_time(150); + +/* + * Premature wake-up tolerance. + * XXX Windows - this needs to be investigated, it shouldn't timeout this long + * before the actual timeout. + */ +const auto epsilon = std::chrono::milliseconds(16); + +/* + * write_notify -- (internal) bump up the counter up to a limit and notify + */ +void +write_notify(nvobj::persistent_ptr proot, bool notify, bool all) +{ + std::lock_guard lock(proot->pmutex); + + while (proot->counter < limit) + proot->counter++; + + if (!notify) + return; + + if (all) + proot->cond.notify_all(); + else + proot->cond.notify_one(); +} + +/* + * reader_mutex -- (internal) verify the counter value + */ +void +reader_mutex(nvobj::persistent_ptr proot) +{ + proot->pmutex.lock(); + while (proot->counter != limit) + proot->cond.wait(proot->pmutex); + + UT_ASSERTeq(proot->counter, limit); + proot->pmutex.unlock(); +} + +/* + * reader_mutex_pred -- (internal) verify the counter value + */ +void +reader_mutex_pred(nvobj::persistent_ptr proot) +{ + proot->pmutex.lock(); + proot->cond.wait(proot->pmutex, + [&]() { return proot->counter == limit; }); + + UT_ASSERTeq(proot->counter, limit); + proot->pmutex.unlock(); +} + +/* + * reader_lock -- (internal) verify the counter value + */ +void +reader_lock(nvobj::persistent_ptr proot) +{ + std::unique_lock lock(proot->pmutex); + while (proot->counter != limit) + proot->cond.wait(lock); + + UT_ASSERTeq(proot->counter, limit); + lock.unlock(); +} + +/* + * reader_lock_pred -- (internal) verify the counter value + */ +void +reader_lock_pred(nvobj::persistent_ptr proot) +{ + std::unique_lock lock(proot->pmutex); + proot->cond.wait(lock, [&]() { return proot->counter == limit; }); + + UT_ASSERTeq(proot->counter, limit); + lock.unlock(); +} + +/* + * reader_mutex_until -- (internal) verify the counter value or timeout + */ +void +reader_mutex_until(nvobj::persistent_ptr proot) +{ + proot->pmutex.lock(); + auto until = std::chrono::system_clock::now(); + until += wait_time; + auto ret = proot->cond.wait_until(proot->pmutex, until); + + auto now = std::chrono::system_clock::now(); + if (ret == std::cv_status::timeout) { + auto diff = + std::chrono::duration_cast( + until - now); + if (now < until) + UT_ASSERT(diff < epsilon); + } else { + UT_ASSERTeq(proot->counter, limit); + } + proot->pmutex.unlock(); +} + +/* + * reader_mutex_until_pred -- (internal) verify the counter value or timeout + */ +void +reader_mutex_until_pred(nvobj::persistent_ptr proot) +{ + proot->pmutex.lock(); + auto until = std::chrono::system_clock::now(); + until += wait_time; + auto ret = proot->cond.wait_until(proot->pmutex, until, [&]() { + return proot->counter == limit; + }); + + auto now = std::chrono::system_clock::now(); + if (ret == false) { + auto diff = + std::chrono::duration_cast( + until - now); + if (now < until) + UT_ASSERT(diff < epsilon); + } else { + UT_ASSERTeq(proot->counter, limit); + } + proot->pmutex.unlock(); +} + +/* + * reader_lock_until -- (internal) verify the counter value or timeout + */ +void +reader_lock_until(nvobj::persistent_ptr proot) +{ + std::unique_lock lock(proot->pmutex); + auto until = std::chrono::system_clock::now(); + until += wait_time; + auto ret = proot->cond.wait_until(lock, until); + + auto now = std::chrono::system_clock::now(); + if (ret == std::cv_status::timeout) { + auto diff = + std::chrono::duration_cast( + until - now); + if (now < until) + UT_ASSERT(diff < epsilon); + } else { + UT_ASSERTeq(proot->counter, limit); + } + lock.unlock(); +} + +/* + * reader_lock_until_pred -- (internal) verify the counter value or timeout + */ +void +reader_lock_until_pred(nvobj::persistent_ptr proot) +{ + std::unique_lock lock(proot->pmutex); + auto until = std::chrono::system_clock::now(); + until += wait_time; + auto ret = proot->cond.wait_until( + lock, until, [&]() { return proot->counter == limit; }); + + auto now = std::chrono::system_clock::now(); + if (ret == false) { + auto diff = + std::chrono::duration_cast( + until - now); + if (now < until) + UT_ASSERT(diff < epsilon); + } else { + UT_ASSERTeq(proot->counter, limit); + } + lock.unlock(); +} + +/* + * reader_mutex_for -- (internal) verify the counter value or timeout + */ +void +reader_mutex_for(nvobj::persistent_ptr proot) +{ + proot->pmutex.lock(); + auto until = std::chrono::system_clock::now(); + until += wait_time; + auto ret = proot->cond.wait_for(proot->pmutex, wait_time); + + auto now = std::chrono::system_clock::now(); + if (ret == std::cv_status::timeout) { + auto diff = + std::chrono::duration_cast( + until - now); + if (now < until) + UT_ASSERT(diff < epsilon); + } else { + UT_ASSERTeq(proot->counter, limit); + } + proot->pmutex.unlock(); +} + +/* + * reader_mutex_for_pred -- (internal) verify the counter value or timeout + */ +void +reader_mutex_for_pred(nvobj::persistent_ptr proot) +{ + proot->pmutex.lock(); + auto until = std::chrono::system_clock::now(); + until += wait_time; + auto ret = proot->cond.wait_for(proot->pmutex, wait_time, [&]() { + return proot->counter == limit; + }); + + auto now = std::chrono::system_clock::now(); + if (ret == false) { + auto diff = + std::chrono::duration_cast( + until - now); + if (now < until) + UT_ASSERT(diff < epsilon); + } else { + UT_ASSERTeq(proot->counter, limit); + } + proot->pmutex.unlock(); +} + +/* + * reader_lock_for -- (internal) verify the counter value or timeout + */ +void +reader_lock_for(nvobj::persistent_ptr proot) +{ + std::unique_lock lock(proot->pmutex); + auto until = std::chrono::system_clock::now(); + until += wait_time; + auto ret = proot->cond.wait_for(lock, wait_time); + + auto now = std::chrono::system_clock::now(); + if (ret == std::cv_status::timeout) { + auto diff = + std::chrono::duration_cast( + until - now); + if (now < until) + UT_ASSERT(diff < epsilon); + } else { + UT_ASSERTeq(proot->counter, limit); + } + lock.unlock(); +} + +/* + * reader_lock_for_pred -- (internal) verify the counter value or timeout + */ +void +reader_lock_for_pred(nvobj::persistent_ptr proot) +{ + std::unique_lock lock(proot->pmutex); + auto until = std::chrono::system_clock::now(); + until += wait_time; + auto ret = proot->cond.wait_for( + lock, wait_time, [&]() { return proot->counter == limit; }); + + auto now = std::chrono::system_clock::now(); + if (ret == false) { + auto diff = + std::chrono::duration_cast( + until - now); + if (now < until) + UT_ASSERT(diff < epsilon); + } else { + UT_ASSERTeq(proot->counter, limit); + } + lock.unlock(); +} + +/* + * cond_zero_test -- (internal) test the zeroing constructor + */ +void +cond_zero_test(nvobj::pool &pop) +{ + PMEMoid raw_cnd; + + pmemobj_alloc(pop.handle(), &raw_cnd, sizeof(PMEMcond), 1, + [](PMEMobjpool *pop, void *ptr, void *) -> int { + PMEMcond *mtx = static_cast(ptr); + pmemobj_memset_persist(pop, mtx, 1, sizeof(*mtx)); + return 0; + }, + nullptr); + + nvobj::condition_variable *placed_mtx = + new (pmemobj_direct(raw_cnd)) nvobj::condition_variable; + std::unique_lock lock(pop.root()->pmutex); + placed_mtx->wait_for(lock, wait_time, []() { return false; }); +} + +/* + * mutex_test -- (internal) launch worker threads to test the pshared_mutex + */ +template +void +mutex_test(nvobj::pool &pop, bool notify, bool notify_all, + const Reader &writer, const Writer &reader) +{ + const auto total_threads = num_threads * 2u; + std::thread threads[total_threads]; + + nvobj::persistent_ptr proot = pop.root(); + + for (unsigned i = 0; i < total_threads; i += 2) { + threads[i] = std::thread(reader, proot); + threads[i + 1] = std::thread(writer, proot, notify, notify_all); + } + + for (unsigned i = 0; i < total_threads; ++i) + threads[i].join(); +} +} + +int +main(int argc, char *argv[]) +{ + START(); + + if (argc != 2) + UT_FATAL("usage: %s file-name", argv[0]); + + const char *path = argv[1]; + + nvobj::pool pop; + + try { + pop = nvobj::pool::create( + path, LAYOUT, PMEMOBJ_MIN_POOL, S_IWUSR | S_IRUSR); + } catch (pmem::pool_error &pe) { + UT_FATAL("!pool::create: %s %s", pe.what(), path); + } + + cond_zero_test(pop); + + std::vector notify_functions( + {reader_mutex, reader_mutex_pred, reader_lock, reader_lock_pred, + reader_mutex_until, reader_mutex_until_pred, reader_lock_until, + reader_lock_until_pred, reader_mutex_for, + reader_mutex_for_pred, reader_lock_for, reader_lock_for_pred}); + + for (auto func : notify_functions) { + unsigned reset_value = 42; + + mutex_test(pop, true, false, write_notify, func); + pop.root()->counter = reset_value; + + mutex_test(pop, true, true, write_notify, func); + pop.root()->counter = reset_value; + } + + std::vector not_notify_functions( + {reader_mutex_until, reader_mutex_until_pred, reader_lock_until, + reader_lock_until_pred, reader_mutex_for, + reader_mutex_for_pred, reader_lock_for, reader_lock_for_pred}); + + for (auto func : not_notify_functions) { + unsigned reset_value = 42; + + mutex_test(pop, false, false, write_notify, func); + pop.root()->counter = reset_value; + + mutex_test(pop, false, true, write_notify, func); + pop.root()->counter = reset_value; + } + + /* pmemcheck related persist */ + pmemobj_persist(pop.handle(), &(pop.root()->counter), + sizeof(pop.root()->counter)); + + pop.close(); + + return 0; +} diff --git a/tests/cond_var_posix/cond_var_posix.cpp b/tests/cond_var_posix/cond_var_posix.cpp new file mode 100644 index 0000000..7ade3d7 --- /dev/null +++ b/tests/cond_var_posix/cond_var_posix.cpp @@ -0,0 +1,517 @@ +/* + * Copyright 2016-2018, Intel Corporation + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * * Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +/* + * obj_cpp_cond_var_posix.c -- cpp condition variable test + */ + +#include "pthread_common.hpp" +#include "unittest.hpp" + +#include +#include +#include + +#include +#include + +#define LAYOUT "cpp" + +namespace nvobj = pmem::obj; + +namespace +{ + +/* convenience typedef */ +typedef void *(*reader_type)(void *); + +/* pool root structure */ +struct root { + nvobj::mutex pmutex; + nvobj::condition_variable cond; + unsigned counter; +}; + +/* the number of threads */ +const unsigned num_threads = 30; + +/* notification limit */ +const unsigned limit = 7000; + +/* cond wait time in milliseconds */ +const std::chrono::milliseconds wait_time(150); + +/* arguments for write worker */ +struct writer_args { + nvobj::persistent_ptr proot; + bool notify; + bool all; +}; + +/* + * write_notify -- (internal) bump up the counter up to a limit and notify + */ +void * +write_notify(void *args) +{ + struct writer_args *wargs = static_cast(args); + + std::lock_guard lock(wargs->proot->pmutex); + + while (wargs->proot->counter < limit) + wargs->proot->counter++; + + if (wargs->notify) { + if (wargs->all) + wargs->proot->cond.notify_all(); + else + wargs->proot->cond.notify_one(); + } + + return nullptr; +} + +/* + * reader_mutex -- (internal) verify the counter value + */ +void * +reader_mutex(void *arg) +{ + nvobj::persistent_ptr *proot = + static_cast *>(arg); + (*proot)->pmutex.lock(); + while ((*proot)->counter != limit) + (*proot)->cond.wait((*proot)->pmutex); + + UT_ASSERTeq((*proot)->counter, limit); + (*proot)->pmutex.unlock(); + + return nullptr; +} + +/* + * reader_mutex_pred -- (internal) verify the counter value + */ +void * +reader_mutex_pred(void *arg) +{ + nvobj::persistent_ptr *proot = + static_cast *>(arg); + (*proot)->pmutex.lock(); + (*proot)->cond.wait((*proot)->pmutex, + [&]() { return (*proot)->counter == limit; }); + + UT_ASSERTeq((*proot)->counter, limit); + (*proot)->pmutex.unlock(); + + return nullptr; +} + +/* + * reader_lock -- (internal) verify the counter value + */ +void * +reader_lock(void *arg) +{ + nvobj::persistent_ptr *proot = + static_cast *>(arg); + std::unique_lock lock((*proot)->pmutex); + while ((*proot)->counter != limit) + (*proot)->cond.wait(lock); + + UT_ASSERTeq((*proot)->counter, limit); + lock.unlock(); + + return nullptr; +} + +/* + * reader_lock_pred -- (internal) verify the counter value + */ +void * +reader_lock_pred(void *arg) +{ + nvobj::persistent_ptr *proot = + static_cast *>(arg); + std::unique_lock lock((*proot)->pmutex); + (*proot)->cond.wait(lock, [&]() { return (*proot)->counter == limit; }); + + UT_ASSERTeq((*proot)->counter, limit); + lock.unlock(); + + return nullptr; +} + +/* + * reader_mutex_until -- (internal) verify the counter value or timeout + */ +void * +reader_mutex_until(void *arg) +{ + nvobj::persistent_ptr *proot = + static_cast *>(arg); + (*proot)->pmutex.lock(); + auto until = std::chrono::system_clock::now(); + until += wait_time; + auto ret = (*proot)->cond.wait_until((*proot)->pmutex, until); + + auto now = std::chrono::system_clock::now(); + if (ret == std::cv_status::timeout) { + auto epsilon = std::chrono::milliseconds(10); + auto diff = + std::chrono::duration_cast( + until - now); + if (now < until) + UT_ASSERT(diff < epsilon); + } else { + UT_ASSERTeq((*proot)->counter, limit); + } + (*proot)->pmutex.unlock(); + + return nullptr; +} + +/* + * reader_mutex_until_pred -- (internal) verify the counter value or timeout + */ +void * +reader_mutex_until_pred(void *arg) +{ + nvobj::persistent_ptr *proot = + static_cast *>(arg); + (*proot)->pmutex.lock(); + auto until = std::chrono::system_clock::now(); + until += wait_time; + auto ret = (*proot)->cond.wait_until((*proot)->pmutex, until, [&]() { + return (*proot)->counter == limit; + }); + + auto now = std::chrono::system_clock::now(); + if (ret == false) { + auto epsilon = std::chrono::milliseconds(10); + auto diff = + std::chrono::duration_cast( + until - now); + if (now < until) + UT_ASSERT(diff < epsilon); + } else { + UT_ASSERTeq((*proot)->counter, limit); + } + (*proot)->pmutex.unlock(); + + return nullptr; +} + +/* + * reader_lock_until -- (internal) verify the counter value or timeout + */ +void * +reader_lock_until(void *arg) +{ + nvobj::persistent_ptr *proot = + static_cast *>(arg); + std::unique_lock lock((*proot)->pmutex); + auto until = std::chrono::system_clock::now(); + until += wait_time; + auto ret = (*proot)->cond.wait_until(lock, until); + + auto now = std::chrono::system_clock::now(); + if (ret == std::cv_status::timeout) { + auto epsilon = std::chrono::milliseconds(10); + auto diff = + std::chrono::duration_cast( + until - now); + if (now < until) + UT_ASSERT(diff < epsilon); + } else { + UT_ASSERTeq((*proot)->counter, limit); + } + lock.unlock(); + + return nullptr; +} + +/* + * reader_lock_until_pred -- (internal) verify the counter value or timeout + */ +void * +reader_lock_until_pred(void *arg) +{ + nvobj::persistent_ptr *proot = + static_cast *>(arg); + std::unique_lock lock((*proot)->pmutex); + auto until = std::chrono::system_clock::now(); + until += wait_time; + auto ret = (*proot)->cond.wait_until( + lock, until, [&]() { return (*proot)->counter == limit; }); + + auto now = std::chrono::system_clock::now(); + if (ret == false) { + auto epsilon = std::chrono::milliseconds(10); + auto diff = + std::chrono::duration_cast( + until - now); + if (now < until) + UT_ASSERT(diff < epsilon); + } else { + UT_ASSERTeq((*proot)->counter, limit); + } + lock.unlock(); + + return nullptr; +} + +/* + * reader_mutex_for -- (internal) verify the counter value or timeout + */ +void * +reader_mutex_for(void *arg) +{ + nvobj::persistent_ptr *proot = + static_cast *>(arg); + (*proot)->pmutex.lock(); + auto until = std::chrono::system_clock::now(); + until += wait_time; + auto ret = (*proot)->cond.wait_for((*proot)->pmutex, wait_time); + + auto now = std::chrono::system_clock::now(); + if (ret == std::cv_status::timeout) { + auto epsilon = std::chrono::milliseconds(10); + auto diff = + std::chrono::duration_cast( + until - now); + if (now < until) + UT_ASSERT(diff < epsilon); + } else { + UT_ASSERTeq((*proot)->counter, limit); + } + (*proot)->pmutex.unlock(); + + return nullptr; +} + +/* + * reader_mutex_for_pred -- (internal) verify the counter value or timeout + */ +void * +reader_mutex_for_pred(void *arg) +{ + nvobj::persistent_ptr *proot = + static_cast *>(arg); + (*proot)->pmutex.lock(); + auto until = std::chrono::system_clock::now(); + until += wait_time; + auto ret = (*proot)->cond.wait_for((*proot)->pmutex, wait_time, [&]() { + return (*proot)->counter == limit; + }); + + auto now = std::chrono::system_clock::now(); + if (ret == false) { + auto epsilon = std::chrono::milliseconds(10); + auto diff = + std::chrono::duration_cast( + until - now); + if (now < until) + UT_ASSERT(diff < epsilon); + } else { + UT_ASSERTeq((*proot)->counter, limit); + } + (*proot)->pmutex.unlock(); + + return nullptr; +} + +/* + * reader_lock_for -- (internal) verify the counter value or timeout + */ +void * +reader_lock_for(void *arg) +{ + nvobj::persistent_ptr *proot = + static_cast *>(arg); + std::unique_lock lock((*proot)->pmutex); + auto until = std::chrono::system_clock::now(); + until += wait_time; + auto ret = (*proot)->cond.wait_for(lock, wait_time); + + auto now = std::chrono::system_clock::now(); + if (ret == std::cv_status::timeout) { + auto epsilon = std::chrono::milliseconds(10); + auto diff = + std::chrono::duration_cast( + until - now); + if (now < until) + UT_ASSERT(diff < epsilon); + } else { + UT_ASSERTeq((*proot)->counter, limit); + } + lock.unlock(); + + return nullptr; +} + +/* + * reader_lock_for_pred -- (internal) verify the counter value or timeout + */ +void * +reader_lock_for_pred(void *arg) +{ + nvobj::persistent_ptr *proot = + static_cast *>(arg); + std::unique_lock lock((*proot)->pmutex); + auto until = std::chrono::system_clock::now(); + until += wait_time; + auto ret = (*proot)->cond.wait_for( + lock, wait_time, [&]() { return (*proot)->counter == limit; }); + + auto now = std::chrono::system_clock::now(); + if (ret == false) { + auto epsilon = std::chrono::milliseconds(10); + auto diff = + std::chrono::duration_cast( + until - now); + if (now < until) + UT_ASSERT(diff < epsilon); + } else { + UT_ASSERTeq((*proot)->counter, limit); + } + lock.unlock(); + + return nullptr; +} + +/* + * cond_zero_test -- (internal) test the zeroing constructor + */ +void +cond_zero_test(nvobj::pool &pop) +{ + PMEMoid raw_cnd; + + pmemobj_alloc(pop.handle(), &raw_cnd, sizeof(PMEMcond), 1, + [](PMEMobjpool *pop, void *ptr, void *arg) -> int { + PMEMcond *mtx = static_cast(ptr); + pmemobj_memset_persist(pop, mtx, 1, sizeof(*mtx)); + return 0; + }, + nullptr); + + nvobj::condition_variable *placed_mtx = + new (pmemobj_direct(raw_cnd)) nvobj::condition_variable; + std::unique_lock lock(pop.root()->pmutex); + placed_mtx->wait_for(lock, wait_time, []() { return false; }); +} + +/* + * mutex_test -- (internal) launch worker threads to test the pshared_mutex + */ +template +void +mutex_test(nvobj::pool &pop, bool notify, bool notify_all, + Reader writer, Writer reader) +{ + const auto total_threads = num_threads * 2u; + pthread_t threads[total_threads]; + + nvobj::persistent_ptr proot = pop.root(); + struct writer_args wargs = {proot, notify, notify_all}; + + for (unsigned i = 0; i < total_threads; i += 2) { + ut_pthread_create(&threads[i], nullptr, reader, &proot); + ut_pthread_create(&threads[i + 1], nullptr, writer, &wargs); + } + + for (unsigned i = 0; i < total_threads; ++i) + ut_pthread_join(&threads[i], nullptr); +} +} + +int +main(int argc, char *argv[]) +{ + START(); + + if (argc != 2) + UT_FATAL("usage: %s file-name", argv[0]); + + const char *path = argv[1]; + + nvobj::pool pop; + + try { + pop = nvobj::pool::create( + path, LAYOUT, PMEMOBJ_MIN_POOL, S_IWUSR | S_IRUSR); + } catch (pmem::pool_error &pe) { + UT_FATAL("!pool::create: %s %s", pe.what(), path); + } + + cond_zero_test(pop); + + std::vector notify_functions( + {reader_mutex, reader_mutex_pred, reader_lock, reader_lock_pred, + reader_mutex_until, reader_mutex_until_pred, reader_lock_until, + reader_lock_until_pred, reader_mutex_for, + reader_mutex_for_pred, reader_lock_for, reader_lock_for_pred}); + + for (auto func : notify_functions) { + unsigned reset_value = 42; + + mutex_test(pop, true, false, write_notify, func); + pop.root()->counter = reset_value; + + mutex_test(pop, true, true, write_notify, func); + pop.root()->counter = reset_value; + } + + std::vector not_notify_functions( + {reader_mutex_until, reader_mutex_until_pred, reader_lock_until, + reader_lock_until_pred, reader_mutex_for, + reader_mutex_for_pred, reader_lock_for, reader_lock_for_pred}); + + for (auto func : not_notify_functions) { + unsigned reset_value = 42; + + mutex_test(pop, false, false, write_notify, func); + pop.root()->counter = reset_value; + + mutex_test(pop, false, true, write_notify, func); + pop.root()->counter = reset_value; + } + + /* pmemcheck related persist */ + pmemobj_persist(pop.handle(), &(pop.root()->counter), + sizeof(pop.root()->counter)); + + pop.close(); + + return 0; +} diff --git a/tests/ctest_helpers.cmake b/tests/ctest_helpers.cmake new file mode 100644 index 0000000..6358475 --- /dev/null +++ b/tests/ctest_helpers.cmake @@ -0,0 +1,343 @@ +# +# Copyright 2018-2019, Intel Corporation +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# +# * Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# +# * Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in +# the documentation and/or other materials provided with the +# distribution. +# +# * Neither the name of the copyright holder nor the names of its +# contributors may be used to endorse or promote products derived +# from this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +# +# ctest_helpers.cmake - helper functions for tests/CMakeLists.txt +# + +set(TEST_ROOT_DIR ${PROJECT_SOURCE_DIR}/tests) + +set(GLOBAL_TEST_ARGS + -DPERL_EXECUTABLE=${PERL_EXECUTABLE} + -DMATCH_SCRIPT=${PROJECT_SOURCE_DIR}/tests/match + -DPARENT_DIR=${TEST_DIR} + -DTESTS_USE_FORCED_PMEM=${TESTS_USE_FORCED_PMEM} + -DTEST_ROOT_DIR=${TEST_ROOT_DIR}) + +if(TRACE_TESTS) + set(GLOBAL_TEST_ARGS ${GLOBAL_TEST_ARGS} --trace-expand) +endif() + +set(INCLUDE_DIRS ${LIBPMEMOBJ_INCLUDE_DIRS} common/ .. .) +set(LIBS_DIRS ${LIBPMEMOBJ_LIBRARY_DIRS}) + +include_directories(${INCLUDE_DIRS}) +link_directories(${LIBS_DIRS}) + +set(SAVED_CMAKE_REQUIRED_FLAGS ${CMAKE_REQUIRED_FLAGS}) +set(SAVED_CMAKE_REQUIRED_INCLUDES ${CMAKE_REQUIRED_INCLUDES}) + +if(NOT MSVC_VERSION) + # Check for issues with older clang compilers which assert on delete persistent<[][]>. + set(CMAKE_REQUIRED_INCLUDES ${CMAKE_CURRENT_SOURCE_DIR}/../include ${LIBPMEMOBJ_INCLUDE_DIRS}) + set(CMAKE_REQUIRED_FLAGS "--std=c++11 -Wno-error -c") + CHECK_CXX_SOURCE_COMPILES( + "#include + using namespace pmem::obj; + int main() { + delete_persistent(make_persistent(2), 2); + return 0; + }" + NO_CLANG_TEMPLATE_BUG) + + # This is a workaround for older incompatible versions of libstdc++ and clang. + # Please see https://llvm.org/bugs/show_bug.cgi?id=15517 for more info. + set(CMAKE_REQUIRED_FLAGS "--std=c++11 -Wno-error -include future") + CHECK_CXX_SOURCE_COMPILES( + "int main() { return 0; }" + NO_CHRONO_BUG) + + set(CMAKE_REQUIRED_FLAGS "--std=c++${CMAKE_CXX_STANDARD} -c") + CHECK_CXX_SOURCE_COMPILES( + "#include + int main() { + #if !__cpp_lib_is_aggregate + static_assert(false, \"\"); + #endif + }" + AGGREGATE_INITIALIZATION_AVAILABLE + ) +else() + set(AGGREGATE_INITIALIZATION_AVAILABLE FALSE) + set(NO_CLANG_TEMPLATE_BUG TRUE) + set(NO_CHRONO_BUG TRUE) +endif() + +set(CMAKE_REQUIRED_FLAGS "--std=c++${CMAKE_CXX_STANDARD} -c") +CHECK_CXX_SOURCE_COMPILES( + "#include + int main() { + std::max_align_t var; + return 0; + }" + MAX_ALIGN_TYPE_EXISTS) + +set(CMAKE_REQUIRED_FLAGS ${SAVED_CMAKE_REQUIRED_FLAGS}) +set(CMAKE_REQUIRED_INCLUDES ${SAVED_CMAKE_REQUIRED_INCLUDES}) + +function(find_pmemcheck) + set(ENV{PATH} ${VALGRIND_PREFIX}/bin:$ENV{PATH}) + execute_process(COMMAND valgrind --tool=pmemcheck --help + RESULT_VARIABLE VALGRIND_PMEMCHECK_RET + OUTPUT_QUIET + ERROR_QUIET) + if(VALGRIND_PMEMCHECK_RET) + set(VALGRIND_PMEMCHECK_FOUND 0 CACHE INTERNAL "") + else() + set(VALGRIND_PMEMCHECK_FOUND 1 CACHE INTERNAL "") + endif() + + if(VALGRIND_PMEMCHECK_FOUND) + execute_process(COMMAND valgrind --tool=pmemcheck true + ERROR_VARIABLE PMEMCHECK_OUT + OUTPUT_QUIET) + + string(REGEX MATCH ".*pmemcheck-([0-9.]*),.*" PMEMCHECK_OUT "${PMEMCHECK_OUT}") + set(PMEMCHECK_VERSION ${CMAKE_MATCH_1} CACHE INTERNAL "") + else() + message(WARNING "Valgrind pmemcheck NOT found. Pmemcheck tests will not be performed.") + endif() +endfunction() + +function(build_pmemobj_cow_check) + execute_process(COMMAND ${CMAKE_COMMAND} + ${PROJECT_SOURCE_DIR}/tests/pmemobj_check_cow/CMakeLists.txt + -DLIBPMEMOBJ_INCLUDE_DIRS=${LIBPMEMOBJ_INCLUDE_DIRS} + -DLIBPMEMOBJ++_INCLUDE_DIRS=${PROJECT_SOURCE_DIR}/include + -DLIBPMEMOBJ_LIBRARIES=${LIBPMEMOBJ_LIBRARIES} + -DLIBPMEMOBJ_LIBRARY_DIRS=${LIBPMEMOBJ_LIBRARY_DIRS} + -Bpmemobj_check_cow + OUTPUT_QUIET) + + execute_process(COMMAND ${CMAKE_COMMAND} + --build pmemobj_check_cow + OUTPUT_QUIET) +endfunction() + +# pmreorder tests require COW support in libpmemobj because if checker program +# does any recovery (for example in pool::open) this is not logged and will not +# be reverted by pmreorder. This results in unexpected state in proceding +# pmreorder steps (expected state is initial pool, modified only by pmreorder) +function(check_pmemobj_cow_support pool) + build_pmemobj_cow_check() + set(ENV{PMEMOBJ_COW} 1) + + execute_process(COMMAND pmemobj_check_cow/pmemobj_check_cow + ${pool} RESULT_VARIABLE ret) + if (ret EQUAL 0) + set(PMEMOBJ_COW_SUPPORTED true CACHE INTERNAL "") + elseif(ret EQUAL 2) + set(PMEMOBJ_COW_SUPPORTED false CACHE INTERNAL "") + message(WARNING "Pmemobj does not support PMEMOBJ_COW. Pmreorder tests will not be performed.") + else() + message(FATAL_ERROR "pmemobj_check_cow failed") + endif() + + unset(ENV{PMEMOBJ_COW}) +endfunction() + +function(find_packages) + if(PKG_CONFIG_FOUND) + pkg_check_modules(CURSES QUIET ncurses) + else() + # Specifies that we want FindCurses to find ncurses and not just any + # curses library + set(CURSES_NEED_NCURSES TRUE) + find_package(Curses QUIET) + endif() + + # Look for valgrind only if proper option is enabled. + if (TESTS_USE_VALGRIND) + if(PKG_CONFIG_FOUND) + pkg_check_modules(VALGRIND QUIET valgrind) + else() + find_package(VALGRIND QUIET) + endif() + endif() + + if(PKG_CONFIG_FOUND) + pkg_check_modules(LIBUNWIND QUIET libunwind) + else() + find_package(LIBUNWIND QUIET) + endif() + if(NOT LIBUNWIND_FOUND) + message(WARNING "libunwind not found. Stack traces from tests will not be reliable") + endif() + + if(NOT WIN32) + if(VALGRIND_FOUND) + include_directories(${VALGRIND_INCLUDE_DIRS}) + find_pmemcheck() + + if ((NOT(PMEMCHECK_VERSION LESS 1.0)) AND PMEMCHECK_VERSION LESS 2.0) + find_program(PMREORDER names pmreorder HINTS ${LIBPMEMOBJ_PREFIX}/bin) + check_pmemobj_cow_support("cow.pool") + + if(PMREORDER AND PMEMOBJ_COW_SUPPORTED) + set(ENV{PATH} ${LIBPMEMOBJ_PREFIX}/bin:$ENV{PATH}) + set(PMREORDER_SUPPORTED true CACHE INTERNAL "pmreorder support") + endif() + else() + message(STATUS "Pmreorder will not be used. Pmemcheck must be installed in version 1.X") + endif() + elseif(TESTS_USE_VALGRIND) + message(WARNING "Valgrind not found. Valgrind tests will not be performed.") + endif() + endif() +endfunction() + +function(build_test name) + # skip posix tests + if(${name} MATCHES "posix$" AND WIN32) + return() + endif() + + set(srcs ${ARGN}) + prepend(srcs ${CMAKE_CURRENT_SOURCE_DIR} ${srcs}) + + add_cppstyle(tests-${name} ${srcs}) + add_check_whitespace(tests-${name} ${srcs}) + + add_executable(${name} ${srcs}) + target_link_libraries(${name} ${LIBPMEMOBJ_LIBRARIES} ${CMAKE_THREAD_LIBS_INIT} test_backtrace valgrind_internal) + if(LIBUNWIND_FOUND) + target_link_libraries(${name} ${LIBUNWIND_LIBRARIES} ${CMAKE_DL_LIBS}) + endif() + if(WIN32) + target_link_libraries(${name} dbghelp) + endif() + target_compile_definitions(${name} PRIVATE TESTS_LIBPMEMOBJ_VERSION=0x${LIBPMEMOBJ_VERSION_NUM}) + + add_dependencies(tests ${name}) +endfunction() + +set(vg_tracers memcheck helgrind drd pmemcheck) + +# Configures testcase ${name} ${testcase} using tracer ${tracer}, cmake_script is used to run test +function(add_testcase name tracer testcase cmake_script) + set(executable ${name}) + add_test(NAME ${executable}_${testcase}_${tracer} + COMMAND ${CMAKE_COMMAND} + ${GLOBAL_TEST_ARGS} + -DTEST_NAME=${executable}_${testcase}_${tracer} + -DTESTCASE=${testcase} + -DSRC_DIR=${CMAKE_CURRENT_SOURCE_DIR}/${name} + -DBIN_DIR=${CMAKE_CURRENT_BINARY_DIR}/${executable}_${testcase}_${tracer} + -DTEST_EXECUTABLE=$ + -DTRACER=${tracer} + -DLONG_TESTS=${LONG_TESTS} + -P ${cmake_script}) + + set_tests_properties(${name}_${testcase}_${tracer} PROPERTIES + ENVIRONMENT "LC_ALL=C;PATH=$ENV{PATH};" + FAIL_REGULAR_EXPRESSION Sanitizer) + + if (${tracer} STREQUAL pmemcheck) + # XXX: if we use FATAL_ERROR in test.cmake - pmemcheck passes anyway + set_tests_properties(${name}_${testcase}_${tracer} PROPERTIES + FAIL_REGULAR_EXPRESSION "CMake Error") + endif() + + if (${tracer} STREQUAL pmemcheck) + set_tests_properties(${name}_${testcase}_${tracer} PROPERTIES + COST 100) + elseif(${tracer} IN_LIST vg_tracers) + set_tests_properties(${name}_${testcase}_${tracer} PROPERTIES + COST 50) + else() + set_tests_properties(${name}_${testcase}_${tracer} PROPERTIES + COST 10) + endif() +endfunction() + +function(skip_test name message) + add_test(NAME ${name}_${message} + COMMAND ${CMAKE_COMMAND} -P ${TEST_ROOT_DIR}/true.cmake) + + set_tests_properties(${name}_${message} PROPERTIES COST 0) +endfunction() + +# adds testcase with name, tracer, and cmake_script responsible for running it +function(add_test_common name tracer testcase cmake_script) + if(${tracer} STREQUAL "") + set(tracer none) + endif() + + if (NOT WIN32 AND (NOT VALGRIND_FOUND) AND ${tracer} IN_LIST vg_tracers) + # Only print "SKIPPED_*" message when option is enabled + if (TESTS_USE_VALGRIND) + skip_test(${name}_${testcase}_${tracer} "SKIPPED_BECAUSE_OF_MISSING_VALGRIND") + endif() + return() + endif() + + if (NOT WIN32 AND (NOT VALGRIND_PMEMCHECK_FOUND) AND ${tracer} STREQUAL "pmemcheck") + # Only print "SKIPPED_*" message when option is enabled + if (TESTS_USE_VALGRIND) + skip_test(${name}_${testcase}_${tracer} "SKIPPED_BECAUSE_OF_MISSING_PMEMCHECK") + endif() + return() + endif() + + if (NOT WIN32 AND (USE_ASAN OR USE_UBSAN) AND ${tracer} IN_LIST vg_tracers) + skip_test(${name}_${testcase}_${tracer} "SKIPPED_BECAUSE_SANITIZER_USED") + return() + endif() + + # if test was not build + if (NOT TARGET ${name}) + return() + endif() + + # skip all tests with pmemcheck/memcheck/drd on windows + if ((NOT ${tracer} STREQUAL none) AND WIN32) + return() + endif() + + add_testcase(${name} ${tracer} ${testcase} ${cmake_script}) +endfunction() + +function(add_test_generic) + set(oneValueArgs NAME CASE) + set(multiValueArgs TRACERS) + cmake_parse_arguments(TEST "" "${oneValueArgs}" "${multiValueArgs}" ${ARGN}) + + if("${TEST_CASE}" STREQUAL "") + set(TEST_CASE "0") + set(cmake_script ${CMAKE_CURRENT_SOURCE_DIR}/run_default.cmake) + else() + set(cmake_script ${CMAKE_CURRENT_SOURCE_DIR}/${TEST_NAME}/${TEST_NAME}_${TEST_CASE}.cmake) + endif() + + foreach(tracer ${TEST_TRACERS}) + add_test_common(${TEST_NAME} ${tracer} ${TEST_CASE} ${cmake_script}) + endforeach() +endfunction() diff --git a/tests/ctl/ctl.cpp b/tests/ctl/ctl.cpp new file mode 100644 index 0000000..37ba0d5 --- /dev/null +++ b/tests/ctl/ctl.cpp @@ -0,0 +1,154 @@ +/* + * Copyright 2018-2019, Intel Corporation + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * * Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include +#include +#include + +#include "unittest.hpp" + +struct root { +}; + +using Object = int[10240]; + +void +run_ctl_pool_prefault(pmem::obj::pool &pop) try { + pop.ctl_set("prefault.at_open", 1); + + auto prefault_at_open = pop.ctl_get("prefault.at_open"); + UT_ASSERTeq(prefault_at_open, 1); + + pop.ctl_set("prefault.at_open", 0); + + prefault_at_open = pop.ctl_get("prefault.at_open"); + UT_ASSERTeq(prefault_at_open, 0); +} catch (...) { + UT_ASSERT(0); +} + +void +run_ctl_pool_extend(pmem::obj::pool &pop) try { + /* disable auto-extend */ + pop.ctl_set("heap.size.granularity", 0); + + pmem::obj::persistent_ptr ptr; + try { + /* allocate until OOM */ + while (true) { + pmem::obj::make_persistent_atomic(pop, ptr); + } + } catch (...) { + } + + pop.ctl_exec("heap.size.extend", (1 << 20) * 10); + + /* next allocation should succeed */ + try { + pmem::obj::make_persistent_atomic(pop, ptr); + } catch (...) { + UT_ASSERT(0); + } +} catch (...) { + UT_ASSERT(0); +} + +void +run_ctl_global() try { + pmem::obj::ctl_set("prefault.at_create", 1); + + auto prefault_at_create = pmem::obj::ctl_get("prefault.at_create"); + UT_ASSERTeq(prefault_at_create, 1); + + pmem::obj::ctl_set("prefault.at_create", 0); + + prefault_at_create = pmem::obj::ctl_get("prefault.at_create"); + UT_ASSERTeq(prefault_at_create, 0); +} catch (...) { + UT_ASSERT(0); +} + +void +run_ctl_exception() +{ + try { + /* run query with non-existing entry point */ + pmem::obj::ctl_set("prefault.non_existing_entry_point", 1); + UT_ASSERT(0); + } catch (pmem::ctl_error &e) { + } catch (...) { + UT_ASSERT(0); + } + + try { + /* run query with non-existing entry point */ + pmem::obj::ctl_get("prefault.non_existing_entry_point"); + UT_ASSERT(0); + } catch (pmem::ctl_error &e) { + } catch (...) { + UT_ASSERT(0); + } + + try { + /* run query with non-existing entry point */ + pmem::obj::ctl_exec("prefault.non_existing_entry_point", + 1); + UT_ASSERT(0); + } catch (pmem::ctl_error &e) { + } catch (...) { + UT_ASSERT(0); + } +} + +int +main(int argc, char *argv[]) +{ + START(); + + if (argc < 2) { + UT_FATAL("usage: %s file-name", argv[0]); + return 1; + } + + auto path = argv[1]; + auto pop = pmem::obj::pool::create(path, "ctl_test", 0, + S_IWUSR | S_IRUSR); + + run_ctl_pool_prefault(pop); + run_ctl_pool_extend(pop); + run_ctl_global(); + run_ctl_exception(); + + pop.close(); + + return 0; +} diff --git a/tests/ctl/ctl_0.cmake b/tests/ctl/ctl_0.cmake new file mode 100644 index 0000000..157c6ea --- /dev/null +++ b/tests/ctl/ctl_0.cmake @@ -0,0 +1,43 @@ +# +# Copyright 2018, Intel Corporation +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# +# * Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# +# * Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in +# the documentation and/or other materials provided with the +# distribution. +# +# * Neither the name of the copyright holder nor the names of its +# contributors may be used to endorse or promote products derived +# from this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +include(${SRC_DIR}/../helpers.cmake) + +setup() + +set(TESTDIR ${DIR}/testdir) +configure_file(${SRC_DIR}/pool.set.in ${DIR}/pool.set @ONLY) + +file(MAKE_DIRECTORY ${DIR}/testdir) + +execute(${TEST_EXECUTABLE} ${DIR}/pool.set) + +finish() diff --git a/tests/ctl/pool.set.in b/tests/ctl/pool.set.in new file mode 100644 index 0000000..827ab1b --- /dev/null +++ b/tests/ctl/pool.set.in @@ -0,0 +1,3 @@ +PMEMPOOLSET +OPTION SINGLEHDR +16M @TESTDIR@ diff --git a/tests/ctl_win/ctl_win.cpp b/tests/ctl_win/ctl_win.cpp new file mode 100644 index 0000000..2133136 --- /dev/null +++ b/tests/ctl_win/ctl_win.cpp @@ -0,0 +1,159 @@ +/* + * Copyright 2018-2019, Intel Corporation + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * * Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include +#include +#include + +#include "unittest.hpp" + +struct root { +}; + +using Object = int[10240]; + +void +run_ctl_pool_prefault(pmem::obj::pool &pop) try { + pop.ctl_set(ut_toUTF8(L"prefault.at_open"), 1); + + auto prefault_at_open = + pop.ctl_get(ut_toUTF8(L"prefault.at_open")); + UT_ASSERTeq(prefault_at_open, 1); + + pop.ctl_set(ut_toUTF8(L"prefault.at_open"), 0); + + prefault_at_open = pop.ctl_get(ut_toUTF8(L"prefault.at_open")); + UT_ASSERTeq(prefault_at_open, 0); +} catch (...) { + UT_ASSERT(0); +} + +void +run_ctl_pool_extend(pmem::obj::pool &pop) try { + /* disable auto-extend */ + pop.ctl_set(ut_toUTF8(L"heap.size.granularity"), 0); + + pmem::obj::persistent_ptr ptr; + try { + /* allocate until OOM */ + while (true) { + pmem::obj::make_persistent_atomic(pop, ptr); + } + } catch (...) { + } + + pop.ctl_exec(ut_toUTF8(L"heap.size.extend"), (1 << 20) * 10); + + /* next allocation should succeed */ + try { + pmem::obj::make_persistent_atomic(pop, ptr); + } catch (...) { + UT_ASSERT(0); + } +} catch (...) { + UT_ASSERT(0); +} + +void +run_ctl_global() try { + pmem::obj::ctl_set(ut_toUTF8(L"prefault.at_create"), 1); + + auto prefault_at_create = + pmem::obj::ctl_get(ut_toUTF8(L"prefault.at_create")); + UT_ASSERTeq(prefault_at_create, 1); + + pmem::obj::ctl_set(ut_toUTF8(L"prefault.at_create"), 0); + + prefault_at_create = + pmem::obj::ctl_get(ut_toUTF8(L"prefault.at_create")); + UT_ASSERTeq(prefault_at_create, 0); +} catch (...) { + UT_ASSERT(0); +} + +void +run_ctl_exception() +{ + try { + /* run query with non-existing entry point */ + pmem::obj::ctl_set( + ut_toUTF8(L"prefault.non_existing_entry_point"), 1); + UT_ASSERT(0); + } catch (pmem::ctl_error &e) { + } catch (...) { + UT_ASSERT(0); + } + + try { + /* run query with non-existing entry point */ + pmem::obj::ctl_get( + ut_toUTF8(L"prefault.non_existing_entry_point")); + UT_ASSERT(0); + } catch (pmem::ctl_error &e) { + } catch (...) { + UT_ASSERT(0); + } + + try { + /* run query with non-existing entry point */ + pmem::obj::ctl_exec( + ut_toUTF8(L"prefault.non_existing_entry_point"), 1); + UT_ASSERT(0); + } catch (pmem::ctl_error &e) { + } catch (...) { + UT_ASSERT(0); + } +} + +int +wmain(int argc, wchar_t *argv[]) +{ + START(); + + if (argc < 2) { + UT_FATAL("usage: %s file-name", ut_toUTF8(argv[0])); + return 1; + } + + auto path = argv[1]; + auto pop = pmem::obj::pool::create(path, L"ctl_test", 0, + S_IWUSR | S_IRUSR); + + run_ctl_pool_prefault(pop); + run_ctl_pool_extend(pop); + run_ctl_global(); + run_ctl_exception(); + + pop.close(); + + return 0; +} diff --git a/tests/ctl_win/ctl_win_0.cmake b/tests/ctl_win/ctl_win_0.cmake new file mode 100644 index 0000000..157c6ea --- /dev/null +++ b/tests/ctl_win/ctl_win_0.cmake @@ -0,0 +1,43 @@ +# +# Copyright 2018, Intel Corporation +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# +# * Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# +# * Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in +# the documentation and/or other materials provided with the +# distribution. +# +# * Neither the name of the copyright holder nor the names of its +# contributors may be used to endorse or promote products derived +# from this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +include(${SRC_DIR}/../helpers.cmake) + +setup() + +set(TESTDIR ${DIR}/testdir) +configure_file(${SRC_DIR}/pool.set.in ${DIR}/pool.set @ONLY) + +file(MAKE_DIRECTORY ${DIR}/testdir) + +execute(${TEST_EXECUTABLE} ${DIR}/pool.set) + +finish() diff --git a/tests/ctl_win/pool.set.in b/tests/ctl_win/pool.set.in new file mode 100644 index 0000000..827ab1b --- /dev/null +++ b/tests/ctl_win/pool.set.in @@ -0,0 +1,3 @@ +PMEMPOOLSET +OPTION SINGLEHDR +16M @TESTDIR@ diff --git a/tests/detail_common/detail_common.cpp b/tests/detail_common/detail_common.cpp new file mode 100644 index 0000000..9aae151 --- /dev/null +++ b/tests/detail_common/detail_common.cpp @@ -0,0 +1,72 @@ +/* + * Copyright 2018, Intel Corporation + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * * Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +/* + * detail_common.cpp -- detail/common.hpp functions tests + */ +#include "unittest.hpp" + +#include + +void +test_next_pow_2() +{ + UT_ASSERT(1 == pmem::detail::next_pow_2(0U)); + UT_ASSERT(1 == pmem::detail::next_pow_2(1U)); + UT_ASSERT(2 == pmem::detail::next_pow_2(2U)); + UT_ASSERT(4 == pmem::detail::next_pow_2(3U)); + UT_ASSERT(4096 == pmem::detail::next_pow_2(2507U)); + UT_ASSERT(1 == pmem::detail::next_pow_2(static_cast(0))); + UT_ASSERT(1 == pmem::detail::next_pow_2(static_cast(1))); + UT_ASSERT(2 == pmem::detail::next_pow_2(static_cast(2))); + UT_ASSERT(4 == pmem::detail::next_pow_2(static_cast(3))); + UT_ASSERT(4096 == + pmem::detail::next_pow_2(static_cast(2507))); + UT_ASSERT(1ULL << 32 == + pmem::detail::next_pow_2(static_cast(1ULL << 32))); + UT_ASSERT(1ULL << 33 == + pmem::detail::next_pow_2( + static_cast((1ULL << 32) + 1))); + UT_ASSERT(1ULL << 50 == + pmem::detail::next_pow_2(static_cast( + (1ULL << 49) + (1ULL << 38) + (1ULL << 17) + 2507))); +} + +int +main() +{ + START(); + + test_next_pow_2(); + + return 0; +} diff --git a/tests/ex-pman/ex-pman_0.cmake b/tests/ex-pman/ex-pman_0.cmake new file mode 100644 index 0000000..f91cd24 --- /dev/null +++ b/tests/ex-pman/ex-pman_0.cmake @@ -0,0 +1,45 @@ +# +# Copyright 2018, Intel Corporation +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# +# * Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# +# * Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in +# the documentation and/or other materials provided with the +# distribution. +# +# * Neither the name of the copyright holder nor the names of its +# contributors may be used to endorse or promote products derived +# from this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +include(${SRC_DIR}/../helpers.cmake) + +setup() + +execute_process(COMMAND tty OUTPUT_FILE /dev/null RESULT_VARIABLE result) + +if (result EQUAL 0) + execute(${SRC_DIR}/prepare_input.sh ${DIR}/input) + execute(${TEST_EXECUTABLE} ${DIR}/testfile ${SRC_DIR}/../../examples/pman/map INPUT_FILE ${DIR}/input) +else() + message(WARNING "Skip: stdout is not terminal") +endif() + +finish() diff --git a/tests/ex-pman/prepare_input.sh b/tests/ex-pman/prepare_input.sh new file mode 100755 index 0000000..445860d --- /dev/null +++ b/tests/ex-pman/prepare_input.sh @@ -0,0 +1,41 @@ +#!/usr/bin/env bash +# +# Copyright 2018, Intel Corporation +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# +# * Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# +# * Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in +# the documentation and/or other materials provided with the +# distribution. +# +# * Neither the name of the copyright holder nor the names of its +# contributors may be used to endorse or promote products derived +# from this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +# +set -e + +# prepares input for ex-pman test +# usage: ./prepare_input.sh input_file + +dd if=/dev/zero bs=64 count=1 2>>/dev/null >> $1 +echo -n slkiiijjbjjii >> $1 +dd if=/dev/zero bs=128 count=1 2>>/dev/null >> $1 +echo -n q >> $1 diff --git a/tests/ex-queue/ex-queue_0.cmake b/tests/ex-queue/ex-queue_0.cmake new file mode 100644 index 0000000..e1ee1a2 --- /dev/null +++ b/tests/ex-queue/ex-queue_0.cmake @@ -0,0 +1,44 @@ +# +# Copyright 2018, Intel Corporation +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# +# * Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# +# * Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in +# the documentation and/or other materials provided with the +# distribution. +# +# * Neither the name of the copyright holder nor the names of its +# contributors may be used to endorse or promote products derived +# from this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +include(${SRC_DIR}/../helpers.cmake) + +setup() + +execute(${TEST_EXECUTABLE} ${DIR}/testfile push 1) +execute(${TEST_EXECUTABLE} ${DIR}/testfile push 2) +execute(${TEST_EXECUTABLE} ${DIR}/testfile push 3) +execute(${TEST_EXECUTABLE} ${DIR}/testfile pop) +execute(${TEST_EXECUTABLE} ${DIR}/testfile show) + +check_file_exists(${DIR}/testfile) + +finish() diff --git a/tests/ex-queue/ex-queue_0_none.out.match b/tests/ex-queue/ex-queue_0_none.out.match new file mode 100644 index 0000000..4792e70 --- /dev/null +++ b/tests/ex-queue/ex-queue_0_none.out.match @@ -0,0 +1,2 @@ +2 +3 diff --git a/tests/external/CMakeLists.txt b/tests/external/CMakeLists.txt new file mode 100644 index 0000000..e911395 --- /dev/null +++ b/tests/external/CMakeLists.txt @@ -0,0 +1,590 @@ +# +# Copyright 2018-2019, Intel Corporation +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# +# * Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# +# * Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in +# the documentation and/or other materials provided with the +# distribution. +# +# * Neither the name of the copyright holder nor the names of its +# contributors may be used to endorse or promote products derived +# from this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +include(../ctest_helpers.cmake) + +function(add_test_expect_failure name) + set(srcs ${ARGN}) + prepend(srcs ${CMAKE_CURRENT_SOURCE_DIR} ${srcs}) + + add_cppstyle(tests-external-${name} ${srcs}) + add_check_whitespace(tests-external-${name} ${srcs}) + + add_executable(${name}_fail_expected ${srcs}) + set_target_properties(${name}_fail_expected PROPERTIES + EXCLUDE_FROM_ALL TRUE + EXCLUDE_FROM_DEFAULT_BUILD TRUE) + + add_test(NAME ${name}_fail_expected + COMMAND ${CMAKE_COMMAND} --build ${CMAKE_BINARY_DIR} --target ${name}_fail_expected + WORKING_DIRECTORY ${CMAKE_BINARY_DIR}) + + set_tests_properties(${name}_fail_expected PROPERTIES WILL_FAIL TRUE) +endfunction() + +if (ENABLE_ARRAY) + build_test(array_at libcxx/array/at.pass.cpp) + add_test_generic(NAME array_at TRACERS none) + + build_test(array_begin libcxx/array/begin.pass.cpp) + add_test_generic(NAME array_begin TRACERS none) + + build_test(array_compare libcxx/array/compare.pass.cpp) + add_test_generic(NAME array_compare TRACERS none) + + build_test(array_contiguous libcxx/array/contiguous.pass.cpp) + add_test_generic(NAME array_contiguous TRACERS none) + + build_test(array_empty libcxx/array/empty.pass.cpp) + add_test_generic(NAME array_empty TRACERS none) + + build_test(array_front_back libcxx/array/front_back.pass.cpp) + add_test_generic(NAME array_front_back TRACERS none) + + build_test(array_indexing libcxx/array/indexing.pass.cpp) + add_test_generic(NAME array_indexing TRACERS none) + + build_test(array_max_size libcxx/array/max_size.pass.cpp) + add_test_generic(NAME array_max_size TRACERS none) + + if (MAX_ALIGN_TYPE_EXISTS) + build_test(array_size_and_alignment libcxx/array/size_and_alignment.pass.cpp) + add_test_generic(NAME array_size_and_alignment TRACERS none) + endif() + + build_test(array_types libcxx/array/types.pass.cpp) + add_test_generic(NAME array_types TRACERS none) + + add_test_expect_failure(array_compare_0 libcxx/array/compare.fail_0.cpp) + add_test_expect_failure(array_compare_1 libcxx/array/compare.fail_1.cpp) + add_test_expect_failure(array_compare_2 libcxx/array/compare.fail_2.cpp) + + build_test(array_cons_default libcxx/array/array.cons/default.pass.cpp) + add_test_generic(NAME array_cons_default TRACERS none) + + add_test_expect_failure(array_copy_assignment libcxx/array/array.cons/copy_assignment.fail.cpp) + + build_test(array_cons_implicit_copy libcxx/array/array.cons/implicit_copy.pass.cpp) + add_test_generic(NAME array_cons_implicit_copy TRACERS none) + + build_test(array_initializer_list libcxx/array/array.cons/initializer_list.pass.cpp) + add_test_generic(NAME array_initializer_list TRACERS none) + + if (MAX_ALIGN_TYPE_EXISTS) + build_test(array_data_const libcxx/array/array.data/data_const.pass.cpp) + add_test_generic(NAME array_data_const TRACERS none) + endif() + + if (MAX_ALIGN_TYPE_EXISTS) + build_test(array_data libcxx/array/array.data/data.pass.cpp) + add_test_generic(NAME array_data TRACERS none) + endif() + + add_test_expect_failure(array_fill libcxx/array/array.fill/fill.fail.cpp) + + build_test(array_fill libcxx/array/array.fill/fill.pass.cpp) + add_test_generic(NAME array_fill TRACERS none) + + build_test(array_size libcxx/array/array.size/size.pass.cpp) + add_test_generic(NAME array_size TRACERS none) + + build_test(array_swap libcxx/array/array.special/swap.pass.cpp) + add_test_generic(NAME array_swap TRACERS none) + + add_test_expect_failure(array_swap libcxx/array/array.swap/swap.fail.cpp) + + build_test(array_swap_2 libcxx/array/array.swap/swap.pass.cpp) + add_test_generic(NAME array_swap_2 TRACERS none) + + build_test(array_get_const_rv libcxx/array/array.tuple/get_const_rv.pass.cpp) + add_test_generic(NAME array_get_const_rv TRACERS none) + + build_test(array_get_const libcxx/array/array.tuple/get_const.pass.cpp) + add_test_generic(NAME array_get_const TRACERS none) + + build_test(array_get_rv libcxx/array/array.tuple/get_rv.pass.cpp) + add_test_generic(NAME array_get_rv TRACERS none) + + build_test(array_get libcxx/array/array.tuple/get.pass.cpp) + add_test_generic(NAME array_get TRACERS none) + + add_test_expect_failure(array_get libcxx/array/array.tuple/get.fail.cpp) + + build_test(array_iterators libcxx/array/iterators.pass.cpp) + add_test_generic(NAME array_iterators TRACERS none) +endif() + +if (ENABLE_VECTOR) + build_test(vector_libcxx_assign_copy libcxx/vector/vector.cons/assign_copy.pass.cpp) + add_test_generic(NAME vector_libcxx_assign_copy TRACERS none pmemcheck memcheck) + + build_test(vector_libcxx_assign_initializer_list libcxx/vector/vector.cons/assign_initializer_list.pass.cpp) + add_test_generic(NAME vector_libcxx_assign_initializer_list TRACERS none pmemcheck memcheck) + + build_test(vector_libcxx_assign_iter_iter libcxx/vector/vector.cons/assign_iter_iter.pass.cpp) + add_test_generic(NAME vector_libcxx_assign_iter_iter TRACERS none pmemcheck memcheck) + + build_test(vector_libcxx_assign_move_pass libcxx/vector/vector.cons/assign_move.pass.cpp) + add_test_generic(NAME vector_libcxx_assign_move_pass TRACERS none pmemcheck memcheck) + + build_test(vector_libcxx_assign_size_value libcxx/vector/vector.cons/assign_size_value.pass.cpp) + add_test_generic(NAME vector_libcxx_assign_size_value TRACERS none pmemcheck memcheck) + + build_test(vector_libcxx_ctor_default libcxx/vector/vector.cons/construct_default.pass.cpp) + add_test_generic(NAME vector_libcxx_ctor_default TRACERS none pmemcheck memcheck) + + build_test(vector_libcxx_ctor_iter_iter libcxx/vector/vector.cons/construct_iter_iter.pass.cpp) + add_test_generic(NAME vector_libcxx_ctor_iter_iter TRACERS none pmemcheck memcheck) + + build_test(vector_libcxx_ctor_move libcxx/vector/vector.cons/move.pass.cpp) + add_test_generic(NAME vector_libcxx_ctor_move TRACERS none pmemcheck memcheck) + + build_test(vector_libcxx_ctor_size libcxx/vector/vector.cons/construct_size.pass.cpp) + add_test_generic(NAME vector_libcxx_ctor_size TRACERS none pmemcheck memcheck) + + build_test(vector_libcxx_ctor_size_value libcxx/vector/vector.cons/construct_size_value.pass.cpp) + add_test_generic(NAME vector_libcxx_ctor_size_value TRACERS none pmemcheck memcheck) + + build_test(vector_libcxx_copy libcxx/vector/vector.cons/copy.pass.cpp) + add_test_generic(NAME vector_libcxx_copy TRACERS none pmemcheck memcheck) + + build_test(vector_libcxx_dtor_noexcept libcxx/vector/vector.cons/dtor_noexcept.pass.cpp) + add_test_generic(NAME vector_libcxx_dtor_noexcept TRACERS none) + + build_test(vector_libcxx_contiguous libcxx/vector/contiguous.pass.cpp) + add_test_generic(NAME vector_libcxx_contiguous TRACERS none pmemcheck memcheck) + + build_test(vector_libcxx_types libcxx/vector/types.pass.cpp) + add_test_generic(NAME vector_libcxx_types TRACERS none) + + build_test(vector_libcxx_iterators libcxx/vector/iterators.pass.cpp) + add_test_generic(NAME vector_libcxx_iterators TRACERS TRACERS none pmemcheck memcheck) + + build_test(vector_libcxx_data_const libcxx/vector/vector.data/data_const.pass.cpp) + add_test_generic(NAME vector_libcxx_data_const TRACERS none pmemcheck memcheck) + + build_test(vector_libcxx_data libcxx/vector/vector.data/data.pass.cpp) + add_test_generic(NAME vector_libcxx_data TRACERS none pmemcheck memcheck) + + build_test(vector_libcxx_initializer_list libcxx/vector/vector.cons/initializer_list.pass.cpp) + add_test_generic(NAME vector_libcxx_initializer_list TRACERS none pmemcheck memcheck) + + build_test(vector_libcxx_op_equal_initializer_list libcxx/vector/vector.cons/op_equal_initializer_list.pass.cpp) + add_test_generic(NAME vector_libcxx_op_equal_initializer_list TRACERS none pmemcheck memcheck) + + build_test(vector_libcxx_capacity libcxx/vector/vector.capacity/capacity.pass.cpp) + add_test_generic(NAME vector_libcxx_capacity TRACERS none pmemcheck memcheck) + + build_test(vector_libcxx_empty libcxx/vector/vector.capacity/empty.pass.cpp) + add_test_generic(NAME vector_libcxx_empty TRACERS none pmemcheck memcheck) + + build_test(vector_libcxx_max_size libcxx/vector/vector.capacity/max_size.pass.cpp) + add_test_generic(NAME vector_libcxx_max_size TRACERS none pmemcheck memcheck) + + build_test(vector_libcxx_reserve libcxx/vector/vector.capacity/reserve.pass.cpp) + add_test_generic(NAME vector_libcxx_reserve TRACERS none pmemcheck memcheck) + + build_test(vector_libcxx_resize_size libcxx/vector/vector.capacity/resize_size.pass.cpp) + add_test_generic(NAME vector_libcxx_resize_size TRACERS none pmemcheck memcheck) + + build_test(vector_libcxx_resize_size_value libcxx/vector/vector.capacity/resize_size_value.pass.cpp) + add_test_generic(NAME vector_libcxx_resize_size_value TRACERS none pmemcheck memcheck) + + build_test(vector_libcxx_shrink_to_fit libcxx/vector/vector.capacity/shrink_to_fit.pass.cpp) + add_test_generic(NAME vector_libcxx_shrink_to_fit TRACERS none pmemcheck memcheck) + + build_test(vector_libcxx_size libcxx/vector/vector.capacity/size.pass.cpp) + add_test_generic(NAME vector_libcxx_size TRACERS none pmemcheck memcheck) + + build_test(vector_libcxx_swap libcxx/vector/vector.capacity/swap.pass.cpp) + add_test_generic(NAME vector_libcxx_swap TRACERS none pmemcheck memcheck) + + build_test(vector_libcxx_clear libcxx/vector/vector.modifiers/clear.pass.cpp) + add_test_generic(NAME vector_libcxx_clear TRACERS none pmemcheck memcheck) + + build_test(vector_libcxx_emplace libcxx/vector/vector.modifiers/emplace.pass.cpp) + add_test_generic(NAME vector_libcxx_emplace TRACERS none pmemcheck memcheck) + + build_test(vector_libcxx_emplace_back libcxx/vector/vector.modifiers/emplace_back.pass.cpp) + add_test_generic(NAME vector_libcxx_emplace_back TRACERS none pmemcheck memcheck) + + build_test(vector_libcxx_emplace_extra libcxx/vector/vector.modifiers/emplace_extra.pass.cpp) + add_test_generic(NAME vector_libcxx_emplace_extra TRACERS none pmemcheck memcheck) + + build_test(vector_libcxx_erase_iter libcxx/vector/vector.modifiers/erase_iter.pass.cpp) + add_test_generic(NAME vector_libcxx_erase_iter TRACERS none pmemcheck memcheck) + + build_test(vector_libcxx_erase_iter_iter libcxx/vector/vector.modifiers/erase_iter_iter.pass.cpp) + add_test_generic(NAME vector_libcxx_erase_iter_iter TRACERS none pmemcheck memcheck) + + build_test(vector_libcxx_insert_iter_initializer_list libcxx/vector/vector.modifiers/insert_iter_initializer_list.pass.cpp) + add_test_generic(NAME vector_libcxx_insert_iter_initializer_list TRACERS none pmemcheck memcheck) + + build_test(vector_libcxx_insert_iter_iter_iter libcxx/vector/vector.modifiers/insert_iter_iter_iter.pass.cpp) + add_test_generic(NAME vector_libcxx_insert_iter_iter_iter TRACERS none pmemcheck memcheck) + + build_test(vector_libcxx_insert_iter_rvalue libcxx/vector/vector.modifiers/insert_iter_rvalue.pass.cpp) + add_test_generic(NAME vector_libcxx_insert_iter_rvalue TRACERS none pmemcheck memcheck) + + build_test(vector_libcxx_insert_iter_size_value libcxx/vector/vector.modifiers/insert_iter_size_value.pass.cpp) + add_test_generic(NAME vector_libcxx_insert_iter_size_value TRACERS none pmemcheck memcheck) + + build_test(vector_libcxx_insert_iter_value libcxx/vector/vector.modifiers/insert_iter_value.pass.cpp) + add_test_generic(NAME vector_libcxx_insert_iter_value TRACERS none pmemcheck memcheck) + + build_test(vector_libcxx_pop_back libcxx/vector/vector.modifiers/pop_back.pass.cpp) + add_test_generic(NAME vector_libcxx_pop_back TRACERS none pmemcheck memcheck) + + build_test(vector_libcxx_push_back libcxx/vector/vector.modifiers/push_back.pass.cpp) + add_test_generic(NAME vector_libcxx_push_back TRACERS none pmemcheck memcheck) + + # XXX: port libcxx test vector.modifiers/push_back_exception_safety.pass + + build_test(vector_libcxx_push_back_rvalue libcxx/vector/vector.modifiers/push_back_rvalue.pass.cpp) + add_test_generic(NAME vector_libcxx_push_back_rvalue TRACERS none pmemcheck memcheck) + + build_test(vector_libcxx_special_swap libcxx/vector/vector.special/swap.pass.cpp) + add_test_generic(NAME vector_libcxx_special_swap TRACERS none pmemcheck memcheck) +endif() + +if (ENABLE_STRING) + build_test(string_libcxx_cons_initializer_list libcxx/basic_string/string.cons/initializer_list.pass.cpp) + add_test_generic(NAME string_libcxx_cons_initializer_list TRACERS none pmemcheck memcheck) + + build_test(string_libcxx_cons_iter_alloc libcxx/basic_string/string.cons/iter_alloc.pass.cpp) + add_test_generic(NAME string_libcxx_cons_iter_alloc TRACERS none pmemcheck memcheck) + + build_test(string_libcxx_cons_move libcxx/basic_string/string.cons/move.pass.cpp) + add_test_generic(NAME string_libcxx_cons_move TRACERS none pmemcheck memcheck) + + build_test(string_libcxx_cons_pointer_alloc libcxx/basic_string/string.cons/pointer_alloc.pass.cpp) + add_test_generic(NAME string_libcxx_cons_pointer_alloc TRACERS none pmemcheck memcheck) + + build_test(string_libcxx_cons_pointer_size_alloc libcxx/basic_string/string.cons/pointer_size_alloc.pass.cpp) + add_test_generic(NAME string_libcxx_cons_pointer_size_alloc TRACERS none pmemcheck memcheck) + + build_test(string_libcxx_cons_size_char_alloc libcxx/basic_string/string.cons/size_char_alloc.pass.cpp) + add_test_generic(NAME string_libcxx_cons_size_char_alloc TRACERS none pmemcheck memcheck) + + build_test(string_libcxx_cons_copy libcxx/basic_string/string.cons/copy.pass.cpp) + add_test_generic(NAME string_libcxx_cons_copy TRACERS none pmemcheck memcheck) + + build_test(string_libcxx_cons_substr libcxx/basic_string/string.cons/substr.pass.cpp) + add_test_generic(NAME string_libcxx_cons_substr TRACERS none pmemcheck memcheck) + + build_test(string_libcxx_dtor_noexcept libcxx/basic_string/string.cons/dtor_noexcept.pass.cpp) + add_test_generic(NAME string_libcxx_dtor_noexcept TRACERS none) + + build_test(string_libcxx_ops_compare_pointer libcxx/basic_string/string.ops/string_compare/pointer.pass.cpp) + add_test_generic(NAME string_libcxx_ops_compare_pointer TRACERS none pmemcheck memcheck) + + build_test(string_libcxx_ops_compare_size_size_pointer_size libcxx/basic_string/string.ops/string_compare/size_size_pointer_size.pass.cpp) + add_test_generic(NAME string_libcxx_ops_compare_size_size_pointer_size TRACERS none pmemcheck memcheck) + + build_test(string_libcxx_ops_compare_size_size_pointer libcxx/basic_string/string.ops/string_compare/size_size_pointer.pass.cpp) + add_test_generic(NAME string_libcxx_ops_compare_size_size_pointer TRACERS none pmemcheck memcheck) + + build_test(string_libcxx_ops_compare_size_size_string_size_size libcxx/basic_string/string.ops/string_compare/size_size_string_size_size.pass.cpp) + add_test_generic(NAME string_libcxx_ops_compare_size_size_string_size_size TRACERS none pmemcheck memcheck) + + build_test(string_libcxx_ops_compare_size_size_string libcxx/basic_string/string.ops/string_compare/size_size_string.pass.cpp) + add_test_generic(NAME string_libcxx_ops_compare_size_size_string TRACERS none pmemcheck memcheck) + + build_test(string_libcxx_ops_compare_string libcxx/basic_string/string.ops/string_compare/string.pass.cpp) + add_test_generic(NAME string_libcxx_ops_compare_string TRACERS none pmemcheck memcheck) + + build_test(string_libcxx_nonmembers_opne_pointer_string libcxx/basic_string/string.nonmembers/string_opne/pointer_string.pass.cpp) + add_test_generic(NAME string_libcxx_nonmembers_opne_pointer_string TRACERS none pmemcheck memcheck) + + build_test(string_libcxx_nonmembers_opne_string_pointer libcxx/basic_string/string.nonmembers/string_opne/string_pointer.pass.cpp) + add_test_generic(NAME string_libcxx_nonmembers_opne_string_pointer TRACERS none pmemcheck memcheck) + + build_test(string_libcxx_nonmembers_opne_string_string libcxx/basic_string/string.nonmembers/string_opne/string_string.pass.cpp) + add_test_generic(NAME string_libcxx_nonmembers_opne_string_string TRACERS none pmemcheck memcheck) + + build_test(string_libcxx_nonmembers_opeq_pointer_string libcxx/basic_string/string.nonmembers/string_opeq/pointer_string.pass.cpp) + add_test_generic(NAME string_libcxx_nonmembers_opeq_pointer_string TRACERS none pmemcheck memcheck) + + build_test(string_libcxx_nonmembers_opeq_string_pointer libcxx/basic_string/string.nonmembers/string_opeq/string_pointer.pass.cpp) + add_test_generic(NAME string_libcxx_nonmembers_opeq_string_pointer TRACERS none pmemcheck memcheck) + + build_test(string_libcxx_nonmembers_opeq_string_string libcxx/basic_string/string.nonmembers/string_opeq/string_string.pass.cpp) + add_test_generic(NAME string_libcxx_nonmembers_opeq_string_string TRACERS none pmemcheck memcheck) + + build_test(string_libcxx_nonmembers_opgt_pointer_string libcxx/basic_string/string.nonmembers/string_opgt/pointer_string.pass.cpp) + add_test_generic(NAME string_libcxx_nonmembers_opgt_pointer_string TRACERS none pmemcheck memcheck) + + build_test(string_libcxx_nonmembers_opgt_string_pointer libcxx/basic_string/string.nonmembers/string_opgt/string_pointer.pass.cpp) + add_test_generic(NAME string_libcxx_nonmembers_opgt_string_pointer TRACERS none pmemcheck memcheck) + + build_test(string_libcxx_nonmembers_opgt_string_string libcxx/basic_string/string.nonmembers/string_opgt/string_string.pass.cpp) + add_test_generic(NAME string_libcxx_nonmembers_opgt_string_string TRACERS none pmemcheck memcheck) + + build_test(string_libcxx_nonmembers_opge_pointer_string libcxx/basic_string/string.nonmembers/string_opge/pointer_string.pass.cpp) + add_test_generic(NAME string_libcxx_nonmembers_opge_pointer_string TRACERS none pmemcheck memcheck) + + build_test(string_libcxx_nonmembers_opge_string_pointer libcxx/basic_string/string.nonmembers/string_opge/string_pointer.pass.cpp) + add_test_generic(NAME string_libcxx_nonmembers_opge_string_pointer TRACERS none pmemcheck memcheck) + + build_test(string_libcxx_nonmembers_opge_string_string libcxx/basic_string/string.nonmembers/string_opge/string_string.pass.cpp) + add_test_generic(NAME string_libcxx_nonmembers_opge_string_string TRACERS none pmemcheck memcheck) + + build_test(string_libcxx_nonmembers_ople_pointer_string libcxx/basic_string/string.nonmembers/string_ople/pointer_string.pass.cpp) + add_test_generic(NAME string_libcxx_nonmembers_ople_pointer_string TRACERS none pmemcheck memcheck) + + build_test(string_libcxx_nonmembers_ople_string_pointer libcxx/basic_string/string.nonmembers/string_ople/string_pointer.pass.cpp) + add_test_generic(NAME string_libcxx_nonmembers_ople_string_pointer TRACERS none pmemcheck memcheck) + + build_test(string_libcxx_nonmembers_ople_string_string libcxx/basic_string/string.nonmembers/string_ople/string_string.pass.cpp) + add_test_generic(NAME string_libcxx_nonmembers_ople_string_string TRACERS none pmemcheck memcheck) + + build_test(string_libcxx_nonmembers_oplt_pointer_string libcxx/basic_string/string.nonmembers/string_oplt/pointer_string.pass.cpp) + add_test_generic(NAME string_libcxx_nonmembers_oplt_pointer_string TRACERS none pmemcheck memcheck) + + build_test(string_libcxx_nonmembers_oplt_string_pointer libcxx/basic_string/string.nonmembers/string_oplt/string_pointer.pass.cpp) + add_test_generic(NAME string_libcxx_nonmembers_oplt_string_pointer TRACERS none pmemcheck memcheck) + + build_test(string_libcxx_nonmembers_oplt_string_string libcxx/basic_string/string.nonmembers/string_oplt/string_string.pass.cpp) + add_test_generic(NAME string_libcxx_nonmembers_oplt_string_string TRACERS none pmemcheck memcheck) + + # XXX: port libcxx test basic_string/string.starts_with/starts_with.string_view.pass + # XXX: port libcxx test basic_string/string.starts_with/starts_with.ptr.pass + # XXX: port libcxx test basic_string/string.starts_with/starts_with.char.pass + # XXX: port libcxx test basic_string/test_trai + # XXX: port libcxx test basic_string/string.ends_with/ends_with.ptr.pass + # XXX: port libcxx test basic_string/string.ends_with/ends_with.string_view.pass + # XXX: port libcxx test basic_string/string.ends_with/ends_with.char.pass + + build_test(string_libcxx_access_at libcxx/basic_string/string.access/at.pass.cpp) + add_test_generic(NAME string_libcxx_access_at TRACERS none pmemcheck memcheck) + + build_test(string_libcxx_access_back libcxx/basic_string/string.access/back.pass.cpp) + add_test_generic(NAME string_libcxx_access_back TRACERS none pmemcheck memcheck) + + build_test(string_libcxx_access_front libcxx/basic_string/string.access/front.pass.cpp) + add_test_generic(NAME string_libcxx_access_front TRACERS none pmemcheck memcheck) + + build_test(string_libcxx_access_index libcxx/basic_string/string.access/index.pass.cpp) + add_test_generic(NAME string_libcxx_access_index TRACERS none pmemcheck memcheck) + + # XXX: port libcxx test basic_string/string.nonmembers/string_oplt=/string_string_view.pass + # XXX: port libcxx test basic_string/string.nonmembers/string_oplt=/string_view_string.pass + # XXX: port libcxx test basic_string/string.nonmembers/string_operator==/string_string_view.pass + # XXX: port libcxx test basic_string/string.nonmembers/string_operator==/string_view_string.pass + # XXX: port libcxx test basic_string/string.nonmembers/string.special/swap.pass + # XXX: port libcxx test basic_string/string.nonmembers/string.special/swap_noexcept.pass + # XXX: port libcxx test basic_string/string.nonmembers/string.io/stream_extract.pass + # XXX: port libcxx test basic_string/string.nonmembers/string.io/stream_insert.pass + # XXX: port libcxx test basic_string/string.nonmembers/string.io/get_line.pass + # XXX: port libcxx test basic_string/string.nonmembers/string.io/get_line_delim_rv.pass + # XXX: port libcxx test basic_string/string.nonmembers/string.io/get_line_delim.pass + # XXX: port libcxx test basic_string/string.nonmembers/string.io/get_line_rv.pass + # XXX: port libcxx test basic_string/string.nonmembers/string_op+/pointer_string.pass + # XXX: port libcxx test basic_string/string.nonmembers/string_op+/string_pointer.pass + # XXX: port libcxx test basic_string/string.nonmembers/string_op+/char_string.pass + # XXX: port libcxx test basic_string/string.nonmembers/string_op+/string_char.pass + # XXX: port libcxx test basic_string/string.nonmembers/string_op+/string_string.pass + # XXX: port libcxx test basic_string/string.nonmembers/string_oplt/string_string_view.pass + # XXX: port libcxx test basic_string/string.nonmembers/string_oplt/string_view_string.pass + # XXX: port libcxx test basic_string/string.nonmembers/string_op!=/string_string_view.pass + # XXX: port libcxx test basic_string/string.nonmembers/string_op!=/string_view_string.pass + # XXX: port libcxx test basic_string/string.nonmembers/string_opgt/string_string_view.pass + # XXX: port libcxx test basic_string/string.nonmembers/string_opgt/string_view_string.pass + # XXX: port libcxx test basic_string/string.nonmembers/string_opgt=/string_string_view.pass + # XXX: port libcxx test basic_string/string.nonmembers/string_opgt=/string_view_string.pass + # XXX: port libcxx test basic_string/string.ops/string_find.last.of/string_size.pass + # XXX: port libcxx test basic_string/string.ops/string_find.last.of/string_view_size.pass + # XXX: port libcxx test basic_string/string.ops/string_find.last.of/pointer_size.pass + # XXX: port libcxx test basic_string/string.ops/string_find.last.of/char_size.pass + # XXX: port libcxx test basic_string/string.ops/string_find.last.of/pointer_size_size.pass + # XXX: port libcxx test basic_string/string.ops/string_find.last.not.of/string_size.pass + # XXX: port libcxx test basic_string/string.ops/string_find.last.not.of/string_view_size.pass + # XXX: port libcxx test basic_string/string.ops/string_find.last.not.of/pointer_size.pass + # XXX: port libcxx test basic_string/string.ops/string_find.last.not.of/char_size.pass + # XXX: port libcxx test basic_string/string.ops/string_find.last.not.of/pointer_size_size.pass + # XXX: port libcxx test basic_string/string.ops/string_compare/size_size_string_view.pass + # XXX: port libcxx test basic_string/string.ops/string_compare/size_size_T_size_size.pass + # XXX: port libcxx test basic_string/string.ops/string_compare/string_view.pass + # XXX: port libcxx test basic_string/string.ops/string_find.first.not.of/string_size.pass + # XXX: port libcxx test basic_string/string.ops/string_find.first.not.of/string_view_size.pass + # XXX: port libcxx test basic_string/string.ops/string_find.first.not.of/pointer_size.pass + # XXX: port libcxx test basic_string/string.ops/string_find.first.not.of/char_size.pass + # XXX: port libcxx test basic_string/string.ops/string_find.first.not.of/pointer_size_size.pass + # XXX: port libcxx test basic_string/string.ops/string_rfind/string_size.pass + # XXX: port libcxx test basic_string/string.ops/string_rfind/string_view_size.pass + # XXX: port libcxx test basic_string/string.ops/string_rfind/pointer_size.pass + # XXX: port libcxx test basic_string/string.ops/string_rfind/char_size.pass + # XXX: port libcxx test basic_string/string.ops/string_rfind/pointer_size_size.pass + # XXX: port libcxx test basic_string/string.ops/string_find.first.of/string_size.pass + # XXX: port libcxx test basic_string/string.ops/string_find.first.of/string_view_size.pass + # XXX: port libcxx test basic_string/string.ops/string_find.first.of/pointer_size.pass + # XXX: port libcxx test basic_string/string.ops/string_find.first.of/char_size.pass + # XXX: port libcxx test basic_string/string.ops/string_find.first.of/pointer_size_size.pass + # XXX: port libcxx test basic_string/string.ops/string_find/string_size.pass + # XXX: port libcxx test basic_string/string.ops/string_find/string_view_size.pass + # XXX: port libcxx test basic_string/string.ops/string_find/pointer_size.pass + # XXX: port libcxx test basic_string/string.ops/string_find/char_size.pass + # XXX: port libcxx test basic_string/string.ops/string_find/pointer_size_size.pass + # XXX: port libcxx test basic_string/string.ops/string_substr/substr.pass + # XXX: port libcxx test basic_string/string.ops/string.accessors/get_allocator.pass + # XXX: port libcxx test basic_string/string.ops/string.accessors/c_str.pass + # XXX: port libcxx test basic_string/string.ops/string.accessors/data.pass + # XXX: port libcxx test basic_string/types.pass + # XXX: port libcxx test basic_string/traits_mismatch.fail + # XXX: port libcxx test basic_string/string.modifiers/string_swap/swap.pass + # XXX: port libcxx test basic_string/string.modifiers/string_erase/iter_iter.pass + # XXX: port libcxx test basic_string/string.modifiers/string_erase/size_size.pass + # XXX: port libcxx test basic_string/string.modifiers/string_erase/iter.pass + # XXX: port libcxx test basic_string/string.modifiers/string_erase/pop_back.pass + # XXX: port libcxx test basic_string/string.modifiers/string_replace/size_size_size_char.pass + # XXX: port libcxx test basic_string/string.modifiers/string_replace/iter_iter_iter_iter.pass + # XXX: port libcxx test basic_string/string.modifiers/string_replace/size_size_string_size_size.pass + # XXX: port libcxx test basic_string/string.modifiers/string_replace/size_size_string.pass + # XXX: port libcxx test basic_string/string.modifiers/string_replace/size_size_string_view.pass + # XXX: port libcxx test basic_string/string.modifiers/string_replace/size_size_T_size_size.pass + # XXX: port libcxx test basic_string/string.modifiers/string_replace/iter_iter_string_view.pass + # XXX: port libcxx test basic_string/string.modifiers/string_replace/iter_iter_initializer_list.pass + # XXX: port libcxx test basic_string/string.modifiers/string_replace/iter_iter_string.pass + # XXX: port libcxx test basic_string/string.modifiers/string_replace/iter_iter_pointer.pass + # XXX: port libcxx test basic_string/string.modifiers/string_replace/size_size_pointer.pass + # XXX: port libcxx test basic_string/string.modifiers/string_replace/iter_iter_pointer_size.pass + # XXX: port libcxx test basic_string/string.modifiers/string_replace/iter_iter_size_char.pass + # XXX: port libcxx test basic_string/string.modifiers/string_replace/size_size_pointer_size.pass + # XXX: port libcxx test basic_string/string.modifiers/string_op_plus_equal/char.pass + # XXX: port libcxx test basic_string/string.modifiers/string_op_plus_equal/string.pass + # XXX: port libcxx test basic_string/string.modifiers/string_op_plus_equal/initializer_list.pass + # XXX: port libcxx test basic_string/string.modifiers/string_op_plus_equal/pointer.pass + # XXX: port libcxx test basic_string/string.modifiers/string_copy/copy.pass + # XXX: port libcxx test basic_string/string.modifiers/string_append/push_back.pass + # XXX: port libcxx test basic_string/string.modifiers/string_append/iterator.pass + # XXX: port libcxx test basic_string/string.modifiers/string_append/T_size_size.pass + # XXX: port libcxx test basic_string/string.modifiers/string_append/string_size_size.pass + # XXX: port libcxx test basic_string/string.modifiers/string_append/pointer_size.pass + # XXX: port libcxx test basic_string/string.modifiers/string_append/size_char.pass + # XXX: port libcxx test basic_string/string.modifiers/string_append/string_view.pass + # XXX: port libcxx test basic_string/string.modifiers/string_append/string.pass + # XXX: port libcxx test basic_string/string.modifiers/string_append/initializer_list.pass + # XXX: port libcxx test basic_string/string.modifiers/string_append/pointer.pass + # XXX: port libcxx test basic_string/string.modifiers/string_insert/iter_char.pass + # XXX: port libcxx test basic_string/string.modifiers/string_insert/iter_initializer_list.pass + # XXX: port libcxx test basic_string/string.modifiers/string_insert/size_string_size_size.pass + # XXX: port libcxx test basic_string/string.modifiers/string_insert/size_string.pass + # XXX: port libcxx test basic_string/string.modifiers/string_insert/iter_size_char.pass + # XXX: port libcxx test basic_string/string.modifiers/string_insert/size_size_char.pass + # XXX: port libcxx test basic_string/string.modifiers/string_insert/size_pointer.pass + # XXX: port libcxx test basic_string/string.modifiers/string_insert/size_pointer_size.pass + # XXX: port libcxx test basic_string/string.modifiers/string_insert/iter_iter_iter.pass + # XXX: port libcxx test basic_string/string.modifiers/string_insert/string_view.pass + # XXX: port libcxx test basic_string/string.modifiers/string_insert/size_T_size_size.pass + + # XXX: port libcxx test basic_string/string.modifiers/string_assign/T_size_size.pass + # XXX: port libcxx test basic_string/string.modifiers/string_assign/string_view.pass + + build_test(string_libcxx_modifiers_assign_initializer_list libcxx/basic_string/string.modifiers/string_assign/initializer_list.pass.cpp) + add_test_generic(NAME string_libcxx_modifiers_assign_initializer_list TRACERS none pmemcheck memcheck) + + build_test(string_libcxx_modifiers_assign_iterator libcxx/basic_string/string.modifiers/string_assign/iterator.pass.cpp) + add_test_generic(NAME string_libcxx_modifiers_assign_iterator TRACERS none pmemcheck memcheck) + + build_test(string_libcxx_modifiers_assign_pointer libcxx/basic_string/string.modifiers/string_assign/pointer.pass.cpp) + add_test_generic(NAME string_libcxx_modifiers_assign_pointer TRACERS none pmemcheck memcheck) + + build_test(string_libcxx_modifiers_assign_pointer_size libcxx/basic_string/string.modifiers/string_assign/pointer_size.pass.cpp) + add_test_generic(NAME string_libcxx_modifiers_assign_pointer_size TRACERS none pmemcheck memcheck) + + build_test(string_libcxx_modifiers_assign_rv_string libcxx/basic_string/string.modifiers/string_assign/rv_string.pass.cpp) + add_test_generic(NAME string_libcxx_modifiers_assign_rv_string TRACERS none pmemcheck memcheck) + + build_test(string_libcxx_modifiers_assign_size_char libcxx/basic_string/string.modifiers/string_assign/size_char.pass.cpp) + add_test_generic(NAME string_libcxx_modifiers_assign_size_char TRACERS none pmemcheck memcheck) + + build_test(string_libcxx_modifiers_assign_string libcxx/basic_string/string.modifiers/string_assign/string.pass.cpp) + add_test_generic(NAME string_libcxx_modifiers_assign_string TRACERS none pmemcheck memcheck) + + build_test(string_libcxx_modifiers_assign_string_size_size libcxx/basic_string/string.modifiers/string_assign/string_size_size.pass.cpp) + add_test_generic(NAME string_libcxx_modifiers_assign_string_size_size TRACERS none pmemcheck memcheck) + + # XXX: port libcxx test basic_string/string.modifiers/nothing_to_do.pass + # XXX: port libcxx test basic_string/char.bad.fail + # XXX: port libcxx test basic_string/string.iterators/db_iterators_8.pass + # XXX: port libcxx test basic_string/string.iterators/begin.pass + # XXX: port libcxx test basic_string/string.iterators/cbegin.pass + # XXX: port libcxx test basic_string/string.iterators/rend.pass + # XXX: port libcxx test basic_string/string.iterators/cend.pass + # XXX: port libcxx test basic_string/string.iterators/db_iterators_5.pass + # XXX: port libcxx test basic_string/string.iterators/db_iterators_2.pass + # XXX: port libcxx test basic_string/string.iterators/crbegin.pass + # XXX: port libcxx test basic_string/string.iterators/iterators.pass + # XXX: port libcxx test basic_string/string.iterators/db_iterators_7.pass + # XXX: port libcxx test basic_string/string.iterators/db_iterators_3.pass + # XXX: port libcxx test basic_string/string.iterators/rbegin.pass + # XXX: port libcxx test basic_string/string.iterators/db_iterators_4.pass + # XXX: port libcxx test basic_string/string.iterators/crend.pass + # XXX: port libcxx test basic_string/string.iterators/end.pass + # XXX: port libcxx test basic_string/string.iterators/db_iterators_6.pass + # XXX: port libcxx test basic_string/string.require/contiguous.pass + # XXX: port libcxx test basic_string/string.capacity/clear.pass + # XXX: port libcxx test basic_string/string.capacity/resize_size.pass + # XXX: port libcxx test basic_string/string.capacity/size.pass + # XXX: port libcxx test basic_string/string.capacity/length.pass + # XXX: port libcxx test basic_string/string.capacity/reserve.pass + # XXX: port libcxx test basic_string/string.capacity/capacity.pass + # XXX: port libcxx test basic_string/string.capacity/shrink_to_fit.pass + # XXX: port libcxx test basic_string/string.capacity/empty.fail + # XXX: port libcxx test basic_string/string.capacity/empty.pass + # XXX: port libcxx test basic_string/string.capacity/resize_size_char.pass + # XXX: port libcxx test basic_string/string.capacity/max_size.pass + # XXX: port libcxx test basic_string/string.capacity/over_max_size.pass + # XXX: port libcxx test basic_string/string.cons/string_view_assignment.pass + # XXX: port libcxx test basic_string/string.cons/T_size_size.pass + + build_test(string_libcxx_brace_assignment libcxx/basic_string/string.cons/brace_assignment.pass.cpp) + add_test_generic(NAME string_libcxx_brace_assignment TRACERS none pmemcheck memcheck) + + build_test(string_libcxx_char_assignment libcxx/basic_string/string.cons/char_assignment.pass.cpp) + add_test_generic(NAME string_libcxx_char_assignment TRACERS none pmemcheck memcheck) + + build_test(string_libcxx_copy_assignment libcxx/basic_string/string.cons/copy_assignment.pass.cpp) + add_test_generic(NAME string_libcxx_copy_assignment TRACERS none pmemcheck memcheck) + + build_test(string_libcxx_initializer_list_assignment libcxx/basic_string/string.cons/initializer_list_assignment.pass.cpp) + add_test_generic(NAME string_libcxx_initializer_list_assignment TRACERS none pmemcheck memcheck) + + build_test(string_libcxx_move_assignment libcxx/basic_string/string.cons/move_assignment.pass.cpp) + add_test_generic(NAME string_libcxx_move_assignment TRACERS none pmemcheck memcheck) + + build_test(string_libcxx_pointer_assignment libcxx/basic_string/string.cons/pointer_assignment.pass.cpp) + add_test_generic(NAME string_libcxx_pointer_assignment TRACERS none pmemcheck memcheck) + + # XXX: port libcxx test basic_string/string.cons/string_view.pass + # XXX: port libcxx test basic_string/string.cons/initializer_list_assignment.pass + # XXX: port libcxx test basic_string/string.cons/string_view.fail +endif() diff --git a/tests/external/libcxx/CREDITS.TXT b/tests/external/libcxx/CREDITS.TXT new file mode 100644 index 0000000..0ba0bbc --- /dev/null +++ b/tests/external/libcxx/CREDITS.TXT @@ -0,0 +1,153 @@ +This file was copied from libcxx and applies to upstream libcxx contributions. +------------------------------------------------------------------------------- + +This file is a partial list of people who have contributed to the LLVM/libc++ +project. If you have contributed a patch or made some other contribution to +LLVM/libc++, please submit a patch to this file to add yourself, and it will be +done! + +The list is sorted by surname and formatted to allow easy grepping and +beautification by scripts. The fields are: name (N), email (E), web-address +(W), PGP key ID and fingerprint (P), description (D), and snail-mail address +(S). + +N: Saleem Abdulrasool +E: compnerd@compnerd.org +D: Minor patches and Linux fixes. + +N: Dan Albert +E: danalbert@google.com +D: Android support and test runner improvements. + +N: Dimitry Andric +E: dimitry@andric.com +D: Visibility fixes, minor FreeBSD portability patches. + +N: Holger Arnold +E: holgerar@gmail.com +D: Minor fix. + +N: Ruben Van Boxem +E: vanboxem dot ruben at gmail dot com +D: Initial Windows patches. + +N: David Chisnall +E: theraven at theravensnest dot org +D: FreeBSD and Solaris ports, libcxxrt support, some atomics work. + +N: Marshall Clow +E: mclow.lists@gmail.com +E: marshall@idio.com +D: C++14 support, patches and bug fixes. + +N: Jonathan B Coe +E: jbcoe@me.com +D: Implementation of propagate_const. + +N: Glen Joseph Fernandes +E: glenjofe@gmail.com +D: Implementation of to_address. + +N: Eric Fiselier +E: eric@efcs.ca +D: LFTS support, patches and bug fixes. + +N: Bill Fisher +E: william.w.fisher@gmail.com +D: Regex bug fixes. + +N: Matthew Dempsky +E: matthew@dempsky.org +D: Minor patches and bug fixes. + +N: Google Inc. +D: Copyright owner and contributor of the CityHash algorithm + +N: Howard Hinnant +E: hhinnant@apple.com +D: Architect and primary author of libc++ + +N: Hyeon-bin Jeong +E: tuhertz@gmail.com +D: Minor patches and bug fixes. + +N: Argyrios Kyrtzidis +E: kyrtzidis@apple.com +D: Bug fixes. + +N: Bruce Mitchener, Jr. +E: bruce.mitchener@gmail.com +D: Emscripten-related changes. + +N: Michel Morin +E: mimomorin@gmail.com +D: Minor patches to is_convertible. + +N: Andrew Morrow +E: andrew.c.morrow@gmail.com +D: Minor patches and Linux fixes. + +N: Michael Park +E: mcypark@gmail.com +D: Implementation of . + +N: Arvid Picciani +E: aep at exys dot org +D: Minor patches and musl port. + +N: Bjorn Reese +E: breese@users.sourceforge.net +D: Initial regex prototype + +N: Nico Rieck +E: nico.rieck@gmail.com +D: Windows fixes + +N: Jon Roelofs +E: jroelofS@jroelofs.com +D: Remote testing, Newlib port, baremetal/single-threaded support. + +N: Jonathan Sauer +D: Minor patches, mostly related to constexpr + +N: Craig Silverstein +E: csilvers@google.com +D: Implemented Cityhash as the string hash function on 64-bit machines + +N: Richard Smith +D: Minor patches. + +N: Joerg Sonnenberger +E: joerg@NetBSD.org +D: NetBSD port. + +N: Stephan Tolksdorf +E: st@quanttec.com +D: Minor fix + +N: Michael van der Westhuizen +E: r1mikey at gmail dot com + +N: Larisse Voufo +D: Minor patches. + +N: Klaas de Vries +E: klaas at klaasgaaf dot nl +D: Minor bug fix. + +N: Zhang Xiongpang +E: zhangxiongpang@gmail.com +D: Minor patches and bug fixes. + +N: Xing Xue +E: xingxue@ca.ibm.com +D: AIX port + +N: Zhihao Yuan +E: lichray@gmail.com +D: Standard compatibility fixes. + +N: Jeffrey Yasskin +E: jyasskin@gmail.com +E: jyasskin@google.com +D: Linux fixes. diff --git a/tests/external/libcxx/LICENSE.TXT b/tests/external/libcxx/LICENSE.TXT new file mode 100644 index 0000000..c278f2c --- /dev/null +++ b/tests/external/libcxx/LICENSE.TXT @@ -0,0 +1,76 @@ +============================================================================== +libc++ License +============================================================================== + +The libc++ library is dual licensed under both the University of Illinois +"BSD-Like" license and the MIT license. As a user of this code you may choose +to use it under either license. As a contributor, you agree to allow your code +to be used under both. + +Full text of the relevant licenses is included below. + +============================================================================== + +University of Illinois/NCSA +Open Source License + +Copyright (c) 2009-2017 by the contributors listed in CREDITS.TXT + +All rights reserved. + +Developed by: + + LLVM Team + + University of Illinois at Urbana-Champaign + + http://llvm.org + +Permission is hereby granted, free of charge, to any person obtaining a copy of +this software and associated documentation files (the "Software"), to deal with +the Software without restriction, including without limitation the rights to +use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies +of the Software, and to permit persons to whom the Software is furnished to do +so, subject to the following conditions: + + * Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimers. + + * Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimers in the + documentation and/or other materials provided with the distribution. + + * Neither the names of the LLVM Team, University of Illinois at + Urbana-Champaign, nor the names of its contributors may be used to + endorse or promote products derived from this Software without specific + prior written permission. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS +FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS WITH THE +SOFTWARE. + +============================================================================== + +Copyright (c) 2009-2014 by the contributors listed in CREDITS.TXT + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. diff --git a/tests/external/libcxx/README.md b/tests/external/libcxx/README.md new file mode 100644 index 0000000..54e40dc --- /dev/null +++ b/tests/external/libcxx/README.md @@ -0,0 +1,5 @@ +This directory contains tests copied from https://github.com/llvm-mirror/libcxx +and modified to test pmem::obj containers. + +For information on how these tests are licensed, see LICENSE.txt file in this +directory. diff --git a/tests/external/libcxx/array/array.cons/copy_assignment.fail.cpp b/tests/external/libcxx/array/array.cons/copy_assignment.fail.cpp new file mode 100644 index 0000000..53fe93e --- /dev/null +++ b/tests/external/libcxx/array/array.cons/copy_assignment.fail.cpp @@ -0,0 +1,79 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// Copyright 2018, Intel Corporation +// +// Modified to test pmem::obj containers +// + +#include "unittest.hpp" + +#include +#include +#include +#include +#include + +namespace pmem_exp = pmem::obj::experimental; + +struct Testcase1 { + typedef double T; + typedef pmem_exp::array C; + C c = {{1.1, 2.2, 3.3}}, c2 = {{1, 2, 3}}; + + void + run() + { + c2 = c; + } +}; + +struct root { + pmem::obj::persistent_ptr r1; +}; + +void +run(pmem::obj::pool &pop) +{ + try { + pmem::obj::transaction::run(pop, [&] { + pop.root()->r1 = + pmem::obj::make_persistent(); + }); + + /* Should work outside transaction */ + pop.root()->r1->run(); + } catch (...) { + UT_ASSERT(0); + } +} + +int +main(int argc, char *argv[]) +{ + START(); + + if (argc != 2) + UT_FATAL("usage: %s file-name", argv[0]); + + const char *path = argv[1]; + + pmem::obj::pool pop; + try { + pop = pmem::obj::pool::create( + path, "copy_assignment.pass", PMEMOBJ_MIN_POOL, + S_IWUSR | S_IRUSR); + } catch (...) { + UT_FATAL("!pmemobj_create: %s", path); + } + + run(pop); + + return 0; +} diff --git a/tests/external/libcxx/array/array.cons/default.pass.cpp b/tests/external/libcxx/array/array.cons/default.pass.cpp new file mode 100644 index 0000000..4645409 --- /dev/null +++ b/tests/external/libcxx/array/array.cons/default.pass.cpp @@ -0,0 +1,121 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// Copyright 2018, Intel Corporation +// +// Modified to test pmem::obj containers +// + +#include "unittest.hpp" + +#include +#include +#include +#include +#include + +namespace pmem_exp = pmem::obj::experimental; + +struct NoDefault { + NoDefault(int) + { + } +}; + +struct Testcase1 { + typedef double T; + typedef pmem_exp::array C; + C c; + + void + run() + { + UT_ASSERT(c.size() == 3); + } +}; + +struct Testcase2 { + typedef double T; + typedef pmem_exp::array C; + C c; + + void + run() + { + UT_ASSERT(c.size() == 0); + } +}; + +struct Testcase3 { + typedef pmem_exp::array C; + C c; + C c1 = {}; + C c2 = {{}}; + + void + run() + { + UT_ASSERT(c.size() == 0); + UT_ASSERT(c1.size() == 0); + UT_ASSERT(c2.size() == 0); + } +}; + +struct root { + pmem::obj::persistent_ptr r1; + pmem::obj::persistent_ptr r2; + pmem::obj::persistent_ptr r3; +}; + +void +run(pmem::obj::pool &pop) +{ + try { + pmem::obj::transaction::run(pop, [&] { + pop.root()->r1 = + pmem::obj::make_persistent(); + pop.root()->r2 = + pmem::obj::make_persistent(); + pop.root()->r3 = + pmem::obj::make_persistent(); + }); + + pmem::obj::transaction::run(pop, [&] { + pop.root()->r1->run(); + pop.root()->r2->run(); + pop.root()->r3->run(); + }); + } catch (...) { + UT_ASSERT(0); + } +} + +int +main(int argc, char *argv[]) +{ + START(); + + if (argc != 2) + UT_FATAL("usage: %s file-name", argv[0]); + + const char *path = argv[1]; + + pmem::obj::pool pop; + try { + pop = pmem::obj::pool::create(path, "default.pass", + PMEMOBJ_MIN_POOL, + S_IWUSR | S_IRUSR); + } catch (...) { + UT_FATAL("!pmemobj_create: %s", path); + } + + run(pop); + + return 0; +} diff --git a/tests/external/libcxx/array/array.cons/implicit_copy.pass.cpp b/tests/external/libcxx/array/array.cons/implicit_copy.pass.cpp new file mode 100644 index 0000000..4367789 --- /dev/null +++ b/tests/external/libcxx/array/array.cons/implicit_copy.pass.cpp @@ -0,0 +1,184 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// Copyright 2018, Intel Corporation +// +// Modified to test pmem::obj containers +// + +#include "unittest.hpp" + +#include +#include +#include +#include +#include + +namespace pmem_exp = pmem::obj::experimental; + +struct NoDefault { + NoDefault(int) + { + } +}; + +struct Testcase1 { + typedef double T; + typedef pmem_exp::array C; + C c = {{1.1, 2.2, 3.3}}; + C c2 = c; + C c3, c4; + + Testcase1() : c3(c), c4(std::move(c3)) + { + } + + void + run() + { + c2 = c; + static_assert(std::is_copy_constructible::value, ""); + static_assert(std::is_copy_assignable::value, ""); + } +}; + +struct Testcase2 { + typedef double T; + typedef pmem_exp::array C; + C c = {{1.1, 2.2, 3.3}}; + C c2 = c; + + void + run() + { + ((void)c2); + static_assert(std::is_copy_constructible::value, ""); + } +}; + +struct Testcase3 { + typedef double T; + typedef pmem_exp::array C; + C c = {{}}; + C c2 = c; + void + run() + { + c2 = c; + static_assert(std::is_copy_constructible::value, ""); + static_assert(std::is_copy_assignable::value, ""); + } +}; + +struct Testcase4 { + // const arrays of size 0 should disable the implicit copy + // assignment operator. + typedef double T; + typedef pmem_exp::array C; + C c = {{}}; + C c2 = c; + + void + run() + { + ((void)c2); + static_assert(std::is_copy_constructible::value, ""); + } +}; + +struct Testcase5 { + typedef NoDefault T; + typedef pmem_exp::array C; + C c = {{}}; + C c2 = c; + + void + run() + { + c2 = c; + static_assert(std::is_copy_constructible::value, ""); + static_assert(std::is_copy_assignable::value, ""); + } +}; + +struct Testcase6 { + typedef NoDefault T; + typedef pmem_exp::array C; + C c = {{}}; + C c2 = c; + void + run() + { + ((void)c2); + static_assert(std::is_copy_constructible::value, ""); + } +}; + +struct root { + pmem::obj::persistent_ptr r1; + pmem::obj::persistent_ptr r2; + pmem::obj::persistent_ptr r3; + pmem::obj::persistent_ptr r4; + pmem::obj::persistent_ptr r5; + pmem::obj::persistent_ptr r6; +}; + +void +run(pmem::obj::pool &pop) +{ + try { + pmem::obj::transaction::run(pop, [&] { + pop.root()->r1 = + pmem::obj::make_persistent(); + pop.root()->r2 = + pmem::obj::make_persistent(); + pop.root()->r3 = + pmem::obj::make_persistent(); + pop.root()->r4 = + pmem::obj::make_persistent(); + pop.root()->r5 = + pmem::obj::make_persistent(); + pop.root()->r6 = + pmem::obj::make_persistent(); + }); + + pop.root()->r1->run(); + pop.root()->r2->run(); + pop.root()->r3->run(); + pop.root()->r4->run(); + pop.root()->r5->run(); + pop.root()->r6->run(); + } catch (...) { + UT_ASSERT(0); + } +} + +int +main(int argc, char *argv[]) +{ + START(); + + if (argc != 2) + UT_FATAL("usage: %s file-name", argv[0]); + + const char *path = argv[1]; + + pmem::obj::pool pop; + try { + pop = pmem::obj::pool::create(path, "implicit_copy.pass", + PMEMOBJ_MIN_POOL, + S_IWUSR | S_IRUSR); + } catch (...) { + UT_FATAL("!pmemobj_create: %s", path); + } + + run(pop); + + return 0; +} diff --git a/tests/external/libcxx/array/array.cons/initializer_list.pass.cpp b/tests/external/libcxx/array/array.cons/initializer_list.pass.cpp new file mode 100644 index 0000000..dea7ccf --- /dev/null +++ b/tests/external/libcxx/array/array.cons/initializer_list.pass.cpp @@ -0,0 +1,133 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// Copyright 2018, Intel Corporation +// +// Modified to test pmem::obj containers +// + +#include "unittest.hpp" + +#include +#include +#include +#include +#include + +namespace pmem_exp = pmem::obj::experimental; + +struct Testcase1 { + typedef double T; + typedef pmem_exp::array C; + C c = {{1, 2, 3.5}}; + + void + run() + { + UT_ASSERT(c.size() == 3); + UT_ASSERT(c[0] == 1); + UT_ASSERT(c[1] == 2); + UT_ASSERT(c[2] == 3.5); + } +}; + +struct Testcase2 { + typedef double T; + typedef pmem_exp::array C; + C c = {{}}; + + void + run() + { + UT_ASSERT(c.size() == 0); + } +}; + +struct Testcase3 { + typedef double T; + typedef pmem_exp::array C; + C c = {{1}}; + + void + run() + { + UT_ASSERT(c.size() == 3.0); + UT_ASSERT(c[0] == 1); + } +}; + +struct Testcase4 { + typedef int T; + typedef pmem_exp::array C; + C c = {{}}; + + void + run() + { + UT_ASSERT(c.size() == 1); + } +}; + +struct root { + pmem::obj::persistent_ptr r1; + pmem::obj::persistent_ptr r2; + pmem::obj::persistent_ptr r3; + pmem::obj::persistent_ptr r4; +}; + +void +run(pmem::obj::pool &pop) +{ + try { + pmem::obj::transaction::run(pop, [&] { + pop.root()->r1 = + pmem::obj::make_persistent(); + pop.root()->r2 = + pmem::obj::make_persistent(); + pop.root()->r3 = + pmem::obj::make_persistent(); + pop.root()->r4 = + pmem::obj::make_persistent(); + }); + + /* XXX: operator[] needs transaction */ + pmem::obj::transaction::run(pop, [&] { + pop.root()->r1->run(); + pop.root()->r2->run(); + pop.root()->r3->run(); + pop.root()->r4->run(); + }); + } catch (...) { + UT_ASSERT(0); + } +} + +int +main(int argc, char *argv[]) +{ + START(); + + if (argc != 2) + UT_FATAL("usage: %s file-name", argv[0]); + + const char *path = argv[1]; + + pmem::obj::pool pop; + try { + pop = pmem::obj::pool::create( + path, "initializer_list.pass", PMEMOBJ_MIN_POOL, + S_IWUSR | S_IRUSR); + } catch (...) { + UT_FATAL("!pmemobj_create: %s", path); + } + + run(pop); + + return 0; +} diff --git a/tests/external/libcxx/array/array.data/data.pass.cpp b/tests/external/libcxx/array/array.data/data.pass.cpp new file mode 100644 index 0000000..83bd5c2 --- /dev/null +++ b/tests/external/libcxx/array/array.data/data.pass.cpp @@ -0,0 +1,133 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// Copyright 2018, Intel Corporation +// +// Modified to test pmem::obj containers +// + +#include "unittest.hpp" +#include + +#include +#include +#include +#include +#include + +namespace pmem_exp = pmem::obj::experimental; + +struct Testcase1 { + typedef double T; + typedef pmem_exp::array C; + C c = {{1, 2, 3.5}}; + + void + run() + { + T *p = c.data(); + UT_ASSERT(p[0] == 1); + UT_ASSERT(p[1] == 2); + UT_ASSERT(p[2] == 3.5); + + const T *cp = c.cdata(); + UT_ASSERT(cp[0] == 1); + UT_ASSERT(cp[1] == 2); + UT_ASSERT(cp[2] == 3.5); + } +}; + +struct Testcase2 { + typedef double T; + typedef pmem_exp::array C; + C c = {{}}; + + void + run() + { + static_assert( + (std::is_same::value), + ""); + + static_assert( + (std::is_same::value), + ""); + } +}; + +struct Testcase3 { + typedef std::max_align_t T; + typedef pmem_exp::array C; + const C c = {{}}; + C cc = {{}}; + + void + run() + { + const T *p = c.data(); + std::uintptr_t pint = reinterpret_cast(p); + UT_ASSERT(pint % alignof(std::max_align_t) == 0); + + const T *cp = cc.cdata(); + std::uintptr_t cpint = reinterpret_cast(cp); + UT_ASSERT(cpint % alignof(std::max_align_t) == 0); + } +}; + +struct root { + pmem::obj::persistent_ptr r1; + pmem::obj::persistent_ptr r2; + pmem::obj::persistent_ptr r3; +}; + +void +run(pmem::obj::pool &pop) +{ + try { + pmem::obj::transaction::run(pop, [&] { + pop.root()->r1 = + pmem::obj::make_persistent(); + pop.root()->r2 = + pmem::obj::make_persistent(); + pop.root()->r3 = + pmem::obj::make_persistent(); + }); + + pmem::obj::transaction::run(pop, [&] { + pop.root()->r1->run(); + pop.root()->r2->run(); + pop.root()->r3->run(); + }); + } catch (...) { + UT_ASSERT(0); + } +} + +int +main(int argc, char *argv[]) +{ + START(); + + if (argc != 2) + UT_FATAL("usage: %s file-name", argv[0]); + + const char *path = argv[1]; + + pmem::obj::pool pop; + try { + pop = pmem::obj::pool::create( + path, "data.pass", PMEMOBJ_MIN_POOL, S_IWUSR | S_IRUSR); + } catch (...) { + UT_FATAL("!pmemobj_create: %s", path); + } + + run(pop); + + return 0; +} diff --git a/tests/external/libcxx/array/array.data/data_const.pass.cpp b/tests/external/libcxx/array/array.data/data_const.pass.cpp new file mode 100644 index 0000000..a744819 --- /dev/null +++ b/tests/external/libcxx/array/array.data/data_const.pass.cpp @@ -0,0 +1,119 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// Copyright 2018, Intel Corporation +// +// Modified to test pmem::obj containers +// + +#include "unittest.hpp" +#include + +#include +#include +#include +#include +#include + +namespace pmem_exp = pmem::obj::experimental; + +struct Testcase1 { + typedef double T; + typedef pmem_exp::array C; + const C c = {{1, 2, 3.5}}; + C cc = {{1, 2, 3.5}}; + + void + run() + { + { + const T *p = c.data(); + UT_ASSERT(p[0] == 1); + UT_ASSERT(p[1] == 2); + UT_ASSERT(p[2] == 3.5); + } + { + const T *p = cc.cdata(); + UT_ASSERT(p[0] == 1); + UT_ASSERT(p[1] == 2); + UT_ASSERT(p[2] == 3.5); + } + } +}; + +struct Testcase2 { + typedef std::max_align_t T; + typedef pmem_exp::array C; + const C c = {{}}; + C cc = {{}}; + + void + run() + { + { + const T *p = cc.cdata(); + std::uintptr_t pint = + reinterpret_cast(p); + UT_ASSERT(pint % alignof(std::max_align_t) == 0); + } + { + const T *p = cc.cdata(); + std::uintptr_t pint = + reinterpret_cast(p); + UT_ASSERT(pint % alignof(std::max_align_t) == 0); + } + } +}; + +struct root { + pmem::obj::persistent_ptr r1; + pmem::obj::persistent_ptr r2; +}; + +void +run(pmem::obj::pool &pop) +{ + try { + pmem::obj::transaction::run(pop, [&] { + pop.root()->r1 = + pmem::obj::make_persistent(); + pop.root()->r2 = + pmem::obj::make_persistent(); + }); + + pop.root()->r1->run(); + pop.root()->r2->run(); + } catch (...) { + UT_ASSERT(0); + } +} + +int +main(int argc, char *argv[]) +{ + START(); + + if (argc != 2) + UT_FATAL("usage: %s file-name", argv[0]); + + const char *path = argv[1]; + + pmem::obj::pool pop; + try { + pop = pmem::obj::pool::create(path, "data_const.pass", + PMEMOBJ_MIN_POOL, + S_IWUSR | S_IRUSR); + } catch (...) { + UT_FATAL("!pmemobj_create: %s", path); + } + + run(pop); + + return 0; +} diff --git a/tests/external/libcxx/array/array.fill/fill.fail.cpp b/tests/external/libcxx/array/array.fill/fill.fail.cpp new file mode 100644 index 0000000..6e8f188 --- /dev/null +++ b/tests/external/libcxx/array/array.fill/fill.fail.cpp @@ -0,0 +1,36 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// Copyright 2018, Intel Corporation +// +// Modified to test pmem::obj containers +// + +#include "unittest.hpp" + +#include + +namespace pmem_exp = pmem::obj::experimental; + +int +main() +{ + { + START(); + + typedef double T; + typedef pmem_exp::array C; + C c = {{}}; + // expected-error-re@array:* {{static_assert failed + // {{.*}}"cannot fill zero-sized array of type 'const T'"}} + c.fill(5.5); // expected-note {{requested here}} + } + + return 0; +} diff --git a/tests/external/libcxx/array/array.fill/fill.pass.cpp b/tests/external/libcxx/array/array.fill/fill.pass.cpp new file mode 100644 index 0000000..37edac5 --- /dev/null +++ b/tests/external/libcxx/array/array.fill/fill.pass.cpp @@ -0,0 +1,100 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// Copyright 2018, Intel Corporation +// +// Modified to test pmem::obj containers +// + +#include "unittest.hpp" + +#include +#include +#include +#include +#include + +namespace pmem_exp = pmem::obj::experimental; + +struct Testcase1 { + typedef double T; + typedef pmem_exp::array C; + C c = {{1, 2, 3.5}}; + + void + run() + { + c.fill(5.5); + UT_ASSERT(c.size() == 3); + UT_ASSERT(c[0] == 5.5); + UT_ASSERT(c[1] == 5.5); + UT_ASSERT(c[2] == 5.5); + } +}; + +struct Testcase2 { + typedef double T; + typedef pmem_exp::array C; + C c = {{}}; + + void + run() + { + c.fill(5.5); + UT_ASSERT(c.size() == 0); + } +}; + +struct root { + pmem::obj::persistent_ptr r1; + pmem::obj::persistent_ptr r2; +}; + +void +run(pmem::obj::pool &pop) +{ + try { + pmem::obj::transaction::run(pop, [&] { + pop.root()->r1 = + pmem::obj::make_persistent(); + pop.root()->r2 = + pmem::obj::make_persistent(); + }); + + pmem::obj::transaction::run(pop, [&] { + pop.root()->r1->run(); + pop.root()->r2->run(); + }); + } catch (...) { + UT_ASSERT(0); + } +} + +int +main(int argc, char *argv[]) +{ + START(); + + if (argc != 2) + UT_FATAL("usage: %s file-name", argv[0]); + + const char *path = argv[1]; + + pmem::obj::pool pop; + try { + pop = pmem::obj::pool::create( + path, "fill.pass", PMEMOBJ_MIN_POOL, S_IWUSR | S_IRUSR); + } catch (...) { + UT_FATAL("!pmemobj_create: %s", path); + } + + run(pop); + + return 0; +} diff --git a/tests/external/libcxx/array/array.size/size.pass.cpp b/tests/external/libcxx/array/array.size/size.pass.cpp new file mode 100644 index 0000000..f7f738b --- /dev/null +++ b/tests/external/libcxx/array/array.size/size.pass.cpp @@ -0,0 +1,99 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// Copyright 2018, Intel Corporation +// +// Modified to test pmem::obj containers +// + +#include "unittest.hpp" + +#include +#include +#include +#include +#include + +namespace pmem_exp = pmem::obj::experimental; + +struct Testcase1 { + typedef double T; + typedef pmem_exp::array C; + C c = {{1, 2, 3.5}}; + + void + run() + { + UT_ASSERT(c.size() == 3); + UT_ASSERT(c.max_size() == 3); + UT_ASSERT(!c.empty()); + } +}; + +struct Testcase2 { + typedef double T; + typedef pmem_exp::array C; + C c = {{}}; + + void + run() + { + UT_ASSERT(c.size() == 0); + UT_ASSERT(c.max_size() == 0); + UT_ASSERT(c.empty()); + } +}; + +struct root { + pmem::obj::persistent_ptr r1; + pmem::obj::persistent_ptr r2; +}; + +void +run(pmem::obj::pool &pop) +{ + try { + pmem::obj::transaction::run(pop, [&] { + pop.root()->r1 = + pmem::obj::make_persistent(); + pop.root()->r2 = + pmem::obj::make_persistent(); + }); + + pmem::obj::transaction::run(pop, [&] { + pop.root()->r1->run(); + pop.root()->r2->run(); + }); + } catch (...) { + UT_ASSERT(0); + } +} + +int +main(int argc, char *argv[]) +{ + START(); + + if (argc != 2) + UT_FATAL("usage: %s file-name", argv[0]); + + const char *path = argv[1]; + + pmem::obj::pool pop; + try { + pop = pmem::obj::pool::create( + path, "size.pass", PMEMOBJ_MIN_POOL, S_IWUSR | S_IRUSR); + } catch (...) { + UT_FATAL("!pmemobj_create: %s", path); + } + + run(pop); + + return 0; +} diff --git a/tests/external/libcxx/array/array.special/swap.pass.cpp b/tests/external/libcxx/array/array.special/swap.pass.cpp new file mode 100644 index 0000000..acaebd1 --- /dev/null +++ b/tests/external/libcxx/array/array.special/swap.pass.cpp @@ -0,0 +1,147 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// Copyright 2018, Intel Corporation +// +// Modified to test pmem::obj containers +// + +#include "unittest.hpp" + +#include +#include +#include +#include +#include + +namespace pmem_exp = pmem::obj::experimental; + +struct NonSwappable { + NonSwappable() + { + } + +private: + NonSwappable(NonSwappable const &); + NonSwappable &operator=(NonSwappable const &); +}; + +using pmem_exp::swap; + +template +decltype(swap(std::declval(), std::declval())) can_swap_imp(int); + +template +std::false_type can_swap_imp(...); + +template +struct can_swap : std::is_same(0)), void> { +}; + +struct Testcase1 { + typedef double T; + typedef pmem_exp::array C; + C c1 = {{1, 2, 3.5}}; + C c2 = {{4, 5, 6.5}}; + + void + run() + { + swap(c1, c2); + UT_ASSERT(c1.size() == 3); + UT_ASSERT(c1[0] == 4); + UT_ASSERT(c1[1] == 5); + UT_ASSERT(c1[2] == 6.5); + UT_ASSERT(c2.size() == 3); + UT_ASSERT(c2[0] == 1); + UT_ASSERT(c2[1] == 2); + UT_ASSERT(c2[2] == 3.5); + } +}; + +struct Testcase2 { + typedef double T; + typedef pmem_exp::array C; + C c1 = {{}}; + C c2 = {{}}; + + void + run() + { + swap(c1, c2); + UT_ASSERT(c1.size() == 0); + UT_ASSERT(c2.size() == 0); + } +}; + +struct Testcase3 { + typedef NonSwappable T; + typedef pmem_exp::array C0; + static_assert(can_swap::value, ""); + C0 l = {{}}; + C0 r = {{}}; + + void + run() + { + swap(l, r); + } +}; + +struct root { + pmem::obj::persistent_ptr r1; + pmem::obj::persistent_ptr r2; + pmem::obj::persistent_ptr r3; +}; + +void +run(pmem::obj::pool &pop) +{ + try { + pmem::obj::transaction::run(pop, [&] { + pop.root()->r1 = + pmem::obj::make_persistent(); + pop.root()->r2 = + pmem::obj::make_persistent(); + pop.root()->r3 = + pmem::obj::make_persistent(); + }); + + pmem::obj::transaction::run(pop, [&] { + pop.root()->r1->run(); + pop.root()->r2->run(); + pop.root()->r3->run(); + }); + } catch (...) { + UT_ASSERT(0); + } +} + +int +main(int argc, char *argv[]) +{ + START(); + + if (argc != 2) + UT_FATAL("usage: %s file-name", argv[0]); + + const char *path = argv[1]; + + pmem::obj::pool pop; + try { + pop = pmem::obj::pool::create( + path, "swap.pass", PMEMOBJ_MIN_POOL, S_IWUSR | S_IRUSR); + } catch (...) { + UT_FATAL("!pmemobj_create: %s", path); + } + + run(pop); + + return 0; +} diff --git a/tests/external/libcxx/array/array.swap/swap.fail.cpp b/tests/external/libcxx/array/array.swap/swap.fail.cpp new file mode 100644 index 0000000..a786cbe --- /dev/null +++ b/tests/external/libcxx/array/array.swap/swap.fail.cpp @@ -0,0 +1,40 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// Copyright 2018, Intel Corporation +// +// Modified to test pmem::obj containers +// + +#include "unittest.hpp" + +#include + +namespace pmem_exp = pmem::obj::experimental; + +using pmem_exp::swap; + +int +main() +{ + START(); + + { + + typedef double T; + typedef pmem_exp::array C; + C c = {{}}; + C c2 = {{}}; + // expected-error-re@array:* {{static_assert failed + // {{.*}}"cannot swap zero-sized array of type 'const T'"}} + c.swap(c2); // expected-note {{requested here}} + } + + return 0; +} diff --git a/tests/external/libcxx/array/array.swap/swap.pass.cpp b/tests/external/libcxx/array/array.swap/swap.pass.cpp new file mode 100644 index 0000000..6b5f84e --- /dev/null +++ b/tests/external/libcxx/array/array.swap/swap.pass.cpp @@ -0,0 +1,179 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// Copyright 2018, Intel Corporation +// +// Modified to test pmem::obj containers +// + +#include "unittest.hpp" + +#include +#include +#include +#include +#include + +namespace pmem_exp = pmem::obj::experimental; + +using pmem_exp::swap; + +struct NonSwappable { + NonSwappable() + { + } + +private: + NonSwappable(NonSwappable const &); + NonSwappable &operator=(NonSwappable const &); +}; + +struct Testcase1 { + typedef double T; + typedef pmem_exp::array C; + C c1 = {{1, 2, 3.5}}; + C c2 = {{4, 5, 6.5}}; + + void + run() + { + c1.swap(c2); + UT_ASSERT(c1.size() == 3); + UT_ASSERT(c1[0] == 4); + UT_ASSERT(c1[1] == 5); + UT_ASSERT(c1[2] == 6.5); + UT_ASSERT(c2.size() == 3); + UT_ASSERT(c2[0] == 1); + UT_ASSERT(c2[1] == 2); + UT_ASSERT(c2[2] == 3.5); + } +}; + +struct Testcase2 { + typedef double T; + typedef pmem_exp::array C; + C c1 = {{1, 2, 3.5}}; + C c2 = {{4, 5, 6.5}}; + + void + run() + { + swap(c1, c2); + UT_ASSERT(c1.size() == 3); + UT_ASSERT(c1[0] == 4); + UT_ASSERT(c1[1] == 5); + UT_ASSERT(c1[2] == 6.5); + UT_ASSERT(c2.size() == 3); + UT_ASSERT(c2[0] == 1); + UT_ASSERT(c2[1] == 2); + UT_ASSERT(c2[2] == 3.5); + } +}; + +struct Testcase3 { + typedef double T; + typedef pmem_exp::array C; + C c1 = {{}}; + C c2 = {{}}; + void + run() + { + c1.swap(c2); + UT_ASSERT(c1.size() == 0); + UT_ASSERT(c2.size() == 0); + } +}; + +struct Testcase4 { + typedef double T; + typedef pmem_exp::array C; + C c1 = {{}}; + C c2 = {{}}; + + void + run() + { + swap(c1, c2); + UT_ASSERT(c1.size() == 0); + UT_ASSERT(c2.size() == 0); + } +}; + +struct Testcase5 { + typedef NonSwappable T; + typedef pmem_exp::array C0; + C0 l = {{}}; + C0 r = {{}}; + + void + run() + { + l.swap(r); + } +}; + +struct root { + pmem::obj::persistent_ptr r1; + pmem::obj::persistent_ptr r2; + pmem::obj::persistent_ptr r3; + pmem::obj::persistent_ptr r4; + pmem::obj::persistent_ptr r5; +}; + +void +run(pmem::obj::pool &pop) +{ + try { + pmem::obj::transaction::run(pop, [&] { + pop.root()->r1 = + pmem::obj::make_persistent(); + pop.root()->r2 = + pmem::obj::make_persistent(); + pop.root()->r3 = + pmem::obj::make_persistent(); + pop.root()->r4 = + pmem::obj::make_persistent(); + pop.root()->r5 = + pmem::obj::make_persistent(); + }); + + pmem::obj::transaction::run(pop, [&] { + pop.root()->r1->run(); + pop.root()->r2->run(); + pop.root()->r3->run(); + pop.root()->r4->run(); + pop.root()->r5->run(); + }); + } catch (...) { + UT_ASSERT(0); + } +} + +int +main(int argc, char *argv[]) +{ + START(); + + if (argc != 2) + UT_FATAL("usage: %s file-name", argv[0]); + + const char *path = argv[1]; + + pmem::obj::pool pop; + try { + pop = pmem::obj::pool::create( + path, "swap.pass", PMEMOBJ_MIN_POOL, S_IWUSR | S_IRUSR); + } catch (...) { + UT_FATAL("!pmemobj_create: %s", path); + } + + run(pop); + + return 0; +} diff --git a/tests/external/libcxx/array/array.tuple/get.fail.cpp b/tests/external/libcxx/array/array.tuple/get.fail.cpp new file mode 100644 index 0000000..283dd85 --- /dev/null +++ b/tests/external/libcxx/array/array.tuple/get.fail.cpp @@ -0,0 +1,38 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// Copyright 2018, Intel Corporation +// +// Modified to test pmem::obj containers +// + +#include "unittest.hpp" + +#include + +namespace pmem_exp = pmem::obj::experimental; + +using pmem_exp::get; + +int +main() +{ + START(); + + { + typedef double T; + typedef pmem_exp::array C; + C c = {{1, 2, 3.5}}; + get<3>(c) = 5.5; // expected-note {{requested here}} + // expected-error@array:* {{static_assert failed "Index out of + // bounds in std::get<> (std::array)"}} + } + + return 0; +} diff --git a/tests/external/libcxx/array/array.tuple/get.pass.cpp b/tests/external/libcxx/array/array.tuple/get.pass.cpp new file mode 100644 index 0000000..4a7a261 --- /dev/null +++ b/tests/external/libcxx/array/array.tuple/get.pass.cpp @@ -0,0 +1,83 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// Copyright 2018, Intel Corporation +// +// Modified to test pmem::obj containers +// + +#include "unittest.hpp" + +#include +#include +#include +#include +#include + +namespace pmem_exp = pmem::obj::experimental; + +using pmem_exp::get; + +struct Testcase1 { + typedef double T; + typedef pmem_exp::array C; + C c = {{1, 2, 3.5}}; + + void + run() + { + get<1>(c) = 5.5; + UT_ASSERT(c[0] == 1); + UT_ASSERT(c[1] == 5.5); + UT_ASSERT(c[2] == 3.5); + } +}; + +struct root { + pmem::obj::persistent_ptr r1; +}; + +void +run(pmem::obj::pool &pop) +{ + try { + pmem::obj::transaction::run(pop, [&] { + pop.root()->r1 = + pmem::obj::make_persistent(); + }); + + pmem::obj::transaction::run(pop, + [&] { pop.root()->r1->run(); }); + } catch (...) { + UT_ASSERT(0); + } +} + +int +main(int argc, char *argv[]) +{ + START(); + + if (argc != 2) + UT_FATAL("usage: %s file-name", argv[0]); + + const char *path = argv[1]; + + pmem::obj::pool pop; + try { + pop = pmem::obj::pool::create( + path, "get.pass", PMEMOBJ_MIN_POOL, S_IWUSR | S_IRUSR); + } catch (...) { + UT_FATAL("!pmemobj_create: %s", path); + } + + run(pop); + + return 0; +} diff --git a/tests/external/libcxx/array/array.tuple/get_const.pass.cpp b/tests/external/libcxx/array/array.tuple/get_const.pass.cpp new file mode 100644 index 0000000..0773e82 --- /dev/null +++ b/tests/external/libcxx/array/array.tuple/get_const.pass.cpp @@ -0,0 +1,83 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// Copyright 2018, Intel Corporation +// +// Modified to test pmem::obj containers +// + +#include "unittest.hpp" + +#include +#include +#include +#include +#include + +namespace pmem_exp = pmem::obj::experimental; + +using pmem_exp::get; + +struct Testcase1 { + typedef double T; + typedef pmem_exp::array C; + const C c = {{1, 2, 3.5}}; + + void + run() + { + UT_ASSERT(get<0>(c) == 1); + UT_ASSERT(get<1>(c) == 2); + UT_ASSERT(get<2>(c) == 3.5); + } +}; + +struct root { + pmem::obj::persistent_ptr r1; +}; + +void +run(pmem::obj::pool &pop) +{ + try { + pmem::obj::transaction::run(pop, [&] { + pop.root()->r1 = + pmem::obj::make_persistent(); + }); + + pmem::obj::transaction::run(pop, + [&] { pop.root()->r1->run(); }); + } catch (...) { + UT_ASSERT(0); + } +} + +int +main(int argc, char *argv[]) +{ + START(); + + if (argc != 2) + UT_FATAL("usage: %s file-name", argv[0]); + + const char *path = argv[1]; + + pmem::obj::pool pop; + try { + pop = pmem::obj::pool::create(path, "get_const.pass", + PMEMOBJ_MIN_POOL, + S_IWUSR | S_IRUSR); + } catch (...) { + UT_FATAL("!pmemobj_create: %s", path); + } + + run(pop); + + return 0; +} diff --git a/tests/external/libcxx/array/array.tuple/get_const_rv.pass.cpp b/tests/external/libcxx/array/array.tuple/get_const_rv.pass.cpp new file mode 100644 index 0000000..8b90a4c --- /dev/null +++ b/tests/external/libcxx/array/array.tuple/get_const_rv.pass.cpp @@ -0,0 +1,87 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// Copyright 2018, Intel Corporation +// +// Modified to test pmem::obj containers +// + +#include "unittest.hpp" + +#include +#include +#include +#include +#include + +namespace pmem_exp = pmem::obj::experimental; + +using pmem_exp::get; + +struct Testcase1 { + typedef std::unique_ptr T; + typedef pmem_exp::array C; + const C c = {{std::unique_ptr(new double(3.5))}}; + + void + run() + { + static_assert( + std::is_same(std::move(c)))>::value, + ""); + static_assert(noexcept(get<0>(std::move(c))), ""); + const T &&t = get<0>(std::move(c)); + UT_ASSERT(*t == 3.5); + } +}; + +struct root { + pmem::obj::persistent_ptr r1; +}; + +void +run(pmem::obj::pool &pop) +{ + try { + pmem::obj::transaction::run(pop, [&] { + pop.root()->r1 = + pmem::obj::make_persistent(); + }); + + pmem::obj::transaction::run(pop, + [&] { pop.root()->r1->run(); }); + } catch (...) { + UT_ASSERT(0); + } +} + +int +main(int argc, char *argv[]) +{ + START(); + + if (argc != 2) + UT_FATAL("usage: %s file-name", argv[0]); + + const char *path = argv[1]; + + pmem::obj::pool pop; + try { + pop = pmem::obj::pool::create(path, "get_cons_rv.pass", + PMEMOBJ_MIN_POOL, + S_IWUSR | S_IRUSR); + } catch (...) { + UT_FATAL("!pmemobj_create: %s", path); + } + + run(pop); + + return 0; +} diff --git a/tests/external/libcxx/array/array.tuple/get_rv.pass.cpp b/tests/external/libcxx/array/array.tuple/get_rv.pass.cpp new file mode 100644 index 0000000..b06b35f --- /dev/null +++ b/tests/external/libcxx/array/array.tuple/get_rv.pass.cpp @@ -0,0 +1,82 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// Copyright 2018, Intel Corporation +// +// Modified to test pmem::obj containers +// + +#include "unittest.hpp" + +#include +#include +#include +#include +#include + +namespace pmem_exp = pmem::obj::experimental; + +using pmem_exp::get; + +struct Testcase1 { + typedef std::unique_ptr T; + typedef pmem_exp::array C; + C c = {{std::unique_ptr(new double(3.5))}}; + + void + run() + { + T t = get<0>(std::move(c)); + UT_ASSERT(*t == 3.5); + } +}; + +struct root { + pmem::obj::persistent_ptr r1; +}; + +void +run(pmem::obj::pool &pop) +{ + try { + pmem::obj::transaction::run(pop, [&] { + pop.root()->r1 = + pmem::obj::make_persistent(); + }); + + pmem::obj::transaction::run(pop, + [&] { pop.root()->r1->run(); }); + } catch (...) { + UT_ASSERT(0); + } +} + +int +main(int argc, char *argv[]) +{ + START(); + + if (argc != 2) + UT_FATAL("usage: %s file-name", argv[0]); + + const char *path = argv[1]; + + pmem::obj::pool pop; + try { + pop = pmem::obj::pool::create(path, "get_rv.pass", + PMEMOBJ_MIN_POOL, + S_IWUSR | S_IRUSR); + } catch (...) { + UT_FATAL("!pmemobj_create: %s", path); + } + + run(pop); + + return 0; +} diff --git a/tests/external/libcxx/array/at.pass.cpp b/tests/external/libcxx/array/at.pass.cpp new file mode 100644 index 0000000..9600e84 --- /dev/null +++ b/tests/external/libcxx/array/at.pass.cpp @@ -0,0 +1,192 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// Copyright 2018, Intel Corporation +// +// Modified to test pmem::obj containers +// + +#include "unittest.hpp" + +#include +#include +#include +#include +#include + +namespace pmem_exp = pmem::obj::experimental; + +struct Testcase1 { + typedef double T; + typedef pmem_exp::array C; + C c = {{1, 2, 3.5}}; + + void + run() + { + { + C::reference r1 = c.at(0); + UT_ASSERT(r1 == 1); + r1 = 5.5; + UT_ASSERT(c.front() == 5.5); + UT_ASSERT(c.cfront() == 5.5); + + C::reference r2 = c.at(2); + UT_ASSERT(r2 == 3.5); + r2 = 7.5; + UT_ASSERT(c.back() == 7.5); + UT_ASSERT(c.cback() == 7.5); + + try { + c.at(3); + UT_ASSERT(false); + } catch (const std::out_of_range &) { + } + } + { + C::const_reference r1 = c.const_at(0); + UT_ASSERT(r1 == 5.5); + + C::const_reference r2 = c.const_at(2); + UT_ASSERT(r2 == 7.5); + + try { + c.const_at(3); + UT_ASSERT(false); + } catch (const std::out_of_range &) { + } + } + } +}; + +struct Testcase2 { + typedef double T; + typedef pmem_exp::array C; + C c = {{}}; + + void + run() + { + { + C const &cc = c; + try { + c.at(0); + UT_ASSERT(false); + } catch (const std::out_of_range &) { + } + try { + cc.at(0); + UT_ASSERT(false); + } catch (const std::out_of_range &) { + } + } + { + C const &cc = c; + try { + c.const_at(0); + UT_ASSERT(false); + } catch (const std::out_of_range &) { + } + try { + cc.const_at(0); + UT_ASSERT(false); + } catch (const std::out_of_range &) { + } + } + } +}; + +struct Testcase3 { + typedef double T; + typedef pmem_exp::array C; + const C c = {{1, 2, 3.5}}; + + void + run() + { + { + C::const_reference r1 = c.at(0); + UT_ASSERT(r1 == 1); + + C::const_reference r2 = c.at(2); + UT_ASSERT(r2 == 3.5); + + try { + c.at(3); + UT_ASSERT(false); + } catch (const std::out_of_range &) { + } + } + { + C::const_reference r1 = c.const_at(0); + UT_ASSERT(r1 == 1); + + C::const_reference r2 = c.const_at(2); + UT_ASSERT(r2 == 3.5); + + try { + c.const_at(3); + UT_ASSERT(false); + } catch (const std::out_of_range &) { + } + } + } +}; + +struct root { + pmem::obj::persistent_ptr r1; + pmem::obj::persistent_ptr r2; + pmem::obj::persistent_ptr r3; +}; + +void +run(pmem::obj::pool &pop) +{ + try { + pmem::obj::transaction::run(pop, [&] { + pop.root()->r1 = + pmem::obj::make_persistent(); + pop.root()->r2 = + pmem::obj::make_persistent(); + pop.root()->r3 = + pmem::obj::make_persistent(); + }); + + pmem::obj::transaction::run(pop, [&] { + pop.root()->r1->run(); + pop.root()->r2->run(); + pop.root()->r3->run(); + }); + } catch (...) { + UT_ASSERT(0); + } +} + +int +main(int argc, char *argv[]) +{ + START(); + + if (argc != 2) + UT_FATAL("usage: %s file-name", argv[0]); + + const char *path = argv[1]; + + pmem::obj::pool pop; + try { + pop = pmem::obj::pool::create( + path, "at.pass", PMEMOBJ_MIN_POOL, S_IWUSR | S_IRUSR); + } catch (...) { + UT_FATAL("!pmemobj_create: %s", path); + } + + run(pop); + + return 0; +} diff --git a/tests/external/libcxx/array/begin.pass.cpp b/tests/external/libcxx/array/begin.pass.cpp new file mode 100644 index 0000000..839a0a5 --- /dev/null +++ b/tests/external/libcxx/array/begin.pass.cpp @@ -0,0 +1,108 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// Copyright 2018, Intel Corporation +// +// Modified to test pmem::obj containers +// + +#include "unittest.hpp" + +#include +#include +#include +#include +#include + +namespace pmem_exp = pmem::obj::experimental; + +struct Testcase1 { + typedef double T; + typedef pmem_exp::array C; + C c = {{1, 2, 3.5}}; + + void + run() + { + C::iterator i; + i = c.begin(); + UT_ASSERT(*i == 1); + UT_ASSERT(&*i == c.data()); + *i = 5.5; + UT_ASSERT(c[0] == 5.5); + } +}; + +struct Testcase2 { + struct NoDefault { + NoDefault(int) + { + } + }; + typedef NoDefault T; + typedef pmem_exp::array C; + C c = {{}}; + + void + run() + { + UT_ASSERT(c.begin() == c.end()); + UT_ASSERT(static_cast(c).begin() == + static_cast(c).end()); + } +}; + +struct root { + pmem::obj::persistent_ptr r1; + pmem::obj::persistent_ptr r2; +}; + +void +run(pmem::obj::pool &pop) +{ + try { + pmem::obj::transaction::run(pop, [&] { + pop.root()->r1 = + pmem::obj::make_persistent(); + pop.root()->r2 = + pmem::obj::make_persistent(); + }); + + pmem::obj::transaction::run(pop, [&] { + pop.root()->r1->run(); + pop.root()->r2->run(); + }); + } catch (...) { + UT_ASSERT(0); + } +} + +int +main(int argc, char *argv[]) +{ + START(); + + if (argc != 2) + UT_FATAL("usage: %s file-name", argv[0]); + + const char *path = argv[1]; + + pmem::obj::pool pop; + try { + pop = pmem::obj::pool::create(path, "begin.pass", + PMEMOBJ_MIN_POOL, + S_IWUSR | S_IRUSR); + } catch (...) { + UT_FATAL("!pmemobj_create: %s", path); + } + + run(pop); + + return 0; +} diff --git a/tests/external/libcxx/array/compare.fail_0.cpp b/tests/external/libcxx/array/compare.fail_0.cpp new file mode 100644 index 0000000..5156b59 --- /dev/null +++ b/tests/external/libcxx/array/compare.fail_0.cpp @@ -0,0 +1,42 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// Copyright 2018, Intel Corporation +// +// Modified to test pmem::obj containers +// + +#include "unittest.hpp" + +#include + +namespace pmem_exp = pmem::obj::experimental; + +template +struct NoCompare { +}; + +int +main() +{ + START(); + + int result = 0; + { + typedef NoCompare<0> T; + typedef pmem_exp::array C; + C c1 = {{}}; + // expected-error@algorithm:* 2 {{invalid operands to binary + // expression}} + result = (c1 == c1); + result = (c1 < c1); + } + + return result; +} diff --git a/tests/external/libcxx/array/compare.fail_1.cpp b/tests/external/libcxx/array/compare.fail_1.cpp new file mode 100644 index 0000000..90bc20f --- /dev/null +++ b/tests/external/libcxx/array/compare.fail_1.cpp @@ -0,0 +1,42 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// Copyright 2018, Intel Corporation +// +// Modified to test pmem::obj containers +// + +#include "unittest.hpp" + +#include + +namespace pmem_exp = pmem::obj::experimental; + +template +struct NoCompare { +}; + +int +main() +{ + START(); + + int result = 0; + { + typedef NoCompare<1> T; + typedef pmem_exp::array C; + C c1 = {{}}; + // expected-error@algorithm:* 2 {{invalid operands to binary + // expression}} + result = (c1 != c1); + result = (c1 > c1); + } + + return result; +} diff --git a/tests/external/libcxx/array/compare.fail_2.cpp b/tests/external/libcxx/array/compare.fail_2.cpp new file mode 100644 index 0000000..f70770f --- /dev/null +++ b/tests/external/libcxx/array/compare.fail_2.cpp @@ -0,0 +1,42 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// Copyright 2018, Intel Corporation +// +// Modified to test pmem::obj containers +// + +#include "unittest.hpp" + +#include + +namespace pmem_exp = pmem::obj::experimental; + +template +struct NoCompare { +}; + +int +main() +{ + START(); + + int result = 0; + { + typedef NoCompare<2> T; + typedef pmem_exp::array C; + C c1 = {{}}; + // expected-error@algorithm:* 2 {{invalid operands to binary + // expression}} + result = (c1 == c1); + result = (c1 < c1); + } + + return result; +} diff --git a/tests/external/libcxx/array/compare.pass.cpp b/tests/external/libcxx/array/compare.pass.cpp new file mode 100644 index 0000000..3a95b99 --- /dev/null +++ b/tests/external/libcxx/array/compare.pass.cpp @@ -0,0 +1,119 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// Copyright 2018, Intel Corporation +// +// Modified to test pmem::obj containers +// + +#include "unittest.hpp" + +#include + +#include +#include +#include +#include +#include + +namespace pmem_exp = pmem::obj::experimental; + +template +void +test_compare(const Array &LHS, const Array &RHS) +{ + typedef std::vector Vector; + const Vector LHSV(LHS.begin(), LHS.end()); + const Vector RHSV(RHS.begin(), RHS.end()); + UT_ASSERT((LHS == RHS) == (LHSV == RHSV)); + UT_ASSERT((LHS != RHS) == (LHSV != RHSV)); + UT_ASSERT((LHS < RHS) == (LHSV < RHSV)); + UT_ASSERT((LHS <= RHS) == (LHSV <= RHSV)); + UT_ASSERT((LHS > RHS) == (LHSV > RHSV)); + UT_ASSERT((LHS >= RHS) == (LHSV >= RHSV)); +} + +struct Testcase1 { + typedef int T; + typedef pmem_exp::array C; + C c1 = {{1, 2, 3}}; + C c2 = {{1, 2, 3}}; + C c3 = {{3, 2, 1}}; + C c4 = {{1, 2, 1}}; + + void + run() + { + test_compare(c1, c2); + test_compare(c1, c3); + test_compare(c1, c4); + } +}; + +struct Testcase2 { + typedef int T; + typedef pmem_exp::array C; + C c1 = {{}}; + C c2 = {{}}; + + void + run() + { + test_compare(c1, c2); + } +}; + +struct root { + pmem::obj::persistent_ptr r1; + pmem::obj::persistent_ptr r2; +}; + +void +run(pmem::obj::pool &pop) +{ + try { + pmem::obj::transaction::run(pop, [&] { + pop.root()->r1 = + pmem::obj::make_persistent(); + pop.root()->r2 = + pmem::obj::make_persistent(); + }); + + pmem::obj::transaction::run(pop, [&] { + pop.root()->r1->run(); + pop.root()->r2->run(); + }); + } catch (...) { + UT_ASSERT(0); + } +} + +int +main(int argc, char *argv[]) +{ + START(); + + if (argc != 2) + UT_FATAL("usage: %s file-name", argv[0]); + + const char *path = argv[1]; + + pmem::obj::pool pop; + try { + pop = pmem::obj::pool::create(path, "compare.pass", + PMEMOBJ_MIN_POOL, + S_IWUSR | S_IRUSR); + } catch (...) { + UT_FATAL("!pmemobj_create: %s", path); + } + + run(pop); + + return 0; +} diff --git a/tests/external/libcxx/array/contiguous.pass.cpp b/tests/external/libcxx/array/contiguous.pass.cpp new file mode 100644 index 0000000..aa8ba0f --- /dev/null +++ b/tests/external/libcxx/array/contiguous.pass.cpp @@ -0,0 +1,89 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// Copyright 2018, Intel Corporation +// +// Modified to test pmem::obj containers +// + +#include "unittest.hpp" + +#include +#include +#include +#include +#include + +namespace pmem_exp = pmem::obj::experimental; + +template +void +test_contiguous(const C &c) +{ + for (size_t i = 0; i < c.size(); ++i) + UT_ASSERT(*(c.begin() + (ptrdiff_t)i) == + *(std::addressof(*c.begin()) + (ptrdiff_t)i)); +} + +struct Testcase1 { + typedef double T; + typedef pmem_exp::array C; + C c; + + void + run() + { + test_contiguous(C()); + test_contiguous(c); + } +}; + +struct root { + pmem::obj::persistent_ptr r1; +}; + +void +run(pmem::obj::pool &pop) +{ + try { + pmem::obj::transaction::run(pop, [&] { + pop.root()->r1 = + pmem::obj::make_persistent(); + }); + + pmem::obj::transaction::run(pop, + [&] { pop.root()->r1->run(); }); + } catch (...) { + UT_ASSERT(0); + } +} + +int +main(int argc, char *argv[]) +{ + START(); + + if (argc != 2) + UT_FATAL("usage: %s file-name", argv[0]); + + const char *path = argv[1]; + + pmem::obj::pool pop; + try { + pop = pmem::obj::pool::create(path, "contiguous.pass", + PMEMOBJ_MIN_POOL, + S_IWUSR | S_IRUSR); + } catch (...) { + UT_FATAL("!pmemobj_create: %s", path); + } + + run(pop); + + return 0; +} diff --git a/tests/external/libcxx/array/empty.pass.cpp b/tests/external/libcxx/array/empty.pass.cpp new file mode 100644 index 0000000..abf38ec --- /dev/null +++ b/tests/external/libcxx/array/empty.pass.cpp @@ -0,0 +1,96 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// Copyright 2018, Intel Corporation +// +// Modified to test pmem::obj containers +// + +#include "unittest.hpp" + +#include +#include +#include +#include +#include + +namespace pmem_exp = pmem::obj::experimental; + +struct Testcase1 { + typedef pmem_exp::array C; + C c; + + void + run() + { + UT_ASSERT_NOEXCEPT(c.empty()); + UT_ASSERT(!c.empty()); + } +}; + +struct Testcase2 { + typedef pmem_exp::array C; + C c; + + void + run() + { + UT_ASSERT_NOEXCEPT(c.empty()); + UT_ASSERT(c.empty()); + } +}; + +struct root { + pmem::obj::persistent_ptr r1; + pmem::obj::persistent_ptr r2; +}; + +void +run(pmem::obj::pool &pop) +{ + try { + pmem::obj::transaction::run(pop, [&] { + pop.root()->r1 = + pmem::obj::make_persistent(); + pop.root()->r2 = + pmem::obj::make_persistent(); + }); + + pmem::obj::transaction::run(pop, [&] { + pop.root()->r1->run(); + pop.root()->r2->run(); + }); + } catch (...) { + UT_ASSERT(0); + } +} + +int +main(int argc, char *argv[]) +{ + START(); + + if (argc != 2) + UT_FATAL("usage: %s file-name", argv[0]); + + const char *path = argv[1]; + + pmem::obj::pool pop; + try { + pop = pmem::obj::pool::create(path, "empty.pass", + PMEMOBJ_MIN_POOL, + S_IWUSR | S_IRUSR); + } catch (...) { + UT_FATAL("!pmemobj_create: %s", path); + } + + run(pop); + + return 0; +} diff --git a/tests/external/libcxx/array/front_back.pass.cpp b/tests/external/libcxx/array/front_back.pass.cpp new file mode 100644 index 0000000..750e668 --- /dev/null +++ b/tests/external/libcxx/array/front_back.pass.cpp @@ -0,0 +1,215 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// Copyright 2018, Intel Corporation +// +// Modified to test pmem::obj containers +// + +#include "unittest.hpp" + +#include +#include +#include +#include +#include + +namespace pmem_exp = pmem::obj::experimental; + +struct Testcase1 { + typedef double T; + typedef pmem_exp::array C; + C c = {{1, 2, 3.5}}; + + void + run() + { + C::reference r1 = c.front(); + UT_ASSERT(r1 == 1); + r1 = 5.5; + UT_ASSERT(c[0] == 5.5); + + C::reference r2 = c.back(); + UT_ASSERT(r2 == 3.5); + r2 = 7.5; + UT_ASSERT(c[2] == 7.5); + } +}; + +struct Testcase2 { + typedef double T; + typedef pmem_exp::array C; + const C c = {{1, 2, 3.5}}; + + void + run() + { + { + C::const_reference r1 = c.front(); + UT_ASSERT(r1 == 1); + + C::const_reference r2 = c.back(); + UT_ASSERT(r2 == 3.5); + } + { + C::const_reference r1 = c.cfront(); + UT_ASSERT(r1 == 1); + + C::const_reference r2 = c.cback(); + UT_ASSERT(r2 == 3.5); + } + } +}; + +struct Testcase3 { + typedef double T; + typedef pmem_exp::array C; + C c = {{}}; + + void + run() + { + C const &cc = c; + static_assert((std::is_same::value), + ""); + static_assert( + (std::is_same::value), + ""); + static_assert((std::is_same::value), + ""); + static_assert( + (std::is_same::value), + ""); + static_assert( + (std::is_same::value), + ""); + static_assert( + (std::is_same::value), + ""); + static_assert( + (std::is_same::value), + ""); + static_assert( + (std::is_same::value), + ""); + if (c.size() > (0)) { // always false + c.front(); + c.back(); + c.cfront(); + c.cback(); + cc.front(); + cc.back(); + cc.cfront(); + cc.cback(); + } + } +}; + +struct Testcase4 { + typedef double T; + typedef pmem_exp::array C; + C c = {{}}; + + void + run() + { + C const &cc = c; + static_assert( + (std::is_same::value), + ""); + static_assert( + (std::is_same::value), + ""); + static_assert( + (std::is_same::value), + ""); + static_assert( + (std::is_same::value), + ""); + static_assert( + (std::is_same::value), + ""); + static_assert( + (std::is_same::value), + ""); + static_assert( + (std::is_same::value), + ""); + static_assert( + (std::is_same::value), + ""); + if (c.size() > (0)) { + c.front(); + c.back(); + c.cfront(); + c.cback(); + cc.front(); + cc.back(); + cc.cfront(); + cc.cback(); + } + } +}; + +struct root { + pmem::obj::persistent_ptr r1; + pmem::obj::persistent_ptr r2; + pmem::obj::persistent_ptr r3; + pmem::obj::persistent_ptr r4; +}; + +void +run(pmem::obj::pool &pop) +{ + try { + pmem::obj::transaction::run(pop, [&] { + pop.root()->r1 = + pmem::obj::make_persistent(); + pop.root()->r2 = + pmem::obj::make_persistent(); + pop.root()->r3 = + pmem::obj::make_persistent(); + pop.root()->r4 = + pmem::obj::make_persistent(); + }); + + pmem::obj::transaction::run(pop, [&] { + pop.root()->r1->run(); + pop.root()->r2->run(); + pop.root()->r3->run(); + pop.root()->r4->run(); + }); + } catch (...) { + UT_ASSERT(0); + } +} + +int +main(int argc, char *argv[]) +{ + START(); + + if (argc != 2) + UT_FATAL("usage: %s file-name", argv[0]); + + const char *path = argv[1]; + + pmem::obj::pool pop; + try { + pop = pmem::obj::pool::create(path, "front_back.pass", + PMEMOBJ_MIN_POOL, + S_IWUSR | S_IRUSR); + } catch (...) { + UT_FATAL("!pmemobj_create: %s", path); + } + + run(pop); + + return 0; +} diff --git a/tests/external/libcxx/array/indexing.pass.cpp b/tests/external/libcxx/array/indexing.pass.cpp new file mode 100644 index 0000000..989584b --- /dev/null +++ b/tests/external/libcxx/array/indexing.pass.cpp @@ -0,0 +1,158 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// Copyright 2018, Intel Corporation +// +// Modified to test pmem::obj containers +// + +#include "unittest.hpp" + +#include +#include +#include +#include +#include + +namespace pmem_exp = pmem::obj::experimental; + +struct Testcase1 { + typedef double T; + typedef pmem_exp::array C; + C c = {{1, 2, 3.5}}; + + void + run() + { + C::reference r1 = c[0]; + UT_ASSERT(r1 == 1); + r1 = 5.5; + UT_ASSERT(c.front() == 5.5); + + C::reference r2 = c[2]; + UT_ASSERT(r2 == 3.5); + r2 = 7.5; + UT_ASSERT(c.back() == 7.5); + } +}; + +struct Testcase2 { + typedef double T; + typedef pmem_exp::array C; + const C c = {{1, 2, 3.5}}; + + void + run() + { + C::const_reference r1 = c[0]; + UT_ASSERT(r1 == 1); + C::const_reference r2 = c[2]; + UT_ASSERT(r2 == 3.5); + } +}; + +struct Testcase3 { + typedef double T; + typedef pmem_exp::array C; + C c = {{}}; + + void + run() + { + C const &cc = c; + static_assert((std::is_same::value), ""); + static_assert((std::is_same::value), + ""); + if (c.size() > (0)) { // always false + C::reference r1 = c[0]; + C::const_reference r2 = cc[0]; + ((void)r1); + ((void)r2); + } + } +}; + +struct Testcase4 { + typedef double T; + typedef pmem_exp::array C; + C c = {{}}; + + void + run() + { + C const &cc = c; + static_assert((std::is_same::value), + ""); + static_assert((std::is_same::value), + ""); + if (c.size() > (0)) { // always false + C::reference r1 = c[0]; + C::const_reference r2 = cc[0]; + ((void)r1); + ((void)r2); + } + } +}; + +struct root { + pmem::obj::persistent_ptr r1; + pmem::obj::persistent_ptr r2; + pmem::obj::persistent_ptr r3; + pmem::obj::persistent_ptr r4; +}; + +void +run(pmem::obj::pool &pop) +{ + try { + pmem::obj::transaction::run(pop, [&] { + pop.root()->r1 = + pmem::obj::make_persistent(); + pop.root()->r2 = + pmem::obj::make_persistent(); + pop.root()->r3 = + pmem::obj::make_persistent(); + pop.root()->r4 = + pmem::obj::make_persistent(); + }); + + pmem::obj::transaction::run(pop, [&] { + pop.root()->r1->run(); + pop.root()->r2->run(); + pop.root()->r3->run(); + pop.root()->r4->run(); + }); + } catch (...) { + UT_ASSERT(0); + } +} + +int +main(int argc, char *argv[]) +{ + START(); + + if (argc != 2) + UT_FATAL("usage: %s file-name", argv[0]); + + const char *path = argv[1]; + + pmem::obj::pool pop; + try { + pop = pmem::obj::pool::create(path, "indexing.pass", + PMEMOBJ_MIN_POOL, + S_IWUSR | S_IRUSR); + } catch (...) { + UT_FATAL("!pmemobj_create: %s", path); + } + + run(pop); + + return 0; +} diff --git a/tests/external/libcxx/array/iterators.pass.cpp b/tests/external/libcxx/array/iterators.pass.cpp new file mode 100644 index 0000000..68dc95f --- /dev/null +++ b/tests/external/libcxx/array/iterators.pass.cpp @@ -0,0 +1,250 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// Copyright 2018, Intel Corporation +// +// Modified to test pmem::obj containers +// + +#include "unittest.hpp" + +#include +#include +#include +#include +#include + +namespace pmem_exp = pmem::obj::experimental; + +struct Testcase1 { + typedef pmem_exp::array C; + C c; + + void + run() + { + C::iterator i; + i = c.begin(); + C::const_iterator j; + j = c.cbegin(); + UT_ASSERT(i == j); + C::const_iterator k; + k = static_cast(c).begin(); + UT_ASSERT(i == k); + } +}; + +struct Testcase2 { + typedef pmem_exp::array C; + C c; + + void + run() + { + C::iterator i; + i = c.begin(); + C::const_iterator j; + j = c.cbegin(); + UT_ASSERT(i == j); + C::const_iterator k; + k = static_cast(c).begin(); + UT_ASSERT(i == k); + } +}; + +struct Testcase3 { + typedef pmem_exp::array C; + C c; + + void + run() + { + C::iterator ii1{}, ii2{}; + C::iterator ii4 = ii1; + C::const_iterator cii{}; + UT_ASSERT(ii1 == ii2); + UT_ASSERT(ii1 == ii4); + UT_ASSERT(ii1 == cii); + + UT_ASSERT(!(ii1 != ii2)); + UT_ASSERT(!(ii1 != cii)); + + UT_ASSERT(c.begin() == pmem_exp::begin(c)); + UT_ASSERT(c.cbegin() == pmem_exp::cbegin(c)); + UT_ASSERT(c.rbegin() == pmem_exp::rbegin(c)); + UT_ASSERT(c.crbegin() == pmem_exp::crbegin(c)); + UT_ASSERT(c.end() == pmem_exp::end(c)); + UT_ASSERT(c.cend() == pmem_exp::cend(c)); + UT_ASSERT(c.rend() == pmem_exp::rend(c)); + UT_ASSERT(c.crend() == pmem_exp::crend(c)); + + UT_ASSERT(pmem_exp::begin(c) != pmem_exp::end(c)); + UT_ASSERT(pmem_exp::rbegin(c) != pmem_exp::rend(c)); + UT_ASSERT(pmem_exp::cbegin(c) != pmem_exp::cend(c)); + UT_ASSERT(pmem_exp::crbegin(c) != pmem_exp::crend(c)); + } +}; + +struct Testcase4 { + typedef pmem_exp::array C; + C c; + + void + run() + { + C::iterator ii1{}, ii2{}; + C::iterator ii4 = ii1; + C::const_iterator cii{}; + UT_ASSERT(ii1 == ii2); + UT_ASSERT(ii1 == ii4); + + UT_ASSERT(!(ii1 != ii2)); + + UT_ASSERT((ii1 == cii)); + UT_ASSERT((cii == ii1)); + UT_ASSERT(!(ii1 != cii)); + UT_ASSERT(!(cii != ii1)); + UT_ASSERT(!(ii1 < cii)); + UT_ASSERT(!(cii < ii1)); + UT_ASSERT((ii1 <= cii)); + UT_ASSERT((cii <= ii1)); + UT_ASSERT(!(ii1 > cii)); + UT_ASSERT(!(cii > ii1)); + UT_ASSERT((ii1 >= cii)); + UT_ASSERT((cii >= ii1)); + UT_ASSERT(cii - ii1 == 0); + UT_ASSERT(ii1 - cii == 0); + + UT_ASSERT(c.begin() == pmem_exp::begin(c)); + UT_ASSERT(c.cbegin() == pmem_exp::cbegin(c)); + UT_ASSERT(c.rbegin() == pmem_exp::rbegin(c)); + UT_ASSERT(c.crbegin() == pmem_exp::crbegin(c)); + UT_ASSERT(c.end() == pmem_exp::end(c)); + UT_ASSERT(c.cend() == pmem_exp::cend(c)); + UT_ASSERT(c.rend() == pmem_exp::rend(c)); + UT_ASSERT(c.crend() == pmem_exp::crend(c)); + + UT_ASSERT(pmem_exp::begin(c) == pmem_exp::end(c)); + UT_ASSERT(pmem_exp::rbegin(c) == pmem_exp::rend(c)); + UT_ASSERT(pmem_exp::cbegin(c) == pmem_exp::cend(c)); + UT_ASSERT(pmem_exp::crbegin(c) == pmem_exp::crend(c)); + } +}; + +struct Testcase5 { + typedef pmem_exp::array C; + C c{{0, 1, 2, 3, 4}}; + + void + run() + { + UT_ASSERT(c.begin() == pmem_exp::begin(c)); + UT_ASSERT(c.cbegin() == pmem_exp::cbegin(c)); + UT_ASSERT(c.end() == pmem_exp::end(c)); + UT_ASSERT(c.cend() == pmem_exp::cend(c)); + UT_ASSERT(static_cast(c).end() == pmem_exp::cend(c)); + + UT_ASSERT(c.rbegin() == pmem_exp::rbegin(c)); + UT_ASSERT(c.crbegin() == pmem_exp::crbegin(c)); + UT_ASSERT(c.rend() == pmem_exp::rend(c)); + UT_ASSERT(c.crend() == pmem_exp::crend(c)); + UT_ASSERT(static_cast(c).rend() == + pmem_exp::crend(c)); + + UT_ASSERT(pmem_exp::begin(c) != pmem_exp::end(c)); + UT_ASSERT(pmem_exp::rbegin(c) != pmem_exp::rend(c)); + UT_ASSERT(pmem_exp::cbegin(c) != pmem_exp::cend(c)); + UT_ASSERT(pmem_exp::crbegin(c) != pmem_exp::crend(c)); + + UT_ASSERT(*c.begin() == 0); + UT_ASSERT(*c.rbegin() == 4); + UT_ASSERT(*static_cast(c).begin() == 0); + UT_ASSERT(*static_cast(c).rbegin() == 4); + UT_ASSERT(*(c.end() - 1) == 4); + UT_ASSERT(*(c.rend() - 1) == 0); + + UT_ASSERT(*pmem_exp::begin(c) == 0); + UT_ASSERT(*(pmem_exp::begin(c) + 1) == 1); + UT_ASSERT(*pmem_exp::cbegin(c) == 0); + UT_ASSERT(*(pmem_exp::cbegin(c) + 1) == 1); + UT_ASSERT(*pmem_exp::rbegin(c) == 4); + UT_ASSERT(*pmem_exp::crbegin(c) == 4); + + UT_ASSERT(*pmem_exp::begin(static_cast(c)) == 0); + UT_ASSERT(*(pmem_exp::begin(static_cast(c)) + 1) == + 1); + UT_ASSERT(*pmem_exp::rbegin(static_cast(c)) == 4); + UT_ASSERT(*(pmem_exp::rbegin(static_cast(c)) + 1) == + 3); + UT_ASSERT(*(pmem_exp::end(static_cast(c)) - 1) == 4); + UT_ASSERT(*(pmem_exp::rend(static_cast(c)) - 1) == + 0); + } +}; + +struct root { + pmem::obj::persistent_ptr r1; + pmem::obj::persistent_ptr r2; + pmem::obj::persistent_ptr r3; + pmem::obj::persistent_ptr r4; + pmem::obj::persistent_ptr r5; +}; + +void +run(pmem::obj::pool &pop) +{ + try { + pmem::obj::transaction::run(pop, [&] { + pop.root()->r1 = + pmem::obj::make_persistent(); + pop.root()->r2 = + pmem::obj::make_persistent(); + pop.root()->r3 = + pmem::obj::make_persistent(); + pop.root()->r4 = + pmem::obj::make_persistent(); + pop.root()->r5 = + pmem::obj::make_persistent(); + }); + + pmem::obj::transaction::run(pop, [&] { + pop.root()->r1->run(); + pop.root()->r2->run(); + pop.root()->r3->run(); + pop.root()->r4->run(); + pop.root()->r5->run(); + }); + } catch (...) { + UT_ASSERT(0); + } +} + +int +main(int argc, char *argv[]) +{ + START(); + + if (argc != 2) + UT_FATAL("usage: %s file-name", argv[0]); + + const char *path = argv[1]; + + pmem::obj::pool pop; + try { + pop = pmem::obj::pool::create(path, "iterators.pass", + PMEMOBJ_MIN_POOL, + S_IWUSR | S_IRUSR); + } catch (...) { + UT_FATAL("!pmemobj_create: %s", path); + } + + run(pop); + + return 0; +} diff --git a/tests/external/libcxx/array/max_size.pass.cpp b/tests/external/libcxx/array/max_size.pass.cpp new file mode 100644 index 0000000..0fe7f25 --- /dev/null +++ b/tests/external/libcxx/array/max_size.pass.cpp @@ -0,0 +1,96 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// Copyright 2018, Intel Corporation +// +// Modified to test pmem::obj containers +// + +#include "unittest.hpp" + +#include +#include +#include +#include +#include + +namespace pmem_exp = pmem::obj::experimental; + +struct Testcase1 { + typedef pmem_exp::array C; + C c; + + void + run() + { + UT_ASSERT_NOEXCEPT(c.max_size()); + UT_ASSERT(c.max_size() == 2); + } +}; + +struct Testcase2 { + typedef pmem_exp::array C; + C c; + + void + run() + { + UT_ASSERT_NOEXCEPT(c.max_size()); + UT_ASSERT(c.max_size() == 0); + } +}; + +struct root { + pmem::obj::persistent_ptr r1; + pmem::obj::persistent_ptr r2; +}; + +void +run(pmem::obj::pool &pop) +{ + try { + pmem::obj::transaction::run(pop, [&] { + pop.root()->r1 = + pmem::obj::make_persistent(); + pop.root()->r2 = + pmem::obj::make_persistent(); + }); + + pmem::obj::transaction::run(pop, [&] { + pop.root()->r1->run(); + pop.root()->r2->run(); + }); + } catch (...) { + UT_ASSERT(0); + } +} + +int +main(int argc, char *argv[]) +{ + START(); + + if (argc != 2) + UT_FATAL("usage: %s file-name", argv[0]); + + const char *path = argv[1]; + + pmem::obj::pool pop; + try { + pop = pmem::obj::pool::create(path, "max_size.pass", + PMEMOBJ_MIN_POOL, + S_IWUSR | S_IRUSR); + } catch (...) { + UT_FATAL("!pmemobj_create: %s", path); + } + + run(pop); + + return 0; +} diff --git a/tests/external/libcxx/array/size_and_alignment.pass.cpp b/tests/external/libcxx/array/size_and_alignment.pass.cpp new file mode 100644 index 0000000..1df7836 --- /dev/null +++ b/tests/external/libcxx/array/size_and_alignment.pass.cpp @@ -0,0 +1,70 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// Copyright 2018, Intel Corporation +// +// Modified to test pmem::obj containers +// + +#include "unittest.hpp" +#include + +#include + +namespace pmem_exp = pmem::obj::experimental; + +template +struct MyArray { + T elems[Size]; +}; + +template +void +test() +{ + typedef T CArrayT[Size]; + typedef pmem_exp::array ArrayT; + typedef MyArray MyArrayT; + static_assert(sizeof(ArrayT) == sizeof(CArrayT), ""); + static_assert(sizeof(ArrayT) == sizeof(MyArrayT), ""); + static_assert(alignof(ArrayT) == alignof(MyArrayT), ""); +} + +template +void +test_zero_sized() +{ + typedef pmem_exp::array ArrayT; + static_assert(sizeof(ArrayT) == sizeof(T), ""); +} + +template +void +test_type() +{ + test(); + test(); + test_zero_sized(); +} + +// static_assert(sizeof(void*) == 4, ""); + +int +main() +{ + START(); + + test_type(); + test_type(); + test_type(); + test_type(); + test_type(); + + return 0; +} diff --git a/tests/external/libcxx/array/types.pass.cpp b/tests/external/libcxx/array/types.pass.cpp new file mode 100644 index 0000000..8d7280e --- /dev/null +++ b/tests/external/libcxx/array/types.pass.cpp @@ -0,0 +1,171 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// Copyright 2018, Intel Corporation +// +// Modified to test pmem::obj containers +// + +#include "unittest.hpp" +#include + +#include +#include + +namespace pmem_exp = pmem::obj::experimental; + +template +void +test_iterators() +{ + typedef std::iterator_traits ItT; + typedef std::iterator_traits CItT; + static_assert((std::is_same::value), + ""); + static_assert((std::is_same::value), + ""); + static_assert((std::is_same::value), + ""); + static_assert((std::is_same::value), + ""); + static_assert((std::is_same::value), + ""); + + static_assert((std::is_same::value), + ""); + static_assert((std::is_same::value), + ""); + static_assert((std::is_same::value), + ""); + static_assert((std::is_same::value), + ""); + static_assert((std::is_same::value), + ""); +} + +int +main() +{ + START(); + + { + typedef double T; + typedef pmem_exp::array C; + static_assert((std::is_same::value), ""); + static_assert( + (std::is_same::value), + ""); + static_assert( + (std::is_same< + C::iterator, + pmem_exp::basic_contiguous_iterator>::value), + ""); + static_assert( + (std::is_same::value), + ""); + test_iterators(); + static_assert((std::is_same::value), ""); + static_assert( + (std::is_same::value), ""); + static_assert((std::is_same::value), + ""); + static_assert((std::is_same::value), + ""); + static_assert( + (std::is_same< + C::reverse_iterator, + std::reverse_iterator>::value), + ""); + static_assert((std::is_same>::value), + ""); + + static_assert( + (std::is_signed::value), + ""); + static_assert((std::is_unsigned::value), + ""); + static_assert((std::is_same:: + difference_type>::value), + ""); + static_assert( + (std::is_same:: + difference_type>::value), + ""); + } + { + typedef int *T; + typedef pmem_exp::array C; + static_assert((std::is_same::value), ""); + static_assert( + (std::is_same::value), + ""); + static_assert( + (std::is_same< + C::iterator, + pmem_exp::basic_contiguous_iterator>::value), + ""); + static_assert( + (std::is_same::value), + ""); + test_iterators(); + static_assert((std::is_same::value), ""); + static_assert( + (std::is_same::value), ""); + static_assert((std::is_same::value), + ""); + static_assert((std::is_same::value), + ""); + static_assert( + (std::is_same< + C::reverse_iterator, + std::reverse_iterator>::value), + ""); + static_assert((std::is_same>::value), + ""); + + static_assert( + (std::is_signed::value), + ""); + static_assert((std::is_unsigned::value), + ""); + static_assert((std::is_same:: + difference_type>::value), + ""); + static_assert( + (std::is_same:: + difference_type>::value), + ""); + } + + return 0; +} diff --git a/tests/external/libcxx/basic_string/char.bad.fail.cpp b/tests/external/libcxx/basic_string/char.bad.fail.cpp new file mode 100644 index 0000000..1878cd0 --- /dev/null +++ b/tests/external/libcxx/basic_string/char.bad.fail.cpp @@ -0,0 +1,53 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// +// ... manipulating sequences of any non-array trivial standard-layout types. + +#include +#include "test_traits.h" + +struct NotTrivial { + NotTrivial() : value(3) {} + int value; +}; + +struct NotStandardLayout { +public: + NotStandardLayout() : one(1), two(2) {} + int sum() const { return one + two; } // silences "unused field 'two' warning" + int one; +private: + int two; +}; + +int main() +{ + { +// array + typedef char C[3]; + static_assert(std::is_array::value, ""); + std::basic_string > s; +// expected-error-re@string:* {{static_assert failed{{.*}} "Character type of basic_string must not be an array"}} + } + + { +// not trivial + static_assert(!std::is_trivial::value, ""); + std::basic_string > s; +// expected-error-re@string:* {{static_assert failed{{.*}} "Character type of basic_string must be trivial"}} + } + + { +// not standard layout + static_assert(!std::is_standard_layout::value, ""); + std::basic_string > s; +// expected-error-re@string:* {{static_assert failed{{.*}} "Character type of basic_string must be standard-layout"}} + } +} diff --git a/tests/external/libcxx/basic_string/string.access/at.pass.cpp b/tests/external/libcxx/basic_string/string.access/at.pass.cpp new file mode 100644 index 0000000..0000bf7 --- /dev/null +++ b/tests/external/libcxx/basic_string/string.access/at.pass.cpp @@ -0,0 +1,103 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// Copyright 2019, Intel Corporation +// +// Modified to test pmem::obj containers +// + +#include "unittest.hpp" + +#include +#include + +namespace nvobj = pmem::obj; +namespace pmem_exp = nvobj::experimental; +using C = pmem_exp::string; + +struct root { + nvobj::persistent_ptr s1; + nvobj::persistent_ptr s2; + nvobj::persistent_ptr s3; +}; + +template +void +test(S &s, typename S::size_type pos) +{ + const S &cs = s; + + if (pos < s.size()) { + UT_ASSERT(s.at(pos) == s[pos]); + UT_ASSERT(cs.at(pos) == cs[pos]); + } else { + try { + s.at(pos); + UT_ASSERT(false); + } catch (std::out_of_range &) { + UT_ASSERT(pos >= s.size()); + } + try { + cs.at(pos); + UT_ASSERT(false); + } catch (std::out_of_range &) { + UT_ASSERT(pos >= s.size()); + } + } +} + +int +main(int argc, char *argv[]) +{ + START(); + + if (argc < 2) { + std::cerr << "usage: " << argv[0] << " file-name" << std::endl; + return 1; + } + + auto path = argv[1]; + auto pop = nvobj::pool::create( + path, "StringTest: at", PMEMOBJ_MIN_POOL, S_IWUSR | S_IRUSR); + + auto r = pop.root(); + + try { + nvobj::transaction::run(pop, [&] { + r->s1 = nvobj::make_persistent(); + r->s2 = nvobj::make_persistent("123"); + r->s3 = nvobj::make_persistent( + "1234567890123456789012345678901234567890" + "1234567890123456789012345678901234567890" + "1234567890123456789012345678901234567890" + "1234567890"); + }); + + test(*r->s1, 0); + test(*r->s2, 0); + test(*r->s2, 1); + test(*r->s2, 2); + test(*r->s2, 3); + test(*r->s3, 0); + test(*r->s3, 64); + test(*r->s3, r->s3->size()); + + nvobj::transaction::run(pop, [&] { + nvobj::delete_persistent(r->s1); + nvobj::delete_persistent(r->s2); + nvobj::delete_persistent(r->s3); + }); + } catch (std::exception &e) { + UT_FATALexc(e); + } + + pop.close(); + + return 0; +} diff --git a/tests/external/libcxx/basic_string/string.access/back.pass.cpp b/tests/external/libcxx/basic_string/string.access/back.pass.cpp new file mode 100644 index 0000000..7e352a0 --- /dev/null +++ b/tests/external/libcxx/basic_string/string.access/back.pass.cpp @@ -0,0 +1,87 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// Copyright 2019, Intel Corporation +// +// Modified to test pmem::obj containers +// + +#include "unittest.hpp" + +#include +#include + +namespace nvobj = pmem::obj; +namespace pmem_exp = nvobj::experimental; +using C = pmem_exp::string; + +struct root { + nvobj::persistent_ptr s1; + nvobj::persistent_ptr s2; + nvobj::persistent_ptr s3; +}; + +template +void +test(S &s) +{ + const S &cs = s; + UT_ASSERT(&cs.back() == &cs[cs.size() - 1]); + UT_ASSERT(&cs.back() == &cs[cs.size() - 1]); + UT_ASSERT(&s.back() == &s[cs.size() - 1]); + s.back() = typename S::value_type('z'); + UT_ASSERT(s.back() == typename S::value_type('z')); + UT_ASSERT(s.back() == s.cback()); +} + +int +main(int argc, char *argv[]) +{ + START(); + + if (argc < 2) { + std::cerr << "usage: " << argv[0] << " file-name" << std::endl; + return 1; + } + + auto path = argv[1]; + auto pop = nvobj::pool::create( + path, "StringTest: back", PMEMOBJ_MIN_POOL, S_IWUSR | S_IRUSR); + + auto r = pop.root(); + + try { + nvobj::transaction::run(pop, [&] { + r->s1 = nvobj::make_persistent("1"); + r->s2 = nvobj::make_persistent( + "1234567890123456789012345678901234567890"); + r->s3 = nvobj::make_persistent( + "1234567890123456789012345678901234567890" + "1234567890123456789012345678901234567890" + "1234567890123456789012345678901234567890" + "1234567890"); + }); + + test(*r->s1); + test(*r->s2); + test(*r->s3); + + nvobj::transaction::run(pop, [&] { + nvobj::delete_persistent(r->s1); + nvobj::delete_persistent(r->s2); + nvobj::delete_persistent(r->s3); + }); + } catch (std::exception &e) { + UT_FATALexc(e); + } + + pop.close(); + + return 0; +} diff --git a/tests/external/libcxx/basic_string/string.access/front.pass.cpp b/tests/external/libcxx/basic_string/string.access/front.pass.cpp new file mode 100644 index 0000000..3303987 --- /dev/null +++ b/tests/external/libcxx/basic_string/string.access/front.pass.cpp @@ -0,0 +1,86 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// Copyright 2019, Intel Corporation +// +// Modified to test pmem::obj containers +// + +#include "unittest.hpp" + +#include +#include + +namespace nvobj = pmem::obj; +namespace pmem_exp = nvobj::experimental; +using C = pmem_exp::string; + +struct root { + nvobj::persistent_ptr s1; + nvobj::persistent_ptr s2; + nvobj::persistent_ptr s3; +}; + +template +void +test(S &s) +{ + const S &cs = s; + UT_ASSERT(&cs.front() == &cs[0]); + UT_ASSERT(&s.front() == &s[0]); + s.front() = typename S::value_type('z'); + UT_ASSERT(s.front() == typename S::value_type('z')); + UT_ASSERT(s.front() == s.cfront()); +} + +int +main(int argc, char *argv[]) +{ + START(); + + if (argc < 2) { + std::cerr << "usage: " << argv[0] << " file-name" << std::endl; + return 1; + } + + auto path = argv[1]; + auto pop = nvobj::pool::create( + path, "StringTest: front", PMEMOBJ_MIN_POOL, S_IWUSR | S_IRUSR); + + auto r = pop.root(); + + try { + nvobj::transaction::run(pop, [&] { + r->s1 = nvobj::make_persistent("1"); + r->s2 = nvobj::make_persistent( + "1234567890123456789012345678901234567890"); + r->s3 = nvobj::make_persistent( + "1234567890123456789012345678901234567890" + "1234567890123456789012345678901234567890" + "1234567890123456789012345678901234567890" + "1234567890"); + }); + + test(*r->s1); + test(*r->s2); + test(*r->s3); + + nvobj::transaction::run(pop, [&] { + nvobj::delete_persistent(r->s1); + nvobj::delete_persistent(r->s2); + nvobj::delete_persistent(r->s3); + }); + } catch (std::exception &e) { + UT_FATALexc(e); + } + + pop.close(); + + return 0; +} diff --git a/tests/external/libcxx/basic_string/string.access/index.pass.cpp b/tests/external/libcxx/basic_string/string.access/index.pass.cpp new file mode 100644 index 0000000..65f8274 --- /dev/null +++ b/tests/external/libcxx/basic_string/string.access/index.pass.cpp @@ -0,0 +1,87 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// Copyright 2019, Intel Corporation +// +// Modified to test pmem::obj containers +// + +#include "unittest.hpp" + +#include +#include + +namespace nvobj = pmem::obj; +namespace pmem_exp = nvobj::experimental; +using C = pmem_exp::string; + +struct root { + nvobj::persistent_ptr s1; + nvobj::persistent_ptr s2; +}; + +template +void +test(pmem::obj::pool &pop, S &s) +{ + const S &cs = s; + for (typename S::size_type i = 0; i < cs.size(); ++i) { + UT_ASSERT(s[i] == static_cast('0' + i % 10)); + UT_ASSERT(cs[i] == s[i]); + } + UT_ASSERT(cs[cs.size()] == '\0'); + + nvobj::transaction::run(pop, [&] { + const nvobj::persistent_ptr s2 = nvobj::make_persistent(); + UT_ASSERT((*s2)[0] == '\0'); + nvobj::delete_persistent(s2); + }); +} + +int +main(int argc, char *argv[]) +{ + START(); + + if (argc < 2) { + std::cerr << "usage: " << argv[0] << " file-name" << std::endl; + return 1; + } + + auto path = argv[1]; + auto pop = nvobj::pool::create( + path, "StringTest: index", PMEMOBJ_MIN_POOL, S_IWUSR | S_IRUSR); + + auto r = pop.root(); + + try { + nvobj::transaction::run(pop, [&] { + r->s1 = nvobj::make_persistent("0123456789"); + r->s2 = nvobj::make_persistent( + "0123456789012345678901234567890123456789" + "0123456789012345678901234567890123456789" + "0123456789012345678901234567890123456789" + "01234567890"); + }); + + test(pop, *r->s1); + test(pop, *r->s2); + + nvobj::transaction::run(pop, [&] { + nvobj::delete_persistent(r->s1); + nvobj::delete_persistent(r->s2); + }); + } catch (std::exception &e) { + UT_FATALexc(e); + } + + pop.close(); + + return 0; +} diff --git a/tests/external/libcxx/basic_string/string.capacity/capacity.pass.cpp b/tests/external/libcxx/basic_string/string.capacity/capacity.pass.cpp new file mode 100644 index 0000000..79fbd2e --- /dev/null +++ b/tests/external/libcxx/basic_string/string.capacity/capacity.pass.cpp @@ -0,0 +1,64 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// + +// size_type capacity() const; + +#include +#include + +#include "test_allocator.h" +#include "min_allocator.h" + +#include "test_macros.h" + +template +void +test(S s) +{ + S::allocator_type::throw_after = 0; +#ifndef TEST_HAS_NO_EXCEPTIONS + try +#endif + { + while (s.size() < s.capacity()) + s.push_back(typename S::value_type()); + assert(s.size() == s.capacity()); + } +#ifndef TEST_HAS_NO_EXCEPTIONS + catch (...) + { + assert(false); + } +#endif + S::allocator_type::throw_after = INT_MAX; +} + +int main() +{ + { + typedef std::basic_string, test_allocator > S; + S s; + test(s); + s.assign(10, 'a'); + s.erase(5); + test(s); + s.assign(100, 'a'); + s.erase(50); + test(s); + } +#if TEST_STD_VER >= 11 + { + typedef std::basic_string, min_allocator> S; + S s; + assert(s.capacity() > 0); + } +#endif +} diff --git a/tests/external/libcxx/basic_string/string.capacity/clear.pass.cpp b/tests/external/libcxx/basic_string/string.capacity/clear.pass.cpp new file mode 100644 index 0000000..e0254c0 --- /dev/null +++ b/tests/external/libcxx/basic_string/string.capacity/clear.pass.cpp @@ -0,0 +1,57 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// + +// void clear(); + +#include +#include + +#include "min_allocator.h" + +template +void +test(S s) +{ + s.clear(); + assert(s.size() == 0); +} + +int main() +{ + { + typedef std::string S; + S s; + test(s); + + s.assign(10, 'a'); + s.erase(5); + test(s); + + s.assign(100, 'a'); + s.erase(50); + test(s); + } +#if TEST_STD_VER >= 11 + { + typedef std::basic_string, min_allocator> S; + S s; + test(s); + + s.assign(10, 'a'); + s.erase(5); + test(s); + + s.assign(100, 'a'); + s.erase(50); + test(s); + } +#endif +} diff --git a/tests/external/libcxx/basic_string/string.capacity/empty.fail.cpp b/tests/external/libcxx/basic_string/string.capacity/empty.fail.cpp new file mode 100644 index 0000000..addb02e --- /dev/null +++ b/tests/external/libcxx/basic_string/string.capacity/empty.fail.cpp @@ -0,0 +1,28 @@ +// -*- C++ -*- +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// + +// class deque + +// bool empty() const noexcept; + +// UNSUPPORTED: c++98, c++03, c++11, c++14, c++17 +// UNSUPPORTED: clang-3.3, clang-3.4, clang-3.5, clang-3.6, clang-3.7, clang-3.8 + +#include + +#include "test_macros.h" + +int main () +{ + std::string c; + c.empty(); // expected-error {{ignoring return value of function declared with 'nodiscard' attribute}} +} diff --git a/tests/external/libcxx/basic_string/string.capacity/empty.pass.cpp b/tests/external/libcxx/basic_string/string.capacity/empty.pass.cpp new file mode 100644 index 0000000..a61a410 --- /dev/null +++ b/tests/external/libcxx/basic_string/string.capacity/empty.pass.cpp @@ -0,0 +1,44 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// + +// bool empty() const noexcept; + +#include +#include + +#include "test_macros.h" +#include "min_allocator.h" + +template +void +test(const S& s) +{ + ASSERT_NOEXCEPT(s.empty()); + assert(s.empty() == (s.size() == 0)); +} + +int main() +{ + { + typedef std::string S; + test(S()); + test(S("123")); + test(S("12345678901234567890123456789012345678901234567890")); + } +#if TEST_STD_VER >= 11 + { + typedef std::basic_string, min_allocator> S; + test(S()); + test(S("123")); + test(S("12345678901234567890123456789012345678901234567890")); + } +#endif +} diff --git a/tests/external/libcxx/basic_string/string.capacity/length.pass.cpp b/tests/external/libcxx/basic_string/string.capacity/length.pass.cpp new file mode 100644 index 0000000..13e966d --- /dev/null +++ b/tests/external/libcxx/basic_string/string.capacity/length.pass.cpp @@ -0,0 +1,42 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// + +// size_type length() const; + +#include +#include + +#include "min_allocator.h" + +template +void +test(const S& s) +{ + assert(s.length() == s.size()); +} + +int main() +{ + { + typedef std::string S; + test(S()); + test(S("123")); + test(S("12345678901234567890123456789012345678901234567890")); + } +#if TEST_STD_VER >= 11 + { + typedef std::basic_string, min_allocator> S; + test(S()); + test(S("123")); + test(S("12345678901234567890123456789012345678901234567890")); + } +#endif +} diff --git a/tests/external/libcxx/basic_string/string.capacity/max_size.pass.cpp b/tests/external/libcxx/basic_string/string.capacity/max_size.pass.cpp new file mode 100644 index 0000000..a8f8126 --- /dev/null +++ b/tests/external/libcxx/basic_string/string.capacity/max_size.pass.cpp @@ -0,0 +1,74 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// UNSUPPORTED: libcpp-no-exceptions +// + +// size_type max_size() const; + +// NOTE: asan and msan will fail for one of two reasons +// 1. If allocator_may_return_null=0 then they will fail because the allocation +// returns null. +// 2. If allocator_may_return_null=1 then they will fail because the allocation +// is too large to succeed. +// UNSUPPORTED: sanitizer-new-delete + +#include +#include + +#include "min_allocator.h" + +template +void +test1(const S& s) +{ + S s2(s); + const size_t sz = s2.max_size() - 1; + try { s2.resize(sz, 'x'); } + catch ( const std::bad_alloc & ) { return ; } + assert ( s2.size() == sz ); +} + +template +void +test2(const S& s) +{ + S s2(s); + const size_t sz = s2.max_size(); + try { s2.resize(sz, 'x'); } + catch ( const std::bad_alloc & ) { return ; } + assert ( s.size() == sz ); +} + +template +void +test(const S& s) +{ + assert(s.max_size() >= s.size()); + test1(s); + test2(s); +} + +int main() +{ + { + typedef std::string S; + test(S()); + test(S("123")); + test(S("12345678901234567890123456789012345678901234567890")); + } +#if TEST_STD_VER >= 11 + { + typedef std::basic_string, min_allocator> S; + test(S()); + test(S("123")); + test(S("12345678901234567890123456789012345678901234567890")); + } +#endif +} diff --git a/tests/external/libcxx/basic_string/string.capacity/over_max_size.pass.cpp b/tests/external/libcxx/basic_string/string.capacity/over_max_size.pass.cpp new file mode 100644 index 0000000..f36f53e --- /dev/null +++ b/tests/external/libcxx/basic_string/string.capacity/over_max_size.pass.cpp @@ -0,0 +1,54 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// UNSUPPORTED: libcpp-no-exceptions +// XFAIL: with_system_cxx_lib=macosx10.11 +// XFAIL: with_system_cxx_lib=macosx10.10 +// XFAIL: with_system_cxx_lib=macosx10.9 +// XFAIL: with_system_cxx_lib=macosx10.8 +// XFAIL: with_system_cxx_lib=macosx10.7 + +// + +// size_type max_size() const; + +#include +#include + +#include "min_allocator.h" + +template +void +test(const S& s) +{ + assert(s.max_size() >= s.size()); + S s2(s); + const size_t sz = s2.max_size() + 1; + try { s2.resize(sz, 'x'); } + catch ( const std::length_error & ) { return ; } + assert ( false ); +} + +int main() +{ + { + typedef std::string S; + test(S()); + test(S("123")); + test(S("12345678901234567890123456789012345678901234567890")); + } +#if TEST_STD_VER >= 11 + { + typedef std::basic_string, min_allocator> S; + test(S()); + test(S("123")); + test(S("12345678901234567890123456789012345678901234567890")); + } +#endif +} diff --git a/tests/external/libcxx/basic_string/string.capacity/reserve.pass.cpp b/tests/external/libcxx/basic_string/string.capacity/reserve.pass.cpp new file mode 100644 index 0000000..7210152 --- /dev/null +++ b/tests/external/libcxx/basic_string/string.capacity/reserve.pass.cpp @@ -0,0 +1,128 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// + +// void reserve(size_type res_arg=0); + +#include +#include +#include + +#include "test_macros.h" +#include "min_allocator.h" + +template +void +test(S s) +{ + typename S::size_type old_cap = s.capacity(); + S s0 = s; + s.reserve(); + LIBCPP_ASSERT(s.__invariants()); + assert(s == s0); + assert(s.capacity() <= old_cap); + assert(s.capacity() >= s.size()); +} + +template +void +test(S s, typename S::size_type res_arg) +{ + typename S::size_type old_cap = s.capacity(); + ((void)old_cap); // Prevent unused warning + S s0 = s; + if (res_arg <= s.max_size()) + { + s.reserve(res_arg); + assert(s == s0); + assert(s.capacity() >= res_arg); + assert(s.capacity() >= s.size()); + } +#ifndef TEST_HAS_NO_EXCEPTIONS + else + { + try + { + s.reserve(res_arg); + assert(false); + } + catch (std::length_error&) + { + assert(res_arg > s.max_size()); + } + } +#endif +} + +int main() +{ + { + typedef std::string S; + { + S s; + test(s); + + s.assign(10, 'a'); + s.erase(5); + test(s); + + s.assign(100, 'a'); + s.erase(50); + test(s); + } + { + S s; + test(s, 5); + test(s, 10); + test(s, 50); + } + { + S s(100, 'a'); + s.erase(50); + test(s, 5); + test(s, 10); + test(s, 50); + test(s, 100); + test(s, S::npos); + } + } +#if TEST_STD_VER >= 11 + { + typedef std::basic_string, min_allocator> S; + { + S s; + test(s); + + s.assign(10, 'a'); + s.erase(5); + test(s); + + s.assign(100, 'a'); + s.erase(50); + test(s); + } + { + S s; + test(s, 5); + test(s, 10); + test(s, 50); + } + { + S s(100, 'a'); + s.erase(50); + test(s, 5); + test(s, 10); + test(s, 50); + test(s, 100); + test(s, S::npos); + } + } +#endif +} diff --git a/tests/external/libcxx/basic_string/string.capacity/resize_size.pass.cpp b/tests/external/libcxx/basic_string/string.capacity/resize_size.pass.cpp new file mode 100644 index 0000000..78200d5 --- /dev/null +++ b/tests/external/libcxx/basic_string/string.capacity/resize_size.pass.cpp @@ -0,0 +1,89 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// + +// void resize(size_type n); + +#include +#include +#include + +#include "test_macros.h" +#include "min_allocator.h" + +template +void +test(S s, typename S::size_type n, S expected) +{ + if (n <= s.max_size()) + { + s.resize(n); + LIBCPP_ASSERT(s.__invariants()); + assert(s == expected); + } +#ifndef TEST_HAS_NO_EXCEPTIONS + else + { + try + { + s.resize(n); + assert(false); + } + catch (std::length_error&) + { + assert(n > s.max_size()); + } + } +#endif +} + +int main() +{ + { + typedef std::string S; + test(S(), 0, S()); + test(S(), 1, S(1, '\0')); + test(S(), 10, S(10, '\0')); + test(S(), 100, S(100, '\0')); + test(S("12345"), 0, S()); + test(S("12345"), 2, S("12")); + test(S("12345"), 5, S("12345")); + test(S("12345"), 15, S("12345\0\0\0\0\0\0\0\0\0\0", 15)); + test(S("12345678901234567890123456789012345678901234567890"), 0, S()); + test(S("12345678901234567890123456789012345678901234567890"), 10, + S("1234567890")); + test(S("12345678901234567890123456789012345678901234567890"), 50, + S("12345678901234567890123456789012345678901234567890")); + test(S("12345678901234567890123456789012345678901234567890"), 60, + S("12345678901234567890123456789012345678901234567890\0\0\0\0\0\0\0\0\0\0", 60)); + test(S(), S::npos, S("not going to happen")); + } +#if TEST_STD_VER >= 11 + { + typedef std::basic_string, min_allocator> S; + test(S(), 0, S()); + test(S(), 1, S(1, '\0')); + test(S(), 10, S(10, '\0')); + test(S(), 100, S(100, '\0')); + test(S("12345"), 0, S()); + test(S("12345"), 2, S("12")); + test(S("12345"), 5, S("12345")); + test(S("12345"), 15, S("12345\0\0\0\0\0\0\0\0\0\0", 15)); + test(S("12345678901234567890123456789012345678901234567890"), 0, S()); + test(S("12345678901234567890123456789012345678901234567890"), 10, + S("1234567890")); + test(S("12345678901234567890123456789012345678901234567890"), 50, + S("12345678901234567890123456789012345678901234567890")); + test(S("12345678901234567890123456789012345678901234567890"), 60, + S("12345678901234567890123456789012345678901234567890\0\0\0\0\0\0\0\0\0\0", 60)); + test(S(), S::npos, S("not going to happen")); + } +#endif +} diff --git a/tests/external/libcxx/basic_string/string.capacity/resize_size_char.pass.cpp b/tests/external/libcxx/basic_string/string.capacity/resize_size_char.pass.cpp new file mode 100644 index 0000000..288eb32 --- /dev/null +++ b/tests/external/libcxx/basic_string/string.capacity/resize_size_char.pass.cpp @@ -0,0 +1,89 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// + +// void resize(size_type n, charT c); + +#include +#include +#include + +#include "test_macros.h" +#include "min_allocator.h" + +template +void +test(S s, typename S::size_type n, typename S::value_type c, S expected) +{ + if (n <= s.max_size()) + { + s.resize(n, c); + LIBCPP_ASSERT(s.__invariants()); + assert(s == expected); + } +#ifndef TEST_HAS_NO_EXCEPTIONS + else + { + try + { + s.resize(n, c); + assert(false); + } + catch (std::length_error&) + { + assert(n > s.max_size()); + } + } +#endif +} + +int main() +{ + { + typedef std::string S; + test(S(), 0, 'a', S()); + test(S(), 1, 'a', S("a")); + test(S(), 10, 'a', S(10, 'a')); + test(S(), 100, 'a', S(100, 'a')); + test(S("12345"), 0, 'a', S()); + test(S("12345"), 2, 'a', S("12")); + test(S("12345"), 5, 'a', S("12345")); + test(S("12345"), 15, 'a', S("12345aaaaaaaaaa")); + test(S("12345678901234567890123456789012345678901234567890"), 0, 'a', S()); + test(S("12345678901234567890123456789012345678901234567890"), 10, 'a', + S("1234567890")); + test(S("12345678901234567890123456789012345678901234567890"), 50, 'a', + S("12345678901234567890123456789012345678901234567890")); + test(S("12345678901234567890123456789012345678901234567890"), 60, 'a', + S("12345678901234567890123456789012345678901234567890aaaaaaaaaa")); + test(S(), S::npos, 'a', S("not going to happen")); + } +#if TEST_STD_VER >= 11 + { + typedef std::basic_string, min_allocator> S; + test(S(), 0, 'a', S()); + test(S(), 1, 'a', S("a")); + test(S(), 10, 'a', S(10, 'a')); + test(S(), 100, 'a', S(100, 'a')); + test(S("12345"), 0, 'a', S()); + test(S("12345"), 2, 'a', S("12")); + test(S("12345"), 5, 'a', S("12345")); + test(S("12345"), 15, 'a', S("12345aaaaaaaaaa")); + test(S("12345678901234567890123456789012345678901234567890"), 0, 'a', S()); + test(S("12345678901234567890123456789012345678901234567890"), 10, 'a', + S("1234567890")); + test(S("12345678901234567890123456789012345678901234567890"), 50, 'a', + S("12345678901234567890123456789012345678901234567890")); + test(S("12345678901234567890123456789012345678901234567890"), 60, 'a', + S("12345678901234567890123456789012345678901234567890aaaaaaaaaa")); + test(S(), S::npos, 'a', S("not going to happen")); + } +#endif +} diff --git a/tests/external/libcxx/basic_string/string.capacity/shrink_to_fit.pass.cpp b/tests/external/libcxx/basic_string/string.capacity/shrink_to_fit.pass.cpp new file mode 100644 index 0000000..656ea1d --- /dev/null +++ b/tests/external/libcxx/basic_string/string.capacity/shrink_to_fit.pass.cpp @@ -0,0 +1,63 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// + +// void shrink_to_fit(); + +#include +#include + +#include "test_macros.h" +#include "min_allocator.h" + +template +void +test(S s) +{ + typename S::size_type old_cap = s.capacity(); + S s0 = s; + s.shrink_to_fit(); + LIBCPP_ASSERT(s.__invariants()); + assert(s == s0); + assert(s.capacity() <= old_cap); + assert(s.capacity() >= s.size()); +} + +int main() +{ + { + typedef std::string S; + S s; + test(s); + + s.assign(10, 'a'); + s.erase(5); + test(s); + + s.assign(100, 'a'); + s.erase(50); + test(s); + } +#if TEST_STD_VER >= 11 + { + typedef std::basic_string, min_allocator> S; + S s; + test(s); + + s.assign(10, 'a'); + s.erase(5); + test(s); + + s.assign(100, 'a'); + s.erase(50); + test(s); + } +#endif +} diff --git a/tests/external/libcxx/basic_string/string.capacity/size.pass.cpp b/tests/external/libcxx/basic_string/string.capacity/size.pass.cpp new file mode 100644 index 0000000..4657aea --- /dev/null +++ b/tests/external/libcxx/basic_string/string.capacity/size.pass.cpp @@ -0,0 +1,42 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// + +// size_type size() const; + +#include +#include + +#include "min_allocator.h" + +template +void +test(const S& s, typename S::size_type c) +{ + assert(s.size() == c); +} + +int main() +{ + { + typedef std::string S; + test(S(), 0); + test(S("123"), 3); + test(S("12345678901234567890123456789012345678901234567890"), 50); + } +#if TEST_STD_VER >= 11 + { + typedef std::basic_string, min_allocator> S; + test(S(), 0); + test(S("123"), 3); + test(S("12345678901234567890123456789012345678901234567890"), 50); + } +#endif +} diff --git a/tests/external/libcxx/basic_string/string.cons/T_size_size.pass.cpp b/tests/external/libcxx/basic_string/string.cons/T_size_size.pass.cpp new file mode 100644 index 0000000..67ac434 --- /dev/null +++ b/tests/external/libcxx/basic_string/string.cons/T_size_size.pass.cpp @@ -0,0 +1,187 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// + +// template +// basic_string(const _Tp& __t, size_type __pos, size_type __n, +// const allocator_type& __a = allocator_type()); +// +// Mostly we're testing string_view here + +#include +#include +#include +#include +#include + +#include "test_macros.h" +#include "test_allocator.h" +#include "min_allocator.h" + +template +void +test(SV sv, std::size_t pos, std::size_t n) +{ + typedef typename S::traits_type T; + typedef typename S::allocator_type A; + typedef typename S::size_type Size; + if (pos <= sv.size()) + { + S s2(sv, static_cast(pos), static_cast(n)); + LIBCPP_ASSERT(s2.__invariants()); + assert(pos <= sv.size()); + std::size_t rlen = std::min(sv.size() - pos, n); + assert(s2.size() == rlen); + assert(T::compare(s2.data(), sv.data() + pos, rlen) == 0); + assert(s2.get_allocator() == A()); + assert(s2.capacity() >= s2.size()); + } +#ifndef TEST_HAS_NO_EXCEPTIONS + else + { + try + { + S s2(sv, static_cast(pos), static_cast(n)); + assert(false); + } + catch (std::out_of_range&) + { + assert(pos > sv.size()); + } + } +#endif +} + +template +void +test(SV sv, std::size_t pos, std::size_t n, const typename S::allocator_type& a) +{ + typedef typename S::traits_type T; + typedef typename S::size_type Size; + if (pos <= sv.size()) + { + S s2(sv, static_cast(pos), static_cast(n), a); + LIBCPP_ASSERT(s2.__invariants()); + assert(pos <= sv.size()); + std::size_t rlen = std::min(sv.size() - pos, n); + assert(s2.size() == rlen); + assert(T::compare(s2.data(), sv.data() + pos, rlen) == 0); + assert(s2.get_allocator() == a); + assert(s2.capacity() >= s2.size()); + } +#ifndef TEST_HAS_NO_EXCEPTIONS + else + { + try + { + S s2(sv, static_cast(pos), static_cast(n), a); + assert(false); + } + catch (std::out_of_range&) + { + assert(pos > sv.size()); + } + } +#endif +} + +int main() +{ + + { + typedef test_allocator A; + typedef std::basic_string_view > SV; + typedef std::basic_string , A> S; + + test(SV(), 0, 0); + test(SV(), 0, 1); + test(SV(), 1, 0); + test(SV(), 1, 1); + test(SV(), 1, 2); + test(SV("1"), 0, 0); + test(SV("1"), 0, 1); + test(SV("1234567890123456789012345678901234567890123456789012345678901234567890"), 50, 0); + test(SV("1234567890123456789012345678901234567890123456789012345678901234567890"), 50, 1); + test(SV("1234567890123456789012345678901234567890123456789012345678901234567890"), 50, 10); + test(SV("1234567890123456789012345678901234567890123456789012345678901234567890"), 50, 100); + + test(SV(), 0, 0, A(4)); + test(SV(), 0, 1, A(4)); + test(SV(), 1, 0, A(4)); + test(SV(), 1, 1, A(4)); + test(SV(), 1, 2, A(4)); + test(SV("1"), 0, 0, A(6)); + test(SV("1"), 0, 1, A(6)); + test(SV("1234567890123456789012345678901234567890123456789012345678901234567890"), 50, 0, A(8)); + test(SV("1234567890123456789012345678901234567890123456789012345678901234567890"), 50, 1, A(8)); + test(SV("1234567890123456789012345678901234567890123456789012345678901234567890"), 50, 10, A(8)); + test(SV("1234567890123456789012345678901234567890123456789012345678901234567890"), 50, 100, A(8)); + } + +#if TEST_STD_VER >= 11 + { + typedef min_allocator A; + typedef std::basic_string_view > SV; + typedef std::basic_string , A> S; + + test(SV(), 0, 0); + test(SV(), 0, 1); + test(SV(), 1, 0); + test(SV(), 1, 1); + test(SV(), 1, 2); + test(SV("1"), 0, 0); + test(SV("1"), 0, 1); + test(SV("1234567890123456789012345678901234567890123456789012345678901234567890"), 50, 0); + test(SV("1234567890123456789012345678901234567890123456789012345678901234567890"), 50, 1); + test(SV("1234567890123456789012345678901234567890123456789012345678901234567890"), 50, 10); + test(SV("1234567890123456789012345678901234567890123456789012345678901234567890"), 50, 100); + + test(SV(), 0, 0, A()); + test(SV(), 0, 1, A()); + test(SV(), 1, 0, A()); + test(SV(), 1, 1, A()); + test(SV(), 1, 2, A()); + test(SV("1"), 0, 0, A()); + test(SV("1"), 0, 1, A()); + test(SV("1234567890123456789012345678901234567890123456789012345678901234567890"), 50, 0, A()); + test(SV("1234567890123456789012345678901234567890123456789012345678901234567890"), 50, 1, A()); + test(SV("1234567890123456789012345678901234567890123456789012345678901234567890"), 50, 10, A()); + test(SV("1234567890123456789012345678901234567890123456789012345678901234567890"), 50, 100, A()); + } +#endif + { + typedef std::string S; + typedef std::string_view SV; + S s = "ABCD"; + SV sv = "EFGH"; + char arr[] = "IJKL"; + + S s1("CDEF", 4); // calls ctor(const char *, len) + assert(s1 == "CDEF"); + + S s2("QRST", 0, 3); // calls ctor(string("QRST", pos, len) + assert(s2 == "QRS"); + + S s3(sv, 0, std::string::npos); // calls ctor(T, pos, npos) + assert(s3 == sv); + + S s4(sv, 0, 3); // calls ctor(T, pos, len) + assert(s4 == "EFG"); + + S s5(arr, 0, 2); // calls ctor(const char *, len) + assert(s5 == "IJ"); + + S s6(arr, 0); // calls ctor(const char *, len) + assert(s6 == ""); + + S s7(s.data(), 2); // calls ctor(const char *, len) + assert(s7 == "AB"); + } +} diff --git a/tests/external/libcxx/basic_string/string.cons/brace_assignment.pass.cpp b/tests/external/libcxx/basic_string/string.cons/brace_assignment.pass.cpp new file mode 100644 index 0000000..3b38fd4 --- /dev/null +++ b/tests/external/libcxx/basic_string/string.cons/brace_assignment.pass.cpp @@ -0,0 +1,78 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// Copyright 2019, Intel Corporation +// +// Modified to test pmem::obj containers +// + +#include "unittest.hpp" + +#include + +namespace nvobj = pmem::obj; +namespace pmem_exp = pmem::obj::experimental; +using S = pmem_exp::string; + +struct root { + nvobj::persistent_ptr s; + nvobj::persistent_ptr tmp; +}; + +int +main(int argc, char *argv[]) +{ + START(); + + if (argc < 2) { + std::cerr << "usage: " << argv[0] << " file-name" << std::endl; + return 1; + } + + auto path = argv[1]; + auto pop = nvobj::pool::create( + path, "string_test", PMEMOBJ_MIN_POOL, S_IWUSR | S_IRUSR); + + auto r = pop.root(); + + try { + nvobj::transaction::run(pop, [&] { + r->s = nvobj::make_persistent("hello world"); + }); + + *r->s = {}; + UT_ASSERT(r->s->empty()); + + nvobj::transaction::run( + pop, [&] { nvobj::delete_persistent(r->s); }); + } catch (std::exception &e) { + UT_FATALexc(e); + } + + try { + nvobj::transaction::run(pop, [&] { + r->s = nvobj::make_persistent("hello world"); + r->tmp = nvobj::make_persistent("abc", 2U); + }); + + *r->s = *r->tmp; + UT_ASSERT(*r->s == "ab"); + + nvobj::transaction::run(pop, [&] { + nvobj::delete_persistent(r->s); + nvobj::delete_persistent(r->tmp); + }); + } catch (std::exception &e) { + UT_FATALexc(e); + } + + pop.close(); + + return 0; +} diff --git a/tests/external/libcxx/basic_string/string.cons/char_assignment.pass.cpp b/tests/external/libcxx/basic_string/string.cons/char_assignment.pass.cpp new file mode 100644 index 0000000..88ff601 --- /dev/null +++ b/tests/external/libcxx/basic_string/string.cons/char_assignment.pass.cpp @@ -0,0 +1,80 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// Copyright 2019, Intel Corporation +// +// Modified to test pmem::obj containers +// + +#include "unittest.hpp" + +#include + +namespace nvobj = pmem::obj; +namespace pmem_exp = pmem::obj::experimental; +using S = pmem_exp::string; + +struct root { + nvobj::persistent_ptr s_arr[4]; +}; + +template +void +test(S &s1, typename S::value_type s2) +{ + typedef typename S::traits_type T; + s1 = s2; + UT_ASSERT(s1.size() == 1); + UT_ASSERT(T::eq(s1[0], s2)); + UT_ASSERT(s1.capacity() >= s1.size()); +} + +int +main(int argc, char *argv[]) +{ + START(); + + if (argc < 2) { + std::cerr << "usage: " << argv[0] << " file-name" << std::endl; + return 1; + } + + auto path = argv[1]; + auto pop = nvobj::pool::create( + path, "string_test", PMEMOBJ_MIN_POOL, S_IWUSR | S_IRUSR); + + auto &s_arr = pop.root()->s_arr; + + try { + nvobj::transaction::run(pop, [&] { + s_arr[0] = nvobj::make_persistent(); + s_arr[1] = nvobj::make_persistent("1"); + s_arr[2] = nvobj::make_persistent("123456789"); + s_arr[3] = nvobj::make_persistent( + "1234567890123456789012345678901234567890123456789012345678901234567890"); + }); + + test(*s_arr[0], 'a'); + test(*s_arr[1], 'a'); + test(*s_arr[2], 'a'); + test(*s_arr[3], 'a'); + + nvobj::transaction::run(pop, [&] { + for (unsigned i = 0; i < 4; ++i) { + nvobj::delete_persistent(s_arr[i]); + } + }); + } catch (std::exception &e) { + UT_FATALexc(e); + } + + pop.close(); + + return 0; +} diff --git a/tests/external/libcxx/basic_string/string.cons/copy.pass.cpp b/tests/external/libcxx/basic_string/string.cons/copy.pass.cpp new file mode 100644 index 0000000..6c3e11f --- /dev/null +++ b/tests/external/libcxx/basic_string/string.cons/copy.pass.cpp @@ -0,0 +1,175 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// Copyright 2019, Intel Corporation +// +// Modified to test pmem::obj containers +// + +#include "unittest.hpp" + +#include +#include +#include +#include +#include + +namespace pmem_exp = pmem::obj::experimental; +namespace nvobj = pmem::obj; + +struct root { + nvobj::persistent_ptr s; + nvobj::persistent_ptr ws; +}; + +template +void +test(S &s1, pmem::obj::pool &pop, nvobj::persistent_ptr &ptr) +{ + using T = typename S::traits_type; + + nvobj::transaction::run(pop, + [&] { ptr = nvobj::make_persistent(s1); }); + + auto &s2 = *ptr; + + UT_ASSERT(s2 == s1); + + UT_ASSERT(s1.size() == s2.size()); + UT_ASSERT(T::compare(s2.c_str(), s1.c_str(), s1.size()) == 0); + UT_ASSERT(s2.capacity() >= s2.size()); + + nvobj::transaction::run(pop, [&] { + UT_ASSERT(s2.c_str() == s2.data()); + UT_ASSERT(s2.c_str() == s2.cdata()); + UT_ASSERT(s2.c_str() == static_cast(s2).data()); + }); + + nvobj::transaction::run(pop, [&] { nvobj::delete_persistent(ptr); }); +} + +void +run(pmem::obj::pool &pop) +{ + auto r = pop.root(); + + try { + nvobj::persistent_ptr s1, s2, s3, s4; + + nvobj::transaction::run(pop, [&] { + s1 = nvobj::make_persistent(); + }); + + nvobj::transaction::run(pop, [&] { + s2 = nvobj::make_persistent("1"); + }); + + nvobj::transaction::run(pop, [&] { + s3 = nvobj::make_persistent( + "1234567890"); + }); + + nvobj::transaction::run(pop, [&] { + s4 = nvobj::make_persistent( + "1234567890123456789012345678901234567890" + "1234567890123456789012345678901234567890" + "1234567890123456789012345678901234567890" + "1234567890"); + }); + + test(*s1, pop, r->s); + test(*s2, pop, r->s); + test(*s3, pop, r->s); + test(*s4, pop, r->s); + + nvobj::transaction::run(pop, [&] { + nvobj::delete_persistent(s1); + nvobj::delete_persistent(s2); + nvobj::delete_persistent(s3); + nvobj::delete_persistent(s4); + }); + + } catch (std::exception &e) { + UT_FATALexc(e); + } +} + +void +run_wstring(pmem::obj::pool &pop) +{ + auto r = pop.root(); + + try { + nvobj::persistent_ptr ws1, ws2, ws3, ws4; + + nvobj::transaction::run(pop, [&] { + ws1 = nvobj::make_persistent(); + }); + + nvobj::transaction::run(pop, [&] { + ws2 = nvobj::make_persistent(L"1"); + }); + + nvobj::transaction::run(pop, [&] { + ws3 = nvobj::make_persistent( + L"12345678901234567890"); + }); + + nvobj::transaction::run(pop, [&] { + ws4 = nvobj::make_persistent( + L"1234567890123456789012345678901234567890" + "1234567890123456789012345678901234567890" + "1234567890123456789012345678901234567890" + "1234567890"); + }); + + test(*ws1, pop, r->ws); + test(*ws2, pop, r->ws); + test(*ws3, pop, r->ws); + test(*ws4, pop, r->ws); + + nvobj::transaction::run(pop, [&] { + nvobj::delete_persistent(ws1); + nvobj::delete_persistent(ws2); + nvobj::delete_persistent(ws3); + nvobj::delete_persistent(ws4); + }); + + } catch (std::exception &e) { + UT_FATALexc(e); + } +} + +int +main(int argc, char *argv[]) +{ + START(); + + if (argc != 2) + UT_FATAL("usage: %s file-name", argv[0]); + + const char *path = argv[1]; + + pmem::obj::pool pop; + + try { + pop = pmem::obj::pool::create(path, "string_test", + PMEMOBJ_MIN_POOL, + S_IWUSR | S_IRUSR); + } catch (...) { + UT_FATAL("!pmemobj_create: %s", path); + } + + run(pop); + run_wstring(pop); + + pop.close(); + + return 0; +} diff --git a/tests/external/libcxx/basic_string/string.cons/copy_assignment.pass.cpp b/tests/external/libcxx/basic_string/string.cons/copy_assignment.pass.cpp new file mode 100644 index 0000000..8b40f9f --- /dev/null +++ b/tests/external/libcxx/basic_string/string.cons/copy_assignment.pass.cpp @@ -0,0 +1,121 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// Copyright 2019, Intel Corporation +// +// Modified to test pmem::obj containers +// + +#include "unittest.hpp" + +#include + +namespace nvobj = pmem::obj; +namespace pmem_exp = pmem::obj::experimental; +using S = pmem_exp::string; + +struct root { + nvobj::persistent_ptr s1; + nvobj::persistent_ptr s_arr[7]; +}; + +template +void +test(nvobj::pool &pop, const S &s, const S &s2) +{ + auto r = pop.root(); + nvobj::transaction::run(pop, + [&] { r->s1 = nvobj::make_persistent(s); }); + auto &s1 = *r->s1; + + s1 = s2; + UT_ASSERT(s1 == s2); + UT_ASSERT(s1.capacity() >= s1.size()); + + nvobj::transaction::run(pop, + [&] { nvobj::delete_persistent(r->s1); }); +} + +void +test_self_assignment(nvobj::pool &pop, const S &s1) +{ + auto r = pop.root(); + + nvobj::transaction::run(pop, + [&] { r->s1 = nvobj::make_persistent(s1); }); + + /* Workaround for -Wself-assign-overloaded compile error */ + auto &s = *r->s1; + + s = *r->s1; + UT_ASSERT(s == s1); + UT_ASSERT(s.capacity() >= s1.size()); + + nvobj::transaction::run(pop, + [&] { nvobj::delete_persistent(r->s1); }); +} + +int +main(int argc, char *argv[]) +{ + START(); + + if (argc < 2) { + std::cerr << "usage: " << argv[0] << " file-name" << std::endl; + return 1; + } + + auto path = argv[1]; + auto pop = nvobj::pool::create( + path, "string_test", PMEMOBJ_MIN_POOL, S_IWUSR | S_IRUSR); + + auto &s_arr = pop.root()->s_arr; + + try { + nvobj::transaction::run(pop, [&] { + s_arr[0] = nvobj::make_persistent(); + s_arr[1] = nvobj::make_persistent("1"); + s_arr[2] = nvobj::make_persistent("2"); + s_arr[3] = nvobj::make_persistent("123456789"); + s_arr[4] = nvobj::make_persistent( + "1234567890123456789012345678901234567890123456789012345678901234567890"); + s_arr[5] = nvobj::make_persistent( + "1234567890123456789012345678901234567890123456789012345678901234567890" + "1234567890123456789012345678901234567890123456789012345678901234567890"); + s_arr[6] = nvobj::make_persistent( + "abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz"); + }); + + test(pop, *s_arr[0], *s_arr[0]); + test(pop, *s_arr[1], *s_arr[0]); + test(pop, *s_arr[0], *s_arr[1]); + test(pop, *s_arr[1], *s_arr[2]); + test(pop, *s_arr[1], *s_arr[2]); + + test(pop, *s_arr[0], *s_arr[6]); + test(pop, *s_arr[3], *s_arr[6]); + test(pop, *s_arr[4], *s_arr[6]); + test(pop, *s_arr[5], *s_arr[6]); + + test_self_assignment(pop, *s_arr[0]); + test_self_assignment(pop, *s_arr[3]); + + nvobj::transaction::run(pop, [&] { + for (unsigned i = 0; i < 7; ++i) { + nvobj::delete_persistent(s_arr[i]); + } + }); + } catch (std::exception &e) { + UT_FATALexc(e); + } + + pop.close(); + + return 0; +} diff --git a/tests/external/libcxx/basic_string/string.cons/dtor_noexcept.pass.cpp b/tests/external/libcxx/basic_string/string.cons/dtor_noexcept.pass.cpp new file mode 100644 index 0000000..c6e3a5f --- /dev/null +++ b/tests/external/libcxx/basic_string/string.cons/dtor_noexcept.pass.cpp @@ -0,0 +1,28 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// Copyright 2019, Intel Corporation +// +// Modified to test pmem::obj containers +// + +#include "unittest.hpp" + +#include + +namespace pmem_exp = pmem::obj::experimental; + +int +main() +{ + { + typedef pmem_exp::string C; + static_assert(std::is_nothrow_destructible::value, ""); + } +} diff --git a/tests/external/libcxx/basic_string/string.cons/initializer_list.pass.cpp b/tests/external/libcxx/basic_string/string.cons/initializer_list.pass.cpp new file mode 100644 index 0000000..99a824a --- /dev/null +++ b/tests/external/libcxx/basic_string/string.cons/initializer_list.pass.cpp @@ -0,0 +1,115 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// Copyright 2019, Intel Corporation +// +// Modified to test pmem::obj containers +// + +#include "unittest.hpp" + +#include +#include +#include +#include +#include + +namespace pmem_exp = pmem::obj::experimental; +namespace nvobj = pmem::obj; + +struct testcase1 { + pmem_exp::string s = {'a', 'b', 'c'}; + pmem_exp::string s_long = { + '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '1', '2', + '3', '4', '5', '6', '7', '8', '9', '0', '1', '2', '3', '4', + '5', '6', '7', '8', '9', '0', '1', '2', '3', '4', '5', '6', + '7', '8', '9', '0', '1', '2', '3', '4', '5', '6', '7', '8', + '9', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', + '1', '2', '3', '4', '5', '6', '7', '8', '9', '0'}; + + void + run() + { + using T = typename pmem_exp::string::traits_type; + UT_ASSERT(s == "abc"); + UT_ASSERT( + s_long == + "1234567890123456789012345678901234567890123456789012345678901234567890"); + UT_ASSERT(T::compare(s.c_str(), "abc", s.size()) == 0); + UT_ASSERT( + T::compare( + s_long.c_str(), + "1234567890123456789012345678901234567890123456789012345678901234567890", + s_long.size()) == 0); + } +}; + +struct testcase2 { + std::wstring s = {L'a', L'b', L'c'}; + + void + run() + { + UT_ASSERT(s == L"abc"); + } +}; + +struct root { + nvobj::persistent_ptr r1; + nvobj::persistent_ptr r2; +}; + +void +run(pmem::obj::pool &pop) +{ + try { + pmem::obj::transaction::run(pop, [&] { + pop.root()->r1 = + pmem::obj::make_persistent(); + pop.root()->r2 = + pmem::obj::make_persistent(); + }); + + pop.root()->r1->run(); + pop.root()->r2->run(); + + pmem::obj::transaction::run(pop, [&] { + pmem::obj::delete_persistent(pop.root()->r1); + pmem::obj::delete_persistent(pop.root()->r2); + }); + } catch (std::exception &e) { + UT_FATALexc(e); + } +} + +int +main(int argc, char *argv[]) +{ + START(); + + if (argc != 2) + UT_FATAL("usage: %s file-name", argv[0]); + + const char *path = argv[1]; + + pmem::obj::pool pop; + try { + pop = pmem::obj::pool::create( + path, "copy_assignment.pass", PMEMOBJ_MIN_POOL, + S_IWUSR | S_IRUSR); + } catch (...) { + UT_FATAL("!pmemobj_create: %s", path); + } + + run(pop); + + pop.close(); + + return 0; +} diff --git a/tests/external/libcxx/basic_string/string.cons/initializer_list_assignment.pass.cpp b/tests/external/libcxx/basic_string/string.cons/initializer_list_assignment.pass.cpp new file mode 100644 index 0000000..0b57118 --- /dev/null +++ b/tests/external/libcxx/basic_string/string.cons/initializer_list_assignment.pass.cpp @@ -0,0 +1,63 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// Copyright 2019, Intel Corporation +// +// Modified to test pmem::obj containers +// + +#include "unittest.hpp" + +#include +#include +#include +#include +#include + +namespace nvobj = pmem::obj; +namespace pmem_exp = pmem::obj::experimental; +using C = pmem_exp::string; + +struct root { + nvobj::persistent_ptr s; +}; + +int +main(int argc, char *argv[]) +{ + START(); + + if (argc < 2) { + std::cerr << "usage: " << argv[0] << " file-name" << std::endl; + return 1; + } + + auto path = argv[1]; + auto pop = nvobj::pool::create( + path, "string_test", PMEMOBJ_MIN_POOL, S_IWUSR | S_IRUSR); + + auto r = pop.root(); + + try { + nvobj::transaction::run( + pop, [&] { r->s = nvobj::make_persistent(); }); + + *r->s = {'a', 'b', 'c'}; + UT_ASSERT(*r->s == "abc"); + + nvobj::transaction::run( + pop, [&] { nvobj::delete_persistent(r->s); }); + } catch (std::exception &e) { + UT_FATALexc(e); + } + + pop.close(); + + return 0; +} diff --git a/tests/external/libcxx/basic_string/string.cons/iter_alloc.pass.cpp b/tests/external/libcxx/basic_string/string.cons/iter_alloc.pass.cpp new file mode 100644 index 0000000..002ce19 --- /dev/null +++ b/tests/external/libcxx/basic_string/string.cons/iter_alloc.pass.cpp @@ -0,0 +1,116 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// Copyright 2019, Intel Corporation +// +// Modified to test pmem::obj containers +// + +#include "unittest.hpp" + +#include +#include +#include +#include +#include + +namespace pmem_exp = pmem::obj::experimental; +namespace nvobj = pmem::obj; + +struct root { + nvobj::persistent_ptr s1; +}; + +template +void +test(It first, It last, pmem::obj::pool &pop) +{ + typedef typename std::iterator_traits::value_type charT; + typedef pmem_exp::basic_string> S; + + auto r = pop.root(); + + pmem::obj::transaction::run( + pop, [&] { r->s1 = nvobj::make_persistent(first, last); }); + + auto &s2 = *r->s1; + + UT_ASSERT(s2.size() == + static_cast(std::distance(first, last))); + unsigned i = 0; + pmem::obj::transaction::run(pop, [&] { + for (It it = first; it != last; ++it, ++i) + UT_ASSERT(s2[i] == *it); + UT_ASSERT(s2.capacity() >= s2.size()); + }); + + nvobj::transaction::run(pop, [&] { + UT_ASSERT(s2.c_str() == s2.data()); + UT_ASSERT(s2.c_str() == s2.cdata()); + UT_ASSERT(s2.c_str() == + static_cast(s2).data()); + }); + + pmem::obj::transaction::run( + pop, [&] { nvobj::delete_persistent(r->s1); }); +} + +void +run(pmem::obj::pool &pop) +{ + const char *s = + "123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890"; + + try { + test(s, s, pop); + test(s, s + 1, pop); + test(s, s + 10, pop); + test(s, s + 50, pop); + test(s, s + 70, pop); + test(test_support::input_it(s), + test_support::input_it(s), pop); + test(test_support::input_it(s), + test_support::input_it(s + 1), pop); + test(test_support::input_it(s), + test_support::input_it(s + 10), pop); + test(test_support::input_it(s), + test_support::input_it(s + 50), pop); + test(test_support::input_it(s), + test_support::input_it(s + 70), pop); + } catch (std::exception &e) { + UT_FATALexc(e); + } +} + +int +main(int argc, char *argv[]) +{ + START(); + + if (argc != 2) + UT_FATAL("usage: %s file-name", argv[0]); + + const char *path = argv[1]; + + pmem::obj::pool pop; + + try { + pop = pmem::obj::pool::create(path, "iter_alloc.pass", + PMEMOBJ_MIN_POOL, + S_IWUSR | S_IRUSR); + } catch (...) { + UT_FATAL("!pmemobj_create: %s", path); + } + + run(pop); + + pop.close(); + + return 0; +} diff --git a/tests/external/libcxx/basic_string/string.cons/move.pass.cpp b/tests/external/libcxx/basic_string/string.cons/move.pass.cpp new file mode 100644 index 0000000..0223d5c --- /dev/null +++ b/tests/external/libcxx/basic_string/string.cons/move.pass.cpp @@ -0,0 +1,136 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// Copyright 2019, Intel Corporation +// +// Modified to test pmem::obj containers +// + +#include "unittest.hpp" + +#include +#include +#include +#include +#include + +namespace pmem_exp = pmem::obj::experimental; +namespace nvobj = pmem::obj; + +using string_type = pmem_exp::string; + +struct root { + nvobj::persistent_ptr s1; + nvobj::persistent_ptr s2; +}; + +template +void +test(S &s0, pmem::obj::pool &pop) +{ + using T = typename string_type::traits_type; + auto r = pop.root(); + + nvobj::transaction::run( + pop, [&] { r->s1 = nvobj::make_persistent(s0); }); + + nvobj::transaction::run(pop, [&] { + r->s2 = nvobj::make_persistent(std::move(s0)); + }); + + UT_ASSERT(s0.size() == 0); + UT_ASSERT(*r->s2 == *r->s1); + + UT_ASSERT(r->s1->size() == r->s2->size()); + UT_ASSERT(T::compare(r->s2->c_str(), r->s1->c_str(), r->s1->size()) == + 0); + UT_ASSERT(r->s2->capacity() >= r->s2->size()); + + nvobj::transaction::run(pop, [&] { + UT_ASSERT(r->s2->c_str() == r->s2->data()); + UT_ASSERT(r->s2->c_str() == r->s2->cdata()); + UT_ASSERT(r->s2->c_str() == + static_cast(*r->s2).data()); + }); + + nvobj::transaction::run(pop, [&] { + nvobj::delete_persistent(r->s1); + nvobj::delete_persistent(r->s2); + }); +} + +void +run(pmem::obj::pool &pop) +{ + try { + nvobj::persistent_ptr s1, s2, s3, s4; + + nvobj::transaction::run(pop, [&] { + s1 = nvobj::make_persistent(); + }); + + nvobj::transaction::run(pop, [&] { + s2 = nvobj::make_persistent("1"); + }); + + nvobj::transaction::run(pop, [&] { + s3 = nvobj::make_persistent("1234567890"); + }); + + nvobj::transaction::run(pop, [&] { + s4 = nvobj::make_persistent( + "1234567890123456789012345678901234567890" + "1234567890123456789012345678901234567890" + "1234567890123456789012345678901234567890" + "1234567890"); + }); + + test(*s1, pop); + test(*s2, pop); + test(*s3, pop); + test(*s4, pop); + + nvobj::transaction::run(pop, [&] { + nvobj::delete_persistent(s1); + nvobj::delete_persistent(s2); + nvobj::delete_persistent(s3); + nvobj::delete_persistent(s4); + }); + + } catch (std::exception &e) { + UT_FATALexc(e); + } +} + +int +main(int argc, char *argv[]) +{ + START(); + + if (argc != 2) + UT_FATAL("usage: %s file-name", argv[0]); + + const char *path = argv[1]; + + pmem::obj::pool pop; + + try { + pop = pmem::obj::pool::create(path, "string_test", + PMEMOBJ_MIN_POOL, + S_IWUSR | S_IRUSR); + } catch (...) { + UT_FATAL("!pmemobj_create: %s", path); + } + + run(pop); + + pop.close(); + + return 0; +} diff --git a/tests/external/libcxx/basic_string/string.cons/move_assignment.pass.cpp b/tests/external/libcxx/basic_string/string.cons/move_assignment.pass.cpp new file mode 100644 index 0000000..54559d2 --- /dev/null +++ b/tests/external/libcxx/basic_string/string.cons/move_assignment.pass.cpp @@ -0,0 +1,131 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// Copyright 2019, Intel Corporation +// +// Modified to test pmem::obj containers +// + +#include "unittest.hpp" + +#include + +namespace nvobj = pmem::obj; +namespace pmem_exp = pmem::obj::experimental; +using S = pmem_exp::string; + +struct root { + nvobj::persistent_ptr s0, s1, s2; + nvobj::persistent_ptr s_arr[7]; +}; + +template +void +test(nvobj::pool &pop, const S &s_1, const S &s_2) +{ + auto r = pop.root(); + + nvobj::transaction::run(pop, [&] { + r->s0 = nvobj::make_persistent(s_2); + r->s1 = nvobj::make_persistent(s_1); + r->s2 = nvobj::make_persistent(s_2); + }); + + auto &s0 = *r->s0; + auto &s1 = *r->s1; + auto &s2 = *r->s2; + + s1 = std::move(s2); + UT_ASSERT(s1 == s0); + UT_ASSERT(s1.capacity() >= s1.size()); + + nvobj::transaction::run(pop, [&] { + nvobj::delete_persistent(r->s0); + nvobj::delete_persistent(r->s1); + nvobj::delete_persistent(r->s2); + }); +} + +void +test_self_assignment(nvobj::pool &pop, const S &s1) +{ + auto r = pop.root(); + + nvobj::transaction::run(pop, + [&] { r->s0 = nvobj::make_persistent(s1); }); + + auto &s = *r->s0; + auto &s_alias = *r->s0; + + s = std::move(s_alias); + UT_ASSERT(s == s1); + UT_ASSERT(s.capacity() >= s1.size()); + + nvobj::transaction::run(pop, + [&] { nvobj::delete_persistent(r->s0); }); +} + +int +main(int argc, char *argv[]) +{ + START(); + + if (argc < 2) { + std::cerr << "usage: " << argv[0] << " file-name" << std::endl; + return 1; + } + + auto path = argv[1]; + auto pop = nvobj::pool::create( + path, "string_test", PMEMOBJ_MIN_POOL, S_IWUSR | S_IRUSR); + + auto &s_arr = pop.root()->s_arr; + + try { + nvobj::transaction::run(pop, [&] { + s_arr[0] = nvobj::make_persistent(); + s_arr[1] = nvobj::make_persistent("1"); + s_arr[2] = nvobj::make_persistent("2"); + s_arr[3] = nvobj::make_persistent("123456789"); + s_arr[4] = nvobj::make_persistent( + "1234567890123456789012345678901234567890123456789012345678901234567890"); + s_arr[5] = nvobj::make_persistent( + "1234567890123456789012345678901234567890123456789012345678901234567890" + "1234567890123456789012345678901234567890123456789012345678901234567890"); + s_arr[6] = nvobj::make_persistent( + "abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz"); + }); + + test(pop, *s_arr[0], *s_arr[0]); + test(pop, *s_arr[1], *s_arr[0]); + test(pop, *s_arr[0], *s_arr[1]); + test(pop, *s_arr[1], *s_arr[2]); + test(pop, *s_arr[1], *s_arr[2]); + + test(pop, *s_arr[0], *s_arr[6]); + test(pop, *s_arr[3], *s_arr[6]); + test(pop, *s_arr[4], *s_arr[6]); + test(pop, *s_arr[5], *s_arr[6]); + + test_self_assignment(pop, *s_arr[0]); + test_self_assignment(pop, *s_arr[3]); + + nvobj::transaction::run(pop, [&] { + for (unsigned i = 0; i < 7; ++i) { + nvobj::delete_persistent(s_arr[i]); + } + }); + } catch (std::exception &e) { + UT_FATALexc(e); + } + + pop.close(); + + return 0; +} diff --git a/tests/external/libcxx/basic_string/string.cons/pointer_alloc.pass.cpp b/tests/external/libcxx/basic_string/string.cons/pointer_alloc.pass.cpp new file mode 100644 index 0000000..86a9e96 --- /dev/null +++ b/tests/external/libcxx/basic_string/string.cons/pointer_alloc.pass.cpp @@ -0,0 +1,107 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// Copyright 2019, Intel Corporation +// +// Modified to test pmem::obj containers +// + +#include "unittest.hpp" + +#include +#include +#include +#include +#include + +namespace pmem_exp = pmem::obj::experimental; +namespace nvobj = pmem::obj; + +struct root { + nvobj::persistent_ptr s1; +}; + +template +void +test(const charT *s, pmem::obj::pool &pop) +{ + typedef pmem_exp::basic_string> S; + typedef typename S::traits_type T; + std::size_t n = T::length(s); + + auto r = pop.root(); + + nvobj::transaction::run(pop, [&] { + r->s1 = nvobj::make_persistent(s); + }); + + auto &s2 = *r->s1; + + UT_ASSERT(s2.size() == n); + UT_ASSERT(T::compare(s2.c_str(), s, n) == 0); + + nvobj::transaction::run(pop, [&] { + UT_ASSERT(s2.c_str() == s2.data()); + UT_ASSERT(s2.c_str() == s2.cdata()); + UT_ASSERT(s2.c_str() == + static_cast(s2).data()); + }); + UT_ASSERT(s2.capacity() >= s2.size()); + + nvobj::transaction::run(pop, [&] { + nvobj::delete_persistent(r->s1); + }); +} + +void +run(pmem::obj::pool &pop) +{ + try { + test("", pop); + test("1", pop); + test("1234567980", pop); + test("123456798012345679801234567980" + "123456798012345679801234567980", + pop); + test("12345679801234567980123456798012345679801234567980" + "12345679801234567980123456798012345679801234567980" + "12345679801234567980", + pop); + + } catch (std::exception &e) { + UT_FATALexc(e); + } +} + +int +main(int argc, char *argv[]) +{ + START(); + + if (argc != 2) + UT_FATAL("usage: %s file-name", argv[0]); + + const char *path = argv[1]; + + pmem::obj::pool pop; + + try { + pop = pmem::obj::pool::create(path, "string_test", + PMEMOBJ_MIN_POOL, + S_IWUSR | S_IRUSR); + } catch (...) { + UT_FATAL("!pmemobj_create: %s", path); + } + + run(pop); + + pop.close(); + + return 0; +} diff --git a/tests/external/libcxx/basic_string/string.cons/pointer_assignment.pass.cpp b/tests/external/libcxx/basic_string/string.cons/pointer_assignment.pass.cpp new file mode 100644 index 0000000..5d21413 --- /dev/null +++ b/tests/external/libcxx/basic_string/string.cons/pointer_assignment.pass.cpp @@ -0,0 +1,107 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// Copyright 2019, Intel Corporation +// +// Modified to test pmem::obj containers +// + +#include "unittest.hpp" + +#include +#include + +namespace nvobj = pmem::obj; +namespace pmem_exp = pmem::obj::experimental; +using S = pmem_exp::string; + +struct root { + nvobj::persistent_ptr s1; + nvobj::persistent_ptr s_arr[6]; +}; + +template +void +test(nvobj::pool &pop, const S &s_1, + const typename S::value_type *s2) +{ + auto r = pop.root(); + + nvobj::transaction::run( + pop, [&] { r->s1 = nvobj::make_persistent(s_1); }); + + auto &s1 = *r->s1; + + typedef typename S::traits_type T; + s1 = s2; + UT_ASSERT(s1.size() == T::length(s2)); + UT_ASSERT(T::compare(s1.data(), s2, s1.size()) == 0); + UT_ASSERT(s1.capacity() >= s1.size()); + + nvobj::transaction::run(pop, + [&] { nvobj::delete_persistent(r->s1); }); +} + +int +main(int argc, char *argv[]) +{ + START(); + + if (argc < 2) { + std::cerr << "usage: " << argv[0] << " file-name" << std::endl; + return 1; + } + + auto path = argv[1]; + auto pop = nvobj::pool::create( + path, "string_test", PMEMOBJ_MIN_POOL, S_IWUSR | S_IRUSR); + + auto &s_arr = pop.root()->s_arr; + + try { + nvobj::transaction::run(pop, [&] { + s_arr[0] = nvobj::make_persistent(); + s_arr[1] = nvobj::make_persistent("1"); + s_arr[2] = nvobj::make_persistent("2"); + s_arr[3] = nvobj::make_persistent("123456789"); + s_arr[4] = nvobj::make_persistent( + "1234567890123456789012345678901234567890123456789012345678901234567890"); + s_arr[5] = nvobj::make_persistent( + "1234567890123456789012345678901234567890123456789012345678901234567890" + "1234567890123456789012345678901234567890123456789012345678901234567890"); + }); + + test(pop, *s_arr[0], ""); + test(pop, *s_arr[1], ""); + test(pop, *s_arr[0], "1"); + test(pop, *s_arr[1], "2"); + test(pop, *s_arr[1], "2"); + + test(pop, *s_arr[0], + "abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz"); + test(pop, *s_arr[3], + "abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz"); + test(pop, *s_arr[4], + "abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz"); + test(pop, *s_arr[5], + "abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz"); + + nvobj::transaction::run(pop, [&] { + for (unsigned i = 0; i < 6; ++i) { + nvobj::delete_persistent(s_arr[i]); + } + }); + } catch (std::exception &e) { + UT_FATALexc(e); + } + + pop.close(); + + return 0; +} diff --git a/tests/external/libcxx/basic_string/string.cons/pointer_size_alloc.pass.cpp b/tests/external/libcxx/basic_string/string.cons/pointer_size_alloc.pass.cpp new file mode 100644 index 0000000..52542b8 --- /dev/null +++ b/tests/external/libcxx/basic_string/string.cons/pointer_size_alloc.pass.cpp @@ -0,0 +1,103 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// Copyright 2019, Intel Corporation +// +// Modified to test pmem::obj containers +// + +#include "unittest.hpp" + +#include +#include +#include +#include +#include + +namespace pmem_exp = pmem::obj::experimental; +namespace nvobj = pmem::obj; + +struct root { + nvobj::persistent_ptr s1; +}; + +template +void +test(const charT *s, unsigned n, pmem::obj::pool &pop) +{ + typedef pmem_exp::basic_string> S; + typedef typename S::traits_type T; + + auto r = pop.root(); + + nvobj::transaction::run(pop, [&] { + r->s1 = nvobj::make_persistent(s, n); + }); + + auto &s2 = *r->s1; + + UT_ASSERT(s2.size() == n); + UT_ASSERT(T::compare(s2.c_str(), s, n) == 0); + UT_ASSERT(s2.capacity() >= s2.size()); + + nvobj::transaction::run(pop, [&] { + UT_ASSERT(s2.c_str() == s2.data()); + UT_ASSERT(s2.c_str() == s2.cdata()); + UT_ASSERT(s2.c_str() == + static_cast(s2).data()); + }); + + nvobj::transaction::run(pop, [&] { + nvobj::delete_persistent(r->s1); + }); +} + +void +run(pmem::obj::pool &pop) +{ + try { + test("", 0, pop); + test("1", 1, pop); + test("1234567980", 10, pop); + test("123456798012345679801234567980123456798012345679801234567980", + 60, pop); + test("123456798012345679801234567980123456798012345679801234567980" + "123456798012345679801234567980123456798012345679801234567980", + 120, pop); + } catch (std::exception &e) { + UT_FATALexc(e); + } +} + +int +main(int argc, char *argv[]) +{ + START(); + + if (argc != 2) + UT_FATAL("usage: %s file-name", argv[0]); + + const char *path = argv[1]; + + pmem::obj::pool pop; + + try { + pop = pmem::obj::pool::create(path, "string_test", + PMEMOBJ_MIN_POOL, + S_IWUSR | S_IRUSR); + } catch (...) { + UT_FATAL("!pmemobj_create: %s", path); + } + + run(pop); + + pop.close(); + + return 0; +} diff --git a/tests/external/libcxx/basic_string/string.cons/size_char_alloc.pass.cpp b/tests/external/libcxx/basic_string/string.cons/size_char_alloc.pass.cpp new file mode 100644 index 0000000..aa0b866 --- /dev/null +++ b/tests/external/libcxx/basic_string/string.cons/size_char_alloc.pass.cpp @@ -0,0 +1,99 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// Copyright 2019, Intel Corporation +// +// Modified to test pmem::obj containers +// + +#include "unittest.hpp" + +#include +#include +#include +#include +#include + +namespace pmem_exp = pmem::obj::experimental; +namespace nvobj = pmem::obj; + +struct root { + nvobj::persistent_ptr s1; +}; + +template +void +test(unsigned n, charT c, pmem::obj::pool &pop) +{ + auto r = pop.root(); + + nvobj::transaction::run(pop, [&] { + r->s1 = nvobj::make_persistent(n, c); + }); + + auto &s2 = *r->s1; + + UT_ASSERT(s2.size() == n); + nvobj::transaction::run(pop, [&] { + for (unsigned i = 0; i < n; ++i) + UT_ASSERT(s2[i] == c); + }); + UT_ASSERT(s2.capacity() >= s2.size()); + + nvobj::transaction::run(pop, [&] { + UT_ASSERT(s2.c_str() == s2.data()); + UT_ASSERT(s2.c_str() == s2.cdata()); + UT_ASSERT(s2.c_str() == + static_cast(s2).data()); + }); + + nvobj::transaction::run(pop, [&] { + nvobj::delete_persistent(r->s1); + }); +} + +void +run(pmem::obj::pool &pop) +{ + try { + test(0, 'a', pop); + test(1, 'a', pop); + test(10, 'a', pop); + test(100, 'a', pop); + } catch (std::exception &e) { + UT_FATALexc(e); + } +} + +int +main(int argc, char *argv[]) +{ + START(); + + if (argc != 2) + UT_FATAL("usage: %s file-name", argv[0]); + + const char *path = argv[1]; + + pmem::obj::pool pop; + + try { + pop = pmem::obj::pool::create(path, "string_test", + PMEMOBJ_MIN_POOL, + S_IWUSR | S_IRUSR); + } catch (...) { + UT_FATAL("!pmemobj_create: %s", path); + } + + run(pop); + + pop.close(); + + return 0; +} diff --git a/tests/external/libcxx/basic_string/string.cons/string_view.fail.cpp b/tests/external/libcxx/basic_string/string.cons/string_view.fail.cpp new file mode 100644 index 0000000..3d3bf41 --- /dev/null +++ b/tests/external/libcxx/basic_string/string.cons/string_view.fail.cpp @@ -0,0 +1,23 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// + +// explicit basic_string(basic_string_view sv, const Allocator& a = Allocator()); + +#include +#include + +void foo ( const string &s ) {} + +int main() +{ + std::string_view sv = "ABCDE"; + foo(sv); // requires implicit conversion from string_view to string +} diff --git a/tests/external/libcxx/basic_string/string.cons/string_view.pass.cpp b/tests/external/libcxx/basic_string/string.cons/string_view.pass.cpp new file mode 100644 index 0000000..78ceae7 --- /dev/null +++ b/tests/external/libcxx/basic_string/string.cons/string_view.pass.cpp @@ -0,0 +1,111 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// + +// explicit basic_string(basic_string_view sv, const Allocator& a = Allocator()); + +#include +#include +#include +#include +#include + +#include "test_macros.h" +#include "test_allocator.h" +#include "min_allocator.h" + +template +void +test(std::basic_string_view sv) +{ + typedef std::basic_string, test_allocator > S; + typedef typename S::traits_type T; + typedef typename S::allocator_type A; + { + S s2(sv); + LIBCPP_ASSERT(s2.__invariants()); + assert(s2.size() == sv.size()); + assert(T::compare(s2.data(), sv.data(), sv.size()) == 0); + assert(s2.get_allocator() == A()); + assert(s2.capacity() >= s2.size()); + } + { + S s2; + s2 = sv; + LIBCPP_ASSERT(s2.__invariants()); + assert(s2.size() == sv.size()); + assert(T::compare(s2.data(), sv.data(), sv.size()) == 0); + assert(s2.get_allocator() == A()); + assert(s2.capacity() >= s2.size()); + } +} + +template +void +test(std::basic_string_view sv, const A& a) +{ + typedef std::basic_string, A> S; + typedef typename S::traits_type T; + { + S s2(sv, a); + LIBCPP_ASSERT(s2.__invariants()); + assert(s2.size() == sv.size()); + assert(T::compare(s2.data(), sv.data(), sv.size()) == 0); + assert(s2.get_allocator() == a); + assert(s2.capacity() >= s2.size()); + } + { + S s2(a); + s2 = sv; + LIBCPP_ASSERT(s2.__invariants()); + assert(s2.size() == sv.size()); + assert(T::compare(s2.data(), sv.data(), sv.size()) == 0); + assert(s2.get_allocator() == a); + assert(s2.capacity() >= s2.size()); + } +} + +int main() +{ + { + typedef test_allocator A; + typedef std::basic_string_view > SV; + + test(SV("")); + test(SV(""), A(2)); + + test(SV("1")); + test(SV("1") ,A(2)); + + test(SV("1234567980")); + test(SV("1234567980"), A(2)); + + test(SV("123456798012345679801234567980123456798012345679801234567980")); + test(SV("123456798012345679801234567980123456798012345679801234567980"), A(2)); + } +#if TEST_STD_VER >= 11 + { + typedef min_allocator A; + typedef std::basic_string_view > SV; + + test(SV("")); + test(SV(""), A()); + + test(SV("1")); + test(SV("1") ,A()); + + test(SV("1234567980")); + test(SV("1234567980"), A()); + + test(SV("123456798012345679801234567980123456798012345679801234567980")); + test(SV("123456798012345679801234567980123456798012345679801234567980"), A()); + } +#endif +} diff --git a/tests/external/libcxx/basic_string/string.cons/string_view_assignment.pass.cpp b/tests/external/libcxx/basic_string/string.cons/string_view_assignment.pass.cpp new file mode 100644 index 0000000..1d400b7 --- /dev/null +++ b/tests/external/libcxx/basic_string/string.cons/string_view_assignment.pass.cpp @@ -0,0 +1,74 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// + +// basic_string& operator=(basic_string_view sv); + +#include +#include + +#include "test_macros.h" +#include "min_allocator.h" + +template +void +test(S s1, SV sv) +{ + typedef typename S::traits_type T; + s1 = sv; + LIBCPP_ASSERT(s1.__invariants()); + assert(s1.size() == sv.size()); + assert(T::compare(s1.data(), sv.data(), s1.size()) == 0); + assert(s1.capacity() >= s1.size()); +} + +int main() +{ + { + typedef std::string S; + typedef std::string_view SV; + test(S(), SV("")); + test(S("1"), SV("")); + test(S(), SV("1")); + test(S("1"), SV("2")); + test(S("1"), SV("2")); + + test(S(), + SV("abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz")); + test(S("123456789"), + SV("abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz")); + test(S("1234567890123456789012345678901234567890123456789012345678901234567890"), + SV("abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz")); + test(S("1234567890123456789012345678901234567890123456789012345678901234567890" + "1234567890123456789012345678901234567890123456789012345678901234567890"), + SV("abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz")); + } +#if TEST_STD_VER >= 11 + { + typedef std::basic_string, min_allocator> S; + typedef std::string_view SV; + test(S(), SV("")); + test(S("1"), SV("")); + test(S(), SV("1")); + test(S("1"), SV("2")); + test(S("1"), SV("2")); + + test(S(), + SV("abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz")); + test(S("123456789"), + SV("abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz")); + test(S("1234567890123456789012345678901234567890123456789012345678901234567890"), + SV("abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz")); + test(S("1234567890123456789012345678901234567890123456789012345678901234567890" + "1234567890123456789012345678901234567890123456789012345678901234567890"), + SV("abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz")); + } +#endif +} diff --git a/tests/external/libcxx/basic_string/string.cons/substr.pass.cpp b/tests/external/libcxx/basic_string/string.cons/substr.pass.cpp new file mode 100644 index 0000000..a19fc07 --- /dev/null +++ b/tests/external/libcxx/basic_string/string.cons/substr.pass.cpp @@ -0,0 +1,221 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// Copyright 2019, Intel Corporation +// +// Modified to test pmem::obj containers +// + +#include "unittest.hpp" + +#include +#include +#include +#include +#include + +namespace pmem_exp = pmem::obj::experimental; +namespace nvobj = pmem::obj; + +using string_type = pmem_exp::string; + +struct root { + nvobj::persistent_ptr s1; +}; + +template +void +test(S &str, unsigned pos, pmem::obj::pool &pop) +{ + typedef typename S::traits_type T; + + auto r = pop.root(); + + if (pos <= str.size()) { + nvobj::transaction::run(pop, [&] { + r->s1 = nvobj::make_persistent(str, pos); + }); + auto &s2 = *r->s1; + + typename S::size_type rlen = str.size() - pos; + UT_ASSERT(s2.size() == rlen); + UT_ASSERT(T::compare(s2.cdata(), str.cdata() + pos, rlen) == 0); + UT_ASSERT(s2.capacity() >= s2.size()); + + nvobj::transaction::run(pop, [&] { + UT_ASSERT(s2.c_str() == s2.data()); + UT_ASSERT(s2.c_str() == s2.cdata()); + UT_ASSERT(s2.c_str() == + static_cast(s2).data()); + }); + + nvobj::transaction::run(pop, [&] { + nvobj::delete_persistent(r->s1); + }); + } else { + try { + nvobj::transaction::run(pop, [&] { + r->s1 = nvobj::make_persistent( + str, pos); + }); + UT_ASSERT(0); + } catch (std::out_of_range &) { + UT_ASSERT(pos > str.size()); + } + } +} + +template +void +test(S &str, unsigned pos, unsigned n, pmem::obj::pool &pop) +{ + typedef typename S::traits_type T; + + auto r = pop.root(); + + if (pos <= str.size()) { + nvobj::transaction::run(pop, [&] { + r->s1 = nvobj::make_persistent(str, pos, + n); + }); + + auto &s2 = *r->s1; + + typename S::size_type rlen = + std::min(str.size() - pos, n); + UT_ASSERT(s2.size() == rlen); + UT_ASSERT(T::compare(s2.cdata(), str.cdata() + pos, rlen) == 0); + UT_ASSERT(s2.capacity() >= s2.size()); + + nvobj::transaction::run(pop, [&] { + UT_ASSERT(s2.c_str() == s2.data()); + UT_ASSERT(s2.c_str() == s2.cdata()); + UT_ASSERT(s2.c_str() == + static_cast(s2).data()); + }); + + nvobj::transaction::run(pop, [&] { + nvobj::delete_persistent(r->s1); + }); + } else { + try { + nvobj::transaction::run(pop, [&] { + r->s1 = nvobj::make_persistent( + str, pos, n); + }); + UT_ASSERT(0); + } catch (std::out_of_range &) { + UT_ASSERT(pos > str.size()); + } + } +} + +void +run(pmem::obj::pool &pop) +{ + try { + nvobj::persistent_ptr s_default, s1, s2, s3; + + nvobj::transaction::run(pop, [&] { + s_default = nvobj::make_persistent(); + }); + + nvobj::transaction::run(pop, [&] { + s1 = nvobj::make_persistent("1"); + }); + + nvobj::transaction::run(pop, [&] { + s2 = nvobj::make_persistent( + "1234567890123456789012345678901234567890" + "123456789012345678901234567890"); + }); + + nvobj::transaction::run(pop, [&] { + s3 = nvobj::make_persistent( + "1234567890123456789012345678901234567890" + "1234567890123456789012345678901234567890" + "1234567890123456789012345678901234567890" + "1234567890"); + }); + + test(*s_default, 0, pop); + test(*s_default, 1, pop); + + test(*s1, 0, pop); + test(*s1, 1, pop); + test(*s1, 2, pop); + + test(*s2, 0, pop); + test(*s2, 5, pop); + test(*s2, 50, pop); + test(*s2, 500, pop); + + test(*s3, 0, pop); + test(*s3, 5, pop); + test(*s3, 50, pop); + test(*s3, 500, pop); + + test(*s_default, 0, 0, pop); + test(*s_default, 0, 1, pop); + test(*s_default, 1, 0, pop); + test(*s_default, 1, 1, pop); + test(*s_default, 1, 2, pop); + + test(*s1, 0, 0, pop); + test(*s1, 0, 1, pop); + test(*s1, 1, 1, pop); + + test(*s2, 0, 5, pop); + test(*s2, 50, 0, pop); + test(*s2, 50, 1, pop); + test(*s2, 50, 10, pop); + test(*s2, 50, 100, pop); + + test(*s3, 0, 5, pop); + test(*s3, 50, 0, pop); + test(*s3, 50, 1, pop); + test(*s3, 50, 10, pop); + test(*s3, 50, 100, pop); + + nvobj::transaction::run(pop, [&] { + nvobj::delete_persistent(s1); + nvobj::delete_persistent(s2); + nvobj::delete_persistent(s3); + }); + } catch (std::exception &e) { + UT_FATALexc(e); + } +} + +int +main(int argc, char *argv[]) +{ + START(); + + if (argc != 2) + UT_FATAL("usage: %s file-name", argv[0]); + + const char *path = argv[1]; + + pmem::obj::pool pop; + + try { + pop = pmem::obj::pool::create(path, "string_test", + PMEMOBJ_MIN_POOL, + S_IWUSR | S_IRUSR); + } catch (...) { + UT_FATAL("!pmemobj_create: %s", path); + } + + run(pop); + + pop.close(); + + return 0; +} diff --git a/tests/external/libcxx/basic_string/string.ends_with/ends_with.char.pass.cpp b/tests/external/libcxx/basic_string/string.ends_with/ends_with.char.pass.cpp new file mode 100644 index 0000000..6091e0c --- /dev/null +++ b/tests/external/libcxx/basic_string/string.ends_with/ends_with.char.pass.cpp @@ -0,0 +1,34 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// UNSUPPORTED: c++98, c++03, c++11, c++14, c++17 + +// + +// bool ends_with(charT x) const noexcept; + +#include +#include + +#include "test_macros.h" + +int main() +{ + { + typedef std::string S; + S s1 {}; + S s2 { "abcde", 5 }; + + ASSERT_NOEXCEPT(s1.ends_with('e')); + + assert (!s1.ends_with('e')); + assert (!s1.ends_with('x')); + assert ( s2.ends_with('e')); + assert (!s2.ends_with('x')); + } +} diff --git a/tests/external/libcxx/basic_string/string.ends_with/ends_with.ptr.pass.cpp b/tests/external/libcxx/basic_string/string.ends_with/ends_with.ptr.pass.cpp new file mode 100644 index 0000000..b1f5fcd --- /dev/null +++ b/tests/external/libcxx/basic_string/string.ends_with/ends_with.ptr.pass.cpp @@ -0,0 +1,63 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// UNSUPPORTED: c++98, c++03, c++11, c++14, c++17 + +// + +// bool ends_with(const CharT *x) const; + +#include +#include + +#include "test_macros.h" + +int main() +{ + { + typedef std::string S; + const char *s = "abcde"; + + S s0; + S s1 { s + 4, 1 }; + S s2 { s + 3, 2 }; +// S s3 { s + 2, 3 }; +// S s4 { s + 1, 4 }; +// S s5 { s, 5 }; + S sNot { "def", 3 }; + + LIBCPP_ASSERT_NOEXCEPT(s0.ends_with("")); + + assert ( s0.ends_with("")); + assert (!s0.ends_with("e")); + + assert ( s1.ends_with("")); + assert ( s1.ends_with("e")); + assert (!s1.ends_with("de")); + assert (!s1.ends_with("cde")); + assert (!s1.ends_with("bcde")); + assert (!s1.ends_with("abcde")); + assert (!s1.ends_with("def")); + + assert ( s2.ends_with("")); + assert ( s2.ends_with("e")); + assert ( s2.ends_with("de")); + assert (!s2.ends_with("cde")); + assert (!s2.ends_with("bcde")); + assert (!s2.ends_with("abcde")); + assert (!s2.ends_with("def")); + + assert ( sNot.ends_with("")); + assert (!sNot.ends_with("e")); + assert (!sNot.ends_with("de")); + assert (!sNot.ends_with("cde")); + assert (!sNot.ends_with("bcde")); + assert (!sNot.ends_with("abcde")); + assert ( sNot.ends_with("def")); + } +} diff --git a/tests/external/libcxx/basic_string/string.ends_with/ends_with.string_view.pass.cpp b/tests/external/libcxx/basic_string/string.ends_with/ends_with.string_view.pass.cpp new file mode 100644 index 0000000..4bbd4bc --- /dev/null +++ b/tests/external/libcxx/basic_string/string.ends_with/ends_with.string_view.pass.cpp @@ -0,0 +1,72 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// UNSUPPORTED: c++98, c++03, c++11, c++14, c++17 + +// + +// bool ends_with(basic_string_view x) const noexcept; + +#include +#include + +#include "test_macros.h" + +int main() +{ + { + typedef std::string S; + typedef std::string_view SV; + const char *s = "abcde"; + + S s0; + S s1 { s + 4, 1 }; + S s2 { s + 3, 2 }; +// S s3 { s + 2, 3 }; +// S s4 { s + 1, 4 }; +// S s5 { s, 5 }; + S sNot { "def", 3 }; + + SV sv0; + SV sv1 { s + 4, 1 }; + SV sv2 { s + 3, 2 }; + SV sv3 { s + 2, 3 }; + SV sv4 { s + 1, 4 }; + SV sv5 { s , 5 }; + SV svNot {"def", 3 }; + + ASSERT_NOEXCEPT(s0.ends_with(sv0)); + + assert ( s0.ends_with(sv0)); + assert (!s0.ends_with(sv1)); + + assert ( s1.ends_with(sv0)); + assert ( s1.ends_with(sv1)); + assert (!s1.ends_with(sv2)); + assert (!s1.ends_with(sv3)); + assert (!s1.ends_with(sv4)); + assert (!s1.ends_with(sv5)); + assert (!s1.ends_with(svNot)); + + assert ( s2.ends_with(sv0)); + assert ( s2.ends_with(sv1)); + assert ( s2.ends_with(sv2)); + assert (!s2.ends_with(sv3)); + assert (!s2.ends_with(sv4)); + assert (!s2.ends_with(sv5)); + assert (!s2.ends_with(svNot)); + + assert ( sNot.ends_with(sv0)); + assert (!sNot.ends_with(sv1)); + assert (!sNot.ends_with(sv2)); + assert (!sNot.ends_with(sv3)); + assert (!sNot.ends_with(sv4)); + assert (!sNot.ends_with(sv5)); + assert ( sNot.ends_with(svNot)); + } +} diff --git a/tests/external/libcxx/basic_string/string.iterators/begin.pass.cpp b/tests/external/libcxx/basic_string/string.iterators/begin.pass.cpp new file mode 100644 index 0000000..ea81111 --- /dev/null +++ b/tests/external/libcxx/basic_string/string.iterators/begin.pass.cpp @@ -0,0 +1,48 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// + +// iterator begin(); +// const_iterator begin() const; + +#include +#include + +#include "min_allocator.h" + +template +void +test(S s) +{ + const S& cs = s; + typename S::iterator b = s.begin(); + typename S::const_iterator cb = cs.begin(); + if (!s.empty()) + { + assert(*b == s[0]); + } + assert(b == cb); +} + +int main() +{ + { + typedef std::string S; + test(S()); + test(S("123")); + } +#if TEST_STD_VER >= 11 + { + typedef std::basic_string, min_allocator> S; + test(S()); + test(S("123")); + } +#endif +} diff --git a/tests/external/libcxx/basic_string/string.iterators/cbegin.pass.cpp b/tests/external/libcxx/basic_string/string.iterators/cbegin.pass.cpp new file mode 100644 index 0000000..fb4b4bd --- /dev/null +++ b/tests/external/libcxx/basic_string/string.iterators/cbegin.pass.cpp @@ -0,0 +1,45 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// + +// const_iterator cbegin() const; + +#include +#include + +#include "min_allocator.h" + +template +void +test(const S& s) +{ + typename S::const_iterator cb = s.cbegin(); + if (!s.empty()) + { + assert(*cb == s[0]); + } + assert(cb == s.begin()); +} + +int main() +{ + { + typedef std::string S; + test(S()); + test(S("123")); + } +#if TEST_STD_VER >= 11 + { + typedef std::basic_string, min_allocator> S; + test(S()); + test(S("123")); + } +#endif +} diff --git a/tests/external/libcxx/basic_string/string.iterators/cend.pass.cpp b/tests/external/libcxx/basic_string/string.iterators/cend.pass.cpp new file mode 100644 index 0000000..9ee56be --- /dev/null +++ b/tests/external/libcxx/basic_string/string.iterators/cend.pass.cpp @@ -0,0 +1,41 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// + +// const_iterator cend() const; + +#include +#include + +#include "min_allocator.h" + +template +void +test(const S& s) +{ + typename S::const_iterator ce = s.cend(); + assert(ce == s.end()); +} + +int main() +{ + { + typedef std::string S; + test(S()); + test(S("123")); + } +#if TEST_STD_VER >= 11 + { + typedef std::basic_string, min_allocator> S; + test(S()); + test(S("123")); + } +#endif +} diff --git a/tests/external/libcxx/basic_string/string.iterators/crbegin.pass.cpp b/tests/external/libcxx/basic_string/string.iterators/crbegin.pass.cpp new file mode 100644 index 0000000..90988a3 --- /dev/null +++ b/tests/external/libcxx/basic_string/string.iterators/crbegin.pass.cpp @@ -0,0 +1,45 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// + +// const_reverse_iterator crbegin() const; + +#include +#include + +#include "min_allocator.h" + +template +void +test(const S& s) +{ + typename S::const_reverse_iterator cb = s.crbegin(); + if (!s.empty()) + { + assert(*cb == s.back()); + } + assert(cb == s.rbegin()); +} + +int main() +{ + { + typedef std::string S; + test(S()); + test(S("123")); + } +#if TEST_STD_VER >= 11 + { + typedef std::basic_string, min_allocator> S; + test(S()); + test(S("123")); + } +#endif +} diff --git a/tests/external/libcxx/basic_string/string.iterators/crend.pass.cpp b/tests/external/libcxx/basic_string/string.iterators/crend.pass.cpp new file mode 100644 index 0000000..bb38378 --- /dev/null +++ b/tests/external/libcxx/basic_string/string.iterators/crend.pass.cpp @@ -0,0 +1,41 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// + +// const_reverse_iterator crend() const; + +#include +#include + +#include "min_allocator.h" + +template +void +test(const S& s) +{ + typename S::const_reverse_iterator ce = s.crend(); + assert(ce == s.rend()); +} + +int main() +{ + { + typedef std::string S; + test(S()); + test(S("123")); + } +#if TEST_STD_VER >= 11 + { + typedef std::basic_string, min_allocator> S; + test(S()); + test(S("123")); + } +#endif +} diff --git a/tests/external/libcxx/basic_string/string.iterators/db_iterators_2.pass.cpp b/tests/external/libcxx/basic_string/string.iterators/db_iterators_2.pass.cpp new file mode 100644 index 0000000..e46368c --- /dev/null +++ b/tests/external/libcxx/basic_string/string.iterators/db_iterators_2.pass.cpp @@ -0,0 +1,52 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// + +// Compare iterators from different containers with <. + +#if _LIBCPP_DEBUG >= 1 + +#define _LIBCPP_ASSERT(x, m) ((x) ? (void)0 : std::exit(0)) + +#include +#include +#include +#include +#include + +#include "min_allocator.h" + +int main() +{ + { + typedef std::string S; + S s1; + S s2; + bool b = s1.begin() < s2.begin(); + assert(false); + } +#if TEST_STD_VER >= 11 + { + typedef std::basic_string, min_allocator> S; + S s1; + S s2; + bool b = s1.begin() < s2.begin(); + assert(false); + } +#endif +} + +#else + +int main() +{ +} + +#endif diff --git a/tests/external/libcxx/basic_string/string.iterators/db_iterators_3.pass.cpp b/tests/external/libcxx/basic_string/string.iterators/db_iterators_3.pass.cpp new file mode 100644 index 0000000..3ed15d7 --- /dev/null +++ b/tests/external/libcxx/basic_string/string.iterators/db_iterators_3.pass.cpp @@ -0,0 +1,52 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// + +// Subtract iterators from different containers with <. + +#if _LIBCPP_DEBUG >= 1 + +#define _LIBCPP_ASSERT(x, m) ((x) ? (void)0 : std::exit(0)) + +#include +#include +#include +#include +#include + +#include "min_allocator.h" + +int main() +{ + { + typedef std::string S; + S s1; + S s2; + int i = s1.begin() - s2.begin(); + assert(false); + } +#if TEST_STD_VER >= 11 + { + typedef std::basic_string, min_allocator> S; + S s1; + S s2; + int i = s1.begin() - s2.begin(); + assert(false); + } +#endif +} + +#else + +int main() +{ +} + +#endif diff --git a/tests/external/libcxx/basic_string/string.iterators/db_iterators_4.pass.cpp b/tests/external/libcxx/basic_string/string.iterators/db_iterators_4.pass.cpp new file mode 100644 index 0000000..85ea220 --- /dev/null +++ b/tests/external/libcxx/basic_string/string.iterators/db_iterators_4.pass.cpp @@ -0,0 +1,54 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// + +// Index iterator out of bounds. + +#if _LIBCPP_DEBUG >= 1 + +#define _LIBCPP_ASSERT(x, m) ((x) ? (void)0 : std::exit(0)) + +#include +#include +#include +#include +#include + +#include "min_allocator.h" + +int main() +{ + { + typedef std::string C; + C c(1, '\0'); + C::iterator i = c.begin(); + assert(i[0] == 0); + assert(i[1] == 0); + assert(false); + } +#if TEST_STD_VER >= 11 + { + typedef std::basic_string, min_allocator> C; + C c(1, '\0'); + C::iterator i = c.begin(); + assert(i[0] == 0); + assert(i[1] == 0); + assert(false); + } +#endif +} + +#else + +int main() +{ +} + +#endif diff --git a/tests/external/libcxx/basic_string/string.iterators/db_iterators_5.pass.cpp b/tests/external/libcxx/basic_string/string.iterators/db_iterators_5.pass.cpp new file mode 100644 index 0000000..9702090 --- /dev/null +++ b/tests/external/libcxx/basic_string/string.iterators/db_iterators_5.pass.cpp @@ -0,0 +1,58 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// + +// Add to iterator out of bounds. + +#if _LIBCPP_DEBUG >= 1 + +#define _LIBCPP_ASSERT(x, m) ((x) ? (void)0 : std::exit(0)) + +#include +#include +#include +#include +#include + +#include "min_allocator.h" + +int main() +{ + { + typedef std::string C; + C c(1, '\0'); + C::iterator i = c.begin(); + i += 1; + assert(i == c.end()); + i = c.begin(); + i += 2; + assert(false); + } +#if TEST_STD_VER >= 11 + { + typedef std::basic_string, min_allocator> C; + C c(1, '\0'); + C::iterator i = c.begin(); + i += 1; + assert(i == c.end()); + i = c.begin(); + i += 2; + assert(false); + } +#endif +} + +#else + +int main() +{ +} + +#endif diff --git a/tests/external/libcxx/basic_string/string.iterators/db_iterators_6.pass.cpp b/tests/external/libcxx/basic_string/string.iterators/db_iterators_6.pass.cpp new file mode 100644 index 0000000..e42ba4c --- /dev/null +++ b/tests/external/libcxx/basic_string/string.iterators/db_iterators_6.pass.cpp @@ -0,0 +1,56 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// + +// Decrement iterator prior to begin. + +#if _LIBCPP_DEBUG >= 1 + +#define _LIBCPP_ASSERT(x, m) ((x) ? (void)0 : std::exit(0)) + +#include +#include +#include +#include +#include + +#include "min_allocator.h" + +int main() +{ + { + typedef std::string C; + C c(1, '\0'); + C::iterator i = c.end(); + --i; + assert(i == c.begin()); + --i; + assert(false); + } +#if TEST_STD_VER >= 11 + { + typedef std::basic_string, min_allocator> C; + C c(1, '\0'); + C::iterator i = c.end(); + --i; + assert(i == c.begin()); + --i; + assert(false); + } +#endif +} + +#else + +int main() +{ +} + +#endif diff --git a/tests/external/libcxx/basic_string/string.iterators/db_iterators_7.pass.cpp b/tests/external/libcxx/basic_string/string.iterators/db_iterators_7.pass.cpp new file mode 100644 index 0000000..69a6821 --- /dev/null +++ b/tests/external/libcxx/basic_string/string.iterators/db_iterators_7.pass.cpp @@ -0,0 +1,56 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// + +// Increment iterator past end. + +#if _LIBCPP_DEBUG >= 1 + +#define _LIBCPP_ASSERT(x, m) ((x) ? (void)0 : std::exit(0)) + +#include +#include +#include +#include +#include + +#include "min_allocator.h" + +int main() +{ + { + typedef std::string C; + C c(1, '\0'); + C::iterator i = c.begin(); + ++i; + assert(i == c.end()); + ++i; + assert(false); + } +#if TEST_STD_VER >= 11 + { + typedef std::basic_string, min_allocator> C; + C c(1, '\0'); + C::iterator i = c.begin(); + ++i; + assert(i == c.end()); + ++i; + assert(false); + } +#endif +} + +#else + +int main() +{ +} + +#endif diff --git a/tests/external/libcxx/basic_string/string.iterators/db_iterators_8.pass.cpp b/tests/external/libcxx/basic_string/string.iterators/db_iterators_8.pass.cpp new file mode 100644 index 0000000..5472773 --- /dev/null +++ b/tests/external/libcxx/basic_string/string.iterators/db_iterators_8.pass.cpp @@ -0,0 +1,52 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// + +// Dereference non-dereferenceable iterator. + +#if _LIBCPP_DEBUG >= 1 + +#define _LIBCPP_ASSERT(x, m) ((x) ? (void)0 : std::exit(0)) + +#include +#include +#include +#include +#include + +#include "min_allocator.h" + +int main() +{ + { + typedef std::string C; + C c(1, '\0'); + C::iterator i = c.end(); + char j = *i; + assert(false); + } +#if TEST_STD_VER >= 11 + { + typedef std::basic_string, min_allocator> C; + C c(1, '\0'); + C::iterator i = c.end(); + char j = *i; + assert(false); + } +#endif +} + +#else + +int main() +{ +} + +#endif diff --git a/tests/external/libcxx/basic_string/string.iterators/end.pass.cpp b/tests/external/libcxx/basic_string/string.iterators/end.pass.cpp new file mode 100644 index 0000000..3ad6026 --- /dev/null +++ b/tests/external/libcxx/basic_string/string.iterators/end.pass.cpp @@ -0,0 +1,51 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// + +// iterator end(); +// const_iterator end() const; + +#include +#include +#include + +#include "min_allocator.h" + +template +void +test(S s) +{ + const S& cs = s; + typename S::iterator e = s.end(); + typename S::const_iterator ce = cs.end(); + if (s.empty()) + { + assert(e == s.begin()); + assert(ce == cs.begin()); + } + assert(static_cast(e - s.begin()) == s.size()); + assert(static_cast(ce - cs.begin()) == cs.size()); +} + +int main() +{ + { + typedef std::string S; + test(S()); + test(S("123")); + } +#if TEST_STD_VER >= 11 + { + typedef std::basic_string, min_allocator> S; + test(S()); + test(S("123")); + } +#endif +} diff --git a/tests/external/libcxx/basic_string/string.iterators/iterators.pass.cpp b/tests/external/libcxx/basic_string/string.iterators/iterators.pass.cpp new file mode 100644 index 0000000..9466f11 --- /dev/null +++ b/tests/external/libcxx/basic_string/string.iterators/iterators.pass.cpp @@ -0,0 +1,73 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// UNSUPPORTED: c++98, c++03, c++11 + +// + +// iterator begin(); +// iterator end(); +// const_iterator begin() const; +// const_iterator end() const; +// const_iterator cbegin() const; +// const_iterator cend() const; + +#include +#include + +int main() +{ + { // N3644 testing + typedef std::string C; + C::iterator ii1{}, ii2{}; + C::iterator ii4 = ii1; + C::const_iterator cii{}; + assert ( ii1 == ii2 ); + assert ( ii1 == ii4 ); + assert ( ii1 == cii ); + assert ( !(ii1 != ii2 )); + assert ( !(ii1 != cii )); + } + + { // N3644 testing + typedef std::wstring C; + C::iterator ii1{}, ii2{}; + C::iterator ii4 = ii1; + C::const_iterator cii{}; + assert ( ii1 == ii2 ); + assert ( ii1 == ii4 ); + assert ( ii1 == cii ); + assert ( !(ii1 != ii2 )); + assert ( !(ii1 != cii )); + } + + { // N3644 testing + typedef std::u16string C; + C::iterator ii1{}, ii2{}; + C::iterator ii4 = ii1; + C::const_iterator cii{}; + assert ( ii1 == ii2 ); + assert ( ii1 == ii4 ); + assert ( ii1 == cii ); + assert ( !(ii1 != ii2 )); + assert ( !(ii1 != cii )); + } + + { // N3644 testing + typedef std::u32string C; + C::iterator ii1{}, ii2{}; + C::iterator ii4 = ii1; + C::const_iterator cii{}; + assert ( ii1 == ii2 ); + assert ( ii1 == ii4 ); + assert ( ii1 == cii ); + assert ( !(ii1 != ii2 )); + assert ( !(ii1 != cii )); + } +} diff --git a/tests/external/libcxx/basic_string/string.iterators/rbegin.pass.cpp b/tests/external/libcxx/basic_string/string.iterators/rbegin.pass.cpp new file mode 100644 index 0000000..698d613 --- /dev/null +++ b/tests/external/libcxx/basic_string/string.iterators/rbegin.pass.cpp @@ -0,0 +1,48 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// + +// reverse_iterator rbegin(); +// const_reverse_iterator rbegin() const; + +#include +#include + +#include "min_allocator.h" + +template +void +test(S s) +{ + const S& cs = s; + typename S::reverse_iterator b = s.rbegin(); + typename S::const_reverse_iterator cb = cs.rbegin(); + if (!s.empty()) + { + assert(*b == s.back()); + } + assert(b == cb); +} + +int main() +{ + { + typedef std::string S; + test(S()); + test(S("123")); + } +#if TEST_STD_VER >= 11 + { + typedef std::basic_string, min_allocator> S; + test(S()); + test(S("123")); + } +#endif +} diff --git a/tests/external/libcxx/basic_string/string.iterators/rend.pass.cpp b/tests/external/libcxx/basic_string/string.iterators/rend.pass.cpp new file mode 100644 index 0000000..93c47e6 --- /dev/null +++ b/tests/external/libcxx/basic_string/string.iterators/rend.pass.cpp @@ -0,0 +1,51 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// + +// reverse_iterator rend(); +// const_reverse_iterator rend() const; + +#include +#include +#include + +#include "min_allocator.h" + +template +void +test(S s) +{ + const S& cs = s; + typename S::reverse_iterator e = s.rend(); + typename S::const_reverse_iterator ce = cs.rend(); + if (s.empty()) + { + assert(e == s.rbegin()); + assert(ce == cs.rbegin()); + } + assert(static_cast(e - s.rbegin()) == s.size()); + assert(static_cast(ce - cs.rbegin()) == cs.size()); +} + +int main() +{ + { + typedef std::string S; + test(S()); + test(S("123")); + } +#if TEST_STD_VER >= 11 + { + typedef std::basic_string, min_allocator> S; + test(S()); + test(S("123")); + } +#endif +} diff --git a/tests/external/libcxx/basic_string/string.modifiers/nothing_to_do.pass.cpp b/tests/external/libcxx/basic_string/string.modifiers/nothing_to_do.pass.cpp new file mode 100644 index 0000000..b58f5c5 --- /dev/null +++ b/tests/external/libcxx/basic_string/string.modifiers/nothing_to_do.pass.cpp @@ -0,0 +1,12 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +int main() +{ +} diff --git a/tests/external/libcxx/basic_string/string.modifiers/string_append/T_size_size.pass.cpp b/tests/external/libcxx/basic_string/string.modifiers/string_append/T_size_size.pass.cpp new file mode 100644 index 0000000..fcd18b7 --- /dev/null +++ b/tests/external/libcxx/basic_string/string.modifiers/string_append/T_size_size.pass.cpp @@ -0,0 +1,200 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// + +// template +// basic_string& append(const T& t, size_type pos, size_type n=npos); // C++17 + +#include +#include +#include +#include + +#include "test_macros.h" +#include "min_allocator.h" + +template +void +test(S s, SV sv, typename S::size_type pos, typename S::size_type n, S expected) +{ + if (pos <= sv.size()) + { + s.append(sv, pos, n); + LIBCPP_ASSERT(s.__invariants()); + assert(s == expected); + } +#ifndef TEST_HAS_NO_EXCEPTIONS + else + { + try + { + s.append(sv, pos, n); + assert(false); + } + catch (std::out_of_range&) + { + assert(pos > sv.size()); + } + } +#endif +} + +template +void +test_npos(S s, SV sv, typename S::size_type pos, S expected) +{ + if (pos <= sv.size()) + { + s.append(sv, pos); + LIBCPP_ASSERT(s.__invariants()); + assert(s == expected); + } +#ifndef TEST_HAS_NO_EXCEPTIONS + else + { + try + { + s.append(sv, pos); + assert(false); + } + catch (std::out_of_range&) + { + assert(pos > sv.size()); + } + } +#endif +} + +int main() +{ + { + typedef std::string S; + typedef std::string_view SV; + test(S(), SV(), 0, 0, S()); + test(S(), SV(), 1, 0, S()); + test(S(), SV("12345"), 0, 3, S("123")); + test(S(), SV("12345"), 1, 4, S("2345")); + test(S(), SV("12345"), 3, 15, S("45")); + test(S(), SV("12345"), 5, 15, S("")); + test(S(), SV("12345"), 6, 15, S("not happening")); + test(S(), SV("12345678901234567890"), 0, 0, S()); + test(S(), SV("12345678901234567890"), 1, 1, S("2")); + test(S(), SV("12345678901234567890"), 2, 3, S("345")); + test(S(), SV("12345678901234567890"), 12, 13, S("34567890")); + test(S(), SV("12345678901234567890"), 21, 13, S("not happening")); + + test(S("12345"), SV(), 0, 0, S("12345")); + test(S("12345"), SV("12345"), 2, 2, S("1234534")); + test(S("12345"), SV("1234567890"), 0, 100, S("123451234567890")); + + test(S("12345678901234567890"), SV(), 0, 0, S("12345678901234567890")); + test(S("12345678901234567890"), SV("12345"), 1, 3, S("12345678901234567890234")); + test(S("12345678901234567890"), SV("12345678901234567890"), 5, 10, + S("123456789012345678906789012345")); + } +#if TEST_STD_VER >= 11 + { + typedef std::basic_string , min_allocator> S; + typedef std::basic_string_view > SV; + test(S(), SV(), 0, 0, S()); + test(S(), SV(), 1, 0, S()); + test(S(), SV("12345"), 0, 3, S("123")); + test(S(), SV("12345"), 1, 4, S("2345")); + test(S(), SV("12345"), 3, 15, S("45")); + test(S(), SV("12345"), 5, 15, S("")); + test(S(), SV("12345"), 6, 15, S("not happening")); + test(S(), SV("12345678901234567890"), 0, 0, S()); + test(S(), SV("12345678901234567890"), 1, 1, S("2")); + test(S(), SV("12345678901234567890"), 2, 3, S("345")); + test(S(), SV("12345678901234567890"), 12, 13, S("34567890")); + test(S(), SV("12345678901234567890"), 21, 13, S("not happening")); + + test(S("12345"), SV(), 0, 0, S("12345")); + test(S("12345"), SV("12345"), 2, 2, S("1234534")); + test(S("12345"), SV("1234567890"), 0, 100, S("123451234567890")); + + test(S("12345678901234567890"), SV(), 0, 0, S("12345678901234567890")); + test(S("12345678901234567890"), SV("12345"), 1, 3, S("12345678901234567890234")); + test(S("12345678901234567890"), SV("12345678901234567890"), 5, 10, + S("123456789012345678906789012345")); + } +#endif + { + typedef std::string S; + typedef std::string_view SV; + test_npos(S(), SV(), 0, S()); + test_npos(S(), SV(), 1, S()); + test_npos(S(), SV("12345"), 0, S("12345")); + test_npos(S(), SV("12345"), 1, S("2345")); + test_npos(S(), SV("12345"), 3, S("45")); + test_npos(S(), SV("12345"), 5, S("")); + test_npos(S(), SV("12345"), 6, S("not happening")); + } + + { + std::string s; + std::string_view sv = "EFGH"; + char arr[] = "IJKL"; + + s.append("CDEF", 0); // calls append(const char *, len) + assert(s == ""); + s.clear(); + + s.append("QRST", 0, std::string::npos); // calls append(string("QRST"), pos, npos) + assert(s == "QRST"); + s.clear(); + + s.append(sv, 0); // calls append(T, pos, npos) + assert(s == sv); + s.clear(); + + s.append(sv, 0, std::string::npos); // calls append(T, pos, npos) + assert(s == sv); + s.clear(); + + s.append(arr, 0); // calls append(const char *, len) + assert(s == ""); + s.clear(); + + s.append(arr, 0, std::string::npos); // calls append(string("IJKL"), pos, npos) + assert(s == "IJKL"); + s.clear(); + + s.append(arr, 0); // calls append(const char *, len) + assert(s == ""); + s.clear(); + } + + { + std::string s = "ABCD"; + std::string_view sv = s; + s.append(sv); + assert(s == "ABCDABCD"); + + sv = s; + s.append(sv, 0, std::string::npos); + assert(s == "ABCDABCDABCDABCD"); + + sv = s; + s.append(sv, sv.size()); + assert(s == "ABCDABCDABCDABCD"); + } + + { + std::string s = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"; + std::string_view sv = s; + s.append(sv); + assert(s == "ABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZ"); + + sv = s; + s.append(sv, 0, std::string::npos); + assert(s == "ABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZ"); + } +} diff --git a/tests/external/libcxx/basic_string/string.modifiers/string_append/initializer_list.pass.cpp b/tests/external/libcxx/basic_string/string.modifiers/string_append/initializer_list.pass.cpp new file mode 100644 index 0000000..d30ca44 --- /dev/null +++ b/tests/external/libcxx/basic_string/string.modifiers/string_append/initializer_list.pass.cpp @@ -0,0 +1,35 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// UNSUPPORTED: c++98, c++03 + +// + +// basic_string& append(initializer_list il); + +#include +#include + +#include "test_macros.h" +#include "min_allocator.h" + +int main() +{ + { + std::string s("123"); + s.append({'a', 'b', 'c'}); + assert(s == "123abc"); + } + { + typedef std::basic_string, min_allocator> S; + S s("123"); + s.append({'a', 'b', 'c'}); + assert(s == "123abc"); + } +} diff --git a/tests/external/libcxx/basic_string/string.modifiers/string_append/iterator.pass.cpp b/tests/external/libcxx/basic_string/string.modifiers/string_append/iterator.pass.cpp new file mode 100644 index 0000000..7ed5540 --- /dev/null +++ b/tests/external/libcxx/basic_string/string.modifiers/string_append/iterator.pass.cpp @@ -0,0 +1,223 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// + +// template +// basic_string& append(InputIterator first, InputIterator last); + +#include +#include + +#include "test_iterators.h" +#include "min_allocator.h" + +template +void +test(S s, It first, It last, S expected) +{ + s.append(first, last); + LIBCPP_ASSERT(s.__invariants()); + assert(s == expected); +} + +#ifndef TEST_HAS_NO_EXCEPTIONS +template +void +test_exceptions(S s, It first, It last) +{ + S aCopy = s; + try { + s.append(first, last); + assert(false); + } + catch (...) {} + LIBCPP_ASSERT(s.__invariants()); + assert(s == aCopy); +} +#endif + +int main() +{ + { + typedef std::string S; + const char* s = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"; + test(S(), s, s, S()); + test(S(), s, s+1, S("A")); + test(S(), s, s+10, S("ABCDEFGHIJ")); + test(S(), s, s+52, S("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz")); + + test(S("12345"), s, s, S("12345")); + test(S("12345"), s, s+1, S("12345A")); + test(S("12345"), s, s+10, S("12345ABCDEFGHIJ")); + test(S("12345"), s, s+52, S("12345ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz")); + + test(S("1234567890"), s, s, S("1234567890")); + test(S("1234567890"), s, s+1, S("1234567890A")); + test(S("1234567890"), s, s+10, S("1234567890ABCDEFGHIJ")); + test(S("1234567890"), s, s+52, S("1234567890ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz")); + + test(S("12345678901234567890"), s, s, S("12345678901234567890")); + test(S("12345678901234567890"), s, s+1, S("12345678901234567890""A")); + test(S("12345678901234567890"), s, s+10, S("12345678901234567890""ABCDEFGHIJ")); + test(S("12345678901234567890"), s, s+52, + S("12345678901234567890""ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz")); + + test(S(), input_iterator(s), input_iterator(s), S()); + test(S(), input_iterator(s), input_iterator(s+1), S("A")); + test(S(), input_iterator(s), input_iterator(s+10), + S("ABCDEFGHIJ")); + test(S(), input_iterator(s), input_iterator(s+52), + S("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz")); + + test(S("12345"), input_iterator(s), input_iterator(s), + S("12345")); + test(S("12345"), input_iterator(s), input_iterator(s+1), + S("12345A")); + test(S("12345"), input_iterator(s), input_iterator(s+10), + S("12345ABCDEFGHIJ")); + test(S("12345"), input_iterator(s), input_iterator(s+52), + S("12345ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz")); + + test(S("1234567890"), input_iterator(s), input_iterator(s), + S("1234567890")); + test(S("1234567890"), input_iterator(s), input_iterator(s+1), + S("1234567890A")); + test(S("1234567890"), input_iterator(s), input_iterator(s+10), + S("1234567890ABCDEFGHIJ")); + test(S("1234567890"), input_iterator(s), input_iterator(s+52), + S("1234567890ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz")); + + test(S("12345678901234567890"), input_iterator(s), input_iterator(s), + S("12345678901234567890")); + test(S("12345678901234567890"), input_iterator(s), input_iterator(s+1), + S("12345678901234567890""A")); + test(S("12345678901234567890"), input_iterator(s), input_iterator(s+10), + S("12345678901234567890""ABCDEFGHIJ")); + test(S("12345678901234567890"), input_iterator(s), input_iterator(s+52), + S("12345678901234567890""ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz")); + } +#if TEST_STD_VER >= 11 + { + typedef std::basic_string, min_allocator> S; + const char* s = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"; + test(S(), s, s, S()); + test(S(), s, s+1, S("A")); + test(S(), s, s+10, S("ABCDEFGHIJ")); + test(S(), s, s+52, S("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz")); + + test(S("12345"), s, s, S("12345")); + test(S("12345"), s, s+1, S("12345A")); + test(S("12345"), s, s+10, S("12345ABCDEFGHIJ")); + test(S("12345"), s, s+52, S("12345ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz")); + + test(S("1234567890"), s, s, S("1234567890")); + test(S("1234567890"), s, s+1, S("1234567890A")); + test(S("1234567890"), s, s+10, S("1234567890ABCDEFGHIJ")); + test(S("1234567890"), s, s+52, S("1234567890ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz")); + + test(S("12345678901234567890"), s, s, S("12345678901234567890")); + test(S("12345678901234567890"), s, s+1, S("12345678901234567890""A")); + test(S("12345678901234567890"), s, s+10, S("12345678901234567890""ABCDEFGHIJ")); + test(S("12345678901234567890"), s, s+52, + S("12345678901234567890""ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz")); + + test(S(), input_iterator(s), input_iterator(s), S()); + test(S(), input_iterator(s), input_iterator(s+1), S("A")); + test(S(), input_iterator(s), input_iterator(s+10), + S("ABCDEFGHIJ")); + test(S(), input_iterator(s), input_iterator(s+52), + S("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz")); + + test(S("12345"), input_iterator(s), input_iterator(s), + S("12345")); + test(S("12345"), input_iterator(s), input_iterator(s+1), + S("12345A")); + test(S("12345"), input_iterator(s), input_iterator(s+10), + S("12345ABCDEFGHIJ")); + test(S("12345"), input_iterator(s), input_iterator(s+52), + S("12345ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz")); + + test(S("1234567890"), input_iterator(s), input_iterator(s), + S("1234567890")); + test(S("1234567890"), input_iterator(s), input_iterator(s+1), + S("1234567890A")); + test(S("1234567890"), input_iterator(s), input_iterator(s+10), + S("1234567890ABCDEFGHIJ")); + test(S("1234567890"), input_iterator(s), input_iterator(s+52), + S("1234567890ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz")); + + test(S("12345678901234567890"), input_iterator(s), input_iterator(s), + S("12345678901234567890")); + test(S("12345678901234567890"), input_iterator(s), input_iterator(s+1), + S("12345678901234567890""A")); + test(S("12345678901234567890"), input_iterator(s), input_iterator(s+10), + S("12345678901234567890""ABCDEFGHIJ")); + test(S("12345678901234567890"), input_iterator(s), input_iterator(s+52), + S("12345678901234567890""ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz")); + } +#endif +#ifndef TEST_HAS_NO_EXCEPTIONS + { // test iterator operations that throw + typedef std::string S; + typedef ThrowingIterator TIter; + typedef input_iterator IIter; + const char* s = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"; + test_exceptions(S(), IIter(TIter(s, s+10, 4, TIter::TAIncrement)), IIter()); + test_exceptions(S(), IIter(TIter(s, s+10, 5, TIter::TADereference)), IIter()); + test_exceptions(S(), IIter(TIter(s, s+10, 6, TIter::TAComparison)), IIter()); + + test_exceptions(S(), TIter(s, s+10, 4, TIter::TAIncrement), TIter()); + test_exceptions(S(), TIter(s, s+10, 5, TIter::TADereference), TIter()); + test_exceptions(S(), TIter(s, s+10, 6, TIter::TAComparison), TIter()); + } +#endif + + { // test appending to self + typedef std::string S; + S s_short = "123/"; + S s_long = "Lorem ipsum dolor sit amet, consectetur/"; + + s_short.append(s_short.begin(), s_short.end()); + assert(s_short == "123/123/"); + s_short.append(s_short.begin(), s_short.end()); + assert(s_short == "123/123/123/123/"); + s_short.append(s_short.begin(), s_short.end()); + assert(s_short == "123/123/123/123/123/123/123/123/"); + + s_long.append(s_long.begin(), s_long.end()); + assert(s_long == "Lorem ipsum dolor sit amet, consectetur/Lorem ipsum dolor sit amet, consectetur/"); + } + + { // test appending a different type + typedef std::string S; + const uint8_t p[] = "ABCD"; + + S s; + s.append(p, p + 4); + assert(s == "ABCD"); + } + + { // test with a move iterator that returns char&& + typedef forward_iterator It; + typedef std::move_iterator MoveIt; + const char p[] = "ABCD"; + std::string s; + s.append(MoveIt(It(std::begin(p))), MoveIt(It(std::end(p) - 1))); + assert(s == "ABCD"); + } + { // test with a move iterator that returns char&& + typedef const char* It; + typedef std::move_iterator MoveIt; + const char p[] = "ABCD"; + std::string s; + s.append(MoveIt(It(std::begin(p))), MoveIt(It(std::end(p) - 1))); + assert(s == "ABCD"); + } +} diff --git a/tests/external/libcxx/basic_string/string.modifiers/string_append/pointer.pass.cpp b/tests/external/libcxx/basic_string/string.modifiers/string_append/pointer.pass.cpp new file mode 100644 index 0000000..823905d --- /dev/null +++ b/tests/external/libcxx/basic_string/string.modifiers/string_append/pointer.pass.cpp @@ -0,0 +1,80 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// + +// basic_string& append(const charT* s); + +#include +#include +#include + +#include "test_macros.h" +#include "min_allocator.h" + +template +void +test(S s, const typename S::value_type* str, S expected) +{ + s.append(str); + LIBCPP_ASSERT(s.__invariants()); + assert(s == expected); +} + +int main() +{ + { + typedef std::string S; + test(S(), "", S()); + test(S(), "12345", S("12345")); + test(S(), "12345678901234567890", S("12345678901234567890")); + + test(S("12345"), "", S("12345")); + test(S("12345"), "12345", S("1234512345")); + test(S("12345"), "1234567890", S("123451234567890")); + + test(S("12345678901234567890"), "", S("12345678901234567890")); + test(S("12345678901234567890"), "12345", S("1234567890123456789012345")); + test(S("12345678901234567890"), "12345678901234567890", + S("1234567890123456789012345678901234567890")); + } +#if TEST_STD_VER >= 11 + { + typedef std::basic_string, min_allocator> S; + test(S(), "", S()); + test(S(), "12345", S("12345")); + test(S(), "12345678901234567890", S("12345678901234567890")); + + test(S("12345"), "", S("12345")); + test(S("12345"), "12345", S("1234512345")); + test(S("12345"), "1234567890", S("123451234567890")); + + test(S("12345678901234567890"), "", S("12345678901234567890")); + test(S("12345678901234567890"), "12345", S("1234567890123456789012345")); + test(S("12345678901234567890"), "12345678901234567890", + S("1234567890123456789012345678901234567890")); + } +#endif + + { // test appending to self + typedef std::string S; + S s_short = "123/"; + S s_long = "Lorem ipsum dolor sit amet, consectetur/"; + + s_short.append(s_short.c_str()); + assert(s_short == "123/123/"); + s_short.append(s_short.c_str()); + assert(s_short == "123/123/123/123/"); + s_short.append(s_short.c_str()); + assert(s_short == "123/123/123/123/123/123/123/123/"); + + s_long.append(s_long.c_str()); + assert(s_long == "Lorem ipsum dolor sit amet, consectetur/Lorem ipsum dolor sit amet, consectetur/"); + } +} diff --git a/tests/external/libcxx/basic_string/string.modifiers/string_append/pointer_size.pass.cpp b/tests/external/libcxx/basic_string/string.modifiers/string_append/pointer_size.pass.cpp new file mode 100644 index 0000000..f09ec68 --- /dev/null +++ b/tests/external/libcxx/basic_string/string.modifiers/string_append/pointer_size.pass.cpp @@ -0,0 +1,89 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// + +// basic_string& +// append(const charT* s, size_type n); + +#include +#include +#include + +#include "test_macros.h" +#include "min_allocator.h" + +template +void +test(S s, const typename S::value_type* str, typename S::size_type n, S expected) +{ + s.append(str, n); + LIBCPP_ASSERT(s.__invariants()); + assert(s == expected); +} + +int main() +{ + { + typedef std::string S; + test(S(), "", 0, S()); + test(S(), "12345", 3, S("123")); + test(S(), "12345", 4, S("1234")); + test(S(), "12345678901234567890", 0, S()); + test(S(), "12345678901234567890", 1, S("1")); + test(S(), "12345678901234567890", 3, S("123")); + test(S(), "12345678901234567890", 20, S("12345678901234567890")); + + test(S("12345"), "", 0, S("12345")); + test(S("12345"), "12345", 5, S("1234512345")); + test(S("12345"), "1234567890", 10, S("123451234567890")); + + test(S("12345678901234567890"), "", 0, S("12345678901234567890")); + test(S("12345678901234567890"), "12345", 5, S("1234567890123456789012345")); + test(S("12345678901234567890"), "12345678901234567890", 20, + S("1234567890123456789012345678901234567890")); + } +#if TEST_STD_VER >= 11 + { + typedef std::basic_string, min_allocator> S; + test(S(), "", 0, S()); + test(S(), "12345", 3, S("123")); + test(S(), "12345", 4, S("1234")); + test(S(), "12345678901234567890", 0, S()); + test(S(), "12345678901234567890", 1, S("1")); + test(S(), "12345678901234567890", 3, S("123")); + test(S(), "12345678901234567890", 20, S("12345678901234567890")); + + test(S("12345"), "", 0, S("12345")); + test(S("12345"), "12345", 5, S("1234512345")); + test(S("12345"), "1234567890", 10, S("123451234567890")); + + test(S("12345678901234567890"), "", 0, S("12345678901234567890")); + test(S("12345678901234567890"), "12345", 5, S("1234567890123456789012345")); + test(S("12345678901234567890"), "12345678901234567890", 20, + S("1234567890123456789012345678901234567890")); + } +#endif + + { // test appending to self + typedef std::string S; + S s_short = "123/"; + S s_long = "Lorem ipsum dolor sit amet, consectetur/"; + + s_short.append(s_short.data(), s_short.size()); + assert(s_short == "123/123/"); + s_short.append(s_short.data(), s_short.size()); + assert(s_short == "123/123/123/123/"); + s_short.append(s_short.data(), s_short.size()); + assert(s_short == "123/123/123/123/123/123/123/123/"); + + s_long.append(s_long.data(), s_long.size()); + assert(s_long == "Lorem ipsum dolor sit amet, consectetur/Lorem ipsum dolor sit amet, consectetur/"); + } +} diff --git a/tests/external/libcxx/basic_string/string.modifiers/string_append/push_back.pass.cpp b/tests/external/libcxx/basic_string/string.modifiers/string_append/push_back.pass.cpp new file mode 100644 index 0000000..38b68aa --- /dev/null +++ b/tests/external/libcxx/basic_string/string.modifiers/string_append/push_back.pass.cpp @@ -0,0 +1,60 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// + +// void push_back(charT c) + +#include +#include + +#include "test_macros.h" +#include "min_allocator.h" + +struct veryLarge +{ + long long a; + char b; +}; + +template +void +test(S s, typename S::value_type c, S expected) +{ + s.push_back(c); + LIBCPP_ASSERT(s.__invariants()); + assert(s == expected); +} + +int main() +{ + { + typedef std::string S; + test(S(), 'a', S(1, 'a')); + test(S("12345"), 'a', S("12345a")); + test(S("12345678901234567890"), 'a', S("12345678901234567890a")); + } +#if TEST_STD_VER >= 11 + { + typedef std::basic_string, min_allocator> S; + test(S(), 'a', S(1, 'a')); + test(S("12345"), 'a', S("12345a")); + test(S("12345678901234567890"), 'a', S("12345678901234567890a")); + } +#endif + + { +// https://bugs.llvm.org/show_bug.cgi?id=31454 + std::basic_string s; + veryLarge vl = {}; + s.push_back(vl); + s.push_back(vl); + s.push_back(vl); + } +} diff --git a/tests/external/libcxx/basic_string/string.modifiers/string_append/size_char.pass.cpp b/tests/external/libcxx/basic_string/string.modifiers/string_append/size_char.pass.cpp new file mode 100644 index 0000000..1610ab5 --- /dev/null +++ b/tests/external/libcxx/basic_string/string.modifiers/string_append/size_char.pass.cpp @@ -0,0 +1,64 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// + +// basic_string& +// append(size_type n, charT c); + +#include +#include + +#include "test_macros.h" +#include "min_allocator.h" + +template +void +test(S s, typename S::size_type n, typename S::value_type c, S expected) +{ + s.append(n, c); + LIBCPP_ASSERT(s.__invariants()); + assert(s == expected); +} + +int main() +{ + { + typedef std::string S; + test(S(), 0, 'a', S()); + test(S(), 1, 'a', S(1, 'a')); + test(S(), 10, 'a', S(10, 'a')); + test(S(), 100, 'a', S(100, 'a')); + + test(S("12345"), 0, 'a', S("12345")); + test(S("12345"), 1, 'a', S("12345a")); + test(S("12345"), 10, 'a', S("12345aaaaaaaaaa")); + + test(S("12345678901234567890"), 0, 'a', S("12345678901234567890")); + test(S("12345678901234567890"), 1, 'a', S("12345678901234567890a")); + test(S("12345678901234567890"), 10, 'a', S("12345678901234567890aaaaaaaaaa")); + } +#if TEST_STD_VER >= 11 + { + typedef std::basic_string, min_allocator> S; + test(S(), 0, 'a', S()); + test(S(), 1, 'a', S(1, 'a')); + test(S(), 10, 'a', S(10, 'a')); + test(S(), 100, 'a', S(100, 'a')); + + test(S("12345"), 0, 'a', S("12345")); + test(S("12345"), 1, 'a', S("12345a")); + test(S("12345"), 10, 'a', S("12345aaaaaaaaaa")); + + test(S("12345678901234567890"), 0, 'a', S("12345678901234567890")); + test(S("12345678901234567890"), 1, 'a', S("12345678901234567890a")); + test(S("12345678901234567890"), 10, 'a', S("12345678901234567890aaaaaaaaaa")); + } +#endif +} diff --git a/tests/external/libcxx/basic_string/string.modifiers/string_append/string.pass.cpp b/tests/external/libcxx/basic_string/string.modifiers/string_append/string.pass.cpp new file mode 100644 index 0000000..b370426 --- /dev/null +++ b/tests/external/libcxx/basic_string/string.modifiers/string_append/string.pass.cpp @@ -0,0 +1,89 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// + +// basic_string& +// append(const basic_string& str); + +#include +#include + +#include "test_macros.h" +#include "min_allocator.h" + +template +void +test(S s, S str, S expected) +{ + s.append(str); + LIBCPP_ASSERT(s.__invariants()); + assert(s == expected); +} + +int main() +{ + { + typedef std::string S; + test(S(), S(), S()); + test(S(), S("12345"), S("12345")); + test(S(), S("1234567890"), S("1234567890")); + test(S(), S("12345678901234567890"), S("12345678901234567890")); + + test(S("12345"), S(), S("12345")); + test(S("12345"), S("12345"), S("1234512345")); + test(S("12345"), S("1234567890"), S("123451234567890")); + test(S("12345"), S("12345678901234567890"), S("1234512345678901234567890")); + + test(S("1234567890"), S(), S("1234567890")); + test(S("1234567890"), S("12345"), S("123456789012345")); + test(S("1234567890"), S("1234567890"), S("12345678901234567890")); + test(S("1234567890"), S("12345678901234567890"), S("123456789012345678901234567890")); + + test(S("12345678901234567890"), S(), S("12345678901234567890")); + test(S("12345678901234567890"), S("12345"), S("1234567890123456789012345")); + test(S("12345678901234567890"), S("1234567890"), S("123456789012345678901234567890")); + test(S("12345678901234567890"), S("12345678901234567890"), + S("1234567890123456789012345678901234567890")); + } +#if TEST_STD_VER >= 11 + { + typedef std::basic_string, min_allocator> S; + test(S(), S(), S()); + test(S(), S("12345"), S("12345")); + test(S(), S("1234567890"), S("1234567890")); + test(S(), S("12345678901234567890"), S("12345678901234567890")); + + test(S("12345"), S(), S("12345")); + test(S("12345"), S("12345"), S("1234512345")); + test(S("12345"), S("1234567890"), S("123451234567890")); + test(S("12345"), S("12345678901234567890"), S("1234512345678901234567890")); + + test(S("1234567890"), S(), S("1234567890")); + test(S("1234567890"), S("12345"), S("123456789012345")); + test(S("1234567890"), S("1234567890"), S("12345678901234567890")); + test(S("1234567890"), S("12345678901234567890"), S("123456789012345678901234567890")); + + test(S("12345678901234567890"), S(), S("12345678901234567890")); + test(S("12345678901234567890"), S("12345"), S("1234567890123456789012345")); + test(S("12345678901234567890"), S("1234567890"), S("123456789012345678901234567890")); + test(S("12345678901234567890"), S("12345678901234567890"), + S("1234567890123456789012345678901234567890")); + } +#endif + +#if TEST_STD_VER > 3 + { // LWG 2946 + std::string s; + s.append({"abc", 1}); + assert(s.size() == 1); + assert(s == "a"); + } +#endif +} diff --git a/tests/external/libcxx/basic_string/string.modifiers/string_append/string_size_size.pass.cpp b/tests/external/libcxx/basic_string/string.modifiers/string_append/string_size_size.pass.cpp new file mode 100644 index 0000000..588c15a --- /dev/null +++ b/tests/external/libcxx/basic_string/string.modifiers/string_append/string_size_size.pass.cpp @@ -0,0 +1,137 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// + +// basic_string& +// append(const basic_string& str, size_type pos, size_type n = npos); +// the "= npos" was added for C++14 + +#include +#include +#include + +#include "test_macros.h" +#include "min_allocator.h" + +template +void +test(S s, S str, typename S::size_type pos, typename S::size_type n, S expected) +{ + if (pos <= str.size()) + { + s.append(str, pos, n); + LIBCPP_ASSERT(s.__invariants()); + assert(s == expected); + } +#ifndef TEST_HAS_NO_EXCEPTIONS + else + { + try + { + s.append(str, pos, n); + assert(false); + } + catch (std::out_of_range&) + { + assert(pos > str.size()); + } + } +#endif +} + +template +void +test_npos(S s, S str, typename S::size_type pos, S expected) +{ + if (pos <= str.size()) + { + s.append(str, pos); + LIBCPP_ASSERT(s.__invariants()); + assert(s == expected); + } +#ifndef TEST_HAS_NO_EXCEPTIONS + else + { + try + { + s.append(str, pos); + assert(false); + } + catch (std::out_of_range&) + { + assert(pos > str.size()); + } + } +#endif +} + +int main() +{ + { + typedef std::string S; + test(S(), S(), 0, 0, S()); + test(S(), S(), 1, 0, S()); + test(S(), S("12345"), 0, 3, S("123")); + test(S(), S("12345"), 1, 4, S("2345")); + test(S(), S("12345"), 3, 15, S("45")); + test(S(), S("12345"), 5, 15, S("")); + test(S(), S("12345"), 6, 15, S("not happening")); + test(S(), S("12345678901234567890"), 0, 0, S()); + test(S(), S("12345678901234567890"), 1, 1, S("2")); + test(S(), S("12345678901234567890"), 2, 3, S("345")); + test(S(), S("12345678901234567890"), 12, 13, S("34567890")); + test(S(), S("12345678901234567890"), 21, 13, S("not happening")); + + test(S("12345"), S(), 0, 0, S("12345")); + test(S("12345"), S("12345"), 2, 2, S("1234534")); + test(S("12345"), S("1234567890"), 0, 100, S("123451234567890")); + + test(S("12345678901234567890"), S(), 0, 0, S("12345678901234567890")); + test(S("12345678901234567890"), S("12345"), 1, 3, S("12345678901234567890234")); + test(S("12345678901234567890"), S("12345678901234567890"), 5, 10, + S("123456789012345678906789012345")); + } +#if TEST_STD_VER >= 11 + { + typedef std::basic_string, min_allocator> S; + test(S(), S(), 0, 0, S()); + test(S(), S(), 1, 0, S()); + test(S(), S("12345"), 0, 3, S("123")); + test(S(), S("12345"), 1, 4, S("2345")); + test(S(), S("12345"), 3, 15, S("45")); + test(S(), S("12345"), 5, 15, S("")); + test(S(), S("12345"), 6, 15, S("not happening")); + test(S(), S("12345678901234567890"), 0, 0, S()); + test(S(), S("12345678901234567890"), 1, 1, S("2")); + test(S(), S("12345678901234567890"), 2, 3, S("345")); + test(S(), S("12345678901234567890"), 12, 13, S("34567890")); + test(S(), S("12345678901234567890"), 21, 13, S("not happening")); + + test(S("12345"), S(), 0, 0, S("12345")); + test(S("12345"), S("12345"), 2, 2, S("1234534")); + test(S("12345"), S("1234567890"), 0, 100, S("123451234567890")); + + test(S("12345678901234567890"), S(), 0, 0, S("12345678901234567890")); + test(S("12345678901234567890"), S("12345"), 1, 3, S("12345678901234567890234")); + test(S("12345678901234567890"), S("12345678901234567890"), 5, 10, + S("123456789012345678906789012345")); + } +#endif + { + typedef std::string S; + test_npos(S(), S(), 0, S()); + test_npos(S(), S(), 1, S()); + test_npos(S(), S("12345"), 0, S("12345")); + test_npos(S(), S("12345"), 1, S("2345")); + test_npos(S(), S("12345"), 3, S("45")); + test_npos(S(), S("12345"), 5, S("")); + test_npos(S(), S("12345"), 6, S("not happening")); + } +} diff --git a/tests/external/libcxx/basic_string/string.modifiers/string_append/string_view.pass.cpp b/tests/external/libcxx/basic_string/string.modifiers/string_append/string_view.pass.cpp new file mode 100644 index 0000000..2d85b15 --- /dev/null +++ b/tests/external/libcxx/basic_string/string.modifiers/string_append/string_view.pass.cpp @@ -0,0 +1,83 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// + +// basic_string& +// append(basic_string_view sv); + +#include +#include +#include + +#include "test_macros.h" +#include "min_allocator.h" + +template +void +test(S s, SV sv, S expected) +{ + s.append(sv); + LIBCPP_ASSERT(s.__invariants()); + assert(s == expected); +} + +int main() +{ + { + typedef std::string S; + typedef std::string_view SV; + test(S(), SV(), S()); + test(S(), SV("12345"), S("12345")); + test(S(), SV("1234567890"), S("1234567890")); + test(S(), SV("12345678901234567890"), S("12345678901234567890")); + + test(S("12345"), SV(), S("12345")); + test(S("12345"), SV("12345"), S("1234512345")); + test(S("12345"), SV("1234567890"), S("123451234567890")); + test(S("12345"), SV("12345678901234567890"), S("1234512345678901234567890")); + + test(S("1234567890"), SV(), S("1234567890")); + test(S("1234567890"), SV("12345"), S("123456789012345")); + test(S("1234567890"), SV("1234567890"), S("12345678901234567890")); + test(S("1234567890"), SV("12345678901234567890"), S("123456789012345678901234567890")); + + test(S("12345678901234567890"), SV(), S("12345678901234567890")); + test(S("12345678901234567890"), SV("12345"), S("1234567890123456789012345")); + test(S("12345678901234567890"), SV("1234567890"), S("123456789012345678901234567890")); + test(S("12345678901234567890"), SV("12345678901234567890"), + S("1234567890123456789012345678901234567890")); + } +#if TEST_STD_VER >= 11 + { + typedef std::basic_string , min_allocator> S; + typedef std::basic_string_view > SV; + test(S(), SV(), S()); + test(S(), SV("12345"), S("12345")); + test(S(), SV("1234567890"), S("1234567890")); + test(S(), SV("12345678901234567890"), S("12345678901234567890")); + + test(S("12345"), SV(), S("12345")); + test(S("12345"), SV("12345"), S("1234512345")); + test(S("12345"), SV("1234567890"), S("123451234567890")); + test(S("12345"), SV("12345678901234567890"), S("1234512345678901234567890")); + + test(S("1234567890"), SV(), S("1234567890")); + test(S("1234567890"), SV("12345"), S("123456789012345")); + test(S("1234567890"), SV("1234567890"), S("12345678901234567890")); + test(S("1234567890"), SV("12345678901234567890"), S("123456789012345678901234567890")); + + test(S("12345678901234567890"), SV(), S("12345678901234567890")); + test(S("12345678901234567890"), SV("12345"), S("1234567890123456789012345")); + test(S("12345678901234567890"), SV("1234567890"), S("123456789012345678901234567890")); + test(S("12345678901234567890"), SV("12345678901234567890"), + S("1234567890123456789012345678901234567890")); + } +#endif +} diff --git a/tests/external/libcxx/basic_string/string.modifiers/string_assign/T_size_size.pass.cpp b/tests/external/libcxx/basic_string/string.modifiers/string_assign/T_size_size.pass.cpp new file mode 100644 index 0000000..bf51d81 --- /dev/null +++ b/tests/external/libcxx/basic_string/string.modifiers/string_assign/T_size_size.pass.cpp @@ -0,0 +1,195 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// + +// template +// basic_string& assign(const T& t, size_type pos, size_type n=npos); // C++17 + +#include +#include +#include + +#include "test_macros.h" +#include "min_allocator.h" + +template +void +test(S s, SV sv, typename S::size_type pos, typename S::size_type n, S expected) +{ + if (pos <= sv.size()) + { + s.assign(sv, pos, n); + LIBCPP_ASSERT(s.__invariants()); + assert(s == expected); + } +#ifndef TEST_HAS_NO_EXCEPTIONS + else + { + try + { + s.assign(sv, pos, n); + assert(false); + } + catch (std::out_of_range&) + { + assert(pos > sv.size()); + } + } +#endif +} + +template +void +test_npos(S s, SV sv, typename S::size_type pos, S expected) +{ + if (pos <= sv.size()) + { + s.assign(sv, pos); + LIBCPP_ASSERT(s.__invariants()); + assert(s == expected); + } +#ifndef TEST_HAS_NO_EXCEPTIONS + else + { + try + { + s.assign(sv, pos); + assert(false); + } + catch (std::out_of_range&) + { + assert(pos > sv.size()); + } + } +#endif +} + +int main() +{ + { + typedef std::string S; + typedef std::string_view SV; + test(S(), SV(), 0, 0, S()); + test(S(), SV(), 1, 0, S()); + test(S(), SV("12345"), 0, 3, S("123")); + test(S(), SV("12345"), 1, 4, S("2345")); + test(S(), SV("12345"), 3, 15, S("45")); + test(S(), SV("12345"), 5, 15, S("")); + test(S(), SV("12345"), 6, 15, S("not happening")); + test(S(), SV("12345678901234567890"), 0, 0, S()); + test(S(), SV("12345678901234567890"), 1, 1, S("2")); + test(S(), SV("12345678901234567890"), 2, 3, S("345")); + test(S(), SV("12345678901234567890"), 12, 13, S("34567890")); + test(S(), SV("12345678901234567890"), 21, 13, S("not happening")); + + test(S("12345"), SV(), 0, 0, S()); + test(S("12345"), SV("12345"), 2, 2, S("34")); + test(S("12345"), SV("1234567890"), 0, 100, S("1234567890")); + + test(S("12345678901234567890"), SV(), 0, 0, S()); + test(S("12345678901234567890"), SV("12345"), 1, 3, S("234")); + test(S("12345678901234567890"), SV("12345678901234567890"), 5, 10, + S("6789012345")); + } +#if TEST_STD_VER >= 11 + { + typedef std::basic_string , min_allocator> S; + typedef std::basic_string_view > SV; + test(S(), SV(), 0, 0, S()); + test(S(), SV(), 1, 0, S()); + test(S(), SV("12345"), 0, 3, S("123")); + test(S(), SV("12345"), 1, 4, S("2345")); + test(S(), SV("12345"), 3, 15, S("45")); + test(S(), SV("12345"), 5, 15, S("")); + test(S(), SV("12345"), 6, 15, S("not happening")); + test(S(), SV("12345678901234567890"), 0, 0, S()); + test(S(), SV("12345678901234567890"), 1, 1, S("2")); + test(S(), SV("12345678901234567890"), 2, 3, S("345")); + test(S(), SV("12345678901234567890"), 12, 13, S("34567890")); + test(S(), SV("12345678901234567890"), 21, 13, S("not happening")); + + test(S("12345"), SV(), 0, 0, S()); + test(S("12345"), SV("12345"), 2, 2, S("34")); + test(S("12345"), SV("1234567890"), 0, 100, S("1234567890")); + + test(S("12345678901234567890"), SV(), 0, 0, S()); + test(S("12345678901234567890"), SV("12345"), 1, 3, S("234")); + test(S("12345678901234567890"), SV("12345678901234567890"), 5, 10, + S("6789012345")); + } +#endif + { + typedef std::string S; + typedef std::string_view SV; + test_npos(S(), SV(), 0, S()); + test_npos(S(), SV(), 1, S()); + test_npos(S(), SV("12345"), 0, S("12345")); + test_npos(S(), SV("12345"), 1, S("2345")); + test_npos(S(), SV("12345"), 3, S("45")); + test_npos(S(), SV("12345"), 5, S("")); + test_npos(S(), SV("12345"), 6, S("not happening")); + } + + { + std::string s = "ABCD"; + std::string_view sv = "EFGH"; + char arr[] = "IJKL"; + + s.assign("CDEF", 0); // calls assign(const char *, len) + assert(s == ""); + s.clear(); + + s.assign("QRST", 0, std::string::npos); // calls assign(string("QRST", pos, len) + assert(s == "QRST"); + s.clear(); + + s.assign(sv, 0); // calls assign(T, pos, npos) + assert(s == sv); + s.clear(); + + s.assign(sv, 0, std::string::npos); // calls assign(T, pos, npos) + assert(s == sv); + s.clear(); + + s.assign(arr, 0); // calls assign(const char *, len) + assert(s == ""); + s.clear(); + + s.assign(arr, 0, std::string::npos); // calls assign(string("IJKL"), pos, npos) + assert(s == "IJKL"); + s.clear(); + + s.assign(arr, 0); // calls assign(const char *, len) + assert(s == ""); + s.clear(); + } + + { + std::string s = "ABCD"; + std::string_view sv = s; + s.assign(sv); + assert(s == "ABCD"); + + sv = s; + s.assign(sv, 0, std::string::npos); + assert(s == "ABCD"); + } + + { + std::string s = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"; + std::string_view sv = s; + s.assign(sv); + assert(s == "ABCDEFGHIJKLMNOPQRSTUVWXYZ"); + + sv = s; + s.assign(sv, 0, std::string::npos); + assert(s == "ABCDEFGHIJKLMNOPQRSTUVWXYZ"); + } +} diff --git a/tests/external/libcxx/basic_string/string.modifiers/string_assign/initializer_list.pass.cpp b/tests/external/libcxx/basic_string/string.modifiers/string_assign/initializer_list.pass.cpp new file mode 100644 index 0000000..be1af17 --- /dev/null +++ b/tests/external/libcxx/basic_string/string.modifiers/string_assign/initializer_list.pass.cpp @@ -0,0 +1,60 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// Copyright 2019, Intel Corporation +// +// Modified to test pmem::obj containers +// + +#include "unittest.hpp" + +#include +#include + +namespace nvobj = pmem::obj; +namespace pmem_exp = pmem::obj::experimental; +using S = pmem_exp::string; + +struct root { + nvobj::persistent_ptr s; +}; + +int +main(int argc, char *argv[]) +{ + START(); + + if (argc < 2) { + std::cerr << "usage: " << argv[0] << " file-name" << std::endl; + return 1; + } + + auto path = argv[1]; + auto pop = nvobj::pool::create( + path, "string_test", PMEMOBJ_MIN_POOL, S_IWUSR | S_IRUSR); + + auto r = pop.root(); + + try { + nvobj::transaction::run( + pop, [&] { r->s = nvobj::make_persistent("123"); }); + + r->s->assign({'a', 'b', 'c'}); + UT_ASSERT(*r->s == "abc"); + + nvobj::transaction::run( + pop, [&] { nvobj::delete_persistent(r->s); }); + } catch (std::exception &e) { + UT_FATALexc(e); + } + + pop.close(); + + return 0; +} diff --git a/tests/external/libcxx/basic_string/string.modifiers/string_assign/iterator.pass.cpp b/tests/external/libcxx/basic_string/string.modifiers/string_assign/iterator.pass.cpp new file mode 100644 index 0000000..83303ce --- /dev/null +++ b/tests/external/libcxx/basic_string/string.modifiers/string_assign/iterator.pass.cpp @@ -0,0 +1,410 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// Copyright 2019, Intel Corporation +// +// Modified to test pmem::obj containers +// + +#include "unittest.hpp" + +#include + +namespace nvobj = pmem::obj; +namespace pmem_exp = pmem::obj::experimental; +using S = pmem_exp::string; + +template +struct ThrowingIterator { + typedef std::bidirectional_iterator_tag iterator_category; + typedef ptrdiff_t difference_type; + typedef const T value_type; + typedef const T *pointer; + typedef const T &reference; + + enum ThrowingAction { + TAIncrement, + TADecrement, + TADereference, + TAAssignment, + TAComparison + }; + + // Constructors + ThrowingIterator() + : begin_(nullptr), + end_(nullptr), + current_(nullptr), + action_(TADereference), + index_(0) + { + } + ThrowingIterator(const T *first, const T *last, size_t index = 0, + ThrowingAction action = TADereference) + : begin_(first), + end_(last), + current_(first), + action_(action), + index_(index) + { + } + ThrowingIterator(const ThrowingIterator &rhs) + : begin_(rhs.begin_), + end_(rhs.end_), + current_(rhs.current_), + action_(rhs.action_), + index_(rhs.index_) + { + } + ThrowingIterator & + operator=(const ThrowingIterator &rhs) + { + if (action_ == TAAssignment) { + if (index_ == 0) + throw std::runtime_error( + "throw from iterator assignment"); + else + --index_; + } + begin_ = rhs.begin_; + end_ = rhs.end_; + current_ = rhs.current_; + action_ = rhs.action_; + index_ = rhs.index_; + return *this; + } + + // iterator operations + reference operator*() const + { + if (action_ == TADereference) { + if (index_ == 0) + throw std::runtime_error( + "throw from iterator dereference"); + else + --index_; + } + return *current_; + } + + ThrowingIterator & + operator++() + { + if (action_ == TAIncrement) { + if (index_ == 0) + throw std::runtime_error( + "throw from iterator increment"); + else + --index_; + } + ++current_; + return *this; + } + + ThrowingIterator + operator++(int) + { + ThrowingIterator temp = *this; + ++(*this); + return temp; + } + + ThrowingIterator & + operator--() + { + if (action_ == TADecrement) { + if (index_ == 0) + throw std::runtime_error( + "throw from iterator decrement"); + else + --index_; + } + --current_; + return *this; + } + + ThrowingIterator + operator--(int) + { + ThrowingIterator temp = *this; + --(*this); + return temp; + } + + bool + operator==(const ThrowingIterator &rhs) const + { + if (action_ == TAComparison) { + if (index_ == 0) + throw std::runtime_error( + "throw from iterator comparison"); + else + --index_; + } + bool atEndL = current_ == end_; + bool atEndR = rhs.current_ == rhs.end_; + if (atEndL != atEndR) + return false; // one is at the end (or empty), the other + // is not. + if (atEndL) + return true; // both are at the end (or empty) + return current_ == rhs.current_; + } + + bool + operator!=(const ThrowingIterator &rhs) const + { + return !(*this == rhs); + } + +private: + const T *begin_; + const T *end_; + const T *current_; + ThrowingAction action_; + mutable size_t index_; +}; + +struct root { + nvobj::persistent_ptr s, s_short, s_long; + nvobj::persistent_ptr s_arr[8]; + nvobj::persistent_ptr aCopy; +}; + +template +void +test(nvobj::pool &pop, const S &s1, It first, It last, + const S &expected) +{ + auto r = pop.root(); + + nvobj::transaction::run(pop, + [&] { r->s = nvobj::make_persistent(s1); }); + + auto &s = *r->s; + + s.assign(first, last); + + UT_ASSERT(s == expected); + + nvobj::transaction::run(pop, + [&] { nvobj::delete_persistent(r->s); }); +} + +template +void +test_exceptions(nvobj::pool &pop, const S &s1, It first, It last) +{ + auto r = pop.root(); + + nvobj::transaction::run(pop, [&] { + r->s = nvobj::make_persistent(s1); + r->aCopy = nvobj::make_persistent(*r->s); + }); + + try { + r->s->assign(first, last); + UT_ASSERT(false); + } catch (std::runtime_error &) { + } catch (std::exception &e) { + UT_FATALexc(e); + } + + UT_ASSERT(*r->s == *r->aCopy); + + nvobj::transaction::run(pop, [&] { + nvobj::delete_persistent(r->s); + nvobj::delete_persistent(r->aCopy); + }); +} + +int +main(int argc, char *argv[]) +{ + START(); + + if (argc < 2) { + std::cerr << "usage: " << argv[0] << " file-name" << std::endl; + return 1; + } + + auto path = argv[1]; + auto pop = nvobj::pool::create( + path, "string_test", PMEMOBJ_MIN_POOL, S_IWUSR | S_IRUSR); + + auto r = pop.root(); + { + auto &s_arr = r->s_arr; + const char *s = + "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"; + try { + nvobj::transaction::run(pop, [&] { + s_arr[0] = nvobj::make_persistent(); + s_arr[1] = nvobj::make_persistent("A"); + s_arr[2] = + nvobj::make_persistent("ABCDEFGHIJ"); + s_arr[3] = nvobj::make_persistent( + "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"); + s_arr[4] = nvobj::make_persistent("12345"); + s_arr[5] = + nvobj::make_persistent("1234567890"); + s_arr[6] = nvobj::make_persistent( + "12345678901234567890"); + s_arr[7] = nvobj::make_persistent( + "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"); + }); + + test(pop, *s_arr[0], s, s, *s_arr[0]); + test(pop, *s_arr[0], s, s + 1, *s_arr[1]); + test(pop, *s_arr[0], s, s + 10, *s_arr[2]); + test(pop, *s_arr[0], s, s + 52, *s_arr[3]); + test(pop, *s_arr[0], s, s + 78, *s_arr[7]); + + test(pop, *s_arr[4], s, s, *s_arr[0]); + test(pop, *s_arr[4], s, s + 1, *s_arr[1]); + test(pop, *s_arr[4], s, s + 10, *s_arr[2]); + test(pop, *s_arr[4], s, s + 52, *s_arr[3]); + test(pop, *s_arr[4], s, s + 78, *s_arr[7]); + + test(pop, *s_arr[5], s, s, *s_arr[0]); + test(pop, *s_arr[5], s, s + 1, *s_arr[1]); + test(pop, *s_arr[5], s, s + 10, *s_arr[2]); + test(pop, *s_arr[5], s, s + 52, *s_arr[3]); + test(pop, *s_arr[5], s, s + 78, *s_arr[7]); + + test(pop, *s_arr[6], s, s, *s_arr[0]); + test(pop, *s_arr[6], s, s + 1, *s_arr[1]); + test(pop, *s_arr[6], s, s + 10, *s_arr[2]); + test(pop, *s_arr[6], s, s + 52, *s_arr[3]); + test(pop, *s_arr[6], s, s + 78, *s_arr[7]); + + using It = test_support::input_it; + + test(pop, *s_arr[0], It(s), It(s), *s_arr[0]); + test(pop, *s_arr[0], It(s), It(s + 1), *s_arr[1]); + test(pop, *s_arr[0], It(s), It(s + 10), *s_arr[2]); + test(pop, *s_arr[0], It(s), It(s + 52), *s_arr[3]); + test(pop, *s_arr[0], It(s), It(s + 78), *s_arr[7]); + + test(pop, *s_arr[4], It(s), It(s), *s_arr[0]); + test(pop, *s_arr[4], It(s), It(s + 1), *s_arr[1]); + test(pop, *s_arr[4], It(s), It(s + 10), *s_arr[2]); + test(pop, *s_arr[4], It(s), It(s + 52), *s_arr[3]); + test(pop, *s_arr[4], It(s), It(s + 78), *s_arr[7]); + + test(pop, *s_arr[5], It(s), It(s), *s_arr[0]); + test(pop, *s_arr[5], It(s), It(s + 1), *s_arr[1]); + test(pop, *s_arr[5], It(s), It(s + 10), *s_arr[2]); + test(pop, *s_arr[5], It(s), It(s + 52), *s_arr[3]); + test(pop, *s_arr[5], It(s), It(s + 78), *s_arr[7]); + + test(pop, *s_arr[6], It(s), It(s), *s_arr[0]); + test(pop, *s_arr[6], It(s), It(s + 1), *s_arr[1]); + test(pop, *s_arr[6], It(s), It(s + 10), *s_arr[2]); + test(pop, *s_arr[6], It(s), It(s + 52), *s_arr[3]); + test(pop, *s_arr[6], It(s), It(s + 78), *s_arr[7]); + + nvobj::transaction::run(pop, [&] { + for (unsigned i = 0; i < 8; ++i) { + nvobj::delete_persistent(s_arr[i]); + } + }); + } catch (std::exception &e) { + UT_FATALexc(e); + } + } + { // test assigning to self + try { + nvobj::transaction::run(pop, [&] { + r->s_short = nvobj::make_persistent("123/"); + r->s_long = nvobj::make_persistent( + "Lorem ipsum dolor sit amet, consectetur/"); + }); + + auto &s_short = *r->s_short; + auto &s_long = *r->s_long; + + s_short.assign(s_short.begin(), s_short.end()); + UT_ASSERT(s_short == "123/"); + s_short.assign(s_short.begin() + 2, s_short.end()); + UT_ASSERT(s_short == "3/"); + + s_long.assign(s_long.begin(), s_long.end()); + UT_ASSERT(s_long == + "Lorem ipsum dolor sit amet, consectetur/"); + + s_long.assign(s_long.begin() + 30, s_long.end()); + UT_ASSERT(s_long == "nsectetur/"); + + nvobj::transaction::run(pop, [&] { + nvobj::delete_persistent(r->s_short); + nvobj::delete_persistent(r->s_long); + }); + } catch (std::exception &e) { + UT_FATALexc(e); + } + } + { // test assigning a different type + const int8_t p[] = "ABCD"; + try { + nvobj::transaction::run(pop, [&] { + r->s = nvobj::make_persistent(); + }); + + auto &s = *r->s; + + s.assign(p, p + 4); + UT_ASSERT(s == "ABCD"); + + nvobj::transaction::run(pop, [&] { + nvobj::delete_persistent(r->s); + }); + } catch (std::exception &e) { + UT_FATALexc(e); + } + } + { + typedef ThrowingIterator TIter; + typedef test_support::forward_it IIter; + const char *s = + "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"; + + nvobj::transaction::run(pop, [&] { + r->s_arr[0] = nvobj::make_persistent(); + }); + + test_exceptions(pop, *r->s_arr[0], + IIter(TIter(s, s + 10, 4, TIter::TAIncrement)), + IIter()); + test_exceptions( + pop, *r->s_arr[0], + IIter(TIter(s, s + 10, 5, TIter::TADereference)), + IIter()); + test_exceptions(pop, *r->s_arr[0], + IIter(TIter(s, s + 10, 6, TIter::TAComparison)), + IIter()); + + test_exceptions(pop, *r->s_arr[0], + TIter(s, s + 10, 4, TIter::TAIncrement), + TIter()); + test_exceptions(pop, *r->s_arr[0], + TIter(s, s + 10, 5, TIter::TADereference), + TIter()); + test_exceptions(pop, *r->s_arr[0], + TIter(s, s + 10, 6, TIter::TAComparison), + TIter()); + + nvobj::transaction::run( + pop, [&] { nvobj::delete_persistent(r->s_arr[0]); }); + } + + pop.close(); + + return 0; +} diff --git a/tests/external/libcxx/basic_string/string.modifiers/string_assign/pointer.pass.cpp b/tests/external/libcxx/basic_string/string.modifiers/string_assign/pointer.pass.cpp new file mode 100644 index 0000000..fb52852 --- /dev/null +++ b/tests/external/libcxx/basic_string/string.modifiers/string_assign/pointer.pass.cpp @@ -0,0 +1,144 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// Copyright 2019, Intel Corporation +// +// Modified to test pmem::obj containers +// + +#include "unittest.hpp" + +#include + +namespace nvobj = pmem::obj; +namespace pmem_exp = pmem::obj::experimental; +using S = pmem_exp::string; + +struct root { + nvobj::persistent_ptr s, s_short, s_long; + nvobj::persistent_ptr s_arr[5]; +}; + +template +void +test(nvobj::pool &pop, const S &s1, + const typename S::value_type *str, const S &expected) +{ + auto r = pop.root(); + + nvobj::transaction::run(pop, + [&] { r->s = nvobj::make_persistent(s1); }); + + auto &s = *r->s; + + s.assign(str); + UT_ASSERT(s == expected); + + nvobj::transaction::run(pop, + [&] { nvobj::delete_persistent(r->s); }); +} + +int +main(int argc, char *argv[]) +{ + START(); + + if (argc < 2) { + std::cerr << "usage: " << argv[0] << " file-name" << std::endl; + return 1; + } + + auto path = argv[1]; + auto pop = nvobj::pool::create( + path, "string_test", PMEMOBJ_MIN_POOL, S_IWUSR | S_IRUSR); + + auto r = pop.root(); + { + auto &s_arr = r->s_arr; + try { + nvobj::transaction::run(pop, [&] { + s_arr[0] = nvobj::make_persistent(); + s_arr[1] = nvobj::make_persistent("12345"); + s_arr[2] = + nvobj::make_persistent("1234567890"); + s_arr[3] = nvobj::make_persistent( + "12345678901234567890"); + s_arr[4] = nvobj::make_persistent( + "1234567890123456789012345678901234567890123456789012345678901234567890"); + }); + + test(pop, *s_arr[0], "", *s_arr[0]); + test(pop, *s_arr[0], "12345", *s_arr[1]); + test(pop, *s_arr[0], "12345678901234567890", *s_arr[3]); + test(pop, *s_arr[0], + "1234567890123456789012345678901234567890123456789012345678901234567890", + *s_arr[4]); + + test(pop, *s_arr[1], "", *s_arr[0]); + test(pop, *s_arr[1], "12345", *s_arr[1]); + test(pop, *s_arr[1], "1234567890", *s_arr[2]); + test(pop, *s_arr[1], + "1234567890123456789012345678901234567890123456789012345678901234567890", + *s_arr[4]); + + test(pop, *s_arr[3], "", *s_arr[0]); + test(pop, *s_arr[3], "12345", *s_arr[1]); + test(pop, *s_arr[3], "12345678901234567890", *s_arr[3]); + test(pop, *s_arr[3], + "1234567890123456789012345678901234567890123456789012345678901234567890", + *s_arr[4]); + + test(pop, *s_arr[4], "", *s_arr[0]); + test(pop, *s_arr[4], "12345", *s_arr[1]); + test(pop, *s_arr[4], "12345678901234567890", *s_arr[3]); + test(pop, *s_arr[4], + "1234567890123456789012345678901234567890123456789012345678901234567890", + *s_arr[4]); + + nvobj::transaction::run(pop, [&] { + for (unsigned i = 0; i < 5; ++i) { + nvobj::delete_persistent(s_arr[i]); + } + }); + } catch (std::exception &e) { + UT_FATALexc(e); + } + } + { // test assignment to self + try { + nvobj::transaction::run(pop, [&] { + r->s_short = nvobj::make_persistent("123/"); + r->s_long = nvobj::make_persistent( + "Lorem ipsum dolor sit amet, consectetur/"); + }); + + auto &s_short = *r->s_short; + auto &s_long = *r->s_long; + + s_short.assign(s_short.c_str()); + UT_ASSERT(s_short == "123/"); + s_short.assign(s_short.c_str() + 2); + UT_ASSERT(s_short == "3/"); + + s_long.assign(s_long.c_str() + 30); + UT_ASSERT(s_long == "nsectetur/"); + + nvobj::transaction::run(pop, [&] { + nvobj::delete_persistent(r->s_short); + nvobj::delete_persistent(r->s_long); + }); + } catch (std::exception &e) { + UT_FATALexc(e); + } + } + + pop.close(); + + return 0; +} diff --git a/tests/external/libcxx/basic_string/string.modifiers/string_assign/pointer_size.pass.cpp b/tests/external/libcxx/basic_string/string.modifiers/string_assign/pointer_size.pass.cpp new file mode 100644 index 0000000..274eef0 --- /dev/null +++ b/tests/external/libcxx/basic_string/string.modifiers/string_assign/pointer_size.pass.cpp @@ -0,0 +1,153 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// Copyright 2019, Intel Corporation +// +// Modified to test pmem::obj containers +// + +#include "unittest.hpp" + +#include + +namespace nvobj = pmem::obj; +namespace pmem_exp = pmem::obj::experimental; +using S = pmem_exp::string; + +struct root { + nvobj::persistent_ptr s, s_short, s_long; + nvobj::persistent_ptr s_arr[8]; +}; + +template +void +test(nvobj::pool &pop, const S &s1, + const typename S::value_type *str, typename S::size_type n, + const S &expected) +{ + auto r = pop.root(); + + nvobj::transaction::run(pop, + [&] { r->s = nvobj::make_persistent(s1); }); + + auto &s = *r->s; + + s.assign(str, n); + UT_ASSERT(s == expected); + + nvobj::transaction::run(pop, + [&] { nvobj::delete_persistent(r->s); }); +} + +int +main(int argc, char *argv[]) +{ + START(); + + if (argc < 2) { + std::cerr << "usage: " << argv[0] << " file-name" << std::endl; + return 1; + } + + auto path = argv[1]; + auto pop = nvobj::pool::create( + path, "string_test", PMEMOBJ_MIN_POOL, S_IWUSR | S_IRUSR); + + auto r = pop.root(); + { + auto &s_arr = r->s_arr; + try { + nvobj::transaction::run(pop, [&] { + s_arr[0] = nvobj::make_persistent(); + s_arr[1] = nvobj::make_persistent("1"); + s_arr[2] = nvobj::make_persistent("123"); + s_arr[3] = nvobj::make_persistent("1234"); + s_arr[4] = nvobj::make_persistent("12345"); + s_arr[5] = + nvobj::make_persistent("1234567890"); + s_arr[6] = nvobj::make_persistent( + "12345678901234567890"); + s_arr[7] = nvobj::make_persistent( + "12345678901234567890123456789012345678901234567890123456789012345678901234567890"); + }); + + test(pop, *s_arr[0], "", 0, *s_arr[0]); + test(pop, *s_arr[0], "12345", 3, *s_arr[2]); + test(pop, *s_arr[0], "12345", 4, *s_arr[3]); + test(pop, *s_arr[0], "12345678901234567890", 0, + *s_arr[0]); + test(pop, *s_arr[0], "12345678901234567890", 1, + *s_arr[1]); + test(pop, *s_arr[0], "12345678901234567890", 3, + *s_arr[2]); + test(pop, *s_arr[0], "12345678901234567890", 20, + *s_arr[6]); + test(pop, *s_arr[0], + "12345678901234567890123456789012345678901234567890123456789012345678901234567890", + 80, *s_arr[7]); + + test(pop, *s_arr[4], "", 0, *s_arr[0]); + test(pop, *s_arr[4], "12345", 5, *s_arr[4]); + test(pop, *s_arr[4], "1234567890", 10, *s_arr[5]); + + test(pop, *s_arr[6], "", 0, *s_arr[0]); + test(pop, *s_arr[6], "12345", 5, *s_arr[4]); + test(pop, *s_arr[6], "12345678901234567890", 20, + *s_arr[6]); + + nvobj::transaction::run(pop, [&] { + for (unsigned i = 0; i < 8; ++i) { + nvobj::delete_persistent(s_arr[i]); + } + }); + } catch (std::exception &e) { + UT_FATALexc(e); + } + } + { + { // test assignment to self + try { + nvobj::transaction::run(pop, [&] { + r->s_short = nvobj::make_persistent( + "123/"); + r->s_long = nvobj::make_persistent( + "Lorem ipsum dolor sit amet, consectetur/"); + }); + + auto &s_short = *r->s_short; + auto &s_long = *r->s_long; + + s_short.assign(s_short.data(), s_short.size()); + UT_ASSERT(s_short == "123/"); + s_short.assign(s_short.data() + 2, + s_short.size() - 2); + UT_ASSERT(s_short == "3/"); + + s_long.assign(s_long.data(), s_long.size()); + UT_ASSERT( + s_long == + "Lorem ipsum dolor sit amet, consectetur/"); + + s_long.assign(s_long.data() + 2, 8); + UT_ASSERT(s_long == "rem ipsu"); + + nvobj::transaction::run(pop, [&] { + nvobj::delete_persistent(r->s_short); + nvobj::delete_persistent(r->s_long); + }); + } catch (std::exception &e) { + UT_FATALexc(e); + } + } + } + + pop.close(); + + return 0; +} diff --git a/tests/external/libcxx/basic_string/string.modifiers/string_assign/rv_string.pass.cpp b/tests/external/libcxx/basic_string/string.modifiers/string_assign/rv_string.pass.cpp new file mode 100644 index 0000000..dea61e0 --- /dev/null +++ b/tests/external/libcxx/basic_string/string.modifiers/string_assign/rv_string.pass.cpp @@ -0,0 +1,137 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// Copyright 2019, Intel Corporation +// +// Modified to test pmem::obj containers +// + +#include "unittest.hpp" + +#include + +namespace nvobj = pmem::obj; +namespace pmem_exp = pmem::obj::experimental; +using S = pmem_exp::string; + +struct root { + nvobj::persistent_ptr s, str; + nvobj::persistent_ptr s_arr[5]; +}; + +template +void +test(nvobj::pool &pop, const S &s1, const S &str1, + const S &expected) +{ + auto r = pop.root(); + + nvobj::transaction::run(pop, [&] { + r->s = nvobj::make_persistent(s1); + r->str = nvobj::make_persistent(str1); + }); + + auto &s = *r->s; + auto &str = *r->str; + + s.assign(std::move(str)); + UT_ASSERT(s == expected); + + nvobj::transaction::run(pop, [&] { + nvobj::delete_persistent(r->s); + nvobj::delete_persistent(r->str); + }); +} + +void +test_self_assignment(nvobj::pool &pop, const S &s1, + const S &expected) +{ + auto r = pop.root(); + + nvobj::transaction::run(pop, + [&] { r->s = nvobj::make_persistent(s1); }); + + auto &s = *r->s; + + s.assign(std::move(s)); + UT_ASSERT(s == expected); + + nvobj::transaction::run(pop, + [&] { nvobj::delete_persistent(r->s); }); +} + +int +main(int argc, char *argv[]) +{ + START(); + + if (argc < 2) { + std::cerr << "usage: " << argv[0] << " file-name" << std::endl; + return 1; + } + + auto path = argv[1]; + auto pop = nvobj::pool::create( + path, "string_test", PMEMOBJ_MIN_POOL, S_IWUSR | S_IRUSR); + + auto &s_arr = pop.root()->s_arr; + { + try { + nvobj::transaction::run(pop, [&] { + s_arr[0] = nvobj::make_persistent(); + s_arr[1] = nvobj::make_persistent("12345"); + s_arr[2] = + nvobj::make_persistent("1234567890"); + s_arr[3] = nvobj::make_persistent( + "12345678901234567890"); + s_arr[4] = nvobj::make_persistent( + "12345678901234567890123456789012345678901234567890123456789012345678901234567890"); + }); + + test(pop, *s_arr[0], *s_arr[0], *s_arr[0]); + test(pop, *s_arr[0], *s_arr[1], *s_arr[1]); + test(pop, *s_arr[0], *s_arr[2], *s_arr[2]); + test(pop, *s_arr[0], *s_arr[3], *s_arr[3]); + test(pop, *s_arr[0], *s_arr[4], *s_arr[4]); + + test(pop, *s_arr[1], *s_arr[0], *s_arr[0]); + test(pop, *s_arr[1], *s_arr[1], *s_arr[1]); + test(pop, *s_arr[1], *s_arr[2], *s_arr[2]); + test(pop, *s_arr[1], *s_arr[3], *s_arr[3]); + test(pop, *s_arr[1], *s_arr[4], *s_arr[4]); + + test(pop, *s_arr[2], *s_arr[0], *s_arr[0]); + test(pop, *s_arr[2], *s_arr[1], *s_arr[1]); + test(pop, *s_arr[2], *s_arr[2], *s_arr[2]); + test(pop, *s_arr[2], *s_arr[3], *s_arr[3]); + test(pop, *s_arr[2], *s_arr[4], *s_arr[4]); + + test(pop, *s_arr[3], *s_arr[0], *s_arr[0]); + test(pop, *s_arr[3], *s_arr[1], *s_arr[1]); + test(pop, *s_arr[3], *s_arr[2], *s_arr[2]); + test(pop, *s_arr[3], *s_arr[3], *s_arr[3]); + test(pop, *s_arr[3], *s_arr[4], *s_arr[4]); + + test_self_assignment(pop, *s_arr[3], *s_arr[3]); + + nvobj::transaction::run(pop, [&] { + for (unsigned i = 0; i < 5; ++i) { + nvobj::delete_persistent(s_arr[i]); + } + }); + } catch (std::exception &e) { + UT_FATALexc(e); + } + } + + pop.close(); + + return 0; +} diff --git a/tests/external/libcxx/basic_string/string.modifiers/string_assign/size_char.pass.cpp b/tests/external/libcxx/basic_string/string.modifiers/string_assign/size_char.pass.cpp new file mode 100644 index 0000000..b79c115 --- /dev/null +++ b/tests/external/libcxx/basic_string/string.modifiers/string_assign/size_char.pass.cpp @@ -0,0 +1,100 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// Copyright 2019, Intel Corporation +// +// Modified to test pmem::obj containers +// + +#include "unittest.hpp" + +#include + +namespace nvobj = pmem::obj; +namespace pmem_exp = pmem::obj::experimental; +using S = pmem_exp::string; + +struct root { + nvobj::persistent_ptr s; + nvobj::persistent_ptr s_arr[6]; +}; + +template +void +test(nvobj::pool &pop, const S &s1, typename S::size_type n, + typename S::value_type c, const S &expected) +{ + auto r = pop.root(); + + nvobj::transaction::run(pop, + [&] { r->s = nvobj::make_persistent(s1); }); + + auto &s = *r->s; + + s.assign(n, c); + UT_ASSERT(s == expected); + + nvobj::transaction::run(pop, + [&] { nvobj::delete_persistent(r->s); }); +} + +int +main(int argc, char *argv[]) +{ + START(); + + if (argc < 2) { + std::cerr << "usage: " << argv[0] << " file-name" << std::endl; + return 1; + } + + auto path = argv[1]; + auto pop = nvobj::pool::create( + path, "string_test", PMEMOBJ_MIN_POOL, S_IWUSR | S_IRUSR); + + auto &s_arr = pop.root()->s_arr; + { + try { + nvobj::transaction::run(pop, [&] { + s_arr[0] = nvobj::make_persistent(); + s_arr[1] = nvobj::make_persistent("12345"); + s_arr[2] = nvobj::make_persistent( + "12345678901234567890"); + s_arr[3] = nvobj::make_persistent(1U, 'a'); + s_arr[4] = nvobj::make_persistent(10U, 'a'); + s_arr[5] = nvobj::make_persistent(100U, 'a'); + }); + + test(pop, *s_arr[0], 0, 'a', *s_arr[0]); + test(pop, *s_arr[0], 1, 'a', *s_arr[3]); + test(pop, *s_arr[0], 10, 'a', *s_arr[4]); + test(pop, *s_arr[0], 100, 'a', *s_arr[5]); + + test(pop, *s_arr[1], 0, 'a', *s_arr[0]); + test(pop, *s_arr[1], 1, 'a', *s_arr[3]); + test(pop, *s_arr[1], 10, 'a', *s_arr[4]); + + test(pop, *s_arr[2], 0, 'a', *s_arr[0]); + test(pop, *s_arr[2], 1, 'a', *s_arr[3]); + test(pop, *s_arr[2], 10, 'a', *s_arr[4]); + + nvobj::transaction::run(pop, [&] { + for (unsigned i = 0; i < 6; ++i) { + nvobj::delete_persistent(s_arr[i]); + } + }); + } catch (std::exception &e) { + UT_FATALexc(e); + } + } + + pop.close(); + + return 0; +} diff --git a/tests/external/libcxx/basic_string/string.modifiers/string_assign/string.pass.cpp b/tests/external/libcxx/basic_string/string.modifiers/string_assign/string.pass.cpp new file mode 100644 index 0000000..2403a16 --- /dev/null +++ b/tests/external/libcxx/basic_string/string.modifiers/string_assign/string.pass.cpp @@ -0,0 +1,132 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// Copyright 2019, Intel Corporation +// +// Modified to test pmem::obj containers +// + +#include "unittest.hpp" + +#include + +namespace nvobj = pmem::obj; +namespace pmem_exp = pmem::obj::experimental; +using S = pmem_exp::string; + +struct root { + nvobj::persistent_ptr s; + nvobj::persistent_ptr s_arr[5]; +}; + +template +void +test(nvobj::pool &pop, const S &s1, const S &str, + const S &expected) +{ + auto r = pop.root(); + + nvobj::transaction::run(pop, + [&] { r->s = nvobj::make_persistent(s1); }); + + auto &s = *r->s; + + s.assign(str); + UT_ASSERT(s == expected); + + nvobj::transaction::run(pop, + [&] { nvobj::delete_persistent(r->s); }); +} + +void +test_self_assignment(nvobj::pool &pop, const S &s1, + const S &expected) +{ + auto r = pop.root(); + + nvobj::transaction::run(pop, + [&] { r->s = nvobj::make_persistent(s1); }); + + auto &s = *r->s; + + s.assign(s); + UT_ASSERT(s == expected); + + nvobj::transaction::run(pop, + [&] { nvobj::delete_persistent(r->s); }); +} + +int +main(int argc, char *argv[]) +{ + START(); + + if (argc < 2) { + std::cerr << "usage: " << argv[0] << " file-name" << std::endl; + return 1; + } + + auto path = argv[1]; + auto pop = nvobj::pool::create( + path, "string_test", PMEMOBJ_MIN_POOL, S_IWUSR | S_IRUSR); + + auto &s_arr = pop.root()->s_arr; + { + try { + nvobj::transaction::run(pop, [&] { + s_arr[0] = nvobj::make_persistent(); + s_arr[1] = nvobj::make_persistent("12345"); + s_arr[2] = + nvobj::make_persistent("1234567890"); + s_arr[3] = nvobj::make_persistent( + "12345678901234567890"); + s_arr[4] = nvobj::make_persistent( + "12345678901234567890123456789012345678901234567890123456789012345678901234567890"); + }); + + test(pop, *s_arr[0], *s_arr[0], *s_arr[0]); + test(pop, *s_arr[0], *s_arr[1], *s_arr[1]); + test(pop, *s_arr[0], *s_arr[2], *s_arr[2]); + test(pop, *s_arr[0], *s_arr[3], *s_arr[3]); + test(pop, *s_arr[0], *s_arr[4], *s_arr[4]); + + test(pop, *s_arr[1], *s_arr[0], *s_arr[0]); + test(pop, *s_arr[1], *s_arr[1], *s_arr[1]); + test(pop, *s_arr[1], *s_arr[2], *s_arr[2]); + test(pop, *s_arr[1], *s_arr[3], *s_arr[3]); + test(pop, *s_arr[1], *s_arr[4], *s_arr[4]); + + test(pop, *s_arr[2], *s_arr[0], *s_arr[0]); + test(pop, *s_arr[2], *s_arr[1], *s_arr[1]); + test(pop, *s_arr[2], *s_arr[2], *s_arr[2]); + test(pop, *s_arr[2], *s_arr[3], *s_arr[3]); + test(pop, *s_arr[2], *s_arr[4], *s_arr[4]); + + test(pop, *s_arr[3], *s_arr[0], *s_arr[0]); + test(pop, *s_arr[3], *s_arr[1], *s_arr[1]); + test(pop, *s_arr[3], *s_arr[2], *s_arr[2]); + test(pop, *s_arr[3], *s_arr[3], *s_arr[3]); + test(pop, *s_arr[3], *s_arr[4], *s_arr[4]); + + test_self_assignment(pop, *s_arr[3], *s_arr[3]); + + nvobj::transaction::run(pop, [&] { + for (unsigned i = 0; i < 5; ++i) { + nvobj::delete_persistent(s_arr[i]); + } + }); + } catch (std::exception &e) { + UT_FATALexc(e); + } + } + + pop.close(); + + return 0; +} diff --git a/tests/external/libcxx/basic_string/string.modifiers/string_assign/string_size_size.pass.cpp b/tests/external/libcxx/basic_string/string.modifiers/string_assign/string_size_size.pass.cpp new file mode 100644 index 0000000..a56f522 --- /dev/null +++ b/tests/external/libcxx/basic_string/string.modifiers/string_assign/string_size_size.pass.cpp @@ -0,0 +1,218 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// Copyright 2019, Intel Corporation +// +// Modified to test pmem::obj containers +// + +#include "unittest.hpp" + +#include + +namespace nvobj = pmem::obj; +namespace pmem_exp = pmem::obj::experimental; +using S = pmem_exp::string; + +struct root { + nvobj::persistent_ptr s; + nvobj::persistent_ptr s_arr[17]; +}; + +template +void +test(nvobj::pool &pop, const S &s1, const S &str, + typename S::size_type pos, typename S::size_type n, const S &expected) +{ + auto r = pop.root(); + + nvobj::transaction::run(pop, + [&] { r->s = nvobj::make_persistent(s1); }); + + auto &s = *r->s; + + if (pos <= str.size()) { + s.assign(str, pos, n); + UT_ASSERT(s == expected); + } else { + try { + s.assign(str, pos, n); + UT_ASSERT(false); + } catch (std::out_of_range &) { + UT_ASSERT(pos > str.size()); + } + } + + nvobj::transaction::run(pop, + [&] { nvobj::delete_persistent(r->s); }); +} + +template +void +test_npos(nvobj::pool &pop, const S &s1, const S &str, + typename S::size_type pos, const S &expected) +{ + auto r = pop.root(); + + nvobj::transaction::run(pop, + [&] { r->s = nvobj::make_persistent(s1); }); + + auto &s = *r->s; + + if (pos <= str.size()) { + s.assign(str, pos); + UT_ASSERT(s == expected); + } else { + try { + s.assign(str, pos); + UT_ASSERT(false); + } catch (std::out_of_range &) { + UT_ASSERT(pos > str.size()); + } + } + + nvobj::transaction::run(pop, + [&] { nvobj::delete_persistent(r->s); }); +} + +int +main(int argc, char *argv[]) +{ + START(); + + if (argc < 2) { + std::cerr << "usage: " << argv[0] << " file-name" << std::endl; + return 1; + } + + auto path = argv[1]; + auto pop = nvobj::pool::create( + path, "string_test", PMEMOBJ_MIN_POOL, S_IWUSR | S_IRUSR); + + auto &s_arr = pop.root()->s_arr; + { + try { + nvobj::transaction::run(pop, [&] { + s_arr[0] = nvobj::make_persistent(); + s_arr[1] = nvobj::make_persistent("123"); + s_arr[2] = nvobj::make_persistent("12345"); + s_arr[3] = nvobj::make_persistent("2345"); + s_arr[4] = nvobj::make_persistent("45"); + s_arr[5] = nvobj::make_persistent(""); + s_arr[6] = nvobj::make_persistent( + "not happening"); + s_arr[7] = nvobj::make_persistent( + "12345678901234567890"); + s_arr[8] = nvobj::make_persistent("2"); + s_arr[9] = nvobj::make_persistent("345"); + s_arr[10] = + nvobj::make_persistent("34567890"); + s_arr[11] = nvobj::make_persistent("34"); + s_arr[12] = + nvobj::make_persistent("1234567890"); + s_arr[13] = + nvobj::make_persistent("34567890"); + s_arr[14] = nvobj::make_persistent("234"); + s_arr[15] = + nvobj::make_persistent("6789012345"); + s_arr[16] = nvobj::make_persistent( + "12345678901234567890123456789012345678901234567890123456789012345678901234567890"); + }); + + test(pop, *s_arr[0], *s_arr[0], 0, 0, *s_arr[0]); + test(pop, *s_arr[0], *s_arr[0], 1, 0, *s_arr[0]); + test(pop, *s_arr[0], *s_arr[2], 0, 3, *s_arr[1]); + test(pop, *s_arr[0], *s_arr[2], 1, 4, *s_arr[3]); + test(pop, *s_arr[0], *s_arr[2], 3, 15, *s_arr[4]); + test(pop, *s_arr[0], *s_arr[2], 5, 15, *s_arr[5]); + test(pop, *s_arr[0], *s_arr[2], 6, 15, *s_arr[6]); + test(pop, *s_arr[0], *s_arr[7], 0, 0, *s_arr[0]); + test(pop, *s_arr[0], *s_arr[7], 1, 1, *s_arr[8]); + test(pop, *s_arr[0], *s_arr[7], 2, 3, *s_arr[9]); + test(pop, *s_arr[0], *s_arr[7], 12, 13, *s_arr[10]); + test(pop, *s_arr[0], *s_arr[7], 21, 13, *s_arr[6]); + test(pop, *s_arr[0], *s_arr[16], 10, 20, *s_arr[7]); + test(pop, *s_arr[0], *s_arr[16], 0, 80, *s_arr[16]); + + test(pop, *s_arr[2], *s_arr[0], 0, 0, *s_arr[0]); + test(pop, *s_arr[2], *s_arr[2], 2, 2, *s_arr[11]); + test(pop, *s_arr[2], *s_arr[12], 0, 100, *s_arr[12]); + + test(pop, *s_arr[7], *s_arr[0], 0, 0, *s_arr[0]); + test(pop, *s_arr[7], *s_arr[2], 1, 3, *s_arr[14]); + test(pop, *s_arr[7], *s_arr[7], 5, 10, *s_arr[15]); + + test(pop, *s_arr[16], *s_arr[0], 0, 0, *s_arr[0]); + test(pop, *s_arr[16], *s_arr[2], 1, 3, *s_arr[14]); + test(pop, *s_arr[16], *s_arr[7], 5, 10, *s_arr[15]); + + nvobj::transaction::run(pop, [&] { + for (unsigned i = 0; i < 17; ++i) { + nvobj::delete_persistent(s_arr[i]); + } + }); + } catch (std::exception &e) { + UT_FATALexc(e); + } + } + { + { + try { + nvobj::transaction::run(pop, [&] { + s_arr[0] = nvobj::make_persistent(); + s_arr[1] = nvobj::make_persistent( + "12345"); + s_arr[2] = nvobj::make_persistent( + "2345"); + s_arr[3] = + nvobj::make_persistent("45"); + s_arr[4] = + nvobj::make_persistent(""); + s_arr[5] = nvobj::make_persistent( + "not happening"); + s_arr[6] = nvobj::make_persistent( + "12345678901234567890123456789012345678901234567890123456789012345678901234567890"); + }); + + test_npos(pop, *s_arr[0], *s_arr[0], 0, + *s_arr[0]); + test_npos(pop, *s_arr[0], *s_arr[0], 1, + *s_arr[0]); + + test_npos(pop, *s_arr[0], *s_arr[1], 0, + *s_arr[1]); + test_npos(pop, *s_arr[0], *s_arr[1], 1, + *s_arr[2]); + test_npos(pop, *s_arr[0], *s_arr[1], 3, + *s_arr[3]); + test_npos(pop, *s_arr[0], *s_arr[1], 5, + *s_arr[4]); + test_npos(pop, *s_arr[0], *s_arr[1], 6, + *s_arr[5]); + test_npos(pop, *s_arr[0], *s_arr[6], 0, + *s_arr[6]); + test_npos(pop, *s_arr[6], *s_arr[1], 1, + *s_arr[2]); + + nvobj::transaction::run(pop, [&] { + for (unsigned i = 0; i < 7; ++i) { + nvobj::delete_persistent( + s_arr[i]); + } + }); + } catch (std::exception &e) { + UT_FATALexc(e); + } + } + } + + pop.close(); + + return 0; +} diff --git a/tests/external/libcxx/basic_string/string.modifiers/string_assign/string_view.pass.cpp b/tests/external/libcxx/basic_string/string.modifiers/string_assign/string_view.pass.cpp new file mode 100644 index 0000000..e56b094 --- /dev/null +++ b/tests/external/libcxx/basic_string/string.modifiers/string_assign/string_view.pass.cpp @@ -0,0 +1,105 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// + +// basic_string& +// assign(basic_string_view sv); + +#include +#include +#include + +#include "test_macros.h" +#include "min_allocator.h" +#include "test_allocator.h" + +template +void +test(S s, SV sv, S expected) +{ + s.assign(sv); + LIBCPP_ASSERT(s.__invariants()); + assert(s == expected); +} + +template +void +testAlloc(S s, SV sv, const typename S::allocator_type& a) +{ + s.assign(sv); + LIBCPP_ASSERT(s.__invariants()); + assert(s == sv); + assert(s.get_allocator() == a); +} + +int main() +{ + { + typedef std::string S; + typedef std::string_view SV; + test(S(), SV(), S()); + test(S(), SV("12345"), S("12345")); + test(S(), SV("1234567890"), S("1234567890")); + test(S(), SV("12345678901234567890"), S("12345678901234567890")); + + test(S("12345"), SV(), S()); + test(S("12345"), SV("12345"), S("12345")); + test(S("12345"), SV("1234567890"), S("1234567890")); + test(S("12345"), SV("12345678901234567890"), S("12345678901234567890")); + + test(S("1234567890"), SV(), S()); + test(S("1234567890"), SV("12345"), S("12345")); + test(S("1234567890"), SV("1234567890"), S("1234567890")); + test(S("1234567890"), SV("12345678901234567890"), S("12345678901234567890")); + + test(S("12345678901234567890"), SV(), S()); + test(S("12345678901234567890"), SV("12345"), S("12345")); + test(S("12345678901234567890"), SV("1234567890"), S("1234567890")); + test(S("12345678901234567890"), SV("12345678901234567890"), + S("12345678901234567890")); + + testAlloc(S(), SV(), std::allocator()); + testAlloc(S(), SV("12345"), std::allocator()); + testAlloc(S(), SV("1234567890"), std::allocator()); + testAlloc(S(), SV("12345678901234567890"), std::allocator()); + } + +#if TEST_STD_VER >= 11 + { + typedef std::basic_string , min_allocator> S; + typedef std::basic_string_view > SV; + test(S(), SV(), S()); + test(S(), SV("12345"), S("12345")); + test(S(), SV("1234567890"), S("1234567890")); + test(S(), SV("12345678901234567890"), S("12345678901234567890")); + + test(S("12345"), SV(), S()); + test(S("12345"), SV("12345"), S("12345")); + test(S("12345"), SV("1234567890"), S("1234567890")); + test(S("12345"), SV("12345678901234567890"), S("12345678901234567890")); + + test(S("1234567890"), SV(), S()); + test(S("1234567890"), SV("12345"), S("12345")); + test(S("1234567890"), SV("1234567890"), S("1234567890")); + test(S("1234567890"), SV("12345678901234567890"), S("12345678901234567890")); + + test(S("12345678901234567890"), SV(), S()); + test(S("12345678901234567890"), SV("12345"), S("12345")); + test(S("12345678901234567890"), SV("1234567890"), S("1234567890")); + test(S("12345678901234567890"), SV("12345678901234567890"), + S("12345678901234567890")); + + testAlloc(S(), SV(), min_allocator()); + testAlloc(S(), SV("12345"), min_allocator()); + testAlloc(S(), SV("1234567890"), min_allocator()); + testAlloc(S(), SV("12345678901234567890"), min_allocator()); + } +#endif +} diff --git a/tests/external/libcxx/basic_string/string.modifiers/string_copy/copy.pass.cpp b/tests/external/libcxx/basic_string/string.modifiers/string_copy/copy.pass.cpp new file mode 100644 index 0000000..664d204 --- /dev/null +++ b/tests/external/libcxx/basic_string/string.modifiers/string_copy/copy.pass.cpp @@ -0,0 +1,181 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// + +// size_type copy(charT* s, size_type n, size_type pos = 0) const; + +#include +#include +#include +#include + +#include "test_macros.h" +#include "min_allocator.h" + +template +void +test(S str, typename S::value_type* s, typename S::size_type n, + typename S::size_type pos) +{ + const S& cs = str; + if (pos <= cs.size()) + { + typename S::size_type r = cs.copy(s, n, pos); + typename S::size_type rlen = std::min(n, cs.size() - pos); + assert(r == rlen); + for (r = 0; r < rlen; ++r) + assert(S::traits_type::eq(cs[pos+r], s[r])); + } +#ifndef TEST_HAS_NO_EXCEPTIONS + else + { + try + { + typename S::size_type r = cs.copy(s, n, pos); + ((void)r); // Prevent unused warning + assert(false); + } + catch (std::out_of_range&) + { + assert(pos > str.size()); + } + } +#endif +} + +int main() +{ + { + typedef std::string S; + char s[50]; + test(S(""), s, 0, 0); + test(S(""), s, 0, 1); + test(S(""), s, 1, 0); + test(S("abcde"), s, 0, 0); + test(S("abcde"), s, 0, 1); + test(S("abcde"), s, 0, 2); + test(S("abcde"), s, 0, 4); + test(S("abcde"), s, 0, 5); + test(S("abcde"), s, 0, 6); + test(S("abcde"), s, 1, 0); + test(S("abcde"), s, 1, 1); + test(S("abcde"), s, 1, 2); + test(S("abcde"), s, 1, 4); + test(S("abcde"), s, 1, 5); + test(S("abcde"), s, 2, 0); + test(S("abcde"), s, 2, 1); + test(S("abcde"), s, 2, 2); + test(S("abcde"), s, 2, 4); + test(S("abcde"), s, 4, 0); + test(S("abcde"), s, 4, 1); + test(S("abcde"), s, 4, 2); + test(S("abcde"), s, 5, 0); + test(S("abcde"), s, 5, 1); + test(S("abcde"), s, 6, 0); + test(S("abcdefghijklmnopqrst"), s, 0, 0); + test(S("abcdefghijklmnopqrst"), s, 0, 1); + test(S("abcdefghijklmnopqrst"), s, 0, 2); + test(S("abcdefghijklmnopqrst"), s, 0, 10); + test(S("abcdefghijklmnopqrst"), s, 0, 19); + test(S("abcdefghijklmnopqrst"), s, 0, 20); + test(S("abcdefghijklmnopqrst"), s, 0, 21); + test(S("abcdefghijklmnopqrst"), s, 1, 0); + test(S("abcdefghijklmnopqrst"), s, 1, 1); + test(S("abcdefghijklmnopqrst"), s, 1, 2); + test(S("abcdefghijklmnopqrst"), s, 1, 9); + test(S("abcdefghijklmnopqrst"), s, 1, 18); + test(S("abcdefghijklmnopqrst"), s, 1, 19); + test(S("abcdefghijklmnopqrst"), s, 1, 20); + test(S("abcdefghijklmnopqrst"), s, 2, 0); + test(S("abcdefghijklmnopqrst"), s, 2, 1); + test(S("abcdefghijklmnopqrst"), s, 2, 2); + test(S("abcdefghijklmnopqrst"), s, 2, 9); + test(S("abcdefghijklmnopqrst"), s, 2, 17); + test(S("abcdefghijklmnopqrst"), s, 2, 18); + test(S("abcdefghijklmnopqrst"), s, 2, 19); + test(S("abcdefghijklmnopqrst"), s, 10, 0); + test(S("abcdefghijklmnopqrst"), s, 10, 1); + test(S("abcdefghijklmnopqrst"), s, 10, 2); + test(S("abcdefghijklmnopqrst"), s, 10, 5); + test(S("abcdefghijklmnopqrst"), s, 10, 9); + test(S("abcdefghijklmnopqrst"), s, 10, 10); + test(S("abcdefghijklmnopqrst"), s, 10, 11); + test(S("abcdefghijklmnopqrst"), s, 19, 0); + test(S("abcdefghijklmnopqrst"), s, 19, 1); + test(S("abcdefghijklmnopqrst"), s, 19, 2); + test(S("abcdefghijklmnopqrst"), s, 20, 0); + test(S("abcdefghijklmnopqrst"), s, 20, 1); + test(S("abcdefghijklmnopqrst"), s, 21, 0); + } +#if TEST_STD_VER >= 11 + { + typedef std::basic_string, min_allocator> S; + char s[50]; + test(S(""), s, 0, 0); + test(S(""), s, 0, 1); + test(S(""), s, 1, 0); + test(S("abcde"), s, 0, 0); + test(S("abcde"), s, 0, 1); + test(S("abcde"), s, 0, 2); + test(S("abcde"), s, 0, 4); + test(S("abcde"), s, 0, 5); + test(S("abcde"), s, 0, 6); + test(S("abcde"), s, 1, 0); + test(S("abcde"), s, 1, 1); + test(S("abcde"), s, 1, 2); + test(S("abcde"), s, 1, 4); + test(S("abcde"), s, 1, 5); + test(S("abcde"), s, 2, 0); + test(S("abcde"), s, 2, 1); + test(S("abcde"), s, 2, 2); + test(S("abcde"), s, 2, 4); + test(S("abcde"), s, 4, 0); + test(S("abcde"), s, 4, 1); + test(S("abcde"), s, 4, 2); + test(S("abcde"), s, 5, 0); + test(S("abcde"), s, 5, 1); + test(S("abcde"), s, 6, 0); + test(S("abcdefghijklmnopqrst"), s, 0, 0); + test(S("abcdefghijklmnopqrst"), s, 0, 1); + test(S("abcdefghijklmnopqrst"), s, 0, 2); + test(S("abcdefghijklmnopqrst"), s, 0, 10); + test(S("abcdefghijklmnopqrst"), s, 0, 19); + test(S("abcdefghijklmnopqrst"), s, 0, 20); + test(S("abcdefghijklmnopqrst"), s, 0, 21); + test(S("abcdefghijklmnopqrst"), s, 1, 0); + test(S("abcdefghijklmnopqrst"), s, 1, 1); + test(S("abcdefghijklmnopqrst"), s, 1, 2); + test(S("abcdefghijklmnopqrst"), s, 1, 9); + test(S("abcdefghijklmnopqrst"), s, 1, 18); + test(S("abcdefghijklmnopqrst"), s, 1, 19); + test(S("abcdefghijklmnopqrst"), s, 1, 20); + test(S("abcdefghijklmnopqrst"), s, 2, 0); + test(S("abcdefghijklmnopqrst"), s, 2, 1); + test(S("abcdefghijklmnopqrst"), s, 2, 2); + test(S("abcdefghijklmnopqrst"), s, 2, 9); + test(S("abcdefghijklmnopqrst"), s, 2, 17); + test(S("abcdefghijklmnopqrst"), s, 2, 18); + test(S("abcdefghijklmnopqrst"), s, 2, 19); + test(S("abcdefghijklmnopqrst"), s, 10, 0); + test(S("abcdefghijklmnopqrst"), s, 10, 1); + test(S("abcdefghijklmnopqrst"), s, 10, 2); + test(S("abcdefghijklmnopqrst"), s, 10, 5); + test(S("abcdefghijklmnopqrst"), s, 10, 9); + test(S("abcdefghijklmnopqrst"), s, 10, 10); + test(S("abcdefghijklmnopqrst"), s, 10, 11); + test(S("abcdefghijklmnopqrst"), s, 19, 0); + test(S("abcdefghijklmnopqrst"), s, 19, 1); + test(S("abcdefghijklmnopqrst"), s, 19, 2); + test(S("abcdefghijklmnopqrst"), s, 20, 0); + test(S("abcdefghijklmnopqrst"), s, 20, 1); + test(S("abcdefghijklmnopqrst"), s, 21, 0); + } +#endif +} diff --git a/tests/external/libcxx/basic_string/string.modifiers/string_erase/iter.pass.cpp b/tests/external/libcxx/basic_string/string.modifiers/string_erase/iter.pass.cpp new file mode 100644 index 0000000..31add9d --- /dev/null +++ b/tests/external/libcxx/basic_string/string.modifiers/string_erase/iter.pass.cpp @@ -0,0 +1,66 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// + +// iterator erase(const_iterator p); + +#include +#include + +#include "test_macros.h" +#include "min_allocator.h" + +template +void +test(S s, typename S::difference_type pos, S expected) +{ + typename S::const_iterator p = s.begin() + pos; + typename S::iterator i = s.erase(p); + LIBCPP_ASSERT(s.__invariants()); + assert(s[s.size()] == typename S::value_type()); + assert(s == expected); + assert(i - s.begin() == pos); +} + +int main() +{ + { + typedef std::string S; + test(S("abcde"), 0, S("bcde")); + test(S("abcde"), 1, S("acde")); + test(S("abcde"), 2, S("abde")); + test(S("abcde"), 4, S("abcd")); + test(S("abcdefghij"), 0, S("bcdefghij")); + test(S("abcdefghij"), 1, S("acdefghij")); + test(S("abcdefghij"), 5, S("abcdeghij")); + test(S("abcdefghij"), 9, S("abcdefghi")); + test(S("abcdefghijklmnopqrst"), 0, S("bcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, S("acdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 10, S("abcdefghijlmnopqrst")); + test(S("abcdefghijklmnopqrst"), 19, S("abcdefghijklmnopqrs")); + } +#if TEST_STD_VER >= 11 + { + typedef std::basic_string, min_allocator> S; + test(S("abcde"), 0, S("bcde")); + test(S("abcde"), 1, S("acde")); + test(S("abcde"), 2, S("abde")); + test(S("abcde"), 4, S("abcd")); + test(S("abcdefghij"), 0, S("bcdefghij")); + test(S("abcdefghij"), 1, S("acdefghij")); + test(S("abcdefghij"), 5, S("abcdeghij")); + test(S("abcdefghij"), 9, S("abcdefghi")); + test(S("abcdefghijklmnopqrst"), 0, S("bcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, S("acdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 10, S("abcdefghijlmnopqrst")); + test(S("abcdefghijklmnopqrst"), 19, S("abcdefghijklmnopqrs")); + } +#endif +} diff --git a/tests/external/libcxx/basic_string/string.modifiers/string_erase/iter_iter.pass.cpp b/tests/external/libcxx/basic_string/string.modifiers/string_erase/iter_iter.pass.cpp new file mode 100644 index 0000000..858d375 --- /dev/null +++ b/tests/external/libcxx/basic_string/string.modifiers/string_erase/iter_iter.pass.cpp @@ -0,0 +1,151 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// + +// iterator erase(const_iterator first, const_iterator last); + +#include +#include + +#include "test_macros.h" +#include "min_allocator.h" + +template +void +test(S s, typename S::difference_type pos, typename S::difference_type n, S expected) +{ + typename S::const_iterator first = s.cbegin() + pos; + typename S::const_iterator last = s.cbegin() + pos + n; + typename S::iterator i = s.erase(first, last); + LIBCPP_ASSERT(s.__invariants()); + assert(s[s.size()] == typename S::value_type()); + assert(s == expected); + assert(i - s.begin() == pos); +} + +int main() +{ + { + typedef std::string S; + test(S(""), 0, 0, S("")); + test(S("abcde"), 0, 0, S("abcde")); + test(S("abcde"), 0, 1, S("bcde")); + test(S("abcde"), 0, 2, S("cde")); + test(S("abcde"), 0, 4, S("e")); + test(S("abcde"), 0, 5, S("")); + test(S("abcde"), 1, 0, S("abcde")); + test(S("abcde"), 1, 1, S("acde")); + test(S("abcde"), 1, 2, S("ade")); + test(S("abcde"), 1, 3, S("ae")); + test(S("abcde"), 1, 4, S("a")); + test(S("abcde"), 2, 0, S("abcde")); + test(S("abcde"), 2, 1, S("abde")); + test(S("abcde"), 2, 2, S("abe")); + test(S("abcde"), 2, 3, S("ab")); + test(S("abcde"), 4, 0, S("abcde")); + test(S("abcde"), 4, 1, S("abcd")); + test(S("abcde"), 5, 0, S("abcde")); + test(S("abcdefghij"), 0, 0, S("abcdefghij")); + test(S("abcdefghij"), 0, 1, S("bcdefghij")); + test(S("abcdefghij"), 0, 5, S("fghij")); + test(S("abcdefghij"), 0, 9, S("j")); + test(S("abcdefghij"), 0, 10, S("")); + test(S("abcdefghij"), 1, 0, S("abcdefghij")); + test(S("abcdefghij"), 1, 1, S("acdefghij")); + test(S("abcdefghij"), 1, 4, S("afghij")); + test(S("abcdefghij"), 1, 8, S("aj")); + test(S("abcdefghij"), 1, 9, S("a")); + test(S("abcdefghij"), 5, 0, S("abcdefghij")); + test(S("abcdefghij"), 5, 1, S("abcdeghij")); + test(S("abcdefghij"), 5, 2, S("abcdehij")); + test(S("abcdefghij"), 5, 4, S("abcdej")); + test(S("abcdefghij"), 5, 5, S("abcde")); + test(S("abcdefghij"), 9, 0, S("abcdefghij")); + test(S("abcdefghij"), 9, 1, S("abcdefghi")); + test(S("abcdefghij"), 10, 0, S("abcdefghij")); + test(S("abcdefghijklmnopqrst"), 0, 0, S("abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, 1, S("bcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, 10, S("klmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, 19, S("t")); + test(S("abcdefghijklmnopqrst"), 0, 20, S("")); + test(S("abcdefghijklmnopqrst"), 1, 0, S("abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, 1, S("acdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, 9, S("aklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, 18, S("at")); + test(S("abcdefghijklmnopqrst"), 1, 19, S("a")); + test(S("abcdefghijklmnopqrst"), 10, 0, S("abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 10, 1, S("abcdefghijlmnopqrst")); + test(S("abcdefghijklmnopqrst"), 10, 5, S("abcdefghijpqrst")); + test(S("abcdefghijklmnopqrst"), 10, 9, S("abcdefghijt")); + test(S("abcdefghijklmnopqrst"), 10, 10, S("abcdefghij")); + test(S("abcdefghijklmnopqrst"), 19, 0, S("abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 19, 1, S("abcdefghijklmnopqrs")); + test(S("abcdefghijklmnopqrst"), 20, 0, S("abcdefghijklmnopqrst")); + } +#if TEST_STD_VER >= 11 + { + typedef std::basic_string, min_allocator> S; + test(S(""), 0, 0, S("")); + test(S("abcde"), 0, 0, S("abcde")); + test(S("abcde"), 0, 1, S("bcde")); + test(S("abcde"), 0, 2, S("cde")); + test(S("abcde"), 0, 4, S("e")); + test(S("abcde"), 0, 5, S("")); + test(S("abcde"), 1, 0, S("abcde")); + test(S("abcde"), 1, 1, S("acde")); + test(S("abcde"), 1, 2, S("ade")); + test(S("abcde"), 1, 3, S("ae")); + test(S("abcde"), 1, 4, S("a")); + test(S("abcde"), 2, 0, S("abcde")); + test(S("abcde"), 2, 1, S("abde")); + test(S("abcde"), 2, 2, S("abe")); + test(S("abcde"), 2, 3, S("ab")); + test(S("abcde"), 4, 0, S("abcde")); + test(S("abcde"), 4, 1, S("abcd")); + test(S("abcde"), 5, 0, S("abcde")); + test(S("abcdefghij"), 0, 0, S("abcdefghij")); + test(S("abcdefghij"), 0, 1, S("bcdefghij")); + test(S("abcdefghij"), 0, 5, S("fghij")); + test(S("abcdefghij"), 0, 9, S("j")); + test(S("abcdefghij"), 0, 10, S("")); + test(S("abcdefghij"), 1, 0, S("abcdefghij")); + test(S("abcdefghij"), 1, 1, S("acdefghij")); + test(S("abcdefghij"), 1, 4, S("afghij")); + test(S("abcdefghij"), 1, 8, S("aj")); + test(S("abcdefghij"), 1, 9, S("a")); + test(S("abcdefghij"), 5, 0, S("abcdefghij")); + test(S("abcdefghij"), 5, 1, S("abcdeghij")); + test(S("abcdefghij"), 5, 2, S("abcdehij")); + test(S("abcdefghij"), 5, 4, S("abcdej")); + test(S("abcdefghij"), 5, 5, S("abcde")); + test(S("abcdefghij"), 9, 0, S("abcdefghij")); + test(S("abcdefghij"), 9, 1, S("abcdefghi")); + test(S("abcdefghij"), 10, 0, S("abcdefghij")); + test(S("abcdefghijklmnopqrst"), 0, 0, S("abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, 1, S("bcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, 10, S("klmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, 19, S("t")); + test(S("abcdefghijklmnopqrst"), 0, 20, S("")); + test(S("abcdefghijklmnopqrst"), 1, 0, S("abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, 1, S("acdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, 9, S("aklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, 18, S("at")); + test(S("abcdefghijklmnopqrst"), 1, 19, S("a")); + test(S("abcdefghijklmnopqrst"), 10, 0, S("abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 10, 1, S("abcdefghijlmnopqrst")); + test(S("abcdefghijklmnopqrst"), 10, 5, S("abcdefghijpqrst")); + test(S("abcdefghijklmnopqrst"), 10, 9, S("abcdefghijt")); + test(S("abcdefghijklmnopqrst"), 10, 10, S("abcdefghij")); + test(S("abcdefghijklmnopqrst"), 19, 0, S("abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 19, 1, S("abcdefghijklmnopqrs")); + test(S("abcdefghijklmnopqrst"), 20, 0, S("abcdefghijklmnopqrst")); + } +#endif +} diff --git a/tests/external/libcxx/basic_string/string.modifiers/string_erase/pop_back.pass.cpp b/tests/external/libcxx/basic_string/string.modifiers/string_erase/pop_back.pass.cpp new file mode 100644 index 0000000..8424b54 --- /dev/null +++ b/tests/external/libcxx/basic_string/string.modifiers/string_erase/pop_back.pass.cpp @@ -0,0 +1,46 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// + +// void pop_back(); + +#include +#include + +#include "test_macros.h" +#include "min_allocator.h" + +template +void +test(S s, S expected) +{ + s.pop_back(); + LIBCPP_ASSERT(s.__invariants()); + assert(s[s.size()] == typename S::value_type()); + assert(s == expected); +} + +int main() +{ + { + typedef std::string S; + test(S("abcde"), S("abcd")); + test(S("abcdefghij"), S("abcdefghi")); + test(S("abcdefghijklmnopqrst"), S("abcdefghijklmnopqrs")); + } +#if TEST_STD_VER >= 11 + { + typedef std::basic_string, min_allocator> S; + test(S("abcde"), S("abcd")); + test(S("abcdefghij"), S("abcdefghi")); + test(S("abcdefghijklmnopqrst"), S("abcdefghijklmnopqrs")); + } +#endif +} diff --git a/tests/external/libcxx/basic_string/string.modifiers/string_erase/size_size.pass.cpp b/tests/external/libcxx/basic_string/string.modifiers/string_erase/size_size.pass.cpp new file mode 100644 index 0000000..2c900bb --- /dev/null +++ b/tests/external/libcxx/basic_string/string.modifiers/string_erase/size_size.pass.cpp @@ -0,0 +1,302 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// + +// basic_string& +// erase(size_type pos = 0, size_type n = npos); + +#include +#include +#include + +#include "test_macros.h" +#include "min_allocator.h" + +template +void +test(S s, typename S::size_type pos, typename S::size_type n, S expected) +{ + const typename S::size_type old_size = s.size(); + S s0 = s; + if (pos <= old_size) + { + s.erase(pos, n); + LIBCPP_ASSERT(s.__invariants()); + assert(s[s.size()] == typename S::value_type()); + assert(s == expected); + } +#ifndef TEST_HAS_NO_EXCEPTIONS + else + { + try + { + s.erase(pos, n); + assert(false); + } + catch (std::out_of_range&) + { + assert(pos > old_size); + assert(s == s0); + } + } +#endif +} + +template +void +test(S s, typename S::size_type pos, S expected) +{ + const typename S::size_type old_size = s.size(); + S s0 = s; + if (pos <= old_size) + { + s.erase(pos); + LIBCPP_ASSERT(s.__invariants()); + assert(s[s.size()] == typename S::value_type()); + assert(s == expected); + } +#ifndef TEST_HAS_NO_EXCEPTIONS + else + { + try + { + s.erase(pos); + assert(false); + } + catch (std::out_of_range&) + { + assert(pos > old_size); + assert(s == s0); + } + } +#endif +} + +template +void +test(S s, S expected) +{ + s.erase(); + LIBCPP_ASSERT(s.__invariants()); + assert(s[s.size()] == typename S::value_type()); + assert(s == expected); +} + +int main() +{ + { + typedef std::string S; + test(S(""), 0, 0, S("")); + test(S(""), 0, 1, S("")); + test(S(""), 1, 0, S("can't happen")); + test(S("abcde"), 0, 0, S("abcde")); + test(S("abcde"), 0, 1, S("bcde")); + test(S("abcde"), 0, 2, S("cde")); + test(S("abcde"), 0, 4, S("e")); + test(S("abcde"), 0, 5, S("")); + test(S("abcde"), 0, 6, S("")); + test(S("abcde"), 1, 0, S("abcde")); + test(S("abcde"), 1, 1, S("acde")); + test(S("abcde"), 1, 2, S("ade")); + test(S("abcde"), 1, 3, S("ae")); + test(S("abcde"), 1, 4, S("a")); + test(S("abcde"), 1, 5, S("a")); + test(S("abcde"), 2, 0, S("abcde")); + test(S("abcde"), 2, 1, S("abde")); + test(S("abcde"), 2, 2, S("abe")); + test(S("abcde"), 2, 3, S("ab")); + test(S("abcde"), 2, 4, S("ab")); + test(S("abcde"), 4, 0, S("abcde")); + test(S("abcde"), 4, 1, S("abcd")); + test(S("abcde"), 4, 2, S("abcd")); + test(S("abcde"), 5, 0, S("abcde")); + test(S("abcde"), 5, 1, S("abcde")); + test(S("abcde"), 6, 0, S("can't happen")); + test(S("abcdefghij"), 0, 0, S("abcdefghij")); + test(S("abcdefghij"), 0, 1, S("bcdefghij")); + test(S("abcdefghij"), 0, 5, S("fghij")); + test(S("abcdefghij"), 0, 9, S("j")); + test(S("abcdefghij"), 0, 10, S("")); + test(S("abcdefghij"), 0, 11, S("")); + test(S("abcdefghij"), 1, 0, S("abcdefghij")); + test(S("abcdefghij"), 1, 1, S("acdefghij")); + test(S("abcdefghij"), 1, 4, S("afghij")); + test(S("abcdefghij"), 1, 8, S("aj")); + test(S("abcdefghij"), 1, 9, S("a")); + test(S("abcdefghij"), 1, 10, S("a")); + test(S("abcdefghij"), 5, 0, S("abcdefghij")); + test(S("abcdefghij"), 5, 1, S("abcdeghij")); + test(S("abcdefghij"), 5, 2, S("abcdehij")); + test(S("abcdefghij"), 5, 4, S("abcdej")); + test(S("abcdefghij"), 5, 5, S("abcde")); + test(S("abcdefghij"), 5, 6, S("abcde")); + test(S("abcdefghij"), 9, 0, S("abcdefghij")); + test(S("abcdefghij"), 9, 1, S("abcdefghi")); + test(S("abcdefghij"), 9, 2, S("abcdefghi")); + test(S("abcdefghij"), 10, 0, S("abcdefghij")); + test(S("abcdefghij"), 10, 1, S("abcdefghij")); + test(S("abcdefghij"), 11, 0, S("can't happen")); + test(S("abcdefghijklmnopqrst"), 0, 0, S("abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, 1, S("bcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, 10, S("klmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, 19, S("t")); + test(S("abcdefghijklmnopqrst"), 0, 20, S("")); + test(S("abcdefghijklmnopqrst"), 0, 21, S("")); + test(S("abcdefghijklmnopqrst"), 1, 0, S("abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, 1, S("acdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, 9, S("aklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, 18, S("at")); + test(S("abcdefghijklmnopqrst"), 1, 19, S("a")); + test(S("abcdefghijklmnopqrst"), 1, 20, S("a")); + test(S("abcdefghijklmnopqrst"), 10, 0, S("abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 10, 1, S("abcdefghijlmnopqrst")); + test(S("abcdefghijklmnopqrst"), 10, 5, S("abcdefghijpqrst")); + test(S("abcdefghijklmnopqrst"), 10, 9, S("abcdefghijt")); + test(S("abcdefghijklmnopqrst"), 10, 10, S("abcdefghij")); + test(S("abcdefghijklmnopqrst"), 10, 11, S("abcdefghij")); + test(S("abcdefghijklmnopqrst"), 19, 0, S("abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 19, 1, S("abcdefghijklmnopqrs")); + test(S("abcdefghijklmnopqrst"), 19, 2, S("abcdefghijklmnopqrs")); + test(S("abcdefghijklmnopqrst"), 20, 0, S("abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 20, 1, S("abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 21, 0, S("can't happen")); + + test(S(""), 0, S("")); + test(S(""), 1, S("can't happen")); + test(S("abcde"), 0, S("")); + test(S("abcde"), 1, S("a")); + test(S("abcde"), 2, S("ab")); + test(S("abcde"), 4, S("abcd")); + test(S("abcde"), 5, S("abcde")); + test(S("abcde"), 6, S("can't happen")); + test(S("abcdefghij"), 0, S("")); + test(S("abcdefghij"), 1, S("a")); + test(S("abcdefghij"), 5, S("abcde")); + test(S("abcdefghij"), 9, S("abcdefghi")); + test(S("abcdefghij"), 10, S("abcdefghij")); + test(S("abcdefghij"), 11, S("can't happen")); + test(S("abcdefghijklmnopqrst"), 0, S("")); + test(S("abcdefghijklmnopqrst"), 1, S("a")); + test(S("abcdefghijklmnopqrst"), 10, S("abcdefghij")); + test(S("abcdefghijklmnopqrst"), 19, S("abcdefghijklmnopqrs")); + test(S("abcdefghijklmnopqrst"), 20, S("abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 21, S("can't happen")); + + test(S(""), S("")); + test(S("abcde"), S("")); + test(S("abcdefghij"), S("")); + test(S("abcdefghijklmnopqrst"), S("")); + } +#if TEST_STD_VER >= 11 + { + typedef std::basic_string, min_allocator> S; + test(S(""), 0, 0, S("")); + test(S(""), 0, 1, S("")); + test(S(""), 1, 0, S("can't happen")); + test(S("abcde"), 0, 0, S("abcde")); + test(S("abcde"), 0, 1, S("bcde")); + test(S("abcde"), 0, 2, S("cde")); + test(S("abcde"), 0, 4, S("e")); + test(S("abcde"), 0, 5, S("")); + test(S("abcde"), 0, 6, S("")); + test(S("abcde"), 1, 0, S("abcde")); + test(S("abcde"), 1, 1, S("acde")); + test(S("abcde"), 1, 2, S("ade")); + test(S("abcde"), 1, 3, S("ae")); + test(S("abcde"), 1, 4, S("a")); + test(S("abcde"), 1, 5, S("a")); + test(S("abcde"), 2, 0, S("abcde")); + test(S("abcde"), 2, 1, S("abde")); + test(S("abcde"), 2, 2, S("abe")); + test(S("abcde"), 2, 3, S("ab")); + test(S("abcde"), 2, 4, S("ab")); + test(S("abcde"), 4, 0, S("abcde")); + test(S("abcde"), 4, 1, S("abcd")); + test(S("abcde"), 4, 2, S("abcd")); + test(S("abcde"), 5, 0, S("abcde")); + test(S("abcde"), 5, 1, S("abcde")); + test(S("abcde"), 6, 0, S("can't happen")); + test(S("abcdefghij"), 0, 0, S("abcdefghij")); + test(S("abcdefghij"), 0, 1, S("bcdefghij")); + test(S("abcdefghij"), 0, 5, S("fghij")); + test(S("abcdefghij"), 0, 9, S("j")); + test(S("abcdefghij"), 0, 10, S("")); + test(S("abcdefghij"), 0, 11, S("")); + test(S("abcdefghij"), 1, 0, S("abcdefghij")); + test(S("abcdefghij"), 1, 1, S("acdefghij")); + test(S("abcdefghij"), 1, 4, S("afghij")); + test(S("abcdefghij"), 1, 8, S("aj")); + test(S("abcdefghij"), 1, 9, S("a")); + test(S("abcdefghij"), 1, 10, S("a")); + test(S("abcdefghij"), 5, 0, S("abcdefghij")); + test(S("abcdefghij"), 5, 1, S("abcdeghij")); + test(S("abcdefghij"), 5, 2, S("abcdehij")); + test(S("abcdefghij"), 5, 4, S("abcdej")); + test(S("abcdefghij"), 5, 5, S("abcde")); + test(S("abcdefghij"), 5, 6, S("abcde")); + test(S("abcdefghij"), 9, 0, S("abcdefghij")); + test(S("abcdefghij"), 9, 1, S("abcdefghi")); + test(S("abcdefghij"), 9, 2, S("abcdefghi")); + test(S("abcdefghij"), 10, 0, S("abcdefghij")); + test(S("abcdefghij"), 10, 1, S("abcdefghij")); + test(S("abcdefghij"), 11, 0, S("can't happen")); + test(S("abcdefghijklmnopqrst"), 0, 0, S("abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, 1, S("bcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, 10, S("klmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, 19, S("t")); + test(S("abcdefghijklmnopqrst"), 0, 20, S("")); + test(S("abcdefghijklmnopqrst"), 0, 21, S("")); + test(S("abcdefghijklmnopqrst"), 1, 0, S("abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, 1, S("acdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, 9, S("aklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, 18, S("at")); + test(S("abcdefghijklmnopqrst"), 1, 19, S("a")); + test(S("abcdefghijklmnopqrst"), 1, 20, S("a")); + test(S("abcdefghijklmnopqrst"), 10, 0, S("abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 10, 1, S("abcdefghijlmnopqrst")); + test(S("abcdefghijklmnopqrst"), 10, 5, S("abcdefghijpqrst")); + test(S("abcdefghijklmnopqrst"), 10, 9, S("abcdefghijt")); + test(S("abcdefghijklmnopqrst"), 10, 10, S("abcdefghij")); + test(S("abcdefghijklmnopqrst"), 10, 11, S("abcdefghij")); + test(S("abcdefghijklmnopqrst"), 19, 0, S("abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 19, 1, S("abcdefghijklmnopqrs")); + test(S("abcdefghijklmnopqrst"), 19, 2, S("abcdefghijklmnopqrs")); + test(S("abcdefghijklmnopqrst"), 20, 0, S("abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 20, 1, S("abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 21, 0, S("can't happen")); + + test(S(""), 0, S("")); + test(S(""), 1, S("can't happen")); + test(S("abcde"), 0, S("")); + test(S("abcde"), 1, S("a")); + test(S("abcde"), 2, S("ab")); + test(S("abcde"), 4, S("abcd")); + test(S("abcde"), 5, S("abcde")); + test(S("abcde"), 6, S("can't happen")); + test(S("abcdefghij"), 0, S("")); + test(S("abcdefghij"), 1, S("a")); + test(S("abcdefghij"), 5, S("abcde")); + test(S("abcdefghij"), 9, S("abcdefghi")); + test(S("abcdefghij"), 10, S("abcdefghij")); + test(S("abcdefghij"), 11, S("can't happen")); + test(S("abcdefghijklmnopqrst"), 0, S("")); + test(S("abcdefghijklmnopqrst"), 1, S("a")); + test(S("abcdefghijklmnopqrst"), 10, S("abcdefghij")); + test(S("abcdefghijklmnopqrst"), 19, S("abcdefghijklmnopqrs")); + test(S("abcdefghijklmnopqrst"), 20, S("abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 21, S("can't happen")); + + test(S(""), S("")); + test(S("abcde"), S("")); + test(S("abcdefghij"), S("")); + test(S("abcdefghijklmnopqrst"), S("")); + } +#endif +} diff --git a/tests/external/libcxx/basic_string/string.modifiers/string_insert/iter_char.pass.cpp b/tests/external/libcxx/basic_string/string.modifiers/string_insert/iter_char.pass.cpp new file mode 100644 index 0000000..6bd9b7e --- /dev/null +++ b/tests/external/libcxx/basic_string/string.modifiers/string_insert/iter_char.pass.cpp @@ -0,0 +1,76 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// + +// iterator insert(const_iterator p, charT c); + +#include +#include +#include + +#include "test_macros.h" +#include "min_allocator.h" + +template +void +test(S& s, typename S::const_iterator p, typename S::value_type c, S expected) +{ + bool sufficient_cap = s.size() < s.capacity(); + typename S::difference_type pos = p - s.begin(); + typename S::iterator i = s.insert(p, c); + LIBCPP_ASSERT(s.__invariants()); + assert(s == expected); + assert(i - s.begin() == pos); + assert(*i == c); + if (sufficient_cap) + assert(i == p); +} + +int main() +{ + { + typedef std::string S; + S s; + test(s, s.begin(), '1', S("1")); + test(s, s.begin(), 'a', S("a1")); + test(s, s.end(), 'b', S("a1b")); + test(s, s.end()-1, 'c', S("a1cb")); + test(s, s.end()-2, 'd', S("a1dcb")); + test(s, s.end()-3, '2', S("a12dcb")); + test(s, s.end()-4, '3', S("a132dcb")); + test(s, s.end()-5, '4', S("a1432dcb")); + test(s, s.begin()+1, '5', S("a51432dcb")); + test(s, s.begin()+2, '6', S("a561432dcb")); + test(s, s.begin()+3, '7', S("a5671432dcb")); + test(s, s.begin()+4, 'A', S("a567A1432dcb")); + test(s, s.begin()+5, 'B', S("a567AB1432dcb")); + test(s, s.begin()+6, 'C', S("a567ABC1432dcb")); + } +#if TEST_STD_VER >= 11 + { + typedef std::basic_string, min_allocator> S; + S s; + test(s, s.begin(), '1', S("1")); + test(s, s.begin(), 'a', S("a1")); + test(s, s.end(), 'b', S("a1b")); + test(s, s.end()-1, 'c', S("a1cb")); + test(s, s.end()-2, 'd', S("a1dcb")); + test(s, s.end()-3, '2', S("a12dcb")); + test(s, s.end()-4, '3', S("a132dcb")); + test(s, s.end()-5, '4', S("a1432dcb")); + test(s, s.begin()+1, '5', S("a51432dcb")); + test(s, s.begin()+2, '6', S("a561432dcb")); + test(s, s.begin()+3, '7', S("a5671432dcb")); + test(s, s.begin()+4, 'A', S("a567A1432dcb")); + test(s, s.begin()+5, 'B', S("a567AB1432dcb")); + test(s, s.begin()+6, 'C', S("a567ABC1432dcb")); + } +#endif +} diff --git a/tests/external/libcxx/basic_string/string.modifiers/string_insert/iter_initializer_list.pass.cpp b/tests/external/libcxx/basic_string/string.modifiers/string_insert/iter_initializer_list.pass.cpp new file mode 100644 index 0000000..c5b7cbf --- /dev/null +++ b/tests/external/libcxx/basic_string/string.modifiers/string_insert/iter_initializer_list.pass.cpp @@ -0,0 +1,37 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// UNSUPPORTED: c++98, c++03 + +// + +// iterator insert(const_iterator p, initializer_list il); + + +#include +#include + +#include "min_allocator.h" + +int main() +{ + { + std::string s("123456"); + std::string::iterator i = s.insert(s.begin() + 3, {'a', 'b', 'c'}); + assert(i - s.begin() == 3); + assert(s == "123abc456"); + } + { + typedef std::basic_string, min_allocator> S; + S s("123456"); + S::iterator i = s.insert(s.begin() + 3, {'a', 'b', 'c'}); + assert(i - s.begin() == 3); + assert(s == "123abc456"); + } +} diff --git a/tests/external/libcxx/basic_string/string.modifiers/string_insert/iter_iter_iter.pass.cpp b/tests/external/libcxx/basic_string/string.modifiers/string_insert/iter_iter_iter.pass.cpp new file mode 100644 index 0000000..cb4b40f --- /dev/null +++ b/tests/external/libcxx/basic_string/string.modifiers/string_insert/iter_iter_iter.pass.cpp @@ -0,0 +1,222 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// + +// template +// iterator insert(const_iterator p, InputIterator first, InputIterator last); + +#if _LIBCPP_DEBUG >= 1 +#define _LIBCPP_ASSERT(x, m) ((x) ? (void)0 : std::exit(0)) +#endif + +#include +#include + +#include "test_iterators.h" +#include "min_allocator.h" + +template +void +test(S s, typename S::difference_type pos, It first, It last, S expected) +{ + typename S::const_iterator p = s.cbegin() + pos; + typename S::iterator i = s.insert(p, first, last); + LIBCPP_ASSERT(s.__invariants()); + assert(i - s.begin() == pos); + assert(s == expected); +} + +#ifndef TEST_HAS_NO_EXCEPTIONS +template +void +test_exceptions(S s, typename S::difference_type pos, It first, It last) +{ + typename S::const_iterator p = s.cbegin() + pos; + S aCopy = s; + try { + s.insert(p, first, last); + assert(false); + } + catch (...) {} + LIBCPP_ASSERT(s.__invariants()); + assert(s == aCopy); +} +#endif + +int main() +{ + { + typedef std::string S; + const char* s = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"; + test(S(), 0, s, s, S()); + test(S(), 0, s, s+1, S("A")); + test(S(), 0, s, s+10, S("ABCDEFGHIJ")); + test(S(), 0, s, s+52, S("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz")); + + test(S("12345"), 0, s, s, S("12345")); + test(S("12345"), 1, s, s+1, S("1A2345")); + test(S("12345"), 4, s, s+10, S("1234ABCDEFGHIJ5")); + test(S("12345"), 5, s, s+52, S("12345ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz")); + + test(S("1234567890"), 0, s, s, S("1234567890")); + test(S("1234567890"), 1, s, s+1, S("1A234567890")); + test(S("1234567890"), 10, s, s+10, S("1234567890ABCDEFGHIJ")); + test(S("1234567890"), 8, s, s+52, S("12345678ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz90")); + + test(S("12345678901234567890"), 3, s, s, S("12345678901234567890")); + test(S("12345678901234567890"), 3, s, s+1, S("123A45678901234567890")); + test(S("12345678901234567890"), 15, s, s+10, S("123456789012345ABCDEFGHIJ67890")); + test(S("12345678901234567890"), 20, s, s+52, + S("12345678901234567890ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz")); + + test(S(), 0, input_iterator(s), input_iterator(s), S()); + test(S(), 0, input_iterator(s), input_iterator(s+1), S("A")); + test(S(), 0, input_iterator(s), input_iterator(s+10), S("ABCDEFGHIJ")); + test(S(), 0, input_iterator(s), input_iterator(s+52), S("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz")); + + test(S("12345"), 0, input_iterator(s), input_iterator(s), S("12345")); + test(S("12345"), 1, input_iterator(s), input_iterator(s+1), S("1A2345")); + test(S("12345"), 4, input_iterator(s), input_iterator(s+10), S("1234ABCDEFGHIJ5")); + test(S("12345"), 5, input_iterator(s), input_iterator(s+52), S("12345ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz")); + + test(S("1234567890"), 0, input_iterator(s), input_iterator(s), S("1234567890")); + test(S("1234567890"), 1, input_iterator(s), input_iterator(s+1), S("1A234567890")); + test(S("1234567890"), 10, input_iterator(s), input_iterator(s+10), S("1234567890ABCDEFGHIJ")); + test(S("1234567890"), 8, input_iterator(s), input_iterator(s+52), S("12345678ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz90")); + + test(S("12345678901234567890"), 3, input_iterator(s), input_iterator(s), S("12345678901234567890")); + test(S("12345678901234567890"), 3, input_iterator(s), input_iterator(s+1), S("123A45678901234567890")); + test(S("12345678901234567890"), 15, input_iterator(s), input_iterator(s+10), S("123456789012345ABCDEFGHIJ67890")); + test(S("12345678901234567890"), 20, input_iterator(s), input_iterator(s+52), + S("12345678901234567890ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz")); + } +#if TEST_STD_VER >= 11 + { + typedef std::basic_string, min_allocator> S; + const char* s = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"; + test(S(), 0, s, s, S()); + test(S(), 0, s, s+1, S("A")); + test(S(), 0, s, s+10, S("ABCDEFGHIJ")); + test(S(), 0, s, s+52, S("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz")); + + test(S("12345"), 0, s, s, S("12345")); + test(S("12345"), 1, s, s+1, S("1A2345")); + test(S("12345"), 4, s, s+10, S("1234ABCDEFGHIJ5")); + test(S("12345"), 5, s, s+52, S("12345ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz")); + + test(S("1234567890"), 0, s, s, S("1234567890")); + test(S("1234567890"), 1, s, s+1, S("1A234567890")); + test(S("1234567890"), 10, s, s+10, S("1234567890ABCDEFGHIJ")); + test(S("1234567890"), 8, s, s+52, S("12345678ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz90")); + + test(S("12345678901234567890"), 3, s, s, S("12345678901234567890")); + test(S("12345678901234567890"), 3, s, s+1, S("123A45678901234567890")); + test(S("12345678901234567890"), 15, s, s+10, S("123456789012345ABCDEFGHIJ67890")); + test(S("12345678901234567890"), 20, s, s+52, + S("12345678901234567890ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz")); + + test(S(), 0, input_iterator(s), input_iterator(s), S()); + test(S(), 0, input_iterator(s), input_iterator(s+1), S("A")); + test(S(), 0, input_iterator(s), input_iterator(s+10), S("ABCDEFGHIJ")); + test(S(), 0, input_iterator(s), input_iterator(s+52), S("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz")); + + test(S("12345"), 0, input_iterator(s), input_iterator(s), S("12345")); + test(S("12345"), 1, input_iterator(s), input_iterator(s+1), S("1A2345")); + test(S("12345"), 4, input_iterator(s), input_iterator(s+10), S("1234ABCDEFGHIJ5")); + test(S("12345"), 5, input_iterator(s), input_iterator(s+52), S("12345ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz")); + + test(S("1234567890"), 0, input_iterator(s), input_iterator(s), S("1234567890")); + test(S("1234567890"), 1, input_iterator(s), input_iterator(s+1), S("1A234567890")); + test(S("1234567890"), 10, input_iterator(s), input_iterator(s+10), S("1234567890ABCDEFGHIJ")); + test(S("1234567890"), 8, input_iterator(s), input_iterator(s+52), S("12345678ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz90")); + + test(S("12345678901234567890"), 3, input_iterator(s), input_iterator(s), S("12345678901234567890")); + test(S("12345678901234567890"), 3, input_iterator(s), input_iterator(s+1), S("123A45678901234567890")); + test(S("12345678901234567890"), 15, input_iterator(s), input_iterator(s+10), S("123456789012345ABCDEFGHIJ67890")); + test(S("12345678901234567890"), 20, input_iterator(s), input_iterator(s+52), + S("12345678901234567890ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz")); + } +#endif +#ifndef TEST_HAS_NO_EXCEPTIONS + { // test iterator operations that throw + typedef std::string S; + typedef ThrowingIterator TIter; + typedef input_iterator IIter; + const char* s = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"; + test_exceptions(S(), 0, IIter(TIter(s, s+10, 4, TIter::TAIncrement)), IIter()); + test_exceptions(S(), 0, IIter(TIter(s, s+10, 5, TIter::TADereference)), IIter()); + test_exceptions(S(), 0, IIter(TIter(s, s+10, 6, TIter::TAComparison)), IIter()); + + test_exceptions(S(), 0, TIter(s, s+10, 4, TIter::TAIncrement), TIter()); + test_exceptions(S(), 0, TIter(s, s+10, 5, TIter::TADereference), TIter()); + test_exceptions(S(), 0, TIter(s, s+10, 6, TIter::TAComparison), TIter()); + } +#endif +#if _LIBCPP_DEBUG >= 1 + { + std::string v; + std::string v2; + char a[] = "123"; + const int N = sizeof(a)/sizeof(a[0]); + std::string::iterator i = v.insert(v2.cbegin() + 10, a, a+N); + assert(false); + } +#endif + + { // test inserting into self + typedef std::string S; + S s_short = "123/"; + S s_long = "Lorem ipsum dolor sit amet, consectetur/"; + + s_short.insert(s_short.begin(), s_short.begin(), s_short.end()); + assert(s_short == "123/123/"); + s_short.insert(s_short.begin(), s_short.begin(), s_short.end()); + assert(s_short == "123/123/123/123/"); + s_short.insert(s_short.begin(), s_short.begin(), s_short.end()); + assert(s_short == "123/123/123/123/123/123/123/123/"); + + s_long.insert(s_long.begin(), s_long.begin(), s_long.end()); + assert(s_long == "Lorem ipsum dolor sit amet, consectetur/Lorem ipsum dolor sit amet, consectetur/"); + } + + { // test assigning a different type + typedef std::string S; + const uint8_t p[] = "ABCD"; + + S s; + s.insert(s.begin(), p, p + 4); + assert(s == "ABCD"); + } + + { // test with a move iterator that returns char&& + typedef input_iterator It; + typedef std::move_iterator MoveIt; + const char p[] = "ABCD"; + std::string s; + s.insert(s.begin(), MoveIt(It(std::begin(p))), MoveIt(It(std::end(p) - 1))); + assert(s == "ABCD"); + } + { // test with a move iterator that returns char&& + typedef forward_iterator It; + typedef std::move_iterator MoveIt; + const char p[] = "ABCD"; + std::string s; + s.insert(s.begin(), MoveIt(It(std::begin(p))), MoveIt(It(std::end(p) - 1))); + assert(s == "ABCD"); + } + { // test with a move iterator that returns char&& + typedef const char* It; + typedef std::move_iterator MoveIt; + const char p[] = "ABCD"; + std::string s; + s.insert(s.begin(), MoveIt(It(std::begin(p))), MoveIt(It(std::end(p) - 1))); + assert(s == "ABCD"); + } +} diff --git a/tests/external/libcxx/basic_string/string.modifiers/string_insert/iter_size_char.pass.cpp b/tests/external/libcxx/basic_string/string.modifiers/string_insert/iter_size_char.pass.cpp new file mode 100644 index 0000000..c9cd0c2 --- /dev/null +++ b/tests/external/libcxx/basic_string/string.modifiers/string_insert/iter_size_char.pass.cpp @@ -0,0 +1,170 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// + +// iterator insert(const_iterator p, size_type n, charT c); + +#include +#include + +#include "test_macros.h" +#include "min_allocator.h" + +template +void +test(S s, typename S::difference_type pos, typename S::size_type n, + typename S::value_type c, S expected) +{ + typename S::const_iterator p = s.cbegin() + pos; + typename S::iterator i = s.insert(p, n, c); + LIBCPP_ASSERT(s.__invariants()); + assert(i - s.begin() == pos); + assert(s == expected); +} + +int main() +{ + { + typedef std::string S; + test(S(""), 0, 0, '1', S("")); + test(S(""), 0, 5, '1', S("11111")); + test(S(""), 0, 10, '1', S("1111111111")); + test(S(""), 0, 20, '1', S("11111111111111111111")); + test(S("abcde"), 0, 0, '1', S("abcde")); + test(S("abcde"), 0, 5, '1', S("11111abcde")); + test(S("abcde"), 0, 10, '1', S("1111111111abcde")); + test(S("abcde"), 0, 20, '1', S("11111111111111111111abcde")); + test(S("abcde"), 1, 0, '1', S("abcde")); + test(S("abcde"), 1, 5, '1', S("a11111bcde")); + test(S("abcde"), 1, 10, '1', S("a1111111111bcde")); + test(S("abcde"), 1, 20, '1', S("a11111111111111111111bcde")); + test(S("abcde"), 2, 0, '1', S("abcde")); + test(S("abcde"), 2, 5, '1', S("ab11111cde")); + test(S("abcde"), 2, 10, '1', S("ab1111111111cde")); + test(S("abcde"), 2, 20, '1', S("ab11111111111111111111cde")); + test(S("abcde"), 4, 0, '1', S("abcde")); + test(S("abcde"), 4, 5, '1', S("abcd11111e")); + test(S("abcde"), 4, 10, '1', S("abcd1111111111e")); + test(S("abcde"), 4, 20, '1', S("abcd11111111111111111111e")); + test(S("abcde"), 5, 0, '1', S("abcde")); + test(S("abcde"), 5, 5, '1', S("abcde11111")); + test(S("abcde"), 5, 10, '1', S("abcde1111111111")); + test(S("abcde"), 5, 20, '1', S("abcde11111111111111111111")); + test(S("abcdefghij"), 0, 0, '1', S("abcdefghij")); + test(S("abcdefghij"), 0, 5, '1', S("11111abcdefghij")); + test(S("abcdefghij"), 0, 10, '1', S("1111111111abcdefghij")); + test(S("abcdefghij"), 0, 20, '1', S("11111111111111111111abcdefghij")); + test(S("abcdefghij"), 1, 0, '1', S("abcdefghij")); + test(S("abcdefghij"), 1, 5, '1', S("a11111bcdefghij")); + test(S("abcdefghij"), 1, 10, '1', S("a1111111111bcdefghij")); + test(S("abcdefghij"), 1, 20, '1', S("a11111111111111111111bcdefghij")); + test(S("abcdefghij"), 5, 0, '1', S("abcdefghij")); + test(S("abcdefghij"), 5, 5, '1', S("abcde11111fghij")); + test(S("abcdefghij"), 5, 10, '1', S("abcde1111111111fghij")); + test(S("abcdefghij"), 5, 20, '1', S("abcde11111111111111111111fghij")); + test(S("abcdefghij"), 9, 0, '1', S("abcdefghij")); + test(S("abcdefghij"), 9, 5, '1', S("abcdefghi11111j")); + test(S("abcdefghij"), 9, 10, '1', S("abcdefghi1111111111j")); + test(S("abcdefghij"), 9, 20, '1', S("abcdefghi11111111111111111111j")); + test(S("abcdefghij"), 10, 0, '1', S("abcdefghij")); + test(S("abcdefghij"), 10, 5, '1', S("abcdefghij11111")); + test(S("abcdefghij"), 10, 10, '1', S("abcdefghij1111111111")); + test(S("abcdefghij"), 10, 20, '1', S("abcdefghij11111111111111111111")); + test(S("abcdefghijklmnopqrst"), 0, 0, '1', S("abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, 5, '1', S("11111abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, 10, '1', S("1111111111abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, 20, '1', S("11111111111111111111abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, 0, '1', S("abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, 5, '1', S("a11111bcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, 10, '1', S("a1111111111bcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, 20, '1', S("a11111111111111111111bcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 10, 0, '1', S("abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 10, 5, '1', S("abcdefghij11111klmnopqrst")); + test(S("abcdefghijklmnopqrst"), 10, 10, '1', S("abcdefghij1111111111klmnopqrst")); + test(S("abcdefghijklmnopqrst"), 10, 20, '1', S("abcdefghij11111111111111111111klmnopqrst")); + test(S("abcdefghijklmnopqrst"), 19, 0, '1', S("abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 19, 5, '1', S("abcdefghijklmnopqrs11111t")); + test(S("abcdefghijklmnopqrst"), 19, 10, '1', S("abcdefghijklmnopqrs1111111111t")); + test(S("abcdefghijklmnopqrst"), 19, 20, '1', S("abcdefghijklmnopqrs11111111111111111111t")); + test(S("abcdefghijklmnopqrst"), 20, 0, '1', S("abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 20, 5, '1', S("abcdefghijklmnopqrst11111")); + test(S("abcdefghijklmnopqrst"), 20, 10, '1', S("abcdefghijklmnopqrst1111111111")); + test(S("abcdefghijklmnopqrst"), 20, 20, '1', S("abcdefghijklmnopqrst11111111111111111111")); + } +#if TEST_STD_VER >= 11 + { + typedef std::basic_string, min_allocator> S; + test(S(""), 0, 0, '1', S("")); + test(S(""), 0, 5, '1', S("11111")); + test(S(""), 0, 10, '1', S("1111111111")); + test(S(""), 0, 20, '1', S("11111111111111111111")); + test(S("abcde"), 0, 0, '1', S("abcde")); + test(S("abcde"), 0, 5, '1', S("11111abcde")); + test(S("abcde"), 0, 10, '1', S("1111111111abcde")); + test(S("abcde"), 0, 20, '1', S("11111111111111111111abcde")); + test(S("abcde"), 1, 0, '1', S("abcde")); + test(S("abcde"), 1, 5, '1', S("a11111bcde")); + test(S("abcde"), 1, 10, '1', S("a1111111111bcde")); + test(S("abcde"), 1, 20, '1', S("a11111111111111111111bcde")); + test(S("abcde"), 2, 0, '1', S("abcde")); + test(S("abcde"), 2, 5, '1', S("ab11111cde")); + test(S("abcde"), 2, 10, '1', S("ab1111111111cde")); + test(S("abcde"), 2, 20, '1', S("ab11111111111111111111cde")); + test(S("abcde"), 4, 0, '1', S("abcde")); + test(S("abcde"), 4, 5, '1', S("abcd11111e")); + test(S("abcde"), 4, 10, '1', S("abcd1111111111e")); + test(S("abcde"), 4, 20, '1', S("abcd11111111111111111111e")); + test(S("abcde"), 5, 0, '1', S("abcde")); + test(S("abcde"), 5, 5, '1', S("abcde11111")); + test(S("abcde"), 5, 10, '1', S("abcde1111111111")); + test(S("abcde"), 5, 20, '1', S("abcde11111111111111111111")); + test(S("abcdefghij"), 0, 0, '1', S("abcdefghij")); + test(S("abcdefghij"), 0, 5, '1', S("11111abcdefghij")); + test(S("abcdefghij"), 0, 10, '1', S("1111111111abcdefghij")); + test(S("abcdefghij"), 0, 20, '1', S("11111111111111111111abcdefghij")); + test(S("abcdefghij"), 1, 0, '1', S("abcdefghij")); + test(S("abcdefghij"), 1, 5, '1', S("a11111bcdefghij")); + test(S("abcdefghij"), 1, 10, '1', S("a1111111111bcdefghij")); + test(S("abcdefghij"), 1, 20, '1', S("a11111111111111111111bcdefghij")); + test(S("abcdefghij"), 5, 0, '1', S("abcdefghij")); + test(S("abcdefghij"), 5, 5, '1', S("abcde11111fghij")); + test(S("abcdefghij"), 5, 10, '1', S("abcde1111111111fghij")); + test(S("abcdefghij"), 5, 20, '1', S("abcde11111111111111111111fghij")); + test(S("abcdefghij"), 9, 0, '1', S("abcdefghij")); + test(S("abcdefghij"), 9, 5, '1', S("abcdefghi11111j")); + test(S("abcdefghij"), 9, 10, '1', S("abcdefghi1111111111j")); + test(S("abcdefghij"), 9, 20, '1', S("abcdefghi11111111111111111111j")); + test(S("abcdefghij"), 10, 0, '1', S("abcdefghij")); + test(S("abcdefghij"), 10, 5, '1', S("abcdefghij11111")); + test(S("abcdefghij"), 10, 10, '1', S("abcdefghij1111111111")); + test(S("abcdefghij"), 10, 20, '1', S("abcdefghij11111111111111111111")); + test(S("abcdefghijklmnopqrst"), 0, 0, '1', S("abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, 5, '1', S("11111abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, 10, '1', S("1111111111abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, 20, '1', S("11111111111111111111abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, 0, '1', S("abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, 5, '1', S("a11111bcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, 10, '1', S("a1111111111bcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, 20, '1', S("a11111111111111111111bcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 10, 0, '1', S("abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 10, 5, '1', S("abcdefghij11111klmnopqrst")); + test(S("abcdefghijklmnopqrst"), 10, 10, '1', S("abcdefghij1111111111klmnopqrst")); + test(S("abcdefghijklmnopqrst"), 10, 20, '1', S("abcdefghij11111111111111111111klmnopqrst")); + test(S("abcdefghijklmnopqrst"), 19, 0, '1', S("abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 19, 5, '1', S("abcdefghijklmnopqrs11111t")); + test(S("abcdefghijklmnopqrst"), 19, 10, '1', S("abcdefghijklmnopqrs1111111111t")); + test(S("abcdefghijklmnopqrst"), 19, 20, '1', S("abcdefghijklmnopqrs11111111111111111111t")); + test(S("abcdefghijklmnopqrst"), 20, 0, '1', S("abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 20, 5, '1', S("abcdefghijklmnopqrst11111")); + test(S("abcdefghijklmnopqrst"), 20, 10, '1', S("abcdefghijklmnopqrst1111111111")); + test(S("abcdefghijklmnopqrst"), 20, 20, '1', S("abcdefghijklmnopqrst11111111111111111111")); + } +#endif +} diff --git a/tests/external/libcxx/basic_string/string.modifiers/string_insert/size_T_size_size.pass.cpp b/tests/external/libcxx/basic_string/string.modifiers/string_insert/size_T_size_size.pass.cpp new file mode 100644 index 0000000..e9476f4 --- /dev/null +++ b/tests/external/libcxx/basic_string/string.modifiers/string_insert/size_T_size_size.pass.cpp @@ -0,0 +1,1842 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// + +// template +// basic_string& assign(size_type pos1, const T& t, size_type pos2, size_type n=npos); // C++17 +// +// Mostly we're testing string_view here + +#include +#include +#include + +#include "test_macros.h" +#include "min_allocator.h" + +template +void +test(S s, typename S::size_type pos1, SV sv, typename S::size_type pos2, + typename S::size_type n, S expected) +{ + static_assert((!std::is_same::value), ""); + const typename S::size_type old_size = s.size(); + S s0 = s; + if (pos1 <= old_size && pos2 <= sv.size()) + { + s.insert(pos1, sv, pos2, n); + LIBCPP_ASSERT(s.__invariants()); + assert(s == expected); + } +#ifndef TEST_HAS_NO_EXCEPTIONS + else + { + try + { + s.insert(pos1, sv, pos2, n); + assert(false); + } + catch (std::out_of_range&) + { + assert(pos1 > old_size || pos2 > sv.size()); + assert(s == s0); + } + } +#endif +} + +template +void +test_npos(S s, typename S::size_type pos1, SV sv, typename S::size_type pos2, S expected) +{ + static_assert((!std::is_same::value), ""); + const typename S::size_type old_size = s.size(); + S s0 = s; + if (pos1 <= old_size && pos2 <= sv.size()) + { + s.insert(pos1, sv, pos2); + LIBCPP_ASSERT(s.__invariants()); + assert(s == expected); + } +#ifndef TEST_HAS_NO_EXCEPTIONS + else + { + try + { + s.insert(pos1, sv, pos2); + assert(false); + } + catch (std::out_of_range&) + { + assert(pos1 > old_size || pos2 > sv.size()); + assert(s == s0); + } + } +#endif +} + + +template +void test0() +{ + test(S(""), 0, SV(""), 0, 0, S("")); + test(S(""), 0, SV(""), 0, 1, S("")); + test(S(""), 0, SV(""), 1, 0, S("can't happen")); + test(S(""), 0, SV("12345"), 0, 0, S("")); + test(S(""), 0, SV("12345"), 0, 1, S("1")); + test(S(""), 0, SV("12345"), 0, 2, S("12")); + test(S(""), 0, SV("12345"), 0, 4, S("1234")); + test(S(""), 0, SV("12345"), 0, 5, S("12345")); + test(S(""), 0, SV("12345"), 0, 6, S("12345")); + test(S(""), 0, SV("12345"), 1, 0, S("")); + test(S(""), 0, SV("12345"), 1, 1, S("2")); + test(S(""), 0, SV("12345"), 1, 2, S("23")); + test(S(""), 0, SV("12345"), 1, 3, S("234")); + test(S(""), 0, SV("12345"), 1, 4, S("2345")); + test(S(""), 0, SV("12345"), 1, 5, S("2345")); + test(S(""), 0, SV("12345"), 2, 0, S("")); + test(S(""), 0, SV("12345"), 2, 1, S("3")); + test(S(""), 0, SV("12345"), 2, 2, S("34")); + test(S(""), 0, SV("12345"), 2, 3, S("345")); + test(S(""), 0, SV("12345"), 2, 4, S("345")); + test(S(""), 0, SV("12345"), 4, 0, S("")); + test(S(""), 0, SV("12345"), 4, 1, S("5")); + test(S(""), 0, SV("12345"), 4, 2, S("5")); + test(S(""), 0, SV("12345"), 5, 0, S("")); + test(S(""), 0, SV("12345"), 5, 1, S("")); + test(S(""), 0, SV("12345"), 6, 0, S("can't happen")); + test(S(""), 0, SV("1234567890"), 0, 0, S("")); + test(S(""), 0, SV("1234567890"), 0, 1, S("1")); + test(S(""), 0, SV("1234567890"), 0, 5, S("12345")); + test(S(""), 0, SV("1234567890"), 0, 9, S("123456789")); + test(S(""), 0, SV("1234567890"), 0, 10, S("1234567890")); + test(S(""), 0, SV("1234567890"), 0, 11, S("1234567890")); + test(S(""), 0, SV("1234567890"), 1, 0, S("")); + test(S(""), 0, SV("1234567890"), 1, 1, S("2")); + test(S(""), 0, SV("1234567890"), 1, 4, S("2345")); + test(S(""), 0, SV("1234567890"), 1, 8, S("23456789")); + test(S(""), 0, SV("1234567890"), 1, 9, S("234567890")); + test(S(""), 0, SV("1234567890"), 1, 10, S("234567890")); + test(S(""), 0, SV("1234567890"), 5, 0, S("")); + test(S(""), 0, SV("1234567890"), 5, 1, S("6")); + test(S(""), 0, SV("1234567890"), 5, 2, S("67")); + test(S(""), 0, SV("1234567890"), 5, 4, S("6789")); + test(S(""), 0, SV("1234567890"), 5, 5, S("67890")); + test(S(""), 0, SV("1234567890"), 5, 6, S("67890")); + test(S(""), 0, SV("1234567890"), 9, 0, S("")); + test(S(""), 0, SV("1234567890"), 9, 1, S("0")); + test(S(""), 0, SV("1234567890"), 9, 2, S("0")); + test(S(""), 0, SV("1234567890"), 10, 0, S("")); + test(S(""), 0, SV("1234567890"), 10, 1, S("")); + test(S(""), 0, SV("1234567890"), 11, 0, S("can't happen")); +} + +template +void test1() +{ + test(S(""), 0, SV("12345678901234567890"), 0, 0, S("")); + test(S(""), 0, SV("12345678901234567890"), 0, 1, S("1")); + test(S(""), 0, SV("12345678901234567890"), 0, 10, S("1234567890")); + test(S(""), 0, SV("12345678901234567890"), 0, 19, S("1234567890123456789")); + test(S(""), 0, SV("12345678901234567890"), 0, 20, S("12345678901234567890")); + test(S(""), 0, SV("12345678901234567890"), 0, 21, S("12345678901234567890")); + test(S(""), 0, SV("12345678901234567890"), 1, 0, S("")); + test(S(""), 0, SV("12345678901234567890"), 1, 1, S("2")); + test(S(""), 0, SV("12345678901234567890"), 1, 9, S("234567890")); + test(S(""), 0, SV("12345678901234567890"), 1, 18, S("234567890123456789")); + test(S(""), 0, SV("12345678901234567890"), 1, 19, S("2345678901234567890")); + test(S(""), 0, SV("12345678901234567890"), 1, 20, S("2345678901234567890")); + test(S(""), 0, SV("12345678901234567890"), 10, 0, S("")); + test(S(""), 0, SV("12345678901234567890"), 10, 1, S("1")); + test(S(""), 0, SV("12345678901234567890"), 10, 5, S("12345")); + test(S(""), 0, SV("12345678901234567890"), 10, 9, S("123456789")); + test(S(""), 0, SV("12345678901234567890"), 10, 10, S("1234567890")); + test(S(""), 0, SV("12345678901234567890"), 10, 11, S("1234567890")); + test(S(""), 0, SV("12345678901234567890"), 19, 0, S("")); + test(S(""), 0, SV("12345678901234567890"), 19, 1, S("0")); + test(S(""), 0, SV("12345678901234567890"), 19, 2, S("0")); + test(S(""), 0, SV("12345678901234567890"), 20, 0, S("")); + test(S(""), 0, SV("12345678901234567890"), 20, 1, S("")); + test(S(""), 0, SV("12345678901234567890"), 21, 0, S("can't happen")); + test(S(""), 1, SV(""), 0, 0, S("can't happen")); + test(S(""), 1, SV(""), 0, 1, S("can't happen")); + test(S(""), 1, SV(""), 1, 0, S("can't happen")); + test(S(""), 1, SV("12345"), 0, 0, S("can't happen")); + test(S(""), 1, SV("12345"), 0, 1, S("can't happen")); + test(S(""), 1, SV("12345"), 0, 2, S("can't happen")); + test(S(""), 1, SV("12345"), 0, 4, S("can't happen")); + test(S(""), 1, SV("12345"), 0, 5, S("can't happen")); + test(S(""), 1, SV("12345"), 0, 6, S("can't happen")); + test(S(""), 1, SV("12345"), 1, 0, S("can't happen")); + test(S(""), 1, SV("12345"), 1, 1, S("can't happen")); + test(S(""), 1, SV("12345"), 1, 2, S("can't happen")); + test(S(""), 1, SV("12345"), 1, 3, S("can't happen")); + test(S(""), 1, SV("12345"), 1, 4, S("can't happen")); + test(S(""), 1, SV("12345"), 1, 5, S("can't happen")); + test(S(""), 1, SV("12345"), 2, 0, S("can't happen")); + test(S(""), 1, SV("12345"), 2, 1, S("can't happen")); + test(S(""), 1, SV("12345"), 2, 2, S("can't happen")); + test(S(""), 1, SV("12345"), 2, 3, S("can't happen")); + test(S(""), 1, SV("12345"), 2, 4, S("can't happen")); + test(S(""), 1, SV("12345"), 4, 0, S("can't happen")); + test(S(""), 1, SV("12345"), 4, 1, S("can't happen")); + test(S(""), 1, SV("12345"), 4, 2, S("can't happen")); + test(S(""), 1, SV("12345"), 5, 0, S("can't happen")); + test(S(""), 1, SV("12345"), 5, 1, S("can't happen")); + test(S(""), 1, SV("12345"), 6, 0, S("can't happen")); +} + +template +void test2() +{ + test(S(""), 1, SV("1234567890"), 0, 0, S("can't happen")); + test(S(""), 1, SV("1234567890"), 0, 1, S("can't happen")); + test(S(""), 1, SV("1234567890"), 0, 5, S("can't happen")); + test(S(""), 1, SV("1234567890"), 0, 9, S("can't happen")); + test(S(""), 1, SV("1234567890"), 0, 10, S("can't happen")); + test(S(""), 1, SV("1234567890"), 0, 11, S("can't happen")); + test(S(""), 1, SV("1234567890"), 1, 0, S("can't happen")); + test(S(""), 1, SV("1234567890"), 1, 1, S("can't happen")); + test(S(""), 1, SV("1234567890"), 1, 4, S("can't happen")); + test(S(""), 1, SV("1234567890"), 1, 8, S("can't happen")); + test(S(""), 1, SV("1234567890"), 1, 9, S("can't happen")); + test(S(""), 1, SV("1234567890"), 1, 10, S("can't happen")); + test(S(""), 1, SV("1234567890"), 5, 0, S("can't happen")); + test(S(""), 1, SV("1234567890"), 5, 1, S("can't happen")); + test(S(""), 1, SV("1234567890"), 5, 2, S("can't happen")); + test(S(""), 1, SV("1234567890"), 5, 4, S("can't happen")); + test(S(""), 1, SV("1234567890"), 5, 5, S("can't happen")); + test(S(""), 1, SV("1234567890"), 5, 6, S("can't happen")); + test(S(""), 1, SV("1234567890"), 9, 0, S("can't happen")); + test(S(""), 1, SV("1234567890"), 9, 1, S("can't happen")); + test(S(""), 1, SV("1234567890"), 9, 2, S("can't happen")); + test(S(""), 1, SV("1234567890"), 10, 0, S("can't happen")); + test(S(""), 1, SV("1234567890"), 10, 1, S("can't happen")); + test(S(""), 1, SV("1234567890"), 11, 0, S("can't happen")); + test(S(""), 1, SV("12345678901234567890"), 0, 0, S("can't happen")); + test(S(""), 1, SV("12345678901234567890"), 0, 1, S("can't happen")); + test(S(""), 1, SV("12345678901234567890"), 0, 10, S("can't happen")); + test(S(""), 1, SV("12345678901234567890"), 0, 19, S("can't happen")); + test(S(""), 1, SV("12345678901234567890"), 0, 20, S("can't happen")); + test(S(""), 1, SV("12345678901234567890"), 0, 21, S("can't happen")); + test(S(""), 1, SV("12345678901234567890"), 1, 0, S("can't happen")); + test(S(""), 1, SV("12345678901234567890"), 1, 1, S("can't happen")); + test(S(""), 1, SV("12345678901234567890"), 1, 9, S("can't happen")); + test(S(""), 1, SV("12345678901234567890"), 1, 18, S("can't happen")); + test(S(""), 1, SV("12345678901234567890"), 1, 19, S("can't happen")); + test(S(""), 1, SV("12345678901234567890"), 1, 20, S("can't happen")); + test(S(""), 1, SV("12345678901234567890"), 10, 0, S("can't happen")); + test(S(""), 1, SV("12345678901234567890"), 10, 1, S("can't happen")); + test(S(""), 1, SV("12345678901234567890"), 10, 5, S("can't happen")); + test(S(""), 1, SV("12345678901234567890"), 10, 9, S("can't happen")); + test(S(""), 1, SV("12345678901234567890"), 10, 10, S("can't happen")); + test(S(""), 1, SV("12345678901234567890"), 10, 11, S("can't happen")); + test(S(""), 1, SV("12345678901234567890"), 19, 0, S("can't happen")); + test(S(""), 1, SV("12345678901234567890"), 19, 1, S("can't happen")); + test(S(""), 1, SV("12345678901234567890"), 19, 2, S("can't happen")); + test(S(""), 1, SV("12345678901234567890"), 20, 0, S("can't happen")); + test(S(""), 1, SV("12345678901234567890"), 20, 1, S("can't happen")); + test(S(""), 1, SV("12345678901234567890"), 21, 0, S("can't happen")); + test(S("abcde"), 0, SV(""), 0, 0, S("abcde")); + test(S("abcde"), 0, SV(""), 0, 1, S("abcde")); +} + +template +void test3() +{ + test(S("abcde"), 0, SV(""), 1, 0, S("can't happen")); + test(S("abcde"), 0, SV("12345"), 0, 0, S("abcde")); + test(S("abcde"), 0, SV("12345"), 0, 1, S("1abcde")); + test(S("abcde"), 0, SV("12345"), 0, 2, S("12abcde")); + test(S("abcde"), 0, SV("12345"), 0, 4, S("1234abcde")); + test(S("abcde"), 0, SV("12345"), 0, 5, S("12345abcde")); + test(S("abcde"), 0, SV("12345"), 0, 6, S("12345abcde")); + test(S("abcde"), 0, SV("12345"), 1, 0, S("abcde")); + test(S("abcde"), 0, SV("12345"), 1, 1, S("2abcde")); + test(S("abcde"), 0, SV("12345"), 1, 2, S("23abcde")); + test(S("abcde"), 0, SV("12345"), 1, 3, S("234abcde")); + test(S("abcde"), 0, SV("12345"), 1, 4, S("2345abcde")); + test(S("abcde"), 0, SV("12345"), 1, 5, S("2345abcde")); + test(S("abcde"), 0, SV("12345"), 2, 0, S("abcde")); + test(S("abcde"), 0, SV("12345"), 2, 1, S("3abcde")); + test(S("abcde"), 0, SV("12345"), 2, 2, S("34abcde")); + test(S("abcde"), 0, SV("12345"), 2, 3, S("345abcde")); + test(S("abcde"), 0, SV("12345"), 2, 4, S("345abcde")); + test(S("abcde"), 0, SV("12345"), 4, 0, S("abcde")); + test(S("abcde"), 0, SV("12345"), 4, 1, S("5abcde")); + test(S("abcde"), 0, SV("12345"), 4, 2, S("5abcde")); + test(S("abcde"), 0, SV("12345"), 5, 0, S("abcde")); + test(S("abcde"), 0, SV("12345"), 5, 1, S("abcde")); + test(S("abcde"), 0, SV("12345"), 6, 0, S("can't happen")); + test(S("abcde"), 0, SV("1234567890"), 0, 0, S("abcde")); + test(S("abcde"), 0, SV("1234567890"), 0, 1, S("1abcde")); + test(S("abcde"), 0, SV("1234567890"), 0, 5, S("12345abcde")); + test(S("abcde"), 0, SV("1234567890"), 0, 9, S("123456789abcde")); + test(S("abcde"), 0, SV("1234567890"), 0, 10, S("1234567890abcde")); + test(S("abcde"), 0, SV("1234567890"), 0, 11, S("1234567890abcde")); + test(S("abcde"), 0, SV("1234567890"), 1, 0, S("abcde")); + test(S("abcde"), 0, SV("1234567890"), 1, 1, S("2abcde")); + test(S("abcde"), 0, SV("1234567890"), 1, 4, S("2345abcde")); + test(S("abcde"), 0, SV("1234567890"), 1, 8, S("23456789abcde")); + test(S("abcde"), 0, SV("1234567890"), 1, 9, S("234567890abcde")); + test(S("abcde"), 0, SV("1234567890"), 1, 10, S("234567890abcde")); + test(S("abcde"), 0, SV("1234567890"), 5, 0, S("abcde")); + test(S("abcde"), 0, SV("1234567890"), 5, 1, S("6abcde")); + test(S("abcde"), 0, SV("1234567890"), 5, 2, S("67abcde")); + test(S("abcde"), 0, SV("1234567890"), 5, 4, S("6789abcde")); + test(S("abcde"), 0, SV("1234567890"), 5, 5, S("67890abcde")); + test(S("abcde"), 0, SV("1234567890"), 5, 6, S("67890abcde")); + test(S("abcde"), 0, SV("1234567890"), 9, 0, S("abcde")); + test(S("abcde"), 0, SV("1234567890"), 9, 1, S("0abcde")); + test(S("abcde"), 0, SV("1234567890"), 9, 2, S("0abcde")); + test(S("abcde"), 0, SV("1234567890"), 10, 0, S("abcde")); + test(S("abcde"), 0, SV("1234567890"), 10, 1, S("abcde")); + test(S("abcde"), 0, SV("1234567890"), 11, 0, S("can't happen")); + test(S("abcde"), 0, SV("12345678901234567890"), 0, 0, S("abcde")); + test(S("abcde"), 0, SV("12345678901234567890"), 0, 1, S("1abcde")); +} + +template +void test4() +{ + test(S("abcde"), 0, SV("12345678901234567890"), 0, 10, S("1234567890abcde")); + test(S("abcde"), 0, SV("12345678901234567890"), 0, 19, S("1234567890123456789abcde")); + test(S("abcde"), 0, SV("12345678901234567890"), 0, 20, S("12345678901234567890abcde")); + test(S("abcde"), 0, SV("12345678901234567890"), 0, 21, S("12345678901234567890abcde")); + test(S("abcde"), 0, SV("12345678901234567890"), 1, 0, S("abcde")); + test(S("abcde"), 0, SV("12345678901234567890"), 1, 1, S("2abcde")); + test(S("abcde"), 0, SV("12345678901234567890"), 1, 9, S("234567890abcde")); + test(S("abcde"), 0, SV("12345678901234567890"), 1, 18, S("234567890123456789abcde")); + test(S("abcde"), 0, SV("12345678901234567890"), 1, 19, S("2345678901234567890abcde")); + test(S("abcde"), 0, SV("12345678901234567890"), 1, 20, S("2345678901234567890abcde")); + test(S("abcde"), 0, SV("12345678901234567890"), 10, 0, S("abcde")); + test(S("abcde"), 0, SV("12345678901234567890"), 10, 1, S("1abcde")); + test(S("abcde"), 0, SV("12345678901234567890"), 10, 5, S("12345abcde")); + test(S("abcde"), 0, SV("12345678901234567890"), 10, 9, S("123456789abcde")); + test(S("abcde"), 0, SV("12345678901234567890"), 10, 10, S("1234567890abcde")); + test(S("abcde"), 0, SV("12345678901234567890"), 10, 11, S("1234567890abcde")); + test(S("abcde"), 0, SV("12345678901234567890"), 19, 0, S("abcde")); + test(S("abcde"), 0, SV("12345678901234567890"), 19, 1, S("0abcde")); + test(S("abcde"), 0, SV("12345678901234567890"), 19, 2, S("0abcde")); + test(S("abcde"), 0, SV("12345678901234567890"), 20, 0, S("abcde")); + test(S("abcde"), 0, SV("12345678901234567890"), 20, 1, S("abcde")); + test(S("abcde"), 0, SV("12345678901234567890"), 21, 0, S("can't happen")); + test(S("abcde"), 1, SV(""), 0, 0, S("abcde")); + test(S("abcde"), 1, SV(""), 0, 1, S("abcde")); + test(S("abcde"), 1, SV(""), 1, 0, S("can't happen")); + test(S("abcde"), 1, SV("12345"), 0, 0, S("abcde")); + test(S("abcde"), 1, SV("12345"), 0, 1, S("a1bcde")); + test(S("abcde"), 1, SV("12345"), 0, 2, S("a12bcde")); + test(S("abcde"), 1, SV("12345"), 0, 4, S("a1234bcde")); + test(S("abcde"), 1, SV("12345"), 0, 5, S("a12345bcde")); + test(S("abcde"), 1, SV("12345"), 0, 6, S("a12345bcde")); + test(S("abcde"), 1, SV("12345"), 1, 0, S("abcde")); + test(S("abcde"), 1, SV("12345"), 1, 1, S("a2bcde")); + test(S("abcde"), 1, SV("12345"), 1, 2, S("a23bcde")); + test(S("abcde"), 1, SV("12345"), 1, 3, S("a234bcde")); + test(S("abcde"), 1, SV("12345"), 1, 4, S("a2345bcde")); + test(S("abcde"), 1, SV("12345"), 1, 5, S("a2345bcde")); + test(S("abcde"), 1, SV("12345"), 2, 0, S("abcde")); + test(S("abcde"), 1, SV("12345"), 2, 1, S("a3bcde")); + test(S("abcde"), 1, SV("12345"), 2, 2, S("a34bcde")); + test(S("abcde"), 1, SV("12345"), 2, 3, S("a345bcde")); + test(S("abcde"), 1, SV("12345"), 2, 4, S("a345bcde")); + test(S("abcde"), 1, SV("12345"), 4, 0, S("abcde")); + test(S("abcde"), 1, SV("12345"), 4, 1, S("a5bcde")); + test(S("abcde"), 1, SV("12345"), 4, 2, S("a5bcde")); + test(S("abcde"), 1, SV("12345"), 5, 0, S("abcde")); + test(S("abcde"), 1, SV("12345"), 5, 1, S("abcde")); + test(S("abcde"), 1, SV("12345"), 6, 0, S("can't happen")); + test(S("abcde"), 1, SV("1234567890"), 0, 0, S("abcde")); + test(S("abcde"), 1, SV("1234567890"), 0, 1, S("a1bcde")); +} + +template +void test5() +{ + test(S("abcde"), 1, SV("1234567890"), 0, 5, S("a12345bcde")); + test(S("abcde"), 1, SV("1234567890"), 0, 9, S("a123456789bcde")); + test(S("abcde"), 1, SV("1234567890"), 0, 10, S("a1234567890bcde")); + test(S("abcde"), 1, SV("1234567890"), 0, 11, S("a1234567890bcde")); + test(S("abcde"), 1, SV("1234567890"), 1, 0, S("abcde")); + test(S("abcde"), 1, SV("1234567890"), 1, 1, S("a2bcde")); + test(S("abcde"), 1, SV("1234567890"), 1, 4, S("a2345bcde")); + test(S("abcde"), 1, SV("1234567890"), 1, 8, S("a23456789bcde")); + test(S("abcde"), 1, SV("1234567890"), 1, 9, S("a234567890bcde")); + test(S("abcde"), 1, SV("1234567890"), 1, 10, S("a234567890bcde")); + test(S("abcde"), 1, SV("1234567890"), 5, 0, S("abcde")); + test(S("abcde"), 1, SV("1234567890"), 5, 1, S("a6bcde")); + test(S("abcde"), 1, SV("1234567890"), 5, 2, S("a67bcde")); + test(S("abcde"), 1, SV("1234567890"), 5, 4, S("a6789bcde")); + test(S("abcde"), 1, SV("1234567890"), 5, 5, S("a67890bcde")); + test(S("abcde"), 1, SV("1234567890"), 5, 6, S("a67890bcde")); + test(S("abcde"), 1, SV("1234567890"), 9, 0, S("abcde")); + test(S("abcde"), 1, SV("1234567890"), 9, 1, S("a0bcde")); + test(S("abcde"), 1, SV("1234567890"), 9, 2, S("a0bcde")); + test(S("abcde"), 1, SV("1234567890"), 10, 0, S("abcde")); + test(S("abcde"), 1, SV("1234567890"), 10, 1, S("abcde")); + test(S("abcde"), 1, SV("1234567890"), 11, 0, S("can't happen")); + test(S("abcde"), 1, SV("12345678901234567890"), 0, 0, S("abcde")); + test(S("abcde"), 1, SV("12345678901234567890"), 0, 1, S("a1bcde")); + test(S("abcde"), 1, SV("12345678901234567890"), 0, 10, S("a1234567890bcde")); + test(S("abcde"), 1, SV("12345678901234567890"), 0, 19, S("a1234567890123456789bcde")); + test(S("abcde"), 1, SV("12345678901234567890"), 0, 20, S("a12345678901234567890bcde")); + test(S("abcde"), 1, SV("12345678901234567890"), 0, 21, S("a12345678901234567890bcde")); + test(S("abcde"), 1, SV("12345678901234567890"), 1, 0, S("abcde")); + test(S("abcde"), 1, SV("12345678901234567890"), 1, 1, S("a2bcde")); + test(S("abcde"), 1, SV("12345678901234567890"), 1, 9, S("a234567890bcde")); + test(S("abcde"), 1, SV("12345678901234567890"), 1, 18, S("a234567890123456789bcde")); + test(S("abcde"), 1, SV("12345678901234567890"), 1, 19, S("a2345678901234567890bcde")); + test(S("abcde"), 1, SV("12345678901234567890"), 1, 20, S("a2345678901234567890bcde")); + test(S("abcde"), 1, SV("12345678901234567890"), 10, 0, S("abcde")); + test(S("abcde"), 1, SV("12345678901234567890"), 10, 1, S("a1bcde")); + test(S("abcde"), 1, SV("12345678901234567890"), 10, 5, S("a12345bcde")); + test(S("abcde"), 1, SV("12345678901234567890"), 10, 9, S("a123456789bcde")); + test(S("abcde"), 1, SV("12345678901234567890"), 10, 10, S("a1234567890bcde")); + test(S("abcde"), 1, SV("12345678901234567890"), 10, 11, S("a1234567890bcde")); + test(S("abcde"), 1, SV("12345678901234567890"), 19, 0, S("abcde")); + test(S("abcde"), 1, SV("12345678901234567890"), 19, 1, S("a0bcde")); + test(S("abcde"), 1, SV("12345678901234567890"), 19, 2, S("a0bcde")); + test(S("abcde"), 1, SV("12345678901234567890"), 20, 0, S("abcde")); + test(S("abcde"), 1, SV("12345678901234567890"), 20, 1, S("abcde")); + test(S("abcde"), 1, SV("12345678901234567890"), 21, 0, S("can't happen")); + test(S("abcde"), 2, SV(""), 0, 0, S("abcde")); + test(S("abcde"), 2, SV(""), 0, 1, S("abcde")); + test(S("abcde"), 2, SV(""), 1, 0, S("can't happen")); + test(S("abcde"), 2, SV("12345"), 0, 0, S("abcde")); +} + +template +void test6() +{ + test(S("abcde"), 2, SV("12345"), 0, 1, S("ab1cde")); + test(S("abcde"), 2, SV("12345"), 0, 2, S("ab12cde")); + test(S("abcde"), 2, SV("12345"), 0, 4, S("ab1234cde")); + test(S("abcde"), 2, SV("12345"), 0, 5, S("ab12345cde")); + test(S("abcde"), 2, SV("12345"), 0, 6, S("ab12345cde")); + test(S("abcde"), 2, SV("12345"), 1, 0, S("abcde")); + test(S("abcde"), 2, SV("12345"), 1, 1, S("ab2cde")); + test(S("abcde"), 2, SV("12345"), 1, 2, S("ab23cde")); + test(S("abcde"), 2, SV("12345"), 1, 3, S("ab234cde")); + test(S("abcde"), 2, SV("12345"), 1, 4, S("ab2345cde")); + test(S("abcde"), 2, SV("12345"), 1, 5, S("ab2345cde")); + test(S("abcde"), 2, SV("12345"), 2, 0, S("abcde")); + test(S("abcde"), 2, SV("12345"), 2, 1, S("ab3cde")); + test(S("abcde"), 2, SV("12345"), 2, 2, S("ab34cde")); + test(S("abcde"), 2, SV("12345"), 2, 3, S("ab345cde")); + test(S("abcde"), 2, SV("12345"), 2, 4, S("ab345cde")); + test(S("abcde"), 2, SV("12345"), 4, 0, S("abcde")); + test(S("abcde"), 2, SV("12345"), 4, 1, S("ab5cde")); + test(S("abcde"), 2, SV("12345"), 4, 2, S("ab5cde")); + test(S("abcde"), 2, SV("12345"), 5, 0, S("abcde")); + test(S("abcde"), 2, SV("12345"), 5, 1, S("abcde")); + test(S("abcde"), 2, SV("12345"), 6, 0, S("can't happen")); + test(S("abcde"), 2, SV("1234567890"), 0, 0, S("abcde")); + test(S("abcde"), 2, SV("1234567890"), 0, 1, S("ab1cde")); + test(S("abcde"), 2, SV("1234567890"), 0, 5, S("ab12345cde")); + test(S("abcde"), 2, SV("1234567890"), 0, 9, S("ab123456789cde")); + test(S("abcde"), 2, SV("1234567890"), 0, 10, S("ab1234567890cde")); + test(S("abcde"), 2, SV("1234567890"), 0, 11, S("ab1234567890cde")); + test(S("abcde"), 2, SV("1234567890"), 1, 0, S("abcde")); + test(S("abcde"), 2, SV("1234567890"), 1, 1, S("ab2cde")); + test(S("abcde"), 2, SV("1234567890"), 1, 4, S("ab2345cde")); + test(S("abcde"), 2, SV("1234567890"), 1, 8, S("ab23456789cde")); + test(S("abcde"), 2, SV("1234567890"), 1, 9, S("ab234567890cde")); + test(S("abcde"), 2, SV("1234567890"), 1, 10, S("ab234567890cde")); + test(S("abcde"), 2, SV("1234567890"), 5, 0, S("abcde")); + test(S("abcde"), 2, SV("1234567890"), 5, 1, S("ab6cde")); + test(S("abcde"), 2, SV("1234567890"), 5, 2, S("ab67cde")); + test(S("abcde"), 2, SV("1234567890"), 5, 4, S("ab6789cde")); + test(S("abcde"), 2, SV("1234567890"), 5, 5, S("ab67890cde")); + test(S("abcde"), 2, SV("1234567890"), 5, 6, S("ab67890cde")); + test(S("abcde"), 2, SV("1234567890"), 9, 0, S("abcde")); + test(S("abcde"), 2, SV("1234567890"), 9, 1, S("ab0cde")); + test(S("abcde"), 2, SV("1234567890"), 9, 2, S("ab0cde")); + test(S("abcde"), 2, SV("1234567890"), 10, 0, S("abcde")); + test(S("abcde"), 2, SV("1234567890"), 10, 1, S("abcde")); + test(S("abcde"), 2, SV("1234567890"), 11, 0, S("can't happen")); + test(S("abcde"), 2, SV("12345678901234567890"), 0, 0, S("abcde")); + test(S("abcde"), 2, SV("12345678901234567890"), 0, 1, S("ab1cde")); + test(S("abcde"), 2, SV("12345678901234567890"), 0, 10, S("ab1234567890cde")); + test(S("abcde"), 2, SV("12345678901234567890"), 0, 19, S("ab1234567890123456789cde")); +} + +template +void test7() +{ + test(S("abcde"), 2, SV("12345678901234567890"), 0, 20, S("ab12345678901234567890cde")); + test(S("abcde"), 2, SV("12345678901234567890"), 0, 21, S("ab12345678901234567890cde")); + test(S("abcde"), 2, SV("12345678901234567890"), 1, 0, S("abcde")); + test(S("abcde"), 2, SV("12345678901234567890"), 1, 1, S("ab2cde")); + test(S("abcde"), 2, SV("12345678901234567890"), 1, 9, S("ab234567890cde")); + test(S("abcde"), 2, SV("12345678901234567890"), 1, 18, S("ab234567890123456789cde")); + test(S("abcde"), 2, SV("12345678901234567890"), 1, 19, S("ab2345678901234567890cde")); + test(S("abcde"), 2, SV("12345678901234567890"), 1, 20, S("ab2345678901234567890cde")); + test(S("abcde"), 2, SV("12345678901234567890"), 10, 0, S("abcde")); + test(S("abcde"), 2, SV("12345678901234567890"), 10, 1, S("ab1cde")); + test(S("abcde"), 2, SV("12345678901234567890"), 10, 5, S("ab12345cde")); + test(S("abcde"), 2, SV("12345678901234567890"), 10, 9, S("ab123456789cde")); + test(S("abcde"), 2, SV("12345678901234567890"), 10, 10, S("ab1234567890cde")); + test(S("abcde"), 2, SV("12345678901234567890"), 10, 11, S("ab1234567890cde")); + test(S("abcde"), 2, SV("12345678901234567890"), 19, 0, S("abcde")); + test(S("abcde"), 2, SV("12345678901234567890"), 19, 1, S("ab0cde")); + test(S("abcde"), 2, SV("12345678901234567890"), 19, 2, S("ab0cde")); + test(S("abcde"), 2, SV("12345678901234567890"), 20, 0, S("abcde")); + test(S("abcde"), 2, SV("12345678901234567890"), 20, 1, S("abcde")); + test(S("abcde"), 2, SV("12345678901234567890"), 21, 0, S("can't happen")); + test(S("abcde"), 4, SV(""), 0, 0, S("abcde")); + test(S("abcde"), 4, SV(""), 0, 1, S("abcde")); + test(S("abcde"), 4, SV(""), 1, 0, S("can't happen")); + test(S("abcde"), 4, SV("12345"), 0, 0, S("abcde")); + test(S("abcde"), 4, SV("12345"), 0, 1, S("abcd1e")); + test(S("abcde"), 4, SV("12345"), 0, 2, S("abcd12e")); + test(S("abcde"), 4, SV("12345"), 0, 4, S("abcd1234e")); + test(S("abcde"), 4, SV("12345"), 0, 5, S("abcd12345e")); + test(S("abcde"), 4, SV("12345"), 0, 6, S("abcd12345e")); + test(S("abcde"), 4, SV("12345"), 1, 0, S("abcde")); + test(S("abcde"), 4, SV("12345"), 1, 1, S("abcd2e")); + test(S("abcde"), 4, SV("12345"), 1, 2, S("abcd23e")); + test(S("abcde"), 4, SV("12345"), 1, 3, S("abcd234e")); + test(S("abcde"), 4, SV("12345"), 1, 4, S("abcd2345e")); + test(S("abcde"), 4, SV("12345"), 1, 5, S("abcd2345e")); + test(S("abcde"), 4, SV("12345"), 2, 0, S("abcde")); + test(S("abcde"), 4, SV("12345"), 2, 1, S("abcd3e")); + test(S("abcde"), 4, SV("12345"), 2, 2, S("abcd34e")); + test(S("abcde"), 4, SV("12345"), 2, 3, S("abcd345e")); + test(S("abcde"), 4, SV("12345"), 2, 4, S("abcd345e")); + test(S("abcde"), 4, SV("12345"), 4, 0, S("abcde")); + test(S("abcde"), 4, SV("12345"), 4, 1, S("abcd5e")); + test(S("abcde"), 4, SV("12345"), 4, 2, S("abcd5e")); + test(S("abcde"), 4, SV("12345"), 5, 0, S("abcde")); + test(S("abcde"), 4, SV("12345"), 5, 1, S("abcde")); + test(S("abcde"), 4, SV("12345"), 6, 0, S("can't happen")); + test(S("abcde"), 4, SV("1234567890"), 0, 0, S("abcde")); + test(S("abcde"), 4, SV("1234567890"), 0, 1, S("abcd1e")); + test(S("abcde"), 4, SV("1234567890"), 0, 5, S("abcd12345e")); + test(S("abcde"), 4, SV("1234567890"), 0, 9, S("abcd123456789e")); +} + +template +void test8() +{ + test(S("abcde"), 4, SV("1234567890"), 0, 10, S("abcd1234567890e")); + test(S("abcde"), 4, SV("1234567890"), 0, 11, S("abcd1234567890e")); + test(S("abcde"), 4, SV("1234567890"), 1, 0, S("abcde")); + test(S("abcde"), 4, SV("1234567890"), 1, 1, S("abcd2e")); + test(S("abcde"), 4, SV("1234567890"), 1, 4, S("abcd2345e")); + test(S("abcde"), 4, SV("1234567890"), 1, 8, S("abcd23456789e")); + test(S("abcde"), 4, SV("1234567890"), 1, 9, S("abcd234567890e")); + test(S("abcde"), 4, SV("1234567890"), 1, 10, S("abcd234567890e")); + test(S("abcde"), 4, SV("1234567890"), 5, 0, S("abcde")); + test(S("abcde"), 4, SV("1234567890"), 5, 1, S("abcd6e")); + test(S("abcde"), 4, SV("1234567890"), 5, 2, S("abcd67e")); + test(S("abcde"), 4, SV("1234567890"), 5, 4, S("abcd6789e")); + test(S("abcde"), 4, SV("1234567890"), 5, 5, S("abcd67890e")); + test(S("abcde"), 4, SV("1234567890"), 5, 6, S("abcd67890e")); + test(S("abcde"), 4, SV("1234567890"), 9, 0, S("abcde")); + test(S("abcde"), 4, SV("1234567890"), 9, 1, S("abcd0e")); + test(S("abcde"), 4, SV("1234567890"), 9, 2, S("abcd0e")); + test(S("abcde"), 4, SV("1234567890"), 10, 0, S("abcde")); + test(S("abcde"), 4, SV("1234567890"), 10, 1, S("abcde")); + test(S("abcde"), 4, SV("1234567890"), 11, 0, S("can't happen")); + test(S("abcde"), 4, SV("12345678901234567890"), 0, 0, S("abcde")); + test(S("abcde"), 4, SV("12345678901234567890"), 0, 1, S("abcd1e")); + test(S("abcde"), 4, SV("12345678901234567890"), 0, 10, S("abcd1234567890e")); + test(S("abcde"), 4, SV("12345678901234567890"), 0, 19, S("abcd1234567890123456789e")); + test(S("abcde"), 4, SV("12345678901234567890"), 0, 20, S("abcd12345678901234567890e")); + test(S("abcde"), 4, SV("12345678901234567890"), 0, 21, S("abcd12345678901234567890e")); + test(S("abcde"), 4, SV("12345678901234567890"), 1, 0, S("abcde")); + test(S("abcde"), 4, SV("12345678901234567890"), 1, 1, S("abcd2e")); + test(S("abcde"), 4, SV("12345678901234567890"), 1, 9, S("abcd234567890e")); + test(S("abcde"), 4, SV("12345678901234567890"), 1, 18, S("abcd234567890123456789e")); + test(S("abcde"), 4, SV("12345678901234567890"), 1, 19, S("abcd2345678901234567890e")); + test(S("abcde"), 4, SV("12345678901234567890"), 1, 20, S("abcd2345678901234567890e")); + test(S("abcde"), 4, SV("12345678901234567890"), 10, 0, S("abcde")); + test(S("abcde"), 4, SV("12345678901234567890"), 10, 1, S("abcd1e")); + test(S("abcde"), 4, SV("12345678901234567890"), 10, 5, S("abcd12345e")); + test(S("abcde"), 4, SV("12345678901234567890"), 10, 9, S("abcd123456789e")); + test(S("abcde"), 4, SV("12345678901234567890"), 10, 10, S("abcd1234567890e")); + test(S("abcde"), 4, SV("12345678901234567890"), 10, 11, S("abcd1234567890e")); + test(S("abcde"), 4, SV("12345678901234567890"), 19, 0, S("abcde")); + test(S("abcde"), 4, SV("12345678901234567890"), 19, 1, S("abcd0e")); + test(S("abcde"), 4, SV("12345678901234567890"), 19, 2, S("abcd0e")); + test(S("abcde"), 4, SV("12345678901234567890"), 20, 0, S("abcde")); + test(S("abcde"), 4, SV("12345678901234567890"), 20, 1, S("abcde")); + test(S("abcde"), 4, SV("12345678901234567890"), 21, 0, S("can't happen")); + test(S("abcde"), 5, SV(""), 0, 0, S("abcde")); + test(S("abcde"), 5, SV(""), 0, 1, S("abcde")); + test(S("abcde"), 5, SV(""), 1, 0, S("can't happen")); + test(S("abcde"), 5, SV("12345"), 0, 0, S("abcde")); + test(S("abcde"), 5, SV("12345"), 0, 1, S("abcde1")); + test(S("abcde"), 5, SV("12345"), 0, 2, S("abcde12")); +} + +template +void test9() +{ + test(S("abcde"), 5, SV("12345"), 0, 4, S("abcde1234")); + test(S("abcde"), 5, SV("12345"), 0, 5, S("abcde12345")); + test(S("abcde"), 5, SV("12345"), 0, 6, S("abcde12345")); + test(S("abcde"), 5, SV("12345"), 1, 0, S("abcde")); + test(S("abcde"), 5, SV("12345"), 1, 1, S("abcde2")); + test(S("abcde"), 5, SV("12345"), 1, 2, S("abcde23")); + test(S("abcde"), 5, SV("12345"), 1, 3, S("abcde234")); + test(S("abcde"), 5, SV("12345"), 1, 4, S("abcde2345")); + test(S("abcde"), 5, SV("12345"), 1, 5, S("abcde2345")); + test(S("abcde"), 5, SV("12345"), 2, 0, S("abcde")); + test(S("abcde"), 5, SV("12345"), 2, 1, S("abcde3")); + test(S("abcde"), 5, SV("12345"), 2, 2, S("abcde34")); + test(S("abcde"), 5, SV("12345"), 2, 3, S("abcde345")); + test(S("abcde"), 5, SV("12345"), 2, 4, S("abcde345")); + test(S("abcde"), 5, SV("12345"), 4, 0, S("abcde")); + test(S("abcde"), 5, SV("12345"), 4, 1, S("abcde5")); + test(S("abcde"), 5, SV("12345"), 4, 2, S("abcde5")); + test(S("abcde"), 5, SV("12345"), 5, 0, S("abcde")); + test(S("abcde"), 5, SV("12345"), 5, 1, S("abcde")); + test(S("abcde"), 5, SV("12345"), 6, 0, S("can't happen")); + test(S("abcde"), 5, SV("1234567890"), 0, 0, S("abcde")); + test(S("abcde"), 5, SV("1234567890"), 0, 1, S("abcde1")); + test(S("abcde"), 5, SV("1234567890"), 0, 5, S("abcde12345")); + test(S("abcde"), 5, SV("1234567890"), 0, 9, S("abcde123456789")); + test(S("abcde"), 5, SV("1234567890"), 0, 10, S("abcde1234567890")); + test(S("abcde"), 5, SV("1234567890"), 0, 11, S("abcde1234567890")); + test(S("abcde"), 5, SV("1234567890"), 1, 0, S("abcde")); + test(S("abcde"), 5, SV("1234567890"), 1, 1, S("abcde2")); + test(S("abcde"), 5, SV("1234567890"), 1, 4, S("abcde2345")); + test(S("abcde"), 5, SV("1234567890"), 1, 8, S("abcde23456789")); + test(S("abcde"), 5, SV("1234567890"), 1, 9, S("abcde234567890")); + test(S("abcde"), 5, SV("1234567890"), 1, 10, S("abcde234567890")); + test(S("abcde"), 5, SV("1234567890"), 5, 0, S("abcde")); + test(S("abcde"), 5, SV("1234567890"), 5, 1, S("abcde6")); + test(S("abcde"), 5, SV("1234567890"), 5, 2, S("abcde67")); + test(S("abcde"), 5, SV("1234567890"), 5, 4, S("abcde6789")); + test(S("abcde"), 5, SV("1234567890"), 5, 5, S("abcde67890")); + test(S("abcde"), 5, SV("1234567890"), 5, 6, S("abcde67890")); + test(S("abcde"), 5, SV("1234567890"), 9, 0, S("abcde")); + test(S("abcde"), 5, SV("1234567890"), 9, 1, S("abcde0")); + test(S("abcde"), 5, SV("1234567890"), 9, 2, S("abcde0")); + test(S("abcde"), 5, SV("1234567890"), 10, 0, S("abcde")); + test(S("abcde"), 5, SV("1234567890"), 10, 1, S("abcde")); + test(S("abcde"), 5, SV("1234567890"), 11, 0, S("can't happen")); + test(S("abcde"), 5, SV("12345678901234567890"), 0, 0, S("abcde")); + test(S("abcde"), 5, SV("12345678901234567890"), 0, 1, S("abcde1")); + test(S("abcde"), 5, SV("12345678901234567890"), 0, 10, S("abcde1234567890")); + test(S("abcde"), 5, SV("12345678901234567890"), 0, 19, S("abcde1234567890123456789")); + test(S("abcde"), 5, SV("12345678901234567890"), 0, 20, S("abcde12345678901234567890")); + test(S("abcde"), 5, SV("12345678901234567890"), 0, 21, S("abcde12345678901234567890")); +} + +template +void test10() +{ + test(S("abcde"), 5, SV("12345678901234567890"), 1, 0, S("abcde")); + test(S("abcde"), 5, SV("12345678901234567890"), 1, 1, S("abcde2")); + test(S("abcde"), 5, SV("12345678901234567890"), 1, 9, S("abcde234567890")); + test(S("abcde"), 5, SV("12345678901234567890"), 1, 18, S("abcde234567890123456789")); + test(S("abcde"), 5, SV("12345678901234567890"), 1, 19, S("abcde2345678901234567890")); + test(S("abcde"), 5, SV("12345678901234567890"), 1, 20, S("abcde2345678901234567890")); + test(S("abcde"), 5, SV("12345678901234567890"), 10, 0, S("abcde")); + test(S("abcde"), 5, SV("12345678901234567890"), 10, 1, S("abcde1")); + test(S("abcde"), 5, SV("12345678901234567890"), 10, 5, S("abcde12345")); + test(S("abcde"), 5, SV("12345678901234567890"), 10, 9, S("abcde123456789")); + test(S("abcde"), 5, SV("12345678901234567890"), 10, 10, S("abcde1234567890")); + test(S("abcde"), 5, SV("12345678901234567890"), 10, 11, S("abcde1234567890")); + test(S("abcde"), 5, SV("12345678901234567890"), 19, 0, S("abcde")); + test(S("abcde"), 5, SV("12345678901234567890"), 19, 1, S("abcde0")); + test(S("abcde"), 5, SV("12345678901234567890"), 19, 2, S("abcde0")); + test(S("abcde"), 5, SV("12345678901234567890"), 20, 0, S("abcde")); + test(S("abcde"), 5, SV("12345678901234567890"), 20, 1, S("abcde")); + test(S("abcde"), 5, SV("12345678901234567890"), 21, 0, S("can't happen")); + test(S("abcde"), 6, SV(""), 0, 0, S("can't happen")); + test(S("abcde"), 6, SV(""), 0, 1, S("can't happen")); + test(S("abcde"), 6, SV(""), 1, 0, S("can't happen")); + test(S("abcde"), 6, SV("12345"), 0, 0, S("can't happen")); + test(S("abcde"), 6, SV("12345"), 0, 1, S("can't happen")); + test(S("abcde"), 6, SV("12345"), 0, 2, S("can't happen")); + test(S("abcde"), 6, SV("12345"), 0, 4, S("can't happen")); + test(S("abcde"), 6, SV("12345"), 0, 5, S("can't happen")); + test(S("abcde"), 6, SV("12345"), 0, 6, S("can't happen")); + test(S("abcde"), 6, SV("12345"), 1, 0, S("can't happen")); + test(S("abcde"), 6, SV("12345"), 1, 1, S("can't happen")); + test(S("abcde"), 6, SV("12345"), 1, 2, S("can't happen")); + test(S("abcde"), 6, SV("12345"), 1, 3, S("can't happen")); + test(S("abcde"), 6, SV("12345"), 1, 4, S("can't happen")); + test(S("abcde"), 6, SV("12345"), 1, 5, S("can't happen")); + test(S("abcde"), 6, SV("12345"), 2, 0, S("can't happen")); + test(S("abcde"), 6, SV("12345"), 2, 1, S("can't happen")); + test(S("abcde"), 6, SV("12345"), 2, 2, S("can't happen")); + test(S("abcde"), 6, SV("12345"), 2, 3, S("can't happen")); + test(S("abcde"), 6, SV("12345"), 2, 4, S("can't happen")); + test(S("abcde"), 6, SV("12345"), 4, 0, S("can't happen")); + test(S("abcde"), 6, SV("12345"), 4, 1, S("can't happen")); + test(S("abcde"), 6, SV("12345"), 4, 2, S("can't happen")); + test(S("abcde"), 6, SV("12345"), 5, 0, S("can't happen")); + test(S("abcde"), 6, SV("12345"), 5, 1, S("can't happen")); + test(S("abcde"), 6, SV("12345"), 6, 0, S("can't happen")); + test(S("abcde"), 6, SV("1234567890"), 0, 0, S("can't happen")); + test(S("abcde"), 6, SV("1234567890"), 0, 1, S("can't happen")); + test(S("abcde"), 6, SV("1234567890"), 0, 5, S("can't happen")); + test(S("abcde"), 6, SV("1234567890"), 0, 9, S("can't happen")); + test(S("abcde"), 6, SV("1234567890"), 0, 10, S("can't happen")); + test(S("abcde"), 6, SV("1234567890"), 0, 11, S("can't happen")); +} + +template +void test11() +{ + test(S("abcde"), 6, SV("1234567890"), 1, 0, S("can't happen")); + test(S("abcde"), 6, SV("1234567890"), 1, 1, S("can't happen")); + test(S("abcde"), 6, SV("1234567890"), 1, 4, S("can't happen")); + test(S("abcde"), 6, SV("1234567890"), 1, 8, S("can't happen")); + test(S("abcde"), 6, SV("1234567890"), 1, 9, S("can't happen")); + test(S("abcde"), 6, SV("1234567890"), 1, 10, S("can't happen")); + test(S("abcde"), 6, SV("1234567890"), 5, 0, S("can't happen")); + test(S("abcde"), 6, SV("1234567890"), 5, 1, S("can't happen")); + test(S("abcde"), 6, SV("1234567890"), 5, 2, S("can't happen")); + test(S("abcde"), 6, SV("1234567890"), 5, 4, S("can't happen")); + test(S("abcde"), 6, SV("1234567890"), 5, 5, S("can't happen")); + test(S("abcde"), 6, SV("1234567890"), 5, 6, S("can't happen")); + test(S("abcde"), 6, SV("1234567890"), 9, 0, S("can't happen")); + test(S("abcde"), 6, SV("1234567890"), 9, 1, S("can't happen")); + test(S("abcde"), 6, SV("1234567890"), 9, 2, S("can't happen")); + test(S("abcde"), 6, SV("1234567890"), 10, 0, S("can't happen")); + test(S("abcde"), 6, SV("1234567890"), 10, 1, S("can't happen")); + test(S("abcde"), 6, SV("1234567890"), 11, 0, S("can't happen")); + test(S("abcde"), 6, SV("12345678901234567890"), 0, 0, S("can't happen")); + test(S("abcde"), 6, SV("12345678901234567890"), 0, 1, S("can't happen")); + test(S("abcde"), 6, SV("12345678901234567890"), 0, 10, S("can't happen")); + test(S("abcde"), 6, SV("12345678901234567890"), 0, 19, S("can't happen")); + test(S("abcde"), 6, SV("12345678901234567890"), 0, 20, S("can't happen")); + test(S("abcde"), 6, SV("12345678901234567890"), 0, 21, S("can't happen")); + test(S("abcde"), 6, SV("12345678901234567890"), 1, 0, S("can't happen")); + test(S("abcde"), 6, SV("12345678901234567890"), 1, 1, S("can't happen")); + test(S("abcde"), 6, SV("12345678901234567890"), 1, 9, S("can't happen")); + test(S("abcde"), 6, SV("12345678901234567890"), 1, 18, S("can't happen")); + test(S("abcde"), 6, SV("12345678901234567890"), 1, 19, S("can't happen")); + test(S("abcde"), 6, SV("12345678901234567890"), 1, 20, S("can't happen")); + test(S("abcde"), 6, SV("12345678901234567890"), 10, 0, S("can't happen")); + test(S("abcde"), 6, SV("12345678901234567890"), 10, 1, S("can't happen")); + test(S("abcde"), 6, SV("12345678901234567890"), 10, 5, S("can't happen")); + test(S("abcde"), 6, SV("12345678901234567890"), 10, 9, S("can't happen")); + test(S("abcde"), 6, SV("12345678901234567890"), 10, 10, S("can't happen")); + test(S("abcde"), 6, SV("12345678901234567890"), 10, 11, S("can't happen")); + test(S("abcde"), 6, SV("12345678901234567890"), 19, 0, S("can't happen")); + test(S("abcde"), 6, SV("12345678901234567890"), 19, 1, S("can't happen")); + test(S("abcde"), 6, SV("12345678901234567890"), 19, 2, S("can't happen")); + test(S("abcde"), 6, SV("12345678901234567890"), 20, 0, S("can't happen")); + test(S("abcde"), 6, SV("12345678901234567890"), 20, 1, S("can't happen")); + test(S("abcde"), 6, SV("12345678901234567890"), 21, 0, S("can't happen")); + test(S("abcdefghij"), 0, SV(""), 0, 0, S("abcdefghij")); + test(S("abcdefghij"), 0, SV(""), 0, 1, S("abcdefghij")); + test(S("abcdefghij"), 0, SV(""), 1, 0, S("can't happen")); + test(S("abcdefghij"), 0, SV("12345"), 0, 0, S("abcdefghij")); + test(S("abcdefghij"), 0, SV("12345"), 0, 1, S("1abcdefghij")); + test(S("abcdefghij"), 0, SV("12345"), 0, 2, S("12abcdefghij")); + test(S("abcdefghij"), 0, SV("12345"), 0, 4, S("1234abcdefghij")); + test(S("abcdefghij"), 0, SV("12345"), 0, 5, S("12345abcdefghij")); +} + +template +void test12() +{ + test(S("abcdefghij"), 0, SV("12345"), 0, 6, S("12345abcdefghij")); + test(S("abcdefghij"), 0, SV("12345"), 1, 0, S("abcdefghij")); + test(S("abcdefghij"), 0, SV("12345"), 1, 1, S("2abcdefghij")); + test(S("abcdefghij"), 0, SV("12345"), 1, 2, S("23abcdefghij")); + test(S("abcdefghij"), 0, SV("12345"), 1, 3, S("234abcdefghij")); + test(S("abcdefghij"), 0, SV("12345"), 1, 4, S("2345abcdefghij")); + test(S("abcdefghij"), 0, SV("12345"), 1, 5, S("2345abcdefghij")); + test(S("abcdefghij"), 0, SV("12345"), 2, 0, S("abcdefghij")); + test(S("abcdefghij"), 0, SV("12345"), 2, 1, S("3abcdefghij")); + test(S("abcdefghij"), 0, SV("12345"), 2, 2, S("34abcdefghij")); + test(S("abcdefghij"), 0, SV("12345"), 2, 3, S("345abcdefghij")); + test(S("abcdefghij"), 0, SV("12345"), 2, 4, S("345abcdefghij")); + test(S("abcdefghij"), 0, SV("12345"), 4, 0, S("abcdefghij")); + test(S("abcdefghij"), 0, SV("12345"), 4, 1, S("5abcdefghij")); + test(S("abcdefghij"), 0, SV("12345"), 4, 2, S("5abcdefghij")); + test(S("abcdefghij"), 0, SV("12345"), 5, 0, S("abcdefghij")); + test(S("abcdefghij"), 0, SV("12345"), 5, 1, S("abcdefghij")); + test(S("abcdefghij"), 0, SV("12345"), 6, 0, S("can't happen")); + test(S("abcdefghij"), 0, SV("1234567890"), 0, 0, S("abcdefghij")); + test(S("abcdefghij"), 0, SV("1234567890"), 0, 1, S("1abcdefghij")); + test(S("abcdefghij"), 0, SV("1234567890"), 0, 5, S("12345abcdefghij")); + test(S("abcdefghij"), 0, SV("1234567890"), 0, 9, S("123456789abcdefghij")); + test(S("abcdefghij"), 0, SV("1234567890"), 0, 10, S("1234567890abcdefghij")); + test(S("abcdefghij"), 0, SV("1234567890"), 0, 11, S("1234567890abcdefghij")); + test(S("abcdefghij"), 0, SV("1234567890"), 1, 0, S("abcdefghij")); + test(S("abcdefghij"), 0, SV("1234567890"), 1, 1, S("2abcdefghij")); + test(S("abcdefghij"), 0, SV("1234567890"), 1, 4, S("2345abcdefghij")); + test(S("abcdefghij"), 0, SV("1234567890"), 1, 8, S("23456789abcdefghij")); + test(S("abcdefghij"), 0, SV("1234567890"), 1, 9, S("234567890abcdefghij")); + test(S("abcdefghij"), 0, SV("1234567890"), 1, 10, S("234567890abcdefghij")); + test(S("abcdefghij"), 0, SV("1234567890"), 5, 0, S("abcdefghij")); + test(S("abcdefghij"), 0, SV("1234567890"), 5, 1, S("6abcdefghij")); + test(S("abcdefghij"), 0, SV("1234567890"), 5, 2, S("67abcdefghij")); + test(S("abcdefghij"), 0, SV("1234567890"), 5, 4, S("6789abcdefghij")); + test(S("abcdefghij"), 0, SV("1234567890"), 5, 5, S("67890abcdefghij")); + test(S("abcdefghij"), 0, SV("1234567890"), 5, 6, S("67890abcdefghij")); + test(S("abcdefghij"), 0, SV("1234567890"), 9, 0, S("abcdefghij")); + test(S("abcdefghij"), 0, SV("1234567890"), 9, 1, S("0abcdefghij")); + test(S("abcdefghij"), 0, SV("1234567890"), 9, 2, S("0abcdefghij")); + test(S("abcdefghij"), 0, SV("1234567890"), 10, 0, S("abcdefghij")); + test(S("abcdefghij"), 0, SV("1234567890"), 10, 1, S("abcdefghij")); + test(S("abcdefghij"), 0, SV("1234567890"), 11, 0, S("can't happen")); + test(S("abcdefghij"), 0, SV("12345678901234567890"), 0, 0, S("abcdefghij")); + test(S("abcdefghij"), 0, SV("12345678901234567890"), 0, 1, S("1abcdefghij")); + test(S("abcdefghij"), 0, SV("12345678901234567890"), 0, 10, S("1234567890abcdefghij")); + test(S("abcdefghij"), 0, SV("12345678901234567890"), 0, 19, S("1234567890123456789abcdefghij")); + test(S("abcdefghij"), 0, SV("12345678901234567890"), 0, 20, S("12345678901234567890abcdefghij")); + test(S("abcdefghij"), 0, SV("12345678901234567890"), 0, 21, S("12345678901234567890abcdefghij")); + test(S("abcdefghij"), 0, SV("12345678901234567890"), 1, 0, S("abcdefghij")); + test(S("abcdefghij"), 0, SV("12345678901234567890"), 1, 1, S("2abcdefghij")); +} + +template +void test13() +{ + test(S("abcdefghij"), 0, SV("12345678901234567890"), 1, 9, S("234567890abcdefghij")); + test(S("abcdefghij"), 0, SV("12345678901234567890"), 1, 18, S("234567890123456789abcdefghij")); + test(S("abcdefghij"), 0, SV("12345678901234567890"), 1, 19, S("2345678901234567890abcdefghij")); + test(S("abcdefghij"), 0, SV("12345678901234567890"), 1, 20, S("2345678901234567890abcdefghij")); + test(S("abcdefghij"), 0, SV("12345678901234567890"), 10, 0, S("abcdefghij")); + test(S("abcdefghij"), 0, SV("12345678901234567890"), 10, 1, S("1abcdefghij")); + test(S("abcdefghij"), 0, SV("12345678901234567890"), 10, 5, S("12345abcdefghij")); + test(S("abcdefghij"), 0, SV("12345678901234567890"), 10, 9, S("123456789abcdefghij")); + test(S("abcdefghij"), 0, SV("12345678901234567890"), 10, 10, S("1234567890abcdefghij")); + test(S("abcdefghij"), 0, SV("12345678901234567890"), 10, 11, S("1234567890abcdefghij")); + test(S("abcdefghij"), 0, SV("12345678901234567890"), 19, 0, S("abcdefghij")); + test(S("abcdefghij"), 0, SV("12345678901234567890"), 19, 1, S("0abcdefghij")); + test(S("abcdefghij"), 0, SV("12345678901234567890"), 19, 2, S("0abcdefghij")); + test(S("abcdefghij"), 0, SV("12345678901234567890"), 20, 0, S("abcdefghij")); + test(S("abcdefghij"), 0, SV("12345678901234567890"), 20, 1, S("abcdefghij")); + test(S("abcdefghij"), 0, SV("12345678901234567890"), 21, 0, S("can't happen")); + test(S("abcdefghij"), 1, SV(""), 0, 0, S("abcdefghij")); + test(S("abcdefghij"), 1, SV(""), 0, 1, S("abcdefghij")); + test(S("abcdefghij"), 1, SV(""), 1, 0, S("can't happen")); + test(S("abcdefghij"), 1, SV("12345"), 0, 0, S("abcdefghij")); + test(S("abcdefghij"), 1, SV("12345"), 0, 1, S("a1bcdefghij")); + test(S("abcdefghij"), 1, SV("12345"), 0, 2, S("a12bcdefghij")); + test(S("abcdefghij"), 1, SV("12345"), 0, 4, S("a1234bcdefghij")); + test(S("abcdefghij"), 1, SV("12345"), 0, 5, S("a12345bcdefghij")); + test(S("abcdefghij"), 1, SV("12345"), 0, 6, S("a12345bcdefghij")); + test(S("abcdefghij"), 1, SV("12345"), 1, 0, S("abcdefghij")); + test(S("abcdefghij"), 1, SV("12345"), 1, 1, S("a2bcdefghij")); + test(S("abcdefghij"), 1, SV("12345"), 1, 2, S("a23bcdefghij")); + test(S("abcdefghij"), 1, SV("12345"), 1, 3, S("a234bcdefghij")); + test(S("abcdefghij"), 1, SV("12345"), 1, 4, S("a2345bcdefghij")); + test(S("abcdefghij"), 1, SV("12345"), 1, 5, S("a2345bcdefghij")); + test(S("abcdefghij"), 1, SV("12345"), 2, 0, S("abcdefghij")); + test(S("abcdefghij"), 1, SV("12345"), 2, 1, S("a3bcdefghij")); + test(S("abcdefghij"), 1, SV("12345"), 2, 2, S("a34bcdefghij")); + test(S("abcdefghij"), 1, SV("12345"), 2, 3, S("a345bcdefghij")); + test(S("abcdefghij"), 1, SV("12345"), 2, 4, S("a345bcdefghij")); + test(S("abcdefghij"), 1, SV("12345"), 4, 0, S("abcdefghij")); + test(S("abcdefghij"), 1, SV("12345"), 4, 1, S("a5bcdefghij")); + test(S("abcdefghij"), 1, SV("12345"), 4, 2, S("a5bcdefghij")); + test(S("abcdefghij"), 1, SV("12345"), 5, 0, S("abcdefghij")); + test(S("abcdefghij"), 1, SV("12345"), 5, 1, S("abcdefghij")); + test(S("abcdefghij"), 1, SV("12345"), 6, 0, S("can't happen")); + test(S("abcdefghij"), 1, SV("1234567890"), 0, 0, S("abcdefghij")); + test(S("abcdefghij"), 1, SV("1234567890"), 0, 1, S("a1bcdefghij")); + test(S("abcdefghij"), 1, SV("1234567890"), 0, 5, S("a12345bcdefghij")); + test(S("abcdefghij"), 1, SV("1234567890"), 0, 9, S("a123456789bcdefghij")); + test(S("abcdefghij"), 1, SV("1234567890"), 0, 10, S("a1234567890bcdefghij")); + test(S("abcdefghij"), 1, SV("1234567890"), 0, 11, S("a1234567890bcdefghij")); + test(S("abcdefghij"), 1, SV("1234567890"), 1, 0, S("abcdefghij")); + test(S("abcdefghij"), 1, SV("1234567890"), 1, 1, S("a2bcdefghij")); +} + +template +void test14() +{ + test(S("abcdefghij"), 1, SV("1234567890"), 1, 4, S("a2345bcdefghij")); + test(S("abcdefghij"), 1, SV("1234567890"), 1, 8, S("a23456789bcdefghij")); + test(S("abcdefghij"), 1, SV("1234567890"), 1, 9, S("a234567890bcdefghij")); + test(S("abcdefghij"), 1, SV("1234567890"), 1, 10, S("a234567890bcdefghij")); + test(S("abcdefghij"), 1, SV("1234567890"), 5, 0, S("abcdefghij")); + test(S("abcdefghij"), 1, SV("1234567890"), 5, 1, S("a6bcdefghij")); + test(S("abcdefghij"), 1, SV("1234567890"), 5, 2, S("a67bcdefghij")); + test(S("abcdefghij"), 1, SV("1234567890"), 5, 4, S("a6789bcdefghij")); + test(S("abcdefghij"), 1, SV("1234567890"), 5, 5, S("a67890bcdefghij")); + test(S("abcdefghij"), 1, SV("1234567890"), 5, 6, S("a67890bcdefghij")); + test(S("abcdefghij"), 1, SV("1234567890"), 9, 0, S("abcdefghij")); + test(S("abcdefghij"), 1, SV("1234567890"), 9, 1, S("a0bcdefghij")); + test(S("abcdefghij"), 1, SV("1234567890"), 9, 2, S("a0bcdefghij")); + test(S("abcdefghij"), 1, SV("1234567890"), 10, 0, S("abcdefghij")); + test(S("abcdefghij"), 1, SV("1234567890"), 10, 1, S("abcdefghij")); + test(S("abcdefghij"), 1, SV("1234567890"), 11, 0, S("can't happen")); + test(S("abcdefghij"), 1, SV("12345678901234567890"), 0, 0, S("abcdefghij")); + test(S("abcdefghij"), 1, SV("12345678901234567890"), 0, 1, S("a1bcdefghij")); + test(S("abcdefghij"), 1, SV("12345678901234567890"), 0, 10, S("a1234567890bcdefghij")); + test(S("abcdefghij"), 1, SV("12345678901234567890"), 0, 19, S("a1234567890123456789bcdefghij")); + test(S("abcdefghij"), 1, SV("12345678901234567890"), 0, 20, S("a12345678901234567890bcdefghij")); + test(S("abcdefghij"), 1, SV("12345678901234567890"), 0, 21, S("a12345678901234567890bcdefghij")); + test(S("abcdefghij"), 1, SV("12345678901234567890"), 1, 0, S("abcdefghij")); + test(S("abcdefghij"), 1, SV("12345678901234567890"), 1, 1, S("a2bcdefghij")); + test(S("abcdefghij"), 1, SV("12345678901234567890"), 1, 9, S("a234567890bcdefghij")); + test(S("abcdefghij"), 1, SV("12345678901234567890"), 1, 18, S("a234567890123456789bcdefghij")); + test(S("abcdefghij"), 1, SV("12345678901234567890"), 1, 19, S("a2345678901234567890bcdefghij")); + test(S("abcdefghij"), 1, SV("12345678901234567890"), 1, 20, S("a2345678901234567890bcdefghij")); + test(S("abcdefghij"), 1, SV("12345678901234567890"), 10, 0, S("abcdefghij")); + test(S("abcdefghij"), 1, SV("12345678901234567890"), 10, 1, S("a1bcdefghij")); + test(S("abcdefghij"), 1, SV("12345678901234567890"), 10, 5, S("a12345bcdefghij")); + test(S("abcdefghij"), 1, SV("12345678901234567890"), 10, 9, S("a123456789bcdefghij")); + test(S("abcdefghij"), 1, SV("12345678901234567890"), 10, 10, S("a1234567890bcdefghij")); + test(S("abcdefghij"), 1, SV("12345678901234567890"), 10, 11, S("a1234567890bcdefghij")); + test(S("abcdefghij"), 1, SV("12345678901234567890"), 19, 0, S("abcdefghij")); + test(S("abcdefghij"), 1, SV("12345678901234567890"), 19, 1, S("a0bcdefghij")); + test(S("abcdefghij"), 1, SV("12345678901234567890"), 19, 2, S("a0bcdefghij")); + test(S("abcdefghij"), 1, SV("12345678901234567890"), 20, 0, S("abcdefghij")); + test(S("abcdefghij"), 1, SV("12345678901234567890"), 20, 1, S("abcdefghij")); + test(S("abcdefghij"), 1, SV("12345678901234567890"), 21, 0, S("can't happen")); + test(S("abcdefghij"), 5, SV(""), 0, 0, S("abcdefghij")); + test(S("abcdefghij"), 5, SV(""), 0, 1, S("abcdefghij")); + test(S("abcdefghij"), 5, SV(""), 1, 0, S("can't happen")); + test(S("abcdefghij"), 5, SV("12345"), 0, 0, S("abcdefghij")); + test(S("abcdefghij"), 5, SV("12345"), 0, 1, S("abcde1fghij")); + test(S("abcdefghij"), 5, SV("12345"), 0, 2, S("abcde12fghij")); + test(S("abcdefghij"), 5, SV("12345"), 0, 4, S("abcde1234fghij")); + test(S("abcdefghij"), 5, SV("12345"), 0, 5, S("abcde12345fghij")); + test(S("abcdefghij"), 5, SV("12345"), 0, 6, S("abcde12345fghij")); + test(S("abcdefghij"), 5, SV("12345"), 1, 0, S("abcdefghij")); +} + +template +void test15() +{ + test(S("abcdefghij"), 5, SV("12345"), 1, 1, S("abcde2fghij")); + test(S("abcdefghij"), 5, SV("12345"), 1, 2, S("abcde23fghij")); + test(S("abcdefghij"), 5, SV("12345"), 1, 3, S("abcde234fghij")); + test(S("abcdefghij"), 5, SV("12345"), 1, 4, S("abcde2345fghij")); + test(S("abcdefghij"), 5, SV("12345"), 1, 5, S("abcde2345fghij")); + test(S("abcdefghij"), 5, SV("12345"), 2, 0, S("abcdefghij")); + test(S("abcdefghij"), 5, SV("12345"), 2, 1, S("abcde3fghij")); + test(S("abcdefghij"), 5, SV("12345"), 2, 2, S("abcde34fghij")); + test(S("abcdefghij"), 5, SV("12345"), 2, 3, S("abcde345fghij")); + test(S("abcdefghij"), 5, SV("12345"), 2, 4, S("abcde345fghij")); + test(S("abcdefghij"), 5, SV("12345"), 4, 0, S("abcdefghij")); + test(S("abcdefghij"), 5, SV("12345"), 4, 1, S("abcde5fghij")); + test(S("abcdefghij"), 5, SV("12345"), 4, 2, S("abcde5fghij")); + test(S("abcdefghij"), 5, SV("12345"), 5, 0, S("abcdefghij")); + test(S("abcdefghij"), 5, SV("12345"), 5, 1, S("abcdefghij")); + test(S("abcdefghij"), 5, SV("12345"), 6, 0, S("can't happen")); + test(S("abcdefghij"), 5, SV("1234567890"), 0, 0, S("abcdefghij")); + test(S("abcdefghij"), 5, SV("1234567890"), 0, 1, S("abcde1fghij")); + test(S("abcdefghij"), 5, SV("1234567890"), 0, 5, S("abcde12345fghij")); + test(S("abcdefghij"), 5, SV("1234567890"), 0, 9, S("abcde123456789fghij")); + test(S("abcdefghij"), 5, SV("1234567890"), 0, 10, S("abcde1234567890fghij")); + test(S("abcdefghij"), 5, SV("1234567890"), 0, 11, S("abcde1234567890fghij")); + test(S("abcdefghij"), 5, SV("1234567890"), 1, 0, S("abcdefghij")); + test(S("abcdefghij"), 5, SV("1234567890"), 1, 1, S("abcde2fghij")); + test(S("abcdefghij"), 5, SV("1234567890"), 1, 4, S("abcde2345fghij")); + test(S("abcdefghij"), 5, SV("1234567890"), 1, 8, S("abcde23456789fghij")); + test(S("abcdefghij"), 5, SV("1234567890"), 1, 9, S("abcde234567890fghij")); + test(S("abcdefghij"), 5, SV("1234567890"), 1, 10, S("abcde234567890fghij")); + test(S("abcdefghij"), 5, SV("1234567890"), 5, 0, S("abcdefghij")); + test(S("abcdefghij"), 5, SV("1234567890"), 5, 1, S("abcde6fghij")); + test(S("abcdefghij"), 5, SV("1234567890"), 5, 2, S("abcde67fghij")); + test(S("abcdefghij"), 5, SV("1234567890"), 5, 4, S("abcde6789fghij")); + test(S("abcdefghij"), 5, SV("1234567890"), 5, 5, S("abcde67890fghij")); + test(S("abcdefghij"), 5, SV("1234567890"), 5, 6, S("abcde67890fghij")); + test(S("abcdefghij"), 5, SV("1234567890"), 9, 0, S("abcdefghij")); + test(S("abcdefghij"), 5, SV("1234567890"), 9, 1, S("abcde0fghij")); + test(S("abcdefghij"), 5, SV("1234567890"), 9, 2, S("abcde0fghij")); + test(S("abcdefghij"), 5, SV("1234567890"), 10, 0, S("abcdefghij")); + test(S("abcdefghij"), 5, SV("1234567890"), 10, 1, S("abcdefghij")); + test(S("abcdefghij"), 5, SV("1234567890"), 11, 0, S("can't happen")); + test(S("abcdefghij"), 5, SV("12345678901234567890"), 0, 0, S("abcdefghij")); + test(S("abcdefghij"), 5, SV("12345678901234567890"), 0, 1, S("abcde1fghij")); + test(S("abcdefghij"), 5, SV("12345678901234567890"), 0, 10, S("abcde1234567890fghij")); + test(S("abcdefghij"), 5, SV("12345678901234567890"), 0, 19, S("abcde1234567890123456789fghij")); + test(S("abcdefghij"), 5, SV("12345678901234567890"), 0, 20, S("abcde12345678901234567890fghij")); + test(S("abcdefghij"), 5, SV("12345678901234567890"), 0, 21, S("abcde12345678901234567890fghij")); + test(S("abcdefghij"), 5, SV("12345678901234567890"), 1, 0, S("abcdefghij")); + test(S("abcdefghij"), 5, SV("12345678901234567890"), 1, 1, S("abcde2fghij")); + test(S("abcdefghij"), 5, SV("12345678901234567890"), 1, 9, S("abcde234567890fghij")); + test(S("abcdefghij"), 5, SV("12345678901234567890"), 1, 18, S("abcde234567890123456789fghij")); +} + +template +void test16() +{ + test(S("abcdefghij"), 5, SV("12345678901234567890"), 1, 19, S("abcde2345678901234567890fghij")); + test(S("abcdefghij"), 5, SV("12345678901234567890"), 1, 20, S("abcde2345678901234567890fghij")); + test(S("abcdefghij"), 5, SV("12345678901234567890"), 10, 0, S("abcdefghij")); + test(S("abcdefghij"), 5, SV("12345678901234567890"), 10, 1, S("abcde1fghij")); + test(S("abcdefghij"), 5, SV("12345678901234567890"), 10, 5, S("abcde12345fghij")); + test(S("abcdefghij"), 5, SV("12345678901234567890"), 10, 9, S("abcde123456789fghij")); + test(S("abcdefghij"), 5, SV("12345678901234567890"), 10, 10, S("abcde1234567890fghij")); + test(S("abcdefghij"), 5, SV("12345678901234567890"), 10, 11, S("abcde1234567890fghij")); + test(S("abcdefghij"), 5, SV("12345678901234567890"), 19, 0, S("abcdefghij")); + test(S("abcdefghij"), 5, SV("12345678901234567890"), 19, 1, S("abcde0fghij")); + test(S("abcdefghij"), 5, SV("12345678901234567890"), 19, 2, S("abcde0fghij")); + test(S("abcdefghij"), 5, SV("12345678901234567890"), 20, 0, S("abcdefghij")); + test(S("abcdefghij"), 5, SV("12345678901234567890"), 20, 1, S("abcdefghij")); + test(S("abcdefghij"), 5, SV("12345678901234567890"), 21, 0, S("can't happen")); + test(S("abcdefghij"), 9, SV(""), 0, 0, S("abcdefghij")); + test(S("abcdefghij"), 9, SV(""), 0, 1, S("abcdefghij")); + test(S("abcdefghij"), 9, SV(""), 1, 0, S("can't happen")); + test(S("abcdefghij"), 9, SV("12345"), 0, 0, S("abcdefghij")); + test(S("abcdefghij"), 9, SV("12345"), 0, 1, S("abcdefghi1j")); + test(S("abcdefghij"), 9, SV("12345"), 0, 2, S("abcdefghi12j")); + test(S("abcdefghij"), 9, SV("12345"), 0, 4, S("abcdefghi1234j")); + test(S("abcdefghij"), 9, SV("12345"), 0, 5, S("abcdefghi12345j")); + test(S("abcdefghij"), 9, SV("12345"), 0, 6, S("abcdefghi12345j")); + test(S("abcdefghij"), 9, SV("12345"), 1, 0, S("abcdefghij")); + test(S("abcdefghij"), 9, SV("12345"), 1, 1, S("abcdefghi2j")); + test(S("abcdefghij"), 9, SV("12345"), 1, 2, S("abcdefghi23j")); + test(S("abcdefghij"), 9, SV("12345"), 1, 3, S("abcdefghi234j")); + test(S("abcdefghij"), 9, SV("12345"), 1, 4, S("abcdefghi2345j")); + test(S("abcdefghij"), 9, SV("12345"), 1, 5, S("abcdefghi2345j")); + test(S("abcdefghij"), 9, SV("12345"), 2, 0, S("abcdefghij")); + test(S("abcdefghij"), 9, SV("12345"), 2, 1, S("abcdefghi3j")); + test(S("abcdefghij"), 9, SV("12345"), 2, 2, S("abcdefghi34j")); + test(S("abcdefghij"), 9, SV("12345"), 2, 3, S("abcdefghi345j")); + test(S("abcdefghij"), 9, SV("12345"), 2, 4, S("abcdefghi345j")); + test(S("abcdefghij"), 9, SV("12345"), 4, 0, S("abcdefghij")); + test(S("abcdefghij"), 9, SV("12345"), 4, 1, S("abcdefghi5j")); + test(S("abcdefghij"), 9, SV("12345"), 4, 2, S("abcdefghi5j")); + test(S("abcdefghij"), 9, SV("12345"), 5, 0, S("abcdefghij")); + test(S("abcdefghij"), 9, SV("12345"), 5, 1, S("abcdefghij")); + test(S("abcdefghij"), 9, SV("12345"), 6, 0, S("can't happen")); + test(S("abcdefghij"), 9, SV("1234567890"), 0, 0, S("abcdefghij")); + test(S("abcdefghij"), 9, SV("1234567890"), 0, 1, S("abcdefghi1j")); + test(S("abcdefghij"), 9, SV("1234567890"), 0, 5, S("abcdefghi12345j")); + test(S("abcdefghij"), 9, SV("1234567890"), 0, 9, S("abcdefghi123456789j")); + test(S("abcdefghij"), 9, SV("1234567890"), 0, 10, S("abcdefghi1234567890j")); + test(S("abcdefghij"), 9, SV("1234567890"), 0, 11, S("abcdefghi1234567890j")); + test(S("abcdefghij"), 9, SV("1234567890"), 1, 0, S("abcdefghij")); + test(S("abcdefghij"), 9, SV("1234567890"), 1, 1, S("abcdefghi2j")); + test(S("abcdefghij"), 9, SV("1234567890"), 1, 4, S("abcdefghi2345j")); + test(S("abcdefghij"), 9, SV("1234567890"), 1, 8, S("abcdefghi23456789j")); +} + +template +void test17() +{ + test(S("abcdefghij"), 9, SV("1234567890"), 1, 9, S("abcdefghi234567890j")); + test(S("abcdefghij"), 9, SV("1234567890"), 1, 10, S("abcdefghi234567890j")); + test(S("abcdefghij"), 9, SV("1234567890"), 5, 0, S("abcdefghij")); + test(S("abcdefghij"), 9, SV("1234567890"), 5, 1, S("abcdefghi6j")); + test(S("abcdefghij"), 9, SV("1234567890"), 5, 2, S("abcdefghi67j")); + test(S("abcdefghij"), 9, SV("1234567890"), 5, 4, S("abcdefghi6789j")); + test(S("abcdefghij"), 9, SV("1234567890"), 5, 5, S("abcdefghi67890j")); + test(S("abcdefghij"), 9, SV("1234567890"), 5, 6, S("abcdefghi67890j")); + test(S("abcdefghij"), 9, SV("1234567890"), 9, 0, S("abcdefghij")); + test(S("abcdefghij"), 9, SV("1234567890"), 9, 1, S("abcdefghi0j")); + test(S("abcdefghij"), 9, SV("1234567890"), 9, 2, S("abcdefghi0j")); + test(S("abcdefghij"), 9, SV("1234567890"), 10, 0, S("abcdefghij")); + test(S("abcdefghij"), 9, SV("1234567890"), 10, 1, S("abcdefghij")); + test(S("abcdefghij"), 9, SV("1234567890"), 11, 0, S("can't happen")); + test(S("abcdefghij"), 9, SV("12345678901234567890"), 0, 0, S("abcdefghij")); + test(S("abcdefghij"), 9, SV("12345678901234567890"), 0, 1, S("abcdefghi1j")); + test(S("abcdefghij"), 9, SV("12345678901234567890"), 0, 10, S("abcdefghi1234567890j")); + test(S("abcdefghij"), 9, SV("12345678901234567890"), 0, 19, S("abcdefghi1234567890123456789j")); + test(S("abcdefghij"), 9, SV("12345678901234567890"), 0, 20, S("abcdefghi12345678901234567890j")); + test(S("abcdefghij"), 9, SV("12345678901234567890"), 0, 21, S("abcdefghi12345678901234567890j")); + test(S("abcdefghij"), 9, SV("12345678901234567890"), 1, 0, S("abcdefghij")); + test(S("abcdefghij"), 9, SV("12345678901234567890"), 1, 1, S("abcdefghi2j")); + test(S("abcdefghij"), 9, SV("12345678901234567890"), 1, 9, S("abcdefghi234567890j")); + test(S("abcdefghij"), 9, SV("12345678901234567890"), 1, 18, S("abcdefghi234567890123456789j")); + test(S("abcdefghij"), 9, SV("12345678901234567890"), 1, 19, S("abcdefghi2345678901234567890j")); + test(S("abcdefghij"), 9, SV("12345678901234567890"), 1, 20, S("abcdefghi2345678901234567890j")); + test(S("abcdefghij"), 9, SV("12345678901234567890"), 10, 0, S("abcdefghij")); + test(S("abcdefghij"), 9, SV("12345678901234567890"), 10, 1, S("abcdefghi1j")); + test(S("abcdefghij"), 9, SV("12345678901234567890"), 10, 5, S("abcdefghi12345j")); + test(S("abcdefghij"), 9, SV("12345678901234567890"), 10, 9, S("abcdefghi123456789j")); + test(S("abcdefghij"), 9, SV("12345678901234567890"), 10, 10, S("abcdefghi1234567890j")); + test(S("abcdefghij"), 9, SV("12345678901234567890"), 10, 11, S("abcdefghi1234567890j")); + test(S("abcdefghij"), 9, SV("12345678901234567890"), 19, 0, S("abcdefghij")); + test(S("abcdefghij"), 9, SV("12345678901234567890"), 19, 1, S("abcdefghi0j")); + test(S("abcdefghij"), 9, SV("12345678901234567890"), 19, 2, S("abcdefghi0j")); + test(S("abcdefghij"), 9, SV("12345678901234567890"), 20, 0, S("abcdefghij")); + test(S("abcdefghij"), 9, SV("12345678901234567890"), 20, 1, S("abcdefghij")); + test(S("abcdefghij"), 9, SV("12345678901234567890"), 21, 0, S("can't happen")); + test(S("abcdefghij"), 10, SV(""), 0, 0, S("abcdefghij")); + test(S("abcdefghij"), 10, SV(""), 0, 1, S("abcdefghij")); + test(S("abcdefghij"), 10, SV(""), 1, 0, S("can't happen")); + test(S("abcdefghij"), 10, SV("12345"), 0, 0, S("abcdefghij")); + test(S("abcdefghij"), 10, SV("12345"), 0, 1, S("abcdefghij1")); + test(S("abcdefghij"), 10, SV("12345"), 0, 2, S("abcdefghij12")); + test(S("abcdefghij"), 10, SV("12345"), 0, 4, S("abcdefghij1234")); + test(S("abcdefghij"), 10, SV("12345"), 0, 5, S("abcdefghij12345")); + test(S("abcdefghij"), 10, SV("12345"), 0, 6, S("abcdefghij12345")); + test(S("abcdefghij"), 10, SV("12345"), 1, 0, S("abcdefghij")); + test(S("abcdefghij"), 10, SV("12345"), 1, 1, S("abcdefghij2")); + test(S("abcdefghij"), 10, SV("12345"), 1, 2, S("abcdefghij23")); +} + +template +void test18() +{ + test(S("abcdefghij"), 10, SV("12345"), 1, 3, S("abcdefghij234")); + test(S("abcdefghij"), 10, SV("12345"), 1, 4, S("abcdefghij2345")); + test(S("abcdefghij"), 10, SV("12345"), 1, 5, S("abcdefghij2345")); + test(S("abcdefghij"), 10, SV("12345"), 2, 0, S("abcdefghij")); + test(S("abcdefghij"), 10, SV("12345"), 2, 1, S("abcdefghij3")); + test(S("abcdefghij"), 10, SV("12345"), 2, 2, S("abcdefghij34")); + test(S("abcdefghij"), 10, SV("12345"), 2, 3, S("abcdefghij345")); + test(S("abcdefghij"), 10, SV("12345"), 2, 4, S("abcdefghij345")); + test(S("abcdefghij"), 10, SV("12345"), 4, 0, S("abcdefghij")); + test(S("abcdefghij"), 10, SV("12345"), 4, 1, S("abcdefghij5")); + test(S("abcdefghij"), 10, SV("12345"), 4, 2, S("abcdefghij5")); + test(S("abcdefghij"), 10, SV("12345"), 5, 0, S("abcdefghij")); + test(S("abcdefghij"), 10, SV("12345"), 5, 1, S("abcdefghij")); + test(S("abcdefghij"), 10, SV("12345"), 6, 0, S("can't happen")); + test(S("abcdefghij"), 10, SV("1234567890"), 0, 0, S("abcdefghij")); + test(S("abcdefghij"), 10, SV("1234567890"), 0, 1, S("abcdefghij1")); + test(S("abcdefghij"), 10, SV("1234567890"), 0, 5, S("abcdefghij12345")); + test(S("abcdefghij"), 10, SV("1234567890"), 0, 9, S("abcdefghij123456789")); + test(S("abcdefghij"), 10, SV("1234567890"), 0, 10, S("abcdefghij1234567890")); + test(S("abcdefghij"), 10, SV("1234567890"), 0, 11, S("abcdefghij1234567890")); + test(S("abcdefghij"), 10, SV("1234567890"), 1, 0, S("abcdefghij")); + test(S("abcdefghij"), 10, SV("1234567890"), 1, 1, S("abcdefghij2")); + test(S("abcdefghij"), 10, SV("1234567890"), 1, 4, S("abcdefghij2345")); + test(S("abcdefghij"), 10, SV("1234567890"), 1, 8, S("abcdefghij23456789")); + test(S("abcdefghij"), 10, SV("1234567890"), 1, 9, S("abcdefghij234567890")); + test(S("abcdefghij"), 10, SV("1234567890"), 1, 10, S("abcdefghij234567890")); + test(S("abcdefghij"), 10, SV("1234567890"), 5, 0, S("abcdefghij")); + test(S("abcdefghij"), 10, SV("1234567890"), 5, 1, S("abcdefghij6")); + test(S("abcdefghij"), 10, SV("1234567890"), 5, 2, S("abcdefghij67")); + test(S("abcdefghij"), 10, SV("1234567890"), 5, 4, S("abcdefghij6789")); + test(S("abcdefghij"), 10, SV("1234567890"), 5, 5, S("abcdefghij67890")); + test(S("abcdefghij"), 10, SV("1234567890"), 5, 6, S("abcdefghij67890")); + test(S("abcdefghij"), 10, SV("1234567890"), 9, 0, S("abcdefghij")); + test(S("abcdefghij"), 10, SV("1234567890"), 9, 1, S("abcdefghij0")); + test(S("abcdefghij"), 10, SV("1234567890"), 9, 2, S("abcdefghij0")); + test(S("abcdefghij"), 10, SV("1234567890"), 10, 0, S("abcdefghij")); + test(S("abcdefghij"), 10, SV("1234567890"), 10, 1, S("abcdefghij")); + test(S("abcdefghij"), 10, SV("1234567890"), 11, 0, S("can't happen")); + test(S("abcdefghij"), 10, SV("12345678901234567890"), 0, 0, S("abcdefghij")); + test(S("abcdefghij"), 10, SV("12345678901234567890"), 0, 1, S("abcdefghij1")); + test(S("abcdefghij"), 10, SV("12345678901234567890"), 0, 10, S("abcdefghij1234567890")); + test(S("abcdefghij"), 10, SV("12345678901234567890"), 0, 19, S("abcdefghij1234567890123456789")); + test(S("abcdefghij"), 10, SV("12345678901234567890"), 0, 20, S("abcdefghij12345678901234567890")); + test(S("abcdefghij"), 10, SV("12345678901234567890"), 0, 21, S("abcdefghij12345678901234567890")); + test(S("abcdefghij"), 10, SV("12345678901234567890"), 1, 0, S("abcdefghij")); + test(S("abcdefghij"), 10, SV("12345678901234567890"), 1, 1, S("abcdefghij2")); + test(S("abcdefghij"), 10, SV("12345678901234567890"), 1, 9, S("abcdefghij234567890")); + test(S("abcdefghij"), 10, SV("12345678901234567890"), 1, 18, S("abcdefghij234567890123456789")); + test(S("abcdefghij"), 10, SV("12345678901234567890"), 1, 19, S("abcdefghij2345678901234567890")); + test(S("abcdefghij"), 10, SV("12345678901234567890"), 1, 20, S("abcdefghij2345678901234567890")); +} + +template +void test19() +{ + test(S("abcdefghij"), 10, SV("12345678901234567890"), 10, 0, S("abcdefghij")); + test(S("abcdefghij"), 10, SV("12345678901234567890"), 10, 1, S("abcdefghij1")); + test(S("abcdefghij"), 10, SV("12345678901234567890"), 10, 5, S("abcdefghij12345")); + test(S("abcdefghij"), 10, SV("12345678901234567890"), 10, 9, S("abcdefghij123456789")); + test(S("abcdefghij"), 10, SV("12345678901234567890"), 10, 10, S("abcdefghij1234567890")); + test(S("abcdefghij"), 10, SV("12345678901234567890"), 10, 11, S("abcdefghij1234567890")); + test(S("abcdefghij"), 10, SV("12345678901234567890"), 19, 0, S("abcdefghij")); + test(S("abcdefghij"), 10, SV("12345678901234567890"), 19, 1, S("abcdefghij0")); + test(S("abcdefghij"), 10, SV("12345678901234567890"), 19, 2, S("abcdefghij0")); + test(S("abcdefghij"), 10, SV("12345678901234567890"), 20, 0, S("abcdefghij")); + test(S("abcdefghij"), 10, SV("12345678901234567890"), 20, 1, S("abcdefghij")); + test(S("abcdefghij"), 10, SV("12345678901234567890"), 21, 0, S("can't happen")); + test(S("abcdefghij"), 11, SV(""), 0, 0, S("can't happen")); + test(S("abcdefghij"), 11, SV(""), 0, 1, S("can't happen")); + test(S("abcdefghij"), 11, SV(""), 1, 0, S("can't happen")); + test(S("abcdefghij"), 11, SV("12345"), 0, 0, S("can't happen")); + test(S("abcdefghij"), 11, SV("12345"), 0, 1, S("can't happen")); + test(S("abcdefghij"), 11, SV("12345"), 0, 2, S("can't happen")); + test(S("abcdefghij"), 11, SV("12345"), 0, 4, S("can't happen")); + test(S("abcdefghij"), 11, SV("12345"), 0, 5, S("can't happen")); + test(S("abcdefghij"), 11, SV("12345"), 0, 6, S("can't happen")); + test(S("abcdefghij"), 11, SV("12345"), 1, 0, S("can't happen")); + test(S("abcdefghij"), 11, SV("12345"), 1, 1, S("can't happen")); + test(S("abcdefghij"), 11, SV("12345"), 1, 2, S("can't happen")); + test(S("abcdefghij"), 11, SV("12345"), 1, 3, S("can't happen")); + test(S("abcdefghij"), 11, SV("12345"), 1, 4, S("can't happen")); + test(S("abcdefghij"), 11, SV("12345"), 1, 5, S("can't happen")); + test(S("abcdefghij"), 11, SV("12345"), 2, 0, S("can't happen")); + test(S("abcdefghij"), 11, SV("12345"), 2, 1, S("can't happen")); + test(S("abcdefghij"), 11, SV("12345"), 2, 2, S("can't happen")); + test(S("abcdefghij"), 11, SV("12345"), 2, 3, S("can't happen")); + test(S("abcdefghij"), 11, SV("12345"), 2, 4, S("can't happen")); + test(S("abcdefghij"), 11, SV("12345"), 4, 0, S("can't happen")); + test(S("abcdefghij"), 11, SV("12345"), 4, 1, S("can't happen")); + test(S("abcdefghij"), 11, SV("12345"), 4, 2, S("can't happen")); + test(S("abcdefghij"), 11, SV("12345"), 5, 0, S("can't happen")); + test(S("abcdefghij"), 11, SV("12345"), 5, 1, S("can't happen")); + test(S("abcdefghij"), 11, SV("12345"), 6, 0, S("can't happen")); + test(S("abcdefghij"), 11, SV("1234567890"), 0, 0, S("can't happen")); + test(S("abcdefghij"), 11, SV("1234567890"), 0, 1, S("can't happen")); + test(S("abcdefghij"), 11, SV("1234567890"), 0, 5, S("can't happen")); + test(S("abcdefghij"), 11, SV("1234567890"), 0, 9, S("can't happen")); + test(S("abcdefghij"), 11, SV("1234567890"), 0, 10, S("can't happen")); + test(S("abcdefghij"), 11, SV("1234567890"), 0, 11, S("can't happen")); + test(S("abcdefghij"), 11, SV("1234567890"), 1, 0, S("can't happen")); + test(S("abcdefghij"), 11, SV("1234567890"), 1, 1, S("can't happen")); + test(S("abcdefghij"), 11, SV("1234567890"), 1, 4, S("can't happen")); + test(S("abcdefghij"), 11, SV("1234567890"), 1, 8, S("can't happen")); + test(S("abcdefghij"), 11, SV("1234567890"), 1, 9, S("can't happen")); + test(S("abcdefghij"), 11, SV("1234567890"), 1, 10, S("can't happen")); +} + +template +void test20() +{ + test(S("abcdefghij"), 11, SV("1234567890"), 5, 0, S("can't happen")); + test(S("abcdefghij"), 11, SV("1234567890"), 5, 1, S("can't happen")); + test(S("abcdefghij"), 11, SV("1234567890"), 5, 2, S("can't happen")); + test(S("abcdefghij"), 11, SV("1234567890"), 5, 4, S("can't happen")); + test(S("abcdefghij"), 11, SV("1234567890"), 5, 5, S("can't happen")); + test(S("abcdefghij"), 11, SV("1234567890"), 5, 6, S("can't happen")); + test(S("abcdefghij"), 11, SV("1234567890"), 9, 0, S("can't happen")); + test(S("abcdefghij"), 11, SV("1234567890"), 9, 1, S("can't happen")); + test(S("abcdefghij"), 11, SV("1234567890"), 9, 2, S("can't happen")); + test(S("abcdefghij"), 11, SV("1234567890"), 10, 0, S("can't happen")); + test(S("abcdefghij"), 11, SV("1234567890"), 10, 1, S("can't happen")); + test(S("abcdefghij"), 11, SV("1234567890"), 11, 0, S("can't happen")); + test(S("abcdefghij"), 11, SV("12345678901234567890"), 0, 0, S("can't happen")); + test(S("abcdefghij"), 11, SV("12345678901234567890"), 0, 1, S("can't happen")); + test(S("abcdefghij"), 11, SV("12345678901234567890"), 0, 10, S("can't happen")); + test(S("abcdefghij"), 11, SV("12345678901234567890"), 0, 19, S("can't happen")); + test(S("abcdefghij"), 11, SV("12345678901234567890"), 0, 20, S("can't happen")); + test(S("abcdefghij"), 11, SV("12345678901234567890"), 0, 21, S("can't happen")); + test(S("abcdefghij"), 11, SV("12345678901234567890"), 1, 0, S("can't happen")); + test(S("abcdefghij"), 11, SV("12345678901234567890"), 1, 1, S("can't happen")); + test(S("abcdefghij"), 11, SV("12345678901234567890"), 1, 9, S("can't happen")); + test(S("abcdefghij"), 11, SV("12345678901234567890"), 1, 18, S("can't happen")); + test(S("abcdefghij"), 11, SV("12345678901234567890"), 1, 19, S("can't happen")); + test(S("abcdefghij"), 11, SV("12345678901234567890"), 1, 20, S("can't happen")); + test(S("abcdefghij"), 11, SV("12345678901234567890"), 10, 0, S("can't happen")); + test(S("abcdefghij"), 11, SV("12345678901234567890"), 10, 1, S("can't happen")); + test(S("abcdefghij"), 11, SV("12345678901234567890"), 10, 5, S("can't happen")); + test(S("abcdefghij"), 11, SV("12345678901234567890"), 10, 9, S("can't happen")); + test(S("abcdefghij"), 11, SV("12345678901234567890"), 10, 10, S("can't happen")); + test(S("abcdefghij"), 11, SV("12345678901234567890"), 10, 11, S("can't happen")); + test(S("abcdefghij"), 11, SV("12345678901234567890"), 19, 0, S("can't happen")); + test(S("abcdefghij"), 11, SV("12345678901234567890"), 19, 1, S("can't happen")); + test(S("abcdefghij"), 11, SV("12345678901234567890"), 19, 2, S("can't happen")); + test(S("abcdefghij"), 11, SV("12345678901234567890"), 20, 0, S("can't happen")); + test(S("abcdefghij"), 11, SV("12345678901234567890"), 20, 1, S("can't happen")); + test(S("abcdefghij"), 11, SV("12345678901234567890"), 21, 0, S("can't happen")); + test(S("abcdefghijklmnopqrst"), 0, SV(""), 0, 0, S("abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, SV(""), 0, 1, S("abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, SV(""), 1, 0, S("can't happen")); + test(S("abcdefghijklmnopqrst"), 0, SV("12345"), 0, 0, S("abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, SV("12345"), 0, 1, S("1abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, SV("12345"), 0, 2, S("12abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, SV("12345"), 0, 4, S("1234abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, SV("12345"), 0, 5, S("12345abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, SV("12345"), 0, 6, S("12345abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, SV("12345"), 1, 0, S("abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, SV("12345"), 1, 1, S("2abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, SV("12345"), 1, 2, S("23abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, SV("12345"), 1, 3, S("234abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, SV("12345"), 1, 4, S("2345abcdefghijklmnopqrst")); +} + +template +void test21() +{ + test(S("abcdefghijklmnopqrst"), 0, SV("12345"), 1, 5, S("2345abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, SV("12345"), 2, 0, S("abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, SV("12345"), 2, 1, S("3abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, SV("12345"), 2, 2, S("34abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, SV("12345"), 2, 3, S("345abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, SV("12345"), 2, 4, S("345abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, SV("12345"), 4, 0, S("abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, SV("12345"), 4, 1, S("5abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, SV("12345"), 4, 2, S("5abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, SV("12345"), 5, 0, S("abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, SV("12345"), 5, 1, S("abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, SV("12345"), 6, 0, S("can't happen")); + test(S("abcdefghijklmnopqrst"), 0, SV("1234567890"), 0, 0, S("abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, SV("1234567890"), 0, 1, S("1abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, SV("1234567890"), 0, 5, S("12345abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, SV("1234567890"), 0, 9, S("123456789abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, SV("1234567890"), 0, 10, S("1234567890abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, SV("1234567890"), 0, 11, S("1234567890abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, SV("1234567890"), 1, 0, S("abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, SV("1234567890"), 1, 1, S("2abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, SV("1234567890"), 1, 4, S("2345abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, SV("1234567890"), 1, 8, S("23456789abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, SV("1234567890"), 1, 9, S("234567890abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, SV("1234567890"), 1, 10, S("234567890abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, SV("1234567890"), 5, 0, S("abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, SV("1234567890"), 5, 1, S("6abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, SV("1234567890"), 5, 2, S("67abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, SV("1234567890"), 5, 4, S("6789abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, SV("1234567890"), 5, 5, S("67890abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, SV("1234567890"), 5, 6, S("67890abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, SV("1234567890"), 9, 0, S("abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, SV("1234567890"), 9, 1, S("0abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, SV("1234567890"), 9, 2, S("0abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, SV("1234567890"), 10, 0, S("abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, SV("1234567890"), 10, 1, S("abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, SV("1234567890"), 11, 0, S("can't happen")); + test(S("abcdefghijklmnopqrst"), 0, SV("12345678901234567890"), 0, 0, S("abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, SV("12345678901234567890"), 0, 1, S("1abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, SV("12345678901234567890"), 0, 10, S("1234567890abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, SV("12345678901234567890"), 0, 19, S("1234567890123456789abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, SV("12345678901234567890"), 0, 20, S("12345678901234567890abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, SV("12345678901234567890"), 0, 21, S("12345678901234567890abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, SV("12345678901234567890"), 1, 0, S("abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, SV("12345678901234567890"), 1, 1, S("2abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, SV("12345678901234567890"), 1, 9, S("234567890abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, SV("12345678901234567890"), 1, 18, S("234567890123456789abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, SV("12345678901234567890"), 1, 19, S("2345678901234567890abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, SV("12345678901234567890"), 1, 20, S("2345678901234567890abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, SV("12345678901234567890"), 10, 0, S("abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, SV("12345678901234567890"), 10, 1, S("1abcdefghijklmnopqrst")); +} + +template +void test22() +{ + test(S("abcdefghijklmnopqrst"), 0, SV("12345678901234567890"), 10, 5, S("12345abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, SV("12345678901234567890"), 10, 9, S("123456789abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, SV("12345678901234567890"), 10, 10, S("1234567890abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, SV("12345678901234567890"), 10, 11, S("1234567890abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, SV("12345678901234567890"), 19, 0, S("abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, SV("12345678901234567890"), 19, 1, S("0abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, SV("12345678901234567890"), 19, 2, S("0abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, SV("12345678901234567890"), 20, 0, S("abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, SV("12345678901234567890"), 20, 1, S("abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, SV("12345678901234567890"), 21, 0, S("can't happen")); + test(S("abcdefghijklmnopqrst"), 1, SV(""), 0, 0, S("abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, SV(""), 0, 1, S("abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, SV(""), 1, 0, S("can't happen")); + test(S("abcdefghijklmnopqrst"), 1, SV("12345"), 0, 0, S("abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, SV("12345"), 0, 1, S("a1bcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, SV("12345"), 0, 2, S("a12bcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, SV("12345"), 0, 4, S("a1234bcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, SV("12345"), 0, 5, S("a12345bcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, SV("12345"), 0, 6, S("a12345bcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, SV("12345"), 1, 0, S("abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, SV("12345"), 1, 1, S("a2bcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, SV("12345"), 1, 2, S("a23bcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, SV("12345"), 1, 3, S("a234bcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, SV("12345"), 1, 4, S("a2345bcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, SV("12345"), 1, 5, S("a2345bcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, SV("12345"), 2, 0, S("abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, SV("12345"), 2, 1, S("a3bcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, SV("12345"), 2, 2, S("a34bcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, SV("12345"), 2, 3, S("a345bcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, SV("12345"), 2, 4, S("a345bcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, SV("12345"), 4, 0, S("abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, SV("12345"), 4, 1, S("a5bcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, SV("12345"), 4, 2, S("a5bcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, SV("12345"), 5, 0, S("abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, SV("12345"), 5, 1, S("abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, SV("12345"), 6, 0, S("can't happen")); + test(S("abcdefghijklmnopqrst"), 1, SV("1234567890"), 0, 0, S("abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, SV("1234567890"), 0, 1, S("a1bcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, SV("1234567890"), 0, 5, S("a12345bcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, SV("1234567890"), 0, 9, S("a123456789bcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, SV("1234567890"), 0, 10, S("a1234567890bcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, SV("1234567890"), 0, 11, S("a1234567890bcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, SV("1234567890"), 1, 0, S("abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, SV("1234567890"), 1, 1, S("a2bcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, SV("1234567890"), 1, 4, S("a2345bcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, SV("1234567890"), 1, 8, S("a23456789bcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, SV("1234567890"), 1, 9, S("a234567890bcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, SV("1234567890"), 1, 10, S("a234567890bcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, SV("1234567890"), 5, 0, S("abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, SV("1234567890"), 5, 1, S("a6bcdefghijklmnopqrst")); +} + +template +void test23() +{ + test(S("abcdefghijklmnopqrst"), 1, SV("1234567890"), 5, 2, S("a67bcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, SV("1234567890"), 5, 4, S("a6789bcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, SV("1234567890"), 5, 5, S("a67890bcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, SV("1234567890"), 5, 6, S("a67890bcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, SV("1234567890"), 9, 0, S("abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, SV("1234567890"), 9, 1, S("a0bcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, SV("1234567890"), 9, 2, S("a0bcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, SV("1234567890"), 10, 0, S("abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, SV("1234567890"), 10, 1, S("abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, SV("1234567890"), 11, 0, S("can't happen")); + test(S("abcdefghijklmnopqrst"), 1, SV("12345678901234567890"), 0, 0, S("abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, SV("12345678901234567890"), 0, 1, S("a1bcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, SV("12345678901234567890"), 0, 10, S("a1234567890bcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, SV("12345678901234567890"), 0, 19, S("a1234567890123456789bcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, SV("12345678901234567890"), 0, 20, S("a12345678901234567890bcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, SV("12345678901234567890"), 0, 21, S("a12345678901234567890bcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, SV("12345678901234567890"), 1, 0, S("abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, SV("12345678901234567890"), 1, 1, S("a2bcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, SV("12345678901234567890"), 1, 9, S("a234567890bcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, SV("12345678901234567890"), 1, 18, S("a234567890123456789bcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, SV("12345678901234567890"), 1, 19, S("a2345678901234567890bcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, SV("12345678901234567890"), 1, 20, S("a2345678901234567890bcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, SV("12345678901234567890"), 10, 0, S("abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, SV("12345678901234567890"), 10, 1, S("a1bcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, SV("12345678901234567890"), 10, 5, S("a12345bcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, SV("12345678901234567890"), 10, 9, S("a123456789bcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, SV("12345678901234567890"), 10, 10, S("a1234567890bcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, SV("12345678901234567890"), 10, 11, S("a1234567890bcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, SV("12345678901234567890"), 19, 0, S("abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, SV("12345678901234567890"), 19, 1, S("a0bcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, SV("12345678901234567890"), 19, 2, S("a0bcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, SV("12345678901234567890"), 20, 0, S("abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, SV("12345678901234567890"), 20, 1, S("abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, SV("12345678901234567890"), 21, 0, S("can't happen")); + test(S("abcdefghijklmnopqrst"), 10, SV(""), 0, 0, S("abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 10, SV(""), 0, 1, S("abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 10, SV(""), 1, 0, S("can't happen")); + test(S("abcdefghijklmnopqrst"), 10, SV("12345"), 0, 0, S("abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 10, SV("12345"), 0, 1, S("abcdefghij1klmnopqrst")); + test(S("abcdefghijklmnopqrst"), 10, SV("12345"), 0, 2, S("abcdefghij12klmnopqrst")); + test(S("abcdefghijklmnopqrst"), 10, SV("12345"), 0, 4, S("abcdefghij1234klmnopqrst")); + test(S("abcdefghijklmnopqrst"), 10, SV("12345"), 0, 5, S("abcdefghij12345klmnopqrst")); + test(S("abcdefghijklmnopqrst"), 10, SV("12345"), 0, 6, S("abcdefghij12345klmnopqrst")); + test(S("abcdefghijklmnopqrst"), 10, SV("12345"), 1, 0, S("abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 10, SV("12345"), 1, 1, S("abcdefghij2klmnopqrst")); + test(S("abcdefghijklmnopqrst"), 10, SV("12345"), 1, 2, S("abcdefghij23klmnopqrst")); + test(S("abcdefghijklmnopqrst"), 10, SV("12345"), 1, 3, S("abcdefghij234klmnopqrst")); + test(S("abcdefghijklmnopqrst"), 10, SV("12345"), 1, 4, S("abcdefghij2345klmnopqrst")); + test(S("abcdefghijklmnopqrst"), 10, SV("12345"), 1, 5, S("abcdefghij2345klmnopqrst")); + test(S("abcdefghijklmnopqrst"), 10, SV("12345"), 2, 0, S("abcdefghijklmnopqrst")); +} + +template +void test24() +{ + test(S("abcdefghijklmnopqrst"), 10, SV("12345"), 2, 1, S("abcdefghij3klmnopqrst")); + test(S("abcdefghijklmnopqrst"), 10, SV("12345"), 2, 2, S("abcdefghij34klmnopqrst")); + test(S("abcdefghijklmnopqrst"), 10, SV("12345"), 2, 3, S("abcdefghij345klmnopqrst")); + test(S("abcdefghijklmnopqrst"), 10, SV("12345"), 2, 4, S("abcdefghij345klmnopqrst")); + test(S("abcdefghijklmnopqrst"), 10, SV("12345"), 4, 0, S("abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 10, SV("12345"), 4, 1, S("abcdefghij5klmnopqrst")); + test(S("abcdefghijklmnopqrst"), 10, SV("12345"), 4, 2, S("abcdefghij5klmnopqrst")); + test(S("abcdefghijklmnopqrst"), 10, SV("12345"), 5, 0, S("abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 10, SV("12345"), 5, 1, S("abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 10, SV("12345"), 6, 0, S("can't happen")); + test(S("abcdefghijklmnopqrst"), 10, SV("1234567890"), 0, 0, S("abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 10, SV("1234567890"), 0, 1, S("abcdefghij1klmnopqrst")); + test(S("abcdefghijklmnopqrst"), 10, SV("1234567890"), 0, 5, S("abcdefghij12345klmnopqrst")); + test(S("abcdefghijklmnopqrst"), 10, SV("1234567890"), 0, 9, S("abcdefghij123456789klmnopqrst")); + test(S("abcdefghijklmnopqrst"), 10, SV("1234567890"), 0, 10, S("abcdefghij1234567890klmnopqrst")); + test(S("abcdefghijklmnopqrst"), 10, SV("1234567890"), 0, 11, S("abcdefghij1234567890klmnopqrst")); + test(S("abcdefghijklmnopqrst"), 10, SV("1234567890"), 1, 0, S("abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 10, SV("1234567890"), 1, 1, S("abcdefghij2klmnopqrst")); + test(S("abcdefghijklmnopqrst"), 10, SV("1234567890"), 1, 4, S("abcdefghij2345klmnopqrst")); + test(S("abcdefghijklmnopqrst"), 10, SV("1234567890"), 1, 8, S("abcdefghij23456789klmnopqrst")); + test(S("abcdefghijklmnopqrst"), 10, SV("1234567890"), 1, 9, S("abcdefghij234567890klmnopqrst")); + test(S("abcdefghijklmnopqrst"), 10, SV("1234567890"), 1, 10, S("abcdefghij234567890klmnopqrst")); + test(S("abcdefghijklmnopqrst"), 10, SV("1234567890"), 5, 0, S("abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 10, SV("1234567890"), 5, 1, S("abcdefghij6klmnopqrst")); + test(S("abcdefghijklmnopqrst"), 10, SV("1234567890"), 5, 2, S("abcdefghij67klmnopqrst")); + test(S("abcdefghijklmnopqrst"), 10, SV("1234567890"), 5, 4, S("abcdefghij6789klmnopqrst")); + test(S("abcdefghijklmnopqrst"), 10, SV("1234567890"), 5, 5, S("abcdefghij67890klmnopqrst")); + test(S("abcdefghijklmnopqrst"), 10, SV("1234567890"), 5, 6, S("abcdefghij67890klmnopqrst")); + test(S("abcdefghijklmnopqrst"), 10, SV("1234567890"), 9, 0, S("abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 10, SV("1234567890"), 9, 1, S("abcdefghij0klmnopqrst")); + test(S("abcdefghijklmnopqrst"), 10, SV("1234567890"), 9, 2, S("abcdefghij0klmnopqrst")); + test(S("abcdefghijklmnopqrst"), 10, SV("1234567890"), 10, 0, S("abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 10, SV("1234567890"), 10, 1, S("abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 10, SV("1234567890"), 11, 0, S("can't happen")); + test(S("abcdefghijklmnopqrst"), 10, SV("12345678901234567890"), 0, 0, S("abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 10, SV("12345678901234567890"), 0, 1, S("abcdefghij1klmnopqrst")); + test(S("abcdefghijklmnopqrst"), 10, SV("12345678901234567890"), 0, 10, S("abcdefghij1234567890klmnopqrst")); + test(S("abcdefghijklmnopqrst"), 10, SV("12345678901234567890"), 0, 19, S("abcdefghij1234567890123456789klmnopqrst")); + test(S("abcdefghijklmnopqrst"), 10, SV("12345678901234567890"), 0, 20, S("abcdefghij12345678901234567890klmnopqrst")); + test(S("abcdefghijklmnopqrst"), 10, SV("12345678901234567890"), 0, 21, S("abcdefghij12345678901234567890klmnopqrst")); + test(S("abcdefghijklmnopqrst"), 10, SV("12345678901234567890"), 1, 0, S("abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 10, SV("12345678901234567890"), 1, 1, S("abcdefghij2klmnopqrst")); + test(S("abcdefghijklmnopqrst"), 10, SV("12345678901234567890"), 1, 9, S("abcdefghij234567890klmnopqrst")); + test(S("abcdefghijklmnopqrst"), 10, SV("12345678901234567890"), 1, 18, S("abcdefghij234567890123456789klmnopqrst")); + test(S("abcdefghijklmnopqrst"), 10, SV("12345678901234567890"), 1, 19, S("abcdefghij2345678901234567890klmnopqrst")); + test(S("abcdefghijklmnopqrst"), 10, SV("12345678901234567890"), 1, 20, S("abcdefghij2345678901234567890klmnopqrst")); + test(S("abcdefghijklmnopqrst"), 10, SV("12345678901234567890"), 10, 0, S("abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 10, SV("12345678901234567890"), 10, 1, S("abcdefghij1klmnopqrst")); + test(S("abcdefghijklmnopqrst"), 10, SV("12345678901234567890"), 10, 5, S("abcdefghij12345klmnopqrst")); + test(S("abcdefghijklmnopqrst"), 10, SV("12345678901234567890"), 10, 9, S("abcdefghij123456789klmnopqrst")); +} + +template +void test25() +{ + test(S("abcdefghijklmnopqrst"), 10, SV("12345678901234567890"), 10, 10, S("abcdefghij1234567890klmnopqrst")); + test(S("abcdefghijklmnopqrst"), 10, SV("12345678901234567890"), 10, 11, S("abcdefghij1234567890klmnopqrst")); + test(S("abcdefghijklmnopqrst"), 10, SV("12345678901234567890"), 19, 0, S("abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 10, SV("12345678901234567890"), 19, 1, S("abcdefghij0klmnopqrst")); + test(S("abcdefghijklmnopqrst"), 10, SV("12345678901234567890"), 19, 2, S("abcdefghij0klmnopqrst")); + test(S("abcdefghijklmnopqrst"), 10, SV("12345678901234567890"), 20, 0, S("abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 10, SV("12345678901234567890"), 20, 1, S("abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 10, SV("12345678901234567890"), 21, 0, S("can't happen")); + test(S("abcdefghijklmnopqrst"), 19, SV(""), 0, 0, S("abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 19, SV(""), 0, 1, S("abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 19, SV(""), 1, 0, S("can't happen")); + test(S("abcdefghijklmnopqrst"), 19, SV("12345"), 0, 0, S("abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 19, SV("12345"), 0, 1, S("abcdefghijklmnopqrs1t")); + test(S("abcdefghijklmnopqrst"), 19, SV("12345"), 0, 2, S("abcdefghijklmnopqrs12t")); + test(S("abcdefghijklmnopqrst"), 19, SV("12345"), 0, 4, S("abcdefghijklmnopqrs1234t")); + test(S("abcdefghijklmnopqrst"), 19, SV("12345"), 0, 5, S("abcdefghijklmnopqrs12345t")); + test(S("abcdefghijklmnopqrst"), 19, SV("12345"), 0, 6, S("abcdefghijklmnopqrs12345t")); + test(S("abcdefghijklmnopqrst"), 19, SV("12345"), 1, 0, S("abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 19, SV("12345"), 1, 1, S("abcdefghijklmnopqrs2t")); + test(S("abcdefghijklmnopqrst"), 19, SV("12345"), 1, 2, S("abcdefghijklmnopqrs23t")); + test(S("abcdefghijklmnopqrst"), 19, SV("12345"), 1, 3, S("abcdefghijklmnopqrs234t")); + test(S("abcdefghijklmnopqrst"), 19, SV("12345"), 1, 4, S("abcdefghijklmnopqrs2345t")); + test(S("abcdefghijklmnopqrst"), 19, SV("12345"), 1, 5, S("abcdefghijklmnopqrs2345t")); + test(S("abcdefghijklmnopqrst"), 19, SV("12345"), 2, 0, S("abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 19, SV("12345"), 2, 1, S("abcdefghijklmnopqrs3t")); + test(S("abcdefghijklmnopqrst"), 19, SV("12345"), 2, 2, S("abcdefghijklmnopqrs34t")); + test(S("abcdefghijklmnopqrst"), 19, SV("12345"), 2, 3, S("abcdefghijklmnopqrs345t")); + test(S("abcdefghijklmnopqrst"), 19, SV("12345"), 2, 4, S("abcdefghijklmnopqrs345t")); + test(S("abcdefghijklmnopqrst"), 19, SV("12345"), 4, 0, S("abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 19, SV("12345"), 4, 1, S("abcdefghijklmnopqrs5t")); + test(S("abcdefghijklmnopqrst"), 19, SV("12345"), 4, 2, S("abcdefghijklmnopqrs5t")); + test(S("abcdefghijklmnopqrst"), 19, SV("12345"), 5, 0, S("abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 19, SV("12345"), 5, 1, S("abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 19, SV("12345"), 6, 0, S("can't happen")); + test(S("abcdefghijklmnopqrst"), 19, SV("1234567890"), 0, 0, S("abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 19, SV("1234567890"), 0, 1, S("abcdefghijklmnopqrs1t")); + test(S("abcdefghijklmnopqrst"), 19, SV("1234567890"), 0, 5, S("abcdefghijklmnopqrs12345t")); + test(S("abcdefghijklmnopqrst"), 19, SV("1234567890"), 0, 9, S("abcdefghijklmnopqrs123456789t")); + test(S("abcdefghijklmnopqrst"), 19, SV("1234567890"), 0, 10, S("abcdefghijklmnopqrs1234567890t")); + test(S("abcdefghijklmnopqrst"), 19, SV("1234567890"), 0, 11, S("abcdefghijklmnopqrs1234567890t")); + test(S("abcdefghijklmnopqrst"), 19, SV("1234567890"), 1, 0, S("abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 19, SV("1234567890"), 1, 1, S("abcdefghijklmnopqrs2t")); + test(S("abcdefghijklmnopqrst"), 19, SV("1234567890"), 1, 4, S("abcdefghijklmnopqrs2345t")); + test(S("abcdefghijklmnopqrst"), 19, SV("1234567890"), 1, 8, S("abcdefghijklmnopqrs23456789t")); + test(S("abcdefghijklmnopqrst"), 19, SV("1234567890"), 1, 9, S("abcdefghijklmnopqrs234567890t")); + test(S("abcdefghijklmnopqrst"), 19, SV("1234567890"), 1, 10, S("abcdefghijklmnopqrs234567890t")); + test(S("abcdefghijklmnopqrst"), 19, SV("1234567890"), 5, 0, S("abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 19, SV("1234567890"), 5, 1, S("abcdefghijklmnopqrs6t")); + test(S("abcdefghijklmnopqrst"), 19, SV("1234567890"), 5, 2, S("abcdefghijklmnopqrs67t")); + test(S("abcdefghijklmnopqrst"), 19, SV("1234567890"), 5, 4, S("abcdefghijklmnopqrs6789t")); +} + +template +void test26() +{ + test(S("abcdefghijklmnopqrst"), 19, SV("1234567890"), 5, 5, S("abcdefghijklmnopqrs67890t")); + test(S("abcdefghijklmnopqrst"), 19, SV("1234567890"), 5, 6, S("abcdefghijklmnopqrs67890t")); + test(S("abcdefghijklmnopqrst"), 19, SV("1234567890"), 9, 0, S("abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 19, SV("1234567890"), 9, 1, S("abcdefghijklmnopqrs0t")); + test(S("abcdefghijklmnopqrst"), 19, SV("1234567890"), 9, 2, S("abcdefghijklmnopqrs0t")); + test(S("abcdefghijklmnopqrst"), 19, SV("1234567890"), 10, 0, S("abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 19, SV("1234567890"), 10, 1, S("abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 19, SV("1234567890"), 11, 0, S("can't happen")); + test(S("abcdefghijklmnopqrst"), 19, SV("12345678901234567890"), 0, 0, S("abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 19, SV("12345678901234567890"), 0, 1, S("abcdefghijklmnopqrs1t")); + test(S("abcdefghijklmnopqrst"), 19, SV("12345678901234567890"), 0, 10, S("abcdefghijklmnopqrs1234567890t")); + test(S("abcdefghijklmnopqrst"), 19, SV("12345678901234567890"), 0, 19, S("abcdefghijklmnopqrs1234567890123456789t")); + test(S("abcdefghijklmnopqrst"), 19, SV("12345678901234567890"), 0, 20, S("abcdefghijklmnopqrs12345678901234567890t")); + test(S("abcdefghijklmnopqrst"), 19, SV("12345678901234567890"), 0, 21, S("abcdefghijklmnopqrs12345678901234567890t")); + test(S("abcdefghijklmnopqrst"), 19, SV("12345678901234567890"), 1, 0, S("abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 19, SV("12345678901234567890"), 1, 1, S("abcdefghijklmnopqrs2t")); + test(S("abcdefghijklmnopqrst"), 19, SV("12345678901234567890"), 1, 9, S("abcdefghijklmnopqrs234567890t")); + test(S("abcdefghijklmnopqrst"), 19, SV("12345678901234567890"), 1, 18, S("abcdefghijklmnopqrs234567890123456789t")); + test(S("abcdefghijklmnopqrst"), 19, SV("12345678901234567890"), 1, 19, S("abcdefghijklmnopqrs2345678901234567890t")); + test(S("abcdefghijklmnopqrst"), 19, SV("12345678901234567890"), 1, 20, S("abcdefghijklmnopqrs2345678901234567890t")); + test(S("abcdefghijklmnopqrst"), 19, SV("12345678901234567890"), 10, 0, S("abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 19, SV("12345678901234567890"), 10, 1, S("abcdefghijklmnopqrs1t")); + test(S("abcdefghijklmnopqrst"), 19, SV("12345678901234567890"), 10, 5, S("abcdefghijklmnopqrs12345t")); + test(S("abcdefghijklmnopqrst"), 19, SV("12345678901234567890"), 10, 9, S("abcdefghijklmnopqrs123456789t")); + test(S("abcdefghijklmnopqrst"), 19, SV("12345678901234567890"), 10, 10, S("abcdefghijklmnopqrs1234567890t")); + test(S("abcdefghijklmnopqrst"), 19, SV("12345678901234567890"), 10, 11, S("abcdefghijklmnopqrs1234567890t")); + test(S("abcdefghijklmnopqrst"), 19, SV("12345678901234567890"), 19, 0, S("abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 19, SV("12345678901234567890"), 19, 1, S("abcdefghijklmnopqrs0t")); + test(S("abcdefghijklmnopqrst"), 19, SV("12345678901234567890"), 19, 2, S("abcdefghijklmnopqrs0t")); + test(S("abcdefghijklmnopqrst"), 19, SV("12345678901234567890"), 20, 0, S("abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 19, SV("12345678901234567890"), 20, 1, S("abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 19, SV("12345678901234567890"), 21, 0, S("can't happen")); + test(S("abcdefghijklmnopqrst"), 20, SV(""), 0, 0, S("abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 20, SV(""), 0, 1, S("abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 20, SV(""), 1, 0, S("can't happen")); + test(S("abcdefghijklmnopqrst"), 20, SV("12345"), 0, 0, S("abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 20, SV("12345"), 0, 1, S("abcdefghijklmnopqrst1")); + test(S("abcdefghijklmnopqrst"), 20, SV("12345"), 0, 2, S("abcdefghijklmnopqrst12")); + test(S("abcdefghijklmnopqrst"), 20, SV("12345"), 0, 4, S("abcdefghijklmnopqrst1234")); + test(S("abcdefghijklmnopqrst"), 20, SV("12345"), 0, 5, S("abcdefghijklmnopqrst12345")); + test(S("abcdefghijklmnopqrst"), 20, SV("12345"), 0, 6, S("abcdefghijklmnopqrst12345")); + test(S("abcdefghijklmnopqrst"), 20, SV("12345"), 1, 0, S("abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 20, SV("12345"), 1, 1, S("abcdefghijklmnopqrst2")); + test(S("abcdefghijklmnopqrst"), 20, SV("12345"), 1, 2, S("abcdefghijklmnopqrst23")); + test(S("abcdefghijklmnopqrst"), 20, SV("12345"), 1, 3, S("abcdefghijklmnopqrst234")); + test(S("abcdefghijklmnopqrst"), 20, SV("12345"), 1, 4, S("abcdefghijklmnopqrst2345")); + test(S("abcdefghijklmnopqrst"), 20, SV("12345"), 1, 5, S("abcdefghijklmnopqrst2345")); + test(S("abcdefghijklmnopqrst"), 20, SV("12345"), 2, 0, S("abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 20, SV("12345"), 2, 1, S("abcdefghijklmnopqrst3")); + test(S("abcdefghijklmnopqrst"), 20, SV("12345"), 2, 2, S("abcdefghijklmnopqrst34")); +} + +template +void test27() +{ + test(S("abcdefghijklmnopqrst"), 20, SV("12345"), 2, 3, S("abcdefghijklmnopqrst345")); + test(S("abcdefghijklmnopqrst"), 20, SV("12345"), 2, 4, S("abcdefghijklmnopqrst345")); + test(S("abcdefghijklmnopqrst"), 20, SV("12345"), 4, 0, S("abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 20, SV("12345"), 4, 1, S("abcdefghijklmnopqrst5")); + test(S("abcdefghijklmnopqrst"), 20, SV("12345"), 4, 2, S("abcdefghijklmnopqrst5")); + test(S("abcdefghijklmnopqrst"), 20, SV("12345"), 5, 0, S("abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 20, SV("12345"), 5, 1, S("abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 20, SV("12345"), 6, 0, S("can't happen")); + test(S("abcdefghijklmnopqrst"), 20, SV("1234567890"), 0, 0, S("abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 20, SV("1234567890"), 0, 1, S("abcdefghijklmnopqrst1")); + test(S("abcdefghijklmnopqrst"), 20, SV("1234567890"), 0, 5, S("abcdefghijklmnopqrst12345")); + test(S("abcdefghijklmnopqrst"), 20, SV("1234567890"), 0, 9, S("abcdefghijklmnopqrst123456789")); + test(S("abcdefghijklmnopqrst"), 20, SV("1234567890"), 0, 10, S("abcdefghijklmnopqrst1234567890")); + test(S("abcdefghijklmnopqrst"), 20, SV("1234567890"), 0, 11, S("abcdefghijklmnopqrst1234567890")); + test(S("abcdefghijklmnopqrst"), 20, SV("1234567890"), 1, 0, S("abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 20, SV("1234567890"), 1, 1, S("abcdefghijklmnopqrst2")); + test(S("abcdefghijklmnopqrst"), 20, SV("1234567890"), 1, 4, S("abcdefghijklmnopqrst2345")); + test(S("abcdefghijklmnopqrst"), 20, SV("1234567890"), 1, 8, S("abcdefghijklmnopqrst23456789")); + test(S("abcdefghijklmnopqrst"), 20, SV("1234567890"), 1, 9, S("abcdefghijklmnopqrst234567890")); + test(S("abcdefghijklmnopqrst"), 20, SV("1234567890"), 1, 10, S("abcdefghijklmnopqrst234567890")); + test(S("abcdefghijklmnopqrst"), 20, SV("1234567890"), 5, 0, S("abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 20, SV("1234567890"), 5, 1, S("abcdefghijklmnopqrst6")); + test(S("abcdefghijklmnopqrst"), 20, SV("1234567890"), 5, 2, S("abcdefghijklmnopqrst67")); + test(S("abcdefghijklmnopqrst"), 20, SV("1234567890"), 5, 4, S("abcdefghijklmnopqrst6789")); + test(S("abcdefghijklmnopqrst"), 20, SV("1234567890"), 5, 5, S("abcdefghijklmnopqrst67890")); + test(S("abcdefghijklmnopqrst"), 20, SV("1234567890"), 5, 6, S("abcdefghijklmnopqrst67890")); + test(S("abcdefghijklmnopqrst"), 20, SV("1234567890"), 9, 0, S("abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 20, SV("1234567890"), 9, 1, S("abcdefghijklmnopqrst0")); + test(S("abcdefghijklmnopqrst"), 20, SV("1234567890"), 9, 2, S("abcdefghijklmnopqrst0")); + test(S("abcdefghijklmnopqrst"), 20, SV("1234567890"), 10, 0, S("abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 20, SV("1234567890"), 10, 1, S("abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 20, SV("1234567890"), 11, 0, S("can't happen")); + test(S("abcdefghijklmnopqrst"), 20, SV("12345678901234567890"), 0, 0, S("abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 20, SV("12345678901234567890"), 0, 1, S("abcdefghijklmnopqrst1")); + test(S("abcdefghijklmnopqrst"), 20, SV("12345678901234567890"), 0, 10, S("abcdefghijklmnopqrst1234567890")); + test(S("abcdefghijklmnopqrst"), 20, SV("12345678901234567890"), 0, 19, S("abcdefghijklmnopqrst1234567890123456789")); + test(S("abcdefghijklmnopqrst"), 20, SV("12345678901234567890"), 0, 20, S("abcdefghijklmnopqrst12345678901234567890")); + test(S("abcdefghijklmnopqrst"), 20, SV("12345678901234567890"), 0, 21, S("abcdefghijklmnopqrst12345678901234567890")); + test(S("abcdefghijklmnopqrst"), 20, SV("12345678901234567890"), 1, 0, S("abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 20, SV("12345678901234567890"), 1, 1, S("abcdefghijklmnopqrst2")); + test(S("abcdefghijklmnopqrst"), 20, SV("12345678901234567890"), 1, 9, S("abcdefghijklmnopqrst234567890")); + test(S("abcdefghijklmnopqrst"), 20, SV("12345678901234567890"), 1, 18, S("abcdefghijklmnopqrst234567890123456789")); + test(S("abcdefghijklmnopqrst"), 20, SV("12345678901234567890"), 1, 19, S("abcdefghijklmnopqrst2345678901234567890")); + test(S("abcdefghijklmnopqrst"), 20, SV("12345678901234567890"), 1, 20, S("abcdefghijklmnopqrst2345678901234567890")); + test(S("abcdefghijklmnopqrst"), 20, SV("12345678901234567890"), 10, 0, S("abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 20, SV("12345678901234567890"), 10, 1, S("abcdefghijklmnopqrst1")); + test(S("abcdefghijklmnopqrst"), 20, SV("12345678901234567890"), 10, 5, S("abcdefghijklmnopqrst12345")); + test(S("abcdefghijklmnopqrst"), 20, SV("12345678901234567890"), 10, 9, S("abcdefghijklmnopqrst123456789")); + test(S("abcdefghijklmnopqrst"), 20, SV("12345678901234567890"), 10, 10, S("abcdefghijklmnopqrst1234567890")); + test(S("abcdefghijklmnopqrst"), 20, SV("12345678901234567890"), 10, 11, S("abcdefghijklmnopqrst1234567890")); +} + +template +void test28() +{ + test(S("abcdefghijklmnopqrst"), 20, SV("12345678901234567890"), 19, 0, S("abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 20, SV("12345678901234567890"), 19, 1, S("abcdefghijklmnopqrst0")); + test(S("abcdefghijklmnopqrst"), 20, SV("12345678901234567890"), 19, 2, S("abcdefghijklmnopqrst0")); + test(S("abcdefghijklmnopqrst"), 20, SV("12345678901234567890"), 20, 0, S("abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 20, SV("12345678901234567890"), 20, 1, S("abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 20, SV("12345678901234567890"), 21, 0, S("can't happen")); + test(S("abcdefghijklmnopqrst"), 21, SV(""), 0, 0, S("can't happen")); + test(S("abcdefghijklmnopqrst"), 21, SV(""), 0, 1, S("can't happen")); + test(S("abcdefghijklmnopqrst"), 21, SV(""), 1, 0, S("can't happen")); + test(S("abcdefghijklmnopqrst"), 21, SV("12345"), 0, 0, S("can't happen")); + test(S("abcdefghijklmnopqrst"), 21, SV("12345"), 0, 1, S("can't happen")); + test(S("abcdefghijklmnopqrst"), 21, SV("12345"), 0, 2, S("can't happen")); + test(S("abcdefghijklmnopqrst"), 21, SV("12345"), 0, 4, S("can't happen")); + test(S("abcdefghijklmnopqrst"), 21, SV("12345"), 0, 5, S("can't happen")); + test(S("abcdefghijklmnopqrst"), 21, SV("12345"), 0, 6, S("can't happen")); + test(S("abcdefghijklmnopqrst"), 21, SV("12345"), 1, 0, S("can't happen")); + test(S("abcdefghijklmnopqrst"), 21, SV("12345"), 1, 1, S("can't happen")); + test(S("abcdefghijklmnopqrst"), 21, SV("12345"), 1, 2, S("can't happen")); + test(S("abcdefghijklmnopqrst"), 21, SV("12345"), 1, 3, S("can't happen")); + test(S("abcdefghijklmnopqrst"), 21, SV("12345"), 1, 4, S("can't happen")); + test(S("abcdefghijklmnopqrst"), 21, SV("12345"), 1, 5, S("can't happen")); + test(S("abcdefghijklmnopqrst"), 21, SV("12345"), 2, 0, S("can't happen")); + test(S("abcdefghijklmnopqrst"), 21, SV("12345"), 2, 1, S("can't happen")); + test(S("abcdefghijklmnopqrst"), 21, SV("12345"), 2, 2, S("can't happen")); + test(S("abcdefghijklmnopqrst"), 21, SV("12345"), 2, 3, S("can't happen")); + test(S("abcdefghijklmnopqrst"), 21, SV("12345"), 2, 4, S("can't happen")); + test(S("abcdefghijklmnopqrst"), 21, SV("12345"), 4, 0, S("can't happen")); + test(S("abcdefghijklmnopqrst"), 21, SV("12345"), 4, 1, S("can't happen")); + test(S("abcdefghijklmnopqrst"), 21, SV("12345"), 4, 2, S("can't happen")); + test(S("abcdefghijklmnopqrst"), 21, SV("12345"), 5, 0, S("can't happen")); + test(S("abcdefghijklmnopqrst"), 21, SV("12345"), 5, 1, S("can't happen")); + test(S("abcdefghijklmnopqrst"), 21, SV("12345"), 6, 0, S("can't happen")); + test(S("abcdefghijklmnopqrst"), 21, SV("1234567890"), 0, 0, S("can't happen")); + test(S("abcdefghijklmnopqrst"), 21, SV("1234567890"), 0, 1, S("can't happen")); + test(S("abcdefghijklmnopqrst"), 21, SV("1234567890"), 0, 5, S("can't happen")); + test(S("abcdefghijklmnopqrst"), 21, SV("1234567890"), 0, 9, S("can't happen")); + test(S("abcdefghijklmnopqrst"), 21, SV("1234567890"), 0, 10, S("can't happen")); + test(S("abcdefghijklmnopqrst"), 21, SV("1234567890"), 0, 11, S("can't happen")); + test(S("abcdefghijklmnopqrst"), 21, SV("1234567890"), 1, 0, S("can't happen")); + test(S("abcdefghijklmnopqrst"), 21, SV("1234567890"), 1, 1, S("can't happen")); + test(S("abcdefghijklmnopqrst"), 21, SV("1234567890"), 1, 4, S("can't happen")); + test(S("abcdefghijklmnopqrst"), 21, SV("1234567890"), 1, 8, S("can't happen")); + test(S("abcdefghijklmnopqrst"), 21, SV("1234567890"), 1, 9, S("can't happen")); + test(S("abcdefghijklmnopqrst"), 21, SV("1234567890"), 1, 10, S("can't happen")); + test(S("abcdefghijklmnopqrst"), 21, SV("1234567890"), 5, 0, S("can't happen")); + test(S("abcdefghijklmnopqrst"), 21, SV("1234567890"), 5, 1, S("can't happen")); + test(S("abcdefghijklmnopqrst"), 21, SV("1234567890"), 5, 2, S("can't happen")); + test(S("abcdefghijklmnopqrst"), 21, SV("1234567890"), 5, 4, S("can't happen")); + test(S("abcdefghijklmnopqrst"), 21, SV("1234567890"), 5, 5, S("can't happen")); + test(S("abcdefghijklmnopqrst"), 21, SV("1234567890"), 5, 6, S("can't happen")); +} + +template +void test29() +{ + test(S("abcdefghijklmnopqrst"), 21, SV("1234567890"), 9, 0, S("can't happen")); + test(S("abcdefghijklmnopqrst"), 21, SV("1234567890"), 9, 1, S("can't happen")); + test(S("abcdefghijklmnopqrst"), 21, SV("1234567890"), 9, 2, S("can't happen")); + test(S("abcdefghijklmnopqrst"), 21, SV("1234567890"), 10, 0, S("can't happen")); + test(S("abcdefghijklmnopqrst"), 21, SV("1234567890"), 10, 1, S("can't happen")); + test(S("abcdefghijklmnopqrst"), 21, SV("1234567890"), 11, 0, S("can't happen")); + test(S("abcdefghijklmnopqrst"), 21, SV("12345678901234567890"), 0, 0, S("can't happen")); + test(S("abcdefghijklmnopqrst"), 21, SV("12345678901234567890"), 0, 1, S("can't happen")); + test(S("abcdefghijklmnopqrst"), 21, SV("12345678901234567890"), 0, 10, S("can't happen")); + test(S("abcdefghijklmnopqrst"), 21, SV("12345678901234567890"), 0, 19, S("can't happen")); + test(S("abcdefghijklmnopqrst"), 21, SV("12345678901234567890"), 0, 20, S("can't happen")); + test(S("abcdefghijklmnopqrst"), 21, SV("12345678901234567890"), 0, 21, S("can't happen")); + test(S("abcdefghijklmnopqrst"), 21, SV("12345678901234567890"), 1, 0, S("can't happen")); + test(S("abcdefghijklmnopqrst"), 21, SV("12345678901234567890"), 1, 1, S("can't happen")); + test(S("abcdefghijklmnopqrst"), 21, SV("12345678901234567890"), 1, 9, S("can't happen")); + test(S("abcdefghijklmnopqrst"), 21, SV("12345678901234567890"), 1, 18, S("can't happen")); + test(S("abcdefghijklmnopqrst"), 21, SV("12345678901234567890"), 1, 19, S("can't happen")); + test(S("abcdefghijklmnopqrst"), 21, SV("12345678901234567890"), 1, 20, S("can't happen")); + test(S("abcdefghijklmnopqrst"), 21, SV("12345678901234567890"), 10, 0, S("can't happen")); + test(S("abcdefghijklmnopqrst"), 21, SV("12345678901234567890"), 10, 1, S("can't happen")); + test(S("abcdefghijklmnopqrst"), 21, SV("12345678901234567890"), 10, 5, S("can't happen")); + test(S("abcdefghijklmnopqrst"), 21, SV("12345678901234567890"), 10, 9, S("can't happen")); + test(S("abcdefghijklmnopqrst"), 21, SV("12345678901234567890"), 10, 10, S("can't happen")); + test(S("abcdefghijklmnopqrst"), 21, SV("12345678901234567890"), 10, 11, S("can't happen")); + test(S("abcdefghijklmnopqrst"), 21, SV("12345678901234567890"), 19, 0, S("can't happen")); + test(S("abcdefghijklmnopqrst"), 21, SV("12345678901234567890"), 19, 1, S("can't happen")); + test(S("abcdefghijklmnopqrst"), 21, SV("12345678901234567890"), 19, 2, S("can't happen")); + test(S("abcdefghijklmnopqrst"), 21, SV("12345678901234567890"), 20, 0, S("can't happen")); + test(S("abcdefghijklmnopqrst"), 21, SV("12345678901234567890"), 20, 1, S("can't happen")); + test(S("abcdefghijklmnopqrst"), 21, SV("12345678901234567890"), 21, 0, S("can't happen")); +} + +template +void test30() +{ + test_npos(S(""), 0, SV("12345678901234567890"), 0, S("12345678901234567890")); + test_npos(S(""), 0, SV("12345678901234567890"), 1, S( "2345678901234567890")); + test_npos(S(""), 0, SV("12345678901234567890"), 2, S( "345678901234567890")); + test_npos(S(""), 0, SV("12345678901234567890"), 3, S( "45678901234567890")); + test_npos(S(""), 0, SV("12345678901234567890"), 5, S( "678901234567890")); + test_npos(S(""), 0, SV("12345678901234567890"), 10, S( "1234567890")); + test_npos(S(""), 0, SV("12345678901234567890"), 21, S("can't happen")); + test_npos(S("abcdefghijklmnopqrst"), 10, SV("12345"), 0, S("abcdefghij12345klmnopqrst")); + test_npos(S("abcdefghijklmnopqrst"), 10, SV("12345"), 1, S("abcdefghij2345klmnopqrst")); + test_npos(S("abcdefghijklmnopqrst"), 10, SV("12345"), 3, S("abcdefghij45klmnopqrst")); + test_npos(S("abcdefghijklmnopqrst"), 10, SV("12345"), 5, S("abcdefghijklmnopqrst")); + test_npos(S("abcdefghijklmnopqrst"), 10, SV("12345"), 6, S("can't happen")); +} + +int main() +{ + { + typedef std::string S; + typedef std::string_view SV; + test0(); + test1(); + test2(); + test3(); + test4(); + test5(); + test6(); + test7(); + test8(); + test9(); + test10(); + test11(); + test12(); + test13(); + test14(); + test15(); + test16(); + test17(); + test18(); + test19(); + test20(); + test21(); + test22(); + test23(); + test24(); + test25(); + test26(); + test27(); + test28(); + test29(); + test30(); + } +#if TEST_STD_VER >= 11 + { + typedef std::basic_string, min_allocator> S; + typedef std::basic_string_view> SV; + test0(); + test1(); + test2(); + test3(); + test4(); + test5(); + test6(); + test7(); + test8(); + test9(); + test10(); + test11(); + test12(); + test13(); + test14(); + test15(); + test16(); + test17(); + test18(); + test19(); + test20(); + test21(); + test22(); + test23(); + test24(); + test25(); + test26(); + test27(); + test28(); + test29(); + test30(); + } +#endif + { + typedef std::string S; + typedef std::string_view SV; + S s; + SV sv = "EFGH"; + char arr[] = "IJKL"; + + s.insert(0, "CDEF", 0); // calls insert(const char *, len) + assert(s == ""); + s.clear(); + + s.insert(0, "QRST", 0, std::string::npos); // calls insert(string("QRST"), pos, npos) + assert(s == "QRST"); + s.clear(); + + s.insert(0, sv, 0); // calls insert(T, pos, npos) + assert(s == sv); + s.clear(); + + s.insert(0, sv, 0, std::string::npos); // calls insert(T, pos, npos) + assert(s == sv); + s.clear(); + + s.insert(0, arr, 0); // calls insert(const char *, len) + assert(s == ""); + s.clear(); + + s.insert(0, arr, 0, std::string::npos); // calls insert(string("IJKL"), pos, npos) + assert(s == "IJKL"); + s.clear(); + + s.insert(0, arr, 0); // calls insert(const char *, len) + assert(s == ""); + s.clear(); + } +} diff --git a/tests/external/libcxx/basic_string/string.modifiers/string_insert/size_pointer.pass.cpp b/tests/external/libcxx/basic_string/string.modifiers/string_insert/size_pointer.pass.cpp new file mode 100644 index 0000000..b4505a4 --- /dev/null +++ b/tests/external/libcxx/basic_string/string.modifiers/string_insert/size_pointer.pass.cpp @@ -0,0 +1,237 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// + +// basic_string& +// insert(size_type pos, const charT* s); + +#include +#include +#include + +#include "test_macros.h" +#include "min_allocator.h" + +template +void +test(S s, typename S::size_type pos, const typename S::value_type* str, S expected) +{ + const typename S::size_type old_size = s.size(); + S s0 = s; + if (pos <= old_size) + { + s.insert(pos, str); + LIBCPP_ASSERT(s.__invariants()); + assert(s == expected); + } +#ifndef TEST_HAS_NO_EXCEPTIONS + else + { + try + { + s.insert(pos, str); + assert(false); + } + catch (std::out_of_range&) + { + assert(pos > old_size); + assert(s == s0); + } + } +#endif +} + +int main() +{ + { + typedef std::string S; + test(S(""), 0, "", S("")); + test(S(""), 0, "12345", S("12345")); + test(S(""), 0, "1234567890", S("1234567890")); + test(S(""), 0, "12345678901234567890", S("12345678901234567890")); + test(S(""), 1, "", S("can't happen")); + test(S(""), 1, "12345", S("can't happen")); + test(S(""), 1, "1234567890", S("can't happen")); + test(S(""), 1, "12345678901234567890", S("can't happen")); + test(S("abcde"), 0, "", S("abcde")); + test(S("abcde"), 0, "12345", S("12345abcde")); + test(S("abcde"), 0, "1234567890", S("1234567890abcde")); + test(S("abcde"), 0, "12345678901234567890", S("12345678901234567890abcde")); + test(S("abcde"), 1, "", S("abcde")); + test(S("abcde"), 1, "12345", S("a12345bcde")); + test(S("abcde"), 1, "1234567890", S("a1234567890bcde")); + test(S("abcde"), 1, "12345678901234567890", S("a12345678901234567890bcde")); + test(S("abcde"), 2, "", S("abcde")); + test(S("abcde"), 2, "12345", S("ab12345cde")); + test(S("abcde"), 2, "1234567890", S("ab1234567890cde")); + test(S("abcde"), 2, "12345678901234567890", S("ab12345678901234567890cde")); + test(S("abcde"), 4, "", S("abcde")); + test(S("abcde"), 4, "12345", S("abcd12345e")); + test(S("abcde"), 4, "1234567890", S("abcd1234567890e")); + test(S("abcde"), 4, "12345678901234567890", S("abcd12345678901234567890e")); + test(S("abcde"), 5, "", S("abcde")); + test(S("abcde"), 5, "12345", S("abcde12345")); + test(S("abcde"), 5, "1234567890", S("abcde1234567890")); + test(S("abcde"), 5, "12345678901234567890", S("abcde12345678901234567890")); + test(S("abcde"), 6, "", S("can't happen")); + test(S("abcde"), 6, "12345", S("can't happen")); + test(S("abcde"), 6, "1234567890", S("can't happen")); + test(S("abcde"), 6, "12345678901234567890", S("can't happen")); + test(S("abcdefghij"), 0, "", S("abcdefghij")); + test(S("abcdefghij"), 0, "12345", S("12345abcdefghij")); + test(S("abcdefghij"), 0, "1234567890", S("1234567890abcdefghij")); + test(S("abcdefghij"), 0, "12345678901234567890", S("12345678901234567890abcdefghij")); + test(S("abcdefghij"), 1, "", S("abcdefghij")); + test(S("abcdefghij"), 1, "12345", S("a12345bcdefghij")); + test(S("abcdefghij"), 1, "1234567890", S("a1234567890bcdefghij")); + test(S("abcdefghij"), 1, "12345678901234567890", S("a12345678901234567890bcdefghij")); + test(S("abcdefghij"), 5, "", S("abcdefghij")); + test(S("abcdefghij"), 5, "12345", S("abcde12345fghij")); + test(S("abcdefghij"), 5, "1234567890", S("abcde1234567890fghij")); + test(S("abcdefghij"), 5, "12345678901234567890", S("abcde12345678901234567890fghij")); + test(S("abcdefghij"), 9, "", S("abcdefghij")); + test(S("abcdefghij"), 9, "12345", S("abcdefghi12345j")); + test(S("abcdefghij"), 9, "1234567890", S("abcdefghi1234567890j")); + test(S("abcdefghij"), 9, "12345678901234567890", S("abcdefghi12345678901234567890j")); + test(S("abcdefghij"), 10, "", S("abcdefghij")); + test(S("abcdefghij"), 10, "12345", S("abcdefghij12345")); + test(S("abcdefghij"), 10, "1234567890", S("abcdefghij1234567890")); + test(S("abcdefghij"), 10, "12345678901234567890", S("abcdefghij12345678901234567890")); + test(S("abcdefghij"), 11, "", S("can't happen")); + test(S("abcdefghij"), 11, "12345", S("can't happen")); + test(S("abcdefghij"), 11, "1234567890", S("can't happen")); + test(S("abcdefghij"), 11, "12345678901234567890", S("can't happen")); + test(S("abcdefghijklmnopqrst"), 0, "", S("abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, "12345", S("12345abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, "1234567890", S("1234567890abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, "12345678901234567890", S("12345678901234567890abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, "", S("abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, "12345", S("a12345bcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, "1234567890", S("a1234567890bcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, "12345678901234567890", S("a12345678901234567890bcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 10, "", S("abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 10, "12345", S("abcdefghij12345klmnopqrst")); + test(S("abcdefghijklmnopqrst"), 10, "1234567890", S("abcdefghij1234567890klmnopqrst")); + test(S("abcdefghijklmnopqrst"), 10, "12345678901234567890", S("abcdefghij12345678901234567890klmnopqrst")); + test(S("abcdefghijklmnopqrst"), 19, "", S("abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 19, "12345", S("abcdefghijklmnopqrs12345t")); + test(S("abcdefghijklmnopqrst"), 19, "1234567890", S("abcdefghijklmnopqrs1234567890t")); + test(S("abcdefghijklmnopqrst"), 19, "12345678901234567890", S("abcdefghijklmnopqrs12345678901234567890t")); + test(S("abcdefghijklmnopqrst"), 20, "", S("abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 20, "12345", S("abcdefghijklmnopqrst12345")); + test(S("abcdefghijklmnopqrst"), 20, "1234567890", S("abcdefghijklmnopqrst1234567890")); + test(S("abcdefghijklmnopqrst"), 20, "12345678901234567890", S("abcdefghijklmnopqrst12345678901234567890")); + test(S("abcdefghijklmnopqrst"), 21, "", S("can't happen")); + test(S("abcdefghijklmnopqrst"), 21, "12345", S("can't happen")); + test(S("abcdefghijklmnopqrst"), 21, "1234567890", S("can't happen")); + test(S("abcdefghijklmnopqrst"), 21, "12345678901234567890", S("can't happen")); + } +#if TEST_STD_VER >= 11 + { + typedef std::basic_string, min_allocator> S; + test(S(""), 0, "", S("")); + test(S(""), 0, "12345", S("12345")); + test(S(""), 0, "1234567890", S("1234567890")); + test(S(""), 0, "12345678901234567890", S("12345678901234567890")); + test(S(""), 1, "", S("can't happen")); + test(S(""), 1, "12345", S("can't happen")); + test(S(""), 1, "1234567890", S("can't happen")); + test(S(""), 1, "12345678901234567890", S("can't happen")); + test(S("abcde"), 0, "", S("abcde")); + test(S("abcde"), 0, "12345", S("12345abcde")); + test(S("abcde"), 0, "1234567890", S("1234567890abcde")); + test(S("abcde"), 0, "12345678901234567890", S("12345678901234567890abcde")); + test(S("abcde"), 1, "", S("abcde")); + test(S("abcde"), 1, "12345", S("a12345bcde")); + test(S("abcde"), 1, "1234567890", S("a1234567890bcde")); + test(S("abcde"), 1, "12345678901234567890", S("a12345678901234567890bcde")); + test(S("abcde"), 2, "", S("abcde")); + test(S("abcde"), 2, "12345", S("ab12345cde")); + test(S("abcde"), 2, "1234567890", S("ab1234567890cde")); + test(S("abcde"), 2, "12345678901234567890", S("ab12345678901234567890cde")); + test(S("abcde"), 4, "", S("abcde")); + test(S("abcde"), 4, "12345", S("abcd12345e")); + test(S("abcde"), 4, "1234567890", S("abcd1234567890e")); + test(S("abcde"), 4, "12345678901234567890", S("abcd12345678901234567890e")); + test(S("abcde"), 5, "", S("abcde")); + test(S("abcde"), 5, "12345", S("abcde12345")); + test(S("abcde"), 5, "1234567890", S("abcde1234567890")); + test(S("abcde"), 5, "12345678901234567890", S("abcde12345678901234567890")); + test(S("abcde"), 6, "", S("can't happen")); + test(S("abcde"), 6, "12345", S("can't happen")); + test(S("abcde"), 6, "1234567890", S("can't happen")); + test(S("abcde"), 6, "12345678901234567890", S("can't happen")); + test(S("abcdefghij"), 0, "", S("abcdefghij")); + test(S("abcdefghij"), 0, "12345", S("12345abcdefghij")); + test(S("abcdefghij"), 0, "1234567890", S("1234567890abcdefghij")); + test(S("abcdefghij"), 0, "12345678901234567890", S("12345678901234567890abcdefghij")); + test(S("abcdefghij"), 1, "", S("abcdefghij")); + test(S("abcdefghij"), 1, "12345", S("a12345bcdefghij")); + test(S("abcdefghij"), 1, "1234567890", S("a1234567890bcdefghij")); + test(S("abcdefghij"), 1, "12345678901234567890", S("a12345678901234567890bcdefghij")); + test(S("abcdefghij"), 5, "", S("abcdefghij")); + test(S("abcdefghij"), 5, "12345", S("abcde12345fghij")); + test(S("abcdefghij"), 5, "1234567890", S("abcde1234567890fghij")); + test(S("abcdefghij"), 5, "12345678901234567890", S("abcde12345678901234567890fghij")); + test(S("abcdefghij"), 9, "", S("abcdefghij")); + test(S("abcdefghij"), 9, "12345", S("abcdefghi12345j")); + test(S("abcdefghij"), 9, "1234567890", S("abcdefghi1234567890j")); + test(S("abcdefghij"), 9, "12345678901234567890", S("abcdefghi12345678901234567890j")); + test(S("abcdefghij"), 10, "", S("abcdefghij")); + test(S("abcdefghij"), 10, "12345", S("abcdefghij12345")); + test(S("abcdefghij"), 10, "1234567890", S("abcdefghij1234567890")); + test(S("abcdefghij"), 10, "12345678901234567890", S("abcdefghij12345678901234567890")); + test(S("abcdefghij"), 11, "", S("can't happen")); + test(S("abcdefghij"), 11, "12345", S("can't happen")); + test(S("abcdefghij"), 11, "1234567890", S("can't happen")); + test(S("abcdefghij"), 11, "12345678901234567890", S("can't happen")); + test(S("abcdefghijklmnopqrst"), 0, "", S("abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, "12345", S("12345abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, "1234567890", S("1234567890abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, "12345678901234567890", S("12345678901234567890abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, "", S("abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, "12345", S("a12345bcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, "1234567890", S("a1234567890bcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, "12345678901234567890", S("a12345678901234567890bcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 10, "", S("abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 10, "12345", S("abcdefghij12345klmnopqrst")); + test(S("abcdefghijklmnopqrst"), 10, "1234567890", S("abcdefghij1234567890klmnopqrst")); + test(S("abcdefghijklmnopqrst"), 10, "12345678901234567890", S("abcdefghij12345678901234567890klmnopqrst")); + test(S("abcdefghijklmnopqrst"), 19, "", S("abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 19, "12345", S("abcdefghijklmnopqrs12345t")); + test(S("abcdefghijklmnopqrst"), 19, "1234567890", S("abcdefghijklmnopqrs1234567890t")); + test(S("abcdefghijklmnopqrst"), 19, "12345678901234567890", S("abcdefghijklmnopqrs12345678901234567890t")); + test(S("abcdefghijklmnopqrst"), 20, "", S("abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 20, "12345", S("abcdefghijklmnopqrst12345")); + test(S("abcdefghijklmnopqrst"), 20, "1234567890", S("abcdefghijklmnopqrst1234567890")); + test(S("abcdefghijklmnopqrst"), 20, "12345678901234567890", S("abcdefghijklmnopqrst12345678901234567890")); + test(S("abcdefghijklmnopqrst"), 21, "", S("can't happen")); + test(S("abcdefghijklmnopqrst"), 21, "12345", S("can't happen")); + test(S("abcdefghijklmnopqrst"), 21, "1234567890", S("can't happen")); + test(S("abcdefghijklmnopqrst"), 21, "12345678901234567890", S("can't happen")); + } +#endif + + { // test inserting into self + typedef std::string S; + S s_short = "123/"; + S s_long = "Lorem ipsum dolor sit amet, consectetur/"; + + s_short.insert(0, s_short.c_str()); + assert(s_short == "123/123/"); + s_short.insert(0, s_short.c_str()); + assert(s_short == "123/123/123/123/"); + s_short.insert(0, s_short.c_str()); + assert(s_short == "123/123/123/123/123/123/123/123/"); + + s_long.insert(0, s_long.c_str()); + assert(s_long == "Lorem ipsum dolor sit amet, consectetur/Lorem ipsum dolor sit amet, consectetur/"); + } +} diff --git a/tests/external/libcxx/basic_string/string.modifiers/string_insert/size_pointer_size.pass.cpp b/tests/external/libcxx/basic_string/string.modifiers/string_insert/size_pointer_size.pass.cpp new file mode 100644 index 0000000..ee5991c --- /dev/null +++ b/tests/external/libcxx/basic_string/string.modifiers/string_insert/size_pointer_size.pass.cpp @@ -0,0 +1,718 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// + +// basic_string& +// insert(size_type pos, const charT* s, size_type n); + +#include +#include +#include + +#include "test_macros.h" +#include "min_allocator.h" + +template +void +test(S s, typename S::size_type pos, const typename S::value_type* str, + typename S::size_type n, S expected) +{ + const typename S::size_type old_size = s.size(); + S s0 = s; + if (pos <= old_size) + { + s.insert(pos, str, n); + LIBCPP_ASSERT(s.__invariants()); + assert(s == expected); + } +#ifndef TEST_HAS_NO_EXCEPTIONS + else + { + try + { + s.insert(pos, str, n); + assert(false); + } + catch (std::out_of_range&) + { + assert(pos > old_size); + assert(s == s0); + } + } +#endif +} + +int main() +{ + { + typedef std::string S; + test(S(""), 0, "", 0, S("")); + test(S(""), 0, "12345", 0, S("")); + test(S(""), 0, "12345", 1, S("1")); + test(S(""), 0, "12345", 2, S("12")); + test(S(""), 0, "12345", 4, S("1234")); + test(S(""), 0, "12345", 5, S("12345")); + test(S(""), 0, "1234567890", 0, S("")); + test(S(""), 0, "1234567890", 1, S("1")); + test(S(""), 0, "1234567890", 5, S("12345")); + test(S(""), 0, "1234567890", 9, S("123456789")); + test(S(""), 0, "1234567890", 10, S("1234567890")); + test(S(""), 0, "12345678901234567890", 0, S("")); + test(S(""), 0, "12345678901234567890", 1, S("1")); + test(S(""), 0, "12345678901234567890", 10, S("1234567890")); + test(S(""), 0, "12345678901234567890", 19, S("1234567890123456789")); + test(S(""), 0, "12345678901234567890", 20, S("12345678901234567890")); + test(S(""), 1, "", 0, S("can't happen")); + test(S(""), 1, "12345", 0, S("can't happen")); + test(S(""), 1, "12345", 1, S("can't happen")); + test(S(""), 1, "12345", 2, S("can't happen")); + test(S(""), 1, "12345", 4, S("can't happen")); + test(S(""), 1, "12345", 5, S("can't happen")); + test(S(""), 1, "1234567890", 0, S("can't happen")); + test(S(""), 1, "1234567890", 1, S("can't happen")); + test(S(""), 1, "1234567890", 5, S("can't happen")); + test(S(""), 1, "1234567890", 9, S("can't happen")); + test(S(""), 1, "1234567890", 10, S("can't happen")); + test(S(""), 1, "12345678901234567890", 0, S("can't happen")); + test(S(""), 1, "12345678901234567890", 1, S("can't happen")); + test(S(""), 1, "12345678901234567890", 10, S("can't happen")); + test(S(""), 1, "12345678901234567890", 19, S("can't happen")); + test(S(""), 1, "12345678901234567890", 20, S("can't happen")); + test(S("abcde"), 0, "", 0, S("abcde")); + test(S("abcde"), 0, "12345", 0, S("abcde")); + test(S("abcde"), 0, "12345", 1, S("1abcde")); + test(S("abcde"), 0, "12345", 2, S("12abcde")); + test(S("abcde"), 0, "12345", 4, S("1234abcde")); + test(S("abcde"), 0, "12345", 5, S("12345abcde")); + test(S("abcde"), 0, "1234567890", 0, S("abcde")); + test(S("abcde"), 0, "1234567890", 1, S("1abcde")); + test(S("abcde"), 0, "1234567890", 5, S("12345abcde")); + test(S("abcde"), 0, "1234567890", 9, S("123456789abcde")); + test(S("abcde"), 0, "1234567890", 10, S("1234567890abcde")); + test(S("abcde"), 0, "12345678901234567890", 0, S("abcde")); + test(S("abcde"), 0, "12345678901234567890", 1, S("1abcde")); + test(S("abcde"), 0, "12345678901234567890", 10, S("1234567890abcde")); + test(S("abcde"), 0, "12345678901234567890", 19, S("1234567890123456789abcde")); + test(S("abcde"), 0, "12345678901234567890", 20, S("12345678901234567890abcde")); + test(S("abcde"), 1, "", 0, S("abcde")); + test(S("abcde"), 1, "12345", 0, S("abcde")); + test(S("abcde"), 1, "12345", 1, S("a1bcde")); + test(S("abcde"), 1, "12345", 2, S("a12bcde")); + test(S("abcde"), 1, "12345", 4, S("a1234bcde")); + test(S("abcde"), 1, "12345", 5, S("a12345bcde")); + test(S("abcde"), 1, "1234567890", 0, S("abcde")); + test(S("abcde"), 1, "1234567890", 1, S("a1bcde")); + test(S("abcde"), 1, "1234567890", 5, S("a12345bcde")); + test(S("abcde"), 1, "1234567890", 9, S("a123456789bcde")); + test(S("abcde"), 1, "1234567890", 10, S("a1234567890bcde")); + test(S("abcde"), 1, "12345678901234567890", 0, S("abcde")); + test(S("abcde"), 1, "12345678901234567890", 1, S("a1bcde")); + test(S("abcde"), 1, "12345678901234567890", 10, S("a1234567890bcde")); + test(S("abcde"), 1, "12345678901234567890", 19, S("a1234567890123456789bcde")); + test(S("abcde"), 1, "12345678901234567890", 20, S("a12345678901234567890bcde")); + test(S("abcde"), 2, "", 0, S("abcde")); + test(S("abcde"), 2, "12345", 0, S("abcde")); + test(S("abcde"), 2, "12345", 1, S("ab1cde")); + test(S("abcde"), 2, "12345", 2, S("ab12cde")); + test(S("abcde"), 2, "12345", 4, S("ab1234cde")); + test(S("abcde"), 2, "12345", 5, S("ab12345cde")); + test(S("abcde"), 2, "1234567890", 0, S("abcde")); + test(S("abcde"), 2, "1234567890", 1, S("ab1cde")); + test(S("abcde"), 2, "1234567890", 5, S("ab12345cde")); + test(S("abcde"), 2, "1234567890", 9, S("ab123456789cde")); + test(S("abcde"), 2, "1234567890", 10, S("ab1234567890cde")); + test(S("abcde"), 2, "12345678901234567890", 0, S("abcde")); + test(S("abcde"), 2, "12345678901234567890", 1, S("ab1cde")); + test(S("abcde"), 2, "12345678901234567890", 10, S("ab1234567890cde")); + test(S("abcde"), 2, "12345678901234567890", 19, S("ab1234567890123456789cde")); + test(S("abcde"), 2, "12345678901234567890", 20, S("ab12345678901234567890cde")); + test(S("abcde"), 4, "", 0, S("abcde")); + test(S("abcde"), 4, "12345", 0, S("abcde")); + test(S("abcde"), 4, "12345", 1, S("abcd1e")); + test(S("abcde"), 4, "12345", 2, S("abcd12e")); + test(S("abcde"), 4, "12345", 4, S("abcd1234e")); + test(S("abcde"), 4, "12345", 5, S("abcd12345e")); + test(S("abcde"), 4, "1234567890", 0, S("abcde")); + test(S("abcde"), 4, "1234567890", 1, S("abcd1e")); + test(S("abcde"), 4, "1234567890", 5, S("abcd12345e")); + test(S("abcde"), 4, "1234567890", 9, S("abcd123456789e")); + test(S("abcde"), 4, "1234567890", 10, S("abcd1234567890e")); + test(S("abcde"), 4, "12345678901234567890", 0, S("abcde")); + test(S("abcde"), 4, "12345678901234567890", 1, S("abcd1e")); + test(S("abcde"), 4, "12345678901234567890", 10, S("abcd1234567890e")); + test(S("abcde"), 4, "12345678901234567890", 19, S("abcd1234567890123456789e")); + test(S("abcde"), 4, "12345678901234567890", 20, S("abcd12345678901234567890e")); + test(S("abcde"), 5, "", 0, S("abcde")); + test(S("abcde"), 5, "12345", 0, S("abcde")); + test(S("abcde"), 5, "12345", 1, S("abcde1")); + test(S("abcde"), 5, "12345", 2, S("abcde12")); + test(S("abcde"), 5, "12345", 4, S("abcde1234")); + test(S("abcde"), 5, "12345", 5, S("abcde12345")); + test(S("abcde"), 5, "1234567890", 0, S("abcde")); + test(S("abcde"), 5, "1234567890", 1, S("abcde1")); + test(S("abcde"), 5, "1234567890", 5, S("abcde12345")); + test(S("abcde"), 5, "1234567890", 9, S("abcde123456789")); + test(S("abcde"), 5, "1234567890", 10, S("abcde1234567890")); + test(S("abcde"), 5, "12345678901234567890", 0, S("abcde")); + test(S("abcde"), 5, "12345678901234567890", 1, S("abcde1")); + test(S("abcde"), 5, "12345678901234567890", 10, S("abcde1234567890")); + test(S("abcde"), 5, "12345678901234567890", 19, S("abcde1234567890123456789")); + test(S("abcde"), 5, "12345678901234567890", 20, S("abcde12345678901234567890")); + test(S("abcde"), 6, "", 0, S("can't happen")); + test(S("abcde"), 6, "12345", 0, S("can't happen")); + test(S("abcde"), 6, "12345", 1, S("can't happen")); + test(S("abcde"), 6, "12345", 2, S("can't happen")); + test(S("abcde"), 6, "12345", 4, S("can't happen")); + test(S("abcde"), 6, "12345", 5, S("can't happen")); + test(S("abcde"), 6, "1234567890", 0, S("can't happen")); + test(S("abcde"), 6, "1234567890", 1, S("can't happen")); + test(S("abcde"), 6, "1234567890", 5, S("can't happen")); + test(S("abcde"), 6, "1234567890", 9, S("can't happen")); + test(S("abcde"), 6, "1234567890", 10, S("can't happen")); + test(S("abcde"), 6, "12345678901234567890", 0, S("can't happen")); + test(S("abcde"), 6, "12345678901234567890", 1, S("can't happen")); + test(S("abcde"), 6, "12345678901234567890", 10, S("can't happen")); + test(S("abcde"), 6, "12345678901234567890", 19, S("can't happen")); + test(S("abcde"), 6, "12345678901234567890", 20, S("can't happen")); + test(S("abcdefghij"), 0, "", 0, S("abcdefghij")); + test(S("abcdefghij"), 0, "12345", 0, S("abcdefghij")); + test(S("abcdefghij"), 0, "12345", 1, S("1abcdefghij")); + test(S("abcdefghij"), 0, "12345", 2, S("12abcdefghij")); + test(S("abcdefghij"), 0, "12345", 4, S("1234abcdefghij")); + test(S("abcdefghij"), 0, "12345", 5, S("12345abcdefghij")); + test(S("abcdefghij"), 0, "1234567890", 0, S("abcdefghij")); + test(S("abcdefghij"), 0, "1234567890", 1, S("1abcdefghij")); + test(S("abcdefghij"), 0, "1234567890", 5, S("12345abcdefghij")); + test(S("abcdefghij"), 0, "1234567890", 9, S("123456789abcdefghij")); + test(S("abcdefghij"), 0, "1234567890", 10, S("1234567890abcdefghij")); + test(S("abcdefghij"), 0, "12345678901234567890", 0, S("abcdefghij")); + test(S("abcdefghij"), 0, "12345678901234567890", 1, S("1abcdefghij")); + test(S("abcdefghij"), 0, "12345678901234567890", 10, S("1234567890abcdefghij")); + test(S("abcdefghij"), 0, "12345678901234567890", 19, S("1234567890123456789abcdefghij")); + test(S("abcdefghij"), 0, "12345678901234567890", 20, S("12345678901234567890abcdefghij")); + test(S("abcdefghij"), 1, "", 0, S("abcdefghij")); + test(S("abcdefghij"), 1, "12345", 0, S("abcdefghij")); + test(S("abcdefghij"), 1, "12345", 1, S("a1bcdefghij")); + test(S("abcdefghij"), 1, "12345", 2, S("a12bcdefghij")); + test(S("abcdefghij"), 1, "12345", 4, S("a1234bcdefghij")); + test(S("abcdefghij"), 1, "12345", 5, S("a12345bcdefghij")); + test(S("abcdefghij"), 1, "1234567890", 0, S("abcdefghij")); + test(S("abcdefghij"), 1, "1234567890", 1, S("a1bcdefghij")); + test(S("abcdefghij"), 1, "1234567890", 5, S("a12345bcdefghij")); + test(S("abcdefghij"), 1, "1234567890", 9, S("a123456789bcdefghij")); + test(S("abcdefghij"), 1, "1234567890", 10, S("a1234567890bcdefghij")); + test(S("abcdefghij"), 1, "12345678901234567890", 0, S("abcdefghij")); + test(S("abcdefghij"), 1, "12345678901234567890", 1, S("a1bcdefghij")); + test(S("abcdefghij"), 1, "12345678901234567890", 10, S("a1234567890bcdefghij")); + test(S("abcdefghij"), 1, "12345678901234567890", 19, S("a1234567890123456789bcdefghij")); + test(S("abcdefghij"), 1, "12345678901234567890", 20, S("a12345678901234567890bcdefghij")); + test(S("abcdefghij"), 5, "", 0, S("abcdefghij")); + test(S("abcdefghij"), 5, "12345", 0, S("abcdefghij")); + test(S("abcdefghij"), 5, "12345", 1, S("abcde1fghij")); + test(S("abcdefghij"), 5, "12345", 2, S("abcde12fghij")); + test(S("abcdefghij"), 5, "12345", 4, S("abcde1234fghij")); + test(S("abcdefghij"), 5, "12345", 5, S("abcde12345fghij")); + test(S("abcdefghij"), 5, "1234567890", 0, S("abcdefghij")); + test(S("abcdefghij"), 5, "1234567890", 1, S("abcde1fghij")); + test(S("abcdefghij"), 5, "1234567890", 5, S("abcde12345fghij")); + test(S("abcdefghij"), 5, "1234567890", 9, S("abcde123456789fghij")); + test(S("abcdefghij"), 5, "1234567890", 10, S("abcde1234567890fghij")); + test(S("abcdefghij"), 5, "12345678901234567890", 0, S("abcdefghij")); + test(S("abcdefghij"), 5, "12345678901234567890", 1, S("abcde1fghij")); + test(S("abcdefghij"), 5, "12345678901234567890", 10, S("abcde1234567890fghij")); + test(S("abcdefghij"), 5, "12345678901234567890", 19, S("abcde1234567890123456789fghij")); + test(S("abcdefghij"), 5, "12345678901234567890", 20, S("abcde12345678901234567890fghij")); + test(S("abcdefghij"), 9, "", 0, S("abcdefghij")); + test(S("abcdefghij"), 9, "12345", 0, S("abcdefghij")); + test(S("abcdefghij"), 9, "12345", 1, S("abcdefghi1j")); + test(S("abcdefghij"), 9, "12345", 2, S("abcdefghi12j")); + test(S("abcdefghij"), 9, "12345", 4, S("abcdefghi1234j")); + test(S("abcdefghij"), 9, "12345", 5, S("abcdefghi12345j")); + test(S("abcdefghij"), 9, "1234567890", 0, S("abcdefghij")); + test(S("abcdefghij"), 9, "1234567890", 1, S("abcdefghi1j")); + test(S("abcdefghij"), 9, "1234567890", 5, S("abcdefghi12345j")); + test(S("abcdefghij"), 9, "1234567890", 9, S("abcdefghi123456789j")); + test(S("abcdefghij"), 9, "1234567890", 10, S("abcdefghi1234567890j")); + test(S("abcdefghij"), 9, "12345678901234567890", 0, S("abcdefghij")); + test(S("abcdefghij"), 9, "12345678901234567890", 1, S("abcdefghi1j")); + test(S("abcdefghij"), 9, "12345678901234567890", 10, S("abcdefghi1234567890j")); + test(S("abcdefghij"), 9, "12345678901234567890", 19, S("abcdefghi1234567890123456789j")); + test(S("abcdefghij"), 9, "12345678901234567890", 20, S("abcdefghi12345678901234567890j")); + test(S("abcdefghij"), 10, "", 0, S("abcdefghij")); + test(S("abcdefghij"), 10, "12345", 0, S("abcdefghij")); + test(S("abcdefghij"), 10, "12345", 1, S("abcdefghij1")); + test(S("abcdefghij"), 10, "12345", 2, S("abcdefghij12")); + test(S("abcdefghij"), 10, "12345", 4, S("abcdefghij1234")); + test(S("abcdefghij"), 10, "12345", 5, S("abcdefghij12345")); + test(S("abcdefghij"), 10, "1234567890", 0, S("abcdefghij")); + test(S("abcdefghij"), 10, "1234567890", 1, S("abcdefghij1")); + test(S("abcdefghij"), 10, "1234567890", 5, S("abcdefghij12345")); + test(S("abcdefghij"), 10, "1234567890", 9, S("abcdefghij123456789")); + test(S("abcdefghij"), 10, "1234567890", 10, S("abcdefghij1234567890")); + test(S("abcdefghij"), 10, "12345678901234567890", 0, S("abcdefghij")); + test(S("abcdefghij"), 10, "12345678901234567890", 1, S("abcdefghij1")); + test(S("abcdefghij"), 10, "12345678901234567890", 10, S("abcdefghij1234567890")); + test(S("abcdefghij"), 10, "12345678901234567890", 19, S("abcdefghij1234567890123456789")); + test(S("abcdefghij"), 10, "12345678901234567890", 20, S("abcdefghij12345678901234567890")); + test(S("abcdefghij"), 11, "", 0, S("can't happen")); + test(S("abcdefghij"), 11, "12345", 0, S("can't happen")); + test(S("abcdefghij"), 11, "12345", 1, S("can't happen")); + test(S("abcdefghij"), 11, "12345", 2, S("can't happen")); + test(S("abcdefghij"), 11, "12345", 4, S("can't happen")); + test(S("abcdefghij"), 11, "12345", 5, S("can't happen")); + test(S("abcdefghij"), 11, "1234567890", 0, S("can't happen")); + test(S("abcdefghij"), 11, "1234567890", 1, S("can't happen")); + test(S("abcdefghij"), 11, "1234567890", 5, S("can't happen")); + test(S("abcdefghij"), 11, "1234567890", 9, S("can't happen")); + test(S("abcdefghij"), 11, "1234567890", 10, S("can't happen")); + test(S("abcdefghij"), 11, "12345678901234567890", 0, S("can't happen")); + test(S("abcdefghij"), 11, "12345678901234567890", 1, S("can't happen")); + test(S("abcdefghij"), 11, "12345678901234567890", 10, S("can't happen")); + test(S("abcdefghij"), 11, "12345678901234567890", 19, S("can't happen")); + test(S("abcdefghij"), 11, "12345678901234567890", 20, S("can't happen")); + test(S("abcdefghijklmnopqrst"), 0, "", 0, S("abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, "12345", 0, S("abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, "12345", 1, S("1abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, "12345", 2, S("12abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, "12345", 4, S("1234abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, "12345", 5, S("12345abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, "1234567890", 0, S("abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, "1234567890", 1, S("1abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, "1234567890", 5, S("12345abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, "1234567890", 9, S("123456789abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, "1234567890", 10, S("1234567890abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, "12345678901234567890", 0, S("abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, "12345678901234567890", 1, S("1abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, "12345678901234567890", 10, S("1234567890abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, "12345678901234567890", 19, S("1234567890123456789abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, "12345678901234567890", 20, S("12345678901234567890abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, "", 0, S("abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, "12345", 0, S("abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, "12345", 1, S("a1bcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, "12345", 2, S("a12bcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, "12345", 4, S("a1234bcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, "12345", 5, S("a12345bcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, "1234567890", 0, S("abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, "1234567890", 1, S("a1bcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, "1234567890", 5, S("a12345bcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, "1234567890", 9, S("a123456789bcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, "1234567890", 10, S("a1234567890bcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, "12345678901234567890", 0, S("abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, "12345678901234567890", 1, S("a1bcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, "12345678901234567890", 10, S("a1234567890bcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, "12345678901234567890", 19, S("a1234567890123456789bcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, "12345678901234567890", 20, S("a12345678901234567890bcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 10, "", 0, S("abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 10, "12345", 0, S("abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 10, "12345", 1, S("abcdefghij1klmnopqrst")); + test(S("abcdefghijklmnopqrst"), 10, "12345", 2, S("abcdefghij12klmnopqrst")); + test(S("abcdefghijklmnopqrst"), 10, "12345", 4, S("abcdefghij1234klmnopqrst")); + test(S("abcdefghijklmnopqrst"), 10, "12345", 5, S("abcdefghij12345klmnopqrst")); + test(S("abcdefghijklmnopqrst"), 10, "1234567890", 0, S("abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 10, "1234567890", 1, S("abcdefghij1klmnopqrst")); + test(S("abcdefghijklmnopqrst"), 10, "1234567890", 5, S("abcdefghij12345klmnopqrst")); + test(S("abcdefghijklmnopqrst"), 10, "1234567890", 9, S("abcdefghij123456789klmnopqrst")); + test(S("abcdefghijklmnopqrst"), 10, "1234567890", 10, S("abcdefghij1234567890klmnopqrst")); + test(S("abcdefghijklmnopqrst"), 10, "12345678901234567890", 0, S("abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 10, "12345678901234567890", 1, S("abcdefghij1klmnopqrst")); + test(S("abcdefghijklmnopqrst"), 10, "12345678901234567890", 10, S("abcdefghij1234567890klmnopqrst")); + test(S("abcdefghijklmnopqrst"), 10, "12345678901234567890", 19, S("abcdefghij1234567890123456789klmnopqrst")); + test(S("abcdefghijklmnopqrst"), 10, "12345678901234567890", 20, S("abcdefghij12345678901234567890klmnopqrst")); + test(S("abcdefghijklmnopqrst"), 19, "", 0, S("abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 19, "12345", 0, S("abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 19, "12345", 1, S("abcdefghijklmnopqrs1t")); + test(S("abcdefghijklmnopqrst"), 19, "12345", 2, S("abcdefghijklmnopqrs12t")); + test(S("abcdefghijklmnopqrst"), 19, "12345", 4, S("abcdefghijklmnopqrs1234t")); + test(S("abcdefghijklmnopqrst"), 19, "12345", 5, S("abcdefghijklmnopqrs12345t")); + test(S("abcdefghijklmnopqrst"), 19, "1234567890", 0, S("abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 19, "1234567890", 1, S("abcdefghijklmnopqrs1t")); + test(S("abcdefghijklmnopqrst"), 19, "1234567890", 5, S("abcdefghijklmnopqrs12345t")); + test(S("abcdefghijklmnopqrst"), 19, "1234567890", 9, S("abcdefghijklmnopqrs123456789t")); + test(S("abcdefghijklmnopqrst"), 19, "1234567890", 10, S("abcdefghijklmnopqrs1234567890t")); + test(S("abcdefghijklmnopqrst"), 19, "12345678901234567890", 0, S("abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 19, "12345678901234567890", 1, S("abcdefghijklmnopqrs1t")); + test(S("abcdefghijklmnopqrst"), 19, "12345678901234567890", 10, S("abcdefghijklmnopqrs1234567890t")); + test(S("abcdefghijklmnopqrst"), 19, "12345678901234567890", 19, S("abcdefghijklmnopqrs1234567890123456789t")); + test(S("abcdefghijklmnopqrst"), 19, "12345678901234567890", 20, S("abcdefghijklmnopqrs12345678901234567890t")); + test(S("abcdefghijklmnopqrst"), 20, "", 0, S("abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 20, "12345", 0, S("abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 20, "12345", 1, S("abcdefghijklmnopqrst1")); + test(S("abcdefghijklmnopqrst"), 20, "12345", 2, S("abcdefghijklmnopqrst12")); + test(S("abcdefghijklmnopqrst"), 20, "12345", 4, S("abcdefghijklmnopqrst1234")); + test(S("abcdefghijklmnopqrst"), 20, "12345", 5, S("abcdefghijklmnopqrst12345")); + test(S("abcdefghijklmnopqrst"), 20, "1234567890", 0, S("abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 20, "1234567890", 1, S("abcdefghijklmnopqrst1")); + test(S("abcdefghijklmnopqrst"), 20, "1234567890", 5, S("abcdefghijklmnopqrst12345")); + test(S("abcdefghijklmnopqrst"), 20, "1234567890", 9, S("abcdefghijklmnopqrst123456789")); + test(S("abcdefghijklmnopqrst"), 20, "1234567890", 10, S("abcdefghijklmnopqrst1234567890")); + test(S("abcdefghijklmnopqrst"), 20, "12345678901234567890", 0, S("abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 20, "12345678901234567890", 1, S("abcdefghijklmnopqrst1")); + test(S("abcdefghijklmnopqrst"), 20, "12345678901234567890", 10, S("abcdefghijklmnopqrst1234567890")); + test(S("abcdefghijklmnopqrst"), 20, "12345678901234567890", 19, S("abcdefghijklmnopqrst1234567890123456789")); + test(S("abcdefghijklmnopqrst"), 20, "12345678901234567890", 20, S("abcdefghijklmnopqrst12345678901234567890")); + test(S("abcdefghijklmnopqrst"), 21, "", 0, S("can't happen")); + test(S("abcdefghijklmnopqrst"), 21, "12345", 0, S("can't happen")); + test(S("abcdefghijklmnopqrst"), 21, "12345", 1, S("can't happen")); + test(S("abcdefghijklmnopqrst"), 21, "12345", 2, S("can't happen")); + test(S("abcdefghijklmnopqrst"), 21, "12345", 4, S("can't happen")); + test(S("abcdefghijklmnopqrst"), 21, "12345", 5, S("can't happen")); + test(S("abcdefghijklmnopqrst"), 21, "1234567890", 0, S("can't happen")); + test(S("abcdefghijklmnopqrst"), 21, "1234567890", 1, S("can't happen")); + test(S("abcdefghijklmnopqrst"), 21, "1234567890", 5, S("can't happen")); + test(S("abcdefghijklmnopqrst"), 21, "1234567890", 9, S("can't happen")); + test(S("abcdefghijklmnopqrst"), 21, "1234567890", 10, S("can't happen")); + test(S("abcdefghijklmnopqrst"), 21, "12345678901234567890", 0, S("can't happen")); + test(S("abcdefghijklmnopqrst"), 21, "12345678901234567890", 1, S("can't happen")); + test(S("abcdefghijklmnopqrst"), 21, "12345678901234567890", 10, S("can't happen")); + test(S("abcdefghijklmnopqrst"), 21, "12345678901234567890", 19, S("can't happen")); + test(S("abcdefghijklmnopqrst"), 21, "12345678901234567890", 20, S("can't happen")); + } +#if TEST_STD_VER >= 11 + { + typedef std::basic_string, min_allocator> S; + test(S(""), 0, "", 0, S("")); + test(S(""), 0, "12345", 0, S("")); + test(S(""), 0, "12345", 1, S("1")); + test(S(""), 0, "12345", 2, S("12")); + test(S(""), 0, "12345", 4, S("1234")); + test(S(""), 0, "12345", 5, S("12345")); + test(S(""), 0, "1234567890", 0, S("")); + test(S(""), 0, "1234567890", 1, S("1")); + test(S(""), 0, "1234567890", 5, S("12345")); + test(S(""), 0, "1234567890", 9, S("123456789")); + test(S(""), 0, "1234567890", 10, S("1234567890")); + test(S(""), 0, "12345678901234567890", 0, S("")); + test(S(""), 0, "12345678901234567890", 1, S("1")); + test(S(""), 0, "12345678901234567890", 10, S("1234567890")); + test(S(""), 0, "12345678901234567890", 19, S("1234567890123456789")); + test(S(""), 0, "12345678901234567890", 20, S("12345678901234567890")); + test(S(""), 1, "", 0, S("can't happen")); + test(S(""), 1, "12345", 0, S("can't happen")); + test(S(""), 1, "12345", 1, S("can't happen")); + test(S(""), 1, "12345", 2, S("can't happen")); + test(S(""), 1, "12345", 4, S("can't happen")); + test(S(""), 1, "12345", 5, S("can't happen")); + test(S(""), 1, "1234567890", 0, S("can't happen")); + test(S(""), 1, "1234567890", 1, S("can't happen")); + test(S(""), 1, "1234567890", 5, S("can't happen")); + test(S(""), 1, "1234567890", 9, S("can't happen")); + test(S(""), 1, "1234567890", 10, S("can't happen")); + test(S(""), 1, "12345678901234567890", 0, S("can't happen")); + test(S(""), 1, "12345678901234567890", 1, S("can't happen")); + test(S(""), 1, "12345678901234567890", 10, S("can't happen")); + test(S(""), 1, "12345678901234567890", 19, S("can't happen")); + test(S(""), 1, "12345678901234567890", 20, S("can't happen")); + test(S("abcde"), 0, "", 0, S("abcde")); + test(S("abcde"), 0, "12345", 0, S("abcde")); + test(S("abcde"), 0, "12345", 1, S("1abcde")); + test(S("abcde"), 0, "12345", 2, S("12abcde")); + test(S("abcde"), 0, "12345", 4, S("1234abcde")); + test(S("abcde"), 0, "12345", 5, S("12345abcde")); + test(S("abcde"), 0, "1234567890", 0, S("abcde")); + test(S("abcde"), 0, "1234567890", 1, S("1abcde")); + test(S("abcde"), 0, "1234567890", 5, S("12345abcde")); + test(S("abcde"), 0, "1234567890", 9, S("123456789abcde")); + test(S("abcde"), 0, "1234567890", 10, S("1234567890abcde")); + test(S("abcde"), 0, "12345678901234567890", 0, S("abcde")); + test(S("abcde"), 0, "12345678901234567890", 1, S("1abcde")); + test(S("abcde"), 0, "12345678901234567890", 10, S("1234567890abcde")); + test(S("abcde"), 0, "12345678901234567890", 19, S("1234567890123456789abcde")); + test(S("abcde"), 0, "12345678901234567890", 20, S("12345678901234567890abcde")); + test(S("abcde"), 1, "", 0, S("abcde")); + test(S("abcde"), 1, "12345", 0, S("abcde")); + test(S("abcde"), 1, "12345", 1, S("a1bcde")); + test(S("abcde"), 1, "12345", 2, S("a12bcde")); + test(S("abcde"), 1, "12345", 4, S("a1234bcde")); + test(S("abcde"), 1, "12345", 5, S("a12345bcde")); + test(S("abcde"), 1, "1234567890", 0, S("abcde")); + test(S("abcde"), 1, "1234567890", 1, S("a1bcde")); + test(S("abcde"), 1, "1234567890", 5, S("a12345bcde")); + test(S("abcde"), 1, "1234567890", 9, S("a123456789bcde")); + test(S("abcde"), 1, "1234567890", 10, S("a1234567890bcde")); + test(S("abcde"), 1, "12345678901234567890", 0, S("abcde")); + test(S("abcde"), 1, "12345678901234567890", 1, S("a1bcde")); + test(S("abcde"), 1, "12345678901234567890", 10, S("a1234567890bcde")); + test(S("abcde"), 1, "12345678901234567890", 19, S("a1234567890123456789bcde")); + test(S("abcde"), 1, "12345678901234567890", 20, S("a12345678901234567890bcde")); + test(S("abcde"), 2, "", 0, S("abcde")); + test(S("abcde"), 2, "12345", 0, S("abcde")); + test(S("abcde"), 2, "12345", 1, S("ab1cde")); + test(S("abcde"), 2, "12345", 2, S("ab12cde")); + test(S("abcde"), 2, "12345", 4, S("ab1234cde")); + test(S("abcde"), 2, "12345", 5, S("ab12345cde")); + test(S("abcde"), 2, "1234567890", 0, S("abcde")); + test(S("abcde"), 2, "1234567890", 1, S("ab1cde")); + test(S("abcde"), 2, "1234567890", 5, S("ab12345cde")); + test(S("abcde"), 2, "1234567890", 9, S("ab123456789cde")); + test(S("abcde"), 2, "1234567890", 10, S("ab1234567890cde")); + test(S("abcde"), 2, "12345678901234567890", 0, S("abcde")); + test(S("abcde"), 2, "12345678901234567890", 1, S("ab1cde")); + test(S("abcde"), 2, "12345678901234567890", 10, S("ab1234567890cde")); + test(S("abcde"), 2, "12345678901234567890", 19, S("ab1234567890123456789cde")); + test(S("abcde"), 2, "12345678901234567890", 20, S("ab12345678901234567890cde")); + test(S("abcde"), 4, "", 0, S("abcde")); + test(S("abcde"), 4, "12345", 0, S("abcde")); + test(S("abcde"), 4, "12345", 1, S("abcd1e")); + test(S("abcde"), 4, "12345", 2, S("abcd12e")); + test(S("abcde"), 4, "12345", 4, S("abcd1234e")); + test(S("abcde"), 4, "12345", 5, S("abcd12345e")); + test(S("abcde"), 4, "1234567890", 0, S("abcde")); + test(S("abcde"), 4, "1234567890", 1, S("abcd1e")); + test(S("abcde"), 4, "1234567890", 5, S("abcd12345e")); + test(S("abcde"), 4, "1234567890", 9, S("abcd123456789e")); + test(S("abcde"), 4, "1234567890", 10, S("abcd1234567890e")); + test(S("abcde"), 4, "12345678901234567890", 0, S("abcde")); + test(S("abcde"), 4, "12345678901234567890", 1, S("abcd1e")); + test(S("abcde"), 4, "12345678901234567890", 10, S("abcd1234567890e")); + test(S("abcde"), 4, "12345678901234567890", 19, S("abcd1234567890123456789e")); + test(S("abcde"), 4, "12345678901234567890", 20, S("abcd12345678901234567890e")); + test(S("abcde"), 5, "", 0, S("abcde")); + test(S("abcde"), 5, "12345", 0, S("abcde")); + test(S("abcde"), 5, "12345", 1, S("abcde1")); + test(S("abcde"), 5, "12345", 2, S("abcde12")); + test(S("abcde"), 5, "12345", 4, S("abcde1234")); + test(S("abcde"), 5, "12345", 5, S("abcde12345")); + test(S("abcde"), 5, "1234567890", 0, S("abcde")); + test(S("abcde"), 5, "1234567890", 1, S("abcde1")); + test(S("abcde"), 5, "1234567890", 5, S("abcde12345")); + test(S("abcde"), 5, "1234567890", 9, S("abcde123456789")); + test(S("abcde"), 5, "1234567890", 10, S("abcde1234567890")); + test(S("abcde"), 5, "12345678901234567890", 0, S("abcde")); + test(S("abcde"), 5, "12345678901234567890", 1, S("abcde1")); + test(S("abcde"), 5, "12345678901234567890", 10, S("abcde1234567890")); + test(S("abcde"), 5, "12345678901234567890", 19, S("abcde1234567890123456789")); + test(S("abcde"), 5, "12345678901234567890", 20, S("abcde12345678901234567890")); + test(S("abcde"), 6, "", 0, S("can't happen")); + test(S("abcde"), 6, "12345", 0, S("can't happen")); + test(S("abcde"), 6, "12345", 1, S("can't happen")); + test(S("abcde"), 6, "12345", 2, S("can't happen")); + test(S("abcde"), 6, "12345", 4, S("can't happen")); + test(S("abcde"), 6, "12345", 5, S("can't happen")); + test(S("abcde"), 6, "1234567890", 0, S("can't happen")); + test(S("abcde"), 6, "1234567890", 1, S("can't happen")); + test(S("abcde"), 6, "1234567890", 5, S("can't happen")); + test(S("abcde"), 6, "1234567890", 9, S("can't happen")); + test(S("abcde"), 6, "1234567890", 10, S("can't happen")); + test(S("abcde"), 6, "12345678901234567890", 0, S("can't happen")); + test(S("abcde"), 6, "12345678901234567890", 1, S("can't happen")); + test(S("abcde"), 6, "12345678901234567890", 10, S("can't happen")); + test(S("abcde"), 6, "12345678901234567890", 19, S("can't happen")); + test(S("abcde"), 6, "12345678901234567890", 20, S("can't happen")); + test(S("abcdefghij"), 0, "", 0, S("abcdefghij")); + test(S("abcdefghij"), 0, "12345", 0, S("abcdefghij")); + test(S("abcdefghij"), 0, "12345", 1, S("1abcdefghij")); + test(S("abcdefghij"), 0, "12345", 2, S("12abcdefghij")); + test(S("abcdefghij"), 0, "12345", 4, S("1234abcdefghij")); + test(S("abcdefghij"), 0, "12345", 5, S("12345abcdefghij")); + test(S("abcdefghij"), 0, "1234567890", 0, S("abcdefghij")); + test(S("abcdefghij"), 0, "1234567890", 1, S("1abcdefghij")); + test(S("abcdefghij"), 0, "1234567890", 5, S("12345abcdefghij")); + test(S("abcdefghij"), 0, "1234567890", 9, S("123456789abcdefghij")); + test(S("abcdefghij"), 0, "1234567890", 10, S("1234567890abcdefghij")); + test(S("abcdefghij"), 0, "12345678901234567890", 0, S("abcdefghij")); + test(S("abcdefghij"), 0, "12345678901234567890", 1, S("1abcdefghij")); + test(S("abcdefghij"), 0, "12345678901234567890", 10, S("1234567890abcdefghij")); + test(S("abcdefghij"), 0, "12345678901234567890", 19, S("1234567890123456789abcdefghij")); + test(S("abcdefghij"), 0, "12345678901234567890", 20, S("12345678901234567890abcdefghij")); + test(S("abcdefghij"), 1, "", 0, S("abcdefghij")); + test(S("abcdefghij"), 1, "12345", 0, S("abcdefghij")); + test(S("abcdefghij"), 1, "12345", 1, S("a1bcdefghij")); + test(S("abcdefghij"), 1, "12345", 2, S("a12bcdefghij")); + test(S("abcdefghij"), 1, "12345", 4, S("a1234bcdefghij")); + test(S("abcdefghij"), 1, "12345", 5, S("a12345bcdefghij")); + test(S("abcdefghij"), 1, "1234567890", 0, S("abcdefghij")); + test(S("abcdefghij"), 1, "1234567890", 1, S("a1bcdefghij")); + test(S("abcdefghij"), 1, "1234567890", 5, S("a12345bcdefghij")); + test(S("abcdefghij"), 1, "1234567890", 9, S("a123456789bcdefghij")); + test(S("abcdefghij"), 1, "1234567890", 10, S("a1234567890bcdefghij")); + test(S("abcdefghij"), 1, "12345678901234567890", 0, S("abcdefghij")); + test(S("abcdefghij"), 1, "12345678901234567890", 1, S("a1bcdefghij")); + test(S("abcdefghij"), 1, "12345678901234567890", 10, S("a1234567890bcdefghij")); + test(S("abcdefghij"), 1, "12345678901234567890", 19, S("a1234567890123456789bcdefghij")); + test(S("abcdefghij"), 1, "12345678901234567890", 20, S("a12345678901234567890bcdefghij")); + test(S("abcdefghij"), 5, "", 0, S("abcdefghij")); + test(S("abcdefghij"), 5, "12345", 0, S("abcdefghij")); + test(S("abcdefghij"), 5, "12345", 1, S("abcde1fghij")); + test(S("abcdefghij"), 5, "12345", 2, S("abcde12fghij")); + test(S("abcdefghij"), 5, "12345", 4, S("abcde1234fghij")); + test(S("abcdefghij"), 5, "12345", 5, S("abcde12345fghij")); + test(S("abcdefghij"), 5, "1234567890", 0, S("abcdefghij")); + test(S("abcdefghij"), 5, "1234567890", 1, S("abcde1fghij")); + test(S("abcdefghij"), 5, "1234567890", 5, S("abcde12345fghij")); + test(S("abcdefghij"), 5, "1234567890", 9, S("abcde123456789fghij")); + test(S("abcdefghij"), 5, "1234567890", 10, S("abcde1234567890fghij")); + test(S("abcdefghij"), 5, "12345678901234567890", 0, S("abcdefghij")); + test(S("abcdefghij"), 5, "12345678901234567890", 1, S("abcde1fghij")); + test(S("abcdefghij"), 5, "12345678901234567890", 10, S("abcde1234567890fghij")); + test(S("abcdefghij"), 5, "12345678901234567890", 19, S("abcde1234567890123456789fghij")); + test(S("abcdefghij"), 5, "12345678901234567890", 20, S("abcde12345678901234567890fghij")); + test(S("abcdefghij"), 9, "", 0, S("abcdefghij")); + test(S("abcdefghij"), 9, "12345", 0, S("abcdefghij")); + test(S("abcdefghij"), 9, "12345", 1, S("abcdefghi1j")); + test(S("abcdefghij"), 9, "12345", 2, S("abcdefghi12j")); + test(S("abcdefghij"), 9, "12345", 4, S("abcdefghi1234j")); + test(S("abcdefghij"), 9, "12345", 5, S("abcdefghi12345j")); + test(S("abcdefghij"), 9, "1234567890", 0, S("abcdefghij")); + test(S("abcdefghij"), 9, "1234567890", 1, S("abcdefghi1j")); + test(S("abcdefghij"), 9, "1234567890", 5, S("abcdefghi12345j")); + test(S("abcdefghij"), 9, "1234567890", 9, S("abcdefghi123456789j")); + test(S("abcdefghij"), 9, "1234567890", 10, S("abcdefghi1234567890j")); + test(S("abcdefghij"), 9, "12345678901234567890", 0, S("abcdefghij")); + test(S("abcdefghij"), 9, "12345678901234567890", 1, S("abcdefghi1j")); + test(S("abcdefghij"), 9, "12345678901234567890", 10, S("abcdefghi1234567890j")); + test(S("abcdefghij"), 9, "12345678901234567890", 19, S("abcdefghi1234567890123456789j")); + test(S("abcdefghij"), 9, "12345678901234567890", 20, S("abcdefghi12345678901234567890j")); + test(S("abcdefghij"), 10, "", 0, S("abcdefghij")); + test(S("abcdefghij"), 10, "12345", 0, S("abcdefghij")); + test(S("abcdefghij"), 10, "12345", 1, S("abcdefghij1")); + test(S("abcdefghij"), 10, "12345", 2, S("abcdefghij12")); + test(S("abcdefghij"), 10, "12345", 4, S("abcdefghij1234")); + test(S("abcdefghij"), 10, "12345", 5, S("abcdefghij12345")); + test(S("abcdefghij"), 10, "1234567890", 0, S("abcdefghij")); + test(S("abcdefghij"), 10, "1234567890", 1, S("abcdefghij1")); + test(S("abcdefghij"), 10, "1234567890", 5, S("abcdefghij12345")); + test(S("abcdefghij"), 10, "1234567890", 9, S("abcdefghij123456789")); + test(S("abcdefghij"), 10, "1234567890", 10, S("abcdefghij1234567890")); + test(S("abcdefghij"), 10, "12345678901234567890", 0, S("abcdefghij")); + test(S("abcdefghij"), 10, "12345678901234567890", 1, S("abcdefghij1")); + test(S("abcdefghij"), 10, "12345678901234567890", 10, S("abcdefghij1234567890")); + test(S("abcdefghij"), 10, "12345678901234567890", 19, S("abcdefghij1234567890123456789")); + test(S("abcdefghij"), 10, "12345678901234567890", 20, S("abcdefghij12345678901234567890")); + test(S("abcdefghij"), 11, "", 0, S("can't happen")); + test(S("abcdefghij"), 11, "12345", 0, S("can't happen")); + test(S("abcdefghij"), 11, "12345", 1, S("can't happen")); + test(S("abcdefghij"), 11, "12345", 2, S("can't happen")); + test(S("abcdefghij"), 11, "12345", 4, S("can't happen")); + test(S("abcdefghij"), 11, "12345", 5, S("can't happen")); + test(S("abcdefghij"), 11, "1234567890", 0, S("can't happen")); + test(S("abcdefghij"), 11, "1234567890", 1, S("can't happen")); + test(S("abcdefghij"), 11, "1234567890", 5, S("can't happen")); + test(S("abcdefghij"), 11, "1234567890", 9, S("can't happen")); + test(S("abcdefghij"), 11, "1234567890", 10, S("can't happen")); + test(S("abcdefghij"), 11, "12345678901234567890", 0, S("can't happen")); + test(S("abcdefghij"), 11, "12345678901234567890", 1, S("can't happen")); + test(S("abcdefghij"), 11, "12345678901234567890", 10, S("can't happen")); + test(S("abcdefghij"), 11, "12345678901234567890", 19, S("can't happen")); + test(S("abcdefghij"), 11, "12345678901234567890", 20, S("can't happen")); + test(S("abcdefghijklmnopqrst"), 0, "", 0, S("abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, "12345", 0, S("abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, "12345", 1, S("1abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, "12345", 2, S("12abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, "12345", 4, S("1234abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, "12345", 5, S("12345abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, "1234567890", 0, S("abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, "1234567890", 1, S("1abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, "1234567890", 5, S("12345abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, "1234567890", 9, S("123456789abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, "1234567890", 10, S("1234567890abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, "12345678901234567890", 0, S("abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, "12345678901234567890", 1, S("1abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, "12345678901234567890", 10, S("1234567890abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, "12345678901234567890", 19, S("1234567890123456789abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, "12345678901234567890", 20, S("12345678901234567890abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, "", 0, S("abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, "12345", 0, S("abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, "12345", 1, S("a1bcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, "12345", 2, S("a12bcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, "12345", 4, S("a1234bcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, "12345", 5, S("a12345bcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, "1234567890", 0, S("abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, "1234567890", 1, S("a1bcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, "1234567890", 5, S("a12345bcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, "1234567890", 9, S("a123456789bcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, "1234567890", 10, S("a1234567890bcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, "12345678901234567890", 0, S("abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, "12345678901234567890", 1, S("a1bcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, "12345678901234567890", 10, S("a1234567890bcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, "12345678901234567890", 19, S("a1234567890123456789bcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, "12345678901234567890", 20, S("a12345678901234567890bcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 10, "", 0, S("abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 10, "12345", 0, S("abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 10, "12345", 1, S("abcdefghij1klmnopqrst")); + test(S("abcdefghijklmnopqrst"), 10, "12345", 2, S("abcdefghij12klmnopqrst")); + test(S("abcdefghijklmnopqrst"), 10, "12345", 4, S("abcdefghij1234klmnopqrst")); + test(S("abcdefghijklmnopqrst"), 10, "12345", 5, S("abcdefghij12345klmnopqrst")); + test(S("abcdefghijklmnopqrst"), 10, "1234567890", 0, S("abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 10, "1234567890", 1, S("abcdefghij1klmnopqrst")); + test(S("abcdefghijklmnopqrst"), 10, "1234567890", 5, S("abcdefghij12345klmnopqrst")); + test(S("abcdefghijklmnopqrst"), 10, "1234567890", 9, S("abcdefghij123456789klmnopqrst")); + test(S("abcdefghijklmnopqrst"), 10, "1234567890", 10, S("abcdefghij1234567890klmnopqrst")); + test(S("abcdefghijklmnopqrst"), 10, "12345678901234567890", 0, S("abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 10, "12345678901234567890", 1, S("abcdefghij1klmnopqrst")); + test(S("abcdefghijklmnopqrst"), 10, "12345678901234567890", 10, S("abcdefghij1234567890klmnopqrst")); + test(S("abcdefghijklmnopqrst"), 10, "12345678901234567890", 19, S("abcdefghij1234567890123456789klmnopqrst")); + test(S("abcdefghijklmnopqrst"), 10, "12345678901234567890", 20, S("abcdefghij12345678901234567890klmnopqrst")); + test(S("abcdefghijklmnopqrst"), 19, "", 0, S("abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 19, "12345", 0, S("abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 19, "12345", 1, S("abcdefghijklmnopqrs1t")); + test(S("abcdefghijklmnopqrst"), 19, "12345", 2, S("abcdefghijklmnopqrs12t")); + test(S("abcdefghijklmnopqrst"), 19, "12345", 4, S("abcdefghijklmnopqrs1234t")); + test(S("abcdefghijklmnopqrst"), 19, "12345", 5, S("abcdefghijklmnopqrs12345t")); + test(S("abcdefghijklmnopqrst"), 19, "1234567890", 0, S("abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 19, "1234567890", 1, S("abcdefghijklmnopqrs1t")); + test(S("abcdefghijklmnopqrst"), 19, "1234567890", 5, S("abcdefghijklmnopqrs12345t")); + test(S("abcdefghijklmnopqrst"), 19, "1234567890", 9, S("abcdefghijklmnopqrs123456789t")); + test(S("abcdefghijklmnopqrst"), 19, "1234567890", 10, S("abcdefghijklmnopqrs1234567890t")); + test(S("abcdefghijklmnopqrst"), 19, "12345678901234567890", 0, S("abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 19, "12345678901234567890", 1, S("abcdefghijklmnopqrs1t")); + test(S("abcdefghijklmnopqrst"), 19, "12345678901234567890", 10, S("abcdefghijklmnopqrs1234567890t")); + test(S("abcdefghijklmnopqrst"), 19, "12345678901234567890", 19, S("abcdefghijklmnopqrs1234567890123456789t")); + test(S("abcdefghijklmnopqrst"), 19, "12345678901234567890", 20, S("abcdefghijklmnopqrs12345678901234567890t")); + test(S("abcdefghijklmnopqrst"), 20, "", 0, S("abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 20, "12345", 0, S("abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 20, "12345", 1, S("abcdefghijklmnopqrst1")); + test(S("abcdefghijklmnopqrst"), 20, "12345", 2, S("abcdefghijklmnopqrst12")); + test(S("abcdefghijklmnopqrst"), 20, "12345", 4, S("abcdefghijklmnopqrst1234")); + test(S("abcdefghijklmnopqrst"), 20, "12345", 5, S("abcdefghijklmnopqrst12345")); + test(S("abcdefghijklmnopqrst"), 20, "1234567890", 0, S("abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 20, "1234567890", 1, S("abcdefghijklmnopqrst1")); + test(S("abcdefghijklmnopqrst"), 20, "1234567890", 5, S("abcdefghijklmnopqrst12345")); + test(S("abcdefghijklmnopqrst"), 20, "1234567890", 9, S("abcdefghijklmnopqrst123456789")); + test(S("abcdefghijklmnopqrst"), 20, "1234567890", 10, S("abcdefghijklmnopqrst1234567890")); + test(S("abcdefghijklmnopqrst"), 20, "12345678901234567890", 0, S("abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 20, "12345678901234567890", 1, S("abcdefghijklmnopqrst1")); + test(S("abcdefghijklmnopqrst"), 20, "12345678901234567890", 10, S("abcdefghijklmnopqrst1234567890")); + test(S("abcdefghijklmnopqrst"), 20, "12345678901234567890", 19, S("abcdefghijklmnopqrst1234567890123456789")); + test(S("abcdefghijklmnopqrst"), 20, "12345678901234567890", 20, S("abcdefghijklmnopqrst12345678901234567890")); + test(S("abcdefghijklmnopqrst"), 21, "", 0, S("can't happen")); + test(S("abcdefghijklmnopqrst"), 21, "12345", 0, S("can't happen")); + test(S("abcdefghijklmnopqrst"), 21, "12345", 1, S("can't happen")); + test(S("abcdefghijklmnopqrst"), 21, "12345", 2, S("can't happen")); + test(S("abcdefghijklmnopqrst"), 21, "12345", 4, S("can't happen")); + test(S("abcdefghijklmnopqrst"), 21, "12345", 5, S("can't happen")); + test(S("abcdefghijklmnopqrst"), 21, "1234567890", 0, S("can't happen")); + test(S("abcdefghijklmnopqrst"), 21, "1234567890", 1, S("can't happen")); + test(S("abcdefghijklmnopqrst"), 21, "1234567890", 5, S("can't happen")); + test(S("abcdefghijklmnopqrst"), 21, "1234567890", 9, S("can't happen")); + test(S("abcdefghijklmnopqrst"), 21, "1234567890", 10, S("can't happen")); + test(S("abcdefghijklmnopqrst"), 21, "12345678901234567890", 0, S("can't happen")); + test(S("abcdefghijklmnopqrst"), 21, "12345678901234567890", 1, S("can't happen")); + test(S("abcdefghijklmnopqrst"), 21, "12345678901234567890", 10, S("can't happen")); + test(S("abcdefghijklmnopqrst"), 21, "12345678901234567890", 19, S("can't happen")); + test(S("abcdefghijklmnopqrst"), 21, "12345678901234567890", 20, S("can't happen")); + } +#endif + + { // test inserting into self + typedef std::string S; + S s_short = "123/"; + S s_long = "Lorem ipsum dolor sit amet, consectetur/"; + + s_short.insert(0, s_short.data(), s_short.size()); + assert(s_short == "123/123/"); + s_short.insert(0, s_short.data(), s_short.size()); + assert(s_short == "123/123/123/123/"); + s_short.insert(0, s_short.data(), s_short.size()); + assert(s_short == "123/123/123/123/123/123/123/123/"); + + s_long.insert(0, s_long.data(), s_long.size()); + assert(s_long == "Lorem ipsum dolor sit amet, consectetur/Lorem ipsum dolor sit amet, consectetur/"); + } +} diff --git a/tests/external/libcxx/basic_string/string.modifiers/string_insert/size_size_char.pass.cpp b/tests/external/libcxx/basic_string/string.modifiers/string_insert/size_size_char.pass.cpp new file mode 100644 index 0000000..a769604 --- /dev/null +++ b/tests/external/libcxx/basic_string/string.modifiers/string_insert/size_size_char.pass.cpp @@ -0,0 +1,222 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// + +// basic_string& +// insert(size_type pos, size_type n, charT c); + +#include +#include +#include + +#include "test_macros.h" +#include "min_allocator.h" + +template +void +test(S s, typename S::size_type pos, typename S::size_type n, + typename S::value_type str, S expected) +{ + const typename S::size_type old_size = s.size(); + S s0 = s; + if (pos <= old_size) + { + s.insert(pos, n, str); + LIBCPP_ASSERT(s.__invariants()); + assert(s == expected); + } +#ifndef TEST_HAS_NO_EXCEPTIONS + else + { + try + { + s.insert(pos, n, str); + assert(false); + } + catch (std::out_of_range&) + { + assert(pos > old_size); + assert(s == s0); + } + } +#endif +} + +int main() +{ + { + typedef std::string S; + test(S(""), 0, 0, '1', S("")); + test(S(""), 0, 5, '1', S("11111")); + test(S(""), 0, 10, '1', S("1111111111")); + test(S(""), 0, 20, '1', S("11111111111111111111")); + test(S(""), 1, 0, '1', S("can't happen")); + test(S(""), 1, 5, '1', S("can't happen")); + test(S(""), 1, 10, '1', S("can't happen")); + test(S(""), 1, 20, '1', S("can't happen")); + test(S("abcde"), 0, 0, '1', S("abcde")); + test(S("abcde"), 0, 5, '1', S("11111abcde")); + test(S("abcde"), 0, 10, '1', S("1111111111abcde")); + test(S("abcde"), 0, 20, '1', S("11111111111111111111abcde")); + test(S("abcde"), 1, 0, '1', S("abcde")); + test(S("abcde"), 1, 5, '1', S("a11111bcde")); + test(S("abcde"), 1, 10, '1', S("a1111111111bcde")); + test(S("abcde"), 1, 20, '1', S("a11111111111111111111bcde")); + test(S("abcde"), 2, 0, '1', S("abcde")); + test(S("abcde"), 2, 5, '1', S("ab11111cde")); + test(S("abcde"), 2, 10, '1', S("ab1111111111cde")); + test(S("abcde"), 2, 20, '1', S("ab11111111111111111111cde")); + test(S("abcde"), 4, 0, '1', S("abcde")); + test(S("abcde"), 4, 5, '1', S("abcd11111e")); + test(S("abcde"), 4, 10, '1', S("abcd1111111111e")); + test(S("abcde"), 4, 20, '1', S("abcd11111111111111111111e")); + test(S("abcde"), 5, 0, '1', S("abcde")); + test(S("abcde"), 5, 5, '1', S("abcde11111")); + test(S("abcde"), 5, 10, '1', S("abcde1111111111")); + test(S("abcde"), 5, 20, '1', S("abcde11111111111111111111")); + test(S("abcde"), 6, 0, '1', S("can't happen")); + test(S("abcde"), 6, 5, '1', S("can't happen")); + test(S("abcde"), 6, 10, '1', S("can't happen")); + test(S("abcde"), 6, 20, '1', S("can't happen")); + test(S("abcdefghij"), 0, 0, '1', S("abcdefghij")); + test(S("abcdefghij"), 0, 5, '1', S("11111abcdefghij")); + test(S("abcdefghij"), 0, 10, '1', S("1111111111abcdefghij")); + test(S("abcdefghij"), 0, 20, '1', S("11111111111111111111abcdefghij")); + test(S("abcdefghij"), 1, 0, '1', S("abcdefghij")); + test(S("abcdefghij"), 1, 5, '1', S("a11111bcdefghij")); + test(S("abcdefghij"), 1, 10, '1', S("a1111111111bcdefghij")); + test(S("abcdefghij"), 1, 20, '1', S("a11111111111111111111bcdefghij")); + test(S("abcdefghij"), 5, 0, '1', S("abcdefghij")); + test(S("abcdefghij"), 5, 5, '1', S("abcde11111fghij")); + test(S("abcdefghij"), 5, 10, '1', S("abcde1111111111fghij")); + test(S("abcdefghij"), 5, 20, '1', S("abcde11111111111111111111fghij")); + test(S("abcdefghij"), 9, 0, '1', S("abcdefghij")); + test(S("abcdefghij"), 9, 5, '1', S("abcdefghi11111j")); + test(S("abcdefghij"), 9, 10, '1', S("abcdefghi1111111111j")); + test(S("abcdefghij"), 9, 20, '1', S("abcdefghi11111111111111111111j")); + test(S("abcdefghij"), 10, 0, '1', S("abcdefghij")); + test(S("abcdefghij"), 10, 5, '1', S("abcdefghij11111")); + test(S("abcdefghij"), 10, 10, '1', S("abcdefghij1111111111")); + test(S("abcdefghij"), 10, 20, '1', S("abcdefghij11111111111111111111")); + test(S("abcdefghij"), 11, 0, '1', S("can't happen")); + test(S("abcdefghij"), 11, 5, '1', S("can't happen")); + test(S("abcdefghij"), 11, 10, '1', S("can't happen")); + test(S("abcdefghij"), 11, 20, '1', S("can't happen")); + test(S("abcdefghijklmnopqrst"), 0, 0, '1', S("abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, 5, '1', S("11111abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, 10, '1', S("1111111111abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, 20, '1', S("11111111111111111111abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, 0, '1', S("abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, 5, '1', S("a11111bcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, 10, '1', S("a1111111111bcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, 20, '1', S("a11111111111111111111bcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 10, 0, '1', S("abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 10, 5, '1', S("abcdefghij11111klmnopqrst")); + test(S("abcdefghijklmnopqrst"), 10, 10, '1', S("abcdefghij1111111111klmnopqrst")); + test(S("abcdefghijklmnopqrst"), 10, 20, '1', S("abcdefghij11111111111111111111klmnopqrst")); + test(S("abcdefghijklmnopqrst"), 19, 0, '1', S("abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 19, 5, '1', S("abcdefghijklmnopqrs11111t")); + test(S("abcdefghijklmnopqrst"), 19, 10, '1', S("abcdefghijklmnopqrs1111111111t")); + test(S("abcdefghijklmnopqrst"), 19, 20, '1', S("abcdefghijklmnopqrs11111111111111111111t")); + test(S("abcdefghijklmnopqrst"), 20, 0, '1', S("abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 20, 5, '1', S("abcdefghijklmnopqrst11111")); + test(S("abcdefghijklmnopqrst"), 20, 10, '1', S("abcdefghijklmnopqrst1111111111")); + test(S("abcdefghijklmnopqrst"), 20, 20, '1', S("abcdefghijklmnopqrst11111111111111111111")); + test(S("abcdefghijklmnopqrst"), 21, 0, '1', S("can't happen")); + test(S("abcdefghijklmnopqrst"), 21, 5, '1', S("can't happen")); + test(S("abcdefghijklmnopqrst"), 21, 10, '1', S("can't happen")); + test(S("abcdefghijklmnopqrst"), 21, 20, '1', S("can't happen")); + } +#if TEST_STD_VER >= 11 + { + typedef std::basic_string, min_allocator> S; + test(S(""), 0, 0, '1', S("")); + test(S(""), 0, 5, '1', S("11111")); + test(S(""), 0, 10, '1', S("1111111111")); + test(S(""), 0, 20, '1', S("11111111111111111111")); + test(S(""), 1, 0, '1', S("can't happen")); + test(S(""), 1, 5, '1', S("can't happen")); + test(S(""), 1, 10, '1', S("can't happen")); + test(S(""), 1, 20, '1', S("can't happen")); + test(S("abcde"), 0, 0, '1', S("abcde")); + test(S("abcde"), 0, 5, '1', S("11111abcde")); + test(S("abcde"), 0, 10, '1', S("1111111111abcde")); + test(S("abcde"), 0, 20, '1', S("11111111111111111111abcde")); + test(S("abcde"), 1, 0, '1', S("abcde")); + test(S("abcde"), 1, 5, '1', S("a11111bcde")); + test(S("abcde"), 1, 10, '1', S("a1111111111bcde")); + test(S("abcde"), 1, 20, '1', S("a11111111111111111111bcde")); + test(S("abcde"), 2, 0, '1', S("abcde")); + test(S("abcde"), 2, 5, '1', S("ab11111cde")); + test(S("abcde"), 2, 10, '1', S("ab1111111111cde")); + test(S("abcde"), 2, 20, '1', S("ab11111111111111111111cde")); + test(S("abcde"), 4, 0, '1', S("abcde")); + test(S("abcde"), 4, 5, '1', S("abcd11111e")); + test(S("abcde"), 4, 10, '1', S("abcd1111111111e")); + test(S("abcde"), 4, 20, '1', S("abcd11111111111111111111e")); + test(S("abcde"), 5, 0, '1', S("abcde")); + test(S("abcde"), 5, 5, '1', S("abcde11111")); + test(S("abcde"), 5, 10, '1', S("abcde1111111111")); + test(S("abcde"), 5, 20, '1', S("abcde11111111111111111111")); + test(S("abcde"), 6, 0, '1', S("can't happen")); + test(S("abcde"), 6, 5, '1', S("can't happen")); + test(S("abcde"), 6, 10, '1', S("can't happen")); + test(S("abcde"), 6, 20, '1', S("can't happen")); + test(S("abcdefghij"), 0, 0, '1', S("abcdefghij")); + test(S("abcdefghij"), 0, 5, '1', S("11111abcdefghij")); + test(S("abcdefghij"), 0, 10, '1', S("1111111111abcdefghij")); + test(S("abcdefghij"), 0, 20, '1', S("11111111111111111111abcdefghij")); + test(S("abcdefghij"), 1, 0, '1', S("abcdefghij")); + test(S("abcdefghij"), 1, 5, '1', S("a11111bcdefghij")); + test(S("abcdefghij"), 1, 10, '1', S("a1111111111bcdefghij")); + test(S("abcdefghij"), 1, 20, '1', S("a11111111111111111111bcdefghij")); + test(S("abcdefghij"), 5, 0, '1', S("abcdefghij")); + test(S("abcdefghij"), 5, 5, '1', S("abcde11111fghij")); + test(S("abcdefghij"), 5, 10, '1', S("abcde1111111111fghij")); + test(S("abcdefghij"), 5, 20, '1', S("abcde11111111111111111111fghij")); + test(S("abcdefghij"), 9, 0, '1', S("abcdefghij")); + test(S("abcdefghij"), 9, 5, '1', S("abcdefghi11111j")); + test(S("abcdefghij"), 9, 10, '1', S("abcdefghi1111111111j")); + test(S("abcdefghij"), 9, 20, '1', S("abcdefghi11111111111111111111j")); + test(S("abcdefghij"), 10, 0, '1', S("abcdefghij")); + test(S("abcdefghij"), 10, 5, '1', S("abcdefghij11111")); + test(S("abcdefghij"), 10, 10, '1', S("abcdefghij1111111111")); + test(S("abcdefghij"), 10, 20, '1', S("abcdefghij11111111111111111111")); + test(S("abcdefghij"), 11, 0, '1', S("can't happen")); + test(S("abcdefghij"), 11, 5, '1', S("can't happen")); + test(S("abcdefghij"), 11, 10, '1', S("can't happen")); + test(S("abcdefghij"), 11, 20, '1', S("can't happen")); + test(S("abcdefghijklmnopqrst"), 0, 0, '1', S("abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, 5, '1', S("11111abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, 10, '1', S("1111111111abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, 20, '1', S("11111111111111111111abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, 0, '1', S("abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, 5, '1', S("a11111bcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, 10, '1', S("a1111111111bcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, 20, '1', S("a11111111111111111111bcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 10, 0, '1', S("abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 10, 5, '1', S("abcdefghij11111klmnopqrst")); + test(S("abcdefghijklmnopqrst"), 10, 10, '1', S("abcdefghij1111111111klmnopqrst")); + test(S("abcdefghijklmnopqrst"), 10, 20, '1', S("abcdefghij11111111111111111111klmnopqrst")); + test(S("abcdefghijklmnopqrst"), 19, 0, '1', S("abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 19, 5, '1', S("abcdefghijklmnopqrs11111t")); + test(S("abcdefghijklmnopqrst"), 19, 10, '1', S("abcdefghijklmnopqrs1111111111t")); + test(S("abcdefghijklmnopqrst"), 19, 20, '1', S("abcdefghijklmnopqrs11111111111111111111t")); + test(S("abcdefghijklmnopqrst"), 20, 0, '1', S("abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 20, 5, '1', S("abcdefghijklmnopqrst11111")); + test(S("abcdefghijklmnopqrst"), 20, 10, '1', S("abcdefghijklmnopqrst1111111111")); + test(S("abcdefghijklmnopqrst"), 20, 20, '1', S("abcdefghijklmnopqrst11111111111111111111")); + test(S("abcdefghijklmnopqrst"), 21, 0, '1', S("can't happen")); + test(S("abcdefghijklmnopqrst"), 21, 5, '1', S("can't happen")); + test(S("abcdefghijklmnopqrst"), 21, 10, '1', S("can't happen")); + test(S("abcdefghijklmnopqrst"), 21, 20, '1', S("can't happen")); + } +#endif +} diff --git a/tests/external/libcxx/basic_string/string.modifiers/string_insert/size_string.pass.cpp b/tests/external/libcxx/basic_string/string.modifiers/string_insert/size_string.pass.cpp new file mode 100644 index 0000000..4c3a872 --- /dev/null +++ b/tests/external/libcxx/basic_string/string.modifiers/string_insert/size_string.pass.cpp @@ -0,0 +1,230 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// + +// basic_string& +// insert(size_type pos1, const basic_string& str); + +#include +#include +#include + +#include "test_macros.h" +#include "min_allocator.h" + +template +void +test(S s, typename S::size_type pos, S str, S expected) +{ + const typename S::size_type old_size = s.size(); + S s0 = s; + if (pos <= old_size) + { + s.insert(pos, str); + LIBCPP_ASSERT(s.__invariants()); + assert(s == expected); + } +#ifndef TEST_HAS_NO_EXCEPTIONS + else + { + try + { + s.insert(pos, str); + assert(false); + } + catch (std::out_of_range&) + { + assert(pos > old_size); + assert(s == s0); + } + } +#endif +} + +int main() +{ + { + typedef std::string S; + test(S(""), 0, S(""), S("")); + test(S(""), 0, S("12345"), S("12345")); + test(S(""), 0, S("1234567890"), S("1234567890")); + test(S(""), 0, S("12345678901234567890"), S("12345678901234567890")); + test(S(""), 1, S(""), S("can't happen")); + test(S(""), 1, S("12345"), S("can't happen")); + test(S(""), 1, S("1234567890"), S("can't happen")); + test(S(""), 1, S("12345678901234567890"), S("can't happen")); + test(S("abcde"), 0, S(""), S("abcde")); + test(S("abcde"), 0, S("12345"), S("12345abcde")); + test(S("abcde"), 0, S("1234567890"), S("1234567890abcde")); + test(S("abcde"), 0, S("12345678901234567890"), S("12345678901234567890abcde")); + test(S("abcde"), 1, S(""), S("abcde")); + test(S("abcde"), 1, S("12345"), S("a12345bcde")); + test(S("abcde"), 1, S("1234567890"), S("a1234567890bcde")); + test(S("abcde"), 1, S("12345678901234567890"), S("a12345678901234567890bcde")); + test(S("abcde"), 2, S(""), S("abcde")); + test(S("abcde"), 2, S("12345"), S("ab12345cde")); + test(S("abcde"), 2, S("1234567890"), S("ab1234567890cde")); + test(S("abcde"), 2, S("12345678901234567890"), S("ab12345678901234567890cde")); + test(S("abcde"), 4, S(""), S("abcde")); + test(S("abcde"), 4, S("12345"), S("abcd12345e")); + test(S("abcde"), 4, S("1234567890"), S("abcd1234567890e")); + test(S("abcde"), 4, S("12345678901234567890"), S("abcd12345678901234567890e")); + test(S("abcde"), 5, S(""), S("abcde")); + test(S("abcde"), 5, S("12345"), S("abcde12345")); + test(S("abcde"), 5, S("1234567890"), S("abcde1234567890")); + test(S("abcde"), 5, S("12345678901234567890"), S("abcde12345678901234567890")); + test(S("abcde"), 6, S(""), S("can't happen")); + test(S("abcde"), 6, S("12345"), S("can't happen")); + test(S("abcde"), 6, S("1234567890"), S("can't happen")); + test(S("abcde"), 6, S("12345678901234567890"), S("can't happen")); + test(S("abcdefghij"), 0, S(""), S("abcdefghij")); + test(S("abcdefghij"), 0, S("12345"), S("12345abcdefghij")); + test(S("abcdefghij"), 0, S("1234567890"), S("1234567890abcdefghij")); + test(S("abcdefghij"), 0, S("12345678901234567890"), S("12345678901234567890abcdefghij")); + test(S("abcdefghij"), 1, S(""), S("abcdefghij")); + test(S("abcdefghij"), 1, S("12345"), S("a12345bcdefghij")); + test(S("abcdefghij"), 1, S("1234567890"), S("a1234567890bcdefghij")); + test(S("abcdefghij"), 1, S("12345678901234567890"), S("a12345678901234567890bcdefghij")); + test(S("abcdefghij"), 5, S(""), S("abcdefghij")); + test(S("abcdefghij"), 5, S("12345"), S("abcde12345fghij")); + test(S("abcdefghij"), 5, S("1234567890"), S("abcde1234567890fghij")); + test(S("abcdefghij"), 5, S("12345678901234567890"), S("abcde12345678901234567890fghij")); + test(S("abcdefghij"), 9, S(""), S("abcdefghij")); + test(S("abcdefghij"), 9, S("12345"), S("abcdefghi12345j")); + test(S("abcdefghij"), 9, S("1234567890"), S("abcdefghi1234567890j")); + test(S("abcdefghij"), 9, S("12345678901234567890"), S("abcdefghi12345678901234567890j")); + test(S("abcdefghij"), 10, S(""), S("abcdefghij")); + test(S("abcdefghij"), 10, S("12345"), S("abcdefghij12345")); + test(S("abcdefghij"), 10, S("1234567890"), S("abcdefghij1234567890")); + test(S("abcdefghij"), 10, S("12345678901234567890"), S("abcdefghij12345678901234567890")); + test(S("abcdefghij"), 11, S(""), S("can't happen")); + test(S("abcdefghij"), 11, S("12345"), S("can't happen")); + test(S("abcdefghij"), 11, S("1234567890"), S("can't happen")); + test(S("abcdefghij"), 11, S("12345678901234567890"), S("can't happen")); + test(S("abcdefghijklmnopqrst"), 0, S(""), S("abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, S("12345"), S("12345abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, S("1234567890"), S("1234567890abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, S("12345678901234567890"), S("12345678901234567890abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, S(""), S("abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, S("12345"), S("a12345bcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, S("1234567890"), S("a1234567890bcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, S("12345678901234567890"), S("a12345678901234567890bcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 10, S(""), S("abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 10, S("12345"), S("abcdefghij12345klmnopqrst")); + test(S("abcdefghijklmnopqrst"), 10, S("1234567890"), S("abcdefghij1234567890klmnopqrst")); + test(S("abcdefghijklmnopqrst"), 10, S("12345678901234567890"), S("abcdefghij12345678901234567890klmnopqrst")); + test(S("abcdefghijklmnopqrst"), 19, S(""), S("abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 19, S("12345"), S("abcdefghijklmnopqrs12345t")); + test(S("abcdefghijklmnopqrst"), 19, S("1234567890"), S("abcdefghijklmnopqrs1234567890t")); + test(S("abcdefghijklmnopqrst"), 19, S("12345678901234567890"), S("abcdefghijklmnopqrs12345678901234567890t")); + test(S("abcdefghijklmnopqrst"), 20, S(""), S("abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 20, S("12345"), S("abcdefghijklmnopqrst12345")); + test(S("abcdefghijklmnopqrst"), 20, S("1234567890"), S("abcdefghijklmnopqrst1234567890")); + test(S("abcdefghijklmnopqrst"), 20, S("12345678901234567890"), S("abcdefghijklmnopqrst12345678901234567890")); + test(S("abcdefghijklmnopqrst"), 21, S(""), S("can't happen")); + test(S("abcdefghijklmnopqrst"), 21, S("12345"), S("can't happen")); + test(S("abcdefghijklmnopqrst"), 21, S("1234567890"), S("can't happen")); + test(S("abcdefghijklmnopqrst"), 21, S("12345678901234567890"), S("can't happen")); + } +#if TEST_STD_VER >= 11 + { + typedef std::basic_string, min_allocator> S; + test(S(""), 0, S(""), S("")); + test(S(""), 0, S("12345"), S("12345")); + test(S(""), 0, S("1234567890"), S("1234567890")); + test(S(""), 0, S("12345678901234567890"), S("12345678901234567890")); + test(S(""), 1, S(""), S("can't happen")); + test(S(""), 1, S("12345"), S("can't happen")); + test(S(""), 1, S("1234567890"), S("can't happen")); + test(S(""), 1, S("12345678901234567890"), S("can't happen")); + test(S("abcde"), 0, S(""), S("abcde")); + test(S("abcde"), 0, S("12345"), S("12345abcde")); + test(S("abcde"), 0, S("1234567890"), S("1234567890abcde")); + test(S("abcde"), 0, S("12345678901234567890"), S("12345678901234567890abcde")); + test(S("abcde"), 1, S(""), S("abcde")); + test(S("abcde"), 1, S("12345"), S("a12345bcde")); + test(S("abcde"), 1, S("1234567890"), S("a1234567890bcde")); + test(S("abcde"), 1, S("12345678901234567890"), S("a12345678901234567890bcde")); + test(S("abcde"), 2, S(""), S("abcde")); + test(S("abcde"), 2, S("12345"), S("ab12345cde")); + test(S("abcde"), 2, S("1234567890"), S("ab1234567890cde")); + test(S("abcde"), 2, S("12345678901234567890"), S("ab12345678901234567890cde")); + test(S("abcde"), 4, S(""), S("abcde")); + test(S("abcde"), 4, S("12345"), S("abcd12345e")); + test(S("abcde"), 4, S("1234567890"), S("abcd1234567890e")); + test(S("abcde"), 4, S("12345678901234567890"), S("abcd12345678901234567890e")); + test(S("abcde"), 5, S(""), S("abcde")); + test(S("abcde"), 5, S("12345"), S("abcde12345")); + test(S("abcde"), 5, S("1234567890"), S("abcde1234567890")); + test(S("abcde"), 5, S("12345678901234567890"), S("abcde12345678901234567890")); + test(S("abcde"), 6, S(""), S("can't happen")); + test(S("abcde"), 6, S("12345"), S("can't happen")); + test(S("abcde"), 6, S("1234567890"), S("can't happen")); + test(S("abcde"), 6, S("12345678901234567890"), S("can't happen")); + test(S("abcdefghij"), 0, S(""), S("abcdefghij")); + test(S("abcdefghij"), 0, S("12345"), S("12345abcdefghij")); + test(S("abcdefghij"), 0, S("1234567890"), S("1234567890abcdefghij")); + test(S("abcdefghij"), 0, S("12345678901234567890"), S("12345678901234567890abcdefghij")); + test(S("abcdefghij"), 1, S(""), S("abcdefghij")); + test(S("abcdefghij"), 1, S("12345"), S("a12345bcdefghij")); + test(S("abcdefghij"), 1, S("1234567890"), S("a1234567890bcdefghij")); + test(S("abcdefghij"), 1, S("12345678901234567890"), S("a12345678901234567890bcdefghij")); + test(S("abcdefghij"), 5, S(""), S("abcdefghij")); + test(S("abcdefghij"), 5, S("12345"), S("abcde12345fghij")); + test(S("abcdefghij"), 5, S("1234567890"), S("abcde1234567890fghij")); + test(S("abcdefghij"), 5, S("12345678901234567890"), S("abcde12345678901234567890fghij")); + test(S("abcdefghij"), 9, S(""), S("abcdefghij")); + test(S("abcdefghij"), 9, S("12345"), S("abcdefghi12345j")); + test(S("abcdefghij"), 9, S("1234567890"), S("abcdefghi1234567890j")); + test(S("abcdefghij"), 9, S("12345678901234567890"), S("abcdefghi12345678901234567890j")); + test(S("abcdefghij"), 10, S(""), S("abcdefghij")); + test(S("abcdefghij"), 10, S("12345"), S("abcdefghij12345")); + test(S("abcdefghij"), 10, S("1234567890"), S("abcdefghij1234567890")); + test(S("abcdefghij"), 10, S("12345678901234567890"), S("abcdefghij12345678901234567890")); + test(S("abcdefghij"), 11, S(""), S("can't happen")); + test(S("abcdefghij"), 11, S("12345"), S("can't happen")); + test(S("abcdefghij"), 11, S("1234567890"), S("can't happen")); + test(S("abcdefghij"), 11, S("12345678901234567890"), S("can't happen")); + test(S("abcdefghijklmnopqrst"), 0, S(""), S("abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, S("12345"), S("12345abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, S("1234567890"), S("1234567890abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, S("12345678901234567890"), S("12345678901234567890abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, S(""), S("abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, S("12345"), S("a12345bcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, S("1234567890"), S("a1234567890bcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, S("12345678901234567890"), S("a12345678901234567890bcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 10, S(""), S("abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 10, S("12345"), S("abcdefghij12345klmnopqrst")); + test(S("abcdefghijklmnopqrst"), 10, S("1234567890"), S("abcdefghij1234567890klmnopqrst")); + test(S("abcdefghijklmnopqrst"), 10, S("12345678901234567890"), S("abcdefghij12345678901234567890klmnopqrst")); + test(S("abcdefghijklmnopqrst"), 19, S(""), S("abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 19, S("12345"), S("abcdefghijklmnopqrs12345t")); + test(S("abcdefghijklmnopqrst"), 19, S("1234567890"), S("abcdefghijklmnopqrs1234567890t")); + test(S("abcdefghijklmnopqrst"), 19, S("12345678901234567890"), S("abcdefghijklmnopqrs12345678901234567890t")); + test(S("abcdefghijklmnopqrst"), 20, S(""), S("abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 20, S("12345"), S("abcdefghijklmnopqrst12345")); + test(S("abcdefghijklmnopqrst"), 20, S("1234567890"), S("abcdefghijklmnopqrst1234567890")); + test(S("abcdefghijklmnopqrst"), 20, S("12345678901234567890"), S("abcdefghijklmnopqrst12345678901234567890")); + test(S("abcdefghijklmnopqrst"), 21, S(""), S("can't happen")); + test(S("abcdefghijklmnopqrst"), 21, S("12345"), S("can't happen")); + test(S("abcdefghijklmnopqrst"), 21, S("1234567890"), S("can't happen")); + test(S("abcdefghijklmnopqrst"), 21, S("12345678901234567890"), S("can't happen")); + } +#endif + +#if TEST_STD_VER > 3 + { // LWG 2946 + std::string s; + s.insert(0, {"abc", 1}); + assert(s.size() == 1); + assert(s == "a"); + } +#endif +} diff --git a/tests/external/libcxx/basic_string/string.modifiers/string_insert/size_string_size_size.pass.cpp b/tests/external/libcxx/basic_string/string.modifiers/string_insert/size_string_size_size.pass.cpp new file mode 100644 index 0000000..67ba7ec --- /dev/null +++ b/tests/external/libcxx/basic_string/string.modifiers/string_insert/size_string_size_size.pass.cpp @@ -0,0 +1,1803 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// + +// basic_string& +// insert(size_type pos1, const basic_string& str, +// size_type pos2, size_type n=npos); +// the "=npos" was added in C++14 + +#include +#include +#include + +#include "test_macros.h" +#include "min_allocator.h" + +template +void +test(S s, typename S::size_type pos1, S str, typename S::size_type pos2, + typename S::size_type n, S expected) +{ + const typename S::size_type old_size = s.size(); + S s0 = s; + if (pos1 <= old_size && pos2 <= str.size()) + { + s.insert(pos1, str, pos2, n); + LIBCPP_ASSERT(s.__invariants()); + assert(s == expected); + } +#ifndef TEST_HAS_NO_EXCEPTIONS + else + { + try + { + s.insert(pos1, str, pos2, n); + assert(false); + } + catch (std::out_of_range&) + { + assert(pos1 > old_size || pos2 > str.size()); + assert(s == s0); + } + } +#endif +} + +template +void +test_npos(S s, typename S::size_type pos1, S str, typename S::size_type pos2, S expected) +{ + const typename S::size_type old_size = s.size(); + S s0 = s; + if (pos1 <= old_size && pos2 <= str.size()) + { + s.insert(pos1, str, pos2); + LIBCPP_ASSERT(s.__invariants()); + assert(s == expected); + } +#ifndef TEST_HAS_NO_EXCEPTIONS + else + { + try + { + s.insert(pos1, str, pos2); + assert(false); + } + catch (std::out_of_range&) + { + assert(pos1 > old_size || pos2 > str.size()); + assert(s == s0); + } + } +#endif +} + + +template +void test0() +{ + test(S(""), 0, S(""), 0, 0, S("")); + test(S(""), 0, S(""), 0, 1, S("")); + test(S(""), 0, S(""), 1, 0, S("can't happen")); + test(S(""), 0, S("12345"), 0, 0, S("")); + test(S(""), 0, S("12345"), 0, 1, S("1")); + test(S(""), 0, S("12345"), 0, 2, S("12")); + test(S(""), 0, S("12345"), 0, 4, S("1234")); + test(S(""), 0, S("12345"), 0, 5, S("12345")); + test(S(""), 0, S("12345"), 0, 6, S("12345")); + test(S(""), 0, S("12345"), 1, 0, S("")); + test(S(""), 0, S("12345"), 1, 1, S("2")); + test(S(""), 0, S("12345"), 1, 2, S("23")); + test(S(""), 0, S("12345"), 1, 3, S("234")); + test(S(""), 0, S("12345"), 1, 4, S("2345")); + test(S(""), 0, S("12345"), 1, 5, S("2345")); + test(S(""), 0, S("12345"), 2, 0, S("")); + test(S(""), 0, S("12345"), 2, 1, S("3")); + test(S(""), 0, S("12345"), 2, 2, S("34")); + test(S(""), 0, S("12345"), 2, 3, S("345")); + test(S(""), 0, S("12345"), 2, 4, S("345")); + test(S(""), 0, S("12345"), 4, 0, S("")); + test(S(""), 0, S("12345"), 4, 1, S("5")); + test(S(""), 0, S("12345"), 4, 2, S("5")); + test(S(""), 0, S("12345"), 5, 0, S("")); + test(S(""), 0, S("12345"), 5, 1, S("")); + test(S(""), 0, S("12345"), 6, 0, S("can't happen")); + test(S(""), 0, S("1234567890"), 0, 0, S("")); + test(S(""), 0, S("1234567890"), 0, 1, S("1")); + test(S(""), 0, S("1234567890"), 0, 5, S("12345")); + test(S(""), 0, S("1234567890"), 0, 9, S("123456789")); + test(S(""), 0, S("1234567890"), 0, 10, S("1234567890")); + test(S(""), 0, S("1234567890"), 0, 11, S("1234567890")); + test(S(""), 0, S("1234567890"), 1, 0, S("")); + test(S(""), 0, S("1234567890"), 1, 1, S("2")); + test(S(""), 0, S("1234567890"), 1, 4, S("2345")); + test(S(""), 0, S("1234567890"), 1, 8, S("23456789")); + test(S(""), 0, S("1234567890"), 1, 9, S("234567890")); + test(S(""), 0, S("1234567890"), 1, 10, S("234567890")); + test(S(""), 0, S("1234567890"), 5, 0, S("")); + test(S(""), 0, S("1234567890"), 5, 1, S("6")); + test(S(""), 0, S("1234567890"), 5, 2, S("67")); + test(S(""), 0, S("1234567890"), 5, 4, S("6789")); + test(S(""), 0, S("1234567890"), 5, 5, S("67890")); + test(S(""), 0, S("1234567890"), 5, 6, S("67890")); + test(S(""), 0, S("1234567890"), 9, 0, S("")); + test(S(""), 0, S("1234567890"), 9, 1, S("0")); + test(S(""), 0, S("1234567890"), 9, 2, S("0")); + test(S(""), 0, S("1234567890"), 10, 0, S("")); + test(S(""), 0, S("1234567890"), 10, 1, S("")); + test(S(""), 0, S("1234567890"), 11, 0, S("can't happen")); +} + +template +void test1() +{ + test(S(""), 0, S("12345678901234567890"), 0, 0, S("")); + test(S(""), 0, S("12345678901234567890"), 0, 1, S("1")); + test(S(""), 0, S("12345678901234567890"), 0, 10, S("1234567890")); + test(S(""), 0, S("12345678901234567890"), 0, 19, S("1234567890123456789")); + test(S(""), 0, S("12345678901234567890"), 0, 20, S("12345678901234567890")); + test(S(""), 0, S("12345678901234567890"), 0, 21, S("12345678901234567890")); + test(S(""), 0, S("12345678901234567890"), 1, 0, S("")); + test(S(""), 0, S("12345678901234567890"), 1, 1, S("2")); + test(S(""), 0, S("12345678901234567890"), 1, 9, S("234567890")); + test(S(""), 0, S("12345678901234567890"), 1, 18, S("234567890123456789")); + test(S(""), 0, S("12345678901234567890"), 1, 19, S("2345678901234567890")); + test(S(""), 0, S("12345678901234567890"), 1, 20, S("2345678901234567890")); + test(S(""), 0, S("12345678901234567890"), 10, 0, S("")); + test(S(""), 0, S("12345678901234567890"), 10, 1, S("1")); + test(S(""), 0, S("12345678901234567890"), 10, 5, S("12345")); + test(S(""), 0, S("12345678901234567890"), 10, 9, S("123456789")); + test(S(""), 0, S("12345678901234567890"), 10, 10, S("1234567890")); + test(S(""), 0, S("12345678901234567890"), 10, 11, S("1234567890")); + test(S(""), 0, S("12345678901234567890"), 19, 0, S("")); + test(S(""), 0, S("12345678901234567890"), 19, 1, S("0")); + test(S(""), 0, S("12345678901234567890"), 19, 2, S("0")); + test(S(""), 0, S("12345678901234567890"), 20, 0, S("")); + test(S(""), 0, S("12345678901234567890"), 20, 1, S("")); + test(S(""), 0, S("12345678901234567890"), 21, 0, S("can't happen")); + test(S(""), 1, S(""), 0, 0, S("can't happen")); + test(S(""), 1, S(""), 0, 1, S("can't happen")); + test(S(""), 1, S(""), 1, 0, S("can't happen")); + test(S(""), 1, S("12345"), 0, 0, S("can't happen")); + test(S(""), 1, S("12345"), 0, 1, S("can't happen")); + test(S(""), 1, S("12345"), 0, 2, S("can't happen")); + test(S(""), 1, S("12345"), 0, 4, S("can't happen")); + test(S(""), 1, S("12345"), 0, 5, S("can't happen")); + test(S(""), 1, S("12345"), 0, 6, S("can't happen")); + test(S(""), 1, S("12345"), 1, 0, S("can't happen")); + test(S(""), 1, S("12345"), 1, 1, S("can't happen")); + test(S(""), 1, S("12345"), 1, 2, S("can't happen")); + test(S(""), 1, S("12345"), 1, 3, S("can't happen")); + test(S(""), 1, S("12345"), 1, 4, S("can't happen")); + test(S(""), 1, S("12345"), 1, 5, S("can't happen")); + test(S(""), 1, S("12345"), 2, 0, S("can't happen")); + test(S(""), 1, S("12345"), 2, 1, S("can't happen")); + test(S(""), 1, S("12345"), 2, 2, S("can't happen")); + test(S(""), 1, S("12345"), 2, 3, S("can't happen")); + test(S(""), 1, S("12345"), 2, 4, S("can't happen")); + test(S(""), 1, S("12345"), 4, 0, S("can't happen")); + test(S(""), 1, S("12345"), 4, 1, S("can't happen")); + test(S(""), 1, S("12345"), 4, 2, S("can't happen")); + test(S(""), 1, S("12345"), 5, 0, S("can't happen")); + test(S(""), 1, S("12345"), 5, 1, S("can't happen")); + test(S(""), 1, S("12345"), 6, 0, S("can't happen")); +} + +template +void test2() +{ + test(S(""), 1, S("1234567890"), 0, 0, S("can't happen")); + test(S(""), 1, S("1234567890"), 0, 1, S("can't happen")); + test(S(""), 1, S("1234567890"), 0, 5, S("can't happen")); + test(S(""), 1, S("1234567890"), 0, 9, S("can't happen")); + test(S(""), 1, S("1234567890"), 0, 10, S("can't happen")); + test(S(""), 1, S("1234567890"), 0, 11, S("can't happen")); + test(S(""), 1, S("1234567890"), 1, 0, S("can't happen")); + test(S(""), 1, S("1234567890"), 1, 1, S("can't happen")); + test(S(""), 1, S("1234567890"), 1, 4, S("can't happen")); + test(S(""), 1, S("1234567890"), 1, 8, S("can't happen")); + test(S(""), 1, S("1234567890"), 1, 9, S("can't happen")); + test(S(""), 1, S("1234567890"), 1, 10, S("can't happen")); + test(S(""), 1, S("1234567890"), 5, 0, S("can't happen")); + test(S(""), 1, S("1234567890"), 5, 1, S("can't happen")); + test(S(""), 1, S("1234567890"), 5, 2, S("can't happen")); + test(S(""), 1, S("1234567890"), 5, 4, S("can't happen")); + test(S(""), 1, S("1234567890"), 5, 5, S("can't happen")); + test(S(""), 1, S("1234567890"), 5, 6, S("can't happen")); + test(S(""), 1, S("1234567890"), 9, 0, S("can't happen")); + test(S(""), 1, S("1234567890"), 9, 1, S("can't happen")); + test(S(""), 1, S("1234567890"), 9, 2, S("can't happen")); + test(S(""), 1, S("1234567890"), 10, 0, S("can't happen")); + test(S(""), 1, S("1234567890"), 10, 1, S("can't happen")); + test(S(""), 1, S("1234567890"), 11, 0, S("can't happen")); + test(S(""), 1, S("12345678901234567890"), 0, 0, S("can't happen")); + test(S(""), 1, S("12345678901234567890"), 0, 1, S("can't happen")); + test(S(""), 1, S("12345678901234567890"), 0, 10, S("can't happen")); + test(S(""), 1, S("12345678901234567890"), 0, 19, S("can't happen")); + test(S(""), 1, S("12345678901234567890"), 0, 20, S("can't happen")); + test(S(""), 1, S("12345678901234567890"), 0, 21, S("can't happen")); + test(S(""), 1, S("12345678901234567890"), 1, 0, S("can't happen")); + test(S(""), 1, S("12345678901234567890"), 1, 1, S("can't happen")); + test(S(""), 1, S("12345678901234567890"), 1, 9, S("can't happen")); + test(S(""), 1, S("12345678901234567890"), 1, 18, S("can't happen")); + test(S(""), 1, S("12345678901234567890"), 1, 19, S("can't happen")); + test(S(""), 1, S("12345678901234567890"), 1, 20, S("can't happen")); + test(S(""), 1, S("12345678901234567890"), 10, 0, S("can't happen")); + test(S(""), 1, S("12345678901234567890"), 10, 1, S("can't happen")); + test(S(""), 1, S("12345678901234567890"), 10, 5, S("can't happen")); + test(S(""), 1, S("12345678901234567890"), 10, 9, S("can't happen")); + test(S(""), 1, S("12345678901234567890"), 10, 10, S("can't happen")); + test(S(""), 1, S("12345678901234567890"), 10, 11, S("can't happen")); + test(S(""), 1, S("12345678901234567890"), 19, 0, S("can't happen")); + test(S(""), 1, S("12345678901234567890"), 19, 1, S("can't happen")); + test(S(""), 1, S("12345678901234567890"), 19, 2, S("can't happen")); + test(S(""), 1, S("12345678901234567890"), 20, 0, S("can't happen")); + test(S(""), 1, S("12345678901234567890"), 20, 1, S("can't happen")); + test(S(""), 1, S("12345678901234567890"), 21, 0, S("can't happen")); + test(S("abcde"), 0, S(""), 0, 0, S("abcde")); + test(S("abcde"), 0, S(""), 0, 1, S("abcde")); +} + +template +void test3() +{ + test(S("abcde"), 0, S(""), 1, 0, S("can't happen")); + test(S("abcde"), 0, S("12345"), 0, 0, S("abcde")); + test(S("abcde"), 0, S("12345"), 0, 1, S("1abcde")); + test(S("abcde"), 0, S("12345"), 0, 2, S("12abcde")); + test(S("abcde"), 0, S("12345"), 0, 4, S("1234abcde")); + test(S("abcde"), 0, S("12345"), 0, 5, S("12345abcde")); + test(S("abcde"), 0, S("12345"), 0, 6, S("12345abcde")); + test(S("abcde"), 0, S("12345"), 1, 0, S("abcde")); + test(S("abcde"), 0, S("12345"), 1, 1, S("2abcde")); + test(S("abcde"), 0, S("12345"), 1, 2, S("23abcde")); + test(S("abcde"), 0, S("12345"), 1, 3, S("234abcde")); + test(S("abcde"), 0, S("12345"), 1, 4, S("2345abcde")); + test(S("abcde"), 0, S("12345"), 1, 5, S("2345abcde")); + test(S("abcde"), 0, S("12345"), 2, 0, S("abcde")); + test(S("abcde"), 0, S("12345"), 2, 1, S("3abcde")); + test(S("abcde"), 0, S("12345"), 2, 2, S("34abcde")); + test(S("abcde"), 0, S("12345"), 2, 3, S("345abcde")); + test(S("abcde"), 0, S("12345"), 2, 4, S("345abcde")); + test(S("abcde"), 0, S("12345"), 4, 0, S("abcde")); + test(S("abcde"), 0, S("12345"), 4, 1, S("5abcde")); + test(S("abcde"), 0, S("12345"), 4, 2, S("5abcde")); + test(S("abcde"), 0, S("12345"), 5, 0, S("abcde")); + test(S("abcde"), 0, S("12345"), 5, 1, S("abcde")); + test(S("abcde"), 0, S("12345"), 6, 0, S("can't happen")); + test(S("abcde"), 0, S("1234567890"), 0, 0, S("abcde")); + test(S("abcde"), 0, S("1234567890"), 0, 1, S("1abcde")); + test(S("abcde"), 0, S("1234567890"), 0, 5, S("12345abcde")); + test(S("abcde"), 0, S("1234567890"), 0, 9, S("123456789abcde")); + test(S("abcde"), 0, S("1234567890"), 0, 10, S("1234567890abcde")); + test(S("abcde"), 0, S("1234567890"), 0, 11, S("1234567890abcde")); + test(S("abcde"), 0, S("1234567890"), 1, 0, S("abcde")); + test(S("abcde"), 0, S("1234567890"), 1, 1, S("2abcde")); + test(S("abcde"), 0, S("1234567890"), 1, 4, S("2345abcde")); + test(S("abcde"), 0, S("1234567890"), 1, 8, S("23456789abcde")); + test(S("abcde"), 0, S("1234567890"), 1, 9, S("234567890abcde")); + test(S("abcde"), 0, S("1234567890"), 1, 10, S("234567890abcde")); + test(S("abcde"), 0, S("1234567890"), 5, 0, S("abcde")); + test(S("abcde"), 0, S("1234567890"), 5, 1, S("6abcde")); + test(S("abcde"), 0, S("1234567890"), 5, 2, S("67abcde")); + test(S("abcde"), 0, S("1234567890"), 5, 4, S("6789abcde")); + test(S("abcde"), 0, S("1234567890"), 5, 5, S("67890abcde")); + test(S("abcde"), 0, S("1234567890"), 5, 6, S("67890abcde")); + test(S("abcde"), 0, S("1234567890"), 9, 0, S("abcde")); + test(S("abcde"), 0, S("1234567890"), 9, 1, S("0abcde")); + test(S("abcde"), 0, S("1234567890"), 9, 2, S("0abcde")); + test(S("abcde"), 0, S("1234567890"), 10, 0, S("abcde")); + test(S("abcde"), 0, S("1234567890"), 10, 1, S("abcde")); + test(S("abcde"), 0, S("1234567890"), 11, 0, S("can't happen")); + test(S("abcde"), 0, S("12345678901234567890"), 0, 0, S("abcde")); + test(S("abcde"), 0, S("12345678901234567890"), 0, 1, S("1abcde")); +} + +template +void test4() +{ + test(S("abcde"), 0, S("12345678901234567890"), 0, 10, S("1234567890abcde")); + test(S("abcde"), 0, S("12345678901234567890"), 0, 19, S("1234567890123456789abcde")); + test(S("abcde"), 0, S("12345678901234567890"), 0, 20, S("12345678901234567890abcde")); + test(S("abcde"), 0, S("12345678901234567890"), 0, 21, S("12345678901234567890abcde")); + test(S("abcde"), 0, S("12345678901234567890"), 1, 0, S("abcde")); + test(S("abcde"), 0, S("12345678901234567890"), 1, 1, S("2abcde")); + test(S("abcde"), 0, S("12345678901234567890"), 1, 9, S("234567890abcde")); + test(S("abcde"), 0, S("12345678901234567890"), 1, 18, S("234567890123456789abcde")); + test(S("abcde"), 0, S("12345678901234567890"), 1, 19, S("2345678901234567890abcde")); + test(S("abcde"), 0, S("12345678901234567890"), 1, 20, S("2345678901234567890abcde")); + test(S("abcde"), 0, S("12345678901234567890"), 10, 0, S("abcde")); + test(S("abcde"), 0, S("12345678901234567890"), 10, 1, S("1abcde")); + test(S("abcde"), 0, S("12345678901234567890"), 10, 5, S("12345abcde")); + test(S("abcde"), 0, S("12345678901234567890"), 10, 9, S("123456789abcde")); + test(S("abcde"), 0, S("12345678901234567890"), 10, 10, S("1234567890abcde")); + test(S("abcde"), 0, S("12345678901234567890"), 10, 11, S("1234567890abcde")); + test(S("abcde"), 0, S("12345678901234567890"), 19, 0, S("abcde")); + test(S("abcde"), 0, S("12345678901234567890"), 19, 1, S("0abcde")); + test(S("abcde"), 0, S("12345678901234567890"), 19, 2, S("0abcde")); + test(S("abcde"), 0, S("12345678901234567890"), 20, 0, S("abcde")); + test(S("abcde"), 0, S("12345678901234567890"), 20, 1, S("abcde")); + test(S("abcde"), 0, S("12345678901234567890"), 21, 0, S("can't happen")); + test(S("abcde"), 1, S(""), 0, 0, S("abcde")); + test(S("abcde"), 1, S(""), 0, 1, S("abcde")); + test(S("abcde"), 1, S(""), 1, 0, S("can't happen")); + test(S("abcde"), 1, S("12345"), 0, 0, S("abcde")); + test(S("abcde"), 1, S("12345"), 0, 1, S("a1bcde")); + test(S("abcde"), 1, S("12345"), 0, 2, S("a12bcde")); + test(S("abcde"), 1, S("12345"), 0, 4, S("a1234bcde")); + test(S("abcde"), 1, S("12345"), 0, 5, S("a12345bcde")); + test(S("abcde"), 1, S("12345"), 0, 6, S("a12345bcde")); + test(S("abcde"), 1, S("12345"), 1, 0, S("abcde")); + test(S("abcde"), 1, S("12345"), 1, 1, S("a2bcde")); + test(S("abcde"), 1, S("12345"), 1, 2, S("a23bcde")); + test(S("abcde"), 1, S("12345"), 1, 3, S("a234bcde")); + test(S("abcde"), 1, S("12345"), 1, 4, S("a2345bcde")); + test(S("abcde"), 1, S("12345"), 1, 5, S("a2345bcde")); + test(S("abcde"), 1, S("12345"), 2, 0, S("abcde")); + test(S("abcde"), 1, S("12345"), 2, 1, S("a3bcde")); + test(S("abcde"), 1, S("12345"), 2, 2, S("a34bcde")); + test(S("abcde"), 1, S("12345"), 2, 3, S("a345bcde")); + test(S("abcde"), 1, S("12345"), 2, 4, S("a345bcde")); + test(S("abcde"), 1, S("12345"), 4, 0, S("abcde")); + test(S("abcde"), 1, S("12345"), 4, 1, S("a5bcde")); + test(S("abcde"), 1, S("12345"), 4, 2, S("a5bcde")); + test(S("abcde"), 1, S("12345"), 5, 0, S("abcde")); + test(S("abcde"), 1, S("12345"), 5, 1, S("abcde")); + test(S("abcde"), 1, S("12345"), 6, 0, S("can't happen")); + test(S("abcde"), 1, S("1234567890"), 0, 0, S("abcde")); + test(S("abcde"), 1, S("1234567890"), 0, 1, S("a1bcde")); +} + +template +void test5() +{ + test(S("abcde"), 1, S("1234567890"), 0, 5, S("a12345bcde")); + test(S("abcde"), 1, S("1234567890"), 0, 9, S("a123456789bcde")); + test(S("abcde"), 1, S("1234567890"), 0, 10, S("a1234567890bcde")); + test(S("abcde"), 1, S("1234567890"), 0, 11, S("a1234567890bcde")); + test(S("abcde"), 1, S("1234567890"), 1, 0, S("abcde")); + test(S("abcde"), 1, S("1234567890"), 1, 1, S("a2bcde")); + test(S("abcde"), 1, S("1234567890"), 1, 4, S("a2345bcde")); + test(S("abcde"), 1, S("1234567890"), 1, 8, S("a23456789bcde")); + test(S("abcde"), 1, S("1234567890"), 1, 9, S("a234567890bcde")); + test(S("abcde"), 1, S("1234567890"), 1, 10, S("a234567890bcde")); + test(S("abcde"), 1, S("1234567890"), 5, 0, S("abcde")); + test(S("abcde"), 1, S("1234567890"), 5, 1, S("a6bcde")); + test(S("abcde"), 1, S("1234567890"), 5, 2, S("a67bcde")); + test(S("abcde"), 1, S("1234567890"), 5, 4, S("a6789bcde")); + test(S("abcde"), 1, S("1234567890"), 5, 5, S("a67890bcde")); + test(S("abcde"), 1, S("1234567890"), 5, 6, S("a67890bcde")); + test(S("abcde"), 1, S("1234567890"), 9, 0, S("abcde")); + test(S("abcde"), 1, S("1234567890"), 9, 1, S("a0bcde")); + test(S("abcde"), 1, S("1234567890"), 9, 2, S("a0bcde")); + test(S("abcde"), 1, S("1234567890"), 10, 0, S("abcde")); + test(S("abcde"), 1, S("1234567890"), 10, 1, S("abcde")); + test(S("abcde"), 1, S("1234567890"), 11, 0, S("can't happen")); + test(S("abcde"), 1, S("12345678901234567890"), 0, 0, S("abcde")); + test(S("abcde"), 1, S("12345678901234567890"), 0, 1, S("a1bcde")); + test(S("abcde"), 1, S("12345678901234567890"), 0, 10, S("a1234567890bcde")); + test(S("abcde"), 1, S("12345678901234567890"), 0, 19, S("a1234567890123456789bcde")); + test(S("abcde"), 1, S("12345678901234567890"), 0, 20, S("a12345678901234567890bcde")); + test(S("abcde"), 1, S("12345678901234567890"), 0, 21, S("a12345678901234567890bcde")); + test(S("abcde"), 1, S("12345678901234567890"), 1, 0, S("abcde")); + test(S("abcde"), 1, S("12345678901234567890"), 1, 1, S("a2bcde")); + test(S("abcde"), 1, S("12345678901234567890"), 1, 9, S("a234567890bcde")); + test(S("abcde"), 1, S("12345678901234567890"), 1, 18, S("a234567890123456789bcde")); + test(S("abcde"), 1, S("12345678901234567890"), 1, 19, S("a2345678901234567890bcde")); + test(S("abcde"), 1, S("12345678901234567890"), 1, 20, S("a2345678901234567890bcde")); + test(S("abcde"), 1, S("12345678901234567890"), 10, 0, S("abcde")); + test(S("abcde"), 1, S("12345678901234567890"), 10, 1, S("a1bcde")); + test(S("abcde"), 1, S("12345678901234567890"), 10, 5, S("a12345bcde")); + test(S("abcde"), 1, S("12345678901234567890"), 10, 9, S("a123456789bcde")); + test(S("abcde"), 1, S("12345678901234567890"), 10, 10, S("a1234567890bcde")); + test(S("abcde"), 1, S("12345678901234567890"), 10, 11, S("a1234567890bcde")); + test(S("abcde"), 1, S("12345678901234567890"), 19, 0, S("abcde")); + test(S("abcde"), 1, S("12345678901234567890"), 19, 1, S("a0bcde")); + test(S("abcde"), 1, S("12345678901234567890"), 19, 2, S("a0bcde")); + test(S("abcde"), 1, S("12345678901234567890"), 20, 0, S("abcde")); + test(S("abcde"), 1, S("12345678901234567890"), 20, 1, S("abcde")); + test(S("abcde"), 1, S("12345678901234567890"), 21, 0, S("can't happen")); + test(S("abcde"), 2, S(""), 0, 0, S("abcde")); + test(S("abcde"), 2, S(""), 0, 1, S("abcde")); + test(S("abcde"), 2, S(""), 1, 0, S("can't happen")); + test(S("abcde"), 2, S("12345"), 0, 0, S("abcde")); +} + +template +void test6() +{ + test(S("abcde"), 2, S("12345"), 0, 1, S("ab1cde")); + test(S("abcde"), 2, S("12345"), 0, 2, S("ab12cde")); + test(S("abcde"), 2, S("12345"), 0, 4, S("ab1234cde")); + test(S("abcde"), 2, S("12345"), 0, 5, S("ab12345cde")); + test(S("abcde"), 2, S("12345"), 0, 6, S("ab12345cde")); + test(S("abcde"), 2, S("12345"), 1, 0, S("abcde")); + test(S("abcde"), 2, S("12345"), 1, 1, S("ab2cde")); + test(S("abcde"), 2, S("12345"), 1, 2, S("ab23cde")); + test(S("abcde"), 2, S("12345"), 1, 3, S("ab234cde")); + test(S("abcde"), 2, S("12345"), 1, 4, S("ab2345cde")); + test(S("abcde"), 2, S("12345"), 1, 5, S("ab2345cde")); + test(S("abcde"), 2, S("12345"), 2, 0, S("abcde")); + test(S("abcde"), 2, S("12345"), 2, 1, S("ab3cde")); + test(S("abcde"), 2, S("12345"), 2, 2, S("ab34cde")); + test(S("abcde"), 2, S("12345"), 2, 3, S("ab345cde")); + test(S("abcde"), 2, S("12345"), 2, 4, S("ab345cde")); + test(S("abcde"), 2, S("12345"), 4, 0, S("abcde")); + test(S("abcde"), 2, S("12345"), 4, 1, S("ab5cde")); + test(S("abcde"), 2, S("12345"), 4, 2, S("ab5cde")); + test(S("abcde"), 2, S("12345"), 5, 0, S("abcde")); + test(S("abcde"), 2, S("12345"), 5, 1, S("abcde")); + test(S("abcde"), 2, S("12345"), 6, 0, S("can't happen")); + test(S("abcde"), 2, S("1234567890"), 0, 0, S("abcde")); + test(S("abcde"), 2, S("1234567890"), 0, 1, S("ab1cde")); + test(S("abcde"), 2, S("1234567890"), 0, 5, S("ab12345cde")); + test(S("abcde"), 2, S("1234567890"), 0, 9, S("ab123456789cde")); + test(S("abcde"), 2, S("1234567890"), 0, 10, S("ab1234567890cde")); + test(S("abcde"), 2, S("1234567890"), 0, 11, S("ab1234567890cde")); + test(S("abcde"), 2, S("1234567890"), 1, 0, S("abcde")); + test(S("abcde"), 2, S("1234567890"), 1, 1, S("ab2cde")); + test(S("abcde"), 2, S("1234567890"), 1, 4, S("ab2345cde")); + test(S("abcde"), 2, S("1234567890"), 1, 8, S("ab23456789cde")); + test(S("abcde"), 2, S("1234567890"), 1, 9, S("ab234567890cde")); + test(S("abcde"), 2, S("1234567890"), 1, 10, S("ab234567890cde")); + test(S("abcde"), 2, S("1234567890"), 5, 0, S("abcde")); + test(S("abcde"), 2, S("1234567890"), 5, 1, S("ab6cde")); + test(S("abcde"), 2, S("1234567890"), 5, 2, S("ab67cde")); + test(S("abcde"), 2, S("1234567890"), 5, 4, S("ab6789cde")); + test(S("abcde"), 2, S("1234567890"), 5, 5, S("ab67890cde")); + test(S("abcde"), 2, S("1234567890"), 5, 6, S("ab67890cde")); + test(S("abcde"), 2, S("1234567890"), 9, 0, S("abcde")); + test(S("abcde"), 2, S("1234567890"), 9, 1, S("ab0cde")); + test(S("abcde"), 2, S("1234567890"), 9, 2, S("ab0cde")); + test(S("abcde"), 2, S("1234567890"), 10, 0, S("abcde")); + test(S("abcde"), 2, S("1234567890"), 10, 1, S("abcde")); + test(S("abcde"), 2, S("1234567890"), 11, 0, S("can't happen")); + test(S("abcde"), 2, S("12345678901234567890"), 0, 0, S("abcde")); + test(S("abcde"), 2, S("12345678901234567890"), 0, 1, S("ab1cde")); + test(S("abcde"), 2, S("12345678901234567890"), 0, 10, S("ab1234567890cde")); + test(S("abcde"), 2, S("12345678901234567890"), 0, 19, S("ab1234567890123456789cde")); +} + +template +void test7() +{ + test(S("abcde"), 2, S("12345678901234567890"), 0, 20, S("ab12345678901234567890cde")); + test(S("abcde"), 2, S("12345678901234567890"), 0, 21, S("ab12345678901234567890cde")); + test(S("abcde"), 2, S("12345678901234567890"), 1, 0, S("abcde")); + test(S("abcde"), 2, S("12345678901234567890"), 1, 1, S("ab2cde")); + test(S("abcde"), 2, S("12345678901234567890"), 1, 9, S("ab234567890cde")); + test(S("abcde"), 2, S("12345678901234567890"), 1, 18, S("ab234567890123456789cde")); + test(S("abcde"), 2, S("12345678901234567890"), 1, 19, S("ab2345678901234567890cde")); + test(S("abcde"), 2, S("12345678901234567890"), 1, 20, S("ab2345678901234567890cde")); + test(S("abcde"), 2, S("12345678901234567890"), 10, 0, S("abcde")); + test(S("abcde"), 2, S("12345678901234567890"), 10, 1, S("ab1cde")); + test(S("abcde"), 2, S("12345678901234567890"), 10, 5, S("ab12345cde")); + test(S("abcde"), 2, S("12345678901234567890"), 10, 9, S("ab123456789cde")); + test(S("abcde"), 2, S("12345678901234567890"), 10, 10, S("ab1234567890cde")); + test(S("abcde"), 2, S("12345678901234567890"), 10, 11, S("ab1234567890cde")); + test(S("abcde"), 2, S("12345678901234567890"), 19, 0, S("abcde")); + test(S("abcde"), 2, S("12345678901234567890"), 19, 1, S("ab0cde")); + test(S("abcde"), 2, S("12345678901234567890"), 19, 2, S("ab0cde")); + test(S("abcde"), 2, S("12345678901234567890"), 20, 0, S("abcde")); + test(S("abcde"), 2, S("12345678901234567890"), 20, 1, S("abcde")); + test(S("abcde"), 2, S("12345678901234567890"), 21, 0, S("can't happen")); + test(S("abcde"), 4, S(""), 0, 0, S("abcde")); + test(S("abcde"), 4, S(""), 0, 1, S("abcde")); + test(S("abcde"), 4, S(""), 1, 0, S("can't happen")); + test(S("abcde"), 4, S("12345"), 0, 0, S("abcde")); + test(S("abcde"), 4, S("12345"), 0, 1, S("abcd1e")); + test(S("abcde"), 4, S("12345"), 0, 2, S("abcd12e")); + test(S("abcde"), 4, S("12345"), 0, 4, S("abcd1234e")); + test(S("abcde"), 4, S("12345"), 0, 5, S("abcd12345e")); + test(S("abcde"), 4, S("12345"), 0, 6, S("abcd12345e")); + test(S("abcde"), 4, S("12345"), 1, 0, S("abcde")); + test(S("abcde"), 4, S("12345"), 1, 1, S("abcd2e")); + test(S("abcde"), 4, S("12345"), 1, 2, S("abcd23e")); + test(S("abcde"), 4, S("12345"), 1, 3, S("abcd234e")); + test(S("abcde"), 4, S("12345"), 1, 4, S("abcd2345e")); + test(S("abcde"), 4, S("12345"), 1, 5, S("abcd2345e")); + test(S("abcde"), 4, S("12345"), 2, 0, S("abcde")); + test(S("abcde"), 4, S("12345"), 2, 1, S("abcd3e")); + test(S("abcde"), 4, S("12345"), 2, 2, S("abcd34e")); + test(S("abcde"), 4, S("12345"), 2, 3, S("abcd345e")); + test(S("abcde"), 4, S("12345"), 2, 4, S("abcd345e")); + test(S("abcde"), 4, S("12345"), 4, 0, S("abcde")); + test(S("abcde"), 4, S("12345"), 4, 1, S("abcd5e")); + test(S("abcde"), 4, S("12345"), 4, 2, S("abcd5e")); + test(S("abcde"), 4, S("12345"), 5, 0, S("abcde")); + test(S("abcde"), 4, S("12345"), 5, 1, S("abcde")); + test(S("abcde"), 4, S("12345"), 6, 0, S("can't happen")); + test(S("abcde"), 4, S("1234567890"), 0, 0, S("abcde")); + test(S("abcde"), 4, S("1234567890"), 0, 1, S("abcd1e")); + test(S("abcde"), 4, S("1234567890"), 0, 5, S("abcd12345e")); + test(S("abcde"), 4, S("1234567890"), 0, 9, S("abcd123456789e")); +} + +template +void test8() +{ + test(S("abcde"), 4, S("1234567890"), 0, 10, S("abcd1234567890e")); + test(S("abcde"), 4, S("1234567890"), 0, 11, S("abcd1234567890e")); + test(S("abcde"), 4, S("1234567890"), 1, 0, S("abcde")); + test(S("abcde"), 4, S("1234567890"), 1, 1, S("abcd2e")); + test(S("abcde"), 4, S("1234567890"), 1, 4, S("abcd2345e")); + test(S("abcde"), 4, S("1234567890"), 1, 8, S("abcd23456789e")); + test(S("abcde"), 4, S("1234567890"), 1, 9, S("abcd234567890e")); + test(S("abcde"), 4, S("1234567890"), 1, 10, S("abcd234567890e")); + test(S("abcde"), 4, S("1234567890"), 5, 0, S("abcde")); + test(S("abcde"), 4, S("1234567890"), 5, 1, S("abcd6e")); + test(S("abcde"), 4, S("1234567890"), 5, 2, S("abcd67e")); + test(S("abcde"), 4, S("1234567890"), 5, 4, S("abcd6789e")); + test(S("abcde"), 4, S("1234567890"), 5, 5, S("abcd67890e")); + test(S("abcde"), 4, S("1234567890"), 5, 6, S("abcd67890e")); + test(S("abcde"), 4, S("1234567890"), 9, 0, S("abcde")); + test(S("abcde"), 4, S("1234567890"), 9, 1, S("abcd0e")); + test(S("abcde"), 4, S("1234567890"), 9, 2, S("abcd0e")); + test(S("abcde"), 4, S("1234567890"), 10, 0, S("abcde")); + test(S("abcde"), 4, S("1234567890"), 10, 1, S("abcde")); + test(S("abcde"), 4, S("1234567890"), 11, 0, S("can't happen")); + test(S("abcde"), 4, S("12345678901234567890"), 0, 0, S("abcde")); + test(S("abcde"), 4, S("12345678901234567890"), 0, 1, S("abcd1e")); + test(S("abcde"), 4, S("12345678901234567890"), 0, 10, S("abcd1234567890e")); + test(S("abcde"), 4, S("12345678901234567890"), 0, 19, S("abcd1234567890123456789e")); + test(S("abcde"), 4, S("12345678901234567890"), 0, 20, S("abcd12345678901234567890e")); + test(S("abcde"), 4, S("12345678901234567890"), 0, 21, S("abcd12345678901234567890e")); + test(S("abcde"), 4, S("12345678901234567890"), 1, 0, S("abcde")); + test(S("abcde"), 4, S("12345678901234567890"), 1, 1, S("abcd2e")); + test(S("abcde"), 4, S("12345678901234567890"), 1, 9, S("abcd234567890e")); + test(S("abcde"), 4, S("12345678901234567890"), 1, 18, S("abcd234567890123456789e")); + test(S("abcde"), 4, S("12345678901234567890"), 1, 19, S("abcd2345678901234567890e")); + test(S("abcde"), 4, S("12345678901234567890"), 1, 20, S("abcd2345678901234567890e")); + test(S("abcde"), 4, S("12345678901234567890"), 10, 0, S("abcde")); + test(S("abcde"), 4, S("12345678901234567890"), 10, 1, S("abcd1e")); + test(S("abcde"), 4, S("12345678901234567890"), 10, 5, S("abcd12345e")); + test(S("abcde"), 4, S("12345678901234567890"), 10, 9, S("abcd123456789e")); + test(S("abcde"), 4, S("12345678901234567890"), 10, 10, S("abcd1234567890e")); + test(S("abcde"), 4, S("12345678901234567890"), 10, 11, S("abcd1234567890e")); + test(S("abcde"), 4, S("12345678901234567890"), 19, 0, S("abcde")); + test(S("abcde"), 4, S("12345678901234567890"), 19, 1, S("abcd0e")); + test(S("abcde"), 4, S("12345678901234567890"), 19, 2, S("abcd0e")); + test(S("abcde"), 4, S("12345678901234567890"), 20, 0, S("abcde")); + test(S("abcde"), 4, S("12345678901234567890"), 20, 1, S("abcde")); + test(S("abcde"), 4, S("12345678901234567890"), 21, 0, S("can't happen")); + test(S("abcde"), 5, S(""), 0, 0, S("abcde")); + test(S("abcde"), 5, S(""), 0, 1, S("abcde")); + test(S("abcde"), 5, S(""), 1, 0, S("can't happen")); + test(S("abcde"), 5, S("12345"), 0, 0, S("abcde")); + test(S("abcde"), 5, S("12345"), 0, 1, S("abcde1")); + test(S("abcde"), 5, S("12345"), 0, 2, S("abcde12")); +} + +template +void test9() +{ + test(S("abcde"), 5, S("12345"), 0, 4, S("abcde1234")); + test(S("abcde"), 5, S("12345"), 0, 5, S("abcde12345")); + test(S("abcde"), 5, S("12345"), 0, 6, S("abcde12345")); + test(S("abcde"), 5, S("12345"), 1, 0, S("abcde")); + test(S("abcde"), 5, S("12345"), 1, 1, S("abcde2")); + test(S("abcde"), 5, S("12345"), 1, 2, S("abcde23")); + test(S("abcde"), 5, S("12345"), 1, 3, S("abcde234")); + test(S("abcde"), 5, S("12345"), 1, 4, S("abcde2345")); + test(S("abcde"), 5, S("12345"), 1, 5, S("abcde2345")); + test(S("abcde"), 5, S("12345"), 2, 0, S("abcde")); + test(S("abcde"), 5, S("12345"), 2, 1, S("abcde3")); + test(S("abcde"), 5, S("12345"), 2, 2, S("abcde34")); + test(S("abcde"), 5, S("12345"), 2, 3, S("abcde345")); + test(S("abcde"), 5, S("12345"), 2, 4, S("abcde345")); + test(S("abcde"), 5, S("12345"), 4, 0, S("abcde")); + test(S("abcde"), 5, S("12345"), 4, 1, S("abcde5")); + test(S("abcde"), 5, S("12345"), 4, 2, S("abcde5")); + test(S("abcde"), 5, S("12345"), 5, 0, S("abcde")); + test(S("abcde"), 5, S("12345"), 5, 1, S("abcde")); + test(S("abcde"), 5, S("12345"), 6, 0, S("can't happen")); + test(S("abcde"), 5, S("1234567890"), 0, 0, S("abcde")); + test(S("abcde"), 5, S("1234567890"), 0, 1, S("abcde1")); + test(S("abcde"), 5, S("1234567890"), 0, 5, S("abcde12345")); + test(S("abcde"), 5, S("1234567890"), 0, 9, S("abcde123456789")); + test(S("abcde"), 5, S("1234567890"), 0, 10, S("abcde1234567890")); + test(S("abcde"), 5, S("1234567890"), 0, 11, S("abcde1234567890")); + test(S("abcde"), 5, S("1234567890"), 1, 0, S("abcde")); + test(S("abcde"), 5, S("1234567890"), 1, 1, S("abcde2")); + test(S("abcde"), 5, S("1234567890"), 1, 4, S("abcde2345")); + test(S("abcde"), 5, S("1234567890"), 1, 8, S("abcde23456789")); + test(S("abcde"), 5, S("1234567890"), 1, 9, S("abcde234567890")); + test(S("abcde"), 5, S("1234567890"), 1, 10, S("abcde234567890")); + test(S("abcde"), 5, S("1234567890"), 5, 0, S("abcde")); + test(S("abcde"), 5, S("1234567890"), 5, 1, S("abcde6")); + test(S("abcde"), 5, S("1234567890"), 5, 2, S("abcde67")); + test(S("abcde"), 5, S("1234567890"), 5, 4, S("abcde6789")); + test(S("abcde"), 5, S("1234567890"), 5, 5, S("abcde67890")); + test(S("abcde"), 5, S("1234567890"), 5, 6, S("abcde67890")); + test(S("abcde"), 5, S("1234567890"), 9, 0, S("abcde")); + test(S("abcde"), 5, S("1234567890"), 9, 1, S("abcde0")); + test(S("abcde"), 5, S("1234567890"), 9, 2, S("abcde0")); + test(S("abcde"), 5, S("1234567890"), 10, 0, S("abcde")); + test(S("abcde"), 5, S("1234567890"), 10, 1, S("abcde")); + test(S("abcde"), 5, S("1234567890"), 11, 0, S("can't happen")); + test(S("abcde"), 5, S("12345678901234567890"), 0, 0, S("abcde")); + test(S("abcde"), 5, S("12345678901234567890"), 0, 1, S("abcde1")); + test(S("abcde"), 5, S("12345678901234567890"), 0, 10, S("abcde1234567890")); + test(S("abcde"), 5, S("12345678901234567890"), 0, 19, S("abcde1234567890123456789")); + test(S("abcde"), 5, S("12345678901234567890"), 0, 20, S("abcde12345678901234567890")); + test(S("abcde"), 5, S("12345678901234567890"), 0, 21, S("abcde12345678901234567890")); +} + +template +void test10() +{ + test(S("abcde"), 5, S("12345678901234567890"), 1, 0, S("abcde")); + test(S("abcde"), 5, S("12345678901234567890"), 1, 1, S("abcde2")); + test(S("abcde"), 5, S("12345678901234567890"), 1, 9, S("abcde234567890")); + test(S("abcde"), 5, S("12345678901234567890"), 1, 18, S("abcde234567890123456789")); + test(S("abcde"), 5, S("12345678901234567890"), 1, 19, S("abcde2345678901234567890")); + test(S("abcde"), 5, S("12345678901234567890"), 1, 20, S("abcde2345678901234567890")); + test(S("abcde"), 5, S("12345678901234567890"), 10, 0, S("abcde")); + test(S("abcde"), 5, S("12345678901234567890"), 10, 1, S("abcde1")); + test(S("abcde"), 5, S("12345678901234567890"), 10, 5, S("abcde12345")); + test(S("abcde"), 5, S("12345678901234567890"), 10, 9, S("abcde123456789")); + test(S("abcde"), 5, S("12345678901234567890"), 10, 10, S("abcde1234567890")); + test(S("abcde"), 5, S("12345678901234567890"), 10, 11, S("abcde1234567890")); + test(S("abcde"), 5, S("12345678901234567890"), 19, 0, S("abcde")); + test(S("abcde"), 5, S("12345678901234567890"), 19, 1, S("abcde0")); + test(S("abcde"), 5, S("12345678901234567890"), 19, 2, S("abcde0")); + test(S("abcde"), 5, S("12345678901234567890"), 20, 0, S("abcde")); + test(S("abcde"), 5, S("12345678901234567890"), 20, 1, S("abcde")); + test(S("abcde"), 5, S("12345678901234567890"), 21, 0, S("can't happen")); + test(S("abcde"), 6, S(""), 0, 0, S("can't happen")); + test(S("abcde"), 6, S(""), 0, 1, S("can't happen")); + test(S("abcde"), 6, S(""), 1, 0, S("can't happen")); + test(S("abcde"), 6, S("12345"), 0, 0, S("can't happen")); + test(S("abcde"), 6, S("12345"), 0, 1, S("can't happen")); + test(S("abcde"), 6, S("12345"), 0, 2, S("can't happen")); + test(S("abcde"), 6, S("12345"), 0, 4, S("can't happen")); + test(S("abcde"), 6, S("12345"), 0, 5, S("can't happen")); + test(S("abcde"), 6, S("12345"), 0, 6, S("can't happen")); + test(S("abcde"), 6, S("12345"), 1, 0, S("can't happen")); + test(S("abcde"), 6, S("12345"), 1, 1, S("can't happen")); + test(S("abcde"), 6, S("12345"), 1, 2, S("can't happen")); + test(S("abcde"), 6, S("12345"), 1, 3, S("can't happen")); + test(S("abcde"), 6, S("12345"), 1, 4, S("can't happen")); + test(S("abcde"), 6, S("12345"), 1, 5, S("can't happen")); + test(S("abcde"), 6, S("12345"), 2, 0, S("can't happen")); + test(S("abcde"), 6, S("12345"), 2, 1, S("can't happen")); + test(S("abcde"), 6, S("12345"), 2, 2, S("can't happen")); + test(S("abcde"), 6, S("12345"), 2, 3, S("can't happen")); + test(S("abcde"), 6, S("12345"), 2, 4, S("can't happen")); + test(S("abcde"), 6, S("12345"), 4, 0, S("can't happen")); + test(S("abcde"), 6, S("12345"), 4, 1, S("can't happen")); + test(S("abcde"), 6, S("12345"), 4, 2, S("can't happen")); + test(S("abcde"), 6, S("12345"), 5, 0, S("can't happen")); + test(S("abcde"), 6, S("12345"), 5, 1, S("can't happen")); + test(S("abcde"), 6, S("12345"), 6, 0, S("can't happen")); + test(S("abcde"), 6, S("1234567890"), 0, 0, S("can't happen")); + test(S("abcde"), 6, S("1234567890"), 0, 1, S("can't happen")); + test(S("abcde"), 6, S("1234567890"), 0, 5, S("can't happen")); + test(S("abcde"), 6, S("1234567890"), 0, 9, S("can't happen")); + test(S("abcde"), 6, S("1234567890"), 0, 10, S("can't happen")); + test(S("abcde"), 6, S("1234567890"), 0, 11, S("can't happen")); +} + +template +void test11() +{ + test(S("abcde"), 6, S("1234567890"), 1, 0, S("can't happen")); + test(S("abcde"), 6, S("1234567890"), 1, 1, S("can't happen")); + test(S("abcde"), 6, S("1234567890"), 1, 4, S("can't happen")); + test(S("abcde"), 6, S("1234567890"), 1, 8, S("can't happen")); + test(S("abcde"), 6, S("1234567890"), 1, 9, S("can't happen")); + test(S("abcde"), 6, S("1234567890"), 1, 10, S("can't happen")); + test(S("abcde"), 6, S("1234567890"), 5, 0, S("can't happen")); + test(S("abcde"), 6, S("1234567890"), 5, 1, S("can't happen")); + test(S("abcde"), 6, S("1234567890"), 5, 2, S("can't happen")); + test(S("abcde"), 6, S("1234567890"), 5, 4, S("can't happen")); + test(S("abcde"), 6, S("1234567890"), 5, 5, S("can't happen")); + test(S("abcde"), 6, S("1234567890"), 5, 6, S("can't happen")); + test(S("abcde"), 6, S("1234567890"), 9, 0, S("can't happen")); + test(S("abcde"), 6, S("1234567890"), 9, 1, S("can't happen")); + test(S("abcde"), 6, S("1234567890"), 9, 2, S("can't happen")); + test(S("abcde"), 6, S("1234567890"), 10, 0, S("can't happen")); + test(S("abcde"), 6, S("1234567890"), 10, 1, S("can't happen")); + test(S("abcde"), 6, S("1234567890"), 11, 0, S("can't happen")); + test(S("abcde"), 6, S("12345678901234567890"), 0, 0, S("can't happen")); + test(S("abcde"), 6, S("12345678901234567890"), 0, 1, S("can't happen")); + test(S("abcde"), 6, S("12345678901234567890"), 0, 10, S("can't happen")); + test(S("abcde"), 6, S("12345678901234567890"), 0, 19, S("can't happen")); + test(S("abcde"), 6, S("12345678901234567890"), 0, 20, S("can't happen")); + test(S("abcde"), 6, S("12345678901234567890"), 0, 21, S("can't happen")); + test(S("abcde"), 6, S("12345678901234567890"), 1, 0, S("can't happen")); + test(S("abcde"), 6, S("12345678901234567890"), 1, 1, S("can't happen")); + test(S("abcde"), 6, S("12345678901234567890"), 1, 9, S("can't happen")); + test(S("abcde"), 6, S("12345678901234567890"), 1, 18, S("can't happen")); + test(S("abcde"), 6, S("12345678901234567890"), 1, 19, S("can't happen")); + test(S("abcde"), 6, S("12345678901234567890"), 1, 20, S("can't happen")); + test(S("abcde"), 6, S("12345678901234567890"), 10, 0, S("can't happen")); + test(S("abcde"), 6, S("12345678901234567890"), 10, 1, S("can't happen")); + test(S("abcde"), 6, S("12345678901234567890"), 10, 5, S("can't happen")); + test(S("abcde"), 6, S("12345678901234567890"), 10, 9, S("can't happen")); + test(S("abcde"), 6, S("12345678901234567890"), 10, 10, S("can't happen")); + test(S("abcde"), 6, S("12345678901234567890"), 10, 11, S("can't happen")); + test(S("abcde"), 6, S("12345678901234567890"), 19, 0, S("can't happen")); + test(S("abcde"), 6, S("12345678901234567890"), 19, 1, S("can't happen")); + test(S("abcde"), 6, S("12345678901234567890"), 19, 2, S("can't happen")); + test(S("abcde"), 6, S("12345678901234567890"), 20, 0, S("can't happen")); + test(S("abcde"), 6, S("12345678901234567890"), 20, 1, S("can't happen")); + test(S("abcde"), 6, S("12345678901234567890"), 21, 0, S("can't happen")); + test(S("abcdefghij"), 0, S(""), 0, 0, S("abcdefghij")); + test(S("abcdefghij"), 0, S(""), 0, 1, S("abcdefghij")); + test(S("abcdefghij"), 0, S(""), 1, 0, S("can't happen")); + test(S("abcdefghij"), 0, S("12345"), 0, 0, S("abcdefghij")); + test(S("abcdefghij"), 0, S("12345"), 0, 1, S("1abcdefghij")); + test(S("abcdefghij"), 0, S("12345"), 0, 2, S("12abcdefghij")); + test(S("abcdefghij"), 0, S("12345"), 0, 4, S("1234abcdefghij")); + test(S("abcdefghij"), 0, S("12345"), 0, 5, S("12345abcdefghij")); +} + +template +void test12() +{ + test(S("abcdefghij"), 0, S("12345"), 0, 6, S("12345abcdefghij")); + test(S("abcdefghij"), 0, S("12345"), 1, 0, S("abcdefghij")); + test(S("abcdefghij"), 0, S("12345"), 1, 1, S("2abcdefghij")); + test(S("abcdefghij"), 0, S("12345"), 1, 2, S("23abcdefghij")); + test(S("abcdefghij"), 0, S("12345"), 1, 3, S("234abcdefghij")); + test(S("abcdefghij"), 0, S("12345"), 1, 4, S("2345abcdefghij")); + test(S("abcdefghij"), 0, S("12345"), 1, 5, S("2345abcdefghij")); + test(S("abcdefghij"), 0, S("12345"), 2, 0, S("abcdefghij")); + test(S("abcdefghij"), 0, S("12345"), 2, 1, S("3abcdefghij")); + test(S("abcdefghij"), 0, S("12345"), 2, 2, S("34abcdefghij")); + test(S("abcdefghij"), 0, S("12345"), 2, 3, S("345abcdefghij")); + test(S("abcdefghij"), 0, S("12345"), 2, 4, S("345abcdefghij")); + test(S("abcdefghij"), 0, S("12345"), 4, 0, S("abcdefghij")); + test(S("abcdefghij"), 0, S("12345"), 4, 1, S("5abcdefghij")); + test(S("abcdefghij"), 0, S("12345"), 4, 2, S("5abcdefghij")); + test(S("abcdefghij"), 0, S("12345"), 5, 0, S("abcdefghij")); + test(S("abcdefghij"), 0, S("12345"), 5, 1, S("abcdefghij")); + test(S("abcdefghij"), 0, S("12345"), 6, 0, S("can't happen")); + test(S("abcdefghij"), 0, S("1234567890"), 0, 0, S("abcdefghij")); + test(S("abcdefghij"), 0, S("1234567890"), 0, 1, S("1abcdefghij")); + test(S("abcdefghij"), 0, S("1234567890"), 0, 5, S("12345abcdefghij")); + test(S("abcdefghij"), 0, S("1234567890"), 0, 9, S("123456789abcdefghij")); + test(S("abcdefghij"), 0, S("1234567890"), 0, 10, S("1234567890abcdefghij")); + test(S("abcdefghij"), 0, S("1234567890"), 0, 11, S("1234567890abcdefghij")); + test(S("abcdefghij"), 0, S("1234567890"), 1, 0, S("abcdefghij")); + test(S("abcdefghij"), 0, S("1234567890"), 1, 1, S("2abcdefghij")); + test(S("abcdefghij"), 0, S("1234567890"), 1, 4, S("2345abcdefghij")); + test(S("abcdefghij"), 0, S("1234567890"), 1, 8, S("23456789abcdefghij")); + test(S("abcdefghij"), 0, S("1234567890"), 1, 9, S("234567890abcdefghij")); + test(S("abcdefghij"), 0, S("1234567890"), 1, 10, S("234567890abcdefghij")); + test(S("abcdefghij"), 0, S("1234567890"), 5, 0, S("abcdefghij")); + test(S("abcdefghij"), 0, S("1234567890"), 5, 1, S("6abcdefghij")); + test(S("abcdefghij"), 0, S("1234567890"), 5, 2, S("67abcdefghij")); + test(S("abcdefghij"), 0, S("1234567890"), 5, 4, S("6789abcdefghij")); + test(S("abcdefghij"), 0, S("1234567890"), 5, 5, S("67890abcdefghij")); + test(S("abcdefghij"), 0, S("1234567890"), 5, 6, S("67890abcdefghij")); + test(S("abcdefghij"), 0, S("1234567890"), 9, 0, S("abcdefghij")); + test(S("abcdefghij"), 0, S("1234567890"), 9, 1, S("0abcdefghij")); + test(S("abcdefghij"), 0, S("1234567890"), 9, 2, S("0abcdefghij")); + test(S("abcdefghij"), 0, S("1234567890"), 10, 0, S("abcdefghij")); + test(S("abcdefghij"), 0, S("1234567890"), 10, 1, S("abcdefghij")); + test(S("abcdefghij"), 0, S("1234567890"), 11, 0, S("can't happen")); + test(S("abcdefghij"), 0, S("12345678901234567890"), 0, 0, S("abcdefghij")); + test(S("abcdefghij"), 0, S("12345678901234567890"), 0, 1, S("1abcdefghij")); + test(S("abcdefghij"), 0, S("12345678901234567890"), 0, 10, S("1234567890abcdefghij")); + test(S("abcdefghij"), 0, S("12345678901234567890"), 0, 19, S("1234567890123456789abcdefghij")); + test(S("abcdefghij"), 0, S("12345678901234567890"), 0, 20, S("12345678901234567890abcdefghij")); + test(S("abcdefghij"), 0, S("12345678901234567890"), 0, 21, S("12345678901234567890abcdefghij")); + test(S("abcdefghij"), 0, S("12345678901234567890"), 1, 0, S("abcdefghij")); + test(S("abcdefghij"), 0, S("12345678901234567890"), 1, 1, S("2abcdefghij")); +} + +template +void test13() +{ + test(S("abcdefghij"), 0, S("12345678901234567890"), 1, 9, S("234567890abcdefghij")); + test(S("abcdefghij"), 0, S("12345678901234567890"), 1, 18, S("234567890123456789abcdefghij")); + test(S("abcdefghij"), 0, S("12345678901234567890"), 1, 19, S("2345678901234567890abcdefghij")); + test(S("abcdefghij"), 0, S("12345678901234567890"), 1, 20, S("2345678901234567890abcdefghij")); + test(S("abcdefghij"), 0, S("12345678901234567890"), 10, 0, S("abcdefghij")); + test(S("abcdefghij"), 0, S("12345678901234567890"), 10, 1, S("1abcdefghij")); + test(S("abcdefghij"), 0, S("12345678901234567890"), 10, 5, S("12345abcdefghij")); + test(S("abcdefghij"), 0, S("12345678901234567890"), 10, 9, S("123456789abcdefghij")); + test(S("abcdefghij"), 0, S("12345678901234567890"), 10, 10, S("1234567890abcdefghij")); + test(S("abcdefghij"), 0, S("12345678901234567890"), 10, 11, S("1234567890abcdefghij")); + test(S("abcdefghij"), 0, S("12345678901234567890"), 19, 0, S("abcdefghij")); + test(S("abcdefghij"), 0, S("12345678901234567890"), 19, 1, S("0abcdefghij")); + test(S("abcdefghij"), 0, S("12345678901234567890"), 19, 2, S("0abcdefghij")); + test(S("abcdefghij"), 0, S("12345678901234567890"), 20, 0, S("abcdefghij")); + test(S("abcdefghij"), 0, S("12345678901234567890"), 20, 1, S("abcdefghij")); + test(S("abcdefghij"), 0, S("12345678901234567890"), 21, 0, S("can't happen")); + test(S("abcdefghij"), 1, S(""), 0, 0, S("abcdefghij")); + test(S("abcdefghij"), 1, S(""), 0, 1, S("abcdefghij")); + test(S("abcdefghij"), 1, S(""), 1, 0, S("can't happen")); + test(S("abcdefghij"), 1, S("12345"), 0, 0, S("abcdefghij")); + test(S("abcdefghij"), 1, S("12345"), 0, 1, S("a1bcdefghij")); + test(S("abcdefghij"), 1, S("12345"), 0, 2, S("a12bcdefghij")); + test(S("abcdefghij"), 1, S("12345"), 0, 4, S("a1234bcdefghij")); + test(S("abcdefghij"), 1, S("12345"), 0, 5, S("a12345bcdefghij")); + test(S("abcdefghij"), 1, S("12345"), 0, 6, S("a12345bcdefghij")); + test(S("abcdefghij"), 1, S("12345"), 1, 0, S("abcdefghij")); + test(S("abcdefghij"), 1, S("12345"), 1, 1, S("a2bcdefghij")); + test(S("abcdefghij"), 1, S("12345"), 1, 2, S("a23bcdefghij")); + test(S("abcdefghij"), 1, S("12345"), 1, 3, S("a234bcdefghij")); + test(S("abcdefghij"), 1, S("12345"), 1, 4, S("a2345bcdefghij")); + test(S("abcdefghij"), 1, S("12345"), 1, 5, S("a2345bcdefghij")); + test(S("abcdefghij"), 1, S("12345"), 2, 0, S("abcdefghij")); + test(S("abcdefghij"), 1, S("12345"), 2, 1, S("a3bcdefghij")); + test(S("abcdefghij"), 1, S("12345"), 2, 2, S("a34bcdefghij")); + test(S("abcdefghij"), 1, S("12345"), 2, 3, S("a345bcdefghij")); + test(S("abcdefghij"), 1, S("12345"), 2, 4, S("a345bcdefghij")); + test(S("abcdefghij"), 1, S("12345"), 4, 0, S("abcdefghij")); + test(S("abcdefghij"), 1, S("12345"), 4, 1, S("a5bcdefghij")); + test(S("abcdefghij"), 1, S("12345"), 4, 2, S("a5bcdefghij")); + test(S("abcdefghij"), 1, S("12345"), 5, 0, S("abcdefghij")); + test(S("abcdefghij"), 1, S("12345"), 5, 1, S("abcdefghij")); + test(S("abcdefghij"), 1, S("12345"), 6, 0, S("can't happen")); + test(S("abcdefghij"), 1, S("1234567890"), 0, 0, S("abcdefghij")); + test(S("abcdefghij"), 1, S("1234567890"), 0, 1, S("a1bcdefghij")); + test(S("abcdefghij"), 1, S("1234567890"), 0, 5, S("a12345bcdefghij")); + test(S("abcdefghij"), 1, S("1234567890"), 0, 9, S("a123456789bcdefghij")); + test(S("abcdefghij"), 1, S("1234567890"), 0, 10, S("a1234567890bcdefghij")); + test(S("abcdefghij"), 1, S("1234567890"), 0, 11, S("a1234567890bcdefghij")); + test(S("abcdefghij"), 1, S("1234567890"), 1, 0, S("abcdefghij")); + test(S("abcdefghij"), 1, S("1234567890"), 1, 1, S("a2bcdefghij")); +} + +template +void test14() +{ + test(S("abcdefghij"), 1, S("1234567890"), 1, 4, S("a2345bcdefghij")); + test(S("abcdefghij"), 1, S("1234567890"), 1, 8, S("a23456789bcdefghij")); + test(S("abcdefghij"), 1, S("1234567890"), 1, 9, S("a234567890bcdefghij")); + test(S("abcdefghij"), 1, S("1234567890"), 1, 10, S("a234567890bcdefghij")); + test(S("abcdefghij"), 1, S("1234567890"), 5, 0, S("abcdefghij")); + test(S("abcdefghij"), 1, S("1234567890"), 5, 1, S("a6bcdefghij")); + test(S("abcdefghij"), 1, S("1234567890"), 5, 2, S("a67bcdefghij")); + test(S("abcdefghij"), 1, S("1234567890"), 5, 4, S("a6789bcdefghij")); + test(S("abcdefghij"), 1, S("1234567890"), 5, 5, S("a67890bcdefghij")); + test(S("abcdefghij"), 1, S("1234567890"), 5, 6, S("a67890bcdefghij")); + test(S("abcdefghij"), 1, S("1234567890"), 9, 0, S("abcdefghij")); + test(S("abcdefghij"), 1, S("1234567890"), 9, 1, S("a0bcdefghij")); + test(S("abcdefghij"), 1, S("1234567890"), 9, 2, S("a0bcdefghij")); + test(S("abcdefghij"), 1, S("1234567890"), 10, 0, S("abcdefghij")); + test(S("abcdefghij"), 1, S("1234567890"), 10, 1, S("abcdefghij")); + test(S("abcdefghij"), 1, S("1234567890"), 11, 0, S("can't happen")); + test(S("abcdefghij"), 1, S("12345678901234567890"), 0, 0, S("abcdefghij")); + test(S("abcdefghij"), 1, S("12345678901234567890"), 0, 1, S("a1bcdefghij")); + test(S("abcdefghij"), 1, S("12345678901234567890"), 0, 10, S("a1234567890bcdefghij")); + test(S("abcdefghij"), 1, S("12345678901234567890"), 0, 19, S("a1234567890123456789bcdefghij")); + test(S("abcdefghij"), 1, S("12345678901234567890"), 0, 20, S("a12345678901234567890bcdefghij")); + test(S("abcdefghij"), 1, S("12345678901234567890"), 0, 21, S("a12345678901234567890bcdefghij")); + test(S("abcdefghij"), 1, S("12345678901234567890"), 1, 0, S("abcdefghij")); + test(S("abcdefghij"), 1, S("12345678901234567890"), 1, 1, S("a2bcdefghij")); + test(S("abcdefghij"), 1, S("12345678901234567890"), 1, 9, S("a234567890bcdefghij")); + test(S("abcdefghij"), 1, S("12345678901234567890"), 1, 18, S("a234567890123456789bcdefghij")); + test(S("abcdefghij"), 1, S("12345678901234567890"), 1, 19, S("a2345678901234567890bcdefghij")); + test(S("abcdefghij"), 1, S("12345678901234567890"), 1, 20, S("a2345678901234567890bcdefghij")); + test(S("abcdefghij"), 1, S("12345678901234567890"), 10, 0, S("abcdefghij")); + test(S("abcdefghij"), 1, S("12345678901234567890"), 10, 1, S("a1bcdefghij")); + test(S("abcdefghij"), 1, S("12345678901234567890"), 10, 5, S("a12345bcdefghij")); + test(S("abcdefghij"), 1, S("12345678901234567890"), 10, 9, S("a123456789bcdefghij")); + test(S("abcdefghij"), 1, S("12345678901234567890"), 10, 10, S("a1234567890bcdefghij")); + test(S("abcdefghij"), 1, S("12345678901234567890"), 10, 11, S("a1234567890bcdefghij")); + test(S("abcdefghij"), 1, S("12345678901234567890"), 19, 0, S("abcdefghij")); + test(S("abcdefghij"), 1, S("12345678901234567890"), 19, 1, S("a0bcdefghij")); + test(S("abcdefghij"), 1, S("12345678901234567890"), 19, 2, S("a0bcdefghij")); + test(S("abcdefghij"), 1, S("12345678901234567890"), 20, 0, S("abcdefghij")); + test(S("abcdefghij"), 1, S("12345678901234567890"), 20, 1, S("abcdefghij")); + test(S("abcdefghij"), 1, S("12345678901234567890"), 21, 0, S("can't happen")); + test(S("abcdefghij"), 5, S(""), 0, 0, S("abcdefghij")); + test(S("abcdefghij"), 5, S(""), 0, 1, S("abcdefghij")); + test(S("abcdefghij"), 5, S(""), 1, 0, S("can't happen")); + test(S("abcdefghij"), 5, S("12345"), 0, 0, S("abcdefghij")); + test(S("abcdefghij"), 5, S("12345"), 0, 1, S("abcde1fghij")); + test(S("abcdefghij"), 5, S("12345"), 0, 2, S("abcde12fghij")); + test(S("abcdefghij"), 5, S("12345"), 0, 4, S("abcde1234fghij")); + test(S("abcdefghij"), 5, S("12345"), 0, 5, S("abcde12345fghij")); + test(S("abcdefghij"), 5, S("12345"), 0, 6, S("abcde12345fghij")); + test(S("abcdefghij"), 5, S("12345"), 1, 0, S("abcdefghij")); +} + +template +void test15() +{ + test(S("abcdefghij"), 5, S("12345"), 1, 1, S("abcde2fghij")); + test(S("abcdefghij"), 5, S("12345"), 1, 2, S("abcde23fghij")); + test(S("abcdefghij"), 5, S("12345"), 1, 3, S("abcde234fghij")); + test(S("abcdefghij"), 5, S("12345"), 1, 4, S("abcde2345fghij")); + test(S("abcdefghij"), 5, S("12345"), 1, 5, S("abcde2345fghij")); + test(S("abcdefghij"), 5, S("12345"), 2, 0, S("abcdefghij")); + test(S("abcdefghij"), 5, S("12345"), 2, 1, S("abcde3fghij")); + test(S("abcdefghij"), 5, S("12345"), 2, 2, S("abcde34fghij")); + test(S("abcdefghij"), 5, S("12345"), 2, 3, S("abcde345fghij")); + test(S("abcdefghij"), 5, S("12345"), 2, 4, S("abcde345fghij")); + test(S("abcdefghij"), 5, S("12345"), 4, 0, S("abcdefghij")); + test(S("abcdefghij"), 5, S("12345"), 4, 1, S("abcde5fghij")); + test(S("abcdefghij"), 5, S("12345"), 4, 2, S("abcde5fghij")); + test(S("abcdefghij"), 5, S("12345"), 5, 0, S("abcdefghij")); + test(S("abcdefghij"), 5, S("12345"), 5, 1, S("abcdefghij")); + test(S("abcdefghij"), 5, S("12345"), 6, 0, S("can't happen")); + test(S("abcdefghij"), 5, S("1234567890"), 0, 0, S("abcdefghij")); + test(S("abcdefghij"), 5, S("1234567890"), 0, 1, S("abcde1fghij")); + test(S("abcdefghij"), 5, S("1234567890"), 0, 5, S("abcde12345fghij")); + test(S("abcdefghij"), 5, S("1234567890"), 0, 9, S("abcde123456789fghij")); + test(S("abcdefghij"), 5, S("1234567890"), 0, 10, S("abcde1234567890fghij")); + test(S("abcdefghij"), 5, S("1234567890"), 0, 11, S("abcde1234567890fghij")); + test(S("abcdefghij"), 5, S("1234567890"), 1, 0, S("abcdefghij")); + test(S("abcdefghij"), 5, S("1234567890"), 1, 1, S("abcde2fghij")); + test(S("abcdefghij"), 5, S("1234567890"), 1, 4, S("abcde2345fghij")); + test(S("abcdefghij"), 5, S("1234567890"), 1, 8, S("abcde23456789fghij")); + test(S("abcdefghij"), 5, S("1234567890"), 1, 9, S("abcde234567890fghij")); + test(S("abcdefghij"), 5, S("1234567890"), 1, 10, S("abcde234567890fghij")); + test(S("abcdefghij"), 5, S("1234567890"), 5, 0, S("abcdefghij")); + test(S("abcdefghij"), 5, S("1234567890"), 5, 1, S("abcde6fghij")); + test(S("abcdefghij"), 5, S("1234567890"), 5, 2, S("abcde67fghij")); + test(S("abcdefghij"), 5, S("1234567890"), 5, 4, S("abcde6789fghij")); + test(S("abcdefghij"), 5, S("1234567890"), 5, 5, S("abcde67890fghij")); + test(S("abcdefghij"), 5, S("1234567890"), 5, 6, S("abcde67890fghij")); + test(S("abcdefghij"), 5, S("1234567890"), 9, 0, S("abcdefghij")); + test(S("abcdefghij"), 5, S("1234567890"), 9, 1, S("abcde0fghij")); + test(S("abcdefghij"), 5, S("1234567890"), 9, 2, S("abcde0fghij")); + test(S("abcdefghij"), 5, S("1234567890"), 10, 0, S("abcdefghij")); + test(S("abcdefghij"), 5, S("1234567890"), 10, 1, S("abcdefghij")); + test(S("abcdefghij"), 5, S("1234567890"), 11, 0, S("can't happen")); + test(S("abcdefghij"), 5, S("12345678901234567890"), 0, 0, S("abcdefghij")); + test(S("abcdefghij"), 5, S("12345678901234567890"), 0, 1, S("abcde1fghij")); + test(S("abcdefghij"), 5, S("12345678901234567890"), 0, 10, S("abcde1234567890fghij")); + test(S("abcdefghij"), 5, S("12345678901234567890"), 0, 19, S("abcde1234567890123456789fghij")); + test(S("abcdefghij"), 5, S("12345678901234567890"), 0, 20, S("abcde12345678901234567890fghij")); + test(S("abcdefghij"), 5, S("12345678901234567890"), 0, 21, S("abcde12345678901234567890fghij")); + test(S("abcdefghij"), 5, S("12345678901234567890"), 1, 0, S("abcdefghij")); + test(S("abcdefghij"), 5, S("12345678901234567890"), 1, 1, S("abcde2fghij")); + test(S("abcdefghij"), 5, S("12345678901234567890"), 1, 9, S("abcde234567890fghij")); + test(S("abcdefghij"), 5, S("12345678901234567890"), 1, 18, S("abcde234567890123456789fghij")); +} + +template +void test16() +{ + test(S("abcdefghij"), 5, S("12345678901234567890"), 1, 19, S("abcde2345678901234567890fghij")); + test(S("abcdefghij"), 5, S("12345678901234567890"), 1, 20, S("abcde2345678901234567890fghij")); + test(S("abcdefghij"), 5, S("12345678901234567890"), 10, 0, S("abcdefghij")); + test(S("abcdefghij"), 5, S("12345678901234567890"), 10, 1, S("abcde1fghij")); + test(S("abcdefghij"), 5, S("12345678901234567890"), 10, 5, S("abcde12345fghij")); + test(S("abcdefghij"), 5, S("12345678901234567890"), 10, 9, S("abcde123456789fghij")); + test(S("abcdefghij"), 5, S("12345678901234567890"), 10, 10, S("abcde1234567890fghij")); + test(S("abcdefghij"), 5, S("12345678901234567890"), 10, 11, S("abcde1234567890fghij")); + test(S("abcdefghij"), 5, S("12345678901234567890"), 19, 0, S("abcdefghij")); + test(S("abcdefghij"), 5, S("12345678901234567890"), 19, 1, S("abcde0fghij")); + test(S("abcdefghij"), 5, S("12345678901234567890"), 19, 2, S("abcde0fghij")); + test(S("abcdefghij"), 5, S("12345678901234567890"), 20, 0, S("abcdefghij")); + test(S("abcdefghij"), 5, S("12345678901234567890"), 20, 1, S("abcdefghij")); + test(S("abcdefghij"), 5, S("12345678901234567890"), 21, 0, S("can't happen")); + test(S("abcdefghij"), 9, S(""), 0, 0, S("abcdefghij")); + test(S("abcdefghij"), 9, S(""), 0, 1, S("abcdefghij")); + test(S("abcdefghij"), 9, S(""), 1, 0, S("can't happen")); + test(S("abcdefghij"), 9, S("12345"), 0, 0, S("abcdefghij")); + test(S("abcdefghij"), 9, S("12345"), 0, 1, S("abcdefghi1j")); + test(S("abcdefghij"), 9, S("12345"), 0, 2, S("abcdefghi12j")); + test(S("abcdefghij"), 9, S("12345"), 0, 4, S("abcdefghi1234j")); + test(S("abcdefghij"), 9, S("12345"), 0, 5, S("abcdefghi12345j")); + test(S("abcdefghij"), 9, S("12345"), 0, 6, S("abcdefghi12345j")); + test(S("abcdefghij"), 9, S("12345"), 1, 0, S("abcdefghij")); + test(S("abcdefghij"), 9, S("12345"), 1, 1, S("abcdefghi2j")); + test(S("abcdefghij"), 9, S("12345"), 1, 2, S("abcdefghi23j")); + test(S("abcdefghij"), 9, S("12345"), 1, 3, S("abcdefghi234j")); + test(S("abcdefghij"), 9, S("12345"), 1, 4, S("abcdefghi2345j")); + test(S("abcdefghij"), 9, S("12345"), 1, 5, S("abcdefghi2345j")); + test(S("abcdefghij"), 9, S("12345"), 2, 0, S("abcdefghij")); + test(S("abcdefghij"), 9, S("12345"), 2, 1, S("abcdefghi3j")); + test(S("abcdefghij"), 9, S("12345"), 2, 2, S("abcdefghi34j")); + test(S("abcdefghij"), 9, S("12345"), 2, 3, S("abcdefghi345j")); + test(S("abcdefghij"), 9, S("12345"), 2, 4, S("abcdefghi345j")); + test(S("abcdefghij"), 9, S("12345"), 4, 0, S("abcdefghij")); + test(S("abcdefghij"), 9, S("12345"), 4, 1, S("abcdefghi5j")); + test(S("abcdefghij"), 9, S("12345"), 4, 2, S("abcdefghi5j")); + test(S("abcdefghij"), 9, S("12345"), 5, 0, S("abcdefghij")); + test(S("abcdefghij"), 9, S("12345"), 5, 1, S("abcdefghij")); + test(S("abcdefghij"), 9, S("12345"), 6, 0, S("can't happen")); + test(S("abcdefghij"), 9, S("1234567890"), 0, 0, S("abcdefghij")); + test(S("abcdefghij"), 9, S("1234567890"), 0, 1, S("abcdefghi1j")); + test(S("abcdefghij"), 9, S("1234567890"), 0, 5, S("abcdefghi12345j")); + test(S("abcdefghij"), 9, S("1234567890"), 0, 9, S("abcdefghi123456789j")); + test(S("abcdefghij"), 9, S("1234567890"), 0, 10, S("abcdefghi1234567890j")); + test(S("abcdefghij"), 9, S("1234567890"), 0, 11, S("abcdefghi1234567890j")); + test(S("abcdefghij"), 9, S("1234567890"), 1, 0, S("abcdefghij")); + test(S("abcdefghij"), 9, S("1234567890"), 1, 1, S("abcdefghi2j")); + test(S("abcdefghij"), 9, S("1234567890"), 1, 4, S("abcdefghi2345j")); + test(S("abcdefghij"), 9, S("1234567890"), 1, 8, S("abcdefghi23456789j")); +} + +template +void test17() +{ + test(S("abcdefghij"), 9, S("1234567890"), 1, 9, S("abcdefghi234567890j")); + test(S("abcdefghij"), 9, S("1234567890"), 1, 10, S("abcdefghi234567890j")); + test(S("abcdefghij"), 9, S("1234567890"), 5, 0, S("abcdefghij")); + test(S("abcdefghij"), 9, S("1234567890"), 5, 1, S("abcdefghi6j")); + test(S("abcdefghij"), 9, S("1234567890"), 5, 2, S("abcdefghi67j")); + test(S("abcdefghij"), 9, S("1234567890"), 5, 4, S("abcdefghi6789j")); + test(S("abcdefghij"), 9, S("1234567890"), 5, 5, S("abcdefghi67890j")); + test(S("abcdefghij"), 9, S("1234567890"), 5, 6, S("abcdefghi67890j")); + test(S("abcdefghij"), 9, S("1234567890"), 9, 0, S("abcdefghij")); + test(S("abcdefghij"), 9, S("1234567890"), 9, 1, S("abcdefghi0j")); + test(S("abcdefghij"), 9, S("1234567890"), 9, 2, S("abcdefghi0j")); + test(S("abcdefghij"), 9, S("1234567890"), 10, 0, S("abcdefghij")); + test(S("abcdefghij"), 9, S("1234567890"), 10, 1, S("abcdefghij")); + test(S("abcdefghij"), 9, S("1234567890"), 11, 0, S("can't happen")); + test(S("abcdefghij"), 9, S("12345678901234567890"), 0, 0, S("abcdefghij")); + test(S("abcdefghij"), 9, S("12345678901234567890"), 0, 1, S("abcdefghi1j")); + test(S("abcdefghij"), 9, S("12345678901234567890"), 0, 10, S("abcdefghi1234567890j")); + test(S("abcdefghij"), 9, S("12345678901234567890"), 0, 19, S("abcdefghi1234567890123456789j")); + test(S("abcdefghij"), 9, S("12345678901234567890"), 0, 20, S("abcdefghi12345678901234567890j")); + test(S("abcdefghij"), 9, S("12345678901234567890"), 0, 21, S("abcdefghi12345678901234567890j")); + test(S("abcdefghij"), 9, S("12345678901234567890"), 1, 0, S("abcdefghij")); + test(S("abcdefghij"), 9, S("12345678901234567890"), 1, 1, S("abcdefghi2j")); + test(S("abcdefghij"), 9, S("12345678901234567890"), 1, 9, S("abcdefghi234567890j")); + test(S("abcdefghij"), 9, S("12345678901234567890"), 1, 18, S("abcdefghi234567890123456789j")); + test(S("abcdefghij"), 9, S("12345678901234567890"), 1, 19, S("abcdefghi2345678901234567890j")); + test(S("abcdefghij"), 9, S("12345678901234567890"), 1, 20, S("abcdefghi2345678901234567890j")); + test(S("abcdefghij"), 9, S("12345678901234567890"), 10, 0, S("abcdefghij")); + test(S("abcdefghij"), 9, S("12345678901234567890"), 10, 1, S("abcdefghi1j")); + test(S("abcdefghij"), 9, S("12345678901234567890"), 10, 5, S("abcdefghi12345j")); + test(S("abcdefghij"), 9, S("12345678901234567890"), 10, 9, S("abcdefghi123456789j")); + test(S("abcdefghij"), 9, S("12345678901234567890"), 10, 10, S("abcdefghi1234567890j")); + test(S("abcdefghij"), 9, S("12345678901234567890"), 10, 11, S("abcdefghi1234567890j")); + test(S("abcdefghij"), 9, S("12345678901234567890"), 19, 0, S("abcdefghij")); + test(S("abcdefghij"), 9, S("12345678901234567890"), 19, 1, S("abcdefghi0j")); + test(S("abcdefghij"), 9, S("12345678901234567890"), 19, 2, S("abcdefghi0j")); + test(S("abcdefghij"), 9, S("12345678901234567890"), 20, 0, S("abcdefghij")); + test(S("abcdefghij"), 9, S("12345678901234567890"), 20, 1, S("abcdefghij")); + test(S("abcdefghij"), 9, S("12345678901234567890"), 21, 0, S("can't happen")); + test(S("abcdefghij"), 10, S(""), 0, 0, S("abcdefghij")); + test(S("abcdefghij"), 10, S(""), 0, 1, S("abcdefghij")); + test(S("abcdefghij"), 10, S(""), 1, 0, S("can't happen")); + test(S("abcdefghij"), 10, S("12345"), 0, 0, S("abcdefghij")); + test(S("abcdefghij"), 10, S("12345"), 0, 1, S("abcdefghij1")); + test(S("abcdefghij"), 10, S("12345"), 0, 2, S("abcdefghij12")); + test(S("abcdefghij"), 10, S("12345"), 0, 4, S("abcdefghij1234")); + test(S("abcdefghij"), 10, S("12345"), 0, 5, S("abcdefghij12345")); + test(S("abcdefghij"), 10, S("12345"), 0, 6, S("abcdefghij12345")); + test(S("abcdefghij"), 10, S("12345"), 1, 0, S("abcdefghij")); + test(S("abcdefghij"), 10, S("12345"), 1, 1, S("abcdefghij2")); + test(S("abcdefghij"), 10, S("12345"), 1, 2, S("abcdefghij23")); +} + +template +void test18() +{ + test(S("abcdefghij"), 10, S("12345"), 1, 3, S("abcdefghij234")); + test(S("abcdefghij"), 10, S("12345"), 1, 4, S("abcdefghij2345")); + test(S("abcdefghij"), 10, S("12345"), 1, 5, S("abcdefghij2345")); + test(S("abcdefghij"), 10, S("12345"), 2, 0, S("abcdefghij")); + test(S("abcdefghij"), 10, S("12345"), 2, 1, S("abcdefghij3")); + test(S("abcdefghij"), 10, S("12345"), 2, 2, S("abcdefghij34")); + test(S("abcdefghij"), 10, S("12345"), 2, 3, S("abcdefghij345")); + test(S("abcdefghij"), 10, S("12345"), 2, 4, S("abcdefghij345")); + test(S("abcdefghij"), 10, S("12345"), 4, 0, S("abcdefghij")); + test(S("abcdefghij"), 10, S("12345"), 4, 1, S("abcdefghij5")); + test(S("abcdefghij"), 10, S("12345"), 4, 2, S("abcdefghij5")); + test(S("abcdefghij"), 10, S("12345"), 5, 0, S("abcdefghij")); + test(S("abcdefghij"), 10, S("12345"), 5, 1, S("abcdefghij")); + test(S("abcdefghij"), 10, S("12345"), 6, 0, S("can't happen")); + test(S("abcdefghij"), 10, S("1234567890"), 0, 0, S("abcdefghij")); + test(S("abcdefghij"), 10, S("1234567890"), 0, 1, S("abcdefghij1")); + test(S("abcdefghij"), 10, S("1234567890"), 0, 5, S("abcdefghij12345")); + test(S("abcdefghij"), 10, S("1234567890"), 0, 9, S("abcdefghij123456789")); + test(S("abcdefghij"), 10, S("1234567890"), 0, 10, S("abcdefghij1234567890")); + test(S("abcdefghij"), 10, S("1234567890"), 0, 11, S("abcdefghij1234567890")); + test(S("abcdefghij"), 10, S("1234567890"), 1, 0, S("abcdefghij")); + test(S("abcdefghij"), 10, S("1234567890"), 1, 1, S("abcdefghij2")); + test(S("abcdefghij"), 10, S("1234567890"), 1, 4, S("abcdefghij2345")); + test(S("abcdefghij"), 10, S("1234567890"), 1, 8, S("abcdefghij23456789")); + test(S("abcdefghij"), 10, S("1234567890"), 1, 9, S("abcdefghij234567890")); + test(S("abcdefghij"), 10, S("1234567890"), 1, 10, S("abcdefghij234567890")); + test(S("abcdefghij"), 10, S("1234567890"), 5, 0, S("abcdefghij")); + test(S("abcdefghij"), 10, S("1234567890"), 5, 1, S("abcdefghij6")); + test(S("abcdefghij"), 10, S("1234567890"), 5, 2, S("abcdefghij67")); + test(S("abcdefghij"), 10, S("1234567890"), 5, 4, S("abcdefghij6789")); + test(S("abcdefghij"), 10, S("1234567890"), 5, 5, S("abcdefghij67890")); + test(S("abcdefghij"), 10, S("1234567890"), 5, 6, S("abcdefghij67890")); + test(S("abcdefghij"), 10, S("1234567890"), 9, 0, S("abcdefghij")); + test(S("abcdefghij"), 10, S("1234567890"), 9, 1, S("abcdefghij0")); + test(S("abcdefghij"), 10, S("1234567890"), 9, 2, S("abcdefghij0")); + test(S("abcdefghij"), 10, S("1234567890"), 10, 0, S("abcdefghij")); + test(S("abcdefghij"), 10, S("1234567890"), 10, 1, S("abcdefghij")); + test(S("abcdefghij"), 10, S("1234567890"), 11, 0, S("can't happen")); + test(S("abcdefghij"), 10, S("12345678901234567890"), 0, 0, S("abcdefghij")); + test(S("abcdefghij"), 10, S("12345678901234567890"), 0, 1, S("abcdefghij1")); + test(S("abcdefghij"), 10, S("12345678901234567890"), 0, 10, S("abcdefghij1234567890")); + test(S("abcdefghij"), 10, S("12345678901234567890"), 0, 19, S("abcdefghij1234567890123456789")); + test(S("abcdefghij"), 10, S("12345678901234567890"), 0, 20, S("abcdefghij12345678901234567890")); + test(S("abcdefghij"), 10, S("12345678901234567890"), 0, 21, S("abcdefghij12345678901234567890")); + test(S("abcdefghij"), 10, S("12345678901234567890"), 1, 0, S("abcdefghij")); + test(S("abcdefghij"), 10, S("12345678901234567890"), 1, 1, S("abcdefghij2")); + test(S("abcdefghij"), 10, S("12345678901234567890"), 1, 9, S("abcdefghij234567890")); + test(S("abcdefghij"), 10, S("12345678901234567890"), 1, 18, S("abcdefghij234567890123456789")); + test(S("abcdefghij"), 10, S("12345678901234567890"), 1, 19, S("abcdefghij2345678901234567890")); + test(S("abcdefghij"), 10, S("12345678901234567890"), 1, 20, S("abcdefghij2345678901234567890")); +} + +template +void test19() +{ + test(S("abcdefghij"), 10, S("12345678901234567890"), 10, 0, S("abcdefghij")); + test(S("abcdefghij"), 10, S("12345678901234567890"), 10, 1, S("abcdefghij1")); + test(S("abcdefghij"), 10, S("12345678901234567890"), 10, 5, S("abcdefghij12345")); + test(S("abcdefghij"), 10, S("12345678901234567890"), 10, 9, S("abcdefghij123456789")); + test(S("abcdefghij"), 10, S("12345678901234567890"), 10, 10, S("abcdefghij1234567890")); + test(S("abcdefghij"), 10, S("12345678901234567890"), 10, 11, S("abcdefghij1234567890")); + test(S("abcdefghij"), 10, S("12345678901234567890"), 19, 0, S("abcdefghij")); + test(S("abcdefghij"), 10, S("12345678901234567890"), 19, 1, S("abcdefghij0")); + test(S("abcdefghij"), 10, S("12345678901234567890"), 19, 2, S("abcdefghij0")); + test(S("abcdefghij"), 10, S("12345678901234567890"), 20, 0, S("abcdefghij")); + test(S("abcdefghij"), 10, S("12345678901234567890"), 20, 1, S("abcdefghij")); + test(S("abcdefghij"), 10, S("12345678901234567890"), 21, 0, S("can't happen")); + test(S("abcdefghij"), 11, S(""), 0, 0, S("can't happen")); + test(S("abcdefghij"), 11, S(""), 0, 1, S("can't happen")); + test(S("abcdefghij"), 11, S(""), 1, 0, S("can't happen")); + test(S("abcdefghij"), 11, S("12345"), 0, 0, S("can't happen")); + test(S("abcdefghij"), 11, S("12345"), 0, 1, S("can't happen")); + test(S("abcdefghij"), 11, S("12345"), 0, 2, S("can't happen")); + test(S("abcdefghij"), 11, S("12345"), 0, 4, S("can't happen")); + test(S("abcdefghij"), 11, S("12345"), 0, 5, S("can't happen")); + test(S("abcdefghij"), 11, S("12345"), 0, 6, S("can't happen")); + test(S("abcdefghij"), 11, S("12345"), 1, 0, S("can't happen")); + test(S("abcdefghij"), 11, S("12345"), 1, 1, S("can't happen")); + test(S("abcdefghij"), 11, S("12345"), 1, 2, S("can't happen")); + test(S("abcdefghij"), 11, S("12345"), 1, 3, S("can't happen")); + test(S("abcdefghij"), 11, S("12345"), 1, 4, S("can't happen")); + test(S("abcdefghij"), 11, S("12345"), 1, 5, S("can't happen")); + test(S("abcdefghij"), 11, S("12345"), 2, 0, S("can't happen")); + test(S("abcdefghij"), 11, S("12345"), 2, 1, S("can't happen")); + test(S("abcdefghij"), 11, S("12345"), 2, 2, S("can't happen")); + test(S("abcdefghij"), 11, S("12345"), 2, 3, S("can't happen")); + test(S("abcdefghij"), 11, S("12345"), 2, 4, S("can't happen")); + test(S("abcdefghij"), 11, S("12345"), 4, 0, S("can't happen")); + test(S("abcdefghij"), 11, S("12345"), 4, 1, S("can't happen")); + test(S("abcdefghij"), 11, S("12345"), 4, 2, S("can't happen")); + test(S("abcdefghij"), 11, S("12345"), 5, 0, S("can't happen")); + test(S("abcdefghij"), 11, S("12345"), 5, 1, S("can't happen")); + test(S("abcdefghij"), 11, S("12345"), 6, 0, S("can't happen")); + test(S("abcdefghij"), 11, S("1234567890"), 0, 0, S("can't happen")); + test(S("abcdefghij"), 11, S("1234567890"), 0, 1, S("can't happen")); + test(S("abcdefghij"), 11, S("1234567890"), 0, 5, S("can't happen")); + test(S("abcdefghij"), 11, S("1234567890"), 0, 9, S("can't happen")); + test(S("abcdefghij"), 11, S("1234567890"), 0, 10, S("can't happen")); + test(S("abcdefghij"), 11, S("1234567890"), 0, 11, S("can't happen")); + test(S("abcdefghij"), 11, S("1234567890"), 1, 0, S("can't happen")); + test(S("abcdefghij"), 11, S("1234567890"), 1, 1, S("can't happen")); + test(S("abcdefghij"), 11, S("1234567890"), 1, 4, S("can't happen")); + test(S("abcdefghij"), 11, S("1234567890"), 1, 8, S("can't happen")); + test(S("abcdefghij"), 11, S("1234567890"), 1, 9, S("can't happen")); + test(S("abcdefghij"), 11, S("1234567890"), 1, 10, S("can't happen")); +} + +template +void test20() +{ + test(S("abcdefghij"), 11, S("1234567890"), 5, 0, S("can't happen")); + test(S("abcdefghij"), 11, S("1234567890"), 5, 1, S("can't happen")); + test(S("abcdefghij"), 11, S("1234567890"), 5, 2, S("can't happen")); + test(S("abcdefghij"), 11, S("1234567890"), 5, 4, S("can't happen")); + test(S("abcdefghij"), 11, S("1234567890"), 5, 5, S("can't happen")); + test(S("abcdefghij"), 11, S("1234567890"), 5, 6, S("can't happen")); + test(S("abcdefghij"), 11, S("1234567890"), 9, 0, S("can't happen")); + test(S("abcdefghij"), 11, S("1234567890"), 9, 1, S("can't happen")); + test(S("abcdefghij"), 11, S("1234567890"), 9, 2, S("can't happen")); + test(S("abcdefghij"), 11, S("1234567890"), 10, 0, S("can't happen")); + test(S("abcdefghij"), 11, S("1234567890"), 10, 1, S("can't happen")); + test(S("abcdefghij"), 11, S("1234567890"), 11, 0, S("can't happen")); + test(S("abcdefghij"), 11, S("12345678901234567890"), 0, 0, S("can't happen")); + test(S("abcdefghij"), 11, S("12345678901234567890"), 0, 1, S("can't happen")); + test(S("abcdefghij"), 11, S("12345678901234567890"), 0, 10, S("can't happen")); + test(S("abcdefghij"), 11, S("12345678901234567890"), 0, 19, S("can't happen")); + test(S("abcdefghij"), 11, S("12345678901234567890"), 0, 20, S("can't happen")); + test(S("abcdefghij"), 11, S("12345678901234567890"), 0, 21, S("can't happen")); + test(S("abcdefghij"), 11, S("12345678901234567890"), 1, 0, S("can't happen")); + test(S("abcdefghij"), 11, S("12345678901234567890"), 1, 1, S("can't happen")); + test(S("abcdefghij"), 11, S("12345678901234567890"), 1, 9, S("can't happen")); + test(S("abcdefghij"), 11, S("12345678901234567890"), 1, 18, S("can't happen")); + test(S("abcdefghij"), 11, S("12345678901234567890"), 1, 19, S("can't happen")); + test(S("abcdefghij"), 11, S("12345678901234567890"), 1, 20, S("can't happen")); + test(S("abcdefghij"), 11, S("12345678901234567890"), 10, 0, S("can't happen")); + test(S("abcdefghij"), 11, S("12345678901234567890"), 10, 1, S("can't happen")); + test(S("abcdefghij"), 11, S("12345678901234567890"), 10, 5, S("can't happen")); + test(S("abcdefghij"), 11, S("12345678901234567890"), 10, 9, S("can't happen")); + test(S("abcdefghij"), 11, S("12345678901234567890"), 10, 10, S("can't happen")); + test(S("abcdefghij"), 11, S("12345678901234567890"), 10, 11, S("can't happen")); + test(S("abcdefghij"), 11, S("12345678901234567890"), 19, 0, S("can't happen")); + test(S("abcdefghij"), 11, S("12345678901234567890"), 19, 1, S("can't happen")); + test(S("abcdefghij"), 11, S("12345678901234567890"), 19, 2, S("can't happen")); + test(S("abcdefghij"), 11, S("12345678901234567890"), 20, 0, S("can't happen")); + test(S("abcdefghij"), 11, S("12345678901234567890"), 20, 1, S("can't happen")); + test(S("abcdefghij"), 11, S("12345678901234567890"), 21, 0, S("can't happen")); + test(S("abcdefghijklmnopqrst"), 0, S(""), 0, 0, S("abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, S(""), 0, 1, S("abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, S(""), 1, 0, S("can't happen")); + test(S("abcdefghijklmnopqrst"), 0, S("12345"), 0, 0, S("abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, S("12345"), 0, 1, S("1abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, S("12345"), 0, 2, S("12abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, S("12345"), 0, 4, S("1234abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, S("12345"), 0, 5, S("12345abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, S("12345"), 0, 6, S("12345abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, S("12345"), 1, 0, S("abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, S("12345"), 1, 1, S("2abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, S("12345"), 1, 2, S("23abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, S("12345"), 1, 3, S("234abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, S("12345"), 1, 4, S("2345abcdefghijklmnopqrst")); +} + +template +void test21() +{ + test(S("abcdefghijklmnopqrst"), 0, S("12345"), 1, 5, S("2345abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, S("12345"), 2, 0, S("abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, S("12345"), 2, 1, S("3abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, S("12345"), 2, 2, S("34abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, S("12345"), 2, 3, S("345abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, S("12345"), 2, 4, S("345abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, S("12345"), 4, 0, S("abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, S("12345"), 4, 1, S("5abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, S("12345"), 4, 2, S("5abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, S("12345"), 5, 0, S("abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, S("12345"), 5, 1, S("abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, S("12345"), 6, 0, S("can't happen")); + test(S("abcdefghijklmnopqrst"), 0, S("1234567890"), 0, 0, S("abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, S("1234567890"), 0, 1, S("1abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, S("1234567890"), 0, 5, S("12345abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, S("1234567890"), 0, 9, S("123456789abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, S("1234567890"), 0, 10, S("1234567890abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, S("1234567890"), 0, 11, S("1234567890abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, S("1234567890"), 1, 0, S("abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, S("1234567890"), 1, 1, S("2abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, S("1234567890"), 1, 4, S("2345abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, S("1234567890"), 1, 8, S("23456789abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, S("1234567890"), 1, 9, S("234567890abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, S("1234567890"), 1, 10, S("234567890abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, S("1234567890"), 5, 0, S("abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, S("1234567890"), 5, 1, S("6abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, S("1234567890"), 5, 2, S("67abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, S("1234567890"), 5, 4, S("6789abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, S("1234567890"), 5, 5, S("67890abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, S("1234567890"), 5, 6, S("67890abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, S("1234567890"), 9, 0, S("abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, S("1234567890"), 9, 1, S("0abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, S("1234567890"), 9, 2, S("0abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, S("1234567890"), 10, 0, S("abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, S("1234567890"), 10, 1, S("abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, S("1234567890"), 11, 0, S("can't happen")); + test(S("abcdefghijklmnopqrst"), 0, S("12345678901234567890"), 0, 0, S("abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, S("12345678901234567890"), 0, 1, S("1abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, S("12345678901234567890"), 0, 10, S("1234567890abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, S("12345678901234567890"), 0, 19, S("1234567890123456789abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, S("12345678901234567890"), 0, 20, S("12345678901234567890abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, S("12345678901234567890"), 0, 21, S("12345678901234567890abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, S("12345678901234567890"), 1, 0, S("abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, S("12345678901234567890"), 1, 1, S("2abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, S("12345678901234567890"), 1, 9, S("234567890abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, S("12345678901234567890"), 1, 18, S("234567890123456789abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, S("12345678901234567890"), 1, 19, S("2345678901234567890abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, S("12345678901234567890"), 1, 20, S("2345678901234567890abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, S("12345678901234567890"), 10, 0, S("abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, S("12345678901234567890"), 10, 1, S("1abcdefghijklmnopqrst")); +} + +template +void test22() +{ + test(S("abcdefghijklmnopqrst"), 0, S("12345678901234567890"), 10, 5, S("12345abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, S("12345678901234567890"), 10, 9, S("123456789abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, S("12345678901234567890"), 10, 10, S("1234567890abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, S("12345678901234567890"), 10, 11, S("1234567890abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, S("12345678901234567890"), 19, 0, S("abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, S("12345678901234567890"), 19, 1, S("0abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, S("12345678901234567890"), 19, 2, S("0abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, S("12345678901234567890"), 20, 0, S("abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, S("12345678901234567890"), 20, 1, S("abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, S("12345678901234567890"), 21, 0, S("can't happen")); + test(S("abcdefghijklmnopqrst"), 1, S(""), 0, 0, S("abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, S(""), 0, 1, S("abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, S(""), 1, 0, S("can't happen")); + test(S("abcdefghijklmnopqrst"), 1, S("12345"), 0, 0, S("abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, S("12345"), 0, 1, S("a1bcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, S("12345"), 0, 2, S("a12bcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, S("12345"), 0, 4, S("a1234bcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, S("12345"), 0, 5, S("a12345bcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, S("12345"), 0, 6, S("a12345bcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, S("12345"), 1, 0, S("abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, S("12345"), 1, 1, S("a2bcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, S("12345"), 1, 2, S("a23bcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, S("12345"), 1, 3, S("a234bcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, S("12345"), 1, 4, S("a2345bcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, S("12345"), 1, 5, S("a2345bcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, S("12345"), 2, 0, S("abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, S("12345"), 2, 1, S("a3bcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, S("12345"), 2, 2, S("a34bcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, S("12345"), 2, 3, S("a345bcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, S("12345"), 2, 4, S("a345bcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, S("12345"), 4, 0, S("abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, S("12345"), 4, 1, S("a5bcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, S("12345"), 4, 2, S("a5bcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, S("12345"), 5, 0, S("abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, S("12345"), 5, 1, S("abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, S("12345"), 6, 0, S("can't happen")); + test(S("abcdefghijklmnopqrst"), 1, S("1234567890"), 0, 0, S("abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, S("1234567890"), 0, 1, S("a1bcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, S("1234567890"), 0, 5, S("a12345bcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, S("1234567890"), 0, 9, S("a123456789bcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, S("1234567890"), 0, 10, S("a1234567890bcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, S("1234567890"), 0, 11, S("a1234567890bcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, S("1234567890"), 1, 0, S("abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, S("1234567890"), 1, 1, S("a2bcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, S("1234567890"), 1, 4, S("a2345bcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, S("1234567890"), 1, 8, S("a23456789bcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, S("1234567890"), 1, 9, S("a234567890bcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, S("1234567890"), 1, 10, S("a234567890bcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, S("1234567890"), 5, 0, S("abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, S("1234567890"), 5, 1, S("a6bcdefghijklmnopqrst")); +} + +template +void test23() +{ + test(S("abcdefghijklmnopqrst"), 1, S("1234567890"), 5, 2, S("a67bcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, S("1234567890"), 5, 4, S("a6789bcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, S("1234567890"), 5, 5, S("a67890bcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, S("1234567890"), 5, 6, S("a67890bcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, S("1234567890"), 9, 0, S("abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, S("1234567890"), 9, 1, S("a0bcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, S("1234567890"), 9, 2, S("a0bcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, S("1234567890"), 10, 0, S("abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, S("1234567890"), 10, 1, S("abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, S("1234567890"), 11, 0, S("can't happen")); + test(S("abcdefghijklmnopqrst"), 1, S("12345678901234567890"), 0, 0, S("abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, S("12345678901234567890"), 0, 1, S("a1bcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, S("12345678901234567890"), 0, 10, S("a1234567890bcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, S("12345678901234567890"), 0, 19, S("a1234567890123456789bcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, S("12345678901234567890"), 0, 20, S("a12345678901234567890bcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, S("12345678901234567890"), 0, 21, S("a12345678901234567890bcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, S("12345678901234567890"), 1, 0, S("abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, S("12345678901234567890"), 1, 1, S("a2bcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, S("12345678901234567890"), 1, 9, S("a234567890bcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, S("12345678901234567890"), 1, 18, S("a234567890123456789bcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, S("12345678901234567890"), 1, 19, S("a2345678901234567890bcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, S("12345678901234567890"), 1, 20, S("a2345678901234567890bcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, S("12345678901234567890"), 10, 0, S("abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, S("12345678901234567890"), 10, 1, S("a1bcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, S("12345678901234567890"), 10, 5, S("a12345bcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, S("12345678901234567890"), 10, 9, S("a123456789bcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, S("12345678901234567890"), 10, 10, S("a1234567890bcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, S("12345678901234567890"), 10, 11, S("a1234567890bcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, S("12345678901234567890"), 19, 0, S("abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, S("12345678901234567890"), 19, 1, S("a0bcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, S("12345678901234567890"), 19, 2, S("a0bcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, S("12345678901234567890"), 20, 0, S("abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, S("12345678901234567890"), 20, 1, S("abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, S("12345678901234567890"), 21, 0, S("can't happen")); + test(S("abcdefghijklmnopqrst"), 10, S(""), 0, 0, S("abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 10, S(""), 0, 1, S("abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 10, S(""), 1, 0, S("can't happen")); + test(S("abcdefghijklmnopqrst"), 10, S("12345"), 0, 0, S("abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 10, S("12345"), 0, 1, S("abcdefghij1klmnopqrst")); + test(S("abcdefghijklmnopqrst"), 10, S("12345"), 0, 2, S("abcdefghij12klmnopqrst")); + test(S("abcdefghijklmnopqrst"), 10, S("12345"), 0, 4, S("abcdefghij1234klmnopqrst")); + test(S("abcdefghijklmnopqrst"), 10, S("12345"), 0, 5, S("abcdefghij12345klmnopqrst")); + test(S("abcdefghijklmnopqrst"), 10, S("12345"), 0, 6, S("abcdefghij12345klmnopqrst")); + test(S("abcdefghijklmnopqrst"), 10, S("12345"), 1, 0, S("abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 10, S("12345"), 1, 1, S("abcdefghij2klmnopqrst")); + test(S("abcdefghijklmnopqrst"), 10, S("12345"), 1, 2, S("abcdefghij23klmnopqrst")); + test(S("abcdefghijklmnopqrst"), 10, S("12345"), 1, 3, S("abcdefghij234klmnopqrst")); + test(S("abcdefghijklmnopqrst"), 10, S("12345"), 1, 4, S("abcdefghij2345klmnopqrst")); + test(S("abcdefghijklmnopqrst"), 10, S("12345"), 1, 5, S("abcdefghij2345klmnopqrst")); + test(S("abcdefghijklmnopqrst"), 10, S("12345"), 2, 0, S("abcdefghijklmnopqrst")); +} + +template +void test24() +{ + test(S("abcdefghijklmnopqrst"), 10, S("12345"), 2, 1, S("abcdefghij3klmnopqrst")); + test(S("abcdefghijklmnopqrst"), 10, S("12345"), 2, 2, S("abcdefghij34klmnopqrst")); + test(S("abcdefghijklmnopqrst"), 10, S("12345"), 2, 3, S("abcdefghij345klmnopqrst")); + test(S("abcdefghijklmnopqrst"), 10, S("12345"), 2, 4, S("abcdefghij345klmnopqrst")); + test(S("abcdefghijklmnopqrst"), 10, S("12345"), 4, 0, S("abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 10, S("12345"), 4, 1, S("abcdefghij5klmnopqrst")); + test(S("abcdefghijklmnopqrst"), 10, S("12345"), 4, 2, S("abcdefghij5klmnopqrst")); + test(S("abcdefghijklmnopqrst"), 10, S("12345"), 5, 0, S("abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 10, S("12345"), 5, 1, S("abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 10, S("12345"), 6, 0, S("can't happen")); + test(S("abcdefghijklmnopqrst"), 10, S("1234567890"), 0, 0, S("abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 10, S("1234567890"), 0, 1, S("abcdefghij1klmnopqrst")); + test(S("abcdefghijklmnopqrst"), 10, S("1234567890"), 0, 5, S("abcdefghij12345klmnopqrst")); + test(S("abcdefghijklmnopqrst"), 10, S("1234567890"), 0, 9, S("abcdefghij123456789klmnopqrst")); + test(S("abcdefghijklmnopqrst"), 10, S("1234567890"), 0, 10, S("abcdefghij1234567890klmnopqrst")); + test(S("abcdefghijklmnopqrst"), 10, S("1234567890"), 0, 11, S("abcdefghij1234567890klmnopqrst")); + test(S("abcdefghijklmnopqrst"), 10, S("1234567890"), 1, 0, S("abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 10, S("1234567890"), 1, 1, S("abcdefghij2klmnopqrst")); + test(S("abcdefghijklmnopqrst"), 10, S("1234567890"), 1, 4, S("abcdefghij2345klmnopqrst")); + test(S("abcdefghijklmnopqrst"), 10, S("1234567890"), 1, 8, S("abcdefghij23456789klmnopqrst")); + test(S("abcdefghijklmnopqrst"), 10, S("1234567890"), 1, 9, S("abcdefghij234567890klmnopqrst")); + test(S("abcdefghijklmnopqrst"), 10, S("1234567890"), 1, 10, S("abcdefghij234567890klmnopqrst")); + test(S("abcdefghijklmnopqrst"), 10, S("1234567890"), 5, 0, S("abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 10, S("1234567890"), 5, 1, S("abcdefghij6klmnopqrst")); + test(S("abcdefghijklmnopqrst"), 10, S("1234567890"), 5, 2, S("abcdefghij67klmnopqrst")); + test(S("abcdefghijklmnopqrst"), 10, S("1234567890"), 5, 4, S("abcdefghij6789klmnopqrst")); + test(S("abcdefghijklmnopqrst"), 10, S("1234567890"), 5, 5, S("abcdefghij67890klmnopqrst")); + test(S("abcdefghijklmnopqrst"), 10, S("1234567890"), 5, 6, S("abcdefghij67890klmnopqrst")); + test(S("abcdefghijklmnopqrst"), 10, S("1234567890"), 9, 0, S("abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 10, S("1234567890"), 9, 1, S("abcdefghij0klmnopqrst")); + test(S("abcdefghijklmnopqrst"), 10, S("1234567890"), 9, 2, S("abcdefghij0klmnopqrst")); + test(S("abcdefghijklmnopqrst"), 10, S("1234567890"), 10, 0, S("abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 10, S("1234567890"), 10, 1, S("abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 10, S("1234567890"), 11, 0, S("can't happen")); + test(S("abcdefghijklmnopqrst"), 10, S("12345678901234567890"), 0, 0, S("abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 10, S("12345678901234567890"), 0, 1, S("abcdefghij1klmnopqrst")); + test(S("abcdefghijklmnopqrst"), 10, S("12345678901234567890"), 0, 10, S("abcdefghij1234567890klmnopqrst")); + test(S("abcdefghijklmnopqrst"), 10, S("12345678901234567890"), 0, 19, S("abcdefghij1234567890123456789klmnopqrst")); + test(S("abcdefghijklmnopqrst"), 10, S("12345678901234567890"), 0, 20, S("abcdefghij12345678901234567890klmnopqrst")); + test(S("abcdefghijklmnopqrst"), 10, S("12345678901234567890"), 0, 21, S("abcdefghij12345678901234567890klmnopqrst")); + test(S("abcdefghijklmnopqrst"), 10, S("12345678901234567890"), 1, 0, S("abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 10, S("12345678901234567890"), 1, 1, S("abcdefghij2klmnopqrst")); + test(S("abcdefghijklmnopqrst"), 10, S("12345678901234567890"), 1, 9, S("abcdefghij234567890klmnopqrst")); + test(S("abcdefghijklmnopqrst"), 10, S("12345678901234567890"), 1, 18, S("abcdefghij234567890123456789klmnopqrst")); + test(S("abcdefghijklmnopqrst"), 10, S("12345678901234567890"), 1, 19, S("abcdefghij2345678901234567890klmnopqrst")); + test(S("abcdefghijklmnopqrst"), 10, S("12345678901234567890"), 1, 20, S("abcdefghij2345678901234567890klmnopqrst")); + test(S("abcdefghijklmnopqrst"), 10, S("12345678901234567890"), 10, 0, S("abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 10, S("12345678901234567890"), 10, 1, S("abcdefghij1klmnopqrst")); + test(S("abcdefghijklmnopqrst"), 10, S("12345678901234567890"), 10, 5, S("abcdefghij12345klmnopqrst")); + test(S("abcdefghijklmnopqrst"), 10, S("12345678901234567890"), 10, 9, S("abcdefghij123456789klmnopqrst")); +} + +template +void test25() +{ + test(S("abcdefghijklmnopqrst"), 10, S("12345678901234567890"), 10, 10, S("abcdefghij1234567890klmnopqrst")); + test(S("abcdefghijklmnopqrst"), 10, S("12345678901234567890"), 10, 11, S("abcdefghij1234567890klmnopqrst")); + test(S("abcdefghijklmnopqrst"), 10, S("12345678901234567890"), 19, 0, S("abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 10, S("12345678901234567890"), 19, 1, S("abcdefghij0klmnopqrst")); + test(S("abcdefghijklmnopqrst"), 10, S("12345678901234567890"), 19, 2, S("abcdefghij0klmnopqrst")); + test(S("abcdefghijklmnopqrst"), 10, S("12345678901234567890"), 20, 0, S("abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 10, S("12345678901234567890"), 20, 1, S("abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 10, S("12345678901234567890"), 21, 0, S("can't happen")); + test(S("abcdefghijklmnopqrst"), 19, S(""), 0, 0, S("abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 19, S(""), 0, 1, S("abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 19, S(""), 1, 0, S("can't happen")); + test(S("abcdefghijklmnopqrst"), 19, S("12345"), 0, 0, S("abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 19, S("12345"), 0, 1, S("abcdefghijklmnopqrs1t")); + test(S("abcdefghijklmnopqrst"), 19, S("12345"), 0, 2, S("abcdefghijklmnopqrs12t")); + test(S("abcdefghijklmnopqrst"), 19, S("12345"), 0, 4, S("abcdefghijklmnopqrs1234t")); + test(S("abcdefghijklmnopqrst"), 19, S("12345"), 0, 5, S("abcdefghijklmnopqrs12345t")); + test(S("abcdefghijklmnopqrst"), 19, S("12345"), 0, 6, S("abcdefghijklmnopqrs12345t")); + test(S("abcdefghijklmnopqrst"), 19, S("12345"), 1, 0, S("abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 19, S("12345"), 1, 1, S("abcdefghijklmnopqrs2t")); + test(S("abcdefghijklmnopqrst"), 19, S("12345"), 1, 2, S("abcdefghijklmnopqrs23t")); + test(S("abcdefghijklmnopqrst"), 19, S("12345"), 1, 3, S("abcdefghijklmnopqrs234t")); + test(S("abcdefghijklmnopqrst"), 19, S("12345"), 1, 4, S("abcdefghijklmnopqrs2345t")); + test(S("abcdefghijklmnopqrst"), 19, S("12345"), 1, 5, S("abcdefghijklmnopqrs2345t")); + test(S("abcdefghijklmnopqrst"), 19, S("12345"), 2, 0, S("abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 19, S("12345"), 2, 1, S("abcdefghijklmnopqrs3t")); + test(S("abcdefghijklmnopqrst"), 19, S("12345"), 2, 2, S("abcdefghijklmnopqrs34t")); + test(S("abcdefghijklmnopqrst"), 19, S("12345"), 2, 3, S("abcdefghijklmnopqrs345t")); + test(S("abcdefghijklmnopqrst"), 19, S("12345"), 2, 4, S("abcdefghijklmnopqrs345t")); + test(S("abcdefghijklmnopqrst"), 19, S("12345"), 4, 0, S("abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 19, S("12345"), 4, 1, S("abcdefghijklmnopqrs5t")); + test(S("abcdefghijklmnopqrst"), 19, S("12345"), 4, 2, S("abcdefghijklmnopqrs5t")); + test(S("abcdefghijklmnopqrst"), 19, S("12345"), 5, 0, S("abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 19, S("12345"), 5, 1, S("abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 19, S("12345"), 6, 0, S("can't happen")); + test(S("abcdefghijklmnopqrst"), 19, S("1234567890"), 0, 0, S("abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 19, S("1234567890"), 0, 1, S("abcdefghijklmnopqrs1t")); + test(S("abcdefghijklmnopqrst"), 19, S("1234567890"), 0, 5, S("abcdefghijklmnopqrs12345t")); + test(S("abcdefghijklmnopqrst"), 19, S("1234567890"), 0, 9, S("abcdefghijklmnopqrs123456789t")); + test(S("abcdefghijklmnopqrst"), 19, S("1234567890"), 0, 10, S("abcdefghijklmnopqrs1234567890t")); + test(S("abcdefghijklmnopqrst"), 19, S("1234567890"), 0, 11, S("abcdefghijklmnopqrs1234567890t")); + test(S("abcdefghijklmnopqrst"), 19, S("1234567890"), 1, 0, S("abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 19, S("1234567890"), 1, 1, S("abcdefghijklmnopqrs2t")); + test(S("abcdefghijklmnopqrst"), 19, S("1234567890"), 1, 4, S("abcdefghijklmnopqrs2345t")); + test(S("abcdefghijklmnopqrst"), 19, S("1234567890"), 1, 8, S("abcdefghijklmnopqrs23456789t")); + test(S("abcdefghijklmnopqrst"), 19, S("1234567890"), 1, 9, S("abcdefghijklmnopqrs234567890t")); + test(S("abcdefghijklmnopqrst"), 19, S("1234567890"), 1, 10, S("abcdefghijklmnopqrs234567890t")); + test(S("abcdefghijklmnopqrst"), 19, S("1234567890"), 5, 0, S("abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 19, S("1234567890"), 5, 1, S("abcdefghijklmnopqrs6t")); + test(S("abcdefghijklmnopqrst"), 19, S("1234567890"), 5, 2, S("abcdefghijklmnopqrs67t")); + test(S("abcdefghijklmnopqrst"), 19, S("1234567890"), 5, 4, S("abcdefghijklmnopqrs6789t")); +} + +template +void test26() +{ + test(S("abcdefghijklmnopqrst"), 19, S("1234567890"), 5, 5, S("abcdefghijklmnopqrs67890t")); + test(S("abcdefghijklmnopqrst"), 19, S("1234567890"), 5, 6, S("abcdefghijklmnopqrs67890t")); + test(S("abcdefghijklmnopqrst"), 19, S("1234567890"), 9, 0, S("abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 19, S("1234567890"), 9, 1, S("abcdefghijklmnopqrs0t")); + test(S("abcdefghijklmnopqrst"), 19, S("1234567890"), 9, 2, S("abcdefghijklmnopqrs0t")); + test(S("abcdefghijklmnopqrst"), 19, S("1234567890"), 10, 0, S("abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 19, S("1234567890"), 10, 1, S("abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 19, S("1234567890"), 11, 0, S("can't happen")); + test(S("abcdefghijklmnopqrst"), 19, S("12345678901234567890"), 0, 0, S("abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 19, S("12345678901234567890"), 0, 1, S("abcdefghijklmnopqrs1t")); + test(S("abcdefghijklmnopqrst"), 19, S("12345678901234567890"), 0, 10, S("abcdefghijklmnopqrs1234567890t")); + test(S("abcdefghijklmnopqrst"), 19, S("12345678901234567890"), 0, 19, S("abcdefghijklmnopqrs1234567890123456789t")); + test(S("abcdefghijklmnopqrst"), 19, S("12345678901234567890"), 0, 20, S("abcdefghijklmnopqrs12345678901234567890t")); + test(S("abcdefghijklmnopqrst"), 19, S("12345678901234567890"), 0, 21, S("abcdefghijklmnopqrs12345678901234567890t")); + test(S("abcdefghijklmnopqrst"), 19, S("12345678901234567890"), 1, 0, S("abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 19, S("12345678901234567890"), 1, 1, S("abcdefghijklmnopqrs2t")); + test(S("abcdefghijklmnopqrst"), 19, S("12345678901234567890"), 1, 9, S("abcdefghijklmnopqrs234567890t")); + test(S("abcdefghijklmnopqrst"), 19, S("12345678901234567890"), 1, 18, S("abcdefghijklmnopqrs234567890123456789t")); + test(S("abcdefghijklmnopqrst"), 19, S("12345678901234567890"), 1, 19, S("abcdefghijklmnopqrs2345678901234567890t")); + test(S("abcdefghijklmnopqrst"), 19, S("12345678901234567890"), 1, 20, S("abcdefghijklmnopqrs2345678901234567890t")); + test(S("abcdefghijklmnopqrst"), 19, S("12345678901234567890"), 10, 0, S("abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 19, S("12345678901234567890"), 10, 1, S("abcdefghijklmnopqrs1t")); + test(S("abcdefghijklmnopqrst"), 19, S("12345678901234567890"), 10, 5, S("abcdefghijklmnopqrs12345t")); + test(S("abcdefghijklmnopqrst"), 19, S("12345678901234567890"), 10, 9, S("abcdefghijklmnopqrs123456789t")); + test(S("abcdefghijklmnopqrst"), 19, S("12345678901234567890"), 10, 10, S("abcdefghijklmnopqrs1234567890t")); + test(S("abcdefghijklmnopqrst"), 19, S("12345678901234567890"), 10, 11, S("abcdefghijklmnopqrs1234567890t")); + test(S("abcdefghijklmnopqrst"), 19, S("12345678901234567890"), 19, 0, S("abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 19, S("12345678901234567890"), 19, 1, S("abcdefghijklmnopqrs0t")); + test(S("abcdefghijklmnopqrst"), 19, S("12345678901234567890"), 19, 2, S("abcdefghijklmnopqrs0t")); + test(S("abcdefghijklmnopqrst"), 19, S("12345678901234567890"), 20, 0, S("abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 19, S("12345678901234567890"), 20, 1, S("abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 19, S("12345678901234567890"), 21, 0, S("can't happen")); + test(S("abcdefghijklmnopqrst"), 20, S(""), 0, 0, S("abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 20, S(""), 0, 1, S("abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 20, S(""), 1, 0, S("can't happen")); + test(S("abcdefghijklmnopqrst"), 20, S("12345"), 0, 0, S("abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 20, S("12345"), 0, 1, S("abcdefghijklmnopqrst1")); + test(S("abcdefghijklmnopqrst"), 20, S("12345"), 0, 2, S("abcdefghijklmnopqrst12")); + test(S("abcdefghijklmnopqrst"), 20, S("12345"), 0, 4, S("abcdefghijklmnopqrst1234")); + test(S("abcdefghijklmnopqrst"), 20, S("12345"), 0, 5, S("abcdefghijklmnopqrst12345")); + test(S("abcdefghijklmnopqrst"), 20, S("12345"), 0, 6, S("abcdefghijklmnopqrst12345")); + test(S("abcdefghijklmnopqrst"), 20, S("12345"), 1, 0, S("abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 20, S("12345"), 1, 1, S("abcdefghijklmnopqrst2")); + test(S("abcdefghijklmnopqrst"), 20, S("12345"), 1, 2, S("abcdefghijklmnopqrst23")); + test(S("abcdefghijklmnopqrst"), 20, S("12345"), 1, 3, S("abcdefghijklmnopqrst234")); + test(S("abcdefghijklmnopqrst"), 20, S("12345"), 1, 4, S("abcdefghijklmnopqrst2345")); + test(S("abcdefghijklmnopqrst"), 20, S("12345"), 1, 5, S("abcdefghijklmnopqrst2345")); + test(S("abcdefghijklmnopqrst"), 20, S("12345"), 2, 0, S("abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 20, S("12345"), 2, 1, S("abcdefghijklmnopqrst3")); + test(S("abcdefghijklmnopqrst"), 20, S("12345"), 2, 2, S("abcdefghijklmnopqrst34")); +} + +template +void test27() +{ + test(S("abcdefghijklmnopqrst"), 20, S("12345"), 2, 3, S("abcdefghijklmnopqrst345")); + test(S("abcdefghijklmnopqrst"), 20, S("12345"), 2, 4, S("abcdefghijklmnopqrst345")); + test(S("abcdefghijklmnopqrst"), 20, S("12345"), 4, 0, S("abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 20, S("12345"), 4, 1, S("abcdefghijklmnopqrst5")); + test(S("abcdefghijklmnopqrst"), 20, S("12345"), 4, 2, S("abcdefghijklmnopqrst5")); + test(S("abcdefghijklmnopqrst"), 20, S("12345"), 5, 0, S("abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 20, S("12345"), 5, 1, S("abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 20, S("12345"), 6, 0, S("can't happen")); + test(S("abcdefghijklmnopqrst"), 20, S("1234567890"), 0, 0, S("abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 20, S("1234567890"), 0, 1, S("abcdefghijklmnopqrst1")); + test(S("abcdefghijklmnopqrst"), 20, S("1234567890"), 0, 5, S("abcdefghijklmnopqrst12345")); + test(S("abcdefghijklmnopqrst"), 20, S("1234567890"), 0, 9, S("abcdefghijklmnopqrst123456789")); + test(S("abcdefghijklmnopqrst"), 20, S("1234567890"), 0, 10, S("abcdefghijklmnopqrst1234567890")); + test(S("abcdefghijklmnopqrst"), 20, S("1234567890"), 0, 11, S("abcdefghijklmnopqrst1234567890")); + test(S("abcdefghijklmnopqrst"), 20, S("1234567890"), 1, 0, S("abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 20, S("1234567890"), 1, 1, S("abcdefghijklmnopqrst2")); + test(S("abcdefghijklmnopqrst"), 20, S("1234567890"), 1, 4, S("abcdefghijklmnopqrst2345")); + test(S("abcdefghijklmnopqrst"), 20, S("1234567890"), 1, 8, S("abcdefghijklmnopqrst23456789")); + test(S("abcdefghijklmnopqrst"), 20, S("1234567890"), 1, 9, S("abcdefghijklmnopqrst234567890")); + test(S("abcdefghijklmnopqrst"), 20, S("1234567890"), 1, 10, S("abcdefghijklmnopqrst234567890")); + test(S("abcdefghijklmnopqrst"), 20, S("1234567890"), 5, 0, S("abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 20, S("1234567890"), 5, 1, S("abcdefghijklmnopqrst6")); + test(S("abcdefghijklmnopqrst"), 20, S("1234567890"), 5, 2, S("abcdefghijklmnopqrst67")); + test(S("abcdefghijklmnopqrst"), 20, S("1234567890"), 5, 4, S("abcdefghijklmnopqrst6789")); + test(S("abcdefghijklmnopqrst"), 20, S("1234567890"), 5, 5, S("abcdefghijklmnopqrst67890")); + test(S("abcdefghijklmnopqrst"), 20, S("1234567890"), 5, 6, S("abcdefghijklmnopqrst67890")); + test(S("abcdefghijklmnopqrst"), 20, S("1234567890"), 9, 0, S("abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 20, S("1234567890"), 9, 1, S("abcdefghijklmnopqrst0")); + test(S("abcdefghijklmnopqrst"), 20, S("1234567890"), 9, 2, S("abcdefghijklmnopqrst0")); + test(S("abcdefghijklmnopqrst"), 20, S("1234567890"), 10, 0, S("abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 20, S("1234567890"), 10, 1, S("abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 20, S("1234567890"), 11, 0, S("can't happen")); + test(S("abcdefghijklmnopqrst"), 20, S("12345678901234567890"), 0, 0, S("abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 20, S("12345678901234567890"), 0, 1, S("abcdefghijklmnopqrst1")); + test(S("abcdefghijklmnopqrst"), 20, S("12345678901234567890"), 0, 10, S("abcdefghijklmnopqrst1234567890")); + test(S("abcdefghijklmnopqrst"), 20, S("12345678901234567890"), 0, 19, S("abcdefghijklmnopqrst1234567890123456789")); + test(S("abcdefghijklmnopqrst"), 20, S("12345678901234567890"), 0, 20, S("abcdefghijklmnopqrst12345678901234567890")); + test(S("abcdefghijklmnopqrst"), 20, S("12345678901234567890"), 0, 21, S("abcdefghijklmnopqrst12345678901234567890")); + test(S("abcdefghijklmnopqrst"), 20, S("12345678901234567890"), 1, 0, S("abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 20, S("12345678901234567890"), 1, 1, S("abcdefghijklmnopqrst2")); + test(S("abcdefghijklmnopqrst"), 20, S("12345678901234567890"), 1, 9, S("abcdefghijklmnopqrst234567890")); + test(S("abcdefghijklmnopqrst"), 20, S("12345678901234567890"), 1, 18, S("abcdefghijklmnopqrst234567890123456789")); + test(S("abcdefghijklmnopqrst"), 20, S("12345678901234567890"), 1, 19, S("abcdefghijklmnopqrst2345678901234567890")); + test(S("abcdefghijklmnopqrst"), 20, S("12345678901234567890"), 1, 20, S("abcdefghijklmnopqrst2345678901234567890")); + test(S("abcdefghijklmnopqrst"), 20, S("12345678901234567890"), 10, 0, S("abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 20, S("12345678901234567890"), 10, 1, S("abcdefghijklmnopqrst1")); + test(S("abcdefghijklmnopqrst"), 20, S("12345678901234567890"), 10, 5, S("abcdefghijklmnopqrst12345")); + test(S("abcdefghijklmnopqrst"), 20, S("12345678901234567890"), 10, 9, S("abcdefghijklmnopqrst123456789")); + test(S("abcdefghijklmnopqrst"), 20, S("12345678901234567890"), 10, 10, S("abcdefghijklmnopqrst1234567890")); + test(S("abcdefghijklmnopqrst"), 20, S("12345678901234567890"), 10, 11, S("abcdefghijklmnopqrst1234567890")); +} + +template +void test28() +{ + test(S("abcdefghijklmnopqrst"), 20, S("12345678901234567890"), 19, 0, S("abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 20, S("12345678901234567890"), 19, 1, S("abcdefghijklmnopqrst0")); + test(S("abcdefghijklmnopqrst"), 20, S("12345678901234567890"), 19, 2, S("abcdefghijklmnopqrst0")); + test(S("abcdefghijklmnopqrst"), 20, S("12345678901234567890"), 20, 0, S("abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 20, S("12345678901234567890"), 20, 1, S("abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 20, S("12345678901234567890"), 21, 0, S("can't happen")); + test(S("abcdefghijklmnopqrst"), 21, S(""), 0, 0, S("can't happen")); + test(S("abcdefghijklmnopqrst"), 21, S(""), 0, 1, S("can't happen")); + test(S("abcdefghijklmnopqrst"), 21, S(""), 1, 0, S("can't happen")); + test(S("abcdefghijklmnopqrst"), 21, S("12345"), 0, 0, S("can't happen")); + test(S("abcdefghijklmnopqrst"), 21, S("12345"), 0, 1, S("can't happen")); + test(S("abcdefghijklmnopqrst"), 21, S("12345"), 0, 2, S("can't happen")); + test(S("abcdefghijklmnopqrst"), 21, S("12345"), 0, 4, S("can't happen")); + test(S("abcdefghijklmnopqrst"), 21, S("12345"), 0, 5, S("can't happen")); + test(S("abcdefghijklmnopqrst"), 21, S("12345"), 0, 6, S("can't happen")); + test(S("abcdefghijklmnopqrst"), 21, S("12345"), 1, 0, S("can't happen")); + test(S("abcdefghijklmnopqrst"), 21, S("12345"), 1, 1, S("can't happen")); + test(S("abcdefghijklmnopqrst"), 21, S("12345"), 1, 2, S("can't happen")); + test(S("abcdefghijklmnopqrst"), 21, S("12345"), 1, 3, S("can't happen")); + test(S("abcdefghijklmnopqrst"), 21, S("12345"), 1, 4, S("can't happen")); + test(S("abcdefghijklmnopqrst"), 21, S("12345"), 1, 5, S("can't happen")); + test(S("abcdefghijklmnopqrst"), 21, S("12345"), 2, 0, S("can't happen")); + test(S("abcdefghijklmnopqrst"), 21, S("12345"), 2, 1, S("can't happen")); + test(S("abcdefghijklmnopqrst"), 21, S("12345"), 2, 2, S("can't happen")); + test(S("abcdefghijklmnopqrst"), 21, S("12345"), 2, 3, S("can't happen")); + test(S("abcdefghijklmnopqrst"), 21, S("12345"), 2, 4, S("can't happen")); + test(S("abcdefghijklmnopqrst"), 21, S("12345"), 4, 0, S("can't happen")); + test(S("abcdefghijklmnopqrst"), 21, S("12345"), 4, 1, S("can't happen")); + test(S("abcdefghijklmnopqrst"), 21, S("12345"), 4, 2, S("can't happen")); + test(S("abcdefghijklmnopqrst"), 21, S("12345"), 5, 0, S("can't happen")); + test(S("abcdefghijklmnopqrst"), 21, S("12345"), 5, 1, S("can't happen")); + test(S("abcdefghijklmnopqrst"), 21, S("12345"), 6, 0, S("can't happen")); + test(S("abcdefghijklmnopqrst"), 21, S("1234567890"), 0, 0, S("can't happen")); + test(S("abcdefghijklmnopqrst"), 21, S("1234567890"), 0, 1, S("can't happen")); + test(S("abcdefghijklmnopqrst"), 21, S("1234567890"), 0, 5, S("can't happen")); + test(S("abcdefghijklmnopqrst"), 21, S("1234567890"), 0, 9, S("can't happen")); + test(S("abcdefghijklmnopqrst"), 21, S("1234567890"), 0, 10, S("can't happen")); + test(S("abcdefghijklmnopqrst"), 21, S("1234567890"), 0, 11, S("can't happen")); + test(S("abcdefghijklmnopqrst"), 21, S("1234567890"), 1, 0, S("can't happen")); + test(S("abcdefghijklmnopqrst"), 21, S("1234567890"), 1, 1, S("can't happen")); + test(S("abcdefghijklmnopqrst"), 21, S("1234567890"), 1, 4, S("can't happen")); + test(S("abcdefghijklmnopqrst"), 21, S("1234567890"), 1, 8, S("can't happen")); + test(S("abcdefghijklmnopqrst"), 21, S("1234567890"), 1, 9, S("can't happen")); + test(S("abcdefghijklmnopqrst"), 21, S("1234567890"), 1, 10, S("can't happen")); + test(S("abcdefghijklmnopqrst"), 21, S("1234567890"), 5, 0, S("can't happen")); + test(S("abcdefghijklmnopqrst"), 21, S("1234567890"), 5, 1, S("can't happen")); + test(S("abcdefghijklmnopqrst"), 21, S("1234567890"), 5, 2, S("can't happen")); + test(S("abcdefghijklmnopqrst"), 21, S("1234567890"), 5, 4, S("can't happen")); + test(S("abcdefghijklmnopqrst"), 21, S("1234567890"), 5, 5, S("can't happen")); + test(S("abcdefghijklmnopqrst"), 21, S("1234567890"), 5, 6, S("can't happen")); +} + +template +void test29() +{ + test(S("abcdefghijklmnopqrst"), 21, S("1234567890"), 9, 0, S("can't happen")); + test(S("abcdefghijklmnopqrst"), 21, S("1234567890"), 9, 1, S("can't happen")); + test(S("abcdefghijklmnopqrst"), 21, S("1234567890"), 9, 2, S("can't happen")); + test(S("abcdefghijklmnopqrst"), 21, S("1234567890"), 10, 0, S("can't happen")); + test(S("abcdefghijklmnopqrst"), 21, S("1234567890"), 10, 1, S("can't happen")); + test(S("abcdefghijklmnopqrst"), 21, S("1234567890"), 11, 0, S("can't happen")); + test(S("abcdefghijklmnopqrst"), 21, S("12345678901234567890"), 0, 0, S("can't happen")); + test(S("abcdefghijklmnopqrst"), 21, S("12345678901234567890"), 0, 1, S("can't happen")); + test(S("abcdefghijklmnopqrst"), 21, S("12345678901234567890"), 0, 10, S("can't happen")); + test(S("abcdefghijklmnopqrst"), 21, S("12345678901234567890"), 0, 19, S("can't happen")); + test(S("abcdefghijklmnopqrst"), 21, S("12345678901234567890"), 0, 20, S("can't happen")); + test(S("abcdefghijklmnopqrst"), 21, S("12345678901234567890"), 0, 21, S("can't happen")); + test(S("abcdefghijklmnopqrst"), 21, S("12345678901234567890"), 1, 0, S("can't happen")); + test(S("abcdefghijklmnopqrst"), 21, S("12345678901234567890"), 1, 1, S("can't happen")); + test(S("abcdefghijklmnopqrst"), 21, S("12345678901234567890"), 1, 9, S("can't happen")); + test(S("abcdefghijklmnopqrst"), 21, S("12345678901234567890"), 1, 18, S("can't happen")); + test(S("abcdefghijklmnopqrst"), 21, S("12345678901234567890"), 1, 19, S("can't happen")); + test(S("abcdefghijklmnopqrst"), 21, S("12345678901234567890"), 1, 20, S("can't happen")); + test(S("abcdefghijklmnopqrst"), 21, S("12345678901234567890"), 10, 0, S("can't happen")); + test(S("abcdefghijklmnopqrst"), 21, S("12345678901234567890"), 10, 1, S("can't happen")); + test(S("abcdefghijklmnopqrst"), 21, S("12345678901234567890"), 10, 5, S("can't happen")); + test(S("abcdefghijklmnopqrst"), 21, S("12345678901234567890"), 10, 9, S("can't happen")); + test(S("abcdefghijklmnopqrst"), 21, S("12345678901234567890"), 10, 10, S("can't happen")); + test(S("abcdefghijklmnopqrst"), 21, S("12345678901234567890"), 10, 11, S("can't happen")); + test(S("abcdefghijklmnopqrst"), 21, S("12345678901234567890"), 19, 0, S("can't happen")); + test(S("abcdefghijklmnopqrst"), 21, S("12345678901234567890"), 19, 1, S("can't happen")); + test(S("abcdefghijklmnopqrst"), 21, S("12345678901234567890"), 19, 2, S("can't happen")); + test(S("abcdefghijklmnopqrst"), 21, S("12345678901234567890"), 20, 0, S("can't happen")); + test(S("abcdefghijklmnopqrst"), 21, S("12345678901234567890"), 20, 1, S("can't happen")); + test(S("abcdefghijklmnopqrst"), 21, S("12345678901234567890"), 21, 0, S("can't happen")); +} + +template +void test30() +{ + test_npos(S(""), 0, S("12345678901234567890"), 0, S("12345678901234567890")); + test_npos(S(""), 0, S("12345678901234567890"), 1, S( "2345678901234567890")); + test_npos(S(""), 0, S("12345678901234567890"), 2, S( "345678901234567890")); + test_npos(S(""), 0, S("12345678901234567890"), 3, S( "45678901234567890")); + test_npos(S(""), 0, S("12345678901234567890"), 5, S( "678901234567890")); + test_npos(S(""), 0, S("12345678901234567890"), 10, S( "1234567890")); + test_npos(S(""), 0, S("12345678901234567890"), 21, S("can't happen")); + test_npos(S("abcdefghijklmnopqrst"), 10, S("12345"), 0, S("abcdefghij12345klmnopqrst")); + test_npos(S("abcdefghijklmnopqrst"), 10, S("12345"), 1, S("abcdefghij2345klmnopqrst")); + test_npos(S("abcdefghijklmnopqrst"), 10, S("12345"), 3, S("abcdefghij45klmnopqrst")); + test_npos(S("abcdefghijklmnopqrst"), 10, S("12345"), 5, S("abcdefghijklmnopqrst")); + test_npos(S("abcdefghijklmnopqrst"), 10, S("12345"), 6, S("can't happen")); +} + +int main() +{ + { + typedef std::string S; + test0(); + test1(); + test2(); + test3(); + test4(); + test5(); + test6(); + test7(); + test8(); + test9(); + test10(); + test11(); + test12(); + test13(); + test14(); + test15(); + test16(); + test17(); + test18(); + test19(); + test20(); + test21(); + test22(); + test23(); + test24(); + test25(); + test26(); + test27(); + test28(); + test29(); + test30(); + } +#if TEST_STD_VER >= 11 + { + typedef std::basic_string, min_allocator> S; + test0(); + test1(); + test2(); + test3(); + test4(); + test5(); + test6(); + test7(); + test8(); + test9(); + test10(); + test11(); + test12(); + test13(); + test14(); + test15(); + test16(); + test17(); + test18(); + test19(); + test20(); + test21(); + test22(); + test23(); + test24(); + test25(); + test26(); + test27(); + test28(); + test29(); + test30(); + } +#endif +} diff --git a/tests/external/libcxx/basic_string/string.modifiers/string_insert/string_view.pass.cpp b/tests/external/libcxx/basic_string/string.modifiers/string_insert/string_view.pass.cpp new file mode 100644 index 0000000..970cbcb --- /dev/null +++ b/tests/external/libcxx/basic_string/string.modifiers/string_insert/string_view.pass.cpp @@ -0,0 +1,239 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// + +// basic_string& +// insert(size_type pos, string_view sv); + +#include +#include +#include + +#include "test_macros.h" +#include "min_allocator.h" + +template +void +test(S s, typename S::size_type pos, SV sv, S expected) +{ + const typename S::size_type old_size = s.size(); + S s0 = s; + if (pos <= old_size) + { + s.insert(pos, sv); + LIBCPP_ASSERT(s.__invariants()); + assert(s == expected); + } +#ifndef TEST_HAS_NO_EXCEPTIONS + else + { + try + { + s.insert(pos, sv); + assert(false); + } + catch (std::out_of_range&) + { + assert(pos > old_size); + assert(s == s0); + } + } +#endif +} + +int main() +{ + { + typedef std::string S; + typedef std::string_view SV; + test(S(""), 0, SV(""), S("")); + test(S(""), 0, SV("12345"), S("12345")); + test(S(""), 0, SV("1234567890"), S("1234567890")); + test(S(""), 0, SV("12345678901234567890"), S("12345678901234567890")); + test(S(""), 1, SV(""), S("can't happen")); + test(S(""), 1, SV("12345"), S("can't happen")); + test(S(""), 1, SV("1234567890"), S("can't happen")); + test(S(""), 1, SV("12345678901234567890"), S("can't happen")); + test(S("abcde"), 0, SV(""), S("abcde")); + test(S("abcde"), 0, SV("12345"), S("12345abcde")); + test(S("abcde"), 0, SV("1234567890"), S("1234567890abcde")); + test(S("abcde"), 0, SV("12345678901234567890"), S("12345678901234567890abcde")); + test(S("abcde"), 1, SV(""), S("abcde")); + test(S("abcde"), 1, SV("12345"), S("a12345bcde")); + test(S("abcde"), 1, SV("1234567890"), S("a1234567890bcde")); + test(S("abcde"), 1, SV("12345678901234567890"), S("a12345678901234567890bcde")); + test(S("abcde"), 2, SV(""), S("abcde")); + test(S("abcde"), 2, SV("12345"), S("ab12345cde")); + test(S("abcde"), 2, SV("1234567890"), S("ab1234567890cde")); + test(S("abcde"), 2, SV("12345678901234567890"), S("ab12345678901234567890cde")); + test(S("abcde"), 4, SV(""), S("abcde")); + test(S("abcde"), 4, SV("12345"), S("abcd12345e")); + test(S("abcde"), 4, SV("1234567890"), S("abcd1234567890e")); + test(S("abcde"), 4, SV("12345678901234567890"), S("abcd12345678901234567890e")); + test(S("abcde"), 5, SV(""), S("abcde")); + test(S("abcde"), 5, SV("12345"), S("abcde12345")); + test(S("abcde"), 5, SV("1234567890"), S("abcde1234567890")); + test(S("abcde"), 5, SV("12345678901234567890"), S("abcde12345678901234567890")); + test(S("abcde"), 6, SV(""), S("can't happen")); + test(S("abcde"), 6, SV("12345"), S("can't happen")); + test(S("abcde"), 6, SV("1234567890"), S("can't happen")); + test(S("abcde"), 6, SV("12345678901234567890"), S("can't happen")); + test(S("abcdefghij"), 0, SV(""), S("abcdefghij")); + test(S("abcdefghij"), 0, SV("12345"), S("12345abcdefghij")); + test(S("abcdefghij"), 0, SV("1234567890"), S("1234567890abcdefghij")); + test(S("abcdefghij"), 0, SV("12345678901234567890"), S("12345678901234567890abcdefghij")); + test(S("abcdefghij"), 1, SV(""), S("abcdefghij")); + test(S("abcdefghij"), 1, SV("12345"), S("a12345bcdefghij")); + test(S("abcdefghij"), 1, SV("1234567890"), S("a1234567890bcdefghij")); + test(S("abcdefghij"), 1, SV("12345678901234567890"), S("a12345678901234567890bcdefghij")); + test(S("abcdefghij"), 5, SV(""), S("abcdefghij")); + test(S("abcdefghij"), 5, SV("12345"), S("abcde12345fghij")); + test(S("abcdefghij"), 5, SV("1234567890"), S("abcde1234567890fghij")); + test(S("abcdefghij"), 5, SV("12345678901234567890"), S("abcde12345678901234567890fghij")); + test(S("abcdefghij"), 9, SV(""), S("abcdefghij")); + test(S("abcdefghij"), 9, SV("12345"), S("abcdefghi12345j")); + test(S("abcdefghij"), 9, SV("1234567890"), S("abcdefghi1234567890j")); + test(S("abcdefghij"), 9, SV("12345678901234567890"), S("abcdefghi12345678901234567890j")); + test(S("abcdefghij"), 10, SV(""), S("abcdefghij")); + test(S("abcdefghij"), 10, SV("12345"), S("abcdefghij12345")); + test(S("abcdefghij"), 10, SV("1234567890"), S("abcdefghij1234567890")); + test(S("abcdefghij"), 10, SV("12345678901234567890"), S("abcdefghij12345678901234567890")); + test(S("abcdefghij"), 11, SV(""), S("can't happen")); + test(S("abcdefghij"), 11, SV("12345"), S("can't happen")); + test(S("abcdefghij"), 11, SV("1234567890"), S("can't happen")); + test(S("abcdefghij"), 11, SV("12345678901234567890"), S("can't happen")); + test(S("abcdefghijklmnopqrst"), 0, SV(""), S("abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, SV("12345"), S("12345abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, SV("1234567890"), S("1234567890abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, SV("12345678901234567890"), S("12345678901234567890abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, SV(""), S("abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, SV("12345"), S("a12345bcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, SV("1234567890"), S("a1234567890bcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, SV("12345678901234567890"), S("a12345678901234567890bcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 10, SV(""), S("abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 10, SV("12345"), S("abcdefghij12345klmnopqrst")); + test(S("abcdefghijklmnopqrst"), 10, SV("1234567890"), S("abcdefghij1234567890klmnopqrst")); + test(S("abcdefghijklmnopqrst"), 10, SV("12345678901234567890"), S("abcdefghij12345678901234567890klmnopqrst")); + test(S("abcdefghijklmnopqrst"), 19, SV(""), S("abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 19, SV("12345"), S("abcdefghijklmnopqrs12345t")); + test(S("abcdefghijklmnopqrst"), 19, SV("1234567890"), S("abcdefghijklmnopqrs1234567890t")); + test(S("abcdefghijklmnopqrst"), 19, SV("12345678901234567890"), S("abcdefghijklmnopqrs12345678901234567890t")); + test(S("abcdefghijklmnopqrst"), 20, SV(""), S("abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 20, SV("12345"), S("abcdefghijklmnopqrst12345")); + test(S("abcdefghijklmnopqrst"), 20, SV("1234567890"), S("abcdefghijklmnopqrst1234567890")); + test(S("abcdefghijklmnopqrst"), 20, SV("12345678901234567890"), S("abcdefghijklmnopqrst12345678901234567890")); + test(S("abcdefghijklmnopqrst"), 21, SV(""), S("can't happen")); + test(S("abcdefghijklmnopqrst"), 21, SV("12345"), S("can't happen")); + test(S("abcdefghijklmnopqrst"), 21, SV("1234567890"), S("can't happen")); + test(S("abcdefghijklmnopqrst"), 21, SV("12345678901234567890"), S("can't happen")); + } +#if TEST_STD_VER >= 11 + { + typedef std::basic_string, min_allocator> S; + typedef std::string_view SV; + test(S(""), 0, SV(""), S("")); + test(S(""), 0, SV("12345"), S("12345")); + test(S(""), 0, SV("1234567890"), S("1234567890")); + test(S(""), 0, SV("12345678901234567890"), S("12345678901234567890")); + test(S(""), 1, SV(""), S("can't happen")); + test(S(""), 1, SV("12345"), S("can't happen")); + test(S(""), 1, SV("1234567890"), S("can't happen")); + test(S(""), 1, SV("12345678901234567890"), S("can't happen")); + test(S("abcde"), 0, SV(""), S("abcde")); + test(S("abcde"), 0, SV("12345"), S("12345abcde")); + test(S("abcde"), 0, SV("1234567890"), S("1234567890abcde")); + test(S("abcde"), 0, SV("12345678901234567890"), S("12345678901234567890abcde")); + test(S("abcde"), 1, SV(""), S("abcde")); + test(S("abcde"), 1, SV("12345"), S("a12345bcde")); + test(S("abcde"), 1, SV("1234567890"), S("a1234567890bcde")); + test(S("abcde"), 1, SV("12345678901234567890"), S("a12345678901234567890bcde")); + test(S("abcde"), 2, SV(""), S("abcde")); + test(S("abcde"), 2, SV("12345"), S("ab12345cde")); + test(S("abcde"), 2, SV("1234567890"), S("ab1234567890cde")); + test(S("abcde"), 2, SV("12345678901234567890"), S("ab12345678901234567890cde")); + test(S("abcde"), 4, SV(""), S("abcde")); + test(S("abcde"), 4, SV("12345"), S("abcd12345e")); + test(S("abcde"), 4, SV("1234567890"), S("abcd1234567890e")); + test(S("abcde"), 4, SV("12345678901234567890"), S("abcd12345678901234567890e")); + test(S("abcde"), 5, SV(""), S("abcde")); + test(S("abcde"), 5, SV("12345"), S("abcde12345")); + test(S("abcde"), 5, SV("1234567890"), S("abcde1234567890")); + test(S("abcde"), 5, SV("12345678901234567890"), S("abcde12345678901234567890")); + test(S("abcde"), 6, SV(""), S("can't happen")); + test(S("abcde"), 6, SV("12345"), S("can't happen")); + test(S("abcde"), 6, SV("1234567890"), S("can't happen")); + test(S("abcde"), 6, SV("12345678901234567890"), S("can't happen")); + test(S("abcdefghij"), 0, SV(""), S("abcdefghij")); + test(S("abcdefghij"), 0, SV("12345"), S("12345abcdefghij")); + test(S("abcdefghij"), 0, SV("1234567890"), S("1234567890abcdefghij")); + test(S("abcdefghij"), 0, SV("12345678901234567890"), S("12345678901234567890abcdefghij")); + test(S("abcdefghij"), 1, SV(""), S("abcdefghij")); + test(S("abcdefghij"), 1, SV("12345"), S("a12345bcdefghij")); + test(S("abcdefghij"), 1, SV("1234567890"), S("a1234567890bcdefghij")); + test(S("abcdefghij"), 1, SV("12345678901234567890"), S("a12345678901234567890bcdefghij")); + test(S("abcdefghij"), 5, SV(""), S("abcdefghij")); + test(S("abcdefghij"), 5, SV("12345"), S("abcde12345fghij")); + test(S("abcdefghij"), 5, SV("1234567890"), S("abcde1234567890fghij")); + test(S("abcdefghij"), 5, SV("12345678901234567890"), S("abcde12345678901234567890fghij")); + test(S("abcdefghij"), 9, SV(""), S("abcdefghij")); + test(S("abcdefghij"), 9, SV("12345"), S("abcdefghi12345j")); + test(S("abcdefghij"), 9, SV("1234567890"), S("abcdefghi1234567890j")); + test(S("abcdefghij"), 9, SV("12345678901234567890"), S("abcdefghi12345678901234567890j")); + test(S("abcdefghij"), 10, SV(""), S("abcdefghij")); + test(S("abcdefghij"), 10, SV("12345"), S("abcdefghij12345")); + test(S("abcdefghij"), 10, SV("1234567890"), S("abcdefghij1234567890")); + test(S("abcdefghij"), 10, SV("12345678901234567890"), S("abcdefghij12345678901234567890")); + test(S("abcdefghij"), 11, SV(""), S("can't happen")); + test(S("abcdefghij"), 11, SV("12345"), S("can't happen")); + test(S("abcdefghij"), 11, SV("1234567890"), S("can't happen")); + test(S("abcdefghij"), 11, SV("12345678901234567890"), S("can't happen")); + test(S("abcdefghijklmnopqrst"), 0, SV(""), S("abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, SV("12345"), S("12345abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, SV("1234567890"), S("1234567890abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, SV("12345678901234567890"), S("12345678901234567890abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, SV(""), S("abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, SV("12345"), S("a12345bcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, SV("1234567890"), S("a1234567890bcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, SV("12345678901234567890"), S("a12345678901234567890bcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 10, SV(""), S("abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 10, SV("12345"), S("abcdefghij12345klmnopqrst")); + test(S("abcdefghijklmnopqrst"), 10, SV("1234567890"), S("abcdefghij1234567890klmnopqrst")); + test(S("abcdefghijklmnopqrst"), 10, SV("12345678901234567890"), S("abcdefghij12345678901234567890klmnopqrst")); + test(S("abcdefghijklmnopqrst"), 19, SV(""), S("abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 19, SV("12345"), S("abcdefghijklmnopqrs12345t")); + test(S("abcdefghijklmnopqrst"), 19, SV("1234567890"), S("abcdefghijklmnopqrs1234567890t")); + test(S("abcdefghijklmnopqrst"), 19, SV("12345678901234567890"), S("abcdefghijklmnopqrs12345678901234567890t")); + test(S("abcdefghijklmnopqrst"), 20, SV(""), S("abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 20, SV("12345"), S("abcdefghijklmnopqrst12345")); + test(S("abcdefghijklmnopqrst"), 20, SV("1234567890"), S("abcdefghijklmnopqrst1234567890")); + test(S("abcdefghijklmnopqrst"), 20, SV("12345678901234567890"), S("abcdefghijklmnopqrst12345678901234567890")); + test(S("abcdefghijklmnopqrst"), 21, SV(""), S("can't happen")); + test(S("abcdefghijklmnopqrst"), 21, SV("12345"), S("can't happen")); + test(S("abcdefghijklmnopqrst"), 21, SV("1234567890"), S("can't happen")); + test(S("abcdefghijklmnopqrst"), 21, SV("12345678901234567890"), S("can't happen")); + } +#endif + + { // test inserting into self + typedef std::string S; + S s_short = "123/"; + S s_long = "Lorem ipsum dolor sit amet, consectetur/"; + + s_short.insert(0, s_short.c_str()); + assert(s_short == "123/123/"); + s_short.insert(0, s_short.c_str()); + assert(s_short == "123/123/123/123/"); + s_short.insert(0, s_short.c_str()); + assert(s_short == "123/123/123/123/123/123/123/123/"); + + s_long.insert(0, s_long.c_str()); + assert(s_long == "Lorem ipsum dolor sit amet, consectetur/Lorem ipsum dolor sit amet, consectetur/"); + } +} diff --git a/tests/external/libcxx/basic_string/string.modifiers/string_op_plus_equal/char.pass.cpp b/tests/external/libcxx/basic_string/string.modifiers/string_op_plus_equal/char.pass.cpp new file mode 100644 index 0000000..f39ed03 --- /dev/null +++ b/tests/external/libcxx/basic_string/string.modifiers/string_op_plus_equal/char.pass.cpp @@ -0,0 +1,47 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// + +// basic_string& operator+=(charT c); + +#include +#include + +#include "test_macros.h" +#include "min_allocator.h" + +template +void +test(S s, typename S::value_type str, S expected) +{ + s += str; + LIBCPP_ASSERT(s.__invariants()); + assert(s == expected); +} + +int main() +{ + { + typedef std::string S; + test(S(), 'a', S("a")); + test(S("12345"), 'a', S("12345a")); + test(S("1234567890"), 'a', S("1234567890a")); + test(S("12345678901234567890"), 'a', S("12345678901234567890a")); + } +#if TEST_STD_VER >= 11 + { + typedef std::basic_string, min_allocator> S; + test(S(), 'a', S("a")); + test(S("12345"), 'a', S("12345a")); + test(S("1234567890"), 'a', S("1234567890a")); + test(S("12345678901234567890"), 'a', S("12345678901234567890a")); + } +#endif +} diff --git a/tests/external/libcxx/basic_string/string.modifiers/string_op_plus_equal/initializer_list.pass.cpp b/tests/external/libcxx/basic_string/string.modifiers/string_op_plus_equal/initializer_list.pass.cpp new file mode 100644 index 0000000..5b32af9 --- /dev/null +++ b/tests/external/libcxx/basic_string/string.modifiers/string_op_plus_equal/initializer_list.pass.cpp @@ -0,0 +1,34 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// UNSUPPORTED: c++98, c++03 + +// + +// basic_string& operator+=(initializer_list il); + +#include +#include + +#include "min_allocator.h" + +int main() +{ + { + std::string s("123"); + s += {'a', 'b', 'c'}; + assert(s == "123abc"); + } + { + typedef std::basic_string, min_allocator> S; + S s("123"); + s += {'a', 'b', 'c'}; + assert(s == "123abc"); + } +} diff --git a/tests/external/libcxx/basic_string/string.modifiers/string_op_plus_equal/pointer.pass.cpp b/tests/external/libcxx/basic_string/string.modifiers/string_op_plus_equal/pointer.pass.cpp new file mode 100644 index 0000000..c19fd29 --- /dev/null +++ b/tests/external/libcxx/basic_string/string.modifiers/string_op_plus_equal/pointer.pass.cpp @@ -0,0 +1,79 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// + +// basic_string& operator+=(const charT* s); + +#include +#include + +#include "test_macros.h" +#include "min_allocator.h" + +template +void +test(S s, const typename S::value_type* str, S expected) +{ + s += str; + LIBCPP_ASSERT(s.__invariants()); + assert(s == expected); +} + +int main() +{ + { + typedef std::string S; + test(S(), "", S()); + test(S(), "12345", S("12345")); + test(S(), "1234567890", S("1234567890")); + test(S(), "12345678901234567890", S("12345678901234567890")); + + test(S("12345"), "", S("12345")); + test(S("12345"), "12345", S("1234512345")); + test(S("12345"), "1234567890", S("123451234567890")); + test(S("12345"), "12345678901234567890", S("1234512345678901234567890")); + + test(S("1234567890"), "", S("1234567890")); + test(S("1234567890"), "12345", S("123456789012345")); + test(S("1234567890"), "1234567890", S("12345678901234567890")); + test(S("1234567890"), "12345678901234567890", S("123456789012345678901234567890")); + + test(S("12345678901234567890"), "", S("12345678901234567890")); + test(S("12345678901234567890"), "12345", S("1234567890123456789012345")); + test(S("12345678901234567890"), "1234567890", S("123456789012345678901234567890")); + test(S("12345678901234567890"), "12345678901234567890", + S("1234567890123456789012345678901234567890")); + } +#if TEST_STD_VER >= 11 + { + typedef std::basic_string, min_allocator> S; + test(S(), "", S()); + test(S(), "12345", S("12345")); + test(S(), "1234567890", S("1234567890")); + test(S(), "12345678901234567890", S("12345678901234567890")); + + test(S("12345"), "", S("12345")); + test(S("12345"), "12345", S("1234512345")); + test(S("12345"), "1234567890", S("123451234567890")); + test(S("12345"), "12345678901234567890", S("1234512345678901234567890")); + + test(S("1234567890"), "", S("1234567890")); + test(S("1234567890"), "12345", S("123456789012345")); + test(S("1234567890"), "1234567890", S("12345678901234567890")); + test(S("1234567890"), "12345678901234567890", S("123456789012345678901234567890")); + + test(S("12345678901234567890"), "", S("12345678901234567890")); + test(S("12345678901234567890"), "12345", S("1234567890123456789012345")); + test(S("12345678901234567890"), "1234567890", S("123456789012345678901234567890")); + test(S("12345678901234567890"), "12345678901234567890", + S("1234567890123456789012345678901234567890")); + } +#endif +} diff --git a/tests/external/libcxx/basic_string/string.modifiers/string_op_plus_equal/string.pass.cpp b/tests/external/libcxx/basic_string/string.modifiers/string_op_plus_equal/string.pass.cpp new file mode 100644 index 0000000..bbe3850 --- /dev/null +++ b/tests/external/libcxx/basic_string/string.modifiers/string_op_plus_equal/string.pass.cpp @@ -0,0 +1,89 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// + +// basic_string& +// operator+=(const basic_string& str); + +#include +#include + +#include "test_macros.h" +#include "min_allocator.h" + +template +void +test(S s, S str, S expected) +{ + s += str; + LIBCPP_ASSERT(s.__invariants()); + assert(s == expected); +} + +int main() +{ + { + typedef std::string S; + test(S(), S(), S()); + test(S(), S("12345"), S("12345")); + test(S(), S("1234567890"), S("1234567890")); + test(S(), S("12345678901234567890"), S("12345678901234567890")); + + test(S("12345"), S(), S("12345")); + test(S("12345"), S("12345"), S("1234512345")); + test(S("12345"), S("1234567890"), S("123451234567890")); + test(S("12345"), S("12345678901234567890"), S("1234512345678901234567890")); + + test(S("1234567890"), S(), S("1234567890")); + test(S("1234567890"), S("12345"), S("123456789012345")); + test(S("1234567890"), S("1234567890"), S("12345678901234567890")); + test(S("1234567890"), S("12345678901234567890"), S("123456789012345678901234567890")); + + test(S("12345678901234567890"), S(), S("12345678901234567890")); + test(S("12345678901234567890"), S("12345"), S("1234567890123456789012345")); + test(S("12345678901234567890"), S("1234567890"), S("123456789012345678901234567890")); + test(S("12345678901234567890"), S("12345678901234567890"), + S("1234567890123456789012345678901234567890")); + } +#if TEST_STD_VER >= 11 + { + typedef std::basic_string, min_allocator> S; + test(S(), S(), S()); + test(S(), S("12345"), S("12345")); + test(S(), S("1234567890"), S("1234567890")); + test(S(), S("12345678901234567890"), S("12345678901234567890")); + + test(S("12345"), S(), S("12345")); + test(S("12345"), S("12345"), S("1234512345")); + test(S("12345"), S("1234567890"), S("123451234567890")); + test(S("12345"), S("12345678901234567890"), S("1234512345678901234567890")); + + test(S("1234567890"), S(), S("1234567890")); + test(S("1234567890"), S("12345"), S("123456789012345")); + test(S("1234567890"), S("1234567890"), S("12345678901234567890")); + test(S("1234567890"), S("12345678901234567890"), S("123456789012345678901234567890")); + + test(S("12345678901234567890"), S(), S("12345678901234567890")); + test(S("12345678901234567890"), S("12345"), S("1234567890123456789012345")); + test(S("12345678901234567890"), S("1234567890"), S("123456789012345678901234567890")); + test(S("12345678901234567890"), S("12345678901234567890"), + S("1234567890123456789012345678901234567890")); + } +#endif + +#if TEST_STD_VER > 3 + { // LWG 2946 + std::string s; + s += {"abc", 1}; + assert(s.size() == 1); + assert(s == "a"); + } +#endif +} diff --git a/tests/external/libcxx/basic_string/string.modifiers/string_replace/iter_iter_initializer_list.pass.cpp b/tests/external/libcxx/basic_string/string.modifiers/string_replace/iter_iter_initializer_list.pass.cpp new file mode 100644 index 0000000..2a705eb --- /dev/null +++ b/tests/external/libcxx/basic_string/string.modifiers/string_replace/iter_iter_initializer_list.pass.cpp @@ -0,0 +1,34 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// UNSUPPORTED: c++98, c++03 + +// + +// basic_string& replace(const_iterator i1, const_iterator i2, initializer_list il); + +#include +#include + +#include "min_allocator.h" + +int main() +{ + { + std::string s("123def456"); + s.replace(s.cbegin() + 3, s.cbegin() + 6, {'a', 'b', 'c'}); + assert(s == "123abc456"); + } + { + typedef std::basic_string, min_allocator> S; + S s("123def456"); + s.replace(s.cbegin() + 3, s.cbegin() + 6, {'a', 'b', 'c'}); + assert(s == "123abc456"); + } +} diff --git a/tests/external/libcxx/basic_string/string.modifiers/string_replace/iter_iter_iter_iter.pass.cpp b/tests/external/libcxx/basic_string/string.modifiers/string_replace/iter_iter_iter_iter.pass.cpp new file mode 100644 index 0000000..f8126bc --- /dev/null +++ b/tests/external/libcxx/basic_string/string.modifiers/string_replace/iter_iter_iter_iter.pass.cpp @@ -0,0 +1,1040 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// + +// template +// basic_string& +// replace(const_iterator i1, const_iterator i2, InputIterator j1, InputIterator j2); + +#include +#include +#include + +#include "min_allocator.h" +#include "test_iterators.h" + +template +void +test(S s, typename S::size_type pos1, typename S::size_type n1, It f, It l, S expected) +{ + typename S::size_type old_size = s.size(); + typename S::const_iterator first = s.begin() + pos1; + typename S::const_iterator last = s.begin() + pos1 + n1; + typename S::size_type xlen = last - first; + s.replace(first, last, f, l); + LIBCPP_ASSERT(s.__invariants()); + assert(s == expected); + typename S::size_type rlen = std::distance(f, l); + assert(s.size() == old_size - xlen + rlen); +} + +#ifndef TEST_HAS_NO_EXCEPTIONS +template +void +test_exceptions(S s, typename S::size_type pos1, typename S::size_type n1, It f, It l) +{ + typename S::const_iterator first = s.begin() + pos1; + typename S::const_iterator last = s.begin() + pos1 + n1; + S aCopy = s; + try { + s.replace(first, last, f, l); + assert(false); + } + catch (...) {} + LIBCPP_ASSERT(s.__invariants()); + assert(s == aCopy); +} +#endif + +const char* str = "12345678901234567890"; + +template +void test0() +{ + test(S(""), 0, 0, str, str+0, S("")); + test(S(""), 0, 0, str, str+0, S("")); + test(S(""), 0, 0, str, str+1, S("1")); + test(S(""), 0, 0, str, str+2, S("12")); + test(S(""), 0, 0, str, str+4, S("1234")); + test(S(""), 0, 0, str, str+5, S("12345")); + test(S(""), 0, 0, str, str+0, S("")); + test(S(""), 0, 0, str, str+1, S("1")); + test(S(""), 0, 0, str, str+5, S("12345")); + test(S(""), 0, 0, str, str+9, S("123456789")); + test(S(""), 0, 0, str, str+10, S("1234567890")); + test(S(""), 0, 0, str, str+0, S("")); + test(S(""), 0, 0, str, str+1, S("1")); + test(S(""), 0, 0, str, str+10, S("1234567890")); + test(S(""), 0, 0, str, str+19, S("1234567890123456789")); + test(S(""), 0, 0, str, str+20, S("12345678901234567890")); + test(S("abcde"), 0, 0, str, str+0, S("abcde")); + test(S("abcde"), 0, 0, str, str+0, S("abcde")); + test(S("abcde"), 0, 0, str, str+1, S("1abcde")); + test(S("abcde"), 0, 0, str, str+2, S("12abcde")); + test(S("abcde"), 0, 0, str, str+4, S("1234abcde")); + test(S("abcde"), 0, 0, str, str+5, S("12345abcde")); + test(S("abcde"), 0, 0, str, str+0, S("abcde")); + test(S("abcde"), 0, 0, str, str+1, S("1abcde")); + test(S("abcde"), 0, 0, str, str+5, S("12345abcde")); + test(S("abcde"), 0, 0, str, str+9, S("123456789abcde")); + test(S("abcde"), 0, 0, str, str+10, S("1234567890abcde")); + test(S("abcde"), 0, 0, str, str+0, S("abcde")); + test(S("abcde"), 0, 0, str, str+1, S("1abcde")); + test(S("abcde"), 0, 0, str, str+10, S("1234567890abcde")); + test(S("abcde"), 0, 0, str, str+19, S("1234567890123456789abcde")); + test(S("abcde"), 0, 0, str, str+20, S("12345678901234567890abcde")); + test(S("abcde"), 0, 1, str, str+0, S("bcde")); + test(S("abcde"), 0, 1, str, str+0, S("bcde")); + test(S("abcde"), 0, 1, str, str+1, S("1bcde")); + test(S("abcde"), 0, 1, str, str+2, S("12bcde")); + test(S("abcde"), 0, 1, str, str+4, S("1234bcde")); + test(S("abcde"), 0, 1, str, str+5, S("12345bcde")); + test(S("abcde"), 0, 1, str, str+0, S("bcde")); + test(S("abcde"), 0, 1, str, str+1, S("1bcde")); + test(S("abcde"), 0, 1, str, str+5, S("12345bcde")); + test(S("abcde"), 0, 1, str, str+9, S("123456789bcde")); + test(S("abcde"), 0, 1, str, str+10, S("1234567890bcde")); + test(S("abcde"), 0, 1, str, str+0, S("bcde")); + test(S("abcde"), 0, 1, str, str+1, S("1bcde")); + test(S("abcde"), 0, 1, str, str+10, S("1234567890bcde")); + test(S("abcde"), 0, 1, str, str+19, S("1234567890123456789bcde")); + test(S("abcde"), 0, 1, str, str+20, S("12345678901234567890bcde")); + test(S("abcde"), 0, 2, str, str+0, S("cde")); + test(S("abcde"), 0, 2, str, str+0, S("cde")); + test(S("abcde"), 0, 2, str, str+1, S("1cde")); + test(S("abcde"), 0, 2, str, str+2, S("12cde")); + test(S("abcde"), 0, 2, str, str+4, S("1234cde")); + test(S("abcde"), 0, 2, str, str+5, S("12345cde")); + test(S("abcde"), 0, 2, str, str+0, S("cde")); + test(S("abcde"), 0, 2, str, str+1, S("1cde")); + test(S("abcde"), 0, 2, str, str+5, S("12345cde")); + test(S("abcde"), 0, 2, str, str+9, S("123456789cde")); + test(S("abcde"), 0, 2, str, str+10, S("1234567890cde")); + test(S("abcde"), 0, 2, str, str+0, S("cde")); + test(S("abcde"), 0, 2, str, str+1, S("1cde")); + test(S("abcde"), 0, 2, str, str+10, S("1234567890cde")); + test(S("abcde"), 0, 2, str, str+19, S("1234567890123456789cde")); + test(S("abcde"), 0, 2, str, str+20, S("12345678901234567890cde")); + test(S("abcde"), 0, 4, str, str+0, S("e")); + test(S("abcde"), 0, 4, str, str+0, S("e")); + test(S("abcde"), 0, 4, str, str+1, S("1e")); + test(S("abcde"), 0, 4, str, str+2, S("12e")); + test(S("abcde"), 0, 4, str, str+4, S("1234e")); + test(S("abcde"), 0, 4, str, str+5, S("12345e")); + test(S("abcde"), 0, 4, str, str+0, S("e")); + test(S("abcde"), 0, 4, str, str+1, S("1e")); + test(S("abcde"), 0, 4, str, str+5, S("12345e")); + test(S("abcde"), 0, 4, str, str+9, S("123456789e")); + test(S("abcde"), 0, 4, str, str+10, S("1234567890e")); + test(S("abcde"), 0, 4, str, str+0, S("e")); + test(S("abcde"), 0, 4, str, str+1, S("1e")); + test(S("abcde"), 0, 4, str, str+10, S("1234567890e")); + test(S("abcde"), 0, 4, str, str+19, S("1234567890123456789e")); + test(S("abcde"), 0, 4, str, str+20, S("12345678901234567890e")); + test(S("abcde"), 0, 5, str, str+0, S("")); + test(S("abcde"), 0, 5, str, str+0, S("")); + test(S("abcde"), 0, 5, str, str+1, S("1")); + test(S("abcde"), 0, 5, str, str+2, S("12")); + test(S("abcde"), 0, 5, str, str+4, S("1234")); + test(S("abcde"), 0, 5, str, str+5, S("12345")); + test(S("abcde"), 0, 5, str, str+0, S("")); + test(S("abcde"), 0, 5, str, str+1, S("1")); + test(S("abcde"), 0, 5, str, str+5, S("12345")); + test(S("abcde"), 0, 5, str, str+9, S("123456789")); + test(S("abcde"), 0, 5, str, str+10, S("1234567890")); + test(S("abcde"), 0, 5, str, str+0, S("")); + test(S("abcde"), 0, 5, str, str+1, S("1")); + test(S("abcde"), 0, 5, str, str+10, S("1234567890")); + test(S("abcde"), 0, 5, str, str+19, S("1234567890123456789")); + test(S("abcde"), 0, 5, str, str+20, S("12345678901234567890")); + test(S("abcde"), 1, 0, str, str+0, S("abcde")); + test(S("abcde"), 1, 0, str, str+0, S("abcde")); + test(S("abcde"), 1, 0, str, str+1, S("a1bcde")); + test(S("abcde"), 1, 0, str, str+2, S("a12bcde")); +} + +template +void test1() +{ + test(S("abcde"), 1, 0, str, str+4, S("a1234bcde")); + test(S("abcde"), 1, 0, str, str+5, S("a12345bcde")); + test(S("abcde"), 1, 0, str, str+0, S("abcde")); + test(S("abcde"), 1, 0, str, str+1, S("a1bcde")); + test(S("abcde"), 1, 0, str, str+5, S("a12345bcde")); + test(S("abcde"), 1, 0, str, str+9, S("a123456789bcde")); + test(S("abcde"), 1, 0, str, str+10, S("a1234567890bcde")); + test(S("abcde"), 1, 0, str, str+0, S("abcde")); + test(S("abcde"), 1, 0, str, str+1, S("a1bcde")); + test(S("abcde"), 1, 0, str, str+10, S("a1234567890bcde")); + test(S("abcde"), 1, 0, str, str+19, S("a1234567890123456789bcde")); + test(S("abcde"), 1, 0, str, str+20, S("a12345678901234567890bcde")); + test(S("abcde"), 1, 1, str, str+0, S("acde")); + test(S("abcde"), 1, 1, str, str+0, S("acde")); + test(S("abcde"), 1, 1, str, str+1, S("a1cde")); + test(S("abcde"), 1, 1, str, str+2, S("a12cde")); + test(S("abcde"), 1, 1, str, str+4, S("a1234cde")); + test(S("abcde"), 1, 1, str, str+5, S("a12345cde")); + test(S("abcde"), 1, 1, str, str+0, S("acde")); + test(S("abcde"), 1, 1, str, str+1, S("a1cde")); + test(S("abcde"), 1, 1, str, str+5, S("a12345cde")); + test(S("abcde"), 1, 1, str, str+9, S("a123456789cde")); + test(S("abcde"), 1, 1, str, str+10, S("a1234567890cde")); + test(S("abcde"), 1, 1, str, str+0, S("acde")); + test(S("abcde"), 1, 1, str, str+1, S("a1cde")); + test(S("abcde"), 1, 1, str, str+10, S("a1234567890cde")); + test(S("abcde"), 1, 1, str, str+19, S("a1234567890123456789cde")); + test(S("abcde"), 1, 1, str, str+20, S("a12345678901234567890cde")); + test(S("abcde"), 1, 2, str, str+0, S("ade")); + test(S("abcde"), 1, 2, str, str+0, S("ade")); + test(S("abcde"), 1, 2, str, str+1, S("a1de")); + test(S("abcde"), 1, 2, str, str+2, S("a12de")); + test(S("abcde"), 1, 2, str, str+4, S("a1234de")); + test(S("abcde"), 1, 2, str, str+5, S("a12345de")); + test(S("abcde"), 1, 2, str, str+0, S("ade")); + test(S("abcde"), 1, 2, str, str+1, S("a1de")); + test(S("abcde"), 1, 2, str, str+5, S("a12345de")); + test(S("abcde"), 1, 2, str, str+9, S("a123456789de")); + test(S("abcde"), 1, 2, str, str+10, S("a1234567890de")); + test(S("abcde"), 1, 2, str, str+0, S("ade")); + test(S("abcde"), 1, 2, str, str+1, S("a1de")); + test(S("abcde"), 1, 2, str, str+10, S("a1234567890de")); + test(S("abcde"), 1, 2, str, str+19, S("a1234567890123456789de")); + test(S("abcde"), 1, 2, str, str+20, S("a12345678901234567890de")); + test(S("abcde"), 1, 3, str, str+0, S("ae")); + test(S("abcde"), 1, 3, str, str+0, S("ae")); + test(S("abcde"), 1, 3, str, str+1, S("a1e")); + test(S("abcde"), 1, 3, str, str+2, S("a12e")); + test(S("abcde"), 1, 3, str, str+4, S("a1234e")); + test(S("abcde"), 1, 3, str, str+5, S("a12345e")); + test(S("abcde"), 1, 3, str, str+0, S("ae")); + test(S("abcde"), 1, 3, str, str+1, S("a1e")); + test(S("abcde"), 1, 3, str, str+5, S("a12345e")); + test(S("abcde"), 1, 3, str, str+9, S("a123456789e")); + test(S("abcde"), 1, 3, str, str+10, S("a1234567890e")); + test(S("abcde"), 1, 3, str, str+0, S("ae")); + test(S("abcde"), 1, 3, str, str+1, S("a1e")); + test(S("abcde"), 1, 3, str, str+10, S("a1234567890e")); + test(S("abcde"), 1, 3, str, str+19, S("a1234567890123456789e")); + test(S("abcde"), 1, 3, str, str+20, S("a12345678901234567890e")); + test(S("abcde"), 1, 4, str, str+0, S("a")); + test(S("abcde"), 1, 4, str, str+0, S("a")); + test(S("abcde"), 1, 4, str, str+1, S("a1")); + test(S("abcde"), 1, 4, str, str+2, S("a12")); + test(S("abcde"), 1, 4, str, str+4, S("a1234")); + test(S("abcde"), 1, 4, str, str+5, S("a12345")); + test(S("abcde"), 1, 4, str, str+0, S("a")); + test(S("abcde"), 1, 4, str, str+1, S("a1")); + test(S("abcde"), 1, 4, str, str+5, S("a12345")); + test(S("abcde"), 1, 4, str, str+9, S("a123456789")); + test(S("abcde"), 1, 4, str, str+10, S("a1234567890")); + test(S("abcde"), 1, 4, str, str+0, S("a")); + test(S("abcde"), 1, 4, str, str+1, S("a1")); + test(S("abcde"), 1, 4, str, str+10, S("a1234567890")); + test(S("abcde"), 1, 4, str, str+19, S("a1234567890123456789")); + test(S("abcde"), 1, 4, str, str+20, S("a12345678901234567890")); + test(S("abcde"), 2, 0, str, str+0, S("abcde")); + test(S("abcde"), 2, 0, str, str+0, S("abcde")); + test(S("abcde"), 2, 0, str, str+1, S("ab1cde")); + test(S("abcde"), 2, 0, str, str+2, S("ab12cde")); + test(S("abcde"), 2, 0, str, str+4, S("ab1234cde")); + test(S("abcde"), 2, 0, str, str+5, S("ab12345cde")); + test(S("abcde"), 2, 0, str, str+0, S("abcde")); + test(S("abcde"), 2, 0, str, str+1, S("ab1cde")); + test(S("abcde"), 2, 0, str, str+5, S("ab12345cde")); + test(S("abcde"), 2, 0, str, str+9, S("ab123456789cde")); + test(S("abcde"), 2, 0, str, str+10, S("ab1234567890cde")); + test(S("abcde"), 2, 0, str, str+0, S("abcde")); + test(S("abcde"), 2, 0, str, str+1, S("ab1cde")); + test(S("abcde"), 2, 0, str, str+10, S("ab1234567890cde")); + test(S("abcde"), 2, 0, str, str+19, S("ab1234567890123456789cde")); + test(S("abcde"), 2, 0, str, str+20, S("ab12345678901234567890cde")); + test(S("abcde"), 2, 1, str, str+0, S("abde")); + test(S("abcde"), 2, 1, str, str+0, S("abde")); + test(S("abcde"), 2, 1, str, str+1, S("ab1de")); + test(S("abcde"), 2, 1, str, str+2, S("ab12de")); + test(S("abcde"), 2, 1, str, str+4, S("ab1234de")); + test(S("abcde"), 2, 1, str, str+5, S("ab12345de")); + test(S("abcde"), 2, 1, str, str+0, S("abde")); + test(S("abcde"), 2, 1, str, str+1, S("ab1de")); +} + +template +void test2() +{ + test(S("abcde"), 2, 1, str, str+5, S("ab12345de")); + test(S("abcde"), 2, 1, str, str+9, S("ab123456789de")); + test(S("abcde"), 2, 1, str, str+10, S("ab1234567890de")); + test(S("abcde"), 2, 1, str, str+0, S("abde")); + test(S("abcde"), 2, 1, str, str+1, S("ab1de")); + test(S("abcde"), 2, 1, str, str+10, S("ab1234567890de")); + test(S("abcde"), 2, 1, str, str+19, S("ab1234567890123456789de")); + test(S("abcde"), 2, 1, str, str+20, S("ab12345678901234567890de")); + test(S("abcde"), 2, 2, str, str+0, S("abe")); + test(S("abcde"), 2, 2, str, str+0, S("abe")); + test(S("abcde"), 2, 2, str, str+1, S("ab1e")); + test(S("abcde"), 2, 2, str, str+2, S("ab12e")); + test(S("abcde"), 2, 2, str, str+4, S("ab1234e")); + test(S("abcde"), 2, 2, str, str+5, S("ab12345e")); + test(S("abcde"), 2, 2, str, str+0, S("abe")); + test(S("abcde"), 2, 2, str, str+1, S("ab1e")); + test(S("abcde"), 2, 2, str, str+5, S("ab12345e")); + test(S("abcde"), 2, 2, str, str+9, S("ab123456789e")); + test(S("abcde"), 2, 2, str, str+10, S("ab1234567890e")); + test(S("abcde"), 2, 2, str, str+0, S("abe")); + test(S("abcde"), 2, 2, str, str+1, S("ab1e")); + test(S("abcde"), 2, 2, str, str+10, S("ab1234567890e")); + test(S("abcde"), 2, 2, str, str+19, S("ab1234567890123456789e")); + test(S("abcde"), 2, 2, str, str+20, S("ab12345678901234567890e")); + test(S("abcde"), 2, 3, str, str+0, S("ab")); + test(S("abcde"), 2, 3, str, str+0, S("ab")); + test(S("abcde"), 2, 3, str, str+1, S("ab1")); + test(S("abcde"), 2, 3, str, str+2, S("ab12")); + test(S("abcde"), 2, 3, str, str+4, S("ab1234")); + test(S("abcde"), 2, 3, str, str+5, S("ab12345")); + test(S("abcde"), 2, 3, str, str+0, S("ab")); + test(S("abcde"), 2, 3, str, str+1, S("ab1")); + test(S("abcde"), 2, 3, str, str+5, S("ab12345")); + test(S("abcde"), 2, 3, str, str+9, S("ab123456789")); + test(S("abcde"), 2, 3, str, str+10, S("ab1234567890")); + test(S("abcde"), 2, 3, str, str+0, S("ab")); + test(S("abcde"), 2, 3, str, str+1, S("ab1")); + test(S("abcde"), 2, 3, str, str+10, S("ab1234567890")); + test(S("abcde"), 2, 3, str, str+19, S("ab1234567890123456789")); + test(S("abcde"), 2, 3, str, str+20, S("ab12345678901234567890")); + test(S("abcde"), 4, 0, str, str+0, S("abcde")); + test(S("abcde"), 4, 0, str, str+0, S("abcde")); + test(S("abcde"), 4, 0, str, str+1, S("abcd1e")); + test(S("abcde"), 4, 0, str, str+2, S("abcd12e")); + test(S("abcde"), 4, 0, str, str+4, S("abcd1234e")); + test(S("abcde"), 4, 0, str, str+5, S("abcd12345e")); + test(S("abcde"), 4, 0, str, str+0, S("abcde")); + test(S("abcde"), 4, 0, str, str+1, S("abcd1e")); + test(S("abcde"), 4, 0, str, str+5, S("abcd12345e")); + test(S("abcde"), 4, 0, str, str+9, S("abcd123456789e")); + test(S("abcde"), 4, 0, str, str+10, S("abcd1234567890e")); + test(S("abcde"), 4, 0, str, str+0, S("abcde")); + test(S("abcde"), 4, 0, str, str+1, S("abcd1e")); + test(S("abcde"), 4, 0, str, str+10, S("abcd1234567890e")); + test(S("abcde"), 4, 0, str, str+19, S("abcd1234567890123456789e")); + test(S("abcde"), 4, 0, str, str+20, S("abcd12345678901234567890e")); + test(S("abcde"), 4, 1, str, str+0, S("abcd")); + test(S("abcde"), 4, 1, str, str+0, S("abcd")); + test(S("abcde"), 4, 1, str, str+1, S("abcd1")); + test(S("abcde"), 4, 1, str, str+2, S("abcd12")); + test(S("abcde"), 4, 1, str, str+4, S("abcd1234")); + test(S("abcde"), 4, 1, str, str+5, S("abcd12345")); + test(S("abcde"), 4, 1, str, str+0, S("abcd")); + test(S("abcde"), 4, 1, str, str+1, S("abcd1")); + test(S("abcde"), 4, 1, str, str+5, S("abcd12345")); + test(S("abcde"), 4, 1, str, str+9, S("abcd123456789")); + test(S("abcde"), 4, 1, str, str+10, S("abcd1234567890")); + test(S("abcde"), 4, 1, str, str+0, S("abcd")); + test(S("abcde"), 4, 1, str, str+1, S("abcd1")); + test(S("abcde"), 4, 1, str, str+10, S("abcd1234567890")); + test(S("abcde"), 4, 1, str, str+19, S("abcd1234567890123456789")); + test(S("abcde"), 4, 1, str, str+20, S("abcd12345678901234567890")); + test(S("abcde"), 5, 0, str, str+0, S("abcde")); + test(S("abcde"), 5, 0, str, str+0, S("abcde")); + test(S("abcde"), 5, 0, str, str+1, S("abcde1")); + test(S("abcde"), 5, 0, str, str+2, S("abcde12")); + test(S("abcde"), 5, 0, str, str+4, S("abcde1234")); + test(S("abcde"), 5, 0, str, str+5, S("abcde12345")); + test(S("abcde"), 5, 0, str, str+0, S("abcde")); + test(S("abcde"), 5, 0, str, str+1, S("abcde1")); + test(S("abcde"), 5, 0, str, str+5, S("abcde12345")); + test(S("abcde"), 5, 0, str, str+9, S("abcde123456789")); + test(S("abcde"), 5, 0, str, str+10, S("abcde1234567890")); + test(S("abcde"), 5, 0, str, str+0, S("abcde")); + test(S("abcde"), 5, 0, str, str+1, S("abcde1")); + test(S("abcde"), 5, 0, str, str+10, S("abcde1234567890")); + test(S("abcde"), 5, 0, str, str+19, S("abcde1234567890123456789")); + test(S("abcde"), 5, 0, str, str+20, S("abcde12345678901234567890")); + test(S("abcdefghij"), 0, 0, str, str+0, S("abcdefghij")); + test(S("abcdefghij"), 0, 0, str, str+0, S("abcdefghij")); + test(S("abcdefghij"), 0, 0, str, str+1, S("1abcdefghij")); + test(S("abcdefghij"), 0, 0, str, str+2, S("12abcdefghij")); + test(S("abcdefghij"), 0, 0, str, str+4, S("1234abcdefghij")); + test(S("abcdefghij"), 0, 0, str, str+5, S("12345abcdefghij")); + test(S("abcdefghij"), 0, 0, str, str+0, S("abcdefghij")); + test(S("abcdefghij"), 0, 0, str, str+1, S("1abcdefghij")); + test(S("abcdefghij"), 0, 0, str, str+5, S("12345abcdefghij")); + test(S("abcdefghij"), 0, 0, str, str+9, S("123456789abcdefghij")); + test(S("abcdefghij"), 0, 0, str, str+10, S("1234567890abcdefghij")); + test(S("abcdefghij"), 0, 0, str, str+0, S("abcdefghij")); +} + +template +void test3() +{ + test(S("abcdefghij"), 0, 0, str, str+1, S("1abcdefghij")); + test(S("abcdefghij"), 0, 0, str, str+10, S("1234567890abcdefghij")); + test(S("abcdefghij"), 0, 0, str, str+19, S("1234567890123456789abcdefghij")); + test(S("abcdefghij"), 0, 0, str, str+20, S("12345678901234567890abcdefghij")); + test(S("abcdefghij"), 0, 1, str, str+0, S("bcdefghij")); + test(S("abcdefghij"), 0, 1, str, str+0, S("bcdefghij")); + test(S("abcdefghij"), 0, 1, str, str+1, S("1bcdefghij")); + test(S("abcdefghij"), 0, 1, str, str+2, S("12bcdefghij")); + test(S("abcdefghij"), 0, 1, str, str+4, S("1234bcdefghij")); + test(S("abcdefghij"), 0, 1, str, str+5, S("12345bcdefghij")); + test(S("abcdefghij"), 0, 1, str, str+0, S("bcdefghij")); + test(S("abcdefghij"), 0, 1, str, str+1, S("1bcdefghij")); + test(S("abcdefghij"), 0, 1, str, str+5, S("12345bcdefghij")); + test(S("abcdefghij"), 0, 1, str, str+9, S("123456789bcdefghij")); + test(S("abcdefghij"), 0, 1, str, str+10, S("1234567890bcdefghij")); + test(S("abcdefghij"), 0, 1, str, str+0, S("bcdefghij")); + test(S("abcdefghij"), 0, 1, str, str+1, S("1bcdefghij")); + test(S("abcdefghij"), 0, 1, str, str+10, S("1234567890bcdefghij")); + test(S("abcdefghij"), 0, 1, str, str+19, S("1234567890123456789bcdefghij")); + test(S("abcdefghij"), 0, 1, str, str+20, S("12345678901234567890bcdefghij")); + test(S("abcdefghij"), 0, 5, str, str+0, S("fghij")); + test(S("abcdefghij"), 0, 5, str, str+0, S("fghij")); + test(S("abcdefghij"), 0, 5, str, str+1, S("1fghij")); + test(S("abcdefghij"), 0, 5, str, str+2, S("12fghij")); + test(S("abcdefghij"), 0, 5, str, str+4, S("1234fghij")); + test(S("abcdefghij"), 0, 5, str, str+5, S("12345fghij")); + test(S("abcdefghij"), 0, 5, str, str+0, S("fghij")); + test(S("abcdefghij"), 0, 5, str, str+1, S("1fghij")); + test(S("abcdefghij"), 0, 5, str, str+5, S("12345fghij")); + test(S("abcdefghij"), 0, 5, str, str+9, S("123456789fghij")); + test(S("abcdefghij"), 0, 5, str, str+10, S("1234567890fghij")); + test(S("abcdefghij"), 0, 5, str, str+0, S("fghij")); + test(S("abcdefghij"), 0, 5, str, str+1, S("1fghij")); + test(S("abcdefghij"), 0, 5, str, str+10, S("1234567890fghij")); + test(S("abcdefghij"), 0, 5, str, str+19, S("1234567890123456789fghij")); + test(S("abcdefghij"), 0, 5, str, str+20, S("12345678901234567890fghij")); + test(S("abcdefghij"), 0, 9, str, str+0, S("j")); + test(S("abcdefghij"), 0, 9, str, str+0, S("j")); + test(S("abcdefghij"), 0, 9, str, str+1, S("1j")); + test(S("abcdefghij"), 0, 9, str, str+2, S("12j")); + test(S("abcdefghij"), 0, 9, str, str+4, S("1234j")); + test(S("abcdefghij"), 0, 9, str, str+5, S("12345j")); + test(S("abcdefghij"), 0, 9, str, str+0, S("j")); + test(S("abcdefghij"), 0, 9, str, str+1, S("1j")); + test(S("abcdefghij"), 0, 9, str, str+5, S("12345j")); + test(S("abcdefghij"), 0, 9, str, str+9, S("123456789j")); + test(S("abcdefghij"), 0, 9, str, str+10, S("1234567890j")); + test(S("abcdefghij"), 0, 9, str, str+0, S("j")); + test(S("abcdefghij"), 0, 9, str, str+1, S("1j")); + test(S("abcdefghij"), 0, 9, str, str+10, S("1234567890j")); + test(S("abcdefghij"), 0, 9, str, str+19, S("1234567890123456789j")); + test(S("abcdefghij"), 0, 9, str, str+20, S("12345678901234567890j")); + test(S("abcdefghij"), 0, 10, str, str+0, S("")); + test(S("abcdefghij"), 0, 10, str, str+0, S("")); + test(S("abcdefghij"), 0, 10, str, str+1, S("1")); + test(S("abcdefghij"), 0, 10, str, str+2, S("12")); + test(S("abcdefghij"), 0, 10, str, str+4, S("1234")); + test(S("abcdefghij"), 0, 10, str, str+5, S("12345")); + test(S("abcdefghij"), 0, 10, str, str+0, S("")); + test(S("abcdefghij"), 0, 10, str, str+1, S("1")); + test(S("abcdefghij"), 0, 10, str, str+5, S("12345")); + test(S("abcdefghij"), 0, 10, str, str+9, S("123456789")); + test(S("abcdefghij"), 0, 10, str, str+10, S("1234567890")); + test(S("abcdefghij"), 0, 10, str, str+0, S("")); + test(S("abcdefghij"), 0, 10, str, str+1, S("1")); + test(S("abcdefghij"), 0, 10, str, str+10, S("1234567890")); + test(S("abcdefghij"), 0, 10, str, str+19, S("1234567890123456789")); + test(S("abcdefghij"), 0, 10, str, str+20, S("12345678901234567890")); + test(S("abcdefghij"), 1, 0, str, str+0, S("abcdefghij")); + test(S("abcdefghij"), 1, 0, str, str+0, S("abcdefghij")); + test(S("abcdefghij"), 1, 0, str, str+1, S("a1bcdefghij")); + test(S("abcdefghij"), 1, 0, str, str+2, S("a12bcdefghij")); + test(S("abcdefghij"), 1, 0, str, str+4, S("a1234bcdefghij")); + test(S("abcdefghij"), 1, 0, str, str+5, S("a12345bcdefghij")); + test(S("abcdefghij"), 1, 0, str, str+0, S("abcdefghij")); + test(S("abcdefghij"), 1, 0, str, str+1, S("a1bcdefghij")); + test(S("abcdefghij"), 1, 0, str, str+5, S("a12345bcdefghij")); + test(S("abcdefghij"), 1, 0, str, str+9, S("a123456789bcdefghij")); + test(S("abcdefghij"), 1, 0, str, str+10, S("a1234567890bcdefghij")); + test(S("abcdefghij"), 1, 0, str, str+0, S("abcdefghij")); + test(S("abcdefghij"), 1, 0, str, str+1, S("a1bcdefghij")); + test(S("abcdefghij"), 1, 0, str, str+10, S("a1234567890bcdefghij")); + test(S("abcdefghij"), 1, 0, str, str+19, S("a1234567890123456789bcdefghij")); + test(S("abcdefghij"), 1, 0, str, str+20, S("a12345678901234567890bcdefghij")); + test(S("abcdefghij"), 1, 1, str, str+0, S("acdefghij")); + test(S("abcdefghij"), 1, 1, str, str+0, S("acdefghij")); + test(S("abcdefghij"), 1, 1, str, str+1, S("a1cdefghij")); + test(S("abcdefghij"), 1, 1, str, str+2, S("a12cdefghij")); + test(S("abcdefghij"), 1, 1, str, str+4, S("a1234cdefghij")); + test(S("abcdefghij"), 1, 1, str, str+5, S("a12345cdefghij")); + test(S("abcdefghij"), 1, 1, str, str+0, S("acdefghij")); + test(S("abcdefghij"), 1, 1, str, str+1, S("a1cdefghij")); + test(S("abcdefghij"), 1, 1, str, str+5, S("a12345cdefghij")); + test(S("abcdefghij"), 1, 1, str, str+9, S("a123456789cdefghij")); + test(S("abcdefghij"), 1, 1, str, str+10, S("a1234567890cdefghij")); + test(S("abcdefghij"), 1, 1, str, str+0, S("acdefghij")); + test(S("abcdefghij"), 1, 1, str, str+1, S("a1cdefghij")); + test(S("abcdefghij"), 1, 1, str, str+10, S("a1234567890cdefghij")); + test(S("abcdefghij"), 1, 1, str, str+19, S("a1234567890123456789cdefghij")); + test(S("abcdefghij"), 1, 1, str, str+20, S("a12345678901234567890cdefghij")); +} + +template +void test4() +{ + test(S("abcdefghij"), 1, 4, str, str+0, S("afghij")); + test(S("abcdefghij"), 1, 4, str, str+0, S("afghij")); + test(S("abcdefghij"), 1, 4, str, str+1, S("a1fghij")); + test(S("abcdefghij"), 1, 4, str, str+2, S("a12fghij")); + test(S("abcdefghij"), 1, 4, str, str+4, S("a1234fghij")); + test(S("abcdefghij"), 1, 4, str, str+5, S("a12345fghij")); + test(S("abcdefghij"), 1, 4, str, str+0, S("afghij")); + test(S("abcdefghij"), 1, 4, str, str+1, S("a1fghij")); + test(S("abcdefghij"), 1, 4, str, str+5, S("a12345fghij")); + test(S("abcdefghij"), 1, 4, str, str+9, S("a123456789fghij")); + test(S("abcdefghij"), 1, 4, str, str+10, S("a1234567890fghij")); + test(S("abcdefghij"), 1, 4, str, str+0, S("afghij")); + test(S("abcdefghij"), 1, 4, str, str+1, S("a1fghij")); + test(S("abcdefghij"), 1, 4, str, str+10, S("a1234567890fghij")); + test(S("abcdefghij"), 1, 4, str, str+19, S("a1234567890123456789fghij")); + test(S("abcdefghij"), 1, 4, str, str+20, S("a12345678901234567890fghij")); + test(S("abcdefghij"), 1, 8, str, str+0, S("aj")); + test(S("abcdefghij"), 1, 8, str, str+0, S("aj")); + test(S("abcdefghij"), 1, 8, str, str+1, S("a1j")); + test(S("abcdefghij"), 1, 8, str, str+2, S("a12j")); + test(S("abcdefghij"), 1, 8, str, str+4, S("a1234j")); + test(S("abcdefghij"), 1, 8, str, str+5, S("a12345j")); + test(S("abcdefghij"), 1, 8, str, str+0, S("aj")); + test(S("abcdefghij"), 1, 8, str, str+1, S("a1j")); + test(S("abcdefghij"), 1, 8, str, str+5, S("a12345j")); + test(S("abcdefghij"), 1, 8, str, str+9, S("a123456789j")); + test(S("abcdefghij"), 1, 8, str, str+10, S("a1234567890j")); + test(S("abcdefghij"), 1, 8, str, str+0, S("aj")); + test(S("abcdefghij"), 1, 8, str, str+1, S("a1j")); + test(S("abcdefghij"), 1, 8, str, str+10, S("a1234567890j")); + test(S("abcdefghij"), 1, 8, str, str+19, S("a1234567890123456789j")); + test(S("abcdefghij"), 1, 8, str, str+20, S("a12345678901234567890j")); + test(S("abcdefghij"), 1, 9, str, str+0, S("a")); + test(S("abcdefghij"), 1, 9, str, str+0, S("a")); + test(S("abcdefghij"), 1, 9, str, str+1, S("a1")); + test(S("abcdefghij"), 1, 9, str, str+2, S("a12")); + test(S("abcdefghij"), 1, 9, str, str+4, S("a1234")); + test(S("abcdefghij"), 1, 9, str, str+5, S("a12345")); + test(S("abcdefghij"), 1, 9, str, str+0, S("a")); + test(S("abcdefghij"), 1, 9, str, str+1, S("a1")); + test(S("abcdefghij"), 1, 9, str, str+5, S("a12345")); + test(S("abcdefghij"), 1, 9, str, str+9, S("a123456789")); + test(S("abcdefghij"), 1, 9, str, str+10, S("a1234567890")); + test(S("abcdefghij"), 1, 9, str, str+0, S("a")); + test(S("abcdefghij"), 1, 9, str, str+1, S("a1")); + test(S("abcdefghij"), 1, 9, str, str+10, S("a1234567890")); + test(S("abcdefghij"), 1, 9, str, str+19, S("a1234567890123456789")); + test(S("abcdefghij"), 1, 9, str, str+20, S("a12345678901234567890")); + test(S("abcdefghij"), 5, 0, str, str+0, S("abcdefghij")); + test(S("abcdefghij"), 5, 0, str, str+0, S("abcdefghij")); + test(S("abcdefghij"), 5, 0, str, str+1, S("abcde1fghij")); + test(S("abcdefghij"), 5, 0, str, str+2, S("abcde12fghij")); + test(S("abcdefghij"), 5, 0, str, str+4, S("abcde1234fghij")); + test(S("abcdefghij"), 5, 0, str, str+5, S("abcde12345fghij")); + test(S("abcdefghij"), 5, 0, str, str+0, S("abcdefghij")); + test(S("abcdefghij"), 5, 0, str, str+1, S("abcde1fghij")); + test(S("abcdefghij"), 5, 0, str, str+5, S("abcde12345fghij")); + test(S("abcdefghij"), 5, 0, str, str+9, S("abcde123456789fghij")); + test(S("abcdefghij"), 5, 0, str, str+10, S("abcde1234567890fghij")); + test(S("abcdefghij"), 5, 0, str, str+0, S("abcdefghij")); + test(S("abcdefghij"), 5, 0, str, str+1, S("abcde1fghij")); + test(S("abcdefghij"), 5, 0, str, str+10, S("abcde1234567890fghij")); + test(S("abcdefghij"), 5, 0, str, str+19, S("abcde1234567890123456789fghij")); + test(S("abcdefghij"), 5, 0, str, str+20, S("abcde12345678901234567890fghij")); + test(S("abcdefghij"), 5, 1, str, str+0, S("abcdeghij")); + test(S("abcdefghij"), 5, 1, str, str+0, S("abcdeghij")); + test(S("abcdefghij"), 5, 1, str, str+1, S("abcde1ghij")); + test(S("abcdefghij"), 5, 1, str, str+2, S("abcde12ghij")); + test(S("abcdefghij"), 5, 1, str, str+4, S("abcde1234ghij")); + test(S("abcdefghij"), 5, 1, str, str+5, S("abcde12345ghij")); + test(S("abcdefghij"), 5, 1, str, str+0, S("abcdeghij")); + test(S("abcdefghij"), 5, 1, str, str+1, S("abcde1ghij")); + test(S("abcdefghij"), 5, 1, str, str+5, S("abcde12345ghij")); + test(S("abcdefghij"), 5, 1, str, str+9, S("abcde123456789ghij")); + test(S("abcdefghij"), 5, 1, str, str+10, S("abcde1234567890ghij")); + test(S("abcdefghij"), 5, 1, str, str+0, S("abcdeghij")); + test(S("abcdefghij"), 5, 1, str, str+1, S("abcde1ghij")); + test(S("abcdefghij"), 5, 1, str, str+10, S("abcde1234567890ghij")); + test(S("abcdefghij"), 5, 1, str, str+19, S("abcde1234567890123456789ghij")); + test(S("abcdefghij"), 5, 1, str, str+20, S("abcde12345678901234567890ghij")); + test(S("abcdefghij"), 5, 2, str, str+0, S("abcdehij")); + test(S("abcdefghij"), 5, 2, str, str+0, S("abcdehij")); + test(S("abcdefghij"), 5, 2, str, str+1, S("abcde1hij")); + test(S("abcdefghij"), 5, 2, str, str+2, S("abcde12hij")); + test(S("abcdefghij"), 5, 2, str, str+4, S("abcde1234hij")); + test(S("abcdefghij"), 5, 2, str, str+5, S("abcde12345hij")); + test(S("abcdefghij"), 5, 2, str, str+0, S("abcdehij")); + test(S("abcdefghij"), 5, 2, str, str+1, S("abcde1hij")); + test(S("abcdefghij"), 5, 2, str, str+5, S("abcde12345hij")); + test(S("abcdefghij"), 5, 2, str, str+9, S("abcde123456789hij")); + test(S("abcdefghij"), 5, 2, str, str+10, S("abcde1234567890hij")); + test(S("abcdefghij"), 5, 2, str, str+0, S("abcdehij")); + test(S("abcdefghij"), 5, 2, str, str+1, S("abcde1hij")); + test(S("abcdefghij"), 5, 2, str, str+10, S("abcde1234567890hij")); + test(S("abcdefghij"), 5, 2, str, str+19, S("abcde1234567890123456789hij")); + test(S("abcdefghij"), 5, 2, str, str+20, S("abcde12345678901234567890hij")); + test(S("abcdefghij"), 5, 4, str, str+0, S("abcdej")); + test(S("abcdefghij"), 5, 4, str, str+0, S("abcdej")); + test(S("abcdefghij"), 5, 4, str, str+1, S("abcde1j")); + test(S("abcdefghij"), 5, 4, str, str+2, S("abcde12j")); +} + +template +void test5() +{ + test(S("abcdefghij"), 5, 4, str, str+4, S("abcde1234j")); + test(S("abcdefghij"), 5, 4, str, str+5, S("abcde12345j")); + test(S("abcdefghij"), 5, 4, str, str+0, S("abcdej")); + test(S("abcdefghij"), 5, 4, str, str+1, S("abcde1j")); + test(S("abcdefghij"), 5, 4, str, str+5, S("abcde12345j")); + test(S("abcdefghij"), 5, 4, str, str+9, S("abcde123456789j")); + test(S("abcdefghij"), 5, 4, str, str+10, S("abcde1234567890j")); + test(S("abcdefghij"), 5, 4, str, str+0, S("abcdej")); + test(S("abcdefghij"), 5, 4, str, str+1, S("abcde1j")); + test(S("abcdefghij"), 5, 4, str, str+10, S("abcde1234567890j")); + test(S("abcdefghij"), 5, 4, str, str+19, S("abcde1234567890123456789j")); + test(S("abcdefghij"), 5, 4, str, str+20, S("abcde12345678901234567890j")); + test(S("abcdefghij"), 5, 5, str, str+0, S("abcde")); + test(S("abcdefghij"), 5, 5, str, str+0, S("abcde")); + test(S("abcdefghij"), 5, 5, str, str+1, S("abcde1")); + test(S("abcdefghij"), 5, 5, str, str+2, S("abcde12")); + test(S("abcdefghij"), 5, 5, str, str+4, S("abcde1234")); + test(S("abcdefghij"), 5, 5, str, str+5, S("abcde12345")); + test(S("abcdefghij"), 5, 5, str, str+0, S("abcde")); + test(S("abcdefghij"), 5, 5, str, str+1, S("abcde1")); + test(S("abcdefghij"), 5, 5, str, str+5, S("abcde12345")); + test(S("abcdefghij"), 5, 5, str, str+9, S("abcde123456789")); + test(S("abcdefghij"), 5, 5, str, str+10, S("abcde1234567890")); + test(S("abcdefghij"), 5, 5, str, str+0, S("abcde")); + test(S("abcdefghij"), 5, 5, str, str+1, S("abcde1")); + test(S("abcdefghij"), 5, 5, str, str+10, S("abcde1234567890")); + test(S("abcdefghij"), 5, 5, str, str+19, S("abcde1234567890123456789")); + test(S("abcdefghij"), 5, 5, str, str+20, S("abcde12345678901234567890")); + test(S("abcdefghij"), 9, 0, str, str+0, S("abcdefghij")); + test(S("abcdefghij"), 9, 0, str, str+0, S("abcdefghij")); + test(S("abcdefghij"), 9, 0, str, str+1, S("abcdefghi1j")); + test(S("abcdefghij"), 9, 0, str, str+2, S("abcdefghi12j")); + test(S("abcdefghij"), 9, 0, str, str+4, S("abcdefghi1234j")); + test(S("abcdefghij"), 9, 0, str, str+5, S("abcdefghi12345j")); + test(S("abcdefghij"), 9, 0, str, str+0, S("abcdefghij")); + test(S("abcdefghij"), 9, 0, str, str+1, S("abcdefghi1j")); + test(S("abcdefghij"), 9, 0, str, str+5, S("abcdefghi12345j")); + test(S("abcdefghij"), 9, 0, str, str+9, S("abcdefghi123456789j")); + test(S("abcdefghij"), 9, 0, str, str+10, S("abcdefghi1234567890j")); + test(S("abcdefghij"), 9, 0, str, str+0, S("abcdefghij")); + test(S("abcdefghij"), 9, 0, str, str+1, S("abcdefghi1j")); + test(S("abcdefghij"), 9, 0, str, str+10, S("abcdefghi1234567890j")); + test(S("abcdefghij"), 9, 0, str, str+19, S("abcdefghi1234567890123456789j")); + test(S("abcdefghij"), 9, 0, str, str+20, S("abcdefghi12345678901234567890j")); + test(S("abcdefghij"), 9, 1, str, str+0, S("abcdefghi")); + test(S("abcdefghij"), 9, 1, str, str+0, S("abcdefghi")); + test(S("abcdefghij"), 9, 1, str, str+1, S("abcdefghi1")); + test(S("abcdefghij"), 9, 1, str, str+2, S("abcdefghi12")); + test(S("abcdefghij"), 9, 1, str, str+4, S("abcdefghi1234")); + test(S("abcdefghij"), 9, 1, str, str+5, S("abcdefghi12345")); + test(S("abcdefghij"), 9, 1, str, str+0, S("abcdefghi")); + test(S("abcdefghij"), 9, 1, str, str+1, S("abcdefghi1")); + test(S("abcdefghij"), 9, 1, str, str+5, S("abcdefghi12345")); + test(S("abcdefghij"), 9, 1, str, str+9, S("abcdefghi123456789")); + test(S("abcdefghij"), 9, 1, str, str+10, S("abcdefghi1234567890")); + test(S("abcdefghij"), 9, 1, str, str+0, S("abcdefghi")); + test(S("abcdefghij"), 9, 1, str, str+1, S("abcdefghi1")); + test(S("abcdefghij"), 9, 1, str, str+10, S("abcdefghi1234567890")); + test(S("abcdefghij"), 9, 1, str, str+19, S("abcdefghi1234567890123456789")); + test(S("abcdefghij"), 9, 1, str, str+20, S("abcdefghi12345678901234567890")); + test(S("abcdefghij"), 10, 0, str, str+0, S("abcdefghij")); + test(S("abcdefghij"), 10, 0, str, str+0, S("abcdefghij")); + test(S("abcdefghij"), 10, 0, str, str+1, S("abcdefghij1")); + test(S("abcdefghij"), 10, 0, str, str+2, S("abcdefghij12")); + test(S("abcdefghij"), 10, 0, str, str+4, S("abcdefghij1234")); + test(S("abcdefghij"), 10, 0, str, str+5, S("abcdefghij12345")); + test(S("abcdefghij"), 10, 0, str, str+0, S("abcdefghij")); + test(S("abcdefghij"), 10, 0, str, str+1, S("abcdefghij1")); + test(S("abcdefghij"), 10, 0, str, str+5, S("abcdefghij12345")); + test(S("abcdefghij"), 10, 0, str, str+9, S("abcdefghij123456789")); + test(S("abcdefghij"), 10, 0, str, str+10, S("abcdefghij1234567890")); + test(S("abcdefghij"), 10, 0, str, str+0, S("abcdefghij")); + test(S("abcdefghij"), 10, 0, str, str+1, S("abcdefghij1")); + test(S("abcdefghij"), 10, 0, str, str+10, S("abcdefghij1234567890")); + test(S("abcdefghij"), 10, 0, str, str+19, S("abcdefghij1234567890123456789")); + test(S("abcdefghij"), 10, 0, str, str+20, S("abcdefghij12345678901234567890")); + test(S("abcdefghijklmnopqrst"), 0, 0, str, str+0, S("abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, 0, str, str+0, S("abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, 0, str, str+1, S("1abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, 0, str, str+2, S("12abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, 0, str, str+4, S("1234abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, 0, str, str+5, S("12345abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, 0, str, str+0, S("abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, 0, str, str+1, S("1abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, 0, str, str+5, S("12345abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, 0, str, str+9, S("123456789abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, 0, str, str+10, S("1234567890abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, 0, str, str+0, S("abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, 0, str, str+1, S("1abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, 0, str, str+10, S("1234567890abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, 0, str, str+19, S("1234567890123456789abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, 0, str, str+20, S("12345678901234567890abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, 1, str, str+0, S("bcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, 1, str, str+0, S("bcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, 1, str, str+1, S("1bcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, 1, str, str+2, S("12bcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, 1, str, str+4, S("1234bcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, 1, str, str+5, S("12345bcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, 1, str, str+0, S("bcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, 1, str, str+1, S("1bcdefghijklmnopqrst")); +} + +template +void test6() +{ + test(S("abcdefghijklmnopqrst"), 0, 1, str, str+5, S("12345bcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, 1, str, str+9, S("123456789bcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, 1, str, str+10, S("1234567890bcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, 1, str, str+0, S("bcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, 1, str, str+1, S("1bcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, 1, str, str+10, S("1234567890bcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, 1, str, str+19, S("1234567890123456789bcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, 1, str, str+20, S("12345678901234567890bcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, 10, str, str+0, S("klmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, 10, str, str+0, S("klmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, 10, str, str+1, S("1klmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, 10, str, str+2, S("12klmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, 10, str, str+4, S("1234klmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, 10, str, str+5, S("12345klmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, 10, str, str+0, S("klmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, 10, str, str+1, S("1klmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, 10, str, str+5, S("12345klmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, 10, str, str+9, S("123456789klmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, 10, str, str+10, S("1234567890klmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, 10, str, str+0, S("klmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, 10, str, str+1, S("1klmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, 10, str, str+10, S("1234567890klmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, 10, str, str+19, S("1234567890123456789klmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, 10, str, str+20, S("12345678901234567890klmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, 19, str, str+0, S("t")); + test(S("abcdefghijklmnopqrst"), 0, 19, str, str+0, S("t")); + test(S("abcdefghijklmnopqrst"), 0, 19, str, str+1, S("1t")); + test(S("abcdefghijklmnopqrst"), 0, 19, str, str+2, S("12t")); + test(S("abcdefghijklmnopqrst"), 0, 19, str, str+4, S("1234t")); + test(S("abcdefghijklmnopqrst"), 0, 19, str, str+5, S("12345t")); + test(S("abcdefghijklmnopqrst"), 0, 19, str, str+0, S("t")); + test(S("abcdefghijklmnopqrst"), 0, 19, str, str+1, S("1t")); + test(S("abcdefghijklmnopqrst"), 0, 19, str, str+5, S("12345t")); + test(S("abcdefghijklmnopqrst"), 0, 19, str, str+9, S("123456789t")); + test(S("abcdefghijklmnopqrst"), 0, 19, str, str+10, S("1234567890t")); + test(S("abcdefghijklmnopqrst"), 0, 19, str, str+0, S("t")); + test(S("abcdefghijklmnopqrst"), 0, 19, str, str+1, S("1t")); + test(S("abcdefghijklmnopqrst"), 0, 19, str, str+10, S("1234567890t")); + test(S("abcdefghijklmnopqrst"), 0, 19, str, str+19, S("1234567890123456789t")); + test(S("abcdefghijklmnopqrst"), 0, 19, str, str+20, S("12345678901234567890t")); + test(S("abcdefghijklmnopqrst"), 0, 20, str, str+0, S("")); + test(S("abcdefghijklmnopqrst"), 0, 20, str, str+0, S("")); + test(S("abcdefghijklmnopqrst"), 0, 20, str, str+1, S("1")); + test(S("abcdefghijklmnopqrst"), 0, 20, str, str+2, S("12")); + test(S("abcdefghijklmnopqrst"), 0, 20, str, str+4, S("1234")); + test(S("abcdefghijklmnopqrst"), 0, 20, str, str+5, S("12345")); + test(S("abcdefghijklmnopqrst"), 0, 20, str, str+0, S("")); + test(S("abcdefghijklmnopqrst"), 0, 20, str, str+1, S("1")); + test(S("abcdefghijklmnopqrst"), 0, 20, str, str+5, S("12345")); + test(S("abcdefghijklmnopqrst"), 0, 20, str, str+9, S("123456789")); + test(S("abcdefghijklmnopqrst"), 0, 20, str, str+10, S("1234567890")); + test(S("abcdefghijklmnopqrst"), 0, 20, str, str+0, S("")); + test(S("abcdefghijklmnopqrst"), 0, 20, str, str+1, S("1")); + test(S("abcdefghijklmnopqrst"), 0, 20, str, str+10, S("1234567890")); + test(S("abcdefghijklmnopqrst"), 0, 20, str, str+19, S("1234567890123456789")); + test(S("abcdefghijklmnopqrst"), 0, 20, str, str+20, S("12345678901234567890")); + test(S("abcdefghijklmnopqrst"), 1, 0, str, str+0, S("abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, 0, str, str+0, S("abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, 0, str, str+1, S("a1bcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, 0, str, str+2, S("a12bcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, 0, str, str+4, S("a1234bcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, 0, str, str+5, S("a12345bcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, 0, str, str+0, S("abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, 0, str, str+1, S("a1bcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, 0, str, str+5, S("a12345bcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, 0, str, str+9, S("a123456789bcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, 0, str, str+10, S("a1234567890bcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, 0, str, str+0, S("abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, 0, str, str+1, S("a1bcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, 0, str, str+10, S("a1234567890bcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, 0, str, str+19, S("a1234567890123456789bcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, 0, str, str+20, S("a12345678901234567890bcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, 1, str, str+0, S("acdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, 1, str, str+0, S("acdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, 1, str, str+1, S("a1cdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, 1, str, str+2, S("a12cdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, 1, str, str+4, S("a1234cdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, 1, str, str+5, S("a12345cdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, 1, str, str+0, S("acdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, 1, str, str+1, S("a1cdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, 1, str, str+5, S("a12345cdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, 1, str, str+9, S("a123456789cdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, 1, str, str+10, S("a1234567890cdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, 1, str, str+0, S("acdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, 1, str, str+1, S("a1cdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, 1, str, str+10, S("a1234567890cdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, 1, str, str+19, S("a1234567890123456789cdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, 1, str, str+20, S("a12345678901234567890cdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, 9, str, str+0, S("aklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, 9, str, str+0, S("aklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, 9, str, str+1, S("a1klmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, 9, str, str+2, S("a12klmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, 9, str, str+4, S("a1234klmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, 9, str, str+5, S("a12345klmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, 9, str, str+0, S("aklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, 9, str, str+1, S("a1klmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, 9, str, str+5, S("a12345klmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, 9, str, str+9, S("a123456789klmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, 9, str, str+10, S("a1234567890klmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, 9, str, str+0, S("aklmnopqrst")); +} + +template +void test7() +{ + test(S("abcdefghijklmnopqrst"), 1, 9, str, str+1, S("a1klmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, 9, str, str+10, S("a1234567890klmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, 9, str, str+19, S("a1234567890123456789klmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, 9, str, str+20, S("a12345678901234567890klmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, 18, str, str+0, S("at")); + test(S("abcdefghijklmnopqrst"), 1, 18, str, str+0, S("at")); + test(S("abcdefghijklmnopqrst"), 1, 18, str, str+1, S("a1t")); + test(S("abcdefghijklmnopqrst"), 1, 18, str, str+2, S("a12t")); + test(S("abcdefghijklmnopqrst"), 1, 18, str, str+4, S("a1234t")); + test(S("abcdefghijklmnopqrst"), 1, 18, str, str+5, S("a12345t")); + test(S("abcdefghijklmnopqrst"), 1, 18, str, str+0, S("at")); + test(S("abcdefghijklmnopqrst"), 1, 18, str, str+1, S("a1t")); + test(S("abcdefghijklmnopqrst"), 1, 18, str, str+5, S("a12345t")); + test(S("abcdefghijklmnopqrst"), 1, 18, str, str+9, S("a123456789t")); + test(S("abcdefghijklmnopqrst"), 1, 18, str, str+10, S("a1234567890t")); + test(S("abcdefghijklmnopqrst"), 1, 18, str, str+0, S("at")); + test(S("abcdefghijklmnopqrst"), 1, 18, str, str+1, S("a1t")); + test(S("abcdefghijklmnopqrst"), 1, 18, str, str+10, S("a1234567890t")); + test(S("abcdefghijklmnopqrst"), 1, 18, str, str+19, S("a1234567890123456789t")); + test(S("abcdefghijklmnopqrst"), 1, 18, str, str+20, S("a12345678901234567890t")); + test(S("abcdefghijklmnopqrst"), 1, 19, str, str+0, S("a")); + test(S("abcdefghijklmnopqrst"), 1, 19, str, str+0, S("a")); + test(S("abcdefghijklmnopqrst"), 1, 19, str, str+1, S("a1")); + test(S("abcdefghijklmnopqrst"), 1, 19, str, str+2, S("a12")); + test(S("abcdefghijklmnopqrst"), 1, 19, str, str+4, S("a1234")); + test(S("abcdefghijklmnopqrst"), 1, 19, str, str+5, S("a12345")); + test(S("abcdefghijklmnopqrst"), 1, 19, str, str+0, S("a")); + test(S("abcdefghijklmnopqrst"), 1, 19, str, str+1, S("a1")); + test(S("abcdefghijklmnopqrst"), 1, 19, str, str+5, S("a12345")); + test(S("abcdefghijklmnopqrst"), 1, 19, str, str+9, S("a123456789")); + test(S("abcdefghijklmnopqrst"), 1, 19, str, str+10, S("a1234567890")); + test(S("abcdefghijklmnopqrst"), 1, 19, str, str+0, S("a")); + test(S("abcdefghijklmnopqrst"), 1, 19, str, str+1, S("a1")); + test(S("abcdefghijklmnopqrst"), 1, 19, str, str+10, S("a1234567890")); + test(S("abcdefghijklmnopqrst"), 1, 19, str, str+19, S("a1234567890123456789")); + test(S("abcdefghijklmnopqrst"), 1, 19, str, str+20, S("a12345678901234567890")); + test(S("abcdefghijklmnopqrst"), 10, 0, str, str+0, S("abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 10, 0, str, str+0, S("abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 10, 0, str, str+1, S("abcdefghij1klmnopqrst")); + test(S("abcdefghijklmnopqrst"), 10, 0, str, str+2, S("abcdefghij12klmnopqrst")); + test(S("abcdefghijklmnopqrst"), 10, 0, str, str+4, S("abcdefghij1234klmnopqrst")); + test(S("abcdefghijklmnopqrst"), 10, 0, str, str+5, S("abcdefghij12345klmnopqrst")); + test(S("abcdefghijklmnopqrst"), 10, 0, str, str+0, S("abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 10, 0, str, str+1, S("abcdefghij1klmnopqrst")); + test(S("abcdefghijklmnopqrst"), 10, 0, str, str+5, S("abcdefghij12345klmnopqrst")); + test(S("abcdefghijklmnopqrst"), 10, 0, str, str+9, S("abcdefghij123456789klmnopqrst")); + test(S("abcdefghijklmnopqrst"), 10, 0, str, str+10, S("abcdefghij1234567890klmnopqrst")); + test(S("abcdefghijklmnopqrst"), 10, 0, str, str+0, S("abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 10, 0, str, str+1, S("abcdefghij1klmnopqrst")); + test(S("abcdefghijklmnopqrst"), 10, 0, str, str+10, S("abcdefghij1234567890klmnopqrst")); + test(S("abcdefghijklmnopqrst"), 10, 0, str, str+19, S("abcdefghij1234567890123456789klmnopqrst")); + test(S("abcdefghijklmnopqrst"), 10, 0, str, str+20, S("abcdefghij12345678901234567890klmnopqrst")); + test(S("abcdefghijklmnopqrst"), 10, 1, str, str+0, S("abcdefghijlmnopqrst")); + test(S("abcdefghijklmnopqrst"), 10, 1, str, str+0, S("abcdefghijlmnopqrst")); + test(S("abcdefghijklmnopqrst"), 10, 1, str, str+1, S("abcdefghij1lmnopqrst")); + test(S("abcdefghijklmnopqrst"), 10, 1, str, str+2, S("abcdefghij12lmnopqrst")); + test(S("abcdefghijklmnopqrst"), 10, 1, str, str+4, S("abcdefghij1234lmnopqrst")); + test(S("abcdefghijklmnopqrst"), 10, 1, str, str+5, S("abcdefghij12345lmnopqrst")); + test(S("abcdefghijklmnopqrst"), 10, 1, str, str+0, S("abcdefghijlmnopqrst")); + test(S("abcdefghijklmnopqrst"), 10, 1, str, str+1, S("abcdefghij1lmnopqrst")); + test(S("abcdefghijklmnopqrst"), 10, 1, str, str+5, S("abcdefghij12345lmnopqrst")); + test(S("abcdefghijklmnopqrst"), 10, 1, str, str+9, S("abcdefghij123456789lmnopqrst")); + test(S("abcdefghijklmnopqrst"), 10, 1, str, str+10, S("abcdefghij1234567890lmnopqrst")); + test(S("abcdefghijklmnopqrst"), 10, 1, str, str+0, S("abcdefghijlmnopqrst")); + test(S("abcdefghijklmnopqrst"), 10, 1, str, str+1, S("abcdefghij1lmnopqrst")); + test(S("abcdefghijklmnopqrst"), 10, 1, str, str+10, S("abcdefghij1234567890lmnopqrst")); + test(S("abcdefghijklmnopqrst"), 10, 1, str, str+19, S("abcdefghij1234567890123456789lmnopqrst")); + test(S("abcdefghijklmnopqrst"), 10, 1, str, str+20, S("abcdefghij12345678901234567890lmnopqrst")); + test(S("abcdefghijklmnopqrst"), 10, 5, str, str+0, S("abcdefghijpqrst")); + test(S("abcdefghijklmnopqrst"), 10, 5, str, str+0, S("abcdefghijpqrst")); + test(S("abcdefghijklmnopqrst"), 10, 5, str, str+1, S("abcdefghij1pqrst")); + test(S("abcdefghijklmnopqrst"), 10, 5, str, str+2, S("abcdefghij12pqrst")); + test(S("abcdefghijklmnopqrst"), 10, 5, str, str+4, S("abcdefghij1234pqrst")); + test(S("abcdefghijklmnopqrst"), 10, 5, str, str+5, S("abcdefghij12345pqrst")); + test(S("abcdefghijklmnopqrst"), 10, 5, str, str+0, S("abcdefghijpqrst")); + test(S("abcdefghijklmnopqrst"), 10, 5, str, str+1, S("abcdefghij1pqrst")); + test(S("abcdefghijklmnopqrst"), 10, 5, str, str+5, S("abcdefghij12345pqrst")); + test(S("abcdefghijklmnopqrst"), 10, 5, str, str+9, S("abcdefghij123456789pqrst")); + test(S("abcdefghijklmnopqrst"), 10, 5, str, str+10, S("abcdefghij1234567890pqrst")); + test(S("abcdefghijklmnopqrst"), 10, 5, str, str+0, S("abcdefghijpqrst")); + test(S("abcdefghijklmnopqrst"), 10, 5, str, str+1, S("abcdefghij1pqrst")); + test(S("abcdefghijklmnopqrst"), 10, 5, str, str+10, S("abcdefghij1234567890pqrst")); + test(S("abcdefghijklmnopqrst"), 10, 5, str, str+19, S("abcdefghij1234567890123456789pqrst")); + test(S("abcdefghijklmnopqrst"), 10, 5, str, str+20, S("abcdefghij12345678901234567890pqrst")); + test(S("abcdefghijklmnopqrst"), 10, 9, str, str+0, S("abcdefghijt")); + test(S("abcdefghijklmnopqrst"), 10, 9, str, str+0, S("abcdefghijt")); + test(S("abcdefghijklmnopqrst"), 10, 9, str, str+1, S("abcdefghij1t")); + test(S("abcdefghijklmnopqrst"), 10, 9, str, str+2, S("abcdefghij12t")); + test(S("abcdefghijklmnopqrst"), 10, 9, str, str+4, S("abcdefghij1234t")); + test(S("abcdefghijklmnopqrst"), 10, 9, str, str+5, S("abcdefghij12345t")); + test(S("abcdefghijklmnopqrst"), 10, 9, str, str+0, S("abcdefghijt")); + test(S("abcdefghijklmnopqrst"), 10, 9, str, str+1, S("abcdefghij1t")); + test(S("abcdefghijklmnopqrst"), 10, 9, str, str+5, S("abcdefghij12345t")); + test(S("abcdefghijklmnopqrst"), 10, 9, str, str+9, S("abcdefghij123456789t")); + test(S("abcdefghijklmnopqrst"), 10, 9, str, str+10, S("abcdefghij1234567890t")); + test(S("abcdefghijklmnopqrst"), 10, 9, str, str+0, S("abcdefghijt")); + test(S("abcdefghijklmnopqrst"), 10, 9, str, str+1, S("abcdefghij1t")); + test(S("abcdefghijklmnopqrst"), 10, 9, str, str+10, S("abcdefghij1234567890t")); + test(S("abcdefghijklmnopqrst"), 10, 9, str, str+19, S("abcdefghij1234567890123456789t")); + test(S("abcdefghijklmnopqrst"), 10, 9, str, str+20, S("abcdefghij12345678901234567890t")); +} + +template +void test8() +{ + test(S("abcdefghijklmnopqrst"), 10, 10, str, str+0, S("abcdefghij")); + test(S("abcdefghijklmnopqrst"), 10, 10, str, str+0, S("abcdefghij")); + test(S("abcdefghijklmnopqrst"), 10, 10, str, str+1, S("abcdefghij1")); + test(S("abcdefghijklmnopqrst"), 10, 10, str, str+2, S("abcdefghij12")); + test(S("abcdefghijklmnopqrst"), 10, 10, str, str+4, S("abcdefghij1234")); + test(S("abcdefghijklmnopqrst"), 10, 10, str, str+5, S("abcdefghij12345")); + test(S("abcdefghijklmnopqrst"), 10, 10, str, str+0, S("abcdefghij")); + test(S("abcdefghijklmnopqrst"), 10, 10, str, str+1, S("abcdefghij1")); + test(S("abcdefghijklmnopqrst"), 10, 10, str, str+5, S("abcdefghij12345")); + test(S("abcdefghijklmnopqrst"), 10, 10, str, str+9, S("abcdefghij123456789")); + test(S("abcdefghijklmnopqrst"), 10, 10, str, str+10, S("abcdefghij1234567890")); + test(S("abcdefghijklmnopqrst"), 10, 10, str, str+0, S("abcdefghij")); + test(S("abcdefghijklmnopqrst"), 10, 10, str, str+1, S("abcdefghij1")); + test(S("abcdefghijklmnopqrst"), 10, 10, str, str+10, S("abcdefghij1234567890")); + test(S("abcdefghijklmnopqrst"), 10, 10, str, str+19, S("abcdefghij1234567890123456789")); + test(S("abcdefghijklmnopqrst"), 10, 10, str, str+20, S("abcdefghij12345678901234567890")); + test(S("abcdefghijklmnopqrst"), 19, 0, str, str+0, S("abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 19, 0, str, str+0, S("abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 19, 0, str, str+1, S("abcdefghijklmnopqrs1t")); + test(S("abcdefghijklmnopqrst"), 19, 0, str, str+2, S("abcdefghijklmnopqrs12t")); + test(S("abcdefghijklmnopqrst"), 19, 0, str, str+4, S("abcdefghijklmnopqrs1234t")); + test(S("abcdefghijklmnopqrst"), 19, 0, str, str+5, S("abcdefghijklmnopqrs12345t")); + test(S("abcdefghijklmnopqrst"), 19, 0, str, str+0, S("abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 19, 0, str, str+1, S("abcdefghijklmnopqrs1t")); + test(S("abcdefghijklmnopqrst"), 19, 0, str, str+5, S("abcdefghijklmnopqrs12345t")); + test(S("abcdefghijklmnopqrst"), 19, 0, str, str+9, S("abcdefghijklmnopqrs123456789t")); + test(S("abcdefghijklmnopqrst"), 19, 0, str, str+10, S("abcdefghijklmnopqrs1234567890t")); + test(S("abcdefghijklmnopqrst"), 19, 0, str, str+0, S("abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 19, 0, str, str+1, S("abcdefghijklmnopqrs1t")); + test(S("abcdefghijklmnopqrst"), 19, 0, str, str+10, S("abcdefghijklmnopqrs1234567890t")); + test(S("abcdefghijklmnopqrst"), 19, 0, str, str+19, S("abcdefghijklmnopqrs1234567890123456789t")); + test(S("abcdefghijklmnopqrst"), 19, 0, str, str+20, S("abcdefghijklmnopqrs12345678901234567890t")); + test(S("abcdefghijklmnopqrst"), 19, 1, str, str+0, S("abcdefghijklmnopqrs")); + test(S("abcdefghijklmnopqrst"), 19, 1, str, str+0, S("abcdefghijklmnopqrs")); + test(S("abcdefghijklmnopqrst"), 19, 1, str, str+1, S("abcdefghijklmnopqrs1")); + test(S("abcdefghijklmnopqrst"), 19, 1, str, str+2, S("abcdefghijklmnopqrs12")); + test(S("abcdefghijklmnopqrst"), 19, 1, str, str+4, S("abcdefghijklmnopqrs1234")); + test(S("abcdefghijklmnopqrst"), 19, 1, str, str+5, S("abcdefghijklmnopqrs12345")); + test(S("abcdefghijklmnopqrst"), 19, 1, str, str+0, S("abcdefghijklmnopqrs")); + test(S("abcdefghijklmnopqrst"), 19, 1, str, str+1, S("abcdefghijklmnopqrs1")); + test(S("abcdefghijklmnopqrst"), 19, 1, str, str+5, S("abcdefghijklmnopqrs12345")); + test(S("abcdefghijklmnopqrst"), 19, 1, str, str+9, S("abcdefghijklmnopqrs123456789")); + test(S("abcdefghijklmnopqrst"), 19, 1, str, str+10, S("abcdefghijklmnopqrs1234567890")); + test(S("abcdefghijklmnopqrst"), 19, 1, str, str+0, S("abcdefghijklmnopqrs")); + test(S("abcdefghijklmnopqrst"), 19, 1, str, str+1, S("abcdefghijklmnopqrs1")); + test(S("abcdefghijklmnopqrst"), 19, 1, str, str+10, S("abcdefghijklmnopqrs1234567890")); + test(S("abcdefghijklmnopqrst"), 19, 1, str, str+19, S("abcdefghijklmnopqrs1234567890123456789")); + test(S("abcdefghijklmnopqrst"), 19, 1, str, str+20, S("abcdefghijklmnopqrs12345678901234567890")); + test(S("abcdefghijklmnopqrst"), 20, 0, str, str+0, S("abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 20, 0, str, str+0, S("abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 20, 0, str, str+1, S("abcdefghijklmnopqrst1")); + test(S("abcdefghijklmnopqrst"), 20, 0, str, str+2, S("abcdefghijklmnopqrst12")); + test(S("abcdefghijklmnopqrst"), 20, 0, str, str+4, S("abcdefghijklmnopqrst1234")); + test(S("abcdefghijklmnopqrst"), 20, 0, str, str+5, S("abcdefghijklmnopqrst12345")); + test(S("abcdefghijklmnopqrst"), 20, 0, str, str+0, S("abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 20, 0, str, str+1, S("abcdefghijklmnopqrst1")); + test(S("abcdefghijklmnopqrst"), 20, 0, str, str+5, S("abcdefghijklmnopqrst12345")); + test(S("abcdefghijklmnopqrst"), 20, 0, str, str+9, S("abcdefghijklmnopqrst123456789")); + test(S("abcdefghijklmnopqrst"), 20, 0, str, str+10, S("abcdefghijklmnopqrst1234567890")); + test(S("abcdefghijklmnopqrst"), 20, 0, str, str+0, S("abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 20, 0, str, str+1, S("abcdefghijklmnopqrst1")); + test(S("abcdefghijklmnopqrst"), 20, 0, str, str+10, S("abcdefghijklmnopqrst1234567890")); + test(S("abcdefghijklmnopqrst"), 20, 0, str, str+19, S("abcdefghijklmnopqrst1234567890123456789")); + test(S("abcdefghijklmnopqrst"), 20, 0, str, str+20, S("abcdefghijklmnopqrst12345678901234567890")); +} + +int main() +{ + { + typedef std::string S; + test0(); + test1(); + test2(); + test3(); + test4(); + test5(); + test6(); + test7(); + test8(); + } +#if TEST_STD_VER >= 11 + { + typedef std::basic_string, min_allocator> S; + test0(); + test1(); + test2(); + test3(); + test4(); + test5(); + test6(); + test7(); + test8(); + } +#endif +#ifndef TEST_HAS_NO_EXCEPTIONS + { // test iterator operations that throw + typedef std::string S; + typedef ThrowingIterator TIter; + typedef input_iterator IIter; + const char* s = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"; + test_exceptions(S("abcdefghijklmnopqrst"), 10, 5, IIter(TIter(s, s+10, 4, TIter::TAIncrement)), IIter()); + test_exceptions(S("abcdefghijklmnopqrst"), 10, 5, IIter(TIter(s, s+10, 5, TIter::TADereference)), IIter()); + test_exceptions(S("abcdefghijklmnopqrst"), 10, 5, IIter(TIter(s, s+10, 6, TIter::TAComparison)), IIter()); + + test_exceptions(S("abcdefghijklmnopqrst"), 10, 5, TIter(s, s+10, 4, TIter::TAIncrement), TIter()); + test_exceptions(S("abcdefghijklmnopqrst"), 10, 5, TIter(s, s+10, 5, TIter::TADereference), TIter()); + test_exceptions(S("abcdefghijklmnopqrst"), 10, 5, TIter(s, s+10, 6, TIter::TAComparison), TIter()); + } +#endif + + { // test replacing into self + typedef std::string S; + S s_short = "123/"; + S s_long = "Lorem ipsum dolor sit amet, consectetur/"; + + s_short.replace(s_short.begin(), s_short.begin(), s_short.begin(), s_short.end()); + assert(s_short == "123/123/"); + s_short.replace(s_short.begin(), s_short.begin(), s_short.begin(), s_short.end()); + assert(s_short == "123/123/123/123/"); + s_short.replace(s_short.begin(), s_short.begin(), s_short.begin(), s_short.end()); + assert(s_short == "123/123/123/123/123/123/123/123/"); + + s_long.replace(s_long.begin(), s_long.begin(), s_long.begin(), s_long.end()); + assert(s_long == "Lorem ipsum dolor sit amet, consectetur/Lorem ipsum dolor sit amet, consectetur/"); + } + + { // test assigning a different type + typedef std::string S; + const uint8_t pc[] = "ABCD"; + uint8_t p[] = "EFGH"; + + S s; + s.replace(s.begin(), s.end(), pc, pc + 4); + assert(s == "ABCD"); + + s.clear(); + s.replace(s.begin(), s.end(), p, p + 4); + assert(s == "EFGH"); + } +} diff --git a/tests/external/libcxx/basic_string/string.modifiers/string_replace/iter_iter_pointer.pass.cpp b/tests/external/libcxx/basic_string/string.modifiers/string_replace/iter_iter_pointer.pass.cpp new file mode 100644 index 0000000..a7d6a6e --- /dev/null +++ b/tests/external/libcxx/basic_string/string.modifiers/string_replace/iter_iter_pointer.pass.cpp @@ -0,0 +1,301 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// + +// basic_string& +// replace(const_iterator i1, const_iterator i2, const charT* s); + +#include + +#include +#include +#include + +#include "min_allocator.h" + +template +void +test(S s, typename S::size_type pos1, typename S::size_type n1, const typename S::value_type* str, S expected) +{ + typename S::size_type old_size = s.size(); + typename S::const_iterator first = s.begin() + pos1; + typename S::const_iterator last = s.begin() + pos1 + n1; + typename S::size_type xlen = last - first; + s.replace(first, last, str); + LIBCPP_ASSERT(s.__invariants()); + assert(s == expected); + typename S::size_type rlen = S::traits_type::length(str); + assert(s.size() == old_size - xlen + rlen); +} + +template +void test0() +{ + test(S(""), 0, 0, "", S("")); + test(S(""), 0, 0, "12345", S("12345")); + test(S(""), 0, 0, "1234567890", S("1234567890")); + test(S(""), 0, 0, "12345678901234567890", S("12345678901234567890")); + test(S("abcde"), 0, 0, "", S("abcde")); + test(S("abcde"), 0, 0, "12345", S("12345abcde")); + test(S("abcde"), 0, 0, "1234567890", S("1234567890abcde")); + test(S("abcde"), 0, 0, "12345678901234567890", S("12345678901234567890abcde")); + test(S("abcde"), 0, 1, "", S("bcde")); + test(S("abcde"), 0, 1, "12345", S("12345bcde")); + test(S("abcde"), 0, 1, "1234567890", S("1234567890bcde")); + test(S("abcde"), 0, 1, "12345678901234567890", S("12345678901234567890bcde")); + test(S("abcde"), 0, 2, "", S("cde")); + test(S("abcde"), 0, 2, "12345", S("12345cde")); + test(S("abcde"), 0, 2, "1234567890", S("1234567890cde")); + test(S("abcde"), 0, 2, "12345678901234567890", S("12345678901234567890cde")); + test(S("abcde"), 0, 4, "", S("e")); + test(S("abcde"), 0, 4, "12345", S("12345e")); + test(S("abcde"), 0, 4, "1234567890", S("1234567890e")); + test(S("abcde"), 0, 4, "12345678901234567890", S("12345678901234567890e")); + test(S("abcde"), 0, 5, "", S("")); + test(S("abcde"), 0, 5, "12345", S("12345")); + test(S("abcde"), 0, 5, "1234567890", S("1234567890")); + test(S("abcde"), 0, 5, "12345678901234567890", S("12345678901234567890")); + test(S("abcde"), 1, 0, "", S("abcde")); + test(S("abcde"), 1, 0, "12345", S("a12345bcde")); + test(S("abcde"), 1, 0, "1234567890", S("a1234567890bcde")); + test(S("abcde"), 1, 0, "12345678901234567890", S("a12345678901234567890bcde")); + test(S("abcde"), 1, 1, "", S("acde")); + test(S("abcde"), 1, 1, "12345", S("a12345cde")); + test(S("abcde"), 1, 1, "1234567890", S("a1234567890cde")); + test(S("abcde"), 1, 1, "12345678901234567890", S("a12345678901234567890cde")); + test(S("abcde"), 1, 2, "", S("ade")); + test(S("abcde"), 1, 2, "12345", S("a12345de")); + test(S("abcde"), 1, 2, "1234567890", S("a1234567890de")); + test(S("abcde"), 1, 2, "12345678901234567890", S("a12345678901234567890de")); + test(S("abcde"), 1, 3, "", S("ae")); + test(S("abcde"), 1, 3, "12345", S("a12345e")); + test(S("abcde"), 1, 3, "1234567890", S("a1234567890e")); + test(S("abcde"), 1, 3, "12345678901234567890", S("a12345678901234567890e")); + test(S("abcde"), 1, 4, "", S("a")); + test(S("abcde"), 1, 4, "12345", S("a12345")); + test(S("abcde"), 1, 4, "1234567890", S("a1234567890")); + test(S("abcde"), 1, 4, "12345678901234567890", S("a12345678901234567890")); + test(S("abcde"), 2, 0, "", S("abcde")); + test(S("abcde"), 2, 0, "12345", S("ab12345cde")); + test(S("abcde"), 2, 0, "1234567890", S("ab1234567890cde")); + test(S("abcde"), 2, 0, "12345678901234567890", S("ab12345678901234567890cde")); + test(S("abcde"), 2, 1, "", S("abde")); + test(S("abcde"), 2, 1, "12345", S("ab12345de")); + test(S("abcde"), 2, 1, "1234567890", S("ab1234567890de")); + test(S("abcde"), 2, 1, "12345678901234567890", S("ab12345678901234567890de")); + test(S("abcde"), 2, 2, "", S("abe")); + test(S("abcde"), 2, 2, "12345", S("ab12345e")); + test(S("abcde"), 2, 2, "1234567890", S("ab1234567890e")); + test(S("abcde"), 2, 2, "12345678901234567890", S("ab12345678901234567890e")); + test(S("abcde"), 2, 3, "", S("ab")); + test(S("abcde"), 2, 3, "12345", S("ab12345")); + test(S("abcde"), 2, 3, "1234567890", S("ab1234567890")); + test(S("abcde"), 2, 3, "12345678901234567890", S("ab12345678901234567890")); + test(S("abcde"), 4, 0, "", S("abcde")); + test(S("abcde"), 4, 0, "12345", S("abcd12345e")); + test(S("abcde"), 4, 0, "1234567890", S("abcd1234567890e")); + test(S("abcde"), 4, 0, "12345678901234567890", S("abcd12345678901234567890e")); + test(S("abcde"), 4, 1, "", S("abcd")); + test(S("abcde"), 4, 1, "12345", S("abcd12345")); + test(S("abcde"), 4, 1, "1234567890", S("abcd1234567890")); + test(S("abcde"), 4, 1, "12345678901234567890", S("abcd12345678901234567890")); + test(S("abcde"), 5, 0, "", S("abcde")); + test(S("abcde"), 5, 0, "12345", S("abcde12345")); + test(S("abcde"), 5, 0, "1234567890", S("abcde1234567890")); + test(S("abcde"), 5, 0, "12345678901234567890", S("abcde12345678901234567890")); + test(S("abcdefghij"), 0, 0, "", S("abcdefghij")); + test(S("abcdefghij"), 0, 0, "12345", S("12345abcdefghij")); + test(S("abcdefghij"), 0, 0, "1234567890", S("1234567890abcdefghij")); + test(S("abcdefghij"), 0, 0, "12345678901234567890", S("12345678901234567890abcdefghij")); + test(S("abcdefghij"), 0, 1, "", S("bcdefghij")); + test(S("abcdefghij"), 0, 1, "12345", S("12345bcdefghij")); + test(S("abcdefghij"), 0, 1, "1234567890", S("1234567890bcdefghij")); + test(S("abcdefghij"), 0, 1, "12345678901234567890", S("12345678901234567890bcdefghij")); + test(S("abcdefghij"), 0, 5, "", S("fghij")); + test(S("abcdefghij"), 0, 5, "12345", S("12345fghij")); + test(S("abcdefghij"), 0, 5, "1234567890", S("1234567890fghij")); + test(S("abcdefghij"), 0, 5, "12345678901234567890", S("12345678901234567890fghij")); + test(S("abcdefghij"), 0, 9, "", S("j")); + test(S("abcdefghij"), 0, 9, "12345", S("12345j")); + test(S("abcdefghij"), 0, 9, "1234567890", S("1234567890j")); + test(S("abcdefghij"), 0, 9, "12345678901234567890", S("12345678901234567890j")); + test(S("abcdefghij"), 0, 10, "", S("")); + test(S("abcdefghij"), 0, 10, "12345", S("12345")); + test(S("abcdefghij"), 0, 10, "1234567890", S("1234567890")); + test(S("abcdefghij"), 0, 10, "12345678901234567890", S("12345678901234567890")); + test(S("abcdefghij"), 1, 0, "", S("abcdefghij")); + test(S("abcdefghij"), 1, 0, "12345", S("a12345bcdefghij")); + test(S("abcdefghij"), 1, 0, "1234567890", S("a1234567890bcdefghij")); + test(S("abcdefghij"), 1, 0, "12345678901234567890", S("a12345678901234567890bcdefghij")); + test(S("abcdefghij"), 1, 1, "", S("acdefghij")); + test(S("abcdefghij"), 1, 1, "12345", S("a12345cdefghij")); + test(S("abcdefghij"), 1, 1, "1234567890", S("a1234567890cdefghij")); + test(S("abcdefghij"), 1, 1, "12345678901234567890", S("a12345678901234567890cdefghij")); +} + +template +void test1() +{ + test(S("abcdefghij"), 1, 4, "", S("afghij")); + test(S("abcdefghij"), 1, 4, "12345", S("a12345fghij")); + test(S("abcdefghij"), 1, 4, "1234567890", S("a1234567890fghij")); + test(S("abcdefghij"), 1, 4, "12345678901234567890", S("a12345678901234567890fghij")); + test(S("abcdefghij"), 1, 8, "", S("aj")); + test(S("abcdefghij"), 1, 8, "12345", S("a12345j")); + test(S("abcdefghij"), 1, 8, "1234567890", S("a1234567890j")); + test(S("abcdefghij"), 1, 8, "12345678901234567890", S("a12345678901234567890j")); + test(S("abcdefghij"), 1, 9, "", S("a")); + test(S("abcdefghij"), 1, 9, "12345", S("a12345")); + test(S("abcdefghij"), 1, 9, "1234567890", S("a1234567890")); + test(S("abcdefghij"), 1, 9, "12345678901234567890", S("a12345678901234567890")); + test(S("abcdefghij"), 5, 0, "", S("abcdefghij")); + test(S("abcdefghij"), 5, 0, "12345", S("abcde12345fghij")); + test(S("abcdefghij"), 5, 0, "1234567890", S("abcde1234567890fghij")); + test(S("abcdefghij"), 5, 0, "12345678901234567890", S("abcde12345678901234567890fghij")); + test(S("abcdefghij"), 5, 1, "", S("abcdeghij")); + test(S("abcdefghij"), 5, 1, "12345", S("abcde12345ghij")); + test(S("abcdefghij"), 5, 1, "1234567890", S("abcde1234567890ghij")); + test(S("abcdefghij"), 5, 1, "12345678901234567890", S("abcde12345678901234567890ghij")); + test(S("abcdefghij"), 5, 2, "", S("abcdehij")); + test(S("abcdefghij"), 5, 2, "12345", S("abcde12345hij")); + test(S("abcdefghij"), 5, 2, "1234567890", S("abcde1234567890hij")); + test(S("abcdefghij"), 5, 2, "12345678901234567890", S("abcde12345678901234567890hij")); + test(S("abcdefghij"), 5, 4, "", S("abcdej")); + test(S("abcdefghij"), 5, 4, "12345", S("abcde12345j")); + test(S("abcdefghij"), 5, 4, "1234567890", S("abcde1234567890j")); + test(S("abcdefghij"), 5, 4, "12345678901234567890", S("abcde12345678901234567890j")); + test(S("abcdefghij"), 5, 5, "", S("abcde")); + test(S("abcdefghij"), 5, 5, "12345", S("abcde12345")); + test(S("abcdefghij"), 5, 5, "1234567890", S("abcde1234567890")); + test(S("abcdefghij"), 5, 5, "12345678901234567890", S("abcde12345678901234567890")); + test(S("abcdefghij"), 9, 0, "", S("abcdefghij")); + test(S("abcdefghij"), 9, 0, "12345", S("abcdefghi12345j")); + test(S("abcdefghij"), 9, 0, "1234567890", S("abcdefghi1234567890j")); + test(S("abcdefghij"), 9, 0, "12345678901234567890", S("abcdefghi12345678901234567890j")); + test(S("abcdefghij"), 9, 1, "", S("abcdefghi")); + test(S("abcdefghij"), 9, 1, "12345", S("abcdefghi12345")); + test(S("abcdefghij"), 9, 1, "1234567890", S("abcdefghi1234567890")); + test(S("abcdefghij"), 9, 1, "12345678901234567890", S("abcdefghi12345678901234567890")); + test(S("abcdefghij"), 10, 0, "", S("abcdefghij")); + test(S("abcdefghij"), 10, 0, "12345", S("abcdefghij12345")); + test(S("abcdefghij"), 10, 0, "1234567890", S("abcdefghij1234567890")); + test(S("abcdefghij"), 10, 0, "12345678901234567890", S("abcdefghij12345678901234567890")); + test(S("abcdefghijklmnopqrst"), 0, 0, "", S("abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, 0, "12345", S("12345abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, 0, "1234567890", S("1234567890abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, 0, "12345678901234567890", S("12345678901234567890abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, 1, "", S("bcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, 1, "12345", S("12345bcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, 1, "1234567890", S("1234567890bcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, 1, "12345678901234567890", S("12345678901234567890bcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, 10, "", S("klmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, 10, "12345", S("12345klmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, 10, "1234567890", S("1234567890klmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, 10, "12345678901234567890", S("12345678901234567890klmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, 19, "", S("t")); + test(S("abcdefghijklmnopqrst"), 0, 19, "12345", S("12345t")); + test(S("abcdefghijklmnopqrst"), 0, 19, "1234567890", S("1234567890t")); + test(S("abcdefghijklmnopqrst"), 0, 19, "12345678901234567890", S("12345678901234567890t")); + test(S("abcdefghijklmnopqrst"), 0, 20, "", S("")); + test(S("abcdefghijklmnopqrst"), 0, 20, "12345", S("12345")); + test(S("abcdefghijklmnopqrst"), 0, 20, "1234567890", S("1234567890")); + test(S("abcdefghijklmnopqrst"), 0, 20, "12345678901234567890", S("12345678901234567890")); + test(S("abcdefghijklmnopqrst"), 1, 0, "", S("abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, 0, "12345", S("a12345bcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, 0, "1234567890", S("a1234567890bcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, 0, "12345678901234567890", S("a12345678901234567890bcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, 1, "", S("acdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, 1, "12345", S("a12345cdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, 1, "1234567890", S("a1234567890cdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, 1, "12345678901234567890", S("a12345678901234567890cdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, 9, "", S("aklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, 9, "12345", S("a12345klmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, 9, "1234567890", S("a1234567890klmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, 9, "12345678901234567890", S("a12345678901234567890klmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, 18, "", S("at")); + test(S("abcdefghijklmnopqrst"), 1, 18, "12345", S("a12345t")); + test(S("abcdefghijklmnopqrst"), 1, 18, "1234567890", S("a1234567890t")); + test(S("abcdefghijklmnopqrst"), 1, 18, "12345678901234567890", S("a12345678901234567890t")); + test(S("abcdefghijklmnopqrst"), 1, 19, "", S("a")); + test(S("abcdefghijklmnopqrst"), 1, 19, "12345", S("a12345")); + test(S("abcdefghijklmnopqrst"), 1, 19, "1234567890", S("a1234567890")); + test(S("abcdefghijklmnopqrst"), 1, 19, "12345678901234567890", S("a12345678901234567890")); + test(S("abcdefghijklmnopqrst"), 10, 0, "", S("abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 10, 0, "12345", S("abcdefghij12345klmnopqrst")); + test(S("abcdefghijklmnopqrst"), 10, 0, "1234567890", S("abcdefghij1234567890klmnopqrst")); + test(S("abcdefghijklmnopqrst"), 10, 0, "12345678901234567890", S("abcdefghij12345678901234567890klmnopqrst")); + test(S("abcdefghijklmnopqrst"), 10, 1, "", S("abcdefghijlmnopqrst")); + test(S("abcdefghijklmnopqrst"), 10, 1, "12345", S("abcdefghij12345lmnopqrst")); + test(S("abcdefghijklmnopqrst"), 10, 1, "1234567890", S("abcdefghij1234567890lmnopqrst")); + test(S("abcdefghijklmnopqrst"), 10, 1, "12345678901234567890", S("abcdefghij12345678901234567890lmnopqrst")); + test(S("abcdefghijklmnopqrst"), 10, 5, "", S("abcdefghijpqrst")); + test(S("abcdefghijklmnopqrst"), 10, 5, "12345", S("abcdefghij12345pqrst")); + test(S("abcdefghijklmnopqrst"), 10, 5, "1234567890", S("abcdefghij1234567890pqrst")); + test(S("abcdefghijklmnopqrst"), 10, 5, "12345678901234567890", S("abcdefghij12345678901234567890pqrst")); + test(S("abcdefghijklmnopqrst"), 10, 9, "", S("abcdefghijt")); + test(S("abcdefghijklmnopqrst"), 10, 9, "12345", S("abcdefghij12345t")); + test(S("abcdefghijklmnopqrst"), 10, 9, "1234567890", S("abcdefghij1234567890t")); + test(S("abcdefghijklmnopqrst"), 10, 9, "12345678901234567890", S("abcdefghij12345678901234567890t")); +} + +template +void test2() +{ + test(S("abcdefghijklmnopqrst"), 10, 10, "", S("abcdefghij")); + test(S("abcdefghijklmnopqrst"), 10, 10, "12345", S("abcdefghij12345")); + test(S("abcdefghijklmnopqrst"), 10, 10, "1234567890", S("abcdefghij1234567890")); + test(S("abcdefghijklmnopqrst"), 10, 10, "12345678901234567890", S("abcdefghij12345678901234567890")); + test(S("abcdefghijklmnopqrst"), 19, 0, "", S("abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 19, 0, "12345", S("abcdefghijklmnopqrs12345t")); + test(S("abcdefghijklmnopqrst"), 19, 0, "1234567890", S("abcdefghijklmnopqrs1234567890t")); + test(S("abcdefghijklmnopqrst"), 19, 0, "12345678901234567890", S("abcdefghijklmnopqrs12345678901234567890t")); + test(S("abcdefghijklmnopqrst"), 19, 1, "", S("abcdefghijklmnopqrs")); + test(S("abcdefghijklmnopqrst"), 19, 1, "12345", S("abcdefghijklmnopqrs12345")); + test(S("abcdefghijklmnopqrst"), 19, 1, "1234567890", S("abcdefghijklmnopqrs1234567890")); + test(S("abcdefghijklmnopqrst"), 19, 1, "12345678901234567890", S("abcdefghijklmnopqrs12345678901234567890")); + test(S("abcdefghijklmnopqrst"), 20, 0, "", S("abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 20, 0, "12345", S("abcdefghijklmnopqrst12345")); + test(S("abcdefghijklmnopqrst"), 20, 0, "1234567890", S("abcdefghijklmnopqrst1234567890")); + test(S("abcdefghijklmnopqrst"), 20, 0, "12345678901234567890", S("abcdefghijklmnopqrst12345678901234567890")); +} + +int main() +{ + { + typedef std::string S; + test0(); + test1(); + test2(); + } +#if TEST_STD_VER >= 11 + { + typedef std::basic_string, min_allocator> S; + test0(); + test1(); + test2(); + } +#endif + + { // test replacing into self + typedef std::string S; + S s_short = "123/"; + S s_long = "Lorem ipsum dolor sit amet, consectetur/"; + + s_short.replace(s_short.begin(), s_short.begin(), s_short.c_str()); + assert(s_short == "123/123/"); + s_short.replace(s_short.begin(), s_short.begin(), s_short.c_str()); + assert(s_short == "123/123/123/123/"); + s_short.replace(s_short.begin(), s_short.begin(), s_short.c_str()); + assert(s_short == "123/123/123/123/123/123/123/123/"); + + s_long.replace(s_long.begin(), s_long.begin(), s_long.c_str()); + assert(s_long == "Lorem ipsum dolor sit amet, consectetur/Lorem ipsum dolor sit amet, consectetur/"); + } +} diff --git a/tests/external/libcxx/basic_string/string.modifiers/string_replace/iter_iter_pointer_size.pass.cpp b/tests/external/libcxx/basic_string/string.modifiers/string_replace/iter_iter_pointer_size.pass.cpp new file mode 100644 index 0000000..6c68b15 --- /dev/null +++ b/tests/external/libcxx/basic_string/string.modifiers/string_replace/iter_iter_pointer_size.pass.cpp @@ -0,0 +1,991 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// + +// basic_string& +// replace(const_iterator i1, const_iterator i2, const charT* s, size_type n); + +#include +#include +#include + +#include "test_macros.h" +#include "min_allocator.h" + +template +void +test(S s, typename S::size_type pos1, typename S::size_type n1, const typename S::value_type* str, + typename S::size_type n2, S expected) +{ + typename S::size_type old_size = s.size(); + typename S::const_iterator first = s.begin() + pos1; + typename S::const_iterator last = s.begin() + pos1 + n1; + typename S::size_type xlen = last - first; + s.replace(first, last, str, n2); + LIBCPP_ASSERT(s.__invariants()); + assert(s == expected); + typename S::size_type rlen = n2; + assert(s.size() == old_size - xlen + rlen); +} + +template +void test0() +{ + test(S(""), 0, 0, "", 0, S("")); + test(S(""), 0, 0, "12345", 0, S("")); + test(S(""), 0, 0, "12345", 1, S("1")); + test(S(""), 0, 0, "12345", 2, S("12")); + test(S(""), 0, 0, "12345", 4, S("1234")); + test(S(""), 0, 0, "12345", 5, S("12345")); + test(S(""), 0, 0, "1234567890", 0, S("")); + test(S(""), 0, 0, "1234567890", 1, S("1")); + test(S(""), 0, 0, "1234567890", 5, S("12345")); + test(S(""), 0, 0, "1234567890", 9, S("123456789")); + test(S(""), 0, 0, "1234567890", 10, S("1234567890")); + test(S(""), 0, 0, "12345678901234567890", 0, S("")); + test(S(""), 0, 0, "12345678901234567890", 1, S("1")); + test(S(""), 0, 0, "12345678901234567890", 10, S("1234567890")); + test(S(""), 0, 0, "12345678901234567890", 19, S("1234567890123456789")); + test(S(""), 0, 0, "12345678901234567890", 20, S("12345678901234567890")); + test(S("abcde"), 0, 0, "", 0, S("abcde")); + test(S("abcde"), 0, 0, "12345", 0, S("abcde")); + test(S("abcde"), 0, 0, "12345", 1, S("1abcde")); + test(S("abcde"), 0, 0, "12345", 2, S("12abcde")); + test(S("abcde"), 0, 0, "12345", 4, S("1234abcde")); + test(S("abcde"), 0, 0, "12345", 5, S("12345abcde")); + test(S("abcde"), 0, 0, "1234567890", 0, S("abcde")); + test(S("abcde"), 0, 0, "1234567890", 1, S("1abcde")); + test(S("abcde"), 0, 0, "1234567890", 5, S("12345abcde")); + test(S("abcde"), 0, 0, "1234567890", 9, S("123456789abcde")); + test(S("abcde"), 0, 0, "1234567890", 10, S("1234567890abcde")); + test(S("abcde"), 0, 0, "12345678901234567890", 0, S("abcde")); + test(S("abcde"), 0, 0, "12345678901234567890", 1, S("1abcde")); + test(S("abcde"), 0, 0, "12345678901234567890", 10, S("1234567890abcde")); + test(S("abcde"), 0, 0, "12345678901234567890", 19, S("1234567890123456789abcde")); + test(S("abcde"), 0, 0, "12345678901234567890", 20, S("12345678901234567890abcde")); + test(S("abcde"), 0, 1, "", 0, S("bcde")); + test(S("abcde"), 0, 1, "12345", 0, S("bcde")); + test(S("abcde"), 0, 1, "12345", 1, S("1bcde")); + test(S("abcde"), 0, 1, "12345", 2, S("12bcde")); + test(S("abcde"), 0, 1, "12345", 4, S("1234bcde")); + test(S("abcde"), 0, 1, "12345", 5, S("12345bcde")); + test(S("abcde"), 0, 1, "1234567890", 0, S("bcde")); + test(S("abcde"), 0, 1, "1234567890", 1, S("1bcde")); + test(S("abcde"), 0, 1, "1234567890", 5, S("12345bcde")); + test(S("abcde"), 0, 1, "1234567890", 9, S("123456789bcde")); + test(S("abcde"), 0, 1, "1234567890", 10, S("1234567890bcde")); + test(S("abcde"), 0, 1, "12345678901234567890", 0, S("bcde")); + test(S("abcde"), 0, 1, "12345678901234567890", 1, S("1bcde")); + test(S("abcde"), 0, 1, "12345678901234567890", 10, S("1234567890bcde")); + test(S("abcde"), 0, 1, "12345678901234567890", 19, S("1234567890123456789bcde")); + test(S("abcde"), 0, 1, "12345678901234567890", 20, S("12345678901234567890bcde")); + test(S("abcde"), 0, 2, "", 0, S("cde")); + test(S("abcde"), 0, 2, "12345", 0, S("cde")); + test(S("abcde"), 0, 2, "12345", 1, S("1cde")); + test(S("abcde"), 0, 2, "12345", 2, S("12cde")); + test(S("abcde"), 0, 2, "12345", 4, S("1234cde")); + test(S("abcde"), 0, 2, "12345", 5, S("12345cde")); + test(S("abcde"), 0, 2, "1234567890", 0, S("cde")); + test(S("abcde"), 0, 2, "1234567890", 1, S("1cde")); + test(S("abcde"), 0, 2, "1234567890", 5, S("12345cde")); + test(S("abcde"), 0, 2, "1234567890", 9, S("123456789cde")); + test(S("abcde"), 0, 2, "1234567890", 10, S("1234567890cde")); + test(S("abcde"), 0, 2, "12345678901234567890", 0, S("cde")); + test(S("abcde"), 0, 2, "12345678901234567890", 1, S("1cde")); + test(S("abcde"), 0, 2, "12345678901234567890", 10, S("1234567890cde")); + test(S("abcde"), 0, 2, "12345678901234567890", 19, S("1234567890123456789cde")); + test(S("abcde"), 0, 2, "12345678901234567890", 20, S("12345678901234567890cde")); + test(S("abcde"), 0, 4, "", 0, S("e")); + test(S("abcde"), 0, 4, "12345", 0, S("e")); + test(S("abcde"), 0, 4, "12345", 1, S("1e")); + test(S("abcde"), 0, 4, "12345", 2, S("12e")); + test(S("abcde"), 0, 4, "12345", 4, S("1234e")); + test(S("abcde"), 0, 4, "12345", 5, S("12345e")); + test(S("abcde"), 0, 4, "1234567890", 0, S("e")); + test(S("abcde"), 0, 4, "1234567890", 1, S("1e")); + test(S("abcde"), 0, 4, "1234567890", 5, S("12345e")); + test(S("abcde"), 0, 4, "1234567890", 9, S("123456789e")); + test(S("abcde"), 0, 4, "1234567890", 10, S("1234567890e")); + test(S("abcde"), 0, 4, "12345678901234567890", 0, S("e")); + test(S("abcde"), 0, 4, "12345678901234567890", 1, S("1e")); + test(S("abcde"), 0, 4, "12345678901234567890", 10, S("1234567890e")); + test(S("abcde"), 0, 4, "12345678901234567890", 19, S("1234567890123456789e")); + test(S("abcde"), 0, 4, "12345678901234567890", 20, S("12345678901234567890e")); + test(S("abcde"), 0, 5, "", 0, S("")); + test(S("abcde"), 0, 5, "12345", 0, S("")); + test(S("abcde"), 0, 5, "12345", 1, S("1")); + test(S("abcde"), 0, 5, "12345", 2, S("12")); + test(S("abcde"), 0, 5, "12345", 4, S("1234")); + test(S("abcde"), 0, 5, "12345", 5, S("12345")); + test(S("abcde"), 0, 5, "1234567890", 0, S("")); + test(S("abcde"), 0, 5, "1234567890", 1, S("1")); + test(S("abcde"), 0, 5, "1234567890", 5, S("12345")); + test(S("abcde"), 0, 5, "1234567890", 9, S("123456789")); + test(S("abcde"), 0, 5, "1234567890", 10, S("1234567890")); + test(S("abcde"), 0, 5, "12345678901234567890", 0, S("")); + test(S("abcde"), 0, 5, "12345678901234567890", 1, S("1")); + test(S("abcde"), 0, 5, "12345678901234567890", 10, S("1234567890")); + test(S("abcde"), 0, 5, "12345678901234567890", 19, S("1234567890123456789")); + test(S("abcde"), 0, 5, "12345678901234567890", 20, S("12345678901234567890")); + test(S("abcde"), 1, 0, "", 0, S("abcde")); + test(S("abcde"), 1, 0, "12345", 0, S("abcde")); + test(S("abcde"), 1, 0, "12345", 1, S("a1bcde")); + test(S("abcde"), 1, 0, "12345", 2, S("a12bcde")); +} + +template +void test1() +{ + test(S("abcde"), 1, 0, "12345", 4, S("a1234bcde")); + test(S("abcde"), 1, 0, "12345", 5, S("a12345bcde")); + test(S("abcde"), 1, 0, "1234567890", 0, S("abcde")); + test(S("abcde"), 1, 0, "1234567890", 1, S("a1bcde")); + test(S("abcde"), 1, 0, "1234567890", 5, S("a12345bcde")); + test(S("abcde"), 1, 0, "1234567890", 9, S("a123456789bcde")); + test(S("abcde"), 1, 0, "1234567890", 10, S("a1234567890bcde")); + test(S("abcde"), 1, 0, "12345678901234567890", 0, S("abcde")); + test(S("abcde"), 1, 0, "12345678901234567890", 1, S("a1bcde")); + test(S("abcde"), 1, 0, "12345678901234567890", 10, S("a1234567890bcde")); + test(S("abcde"), 1, 0, "12345678901234567890", 19, S("a1234567890123456789bcde")); + test(S("abcde"), 1, 0, "12345678901234567890", 20, S("a12345678901234567890bcde")); + test(S("abcde"), 1, 1, "", 0, S("acde")); + test(S("abcde"), 1, 1, "12345", 0, S("acde")); + test(S("abcde"), 1, 1, "12345", 1, S("a1cde")); + test(S("abcde"), 1, 1, "12345", 2, S("a12cde")); + test(S("abcde"), 1, 1, "12345", 4, S("a1234cde")); + test(S("abcde"), 1, 1, "12345", 5, S("a12345cde")); + test(S("abcde"), 1, 1, "1234567890", 0, S("acde")); + test(S("abcde"), 1, 1, "1234567890", 1, S("a1cde")); + test(S("abcde"), 1, 1, "1234567890", 5, S("a12345cde")); + test(S("abcde"), 1, 1, "1234567890", 9, S("a123456789cde")); + test(S("abcde"), 1, 1, "1234567890", 10, S("a1234567890cde")); + test(S("abcde"), 1, 1, "12345678901234567890", 0, S("acde")); + test(S("abcde"), 1, 1, "12345678901234567890", 1, S("a1cde")); + test(S("abcde"), 1, 1, "12345678901234567890", 10, S("a1234567890cde")); + test(S("abcde"), 1, 1, "12345678901234567890", 19, S("a1234567890123456789cde")); + test(S("abcde"), 1, 1, "12345678901234567890", 20, S("a12345678901234567890cde")); + test(S("abcde"), 1, 2, "", 0, S("ade")); + test(S("abcde"), 1, 2, "12345", 0, S("ade")); + test(S("abcde"), 1, 2, "12345", 1, S("a1de")); + test(S("abcde"), 1, 2, "12345", 2, S("a12de")); + test(S("abcde"), 1, 2, "12345", 4, S("a1234de")); + test(S("abcde"), 1, 2, "12345", 5, S("a12345de")); + test(S("abcde"), 1, 2, "1234567890", 0, S("ade")); + test(S("abcde"), 1, 2, "1234567890", 1, S("a1de")); + test(S("abcde"), 1, 2, "1234567890", 5, S("a12345de")); + test(S("abcde"), 1, 2, "1234567890", 9, S("a123456789de")); + test(S("abcde"), 1, 2, "1234567890", 10, S("a1234567890de")); + test(S("abcde"), 1, 2, "12345678901234567890", 0, S("ade")); + test(S("abcde"), 1, 2, "12345678901234567890", 1, S("a1de")); + test(S("abcde"), 1, 2, "12345678901234567890", 10, S("a1234567890de")); + test(S("abcde"), 1, 2, "12345678901234567890", 19, S("a1234567890123456789de")); + test(S("abcde"), 1, 2, "12345678901234567890", 20, S("a12345678901234567890de")); + test(S("abcde"), 1, 3, "", 0, S("ae")); + test(S("abcde"), 1, 3, "12345", 0, S("ae")); + test(S("abcde"), 1, 3, "12345", 1, S("a1e")); + test(S("abcde"), 1, 3, "12345", 2, S("a12e")); + test(S("abcde"), 1, 3, "12345", 4, S("a1234e")); + test(S("abcde"), 1, 3, "12345", 5, S("a12345e")); + test(S("abcde"), 1, 3, "1234567890", 0, S("ae")); + test(S("abcde"), 1, 3, "1234567890", 1, S("a1e")); + test(S("abcde"), 1, 3, "1234567890", 5, S("a12345e")); + test(S("abcde"), 1, 3, "1234567890", 9, S("a123456789e")); + test(S("abcde"), 1, 3, "1234567890", 10, S("a1234567890e")); + test(S("abcde"), 1, 3, "12345678901234567890", 0, S("ae")); + test(S("abcde"), 1, 3, "12345678901234567890", 1, S("a1e")); + test(S("abcde"), 1, 3, "12345678901234567890", 10, S("a1234567890e")); + test(S("abcde"), 1, 3, "12345678901234567890", 19, S("a1234567890123456789e")); + test(S("abcde"), 1, 3, "12345678901234567890", 20, S("a12345678901234567890e")); + test(S("abcde"), 1, 4, "", 0, S("a")); + test(S("abcde"), 1, 4, "12345", 0, S("a")); + test(S("abcde"), 1, 4, "12345", 1, S("a1")); + test(S("abcde"), 1, 4, "12345", 2, S("a12")); + test(S("abcde"), 1, 4, "12345", 4, S("a1234")); + test(S("abcde"), 1, 4, "12345", 5, S("a12345")); + test(S("abcde"), 1, 4, "1234567890", 0, S("a")); + test(S("abcde"), 1, 4, "1234567890", 1, S("a1")); + test(S("abcde"), 1, 4, "1234567890", 5, S("a12345")); + test(S("abcde"), 1, 4, "1234567890", 9, S("a123456789")); + test(S("abcde"), 1, 4, "1234567890", 10, S("a1234567890")); + test(S("abcde"), 1, 4, "12345678901234567890", 0, S("a")); + test(S("abcde"), 1, 4, "12345678901234567890", 1, S("a1")); + test(S("abcde"), 1, 4, "12345678901234567890", 10, S("a1234567890")); + test(S("abcde"), 1, 4, "12345678901234567890", 19, S("a1234567890123456789")); + test(S("abcde"), 1, 4, "12345678901234567890", 20, S("a12345678901234567890")); + test(S("abcde"), 2, 0, "", 0, S("abcde")); + test(S("abcde"), 2, 0, "12345", 0, S("abcde")); + test(S("abcde"), 2, 0, "12345", 1, S("ab1cde")); + test(S("abcde"), 2, 0, "12345", 2, S("ab12cde")); + test(S("abcde"), 2, 0, "12345", 4, S("ab1234cde")); + test(S("abcde"), 2, 0, "12345", 5, S("ab12345cde")); + test(S("abcde"), 2, 0, "1234567890", 0, S("abcde")); + test(S("abcde"), 2, 0, "1234567890", 1, S("ab1cde")); + test(S("abcde"), 2, 0, "1234567890", 5, S("ab12345cde")); + test(S("abcde"), 2, 0, "1234567890", 9, S("ab123456789cde")); + test(S("abcde"), 2, 0, "1234567890", 10, S("ab1234567890cde")); + test(S("abcde"), 2, 0, "12345678901234567890", 0, S("abcde")); + test(S("abcde"), 2, 0, "12345678901234567890", 1, S("ab1cde")); + test(S("abcde"), 2, 0, "12345678901234567890", 10, S("ab1234567890cde")); + test(S("abcde"), 2, 0, "12345678901234567890", 19, S("ab1234567890123456789cde")); + test(S("abcde"), 2, 0, "12345678901234567890", 20, S("ab12345678901234567890cde")); + test(S("abcde"), 2, 1, "", 0, S("abde")); + test(S("abcde"), 2, 1, "12345", 0, S("abde")); + test(S("abcde"), 2, 1, "12345", 1, S("ab1de")); + test(S("abcde"), 2, 1, "12345", 2, S("ab12de")); + test(S("abcde"), 2, 1, "12345", 4, S("ab1234de")); + test(S("abcde"), 2, 1, "12345", 5, S("ab12345de")); + test(S("abcde"), 2, 1, "1234567890", 0, S("abde")); + test(S("abcde"), 2, 1, "1234567890", 1, S("ab1de")); +} + +template +void test2() +{ + test(S("abcde"), 2, 1, "1234567890", 5, S("ab12345de")); + test(S("abcde"), 2, 1, "1234567890", 9, S("ab123456789de")); + test(S("abcde"), 2, 1, "1234567890", 10, S("ab1234567890de")); + test(S("abcde"), 2, 1, "12345678901234567890", 0, S("abde")); + test(S("abcde"), 2, 1, "12345678901234567890", 1, S("ab1de")); + test(S("abcde"), 2, 1, "12345678901234567890", 10, S("ab1234567890de")); + test(S("abcde"), 2, 1, "12345678901234567890", 19, S("ab1234567890123456789de")); + test(S("abcde"), 2, 1, "12345678901234567890", 20, S("ab12345678901234567890de")); + test(S("abcde"), 2, 2, "", 0, S("abe")); + test(S("abcde"), 2, 2, "12345", 0, S("abe")); + test(S("abcde"), 2, 2, "12345", 1, S("ab1e")); + test(S("abcde"), 2, 2, "12345", 2, S("ab12e")); + test(S("abcde"), 2, 2, "12345", 4, S("ab1234e")); + test(S("abcde"), 2, 2, "12345", 5, S("ab12345e")); + test(S("abcde"), 2, 2, "1234567890", 0, S("abe")); + test(S("abcde"), 2, 2, "1234567890", 1, S("ab1e")); + test(S("abcde"), 2, 2, "1234567890", 5, S("ab12345e")); + test(S("abcde"), 2, 2, "1234567890", 9, S("ab123456789e")); + test(S("abcde"), 2, 2, "1234567890", 10, S("ab1234567890e")); + test(S("abcde"), 2, 2, "12345678901234567890", 0, S("abe")); + test(S("abcde"), 2, 2, "12345678901234567890", 1, S("ab1e")); + test(S("abcde"), 2, 2, "12345678901234567890", 10, S("ab1234567890e")); + test(S("abcde"), 2, 2, "12345678901234567890", 19, S("ab1234567890123456789e")); + test(S("abcde"), 2, 2, "12345678901234567890", 20, S("ab12345678901234567890e")); + test(S("abcde"), 2, 3, "", 0, S("ab")); + test(S("abcde"), 2, 3, "12345", 0, S("ab")); + test(S("abcde"), 2, 3, "12345", 1, S("ab1")); + test(S("abcde"), 2, 3, "12345", 2, S("ab12")); + test(S("abcde"), 2, 3, "12345", 4, S("ab1234")); + test(S("abcde"), 2, 3, "12345", 5, S("ab12345")); + test(S("abcde"), 2, 3, "1234567890", 0, S("ab")); + test(S("abcde"), 2, 3, "1234567890", 1, S("ab1")); + test(S("abcde"), 2, 3, "1234567890", 5, S("ab12345")); + test(S("abcde"), 2, 3, "1234567890", 9, S("ab123456789")); + test(S("abcde"), 2, 3, "1234567890", 10, S("ab1234567890")); + test(S("abcde"), 2, 3, "12345678901234567890", 0, S("ab")); + test(S("abcde"), 2, 3, "12345678901234567890", 1, S("ab1")); + test(S("abcde"), 2, 3, "12345678901234567890", 10, S("ab1234567890")); + test(S("abcde"), 2, 3, "12345678901234567890", 19, S("ab1234567890123456789")); + test(S("abcde"), 2, 3, "12345678901234567890", 20, S("ab12345678901234567890")); + test(S("abcde"), 4, 0, "", 0, S("abcde")); + test(S("abcde"), 4, 0, "12345", 0, S("abcde")); + test(S("abcde"), 4, 0, "12345", 1, S("abcd1e")); + test(S("abcde"), 4, 0, "12345", 2, S("abcd12e")); + test(S("abcde"), 4, 0, "12345", 4, S("abcd1234e")); + test(S("abcde"), 4, 0, "12345", 5, S("abcd12345e")); + test(S("abcde"), 4, 0, "1234567890", 0, S("abcde")); + test(S("abcde"), 4, 0, "1234567890", 1, S("abcd1e")); + test(S("abcde"), 4, 0, "1234567890", 5, S("abcd12345e")); + test(S("abcde"), 4, 0, "1234567890", 9, S("abcd123456789e")); + test(S("abcde"), 4, 0, "1234567890", 10, S("abcd1234567890e")); + test(S("abcde"), 4, 0, "12345678901234567890", 0, S("abcde")); + test(S("abcde"), 4, 0, "12345678901234567890", 1, S("abcd1e")); + test(S("abcde"), 4, 0, "12345678901234567890", 10, S("abcd1234567890e")); + test(S("abcde"), 4, 0, "12345678901234567890", 19, S("abcd1234567890123456789e")); + test(S("abcde"), 4, 0, "12345678901234567890", 20, S("abcd12345678901234567890e")); + test(S("abcde"), 4, 1, "", 0, S("abcd")); + test(S("abcde"), 4, 1, "12345", 0, S("abcd")); + test(S("abcde"), 4, 1, "12345", 1, S("abcd1")); + test(S("abcde"), 4, 1, "12345", 2, S("abcd12")); + test(S("abcde"), 4, 1, "12345", 4, S("abcd1234")); + test(S("abcde"), 4, 1, "12345", 5, S("abcd12345")); + test(S("abcde"), 4, 1, "1234567890", 0, S("abcd")); + test(S("abcde"), 4, 1, "1234567890", 1, S("abcd1")); + test(S("abcde"), 4, 1, "1234567890", 5, S("abcd12345")); + test(S("abcde"), 4, 1, "1234567890", 9, S("abcd123456789")); + test(S("abcde"), 4, 1, "1234567890", 10, S("abcd1234567890")); + test(S("abcde"), 4, 1, "12345678901234567890", 0, S("abcd")); + test(S("abcde"), 4, 1, "12345678901234567890", 1, S("abcd1")); + test(S("abcde"), 4, 1, "12345678901234567890", 10, S("abcd1234567890")); + test(S("abcde"), 4, 1, "12345678901234567890", 19, S("abcd1234567890123456789")); + test(S("abcde"), 4, 1, "12345678901234567890", 20, S("abcd12345678901234567890")); + test(S("abcde"), 5, 0, "", 0, S("abcde")); + test(S("abcde"), 5, 0, "12345", 0, S("abcde")); + test(S("abcde"), 5, 0, "12345", 1, S("abcde1")); + test(S("abcde"), 5, 0, "12345", 2, S("abcde12")); + test(S("abcde"), 5, 0, "12345", 4, S("abcde1234")); + test(S("abcde"), 5, 0, "12345", 5, S("abcde12345")); + test(S("abcde"), 5, 0, "1234567890", 0, S("abcde")); + test(S("abcde"), 5, 0, "1234567890", 1, S("abcde1")); + test(S("abcde"), 5, 0, "1234567890", 5, S("abcde12345")); + test(S("abcde"), 5, 0, "1234567890", 9, S("abcde123456789")); + test(S("abcde"), 5, 0, "1234567890", 10, S("abcde1234567890")); + test(S("abcde"), 5, 0, "12345678901234567890", 0, S("abcde")); + test(S("abcde"), 5, 0, "12345678901234567890", 1, S("abcde1")); + test(S("abcde"), 5, 0, "12345678901234567890", 10, S("abcde1234567890")); + test(S("abcde"), 5, 0, "12345678901234567890", 19, S("abcde1234567890123456789")); + test(S("abcde"), 5, 0, "12345678901234567890", 20, S("abcde12345678901234567890")); + test(S("abcdefghij"), 0, 0, "", 0, S("abcdefghij")); + test(S("abcdefghij"), 0, 0, "12345", 0, S("abcdefghij")); + test(S("abcdefghij"), 0, 0, "12345", 1, S("1abcdefghij")); + test(S("abcdefghij"), 0, 0, "12345", 2, S("12abcdefghij")); + test(S("abcdefghij"), 0, 0, "12345", 4, S("1234abcdefghij")); + test(S("abcdefghij"), 0, 0, "12345", 5, S("12345abcdefghij")); + test(S("abcdefghij"), 0, 0, "1234567890", 0, S("abcdefghij")); + test(S("abcdefghij"), 0, 0, "1234567890", 1, S("1abcdefghij")); + test(S("abcdefghij"), 0, 0, "1234567890", 5, S("12345abcdefghij")); + test(S("abcdefghij"), 0, 0, "1234567890", 9, S("123456789abcdefghij")); + test(S("abcdefghij"), 0, 0, "1234567890", 10, S("1234567890abcdefghij")); + test(S("abcdefghij"), 0, 0, "12345678901234567890", 0, S("abcdefghij")); +} + +template +void test3() +{ + test(S("abcdefghij"), 0, 0, "12345678901234567890", 1, S("1abcdefghij")); + test(S("abcdefghij"), 0, 0, "12345678901234567890", 10, S("1234567890abcdefghij")); + test(S("abcdefghij"), 0, 0, "12345678901234567890", 19, S("1234567890123456789abcdefghij")); + test(S("abcdefghij"), 0, 0, "12345678901234567890", 20, S("12345678901234567890abcdefghij")); + test(S("abcdefghij"), 0, 1, "", 0, S("bcdefghij")); + test(S("abcdefghij"), 0, 1, "12345", 0, S("bcdefghij")); + test(S("abcdefghij"), 0, 1, "12345", 1, S("1bcdefghij")); + test(S("abcdefghij"), 0, 1, "12345", 2, S("12bcdefghij")); + test(S("abcdefghij"), 0, 1, "12345", 4, S("1234bcdefghij")); + test(S("abcdefghij"), 0, 1, "12345", 5, S("12345bcdefghij")); + test(S("abcdefghij"), 0, 1, "1234567890", 0, S("bcdefghij")); + test(S("abcdefghij"), 0, 1, "1234567890", 1, S("1bcdefghij")); + test(S("abcdefghij"), 0, 1, "1234567890", 5, S("12345bcdefghij")); + test(S("abcdefghij"), 0, 1, "1234567890", 9, S("123456789bcdefghij")); + test(S("abcdefghij"), 0, 1, "1234567890", 10, S("1234567890bcdefghij")); + test(S("abcdefghij"), 0, 1, "12345678901234567890", 0, S("bcdefghij")); + test(S("abcdefghij"), 0, 1, "12345678901234567890", 1, S("1bcdefghij")); + test(S("abcdefghij"), 0, 1, "12345678901234567890", 10, S("1234567890bcdefghij")); + test(S("abcdefghij"), 0, 1, "12345678901234567890", 19, S("1234567890123456789bcdefghij")); + test(S("abcdefghij"), 0, 1, "12345678901234567890", 20, S("12345678901234567890bcdefghij")); + test(S("abcdefghij"), 0, 5, "", 0, S("fghij")); + test(S("abcdefghij"), 0, 5, "12345", 0, S("fghij")); + test(S("abcdefghij"), 0, 5, "12345", 1, S("1fghij")); + test(S("abcdefghij"), 0, 5, "12345", 2, S("12fghij")); + test(S("abcdefghij"), 0, 5, "12345", 4, S("1234fghij")); + test(S("abcdefghij"), 0, 5, "12345", 5, S("12345fghij")); + test(S("abcdefghij"), 0, 5, "1234567890", 0, S("fghij")); + test(S("abcdefghij"), 0, 5, "1234567890", 1, S("1fghij")); + test(S("abcdefghij"), 0, 5, "1234567890", 5, S("12345fghij")); + test(S("abcdefghij"), 0, 5, "1234567890", 9, S("123456789fghij")); + test(S("abcdefghij"), 0, 5, "1234567890", 10, S("1234567890fghij")); + test(S("abcdefghij"), 0, 5, "12345678901234567890", 0, S("fghij")); + test(S("abcdefghij"), 0, 5, "12345678901234567890", 1, S("1fghij")); + test(S("abcdefghij"), 0, 5, "12345678901234567890", 10, S("1234567890fghij")); + test(S("abcdefghij"), 0, 5, "12345678901234567890", 19, S("1234567890123456789fghij")); + test(S("abcdefghij"), 0, 5, "12345678901234567890", 20, S("12345678901234567890fghij")); + test(S("abcdefghij"), 0, 9, "", 0, S("j")); + test(S("abcdefghij"), 0, 9, "12345", 0, S("j")); + test(S("abcdefghij"), 0, 9, "12345", 1, S("1j")); + test(S("abcdefghij"), 0, 9, "12345", 2, S("12j")); + test(S("abcdefghij"), 0, 9, "12345", 4, S("1234j")); + test(S("abcdefghij"), 0, 9, "12345", 5, S("12345j")); + test(S("abcdefghij"), 0, 9, "1234567890", 0, S("j")); + test(S("abcdefghij"), 0, 9, "1234567890", 1, S("1j")); + test(S("abcdefghij"), 0, 9, "1234567890", 5, S("12345j")); + test(S("abcdefghij"), 0, 9, "1234567890", 9, S("123456789j")); + test(S("abcdefghij"), 0, 9, "1234567890", 10, S("1234567890j")); + test(S("abcdefghij"), 0, 9, "12345678901234567890", 0, S("j")); + test(S("abcdefghij"), 0, 9, "12345678901234567890", 1, S("1j")); + test(S("abcdefghij"), 0, 9, "12345678901234567890", 10, S("1234567890j")); + test(S("abcdefghij"), 0, 9, "12345678901234567890", 19, S("1234567890123456789j")); + test(S("abcdefghij"), 0, 9, "12345678901234567890", 20, S("12345678901234567890j")); + test(S("abcdefghij"), 0, 10, "", 0, S("")); + test(S("abcdefghij"), 0, 10, "12345", 0, S("")); + test(S("abcdefghij"), 0, 10, "12345", 1, S("1")); + test(S("abcdefghij"), 0, 10, "12345", 2, S("12")); + test(S("abcdefghij"), 0, 10, "12345", 4, S("1234")); + test(S("abcdefghij"), 0, 10, "12345", 5, S("12345")); + test(S("abcdefghij"), 0, 10, "1234567890", 0, S("")); + test(S("abcdefghij"), 0, 10, "1234567890", 1, S("1")); + test(S("abcdefghij"), 0, 10, "1234567890", 5, S("12345")); + test(S("abcdefghij"), 0, 10, "1234567890", 9, S("123456789")); + test(S("abcdefghij"), 0, 10, "1234567890", 10, S("1234567890")); + test(S("abcdefghij"), 0, 10, "12345678901234567890", 0, S("")); + test(S("abcdefghij"), 0, 10, "12345678901234567890", 1, S("1")); + test(S("abcdefghij"), 0, 10, "12345678901234567890", 10, S("1234567890")); + test(S("abcdefghij"), 0, 10, "12345678901234567890", 19, S("1234567890123456789")); + test(S("abcdefghij"), 0, 10, "12345678901234567890", 20, S("12345678901234567890")); + test(S("abcdefghij"), 1, 0, "", 0, S("abcdefghij")); + test(S("abcdefghij"), 1, 0, "12345", 0, S("abcdefghij")); + test(S("abcdefghij"), 1, 0, "12345", 1, S("a1bcdefghij")); + test(S("abcdefghij"), 1, 0, "12345", 2, S("a12bcdefghij")); + test(S("abcdefghij"), 1, 0, "12345", 4, S("a1234bcdefghij")); + test(S("abcdefghij"), 1, 0, "12345", 5, S("a12345bcdefghij")); + test(S("abcdefghij"), 1, 0, "1234567890", 0, S("abcdefghij")); + test(S("abcdefghij"), 1, 0, "1234567890", 1, S("a1bcdefghij")); + test(S("abcdefghij"), 1, 0, "1234567890", 5, S("a12345bcdefghij")); + test(S("abcdefghij"), 1, 0, "1234567890", 9, S("a123456789bcdefghij")); + test(S("abcdefghij"), 1, 0, "1234567890", 10, S("a1234567890bcdefghij")); + test(S("abcdefghij"), 1, 0, "12345678901234567890", 0, S("abcdefghij")); + test(S("abcdefghij"), 1, 0, "12345678901234567890", 1, S("a1bcdefghij")); + test(S("abcdefghij"), 1, 0, "12345678901234567890", 10, S("a1234567890bcdefghij")); + test(S("abcdefghij"), 1, 0, "12345678901234567890", 19, S("a1234567890123456789bcdefghij")); + test(S("abcdefghij"), 1, 0, "12345678901234567890", 20, S("a12345678901234567890bcdefghij")); + test(S("abcdefghij"), 1, 1, "", 0, S("acdefghij")); + test(S("abcdefghij"), 1, 1, "12345", 0, S("acdefghij")); + test(S("abcdefghij"), 1, 1, "12345", 1, S("a1cdefghij")); + test(S("abcdefghij"), 1, 1, "12345", 2, S("a12cdefghij")); + test(S("abcdefghij"), 1, 1, "12345", 4, S("a1234cdefghij")); + test(S("abcdefghij"), 1, 1, "12345", 5, S("a12345cdefghij")); + test(S("abcdefghij"), 1, 1, "1234567890", 0, S("acdefghij")); + test(S("abcdefghij"), 1, 1, "1234567890", 1, S("a1cdefghij")); + test(S("abcdefghij"), 1, 1, "1234567890", 5, S("a12345cdefghij")); + test(S("abcdefghij"), 1, 1, "1234567890", 9, S("a123456789cdefghij")); + test(S("abcdefghij"), 1, 1, "1234567890", 10, S("a1234567890cdefghij")); + test(S("abcdefghij"), 1, 1, "12345678901234567890", 0, S("acdefghij")); + test(S("abcdefghij"), 1, 1, "12345678901234567890", 1, S("a1cdefghij")); + test(S("abcdefghij"), 1, 1, "12345678901234567890", 10, S("a1234567890cdefghij")); + test(S("abcdefghij"), 1, 1, "12345678901234567890", 19, S("a1234567890123456789cdefghij")); + test(S("abcdefghij"), 1, 1, "12345678901234567890", 20, S("a12345678901234567890cdefghij")); +} + +template +void test4() +{ + test(S("abcdefghij"), 1, 4, "", 0, S("afghij")); + test(S("abcdefghij"), 1, 4, "12345", 0, S("afghij")); + test(S("abcdefghij"), 1, 4, "12345", 1, S("a1fghij")); + test(S("abcdefghij"), 1, 4, "12345", 2, S("a12fghij")); + test(S("abcdefghij"), 1, 4, "12345", 4, S("a1234fghij")); + test(S("abcdefghij"), 1, 4, "12345", 5, S("a12345fghij")); + test(S("abcdefghij"), 1, 4, "1234567890", 0, S("afghij")); + test(S("abcdefghij"), 1, 4, "1234567890", 1, S("a1fghij")); + test(S("abcdefghij"), 1, 4, "1234567890", 5, S("a12345fghij")); + test(S("abcdefghij"), 1, 4, "1234567890", 9, S("a123456789fghij")); + test(S("abcdefghij"), 1, 4, "1234567890", 10, S("a1234567890fghij")); + test(S("abcdefghij"), 1, 4, "12345678901234567890", 0, S("afghij")); + test(S("abcdefghij"), 1, 4, "12345678901234567890", 1, S("a1fghij")); + test(S("abcdefghij"), 1, 4, "12345678901234567890", 10, S("a1234567890fghij")); + test(S("abcdefghij"), 1, 4, "12345678901234567890", 19, S("a1234567890123456789fghij")); + test(S("abcdefghij"), 1, 4, "12345678901234567890", 20, S("a12345678901234567890fghij")); + test(S("abcdefghij"), 1, 8, "", 0, S("aj")); + test(S("abcdefghij"), 1, 8, "12345", 0, S("aj")); + test(S("abcdefghij"), 1, 8, "12345", 1, S("a1j")); + test(S("abcdefghij"), 1, 8, "12345", 2, S("a12j")); + test(S("abcdefghij"), 1, 8, "12345", 4, S("a1234j")); + test(S("abcdefghij"), 1, 8, "12345", 5, S("a12345j")); + test(S("abcdefghij"), 1, 8, "1234567890", 0, S("aj")); + test(S("abcdefghij"), 1, 8, "1234567890", 1, S("a1j")); + test(S("abcdefghij"), 1, 8, "1234567890", 5, S("a12345j")); + test(S("abcdefghij"), 1, 8, "1234567890", 9, S("a123456789j")); + test(S("abcdefghij"), 1, 8, "1234567890", 10, S("a1234567890j")); + test(S("abcdefghij"), 1, 8, "12345678901234567890", 0, S("aj")); + test(S("abcdefghij"), 1, 8, "12345678901234567890", 1, S("a1j")); + test(S("abcdefghij"), 1, 8, "12345678901234567890", 10, S("a1234567890j")); + test(S("abcdefghij"), 1, 8, "12345678901234567890", 19, S("a1234567890123456789j")); + test(S("abcdefghij"), 1, 8, "12345678901234567890", 20, S("a12345678901234567890j")); + test(S("abcdefghij"), 1, 9, "", 0, S("a")); + test(S("abcdefghij"), 1, 9, "12345", 0, S("a")); + test(S("abcdefghij"), 1, 9, "12345", 1, S("a1")); + test(S("abcdefghij"), 1, 9, "12345", 2, S("a12")); + test(S("abcdefghij"), 1, 9, "12345", 4, S("a1234")); + test(S("abcdefghij"), 1, 9, "12345", 5, S("a12345")); + test(S("abcdefghij"), 1, 9, "1234567890", 0, S("a")); + test(S("abcdefghij"), 1, 9, "1234567890", 1, S("a1")); + test(S("abcdefghij"), 1, 9, "1234567890", 5, S("a12345")); + test(S("abcdefghij"), 1, 9, "1234567890", 9, S("a123456789")); + test(S("abcdefghij"), 1, 9, "1234567890", 10, S("a1234567890")); + test(S("abcdefghij"), 1, 9, "12345678901234567890", 0, S("a")); + test(S("abcdefghij"), 1, 9, "12345678901234567890", 1, S("a1")); + test(S("abcdefghij"), 1, 9, "12345678901234567890", 10, S("a1234567890")); + test(S("abcdefghij"), 1, 9, "12345678901234567890", 19, S("a1234567890123456789")); + test(S("abcdefghij"), 1, 9, "12345678901234567890", 20, S("a12345678901234567890")); + test(S("abcdefghij"), 5, 0, "", 0, S("abcdefghij")); + test(S("abcdefghij"), 5, 0, "12345", 0, S("abcdefghij")); + test(S("abcdefghij"), 5, 0, "12345", 1, S("abcde1fghij")); + test(S("abcdefghij"), 5, 0, "12345", 2, S("abcde12fghij")); + test(S("abcdefghij"), 5, 0, "12345", 4, S("abcde1234fghij")); + test(S("abcdefghij"), 5, 0, "12345", 5, S("abcde12345fghij")); + test(S("abcdefghij"), 5, 0, "1234567890", 0, S("abcdefghij")); + test(S("abcdefghij"), 5, 0, "1234567890", 1, S("abcde1fghij")); + test(S("abcdefghij"), 5, 0, "1234567890", 5, S("abcde12345fghij")); + test(S("abcdefghij"), 5, 0, "1234567890", 9, S("abcde123456789fghij")); + test(S("abcdefghij"), 5, 0, "1234567890", 10, S("abcde1234567890fghij")); + test(S("abcdefghij"), 5, 0, "12345678901234567890", 0, S("abcdefghij")); + test(S("abcdefghij"), 5, 0, "12345678901234567890", 1, S("abcde1fghij")); + test(S("abcdefghij"), 5, 0, "12345678901234567890", 10, S("abcde1234567890fghij")); + test(S("abcdefghij"), 5, 0, "12345678901234567890", 19, S("abcde1234567890123456789fghij")); + test(S("abcdefghij"), 5, 0, "12345678901234567890", 20, S("abcde12345678901234567890fghij")); + test(S("abcdefghij"), 5, 1, "", 0, S("abcdeghij")); + test(S("abcdefghij"), 5, 1, "12345", 0, S("abcdeghij")); + test(S("abcdefghij"), 5, 1, "12345", 1, S("abcde1ghij")); + test(S("abcdefghij"), 5, 1, "12345", 2, S("abcde12ghij")); + test(S("abcdefghij"), 5, 1, "12345", 4, S("abcde1234ghij")); + test(S("abcdefghij"), 5, 1, "12345", 5, S("abcde12345ghij")); + test(S("abcdefghij"), 5, 1, "1234567890", 0, S("abcdeghij")); + test(S("abcdefghij"), 5, 1, "1234567890", 1, S("abcde1ghij")); + test(S("abcdefghij"), 5, 1, "1234567890", 5, S("abcde12345ghij")); + test(S("abcdefghij"), 5, 1, "1234567890", 9, S("abcde123456789ghij")); + test(S("abcdefghij"), 5, 1, "1234567890", 10, S("abcde1234567890ghij")); + test(S("abcdefghij"), 5, 1, "12345678901234567890", 0, S("abcdeghij")); + test(S("abcdefghij"), 5, 1, "12345678901234567890", 1, S("abcde1ghij")); + test(S("abcdefghij"), 5, 1, "12345678901234567890", 10, S("abcde1234567890ghij")); + test(S("abcdefghij"), 5, 1, "12345678901234567890", 19, S("abcde1234567890123456789ghij")); + test(S("abcdefghij"), 5, 1, "12345678901234567890", 20, S("abcde12345678901234567890ghij")); + test(S("abcdefghij"), 5, 2, "", 0, S("abcdehij")); + test(S("abcdefghij"), 5, 2, "12345", 0, S("abcdehij")); + test(S("abcdefghij"), 5, 2, "12345", 1, S("abcde1hij")); + test(S("abcdefghij"), 5, 2, "12345", 2, S("abcde12hij")); + test(S("abcdefghij"), 5, 2, "12345", 4, S("abcde1234hij")); + test(S("abcdefghij"), 5, 2, "12345", 5, S("abcde12345hij")); + test(S("abcdefghij"), 5, 2, "1234567890", 0, S("abcdehij")); + test(S("abcdefghij"), 5, 2, "1234567890", 1, S("abcde1hij")); + test(S("abcdefghij"), 5, 2, "1234567890", 5, S("abcde12345hij")); + test(S("abcdefghij"), 5, 2, "1234567890", 9, S("abcde123456789hij")); + test(S("abcdefghij"), 5, 2, "1234567890", 10, S("abcde1234567890hij")); + test(S("abcdefghij"), 5, 2, "12345678901234567890", 0, S("abcdehij")); + test(S("abcdefghij"), 5, 2, "12345678901234567890", 1, S("abcde1hij")); + test(S("abcdefghij"), 5, 2, "12345678901234567890", 10, S("abcde1234567890hij")); + test(S("abcdefghij"), 5, 2, "12345678901234567890", 19, S("abcde1234567890123456789hij")); + test(S("abcdefghij"), 5, 2, "12345678901234567890", 20, S("abcde12345678901234567890hij")); + test(S("abcdefghij"), 5, 4, "", 0, S("abcdej")); + test(S("abcdefghij"), 5, 4, "12345", 0, S("abcdej")); + test(S("abcdefghij"), 5, 4, "12345", 1, S("abcde1j")); + test(S("abcdefghij"), 5, 4, "12345", 2, S("abcde12j")); +} + +template +void test5() +{ + test(S("abcdefghij"), 5, 4, "12345", 4, S("abcde1234j")); + test(S("abcdefghij"), 5, 4, "12345", 5, S("abcde12345j")); + test(S("abcdefghij"), 5, 4, "1234567890", 0, S("abcdej")); + test(S("abcdefghij"), 5, 4, "1234567890", 1, S("abcde1j")); + test(S("abcdefghij"), 5, 4, "1234567890", 5, S("abcde12345j")); + test(S("abcdefghij"), 5, 4, "1234567890", 9, S("abcde123456789j")); + test(S("abcdefghij"), 5, 4, "1234567890", 10, S("abcde1234567890j")); + test(S("abcdefghij"), 5, 4, "12345678901234567890", 0, S("abcdej")); + test(S("abcdefghij"), 5, 4, "12345678901234567890", 1, S("abcde1j")); + test(S("abcdefghij"), 5, 4, "12345678901234567890", 10, S("abcde1234567890j")); + test(S("abcdefghij"), 5, 4, "12345678901234567890", 19, S("abcde1234567890123456789j")); + test(S("abcdefghij"), 5, 4, "12345678901234567890", 20, S("abcde12345678901234567890j")); + test(S("abcdefghij"), 5, 5, "", 0, S("abcde")); + test(S("abcdefghij"), 5, 5, "12345", 0, S("abcde")); + test(S("abcdefghij"), 5, 5, "12345", 1, S("abcde1")); + test(S("abcdefghij"), 5, 5, "12345", 2, S("abcde12")); + test(S("abcdefghij"), 5, 5, "12345", 4, S("abcde1234")); + test(S("abcdefghij"), 5, 5, "12345", 5, S("abcde12345")); + test(S("abcdefghij"), 5, 5, "1234567890", 0, S("abcde")); + test(S("abcdefghij"), 5, 5, "1234567890", 1, S("abcde1")); + test(S("abcdefghij"), 5, 5, "1234567890", 5, S("abcde12345")); + test(S("abcdefghij"), 5, 5, "1234567890", 9, S("abcde123456789")); + test(S("abcdefghij"), 5, 5, "1234567890", 10, S("abcde1234567890")); + test(S("abcdefghij"), 5, 5, "12345678901234567890", 0, S("abcde")); + test(S("abcdefghij"), 5, 5, "12345678901234567890", 1, S("abcde1")); + test(S("abcdefghij"), 5, 5, "12345678901234567890", 10, S("abcde1234567890")); + test(S("abcdefghij"), 5, 5, "12345678901234567890", 19, S("abcde1234567890123456789")); + test(S("abcdefghij"), 5, 5, "12345678901234567890", 20, S("abcde12345678901234567890")); + test(S("abcdefghij"), 9, 0, "", 0, S("abcdefghij")); + test(S("abcdefghij"), 9, 0, "12345", 0, S("abcdefghij")); + test(S("abcdefghij"), 9, 0, "12345", 1, S("abcdefghi1j")); + test(S("abcdefghij"), 9, 0, "12345", 2, S("abcdefghi12j")); + test(S("abcdefghij"), 9, 0, "12345", 4, S("abcdefghi1234j")); + test(S("abcdefghij"), 9, 0, "12345", 5, S("abcdefghi12345j")); + test(S("abcdefghij"), 9, 0, "1234567890", 0, S("abcdefghij")); + test(S("abcdefghij"), 9, 0, "1234567890", 1, S("abcdefghi1j")); + test(S("abcdefghij"), 9, 0, "1234567890", 5, S("abcdefghi12345j")); + test(S("abcdefghij"), 9, 0, "1234567890", 9, S("abcdefghi123456789j")); + test(S("abcdefghij"), 9, 0, "1234567890", 10, S("abcdefghi1234567890j")); + test(S("abcdefghij"), 9, 0, "12345678901234567890", 0, S("abcdefghij")); + test(S("abcdefghij"), 9, 0, "12345678901234567890", 1, S("abcdefghi1j")); + test(S("abcdefghij"), 9, 0, "12345678901234567890", 10, S("abcdefghi1234567890j")); + test(S("abcdefghij"), 9, 0, "12345678901234567890", 19, S("abcdefghi1234567890123456789j")); + test(S("abcdefghij"), 9, 0, "12345678901234567890", 20, S("abcdefghi12345678901234567890j")); + test(S("abcdefghij"), 9, 1, "", 0, S("abcdefghi")); + test(S("abcdefghij"), 9, 1, "12345", 0, S("abcdefghi")); + test(S("abcdefghij"), 9, 1, "12345", 1, S("abcdefghi1")); + test(S("abcdefghij"), 9, 1, "12345", 2, S("abcdefghi12")); + test(S("abcdefghij"), 9, 1, "12345", 4, S("abcdefghi1234")); + test(S("abcdefghij"), 9, 1, "12345", 5, S("abcdefghi12345")); + test(S("abcdefghij"), 9, 1, "1234567890", 0, S("abcdefghi")); + test(S("abcdefghij"), 9, 1, "1234567890", 1, S("abcdefghi1")); + test(S("abcdefghij"), 9, 1, "1234567890", 5, S("abcdefghi12345")); + test(S("abcdefghij"), 9, 1, "1234567890", 9, S("abcdefghi123456789")); + test(S("abcdefghij"), 9, 1, "1234567890", 10, S("abcdefghi1234567890")); + test(S("abcdefghij"), 9, 1, "12345678901234567890", 0, S("abcdefghi")); + test(S("abcdefghij"), 9, 1, "12345678901234567890", 1, S("abcdefghi1")); + test(S("abcdefghij"), 9, 1, "12345678901234567890", 10, S("abcdefghi1234567890")); + test(S("abcdefghij"), 9, 1, "12345678901234567890", 19, S("abcdefghi1234567890123456789")); + test(S("abcdefghij"), 9, 1, "12345678901234567890", 20, S("abcdefghi12345678901234567890")); + test(S("abcdefghij"), 10, 0, "", 0, S("abcdefghij")); + test(S("abcdefghij"), 10, 0, "12345", 0, S("abcdefghij")); + test(S("abcdefghij"), 10, 0, "12345", 1, S("abcdefghij1")); + test(S("abcdefghij"), 10, 0, "12345", 2, S("abcdefghij12")); + test(S("abcdefghij"), 10, 0, "12345", 4, S("abcdefghij1234")); + test(S("abcdefghij"), 10, 0, "12345", 5, S("abcdefghij12345")); + test(S("abcdefghij"), 10, 0, "1234567890", 0, S("abcdefghij")); + test(S("abcdefghij"), 10, 0, "1234567890", 1, S("abcdefghij1")); + test(S("abcdefghij"), 10, 0, "1234567890", 5, S("abcdefghij12345")); + test(S("abcdefghij"), 10, 0, "1234567890", 9, S("abcdefghij123456789")); + test(S("abcdefghij"), 10, 0, "1234567890", 10, S("abcdefghij1234567890")); + test(S("abcdefghij"), 10, 0, "12345678901234567890", 0, S("abcdefghij")); + test(S("abcdefghij"), 10, 0, "12345678901234567890", 1, S("abcdefghij1")); + test(S("abcdefghij"), 10, 0, "12345678901234567890", 10, S("abcdefghij1234567890")); + test(S("abcdefghij"), 10, 0, "12345678901234567890", 19, S("abcdefghij1234567890123456789")); + test(S("abcdefghij"), 10, 0, "12345678901234567890", 20, S("abcdefghij12345678901234567890")); + test(S("abcdefghijklmnopqrst"), 0, 0, "", 0, S("abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, 0, "12345", 0, S("abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, 0, "12345", 1, S("1abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, 0, "12345", 2, S("12abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, 0, "12345", 4, S("1234abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, 0, "12345", 5, S("12345abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, 0, "1234567890", 0, S("abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, 0, "1234567890", 1, S("1abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, 0, "1234567890", 5, S("12345abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, 0, "1234567890", 9, S("123456789abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, 0, "1234567890", 10, S("1234567890abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, 0, "12345678901234567890", 0, S("abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, 0, "12345678901234567890", 1, S("1abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, 0, "12345678901234567890", 10, S("1234567890abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, 0, "12345678901234567890", 19, S("1234567890123456789abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, 0, "12345678901234567890", 20, S("12345678901234567890abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, 1, "", 0, S("bcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, 1, "12345", 0, S("bcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, 1, "12345", 1, S("1bcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, 1, "12345", 2, S("12bcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, 1, "12345", 4, S("1234bcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, 1, "12345", 5, S("12345bcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, 1, "1234567890", 0, S("bcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, 1, "1234567890", 1, S("1bcdefghijklmnopqrst")); +} + +template +void test6() +{ + test(S("abcdefghijklmnopqrst"), 0, 1, "1234567890", 5, S("12345bcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, 1, "1234567890", 9, S("123456789bcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, 1, "1234567890", 10, S("1234567890bcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, 1, "12345678901234567890", 0, S("bcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, 1, "12345678901234567890", 1, S("1bcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, 1, "12345678901234567890", 10, S("1234567890bcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, 1, "12345678901234567890", 19, S("1234567890123456789bcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, 1, "12345678901234567890", 20, S("12345678901234567890bcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, 10, "", 0, S("klmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, 10, "12345", 0, S("klmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, 10, "12345", 1, S("1klmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, 10, "12345", 2, S("12klmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, 10, "12345", 4, S("1234klmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, 10, "12345", 5, S("12345klmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, 10, "1234567890", 0, S("klmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, 10, "1234567890", 1, S("1klmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, 10, "1234567890", 5, S("12345klmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, 10, "1234567890", 9, S("123456789klmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, 10, "1234567890", 10, S("1234567890klmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, 10, "12345678901234567890", 0, S("klmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, 10, "12345678901234567890", 1, S("1klmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, 10, "12345678901234567890", 10, S("1234567890klmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, 10, "12345678901234567890", 19, S("1234567890123456789klmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, 10, "12345678901234567890", 20, S("12345678901234567890klmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, 19, "", 0, S("t")); + test(S("abcdefghijklmnopqrst"), 0, 19, "12345", 0, S("t")); + test(S("abcdefghijklmnopqrst"), 0, 19, "12345", 1, S("1t")); + test(S("abcdefghijklmnopqrst"), 0, 19, "12345", 2, S("12t")); + test(S("abcdefghijklmnopqrst"), 0, 19, "12345", 4, S("1234t")); + test(S("abcdefghijklmnopqrst"), 0, 19, "12345", 5, S("12345t")); + test(S("abcdefghijklmnopqrst"), 0, 19, "1234567890", 0, S("t")); + test(S("abcdefghijklmnopqrst"), 0, 19, "1234567890", 1, S("1t")); + test(S("abcdefghijklmnopqrst"), 0, 19, "1234567890", 5, S("12345t")); + test(S("abcdefghijklmnopqrst"), 0, 19, "1234567890", 9, S("123456789t")); + test(S("abcdefghijklmnopqrst"), 0, 19, "1234567890", 10, S("1234567890t")); + test(S("abcdefghijklmnopqrst"), 0, 19, "12345678901234567890", 0, S("t")); + test(S("abcdefghijklmnopqrst"), 0, 19, "12345678901234567890", 1, S("1t")); + test(S("abcdefghijklmnopqrst"), 0, 19, "12345678901234567890", 10, S("1234567890t")); + test(S("abcdefghijklmnopqrst"), 0, 19, "12345678901234567890", 19, S("1234567890123456789t")); + test(S("abcdefghijklmnopqrst"), 0, 19, "12345678901234567890", 20, S("12345678901234567890t")); + test(S("abcdefghijklmnopqrst"), 0, 20, "", 0, S("")); + test(S("abcdefghijklmnopqrst"), 0, 20, "12345", 0, S("")); + test(S("abcdefghijklmnopqrst"), 0, 20, "12345", 1, S("1")); + test(S("abcdefghijklmnopqrst"), 0, 20, "12345", 2, S("12")); + test(S("abcdefghijklmnopqrst"), 0, 20, "12345", 4, S("1234")); + test(S("abcdefghijklmnopqrst"), 0, 20, "12345", 5, S("12345")); + test(S("abcdefghijklmnopqrst"), 0, 20, "1234567890", 0, S("")); + test(S("abcdefghijklmnopqrst"), 0, 20, "1234567890", 1, S("1")); + test(S("abcdefghijklmnopqrst"), 0, 20, "1234567890", 5, S("12345")); + test(S("abcdefghijklmnopqrst"), 0, 20, "1234567890", 9, S("123456789")); + test(S("abcdefghijklmnopqrst"), 0, 20, "1234567890", 10, S("1234567890")); + test(S("abcdefghijklmnopqrst"), 0, 20, "12345678901234567890", 0, S("")); + test(S("abcdefghijklmnopqrst"), 0, 20, "12345678901234567890", 1, S("1")); + test(S("abcdefghijklmnopqrst"), 0, 20, "12345678901234567890", 10, S("1234567890")); + test(S("abcdefghijklmnopqrst"), 0, 20, "12345678901234567890", 19, S("1234567890123456789")); + test(S("abcdefghijklmnopqrst"), 0, 20, "12345678901234567890", 20, S("12345678901234567890")); + test(S("abcdefghijklmnopqrst"), 1, 0, "", 0, S("abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, 0, "12345", 0, S("abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, 0, "12345", 1, S("a1bcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, 0, "12345", 2, S("a12bcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, 0, "12345", 4, S("a1234bcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, 0, "12345", 5, S("a12345bcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, 0, "1234567890", 0, S("abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, 0, "1234567890", 1, S("a1bcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, 0, "1234567890", 5, S("a12345bcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, 0, "1234567890", 9, S("a123456789bcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, 0, "1234567890", 10, S("a1234567890bcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, 0, "12345678901234567890", 0, S("abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, 0, "12345678901234567890", 1, S("a1bcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, 0, "12345678901234567890", 10, S("a1234567890bcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, 0, "12345678901234567890", 19, S("a1234567890123456789bcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, 0, "12345678901234567890", 20, S("a12345678901234567890bcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, 1, "", 0, S("acdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, 1, "12345", 0, S("acdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, 1, "12345", 1, S("a1cdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, 1, "12345", 2, S("a12cdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, 1, "12345", 4, S("a1234cdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, 1, "12345", 5, S("a12345cdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, 1, "1234567890", 0, S("acdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, 1, "1234567890", 1, S("a1cdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, 1, "1234567890", 5, S("a12345cdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, 1, "1234567890", 9, S("a123456789cdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, 1, "1234567890", 10, S("a1234567890cdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, 1, "12345678901234567890", 0, S("acdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, 1, "12345678901234567890", 1, S("a1cdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, 1, "12345678901234567890", 10, S("a1234567890cdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, 1, "12345678901234567890", 19, S("a1234567890123456789cdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, 1, "12345678901234567890", 20, S("a12345678901234567890cdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, 9, "", 0, S("aklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, 9, "12345", 0, S("aklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, 9, "12345", 1, S("a1klmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, 9, "12345", 2, S("a12klmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, 9, "12345", 4, S("a1234klmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, 9, "12345", 5, S("a12345klmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, 9, "1234567890", 0, S("aklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, 9, "1234567890", 1, S("a1klmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, 9, "1234567890", 5, S("a12345klmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, 9, "1234567890", 9, S("a123456789klmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, 9, "1234567890", 10, S("a1234567890klmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, 9, "12345678901234567890", 0, S("aklmnopqrst")); +} + +template +void test7() +{ + test(S("abcdefghijklmnopqrst"), 1, 9, "12345678901234567890", 1, S("a1klmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, 9, "12345678901234567890", 10, S("a1234567890klmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, 9, "12345678901234567890", 19, S("a1234567890123456789klmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, 9, "12345678901234567890", 20, S("a12345678901234567890klmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, 18, "", 0, S("at")); + test(S("abcdefghijklmnopqrst"), 1, 18, "12345", 0, S("at")); + test(S("abcdefghijklmnopqrst"), 1, 18, "12345", 1, S("a1t")); + test(S("abcdefghijklmnopqrst"), 1, 18, "12345", 2, S("a12t")); + test(S("abcdefghijklmnopqrst"), 1, 18, "12345", 4, S("a1234t")); + test(S("abcdefghijklmnopqrst"), 1, 18, "12345", 5, S("a12345t")); + test(S("abcdefghijklmnopqrst"), 1, 18, "1234567890", 0, S("at")); + test(S("abcdefghijklmnopqrst"), 1, 18, "1234567890", 1, S("a1t")); + test(S("abcdefghijklmnopqrst"), 1, 18, "1234567890", 5, S("a12345t")); + test(S("abcdefghijklmnopqrst"), 1, 18, "1234567890", 9, S("a123456789t")); + test(S("abcdefghijklmnopqrst"), 1, 18, "1234567890", 10, S("a1234567890t")); + test(S("abcdefghijklmnopqrst"), 1, 18, "12345678901234567890", 0, S("at")); + test(S("abcdefghijklmnopqrst"), 1, 18, "12345678901234567890", 1, S("a1t")); + test(S("abcdefghijklmnopqrst"), 1, 18, "12345678901234567890", 10, S("a1234567890t")); + test(S("abcdefghijklmnopqrst"), 1, 18, "12345678901234567890", 19, S("a1234567890123456789t")); + test(S("abcdefghijklmnopqrst"), 1, 18, "12345678901234567890", 20, S("a12345678901234567890t")); + test(S("abcdefghijklmnopqrst"), 1, 19, "", 0, S("a")); + test(S("abcdefghijklmnopqrst"), 1, 19, "12345", 0, S("a")); + test(S("abcdefghijklmnopqrst"), 1, 19, "12345", 1, S("a1")); + test(S("abcdefghijklmnopqrst"), 1, 19, "12345", 2, S("a12")); + test(S("abcdefghijklmnopqrst"), 1, 19, "12345", 4, S("a1234")); + test(S("abcdefghijklmnopqrst"), 1, 19, "12345", 5, S("a12345")); + test(S("abcdefghijklmnopqrst"), 1, 19, "1234567890", 0, S("a")); + test(S("abcdefghijklmnopqrst"), 1, 19, "1234567890", 1, S("a1")); + test(S("abcdefghijklmnopqrst"), 1, 19, "1234567890", 5, S("a12345")); + test(S("abcdefghijklmnopqrst"), 1, 19, "1234567890", 9, S("a123456789")); + test(S("abcdefghijklmnopqrst"), 1, 19, "1234567890", 10, S("a1234567890")); + test(S("abcdefghijklmnopqrst"), 1, 19, "12345678901234567890", 0, S("a")); + test(S("abcdefghijklmnopqrst"), 1, 19, "12345678901234567890", 1, S("a1")); + test(S("abcdefghijklmnopqrst"), 1, 19, "12345678901234567890", 10, S("a1234567890")); + test(S("abcdefghijklmnopqrst"), 1, 19, "12345678901234567890", 19, S("a1234567890123456789")); + test(S("abcdefghijklmnopqrst"), 1, 19, "12345678901234567890", 20, S("a12345678901234567890")); + test(S("abcdefghijklmnopqrst"), 10, 0, "", 0, S("abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 10, 0, "12345", 0, S("abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 10, 0, "12345", 1, S("abcdefghij1klmnopqrst")); + test(S("abcdefghijklmnopqrst"), 10, 0, "12345", 2, S("abcdefghij12klmnopqrst")); + test(S("abcdefghijklmnopqrst"), 10, 0, "12345", 4, S("abcdefghij1234klmnopqrst")); + test(S("abcdefghijklmnopqrst"), 10, 0, "12345", 5, S("abcdefghij12345klmnopqrst")); + test(S("abcdefghijklmnopqrst"), 10, 0, "1234567890", 0, S("abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 10, 0, "1234567890", 1, S("abcdefghij1klmnopqrst")); + test(S("abcdefghijklmnopqrst"), 10, 0, "1234567890", 5, S("abcdefghij12345klmnopqrst")); + test(S("abcdefghijklmnopqrst"), 10, 0, "1234567890", 9, S("abcdefghij123456789klmnopqrst")); + test(S("abcdefghijklmnopqrst"), 10, 0, "1234567890", 10, S("abcdefghij1234567890klmnopqrst")); + test(S("abcdefghijklmnopqrst"), 10, 0, "12345678901234567890", 0, S("abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 10, 0, "12345678901234567890", 1, S("abcdefghij1klmnopqrst")); + test(S("abcdefghijklmnopqrst"), 10, 0, "12345678901234567890", 10, S("abcdefghij1234567890klmnopqrst")); + test(S("abcdefghijklmnopqrst"), 10, 0, "12345678901234567890", 19, S("abcdefghij1234567890123456789klmnopqrst")); + test(S("abcdefghijklmnopqrst"), 10, 0, "12345678901234567890", 20, S("abcdefghij12345678901234567890klmnopqrst")); + test(S("abcdefghijklmnopqrst"), 10, 1, "", 0, S("abcdefghijlmnopqrst")); + test(S("abcdefghijklmnopqrst"), 10, 1, "12345", 0, S("abcdefghijlmnopqrst")); + test(S("abcdefghijklmnopqrst"), 10, 1, "12345", 1, S("abcdefghij1lmnopqrst")); + test(S("abcdefghijklmnopqrst"), 10, 1, "12345", 2, S("abcdefghij12lmnopqrst")); + test(S("abcdefghijklmnopqrst"), 10, 1, "12345", 4, S("abcdefghij1234lmnopqrst")); + test(S("abcdefghijklmnopqrst"), 10, 1, "12345", 5, S("abcdefghij12345lmnopqrst")); + test(S("abcdefghijklmnopqrst"), 10, 1, "1234567890", 0, S("abcdefghijlmnopqrst")); + test(S("abcdefghijklmnopqrst"), 10, 1, "1234567890", 1, S("abcdefghij1lmnopqrst")); + test(S("abcdefghijklmnopqrst"), 10, 1, "1234567890", 5, S("abcdefghij12345lmnopqrst")); + test(S("abcdefghijklmnopqrst"), 10, 1, "1234567890", 9, S("abcdefghij123456789lmnopqrst")); + test(S("abcdefghijklmnopqrst"), 10, 1, "1234567890", 10, S("abcdefghij1234567890lmnopqrst")); + test(S("abcdefghijklmnopqrst"), 10, 1, "12345678901234567890", 0, S("abcdefghijlmnopqrst")); + test(S("abcdefghijklmnopqrst"), 10, 1, "12345678901234567890", 1, S("abcdefghij1lmnopqrst")); + test(S("abcdefghijklmnopqrst"), 10, 1, "12345678901234567890", 10, S("abcdefghij1234567890lmnopqrst")); + test(S("abcdefghijklmnopqrst"), 10, 1, "12345678901234567890", 19, S("abcdefghij1234567890123456789lmnopqrst")); + test(S("abcdefghijklmnopqrst"), 10, 1, "12345678901234567890", 20, S("abcdefghij12345678901234567890lmnopqrst")); + test(S("abcdefghijklmnopqrst"), 10, 5, "", 0, S("abcdefghijpqrst")); + test(S("abcdefghijklmnopqrst"), 10, 5, "12345", 0, S("abcdefghijpqrst")); + test(S("abcdefghijklmnopqrst"), 10, 5, "12345", 1, S("abcdefghij1pqrst")); + test(S("abcdefghijklmnopqrst"), 10, 5, "12345", 2, S("abcdefghij12pqrst")); + test(S("abcdefghijklmnopqrst"), 10, 5, "12345", 4, S("abcdefghij1234pqrst")); + test(S("abcdefghijklmnopqrst"), 10, 5, "12345", 5, S("abcdefghij12345pqrst")); + test(S("abcdefghijklmnopqrst"), 10, 5, "1234567890", 0, S("abcdefghijpqrst")); + test(S("abcdefghijklmnopqrst"), 10, 5, "1234567890", 1, S("abcdefghij1pqrst")); + test(S("abcdefghijklmnopqrst"), 10, 5, "1234567890", 5, S("abcdefghij12345pqrst")); + test(S("abcdefghijklmnopqrst"), 10, 5, "1234567890", 9, S("abcdefghij123456789pqrst")); + test(S("abcdefghijklmnopqrst"), 10, 5, "1234567890", 10, S("abcdefghij1234567890pqrst")); + test(S("abcdefghijklmnopqrst"), 10, 5, "12345678901234567890", 0, S("abcdefghijpqrst")); + test(S("abcdefghijklmnopqrst"), 10, 5, "12345678901234567890", 1, S("abcdefghij1pqrst")); + test(S("abcdefghijklmnopqrst"), 10, 5, "12345678901234567890", 10, S("abcdefghij1234567890pqrst")); + test(S("abcdefghijklmnopqrst"), 10, 5, "12345678901234567890", 19, S("abcdefghij1234567890123456789pqrst")); + test(S("abcdefghijklmnopqrst"), 10, 5, "12345678901234567890", 20, S("abcdefghij12345678901234567890pqrst")); + test(S("abcdefghijklmnopqrst"), 10, 9, "", 0, S("abcdefghijt")); + test(S("abcdefghijklmnopqrst"), 10, 9, "12345", 0, S("abcdefghijt")); + test(S("abcdefghijklmnopqrst"), 10, 9, "12345", 1, S("abcdefghij1t")); + test(S("abcdefghijklmnopqrst"), 10, 9, "12345", 2, S("abcdefghij12t")); + test(S("abcdefghijklmnopqrst"), 10, 9, "12345", 4, S("abcdefghij1234t")); + test(S("abcdefghijklmnopqrst"), 10, 9, "12345", 5, S("abcdefghij12345t")); + test(S("abcdefghijklmnopqrst"), 10, 9, "1234567890", 0, S("abcdefghijt")); + test(S("abcdefghijklmnopqrst"), 10, 9, "1234567890", 1, S("abcdefghij1t")); + test(S("abcdefghijklmnopqrst"), 10, 9, "1234567890", 5, S("abcdefghij12345t")); + test(S("abcdefghijklmnopqrst"), 10, 9, "1234567890", 9, S("abcdefghij123456789t")); + test(S("abcdefghijklmnopqrst"), 10, 9, "1234567890", 10, S("abcdefghij1234567890t")); + test(S("abcdefghijklmnopqrst"), 10, 9, "12345678901234567890", 0, S("abcdefghijt")); + test(S("abcdefghijklmnopqrst"), 10, 9, "12345678901234567890", 1, S("abcdefghij1t")); + test(S("abcdefghijklmnopqrst"), 10, 9, "12345678901234567890", 10, S("abcdefghij1234567890t")); + test(S("abcdefghijklmnopqrst"), 10, 9, "12345678901234567890", 19, S("abcdefghij1234567890123456789t")); + test(S("abcdefghijklmnopqrst"), 10, 9, "12345678901234567890", 20, S("abcdefghij12345678901234567890t")); +} + +template +void test8() +{ + test(S("abcdefghijklmnopqrst"), 10, 10, "", 0, S("abcdefghij")); + test(S("abcdefghijklmnopqrst"), 10, 10, "12345", 0, S("abcdefghij")); + test(S("abcdefghijklmnopqrst"), 10, 10, "12345", 1, S("abcdefghij1")); + test(S("abcdefghijklmnopqrst"), 10, 10, "12345", 2, S("abcdefghij12")); + test(S("abcdefghijklmnopqrst"), 10, 10, "12345", 4, S("abcdefghij1234")); + test(S("abcdefghijklmnopqrst"), 10, 10, "12345", 5, S("abcdefghij12345")); + test(S("abcdefghijklmnopqrst"), 10, 10, "1234567890", 0, S("abcdefghij")); + test(S("abcdefghijklmnopqrst"), 10, 10, "1234567890", 1, S("abcdefghij1")); + test(S("abcdefghijklmnopqrst"), 10, 10, "1234567890", 5, S("abcdefghij12345")); + test(S("abcdefghijklmnopqrst"), 10, 10, "1234567890", 9, S("abcdefghij123456789")); + test(S("abcdefghijklmnopqrst"), 10, 10, "1234567890", 10, S("abcdefghij1234567890")); + test(S("abcdefghijklmnopqrst"), 10, 10, "12345678901234567890", 0, S("abcdefghij")); + test(S("abcdefghijklmnopqrst"), 10, 10, "12345678901234567890", 1, S("abcdefghij1")); + test(S("abcdefghijklmnopqrst"), 10, 10, "12345678901234567890", 10, S("abcdefghij1234567890")); + test(S("abcdefghijklmnopqrst"), 10, 10, "12345678901234567890", 19, S("abcdefghij1234567890123456789")); + test(S("abcdefghijklmnopqrst"), 10, 10, "12345678901234567890", 20, S("abcdefghij12345678901234567890")); + test(S("abcdefghijklmnopqrst"), 19, 0, "", 0, S("abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 19, 0, "12345", 0, S("abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 19, 0, "12345", 1, S("abcdefghijklmnopqrs1t")); + test(S("abcdefghijklmnopqrst"), 19, 0, "12345", 2, S("abcdefghijklmnopqrs12t")); + test(S("abcdefghijklmnopqrst"), 19, 0, "12345", 4, S("abcdefghijklmnopqrs1234t")); + test(S("abcdefghijklmnopqrst"), 19, 0, "12345", 5, S("abcdefghijklmnopqrs12345t")); + test(S("abcdefghijklmnopqrst"), 19, 0, "1234567890", 0, S("abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 19, 0, "1234567890", 1, S("abcdefghijklmnopqrs1t")); + test(S("abcdefghijklmnopqrst"), 19, 0, "1234567890", 5, S("abcdefghijklmnopqrs12345t")); + test(S("abcdefghijklmnopqrst"), 19, 0, "1234567890", 9, S("abcdefghijklmnopqrs123456789t")); + test(S("abcdefghijklmnopqrst"), 19, 0, "1234567890", 10, S("abcdefghijklmnopqrs1234567890t")); + test(S("abcdefghijklmnopqrst"), 19, 0, "12345678901234567890", 0, S("abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 19, 0, "12345678901234567890", 1, S("abcdefghijklmnopqrs1t")); + test(S("abcdefghijklmnopqrst"), 19, 0, "12345678901234567890", 10, S("abcdefghijklmnopqrs1234567890t")); + test(S("abcdefghijklmnopqrst"), 19, 0, "12345678901234567890", 19, S("abcdefghijklmnopqrs1234567890123456789t")); + test(S("abcdefghijklmnopqrst"), 19, 0, "12345678901234567890", 20, S("abcdefghijklmnopqrs12345678901234567890t")); + test(S("abcdefghijklmnopqrst"), 19, 1, "", 0, S("abcdefghijklmnopqrs")); + test(S("abcdefghijklmnopqrst"), 19, 1, "12345", 0, S("abcdefghijklmnopqrs")); + test(S("abcdefghijklmnopqrst"), 19, 1, "12345", 1, S("abcdefghijklmnopqrs1")); + test(S("abcdefghijklmnopqrst"), 19, 1, "12345", 2, S("abcdefghijklmnopqrs12")); + test(S("abcdefghijklmnopqrst"), 19, 1, "12345", 4, S("abcdefghijklmnopqrs1234")); + test(S("abcdefghijklmnopqrst"), 19, 1, "12345", 5, S("abcdefghijklmnopqrs12345")); + test(S("abcdefghijklmnopqrst"), 19, 1, "1234567890", 0, S("abcdefghijklmnopqrs")); + test(S("abcdefghijklmnopqrst"), 19, 1, "1234567890", 1, S("abcdefghijklmnopqrs1")); + test(S("abcdefghijklmnopqrst"), 19, 1, "1234567890", 5, S("abcdefghijklmnopqrs12345")); + test(S("abcdefghijklmnopqrst"), 19, 1, "1234567890", 9, S("abcdefghijklmnopqrs123456789")); + test(S("abcdefghijklmnopqrst"), 19, 1, "1234567890", 10, S("abcdefghijklmnopqrs1234567890")); + test(S("abcdefghijklmnopqrst"), 19, 1, "12345678901234567890", 0, S("abcdefghijklmnopqrs")); + test(S("abcdefghijklmnopqrst"), 19, 1, "12345678901234567890", 1, S("abcdefghijklmnopqrs1")); + test(S("abcdefghijklmnopqrst"), 19, 1, "12345678901234567890", 10, S("abcdefghijklmnopqrs1234567890")); + test(S("abcdefghijklmnopqrst"), 19, 1, "12345678901234567890", 19, S("abcdefghijklmnopqrs1234567890123456789")); + test(S("abcdefghijklmnopqrst"), 19, 1, "12345678901234567890", 20, S("abcdefghijklmnopqrs12345678901234567890")); + test(S("abcdefghijklmnopqrst"), 20, 0, "", 0, S("abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 20, 0, "12345", 0, S("abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 20, 0, "12345", 1, S("abcdefghijklmnopqrst1")); + test(S("abcdefghijklmnopqrst"), 20, 0, "12345", 2, S("abcdefghijklmnopqrst12")); + test(S("abcdefghijklmnopqrst"), 20, 0, "12345", 4, S("abcdefghijklmnopqrst1234")); + test(S("abcdefghijklmnopqrst"), 20, 0, "12345", 5, S("abcdefghijklmnopqrst12345")); + test(S("abcdefghijklmnopqrst"), 20, 0, "1234567890", 0, S("abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 20, 0, "1234567890", 1, S("abcdefghijklmnopqrst1")); + test(S("abcdefghijklmnopqrst"), 20, 0, "1234567890", 5, S("abcdefghijklmnopqrst12345")); + test(S("abcdefghijklmnopqrst"), 20, 0, "1234567890", 9, S("abcdefghijklmnopqrst123456789")); + test(S("abcdefghijklmnopqrst"), 20, 0, "1234567890", 10, S("abcdefghijklmnopqrst1234567890")); + test(S("abcdefghijklmnopqrst"), 20, 0, "12345678901234567890", 0, S("abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 20, 0, "12345678901234567890", 1, S("abcdefghijklmnopqrst1")); + test(S("abcdefghijklmnopqrst"), 20, 0, "12345678901234567890", 10, S("abcdefghijklmnopqrst1234567890")); + test(S("abcdefghijklmnopqrst"), 20, 0, "12345678901234567890", 19, S("abcdefghijklmnopqrst1234567890123456789")); + test(S("abcdefghijklmnopqrst"), 20, 0, "12345678901234567890", 20, S("abcdefghijklmnopqrst12345678901234567890")); +} + +int main() +{ + { + typedef std::string S; + test0(); + test1(); + test2(); + test3(); + test4(); + test5(); + test6(); + test7(); + test8(); + } +#if TEST_STD_VER >= 11 + { + typedef std::basic_string, min_allocator> S; + test0(); + test1(); + test2(); + test3(); + test4(); + test5(); + test6(); + test7(); + test8(); + } +#endif + + { // test replacing into self + typedef std::string S; + S s_short = "123/"; + S s_long = "Lorem ipsum dolor sit amet, consectetur/"; + + s_short.replace(s_short.begin(), s_short.begin(), s_short.data(), s_short.size()); + assert(s_short == "123/123/"); + s_short.replace(s_short.begin(), s_short.begin(), s_short.data(), s_short.size()); + assert(s_short == "123/123/123/123/"); + s_short.replace(s_short.begin(), s_short.begin(), s_short.data(), s_short.size()); + assert(s_short == "123/123/123/123/123/123/123/123/"); + + s_long.replace(s_long.begin(), s_long.begin(), s_long.data(), s_long.size()); + assert(s_long == "Lorem ipsum dolor sit amet, consectetur/Lorem ipsum dolor sit amet, consectetur/"); + } +} diff --git a/tests/external/libcxx/basic_string/string.modifiers/string_replace/iter_iter_size_char.pass.cpp b/tests/external/libcxx/basic_string/string.modifiers/string_replace/iter_iter_size_char.pass.cpp new file mode 100644 index 0000000..4dbc8ab --- /dev/null +++ b/tests/external/libcxx/basic_string/string.modifiers/string_replace/iter_iter_size_char.pass.cpp @@ -0,0 +1,285 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// + +// basic_string& +// replace(const_iterator i1, const_iterator i2, size_type n, charT c); + +#include +#include +#include + +#include "test_macros.h" +#include "min_allocator.h" + +template +void +test(S s, typename S::size_type pos1, typename S::size_type n1, typename S::size_type n2, + typename S::value_type c, S expected) +{ + typename S::size_type old_size = s.size(); + typename S::const_iterator first = s.begin() + pos1; + typename S::const_iterator last = s.begin() + pos1 + n1; + typename S::size_type xlen = last - first; + s.replace(first, last, n2, c); + LIBCPP_ASSERT(s.__invariants()); + assert(s == expected); + typename S::size_type rlen = n2; + assert(s.size() == old_size - xlen + rlen); +} + +template +void test0() +{ + test(S(""), 0, 0, 0, '3', S("")); + test(S(""), 0, 0, 5, '3', S("33333")); + test(S(""), 0, 0, 10, '3', S("3333333333")); + test(S(""), 0, 0, 20, '3', S("33333333333333333333")); + test(S("abcde"), 0, 0, 0, '3', S("abcde")); + test(S("abcde"), 0, 0, 5, '3', S("33333abcde")); + test(S("abcde"), 0, 0, 10, '3', S("3333333333abcde")); + test(S("abcde"), 0, 0, 20, '3', S("33333333333333333333abcde")); + test(S("abcde"), 0, 1, 0, '3', S("bcde")); + test(S("abcde"), 0, 1, 5, '3', S("33333bcde")); + test(S("abcde"), 0, 1, 10, '3', S("3333333333bcde")); + test(S("abcde"), 0, 1, 20, '3', S("33333333333333333333bcde")); + test(S("abcde"), 0, 2, 0, '3', S("cde")); + test(S("abcde"), 0, 2, 5, '3', S("33333cde")); + test(S("abcde"), 0, 2, 10, '3', S("3333333333cde")); + test(S("abcde"), 0, 2, 20, '3', S("33333333333333333333cde")); + test(S("abcde"), 0, 4, 0, '3', S("e")); + test(S("abcde"), 0, 4, 5, '3', S("33333e")); + test(S("abcde"), 0, 4, 10, '3', S("3333333333e")); + test(S("abcde"), 0, 4, 20, '3', S("33333333333333333333e")); + test(S("abcde"), 0, 5, 0, '3', S("")); + test(S("abcde"), 0, 5, 5, '3', S("33333")); + test(S("abcde"), 0, 5, 10, '3', S("3333333333")); + test(S("abcde"), 0, 5, 20, '3', S("33333333333333333333")); + test(S("abcde"), 1, 0, 0, '3', S("abcde")); + test(S("abcde"), 1, 0, 5, '3', S("a33333bcde")); + test(S("abcde"), 1, 0, 10, '3', S("a3333333333bcde")); + test(S("abcde"), 1, 0, 20, '3', S("a33333333333333333333bcde")); + test(S("abcde"), 1, 1, 0, '3', S("acde")); + test(S("abcde"), 1, 1, 5, '3', S("a33333cde")); + test(S("abcde"), 1, 1, 10, '3', S("a3333333333cde")); + test(S("abcde"), 1, 1, 20, '3', S("a33333333333333333333cde")); + test(S("abcde"), 1, 2, 0, '3', S("ade")); + test(S("abcde"), 1, 2, 5, '3', S("a33333de")); + test(S("abcde"), 1, 2, 10, '3', S("a3333333333de")); + test(S("abcde"), 1, 2, 20, '3', S("a33333333333333333333de")); + test(S("abcde"), 1, 3, 0, '3', S("ae")); + test(S("abcde"), 1, 3, 5, '3', S("a33333e")); + test(S("abcde"), 1, 3, 10, '3', S("a3333333333e")); + test(S("abcde"), 1, 3, 20, '3', S("a33333333333333333333e")); + test(S("abcde"), 1, 4, 0, '3', S("a")); + test(S("abcde"), 1, 4, 5, '3', S("a33333")); + test(S("abcde"), 1, 4, 10, '3', S("a3333333333")); + test(S("abcde"), 1, 4, 20, '3', S("a33333333333333333333")); + test(S("abcde"), 2, 0, 0, '3', S("abcde")); + test(S("abcde"), 2, 0, 5, '3', S("ab33333cde")); + test(S("abcde"), 2, 0, 10, '3', S("ab3333333333cde")); + test(S("abcde"), 2, 0, 20, '3', S("ab33333333333333333333cde")); + test(S("abcde"), 2, 1, 0, '3', S("abde")); + test(S("abcde"), 2, 1, 5, '3', S("ab33333de")); + test(S("abcde"), 2, 1, 10, '3', S("ab3333333333de")); + test(S("abcde"), 2, 1, 20, '3', S("ab33333333333333333333de")); + test(S("abcde"), 2, 2, 0, '3', S("abe")); + test(S("abcde"), 2, 2, 5, '3', S("ab33333e")); + test(S("abcde"), 2, 2, 10, '3', S("ab3333333333e")); + test(S("abcde"), 2, 2, 20, '3', S("ab33333333333333333333e")); + test(S("abcde"), 2, 3, 0, '3', S("ab")); + test(S("abcde"), 2, 3, 5, '3', S("ab33333")); + test(S("abcde"), 2, 3, 10, '3', S("ab3333333333")); + test(S("abcde"), 2, 3, 20, '3', S("ab33333333333333333333")); + test(S("abcde"), 4, 0, 0, '3', S("abcde")); + test(S("abcde"), 4, 0, 5, '3', S("abcd33333e")); + test(S("abcde"), 4, 0, 10, '3', S("abcd3333333333e")); + test(S("abcde"), 4, 0, 20, '3', S("abcd33333333333333333333e")); + test(S("abcde"), 4, 1, 0, '3', S("abcd")); + test(S("abcde"), 4, 1, 5, '3', S("abcd33333")); + test(S("abcde"), 4, 1, 10, '3', S("abcd3333333333")); + test(S("abcde"), 4, 1, 20, '3', S("abcd33333333333333333333")); + test(S("abcde"), 5, 0, 0, '3', S("abcde")); + test(S("abcde"), 5, 0, 5, '3', S("abcde33333")); + test(S("abcde"), 5, 0, 10, '3', S("abcde3333333333")); + test(S("abcde"), 5, 0, 20, '3', S("abcde33333333333333333333")); + test(S("abcdefghij"), 0, 0, 0, '3', S("abcdefghij")); + test(S("abcdefghij"), 0, 0, 5, '3', S("33333abcdefghij")); + test(S("abcdefghij"), 0, 0, 10, '3', S("3333333333abcdefghij")); + test(S("abcdefghij"), 0, 0, 20, '3', S("33333333333333333333abcdefghij")); + test(S("abcdefghij"), 0, 1, 0, '3', S("bcdefghij")); + test(S("abcdefghij"), 0, 1, 5, '3', S("33333bcdefghij")); + test(S("abcdefghij"), 0, 1, 10, '3', S("3333333333bcdefghij")); + test(S("abcdefghij"), 0, 1, 20, '3', S("33333333333333333333bcdefghij")); + test(S("abcdefghij"), 0, 5, 0, '3', S("fghij")); + test(S("abcdefghij"), 0, 5, 5, '3', S("33333fghij")); + test(S("abcdefghij"), 0, 5, 10, '3', S("3333333333fghij")); + test(S("abcdefghij"), 0, 5, 20, '3', S("33333333333333333333fghij")); + test(S("abcdefghij"), 0, 9, 0, '3', S("j")); + test(S("abcdefghij"), 0, 9, 5, '3', S("33333j")); + test(S("abcdefghij"), 0, 9, 10, '3', S("3333333333j")); + test(S("abcdefghij"), 0, 9, 20, '3', S("33333333333333333333j")); + test(S("abcdefghij"), 0, 10, 0, '3', S("")); + test(S("abcdefghij"), 0, 10, 5, '3', S("33333")); + test(S("abcdefghij"), 0, 10, 10, '3', S("3333333333")); + test(S("abcdefghij"), 0, 10, 20, '3', S("33333333333333333333")); + test(S("abcdefghij"), 1, 0, 0, '3', S("abcdefghij")); + test(S("abcdefghij"), 1, 0, 5, '3', S("a33333bcdefghij")); + test(S("abcdefghij"), 1, 0, 10, '3', S("a3333333333bcdefghij")); + test(S("abcdefghij"), 1, 0, 20, '3', S("a33333333333333333333bcdefghij")); + test(S("abcdefghij"), 1, 1, 0, '3', S("acdefghij")); + test(S("abcdefghij"), 1, 1, 5, '3', S("a33333cdefghij")); + test(S("abcdefghij"), 1, 1, 10, '3', S("a3333333333cdefghij")); + test(S("abcdefghij"), 1, 1, 20, '3', S("a33333333333333333333cdefghij")); +} + +template +void test1() +{ + test(S("abcdefghij"), 1, 4, 0, '3', S("afghij")); + test(S("abcdefghij"), 1, 4, 5, '3', S("a33333fghij")); + test(S("abcdefghij"), 1, 4, 10, '3', S("a3333333333fghij")); + test(S("abcdefghij"), 1, 4, 20, '3', S("a33333333333333333333fghij")); + test(S("abcdefghij"), 1, 8, 0, '3', S("aj")); + test(S("abcdefghij"), 1, 8, 5, '3', S("a33333j")); + test(S("abcdefghij"), 1, 8, 10, '3', S("a3333333333j")); + test(S("abcdefghij"), 1, 8, 20, '3', S("a33333333333333333333j")); + test(S("abcdefghij"), 1, 9, 0, '3', S("a")); + test(S("abcdefghij"), 1, 9, 5, '3', S("a33333")); + test(S("abcdefghij"), 1, 9, 10, '3', S("a3333333333")); + test(S("abcdefghij"), 1, 9, 20, '3', S("a33333333333333333333")); + test(S("abcdefghij"), 5, 0, 0, '3', S("abcdefghij")); + test(S("abcdefghij"), 5, 0, 5, '3', S("abcde33333fghij")); + test(S("abcdefghij"), 5, 0, 10, '3', S("abcde3333333333fghij")); + test(S("abcdefghij"), 5, 0, 20, '3', S("abcde33333333333333333333fghij")); + test(S("abcdefghij"), 5, 1, 0, '3', S("abcdeghij")); + test(S("abcdefghij"), 5, 1, 5, '3', S("abcde33333ghij")); + test(S("abcdefghij"), 5, 1, 10, '3', S("abcde3333333333ghij")); + test(S("abcdefghij"), 5, 1, 20, '3', S("abcde33333333333333333333ghij")); + test(S("abcdefghij"), 5, 2, 0, '3', S("abcdehij")); + test(S("abcdefghij"), 5, 2, 5, '3', S("abcde33333hij")); + test(S("abcdefghij"), 5, 2, 10, '3', S("abcde3333333333hij")); + test(S("abcdefghij"), 5, 2, 20, '3', S("abcde33333333333333333333hij")); + test(S("abcdefghij"), 5, 4, 0, '3', S("abcdej")); + test(S("abcdefghij"), 5, 4, 5, '3', S("abcde33333j")); + test(S("abcdefghij"), 5, 4, 10, '3', S("abcde3333333333j")); + test(S("abcdefghij"), 5, 4, 20, '3', S("abcde33333333333333333333j")); + test(S("abcdefghij"), 5, 5, 0, '3', S("abcde")); + test(S("abcdefghij"), 5, 5, 5, '3', S("abcde33333")); + test(S("abcdefghij"), 5, 5, 10, '3', S("abcde3333333333")); + test(S("abcdefghij"), 5, 5, 20, '3', S("abcde33333333333333333333")); + test(S("abcdefghij"), 9, 0, 0, '3', S("abcdefghij")); + test(S("abcdefghij"), 9, 0, 5, '3', S("abcdefghi33333j")); + test(S("abcdefghij"), 9, 0, 10, '3', S("abcdefghi3333333333j")); + test(S("abcdefghij"), 9, 0, 20, '3', S("abcdefghi33333333333333333333j")); + test(S("abcdefghij"), 9, 1, 0, '3', S("abcdefghi")); + test(S("abcdefghij"), 9, 1, 5, '3', S("abcdefghi33333")); + test(S("abcdefghij"), 9, 1, 10, '3', S("abcdefghi3333333333")); + test(S("abcdefghij"), 9, 1, 20, '3', S("abcdefghi33333333333333333333")); + test(S("abcdefghij"), 10, 0, 0, '3', S("abcdefghij")); + test(S("abcdefghij"), 10, 0, 5, '3', S("abcdefghij33333")); + test(S("abcdefghij"), 10, 0, 10, '3', S("abcdefghij3333333333")); + test(S("abcdefghij"), 10, 0, 20, '3', S("abcdefghij33333333333333333333")); + test(S("abcdefghijklmnopqrst"), 0, 0, 0, '3', S("abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, 0, 5, '3', S("33333abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, 0, 10, '3', S("3333333333abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, 0, 20, '3', S("33333333333333333333abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, 1, 0, '3', S("bcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, 1, 5, '3', S("33333bcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, 1, 10, '3', S("3333333333bcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, 1, 20, '3', S("33333333333333333333bcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, 10, 0, '3', S("klmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, 10, 5, '3', S("33333klmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, 10, 10, '3', S("3333333333klmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, 10, 20, '3', S("33333333333333333333klmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, 19, 0, '3', S("t")); + test(S("abcdefghijklmnopqrst"), 0, 19, 5, '3', S("33333t")); + test(S("abcdefghijklmnopqrst"), 0, 19, 10, '3', S("3333333333t")); + test(S("abcdefghijklmnopqrst"), 0, 19, 20, '3', S("33333333333333333333t")); + test(S("abcdefghijklmnopqrst"), 0, 20, 0, '3', S("")); + test(S("abcdefghijklmnopqrst"), 0, 20, 5, '3', S("33333")); + test(S("abcdefghijklmnopqrst"), 0, 20, 10, '3', S("3333333333")); + test(S("abcdefghijklmnopqrst"), 0, 20, 20, '3', S("33333333333333333333")); + test(S("abcdefghijklmnopqrst"), 1, 0, 0, '3', S("abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, 0, 5, '3', S("a33333bcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, 0, 10, '3', S("a3333333333bcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, 0, 20, '3', S("a33333333333333333333bcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, 1, 0, '3', S("acdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, 1, 5, '3', S("a33333cdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, 1, 10, '3', S("a3333333333cdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, 1, 20, '3', S("a33333333333333333333cdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, 9, 0, '3', S("aklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, 9, 5, '3', S("a33333klmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, 9, 10, '3', S("a3333333333klmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, 9, 20, '3', S("a33333333333333333333klmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, 18, 0, '3', S("at")); + test(S("abcdefghijklmnopqrst"), 1, 18, 5, '3', S("a33333t")); + test(S("abcdefghijklmnopqrst"), 1, 18, 10, '3', S("a3333333333t")); + test(S("abcdefghijklmnopqrst"), 1, 18, 20, '3', S("a33333333333333333333t")); + test(S("abcdefghijklmnopqrst"), 1, 19, 0, '3', S("a")); + test(S("abcdefghijklmnopqrst"), 1, 19, 5, '3', S("a33333")); + test(S("abcdefghijklmnopqrst"), 1, 19, 10, '3', S("a3333333333")); + test(S("abcdefghijklmnopqrst"), 1, 19, 20, '3', S("a33333333333333333333")); + test(S("abcdefghijklmnopqrst"), 10, 0, 0, '3', S("abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 10, 0, 5, '3', S("abcdefghij33333klmnopqrst")); + test(S("abcdefghijklmnopqrst"), 10, 0, 10, '3', S("abcdefghij3333333333klmnopqrst")); + test(S("abcdefghijklmnopqrst"), 10, 0, 20, '3', S("abcdefghij33333333333333333333klmnopqrst")); + test(S("abcdefghijklmnopqrst"), 10, 1, 0, '3', S("abcdefghijlmnopqrst")); + test(S("abcdefghijklmnopqrst"), 10, 1, 5, '3', S("abcdefghij33333lmnopqrst")); + test(S("abcdefghijklmnopqrst"), 10, 1, 10, '3', S("abcdefghij3333333333lmnopqrst")); + test(S("abcdefghijklmnopqrst"), 10, 1, 20, '3', S("abcdefghij33333333333333333333lmnopqrst")); + test(S("abcdefghijklmnopqrst"), 10, 5, 0, '3', S("abcdefghijpqrst")); + test(S("abcdefghijklmnopqrst"), 10, 5, 5, '3', S("abcdefghij33333pqrst")); + test(S("abcdefghijklmnopqrst"), 10, 5, 10, '3', S("abcdefghij3333333333pqrst")); + test(S("abcdefghijklmnopqrst"), 10, 5, 20, '3', S("abcdefghij33333333333333333333pqrst")); + test(S("abcdefghijklmnopqrst"), 10, 9, 0, '3', S("abcdefghijt")); + test(S("abcdefghijklmnopqrst"), 10, 9, 5, '3', S("abcdefghij33333t")); + test(S("abcdefghijklmnopqrst"), 10, 9, 10, '3', S("abcdefghij3333333333t")); + test(S("abcdefghijklmnopqrst"), 10, 9, 20, '3', S("abcdefghij33333333333333333333t")); +} + +template +void test2() +{ + test(S("abcdefghijklmnopqrst"), 10, 10, 0, '3', S("abcdefghij")); + test(S("abcdefghijklmnopqrst"), 10, 10, 5, '3', S("abcdefghij33333")); + test(S("abcdefghijklmnopqrst"), 10, 10, 10, '3', S("abcdefghij3333333333")); + test(S("abcdefghijklmnopqrst"), 10, 10, 20, '3', S("abcdefghij33333333333333333333")); + test(S("abcdefghijklmnopqrst"), 19, 0, 0, '3', S("abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 19, 0, 5, '3', S("abcdefghijklmnopqrs33333t")); + test(S("abcdefghijklmnopqrst"), 19, 0, 10, '3', S("abcdefghijklmnopqrs3333333333t")); + test(S("abcdefghijklmnopqrst"), 19, 0, 20, '3', S("abcdefghijklmnopqrs33333333333333333333t")); + test(S("abcdefghijklmnopqrst"), 19, 1, 0, '3', S("abcdefghijklmnopqrs")); + test(S("abcdefghijklmnopqrst"), 19, 1, 5, '3', S("abcdefghijklmnopqrs33333")); + test(S("abcdefghijklmnopqrst"), 19, 1, 10, '3', S("abcdefghijklmnopqrs3333333333")); + test(S("abcdefghijklmnopqrst"), 19, 1, 20, '3', S("abcdefghijklmnopqrs33333333333333333333")); + test(S("abcdefghijklmnopqrst"), 20, 0, 0, '3', S("abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 20, 0, 5, '3', S("abcdefghijklmnopqrst33333")); + test(S("abcdefghijklmnopqrst"), 20, 0, 10, '3', S("abcdefghijklmnopqrst3333333333")); + test(S("abcdefghijklmnopqrst"), 20, 0, 20, '3', S("abcdefghijklmnopqrst33333333333333333333")); +} + +int main() +{ + { + typedef std::string S; + test0(); + test1(); + test2(); + } +#if TEST_STD_VER >= 11 + { + typedef std::basic_string, min_allocator> S; + test0(); + test1(); + test2(); + } +#endif +} diff --git a/tests/external/libcxx/basic_string/string.modifiers/string_replace/iter_iter_string.pass.cpp b/tests/external/libcxx/basic_string/string.modifiers/string_replace/iter_iter_string.pass.cpp new file mode 100644 index 0000000..f5f3125 --- /dev/null +++ b/tests/external/libcxx/basic_string/string.modifiers/string_replace/iter_iter_string.pass.cpp @@ -0,0 +1,293 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// + +// basic_string& +// replace(const_iterator i1, const_iterator i2, const basic_string& str); + +#include +#include +#include + +#include "test_macros.h" +#include "min_allocator.h" + +template +void +test(S s, typename S::size_type pos1, typename S::size_type n1, S str, S expected) +{ + typename S::size_type old_size = s.size(); + typename S::const_iterator first = s.begin() + pos1; + typename S::const_iterator last = s.begin() + pos1 + n1; + typename S::size_type xlen = last - first; + s.replace(first, last, str); + LIBCPP_ASSERT(s.__invariants()); + assert(s == expected); + typename S::size_type rlen = str.size(); + assert(s.size() == old_size - xlen + rlen); +} + +template +void test0() +{ + test(S(""), 0, 0, S(""), S("")); + test(S(""), 0, 0, S("12345"), S("12345")); + test(S(""), 0, 0, S("1234567890"), S("1234567890")); + test(S(""), 0, 0, S("12345678901234567890"), S("12345678901234567890")); + test(S("abcde"), 0, 0, S(""), S("abcde")); + test(S("abcde"), 0, 0, S("12345"), S("12345abcde")); + test(S("abcde"), 0, 0, S("1234567890"), S("1234567890abcde")); + test(S("abcde"), 0, 0, S("12345678901234567890"), S("12345678901234567890abcde")); + test(S("abcde"), 0, 1, S(""), S("bcde")); + test(S("abcde"), 0, 1, S("12345"), S("12345bcde")); + test(S("abcde"), 0, 1, S("1234567890"), S("1234567890bcde")); + test(S("abcde"), 0, 1, S("12345678901234567890"), S("12345678901234567890bcde")); + test(S("abcde"), 0, 2, S(""), S("cde")); + test(S("abcde"), 0, 2, S("12345"), S("12345cde")); + test(S("abcde"), 0, 2, S("1234567890"), S("1234567890cde")); + test(S("abcde"), 0, 2, S("12345678901234567890"), S("12345678901234567890cde")); + test(S("abcde"), 0, 4, S(""), S("e")); + test(S("abcde"), 0, 4, S("12345"), S("12345e")); + test(S("abcde"), 0, 4, S("1234567890"), S("1234567890e")); + test(S("abcde"), 0, 4, S("12345678901234567890"), S("12345678901234567890e")); + test(S("abcde"), 0, 5, S(""), S("")); + test(S("abcde"), 0, 5, S("12345"), S("12345")); + test(S("abcde"), 0, 5, S("1234567890"), S("1234567890")); + test(S("abcde"), 0, 5, S("12345678901234567890"), S("12345678901234567890")); + test(S("abcde"), 1, 0, S(""), S("abcde")); + test(S("abcde"), 1, 0, S("12345"), S("a12345bcde")); + test(S("abcde"), 1, 0, S("1234567890"), S("a1234567890bcde")); + test(S("abcde"), 1, 0, S("12345678901234567890"), S("a12345678901234567890bcde")); + test(S("abcde"), 1, 1, S(""), S("acde")); + test(S("abcde"), 1, 1, S("12345"), S("a12345cde")); + test(S("abcde"), 1, 1, S("1234567890"), S("a1234567890cde")); + test(S("abcde"), 1, 1, S("12345678901234567890"), S("a12345678901234567890cde")); + test(S("abcde"), 1, 2, S(""), S("ade")); + test(S("abcde"), 1, 2, S("12345"), S("a12345de")); + test(S("abcde"), 1, 2, S("1234567890"), S("a1234567890de")); + test(S("abcde"), 1, 2, S("12345678901234567890"), S("a12345678901234567890de")); + test(S("abcde"), 1, 3, S(""), S("ae")); + test(S("abcde"), 1, 3, S("12345"), S("a12345e")); + test(S("abcde"), 1, 3, S("1234567890"), S("a1234567890e")); + test(S("abcde"), 1, 3, S("12345678901234567890"), S("a12345678901234567890e")); + test(S("abcde"), 1, 4, S(""), S("a")); + test(S("abcde"), 1, 4, S("12345"), S("a12345")); + test(S("abcde"), 1, 4, S("1234567890"), S("a1234567890")); + test(S("abcde"), 1, 4, S("12345678901234567890"), S("a12345678901234567890")); + test(S("abcde"), 2, 0, S(""), S("abcde")); + test(S("abcde"), 2, 0, S("12345"), S("ab12345cde")); + test(S("abcde"), 2, 0, S("1234567890"), S("ab1234567890cde")); + test(S("abcde"), 2, 0, S("12345678901234567890"), S("ab12345678901234567890cde")); + test(S("abcde"), 2, 1, S(""), S("abde")); + test(S("abcde"), 2, 1, S("12345"), S("ab12345de")); + test(S("abcde"), 2, 1, S("1234567890"), S("ab1234567890de")); + test(S("abcde"), 2, 1, S("12345678901234567890"), S("ab12345678901234567890de")); + test(S("abcde"), 2, 2, S(""), S("abe")); + test(S("abcde"), 2, 2, S("12345"), S("ab12345e")); + test(S("abcde"), 2, 2, S("1234567890"), S("ab1234567890e")); + test(S("abcde"), 2, 2, S("12345678901234567890"), S("ab12345678901234567890e")); + test(S("abcde"), 2, 3, S(""), S("ab")); + test(S("abcde"), 2, 3, S("12345"), S("ab12345")); + test(S("abcde"), 2, 3, S("1234567890"), S("ab1234567890")); + test(S("abcde"), 2, 3, S("12345678901234567890"), S("ab12345678901234567890")); + test(S("abcde"), 4, 0, S(""), S("abcde")); + test(S("abcde"), 4, 0, S("12345"), S("abcd12345e")); + test(S("abcde"), 4, 0, S("1234567890"), S("abcd1234567890e")); + test(S("abcde"), 4, 0, S("12345678901234567890"), S("abcd12345678901234567890e")); + test(S("abcde"), 4, 1, S(""), S("abcd")); + test(S("abcde"), 4, 1, S("12345"), S("abcd12345")); + test(S("abcde"), 4, 1, S("1234567890"), S("abcd1234567890")); + test(S("abcde"), 4, 1, S("12345678901234567890"), S("abcd12345678901234567890")); + test(S("abcde"), 5, 0, S(""), S("abcde")); + test(S("abcde"), 5, 0, S("12345"), S("abcde12345")); + test(S("abcde"), 5, 0, S("1234567890"), S("abcde1234567890")); + test(S("abcde"), 5, 0, S("12345678901234567890"), S("abcde12345678901234567890")); + test(S("abcdefghij"), 0, 0, S(""), S("abcdefghij")); + test(S("abcdefghij"), 0, 0, S("12345"), S("12345abcdefghij")); + test(S("abcdefghij"), 0, 0, S("1234567890"), S("1234567890abcdefghij")); + test(S("abcdefghij"), 0, 0, S("12345678901234567890"), S("12345678901234567890abcdefghij")); + test(S("abcdefghij"), 0, 1, S(""), S("bcdefghij")); + test(S("abcdefghij"), 0, 1, S("12345"), S("12345bcdefghij")); + test(S("abcdefghij"), 0, 1, S("1234567890"), S("1234567890bcdefghij")); + test(S("abcdefghij"), 0, 1, S("12345678901234567890"), S("12345678901234567890bcdefghij")); + test(S("abcdefghij"), 0, 5, S(""), S("fghij")); + test(S("abcdefghij"), 0, 5, S("12345"), S("12345fghij")); + test(S("abcdefghij"), 0, 5, S("1234567890"), S("1234567890fghij")); + test(S("abcdefghij"), 0, 5, S("12345678901234567890"), S("12345678901234567890fghij")); + test(S("abcdefghij"), 0, 9, S(""), S("j")); + test(S("abcdefghij"), 0, 9, S("12345"), S("12345j")); + test(S("abcdefghij"), 0, 9, S("1234567890"), S("1234567890j")); + test(S("abcdefghij"), 0, 9, S("12345678901234567890"), S("12345678901234567890j")); + test(S("abcdefghij"), 0, 10, S(""), S("")); + test(S("abcdefghij"), 0, 10, S("12345"), S("12345")); + test(S("abcdefghij"), 0, 10, S("1234567890"), S("1234567890")); + test(S("abcdefghij"), 0, 10, S("12345678901234567890"), S("12345678901234567890")); + test(S("abcdefghij"), 1, 0, S(""), S("abcdefghij")); + test(S("abcdefghij"), 1, 0, S("12345"), S("a12345bcdefghij")); + test(S("abcdefghij"), 1, 0, S("1234567890"), S("a1234567890bcdefghij")); + test(S("abcdefghij"), 1, 0, S("12345678901234567890"), S("a12345678901234567890bcdefghij")); + test(S("abcdefghij"), 1, 1, S(""), S("acdefghij")); + test(S("abcdefghij"), 1, 1, S("12345"), S("a12345cdefghij")); + test(S("abcdefghij"), 1, 1, S("1234567890"), S("a1234567890cdefghij")); + test(S("abcdefghij"), 1, 1, S("12345678901234567890"), S("a12345678901234567890cdefghij")); +} + +template +void test1() +{ + test(S("abcdefghij"), 1, 4, S(""), S("afghij")); + test(S("abcdefghij"), 1, 4, S("12345"), S("a12345fghij")); + test(S("abcdefghij"), 1, 4, S("1234567890"), S("a1234567890fghij")); + test(S("abcdefghij"), 1, 4, S("12345678901234567890"), S("a12345678901234567890fghij")); + test(S("abcdefghij"), 1, 8, S(""), S("aj")); + test(S("abcdefghij"), 1, 8, S("12345"), S("a12345j")); + test(S("abcdefghij"), 1, 8, S("1234567890"), S("a1234567890j")); + test(S("abcdefghij"), 1, 8, S("12345678901234567890"), S("a12345678901234567890j")); + test(S("abcdefghij"), 1, 9, S(""), S("a")); + test(S("abcdefghij"), 1, 9, S("12345"), S("a12345")); + test(S("abcdefghij"), 1, 9, S("1234567890"), S("a1234567890")); + test(S("abcdefghij"), 1, 9, S("12345678901234567890"), S("a12345678901234567890")); + test(S("abcdefghij"), 5, 0, S(""), S("abcdefghij")); + test(S("abcdefghij"), 5, 0, S("12345"), S("abcde12345fghij")); + test(S("abcdefghij"), 5, 0, S("1234567890"), S("abcde1234567890fghij")); + test(S("abcdefghij"), 5, 0, S("12345678901234567890"), S("abcde12345678901234567890fghij")); + test(S("abcdefghij"), 5, 1, S(""), S("abcdeghij")); + test(S("abcdefghij"), 5, 1, S("12345"), S("abcde12345ghij")); + test(S("abcdefghij"), 5, 1, S("1234567890"), S("abcde1234567890ghij")); + test(S("abcdefghij"), 5, 1, S("12345678901234567890"), S("abcde12345678901234567890ghij")); + test(S("abcdefghij"), 5, 2, S(""), S("abcdehij")); + test(S("abcdefghij"), 5, 2, S("12345"), S("abcde12345hij")); + test(S("abcdefghij"), 5, 2, S("1234567890"), S("abcde1234567890hij")); + test(S("abcdefghij"), 5, 2, S("12345678901234567890"), S("abcde12345678901234567890hij")); + test(S("abcdefghij"), 5, 4, S(""), S("abcdej")); + test(S("abcdefghij"), 5, 4, S("12345"), S("abcde12345j")); + test(S("abcdefghij"), 5, 4, S("1234567890"), S("abcde1234567890j")); + test(S("abcdefghij"), 5, 4, S("12345678901234567890"), S("abcde12345678901234567890j")); + test(S("abcdefghij"), 5, 5, S(""), S("abcde")); + test(S("abcdefghij"), 5, 5, S("12345"), S("abcde12345")); + test(S("abcdefghij"), 5, 5, S("1234567890"), S("abcde1234567890")); + test(S("abcdefghij"), 5, 5, S("12345678901234567890"), S("abcde12345678901234567890")); + test(S("abcdefghij"), 9, 0, S(""), S("abcdefghij")); + test(S("abcdefghij"), 9, 0, S("12345"), S("abcdefghi12345j")); + test(S("abcdefghij"), 9, 0, S("1234567890"), S("abcdefghi1234567890j")); + test(S("abcdefghij"), 9, 0, S("12345678901234567890"), S("abcdefghi12345678901234567890j")); + test(S("abcdefghij"), 9, 1, S(""), S("abcdefghi")); + test(S("abcdefghij"), 9, 1, S("12345"), S("abcdefghi12345")); + test(S("abcdefghij"), 9, 1, S("1234567890"), S("abcdefghi1234567890")); + test(S("abcdefghij"), 9, 1, S("12345678901234567890"), S("abcdefghi12345678901234567890")); + test(S("abcdefghij"), 10, 0, S(""), S("abcdefghij")); + test(S("abcdefghij"), 10, 0, S("12345"), S("abcdefghij12345")); + test(S("abcdefghij"), 10, 0, S("1234567890"), S("abcdefghij1234567890")); + test(S("abcdefghij"), 10, 0, S("12345678901234567890"), S("abcdefghij12345678901234567890")); + test(S("abcdefghijklmnopqrst"), 0, 0, S(""), S("abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, 0, S("12345"), S("12345abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, 0, S("1234567890"), S("1234567890abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, 0, S("12345678901234567890"), S("12345678901234567890abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, 1, S(""), S("bcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, 1, S("12345"), S("12345bcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, 1, S("1234567890"), S("1234567890bcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, 1, S("12345678901234567890"), S("12345678901234567890bcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, 10, S(""), S("klmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, 10, S("12345"), S("12345klmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, 10, S("1234567890"), S("1234567890klmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, 10, S("12345678901234567890"), S("12345678901234567890klmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, 19, S(""), S("t")); + test(S("abcdefghijklmnopqrst"), 0, 19, S("12345"), S("12345t")); + test(S("abcdefghijklmnopqrst"), 0, 19, S("1234567890"), S("1234567890t")); + test(S("abcdefghijklmnopqrst"), 0, 19, S("12345678901234567890"), S("12345678901234567890t")); + test(S("abcdefghijklmnopqrst"), 0, 20, S(""), S("")); + test(S("abcdefghijklmnopqrst"), 0, 20, S("12345"), S("12345")); + test(S("abcdefghijklmnopqrst"), 0, 20, S("1234567890"), S("1234567890")); + test(S("abcdefghijklmnopqrst"), 0, 20, S("12345678901234567890"), S("12345678901234567890")); + test(S("abcdefghijklmnopqrst"), 1, 0, S(""), S("abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, 0, S("12345"), S("a12345bcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, 0, S("1234567890"), S("a1234567890bcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, 0, S("12345678901234567890"), S("a12345678901234567890bcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, 1, S(""), S("acdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, 1, S("12345"), S("a12345cdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, 1, S("1234567890"), S("a1234567890cdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, 1, S("12345678901234567890"), S("a12345678901234567890cdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, 9, S(""), S("aklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, 9, S("12345"), S("a12345klmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, 9, S("1234567890"), S("a1234567890klmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, 9, S("12345678901234567890"), S("a12345678901234567890klmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, 18, S(""), S("at")); + test(S("abcdefghijklmnopqrst"), 1, 18, S("12345"), S("a12345t")); + test(S("abcdefghijklmnopqrst"), 1, 18, S("1234567890"), S("a1234567890t")); + test(S("abcdefghijklmnopqrst"), 1, 18, S("12345678901234567890"), S("a12345678901234567890t")); + test(S("abcdefghijklmnopqrst"), 1, 19, S(""), S("a")); + test(S("abcdefghijklmnopqrst"), 1, 19, S("12345"), S("a12345")); + test(S("abcdefghijklmnopqrst"), 1, 19, S("1234567890"), S("a1234567890")); + test(S("abcdefghijklmnopqrst"), 1, 19, S("12345678901234567890"), S("a12345678901234567890")); + test(S("abcdefghijklmnopqrst"), 10, 0, S(""), S("abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 10, 0, S("12345"), S("abcdefghij12345klmnopqrst")); + test(S("abcdefghijklmnopqrst"), 10, 0, S("1234567890"), S("abcdefghij1234567890klmnopqrst")); + test(S("abcdefghijklmnopqrst"), 10, 0, S("12345678901234567890"), S("abcdefghij12345678901234567890klmnopqrst")); + test(S("abcdefghijklmnopqrst"), 10, 1, S(""), S("abcdefghijlmnopqrst")); + test(S("abcdefghijklmnopqrst"), 10, 1, S("12345"), S("abcdefghij12345lmnopqrst")); + test(S("abcdefghijklmnopqrst"), 10, 1, S("1234567890"), S("abcdefghij1234567890lmnopqrst")); + test(S("abcdefghijklmnopqrst"), 10, 1, S("12345678901234567890"), S("abcdefghij12345678901234567890lmnopqrst")); + test(S("abcdefghijklmnopqrst"), 10, 5, S(""), S("abcdefghijpqrst")); + test(S("abcdefghijklmnopqrst"), 10, 5, S("12345"), S("abcdefghij12345pqrst")); + test(S("abcdefghijklmnopqrst"), 10, 5, S("1234567890"), S("abcdefghij1234567890pqrst")); + test(S("abcdefghijklmnopqrst"), 10, 5, S("12345678901234567890"), S("abcdefghij12345678901234567890pqrst")); + test(S("abcdefghijklmnopqrst"), 10, 9, S(""), S("abcdefghijt")); + test(S("abcdefghijklmnopqrst"), 10, 9, S("12345"), S("abcdefghij12345t")); + test(S("abcdefghijklmnopqrst"), 10, 9, S("1234567890"), S("abcdefghij1234567890t")); + test(S("abcdefghijklmnopqrst"), 10, 9, S("12345678901234567890"), S("abcdefghij12345678901234567890t")); +} + +template +void test2() +{ + test(S("abcdefghijklmnopqrst"), 10, 10, S(""), S("abcdefghij")); + test(S("abcdefghijklmnopqrst"), 10, 10, S("12345"), S("abcdefghij12345")); + test(S("abcdefghijklmnopqrst"), 10, 10, S("1234567890"), S("abcdefghij1234567890")); + test(S("abcdefghijklmnopqrst"), 10, 10, S("12345678901234567890"), S("abcdefghij12345678901234567890")); + test(S("abcdefghijklmnopqrst"), 19, 0, S(""), S("abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 19, 0, S("12345"), S("abcdefghijklmnopqrs12345t")); + test(S("abcdefghijklmnopqrst"), 19, 0, S("1234567890"), S("abcdefghijklmnopqrs1234567890t")); + test(S("abcdefghijklmnopqrst"), 19, 0, S("12345678901234567890"), S("abcdefghijklmnopqrs12345678901234567890t")); + test(S("abcdefghijklmnopqrst"), 19, 1, S(""), S("abcdefghijklmnopqrs")); + test(S("abcdefghijklmnopqrst"), 19, 1, S("12345"), S("abcdefghijklmnopqrs12345")); + test(S("abcdefghijklmnopqrst"), 19, 1, S("1234567890"), S("abcdefghijklmnopqrs1234567890")); + test(S("abcdefghijklmnopqrst"), 19, 1, S("12345678901234567890"), S("abcdefghijklmnopqrs12345678901234567890")); + test(S("abcdefghijklmnopqrst"), 20, 0, S(""), S("abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 20, 0, S("12345"), S("abcdefghijklmnopqrst12345")); + test(S("abcdefghijklmnopqrst"), 20, 0, S("1234567890"), S("abcdefghijklmnopqrst1234567890")); + test(S("abcdefghijklmnopqrst"), 20, 0, S("12345678901234567890"), S("abcdefghijklmnopqrst12345678901234567890")); +} + +int main() +{ + { + typedef std::string S; + test0(); + test1(); + test2(); + } +#if TEST_STD_VER >= 11 + { + typedef std::basic_string, min_allocator> S; + test0(); + test1(); + test2(); + } +#endif + +#if TEST_STD_VER > 3 + { // LWG 2946 + std::string s = " "; + s.replace(s.cbegin(), s.cend(), {"abc", 1}); + assert(s.size() == 1); + assert(s == "a"); + } +#endif +} diff --git a/tests/external/libcxx/basic_string/string.modifiers/string_replace/iter_iter_string_view.pass.cpp b/tests/external/libcxx/basic_string/string.modifiers/string_replace/iter_iter_string_view.pass.cpp new file mode 100644 index 0000000..ec81001 --- /dev/null +++ b/tests/external/libcxx/basic_string/string.modifiers/string_replace/iter_iter_string_view.pass.cpp @@ -0,0 +1,286 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// + +// basic_string& +// replace(const_iterator i1, const_iterator i2, basic_string_view sv); + +#include +#include +#include + +#include "test_macros.h" +#include "min_allocator.h" + +template +void +test(S s, typename S::size_type pos1, typename S::size_type n1, SV sv, S expected) +{ + typename S::size_type old_size = s.size(); + typename S::const_iterator first = s.begin() + pos1; + typename S::const_iterator last = s.begin() + pos1 + n1; + typename S::size_type xlen = last - first; + s.replace(first, last, sv); + LIBCPP_ASSERT(s.__invariants()); + assert(s == expected); + typename S::size_type rlen = sv.size(); + assert(s.size() == old_size - xlen + rlen); +} + +template +void test0() +{ + test(S(""), 0, 0, SV(""), S("")); + test(S(""), 0, 0, SV("12345"), S("12345")); + test(S(""), 0, 0, SV("1234567890"), S("1234567890")); + test(S(""), 0, 0, SV("12345678901234567890"), S("12345678901234567890")); + test(S("abcde"), 0, 0, SV(""), S("abcde")); + test(S("abcde"), 0, 0, SV("12345"), S("12345abcde")); + test(S("abcde"), 0, 0, SV("1234567890"), S("1234567890abcde")); + test(S("abcde"), 0, 0, SV("12345678901234567890"), S("12345678901234567890abcde")); + test(S("abcde"), 0, 1, SV(""), S("bcde")); + test(S("abcde"), 0, 1, SV("12345"), S("12345bcde")); + test(S("abcde"), 0, 1, SV("1234567890"), S("1234567890bcde")); + test(S("abcde"), 0, 1, SV("12345678901234567890"), S("12345678901234567890bcde")); + test(S("abcde"), 0, 2, SV(""), S("cde")); + test(S("abcde"), 0, 2, SV("12345"), S("12345cde")); + test(S("abcde"), 0, 2, SV("1234567890"), S("1234567890cde")); + test(S("abcde"), 0, 2, SV("12345678901234567890"), S("12345678901234567890cde")); + test(S("abcde"), 0, 4, SV(""), S("e")); + test(S("abcde"), 0, 4, SV("12345"), S("12345e")); + test(S("abcde"), 0, 4, SV("1234567890"), S("1234567890e")); + test(S("abcde"), 0, 4, SV("12345678901234567890"), S("12345678901234567890e")); + test(S("abcde"), 0, 5, SV(""), S("")); + test(S("abcde"), 0, 5, SV("12345"), S("12345")); + test(S("abcde"), 0, 5, SV("1234567890"), S("1234567890")); + test(S("abcde"), 0, 5, SV("12345678901234567890"), S("12345678901234567890")); + test(S("abcde"), 1, 0, SV(""), S("abcde")); + test(S("abcde"), 1, 0, SV("12345"), S("a12345bcde")); + test(S("abcde"), 1, 0, SV("1234567890"), S("a1234567890bcde")); + test(S("abcde"), 1, 0, SV("12345678901234567890"), S("a12345678901234567890bcde")); + test(S("abcde"), 1, 1, SV(""), S("acde")); + test(S("abcde"), 1, 1, SV("12345"), S("a12345cde")); + test(S("abcde"), 1, 1, SV("1234567890"), S("a1234567890cde")); + test(S("abcde"), 1, 1, SV("12345678901234567890"), S("a12345678901234567890cde")); + test(S("abcde"), 1, 2, SV(""), S("ade")); + test(S("abcde"), 1, 2, SV("12345"), S("a12345de")); + test(S("abcde"), 1, 2, SV("1234567890"), S("a1234567890de")); + test(S("abcde"), 1, 2, SV("12345678901234567890"), S("a12345678901234567890de")); + test(S("abcde"), 1, 3, SV(""), S("ae")); + test(S("abcde"), 1, 3, SV("12345"), S("a12345e")); + test(S("abcde"), 1, 3, SV("1234567890"), S("a1234567890e")); + test(S("abcde"), 1, 3, SV("12345678901234567890"), S("a12345678901234567890e")); + test(S("abcde"), 1, 4, SV(""), S("a")); + test(S("abcde"), 1, 4, SV("12345"), S("a12345")); + test(S("abcde"), 1, 4, SV("1234567890"), S("a1234567890")); + test(S("abcde"), 1, 4, SV("12345678901234567890"), S("a12345678901234567890")); + test(S("abcde"), 2, 0, SV(""), S("abcde")); + test(S("abcde"), 2, 0, SV("12345"), S("ab12345cde")); + test(S("abcde"), 2, 0, SV("1234567890"), S("ab1234567890cde")); + test(S("abcde"), 2, 0, SV("12345678901234567890"), S("ab12345678901234567890cde")); + test(S("abcde"), 2, 1, SV(""), S("abde")); + test(S("abcde"), 2, 1, SV("12345"), S("ab12345de")); + test(S("abcde"), 2, 1, SV("1234567890"), S("ab1234567890de")); + test(S("abcde"), 2, 1, SV("12345678901234567890"), S("ab12345678901234567890de")); + test(S("abcde"), 2, 2, SV(""), S("abe")); + test(S("abcde"), 2, 2, SV("12345"), S("ab12345e")); + test(S("abcde"), 2, 2, SV("1234567890"), S("ab1234567890e")); + test(S("abcde"), 2, 2, SV("12345678901234567890"), S("ab12345678901234567890e")); + test(S("abcde"), 2, 3, SV(""), S("ab")); + test(S("abcde"), 2, 3, SV("12345"), S("ab12345")); + test(S("abcde"), 2, 3, SV("1234567890"), S("ab1234567890")); + test(S("abcde"), 2, 3, SV("12345678901234567890"), S("ab12345678901234567890")); + test(S("abcde"), 4, 0, SV(""), S("abcde")); + test(S("abcde"), 4, 0, SV("12345"), S("abcd12345e")); + test(S("abcde"), 4, 0, SV("1234567890"), S("abcd1234567890e")); + test(S("abcde"), 4, 0, SV("12345678901234567890"), S("abcd12345678901234567890e")); + test(S("abcde"), 4, 1, SV(""), S("abcd")); + test(S("abcde"), 4, 1, SV("12345"), S("abcd12345")); + test(S("abcde"), 4, 1, SV("1234567890"), S("abcd1234567890")); + test(S("abcde"), 4, 1, SV("12345678901234567890"), S("abcd12345678901234567890")); + test(S("abcde"), 5, 0, SV(""), S("abcde")); + test(S("abcde"), 5, 0, SV("12345"), S("abcde12345")); + test(S("abcde"), 5, 0, SV("1234567890"), S("abcde1234567890")); + test(S("abcde"), 5, 0, SV("12345678901234567890"), S("abcde12345678901234567890")); + test(S("abcdefghij"), 0, 0, SV(""), S("abcdefghij")); + test(S("abcdefghij"), 0, 0, SV("12345"), S("12345abcdefghij")); + test(S("abcdefghij"), 0, 0, SV("1234567890"), S("1234567890abcdefghij")); + test(S("abcdefghij"), 0, 0, SV("12345678901234567890"), S("12345678901234567890abcdefghij")); + test(S("abcdefghij"), 0, 1, SV(""), S("bcdefghij")); + test(S("abcdefghij"), 0, 1, SV("12345"), S("12345bcdefghij")); + test(S("abcdefghij"), 0, 1, SV("1234567890"), S("1234567890bcdefghij")); + test(S("abcdefghij"), 0, 1, SV("12345678901234567890"), S("12345678901234567890bcdefghij")); + test(S("abcdefghij"), 0, 5, SV(""), S("fghij")); + test(S("abcdefghij"), 0, 5, SV("12345"), S("12345fghij")); + test(S("abcdefghij"), 0, 5, SV("1234567890"), S("1234567890fghij")); + test(S("abcdefghij"), 0, 5, SV("12345678901234567890"), S("12345678901234567890fghij")); + test(S("abcdefghij"), 0, 9, SV(""), S("j")); + test(S("abcdefghij"), 0, 9, SV("12345"), S("12345j")); + test(S("abcdefghij"), 0, 9, SV("1234567890"), S("1234567890j")); + test(S("abcdefghij"), 0, 9, SV("12345678901234567890"), S("12345678901234567890j")); + test(S("abcdefghij"), 0, 10, SV(""), S("")); + test(S("abcdefghij"), 0, 10, SV("12345"), S("12345")); + test(S("abcdefghij"), 0, 10, SV("1234567890"), S("1234567890")); + test(S("abcdefghij"), 0, 10, SV("12345678901234567890"), S("12345678901234567890")); + test(S("abcdefghij"), 1, 0, SV(""), S("abcdefghij")); + test(S("abcdefghij"), 1, 0, SV("12345"), S("a12345bcdefghij")); + test(S("abcdefghij"), 1, 0, SV("1234567890"), S("a1234567890bcdefghij")); + test(S("abcdefghij"), 1, 0, SV("12345678901234567890"), S("a12345678901234567890bcdefghij")); + test(S("abcdefghij"), 1, 1, SV(""), S("acdefghij")); + test(S("abcdefghij"), 1, 1, SV("12345"), S("a12345cdefghij")); + test(S("abcdefghij"), 1, 1, SV("1234567890"), S("a1234567890cdefghij")); + test(S("abcdefghij"), 1, 1, SV("12345678901234567890"), S("a12345678901234567890cdefghij")); +} + +template +void test1() +{ + test(S("abcdefghij"), 1, 4, SV(""), S("afghij")); + test(S("abcdefghij"), 1, 4, SV("12345"), S("a12345fghij")); + test(S("abcdefghij"), 1, 4, SV("1234567890"), S("a1234567890fghij")); + test(S("abcdefghij"), 1, 4, SV("12345678901234567890"), S("a12345678901234567890fghij")); + test(S("abcdefghij"), 1, 8, SV(""), S("aj")); + test(S("abcdefghij"), 1, 8, SV("12345"), S("a12345j")); + test(S("abcdefghij"), 1, 8, SV("1234567890"), S("a1234567890j")); + test(S("abcdefghij"), 1, 8, SV("12345678901234567890"), S("a12345678901234567890j")); + test(S("abcdefghij"), 1, 9, SV(""), S("a")); + test(S("abcdefghij"), 1, 9, SV("12345"), S("a12345")); + test(S("abcdefghij"), 1, 9, SV("1234567890"), S("a1234567890")); + test(S("abcdefghij"), 1, 9, SV("12345678901234567890"), S("a12345678901234567890")); + test(S("abcdefghij"), 5, 0, SV(""), S("abcdefghij")); + test(S("abcdefghij"), 5, 0, SV("12345"), S("abcde12345fghij")); + test(S("abcdefghij"), 5, 0, SV("1234567890"), S("abcde1234567890fghij")); + test(S("abcdefghij"), 5, 0, SV("12345678901234567890"), S("abcde12345678901234567890fghij")); + test(S("abcdefghij"), 5, 1, SV(""), S("abcdeghij")); + test(S("abcdefghij"), 5, 1, SV("12345"), S("abcde12345ghij")); + test(S("abcdefghij"), 5, 1, SV("1234567890"), S("abcde1234567890ghij")); + test(S("abcdefghij"), 5, 1, SV("12345678901234567890"), S("abcde12345678901234567890ghij")); + test(S("abcdefghij"), 5, 2, SV(""), S("abcdehij")); + test(S("abcdefghij"), 5, 2, SV("12345"), S("abcde12345hij")); + test(S("abcdefghij"), 5, 2, SV("1234567890"), S("abcde1234567890hij")); + test(S("abcdefghij"), 5, 2, SV("12345678901234567890"), S("abcde12345678901234567890hij")); + test(S("abcdefghij"), 5, 4, SV(""), S("abcdej")); + test(S("abcdefghij"), 5, 4, SV("12345"), S("abcde12345j")); + test(S("abcdefghij"), 5, 4, SV("1234567890"), S("abcde1234567890j")); + test(S("abcdefghij"), 5, 4, SV("12345678901234567890"), S("abcde12345678901234567890j")); + test(S("abcdefghij"), 5, 5, SV(""), S("abcde")); + test(S("abcdefghij"), 5, 5, SV("12345"), S("abcde12345")); + test(S("abcdefghij"), 5, 5, SV("1234567890"), S("abcde1234567890")); + test(S("abcdefghij"), 5, 5, SV("12345678901234567890"), S("abcde12345678901234567890")); + test(S("abcdefghij"), 9, 0, SV(""), S("abcdefghij")); + test(S("abcdefghij"), 9, 0, SV("12345"), S("abcdefghi12345j")); + test(S("abcdefghij"), 9, 0, SV("1234567890"), S("abcdefghi1234567890j")); + test(S("abcdefghij"), 9, 0, SV("12345678901234567890"), S("abcdefghi12345678901234567890j")); + test(S("abcdefghij"), 9, 1, SV(""), S("abcdefghi")); + test(S("abcdefghij"), 9, 1, SV("12345"), S("abcdefghi12345")); + test(S("abcdefghij"), 9, 1, SV("1234567890"), S("abcdefghi1234567890")); + test(S("abcdefghij"), 9, 1, SV("12345678901234567890"), S("abcdefghi12345678901234567890")); + test(S("abcdefghij"), 10, 0, SV(""), S("abcdefghij")); + test(S("abcdefghij"), 10, 0, SV("12345"), S("abcdefghij12345")); + test(S("abcdefghij"), 10, 0, SV("1234567890"), S("abcdefghij1234567890")); + test(S("abcdefghij"), 10, 0, SV("12345678901234567890"), S("abcdefghij12345678901234567890")); + test(S("abcdefghijklmnopqrst"), 0, 0, SV(""), S("abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, 0, SV("12345"), S("12345abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, 0, SV("1234567890"), S("1234567890abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, 0, SV("12345678901234567890"), S("12345678901234567890abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, 1, SV(""), S("bcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, 1, SV("12345"), S("12345bcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, 1, SV("1234567890"), S("1234567890bcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, 1, SV("12345678901234567890"), S("12345678901234567890bcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, 10, SV(""), S("klmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, 10, SV("12345"), S("12345klmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, 10, SV("1234567890"), S("1234567890klmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, 10, SV("12345678901234567890"), S("12345678901234567890klmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, 19, SV(""), S("t")); + test(S("abcdefghijklmnopqrst"), 0, 19, SV("12345"), S("12345t")); + test(S("abcdefghijklmnopqrst"), 0, 19, SV("1234567890"), S("1234567890t")); + test(S("abcdefghijklmnopqrst"), 0, 19, SV("12345678901234567890"), S("12345678901234567890t")); + test(S("abcdefghijklmnopqrst"), 0, 20, SV(""), S("")); + test(S("abcdefghijklmnopqrst"), 0, 20, SV("12345"), S("12345")); + test(S("abcdefghijklmnopqrst"), 0, 20, SV("1234567890"), S("1234567890")); + test(S("abcdefghijklmnopqrst"), 0, 20, SV("12345678901234567890"), S("12345678901234567890")); + test(S("abcdefghijklmnopqrst"), 1, 0, SV(""), S("abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, 0, SV("12345"), S("a12345bcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, 0, SV("1234567890"), S("a1234567890bcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, 0, SV("12345678901234567890"), S("a12345678901234567890bcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, 1, SV(""), S("acdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, 1, SV("12345"), S("a12345cdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, 1, SV("1234567890"), S("a1234567890cdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, 1, SV("12345678901234567890"), S("a12345678901234567890cdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, 9, SV(""), S("aklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, 9, SV("12345"), S("a12345klmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, 9, SV("1234567890"), S("a1234567890klmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, 9, SV("12345678901234567890"), S("a12345678901234567890klmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, 18, SV(""), S("at")); + test(S("abcdefghijklmnopqrst"), 1, 18, SV("12345"), S("a12345t")); + test(S("abcdefghijklmnopqrst"), 1, 18, SV("1234567890"), S("a1234567890t")); + test(S("abcdefghijklmnopqrst"), 1, 18, SV("12345678901234567890"), S("a12345678901234567890t")); + test(S("abcdefghijklmnopqrst"), 1, 19, SV(""), S("a")); + test(S("abcdefghijklmnopqrst"), 1, 19, SV("12345"), S("a12345")); + test(S("abcdefghijklmnopqrst"), 1, 19, SV("1234567890"), S("a1234567890")); + test(S("abcdefghijklmnopqrst"), 1, 19, SV("12345678901234567890"), S("a12345678901234567890")); + test(S("abcdefghijklmnopqrst"), 10, 0, SV(""), S("abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 10, 0, SV("12345"), S("abcdefghij12345klmnopqrst")); + test(S("abcdefghijklmnopqrst"), 10, 0, SV("1234567890"), S("abcdefghij1234567890klmnopqrst")); + test(S("abcdefghijklmnopqrst"), 10, 0, SV("12345678901234567890"), S("abcdefghij12345678901234567890klmnopqrst")); + test(S("abcdefghijklmnopqrst"), 10, 1, SV(""), S("abcdefghijlmnopqrst")); + test(S("abcdefghijklmnopqrst"), 10, 1, SV("12345"), S("abcdefghij12345lmnopqrst")); + test(S("abcdefghijklmnopqrst"), 10, 1, SV("1234567890"), S("abcdefghij1234567890lmnopqrst")); + test(S("abcdefghijklmnopqrst"), 10, 1, SV("12345678901234567890"), S("abcdefghij12345678901234567890lmnopqrst")); + test(S("abcdefghijklmnopqrst"), 10, 5, SV(""), S("abcdefghijpqrst")); + test(S("abcdefghijklmnopqrst"), 10, 5, SV("12345"), S("abcdefghij12345pqrst")); + test(S("abcdefghijklmnopqrst"), 10, 5, SV("1234567890"), S("abcdefghij1234567890pqrst")); + test(S("abcdefghijklmnopqrst"), 10, 5, SV("12345678901234567890"), S("abcdefghij12345678901234567890pqrst")); + test(S("abcdefghijklmnopqrst"), 10, 9, SV(""), S("abcdefghijt")); + test(S("abcdefghijklmnopqrst"), 10, 9, SV("12345"), S("abcdefghij12345t")); + test(S("abcdefghijklmnopqrst"), 10, 9, SV("1234567890"), S("abcdefghij1234567890t")); + test(S("abcdefghijklmnopqrst"), 10, 9, SV("12345678901234567890"), S("abcdefghij12345678901234567890t")); +} + +template +void test2() +{ + test(S("abcdefghijklmnopqrst"), 10, 10, SV(""), S("abcdefghij")); + test(S("abcdefghijklmnopqrst"), 10, 10, SV("12345"), S("abcdefghij12345")); + test(S("abcdefghijklmnopqrst"), 10, 10, SV("1234567890"), S("abcdefghij1234567890")); + test(S("abcdefghijklmnopqrst"), 10, 10, SV("12345678901234567890"), S("abcdefghij12345678901234567890")); + test(S("abcdefghijklmnopqrst"), 19, 0, SV(""), S("abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 19, 0, SV("12345"), S("abcdefghijklmnopqrs12345t")); + test(S("abcdefghijklmnopqrst"), 19, 0, SV("1234567890"), S("abcdefghijklmnopqrs1234567890t")); + test(S("abcdefghijklmnopqrst"), 19, 0, SV("12345678901234567890"), S("abcdefghijklmnopqrs12345678901234567890t")); + test(S("abcdefghijklmnopqrst"), 19, 1, SV(""), S("abcdefghijklmnopqrs")); + test(S("abcdefghijklmnopqrst"), 19, 1, SV("12345"), S("abcdefghijklmnopqrs12345")); + test(S("abcdefghijklmnopqrst"), 19, 1, SV("1234567890"), S("abcdefghijklmnopqrs1234567890")); + test(S("abcdefghijklmnopqrst"), 19, 1, SV("12345678901234567890"), S("abcdefghijklmnopqrs12345678901234567890")); + test(S("abcdefghijklmnopqrst"), 20, 0, SV(""), S("abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 20, 0, SV("12345"), S("abcdefghijklmnopqrst12345")); + test(S("abcdefghijklmnopqrst"), 20, 0, SV("1234567890"), S("abcdefghijklmnopqrst1234567890")); + test(S("abcdefghijklmnopqrst"), 20, 0, SV("12345678901234567890"), S("abcdefghijklmnopqrst12345678901234567890")); +} + +int main() +{ + { + typedef std::string S; + typedef std::string_view SV; + test0(); + test1(); + test2(); + } +#if TEST_STD_VER >= 11 + { + typedef std::basic_string, min_allocator> S; + typedef std::string_view SV; + test0(); + test1(); + test2(); + } +#endif +} diff --git a/tests/external/libcxx/basic_string/string.modifiers/string_replace/size_size_T_size_size.pass.cpp b/tests/external/libcxx/basic_string/string.modifiers/string_replace/size_size_T_size_size.pass.cpp new file mode 100644 index 0000000..dbf5f5b --- /dev/null +++ b/tests/external/libcxx/basic_string/string.modifiers/string_replace/size_size_T_size_size.pass.cpp @@ -0,0 +1,6029 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// + +// template +// basic_string& replace(size_type pos1, size_type n1, const T& t, +// size_type pos2, size_type n=npos); +// +// Mostly we're testing string_view here + +#include +#include +#include +#include + +#include "test_macros.h" +#include "min_allocator.h" + +template +void +test(S s, typename S::size_type pos1, typename S::size_type n1, + SV sv, typename S::size_type pos2, typename S::size_type n2, + S expected) +{ + typedef typename S::size_type SizeT; + static_assert((!std::is_same::value), ""); + + // String and string_view may not always share the same size type, + // but both types should have the same size (ex. int vs long) + static_assert(sizeof(SizeT) == sizeof(typename SV::size_type), ""); + + const SizeT old_size = s.size(); + S s0 = s; + if (pos1 <= old_size && pos2 <= sv.size()) + { + s.replace(pos1, n1, sv, pos2, n2); + LIBCPP_ASSERT(s.__invariants()); + assert(s == expected); + SizeT xlen = std::min(n1, old_size - pos1); + SizeT rlen = std::min(n2, sv.size() - pos2); + assert(s.size() == old_size - xlen + rlen); + } +#ifndef TEST_HAS_NO_EXCEPTIONS + else + { + try + { + s.replace(pos1, n1, sv, pos2, n2); + assert(false); + } + catch (std::out_of_range&) + { + assert(pos1 > old_size || pos2 > sv.size()); + assert(s == s0); + } + } +#endif +} + +template +void +test_npos(S s, typename S::size_type pos1, typename S::size_type n1, + SV sv, typename S::size_type pos2, + S expected) +{ + typedef typename S::size_type SizeT; + static_assert((!std::is_same::value), ""); + const SizeT old_size = s.size(); + S s0 = s; + if (pos1 <= old_size && pos2 <= sv.size()) + { + s.replace(pos1, n1, sv, pos2); + LIBCPP_ASSERT(s.__invariants()); + assert(s == expected); + SizeT xlen = std::min(n1, old_size - pos1); + SizeT rlen = std::min(S::npos, sv.size() - pos2); + assert(s.size() == old_size - xlen + rlen); + } +#ifndef TEST_HAS_NO_EXCEPTIONS + else + { + try + { + s.replace(pos1, n1, sv, pos2); + assert(false); + } + catch (std::out_of_range&) + { + assert(pos1 > old_size || pos2 > sv.size()); + assert(s == s0); + } + } +#endif +} + + +template +void test0() +{ + test(S(""), 0, 0, SV(""), 0, 0, S("")); + test(S(""), 0, 0, SV(""), 0, 1, S("")); + test(S(""), 0, 0, SV(""), 1, 0, S("can't happen")); + test(S(""), 0, 0, SV("12345"), 0, 0, S("")); + test(S(""), 0, 0, SV("12345"), 0, 1, S("1")); + test(S(""), 0, 0, SV("12345"), 0, 2, S("12")); + test(S(""), 0, 0, SV("12345"), 0, 4, S("1234")); + test(S(""), 0, 0, SV("12345"), 0, 5, S("12345")); + test(S(""), 0, 0, SV("12345"), 0, 6, S("12345")); + test(S(""), 0, 0, SV("12345"), 1, 0, S("")); + test(S(""), 0, 0, SV("12345"), 1, 1, S("2")); + test(S(""), 0, 0, SV("12345"), 1, 2, S("23")); + test(S(""), 0, 0, SV("12345"), 1, 3, S("234")); + test(S(""), 0, 0, SV("12345"), 1, 4, S("2345")); + test(S(""), 0, 0, SV("12345"), 1, 5, S("2345")); + test(S(""), 0, 0, SV("12345"), 2, 0, S("")); + test(S(""), 0, 0, SV("12345"), 2, 1, S("3")); + test(S(""), 0, 0, SV("12345"), 2, 2, S("34")); + test(S(""), 0, 0, SV("12345"), 2, 3, S("345")); + test(S(""), 0, 0, SV("12345"), 2, 4, S("345")); + test(S(""), 0, 0, SV("12345"), 4, 0, S("")); + test(S(""), 0, 0, SV("12345"), 4, 1, S("5")); + test(S(""), 0, 0, SV("12345"), 4, 2, S("5")); + test(S(""), 0, 0, SV("12345"), 5, 0, S("")); + test(S(""), 0, 0, SV("12345"), 5, 1, S("")); + test(S(""), 0, 0, SV("12345"), 6, 0, S("can't happen")); + test(S(""), 0, 0, SV("1234567890"), 0, 0, S("")); + test(S(""), 0, 0, SV("1234567890"), 0, 1, S("1")); + test(S(""), 0, 0, SV("1234567890"), 0, 5, S("12345")); + test(S(""), 0, 0, SV("1234567890"), 0, 9, S("123456789")); + test(S(""), 0, 0, SV("1234567890"), 0, 10, S("1234567890")); + test(S(""), 0, 0, SV("1234567890"), 0, 11, S("1234567890")); + test(S(""), 0, 0, SV("1234567890"), 1, 0, S("")); + test(S(""), 0, 0, SV("1234567890"), 1, 1, S("2")); + test(S(""), 0, 0, SV("1234567890"), 1, 4, S("2345")); + test(S(""), 0, 0, SV("1234567890"), 1, 8, S("23456789")); + test(S(""), 0, 0, SV("1234567890"), 1, 9, S("234567890")); + test(S(""), 0, 0, SV("1234567890"), 1, 10, S("234567890")); + test(S(""), 0, 0, SV("1234567890"), 5, 0, S("")); + test(S(""), 0, 0, SV("1234567890"), 5, 1, S("6")); + test(S(""), 0, 0, SV("1234567890"), 5, 2, S("67")); + test(S(""), 0, 0, SV("1234567890"), 5, 4, S("6789")); + test(S(""), 0, 0, SV("1234567890"), 5, 5, S("67890")); + test(S(""), 0, 0, SV("1234567890"), 5, 6, S("67890")); + test(S(""), 0, 0, SV("1234567890"), 9, 0, S("")); + test(S(""), 0, 0, SV("1234567890"), 9, 1, S("0")); + test(S(""), 0, 0, SV("1234567890"), 9, 2, S("0")); + test(S(""), 0, 0, SV("1234567890"), 10, 0, S("")); + test(S(""), 0, 0, SV("1234567890"), 10, 1, S("")); + test(S(""), 0, 0, SV("1234567890"), 11, 0, S("can't happen")); + test(S(""), 0, 0, SV("12345678901234567890"), 0, 0, S("")); + test(S(""), 0, 0, SV("12345678901234567890"), 0, 1, S("1")); + test(S(""), 0, 0, SV("12345678901234567890"), 0, 10, S("1234567890")); + test(S(""), 0, 0, SV("12345678901234567890"), 0, 19, S("1234567890123456789")); + test(S(""), 0, 0, SV("12345678901234567890"), 0, 20, S("12345678901234567890")); + test(S(""), 0, 0, SV("12345678901234567890"), 0, 21, S("12345678901234567890")); + test(S(""), 0, 0, SV("12345678901234567890"), 1, 0, S("")); + test(S(""), 0, 0, SV("12345678901234567890"), 1, 1, S("2")); + test(S(""), 0, 0, SV("12345678901234567890"), 1, 9, S("234567890")); + test(S(""), 0, 0, SV("12345678901234567890"), 1, 18, S("234567890123456789")); + test(S(""), 0, 0, SV("12345678901234567890"), 1, 19, S("2345678901234567890")); + test(S(""), 0, 0, SV("12345678901234567890"), 1, 20, S("2345678901234567890")); + test(S(""), 0, 0, SV("12345678901234567890"), 10, 0, S("")); + test(S(""), 0, 0, SV("12345678901234567890"), 10, 1, S("1")); + test(S(""), 0, 0, SV("12345678901234567890"), 10, 5, S("12345")); + test(S(""), 0, 0, SV("12345678901234567890"), 10, 9, S("123456789")); + test(S(""), 0, 0, SV("12345678901234567890"), 10, 10, S("1234567890")); + test(S(""), 0, 0, SV("12345678901234567890"), 10, 11, S("1234567890")); + test(S(""), 0, 0, SV("12345678901234567890"), 19, 0, S("")); + test(S(""), 0, 0, SV("12345678901234567890"), 19, 1, S("0")); + test(S(""), 0, 0, SV("12345678901234567890"), 19, 2, S("0")); + test(S(""), 0, 0, SV("12345678901234567890"), 20, 0, S("")); + test(S(""), 0, 0, SV("12345678901234567890"), 20, 1, S("")); + test(S(""), 0, 0, SV("12345678901234567890"), 21, 0, S("can't happen")); + test(S(""), 0, 1, SV(""), 0, 0, S("")); + test(S(""), 0, 1, SV(""), 0, 1, S("")); + test(S(""), 0, 1, SV(""), 1, 0, S("can't happen")); + test(S(""), 0, 1, SV("12345"), 0, 0, S("")); + test(S(""), 0, 1, SV("12345"), 0, 1, S("1")); + test(S(""), 0, 1, SV("12345"), 0, 2, S("12")); + test(S(""), 0, 1, SV("12345"), 0, 4, S("1234")); + test(S(""), 0, 1, SV("12345"), 0, 5, S("12345")); + test(S(""), 0, 1, SV("12345"), 0, 6, S("12345")); + test(S(""), 0, 1, SV("12345"), 1, 0, S("")); + test(S(""), 0, 1, SV("12345"), 1, 1, S("2")); + test(S(""), 0, 1, SV("12345"), 1, 2, S("23")); + test(S(""), 0, 1, SV("12345"), 1, 3, S("234")); + test(S(""), 0, 1, SV("12345"), 1, 4, S("2345")); + test(S(""), 0, 1, SV("12345"), 1, 5, S("2345")); + test(S(""), 0, 1, SV("12345"), 2, 0, S("")); + test(S(""), 0, 1, SV("12345"), 2, 1, S("3")); + test(S(""), 0, 1, SV("12345"), 2, 2, S("34")); + test(S(""), 0, 1, SV("12345"), 2, 3, S("345")); + test(S(""), 0, 1, SV("12345"), 2, 4, S("345")); + test(S(""), 0, 1, SV("12345"), 4, 0, S("")); + test(S(""), 0, 1, SV("12345"), 4, 1, S("5")); + test(S(""), 0, 1, SV("12345"), 4, 2, S("5")); + test(S(""), 0, 1, SV("12345"), 5, 0, S("")); + test(S(""), 0, 1, SV("12345"), 5, 1, S("")); + test(S(""), 0, 1, SV("12345"), 6, 0, S("can't happen")); +} + +template +void test1() +{ + test(S(""), 0, 1, SV("1234567890"), 0, 0, S("")); + test(S(""), 0, 1, SV("1234567890"), 0, 1, S("1")); + test(S(""), 0, 1, SV("1234567890"), 0, 5, S("12345")); + test(S(""), 0, 1, SV("1234567890"), 0, 9, S("123456789")); + test(S(""), 0, 1, SV("1234567890"), 0, 10, S("1234567890")); + test(S(""), 0, 1, SV("1234567890"), 0, 11, S("1234567890")); + test(S(""), 0, 1, SV("1234567890"), 1, 0, S("")); + test(S(""), 0, 1, SV("1234567890"), 1, 1, S("2")); + test(S(""), 0, 1, SV("1234567890"), 1, 4, S("2345")); + test(S(""), 0, 1, SV("1234567890"), 1, 8, S("23456789")); + test(S(""), 0, 1, SV("1234567890"), 1, 9, S("234567890")); + test(S(""), 0, 1, SV("1234567890"), 1, 10, S("234567890")); + test(S(""), 0, 1, SV("1234567890"), 5, 0, S("")); + test(S(""), 0, 1, SV("1234567890"), 5, 1, S("6")); + test(S(""), 0, 1, SV("1234567890"), 5, 2, S("67")); + test(S(""), 0, 1, SV("1234567890"), 5, 4, S("6789")); + test(S(""), 0, 1, SV("1234567890"), 5, 5, S("67890")); + test(S(""), 0, 1, SV("1234567890"), 5, 6, S("67890")); + test(S(""), 0, 1, SV("1234567890"), 9, 0, S("")); + test(S(""), 0, 1, SV("1234567890"), 9, 1, S("0")); + test(S(""), 0, 1, SV("1234567890"), 9, 2, S("0")); + test(S(""), 0, 1, SV("1234567890"), 10, 0, S("")); + test(S(""), 0, 1, SV("1234567890"), 10, 1, S("")); + test(S(""), 0, 1, SV("1234567890"), 11, 0, S("can't happen")); + test(S(""), 0, 1, SV("12345678901234567890"), 0, 0, S("")); + test(S(""), 0, 1, SV("12345678901234567890"), 0, 1, S("1")); + test(S(""), 0, 1, SV("12345678901234567890"), 0, 10, S("1234567890")); + test(S(""), 0, 1, SV("12345678901234567890"), 0, 19, S("1234567890123456789")); + test(S(""), 0, 1, SV("12345678901234567890"), 0, 20, S("12345678901234567890")); + test(S(""), 0, 1, SV("12345678901234567890"), 0, 21, S("12345678901234567890")); + test(S(""), 0, 1, SV("12345678901234567890"), 1, 0, S("")); + test(S(""), 0, 1, SV("12345678901234567890"), 1, 1, S("2")); + test(S(""), 0, 1, SV("12345678901234567890"), 1, 9, S("234567890")); + test(S(""), 0, 1, SV("12345678901234567890"), 1, 18, S("234567890123456789")); + test(S(""), 0, 1, SV("12345678901234567890"), 1, 19, S("2345678901234567890")); + test(S(""), 0, 1, SV("12345678901234567890"), 1, 20, S("2345678901234567890")); + test(S(""), 0, 1, SV("12345678901234567890"), 10, 0, S("")); + test(S(""), 0, 1, SV("12345678901234567890"), 10, 1, S("1")); + test(S(""), 0, 1, SV("12345678901234567890"), 10, 5, S("12345")); + test(S(""), 0, 1, SV("12345678901234567890"), 10, 9, S("123456789")); + test(S(""), 0, 1, SV("12345678901234567890"), 10, 10, S("1234567890")); + test(S(""), 0, 1, SV("12345678901234567890"), 10, 11, S("1234567890")); + test(S(""), 0, 1, SV("12345678901234567890"), 19, 0, S("")); + test(S(""), 0, 1, SV("12345678901234567890"), 19, 1, S("0")); + test(S(""), 0, 1, SV("12345678901234567890"), 19, 2, S("0")); + test(S(""), 0, 1, SV("12345678901234567890"), 20, 0, S("")); + test(S(""), 0, 1, SV("12345678901234567890"), 20, 1, S("")); + test(S(""), 0, 1, SV("12345678901234567890"), 21, 0, S("can't happen")); + test(S(""), 1, 0, SV(""), 0, 0, S("can't happen")); + test(S(""), 1, 0, SV(""), 0, 1, S("can't happen")); + test(S(""), 1, 0, SV(""), 1, 0, S("can't happen")); + test(S(""), 1, 0, SV("12345"), 0, 0, S("can't happen")); + test(S(""), 1, 0, SV("12345"), 0, 1, S("can't happen")); + test(S(""), 1, 0, SV("12345"), 0, 2, S("can't happen")); + test(S(""), 1, 0, SV("12345"), 0, 4, S("can't happen")); + test(S(""), 1, 0, SV("12345"), 0, 5, S("can't happen")); + test(S(""), 1, 0, SV("12345"), 0, 6, S("can't happen")); + test(S(""), 1, 0, SV("12345"), 1, 0, S("can't happen")); + test(S(""), 1, 0, SV("12345"), 1, 1, S("can't happen")); + test(S(""), 1, 0, SV("12345"), 1, 2, S("can't happen")); + test(S(""), 1, 0, SV("12345"), 1, 3, S("can't happen")); + test(S(""), 1, 0, SV("12345"), 1, 4, S("can't happen")); + test(S(""), 1, 0, SV("12345"), 1, 5, S("can't happen")); + test(S(""), 1, 0, SV("12345"), 2, 0, S("can't happen")); + test(S(""), 1, 0, SV("12345"), 2, 1, S("can't happen")); + test(S(""), 1, 0, SV("12345"), 2, 2, S("can't happen")); + test(S(""), 1, 0, SV("12345"), 2, 3, S("can't happen")); + test(S(""), 1, 0, SV("12345"), 2, 4, S("can't happen")); + test(S(""), 1, 0, SV("12345"), 4, 0, S("can't happen")); + test(S(""), 1, 0, SV("12345"), 4, 1, S("can't happen")); + test(S(""), 1, 0, SV("12345"), 4, 2, S("can't happen")); + test(S(""), 1, 0, SV("12345"), 5, 0, S("can't happen")); + test(S(""), 1, 0, SV("12345"), 5, 1, S("can't happen")); + test(S(""), 1, 0, SV("12345"), 6, 0, S("can't happen")); + test(S(""), 1, 0, SV("1234567890"), 0, 0, S("can't happen")); + test(S(""), 1, 0, SV("1234567890"), 0, 1, S("can't happen")); + test(S(""), 1, 0, SV("1234567890"), 0, 5, S("can't happen")); + test(S(""), 1, 0, SV("1234567890"), 0, 9, S("can't happen")); + test(S(""), 1, 0, SV("1234567890"), 0, 10, S("can't happen")); + test(S(""), 1, 0, SV("1234567890"), 0, 11, S("can't happen")); + test(S(""), 1, 0, SV("1234567890"), 1, 0, S("can't happen")); + test(S(""), 1, 0, SV("1234567890"), 1, 1, S("can't happen")); + test(S(""), 1, 0, SV("1234567890"), 1, 4, S("can't happen")); + test(S(""), 1, 0, SV("1234567890"), 1, 8, S("can't happen")); + test(S(""), 1, 0, SV("1234567890"), 1, 9, S("can't happen")); + test(S(""), 1, 0, SV("1234567890"), 1, 10, S("can't happen")); + test(S(""), 1, 0, SV("1234567890"), 5, 0, S("can't happen")); + test(S(""), 1, 0, SV("1234567890"), 5, 1, S("can't happen")); + test(S(""), 1, 0, SV("1234567890"), 5, 2, S("can't happen")); + test(S(""), 1, 0, SV("1234567890"), 5, 4, S("can't happen")); + test(S(""), 1, 0, SV("1234567890"), 5, 5, S("can't happen")); + test(S(""), 1, 0, SV("1234567890"), 5, 6, S("can't happen")); + test(S(""), 1, 0, SV("1234567890"), 9, 0, S("can't happen")); + test(S(""), 1, 0, SV("1234567890"), 9, 1, S("can't happen")); + test(S(""), 1, 0, SV("1234567890"), 9, 2, S("can't happen")); + test(S(""), 1, 0, SV("1234567890"), 10, 0, S("can't happen")); + test(S(""), 1, 0, SV("1234567890"), 10, 1, S("can't happen")); + test(S(""), 1, 0, SV("1234567890"), 11, 0, S("can't happen")); + test(S(""), 1, 0, SV("12345678901234567890"), 0, 0, S("can't happen")); + test(S(""), 1, 0, SV("12345678901234567890"), 0, 1, S("can't happen")); +} + +template +void test2() +{ + test(S(""), 1, 0, SV("12345678901234567890"), 0, 10, S("can't happen")); + test(S(""), 1, 0, SV("12345678901234567890"), 0, 19, S("can't happen")); + test(S(""), 1, 0, SV("12345678901234567890"), 0, 20, S("can't happen")); + test(S(""), 1, 0, SV("12345678901234567890"), 0, 21, S("can't happen")); + test(S(""), 1, 0, SV("12345678901234567890"), 1, 0, S("can't happen")); + test(S(""), 1, 0, SV("12345678901234567890"), 1, 1, S("can't happen")); + test(S(""), 1, 0, SV("12345678901234567890"), 1, 9, S("can't happen")); + test(S(""), 1, 0, SV("12345678901234567890"), 1, 18, S("can't happen")); + test(S(""), 1, 0, SV("12345678901234567890"), 1, 19, S("can't happen")); + test(S(""), 1, 0, SV("12345678901234567890"), 1, 20, S("can't happen")); + test(S(""), 1, 0, SV("12345678901234567890"), 10, 0, S("can't happen")); + test(S(""), 1, 0, SV("12345678901234567890"), 10, 1, S("can't happen")); + test(S(""), 1, 0, SV("12345678901234567890"), 10, 5, S("can't happen")); + test(S(""), 1, 0, SV("12345678901234567890"), 10, 9, S("can't happen")); + test(S(""), 1, 0, SV("12345678901234567890"), 10, 10, S("can't happen")); + test(S(""), 1, 0, SV("12345678901234567890"), 10, 11, S("can't happen")); + test(S(""), 1, 0, SV("12345678901234567890"), 19, 0, S("can't happen")); + test(S(""), 1, 0, SV("12345678901234567890"), 19, 1, S("can't happen")); + test(S(""), 1, 0, SV("12345678901234567890"), 19, 2, S("can't happen")); + test(S(""), 1, 0, SV("12345678901234567890"), 20, 0, S("can't happen")); + test(S(""), 1, 0, SV("12345678901234567890"), 20, 1, S("can't happen")); + test(S(""), 1, 0, SV("12345678901234567890"), 21, 0, S("can't happen")); + test(S("abcde"), 0, 0, SV(""), 0, 0, S("abcde")); + test(S("abcde"), 0, 0, SV(""), 0, 1, S("abcde")); + test(S("abcde"), 0, 0, SV(""), 1, 0, S("can't happen")); + test(S("abcde"), 0, 0, SV("12345"), 0, 0, S("abcde")); + test(S("abcde"), 0, 0, SV("12345"), 0, 1, S("1abcde")); + test(S("abcde"), 0, 0, SV("12345"), 0, 2, S("12abcde")); + test(S("abcde"), 0, 0, SV("12345"), 0, 4, S("1234abcde")); + test(S("abcde"), 0, 0, SV("12345"), 0, 5, S("12345abcde")); + test(S("abcde"), 0, 0, SV("12345"), 0, 6, S("12345abcde")); + test(S("abcde"), 0, 0, SV("12345"), 1, 0, S("abcde")); + test(S("abcde"), 0, 0, SV("12345"), 1, 1, S("2abcde")); + test(S("abcde"), 0, 0, SV("12345"), 1, 2, S("23abcde")); + test(S("abcde"), 0, 0, SV("12345"), 1, 3, S("234abcde")); + test(S("abcde"), 0, 0, SV("12345"), 1, 4, S("2345abcde")); + test(S("abcde"), 0, 0, SV("12345"), 1, 5, S("2345abcde")); + test(S("abcde"), 0, 0, SV("12345"), 2, 0, S("abcde")); + test(S("abcde"), 0, 0, SV("12345"), 2, 1, S("3abcde")); + test(S("abcde"), 0, 0, SV("12345"), 2, 2, S("34abcde")); + test(S("abcde"), 0, 0, SV("12345"), 2, 3, S("345abcde")); + test(S("abcde"), 0, 0, SV("12345"), 2, 4, S("345abcde")); + test(S("abcde"), 0, 0, SV("12345"), 4, 0, S("abcde")); + test(S("abcde"), 0, 0, SV("12345"), 4, 1, S("5abcde")); + test(S("abcde"), 0, 0, SV("12345"), 4, 2, S("5abcde")); + test(S("abcde"), 0, 0, SV("12345"), 5, 0, S("abcde")); + test(S("abcde"), 0, 0, SV("12345"), 5, 1, S("abcde")); + test(S("abcde"), 0, 0, SV("12345"), 6, 0, S("can't happen")); + test(S("abcde"), 0, 0, SV("1234567890"), 0, 0, S("abcde")); + test(S("abcde"), 0, 0, SV("1234567890"), 0, 1, S("1abcde")); + test(S("abcde"), 0, 0, SV("1234567890"), 0, 5, S("12345abcde")); + test(S("abcde"), 0, 0, SV("1234567890"), 0, 9, S("123456789abcde")); + test(S("abcde"), 0, 0, SV("1234567890"), 0, 10, S("1234567890abcde")); + test(S("abcde"), 0, 0, SV("1234567890"), 0, 11, S("1234567890abcde")); + test(S("abcde"), 0, 0, SV("1234567890"), 1, 0, S("abcde")); + test(S("abcde"), 0, 0, SV("1234567890"), 1, 1, S("2abcde")); + test(S("abcde"), 0, 0, SV("1234567890"), 1, 4, S("2345abcde")); + test(S("abcde"), 0, 0, SV("1234567890"), 1, 8, S("23456789abcde")); + test(S("abcde"), 0, 0, SV("1234567890"), 1, 9, S("234567890abcde")); + test(S("abcde"), 0, 0, SV("1234567890"), 1, 10, S("234567890abcde")); + test(S("abcde"), 0, 0, SV("1234567890"), 5, 0, S("abcde")); + test(S("abcde"), 0, 0, SV("1234567890"), 5, 1, S("6abcde")); + test(S("abcde"), 0, 0, SV("1234567890"), 5, 2, S("67abcde")); + test(S("abcde"), 0, 0, SV("1234567890"), 5, 4, S("6789abcde")); + test(S("abcde"), 0, 0, SV("1234567890"), 5, 5, S("67890abcde")); + test(S("abcde"), 0, 0, SV("1234567890"), 5, 6, S("67890abcde")); + test(S("abcde"), 0, 0, SV("1234567890"), 9, 0, S("abcde")); + test(S("abcde"), 0, 0, SV("1234567890"), 9, 1, S("0abcde")); + test(S("abcde"), 0, 0, SV("1234567890"), 9, 2, S("0abcde")); + test(S("abcde"), 0, 0, SV("1234567890"), 10, 0, S("abcde")); + test(S("abcde"), 0, 0, SV("1234567890"), 10, 1, S("abcde")); + test(S("abcde"), 0, 0, SV("1234567890"), 11, 0, S("can't happen")); + test(S("abcde"), 0, 0, SV("12345678901234567890"), 0, 0, S("abcde")); + test(S("abcde"), 0, 0, SV("12345678901234567890"), 0, 1, S("1abcde")); + test(S("abcde"), 0, 0, SV("12345678901234567890"), 0, 10, S("1234567890abcde")); + test(S("abcde"), 0, 0, SV("12345678901234567890"), 0, 19, S("1234567890123456789abcde")); + test(S("abcde"), 0, 0, SV("12345678901234567890"), 0, 20, S("12345678901234567890abcde")); + test(S("abcde"), 0, 0, SV("12345678901234567890"), 0, 21, S("12345678901234567890abcde")); + test(S("abcde"), 0, 0, SV("12345678901234567890"), 1, 0, S("abcde")); + test(S("abcde"), 0, 0, SV("12345678901234567890"), 1, 1, S("2abcde")); + test(S("abcde"), 0, 0, SV("12345678901234567890"), 1, 9, S("234567890abcde")); + test(S("abcde"), 0, 0, SV("12345678901234567890"), 1, 18, S("234567890123456789abcde")); + test(S("abcde"), 0, 0, SV("12345678901234567890"), 1, 19, S("2345678901234567890abcde")); + test(S("abcde"), 0, 0, SV("12345678901234567890"), 1, 20, S("2345678901234567890abcde")); + test(S("abcde"), 0, 0, SV("12345678901234567890"), 10, 0, S("abcde")); + test(S("abcde"), 0, 0, SV("12345678901234567890"), 10, 1, S("1abcde")); + test(S("abcde"), 0, 0, SV("12345678901234567890"), 10, 5, S("12345abcde")); + test(S("abcde"), 0, 0, SV("12345678901234567890"), 10, 9, S("123456789abcde")); + test(S("abcde"), 0, 0, SV("12345678901234567890"), 10, 10, S("1234567890abcde")); + test(S("abcde"), 0, 0, SV("12345678901234567890"), 10, 11, S("1234567890abcde")); + test(S("abcde"), 0, 0, SV("12345678901234567890"), 19, 0, S("abcde")); + test(S("abcde"), 0, 0, SV("12345678901234567890"), 19, 1, S("0abcde")); + test(S("abcde"), 0, 0, SV("12345678901234567890"), 19, 2, S("0abcde")); + test(S("abcde"), 0, 0, SV("12345678901234567890"), 20, 0, S("abcde")); + test(S("abcde"), 0, 0, SV("12345678901234567890"), 20, 1, S("abcde")); + test(S("abcde"), 0, 0, SV("12345678901234567890"), 21, 0, S("can't happen")); + test(S("abcde"), 0, 1, SV(""), 0, 0, S("bcde")); + test(S("abcde"), 0, 1, SV(""), 0, 1, S("bcde")); + test(S("abcde"), 0, 1, SV(""), 1, 0, S("can't happen")); + test(S("abcde"), 0, 1, SV("12345"), 0, 0, S("bcde")); +} + +template +void test3() +{ + test(S("abcde"), 0, 1, SV("12345"), 0, 1, S("1bcde")); + test(S("abcde"), 0, 1, SV("12345"), 0, 2, S("12bcde")); + test(S("abcde"), 0, 1, SV("12345"), 0, 4, S("1234bcde")); + test(S("abcde"), 0, 1, SV("12345"), 0, 5, S("12345bcde")); + test(S("abcde"), 0, 1, SV("12345"), 0, 6, S("12345bcde")); + test(S("abcde"), 0, 1, SV("12345"), 1, 0, S("bcde")); + test(S("abcde"), 0, 1, SV("12345"), 1, 1, S("2bcde")); + test(S("abcde"), 0, 1, SV("12345"), 1, 2, S("23bcde")); + test(S("abcde"), 0, 1, SV("12345"), 1, 3, S("234bcde")); + test(S("abcde"), 0, 1, SV("12345"), 1, 4, S("2345bcde")); + test(S("abcde"), 0, 1, SV("12345"), 1, 5, S("2345bcde")); + test(S("abcde"), 0, 1, SV("12345"), 2, 0, S("bcde")); + test(S("abcde"), 0, 1, SV("12345"), 2, 1, S("3bcde")); + test(S("abcde"), 0, 1, SV("12345"), 2, 2, S("34bcde")); + test(S("abcde"), 0, 1, SV("12345"), 2, 3, S("345bcde")); + test(S("abcde"), 0, 1, SV("12345"), 2, 4, S("345bcde")); + test(S("abcde"), 0, 1, SV("12345"), 4, 0, S("bcde")); + test(S("abcde"), 0, 1, SV("12345"), 4, 1, S("5bcde")); + test(S("abcde"), 0, 1, SV("12345"), 4, 2, S("5bcde")); + test(S("abcde"), 0, 1, SV("12345"), 5, 0, S("bcde")); + test(S("abcde"), 0, 1, SV("12345"), 5, 1, S("bcde")); + test(S("abcde"), 0, 1, SV("12345"), 6, 0, S("can't happen")); + test(S("abcde"), 0, 1, SV("1234567890"), 0, 0, S("bcde")); + test(S("abcde"), 0, 1, SV("1234567890"), 0, 1, S("1bcde")); + test(S("abcde"), 0, 1, SV("1234567890"), 0, 5, S("12345bcde")); + test(S("abcde"), 0, 1, SV("1234567890"), 0, 9, S("123456789bcde")); + test(S("abcde"), 0, 1, SV("1234567890"), 0, 10, S("1234567890bcde")); + test(S("abcde"), 0, 1, SV("1234567890"), 0, 11, S("1234567890bcde")); + test(S("abcde"), 0, 1, SV("1234567890"), 1, 0, S("bcde")); + test(S("abcde"), 0, 1, SV("1234567890"), 1, 1, S("2bcde")); + test(S("abcde"), 0, 1, SV("1234567890"), 1, 4, S("2345bcde")); + test(S("abcde"), 0, 1, SV("1234567890"), 1, 8, S("23456789bcde")); + test(S("abcde"), 0, 1, SV("1234567890"), 1, 9, S("234567890bcde")); + test(S("abcde"), 0, 1, SV("1234567890"), 1, 10, S("234567890bcde")); + test(S("abcde"), 0, 1, SV("1234567890"), 5, 0, S("bcde")); + test(S("abcde"), 0, 1, SV("1234567890"), 5, 1, S("6bcde")); + test(S("abcde"), 0, 1, SV("1234567890"), 5, 2, S("67bcde")); + test(S("abcde"), 0, 1, SV("1234567890"), 5, 4, S("6789bcde")); + test(S("abcde"), 0, 1, SV("1234567890"), 5, 5, S("67890bcde")); + test(S("abcde"), 0, 1, SV("1234567890"), 5, 6, S("67890bcde")); + test(S("abcde"), 0, 1, SV("1234567890"), 9, 0, S("bcde")); + test(S("abcde"), 0, 1, SV("1234567890"), 9, 1, S("0bcde")); + test(S("abcde"), 0, 1, SV("1234567890"), 9, 2, S("0bcde")); + test(S("abcde"), 0, 1, SV("1234567890"), 10, 0, S("bcde")); + test(S("abcde"), 0, 1, SV("1234567890"), 10, 1, S("bcde")); + test(S("abcde"), 0, 1, SV("1234567890"), 11, 0, S("can't happen")); + test(S("abcde"), 0, 1, SV("12345678901234567890"), 0, 0, S("bcde")); + test(S("abcde"), 0, 1, SV("12345678901234567890"), 0, 1, S("1bcde")); + test(S("abcde"), 0, 1, SV("12345678901234567890"), 0, 10, S("1234567890bcde")); + test(S("abcde"), 0, 1, SV("12345678901234567890"), 0, 19, S("1234567890123456789bcde")); + test(S("abcde"), 0, 1, SV("12345678901234567890"), 0, 20, S("12345678901234567890bcde")); + test(S("abcde"), 0, 1, SV("12345678901234567890"), 0, 21, S("12345678901234567890bcde")); + test(S("abcde"), 0, 1, SV("12345678901234567890"), 1, 0, S("bcde")); + test(S("abcde"), 0, 1, SV("12345678901234567890"), 1, 1, S("2bcde")); + test(S("abcde"), 0, 1, SV("12345678901234567890"), 1, 9, S("234567890bcde")); + test(S("abcde"), 0, 1, SV("12345678901234567890"), 1, 18, S("234567890123456789bcde")); + test(S("abcde"), 0, 1, SV("12345678901234567890"), 1, 19, S("2345678901234567890bcde")); + test(S("abcde"), 0, 1, SV("12345678901234567890"), 1, 20, S("2345678901234567890bcde")); + test(S("abcde"), 0, 1, SV("12345678901234567890"), 10, 0, S("bcde")); + test(S("abcde"), 0, 1, SV("12345678901234567890"), 10, 1, S("1bcde")); + test(S("abcde"), 0, 1, SV("12345678901234567890"), 10, 5, S("12345bcde")); + test(S("abcde"), 0, 1, SV("12345678901234567890"), 10, 9, S("123456789bcde")); + test(S("abcde"), 0, 1, SV("12345678901234567890"), 10, 10, S("1234567890bcde")); + test(S("abcde"), 0, 1, SV("12345678901234567890"), 10, 11, S("1234567890bcde")); + test(S("abcde"), 0, 1, SV("12345678901234567890"), 19, 0, S("bcde")); + test(S("abcde"), 0, 1, SV("12345678901234567890"), 19, 1, S("0bcde")); + test(S("abcde"), 0, 1, SV("12345678901234567890"), 19, 2, S("0bcde")); + test(S("abcde"), 0, 1, SV("12345678901234567890"), 20, 0, S("bcde")); + test(S("abcde"), 0, 1, SV("12345678901234567890"), 20, 1, S("bcde")); + test(S("abcde"), 0, 1, SV("12345678901234567890"), 21, 0, S("can't happen")); + test(S("abcde"), 0, 2, SV(""), 0, 0, S("cde")); + test(S("abcde"), 0, 2, SV(""), 0, 1, S("cde")); + test(S("abcde"), 0, 2, SV(""), 1, 0, S("can't happen")); + test(S("abcde"), 0, 2, SV("12345"), 0, 0, S("cde")); + test(S("abcde"), 0, 2, SV("12345"), 0, 1, S("1cde")); + test(S("abcde"), 0, 2, SV("12345"), 0, 2, S("12cde")); + test(S("abcde"), 0, 2, SV("12345"), 0, 4, S("1234cde")); + test(S("abcde"), 0, 2, SV("12345"), 0, 5, S("12345cde")); + test(S("abcde"), 0, 2, SV("12345"), 0, 6, S("12345cde")); + test(S("abcde"), 0, 2, SV("12345"), 1, 0, S("cde")); + test(S("abcde"), 0, 2, SV("12345"), 1, 1, S("2cde")); + test(S("abcde"), 0, 2, SV("12345"), 1, 2, S("23cde")); + test(S("abcde"), 0, 2, SV("12345"), 1, 3, S("234cde")); + test(S("abcde"), 0, 2, SV("12345"), 1, 4, S("2345cde")); + test(S("abcde"), 0, 2, SV("12345"), 1, 5, S("2345cde")); + test(S("abcde"), 0, 2, SV("12345"), 2, 0, S("cde")); + test(S("abcde"), 0, 2, SV("12345"), 2, 1, S("3cde")); + test(S("abcde"), 0, 2, SV("12345"), 2, 2, S("34cde")); + test(S("abcde"), 0, 2, SV("12345"), 2, 3, S("345cde")); + test(S("abcde"), 0, 2, SV("12345"), 2, 4, S("345cde")); + test(S("abcde"), 0, 2, SV("12345"), 4, 0, S("cde")); + test(S("abcde"), 0, 2, SV("12345"), 4, 1, S("5cde")); + test(S("abcde"), 0, 2, SV("12345"), 4, 2, S("5cde")); + test(S("abcde"), 0, 2, SV("12345"), 5, 0, S("cde")); + test(S("abcde"), 0, 2, SV("12345"), 5, 1, S("cde")); + test(S("abcde"), 0, 2, SV("12345"), 6, 0, S("can't happen")); + test(S("abcde"), 0, 2, SV("1234567890"), 0, 0, S("cde")); + test(S("abcde"), 0, 2, SV("1234567890"), 0, 1, S("1cde")); + test(S("abcde"), 0, 2, SV("1234567890"), 0, 5, S("12345cde")); + test(S("abcde"), 0, 2, SV("1234567890"), 0, 9, S("123456789cde")); +} + +template +void test4() +{ + test(S("abcde"), 0, 2, SV("1234567890"), 0, 10, S("1234567890cde")); + test(S("abcde"), 0, 2, SV("1234567890"), 0, 11, S("1234567890cde")); + test(S("abcde"), 0, 2, SV("1234567890"), 1, 0, S("cde")); + test(S("abcde"), 0, 2, SV("1234567890"), 1, 1, S("2cde")); + test(S("abcde"), 0, 2, SV("1234567890"), 1, 4, S("2345cde")); + test(S("abcde"), 0, 2, SV("1234567890"), 1, 8, S("23456789cde")); + test(S("abcde"), 0, 2, SV("1234567890"), 1, 9, S("234567890cde")); + test(S("abcde"), 0, 2, SV("1234567890"), 1, 10, S("234567890cde")); + test(S("abcde"), 0, 2, SV("1234567890"), 5, 0, S("cde")); + test(S("abcde"), 0, 2, SV("1234567890"), 5, 1, S("6cde")); + test(S("abcde"), 0, 2, SV("1234567890"), 5, 2, S("67cde")); + test(S("abcde"), 0, 2, SV("1234567890"), 5, 4, S("6789cde")); + test(S("abcde"), 0, 2, SV("1234567890"), 5, 5, S("67890cde")); + test(S("abcde"), 0, 2, SV("1234567890"), 5, 6, S("67890cde")); + test(S("abcde"), 0, 2, SV("1234567890"), 9, 0, S("cde")); + test(S("abcde"), 0, 2, SV("1234567890"), 9, 1, S("0cde")); + test(S("abcde"), 0, 2, SV("1234567890"), 9, 2, S("0cde")); + test(S("abcde"), 0, 2, SV("1234567890"), 10, 0, S("cde")); + test(S("abcde"), 0, 2, SV("1234567890"), 10, 1, S("cde")); + test(S("abcde"), 0, 2, SV("1234567890"), 11, 0, S("can't happen")); + test(S("abcde"), 0, 2, SV("12345678901234567890"), 0, 0, S("cde")); + test(S("abcde"), 0, 2, SV("12345678901234567890"), 0, 1, S("1cde")); + test(S("abcde"), 0, 2, SV("12345678901234567890"), 0, 10, S("1234567890cde")); + test(S("abcde"), 0, 2, SV("12345678901234567890"), 0, 19, S("1234567890123456789cde")); + test(S("abcde"), 0, 2, SV("12345678901234567890"), 0, 20, S("12345678901234567890cde")); + test(S("abcde"), 0, 2, SV("12345678901234567890"), 0, 21, S("12345678901234567890cde")); + test(S("abcde"), 0, 2, SV("12345678901234567890"), 1, 0, S("cde")); + test(S("abcde"), 0, 2, SV("12345678901234567890"), 1, 1, S("2cde")); + test(S("abcde"), 0, 2, SV("12345678901234567890"), 1, 9, S("234567890cde")); + test(S("abcde"), 0, 2, SV("12345678901234567890"), 1, 18, S("234567890123456789cde")); + test(S("abcde"), 0, 2, SV("12345678901234567890"), 1, 19, S("2345678901234567890cde")); + test(S("abcde"), 0, 2, SV("12345678901234567890"), 1, 20, S("2345678901234567890cde")); + test(S("abcde"), 0, 2, SV("12345678901234567890"), 10, 0, S("cde")); + test(S("abcde"), 0, 2, SV("12345678901234567890"), 10, 1, S("1cde")); + test(S("abcde"), 0, 2, SV("12345678901234567890"), 10, 5, S("12345cde")); + test(S("abcde"), 0, 2, SV("12345678901234567890"), 10, 9, S("123456789cde")); + test(S("abcde"), 0, 2, SV("12345678901234567890"), 10, 10, S("1234567890cde")); + test(S("abcde"), 0, 2, SV("12345678901234567890"), 10, 11, S("1234567890cde")); + test(S("abcde"), 0, 2, SV("12345678901234567890"), 19, 0, S("cde")); + test(S("abcde"), 0, 2, SV("12345678901234567890"), 19, 1, S("0cde")); + test(S("abcde"), 0, 2, SV("12345678901234567890"), 19, 2, S("0cde")); + test(S("abcde"), 0, 2, SV("12345678901234567890"), 20, 0, S("cde")); + test(S("abcde"), 0, 2, SV("12345678901234567890"), 20, 1, S("cde")); + test(S("abcde"), 0, 2, SV("12345678901234567890"), 21, 0, S("can't happen")); + test(S("abcde"), 0, 4, SV(""), 0, 0, S("e")); + test(S("abcde"), 0, 4, SV(""), 0, 1, S("e")); + test(S("abcde"), 0, 4, SV(""), 1, 0, S("can't happen")); + test(S("abcde"), 0, 4, SV("12345"), 0, 0, S("e")); + test(S("abcde"), 0, 4, SV("12345"), 0, 1, S("1e")); + test(S("abcde"), 0, 4, SV("12345"), 0, 2, S("12e")); + test(S("abcde"), 0, 4, SV("12345"), 0, 4, S("1234e")); + test(S("abcde"), 0, 4, SV("12345"), 0, 5, S("12345e")); + test(S("abcde"), 0, 4, SV("12345"), 0, 6, S("12345e")); + test(S("abcde"), 0, 4, SV("12345"), 1, 0, S("e")); + test(S("abcde"), 0, 4, SV("12345"), 1, 1, S("2e")); + test(S("abcde"), 0, 4, SV("12345"), 1, 2, S("23e")); + test(S("abcde"), 0, 4, SV("12345"), 1, 3, S("234e")); + test(S("abcde"), 0, 4, SV("12345"), 1, 4, S("2345e")); + test(S("abcde"), 0, 4, SV("12345"), 1, 5, S("2345e")); + test(S("abcde"), 0, 4, SV("12345"), 2, 0, S("e")); + test(S("abcde"), 0, 4, SV("12345"), 2, 1, S("3e")); + test(S("abcde"), 0, 4, SV("12345"), 2, 2, S("34e")); + test(S("abcde"), 0, 4, SV("12345"), 2, 3, S("345e")); + test(S("abcde"), 0, 4, SV("12345"), 2, 4, S("345e")); + test(S("abcde"), 0, 4, SV("12345"), 4, 0, S("e")); + test(S("abcde"), 0, 4, SV("12345"), 4, 1, S("5e")); + test(S("abcde"), 0, 4, SV("12345"), 4, 2, S("5e")); + test(S("abcde"), 0, 4, SV("12345"), 5, 0, S("e")); + test(S("abcde"), 0, 4, SV("12345"), 5, 1, S("e")); + test(S("abcde"), 0, 4, SV("12345"), 6, 0, S("can't happen")); + test(S("abcde"), 0, 4, SV("1234567890"), 0, 0, S("e")); + test(S("abcde"), 0, 4, SV("1234567890"), 0, 1, S("1e")); + test(S("abcde"), 0, 4, SV("1234567890"), 0, 5, S("12345e")); + test(S("abcde"), 0, 4, SV("1234567890"), 0, 9, S("123456789e")); + test(S("abcde"), 0, 4, SV("1234567890"), 0, 10, S("1234567890e")); + test(S("abcde"), 0, 4, SV("1234567890"), 0, 11, S("1234567890e")); + test(S("abcde"), 0, 4, SV("1234567890"), 1, 0, S("e")); + test(S("abcde"), 0, 4, SV("1234567890"), 1, 1, S("2e")); + test(S("abcde"), 0, 4, SV("1234567890"), 1, 4, S("2345e")); + test(S("abcde"), 0, 4, SV("1234567890"), 1, 8, S("23456789e")); + test(S("abcde"), 0, 4, SV("1234567890"), 1, 9, S("234567890e")); + test(S("abcde"), 0, 4, SV("1234567890"), 1, 10, S("234567890e")); + test(S("abcde"), 0, 4, SV("1234567890"), 5, 0, S("e")); + test(S("abcde"), 0, 4, SV("1234567890"), 5, 1, S("6e")); + test(S("abcde"), 0, 4, SV("1234567890"), 5, 2, S("67e")); + test(S("abcde"), 0, 4, SV("1234567890"), 5, 4, S("6789e")); + test(S("abcde"), 0, 4, SV("1234567890"), 5, 5, S("67890e")); + test(S("abcde"), 0, 4, SV("1234567890"), 5, 6, S("67890e")); + test(S("abcde"), 0, 4, SV("1234567890"), 9, 0, S("e")); + test(S("abcde"), 0, 4, SV("1234567890"), 9, 1, S("0e")); + test(S("abcde"), 0, 4, SV("1234567890"), 9, 2, S("0e")); + test(S("abcde"), 0, 4, SV("1234567890"), 10, 0, S("e")); + test(S("abcde"), 0, 4, SV("1234567890"), 10, 1, S("e")); + test(S("abcde"), 0, 4, SV("1234567890"), 11, 0, S("can't happen")); + test(S("abcde"), 0, 4, SV("12345678901234567890"), 0, 0, S("e")); + test(S("abcde"), 0, 4, SV("12345678901234567890"), 0, 1, S("1e")); + test(S("abcde"), 0, 4, SV("12345678901234567890"), 0, 10, S("1234567890e")); + test(S("abcde"), 0, 4, SV("12345678901234567890"), 0, 19, S("1234567890123456789e")); + test(S("abcde"), 0, 4, SV("12345678901234567890"), 0, 20, S("12345678901234567890e")); + test(S("abcde"), 0, 4, SV("12345678901234567890"), 0, 21, S("12345678901234567890e")); +} + +template +void test5() +{ + test(S("abcde"), 0, 4, SV("12345678901234567890"), 1, 0, S("e")); + test(S("abcde"), 0, 4, SV("12345678901234567890"), 1, 1, S("2e")); + test(S("abcde"), 0, 4, SV("12345678901234567890"), 1, 9, S("234567890e")); + test(S("abcde"), 0, 4, SV("12345678901234567890"), 1, 18, S("234567890123456789e")); + test(S("abcde"), 0, 4, SV("12345678901234567890"), 1, 19, S("2345678901234567890e")); + test(S("abcde"), 0, 4, SV("12345678901234567890"), 1, 20, S("2345678901234567890e")); + test(S("abcde"), 0, 4, SV("12345678901234567890"), 10, 0, S("e")); + test(S("abcde"), 0, 4, SV("12345678901234567890"), 10, 1, S("1e")); + test(S("abcde"), 0, 4, SV("12345678901234567890"), 10, 5, S("12345e")); + test(S("abcde"), 0, 4, SV("12345678901234567890"), 10, 9, S("123456789e")); + test(S("abcde"), 0, 4, SV("12345678901234567890"), 10, 10, S("1234567890e")); + test(S("abcde"), 0, 4, SV("12345678901234567890"), 10, 11, S("1234567890e")); + test(S("abcde"), 0, 4, SV("12345678901234567890"), 19, 0, S("e")); + test(S("abcde"), 0, 4, SV("12345678901234567890"), 19, 1, S("0e")); + test(S("abcde"), 0, 4, SV("12345678901234567890"), 19, 2, S("0e")); + test(S("abcde"), 0, 4, SV("12345678901234567890"), 20, 0, S("e")); + test(S("abcde"), 0, 4, SV("12345678901234567890"), 20, 1, S("e")); + test(S("abcde"), 0, 4, SV("12345678901234567890"), 21, 0, S("can't happen")); + test(S("abcde"), 0, 5, SV(""), 0, 0, S("")); + test(S("abcde"), 0, 5, SV(""), 0, 1, S("")); + test(S("abcde"), 0, 5, SV(""), 1, 0, S("can't happen")); + test(S("abcde"), 0, 5, SV("12345"), 0, 0, S("")); + test(S("abcde"), 0, 5, SV("12345"), 0, 1, S("1")); + test(S("abcde"), 0, 5, SV("12345"), 0, 2, S("12")); + test(S("abcde"), 0, 5, SV("12345"), 0, 4, S("1234")); + test(S("abcde"), 0, 5, SV("12345"), 0, 5, S("12345")); + test(S("abcde"), 0, 5, SV("12345"), 0, 6, S("12345")); + test(S("abcde"), 0, 5, SV("12345"), 1, 0, S("")); + test(S("abcde"), 0, 5, SV("12345"), 1, 1, S("2")); + test(S("abcde"), 0, 5, SV("12345"), 1, 2, S("23")); + test(S("abcde"), 0, 5, SV("12345"), 1, 3, S("234")); + test(S("abcde"), 0, 5, SV("12345"), 1, 4, S("2345")); + test(S("abcde"), 0, 5, SV("12345"), 1, 5, S("2345")); + test(S("abcde"), 0, 5, SV("12345"), 2, 0, S("")); + test(S("abcde"), 0, 5, SV("12345"), 2, 1, S("3")); + test(S("abcde"), 0, 5, SV("12345"), 2, 2, S("34")); + test(S("abcde"), 0, 5, SV("12345"), 2, 3, S("345")); + test(S("abcde"), 0, 5, SV("12345"), 2, 4, S("345")); + test(S("abcde"), 0, 5, SV("12345"), 4, 0, S("")); + test(S("abcde"), 0, 5, SV("12345"), 4, 1, S("5")); + test(S("abcde"), 0, 5, SV("12345"), 4, 2, S("5")); + test(S("abcde"), 0, 5, SV("12345"), 5, 0, S("")); + test(S("abcde"), 0, 5, SV("12345"), 5, 1, S("")); + test(S("abcde"), 0, 5, SV("12345"), 6, 0, S("can't happen")); + test(S("abcde"), 0, 5, SV("1234567890"), 0, 0, S("")); + test(S("abcde"), 0, 5, SV("1234567890"), 0, 1, S("1")); + test(S("abcde"), 0, 5, SV("1234567890"), 0, 5, S("12345")); + test(S("abcde"), 0, 5, SV("1234567890"), 0, 9, S("123456789")); + test(S("abcde"), 0, 5, SV("1234567890"), 0, 10, S("1234567890")); + test(S("abcde"), 0, 5, SV("1234567890"), 0, 11, S("1234567890")); + test(S("abcde"), 0, 5, SV("1234567890"), 1, 0, S("")); + test(S("abcde"), 0, 5, SV("1234567890"), 1, 1, S("2")); + test(S("abcde"), 0, 5, SV("1234567890"), 1, 4, S("2345")); + test(S("abcde"), 0, 5, SV("1234567890"), 1, 8, S("23456789")); + test(S("abcde"), 0, 5, SV("1234567890"), 1, 9, S("234567890")); + test(S("abcde"), 0, 5, SV("1234567890"), 1, 10, S("234567890")); + test(S("abcde"), 0, 5, SV("1234567890"), 5, 0, S("")); + test(S("abcde"), 0, 5, SV("1234567890"), 5, 1, S("6")); + test(S("abcde"), 0, 5, SV("1234567890"), 5, 2, S("67")); + test(S("abcde"), 0, 5, SV("1234567890"), 5, 4, S("6789")); + test(S("abcde"), 0, 5, SV("1234567890"), 5, 5, S("67890")); + test(S("abcde"), 0, 5, SV("1234567890"), 5, 6, S("67890")); + test(S("abcde"), 0, 5, SV("1234567890"), 9, 0, S("")); + test(S("abcde"), 0, 5, SV("1234567890"), 9, 1, S("0")); + test(S("abcde"), 0, 5, SV("1234567890"), 9, 2, S("0")); + test(S("abcde"), 0, 5, SV("1234567890"), 10, 0, S("")); + test(S("abcde"), 0, 5, SV("1234567890"), 10, 1, S("")); + test(S("abcde"), 0, 5, SV("1234567890"), 11, 0, S("can't happen")); + test(S("abcde"), 0, 5, SV("12345678901234567890"), 0, 0, S("")); + test(S("abcde"), 0, 5, SV("12345678901234567890"), 0, 1, S("1")); + test(S("abcde"), 0, 5, SV("12345678901234567890"), 0, 10, S("1234567890")); + test(S("abcde"), 0, 5, SV("12345678901234567890"), 0, 19, S("1234567890123456789")); + test(S("abcde"), 0, 5, SV("12345678901234567890"), 0, 20, S("12345678901234567890")); + test(S("abcde"), 0, 5, SV("12345678901234567890"), 0, 21, S("12345678901234567890")); + test(S("abcde"), 0, 5, SV("12345678901234567890"), 1, 0, S("")); + test(S("abcde"), 0, 5, SV("12345678901234567890"), 1, 1, S("2")); + test(S("abcde"), 0, 5, SV("12345678901234567890"), 1, 9, S("234567890")); + test(S("abcde"), 0, 5, SV("12345678901234567890"), 1, 18, S("234567890123456789")); + test(S("abcde"), 0, 5, SV("12345678901234567890"), 1, 19, S("2345678901234567890")); + test(S("abcde"), 0, 5, SV("12345678901234567890"), 1, 20, S("2345678901234567890")); + test(S("abcde"), 0, 5, SV("12345678901234567890"), 10, 0, S("")); + test(S("abcde"), 0, 5, SV("12345678901234567890"), 10, 1, S("1")); + test(S("abcde"), 0, 5, SV("12345678901234567890"), 10, 5, S("12345")); + test(S("abcde"), 0, 5, SV("12345678901234567890"), 10, 9, S("123456789")); + test(S("abcde"), 0, 5, SV("12345678901234567890"), 10, 10, S("1234567890")); + test(S("abcde"), 0, 5, SV("12345678901234567890"), 10, 11, S("1234567890")); + test(S("abcde"), 0, 5, SV("12345678901234567890"), 19, 0, S("")); + test(S("abcde"), 0, 5, SV("12345678901234567890"), 19, 1, S("0")); + test(S("abcde"), 0, 5, SV("12345678901234567890"), 19, 2, S("0")); + test(S("abcde"), 0, 5, SV("12345678901234567890"), 20, 0, S("")); + test(S("abcde"), 0, 5, SV("12345678901234567890"), 20, 1, S("")); + test(S("abcde"), 0, 5, SV("12345678901234567890"), 21, 0, S("can't happen")); + test(S("abcde"), 0, 6, SV(""), 0, 0, S("")); + test(S("abcde"), 0, 6, SV(""), 0, 1, S("")); + test(S("abcde"), 0, 6, SV(""), 1, 0, S("can't happen")); + test(S("abcde"), 0, 6, SV("12345"), 0, 0, S("")); + test(S("abcde"), 0, 6, SV("12345"), 0, 1, S("1")); + test(S("abcde"), 0, 6, SV("12345"), 0, 2, S("12")); + test(S("abcde"), 0, 6, SV("12345"), 0, 4, S("1234")); + test(S("abcde"), 0, 6, SV("12345"), 0, 5, S("12345")); +} + +template +void test6() +{ + test(S("abcde"), 0, 6, SV("12345"), 0, 6, S("12345")); + test(S("abcde"), 0, 6, SV("12345"), 1, 0, S("")); + test(S("abcde"), 0, 6, SV("12345"), 1, 1, S("2")); + test(S("abcde"), 0, 6, SV("12345"), 1, 2, S("23")); + test(S("abcde"), 0, 6, SV("12345"), 1, 3, S("234")); + test(S("abcde"), 0, 6, SV("12345"), 1, 4, S("2345")); + test(S("abcde"), 0, 6, SV("12345"), 1, 5, S("2345")); + test(S("abcde"), 0, 6, SV("12345"), 2, 0, S("")); + test(S("abcde"), 0, 6, SV("12345"), 2, 1, S("3")); + test(S("abcde"), 0, 6, SV("12345"), 2, 2, S("34")); + test(S("abcde"), 0, 6, SV("12345"), 2, 3, S("345")); + test(S("abcde"), 0, 6, SV("12345"), 2, 4, S("345")); + test(S("abcde"), 0, 6, SV("12345"), 4, 0, S("")); + test(S("abcde"), 0, 6, SV("12345"), 4, 1, S("5")); + test(S("abcde"), 0, 6, SV("12345"), 4, 2, S("5")); + test(S("abcde"), 0, 6, SV("12345"), 5, 0, S("")); + test(S("abcde"), 0, 6, SV("12345"), 5, 1, S("")); + test(S("abcde"), 0, 6, SV("12345"), 6, 0, S("can't happen")); + test(S("abcde"), 0, 6, SV("1234567890"), 0, 0, S("")); + test(S("abcde"), 0, 6, SV("1234567890"), 0, 1, S("1")); + test(S("abcde"), 0, 6, SV("1234567890"), 0, 5, S("12345")); + test(S("abcde"), 0, 6, SV("1234567890"), 0, 9, S("123456789")); + test(S("abcde"), 0, 6, SV("1234567890"), 0, 10, S("1234567890")); + test(S("abcde"), 0, 6, SV("1234567890"), 0, 11, S("1234567890")); + test(S("abcde"), 0, 6, SV("1234567890"), 1, 0, S("")); + test(S("abcde"), 0, 6, SV("1234567890"), 1, 1, S("2")); + test(S("abcde"), 0, 6, SV("1234567890"), 1, 4, S("2345")); + test(S("abcde"), 0, 6, SV("1234567890"), 1, 8, S("23456789")); + test(S("abcde"), 0, 6, SV("1234567890"), 1, 9, S("234567890")); + test(S("abcde"), 0, 6, SV("1234567890"), 1, 10, S("234567890")); + test(S("abcde"), 0, 6, SV("1234567890"), 5, 0, S("")); + test(S("abcde"), 0, 6, SV("1234567890"), 5, 1, S("6")); + test(S("abcde"), 0, 6, SV("1234567890"), 5, 2, S("67")); + test(S("abcde"), 0, 6, SV("1234567890"), 5, 4, S("6789")); + test(S("abcde"), 0, 6, SV("1234567890"), 5, 5, S("67890")); + test(S("abcde"), 0, 6, SV("1234567890"), 5, 6, S("67890")); + test(S("abcde"), 0, 6, SV("1234567890"), 9, 0, S("")); + test(S("abcde"), 0, 6, SV("1234567890"), 9, 1, S("0")); + test(S("abcde"), 0, 6, SV("1234567890"), 9, 2, S("0")); + test(S("abcde"), 0, 6, SV("1234567890"), 10, 0, S("")); + test(S("abcde"), 0, 6, SV("1234567890"), 10, 1, S("")); + test(S("abcde"), 0, 6, SV("1234567890"), 11, 0, S("can't happen")); + test(S("abcde"), 0, 6, SV("12345678901234567890"), 0, 0, S("")); + test(S("abcde"), 0, 6, SV("12345678901234567890"), 0, 1, S("1")); + test(S("abcde"), 0, 6, SV("12345678901234567890"), 0, 10, S("1234567890")); + test(S("abcde"), 0, 6, SV("12345678901234567890"), 0, 19, S("1234567890123456789")); + test(S("abcde"), 0, 6, SV("12345678901234567890"), 0, 20, S("12345678901234567890")); + test(S("abcde"), 0, 6, SV("12345678901234567890"), 0, 21, S("12345678901234567890")); + test(S("abcde"), 0, 6, SV("12345678901234567890"), 1, 0, S("")); + test(S("abcde"), 0, 6, SV("12345678901234567890"), 1, 1, S("2")); + test(S("abcde"), 0, 6, SV("12345678901234567890"), 1, 9, S("234567890")); + test(S("abcde"), 0, 6, SV("12345678901234567890"), 1, 18, S("234567890123456789")); + test(S("abcde"), 0, 6, SV("12345678901234567890"), 1, 19, S("2345678901234567890")); + test(S("abcde"), 0, 6, SV("12345678901234567890"), 1, 20, S("2345678901234567890")); + test(S("abcde"), 0, 6, SV("12345678901234567890"), 10, 0, S("")); + test(S("abcde"), 0, 6, SV("12345678901234567890"), 10, 1, S("1")); + test(S("abcde"), 0, 6, SV("12345678901234567890"), 10, 5, S("12345")); + test(S("abcde"), 0, 6, SV("12345678901234567890"), 10, 9, S("123456789")); + test(S("abcde"), 0, 6, SV("12345678901234567890"), 10, 10, S("1234567890")); + test(S("abcde"), 0, 6, SV("12345678901234567890"), 10, 11, S("1234567890")); + test(S("abcde"), 0, 6, SV("12345678901234567890"), 19, 0, S("")); + test(S("abcde"), 0, 6, SV("12345678901234567890"), 19, 1, S("0")); + test(S("abcde"), 0, 6, SV("12345678901234567890"), 19, 2, S("0")); + test(S("abcde"), 0, 6, SV("12345678901234567890"), 20, 0, S("")); + test(S("abcde"), 0, 6, SV("12345678901234567890"), 20, 1, S("")); + test(S("abcde"), 0, 6, SV("12345678901234567890"), 21, 0, S("can't happen")); + test(S("abcde"), 1, 0, SV(""), 0, 0, S("abcde")); + test(S("abcde"), 1, 0, SV(""), 0, 1, S("abcde")); + test(S("abcde"), 1, 0, SV(""), 1, 0, S("can't happen")); + test(S("abcde"), 1, 0, SV("12345"), 0, 0, S("abcde")); + test(S("abcde"), 1, 0, SV("12345"), 0, 1, S("a1bcde")); + test(S("abcde"), 1, 0, SV("12345"), 0, 2, S("a12bcde")); + test(S("abcde"), 1, 0, SV("12345"), 0, 4, S("a1234bcde")); + test(S("abcde"), 1, 0, SV("12345"), 0, 5, S("a12345bcde")); + test(S("abcde"), 1, 0, SV("12345"), 0, 6, S("a12345bcde")); + test(S("abcde"), 1, 0, SV("12345"), 1, 0, S("abcde")); + test(S("abcde"), 1, 0, SV("12345"), 1, 1, S("a2bcde")); + test(S("abcde"), 1, 0, SV("12345"), 1, 2, S("a23bcde")); + test(S("abcde"), 1, 0, SV("12345"), 1, 3, S("a234bcde")); + test(S("abcde"), 1, 0, SV("12345"), 1, 4, S("a2345bcde")); + test(S("abcde"), 1, 0, SV("12345"), 1, 5, S("a2345bcde")); + test(S("abcde"), 1, 0, SV("12345"), 2, 0, S("abcde")); + test(S("abcde"), 1, 0, SV("12345"), 2, 1, S("a3bcde")); + test(S("abcde"), 1, 0, SV("12345"), 2, 2, S("a34bcde")); + test(S("abcde"), 1, 0, SV("12345"), 2, 3, S("a345bcde")); + test(S("abcde"), 1, 0, SV("12345"), 2, 4, S("a345bcde")); + test(S("abcde"), 1, 0, SV("12345"), 4, 0, S("abcde")); + test(S("abcde"), 1, 0, SV("12345"), 4, 1, S("a5bcde")); + test(S("abcde"), 1, 0, SV("12345"), 4, 2, S("a5bcde")); + test(S("abcde"), 1, 0, SV("12345"), 5, 0, S("abcde")); + test(S("abcde"), 1, 0, SV("12345"), 5, 1, S("abcde")); + test(S("abcde"), 1, 0, SV("12345"), 6, 0, S("can't happen")); + test(S("abcde"), 1, 0, SV("1234567890"), 0, 0, S("abcde")); + test(S("abcde"), 1, 0, SV("1234567890"), 0, 1, S("a1bcde")); + test(S("abcde"), 1, 0, SV("1234567890"), 0, 5, S("a12345bcde")); + test(S("abcde"), 1, 0, SV("1234567890"), 0, 9, S("a123456789bcde")); + test(S("abcde"), 1, 0, SV("1234567890"), 0, 10, S("a1234567890bcde")); + test(S("abcde"), 1, 0, SV("1234567890"), 0, 11, S("a1234567890bcde")); + test(S("abcde"), 1, 0, SV("1234567890"), 1, 0, S("abcde")); + test(S("abcde"), 1, 0, SV("1234567890"), 1, 1, S("a2bcde")); +} + +template +void test7() +{ + test(S("abcde"), 1, 0, SV("1234567890"), 1, 4, S("a2345bcde")); + test(S("abcde"), 1, 0, SV("1234567890"), 1, 8, S("a23456789bcde")); + test(S("abcde"), 1, 0, SV("1234567890"), 1, 9, S("a234567890bcde")); + test(S("abcde"), 1, 0, SV("1234567890"), 1, 10, S("a234567890bcde")); + test(S("abcde"), 1, 0, SV("1234567890"), 5, 0, S("abcde")); + test(S("abcde"), 1, 0, SV("1234567890"), 5, 1, S("a6bcde")); + test(S("abcde"), 1, 0, SV("1234567890"), 5, 2, S("a67bcde")); + test(S("abcde"), 1, 0, SV("1234567890"), 5, 4, S("a6789bcde")); + test(S("abcde"), 1, 0, SV("1234567890"), 5, 5, S("a67890bcde")); + test(S("abcde"), 1, 0, SV("1234567890"), 5, 6, S("a67890bcde")); + test(S("abcde"), 1, 0, SV("1234567890"), 9, 0, S("abcde")); + test(S("abcde"), 1, 0, SV("1234567890"), 9, 1, S("a0bcde")); + test(S("abcde"), 1, 0, SV("1234567890"), 9, 2, S("a0bcde")); + test(S("abcde"), 1, 0, SV("1234567890"), 10, 0, S("abcde")); + test(S("abcde"), 1, 0, SV("1234567890"), 10, 1, S("abcde")); + test(S("abcde"), 1, 0, SV("1234567890"), 11, 0, S("can't happen")); + test(S("abcde"), 1, 0, SV("12345678901234567890"), 0, 0, S("abcde")); + test(S("abcde"), 1, 0, SV("12345678901234567890"), 0, 1, S("a1bcde")); + test(S("abcde"), 1, 0, SV("12345678901234567890"), 0, 10, S("a1234567890bcde")); + test(S("abcde"), 1, 0, SV("12345678901234567890"), 0, 19, S("a1234567890123456789bcde")); + test(S("abcde"), 1, 0, SV("12345678901234567890"), 0, 20, S("a12345678901234567890bcde")); + test(S("abcde"), 1, 0, SV("12345678901234567890"), 0, 21, S("a12345678901234567890bcde")); + test(S("abcde"), 1, 0, SV("12345678901234567890"), 1, 0, S("abcde")); + test(S("abcde"), 1, 0, SV("12345678901234567890"), 1, 1, S("a2bcde")); + test(S("abcde"), 1, 0, SV("12345678901234567890"), 1, 9, S("a234567890bcde")); + test(S("abcde"), 1, 0, SV("12345678901234567890"), 1, 18, S("a234567890123456789bcde")); + test(S("abcde"), 1, 0, SV("12345678901234567890"), 1, 19, S("a2345678901234567890bcde")); + test(S("abcde"), 1, 0, SV("12345678901234567890"), 1, 20, S("a2345678901234567890bcde")); + test(S("abcde"), 1, 0, SV("12345678901234567890"), 10, 0, S("abcde")); + test(S("abcde"), 1, 0, SV("12345678901234567890"), 10, 1, S("a1bcde")); + test(S("abcde"), 1, 0, SV("12345678901234567890"), 10, 5, S("a12345bcde")); + test(S("abcde"), 1, 0, SV("12345678901234567890"), 10, 9, S("a123456789bcde")); + test(S("abcde"), 1, 0, SV("12345678901234567890"), 10, 10, S("a1234567890bcde")); + test(S("abcde"), 1, 0, SV("12345678901234567890"), 10, 11, S("a1234567890bcde")); + test(S("abcde"), 1, 0, SV("12345678901234567890"), 19, 0, S("abcde")); + test(S("abcde"), 1, 0, SV("12345678901234567890"), 19, 1, S("a0bcde")); + test(S("abcde"), 1, 0, SV("12345678901234567890"), 19, 2, S("a0bcde")); + test(S("abcde"), 1, 0, SV("12345678901234567890"), 20, 0, S("abcde")); + test(S("abcde"), 1, 0, SV("12345678901234567890"), 20, 1, S("abcde")); + test(S("abcde"), 1, 0, SV("12345678901234567890"), 21, 0, S("can't happen")); + test(S("abcde"), 1, 1, SV(""), 0, 0, S("acde")); + test(S("abcde"), 1, 1, SV(""), 0, 1, S("acde")); + test(S("abcde"), 1, 1, SV(""), 1, 0, S("can't happen")); + test(S("abcde"), 1, 1, SV("12345"), 0, 0, S("acde")); + test(S("abcde"), 1, 1, SV("12345"), 0, 1, S("a1cde")); + test(S("abcde"), 1, 1, SV("12345"), 0, 2, S("a12cde")); + test(S("abcde"), 1, 1, SV("12345"), 0, 4, S("a1234cde")); + test(S("abcde"), 1, 1, SV("12345"), 0, 5, S("a12345cde")); + test(S("abcde"), 1, 1, SV("12345"), 0, 6, S("a12345cde")); + test(S("abcde"), 1, 1, SV("12345"), 1, 0, S("acde")); + test(S("abcde"), 1, 1, SV("12345"), 1, 1, S("a2cde")); + test(S("abcde"), 1, 1, SV("12345"), 1, 2, S("a23cde")); + test(S("abcde"), 1, 1, SV("12345"), 1, 3, S("a234cde")); + test(S("abcde"), 1, 1, SV("12345"), 1, 4, S("a2345cde")); + test(S("abcde"), 1, 1, SV("12345"), 1, 5, S("a2345cde")); + test(S("abcde"), 1, 1, SV("12345"), 2, 0, S("acde")); + test(S("abcde"), 1, 1, SV("12345"), 2, 1, S("a3cde")); + test(S("abcde"), 1, 1, SV("12345"), 2, 2, S("a34cde")); + test(S("abcde"), 1, 1, SV("12345"), 2, 3, S("a345cde")); + test(S("abcde"), 1, 1, SV("12345"), 2, 4, S("a345cde")); + test(S("abcde"), 1, 1, SV("12345"), 4, 0, S("acde")); + test(S("abcde"), 1, 1, SV("12345"), 4, 1, S("a5cde")); + test(S("abcde"), 1, 1, SV("12345"), 4, 2, S("a5cde")); + test(S("abcde"), 1, 1, SV("12345"), 5, 0, S("acde")); + test(S("abcde"), 1, 1, SV("12345"), 5, 1, S("acde")); + test(S("abcde"), 1, 1, SV("12345"), 6, 0, S("can't happen")); + test(S("abcde"), 1, 1, SV("1234567890"), 0, 0, S("acde")); + test(S("abcde"), 1, 1, SV("1234567890"), 0, 1, S("a1cde")); + test(S("abcde"), 1, 1, SV("1234567890"), 0, 5, S("a12345cde")); + test(S("abcde"), 1, 1, SV("1234567890"), 0, 9, S("a123456789cde")); + test(S("abcde"), 1, 1, SV("1234567890"), 0, 10, S("a1234567890cde")); + test(S("abcde"), 1, 1, SV("1234567890"), 0, 11, S("a1234567890cde")); + test(S("abcde"), 1, 1, SV("1234567890"), 1, 0, S("acde")); + test(S("abcde"), 1, 1, SV("1234567890"), 1, 1, S("a2cde")); + test(S("abcde"), 1, 1, SV("1234567890"), 1, 4, S("a2345cde")); + test(S("abcde"), 1, 1, SV("1234567890"), 1, 8, S("a23456789cde")); + test(S("abcde"), 1, 1, SV("1234567890"), 1, 9, S("a234567890cde")); + test(S("abcde"), 1, 1, SV("1234567890"), 1, 10, S("a234567890cde")); + test(S("abcde"), 1, 1, SV("1234567890"), 5, 0, S("acde")); + test(S("abcde"), 1, 1, SV("1234567890"), 5, 1, S("a6cde")); + test(S("abcde"), 1, 1, SV("1234567890"), 5, 2, S("a67cde")); + test(S("abcde"), 1, 1, SV("1234567890"), 5, 4, S("a6789cde")); + test(S("abcde"), 1, 1, SV("1234567890"), 5, 5, S("a67890cde")); + test(S("abcde"), 1, 1, SV("1234567890"), 5, 6, S("a67890cde")); + test(S("abcde"), 1, 1, SV("1234567890"), 9, 0, S("acde")); + test(S("abcde"), 1, 1, SV("1234567890"), 9, 1, S("a0cde")); + test(S("abcde"), 1, 1, SV("1234567890"), 9, 2, S("a0cde")); + test(S("abcde"), 1, 1, SV("1234567890"), 10, 0, S("acde")); + test(S("abcde"), 1, 1, SV("1234567890"), 10, 1, S("acde")); + test(S("abcde"), 1, 1, SV("1234567890"), 11, 0, S("can't happen")); + test(S("abcde"), 1, 1, SV("12345678901234567890"), 0, 0, S("acde")); + test(S("abcde"), 1, 1, SV("12345678901234567890"), 0, 1, S("a1cde")); + test(S("abcde"), 1, 1, SV("12345678901234567890"), 0, 10, S("a1234567890cde")); + test(S("abcde"), 1, 1, SV("12345678901234567890"), 0, 19, S("a1234567890123456789cde")); + test(S("abcde"), 1, 1, SV("12345678901234567890"), 0, 20, S("a12345678901234567890cde")); + test(S("abcde"), 1, 1, SV("12345678901234567890"), 0, 21, S("a12345678901234567890cde")); + test(S("abcde"), 1, 1, SV("12345678901234567890"), 1, 0, S("acde")); + test(S("abcde"), 1, 1, SV("12345678901234567890"), 1, 1, S("a2cde")); + test(S("abcde"), 1, 1, SV("12345678901234567890"), 1, 9, S("a234567890cde")); + test(S("abcde"), 1, 1, SV("12345678901234567890"), 1, 18, S("a234567890123456789cde")); +} + +template +void test8() +{ + test(S("abcde"), 1, 1, SV("12345678901234567890"), 1, 19, S("a2345678901234567890cde")); + test(S("abcde"), 1, 1, SV("12345678901234567890"), 1, 20, S("a2345678901234567890cde")); + test(S("abcde"), 1, 1, SV("12345678901234567890"), 10, 0, S("acde")); + test(S("abcde"), 1, 1, SV("12345678901234567890"), 10, 1, S("a1cde")); + test(S("abcde"), 1, 1, SV("12345678901234567890"), 10, 5, S("a12345cde")); + test(S("abcde"), 1, 1, SV("12345678901234567890"), 10, 9, S("a123456789cde")); + test(S("abcde"), 1, 1, SV("12345678901234567890"), 10, 10, S("a1234567890cde")); + test(S("abcde"), 1, 1, SV("12345678901234567890"), 10, 11, S("a1234567890cde")); + test(S("abcde"), 1, 1, SV("12345678901234567890"), 19, 0, S("acde")); + test(S("abcde"), 1, 1, SV("12345678901234567890"), 19, 1, S("a0cde")); + test(S("abcde"), 1, 1, SV("12345678901234567890"), 19, 2, S("a0cde")); + test(S("abcde"), 1, 1, SV("12345678901234567890"), 20, 0, S("acde")); + test(S("abcde"), 1, 1, SV("12345678901234567890"), 20, 1, S("acde")); + test(S("abcde"), 1, 1, SV("12345678901234567890"), 21, 0, S("can't happen")); + test(S("abcde"), 1, 2, SV(""), 0, 0, S("ade")); + test(S("abcde"), 1, 2, SV(""), 0, 1, S("ade")); + test(S("abcde"), 1, 2, SV(""), 1, 0, S("can't happen")); + test(S("abcde"), 1, 2, SV("12345"), 0, 0, S("ade")); + test(S("abcde"), 1, 2, SV("12345"), 0, 1, S("a1de")); + test(S("abcde"), 1, 2, SV("12345"), 0, 2, S("a12de")); + test(S("abcde"), 1, 2, SV("12345"), 0, 4, S("a1234de")); + test(S("abcde"), 1, 2, SV("12345"), 0, 5, S("a12345de")); + test(S("abcde"), 1, 2, SV("12345"), 0, 6, S("a12345de")); + test(S("abcde"), 1, 2, SV("12345"), 1, 0, S("ade")); + test(S("abcde"), 1, 2, SV("12345"), 1, 1, S("a2de")); + test(S("abcde"), 1, 2, SV("12345"), 1, 2, S("a23de")); + test(S("abcde"), 1, 2, SV("12345"), 1, 3, S("a234de")); + test(S("abcde"), 1, 2, SV("12345"), 1, 4, S("a2345de")); + test(S("abcde"), 1, 2, SV("12345"), 1, 5, S("a2345de")); + test(S("abcde"), 1, 2, SV("12345"), 2, 0, S("ade")); + test(S("abcde"), 1, 2, SV("12345"), 2, 1, S("a3de")); + test(S("abcde"), 1, 2, SV("12345"), 2, 2, S("a34de")); + test(S("abcde"), 1, 2, SV("12345"), 2, 3, S("a345de")); + test(S("abcde"), 1, 2, SV("12345"), 2, 4, S("a345de")); + test(S("abcde"), 1, 2, SV("12345"), 4, 0, S("ade")); + test(S("abcde"), 1, 2, SV("12345"), 4, 1, S("a5de")); + test(S("abcde"), 1, 2, SV("12345"), 4, 2, S("a5de")); + test(S("abcde"), 1, 2, SV("12345"), 5, 0, S("ade")); + test(S("abcde"), 1, 2, SV("12345"), 5, 1, S("ade")); + test(S("abcde"), 1, 2, SV("12345"), 6, 0, S("can't happen")); + test(S("abcde"), 1, 2, SV("1234567890"), 0, 0, S("ade")); + test(S("abcde"), 1, 2, SV("1234567890"), 0, 1, S("a1de")); + test(S("abcde"), 1, 2, SV("1234567890"), 0, 5, S("a12345de")); + test(S("abcde"), 1, 2, SV("1234567890"), 0, 9, S("a123456789de")); + test(S("abcde"), 1, 2, SV("1234567890"), 0, 10, S("a1234567890de")); + test(S("abcde"), 1, 2, SV("1234567890"), 0, 11, S("a1234567890de")); + test(S("abcde"), 1, 2, SV("1234567890"), 1, 0, S("ade")); + test(S("abcde"), 1, 2, SV("1234567890"), 1, 1, S("a2de")); + test(S("abcde"), 1, 2, SV("1234567890"), 1, 4, S("a2345de")); + test(S("abcde"), 1, 2, SV("1234567890"), 1, 8, S("a23456789de")); + test(S("abcde"), 1, 2, SV("1234567890"), 1, 9, S("a234567890de")); + test(S("abcde"), 1, 2, SV("1234567890"), 1, 10, S("a234567890de")); + test(S("abcde"), 1, 2, SV("1234567890"), 5, 0, S("ade")); + test(S("abcde"), 1, 2, SV("1234567890"), 5, 1, S("a6de")); + test(S("abcde"), 1, 2, SV("1234567890"), 5, 2, S("a67de")); + test(S("abcde"), 1, 2, SV("1234567890"), 5, 4, S("a6789de")); + test(S("abcde"), 1, 2, SV("1234567890"), 5, 5, S("a67890de")); + test(S("abcde"), 1, 2, SV("1234567890"), 5, 6, S("a67890de")); + test(S("abcde"), 1, 2, SV("1234567890"), 9, 0, S("ade")); + test(S("abcde"), 1, 2, SV("1234567890"), 9, 1, S("a0de")); + test(S("abcde"), 1, 2, SV("1234567890"), 9, 2, S("a0de")); + test(S("abcde"), 1, 2, SV("1234567890"), 10, 0, S("ade")); + test(S("abcde"), 1, 2, SV("1234567890"), 10, 1, S("ade")); + test(S("abcde"), 1, 2, SV("1234567890"), 11, 0, S("can't happen")); + test(S("abcde"), 1, 2, SV("12345678901234567890"), 0, 0, S("ade")); + test(S("abcde"), 1, 2, SV("12345678901234567890"), 0, 1, S("a1de")); + test(S("abcde"), 1, 2, SV("12345678901234567890"), 0, 10, S("a1234567890de")); + test(S("abcde"), 1, 2, SV("12345678901234567890"), 0, 19, S("a1234567890123456789de")); + test(S("abcde"), 1, 2, SV("12345678901234567890"), 0, 20, S("a12345678901234567890de")); + test(S("abcde"), 1, 2, SV("12345678901234567890"), 0, 21, S("a12345678901234567890de")); + test(S("abcde"), 1, 2, SV("12345678901234567890"), 1, 0, S("ade")); + test(S("abcde"), 1, 2, SV("12345678901234567890"), 1, 1, S("a2de")); + test(S("abcde"), 1, 2, SV("12345678901234567890"), 1, 9, S("a234567890de")); + test(S("abcde"), 1, 2, SV("12345678901234567890"), 1, 18, S("a234567890123456789de")); + test(S("abcde"), 1, 2, SV("12345678901234567890"), 1, 19, S("a2345678901234567890de")); + test(S("abcde"), 1, 2, SV("12345678901234567890"), 1, 20, S("a2345678901234567890de")); + test(S("abcde"), 1, 2, SV("12345678901234567890"), 10, 0, S("ade")); + test(S("abcde"), 1, 2, SV("12345678901234567890"), 10, 1, S("a1de")); + test(S("abcde"), 1, 2, SV("12345678901234567890"), 10, 5, S("a12345de")); + test(S("abcde"), 1, 2, SV("12345678901234567890"), 10, 9, S("a123456789de")); + test(S("abcde"), 1, 2, SV("12345678901234567890"), 10, 10, S("a1234567890de")); + test(S("abcde"), 1, 2, SV("12345678901234567890"), 10, 11, S("a1234567890de")); + test(S("abcde"), 1, 2, SV("12345678901234567890"), 19, 0, S("ade")); + test(S("abcde"), 1, 2, SV("12345678901234567890"), 19, 1, S("a0de")); + test(S("abcde"), 1, 2, SV("12345678901234567890"), 19, 2, S("a0de")); + test(S("abcde"), 1, 2, SV("12345678901234567890"), 20, 0, S("ade")); + test(S("abcde"), 1, 2, SV("12345678901234567890"), 20, 1, S("ade")); + test(S("abcde"), 1, 2, SV("12345678901234567890"), 21, 0, S("can't happen")); + test(S("abcde"), 1, 3, SV(""), 0, 0, S("ae")); + test(S("abcde"), 1, 3, SV(""), 0, 1, S("ae")); + test(S("abcde"), 1, 3, SV(""), 1, 0, S("can't happen")); + test(S("abcde"), 1, 3, SV("12345"), 0, 0, S("ae")); + test(S("abcde"), 1, 3, SV("12345"), 0, 1, S("a1e")); + test(S("abcde"), 1, 3, SV("12345"), 0, 2, S("a12e")); + test(S("abcde"), 1, 3, SV("12345"), 0, 4, S("a1234e")); + test(S("abcde"), 1, 3, SV("12345"), 0, 5, S("a12345e")); + test(S("abcde"), 1, 3, SV("12345"), 0, 6, S("a12345e")); + test(S("abcde"), 1, 3, SV("12345"), 1, 0, S("ae")); + test(S("abcde"), 1, 3, SV("12345"), 1, 1, S("a2e")); + test(S("abcde"), 1, 3, SV("12345"), 1, 2, S("a23e")); +} + +template +void test9() +{ + test(S("abcde"), 1, 3, SV("12345"), 1, 3, S("a234e")); + test(S("abcde"), 1, 3, SV("12345"), 1, 4, S("a2345e")); + test(S("abcde"), 1, 3, SV("12345"), 1, 5, S("a2345e")); + test(S("abcde"), 1, 3, SV("12345"), 2, 0, S("ae")); + test(S("abcde"), 1, 3, SV("12345"), 2, 1, S("a3e")); + test(S("abcde"), 1, 3, SV("12345"), 2, 2, S("a34e")); + test(S("abcde"), 1, 3, SV("12345"), 2, 3, S("a345e")); + test(S("abcde"), 1, 3, SV("12345"), 2, 4, S("a345e")); + test(S("abcde"), 1, 3, SV("12345"), 4, 0, S("ae")); + test(S("abcde"), 1, 3, SV("12345"), 4, 1, S("a5e")); + test(S("abcde"), 1, 3, SV("12345"), 4, 2, S("a5e")); + test(S("abcde"), 1, 3, SV("12345"), 5, 0, S("ae")); + test(S("abcde"), 1, 3, SV("12345"), 5, 1, S("ae")); + test(S("abcde"), 1, 3, SV("12345"), 6, 0, S("can't happen")); + test(S("abcde"), 1, 3, SV("1234567890"), 0, 0, S("ae")); + test(S("abcde"), 1, 3, SV("1234567890"), 0, 1, S("a1e")); + test(S("abcde"), 1, 3, SV("1234567890"), 0, 5, S("a12345e")); + test(S("abcde"), 1, 3, SV("1234567890"), 0, 9, S("a123456789e")); + test(S("abcde"), 1, 3, SV("1234567890"), 0, 10, S("a1234567890e")); + test(S("abcde"), 1, 3, SV("1234567890"), 0, 11, S("a1234567890e")); + test(S("abcde"), 1, 3, SV("1234567890"), 1, 0, S("ae")); + test(S("abcde"), 1, 3, SV("1234567890"), 1, 1, S("a2e")); + test(S("abcde"), 1, 3, SV("1234567890"), 1, 4, S("a2345e")); + test(S("abcde"), 1, 3, SV("1234567890"), 1, 8, S("a23456789e")); + test(S("abcde"), 1, 3, SV("1234567890"), 1, 9, S("a234567890e")); + test(S("abcde"), 1, 3, SV("1234567890"), 1, 10, S("a234567890e")); + test(S("abcde"), 1, 3, SV("1234567890"), 5, 0, S("ae")); + test(S("abcde"), 1, 3, SV("1234567890"), 5, 1, S("a6e")); + test(S("abcde"), 1, 3, SV("1234567890"), 5, 2, S("a67e")); + test(S("abcde"), 1, 3, SV("1234567890"), 5, 4, S("a6789e")); + test(S("abcde"), 1, 3, SV("1234567890"), 5, 5, S("a67890e")); + test(S("abcde"), 1, 3, SV("1234567890"), 5, 6, S("a67890e")); + test(S("abcde"), 1, 3, SV("1234567890"), 9, 0, S("ae")); + test(S("abcde"), 1, 3, SV("1234567890"), 9, 1, S("a0e")); + test(S("abcde"), 1, 3, SV("1234567890"), 9, 2, S("a0e")); + test(S("abcde"), 1, 3, SV("1234567890"), 10, 0, S("ae")); + test(S("abcde"), 1, 3, SV("1234567890"), 10, 1, S("ae")); + test(S("abcde"), 1, 3, SV("1234567890"), 11, 0, S("can't happen")); + test(S("abcde"), 1, 3, SV("12345678901234567890"), 0, 0, S("ae")); + test(S("abcde"), 1, 3, SV("12345678901234567890"), 0, 1, S("a1e")); + test(S("abcde"), 1, 3, SV("12345678901234567890"), 0, 10, S("a1234567890e")); + test(S("abcde"), 1, 3, SV("12345678901234567890"), 0, 19, S("a1234567890123456789e")); + test(S("abcde"), 1, 3, SV("12345678901234567890"), 0, 20, S("a12345678901234567890e")); + test(S("abcde"), 1, 3, SV("12345678901234567890"), 0, 21, S("a12345678901234567890e")); + test(S("abcde"), 1, 3, SV("12345678901234567890"), 1, 0, S("ae")); + test(S("abcde"), 1, 3, SV("12345678901234567890"), 1, 1, S("a2e")); + test(S("abcde"), 1, 3, SV("12345678901234567890"), 1, 9, S("a234567890e")); + test(S("abcde"), 1, 3, SV("12345678901234567890"), 1, 18, S("a234567890123456789e")); + test(S("abcde"), 1, 3, SV("12345678901234567890"), 1, 19, S("a2345678901234567890e")); + test(S("abcde"), 1, 3, SV("12345678901234567890"), 1, 20, S("a2345678901234567890e")); + test(S("abcde"), 1, 3, SV("12345678901234567890"), 10, 0, S("ae")); + test(S("abcde"), 1, 3, SV("12345678901234567890"), 10, 1, S("a1e")); + test(S("abcde"), 1, 3, SV("12345678901234567890"), 10, 5, S("a12345e")); + test(S("abcde"), 1, 3, SV("12345678901234567890"), 10, 9, S("a123456789e")); + test(S("abcde"), 1, 3, SV("12345678901234567890"), 10, 10, S("a1234567890e")); + test(S("abcde"), 1, 3, SV("12345678901234567890"), 10, 11, S("a1234567890e")); + test(S("abcde"), 1, 3, SV("12345678901234567890"), 19, 0, S("ae")); + test(S("abcde"), 1, 3, SV("12345678901234567890"), 19, 1, S("a0e")); + test(S("abcde"), 1, 3, SV("12345678901234567890"), 19, 2, S("a0e")); + test(S("abcde"), 1, 3, SV("12345678901234567890"), 20, 0, S("ae")); + test(S("abcde"), 1, 3, SV("12345678901234567890"), 20, 1, S("ae")); + test(S("abcde"), 1, 3, SV("12345678901234567890"), 21, 0, S("can't happen")); + test(S("abcde"), 1, 4, SV(""), 0, 0, S("a")); + test(S("abcde"), 1, 4, SV(""), 0, 1, S("a")); + test(S("abcde"), 1, 4, SV(""), 1, 0, S("can't happen")); + test(S("abcde"), 1, 4, SV("12345"), 0, 0, S("a")); + test(S("abcde"), 1, 4, SV("12345"), 0, 1, S("a1")); + test(S("abcde"), 1, 4, SV("12345"), 0, 2, S("a12")); + test(S("abcde"), 1, 4, SV("12345"), 0, 4, S("a1234")); + test(S("abcde"), 1, 4, SV("12345"), 0, 5, S("a12345")); + test(S("abcde"), 1, 4, SV("12345"), 0, 6, S("a12345")); + test(S("abcde"), 1, 4, SV("12345"), 1, 0, S("a")); + test(S("abcde"), 1, 4, SV("12345"), 1, 1, S("a2")); + test(S("abcde"), 1, 4, SV("12345"), 1, 2, S("a23")); + test(S("abcde"), 1, 4, SV("12345"), 1, 3, S("a234")); + test(S("abcde"), 1, 4, SV("12345"), 1, 4, S("a2345")); + test(S("abcde"), 1, 4, SV("12345"), 1, 5, S("a2345")); + test(S("abcde"), 1, 4, SV("12345"), 2, 0, S("a")); + test(S("abcde"), 1, 4, SV("12345"), 2, 1, S("a3")); + test(S("abcde"), 1, 4, SV("12345"), 2, 2, S("a34")); + test(S("abcde"), 1, 4, SV("12345"), 2, 3, S("a345")); + test(S("abcde"), 1, 4, SV("12345"), 2, 4, S("a345")); + test(S("abcde"), 1, 4, SV("12345"), 4, 0, S("a")); + test(S("abcde"), 1, 4, SV("12345"), 4, 1, S("a5")); + test(S("abcde"), 1, 4, SV("12345"), 4, 2, S("a5")); + test(S("abcde"), 1, 4, SV("12345"), 5, 0, S("a")); + test(S("abcde"), 1, 4, SV("12345"), 5, 1, S("a")); + test(S("abcde"), 1, 4, SV("12345"), 6, 0, S("can't happen")); + test(S("abcde"), 1, 4, SV("1234567890"), 0, 0, S("a")); + test(S("abcde"), 1, 4, SV("1234567890"), 0, 1, S("a1")); + test(S("abcde"), 1, 4, SV("1234567890"), 0, 5, S("a12345")); + test(S("abcde"), 1, 4, SV("1234567890"), 0, 9, S("a123456789")); + test(S("abcde"), 1, 4, SV("1234567890"), 0, 10, S("a1234567890")); + test(S("abcde"), 1, 4, SV("1234567890"), 0, 11, S("a1234567890")); + test(S("abcde"), 1, 4, SV("1234567890"), 1, 0, S("a")); + test(S("abcde"), 1, 4, SV("1234567890"), 1, 1, S("a2")); + test(S("abcde"), 1, 4, SV("1234567890"), 1, 4, S("a2345")); + test(S("abcde"), 1, 4, SV("1234567890"), 1, 8, S("a23456789")); + test(S("abcde"), 1, 4, SV("1234567890"), 1, 9, S("a234567890")); + test(S("abcde"), 1, 4, SV("1234567890"), 1, 10, S("a234567890")); +} + +template +void test10() +{ + test(S("abcde"), 1, 4, SV("1234567890"), 5, 0, S("a")); + test(S("abcde"), 1, 4, SV("1234567890"), 5, 1, S("a6")); + test(S("abcde"), 1, 4, SV("1234567890"), 5, 2, S("a67")); + test(S("abcde"), 1, 4, SV("1234567890"), 5, 4, S("a6789")); + test(S("abcde"), 1, 4, SV("1234567890"), 5, 5, S("a67890")); + test(S("abcde"), 1, 4, SV("1234567890"), 5, 6, S("a67890")); + test(S("abcde"), 1, 4, SV("1234567890"), 9, 0, S("a")); + test(S("abcde"), 1, 4, SV("1234567890"), 9, 1, S("a0")); + test(S("abcde"), 1, 4, SV("1234567890"), 9, 2, S("a0")); + test(S("abcde"), 1, 4, SV("1234567890"), 10, 0, S("a")); + test(S("abcde"), 1, 4, SV("1234567890"), 10, 1, S("a")); + test(S("abcde"), 1, 4, SV("1234567890"), 11, 0, S("can't happen")); + test(S("abcde"), 1, 4, SV("12345678901234567890"), 0, 0, S("a")); + test(S("abcde"), 1, 4, SV("12345678901234567890"), 0, 1, S("a1")); + test(S("abcde"), 1, 4, SV("12345678901234567890"), 0, 10, S("a1234567890")); + test(S("abcde"), 1, 4, SV("12345678901234567890"), 0, 19, S("a1234567890123456789")); + test(S("abcde"), 1, 4, SV("12345678901234567890"), 0, 20, S("a12345678901234567890")); + test(S("abcde"), 1, 4, SV("12345678901234567890"), 0, 21, S("a12345678901234567890")); + test(S("abcde"), 1, 4, SV("12345678901234567890"), 1, 0, S("a")); + test(S("abcde"), 1, 4, SV("12345678901234567890"), 1, 1, S("a2")); + test(S("abcde"), 1, 4, SV("12345678901234567890"), 1, 9, S("a234567890")); + test(S("abcde"), 1, 4, SV("12345678901234567890"), 1, 18, S("a234567890123456789")); + test(S("abcde"), 1, 4, SV("12345678901234567890"), 1, 19, S("a2345678901234567890")); + test(S("abcde"), 1, 4, SV("12345678901234567890"), 1, 20, S("a2345678901234567890")); + test(S("abcde"), 1, 4, SV("12345678901234567890"), 10, 0, S("a")); + test(S("abcde"), 1, 4, SV("12345678901234567890"), 10, 1, S("a1")); + test(S("abcde"), 1, 4, SV("12345678901234567890"), 10, 5, S("a12345")); + test(S("abcde"), 1, 4, SV("12345678901234567890"), 10, 9, S("a123456789")); + test(S("abcde"), 1, 4, SV("12345678901234567890"), 10, 10, S("a1234567890")); + test(S("abcde"), 1, 4, SV("12345678901234567890"), 10, 11, S("a1234567890")); + test(S("abcde"), 1, 4, SV("12345678901234567890"), 19, 0, S("a")); + test(S("abcde"), 1, 4, SV("12345678901234567890"), 19, 1, S("a0")); + test(S("abcde"), 1, 4, SV("12345678901234567890"), 19, 2, S("a0")); + test(S("abcde"), 1, 4, SV("12345678901234567890"), 20, 0, S("a")); + test(S("abcde"), 1, 4, SV("12345678901234567890"), 20, 1, S("a")); + test(S("abcde"), 1, 4, SV("12345678901234567890"), 21, 0, S("can't happen")); + test(S("abcde"), 1, 5, SV(""), 0, 0, S("a")); + test(S("abcde"), 1, 5, SV(""), 0, 1, S("a")); + test(S("abcde"), 1, 5, SV(""), 1, 0, S("can't happen")); + test(S("abcde"), 1, 5, SV("12345"), 0, 0, S("a")); + test(S("abcde"), 1, 5, SV("12345"), 0, 1, S("a1")); + test(S("abcde"), 1, 5, SV("12345"), 0, 2, S("a12")); + test(S("abcde"), 1, 5, SV("12345"), 0, 4, S("a1234")); + test(S("abcde"), 1, 5, SV("12345"), 0, 5, S("a12345")); + test(S("abcde"), 1, 5, SV("12345"), 0, 6, S("a12345")); + test(S("abcde"), 1, 5, SV("12345"), 1, 0, S("a")); + test(S("abcde"), 1, 5, SV("12345"), 1, 1, S("a2")); + test(S("abcde"), 1, 5, SV("12345"), 1, 2, S("a23")); + test(S("abcde"), 1, 5, SV("12345"), 1, 3, S("a234")); + test(S("abcde"), 1, 5, SV("12345"), 1, 4, S("a2345")); + test(S("abcde"), 1, 5, SV("12345"), 1, 5, S("a2345")); + test(S("abcde"), 1, 5, SV("12345"), 2, 0, S("a")); + test(S("abcde"), 1, 5, SV("12345"), 2, 1, S("a3")); + test(S("abcde"), 1, 5, SV("12345"), 2, 2, S("a34")); + test(S("abcde"), 1, 5, SV("12345"), 2, 3, S("a345")); + test(S("abcde"), 1, 5, SV("12345"), 2, 4, S("a345")); + test(S("abcde"), 1, 5, SV("12345"), 4, 0, S("a")); + test(S("abcde"), 1, 5, SV("12345"), 4, 1, S("a5")); + test(S("abcde"), 1, 5, SV("12345"), 4, 2, S("a5")); + test(S("abcde"), 1, 5, SV("12345"), 5, 0, S("a")); + test(S("abcde"), 1, 5, SV("12345"), 5, 1, S("a")); + test(S("abcde"), 1, 5, SV("12345"), 6, 0, S("can't happen")); + test(S("abcde"), 1, 5, SV("1234567890"), 0, 0, S("a")); + test(S("abcde"), 1, 5, SV("1234567890"), 0, 1, S("a1")); + test(S("abcde"), 1, 5, SV("1234567890"), 0, 5, S("a12345")); + test(S("abcde"), 1, 5, SV("1234567890"), 0, 9, S("a123456789")); + test(S("abcde"), 1, 5, SV("1234567890"), 0, 10, S("a1234567890")); + test(S("abcde"), 1, 5, SV("1234567890"), 0, 11, S("a1234567890")); + test(S("abcde"), 1, 5, SV("1234567890"), 1, 0, S("a")); + test(S("abcde"), 1, 5, SV("1234567890"), 1, 1, S("a2")); + test(S("abcde"), 1, 5, SV("1234567890"), 1, 4, S("a2345")); + test(S("abcde"), 1, 5, SV("1234567890"), 1, 8, S("a23456789")); + test(S("abcde"), 1, 5, SV("1234567890"), 1, 9, S("a234567890")); + test(S("abcde"), 1, 5, SV("1234567890"), 1, 10, S("a234567890")); + test(S("abcde"), 1, 5, SV("1234567890"), 5, 0, S("a")); + test(S("abcde"), 1, 5, SV("1234567890"), 5, 1, S("a6")); + test(S("abcde"), 1, 5, SV("1234567890"), 5, 2, S("a67")); + test(S("abcde"), 1, 5, SV("1234567890"), 5, 4, S("a6789")); + test(S("abcde"), 1, 5, SV("1234567890"), 5, 5, S("a67890")); + test(S("abcde"), 1, 5, SV("1234567890"), 5, 6, S("a67890")); + test(S("abcde"), 1, 5, SV("1234567890"), 9, 0, S("a")); + test(S("abcde"), 1, 5, SV("1234567890"), 9, 1, S("a0")); + test(S("abcde"), 1, 5, SV("1234567890"), 9, 2, S("a0")); + test(S("abcde"), 1, 5, SV("1234567890"), 10, 0, S("a")); + test(S("abcde"), 1, 5, SV("1234567890"), 10, 1, S("a")); + test(S("abcde"), 1, 5, SV("1234567890"), 11, 0, S("can't happen")); + test(S("abcde"), 1, 5, SV("12345678901234567890"), 0, 0, S("a")); + test(S("abcde"), 1, 5, SV("12345678901234567890"), 0, 1, S("a1")); + test(S("abcde"), 1, 5, SV("12345678901234567890"), 0, 10, S("a1234567890")); + test(S("abcde"), 1, 5, SV("12345678901234567890"), 0, 19, S("a1234567890123456789")); + test(S("abcde"), 1, 5, SV("12345678901234567890"), 0, 20, S("a12345678901234567890")); + test(S("abcde"), 1, 5, SV("12345678901234567890"), 0, 21, S("a12345678901234567890")); + test(S("abcde"), 1, 5, SV("12345678901234567890"), 1, 0, S("a")); + test(S("abcde"), 1, 5, SV("12345678901234567890"), 1, 1, S("a2")); + test(S("abcde"), 1, 5, SV("12345678901234567890"), 1, 9, S("a234567890")); + test(S("abcde"), 1, 5, SV("12345678901234567890"), 1, 18, S("a234567890123456789")); + test(S("abcde"), 1, 5, SV("12345678901234567890"), 1, 19, S("a2345678901234567890")); + test(S("abcde"), 1, 5, SV("12345678901234567890"), 1, 20, S("a2345678901234567890")); + test(S("abcde"), 1, 5, SV("12345678901234567890"), 10, 0, S("a")); + test(S("abcde"), 1, 5, SV("12345678901234567890"), 10, 1, S("a1")); +} + +template +void test11() +{ + test(S("abcde"), 1, 5, SV("12345678901234567890"), 10, 5, S("a12345")); + test(S("abcde"), 1, 5, SV("12345678901234567890"), 10, 9, S("a123456789")); + test(S("abcde"), 1, 5, SV("12345678901234567890"), 10, 10, S("a1234567890")); + test(S("abcde"), 1, 5, SV("12345678901234567890"), 10, 11, S("a1234567890")); + test(S("abcde"), 1, 5, SV("12345678901234567890"), 19, 0, S("a")); + test(S("abcde"), 1, 5, SV("12345678901234567890"), 19, 1, S("a0")); + test(S("abcde"), 1, 5, SV("12345678901234567890"), 19, 2, S("a0")); + test(S("abcde"), 1, 5, SV("12345678901234567890"), 20, 0, S("a")); + test(S("abcde"), 1, 5, SV("12345678901234567890"), 20, 1, S("a")); + test(S("abcde"), 1, 5, SV("12345678901234567890"), 21, 0, S("can't happen")); + test(S("abcde"), 2, 0, SV(""), 0, 0, S("abcde")); + test(S("abcde"), 2, 0, SV(""), 0, 1, S("abcde")); + test(S("abcde"), 2, 0, SV(""), 1, 0, S("can't happen")); + test(S("abcde"), 2, 0, SV("12345"), 0, 0, S("abcde")); + test(S("abcde"), 2, 0, SV("12345"), 0, 1, S("ab1cde")); + test(S("abcde"), 2, 0, SV("12345"), 0, 2, S("ab12cde")); + test(S("abcde"), 2, 0, SV("12345"), 0, 4, S("ab1234cde")); + test(S("abcde"), 2, 0, SV("12345"), 0, 5, S("ab12345cde")); + test(S("abcde"), 2, 0, SV("12345"), 0, 6, S("ab12345cde")); + test(S("abcde"), 2, 0, SV("12345"), 1, 0, S("abcde")); + test(S("abcde"), 2, 0, SV("12345"), 1, 1, S("ab2cde")); + test(S("abcde"), 2, 0, SV("12345"), 1, 2, S("ab23cde")); + test(S("abcde"), 2, 0, SV("12345"), 1, 3, S("ab234cde")); + test(S("abcde"), 2, 0, SV("12345"), 1, 4, S("ab2345cde")); + test(S("abcde"), 2, 0, SV("12345"), 1, 5, S("ab2345cde")); + test(S("abcde"), 2, 0, SV("12345"), 2, 0, S("abcde")); + test(S("abcde"), 2, 0, SV("12345"), 2, 1, S("ab3cde")); + test(S("abcde"), 2, 0, SV("12345"), 2, 2, S("ab34cde")); + test(S("abcde"), 2, 0, SV("12345"), 2, 3, S("ab345cde")); + test(S("abcde"), 2, 0, SV("12345"), 2, 4, S("ab345cde")); + test(S("abcde"), 2, 0, SV("12345"), 4, 0, S("abcde")); + test(S("abcde"), 2, 0, SV("12345"), 4, 1, S("ab5cde")); + test(S("abcde"), 2, 0, SV("12345"), 4, 2, S("ab5cde")); + test(S("abcde"), 2, 0, SV("12345"), 5, 0, S("abcde")); + test(S("abcde"), 2, 0, SV("12345"), 5, 1, S("abcde")); + test(S("abcde"), 2, 0, SV("12345"), 6, 0, S("can't happen")); + test(S("abcde"), 2, 0, SV("1234567890"), 0, 0, S("abcde")); + test(S("abcde"), 2, 0, SV("1234567890"), 0, 1, S("ab1cde")); + test(S("abcde"), 2, 0, SV("1234567890"), 0, 5, S("ab12345cde")); + test(S("abcde"), 2, 0, SV("1234567890"), 0, 9, S("ab123456789cde")); + test(S("abcde"), 2, 0, SV("1234567890"), 0, 10, S("ab1234567890cde")); + test(S("abcde"), 2, 0, SV("1234567890"), 0, 11, S("ab1234567890cde")); + test(S("abcde"), 2, 0, SV("1234567890"), 1, 0, S("abcde")); + test(S("abcde"), 2, 0, SV("1234567890"), 1, 1, S("ab2cde")); + test(S("abcde"), 2, 0, SV("1234567890"), 1, 4, S("ab2345cde")); + test(S("abcde"), 2, 0, SV("1234567890"), 1, 8, S("ab23456789cde")); + test(S("abcde"), 2, 0, SV("1234567890"), 1, 9, S("ab234567890cde")); + test(S("abcde"), 2, 0, SV("1234567890"), 1, 10, S("ab234567890cde")); + test(S("abcde"), 2, 0, SV("1234567890"), 5, 0, S("abcde")); + test(S("abcde"), 2, 0, SV("1234567890"), 5, 1, S("ab6cde")); + test(S("abcde"), 2, 0, SV("1234567890"), 5, 2, S("ab67cde")); + test(S("abcde"), 2, 0, SV("1234567890"), 5, 4, S("ab6789cde")); + test(S("abcde"), 2, 0, SV("1234567890"), 5, 5, S("ab67890cde")); + test(S("abcde"), 2, 0, SV("1234567890"), 5, 6, S("ab67890cde")); + test(S("abcde"), 2, 0, SV("1234567890"), 9, 0, S("abcde")); + test(S("abcde"), 2, 0, SV("1234567890"), 9, 1, S("ab0cde")); + test(S("abcde"), 2, 0, SV("1234567890"), 9, 2, S("ab0cde")); + test(S("abcde"), 2, 0, SV("1234567890"), 10, 0, S("abcde")); + test(S("abcde"), 2, 0, SV("1234567890"), 10, 1, S("abcde")); + test(S("abcde"), 2, 0, SV("1234567890"), 11, 0, S("can't happen")); + test(S("abcde"), 2, 0, SV("12345678901234567890"), 0, 0, S("abcde")); + test(S("abcde"), 2, 0, SV("12345678901234567890"), 0, 1, S("ab1cde")); + test(S("abcde"), 2, 0, SV("12345678901234567890"), 0, 10, S("ab1234567890cde")); + test(S("abcde"), 2, 0, SV("12345678901234567890"), 0, 19, S("ab1234567890123456789cde")); + test(S("abcde"), 2, 0, SV("12345678901234567890"), 0, 20, S("ab12345678901234567890cde")); + test(S("abcde"), 2, 0, SV("12345678901234567890"), 0, 21, S("ab12345678901234567890cde")); + test(S("abcde"), 2, 0, SV("12345678901234567890"), 1, 0, S("abcde")); + test(S("abcde"), 2, 0, SV("12345678901234567890"), 1, 1, S("ab2cde")); + test(S("abcde"), 2, 0, SV("12345678901234567890"), 1, 9, S("ab234567890cde")); + test(S("abcde"), 2, 0, SV("12345678901234567890"), 1, 18, S("ab234567890123456789cde")); + test(S("abcde"), 2, 0, SV("12345678901234567890"), 1, 19, S("ab2345678901234567890cde")); + test(S("abcde"), 2, 0, SV("12345678901234567890"), 1, 20, S("ab2345678901234567890cde")); + test(S("abcde"), 2, 0, SV("12345678901234567890"), 10, 0, S("abcde")); + test(S("abcde"), 2, 0, SV("12345678901234567890"), 10, 1, S("ab1cde")); + test(S("abcde"), 2, 0, SV("12345678901234567890"), 10, 5, S("ab12345cde")); + test(S("abcde"), 2, 0, SV("12345678901234567890"), 10, 9, S("ab123456789cde")); + test(S("abcde"), 2, 0, SV("12345678901234567890"), 10, 10, S("ab1234567890cde")); + test(S("abcde"), 2, 0, SV("12345678901234567890"), 10, 11, S("ab1234567890cde")); + test(S("abcde"), 2, 0, SV("12345678901234567890"), 19, 0, S("abcde")); + test(S("abcde"), 2, 0, SV("12345678901234567890"), 19, 1, S("ab0cde")); + test(S("abcde"), 2, 0, SV("12345678901234567890"), 19, 2, S("ab0cde")); + test(S("abcde"), 2, 0, SV("12345678901234567890"), 20, 0, S("abcde")); + test(S("abcde"), 2, 0, SV("12345678901234567890"), 20, 1, S("abcde")); + test(S("abcde"), 2, 0, SV("12345678901234567890"), 21, 0, S("can't happen")); + test(S("abcde"), 2, 1, SV(""), 0, 0, S("abde")); + test(S("abcde"), 2, 1, SV(""), 0, 1, S("abde")); + test(S("abcde"), 2, 1, SV(""), 1, 0, S("can't happen")); + test(S("abcde"), 2, 1, SV("12345"), 0, 0, S("abde")); + test(S("abcde"), 2, 1, SV("12345"), 0, 1, S("ab1de")); + test(S("abcde"), 2, 1, SV("12345"), 0, 2, S("ab12de")); + test(S("abcde"), 2, 1, SV("12345"), 0, 4, S("ab1234de")); + test(S("abcde"), 2, 1, SV("12345"), 0, 5, S("ab12345de")); + test(S("abcde"), 2, 1, SV("12345"), 0, 6, S("ab12345de")); + test(S("abcde"), 2, 1, SV("12345"), 1, 0, S("abde")); + test(S("abcde"), 2, 1, SV("12345"), 1, 1, S("ab2de")); + test(S("abcde"), 2, 1, SV("12345"), 1, 2, S("ab23de")); + test(S("abcde"), 2, 1, SV("12345"), 1, 3, S("ab234de")); + test(S("abcde"), 2, 1, SV("12345"), 1, 4, S("ab2345de")); + test(S("abcde"), 2, 1, SV("12345"), 1, 5, S("ab2345de")); + test(S("abcde"), 2, 1, SV("12345"), 2, 0, S("abde")); +} + +template +void test12() +{ + test(S("abcde"), 2, 1, SV("12345"), 2, 1, S("ab3de")); + test(S("abcde"), 2, 1, SV("12345"), 2, 2, S("ab34de")); + test(S("abcde"), 2, 1, SV("12345"), 2, 3, S("ab345de")); + test(S("abcde"), 2, 1, SV("12345"), 2, 4, S("ab345de")); + test(S("abcde"), 2, 1, SV("12345"), 4, 0, S("abde")); + test(S("abcde"), 2, 1, SV("12345"), 4, 1, S("ab5de")); + test(S("abcde"), 2, 1, SV("12345"), 4, 2, S("ab5de")); + test(S("abcde"), 2, 1, SV("12345"), 5, 0, S("abde")); + test(S("abcde"), 2, 1, SV("12345"), 5, 1, S("abde")); + test(S("abcde"), 2, 1, SV("12345"), 6, 0, S("can't happen")); + test(S("abcde"), 2, 1, SV("1234567890"), 0, 0, S("abde")); + test(S("abcde"), 2, 1, SV("1234567890"), 0, 1, S("ab1de")); + test(S("abcde"), 2, 1, SV("1234567890"), 0, 5, S("ab12345de")); + test(S("abcde"), 2, 1, SV("1234567890"), 0, 9, S("ab123456789de")); + test(S("abcde"), 2, 1, SV("1234567890"), 0, 10, S("ab1234567890de")); + test(S("abcde"), 2, 1, SV("1234567890"), 0, 11, S("ab1234567890de")); + test(S("abcde"), 2, 1, SV("1234567890"), 1, 0, S("abde")); + test(S("abcde"), 2, 1, SV("1234567890"), 1, 1, S("ab2de")); + test(S("abcde"), 2, 1, SV("1234567890"), 1, 4, S("ab2345de")); + test(S("abcde"), 2, 1, SV("1234567890"), 1, 8, S("ab23456789de")); + test(S("abcde"), 2, 1, SV("1234567890"), 1, 9, S("ab234567890de")); + test(S("abcde"), 2, 1, SV("1234567890"), 1, 10, S("ab234567890de")); + test(S("abcde"), 2, 1, SV("1234567890"), 5, 0, S("abde")); + test(S("abcde"), 2, 1, SV("1234567890"), 5, 1, S("ab6de")); + test(S("abcde"), 2, 1, SV("1234567890"), 5, 2, S("ab67de")); + test(S("abcde"), 2, 1, SV("1234567890"), 5, 4, S("ab6789de")); + test(S("abcde"), 2, 1, SV("1234567890"), 5, 5, S("ab67890de")); + test(S("abcde"), 2, 1, SV("1234567890"), 5, 6, S("ab67890de")); + test(S("abcde"), 2, 1, SV("1234567890"), 9, 0, S("abde")); + test(S("abcde"), 2, 1, SV("1234567890"), 9, 1, S("ab0de")); + test(S("abcde"), 2, 1, SV("1234567890"), 9, 2, S("ab0de")); + test(S("abcde"), 2, 1, SV("1234567890"), 10, 0, S("abde")); + test(S("abcde"), 2, 1, SV("1234567890"), 10, 1, S("abde")); + test(S("abcde"), 2, 1, SV("1234567890"), 11, 0, S("can't happen")); + test(S("abcde"), 2, 1, SV("12345678901234567890"), 0, 0, S("abde")); + test(S("abcde"), 2, 1, SV("12345678901234567890"), 0, 1, S("ab1de")); + test(S("abcde"), 2, 1, SV("12345678901234567890"), 0, 10, S("ab1234567890de")); + test(S("abcde"), 2, 1, SV("12345678901234567890"), 0, 19, S("ab1234567890123456789de")); + test(S("abcde"), 2, 1, SV("12345678901234567890"), 0, 20, S("ab12345678901234567890de")); + test(S("abcde"), 2, 1, SV("12345678901234567890"), 0, 21, S("ab12345678901234567890de")); + test(S("abcde"), 2, 1, SV("12345678901234567890"), 1, 0, S("abde")); + test(S("abcde"), 2, 1, SV("12345678901234567890"), 1, 1, S("ab2de")); + test(S("abcde"), 2, 1, SV("12345678901234567890"), 1, 9, S("ab234567890de")); + test(S("abcde"), 2, 1, SV("12345678901234567890"), 1, 18, S("ab234567890123456789de")); + test(S("abcde"), 2, 1, SV("12345678901234567890"), 1, 19, S("ab2345678901234567890de")); + test(S("abcde"), 2, 1, SV("12345678901234567890"), 1, 20, S("ab2345678901234567890de")); + test(S("abcde"), 2, 1, SV("12345678901234567890"), 10, 0, S("abde")); + test(S("abcde"), 2, 1, SV("12345678901234567890"), 10, 1, S("ab1de")); + test(S("abcde"), 2, 1, SV("12345678901234567890"), 10, 5, S("ab12345de")); + test(S("abcde"), 2, 1, SV("12345678901234567890"), 10, 9, S("ab123456789de")); + test(S("abcde"), 2, 1, SV("12345678901234567890"), 10, 10, S("ab1234567890de")); + test(S("abcde"), 2, 1, SV("12345678901234567890"), 10, 11, S("ab1234567890de")); + test(S("abcde"), 2, 1, SV("12345678901234567890"), 19, 0, S("abde")); + test(S("abcde"), 2, 1, SV("12345678901234567890"), 19, 1, S("ab0de")); + test(S("abcde"), 2, 1, SV("12345678901234567890"), 19, 2, S("ab0de")); + test(S("abcde"), 2, 1, SV("12345678901234567890"), 20, 0, S("abde")); + test(S("abcde"), 2, 1, SV("12345678901234567890"), 20, 1, S("abde")); + test(S("abcde"), 2, 1, SV("12345678901234567890"), 21, 0, S("can't happen")); + test(S("abcde"), 2, 2, SV(""), 0, 0, S("abe")); + test(S("abcde"), 2, 2, SV(""), 0, 1, S("abe")); + test(S("abcde"), 2, 2, SV(""), 1, 0, S("can't happen")); + test(S("abcde"), 2, 2, SV("12345"), 0, 0, S("abe")); + test(S("abcde"), 2, 2, SV("12345"), 0, 1, S("ab1e")); + test(S("abcde"), 2, 2, SV("12345"), 0, 2, S("ab12e")); + test(S("abcde"), 2, 2, SV("12345"), 0, 4, S("ab1234e")); + test(S("abcde"), 2, 2, SV("12345"), 0, 5, S("ab12345e")); + test(S("abcde"), 2, 2, SV("12345"), 0, 6, S("ab12345e")); + test(S("abcde"), 2, 2, SV("12345"), 1, 0, S("abe")); + test(S("abcde"), 2, 2, SV("12345"), 1, 1, S("ab2e")); + test(S("abcde"), 2, 2, SV("12345"), 1, 2, S("ab23e")); + test(S("abcde"), 2, 2, SV("12345"), 1, 3, S("ab234e")); + test(S("abcde"), 2, 2, SV("12345"), 1, 4, S("ab2345e")); + test(S("abcde"), 2, 2, SV("12345"), 1, 5, S("ab2345e")); + test(S("abcde"), 2, 2, SV("12345"), 2, 0, S("abe")); + test(S("abcde"), 2, 2, SV("12345"), 2, 1, S("ab3e")); + test(S("abcde"), 2, 2, SV("12345"), 2, 2, S("ab34e")); + test(S("abcde"), 2, 2, SV("12345"), 2, 3, S("ab345e")); + test(S("abcde"), 2, 2, SV("12345"), 2, 4, S("ab345e")); + test(S("abcde"), 2, 2, SV("12345"), 4, 0, S("abe")); + test(S("abcde"), 2, 2, SV("12345"), 4, 1, S("ab5e")); + test(S("abcde"), 2, 2, SV("12345"), 4, 2, S("ab5e")); + test(S("abcde"), 2, 2, SV("12345"), 5, 0, S("abe")); + test(S("abcde"), 2, 2, SV("12345"), 5, 1, S("abe")); + test(S("abcde"), 2, 2, SV("12345"), 6, 0, S("can't happen")); + test(S("abcde"), 2, 2, SV("1234567890"), 0, 0, S("abe")); + test(S("abcde"), 2, 2, SV("1234567890"), 0, 1, S("ab1e")); + test(S("abcde"), 2, 2, SV("1234567890"), 0, 5, S("ab12345e")); + test(S("abcde"), 2, 2, SV("1234567890"), 0, 9, S("ab123456789e")); + test(S("abcde"), 2, 2, SV("1234567890"), 0, 10, S("ab1234567890e")); + test(S("abcde"), 2, 2, SV("1234567890"), 0, 11, S("ab1234567890e")); + test(S("abcde"), 2, 2, SV("1234567890"), 1, 0, S("abe")); + test(S("abcde"), 2, 2, SV("1234567890"), 1, 1, S("ab2e")); + test(S("abcde"), 2, 2, SV("1234567890"), 1, 4, S("ab2345e")); + test(S("abcde"), 2, 2, SV("1234567890"), 1, 8, S("ab23456789e")); + test(S("abcde"), 2, 2, SV("1234567890"), 1, 9, S("ab234567890e")); + test(S("abcde"), 2, 2, SV("1234567890"), 1, 10, S("ab234567890e")); + test(S("abcde"), 2, 2, SV("1234567890"), 5, 0, S("abe")); + test(S("abcde"), 2, 2, SV("1234567890"), 5, 1, S("ab6e")); + test(S("abcde"), 2, 2, SV("1234567890"), 5, 2, S("ab67e")); + test(S("abcde"), 2, 2, SV("1234567890"), 5, 4, S("ab6789e")); +} + +template +void test13() +{ + test(S("abcde"), 2, 2, SV("1234567890"), 5, 5, S("ab67890e")); + test(S("abcde"), 2, 2, SV("1234567890"), 5, 6, S("ab67890e")); + test(S("abcde"), 2, 2, SV("1234567890"), 9, 0, S("abe")); + test(S("abcde"), 2, 2, SV("1234567890"), 9, 1, S("ab0e")); + test(S("abcde"), 2, 2, SV("1234567890"), 9, 2, S("ab0e")); + test(S("abcde"), 2, 2, SV("1234567890"), 10, 0, S("abe")); + test(S("abcde"), 2, 2, SV("1234567890"), 10, 1, S("abe")); + test(S("abcde"), 2, 2, SV("1234567890"), 11, 0, S("can't happen")); + test(S("abcde"), 2, 2, SV("12345678901234567890"), 0, 0, S("abe")); + test(S("abcde"), 2, 2, SV("12345678901234567890"), 0, 1, S("ab1e")); + test(S("abcde"), 2, 2, SV("12345678901234567890"), 0, 10, S("ab1234567890e")); + test(S("abcde"), 2, 2, SV("12345678901234567890"), 0, 19, S("ab1234567890123456789e")); + test(S("abcde"), 2, 2, SV("12345678901234567890"), 0, 20, S("ab12345678901234567890e")); + test(S("abcde"), 2, 2, SV("12345678901234567890"), 0, 21, S("ab12345678901234567890e")); + test(S("abcde"), 2, 2, SV("12345678901234567890"), 1, 0, S("abe")); + test(S("abcde"), 2, 2, SV("12345678901234567890"), 1, 1, S("ab2e")); + test(S("abcde"), 2, 2, SV("12345678901234567890"), 1, 9, S("ab234567890e")); + test(S("abcde"), 2, 2, SV("12345678901234567890"), 1, 18, S("ab234567890123456789e")); + test(S("abcde"), 2, 2, SV("12345678901234567890"), 1, 19, S("ab2345678901234567890e")); + test(S("abcde"), 2, 2, SV("12345678901234567890"), 1, 20, S("ab2345678901234567890e")); + test(S("abcde"), 2, 2, SV("12345678901234567890"), 10, 0, S("abe")); + test(S("abcde"), 2, 2, SV("12345678901234567890"), 10, 1, S("ab1e")); + test(S("abcde"), 2, 2, SV("12345678901234567890"), 10, 5, S("ab12345e")); + test(S("abcde"), 2, 2, SV("12345678901234567890"), 10, 9, S("ab123456789e")); + test(S("abcde"), 2, 2, SV("12345678901234567890"), 10, 10, S("ab1234567890e")); + test(S("abcde"), 2, 2, SV("12345678901234567890"), 10, 11, S("ab1234567890e")); + test(S("abcde"), 2, 2, SV("12345678901234567890"), 19, 0, S("abe")); + test(S("abcde"), 2, 2, SV("12345678901234567890"), 19, 1, S("ab0e")); + test(S("abcde"), 2, 2, SV("12345678901234567890"), 19, 2, S("ab0e")); + test(S("abcde"), 2, 2, SV("12345678901234567890"), 20, 0, S("abe")); + test(S("abcde"), 2, 2, SV("12345678901234567890"), 20, 1, S("abe")); + test(S("abcde"), 2, 2, SV("12345678901234567890"), 21, 0, S("can't happen")); + test(S("abcde"), 2, 3, SV(""), 0, 0, S("ab")); + test(S("abcde"), 2, 3, SV(""), 0, 1, S("ab")); + test(S("abcde"), 2, 3, SV(""), 1, 0, S("can't happen")); + test(S("abcde"), 2, 3, SV("12345"), 0, 0, S("ab")); + test(S("abcde"), 2, 3, SV("12345"), 0, 1, S("ab1")); + test(S("abcde"), 2, 3, SV("12345"), 0, 2, S("ab12")); + test(S("abcde"), 2, 3, SV("12345"), 0, 4, S("ab1234")); + test(S("abcde"), 2, 3, SV("12345"), 0, 5, S("ab12345")); + test(S("abcde"), 2, 3, SV("12345"), 0, 6, S("ab12345")); + test(S("abcde"), 2, 3, SV("12345"), 1, 0, S("ab")); + test(S("abcde"), 2, 3, SV("12345"), 1, 1, S("ab2")); + test(S("abcde"), 2, 3, SV("12345"), 1, 2, S("ab23")); + test(S("abcde"), 2, 3, SV("12345"), 1, 3, S("ab234")); + test(S("abcde"), 2, 3, SV("12345"), 1, 4, S("ab2345")); + test(S("abcde"), 2, 3, SV("12345"), 1, 5, S("ab2345")); + test(S("abcde"), 2, 3, SV("12345"), 2, 0, S("ab")); + test(S("abcde"), 2, 3, SV("12345"), 2, 1, S("ab3")); + test(S("abcde"), 2, 3, SV("12345"), 2, 2, S("ab34")); + test(S("abcde"), 2, 3, SV("12345"), 2, 3, S("ab345")); + test(S("abcde"), 2, 3, SV("12345"), 2, 4, S("ab345")); + test(S("abcde"), 2, 3, SV("12345"), 4, 0, S("ab")); + test(S("abcde"), 2, 3, SV("12345"), 4, 1, S("ab5")); + test(S("abcde"), 2, 3, SV("12345"), 4, 2, S("ab5")); + test(S("abcde"), 2, 3, SV("12345"), 5, 0, S("ab")); + test(S("abcde"), 2, 3, SV("12345"), 5, 1, S("ab")); + test(S("abcde"), 2, 3, SV("12345"), 6, 0, S("can't happen")); + test(S("abcde"), 2, 3, SV("1234567890"), 0, 0, S("ab")); + test(S("abcde"), 2, 3, SV("1234567890"), 0, 1, S("ab1")); + test(S("abcde"), 2, 3, SV("1234567890"), 0, 5, S("ab12345")); + test(S("abcde"), 2, 3, SV("1234567890"), 0, 9, S("ab123456789")); + test(S("abcde"), 2, 3, SV("1234567890"), 0, 10, S("ab1234567890")); + test(S("abcde"), 2, 3, SV("1234567890"), 0, 11, S("ab1234567890")); + test(S("abcde"), 2, 3, SV("1234567890"), 1, 0, S("ab")); + test(S("abcde"), 2, 3, SV("1234567890"), 1, 1, S("ab2")); + test(S("abcde"), 2, 3, SV("1234567890"), 1, 4, S("ab2345")); + test(S("abcde"), 2, 3, SV("1234567890"), 1, 8, S("ab23456789")); + test(S("abcde"), 2, 3, SV("1234567890"), 1, 9, S("ab234567890")); + test(S("abcde"), 2, 3, SV("1234567890"), 1, 10, S("ab234567890")); + test(S("abcde"), 2, 3, SV("1234567890"), 5, 0, S("ab")); + test(S("abcde"), 2, 3, SV("1234567890"), 5, 1, S("ab6")); + test(S("abcde"), 2, 3, SV("1234567890"), 5, 2, S("ab67")); + test(S("abcde"), 2, 3, SV("1234567890"), 5, 4, S("ab6789")); + test(S("abcde"), 2, 3, SV("1234567890"), 5, 5, S("ab67890")); + test(S("abcde"), 2, 3, SV("1234567890"), 5, 6, S("ab67890")); + test(S("abcde"), 2, 3, SV("1234567890"), 9, 0, S("ab")); + test(S("abcde"), 2, 3, SV("1234567890"), 9, 1, S("ab0")); + test(S("abcde"), 2, 3, SV("1234567890"), 9, 2, S("ab0")); + test(S("abcde"), 2, 3, SV("1234567890"), 10, 0, S("ab")); + test(S("abcde"), 2, 3, SV("1234567890"), 10, 1, S("ab")); + test(S("abcde"), 2, 3, SV("1234567890"), 11, 0, S("can't happen")); + test(S("abcde"), 2, 3, SV("12345678901234567890"), 0, 0, S("ab")); + test(S("abcde"), 2, 3, SV("12345678901234567890"), 0, 1, S("ab1")); + test(S("abcde"), 2, 3, SV("12345678901234567890"), 0, 10, S("ab1234567890")); + test(S("abcde"), 2, 3, SV("12345678901234567890"), 0, 19, S("ab1234567890123456789")); + test(S("abcde"), 2, 3, SV("12345678901234567890"), 0, 20, S("ab12345678901234567890")); + test(S("abcde"), 2, 3, SV("12345678901234567890"), 0, 21, S("ab12345678901234567890")); + test(S("abcde"), 2, 3, SV("12345678901234567890"), 1, 0, S("ab")); + test(S("abcde"), 2, 3, SV("12345678901234567890"), 1, 1, S("ab2")); + test(S("abcde"), 2, 3, SV("12345678901234567890"), 1, 9, S("ab234567890")); + test(S("abcde"), 2, 3, SV("12345678901234567890"), 1, 18, S("ab234567890123456789")); + test(S("abcde"), 2, 3, SV("12345678901234567890"), 1, 19, S("ab2345678901234567890")); + test(S("abcde"), 2, 3, SV("12345678901234567890"), 1, 20, S("ab2345678901234567890")); + test(S("abcde"), 2, 3, SV("12345678901234567890"), 10, 0, S("ab")); + test(S("abcde"), 2, 3, SV("12345678901234567890"), 10, 1, S("ab1")); + test(S("abcde"), 2, 3, SV("12345678901234567890"), 10, 5, S("ab12345")); + test(S("abcde"), 2, 3, SV("12345678901234567890"), 10, 9, S("ab123456789")); + test(S("abcde"), 2, 3, SV("12345678901234567890"), 10, 10, S("ab1234567890")); + test(S("abcde"), 2, 3, SV("12345678901234567890"), 10, 11, S("ab1234567890")); +} + +template +void test14() +{ + test(S("abcde"), 2, 3, SV("12345678901234567890"), 19, 0, S("ab")); + test(S("abcde"), 2, 3, SV("12345678901234567890"), 19, 1, S("ab0")); + test(S("abcde"), 2, 3, SV("12345678901234567890"), 19, 2, S("ab0")); + test(S("abcde"), 2, 3, SV("12345678901234567890"), 20, 0, S("ab")); + test(S("abcde"), 2, 3, SV("12345678901234567890"), 20, 1, S("ab")); + test(S("abcde"), 2, 3, SV("12345678901234567890"), 21, 0, S("can't happen")); + test(S("abcde"), 2, 4, SV(""), 0, 0, S("ab")); + test(S("abcde"), 2, 4, SV(""), 0, 1, S("ab")); + test(S("abcde"), 2, 4, SV(""), 1, 0, S("can't happen")); + test(S("abcde"), 2, 4, SV("12345"), 0, 0, S("ab")); + test(S("abcde"), 2, 4, SV("12345"), 0, 1, S("ab1")); + test(S("abcde"), 2, 4, SV("12345"), 0, 2, S("ab12")); + test(S("abcde"), 2, 4, SV("12345"), 0, 4, S("ab1234")); + test(S("abcde"), 2, 4, SV("12345"), 0, 5, S("ab12345")); + test(S("abcde"), 2, 4, SV("12345"), 0, 6, S("ab12345")); + test(S("abcde"), 2, 4, SV("12345"), 1, 0, S("ab")); + test(S("abcde"), 2, 4, SV("12345"), 1, 1, S("ab2")); + test(S("abcde"), 2, 4, SV("12345"), 1, 2, S("ab23")); + test(S("abcde"), 2, 4, SV("12345"), 1, 3, S("ab234")); + test(S("abcde"), 2, 4, SV("12345"), 1, 4, S("ab2345")); + test(S("abcde"), 2, 4, SV("12345"), 1, 5, S("ab2345")); + test(S("abcde"), 2, 4, SV("12345"), 2, 0, S("ab")); + test(S("abcde"), 2, 4, SV("12345"), 2, 1, S("ab3")); + test(S("abcde"), 2, 4, SV("12345"), 2, 2, S("ab34")); + test(S("abcde"), 2, 4, SV("12345"), 2, 3, S("ab345")); + test(S("abcde"), 2, 4, SV("12345"), 2, 4, S("ab345")); + test(S("abcde"), 2, 4, SV("12345"), 4, 0, S("ab")); + test(S("abcde"), 2, 4, SV("12345"), 4, 1, S("ab5")); + test(S("abcde"), 2, 4, SV("12345"), 4, 2, S("ab5")); + test(S("abcde"), 2, 4, SV("12345"), 5, 0, S("ab")); + test(S("abcde"), 2, 4, SV("12345"), 5, 1, S("ab")); + test(S("abcde"), 2, 4, SV("12345"), 6, 0, S("can't happen")); + test(S("abcde"), 2, 4, SV("1234567890"), 0, 0, S("ab")); + test(S("abcde"), 2, 4, SV("1234567890"), 0, 1, S("ab1")); + test(S("abcde"), 2, 4, SV("1234567890"), 0, 5, S("ab12345")); + test(S("abcde"), 2, 4, SV("1234567890"), 0, 9, S("ab123456789")); + test(S("abcde"), 2, 4, SV("1234567890"), 0, 10, S("ab1234567890")); + test(S("abcde"), 2, 4, SV("1234567890"), 0, 11, S("ab1234567890")); + test(S("abcde"), 2, 4, SV("1234567890"), 1, 0, S("ab")); + test(S("abcde"), 2, 4, SV("1234567890"), 1, 1, S("ab2")); + test(S("abcde"), 2, 4, SV("1234567890"), 1, 4, S("ab2345")); + test(S("abcde"), 2, 4, SV("1234567890"), 1, 8, S("ab23456789")); + test(S("abcde"), 2, 4, SV("1234567890"), 1, 9, S("ab234567890")); + test(S("abcde"), 2, 4, SV("1234567890"), 1, 10, S("ab234567890")); + test(S("abcde"), 2, 4, SV("1234567890"), 5, 0, S("ab")); + test(S("abcde"), 2, 4, SV("1234567890"), 5, 1, S("ab6")); + test(S("abcde"), 2, 4, SV("1234567890"), 5, 2, S("ab67")); + test(S("abcde"), 2, 4, SV("1234567890"), 5, 4, S("ab6789")); + test(S("abcde"), 2, 4, SV("1234567890"), 5, 5, S("ab67890")); + test(S("abcde"), 2, 4, SV("1234567890"), 5, 6, S("ab67890")); + test(S("abcde"), 2, 4, SV("1234567890"), 9, 0, S("ab")); + test(S("abcde"), 2, 4, SV("1234567890"), 9, 1, S("ab0")); + test(S("abcde"), 2, 4, SV("1234567890"), 9, 2, S("ab0")); + test(S("abcde"), 2, 4, SV("1234567890"), 10, 0, S("ab")); + test(S("abcde"), 2, 4, SV("1234567890"), 10, 1, S("ab")); + test(S("abcde"), 2, 4, SV("1234567890"), 11, 0, S("can't happen")); + test(S("abcde"), 2, 4, SV("12345678901234567890"), 0, 0, S("ab")); + test(S("abcde"), 2, 4, SV("12345678901234567890"), 0, 1, S("ab1")); + test(S("abcde"), 2, 4, SV("12345678901234567890"), 0, 10, S("ab1234567890")); + test(S("abcde"), 2, 4, SV("12345678901234567890"), 0, 19, S("ab1234567890123456789")); + test(S("abcde"), 2, 4, SV("12345678901234567890"), 0, 20, S("ab12345678901234567890")); + test(S("abcde"), 2, 4, SV("12345678901234567890"), 0, 21, S("ab12345678901234567890")); + test(S("abcde"), 2, 4, SV("12345678901234567890"), 1, 0, S("ab")); + test(S("abcde"), 2, 4, SV("12345678901234567890"), 1, 1, S("ab2")); + test(S("abcde"), 2, 4, SV("12345678901234567890"), 1, 9, S("ab234567890")); + test(S("abcde"), 2, 4, SV("12345678901234567890"), 1, 18, S("ab234567890123456789")); + test(S("abcde"), 2, 4, SV("12345678901234567890"), 1, 19, S("ab2345678901234567890")); + test(S("abcde"), 2, 4, SV("12345678901234567890"), 1, 20, S("ab2345678901234567890")); + test(S("abcde"), 2, 4, SV("12345678901234567890"), 10, 0, S("ab")); + test(S("abcde"), 2, 4, SV("12345678901234567890"), 10, 1, S("ab1")); + test(S("abcde"), 2, 4, SV("12345678901234567890"), 10, 5, S("ab12345")); + test(S("abcde"), 2, 4, SV("12345678901234567890"), 10, 9, S("ab123456789")); + test(S("abcde"), 2, 4, SV("12345678901234567890"), 10, 10, S("ab1234567890")); + test(S("abcde"), 2, 4, SV("12345678901234567890"), 10, 11, S("ab1234567890")); + test(S("abcde"), 2, 4, SV("12345678901234567890"), 19, 0, S("ab")); + test(S("abcde"), 2, 4, SV("12345678901234567890"), 19, 1, S("ab0")); + test(S("abcde"), 2, 4, SV("12345678901234567890"), 19, 2, S("ab0")); + test(S("abcde"), 2, 4, SV("12345678901234567890"), 20, 0, S("ab")); + test(S("abcde"), 2, 4, SV("12345678901234567890"), 20, 1, S("ab")); + test(S("abcde"), 2, 4, SV("12345678901234567890"), 21, 0, S("can't happen")); + test(S("abcde"), 4, 0, SV(""), 0, 0, S("abcde")); + test(S("abcde"), 4, 0, SV(""), 0, 1, S("abcde")); + test(S("abcde"), 4, 0, SV(""), 1, 0, S("can't happen")); + test(S("abcde"), 4, 0, SV("12345"), 0, 0, S("abcde")); + test(S("abcde"), 4, 0, SV("12345"), 0, 1, S("abcd1e")); + test(S("abcde"), 4, 0, SV("12345"), 0, 2, S("abcd12e")); + test(S("abcde"), 4, 0, SV("12345"), 0, 4, S("abcd1234e")); + test(S("abcde"), 4, 0, SV("12345"), 0, 5, S("abcd12345e")); + test(S("abcde"), 4, 0, SV("12345"), 0, 6, S("abcd12345e")); + test(S("abcde"), 4, 0, SV("12345"), 1, 0, S("abcde")); + test(S("abcde"), 4, 0, SV("12345"), 1, 1, S("abcd2e")); + test(S("abcde"), 4, 0, SV("12345"), 1, 2, S("abcd23e")); + test(S("abcde"), 4, 0, SV("12345"), 1, 3, S("abcd234e")); + test(S("abcde"), 4, 0, SV("12345"), 1, 4, S("abcd2345e")); + test(S("abcde"), 4, 0, SV("12345"), 1, 5, S("abcd2345e")); + test(S("abcde"), 4, 0, SV("12345"), 2, 0, S("abcde")); + test(S("abcde"), 4, 0, SV("12345"), 2, 1, S("abcd3e")); + test(S("abcde"), 4, 0, SV("12345"), 2, 2, S("abcd34e")); + test(S("abcde"), 4, 0, SV("12345"), 2, 3, S("abcd345e")); + test(S("abcde"), 4, 0, SV("12345"), 2, 4, S("abcd345e")); +} + +template +void test15() +{ + test(S("abcde"), 4, 0, SV("12345"), 4, 0, S("abcde")); + test(S("abcde"), 4, 0, SV("12345"), 4, 1, S("abcd5e")); + test(S("abcde"), 4, 0, SV("12345"), 4, 2, S("abcd5e")); + test(S("abcde"), 4, 0, SV("12345"), 5, 0, S("abcde")); + test(S("abcde"), 4, 0, SV("12345"), 5, 1, S("abcde")); + test(S("abcde"), 4, 0, SV("12345"), 6, 0, S("can't happen")); + test(S("abcde"), 4, 0, SV("1234567890"), 0, 0, S("abcde")); + test(S("abcde"), 4, 0, SV("1234567890"), 0, 1, S("abcd1e")); + test(S("abcde"), 4, 0, SV("1234567890"), 0, 5, S("abcd12345e")); + test(S("abcde"), 4, 0, SV("1234567890"), 0, 9, S("abcd123456789e")); + test(S("abcde"), 4, 0, SV("1234567890"), 0, 10, S("abcd1234567890e")); + test(S("abcde"), 4, 0, SV("1234567890"), 0, 11, S("abcd1234567890e")); + test(S("abcde"), 4, 0, SV("1234567890"), 1, 0, S("abcde")); + test(S("abcde"), 4, 0, SV("1234567890"), 1, 1, S("abcd2e")); + test(S("abcde"), 4, 0, SV("1234567890"), 1, 4, S("abcd2345e")); + test(S("abcde"), 4, 0, SV("1234567890"), 1, 8, S("abcd23456789e")); + test(S("abcde"), 4, 0, SV("1234567890"), 1, 9, S("abcd234567890e")); + test(S("abcde"), 4, 0, SV("1234567890"), 1, 10, S("abcd234567890e")); + test(S("abcde"), 4, 0, SV("1234567890"), 5, 0, S("abcde")); + test(S("abcde"), 4, 0, SV("1234567890"), 5, 1, S("abcd6e")); + test(S("abcde"), 4, 0, SV("1234567890"), 5, 2, S("abcd67e")); + test(S("abcde"), 4, 0, SV("1234567890"), 5, 4, S("abcd6789e")); + test(S("abcde"), 4, 0, SV("1234567890"), 5, 5, S("abcd67890e")); + test(S("abcde"), 4, 0, SV("1234567890"), 5, 6, S("abcd67890e")); + test(S("abcde"), 4, 0, SV("1234567890"), 9, 0, S("abcde")); + test(S("abcde"), 4, 0, SV("1234567890"), 9, 1, S("abcd0e")); + test(S("abcde"), 4, 0, SV("1234567890"), 9, 2, S("abcd0e")); + test(S("abcde"), 4, 0, SV("1234567890"), 10, 0, S("abcde")); + test(S("abcde"), 4, 0, SV("1234567890"), 10, 1, S("abcde")); + test(S("abcde"), 4, 0, SV("1234567890"), 11, 0, S("can't happen")); + test(S("abcde"), 4, 0, SV("12345678901234567890"), 0, 0, S("abcde")); + test(S("abcde"), 4, 0, SV("12345678901234567890"), 0, 1, S("abcd1e")); + test(S("abcde"), 4, 0, SV("12345678901234567890"), 0, 10, S("abcd1234567890e")); + test(S("abcde"), 4, 0, SV("12345678901234567890"), 0, 19, S("abcd1234567890123456789e")); + test(S("abcde"), 4, 0, SV("12345678901234567890"), 0, 20, S("abcd12345678901234567890e")); + test(S("abcde"), 4, 0, SV("12345678901234567890"), 0, 21, S("abcd12345678901234567890e")); + test(S("abcde"), 4, 0, SV("12345678901234567890"), 1, 0, S("abcde")); + test(S("abcde"), 4, 0, SV("12345678901234567890"), 1, 1, S("abcd2e")); + test(S("abcde"), 4, 0, SV("12345678901234567890"), 1, 9, S("abcd234567890e")); + test(S("abcde"), 4, 0, SV("12345678901234567890"), 1, 18, S("abcd234567890123456789e")); + test(S("abcde"), 4, 0, SV("12345678901234567890"), 1, 19, S("abcd2345678901234567890e")); + test(S("abcde"), 4, 0, SV("12345678901234567890"), 1, 20, S("abcd2345678901234567890e")); + test(S("abcde"), 4, 0, SV("12345678901234567890"), 10, 0, S("abcde")); + test(S("abcde"), 4, 0, SV("12345678901234567890"), 10, 1, S("abcd1e")); + test(S("abcde"), 4, 0, SV("12345678901234567890"), 10, 5, S("abcd12345e")); + test(S("abcde"), 4, 0, SV("12345678901234567890"), 10, 9, S("abcd123456789e")); + test(S("abcde"), 4, 0, SV("12345678901234567890"), 10, 10, S("abcd1234567890e")); + test(S("abcde"), 4, 0, SV("12345678901234567890"), 10, 11, S("abcd1234567890e")); + test(S("abcde"), 4, 0, SV("12345678901234567890"), 19, 0, S("abcde")); + test(S("abcde"), 4, 0, SV("12345678901234567890"), 19, 1, S("abcd0e")); + test(S("abcde"), 4, 0, SV("12345678901234567890"), 19, 2, S("abcd0e")); + test(S("abcde"), 4, 0, SV("12345678901234567890"), 20, 0, S("abcde")); + test(S("abcde"), 4, 0, SV("12345678901234567890"), 20, 1, S("abcde")); + test(S("abcde"), 4, 0, SV("12345678901234567890"), 21, 0, S("can't happen")); + test(S("abcde"), 4, 1, SV(""), 0, 0, S("abcd")); + test(S("abcde"), 4, 1, SV(""), 0, 1, S("abcd")); + test(S("abcde"), 4, 1, SV(""), 1, 0, S("can't happen")); + test(S("abcde"), 4, 1, SV("12345"), 0, 0, S("abcd")); + test(S("abcde"), 4, 1, SV("12345"), 0, 1, S("abcd1")); + test(S("abcde"), 4, 1, SV("12345"), 0, 2, S("abcd12")); + test(S("abcde"), 4, 1, SV("12345"), 0, 4, S("abcd1234")); + test(S("abcde"), 4, 1, SV("12345"), 0, 5, S("abcd12345")); + test(S("abcde"), 4, 1, SV("12345"), 0, 6, S("abcd12345")); + test(S("abcde"), 4, 1, SV("12345"), 1, 0, S("abcd")); + test(S("abcde"), 4, 1, SV("12345"), 1, 1, S("abcd2")); + test(S("abcde"), 4, 1, SV("12345"), 1, 2, S("abcd23")); + test(S("abcde"), 4, 1, SV("12345"), 1, 3, S("abcd234")); + test(S("abcde"), 4, 1, SV("12345"), 1, 4, S("abcd2345")); + test(S("abcde"), 4, 1, SV("12345"), 1, 5, S("abcd2345")); + test(S("abcde"), 4, 1, SV("12345"), 2, 0, S("abcd")); + test(S("abcde"), 4, 1, SV("12345"), 2, 1, S("abcd3")); + test(S("abcde"), 4, 1, SV("12345"), 2, 2, S("abcd34")); + test(S("abcde"), 4, 1, SV("12345"), 2, 3, S("abcd345")); + test(S("abcde"), 4, 1, SV("12345"), 2, 4, S("abcd345")); + test(S("abcde"), 4, 1, SV("12345"), 4, 0, S("abcd")); + test(S("abcde"), 4, 1, SV("12345"), 4, 1, S("abcd5")); + test(S("abcde"), 4, 1, SV("12345"), 4, 2, S("abcd5")); + test(S("abcde"), 4, 1, SV("12345"), 5, 0, S("abcd")); + test(S("abcde"), 4, 1, SV("12345"), 5, 1, S("abcd")); + test(S("abcde"), 4, 1, SV("12345"), 6, 0, S("can't happen")); + test(S("abcde"), 4, 1, SV("1234567890"), 0, 0, S("abcd")); + test(S("abcde"), 4, 1, SV("1234567890"), 0, 1, S("abcd1")); + test(S("abcde"), 4, 1, SV("1234567890"), 0, 5, S("abcd12345")); + test(S("abcde"), 4, 1, SV("1234567890"), 0, 9, S("abcd123456789")); + test(S("abcde"), 4, 1, SV("1234567890"), 0, 10, S("abcd1234567890")); + test(S("abcde"), 4, 1, SV("1234567890"), 0, 11, S("abcd1234567890")); + test(S("abcde"), 4, 1, SV("1234567890"), 1, 0, S("abcd")); + test(S("abcde"), 4, 1, SV("1234567890"), 1, 1, S("abcd2")); + test(S("abcde"), 4, 1, SV("1234567890"), 1, 4, S("abcd2345")); + test(S("abcde"), 4, 1, SV("1234567890"), 1, 8, S("abcd23456789")); + test(S("abcde"), 4, 1, SV("1234567890"), 1, 9, S("abcd234567890")); + test(S("abcde"), 4, 1, SV("1234567890"), 1, 10, S("abcd234567890")); + test(S("abcde"), 4, 1, SV("1234567890"), 5, 0, S("abcd")); + test(S("abcde"), 4, 1, SV("1234567890"), 5, 1, S("abcd6")); + test(S("abcde"), 4, 1, SV("1234567890"), 5, 2, S("abcd67")); + test(S("abcde"), 4, 1, SV("1234567890"), 5, 4, S("abcd6789")); + test(S("abcde"), 4, 1, SV("1234567890"), 5, 5, S("abcd67890")); + test(S("abcde"), 4, 1, SV("1234567890"), 5, 6, S("abcd67890")); + test(S("abcde"), 4, 1, SV("1234567890"), 9, 0, S("abcd")); + test(S("abcde"), 4, 1, SV("1234567890"), 9, 1, S("abcd0")); +} + +template +void test16() +{ + test(S("abcde"), 4, 1, SV("1234567890"), 9, 2, S("abcd0")); + test(S("abcde"), 4, 1, SV("1234567890"), 10, 0, S("abcd")); + test(S("abcde"), 4, 1, SV("1234567890"), 10, 1, S("abcd")); + test(S("abcde"), 4, 1, SV("1234567890"), 11, 0, S("can't happen")); + test(S("abcde"), 4, 1, SV("12345678901234567890"), 0, 0, S("abcd")); + test(S("abcde"), 4, 1, SV("12345678901234567890"), 0, 1, S("abcd1")); + test(S("abcde"), 4, 1, SV("12345678901234567890"), 0, 10, S("abcd1234567890")); + test(S("abcde"), 4, 1, SV("12345678901234567890"), 0, 19, S("abcd1234567890123456789")); + test(S("abcde"), 4, 1, SV("12345678901234567890"), 0, 20, S("abcd12345678901234567890")); + test(S("abcde"), 4, 1, SV("12345678901234567890"), 0, 21, S("abcd12345678901234567890")); + test(S("abcde"), 4, 1, SV("12345678901234567890"), 1, 0, S("abcd")); + test(S("abcde"), 4, 1, SV("12345678901234567890"), 1, 1, S("abcd2")); + test(S("abcde"), 4, 1, SV("12345678901234567890"), 1, 9, S("abcd234567890")); + test(S("abcde"), 4, 1, SV("12345678901234567890"), 1, 18, S("abcd234567890123456789")); + test(S("abcde"), 4, 1, SV("12345678901234567890"), 1, 19, S("abcd2345678901234567890")); + test(S("abcde"), 4, 1, SV("12345678901234567890"), 1, 20, S("abcd2345678901234567890")); + test(S("abcde"), 4, 1, SV("12345678901234567890"), 10, 0, S("abcd")); + test(S("abcde"), 4, 1, SV("12345678901234567890"), 10, 1, S("abcd1")); + test(S("abcde"), 4, 1, SV("12345678901234567890"), 10, 5, S("abcd12345")); + test(S("abcde"), 4, 1, SV("12345678901234567890"), 10, 9, S("abcd123456789")); + test(S("abcde"), 4, 1, SV("12345678901234567890"), 10, 10, S("abcd1234567890")); + test(S("abcde"), 4, 1, SV("12345678901234567890"), 10, 11, S("abcd1234567890")); + test(S("abcde"), 4, 1, SV("12345678901234567890"), 19, 0, S("abcd")); + test(S("abcde"), 4, 1, SV("12345678901234567890"), 19, 1, S("abcd0")); + test(S("abcde"), 4, 1, SV("12345678901234567890"), 19, 2, S("abcd0")); + test(S("abcde"), 4, 1, SV("12345678901234567890"), 20, 0, S("abcd")); + test(S("abcde"), 4, 1, SV("12345678901234567890"), 20, 1, S("abcd")); + test(S("abcde"), 4, 1, SV("12345678901234567890"), 21, 0, S("can't happen")); + test(S("abcde"), 4, 2, SV(""), 0, 0, S("abcd")); + test(S("abcde"), 4, 2, SV(""), 0, 1, S("abcd")); + test(S("abcde"), 4, 2, SV(""), 1, 0, S("can't happen")); + test(S("abcde"), 4, 2, SV("12345"), 0, 0, S("abcd")); + test(S("abcde"), 4, 2, SV("12345"), 0, 1, S("abcd1")); + test(S("abcde"), 4, 2, SV("12345"), 0, 2, S("abcd12")); + test(S("abcde"), 4, 2, SV("12345"), 0, 4, S("abcd1234")); + test(S("abcde"), 4, 2, SV("12345"), 0, 5, S("abcd12345")); + test(S("abcde"), 4, 2, SV("12345"), 0, 6, S("abcd12345")); + test(S("abcde"), 4, 2, SV("12345"), 1, 0, S("abcd")); + test(S("abcde"), 4, 2, SV("12345"), 1, 1, S("abcd2")); + test(S("abcde"), 4, 2, SV("12345"), 1, 2, S("abcd23")); + test(S("abcde"), 4, 2, SV("12345"), 1, 3, S("abcd234")); + test(S("abcde"), 4, 2, SV("12345"), 1, 4, S("abcd2345")); + test(S("abcde"), 4, 2, SV("12345"), 1, 5, S("abcd2345")); + test(S("abcde"), 4, 2, SV("12345"), 2, 0, S("abcd")); + test(S("abcde"), 4, 2, SV("12345"), 2, 1, S("abcd3")); + test(S("abcde"), 4, 2, SV("12345"), 2, 2, S("abcd34")); + test(S("abcde"), 4, 2, SV("12345"), 2, 3, S("abcd345")); + test(S("abcde"), 4, 2, SV("12345"), 2, 4, S("abcd345")); + test(S("abcde"), 4, 2, SV("12345"), 4, 0, S("abcd")); + test(S("abcde"), 4, 2, SV("12345"), 4, 1, S("abcd5")); + test(S("abcde"), 4, 2, SV("12345"), 4, 2, S("abcd5")); + test(S("abcde"), 4, 2, SV("12345"), 5, 0, S("abcd")); + test(S("abcde"), 4, 2, SV("12345"), 5, 1, S("abcd")); + test(S("abcde"), 4, 2, SV("12345"), 6, 0, S("can't happen")); + test(S("abcde"), 4, 2, SV("1234567890"), 0, 0, S("abcd")); + test(S("abcde"), 4, 2, SV("1234567890"), 0, 1, S("abcd1")); + test(S("abcde"), 4, 2, SV("1234567890"), 0, 5, S("abcd12345")); + test(S("abcde"), 4, 2, SV("1234567890"), 0, 9, S("abcd123456789")); + test(S("abcde"), 4, 2, SV("1234567890"), 0, 10, S("abcd1234567890")); + test(S("abcde"), 4, 2, SV("1234567890"), 0, 11, S("abcd1234567890")); + test(S("abcde"), 4, 2, SV("1234567890"), 1, 0, S("abcd")); + test(S("abcde"), 4, 2, SV("1234567890"), 1, 1, S("abcd2")); + test(S("abcde"), 4, 2, SV("1234567890"), 1, 4, S("abcd2345")); + test(S("abcde"), 4, 2, SV("1234567890"), 1, 8, S("abcd23456789")); + test(S("abcde"), 4, 2, SV("1234567890"), 1, 9, S("abcd234567890")); + test(S("abcde"), 4, 2, SV("1234567890"), 1, 10, S("abcd234567890")); + test(S("abcde"), 4, 2, SV("1234567890"), 5, 0, S("abcd")); + test(S("abcde"), 4, 2, SV("1234567890"), 5, 1, S("abcd6")); + test(S("abcde"), 4, 2, SV("1234567890"), 5, 2, S("abcd67")); + test(S("abcde"), 4, 2, SV("1234567890"), 5, 4, S("abcd6789")); + test(S("abcde"), 4, 2, SV("1234567890"), 5, 5, S("abcd67890")); + test(S("abcde"), 4, 2, SV("1234567890"), 5, 6, S("abcd67890")); + test(S("abcde"), 4, 2, SV("1234567890"), 9, 0, S("abcd")); + test(S("abcde"), 4, 2, SV("1234567890"), 9, 1, S("abcd0")); + test(S("abcde"), 4, 2, SV("1234567890"), 9, 2, S("abcd0")); + test(S("abcde"), 4, 2, SV("1234567890"), 10, 0, S("abcd")); + test(S("abcde"), 4, 2, SV("1234567890"), 10, 1, S("abcd")); + test(S("abcde"), 4, 2, SV("1234567890"), 11, 0, S("can't happen")); + test(S("abcde"), 4, 2, SV("12345678901234567890"), 0, 0, S("abcd")); + test(S("abcde"), 4, 2, SV("12345678901234567890"), 0, 1, S("abcd1")); + test(S("abcde"), 4, 2, SV("12345678901234567890"), 0, 10, S("abcd1234567890")); + test(S("abcde"), 4, 2, SV("12345678901234567890"), 0, 19, S("abcd1234567890123456789")); + test(S("abcde"), 4, 2, SV("12345678901234567890"), 0, 20, S("abcd12345678901234567890")); + test(S("abcde"), 4, 2, SV("12345678901234567890"), 0, 21, S("abcd12345678901234567890")); + test(S("abcde"), 4, 2, SV("12345678901234567890"), 1, 0, S("abcd")); + test(S("abcde"), 4, 2, SV("12345678901234567890"), 1, 1, S("abcd2")); + test(S("abcde"), 4, 2, SV("12345678901234567890"), 1, 9, S("abcd234567890")); + test(S("abcde"), 4, 2, SV("12345678901234567890"), 1, 18, S("abcd234567890123456789")); + test(S("abcde"), 4, 2, SV("12345678901234567890"), 1, 19, S("abcd2345678901234567890")); + test(S("abcde"), 4, 2, SV("12345678901234567890"), 1, 20, S("abcd2345678901234567890")); + test(S("abcde"), 4, 2, SV("12345678901234567890"), 10, 0, S("abcd")); + test(S("abcde"), 4, 2, SV("12345678901234567890"), 10, 1, S("abcd1")); + test(S("abcde"), 4, 2, SV("12345678901234567890"), 10, 5, S("abcd12345")); + test(S("abcde"), 4, 2, SV("12345678901234567890"), 10, 9, S("abcd123456789")); + test(S("abcde"), 4, 2, SV("12345678901234567890"), 10, 10, S("abcd1234567890")); + test(S("abcde"), 4, 2, SV("12345678901234567890"), 10, 11, S("abcd1234567890")); + test(S("abcde"), 4, 2, SV("12345678901234567890"), 19, 0, S("abcd")); + test(S("abcde"), 4, 2, SV("12345678901234567890"), 19, 1, S("abcd0")); + test(S("abcde"), 4, 2, SV("12345678901234567890"), 19, 2, S("abcd0")); + test(S("abcde"), 4, 2, SV("12345678901234567890"), 20, 0, S("abcd")); +} + +template +void test17() +{ + test(S("abcde"), 4, 2, SV("12345678901234567890"), 20, 1, S("abcd")); + test(S("abcde"), 4, 2, SV("12345678901234567890"), 21, 0, S("can't happen")); + test(S("abcde"), 5, 0, SV(""), 0, 0, S("abcde")); + test(S("abcde"), 5, 0, SV(""), 0, 1, S("abcde")); + test(S("abcde"), 5, 0, SV(""), 1, 0, S("can't happen")); + test(S("abcde"), 5, 0, SV("12345"), 0, 0, S("abcde")); + test(S("abcde"), 5, 0, SV("12345"), 0, 1, S("abcde1")); + test(S("abcde"), 5, 0, SV("12345"), 0, 2, S("abcde12")); + test(S("abcde"), 5, 0, SV("12345"), 0, 4, S("abcde1234")); + test(S("abcde"), 5, 0, SV("12345"), 0, 5, S("abcde12345")); + test(S("abcde"), 5, 0, SV("12345"), 0, 6, S("abcde12345")); + test(S("abcde"), 5, 0, SV("12345"), 1, 0, S("abcde")); + test(S("abcde"), 5, 0, SV("12345"), 1, 1, S("abcde2")); + test(S("abcde"), 5, 0, SV("12345"), 1, 2, S("abcde23")); + test(S("abcde"), 5, 0, SV("12345"), 1, 3, S("abcde234")); + test(S("abcde"), 5, 0, SV("12345"), 1, 4, S("abcde2345")); + test(S("abcde"), 5, 0, SV("12345"), 1, 5, S("abcde2345")); + test(S("abcde"), 5, 0, SV("12345"), 2, 0, S("abcde")); + test(S("abcde"), 5, 0, SV("12345"), 2, 1, S("abcde3")); + test(S("abcde"), 5, 0, SV("12345"), 2, 2, S("abcde34")); + test(S("abcde"), 5, 0, SV("12345"), 2, 3, S("abcde345")); + test(S("abcde"), 5, 0, SV("12345"), 2, 4, S("abcde345")); + test(S("abcde"), 5, 0, SV("12345"), 4, 0, S("abcde")); + test(S("abcde"), 5, 0, SV("12345"), 4, 1, S("abcde5")); + test(S("abcde"), 5, 0, SV("12345"), 4, 2, S("abcde5")); + test(S("abcde"), 5, 0, SV("12345"), 5, 0, S("abcde")); + test(S("abcde"), 5, 0, SV("12345"), 5, 1, S("abcde")); + test(S("abcde"), 5, 0, SV("12345"), 6, 0, S("can't happen")); + test(S("abcde"), 5, 0, SV("1234567890"), 0, 0, S("abcde")); + test(S("abcde"), 5, 0, SV("1234567890"), 0, 1, S("abcde1")); + test(S("abcde"), 5, 0, SV("1234567890"), 0, 5, S("abcde12345")); + test(S("abcde"), 5, 0, SV("1234567890"), 0, 9, S("abcde123456789")); + test(S("abcde"), 5, 0, SV("1234567890"), 0, 10, S("abcde1234567890")); + test(S("abcde"), 5, 0, SV("1234567890"), 0, 11, S("abcde1234567890")); + test(S("abcde"), 5, 0, SV("1234567890"), 1, 0, S("abcde")); + test(S("abcde"), 5, 0, SV("1234567890"), 1, 1, S("abcde2")); + test(S("abcde"), 5, 0, SV("1234567890"), 1, 4, S("abcde2345")); + test(S("abcde"), 5, 0, SV("1234567890"), 1, 8, S("abcde23456789")); + test(S("abcde"), 5, 0, SV("1234567890"), 1, 9, S("abcde234567890")); + test(S("abcde"), 5, 0, SV("1234567890"), 1, 10, S("abcde234567890")); + test(S("abcde"), 5, 0, SV("1234567890"), 5, 0, S("abcde")); + test(S("abcde"), 5, 0, SV("1234567890"), 5, 1, S("abcde6")); + test(S("abcde"), 5, 0, SV("1234567890"), 5, 2, S("abcde67")); + test(S("abcde"), 5, 0, SV("1234567890"), 5, 4, S("abcde6789")); + test(S("abcde"), 5, 0, SV("1234567890"), 5, 5, S("abcde67890")); + test(S("abcde"), 5, 0, SV("1234567890"), 5, 6, S("abcde67890")); + test(S("abcde"), 5, 0, SV("1234567890"), 9, 0, S("abcde")); + test(S("abcde"), 5, 0, SV("1234567890"), 9, 1, S("abcde0")); + test(S("abcde"), 5, 0, SV("1234567890"), 9, 2, S("abcde0")); + test(S("abcde"), 5, 0, SV("1234567890"), 10, 0, S("abcde")); + test(S("abcde"), 5, 0, SV("1234567890"), 10, 1, S("abcde")); + test(S("abcde"), 5, 0, SV("1234567890"), 11, 0, S("can't happen")); + test(S("abcde"), 5, 0, SV("12345678901234567890"), 0, 0, S("abcde")); + test(S("abcde"), 5, 0, SV("12345678901234567890"), 0, 1, S("abcde1")); + test(S("abcde"), 5, 0, SV("12345678901234567890"), 0, 10, S("abcde1234567890")); + test(S("abcde"), 5, 0, SV("12345678901234567890"), 0, 19, S("abcde1234567890123456789")); + test(S("abcde"), 5, 0, SV("12345678901234567890"), 0, 20, S("abcde12345678901234567890")); + test(S("abcde"), 5, 0, SV("12345678901234567890"), 0, 21, S("abcde12345678901234567890")); + test(S("abcde"), 5, 0, SV("12345678901234567890"), 1, 0, S("abcde")); + test(S("abcde"), 5, 0, SV("12345678901234567890"), 1, 1, S("abcde2")); + test(S("abcde"), 5, 0, SV("12345678901234567890"), 1, 9, S("abcde234567890")); + test(S("abcde"), 5, 0, SV("12345678901234567890"), 1, 18, S("abcde234567890123456789")); + test(S("abcde"), 5, 0, SV("12345678901234567890"), 1, 19, S("abcde2345678901234567890")); + test(S("abcde"), 5, 0, SV("12345678901234567890"), 1, 20, S("abcde2345678901234567890")); + test(S("abcde"), 5, 0, SV("12345678901234567890"), 10, 0, S("abcde")); + test(S("abcde"), 5, 0, SV("12345678901234567890"), 10, 1, S("abcde1")); + test(S("abcde"), 5, 0, SV("12345678901234567890"), 10, 5, S("abcde12345")); + test(S("abcde"), 5, 0, SV("12345678901234567890"), 10, 9, S("abcde123456789")); + test(S("abcde"), 5, 0, SV("12345678901234567890"), 10, 10, S("abcde1234567890")); + test(S("abcde"), 5, 0, SV("12345678901234567890"), 10, 11, S("abcde1234567890")); + test(S("abcde"), 5, 0, SV("12345678901234567890"), 19, 0, S("abcde")); + test(S("abcde"), 5, 0, SV("12345678901234567890"), 19, 1, S("abcde0")); + test(S("abcde"), 5, 0, SV("12345678901234567890"), 19, 2, S("abcde0")); + test(S("abcde"), 5, 0, SV("12345678901234567890"), 20, 0, S("abcde")); + test(S("abcde"), 5, 0, SV("12345678901234567890"), 20, 1, S("abcde")); + test(S("abcde"), 5, 0, SV("12345678901234567890"), 21, 0, S("can't happen")); + test(S("abcde"), 5, 1, SV(""), 0, 0, S("abcde")); + test(S("abcde"), 5, 1, SV(""), 0, 1, S("abcde")); + test(S("abcde"), 5, 1, SV(""), 1, 0, S("can't happen")); + test(S("abcde"), 5, 1, SV("12345"), 0, 0, S("abcde")); + test(S("abcde"), 5, 1, SV("12345"), 0, 1, S("abcde1")); + test(S("abcde"), 5, 1, SV("12345"), 0, 2, S("abcde12")); + test(S("abcde"), 5, 1, SV("12345"), 0, 4, S("abcde1234")); + test(S("abcde"), 5, 1, SV("12345"), 0, 5, S("abcde12345")); + test(S("abcde"), 5, 1, SV("12345"), 0, 6, S("abcde12345")); + test(S("abcde"), 5, 1, SV("12345"), 1, 0, S("abcde")); + test(S("abcde"), 5, 1, SV("12345"), 1, 1, S("abcde2")); + test(S("abcde"), 5, 1, SV("12345"), 1, 2, S("abcde23")); + test(S("abcde"), 5, 1, SV("12345"), 1, 3, S("abcde234")); + test(S("abcde"), 5, 1, SV("12345"), 1, 4, S("abcde2345")); + test(S("abcde"), 5, 1, SV("12345"), 1, 5, S("abcde2345")); + test(S("abcde"), 5, 1, SV("12345"), 2, 0, S("abcde")); + test(S("abcde"), 5, 1, SV("12345"), 2, 1, S("abcde3")); + test(S("abcde"), 5, 1, SV("12345"), 2, 2, S("abcde34")); + test(S("abcde"), 5, 1, SV("12345"), 2, 3, S("abcde345")); + test(S("abcde"), 5, 1, SV("12345"), 2, 4, S("abcde345")); + test(S("abcde"), 5, 1, SV("12345"), 4, 0, S("abcde")); + test(S("abcde"), 5, 1, SV("12345"), 4, 1, S("abcde5")); + test(S("abcde"), 5, 1, SV("12345"), 4, 2, S("abcde5")); + test(S("abcde"), 5, 1, SV("12345"), 5, 0, S("abcde")); +} + +template +void test18() +{ + test(S("abcde"), 5, 1, SV("12345"), 5, 1, S("abcde")); + test(S("abcde"), 5, 1, SV("12345"), 6, 0, S("can't happen")); + test(S("abcde"), 5, 1, SV("1234567890"), 0, 0, S("abcde")); + test(S("abcde"), 5, 1, SV("1234567890"), 0, 1, S("abcde1")); + test(S("abcde"), 5, 1, SV("1234567890"), 0, 5, S("abcde12345")); + test(S("abcde"), 5, 1, SV("1234567890"), 0, 9, S("abcde123456789")); + test(S("abcde"), 5, 1, SV("1234567890"), 0, 10, S("abcde1234567890")); + test(S("abcde"), 5, 1, SV("1234567890"), 0, 11, S("abcde1234567890")); + test(S("abcde"), 5, 1, SV("1234567890"), 1, 0, S("abcde")); + test(S("abcde"), 5, 1, SV("1234567890"), 1, 1, S("abcde2")); + test(S("abcde"), 5, 1, SV("1234567890"), 1, 4, S("abcde2345")); + test(S("abcde"), 5, 1, SV("1234567890"), 1, 8, S("abcde23456789")); + test(S("abcde"), 5, 1, SV("1234567890"), 1, 9, S("abcde234567890")); + test(S("abcde"), 5, 1, SV("1234567890"), 1, 10, S("abcde234567890")); + test(S("abcde"), 5, 1, SV("1234567890"), 5, 0, S("abcde")); + test(S("abcde"), 5, 1, SV("1234567890"), 5, 1, S("abcde6")); + test(S("abcde"), 5, 1, SV("1234567890"), 5, 2, S("abcde67")); + test(S("abcde"), 5, 1, SV("1234567890"), 5, 4, S("abcde6789")); + test(S("abcde"), 5, 1, SV("1234567890"), 5, 5, S("abcde67890")); + test(S("abcde"), 5, 1, SV("1234567890"), 5, 6, S("abcde67890")); + test(S("abcde"), 5, 1, SV("1234567890"), 9, 0, S("abcde")); + test(S("abcde"), 5, 1, SV("1234567890"), 9, 1, S("abcde0")); + test(S("abcde"), 5, 1, SV("1234567890"), 9, 2, S("abcde0")); + test(S("abcde"), 5, 1, SV("1234567890"), 10, 0, S("abcde")); + test(S("abcde"), 5, 1, SV("1234567890"), 10, 1, S("abcde")); + test(S("abcde"), 5, 1, SV("1234567890"), 11, 0, S("can't happen")); + test(S("abcde"), 5, 1, SV("12345678901234567890"), 0, 0, S("abcde")); + test(S("abcde"), 5, 1, SV("12345678901234567890"), 0, 1, S("abcde1")); + test(S("abcde"), 5, 1, SV("12345678901234567890"), 0, 10, S("abcde1234567890")); + test(S("abcde"), 5, 1, SV("12345678901234567890"), 0, 19, S("abcde1234567890123456789")); + test(S("abcde"), 5, 1, SV("12345678901234567890"), 0, 20, S("abcde12345678901234567890")); + test(S("abcde"), 5, 1, SV("12345678901234567890"), 0, 21, S("abcde12345678901234567890")); + test(S("abcde"), 5, 1, SV("12345678901234567890"), 1, 0, S("abcde")); + test(S("abcde"), 5, 1, SV("12345678901234567890"), 1, 1, S("abcde2")); + test(S("abcde"), 5, 1, SV("12345678901234567890"), 1, 9, S("abcde234567890")); + test(S("abcde"), 5, 1, SV("12345678901234567890"), 1, 18, S("abcde234567890123456789")); + test(S("abcde"), 5, 1, SV("12345678901234567890"), 1, 19, S("abcde2345678901234567890")); + test(S("abcde"), 5, 1, SV("12345678901234567890"), 1, 20, S("abcde2345678901234567890")); + test(S("abcde"), 5, 1, SV("12345678901234567890"), 10, 0, S("abcde")); + test(S("abcde"), 5, 1, SV("12345678901234567890"), 10, 1, S("abcde1")); + test(S("abcde"), 5, 1, SV("12345678901234567890"), 10, 5, S("abcde12345")); + test(S("abcde"), 5, 1, SV("12345678901234567890"), 10, 9, S("abcde123456789")); + test(S("abcde"), 5, 1, SV("12345678901234567890"), 10, 10, S("abcde1234567890")); + test(S("abcde"), 5, 1, SV("12345678901234567890"), 10, 11, S("abcde1234567890")); + test(S("abcde"), 5, 1, SV("12345678901234567890"), 19, 0, S("abcde")); + test(S("abcde"), 5, 1, SV("12345678901234567890"), 19, 1, S("abcde0")); + test(S("abcde"), 5, 1, SV("12345678901234567890"), 19, 2, S("abcde0")); + test(S("abcde"), 5, 1, SV("12345678901234567890"), 20, 0, S("abcde")); + test(S("abcde"), 5, 1, SV("12345678901234567890"), 20, 1, S("abcde")); + test(S("abcde"), 5, 1, SV("12345678901234567890"), 21, 0, S("can't happen")); + test(S("abcde"), 6, 0, SV(""), 0, 0, S("can't happen")); + test(S("abcde"), 6, 0, SV(""), 0, 1, S("can't happen")); + test(S("abcde"), 6, 0, SV(""), 1, 0, S("can't happen")); + test(S("abcde"), 6, 0, SV("12345"), 0, 0, S("can't happen")); + test(S("abcde"), 6, 0, SV("12345"), 0, 1, S("can't happen")); + test(S("abcde"), 6, 0, SV("12345"), 0, 2, S("can't happen")); + test(S("abcde"), 6, 0, SV("12345"), 0, 4, S("can't happen")); + test(S("abcde"), 6, 0, SV("12345"), 0, 5, S("can't happen")); + test(S("abcde"), 6, 0, SV("12345"), 0, 6, S("can't happen")); + test(S("abcde"), 6, 0, SV("12345"), 1, 0, S("can't happen")); + test(S("abcde"), 6, 0, SV("12345"), 1, 1, S("can't happen")); + test(S("abcde"), 6, 0, SV("12345"), 1, 2, S("can't happen")); + test(S("abcde"), 6, 0, SV("12345"), 1, 3, S("can't happen")); + test(S("abcde"), 6, 0, SV("12345"), 1, 4, S("can't happen")); + test(S("abcde"), 6, 0, SV("12345"), 1, 5, S("can't happen")); + test(S("abcde"), 6, 0, SV("12345"), 2, 0, S("can't happen")); + test(S("abcde"), 6, 0, SV("12345"), 2, 1, S("can't happen")); + test(S("abcde"), 6, 0, SV("12345"), 2, 2, S("can't happen")); + test(S("abcde"), 6, 0, SV("12345"), 2, 3, S("can't happen")); + test(S("abcde"), 6, 0, SV("12345"), 2, 4, S("can't happen")); + test(S("abcde"), 6, 0, SV("12345"), 4, 0, S("can't happen")); + test(S("abcde"), 6, 0, SV("12345"), 4, 1, S("can't happen")); + test(S("abcde"), 6, 0, SV("12345"), 4, 2, S("can't happen")); + test(S("abcde"), 6, 0, SV("12345"), 5, 0, S("can't happen")); + test(S("abcde"), 6, 0, SV("12345"), 5, 1, S("can't happen")); + test(S("abcde"), 6, 0, SV("12345"), 6, 0, S("can't happen")); + test(S("abcde"), 6, 0, SV("1234567890"), 0, 0, S("can't happen")); + test(S("abcde"), 6, 0, SV("1234567890"), 0, 1, S("can't happen")); + test(S("abcde"), 6, 0, SV("1234567890"), 0, 5, S("can't happen")); + test(S("abcde"), 6, 0, SV("1234567890"), 0, 9, S("can't happen")); + test(S("abcde"), 6, 0, SV("1234567890"), 0, 10, S("can't happen")); + test(S("abcde"), 6, 0, SV("1234567890"), 0, 11, S("can't happen")); + test(S("abcde"), 6, 0, SV("1234567890"), 1, 0, S("can't happen")); + test(S("abcde"), 6, 0, SV("1234567890"), 1, 1, S("can't happen")); + test(S("abcde"), 6, 0, SV("1234567890"), 1, 4, S("can't happen")); + test(S("abcde"), 6, 0, SV("1234567890"), 1, 8, S("can't happen")); + test(S("abcde"), 6, 0, SV("1234567890"), 1, 9, S("can't happen")); + test(S("abcde"), 6, 0, SV("1234567890"), 1, 10, S("can't happen")); + test(S("abcde"), 6, 0, SV("1234567890"), 5, 0, S("can't happen")); + test(S("abcde"), 6, 0, SV("1234567890"), 5, 1, S("can't happen")); + test(S("abcde"), 6, 0, SV("1234567890"), 5, 2, S("can't happen")); + test(S("abcde"), 6, 0, SV("1234567890"), 5, 4, S("can't happen")); + test(S("abcde"), 6, 0, SV("1234567890"), 5, 5, S("can't happen")); + test(S("abcde"), 6, 0, SV("1234567890"), 5, 6, S("can't happen")); + test(S("abcde"), 6, 0, SV("1234567890"), 9, 0, S("can't happen")); + test(S("abcde"), 6, 0, SV("1234567890"), 9, 1, S("can't happen")); + test(S("abcde"), 6, 0, SV("1234567890"), 9, 2, S("can't happen")); + test(S("abcde"), 6, 0, SV("1234567890"), 10, 0, S("can't happen")); + test(S("abcde"), 6, 0, SV("1234567890"), 10, 1, S("can't happen")); + test(S("abcde"), 6, 0, SV("1234567890"), 11, 0, S("can't happen")); +} + +template +void test19() +{ + test(S("abcde"), 6, 0, SV("12345678901234567890"), 0, 0, S("can't happen")); + test(S("abcde"), 6, 0, SV("12345678901234567890"), 0, 1, S("can't happen")); + test(S("abcde"), 6, 0, SV("12345678901234567890"), 0, 10, S("can't happen")); + test(S("abcde"), 6, 0, SV("12345678901234567890"), 0, 19, S("can't happen")); + test(S("abcde"), 6, 0, SV("12345678901234567890"), 0, 20, S("can't happen")); + test(S("abcde"), 6, 0, SV("12345678901234567890"), 0, 21, S("can't happen")); + test(S("abcde"), 6, 0, SV("12345678901234567890"), 1, 0, S("can't happen")); + test(S("abcde"), 6, 0, SV("12345678901234567890"), 1, 1, S("can't happen")); + test(S("abcde"), 6, 0, SV("12345678901234567890"), 1, 9, S("can't happen")); + test(S("abcde"), 6, 0, SV("12345678901234567890"), 1, 18, S("can't happen")); + test(S("abcde"), 6, 0, SV("12345678901234567890"), 1, 19, S("can't happen")); + test(S("abcde"), 6, 0, SV("12345678901234567890"), 1, 20, S("can't happen")); + test(S("abcde"), 6, 0, SV("12345678901234567890"), 10, 0, S("can't happen")); + test(S("abcde"), 6, 0, SV("12345678901234567890"), 10, 1, S("can't happen")); + test(S("abcde"), 6, 0, SV("12345678901234567890"), 10, 5, S("can't happen")); + test(S("abcde"), 6, 0, SV("12345678901234567890"), 10, 9, S("can't happen")); + test(S("abcde"), 6, 0, SV("12345678901234567890"), 10, 10, S("can't happen")); + test(S("abcde"), 6, 0, SV("12345678901234567890"), 10, 11, S("can't happen")); + test(S("abcde"), 6, 0, SV("12345678901234567890"), 19, 0, S("can't happen")); + test(S("abcde"), 6, 0, SV("12345678901234567890"), 19, 1, S("can't happen")); + test(S("abcde"), 6, 0, SV("12345678901234567890"), 19, 2, S("can't happen")); + test(S("abcde"), 6, 0, SV("12345678901234567890"), 20, 0, S("can't happen")); + test(S("abcde"), 6, 0, SV("12345678901234567890"), 20, 1, S("can't happen")); + test(S("abcde"), 6, 0, SV("12345678901234567890"), 21, 0, S("can't happen")); + test(S("abcdefghij"), 0, 0, SV(""), 0, 0, S("abcdefghij")); + test(S("abcdefghij"), 0, 0, SV(""), 0, 1, S("abcdefghij")); + test(S("abcdefghij"), 0, 0, SV(""), 1, 0, S("can't happen")); + test(S("abcdefghij"), 0, 0, SV("12345"), 0, 0, S("abcdefghij")); + test(S("abcdefghij"), 0, 0, SV("12345"), 0, 1, S("1abcdefghij")); + test(S("abcdefghij"), 0, 0, SV("12345"), 0, 2, S("12abcdefghij")); + test(S("abcdefghij"), 0, 0, SV("12345"), 0, 4, S("1234abcdefghij")); + test(S("abcdefghij"), 0, 0, SV("12345"), 0, 5, S("12345abcdefghij")); + test(S("abcdefghij"), 0, 0, SV("12345"), 0, 6, S("12345abcdefghij")); + test(S("abcdefghij"), 0, 0, SV("12345"), 1, 0, S("abcdefghij")); + test(S("abcdefghij"), 0, 0, SV("12345"), 1, 1, S("2abcdefghij")); + test(S("abcdefghij"), 0, 0, SV("12345"), 1, 2, S("23abcdefghij")); + test(S("abcdefghij"), 0, 0, SV("12345"), 1, 3, S("234abcdefghij")); + test(S("abcdefghij"), 0, 0, SV("12345"), 1, 4, S("2345abcdefghij")); + test(S("abcdefghij"), 0, 0, SV("12345"), 1, 5, S("2345abcdefghij")); + test(S("abcdefghij"), 0, 0, SV("12345"), 2, 0, S("abcdefghij")); + test(S("abcdefghij"), 0, 0, SV("12345"), 2, 1, S("3abcdefghij")); + test(S("abcdefghij"), 0, 0, SV("12345"), 2, 2, S("34abcdefghij")); + test(S("abcdefghij"), 0, 0, SV("12345"), 2, 3, S("345abcdefghij")); + test(S("abcdefghij"), 0, 0, SV("12345"), 2, 4, S("345abcdefghij")); + test(S("abcdefghij"), 0, 0, SV("12345"), 4, 0, S("abcdefghij")); + test(S("abcdefghij"), 0, 0, SV("12345"), 4, 1, S("5abcdefghij")); + test(S("abcdefghij"), 0, 0, SV("12345"), 4, 2, S("5abcdefghij")); + test(S("abcdefghij"), 0, 0, SV("12345"), 5, 0, S("abcdefghij")); + test(S("abcdefghij"), 0, 0, SV("12345"), 5, 1, S("abcdefghij")); + test(S("abcdefghij"), 0, 0, SV("12345"), 6, 0, S("can't happen")); + test(S("abcdefghij"), 0, 0, SV("1234567890"), 0, 0, S("abcdefghij")); + test(S("abcdefghij"), 0, 0, SV("1234567890"), 0, 1, S("1abcdefghij")); + test(S("abcdefghij"), 0, 0, SV("1234567890"), 0, 5, S("12345abcdefghij")); + test(S("abcdefghij"), 0, 0, SV("1234567890"), 0, 9, S("123456789abcdefghij")); + test(S("abcdefghij"), 0, 0, SV("1234567890"), 0, 10, S("1234567890abcdefghij")); + test(S("abcdefghij"), 0, 0, SV("1234567890"), 0, 11, S("1234567890abcdefghij")); + test(S("abcdefghij"), 0, 0, SV("1234567890"), 1, 0, S("abcdefghij")); + test(S("abcdefghij"), 0, 0, SV("1234567890"), 1, 1, S("2abcdefghij")); + test(S("abcdefghij"), 0, 0, SV("1234567890"), 1, 4, S("2345abcdefghij")); + test(S("abcdefghij"), 0, 0, SV("1234567890"), 1, 8, S("23456789abcdefghij")); + test(S("abcdefghij"), 0, 0, SV("1234567890"), 1, 9, S("234567890abcdefghij")); + test(S("abcdefghij"), 0, 0, SV("1234567890"), 1, 10, S("234567890abcdefghij")); + test(S("abcdefghij"), 0, 0, SV("1234567890"), 5, 0, S("abcdefghij")); + test(S("abcdefghij"), 0, 0, SV("1234567890"), 5, 1, S("6abcdefghij")); + test(S("abcdefghij"), 0, 0, SV("1234567890"), 5, 2, S("67abcdefghij")); + test(S("abcdefghij"), 0, 0, SV("1234567890"), 5, 4, S("6789abcdefghij")); + test(S("abcdefghij"), 0, 0, SV("1234567890"), 5, 5, S("67890abcdefghij")); + test(S("abcdefghij"), 0, 0, SV("1234567890"), 5, 6, S("67890abcdefghij")); + test(S("abcdefghij"), 0, 0, SV("1234567890"), 9, 0, S("abcdefghij")); + test(S("abcdefghij"), 0, 0, SV("1234567890"), 9, 1, S("0abcdefghij")); + test(S("abcdefghij"), 0, 0, SV("1234567890"), 9, 2, S("0abcdefghij")); + test(S("abcdefghij"), 0, 0, SV("1234567890"), 10, 0, S("abcdefghij")); + test(S("abcdefghij"), 0, 0, SV("1234567890"), 10, 1, S("abcdefghij")); + test(S("abcdefghij"), 0, 0, SV("1234567890"), 11, 0, S("can't happen")); + test(S("abcdefghij"), 0, 0, SV("12345678901234567890"), 0, 0, S("abcdefghij")); + test(S("abcdefghij"), 0, 0, SV("12345678901234567890"), 0, 1, S("1abcdefghij")); + test(S("abcdefghij"), 0, 0, SV("12345678901234567890"), 0, 10, S("1234567890abcdefghij")); + test(S("abcdefghij"), 0, 0, SV("12345678901234567890"), 0, 19, S("1234567890123456789abcdefghij")); + test(S("abcdefghij"), 0, 0, SV("12345678901234567890"), 0, 20, S("12345678901234567890abcdefghij")); + test(S("abcdefghij"), 0, 0, SV("12345678901234567890"), 0, 21, S("12345678901234567890abcdefghij")); + test(S("abcdefghij"), 0, 0, SV("12345678901234567890"), 1, 0, S("abcdefghij")); + test(S("abcdefghij"), 0, 0, SV("12345678901234567890"), 1, 1, S("2abcdefghij")); + test(S("abcdefghij"), 0, 0, SV("12345678901234567890"), 1, 9, S("234567890abcdefghij")); + test(S("abcdefghij"), 0, 0, SV("12345678901234567890"), 1, 18, S("234567890123456789abcdefghij")); + test(S("abcdefghij"), 0, 0, SV("12345678901234567890"), 1, 19, S("2345678901234567890abcdefghij")); + test(S("abcdefghij"), 0, 0, SV("12345678901234567890"), 1, 20, S("2345678901234567890abcdefghij")); + test(S("abcdefghij"), 0, 0, SV("12345678901234567890"), 10, 0, S("abcdefghij")); + test(S("abcdefghij"), 0, 0, SV("12345678901234567890"), 10, 1, S("1abcdefghij")); + test(S("abcdefghij"), 0, 0, SV("12345678901234567890"), 10, 5, S("12345abcdefghij")); + test(S("abcdefghij"), 0, 0, SV("12345678901234567890"), 10, 9, S("123456789abcdefghij")); + test(S("abcdefghij"), 0, 0, SV("12345678901234567890"), 10, 10, S("1234567890abcdefghij")); + test(S("abcdefghij"), 0, 0, SV("12345678901234567890"), 10, 11, S("1234567890abcdefghij")); + test(S("abcdefghij"), 0, 0, SV("12345678901234567890"), 19, 0, S("abcdefghij")); + test(S("abcdefghij"), 0, 0, SV("12345678901234567890"), 19, 1, S("0abcdefghij")); + test(S("abcdefghij"), 0, 0, SV("12345678901234567890"), 19, 2, S("0abcdefghij")); + test(S("abcdefghij"), 0, 0, SV("12345678901234567890"), 20, 0, S("abcdefghij")); + test(S("abcdefghij"), 0, 0, SV("12345678901234567890"), 20, 1, S("abcdefghij")); + test(S("abcdefghij"), 0, 0, SV("12345678901234567890"), 21, 0, S("can't happen")); + test(S("abcdefghij"), 0, 1, SV(""), 0, 0, S("bcdefghij")); + test(S("abcdefghij"), 0, 1, SV(""), 0, 1, S("bcdefghij")); +} + +template +void test20() +{ + test(S("abcdefghij"), 0, 1, SV(""), 1, 0, S("can't happen")); + test(S("abcdefghij"), 0, 1, SV("12345"), 0, 0, S("bcdefghij")); + test(S("abcdefghij"), 0, 1, SV("12345"), 0, 1, S("1bcdefghij")); + test(S("abcdefghij"), 0, 1, SV("12345"), 0, 2, S("12bcdefghij")); + test(S("abcdefghij"), 0, 1, SV("12345"), 0, 4, S("1234bcdefghij")); + test(S("abcdefghij"), 0, 1, SV("12345"), 0, 5, S("12345bcdefghij")); + test(S("abcdefghij"), 0, 1, SV("12345"), 0, 6, S("12345bcdefghij")); + test(S("abcdefghij"), 0, 1, SV("12345"), 1, 0, S("bcdefghij")); + test(S("abcdefghij"), 0, 1, SV("12345"), 1, 1, S("2bcdefghij")); + test(S("abcdefghij"), 0, 1, SV("12345"), 1, 2, S("23bcdefghij")); + test(S("abcdefghij"), 0, 1, SV("12345"), 1, 3, S("234bcdefghij")); + test(S("abcdefghij"), 0, 1, SV("12345"), 1, 4, S("2345bcdefghij")); + test(S("abcdefghij"), 0, 1, SV("12345"), 1, 5, S("2345bcdefghij")); + test(S("abcdefghij"), 0, 1, SV("12345"), 2, 0, S("bcdefghij")); + test(S("abcdefghij"), 0, 1, SV("12345"), 2, 1, S("3bcdefghij")); + test(S("abcdefghij"), 0, 1, SV("12345"), 2, 2, S("34bcdefghij")); + test(S("abcdefghij"), 0, 1, SV("12345"), 2, 3, S("345bcdefghij")); + test(S("abcdefghij"), 0, 1, SV("12345"), 2, 4, S("345bcdefghij")); + test(S("abcdefghij"), 0, 1, SV("12345"), 4, 0, S("bcdefghij")); + test(S("abcdefghij"), 0, 1, SV("12345"), 4, 1, S("5bcdefghij")); + test(S("abcdefghij"), 0, 1, SV("12345"), 4, 2, S("5bcdefghij")); + test(S("abcdefghij"), 0, 1, SV("12345"), 5, 0, S("bcdefghij")); + test(S("abcdefghij"), 0, 1, SV("12345"), 5, 1, S("bcdefghij")); + test(S("abcdefghij"), 0, 1, SV("12345"), 6, 0, S("can't happen")); + test(S("abcdefghij"), 0, 1, SV("1234567890"), 0, 0, S("bcdefghij")); + test(S("abcdefghij"), 0, 1, SV("1234567890"), 0, 1, S("1bcdefghij")); + test(S("abcdefghij"), 0, 1, SV("1234567890"), 0, 5, S("12345bcdefghij")); + test(S("abcdefghij"), 0, 1, SV("1234567890"), 0, 9, S("123456789bcdefghij")); + test(S("abcdefghij"), 0, 1, SV("1234567890"), 0, 10, S("1234567890bcdefghij")); + test(S("abcdefghij"), 0, 1, SV("1234567890"), 0, 11, S("1234567890bcdefghij")); + test(S("abcdefghij"), 0, 1, SV("1234567890"), 1, 0, S("bcdefghij")); + test(S("abcdefghij"), 0, 1, SV("1234567890"), 1, 1, S("2bcdefghij")); + test(S("abcdefghij"), 0, 1, SV("1234567890"), 1, 4, S("2345bcdefghij")); + test(S("abcdefghij"), 0, 1, SV("1234567890"), 1, 8, S("23456789bcdefghij")); + test(S("abcdefghij"), 0, 1, SV("1234567890"), 1, 9, S("234567890bcdefghij")); + test(S("abcdefghij"), 0, 1, SV("1234567890"), 1, 10, S("234567890bcdefghij")); + test(S("abcdefghij"), 0, 1, SV("1234567890"), 5, 0, S("bcdefghij")); + test(S("abcdefghij"), 0, 1, SV("1234567890"), 5, 1, S("6bcdefghij")); + test(S("abcdefghij"), 0, 1, SV("1234567890"), 5, 2, S("67bcdefghij")); + test(S("abcdefghij"), 0, 1, SV("1234567890"), 5, 4, S("6789bcdefghij")); + test(S("abcdefghij"), 0, 1, SV("1234567890"), 5, 5, S("67890bcdefghij")); + test(S("abcdefghij"), 0, 1, SV("1234567890"), 5, 6, S("67890bcdefghij")); + test(S("abcdefghij"), 0, 1, SV("1234567890"), 9, 0, S("bcdefghij")); + test(S("abcdefghij"), 0, 1, SV("1234567890"), 9, 1, S("0bcdefghij")); + test(S("abcdefghij"), 0, 1, SV("1234567890"), 9, 2, S("0bcdefghij")); + test(S("abcdefghij"), 0, 1, SV("1234567890"), 10, 0, S("bcdefghij")); + test(S("abcdefghij"), 0, 1, SV("1234567890"), 10, 1, S("bcdefghij")); + test(S("abcdefghij"), 0, 1, SV("1234567890"), 11, 0, S("can't happen")); + test(S("abcdefghij"), 0, 1, SV("12345678901234567890"), 0, 0, S("bcdefghij")); + test(S("abcdefghij"), 0, 1, SV("12345678901234567890"), 0, 1, S("1bcdefghij")); + test(S("abcdefghij"), 0, 1, SV("12345678901234567890"), 0, 10, S("1234567890bcdefghij")); + test(S("abcdefghij"), 0, 1, SV("12345678901234567890"), 0, 19, S("1234567890123456789bcdefghij")); + test(S("abcdefghij"), 0, 1, SV("12345678901234567890"), 0, 20, S("12345678901234567890bcdefghij")); + test(S("abcdefghij"), 0, 1, SV("12345678901234567890"), 0, 21, S("12345678901234567890bcdefghij")); + test(S("abcdefghij"), 0, 1, SV("12345678901234567890"), 1, 0, S("bcdefghij")); + test(S("abcdefghij"), 0, 1, SV("12345678901234567890"), 1, 1, S("2bcdefghij")); + test(S("abcdefghij"), 0, 1, SV("12345678901234567890"), 1, 9, S("234567890bcdefghij")); + test(S("abcdefghij"), 0, 1, SV("12345678901234567890"), 1, 18, S("234567890123456789bcdefghij")); + test(S("abcdefghij"), 0, 1, SV("12345678901234567890"), 1, 19, S("2345678901234567890bcdefghij")); + test(S("abcdefghij"), 0, 1, SV("12345678901234567890"), 1, 20, S("2345678901234567890bcdefghij")); + test(S("abcdefghij"), 0, 1, SV("12345678901234567890"), 10, 0, S("bcdefghij")); + test(S("abcdefghij"), 0, 1, SV("12345678901234567890"), 10, 1, S("1bcdefghij")); + test(S("abcdefghij"), 0, 1, SV("12345678901234567890"), 10, 5, S("12345bcdefghij")); + test(S("abcdefghij"), 0, 1, SV("12345678901234567890"), 10, 9, S("123456789bcdefghij")); + test(S("abcdefghij"), 0, 1, SV("12345678901234567890"), 10, 10, S("1234567890bcdefghij")); + test(S("abcdefghij"), 0, 1, SV("12345678901234567890"), 10, 11, S("1234567890bcdefghij")); + test(S("abcdefghij"), 0, 1, SV("12345678901234567890"), 19, 0, S("bcdefghij")); + test(S("abcdefghij"), 0, 1, SV("12345678901234567890"), 19, 1, S("0bcdefghij")); + test(S("abcdefghij"), 0, 1, SV("12345678901234567890"), 19, 2, S("0bcdefghij")); + test(S("abcdefghij"), 0, 1, SV("12345678901234567890"), 20, 0, S("bcdefghij")); + test(S("abcdefghij"), 0, 1, SV("12345678901234567890"), 20, 1, S("bcdefghij")); + test(S("abcdefghij"), 0, 1, SV("12345678901234567890"), 21, 0, S("can't happen")); + test(S("abcdefghij"), 0, 5, SV(""), 0, 0, S("fghij")); + test(S("abcdefghij"), 0, 5, SV(""), 0, 1, S("fghij")); + test(S("abcdefghij"), 0, 5, SV(""), 1, 0, S("can't happen")); + test(S("abcdefghij"), 0, 5, SV("12345"), 0, 0, S("fghij")); + test(S("abcdefghij"), 0, 5, SV("12345"), 0, 1, S("1fghij")); + test(S("abcdefghij"), 0, 5, SV("12345"), 0, 2, S("12fghij")); + test(S("abcdefghij"), 0, 5, SV("12345"), 0, 4, S("1234fghij")); + test(S("abcdefghij"), 0, 5, SV("12345"), 0, 5, S("12345fghij")); + test(S("abcdefghij"), 0, 5, SV("12345"), 0, 6, S("12345fghij")); + test(S("abcdefghij"), 0, 5, SV("12345"), 1, 0, S("fghij")); + test(S("abcdefghij"), 0, 5, SV("12345"), 1, 1, S("2fghij")); + test(S("abcdefghij"), 0, 5, SV("12345"), 1, 2, S("23fghij")); + test(S("abcdefghij"), 0, 5, SV("12345"), 1, 3, S("234fghij")); + test(S("abcdefghij"), 0, 5, SV("12345"), 1, 4, S("2345fghij")); + test(S("abcdefghij"), 0, 5, SV("12345"), 1, 5, S("2345fghij")); + test(S("abcdefghij"), 0, 5, SV("12345"), 2, 0, S("fghij")); + test(S("abcdefghij"), 0, 5, SV("12345"), 2, 1, S("3fghij")); + test(S("abcdefghij"), 0, 5, SV("12345"), 2, 2, S("34fghij")); + test(S("abcdefghij"), 0, 5, SV("12345"), 2, 3, S("345fghij")); + test(S("abcdefghij"), 0, 5, SV("12345"), 2, 4, S("345fghij")); + test(S("abcdefghij"), 0, 5, SV("12345"), 4, 0, S("fghij")); + test(S("abcdefghij"), 0, 5, SV("12345"), 4, 1, S("5fghij")); + test(S("abcdefghij"), 0, 5, SV("12345"), 4, 2, S("5fghij")); + test(S("abcdefghij"), 0, 5, SV("12345"), 5, 0, S("fghij")); + test(S("abcdefghij"), 0, 5, SV("12345"), 5, 1, S("fghij")); + test(S("abcdefghij"), 0, 5, SV("12345"), 6, 0, S("can't happen")); + test(S("abcdefghij"), 0, 5, SV("1234567890"), 0, 0, S("fghij")); + test(S("abcdefghij"), 0, 5, SV("1234567890"), 0, 1, S("1fghij")); +} + +template +void test21() +{ + test(S("abcdefghij"), 0, 5, SV("1234567890"), 0, 5, S("12345fghij")); + test(S("abcdefghij"), 0, 5, SV("1234567890"), 0, 9, S("123456789fghij")); + test(S("abcdefghij"), 0, 5, SV("1234567890"), 0, 10, S("1234567890fghij")); + test(S("abcdefghij"), 0, 5, SV("1234567890"), 0, 11, S("1234567890fghij")); + test(S("abcdefghij"), 0, 5, SV("1234567890"), 1, 0, S("fghij")); + test(S("abcdefghij"), 0, 5, SV("1234567890"), 1, 1, S("2fghij")); + test(S("abcdefghij"), 0, 5, SV("1234567890"), 1, 4, S("2345fghij")); + test(S("abcdefghij"), 0, 5, SV("1234567890"), 1, 8, S("23456789fghij")); + test(S("abcdefghij"), 0, 5, SV("1234567890"), 1, 9, S("234567890fghij")); + test(S("abcdefghij"), 0, 5, SV("1234567890"), 1, 10, S("234567890fghij")); + test(S("abcdefghij"), 0, 5, SV("1234567890"), 5, 0, S("fghij")); + test(S("abcdefghij"), 0, 5, SV("1234567890"), 5, 1, S("6fghij")); + test(S("abcdefghij"), 0, 5, SV("1234567890"), 5, 2, S("67fghij")); + test(S("abcdefghij"), 0, 5, SV("1234567890"), 5, 4, S("6789fghij")); + test(S("abcdefghij"), 0, 5, SV("1234567890"), 5, 5, S("67890fghij")); + test(S("abcdefghij"), 0, 5, SV("1234567890"), 5, 6, S("67890fghij")); + test(S("abcdefghij"), 0, 5, SV("1234567890"), 9, 0, S("fghij")); + test(S("abcdefghij"), 0, 5, SV("1234567890"), 9, 1, S("0fghij")); + test(S("abcdefghij"), 0, 5, SV("1234567890"), 9, 2, S("0fghij")); + test(S("abcdefghij"), 0, 5, SV("1234567890"), 10, 0, S("fghij")); + test(S("abcdefghij"), 0, 5, SV("1234567890"), 10, 1, S("fghij")); + test(S("abcdefghij"), 0, 5, SV("1234567890"), 11, 0, S("can't happen")); + test(S("abcdefghij"), 0, 5, SV("12345678901234567890"), 0, 0, S("fghij")); + test(S("abcdefghij"), 0, 5, SV("12345678901234567890"), 0, 1, S("1fghij")); + test(S("abcdefghij"), 0, 5, SV("12345678901234567890"), 0, 10, S("1234567890fghij")); + test(S("abcdefghij"), 0, 5, SV("12345678901234567890"), 0, 19, S("1234567890123456789fghij")); + test(S("abcdefghij"), 0, 5, SV("12345678901234567890"), 0, 20, S("12345678901234567890fghij")); + test(S("abcdefghij"), 0, 5, SV("12345678901234567890"), 0, 21, S("12345678901234567890fghij")); + test(S("abcdefghij"), 0, 5, SV("12345678901234567890"), 1, 0, S("fghij")); + test(S("abcdefghij"), 0, 5, SV("12345678901234567890"), 1, 1, S("2fghij")); + test(S("abcdefghij"), 0, 5, SV("12345678901234567890"), 1, 9, S("234567890fghij")); + test(S("abcdefghij"), 0, 5, SV("12345678901234567890"), 1, 18, S("234567890123456789fghij")); + test(S("abcdefghij"), 0, 5, SV("12345678901234567890"), 1, 19, S("2345678901234567890fghij")); + test(S("abcdefghij"), 0, 5, SV("12345678901234567890"), 1, 20, S("2345678901234567890fghij")); + test(S("abcdefghij"), 0, 5, SV("12345678901234567890"), 10, 0, S("fghij")); + test(S("abcdefghij"), 0, 5, SV("12345678901234567890"), 10, 1, S("1fghij")); + test(S("abcdefghij"), 0, 5, SV("12345678901234567890"), 10, 5, S("12345fghij")); + test(S("abcdefghij"), 0, 5, SV("12345678901234567890"), 10, 9, S("123456789fghij")); + test(S("abcdefghij"), 0, 5, SV("12345678901234567890"), 10, 10, S("1234567890fghij")); + test(S("abcdefghij"), 0, 5, SV("12345678901234567890"), 10, 11, S("1234567890fghij")); + test(S("abcdefghij"), 0, 5, SV("12345678901234567890"), 19, 0, S("fghij")); + test(S("abcdefghij"), 0, 5, SV("12345678901234567890"), 19, 1, S("0fghij")); + test(S("abcdefghij"), 0, 5, SV("12345678901234567890"), 19, 2, S("0fghij")); + test(S("abcdefghij"), 0, 5, SV("12345678901234567890"), 20, 0, S("fghij")); + test(S("abcdefghij"), 0, 5, SV("12345678901234567890"), 20, 1, S("fghij")); + test(S("abcdefghij"), 0, 5, SV("12345678901234567890"), 21, 0, S("can't happen")); + test(S("abcdefghij"), 0, 9, SV(""), 0, 0, S("j")); + test(S("abcdefghij"), 0, 9, SV(""), 0, 1, S("j")); + test(S("abcdefghij"), 0, 9, SV(""), 1, 0, S("can't happen")); + test(S("abcdefghij"), 0, 9, SV("12345"), 0, 0, S("j")); + test(S("abcdefghij"), 0, 9, SV("12345"), 0, 1, S("1j")); + test(S("abcdefghij"), 0, 9, SV("12345"), 0, 2, S("12j")); + test(S("abcdefghij"), 0, 9, SV("12345"), 0, 4, S("1234j")); + test(S("abcdefghij"), 0, 9, SV("12345"), 0, 5, S("12345j")); + test(S("abcdefghij"), 0, 9, SV("12345"), 0, 6, S("12345j")); + test(S("abcdefghij"), 0, 9, SV("12345"), 1, 0, S("j")); + test(S("abcdefghij"), 0, 9, SV("12345"), 1, 1, S("2j")); + test(S("abcdefghij"), 0, 9, SV("12345"), 1, 2, S("23j")); + test(S("abcdefghij"), 0, 9, SV("12345"), 1, 3, S("234j")); + test(S("abcdefghij"), 0, 9, SV("12345"), 1, 4, S("2345j")); + test(S("abcdefghij"), 0, 9, SV("12345"), 1, 5, S("2345j")); + test(S("abcdefghij"), 0, 9, SV("12345"), 2, 0, S("j")); + test(S("abcdefghij"), 0, 9, SV("12345"), 2, 1, S("3j")); + test(S("abcdefghij"), 0, 9, SV("12345"), 2, 2, S("34j")); + test(S("abcdefghij"), 0, 9, SV("12345"), 2, 3, S("345j")); + test(S("abcdefghij"), 0, 9, SV("12345"), 2, 4, S("345j")); + test(S("abcdefghij"), 0, 9, SV("12345"), 4, 0, S("j")); + test(S("abcdefghij"), 0, 9, SV("12345"), 4, 1, S("5j")); + test(S("abcdefghij"), 0, 9, SV("12345"), 4, 2, S("5j")); + test(S("abcdefghij"), 0, 9, SV("12345"), 5, 0, S("j")); + test(S("abcdefghij"), 0, 9, SV("12345"), 5, 1, S("j")); + test(S("abcdefghij"), 0, 9, SV("12345"), 6, 0, S("can't happen")); + test(S("abcdefghij"), 0, 9, SV("1234567890"), 0, 0, S("j")); + test(S("abcdefghij"), 0, 9, SV("1234567890"), 0, 1, S("1j")); + test(S("abcdefghij"), 0, 9, SV("1234567890"), 0, 5, S("12345j")); + test(S("abcdefghij"), 0, 9, SV("1234567890"), 0, 9, S("123456789j")); + test(S("abcdefghij"), 0, 9, SV("1234567890"), 0, 10, S("1234567890j")); + test(S("abcdefghij"), 0, 9, SV("1234567890"), 0, 11, S("1234567890j")); + test(S("abcdefghij"), 0, 9, SV("1234567890"), 1, 0, S("j")); + test(S("abcdefghij"), 0, 9, SV("1234567890"), 1, 1, S("2j")); + test(S("abcdefghij"), 0, 9, SV("1234567890"), 1, 4, S("2345j")); + test(S("abcdefghij"), 0, 9, SV("1234567890"), 1, 8, S("23456789j")); + test(S("abcdefghij"), 0, 9, SV("1234567890"), 1, 9, S("234567890j")); + test(S("abcdefghij"), 0, 9, SV("1234567890"), 1, 10, S("234567890j")); + test(S("abcdefghij"), 0, 9, SV("1234567890"), 5, 0, S("j")); + test(S("abcdefghij"), 0, 9, SV("1234567890"), 5, 1, S("6j")); + test(S("abcdefghij"), 0, 9, SV("1234567890"), 5, 2, S("67j")); + test(S("abcdefghij"), 0, 9, SV("1234567890"), 5, 4, S("6789j")); + test(S("abcdefghij"), 0, 9, SV("1234567890"), 5, 5, S("67890j")); + test(S("abcdefghij"), 0, 9, SV("1234567890"), 5, 6, S("67890j")); + test(S("abcdefghij"), 0, 9, SV("1234567890"), 9, 0, S("j")); + test(S("abcdefghij"), 0, 9, SV("1234567890"), 9, 1, S("0j")); + test(S("abcdefghij"), 0, 9, SV("1234567890"), 9, 2, S("0j")); + test(S("abcdefghij"), 0, 9, SV("1234567890"), 10, 0, S("j")); + test(S("abcdefghij"), 0, 9, SV("1234567890"), 10, 1, S("j")); + test(S("abcdefghij"), 0, 9, SV("1234567890"), 11, 0, S("can't happen")); + test(S("abcdefghij"), 0, 9, SV("12345678901234567890"), 0, 0, S("j")); + test(S("abcdefghij"), 0, 9, SV("12345678901234567890"), 0, 1, S("1j")); + test(S("abcdefghij"), 0, 9, SV("12345678901234567890"), 0, 10, S("1234567890j")); + test(S("abcdefghij"), 0, 9, SV("12345678901234567890"), 0, 19, S("1234567890123456789j")); +} + +template +void test22() +{ + test(S("abcdefghij"), 0, 9, SV("12345678901234567890"), 0, 20, S("12345678901234567890j")); + test(S("abcdefghij"), 0, 9, SV("12345678901234567890"), 0, 21, S("12345678901234567890j")); + test(S("abcdefghij"), 0, 9, SV("12345678901234567890"), 1, 0, S("j")); + test(S("abcdefghij"), 0, 9, SV("12345678901234567890"), 1, 1, S("2j")); + test(S("abcdefghij"), 0, 9, SV("12345678901234567890"), 1, 9, S("234567890j")); + test(S("abcdefghij"), 0, 9, SV("12345678901234567890"), 1, 18, S("234567890123456789j")); + test(S("abcdefghij"), 0, 9, SV("12345678901234567890"), 1, 19, S("2345678901234567890j")); + test(S("abcdefghij"), 0, 9, SV("12345678901234567890"), 1, 20, S("2345678901234567890j")); + test(S("abcdefghij"), 0, 9, SV("12345678901234567890"), 10, 0, S("j")); + test(S("abcdefghij"), 0, 9, SV("12345678901234567890"), 10, 1, S("1j")); + test(S("abcdefghij"), 0, 9, SV("12345678901234567890"), 10, 5, S("12345j")); + test(S("abcdefghij"), 0, 9, SV("12345678901234567890"), 10, 9, S("123456789j")); + test(S("abcdefghij"), 0, 9, SV("12345678901234567890"), 10, 10, S("1234567890j")); + test(S("abcdefghij"), 0, 9, SV("12345678901234567890"), 10, 11, S("1234567890j")); + test(S("abcdefghij"), 0, 9, SV("12345678901234567890"), 19, 0, S("j")); + test(S("abcdefghij"), 0, 9, SV("12345678901234567890"), 19, 1, S("0j")); + test(S("abcdefghij"), 0, 9, SV("12345678901234567890"), 19, 2, S("0j")); + test(S("abcdefghij"), 0, 9, SV("12345678901234567890"), 20, 0, S("j")); + test(S("abcdefghij"), 0, 9, SV("12345678901234567890"), 20, 1, S("j")); + test(S("abcdefghij"), 0, 9, SV("12345678901234567890"), 21, 0, S("can't happen")); + test(S("abcdefghij"), 0, 10, SV(""), 0, 0, S("")); + test(S("abcdefghij"), 0, 10, SV(""), 0, 1, S("")); + test(S("abcdefghij"), 0, 10, SV(""), 1, 0, S("can't happen")); + test(S("abcdefghij"), 0, 10, SV("12345"), 0, 0, S("")); + test(S("abcdefghij"), 0, 10, SV("12345"), 0, 1, S("1")); + test(S("abcdefghij"), 0, 10, SV("12345"), 0, 2, S("12")); + test(S("abcdefghij"), 0, 10, SV("12345"), 0, 4, S("1234")); + test(S("abcdefghij"), 0, 10, SV("12345"), 0, 5, S("12345")); + test(S("abcdefghij"), 0, 10, SV("12345"), 0, 6, S("12345")); + test(S("abcdefghij"), 0, 10, SV("12345"), 1, 0, S("")); + test(S("abcdefghij"), 0, 10, SV("12345"), 1, 1, S("2")); + test(S("abcdefghij"), 0, 10, SV("12345"), 1, 2, S("23")); + test(S("abcdefghij"), 0, 10, SV("12345"), 1, 3, S("234")); + test(S("abcdefghij"), 0, 10, SV("12345"), 1, 4, S("2345")); + test(S("abcdefghij"), 0, 10, SV("12345"), 1, 5, S("2345")); + test(S("abcdefghij"), 0, 10, SV("12345"), 2, 0, S("")); + test(S("abcdefghij"), 0, 10, SV("12345"), 2, 1, S("3")); + test(S("abcdefghij"), 0, 10, SV("12345"), 2, 2, S("34")); + test(S("abcdefghij"), 0, 10, SV("12345"), 2, 3, S("345")); + test(S("abcdefghij"), 0, 10, SV("12345"), 2, 4, S("345")); + test(S("abcdefghij"), 0, 10, SV("12345"), 4, 0, S("")); + test(S("abcdefghij"), 0, 10, SV("12345"), 4, 1, S("5")); + test(S("abcdefghij"), 0, 10, SV("12345"), 4, 2, S("5")); + test(S("abcdefghij"), 0, 10, SV("12345"), 5, 0, S("")); + test(S("abcdefghij"), 0, 10, SV("12345"), 5, 1, S("")); + test(S("abcdefghij"), 0, 10, SV("12345"), 6, 0, S("can't happen")); + test(S("abcdefghij"), 0, 10, SV("1234567890"), 0, 0, S("")); + test(S("abcdefghij"), 0, 10, SV("1234567890"), 0, 1, S("1")); + test(S("abcdefghij"), 0, 10, SV("1234567890"), 0, 5, S("12345")); + test(S("abcdefghij"), 0, 10, SV("1234567890"), 0, 9, S("123456789")); + test(S("abcdefghij"), 0, 10, SV("1234567890"), 0, 10, S("1234567890")); + test(S("abcdefghij"), 0, 10, SV("1234567890"), 0, 11, S("1234567890")); + test(S("abcdefghij"), 0, 10, SV("1234567890"), 1, 0, S("")); + test(S("abcdefghij"), 0, 10, SV("1234567890"), 1, 1, S("2")); + test(S("abcdefghij"), 0, 10, SV("1234567890"), 1, 4, S("2345")); + test(S("abcdefghij"), 0, 10, SV("1234567890"), 1, 8, S("23456789")); + test(S("abcdefghij"), 0, 10, SV("1234567890"), 1, 9, S("234567890")); + test(S("abcdefghij"), 0, 10, SV("1234567890"), 1, 10, S("234567890")); + test(S("abcdefghij"), 0, 10, SV("1234567890"), 5, 0, S("")); + test(S("abcdefghij"), 0, 10, SV("1234567890"), 5, 1, S("6")); + test(S("abcdefghij"), 0, 10, SV("1234567890"), 5, 2, S("67")); + test(S("abcdefghij"), 0, 10, SV("1234567890"), 5, 4, S("6789")); + test(S("abcdefghij"), 0, 10, SV("1234567890"), 5, 5, S("67890")); + test(S("abcdefghij"), 0, 10, SV("1234567890"), 5, 6, S("67890")); + test(S("abcdefghij"), 0, 10, SV("1234567890"), 9, 0, S("")); + test(S("abcdefghij"), 0, 10, SV("1234567890"), 9, 1, S("0")); + test(S("abcdefghij"), 0, 10, SV("1234567890"), 9, 2, S("0")); + test(S("abcdefghij"), 0, 10, SV("1234567890"), 10, 0, S("")); + test(S("abcdefghij"), 0, 10, SV("1234567890"), 10, 1, S("")); + test(S("abcdefghij"), 0, 10, SV("1234567890"), 11, 0, S("can't happen")); + test(S("abcdefghij"), 0, 10, SV("12345678901234567890"), 0, 0, S("")); + test(S("abcdefghij"), 0, 10, SV("12345678901234567890"), 0, 1, S("1")); + test(S("abcdefghij"), 0, 10, SV("12345678901234567890"), 0, 10, S("1234567890")); + test(S("abcdefghij"), 0, 10, SV("12345678901234567890"), 0, 19, S("1234567890123456789")); + test(S("abcdefghij"), 0, 10, SV("12345678901234567890"), 0, 20, S("12345678901234567890")); + test(S("abcdefghij"), 0, 10, SV("12345678901234567890"), 0, 21, S("12345678901234567890")); + test(S("abcdefghij"), 0, 10, SV("12345678901234567890"), 1, 0, S("")); + test(S("abcdefghij"), 0, 10, SV("12345678901234567890"), 1, 1, S("2")); + test(S("abcdefghij"), 0, 10, SV("12345678901234567890"), 1, 9, S("234567890")); + test(S("abcdefghij"), 0, 10, SV("12345678901234567890"), 1, 18, S("234567890123456789")); + test(S("abcdefghij"), 0, 10, SV("12345678901234567890"), 1, 19, S("2345678901234567890")); + test(S("abcdefghij"), 0, 10, SV("12345678901234567890"), 1, 20, S("2345678901234567890")); + test(S("abcdefghij"), 0, 10, SV("12345678901234567890"), 10, 0, S("")); + test(S("abcdefghij"), 0, 10, SV("12345678901234567890"), 10, 1, S("1")); + test(S("abcdefghij"), 0, 10, SV("12345678901234567890"), 10, 5, S("12345")); + test(S("abcdefghij"), 0, 10, SV("12345678901234567890"), 10, 9, S("123456789")); + test(S("abcdefghij"), 0, 10, SV("12345678901234567890"), 10, 10, S("1234567890")); + test(S("abcdefghij"), 0, 10, SV("12345678901234567890"), 10, 11, S("1234567890")); + test(S("abcdefghij"), 0, 10, SV("12345678901234567890"), 19, 0, S("")); + test(S("abcdefghij"), 0, 10, SV("12345678901234567890"), 19, 1, S("0")); + test(S("abcdefghij"), 0, 10, SV("12345678901234567890"), 19, 2, S("0")); + test(S("abcdefghij"), 0, 10, SV("12345678901234567890"), 20, 0, S("")); + test(S("abcdefghij"), 0, 10, SV("12345678901234567890"), 20, 1, S("")); + test(S("abcdefghij"), 0, 10, SV("12345678901234567890"), 21, 0, S("can't happen")); + test(S("abcdefghij"), 0, 11, SV(""), 0, 0, S("")); + test(S("abcdefghij"), 0, 11, SV(""), 0, 1, S("")); + test(S("abcdefghij"), 0, 11, SV(""), 1, 0, S("can't happen")); + test(S("abcdefghij"), 0, 11, SV("12345"), 0, 0, S("")); + test(S("abcdefghij"), 0, 11, SV("12345"), 0, 1, S("1")); + test(S("abcdefghij"), 0, 11, SV("12345"), 0, 2, S("12")); +} + +template +void test23() +{ + test(S("abcdefghij"), 0, 11, SV("12345"), 0, 4, S("1234")); + test(S("abcdefghij"), 0, 11, SV("12345"), 0, 5, S("12345")); + test(S("abcdefghij"), 0, 11, SV("12345"), 0, 6, S("12345")); + test(S("abcdefghij"), 0, 11, SV("12345"), 1, 0, S("")); + test(S("abcdefghij"), 0, 11, SV("12345"), 1, 1, S("2")); + test(S("abcdefghij"), 0, 11, SV("12345"), 1, 2, S("23")); + test(S("abcdefghij"), 0, 11, SV("12345"), 1, 3, S("234")); + test(S("abcdefghij"), 0, 11, SV("12345"), 1, 4, S("2345")); + test(S("abcdefghij"), 0, 11, SV("12345"), 1, 5, S("2345")); + test(S("abcdefghij"), 0, 11, SV("12345"), 2, 0, S("")); + test(S("abcdefghij"), 0, 11, SV("12345"), 2, 1, S("3")); + test(S("abcdefghij"), 0, 11, SV("12345"), 2, 2, S("34")); + test(S("abcdefghij"), 0, 11, SV("12345"), 2, 3, S("345")); + test(S("abcdefghij"), 0, 11, SV("12345"), 2, 4, S("345")); + test(S("abcdefghij"), 0, 11, SV("12345"), 4, 0, S("")); + test(S("abcdefghij"), 0, 11, SV("12345"), 4, 1, S("5")); + test(S("abcdefghij"), 0, 11, SV("12345"), 4, 2, S("5")); + test(S("abcdefghij"), 0, 11, SV("12345"), 5, 0, S("")); + test(S("abcdefghij"), 0, 11, SV("12345"), 5, 1, S("")); + test(S("abcdefghij"), 0, 11, SV("12345"), 6, 0, S("can't happen")); + test(S("abcdefghij"), 0, 11, SV("1234567890"), 0, 0, S("")); + test(S("abcdefghij"), 0, 11, SV("1234567890"), 0, 1, S("1")); + test(S("abcdefghij"), 0, 11, SV("1234567890"), 0, 5, S("12345")); + test(S("abcdefghij"), 0, 11, SV("1234567890"), 0, 9, S("123456789")); + test(S("abcdefghij"), 0, 11, SV("1234567890"), 0, 10, S("1234567890")); + test(S("abcdefghij"), 0, 11, SV("1234567890"), 0, 11, S("1234567890")); + test(S("abcdefghij"), 0, 11, SV("1234567890"), 1, 0, S("")); + test(S("abcdefghij"), 0, 11, SV("1234567890"), 1, 1, S("2")); + test(S("abcdefghij"), 0, 11, SV("1234567890"), 1, 4, S("2345")); + test(S("abcdefghij"), 0, 11, SV("1234567890"), 1, 8, S("23456789")); + test(S("abcdefghij"), 0, 11, SV("1234567890"), 1, 9, S("234567890")); + test(S("abcdefghij"), 0, 11, SV("1234567890"), 1, 10, S("234567890")); + test(S("abcdefghij"), 0, 11, SV("1234567890"), 5, 0, S("")); + test(S("abcdefghij"), 0, 11, SV("1234567890"), 5, 1, S("6")); + test(S("abcdefghij"), 0, 11, SV("1234567890"), 5, 2, S("67")); + test(S("abcdefghij"), 0, 11, SV("1234567890"), 5, 4, S("6789")); + test(S("abcdefghij"), 0, 11, SV("1234567890"), 5, 5, S("67890")); + test(S("abcdefghij"), 0, 11, SV("1234567890"), 5, 6, S("67890")); + test(S("abcdefghij"), 0, 11, SV("1234567890"), 9, 0, S("")); + test(S("abcdefghij"), 0, 11, SV("1234567890"), 9, 1, S("0")); + test(S("abcdefghij"), 0, 11, SV("1234567890"), 9, 2, S("0")); + test(S("abcdefghij"), 0, 11, SV("1234567890"), 10, 0, S("")); + test(S("abcdefghij"), 0, 11, SV("1234567890"), 10, 1, S("")); + test(S("abcdefghij"), 0, 11, SV("1234567890"), 11, 0, S("can't happen")); + test(S("abcdefghij"), 0, 11, SV("12345678901234567890"), 0, 0, S("")); + test(S("abcdefghij"), 0, 11, SV("12345678901234567890"), 0, 1, S("1")); + test(S("abcdefghij"), 0, 11, SV("12345678901234567890"), 0, 10, S("1234567890")); + test(S("abcdefghij"), 0, 11, SV("12345678901234567890"), 0, 19, S("1234567890123456789")); + test(S("abcdefghij"), 0, 11, SV("12345678901234567890"), 0, 20, S("12345678901234567890")); + test(S("abcdefghij"), 0, 11, SV("12345678901234567890"), 0, 21, S("12345678901234567890")); + test(S("abcdefghij"), 0, 11, SV("12345678901234567890"), 1, 0, S("")); + test(S("abcdefghij"), 0, 11, SV("12345678901234567890"), 1, 1, S("2")); + test(S("abcdefghij"), 0, 11, SV("12345678901234567890"), 1, 9, S("234567890")); + test(S("abcdefghij"), 0, 11, SV("12345678901234567890"), 1, 18, S("234567890123456789")); + test(S("abcdefghij"), 0, 11, SV("12345678901234567890"), 1, 19, S("2345678901234567890")); + test(S("abcdefghij"), 0, 11, SV("12345678901234567890"), 1, 20, S("2345678901234567890")); + test(S("abcdefghij"), 0, 11, SV("12345678901234567890"), 10, 0, S("")); + test(S("abcdefghij"), 0, 11, SV("12345678901234567890"), 10, 1, S("1")); + test(S("abcdefghij"), 0, 11, SV("12345678901234567890"), 10, 5, S("12345")); + test(S("abcdefghij"), 0, 11, SV("12345678901234567890"), 10, 9, S("123456789")); + test(S("abcdefghij"), 0, 11, SV("12345678901234567890"), 10, 10, S("1234567890")); + test(S("abcdefghij"), 0, 11, SV("12345678901234567890"), 10, 11, S("1234567890")); + test(S("abcdefghij"), 0, 11, SV("12345678901234567890"), 19, 0, S("")); + test(S("abcdefghij"), 0, 11, SV("12345678901234567890"), 19, 1, S("0")); + test(S("abcdefghij"), 0, 11, SV("12345678901234567890"), 19, 2, S("0")); + test(S("abcdefghij"), 0, 11, SV("12345678901234567890"), 20, 0, S("")); + test(S("abcdefghij"), 0, 11, SV("12345678901234567890"), 20, 1, S("")); + test(S("abcdefghij"), 0, 11, SV("12345678901234567890"), 21, 0, S("can't happen")); + test(S("abcdefghij"), 1, 0, SV(""), 0, 0, S("abcdefghij")); + test(S("abcdefghij"), 1, 0, SV(""), 0, 1, S("abcdefghij")); + test(S("abcdefghij"), 1, 0, SV(""), 1, 0, S("can't happen")); + test(S("abcdefghij"), 1, 0, SV("12345"), 0, 0, S("abcdefghij")); + test(S("abcdefghij"), 1, 0, SV("12345"), 0, 1, S("a1bcdefghij")); + test(S("abcdefghij"), 1, 0, SV("12345"), 0, 2, S("a12bcdefghij")); + test(S("abcdefghij"), 1, 0, SV("12345"), 0, 4, S("a1234bcdefghij")); + test(S("abcdefghij"), 1, 0, SV("12345"), 0, 5, S("a12345bcdefghij")); + test(S("abcdefghij"), 1, 0, SV("12345"), 0, 6, S("a12345bcdefghij")); + test(S("abcdefghij"), 1, 0, SV("12345"), 1, 0, S("abcdefghij")); + test(S("abcdefghij"), 1, 0, SV("12345"), 1, 1, S("a2bcdefghij")); + test(S("abcdefghij"), 1, 0, SV("12345"), 1, 2, S("a23bcdefghij")); + test(S("abcdefghij"), 1, 0, SV("12345"), 1, 3, S("a234bcdefghij")); + test(S("abcdefghij"), 1, 0, SV("12345"), 1, 4, S("a2345bcdefghij")); + test(S("abcdefghij"), 1, 0, SV("12345"), 1, 5, S("a2345bcdefghij")); + test(S("abcdefghij"), 1, 0, SV("12345"), 2, 0, S("abcdefghij")); + test(S("abcdefghij"), 1, 0, SV("12345"), 2, 1, S("a3bcdefghij")); + test(S("abcdefghij"), 1, 0, SV("12345"), 2, 2, S("a34bcdefghij")); + test(S("abcdefghij"), 1, 0, SV("12345"), 2, 3, S("a345bcdefghij")); + test(S("abcdefghij"), 1, 0, SV("12345"), 2, 4, S("a345bcdefghij")); + test(S("abcdefghij"), 1, 0, SV("12345"), 4, 0, S("abcdefghij")); + test(S("abcdefghij"), 1, 0, SV("12345"), 4, 1, S("a5bcdefghij")); + test(S("abcdefghij"), 1, 0, SV("12345"), 4, 2, S("a5bcdefghij")); + test(S("abcdefghij"), 1, 0, SV("12345"), 5, 0, S("abcdefghij")); + test(S("abcdefghij"), 1, 0, SV("12345"), 5, 1, S("abcdefghij")); + test(S("abcdefghij"), 1, 0, SV("12345"), 6, 0, S("can't happen")); + test(S("abcdefghij"), 1, 0, SV("1234567890"), 0, 0, S("abcdefghij")); + test(S("abcdefghij"), 1, 0, SV("1234567890"), 0, 1, S("a1bcdefghij")); + test(S("abcdefghij"), 1, 0, SV("1234567890"), 0, 5, S("a12345bcdefghij")); + test(S("abcdefghij"), 1, 0, SV("1234567890"), 0, 9, S("a123456789bcdefghij")); + test(S("abcdefghij"), 1, 0, SV("1234567890"), 0, 10, S("a1234567890bcdefghij")); + test(S("abcdefghij"), 1, 0, SV("1234567890"), 0, 11, S("a1234567890bcdefghij")); +} + +template +void test24() +{ + test(S("abcdefghij"), 1, 0, SV("1234567890"), 1, 0, S("abcdefghij")); + test(S("abcdefghij"), 1, 0, SV("1234567890"), 1, 1, S("a2bcdefghij")); + test(S("abcdefghij"), 1, 0, SV("1234567890"), 1, 4, S("a2345bcdefghij")); + test(S("abcdefghij"), 1, 0, SV("1234567890"), 1, 8, S("a23456789bcdefghij")); + test(S("abcdefghij"), 1, 0, SV("1234567890"), 1, 9, S("a234567890bcdefghij")); + test(S("abcdefghij"), 1, 0, SV("1234567890"), 1, 10, S("a234567890bcdefghij")); + test(S("abcdefghij"), 1, 0, SV("1234567890"), 5, 0, S("abcdefghij")); + test(S("abcdefghij"), 1, 0, SV("1234567890"), 5, 1, S("a6bcdefghij")); + test(S("abcdefghij"), 1, 0, SV("1234567890"), 5, 2, S("a67bcdefghij")); + test(S("abcdefghij"), 1, 0, SV("1234567890"), 5, 4, S("a6789bcdefghij")); + test(S("abcdefghij"), 1, 0, SV("1234567890"), 5, 5, S("a67890bcdefghij")); + test(S("abcdefghij"), 1, 0, SV("1234567890"), 5, 6, S("a67890bcdefghij")); + test(S("abcdefghij"), 1, 0, SV("1234567890"), 9, 0, S("abcdefghij")); + test(S("abcdefghij"), 1, 0, SV("1234567890"), 9, 1, S("a0bcdefghij")); + test(S("abcdefghij"), 1, 0, SV("1234567890"), 9, 2, S("a0bcdefghij")); + test(S("abcdefghij"), 1, 0, SV("1234567890"), 10, 0, S("abcdefghij")); + test(S("abcdefghij"), 1, 0, SV("1234567890"), 10, 1, S("abcdefghij")); + test(S("abcdefghij"), 1, 0, SV("1234567890"), 11, 0, S("can't happen")); + test(S("abcdefghij"), 1, 0, SV("12345678901234567890"), 0, 0, S("abcdefghij")); + test(S("abcdefghij"), 1, 0, SV("12345678901234567890"), 0, 1, S("a1bcdefghij")); + test(S("abcdefghij"), 1, 0, SV("12345678901234567890"), 0, 10, S("a1234567890bcdefghij")); + test(S("abcdefghij"), 1, 0, SV("12345678901234567890"), 0, 19, S("a1234567890123456789bcdefghij")); + test(S("abcdefghij"), 1, 0, SV("12345678901234567890"), 0, 20, S("a12345678901234567890bcdefghij")); + test(S("abcdefghij"), 1, 0, SV("12345678901234567890"), 0, 21, S("a12345678901234567890bcdefghij")); + test(S("abcdefghij"), 1, 0, SV("12345678901234567890"), 1, 0, S("abcdefghij")); + test(S("abcdefghij"), 1, 0, SV("12345678901234567890"), 1, 1, S("a2bcdefghij")); + test(S("abcdefghij"), 1, 0, SV("12345678901234567890"), 1, 9, S("a234567890bcdefghij")); + test(S("abcdefghij"), 1, 0, SV("12345678901234567890"), 1, 18, S("a234567890123456789bcdefghij")); + test(S("abcdefghij"), 1, 0, SV("12345678901234567890"), 1, 19, S("a2345678901234567890bcdefghij")); + test(S("abcdefghij"), 1, 0, SV("12345678901234567890"), 1, 20, S("a2345678901234567890bcdefghij")); + test(S("abcdefghij"), 1, 0, SV("12345678901234567890"), 10, 0, S("abcdefghij")); + test(S("abcdefghij"), 1, 0, SV("12345678901234567890"), 10, 1, S("a1bcdefghij")); + test(S("abcdefghij"), 1, 0, SV("12345678901234567890"), 10, 5, S("a12345bcdefghij")); + test(S("abcdefghij"), 1, 0, SV("12345678901234567890"), 10, 9, S("a123456789bcdefghij")); + test(S("abcdefghij"), 1, 0, SV("12345678901234567890"), 10, 10, S("a1234567890bcdefghij")); + test(S("abcdefghij"), 1, 0, SV("12345678901234567890"), 10, 11, S("a1234567890bcdefghij")); + test(S("abcdefghij"), 1, 0, SV("12345678901234567890"), 19, 0, S("abcdefghij")); + test(S("abcdefghij"), 1, 0, SV("12345678901234567890"), 19, 1, S("a0bcdefghij")); + test(S("abcdefghij"), 1, 0, SV("12345678901234567890"), 19, 2, S("a0bcdefghij")); + test(S("abcdefghij"), 1, 0, SV("12345678901234567890"), 20, 0, S("abcdefghij")); + test(S("abcdefghij"), 1, 0, SV("12345678901234567890"), 20, 1, S("abcdefghij")); + test(S("abcdefghij"), 1, 0, SV("12345678901234567890"), 21, 0, S("can't happen")); + test(S("abcdefghij"), 1, 1, SV(""), 0, 0, S("acdefghij")); + test(S("abcdefghij"), 1, 1, SV(""), 0, 1, S("acdefghij")); + test(S("abcdefghij"), 1, 1, SV(""), 1, 0, S("can't happen")); + test(S("abcdefghij"), 1, 1, SV("12345"), 0, 0, S("acdefghij")); + test(S("abcdefghij"), 1, 1, SV("12345"), 0, 1, S("a1cdefghij")); + test(S("abcdefghij"), 1, 1, SV("12345"), 0, 2, S("a12cdefghij")); + test(S("abcdefghij"), 1, 1, SV("12345"), 0, 4, S("a1234cdefghij")); + test(S("abcdefghij"), 1, 1, SV("12345"), 0, 5, S("a12345cdefghij")); + test(S("abcdefghij"), 1, 1, SV("12345"), 0, 6, S("a12345cdefghij")); + test(S("abcdefghij"), 1, 1, SV("12345"), 1, 0, S("acdefghij")); + test(S("abcdefghij"), 1, 1, SV("12345"), 1, 1, S("a2cdefghij")); + test(S("abcdefghij"), 1, 1, SV("12345"), 1, 2, S("a23cdefghij")); + test(S("abcdefghij"), 1, 1, SV("12345"), 1, 3, S("a234cdefghij")); + test(S("abcdefghij"), 1, 1, SV("12345"), 1, 4, S("a2345cdefghij")); + test(S("abcdefghij"), 1, 1, SV("12345"), 1, 5, S("a2345cdefghij")); + test(S("abcdefghij"), 1, 1, SV("12345"), 2, 0, S("acdefghij")); + test(S("abcdefghij"), 1, 1, SV("12345"), 2, 1, S("a3cdefghij")); + test(S("abcdefghij"), 1, 1, SV("12345"), 2, 2, S("a34cdefghij")); + test(S("abcdefghij"), 1, 1, SV("12345"), 2, 3, S("a345cdefghij")); + test(S("abcdefghij"), 1, 1, SV("12345"), 2, 4, S("a345cdefghij")); + test(S("abcdefghij"), 1, 1, SV("12345"), 4, 0, S("acdefghij")); + test(S("abcdefghij"), 1, 1, SV("12345"), 4, 1, S("a5cdefghij")); + test(S("abcdefghij"), 1, 1, SV("12345"), 4, 2, S("a5cdefghij")); + test(S("abcdefghij"), 1, 1, SV("12345"), 5, 0, S("acdefghij")); + test(S("abcdefghij"), 1, 1, SV("12345"), 5, 1, S("acdefghij")); + test(S("abcdefghij"), 1, 1, SV("12345"), 6, 0, S("can't happen")); + test(S("abcdefghij"), 1, 1, SV("1234567890"), 0, 0, S("acdefghij")); + test(S("abcdefghij"), 1, 1, SV("1234567890"), 0, 1, S("a1cdefghij")); + test(S("abcdefghij"), 1, 1, SV("1234567890"), 0, 5, S("a12345cdefghij")); + test(S("abcdefghij"), 1, 1, SV("1234567890"), 0, 9, S("a123456789cdefghij")); + test(S("abcdefghij"), 1, 1, SV("1234567890"), 0, 10, S("a1234567890cdefghij")); + test(S("abcdefghij"), 1, 1, SV("1234567890"), 0, 11, S("a1234567890cdefghij")); + test(S("abcdefghij"), 1, 1, SV("1234567890"), 1, 0, S("acdefghij")); + test(S("abcdefghij"), 1, 1, SV("1234567890"), 1, 1, S("a2cdefghij")); + test(S("abcdefghij"), 1, 1, SV("1234567890"), 1, 4, S("a2345cdefghij")); + test(S("abcdefghij"), 1, 1, SV("1234567890"), 1, 8, S("a23456789cdefghij")); + test(S("abcdefghij"), 1, 1, SV("1234567890"), 1, 9, S("a234567890cdefghij")); + test(S("abcdefghij"), 1, 1, SV("1234567890"), 1, 10, S("a234567890cdefghij")); + test(S("abcdefghij"), 1, 1, SV("1234567890"), 5, 0, S("acdefghij")); + test(S("abcdefghij"), 1, 1, SV("1234567890"), 5, 1, S("a6cdefghij")); + test(S("abcdefghij"), 1, 1, SV("1234567890"), 5, 2, S("a67cdefghij")); + test(S("abcdefghij"), 1, 1, SV("1234567890"), 5, 4, S("a6789cdefghij")); + test(S("abcdefghij"), 1, 1, SV("1234567890"), 5, 5, S("a67890cdefghij")); + test(S("abcdefghij"), 1, 1, SV("1234567890"), 5, 6, S("a67890cdefghij")); + test(S("abcdefghij"), 1, 1, SV("1234567890"), 9, 0, S("acdefghij")); + test(S("abcdefghij"), 1, 1, SV("1234567890"), 9, 1, S("a0cdefghij")); + test(S("abcdefghij"), 1, 1, SV("1234567890"), 9, 2, S("a0cdefghij")); + test(S("abcdefghij"), 1, 1, SV("1234567890"), 10, 0, S("acdefghij")); + test(S("abcdefghij"), 1, 1, SV("1234567890"), 10, 1, S("acdefghij")); + test(S("abcdefghij"), 1, 1, SV("1234567890"), 11, 0, S("can't happen")); + test(S("abcdefghij"), 1, 1, SV("12345678901234567890"), 0, 0, S("acdefghij")); + test(S("abcdefghij"), 1, 1, SV("12345678901234567890"), 0, 1, S("a1cdefghij")); + test(S("abcdefghij"), 1, 1, SV("12345678901234567890"), 0, 10, S("a1234567890cdefghij")); + test(S("abcdefghij"), 1, 1, SV("12345678901234567890"), 0, 19, S("a1234567890123456789cdefghij")); + test(S("abcdefghij"), 1, 1, SV("12345678901234567890"), 0, 20, S("a12345678901234567890cdefghij")); + test(S("abcdefghij"), 1, 1, SV("12345678901234567890"), 0, 21, S("a12345678901234567890cdefghij")); + test(S("abcdefghij"), 1, 1, SV("12345678901234567890"), 1, 0, S("acdefghij")); + test(S("abcdefghij"), 1, 1, SV("12345678901234567890"), 1, 1, S("a2cdefghij")); +} + +template +void test25() +{ + test(S("abcdefghij"), 1, 1, SV("12345678901234567890"), 1, 9, S("a234567890cdefghij")); + test(S("abcdefghij"), 1, 1, SV("12345678901234567890"), 1, 18, S("a234567890123456789cdefghij")); + test(S("abcdefghij"), 1, 1, SV("12345678901234567890"), 1, 19, S("a2345678901234567890cdefghij")); + test(S("abcdefghij"), 1, 1, SV("12345678901234567890"), 1, 20, S("a2345678901234567890cdefghij")); + test(S("abcdefghij"), 1, 1, SV("12345678901234567890"), 10, 0, S("acdefghij")); + test(S("abcdefghij"), 1, 1, SV("12345678901234567890"), 10, 1, S("a1cdefghij")); + test(S("abcdefghij"), 1, 1, SV("12345678901234567890"), 10, 5, S("a12345cdefghij")); + test(S("abcdefghij"), 1, 1, SV("12345678901234567890"), 10, 9, S("a123456789cdefghij")); + test(S("abcdefghij"), 1, 1, SV("12345678901234567890"), 10, 10, S("a1234567890cdefghij")); + test(S("abcdefghij"), 1, 1, SV("12345678901234567890"), 10, 11, S("a1234567890cdefghij")); + test(S("abcdefghij"), 1, 1, SV("12345678901234567890"), 19, 0, S("acdefghij")); + test(S("abcdefghij"), 1, 1, SV("12345678901234567890"), 19, 1, S("a0cdefghij")); + test(S("abcdefghij"), 1, 1, SV("12345678901234567890"), 19, 2, S("a0cdefghij")); + test(S("abcdefghij"), 1, 1, SV("12345678901234567890"), 20, 0, S("acdefghij")); + test(S("abcdefghij"), 1, 1, SV("12345678901234567890"), 20, 1, S("acdefghij")); + test(S("abcdefghij"), 1, 1, SV("12345678901234567890"), 21, 0, S("can't happen")); + test(S("abcdefghij"), 1, 4, SV(""), 0, 0, S("afghij")); + test(S("abcdefghij"), 1, 4, SV(""), 0, 1, S("afghij")); + test(S("abcdefghij"), 1, 4, SV(""), 1, 0, S("can't happen")); + test(S("abcdefghij"), 1, 4, SV("12345"), 0, 0, S("afghij")); + test(S("abcdefghij"), 1, 4, SV("12345"), 0, 1, S("a1fghij")); + test(S("abcdefghij"), 1, 4, SV("12345"), 0, 2, S("a12fghij")); + test(S("abcdefghij"), 1, 4, SV("12345"), 0, 4, S("a1234fghij")); + test(S("abcdefghij"), 1, 4, SV("12345"), 0, 5, S("a12345fghij")); + test(S("abcdefghij"), 1, 4, SV("12345"), 0, 6, S("a12345fghij")); + test(S("abcdefghij"), 1, 4, SV("12345"), 1, 0, S("afghij")); + test(S("abcdefghij"), 1, 4, SV("12345"), 1, 1, S("a2fghij")); + test(S("abcdefghij"), 1, 4, SV("12345"), 1, 2, S("a23fghij")); + test(S("abcdefghij"), 1, 4, SV("12345"), 1, 3, S("a234fghij")); + test(S("abcdefghij"), 1, 4, SV("12345"), 1, 4, S("a2345fghij")); + test(S("abcdefghij"), 1, 4, SV("12345"), 1, 5, S("a2345fghij")); + test(S("abcdefghij"), 1, 4, SV("12345"), 2, 0, S("afghij")); + test(S("abcdefghij"), 1, 4, SV("12345"), 2, 1, S("a3fghij")); + test(S("abcdefghij"), 1, 4, SV("12345"), 2, 2, S("a34fghij")); + test(S("abcdefghij"), 1, 4, SV("12345"), 2, 3, S("a345fghij")); + test(S("abcdefghij"), 1, 4, SV("12345"), 2, 4, S("a345fghij")); + test(S("abcdefghij"), 1, 4, SV("12345"), 4, 0, S("afghij")); + test(S("abcdefghij"), 1, 4, SV("12345"), 4, 1, S("a5fghij")); + test(S("abcdefghij"), 1, 4, SV("12345"), 4, 2, S("a5fghij")); + test(S("abcdefghij"), 1, 4, SV("12345"), 5, 0, S("afghij")); + test(S("abcdefghij"), 1, 4, SV("12345"), 5, 1, S("afghij")); + test(S("abcdefghij"), 1, 4, SV("12345"), 6, 0, S("can't happen")); + test(S("abcdefghij"), 1, 4, SV("1234567890"), 0, 0, S("afghij")); + test(S("abcdefghij"), 1, 4, SV("1234567890"), 0, 1, S("a1fghij")); + test(S("abcdefghij"), 1, 4, SV("1234567890"), 0, 5, S("a12345fghij")); + test(S("abcdefghij"), 1, 4, SV("1234567890"), 0, 9, S("a123456789fghij")); + test(S("abcdefghij"), 1, 4, SV("1234567890"), 0, 10, S("a1234567890fghij")); + test(S("abcdefghij"), 1, 4, SV("1234567890"), 0, 11, S("a1234567890fghij")); + test(S("abcdefghij"), 1, 4, SV("1234567890"), 1, 0, S("afghij")); + test(S("abcdefghij"), 1, 4, SV("1234567890"), 1, 1, S("a2fghij")); + test(S("abcdefghij"), 1, 4, SV("1234567890"), 1, 4, S("a2345fghij")); + test(S("abcdefghij"), 1, 4, SV("1234567890"), 1, 8, S("a23456789fghij")); + test(S("abcdefghij"), 1, 4, SV("1234567890"), 1, 9, S("a234567890fghij")); + test(S("abcdefghij"), 1, 4, SV("1234567890"), 1, 10, S("a234567890fghij")); + test(S("abcdefghij"), 1, 4, SV("1234567890"), 5, 0, S("afghij")); + test(S("abcdefghij"), 1, 4, SV("1234567890"), 5, 1, S("a6fghij")); + test(S("abcdefghij"), 1, 4, SV("1234567890"), 5, 2, S("a67fghij")); + test(S("abcdefghij"), 1, 4, SV("1234567890"), 5, 4, S("a6789fghij")); + test(S("abcdefghij"), 1, 4, SV("1234567890"), 5, 5, S("a67890fghij")); + test(S("abcdefghij"), 1, 4, SV("1234567890"), 5, 6, S("a67890fghij")); + test(S("abcdefghij"), 1, 4, SV("1234567890"), 9, 0, S("afghij")); + test(S("abcdefghij"), 1, 4, SV("1234567890"), 9, 1, S("a0fghij")); + test(S("abcdefghij"), 1, 4, SV("1234567890"), 9, 2, S("a0fghij")); + test(S("abcdefghij"), 1, 4, SV("1234567890"), 10, 0, S("afghij")); + test(S("abcdefghij"), 1, 4, SV("1234567890"), 10, 1, S("afghij")); + test(S("abcdefghij"), 1, 4, SV("1234567890"), 11, 0, S("can't happen")); + test(S("abcdefghij"), 1, 4, SV("12345678901234567890"), 0, 0, S("afghij")); + test(S("abcdefghij"), 1, 4, SV("12345678901234567890"), 0, 1, S("a1fghij")); + test(S("abcdefghij"), 1, 4, SV("12345678901234567890"), 0, 10, S("a1234567890fghij")); + test(S("abcdefghij"), 1, 4, SV("12345678901234567890"), 0, 19, S("a1234567890123456789fghij")); + test(S("abcdefghij"), 1, 4, SV("12345678901234567890"), 0, 20, S("a12345678901234567890fghij")); + test(S("abcdefghij"), 1, 4, SV("12345678901234567890"), 0, 21, S("a12345678901234567890fghij")); + test(S("abcdefghij"), 1, 4, SV("12345678901234567890"), 1, 0, S("afghij")); + test(S("abcdefghij"), 1, 4, SV("12345678901234567890"), 1, 1, S("a2fghij")); + test(S("abcdefghij"), 1, 4, SV("12345678901234567890"), 1, 9, S("a234567890fghij")); + test(S("abcdefghij"), 1, 4, SV("12345678901234567890"), 1, 18, S("a234567890123456789fghij")); + test(S("abcdefghij"), 1, 4, SV("12345678901234567890"), 1, 19, S("a2345678901234567890fghij")); + test(S("abcdefghij"), 1, 4, SV("12345678901234567890"), 1, 20, S("a2345678901234567890fghij")); + test(S("abcdefghij"), 1, 4, SV("12345678901234567890"), 10, 0, S("afghij")); + test(S("abcdefghij"), 1, 4, SV("12345678901234567890"), 10, 1, S("a1fghij")); + test(S("abcdefghij"), 1, 4, SV("12345678901234567890"), 10, 5, S("a12345fghij")); + test(S("abcdefghij"), 1, 4, SV("12345678901234567890"), 10, 9, S("a123456789fghij")); + test(S("abcdefghij"), 1, 4, SV("12345678901234567890"), 10, 10, S("a1234567890fghij")); + test(S("abcdefghij"), 1, 4, SV("12345678901234567890"), 10, 11, S("a1234567890fghij")); + test(S("abcdefghij"), 1, 4, SV("12345678901234567890"), 19, 0, S("afghij")); + test(S("abcdefghij"), 1, 4, SV("12345678901234567890"), 19, 1, S("a0fghij")); + test(S("abcdefghij"), 1, 4, SV("12345678901234567890"), 19, 2, S("a0fghij")); + test(S("abcdefghij"), 1, 4, SV("12345678901234567890"), 20, 0, S("afghij")); + test(S("abcdefghij"), 1, 4, SV("12345678901234567890"), 20, 1, S("afghij")); + test(S("abcdefghij"), 1, 4, SV("12345678901234567890"), 21, 0, S("can't happen")); + test(S("abcdefghij"), 1, 8, SV(""), 0, 0, S("aj")); + test(S("abcdefghij"), 1, 8, SV(""), 0, 1, S("aj")); + test(S("abcdefghij"), 1, 8, SV(""), 1, 0, S("can't happen")); + test(S("abcdefghij"), 1, 8, SV("12345"), 0, 0, S("aj")); + test(S("abcdefghij"), 1, 8, SV("12345"), 0, 1, S("a1j")); + test(S("abcdefghij"), 1, 8, SV("12345"), 0, 2, S("a12j")); + test(S("abcdefghij"), 1, 8, SV("12345"), 0, 4, S("a1234j")); + test(S("abcdefghij"), 1, 8, SV("12345"), 0, 5, S("a12345j")); + test(S("abcdefghij"), 1, 8, SV("12345"), 0, 6, S("a12345j")); + test(S("abcdefghij"), 1, 8, SV("12345"), 1, 0, S("aj")); +} + +template +void test26() +{ + test(S("abcdefghij"), 1, 8, SV("12345"), 1, 1, S("a2j")); + test(S("abcdefghij"), 1, 8, SV("12345"), 1, 2, S("a23j")); + test(S("abcdefghij"), 1, 8, SV("12345"), 1, 3, S("a234j")); + test(S("abcdefghij"), 1, 8, SV("12345"), 1, 4, S("a2345j")); + test(S("abcdefghij"), 1, 8, SV("12345"), 1, 5, S("a2345j")); + test(S("abcdefghij"), 1, 8, SV("12345"), 2, 0, S("aj")); + test(S("abcdefghij"), 1, 8, SV("12345"), 2, 1, S("a3j")); + test(S("abcdefghij"), 1, 8, SV("12345"), 2, 2, S("a34j")); + test(S("abcdefghij"), 1, 8, SV("12345"), 2, 3, S("a345j")); + test(S("abcdefghij"), 1, 8, SV("12345"), 2, 4, S("a345j")); + test(S("abcdefghij"), 1, 8, SV("12345"), 4, 0, S("aj")); + test(S("abcdefghij"), 1, 8, SV("12345"), 4, 1, S("a5j")); + test(S("abcdefghij"), 1, 8, SV("12345"), 4, 2, S("a5j")); + test(S("abcdefghij"), 1, 8, SV("12345"), 5, 0, S("aj")); + test(S("abcdefghij"), 1, 8, SV("12345"), 5, 1, S("aj")); + test(S("abcdefghij"), 1, 8, SV("12345"), 6, 0, S("can't happen")); + test(S("abcdefghij"), 1, 8, SV("1234567890"), 0, 0, S("aj")); + test(S("abcdefghij"), 1, 8, SV("1234567890"), 0, 1, S("a1j")); + test(S("abcdefghij"), 1, 8, SV("1234567890"), 0, 5, S("a12345j")); + test(S("abcdefghij"), 1, 8, SV("1234567890"), 0, 9, S("a123456789j")); + test(S("abcdefghij"), 1, 8, SV("1234567890"), 0, 10, S("a1234567890j")); + test(S("abcdefghij"), 1, 8, SV("1234567890"), 0, 11, S("a1234567890j")); + test(S("abcdefghij"), 1, 8, SV("1234567890"), 1, 0, S("aj")); + test(S("abcdefghij"), 1, 8, SV("1234567890"), 1, 1, S("a2j")); + test(S("abcdefghij"), 1, 8, SV("1234567890"), 1, 4, S("a2345j")); + test(S("abcdefghij"), 1, 8, SV("1234567890"), 1, 8, S("a23456789j")); + test(S("abcdefghij"), 1, 8, SV("1234567890"), 1, 9, S("a234567890j")); + test(S("abcdefghij"), 1, 8, SV("1234567890"), 1, 10, S("a234567890j")); + test(S("abcdefghij"), 1, 8, SV("1234567890"), 5, 0, S("aj")); + test(S("abcdefghij"), 1, 8, SV("1234567890"), 5, 1, S("a6j")); + test(S("abcdefghij"), 1, 8, SV("1234567890"), 5, 2, S("a67j")); + test(S("abcdefghij"), 1, 8, SV("1234567890"), 5, 4, S("a6789j")); + test(S("abcdefghij"), 1, 8, SV("1234567890"), 5, 5, S("a67890j")); + test(S("abcdefghij"), 1, 8, SV("1234567890"), 5, 6, S("a67890j")); + test(S("abcdefghij"), 1, 8, SV("1234567890"), 9, 0, S("aj")); + test(S("abcdefghij"), 1, 8, SV("1234567890"), 9, 1, S("a0j")); + test(S("abcdefghij"), 1, 8, SV("1234567890"), 9, 2, S("a0j")); + test(S("abcdefghij"), 1, 8, SV("1234567890"), 10, 0, S("aj")); + test(S("abcdefghij"), 1, 8, SV("1234567890"), 10, 1, S("aj")); + test(S("abcdefghij"), 1, 8, SV("1234567890"), 11, 0, S("can't happen")); + test(S("abcdefghij"), 1, 8, SV("12345678901234567890"), 0, 0, S("aj")); + test(S("abcdefghij"), 1, 8, SV("12345678901234567890"), 0, 1, S("a1j")); + test(S("abcdefghij"), 1, 8, SV("12345678901234567890"), 0, 10, S("a1234567890j")); + test(S("abcdefghij"), 1, 8, SV("12345678901234567890"), 0, 19, S("a1234567890123456789j")); + test(S("abcdefghij"), 1, 8, SV("12345678901234567890"), 0, 20, S("a12345678901234567890j")); + test(S("abcdefghij"), 1, 8, SV("12345678901234567890"), 0, 21, S("a12345678901234567890j")); + test(S("abcdefghij"), 1, 8, SV("12345678901234567890"), 1, 0, S("aj")); + test(S("abcdefghij"), 1, 8, SV("12345678901234567890"), 1, 1, S("a2j")); + test(S("abcdefghij"), 1, 8, SV("12345678901234567890"), 1, 9, S("a234567890j")); + test(S("abcdefghij"), 1, 8, SV("12345678901234567890"), 1, 18, S("a234567890123456789j")); + test(S("abcdefghij"), 1, 8, SV("12345678901234567890"), 1, 19, S("a2345678901234567890j")); + test(S("abcdefghij"), 1, 8, SV("12345678901234567890"), 1, 20, S("a2345678901234567890j")); + test(S("abcdefghij"), 1, 8, SV("12345678901234567890"), 10, 0, S("aj")); + test(S("abcdefghij"), 1, 8, SV("12345678901234567890"), 10, 1, S("a1j")); + test(S("abcdefghij"), 1, 8, SV("12345678901234567890"), 10, 5, S("a12345j")); + test(S("abcdefghij"), 1, 8, SV("12345678901234567890"), 10, 9, S("a123456789j")); + test(S("abcdefghij"), 1, 8, SV("12345678901234567890"), 10, 10, S("a1234567890j")); + test(S("abcdefghij"), 1, 8, SV("12345678901234567890"), 10, 11, S("a1234567890j")); + test(S("abcdefghij"), 1, 8, SV("12345678901234567890"), 19, 0, S("aj")); + test(S("abcdefghij"), 1, 8, SV("12345678901234567890"), 19, 1, S("a0j")); + test(S("abcdefghij"), 1, 8, SV("12345678901234567890"), 19, 2, S("a0j")); + test(S("abcdefghij"), 1, 8, SV("12345678901234567890"), 20, 0, S("aj")); + test(S("abcdefghij"), 1, 8, SV("12345678901234567890"), 20, 1, S("aj")); + test(S("abcdefghij"), 1, 8, SV("12345678901234567890"), 21, 0, S("can't happen")); + test(S("abcdefghij"), 1, 9, SV(""), 0, 0, S("a")); + test(S("abcdefghij"), 1, 9, SV(""), 0, 1, S("a")); + test(S("abcdefghij"), 1, 9, SV(""), 1, 0, S("can't happen")); + test(S("abcdefghij"), 1, 9, SV("12345"), 0, 0, S("a")); + test(S("abcdefghij"), 1, 9, SV("12345"), 0, 1, S("a1")); + test(S("abcdefghij"), 1, 9, SV("12345"), 0, 2, S("a12")); + test(S("abcdefghij"), 1, 9, SV("12345"), 0, 4, S("a1234")); + test(S("abcdefghij"), 1, 9, SV("12345"), 0, 5, S("a12345")); + test(S("abcdefghij"), 1, 9, SV("12345"), 0, 6, S("a12345")); + test(S("abcdefghij"), 1, 9, SV("12345"), 1, 0, S("a")); + test(S("abcdefghij"), 1, 9, SV("12345"), 1, 1, S("a2")); + test(S("abcdefghij"), 1, 9, SV("12345"), 1, 2, S("a23")); + test(S("abcdefghij"), 1, 9, SV("12345"), 1, 3, S("a234")); + test(S("abcdefghij"), 1, 9, SV("12345"), 1, 4, S("a2345")); + test(S("abcdefghij"), 1, 9, SV("12345"), 1, 5, S("a2345")); + test(S("abcdefghij"), 1, 9, SV("12345"), 2, 0, S("a")); + test(S("abcdefghij"), 1, 9, SV("12345"), 2, 1, S("a3")); + test(S("abcdefghij"), 1, 9, SV("12345"), 2, 2, S("a34")); + test(S("abcdefghij"), 1, 9, SV("12345"), 2, 3, S("a345")); + test(S("abcdefghij"), 1, 9, SV("12345"), 2, 4, S("a345")); + test(S("abcdefghij"), 1, 9, SV("12345"), 4, 0, S("a")); + test(S("abcdefghij"), 1, 9, SV("12345"), 4, 1, S("a5")); + test(S("abcdefghij"), 1, 9, SV("12345"), 4, 2, S("a5")); + test(S("abcdefghij"), 1, 9, SV("12345"), 5, 0, S("a")); + test(S("abcdefghij"), 1, 9, SV("12345"), 5, 1, S("a")); + test(S("abcdefghij"), 1, 9, SV("12345"), 6, 0, S("can't happen")); + test(S("abcdefghij"), 1, 9, SV("1234567890"), 0, 0, S("a")); + test(S("abcdefghij"), 1, 9, SV("1234567890"), 0, 1, S("a1")); + test(S("abcdefghij"), 1, 9, SV("1234567890"), 0, 5, S("a12345")); + test(S("abcdefghij"), 1, 9, SV("1234567890"), 0, 9, S("a123456789")); + test(S("abcdefghij"), 1, 9, SV("1234567890"), 0, 10, S("a1234567890")); + test(S("abcdefghij"), 1, 9, SV("1234567890"), 0, 11, S("a1234567890")); + test(S("abcdefghij"), 1, 9, SV("1234567890"), 1, 0, S("a")); + test(S("abcdefghij"), 1, 9, SV("1234567890"), 1, 1, S("a2")); + test(S("abcdefghij"), 1, 9, SV("1234567890"), 1, 4, S("a2345")); + test(S("abcdefghij"), 1, 9, SV("1234567890"), 1, 8, S("a23456789")); +} + +template +void test27() +{ + test(S("abcdefghij"), 1, 9, SV("1234567890"), 1, 9, S("a234567890")); + test(S("abcdefghij"), 1, 9, SV("1234567890"), 1, 10, S("a234567890")); + test(S("abcdefghij"), 1, 9, SV("1234567890"), 5, 0, S("a")); + test(S("abcdefghij"), 1, 9, SV("1234567890"), 5, 1, S("a6")); + test(S("abcdefghij"), 1, 9, SV("1234567890"), 5, 2, S("a67")); + test(S("abcdefghij"), 1, 9, SV("1234567890"), 5, 4, S("a6789")); + test(S("abcdefghij"), 1, 9, SV("1234567890"), 5, 5, S("a67890")); + test(S("abcdefghij"), 1, 9, SV("1234567890"), 5, 6, S("a67890")); + test(S("abcdefghij"), 1, 9, SV("1234567890"), 9, 0, S("a")); + test(S("abcdefghij"), 1, 9, SV("1234567890"), 9, 1, S("a0")); + test(S("abcdefghij"), 1, 9, SV("1234567890"), 9, 2, S("a0")); + test(S("abcdefghij"), 1, 9, SV("1234567890"), 10, 0, S("a")); + test(S("abcdefghij"), 1, 9, SV("1234567890"), 10, 1, S("a")); + test(S("abcdefghij"), 1, 9, SV("1234567890"), 11, 0, S("can't happen")); + test(S("abcdefghij"), 1, 9, SV("12345678901234567890"), 0, 0, S("a")); + test(S("abcdefghij"), 1, 9, SV("12345678901234567890"), 0, 1, S("a1")); + test(S("abcdefghij"), 1, 9, SV("12345678901234567890"), 0, 10, S("a1234567890")); + test(S("abcdefghij"), 1, 9, SV("12345678901234567890"), 0, 19, S("a1234567890123456789")); + test(S("abcdefghij"), 1, 9, SV("12345678901234567890"), 0, 20, S("a12345678901234567890")); + test(S("abcdefghij"), 1, 9, SV("12345678901234567890"), 0, 21, S("a12345678901234567890")); + test(S("abcdefghij"), 1, 9, SV("12345678901234567890"), 1, 0, S("a")); + test(S("abcdefghij"), 1, 9, SV("12345678901234567890"), 1, 1, S("a2")); + test(S("abcdefghij"), 1, 9, SV("12345678901234567890"), 1, 9, S("a234567890")); + test(S("abcdefghij"), 1, 9, SV("12345678901234567890"), 1, 18, S("a234567890123456789")); + test(S("abcdefghij"), 1, 9, SV("12345678901234567890"), 1, 19, S("a2345678901234567890")); + test(S("abcdefghij"), 1, 9, SV("12345678901234567890"), 1, 20, S("a2345678901234567890")); + test(S("abcdefghij"), 1, 9, SV("12345678901234567890"), 10, 0, S("a")); + test(S("abcdefghij"), 1, 9, SV("12345678901234567890"), 10, 1, S("a1")); + test(S("abcdefghij"), 1, 9, SV("12345678901234567890"), 10, 5, S("a12345")); + test(S("abcdefghij"), 1, 9, SV("12345678901234567890"), 10, 9, S("a123456789")); + test(S("abcdefghij"), 1, 9, SV("12345678901234567890"), 10, 10, S("a1234567890")); + test(S("abcdefghij"), 1, 9, SV("12345678901234567890"), 10, 11, S("a1234567890")); + test(S("abcdefghij"), 1, 9, SV("12345678901234567890"), 19, 0, S("a")); + test(S("abcdefghij"), 1, 9, SV("12345678901234567890"), 19, 1, S("a0")); + test(S("abcdefghij"), 1, 9, SV("12345678901234567890"), 19, 2, S("a0")); + test(S("abcdefghij"), 1, 9, SV("12345678901234567890"), 20, 0, S("a")); + test(S("abcdefghij"), 1, 9, SV("12345678901234567890"), 20, 1, S("a")); + test(S("abcdefghij"), 1, 9, SV("12345678901234567890"), 21, 0, S("can't happen")); + test(S("abcdefghij"), 1, 10, SV(""), 0, 0, S("a")); + test(S("abcdefghij"), 1, 10, SV(""), 0, 1, S("a")); + test(S("abcdefghij"), 1, 10, SV(""), 1, 0, S("can't happen")); + test(S("abcdefghij"), 1, 10, SV("12345"), 0, 0, S("a")); + test(S("abcdefghij"), 1, 10, SV("12345"), 0, 1, S("a1")); + test(S("abcdefghij"), 1, 10, SV("12345"), 0, 2, S("a12")); + test(S("abcdefghij"), 1, 10, SV("12345"), 0, 4, S("a1234")); + test(S("abcdefghij"), 1, 10, SV("12345"), 0, 5, S("a12345")); + test(S("abcdefghij"), 1, 10, SV("12345"), 0, 6, S("a12345")); + test(S("abcdefghij"), 1, 10, SV("12345"), 1, 0, S("a")); + test(S("abcdefghij"), 1, 10, SV("12345"), 1, 1, S("a2")); + test(S("abcdefghij"), 1, 10, SV("12345"), 1, 2, S("a23")); + test(S("abcdefghij"), 1, 10, SV("12345"), 1, 3, S("a234")); + test(S("abcdefghij"), 1, 10, SV("12345"), 1, 4, S("a2345")); + test(S("abcdefghij"), 1, 10, SV("12345"), 1, 5, S("a2345")); + test(S("abcdefghij"), 1, 10, SV("12345"), 2, 0, S("a")); + test(S("abcdefghij"), 1, 10, SV("12345"), 2, 1, S("a3")); + test(S("abcdefghij"), 1, 10, SV("12345"), 2, 2, S("a34")); + test(S("abcdefghij"), 1, 10, SV("12345"), 2, 3, S("a345")); + test(S("abcdefghij"), 1, 10, SV("12345"), 2, 4, S("a345")); + test(S("abcdefghij"), 1, 10, SV("12345"), 4, 0, S("a")); + test(S("abcdefghij"), 1, 10, SV("12345"), 4, 1, S("a5")); + test(S("abcdefghij"), 1, 10, SV("12345"), 4, 2, S("a5")); + test(S("abcdefghij"), 1, 10, SV("12345"), 5, 0, S("a")); + test(S("abcdefghij"), 1, 10, SV("12345"), 5, 1, S("a")); + test(S("abcdefghij"), 1, 10, SV("12345"), 6, 0, S("can't happen")); + test(S("abcdefghij"), 1, 10, SV("1234567890"), 0, 0, S("a")); + test(S("abcdefghij"), 1, 10, SV("1234567890"), 0, 1, S("a1")); + test(S("abcdefghij"), 1, 10, SV("1234567890"), 0, 5, S("a12345")); + test(S("abcdefghij"), 1, 10, SV("1234567890"), 0, 9, S("a123456789")); + test(S("abcdefghij"), 1, 10, SV("1234567890"), 0, 10, S("a1234567890")); + test(S("abcdefghij"), 1, 10, SV("1234567890"), 0, 11, S("a1234567890")); + test(S("abcdefghij"), 1, 10, SV("1234567890"), 1, 0, S("a")); + test(S("abcdefghij"), 1, 10, SV("1234567890"), 1, 1, S("a2")); + test(S("abcdefghij"), 1, 10, SV("1234567890"), 1, 4, S("a2345")); + test(S("abcdefghij"), 1, 10, SV("1234567890"), 1, 8, S("a23456789")); + test(S("abcdefghij"), 1, 10, SV("1234567890"), 1, 9, S("a234567890")); + test(S("abcdefghij"), 1, 10, SV("1234567890"), 1, 10, S("a234567890")); + test(S("abcdefghij"), 1, 10, SV("1234567890"), 5, 0, S("a")); + test(S("abcdefghij"), 1, 10, SV("1234567890"), 5, 1, S("a6")); + test(S("abcdefghij"), 1, 10, SV("1234567890"), 5, 2, S("a67")); + test(S("abcdefghij"), 1, 10, SV("1234567890"), 5, 4, S("a6789")); + test(S("abcdefghij"), 1, 10, SV("1234567890"), 5, 5, S("a67890")); + test(S("abcdefghij"), 1, 10, SV("1234567890"), 5, 6, S("a67890")); + test(S("abcdefghij"), 1, 10, SV("1234567890"), 9, 0, S("a")); + test(S("abcdefghij"), 1, 10, SV("1234567890"), 9, 1, S("a0")); + test(S("abcdefghij"), 1, 10, SV("1234567890"), 9, 2, S("a0")); + test(S("abcdefghij"), 1, 10, SV("1234567890"), 10, 0, S("a")); + test(S("abcdefghij"), 1, 10, SV("1234567890"), 10, 1, S("a")); + test(S("abcdefghij"), 1, 10, SV("1234567890"), 11, 0, S("can't happen")); + test(S("abcdefghij"), 1, 10, SV("12345678901234567890"), 0, 0, S("a")); + test(S("abcdefghij"), 1, 10, SV("12345678901234567890"), 0, 1, S("a1")); + test(S("abcdefghij"), 1, 10, SV("12345678901234567890"), 0, 10, S("a1234567890")); + test(S("abcdefghij"), 1, 10, SV("12345678901234567890"), 0, 19, S("a1234567890123456789")); + test(S("abcdefghij"), 1, 10, SV("12345678901234567890"), 0, 20, S("a12345678901234567890")); + test(S("abcdefghij"), 1, 10, SV("12345678901234567890"), 0, 21, S("a12345678901234567890")); + test(S("abcdefghij"), 1, 10, SV("12345678901234567890"), 1, 0, S("a")); + test(S("abcdefghij"), 1, 10, SV("12345678901234567890"), 1, 1, S("a2")); + test(S("abcdefghij"), 1, 10, SV("12345678901234567890"), 1, 9, S("a234567890")); + test(S("abcdefghij"), 1, 10, SV("12345678901234567890"), 1, 18, S("a234567890123456789")); + test(S("abcdefghij"), 1, 10, SV("12345678901234567890"), 1, 19, S("a2345678901234567890")); + test(S("abcdefghij"), 1, 10, SV("12345678901234567890"), 1, 20, S("a2345678901234567890")); +} + +template +void test28() +{ + test(S("abcdefghij"), 1, 10, SV("12345678901234567890"), 10, 0, S("a")); + test(S("abcdefghij"), 1, 10, SV("12345678901234567890"), 10, 1, S("a1")); + test(S("abcdefghij"), 1, 10, SV("12345678901234567890"), 10, 5, S("a12345")); + test(S("abcdefghij"), 1, 10, SV("12345678901234567890"), 10, 9, S("a123456789")); + test(S("abcdefghij"), 1, 10, SV("12345678901234567890"), 10, 10, S("a1234567890")); + test(S("abcdefghij"), 1, 10, SV("12345678901234567890"), 10, 11, S("a1234567890")); + test(S("abcdefghij"), 1, 10, SV("12345678901234567890"), 19, 0, S("a")); + test(S("abcdefghij"), 1, 10, SV("12345678901234567890"), 19, 1, S("a0")); + test(S("abcdefghij"), 1, 10, SV("12345678901234567890"), 19, 2, S("a0")); + test(S("abcdefghij"), 1, 10, SV("12345678901234567890"), 20, 0, S("a")); + test(S("abcdefghij"), 1, 10, SV("12345678901234567890"), 20, 1, S("a")); + test(S("abcdefghij"), 1, 10, SV("12345678901234567890"), 21, 0, S("can't happen")); + test(S("abcdefghij"), 5, 0, SV(""), 0, 0, S("abcdefghij")); + test(S("abcdefghij"), 5, 0, SV(""), 0, 1, S("abcdefghij")); + test(S("abcdefghij"), 5, 0, SV(""), 1, 0, S("can't happen")); + test(S("abcdefghij"), 5, 0, SV("12345"), 0, 0, S("abcdefghij")); + test(S("abcdefghij"), 5, 0, SV("12345"), 0, 1, S("abcde1fghij")); + test(S("abcdefghij"), 5, 0, SV("12345"), 0, 2, S("abcde12fghij")); + test(S("abcdefghij"), 5, 0, SV("12345"), 0, 4, S("abcde1234fghij")); + test(S("abcdefghij"), 5, 0, SV("12345"), 0, 5, S("abcde12345fghij")); + test(S("abcdefghij"), 5, 0, SV("12345"), 0, 6, S("abcde12345fghij")); + test(S("abcdefghij"), 5, 0, SV("12345"), 1, 0, S("abcdefghij")); + test(S("abcdefghij"), 5, 0, SV("12345"), 1, 1, S("abcde2fghij")); + test(S("abcdefghij"), 5, 0, SV("12345"), 1, 2, S("abcde23fghij")); + test(S("abcdefghij"), 5, 0, SV("12345"), 1, 3, S("abcde234fghij")); + test(S("abcdefghij"), 5, 0, SV("12345"), 1, 4, S("abcde2345fghij")); + test(S("abcdefghij"), 5, 0, SV("12345"), 1, 5, S("abcde2345fghij")); + test(S("abcdefghij"), 5, 0, SV("12345"), 2, 0, S("abcdefghij")); + test(S("abcdefghij"), 5, 0, SV("12345"), 2, 1, S("abcde3fghij")); + test(S("abcdefghij"), 5, 0, SV("12345"), 2, 2, S("abcde34fghij")); + test(S("abcdefghij"), 5, 0, SV("12345"), 2, 3, S("abcde345fghij")); + test(S("abcdefghij"), 5, 0, SV("12345"), 2, 4, S("abcde345fghij")); + test(S("abcdefghij"), 5, 0, SV("12345"), 4, 0, S("abcdefghij")); + test(S("abcdefghij"), 5, 0, SV("12345"), 4, 1, S("abcde5fghij")); + test(S("abcdefghij"), 5, 0, SV("12345"), 4, 2, S("abcde5fghij")); + test(S("abcdefghij"), 5, 0, SV("12345"), 5, 0, S("abcdefghij")); + test(S("abcdefghij"), 5, 0, SV("12345"), 5, 1, S("abcdefghij")); + test(S("abcdefghij"), 5, 0, SV("12345"), 6, 0, S("can't happen")); + test(S("abcdefghij"), 5, 0, SV("1234567890"), 0, 0, S("abcdefghij")); + test(S("abcdefghij"), 5, 0, SV("1234567890"), 0, 1, S("abcde1fghij")); + test(S("abcdefghij"), 5, 0, SV("1234567890"), 0, 5, S("abcde12345fghij")); + test(S("abcdefghij"), 5, 0, SV("1234567890"), 0, 9, S("abcde123456789fghij")); + test(S("abcdefghij"), 5, 0, SV("1234567890"), 0, 10, S("abcde1234567890fghij")); + test(S("abcdefghij"), 5, 0, SV("1234567890"), 0, 11, S("abcde1234567890fghij")); + test(S("abcdefghij"), 5, 0, SV("1234567890"), 1, 0, S("abcdefghij")); + test(S("abcdefghij"), 5, 0, SV("1234567890"), 1, 1, S("abcde2fghij")); + test(S("abcdefghij"), 5, 0, SV("1234567890"), 1, 4, S("abcde2345fghij")); + test(S("abcdefghij"), 5, 0, SV("1234567890"), 1, 8, S("abcde23456789fghij")); + test(S("abcdefghij"), 5, 0, SV("1234567890"), 1, 9, S("abcde234567890fghij")); + test(S("abcdefghij"), 5, 0, SV("1234567890"), 1, 10, S("abcde234567890fghij")); + test(S("abcdefghij"), 5, 0, SV("1234567890"), 5, 0, S("abcdefghij")); + test(S("abcdefghij"), 5, 0, SV("1234567890"), 5, 1, S("abcde6fghij")); + test(S("abcdefghij"), 5, 0, SV("1234567890"), 5, 2, S("abcde67fghij")); + test(S("abcdefghij"), 5, 0, SV("1234567890"), 5, 4, S("abcde6789fghij")); + test(S("abcdefghij"), 5, 0, SV("1234567890"), 5, 5, S("abcde67890fghij")); + test(S("abcdefghij"), 5, 0, SV("1234567890"), 5, 6, S("abcde67890fghij")); + test(S("abcdefghij"), 5, 0, SV("1234567890"), 9, 0, S("abcdefghij")); + test(S("abcdefghij"), 5, 0, SV("1234567890"), 9, 1, S("abcde0fghij")); + test(S("abcdefghij"), 5, 0, SV("1234567890"), 9, 2, S("abcde0fghij")); + test(S("abcdefghij"), 5, 0, SV("1234567890"), 10, 0, S("abcdefghij")); + test(S("abcdefghij"), 5, 0, SV("1234567890"), 10, 1, S("abcdefghij")); + test(S("abcdefghij"), 5, 0, SV("1234567890"), 11, 0, S("can't happen")); + test(S("abcdefghij"), 5, 0, SV("12345678901234567890"), 0, 0, S("abcdefghij")); + test(S("abcdefghij"), 5, 0, SV("12345678901234567890"), 0, 1, S("abcde1fghij")); + test(S("abcdefghij"), 5, 0, SV("12345678901234567890"), 0, 10, S("abcde1234567890fghij")); + test(S("abcdefghij"), 5, 0, SV("12345678901234567890"), 0, 19, S("abcde1234567890123456789fghij")); + test(S("abcdefghij"), 5, 0, SV("12345678901234567890"), 0, 20, S("abcde12345678901234567890fghij")); + test(S("abcdefghij"), 5, 0, SV("12345678901234567890"), 0, 21, S("abcde12345678901234567890fghij")); + test(S("abcdefghij"), 5, 0, SV("12345678901234567890"), 1, 0, S("abcdefghij")); + test(S("abcdefghij"), 5, 0, SV("12345678901234567890"), 1, 1, S("abcde2fghij")); + test(S("abcdefghij"), 5, 0, SV("12345678901234567890"), 1, 9, S("abcde234567890fghij")); + test(S("abcdefghij"), 5, 0, SV("12345678901234567890"), 1, 18, S("abcde234567890123456789fghij")); + test(S("abcdefghij"), 5, 0, SV("12345678901234567890"), 1, 19, S("abcde2345678901234567890fghij")); + test(S("abcdefghij"), 5, 0, SV("12345678901234567890"), 1, 20, S("abcde2345678901234567890fghij")); + test(S("abcdefghij"), 5, 0, SV("12345678901234567890"), 10, 0, S("abcdefghij")); + test(S("abcdefghij"), 5, 0, SV("12345678901234567890"), 10, 1, S("abcde1fghij")); + test(S("abcdefghij"), 5, 0, SV("12345678901234567890"), 10, 5, S("abcde12345fghij")); + test(S("abcdefghij"), 5, 0, SV("12345678901234567890"), 10, 9, S("abcde123456789fghij")); + test(S("abcdefghij"), 5, 0, SV("12345678901234567890"), 10, 10, S("abcde1234567890fghij")); + test(S("abcdefghij"), 5, 0, SV("12345678901234567890"), 10, 11, S("abcde1234567890fghij")); + test(S("abcdefghij"), 5, 0, SV("12345678901234567890"), 19, 0, S("abcdefghij")); + test(S("abcdefghij"), 5, 0, SV("12345678901234567890"), 19, 1, S("abcde0fghij")); + test(S("abcdefghij"), 5, 0, SV("12345678901234567890"), 19, 2, S("abcde0fghij")); + test(S("abcdefghij"), 5, 0, SV("12345678901234567890"), 20, 0, S("abcdefghij")); + test(S("abcdefghij"), 5, 0, SV("12345678901234567890"), 20, 1, S("abcdefghij")); + test(S("abcdefghij"), 5, 0, SV("12345678901234567890"), 21, 0, S("can't happen")); + test(S("abcdefghij"), 5, 1, SV(""), 0, 0, S("abcdeghij")); + test(S("abcdefghij"), 5, 1, SV(""), 0, 1, S("abcdeghij")); + test(S("abcdefghij"), 5, 1, SV(""), 1, 0, S("can't happen")); + test(S("abcdefghij"), 5, 1, SV("12345"), 0, 0, S("abcdeghij")); + test(S("abcdefghij"), 5, 1, SV("12345"), 0, 1, S("abcde1ghij")); + test(S("abcdefghij"), 5, 1, SV("12345"), 0, 2, S("abcde12ghij")); + test(S("abcdefghij"), 5, 1, SV("12345"), 0, 4, S("abcde1234ghij")); + test(S("abcdefghij"), 5, 1, SV("12345"), 0, 5, S("abcde12345ghij")); + test(S("abcdefghij"), 5, 1, SV("12345"), 0, 6, S("abcde12345ghij")); + test(S("abcdefghij"), 5, 1, SV("12345"), 1, 0, S("abcdeghij")); + test(S("abcdefghij"), 5, 1, SV("12345"), 1, 1, S("abcde2ghij")); + test(S("abcdefghij"), 5, 1, SV("12345"), 1, 2, S("abcde23ghij")); + test(S("abcdefghij"), 5, 1, SV("12345"), 1, 3, S("abcde234ghij")); + test(S("abcdefghij"), 5, 1, SV("12345"), 1, 4, S("abcde2345ghij")); +} + +template +void test29() +{ + test(S("abcdefghij"), 5, 1, SV("12345"), 1, 5, S("abcde2345ghij")); + test(S("abcdefghij"), 5, 1, SV("12345"), 2, 0, S("abcdeghij")); + test(S("abcdefghij"), 5, 1, SV("12345"), 2, 1, S("abcde3ghij")); + test(S("abcdefghij"), 5, 1, SV("12345"), 2, 2, S("abcde34ghij")); + test(S("abcdefghij"), 5, 1, SV("12345"), 2, 3, S("abcde345ghij")); + test(S("abcdefghij"), 5, 1, SV("12345"), 2, 4, S("abcde345ghij")); + test(S("abcdefghij"), 5, 1, SV("12345"), 4, 0, S("abcdeghij")); + test(S("abcdefghij"), 5, 1, SV("12345"), 4, 1, S("abcde5ghij")); + test(S("abcdefghij"), 5, 1, SV("12345"), 4, 2, S("abcde5ghij")); + test(S("abcdefghij"), 5, 1, SV("12345"), 5, 0, S("abcdeghij")); + test(S("abcdefghij"), 5, 1, SV("12345"), 5, 1, S("abcdeghij")); + test(S("abcdefghij"), 5, 1, SV("12345"), 6, 0, S("can't happen")); + test(S("abcdefghij"), 5, 1, SV("1234567890"), 0, 0, S("abcdeghij")); + test(S("abcdefghij"), 5, 1, SV("1234567890"), 0, 1, S("abcde1ghij")); + test(S("abcdefghij"), 5, 1, SV("1234567890"), 0, 5, S("abcde12345ghij")); + test(S("abcdefghij"), 5, 1, SV("1234567890"), 0, 9, S("abcde123456789ghij")); + test(S("abcdefghij"), 5, 1, SV("1234567890"), 0, 10, S("abcde1234567890ghij")); + test(S("abcdefghij"), 5, 1, SV("1234567890"), 0, 11, S("abcde1234567890ghij")); + test(S("abcdefghij"), 5, 1, SV("1234567890"), 1, 0, S("abcdeghij")); + test(S("abcdefghij"), 5, 1, SV("1234567890"), 1, 1, S("abcde2ghij")); + test(S("abcdefghij"), 5, 1, SV("1234567890"), 1, 4, S("abcde2345ghij")); + test(S("abcdefghij"), 5, 1, SV("1234567890"), 1, 8, S("abcde23456789ghij")); + test(S("abcdefghij"), 5, 1, SV("1234567890"), 1, 9, S("abcde234567890ghij")); + test(S("abcdefghij"), 5, 1, SV("1234567890"), 1, 10, S("abcde234567890ghij")); + test(S("abcdefghij"), 5, 1, SV("1234567890"), 5, 0, S("abcdeghij")); + test(S("abcdefghij"), 5, 1, SV("1234567890"), 5, 1, S("abcde6ghij")); + test(S("abcdefghij"), 5, 1, SV("1234567890"), 5, 2, S("abcde67ghij")); + test(S("abcdefghij"), 5, 1, SV("1234567890"), 5, 4, S("abcde6789ghij")); + test(S("abcdefghij"), 5, 1, SV("1234567890"), 5, 5, S("abcde67890ghij")); + test(S("abcdefghij"), 5, 1, SV("1234567890"), 5, 6, S("abcde67890ghij")); + test(S("abcdefghij"), 5, 1, SV("1234567890"), 9, 0, S("abcdeghij")); + test(S("abcdefghij"), 5, 1, SV("1234567890"), 9, 1, S("abcde0ghij")); + test(S("abcdefghij"), 5, 1, SV("1234567890"), 9, 2, S("abcde0ghij")); + test(S("abcdefghij"), 5, 1, SV("1234567890"), 10, 0, S("abcdeghij")); + test(S("abcdefghij"), 5, 1, SV("1234567890"), 10, 1, S("abcdeghij")); + test(S("abcdefghij"), 5, 1, SV("1234567890"), 11, 0, S("can't happen")); + test(S("abcdefghij"), 5, 1, SV("12345678901234567890"), 0, 0, S("abcdeghij")); + test(S("abcdefghij"), 5, 1, SV("12345678901234567890"), 0, 1, S("abcde1ghij")); + test(S("abcdefghij"), 5, 1, SV("12345678901234567890"), 0, 10, S("abcde1234567890ghij")); + test(S("abcdefghij"), 5, 1, SV("12345678901234567890"), 0, 19, S("abcde1234567890123456789ghij")); + test(S("abcdefghij"), 5, 1, SV("12345678901234567890"), 0, 20, S("abcde12345678901234567890ghij")); + test(S("abcdefghij"), 5, 1, SV("12345678901234567890"), 0, 21, S("abcde12345678901234567890ghij")); + test(S("abcdefghij"), 5, 1, SV("12345678901234567890"), 1, 0, S("abcdeghij")); + test(S("abcdefghij"), 5, 1, SV("12345678901234567890"), 1, 1, S("abcde2ghij")); + test(S("abcdefghij"), 5, 1, SV("12345678901234567890"), 1, 9, S("abcde234567890ghij")); + test(S("abcdefghij"), 5, 1, SV("12345678901234567890"), 1, 18, S("abcde234567890123456789ghij")); + test(S("abcdefghij"), 5, 1, SV("12345678901234567890"), 1, 19, S("abcde2345678901234567890ghij")); + test(S("abcdefghij"), 5, 1, SV("12345678901234567890"), 1, 20, S("abcde2345678901234567890ghij")); + test(S("abcdefghij"), 5, 1, SV("12345678901234567890"), 10, 0, S("abcdeghij")); + test(S("abcdefghij"), 5, 1, SV("12345678901234567890"), 10, 1, S("abcde1ghij")); + test(S("abcdefghij"), 5, 1, SV("12345678901234567890"), 10, 5, S("abcde12345ghij")); + test(S("abcdefghij"), 5, 1, SV("12345678901234567890"), 10, 9, S("abcde123456789ghij")); + test(S("abcdefghij"), 5, 1, SV("12345678901234567890"), 10, 10, S("abcde1234567890ghij")); + test(S("abcdefghij"), 5, 1, SV("12345678901234567890"), 10, 11, S("abcde1234567890ghij")); + test(S("abcdefghij"), 5, 1, SV("12345678901234567890"), 19, 0, S("abcdeghij")); + test(S("abcdefghij"), 5, 1, SV("12345678901234567890"), 19, 1, S("abcde0ghij")); + test(S("abcdefghij"), 5, 1, SV("12345678901234567890"), 19, 2, S("abcde0ghij")); + test(S("abcdefghij"), 5, 1, SV("12345678901234567890"), 20, 0, S("abcdeghij")); + test(S("abcdefghij"), 5, 1, SV("12345678901234567890"), 20, 1, S("abcdeghij")); + test(S("abcdefghij"), 5, 1, SV("12345678901234567890"), 21, 0, S("can't happen")); + test(S("abcdefghij"), 5, 2, SV(""), 0, 0, S("abcdehij")); + test(S("abcdefghij"), 5, 2, SV(""), 0, 1, S("abcdehij")); + test(S("abcdefghij"), 5, 2, SV(""), 1, 0, S("can't happen")); + test(S("abcdefghij"), 5, 2, SV("12345"), 0, 0, S("abcdehij")); + test(S("abcdefghij"), 5, 2, SV("12345"), 0, 1, S("abcde1hij")); + test(S("abcdefghij"), 5, 2, SV("12345"), 0, 2, S("abcde12hij")); + test(S("abcdefghij"), 5, 2, SV("12345"), 0, 4, S("abcde1234hij")); + test(S("abcdefghij"), 5, 2, SV("12345"), 0, 5, S("abcde12345hij")); + test(S("abcdefghij"), 5, 2, SV("12345"), 0, 6, S("abcde12345hij")); + test(S("abcdefghij"), 5, 2, SV("12345"), 1, 0, S("abcdehij")); + test(S("abcdefghij"), 5, 2, SV("12345"), 1, 1, S("abcde2hij")); + test(S("abcdefghij"), 5, 2, SV("12345"), 1, 2, S("abcde23hij")); + test(S("abcdefghij"), 5, 2, SV("12345"), 1, 3, S("abcde234hij")); + test(S("abcdefghij"), 5, 2, SV("12345"), 1, 4, S("abcde2345hij")); + test(S("abcdefghij"), 5, 2, SV("12345"), 1, 5, S("abcde2345hij")); + test(S("abcdefghij"), 5, 2, SV("12345"), 2, 0, S("abcdehij")); + test(S("abcdefghij"), 5, 2, SV("12345"), 2, 1, S("abcde3hij")); + test(S("abcdefghij"), 5, 2, SV("12345"), 2, 2, S("abcde34hij")); + test(S("abcdefghij"), 5, 2, SV("12345"), 2, 3, S("abcde345hij")); + test(S("abcdefghij"), 5, 2, SV("12345"), 2, 4, S("abcde345hij")); + test(S("abcdefghij"), 5, 2, SV("12345"), 4, 0, S("abcdehij")); + test(S("abcdefghij"), 5, 2, SV("12345"), 4, 1, S("abcde5hij")); + test(S("abcdefghij"), 5, 2, SV("12345"), 4, 2, S("abcde5hij")); + test(S("abcdefghij"), 5, 2, SV("12345"), 5, 0, S("abcdehij")); + test(S("abcdefghij"), 5, 2, SV("12345"), 5, 1, S("abcdehij")); + test(S("abcdefghij"), 5, 2, SV("12345"), 6, 0, S("can't happen")); + test(S("abcdefghij"), 5, 2, SV("1234567890"), 0, 0, S("abcdehij")); + test(S("abcdefghij"), 5, 2, SV("1234567890"), 0, 1, S("abcde1hij")); + test(S("abcdefghij"), 5, 2, SV("1234567890"), 0, 5, S("abcde12345hij")); + test(S("abcdefghij"), 5, 2, SV("1234567890"), 0, 9, S("abcde123456789hij")); + test(S("abcdefghij"), 5, 2, SV("1234567890"), 0, 10, S("abcde1234567890hij")); + test(S("abcdefghij"), 5, 2, SV("1234567890"), 0, 11, S("abcde1234567890hij")); + test(S("abcdefghij"), 5, 2, SV("1234567890"), 1, 0, S("abcdehij")); + test(S("abcdefghij"), 5, 2, SV("1234567890"), 1, 1, S("abcde2hij")); + test(S("abcdefghij"), 5, 2, SV("1234567890"), 1, 4, S("abcde2345hij")); + test(S("abcdefghij"), 5, 2, SV("1234567890"), 1, 8, S("abcde23456789hij")); + test(S("abcdefghij"), 5, 2, SV("1234567890"), 1, 9, S("abcde234567890hij")); + test(S("abcdefghij"), 5, 2, SV("1234567890"), 1, 10, S("abcde234567890hij")); + test(S("abcdefghij"), 5, 2, SV("1234567890"), 5, 0, S("abcdehij")); + test(S("abcdefghij"), 5, 2, SV("1234567890"), 5, 1, S("abcde6hij")); +} + +template +void test30() +{ + test(S("abcdefghij"), 5, 2, SV("1234567890"), 5, 2, S("abcde67hij")); + test(S("abcdefghij"), 5, 2, SV("1234567890"), 5, 4, S("abcde6789hij")); + test(S("abcdefghij"), 5, 2, SV("1234567890"), 5, 5, S("abcde67890hij")); + test(S("abcdefghij"), 5, 2, SV("1234567890"), 5, 6, S("abcde67890hij")); + test(S("abcdefghij"), 5, 2, SV("1234567890"), 9, 0, S("abcdehij")); + test(S("abcdefghij"), 5, 2, SV("1234567890"), 9, 1, S("abcde0hij")); + test(S("abcdefghij"), 5, 2, SV("1234567890"), 9, 2, S("abcde0hij")); + test(S("abcdefghij"), 5, 2, SV("1234567890"), 10, 0, S("abcdehij")); + test(S("abcdefghij"), 5, 2, SV("1234567890"), 10, 1, S("abcdehij")); + test(S("abcdefghij"), 5, 2, SV("1234567890"), 11, 0, S("can't happen")); + test(S("abcdefghij"), 5, 2, SV("12345678901234567890"), 0, 0, S("abcdehij")); + test(S("abcdefghij"), 5, 2, SV("12345678901234567890"), 0, 1, S("abcde1hij")); + test(S("abcdefghij"), 5, 2, SV("12345678901234567890"), 0, 10, S("abcde1234567890hij")); + test(S("abcdefghij"), 5, 2, SV("12345678901234567890"), 0, 19, S("abcde1234567890123456789hij")); + test(S("abcdefghij"), 5, 2, SV("12345678901234567890"), 0, 20, S("abcde12345678901234567890hij")); + test(S("abcdefghij"), 5, 2, SV("12345678901234567890"), 0, 21, S("abcde12345678901234567890hij")); + test(S("abcdefghij"), 5, 2, SV("12345678901234567890"), 1, 0, S("abcdehij")); + test(S("abcdefghij"), 5, 2, SV("12345678901234567890"), 1, 1, S("abcde2hij")); + test(S("abcdefghij"), 5, 2, SV("12345678901234567890"), 1, 9, S("abcde234567890hij")); + test(S("abcdefghij"), 5, 2, SV("12345678901234567890"), 1, 18, S("abcde234567890123456789hij")); + test(S("abcdefghij"), 5, 2, SV("12345678901234567890"), 1, 19, S("abcde2345678901234567890hij")); + test(S("abcdefghij"), 5, 2, SV("12345678901234567890"), 1, 20, S("abcde2345678901234567890hij")); + test(S("abcdefghij"), 5, 2, SV("12345678901234567890"), 10, 0, S("abcdehij")); + test(S("abcdefghij"), 5, 2, SV("12345678901234567890"), 10, 1, S("abcde1hij")); + test(S("abcdefghij"), 5, 2, SV("12345678901234567890"), 10, 5, S("abcde12345hij")); + test(S("abcdefghij"), 5, 2, SV("12345678901234567890"), 10, 9, S("abcde123456789hij")); + test(S("abcdefghij"), 5, 2, SV("12345678901234567890"), 10, 10, S("abcde1234567890hij")); + test(S("abcdefghij"), 5, 2, SV("12345678901234567890"), 10, 11, S("abcde1234567890hij")); + test(S("abcdefghij"), 5, 2, SV("12345678901234567890"), 19, 0, S("abcdehij")); + test(S("abcdefghij"), 5, 2, SV("12345678901234567890"), 19, 1, S("abcde0hij")); + test(S("abcdefghij"), 5, 2, SV("12345678901234567890"), 19, 2, S("abcde0hij")); + test(S("abcdefghij"), 5, 2, SV("12345678901234567890"), 20, 0, S("abcdehij")); + test(S("abcdefghij"), 5, 2, SV("12345678901234567890"), 20, 1, S("abcdehij")); + test(S("abcdefghij"), 5, 2, SV("12345678901234567890"), 21, 0, S("can't happen")); + test(S("abcdefghij"), 5, 4, SV(""), 0, 0, S("abcdej")); + test(S("abcdefghij"), 5, 4, SV(""), 0, 1, S("abcdej")); + test(S("abcdefghij"), 5, 4, SV(""), 1, 0, S("can't happen")); + test(S("abcdefghij"), 5, 4, SV("12345"), 0, 0, S("abcdej")); + test(S("abcdefghij"), 5, 4, SV("12345"), 0, 1, S("abcde1j")); + test(S("abcdefghij"), 5, 4, SV("12345"), 0, 2, S("abcde12j")); + test(S("abcdefghij"), 5, 4, SV("12345"), 0, 4, S("abcde1234j")); + test(S("abcdefghij"), 5, 4, SV("12345"), 0, 5, S("abcde12345j")); + test(S("abcdefghij"), 5, 4, SV("12345"), 0, 6, S("abcde12345j")); + test(S("abcdefghij"), 5, 4, SV("12345"), 1, 0, S("abcdej")); + test(S("abcdefghij"), 5, 4, SV("12345"), 1, 1, S("abcde2j")); + test(S("abcdefghij"), 5, 4, SV("12345"), 1, 2, S("abcde23j")); + test(S("abcdefghij"), 5, 4, SV("12345"), 1, 3, S("abcde234j")); + test(S("abcdefghij"), 5, 4, SV("12345"), 1, 4, S("abcde2345j")); + test(S("abcdefghij"), 5, 4, SV("12345"), 1, 5, S("abcde2345j")); + test(S("abcdefghij"), 5, 4, SV("12345"), 2, 0, S("abcdej")); + test(S("abcdefghij"), 5, 4, SV("12345"), 2, 1, S("abcde3j")); + test(S("abcdefghij"), 5, 4, SV("12345"), 2, 2, S("abcde34j")); + test(S("abcdefghij"), 5, 4, SV("12345"), 2, 3, S("abcde345j")); + test(S("abcdefghij"), 5, 4, SV("12345"), 2, 4, S("abcde345j")); + test(S("abcdefghij"), 5, 4, SV("12345"), 4, 0, S("abcdej")); + test(S("abcdefghij"), 5, 4, SV("12345"), 4, 1, S("abcde5j")); + test(S("abcdefghij"), 5, 4, SV("12345"), 4, 2, S("abcde5j")); + test(S("abcdefghij"), 5, 4, SV("12345"), 5, 0, S("abcdej")); + test(S("abcdefghij"), 5, 4, SV("12345"), 5, 1, S("abcdej")); + test(S("abcdefghij"), 5, 4, SV("12345"), 6, 0, S("can't happen")); + test(S("abcdefghij"), 5, 4, SV("1234567890"), 0, 0, S("abcdej")); + test(S("abcdefghij"), 5, 4, SV("1234567890"), 0, 1, S("abcde1j")); + test(S("abcdefghij"), 5, 4, SV("1234567890"), 0, 5, S("abcde12345j")); + test(S("abcdefghij"), 5, 4, SV("1234567890"), 0, 9, S("abcde123456789j")); + test(S("abcdefghij"), 5, 4, SV("1234567890"), 0, 10, S("abcde1234567890j")); + test(S("abcdefghij"), 5, 4, SV("1234567890"), 0, 11, S("abcde1234567890j")); + test(S("abcdefghij"), 5, 4, SV("1234567890"), 1, 0, S("abcdej")); + test(S("abcdefghij"), 5, 4, SV("1234567890"), 1, 1, S("abcde2j")); + test(S("abcdefghij"), 5, 4, SV("1234567890"), 1, 4, S("abcde2345j")); + test(S("abcdefghij"), 5, 4, SV("1234567890"), 1, 8, S("abcde23456789j")); + test(S("abcdefghij"), 5, 4, SV("1234567890"), 1, 9, S("abcde234567890j")); + test(S("abcdefghij"), 5, 4, SV("1234567890"), 1, 10, S("abcde234567890j")); + test(S("abcdefghij"), 5, 4, SV("1234567890"), 5, 0, S("abcdej")); + test(S("abcdefghij"), 5, 4, SV("1234567890"), 5, 1, S("abcde6j")); + test(S("abcdefghij"), 5, 4, SV("1234567890"), 5, 2, S("abcde67j")); + test(S("abcdefghij"), 5, 4, SV("1234567890"), 5, 4, S("abcde6789j")); + test(S("abcdefghij"), 5, 4, SV("1234567890"), 5, 5, S("abcde67890j")); + test(S("abcdefghij"), 5, 4, SV("1234567890"), 5, 6, S("abcde67890j")); + test(S("abcdefghij"), 5, 4, SV("1234567890"), 9, 0, S("abcdej")); + test(S("abcdefghij"), 5, 4, SV("1234567890"), 9, 1, S("abcde0j")); + test(S("abcdefghij"), 5, 4, SV("1234567890"), 9, 2, S("abcde0j")); + test(S("abcdefghij"), 5, 4, SV("1234567890"), 10, 0, S("abcdej")); + test(S("abcdefghij"), 5, 4, SV("1234567890"), 10, 1, S("abcdej")); + test(S("abcdefghij"), 5, 4, SV("1234567890"), 11, 0, S("can't happen")); + test(S("abcdefghij"), 5, 4, SV("12345678901234567890"), 0, 0, S("abcdej")); + test(S("abcdefghij"), 5, 4, SV("12345678901234567890"), 0, 1, S("abcde1j")); + test(S("abcdefghij"), 5, 4, SV("12345678901234567890"), 0, 10, S("abcde1234567890j")); + test(S("abcdefghij"), 5, 4, SV("12345678901234567890"), 0, 19, S("abcde1234567890123456789j")); + test(S("abcdefghij"), 5, 4, SV("12345678901234567890"), 0, 20, S("abcde12345678901234567890j")); + test(S("abcdefghij"), 5, 4, SV("12345678901234567890"), 0, 21, S("abcde12345678901234567890j")); + test(S("abcdefghij"), 5, 4, SV("12345678901234567890"), 1, 0, S("abcdej")); + test(S("abcdefghij"), 5, 4, SV("12345678901234567890"), 1, 1, S("abcde2j")); + test(S("abcdefghij"), 5, 4, SV("12345678901234567890"), 1, 9, S("abcde234567890j")); + test(S("abcdefghij"), 5, 4, SV("12345678901234567890"), 1, 18, S("abcde234567890123456789j")); + test(S("abcdefghij"), 5, 4, SV("12345678901234567890"), 1, 19, S("abcde2345678901234567890j")); + test(S("abcdefghij"), 5, 4, SV("12345678901234567890"), 1, 20, S("abcde2345678901234567890j")); + test(S("abcdefghij"), 5, 4, SV("12345678901234567890"), 10, 0, S("abcdej")); + test(S("abcdefghij"), 5, 4, SV("12345678901234567890"), 10, 1, S("abcde1j")); + test(S("abcdefghij"), 5, 4, SV("12345678901234567890"), 10, 5, S("abcde12345j")); + test(S("abcdefghij"), 5, 4, SV("12345678901234567890"), 10, 9, S("abcde123456789j")); +} + +template +void test31() +{ + test(S("abcdefghij"), 5, 4, SV("12345678901234567890"), 10, 10, S("abcde1234567890j")); + test(S("abcdefghij"), 5, 4, SV("12345678901234567890"), 10, 11, S("abcde1234567890j")); + test(S("abcdefghij"), 5, 4, SV("12345678901234567890"), 19, 0, S("abcdej")); + test(S("abcdefghij"), 5, 4, SV("12345678901234567890"), 19, 1, S("abcde0j")); + test(S("abcdefghij"), 5, 4, SV("12345678901234567890"), 19, 2, S("abcde0j")); + test(S("abcdefghij"), 5, 4, SV("12345678901234567890"), 20, 0, S("abcdej")); + test(S("abcdefghij"), 5, 4, SV("12345678901234567890"), 20, 1, S("abcdej")); + test(S("abcdefghij"), 5, 4, SV("12345678901234567890"), 21, 0, S("can't happen")); + test(S("abcdefghij"), 5, 5, SV(""), 0, 0, S("abcde")); + test(S("abcdefghij"), 5, 5, SV(""), 0, 1, S("abcde")); + test(S("abcdefghij"), 5, 5, SV(""), 1, 0, S("can't happen")); + test(S("abcdefghij"), 5, 5, SV("12345"), 0, 0, S("abcde")); + test(S("abcdefghij"), 5, 5, SV("12345"), 0, 1, S("abcde1")); + test(S("abcdefghij"), 5, 5, SV("12345"), 0, 2, S("abcde12")); + test(S("abcdefghij"), 5, 5, SV("12345"), 0, 4, S("abcde1234")); + test(S("abcdefghij"), 5, 5, SV("12345"), 0, 5, S("abcde12345")); + test(S("abcdefghij"), 5, 5, SV("12345"), 0, 6, S("abcde12345")); + test(S("abcdefghij"), 5, 5, SV("12345"), 1, 0, S("abcde")); + test(S("abcdefghij"), 5, 5, SV("12345"), 1, 1, S("abcde2")); + test(S("abcdefghij"), 5, 5, SV("12345"), 1, 2, S("abcde23")); + test(S("abcdefghij"), 5, 5, SV("12345"), 1, 3, S("abcde234")); + test(S("abcdefghij"), 5, 5, SV("12345"), 1, 4, S("abcde2345")); + test(S("abcdefghij"), 5, 5, SV("12345"), 1, 5, S("abcde2345")); + test(S("abcdefghij"), 5, 5, SV("12345"), 2, 0, S("abcde")); + test(S("abcdefghij"), 5, 5, SV("12345"), 2, 1, S("abcde3")); + test(S("abcdefghij"), 5, 5, SV("12345"), 2, 2, S("abcde34")); + test(S("abcdefghij"), 5, 5, SV("12345"), 2, 3, S("abcde345")); + test(S("abcdefghij"), 5, 5, SV("12345"), 2, 4, S("abcde345")); + test(S("abcdefghij"), 5, 5, SV("12345"), 4, 0, S("abcde")); + test(S("abcdefghij"), 5, 5, SV("12345"), 4, 1, S("abcde5")); + test(S("abcdefghij"), 5, 5, SV("12345"), 4, 2, S("abcde5")); + test(S("abcdefghij"), 5, 5, SV("12345"), 5, 0, S("abcde")); + test(S("abcdefghij"), 5, 5, SV("12345"), 5, 1, S("abcde")); + test(S("abcdefghij"), 5, 5, SV("12345"), 6, 0, S("can't happen")); + test(S("abcdefghij"), 5, 5, SV("1234567890"), 0, 0, S("abcde")); + test(S("abcdefghij"), 5, 5, SV("1234567890"), 0, 1, S("abcde1")); + test(S("abcdefghij"), 5, 5, SV("1234567890"), 0, 5, S("abcde12345")); + test(S("abcdefghij"), 5, 5, SV("1234567890"), 0, 9, S("abcde123456789")); + test(S("abcdefghij"), 5, 5, SV("1234567890"), 0, 10, S("abcde1234567890")); + test(S("abcdefghij"), 5, 5, SV("1234567890"), 0, 11, S("abcde1234567890")); + test(S("abcdefghij"), 5, 5, SV("1234567890"), 1, 0, S("abcde")); + test(S("abcdefghij"), 5, 5, SV("1234567890"), 1, 1, S("abcde2")); + test(S("abcdefghij"), 5, 5, SV("1234567890"), 1, 4, S("abcde2345")); + test(S("abcdefghij"), 5, 5, SV("1234567890"), 1, 8, S("abcde23456789")); + test(S("abcdefghij"), 5, 5, SV("1234567890"), 1, 9, S("abcde234567890")); + test(S("abcdefghij"), 5, 5, SV("1234567890"), 1, 10, S("abcde234567890")); + test(S("abcdefghij"), 5, 5, SV("1234567890"), 5, 0, S("abcde")); + test(S("abcdefghij"), 5, 5, SV("1234567890"), 5, 1, S("abcde6")); + test(S("abcdefghij"), 5, 5, SV("1234567890"), 5, 2, S("abcde67")); + test(S("abcdefghij"), 5, 5, SV("1234567890"), 5, 4, S("abcde6789")); + test(S("abcdefghij"), 5, 5, SV("1234567890"), 5, 5, S("abcde67890")); + test(S("abcdefghij"), 5, 5, SV("1234567890"), 5, 6, S("abcde67890")); + test(S("abcdefghij"), 5, 5, SV("1234567890"), 9, 0, S("abcde")); + test(S("abcdefghij"), 5, 5, SV("1234567890"), 9, 1, S("abcde0")); + test(S("abcdefghij"), 5, 5, SV("1234567890"), 9, 2, S("abcde0")); + test(S("abcdefghij"), 5, 5, SV("1234567890"), 10, 0, S("abcde")); + test(S("abcdefghij"), 5, 5, SV("1234567890"), 10, 1, S("abcde")); + test(S("abcdefghij"), 5, 5, SV("1234567890"), 11, 0, S("can't happen")); + test(S("abcdefghij"), 5, 5, SV("12345678901234567890"), 0, 0, S("abcde")); + test(S("abcdefghij"), 5, 5, SV("12345678901234567890"), 0, 1, S("abcde1")); + test(S("abcdefghij"), 5, 5, SV("12345678901234567890"), 0, 10, S("abcde1234567890")); + test(S("abcdefghij"), 5, 5, SV("12345678901234567890"), 0, 19, S("abcde1234567890123456789")); + test(S("abcdefghij"), 5, 5, SV("12345678901234567890"), 0, 20, S("abcde12345678901234567890")); + test(S("abcdefghij"), 5, 5, SV("12345678901234567890"), 0, 21, S("abcde12345678901234567890")); + test(S("abcdefghij"), 5, 5, SV("12345678901234567890"), 1, 0, S("abcde")); + test(S("abcdefghij"), 5, 5, SV("12345678901234567890"), 1, 1, S("abcde2")); + test(S("abcdefghij"), 5, 5, SV("12345678901234567890"), 1, 9, S("abcde234567890")); + test(S("abcdefghij"), 5, 5, SV("12345678901234567890"), 1, 18, S("abcde234567890123456789")); + test(S("abcdefghij"), 5, 5, SV("12345678901234567890"), 1, 19, S("abcde2345678901234567890")); + test(S("abcdefghij"), 5, 5, SV("12345678901234567890"), 1, 20, S("abcde2345678901234567890")); + test(S("abcdefghij"), 5, 5, SV("12345678901234567890"), 10, 0, S("abcde")); + test(S("abcdefghij"), 5, 5, SV("12345678901234567890"), 10, 1, S("abcde1")); + test(S("abcdefghij"), 5, 5, SV("12345678901234567890"), 10, 5, S("abcde12345")); + test(S("abcdefghij"), 5, 5, SV("12345678901234567890"), 10, 9, S("abcde123456789")); + test(S("abcdefghij"), 5, 5, SV("12345678901234567890"), 10, 10, S("abcde1234567890")); + test(S("abcdefghij"), 5, 5, SV("12345678901234567890"), 10, 11, S("abcde1234567890")); + test(S("abcdefghij"), 5, 5, SV("12345678901234567890"), 19, 0, S("abcde")); + test(S("abcdefghij"), 5, 5, SV("12345678901234567890"), 19, 1, S("abcde0")); + test(S("abcdefghij"), 5, 5, SV("12345678901234567890"), 19, 2, S("abcde0")); + test(S("abcdefghij"), 5, 5, SV("12345678901234567890"), 20, 0, S("abcde")); + test(S("abcdefghij"), 5, 5, SV("12345678901234567890"), 20, 1, S("abcde")); + test(S("abcdefghij"), 5, 5, SV("12345678901234567890"), 21, 0, S("can't happen")); + test(S("abcdefghij"), 5, 6, SV(""), 0, 0, S("abcde")); + test(S("abcdefghij"), 5, 6, SV(""), 0, 1, S("abcde")); + test(S("abcdefghij"), 5, 6, SV(""), 1, 0, S("can't happen")); + test(S("abcdefghij"), 5, 6, SV("12345"), 0, 0, S("abcde")); + test(S("abcdefghij"), 5, 6, SV("12345"), 0, 1, S("abcde1")); + test(S("abcdefghij"), 5, 6, SV("12345"), 0, 2, S("abcde12")); + test(S("abcdefghij"), 5, 6, SV("12345"), 0, 4, S("abcde1234")); + test(S("abcdefghij"), 5, 6, SV("12345"), 0, 5, S("abcde12345")); + test(S("abcdefghij"), 5, 6, SV("12345"), 0, 6, S("abcde12345")); + test(S("abcdefghij"), 5, 6, SV("12345"), 1, 0, S("abcde")); + test(S("abcdefghij"), 5, 6, SV("12345"), 1, 1, S("abcde2")); + test(S("abcdefghij"), 5, 6, SV("12345"), 1, 2, S("abcde23")); + test(S("abcdefghij"), 5, 6, SV("12345"), 1, 3, S("abcde234")); + test(S("abcdefghij"), 5, 6, SV("12345"), 1, 4, S("abcde2345")); + test(S("abcdefghij"), 5, 6, SV("12345"), 1, 5, S("abcde2345")); + test(S("abcdefghij"), 5, 6, SV("12345"), 2, 0, S("abcde")); + test(S("abcdefghij"), 5, 6, SV("12345"), 2, 1, S("abcde3")); + test(S("abcdefghij"), 5, 6, SV("12345"), 2, 2, S("abcde34")); +} + +template +void test32() +{ + test(S("abcdefghij"), 5, 6, SV("12345"), 2, 3, S("abcde345")); + test(S("abcdefghij"), 5, 6, SV("12345"), 2, 4, S("abcde345")); + test(S("abcdefghij"), 5, 6, SV("12345"), 4, 0, S("abcde")); + test(S("abcdefghij"), 5, 6, SV("12345"), 4, 1, S("abcde5")); + test(S("abcdefghij"), 5, 6, SV("12345"), 4, 2, S("abcde5")); + test(S("abcdefghij"), 5, 6, SV("12345"), 5, 0, S("abcde")); + test(S("abcdefghij"), 5, 6, SV("12345"), 5, 1, S("abcde")); + test(S("abcdefghij"), 5, 6, SV("12345"), 6, 0, S("can't happen")); + test(S("abcdefghij"), 5, 6, SV("1234567890"), 0, 0, S("abcde")); + test(S("abcdefghij"), 5, 6, SV("1234567890"), 0, 1, S("abcde1")); + test(S("abcdefghij"), 5, 6, SV("1234567890"), 0, 5, S("abcde12345")); + test(S("abcdefghij"), 5, 6, SV("1234567890"), 0, 9, S("abcde123456789")); + test(S("abcdefghij"), 5, 6, SV("1234567890"), 0, 10, S("abcde1234567890")); + test(S("abcdefghij"), 5, 6, SV("1234567890"), 0, 11, S("abcde1234567890")); + test(S("abcdefghij"), 5, 6, SV("1234567890"), 1, 0, S("abcde")); + test(S("abcdefghij"), 5, 6, SV("1234567890"), 1, 1, S("abcde2")); + test(S("abcdefghij"), 5, 6, SV("1234567890"), 1, 4, S("abcde2345")); + test(S("abcdefghij"), 5, 6, SV("1234567890"), 1, 8, S("abcde23456789")); + test(S("abcdefghij"), 5, 6, SV("1234567890"), 1, 9, S("abcde234567890")); + test(S("abcdefghij"), 5, 6, SV("1234567890"), 1, 10, S("abcde234567890")); + test(S("abcdefghij"), 5, 6, SV("1234567890"), 5, 0, S("abcde")); + test(S("abcdefghij"), 5, 6, SV("1234567890"), 5, 1, S("abcde6")); + test(S("abcdefghij"), 5, 6, SV("1234567890"), 5, 2, S("abcde67")); + test(S("abcdefghij"), 5, 6, SV("1234567890"), 5, 4, S("abcde6789")); + test(S("abcdefghij"), 5, 6, SV("1234567890"), 5, 5, S("abcde67890")); + test(S("abcdefghij"), 5, 6, SV("1234567890"), 5, 6, S("abcde67890")); + test(S("abcdefghij"), 5, 6, SV("1234567890"), 9, 0, S("abcde")); + test(S("abcdefghij"), 5, 6, SV("1234567890"), 9, 1, S("abcde0")); + test(S("abcdefghij"), 5, 6, SV("1234567890"), 9, 2, S("abcde0")); + test(S("abcdefghij"), 5, 6, SV("1234567890"), 10, 0, S("abcde")); + test(S("abcdefghij"), 5, 6, SV("1234567890"), 10, 1, S("abcde")); + test(S("abcdefghij"), 5, 6, SV("1234567890"), 11, 0, S("can't happen")); + test(S("abcdefghij"), 5, 6, SV("12345678901234567890"), 0, 0, S("abcde")); + test(S("abcdefghij"), 5, 6, SV("12345678901234567890"), 0, 1, S("abcde1")); + test(S("abcdefghij"), 5, 6, SV("12345678901234567890"), 0, 10, S("abcde1234567890")); + test(S("abcdefghij"), 5, 6, SV("12345678901234567890"), 0, 19, S("abcde1234567890123456789")); + test(S("abcdefghij"), 5, 6, SV("12345678901234567890"), 0, 20, S("abcde12345678901234567890")); + test(S("abcdefghij"), 5, 6, SV("12345678901234567890"), 0, 21, S("abcde12345678901234567890")); + test(S("abcdefghij"), 5, 6, SV("12345678901234567890"), 1, 0, S("abcde")); + test(S("abcdefghij"), 5, 6, SV("12345678901234567890"), 1, 1, S("abcde2")); + test(S("abcdefghij"), 5, 6, SV("12345678901234567890"), 1, 9, S("abcde234567890")); + test(S("abcdefghij"), 5, 6, SV("12345678901234567890"), 1, 18, S("abcde234567890123456789")); + test(S("abcdefghij"), 5, 6, SV("12345678901234567890"), 1, 19, S("abcde2345678901234567890")); + test(S("abcdefghij"), 5, 6, SV("12345678901234567890"), 1, 20, S("abcde2345678901234567890")); + test(S("abcdefghij"), 5, 6, SV("12345678901234567890"), 10, 0, S("abcde")); + test(S("abcdefghij"), 5, 6, SV("12345678901234567890"), 10, 1, S("abcde1")); + test(S("abcdefghij"), 5, 6, SV("12345678901234567890"), 10, 5, S("abcde12345")); + test(S("abcdefghij"), 5, 6, SV("12345678901234567890"), 10, 9, S("abcde123456789")); + test(S("abcdefghij"), 5, 6, SV("12345678901234567890"), 10, 10, S("abcde1234567890")); + test(S("abcdefghij"), 5, 6, SV("12345678901234567890"), 10, 11, S("abcde1234567890")); + test(S("abcdefghij"), 5, 6, SV("12345678901234567890"), 19, 0, S("abcde")); + test(S("abcdefghij"), 5, 6, SV("12345678901234567890"), 19, 1, S("abcde0")); + test(S("abcdefghij"), 5, 6, SV("12345678901234567890"), 19, 2, S("abcde0")); + test(S("abcdefghij"), 5, 6, SV("12345678901234567890"), 20, 0, S("abcde")); + test(S("abcdefghij"), 5, 6, SV("12345678901234567890"), 20, 1, S("abcde")); + test(S("abcdefghij"), 5, 6, SV("12345678901234567890"), 21, 0, S("can't happen")); + test(S("abcdefghij"), 9, 0, SV(""), 0, 0, S("abcdefghij")); + test(S("abcdefghij"), 9, 0, SV(""), 0, 1, S("abcdefghij")); + test(S("abcdefghij"), 9, 0, SV(""), 1, 0, S("can't happen")); + test(S("abcdefghij"), 9, 0, SV("12345"), 0, 0, S("abcdefghij")); + test(S("abcdefghij"), 9, 0, SV("12345"), 0, 1, S("abcdefghi1j")); + test(S("abcdefghij"), 9, 0, SV("12345"), 0, 2, S("abcdefghi12j")); + test(S("abcdefghij"), 9, 0, SV("12345"), 0, 4, S("abcdefghi1234j")); + test(S("abcdefghij"), 9, 0, SV("12345"), 0, 5, S("abcdefghi12345j")); + test(S("abcdefghij"), 9, 0, SV("12345"), 0, 6, S("abcdefghi12345j")); + test(S("abcdefghij"), 9, 0, SV("12345"), 1, 0, S("abcdefghij")); + test(S("abcdefghij"), 9, 0, SV("12345"), 1, 1, S("abcdefghi2j")); + test(S("abcdefghij"), 9, 0, SV("12345"), 1, 2, S("abcdefghi23j")); + test(S("abcdefghij"), 9, 0, SV("12345"), 1, 3, S("abcdefghi234j")); + test(S("abcdefghij"), 9, 0, SV("12345"), 1, 4, S("abcdefghi2345j")); + test(S("abcdefghij"), 9, 0, SV("12345"), 1, 5, S("abcdefghi2345j")); + test(S("abcdefghij"), 9, 0, SV("12345"), 2, 0, S("abcdefghij")); + test(S("abcdefghij"), 9, 0, SV("12345"), 2, 1, S("abcdefghi3j")); + test(S("abcdefghij"), 9, 0, SV("12345"), 2, 2, S("abcdefghi34j")); + test(S("abcdefghij"), 9, 0, SV("12345"), 2, 3, S("abcdefghi345j")); + test(S("abcdefghij"), 9, 0, SV("12345"), 2, 4, S("abcdefghi345j")); + test(S("abcdefghij"), 9, 0, SV("12345"), 4, 0, S("abcdefghij")); + test(S("abcdefghij"), 9, 0, SV("12345"), 4, 1, S("abcdefghi5j")); + test(S("abcdefghij"), 9, 0, SV("12345"), 4, 2, S("abcdefghi5j")); + test(S("abcdefghij"), 9, 0, SV("12345"), 5, 0, S("abcdefghij")); + test(S("abcdefghij"), 9, 0, SV("12345"), 5, 1, S("abcdefghij")); + test(S("abcdefghij"), 9, 0, SV("12345"), 6, 0, S("can't happen")); + test(S("abcdefghij"), 9, 0, SV("1234567890"), 0, 0, S("abcdefghij")); + test(S("abcdefghij"), 9, 0, SV("1234567890"), 0, 1, S("abcdefghi1j")); + test(S("abcdefghij"), 9, 0, SV("1234567890"), 0, 5, S("abcdefghi12345j")); + test(S("abcdefghij"), 9, 0, SV("1234567890"), 0, 9, S("abcdefghi123456789j")); + test(S("abcdefghij"), 9, 0, SV("1234567890"), 0, 10, S("abcdefghi1234567890j")); + test(S("abcdefghij"), 9, 0, SV("1234567890"), 0, 11, S("abcdefghi1234567890j")); + test(S("abcdefghij"), 9, 0, SV("1234567890"), 1, 0, S("abcdefghij")); + test(S("abcdefghij"), 9, 0, SV("1234567890"), 1, 1, S("abcdefghi2j")); + test(S("abcdefghij"), 9, 0, SV("1234567890"), 1, 4, S("abcdefghi2345j")); + test(S("abcdefghij"), 9, 0, SV("1234567890"), 1, 8, S("abcdefghi23456789j")); + test(S("abcdefghij"), 9, 0, SV("1234567890"), 1, 9, S("abcdefghi234567890j")); + test(S("abcdefghij"), 9, 0, SV("1234567890"), 1, 10, S("abcdefghi234567890j")); + test(S("abcdefghij"), 9, 0, SV("1234567890"), 5, 0, S("abcdefghij")); + test(S("abcdefghij"), 9, 0, SV("1234567890"), 5, 1, S("abcdefghi6j")); + test(S("abcdefghij"), 9, 0, SV("1234567890"), 5, 2, S("abcdefghi67j")); + test(S("abcdefghij"), 9, 0, SV("1234567890"), 5, 4, S("abcdefghi6789j")); + test(S("abcdefghij"), 9, 0, SV("1234567890"), 5, 5, S("abcdefghi67890j")); + test(S("abcdefghij"), 9, 0, SV("1234567890"), 5, 6, S("abcdefghi67890j")); +} + +template +void test33() +{ + test(S("abcdefghij"), 9, 0, SV("1234567890"), 9, 0, S("abcdefghij")); + test(S("abcdefghij"), 9, 0, SV("1234567890"), 9, 1, S("abcdefghi0j")); + test(S("abcdefghij"), 9, 0, SV("1234567890"), 9, 2, S("abcdefghi0j")); + test(S("abcdefghij"), 9, 0, SV("1234567890"), 10, 0, S("abcdefghij")); + test(S("abcdefghij"), 9, 0, SV("1234567890"), 10, 1, S("abcdefghij")); + test(S("abcdefghij"), 9, 0, SV("1234567890"), 11, 0, S("can't happen")); + test(S("abcdefghij"), 9, 0, SV("12345678901234567890"), 0, 0, S("abcdefghij")); + test(S("abcdefghij"), 9, 0, SV("12345678901234567890"), 0, 1, S("abcdefghi1j")); + test(S("abcdefghij"), 9, 0, SV("12345678901234567890"), 0, 10, S("abcdefghi1234567890j")); + test(S("abcdefghij"), 9, 0, SV("12345678901234567890"), 0, 19, S("abcdefghi1234567890123456789j")); + test(S("abcdefghij"), 9, 0, SV("12345678901234567890"), 0, 20, S("abcdefghi12345678901234567890j")); + test(S("abcdefghij"), 9, 0, SV("12345678901234567890"), 0, 21, S("abcdefghi12345678901234567890j")); + test(S("abcdefghij"), 9, 0, SV("12345678901234567890"), 1, 0, S("abcdefghij")); + test(S("abcdefghij"), 9, 0, SV("12345678901234567890"), 1, 1, S("abcdefghi2j")); + test(S("abcdefghij"), 9, 0, SV("12345678901234567890"), 1, 9, S("abcdefghi234567890j")); + test(S("abcdefghij"), 9, 0, SV("12345678901234567890"), 1, 18, S("abcdefghi234567890123456789j")); + test(S("abcdefghij"), 9, 0, SV("12345678901234567890"), 1, 19, S("abcdefghi2345678901234567890j")); + test(S("abcdefghij"), 9, 0, SV("12345678901234567890"), 1, 20, S("abcdefghi2345678901234567890j")); + test(S("abcdefghij"), 9, 0, SV("12345678901234567890"), 10, 0, S("abcdefghij")); + test(S("abcdefghij"), 9, 0, SV("12345678901234567890"), 10, 1, S("abcdefghi1j")); + test(S("abcdefghij"), 9, 0, SV("12345678901234567890"), 10, 5, S("abcdefghi12345j")); + test(S("abcdefghij"), 9, 0, SV("12345678901234567890"), 10, 9, S("abcdefghi123456789j")); + test(S("abcdefghij"), 9, 0, SV("12345678901234567890"), 10, 10, S("abcdefghi1234567890j")); + test(S("abcdefghij"), 9, 0, SV("12345678901234567890"), 10, 11, S("abcdefghi1234567890j")); + test(S("abcdefghij"), 9, 0, SV("12345678901234567890"), 19, 0, S("abcdefghij")); + test(S("abcdefghij"), 9, 0, SV("12345678901234567890"), 19, 1, S("abcdefghi0j")); + test(S("abcdefghij"), 9, 0, SV("12345678901234567890"), 19, 2, S("abcdefghi0j")); + test(S("abcdefghij"), 9, 0, SV("12345678901234567890"), 20, 0, S("abcdefghij")); + test(S("abcdefghij"), 9, 0, SV("12345678901234567890"), 20, 1, S("abcdefghij")); + test(S("abcdefghij"), 9, 0, SV("12345678901234567890"), 21, 0, S("can't happen")); + test(S("abcdefghij"), 9, 1, SV(""), 0, 0, S("abcdefghi")); + test(S("abcdefghij"), 9, 1, SV(""), 0, 1, S("abcdefghi")); + test(S("abcdefghij"), 9, 1, SV(""), 1, 0, S("can't happen")); + test(S("abcdefghij"), 9, 1, SV("12345"), 0, 0, S("abcdefghi")); + test(S("abcdefghij"), 9, 1, SV("12345"), 0, 1, S("abcdefghi1")); + test(S("abcdefghij"), 9, 1, SV("12345"), 0, 2, S("abcdefghi12")); + test(S("abcdefghij"), 9, 1, SV("12345"), 0, 4, S("abcdefghi1234")); + test(S("abcdefghij"), 9, 1, SV("12345"), 0, 5, S("abcdefghi12345")); + test(S("abcdefghij"), 9, 1, SV("12345"), 0, 6, S("abcdefghi12345")); + test(S("abcdefghij"), 9, 1, SV("12345"), 1, 0, S("abcdefghi")); + test(S("abcdefghij"), 9, 1, SV("12345"), 1, 1, S("abcdefghi2")); + test(S("abcdefghij"), 9, 1, SV("12345"), 1, 2, S("abcdefghi23")); + test(S("abcdefghij"), 9, 1, SV("12345"), 1, 3, S("abcdefghi234")); + test(S("abcdefghij"), 9, 1, SV("12345"), 1, 4, S("abcdefghi2345")); + test(S("abcdefghij"), 9, 1, SV("12345"), 1, 5, S("abcdefghi2345")); + test(S("abcdefghij"), 9, 1, SV("12345"), 2, 0, S("abcdefghi")); + test(S("abcdefghij"), 9, 1, SV("12345"), 2, 1, S("abcdefghi3")); + test(S("abcdefghij"), 9, 1, SV("12345"), 2, 2, S("abcdefghi34")); + test(S("abcdefghij"), 9, 1, SV("12345"), 2, 3, S("abcdefghi345")); + test(S("abcdefghij"), 9, 1, SV("12345"), 2, 4, S("abcdefghi345")); + test(S("abcdefghij"), 9, 1, SV("12345"), 4, 0, S("abcdefghi")); + test(S("abcdefghij"), 9, 1, SV("12345"), 4, 1, S("abcdefghi5")); + test(S("abcdefghij"), 9, 1, SV("12345"), 4, 2, S("abcdefghi5")); + test(S("abcdefghij"), 9, 1, SV("12345"), 5, 0, S("abcdefghi")); + test(S("abcdefghij"), 9, 1, SV("12345"), 5, 1, S("abcdefghi")); + test(S("abcdefghij"), 9, 1, SV("12345"), 6, 0, S("can't happen")); + test(S("abcdefghij"), 9, 1, SV("1234567890"), 0, 0, S("abcdefghi")); + test(S("abcdefghij"), 9, 1, SV("1234567890"), 0, 1, S("abcdefghi1")); + test(S("abcdefghij"), 9, 1, SV("1234567890"), 0, 5, S("abcdefghi12345")); + test(S("abcdefghij"), 9, 1, SV("1234567890"), 0, 9, S("abcdefghi123456789")); + test(S("abcdefghij"), 9, 1, SV("1234567890"), 0, 10, S("abcdefghi1234567890")); + test(S("abcdefghij"), 9, 1, SV("1234567890"), 0, 11, S("abcdefghi1234567890")); + test(S("abcdefghij"), 9, 1, SV("1234567890"), 1, 0, S("abcdefghi")); + test(S("abcdefghij"), 9, 1, SV("1234567890"), 1, 1, S("abcdefghi2")); + test(S("abcdefghij"), 9, 1, SV("1234567890"), 1, 4, S("abcdefghi2345")); + test(S("abcdefghij"), 9, 1, SV("1234567890"), 1, 8, S("abcdefghi23456789")); + test(S("abcdefghij"), 9, 1, SV("1234567890"), 1, 9, S("abcdefghi234567890")); + test(S("abcdefghij"), 9, 1, SV("1234567890"), 1, 10, S("abcdefghi234567890")); + test(S("abcdefghij"), 9, 1, SV("1234567890"), 5, 0, S("abcdefghi")); + test(S("abcdefghij"), 9, 1, SV("1234567890"), 5, 1, S("abcdefghi6")); + test(S("abcdefghij"), 9, 1, SV("1234567890"), 5, 2, S("abcdefghi67")); + test(S("abcdefghij"), 9, 1, SV("1234567890"), 5, 4, S("abcdefghi6789")); + test(S("abcdefghij"), 9, 1, SV("1234567890"), 5, 5, S("abcdefghi67890")); + test(S("abcdefghij"), 9, 1, SV("1234567890"), 5, 6, S("abcdefghi67890")); + test(S("abcdefghij"), 9, 1, SV("1234567890"), 9, 0, S("abcdefghi")); + test(S("abcdefghij"), 9, 1, SV("1234567890"), 9, 1, S("abcdefghi0")); + test(S("abcdefghij"), 9, 1, SV("1234567890"), 9, 2, S("abcdefghi0")); + test(S("abcdefghij"), 9, 1, SV("1234567890"), 10, 0, S("abcdefghi")); + test(S("abcdefghij"), 9, 1, SV("1234567890"), 10, 1, S("abcdefghi")); + test(S("abcdefghij"), 9, 1, SV("1234567890"), 11, 0, S("can't happen")); + test(S("abcdefghij"), 9, 1, SV("12345678901234567890"), 0, 0, S("abcdefghi")); + test(S("abcdefghij"), 9, 1, SV("12345678901234567890"), 0, 1, S("abcdefghi1")); + test(S("abcdefghij"), 9, 1, SV("12345678901234567890"), 0, 10, S("abcdefghi1234567890")); + test(S("abcdefghij"), 9, 1, SV("12345678901234567890"), 0, 19, S("abcdefghi1234567890123456789")); + test(S("abcdefghij"), 9, 1, SV("12345678901234567890"), 0, 20, S("abcdefghi12345678901234567890")); + test(S("abcdefghij"), 9, 1, SV("12345678901234567890"), 0, 21, S("abcdefghi12345678901234567890")); + test(S("abcdefghij"), 9, 1, SV("12345678901234567890"), 1, 0, S("abcdefghi")); + test(S("abcdefghij"), 9, 1, SV("12345678901234567890"), 1, 1, S("abcdefghi2")); + test(S("abcdefghij"), 9, 1, SV("12345678901234567890"), 1, 9, S("abcdefghi234567890")); + test(S("abcdefghij"), 9, 1, SV("12345678901234567890"), 1, 18, S("abcdefghi234567890123456789")); + test(S("abcdefghij"), 9, 1, SV("12345678901234567890"), 1, 19, S("abcdefghi2345678901234567890")); + test(S("abcdefghij"), 9, 1, SV("12345678901234567890"), 1, 20, S("abcdefghi2345678901234567890")); + test(S("abcdefghij"), 9, 1, SV("12345678901234567890"), 10, 0, S("abcdefghi")); + test(S("abcdefghij"), 9, 1, SV("12345678901234567890"), 10, 1, S("abcdefghi1")); + test(S("abcdefghij"), 9, 1, SV("12345678901234567890"), 10, 5, S("abcdefghi12345")); + test(S("abcdefghij"), 9, 1, SV("12345678901234567890"), 10, 9, S("abcdefghi123456789")); + test(S("abcdefghij"), 9, 1, SV("12345678901234567890"), 10, 10, S("abcdefghi1234567890")); + test(S("abcdefghij"), 9, 1, SV("12345678901234567890"), 10, 11, S("abcdefghi1234567890")); + test(S("abcdefghij"), 9, 1, SV("12345678901234567890"), 19, 0, S("abcdefghi")); + test(S("abcdefghij"), 9, 1, SV("12345678901234567890"), 19, 1, S("abcdefghi0")); +} + +template +void test34() +{ + test(S("abcdefghij"), 9, 1, SV("12345678901234567890"), 19, 2, S("abcdefghi0")); + test(S("abcdefghij"), 9, 1, SV("12345678901234567890"), 20, 0, S("abcdefghi")); + test(S("abcdefghij"), 9, 1, SV("12345678901234567890"), 20, 1, S("abcdefghi")); + test(S("abcdefghij"), 9, 1, SV("12345678901234567890"), 21, 0, S("can't happen")); + test(S("abcdefghij"), 9, 2, SV(""), 0, 0, S("abcdefghi")); + test(S("abcdefghij"), 9, 2, SV(""), 0, 1, S("abcdefghi")); + test(S("abcdefghij"), 9, 2, SV(""), 1, 0, S("can't happen")); + test(S("abcdefghij"), 9, 2, SV("12345"), 0, 0, S("abcdefghi")); + test(S("abcdefghij"), 9, 2, SV("12345"), 0, 1, S("abcdefghi1")); + test(S("abcdefghij"), 9, 2, SV("12345"), 0, 2, S("abcdefghi12")); + test(S("abcdefghij"), 9, 2, SV("12345"), 0, 4, S("abcdefghi1234")); + test(S("abcdefghij"), 9, 2, SV("12345"), 0, 5, S("abcdefghi12345")); + test(S("abcdefghij"), 9, 2, SV("12345"), 0, 6, S("abcdefghi12345")); + test(S("abcdefghij"), 9, 2, SV("12345"), 1, 0, S("abcdefghi")); + test(S("abcdefghij"), 9, 2, SV("12345"), 1, 1, S("abcdefghi2")); + test(S("abcdefghij"), 9, 2, SV("12345"), 1, 2, S("abcdefghi23")); + test(S("abcdefghij"), 9, 2, SV("12345"), 1, 3, S("abcdefghi234")); + test(S("abcdefghij"), 9, 2, SV("12345"), 1, 4, S("abcdefghi2345")); + test(S("abcdefghij"), 9, 2, SV("12345"), 1, 5, S("abcdefghi2345")); + test(S("abcdefghij"), 9, 2, SV("12345"), 2, 0, S("abcdefghi")); + test(S("abcdefghij"), 9, 2, SV("12345"), 2, 1, S("abcdefghi3")); + test(S("abcdefghij"), 9, 2, SV("12345"), 2, 2, S("abcdefghi34")); + test(S("abcdefghij"), 9, 2, SV("12345"), 2, 3, S("abcdefghi345")); + test(S("abcdefghij"), 9, 2, SV("12345"), 2, 4, S("abcdefghi345")); + test(S("abcdefghij"), 9, 2, SV("12345"), 4, 0, S("abcdefghi")); + test(S("abcdefghij"), 9, 2, SV("12345"), 4, 1, S("abcdefghi5")); + test(S("abcdefghij"), 9, 2, SV("12345"), 4, 2, S("abcdefghi5")); + test(S("abcdefghij"), 9, 2, SV("12345"), 5, 0, S("abcdefghi")); + test(S("abcdefghij"), 9, 2, SV("12345"), 5, 1, S("abcdefghi")); + test(S("abcdefghij"), 9, 2, SV("12345"), 6, 0, S("can't happen")); + test(S("abcdefghij"), 9, 2, SV("1234567890"), 0, 0, S("abcdefghi")); + test(S("abcdefghij"), 9, 2, SV("1234567890"), 0, 1, S("abcdefghi1")); + test(S("abcdefghij"), 9, 2, SV("1234567890"), 0, 5, S("abcdefghi12345")); + test(S("abcdefghij"), 9, 2, SV("1234567890"), 0, 9, S("abcdefghi123456789")); + test(S("abcdefghij"), 9, 2, SV("1234567890"), 0, 10, S("abcdefghi1234567890")); + test(S("abcdefghij"), 9, 2, SV("1234567890"), 0, 11, S("abcdefghi1234567890")); + test(S("abcdefghij"), 9, 2, SV("1234567890"), 1, 0, S("abcdefghi")); + test(S("abcdefghij"), 9, 2, SV("1234567890"), 1, 1, S("abcdefghi2")); + test(S("abcdefghij"), 9, 2, SV("1234567890"), 1, 4, S("abcdefghi2345")); + test(S("abcdefghij"), 9, 2, SV("1234567890"), 1, 8, S("abcdefghi23456789")); + test(S("abcdefghij"), 9, 2, SV("1234567890"), 1, 9, S("abcdefghi234567890")); + test(S("abcdefghij"), 9, 2, SV("1234567890"), 1, 10, S("abcdefghi234567890")); + test(S("abcdefghij"), 9, 2, SV("1234567890"), 5, 0, S("abcdefghi")); + test(S("abcdefghij"), 9, 2, SV("1234567890"), 5, 1, S("abcdefghi6")); + test(S("abcdefghij"), 9, 2, SV("1234567890"), 5, 2, S("abcdefghi67")); + test(S("abcdefghij"), 9, 2, SV("1234567890"), 5, 4, S("abcdefghi6789")); + test(S("abcdefghij"), 9, 2, SV("1234567890"), 5, 5, S("abcdefghi67890")); + test(S("abcdefghij"), 9, 2, SV("1234567890"), 5, 6, S("abcdefghi67890")); + test(S("abcdefghij"), 9, 2, SV("1234567890"), 9, 0, S("abcdefghi")); + test(S("abcdefghij"), 9, 2, SV("1234567890"), 9, 1, S("abcdefghi0")); + test(S("abcdefghij"), 9, 2, SV("1234567890"), 9, 2, S("abcdefghi0")); + test(S("abcdefghij"), 9, 2, SV("1234567890"), 10, 0, S("abcdefghi")); + test(S("abcdefghij"), 9, 2, SV("1234567890"), 10, 1, S("abcdefghi")); + test(S("abcdefghij"), 9, 2, SV("1234567890"), 11, 0, S("can't happen")); + test(S("abcdefghij"), 9, 2, SV("12345678901234567890"), 0, 0, S("abcdefghi")); + test(S("abcdefghij"), 9, 2, SV("12345678901234567890"), 0, 1, S("abcdefghi1")); + test(S("abcdefghij"), 9, 2, SV("12345678901234567890"), 0, 10, S("abcdefghi1234567890")); + test(S("abcdefghij"), 9, 2, SV("12345678901234567890"), 0, 19, S("abcdefghi1234567890123456789")); + test(S("abcdefghij"), 9, 2, SV("12345678901234567890"), 0, 20, S("abcdefghi12345678901234567890")); + test(S("abcdefghij"), 9, 2, SV("12345678901234567890"), 0, 21, S("abcdefghi12345678901234567890")); + test(S("abcdefghij"), 9, 2, SV("12345678901234567890"), 1, 0, S("abcdefghi")); + test(S("abcdefghij"), 9, 2, SV("12345678901234567890"), 1, 1, S("abcdefghi2")); + test(S("abcdefghij"), 9, 2, SV("12345678901234567890"), 1, 9, S("abcdefghi234567890")); + test(S("abcdefghij"), 9, 2, SV("12345678901234567890"), 1, 18, S("abcdefghi234567890123456789")); + test(S("abcdefghij"), 9, 2, SV("12345678901234567890"), 1, 19, S("abcdefghi2345678901234567890")); + test(S("abcdefghij"), 9, 2, SV("12345678901234567890"), 1, 20, S("abcdefghi2345678901234567890")); + test(S("abcdefghij"), 9, 2, SV("12345678901234567890"), 10, 0, S("abcdefghi")); + test(S("abcdefghij"), 9, 2, SV("12345678901234567890"), 10, 1, S("abcdefghi1")); + test(S("abcdefghij"), 9, 2, SV("12345678901234567890"), 10, 5, S("abcdefghi12345")); + test(S("abcdefghij"), 9, 2, SV("12345678901234567890"), 10, 9, S("abcdefghi123456789")); + test(S("abcdefghij"), 9, 2, SV("12345678901234567890"), 10, 10, S("abcdefghi1234567890")); + test(S("abcdefghij"), 9, 2, SV("12345678901234567890"), 10, 11, S("abcdefghi1234567890")); + test(S("abcdefghij"), 9, 2, SV("12345678901234567890"), 19, 0, S("abcdefghi")); + test(S("abcdefghij"), 9, 2, SV("12345678901234567890"), 19, 1, S("abcdefghi0")); + test(S("abcdefghij"), 9, 2, SV("12345678901234567890"), 19, 2, S("abcdefghi0")); + test(S("abcdefghij"), 9, 2, SV("12345678901234567890"), 20, 0, S("abcdefghi")); + test(S("abcdefghij"), 9, 2, SV("12345678901234567890"), 20, 1, S("abcdefghi")); + test(S("abcdefghij"), 9, 2, SV("12345678901234567890"), 21, 0, S("can't happen")); + test(S("abcdefghij"), 10, 0, SV(""), 0, 0, S("abcdefghij")); + test(S("abcdefghij"), 10, 0, SV(""), 0, 1, S("abcdefghij")); + test(S("abcdefghij"), 10, 0, SV(""), 1, 0, S("can't happen")); + test(S("abcdefghij"), 10, 0, SV("12345"), 0, 0, S("abcdefghij")); + test(S("abcdefghij"), 10, 0, SV("12345"), 0, 1, S("abcdefghij1")); + test(S("abcdefghij"), 10, 0, SV("12345"), 0, 2, S("abcdefghij12")); + test(S("abcdefghij"), 10, 0, SV("12345"), 0, 4, S("abcdefghij1234")); + test(S("abcdefghij"), 10, 0, SV("12345"), 0, 5, S("abcdefghij12345")); + test(S("abcdefghij"), 10, 0, SV("12345"), 0, 6, S("abcdefghij12345")); + test(S("abcdefghij"), 10, 0, SV("12345"), 1, 0, S("abcdefghij")); + test(S("abcdefghij"), 10, 0, SV("12345"), 1, 1, S("abcdefghij2")); + test(S("abcdefghij"), 10, 0, SV("12345"), 1, 2, S("abcdefghij23")); + test(S("abcdefghij"), 10, 0, SV("12345"), 1, 3, S("abcdefghij234")); + test(S("abcdefghij"), 10, 0, SV("12345"), 1, 4, S("abcdefghij2345")); + test(S("abcdefghij"), 10, 0, SV("12345"), 1, 5, S("abcdefghij2345")); + test(S("abcdefghij"), 10, 0, SV("12345"), 2, 0, S("abcdefghij")); + test(S("abcdefghij"), 10, 0, SV("12345"), 2, 1, S("abcdefghij3")); + test(S("abcdefghij"), 10, 0, SV("12345"), 2, 2, S("abcdefghij34")); + test(S("abcdefghij"), 10, 0, SV("12345"), 2, 3, S("abcdefghij345")); + test(S("abcdefghij"), 10, 0, SV("12345"), 2, 4, S("abcdefghij345")); + test(S("abcdefghij"), 10, 0, SV("12345"), 4, 0, S("abcdefghij")); + test(S("abcdefghij"), 10, 0, SV("12345"), 4, 1, S("abcdefghij5")); +} + +template +void test35() +{ + test(S("abcdefghij"), 10, 0, SV("12345"), 4, 2, S("abcdefghij5")); + test(S("abcdefghij"), 10, 0, SV("12345"), 5, 0, S("abcdefghij")); + test(S("abcdefghij"), 10, 0, SV("12345"), 5, 1, S("abcdefghij")); + test(S("abcdefghij"), 10, 0, SV("12345"), 6, 0, S("can't happen")); + test(S("abcdefghij"), 10, 0, SV("1234567890"), 0, 0, S("abcdefghij")); + test(S("abcdefghij"), 10, 0, SV("1234567890"), 0, 1, S("abcdefghij1")); + test(S("abcdefghij"), 10, 0, SV("1234567890"), 0, 5, S("abcdefghij12345")); + test(S("abcdefghij"), 10, 0, SV("1234567890"), 0, 9, S("abcdefghij123456789")); + test(S("abcdefghij"), 10, 0, SV("1234567890"), 0, 10, S("abcdefghij1234567890")); + test(S("abcdefghij"), 10, 0, SV("1234567890"), 0, 11, S("abcdefghij1234567890")); + test(S("abcdefghij"), 10, 0, SV("1234567890"), 1, 0, S("abcdefghij")); + test(S("abcdefghij"), 10, 0, SV("1234567890"), 1, 1, S("abcdefghij2")); + test(S("abcdefghij"), 10, 0, SV("1234567890"), 1, 4, S("abcdefghij2345")); + test(S("abcdefghij"), 10, 0, SV("1234567890"), 1, 8, S("abcdefghij23456789")); + test(S("abcdefghij"), 10, 0, SV("1234567890"), 1, 9, S("abcdefghij234567890")); + test(S("abcdefghij"), 10, 0, SV("1234567890"), 1, 10, S("abcdefghij234567890")); + test(S("abcdefghij"), 10, 0, SV("1234567890"), 5, 0, S("abcdefghij")); + test(S("abcdefghij"), 10, 0, SV("1234567890"), 5, 1, S("abcdefghij6")); + test(S("abcdefghij"), 10, 0, SV("1234567890"), 5, 2, S("abcdefghij67")); + test(S("abcdefghij"), 10, 0, SV("1234567890"), 5, 4, S("abcdefghij6789")); + test(S("abcdefghij"), 10, 0, SV("1234567890"), 5, 5, S("abcdefghij67890")); + test(S("abcdefghij"), 10, 0, SV("1234567890"), 5, 6, S("abcdefghij67890")); + test(S("abcdefghij"), 10, 0, SV("1234567890"), 9, 0, S("abcdefghij")); + test(S("abcdefghij"), 10, 0, SV("1234567890"), 9, 1, S("abcdefghij0")); + test(S("abcdefghij"), 10, 0, SV("1234567890"), 9, 2, S("abcdefghij0")); + test(S("abcdefghij"), 10, 0, SV("1234567890"), 10, 0, S("abcdefghij")); + test(S("abcdefghij"), 10, 0, SV("1234567890"), 10, 1, S("abcdefghij")); + test(S("abcdefghij"), 10, 0, SV("1234567890"), 11, 0, S("can't happen")); + test(S("abcdefghij"), 10, 0, SV("12345678901234567890"), 0, 0, S("abcdefghij")); + test(S("abcdefghij"), 10, 0, SV("12345678901234567890"), 0, 1, S("abcdefghij1")); + test(S("abcdefghij"), 10, 0, SV("12345678901234567890"), 0, 10, S("abcdefghij1234567890")); + test(S("abcdefghij"), 10, 0, SV("12345678901234567890"), 0, 19, S("abcdefghij1234567890123456789")); + test(S("abcdefghij"), 10, 0, SV("12345678901234567890"), 0, 20, S("abcdefghij12345678901234567890")); + test(S("abcdefghij"), 10, 0, SV("12345678901234567890"), 0, 21, S("abcdefghij12345678901234567890")); + test(S("abcdefghij"), 10, 0, SV("12345678901234567890"), 1, 0, S("abcdefghij")); + test(S("abcdefghij"), 10, 0, SV("12345678901234567890"), 1, 1, S("abcdefghij2")); + test(S("abcdefghij"), 10, 0, SV("12345678901234567890"), 1, 9, S("abcdefghij234567890")); + test(S("abcdefghij"), 10, 0, SV("12345678901234567890"), 1, 18, S("abcdefghij234567890123456789")); + test(S("abcdefghij"), 10, 0, SV("12345678901234567890"), 1, 19, S("abcdefghij2345678901234567890")); + test(S("abcdefghij"), 10, 0, SV("12345678901234567890"), 1, 20, S("abcdefghij2345678901234567890")); + test(S("abcdefghij"), 10, 0, SV("12345678901234567890"), 10, 0, S("abcdefghij")); + test(S("abcdefghij"), 10, 0, SV("12345678901234567890"), 10, 1, S("abcdefghij1")); + test(S("abcdefghij"), 10, 0, SV("12345678901234567890"), 10, 5, S("abcdefghij12345")); + test(S("abcdefghij"), 10, 0, SV("12345678901234567890"), 10, 9, S("abcdefghij123456789")); + test(S("abcdefghij"), 10, 0, SV("12345678901234567890"), 10, 10, S("abcdefghij1234567890")); + test(S("abcdefghij"), 10, 0, SV("12345678901234567890"), 10, 11, S("abcdefghij1234567890")); + test(S("abcdefghij"), 10, 0, SV("12345678901234567890"), 19, 0, S("abcdefghij")); + test(S("abcdefghij"), 10, 0, SV("12345678901234567890"), 19, 1, S("abcdefghij0")); + test(S("abcdefghij"), 10, 0, SV("12345678901234567890"), 19, 2, S("abcdefghij0")); + test(S("abcdefghij"), 10, 0, SV("12345678901234567890"), 20, 0, S("abcdefghij")); + test(S("abcdefghij"), 10, 0, SV("12345678901234567890"), 20, 1, S("abcdefghij")); + test(S("abcdefghij"), 10, 0, SV("12345678901234567890"), 21, 0, S("can't happen")); + test(S("abcdefghij"), 10, 1, SV(""), 0, 0, S("abcdefghij")); + test(S("abcdefghij"), 10, 1, SV(""), 0, 1, S("abcdefghij")); + test(S("abcdefghij"), 10, 1, SV(""), 1, 0, S("can't happen")); + test(S("abcdefghij"), 10, 1, SV("12345"), 0, 0, S("abcdefghij")); + test(S("abcdefghij"), 10, 1, SV("12345"), 0, 1, S("abcdefghij1")); + test(S("abcdefghij"), 10, 1, SV("12345"), 0, 2, S("abcdefghij12")); + test(S("abcdefghij"), 10, 1, SV("12345"), 0, 4, S("abcdefghij1234")); + test(S("abcdefghij"), 10, 1, SV("12345"), 0, 5, S("abcdefghij12345")); + test(S("abcdefghij"), 10, 1, SV("12345"), 0, 6, S("abcdefghij12345")); + test(S("abcdefghij"), 10, 1, SV("12345"), 1, 0, S("abcdefghij")); + test(S("abcdefghij"), 10, 1, SV("12345"), 1, 1, S("abcdefghij2")); + test(S("abcdefghij"), 10, 1, SV("12345"), 1, 2, S("abcdefghij23")); + test(S("abcdefghij"), 10, 1, SV("12345"), 1, 3, S("abcdefghij234")); + test(S("abcdefghij"), 10, 1, SV("12345"), 1, 4, S("abcdefghij2345")); + test(S("abcdefghij"), 10, 1, SV("12345"), 1, 5, S("abcdefghij2345")); + test(S("abcdefghij"), 10, 1, SV("12345"), 2, 0, S("abcdefghij")); + test(S("abcdefghij"), 10, 1, SV("12345"), 2, 1, S("abcdefghij3")); + test(S("abcdefghij"), 10, 1, SV("12345"), 2, 2, S("abcdefghij34")); + test(S("abcdefghij"), 10, 1, SV("12345"), 2, 3, S("abcdefghij345")); + test(S("abcdefghij"), 10, 1, SV("12345"), 2, 4, S("abcdefghij345")); + test(S("abcdefghij"), 10, 1, SV("12345"), 4, 0, S("abcdefghij")); + test(S("abcdefghij"), 10, 1, SV("12345"), 4, 1, S("abcdefghij5")); + test(S("abcdefghij"), 10, 1, SV("12345"), 4, 2, S("abcdefghij5")); + test(S("abcdefghij"), 10, 1, SV("12345"), 5, 0, S("abcdefghij")); + test(S("abcdefghij"), 10, 1, SV("12345"), 5, 1, S("abcdefghij")); + test(S("abcdefghij"), 10, 1, SV("12345"), 6, 0, S("can't happen")); + test(S("abcdefghij"), 10, 1, SV("1234567890"), 0, 0, S("abcdefghij")); + test(S("abcdefghij"), 10, 1, SV("1234567890"), 0, 1, S("abcdefghij1")); + test(S("abcdefghij"), 10, 1, SV("1234567890"), 0, 5, S("abcdefghij12345")); + test(S("abcdefghij"), 10, 1, SV("1234567890"), 0, 9, S("abcdefghij123456789")); + test(S("abcdefghij"), 10, 1, SV("1234567890"), 0, 10, S("abcdefghij1234567890")); + test(S("abcdefghij"), 10, 1, SV("1234567890"), 0, 11, S("abcdefghij1234567890")); + test(S("abcdefghij"), 10, 1, SV("1234567890"), 1, 0, S("abcdefghij")); + test(S("abcdefghij"), 10, 1, SV("1234567890"), 1, 1, S("abcdefghij2")); + test(S("abcdefghij"), 10, 1, SV("1234567890"), 1, 4, S("abcdefghij2345")); + test(S("abcdefghij"), 10, 1, SV("1234567890"), 1, 8, S("abcdefghij23456789")); + test(S("abcdefghij"), 10, 1, SV("1234567890"), 1, 9, S("abcdefghij234567890")); + test(S("abcdefghij"), 10, 1, SV("1234567890"), 1, 10, S("abcdefghij234567890")); + test(S("abcdefghij"), 10, 1, SV("1234567890"), 5, 0, S("abcdefghij")); + test(S("abcdefghij"), 10, 1, SV("1234567890"), 5, 1, S("abcdefghij6")); + test(S("abcdefghij"), 10, 1, SV("1234567890"), 5, 2, S("abcdefghij67")); + test(S("abcdefghij"), 10, 1, SV("1234567890"), 5, 4, S("abcdefghij6789")); + test(S("abcdefghij"), 10, 1, SV("1234567890"), 5, 5, S("abcdefghij67890")); + test(S("abcdefghij"), 10, 1, SV("1234567890"), 5, 6, S("abcdefghij67890")); + test(S("abcdefghij"), 10, 1, SV("1234567890"), 9, 0, S("abcdefghij")); + test(S("abcdefghij"), 10, 1, SV("1234567890"), 9, 1, S("abcdefghij0")); + test(S("abcdefghij"), 10, 1, SV("1234567890"), 9, 2, S("abcdefghij0")); + test(S("abcdefghij"), 10, 1, SV("1234567890"), 10, 0, S("abcdefghij")); +} + +template +void test36() +{ + test(S("abcdefghij"), 10, 1, SV("1234567890"), 10, 1, S("abcdefghij")); + test(S("abcdefghij"), 10, 1, SV("1234567890"), 11, 0, S("can't happen")); + test(S("abcdefghij"), 10, 1, SV("12345678901234567890"), 0, 0, S("abcdefghij")); + test(S("abcdefghij"), 10, 1, SV("12345678901234567890"), 0, 1, S("abcdefghij1")); + test(S("abcdefghij"), 10, 1, SV("12345678901234567890"), 0, 10, S("abcdefghij1234567890")); + test(S("abcdefghij"), 10, 1, SV("12345678901234567890"), 0, 19, S("abcdefghij1234567890123456789")); + test(S("abcdefghij"), 10, 1, SV("12345678901234567890"), 0, 20, S("abcdefghij12345678901234567890")); + test(S("abcdefghij"), 10, 1, SV("12345678901234567890"), 0, 21, S("abcdefghij12345678901234567890")); + test(S("abcdefghij"), 10, 1, SV("12345678901234567890"), 1, 0, S("abcdefghij")); + test(S("abcdefghij"), 10, 1, SV("12345678901234567890"), 1, 1, S("abcdefghij2")); + test(S("abcdefghij"), 10, 1, SV("12345678901234567890"), 1, 9, S("abcdefghij234567890")); + test(S("abcdefghij"), 10, 1, SV("12345678901234567890"), 1, 18, S("abcdefghij234567890123456789")); + test(S("abcdefghij"), 10, 1, SV("12345678901234567890"), 1, 19, S("abcdefghij2345678901234567890")); + test(S("abcdefghij"), 10, 1, SV("12345678901234567890"), 1, 20, S("abcdefghij2345678901234567890")); + test(S("abcdefghij"), 10, 1, SV("12345678901234567890"), 10, 0, S("abcdefghij")); + test(S("abcdefghij"), 10, 1, SV("12345678901234567890"), 10, 1, S("abcdefghij1")); + test(S("abcdefghij"), 10, 1, SV("12345678901234567890"), 10, 5, S("abcdefghij12345")); + test(S("abcdefghij"), 10, 1, SV("12345678901234567890"), 10, 9, S("abcdefghij123456789")); + test(S("abcdefghij"), 10, 1, SV("12345678901234567890"), 10, 10, S("abcdefghij1234567890")); + test(S("abcdefghij"), 10, 1, SV("12345678901234567890"), 10, 11, S("abcdefghij1234567890")); + test(S("abcdefghij"), 10, 1, SV("12345678901234567890"), 19, 0, S("abcdefghij")); + test(S("abcdefghij"), 10, 1, SV("12345678901234567890"), 19, 1, S("abcdefghij0")); + test(S("abcdefghij"), 10, 1, SV("12345678901234567890"), 19, 2, S("abcdefghij0")); + test(S("abcdefghij"), 10, 1, SV("12345678901234567890"), 20, 0, S("abcdefghij")); + test(S("abcdefghij"), 10, 1, SV("12345678901234567890"), 20, 1, S("abcdefghij")); + test(S("abcdefghij"), 10, 1, SV("12345678901234567890"), 21, 0, S("can't happen")); + test(S("abcdefghij"), 11, 0, SV(""), 0, 0, S("can't happen")); + test(S("abcdefghij"), 11, 0, SV(""), 0, 1, S("can't happen")); + test(S("abcdefghij"), 11, 0, SV(""), 1, 0, S("can't happen")); + test(S("abcdefghij"), 11, 0, SV("12345"), 0, 0, S("can't happen")); + test(S("abcdefghij"), 11, 0, SV("12345"), 0, 1, S("can't happen")); + test(S("abcdefghij"), 11, 0, SV("12345"), 0, 2, S("can't happen")); + test(S("abcdefghij"), 11, 0, SV("12345"), 0, 4, S("can't happen")); + test(S("abcdefghij"), 11, 0, SV("12345"), 0, 5, S("can't happen")); + test(S("abcdefghij"), 11, 0, SV("12345"), 0, 6, S("can't happen")); + test(S("abcdefghij"), 11, 0, SV("12345"), 1, 0, S("can't happen")); + test(S("abcdefghij"), 11, 0, SV("12345"), 1, 1, S("can't happen")); + test(S("abcdefghij"), 11, 0, SV("12345"), 1, 2, S("can't happen")); + test(S("abcdefghij"), 11, 0, SV("12345"), 1, 3, S("can't happen")); + test(S("abcdefghij"), 11, 0, SV("12345"), 1, 4, S("can't happen")); + test(S("abcdefghij"), 11, 0, SV("12345"), 1, 5, S("can't happen")); + test(S("abcdefghij"), 11, 0, SV("12345"), 2, 0, S("can't happen")); + test(S("abcdefghij"), 11, 0, SV("12345"), 2, 1, S("can't happen")); + test(S("abcdefghij"), 11, 0, SV("12345"), 2, 2, S("can't happen")); + test(S("abcdefghij"), 11, 0, SV("12345"), 2, 3, S("can't happen")); + test(S("abcdefghij"), 11, 0, SV("12345"), 2, 4, S("can't happen")); + test(S("abcdefghij"), 11, 0, SV("12345"), 4, 0, S("can't happen")); + test(S("abcdefghij"), 11, 0, SV("12345"), 4, 1, S("can't happen")); + test(S("abcdefghij"), 11, 0, SV("12345"), 4, 2, S("can't happen")); + test(S("abcdefghij"), 11, 0, SV("12345"), 5, 0, S("can't happen")); + test(S("abcdefghij"), 11, 0, SV("12345"), 5, 1, S("can't happen")); + test(S("abcdefghij"), 11, 0, SV("12345"), 6, 0, S("can't happen")); + test(S("abcdefghij"), 11, 0, SV("1234567890"), 0, 0, S("can't happen")); + test(S("abcdefghij"), 11, 0, SV("1234567890"), 0, 1, S("can't happen")); + test(S("abcdefghij"), 11, 0, SV("1234567890"), 0, 5, S("can't happen")); + test(S("abcdefghij"), 11, 0, SV("1234567890"), 0, 9, S("can't happen")); + test(S("abcdefghij"), 11, 0, SV("1234567890"), 0, 10, S("can't happen")); + test(S("abcdefghij"), 11, 0, SV("1234567890"), 0, 11, S("can't happen")); + test(S("abcdefghij"), 11, 0, SV("1234567890"), 1, 0, S("can't happen")); + test(S("abcdefghij"), 11, 0, SV("1234567890"), 1, 1, S("can't happen")); + test(S("abcdefghij"), 11, 0, SV("1234567890"), 1, 4, S("can't happen")); + test(S("abcdefghij"), 11, 0, SV("1234567890"), 1, 8, S("can't happen")); + test(S("abcdefghij"), 11, 0, SV("1234567890"), 1, 9, S("can't happen")); + test(S("abcdefghij"), 11, 0, SV("1234567890"), 1, 10, S("can't happen")); + test(S("abcdefghij"), 11, 0, SV("1234567890"), 5, 0, S("can't happen")); + test(S("abcdefghij"), 11, 0, SV("1234567890"), 5, 1, S("can't happen")); + test(S("abcdefghij"), 11, 0, SV("1234567890"), 5, 2, S("can't happen")); + test(S("abcdefghij"), 11, 0, SV("1234567890"), 5, 4, S("can't happen")); + test(S("abcdefghij"), 11, 0, SV("1234567890"), 5, 5, S("can't happen")); + test(S("abcdefghij"), 11, 0, SV("1234567890"), 5, 6, S("can't happen")); + test(S("abcdefghij"), 11, 0, SV("1234567890"), 9, 0, S("can't happen")); + test(S("abcdefghij"), 11, 0, SV("1234567890"), 9, 1, S("can't happen")); + test(S("abcdefghij"), 11, 0, SV("1234567890"), 9, 2, S("can't happen")); + test(S("abcdefghij"), 11, 0, SV("1234567890"), 10, 0, S("can't happen")); + test(S("abcdefghij"), 11, 0, SV("1234567890"), 10, 1, S("can't happen")); + test(S("abcdefghij"), 11, 0, SV("1234567890"), 11, 0, S("can't happen")); + test(S("abcdefghij"), 11, 0, SV("12345678901234567890"), 0, 0, S("can't happen")); + test(S("abcdefghij"), 11, 0, SV("12345678901234567890"), 0, 1, S("can't happen")); + test(S("abcdefghij"), 11, 0, SV("12345678901234567890"), 0, 10, S("can't happen")); + test(S("abcdefghij"), 11, 0, SV("12345678901234567890"), 0, 19, S("can't happen")); + test(S("abcdefghij"), 11, 0, SV("12345678901234567890"), 0, 20, S("can't happen")); + test(S("abcdefghij"), 11, 0, SV("12345678901234567890"), 0, 21, S("can't happen")); + test(S("abcdefghij"), 11, 0, SV("12345678901234567890"), 1, 0, S("can't happen")); + test(S("abcdefghij"), 11, 0, SV("12345678901234567890"), 1, 1, S("can't happen")); + test(S("abcdefghij"), 11, 0, SV("12345678901234567890"), 1, 9, S("can't happen")); + test(S("abcdefghij"), 11, 0, SV("12345678901234567890"), 1, 18, S("can't happen")); + test(S("abcdefghij"), 11, 0, SV("12345678901234567890"), 1, 19, S("can't happen")); + test(S("abcdefghij"), 11, 0, SV("12345678901234567890"), 1, 20, S("can't happen")); + test(S("abcdefghij"), 11, 0, SV("12345678901234567890"), 10, 0, S("can't happen")); + test(S("abcdefghij"), 11, 0, SV("12345678901234567890"), 10, 1, S("can't happen")); + test(S("abcdefghij"), 11, 0, SV("12345678901234567890"), 10, 5, S("can't happen")); + test(S("abcdefghij"), 11, 0, SV("12345678901234567890"), 10, 9, S("can't happen")); + test(S("abcdefghij"), 11, 0, SV("12345678901234567890"), 10, 10, S("can't happen")); + test(S("abcdefghij"), 11, 0, SV("12345678901234567890"), 10, 11, S("can't happen")); + test(S("abcdefghij"), 11, 0, SV("12345678901234567890"), 19, 0, S("can't happen")); + test(S("abcdefghij"), 11, 0, SV("12345678901234567890"), 19, 1, S("can't happen")); + test(S("abcdefghij"), 11, 0, SV("12345678901234567890"), 19, 2, S("can't happen")); + test(S("abcdefghij"), 11, 0, SV("12345678901234567890"), 20, 0, S("can't happen")); + test(S("abcdefghij"), 11, 0, SV("12345678901234567890"), 20, 1, S("can't happen")); + test(S("abcdefghij"), 11, 0, SV("12345678901234567890"), 21, 0, S("can't happen")); +} + +template +void test37() +{ + test(S("abcdefghijklmnopqrst"), 0, 0, SV(""), 0, 0, S("abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, 0, SV(""), 0, 1, S("abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, 0, SV(""), 1, 0, S("can't happen")); + test(S("abcdefghijklmnopqrst"), 0, 0, SV("12345"), 0, 0, S("abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, 0, SV("12345"), 0, 1, S("1abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, 0, SV("12345"), 0, 2, S("12abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, 0, SV("12345"), 0, 4, S("1234abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, 0, SV("12345"), 0, 5, S("12345abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, 0, SV("12345"), 0, 6, S("12345abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, 0, SV("12345"), 1, 0, S("abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, 0, SV("12345"), 1, 1, S("2abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, 0, SV("12345"), 1, 2, S("23abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, 0, SV("12345"), 1, 3, S("234abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, 0, SV("12345"), 1, 4, S("2345abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, 0, SV("12345"), 1, 5, S("2345abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, 0, SV("12345"), 2, 0, S("abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, 0, SV("12345"), 2, 1, S("3abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, 0, SV("12345"), 2, 2, S("34abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, 0, SV("12345"), 2, 3, S("345abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, 0, SV("12345"), 2, 4, S("345abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, 0, SV("12345"), 4, 0, S("abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, 0, SV("12345"), 4, 1, S("5abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, 0, SV("12345"), 4, 2, S("5abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, 0, SV("12345"), 5, 0, S("abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, 0, SV("12345"), 5, 1, S("abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, 0, SV("12345"), 6, 0, S("can't happen")); + test(S("abcdefghijklmnopqrst"), 0, 0, SV("1234567890"), 0, 0, S("abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, 0, SV("1234567890"), 0, 1, S("1abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, 0, SV("1234567890"), 0, 5, S("12345abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, 0, SV("1234567890"), 0, 9, S("123456789abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, 0, SV("1234567890"), 0, 10, S("1234567890abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, 0, SV("1234567890"), 0, 11, S("1234567890abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, 0, SV("1234567890"), 1, 0, S("abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, 0, SV("1234567890"), 1, 1, S("2abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, 0, SV("1234567890"), 1, 4, S("2345abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, 0, SV("1234567890"), 1, 8, S("23456789abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, 0, SV("1234567890"), 1, 9, S("234567890abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, 0, SV("1234567890"), 1, 10, S("234567890abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, 0, SV("1234567890"), 5, 0, S("abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, 0, SV("1234567890"), 5, 1, S("6abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, 0, SV("1234567890"), 5, 2, S("67abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, 0, SV("1234567890"), 5, 4, S("6789abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, 0, SV("1234567890"), 5, 5, S("67890abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, 0, SV("1234567890"), 5, 6, S("67890abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, 0, SV("1234567890"), 9, 0, S("abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, 0, SV("1234567890"), 9, 1, S("0abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, 0, SV("1234567890"), 9, 2, S("0abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, 0, SV("1234567890"), 10, 0, S("abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, 0, SV("1234567890"), 10, 1, S("abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, 0, SV("1234567890"), 11, 0, S("can't happen")); + test(S("abcdefghijklmnopqrst"), 0, 0, SV("12345678901234567890"), 0, 0, S("abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, 0, SV("12345678901234567890"), 0, 1, S("1abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, 0, SV("12345678901234567890"), 0, 10, S("1234567890abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, 0, SV("12345678901234567890"), 0, 19, S("1234567890123456789abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, 0, SV("12345678901234567890"), 0, 20, S("12345678901234567890abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, 0, SV("12345678901234567890"), 0, 21, S("12345678901234567890abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, 0, SV("12345678901234567890"), 1, 0, S("abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, 0, SV("12345678901234567890"), 1, 1, S("2abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, 0, SV("12345678901234567890"), 1, 9, S("234567890abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, 0, SV("12345678901234567890"), 1, 18, S("234567890123456789abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, 0, SV("12345678901234567890"), 1, 19, S("2345678901234567890abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, 0, SV("12345678901234567890"), 1, 20, S("2345678901234567890abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, 0, SV("12345678901234567890"), 10, 0, S("abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, 0, SV("12345678901234567890"), 10, 1, S("1abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, 0, SV("12345678901234567890"), 10, 5, S("12345abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, 0, SV("12345678901234567890"), 10, 9, S("123456789abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, 0, SV("12345678901234567890"), 10, 10, S("1234567890abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, 0, SV("12345678901234567890"), 10, 11, S("1234567890abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, 0, SV("12345678901234567890"), 19, 0, S("abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, 0, SV("12345678901234567890"), 19, 1, S("0abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, 0, SV("12345678901234567890"), 19, 2, S("0abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, 0, SV("12345678901234567890"), 20, 0, S("abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, 0, SV("12345678901234567890"), 20, 1, S("abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, 0, SV("12345678901234567890"), 21, 0, S("can't happen")); + test(S("abcdefghijklmnopqrst"), 0, 1, SV(""), 0, 0, S("bcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, 1, SV(""), 0, 1, S("bcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, 1, SV(""), 1, 0, S("can't happen")); + test(S("abcdefghijklmnopqrst"), 0, 1, SV("12345"), 0, 0, S("bcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, 1, SV("12345"), 0, 1, S("1bcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, 1, SV("12345"), 0, 2, S("12bcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, 1, SV("12345"), 0, 4, S("1234bcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, 1, SV("12345"), 0, 5, S("12345bcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, 1, SV("12345"), 0, 6, S("12345bcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, 1, SV("12345"), 1, 0, S("bcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, 1, SV("12345"), 1, 1, S("2bcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, 1, SV("12345"), 1, 2, S("23bcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, 1, SV("12345"), 1, 3, S("234bcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, 1, SV("12345"), 1, 4, S("2345bcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, 1, SV("12345"), 1, 5, S("2345bcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, 1, SV("12345"), 2, 0, S("bcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, 1, SV("12345"), 2, 1, S("3bcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, 1, SV("12345"), 2, 2, S("34bcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, 1, SV("12345"), 2, 3, S("345bcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, 1, SV("12345"), 2, 4, S("345bcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, 1, SV("12345"), 4, 0, S("bcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, 1, SV("12345"), 4, 1, S("5bcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, 1, SV("12345"), 4, 2, S("5bcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, 1, SV("12345"), 5, 0, S("bcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, 1, SV("12345"), 5, 1, S("bcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, 1, SV("12345"), 6, 0, S("can't happen")); +} + +template +void test38() +{ + test(S("abcdefghijklmnopqrst"), 0, 1, SV("1234567890"), 0, 0, S("bcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, 1, SV("1234567890"), 0, 1, S("1bcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, 1, SV("1234567890"), 0, 5, S("12345bcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, 1, SV("1234567890"), 0, 9, S("123456789bcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, 1, SV("1234567890"), 0, 10, S("1234567890bcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, 1, SV("1234567890"), 0, 11, S("1234567890bcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, 1, SV("1234567890"), 1, 0, S("bcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, 1, SV("1234567890"), 1, 1, S("2bcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, 1, SV("1234567890"), 1, 4, S("2345bcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, 1, SV("1234567890"), 1, 8, S("23456789bcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, 1, SV("1234567890"), 1, 9, S("234567890bcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, 1, SV("1234567890"), 1, 10, S("234567890bcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, 1, SV("1234567890"), 5, 0, S("bcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, 1, SV("1234567890"), 5, 1, S("6bcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, 1, SV("1234567890"), 5, 2, S("67bcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, 1, SV("1234567890"), 5, 4, S("6789bcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, 1, SV("1234567890"), 5, 5, S("67890bcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, 1, SV("1234567890"), 5, 6, S("67890bcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, 1, SV("1234567890"), 9, 0, S("bcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, 1, SV("1234567890"), 9, 1, S("0bcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, 1, SV("1234567890"), 9, 2, S("0bcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, 1, SV("1234567890"), 10, 0, S("bcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, 1, SV("1234567890"), 10, 1, S("bcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, 1, SV("1234567890"), 11, 0, S("can't happen")); + test(S("abcdefghijklmnopqrst"), 0, 1, SV("12345678901234567890"), 0, 0, S("bcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, 1, SV("12345678901234567890"), 0, 1, S("1bcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, 1, SV("12345678901234567890"), 0, 10, S("1234567890bcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, 1, SV("12345678901234567890"), 0, 19, S("1234567890123456789bcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, 1, SV("12345678901234567890"), 0, 20, S("12345678901234567890bcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, 1, SV("12345678901234567890"), 0, 21, S("12345678901234567890bcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, 1, SV("12345678901234567890"), 1, 0, S("bcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, 1, SV("12345678901234567890"), 1, 1, S("2bcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, 1, SV("12345678901234567890"), 1, 9, S("234567890bcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, 1, SV("12345678901234567890"), 1, 18, S("234567890123456789bcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, 1, SV("12345678901234567890"), 1, 19, S("2345678901234567890bcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, 1, SV("12345678901234567890"), 1, 20, S("2345678901234567890bcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, 1, SV("12345678901234567890"), 10, 0, S("bcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, 1, SV("12345678901234567890"), 10, 1, S("1bcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, 1, SV("12345678901234567890"), 10, 5, S("12345bcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, 1, SV("12345678901234567890"), 10, 9, S("123456789bcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, 1, SV("12345678901234567890"), 10, 10, S("1234567890bcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, 1, SV("12345678901234567890"), 10, 11, S("1234567890bcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, 1, SV("12345678901234567890"), 19, 0, S("bcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, 1, SV("12345678901234567890"), 19, 1, S("0bcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, 1, SV("12345678901234567890"), 19, 2, S("0bcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, 1, SV("12345678901234567890"), 20, 0, S("bcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, 1, SV("12345678901234567890"), 20, 1, S("bcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, 1, SV("12345678901234567890"), 21, 0, S("can't happen")); + test(S("abcdefghijklmnopqrst"), 0, 10, SV(""), 0, 0, S("klmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, 10, SV(""), 0, 1, S("klmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, 10, SV(""), 1, 0, S("can't happen")); + test(S("abcdefghijklmnopqrst"), 0, 10, SV("12345"), 0, 0, S("klmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, 10, SV("12345"), 0, 1, S("1klmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, 10, SV("12345"), 0, 2, S("12klmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, 10, SV("12345"), 0, 4, S("1234klmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, 10, SV("12345"), 0, 5, S("12345klmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, 10, SV("12345"), 0, 6, S("12345klmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, 10, SV("12345"), 1, 0, S("klmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, 10, SV("12345"), 1, 1, S("2klmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, 10, SV("12345"), 1, 2, S("23klmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, 10, SV("12345"), 1, 3, S("234klmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, 10, SV("12345"), 1, 4, S("2345klmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, 10, SV("12345"), 1, 5, S("2345klmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, 10, SV("12345"), 2, 0, S("klmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, 10, SV("12345"), 2, 1, S("3klmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, 10, SV("12345"), 2, 2, S("34klmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, 10, SV("12345"), 2, 3, S("345klmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, 10, SV("12345"), 2, 4, S("345klmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, 10, SV("12345"), 4, 0, S("klmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, 10, SV("12345"), 4, 1, S("5klmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, 10, SV("12345"), 4, 2, S("5klmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, 10, SV("12345"), 5, 0, S("klmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, 10, SV("12345"), 5, 1, S("klmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, 10, SV("12345"), 6, 0, S("can't happen")); + test(S("abcdefghijklmnopqrst"), 0, 10, SV("1234567890"), 0, 0, S("klmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, 10, SV("1234567890"), 0, 1, S("1klmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, 10, SV("1234567890"), 0, 5, S("12345klmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, 10, SV("1234567890"), 0, 9, S("123456789klmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, 10, SV("1234567890"), 0, 10, S("1234567890klmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, 10, SV("1234567890"), 0, 11, S("1234567890klmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, 10, SV("1234567890"), 1, 0, S("klmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, 10, SV("1234567890"), 1, 1, S("2klmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, 10, SV("1234567890"), 1, 4, S("2345klmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, 10, SV("1234567890"), 1, 8, S("23456789klmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, 10, SV("1234567890"), 1, 9, S("234567890klmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, 10, SV("1234567890"), 1, 10, S("234567890klmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, 10, SV("1234567890"), 5, 0, S("klmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, 10, SV("1234567890"), 5, 1, S("6klmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, 10, SV("1234567890"), 5, 2, S("67klmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, 10, SV("1234567890"), 5, 4, S("6789klmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, 10, SV("1234567890"), 5, 5, S("67890klmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, 10, SV("1234567890"), 5, 6, S("67890klmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, 10, SV("1234567890"), 9, 0, S("klmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, 10, SV("1234567890"), 9, 1, S("0klmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, 10, SV("1234567890"), 9, 2, S("0klmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, 10, SV("1234567890"), 10, 0, S("klmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, 10, SV("1234567890"), 10, 1, S("klmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, 10, SV("1234567890"), 11, 0, S("can't happen")); + test(S("abcdefghijklmnopqrst"), 0, 10, SV("12345678901234567890"), 0, 0, S("klmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, 10, SV("12345678901234567890"), 0, 1, S("1klmnopqrst")); +} + +template +void test39() +{ + test(S("abcdefghijklmnopqrst"), 0, 10, SV("12345678901234567890"), 0, 10, S("1234567890klmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, 10, SV("12345678901234567890"), 0, 19, S("1234567890123456789klmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, 10, SV("12345678901234567890"), 0, 20, S("12345678901234567890klmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, 10, SV("12345678901234567890"), 0, 21, S("12345678901234567890klmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, 10, SV("12345678901234567890"), 1, 0, S("klmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, 10, SV("12345678901234567890"), 1, 1, S("2klmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, 10, SV("12345678901234567890"), 1, 9, S("234567890klmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, 10, SV("12345678901234567890"), 1, 18, S("234567890123456789klmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, 10, SV("12345678901234567890"), 1, 19, S("2345678901234567890klmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, 10, SV("12345678901234567890"), 1, 20, S("2345678901234567890klmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, 10, SV("12345678901234567890"), 10, 0, S("klmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, 10, SV("12345678901234567890"), 10, 1, S("1klmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, 10, SV("12345678901234567890"), 10, 5, S("12345klmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, 10, SV("12345678901234567890"), 10, 9, S("123456789klmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, 10, SV("12345678901234567890"), 10, 10, S("1234567890klmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, 10, SV("12345678901234567890"), 10, 11, S("1234567890klmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, 10, SV("12345678901234567890"), 19, 0, S("klmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, 10, SV("12345678901234567890"), 19, 1, S("0klmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, 10, SV("12345678901234567890"), 19, 2, S("0klmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, 10, SV("12345678901234567890"), 20, 0, S("klmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, 10, SV("12345678901234567890"), 20, 1, S("klmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, 10, SV("12345678901234567890"), 21, 0, S("can't happen")); + test(S("abcdefghijklmnopqrst"), 0, 19, SV(""), 0, 0, S("t")); + test(S("abcdefghijklmnopqrst"), 0, 19, SV(""), 0, 1, S("t")); + test(S("abcdefghijklmnopqrst"), 0, 19, SV(""), 1, 0, S("can't happen")); + test(S("abcdefghijklmnopqrst"), 0, 19, SV("12345"), 0, 0, S("t")); + test(S("abcdefghijklmnopqrst"), 0, 19, SV("12345"), 0, 1, S("1t")); + test(S("abcdefghijklmnopqrst"), 0, 19, SV("12345"), 0, 2, S("12t")); + test(S("abcdefghijklmnopqrst"), 0, 19, SV("12345"), 0, 4, S("1234t")); + test(S("abcdefghijklmnopqrst"), 0, 19, SV("12345"), 0, 5, S("12345t")); + test(S("abcdefghijklmnopqrst"), 0, 19, SV("12345"), 0, 6, S("12345t")); + test(S("abcdefghijklmnopqrst"), 0, 19, SV("12345"), 1, 0, S("t")); + test(S("abcdefghijklmnopqrst"), 0, 19, SV("12345"), 1, 1, S("2t")); + test(S("abcdefghijklmnopqrst"), 0, 19, SV("12345"), 1, 2, S("23t")); + test(S("abcdefghijklmnopqrst"), 0, 19, SV("12345"), 1, 3, S("234t")); + test(S("abcdefghijklmnopqrst"), 0, 19, SV("12345"), 1, 4, S("2345t")); + test(S("abcdefghijklmnopqrst"), 0, 19, SV("12345"), 1, 5, S("2345t")); + test(S("abcdefghijklmnopqrst"), 0, 19, SV("12345"), 2, 0, S("t")); + test(S("abcdefghijklmnopqrst"), 0, 19, SV("12345"), 2, 1, S("3t")); + test(S("abcdefghijklmnopqrst"), 0, 19, SV("12345"), 2, 2, S("34t")); + test(S("abcdefghijklmnopqrst"), 0, 19, SV("12345"), 2, 3, S("345t")); + test(S("abcdefghijklmnopqrst"), 0, 19, SV("12345"), 2, 4, S("345t")); + test(S("abcdefghijklmnopqrst"), 0, 19, SV("12345"), 4, 0, S("t")); + test(S("abcdefghijklmnopqrst"), 0, 19, SV("12345"), 4, 1, S("5t")); + test(S("abcdefghijklmnopqrst"), 0, 19, SV("12345"), 4, 2, S("5t")); + test(S("abcdefghijklmnopqrst"), 0, 19, SV("12345"), 5, 0, S("t")); + test(S("abcdefghijklmnopqrst"), 0, 19, SV("12345"), 5, 1, S("t")); + test(S("abcdefghijklmnopqrst"), 0, 19, SV("12345"), 6, 0, S("can't happen")); + test(S("abcdefghijklmnopqrst"), 0, 19, SV("1234567890"), 0, 0, S("t")); + test(S("abcdefghijklmnopqrst"), 0, 19, SV("1234567890"), 0, 1, S("1t")); + test(S("abcdefghijklmnopqrst"), 0, 19, SV("1234567890"), 0, 5, S("12345t")); + test(S("abcdefghijklmnopqrst"), 0, 19, SV("1234567890"), 0, 9, S("123456789t")); + test(S("abcdefghijklmnopqrst"), 0, 19, SV("1234567890"), 0, 10, S("1234567890t")); + test(S("abcdefghijklmnopqrst"), 0, 19, SV("1234567890"), 0, 11, S("1234567890t")); + test(S("abcdefghijklmnopqrst"), 0, 19, SV("1234567890"), 1, 0, S("t")); + test(S("abcdefghijklmnopqrst"), 0, 19, SV("1234567890"), 1, 1, S("2t")); + test(S("abcdefghijklmnopqrst"), 0, 19, SV("1234567890"), 1, 4, S("2345t")); + test(S("abcdefghijklmnopqrst"), 0, 19, SV("1234567890"), 1, 8, S("23456789t")); + test(S("abcdefghijklmnopqrst"), 0, 19, SV("1234567890"), 1, 9, S("234567890t")); + test(S("abcdefghijklmnopqrst"), 0, 19, SV("1234567890"), 1, 10, S("234567890t")); + test(S("abcdefghijklmnopqrst"), 0, 19, SV("1234567890"), 5, 0, S("t")); + test(S("abcdefghijklmnopqrst"), 0, 19, SV("1234567890"), 5, 1, S("6t")); + test(S("abcdefghijklmnopqrst"), 0, 19, SV("1234567890"), 5, 2, S("67t")); + test(S("abcdefghijklmnopqrst"), 0, 19, SV("1234567890"), 5, 4, S("6789t")); + test(S("abcdefghijklmnopqrst"), 0, 19, SV("1234567890"), 5, 5, S("67890t")); + test(S("abcdefghijklmnopqrst"), 0, 19, SV("1234567890"), 5, 6, S("67890t")); + test(S("abcdefghijklmnopqrst"), 0, 19, SV("1234567890"), 9, 0, S("t")); + test(S("abcdefghijklmnopqrst"), 0, 19, SV("1234567890"), 9, 1, S("0t")); + test(S("abcdefghijklmnopqrst"), 0, 19, SV("1234567890"), 9, 2, S("0t")); + test(S("abcdefghijklmnopqrst"), 0, 19, SV("1234567890"), 10, 0, S("t")); + test(S("abcdefghijklmnopqrst"), 0, 19, SV("1234567890"), 10, 1, S("t")); + test(S("abcdefghijklmnopqrst"), 0, 19, SV("1234567890"), 11, 0, S("can't happen")); + test(S("abcdefghijklmnopqrst"), 0, 19, SV("12345678901234567890"), 0, 0, S("t")); + test(S("abcdefghijklmnopqrst"), 0, 19, SV("12345678901234567890"), 0, 1, S("1t")); + test(S("abcdefghijklmnopqrst"), 0, 19, SV("12345678901234567890"), 0, 10, S("1234567890t")); + test(S("abcdefghijklmnopqrst"), 0, 19, SV("12345678901234567890"), 0, 19, S("1234567890123456789t")); + test(S("abcdefghijklmnopqrst"), 0, 19, SV("12345678901234567890"), 0, 20, S("12345678901234567890t")); + test(S("abcdefghijklmnopqrst"), 0, 19, SV("12345678901234567890"), 0, 21, S("12345678901234567890t")); + test(S("abcdefghijklmnopqrst"), 0, 19, SV("12345678901234567890"), 1, 0, S("t")); + test(S("abcdefghijklmnopqrst"), 0, 19, SV("12345678901234567890"), 1, 1, S("2t")); + test(S("abcdefghijklmnopqrst"), 0, 19, SV("12345678901234567890"), 1, 9, S("234567890t")); + test(S("abcdefghijklmnopqrst"), 0, 19, SV("12345678901234567890"), 1, 18, S("234567890123456789t")); + test(S("abcdefghijklmnopqrst"), 0, 19, SV("12345678901234567890"), 1, 19, S("2345678901234567890t")); + test(S("abcdefghijklmnopqrst"), 0, 19, SV("12345678901234567890"), 1, 20, S("2345678901234567890t")); + test(S("abcdefghijklmnopqrst"), 0, 19, SV("12345678901234567890"), 10, 0, S("t")); + test(S("abcdefghijklmnopqrst"), 0, 19, SV("12345678901234567890"), 10, 1, S("1t")); + test(S("abcdefghijklmnopqrst"), 0, 19, SV("12345678901234567890"), 10, 5, S("12345t")); + test(S("abcdefghijklmnopqrst"), 0, 19, SV("12345678901234567890"), 10, 9, S("123456789t")); + test(S("abcdefghijklmnopqrst"), 0, 19, SV("12345678901234567890"), 10, 10, S("1234567890t")); + test(S("abcdefghijklmnopqrst"), 0, 19, SV("12345678901234567890"), 10, 11, S("1234567890t")); + test(S("abcdefghijklmnopqrst"), 0, 19, SV("12345678901234567890"), 19, 0, S("t")); + test(S("abcdefghijklmnopqrst"), 0, 19, SV("12345678901234567890"), 19, 1, S("0t")); + test(S("abcdefghijklmnopqrst"), 0, 19, SV("12345678901234567890"), 19, 2, S("0t")); + test(S("abcdefghijklmnopqrst"), 0, 19, SV("12345678901234567890"), 20, 0, S("t")); + test(S("abcdefghijklmnopqrst"), 0, 19, SV("12345678901234567890"), 20, 1, S("t")); + test(S("abcdefghijklmnopqrst"), 0, 19, SV("12345678901234567890"), 21, 0, S("can't happen")); + test(S("abcdefghijklmnopqrst"), 0, 20, SV(""), 0, 0, S("")); + test(S("abcdefghijklmnopqrst"), 0, 20, SV(""), 0, 1, S("")); + test(S("abcdefghijklmnopqrst"), 0, 20, SV(""), 1, 0, S("can't happen")); + test(S("abcdefghijklmnopqrst"), 0, 20, SV("12345"), 0, 0, S("")); +} + +template +void test40() +{ + test(S("abcdefghijklmnopqrst"), 0, 20, SV("12345"), 0, 1, S("1")); + test(S("abcdefghijklmnopqrst"), 0, 20, SV("12345"), 0, 2, S("12")); + test(S("abcdefghijklmnopqrst"), 0, 20, SV("12345"), 0, 4, S("1234")); + test(S("abcdefghijklmnopqrst"), 0, 20, SV("12345"), 0, 5, S("12345")); + test(S("abcdefghijklmnopqrst"), 0, 20, SV("12345"), 0, 6, S("12345")); + test(S("abcdefghijklmnopqrst"), 0, 20, SV("12345"), 1, 0, S("")); + test(S("abcdefghijklmnopqrst"), 0, 20, SV("12345"), 1, 1, S("2")); + test(S("abcdefghijklmnopqrst"), 0, 20, SV("12345"), 1, 2, S("23")); + test(S("abcdefghijklmnopqrst"), 0, 20, SV("12345"), 1, 3, S("234")); + test(S("abcdefghijklmnopqrst"), 0, 20, SV("12345"), 1, 4, S("2345")); + test(S("abcdefghijklmnopqrst"), 0, 20, SV("12345"), 1, 5, S("2345")); + test(S("abcdefghijklmnopqrst"), 0, 20, SV("12345"), 2, 0, S("")); + test(S("abcdefghijklmnopqrst"), 0, 20, SV("12345"), 2, 1, S("3")); + test(S("abcdefghijklmnopqrst"), 0, 20, SV("12345"), 2, 2, S("34")); + test(S("abcdefghijklmnopqrst"), 0, 20, SV("12345"), 2, 3, S("345")); + test(S("abcdefghijklmnopqrst"), 0, 20, SV("12345"), 2, 4, S("345")); + test(S("abcdefghijklmnopqrst"), 0, 20, SV("12345"), 4, 0, S("")); + test(S("abcdefghijklmnopqrst"), 0, 20, SV("12345"), 4, 1, S("5")); + test(S("abcdefghijklmnopqrst"), 0, 20, SV("12345"), 4, 2, S("5")); + test(S("abcdefghijklmnopqrst"), 0, 20, SV("12345"), 5, 0, S("")); + test(S("abcdefghijklmnopqrst"), 0, 20, SV("12345"), 5, 1, S("")); + test(S("abcdefghijklmnopqrst"), 0, 20, SV("12345"), 6, 0, S("can't happen")); + test(S("abcdefghijklmnopqrst"), 0, 20, SV("1234567890"), 0, 0, S("")); + test(S("abcdefghijklmnopqrst"), 0, 20, SV("1234567890"), 0, 1, S("1")); + test(S("abcdefghijklmnopqrst"), 0, 20, SV("1234567890"), 0, 5, S("12345")); + test(S("abcdefghijklmnopqrst"), 0, 20, SV("1234567890"), 0, 9, S("123456789")); + test(S("abcdefghijklmnopqrst"), 0, 20, SV("1234567890"), 0, 10, S("1234567890")); + test(S("abcdefghijklmnopqrst"), 0, 20, SV("1234567890"), 0, 11, S("1234567890")); + test(S("abcdefghijklmnopqrst"), 0, 20, SV("1234567890"), 1, 0, S("")); + test(S("abcdefghijklmnopqrst"), 0, 20, SV("1234567890"), 1, 1, S("2")); + test(S("abcdefghijklmnopqrst"), 0, 20, SV("1234567890"), 1, 4, S("2345")); + test(S("abcdefghijklmnopqrst"), 0, 20, SV("1234567890"), 1, 8, S("23456789")); + test(S("abcdefghijklmnopqrst"), 0, 20, SV("1234567890"), 1, 9, S("234567890")); + test(S("abcdefghijklmnopqrst"), 0, 20, SV("1234567890"), 1, 10, S("234567890")); + test(S("abcdefghijklmnopqrst"), 0, 20, SV("1234567890"), 5, 0, S("")); + test(S("abcdefghijklmnopqrst"), 0, 20, SV("1234567890"), 5, 1, S("6")); + test(S("abcdefghijklmnopqrst"), 0, 20, SV("1234567890"), 5, 2, S("67")); + test(S("abcdefghijklmnopqrst"), 0, 20, SV("1234567890"), 5, 4, S("6789")); + test(S("abcdefghijklmnopqrst"), 0, 20, SV("1234567890"), 5, 5, S("67890")); + test(S("abcdefghijklmnopqrst"), 0, 20, SV("1234567890"), 5, 6, S("67890")); + test(S("abcdefghijklmnopqrst"), 0, 20, SV("1234567890"), 9, 0, S("")); + test(S("abcdefghijklmnopqrst"), 0, 20, SV("1234567890"), 9, 1, S("0")); + test(S("abcdefghijklmnopqrst"), 0, 20, SV("1234567890"), 9, 2, S("0")); + test(S("abcdefghijklmnopqrst"), 0, 20, SV("1234567890"), 10, 0, S("")); + test(S("abcdefghijklmnopqrst"), 0, 20, SV("1234567890"), 10, 1, S("")); + test(S("abcdefghijklmnopqrst"), 0, 20, SV("1234567890"), 11, 0, S("can't happen")); + test(S("abcdefghijklmnopqrst"), 0, 20, SV("12345678901234567890"), 0, 0, S("")); + test(S("abcdefghijklmnopqrst"), 0, 20, SV("12345678901234567890"), 0, 1, S("1")); + test(S("abcdefghijklmnopqrst"), 0, 20, SV("12345678901234567890"), 0, 10, S("1234567890")); + test(S("abcdefghijklmnopqrst"), 0, 20, SV("12345678901234567890"), 0, 19, S("1234567890123456789")); + test(S("abcdefghijklmnopqrst"), 0, 20, SV("12345678901234567890"), 0, 20, S("12345678901234567890")); + test(S("abcdefghijklmnopqrst"), 0, 20, SV("12345678901234567890"), 0, 21, S("12345678901234567890")); + test(S("abcdefghijklmnopqrst"), 0, 20, SV("12345678901234567890"), 1, 0, S("")); + test(S("abcdefghijklmnopqrst"), 0, 20, SV("12345678901234567890"), 1, 1, S("2")); + test(S("abcdefghijklmnopqrst"), 0, 20, SV("12345678901234567890"), 1, 9, S("234567890")); + test(S("abcdefghijklmnopqrst"), 0, 20, SV("12345678901234567890"), 1, 18, S("234567890123456789")); + test(S("abcdefghijklmnopqrst"), 0, 20, SV("12345678901234567890"), 1, 19, S("2345678901234567890")); + test(S("abcdefghijklmnopqrst"), 0, 20, SV("12345678901234567890"), 1, 20, S("2345678901234567890")); + test(S("abcdefghijklmnopqrst"), 0, 20, SV("12345678901234567890"), 10, 0, S("")); + test(S("abcdefghijklmnopqrst"), 0, 20, SV("12345678901234567890"), 10, 1, S("1")); + test(S("abcdefghijklmnopqrst"), 0, 20, SV("12345678901234567890"), 10, 5, S("12345")); + test(S("abcdefghijklmnopqrst"), 0, 20, SV("12345678901234567890"), 10, 9, S("123456789")); + test(S("abcdefghijklmnopqrst"), 0, 20, SV("12345678901234567890"), 10, 10, S("1234567890")); + test(S("abcdefghijklmnopqrst"), 0, 20, SV("12345678901234567890"), 10, 11, S("1234567890")); + test(S("abcdefghijklmnopqrst"), 0, 20, SV("12345678901234567890"), 19, 0, S("")); + test(S("abcdefghijklmnopqrst"), 0, 20, SV("12345678901234567890"), 19, 1, S("0")); + test(S("abcdefghijklmnopqrst"), 0, 20, SV("12345678901234567890"), 19, 2, S("0")); + test(S("abcdefghijklmnopqrst"), 0, 20, SV("12345678901234567890"), 20, 0, S("")); + test(S("abcdefghijklmnopqrst"), 0, 20, SV("12345678901234567890"), 20, 1, S("")); + test(S("abcdefghijklmnopqrst"), 0, 20, SV("12345678901234567890"), 21, 0, S("can't happen")); + test(S("abcdefghijklmnopqrst"), 0, 21, SV(""), 0, 0, S("")); + test(S("abcdefghijklmnopqrst"), 0, 21, SV(""), 0, 1, S("")); + test(S("abcdefghijklmnopqrst"), 0, 21, SV(""), 1, 0, S("can't happen")); + test(S("abcdefghijklmnopqrst"), 0, 21, SV("12345"), 0, 0, S("")); + test(S("abcdefghijklmnopqrst"), 0, 21, SV("12345"), 0, 1, S("1")); + test(S("abcdefghijklmnopqrst"), 0, 21, SV("12345"), 0, 2, S("12")); + test(S("abcdefghijklmnopqrst"), 0, 21, SV("12345"), 0, 4, S("1234")); + test(S("abcdefghijklmnopqrst"), 0, 21, SV("12345"), 0, 5, S("12345")); + test(S("abcdefghijklmnopqrst"), 0, 21, SV("12345"), 0, 6, S("12345")); + test(S("abcdefghijklmnopqrst"), 0, 21, SV("12345"), 1, 0, S("")); + test(S("abcdefghijklmnopqrst"), 0, 21, SV("12345"), 1, 1, S("2")); + test(S("abcdefghijklmnopqrst"), 0, 21, SV("12345"), 1, 2, S("23")); + test(S("abcdefghijklmnopqrst"), 0, 21, SV("12345"), 1, 3, S("234")); + test(S("abcdefghijklmnopqrst"), 0, 21, SV("12345"), 1, 4, S("2345")); + test(S("abcdefghijklmnopqrst"), 0, 21, SV("12345"), 1, 5, S("2345")); + test(S("abcdefghijklmnopqrst"), 0, 21, SV("12345"), 2, 0, S("")); + test(S("abcdefghijklmnopqrst"), 0, 21, SV("12345"), 2, 1, S("3")); + test(S("abcdefghijklmnopqrst"), 0, 21, SV("12345"), 2, 2, S("34")); + test(S("abcdefghijklmnopqrst"), 0, 21, SV("12345"), 2, 3, S("345")); + test(S("abcdefghijklmnopqrst"), 0, 21, SV("12345"), 2, 4, S("345")); + test(S("abcdefghijklmnopqrst"), 0, 21, SV("12345"), 4, 0, S("")); + test(S("abcdefghijklmnopqrst"), 0, 21, SV("12345"), 4, 1, S("5")); + test(S("abcdefghijklmnopqrst"), 0, 21, SV("12345"), 4, 2, S("5")); + test(S("abcdefghijklmnopqrst"), 0, 21, SV("12345"), 5, 0, S("")); + test(S("abcdefghijklmnopqrst"), 0, 21, SV("12345"), 5, 1, S("")); + test(S("abcdefghijklmnopqrst"), 0, 21, SV("12345"), 6, 0, S("can't happen")); + test(S("abcdefghijklmnopqrst"), 0, 21, SV("1234567890"), 0, 0, S("")); + test(S("abcdefghijklmnopqrst"), 0, 21, SV("1234567890"), 0, 1, S("1")); + test(S("abcdefghijklmnopqrst"), 0, 21, SV("1234567890"), 0, 5, S("12345")); + test(S("abcdefghijklmnopqrst"), 0, 21, SV("1234567890"), 0, 9, S("123456789")); +} + +template +void test41() +{ + test(S("abcdefghijklmnopqrst"), 0, 21, SV("1234567890"), 0, 10, S("1234567890")); + test(S("abcdefghijklmnopqrst"), 0, 21, SV("1234567890"), 0, 11, S("1234567890")); + test(S("abcdefghijklmnopqrst"), 0, 21, SV("1234567890"), 1, 0, S("")); + test(S("abcdefghijklmnopqrst"), 0, 21, SV("1234567890"), 1, 1, S("2")); + test(S("abcdefghijklmnopqrst"), 0, 21, SV("1234567890"), 1, 4, S("2345")); + test(S("abcdefghijklmnopqrst"), 0, 21, SV("1234567890"), 1, 8, S("23456789")); + test(S("abcdefghijklmnopqrst"), 0, 21, SV("1234567890"), 1, 9, S("234567890")); + test(S("abcdefghijklmnopqrst"), 0, 21, SV("1234567890"), 1, 10, S("234567890")); + test(S("abcdefghijklmnopqrst"), 0, 21, SV("1234567890"), 5, 0, S("")); + test(S("abcdefghijklmnopqrst"), 0, 21, SV("1234567890"), 5, 1, S("6")); + test(S("abcdefghijklmnopqrst"), 0, 21, SV("1234567890"), 5, 2, S("67")); + test(S("abcdefghijklmnopqrst"), 0, 21, SV("1234567890"), 5, 4, S("6789")); + test(S("abcdefghijklmnopqrst"), 0, 21, SV("1234567890"), 5, 5, S("67890")); + test(S("abcdefghijklmnopqrst"), 0, 21, SV("1234567890"), 5, 6, S("67890")); + test(S("abcdefghijklmnopqrst"), 0, 21, SV("1234567890"), 9, 0, S("")); + test(S("abcdefghijklmnopqrst"), 0, 21, SV("1234567890"), 9, 1, S("0")); + test(S("abcdefghijklmnopqrst"), 0, 21, SV("1234567890"), 9, 2, S("0")); + test(S("abcdefghijklmnopqrst"), 0, 21, SV("1234567890"), 10, 0, S("")); + test(S("abcdefghijklmnopqrst"), 0, 21, SV("1234567890"), 10, 1, S("")); + test(S("abcdefghijklmnopqrst"), 0, 21, SV("1234567890"), 11, 0, S("can't happen")); + test(S("abcdefghijklmnopqrst"), 0, 21, SV("12345678901234567890"), 0, 0, S("")); + test(S("abcdefghijklmnopqrst"), 0, 21, SV("12345678901234567890"), 0, 1, S("1")); + test(S("abcdefghijklmnopqrst"), 0, 21, SV("12345678901234567890"), 0, 10, S("1234567890")); + test(S("abcdefghijklmnopqrst"), 0, 21, SV("12345678901234567890"), 0, 19, S("1234567890123456789")); + test(S("abcdefghijklmnopqrst"), 0, 21, SV("12345678901234567890"), 0, 20, S("12345678901234567890")); + test(S("abcdefghijklmnopqrst"), 0, 21, SV("12345678901234567890"), 0, 21, S("12345678901234567890")); + test(S("abcdefghijklmnopqrst"), 0, 21, SV("12345678901234567890"), 1, 0, S("")); + test(S("abcdefghijklmnopqrst"), 0, 21, SV("12345678901234567890"), 1, 1, S("2")); + test(S("abcdefghijklmnopqrst"), 0, 21, SV("12345678901234567890"), 1, 9, S("234567890")); + test(S("abcdefghijklmnopqrst"), 0, 21, SV("12345678901234567890"), 1, 18, S("234567890123456789")); + test(S("abcdefghijklmnopqrst"), 0, 21, SV("12345678901234567890"), 1, 19, S("2345678901234567890")); + test(S("abcdefghijklmnopqrst"), 0, 21, SV("12345678901234567890"), 1, 20, S("2345678901234567890")); + test(S("abcdefghijklmnopqrst"), 0, 21, SV("12345678901234567890"), 10, 0, S("")); + test(S("abcdefghijklmnopqrst"), 0, 21, SV("12345678901234567890"), 10, 1, S("1")); + test(S("abcdefghijklmnopqrst"), 0, 21, SV("12345678901234567890"), 10, 5, S("12345")); + test(S("abcdefghijklmnopqrst"), 0, 21, SV("12345678901234567890"), 10, 9, S("123456789")); + test(S("abcdefghijklmnopqrst"), 0, 21, SV("12345678901234567890"), 10, 10, S("1234567890")); + test(S("abcdefghijklmnopqrst"), 0, 21, SV("12345678901234567890"), 10, 11, S("1234567890")); + test(S("abcdefghijklmnopqrst"), 0, 21, SV("12345678901234567890"), 19, 0, S("")); + test(S("abcdefghijklmnopqrst"), 0, 21, SV("12345678901234567890"), 19, 1, S("0")); + test(S("abcdefghijklmnopqrst"), 0, 21, SV("12345678901234567890"), 19, 2, S("0")); + test(S("abcdefghijklmnopqrst"), 0, 21, SV("12345678901234567890"), 20, 0, S("")); + test(S("abcdefghijklmnopqrst"), 0, 21, SV("12345678901234567890"), 20, 1, S("")); + test(S("abcdefghijklmnopqrst"), 0, 21, SV("12345678901234567890"), 21, 0, S("can't happen")); + test(S("abcdefghijklmnopqrst"), 1, 0, SV(""), 0, 0, S("abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, 0, SV(""), 0, 1, S("abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, 0, SV(""), 1, 0, S("can't happen")); + test(S("abcdefghijklmnopqrst"), 1, 0, SV("12345"), 0, 0, S("abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, 0, SV("12345"), 0, 1, S("a1bcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, 0, SV("12345"), 0, 2, S("a12bcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, 0, SV("12345"), 0, 4, S("a1234bcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, 0, SV("12345"), 0, 5, S("a12345bcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, 0, SV("12345"), 0, 6, S("a12345bcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, 0, SV("12345"), 1, 0, S("abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, 0, SV("12345"), 1, 1, S("a2bcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, 0, SV("12345"), 1, 2, S("a23bcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, 0, SV("12345"), 1, 3, S("a234bcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, 0, SV("12345"), 1, 4, S("a2345bcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, 0, SV("12345"), 1, 5, S("a2345bcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, 0, SV("12345"), 2, 0, S("abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, 0, SV("12345"), 2, 1, S("a3bcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, 0, SV("12345"), 2, 2, S("a34bcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, 0, SV("12345"), 2, 3, S("a345bcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, 0, SV("12345"), 2, 4, S("a345bcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, 0, SV("12345"), 4, 0, S("abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, 0, SV("12345"), 4, 1, S("a5bcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, 0, SV("12345"), 4, 2, S("a5bcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, 0, SV("12345"), 5, 0, S("abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, 0, SV("12345"), 5, 1, S("abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, 0, SV("12345"), 6, 0, S("can't happen")); + test(S("abcdefghijklmnopqrst"), 1, 0, SV("1234567890"), 0, 0, S("abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, 0, SV("1234567890"), 0, 1, S("a1bcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, 0, SV("1234567890"), 0, 5, S("a12345bcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, 0, SV("1234567890"), 0, 9, S("a123456789bcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, 0, SV("1234567890"), 0, 10, S("a1234567890bcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, 0, SV("1234567890"), 0, 11, S("a1234567890bcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, 0, SV("1234567890"), 1, 0, S("abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, 0, SV("1234567890"), 1, 1, S("a2bcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, 0, SV("1234567890"), 1, 4, S("a2345bcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, 0, SV("1234567890"), 1, 8, S("a23456789bcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, 0, SV("1234567890"), 1, 9, S("a234567890bcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, 0, SV("1234567890"), 1, 10, S("a234567890bcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, 0, SV("1234567890"), 5, 0, S("abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, 0, SV("1234567890"), 5, 1, S("a6bcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, 0, SV("1234567890"), 5, 2, S("a67bcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, 0, SV("1234567890"), 5, 4, S("a6789bcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, 0, SV("1234567890"), 5, 5, S("a67890bcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, 0, SV("1234567890"), 5, 6, S("a67890bcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, 0, SV("1234567890"), 9, 0, S("abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, 0, SV("1234567890"), 9, 1, S("a0bcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, 0, SV("1234567890"), 9, 2, S("a0bcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, 0, SV("1234567890"), 10, 0, S("abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, 0, SV("1234567890"), 10, 1, S("abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, 0, SV("1234567890"), 11, 0, S("can't happen")); + test(S("abcdefghijklmnopqrst"), 1, 0, SV("12345678901234567890"), 0, 0, S("abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, 0, SV("12345678901234567890"), 0, 1, S("a1bcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, 0, SV("12345678901234567890"), 0, 10, S("a1234567890bcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, 0, SV("12345678901234567890"), 0, 19, S("a1234567890123456789bcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, 0, SV("12345678901234567890"), 0, 20, S("a12345678901234567890bcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, 0, SV("12345678901234567890"), 0, 21, S("a12345678901234567890bcdefghijklmnopqrst")); +} + +template +void test42() +{ + test(S("abcdefghijklmnopqrst"), 1, 0, SV("12345678901234567890"), 1, 0, S("abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, 0, SV("12345678901234567890"), 1, 1, S("a2bcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, 0, SV("12345678901234567890"), 1, 9, S("a234567890bcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, 0, SV("12345678901234567890"), 1, 18, S("a234567890123456789bcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, 0, SV("12345678901234567890"), 1, 19, S("a2345678901234567890bcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, 0, SV("12345678901234567890"), 1, 20, S("a2345678901234567890bcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, 0, SV("12345678901234567890"), 10, 0, S("abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, 0, SV("12345678901234567890"), 10, 1, S("a1bcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, 0, SV("12345678901234567890"), 10, 5, S("a12345bcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, 0, SV("12345678901234567890"), 10, 9, S("a123456789bcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, 0, SV("12345678901234567890"), 10, 10, S("a1234567890bcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, 0, SV("12345678901234567890"), 10, 11, S("a1234567890bcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, 0, SV("12345678901234567890"), 19, 0, S("abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, 0, SV("12345678901234567890"), 19, 1, S("a0bcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, 0, SV("12345678901234567890"), 19, 2, S("a0bcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, 0, SV("12345678901234567890"), 20, 0, S("abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, 0, SV("12345678901234567890"), 20, 1, S("abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, 0, SV("12345678901234567890"), 21, 0, S("can't happen")); + test(S("abcdefghijklmnopqrst"), 1, 1, SV(""), 0, 0, S("acdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, 1, SV(""), 0, 1, S("acdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, 1, SV(""), 1, 0, S("can't happen")); + test(S("abcdefghijklmnopqrst"), 1, 1, SV("12345"), 0, 0, S("acdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, 1, SV("12345"), 0, 1, S("a1cdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, 1, SV("12345"), 0, 2, S("a12cdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, 1, SV("12345"), 0, 4, S("a1234cdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, 1, SV("12345"), 0, 5, S("a12345cdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, 1, SV("12345"), 0, 6, S("a12345cdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, 1, SV("12345"), 1, 0, S("acdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, 1, SV("12345"), 1, 1, S("a2cdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, 1, SV("12345"), 1, 2, S("a23cdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, 1, SV("12345"), 1, 3, S("a234cdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, 1, SV("12345"), 1, 4, S("a2345cdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, 1, SV("12345"), 1, 5, S("a2345cdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, 1, SV("12345"), 2, 0, S("acdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, 1, SV("12345"), 2, 1, S("a3cdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, 1, SV("12345"), 2, 2, S("a34cdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, 1, SV("12345"), 2, 3, S("a345cdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, 1, SV("12345"), 2, 4, S("a345cdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, 1, SV("12345"), 4, 0, S("acdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, 1, SV("12345"), 4, 1, S("a5cdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, 1, SV("12345"), 4, 2, S("a5cdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, 1, SV("12345"), 5, 0, S("acdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, 1, SV("12345"), 5, 1, S("acdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, 1, SV("12345"), 6, 0, S("can't happen")); + test(S("abcdefghijklmnopqrst"), 1, 1, SV("1234567890"), 0, 0, S("acdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, 1, SV("1234567890"), 0, 1, S("a1cdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, 1, SV("1234567890"), 0, 5, S("a12345cdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, 1, SV("1234567890"), 0, 9, S("a123456789cdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, 1, SV("1234567890"), 0, 10, S("a1234567890cdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, 1, SV("1234567890"), 0, 11, S("a1234567890cdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, 1, SV("1234567890"), 1, 0, S("acdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, 1, SV("1234567890"), 1, 1, S("a2cdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, 1, SV("1234567890"), 1, 4, S("a2345cdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, 1, SV("1234567890"), 1, 8, S("a23456789cdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, 1, SV("1234567890"), 1, 9, S("a234567890cdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, 1, SV("1234567890"), 1, 10, S("a234567890cdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, 1, SV("1234567890"), 5, 0, S("acdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, 1, SV("1234567890"), 5, 1, S("a6cdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, 1, SV("1234567890"), 5, 2, S("a67cdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, 1, SV("1234567890"), 5, 4, S("a6789cdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, 1, SV("1234567890"), 5, 5, S("a67890cdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, 1, SV("1234567890"), 5, 6, S("a67890cdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, 1, SV("1234567890"), 9, 0, S("acdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, 1, SV("1234567890"), 9, 1, S("a0cdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, 1, SV("1234567890"), 9, 2, S("a0cdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, 1, SV("1234567890"), 10, 0, S("acdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, 1, SV("1234567890"), 10, 1, S("acdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, 1, SV("1234567890"), 11, 0, S("can't happen")); + test(S("abcdefghijklmnopqrst"), 1, 1, SV("12345678901234567890"), 0, 0, S("acdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, 1, SV("12345678901234567890"), 0, 1, S("a1cdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, 1, SV("12345678901234567890"), 0, 10, S("a1234567890cdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, 1, SV("12345678901234567890"), 0, 19, S("a1234567890123456789cdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, 1, SV("12345678901234567890"), 0, 20, S("a12345678901234567890cdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, 1, SV("12345678901234567890"), 0, 21, S("a12345678901234567890cdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, 1, SV("12345678901234567890"), 1, 0, S("acdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, 1, SV("12345678901234567890"), 1, 1, S("a2cdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, 1, SV("12345678901234567890"), 1, 9, S("a234567890cdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, 1, SV("12345678901234567890"), 1, 18, S("a234567890123456789cdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, 1, SV("12345678901234567890"), 1, 19, S("a2345678901234567890cdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, 1, SV("12345678901234567890"), 1, 20, S("a2345678901234567890cdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, 1, SV("12345678901234567890"), 10, 0, S("acdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, 1, SV("12345678901234567890"), 10, 1, S("a1cdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, 1, SV("12345678901234567890"), 10, 5, S("a12345cdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, 1, SV("12345678901234567890"), 10, 9, S("a123456789cdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, 1, SV("12345678901234567890"), 10, 10, S("a1234567890cdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, 1, SV("12345678901234567890"), 10, 11, S("a1234567890cdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, 1, SV("12345678901234567890"), 19, 0, S("acdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, 1, SV("12345678901234567890"), 19, 1, S("a0cdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, 1, SV("12345678901234567890"), 19, 2, S("a0cdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, 1, SV("12345678901234567890"), 20, 0, S("acdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, 1, SV("12345678901234567890"), 20, 1, S("acdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, 1, SV("12345678901234567890"), 21, 0, S("can't happen")); + test(S("abcdefghijklmnopqrst"), 1, 9, SV(""), 0, 0, S("aklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, 9, SV(""), 0, 1, S("aklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, 9, SV(""), 1, 0, S("can't happen")); + test(S("abcdefghijklmnopqrst"), 1, 9, SV("12345"), 0, 0, S("aklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, 9, SV("12345"), 0, 1, S("a1klmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, 9, SV("12345"), 0, 2, S("a12klmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, 9, SV("12345"), 0, 4, S("a1234klmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, 9, SV("12345"), 0, 5, S("a12345klmnopqrst")); +} + +template +void test43() +{ + test(S("abcdefghijklmnopqrst"), 1, 9, SV("12345"), 0, 6, S("a12345klmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, 9, SV("12345"), 1, 0, S("aklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, 9, SV("12345"), 1, 1, S("a2klmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, 9, SV("12345"), 1, 2, S("a23klmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, 9, SV("12345"), 1, 3, S("a234klmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, 9, SV("12345"), 1, 4, S("a2345klmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, 9, SV("12345"), 1, 5, S("a2345klmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, 9, SV("12345"), 2, 0, S("aklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, 9, SV("12345"), 2, 1, S("a3klmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, 9, SV("12345"), 2, 2, S("a34klmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, 9, SV("12345"), 2, 3, S("a345klmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, 9, SV("12345"), 2, 4, S("a345klmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, 9, SV("12345"), 4, 0, S("aklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, 9, SV("12345"), 4, 1, S("a5klmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, 9, SV("12345"), 4, 2, S("a5klmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, 9, SV("12345"), 5, 0, S("aklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, 9, SV("12345"), 5, 1, S("aklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, 9, SV("12345"), 6, 0, S("can't happen")); + test(S("abcdefghijklmnopqrst"), 1, 9, SV("1234567890"), 0, 0, S("aklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, 9, SV("1234567890"), 0, 1, S("a1klmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, 9, SV("1234567890"), 0, 5, S("a12345klmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, 9, SV("1234567890"), 0, 9, S("a123456789klmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, 9, SV("1234567890"), 0, 10, S("a1234567890klmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, 9, SV("1234567890"), 0, 11, S("a1234567890klmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, 9, SV("1234567890"), 1, 0, S("aklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, 9, SV("1234567890"), 1, 1, S("a2klmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, 9, SV("1234567890"), 1, 4, S("a2345klmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, 9, SV("1234567890"), 1, 8, S("a23456789klmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, 9, SV("1234567890"), 1, 9, S("a234567890klmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, 9, SV("1234567890"), 1, 10, S("a234567890klmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, 9, SV("1234567890"), 5, 0, S("aklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, 9, SV("1234567890"), 5, 1, S("a6klmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, 9, SV("1234567890"), 5, 2, S("a67klmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, 9, SV("1234567890"), 5, 4, S("a6789klmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, 9, SV("1234567890"), 5, 5, S("a67890klmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, 9, SV("1234567890"), 5, 6, S("a67890klmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, 9, SV("1234567890"), 9, 0, S("aklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, 9, SV("1234567890"), 9, 1, S("a0klmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, 9, SV("1234567890"), 9, 2, S("a0klmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, 9, SV("1234567890"), 10, 0, S("aklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, 9, SV("1234567890"), 10, 1, S("aklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, 9, SV("1234567890"), 11, 0, S("can't happen")); + test(S("abcdefghijklmnopqrst"), 1, 9, SV("12345678901234567890"), 0, 0, S("aklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, 9, SV("12345678901234567890"), 0, 1, S("a1klmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, 9, SV("12345678901234567890"), 0, 10, S("a1234567890klmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, 9, SV("12345678901234567890"), 0, 19, S("a1234567890123456789klmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, 9, SV("12345678901234567890"), 0, 20, S("a12345678901234567890klmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, 9, SV("12345678901234567890"), 0, 21, S("a12345678901234567890klmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, 9, SV("12345678901234567890"), 1, 0, S("aklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, 9, SV("12345678901234567890"), 1, 1, S("a2klmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, 9, SV("12345678901234567890"), 1, 9, S("a234567890klmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, 9, SV("12345678901234567890"), 1, 18, S("a234567890123456789klmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, 9, SV("12345678901234567890"), 1, 19, S("a2345678901234567890klmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, 9, SV("12345678901234567890"), 1, 20, S("a2345678901234567890klmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, 9, SV("12345678901234567890"), 10, 0, S("aklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, 9, SV("12345678901234567890"), 10, 1, S("a1klmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, 9, SV("12345678901234567890"), 10, 5, S("a12345klmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, 9, SV("12345678901234567890"), 10, 9, S("a123456789klmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, 9, SV("12345678901234567890"), 10, 10, S("a1234567890klmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, 9, SV("12345678901234567890"), 10, 11, S("a1234567890klmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, 9, SV("12345678901234567890"), 19, 0, S("aklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, 9, SV("12345678901234567890"), 19, 1, S("a0klmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, 9, SV("12345678901234567890"), 19, 2, S("a0klmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, 9, SV("12345678901234567890"), 20, 0, S("aklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, 9, SV("12345678901234567890"), 20, 1, S("aklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, 9, SV("12345678901234567890"), 21, 0, S("can't happen")); + test(S("abcdefghijklmnopqrst"), 1, 18, SV(""), 0, 0, S("at")); + test(S("abcdefghijklmnopqrst"), 1, 18, SV(""), 0, 1, S("at")); + test(S("abcdefghijklmnopqrst"), 1, 18, SV(""), 1, 0, S("can't happen")); + test(S("abcdefghijklmnopqrst"), 1, 18, SV("12345"), 0, 0, S("at")); + test(S("abcdefghijklmnopqrst"), 1, 18, SV("12345"), 0, 1, S("a1t")); + test(S("abcdefghijklmnopqrst"), 1, 18, SV("12345"), 0, 2, S("a12t")); + test(S("abcdefghijklmnopqrst"), 1, 18, SV("12345"), 0, 4, S("a1234t")); + test(S("abcdefghijklmnopqrst"), 1, 18, SV("12345"), 0, 5, S("a12345t")); + test(S("abcdefghijklmnopqrst"), 1, 18, SV("12345"), 0, 6, S("a12345t")); + test(S("abcdefghijklmnopqrst"), 1, 18, SV("12345"), 1, 0, S("at")); + test(S("abcdefghijklmnopqrst"), 1, 18, SV("12345"), 1, 1, S("a2t")); + test(S("abcdefghijklmnopqrst"), 1, 18, SV("12345"), 1, 2, S("a23t")); + test(S("abcdefghijklmnopqrst"), 1, 18, SV("12345"), 1, 3, S("a234t")); + test(S("abcdefghijklmnopqrst"), 1, 18, SV("12345"), 1, 4, S("a2345t")); + test(S("abcdefghijklmnopqrst"), 1, 18, SV("12345"), 1, 5, S("a2345t")); + test(S("abcdefghijklmnopqrst"), 1, 18, SV("12345"), 2, 0, S("at")); + test(S("abcdefghijklmnopqrst"), 1, 18, SV("12345"), 2, 1, S("a3t")); + test(S("abcdefghijklmnopqrst"), 1, 18, SV("12345"), 2, 2, S("a34t")); + test(S("abcdefghijklmnopqrst"), 1, 18, SV("12345"), 2, 3, S("a345t")); + test(S("abcdefghijklmnopqrst"), 1, 18, SV("12345"), 2, 4, S("a345t")); + test(S("abcdefghijklmnopqrst"), 1, 18, SV("12345"), 4, 0, S("at")); + test(S("abcdefghijklmnopqrst"), 1, 18, SV("12345"), 4, 1, S("a5t")); + test(S("abcdefghijklmnopqrst"), 1, 18, SV("12345"), 4, 2, S("a5t")); + test(S("abcdefghijklmnopqrst"), 1, 18, SV("12345"), 5, 0, S("at")); + test(S("abcdefghijklmnopqrst"), 1, 18, SV("12345"), 5, 1, S("at")); + test(S("abcdefghijklmnopqrst"), 1, 18, SV("12345"), 6, 0, S("can't happen")); + test(S("abcdefghijklmnopqrst"), 1, 18, SV("1234567890"), 0, 0, S("at")); + test(S("abcdefghijklmnopqrst"), 1, 18, SV("1234567890"), 0, 1, S("a1t")); + test(S("abcdefghijklmnopqrst"), 1, 18, SV("1234567890"), 0, 5, S("a12345t")); + test(S("abcdefghijklmnopqrst"), 1, 18, SV("1234567890"), 0, 9, S("a123456789t")); + test(S("abcdefghijklmnopqrst"), 1, 18, SV("1234567890"), 0, 10, S("a1234567890t")); + test(S("abcdefghijklmnopqrst"), 1, 18, SV("1234567890"), 0, 11, S("a1234567890t")); + test(S("abcdefghijklmnopqrst"), 1, 18, SV("1234567890"), 1, 0, S("at")); + test(S("abcdefghijklmnopqrst"), 1, 18, SV("1234567890"), 1, 1, S("a2t")); +} + +template +void test44() +{ + test(S("abcdefghijklmnopqrst"), 1, 18, SV("1234567890"), 1, 4, S("a2345t")); + test(S("abcdefghijklmnopqrst"), 1, 18, SV("1234567890"), 1, 8, S("a23456789t")); + test(S("abcdefghijklmnopqrst"), 1, 18, SV("1234567890"), 1, 9, S("a234567890t")); + test(S("abcdefghijklmnopqrst"), 1, 18, SV("1234567890"), 1, 10, S("a234567890t")); + test(S("abcdefghijklmnopqrst"), 1, 18, SV("1234567890"), 5, 0, S("at")); + test(S("abcdefghijklmnopqrst"), 1, 18, SV("1234567890"), 5, 1, S("a6t")); + test(S("abcdefghijklmnopqrst"), 1, 18, SV("1234567890"), 5, 2, S("a67t")); + test(S("abcdefghijklmnopqrst"), 1, 18, SV("1234567890"), 5, 4, S("a6789t")); + test(S("abcdefghijklmnopqrst"), 1, 18, SV("1234567890"), 5, 5, S("a67890t")); + test(S("abcdefghijklmnopqrst"), 1, 18, SV("1234567890"), 5, 6, S("a67890t")); + test(S("abcdefghijklmnopqrst"), 1, 18, SV("1234567890"), 9, 0, S("at")); + test(S("abcdefghijklmnopqrst"), 1, 18, SV("1234567890"), 9, 1, S("a0t")); + test(S("abcdefghijklmnopqrst"), 1, 18, SV("1234567890"), 9, 2, S("a0t")); + test(S("abcdefghijklmnopqrst"), 1, 18, SV("1234567890"), 10, 0, S("at")); + test(S("abcdefghijklmnopqrst"), 1, 18, SV("1234567890"), 10, 1, S("at")); + test(S("abcdefghijklmnopqrst"), 1, 18, SV("1234567890"), 11, 0, S("can't happen")); + test(S("abcdefghijklmnopqrst"), 1, 18, SV("12345678901234567890"), 0, 0, S("at")); + test(S("abcdefghijklmnopqrst"), 1, 18, SV("12345678901234567890"), 0, 1, S("a1t")); + test(S("abcdefghijklmnopqrst"), 1, 18, SV("12345678901234567890"), 0, 10, S("a1234567890t")); + test(S("abcdefghijklmnopqrst"), 1, 18, SV("12345678901234567890"), 0, 19, S("a1234567890123456789t")); + test(S("abcdefghijklmnopqrst"), 1, 18, SV("12345678901234567890"), 0, 20, S("a12345678901234567890t")); + test(S("abcdefghijklmnopqrst"), 1, 18, SV("12345678901234567890"), 0, 21, S("a12345678901234567890t")); + test(S("abcdefghijklmnopqrst"), 1, 18, SV("12345678901234567890"), 1, 0, S("at")); + test(S("abcdefghijklmnopqrst"), 1, 18, SV("12345678901234567890"), 1, 1, S("a2t")); + test(S("abcdefghijklmnopqrst"), 1, 18, SV("12345678901234567890"), 1, 9, S("a234567890t")); + test(S("abcdefghijklmnopqrst"), 1, 18, SV("12345678901234567890"), 1, 18, S("a234567890123456789t")); + test(S("abcdefghijklmnopqrst"), 1, 18, SV("12345678901234567890"), 1, 19, S("a2345678901234567890t")); + test(S("abcdefghijklmnopqrst"), 1, 18, SV("12345678901234567890"), 1, 20, S("a2345678901234567890t")); + test(S("abcdefghijklmnopqrst"), 1, 18, SV("12345678901234567890"), 10, 0, S("at")); + test(S("abcdefghijklmnopqrst"), 1, 18, SV("12345678901234567890"), 10, 1, S("a1t")); + test(S("abcdefghijklmnopqrst"), 1, 18, SV("12345678901234567890"), 10, 5, S("a12345t")); + test(S("abcdefghijklmnopqrst"), 1, 18, SV("12345678901234567890"), 10, 9, S("a123456789t")); + test(S("abcdefghijklmnopqrst"), 1, 18, SV("12345678901234567890"), 10, 10, S("a1234567890t")); + test(S("abcdefghijklmnopqrst"), 1, 18, SV("12345678901234567890"), 10, 11, S("a1234567890t")); + test(S("abcdefghijklmnopqrst"), 1, 18, SV("12345678901234567890"), 19, 0, S("at")); + test(S("abcdefghijklmnopqrst"), 1, 18, SV("12345678901234567890"), 19, 1, S("a0t")); + test(S("abcdefghijklmnopqrst"), 1, 18, SV("12345678901234567890"), 19, 2, S("a0t")); + test(S("abcdefghijklmnopqrst"), 1, 18, SV("12345678901234567890"), 20, 0, S("at")); + test(S("abcdefghijklmnopqrst"), 1, 18, SV("12345678901234567890"), 20, 1, S("at")); + test(S("abcdefghijklmnopqrst"), 1, 18, SV("12345678901234567890"), 21, 0, S("can't happen")); + test(S("abcdefghijklmnopqrst"), 1, 19, SV(""), 0, 0, S("a")); + test(S("abcdefghijklmnopqrst"), 1, 19, SV(""), 0, 1, S("a")); + test(S("abcdefghijklmnopqrst"), 1, 19, SV(""), 1, 0, S("can't happen")); + test(S("abcdefghijklmnopqrst"), 1, 19, SV("12345"), 0, 0, S("a")); + test(S("abcdefghijklmnopqrst"), 1, 19, SV("12345"), 0, 1, S("a1")); + test(S("abcdefghijklmnopqrst"), 1, 19, SV("12345"), 0, 2, S("a12")); + test(S("abcdefghijklmnopqrst"), 1, 19, SV("12345"), 0, 4, S("a1234")); + test(S("abcdefghijklmnopqrst"), 1, 19, SV("12345"), 0, 5, S("a12345")); + test(S("abcdefghijklmnopqrst"), 1, 19, SV("12345"), 0, 6, S("a12345")); + test(S("abcdefghijklmnopqrst"), 1, 19, SV("12345"), 1, 0, S("a")); + test(S("abcdefghijklmnopqrst"), 1, 19, SV("12345"), 1, 1, S("a2")); + test(S("abcdefghijklmnopqrst"), 1, 19, SV("12345"), 1, 2, S("a23")); + test(S("abcdefghijklmnopqrst"), 1, 19, SV("12345"), 1, 3, S("a234")); + test(S("abcdefghijklmnopqrst"), 1, 19, SV("12345"), 1, 4, S("a2345")); + test(S("abcdefghijklmnopqrst"), 1, 19, SV("12345"), 1, 5, S("a2345")); + test(S("abcdefghijklmnopqrst"), 1, 19, SV("12345"), 2, 0, S("a")); + test(S("abcdefghijklmnopqrst"), 1, 19, SV("12345"), 2, 1, S("a3")); + test(S("abcdefghijklmnopqrst"), 1, 19, SV("12345"), 2, 2, S("a34")); + test(S("abcdefghijklmnopqrst"), 1, 19, SV("12345"), 2, 3, S("a345")); + test(S("abcdefghijklmnopqrst"), 1, 19, SV("12345"), 2, 4, S("a345")); + test(S("abcdefghijklmnopqrst"), 1, 19, SV("12345"), 4, 0, S("a")); + test(S("abcdefghijklmnopqrst"), 1, 19, SV("12345"), 4, 1, S("a5")); + test(S("abcdefghijklmnopqrst"), 1, 19, SV("12345"), 4, 2, S("a5")); + test(S("abcdefghijklmnopqrst"), 1, 19, SV("12345"), 5, 0, S("a")); + test(S("abcdefghijklmnopqrst"), 1, 19, SV("12345"), 5, 1, S("a")); + test(S("abcdefghijklmnopqrst"), 1, 19, SV("12345"), 6, 0, S("can't happen")); + test(S("abcdefghijklmnopqrst"), 1, 19, SV("1234567890"), 0, 0, S("a")); + test(S("abcdefghijklmnopqrst"), 1, 19, SV("1234567890"), 0, 1, S("a1")); + test(S("abcdefghijklmnopqrst"), 1, 19, SV("1234567890"), 0, 5, S("a12345")); + test(S("abcdefghijklmnopqrst"), 1, 19, SV("1234567890"), 0, 9, S("a123456789")); + test(S("abcdefghijklmnopqrst"), 1, 19, SV("1234567890"), 0, 10, S("a1234567890")); + test(S("abcdefghijklmnopqrst"), 1, 19, SV("1234567890"), 0, 11, S("a1234567890")); + test(S("abcdefghijklmnopqrst"), 1, 19, SV("1234567890"), 1, 0, S("a")); + test(S("abcdefghijklmnopqrst"), 1, 19, SV("1234567890"), 1, 1, S("a2")); + test(S("abcdefghijklmnopqrst"), 1, 19, SV("1234567890"), 1, 4, S("a2345")); + test(S("abcdefghijklmnopqrst"), 1, 19, SV("1234567890"), 1, 8, S("a23456789")); + test(S("abcdefghijklmnopqrst"), 1, 19, SV("1234567890"), 1, 9, S("a234567890")); + test(S("abcdefghijklmnopqrst"), 1, 19, SV("1234567890"), 1, 10, S("a234567890")); + test(S("abcdefghijklmnopqrst"), 1, 19, SV("1234567890"), 5, 0, S("a")); + test(S("abcdefghijklmnopqrst"), 1, 19, SV("1234567890"), 5, 1, S("a6")); + test(S("abcdefghijklmnopqrst"), 1, 19, SV("1234567890"), 5, 2, S("a67")); + test(S("abcdefghijklmnopqrst"), 1, 19, SV("1234567890"), 5, 4, S("a6789")); + test(S("abcdefghijklmnopqrst"), 1, 19, SV("1234567890"), 5, 5, S("a67890")); + test(S("abcdefghijklmnopqrst"), 1, 19, SV("1234567890"), 5, 6, S("a67890")); + test(S("abcdefghijklmnopqrst"), 1, 19, SV("1234567890"), 9, 0, S("a")); + test(S("abcdefghijklmnopqrst"), 1, 19, SV("1234567890"), 9, 1, S("a0")); + test(S("abcdefghijklmnopqrst"), 1, 19, SV("1234567890"), 9, 2, S("a0")); + test(S("abcdefghijklmnopqrst"), 1, 19, SV("1234567890"), 10, 0, S("a")); + test(S("abcdefghijklmnopqrst"), 1, 19, SV("1234567890"), 10, 1, S("a")); + test(S("abcdefghijklmnopqrst"), 1, 19, SV("1234567890"), 11, 0, S("can't happen")); + test(S("abcdefghijklmnopqrst"), 1, 19, SV("12345678901234567890"), 0, 0, S("a")); + test(S("abcdefghijklmnopqrst"), 1, 19, SV("12345678901234567890"), 0, 1, S("a1")); + test(S("abcdefghijklmnopqrst"), 1, 19, SV("12345678901234567890"), 0, 10, S("a1234567890")); + test(S("abcdefghijklmnopqrst"), 1, 19, SV("12345678901234567890"), 0, 19, S("a1234567890123456789")); + test(S("abcdefghijklmnopqrst"), 1, 19, SV("12345678901234567890"), 0, 20, S("a12345678901234567890")); + test(S("abcdefghijklmnopqrst"), 1, 19, SV("12345678901234567890"), 0, 21, S("a12345678901234567890")); + test(S("abcdefghijklmnopqrst"), 1, 19, SV("12345678901234567890"), 1, 0, S("a")); + test(S("abcdefghijklmnopqrst"), 1, 19, SV("12345678901234567890"), 1, 1, S("a2")); + test(S("abcdefghijklmnopqrst"), 1, 19, SV("12345678901234567890"), 1, 9, S("a234567890")); + test(S("abcdefghijklmnopqrst"), 1, 19, SV("12345678901234567890"), 1, 18, S("a234567890123456789")); +} + +template +void test45() +{ + test(S("abcdefghijklmnopqrst"), 1, 19, SV("12345678901234567890"), 1, 19, S("a2345678901234567890")); + test(S("abcdefghijklmnopqrst"), 1, 19, SV("12345678901234567890"), 1, 20, S("a2345678901234567890")); + test(S("abcdefghijklmnopqrst"), 1, 19, SV("12345678901234567890"), 10, 0, S("a")); + test(S("abcdefghijklmnopqrst"), 1, 19, SV("12345678901234567890"), 10, 1, S("a1")); + test(S("abcdefghijklmnopqrst"), 1, 19, SV("12345678901234567890"), 10, 5, S("a12345")); + test(S("abcdefghijklmnopqrst"), 1, 19, SV("12345678901234567890"), 10, 9, S("a123456789")); + test(S("abcdefghijklmnopqrst"), 1, 19, SV("12345678901234567890"), 10, 10, S("a1234567890")); + test(S("abcdefghijklmnopqrst"), 1, 19, SV("12345678901234567890"), 10, 11, S("a1234567890")); + test(S("abcdefghijklmnopqrst"), 1, 19, SV("12345678901234567890"), 19, 0, S("a")); + test(S("abcdefghijklmnopqrst"), 1, 19, SV("12345678901234567890"), 19, 1, S("a0")); + test(S("abcdefghijklmnopqrst"), 1, 19, SV("12345678901234567890"), 19, 2, S("a0")); + test(S("abcdefghijklmnopqrst"), 1, 19, SV("12345678901234567890"), 20, 0, S("a")); + test(S("abcdefghijklmnopqrst"), 1, 19, SV("12345678901234567890"), 20, 1, S("a")); + test(S("abcdefghijklmnopqrst"), 1, 19, SV("12345678901234567890"), 21, 0, S("can't happen")); + test(S("abcdefghijklmnopqrst"), 1, 20, SV(""), 0, 0, S("a")); + test(S("abcdefghijklmnopqrst"), 1, 20, SV(""), 0, 1, S("a")); + test(S("abcdefghijklmnopqrst"), 1, 20, SV(""), 1, 0, S("can't happen")); + test(S("abcdefghijklmnopqrst"), 1, 20, SV("12345"), 0, 0, S("a")); + test(S("abcdefghijklmnopqrst"), 1, 20, SV("12345"), 0, 1, S("a1")); + test(S("abcdefghijklmnopqrst"), 1, 20, SV("12345"), 0, 2, S("a12")); + test(S("abcdefghijklmnopqrst"), 1, 20, SV("12345"), 0, 4, S("a1234")); + test(S("abcdefghijklmnopqrst"), 1, 20, SV("12345"), 0, 5, S("a12345")); + test(S("abcdefghijklmnopqrst"), 1, 20, SV("12345"), 0, 6, S("a12345")); + test(S("abcdefghijklmnopqrst"), 1, 20, SV("12345"), 1, 0, S("a")); + test(S("abcdefghijklmnopqrst"), 1, 20, SV("12345"), 1, 1, S("a2")); + test(S("abcdefghijklmnopqrst"), 1, 20, SV("12345"), 1, 2, S("a23")); + test(S("abcdefghijklmnopqrst"), 1, 20, SV("12345"), 1, 3, S("a234")); + test(S("abcdefghijklmnopqrst"), 1, 20, SV("12345"), 1, 4, S("a2345")); + test(S("abcdefghijklmnopqrst"), 1, 20, SV("12345"), 1, 5, S("a2345")); + test(S("abcdefghijklmnopqrst"), 1, 20, SV("12345"), 2, 0, S("a")); + test(S("abcdefghijklmnopqrst"), 1, 20, SV("12345"), 2, 1, S("a3")); + test(S("abcdefghijklmnopqrst"), 1, 20, SV("12345"), 2, 2, S("a34")); + test(S("abcdefghijklmnopqrst"), 1, 20, SV("12345"), 2, 3, S("a345")); + test(S("abcdefghijklmnopqrst"), 1, 20, SV("12345"), 2, 4, S("a345")); + test(S("abcdefghijklmnopqrst"), 1, 20, SV("12345"), 4, 0, S("a")); + test(S("abcdefghijklmnopqrst"), 1, 20, SV("12345"), 4, 1, S("a5")); + test(S("abcdefghijklmnopqrst"), 1, 20, SV("12345"), 4, 2, S("a5")); + test(S("abcdefghijklmnopqrst"), 1, 20, SV("12345"), 5, 0, S("a")); + test(S("abcdefghijklmnopqrst"), 1, 20, SV("12345"), 5, 1, S("a")); + test(S("abcdefghijklmnopqrst"), 1, 20, SV("12345"), 6, 0, S("can't happen")); + test(S("abcdefghijklmnopqrst"), 1, 20, SV("1234567890"), 0, 0, S("a")); + test(S("abcdefghijklmnopqrst"), 1, 20, SV("1234567890"), 0, 1, S("a1")); + test(S("abcdefghijklmnopqrst"), 1, 20, SV("1234567890"), 0, 5, S("a12345")); + test(S("abcdefghijklmnopqrst"), 1, 20, SV("1234567890"), 0, 9, S("a123456789")); + test(S("abcdefghijklmnopqrst"), 1, 20, SV("1234567890"), 0, 10, S("a1234567890")); + test(S("abcdefghijklmnopqrst"), 1, 20, SV("1234567890"), 0, 11, S("a1234567890")); + test(S("abcdefghijklmnopqrst"), 1, 20, SV("1234567890"), 1, 0, S("a")); + test(S("abcdefghijklmnopqrst"), 1, 20, SV("1234567890"), 1, 1, S("a2")); + test(S("abcdefghijklmnopqrst"), 1, 20, SV("1234567890"), 1, 4, S("a2345")); + test(S("abcdefghijklmnopqrst"), 1, 20, SV("1234567890"), 1, 8, S("a23456789")); + test(S("abcdefghijklmnopqrst"), 1, 20, SV("1234567890"), 1, 9, S("a234567890")); + test(S("abcdefghijklmnopqrst"), 1, 20, SV("1234567890"), 1, 10, S("a234567890")); + test(S("abcdefghijklmnopqrst"), 1, 20, SV("1234567890"), 5, 0, S("a")); + test(S("abcdefghijklmnopqrst"), 1, 20, SV("1234567890"), 5, 1, S("a6")); + test(S("abcdefghijklmnopqrst"), 1, 20, SV("1234567890"), 5, 2, S("a67")); + test(S("abcdefghijklmnopqrst"), 1, 20, SV("1234567890"), 5, 4, S("a6789")); + test(S("abcdefghijklmnopqrst"), 1, 20, SV("1234567890"), 5, 5, S("a67890")); + test(S("abcdefghijklmnopqrst"), 1, 20, SV("1234567890"), 5, 6, S("a67890")); + test(S("abcdefghijklmnopqrst"), 1, 20, SV("1234567890"), 9, 0, S("a")); + test(S("abcdefghijklmnopqrst"), 1, 20, SV("1234567890"), 9, 1, S("a0")); + test(S("abcdefghijklmnopqrst"), 1, 20, SV("1234567890"), 9, 2, S("a0")); + test(S("abcdefghijklmnopqrst"), 1, 20, SV("1234567890"), 10, 0, S("a")); + test(S("abcdefghijklmnopqrst"), 1, 20, SV("1234567890"), 10, 1, S("a")); + test(S("abcdefghijklmnopqrst"), 1, 20, SV("1234567890"), 11, 0, S("can't happen")); + test(S("abcdefghijklmnopqrst"), 1, 20, SV("12345678901234567890"), 0, 0, S("a")); + test(S("abcdefghijklmnopqrst"), 1, 20, SV("12345678901234567890"), 0, 1, S("a1")); + test(S("abcdefghijklmnopqrst"), 1, 20, SV("12345678901234567890"), 0, 10, S("a1234567890")); + test(S("abcdefghijklmnopqrst"), 1, 20, SV("12345678901234567890"), 0, 19, S("a1234567890123456789")); + test(S("abcdefghijklmnopqrst"), 1, 20, SV("12345678901234567890"), 0, 20, S("a12345678901234567890")); + test(S("abcdefghijklmnopqrst"), 1, 20, SV("12345678901234567890"), 0, 21, S("a12345678901234567890")); + test(S("abcdefghijklmnopqrst"), 1, 20, SV("12345678901234567890"), 1, 0, S("a")); + test(S("abcdefghijklmnopqrst"), 1, 20, SV("12345678901234567890"), 1, 1, S("a2")); + test(S("abcdefghijklmnopqrst"), 1, 20, SV("12345678901234567890"), 1, 9, S("a234567890")); + test(S("abcdefghijklmnopqrst"), 1, 20, SV("12345678901234567890"), 1, 18, S("a234567890123456789")); + test(S("abcdefghijklmnopqrst"), 1, 20, SV("12345678901234567890"), 1, 19, S("a2345678901234567890")); + test(S("abcdefghijklmnopqrst"), 1, 20, SV("12345678901234567890"), 1, 20, S("a2345678901234567890")); + test(S("abcdefghijklmnopqrst"), 1, 20, SV("12345678901234567890"), 10, 0, S("a")); + test(S("abcdefghijklmnopqrst"), 1, 20, SV("12345678901234567890"), 10, 1, S("a1")); + test(S("abcdefghijklmnopqrst"), 1, 20, SV("12345678901234567890"), 10, 5, S("a12345")); + test(S("abcdefghijklmnopqrst"), 1, 20, SV("12345678901234567890"), 10, 9, S("a123456789")); + test(S("abcdefghijklmnopqrst"), 1, 20, SV("12345678901234567890"), 10, 10, S("a1234567890")); + test(S("abcdefghijklmnopqrst"), 1, 20, SV("12345678901234567890"), 10, 11, S("a1234567890")); + test(S("abcdefghijklmnopqrst"), 1, 20, SV("12345678901234567890"), 19, 0, S("a")); + test(S("abcdefghijklmnopqrst"), 1, 20, SV("12345678901234567890"), 19, 1, S("a0")); + test(S("abcdefghijklmnopqrst"), 1, 20, SV("12345678901234567890"), 19, 2, S("a0")); + test(S("abcdefghijklmnopqrst"), 1, 20, SV("12345678901234567890"), 20, 0, S("a")); + test(S("abcdefghijklmnopqrst"), 1, 20, SV("12345678901234567890"), 20, 1, S("a")); + test(S("abcdefghijklmnopqrst"), 1, 20, SV("12345678901234567890"), 21, 0, S("can't happen")); + test(S("abcdefghijklmnopqrst"), 10, 0, SV(""), 0, 0, S("abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 10, 0, SV(""), 0, 1, S("abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 10, 0, SV(""), 1, 0, S("can't happen")); + test(S("abcdefghijklmnopqrst"), 10, 0, SV("12345"), 0, 0, S("abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 10, 0, SV("12345"), 0, 1, S("abcdefghij1klmnopqrst")); + test(S("abcdefghijklmnopqrst"), 10, 0, SV("12345"), 0, 2, S("abcdefghij12klmnopqrst")); + test(S("abcdefghijklmnopqrst"), 10, 0, SV("12345"), 0, 4, S("abcdefghij1234klmnopqrst")); + test(S("abcdefghijklmnopqrst"), 10, 0, SV("12345"), 0, 5, S("abcdefghij12345klmnopqrst")); + test(S("abcdefghijklmnopqrst"), 10, 0, SV("12345"), 0, 6, S("abcdefghij12345klmnopqrst")); + test(S("abcdefghijklmnopqrst"), 10, 0, SV("12345"), 1, 0, S("abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 10, 0, SV("12345"), 1, 1, S("abcdefghij2klmnopqrst")); + test(S("abcdefghijklmnopqrst"), 10, 0, SV("12345"), 1, 2, S("abcdefghij23klmnopqrst")); +} + +template +void test46() +{ + test(S("abcdefghijklmnopqrst"), 10, 0, SV("12345"), 1, 3, S("abcdefghij234klmnopqrst")); + test(S("abcdefghijklmnopqrst"), 10, 0, SV("12345"), 1, 4, S("abcdefghij2345klmnopqrst")); + test(S("abcdefghijklmnopqrst"), 10, 0, SV("12345"), 1, 5, S("abcdefghij2345klmnopqrst")); + test(S("abcdefghijklmnopqrst"), 10, 0, SV("12345"), 2, 0, S("abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 10, 0, SV("12345"), 2, 1, S("abcdefghij3klmnopqrst")); + test(S("abcdefghijklmnopqrst"), 10, 0, SV("12345"), 2, 2, S("abcdefghij34klmnopqrst")); + test(S("abcdefghijklmnopqrst"), 10, 0, SV("12345"), 2, 3, S("abcdefghij345klmnopqrst")); + test(S("abcdefghijklmnopqrst"), 10, 0, SV("12345"), 2, 4, S("abcdefghij345klmnopqrst")); + test(S("abcdefghijklmnopqrst"), 10, 0, SV("12345"), 4, 0, S("abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 10, 0, SV("12345"), 4, 1, S("abcdefghij5klmnopqrst")); + test(S("abcdefghijklmnopqrst"), 10, 0, SV("12345"), 4, 2, S("abcdefghij5klmnopqrst")); + test(S("abcdefghijklmnopqrst"), 10, 0, SV("12345"), 5, 0, S("abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 10, 0, SV("12345"), 5, 1, S("abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 10, 0, SV("12345"), 6, 0, S("can't happen")); + test(S("abcdefghijklmnopqrst"), 10, 0, SV("1234567890"), 0, 0, S("abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 10, 0, SV("1234567890"), 0, 1, S("abcdefghij1klmnopqrst")); + test(S("abcdefghijklmnopqrst"), 10, 0, SV("1234567890"), 0, 5, S("abcdefghij12345klmnopqrst")); + test(S("abcdefghijklmnopqrst"), 10, 0, SV("1234567890"), 0, 9, S("abcdefghij123456789klmnopqrst")); + test(S("abcdefghijklmnopqrst"), 10, 0, SV("1234567890"), 0, 10, S("abcdefghij1234567890klmnopqrst")); + test(S("abcdefghijklmnopqrst"), 10, 0, SV("1234567890"), 0, 11, S("abcdefghij1234567890klmnopqrst")); + test(S("abcdefghijklmnopqrst"), 10, 0, SV("1234567890"), 1, 0, S("abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 10, 0, SV("1234567890"), 1, 1, S("abcdefghij2klmnopqrst")); + test(S("abcdefghijklmnopqrst"), 10, 0, SV("1234567890"), 1, 4, S("abcdefghij2345klmnopqrst")); + test(S("abcdefghijklmnopqrst"), 10, 0, SV("1234567890"), 1, 8, S("abcdefghij23456789klmnopqrst")); + test(S("abcdefghijklmnopqrst"), 10, 0, SV("1234567890"), 1, 9, S("abcdefghij234567890klmnopqrst")); + test(S("abcdefghijklmnopqrst"), 10, 0, SV("1234567890"), 1, 10, S("abcdefghij234567890klmnopqrst")); + test(S("abcdefghijklmnopqrst"), 10, 0, SV("1234567890"), 5, 0, S("abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 10, 0, SV("1234567890"), 5, 1, S("abcdefghij6klmnopqrst")); + test(S("abcdefghijklmnopqrst"), 10, 0, SV("1234567890"), 5, 2, S("abcdefghij67klmnopqrst")); + test(S("abcdefghijklmnopqrst"), 10, 0, SV("1234567890"), 5, 4, S("abcdefghij6789klmnopqrst")); + test(S("abcdefghijklmnopqrst"), 10, 0, SV("1234567890"), 5, 5, S("abcdefghij67890klmnopqrst")); + test(S("abcdefghijklmnopqrst"), 10, 0, SV("1234567890"), 5, 6, S("abcdefghij67890klmnopqrst")); + test(S("abcdefghijklmnopqrst"), 10, 0, SV("1234567890"), 9, 0, S("abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 10, 0, SV("1234567890"), 9, 1, S("abcdefghij0klmnopqrst")); + test(S("abcdefghijklmnopqrst"), 10, 0, SV("1234567890"), 9, 2, S("abcdefghij0klmnopqrst")); + test(S("abcdefghijklmnopqrst"), 10, 0, SV("1234567890"), 10, 0, S("abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 10, 0, SV("1234567890"), 10, 1, S("abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 10, 0, SV("1234567890"), 11, 0, S("can't happen")); + test(S("abcdefghijklmnopqrst"), 10, 0, SV("12345678901234567890"), 0, 0, S("abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 10, 0, SV("12345678901234567890"), 0, 1, S("abcdefghij1klmnopqrst")); + test(S("abcdefghijklmnopqrst"), 10, 0, SV("12345678901234567890"), 0, 10, S("abcdefghij1234567890klmnopqrst")); + test(S("abcdefghijklmnopqrst"), 10, 0, SV("12345678901234567890"), 0, 19, S("abcdefghij1234567890123456789klmnopqrst")); + test(S("abcdefghijklmnopqrst"), 10, 0, SV("12345678901234567890"), 0, 20, S("abcdefghij12345678901234567890klmnopqrst")); + test(S("abcdefghijklmnopqrst"), 10, 0, SV("12345678901234567890"), 0, 21, S("abcdefghij12345678901234567890klmnopqrst")); + test(S("abcdefghijklmnopqrst"), 10, 0, SV("12345678901234567890"), 1, 0, S("abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 10, 0, SV("12345678901234567890"), 1, 1, S("abcdefghij2klmnopqrst")); + test(S("abcdefghijklmnopqrst"), 10, 0, SV("12345678901234567890"), 1, 9, S("abcdefghij234567890klmnopqrst")); + test(S("abcdefghijklmnopqrst"), 10, 0, SV("12345678901234567890"), 1, 18, S("abcdefghij234567890123456789klmnopqrst")); + test(S("abcdefghijklmnopqrst"), 10, 0, SV("12345678901234567890"), 1, 19, S("abcdefghij2345678901234567890klmnopqrst")); + test(S("abcdefghijklmnopqrst"), 10, 0, SV("12345678901234567890"), 1, 20, S("abcdefghij2345678901234567890klmnopqrst")); + test(S("abcdefghijklmnopqrst"), 10, 0, SV("12345678901234567890"), 10, 0, S("abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 10, 0, SV("12345678901234567890"), 10, 1, S("abcdefghij1klmnopqrst")); + test(S("abcdefghijklmnopqrst"), 10, 0, SV("12345678901234567890"), 10, 5, S("abcdefghij12345klmnopqrst")); + test(S("abcdefghijklmnopqrst"), 10, 0, SV("12345678901234567890"), 10, 9, S("abcdefghij123456789klmnopqrst")); + test(S("abcdefghijklmnopqrst"), 10, 0, SV("12345678901234567890"), 10, 10, S("abcdefghij1234567890klmnopqrst")); + test(S("abcdefghijklmnopqrst"), 10, 0, SV("12345678901234567890"), 10, 11, S("abcdefghij1234567890klmnopqrst")); + test(S("abcdefghijklmnopqrst"), 10, 0, SV("12345678901234567890"), 19, 0, S("abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 10, 0, SV("12345678901234567890"), 19, 1, S("abcdefghij0klmnopqrst")); + test(S("abcdefghijklmnopqrst"), 10, 0, SV("12345678901234567890"), 19, 2, S("abcdefghij0klmnopqrst")); + test(S("abcdefghijklmnopqrst"), 10, 0, SV("12345678901234567890"), 20, 0, S("abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 10, 0, SV("12345678901234567890"), 20, 1, S("abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 10, 0, SV("12345678901234567890"), 21, 0, S("can't happen")); + test(S("abcdefghijklmnopqrst"), 10, 1, SV(""), 0, 0, S("abcdefghijlmnopqrst")); + test(S("abcdefghijklmnopqrst"), 10, 1, SV(""), 0, 1, S("abcdefghijlmnopqrst")); + test(S("abcdefghijklmnopqrst"), 10, 1, SV(""), 1, 0, S("can't happen")); + test(S("abcdefghijklmnopqrst"), 10, 1, SV("12345"), 0, 0, S("abcdefghijlmnopqrst")); + test(S("abcdefghijklmnopqrst"), 10, 1, SV("12345"), 0, 1, S("abcdefghij1lmnopqrst")); + test(S("abcdefghijklmnopqrst"), 10, 1, SV("12345"), 0, 2, S("abcdefghij12lmnopqrst")); + test(S("abcdefghijklmnopqrst"), 10, 1, SV("12345"), 0, 4, S("abcdefghij1234lmnopqrst")); + test(S("abcdefghijklmnopqrst"), 10, 1, SV("12345"), 0, 5, S("abcdefghij12345lmnopqrst")); + test(S("abcdefghijklmnopqrst"), 10, 1, SV("12345"), 0, 6, S("abcdefghij12345lmnopqrst")); + test(S("abcdefghijklmnopqrst"), 10, 1, SV("12345"), 1, 0, S("abcdefghijlmnopqrst")); + test(S("abcdefghijklmnopqrst"), 10, 1, SV("12345"), 1, 1, S("abcdefghij2lmnopqrst")); + test(S("abcdefghijklmnopqrst"), 10, 1, SV("12345"), 1, 2, S("abcdefghij23lmnopqrst")); + test(S("abcdefghijklmnopqrst"), 10, 1, SV("12345"), 1, 3, S("abcdefghij234lmnopqrst")); + test(S("abcdefghijklmnopqrst"), 10, 1, SV("12345"), 1, 4, S("abcdefghij2345lmnopqrst")); + test(S("abcdefghijklmnopqrst"), 10, 1, SV("12345"), 1, 5, S("abcdefghij2345lmnopqrst")); + test(S("abcdefghijklmnopqrst"), 10, 1, SV("12345"), 2, 0, S("abcdefghijlmnopqrst")); + test(S("abcdefghijklmnopqrst"), 10, 1, SV("12345"), 2, 1, S("abcdefghij3lmnopqrst")); + test(S("abcdefghijklmnopqrst"), 10, 1, SV("12345"), 2, 2, S("abcdefghij34lmnopqrst")); + test(S("abcdefghijklmnopqrst"), 10, 1, SV("12345"), 2, 3, S("abcdefghij345lmnopqrst")); + test(S("abcdefghijklmnopqrst"), 10, 1, SV("12345"), 2, 4, S("abcdefghij345lmnopqrst")); + test(S("abcdefghijklmnopqrst"), 10, 1, SV("12345"), 4, 0, S("abcdefghijlmnopqrst")); + test(S("abcdefghijklmnopqrst"), 10, 1, SV("12345"), 4, 1, S("abcdefghij5lmnopqrst")); + test(S("abcdefghijklmnopqrst"), 10, 1, SV("12345"), 4, 2, S("abcdefghij5lmnopqrst")); + test(S("abcdefghijklmnopqrst"), 10, 1, SV("12345"), 5, 0, S("abcdefghijlmnopqrst")); + test(S("abcdefghijklmnopqrst"), 10, 1, SV("12345"), 5, 1, S("abcdefghijlmnopqrst")); + test(S("abcdefghijklmnopqrst"), 10, 1, SV("12345"), 6, 0, S("can't happen")); + test(S("abcdefghijklmnopqrst"), 10, 1, SV("1234567890"), 0, 0, S("abcdefghijlmnopqrst")); + test(S("abcdefghijklmnopqrst"), 10, 1, SV("1234567890"), 0, 1, S("abcdefghij1lmnopqrst")); + test(S("abcdefghijklmnopqrst"), 10, 1, SV("1234567890"), 0, 5, S("abcdefghij12345lmnopqrst")); + test(S("abcdefghijklmnopqrst"), 10, 1, SV("1234567890"), 0, 9, S("abcdefghij123456789lmnopqrst")); + test(S("abcdefghijklmnopqrst"), 10, 1, SV("1234567890"), 0, 10, S("abcdefghij1234567890lmnopqrst")); + test(S("abcdefghijklmnopqrst"), 10, 1, SV("1234567890"), 0, 11, S("abcdefghij1234567890lmnopqrst")); + test(S("abcdefghijklmnopqrst"), 10, 1, SV("1234567890"), 1, 0, S("abcdefghijlmnopqrst")); + test(S("abcdefghijklmnopqrst"), 10, 1, SV("1234567890"), 1, 1, S("abcdefghij2lmnopqrst")); + test(S("abcdefghijklmnopqrst"), 10, 1, SV("1234567890"), 1, 4, S("abcdefghij2345lmnopqrst")); + test(S("abcdefghijklmnopqrst"), 10, 1, SV("1234567890"), 1, 8, S("abcdefghij23456789lmnopqrst")); + test(S("abcdefghijklmnopqrst"), 10, 1, SV("1234567890"), 1, 9, S("abcdefghij234567890lmnopqrst")); + test(S("abcdefghijklmnopqrst"), 10, 1, SV("1234567890"), 1, 10, S("abcdefghij234567890lmnopqrst")); +} + +template +void test47() +{ + test(S("abcdefghijklmnopqrst"), 10, 1, SV("1234567890"), 5, 0, S("abcdefghijlmnopqrst")); + test(S("abcdefghijklmnopqrst"), 10, 1, SV("1234567890"), 5, 1, S("abcdefghij6lmnopqrst")); + test(S("abcdefghijklmnopqrst"), 10, 1, SV("1234567890"), 5, 2, S("abcdefghij67lmnopqrst")); + test(S("abcdefghijklmnopqrst"), 10, 1, SV("1234567890"), 5, 4, S("abcdefghij6789lmnopqrst")); + test(S("abcdefghijklmnopqrst"), 10, 1, SV("1234567890"), 5, 5, S("abcdefghij67890lmnopqrst")); + test(S("abcdefghijklmnopqrst"), 10, 1, SV("1234567890"), 5, 6, S("abcdefghij67890lmnopqrst")); + test(S("abcdefghijklmnopqrst"), 10, 1, SV("1234567890"), 9, 0, S("abcdefghijlmnopqrst")); + test(S("abcdefghijklmnopqrst"), 10, 1, SV("1234567890"), 9, 1, S("abcdefghij0lmnopqrst")); + test(S("abcdefghijklmnopqrst"), 10, 1, SV("1234567890"), 9, 2, S("abcdefghij0lmnopqrst")); + test(S("abcdefghijklmnopqrst"), 10, 1, SV("1234567890"), 10, 0, S("abcdefghijlmnopqrst")); + test(S("abcdefghijklmnopqrst"), 10, 1, SV("1234567890"), 10, 1, S("abcdefghijlmnopqrst")); + test(S("abcdefghijklmnopqrst"), 10, 1, SV("1234567890"), 11, 0, S("can't happen")); + test(S("abcdefghijklmnopqrst"), 10, 1, SV("12345678901234567890"), 0, 0, S("abcdefghijlmnopqrst")); + test(S("abcdefghijklmnopqrst"), 10, 1, SV("12345678901234567890"), 0, 1, S("abcdefghij1lmnopqrst")); + test(S("abcdefghijklmnopqrst"), 10, 1, SV("12345678901234567890"), 0, 10, S("abcdefghij1234567890lmnopqrst")); + test(S("abcdefghijklmnopqrst"), 10, 1, SV("12345678901234567890"), 0, 19, S("abcdefghij1234567890123456789lmnopqrst")); + test(S("abcdefghijklmnopqrst"), 10, 1, SV("12345678901234567890"), 0, 20, S("abcdefghij12345678901234567890lmnopqrst")); + test(S("abcdefghijklmnopqrst"), 10, 1, SV("12345678901234567890"), 0, 21, S("abcdefghij12345678901234567890lmnopqrst")); + test(S("abcdefghijklmnopqrst"), 10, 1, SV("12345678901234567890"), 1, 0, S("abcdefghijlmnopqrst")); + test(S("abcdefghijklmnopqrst"), 10, 1, SV("12345678901234567890"), 1, 1, S("abcdefghij2lmnopqrst")); + test(S("abcdefghijklmnopqrst"), 10, 1, SV("12345678901234567890"), 1, 9, S("abcdefghij234567890lmnopqrst")); + test(S("abcdefghijklmnopqrst"), 10, 1, SV("12345678901234567890"), 1, 18, S("abcdefghij234567890123456789lmnopqrst")); + test(S("abcdefghijklmnopqrst"), 10, 1, SV("12345678901234567890"), 1, 19, S("abcdefghij2345678901234567890lmnopqrst")); + test(S("abcdefghijklmnopqrst"), 10, 1, SV("12345678901234567890"), 1, 20, S("abcdefghij2345678901234567890lmnopqrst")); + test(S("abcdefghijklmnopqrst"), 10, 1, SV("12345678901234567890"), 10, 0, S("abcdefghijlmnopqrst")); + test(S("abcdefghijklmnopqrst"), 10, 1, SV("12345678901234567890"), 10, 1, S("abcdefghij1lmnopqrst")); + test(S("abcdefghijklmnopqrst"), 10, 1, SV("12345678901234567890"), 10, 5, S("abcdefghij12345lmnopqrst")); + test(S("abcdefghijklmnopqrst"), 10, 1, SV("12345678901234567890"), 10, 9, S("abcdefghij123456789lmnopqrst")); + test(S("abcdefghijklmnopqrst"), 10, 1, SV("12345678901234567890"), 10, 10, S("abcdefghij1234567890lmnopqrst")); + test(S("abcdefghijklmnopqrst"), 10, 1, SV("12345678901234567890"), 10, 11, S("abcdefghij1234567890lmnopqrst")); + test(S("abcdefghijklmnopqrst"), 10, 1, SV("12345678901234567890"), 19, 0, S("abcdefghijlmnopqrst")); + test(S("abcdefghijklmnopqrst"), 10, 1, SV("12345678901234567890"), 19, 1, S("abcdefghij0lmnopqrst")); + test(S("abcdefghijklmnopqrst"), 10, 1, SV("12345678901234567890"), 19, 2, S("abcdefghij0lmnopqrst")); + test(S("abcdefghijklmnopqrst"), 10, 1, SV("12345678901234567890"), 20, 0, S("abcdefghijlmnopqrst")); + test(S("abcdefghijklmnopqrst"), 10, 1, SV("12345678901234567890"), 20, 1, S("abcdefghijlmnopqrst")); + test(S("abcdefghijklmnopqrst"), 10, 1, SV("12345678901234567890"), 21, 0, S("can't happen")); + test(S("abcdefghijklmnopqrst"), 10, 5, SV(""), 0, 0, S("abcdefghijpqrst")); + test(S("abcdefghijklmnopqrst"), 10, 5, SV(""), 0, 1, S("abcdefghijpqrst")); + test(S("abcdefghijklmnopqrst"), 10, 5, SV(""), 1, 0, S("can't happen")); + test(S("abcdefghijklmnopqrst"), 10, 5, SV("12345"), 0, 0, S("abcdefghijpqrst")); + test(S("abcdefghijklmnopqrst"), 10, 5, SV("12345"), 0, 1, S("abcdefghij1pqrst")); + test(S("abcdefghijklmnopqrst"), 10, 5, SV("12345"), 0, 2, S("abcdefghij12pqrst")); + test(S("abcdefghijklmnopqrst"), 10, 5, SV("12345"), 0, 4, S("abcdefghij1234pqrst")); + test(S("abcdefghijklmnopqrst"), 10, 5, SV("12345"), 0, 5, S("abcdefghij12345pqrst")); + test(S("abcdefghijklmnopqrst"), 10, 5, SV("12345"), 0, 6, S("abcdefghij12345pqrst")); + test(S("abcdefghijklmnopqrst"), 10, 5, SV("12345"), 1, 0, S("abcdefghijpqrst")); + test(S("abcdefghijklmnopqrst"), 10, 5, SV("12345"), 1, 1, S("abcdefghij2pqrst")); + test(S("abcdefghijklmnopqrst"), 10, 5, SV("12345"), 1, 2, S("abcdefghij23pqrst")); + test(S("abcdefghijklmnopqrst"), 10, 5, SV("12345"), 1, 3, S("abcdefghij234pqrst")); + test(S("abcdefghijklmnopqrst"), 10, 5, SV("12345"), 1, 4, S("abcdefghij2345pqrst")); + test(S("abcdefghijklmnopqrst"), 10, 5, SV("12345"), 1, 5, S("abcdefghij2345pqrst")); + test(S("abcdefghijklmnopqrst"), 10, 5, SV("12345"), 2, 0, S("abcdefghijpqrst")); + test(S("abcdefghijklmnopqrst"), 10, 5, SV("12345"), 2, 1, S("abcdefghij3pqrst")); + test(S("abcdefghijklmnopqrst"), 10, 5, SV("12345"), 2, 2, S("abcdefghij34pqrst")); + test(S("abcdefghijklmnopqrst"), 10, 5, SV("12345"), 2, 3, S("abcdefghij345pqrst")); + test(S("abcdefghijklmnopqrst"), 10, 5, SV("12345"), 2, 4, S("abcdefghij345pqrst")); + test(S("abcdefghijklmnopqrst"), 10, 5, SV("12345"), 4, 0, S("abcdefghijpqrst")); + test(S("abcdefghijklmnopqrst"), 10, 5, SV("12345"), 4, 1, S("abcdefghij5pqrst")); + test(S("abcdefghijklmnopqrst"), 10, 5, SV("12345"), 4, 2, S("abcdefghij5pqrst")); + test(S("abcdefghijklmnopqrst"), 10, 5, SV("12345"), 5, 0, S("abcdefghijpqrst")); + test(S("abcdefghijklmnopqrst"), 10, 5, SV("12345"), 5, 1, S("abcdefghijpqrst")); + test(S("abcdefghijklmnopqrst"), 10, 5, SV("12345"), 6, 0, S("can't happen")); + test(S("abcdefghijklmnopqrst"), 10, 5, SV("1234567890"), 0, 0, S("abcdefghijpqrst")); + test(S("abcdefghijklmnopqrst"), 10, 5, SV("1234567890"), 0, 1, S("abcdefghij1pqrst")); + test(S("abcdefghijklmnopqrst"), 10, 5, SV("1234567890"), 0, 5, S("abcdefghij12345pqrst")); + test(S("abcdefghijklmnopqrst"), 10, 5, SV("1234567890"), 0, 9, S("abcdefghij123456789pqrst")); + test(S("abcdefghijklmnopqrst"), 10, 5, SV("1234567890"), 0, 10, S("abcdefghij1234567890pqrst")); + test(S("abcdefghijklmnopqrst"), 10, 5, SV("1234567890"), 0, 11, S("abcdefghij1234567890pqrst")); + test(S("abcdefghijklmnopqrst"), 10, 5, SV("1234567890"), 1, 0, S("abcdefghijpqrst")); + test(S("abcdefghijklmnopqrst"), 10, 5, SV("1234567890"), 1, 1, S("abcdefghij2pqrst")); + test(S("abcdefghijklmnopqrst"), 10, 5, SV("1234567890"), 1, 4, S("abcdefghij2345pqrst")); + test(S("abcdefghijklmnopqrst"), 10, 5, SV("1234567890"), 1, 8, S("abcdefghij23456789pqrst")); + test(S("abcdefghijklmnopqrst"), 10, 5, SV("1234567890"), 1, 9, S("abcdefghij234567890pqrst")); + test(S("abcdefghijklmnopqrst"), 10, 5, SV("1234567890"), 1, 10, S("abcdefghij234567890pqrst")); + test(S("abcdefghijklmnopqrst"), 10, 5, SV("1234567890"), 5, 0, S("abcdefghijpqrst")); + test(S("abcdefghijklmnopqrst"), 10, 5, SV("1234567890"), 5, 1, S("abcdefghij6pqrst")); + test(S("abcdefghijklmnopqrst"), 10, 5, SV("1234567890"), 5, 2, S("abcdefghij67pqrst")); + test(S("abcdefghijklmnopqrst"), 10, 5, SV("1234567890"), 5, 4, S("abcdefghij6789pqrst")); + test(S("abcdefghijklmnopqrst"), 10, 5, SV("1234567890"), 5, 5, S("abcdefghij67890pqrst")); + test(S("abcdefghijklmnopqrst"), 10, 5, SV("1234567890"), 5, 6, S("abcdefghij67890pqrst")); + test(S("abcdefghijklmnopqrst"), 10, 5, SV("1234567890"), 9, 0, S("abcdefghijpqrst")); + test(S("abcdefghijklmnopqrst"), 10, 5, SV("1234567890"), 9, 1, S("abcdefghij0pqrst")); + test(S("abcdefghijklmnopqrst"), 10, 5, SV("1234567890"), 9, 2, S("abcdefghij0pqrst")); + test(S("abcdefghijklmnopqrst"), 10, 5, SV("1234567890"), 10, 0, S("abcdefghijpqrst")); + test(S("abcdefghijklmnopqrst"), 10, 5, SV("1234567890"), 10, 1, S("abcdefghijpqrst")); + test(S("abcdefghijklmnopqrst"), 10, 5, SV("1234567890"), 11, 0, S("can't happen")); + test(S("abcdefghijklmnopqrst"), 10, 5, SV("12345678901234567890"), 0, 0, S("abcdefghijpqrst")); + test(S("abcdefghijklmnopqrst"), 10, 5, SV("12345678901234567890"), 0, 1, S("abcdefghij1pqrst")); + test(S("abcdefghijklmnopqrst"), 10, 5, SV("12345678901234567890"), 0, 10, S("abcdefghij1234567890pqrst")); + test(S("abcdefghijklmnopqrst"), 10, 5, SV("12345678901234567890"), 0, 19, S("abcdefghij1234567890123456789pqrst")); + test(S("abcdefghijklmnopqrst"), 10, 5, SV("12345678901234567890"), 0, 20, S("abcdefghij12345678901234567890pqrst")); + test(S("abcdefghijklmnopqrst"), 10, 5, SV("12345678901234567890"), 0, 21, S("abcdefghij12345678901234567890pqrst")); + test(S("abcdefghijklmnopqrst"), 10, 5, SV("12345678901234567890"), 1, 0, S("abcdefghijpqrst")); + test(S("abcdefghijklmnopqrst"), 10, 5, SV("12345678901234567890"), 1, 1, S("abcdefghij2pqrst")); + test(S("abcdefghijklmnopqrst"), 10, 5, SV("12345678901234567890"), 1, 9, S("abcdefghij234567890pqrst")); + test(S("abcdefghijklmnopqrst"), 10, 5, SV("12345678901234567890"), 1, 18, S("abcdefghij234567890123456789pqrst")); + test(S("abcdefghijklmnopqrst"), 10, 5, SV("12345678901234567890"), 1, 19, S("abcdefghij2345678901234567890pqrst")); + test(S("abcdefghijklmnopqrst"), 10, 5, SV("12345678901234567890"), 1, 20, S("abcdefghij2345678901234567890pqrst")); + test(S("abcdefghijklmnopqrst"), 10, 5, SV("12345678901234567890"), 10, 0, S("abcdefghijpqrst")); + test(S("abcdefghijklmnopqrst"), 10, 5, SV("12345678901234567890"), 10, 1, S("abcdefghij1pqrst")); +} + +template +void test48() +{ + test(S("abcdefghijklmnopqrst"), 10, 5, SV("12345678901234567890"), 10, 5, S("abcdefghij12345pqrst")); + test(S("abcdefghijklmnopqrst"), 10, 5, SV("12345678901234567890"), 10, 9, S("abcdefghij123456789pqrst")); + test(S("abcdefghijklmnopqrst"), 10, 5, SV("12345678901234567890"), 10, 10, S("abcdefghij1234567890pqrst")); + test(S("abcdefghijklmnopqrst"), 10, 5, SV("12345678901234567890"), 10, 11, S("abcdefghij1234567890pqrst")); + test(S("abcdefghijklmnopqrst"), 10, 5, SV("12345678901234567890"), 19, 0, S("abcdefghijpqrst")); + test(S("abcdefghijklmnopqrst"), 10, 5, SV("12345678901234567890"), 19, 1, S("abcdefghij0pqrst")); + test(S("abcdefghijklmnopqrst"), 10, 5, SV("12345678901234567890"), 19, 2, S("abcdefghij0pqrst")); + test(S("abcdefghijklmnopqrst"), 10, 5, SV("12345678901234567890"), 20, 0, S("abcdefghijpqrst")); + test(S("abcdefghijklmnopqrst"), 10, 5, SV("12345678901234567890"), 20, 1, S("abcdefghijpqrst")); + test(S("abcdefghijklmnopqrst"), 10, 5, SV("12345678901234567890"), 21, 0, S("can't happen")); + test(S("abcdefghijklmnopqrst"), 10, 9, SV(""), 0, 0, S("abcdefghijt")); + test(S("abcdefghijklmnopqrst"), 10, 9, SV(""), 0, 1, S("abcdefghijt")); + test(S("abcdefghijklmnopqrst"), 10, 9, SV(""), 1, 0, S("can't happen")); + test(S("abcdefghijklmnopqrst"), 10, 9, SV("12345"), 0, 0, S("abcdefghijt")); + test(S("abcdefghijklmnopqrst"), 10, 9, SV("12345"), 0, 1, S("abcdefghij1t")); + test(S("abcdefghijklmnopqrst"), 10, 9, SV("12345"), 0, 2, S("abcdefghij12t")); + test(S("abcdefghijklmnopqrst"), 10, 9, SV("12345"), 0, 4, S("abcdefghij1234t")); + test(S("abcdefghijklmnopqrst"), 10, 9, SV("12345"), 0, 5, S("abcdefghij12345t")); + test(S("abcdefghijklmnopqrst"), 10, 9, SV("12345"), 0, 6, S("abcdefghij12345t")); + test(S("abcdefghijklmnopqrst"), 10, 9, SV("12345"), 1, 0, S("abcdefghijt")); + test(S("abcdefghijklmnopqrst"), 10, 9, SV("12345"), 1, 1, S("abcdefghij2t")); + test(S("abcdefghijklmnopqrst"), 10, 9, SV("12345"), 1, 2, S("abcdefghij23t")); + test(S("abcdefghijklmnopqrst"), 10, 9, SV("12345"), 1, 3, S("abcdefghij234t")); + test(S("abcdefghijklmnopqrst"), 10, 9, SV("12345"), 1, 4, S("abcdefghij2345t")); + test(S("abcdefghijklmnopqrst"), 10, 9, SV("12345"), 1, 5, S("abcdefghij2345t")); + test(S("abcdefghijklmnopqrst"), 10, 9, SV("12345"), 2, 0, S("abcdefghijt")); + test(S("abcdefghijklmnopqrst"), 10, 9, SV("12345"), 2, 1, S("abcdefghij3t")); + test(S("abcdefghijklmnopqrst"), 10, 9, SV("12345"), 2, 2, S("abcdefghij34t")); + test(S("abcdefghijklmnopqrst"), 10, 9, SV("12345"), 2, 3, S("abcdefghij345t")); + test(S("abcdefghijklmnopqrst"), 10, 9, SV("12345"), 2, 4, S("abcdefghij345t")); + test(S("abcdefghijklmnopqrst"), 10, 9, SV("12345"), 4, 0, S("abcdefghijt")); + test(S("abcdefghijklmnopqrst"), 10, 9, SV("12345"), 4, 1, S("abcdefghij5t")); + test(S("abcdefghijklmnopqrst"), 10, 9, SV("12345"), 4, 2, S("abcdefghij5t")); + test(S("abcdefghijklmnopqrst"), 10, 9, SV("12345"), 5, 0, S("abcdefghijt")); + test(S("abcdefghijklmnopqrst"), 10, 9, SV("12345"), 5, 1, S("abcdefghijt")); + test(S("abcdefghijklmnopqrst"), 10, 9, SV("12345"), 6, 0, S("can't happen")); + test(S("abcdefghijklmnopqrst"), 10, 9, SV("1234567890"), 0, 0, S("abcdefghijt")); + test(S("abcdefghijklmnopqrst"), 10, 9, SV("1234567890"), 0, 1, S("abcdefghij1t")); + test(S("abcdefghijklmnopqrst"), 10, 9, SV("1234567890"), 0, 5, S("abcdefghij12345t")); + test(S("abcdefghijklmnopqrst"), 10, 9, SV("1234567890"), 0, 9, S("abcdefghij123456789t")); + test(S("abcdefghijklmnopqrst"), 10, 9, SV("1234567890"), 0, 10, S("abcdefghij1234567890t")); + test(S("abcdefghijklmnopqrst"), 10, 9, SV("1234567890"), 0, 11, S("abcdefghij1234567890t")); + test(S("abcdefghijklmnopqrst"), 10, 9, SV("1234567890"), 1, 0, S("abcdefghijt")); + test(S("abcdefghijklmnopqrst"), 10, 9, SV("1234567890"), 1, 1, S("abcdefghij2t")); + test(S("abcdefghijklmnopqrst"), 10, 9, SV("1234567890"), 1, 4, S("abcdefghij2345t")); + test(S("abcdefghijklmnopqrst"), 10, 9, SV("1234567890"), 1, 8, S("abcdefghij23456789t")); + test(S("abcdefghijklmnopqrst"), 10, 9, SV("1234567890"), 1, 9, S("abcdefghij234567890t")); + test(S("abcdefghijklmnopqrst"), 10, 9, SV("1234567890"), 1, 10, S("abcdefghij234567890t")); + test(S("abcdefghijklmnopqrst"), 10, 9, SV("1234567890"), 5, 0, S("abcdefghijt")); + test(S("abcdefghijklmnopqrst"), 10, 9, SV("1234567890"), 5, 1, S("abcdefghij6t")); + test(S("abcdefghijklmnopqrst"), 10, 9, SV("1234567890"), 5, 2, S("abcdefghij67t")); + test(S("abcdefghijklmnopqrst"), 10, 9, SV("1234567890"), 5, 4, S("abcdefghij6789t")); + test(S("abcdefghijklmnopqrst"), 10, 9, SV("1234567890"), 5, 5, S("abcdefghij67890t")); + test(S("abcdefghijklmnopqrst"), 10, 9, SV("1234567890"), 5, 6, S("abcdefghij67890t")); + test(S("abcdefghijklmnopqrst"), 10, 9, SV("1234567890"), 9, 0, S("abcdefghijt")); + test(S("abcdefghijklmnopqrst"), 10, 9, SV("1234567890"), 9, 1, S("abcdefghij0t")); + test(S("abcdefghijklmnopqrst"), 10, 9, SV("1234567890"), 9, 2, S("abcdefghij0t")); + test(S("abcdefghijklmnopqrst"), 10, 9, SV("1234567890"), 10, 0, S("abcdefghijt")); + test(S("abcdefghijklmnopqrst"), 10, 9, SV("1234567890"), 10, 1, S("abcdefghijt")); + test(S("abcdefghijklmnopqrst"), 10, 9, SV("1234567890"), 11, 0, S("can't happen")); + test(S("abcdefghijklmnopqrst"), 10, 9, SV("12345678901234567890"), 0, 0, S("abcdefghijt")); + test(S("abcdefghijklmnopqrst"), 10, 9, SV("12345678901234567890"), 0, 1, S("abcdefghij1t")); + test(S("abcdefghijklmnopqrst"), 10, 9, SV("12345678901234567890"), 0, 10, S("abcdefghij1234567890t")); + test(S("abcdefghijklmnopqrst"), 10, 9, SV("12345678901234567890"), 0, 19, S("abcdefghij1234567890123456789t")); + test(S("abcdefghijklmnopqrst"), 10, 9, SV("12345678901234567890"), 0, 20, S("abcdefghij12345678901234567890t")); + test(S("abcdefghijklmnopqrst"), 10, 9, SV("12345678901234567890"), 0, 21, S("abcdefghij12345678901234567890t")); + test(S("abcdefghijklmnopqrst"), 10, 9, SV("12345678901234567890"), 1, 0, S("abcdefghijt")); + test(S("abcdefghijklmnopqrst"), 10, 9, SV("12345678901234567890"), 1, 1, S("abcdefghij2t")); + test(S("abcdefghijklmnopqrst"), 10, 9, SV("12345678901234567890"), 1, 9, S("abcdefghij234567890t")); + test(S("abcdefghijklmnopqrst"), 10, 9, SV("12345678901234567890"), 1, 18, S("abcdefghij234567890123456789t")); + test(S("abcdefghijklmnopqrst"), 10, 9, SV("12345678901234567890"), 1, 19, S("abcdefghij2345678901234567890t")); + test(S("abcdefghijklmnopqrst"), 10, 9, SV("12345678901234567890"), 1, 20, S("abcdefghij2345678901234567890t")); + test(S("abcdefghijklmnopqrst"), 10, 9, SV("12345678901234567890"), 10, 0, S("abcdefghijt")); + test(S("abcdefghijklmnopqrst"), 10, 9, SV("12345678901234567890"), 10, 1, S("abcdefghij1t")); + test(S("abcdefghijklmnopqrst"), 10, 9, SV("12345678901234567890"), 10, 5, S("abcdefghij12345t")); + test(S("abcdefghijklmnopqrst"), 10, 9, SV("12345678901234567890"), 10, 9, S("abcdefghij123456789t")); + test(S("abcdefghijklmnopqrst"), 10, 9, SV("12345678901234567890"), 10, 10, S("abcdefghij1234567890t")); + test(S("abcdefghijklmnopqrst"), 10, 9, SV("12345678901234567890"), 10, 11, S("abcdefghij1234567890t")); + test(S("abcdefghijklmnopqrst"), 10, 9, SV("12345678901234567890"), 19, 0, S("abcdefghijt")); + test(S("abcdefghijklmnopqrst"), 10, 9, SV("12345678901234567890"), 19, 1, S("abcdefghij0t")); + test(S("abcdefghijklmnopqrst"), 10, 9, SV("12345678901234567890"), 19, 2, S("abcdefghij0t")); + test(S("abcdefghijklmnopqrst"), 10, 9, SV("12345678901234567890"), 20, 0, S("abcdefghijt")); + test(S("abcdefghijklmnopqrst"), 10, 9, SV("12345678901234567890"), 20, 1, S("abcdefghijt")); + test(S("abcdefghijklmnopqrst"), 10, 9, SV("12345678901234567890"), 21, 0, S("can't happen")); + test(S("abcdefghijklmnopqrst"), 10, 10, SV(""), 0, 0, S("abcdefghij")); + test(S("abcdefghijklmnopqrst"), 10, 10, SV(""), 0, 1, S("abcdefghij")); + test(S("abcdefghijklmnopqrst"), 10, 10, SV(""), 1, 0, S("can't happen")); + test(S("abcdefghijklmnopqrst"), 10, 10, SV("12345"), 0, 0, S("abcdefghij")); + test(S("abcdefghijklmnopqrst"), 10, 10, SV("12345"), 0, 1, S("abcdefghij1")); + test(S("abcdefghijklmnopqrst"), 10, 10, SV("12345"), 0, 2, S("abcdefghij12")); + test(S("abcdefghijklmnopqrst"), 10, 10, SV("12345"), 0, 4, S("abcdefghij1234")); + test(S("abcdefghijklmnopqrst"), 10, 10, SV("12345"), 0, 5, S("abcdefghij12345")); + test(S("abcdefghijklmnopqrst"), 10, 10, SV("12345"), 0, 6, S("abcdefghij12345")); + test(S("abcdefghijklmnopqrst"), 10, 10, SV("12345"), 1, 0, S("abcdefghij")); + test(S("abcdefghijklmnopqrst"), 10, 10, SV("12345"), 1, 1, S("abcdefghij2")); + test(S("abcdefghijklmnopqrst"), 10, 10, SV("12345"), 1, 2, S("abcdefghij23")); + test(S("abcdefghijklmnopqrst"), 10, 10, SV("12345"), 1, 3, S("abcdefghij234")); + test(S("abcdefghijklmnopqrst"), 10, 10, SV("12345"), 1, 4, S("abcdefghij2345")); + test(S("abcdefghijklmnopqrst"), 10, 10, SV("12345"), 1, 5, S("abcdefghij2345")); + test(S("abcdefghijklmnopqrst"), 10, 10, SV("12345"), 2, 0, S("abcdefghij")); +} + +template +void test49() +{ + test(S("abcdefghijklmnopqrst"), 10, 10, SV("12345"), 2, 1, S("abcdefghij3")); + test(S("abcdefghijklmnopqrst"), 10, 10, SV("12345"), 2, 2, S("abcdefghij34")); + test(S("abcdefghijklmnopqrst"), 10, 10, SV("12345"), 2, 3, S("abcdefghij345")); + test(S("abcdefghijklmnopqrst"), 10, 10, SV("12345"), 2, 4, S("abcdefghij345")); + test(S("abcdefghijklmnopqrst"), 10, 10, SV("12345"), 4, 0, S("abcdefghij")); + test(S("abcdefghijklmnopqrst"), 10, 10, SV("12345"), 4, 1, S("abcdefghij5")); + test(S("abcdefghijklmnopqrst"), 10, 10, SV("12345"), 4, 2, S("abcdefghij5")); + test(S("abcdefghijklmnopqrst"), 10, 10, SV("12345"), 5, 0, S("abcdefghij")); + test(S("abcdefghijklmnopqrst"), 10, 10, SV("12345"), 5, 1, S("abcdefghij")); + test(S("abcdefghijklmnopqrst"), 10, 10, SV("12345"), 6, 0, S("can't happen")); + test(S("abcdefghijklmnopqrst"), 10, 10, SV("1234567890"), 0, 0, S("abcdefghij")); + test(S("abcdefghijklmnopqrst"), 10, 10, SV("1234567890"), 0, 1, S("abcdefghij1")); + test(S("abcdefghijklmnopqrst"), 10, 10, SV("1234567890"), 0, 5, S("abcdefghij12345")); + test(S("abcdefghijklmnopqrst"), 10, 10, SV("1234567890"), 0, 9, S("abcdefghij123456789")); + test(S("abcdefghijklmnopqrst"), 10, 10, SV("1234567890"), 0, 10, S("abcdefghij1234567890")); + test(S("abcdefghijklmnopqrst"), 10, 10, SV("1234567890"), 0, 11, S("abcdefghij1234567890")); + test(S("abcdefghijklmnopqrst"), 10, 10, SV("1234567890"), 1, 0, S("abcdefghij")); + test(S("abcdefghijklmnopqrst"), 10, 10, SV("1234567890"), 1, 1, S("abcdefghij2")); + test(S("abcdefghijklmnopqrst"), 10, 10, SV("1234567890"), 1, 4, S("abcdefghij2345")); + test(S("abcdefghijklmnopqrst"), 10, 10, SV("1234567890"), 1, 8, S("abcdefghij23456789")); + test(S("abcdefghijklmnopqrst"), 10, 10, SV("1234567890"), 1, 9, S("abcdefghij234567890")); + test(S("abcdefghijklmnopqrst"), 10, 10, SV("1234567890"), 1, 10, S("abcdefghij234567890")); + test(S("abcdefghijklmnopqrst"), 10, 10, SV("1234567890"), 5, 0, S("abcdefghij")); + test(S("abcdefghijklmnopqrst"), 10, 10, SV("1234567890"), 5, 1, S("abcdefghij6")); + test(S("abcdefghijklmnopqrst"), 10, 10, SV("1234567890"), 5, 2, S("abcdefghij67")); + test(S("abcdefghijklmnopqrst"), 10, 10, SV("1234567890"), 5, 4, S("abcdefghij6789")); + test(S("abcdefghijklmnopqrst"), 10, 10, SV("1234567890"), 5, 5, S("abcdefghij67890")); + test(S("abcdefghijklmnopqrst"), 10, 10, SV("1234567890"), 5, 6, S("abcdefghij67890")); + test(S("abcdefghijklmnopqrst"), 10, 10, SV("1234567890"), 9, 0, S("abcdefghij")); + test(S("abcdefghijklmnopqrst"), 10, 10, SV("1234567890"), 9, 1, S("abcdefghij0")); + test(S("abcdefghijklmnopqrst"), 10, 10, SV("1234567890"), 9, 2, S("abcdefghij0")); + test(S("abcdefghijklmnopqrst"), 10, 10, SV("1234567890"), 10, 0, S("abcdefghij")); + test(S("abcdefghijklmnopqrst"), 10, 10, SV("1234567890"), 10, 1, S("abcdefghij")); + test(S("abcdefghijklmnopqrst"), 10, 10, SV("1234567890"), 11, 0, S("can't happen")); + test(S("abcdefghijklmnopqrst"), 10, 10, SV("12345678901234567890"), 0, 0, S("abcdefghij")); + test(S("abcdefghijklmnopqrst"), 10, 10, SV("12345678901234567890"), 0, 1, S("abcdefghij1")); + test(S("abcdefghijklmnopqrst"), 10, 10, SV("12345678901234567890"), 0, 10, S("abcdefghij1234567890")); + test(S("abcdefghijklmnopqrst"), 10, 10, SV("12345678901234567890"), 0, 19, S("abcdefghij1234567890123456789")); + test(S("abcdefghijklmnopqrst"), 10, 10, SV("12345678901234567890"), 0, 20, S("abcdefghij12345678901234567890")); + test(S("abcdefghijklmnopqrst"), 10, 10, SV("12345678901234567890"), 0, 21, S("abcdefghij12345678901234567890")); + test(S("abcdefghijklmnopqrst"), 10, 10, SV("12345678901234567890"), 1, 0, S("abcdefghij")); + test(S("abcdefghijklmnopqrst"), 10, 10, SV("12345678901234567890"), 1, 1, S("abcdefghij2")); + test(S("abcdefghijklmnopqrst"), 10, 10, SV("12345678901234567890"), 1, 9, S("abcdefghij234567890")); + test(S("abcdefghijklmnopqrst"), 10, 10, SV("12345678901234567890"), 1, 18, S("abcdefghij234567890123456789")); + test(S("abcdefghijklmnopqrst"), 10, 10, SV("12345678901234567890"), 1, 19, S("abcdefghij2345678901234567890")); + test(S("abcdefghijklmnopqrst"), 10, 10, SV("12345678901234567890"), 1, 20, S("abcdefghij2345678901234567890")); + test(S("abcdefghijklmnopqrst"), 10, 10, SV("12345678901234567890"), 10, 0, S("abcdefghij")); + test(S("abcdefghijklmnopqrst"), 10, 10, SV("12345678901234567890"), 10, 1, S("abcdefghij1")); + test(S("abcdefghijklmnopqrst"), 10, 10, SV("12345678901234567890"), 10, 5, S("abcdefghij12345")); + test(S("abcdefghijklmnopqrst"), 10, 10, SV("12345678901234567890"), 10, 9, S("abcdefghij123456789")); + test(S("abcdefghijklmnopqrst"), 10, 10, SV("12345678901234567890"), 10, 10, S("abcdefghij1234567890")); + test(S("abcdefghijklmnopqrst"), 10, 10, SV("12345678901234567890"), 10, 11, S("abcdefghij1234567890")); + test(S("abcdefghijklmnopqrst"), 10, 10, SV("12345678901234567890"), 19, 0, S("abcdefghij")); + test(S("abcdefghijklmnopqrst"), 10, 10, SV("12345678901234567890"), 19, 1, S("abcdefghij0")); + test(S("abcdefghijklmnopqrst"), 10, 10, SV("12345678901234567890"), 19, 2, S("abcdefghij0")); + test(S("abcdefghijklmnopqrst"), 10, 10, SV("12345678901234567890"), 20, 0, S("abcdefghij")); + test(S("abcdefghijklmnopqrst"), 10, 10, SV("12345678901234567890"), 20, 1, S("abcdefghij")); + test(S("abcdefghijklmnopqrst"), 10, 10, SV("12345678901234567890"), 21, 0, S("can't happen")); + test(S("abcdefghijklmnopqrst"), 10, 11, SV(""), 0, 0, S("abcdefghij")); + test(S("abcdefghijklmnopqrst"), 10, 11, SV(""), 0, 1, S("abcdefghij")); + test(S("abcdefghijklmnopqrst"), 10, 11, SV(""), 1, 0, S("can't happen")); + test(S("abcdefghijklmnopqrst"), 10, 11, SV("12345"), 0, 0, S("abcdefghij")); + test(S("abcdefghijklmnopqrst"), 10, 11, SV("12345"), 0, 1, S("abcdefghij1")); + test(S("abcdefghijklmnopqrst"), 10, 11, SV("12345"), 0, 2, S("abcdefghij12")); + test(S("abcdefghijklmnopqrst"), 10, 11, SV("12345"), 0, 4, S("abcdefghij1234")); + test(S("abcdefghijklmnopqrst"), 10, 11, SV("12345"), 0, 5, S("abcdefghij12345")); + test(S("abcdefghijklmnopqrst"), 10, 11, SV("12345"), 0, 6, S("abcdefghij12345")); + test(S("abcdefghijklmnopqrst"), 10, 11, SV("12345"), 1, 0, S("abcdefghij")); + test(S("abcdefghijklmnopqrst"), 10, 11, SV("12345"), 1, 1, S("abcdefghij2")); + test(S("abcdefghijklmnopqrst"), 10, 11, SV("12345"), 1, 2, S("abcdefghij23")); + test(S("abcdefghijklmnopqrst"), 10, 11, SV("12345"), 1, 3, S("abcdefghij234")); + test(S("abcdefghijklmnopqrst"), 10, 11, SV("12345"), 1, 4, S("abcdefghij2345")); + test(S("abcdefghijklmnopqrst"), 10, 11, SV("12345"), 1, 5, S("abcdefghij2345")); + test(S("abcdefghijklmnopqrst"), 10, 11, SV("12345"), 2, 0, S("abcdefghij")); + test(S("abcdefghijklmnopqrst"), 10, 11, SV("12345"), 2, 1, S("abcdefghij3")); + test(S("abcdefghijklmnopqrst"), 10, 11, SV("12345"), 2, 2, S("abcdefghij34")); + test(S("abcdefghijklmnopqrst"), 10, 11, SV("12345"), 2, 3, S("abcdefghij345")); + test(S("abcdefghijklmnopqrst"), 10, 11, SV("12345"), 2, 4, S("abcdefghij345")); + test(S("abcdefghijklmnopqrst"), 10, 11, SV("12345"), 4, 0, S("abcdefghij")); + test(S("abcdefghijklmnopqrst"), 10, 11, SV("12345"), 4, 1, S("abcdefghij5")); + test(S("abcdefghijklmnopqrst"), 10, 11, SV("12345"), 4, 2, S("abcdefghij5")); + test(S("abcdefghijklmnopqrst"), 10, 11, SV("12345"), 5, 0, S("abcdefghij")); + test(S("abcdefghijklmnopqrst"), 10, 11, SV("12345"), 5, 1, S("abcdefghij")); + test(S("abcdefghijklmnopqrst"), 10, 11, SV("12345"), 6, 0, S("can't happen")); + test(S("abcdefghijklmnopqrst"), 10, 11, SV("1234567890"), 0, 0, S("abcdefghij")); + test(S("abcdefghijklmnopqrst"), 10, 11, SV("1234567890"), 0, 1, S("abcdefghij1")); + test(S("abcdefghijklmnopqrst"), 10, 11, SV("1234567890"), 0, 5, S("abcdefghij12345")); + test(S("abcdefghijklmnopqrst"), 10, 11, SV("1234567890"), 0, 9, S("abcdefghij123456789")); + test(S("abcdefghijklmnopqrst"), 10, 11, SV("1234567890"), 0, 10, S("abcdefghij1234567890")); + test(S("abcdefghijklmnopqrst"), 10, 11, SV("1234567890"), 0, 11, S("abcdefghij1234567890")); + test(S("abcdefghijklmnopqrst"), 10, 11, SV("1234567890"), 1, 0, S("abcdefghij")); + test(S("abcdefghijklmnopqrst"), 10, 11, SV("1234567890"), 1, 1, S("abcdefghij2")); + test(S("abcdefghijklmnopqrst"), 10, 11, SV("1234567890"), 1, 4, S("abcdefghij2345")); + test(S("abcdefghijklmnopqrst"), 10, 11, SV("1234567890"), 1, 8, S("abcdefghij23456789")); + test(S("abcdefghijklmnopqrst"), 10, 11, SV("1234567890"), 1, 9, S("abcdefghij234567890")); + test(S("abcdefghijklmnopqrst"), 10, 11, SV("1234567890"), 1, 10, S("abcdefghij234567890")); + test(S("abcdefghijklmnopqrst"), 10, 11, SV("1234567890"), 5, 0, S("abcdefghij")); + test(S("abcdefghijklmnopqrst"), 10, 11, SV("1234567890"), 5, 1, S("abcdefghij6")); + test(S("abcdefghijklmnopqrst"), 10, 11, SV("1234567890"), 5, 2, S("abcdefghij67")); + test(S("abcdefghijklmnopqrst"), 10, 11, SV("1234567890"), 5, 4, S("abcdefghij6789")); +} + +template +void test50() +{ + test(S("abcdefghijklmnopqrst"), 10, 11, SV("1234567890"), 5, 5, S("abcdefghij67890")); + test(S("abcdefghijklmnopqrst"), 10, 11, SV("1234567890"), 5, 6, S("abcdefghij67890")); + test(S("abcdefghijklmnopqrst"), 10, 11, SV("1234567890"), 9, 0, S("abcdefghij")); + test(S("abcdefghijklmnopqrst"), 10, 11, SV("1234567890"), 9, 1, S("abcdefghij0")); + test(S("abcdefghijklmnopqrst"), 10, 11, SV("1234567890"), 9, 2, S("abcdefghij0")); + test(S("abcdefghijklmnopqrst"), 10, 11, SV("1234567890"), 10, 0, S("abcdefghij")); + test(S("abcdefghijklmnopqrst"), 10, 11, SV("1234567890"), 10, 1, S("abcdefghij")); + test(S("abcdefghijklmnopqrst"), 10, 11, SV("1234567890"), 11, 0, S("can't happen")); + test(S("abcdefghijklmnopqrst"), 10, 11, SV("12345678901234567890"), 0, 0, S("abcdefghij")); + test(S("abcdefghijklmnopqrst"), 10, 11, SV("12345678901234567890"), 0, 1, S("abcdefghij1")); + test(S("abcdefghijklmnopqrst"), 10, 11, SV("12345678901234567890"), 0, 10, S("abcdefghij1234567890")); + test(S("abcdefghijklmnopqrst"), 10, 11, SV("12345678901234567890"), 0, 19, S("abcdefghij1234567890123456789")); + test(S("abcdefghijklmnopqrst"), 10, 11, SV("12345678901234567890"), 0, 20, S("abcdefghij12345678901234567890")); + test(S("abcdefghijklmnopqrst"), 10, 11, SV("12345678901234567890"), 0, 21, S("abcdefghij12345678901234567890")); + test(S("abcdefghijklmnopqrst"), 10, 11, SV("12345678901234567890"), 1, 0, S("abcdefghij")); + test(S("abcdefghijklmnopqrst"), 10, 11, SV("12345678901234567890"), 1, 1, S("abcdefghij2")); + test(S("abcdefghijklmnopqrst"), 10, 11, SV("12345678901234567890"), 1, 9, S("abcdefghij234567890")); + test(S("abcdefghijklmnopqrst"), 10, 11, SV("12345678901234567890"), 1, 18, S("abcdefghij234567890123456789")); + test(S("abcdefghijklmnopqrst"), 10, 11, SV("12345678901234567890"), 1, 19, S("abcdefghij2345678901234567890")); + test(S("abcdefghijklmnopqrst"), 10, 11, SV("12345678901234567890"), 1, 20, S("abcdefghij2345678901234567890")); + test(S("abcdefghijklmnopqrst"), 10, 11, SV("12345678901234567890"), 10, 0, S("abcdefghij")); + test(S("abcdefghijklmnopqrst"), 10, 11, SV("12345678901234567890"), 10, 1, S("abcdefghij1")); + test(S("abcdefghijklmnopqrst"), 10, 11, SV("12345678901234567890"), 10, 5, S("abcdefghij12345")); + test(S("abcdefghijklmnopqrst"), 10, 11, SV("12345678901234567890"), 10, 9, S("abcdefghij123456789")); + test(S("abcdefghijklmnopqrst"), 10, 11, SV("12345678901234567890"), 10, 10, S("abcdefghij1234567890")); + test(S("abcdefghijklmnopqrst"), 10, 11, SV("12345678901234567890"), 10, 11, S("abcdefghij1234567890")); + test(S("abcdefghijklmnopqrst"), 10, 11, SV("12345678901234567890"), 19, 0, S("abcdefghij")); + test(S("abcdefghijklmnopqrst"), 10, 11, SV("12345678901234567890"), 19, 1, S("abcdefghij0")); + test(S("abcdefghijklmnopqrst"), 10, 11, SV("12345678901234567890"), 19, 2, S("abcdefghij0")); + test(S("abcdefghijklmnopqrst"), 10, 11, SV("12345678901234567890"), 20, 0, S("abcdefghij")); + test(S("abcdefghijklmnopqrst"), 10, 11, SV("12345678901234567890"), 20, 1, S("abcdefghij")); + test(S("abcdefghijklmnopqrst"), 10, 11, SV("12345678901234567890"), 21, 0, S("can't happen")); + test(S("abcdefghijklmnopqrst"), 19, 0, SV(""), 0, 0, S("abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 19, 0, SV(""), 0, 1, S("abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 19, 0, SV(""), 1, 0, S("can't happen")); + test(S("abcdefghijklmnopqrst"), 19, 0, SV("12345"), 0, 0, S("abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 19, 0, SV("12345"), 0, 1, S("abcdefghijklmnopqrs1t")); + test(S("abcdefghijklmnopqrst"), 19, 0, SV("12345"), 0, 2, S("abcdefghijklmnopqrs12t")); + test(S("abcdefghijklmnopqrst"), 19, 0, SV("12345"), 0, 4, S("abcdefghijklmnopqrs1234t")); + test(S("abcdefghijklmnopqrst"), 19, 0, SV("12345"), 0, 5, S("abcdefghijklmnopqrs12345t")); + test(S("abcdefghijklmnopqrst"), 19, 0, SV("12345"), 0, 6, S("abcdefghijklmnopqrs12345t")); + test(S("abcdefghijklmnopqrst"), 19, 0, SV("12345"), 1, 0, S("abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 19, 0, SV("12345"), 1, 1, S("abcdefghijklmnopqrs2t")); + test(S("abcdefghijklmnopqrst"), 19, 0, SV("12345"), 1, 2, S("abcdefghijklmnopqrs23t")); + test(S("abcdefghijklmnopqrst"), 19, 0, SV("12345"), 1, 3, S("abcdefghijklmnopqrs234t")); + test(S("abcdefghijklmnopqrst"), 19, 0, SV("12345"), 1, 4, S("abcdefghijklmnopqrs2345t")); + test(S("abcdefghijklmnopqrst"), 19, 0, SV("12345"), 1, 5, S("abcdefghijklmnopqrs2345t")); + test(S("abcdefghijklmnopqrst"), 19, 0, SV("12345"), 2, 0, S("abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 19, 0, SV("12345"), 2, 1, S("abcdefghijklmnopqrs3t")); + test(S("abcdefghijklmnopqrst"), 19, 0, SV("12345"), 2, 2, S("abcdefghijklmnopqrs34t")); + test(S("abcdefghijklmnopqrst"), 19, 0, SV("12345"), 2, 3, S("abcdefghijklmnopqrs345t")); + test(S("abcdefghijklmnopqrst"), 19, 0, SV("12345"), 2, 4, S("abcdefghijklmnopqrs345t")); + test(S("abcdefghijklmnopqrst"), 19, 0, SV("12345"), 4, 0, S("abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 19, 0, SV("12345"), 4, 1, S("abcdefghijklmnopqrs5t")); + test(S("abcdefghijklmnopqrst"), 19, 0, SV("12345"), 4, 2, S("abcdefghijklmnopqrs5t")); + test(S("abcdefghijklmnopqrst"), 19, 0, SV("12345"), 5, 0, S("abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 19, 0, SV("12345"), 5, 1, S("abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 19, 0, SV("12345"), 6, 0, S("can't happen")); + test(S("abcdefghijklmnopqrst"), 19, 0, SV("1234567890"), 0, 0, S("abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 19, 0, SV("1234567890"), 0, 1, S("abcdefghijklmnopqrs1t")); + test(S("abcdefghijklmnopqrst"), 19, 0, SV("1234567890"), 0, 5, S("abcdefghijklmnopqrs12345t")); + test(S("abcdefghijklmnopqrst"), 19, 0, SV("1234567890"), 0, 9, S("abcdefghijklmnopqrs123456789t")); + test(S("abcdefghijklmnopqrst"), 19, 0, SV("1234567890"), 0, 10, S("abcdefghijklmnopqrs1234567890t")); + test(S("abcdefghijklmnopqrst"), 19, 0, SV("1234567890"), 0, 11, S("abcdefghijklmnopqrs1234567890t")); + test(S("abcdefghijklmnopqrst"), 19, 0, SV("1234567890"), 1, 0, S("abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 19, 0, SV("1234567890"), 1, 1, S("abcdefghijklmnopqrs2t")); + test(S("abcdefghijklmnopqrst"), 19, 0, SV("1234567890"), 1, 4, S("abcdefghijklmnopqrs2345t")); + test(S("abcdefghijklmnopqrst"), 19, 0, SV("1234567890"), 1, 8, S("abcdefghijklmnopqrs23456789t")); + test(S("abcdefghijklmnopqrst"), 19, 0, SV("1234567890"), 1, 9, S("abcdefghijklmnopqrs234567890t")); + test(S("abcdefghijklmnopqrst"), 19, 0, SV("1234567890"), 1, 10, S("abcdefghijklmnopqrs234567890t")); + test(S("abcdefghijklmnopqrst"), 19, 0, SV("1234567890"), 5, 0, S("abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 19, 0, SV("1234567890"), 5, 1, S("abcdefghijklmnopqrs6t")); + test(S("abcdefghijklmnopqrst"), 19, 0, SV("1234567890"), 5, 2, S("abcdefghijklmnopqrs67t")); + test(S("abcdefghijklmnopqrst"), 19, 0, SV("1234567890"), 5, 4, S("abcdefghijklmnopqrs6789t")); + test(S("abcdefghijklmnopqrst"), 19, 0, SV("1234567890"), 5, 5, S("abcdefghijklmnopqrs67890t")); + test(S("abcdefghijklmnopqrst"), 19, 0, SV("1234567890"), 5, 6, S("abcdefghijklmnopqrs67890t")); + test(S("abcdefghijklmnopqrst"), 19, 0, SV("1234567890"), 9, 0, S("abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 19, 0, SV("1234567890"), 9, 1, S("abcdefghijklmnopqrs0t")); + test(S("abcdefghijklmnopqrst"), 19, 0, SV("1234567890"), 9, 2, S("abcdefghijklmnopqrs0t")); + test(S("abcdefghijklmnopqrst"), 19, 0, SV("1234567890"), 10, 0, S("abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 19, 0, SV("1234567890"), 10, 1, S("abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 19, 0, SV("1234567890"), 11, 0, S("can't happen")); + test(S("abcdefghijklmnopqrst"), 19, 0, SV("12345678901234567890"), 0, 0, S("abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 19, 0, SV("12345678901234567890"), 0, 1, S("abcdefghijklmnopqrs1t")); + test(S("abcdefghijklmnopqrst"), 19, 0, SV("12345678901234567890"), 0, 10, S("abcdefghijklmnopqrs1234567890t")); + test(S("abcdefghijklmnopqrst"), 19, 0, SV("12345678901234567890"), 0, 19, S("abcdefghijklmnopqrs1234567890123456789t")); + test(S("abcdefghijklmnopqrst"), 19, 0, SV("12345678901234567890"), 0, 20, S("abcdefghijklmnopqrs12345678901234567890t")); + test(S("abcdefghijklmnopqrst"), 19, 0, SV("12345678901234567890"), 0, 21, S("abcdefghijklmnopqrs12345678901234567890t")); + test(S("abcdefghijklmnopqrst"), 19, 0, SV("12345678901234567890"), 1, 0, S("abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 19, 0, SV("12345678901234567890"), 1, 1, S("abcdefghijklmnopqrs2t")); + test(S("abcdefghijklmnopqrst"), 19, 0, SV("12345678901234567890"), 1, 9, S("abcdefghijklmnopqrs234567890t")); + test(S("abcdefghijklmnopqrst"), 19, 0, SV("12345678901234567890"), 1, 18, S("abcdefghijklmnopqrs234567890123456789t")); + test(S("abcdefghijklmnopqrst"), 19, 0, SV("12345678901234567890"), 1, 19, S("abcdefghijklmnopqrs2345678901234567890t")); + test(S("abcdefghijklmnopqrst"), 19, 0, SV("12345678901234567890"), 1, 20, S("abcdefghijklmnopqrs2345678901234567890t")); + test(S("abcdefghijklmnopqrst"), 19, 0, SV("12345678901234567890"), 10, 0, S("abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 19, 0, SV("12345678901234567890"), 10, 1, S("abcdefghijklmnopqrs1t")); + test(S("abcdefghijklmnopqrst"), 19, 0, SV("12345678901234567890"), 10, 5, S("abcdefghijklmnopqrs12345t")); + test(S("abcdefghijklmnopqrst"), 19, 0, SV("12345678901234567890"), 10, 9, S("abcdefghijklmnopqrs123456789t")); + test(S("abcdefghijklmnopqrst"), 19, 0, SV("12345678901234567890"), 10, 10, S("abcdefghijklmnopqrs1234567890t")); + test(S("abcdefghijklmnopqrst"), 19, 0, SV("12345678901234567890"), 10, 11, S("abcdefghijklmnopqrs1234567890t")); +} + +template +void test51() +{ + test(S("abcdefghijklmnopqrst"), 19, 0, SV("12345678901234567890"), 19, 0, S("abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 19, 0, SV("12345678901234567890"), 19, 1, S("abcdefghijklmnopqrs0t")); + test(S("abcdefghijklmnopqrst"), 19, 0, SV("12345678901234567890"), 19, 2, S("abcdefghijklmnopqrs0t")); + test(S("abcdefghijklmnopqrst"), 19, 0, SV("12345678901234567890"), 20, 0, S("abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 19, 0, SV("12345678901234567890"), 20, 1, S("abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 19, 0, SV("12345678901234567890"), 21, 0, S("can't happen")); + test(S("abcdefghijklmnopqrst"), 19, 1, SV(""), 0, 0, S("abcdefghijklmnopqrs")); + test(S("abcdefghijklmnopqrst"), 19, 1, SV(""), 0, 1, S("abcdefghijklmnopqrs")); + test(S("abcdefghijklmnopqrst"), 19, 1, SV(""), 1, 0, S("can't happen")); + test(S("abcdefghijklmnopqrst"), 19, 1, SV("12345"), 0, 0, S("abcdefghijklmnopqrs")); + test(S("abcdefghijklmnopqrst"), 19, 1, SV("12345"), 0, 1, S("abcdefghijklmnopqrs1")); + test(S("abcdefghijklmnopqrst"), 19, 1, SV("12345"), 0, 2, S("abcdefghijklmnopqrs12")); + test(S("abcdefghijklmnopqrst"), 19, 1, SV("12345"), 0, 4, S("abcdefghijklmnopqrs1234")); + test(S("abcdefghijklmnopqrst"), 19, 1, SV("12345"), 0, 5, S("abcdefghijklmnopqrs12345")); + test(S("abcdefghijklmnopqrst"), 19, 1, SV("12345"), 0, 6, S("abcdefghijklmnopqrs12345")); + test(S("abcdefghijklmnopqrst"), 19, 1, SV("12345"), 1, 0, S("abcdefghijklmnopqrs")); + test(S("abcdefghijklmnopqrst"), 19, 1, SV("12345"), 1, 1, S("abcdefghijklmnopqrs2")); + test(S("abcdefghijklmnopqrst"), 19, 1, SV("12345"), 1, 2, S("abcdefghijklmnopqrs23")); + test(S("abcdefghijklmnopqrst"), 19, 1, SV("12345"), 1, 3, S("abcdefghijklmnopqrs234")); + test(S("abcdefghijklmnopqrst"), 19, 1, SV("12345"), 1, 4, S("abcdefghijklmnopqrs2345")); + test(S("abcdefghijklmnopqrst"), 19, 1, SV("12345"), 1, 5, S("abcdefghijklmnopqrs2345")); + test(S("abcdefghijklmnopqrst"), 19, 1, SV("12345"), 2, 0, S("abcdefghijklmnopqrs")); + test(S("abcdefghijklmnopqrst"), 19, 1, SV("12345"), 2, 1, S("abcdefghijklmnopqrs3")); + test(S("abcdefghijklmnopqrst"), 19, 1, SV("12345"), 2, 2, S("abcdefghijklmnopqrs34")); + test(S("abcdefghijklmnopqrst"), 19, 1, SV("12345"), 2, 3, S("abcdefghijklmnopqrs345")); + test(S("abcdefghijklmnopqrst"), 19, 1, SV("12345"), 2, 4, S("abcdefghijklmnopqrs345")); + test(S("abcdefghijklmnopqrst"), 19, 1, SV("12345"), 4, 0, S("abcdefghijklmnopqrs")); + test(S("abcdefghijklmnopqrst"), 19, 1, SV("12345"), 4, 1, S("abcdefghijklmnopqrs5")); + test(S("abcdefghijklmnopqrst"), 19, 1, SV("12345"), 4, 2, S("abcdefghijklmnopqrs5")); + test(S("abcdefghijklmnopqrst"), 19, 1, SV("12345"), 5, 0, S("abcdefghijklmnopqrs")); + test(S("abcdefghijklmnopqrst"), 19, 1, SV("12345"), 5, 1, S("abcdefghijklmnopqrs")); + test(S("abcdefghijklmnopqrst"), 19, 1, SV("12345"), 6, 0, S("can't happen")); + test(S("abcdefghijklmnopqrst"), 19, 1, SV("1234567890"), 0, 0, S("abcdefghijklmnopqrs")); + test(S("abcdefghijklmnopqrst"), 19, 1, SV("1234567890"), 0, 1, S("abcdefghijklmnopqrs1")); + test(S("abcdefghijklmnopqrst"), 19, 1, SV("1234567890"), 0, 5, S("abcdefghijklmnopqrs12345")); + test(S("abcdefghijklmnopqrst"), 19, 1, SV("1234567890"), 0, 9, S("abcdefghijklmnopqrs123456789")); + test(S("abcdefghijklmnopqrst"), 19, 1, SV("1234567890"), 0, 10, S("abcdefghijklmnopqrs1234567890")); + test(S("abcdefghijklmnopqrst"), 19, 1, SV("1234567890"), 0, 11, S("abcdefghijklmnopqrs1234567890")); + test(S("abcdefghijklmnopqrst"), 19, 1, SV("1234567890"), 1, 0, S("abcdefghijklmnopqrs")); + test(S("abcdefghijklmnopqrst"), 19, 1, SV("1234567890"), 1, 1, S("abcdefghijklmnopqrs2")); + test(S("abcdefghijklmnopqrst"), 19, 1, SV("1234567890"), 1, 4, S("abcdefghijklmnopqrs2345")); + test(S("abcdefghijklmnopqrst"), 19, 1, SV("1234567890"), 1, 8, S("abcdefghijklmnopqrs23456789")); + test(S("abcdefghijklmnopqrst"), 19, 1, SV("1234567890"), 1, 9, S("abcdefghijklmnopqrs234567890")); + test(S("abcdefghijklmnopqrst"), 19, 1, SV("1234567890"), 1, 10, S("abcdefghijklmnopqrs234567890")); + test(S("abcdefghijklmnopqrst"), 19, 1, SV("1234567890"), 5, 0, S("abcdefghijklmnopqrs")); + test(S("abcdefghijklmnopqrst"), 19, 1, SV("1234567890"), 5, 1, S("abcdefghijklmnopqrs6")); + test(S("abcdefghijklmnopqrst"), 19, 1, SV("1234567890"), 5, 2, S("abcdefghijklmnopqrs67")); + test(S("abcdefghijklmnopqrst"), 19, 1, SV("1234567890"), 5, 4, S("abcdefghijklmnopqrs6789")); + test(S("abcdefghijklmnopqrst"), 19, 1, SV("1234567890"), 5, 5, S("abcdefghijklmnopqrs67890")); + test(S("abcdefghijklmnopqrst"), 19, 1, SV("1234567890"), 5, 6, S("abcdefghijklmnopqrs67890")); + test(S("abcdefghijklmnopqrst"), 19, 1, SV("1234567890"), 9, 0, S("abcdefghijklmnopqrs")); + test(S("abcdefghijklmnopqrst"), 19, 1, SV("1234567890"), 9, 1, S("abcdefghijklmnopqrs0")); + test(S("abcdefghijklmnopqrst"), 19, 1, SV("1234567890"), 9, 2, S("abcdefghijklmnopqrs0")); + test(S("abcdefghijklmnopqrst"), 19, 1, SV("1234567890"), 10, 0, S("abcdefghijklmnopqrs")); + test(S("abcdefghijklmnopqrst"), 19, 1, SV("1234567890"), 10, 1, S("abcdefghijklmnopqrs")); + test(S("abcdefghijklmnopqrst"), 19, 1, SV("1234567890"), 11, 0, S("can't happen")); + test(S("abcdefghijklmnopqrst"), 19, 1, SV("12345678901234567890"), 0, 0, S("abcdefghijklmnopqrs")); + test(S("abcdefghijklmnopqrst"), 19, 1, SV("12345678901234567890"), 0, 1, S("abcdefghijklmnopqrs1")); + test(S("abcdefghijklmnopqrst"), 19, 1, SV("12345678901234567890"), 0, 10, S("abcdefghijklmnopqrs1234567890")); + test(S("abcdefghijklmnopqrst"), 19, 1, SV("12345678901234567890"), 0, 19, S("abcdefghijklmnopqrs1234567890123456789")); + test(S("abcdefghijklmnopqrst"), 19, 1, SV("12345678901234567890"), 0, 20, S("abcdefghijklmnopqrs12345678901234567890")); + test(S("abcdefghijklmnopqrst"), 19, 1, SV("12345678901234567890"), 0, 21, S("abcdefghijklmnopqrs12345678901234567890")); + test(S("abcdefghijklmnopqrst"), 19, 1, SV("12345678901234567890"), 1, 0, S("abcdefghijklmnopqrs")); + test(S("abcdefghijklmnopqrst"), 19, 1, SV("12345678901234567890"), 1, 1, S("abcdefghijklmnopqrs2")); + test(S("abcdefghijklmnopqrst"), 19, 1, SV("12345678901234567890"), 1, 9, S("abcdefghijklmnopqrs234567890")); + test(S("abcdefghijklmnopqrst"), 19, 1, SV("12345678901234567890"), 1, 18, S("abcdefghijklmnopqrs234567890123456789")); + test(S("abcdefghijklmnopqrst"), 19, 1, SV("12345678901234567890"), 1, 19, S("abcdefghijklmnopqrs2345678901234567890")); + test(S("abcdefghijklmnopqrst"), 19, 1, SV("12345678901234567890"), 1, 20, S("abcdefghijklmnopqrs2345678901234567890")); + test(S("abcdefghijklmnopqrst"), 19, 1, SV("12345678901234567890"), 10, 0, S("abcdefghijklmnopqrs")); + test(S("abcdefghijklmnopqrst"), 19, 1, SV("12345678901234567890"), 10, 1, S("abcdefghijklmnopqrs1")); + test(S("abcdefghijklmnopqrst"), 19, 1, SV("12345678901234567890"), 10, 5, S("abcdefghijklmnopqrs12345")); + test(S("abcdefghijklmnopqrst"), 19, 1, SV("12345678901234567890"), 10, 9, S("abcdefghijklmnopqrs123456789")); + test(S("abcdefghijklmnopqrst"), 19, 1, SV("12345678901234567890"), 10, 10, S("abcdefghijklmnopqrs1234567890")); + test(S("abcdefghijklmnopqrst"), 19, 1, SV("12345678901234567890"), 10, 11, S("abcdefghijklmnopqrs1234567890")); + test(S("abcdefghijklmnopqrst"), 19, 1, SV("12345678901234567890"), 19, 0, S("abcdefghijklmnopqrs")); + test(S("abcdefghijklmnopqrst"), 19, 1, SV("12345678901234567890"), 19, 1, S("abcdefghijklmnopqrs0")); + test(S("abcdefghijklmnopqrst"), 19, 1, SV("12345678901234567890"), 19, 2, S("abcdefghijklmnopqrs0")); + test(S("abcdefghijklmnopqrst"), 19, 1, SV("12345678901234567890"), 20, 0, S("abcdefghijklmnopqrs")); + test(S("abcdefghijklmnopqrst"), 19, 1, SV("12345678901234567890"), 20, 1, S("abcdefghijklmnopqrs")); + test(S("abcdefghijklmnopqrst"), 19, 1, SV("12345678901234567890"), 21, 0, S("can't happen")); + test(S("abcdefghijklmnopqrst"), 19, 2, SV(""), 0, 0, S("abcdefghijklmnopqrs")); + test(S("abcdefghijklmnopqrst"), 19, 2, SV(""), 0, 1, S("abcdefghijklmnopqrs")); + test(S("abcdefghijklmnopqrst"), 19, 2, SV(""), 1, 0, S("can't happen")); + test(S("abcdefghijklmnopqrst"), 19, 2, SV("12345"), 0, 0, S("abcdefghijklmnopqrs")); + test(S("abcdefghijklmnopqrst"), 19, 2, SV("12345"), 0, 1, S("abcdefghijklmnopqrs1")); + test(S("abcdefghijklmnopqrst"), 19, 2, SV("12345"), 0, 2, S("abcdefghijklmnopqrs12")); + test(S("abcdefghijklmnopqrst"), 19, 2, SV("12345"), 0, 4, S("abcdefghijklmnopqrs1234")); + test(S("abcdefghijklmnopqrst"), 19, 2, SV("12345"), 0, 5, S("abcdefghijklmnopqrs12345")); + test(S("abcdefghijklmnopqrst"), 19, 2, SV("12345"), 0, 6, S("abcdefghijklmnopqrs12345")); + test(S("abcdefghijklmnopqrst"), 19, 2, SV("12345"), 1, 0, S("abcdefghijklmnopqrs")); + test(S("abcdefghijklmnopqrst"), 19, 2, SV("12345"), 1, 1, S("abcdefghijklmnopqrs2")); + test(S("abcdefghijklmnopqrst"), 19, 2, SV("12345"), 1, 2, S("abcdefghijklmnopqrs23")); + test(S("abcdefghijklmnopqrst"), 19, 2, SV("12345"), 1, 3, S("abcdefghijklmnopqrs234")); + test(S("abcdefghijklmnopqrst"), 19, 2, SV("12345"), 1, 4, S("abcdefghijklmnopqrs2345")); + test(S("abcdefghijklmnopqrst"), 19, 2, SV("12345"), 1, 5, S("abcdefghijklmnopqrs2345")); + test(S("abcdefghijklmnopqrst"), 19, 2, SV("12345"), 2, 0, S("abcdefghijklmnopqrs")); + test(S("abcdefghijklmnopqrst"), 19, 2, SV("12345"), 2, 1, S("abcdefghijklmnopqrs3")); + test(S("abcdefghijklmnopqrst"), 19, 2, SV("12345"), 2, 2, S("abcdefghijklmnopqrs34")); + test(S("abcdefghijklmnopqrst"), 19, 2, SV("12345"), 2, 3, S("abcdefghijklmnopqrs345")); + test(S("abcdefghijklmnopqrst"), 19, 2, SV("12345"), 2, 4, S("abcdefghijklmnopqrs345")); +} + +template +void test52() +{ + test(S("abcdefghijklmnopqrst"), 19, 2, SV("12345"), 4, 0, S("abcdefghijklmnopqrs")); + test(S("abcdefghijklmnopqrst"), 19, 2, SV("12345"), 4, 1, S("abcdefghijklmnopqrs5")); + test(S("abcdefghijklmnopqrst"), 19, 2, SV("12345"), 4, 2, S("abcdefghijklmnopqrs5")); + test(S("abcdefghijklmnopqrst"), 19, 2, SV("12345"), 5, 0, S("abcdefghijklmnopqrs")); + test(S("abcdefghijklmnopqrst"), 19, 2, SV("12345"), 5, 1, S("abcdefghijklmnopqrs")); + test(S("abcdefghijklmnopqrst"), 19, 2, SV("12345"), 6, 0, S("can't happen")); + test(S("abcdefghijklmnopqrst"), 19, 2, SV("1234567890"), 0, 0, S("abcdefghijklmnopqrs")); + test(S("abcdefghijklmnopqrst"), 19, 2, SV("1234567890"), 0, 1, S("abcdefghijklmnopqrs1")); + test(S("abcdefghijklmnopqrst"), 19, 2, SV("1234567890"), 0, 5, S("abcdefghijklmnopqrs12345")); + test(S("abcdefghijklmnopqrst"), 19, 2, SV("1234567890"), 0, 9, S("abcdefghijklmnopqrs123456789")); + test(S("abcdefghijklmnopqrst"), 19, 2, SV("1234567890"), 0, 10, S("abcdefghijklmnopqrs1234567890")); + test(S("abcdefghijklmnopqrst"), 19, 2, SV("1234567890"), 0, 11, S("abcdefghijklmnopqrs1234567890")); + test(S("abcdefghijklmnopqrst"), 19, 2, SV("1234567890"), 1, 0, S("abcdefghijklmnopqrs")); + test(S("abcdefghijklmnopqrst"), 19, 2, SV("1234567890"), 1, 1, S("abcdefghijklmnopqrs2")); + test(S("abcdefghijklmnopqrst"), 19, 2, SV("1234567890"), 1, 4, S("abcdefghijklmnopqrs2345")); + test(S("abcdefghijklmnopqrst"), 19, 2, SV("1234567890"), 1, 8, S("abcdefghijklmnopqrs23456789")); + test(S("abcdefghijklmnopqrst"), 19, 2, SV("1234567890"), 1, 9, S("abcdefghijklmnopqrs234567890")); + test(S("abcdefghijklmnopqrst"), 19, 2, SV("1234567890"), 1, 10, S("abcdefghijklmnopqrs234567890")); + test(S("abcdefghijklmnopqrst"), 19, 2, SV("1234567890"), 5, 0, S("abcdefghijklmnopqrs")); + test(S("abcdefghijklmnopqrst"), 19, 2, SV("1234567890"), 5, 1, S("abcdefghijklmnopqrs6")); + test(S("abcdefghijklmnopqrst"), 19, 2, SV("1234567890"), 5, 2, S("abcdefghijklmnopqrs67")); + test(S("abcdefghijklmnopqrst"), 19, 2, SV("1234567890"), 5, 4, S("abcdefghijklmnopqrs6789")); + test(S("abcdefghijklmnopqrst"), 19, 2, SV("1234567890"), 5, 5, S("abcdefghijklmnopqrs67890")); + test(S("abcdefghijklmnopqrst"), 19, 2, SV("1234567890"), 5, 6, S("abcdefghijklmnopqrs67890")); + test(S("abcdefghijklmnopqrst"), 19, 2, SV("1234567890"), 9, 0, S("abcdefghijklmnopqrs")); + test(S("abcdefghijklmnopqrst"), 19, 2, SV("1234567890"), 9, 1, S("abcdefghijklmnopqrs0")); + test(S("abcdefghijklmnopqrst"), 19, 2, SV("1234567890"), 9, 2, S("abcdefghijklmnopqrs0")); + test(S("abcdefghijklmnopqrst"), 19, 2, SV("1234567890"), 10, 0, S("abcdefghijklmnopqrs")); + test(S("abcdefghijklmnopqrst"), 19, 2, SV("1234567890"), 10, 1, S("abcdefghijklmnopqrs")); + test(S("abcdefghijklmnopqrst"), 19, 2, SV("1234567890"), 11, 0, S("can't happen")); + test(S("abcdefghijklmnopqrst"), 19, 2, SV("12345678901234567890"), 0, 0, S("abcdefghijklmnopqrs")); + test(S("abcdefghijklmnopqrst"), 19, 2, SV("12345678901234567890"), 0, 1, S("abcdefghijklmnopqrs1")); + test(S("abcdefghijklmnopqrst"), 19, 2, SV("12345678901234567890"), 0, 10, S("abcdefghijklmnopqrs1234567890")); + test(S("abcdefghijklmnopqrst"), 19, 2, SV("12345678901234567890"), 0, 19, S("abcdefghijklmnopqrs1234567890123456789")); + test(S("abcdefghijklmnopqrst"), 19, 2, SV("12345678901234567890"), 0, 20, S("abcdefghijklmnopqrs12345678901234567890")); + test(S("abcdefghijklmnopqrst"), 19, 2, SV("12345678901234567890"), 0, 21, S("abcdefghijklmnopqrs12345678901234567890")); + test(S("abcdefghijklmnopqrst"), 19, 2, SV("12345678901234567890"), 1, 0, S("abcdefghijklmnopqrs")); + test(S("abcdefghijklmnopqrst"), 19, 2, SV("12345678901234567890"), 1, 1, S("abcdefghijklmnopqrs2")); + test(S("abcdefghijklmnopqrst"), 19, 2, SV("12345678901234567890"), 1, 9, S("abcdefghijklmnopqrs234567890")); + test(S("abcdefghijklmnopqrst"), 19, 2, SV("12345678901234567890"), 1, 18, S("abcdefghijklmnopqrs234567890123456789")); + test(S("abcdefghijklmnopqrst"), 19, 2, SV("12345678901234567890"), 1, 19, S("abcdefghijklmnopqrs2345678901234567890")); + test(S("abcdefghijklmnopqrst"), 19, 2, SV("12345678901234567890"), 1, 20, S("abcdefghijklmnopqrs2345678901234567890")); + test(S("abcdefghijklmnopqrst"), 19, 2, SV("12345678901234567890"), 10, 0, S("abcdefghijklmnopqrs")); + test(S("abcdefghijklmnopqrst"), 19, 2, SV("12345678901234567890"), 10, 1, S("abcdefghijklmnopqrs1")); + test(S("abcdefghijklmnopqrst"), 19, 2, SV("12345678901234567890"), 10, 5, S("abcdefghijklmnopqrs12345")); + test(S("abcdefghijklmnopqrst"), 19, 2, SV("12345678901234567890"), 10, 9, S("abcdefghijklmnopqrs123456789")); + test(S("abcdefghijklmnopqrst"), 19, 2, SV("12345678901234567890"), 10, 10, S("abcdefghijklmnopqrs1234567890")); + test(S("abcdefghijklmnopqrst"), 19, 2, SV("12345678901234567890"), 10, 11, S("abcdefghijklmnopqrs1234567890")); + test(S("abcdefghijklmnopqrst"), 19, 2, SV("12345678901234567890"), 19, 0, S("abcdefghijklmnopqrs")); + test(S("abcdefghijklmnopqrst"), 19, 2, SV("12345678901234567890"), 19, 1, S("abcdefghijklmnopqrs0")); + test(S("abcdefghijklmnopqrst"), 19, 2, SV("12345678901234567890"), 19, 2, S("abcdefghijklmnopqrs0")); + test(S("abcdefghijklmnopqrst"), 19, 2, SV("12345678901234567890"), 20, 0, S("abcdefghijklmnopqrs")); + test(S("abcdefghijklmnopqrst"), 19, 2, SV("12345678901234567890"), 20, 1, S("abcdefghijklmnopqrs")); + test(S("abcdefghijklmnopqrst"), 19, 2, SV("12345678901234567890"), 21, 0, S("can't happen")); + test(S("abcdefghijklmnopqrst"), 20, 0, SV(""), 0, 0, S("abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 20, 0, SV(""), 0, 1, S("abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 20, 0, SV(""), 1, 0, S("can't happen")); + test(S("abcdefghijklmnopqrst"), 20, 0, SV("12345"), 0, 0, S("abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 20, 0, SV("12345"), 0, 1, S("abcdefghijklmnopqrst1")); + test(S("abcdefghijklmnopqrst"), 20, 0, SV("12345"), 0, 2, S("abcdefghijklmnopqrst12")); + test(S("abcdefghijklmnopqrst"), 20, 0, SV("12345"), 0, 4, S("abcdefghijklmnopqrst1234")); + test(S("abcdefghijklmnopqrst"), 20, 0, SV("12345"), 0, 5, S("abcdefghijklmnopqrst12345")); + test(S("abcdefghijklmnopqrst"), 20, 0, SV("12345"), 0, 6, S("abcdefghijklmnopqrst12345")); + test(S("abcdefghijklmnopqrst"), 20, 0, SV("12345"), 1, 0, S("abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 20, 0, SV("12345"), 1, 1, S("abcdefghijklmnopqrst2")); + test(S("abcdefghijklmnopqrst"), 20, 0, SV("12345"), 1, 2, S("abcdefghijklmnopqrst23")); + test(S("abcdefghijklmnopqrst"), 20, 0, SV("12345"), 1, 3, S("abcdefghijklmnopqrst234")); + test(S("abcdefghijklmnopqrst"), 20, 0, SV("12345"), 1, 4, S("abcdefghijklmnopqrst2345")); + test(S("abcdefghijklmnopqrst"), 20, 0, SV("12345"), 1, 5, S("abcdefghijklmnopqrst2345")); + test(S("abcdefghijklmnopqrst"), 20, 0, SV("12345"), 2, 0, S("abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 20, 0, SV("12345"), 2, 1, S("abcdefghijklmnopqrst3")); + test(S("abcdefghijklmnopqrst"), 20, 0, SV("12345"), 2, 2, S("abcdefghijklmnopqrst34")); + test(S("abcdefghijklmnopqrst"), 20, 0, SV("12345"), 2, 3, S("abcdefghijklmnopqrst345")); + test(S("abcdefghijklmnopqrst"), 20, 0, SV("12345"), 2, 4, S("abcdefghijklmnopqrst345")); + test(S("abcdefghijklmnopqrst"), 20, 0, SV("12345"), 4, 0, S("abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 20, 0, SV("12345"), 4, 1, S("abcdefghijklmnopqrst5")); + test(S("abcdefghijklmnopqrst"), 20, 0, SV("12345"), 4, 2, S("abcdefghijklmnopqrst5")); + test(S("abcdefghijklmnopqrst"), 20, 0, SV("12345"), 5, 0, S("abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 20, 0, SV("12345"), 5, 1, S("abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 20, 0, SV("12345"), 6, 0, S("can't happen")); + test(S("abcdefghijklmnopqrst"), 20, 0, SV("1234567890"), 0, 0, S("abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 20, 0, SV("1234567890"), 0, 1, S("abcdefghijklmnopqrst1")); + test(S("abcdefghijklmnopqrst"), 20, 0, SV("1234567890"), 0, 5, S("abcdefghijklmnopqrst12345")); + test(S("abcdefghijklmnopqrst"), 20, 0, SV("1234567890"), 0, 9, S("abcdefghijklmnopqrst123456789")); + test(S("abcdefghijklmnopqrst"), 20, 0, SV("1234567890"), 0, 10, S("abcdefghijklmnopqrst1234567890")); + test(S("abcdefghijklmnopqrst"), 20, 0, SV("1234567890"), 0, 11, S("abcdefghijklmnopqrst1234567890")); + test(S("abcdefghijklmnopqrst"), 20, 0, SV("1234567890"), 1, 0, S("abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 20, 0, SV("1234567890"), 1, 1, S("abcdefghijklmnopqrst2")); + test(S("abcdefghijklmnopqrst"), 20, 0, SV("1234567890"), 1, 4, S("abcdefghijklmnopqrst2345")); + test(S("abcdefghijklmnopqrst"), 20, 0, SV("1234567890"), 1, 8, S("abcdefghijklmnopqrst23456789")); + test(S("abcdefghijklmnopqrst"), 20, 0, SV("1234567890"), 1, 9, S("abcdefghijklmnopqrst234567890")); + test(S("abcdefghijklmnopqrst"), 20, 0, SV("1234567890"), 1, 10, S("abcdefghijklmnopqrst234567890")); + test(S("abcdefghijklmnopqrst"), 20, 0, SV("1234567890"), 5, 0, S("abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 20, 0, SV("1234567890"), 5, 1, S("abcdefghijklmnopqrst6")); + test(S("abcdefghijklmnopqrst"), 20, 0, SV("1234567890"), 5, 2, S("abcdefghijklmnopqrst67")); + test(S("abcdefghijklmnopqrst"), 20, 0, SV("1234567890"), 5, 4, S("abcdefghijklmnopqrst6789")); + test(S("abcdefghijklmnopqrst"), 20, 0, SV("1234567890"), 5, 5, S("abcdefghijklmnopqrst67890")); + test(S("abcdefghijklmnopqrst"), 20, 0, SV("1234567890"), 5, 6, S("abcdefghijklmnopqrst67890")); + test(S("abcdefghijklmnopqrst"), 20, 0, SV("1234567890"), 9, 0, S("abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 20, 0, SV("1234567890"), 9, 1, S("abcdefghijklmnopqrst0")); +} + +template +void test53() +{ + test(S("abcdefghijklmnopqrst"), 20, 0, SV("1234567890"), 9, 2, S("abcdefghijklmnopqrst0")); + test(S("abcdefghijklmnopqrst"), 20, 0, SV("1234567890"), 10, 0, S("abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 20, 0, SV("1234567890"), 10, 1, S("abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 20, 0, SV("1234567890"), 11, 0, S("can't happen")); + test(S("abcdefghijklmnopqrst"), 20, 0, SV("12345678901234567890"), 0, 0, S("abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 20, 0, SV("12345678901234567890"), 0, 1, S("abcdefghijklmnopqrst1")); + test(S("abcdefghijklmnopqrst"), 20, 0, SV("12345678901234567890"), 0, 10, S("abcdefghijklmnopqrst1234567890")); + test(S("abcdefghijklmnopqrst"), 20, 0, SV("12345678901234567890"), 0, 19, S("abcdefghijklmnopqrst1234567890123456789")); + test(S("abcdefghijklmnopqrst"), 20, 0, SV("12345678901234567890"), 0, 20, S("abcdefghijklmnopqrst12345678901234567890")); + test(S("abcdefghijklmnopqrst"), 20, 0, SV("12345678901234567890"), 0, 21, S("abcdefghijklmnopqrst12345678901234567890")); + test(S("abcdefghijklmnopqrst"), 20, 0, SV("12345678901234567890"), 1, 0, S("abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 20, 0, SV("12345678901234567890"), 1, 1, S("abcdefghijklmnopqrst2")); + test(S("abcdefghijklmnopqrst"), 20, 0, SV("12345678901234567890"), 1, 9, S("abcdefghijklmnopqrst234567890")); + test(S("abcdefghijklmnopqrst"), 20, 0, SV("12345678901234567890"), 1, 18, S("abcdefghijklmnopqrst234567890123456789")); + test(S("abcdefghijklmnopqrst"), 20, 0, SV("12345678901234567890"), 1, 19, S("abcdefghijklmnopqrst2345678901234567890")); + test(S("abcdefghijklmnopqrst"), 20, 0, SV("12345678901234567890"), 1, 20, S("abcdefghijklmnopqrst2345678901234567890")); + test(S("abcdefghijklmnopqrst"), 20, 0, SV("12345678901234567890"), 10, 0, S("abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 20, 0, SV("12345678901234567890"), 10, 1, S("abcdefghijklmnopqrst1")); + test(S("abcdefghijklmnopqrst"), 20, 0, SV("12345678901234567890"), 10, 5, S("abcdefghijklmnopqrst12345")); + test(S("abcdefghijklmnopqrst"), 20, 0, SV("12345678901234567890"), 10, 9, S("abcdefghijklmnopqrst123456789")); + test(S("abcdefghijklmnopqrst"), 20, 0, SV("12345678901234567890"), 10, 10, S("abcdefghijklmnopqrst1234567890")); + test(S("abcdefghijklmnopqrst"), 20, 0, SV("12345678901234567890"), 10, 11, S("abcdefghijklmnopqrst1234567890")); + test(S("abcdefghijklmnopqrst"), 20, 0, SV("12345678901234567890"), 19, 0, S("abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 20, 0, SV("12345678901234567890"), 19, 1, S("abcdefghijklmnopqrst0")); + test(S("abcdefghijklmnopqrst"), 20, 0, SV("12345678901234567890"), 19, 2, S("abcdefghijklmnopqrst0")); + test(S("abcdefghijklmnopqrst"), 20, 0, SV("12345678901234567890"), 20, 0, S("abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 20, 0, SV("12345678901234567890"), 20, 1, S("abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 20, 0, SV("12345678901234567890"), 21, 0, S("can't happen")); + test(S("abcdefghijklmnopqrst"), 20, 1, SV(""), 0, 0, S("abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 20, 1, SV(""), 0, 1, S("abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 20, 1, SV(""), 1, 0, S("can't happen")); + test(S("abcdefghijklmnopqrst"), 20, 1, SV("12345"), 0, 0, S("abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 20, 1, SV("12345"), 0, 1, S("abcdefghijklmnopqrst1")); + test(S("abcdefghijklmnopqrst"), 20, 1, SV("12345"), 0, 2, S("abcdefghijklmnopqrst12")); + test(S("abcdefghijklmnopqrst"), 20, 1, SV("12345"), 0, 4, S("abcdefghijklmnopqrst1234")); + test(S("abcdefghijklmnopqrst"), 20, 1, SV("12345"), 0, 5, S("abcdefghijklmnopqrst12345")); + test(S("abcdefghijklmnopqrst"), 20, 1, SV("12345"), 0, 6, S("abcdefghijklmnopqrst12345")); + test(S("abcdefghijklmnopqrst"), 20, 1, SV("12345"), 1, 0, S("abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 20, 1, SV("12345"), 1, 1, S("abcdefghijklmnopqrst2")); + test(S("abcdefghijklmnopqrst"), 20, 1, SV("12345"), 1, 2, S("abcdefghijklmnopqrst23")); + test(S("abcdefghijklmnopqrst"), 20, 1, SV("12345"), 1, 3, S("abcdefghijklmnopqrst234")); + test(S("abcdefghijklmnopqrst"), 20, 1, SV("12345"), 1, 4, S("abcdefghijklmnopqrst2345")); + test(S("abcdefghijklmnopqrst"), 20, 1, SV("12345"), 1, 5, S("abcdefghijklmnopqrst2345")); + test(S("abcdefghijklmnopqrst"), 20, 1, SV("12345"), 2, 0, S("abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 20, 1, SV("12345"), 2, 1, S("abcdefghijklmnopqrst3")); + test(S("abcdefghijklmnopqrst"), 20, 1, SV("12345"), 2, 2, S("abcdefghijklmnopqrst34")); + test(S("abcdefghijklmnopqrst"), 20, 1, SV("12345"), 2, 3, S("abcdefghijklmnopqrst345")); + test(S("abcdefghijklmnopqrst"), 20, 1, SV("12345"), 2, 4, S("abcdefghijklmnopqrst345")); + test(S("abcdefghijklmnopqrst"), 20, 1, SV("12345"), 4, 0, S("abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 20, 1, SV("12345"), 4, 1, S("abcdefghijklmnopqrst5")); + test(S("abcdefghijklmnopqrst"), 20, 1, SV("12345"), 4, 2, S("abcdefghijklmnopqrst5")); + test(S("abcdefghijklmnopqrst"), 20, 1, SV("12345"), 5, 0, S("abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 20, 1, SV("12345"), 5, 1, S("abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 20, 1, SV("12345"), 6, 0, S("can't happen")); + test(S("abcdefghijklmnopqrst"), 20, 1, SV("1234567890"), 0, 0, S("abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 20, 1, SV("1234567890"), 0, 1, S("abcdefghijklmnopqrst1")); + test(S("abcdefghijklmnopqrst"), 20, 1, SV("1234567890"), 0, 5, S("abcdefghijklmnopqrst12345")); + test(S("abcdefghijklmnopqrst"), 20, 1, SV("1234567890"), 0, 9, S("abcdefghijklmnopqrst123456789")); + test(S("abcdefghijklmnopqrst"), 20, 1, SV("1234567890"), 0, 10, S("abcdefghijklmnopqrst1234567890")); + test(S("abcdefghijklmnopqrst"), 20, 1, SV("1234567890"), 0, 11, S("abcdefghijklmnopqrst1234567890")); + test(S("abcdefghijklmnopqrst"), 20, 1, SV("1234567890"), 1, 0, S("abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 20, 1, SV("1234567890"), 1, 1, S("abcdefghijklmnopqrst2")); + test(S("abcdefghijklmnopqrst"), 20, 1, SV("1234567890"), 1, 4, S("abcdefghijklmnopqrst2345")); + test(S("abcdefghijklmnopqrst"), 20, 1, SV("1234567890"), 1, 8, S("abcdefghijklmnopqrst23456789")); + test(S("abcdefghijklmnopqrst"), 20, 1, SV("1234567890"), 1, 9, S("abcdefghijklmnopqrst234567890")); + test(S("abcdefghijklmnopqrst"), 20, 1, SV("1234567890"), 1, 10, S("abcdefghijklmnopqrst234567890")); + test(S("abcdefghijklmnopqrst"), 20, 1, SV("1234567890"), 5, 0, S("abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 20, 1, SV("1234567890"), 5, 1, S("abcdefghijklmnopqrst6")); + test(S("abcdefghijklmnopqrst"), 20, 1, SV("1234567890"), 5, 2, S("abcdefghijklmnopqrst67")); + test(S("abcdefghijklmnopqrst"), 20, 1, SV("1234567890"), 5, 4, S("abcdefghijklmnopqrst6789")); + test(S("abcdefghijklmnopqrst"), 20, 1, SV("1234567890"), 5, 5, S("abcdefghijklmnopqrst67890")); + test(S("abcdefghijklmnopqrst"), 20, 1, SV("1234567890"), 5, 6, S("abcdefghijklmnopqrst67890")); + test(S("abcdefghijklmnopqrst"), 20, 1, SV("1234567890"), 9, 0, S("abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 20, 1, SV("1234567890"), 9, 1, S("abcdefghijklmnopqrst0")); + test(S("abcdefghijklmnopqrst"), 20, 1, SV("1234567890"), 9, 2, S("abcdefghijklmnopqrst0")); + test(S("abcdefghijklmnopqrst"), 20, 1, SV("1234567890"), 10, 0, S("abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 20, 1, SV("1234567890"), 10, 1, S("abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 20, 1, SV("1234567890"), 11, 0, S("can't happen")); + test(S("abcdefghijklmnopqrst"), 20, 1, SV("12345678901234567890"), 0, 0, S("abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 20, 1, SV("12345678901234567890"), 0, 1, S("abcdefghijklmnopqrst1")); + test(S("abcdefghijklmnopqrst"), 20, 1, SV("12345678901234567890"), 0, 10, S("abcdefghijklmnopqrst1234567890")); + test(S("abcdefghijklmnopqrst"), 20, 1, SV("12345678901234567890"), 0, 19, S("abcdefghijklmnopqrst1234567890123456789")); + test(S("abcdefghijklmnopqrst"), 20, 1, SV("12345678901234567890"), 0, 20, S("abcdefghijklmnopqrst12345678901234567890")); + test(S("abcdefghijklmnopqrst"), 20, 1, SV("12345678901234567890"), 0, 21, S("abcdefghijklmnopqrst12345678901234567890")); + test(S("abcdefghijklmnopqrst"), 20, 1, SV("12345678901234567890"), 1, 0, S("abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 20, 1, SV("12345678901234567890"), 1, 1, S("abcdefghijklmnopqrst2")); + test(S("abcdefghijklmnopqrst"), 20, 1, SV("12345678901234567890"), 1, 9, S("abcdefghijklmnopqrst234567890")); + test(S("abcdefghijklmnopqrst"), 20, 1, SV("12345678901234567890"), 1, 18, S("abcdefghijklmnopqrst234567890123456789")); + test(S("abcdefghijklmnopqrst"), 20, 1, SV("12345678901234567890"), 1, 19, S("abcdefghijklmnopqrst2345678901234567890")); + test(S("abcdefghijklmnopqrst"), 20, 1, SV("12345678901234567890"), 1, 20, S("abcdefghijklmnopqrst2345678901234567890")); + test(S("abcdefghijklmnopqrst"), 20, 1, SV("12345678901234567890"), 10, 0, S("abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 20, 1, SV("12345678901234567890"), 10, 1, S("abcdefghijklmnopqrst1")); + test(S("abcdefghijklmnopqrst"), 20, 1, SV("12345678901234567890"), 10, 5, S("abcdefghijklmnopqrst12345")); + test(S("abcdefghijklmnopqrst"), 20, 1, SV("12345678901234567890"), 10, 9, S("abcdefghijklmnopqrst123456789")); + test(S("abcdefghijklmnopqrst"), 20, 1, SV("12345678901234567890"), 10, 10, S("abcdefghijklmnopqrst1234567890")); + test(S("abcdefghijklmnopqrst"), 20, 1, SV("12345678901234567890"), 10, 11, S("abcdefghijklmnopqrst1234567890")); + test(S("abcdefghijklmnopqrst"), 20, 1, SV("12345678901234567890"), 19, 0, S("abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 20, 1, SV("12345678901234567890"), 19, 1, S("abcdefghijklmnopqrst0")); + test(S("abcdefghijklmnopqrst"), 20, 1, SV("12345678901234567890"), 19, 2, S("abcdefghijklmnopqrst0")); + test(S("abcdefghijklmnopqrst"), 20, 1, SV("12345678901234567890"), 20, 0, S("abcdefghijklmnopqrst")); +} + +template +void test54() +{ + test(S("abcdefghijklmnopqrst"), 20, 1, SV("12345678901234567890"), 20, 1, S("abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 20, 1, SV("12345678901234567890"), 21, 0, S("can't happen")); + test(S("abcdefghijklmnopqrst"), 21, 0, SV(""), 0, 0, S("can't happen")); + test(S("abcdefghijklmnopqrst"), 21, 0, SV(""), 0, 1, S("can't happen")); + test(S("abcdefghijklmnopqrst"), 21, 0, SV(""), 1, 0, S("can't happen")); + test(S("abcdefghijklmnopqrst"), 21, 0, SV("12345"), 0, 0, S("can't happen")); + test(S("abcdefghijklmnopqrst"), 21, 0, SV("12345"), 0, 1, S("can't happen")); + test(S("abcdefghijklmnopqrst"), 21, 0, SV("12345"), 0, 2, S("can't happen")); + test(S("abcdefghijklmnopqrst"), 21, 0, SV("12345"), 0, 4, S("can't happen")); + test(S("abcdefghijklmnopqrst"), 21, 0, SV("12345"), 0, 5, S("can't happen")); + test(S("abcdefghijklmnopqrst"), 21, 0, SV("12345"), 0, 6, S("can't happen")); + test(S("abcdefghijklmnopqrst"), 21, 0, SV("12345"), 1, 0, S("can't happen")); + test(S("abcdefghijklmnopqrst"), 21, 0, SV("12345"), 1, 1, S("can't happen")); + test(S("abcdefghijklmnopqrst"), 21, 0, SV("12345"), 1, 2, S("can't happen")); + test(S("abcdefghijklmnopqrst"), 21, 0, SV("12345"), 1, 3, S("can't happen")); + test(S("abcdefghijklmnopqrst"), 21, 0, SV("12345"), 1, 4, S("can't happen")); + test(S("abcdefghijklmnopqrst"), 21, 0, SV("12345"), 1, 5, S("can't happen")); + test(S("abcdefghijklmnopqrst"), 21, 0, SV("12345"), 2, 0, S("can't happen")); + test(S("abcdefghijklmnopqrst"), 21, 0, SV("12345"), 2, 1, S("can't happen")); + test(S("abcdefghijklmnopqrst"), 21, 0, SV("12345"), 2, 2, S("can't happen")); + test(S("abcdefghijklmnopqrst"), 21, 0, SV("12345"), 2, 3, S("can't happen")); + test(S("abcdefghijklmnopqrst"), 21, 0, SV("12345"), 2, 4, S("can't happen")); + test(S("abcdefghijklmnopqrst"), 21, 0, SV("12345"), 4, 0, S("can't happen")); + test(S("abcdefghijklmnopqrst"), 21, 0, SV("12345"), 4, 1, S("can't happen")); + test(S("abcdefghijklmnopqrst"), 21, 0, SV("12345"), 4, 2, S("can't happen")); + test(S("abcdefghijklmnopqrst"), 21, 0, SV("12345"), 5, 0, S("can't happen")); + test(S("abcdefghijklmnopqrst"), 21, 0, SV("12345"), 5, 1, S("can't happen")); + test(S("abcdefghijklmnopqrst"), 21, 0, SV("12345"), 6, 0, S("can't happen")); + test(S("abcdefghijklmnopqrst"), 21, 0, SV("1234567890"), 0, 0, S("can't happen")); + test(S("abcdefghijklmnopqrst"), 21, 0, SV("1234567890"), 0, 1, S("can't happen")); + test(S("abcdefghijklmnopqrst"), 21, 0, SV("1234567890"), 0, 5, S("can't happen")); + test(S("abcdefghijklmnopqrst"), 21, 0, SV("1234567890"), 0, 9, S("can't happen")); + test(S("abcdefghijklmnopqrst"), 21, 0, SV("1234567890"), 0, 10, S("can't happen")); + test(S("abcdefghijklmnopqrst"), 21, 0, SV("1234567890"), 0, 11, S("can't happen")); + test(S("abcdefghijklmnopqrst"), 21, 0, SV("1234567890"), 1, 0, S("can't happen")); + test(S("abcdefghijklmnopqrst"), 21, 0, SV("1234567890"), 1, 1, S("can't happen")); + test(S("abcdefghijklmnopqrst"), 21, 0, SV("1234567890"), 1, 4, S("can't happen")); + test(S("abcdefghijklmnopqrst"), 21, 0, SV("1234567890"), 1, 8, S("can't happen")); + test(S("abcdefghijklmnopqrst"), 21, 0, SV("1234567890"), 1, 9, S("can't happen")); + test(S("abcdefghijklmnopqrst"), 21, 0, SV("1234567890"), 1, 10, S("can't happen")); + test(S("abcdefghijklmnopqrst"), 21, 0, SV("1234567890"), 5, 0, S("can't happen")); + test(S("abcdefghijklmnopqrst"), 21, 0, SV("1234567890"), 5, 1, S("can't happen")); + test(S("abcdefghijklmnopqrst"), 21, 0, SV("1234567890"), 5, 2, S("can't happen")); + test(S("abcdefghijklmnopqrst"), 21, 0, SV("1234567890"), 5, 4, S("can't happen")); + test(S("abcdefghijklmnopqrst"), 21, 0, SV("1234567890"), 5, 5, S("can't happen")); + test(S("abcdefghijklmnopqrst"), 21, 0, SV("1234567890"), 5, 6, S("can't happen")); + test(S("abcdefghijklmnopqrst"), 21, 0, SV("1234567890"), 9, 0, S("can't happen")); + test(S("abcdefghijklmnopqrst"), 21, 0, SV("1234567890"), 9, 1, S("can't happen")); + test(S("abcdefghijklmnopqrst"), 21, 0, SV("1234567890"), 9, 2, S("can't happen")); + test(S("abcdefghijklmnopqrst"), 21, 0, SV("1234567890"), 10, 0, S("can't happen")); + test(S("abcdefghijklmnopqrst"), 21, 0, SV("1234567890"), 10, 1, S("can't happen")); + test(S("abcdefghijklmnopqrst"), 21, 0, SV("1234567890"), 11, 0, S("can't happen")); + test(S("abcdefghijklmnopqrst"), 21, 0, SV("12345678901234567890"), 0, 0, S("can't happen")); + test(S("abcdefghijklmnopqrst"), 21, 0, SV("12345678901234567890"), 0, 1, S("can't happen")); + test(S("abcdefghijklmnopqrst"), 21, 0, SV("12345678901234567890"), 0, 10, S("can't happen")); + test(S("abcdefghijklmnopqrst"), 21, 0, SV("12345678901234567890"), 0, 19, S("can't happen")); + test(S("abcdefghijklmnopqrst"), 21, 0, SV("12345678901234567890"), 0, 20, S("can't happen")); + test(S("abcdefghijklmnopqrst"), 21, 0, SV("12345678901234567890"), 0, 21, S("can't happen")); + test(S("abcdefghijklmnopqrst"), 21, 0, SV("12345678901234567890"), 1, 0, S("can't happen")); + test(S("abcdefghijklmnopqrst"), 21, 0, SV("12345678901234567890"), 1, 1, S("can't happen")); + test(S("abcdefghijklmnopqrst"), 21, 0, SV("12345678901234567890"), 1, 9, S("can't happen")); + test(S("abcdefghijklmnopqrst"), 21, 0, SV("12345678901234567890"), 1, 18, S("can't happen")); + test(S("abcdefghijklmnopqrst"), 21, 0, SV("12345678901234567890"), 1, 19, S("can't happen")); + test(S("abcdefghijklmnopqrst"), 21, 0, SV("12345678901234567890"), 1, 20, S("can't happen")); + test(S("abcdefghijklmnopqrst"), 21, 0, SV("12345678901234567890"), 10, 0, S("can't happen")); + test(S("abcdefghijklmnopqrst"), 21, 0, SV("12345678901234567890"), 10, 1, S("can't happen")); + test(S("abcdefghijklmnopqrst"), 21, 0, SV("12345678901234567890"), 10, 5, S("can't happen")); + test(S("abcdefghijklmnopqrst"), 21, 0, SV("12345678901234567890"), 10, 9, S("can't happen")); + test(S("abcdefghijklmnopqrst"), 21, 0, SV("12345678901234567890"), 10, 10, S("can't happen")); + test(S("abcdefghijklmnopqrst"), 21, 0, SV("12345678901234567890"), 10, 11, S("can't happen")); + test(S("abcdefghijklmnopqrst"), 21, 0, SV("12345678901234567890"), 19, 0, S("can't happen")); + test(S("abcdefghijklmnopqrst"), 21, 0, SV("12345678901234567890"), 19, 1, S("can't happen")); + test(S("abcdefghijklmnopqrst"), 21, 0, SV("12345678901234567890"), 19, 2, S("can't happen")); + test(S("abcdefghijklmnopqrst"), 21, 0, SV("12345678901234567890"), 20, 0, S("can't happen")); + test(S("abcdefghijklmnopqrst"), 21, 0, SV("12345678901234567890"), 20, 1, S("can't happen")); + test(S("abcdefghijklmnopqrst"), 21, 0, SV("12345678901234567890"), 21, 0, S("can't happen")); +} + +template +void test55() +{ + test_npos(S("abcdefghij"), 9, 1, SV("12345678901234567890"), 10, S("abcdefghi1234567890")); + test_npos(S("abcdefghij"), 9, 1, SV("12345678901234567890"), 19, S("abcdefghi0")); + test_npos(S("abcdefghij"), 9, 1, SV("12345678901234567890"), 20, S("abcdefghi")); + test_npos(S("abcdefghij"), 9, 1, SV("12345678901234567890"), 20, S("abcdefghi")); + test_npos(S("abcdefghij"), 9, 1, SV("12345678901234567890"), 21, S("can't happen")); + test_npos(S("abcdefghij"), 9, 2, SV(""), 0, S("abcdefghi")); + test_npos(S("abcdefghij"), 9, 2, SV(""), 1, S("can't happen")); + test_npos(S("abcdefghij"), 9, 2, SV("12345"), 0, S("abcdefghi12345")); + test_npos(S("abcdefghij"), 9, 2, SV("12345"), 1, S("abcdefghi2345")); + test_npos(S("abcdefghij"), 9, 2, SV("12345"), 2, S("abcdefghi345")); + test_npos(S("abcdefghij"), 9, 2, SV("12345"), 4, S("abcdefghi5")); + test_npos(S("abcdefghij"), 9, 2, SV("12345"), 5, S("abcdefghi")); + test_npos(S("abcdefghij"), 9, 2, SV("12345"), 6, S("can't happen")); +} + +int main() +{ + { + typedef std::string S; + typedef std::string_view SV; + test0(); + test1(); + test2(); + test3(); + test4(); + test5(); + test6(); + test7(); + test8(); + test9(); + test10(); + test11(); + test12(); + test13(); + test14(); + test15(); + test16(); + test17(); + test18(); + test19(); + test20(); + test21(); + test22(); + test23(); + test24(); + test25(); + test26(); + test27(); + test28(); + test29(); + test30(); + test31(); + test32(); + test33(); + test34(); + test35(); + test36(); + test37(); + test38(); + test39(); + test40(); + test41(); + test42(); + test43(); + test44(); + test45(); + test46(); + test47(); + test48(); + test49(); + test50(); + test51(); + test52(); + test53(); + test54(); + test55(); + } +#if TEST_STD_VER >= 11 + { + typedef std::basic_string, min_allocator> S; + typedef std::basic_string_view> SV; + test0(); + test1(); + test2(); + test3(); + test4(); + test5(); + test6(); + test7(); + test8(); + test9(); + test10(); + test11(); + test12(); + test13(); + test14(); + test15(); + test16(); + test17(); + test18(); + test19(); + test20(); + test21(); + test22(); + test23(); + test24(); + test25(); + test26(); + test27(); + test28(); + test29(); + test30(); + test31(); + test32(); + test33(); + test34(); + test35(); + test36(); + test37(); + test38(); + test39(); + test40(); + test41(); + test42(); + test43(); + test44(); + test45(); + test46(); + test47(); + test48(); + test49(); + test50(); + test51(); + test52(); + test53(); + test54(); + test55(); + } +#endif + { + typedef std::string S; + typedef std::string_view SV; + S s0 = "ABCD"; + S s; + SV sv = "EFGH"; + char arr[] = "IJKL"; + + s = s0; + s.replace(0, 4, "CDEF", 0); // calls replace(pos1, n1, const char *, len) + assert(s == ""); + + s = s0; + s.replace(0, 4, "QRST", 0, std::string::npos); // calls replace(pos1, n1, string("QRST"), pos, npos) + assert(s == "QRST"); + + s = s0; + s.replace(0, 4, sv, 0); // calls replace(pos1, n1, T, pos, npos) + assert(s == sv); + + s = s0; + s.replace(0, 4, sv, 0, std::string::npos); // calls replace(pos1, n1, T, pos, npos) + assert(s == sv); + + s = s0; + s.replace(0, 4, arr, 0); // calls replace(pos1, n1, const char *, len) + assert(s == ""); + + s = s0; + s.replace(0, 4, arr, 0, std::string::npos); // calls replace(pos1, n1, string("IJKL"), pos, npos) + assert(s == "IJKL"); + } +} diff --git a/tests/external/libcxx/basic_string/string.modifiers/string_replace/size_size_pointer.pass.cpp b/tests/external/libcxx/basic_string/string.modifiers/string_replace/size_size_pointer.pass.cpp new file mode 100644 index 0000000..d09c9c2 --- /dev/null +++ b/tests/external/libcxx/basic_string/string.modifiers/string_replace/size_size_pointer.pass.cpp @@ -0,0 +1,383 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// + +// basic_string& +// replace(size_type pos, size_type n1, const charT* s); + +#include +#include +#include +#include + +#include "test_macros.h" +#include "min_allocator.h" + +template +void +test(S s, typename S::size_type pos, typename S::size_type n1, + const typename S::value_type* str, S expected) +{ + const typename S::size_type old_size = s.size(); + S s0 = s; + if (pos <= old_size) + { + s.replace(pos, n1, str); + LIBCPP_ASSERT(s.__invariants()); + assert(s == expected); + typename S::size_type xlen = std::min(n1, old_size - pos); + typename S::size_type rlen = S::traits_type::length(str); + assert(s.size() == old_size - xlen + rlen); + } +#ifndef TEST_HAS_NO_EXCEPTIONS + else + { + try + { + s.replace(pos, n1, str); + assert(false); + } + catch (std::out_of_range&) + { + assert(pos > old_size); + assert(s == s0); + } + } +#endif +} + +template +void test0() +{ + test(S(""), 0, 0, "", S("")); + test(S(""), 0, 0, "12345", S("12345")); + test(S(""), 0, 0, "1234567890", S("1234567890")); + test(S(""), 0, 0, "12345678901234567890", S("12345678901234567890")); + test(S(""), 0, 1, "", S("")); + test(S(""), 0, 1, "12345", S("12345")); + test(S(""), 0, 1, "1234567890", S("1234567890")); + test(S(""), 0, 1, "12345678901234567890", S("12345678901234567890")); + test(S(""), 1, 0, "", S("can't happen")); + test(S(""), 1, 0, "12345", S("can't happen")); + test(S(""), 1, 0, "1234567890", S("can't happen")); + test(S(""), 1, 0, "12345678901234567890", S("can't happen")); + test(S("abcde"), 0, 0, "", S("abcde")); + test(S("abcde"), 0, 0, "12345", S("12345abcde")); + test(S("abcde"), 0, 0, "1234567890", S("1234567890abcde")); + test(S("abcde"), 0, 0, "12345678901234567890", S("12345678901234567890abcde")); + test(S("abcde"), 0, 1, "", S("bcde")); + test(S("abcde"), 0, 1, "12345", S("12345bcde")); + test(S("abcde"), 0, 1, "1234567890", S("1234567890bcde")); + test(S("abcde"), 0, 1, "12345678901234567890", S("12345678901234567890bcde")); + test(S("abcde"), 0, 2, "", S("cde")); + test(S("abcde"), 0, 2, "12345", S("12345cde")); + test(S("abcde"), 0, 2, "1234567890", S("1234567890cde")); + test(S("abcde"), 0, 2, "12345678901234567890", S("12345678901234567890cde")); + test(S("abcde"), 0, 4, "", S("e")); + test(S("abcde"), 0, 4, "12345", S("12345e")); + test(S("abcde"), 0, 4, "1234567890", S("1234567890e")); + test(S("abcde"), 0, 4, "12345678901234567890", S("12345678901234567890e")); + test(S("abcde"), 0, 5, "", S("")); + test(S("abcde"), 0, 5, "12345", S("12345")); + test(S("abcde"), 0, 5, "1234567890", S("1234567890")); + test(S("abcde"), 0, 5, "12345678901234567890", S("12345678901234567890")); + test(S("abcde"), 0, 6, "", S("")); + test(S("abcde"), 0, 6, "12345", S("12345")); + test(S("abcde"), 0, 6, "1234567890", S("1234567890")); + test(S("abcde"), 0, 6, "12345678901234567890", S("12345678901234567890")); + test(S("abcde"), 1, 0, "", S("abcde")); + test(S("abcde"), 1, 0, "12345", S("a12345bcde")); + test(S("abcde"), 1, 0, "1234567890", S("a1234567890bcde")); + test(S("abcde"), 1, 0, "12345678901234567890", S("a12345678901234567890bcde")); + test(S("abcde"), 1, 1, "", S("acde")); + test(S("abcde"), 1, 1, "12345", S("a12345cde")); + test(S("abcde"), 1, 1, "1234567890", S("a1234567890cde")); + test(S("abcde"), 1, 1, "12345678901234567890", S("a12345678901234567890cde")); + test(S("abcde"), 1, 2, "", S("ade")); + test(S("abcde"), 1, 2, "12345", S("a12345de")); + test(S("abcde"), 1, 2, "1234567890", S("a1234567890de")); + test(S("abcde"), 1, 2, "12345678901234567890", S("a12345678901234567890de")); + test(S("abcde"), 1, 3, "", S("ae")); + test(S("abcde"), 1, 3, "12345", S("a12345e")); + test(S("abcde"), 1, 3, "1234567890", S("a1234567890e")); + test(S("abcde"), 1, 3, "12345678901234567890", S("a12345678901234567890e")); + test(S("abcde"), 1, 4, "", S("a")); + test(S("abcde"), 1, 4, "12345", S("a12345")); + test(S("abcde"), 1, 4, "1234567890", S("a1234567890")); + test(S("abcde"), 1, 4, "12345678901234567890", S("a12345678901234567890")); + test(S("abcde"), 1, 5, "", S("a")); + test(S("abcde"), 1, 5, "12345", S("a12345")); + test(S("abcde"), 1, 5, "1234567890", S("a1234567890")); + test(S("abcde"), 1, 5, "12345678901234567890", S("a12345678901234567890")); + test(S("abcde"), 2, 0, "", S("abcde")); + test(S("abcde"), 2, 0, "12345", S("ab12345cde")); + test(S("abcde"), 2, 0, "1234567890", S("ab1234567890cde")); + test(S("abcde"), 2, 0, "12345678901234567890", S("ab12345678901234567890cde")); + test(S("abcde"), 2, 1, "", S("abde")); + test(S("abcde"), 2, 1, "12345", S("ab12345de")); + test(S("abcde"), 2, 1, "1234567890", S("ab1234567890de")); + test(S("abcde"), 2, 1, "12345678901234567890", S("ab12345678901234567890de")); + test(S("abcde"), 2, 2, "", S("abe")); + test(S("abcde"), 2, 2, "12345", S("ab12345e")); + test(S("abcde"), 2, 2, "1234567890", S("ab1234567890e")); + test(S("abcde"), 2, 2, "12345678901234567890", S("ab12345678901234567890e")); + test(S("abcde"), 2, 3, "", S("ab")); + test(S("abcde"), 2, 3, "12345", S("ab12345")); + test(S("abcde"), 2, 3, "1234567890", S("ab1234567890")); + test(S("abcde"), 2, 3, "12345678901234567890", S("ab12345678901234567890")); + test(S("abcde"), 2, 4, "", S("ab")); + test(S("abcde"), 2, 4, "12345", S("ab12345")); + test(S("abcde"), 2, 4, "1234567890", S("ab1234567890")); + test(S("abcde"), 2, 4, "12345678901234567890", S("ab12345678901234567890")); + test(S("abcde"), 4, 0, "", S("abcde")); + test(S("abcde"), 4, 0, "12345", S("abcd12345e")); + test(S("abcde"), 4, 0, "1234567890", S("abcd1234567890e")); + test(S("abcde"), 4, 0, "12345678901234567890", S("abcd12345678901234567890e")); + test(S("abcde"), 4, 1, "", S("abcd")); + test(S("abcde"), 4, 1, "12345", S("abcd12345")); + test(S("abcde"), 4, 1, "1234567890", S("abcd1234567890")); + test(S("abcde"), 4, 1, "12345678901234567890", S("abcd12345678901234567890")); + test(S("abcde"), 4, 2, "", S("abcd")); + test(S("abcde"), 4, 2, "12345", S("abcd12345")); + test(S("abcde"), 4, 2, "1234567890", S("abcd1234567890")); + test(S("abcde"), 4, 2, "12345678901234567890", S("abcd12345678901234567890")); + test(S("abcde"), 5, 0, "", S("abcde")); + test(S("abcde"), 5, 0, "12345", S("abcde12345")); + test(S("abcde"), 5, 0, "1234567890", S("abcde1234567890")); + test(S("abcde"), 5, 0, "12345678901234567890", S("abcde12345678901234567890")); + test(S("abcde"), 5, 1, "", S("abcde")); + test(S("abcde"), 5, 1, "12345", S("abcde12345")); + test(S("abcde"), 5, 1, "1234567890", S("abcde1234567890")); + test(S("abcde"), 5, 1, "12345678901234567890", S("abcde12345678901234567890")); +} + +template +void test1() +{ + test(S("abcde"), 6, 0, "", S("can't happen")); + test(S("abcde"), 6, 0, "12345", S("can't happen")); + test(S("abcde"), 6, 0, "1234567890", S("can't happen")); + test(S("abcde"), 6, 0, "12345678901234567890", S("can't happen")); + test(S("abcdefghij"), 0, 0, "", S("abcdefghij")); + test(S("abcdefghij"), 0, 0, "12345", S("12345abcdefghij")); + test(S("abcdefghij"), 0, 0, "1234567890", S("1234567890abcdefghij")); + test(S("abcdefghij"), 0, 0, "12345678901234567890", S("12345678901234567890abcdefghij")); + test(S("abcdefghij"), 0, 1, "", S("bcdefghij")); + test(S("abcdefghij"), 0, 1, "12345", S("12345bcdefghij")); + test(S("abcdefghij"), 0, 1, "1234567890", S("1234567890bcdefghij")); + test(S("abcdefghij"), 0, 1, "12345678901234567890", S("12345678901234567890bcdefghij")); + test(S("abcdefghij"), 0, 5, "", S("fghij")); + test(S("abcdefghij"), 0, 5, "12345", S("12345fghij")); + test(S("abcdefghij"), 0, 5, "1234567890", S("1234567890fghij")); + test(S("abcdefghij"), 0, 5, "12345678901234567890", S("12345678901234567890fghij")); + test(S("abcdefghij"), 0, 9, "", S("j")); + test(S("abcdefghij"), 0, 9, "12345", S("12345j")); + test(S("abcdefghij"), 0, 9, "1234567890", S("1234567890j")); + test(S("abcdefghij"), 0, 9, "12345678901234567890", S("12345678901234567890j")); + test(S("abcdefghij"), 0, 10, "", S("")); + test(S("abcdefghij"), 0, 10, "12345", S("12345")); + test(S("abcdefghij"), 0, 10, "1234567890", S("1234567890")); + test(S("abcdefghij"), 0, 10, "12345678901234567890", S("12345678901234567890")); + test(S("abcdefghij"), 0, 11, "", S("")); + test(S("abcdefghij"), 0, 11, "12345", S("12345")); + test(S("abcdefghij"), 0, 11, "1234567890", S("1234567890")); + test(S("abcdefghij"), 0, 11, "12345678901234567890", S("12345678901234567890")); + test(S("abcdefghij"), 1, 0, "", S("abcdefghij")); + test(S("abcdefghij"), 1, 0, "12345", S("a12345bcdefghij")); + test(S("abcdefghij"), 1, 0, "1234567890", S("a1234567890bcdefghij")); + test(S("abcdefghij"), 1, 0, "12345678901234567890", S("a12345678901234567890bcdefghij")); + test(S("abcdefghij"), 1, 1, "", S("acdefghij")); + test(S("abcdefghij"), 1, 1, "12345", S("a12345cdefghij")); + test(S("abcdefghij"), 1, 1, "1234567890", S("a1234567890cdefghij")); + test(S("abcdefghij"), 1, 1, "12345678901234567890", S("a12345678901234567890cdefghij")); + test(S("abcdefghij"), 1, 4, "", S("afghij")); + test(S("abcdefghij"), 1, 4, "12345", S("a12345fghij")); + test(S("abcdefghij"), 1, 4, "1234567890", S("a1234567890fghij")); + test(S("abcdefghij"), 1, 4, "12345678901234567890", S("a12345678901234567890fghij")); + test(S("abcdefghij"), 1, 8, "", S("aj")); + test(S("abcdefghij"), 1, 8, "12345", S("a12345j")); + test(S("abcdefghij"), 1, 8, "1234567890", S("a1234567890j")); + test(S("abcdefghij"), 1, 8, "12345678901234567890", S("a12345678901234567890j")); + test(S("abcdefghij"), 1, 9, "", S("a")); + test(S("abcdefghij"), 1, 9, "12345", S("a12345")); + test(S("abcdefghij"), 1, 9, "1234567890", S("a1234567890")); + test(S("abcdefghij"), 1, 9, "12345678901234567890", S("a12345678901234567890")); + test(S("abcdefghij"), 1, 10, "", S("a")); + test(S("abcdefghij"), 1, 10, "12345", S("a12345")); + test(S("abcdefghij"), 1, 10, "1234567890", S("a1234567890")); + test(S("abcdefghij"), 1, 10, "12345678901234567890", S("a12345678901234567890")); + test(S("abcdefghij"), 5, 0, "", S("abcdefghij")); + test(S("abcdefghij"), 5, 0, "12345", S("abcde12345fghij")); + test(S("abcdefghij"), 5, 0, "1234567890", S("abcde1234567890fghij")); + test(S("abcdefghij"), 5, 0, "12345678901234567890", S("abcde12345678901234567890fghij")); + test(S("abcdefghij"), 5, 1, "", S("abcdeghij")); + test(S("abcdefghij"), 5, 1, "12345", S("abcde12345ghij")); + test(S("abcdefghij"), 5, 1, "1234567890", S("abcde1234567890ghij")); + test(S("abcdefghij"), 5, 1, "12345678901234567890", S("abcde12345678901234567890ghij")); + test(S("abcdefghij"), 5, 2, "", S("abcdehij")); + test(S("abcdefghij"), 5, 2, "12345", S("abcde12345hij")); + test(S("abcdefghij"), 5, 2, "1234567890", S("abcde1234567890hij")); + test(S("abcdefghij"), 5, 2, "12345678901234567890", S("abcde12345678901234567890hij")); + test(S("abcdefghij"), 5, 4, "", S("abcdej")); + test(S("abcdefghij"), 5, 4, "12345", S("abcde12345j")); + test(S("abcdefghij"), 5, 4, "1234567890", S("abcde1234567890j")); + test(S("abcdefghij"), 5, 4, "12345678901234567890", S("abcde12345678901234567890j")); + test(S("abcdefghij"), 5, 5, "", S("abcde")); + test(S("abcdefghij"), 5, 5, "12345", S("abcde12345")); + test(S("abcdefghij"), 5, 5, "1234567890", S("abcde1234567890")); + test(S("abcdefghij"), 5, 5, "12345678901234567890", S("abcde12345678901234567890")); + test(S("abcdefghij"), 5, 6, "", S("abcde")); + test(S("abcdefghij"), 5, 6, "12345", S("abcde12345")); + test(S("abcdefghij"), 5, 6, "1234567890", S("abcde1234567890")); + test(S("abcdefghij"), 5, 6, "12345678901234567890", S("abcde12345678901234567890")); + test(S("abcdefghij"), 9, 0, "", S("abcdefghij")); + test(S("abcdefghij"), 9, 0, "12345", S("abcdefghi12345j")); + test(S("abcdefghij"), 9, 0, "1234567890", S("abcdefghi1234567890j")); + test(S("abcdefghij"), 9, 0, "12345678901234567890", S("abcdefghi12345678901234567890j")); + test(S("abcdefghij"), 9, 1, "", S("abcdefghi")); + test(S("abcdefghij"), 9, 1, "12345", S("abcdefghi12345")); + test(S("abcdefghij"), 9, 1, "1234567890", S("abcdefghi1234567890")); + test(S("abcdefghij"), 9, 1, "12345678901234567890", S("abcdefghi12345678901234567890")); + test(S("abcdefghij"), 9, 2, "", S("abcdefghi")); + test(S("abcdefghij"), 9, 2, "12345", S("abcdefghi12345")); + test(S("abcdefghij"), 9, 2, "1234567890", S("abcdefghi1234567890")); + test(S("abcdefghij"), 9, 2, "12345678901234567890", S("abcdefghi12345678901234567890")); + test(S("abcdefghij"), 10, 0, "", S("abcdefghij")); + test(S("abcdefghij"), 10, 0, "12345", S("abcdefghij12345")); + test(S("abcdefghij"), 10, 0, "1234567890", S("abcdefghij1234567890")); + test(S("abcdefghij"), 10, 0, "12345678901234567890", S("abcdefghij12345678901234567890")); + test(S("abcdefghij"), 10, 1, "", S("abcdefghij")); + test(S("abcdefghij"), 10, 1, "12345", S("abcdefghij12345")); + test(S("abcdefghij"), 10, 1, "1234567890", S("abcdefghij1234567890")); + test(S("abcdefghij"), 10, 1, "12345678901234567890", S("abcdefghij12345678901234567890")); + test(S("abcdefghij"), 11, 0, "", S("can't happen")); + test(S("abcdefghij"), 11, 0, "12345", S("can't happen")); + test(S("abcdefghij"), 11, 0, "1234567890", S("can't happen")); + test(S("abcdefghij"), 11, 0, "12345678901234567890", S("can't happen")); +} + +template +void test2() +{ + test(S("abcdefghijklmnopqrst"), 0, 0, "", S("abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, 0, "12345", S("12345abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, 0, "1234567890", S("1234567890abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, 0, "12345678901234567890", S("12345678901234567890abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, 1, "", S("bcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, 1, "12345", S("12345bcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, 1, "1234567890", S("1234567890bcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, 1, "12345678901234567890", S("12345678901234567890bcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, 10, "", S("klmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, 10, "12345", S("12345klmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, 10, "1234567890", S("1234567890klmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, 10, "12345678901234567890", S("12345678901234567890klmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, 19, "", S("t")); + test(S("abcdefghijklmnopqrst"), 0, 19, "12345", S("12345t")); + test(S("abcdefghijklmnopqrst"), 0, 19, "1234567890", S("1234567890t")); + test(S("abcdefghijklmnopqrst"), 0, 19, "12345678901234567890", S("12345678901234567890t")); + test(S("abcdefghijklmnopqrst"), 0, 20, "", S("")); + test(S("abcdefghijklmnopqrst"), 0, 20, "12345", S("12345")); + test(S("abcdefghijklmnopqrst"), 0, 20, "1234567890", S("1234567890")); + test(S("abcdefghijklmnopqrst"), 0, 20, "12345678901234567890", S("12345678901234567890")); + test(S("abcdefghijklmnopqrst"), 0, 21, "", S("")); + test(S("abcdefghijklmnopqrst"), 0, 21, "12345", S("12345")); + test(S("abcdefghijklmnopqrst"), 0, 21, "1234567890", S("1234567890")); + test(S("abcdefghijklmnopqrst"), 0, 21, "12345678901234567890", S("12345678901234567890")); + test(S("abcdefghijklmnopqrst"), 1, 0, "", S("abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, 0, "12345", S("a12345bcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, 0, "1234567890", S("a1234567890bcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, 0, "12345678901234567890", S("a12345678901234567890bcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, 1, "", S("acdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, 1, "12345", S("a12345cdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, 1, "1234567890", S("a1234567890cdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, 1, "12345678901234567890", S("a12345678901234567890cdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, 9, "", S("aklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, 9, "12345", S("a12345klmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, 9, "1234567890", S("a1234567890klmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, 9, "12345678901234567890", S("a12345678901234567890klmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, 18, "", S("at")); + test(S("abcdefghijklmnopqrst"), 1, 18, "12345", S("a12345t")); + test(S("abcdefghijklmnopqrst"), 1, 18, "1234567890", S("a1234567890t")); + test(S("abcdefghijklmnopqrst"), 1, 18, "12345678901234567890", S("a12345678901234567890t")); + test(S("abcdefghijklmnopqrst"), 1, 19, "", S("a")); + test(S("abcdefghijklmnopqrst"), 1, 19, "12345", S("a12345")); + test(S("abcdefghijklmnopqrst"), 1, 19, "1234567890", S("a1234567890")); + test(S("abcdefghijklmnopqrst"), 1, 19, "12345678901234567890", S("a12345678901234567890")); + test(S("abcdefghijklmnopqrst"), 1, 20, "", S("a")); + test(S("abcdefghijklmnopqrst"), 1, 20, "12345", S("a12345")); + test(S("abcdefghijklmnopqrst"), 1, 20, "1234567890", S("a1234567890")); + test(S("abcdefghijklmnopqrst"), 1, 20, "12345678901234567890", S("a12345678901234567890")); + test(S("abcdefghijklmnopqrst"), 10, 0, "", S("abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 10, 0, "12345", S("abcdefghij12345klmnopqrst")); + test(S("abcdefghijklmnopqrst"), 10, 0, "1234567890", S("abcdefghij1234567890klmnopqrst")); + test(S("abcdefghijklmnopqrst"), 10, 0, "12345678901234567890", S("abcdefghij12345678901234567890klmnopqrst")); + test(S("abcdefghijklmnopqrst"), 10, 1, "", S("abcdefghijlmnopqrst")); + test(S("abcdefghijklmnopqrst"), 10, 1, "12345", S("abcdefghij12345lmnopqrst")); + test(S("abcdefghijklmnopqrst"), 10, 1, "1234567890", S("abcdefghij1234567890lmnopqrst")); + test(S("abcdefghijklmnopqrst"), 10, 1, "12345678901234567890", S("abcdefghij12345678901234567890lmnopqrst")); + test(S("abcdefghijklmnopqrst"), 10, 5, "", S("abcdefghijpqrst")); + test(S("abcdefghijklmnopqrst"), 10, 5, "12345", S("abcdefghij12345pqrst")); + test(S("abcdefghijklmnopqrst"), 10, 5, "1234567890", S("abcdefghij1234567890pqrst")); + test(S("abcdefghijklmnopqrst"), 10, 5, "12345678901234567890", S("abcdefghij12345678901234567890pqrst")); + test(S("abcdefghijklmnopqrst"), 10, 9, "", S("abcdefghijt")); + test(S("abcdefghijklmnopqrst"), 10, 9, "12345", S("abcdefghij12345t")); + test(S("abcdefghijklmnopqrst"), 10, 9, "1234567890", S("abcdefghij1234567890t")); + test(S("abcdefghijklmnopqrst"), 10, 9, "12345678901234567890", S("abcdefghij12345678901234567890t")); + test(S("abcdefghijklmnopqrst"), 10, 10, "", S("abcdefghij")); + test(S("abcdefghijklmnopqrst"), 10, 10, "12345", S("abcdefghij12345")); + test(S("abcdefghijklmnopqrst"), 10, 10, "1234567890", S("abcdefghij1234567890")); + test(S("abcdefghijklmnopqrst"), 10, 10, "12345678901234567890", S("abcdefghij12345678901234567890")); + test(S("abcdefghijklmnopqrst"), 10, 11, "", S("abcdefghij")); + test(S("abcdefghijklmnopqrst"), 10, 11, "12345", S("abcdefghij12345")); + test(S("abcdefghijklmnopqrst"), 10, 11, "1234567890", S("abcdefghij1234567890")); + test(S("abcdefghijklmnopqrst"), 10, 11, "12345678901234567890", S("abcdefghij12345678901234567890")); + test(S("abcdefghijklmnopqrst"), 19, 0, "", S("abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 19, 0, "12345", S("abcdefghijklmnopqrs12345t")); + test(S("abcdefghijklmnopqrst"), 19, 0, "1234567890", S("abcdefghijklmnopqrs1234567890t")); + test(S("abcdefghijklmnopqrst"), 19, 0, "12345678901234567890", S("abcdefghijklmnopqrs12345678901234567890t")); + test(S("abcdefghijklmnopqrst"), 19, 1, "", S("abcdefghijklmnopqrs")); + test(S("abcdefghijklmnopqrst"), 19, 1, "12345", S("abcdefghijklmnopqrs12345")); + test(S("abcdefghijklmnopqrst"), 19, 1, "1234567890", S("abcdefghijklmnopqrs1234567890")); + test(S("abcdefghijklmnopqrst"), 19, 1, "12345678901234567890", S("abcdefghijklmnopqrs12345678901234567890")); + test(S("abcdefghijklmnopqrst"), 19, 2, "", S("abcdefghijklmnopqrs")); + test(S("abcdefghijklmnopqrst"), 19, 2, "12345", S("abcdefghijklmnopqrs12345")); + test(S("abcdefghijklmnopqrst"), 19, 2, "1234567890", S("abcdefghijklmnopqrs1234567890")); + test(S("abcdefghijklmnopqrst"), 19, 2, "12345678901234567890", S("abcdefghijklmnopqrs12345678901234567890")); + test(S("abcdefghijklmnopqrst"), 20, 0, "", S("abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 20, 0, "12345", S("abcdefghijklmnopqrst12345")); + test(S("abcdefghijklmnopqrst"), 20, 0, "1234567890", S("abcdefghijklmnopqrst1234567890")); + test(S("abcdefghijklmnopqrst"), 20, 0, "12345678901234567890", S("abcdefghijklmnopqrst12345678901234567890")); + test(S("abcdefghijklmnopqrst"), 20, 1, "", S("abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 20, 1, "12345", S("abcdefghijklmnopqrst12345")); + test(S("abcdefghijklmnopqrst"), 20, 1, "1234567890", S("abcdefghijklmnopqrst1234567890")); + test(S("abcdefghijklmnopqrst"), 20, 1, "12345678901234567890", S("abcdefghijklmnopqrst12345678901234567890")); + test(S("abcdefghijklmnopqrst"), 21, 0, "", S("can't happen")); + test(S("abcdefghijklmnopqrst"), 21, 0, "12345", S("can't happen")); + test(S("abcdefghijklmnopqrst"), 21, 0, "1234567890", S("can't happen")); + test(S("abcdefghijklmnopqrst"), 21, 0, "12345678901234567890", S("can't happen")); +} + +int main() +{ + { + typedef std::string S; + test0(); + test1(); + test2(); + } +#if TEST_STD_VER >= 11 + { + typedef std::basic_string, min_allocator> S; + test0(); + test1(); + test2(); + } +#endif +} diff --git a/tests/external/libcxx/basic_string/string.modifiers/string_replace/size_size_pointer_size.pass.cpp b/tests/external/libcxx/basic_string/string.modifiers/string_replace/size_size_pointer_size.pass.cpp new file mode 100644 index 0000000..5c75128 --- /dev/null +++ b/tests/external/libcxx/basic_string/string.modifiers/string_replace/size_size_pointer_size.pass.cpp @@ -0,0 +1,1335 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// + +// basic_string& +// replace(size_type pos, size_type n1, const charT* s, size_type n2); + +#include +#include +#include +#include + +#include "test_macros.h" +#include "min_allocator.h" + +template +void +test(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) +{ + const typename S::size_type old_size = s.size(); + S s0 = s; + if (pos <= old_size) + { + s.replace(pos, n1, str, n2); + LIBCPP_ASSERT(s.__invariants()); + assert(s == expected); + typename S::size_type xlen = std::min(n1, old_size - pos); + typename S::size_type rlen = n2; + assert(s.size() == old_size - xlen + rlen); + } +#ifndef TEST_HAS_NO_EXCEPTIONS + else + { + try + { + s.replace(pos, n1, str, n2); + assert(false); + } + catch (std::out_of_range&) + { + assert(pos > old_size); + assert(s == s0); + } + } +#endif +} + +template +void test0() +{ + test(S(""), 0, 0, "", 0, S("")); + test(S(""), 0, 0, "12345", 0, S("")); + test(S(""), 0, 0, "12345", 1, S("1")); + test(S(""), 0, 0, "12345", 2, S("12")); + test(S(""), 0, 0, "12345", 4, S("1234")); + test(S(""), 0, 0, "12345", 5, S("12345")); + test(S(""), 0, 0, "1234567890", 0, S("")); + test(S(""), 0, 0, "1234567890", 1, S("1")); + test(S(""), 0, 0, "1234567890", 5, S("12345")); + test(S(""), 0, 0, "1234567890", 9, S("123456789")); + test(S(""), 0, 0, "1234567890", 10, S("1234567890")); + test(S(""), 0, 0, "12345678901234567890", 0, S("")); + test(S(""), 0, 0, "12345678901234567890", 1, S("1")); + test(S(""), 0, 0, "12345678901234567890", 10, S("1234567890")); + test(S(""), 0, 0, "12345678901234567890", 19, S("1234567890123456789")); + test(S(""), 0, 0, "12345678901234567890", 20, S("12345678901234567890")); + test(S(""), 0, 1, "", 0, S("")); + test(S(""), 0, 1, "12345", 0, S("")); + test(S(""), 0, 1, "12345", 1, S("1")); + test(S(""), 0, 1, "12345", 2, S("12")); + test(S(""), 0, 1, "12345", 4, S("1234")); + test(S(""), 0, 1, "12345", 5, S("12345")); + test(S(""), 0, 1, "1234567890", 0, S("")); + test(S(""), 0, 1, "1234567890", 1, S("1")); + test(S(""), 0, 1, "1234567890", 5, S("12345")); + test(S(""), 0, 1, "1234567890", 9, S("123456789")); + test(S(""), 0, 1, "1234567890", 10, S("1234567890")); + test(S(""), 0, 1, "12345678901234567890", 0, S("")); + test(S(""), 0, 1, "12345678901234567890", 1, S("1")); + test(S(""), 0, 1, "12345678901234567890", 10, S("1234567890")); + test(S(""), 0, 1, "12345678901234567890", 19, S("1234567890123456789")); + test(S(""), 0, 1, "12345678901234567890", 20, S("12345678901234567890")); + test(S(""), 1, 0, "", 0, S("can't happen")); + test(S(""), 1, 0, "12345", 0, S("can't happen")); + test(S(""), 1, 0, "12345", 1, S("can't happen")); + test(S(""), 1, 0, "12345", 2, S("can't happen")); + test(S(""), 1, 0, "12345", 4, S("can't happen")); + test(S(""), 1, 0, "12345", 5, S("can't happen")); + test(S(""), 1, 0, "1234567890", 0, S("can't happen")); + test(S(""), 1, 0, "1234567890", 1, S("can't happen")); + test(S(""), 1, 0, "1234567890", 5, S("can't happen")); + test(S(""), 1, 0, "1234567890", 9, S("can't happen")); + test(S(""), 1, 0, "1234567890", 10, S("can't happen")); + test(S(""), 1, 0, "12345678901234567890", 0, S("can't happen")); + test(S(""), 1, 0, "12345678901234567890", 1, S("can't happen")); + test(S(""), 1, 0, "12345678901234567890", 10, S("can't happen")); + test(S(""), 1, 0, "12345678901234567890", 19, S("can't happen")); + test(S(""), 1, 0, "12345678901234567890", 20, S("can't happen")); + test(S("abcde"), 0, 0, "", 0, S("abcde")); + test(S("abcde"), 0, 0, "12345", 0, S("abcde")); + test(S("abcde"), 0, 0, "12345", 1, S("1abcde")); + test(S("abcde"), 0, 0, "12345", 2, S("12abcde")); + test(S("abcde"), 0, 0, "12345", 4, S("1234abcde")); + test(S("abcde"), 0, 0, "12345", 5, S("12345abcde")); + test(S("abcde"), 0, 0, "1234567890", 0, S("abcde")); + test(S("abcde"), 0, 0, "1234567890", 1, S("1abcde")); + test(S("abcde"), 0, 0, "1234567890", 5, S("12345abcde")); + test(S("abcde"), 0, 0, "1234567890", 9, S("123456789abcde")); + test(S("abcde"), 0, 0, "1234567890", 10, S("1234567890abcde")); + test(S("abcde"), 0, 0, "12345678901234567890", 0, S("abcde")); + test(S("abcde"), 0, 0, "12345678901234567890", 1, S("1abcde")); + test(S("abcde"), 0, 0, "12345678901234567890", 10, S("1234567890abcde")); + test(S("abcde"), 0, 0, "12345678901234567890", 19, S("1234567890123456789abcde")); + test(S("abcde"), 0, 0, "12345678901234567890", 20, S("12345678901234567890abcde")); + test(S("abcde"), 0, 1, "", 0, S("bcde")); + test(S("abcde"), 0, 1, "12345", 0, S("bcde")); + test(S("abcde"), 0, 1, "12345", 1, S("1bcde")); + test(S("abcde"), 0, 1, "12345", 2, S("12bcde")); + test(S("abcde"), 0, 1, "12345", 4, S("1234bcde")); + test(S("abcde"), 0, 1, "12345", 5, S("12345bcde")); + test(S("abcde"), 0, 1, "1234567890", 0, S("bcde")); + test(S("abcde"), 0, 1, "1234567890", 1, S("1bcde")); + test(S("abcde"), 0, 1, "1234567890", 5, S("12345bcde")); + test(S("abcde"), 0, 1, "1234567890", 9, S("123456789bcde")); + test(S("abcde"), 0, 1, "1234567890", 10, S("1234567890bcde")); + test(S("abcde"), 0, 1, "12345678901234567890", 0, S("bcde")); + test(S("abcde"), 0, 1, "12345678901234567890", 1, S("1bcde")); + test(S("abcde"), 0, 1, "12345678901234567890", 10, S("1234567890bcde")); + test(S("abcde"), 0, 1, "12345678901234567890", 19, S("1234567890123456789bcde")); + test(S("abcde"), 0, 1, "12345678901234567890", 20, S("12345678901234567890bcde")); + test(S("abcde"), 0, 2, "", 0, S("cde")); + test(S("abcde"), 0, 2, "12345", 0, S("cde")); + test(S("abcde"), 0, 2, "12345", 1, S("1cde")); + test(S("abcde"), 0, 2, "12345", 2, S("12cde")); + test(S("abcde"), 0, 2, "12345", 4, S("1234cde")); + test(S("abcde"), 0, 2, "12345", 5, S("12345cde")); + test(S("abcde"), 0, 2, "1234567890", 0, S("cde")); + test(S("abcde"), 0, 2, "1234567890", 1, S("1cde")); + test(S("abcde"), 0, 2, "1234567890", 5, S("12345cde")); + test(S("abcde"), 0, 2, "1234567890", 9, S("123456789cde")); + test(S("abcde"), 0, 2, "1234567890", 10, S("1234567890cde")); + test(S("abcde"), 0, 2, "12345678901234567890", 0, S("cde")); + test(S("abcde"), 0, 2, "12345678901234567890", 1, S("1cde")); + test(S("abcde"), 0, 2, "12345678901234567890", 10, S("1234567890cde")); + test(S("abcde"), 0, 2, "12345678901234567890", 19, S("1234567890123456789cde")); + test(S("abcde"), 0, 2, "12345678901234567890", 20, S("12345678901234567890cde")); + test(S("abcde"), 0, 4, "", 0, S("e")); + test(S("abcde"), 0, 4, "12345", 0, S("e")); + test(S("abcde"), 0, 4, "12345", 1, S("1e")); + test(S("abcde"), 0, 4, "12345", 2, S("12e")); +} + +template +void test1() +{ + test(S("abcde"), 0, 4, "12345", 4, S("1234e")); + test(S("abcde"), 0, 4, "12345", 5, S("12345e")); + test(S("abcde"), 0, 4, "1234567890", 0, S("e")); + test(S("abcde"), 0, 4, "1234567890", 1, S("1e")); + test(S("abcde"), 0, 4, "1234567890", 5, S("12345e")); + test(S("abcde"), 0, 4, "1234567890", 9, S("123456789e")); + test(S("abcde"), 0, 4, "1234567890", 10, S("1234567890e")); + test(S("abcde"), 0, 4, "12345678901234567890", 0, S("e")); + test(S("abcde"), 0, 4, "12345678901234567890", 1, S("1e")); + test(S("abcde"), 0, 4, "12345678901234567890", 10, S("1234567890e")); + test(S("abcde"), 0, 4, "12345678901234567890", 19, S("1234567890123456789e")); + test(S("abcde"), 0, 4, "12345678901234567890", 20, S("12345678901234567890e")); + test(S("abcde"), 0, 5, "", 0, S("")); + test(S("abcde"), 0, 5, "12345", 0, S("")); + test(S("abcde"), 0, 5, "12345", 1, S("1")); + test(S("abcde"), 0, 5, "12345", 2, S("12")); + test(S("abcde"), 0, 5, "12345", 4, S("1234")); + test(S("abcde"), 0, 5, "12345", 5, S("12345")); + test(S("abcde"), 0, 5, "1234567890", 0, S("")); + test(S("abcde"), 0, 5, "1234567890", 1, S("1")); + test(S("abcde"), 0, 5, "1234567890", 5, S("12345")); + test(S("abcde"), 0, 5, "1234567890", 9, S("123456789")); + test(S("abcde"), 0, 5, "1234567890", 10, S("1234567890")); + test(S("abcde"), 0, 5, "12345678901234567890", 0, S("")); + test(S("abcde"), 0, 5, "12345678901234567890", 1, S("1")); + test(S("abcde"), 0, 5, "12345678901234567890", 10, S("1234567890")); + test(S("abcde"), 0, 5, "12345678901234567890", 19, S("1234567890123456789")); + test(S("abcde"), 0, 5, "12345678901234567890", 20, S("12345678901234567890")); + test(S("abcde"), 0, 6, "", 0, S("")); + test(S("abcde"), 0, 6, "12345", 0, S("")); + test(S("abcde"), 0, 6, "12345", 1, S("1")); + test(S("abcde"), 0, 6, "12345", 2, S("12")); + test(S("abcde"), 0, 6, "12345", 4, S("1234")); + test(S("abcde"), 0, 6, "12345", 5, S("12345")); + test(S("abcde"), 0, 6, "1234567890", 0, S("")); + test(S("abcde"), 0, 6, "1234567890", 1, S("1")); + test(S("abcde"), 0, 6, "1234567890", 5, S("12345")); + test(S("abcde"), 0, 6, "1234567890", 9, S("123456789")); + test(S("abcde"), 0, 6, "1234567890", 10, S("1234567890")); + test(S("abcde"), 0, 6, "12345678901234567890", 0, S("")); + test(S("abcde"), 0, 6, "12345678901234567890", 1, S("1")); + test(S("abcde"), 0, 6, "12345678901234567890", 10, S("1234567890")); + test(S("abcde"), 0, 6, "12345678901234567890", 19, S("1234567890123456789")); + test(S("abcde"), 0, 6, "12345678901234567890", 20, S("12345678901234567890")); + test(S("abcde"), 1, 0, "", 0, S("abcde")); + test(S("abcde"), 1, 0, "12345", 0, S("abcde")); + test(S("abcde"), 1, 0, "12345", 1, S("a1bcde")); + test(S("abcde"), 1, 0, "12345", 2, S("a12bcde")); + test(S("abcde"), 1, 0, "12345", 4, S("a1234bcde")); + test(S("abcde"), 1, 0, "12345", 5, S("a12345bcde")); + test(S("abcde"), 1, 0, "1234567890", 0, S("abcde")); + test(S("abcde"), 1, 0, "1234567890", 1, S("a1bcde")); + test(S("abcde"), 1, 0, "1234567890", 5, S("a12345bcde")); + test(S("abcde"), 1, 0, "1234567890", 9, S("a123456789bcde")); + test(S("abcde"), 1, 0, "1234567890", 10, S("a1234567890bcde")); + test(S("abcde"), 1, 0, "12345678901234567890", 0, S("abcde")); + test(S("abcde"), 1, 0, "12345678901234567890", 1, S("a1bcde")); + test(S("abcde"), 1, 0, "12345678901234567890", 10, S("a1234567890bcde")); + test(S("abcde"), 1, 0, "12345678901234567890", 19, S("a1234567890123456789bcde")); + test(S("abcde"), 1, 0, "12345678901234567890", 20, S("a12345678901234567890bcde")); + test(S("abcde"), 1, 1, "", 0, S("acde")); + test(S("abcde"), 1, 1, "12345", 0, S("acde")); + test(S("abcde"), 1, 1, "12345", 1, S("a1cde")); + test(S("abcde"), 1, 1, "12345", 2, S("a12cde")); + test(S("abcde"), 1, 1, "12345", 4, S("a1234cde")); + test(S("abcde"), 1, 1, "12345", 5, S("a12345cde")); + test(S("abcde"), 1, 1, "1234567890", 0, S("acde")); + test(S("abcde"), 1, 1, "1234567890", 1, S("a1cde")); + test(S("abcde"), 1, 1, "1234567890", 5, S("a12345cde")); + test(S("abcde"), 1, 1, "1234567890", 9, S("a123456789cde")); + test(S("abcde"), 1, 1, "1234567890", 10, S("a1234567890cde")); + test(S("abcde"), 1, 1, "12345678901234567890", 0, S("acde")); + test(S("abcde"), 1, 1, "12345678901234567890", 1, S("a1cde")); + test(S("abcde"), 1, 1, "12345678901234567890", 10, S("a1234567890cde")); + test(S("abcde"), 1, 1, "12345678901234567890", 19, S("a1234567890123456789cde")); + test(S("abcde"), 1, 1, "12345678901234567890", 20, S("a12345678901234567890cde")); + test(S("abcde"), 1, 2, "", 0, S("ade")); + test(S("abcde"), 1, 2, "12345", 0, S("ade")); + test(S("abcde"), 1, 2, "12345", 1, S("a1de")); + test(S("abcde"), 1, 2, "12345", 2, S("a12de")); + test(S("abcde"), 1, 2, "12345", 4, S("a1234de")); + test(S("abcde"), 1, 2, "12345", 5, S("a12345de")); + test(S("abcde"), 1, 2, "1234567890", 0, S("ade")); + test(S("abcde"), 1, 2, "1234567890", 1, S("a1de")); + test(S("abcde"), 1, 2, "1234567890", 5, S("a12345de")); + test(S("abcde"), 1, 2, "1234567890", 9, S("a123456789de")); + test(S("abcde"), 1, 2, "1234567890", 10, S("a1234567890de")); + test(S("abcde"), 1, 2, "12345678901234567890", 0, S("ade")); + test(S("abcde"), 1, 2, "12345678901234567890", 1, S("a1de")); + test(S("abcde"), 1, 2, "12345678901234567890", 10, S("a1234567890de")); + test(S("abcde"), 1, 2, "12345678901234567890", 19, S("a1234567890123456789de")); + test(S("abcde"), 1, 2, "12345678901234567890", 20, S("a12345678901234567890de")); + test(S("abcde"), 1, 3, "", 0, S("ae")); + test(S("abcde"), 1, 3, "12345", 0, S("ae")); + test(S("abcde"), 1, 3, "12345", 1, S("a1e")); + test(S("abcde"), 1, 3, "12345", 2, S("a12e")); + test(S("abcde"), 1, 3, "12345", 4, S("a1234e")); + test(S("abcde"), 1, 3, "12345", 5, S("a12345e")); + test(S("abcde"), 1, 3, "1234567890", 0, S("ae")); + test(S("abcde"), 1, 3, "1234567890", 1, S("a1e")); +} + +template +void test2() +{ + test(S("abcde"), 1, 3, "1234567890", 5, S("a12345e")); + test(S("abcde"), 1, 3, "1234567890", 9, S("a123456789e")); + test(S("abcde"), 1, 3, "1234567890", 10, S("a1234567890e")); + test(S("abcde"), 1, 3, "12345678901234567890", 0, S("ae")); + test(S("abcde"), 1, 3, "12345678901234567890", 1, S("a1e")); + test(S("abcde"), 1, 3, "12345678901234567890", 10, S("a1234567890e")); + test(S("abcde"), 1, 3, "12345678901234567890", 19, S("a1234567890123456789e")); + test(S("abcde"), 1, 3, "12345678901234567890", 20, S("a12345678901234567890e")); + test(S("abcde"), 1, 4, "", 0, S("a")); + test(S("abcde"), 1, 4, "12345", 0, S("a")); + test(S("abcde"), 1, 4, "12345", 1, S("a1")); + test(S("abcde"), 1, 4, "12345", 2, S("a12")); + test(S("abcde"), 1, 4, "12345", 4, S("a1234")); + test(S("abcde"), 1, 4, "12345", 5, S("a12345")); + test(S("abcde"), 1, 4, "1234567890", 0, S("a")); + test(S("abcde"), 1, 4, "1234567890", 1, S("a1")); + test(S("abcde"), 1, 4, "1234567890", 5, S("a12345")); + test(S("abcde"), 1, 4, "1234567890", 9, S("a123456789")); + test(S("abcde"), 1, 4, "1234567890", 10, S("a1234567890")); + test(S("abcde"), 1, 4, "12345678901234567890", 0, S("a")); + test(S("abcde"), 1, 4, "12345678901234567890", 1, S("a1")); + test(S("abcde"), 1, 4, "12345678901234567890", 10, S("a1234567890")); + test(S("abcde"), 1, 4, "12345678901234567890", 19, S("a1234567890123456789")); + test(S("abcde"), 1, 4, "12345678901234567890", 20, S("a12345678901234567890")); + test(S("abcde"), 1, 5, "", 0, S("a")); + test(S("abcde"), 1, 5, "12345", 0, S("a")); + test(S("abcde"), 1, 5, "12345", 1, S("a1")); + test(S("abcde"), 1, 5, "12345", 2, S("a12")); + test(S("abcde"), 1, 5, "12345", 4, S("a1234")); + test(S("abcde"), 1, 5, "12345", 5, S("a12345")); + test(S("abcde"), 1, 5, "1234567890", 0, S("a")); + test(S("abcde"), 1, 5, "1234567890", 1, S("a1")); + test(S("abcde"), 1, 5, "1234567890", 5, S("a12345")); + test(S("abcde"), 1, 5, "1234567890", 9, S("a123456789")); + test(S("abcde"), 1, 5, "1234567890", 10, S("a1234567890")); + test(S("abcde"), 1, 5, "12345678901234567890", 0, S("a")); + test(S("abcde"), 1, 5, "12345678901234567890", 1, S("a1")); + test(S("abcde"), 1, 5, "12345678901234567890", 10, S("a1234567890")); + test(S("abcde"), 1, 5, "12345678901234567890", 19, S("a1234567890123456789")); + test(S("abcde"), 1, 5, "12345678901234567890", 20, S("a12345678901234567890")); + test(S("abcde"), 2, 0, "", 0, S("abcde")); + test(S("abcde"), 2, 0, "12345", 0, S("abcde")); + test(S("abcde"), 2, 0, "12345", 1, S("ab1cde")); + test(S("abcde"), 2, 0, "12345", 2, S("ab12cde")); + test(S("abcde"), 2, 0, "12345", 4, S("ab1234cde")); + test(S("abcde"), 2, 0, "12345", 5, S("ab12345cde")); + test(S("abcde"), 2, 0, "1234567890", 0, S("abcde")); + test(S("abcde"), 2, 0, "1234567890", 1, S("ab1cde")); + test(S("abcde"), 2, 0, "1234567890", 5, S("ab12345cde")); + test(S("abcde"), 2, 0, "1234567890", 9, S("ab123456789cde")); + test(S("abcde"), 2, 0, "1234567890", 10, S("ab1234567890cde")); + test(S("abcde"), 2, 0, "12345678901234567890", 0, S("abcde")); + test(S("abcde"), 2, 0, "12345678901234567890", 1, S("ab1cde")); + test(S("abcde"), 2, 0, "12345678901234567890", 10, S("ab1234567890cde")); + test(S("abcde"), 2, 0, "12345678901234567890", 19, S("ab1234567890123456789cde")); + test(S("abcde"), 2, 0, "12345678901234567890", 20, S("ab12345678901234567890cde")); + test(S("abcde"), 2, 1, "", 0, S("abde")); + test(S("abcde"), 2, 1, "12345", 0, S("abde")); + test(S("abcde"), 2, 1, "12345", 1, S("ab1de")); + test(S("abcde"), 2, 1, "12345", 2, S("ab12de")); + test(S("abcde"), 2, 1, "12345", 4, S("ab1234de")); + test(S("abcde"), 2, 1, "12345", 5, S("ab12345de")); + test(S("abcde"), 2, 1, "1234567890", 0, S("abde")); + test(S("abcde"), 2, 1, "1234567890", 1, S("ab1de")); + test(S("abcde"), 2, 1, "1234567890", 5, S("ab12345de")); + test(S("abcde"), 2, 1, "1234567890", 9, S("ab123456789de")); + test(S("abcde"), 2, 1, "1234567890", 10, S("ab1234567890de")); + test(S("abcde"), 2, 1, "12345678901234567890", 0, S("abde")); + test(S("abcde"), 2, 1, "12345678901234567890", 1, S("ab1de")); + test(S("abcde"), 2, 1, "12345678901234567890", 10, S("ab1234567890de")); + test(S("abcde"), 2, 1, "12345678901234567890", 19, S("ab1234567890123456789de")); + test(S("abcde"), 2, 1, "12345678901234567890", 20, S("ab12345678901234567890de")); + test(S("abcde"), 2, 2, "", 0, S("abe")); + test(S("abcde"), 2, 2, "12345", 0, S("abe")); + test(S("abcde"), 2, 2, "12345", 1, S("ab1e")); + test(S("abcde"), 2, 2, "12345", 2, S("ab12e")); + test(S("abcde"), 2, 2, "12345", 4, S("ab1234e")); + test(S("abcde"), 2, 2, "12345", 5, S("ab12345e")); + test(S("abcde"), 2, 2, "1234567890", 0, S("abe")); + test(S("abcde"), 2, 2, "1234567890", 1, S("ab1e")); + test(S("abcde"), 2, 2, "1234567890", 5, S("ab12345e")); + test(S("abcde"), 2, 2, "1234567890", 9, S("ab123456789e")); + test(S("abcde"), 2, 2, "1234567890", 10, S("ab1234567890e")); + test(S("abcde"), 2, 2, "12345678901234567890", 0, S("abe")); + test(S("abcde"), 2, 2, "12345678901234567890", 1, S("ab1e")); + test(S("abcde"), 2, 2, "12345678901234567890", 10, S("ab1234567890e")); + test(S("abcde"), 2, 2, "12345678901234567890", 19, S("ab1234567890123456789e")); + test(S("abcde"), 2, 2, "12345678901234567890", 20, S("ab12345678901234567890e")); + test(S("abcde"), 2, 3, "", 0, S("ab")); + test(S("abcde"), 2, 3, "12345", 0, S("ab")); + test(S("abcde"), 2, 3, "12345", 1, S("ab1")); + test(S("abcde"), 2, 3, "12345", 2, S("ab12")); + test(S("abcde"), 2, 3, "12345", 4, S("ab1234")); + test(S("abcde"), 2, 3, "12345", 5, S("ab12345")); + test(S("abcde"), 2, 3, "1234567890", 0, S("ab")); + test(S("abcde"), 2, 3, "1234567890", 1, S("ab1")); + test(S("abcde"), 2, 3, "1234567890", 5, S("ab12345")); + test(S("abcde"), 2, 3, "1234567890", 9, S("ab123456789")); + test(S("abcde"), 2, 3, "1234567890", 10, S("ab1234567890")); + test(S("abcde"), 2, 3, "12345678901234567890", 0, S("ab")); +} + +template +void test3() +{ + test(S("abcde"), 2, 3, "12345678901234567890", 1, S("ab1")); + test(S("abcde"), 2, 3, "12345678901234567890", 10, S("ab1234567890")); + test(S("abcde"), 2, 3, "12345678901234567890", 19, S("ab1234567890123456789")); + test(S("abcde"), 2, 3, "12345678901234567890", 20, S("ab12345678901234567890")); + test(S("abcde"), 2, 4, "", 0, S("ab")); + test(S("abcde"), 2, 4, "12345", 0, S("ab")); + test(S("abcde"), 2, 4, "12345", 1, S("ab1")); + test(S("abcde"), 2, 4, "12345", 2, S("ab12")); + test(S("abcde"), 2, 4, "12345", 4, S("ab1234")); + test(S("abcde"), 2, 4, "12345", 5, S("ab12345")); + test(S("abcde"), 2, 4, "1234567890", 0, S("ab")); + test(S("abcde"), 2, 4, "1234567890", 1, S("ab1")); + test(S("abcde"), 2, 4, "1234567890", 5, S("ab12345")); + test(S("abcde"), 2, 4, "1234567890", 9, S("ab123456789")); + test(S("abcde"), 2, 4, "1234567890", 10, S("ab1234567890")); + test(S("abcde"), 2, 4, "12345678901234567890", 0, S("ab")); + test(S("abcde"), 2, 4, "12345678901234567890", 1, S("ab1")); + test(S("abcde"), 2, 4, "12345678901234567890", 10, S("ab1234567890")); + test(S("abcde"), 2, 4, "12345678901234567890", 19, S("ab1234567890123456789")); + test(S("abcde"), 2, 4, "12345678901234567890", 20, S("ab12345678901234567890")); + test(S("abcde"), 4, 0, "", 0, S("abcde")); + test(S("abcde"), 4, 0, "12345", 0, S("abcde")); + test(S("abcde"), 4, 0, "12345", 1, S("abcd1e")); + test(S("abcde"), 4, 0, "12345", 2, S("abcd12e")); + test(S("abcde"), 4, 0, "12345", 4, S("abcd1234e")); + test(S("abcde"), 4, 0, "12345", 5, S("abcd12345e")); + test(S("abcde"), 4, 0, "1234567890", 0, S("abcde")); + test(S("abcde"), 4, 0, "1234567890", 1, S("abcd1e")); + test(S("abcde"), 4, 0, "1234567890", 5, S("abcd12345e")); + test(S("abcde"), 4, 0, "1234567890", 9, S("abcd123456789e")); + test(S("abcde"), 4, 0, "1234567890", 10, S("abcd1234567890e")); + test(S("abcde"), 4, 0, "12345678901234567890", 0, S("abcde")); + test(S("abcde"), 4, 0, "12345678901234567890", 1, S("abcd1e")); + test(S("abcde"), 4, 0, "12345678901234567890", 10, S("abcd1234567890e")); + test(S("abcde"), 4, 0, "12345678901234567890", 19, S("abcd1234567890123456789e")); + test(S("abcde"), 4, 0, "12345678901234567890", 20, S("abcd12345678901234567890e")); + test(S("abcde"), 4, 1, "", 0, S("abcd")); + test(S("abcde"), 4, 1, "12345", 0, S("abcd")); + test(S("abcde"), 4, 1, "12345", 1, S("abcd1")); + test(S("abcde"), 4, 1, "12345", 2, S("abcd12")); + test(S("abcde"), 4, 1, "12345", 4, S("abcd1234")); + test(S("abcde"), 4, 1, "12345", 5, S("abcd12345")); + test(S("abcde"), 4, 1, "1234567890", 0, S("abcd")); + test(S("abcde"), 4, 1, "1234567890", 1, S("abcd1")); + test(S("abcde"), 4, 1, "1234567890", 5, S("abcd12345")); + test(S("abcde"), 4, 1, "1234567890", 9, S("abcd123456789")); + test(S("abcde"), 4, 1, "1234567890", 10, S("abcd1234567890")); + test(S("abcde"), 4, 1, "12345678901234567890", 0, S("abcd")); + test(S("abcde"), 4, 1, "12345678901234567890", 1, S("abcd1")); + test(S("abcde"), 4, 1, "12345678901234567890", 10, S("abcd1234567890")); + test(S("abcde"), 4, 1, "12345678901234567890", 19, S("abcd1234567890123456789")); + test(S("abcde"), 4, 1, "12345678901234567890", 20, S("abcd12345678901234567890")); + test(S("abcde"), 4, 2, "", 0, S("abcd")); + test(S("abcde"), 4, 2, "12345", 0, S("abcd")); + test(S("abcde"), 4, 2, "12345", 1, S("abcd1")); + test(S("abcde"), 4, 2, "12345", 2, S("abcd12")); + test(S("abcde"), 4, 2, "12345", 4, S("abcd1234")); + test(S("abcde"), 4, 2, "12345", 5, S("abcd12345")); + test(S("abcde"), 4, 2, "1234567890", 0, S("abcd")); + test(S("abcde"), 4, 2, "1234567890", 1, S("abcd1")); + test(S("abcde"), 4, 2, "1234567890", 5, S("abcd12345")); + test(S("abcde"), 4, 2, "1234567890", 9, S("abcd123456789")); + test(S("abcde"), 4, 2, "1234567890", 10, S("abcd1234567890")); + test(S("abcde"), 4, 2, "12345678901234567890", 0, S("abcd")); + test(S("abcde"), 4, 2, "12345678901234567890", 1, S("abcd1")); + test(S("abcde"), 4, 2, "12345678901234567890", 10, S("abcd1234567890")); + test(S("abcde"), 4, 2, "12345678901234567890", 19, S("abcd1234567890123456789")); + test(S("abcde"), 4, 2, "12345678901234567890", 20, S("abcd12345678901234567890")); + test(S("abcde"), 5, 0, "", 0, S("abcde")); + test(S("abcde"), 5, 0, "12345", 0, S("abcde")); + test(S("abcde"), 5, 0, "12345", 1, S("abcde1")); + test(S("abcde"), 5, 0, "12345", 2, S("abcde12")); + test(S("abcde"), 5, 0, "12345", 4, S("abcde1234")); + test(S("abcde"), 5, 0, "12345", 5, S("abcde12345")); + test(S("abcde"), 5, 0, "1234567890", 0, S("abcde")); + test(S("abcde"), 5, 0, "1234567890", 1, S("abcde1")); + test(S("abcde"), 5, 0, "1234567890", 5, S("abcde12345")); + test(S("abcde"), 5, 0, "1234567890", 9, S("abcde123456789")); + test(S("abcde"), 5, 0, "1234567890", 10, S("abcde1234567890")); + test(S("abcde"), 5, 0, "12345678901234567890", 0, S("abcde")); + test(S("abcde"), 5, 0, "12345678901234567890", 1, S("abcde1")); + test(S("abcde"), 5, 0, "12345678901234567890", 10, S("abcde1234567890")); + test(S("abcde"), 5, 0, "12345678901234567890", 19, S("abcde1234567890123456789")); + test(S("abcde"), 5, 0, "12345678901234567890", 20, S("abcde12345678901234567890")); + test(S("abcde"), 5, 1, "", 0, S("abcde")); + test(S("abcde"), 5, 1, "12345", 0, S("abcde")); + test(S("abcde"), 5, 1, "12345", 1, S("abcde1")); + test(S("abcde"), 5, 1, "12345", 2, S("abcde12")); + test(S("abcde"), 5, 1, "12345", 4, S("abcde1234")); + test(S("abcde"), 5, 1, "12345", 5, S("abcde12345")); + test(S("abcde"), 5, 1, "1234567890", 0, S("abcde")); + test(S("abcde"), 5, 1, "1234567890", 1, S("abcde1")); + test(S("abcde"), 5, 1, "1234567890", 5, S("abcde12345")); + test(S("abcde"), 5, 1, "1234567890", 9, S("abcde123456789")); + test(S("abcde"), 5, 1, "1234567890", 10, S("abcde1234567890")); + test(S("abcde"), 5, 1, "12345678901234567890", 0, S("abcde")); + test(S("abcde"), 5, 1, "12345678901234567890", 1, S("abcde1")); + test(S("abcde"), 5, 1, "12345678901234567890", 10, S("abcde1234567890")); + test(S("abcde"), 5, 1, "12345678901234567890", 19, S("abcde1234567890123456789")); + test(S("abcde"), 5, 1, "12345678901234567890", 20, S("abcde12345678901234567890")); +} + +template +void test4() +{ + test(S("abcde"), 6, 0, "", 0, S("can't happen")); + test(S("abcde"), 6, 0, "12345", 0, S("can't happen")); + test(S("abcde"), 6, 0, "12345", 1, S("can't happen")); + test(S("abcde"), 6, 0, "12345", 2, S("can't happen")); + test(S("abcde"), 6, 0, "12345", 4, S("can't happen")); + test(S("abcde"), 6, 0, "12345", 5, S("can't happen")); + test(S("abcde"), 6, 0, "1234567890", 0, S("can't happen")); + test(S("abcde"), 6, 0, "1234567890", 1, S("can't happen")); + test(S("abcde"), 6, 0, "1234567890", 5, S("can't happen")); + test(S("abcde"), 6, 0, "1234567890", 9, S("can't happen")); + test(S("abcde"), 6, 0, "1234567890", 10, S("can't happen")); + test(S("abcde"), 6, 0, "12345678901234567890", 0, S("can't happen")); + test(S("abcde"), 6, 0, "12345678901234567890", 1, S("can't happen")); + test(S("abcde"), 6, 0, "12345678901234567890", 10, S("can't happen")); + test(S("abcde"), 6, 0, "12345678901234567890", 19, S("can't happen")); + test(S("abcde"), 6, 0, "12345678901234567890", 20, S("can't happen")); + test(S("abcdefghij"), 0, 0, "", 0, S("abcdefghij")); + test(S("abcdefghij"), 0, 0, "12345", 0, S("abcdefghij")); + test(S("abcdefghij"), 0, 0, "12345", 1, S("1abcdefghij")); + test(S("abcdefghij"), 0, 0, "12345", 2, S("12abcdefghij")); + test(S("abcdefghij"), 0, 0, "12345", 4, S("1234abcdefghij")); + test(S("abcdefghij"), 0, 0, "12345", 5, S("12345abcdefghij")); + test(S("abcdefghij"), 0, 0, "1234567890", 0, S("abcdefghij")); + test(S("abcdefghij"), 0, 0, "1234567890", 1, S("1abcdefghij")); + test(S("abcdefghij"), 0, 0, "1234567890", 5, S("12345abcdefghij")); + test(S("abcdefghij"), 0, 0, "1234567890", 9, S("123456789abcdefghij")); + test(S("abcdefghij"), 0, 0, "1234567890", 10, S("1234567890abcdefghij")); + test(S("abcdefghij"), 0, 0, "12345678901234567890", 0, S("abcdefghij")); + test(S("abcdefghij"), 0, 0, "12345678901234567890", 1, S("1abcdefghij")); + test(S("abcdefghij"), 0, 0, "12345678901234567890", 10, S("1234567890abcdefghij")); + test(S("abcdefghij"), 0, 0, "12345678901234567890", 19, S("1234567890123456789abcdefghij")); + test(S("abcdefghij"), 0, 0, "12345678901234567890", 20, S("12345678901234567890abcdefghij")); + test(S("abcdefghij"), 0, 1, "", 0, S("bcdefghij")); + test(S("abcdefghij"), 0, 1, "12345", 0, S("bcdefghij")); + test(S("abcdefghij"), 0, 1, "12345", 1, S("1bcdefghij")); + test(S("abcdefghij"), 0, 1, "12345", 2, S("12bcdefghij")); + test(S("abcdefghij"), 0, 1, "12345", 4, S("1234bcdefghij")); + test(S("abcdefghij"), 0, 1, "12345", 5, S("12345bcdefghij")); + test(S("abcdefghij"), 0, 1, "1234567890", 0, S("bcdefghij")); + test(S("abcdefghij"), 0, 1, "1234567890", 1, S("1bcdefghij")); + test(S("abcdefghij"), 0, 1, "1234567890", 5, S("12345bcdefghij")); + test(S("abcdefghij"), 0, 1, "1234567890", 9, S("123456789bcdefghij")); + test(S("abcdefghij"), 0, 1, "1234567890", 10, S("1234567890bcdefghij")); + test(S("abcdefghij"), 0, 1, "12345678901234567890", 0, S("bcdefghij")); + test(S("abcdefghij"), 0, 1, "12345678901234567890", 1, S("1bcdefghij")); + test(S("abcdefghij"), 0, 1, "12345678901234567890", 10, S("1234567890bcdefghij")); + test(S("abcdefghij"), 0, 1, "12345678901234567890", 19, S("1234567890123456789bcdefghij")); + test(S("abcdefghij"), 0, 1, "12345678901234567890", 20, S("12345678901234567890bcdefghij")); + test(S("abcdefghij"), 0, 5, "", 0, S("fghij")); + test(S("abcdefghij"), 0, 5, "12345", 0, S("fghij")); + test(S("abcdefghij"), 0, 5, "12345", 1, S("1fghij")); + test(S("abcdefghij"), 0, 5, "12345", 2, S("12fghij")); + test(S("abcdefghij"), 0, 5, "12345", 4, S("1234fghij")); + test(S("abcdefghij"), 0, 5, "12345", 5, S("12345fghij")); + test(S("abcdefghij"), 0, 5, "1234567890", 0, S("fghij")); + test(S("abcdefghij"), 0, 5, "1234567890", 1, S("1fghij")); + test(S("abcdefghij"), 0, 5, "1234567890", 5, S("12345fghij")); + test(S("abcdefghij"), 0, 5, "1234567890", 9, S("123456789fghij")); + test(S("abcdefghij"), 0, 5, "1234567890", 10, S("1234567890fghij")); + test(S("abcdefghij"), 0, 5, "12345678901234567890", 0, S("fghij")); + test(S("abcdefghij"), 0, 5, "12345678901234567890", 1, S("1fghij")); + test(S("abcdefghij"), 0, 5, "12345678901234567890", 10, S("1234567890fghij")); + test(S("abcdefghij"), 0, 5, "12345678901234567890", 19, S("1234567890123456789fghij")); + test(S("abcdefghij"), 0, 5, "12345678901234567890", 20, S("12345678901234567890fghij")); + test(S("abcdefghij"), 0, 9, "", 0, S("j")); + test(S("abcdefghij"), 0, 9, "12345", 0, S("j")); + test(S("abcdefghij"), 0, 9, "12345", 1, S("1j")); + test(S("abcdefghij"), 0, 9, "12345", 2, S("12j")); + test(S("abcdefghij"), 0, 9, "12345", 4, S("1234j")); + test(S("abcdefghij"), 0, 9, "12345", 5, S("12345j")); + test(S("abcdefghij"), 0, 9, "1234567890", 0, S("j")); + test(S("abcdefghij"), 0, 9, "1234567890", 1, S("1j")); + test(S("abcdefghij"), 0, 9, "1234567890", 5, S("12345j")); + test(S("abcdefghij"), 0, 9, "1234567890", 9, S("123456789j")); + test(S("abcdefghij"), 0, 9, "1234567890", 10, S("1234567890j")); + test(S("abcdefghij"), 0, 9, "12345678901234567890", 0, S("j")); + test(S("abcdefghij"), 0, 9, "12345678901234567890", 1, S("1j")); + test(S("abcdefghij"), 0, 9, "12345678901234567890", 10, S("1234567890j")); + test(S("abcdefghij"), 0, 9, "12345678901234567890", 19, S("1234567890123456789j")); + test(S("abcdefghij"), 0, 9, "12345678901234567890", 20, S("12345678901234567890j")); + test(S("abcdefghij"), 0, 10, "", 0, S("")); + test(S("abcdefghij"), 0, 10, "12345", 0, S("")); + test(S("abcdefghij"), 0, 10, "12345", 1, S("1")); + test(S("abcdefghij"), 0, 10, "12345", 2, S("12")); + test(S("abcdefghij"), 0, 10, "12345", 4, S("1234")); + test(S("abcdefghij"), 0, 10, "12345", 5, S("12345")); + test(S("abcdefghij"), 0, 10, "1234567890", 0, S("")); + test(S("abcdefghij"), 0, 10, "1234567890", 1, S("1")); + test(S("abcdefghij"), 0, 10, "1234567890", 5, S("12345")); + test(S("abcdefghij"), 0, 10, "1234567890", 9, S("123456789")); + test(S("abcdefghij"), 0, 10, "1234567890", 10, S("1234567890")); + test(S("abcdefghij"), 0, 10, "12345678901234567890", 0, S("")); + test(S("abcdefghij"), 0, 10, "12345678901234567890", 1, S("1")); + test(S("abcdefghij"), 0, 10, "12345678901234567890", 10, S("1234567890")); + test(S("abcdefghij"), 0, 10, "12345678901234567890", 19, S("1234567890123456789")); + test(S("abcdefghij"), 0, 10, "12345678901234567890", 20, S("12345678901234567890")); + test(S("abcdefghij"), 0, 11, "", 0, S("")); + test(S("abcdefghij"), 0, 11, "12345", 0, S("")); + test(S("abcdefghij"), 0, 11, "12345", 1, S("1")); + test(S("abcdefghij"), 0, 11, "12345", 2, S("12")); +} + +template +void test5() +{ + test(S("abcdefghij"), 0, 11, "12345", 4, S("1234")); + test(S("abcdefghij"), 0, 11, "12345", 5, S("12345")); + test(S("abcdefghij"), 0, 11, "1234567890", 0, S("")); + test(S("abcdefghij"), 0, 11, "1234567890", 1, S("1")); + test(S("abcdefghij"), 0, 11, "1234567890", 5, S("12345")); + test(S("abcdefghij"), 0, 11, "1234567890", 9, S("123456789")); + test(S("abcdefghij"), 0, 11, "1234567890", 10, S("1234567890")); + test(S("abcdefghij"), 0, 11, "12345678901234567890", 0, S("")); + test(S("abcdefghij"), 0, 11, "12345678901234567890", 1, S("1")); + test(S("abcdefghij"), 0, 11, "12345678901234567890", 10, S("1234567890")); + test(S("abcdefghij"), 0, 11, "12345678901234567890", 19, S("1234567890123456789")); + test(S("abcdefghij"), 0, 11, "12345678901234567890", 20, S("12345678901234567890")); + test(S("abcdefghij"), 1, 0, "", 0, S("abcdefghij")); + test(S("abcdefghij"), 1, 0, "12345", 0, S("abcdefghij")); + test(S("abcdefghij"), 1, 0, "12345", 1, S("a1bcdefghij")); + test(S("abcdefghij"), 1, 0, "12345", 2, S("a12bcdefghij")); + test(S("abcdefghij"), 1, 0, "12345", 4, S("a1234bcdefghij")); + test(S("abcdefghij"), 1, 0, "12345", 5, S("a12345bcdefghij")); + test(S("abcdefghij"), 1, 0, "1234567890", 0, S("abcdefghij")); + test(S("abcdefghij"), 1, 0, "1234567890", 1, S("a1bcdefghij")); + test(S("abcdefghij"), 1, 0, "1234567890", 5, S("a12345bcdefghij")); + test(S("abcdefghij"), 1, 0, "1234567890", 9, S("a123456789bcdefghij")); + test(S("abcdefghij"), 1, 0, "1234567890", 10, S("a1234567890bcdefghij")); + test(S("abcdefghij"), 1, 0, "12345678901234567890", 0, S("abcdefghij")); + test(S("abcdefghij"), 1, 0, "12345678901234567890", 1, S("a1bcdefghij")); + test(S("abcdefghij"), 1, 0, "12345678901234567890", 10, S("a1234567890bcdefghij")); + test(S("abcdefghij"), 1, 0, "12345678901234567890", 19, S("a1234567890123456789bcdefghij")); + test(S("abcdefghij"), 1, 0, "12345678901234567890", 20, S("a12345678901234567890bcdefghij")); + test(S("abcdefghij"), 1, 1, "", 0, S("acdefghij")); + test(S("abcdefghij"), 1, 1, "12345", 0, S("acdefghij")); + test(S("abcdefghij"), 1, 1, "12345", 1, S("a1cdefghij")); + test(S("abcdefghij"), 1, 1, "12345", 2, S("a12cdefghij")); + test(S("abcdefghij"), 1, 1, "12345", 4, S("a1234cdefghij")); + test(S("abcdefghij"), 1, 1, "12345", 5, S("a12345cdefghij")); + test(S("abcdefghij"), 1, 1, "1234567890", 0, S("acdefghij")); + test(S("abcdefghij"), 1, 1, "1234567890", 1, S("a1cdefghij")); + test(S("abcdefghij"), 1, 1, "1234567890", 5, S("a12345cdefghij")); + test(S("abcdefghij"), 1, 1, "1234567890", 9, S("a123456789cdefghij")); + test(S("abcdefghij"), 1, 1, "1234567890", 10, S("a1234567890cdefghij")); + test(S("abcdefghij"), 1, 1, "12345678901234567890", 0, S("acdefghij")); + test(S("abcdefghij"), 1, 1, "12345678901234567890", 1, S("a1cdefghij")); + test(S("abcdefghij"), 1, 1, "12345678901234567890", 10, S("a1234567890cdefghij")); + test(S("abcdefghij"), 1, 1, "12345678901234567890", 19, S("a1234567890123456789cdefghij")); + test(S("abcdefghij"), 1, 1, "12345678901234567890", 20, S("a12345678901234567890cdefghij")); + test(S("abcdefghij"), 1, 4, "", 0, S("afghij")); + test(S("abcdefghij"), 1, 4, "12345", 0, S("afghij")); + test(S("abcdefghij"), 1, 4, "12345", 1, S("a1fghij")); + test(S("abcdefghij"), 1, 4, "12345", 2, S("a12fghij")); + test(S("abcdefghij"), 1, 4, "12345", 4, S("a1234fghij")); + test(S("abcdefghij"), 1, 4, "12345", 5, S("a12345fghij")); + test(S("abcdefghij"), 1, 4, "1234567890", 0, S("afghij")); + test(S("abcdefghij"), 1, 4, "1234567890", 1, S("a1fghij")); + test(S("abcdefghij"), 1, 4, "1234567890", 5, S("a12345fghij")); + test(S("abcdefghij"), 1, 4, "1234567890", 9, S("a123456789fghij")); + test(S("abcdefghij"), 1, 4, "1234567890", 10, S("a1234567890fghij")); + test(S("abcdefghij"), 1, 4, "12345678901234567890", 0, S("afghij")); + test(S("abcdefghij"), 1, 4, "12345678901234567890", 1, S("a1fghij")); + test(S("abcdefghij"), 1, 4, "12345678901234567890", 10, S("a1234567890fghij")); + test(S("abcdefghij"), 1, 4, "12345678901234567890", 19, S("a1234567890123456789fghij")); + test(S("abcdefghij"), 1, 4, "12345678901234567890", 20, S("a12345678901234567890fghij")); + test(S("abcdefghij"), 1, 8, "", 0, S("aj")); + test(S("abcdefghij"), 1, 8, "12345", 0, S("aj")); + test(S("abcdefghij"), 1, 8, "12345", 1, S("a1j")); + test(S("abcdefghij"), 1, 8, "12345", 2, S("a12j")); + test(S("abcdefghij"), 1, 8, "12345", 4, S("a1234j")); + test(S("abcdefghij"), 1, 8, "12345", 5, S("a12345j")); + test(S("abcdefghij"), 1, 8, "1234567890", 0, S("aj")); + test(S("abcdefghij"), 1, 8, "1234567890", 1, S("a1j")); + test(S("abcdefghij"), 1, 8, "1234567890", 5, S("a12345j")); + test(S("abcdefghij"), 1, 8, "1234567890", 9, S("a123456789j")); + test(S("abcdefghij"), 1, 8, "1234567890", 10, S("a1234567890j")); + test(S("abcdefghij"), 1, 8, "12345678901234567890", 0, S("aj")); + test(S("abcdefghij"), 1, 8, "12345678901234567890", 1, S("a1j")); + test(S("abcdefghij"), 1, 8, "12345678901234567890", 10, S("a1234567890j")); + test(S("abcdefghij"), 1, 8, "12345678901234567890", 19, S("a1234567890123456789j")); + test(S("abcdefghij"), 1, 8, "12345678901234567890", 20, S("a12345678901234567890j")); + test(S("abcdefghij"), 1, 9, "", 0, S("a")); + test(S("abcdefghij"), 1, 9, "12345", 0, S("a")); + test(S("abcdefghij"), 1, 9, "12345", 1, S("a1")); + test(S("abcdefghij"), 1, 9, "12345", 2, S("a12")); + test(S("abcdefghij"), 1, 9, "12345", 4, S("a1234")); + test(S("abcdefghij"), 1, 9, "12345", 5, S("a12345")); + test(S("abcdefghij"), 1, 9, "1234567890", 0, S("a")); + test(S("abcdefghij"), 1, 9, "1234567890", 1, S("a1")); + test(S("abcdefghij"), 1, 9, "1234567890", 5, S("a12345")); + test(S("abcdefghij"), 1, 9, "1234567890", 9, S("a123456789")); + test(S("abcdefghij"), 1, 9, "1234567890", 10, S("a1234567890")); + test(S("abcdefghij"), 1, 9, "12345678901234567890", 0, S("a")); + test(S("abcdefghij"), 1, 9, "12345678901234567890", 1, S("a1")); + test(S("abcdefghij"), 1, 9, "12345678901234567890", 10, S("a1234567890")); + test(S("abcdefghij"), 1, 9, "12345678901234567890", 19, S("a1234567890123456789")); + test(S("abcdefghij"), 1, 9, "12345678901234567890", 20, S("a12345678901234567890")); + test(S("abcdefghij"), 1, 10, "", 0, S("a")); + test(S("abcdefghij"), 1, 10, "12345", 0, S("a")); + test(S("abcdefghij"), 1, 10, "12345", 1, S("a1")); + test(S("abcdefghij"), 1, 10, "12345", 2, S("a12")); + test(S("abcdefghij"), 1, 10, "12345", 4, S("a1234")); + test(S("abcdefghij"), 1, 10, "12345", 5, S("a12345")); + test(S("abcdefghij"), 1, 10, "1234567890", 0, S("a")); + test(S("abcdefghij"), 1, 10, "1234567890", 1, S("a1")); +} + +template +void test6() +{ + test(S("abcdefghij"), 1, 10, "1234567890", 5, S("a12345")); + test(S("abcdefghij"), 1, 10, "1234567890", 9, S("a123456789")); + test(S("abcdefghij"), 1, 10, "1234567890", 10, S("a1234567890")); + test(S("abcdefghij"), 1, 10, "12345678901234567890", 0, S("a")); + test(S("abcdefghij"), 1, 10, "12345678901234567890", 1, S("a1")); + test(S("abcdefghij"), 1, 10, "12345678901234567890", 10, S("a1234567890")); + test(S("abcdefghij"), 1, 10, "12345678901234567890", 19, S("a1234567890123456789")); + test(S("abcdefghij"), 1, 10, "12345678901234567890", 20, S("a12345678901234567890")); + test(S("abcdefghij"), 5, 0, "", 0, S("abcdefghij")); + test(S("abcdefghij"), 5, 0, "12345", 0, S("abcdefghij")); + test(S("abcdefghij"), 5, 0, "12345", 1, S("abcde1fghij")); + test(S("abcdefghij"), 5, 0, "12345", 2, S("abcde12fghij")); + test(S("abcdefghij"), 5, 0, "12345", 4, S("abcde1234fghij")); + test(S("abcdefghij"), 5, 0, "12345", 5, S("abcde12345fghij")); + test(S("abcdefghij"), 5, 0, "1234567890", 0, S("abcdefghij")); + test(S("abcdefghij"), 5, 0, "1234567890", 1, S("abcde1fghij")); + test(S("abcdefghij"), 5, 0, "1234567890", 5, S("abcde12345fghij")); + test(S("abcdefghij"), 5, 0, "1234567890", 9, S("abcde123456789fghij")); + test(S("abcdefghij"), 5, 0, "1234567890", 10, S("abcde1234567890fghij")); + test(S("abcdefghij"), 5, 0, "12345678901234567890", 0, S("abcdefghij")); + test(S("abcdefghij"), 5, 0, "12345678901234567890", 1, S("abcde1fghij")); + test(S("abcdefghij"), 5, 0, "12345678901234567890", 10, S("abcde1234567890fghij")); + test(S("abcdefghij"), 5, 0, "12345678901234567890", 19, S("abcde1234567890123456789fghij")); + test(S("abcdefghij"), 5, 0, "12345678901234567890", 20, S("abcde12345678901234567890fghij")); + test(S("abcdefghij"), 5, 1, "", 0, S("abcdeghij")); + test(S("abcdefghij"), 5, 1, "12345", 0, S("abcdeghij")); + test(S("abcdefghij"), 5, 1, "12345", 1, S("abcde1ghij")); + test(S("abcdefghij"), 5, 1, "12345", 2, S("abcde12ghij")); + test(S("abcdefghij"), 5, 1, "12345", 4, S("abcde1234ghij")); + test(S("abcdefghij"), 5, 1, "12345", 5, S("abcde12345ghij")); + test(S("abcdefghij"), 5, 1, "1234567890", 0, S("abcdeghij")); + test(S("abcdefghij"), 5, 1, "1234567890", 1, S("abcde1ghij")); + test(S("abcdefghij"), 5, 1, "1234567890", 5, S("abcde12345ghij")); + test(S("abcdefghij"), 5, 1, "1234567890", 9, S("abcde123456789ghij")); + test(S("abcdefghij"), 5, 1, "1234567890", 10, S("abcde1234567890ghij")); + test(S("abcdefghij"), 5, 1, "12345678901234567890", 0, S("abcdeghij")); + test(S("abcdefghij"), 5, 1, "12345678901234567890", 1, S("abcde1ghij")); + test(S("abcdefghij"), 5, 1, "12345678901234567890", 10, S("abcde1234567890ghij")); + test(S("abcdefghij"), 5, 1, "12345678901234567890", 19, S("abcde1234567890123456789ghij")); + test(S("abcdefghij"), 5, 1, "12345678901234567890", 20, S("abcde12345678901234567890ghij")); + test(S("abcdefghij"), 5, 2, "", 0, S("abcdehij")); + test(S("abcdefghij"), 5, 2, "12345", 0, S("abcdehij")); + test(S("abcdefghij"), 5, 2, "12345", 1, S("abcde1hij")); + test(S("abcdefghij"), 5, 2, "12345", 2, S("abcde12hij")); + test(S("abcdefghij"), 5, 2, "12345", 4, S("abcde1234hij")); + test(S("abcdefghij"), 5, 2, "12345", 5, S("abcde12345hij")); + test(S("abcdefghij"), 5, 2, "1234567890", 0, S("abcdehij")); + test(S("abcdefghij"), 5, 2, "1234567890", 1, S("abcde1hij")); + test(S("abcdefghij"), 5, 2, "1234567890", 5, S("abcde12345hij")); + test(S("abcdefghij"), 5, 2, "1234567890", 9, S("abcde123456789hij")); + test(S("abcdefghij"), 5, 2, "1234567890", 10, S("abcde1234567890hij")); + test(S("abcdefghij"), 5, 2, "12345678901234567890", 0, S("abcdehij")); + test(S("abcdefghij"), 5, 2, "12345678901234567890", 1, S("abcde1hij")); + test(S("abcdefghij"), 5, 2, "12345678901234567890", 10, S("abcde1234567890hij")); + test(S("abcdefghij"), 5, 2, "12345678901234567890", 19, S("abcde1234567890123456789hij")); + test(S("abcdefghij"), 5, 2, "12345678901234567890", 20, S("abcde12345678901234567890hij")); + test(S("abcdefghij"), 5, 4, "", 0, S("abcdej")); + test(S("abcdefghij"), 5, 4, "12345", 0, S("abcdej")); + test(S("abcdefghij"), 5, 4, "12345", 1, S("abcde1j")); + test(S("abcdefghij"), 5, 4, "12345", 2, S("abcde12j")); + test(S("abcdefghij"), 5, 4, "12345", 4, S("abcde1234j")); + test(S("abcdefghij"), 5, 4, "12345", 5, S("abcde12345j")); + test(S("abcdefghij"), 5, 4, "1234567890", 0, S("abcdej")); + test(S("abcdefghij"), 5, 4, "1234567890", 1, S("abcde1j")); + test(S("abcdefghij"), 5, 4, "1234567890", 5, S("abcde12345j")); + test(S("abcdefghij"), 5, 4, "1234567890", 9, S("abcde123456789j")); + test(S("abcdefghij"), 5, 4, "1234567890", 10, S("abcde1234567890j")); + test(S("abcdefghij"), 5, 4, "12345678901234567890", 0, S("abcdej")); + test(S("abcdefghij"), 5, 4, "12345678901234567890", 1, S("abcde1j")); + test(S("abcdefghij"), 5, 4, "12345678901234567890", 10, S("abcde1234567890j")); + test(S("abcdefghij"), 5, 4, "12345678901234567890", 19, S("abcde1234567890123456789j")); + test(S("abcdefghij"), 5, 4, "12345678901234567890", 20, S("abcde12345678901234567890j")); + test(S("abcdefghij"), 5, 5, "", 0, S("abcde")); + test(S("abcdefghij"), 5, 5, "12345", 0, S("abcde")); + test(S("abcdefghij"), 5, 5, "12345", 1, S("abcde1")); + test(S("abcdefghij"), 5, 5, "12345", 2, S("abcde12")); + test(S("abcdefghij"), 5, 5, "12345", 4, S("abcde1234")); + test(S("abcdefghij"), 5, 5, "12345", 5, S("abcde12345")); + test(S("abcdefghij"), 5, 5, "1234567890", 0, S("abcde")); + test(S("abcdefghij"), 5, 5, "1234567890", 1, S("abcde1")); + test(S("abcdefghij"), 5, 5, "1234567890", 5, S("abcde12345")); + test(S("abcdefghij"), 5, 5, "1234567890", 9, S("abcde123456789")); + test(S("abcdefghij"), 5, 5, "1234567890", 10, S("abcde1234567890")); + test(S("abcdefghij"), 5, 5, "12345678901234567890", 0, S("abcde")); + test(S("abcdefghij"), 5, 5, "12345678901234567890", 1, S("abcde1")); + test(S("abcdefghij"), 5, 5, "12345678901234567890", 10, S("abcde1234567890")); + test(S("abcdefghij"), 5, 5, "12345678901234567890", 19, S("abcde1234567890123456789")); + test(S("abcdefghij"), 5, 5, "12345678901234567890", 20, S("abcde12345678901234567890")); + test(S("abcdefghij"), 5, 6, "", 0, S("abcde")); + test(S("abcdefghij"), 5, 6, "12345", 0, S("abcde")); + test(S("abcdefghij"), 5, 6, "12345", 1, S("abcde1")); + test(S("abcdefghij"), 5, 6, "12345", 2, S("abcde12")); + test(S("abcdefghij"), 5, 6, "12345", 4, S("abcde1234")); + test(S("abcdefghij"), 5, 6, "12345", 5, S("abcde12345")); + test(S("abcdefghij"), 5, 6, "1234567890", 0, S("abcde")); + test(S("abcdefghij"), 5, 6, "1234567890", 1, S("abcde1")); + test(S("abcdefghij"), 5, 6, "1234567890", 5, S("abcde12345")); + test(S("abcdefghij"), 5, 6, "1234567890", 9, S("abcde123456789")); + test(S("abcdefghij"), 5, 6, "1234567890", 10, S("abcde1234567890")); + test(S("abcdefghij"), 5, 6, "12345678901234567890", 0, S("abcde")); +} + +template +void test7() +{ + test(S("abcdefghij"), 5, 6, "12345678901234567890", 1, S("abcde1")); + test(S("abcdefghij"), 5, 6, "12345678901234567890", 10, S("abcde1234567890")); + test(S("abcdefghij"), 5, 6, "12345678901234567890", 19, S("abcde1234567890123456789")); + test(S("abcdefghij"), 5, 6, "12345678901234567890", 20, S("abcde12345678901234567890")); + test(S("abcdefghij"), 9, 0, "", 0, S("abcdefghij")); + test(S("abcdefghij"), 9, 0, "12345", 0, S("abcdefghij")); + test(S("abcdefghij"), 9, 0, "12345", 1, S("abcdefghi1j")); + test(S("abcdefghij"), 9, 0, "12345", 2, S("abcdefghi12j")); + test(S("abcdefghij"), 9, 0, "12345", 4, S("abcdefghi1234j")); + test(S("abcdefghij"), 9, 0, "12345", 5, S("abcdefghi12345j")); + test(S("abcdefghij"), 9, 0, "1234567890", 0, S("abcdefghij")); + test(S("abcdefghij"), 9, 0, "1234567890", 1, S("abcdefghi1j")); + test(S("abcdefghij"), 9, 0, "1234567890", 5, S("abcdefghi12345j")); + test(S("abcdefghij"), 9, 0, "1234567890", 9, S("abcdefghi123456789j")); + test(S("abcdefghij"), 9, 0, "1234567890", 10, S("abcdefghi1234567890j")); + test(S("abcdefghij"), 9, 0, "12345678901234567890", 0, S("abcdefghij")); + test(S("abcdefghij"), 9, 0, "12345678901234567890", 1, S("abcdefghi1j")); + test(S("abcdefghij"), 9, 0, "12345678901234567890", 10, S("abcdefghi1234567890j")); + test(S("abcdefghij"), 9, 0, "12345678901234567890", 19, S("abcdefghi1234567890123456789j")); + test(S("abcdefghij"), 9, 0, "12345678901234567890", 20, S("abcdefghi12345678901234567890j")); + test(S("abcdefghij"), 9, 1, "", 0, S("abcdefghi")); + test(S("abcdefghij"), 9, 1, "12345", 0, S("abcdefghi")); + test(S("abcdefghij"), 9, 1, "12345", 1, S("abcdefghi1")); + test(S("abcdefghij"), 9, 1, "12345", 2, S("abcdefghi12")); + test(S("abcdefghij"), 9, 1, "12345", 4, S("abcdefghi1234")); + test(S("abcdefghij"), 9, 1, "12345", 5, S("abcdefghi12345")); + test(S("abcdefghij"), 9, 1, "1234567890", 0, S("abcdefghi")); + test(S("abcdefghij"), 9, 1, "1234567890", 1, S("abcdefghi1")); + test(S("abcdefghij"), 9, 1, "1234567890", 5, S("abcdefghi12345")); + test(S("abcdefghij"), 9, 1, "1234567890", 9, S("abcdefghi123456789")); + test(S("abcdefghij"), 9, 1, "1234567890", 10, S("abcdefghi1234567890")); + test(S("abcdefghij"), 9, 1, "12345678901234567890", 0, S("abcdefghi")); + test(S("abcdefghij"), 9, 1, "12345678901234567890", 1, S("abcdefghi1")); + test(S("abcdefghij"), 9, 1, "12345678901234567890", 10, S("abcdefghi1234567890")); + test(S("abcdefghij"), 9, 1, "12345678901234567890", 19, S("abcdefghi1234567890123456789")); + test(S("abcdefghij"), 9, 1, "12345678901234567890", 20, S("abcdefghi12345678901234567890")); + test(S("abcdefghij"), 9, 2, "", 0, S("abcdefghi")); + test(S("abcdefghij"), 9, 2, "12345", 0, S("abcdefghi")); + test(S("abcdefghij"), 9, 2, "12345", 1, S("abcdefghi1")); + test(S("abcdefghij"), 9, 2, "12345", 2, S("abcdefghi12")); + test(S("abcdefghij"), 9, 2, "12345", 4, S("abcdefghi1234")); + test(S("abcdefghij"), 9, 2, "12345", 5, S("abcdefghi12345")); + test(S("abcdefghij"), 9, 2, "1234567890", 0, S("abcdefghi")); + test(S("abcdefghij"), 9, 2, "1234567890", 1, S("abcdefghi1")); + test(S("abcdefghij"), 9, 2, "1234567890", 5, S("abcdefghi12345")); + test(S("abcdefghij"), 9, 2, "1234567890", 9, S("abcdefghi123456789")); + test(S("abcdefghij"), 9, 2, "1234567890", 10, S("abcdefghi1234567890")); + test(S("abcdefghij"), 9, 2, "12345678901234567890", 0, S("abcdefghi")); + test(S("abcdefghij"), 9, 2, "12345678901234567890", 1, S("abcdefghi1")); + test(S("abcdefghij"), 9, 2, "12345678901234567890", 10, S("abcdefghi1234567890")); + test(S("abcdefghij"), 9, 2, "12345678901234567890", 19, S("abcdefghi1234567890123456789")); + test(S("abcdefghij"), 9, 2, "12345678901234567890", 20, S("abcdefghi12345678901234567890")); + test(S("abcdefghij"), 10, 0, "", 0, S("abcdefghij")); + test(S("abcdefghij"), 10, 0, "12345", 0, S("abcdefghij")); + test(S("abcdefghij"), 10, 0, "12345", 1, S("abcdefghij1")); + test(S("abcdefghij"), 10, 0, "12345", 2, S("abcdefghij12")); + test(S("abcdefghij"), 10, 0, "12345", 4, S("abcdefghij1234")); + test(S("abcdefghij"), 10, 0, "12345", 5, S("abcdefghij12345")); + test(S("abcdefghij"), 10, 0, "1234567890", 0, S("abcdefghij")); + test(S("abcdefghij"), 10, 0, "1234567890", 1, S("abcdefghij1")); + test(S("abcdefghij"), 10, 0, "1234567890", 5, S("abcdefghij12345")); + test(S("abcdefghij"), 10, 0, "1234567890", 9, S("abcdefghij123456789")); + test(S("abcdefghij"), 10, 0, "1234567890", 10, S("abcdefghij1234567890")); + test(S("abcdefghij"), 10, 0, "12345678901234567890", 0, S("abcdefghij")); + test(S("abcdefghij"), 10, 0, "12345678901234567890", 1, S("abcdefghij1")); + test(S("abcdefghij"), 10, 0, "12345678901234567890", 10, S("abcdefghij1234567890")); + test(S("abcdefghij"), 10, 0, "12345678901234567890", 19, S("abcdefghij1234567890123456789")); + test(S("abcdefghij"), 10, 0, "12345678901234567890", 20, S("abcdefghij12345678901234567890")); + test(S("abcdefghij"), 10, 1, "", 0, S("abcdefghij")); + test(S("abcdefghij"), 10, 1, "12345", 0, S("abcdefghij")); + test(S("abcdefghij"), 10, 1, "12345", 1, S("abcdefghij1")); + test(S("abcdefghij"), 10, 1, "12345", 2, S("abcdefghij12")); + test(S("abcdefghij"), 10, 1, "12345", 4, S("abcdefghij1234")); + test(S("abcdefghij"), 10, 1, "12345", 5, S("abcdefghij12345")); + test(S("abcdefghij"), 10, 1, "1234567890", 0, S("abcdefghij")); + test(S("abcdefghij"), 10, 1, "1234567890", 1, S("abcdefghij1")); + test(S("abcdefghij"), 10, 1, "1234567890", 5, S("abcdefghij12345")); + test(S("abcdefghij"), 10, 1, "1234567890", 9, S("abcdefghij123456789")); + test(S("abcdefghij"), 10, 1, "1234567890", 10, S("abcdefghij1234567890")); + test(S("abcdefghij"), 10, 1, "12345678901234567890", 0, S("abcdefghij")); + test(S("abcdefghij"), 10, 1, "12345678901234567890", 1, S("abcdefghij1")); + test(S("abcdefghij"), 10, 1, "12345678901234567890", 10, S("abcdefghij1234567890")); + test(S("abcdefghij"), 10, 1, "12345678901234567890", 19, S("abcdefghij1234567890123456789")); + test(S("abcdefghij"), 10, 1, "12345678901234567890", 20, S("abcdefghij12345678901234567890")); + test(S("abcdefghij"), 11, 0, "", 0, S("can't happen")); + test(S("abcdefghij"), 11, 0, "12345", 0, S("can't happen")); + test(S("abcdefghij"), 11, 0, "12345", 1, S("can't happen")); + test(S("abcdefghij"), 11, 0, "12345", 2, S("can't happen")); + test(S("abcdefghij"), 11, 0, "12345", 4, S("can't happen")); + test(S("abcdefghij"), 11, 0, "12345", 5, S("can't happen")); + test(S("abcdefghij"), 11, 0, "1234567890", 0, S("can't happen")); + test(S("abcdefghij"), 11, 0, "1234567890", 1, S("can't happen")); + test(S("abcdefghij"), 11, 0, "1234567890", 5, S("can't happen")); + test(S("abcdefghij"), 11, 0, "1234567890", 9, S("can't happen")); + test(S("abcdefghij"), 11, 0, "1234567890", 10, S("can't happen")); + test(S("abcdefghij"), 11, 0, "12345678901234567890", 0, S("can't happen")); + test(S("abcdefghij"), 11, 0, "12345678901234567890", 1, S("can't happen")); + test(S("abcdefghij"), 11, 0, "12345678901234567890", 10, S("can't happen")); + test(S("abcdefghij"), 11, 0, "12345678901234567890", 19, S("can't happen")); + test(S("abcdefghij"), 11, 0, "12345678901234567890", 20, S("can't happen")); +} + +template +void test8() +{ + test(S("abcdefghijklmnopqrst"), 0, 0, "", 0, S("abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, 0, "12345", 0, S("abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, 0, "12345", 1, S("1abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, 0, "12345", 2, S("12abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, 0, "12345", 4, S("1234abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, 0, "12345", 5, S("12345abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, 0, "1234567890", 0, S("abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, 0, "1234567890", 1, S("1abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, 0, "1234567890", 5, S("12345abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, 0, "1234567890", 9, S("123456789abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, 0, "1234567890", 10, S("1234567890abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, 0, "12345678901234567890", 0, S("abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, 0, "12345678901234567890", 1, S("1abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, 0, "12345678901234567890", 10, S("1234567890abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, 0, "12345678901234567890", 19, S("1234567890123456789abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, 0, "12345678901234567890", 20, S("12345678901234567890abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, 1, "", 0, S("bcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, 1, "12345", 0, S("bcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, 1, "12345", 1, S("1bcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, 1, "12345", 2, S("12bcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, 1, "12345", 4, S("1234bcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, 1, "12345", 5, S("12345bcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, 1, "1234567890", 0, S("bcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, 1, "1234567890", 1, S("1bcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, 1, "1234567890", 5, S("12345bcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, 1, "1234567890", 9, S("123456789bcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, 1, "1234567890", 10, S("1234567890bcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, 1, "12345678901234567890", 0, S("bcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, 1, "12345678901234567890", 1, S("1bcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, 1, "12345678901234567890", 10, S("1234567890bcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, 1, "12345678901234567890", 19, S("1234567890123456789bcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, 1, "12345678901234567890", 20, S("12345678901234567890bcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, 10, "", 0, S("klmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, 10, "12345", 0, S("klmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, 10, "12345", 1, S("1klmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, 10, "12345", 2, S("12klmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, 10, "12345", 4, S("1234klmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, 10, "12345", 5, S("12345klmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, 10, "1234567890", 0, S("klmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, 10, "1234567890", 1, S("1klmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, 10, "1234567890", 5, S("12345klmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, 10, "1234567890", 9, S("123456789klmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, 10, "1234567890", 10, S("1234567890klmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, 10, "12345678901234567890", 0, S("klmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, 10, "12345678901234567890", 1, S("1klmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, 10, "12345678901234567890", 10, S("1234567890klmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, 10, "12345678901234567890", 19, S("1234567890123456789klmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, 10, "12345678901234567890", 20, S("12345678901234567890klmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, 19, "", 0, S("t")); + test(S("abcdefghijklmnopqrst"), 0, 19, "12345", 0, S("t")); + test(S("abcdefghijklmnopqrst"), 0, 19, "12345", 1, S("1t")); + test(S("abcdefghijklmnopqrst"), 0, 19, "12345", 2, S("12t")); + test(S("abcdefghijklmnopqrst"), 0, 19, "12345", 4, S("1234t")); + test(S("abcdefghijklmnopqrst"), 0, 19, "12345", 5, S("12345t")); + test(S("abcdefghijklmnopqrst"), 0, 19, "1234567890", 0, S("t")); + test(S("abcdefghijklmnopqrst"), 0, 19, "1234567890", 1, S("1t")); + test(S("abcdefghijklmnopqrst"), 0, 19, "1234567890", 5, S("12345t")); + test(S("abcdefghijklmnopqrst"), 0, 19, "1234567890", 9, S("123456789t")); + test(S("abcdefghijklmnopqrst"), 0, 19, "1234567890", 10, S("1234567890t")); + test(S("abcdefghijklmnopqrst"), 0, 19, "12345678901234567890", 0, S("t")); + test(S("abcdefghijklmnopqrst"), 0, 19, "12345678901234567890", 1, S("1t")); + test(S("abcdefghijklmnopqrst"), 0, 19, "12345678901234567890", 10, S("1234567890t")); + test(S("abcdefghijklmnopqrst"), 0, 19, "12345678901234567890", 19, S("1234567890123456789t")); + test(S("abcdefghijklmnopqrst"), 0, 19, "12345678901234567890", 20, S("12345678901234567890t")); + test(S("abcdefghijklmnopqrst"), 0, 20, "", 0, S("")); + test(S("abcdefghijklmnopqrst"), 0, 20, "12345", 0, S("")); + test(S("abcdefghijklmnopqrst"), 0, 20, "12345", 1, S("1")); + test(S("abcdefghijklmnopqrst"), 0, 20, "12345", 2, S("12")); + test(S("abcdefghijklmnopqrst"), 0, 20, "12345", 4, S("1234")); + test(S("abcdefghijklmnopqrst"), 0, 20, "12345", 5, S("12345")); + test(S("abcdefghijklmnopqrst"), 0, 20, "1234567890", 0, S("")); + test(S("abcdefghijklmnopqrst"), 0, 20, "1234567890", 1, S("1")); + test(S("abcdefghijklmnopqrst"), 0, 20, "1234567890", 5, S("12345")); + test(S("abcdefghijklmnopqrst"), 0, 20, "1234567890", 9, S("123456789")); + test(S("abcdefghijklmnopqrst"), 0, 20, "1234567890", 10, S("1234567890")); + test(S("abcdefghijklmnopqrst"), 0, 20, "12345678901234567890", 0, S("")); + test(S("abcdefghijklmnopqrst"), 0, 20, "12345678901234567890", 1, S("1")); + test(S("abcdefghijklmnopqrst"), 0, 20, "12345678901234567890", 10, S("1234567890")); + test(S("abcdefghijklmnopqrst"), 0, 20, "12345678901234567890", 19, S("1234567890123456789")); + test(S("abcdefghijklmnopqrst"), 0, 20, "12345678901234567890", 20, S("12345678901234567890")); + test(S("abcdefghijklmnopqrst"), 0, 21, "", 0, S("")); + test(S("abcdefghijklmnopqrst"), 0, 21, "12345", 0, S("")); + test(S("abcdefghijklmnopqrst"), 0, 21, "12345", 1, S("1")); + test(S("abcdefghijklmnopqrst"), 0, 21, "12345", 2, S("12")); + test(S("abcdefghijklmnopqrst"), 0, 21, "12345", 4, S("1234")); + test(S("abcdefghijklmnopqrst"), 0, 21, "12345", 5, S("12345")); + test(S("abcdefghijklmnopqrst"), 0, 21, "1234567890", 0, S("")); + test(S("abcdefghijklmnopqrst"), 0, 21, "1234567890", 1, S("1")); + test(S("abcdefghijklmnopqrst"), 0, 21, "1234567890", 5, S("12345")); + test(S("abcdefghijklmnopqrst"), 0, 21, "1234567890", 9, S("123456789")); + test(S("abcdefghijklmnopqrst"), 0, 21, "1234567890", 10, S("1234567890")); + test(S("abcdefghijklmnopqrst"), 0, 21, "12345678901234567890", 0, S("")); + test(S("abcdefghijklmnopqrst"), 0, 21, "12345678901234567890", 1, S("1")); + test(S("abcdefghijklmnopqrst"), 0, 21, "12345678901234567890", 10, S("1234567890")); + test(S("abcdefghijklmnopqrst"), 0, 21, "12345678901234567890", 19, S("1234567890123456789")); + test(S("abcdefghijklmnopqrst"), 0, 21, "12345678901234567890", 20, S("12345678901234567890")); + test(S("abcdefghijklmnopqrst"), 1, 0, "", 0, S("abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, 0, "12345", 0, S("abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, 0, "12345", 1, S("a1bcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, 0, "12345", 2, S("a12bcdefghijklmnopqrst")); +} + +template +void test9() +{ + test(S("abcdefghijklmnopqrst"), 1, 0, "12345", 4, S("a1234bcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, 0, "12345", 5, S("a12345bcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, 0, "1234567890", 0, S("abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, 0, "1234567890", 1, S("a1bcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, 0, "1234567890", 5, S("a12345bcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, 0, "1234567890", 9, S("a123456789bcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, 0, "1234567890", 10, S("a1234567890bcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, 0, "12345678901234567890", 0, S("abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, 0, "12345678901234567890", 1, S("a1bcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, 0, "12345678901234567890", 10, S("a1234567890bcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, 0, "12345678901234567890", 19, S("a1234567890123456789bcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, 0, "12345678901234567890", 20, S("a12345678901234567890bcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, 1, "", 0, S("acdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, 1, "12345", 0, S("acdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, 1, "12345", 1, S("a1cdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, 1, "12345", 2, S("a12cdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, 1, "12345", 4, S("a1234cdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, 1, "12345", 5, S("a12345cdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, 1, "1234567890", 0, S("acdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, 1, "1234567890", 1, S("a1cdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, 1, "1234567890", 5, S("a12345cdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, 1, "1234567890", 9, S("a123456789cdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, 1, "1234567890", 10, S("a1234567890cdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, 1, "12345678901234567890", 0, S("acdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, 1, "12345678901234567890", 1, S("a1cdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, 1, "12345678901234567890", 10, S("a1234567890cdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, 1, "12345678901234567890", 19, S("a1234567890123456789cdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, 1, "12345678901234567890", 20, S("a12345678901234567890cdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, 9, "", 0, S("aklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, 9, "12345", 0, S("aklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, 9, "12345", 1, S("a1klmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, 9, "12345", 2, S("a12klmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, 9, "12345", 4, S("a1234klmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, 9, "12345", 5, S("a12345klmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, 9, "1234567890", 0, S("aklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, 9, "1234567890", 1, S("a1klmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, 9, "1234567890", 5, S("a12345klmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, 9, "1234567890", 9, S("a123456789klmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, 9, "1234567890", 10, S("a1234567890klmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, 9, "12345678901234567890", 0, S("aklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, 9, "12345678901234567890", 1, S("a1klmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, 9, "12345678901234567890", 10, S("a1234567890klmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, 9, "12345678901234567890", 19, S("a1234567890123456789klmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, 9, "12345678901234567890", 20, S("a12345678901234567890klmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, 18, "", 0, S("at")); + test(S("abcdefghijklmnopqrst"), 1, 18, "12345", 0, S("at")); + test(S("abcdefghijklmnopqrst"), 1, 18, "12345", 1, S("a1t")); + test(S("abcdefghijklmnopqrst"), 1, 18, "12345", 2, S("a12t")); + test(S("abcdefghijklmnopqrst"), 1, 18, "12345", 4, S("a1234t")); + test(S("abcdefghijklmnopqrst"), 1, 18, "12345", 5, S("a12345t")); + test(S("abcdefghijklmnopqrst"), 1, 18, "1234567890", 0, S("at")); + test(S("abcdefghijklmnopqrst"), 1, 18, "1234567890", 1, S("a1t")); + test(S("abcdefghijklmnopqrst"), 1, 18, "1234567890", 5, S("a12345t")); + test(S("abcdefghijklmnopqrst"), 1, 18, "1234567890", 9, S("a123456789t")); + test(S("abcdefghijklmnopqrst"), 1, 18, "1234567890", 10, S("a1234567890t")); + test(S("abcdefghijklmnopqrst"), 1, 18, "12345678901234567890", 0, S("at")); + test(S("abcdefghijklmnopqrst"), 1, 18, "12345678901234567890", 1, S("a1t")); + test(S("abcdefghijklmnopqrst"), 1, 18, "12345678901234567890", 10, S("a1234567890t")); + test(S("abcdefghijklmnopqrst"), 1, 18, "12345678901234567890", 19, S("a1234567890123456789t")); + test(S("abcdefghijklmnopqrst"), 1, 18, "12345678901234567890", 20, S("a12345678901234567890t")); + test(S("abcdefghijklmnopqrst"), 1, 19, "", 0, S("a")); + test(S("abcdefghijklmnopqrst"), 1, 19, "12345", 0, S("a")); + test(S("abcdefghijklmnopqrst"), 1, 19, "12345", 1, S("a1")); + test(S("abcdefghijklmnopqrst"), 1, 19, "12345", 2, S("a12")); + test(S("abcdefghijklmnopqrst"), 1, 19, "12345", 4, S("a1234")); + test(S("abcdefghijklmnopqrst"), 1, 19, "12345", 5, S("a12345")); + test(S("abcdefghijklmnopqrst"), 1, 19, "1234567890", 0, S("a")); + test(S("abcdefghijklmnopqrst"), 1, 19, "1234567890", 1, S("a1")); + test(S("abcdefghijklmnopqrst"), 1, 19, "1234567890", 5, S("a12345")); + test(S("abcdefghijklmnopqrst"), 1, 19, "1234567890", 9, S("a123456789")); + test(S("abcdefghijklmnopqrst"), 1, 19, "1234567890", 10, S("a1234567890")); + test(S("abcdefghijklmnopqrst"), 1, 19, "12345678901234567890", 0, S("a")); + test(S("abcdefghijklmnopqrst"), 1, 19, "12345678901234567890", 1, S("a1")); + test(S("abcdefghijklmnopqrst"), 1, 19, "12345678901234567890", 10, S("a1234567890")); + test(S("abcdefghijklmnopqrst"), 1, 19, "12345678901234567890", 19, S("a1234567890123456789")); + test(S("abcdefghijklmnopqrst"), 1, 19, "12345678901234567890", 20, S("a12345678901234567890")); + test(S("abcdefghijklmnopqrst"), 1, 20, "", 0, S("a")); + test(S("abcdefghijklmnopqrst"), 1, 20, "12345", 0, S("a")); + test(S("abcdefghijklmnopqrst"), 1, 20, "12345", 1, S("a1")); + test(S("abcdefghijklmnopqrst"), 1, 20, "12345", 2, S("a12")); + test(S("abcdefghijklmnopqrst"), 1, 20, "12345", 4, S("a1234")); + test(S("abcdefghijklmnopqrst"), 1, 20, "12345", 5, S("a12345")); + test(S("abcdefghijklmnopqrst"), 1, 20, "1234567890", 0, S("a")); + test(S("abcdefghijklmnopqrst"), 1, 20, "1234567890", 1, S("a1")); + test(S("abcdefghijklmnopqrst"), 1, 20, "1234567890", 5, S("a12345")); + test(S("abcdefghijklmnopqrst"), 1, 20, "1234567890", 9, S("a123456789")); + test(S("abcdefghijklmnopqrst"), 1, 20, "1234567890", 10, S("a1234567890")); + test(S("abcdefghijklmnopqrst"), 1, 20, "12345678901234567890", 0, S("a")); + test(S("abcdefghijklmnopqrst"), 1, 20, "12345678901234567890", 1, S("a1")); + test(S("abcdefghijklmnopqrst"), 1, 20, "12345678901234567890", 10, S("a1234567890")); + test(S("abcdefghijklmnopqrst"), 1, 20, "12345678901234567890", 19, S("a1234567890123456789")); + test(S("abcdefghijklmnopqrst"), 1, 20, "12345678901234567890", 20, S("a12345678901234567890")); + test(S("abcdefghijklmnopqrst"), 10, 0, "", 0, S("abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 10, 0, "12345", 0, S("abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 10, 0, "12345", 1, S("abcdefghij1klmnopqrst")); + test(S("abcdefghijklmnopqrst"), 10, 0, "12345", 2, S("abcdefghij12klmnopqrst")); + test(S("abcdefghijklmnopqrst"), 10, 0, "12345", 4, S("abcdefghij1234klmnopqrst")); + test(S("abcdefghijklmnopqrst"), 10, 0, "12345", 5, S("abcdefghij12345klmnopqrst")); + test(S("abcdefghijklmnopqrst"), 10, 0, "1234567890", 0, S("abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 10, 0, "1234567890", 1, S("abcdefghij1klmnopqrst")); +} + +template +void test10() +{ + test(S("abcdefghijklmnopqrst"), 10, 0, "1234567890", 5, S("abcdefghij12345klmnopqrst")); + test(S("abcdefghijklmnopqrst"), 10, 0, "1234567890", 9, S("abcdefghij123456789klmnopqrst")); + test(S("abcdefghijklmnopqrst"), 10, 0, "1234567890", 10, S("abcdefghij1234567890klmnopqrst")); + test(S("abcdefghijklmnopqrst"), 10, 0, "12345678901234567890", 0, S("abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 10, 0, "12345678901234567890", 1, S("abcdefghij1klmnopqrst")); + test(S("abcdefghijklmnopqrst"), 10, 0, "12345678901234567890", 10, S("abcdefghij1234567890klmnopqrst")); + test(S("abcdefghijklmnopqrst"), 10, 0, "12345678901234567890", 19, S("abcdefghij1234567890123456789klmnopqrst")); + test(S("abcdefghijklmnopqrst"), 10, 0, "12345678901234567890", 20, S("abcdefghij12345678901234567890klmnopqrst")); + test(S("abcdefghijklmnopqrst"), 10, 1, "", 0, S("abcdefghijlmnopqrst")); + test(S("abcdefghijklmnopqrst"), 10, 1, "12345", 0, S("abcdefghijlmnopqrst")); + test(S("abcdefghijklmnopqrst"), 10, 1, "12345", 1, S("abcdefghij1lmnopqrst")); + test(S("abcdefghijklmnopqrst"), 10, 1, "12345", 2, S("abcdefghij12lmnopqrst")); + test(S("abcdefghijklmnopqrst"), 10, 1, "12345", 4, S("abcdefghij1234lmnopqrst")); + test(S("abcdefghijklmnopqrst"), 10, 1, "12345", 5, S("abcdefghij12345lmnopqrst")); + test(S("abcdefghijklmnopqrst"), 10, 1, "1234567890", 0, S("abcdefghijlmnopqrst")); + test(S("abcdefghijklmnopqrst"), 10, 1, "1234567890", 1, S("abcdefghij1lmnopqrst")); + test(S("abcdefghijklmnopqrst"), 10, 1, "1234567890", 5, S("abcdefghij12345lmnopqrst")); + test(S("abcdefghijklmnopqrst"), 10, 1, "1234567890", 9, S("abcdefghij123456789lmnopqrst")); + test(S("abcdefghijklmnopqrst"), 10, 1, "1234567890", 10, S("abcdefghij1234567890lmnopqrst")); + test(S("abcdefghijklmnopqrst"), 10, 1, "12345678901234567890", 0, S("abcdefghijlmnopqrst")); + test(S("abcdefghijklmnopqrst"), 10, 1, "12345678901234567890", 1, S("abcdefghij1lmnopqrst")); + test(S("abcdefghijklmnopqrst"), 10, 1, "12345678901234567890", 10, S("abcdefghij1234567890lmnopqrst")); + test(S("abcdefghijklmnopqrst"), 10, 1, "12345678901234567890", 19, S("abcdefghij1234567890123456789lmnopqrst")); + test(S("abcdefghijklmnopqrst"), 10, 1, "12345678901234567890", 20, S("abcdefghij12345678901234567890lmnopqrst")); + test(S("abcdefghijklmnopqrst"), 10, 5, "", 0, S("abcdefghijpqrst")); + test(S("abcdefghijklmnopqrst"), 10, 5, "12345", 0, S("abcdefghijpqrst")); + test(S("abcdefghijklmnopqrst"), 10, 5, "12345", 1, S("abcdefghij1pqrst")); + test(S("abcdefghijklmnopqrst"), 10, 5, "12345", 2, S("abcdefghij12pqrst")); + test(S("abcdefghijklmnopqrst"), 10, 5, "12345", 4, S("abcdefghij1234pqrst")); + test(S("abcdefghijklmnopqrst"), 10, 5, "12345", 5, S("abcdefghij12345pqrst")); + test(S("abcdefghijklmnopqrst"), 10, 5, "1234567890", 0, S("abcdefghijpqrst")); + test(S("abcdefghijklmnopqrst"), 10, 5, "1234567890", 1, S("abcdefghij1pqrst")); + test(S("abcdefghijklmnopqrst"), 10, 5, "1234567890", 5, S("abcdefghij12345pqrst")); + test(S("abcdefghijklmnopqrst"), 10, 5, "1234567890", 9, S("abcdefghij123456789pqrst")); + test(S("abcdefghijklmnopqrst"), 10, 5, "1234567890", 10, S("abcdefghij1234567890pqrst")); + test(S("abcdefghijklmnopqrst"), 10, 5, "12345678901234567890", 0, S("abcdefghijpqrst")); + test(S("abcdefghijklmnopqrst"), 10, 5, "12345678901234567890", 1, S("abcdefghij1pqrst")); + test(S("abcdefghijklmnopqrst"), 10, 5, "12345678901234567890", 10, S("abcdefghij1234567890pqrst")); + test(S("abcdefghijklmnopqrst"), 10, 5, "12345678901234567890", 19, S("abcdefghij1234567890123456789pqrst")); + test(S("abcdefghijklmnopqrst"), 10, 5, "12345678901234567890", 20, S("abcdefghij12345678901234567890pqrst")); + test(S("abcdefghijklmnopqrst"), 10, 9, "", 0, S("abcdefghijt")); + test(S("abcdefghijklmnopqrst"), 10, 9, "12345", 0, S("abcdefghijt")); + test(S("abcdefghijklmnopqrst"), 10, 9, "12345", 1, S("abcdefghij1t")); + test(S("abcdefghijklmnopqrst"), 10, 9, "12345", 2, S("abcdefghij12t")); + test(S("abcdefghijklmnopqrst"), 10, 9, "12345", 4, S("abcdefghij1234t")); + test(S("abcdefghijklmnopqrst"), 10, 9, "12345", 5, S("abcdefghij12345t")); + test(S("abcdefghijklmnopqrst"), 10, 9, "1234567890", 0, S("abcdefghijt")); + test(S("abcdefghijklmnopqrst"), 10, 9, "1234567890", 1, S("abcdefghij1t")); + test(S("abcdefghijklmnopqrst"), 10, 9, "1234567890", 5, S("abcdefghij12345t")); + test(S("abcdefghijklmnopqrst"), 10, 9, "1234567890", 9, S("abcdefghij123456789t")); + test(S("abcdefghijklmnopqrst"), 10, 9, "1234567890", 10, S("abcdefghij1234567890t")); + test(S("abcdefghijklmnopqrst"), 10, 9, "12345678901234567890", 0, S("abcdefghijt")); + test(S("abcdefghijklmnopqrst"), 10, 9, "12345678901234567890", 1, S("abcdefghij1t")); + test(S("abcdefghijklmnopqrst"), 10, 9, "12345678901234567890", 10, S("abcdefghij1234567890t")); + test(S("abcdefghijklmnopqrst"), 10, 9, "12345678901234567890", 19, S("abcdefghij1234567890123456789t")); + test(S("abcdefghijklmnopqrst"), 10, 9, "12345678901234567890", 20, S("abcdefghij12345678901234567890t")); + test(S("abcdefghijklmnopqrst"), 10, 10, "", 0, S("abcdefghij")); + test(S("abcdefghijklmnopqrst"), 10, 10, "12345", 0, S("abcdefghij")); + test(S("abcdefghijklmnopqrst"), 10, 10, "12345", 1, S("abcdefghij1")); + test(S("abcdefghijklmnopqrst"), 10, 10, "12345", 2, S("abcdefghij12")); + test(S("abcdefghijklmnopqrst"), 10, 10, "12345", 4, S("abcdefghij1234")); + test(S("abcdefghijklmnopqrst"), 10, 10, "12345", 5, S("abcdefghij12345")); + test(S("abcdefghijklmnopqrst"), 10, 10, "1234567890", 0, S("abcdefghij")); + test(S("abcdefghijklmnopqrst"), 10, 10, "1234567890", 1, S("abcdefghij1")); + test(S("abcdefghijklmnopqrst"), 10, 10, "1234567890", 5, S("abcdefghij12345")); + test(S("abcdefghijklmnopqrst"), 10, 10, "1234567890", 9, S("abcdefghij123456789")); + test(S("abcdefghijklmnopqrst"), 10, 10, "1234567890", 10, S("abcdefghij1234567890")); + test(S("abcdefghijklmnopqrst"), 10, 10, "12345678901234567890", 0, S("abcdefghij")); + test(S("abcdefghijklmnopqrst"), 10, 10, "12345678901234567890", 1, S("abcdefghij1")); + test(S("abcdefghijklmnopqrst"), 10, 10, "12345678901234567890", 10, S("abcdefghij1234567890")); + test(S("abcdefghijklmnopqrst"), 10, 10, "12345678901234567890", 19, S("abcdefghij1234567890123456789")); + test(S("abcdefghijklmnopqrst"), 10, 10, "12345678901234567890", 20, S("abcdefghij12345678901234567890")); + test(S("abcdefghijklmnopqrst"), 10, 11, "", 0, S("abcdefghij")); + test(S("abcdefghijklmnopqrst"), 10, 11, "12345", 0, S("abcdefghij")); + test(S("abcdefghijklmnopqrst"), 10, 11, "12345", 1, S("abcdefghij1")); + test(S("abcdefghijklmnopqrst"), 10, 11, "12345", 2, S("abcdefghij12")); + test(S("abcdefghijklmnopqrst"), 10, 11, "12345", 4, S("abcdefghij1234")); + test(S("abcdefghijklmnopqrst"), 10, 11, "12345", 5, S("abcdefghij12345")); + test(S("abcdefghijklmnopqrst"), 10, 11, "1234567890", 0, S("abcdefghij")); + test(S("abcdefghijklmnopqrst"), 10, 11, "1234567890", 1, S("abcdefghij1")); + test(S("abcdefghijklmnopqrst"), 10, 11, "1234567890", 5, S("abcdefghij12345")); + test(S("abcdefghijklmnopqrst"), 10, 11, "1234567890", 9, S("abcdefghij123456789")); + test(S("abcdefghijklmnopqrst"), 10, 11, "1234567890", 10, S("abcdefghij1234567890")); + test(S("abcdefghijklmnopqrst"), 10, 11, "12345678901234567890", 0, S("abcdefghij")); + test(S("abcdefghijklmnopqrst"), 10, 11, "12345678901234567890", 1, S("abcdefghij1")); + test(S("abcdefghijklmnopqrst"), 10, 11, "12345678901234567890", 10, S("abcdefghij1234567890")); + test(S("abcdefghijklmnopqrst"), 10, 11, "12345678901234567890", 19, S("abcdefghij1234567890123456789")); + test(S("abcdefghijklmnopqrst"), 10, 11, "12345678901234567890", 20, S("abcdefghij12345678901234567890")); + test(S("abcdefghijklmnopqrst"), 19, 0, "", 0, S("abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 19, 0, "12345", 0, S("abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 19, 0, "12345", 1, S("abcdefghijklmnopqrs1t")); + test(S("abcdefghijklmnopqrst"), 19, 0, "12345", 2, S("abcdefghijklmnopqrs12t")); + test(S("abcdefghijklmnopqrst"), 19, 0, "12345", 4, S("abcdefghijklmnopqrs1234t")); + test(S("abcdefghijklmnopqrst"), 19, 0, "12345", 5, S("abcdefghijklmnopqrs12345t")); + test(S("abcdefghijklmnopqrst"), 19, 0, "1234567890", 0, S("abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 19, 0, "1234567890", 1, S("abcdefghijklmnopqrs1t")); + test(S("abcdefghijklmnopqrst"), 19, 0, "1234567890", 5, S("abcdefghijklmnopqrs12345t")); + test(S("abcdefghijklmnopqrst"), 19, 0, "1234567890", 9, S("abcdefghijklmnopqrs123456789t")); + test(S("abcdefghijklmnopqrst"), 19, 0, "1234567890", 10, S("abcdefghijklmnopqrs1234567890t")); + test(S("abcdefghijklmnopqrst"), 19, 0, "12345678901234567890", 0, S("abcdefghijklmnopqrst")); +} + +template +void test11() +{ + test(S("abcdefghijklmnopqrst"), 19, 0, "12345678901234567890", 1, S("abcdefghijklmnopqrs1t")); + test(S("abcdefghijklmnopqrst"), 19, 0, "12345678901234567890", 10, S("abcdefghijklmnopqrs1234567890t")); + test(S("abcdefghijklmnopqrst"), 19, 0, "12345678901234567890", 19, S("abcdefghijklmnopqrs1234567890123456789t")); + test(S("abcdefghijklmnopqrst"), 19, 0, "12345678901234567890", 20, S("abcdefghijklmnopqrs12345678901234567890t")); + test(S("abcdefghijklmnopqrst"), 19, 1, "", 0, S("abcdefghijklmnopqrs")); + test(S("abcdefghijklmnopqrst"), 19, 1, "12345", 0, S("abcdefghijklmnopqrs")); + test(S("abcdefghijklmnopqrst"), 19, 1, "12345", 1, S("abcdefghijklmnopqrs1")); + test(S("abcdefghijklmnopqrst"), 19, 1, "12345", 2, S("abcdefghijklmnopqrs12")); + test(S("abcdefghijklmnopqrst"), 19, 1, "12345", 4, S("abcdefghijklmnopqrs1234")); + test(S("abcdefghijklmnopqrst"), 19, 1, "12345", 5, S("abcdefghijklmnopqrs12345")); + test(S("abcdefghijklmnopqrst"), 19, 1, "1234567890", 0, S("abcdefghijklmnopqrs")); + test(S("abcdefghijklmnopqrst"), 19, 1, "1234567890", 1, S("abcdefghijklmnopqrs1")); + test(S("abcdefghijklmnopqrst"), 19, 1, "1234567890", 5, S("abcdefghijklmnopqrs12345")); + test(S("abcdefghijklmnopqrst"), 19, 1, "1234567890", 9, S("abcdefghijklmnopqrs123456789")); + test(S("abcdefghijklmnopqrst"), 19, 1, "1234567890", 10, S("abcdefghijklmnopqrs1234567890")); + test(S("abcdefghijklmnopqrst"), 19, 1, "12345678901234567890", 0, S("abcdefghijklmnopqrs")); + test(S("abcdefghijklmnopqrst"), 19, 1, "12345678901234567890", 1, S("abcdefghijklmnopqrs1")); + test(S("abcdefghijklmnopqrst"), 19, 1, "12345678901234567890", 10, S("abcdefghijklmnopqrs1234567890")); + test(S("abcdefghijklmnopqrst"), 19, 1, "12345678901234567890", 19, S("abcdefghijklmnopqrs1234567890123456789")); + test(S("abcdefghijklmnopqrst"), 19, 1, "12345678901234567890", 20, S("abcdefghijklmnopqrs12345678901234567890")); + test(S("abcdefghijklmnopqrst"), 19, 2, "", 0, S("abcdefghijklmnopqrs")); + test(S("abcdefghijklmnopqrst"), 19, 2, "12345", 0, S("abcdefghijklmnopqrs")); + test(S("abcdefghijklmnopqrst"), 19, 2, "12345", 1, S("abcdefghijklmnopqrs1")); + test(S("abcdefghijklmnopqrst"), 19, 2, "12345", 2, S("abcdefghijklmnopqrs12")); + test(S("abcdefghijklmnopqrst"), 19, 2, "12345", 4, S("abcdefghijklmnopqrs1234")); + test(S("abcdefghijklmnopqrst"), 19, 2, "12345", 5, S("abcdefghijklmnopqrs12345")); + test(S("abcdefghijklmnopqrst"), 19, 2, "1234567890", 0, S("abcdefghijklmnopqrs")); + test(S("abcdefghijklmnopqrst"), 19, 2, "1234567890", 1, S("abcdefghijklmnopqrs1")); + test(S("abcdefghijklmnopqrst"), 19, 2, "1234567890", 5, S("abcdefghijklmnopqrs12345")); + test(S("abcdefghijklmnopqrst"), 19, 2, "1234567890", 9, S("abcdefghijklmnopqrs123456789")); + test(S("abcdefghijklmnopqrst"), 19, 2, "1234567890", 10, S("abcdefghijklmnopqrs1234567890")); + test(S("abcdefghijklmnopqrst"), 19, 2, "12345678901234567890", 0, S("abcdefghijklmnopqrs")); + test(S("abcdefghijklmnopqrst"), 19, 2, "12345678901234567890", 1, S("abcdefghijklmnopqrs1")); + test(S("abcdefghijklmnopqrst"), 19, 2, "12345678901234567890", 10, S("abcdefghijklmnopqrs1234567890")); + test(S("abcdefghijklmnopqrst"), 19, 2, "12345678901234567890", 19, S("abcdefghijklmnopqrs1234567890123456789")); + test(S("abcdefghijklmnopqrst"), 19, 2, "12345678901234567890", 20, S("abcdefghijklmnopqrs12345678901234567890")); + test(S("abcdefghijklmnopqrst"), 20, 0, "", 0, S("abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 20, 0, "12345", 0, S("abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 20, 0, "12345", 1, S("abcdefghijklmnopqrst1")); + test(S("abcdefghijklmnopqrst"), 20, 0, "12345", 2, S("abcdefghijklmnopqrst12")); + test(S("abcdefghijklmnopqrst"), 20, 0, "12345", 4, S("abcdefghijklmnopqrst1234")); + test(S("abcdefghijklmnopqrst"), 20, 0, "12345", 5, S("abcdefghijklmnopqrst12345")); + test(S("abcdefghijklmnopqrst"), 20, 0, "1234567890", 0, S("abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 20, 0, "1234567890", 1, S("abcdefghijklmnopqrst1")); + test(S("abcdefghijklmnopqrst"), 20, 0, "1234567890", 5, S("abcdefghijklmnopqrst12345")); + test(S("abcdefghijklmnopqrst"), 20, 0, "1234567890", 9, S("abcdefghijklmnopqrst123456789")); + test(S("abcdefghijklmnopqrst"), 20, 0, "1234567890", 10, S("abcdefghijklmnopqrst1234567890")); + test(S("abcdefghijklmnopqrst"), 20, 0, "12345678901234567890", 0, S("abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 20, 0, "12345678901234567890", 1, S("abcdefghijklmnopqrst1")); + test(S("abcdefghijklmnopqrst"), 20, 0, "12345678901234567890", 10, S("abcdefghijklmnopqrst1234567890")); + test(S("abcdefghijklmnopqrst"), 20, 0, "12345678901234567890", 19, S("abcdefghijklmnopqrst1234567890123456789")); + test(S("abcdefghijklmnopqrst"), 20, 0, "12345678901234567890", 20, S("abcdefghijklmnopqrst12345678901234567890")); + test(S("abcdefghijklmnopqrst"), 20, 1, "", 0, S("abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 20, 1, "12345", 0, S("abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 20, 1, "12345", 1, S("abcdefghijklmnopqrst1")); + test(S("abcdefghijklmnopqrst"), 20, 1, "12345", 2, S("abcdefghijklmnopqrst12")); + test(S("abcdefghijklmnopqrst"), 20, 1, "12345", 4, S("abcdefghijklmnopqrst1234")); + test(S("abcdefghijklmnopqrst"), 20, 1, "12345", 5, S("abcdefghijklmnopqrst12345")); + test(S("abcdefghijklmnopqrst"), 20, 1, "1234567890", 0, S("abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 20, 1, "1234567890", 1, S("abcdefghijklmnopqrst1")); + test(S("abcdefghijklmnopqrst"), 20, 1, "1234567890", 5, S("abcdefghijklmnopqrst12345")); + test(S("abcdefghijklmnopqrst"), 20, 1, "1234567890", 9, S("abcdefghijklmnopqrst123456789")); + test(S("abcdefghijklmnopqrst"), 20, 1, "1234567890", 10, S("abcdefghijklmnopqrst1234567890")); + test(S("abcdefghijklmnopqrst"), 20, 1, "12345678901234567890", 0, S("abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 20, 1, "12345678901234567890", 1, S("abcdefghijklmnopqrst1")); + test(S("abcdefghijklmnopqrst"), 20, 1, "12345678901234567890", 10, S("abcdefghijklmnopqrst1234567890")); + test(S("abcdefghijklmnopqrst"), 20, 1, "12345678901234567890", 19, S("abcdefghijklmnopqrst1234567890123456789")); + test(S("abcdefghijklmnopqrst"), 20, 1, "12345678901234567890", 20, S("abcdefghijklmnopqrst12345678901234567890")); + test(S("abcdefghijklmnopqrst"), 21, 0, "", 0, S("can't happen")); + test(S("abcdefghijklmnopqrst"), 21, 0, "12345", 0, S("can't happen")); + test(S("abcdefghijklmnopqrst"), 21, 0, "12345", 1, S("can't happen")); + test(S("abcdefghijklmnopqrst"), 21, 0, "12345", 2, S("can't happen")); + test(S("abcdefghijklmnopqrst"), 21, 0, "12345", 4, S("can't happen")); + test(S("abcdefghijklmnopqrst"), 21, 0, "12345", 5, S("can't happen")); + test(S("abcdefghijklmnopqrst"), 21, 0, "1234567890", 0, S("can't happen")); + test(S("abcdefghijklmnopqrst"), 21, 0, "1234567890", 1, S("can't happen")); + test(S("abcdefghijklmnopqrst"), 21, 0, "1234567890", 5, S("can't happen")); + test(S("abcdefghijklmnopqrst"), 21, 0, "1234567890", 9, S("can't happen")); + test(S("abcdefghijklmnopqrst"), 21, 0, "1234567890", 10, S("can't happen")); + test(S("abcdefghijklmnopqrst"), 21, 0, "12345678901234567890", 0, S("can't happen")); + test(S("abcdefghijklmnopqrst"), 21, 0, "12345678901234567890", 1, S("can't happen")); + test(S("abcdefghijklmnopqrst"), 21, 0, "12345678901234567890", 10, S("can't happen")); + test(S("abcdefghijklmnopqrst"), 21, 0, "12345678901234567890", 19, S("can't happen")); + test(S("abcdefghijklmnopqrst"), 21, 0, "12345678901234567890", 20, S("can't happen")); +} + +int main() +{ + { + typedef std::string S; + test0(); + test1(); + test2(); + test3(); + test4(); + test5(); + test6(); + test7(); + test8(); + test9(); + test10(); + test11(); + } +#if TEST_STD_VER >= 11 + { + typedef std::basic_string, min_allocator> S; + test0(); + test1(); + test2(); + test3(); + test4(); + test5(); + test6(); + test7(); + test8(); + test9(); + test10(); + test11(); + } +#endif +} diff --git a/tests/external/libcxx/basic_string/string.modifiers/string_replace/size_size_size_char.pass.cpp b/tests/external/libcxx/basic_string/string.modifiers/string_replace/size_size_size_char.pass.cpp new file mode 100644 index 0000000..75745da --- /dev/null +++ b/tests/external/libcxx/basic_string/string.modifiers/string_replace/size_size_size_char.pass.cpp @@ -0,0 +1,384 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// + +// basic_string& +// replace(size_type pos, size_type n1, size_type n2, charT c); + +#include +#include +#include +#include + +#include "test_macros.h" +#include "min_allocator.h" + +template +void +test(S s, typename S::size_type pos, typename S::size_type n1, + typename S::size_type n2, typename S::value_type c, + S expected) +{ + const typename S::size_type old_size = s.size(); + S s0 = s; + if (pos <= old_size) + { + s.replace(pos, n1, n2, c); + LIBCPP_ASSERT(s.__invariants()); + assert(s == expected); + typename S::size_type xlen = std::min(n1, old_size - pos); + typename S::size_type rlen = n2; + assert(s.size() == old_size - xlen + rlen); + } +#ifndef TEST_HAS_NO_EXCEPTIONS + else + { + try + { + s.replace(pos, n1, n2, c); + assert(false); + } + catch (std::out_of_range&) + { + assert(pos > old_size); + assert(s == s0); + } + } +#endif +} + +template +void test0() +{ + test(S(""), 0, 0, 0, '2', S("")); + test(S(""), 0, 0, 5, '2', S("22222")); + test(S(""), 0, 0, 10, '2', S("2222222222")); + test(S(""), 0, 0, 20, '2', S("22222222222222222222")); + test(S(""), 0, 1, 0, '2', S("")); + test(S(""), 0, 1, 5, '2', S("22222")); + test(S(""), 0, 1, 10, '2', S("2222222222")); + test(S(""), 0, 1, 20, '2', S("22222222222222222222")); + test(S(""), 1, 0, 0, '2', S("can't happen")); + test(S(""), 1, 0, 5, '2', S("can't happen")); + test(S(""), 1, 0, 10, '2', S("can't happen")); + test(S(""), 1, 0, 20, '2', S("can't happen")); + test(S("abcde"), 0, 0, 0, '2', S("abcde")); + test(S("abcde"), 0, 0, 5, '2', S("22222abcde")); + test(S("abcde"), 0, 0, 10, '2', S("2222222222abcde")); + test(S("abcde"), 0, 0, 20, '2', S("22222222222222222222abcde")); + test(S("abcde"), 0, 1, 0, '2', S("bcde")); + test(S("abcde"), 0, 1, 5, '2', S("22222bcde")); + test(S("abcde"), 0, 1, 10, '2', S("2222222222bcde")); + test(S("abcde"), 0, 1, 20, '2', S("22222222222222222222bcde")); + test(S("abcde"), 0, 2, 0, '2', S("cde")); + test(S("abcde"), 0, 2, 5, '2', S("22222cde")); + test(S("abcde"), 0, 2, 10, '2', S("2222222222cde")); + test(S("abcde"), 0, 2, 20, '2', S("22222222222222222222cde")); + test(S("abcde"), 0, 4, 0, '2', S("e")); + test(S("abcde"), 0, 4, 5, '2', S("22222e")); + test(S("abcde"), 0, 4, 10, '2', S("2222222222e")); + test(S("abcde"), 0, 4, 20, '2', S("22222222222222222222e")); + test(S("abcde"), 0, 5, 0, '2', S("")); + test(S("abcde"), 0, 5, 5, '2', S("22222")); + test(S("abcde"), 0, 5, 10, '2', S("2222222222")); + test(S("abcde"), 0, 5, 20, '2', S("22222222222222222222")); + test(S("abcde"), 0, 6, 0, '2', S("")); + test(S("abcde"), 0, 6, 5, '2', S("22222")); + test(S("abcde"), 0, 6, 10, '2', S("2222222222")); + test(S("abcde"), 0, 6, 20, '2', S("22222222222222222222")); + test(S("abcde"), 1, 0, 0, '2', S("abcde")); + test(S("abcde"), 1, 0, 5, '2', S("a22222bcde")); + test(S("abcde"), 1, 0, 10, '2', S("a2222222222bcde")); + test(S("abcde"), 1, 0, 20, '2', S("a22222222222222222222bcde")); + test(S("abcde"), 1, 1, 0, '2', S("acde")); + test(S("abcde"), 1, 1, 5, '2', S("a22222cde")); + test(S("abcde"), 1, 1, 10, '2', S("a2222222222cde")); + test(S("abcde"), 1, 1, 20, '2', S("a22222222222222222222cde")); + test(S("abcde"), 1, 2, 0, '2', S("ade")); + test(S("abcde"), 1, 2, 5, '2', S("a22222de")); + test(S("abcde"), 1, 2, 10, '2', S("a2222222222de")); + test(S("abcde"), 1, 2, 20, '2', S("a22222222222222222222de")); + test(S("abcde"), 1, 3, 0, '2', S("ae")); + test(S("abcde"), 1, 3, 5, '2', S("a22222e")); + test(S("abcde"), 1, 3, 10, '2', S("a2222222222e")); + test(S("abcde"), 1, 3, 20, '2', S("a22222222222222222222e")); + test(S("abcde"), 1, 4, 0, '2', S("a")); + test(S("abcde"), 1, 4, 5, '2', S("a22222")); + test(S("abcde"), 1, 4, 10, '2', S("a2222222222")); + test(S("abcde"), 1, 4, 20, '2', S("a22222222222222222222")); + test(S("abcde"), 1, 5, 0, '2', S("a")); + test(S("abcde"), 1, 5, 5, '2', S("a22222")); + test(S("abcde"), 1, 5, 10, '2', S("a2222222222")); + test(S("abcde"), 1, 5, 20, '2', S("a22222222222222222222")); + test(S("abcde"), 2, 0, 0, '2', S("abcde")); + test(S("abcde"), 2, 0, 5, '2', S("ab22222cde")); + test(S("abcde"), 2, 0, 10, '2', S("ab2222222222cde")); + test(S("abcde"), 2, 0, 20, '2', S("ab22222222222222222222cde")); + test(S("abcde"), 2, 1, 0, '2', S("abde")); + test(S("abcde"), 2, 1, 5, '2', S("ab22222de")); + test(S("abcde"), 2, 1, 10, '2', S("ab2222222222de")); + test(S("abcde"), 2, 1, 20, '2', S("ab22222222222222222222de")); + test(S("abcde"), 2, 2, 0, '2', S("abe")); + test(S("abcde"), 2, 2, 5, '2', S("ab22222e")); + test(S("abcde"), 2, 2, 10, '2', S("ab2222222222e")); + test(S("abcde"), 2, 2, 20, '2', S("ab22222222222222222222e")); + test(S("abcde"), 2, 3, 0, '2', S("ab")); + test(S("abcde"), 2, 3, 5, '2', S("ab22222")); + test(S("abcde"), 2, 3, 10, '2', S("ab2222222222")); + test(S("abcde"), 2, 3, 20, '2', S("ab22222222222222222222")); + test(S("abcde"), 2, 4, 0, '2', S("ab")); + test(S("abcde"), 2, 4, 5, '2', S("ab22222")); + test(S("abcde"), 2, 4, 10, '2', S("ab2222222222")); + test(S("abcde"), 2, 4, 20, '2', S("ab22222222222222222222")); + test(S("abcde"), 4, 0, 0, '2', S("abcde")); + test(S("abcde"), 4, 0, 5, '2', S("abcd22222e")); + test(S("abcde"), 4, 0, 10, '2', S("abcd2222222222e")); + test(S("abcde"), 4, 0, 20, '2', S("abcd22222222222222222222e")); + test(S("abcde"), 4, 1, 0, '2', S("abcd")); + test(S("abcde"), 4, 1, 5, '2', S("abcd22222")); + test(S("abcde"), 4, 1, 10, '2', S("abcd2222222222")); + test(S("abcde"), 4, 1, 20, '2', S("abcd22222222222222222222")); + test(S("abcde"), 4, 2, 0, '2', S("abcd")); + test(S("abcde"), 4, 2, 5, '2', S("abcd22222")); + test(S("abcde"), 4, 2, 10, '2', S("abcd2222222222")); + test(S("abcde"), 4, 2, 20, '2', S("abcd22222222222222222222")); + test(S("abcde"), 5, 0, 0, '2', S("abcde")); + test(S("abcde"), 5, 0, 5, '2', S("abcde22222")); + test(S("abcde"), 5, 0, 10, '2', S("abcde2222222222")); + test(S("abcde"), 5, 0, 20, '2', S("abcde22222222222222222222")); + test(S("abcde"), 5, 1, 0, '2', S("abcde")); + test(S("abcde"), 5, 1, 5, '2', S("abcde22222")); + test(S("abcde"), 5, 1, 10, '2', S("abcde2222222222")); + test(S("abcde"), 5, 1, 20, '2', S("abcde22222222222222222222")); +} + +template +void test1() +{ + test(S("abcde"), 6, 0, 0, '2', S("can't happen")); + test(S("abcde"), 6, 0, 5, '2', S("can't happen")); + test(S("abcde"), 6, 0, 10, '2', S("can't happen")); + test(S("abcde"), 6, 0, 20, '2', S("can't happen")); + test(S("abcdefghij"), 0, 0, 0, '2', S("abcdefghij")); + test(S("abcdefghij"), 0, 0, 5, '2', S("22222abcdefghij")); + test(S("abcdefghij"), 0, 0, 10, '2', S("2222222222abcdefghij")); + test(S("abcdefghij"), 0, 0, 20, '2', S("22222222222222222222abcdefghij")); + test(S("abcdefghij"), 0, 1, 0, '2', S("bcdefghij")); + test(S("abcdefghij"), 0, 1, 5, '2', S("22222bcdefghij")); + test(S("abcdefghij"), 0, 1, 10, '2', S("2222222222bcdefghij")); + test(S("abcdefghij"), 0, 1, 20, '2', S("22222222222222222222bcdefghij")); + test(S("abcdefghij"), 0, 5, 0, '2', S("fghij")); + test(S("abcdefghij"), 0, 5, 5, '2', S("22222fghij")); + test(S("abcdefghij"), 0, 5, 10, '2', S("2222222222fghij")); + test(S("abcdefghij"), 0, 5, 20, '2', S("22222222222222222222fghij")); + test(S("abcdefghij"), 0, 9, 0, '2', S("j")); + test(S("abcdefghij"), 0, 9, 5, '2', S("22222j")); + test(S("abcdefghij"), 0, 9, 10, '2', S("2222222222j")); + test(S("abcdefghij"), 0, 9, 20, '2', S("22222222222222222222j")); + test(S("abcdefghij"), 0, 10, 0, '2', S("")); + test(S("abcdefghij"), 0, 10, 5, '2', S("22222")); + test(S("abcdefghij"), 0, 10, 10, '2', S("2222222222")); + test(S("abcdefghij"), 0, 10, 20, '2', S("22222222222222222222")); + test(S("abcdefghij"), 0, 11, 0, '2', S("")); + test(S("abcdefghij"), 0, 11, 5, '2', S("22222")); + test(S("abcdefghij"), 0, 11, 10, '2', S("2222222222")); + test(S("abcdefghij"), 0, 11, 20, '2', S("22222222222222222222")); + test(S("abcdefghij"), 1, 0, 0, '2', S("abcdefghij")); + test(S("abcdefghij"), 1, 0, 5, '2', S("a22222bcdefghij")); + test(S("abcdefghij"), 1, 0, 10, '2', S("a2222222222bcdefghij")); + test(S("abcdefghij"), 1, 0, 20, '2', S("a22222222222222222222bcdefghij")); + test(S("abcdefghij"), 1, 1, 0, '2', S("acdefghij")); + test(S("abcdefghij"), 1, 1, 5, '2', S("a22222cdefghij")); + test(S("abcdefghij"), 1, 1, 10, '2', S("a2222222222cdefghij")); + test(S("abcdefghij"), 1, 1, 20, '2', S("a22222222222222222222cdefghij")); + test(S("abcdefghij"), 1, 4, 0, '2', S("afghij")); + test(S("abcdefghij"), 1, 4, 5, '2', S("a22222fghij")); + test(S("abcdefghij"), 1, 4, 10, '2', S("a2222222222fghij")); + test(S("abcdefghij"), 1, 4, 20, '2', S("a22222222222222222222fghij")); + test(S("abcdefghij"), 1, 8, 0, '2', S("aj")); + test(S("abcdefghij"), 1, 8, 5, '2', S("a22222j")); + test(S("abcdefghij"), 1, 8, 10, '2', S("a2222222222j")); + test(S("abcdefghij"), 1, 8, 20, '2', S("a22222222222222222222j")); + test(S("abcdefghij"), 1, 9, 0, '2', S("a")); + test(S("abcdefghij"), 1, 9, 5, '2', S("a22222")); + test(S("abcdefghij"), 1, 9, 10, '2', S("a2222222222")); + test(S("abcdefghij"), 1, 9, 20, '2', S("a22222222222222222222")); + test(S("abcdefghij"), 1, 10, 0, '2', S("a")); + test(S("abcdefghij"), 1, 10, 5, '2', S("a22222")); + test(S("abcdefghij"), 1, 10, 10, '2', S("a2222222222")); + test(S("abcdefghij"), 1, 10, 20, '2', S("a22222222222222222222")); + test(S("abcdefghij"), 5, 0, 0, '2', S("abcdefghij")); + test(S("abcdefghij"), 5, 0, 5, '2', S("abcde22222fghij")); + test(S("abcdefghij"), 5, 0, 10, '2', S("abcde2222222222fghij")); + test(S("abcdefghij"), 5, 0, 20, '2', S("abcde22222222222222222222fghij")); + test(S("abcdefghij"), 5, 1, 0, '2', S("abcdeghij")); + test(S("abcdefghij"), 5, 1, 5, '2', S("abcde22222ghij")); + test(S("abcdefghij"), 5, 1, 10, '2', S("abcde2222222222ghij")); + test(S("abcdefghij"), 5, 1, 20, '2', S("abcde22222222222222222222ghij")); + test(S("abcdefghij"), 5, 2, 0, '2', S("abcdehij")); + test(S("abcdefghij"), 5, 2, 5, '2', S("abcde22222hij")); + test(S("abcdefghij"), 5, 2, 10, '2', S("abcde2222222222hij")); + test(S("abcdefghij"), 5, 2, 20, '2', S("abcde22222222222222222222hij")); + test(S("abcdefghij"), 5, 4, 0, '2', S("abcdej")); + test(S("abcdefghij"), 5, 4, 5, '2', S("abcde22222j")); + test(S("abcdefghij"), 5, 4, 10, '2', S("abcde2222222222j")); + test(S("abcdefghij"), 5, 4, 20, '2', S("abcde22222222222222222222j")); + test(S("abcdefghij"), 5, 5, 0, '2', S("abcde")); + test(S("abcdefghij"), 5, 5, 5, '2', S("abcde22222")); + test(S("abcdefghij"), 5, 5, 10, '2', S("abcde2222222222")); + test(S("abcdefghij"), 5, 5, 20, '2', S("abcde22222222222222222222")); + test(S("abcdefghij"), 5, 6, 0, '2', S("abcde")); + test(S("abcdefghij"), 5, 6, 5, '2', S("abcde22222")); + test(S("abcdefghij"), 5, 6, 10, '2', S("abcde2222222222")); + test(S("abcdefghij"), 5, 6, 20, '2', S("abcde22222222222222222222")); + test(S("abcdefghij"), 9, 0, 0, '2', S("abcdefghij")); + test(S("abcdefghij"), 9, 0, 5, '2', S("abcdefghi22222j")); + test(S("abcdefghij"), 9, 0, 10, '2', S("abcdefghi2222222222j")); + test(S("abcdefghij"), 9, 0, 20, '2', S("abcdefghi22222222222222222222j")); + test(S("abcdefghij"), 9, 1, 0, '2', S("abcdefghi")); + test(S("abcdefghij"), 9, 1, 5, '2', S("abcdefghi22222")); + test(S("abcdefghij"), 9, 1, 10, '2', S("abcdefghi2222222222")); + test(S("abcdefghij"), 9, 1, 20, '2', S("abcdefghi22222222222222222222")); + test(S("abcdefghij"), 9, 2, 0, '2', S("abcdefghi")); + test(S("abcdefghij"), 9, 2, 5, '2', S("abcdefghi22222")); + test(S("abcdefghij"), 9, 2, 10, '2', S("abcdefghi2222222222")); + test(S("abcdefghij"), 9, 2, 20, '2', S("abcdefghi22222222222222222222")); + test(S("abcdefghij"), 10, 0, 0, '2', S("abcdefghij")); + test(S("abcdefghij"), 10, 0, 5, '2', S("abcdefghij22222")); + test(S("abcdefghij"), 10, 0, 10, '2', S("abcdefghij2222222222")); + test(S("abcdefghij"), 10, 0, 20, '2', S("abcdefghij22222222222222222222")); + test(S("abcdefghij"), 10, 1, 0, '2', S("abcdefghij")); + test(S("abcdefghij"), 10, 1, 5, '2', S("abcdefghij22222")); + test(S("abcdefghij"), 10, 1, 10, '2', S("abcdefghij2222222222")); + test(S("abcdefghij"), 10, 1, 20, '2', S("abcdefghij22222222222222222222")); + test(S("abcdefghij"), 11, 0, 0, '2', S("can't happen")); + test(S("abcdefghij"), 11, 0, 5, '2', S("can't happen")); + test(S("abcdefghij"), 11, 0, 10, '2', S("can't happen")); + test(S("abcdefghij"), 11, 0, 20, '2', S("can't happen")); +} + +template +void test2() +{ + test(S("abcdefghijklmnopqrst"), 0, 0, 0, '2', S("abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, 0, 5, '2', S("22222abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, 0, 10, '2', S("2222222222abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, 0, 20, '2', S("22222222222222222222abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, 1, 0, '2', S("bcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, 1, 5, '2', S("22222bcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, 1, 10, '2', S("2222222222bcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, 1, 20, '2', S("22222222222222222222bcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, 10, 0, '2', S("klmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, 10, 5, '2', S("22222klmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, 10, 10, '2', S("2222222222klmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, 10, 20, '2', S("22222222222222222222klmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, 19, 0, '2', S("t")); + test(S("abcdefghijklmnopqrst"), 0, 19, 5, '2', S("22222t")); + test(S("abcdefghijklmnopqrst"), 0, 19, 10, '2', S("2222222222t")); + test(S("abcdefghijklmnopqrst"), 0, 19, 20, '2', S("22222222222222222222t")); + test(S("abcdefghijklmnopqrst"), 0, 20, 0, '2', S("")); + test(S("abcdefghijklmnopqrst"), 0, 20, 5, '2', S("22222")); + test(S("abcdefghijklmnopqrst"), 0, 20, 10, '2', S("2222222222")); + test(S("abcdefghijklmnopqrst"), 0, 20, 20, '2', S("22222222222222222222")); + test(S("abcdefghijklmnopqrst"), 0, 21, 0, '2', S("")); + test(S("abcdefghijklmnopqrst"), 0, 21, 5, '2', S("22222")); + test(S("abcdefghijklmnopqrst"), 0, 21, 10, '2', S("2222222222")); + test(S("abcdefghijklmnopqrst"), 0, 21, 20, '2', S("22222222222222222222")); + test(S("abcdefghijklmnopqrst"), 1, 0, 0, '2', S("abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, 0, 5, '2', S("a22222bcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, 0, 10, '2', S("a2222222222bcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, 0, 20, '2', S("a22222222222222222222bcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, 1, 0, '2', S("acdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, 1, 5, '2', S("a22222cdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, 1, 10, '2', S("a2222222222cdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, 1, 20, '2', S("a22222222222222222222cdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, 9, 0, '2', S("aklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, 9, 5, '2', S("a22222klmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, 9, 10, '2', S("a2222222222klmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, 9, 20, '2', S("a22222222222222222222klmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, 18, 0, '2', S("at")); + test(S("abcdefghijklmnopqrst"), 1, 18, 5, '2', S("a22222t")); + test(S("abcdefghijklmnopqrst"), 1, 18, 10, '2', S("a2222222222t")); + test(S("abcdefghijklmnopqrst"), 1, 18, 20, '2', S("a22222222222222222222t")); + test(S("abcdefghijklmnopqrst"), 1, 19, 0, '2', S("a")); + test(S("abcdefghijklmnopqrst"), 1, 19, 5, '2', S("a22222")); + test(S("abcdefghijklmnopqrst"), 1, 19, 10, '2', S("a2222222222")); + test(S("abcdefghijklmnopqrst"), 1, 19, 20, '2', S("a22222222222222222222")); + test(S("abcdefghijklmnopqrst"), 1, 20, 0, '2', S("a")); + test(S("abcdefghijklmnopqrst"), 1, 20, 5, '2', S("a22222")); + test(S("abcdefghijklmnopqrst"), 1, 20, 10, '2', S("a2222222222")); + test(S("abcdefghijklmnopqrst"), 1, 20, 20, '2', S("a22222222222222222222")); + test(S("abcdefghijklmnopqrst"), 10, 0, 0, '2', S("abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 10, 0, 5, '2', S("abcdefghij22222klmnopqrst")); + test(S("abcdefghijklmnopqrst"), 10, 0, 10, '2', S("abcdefghij2222222222klmnopqrst")); + test(S("abcdefghijklmnopqrst"), 10, 0, 20, '2', S("abcdefghij22222222222222222222klmnopqrst")); + test(S("abcdefghijklmnopqrst"), 10, 1, 0, '2', S("abcdefghijlmnopqrst")); + test(S("abcdefghijklmnopqrst"), 10, 1, 5, '2', S("abcdefghij22222lmnopqrst")); + test(S("abcdefghijklmnopqrst"), 10, 1, 10, '2', S("abcdefghij2222222222lmnopqrst")); + test(S("abcdefghijklmnopqrst"), 10, 1, 20, '2', S("abcdefghij22222222222222222222lmnopqrst")); + test(S("abcdefghijklmnopqrst"), 10, 5, 0, '2', S("abcdefghijpqrst")); + test(S("abcdefghijklmnopqrst"), 10, 5, 5, '2', S("abcdefghij22222pqrst")); + test(S("abcdefghijklmnopqrst"), 10, 5, 10, '2', S("abcdefghij2222222222pqrst")); + test(S("abcdefghijklmnopqrst"), 10, 5, 20, '2', S("abcdefghij22222222222222222222pqrst")); + test(S("abcdefghijklmnopqrst"), 10, 9, 0, '2', S("abcdefghijt")); + test(S("abcdefghijklmnopqrst"), 10, 9, 5, '2', S("abcdefghij22222t")); + test(S("abcdefghijklmnopqrst"), 10, 9, 10, '2', S("abcdefghij2222222222t")); + test(S("abcdefghijklmnopqrst"), 10, 9, 20, '2', S("abcdefghij22222222222222222222t")); + test(S("abcdefghijklmnopqrst"), 10, 10, 0, '2', S("abcdefghij")); + test(S("abcdefghijklmnopqrst"), 10, 10, 5, '2', S("abcdefghij22222")); + test(S("abcdefghijklmnopqrst"), 10, 10, 10, '2', S("abcdefghij2222222222")); + test(S("abcdefghijklmnopqrst"), 10, 10, 20, '2', S("abcdefghij22222222222222222222")); + test(S("abcdefghijklmnopqrst"), 10, 11, 0, '2', S("abcdefghij")); + test(S("abcdefghijklmnopqrst"), 10, 11, 5, '2', S("abcdefghij22222")); + test(S("abcdefghijklmnopqrst"), 10, 11, 10, '2', S("abcdefghij2222222222")); + test(S("abcdefghijklmnopqrst"), 10, 11, 20, '2', S("abcdefghij22222222222222222222")); + test(S("abcdefghijklmnopqrst"), 19, 0, 0, '2', S("abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 19, 0, 5, '2', S("abcdefghijklmnopqrs22222t")); + test(S("abcdefghijklmnopqrst"), 19, 0, 10, '2', S("abcdefghijklmnopqrs2222222222t")); + test(S("abcdefghijklmnopqrst"), 19, 0, 20, '2', S("abcdefghijklmnopqrs22222222222222222222t")); + test(S("abcdefghijklmnopqrst"), 19, 1, 0, '2', S("abcdefghijklmnopqrs")); + test(S("abcdefghijklmnopqrst"), 19, 1, 5, '2', S("abcdefghijklmnopqrs22222")); + test(S("abcdefghijklmnopqrst"), 19, 1, 10, '2', S("abcdefghijklmnopqrs2222222222")); + test(S("abcdefghijklmnopqrst"), 19, 1, 20, '2', S("abcdefghijklmnopqrs22222222222222222222")); + test(S("abcdefghijklmnopqrst"), 19, 2, 0, '2', S("abcdefghijklmnopqrs")); + test(S("abcdefghijklmnopqrst"), 19, 2, 5, '2', S("abcdefghijklmnopqrs22222")); + test(S("abcdefghijklmnopqrst"), 19, 2, 10, '2', S("abcdefghijklmnopqrs2222222222")); + test(S("abcdefghijklmnopqrst"), 19, 2, 20, '2', S("abcdefghijklmnopqrs22222222222222222222")); + test(S("abcdefghijklmnopqrst"), 20, 0, 0, '2', S("abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 20, 0, 5, '2', S("abcdefghijklmnopqrst22222")); + test(S("abcdefghijklmnopqrst"), 20, 0, 10, '2', S("abcdefghijklmnopqrst2222222222")); + test(S("abcdefghijklmnopqrst"), 20, 0, 20, '2', S("abcdefghijklmnopqrst22222222222222222222")); + test(S("abcdefghijklmnopqrst"), 20, 1, 0, '2', S("abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 20, 1, 5, '2', S("abcdefghijklmnopqrst22222")); + test(S("abcdefghijklmnopqrst"), 20, 1, 10, '2', S("abcdefghijklmnopqrst2222222222")); + test(S("abcdefghijklmnopqrst"), 20, 1, 20, '2', S("abcdefghijklmnopqrst22222222222222222222")); + test(S("abcdefghijklmnopqrst"), 21, 0, 0, '2', S("can't happen")); + test(S("abcdefghijklmnopqrst"), 21, 0, 5, '2', S("can't happen")); + test(S("abcdefghijklmnopqrst"), 21, 0, 10, '2', S("can't happen")); + test(S("abcdefghijklmnopqrst"), 21, 0, 20, '2', S("can't happen")); +} + +int main() +{ + { + typedef std::string S; + test0(); + test1(); + test2(); + } +#if TEST_STD_VER >= 11 + { + typedef std::basic_string, min_allocator> S; + test0(); + test1(); + test2(); + } +#endif +} diff --git a/tests/external/libcxx/basic_string/string.modifiers/string_replace/size_size_string.pass.cpp b/tests/external/libcxx/basic_string/string.modifiers/string_replace/size_size_string.pass.cpp new file mode 100644 index 0000000..88982e0 --- /dev/null +++ b/tests/external/libcxx/basic_string/string.modifiers/string_replace/size_size_string.pass.cpp @@ -0,0 +1,391 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// + +// basic_string& +// replace(size_type pos1, size_type n1, const basic_string& str); + +#include +#include +#include +#include + +#include "test_macros.h" +#include "min_allocator.h" + +template +void +test(S s, typename S::size_type pos1, typename S::size_type n1, S str, S expected) +{ + const typename S::size_type old_size = s.size(); + S s0 = s; + if (pos1 <= old_size) + { + s.replace(pos1, n1, str); + LIBCPP_ASSERT(s.__invariants()); + assert(s == expected); + typename S::size_type xlen = std::min(n1, old_size - pos1); + typename S::size_type rlen = str.size(); + assert(s.size() == old_size - xlen + rlen); + } +#ifndef TEST_HAS_NO_EXCEPTIONS + else + { + try + { + s.replace(pos1, n1, str); + assert(false); + } + catch (std::out_of_range&) + { + assert(pos1 > old_size); + assert(s == s0); + } + } +#endif +} + +template +void test0() +{ + test(S(""), 0, 0, S(""), S("")); + test(S(""), 0, 0, S("12345"), S("12345")); + test(S(""), 0, 0, S("1234567890"), S("1234567890")); + test(S(""), 0, 0, S("12345678901234567890"), S("12345678901234567890")); + test(S(""), 0, 1, S(""), S("")); + test(S(""), 0, 1, S("12345"), S("12345")); + test(S(""), 0, 1, S("1234567890"), S("1234567890")); + test(S(""), 0, 1, S("12345678901234567890"), S("12345678901234567890")); + test(S(""), 1, 0, S(""), S("can't happen")); + test(S(""), 1, 0, S("12345"), S("can't happen")); + test(S(""), 1, 0, S("1234567890"), S("can't happen")); + test(S(""), 1, 0, S("12345678901234567890"), S("can't happen")); + test(S("abcde"), 0, 0, S(""), S("abcde")); + test(S("abcde"), 0, 0, S("12345"), S("12345abcde")); + test(S("abcde"), 0, 0, S("1234567890"), S("1234567890abcde")); + test(S("abcde"), 0, 0, S("12345678901234567890"), S("12345678901234567890abcde")); + test(S("abcde"), 0, 1, S(""), S("bcde")); + test(S("abcde"), 0, 1, S("12345"), S("12345bcde")); + test(S("abcde"), 0, 1, S("1234567890"), S("1234567890bcde")); + test(S("abcde"), 0, 1, S("12345678901234567890"), S("12345678901234567890bcde")); + test(S("abcde"), 0, 2, S(""), S("cde")); + test(S("abcde"), 0, 2, S("12345"), S("12345cde")); + test(S("abcde"), 0, 2, S("1234567890"), S("1234567890cde")); + test(S("abcde"), 0, 2, S("12345678901234567890"), S("12345678901234567890cde")); + test(S("abcde"), 0, 4, S(""), S("e")); + test(S("abcde"), 0, 4, S("12345"), S("12345e")); + test(S("abcde"), 0, 4, S("1234567890"), S("1234567890e")); + test(S("abcde"), 0, 4, S("12345678901234567890"), S("12345678901234567890e")); + test(S("abcde"), 0, 5, S(""), S("")); + test(S("abcde"), 0, 5, S("12345"), S("12345")); + test(S("abcde"), 0, 5, S("1234567890"), S("1234567890")); + test(S("abcde"), 0, 5, S("12345678901234567890"), S("12345678901234567890")); + test(S("abcde"), 0, 6, S(""), S("")); + test(S("abcde"), 0, 6, S("12345"), S("12345")); + test(S("abcde"), 0, 6, S("1234567890"), S("1234567890")); + test(S("abcde"), 0, 6, S("12345678901234567890"), S("12345678901234567890")); + test(S("abcde"), 1, 0, S(""), S("abcde")); + test(S("abcde"), 1, 0, S("12345"), S("a12345bcde")); + test(S("abcde"), 1, 0, S("1234567890"), S("a1234567890bcde")); + test(S("abcde"), 1, 0, S("12345678901234567890"), S("a12345678901234567890bcde")); + test(S("abcde"), 1, 1, S(""), S("acde")); + test(S("abcde"), 1, 1, S("12345"), S("a12345cde")); + test(S("abcde"), 1, 1, S("1234567890"), S("a1234567890cde")); + test(S("abcde"), 1, 1, S("12345678901234567890"), S("a12345678901234567890cde")); + test(S("abcde"), 1, 2, S(""), S("ade")); + test(S("abcde"), 1, 2, S("12345"), S("a12345de")); + test(S("abcde"), 1, 2, S("1234567890"), S("a1234567890de")); + test(S("abcde"), 1, 2, S("12345678901234567890"), S("a12345678901234567890de")); + test(S("abcde"), 1, 3, S(""), S("ae")); + test(S("abcde"), 1, 3, S("12345"), S("a12345e")); + test(S("abcde"), 1, 3, S("1234567890"), S("a1234567890e")); + test(S("abcde"), 1, 3, S("12345678901234567890"), S("a12345678901234567890e")); + test(S("abcde"), 1, 4, S(""), S("a")); + test(S("abcde"), 1, 4, S("12345"), S("a12345")); + test(S("abcde"), 1, 4, S("1234567890"), S("a1234567890")); + test(S("abcde"), 1, 4, S("12345678901234567890"), S("a12345678901234567890")); + test(S("abcde"), 1, 5, S(""), S("a")); + test(S("abcde"), 1, 5, S("12345"), S("a12345")); + test(S("abcde"), 1, 5, S("1234567890"), S("a1234567890")); + test(S("abcde"), 1, 5, S("12345678901234567890"), S("a12345678901234567890")); + test(S("abcde"), 2, 0, S(""), S("abcde")); + test(S("abcde"), 2, 0, S("12345"), S("ab12345cde")); + test(S("abcde"), 2, 0, S("1234567890"), S("ab1234567890cde")); + test(S("abcde"), 2, 0, S("12345678901234567890"), S("ab12345678901234567890cde")); + test(S("abcde"), 2, 1, S(""), S("abde")); + test(S("abcde"), 2, 1, S("12345"), S("ab12345de")); + test(S("abcde"), 2, 1, S("1234567890"), S("ab1234567890de")); + test(S("abcde"), 2, 1, S("12345678901234567890"), S("ab12345678901234567890de")); + test(S("abcde"), 2, 2, S(""), S("abe")); + test(S("abcde"), 2, 2, S("12345"), S("ab12345e")); + test(S("abcde"), 2, 2, S("1234567890"), S("ab1234567890e")); + test(S("abcde"), 2, 2, S("12345678901234567890"), S("ab12345678901234567890e")); + test(S("abcde"), 2, 3, S(""), S("ab")); + test(S("abcde"), 2, 3, S("12345"), S("ab12345")); + test(S("abcde"), 2, 3, S("1234567890"), S("ab1234567890")); + test(S("abcde"), 2, 3, S("12345678901234567890"), S("ab12345678901234567890")); + test(S("abcde"), 2, 4, S(""), S("ab")); + test(S("abcde"), 2, 4, S("12345"), S("ab12345")); + test(S("abcde"), 2, 4, S("1234567890"), S("ab1234567890")); + test(S("abcde"), 2, 4, S("12345678901234567890"), S("ab12345678901234567890")); + test(S("abcde"), 4, 0, S(""), S("abcde")); + test(S("abcde"), 4, 0, S("12345"), S("abcd12345e")); + test(S("abcde"), 4, 0, S("1234567890"), S("abcd1234567890e")); + test(S("abcde"), 4, 0, S("12345678901234567890"), S("abcd12345678901234567890e")); + test(S("abcde"), 4, 1, S(""), S("abcd")); + test(S("abcde"), 4, 1, S("12345"), S("abcd12345")); + test(S("abcde"), 4, 1, S("1234567890"), S("abcd1234567890")); + test(S("abcde"), 4, 1, S("12345678901234567890"), S("abcd12345678901234567890")); + test(S("abcde"), 4, 2, S(""), S("abcd")); + test(S("abcde"), 4, 2, S("12345"), S("abcd12345")); + test(S("abcde"), 4, 2, S("1234567890"), S("abcd1234567890")); + test(S("abcde"), 4, 2, S("12345678901234567890"), S("abcd12345678901234567890")); + test(S("abcde"), 5, 0, S(""), S("abcde")); + test(S("abcde"), 5, 0, S("12345"), S("abcde12345")); + test(S("abcde"), 5, 0, S("1234567890"), S("abcde1234567890")); + test(S("abcde"), 5, 0, S("12345678901234567890"), S("abcde12345678901234567890")); + test(S("abcde"), 5, 1, S(""), S("abcde")); + test(S("abcde"), 5, 1, S("12345"), S("abcde12345")); + test(S("abcde"), 5, 1, S("1234567890"), S("abcde1234567890")); + test(S("abcde"), 5, 1, S("12345678901234567890"), S("abcde12345678901234567890")); +} + +template +void test1() +{ + test(S("abcde"), 6, 0, S(""), S("can't happen")); + test(S("abcde"), 6, 0, S("12345"), S("can't happen")); + test(S("abcde"), 6, 0, S("1234567890"), S("can't happen")); + test(S("abcde"), 6, 0, S("12345678901234567890"), S("can't happen")); + test(S("abcdefghij"), 0, 0, S(""), S("abcdefghij")); + test(S("abcdefghij"), 0, 0, S("12345"), S("12345abcdefghij")); + test(S("abcdefghij"), 0, 0, S("1234567890"), S("1234567890abcdefghij")); + test(S("abcdefghij"), 0, 0, S("12345678901234567890"), S("12345678901234567890abcdefghij")); + test(S("abcdefghij"), 0, 1, S(""), S("bcdefghij")); + test(S("abcdefghij"), 0, 1, S("12345"), S("12345bcdefghij")); + test(S("abcdefghij"), 0, 1, S("1234567890"), S("1234567890bcdefghij")); + test(S("abcdefghij"), 0, 1, S("12345678901234567890"), S("12345678901234567890bcdefghij")); + test(S("abcdefghij"), 0, 5, S(""), S("fghij")); + test(S("abcdefghij"), 0, 5, S("12345"), S("12345fghij")); + test(S("abcdefghij"), 0, 5, S("1234567890"), S("1234567890fghij")); + test(S("abcdefghij"), 0, 5, S("12345678901234567890"), S("12345678901234567890fghij")); + test(S("abcdefghij"), 0, 9, S(""), S("j")); + test(S("abcdefghij"), 0, 9, S("12345"), S("12345j")); + test(S("abcdefghij"), 0, 9, S("1234567890"), S("1234567890j")); + test(S("abcdefghij"), 0, 9, S("12345678901234567890"), S("12345678901234567890j")); + test(S("abcdefghij"), 0, 10, S(""), S("")); + test(S("abcdefghij"), 0, 10, S("12345"), S("12345")); + test(S("abcdefghij"), 0, 10, S("1234567890"), S("1234567890")); + test(S("abcdefghij"), 0, 10, S("12345678901234567890"), S("12345678901234567890")); + test(S("abcdefghij"), 0, 11, S(""), S("")); + test(S("abcdefghij"), 0, 11, S("12345"), S("12345")); + test(S("abcdefghij"), 0, 11, S("1234567890"), S("1234567890")); + test(S("abcdefghij"), 0, 11, S("12345678901234567890"), S("12345678901234567890")); + test(S("abcdefghij"), 1, 0, S(""), S("abcdefghij")); + test(S("abcdefghij"), 1, 0, S("12345"), S("a12345bcdefghij")); + test(S("abcdefghij"), 1, 0, S("1234567890"), S("a1234567890bcdefghij")); + test(S("abcdefghij"), 1, 0, S("12345678901234567890"), S("a12345678901234567890bcdefghij")); + test(S("abcdefghij"), 1, 1, S(""), S("acdefghij")); + test(S("abcdefghij"), 1, 1, S("12345"), S("a12345cdefghij")); + test(S("abcdefghij"), 1, 1, S("1234567890"), S("a1234567890cdefghij")); + test(S("abcdefghij"), 1, 1, S("12345678901234567890"), S("a12345678901234567890cdefghij")); + test(S("abcdefghij"), 1, 4, S(""), S("afghij")); + test(S("abcdefghij"), 1, 4, S("12345"), S("a12345fghij")); + test(S("abcdefghij"), 1, 4, S("1234567890"), S("a1234567890fghij")); + test(S("abcdefghij"), 1, 4, S("12345678901234567890"), S("a12345678901234567890fghij")); + test(S("abcdefghij"), 1, 8, S(""), S("aj")); + test(S("abcdefghij"), 1, 8, S("12345"), S("a12345j")); + test(S("abcdefghij"), 1, 8, S("1234567890"), S("a1234567890j")); + test(S("abcdefghij"), 1, 8, S("12345678901234567890"), S("a12345678901234567890j")); + test(S("abcdefghij"), 1, 9, S(""), S("a")); + test(S("abcdefghij"), 1, 9, S("12345"), S("a12345")); + test(S("abcdefghij"), 1, 9, S("1234567890"), S("a1234567890")); + test(S("abcdefghij"), 1, 9, S("12345678901234567890"), S("a12345678901234567890")); + test(S("abcdefghij"), 1, 10, S(""), S("a")); + test(S("abcdefghij"), 1, 10, S("12345"), S("a12345")); + test(S("abcdefghij"), 1, 10, S("1234567890"), S("a1234567890")); + test(S("abcdefghij"), 1, 10, S("12345678901234567890"), S("a12345678901234567890")); + test(S("abcdefghij"), 5, 0, S(""), S("abcdefghij")); + test(S("abcdefghij"), 5, 0, S("12345"), S("abcde12345fghij")); + test(S("abcdefghij"), 5, 0, S("1234567890"), S("abcde1234567890fghij")); + test(S("abcdefghij"), 5, 0, S("12345678901234567890"), S("abcde12345678901234567890fghij")); + test(S("abcdefghij"), 5, 1, S(""), S("abcdeghij")); + test(S("abcdefghij"), 5, 1, S("12345"), S("abcde12345ghij")); + test(S("abcdefghij"), 5, 1, S("1234567890"), S("abcde1234567890ghij")); + test(S("abcdefghij"), 5, 1, S("12345678901234567890"), S("abcde12345678901234567890ghij")); + test(S("abcdefghij"), 5, 2, S(""), S("abcdehij")); + test(S("abcdefghij"), 5, 2, S("12345"), S("abcde12345hij")); + test(S("abcdefghij"), 5, 2, S("1234567890"), S("abcde1234567890hij")); + test(S("abcdefghij"), 5, 2, S("12345678901234567890"), S("abcde12345678901234567890hij")); + test(S("abcdefghij"), 5, 4, S(""), S("abcdej")); + test(S("abcdefghij"), 5, 4, S("12345"), S("abcde12345j")); + test(S("abcdefghij"), 5, 4, S("1234567890"), S("abcde1234567890j")); + test(S("abcdefghij"), 5, 4, S("12345678901234567890"), S("abcde12345678901234567890j")); + test(S("abcdefghij"), 5, 5, S(""), S("abcde")); + test(S("abcdefghij"), 5, 5, S("12345"), S("abcde12345")); + test(S("abcdefghij"), 5, 5, S("1234567890"), S("abcde1234567890")); + test(S("abcdefghij"), 5, 5, S("12345678901234567890"), S("abcde12345678901234567890")); + test(S("abcdefghij"), 5, 6, S(""), S("abcde")); + test(S("abcdefghij"), 5, 6, S("12345"), S("abcde12345")); + test(S("abcdefghij"), 5, 6, S("1234567890"), S("abcde1234567890")); + test(S("abcdefghij"), 5, 6, S("12345678901234567890"), S("abcde12345678901234567890")); + test(S("abcdefghij"), 9, 0, S(""), S("abcdefghij")); + test(S("abcdefghij"), 9, 0, S("12345"), S("abcdefghi12345j")); + test(S("abcdefghij"), 9, 0, S("1234567890"), S("abcdefghi1234567890j")); + test(S("abcdefghij"), 9, 0, S("12345678901234567890"), S("abcdefghi12345678901234567890j")); + test(S("abcdefghij"), 9, 1, S(""), S("abcdefghi")); + test(S("abcdefghij"), 9, 1, S("12345"), S("abcdefghi12345")); + test(S("abcdefghij"), 9, 1, S("1234567890"), S("abcdefghi1234567890")); + test(S("abcdefghij"), 9, 1, S("12345678901234567890"), S("abcdefghi12345678901234567890")); + test(S("abcdefghij"), 9, 2, S(""), S("abcdefghi")); + test(S("abcdefghij"), 9, 2, S("12345"), S("abcdefghi12345")); + test(S("abcdefghij"), 9, 2, S("1234567890"), S("abcdefghi1234567890")); + test(S("abcdefghij"), 9, 2, S("12345678901234567890"), S("abcdefghi12345678901234567890")); + test(S("abcdefghij"), 10, 0, S(""), S("abcdefghij")); + test(S("abcdefghij"), 10, 0, S("12345"), S("abcdefghij12345")); + test(S("abcdefghij"), 10, 0, S("1234567890"), S("abcdefghij1234567890")); + test(S("abcdefghij"), 10, 0, S("12345678901234567890"), S("abcdefghij12345678901234567890")); + test(S("abcdefghij"), 10, 1, S(""), S("abcdefghij")); + test(S("abcdefghij"), 10, 1, S("12345"), S("abcdefghij12345")); + test(S("abcdefghij"), 10, 1, S("1234567890"), S("abcdefghij1234567890")); + test(S("abcdefghij"), 10, 1, S("12345678901234567890"), S("abcdefghij12345678901234567890")); + test(S("abcdefghij"), 11, 0, S(""), S("can't happen")); + test(S("abcdefghij"), 11, 0, S("12345"), S("can't happen")); + test(S("abcdefghij"), 11, 0, S("1234567890"), S("can't happen")); + test(S("abcdefghij"), 11, 0, S("12345678901234567890"), S("can't happen")); +} + +template +void test2() +{ + test(S("abcdefghijklmnopqrst"), 0, 0, S(""), S("abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, 0, S("12345"), S("12345abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, 0, S("1234567890"), S("1234567890abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, 0, S("12345678901234567890"), S("12345678901234567890abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, 1, S(""), S("bcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, 1, S("12345"), S("12345bcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, 1, S("1234567890"), S("1234567890bcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, 1, S("12345678901234567890"), S("12345678901234567890bcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, 10, S(""), S("klmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, 10, S("12345"), S("12345klmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, 10, S("1234567890"), S("1234567890klmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, 10, S("12345678901234567890"), S("12345678901234567890klmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, 19, S(""), S("t")); + test(S("abcdefghijklmnopqrst"), 0, 19, S("12345"), S("12345t")); + test(S("abcdefghijklmnopqrst"), 0, 19, S("1234567890"), S("1234567890t")); + test(S("abcdefghijklmnopqrst"), 0, 19, S("12345678901234567890"), S("12345678901234567890t")); + test(S("abcdefghijklmnopqrst"), 0, 20, S(""), S("")); + test(S("abcdefghijklmnopqrst"), 0, 20, S("12345"), S("12345")); + test(S("abcdefghijklmnopqrst"), 0, 20, S("1234567890"), S("1234567890")); + test(S("abcdefghijklmnopqrst"), 0, 20, S("12345678901234567890"), S("12345678901234567890")); + test(S("abcdefghijklmnopqrst"), 0, 21, S(""), S("")); + test(S("abcdefghijklmnopqrst"), 0, 21, S("12345"), S("12345")); + test(S("abcdefghijklmnopqrst"), 0, 21, S("1234567890"), S("1234567890")); + test(S("abcdefghijklmnopqrst"), 0, 21, S("12345678901234567890"), S("12345678901234567890")); + test(S("abcdefghijklmnopqrst"), 1, 0, S(""), S("abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, 0, S("12345"), S("a12345bcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, 0, S("1234567890"), S("a1234567890bcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, 0, S("12345678901234567890"), S("a12345678901234567890bcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, 1, S(""), S("acdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, 1, S("12345"), S("a12345cdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, 1, S("1234567890"), S("a1234567890cdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, 1, S("12345678901234567890"), S("a12345678901234567890cdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, 9, S(""), S("aklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, 9, S("12345"), S("a12345klmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, 9, S("1234567890"), S("a1234567890klmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, 9, S("12345678901234567890"), S("a12345678901234567890klmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, 18, S(""), S("at")); + test(S("abcdefghijklmnopqrst"), 1, 18, S("12345"), S("a12345t")); + test(S("abcdefghijklmnopqrst"), 1, 18, S("1234567890"), S("a1234567890t")); + test(S("abcdefghijklmnopqrst"), 1, 18, S("12345678901234567890"), S("a12345678901234567890t")); + test(S("abcdefghijklmnopqrst"), 1, 19, S(""), S("a")); + test(S("abcdefghijklmnopqrst"), 1, 19, S("12345"), S("a12345")); + test(S("abcdefghijklmnopqrst"), 1, 19, S("1234567890"), S("a1234567890")); + test(S("abcdefghijklmnopqrst"), 1, 19, S("12345678901234567890"), S("a12345678901234567890")); + test(S("abcdefghijklmnopqrst"), 1, 20, S(""), S("a")); + test(S("abcdefghijklmnopqrst"), 1, 20, S("12345"), S("a12345")); + test(S("abcdefghijklmnopqrst"), 1, 20, S("1234567890"), S("a1234567890")); + test(S("abcdefghijklmnopqrst"), 1, 20, S("12345678901234567890"), S("a12345678901234567890")); + test(S("abcdefghijklmnopqrst"), 10, 0, S(""), S("abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 10, 0, S("12345"), S("abcdefghij12345klmnopqrst")); + test(S("abcdefghijklmnopqrst"), 10, 0, S("1234567890"), S("abcdefghij1234567890klmnopqrst")); + test(S("abcdefghijklmnopqrst"), 10, 0, S("12345678901234567890"), S("abcdefghij12345678901234567890klmnopqrst")); + test(S("abcdefghijklmnopqrst"), 10, 1, S(""), S("abcdefghijlmnopqrst")); + test(S("abcdefghijklmnopqrst"), 10, 1, S("12345"), S("abcdefghij12345lmnopqrst")); + test(S("abcdefghijklmnopqrst"), 10, 1, S("1234567890"), S("abcdefghij1234567890lmnopqrst")); + test(S("abcdefghijklmnopqrst"), 10, 1, S("12345678901234567890"), S("abcdefghij12345678901234567890lmnopqrst")); + test(S("abcdefghijklmnopqrst"), 10, 5, S(""), S("abcdefghijpqrst")); + test(S("abcdefghijklmnopqrst"), 10, 5, S("12345"), S("abcdefghij12345pqrst")); + test(S("abcdefghijklmnopqrst"), 10, 5, S("1234567890"), S("abcdefghij1234567890pqrst")); + test(S("abcdefghijklmnopqrst"), 10, 5, S("12345678901234567890"), S("abcdefghij12345678901234567890pqrst")); + test(S("abcdefghijklmnopqrst"), 10, 9, S(""), S("abcdefghijt")); + test(S("abcdefghijklmnopqrst"), 10, 9, S("12345"), S("abcdefghij12345t")); + test(S("abcdefghijklmnopqrst"), 10, 9, S("1234567890"), S("abcdefghij1234567890t")); + test(S("abcdefghijklmnopqrst"), 10, 9, S("12345678901234567890"), S("abcdefghij12345678901234567890t")); + test(S("abcdefghijklmnopqrst"), 10, 10, S(""), S("abcdefghij")); + test(S("abcdefghijklmnopqrst"), 10, 10, S("12345"), S("abcdefghij12345")); + test(S("abcdefghijklmnopqrst"), 10, 10, S("1234567890"), S("abcdefghij1234567890")); + test(S("abcdefghijklmnopqrst"), 10, 10, S("12345678901234567890"), S("abcdefghij12345678901234567890")); + test(S("abcdefghijklmnopqrst"), 10, 11, S(""), S("abcdefghij")); + test(S("abcdefghijklmnopqrst"), 10, 11, S("12345"), S("abcdefghij12345")); + test(S("abcdefghijklmnopqrst"), 10, 11, S("1234567890"), S("abcdefghij1234567890")); + test(S("abcdefghijklmnopqrst"), 10, 11, S("12345678901234567890"), S("abcdefghij12345678901234567890")); + test(S("abcdefghijklmnopqrst"), 19, 0, S(""), S("abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 19, 0, S("12345"), S("abcdefghijklmnopqrs12345t")); + test(S("abcdefghijklmnopqrst"), 19, 0, S("1234567890"), S("abcdefghijklmnopqrs1234567890t")); + test(S("abcdefghijklmnopqrst"), 19, 0, S("12345678901234567890"), S("abcdefghijklmnopqrs12345678901234567890t")); + test(S("abcdefghijklmnopqrst"), 19, 1, S(""), S("abcdefghijklmnopqrs")); + test(S("abcdefghijklmnopqrst"), 19, 1, S("12345"), S("abcdefghijklmnopqrs12345")); + test(S("abcdefghijklmnopqrst"), 19, 1, S("1234567890"), S("abcdefghijklmnopqrs1234567890")); + test(S("abcdefghijklmnopqrst"), 19, 1, S("12345678901234567890"), S("abcdefghijklmnopqrs12345678901234567890")); + test(S("abcdefghijklmnopqrst"), 19, 2, S(""), S("abcdefghijklmnopqrs")); + test(S("abcdefghijklmnopqrst"), 19, 2, S("12345"), S("abcdefghijklmnopqrs12345")); + test(S("abcdefghijklmnopqrst"), 19, 2, S("1234567890"), S("abcdefghijklmnopqrs1234567890")); + test(S("abcdefghijklmnopqrst"), 19, 2, S("12345678901234567890"), S("abcdefghijklmnopqrs12345678901234567890")); + test(S("abcdefghijklmnopqrst"), 20, 0, S(""), S("abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 20, 0, S("12345"), S("abcdefghijklmnopqrst12345")); + test(S("abcdefghijklmnopqrst"), 20, 0, S("1234567890"), S("abcdefghijklmnopqrst1234567890")); + test(S("abcdefghijklmnopqrst"), 20, 0, S("12345678901234567890"), S("abcdefghijklmnopqrst12345678901234567890")); + test(S("abcdefghijklmnopqrst"), 20, 1, S(""), S("abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 20, 1, S("12345"), S("abcdefghijklmnopqrst12345")); + test(S("abcdefghijklmnopqrst"), 20, 1, S("1234567890"), S("abcdefghijklmnopqrst1234567890")); + test(S("abcdefghijklmnopqrst"), 20, 1, S("12345678901234567890"), S("abcdefghijklmnopqrst12345678901234567890")); + test(S("abcdefghijklmnopqrst"), 21, 0, S(""), S("can't happen")); + test(S("abcdefghijklmnopqrst"), 21, 0, S("12345"), S("can't happen")); + test(S("abcdefghijklmnopqrst"), 21, 0, S("1234567890"), S("can't happen")); + test(S("abcdefghijklmnopqrst"), 21, 0, S("12345678901234567890"), S("can't happen")); +} + +int main() +{ + { + typedef std::string S; + test0(); + test1(); + test2(); + } +#if TEST_STD_VER >= 11 + { + typedef std::basic_string, min_allocator> S; + test0(); + test1(); + test2(); + } +#endif + +#if TEST_STD_VER > 3 + { // LWG 2946 + std::string s = " "; + s.replace(0, 1, {"abc", 1}); + assert(s.size() == 1); + assert(s == "a"); + } +#endif +} diff --git a/tests/external/libcxx/basic_string/string.modifiers/string_replace/size_size_string_size_size.pass.cpp b/tests/external/libcxx/basic_string/string.modifiers/string_replace/size_size_string_size_size.pass.cpp new file mode 100644 index 0000000..b49b6f9 --- /dev/null +++ b/tests/external/libcxx/basic_string/string.modifiers/string_replace/size_size_string_size_size.pass.cpp @@ -0,0 +1,5985 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// + +// basic_string& +// replace(size_type pos1, size_type n1, const basic_string& str, +// size_type pos2, size_type n2=npos); +// the "=npos" was added in C++14 + +#include +#include +#include +#include + +#include "test_macros.h" +#include "min_allocator.h" + +template +void +test(S s, typename S::size_type pos1, typename S::size_type n1, + S str, typename S::size_type pos2, typename S::size_type n2, + S expected) +{ + const typename S::size_type old_size = s.size(); + S s0 = s; + if (pos1 <= old_size && pos2 <= str.size()) + { + s.replace(pos1, n1, str, pos2, n2); + LIBCPP_ASSERT(s.__invariants()); + assert(s == expected); + typename S::size_type xlen = std::min(n1, old_size - pos1); + typename S::size_type rlen = std::min(n2, str.size() - pos2); + assert(s.size() == old_size - xlen + rlen); + } +#ifndef TEST_HAS_NO_EXCEPTIONS + else + { + try + { + s.replace(pos1, n1, str, pos2, n2); + assert(false); + } + catch (std::out_of_range&) + { + assert(pos1 > old_size || pos2 > str.size()); + assert(s == s0); + } + } +#endif +} + +template +void +test_npos(S s, typename S::size_type pos1, typename S::size_type n1, + S str, typename S::size_type pos2, + S expected) +{ + const typename S::size_type old_size = s.size(); + S s0 = s; + if (pos1 <= old_size && pos2 <= str.size()) + { + s.replace(pos1, n1, str, pos2); + LIBCPP_ASSERT(s.__invariants()); + assert(s == expected); + typename S::size_type xlen = std::min(n1, old_size - pos1); + typename S::size_type rlen = std::min(S::npos, str.size() - pos2); + assert(s.size() == old_size - xlen + rlen); + } +#ifndef TEST_HAS_NO_EXCEPTIONS + else + { + try + { + s.replace(pos1, n1, str, pos2); + assert(false); + } + catch (std::out_of_range&) + { + assert(pos1 > old_size || pos2 > str.size()); + assert(s == s0); + } + } +#endif +} + + +template +void test0() +{ + test(S(""), 0, 0, S(""), 0, 0, S("")); + test(S(""), 0, 0, S(""), 0, 1, S("")); + test(S(""), 0, 0, S(""), 1, 0, S("can't happen")); + test(S(""), 0, 0, S("12345"), 0, 0, S("")); + test(S(""), 0, 0, S("12345"), 0, 1, S("1")); + test(S(""), 0, 0, S("12345"), 0, 2, S("12")); + test(S(""), 0, 0, S("12345"), 0, 4, S("1234")); + test(S(""), 0, 0, S("12345"), 0, 5, S("12345")); + test(S(""), 0, 0, S("12345"), 0, 6, S("12345")); + test(S(""), 0, 0, S("12345"), 1, 0, S("")); + test(S(""), 0, 0, S("12345"), 1, 1, S("2")); + test(S(""), 0, 0, S("12345"), 1, 2, S("23")); + test(S(""), 0, 0, S("12345"), 1, 3, S("234")); + test(S(""), 0, 0, S("12345"), 1, 4, S("2345")); + test(S(""), 0, 0, S("12345"), 1, 5, S("2345")); + test(S(""), 0, 0, S("12345"), 2, 0, S("")); + test(S(""), 0, 0, S("12345"), 2, 1, S("3")); + test(S(""), 0, 0, S("12345"), 2, 2, S("34")); + test(S(""), 0, 0, S("12345"), 2, 3, S("345")); + test(S(""), 0, 0, S("12345"), 2, 4, S("345")); + test(S(""), 0, 0, S("12345"), 4, 0, S("")); + test(S(""), 0, 0, S("12345"), 4, 1, S("5")); + test(S(""), 0, 0, S("12345"), 4, 2, S("5")); + test(S(""), 0, 0, S("12345"), 5, 0, S("")); + test(S(""), 0, 0, S("12345"), 5, 1, S("")); + test(S(""), 0, 0, S("12345"), 6, 0, S("can't happen")); + test(S(""), 0, 0, S("1234567890"), 0, 0, S("")); + test(S(""), 0, 0, S("1234567890"), 0, 1, S("1")); + test(S(""), 0, 0, S("1234567890"), 0, 5, S("12345")); + test(S(""), 0, 0, S("1234567890"), 0, 9, S("123456789")); + test(S(""), 0, 0, S("1234567890"), 0, 10, S("1234567890")); + test(S(""), 0, 0, S("1234567890"), 0, 11, S("1234567890")); + test(S(""), 0, 0, S("1234567890"), 1, 0, S("")); + test(S(""), 0, 0, S("1234567890"), 1, 1, S("2")); + test(S(""), 0, 0, S("1234567890"), 1, 4, S("2345")); + test(S(""), 0, 0, S("1234567890"), 1, 8, S("23456789")); + test(S(""), 0, 0, S("1234567890"), 1, 9, S("234567890")); + test(S(""), 0, 0, S("1234567890"), 1, 10, S("234567890")); + test(S(""), 0, 0, S("1234567890"), 5, 0, S("")); + test(S(""), 0, 0, S("1234567890"), 5, 1, S("6")); + test(S(""), 0, 0, S("1234567890"), 5, 2, S("67")); + test(S(""), 0, 0, S("1234567890"), 5, 4, S("6789")); + test(S(""), 0, 0, S("1234567890"), 5, 5, S("67890")); + test(S(""), 0, 0, S("1234567890"), 5, 6, S("67890")); + test(S(""), 0, 0, S("1234567890"), 9, 0, S("")); + test(S(""), 0, 0, S("1234567890"), 9, 1, S("0")); + test(S(""), 0, 0, S("1234567890"), 9, 2, S("0")); + test(S(""), 0, 0, S("1234567890"), 10, 0, S("")); + test(S(""), 0, 0, S("1234567890"), 10, 1, S("")); + test(S(""), 0, 0, S("1234567890"), 11, 0, S("can't happen")); + test(S(""), 0, 0, S("12345678901234567890"), 0, 0, S("")); + test(S(""), 0, 0, S("12345678901234567890"), 0, 1, S("1")); + test(S(""), 0, 0, S("12345678901234567890"), 0, 10, S("1234567890")); + test(S(""), 0, 0, S("12345678901234567890"), 0, 19, S("1234567890123456789")); + test(S(""), 0, 0, S("12345678901234567890"), 0, 20, S("12345678901234567890")); + test(S(""), 0, 0, S("12345678901234567890"), 0, 21, S("12345678901234567890")); + test(S(""), 0, 0, S("12345678901234567890"), 1, 0, S("")); + test(S(""), 0, 0, S("12345678901234567890"), 1, 1, S("2")); + test(S(""), 0, 0, S("12345678901234567890"), 1, 9, S("234567890")); + test(S(""), 0, 0, S("12345678901234567890"), 1, 18, S("234567890123456789")); + test(S(""), 0, 0, S("12345678901234567890"), 1, 19, S("2345678901234567890")); + test(S(""), 0, 0, S("12345678901234567890"), 1, 20, S("2345678901234567890")); + test(S(""), 0, 0, S("12345678901234567890"), 10, 0, S("")); + test(S(""), 0, 0, S("12345678901234567890"), 10, 1, S("1")); + test(S(""), 0, 0, S("12345678901234567890"), 10, 5, S("12345")); + test(S(""), 0, 0, S("12345678901234567890"), 10, 9, S("123456789")); + test(S(""), 0, 0, S("12345678901234567890"), 10, 10, S("1234567890")); + test(S(""), 0, 0, S("12345678901234567890"), 10, 11, S("1234567890")); + test(S(""), 0, 0, S("12345678901234567890"), 19, 0, S("")); + test(S(""), 0, 0, S("12345678901234567890"), 19, 1, S("0")); + test(S(""), 0, 0, S("12345678901234567890"), 19, 2, S("0")); + test(S(""), 0, 0, S("12345678901234567890"), 20, 0, S("")); + test(S(""), 0, 0, S("12345678901234567890"), 20, 1, S("")); + test(S(""), 0, 0, S("12345678901234567890"), 21, 0, S("can't happen")); + test(S(""), 0, 1, S(""), 0, 0, S("")); + test(S(""), 0, 1, S(""), 0, 1, S("")); + test(S(""), 0, 1, S(""), 1, 0, S("can't happen")); + test(S(""), 0, 1, S("12345"), 0, 0, S("")); + test(S(""), 0, 1, S("12345"), 0, 1, S("1")); + test(S(""), 0, 1, S("12345"), 0, 2, S("12")); + test(S(""), 0, 1, S("12345"), 0, 4, S("1234")); + test(S(""), 0, 1, S("12345"), 0, 5, S("12345")); + test(S(""), 0, 1, S("12345"), 0, 6, S("12345")); + test(S(""), 0, 1, S("12345"), 1, 0, S("")); + test(S(""), 0, 1, S("12345"), 1, 1, S("2")); + test(S(""), 0, 1, S("12345"), 1, 2, S("23")); + test(S(""), 0, 1, S("12345"), 1, 3, S("234")); + test(S(""), 0, 1, S("12345"), 1, 4, S("2345")); + test(S(""), 0, 1, S("12345"), 1, 5, S("2345")); + test(S(""), 0, 1, S("12345"), 2, 0, S("")); + test(S(""), 0, 1, S("12345"), 2, 1, S("3")); + test(S(""), 0, 1, S("12345"), 2, 2, S("34")); + test(S(""), 0, 1, S("12345"), 2, 3, S("345")); + test(S(""), 0, 1, S("12345"), 2, 4, S("345")); + test(S(""), 0, 1, S("12345"), 4, 0, S("")); + test(S(""), 0, 1, S("12345"), 4, 1, S("5")); + test(S(""), 0, 1, S("12345"), 4, 2, S("5")); + test(S(""), 0, 1, S("12345"), 5, 0, S("")); + test(S(""), 0, 1, S("12345"), 5, 1, S("")); + test(S(""), 0, 1, S("12345"), 6, 0, S("can't happen")); +} + +template +void test1() +{ + test(S(""), 0, 1, S("1234567890"), 0, 0, S("")); + test(S(""), 0, 1, S("1234567890"), 0, 1, S("1")); + test(S(""), 0, 1, S("1234567890"), 0, 5, S("12345")); + test(S(""), 0, 1, S("1234567890"), 0, 9, S("123456789")); + test(S(""), 0, 1, S("1234567890"), 0, 10, S("1234567890")); + test(S(""), 0, 1, S("1234567890"), 0, 11, S("1234567890")); + test(S(""), 0, 1, S("1234567890"), 1, 0, S("")); + test(S(""), 0, 1, S("1234567890"), 1, 1, S("2")); + test(S(""), 0, 1, S("1234567890"), 1, 4, S("2345")); + test(S(""), 0, 1, S("1234567890"), 1, 8, S("23456789")); + test(S(""), 0, 1, S("1234567890"), 1, 9, S("234567890")); + test(S(""), 0, 1, S("1234567890"), 1, 10, S("234567890")); + test(S(""), 0, 1, S("1234567890"), 5, 0, S("")); + test(S(""), 0, 1, S("1234567890"), 5, 1, S("6")); + test(S(""), 0, 1, S("1234567890"), 5, 2, S("67")); + test(S(""), 0, 1, S("1234567890"), 5, 4, S("6789")); + test(S(""), 0, 1, S("1234567890"), 5, 5, S("67890")); + test(S(""), 0, 1, S("1234567890"), 5, 6, S("67890")); + test(S(""), 0, 1, S("1234567890"), 9, 0, S("")); + test(S(""), 0, 1, S("1234567890"), 9, 1, S("0")); + test(S(""), 0, 1, S("1234567890"), 9, 2, S("0")); + test(S(""), 0, 1, S("1234567890"), 10, 0, S("")); + test(S(""), 0, 1, S("1234567890"), 10, 1, S("")); + test(S(""), 0, 1, S("1234567890"), 11, 0, S("can't happen")); + test(S(""), 0, 1, S("12345678901234567890"), 0, 0, S("")); + test(S(""), 0, 1, S("12345678901234567890"), 0, 1, S("1")); + test(S(""), 0, 1, S("12345678901234567890"), 0, 10, S("1234567890")); + test(S(""), 0, 1, S("12345678901234567890"), 0, 19, S("1234567890123456789")); + test(S(""), 0, 1, S("12345678901234567890"), 0, 20, S("12345678901234567890")); + test(S(""), 0, 1, S("12345678901234567890"), 0, 21, S("12345678901234567890")); + test(S(""), 0, 1, S("12345678901234567890"), 1, 0, S("")); + test(S(""), 0, 1, S("12345678901234567890"), 1, 1, S("2")); + test(S(""), 0, 1, S("12345678901234567890"), 1, 9, S("234567890")); + test(S(""), 0, 1, S("12345678901234567890"), 1, 18, S("234567890123456789")); + test(S(""), 0, 1, S("12345678901234567890"), 1, 19, S("2345678901234567890")); + test(S(""), 0, 1, S("12345678901234567890"), 1, 20, S("2345678901234567890")); + test(S(""), 0, 1, S("12345678901234567890"), 10, 0, S("")); + test(S(""), 0, 1, S("12345678901234567890"), 10, 1, S("1")); + test(S(""), 0, 1, S("12345678901234567890"), 10, 5, S("12345")); + test(S(""), 0, 1, S("12345678901234567890"), 10, 9, S("123456789")); + test(S(""), 0, 1, S("12345678901234567890"), 10, 10, S("1234567890")); + test(S(""), 0, 1, S("12345678901234567890"), 10, 11, S("1234567890")); + test(S(""), 0, 1, S("12345678901234567890"), 19, 0, S("")); + test(S(""), 0, 1, S("12345678901234567890"), 19, 1, S("0")); + test(S(""), 0, 1, S("12345678901234567890"), 19, 2, S("0")); + test(S(""), 0, 1, S("12345678901234567890"), 20, 0, S("")); + test(S(""), 0, 1, S("12345678901234567890"), 20, 1, S("")); + test(S(""), 0, 1, S("12345678901234567890"), 21, 0, S("can't happen")); + test(S(""), 1, 0, S(""), 0, 0, S("can't happen")); + test(S(""), 1, 0, S(""), 0, 1, S("can't happen")); + test(S(""), 1, 0, S(""), 1, 0, S("can't happen")); + test(S(""), 1, 0, S("12345"), 0, 0, S("can't happen")); + test(S(""), 1, 0, S("12345"), 0, 1, S("can't happen")); + test(S(""), 1, 0, S("12345"), 0, 2, S("can't happen")); + test(S(""), 1, 0, S("12345"), 0, 4, S("can't happen")); + test(S(""), 1, 0, S("12345"), 0, 5, S("can't happen")); + test(S(""), 1, 0, S("12345"), 0, 6, S("can't happen")); + test(S(""), 1, 0, S("12345"), 1, 0, S("can't happen")); + test(S(""), 1, 0, S("12345"), 1, 1, S("can't happen")); + test(S(""), 1, 0, S("12345"), 1, 2, S("can't happen")); + test(S(""), 1, 0, S("12345"), 1, 3, S("can't happen")); + test(S(""), 1, 0, S("12345"), 1, 4, S("can't happen")); + test(S(""), 1, 0, S("12345"), 1, 5, S("can't happen")); + test(S(""), 1, 0, S("12345"), 2, 0, S("can't happen")); + test(S(""), 1, 0, S("12345"), 2, 1, S("can't happen")); + test(S(""), 1, 0, S("12345"), 2, 2, S("can't happen")); + test(S(""), 1, 0, S("12345"), 2, 3, S("can't happen")); + test(S(""), 1, 0, S("12345"), 2, 4, S("can't happen")); + test(S(""), 1, 0, S("12345"), 4, 0, S("can't happen")); + test(S(""), 1, 0, S("12345"), 4, 1, S("can't happen")); + test(S(""), 1, 0, S("12345"), 4, 2, S("can't happen")); + test(S(""), 1, 0, S("12345"), 5, 0, S("can't happen")); + test(S(""), 1, 0, S("12345"), 5, 1, S("can't happen")); + test(S(""), 1, 0, S("12345"), 6, 0, S("can't happen")); + test(S(""), 1, 0, S("1234567890"), 0, 0, S("can't happen")); + test(S(""), 1, 0, S("1234567890"), 0, 1, S("can't happen")); + test(S(""), 1, 0, S("1234567890"), 0, 5, S("can't happen")); + test(S(""), 1, 0, S("1234567890"), 0, 9, S("can't happen")); + test(S(""), 1, 0, S("1234567890"), 0, 10, S("can't happen")); + test(S(""), 1, 0, S("1234567890"), 0, 11, S("can't happen")); + test(S(""), 1, 0, S("1234567890"), 1, 0, S("can't happen")); + test(S(""), 1, 0, S("1234567890"), 1, 1, S("can't happen")); + test(S(""), 1, 0, S("1234567890"), 1, 4, S("can't happen")); + test(S(""), 1, 0, S("1234567890"), 1, 8, S("can't happen")); + test(S(""), 1, 0, S("1234567890"), 1, 9, S("can't happen")); + test(S(""), 1, 0, S("1234567890"), 1, 10, S("can't happen")); + test(S(""), 1, 0, S("1234567890"), 5, 0, S("can't happen")); + test(S(""), 1, 0, S("1234567890"), 5, 1, S("can't happen")); + test(S(""), 1, 0, S("1234567890"), 5, 2, S("can't happen")); + test(S(""), 1, 0, S("1234567890"), 5, 4, S("can't happen")); + test(S(""), 1, 0, S("1234567890"), 5, 5, S("can't happen")); + test(S(""), 1, 0, S("1234567890"), 5, 6, S("can't happen")); + test(S(""), 1, 0, S("1234567890"), 9, 0, S("can't happen")); + test(S(""), 1, 0, S("1234567890"), 9, 1, S("can't happen")); + test(S(""), 1, 0, S("1234567890"), 9, 2, S("can't happen")); + test(S(""), 1, 0, S("1234567890"), 10, 0, S("can't happen")); + test(S(""), 1, 0, S("1234567890"), 10, 1, S("can't happen")); + test(S(""), 1, 0, S("1234567890"), 11, 0, S("can't happen")); + test(S(""), 1, 0, S("12345678901234567890"), 0, 0, S("can't happen")); + test(S(""), 1, 0, S("12345678901234567890"), 0, 1, S("can't happen")); +} + +template +void test2() +{ + test(S(""), 1, 0, S("12345678901234567890"), 0, 10, S("can't happen")); + test(S(""), 1, 0, S("12345678901234567890"), 0, 19, S("can't happen")); + test(S(""), 1, 0, S("12345678901234567890"), 0, 20, S("can't happen")); + test(S(""), 1, 0, S("12345678901234567890"), 0, 21, S("can't happen")); + test(S(""), 1, 0, S("12345678901234567890"), 1, 0, S("can't happen")); + test(S(""), 1, 0, S("12345678901234567890"), 1, 1, S("can't happen")); + test(S(""), 1, 0, S("12345678901234567890"), 1, 9, S("can't happen")); + test(S(""), 1, 0, S("12345678901234567890"), 1, 18, S("can't happen")); + test(S(""), 1, 0, S("12345678901234567890"), 1, 19, S("can't happen")); + test(S(""), 1, 0, S("12345678901234567890"), 1, 20, S("can't happen")); + test(S(""), 1, 0, S("12345678901234567890"), 10, 0, S("can't happen")); + test(S(""), 1, 0, S("12345678901234567890"), 10, 1, S("can't happen")); + test(S(""), 1, 0, S("12345678901234567890"), 10, 5, S("can't happen")); + test(S(""), 1, 0, S("12345678901234567890"), 10, 9, S("can't happen")); + test(S(""), 1, 0, S("12345678901234567890"), 10, 10, S("can't happen")); + test(S(""), 1, 0, S("12345678901234567890"), 10, 11, S("can't happen")); + test(S(""), 1, 0, S("12345678901234567890"), 19, 0, S("can't happen")); + test(S(""), 1, 0, S("12345678901234567890"), 19, 1, S("can't happen")); + test(S(""), 1, 0, S("12345678901234567890"), 19, 2, S("can't happen")); + test(S(""), 1, 0, S("12345678901234567890"), 20, 0, S("can't happen")); + test(S(""), 1, 0, S("12345678901234567890"), 20, 1, S("can't happen")); + test(S(""), 1, 0, S("12345678901234567890"), 21, 0, S("can't happen")); + test(S("abcde"), 0, 0, S(""), 0, 0, S("abcde")); + test(S("abcde"), 0, 0, S(""), 0, 1, S("abcde")); + test(S("abcde"), 0, 0, S(""), 1, 0, S("can't happen")); + test(S("abcde"), 0, 0, S("12345"), 0, 0, S("abcde")); + test(S("abcde"), 0, 0, S("12345"), 0, 1, S("1abcde")); + test(S("abcde"), 0, 0, S("12345"), 0, 2, S("12abcde")); + test(S("abcde"), 0, 0, S("12345"), 0, 4, S("1234abcde")); + test(S("abcde"), 0, 0, S("12345"), 0, 5, S("12345abcde")); + test(S("abcde"), 0, 0, S("12345"), 0, 6, S("12345abcde")); + test(S("abcde"), 0, 0, S("12345"), 1, 0, S("abcde")); + test(S("abcde"), 0, 0, S("12345"), 1, 1, S("2abcde")); + test(S("abcde"), 0, 0, S("12345"), 1, 2, S("23abcde")); + test(S("abcde"), 0, 0, S("12345"), 1, 3, S("234abcde")); + test(S("abcde"), 0, 0, S("12345"), 1, 4, S("2345abcde")); + test(S("abcde"), 0, 0, S("12345"), 1, 5, S("2345abcde")); + test(S("abcde"), 0, 0, S("12345"), 2, 0, S("abcde")); + test(S("abcde"), 0, 0, S("12345"), 2, 1, S("3abcde")); + test(S("abcde"), 0, 0, S("12345"), 2, 2, S("34abcde")); + test(S("abcde"), 0, 0, S("12345"), 2, 3, S("345abcde")); + test(S("abcde"), 0, 0, S("12345"), 2, 4, S("345abcde")); + test(S("abcde"), 0, 0, S("12345"), 4, 0, S("abcde")); + test(S("abcde"), 0, 0, S("12345"), 4, 1, S("5abcde")); + test(S("abcde"), 0, 0, S("12345"), 4, 2, S("5abcde")); + test(S("abcde"), 0, 0, S("12345"), 5, 0, S("abcde")); + test(S("abcde"), 0, 0, S("12345"), 5, 1, S("abcde")); + test(S("abcde"), 0, 0, S("12345"), 6, 0, S("can't happen")); + test(S("abcde"), 0, 0, S("1234567890"), 0, 0, S("abcde")); + test(S("abcde"), 0, 0, S("1234567890"), 0, 1, S("1abcde")); + test(S("abcde"), 0, 0, S("1234567890"), 0, 5, S("12345abcde")); + test(S("abcde"), 0, 0, S("1234567890"), 0, 9, S("123456789abcde")); + test(S("abcde"), 0, 0, S("1234567890"), 0, 10, S("1234567890abcde")); + test(S("abcde"), 0, 0, S("1234567890"), 0, 11, S("1234567890abcde")); + test(S("abcde"), 0, 0, S("1234567890"), 1, 0, S("abcde")); + test(S("abcde"), 0, 0, S("1234567890"), 1, 1, S("2abcde")); + test(S("abcde"), 0, 0, S("1234567890"), 1, 4, S("2345abcde")); + test(S("abcde"), 0, 0, S("1234567890"), 1, 8, S("23456789abcde")); + test(S("abcde"), 0, 0, S("1234567890"), 1, 9, S("234567890abcde")); + test(S("abcde"), 0, 0, S("1234567890"), 1, 10, S("234567890abcde")); + test(S("abcde"), 0, 0, S("1234567890"), 5, 0, S("abcde")); + test(S("abcde"), 0, 0, S("1234567890"), 5, 1, S("6abcde")); + test(S("abcde"), 0, 0, S("1234567890"), 5, 2, S("67abcde")); + test(S("abcde"), 0, 0, S("1234567890"), 5, 4, S("6789abcde")); + test(S("abcde"), 0, 0, S("1234567890"), 5, 5, S("67890abcde")); + test(S("abcde"), 0, 0, S("1234567890"), 5, 6, S("67890abcde")); + test(S("abcde"), 0, 0, S("1234567890"), 9, 0, S("abcde")); + test(S("abcde"), 0, 0, S("1234567890"), 9, 1, S("0abcde")); + test(S("abcde"), 0, 0, S("1234567890"), 9, 2, S("0abcde")); + test(S("abcde"), 0, 0, S("1234567890"), 10, 0, S("abcde")); + test(S("abcde"), 0, 0, S("1234567890"), 10, 1, S("abcde")); + test(S("abcde"), 0, 0, S("1234567890"), 11, 0, S("can't happen")); + test(S("abcde"), 0, 0, S("12345678901234567890"), 0, 0, S("abcde")); + test(S("abcde"), 0, 0, S("12345678901234567890"), 0, 1, S("1abcde")); + test(S("abcde"), 0, 0, S("12345678901234567890"), 0, 10, S("1234567890abcde")); + test(S("abcde"), 0, 0, S("12345678901234567890"), 0, 19, S("1234567890123456789abcde")); + test(S("abcde"), 0, 0, S("12345678901234567890"), 0, 20, S("12345678901234567890abcde")); + test(S("abcde"), 0, 0, S("12345678901234567890"), 0, 21, S("12345678901234567890abcde")); + test(S("abcde"), 0, 0, S("12345678901234567890"), 1, 0, S("abcde")); + test(S("abcde"), 0, 0, S("12345678901234567890"), 1, 1, S("2abcde")); + test(S("abcde"), 0, 0, S("12345678901234567890"), 1, 9, S("234567890abcde")); + test(S("abcde"), 0, 0, S("12345678901234567890"), 1, 18, S("234567890123456789abcde")); + test(S("abcde"), 0, 0, S("12345678901234567890"), 1, 19, S("2345678901234567890abcde")); + test(S("abcde"), 0, 0, S("12345678901234567890"), 1, 20, S("2345678901234567890abcde")); + test(S("abcde"), 0, 0, S("12345678901234567890"), 10, 0, S("abcde")); + test(S("abcde"), 0, 0, S("12345678901234567890"), 10, 1, S("1abcde")); + test(S("abcde"), 0, 0, S("12345678901234567890"), 10, 5, S("12345abcde")); + test(S("abcde"), 0, 0, S("12345678901234567890"), 10, 9, S("123456789abcde")); + test(S("abcde"), 0, 0, S("12345678901234567890"), 10, 10, S("1234567890abcde")); + test(S("abcde"), 0, 0, S("12345678901234567890"), 10, 11, S("1234567890abcde")); + test(S("abcde"), 0, 0, S("12345678901234567890"), 19, 0, S("abcde")); + test(S("abcde"), 0, 0, S("12345678901234567890"), 19, 1, S("0abcde")); + test(S("abcde"), 0, 0, S("12345678901234567890"), 19, 2, S("0abcde")); + test(S("abcde"), 0, 0, S("12345678901234567890"), 20, 0, S("abcde")); + test(S("abcde"), 0, 0, S("12345678901234567890"), 20, 1, S("abcde")); + test(S("abcde"), 0, 0, S("12345678901234567890"), 21, 0, S("can't happen")); + test(S("abcde"), 0, 1, S(""), 0, 0, S("bcde")); + test(S("abcde"), 0, 1, S(""), 0, 1, S("bcde")); + test(S("abcde"), 0, 1, S(""), 1, 0, S("can't happen")); + test(S("abcde"), 0, 1, S("12345"), 0, 0, S("bcde")); +} + +template +void test3() +{ + test(S("abcde"), 0, 1, S("12345"), 0, 1, S("1bcde")); + test(S("abcde"), 0, 1, S("12345"), 0, 2, S("12bcde")); + test(S("abcde"), 0, 1, S("12345"), 0, 4, S("1234bcde")); + test(S("abcde"), 0, 1, S("12345"), 0, 5, S("12345bcde")); + test(S("abcde"), 0, 1, S("12345"), 0, 6, S("12345bcde")); + test(S("abcde"), 0, 1, S("12345"), 1, 0, S("bcde")); + test(S("abcde"), 0, 1, S("12345"), 1, 1, S("2bcde")); + test(S("abcde"), 0, 1, S("12345"), 1, 2, S("23bcde")); + test(S("abcde"), 0, 1, S("12345"), 1, 3, S("234bcde")); + test(S("abcde"), 0, 1, S("12345"), 1, 4, S("2345bcde")); + test(S("abcde"), 0, 1, S("12345"), 1, 5, S("2345bcde")); + test(S("abcde"), 0, 1, S("12345"), 2, 0, S("bcde")); + test(S("abcde"), 0, 1, S("12345"), 2, 1, S("3bcde")); + test(S("abcde"), 0, 1, S("12345"), 2, 2, S("34bcde")); + test(S("abcde"), 0, 1, S("12345"), 2, 3, S("345bcde")); + test(S("abcde"), 0, 1, S("12345"), 2, 4, S("345bcde")); + test(S("abcde"), 0, 1, S("12345"), 4, 0, S("bcde")); + test(S("abcde"), 0, 1, S("12345"), 4, 1, S("5bcde")); + test(S("abcde"), 0, 1, S("12345"), 4, 2, S("5bcde")); + test(S("abcde"), 0, 1, S("12345"), 5, 0, S("bcde")); + test(S("abcde"), 0, 1, S("12345"), 5, 1, S("bcde")); + test(S("abcde"), 0, 1, S("12345"), 6, 0, S("can't happen")); + test(S("abcde"), 0, 1, S("1234567890"), 0, 0, S("bcde")); + test(S("abcde"), 0, 1, S("1234567890"), 0, 1, S("1bcde")); + test(S("abcde"), 0, 1, S("1234567890"), 0, 5, S("12345bcde")); + test(S("abcde"), 0, 1, S("1234567890"), 0, 9, S("123456789bcde")); + test(S("abcde"), 0, 1, S("1234567890"), 0, 10, S("1234567890bcde")); + test(S("abcde"), 0, 1, S("1234567890"), 0, 11, S("1234567890bcde")); + test(S("abcde"), 0, 1, S("1234567890"), 1, 0, S("bcde")); + test(S("abcde"), 0, 1, S("1234567890"), 1, 1, S("2bcde")); + test(S("abcde"), 0, 1, S("1234567890"), 1, 4, S("2345bcde")); + test(S("abcde"), 0, 1, S("1234567890"), 1, 8, S("23456789bcde")); + test(S("abcde"), 0, 1, S("1234567890"), 1, 9, S("234567890bcde")); + test(S("abcde"), 0, 1, S("1234567890"), 1, 10, S("234567890bcde")); + test(S("abcde"), 0, 1, S("1234567890"), 5, 0, S("bcde")); + test(S("abcde"), 0, 1, S("1234567890"), 5, 1, S("6bcde")); + test(S("abcde"), 0, 1, S("1234567890"), 5, 2, S("67bcde")); + test(S("abcde"), 0, 1, S("1234567890"), 5, 4, S("6789bcde")); + test(S("abcde"), 0, 1, S("1234567890"), 5, 5, S("67890bcde")); + test(S("abcde"), 0, 1, S("1234567890"), 5, 6, S("67890bcde")); + test(S("abcde"), 0, 1, S("1234567890"), 9, 0, S("bcde")); + test(S("abcde"), 0, 1, S("1234567890"), 9, 1, S("0bcde")); + test(S("abcde"), 0, 1, S("1234567890"), 9, 2, S("0bcde")); + test(S("abcde"), 0, 1, S("1234567890"), 10, 0, S("bcde")); + test(S("abcde"), 0, 1, S("1234567890"), 10, 1, S("bcde")); + test(S("abcde"), 0, 1, S("1234567890"), 11, 0, S("can't happen")); + test(S("abcde"), 0, 1, S("12345678901234567890"), 0, 0, S("bcde")); + test(S("abcde"), 0, 1, S("12345678901234567890"), 0, 1, S("1bcde")); + test(S("abcde"), 0, 1, S("12345678901234567890"), 0, 10, S("1234567890bcde")); + test(S("abcde"), 0, 1, S("12345678901234567890"), 0, 19, S("1234567890123456789bcde")); + test(S("abcde"), 0, 1, S("12345678901234567890"), 0, 20, S("12345678901234567890bcde")); + test(S("abcde"), 0, 1, S("12345678901234567890"), 0, 21, S("12345678901234567890bcde")); + test(S("abcde"), 0, 1, S("12345678901234567890"), 1, 0, S("bcde")); + test(S("abcde"), 0, 1, S("12345678901234567890"), 1, 1, S("2bcde")); + test(S("abcde"), 0, 1, S("12345678901234567890"), 1, 9, S("234567890bcde")); + test(S("abcde"), 0, 1, S("12345678901234567890"), 1, 18, S("234567890123456789bcde")); + test(S("abcde"), 0, 1, S("12345678901234567890"), 1, 19, S("2345678901234567890bcde")); + test(S("abcde"), 0, 1, S("12345678901234567890"), 1, 20, S("2345678901234567890bcde")); + test(S("abcde"), 0, 1, S("12345678901234567890"), 10, 0, S("bcde")); + test(S("abcde"), 0, 1, S("12345678901234567890"), 10, 1, S("1bcde")); + test(S("abcde"), 0, 1, S("12345678901234567890"), 10, 5, S("12345bcde")); + test(S("abcde"), 0, 1, S("12345678901234567890"), 10, 9, S("123456789bcde")); + test(S("abcde"), 0, 1, S("12345678901234567890"), 10, 10, S("1234567890bcde")); + test(S("abcde"), 0, 1, S("12345678901234567890"), 10, 11, S("1234567890bcde")); + test(S("abcde"), 0, 1, S("12345678901234567890"), 19, 0, S("bcde")); + test(S("abcde"), 0, 1, S("12345678901234567890"), 19, 1, S("0bcde")); + test(S("abcde"), 0, 1, S("12345678901234567890"), 19, 2, S("0bcde")); + test(S("abcde"), 0, 1, S("12345678901234567890"), 20, 0, S("bcde")); + test(S("abcde"), 0, 1, S("12345678901234567890"), 20, 1, S("bcde")); + test(S("abcde"), 0, 1, S("12345678901234567890"), 21, 0, S("can't happen")); + test(S("abcde"), 0, 2, S(""), 0, 0, S("cde")); + test(S("abcde"), 0, 2, S(""), 0, 1, S("cde")); + test(S("abcde"), 0, 2, S(""), 1, 0, S("can't happen")); + test(S("abcde"), 0, 2, S("12345"), 0, 0, S("cde")); + test(S("abcde"), 0, 2, S("12345"), 0, 1, S("1cde")); + test(S("abcde"), 0, 2, S("12345"), 0, 2, S("12cde")); + test(S("abcde"), 0, 2, S("12345"), 0, 4, S("1234cde")); + test(S("abcde"), 0, 2, S("12345"), 0, 5, S("12345cde")); + test(S("abcde"), 0, 2, S("12345"), 0, 6, S("12345cde")); + test(S("abcde"), 0, 2, S("12345"), 1, 0, S("cde")); + test(S("abcde"), 0, 2, S("12345"), 1, 1, S("2cde")); + test(S("abcde"), 0, 2, S("12345"), 1, 2, S("23cde")); + test(S("abcde"), 0, 2, S("12345"), 1, 3, S("234cde")); + test(S("abcde"), 0, 2, S("12345"), 1, 4, S("2345cde")); + test(S("abcde"), 0, 2, S("12345"), 1, 5, S("2345cde")); + test(S("abcde"), 0, 2, S("12345"), 2, 0, S("cde")); + test(S("abcde"), 0, 2, S("12345"), 2, 1, S("3cde")); + test(S("abcde"), 0, 2, S("12345"), 2, 2, S("34cde")); + test(S("abcde"), 0, 2, S("12345"), 2, 3, S("345cde")); + test(S("abcde"), 0, 2, S("12345"), 2, 4, S("345cde")); + test(S("abcde"), 0, 2, S("12345"), 4, 0, S("cde")); + test(S("abcde"), 0, 2, S("12345"), 4, 1, S("5cde")); + test(S("abcde"), 0, 2, S("12345"), 4, 2, S("5cde")); + test(S("abcde"), 0, 2, S("12345"), 5, 0, S("cde")); + test(S("abcde"), 0, 2, S("12345"), 5, 1, S("cde")); + test(S("abcde"), 0, 2, S("12345"), 6, 0, S("can't happen")); + test(S("abcde"), 0, 2, S("1234567890"), 0, 0, S("cde")); + test(S("abcde"), 0, 2, S("1234567890"), 0, 1, S("1cde")); + test(S("abcde"), 0, 2, S("1234567890"), 0, 5, S("12345cde")); + test(S("abcde"), 0, 2, S("1234567890"), 0, 9, S("123456789cde")); +} + +template +void test4() +{ + test(S("abcde"), 0, 2, S("1234567890"), 0, 10, S("1234567890cde")); + test(S("abcde"), 0, 2, S("1234567890"), 0, 11, S("1234567890cde")); + test(S("abcde"), 0, 2, S("1234567890"), 1, 0, S("cde")); + test(S("abcde"), 0, 2, S("1234567890"), 1, 1, S("2cde")); + test(S("abcde"), 0, 2, S("1234567890"), 1, 4, S("2345cde")); + test(S("abcde"), 0, 2, S("1234567890"), 1, 8, S("23456789cde")); + test(S("abcde"), 0, 2, S("1234567890"), 1, 9, S("234567890cde")); + test(S("abcde"), 0, 2, S("1234567890"), 1, 10, S("234567890cde")); + test(S("abcde"), 0, 2, S("1234567890"), 5, 0, S("cde")); + test(S("abcde"), 0, 2, S("1234567890"), 5, 1, S("6cde")); + test(S("abcde"), 0, 2, S("1234567890"), 5, 2, S("67cde")); + test(S("abcde"), 0, 2, S("1234567890"), 5, 4, S("6789cde")); + test(S("abcde"), 0, 2, S("1234567890"), 5, 5, S("67890cde")); + test(S("abcde"), 0, 2, S("1234567890"), 5, 6, S("67890cde")); + test(S("abcde"), 0, 2, S("1234567890"), 9, 0, S("cde")); + test(S("abcde"), 0, 2, S("1234567890"), 9, 1, S("0cde")); + test(S("abcde"), 0, 2, S("1234567890"), 9, 2, S("0cde")); + test(S("abcde"), 0, 2, S("1234567890"), 10, 0, S("cde")); + test(S("abcde"), 0, 2, S("1234567890"), 10, 1, S("cde")); + test(S("abcde"), 0, 2, S("1234567890"), 11, 0, S("can't happen")); + test(S("abcde"), 0, 2, S("12345678901234567890"), 0, 0, S("cde")); + test(S("abcde"), 0, 2, S("12345678901234567890"), 0, 1, S("1cde")); + test(S("abcde"), 0, 2, S("12345678901234567890"), 0, 10, S("1234567890cde")); + test(S("abcde"), 0, 2, S("12345678901234567890"), 0, 19, S("1234567890123456789cde")); + test(S("abcde"), 0, 2, S("12345678901234567890"), 0, 20, S("12345678901234567890cde")); + test(S("abcde"), 0, 2, S("12345678901234567890"), 0, 21, S("12345678901234567890cde")); + test(S("abcde"), 0, 2, S("12345678901234567890"), 1, 0, S("cde")); + test(S("abcde"), 0, 2, S("12345678901234567890"), 1, 1, S("2cde")); + test(S("abcde"), 0, 2, S("12345678901234567890"), 1, 9, S("234567890cde")); + test(S("abcde"), 0, 2, S("12345678901234567890"), 1, 18, S("234567890123456789cde")); + test(S("abcde"), 0, 2, S("12345678901234567890"), 1, 19, S("2345678901234567890cde")); + test(S("abcde"), 0, 2, S("12345678901234567890"), 1, 20, S("2345678901234567890cde")); + test(S("abcde"), 0, 2, S("12345678901234567890"), 10, 0, S("cde")); + test(S("abcde"), 0, 2, S("12345678901234567890"), 10, 1, S("1cde")); + test(S("abcde"), 0, 2, S("12345678901234567890"), 10, 5, S("12345cde")); + test(S("abcde"), 0, 2, S("12345678901234567890"), 10, 9, S("123456789cde")); + test(S("abcde"), 0, 2, S("12345678901234567890"), 10, 10, S("1234567890cde")); + test(S("abcde"), 0, 2, S("12345678901234567890"), 10, 11, S("1234567890cde")); + test(S("abcde"), 0, 2, S("12345678901234567890"), 19, 0, S("cde")); + test(S("abcde"), 0, 2, S("12345678901234567890"), 19, 1, S("0cde")); + test(S("abcde"), 0, 2, S("12345678901234567890"), 19, 2, S("0cde")); + test(S("abcde"), 0, 2, S("12345678901234567890"), 20, 0, S("cde")); + test(S("abcde"), 0, 2, S("12345678901234567890"), 20, 1, S("cde")); + test(S("abcde"), 0, 2, S("12345678901234567890"), 21, 0, S("can't happen")); + test(S("abcde"), 0, 4, S(""), 0, 0, S("e")); + test(S("abcde"), 0, 4, S(""), 0, 1, S("e")); + test(S("abcde"), 0, 4, S(""), 1, 0, S("can't happen")); + test(S("abcde"), 0, 4, S("12345"), 0, 0, S("e")); + test(S("abcde"), 0, 4, S("12345"), 0, 1, S("1e")); + test(S("abcde"), 0, 4, S("12345"), 0, 2, S("12e")); + test(S("abcde"), 0, 4, S("12345"), 0, 4, S("1234e")); + test(S("abcde"), 0, 4, S("12345"), 0, 5, S("12345e")); + test(S("abcde"), 0, 4, S("12345"), 0, 6, S("12345e")); + test(S("abcde"), 0, 4, S("12345"), 1, 0, S("e")); + test(S("abcde"), 0, 4, S("12345"), 1, 1, S("2e")); + test(S("abcde"), 0, 4, S("12345"), 1, 2, S("23e")); + test(S("abcde"), 0, 4, S("12345"), 1, 3, S("234e")); + test(S("abcde"), 0, 4, S("12345"), 1, 4, S("2345e")); + test(S("abcde"), 0, 4, S("12345"), 1, 5, S("2345e")); + test(S("abcde"), 0, 4, S("12345"), 2, 0, S("e")); + test(S("abcde"), 0, 4, S("12345"), 2, 1, S("3e")); + test(S("abcde"), 0, 4, S("12345"), 2, 2, S("34e")); + test(S("abcde"), 0, 4, S("12345"), 2, 3, S("345e")); + test(S("abcde"), 0, 4, S("12345"), 2, 4, S("345e")); + test(S("abcde"), 0, 4, S("12345"), 4, 0, S("e")); + test(S("abcde"), 0, 4, S("12345"), 4, 1, S("5e")); + test(S("abcde"), 0, 4, S("12345"), 4, 2, S("5e")); + test(S("abcde"), 0, 4, S("12345"), 5, 0, S("e")); + test(S("abcde"), 0, 4, S("12345"), 5, 1, S("e")); + test(S("abcde"), 0, 4, S("12345"), 6, 0, S("can't happen")); + test(S("abcde"), 0, 4, S("1234567890"), 0, 0, S("e")); + test(S("abcde"), 0, 4, S("1234567890"), 0, 1, S("1e")); + test(S("abcde"), 0, 4, S("1234567890"), 0, 5, S("12345e")); + test(S("abcde"), 0, 4, S("1234567890"), 0, 9, S("123456789e")); + test(S("abcde"), 0, 4, S("1234567890"), 0, 10, S("1234567890e")); + test(S("abcde"), 0, 4, S("1234567890"), 0, 11, S("1234567890e")); + test(S("abcde"), 0, 4, S("1234567890"), 1, 0, S("e")); + test(S("abcde"), 0, 4, S("1234567890"), 1, 1, S("2e")); + test(S("abcde"), 0, 4, S("1234567890"), 1, 4, S("2345e")); + test(S("abcde"), 0, 4, S("1234567890"), 1, 8, S("23456789e")); + test(S("abcde"), 0, 4, S("1234567890"), 1, 9, S("234567890e")); + test(S("abcde"), 0, 4, S("1234567890"), 1, 10, S("234567890e")); + test(S("abcde"), 0, 4, S("1234567890"), 5, 0, S("e")); + test(S("abcde"), 0, 4, S("1234567890"), 5, 1, S("6e")); + test(S("abcde"), 0, 4, S("1234567890"), 5, 2, S("67e")); + test(S("abcde"), 0, 4, S("1234567890"), 5, 4, S("6789e")); + test(S("abcde"), 0, 4, S("1234567890"), 5, 5, S("67890e")); + test(S("abcde"), 0, 4, S("1234567890"), 5, 6, S("67890e")); + test(S("abcde"), 0, 4, S("1234567890"), 9, 0, S("e")); + test(S("abcde"), 0, 4, S("1234567890"), 9, 1, S("0e")); + test(S("abcde"), 0, 4, S("1234567890"), 9, 2, S("0e")); + test(S("abcde"), 0, 4, S("1234567890"), 10, 0, S("e")); + test(S("abcde"), 0, 4, S("1234567890"), 10, 1, S("e")); + test(S("abcde"), 0, 4, S("1234567890"), 11, 0, S("can't happen")); + test(S("abcde"), 0, 4, S("12345678901234567890"), 0, 0, S("e")); + test(S("abcde"), 0, 4, S("12345678901234567890"), 0, 1, S("1e")); + test(S("abcde"), 0, 4, S("12345678901234567890"), 0, 10, S("1234567890e")); + test(S("abcde"), 0, 4, S("12345678901234567890"), 0, 19, S("1234567890123456789e")); + test(S("abcde"), 0, 4, S("12345678901234567890"), 0, 20, S("12345678901234567890e")); + test(S("abcde"), 0, 4, S("12345678901234567890"), 0, 21, S("12345678901234567890e")); +} + +template +void test5() +{ + test(S("abcde"), 0, 4, S("12345678901234567890"), 1, 0, S("e")); + test(S("abcde"), 0, 4, S("12345678901234567890"), 1, 1, S("2e")); + test(S("abcde"), 0, 4, S("12345678901234567890"), 1, 9, S("234567890e")); + test(S("abcde"), 0, 4, S("12345678901234567890"), 1, 18, S("234567890123456789e")); + test(S("abcde"), 0, 4, S("12345678901234567890"), 1, 19, S("2345678901234567890e")); + test(S("abcde"), 0, 4, S("12345678901234567890"), 1, 20, S("2345678901234567890e")); + test(S("abcde"), 0, 4, S("12345678901234567890"), 10, 0, S("e")); + test(S("abcde"), 0, 4, S("12345678901234567890"), 10, 1, S("1e")); + test(S("abcde"), 0, 4, S("12345678901234567890"), 10, 5, S("12345e")); + test(S("abcde"), 0, 4, S("12345678901234567890"), 10, 9, S("123456789e")); + test(S("abcde"), 0, 4, S("12345678901234567890"), 10, 10, S("1234567890e")); + test(S("abcde"), 0, 4, S("12345678901234567890"), 10, 11, S("1234567890e")); + test(S("abcde"), 0, 4, S("12345678901234567890"), 19, 0, S("e")); + test(S("abcde"), 0, 4, S("12345678901234567890"), 19, 1, S("0e")); + test(S("abcde"), 0, 4, S("12345678901234567890"), 19, 2, S("0e")); + test(S("abcde"), 0, 4, S("12345678901234567890"), 20, 0, S("e")); + test(S("abcde"), 0, 4, S("12345678901234567890"), 20, 1, S("e")); + test(S("abcde"), 0, 4, S("12345678901234567890"), 21, 0, S("can't happen")); + test(S("abcde"), 0, 5, S(""), 0, 0, S("")); + test(S("abcde"), 0, 5, S(""), 0, 1, S("")); + test(S("abcde"), 0, 5, S(""), 1, 0, S("can't happen")); + test(S("abcde"), 0, 5, S("12345"), 0, 0, S("")); + test(S("abcde"), 0, 5, S("12345"), 0, 1, S("1")); + test(S("abcde"), 0, 5, S("12345"), 0, 2, S("12")); + test(S("abcde"), 0, 5, S("12345"), 0, 4, S("1234")); + test(S("abcde"), 0, 5, S("12345"), 0, 5, S("12345")); + test(S("abcde"), 0, 5, S("12345"), 0, 6, S("12345")); + test(S("abcde"), 0, 5, S("12345"), 1, 0, S("")); + test(S("abcde"), 0, 5, S("12345"), 1, 1, S("2")); + test(S("abcde"), 0, 5, S("12345"), 1, 2, S("23")); + test(S("abcde"), 0, 5, S("12345"), 1, 3, S("234")); + test(S("abcde"), 0, 5, S("12345"), 1, 4, S("2345")); + test(S("abcde"), 0, 5, S("12345"), 1, 5, S("2345")); + test(S("abcde"), 0, 5, S("12345"), 2, 0, S("")); + test(S("abcde"), 0, 5, S("12345"), 2, 1, S("3")); + test(S("abcde"), 0, 5, S("12345"), 2, 2, S("34")); + test(S("abcde"), 0, 5, S("12345"), 2, 3, S("345")); + test(S("abcde"), 0, 5, S("12345"), 2, 4, S("345")); + test(S("abcde"), 0, 5, S("12345"), 4, 0, S("")); + test(S("abcde"), 0, 5, S("12345"), 4, 1, S("5")); + test(S("abcde"), 0, 5, S("12345"), 4, 2, S("5")); + test(S("abcde"), 0, 5, S("12345"), 5, 0, S("")); + test(S("abcde"), 0, 5, S("12345"), 5, 1, S("")); + test(S("abcde"), 0, 5, S("12345"), 6, 0, S("can't happen")); + test(S("abcde"), 0, 5, S("1234567890"), 0, 0, S("")); + test(S("abcde"), 0, 5, S("1234567890"), 0, 1, S("1")); + test(S("abcde"), 0, 5, S("1234567890"), 0, 5, S("12345")); + test(S("abcde"), 0, 5, S("1234567890"), 0, 9, S("123456789")); + test(S("abcde"), 0, 5, S("1234567890"), 0, 10, S("1234567890")); + test(S("abcde"), 0, 5, S("1234567890"), 0, 11, S("1234567890")); + test(S("abcde"), 0, 5, S("1234567890"), 1, 0, S("")); + test(S("abcde"), 0, 5, S("1234567890"), 1, 1, S("2")); + test(S("abcde"), 0, 5, S("1234567890"), 1, 4, S("2345")); + test(S("abcde"), 0, 5, S("1234567890"), 1, 8, S("23456789")); + test(S("abcde"), 0, 5, S("1234567890"), 1, 9, S("234567890")); + test(S("abcde"), 0, 5, S("1234567890"), 1, 10, S("234567890")); + test(S("abcde"), 0, 5, S("1234567890"), 5, 0, S("")); + test(S("abcde"), 0, 5, S("1234567890"), 5, 1, S("6")); + test(S("abcde"), 0, 5, S("1234567890"), 5, 2, S("67")); + test(S("abcde"), 0, 5, S("1234567890"), 5, 4, S("6789")); + test(S("abcde"), 0, 5, S("1234567890"), 5, 5, S("67890")); + test(S("abcde"), 0, 5, S("1234567890"), 5, 6, S("67890")); + test(S("abcde"), 0, 5, S("1234567890"), 9, 0, S("")); + test(S("abcde"), 0, 5, S("1234567890"), 9, 1, S("0")); + test(S("abcde"), 0, 5, S("1234567890"), 9, 2, S("0")); + test(S("abcde"), 0, 5, S("1234567890"), 10, 0, S("")); + test(S("abcde"), 0, 5, S("1234567890"), 10, 1, S("")); + test(S("abcde"), 0, 5, S("1234567890"), 11, 0, S("can't happen")); + test(S("abcde"), 0, 5, S("12345678901234567890"), 0, 0, S("")); + test(S("abcde"), 0, 5, S("12345678901234567890"), 0, 1, S("1")); + test(S("abcde"), 0, 5, S("12345678901234567890"), 0, 10, S("1234567890")); + test(S("abcde"), 0, 5, S("12345678901234567890"), 0, 19, S("1234567890123456789")); + test(S("abcde"), 0, 5, S("12345678901234567890"), 0, 20, S("12345678901234567890")); + test(S("abcde"), 0, 5, S("12345678901234567890"), 0, 21, S("12345678901234567890")); + test(S("abcde"), 0, 5, S("12345678901234567890"), 1, 0, S("")); + test(S("abcde"), 0, 5, S("12345678901234567890"), 1, 1, S("2")); + test(S("abcde"), 0, 5, S("12345678901234567890"), 1, 9, S("234567890")); + test(S("abcde"), 0, 5, S("12345678901234567890"), 1, 18, S("234567890123456789")); + test(S("abcde"), 0, 5, S("12345678901234567890"), 1, 19, S("2345678901234567890")); + test(S("abcde"), 0, 5, S("12345678901234567890"), 1, 20, S("2345678901234567890")); + test(S("abcde"), 0, 5, S("12345678901234567890"), 10, 0, S("")); + test(S("abcde"), 0, 5, S("12345678901234567890"), 10, 1, S("1")); + test(S("abcde"), 0, 5, S("12345678901234567890"), 10, 5, S("12345")); + test(S("abcde"), 0, 5, S("12345678901234567890"), 10, 9, S("123456789")); + test(S("abcde"), 0, 5, S("12345678901234567890"), 10, 10, S("1234567890")); + test(S("abcde"), 0, 5, S("12345678901234567890"), 10, 11, S("1234567890")); + test(S("abcde"), 0, 5, S("12345678901234567890"), 19, 0, S("")); + test(S("abcde"), 0, 5, S("12345678901234567890"), 19, 1, S("0")); + test(S("abcde"), 0, 5, S("12345678901234567890"), 19, 2, S("0")); + test(S("abcde"), 0, 5, S("12345678901234567890"), 20, 0, S("")); + test(S("abcde"), 0, 5, S("12345678901234567890"), 20, 1, S("")); + test(S("abcde"), 0, 5, S("12345678901234567890"), 21, 0, S("can't happen")); + test(S("abcde"), 0, 6, S(""), 0, 0, S("")); + test(S("abcde"), 0, 6, S(""), 0, 1, S("")); + test(S("abcde"), 0, 6, S(""), 1, 0, S("can't happen")); + test(S("abcde"), 0, 6, S("12345"), 0, 0, S("")); + test(S("abcde"), 0, 6, S("12345"), 0, 1, S("1")); + test(S("abcde"), 0, 6, S("12345"), 0, 2, S("12")); + test(S("abcde"), 0, 6, S("12345"), 0, 4, S("1234")); + test(S("abcde"), 0, 6, S("12345"), 0, 5, S("12345")); +} + +template +void test6() +{ + test(S("abcde"), 0, 6, S("12345"), 0, 6, S("12345")); + test(S("abcde"), 0, 6, S("12345"), 1, 0, S("")); + test(S("abcde"), 0, 6, S("12345"), 1, 1, S("2")); + test(S("abcde"), 0, 6, S("12345"), 1, 2, S("23")); + test(S("abcde"), 0, 6, S("12345"), 1, 3, S("234")); + test(S("abcde"), 0, 6, S("12345"), 1, 4, S("2345")); + test(S("abcde"), 0, 6, S("12345"), 1, 5, S("2345")); + test(S("abcde"), 0, 6, S("12345"), 2, 0, S("")); + test(S("abcde"), 0, 6, S("12345"), 2, 1, S("3")); + test(S("abcde"), 0, 6, S("12345"), 2, 2, S("34")); + test(S("abcde"), 0, 6, S("12345"), 2, 3, S("345")); + test(S("abcde"), 0, 6, S("12345"), 2, 4, S("345")); + test(S("abcde"), 0, 6, S("12345"), 4, 0, S("")); + test(S("abcde"), 0, 6, S("12345"), 4, 1, S("5")); + test(S("abcde"), 0, 6, S("12345"), 4, 2, S("5")); + test(S("abcde"), 0, 6, S("12345"), 5, 0, S("")); + test(S("abcde"), 0, 6, S("12345"), 5, 1, S("")); + test(S("abcde"), 0, 6, S("12345"), 6, 0, S("can't happen")); + test(S("abcde"), 0, 6, S("1234567890"), 0, 0, S("")); + test(S("abcde"), 0, 6, S("1234567890"), 0, 1, S("1")); + test(S("abcde"), 0, 6, S("1234567890"), 0, 5, S("12345")); + test(S("abcde"), 0, 6, S("1234567890"), 0, 9, S("123456789")); + test(S("abcde"), 0, 6, S("1234567890"), 0, 10, S("1234567890")); + test(S("abcde"), 0, 6, S("1234567890"), 0, 11, S("1234567890")); + test(S("abcde"), 0, 6, S("1234567890"), 1, 0, S("")); + test(S("abcde"), 0, 6, S("1234567890"), 1, 1, S("2")); + test(S("abcde"), 0, 6, S("1234567890"), 1, 4, S("2345")); + test(S("abcde"), 0, 6, S("1234567890"), 1, 8, S("23456789")); + test(S("abcde"), 0, 6, S("1234567890"), 1, 9, S("234567890")); + test(S("abcde"), 0, 6, S("1234567890"), 1, 10, S("234567890")); + test(S("abcde"), 0, 6, S("1234567890"), 5, 0, S("")); + test(S("abcde"), 0, 6, S("1234567890"), 5, 1, S("6")); + test(S("abcde"), 0, 6, S("1234567890"), 5, 2, S("67")); + test(S("abcde"), 0, 6, S("1234567890"), 5, 4, S("6789")); + test(S("abcde"), 0, 6, S("1234567890"), 5, 5, S("67890")); + test(S("abcde"), 0, 6, S("1234567890"), 5, 6, S("67890")); + test(S("abcde"), 0, 6, S("1234567890"), 9, 0, S("")); + test(S("abcde"), 0, 6, S("1234567890"), 9, 1, S("0")); + test(S("abcde"), 0, 6, S("1234567890"), 9, 2, S("0")); + test(S("abcde"), 0, 6, S("1234567890"), 10, 0, S("")); + test(S("abcde"), 0, 6, S("1234567890"), 10, 1, S("")); + test(S("abcde"), 0, 6, S("1234567890"), 11, 0, S("can't happen")); + test(S("abcde"), 0, 6, S("12345678901234567890"), 0, 0, S("")); + test(S("abcde"), 0, 6, S("12345678901234567890"), 0, 1, S("1")); + test(S("abcde"), 0, 6, S("12345678901234567890"), 0, 10, S("1234567890")); + test(S("abcde"), 0, 6, S("12345678901234567890"), 0, 19, S("1234567890123456789")); + test(S("abcde"), 0, 6, S("12345678901234567890"), 0, 20, S("12345678901234567890")); + test(S("abcde"), 0, 6, S("12345678901234567890"), 0, 21, S("12345678901234567890")); + test(S("abcde"), 0, 6, S("12345678901234567890"), 1, 0, S("")); + test(S("abcde"), 0, 6, S("12345678901234567890"), 1, 1, S("2")); + test(S("abcde"), 0, 6, S("12345678901234567890"), 1, 9, S("234567890")); + test(S("abcde"), 0, 6, S("12345678901234567890"), 1, 18, S("234567890123456789")); + test(S("abcde"), 0, 6, S("12345678901234567890"), 1, 19, S("2345678901234567890")); + test(S("abcde"), 0, 6, S("12345678901234567890"), 1, 20, S("2345678901234567890")); + test(S("abcde"), 0, 6, S("12345678901234567890"), 10, 0, S("")); + test(S("abcde"), 0, 6, S("12345678901234567890"), 10, 1, S("1")); + test(S("abcde"), 0, 6, S("12345678901234567890"), 10, 5, S("12345")); + test(S("abcde"), 0, 6, S("12345678901234567890"), 10, 9, S("123456789")); + test(S("abcde"), 0, 6, S("12345678901234567890"), 10, 10, S("1234567890")); + test(S("abcde"), 0, 6, S("12345678901234567890"), 10, 11, S("1234567890")); + test(S("abcde"), 0, 6, S("12345678901234567890"), 19, 0, S("")); + test(S("abcde"), 0, 6, S("12345678901234567890"), 19, 1, S("0")); + test(S("abcde"), 0, 6, S("12345678901234567890"), 19, 2, S("0")); + test(S("abcde"), 0, 6, S("12345678901234567890"), 20, 0, S("")); + test(S("abcde"), 0, 6, S("12345678901234567890"), 20, 1, S("")); + test(S("abcde"), 0, 6, S("12345678901234567890"), 21, 0, S("can't happen")); + test(S("abcde"), 1, 0, S(""), 0, 0, S("abcde")); + test(S("abcde"), 1, 0, S(""), 0, 1, S("abcde")); + test(S("abcde"), 1, 0, S(""), 1, 0, S("can't happen")); + test(S("abcde"), 1, 0, S("12345"), 0, 0, S("abcde")); + test(S("abcde"), 1, 0, S("12345"), 0, 1, S("a1bcde")); + test(S("abcde"), 1, 0, S("12345"), 0, 2, S("a12bcde")); + test(S("abcde"), 1, 0, S("12345"), 0, 4, S("a1234bcde")); + test(S("abcde"), 1, 0, S("12345"), 0, 5, S("a12345bcde")); + test(S("abcde"), 1, 0, S("12345"), 0, 6, S("a12345bcde")); + test(S("abcde"), 1, 0, S("12345"), 1, 0, S("abcde")); + test(S("abcde"), 1, 0, S("12345"), 1, 1, S("a2bcde")); + test(S("abcde"), 1, 0, S("12345"), 1, 2, S("a23bcde")); + test(S("abcde"), 1, 0, S("12345"), 1, 3, S("a234bcde")); + test(S("abcde"), 1, 0, S("12345"), 1, 4, S("a2345bcde")); + test(S("abcde"), 1, 0, S("12345"), 1, 5, S("a2345bcde")); + test(S("abcde"), 1, 0, S("12345"), 2, 0, S("abcde")); + test(S("abcde"), 1, 0, S("12345"), 2, 1, S("a3bcde")); + test(S("abcde"), 1, 0, S("12345"), 2, 2, S("a34bcde")); + test(S("abcde"), 1, 0, S("12345"), 2, 3, S("a345bcde")); + test(S("abcde"), 1, 0, S("12345"), 2, 4, S("a345bcde")); + test(S("abcde"), 1, 0, S("12345"), 4, 0, S("abcde")); + test(S("abcde"), 1, 0, S("12345"), 4, 1, S("a5bcde")); + test(S("abcde"), 1, 0, S("12345"), 4, 2, S("a5bcde")); + test(S("abcde"), 1, 0, S("12345"), 5, 0, S("abcde")); + test(S("abcde"), 1, 0, S("12345"), 5, 1, S("abcde")); + test(S("abcde"), 1, 0, S("12345"), 6, 0, S("can't happen")); + test(S("abcde"), 1, 0, S("1234567890"), 0, 0, S("abcde")); + test(S("abcde"), 1, 0, S("1234567890"), 0, 1, S("a1bcde")); + test(S("abcde"), 1, 0, S("1234567890"), 0, 5, S("a12345bcde")); + test(S("abcde"), 1, 0, S("1234567890"), 0, 9, S("a123456789bcde")); + test(S("abcde"), 1, 0, S("1234567890"), 0, 10, S("a1234567890bcde")); + test(S("abcde"), 1, 0, S("1234567890"), 0, 11, S("a1234567890bcde")); + test(S("abcde"), 1, 0, S("1234567890"), 1, 0, S("abcde")); + test(S("abcde"), 1, 0, S("1234567890"), 1, 1, S("a2bcde")); +} + +template +void test7() +{ + test(S("abcde"), 1, 0, S("1234567890"), 1, 4, S("a2345bcde")); + test(S("abcde"), 1, 0, S("1234567890"), 1, 8, S("a23456789bcde")); + test(S("abcde"), 1, 0, S("1234567890"), 1, 9, S("a234567890bcde")); + test(S("abcde"), 1, 0, S("1234567890"), 1, 10, S("a234567890bcde")); + test(S("abcde"), 1, 0, S("1234567890"), 5, 0, S("abcde")); + test(S("abcde"), 1, 0, S("1234567890"), 5, 1, S("a6bcde")); + test(S("abcde"), 1, 0, S("1234567890"), 5, 2, S("a67bcde")); + test(S("abcde"), 1, 0, S("1234567890"), 5, 4, S("a6789bcde")); + test(S("abcde"), 1, 0, S("1234567890"), 5, 5, S("a67890bcde")); + test(S("abcde"), 1, 0, S("1234567890"), 5, 6, S("a67890bcde")); + test(S("abcde"), 1, 0, S("1234567890"), 9, 0, S("abcde")); + test(S("abcde"), 1, 0, S("1234567890"), 9, 1, S("a0bcde")); + test(S("abcde"), 1, 0, S("1234567890"), 9, 2, S("a0bcde")); + test(S("abcde"), 1, 0, S("1234567890"), 10, 0, S("abcde")); + test(S("abcde"), 1, 0, S("1234567890"), 10, 1, S("abcde")); + test(S("abcde"), 1, 0, S("1234567890"), 11, 0, S("can't happen")); + test(S("abcde"), 1, 0, S("12345678901234567890"), 0, 0, S("abcde")); + test(S("abcde"), 1, 0, S("12345678901234567890"), 0, 1, S("a1bcde")); + test(S("abcde"), 1, 0, S("12345678901234567890"), 0, 10, S("a1234567890bcde")); + test(S("abcde"), 1, 0, S("12345678901234567890"), 0, 19, S("a1234567890123456789bcde")); + test(S("abcde"), 1, 0, S("12345678901234567890"), 0, 20, S("a12345678901234567890bcde")); + test(S("abcde"), 1, 0, S("12345678901234567890"), 0, 21, S("a12345678901234567890bcde")); + test(S("abcde"), 1, 0, S("12345678901234567890"), 1, 0, S("abcde")); + test(S("abcde"), 1, 0, S("12345678901234567890"), 1, 1, S("a2bcde")); + test(S("abcde"), 1, 0, S("12345678901234567890"), 1, 9, S("a234567890bcde")); + test(S("abcde"), 1, 0, S("12345678901234567890"), 1, 18, S("a234567890123456789bcde")); + test(S("abcde"), 1, 0, S("12345678901234567890"), 1, 19, S("a2345678901234567890bcde")); + test(S("abcde"), 1, 0, S("12345678901234567890"), 1, 20, S("a2345678901234567890bcde")); + test(S("abcde"), 1, 0, S("12345678901234567890"), 10, 0, S("abcde")); + test(S("abcde"), 1, 0, S("12345678901234567890"), 10, 1, S("a1bcde")); + test(S("abcde"), 1, 0, S("12345678901234567890"), 10, 5, S("a12345bcde")); + test(S("abcde"), 1, 0, S("12345678901234567890"), 10, 9, S("a123456789bcde")); + test(S("abcde"), 1, 0, S("12345678901234567890"), 10, 10, S("a1234567890bcde")); + test(S("abcde"), 1, 0, S("12345678901234567890"), 10, 11, S("a1234567890bcde")); + test(S("abcde"), 1, 0, S("12345678901234567890"), 19, 0, S("abcde")); + test(S("abcde"), 1, 0, S("12345678901234567890"), 19, 1, S("a0bcde")); + test(S("abcde"), 1, 0, S("12345678901234567890"), 19, 2, S("a0bcde")); + test(S("abcde"), 1, 0, S("12345678901234567890"), 20, 0, S("abcde")); + test(S("abcde"), 1, 0, S("12345678901234567890"), 20, 1, S("abcde")); + test(S("abcde"), 1, 0, S("12345678901234567890"), 21, 0, S("can't happen")); + test(S("abcde"), 1, 1, S(""), 0, 0, S("acde")); + test(S("abcde"), 1, 1, S(""), 0, 1, S("acde")); + test(S("abcde"), 1, 1, S(""), 1, 0, S("can't happen")); + test(S("abcde"), 1, 1, S("12345"), 0, 0, S("acde")); + test(S("abcde"), 1, 1, S("12345"), 0, 1, S("a1cde")); + test(S("abcde"), 1, 1, S("12345"), 0, 2, S("a12cde")); + test(S("abcde"), 1, 1, S("12345"), 0, 4, S("a1234cde")); + test(S("abcde"), 1, 1, S("12345"), 0, 5, S("a12345cde")); + test(S("abcde"), 1, 1, S("12345"), 0, 6, S("a12345cde")); + test(S("abcde"), 1, 1, S("12345"), 1, 0, S("acde")); + test(S("abcde"), 1, 1, S("12345"), 1, 1, S("a2cde")); + test(S("abcde"), 1, 1, S("12345"), 1, 2, S("a23cde")); + test(S("abcde"), 1, 1, S("12345"), 1, 3, S("a234cde")); + test(S("abcde"), 1, 1, S("12345"), 1, 4, S("a2345cde")); + test(S("abcde"), 1, 1, S("12345"), 1, 5, S("a2345cde")); + test(S("abcde"), 1, 1, S("12345"), 2, 0, S("acde")); + test(S("abcde"), 1, 1, S("12345"), 2, 1, S("a3cde")); + test(S("abcde"), 1, 1, S("12345"), 2, 2, S("a34cde")); + test(S("abcde"), 1, 1, S("12345"), 2, 3, S("a345cde")); + test(S("abcde"), 1, 1, S("12345"), 2, 4, S("a345cde")); + test(S("abcde"), 1, 1, S("12345"), 4, 0, S("acde")); + test(S("abcde"), 1, 1, S("12345"), 4, 1, S("a5cde")); + test(S("abcde"), 1, 1, S("12345"), 4, 2, S("a5cde")); + test(S("abcde"), 1, 1, S("12345"), 5, 0, S("acde")); + test(S("abcde"), 1, 1, S("12345"), 5, 1, S("acde")); + test(S("abcde"), 1, 1, S("12345"), 6, 0, S("can't happen")); + test(S("abcde"), 1, 1, S("1234567890"), 0, 0, S("acde")); + test(S("abcde"), 1, 1, S("1234567890"), 0, 1, S("a1cde")); + test(S("abcde"), 1, 1, S("1234567890"), 0, 5, S("a12345cde")); + test(S("abcde"), 1, 1, S("1234567890"), 0, 9, S("a123456789cde")); + test(S("abcde"), 1, 1, S("1234567890"), 0, 10, S("a1234567890cde")); + test(S("abcde"), 1, 1, S("1234567890"), 0, 11, S("a1234567890cde")); + test(S("abcde"), 1, 1, S("1234567890"), 1, 0, S("acde")); + test(S("abcde"), 1, 1, S("1234567890"), 1, 1, S("a2cde")); + test(S("abcde"), 1, 1, S("1234567890"), 1, 4, S("a2345cde")); + test(S("abcde"), 1, 1, S("1234567890"), 1, 8, S("a23456789cde")); + test(S("abcde"), 1, 1, S("1234567890"), 1, 9, S("a234567890cde")); + test(S("abcde"), 1, 1, S("1234567890"), 1, 10, S("a234567890cde")); + test(S("abcde"), 1, 1, S("1234567890"), 5, 0, S("acde")); + test(S("abcde"), 1, 1, S("1234567890"), 5, 1, S("a6cde")); + test(S("abcde"), 1, 1, S("1234567890"), 5, 2, S("a67cde")); + test(S("abcde"), 1, 1, S("1234567890"), 5, 4, S("a6789cde")); + test(S("abcde"), 1, 1, S("1234567890"), 5, 5, S("a67890cde")); + test(S("abcde"), 1, 1, S("1234567890"), 5, 6, S("a67890cde")); + test(S("abcde"), 1, 1, S("1234567890"), 9, 0, S("acde")); + test(S("abcde"), 1, 1, S("1234567890"), 9, 1, S("a0cde")); + test(S("abcde"), 1, 1, S("1234567890"), 9, 2, S("a0cde")); + test(S("abcde"), 1, 1, S("1234567890"), 10, 0, S("acde")); + test(S("abcde"), 1, 1, S("1234567890"), 10, 1, S("acde")); + test(S("abcde"), 1, 1, S("1234567890"), 11, 0, S("can't happen")); + test(S("abcde"), 1, 1, S("12345678901234567890"), 0, 0, S("acde")); + test(S("abcde"), 1, 1, S("12345678901234567890"), 0, 1, S("a1cde")); + test(S("abcde"), 1, 1, S("12345678901234567890"), 0, 10, S("a1234567890cde")); + test(S("abcde"), 1, 1, S("12345678901234567890"), 0, 19, S("a1234567890123456789cde")); + test(S("abcde"), 1, 1, S("12345678901234567890"), 0, 20, S("a12345678901234567890cde")); + test(S("abcde"), 1, 1, S("12345678901234567890"), 0, 21, S("a12345678901234567890cde")); + test(S("abcde"), 1, 1, S("12345678901234567890"), 1, 0, S("acde")); + test(S("abcde"), 1, 1, S("12345678901234567890"), 1, 1, S("a2cde")); + test(S("abcde"), 1, 1, S("12345678901234567890"), 1, 9, S("a234567890cde")); + test(S("abcde"), 1, 1, S("12345678901234567890"), 1, 18, S("a234567890123456789cde")); +} + +template +void test8() +{ + test(S("abcde"), 1, 1, S("12345678901234567890"), 1, 19, S("a2345678901234567890cde")); + test(S("abcde"), 1, 1, S("12345678901234567890"), 1, 20, S("a2345678901234567890cde")); + test(S("abcde"), 1, 1, S("12345678901234567890"), 10, 0, S("acde")); + test(S("abcde"), 1, 1, S("12345678901234567890"), 10, 1, S("a1cde")); + test(S("abcde"), 1, 1, S("12345678901234567890"), 10, 5, S("a12345cde")); + test(S("abcde"), 1, 1, S("12345678901234567890"), 10, 9, S("a123456789cde")); + test(S("abcde"), 1, 1, S("12345678901234567890"), 10, 10, S("a1234567890cde")); + test(S("abcde"), 1, 1, S("12345678901234567890"), 10, 11, S("a1234567890cde")); + test(S("abcde"), 1, 1, S("12345678901234567890"), 19, 0, S("acde")); + test(S("abcde"), 1, 1, S("12345678901234567890"), 19, 1, S("a0cde")); + test(S("abcde"), 1, 1, S("12345678901234567890"), 19, 2, S("a0cde")); + test(S("abcde"), 1, 1, S("12345678901234567890"), 20, 0, S("acde")); + test(S("abcde"), 1, 1, S("12345678901234567890"), 20, 1, S("acde")); + test(S("abcde"), 1, 1, S("12345678901234567890"), 21, 0, S("can't happen")); + test(S("abcde"), 1, 2, S(""), 0, 0, S("ade")); + test(S("abcde"), 1, 2, S(""), 0, 1, S("ade")); + test(S("abcde"), 1, 2, S(""), 1, 0, S("can't happen")); + test(S("abcde"), 1, 2, S("12345"), 0, 0, S("ade")); + test(S("abcde"), 1, 2, S("12345"), 0, 1, S("a1de")); + test(S("abcde"), 1, 2, S("12345"), 0, 2, S("a12de")); + test(S("abcde"), 1, 2, S("12345"), 0, 4, S("a1234de")); + test(S("abcde"), 1, 2, S("12345"), 0, 5, S("a12345de")); + test(S("abcde"), 1, 2, S("12345"), 0, 6, S("a12345de")); + test(S("abcde"), 1, 2, S("12345"), 1, 0, S("ade")); + test(S("abcde"), 1, 2, S("12345"), 1, 1, S("a2de")); + test(S("abcde"), 1, 2, S("12345"), 1, 2, S("a23de")); + test(S("abcde"), 1, 2, S("12345"), 1, 3, S("a234de")); + test(S("abcde"), 1, 2, S("12345"), 1, 4, S("a2345de")); + test(S("abcde"), 1, 2, S("12345"), 1, 5, S("a2345de")); + test(S("abcde"), 1, 2, S("12345"), 2, 0, S("ade")); + test(S("abcde"), 1, 2, S("12345"), 2, 1, S("a3de")); + test(S("abcde"), 1, 2, S("12345"), 2, 2, S("a34de")); + test(S("abcde"), 1, 2, S("12345"), 2, 3, S("a345de")); + test(S("abcde"), 1, 2, S("12345"), 2, 4, S("a345de")); + test(S("abcde"), 1, 2, S("12345"), 4, 0, S("ade")); + test(S("abcde"), 1, 2, S("12345"), 4, 1, S("a5de")); + test(S("abcde"), 1, 2, S("12345"), 4, 2, S("a5de")); + test(S("abcde"), 1, 2, S("12345"), 5, 0, S("ade")); + test(S("abcde"), 1, 2, S("12345"), 5, 1, S("ade")); + test(S("abcde"), 1, 2, S("12345"), 6, 0, S("can't happen")); + test(S("abcde"), 1, 2, S("1234567890"), 0, 0, S("ade")); + test(S("abcde"), 1, 2, S("1234567890"), 0, 1, S("a1de")); + test(S("abcde"), 1, 2, S("1234567890"), 0, 5, S("a12345de")); + test(S("abcde"), 1, 2, S("1234567890"), 0, 9, S("a123456789de")); + test(S("abcde"), 1, 2, S("1234567890"), 0, 10, S("a1234567890de")); + test(S("abcde"), 1, 2, S("1234567890"), 0, 11, S("a1234567890de")); + test(S("abcde"), 1, 2, S("1234567890"), 1, 0, S("ade")); + test(S("abcde"), 1, 2, S("1234567890"), 1, 1, S("a2de")); + test(S("abcde"), 1, 2, S("1234567890"), 1, 4, S("a2345de")); + test(S("abcde"), 1, 2, S("1234567890"), 1, 8, S("a23456789de")); + test(S("abcde"), 1, 2, S("1234567890"), 1, 9, S("a234567890de")); + test(S("abcde"), 1, 2, S("1234567890"), 1, 10, S("a234567890de")); + test(S("abcde"), 1, 2, S("1234567890"), 5, 0, S("ade")); + test(S("abcde"), 1, 2, S("1234567890"), 5, 1, S("a6de")); + test(S("abcde"), 1, 2, S("1234567890"), 5, 2, S("a67de")); + test(S("abcde"), 1, 2, S("1234567890"), 5, 4, S("a6789de")); + test(S("abcde"), 1, 2, S("1234567890"), 5, 5, S("a67890de")); + test(S("abcde"), 1, 2, S("1234567890"), 5, 6, S("a67890de")); + test(S("abcde"), 1, 2, S("1234567890"), 9, 0, S("ade")); + test(S("abcde"), 1, 2, S("1234567890"), 9, 1, S("a0de")); + test(S("abcde"), 1, 2, S("1234567890"), 9, 2, S("a0de")); + test(S("abcde"), 1, 2, S("1234567890"), 10, 0, S("ade")); + test(S("abcde"), 1, 2, S("1234567890"), 10, 1, S("ade")); + test(S("abcde"), 1, 2, S("1234567890"), 11, 0, S("can't happen")); + test(S("abcde"), 1, 2, S("12345678901234567890"), 0, 0, S("ade")); + test(S("abcde"), 1, 2, S("12345678901234567890"), 0, 1, S("a1de")); + test(S("abcde"), 1, 2, S("12345678901234567890"), 0, 10, S("a1234567890de")); + test(S("abcde"), 1, 2, S("12345678901234567890"), 0, 19, S("a1234567890123456789de")); + test(S("abcde"), 1, 2, S("12345678901234567890"), 0, 20, S("a12345678901234567890de")); + test(S("abcde"), 1, 2, S("12345678901234567890"), 0, 21, S("a12345678901234567890de")); + test(S("abcde"), 1, 2, S("12345678901234567890"), 1, 0, S("ade")); + test(S("abcde"), 1, 2, S("12345678901234567890"), 1, 1, S("a2de")); + test(S("abcde"), 1, 2, S("12345678901234567890"), 1, 9, S("a234567890de")); + test(S("abcde"), 1, 2, S("12345678901234567890"), 1, 18, S("a234567890123456789de")); + test(S("abcde"), 1, 2, S("12345678901234567890"), 1, 19, S("a2345678901234567890de")); + test(S("abcde"), 1, 2, S("12345678901234567890"), 1, 20, S("a2345678901234567890de")); + test(S("abcde"), 1, 2, S("12345678901234567890"), 10, 0, S("ade")); + test(S("abcde"), 1, 2, S("12345678901234567890"), 10, 1, S("a1de")); + test(S("abcde"), 1, 2, S("12345678901234567890"), 10, 5, S("a12345de")); + test(S("abcde"), 1, 2, S("12345678901234567890"), 10, 9, S("a123456789de")); + test(S("abcde"), 1, 2, S("12345678901234567890"), 10, 10, S("a1234567890de")); + test(S("abcde"), 1, 2, S("12345678901234567890"), 10, 11, S("a1234567890de")); + test(S("abcde"), 1, 2, S("12345678901234567890"), 19, 0, S("ade")); + test(S("abcde"), 1, 2, S("12345678901234567890"), 19, 1, S("a0de")); + test(S("abcde"), 1, 2, S("12345678901234567890"), 19, 2, S("a0de")); + test(S("abcde"), 1, 2, S("12345678901234567890"), 20, 0, S("ade")); + test(S("abcde"), 1, 2, S("12345678901234567890"), 20, 1, S("ade")); + test(S("abcde"), 1, 2, S("12345678901234567890"), 21, 0, S("can't happen")); + test(S("abcde"), 1, 3, S(""), 0, 0, S("ae")); + test(S("abcde"), 1, 3, S(""), 0, 1, S("ae")); + test(S("abcde"), 1, 3, S(""), 1, 0, S("can't happen")); + test(S("abcde"), 1, 3, S("12345"), 0, 0, S("ae")); + test(S("abcde"), 1, 3, S("12345"), 0, 1, S("a1e")); + test(S("abcde"), 1, 3, S("12345"), 0, 2, S("a12e")); + test(S("abcde"), 1, 3, S("12345"), 0, 4, S("a1234e")); + test(S("abcde"), 1, 3, S("12345"), 0, 5, S("a12345e")); + test(S("abcde"), 1, 3, S("12345"), 0, 6, S("a12345e")); + test(S("abcde"), 1, 3, S("12345"), 1, 0, S("ae")); + test(S("abcde"), 1, 3, S("12345"), 1, 1, S("a2e")); + test(S("abcde"), 1, 3, S("12345"), 1, 2, S("a23e")); +} + +template +void test9() +{ + test(S("abcde"), 1, 3, S("12345"), 1, 3, S("a234e")); + test(S("abcde"), 1, 3, S("12345"), 1, 4, S("a2345e")); + test(S("abcde"), 1, 3, S("12345"), 1, 5, S("a2345e")); + test(S("abcde"), 1, 3, S("12345"), 2, 0, S("ae")); + test(S("abcde"), 1, 3, S("12345"), 2, 1, S("a3e")); + test(S("abcde"), 1, 3, S("12345"), 2, 2, S("a34e")); + test(S("abcde"), 1, 3, S("12345"), 2, 3, S("a345e")); + test(S("abcde"), 1, 3, S("12345"), 2, 4, S("a345e")); + test(S("abcde"), 1, 3, S("12345"), 4, 0, S("ae")); + test(S("abcde"), 1, 3, S("12345"), 4, 1, S("a5e")); + test(S("abcde"), 1, 3, S("12345"), 4, 2, S("a5e")); + test(S("abcde"), 1, 3, S("12345"), 5, 0, S("ae")); + test(S("abcde"), 1, 3, S("12345"), 5, 1, S("ae")); + test(S("abcde"), 1, 3, S("12345"), 6, 0, S("can't happen")); + test(S("abcde"), 1, 3, S("1234567890"), 0, 0, S("ae")); + test(S("abcde"), 1, 3, S("1234567890"), 0, 1, S("a1e")); + test(S("abcde"), 1, 3, S("1234567890"), 0, 5, S("a12345e")); + test(S("abcde"), 1, 3, S("1234567890"), 0, 9, S("a123456789e")); + test(S("abcde"), 1, 3, S("1234567890"), 0, 10, S("a1234567890e")); + test(S("abcde"), 1, 3, S("1234567890"), 0, 11, S("a1234567890e")); + test(S("abcde"), 1, 3, S("1234567890"), 1, 0, S("ae")); + test(S("abcde"), 1, 3, S("1234567890"), 1, 1, S("a2e")); + test(S("abcde"), 1, 3, S("1234567890"), 1, 4, S("a2345e")); + test(S("abcde"), 1, 3, S("1234567890"), 1, 8, S("a23456789e")); + test(S("abcde"), 1, 3, S("1234567890"), 1, 9, S("a234567890e")); + test(S("abcde"), 1, 3, S("1234567890"), 1, 10, S("a234567890e")); + test(S("abcde"), 1, 3, S("1234567890"), 5, 0, S("ae")); + test(S("abcde"), 1, 3, S("1234567890"), 5, 1, S("a6e")); + test(S("abcde"), 1, 3, S("1234567890"), 5, 2, S("a67e")); + test(S("abcde"), 1, 3, S("1234567890"), 5, 4, S("a6789e")); + test(S("abcde"), 1, 3, S("1234567890"), 5, 5, S("a67890e")); + test(S("abcde"), 1, 3, S("1234567890"), 5, 6, S("a67890e")); + test(S("abcde"), 1, 3, S("1234567890"), 9, 0, S("ae")); + test(S("abcde"), 1, 3, S("1234567890"), 9, 1, S("a0e")); + test(S("abcde"), 1, 3, S("1234567890"), 9, 2, S("a0e")); + test(S("abcde"), 1, 3, S("1234567890"), 10, 0, S("ae")); + test(S("abcde"), 1, 3, S("1234567890"), 10, 1, S("ae")); + test(S("abcde"), 1, 3, S("1234567890"), 11, 0, S("can't happen")); + test(S("abcde"), 1, 3, S("12345678901234567890"), 0, 0, S("ae")); + test(S("abcde"), 1, 3, S("12345678901234567890"), 0, 1, S("a1e")); + test(S("abcde"), 1, 3, S("12345678901234567890"), 0, 10, S("a1234567890e")); + test(S("abcde"), 1, 3, S("12345678901234567890"), 0, 19, S("a1234567890123456789e")); + test(S("abcde"), 1, 3, S("12345678901234567890"), 0, 20, S("a12345678901234567890e")); + test(S("abcde"), 1, 3, S("12345678901234567890"), 0, 21, S("a12345678901234567890e")); + test(S("abcde"), 1, 3, S("12345678901234567890"), 1, 0, S("ae")); + test(S("abcde"), 1, 3, S("12345678901234567890"), 1, 1, S("a2e")); + test(S("abcde"), 1, 3, S("12345678901234567890"), 1, 9, S("a234567890e")); + test(S("abcde"), 1, 3, S("12345678901234567890"), 1, 18, S("a234567890123456789e")); + test(S("abcde"), 1, 3, S("12345678901234567890"), 1, 19, S("a2345678901234567890e")); + test(S("abcde"), 1, 3, S("12345678901234567890"), 1, 20, S("a2345678901234567890e")); + test(S("abcde"), 1, 3, S("12345678901234567890"), 10, 0, S("ae")); + test(S("abcde"), 1, 3, S("12345678901234567890"), 10, 1, S("a1e")); + test(S("abcde"), 1, 3, S("12345678901234567890"), 10, 5, S("a12345e")); + test(S("abcde"), 1, 3, S("12345678901234567890"), 10, 9, S("a123456789e")); + test(S("abcde"), 1, 3, S("12345678901234567890"), 10, 10, S("a1234567890e")); + test(S("abcde"), 1, 3, S("12345678901234567890"), 10, 11, S("a1234567890e")); + test(S("abcde"), 1, 3, S("12345678901234567890"), 19, 0, S("ae")); + test(S("abcde"), 1, 3, S("12345678901234567890"), 19, 1, S("a0e")); + test(S("abcde"), 1, 3, S("12345678901234567890"), 19, 2, S("a0e")); + test(S("abcde"), 1, 3, S("12345678901234567890"), 20, 0, S("ae")); + test(S("abcde"), 1, 3, S("12345678901234567890"), 20, 1, S("ae")); + test(S("abcde"), 1, 3, S("12345678901234567890"), 21, 0, S("can't happen")); + test(S("abcde"), 1, 4, S(""), 0, 0, S("a")); + test(S("abcde"), 1, 4, S(""), 0, 1, S("a")); + test(S("abcde"), 1, 4, S(""), 1, 0, S("can't happen")); + test(S("abcde"), 1, 4, S("12345"), 0, 0, S("a")); + test(S("abcde"), 1, 4, S("12345"), 0, 1, S("a1")); + test(S("abcde"), 1, 4, S("12345"), 0, 2, S("a12")); + test(S("abcde"), 1, 4, S("12345"), 0, 4, S("a1234")); + test(S("abcde"), 1, 4, S("12345"), 0, 5, S("a12345")); + test(S("abcde"), 1, 4, S("12345"), 0, 6, S("a12345")); + test(S("abcde"), 1, 4, S("12345"), 1, 0, S("a")); + test(S("abcde"), 1, 4, S("12345"), 1, 1, S("a2")); + test(S("abcde"), 1, 4, S("12345"), 1, 2, S("a23")); + test(S("abcde"), 1, 4, S("12345"), 1, 3, S("a234")); + test(S("abcde"), 1, 4, S("12345"), 1, 4, S("a2345")); + test(S("abcde"), 1, 4, S("12345"), 1, 5, S("a2345")); + test(S("abcde"), 1, 4, S("12345"), 2, 0, S("a")); + test(S("abcde"), 1, 4, S("12345"), 2, 1, S("a3")); + test(S("abcde"), 1, 4, S("12345"), 2, 2, S("a34")); + test(S("abcde"), 1, 4, S("12345"), 2, 3, S("a345")); + test(S("abcde"), 1, 4, S("12345"), 2, 4, S("a345")); + test(S("abcde"), 1, 4, S("12345"), 4, 0, S("a")); + test(S("abcde"), 1, 4, S("12345"), 4, 1, S("a5")); + test(S("abcde"), 1, 4, S("12345"), 4, 2, S("a5")); + test(S("abcde"), 1, 4, S("12345"), 5, 0, S("a")); + test(S("abcde"), 1, 4, S("12345"), 5, 1, S("a")); + test(S("abcde"), 1, 4, S("12345"), 6, 0, S("can't happen")); + test(S("abcde"), 1, 4, S("1234567890"), 0, 0, S("a")); + test(S("abcde"), 1, 4, S("1234567890"), 0, 1, S("a1")); + test(S("abcde"), 1, 4, S("1234567890"), 0, 5, S("a12345")); + test(S("abcde"), 1, 4, S("1234567890"), 0, 9, S("a123456789")); + test(S("abcde"), 1, 4, S("1234567890"), 0, 10, S("a1234567890")); + test(S("abcde"), 1, 4, S("1234567890"), 0, 11, S("a1234567890")); + test(S("abcde"), 1, 4, S("1234567890"), 1, 0, S("a")); + test(S("abcde"), 1, 4, S("1234567890"), 1, 1, S("a2")); + test(S("abcde"), 1, 4, S("1234567890"), 1, 4, S("a2345")); + test(S("abcde"), 1, 4, S("1234567890"), 1, 8, S("a23456789")); + test(S("abcde"), 1, 4, S("1234567890"), 1, 9, S("a234567890")); + test(S("abcde"), 1, 4, S("1234567890"), 1, 10, S("a234567890")); +} + +template +void test10() +{ + test(S("abcde"), 1, 4, S("1234567890"), 5, 0, S("a")); + test(S("abcde"), 1, 4, S("1234567890"), 5, 1, S("a6")); + test(S("abcde"), 1, 4, S("1234567890"), 5, 2, S("a67")); + test(S("abcde"), 1, 4, S("1234567890"), 5, 4, S("a6789")); + test(S("abcde"), 1, 4, S("1234567890"), 5, 5, S("a67890")); + test(S("abcde"), 1, 4, S("1234567890"), 5, 6, S("a67890")); + test(S("abcde"), 1, 4, S("1234567890"), 9, 0, S("a")); + test(S("abcde"), 1, 4, S("1234567890"), 9, 1, S("a0")); + test(S("abcde"), 1, 4, S("1234567890"), 9, 2, S("a0")); + test(S("abcde"), 1, 4, S("1234567890"), 10, 0, S("a")); + test(S("abcde"), 1, 4, S("1234567890"), 10, 1, S("a")); + test(S("abcde"), 1, 4, S("1234567890"), 11, 0, S("can't happen")); + test(S("abcde"), 1, 4, S("12345678901234567890"), 0, 0, S("a")); + test(S("abcde"), 1, 4, S("12345678901234567890"), 0, 1, S("a1")); + test(S("abcde"), 1, 4, S("12345678901234567890"), 0, 10, S("a1234567890")); + test(S("abcde"), 1, 4, S("12345678901234567890"), 0, 19, S("a1234567890123456789")); + test(S("abcde"), 1, 4, S("12345678901234567890"), 0, 20, S("a12345678901234567890")); + test(S("abcde"), 1, 4, S("12345678901234567890"), 0, 21, S("a12345678901234567890")); + test(S("abcde"), 1, 4, S("12345678901234567890"), 1, 0, S("a")); + test(S("abcde"), 1, 4, S("12345678901234567890"), 1, 1, S("a2")); + test(S("abcde"), 1, 4, S("12345678901234567890"), 1, 9, S("a234567890")); + test(S("abcde"), 1, 4, S("12345678901234567890"), 1, 18, S("a234567890123456789")); + test(S("abcde"), 1, 4, S("12345678901234567890"), 1, 19, S("a2345678901234567890")); + test(S("abcde"), 1, 4, S("12345678901234567890"), 1, 20, S("a2345678901234567890")); + test(S("abcde"), 1, 4, S("12345678901234567890"), 10, 0, S("a")); + test(S("abcde"), 1, 4, S("12345678901234567890"), 10, 1, S("a1")); + test(S("abcde"), 1, 4, S("12345678901234567890"), 10, 5, S("a12345")); + test(S("abcde"), 1, 4, S("12345678901234567890"), 10, 9, S("a123456789")); + test(S("abcde"), 1, 4, S("12345678901234567890"), 10, 10, S("a1234567890")); + test(S("abcde"), 1, 4, S("12345678901234567890"), 10, 11, S("a1234567890")); + test(S("abcde"), 1, 4, S("12345678901234567890"), 19, 0, S("a")); + test(S("abcde"), 1, 4, S("12345678901234567890"), 19, 1, S("a0")); + test(S("abcde"), 1, 4, S("12345678901234567890"), 19, 2, S("a0")); + test(S("abcde"), 1, 4, S("12345678901234567890"), 20, 0, S("a")); + test(S("abcde"), 1, 4, S("12345678901234567890"), 20, 1, S("a")); + test(S("abcde"), 1, 4, S("12345678901234567890"), 21, 0, S("can't happen")); + test(S("abcde"), 1, 5, S(""), 0, 0, S("a")); + test(S("abcde"), 1, 5, S(""), 0, 1, S("a")); + test(S("abcde"), 1, 5, S(""), 1, 0, S("can't happen")); + test(S("abcde"), 1, 5, S("12345"), 0, 0, S("a")); + test(S("abcde"), 1, 5, S("12345"), 0, 1, S("a1")); + test(S("abcde"), 1, 5, S("12345"), 0, 2, S("a12")); + test(S("abcde"), 1, 5, S("12345"), 0, 4, S("a1234")); + test(S("abcde"), 1, 5, S("12345"), 0, 5, S("a12345")); + test(S("abcde"), 1, 5, S("12345"), 0, 6, S("a12345")); + test(S("abcde"), 1, 5, S("12345"), 1, 0, S("a")); + test(S("abcde"), 1, 5, S("12345"), 1, 1, S("a2")); + test(S("abcde"), 1, 5, S("12345"), 1, 2, S("a23")); + test(S("abcde"), 1, 5, S("12345"), 1, 3, S("a234")); + test(S("abcde"), 1, 5, S("12345"), 1, 4, S("a2345")); + test(S("abcde"), 1, 5, S("12345"), 1, 5, S("a2345")); + test(S("abcde"), 1, 5, S("12345"), 2, 0, S("a")); + test(S("abcde"), 1, 5, S("12345"), 2, 1, S("a3")); + test(S("abcde"), 1, 5, S("12345"), 2, 2, S("a34")); + test(S("abcde"), 1, 5, S("12345"), 2, 3, S("a345")); + test(S("abcde"), 1, 5, S("12345"), 2, 4, S("a345")); + test(S("abcde"), 1, 5, S("12345"), 4, 0, S("a")); + test(S("abcde"), 1, 5, S("12345"), 4, 1, S("a5")); + test(S("abcde"), 1, 5, S("12345"), 4, 2, S("a5")); + test(S("abcde"), 1, 5, S("12345"), 5, 0, S("a")); + test(S("abcde"), 1, 5, S("12345"), 5, 1, S("a")); + test(S("abcde"), 1, 5, S("12345"), 6, 0, S("can't happen")); + test(S("abcde"), 1, 5, S("1234567890"), 0, 0, S("a")); + test(S("abcde"), 1, 5, S("1234567890"), 0, 1, S("a1")); + test(S("abcde"), 1, 5, S("1234567890"), 0, 5, S("a12345")); + test(S("abcde"), 1, 5, S("1234567890"), 0, 9, S("a123456789")); + test(S("abcde"), 1, 5, S("1234567890"), 0, 10, S("a1234567890")); + test(S("abcde"), 1, 5, S("1234567890"), 0, 11, S("a1234567890")); + test(S("abcde"), 1, 5, S("1234567890"), 1, 0, S("a")); + test(S("abcde"), 1, 5, S("1234567890"), 1, 1, S("a2")); + test(S("abcde"), 1, 5, S("1234567890"), 1, 4, S("a2345")); + test(S("abcde"), 1, 5, S("1234567890"), 1, 8, S("a23456789")); + test(S("abcde"), 1, 5, S("1234567890"), 1, 9, S("a234567890")); + test(S("abcde"), 1, 5, S("1234567890"), 1, 10, S("a234567890")); + test(S("abcde"), 1, 5, S("1234567890"), 5, 0, S("a")); + test(S("abcde"), 1, 5, S("1234567890"), 5, 1, S("a6")); + test(S("abcde"), 1, 5, S("1234567890"), 5, 2, S("a67")); + test(S("abcde"), 1, 5, S("1234567890"), 5, 4, S("a6789")); + test(S("abcde"), 1, 5, S("1234567890"), 5, 5, S("a67890")); + test(S("abcde"), 1, 5, S("1234567890"), 5, 6, S("a67890")); + test(S("abcde"), 1, 5, S("1234567890"), 9, 0, S("a")); + test(S("abcde"), 1, 5, S("1234567890"), 9, 1, S("a0")); + test(S("abcde"), 1, 5, S("1234567890"), 9, 2, S("a0")); + test(S("abcde"), 1, 5, S("1234567890"), 10, 0, S("a")); + test(S("abcde"), 1, 5, S("1234567890"), 10, 1, S("a")); + test(S("abcde"), 1, 5, S("1234567890"), 11, 0, S("can't happen")); + test(S("abcde"), 1, 5, S("12345678901234567890"), 0, 0, S("a")); + test(S("abcde"), 1, 5, S("12345678901234567890"), 0, 1, S("a1")); + test(S("abcde"), 1, 5, S("12345678901234567890"), 0, 10, S("a1234567890")); + test(S("abcde"), 1, 5, S("12345678901234567890"), 0, 19, S("a1234567890123456789")); + test(S("abcde"), 1, 5, S("12345678901234567890"), 0, 20, S("a12345678901234567890")); + test(S("abcde"), 1, 5, S("12345678901234567890"), 0, 21, S("a12345678901234567890")); + test(S("abcde"), 1, 5, S("12345678901234567890"), 1, 0, S("a")); + test(S("abcde"), 1, 5, S("12345678901234567890"), 1, 1, S("a2")); + test(S("abcde"), 1, 5, S("12345678901234567890"), 1, 9, S("a234567890")); + test(S("abcde"), 1, 5, S("12345678901234567890"), 1, 18, S("a234567890123456789")); + test(S("abcde"), 1, 5, S("12345678901234567890"), 1, 19, S("a2345678901234567890")); + test(S("abcde"), 1, 5, S("12345678901234567890"), 1, 20, S("a2345678901234567890")); + test(S("abcde"), 1, 5, S("12345678901234567890"), 10, 0, S("a")); + test(S("abcde"), 1, 5, S("12345678901234567890"), 10, 1, S("a1")); +} + +template +void test11() +{ + test(S("abcde"), 1, 5, S("12345678901234567890"), 10, 5, S("a12345")); + test(S("abcde"), 1, 5, S("12345678901234567890"), 10, 9, S("a123456789")); + test(S("abcde"), 1, 5, S("12345678901234567890"), 10, 10, S("a1234567890")); + test(S("abcde"), 1, 5, S("12345678901234567890"), 10, 11, S("a1234567890")); + test(S("abcde"), 1, 5, S("12345678901234567890"), 19, 0, S("a")); + test(S("abcde"), 1, 5, S("12345678901234567890"), 19, 1, S("a0")); + test(S("abcde"), 1, 5, S("12345678901234567890"), 19, 2, S("a0")); + test(S("abcde"), 1, 5, S("12345678901234567890"), 20, 0, S("a")); + test(S("abcde"), 1, 5, S("12345678901234567890"), 20, 1, S("a")); + test(S("abcde"), 1, 5, S("12345678901234567890"), 21, 0, S("can't happen")); + test(S("abcde"), 2, 0, S(""), 0, 0, S("abcde")); + test(S("abcde"), 2, 0, S(""), 0, 1, S("abcde")); + test(S("abcde"), 2, 0, S(""), 1, 0, S("can't happen")); + test(S("abcde"), 2, 0, S("12345"), 0, 0, S("abcde")); + test(S("abcde"), 2, 0, S("12345"), 0, 1, S("ab1cde")); + test(S("abcde"), 2, 0, S("12345"), 0, 2, S("ab12cde")); + test(S("abcde"), 2, 0, S("12345"), 0, 4, S("ab1234cde")); + test(S("abcde"), 2, 0, S("12345"), 0, 5, S("ab12345cde")); + test(S("abcde"), 2, 0, S("12345"), 0, 6, S("ab12345cde")); + test(S("abcde"), 2, 0, S("12345"), 1, 0, S("abcde")); + test(S("abcde"), 2, 0, S("12345"), 1, 1, S("ab2cde")); + test(S("abcde"), 2, 0, S("12345"), 1, 2, S("ab23cde")); + test(S("abcde"), 2, 0, S("12345"), 1, 3, S("ab234cde")); + test(S("abcde"), 2, 0, S("12345"), 1, 4, S("ab2345cde")); + test(S("abcde"), 2, 0, S("12345"), 1, 5, S("ab2345cde")); + test(S("abcde"), 2, 0, S("12345"), 2, 0, S("abcde")); + test(S("abcde"), 2, 0, S("12345"), 2, 1, S("ab3cde")); + test(S("abcde"), 2, 0, S("12345"), 2, 2, S("ab34cde")); + test(S("abcde"), 2, 0, S("12345"), 2, 3, S("ab345cde")); + test(S("abcde"), 2, 0, S("12345"), 2, 4, S("ab345cde")); + test(S("abcde"), 2, 0, S("12345"), 4, 0, S("abcde")); + test(S("abcde"), 2, 0, S("12345"), 4, 1, S("ab5cde")); + test(S("abcde"), 2, 0, S("12345"), 4, 2, S("ab5cde")); + test(S("abcde"), 2, 0, S("12345"), 5, 0, S("abcde")); + test(S("abcde"), 2, 0, S("12345"), 5, 1, S("abcde")); + test(S("abcde"), 2, 0, S("12345"), 6, 0, S("can't happen")); + test(S("abcde"), 2, 0, S("1234567890"), 0, 0, S("abcde")); + test(S("abcde"), 2, 0, S("1234567890"), 0, 1, S("ab1cde")); + test(S("abcde"), 2, 0, S("1234567890"), 0, 5, S("ab12345cde")); + test(S("abcde"), 2, 0, S("1234567890"), 0, 9, S("ab123456789cde")); + test(S("abcde"), 2, 0, S("1234567890"), 0, 10, S("ab1234567890cde")); + test(S("abcde"), 2, 0, S("1234567890"), 0, 11, S("ab1234567890cde")); + test(S("abcde"), 2, 0, S("1234567890"), 1, 0, S("abcde")); + test(S("abcde"), 2, 0, S("1234567890"), 1, 1, S("ab2cde")); + test(S("abcde"), 2, 0, S("1234567890"), 1, 4, S("ab2345cde")); + test(S("abcde"), 2, 0, S("1234567890"), 1, 8, S("ab23456789cde")); + test(S("abcde"), 2, 0, S("1234567890"), 1, 9, S("ab234567890cde")); + test(S("abcde"), 2, 0, S("1234567890"), 1, 10, S("ab234567890cde")); + test(S("abcde"), 2, 0, S("1234567890"), 5, 0, S("abcde")); + test(S("abcde"), 2, 0, S("1234567890"), 5, 1, S("ab6cde")); + test(S("abcde"), 2, 0, S("1234567890"), 5, 2, S("ab67cde")); + test(S("abcde"), 2, 0, S("1234567890"), 5, 4, S("ab6789cde")); + test(S("abcde"), 2, 0, S("1234567890"), 5, 5, S("ab67890cde")); + test(S("abcde"), 2, 0, S("1234567890"), 5, 6, S("ab67890cde")); + test(S("abcde"), 2, 0, S("1234567890"), 9, 0, S("abcde")); + test(S("abcde"), 2, 0, S("1234567890"), 9, 1, S("ab0cde")); + test(S("abcde"), 2, 0, S("1234567890"), 9, 2, S("ab0cde")); + test(S("abcde"), 2, 0, S("1234567890"), 10, 0, S("abcde")); + test(S("abcde"), 2, 0, S("1234567890"), 10, 1, S("abcde")); + test(S("abcde"), 2, 0, S("1234567890"), 11, 0, S("can't happen")); + test(S("abcde"), 2, 0, S("12345678901234567890"), 0, 0, S("abcde")); + test(S("abcde"), 2, 0, S("12345678901234567890"), 0, 1, S("ab1cde")); + test(S("abcde"), 2, 0, S("12345678901234567890"), 0, 10, S("ab1234567890cde")); + test(S("abcde"), 2, 0, S("12345678901234567890"), 0, 19, S("ab1234567890123456789cde")); + test(S("abcde"), 2, 0, S("12345678901234567890"), 0, 20, S("ab12345678901234567890cde")); + test(S("abcde"), 2, 0, S("12345678901234567890"), 0, 21, S("ab12345678901234567890cde")); + test(S("abcde"), 2, 0, S("12345678901234567890"), 1, 0, S("abcde")); + test(S("abcde"), 2, 0, S("12345678901234567890"), 1, 1, S("ab2cde")); + test(S("abcde"), 2, 0, S("12345678901234567890"), 1, 9, S("ab234567890cde")); + test(S("abcde"), 2, 0, S("12345678901234567890"), 1, 18, S("ab234567890123456789cde")); + test(S("abcde"), 2, 0, S("12345678901234567890"), 1, 19, S("ab2345678901234567890cde")); + test(S("abcde"), 2, 0, S("12345678901234567890"), 1, 20, S("ab2345678901234567890cde")); + test(S("abcde"), 2, 0, S("12345678901234567890"), 10, 0, S("abcde")); + test(S("abcde"), 2, 0, S("12345678901234567890"), 10, 1, S("ab1cde")); + test(S("abcde"), 2, 0, S("12345678901234567890"), 10, 5, S("ab12345cde")); + test(S("abcde"), 2, 0, S("12345678901234567890"), 10, 9, S("ab123456789cde")); + test(S("abcde"), 2, 0, S("12345678901234567890"), 10, 10, S("ab1234567890cde")); + test(S("abcde"), 2, 0, S("12345678901234567890"), 10, 11, S("ab1234567890cde")); + test(S("abcde"), 2, 0, S("12345678901234567890"), 19, 0, S("abcde")); + test(S("abcde"), 2, 0, S("12345678901234567890"), 19, 1, S("ab0cde")); + test(S("abcde"), 2, 0, S("12345678901234567890"), 19, 2, S("ab0cde")); + test(S("abcde"), 2, 0, S("12345678901234567890"), 20, 0, S("abcde")); + test(S("abcde"), 2, 0, S("12345678901234567890"), 20, 1, S("abcde")); + test(S("abcde"), 2, 0, S("12345678901234567890"), 21, 0, S("can't happen")); + test(S("abcde"), 2, 1, S(""), 0, 0, S("abde")); + test(S("abcde"), 2, 1, S(""), 0, 1, S("abde")); + test(S("abcde"), 2, 1, S(""), 1, 0, S("can't happen")); + test(S("abcde"), 2, 1, S("12345"), 0, 0, S("abde")); + test(S("abcde"), 2, 1, S("12345"), 0, 1, S("ab1de")); + test(S("abcde"), 2, 1, S("12345"), 0, 2, S("ab12de")); + test(S("abcde"), 2, 1, S("12345"), 0, 4, S("ab1234de")); + test(S("abcde"), 2, 1, S("12345"), 0, 5, S("ab12345de")); + test(S("abcde"), 2, 1, S("12345"), 0, 6, S("ab12345de")); + test(S("abcde"), 2, 1, S("12345"), 1, 0, S("abde")); + test(S("abcde"), 2, 1, S("12345"), 1, 1, S("ab2de")); + test(S("abcde"), 2, 1, S("12345"), 1, 2, S("ab23de")); + test(S("abcde"), 2, 1, S("12345"), 1, 3, S("ab234de")); + test(S("abcde"), 2, 1, S("12345"), 1, 4, S("ab2345de")); + test(S("abcde"), 2, 1, S("12345"), 1, 5, S("ab2345de")); + test(S("abcde"), 2, 1, S("12345"), 2, 0, S("abde")); +} + +template +void test12() +{ + test(S("abcde"), 2, 1, S("12345"), 2, 1, S("ab3de")); + test(S("abcde"), 2, 1, S("12345"), 2, 2, S("ab34de")); + test(S("abcde"), 2, 1, S("12345"), 2, 3, S("ab345de")); + test(S("abcde"), 2, 1, S("12345"), 2, 4, S("ab345de")); + test(S("abcde"), 2, 1, S("12345"), 4, 0, S("abde")); + test(S("abcde"), 2, 1, S("12345"), 4, 1, S("ab5de")); + test(S("abcde"), 2, 1, S("12345"), 4, 2, S("ab5de")); + test(S("abcde"), 2, 1, S("12345"), 5, 0, S("abde")); + test(S("abcde"), 2, 1, S("12345"), 5, 1, S("abde")); + test(S("abcde"), 2, 1, S("12345"), 6, 0, S("can't happen")); + test(S("abcde"), 2, 1, S("1234567890"), 0, 0, S("abde")); + test(S("abcde"), 2, 1, S("1234567890"), 0, 1, S("ab1de")); + test(S("abcde"), 2, 1, S("1234567890"), 0, 5, S("ab12345de")); + test(S("abcde"), 2, 1, S("1234567890"), 0, 9, S("ab123456789de")); + test(S("abcde"), 2, 1, S("1234567890"), 0, 10, S("ab1234567890de")); + test(S("abcde"), 2, 1, S("1234567890"), 0, 11, S("ab1234567890de")); + test(S("abcde"), 2, 1, S("1234567890"), 1, 0, S("abde")); + test(S("abcde"), 2, 1, S("1234567890"), 1, 1, S("ab2de")); + test(S("abcde"), 2, 1, S("1234567890"), 1, 4, S("ab2345de")); + test(S("abcde"), 2, 1, S("1234567890"), 1, 8, S("ab23456789de")); + test(S("abcde"), 2, 1, S("1234567890"), 1, 9, S("ab234567890de")); + test(S("abcde"), 2, 1, S("1234567890"), 1, 10, S("ab234567890de")); + test(S("abcde"), 2, 1, S("1234567890"), 5, 0, S("abde")); + test(S("abcde"), 2, 1, S("1234567890"), 5, 1, S("ab6de")); + test(S("abcde"), 2, 1, S("1234567890"), 5, 2, S("ab67de")); + test(S("abcde"), 2, 1, S("1234567890"), 5, 4, S("ab6789de")); + test(S("abcde"), 2, 1, S("1234567890"), 5, 5, S("ab67890de")); + test(S("abcde"), 2, 1, S("1234567890"), 5, 6, S("ab67890de")); + test(S("abcde"), 2, 1, S("1234567890"), 9, 0, S("abde")); + test(S("abcde"), 2, 1, S("1234567890"), 9, 1, S("ab0de")); + test(S("abcde"), 2, 1, S("1234567890"), 9, 2, S("ab0de")); + test(S("abcde"), 2, 1, S("1234567890"), 10, 0, S("abde")); + test(S("abcde"), 2, 1, S("1234567890"), 10, 1, S("abde")); + test(S("abcde"), 2, 1, S("1234567890"), 11, 0, S("can't happen")); + test(S("abcde"), 2, 1, S("12345678901234567890"), 0, 0, S("abde")); + test(S("abcde"), 2, 1, S("12345678901234567890"), 0, 1, S("ab1de")); + test(S("abcde"), 2, 1, S("12345678901234567890"), 0, 10, S("ab1234567890de")); + test(S("abcde"), 2, 1, S("12345678901234567890"), 0, 19, S("ab1234567890123456789de")); + test(S("abcde"), 2, 1, S("12345678901234567890"), 0, 20, S("ab12345678901234567890de")); + test(S("abcde"), 2, 1, S("12345678901234567890"), 0, 21, S("ab12345678901234567890de")); + test(S("abcde"), 2, 1, S("12345678901234567890"), 1, 0, S("abde")); + test(S("abcde"), 2, 1, S("12345678901234567890"), 1, 1, S("ab2de")); + test(S("abcde"), 2, 1, S("12345678901234567890"), 1, 9, S("ab234567890de")); + test(S("abcde"), 2, 1, S("12345678901234567890"), 1, 18, S("ab234567890123456789de")); + test(S("abcde"), 2, 1, S("12345678901234567890"), 1, 19, S("ab2345678901234567890de")); + test(S("abcde"), 2, 1, S("12345678901234567890"), 1, 20, S("ab2345678901234567890de")); + test(S("abcde"), 2, 1, S("12345678901234567890"), 10, 0, S("abde")); + test(S("abcde"), 2, 1, S("12345678901234567890"), 10, 1, S("ab1de")); + test(S("abcde"), 2, 1, S("12345678901234567890"), 10, 5, S("ab12345de")); + test(S("abcde"), 2, 1, S("12345678901234567890"), 10, 9, S("ab123456789de")); + test(S("abcde"), 2, 1, S("12345678901234567890"), 10, 10, S("ab1234567890de")); + test(S("abcde"), 2, 1, S("12345678901234567890"), 10, 11, S("ab1234567890de")); + test(S("abcde"), 2, 1, S("12345678901234567890"), 19, 0, S("abde")); + test(S("abcde"), 2, 1, S("12345678901234567890"), 19, 1, S("ab0de")); + test(S("abcde"), 2, 1, S("12345678901234567890"), 19, 2, S("ab0de")); + test(S("abcde"), 2, 1, S("12345678901234567890"), 20, 0, S("abde")); + test(S("abcde"), 2, 1, S("12345678901234567890"), 20, 1, S("abde")); + test(S("abcde"), 2, 1, S("12345678901234567890"), 21, 0, S("can't happen")); + test(S("abcde"), 2, 2, S(""), 0, 0, S("abe")); + test(S("abcde"), 2, 2, S(""), 0, 1, S("abe")); + test(S("abcde"), 2, 2, S(""), 1, 0, S("can't happen")); + test(S("abcde"), 2, 2, S("12345"), 0, 0, S("abe")); + test(S("abcde"), 2, 2, S("12345"), 0, 1, S("ab1e")); + test(S("abcde"), 2, 2, S("12345"), 0, 2, S("ab12e")); + test(S("abcde"), 2, 2, S("12345"), 0, 4, S("ab1234e")); + test(S("abcde"), 2, 2, S("12345"), 0, 5, S("ab12345e")); + test(S("abcde"), 2, 2, S("12345"), 0, 6, S("ab12345e")); + test(S("abcde"), 2, 2, S("12345"), 1, 0, S("abe")); + test(S("abcde"), 2, 2, S("12345"), 1, 1, S("ab2e")); + test(S("abcde"), 2, 2, S("12345"), 1, 2, S("ab23e")); + test(S("abcde"), 2, 2, S("12345"), 1, 3, S("ab234e")); + test(S("abcde"), 2, 2, S("12345"), 1, 4, S("ab2345e")); + test(S("abcde"), 2, 2, S("12345"), 1, 5, S("ab2345e")); + test(S("abcde"), 2, 2, S("12345"), 2, 0, S("abe")); + test(S("abcde"), 2, 2, S("12345"), 2, 1, S("ab3e")); + test(S("abcde"), 2, 2, S("12345"), 2, 2, S("ab34e")); + test(S("abcde"), 2, 2, S("12345"), 2, 3, S("ab345e")); + test(S("abcde"), 2, 2, S("12345"), 2, 4, S("ab345e")); + test(S("abcde"), 2, 2, S("12345"), 4, 0, S("abe")); + test(S("abcde"), 2, 2, S("12345"), 4, 1, S("ab5e")); + test(S("abcde"), 2, 2, S("12345"), 4, 2, S("ab5e")); + test(S("abcde"), 2, 2, S("12345"), 5, 0, S("abe")); + test(S("abcde"), 2, 2, S("12345"), 5, 1, S("abe")); + test(S("abcde"), 2, 2, S("12345"), 6, 0, S("can't happen")); + test(S("abcde"), 2, 2, S("1234567890"), 0, 0, S("abe")); + test(S("abcde"), 2, 2, S("1234567890"), 0, 1, S("ab1e")); + test(S("abcde"), 2, 2, S("1234567890"), 0, 5, S("ab12345e")); + test(S("abcde"), 2, 2, S("1234567890"), 0, 9, S("ab123456789e")); + test(S("abcde"), 2, 2, S("1234567890"), 0, 10, S("ab1234567890e")); + test(S("abcde"), 2, 2, S("1234567890"), 0, 11, S("ab1234567890e")); + test(S("abcde"), 2, 2, S("1234567890"), 1, 0, S("abe")); + test(S("abcde"), 2, 2, S("1234567890"), 1, 1, S("ab2e")); + test(S("abcde"), 2, 2, S("1234567890"), 1, 4, S("ab2345e")); + test(S("abcde"), 2, 2, S("1234567890"), 1, 8, S("ab23456789e")); + test(S("abcde"), 2, 2, S("1234567890"), 1, 9, S("ab234567890e")); + test(S("abcde"), 2, 2, S("1234567890"), 1, 10, S("ab234567890e")); + test(S("abcde"), 2, 2, S("1234567890"), 5, 0, S("abe")); + test(S("abcde"), 2, 2, S("1234567890"), 5, 1, S("ab6e")); + test(S("abcde"), 2, 2, S("1234567890"), 5, 2, S("ab67e")); + test(S("abcde"), 2, 2, S("1234567890"), 5, 4, S("ab6789e")); +} + +template +void test13() +{ + test(S("abcde"), 2, 2, S("1234567890"), 5, 5, S("ab67890e")); + test(S("abcde"), 2, 2, S("1234567890"), 5, 6, S("ab67890e")); + test(S("abcde"), 2, 2, S("1234567890"), 9, 0, S("abe")); + test(S("abcde"), 2, 2, S("1234567890"), 9, 1, S("ab0e")); + test(S("abcde"), 2, 2, S("1234567890"), 9, 2, S("ab0e")); + test(S("abcde"), 2, 2, S("1234567890"), 10, 0, S("abe")); + test(S("abcde"), 2, 2, S("1234567890"), 10, 1, S("abe")); + test(S("abcde"), 2, 2, S("1234567890"), 11, 0, S("can't happen")); + test(S("abcde"), 2, 2, S("12345678901234567890"), 0, 0, S("abe")); + test(S("abcde"), 2, 2, S("12345678901234567890"), 0, 1, S("ab1e")); + test(S("abcde"), 2, 2, S("12345678901234567890"), 0, 10, S("ab1234567890e")); + test(S("abcde"), 2, 2, S("12345678901234567890"), 0, 19, S("ab1234567890123456789e")); + test(S("abcde"), 2, 2, S("12345678901234567890"), 0, 20, S("ab12345678901234567890e")); + test(S("abcde"), 2, 2, S("12345678901234567890"), 0, 21, S("ab12345678901234567890e")); + test(S("abcde"), 2, 2, S("12345678901234567890"), 1, 0, S("abe")); + test(S("abcde"), 2, 2, S("12345678901234567890"), 1, 1, S("ab2e")); + test(S("abcde"), 2, 2, S("12345678901234567890"), 1, 9, S("ab234567890e")); + test(S("abcde"), 2, 2, S("12345678901234567890"), 1, 18, S("ab234567890123456789e")); + test(S("abcde"), 2, 2, S("12345678901234567890"), 1, 19, S("ab2345678901234567890e")); + test(S("abcde"), 2, 2, S("12345678901234567890"), 1, 20, S("ab2345678901234567890e")); + test(S("abcde"), 2, 2, S("12345678901234567890"), 10, 0, S("abe")); + test(S("abcde"), 2, 2, S("12345678901234567890"), 10, 1, S("ab1e")); + test(S("abcde"), 2, 2, S("12345678901234567890"), 10, 5, S("ab12345e")); + test(S("abcde"), 2, 2, S("12345678901234567890"), 10, 9, S("ab123456789e")); + test(S("abcde"), 2, 2, S("12345678901234567890"), 10, 10, S("ab1234567890e")); + test(S("abcde"), 2, 2, S("12345678901234567890"), 10, 11, S("ab1234567890e")); + test(S("abcde"), 2, 2, S("12345678901234567890"), 19, 0, S("abe")); + test(S("abcde"), 2, 2, S("12345678901234567890"), 19, 1, S("ab0e")); + test(S("abcde"), 2, 2, S("12345678901234567890"), 19, 2, S("ab0e")); + test(S("abcde"), 2, 2, S("12345678901234567890"), 20, 0, S("abe")); + test(S("abcde"), 2, 2, S("12345678901234567890"), 20, 1, S("abe")); + test(S("abcde"), 2, 2, S("12345678901234567890"), 21, 0, S("can't happen")); + test(S("abcde"), 2, 3, S(""), 0, 0, S("ab")); + test(S("abcde"), 2, 3, S(""), 0, 1, S("ab")); + test(S("abcde"), 2, 3, S(""), 1, 0, S("can't happen")); + test(S("abcde"), 2, 3, S("12345"), 0, 0, S("ab")); + test(S("abcde"), 2, 3, S("12345"), 0, 1, S("ab1")); + test(S("abcde"), 2, 3, S("12345"), 0, 2, S("ab12")); + test(S("abcde"), 2, 3, S("12345"), 0, 4, S("ab1234")); + test(S("abcde"), 2, 3, S("12345"), 0, 5, S("ab12345")); + test(S("abcde"), 2, 3, S("12345"), 0, 6, S("ab12345")); + test(S("abcde"), 2, 3, S("12345"), 1, 0, S("ab")); + test(S("abcde"), 2, 3, S("12345"), 1, 1, S("ab2")); + test(S("abcde"), 2, 3, S("12345"), 1, 2, S("ab23")); + test(S("abcde"), 2, 3, S("12345"), 1, 3, S("ab234")); + test(S("abcde"), 2, 3, S("12345"), 1, 4, S("ab2345")); + test(S("abcde"), 2, 3, S("12345"), 1, 5, S("ab2345")); + test(S("abcde"), 2, 3, S("12345"), 2, 0, S("ab")); + test(S("abcde"), 2, 3, S("12345"), 2, 1, S("ab3")); + test(S("abcde"), 2, 3, S("12345"), 2, 2, S("ab34")); + test(S("abcde"), 2, 3, S("12345"), 2, 3, S("ab345")); + test(S("abcde"), 2, 3, S("12345"), 2, 4, S("ab345")); + test(S("abcde"), 2, 3, S("12345"), 4, 0, S("ab")); + test(S("abcde"), 2, 3, S("12345"), 4, 1, S("ab5")); + test(S("abcde"), 2, 3, S("12345"), 4, 2, S("ab5")); + test(S("abcde"), 2, 3, S("12345"), 5, 0, S("ab")); + test(S("abcde"), 2, 3, S("12345"), 5, 1, S("ab")); + test(S("abcde"), 2, 3, S("12345"), 6, 0, S("can't happen")); + test(S("abcde"), 2, 3, S("1234567890"), 0, 0, S("ab")); + test(S("abcde"), 2, 3, S("1234567890"), 0, 1, S("ab1")); + test(S("abcde"), 2, 3, S("1234567890"), 0, 5, S("ab12345")); + test(S("abcde"), 2, 3, S("1234567890"), 0, 9, S("ab123456789")); + test(S("abcde"), 2, 3, S("1234567890"), 0, 10, S("ab1234567890")); + test(S("abcde"), 2, 3, S("1234567890"), 0, 11, S("ab1234567890")); + test(S("abcde"), 2, 3, S("1234567890"), 1, 0, S("ab")); + test(S("abcde"), 2, 3, S("1234567890"), 1, 1, S("ab2")); + test(S("abcde"), 2, 3, S("1234567890"), 1, 4, S("ab2345")); + test(S("abcde"), 2, 3, S("1234567890"), 1, 8, S("ab23456789")); + test(S("abcde"), 2, 3, S("1234567890"), 1, 9, S("ab234567890")); + test(S("abcde"), 2, 3, S("1234567890"), 1, 10, S("ab234567890")); + test(S("abcde"), 2, 3, S("1234567890"), 5, 0, S("ab")); + test(S("abcde"), 2, 3, S("1234567890"), 5, 1, S("ab6")); + test(S("abcde"), 2, 3, S("1234567890"), 5, 2, S("ab67")); + test(S("abcde"), 2, 3, S("1234567890"), 5, 4, S("ab6789")); + test(S("abcde"), 2, 3, S("1234567890"), 5, 5, S("ab67890")); + test(S("abcde"), 2, 3, S("1234567890"), 5, 6, S("ab67890")); + test(S("abcde"), 2, 3, S("1234567890"), 9, 0, S("ab")); + test(S("abcde"), 2, 3, S("1234567890"), 9, 1, S("ab0")); + test(S("abcde"), 2, 3, S("1234567890"), 9, 2, S("ab0")); + test(S("abcde"), 2, 3, S("1234567890"), 10, 0, S("ab")); + test(S("abcde"), 2, 3, S("1234567890"), 10, 1, S("ab")); + test(S("abcde"), 2, 3, S("1234567890"), 11, 0, S("can't happen")); + test(S("abcde"), 2, 3, S("12345678901234567890"), 0, 0, S("ab")); + test(S("abcde"), 2, 3, S("12345678901234567890"), 0, 1, S("ab1")); + test(S("abcde"), 2, 3, S("12345678901234567890"), 0, 10, S("ab1234567890")); + test(S("abcde"), 2, 3, S("12345678901234567890"), 0, 19, S("ab1234567890123456789")); + test(S("abcde"), 2, 3, S("12345678901234567890"), 0, 20, S("ab12345678901234567890")); + test(S("abcde"), 2, 3, S("12345678901234567890"), 0, 21, S("ab12345678901234567890")); + test(S("abcde"), 2, 3, S("12345678901234567890"), 1, 0, S("ab")); + test(S("abcde"), 2, 3, S("12345678901234567890"), 1, 1, S("ab2")); + test(S("abcde"), 2, 3, S("12345678901234567890"), 1, 9, S("ab234567890")); + test(S("abcde"), 2, 3, S("12345678901234567890"), 1, 18, S("ab234567890123456789")); + test(S("abcde"), 2, 3, S("12345678901234567890"), 1, 19, S("ab2345678901234567890")); + test(S("abcde"), 2, 3, S("12345678901234567890"), 1, 20, S("ab2345678901234567890")); + test(S("abcde"), 2, 3, S("12345678901234567890"), 10, 0, S("ab")); + test(S("abcde"), 2, 3, S("12345678901234567890"), 10, 1, S("ab1")); + test(S("abcde"), 2, 3, S("12345678901234567890"), 10, 5, S("ab12345")); + test(S("abcde"), 2, 3, S("12345678901234567890"), 10, 9, S("ab123456789")); + test(S("abcde"), 2, 3, S("12345678901234567890"), 10, 10, S("ab1234567890")); + test(S("abcde"), 2, 3, S("12345678901234567890"), 10, 11, S("ab1234567890")); +} + +template +void test14() +{ + test(S("abcde"), 2, 3, S("12345678901234567890"), 19, 0, S("ab")); + test(S("abcde"), 2, 3, S("12345678901234567890"), 19, 1, S("ab0")); + test(S("abcde"), 2, 3, S("12345678901234567890"), 19, 2, S("ab0")); + test(S("abcde"), 2, 3, S("12345678901234567890"), 20, 0, S("ab")); + test(S("abcde"), 2, 3, S("12345678901234567890"), 20, 1, S("ab")); + test(S("abcde"), 2, 3, S("12345678901234567890"), 21, 0, S("can't happen")); + test(S("abcde"), 2, 4, S(""), 0, 0, S("ab")); + test(S("abcde"), 2, 4, S(""), 0, 1, S("ab")); + test(S("abcde"), 2, 4, S(""), 1, 0, S("can't happen")); + test(S("abcde"), 2, 4, S("12345"), 0, 0, S("ab")); + test(S("abcde"), 2, 4, S("12345"), 0, 1, S("ab1")); + test(S("abcde"), 2, 4, S("12345"), 0, 2, S("ab12")); + test(S("abcde"), 2, 4, S("12345"), 0, 4, S("ab1234")); + test(S("abcde"), 2, 4, S("12345"), 0, 5, S("ab12345")); + test(S("abcde"), 2, 4, S("12345"), 0, 6, S("ab12345")); + test(S("abcde"), 2, 4, S("12345"), 1, 0, S("ab")); + test(S("abcde"), 2, 4, S("12345"), 1, 1, S("ab2")); + test(S("abcde"), 2, 4, S("12345"), 1, 2, S("ab23")); + test(S("abcde"), 2, 4, S("12345"), 1, 3, S("ab234")); + test(S("abcde"), 2, 4, S("12345"), 1, 4, S("ab2345")); + test(S("abcde"), 2, 4, S("12345"), 1, 5, S("ab2345")); + test(S("abcde"), 2, 4, S("12345"), 2, 0, S("ab")); + test(S("abcde"), 2, 4, S("12345"), 2, 1, S("ab3")); + test(S("abcde"), 2, 4, S("12345"), 2, 2, S("ab34")); + test(S("abcde"), 2, 4, S("12345"), 2, 3, S("ab345")); + test(S("abcde"), 2, 4, S("12345"), 2, 4, S("ab345")); + test(S("abcde"), 2, 4, S("12345"), 4, 0, S("ab")); + test(S("abcde"), 2, 4, S("12345"), 4, 1, S("ab5")); + test(S("abcde"), 2, 4, S("12345"), 4, 2, S("ab5")); + test(S("abcde"), 2, 4, S("12345"), 5, 0, S("ab")); + test(S("abcde"), 2, 4, S("12345"), 5, 1, S("ab")); + test(S("abcde"), 2, 4, S("12345"), 6, 0, S("can't happen")); + test(S("abcde"), 2, 4, S("1234567890"), 0, 0, S("ab")); + test(S("abcde"), 2, 4, S("1234567890"), 0, 1, S("ab1")); + test(S("abcde"), 2, 4, S("1234567890"), 0, 5, S("ab12345")); + test(S("abcde"), 2, 4, S("1234567890"), 0, 9, S("ab123456789")); + test(S("abcde"), 2, 4, S("1234567890"), 0, 10, S("ab1234567890")); + test(S("abcde"), 2, 4, S("1234567890"), 0, 11, S("ab1234567890")); + test(S("abcde"), 2, 4, S("1234567890"), 1, 0, S("ab")); + test(S("abcde"), 2, 4, S("1234567890"), 1, 1, S("ab2")); + test(S("abcde"), 2, 4, S("1234567890"), 1, 4, S("ab2345")); + test(S("abcde"), 2, 4, S("1234567890"), 1, 8, S("ab23456789")); + test(S("abcde"), 2, 4, S("1234567890"), 1, 9, S("ab234567890")); + test(S("abcde"), 2, 4, S("1234567890"), 1, 10, S("ab234567890")); + test(S("abcde"), 2, 4, S("1234567890"), 5, 0, S("ab")); + test(S("abcde"), 2, 4, S("1234567890"), 5, 1, S("ab6")); + test(S("abcde"), 2, 4, S("1234567890"), 5, 2, S("ab67")); + test(S("abcde"), 2, 4, S("1234567890"), 5, 4, S("ab6789")); + test(S("abcde"), 2, 4, S("1234567890"), 5, 5, S("ab67890")); + test(S("abcde"), 2, 4, S("1234567890"), 5, 6, S("ab67890")); + test(S("abcde"), 2, 4, S("1234567890"), 9, 0, S("ab")); + test(S("abcde"), 2, 4, S("1234567890"), 9, 1, S("ab0")); + test(S("abcde"), 2, 4, S("1234567890"), 9, 2, S("ab0")); + test(S("abcde"), 2, 4, S("1234567890"), 10, 0, S("ab")); + test(S("abcde"), 2, 4, S("1234567890"), 10, 1, S("ab")); + test(S("abcde"), 2, 4, S("1234567890"), 11, 0, S("can't happen")); + test(S("abcde"), 2, 4, S("12345678901234567890"), 0, 0, S("ab")); + test(S("abcde"), 2, 4, S("12345678901234567890"), 0, 1, S("ab1")); + test(S("abcde"), 2, 4, S("12345678901234567890"), 0, 10, S("ab1234567890")); + test(S("abcde"), 2, 4, S("12345678901234567890"), 0, 19, S("ab1234567890123456789")); + test(S("abcde"), 2, 4, S("12345678901234567890"), 0, 20, S("ab12345678901234567890")); + test(S("abcde"), 2, 4, S("12345678901234567890"), 0, 21, S("ab12345678901234567890")); + test(S("abcde"), 2, 4, S("12345678901234567890"), 1, 0, S("ab")); + test(S("abcde"), 2, 4, S("12345678901234567890"), 1, 1, S("ab2")); + test(S("abcde"), 2, 4, S("12345678901234567890"), 1, 9, S("ab234567890")); + test(S("abcde"), 2, 4, S("12345678901234567890"), 1, 18, S("ab234567890123456789")); + test(S("abcde"), 2, 4, S("12345678901234567890"), 1, 19, S("ab2345678901234567890")); + test(S("abcde"), 2, 4, S("12345678901234567890"), 1, 20, S("ab2345678901234567890")); + test(S("abcde"), 2, 4, S("12345678901234567890"), 10, 0, S("ab")); + test(S("abcde"), 2, 4, S("12345678901234567890"), 10, 1, S("ab1")); + test(S("abcde"), 2, 4, S("12345678901234567890"), 10, 5, S("ab12345")); + test(S("abcde"), 2, 4, S("12345678901234567890"), 10, 9, S("ab123456789")); + test(S("abcde"), 2, 4, S("12345678901234567890"), 10, 10, S("ab1234567890")); + test(S("abcde"), 2, 4, S("12345678901234567890"), 10, 11, S("ab1234567890")); + test(S("abcde"), 2, 4, S("12345678901234567890"), 19, 0, S("ab")); + test(S("abcde"), 2, 4, S("12345678901234567890"), 19, 1, S("ab0")); + test(S("abcde"), 2, 4, S("12345678901234567890"), 19, 2, S("ab0")); + test(S("abcde"), 2, 4, S("12345678901234567890"), 20, 0, S("ab")); + test(S("abcde"), 2, 4, S("12345678901234567890"), 20, 1, S("ab")); + test(S("abcde"), 2, 4, S("12345678901234567890"), 21, 0, S("can't happen")); + test(S("abcde"), 4, 0, S(""), 0, 0, S("abcde")); + test(S("abcde"), 4, 0, S(""), 0, 1, S("abcde")); + test(S("abcde"), 4, 0, S(""), 1, 0, S("can't happen")); + test(S("abcde"), 4, 0, S("12345"), 0, 0, S("abcde")); + test(S("abcde"), 4, 0, S("12345"), 0, 1, S("abcd1e")); + test(S("abcde"), 4, 0, S("12345"), 0, 2, S("abcd12e")); + test(S("abcde"), 4, 0, S("12345"), 0, 4, S("abcd1234e")); + test(S("abcde"), 4, 0, S("12345"), 0, 5, S("abcd12345e")); + test(S("abcde"), 4, 0, S("12345"), 0, 6, S("abcd12345e")); + test(S("abcde"), 4, 0, S("12345"), 1, 0, S("abcde")); + test(S("abcde"), 4, 0, S("12345"), 1, 1, S("abcd2e")); + test(S("abcde"), 4, 0, S("12345"), 1, 2, S("abcd23e")); + test(S("abcde"), 4, 0, S("12345"), 1, 3, S("abcd234e")); + test(S("abcde"), 4, 0, S("12345"), 1, 4, S("abcd2345e")); + test(S("abcde"), 4, 0, S("12345"), 1, 5, S("abcd2345e")); + test(S("abcde"), 4, 0, S("12345"), 2, 0, S("abcde")); + test(S("abcde"), 4, 0, S("12345"), 2, 1, S("abcd3e")); + test(S("abcde"), 4, 0, S("12345"), 2, 2, S("abcd34e")); + test(S("abcde"), 4, 0, S("12345"), 2, 3, S("abcd345e")); + test(S("abcde"), 4, 0, S("12345"), 2, 4, S("abcd345e")); +} + +template +void test15() +{ + test(S("abcde"), 4, 0, S("12345"), 4, 0, S("abcde")); + test(S("abcde"), 4, 0, S("12345"), 4, 1, S("abcd5e")); + test(S("abcde"), 4, 0, S("12345"), 4, 2, S("abcd5e")); + test(S("abcde"), 4, 0, S("12345"), 5, 0, S("abcde")); + test(S("abcde"), 4, 0, S("12345"), 5, 1, S("abcde")); + test(S("abcde"), 4, 0, S("12345"), 6, 0, S("can't happen")); + test(S("abcde"), 4, 0, S("1234567890"), 0, 0, S("abcde")); + test(S("abcde"), 4, 0, S("1234567890"), 0, 1, S("abcd1e")); + test(S("abcde"), 4, 0, S("1234567890"), 0, 5, S("abcd12345e")); + test(S("abcde"), 4, 0, S("1234567890"), 0, 9, S("abcd123456789e")); + test(S("abcde"), 4, 0, S("1234567890"), 0, 10, S("abcd1234567890e")); + test(S("abcde"), 4, 0, S("1234567890"), 0, 11, S("abcd1234567890e")); + test(S("abcde"), 4, 0, S("1234567890"), 1, 0, S("abcde")); + test(S("abcde"), 4, 0, S("1234567890"), 1, 1, S("abcd2e")); + test(S("abcde"), 4, 0, S("1234567890"), 1, 4, S("abcd2345e")); + test(S("abcde"), 4, 0, S("1234567890"), 1, 8, S("abcd23456789e")); + test(S("abcde"), 4, 0, S("1234567890"), 1, 9, S("abcd234567890e")); + test(S("abcde"), 4, 0, S("1234567890"), 1, 10, S("abcd234567890e")); + test(S("abcde"), 4, 0, S("1234567890"), 5, 0, S("abcde")); + test(S("abcde"), 4, 0, S("1234567890"), 5, 1, S("abcd6e")); + test(S("abcde"), 4, 0, S("1234567890"), 5, 2, S("abcd67e")); + test(S("abcde"), 4, 0, S("1234567890"), 5, 4, S("abcd6789e")); + test(S("abcde"), 4, 0, S("1234567890"), 5, 5, S("abcd67890e")); + test(S("abcde"), 4, 0, S("1234567890"), 5, 6, S("abcd67890e")); + test(S("abcde"), 4, 0, S("1234567890"), 9, 0, S("abcde")); + test(S("abcde"), 4, 0, S("1234567890"), 9, 1, S("abcd0e")); + test(S("abcde"), 4, 0, S("1234567890"), 9, 2, S("abcd0e")); + test(S("abcde"), 4, 0, S("1234567890"), 10, 0, S("abcde")); + test(S("abcde"), 4, 0, S("1234567890"), 10, 1, S("abcde")); + test(S("abcde"), 4, 0, S("1234567890"), 11, 0, S("can't happen")); + test(S("abcde"), 4, 0, S("12345678901234567890"), 0, 0, S("abcde")); + test(S("abcde"), 4, 0, S("12345678901234567890"), 0, 1, S("abcd1e")); + test(S("abcde"), 4, 0, S("12345678901234567890"), 0, 10, S("abcd1234567890e")); + test(S("abcde"), 4, 0, S("12345678901234567890"), 0, 19, S("abcd1234567890123456789e")); + test(S("abcde"), 4, 0, S("12345678901234567890"), 0, 20, S("abcd12345678901234567890e")); + test(S("abcde"), 4, 0, S("12345678901234567890"), 0, 21, S("abcd12345678901234567890e")); + test(S("abcde"), 4, 0, S("12345678901234567890"), 1, 0, S("abcde")); + test(S("abcde"), 4, 0, S("12345678901234567890"), 1, 1, S("abcd2e")); + test(S("abcde"), 4, 0, S("12345678901234567890"), 1, 9, S("abcd234567890e")); + test(S("abcde"), 4, 0, S("12345678901234567890"), 1, 18, S("abcd234567890123456789e")); + test(S("abcde"), 4, 0, S("12345678901234567890"), 1, 19, S("abcd2345678901234567890e")); + test(S("abcde"), 4, 0, S("12345678901234567890"), 1, 20, S("abcd2345678901234567890e")); + test(S("abcde"), 4, 0, S("12345678901234567890"), 10, 0, S("abcde")); + test(S("abcde"), 4, 0, S("12345678901234567890"), 10, 1, S("abcd1e")); + test(S("abcde"), 4, 0, S("12345678901234567890"), 10, 5, S("abcd12345e")); + test(S("abcde"), 4, 0, S("12345678901234567890"), 10, 9, S("abcd123456789e")); + test(S("abcde"), 4, 0, S("12345678901234567890"), 10, 10, S("abcd1234567890e")); + test(S("abcde"), 4, 0, S("12345678901234567890"), 10, 11, S("abcd1234567890e")); + test(S("abcde"), 4, 0, S("12345678901234567890"), 19, 0, S("abcde")); + test(S("abcde"), 4, 0, S("12345678901234567890"), 19, 1, S("abcd0e")); + test(S("abcde"), 4, 0, S("12345678901234567890"), 19, 2, S("abcd0e")); + test(S("abcde"), 4, 0, S("12345678901234567890"), 20, 0, S("abcde")); + test(S("abcde"), 4, 0, S("12345678901234567890"), 20, 1, S("abcde")); + test(S("abcde"), 4, 0, S("12345678901234567890"), 21, 0, S("can't happen")); + test(S("abcde"), 4, 1, S(""), 0, 0, S("abcd")); + test(S("abcde"), 4, 1, S(""), 0, 1, S("abcd")); + test(S("abcde"), 4, 1, S(""), 1, 0, S("can't happen")); + test(S("abcde"), 4, 1, S("12345"), 0, 0, S("abcd")); + test(S("abcde"), 4, 1, S("12345"), 0, 1, S("abcd1")); + test(S("abcde"), 4, 1, S("12345"), 0, 2, S("abcd12")); + test(S("abcde"), 4, 1, S("12345"), 0, 4, S("abcd1234")); + test(S("abcde"), 4, 1, S("12345"), 0, 5, S("abcd12345")); + test(S("abcde"), 4, 1, S("12345"), 0, 6, S("abcd12345")); + test(S("abcde"), 4, 1, S("12345"), 1, 0, S("abcd")); + test(S("abcde"), 4, 1, S("12345"), 1, 1, S("abcd2")); + test(S("abcde"), 4, 1, S("12345"), 1, 2, S("abcd23")); + test(S("abcde"), 4, 1, S("12345"), 1, 3, S("abcd234")); + test(S("abcde"), 4, 1, S("12345"), 1, 4, S("abcd2345")); + test(S("abcde"), 4, 1, S("12345"), 1, 5, S("abcd2345")); + test(S("abcde"), 4, 1, S("12345"), 2, 0, S("abcd")); + test(S("abcde"), 4, 1, S("12345"), 2, 1, S("abcd3")); + test(S("abcde"), 4, 1, S("12345"), 2, 2, S("abcd34")); + test(S("abcde"), 4, 1, S("12345"), 2, 3, S("abcd345")); + test(S("abcde"), 4, 1, S("12345"), 2, 4, S("abcd345")); + test(S("abcde"), 4, 1, S("12345"), 4, 0, S("abcd")); + test(S("abcde"), 4, 1, S("12345"), 4, 1, S("abcd5")); + test(S("abcde"), 4, 1, S("12345"), 4, 2, S("abcd5")); + test(S("abcde"), 4, 1, S("12345"), 5, 0, S("abcd")); + test(S("abcde"), 4, 1, S("12345"), 5, 1, S("abcd")); + test(S("abcde"), 4, 1, S("12345"), 6, 0, S("can't happen")); + test(S("abcde"), 4, 1, S("1234567890"), 0, 0, S("abcd")); + test(S("abcde"), 4, 1, S("1234567890"), 0, 1, S("abcd1")); + test(S("abcde"), 4, 1, S("1234567890"), 0, 5, S("abcd12345")); + test(S("abcde"), 4, 1, S("1234567890"), 0, 9, S("abcd123456789")); + test(S("abcde"), 4, 1, S("1234567890"), 0, 10, S("abcd1234567890")); + test(S("abcde"), 4, 1, S("1234567890"), 0, 11, S("abcd1234567890")); + test(S("abcde"), 4, 1, S("1234567890"), 1, 0, S("abcd")); + test(S("abcde"), 4, 1, S("1234567890"), 1, 1, S("abcd2")); + test(S("abcde"), 4, 1, S("1234567890"), 1, 4, S("abcd2345")); + test(S("abcde"), 4, 1, S("1234567890"), 1, 8, S("abcd23456789")); + test(S("abcde"), 4, 1, S("1234567890"), 1, 9, S("abcd234567890")); + test(S("abcde"), 4, 1, S("1234567890"), 1, 10, S("abcd234567890")); + test(S("abcde"), 4, 1, S("1234567890"), 5, 0, S("abcd")); + test(S("abcde"), 4, 1, S("1234567890"), 5, 1, S("abcd6")); + test(S("abcde"), 4, 1, S("1234567890"), 5, 2, S("abcd67")); + test(S("abcde"), 4, 1, S("1234567890"), 5, 4, S("abcd6789")); + test(S("abcde"), 4, 1, S("1234567890"), 5, 5, S("abcd67890")); + test(S("abcde"), 4, 1, S("1234567890"), 5, 6, S("abcd67890")); + test(S("abcde"), 4, 1, S("1234567890"), 9, 0, S("abcd")); + test(S("abcde"), 4, 1, S("1234567890"), 9, 1, S("abcd0")); +} + +template +void test16() +{ + test(S("abcde"), 4, 1, S("1234567890"), 9, 2, S("abcd0")); + test(S("abcde"), 4, 1, S("1234567890"), 10, 0, S("abcd")); + test(S("abcde"), 4, 1, S("1234567890"), 10, 1, S("abcd")); + test(S("abcde"), 4, 1, S("1234567890"), 11, 0, S("can't happen")); + test(S("abcde"), 4, 1, S("12345678901234567890"), 0, 0, S("abcd")); + test(S("abcde"), 4, 1, S("12345678901234567890"), 0, 1, S("abcd1")); + test(S("abcde"), 4, 1, S("12345678901234567890"), 0, 10, S("abcd1234567890")); + test(S("abcde"), 4, 1, S("12345678901234567890"), 0, 19, S("abcd1234567890123456789")); + test(S("abcde"), 4, 1, S("12345678901234567890"), 0, 20, S("abcd12345678901234567890")); + test(S("abcde"), 4, 1, S("12345678901234567890"), 0, 21, S("abcd12345678901234567890")); + test(S("abcde"), 4, 1, S("12345678901234567890"), 1, 0, S("abcd")); + test(S("abcde"), 4, 1, S("12345678901234567890"), 1, 1, S("abcd2")); + test(S("abcde"), 4, 1, S("12345678901234567890"), 1, 9, S("abcd234567890")); + test(S("abcde"), 4, 1, S("12345678901234567890"), 1, 18, S("abcd234567890123456789")); + test(S("abcde"), 4, 1, S("12345678901234567890"), 1, 19, S("abcd2345678901234567890")); + test(S("abcde"), 4, 1, S("12345678901234567890"), 1, 20, S("abcd2345678901234567890")); + test(S("abcde"), 4, 1, S("12345678901234567890"), 10, 0, S("abcd")); + test(S("abcde"), 4, 1, S("12345678901234567890"), 10, 1, S("abcd1")); + test(S("abcde"), 4, 1, S("12345678901234567890"), 10, 5, S("abcd12345")); + test(S("abcde"), 4, 1, S("12345678901234567890"), 10, 9, S("abcd123456789")); + test(S("abcde"), 4, 1, S("12345678901234567890"), 10, 10, S("abcd1234567890")); + test(S("abcde"), 4, 1, S("12345678901234567890"), 10, 11, S("abcd1234567890")); + test(S("abcde"), 4, 1, S("12345678901234567890"), 19, 0, S("abcd")); + test(S("abcde"), 4, 1, S("12345678901234567890"), 19, 1, S("abcd0")); + test(S("abcde"), 4, 1, S("12345678901234567890"), 19, 2, S("abcd0")); + test(S("abcde"), 4, 1, S("12345678901234567890"), 20, 0, S("abcd")); + test(S("abcde"), 4, 1, S("12345678901234567890"), 20, 1, S("abcd")); + test(S("abcde"), 4, 1, S("12345678901234567890"), 21, 0, S("can't happen")); + test(S("abcde"), 4, 2, S(""), 0, 0, S("abcd")); + test(S("abcde"), 4, 2, S(""), 0, 1, S("abcd")); + test(S("abcde"), 4, 2, S(""), 1, 0, S("can't happen")); + test(S("abcde"), 4, 2, S("12345"), 0, 0, S("abcd")); + test(S("abcde"), 4, 2, S("12345"), 0, 1, S("abcd1")); + test(S("abcde"), 4, 2, S("12345"), 0, 2, S("abcd12")); + test(S("abcde"), 4, 2, S("12345"), 0, 4, S("abcd1234")); + test(S("abcde"), 4, 2, S("12345"), 0, 5, S("abcd12345")); + test(S("abcde"), 4, 2, S("12345"), 0, 6, S("abcd12345")); + test(S("abcde"), 4, 2, S("12345"), 1, 0, S("abcd")); + test(S("abcde"), 4, 2, S("12345"), 1, 1, S("abcd2")); + test(S("abcde"), 4, 2, S("12345"), 1, 2, S("abcd23")); + test(S("abcde"), 4, 2, S("12345"), 1, 3, S("abcd234")); + test(S("abcde"), 4, 2, S("12345"), 1, 4, S("abcd2345")); + test(S("abcde"), 4, 2, S("12345"), 1, 5, S("abcd2345")); + test(S("abcde"), 4, 2, S("12345"), 2, 0, S("abcd")); + test(S("abcde"), 4, 2, S("12345"), 2, 1, S("abcd3")); + test(S("abcde"), 4, 2, S("12345"), 2, 2, S("abcd34")); + test(S("abcde"), 4, 2, S("12345"), 2, 3, S("abcd345")); + test(S("abcde"), 4, 2, S("12345"), 2, 4, S("abcd345")); + test(S("abcde"), 4, 2, S("12345"), 4, 0, S("abcd")); + test(S("abcde"), 4, 2, S("12345"), 4, 1, S("abcd5")); + test(S("abcde"), 4, 2, S("12345"), 4, 2, S("abcd5")); + test(S("abcde"), 4, 2, S("12345"), 5, 0, S("abcd")); + test(S("abcde"), 4, 2, S("12345"), 5, 1, S("abcd")); + test(S("abcde"), 4, 2, S("12345"), 6, 0, S("can't happen")); + test(S("abcde"), 4, 2, S("1234567890"), 0, 0, S("abcd")); + test(S("abcde"), 4, 2, S("1234567890"), 0, 1, S("abcd1")); + test(S("abcde"), 4, 2, S("1234567890"), 0, 5, S("abcd12345")); + test(S("abcde"), 4, 2, S("1234567890"), 0, 9, S("abcd123456789")); + test(S("abcde"), 4, 2, S("1234567890"), 0, 10, S("abcd1234567890")); + test(S("abcde"), 4, 2, S("1234567890"), 0, 11, S("abcd1234567890")); + test(S("abcde"), 4, 2, S("1234567890"), 1, 0, S("abcd")); + test(S("abcde"), 4, 2, S("1234567890"), 1, 1, S("abcd2")); + test(S("abcde"), 4, 2, S("1234567890"), 1, 4, S("abcd2345")); + test(S("abcde"), 4, 2, S("1234567890"), 1, 8, S("abcd23456789")); + test(S("abcde"), 4, 2, S("1234567890"), 1, 9, S("abcd234567890")); + test(S("abcde"), 4, 2, S("1234567890"), 1, 10, S("abcd234567890")); + test(S("abcde"), 4, 2, S("1234567890"), 5, 0, S("abcd")); + test(S("abcde"), 4, 2, S("1234567890"), 5, 1, S("abcd6")); + test(S("abcde"), 4, 2, S("1234567890"), 5, 2, S("abcd67")); + test(S("abcde"), 4, 2, S("1234567890"), 5, 4, S("abcd6789")); + test(S("abcde"), 4, 2, S("1234567890"), 5, 5, S("abcd67890")); + test(S("abcde"), 4, 2, S("1234567890"), 5, 6, S("abcd67890")); + test(S("abcde"), 4, 2, S("1234567890"), 9, 0, S("abcd")); + test(S("abcde"), 4, 2, S("1234567890"), 9, 1, S("abcd0")); + test(S("abcde"), 4, 2, S("1234567890"), 9, 2, S("abcd0")); + test(S("abcde"), 4, 2, S("1234567890"), 10, 0, S("abcd")); + test(S("abcde"), 4, 2, S("1234567890"), 10, 1, S("abcd")); + test(S("abcde"), 4, 2, S("1234567890"), 11, 0, S("can't happen")); + test(S("abcde"), 4, 2, S("12345678901234567890"), 0, 0, S("abcd")); + test(S("abcde"), 4, 2, S("12345678901234567890"), 0, 1, S("abcd1")); + test(S("abcde"), 4, 2, S("12345678901234567890"), 0, 10, S("abcd1234567890")); + test(S("abcde"), 4, 2, S("12345678901234567890"), 0, 19, S("abcd1234567890123456789")); + test(S("abcde"), 4, 2, S("12345678901234567890"), 0, 20, S("abcd12345678901234567890")); + test(S("abcde"), 4, 2, S("12345678901234567890"), 0, 21, S("abcd12345678901234567890")); + test(S("abcde"), 4, 2, S("12345678901234567890"), 1, 0, S("abcd")); + test(S("abcde"), 4, 2, S("12345678901234567890"), 1, 1, S("abcd2")); + test(S("abcde"), 4, 2, S("12345678901234567890"), 1, 9, S("abcd234567890")); + test(S("abcde"), 4, 2, S("12345678901234567890"), 1, 18, S("abcd234567890123456789")); + test(S("abcde"), 4, 2, S("12345678901234567890"), 1, 19, S("abcd2345678901234567890")); + test(S("abcde"), 4, 2, S("12345678901234567890"), 1, 20, S("abcd2345678901234567890")); + test(S("abcde"), 4, 2, S("12345678901234567890"), 10, 0, S("abcd")); + test(S("abcde"), 4, 2, S("12345678901234567890"), 10, 1, S("abcd1")); + test(S("abcde"), 4, 2, S("12345678901234567890"), 10, 5, S("abcd12345")); + test(S("abcde"), 4, 2, S("12345678901234567890"), 10, 9, S("abcd123456789")); + test(S("abcde"), 4, 2, S("12345678901234567890"), 10, 10, S("abcd1234567890")); + test(S("abcde"), 4, 2, S("12345678901234567890"), 10, 11, S("abcd1234567890")); + test(S("abcde"), 4, 2, S("12345678901234567890"), 19, 0, S("abcd")); + test(S("abcde"), 4, 2, S("12345678901234567890"), 19, 1, S("abcd0")); + test(S("abcde"), 4, 2, S("12345678901234567890"), 19, 2, S("abcd0")); + test(S("abcde"), 4, 2, S("12345678901234567890"), 20, 0, S("abcd")); +} + +template +void test17() +{ + test(S("abcde"), 4, 2, S("12345678901234567890"), 20, 1, S("abcd")); + test(S("abcde"), 4, 2, S("12345678901234567890"), 21, 0, S("can't happen")); + test(S("abcde"), 5, 0, S(""), 0, 0, S("abcde")); + test(S("abcde"), 5, 0, S(""), 0, 1, S("abcde")); + test(S("abcde"), 5, 0, S(""), 1, 0, S("can't happen")); + test(S("abcde"), 5, 0, S("12345"), 0, 0, S("abcde")); + test(S("abcde"), 5, 0, S("12345"), 0, 1, S("abcde1")); + test(S("abcde"), 5, 0, S("12345"), 0, 2, S("abcde12")); + test(S("abcde"), 5, 0, S("12345"), 0, 4, S("abcde1234")); + test(S("abcde"), 5, 0, S("12345"), 0, 5, S("abcde12345")); + test(S("abcde"), 5, 0, S("12345"), 0, 6, S("abcde12345")); + test(S("abcde"), 5, 0, S("12345"), 1, 0, S("abcde")); + test(S("abcde"), 5, 0, S("12345"), 1, 1, S("abcde2")); + test(S("abcde"), 5, 0, S("12345"), 1, 2, S("abcde23")); + test(S("abcde"), 5, 0, S("12345"), 1, 3, S("abcde234")); + test(S("abcde"), 5, 0, S("12345"), 1, 4, S("abcde2345")); + test(S("abcde"), 5, 0, S("12345"), 1, 5, S("abcde2345")); + test(S("abcde"), 5, 0, S("12345"), 2, 0, S("abcde")); + test(S("abcde"), 5, 0, S("12345"), 2, 1, S("abcde3")); + test(S("abcde"), 5, 0, S("12345"), 2, 2, S("abcde34")); + test(S("abcde"), 5, 0, S("12345"), 2, 3, S("abcde345")); + test(S("abcde"), 5, 0, S("12345"), 2, 4, S("abcde345")); + test(S("abcde"), 5, 0, S("12345"), 4, 0, S("abcde")); + test(S("abcde"), 5, 0, S("12345"), 4, 1, S("abcde5")); + test(S("abcde"), 5, 0, S("12345"), 4, 2, S("abcde5")); + test(S("abcde"), 5, 0, S("12345"), 5, 0, S("abcde")); + test(S("abcde"), 5, 0, S("12345"), 5, 1, S("abcde")); + test(S("abcde"), 5, 0, S("12345"), 6, 0, S("can't happen")); + test(S("abcde"), 5, 0, S("1234567890"), 0, 0, S("abcde")); + test(S("abcde"), 5, 0, S("1234567890"), 0, 1, S("abcde1")); + test(S("abcde"), 5, 0, S("1234567890"), 0, 5, S("abcde12345")); + test(S("abcde"), 5, 0, S("1234567890"), 0, 9, S("abcde123456789")); + test(S("abcde"), 5, 0, S("1234567890"), 0, 10, S("abcde1234567890")); + test(S("abcde"), 5, 0, S("1234567890"), 0, 11, S("abcde1234567890")); + test(S("abcde"), 5, 0, S("1234567890"), 1, 0, S("abcde")); + test(S("abcde"), 5, 0, S("1234567890"), 1, 1, S("abcde2")); + test(S("abcde"), 5, 0, S("1234567890"), 1, 4, S("abcde2345")); + test(S("abcde"), 5, 0, S("1234567890"), 1, 8, S("abcde23456789")); + test(S("abcde"), 5, 0, S("1234567890"), 1, 9, S("abcde234567890")); + test(S("abcde"), 5, 0, S("1234567890"), 1, 10, S("abcde234567890")); + test(S("abcde"), 5, 0, S("1234567890"), 5, 0, S("abcde")); + test(S("abcde"), 5, 0, S("1234567890"), 5, 1, S("abcde6")); + test(S("abcde"), 5, 0, S("1234567890"), 5, 2, S("abcde67")); + test(S("abcde"), 5, 0, S("1234567890"), 5, 4, S("abcde6789")); + test(S("abcde"), 5, 0, S("1234567890"), 5, 5, S("abcde67890")); + test(S("abcde"), 5, 0, S("1234567890"), 5, 6, S("abcde67890")); + test(S("abcde"), 5, 0, S("1234567890"), 9, 0, S("abcde")); + test(S("abcde"), 5, 0, S("1234567890"), 9, 1, S("abcde0")); + test(S("abcde"), 5, 0, S("1234567890"), 9, 2, S("abcde0")); + test(S("abcde"), 5, 0, S("1234567890"), 10, 0, S("abcde")); + test(S("abcde"), 5, 0, S("1234567890"), 10, 1, S("abcde")); + test(S("abcde"), 5, 0, S("1234567890"), 11, 0, S("can't happen")); + test(S("abcde"), 5, 0, S("12345678901234567890"), 0, 0, S("abcde")); + test(S("abcde"), 5, 0, S("12345678901234567890"), 0, 1, S("abcde1")); + test(S("abcde"), 5, 0, S("12345678901234567890"), 0, 10, S("abcde1234567890")); + test(S("abcde"), 5, 0, S("12345678901234567890"), 0, 19, S("abcde1234567890123456789")); + test(S("abcde"), 5, 0, S("12345678901234567890"), 0, 20, S("abcde12345678901234567890")); + test(S("abcde"), 5, 0, S("12345678901234567890"), 0, 21, S("abcde12345678901234567890")); + test(S("abcde"), 5, 0, S("12345678901234567890"), 1, 0, S("abcde")); + test(S("abcde"), 5, 0, S("12345678901234567890"), 1, 1, S("abcde2")); + test(S("abcde"), 5, 0, S("12345678901234567890"), 1, 9, S("abcde234567890")); + test(S("abcde"), 5, 0, S("12345678901234567890"), 1, 18, S("abcde234567890123456789")); + test(S("abcde"), 5, 0, S("12345678901234567890"), 1, 19, S("abcde2345678901234567890")); + test(S("abcde"), 5, 0, S("12345678901234567890"), 1, 20, S("abcde2345678901234567890")); + test(S("abcde"), 5, 0, S("12345678901234567890"), 10, 0, S("abcde")); + test(S("abcde"), 5, 0, S("12345678901234567890"), 10, 1, S("abcde1")); + test(S("abcde"), 5, 0, S("12345678901234567890"), 10, 5, S("abcde12345")); + test(S("abcde"), 5, 0, S("12345678901234567890"), 10, 9, S("abcde123456789")); + test(S("abcde"), 5, 0, S("12345678901234567890"), 10, 10, S("abcde1234567890")); + test(S("abcde"), 5, 0, S("12345678901234567890"), 10, 11, S("abcde1234567890")); + test(S("abcde"), 5, 0, S("12345678901234567890"), 19, 0, S("abcde")); + test(S("abcde"), 5, 0, S("12345678901234567890"), 19, 1, S("abcde0")); + test(S("abcde"), 5, 0, S("12345678901234567890"), 19, 2, S("abcde0")); + test(S("abcde"), 5, 0, S("12345678901234567890"), 20, 0, S("abcde")); + test(S("abcde"), 5, 0, S("12345678901234567890"), 20, 1, S("abcde")); + test(S("abcde"), 5, 0, S("12345678901234567890"), 21, 0, S("can't happen")); + test(S("abcde"), 5, 1, S(""), 0, 0, S("abcde")); + test(S("abcde"), 5, 1, S(""), 0, 1, S("abcde")); + test(S("abcde"), 5, 1, S(""), 1, 0, S("can't happen")); + test(S("abcde"), 5, 1, S("12345"), 0, 0, S("abcde")); + test(S("abcde"), 5, 1, S("12345"), 0, 1, S("abcde1")); + test(S("abcde"), 5, 1, S("12345"), 0, 2, S("abcde12")); + test(S("abcde"), 5, 1, S("12345"), 0, 4, S("abcde1234")); + test(S("abcde"), 5, 1, S("12345"), 0, 5, S("abcde12345")); + test(S("abcde"), 5, 1, S("12345"), 0, 6, S("abcde12345")); + test(S("abcde"), 5, 1, S("12345"), 1, 0, S("abcde")); + test(S("abcde"), 5, 1, S("12345"), 1, 1, S("abcde2")); + test(S("abcde"), 5, 1, S("12345"), 1, 2, S("abcde23")); + test(S("abcde"), 5, 1, S("12345"), 1, 3, S("abcde234")); + test(S("abcde"), 5, 1, S("12345"), 1, 4, S("abcde2345")); + test(S("abcde"), 5, 1, S("12345"), 1, 5, S("abcde2345")); + test(S("abcde"), 5, 1, S("12345"), 2, 0, S("abcde")); + test(S("abcde"), 5, 1, S("12345"), 2, 1, S("abcde3")); + test(S("abcde"), 5, 1, S("12345"), 2, 2, S("abcde34")); + test(S("abcde"), 5, 1, S("12345"), 2, 3, S("abcde345")); + test(S("abcde"), 5, 1, S("12345"), 2, 4, S("abcde345")); + test(S("abcde"), 5, 1, S("12345"), 4, 0, S("abcde")); + test(S("abcde"), 5, 1, S("12345"), 4, 1, S("abcde5")); + test(S("abcde"), 5, 1, S("12345"), 4, 2, S("abcde5")); + test(S("abcde"), 5, 1, S("12345"), 5, 0, S("abcde")); +} + +template +void test18() +{ + test(S("abcde"), 5, 1, S("12345"), 5, 1, S("abcde")); + test(S("abcde"), 5, 1, S("12345"), 6, 0, S("can't happen")); + test(S("abcde"), 5, 1, S("1234567890"), 0, 0, S("abcde")); + test(S("abcde"), 5, 1, S("1234567890"), 0, 1, S("abcde1")); + test(S("abcde"), 5, 1, S("1234567890"), 0, 5, S("abcde12345")); + test(S("abcde"), 5, 1, S("1234567890"), 0, 9, S("abcde123456789")); + test(S("abcde"), 5, 1, S("1234567890"), 0, 10, S("abcde1234567890")); + test(S("abcde"), 5, 1, S("1234567890"), 0, 11, S("abcde1234567890")); + test(S("abcde"), 5, 1, S("1234567890"), 1, 0, S("abcde")); + test(S("abcde"), 5, 1, S("1234567890"), 1, 1, S("abcde2")); + test(S("abcde"), 5, 1, S("1234567890"), 1, 4, S("abcde2345")); + test(S("abcde"), 5, 1, S("1234567890"), 1, 8, S("abcde23456789")); + test(S("abcde"), 5, 1, S("1234567890"), 1, 9, S("abcde234567890")); + test(S("abcde"), 5, 1, S("1234567890"), 1, 10, S("abcde234567890")); + test(S("abcde"), 5, 1, S("1234567890"), 5, 0, S("abcde")); + test(S("abcde"), 5, 1, S("1234567890"), 5, 1, S("abcde6")); + test(S("abcde"), 5, 1, S("1234567890"), 5, 2, S("abcde67")); + test(S("abcde"), 5, 1, S("1234567890"), 5, 4, S("abcde6789")); + test(S("abcde"), 5, 1, S("1234567890"), 5, 5, S("abcde67890")); + test(S("abcde"), 5, 1, S("1234567890"), 5, 6, S("abcde67890")); + test(S("abcde"), 5, 1, S("1234567890"), 9, 0, S("abcde")); + test(S("abcde"), 5, 1, S("1234567890"), 9, 1, S("abcde0")); + test(S("abcde"), 5, 1, S("1234567890"), 9, 2, S("abcde0")); + test(S("abcde"), 5, 1, S("1234567890"), 10, 0, S("abcde")); + test(S("abcde"), 5, 1, S("1234567890"), 10, 1, S("abcde")); + test(S("abcde"), 5, 1, S("1234567890"), 11, 0, S("can't happen")); + test(S("abcde"), 5, 1, S("12345678901234567890"), 0, 0, S("abcde")); + test(S("abcde"), 5, 1, S("12345678901234567890"), 0, 1, S("abcde1")); + test(S("abcde"), 5, 1, S("12345678901234567890"), 0, 10, S("abcde1234567890")); + test(S("abcde"), 5, 1, S("12345678901234567890"), 0, 19, S("abcde1234567890123456789")); + test(S("abcde"), 5, 1, S("12345678901234567890"), 0, 20, S("abcde12345678901234567890")); + test(S("abcde"), 5, 1, S("12345678901234567890"), 0, 21, S("abcde12345678901234567890")); + test(S("abcde"), 5, 1, S("12345678901234567890"), 1, 0, S("abcde")); + test(S("abcde"), 5, 1, S("12345678901234567890"), 1, 1, S("abcde2")); + test(S("abcde"), 5, 1, S("12345678901234567890"), 1, 9, S("abcde234567890")); + test(S("abcde"), 5, 1, S("12345678901234567890"), 1, 18, S("abcde234567890123456789")); + test(S("abcde"), 5, 1, S("12345678901234567890"), 1, 19, S("abcde2345678901234567890")); + test(S("abcde"), 5, 1, S("12345678901234567890"), 1, 20, S("abcde2345678901234567890")); + test(S("abcde"), 5, 1, S("12345678901234567890"), 10, 0, S("abcde")); + test(S("abcde"), 5, 1, S("12345678901234567890"), 10, 1, S("abcde1")); + test(S("abcde"), 5, 1, S("12345678901234567890"), 10, 5, S("abcde12345")); + test(S("abcde"), 5, 1, S("12345678901234567890"), 10, 9, S("abcde123456789")); + test(S("abcde"), 5, 1, S("12345678901234567890"), 10, 10, S("abcde1234567890")); + test(S("abcde"), 5, 1, S("12345678901234567890"), 10, 11, S("abcde1234567890")); + test(S("abcde"), 5, 1, S("12345678901234567890"), 19, 0, S("abcde")); + test(S("abcde"), 5, 1, S("12345678901234567890"), 19, 1, S("abcde0")); + test(S("abcde"), 5, 1, S("12345678901234567890"), 19, 2, S("abcde0")); + test(S("abcde"), 5, 1, S("12345678901234567890"), 20, 0, S("abcde")); + test(S("abcde"), 5, 1, S("12345678901234567890"), 20, 1, S("abcde")); + test(S("abcde"), 5, 1, S("12345678901234567890"), 21, 0, S("can't happen")); + test(S("abcde"), 6, 0, S(""), 0, 0, S("can't happen")); + test(S("abcde"), 6, 0, S(""), 0, 1, S("can't happen")); + test(S("abcde"), 6, 0, S(""), 1, 0, S("can't happen")); + test(S("abcde"), 6, 0, S("12345"), 0, 0, S("can't happen")); + test(S("abcde"), 6, 0, S("12345"), 0, 1, S("can't happen")); + test(S("abcde"), 6, 0, S("12345"), 0, 2, S("can't happen")); + test(S("abcde"), 6, 0, S("12345"), 0, 4, S("can't happen")); + test(S("abcde"), 6, 0, S("12345"), 0, 5, S("can't happen")); + test(S("abcde"), 6, 0, S("12345"), 0, 6, S("can't happen")); + test(S("abcde"), 6, 0, S("12345"), 1, 0, S("can't happen")); + test(S("abcde"), 6, 0, S("12345"), 1, 1, S("can't happen")); + test(S("abcde"), 6, 0, S("12345"), 1, 2, S("can't happen")); + test(S("abcde"), 6, 0, S("12345"), 1, 3, S("can't happen")); + test(S("abcde"), 6, 0, S("12345"), 1, 4, S("can't happen")); + test(S("abcde"), 6, 0, S("12345"), 1, 5, S("can't happen")); + test(S("abcde"), 6, 0, S("12345"), 2, 0, S("can't happen")); + test(S("abcde"), 6, 0, S("12345"), 2, 1, S("can't happen")); + test(S("abcde"), 6, 0, S("12345"), 2, 2, S("can't happen")); + test(S("abcde"), 6, 0, S("12345"), 2, 3, S("can't happen")); + test(S("abcde"), 6, 0, S("12345"), 2, 4, S("can't happen")); + test(S("abcde"), 6, 0, S("12345"), 4, 0, S("can't happen")); + test(S("abcde"), 6, 0, S("12345"), 4, 1, S("can't happen")); + test(S("abcde"), 6, 0, S("12345"), 4, 2, S("can't happen")); + test(S("abcde"), 6, 0, S("12345"), 5, 0, S("can't happen")); + test(S("abcde"), 6, 0, S("12345"), 5, 1, S("can't happen")); + test(S("abcde"), 6, 0, S("12345"), 6, 0, S("can't happen")); + test(S("abcde"), 6, 0, S("1234567890"), 0, 0, S("can't happen")); + test(S("abcde"), 6, 0, S("1234567890"), 0, 1, S("can't happen")); + test(S("abcde"), 6, 0, S("1234567890"), 0, 5, S("can't happen")); + test(S("abcde"), 6, 0, S("1234567890"), 0, 9, S("can't happen")); + test(S("abcde"), 6, 0, S("1234567890"), 0, 10, S("can't happen")); + test(S("abcde"), 6, 0, S("1234567890"), 0, 11, S("can't happen")); + test(S("abcde"), 6, 0, S("1234567890"), 1, 0, S("can't happen")); + test(S("abcde"), 6, 0, S("1234567890"), 1, 1, S("can't happen")); + test(S("abcde"), 6, 0, S("1234567890"), 1, 4, S("can't happen")); + test(S("abcde"), 6, 0, S("1234567890"), 1, 8, S("can't happen")); + test(S("abcde"), 6, 0, S("1234567890"), 1, 9, S("can't happen")); + test(S("abcde"), 6, 0, S("1234567890"), 1, 10, S("can't happen")); + test(S("abcde"), 6, 0, S("1234567890"), 5, 0, S("can't happen")); + test(S("abcde"), 6, 0, S("1234567890"), 5, 1, S("can't happen")); + test(S("abcde"), 6, 0, S("1234567890"), 5, 2, S("can't happen")); + test(S("abcde"), 6, 0, S("1234567890"), 5, 4, S("can't happen")); + test(S("abcde"), 6, 0, S("1234567890"), 5, 5, S("can't happen")); + test(S("abcde"), 6, 0, S("1234567890"), 5, 6, S("can't happen")); + test(S("abcde"), 6, 0, S("1234567890"), 9, 0, S("can't happen")); + test(S("abcde"), 6, 0, S("1234567890"), 9, 1, S("can't happen")); + test(S("abcde"), 6, 0, S("1234567890"), 9, 2, S("can't happen")); + test(S("abcde"), 6, 0, S("1234567890"), 10, 0, S("can't happen")); + test(S("abcde"), 6, 0, S("1234567890"), 10, 1, S("can't happen")); + test(S("abcde"), 6, 0, S("1234567890"), 11, 0, S("can't happen")); +} + +template +void test19() +{ + test(S("abcde"), 6, 0, S("12345678901234567890"), 0, 0, S("can't happen")); + test(S("abcde"), 6, 0, S("12345678901234567890"), 0, 1, S("can't happen")); + test(S("abcde"), 6, 0, S("12345678901234567890"), 0, 10, S("can't happen")); + test(S("abcde"), 6, 0, S("12345678901234567890"), 0, 19, S("can't happen")); + test(S("abcde"), 6, 0, S("12345678901234567890"), 0, 20, S("can't happen")); + test(S("abcde"), 6, 0, S("12345678901234567890"), 0, 21, S("can't happen")); + test(S("abcde"), 6, 0, S("12345678901234567890"), 1, 0, S("can't happen")); + test(S("abcde"), 6, 0, S("12345678901234567890"), 1, 1, S("can't happen")); + test(S("abcde"), 6, 0, S("12345678901234567890"), 1, 9, S("can't happen")); + test(S("abcde"), 6, 0, S("12345678901234567890"), 1, 18, S("can't happen")); + test(S("abcde"), 6, 0, S("12345678901234567890"), 1, 19, S("can't happen")); + test(S("abcde"), 6, 0, S("12345678901234567890"), 1, 20, S("can't happen")); + test(S("abcde"), 6, 0, S("12345678901234567890"), 10, 0, S("can't happen")); + test(S("abcde"), 6, 0, S("12345678901234567890"), 10, 1, S("can't happen")); + test(S("abcde"), 6, 0, S("12345678901234567890"), 10, 5, S("can't happen")); + test(S("abcde"), 6, 0, S("12345678901234567890"), 10, 9, S("can't happen")); + test(S("abcde"), 6, 0, S("12345678901234567890"), 10, 10, S("can't happen")); + test(S("abcde"), 6, 0, S("12345678901234567890"), 10, 11, S("can't happen")); + test(S("abcde"), 6, 0, S("12345678901234567890"), 19, 0, S("can't happen")); + test(S("abcde"), 6, 0, S("12345678901234567890"), 19, 1, S("can't happen")); + test(S("abcde"), 6, 0, S("12345678901234567890"), 19, 2, S("can't happen")); + test(S("abcde"), 6, 0, S("12345678901234567890"), 20, 0, S("can't happen")); + test(S("abcde"), 6, 0, S("12345678901234567890"), 20, 1, S("can't happen")); + test(S("abcde"), 6, 0, S("12345678901234567890"), 21, 0, S("can't happen")); + test(S("abcdefghij"), 0, 0, S(""), 0, 0, S("abcdefghij")); + test(S("abcdefghij"), 0, 0, S(""), 0, 1, S("abcdefghij")); + test(S("abcdefghij"), 0, 0, S(""), 1, 0, S("can't happen")); + test(S("abcdefghij"), 0, 0, S("12345"), 0, 0, S("abcdefghij")); + test(S("abcdefghij"), 0, 0, S("12345"), 0, 1, S("1abcdefghij")); + test(S("abcdefghij"), 0, 0, S("12345"), 0, 2, S("12abcdefghij")); + test(S("abcdefghij"), 0, 0, S("12345"), 0, 4, S("1234abcdefghij")); + test(S("abcdefghij"), 0, 0, S("12345"), 0, 5, S("12345abcdefghij")); + test(S("abcdefghij"), 0, 0, S("12345"), 0, 6, S("12345abcdefghij")); + test(S("abcdefghij"), 0, 0, S("12345"), 1, 0, S("abcdefghij")); + test(S("abcdefghij"), 0, 0, S("12345"), 1, 1, S("2abcdefghij")); + test(S("abcdefghij"), 0, 0, S("12345"), 1, 2, S("23abcdefghij")); + test(S("abcdefghij"), 0, 0, S("12345"), 1, 3, S("234abcdefghij")); + test(S("abcdefghij"), 0, 0, S("12345"), 1, 4, S("2345abcdefghij")); + test(S("abcdefghij"), 0, 0, S("12345"), 1, 5, S("2345abcdefghij")); + test(S("abcdefghij"), 0, 0, S("12345"), 2, 0, S("abcdefghij")); + test(S("abcdefghij"), 0, 0, S("12345"), 2, 1, S("3abcdefghij")); + test(S("abcdefghij"), 0, 0, S("12345"), 2, 2, S("34abcdefghij")); + test(S("abcdefghij"), 0, 0, S("12345"), 2, 3, S("345abcdefghij")); + test(S("abcdefghij"), 0, 0, S("12345"), 2, 4, S("345abcdefghij")); + test(S("abcdefghij"), 0, 0, S("12345"), 4, 0, S("abcdefghij")); + test(S("abcdefghij"), 0, 0, S("12345"), 4, 1, S("5abcdefghij")); + test(S("abcdefghij"), 0, 0, S("12345"), 4, 2, S("5abcdefghij")); + test(S("abcdefghij"), 0, 0, S("12345"), 5, 0, S("abcdefghij")); + test(S("abcdefghij"), 0, 0, S("12345"), 5, 1, S("abcdefghij")); + test(S("abcdefghij"), 0, 0, S("12345"), 6, 0, S("can't happen")); + test(S("abcdefghij"), 0, 0, S("1234567890"), 0, 0, S("abcdefghij")); + test(S("abcdefghij"), 0, 0, S("1234567890"), 0, 1, S("1abcdefghij")); + test(S("abcdefghij"), 0, 0, S("1234567890"), 0, 5, S("12345abcdefghij")); + test(S("abcdefghij"), 0, 0, S("1234567890"), 0, 9, S("123456789abcdefghij")); + test(S("abcdefghij"), 0, 0, S("1234567890"), 0, 10, S("1234567890abcdefghij")); + test(S("abcdefghij"), 0, 0, S("1234567890"), 0, 11, S("1234567890abcdefghij")); + test(S("abcdefghij"), 0, 0, S("1234567890"), 1, 0, S("abcdefghij")); + test(S("abcdefghij"), 0, 0, S("1234567890"), 1, 1, S("2abcdefghij")); + test(S("abcdefghij"), 0, 0, S("1234567890"), 1, 4, S("2345abcdefghij")); + test(S("abcdefghij"), 0, 0, S("1234567890"), 1, 8, S("23456789abcdefghij")); + test(S("abcdefghij"), 0, 0, S("1234567890"), 1, 9, S("234567890abcdefghij")); + test(S("abcdefghij"), 0, 0, S("1234567890"), 1, 10, S("234567890abcdefghij")); + test(S("abcdefghij"), 0, 0, S("1234567890"), 5, 0, S("abcdefghij")); + test(S("abcdefghij"), 0, 0, S("1234567890"), 5, 1, S("6abcdefghij")); + test(S("abcdefghij"), 0, 0, S("1234567890"), 5, 2, S("67abcdefghij")); + test(S("abcdefghij"), 0, 0, S("1234567890"), 5, 4, S("6789abcdefghij")); + test(S("abcdefghij"), 0, 0, S("1234567890"), 5, 5, S("67890abcdefghij")); + test(S("abcdefghij"), 0, 0, S("1234567890"), 5, 6, S("67890abcdefghij")); + test(S("abcdefghij"), 0, 0, S("1234567890"), 9, 0, S("abcdefghij")); + test(S("abcdefghij"), 0, 0, S("1234567890"), 9, 1, S("0abcdefghij")); + test(S("abcdefghij"), 0, 0, S("1234567890"), 9, 2, S("0abcdefghij")); + test(S("abcdefghij"), 0, 0, S("1234567890"), 10, 0, S("abcdefghij")); + test(S("abcdefghij"), 0, 0, S("1234567890"), 10, 1, S("abcdefghij")); + test(S("abcdefghij"), 0, 0, S("1234567890"), 11, 0, S("can't happen")); + test(S("abcdefghij"), 0, 0, S("12345678901234567890"), 0, 0, S("abcdefghij")); + test(S("abcdefghij"), 0, 0, S("12345678901234567890"), 0, 1, S("1abcdefghij")); + test(S("abcdefghij"), 0, 0, S("12345678901234567890"), 0, 10, S("1234567890abcdefghij")); + test(S("abcdefghij"), 0, 0, S("12345678901234567890"), 0, 19, S("1234567890123456789abcdefghij")); + test(S("abcdefghij"), 0, 0, S("12345678901234567890"), 0, 20, S("12345678901234567890abcdefghij")); + test(S("abcdefghij"), 0, 0, S("12345678901234567890"), 0, 21, S("12345678901234567890abcdefghij")); + test(S("abcdefghij"), 0, 0, S("12345678901234567890"), 1, 0, S("abcdefghij")); + test(S("abcdefghij"), 0, 0, S("12345678901234567890"), 1, 1, S("2abcdefghij")); + test(S("abcdefghij"), 0, 0, S("12345678901234567890"), 1, 9, S("234567890abcdefghij")); + test(S("abcdefghij"), 0, 0, S("12345678901234567890"), 1, 18, S("234567890123456789abcdefghij")); + test(S("abcdefghij"), 0, 0, S("12345678901234567890"), 1, 19, S("2345678901234567890abcdefghij")); + test(S("abcdefghij"), 0, 0, S("12345678901234567890"), 1, 20, S("2345678901234567890abcdefghij")); + test(S("abcdefghij"), 0, 0, S("12345678901234567890"), 10, 0, S("abcdefghij")); + test(S("abcdefghij"), 0, 0, S("12345678901234567890"), 10, 1, S("1abcdefghij")); + test(S("abcdefghij"), 0, 0, S("12345678901234567890"), 10, 5, S("12345abcdefghij")); + test(S("abcdefghij"), 0, 0, S("12345678901234567890"), 10, 9, S("123456789abcdefghij")); + test(S("abcdefghij"), 0, 0, S("12345678901234567890"), 10, 10, S("1234567890abcdefghij")); + test(S("abcdefghij"), 0, 0, S("12345678901234567890"), 10, 11, S("1234567890abcdefghij")); + test(S("abcdefghij"), 0, 0, S("12345678901234567890"), 19, 0, S("abcdefghij")); + test(S("abcdefghij"), 0, 0, S("12345678901234567890"), 19, 1, S("0abcdefghij")); + test(S("abcdefghij"), 0, 0, S("12345678901234567890"), 19, 2, S("0abcdefghij")); + test(S("abcdefghij"), 0, 0, S("12345678901234567890"), 20, 0, S("abcdefghij")); + test(S("abcdefghij"), 0, 0, S("12345678901234567890"), 20, 1, S("abcdefghij")); + test(S("abcdefghij"), 0, 0, S("12345678901234567890"), 21, 0, S("can't happen")); + test(S("abcdefghij"), 0, 1, S(""), 0, 0, S("bcdefghij")); + test(S("abcdefghij"), 0, 1, S(""), 0, 1, S("bcdefghij")); +} + +template +void test20() +{ + test(S("abcdefghij"), 0, 1, S(""), 1, 0, S("can't happen")); + test(S("abcdefghij"), 0, 1, S("12345"), 0, 0, S("bcdefghij")); + test(S("abcdefghij"), 0, 1, S("12345"), 0, 1, S("1bcdefghij")); + test(S("abcdefghij"), 0, 1, S("12345"), 0, 2, S("12bcdefghij")); + test(S("abcdefghij"), 0, 1, S("12345"), 0, 4, S("1234bcdefghij")); + test(S("abcdefghij"), 0, 1, S("12345"), 0, 5, S("12345bcdefghij")); + test(S("abcdefghij"), 0, 1, S("12345"), 0, 6, S("12345bcdefghij")); + test(S("abcdefghij"), 0, 1, S("12345"), 1, 0, S("bcdefghij")); + test(S("abcdefghij"), 0, 1, S("12345"), 1, 1, S("2bcdefghij")); + test(S("abcdefghij"), 0, 1, S("12345"), 1, 2, S("23bcdefghij")); + test(S("abcdefghij"), 0, 1, S("12345"), 1, 3, S("234bcdefghij")); + test(S("abcdefghij"), 0, 1, S("12345"), 1, 4, S("2345bcdefghij")); + test(S("abcdefghij"), 0, 1, S("12345"), 1, 5, S("2345bcdefghij")); + test(S("abcdefghij"), 0, 1, S("12345"), 2, 0, S("bcdefghij")); + test(S("abcdefghij"), 0, 1, S("12345"), 2, 1, S("3bcdefghij")); + test(S("abcdefghij"), 0, 1, S("12345"), 2, 2, S("34bcdefghij")); + test(S("abcdefghij"), 0, 1, S("12345"), 2, 3, S("345bcdefghij")); + test(S("abcdefghij"), 0, 1, S("12345"), 2, 4, S("345bcdefghij")); + test(S("abcdefghij"), 0, 1, S("12345"), 4, 0, S("bcdefghij")); + test(S("abcdefghij"), 0, 1, S("12345"), 4, 1, S("5bcdefghij")); + test(S("abcdefghij"), 0, 1, S("12345"), 4, 2, S("5bcdefghij")); + test(S("abcdefghij"), 0, 1, S("12345"), 5, 0, S("bcdefghij")); + test(S("abcdefghij"), 0, 1, S("12345"), 5, 1, S("bcdefghij")); + test(S("abcdefghij"), 0, 1, S("12345"), 6, 0, S("can't happen")); + test(S("abcdefghij"), 0, 1, S("1234567890"), 0, 0, S("bcdefghij")); + test(S("abcdefghij"), 0, 1, S("1234567890"), 0, 1, S("1bcdefghij")); + test(S("abcdefghij"), 0, 1, S("1234567890"), 0, 5, S("12345bcdefghij")); + test(S("abcdefghij"), 0, 1, S("1234567890"), 0, 9, S("123456789bcdefghij")); + test(S("abcdefghij"), 0, 1, S("1234567890"), 0, 10, S("1234567890bcdefghij")); + test(S("abcdefghij"), 0, 1, S("1234567890"), 0, 11, S("1234567890bcdefghij")); + test(S("abcdefghij"), 0, 1, S("1234567890"), 1, 0, S("bcdefghij")); + test(S("abcdefghij"), 0, 1, S("1234567890"), 1, 1, S("2bcdefghij")); + test(S("abcdefghij"), 0, 1, S("1234567890"), 1, 4, S("2345bcdefghij")); + test(S("abcdefghij"), 0, 1, S("1234567890"), 1, 8, S("23456789bcdefghij")); + test(S("abcdefghij"), 0, 1, S("1234567890"), 1, 9, S("234567890bcdefghij")); + test(S("abcdefghij"), 0, 1, S("1234567890"), 1, 10, S("234567890bcdefghij")); + test(S("abcdefghij"), 0, 1, S("1234567890"), 5, 0, S("bcdefghij")); + test(S("abcdefghij"), 0, 1, S("1234567890"), 5, 1, S("6bcdefghij")); + test(S("abcdefghij"), 0, 1, S("1234567890"), 5, 2, S("67bcdefghij")); + test(S("abcdefghij"), 0, 1, S("1234567890"), 5, 4, S("6789bcdefghij")); + test(S("abcdefghij"), 0, 1, S("1234567890"), 5, 5, S("67890bcdefghij")); + test(S("abcdefghij"), 0, 1, S("1234567890"), 5, 6, S("67890bcdefghij")); + test(S("abcdefghij"), 0, 1, S("1234567890"), 9, 0, S("bcdefghij")); + test(S("abcdefghij"), 0, 1, S("1234567890"), 9, 1, S("0bcdefghij")); + test(S("abcdefghij"), 0, 1, S("1234567890"), 9, 2, S("0bcdefghij")); + test(S("abcdefghij"), 0, 1, S("1234567890"), 10, 0, S("bcdefghij")); + test(S("abcdefghij"), 0, 1, S("1234567890"), 10, 1, S("bcdefghij")); + test(S("abcdefghij"), 0, 1, S("1234567890"), 11, 0, S("can't happen")); + test(S("abcdefghij"), 0, 1, S("12345678901234567890"), 0, 0, S("bcdefghij")); + test(S("abcdefghij"), 0, 1, S("12345678901234567890"), 0, 1, S("1bcdefghij")); + test(S("abcdefghij"), 0, 1, S("12345678901234567890"), 0, 10, S("1234567890bcdefghij")); + test(S("abcdefghij"), 0, 1, S("12345678901234567890"), 0, 19, S("1234567890123456789bcdefghij")); + test(S("abcdefghij"), 0, 1, S("12345678901234567890"), 0, 20, S("12345678901234567890bcdefghij")); + test(S("abcdefghij"), 0, 1, S("12345678901234567890"), 0, 21, S("12345678901234567890bcdefghij")); + test(S("abcdefghij"), 0, 1, S("12345678901234567890"), 1, 0, S("bcdefghij")); + test(S("abcdefghij"), 0, 1, S("12345678901234567890"), 1, 1, S("2bcdefghij")); + test(S("abcdefghij"), 0, 1, S("12345678901234567890"), 1, 9, S("234567890bcdefghij")); + test(S("abcdefghij"), 0, 1, S("12345678901234567890"), 1, 18, S("234567890123456789bcdefghij")); + test(S("abcdefghij"), 0, 1, S("12345678901234567890"), 1, 19, S("2345678901234567890bcdefghij")); + test(S("abcdefghij"), 0, 1, S("12345678901234567890"), 1, 20, S("2345678901234567890bcdefghij")); + test(S("abcdefghij"), 0, 1, S("12345678901234567890"), 10, 0, S("bcdefghij")); + test(S("abcdefghij"), 0, 1, S("12345678901234567890"), 10, 1, S("1bcdefghij")); + test(S("abcdefghij"), 0, 1, S("12345678901234567890"), 10, 5, S("12345bcdefghij")); + test(S("abcdefghij"), 0, 1, S("12345678901234567890"), 10, 9, S("123456789bcdefghij")); + test(S("abcdefghij"), 0, 1, S("12345678901234567890"), 10, 10, S("1234567890bcdefghij")); + test(S("abcdefghij"), 0, 1, S("12345678901234567890"), 10, 11, S("1234567890bcdefghij")); + test(S("abcdefghij"), 0, 1, S("12345678901234567890"), 19, 0, S("bcdefghij")); + test(S("abcdefghij"), 0, 1, S("12345678901234567890"), 19, 1, S("0bcdefghij")); + test(S("abcdefghij"), 0, 1, S("12345678901234567890"), 19, 2, S("0bcdefghij")); + test(S("abcdefghij"), 0, 1, S("12345678901234567890"), 20, 0, S("bcdefghij")); + test(S("abcdefghij"), 0, 1, S("12345678901234567890"), 20, 1, S("bcdefghij")); + test(S("abcdefghij"), 0, 1, S("12345678901234567890"), 21, 0, S("can't happen")); + test(S("abcdefghij"), 0, 5, S(""), 0, 0, S("fghij")); + test(S("abcdefghij"), 0, 5, S(""), 0, 1, S("fghij")); + test(S("abcdefghij"), 0, 5, S(""), 1, 0, S("can't happen")); + test(S("abcdefghij"), 0, 5, S("12345"), 0, 0, S("fghij")); + test(S("abcdefghij"), 0, 5, S("12345"), 0, 1, S("1fghij")); + test(S("abcdefghij"), 0, 5, S("12345"), 0, 2, S("12fghij")); + test(S("abcdefghij"), 0, 5, S("12345"), 0, 4, S("1234fghij")); + test(S("abcdefghij"), 0, 5, S("12345"), 0, 5, S("12345fghij")); + test(S("abcdefghij"), 0, 5, S("12345"), 0, 6, S("12345fghij")); + test(S("abcdefghij"), 0, 5, S("12345"), 1, 0, S("fghij")); + test(S("abcdefghij"), 0, 5, S("12345"), 1, 1, S("2fghij")); + test(S("abcdefghij"), 0, 5, S("12345"), 1, 2, S("23fghij")); + test(S("abcdefghij"), 0, 5, S("12345"), 1, 3, S("234fghij")); + test(S("abcdefghij"), 0, 5, S("12345"), 1, 4, S("2345fghij")); + test(S("abcdefghij"), 0, 5, S("12345"), 1, 5, S("2345fghij")); + test(S("abcdefghij"), 0, 5, S("12345"), 2, 0, S("fghij")); + test(S("abcdefghij"), 0, 5, S("12345"), 2, 1, S("3fghij")); + test(S("abcdefghij"), 0, 5, S("12345"), 2, 2, S("34fghij")); + test(S("abcdefghij"), 0, 5, S("12345"), 2, 3, S("345fghij")); + test(S("abcdefghij"), 0, 5, S("12345"), 2, 4, S("345fghij")); + test(S("abcdefghij"), 0, 5, S("12345"), 4, 0, S("fghij")); + test(S("abcdefghij"), 0, 5, S("12345"), 4, 1, S("5fghij")); + test(S("abcdefghij"), 0, 5, S("12345"), 4, 2, S("5fghij")); + test(S("abcdefghij"), 0, 5, S("12345"), 5, 0, S("fghij")); + test(S("abcdefghij"), 0, 5, S("12345"), 5, 1, S("fghij")); + test(S("abcdefghij"), 0, 5, S("12345"), 6, 0, S("can't happen")); + test(S("abcdefghij"), 0, 5, S("1234567890"), 0, 0, S("fghij")); + test(S("abcdefghij"), 0, 5, S("1234567890"), 0, 1, S("1fghij")); +} + +template +void test21() +{ + test(S("abcdefghij"), 0, 5, S("1234567890"), 0, 5, S("12345fghij")); + test(S("abcdefghij"), 0, 5, S("1234567890"), 0, 9, S("123456789fghij")); + test(S("abcdefghij"), 0, 5, S("1234567890"), 0, 10, S("1234567890fghij")); + test(S("abcdefghij"), 0, 5, S("1234567890"), 0, 11, S("1234567890fghij")); + test(S("abcdefghij"), 0, 5, S("1234567890"), 1, 0, S("fghij")); + test(S("abcdefghij"), 0, 5, S("1234567890"), 1, 1, S("2fghij")); + test(S("abcdefghij"), 0, 5, S("1234567890"), 1, 4, S("2345fghij")); + test(S("abcdefghij"), 0, 5, S("1234567890"), 1, 8, S("23456789fghij")); + test(S("abcdefghij"), 0, 5, S("1234567890"), 1, 9, S("234567890fghij")); + test(S("abcdefghij"), 0, 5, S("1234567890"), 1, 10, S("234567890fghij")); + test(S("abcdefghij"), 0, 5, S("1234567890"), 5, 0, S("fghij")); + test(S("abcdefghij"), 0, 5, S("1234567890"), 5, 1, S("6fghij")); + test(S("abcdefghij"), 0, 5, S("1234567890"), 5, 2, S("67fghij")); + test(S("abcdefghij"), 0, 5, S("1234567890"), 5, 4, S("6789fghij")); + test(S("abcdefghij"), 0, 5, S("1234567890"), 5, 5, S("67890fghij")); + test(S("abcdefghij"), 0, 5, S("1234567890"), 5, 6, S("67890fghij")); + test(S("abcdefghij"), 0, 5, S("1234567890"), 9, 0, S("fghij")); + test(S("abcdefghij"), 0, 5, S("1234567890"), 9, 1, S("0fghij")); + test(S("abcdefghij"), 0, 5, S("1234567890"), 9, 2, S("0fghij")); + test(S("abcdefghij"), 0, 5, S("1234567890"), 10, 0, S("fghij")); + test(S("abcdefghij"), 0, 5, S("1234567890"), 10, 1, S("fghij")); + test(S("abcdefghij"), 0, 5, S("1234567890"), 11, 0, S("can't happen")); + test(S("abcdefghij"), 0, 5, S("12345678901234567890"), 0, 0, S("fghij")); + test(S("abcdefghij"), 0, 5, S("12345678901234567890"), 0, 1, S("1fghij")); + test(S("abcdefghij"), 0, 5, S("12345678901234567890"), 0, 10, S("1234567890fghij")); + test(S("abcdefghij"), 0, 5, S("12345678901234567890"), 0, 19, S("1234567890123456789fghij")); + test(S("abcdefghij"), 0, 5, S("12345678901234567890"), 0, 20, S("12345678901234567890fghij")); + test(S("abcdefghij"), 0, 5, S("12345678901234567890"), 0, 21, S("12345678901234567890fghij")); + test(S("abcdefghij"), 0, 5, S("12345678901234567890"), 1, 0, S("fghij")); + test(S("abcdefghij"), 0, 5, S("12345678901234567890"), 1, 1, S("2fghij")); + test(S("abcdefghij"), 0, 5, S("12345678901234567890"), 1, 9, S("234567890fghij")); + test(S("abcdefghij"), 0, 5, S("12345678901234567890"), 1, 18, S("234567890123456789fghij")); + test(S("abcdefghij"), 0, 5, S("12345678901234567890"), 1, 19, S("2345678901234567890fghij")); + test(S("abcdefghij"), 0, 5, S("12345678901234567890"), 1, 20, S("2345678901234567890fghij")); + test(S("abcdefghij"), 0, 5, S("12345678901234567890"), 10, 0, S("fghij")); + test(S("abcdefghij"), 0, 5, S("12345678901234567890"), 10, 1, S("1fghij")); + test(S("abcdefghij"), 0, 5, S("12345678901234567890"), 10, 5, S("12345fghij")); + test(S("abcdefghij"), 0, 5, S("12345678901234567890"), 10, 9, S("123456789fghij")); + test(S("abcdefghij"), 0, 5, S("12345678901234567890"), 10, 10, S("1234567890fghij")); + test(S("abcdefghij"), 0, 5, S("12345678901234567890"), 10, 11, S("1234567890fghij")); + test(S("abcdefghij"), 0, 5, S("12345678901234567890"), 19, 0, S("fghij")); + test(S("abcdefghij"), 0, 5, S("12345678901234567890"), 19, 1, S("0fghij")); + test(S("abcdefghij"), 0, 5, S("12345678901234567890"), 19, 2, S("0fghij")); + test(S("abcdefghij"), 0, 5, S("12345678901234567890"), 20, 0, S("fghij")); + test(S("abcdefghij"), 0, 5, S("12345678901234567890"), 20, 1, S("fghij")); + test(S("abcdefghij"), 0, 5, S("12345678901234567890"), 21, 0, S("can't happen")); + test(S("abcdefghij"), 0, 9, S(""), 0, 0, S("j")); + test(S("abcdefghij"), 0, 9, S(""), 0, 1, S("j")); + test(S("abcdefghij"), 0, 9, S(""), 1, 0, S("can't happen")); + test(S("abcdefghij"), 0, 9, S("12345"), 0, 0, S("j")); + test(S("abcdefghij"), 0, 9, S("12345"), 0, 1, S("1j")); + test(S("abcdefghij"), 0, 9, S("12345"), 0, 2, S("12j")); + test(S("abcdefghij"), 0, 9, S("12345"), 0, 4, S("1234j")); + test(S("abcdefghij"), 0, 9, S("12345"), 0, 5, S("12345j")); + test(S("abcdefghij"), 0, 9, S("12345"), 0, 6, S("12345j")); + test(S("abcdefghij"), 0, 9, S("12345"), 1, 0, S("j")); + test(S("abcdefghij"), 0, 9, S("12345"), 1, 1, S("2j")); + test(S("abcdefghij"), 0, 9, S("12345"), 1, 2, S("23j")); + test(S("abcdefghij"), 0, 9, S("12345"), 1, 3, S("234j")); + test(S("abcdefghij"), 0, 9, S("12345"), 1, 4, S("2345j")); + test(S("abcdefghij"), 0, 9, S("12345"), 1, 5, S("2345j")); + test(S("abcdefghij"), 0, 9, S("12345"), 2, 0, S("j")); + test(S("abcdefghij"), 0, 9, S("12345"), 2, 1, S("3j")); + test(S("abcdefghij"), 0, 9, S("12345"), 2, 2, S("34j")); + test(S("abcdefghij"), 0, 9, S("12345"), 2, 3, S("345j")); + test(S("abcdefghij"), 0, 9, S("12345"), 2, 4, S("345j")); + test(S("abcdefghij"), 0, 9, S("12345"), 4, 0, S("j")); + test(S("abcdefghij"), 0, 9, S("12345"), 4, 1, S("5j")); + test(S("abcdefghij"), 0, 9, S("12345"), 4, 2, S("5j")); + test(S("abcdefghij"), 0, 9, S("12345"), 5, 0, S("j")); + test(S("abcdefghij"), 0, 9, S("12345"), 5, 1, S("j")); + test(S("abcdefghij"), 0, 9, S("12345"), 6, 0, S("can't happen")); + test(S("abcdefghij"), 0, 9, S("1234567890"), 0, 0, S("j")); + test(S("abcdefghij"), 0, 9, S("1234567890"), 0, 1, S("1j")); + test(S("abcdefghij"), 0, 9, S("1234567890"), 0, 5, S("12345j")); + test(S("abcdefghij"), 0, 9, S("1234567890"), 0, 9, S("123456789j")); + test(S("abcdefghij"), 0, 9, S("1234567890"), 0, 10, S("1234567890j")); + test(S("abcdefghij"), 0, 9, S("1234567890"), 0, 11, S("1234567890j")); + test(S("abcdefghij"), 0, 9, S("1234567890"), 1, 0, S("j")); + test(S("abcdefghij"), 0, 9, S("1234567890"), 1, 1, S("2j")); + test(S("abcdefghij"), 0, 9, S("1234567890"), 1, 4, S("2345j")); + test(S("abcdefghij"), 0, 9, S("1234567890"), 1, 8, S("23456789j")); + test(S("abcdefghij"), 0, 9, S("1234567890"), 1, 9, S("234567890j")); + test(S("abcdefghij"), 0, 9, S("1234567890"), 1, 10, S("234567890j")); + test(S("abcdefghij"), 0, 9, S("1234567890"), 5, 0, S("j")); + test(S("abcdefghij"), 0, 9, S("1234567890"), 5, 1, S("6j")); + test(S("abcdefghij"), 0, 9, S("1234567890"), 5, 2, S("67j")); + test(S("abcdefghij"), 0, 9, S("1234567890"), 5, 4, S("6789j")); + test(S("abcdefghij"), 0, 9, S("1234567890"), 5, 5, S("67890j")); + test(S("abcdefghij"), 0, 9, S("1234567890"), 5, 6, S("67890j")); + test(S("abcdefghij"), 0, 9, S("1234567890"), 9, 0, S("j")); + test(S("abcdefghij"), 0, 9, S("1234567890"), 9, 1, S("0j")); + test(S("abcdefghij"), 0, 9, S("1234567890"), 9, 2, S("0j")); + test(S("abcdefghij"), 0, 9, S("1234567890"), 10, 0, S("j")); + test(S("abcdefghij"), 0, 9, S("1234567890"), 10, 1, S("j")); + test(S("abcdefghij"), 0, 9, S("1234567890"), 11, 0, S("can't happen")); + test(S("abcdefghij"), 0, 9, S("12345678901234567890"), 0, 0, S("j")); + test(S("abcdefghij"), 0, 9, S("12345678901234567890"), 0, 1, S("1j")); + test(S("abcdefghij"), 0, 9, S("12345678901234567890"), 0, 10, S("1234567890j")); + test(S("abcdefghij"), 0, 9, S("12345678901234567890"), 0, 19, S("1234567890123456789j")); +} + +template +void test22() +{ + test(S("abcdefghij"), 0, 9, S("12345678901234567890"), 0, 20, S("12345678901234567890j")); + test(S("abcdefghij"), 0, 9, S("12345678901234567890"), 0, 21, S("12345678901234567890j")); + test(S("abcdefghij"), 0, 9, S("12345678901234567890"), 1, 0, S("j")); + test(S("abcdefghij"), 0, 9, S("12345678901234567890"), 1, 1, S("2j")); + test(S("abcdefghij"), 0, 9, S("12345678901234567890"), 1, 9, S("234567890j")); + test(S("abcdefghij"), 0, 9, S("12345678901234567890"), 1, 18, S("234567890123456789j")); + test(S("abcdefghij"), 0, 9, S("12345678901234567890"), 1, 19, S("2345678901234567890j")); + test(S("abcdefghij"), 0, 9, S("12345678901234567890"), 1, 20, S("2345678901234567890j")); + test(S("abcdefghij"), 0, 9, S("12345678901234567890"), 10, 0, S("j")); + test(S("abcdefghij"), 0, 9, S("12345678901234567890"), 10, 1, S("1j")); + test(S("abcdefghij"), 0, 9, S("12345678901234567890"), 10, 5, S("12345j")); + test(S("abcdefghij"), 0, 9, S("12345678901234567890"), 10, 9, S("123456789j")); + test(S("abcdefghij"), 0, 9, S("12345678901234567890"), 10, 10, S("1234567890j")); + test(S("abcdefghij"), 0, 9, S("12345678901234567890"), 10, 11, S("1234567890j")); + test(S("abcdefghij"), 0, 9, S("12345678901234567890"), 19, 0, S("j")); + test(S("abcdefghij"), 0, 9, S("12345678901234567890"), 19, 1, S("0j")); + test(S("abcdefghij"), 0, 9, S("12345678901234567890"), 19, 2, S("0j")); + test(S("abcdefghij"), 0, 9, S("12345678901234567890"), 20, 0, S("j")); + test(S("abcdefghij"), 0, 9, S("12345678901234567890"), 20, 1, S("j")); + test(S("abcdefghij"), 0, 9, S("12345678901234567890"), 21, 0, S("can't happen")); + test(S("abcdefghij"), 0, 10, S(""), 0, 0, S("")); + test(S("abcdefghij"), 0, 10, S(""), 0, 1, S("")); + test(S("abcdefghij"), 0, 10, S(""), 1, 0, S("can't happen")); + test(S("abcdefghij"), 0, 10, S("12345"), 0, 0, S("")); + test(S("abcdefghij"), 0, 10, S("12345"), 0, 1, S("1")); + test(S("abcdefghij"), 0, 10, S("12345"), 0, 2, S("12")); + test(S("abcdefghij"), 0, 10, S("12345"), 0, 4, S("1234")); + test(S("abcdefghij"), 0, 10, S("12345"), 0, 5, S("12345")); + test(S("abcdefghij"), 0, 10, S("12345"), 0, 6, S("12345")); + test(S("abcdefghij"), 0, 10, S("12345"), 1, 0, S("")); + test(S("abcdefghij"), 0, 10, S("12345"), 1, 1, S("2")); + test(S("abcdefghij"), 0, 10, S("12345"), 1, 2, S("23")); + test(S("abcdefghij"), 0, 10, S("12345"), 1, 3, S("234")); + test(S("abcdefghij"), 0, 10, S("12345"), 1, 4, S("2345")); + test(S("abcdefghij"), 0, 10, S("12345"), 1, 5, S("2345")); + test(S("abcdefghij"), 0, 10, S("12345"), 2, 0, S("")); + test(S("abcdefghij"), 0, 10, S("12345"), 2, 1, S("3")); + test(S("abcdefghij"), 0, 10, S("12345"), 2, 2, S("34")); + test(S("abcdefghij"), 0, 10, S("12345"), 2, 3, S("345")); + test(S("abcdefghij"), 0, 10, S("12345"), 2, 4, S("345")); + test(S("abcdefghij"), 0, 10, S("12345"), 4, 0, S("")); + test(S("abcdefghij"), 0, 10, S("12345"), 4, 1, S("5")); + test(S("abcdefghij"), 0, 10, S("12345"), 4, 2, S("5")); + test(S("abcdefghij"), 0, 10, S("12345"), 5, 0, S("")); + test(S("abcdefghij"), 0, 10, S("12345"), 5, 1, S("")); + test(S("abcdefghij"), 0, 10, S("12345"), 6, 0, S("can't happen")); + test(S("abcdefghij"), 0, 10, S("1234567890"), 0, 0, S("")); + test(S("abcdefghij"), 0, 10, S("1234567890"), 0, 1, S("1")); + test(S("abcdefghij"), 0, 10, S("1234567890"), 0, 5, S("12345")); + test(S("abcdefghij"), 0, 10, S("1234567890"), 0, 9, S("123456789")); + test(S("abcdefghij"), 0, 10, S("1234567890"), 0, 10, S("1234567890")); + test(S("abcdefghij"), 0, 10, S("1234567890"), 0, 11, S("1234567890")); + test(S("abcdefghij"), 0, 10, S("1234567890"), 1, 0, S("")); + test(S("abcdefghij"), 0, 10, S("1234567890"), 1, 1, S("2")); + test(S("abcdefghij"), 0, 10, S("1234567890"), 1, 4, S("2345")); + test(S("abcdefghij"), 0, 10, S("1234567890"), 1, 8, S("23456789")); + test(S("abcdefghij"), 0, 10, S("1234567890"), 1, 9, S("234567890")); + test(S("abcdefghij"), 0, 10, S("1234567890"), 1, 10, S("234567890")); + test(S("abcdefghij"), 0, 10, S("1234567890"), 5, 0, S("")); + test(S("abcdefghij"), 0, 10, S("1234567890"), 5, 1, S("6")); + test(S("abcdefghij"), 0, 10, S("1234567890"), 5, 2, S("67")); + test(S("abcdefghij"), 0, 10, S("1234567890"), 5, 4, S("6789")); + test(S("abcdefghij"), 0, 10, S("1234567890"), 5, 5, S("67890")); + test(S("abcdefghij"), 0, 10, S("1234567890"), 5, 6, S("67890")); + test(S("abcdefghij"), 0, 10, S("1234567890"), 9, 0, S("")); + test(S("abcdefghij"), 0, 10, S("1234567890"), 9, 1, S("0")); + test(S("abcdefghij"), 0, 10, S("1234567890"), 9, 2, S("0")); + test(S("abcdefghij"), 0, 10, S("1234567890"), 10, 0, S("")); + test(S("abcdefghij"), 0, 10, S("1234567890"), 10, 1, S("")); + test(S("abcdefghij"), 0, 10, S("1234567890"), 11, 0, S("can't happen")); + test(S("abcdefghij"), 0, 10, S("12345678901234567890"), 0, 0, S("")); + test(S("abcdefghij"), 0, 10, S("12345678901234567890"), 0, 1, S("1")); + test(S("abcdefghij"), 0, 10, S("12345678901234567890"), 0, 10, S("1234567890")); + test(S("abcdefghij"), 0, 10, S("12345678901234567890"), 0, 19, S("1234567890123456789")); + test(S("abcdefghij"), 0, 10, S("12345678901234567890"), 0, 20, S("12345678901234567890")); + test(S("abcdefghij"), 0, 10, S("12345678901234567890"), 0, 21, S("12345678901234567890")); + test(S("abcdefghij"), 0, 10, S("12345678901234567890"), 1, 0, S("")); + test(S("abcdefghij"), 0, 10, S("12345678901234567890"), 1, 1, S("2")); + test(S("abcdefghij"), 0, 10, S("12345678901234567890"), 1, 9, S("234567890")); + test(S("abcdefghij"), 0, 10, S("12345678901234567890"), 1, 18, S("234567890123456789")); + test(S("abcdefghij"), 0, 10, S("12345678901234567890"), 1, 19, S("2345678901234567890")); + test(S("abcdefghij"), 0, 10, S("12345678901234567890"), 1, 20, S("2345678901234567890")); + test(S("abcdefghij"), 0, 10, S("12345678901234567890"), 10, 0, S("")); + test(S("abcdefghij"), 0, 10, S("12345678901234567890"), 10, 1, S("1")); + test(S("abcdefghij"), 0, 10, S("12345678901234567890"), 10, 5, S("12345")); + test(S("abcdefghij"), 0, 10, S("12345678901234567890"), 10, 9, S("123456789")); + test(S("abcdefghij"), 0, 10, S("12345678901234567890"), 10, 10, S("1234567890")); + test(S("abcdefghij"), 0, 10, S("12345678901234567890"), 10, 11, S("1234567890")); + test(S("abcdefghij"), 0, 10, S("12345678901234567890"), 19, 0, S("")); + test(S("abcdefghij"), 0, 10, S("12345678901234567890"), 19, 1, S("0")); + test(S("abcdefghij"), 0, 10, S("12345678901234567890"), 19, 2, S("0")); + test(S("abcdefghij"), 0, 10, S("12345678901234567890"), 20, 0, S("")); + test(S("abcdefghij"), 0, 10, S("12345678901234567890"), 20, 1, S("")); + test(S("abcdefghij"), 0, 10, S("12345678901234567890"), 21, 0, S("can't happen")); + test(S("abcdefghij"), 0, 11, S(""), 0, 0, S("")); + test(S("abcdefghij"), 0, 11, S(""), 0, 1, S("")); + test(S("abcdefghij"), 0, 11, S(""), 1, 0, S("can't happen")); + test(S("abcdefghij"), 0, 11, S("12345"), 0, 0, S("")); + test(S("abcdefghij"), 0, 11, S("12345"), 0, 1, S("1")); + test(S("abcdefghij"), 0, 11, S("12345"), 0, 2, S("12")); +} + +template +void test23() +{ + test(S("abcdefghij"), 0, 11, S("12345"), 0, 4, S("1234")); + test(S("abcdefghij"), 0, 11, S("12345"), 0, 5, S("12345")); + test(S("abcdefghij"), 0, 11, S("12345"), 0, 6, S("12345")); + test(S("abcdefghij"), 0, 11, S("12345"), 1, 0, S("")); + test(S("abcdefghij"), 0, 11, S("12345"), 1, 1, S("2")); + test(S("abcdefghij"), 0, 11, S("12345"), 1, 2, S("23")); + test(S("abcdefghij"), 0, 11, S("12345"), 1, 3, S("234")); + test(S("abcdefghij"), 0, 11, S("12345"), 1, 4, S("2345")); + test(S("abcdefghij"), 0, 11, S("12345"), 1, 5, S("2345")); + test(S("abcdefghij"), 0, 11, S("12345"), 2, 0, S("")); + test(S("abcdefghij"), 0, 11, S("12345"), 2, 1, S("3")); + test(S("abcdefghij"), 0, 11, S("12345"), 2, 2, S("34")); + test(S("abcdefghij"), 0, 11, S("12345"), 2, 3, S("345")); + test(S("abcdefghij"), 0, 11, S("12345"), 2, 4, S("345")); + test(S("abcdefghij"), 0, 11, S("12345"), 4, 0, S("")); + test(S("abcdefghij"), 0, 11, S("12345"), 4, 1, S("5")); + test(S("abcdefghij"), 0, 11, S("12345"), 4, 2, S("5")); + test(S("abcdefghij"), 0, 11, S("12345"), 5, 0, S("")); + test(S("abcdefghij"), 0, 11, S("12345"), 5, 1, S("")); + test(S("abcdefghij"), 0, 11, S("12345"), 6, 0, S("can't happen")); + test(S("abcdefghij"), 0, 11, S("1234567890"), 0, 0, S("")); + test(S("abcdefghij"), 0, 11, S("1234567890"), 0, 1, S("1")); + test(S("abcdefghij"), 0, 11, S("1234567890"), 0, 5, S("12345")); + test(S("abcdefghij"), 0, 11, S("1234567890"), 0, 9, S("123456789")); + test(S("abcdefghij"), 0, 11, S("1234567890"), 0, 10, S("1234567890")); + test(S("abcdefghij"), 0, 11, S("1234567890"), 0, 11, S("1234567890")); + test(S("abcdefghij"), 0, 11, S("1234567890"), 1, 0, S("")); + test(S("abcdefghij"), 0, 11, S("1234567890"), 1, 1, S("2")); + test(S("abcdefghij"), 0, 11, S("1234567890"), 1, 4, S("2345")); + test(S("abcdefghij"), 0, 11, S("1234567890"), 1, 8, S("23456789")); + test(S("abcdefghij"), 0, 11, S("1234567890"), 1, 9, S("234567890")); + test(S("abcdefghij"), 0, 11, S("1234567890"), 1, 10, S("234567890")); + test(S("abcdefghij"), 0, 11, S("1234567890"), 5, 0, S("")); + test(S("abcdefghij"), 0, 11, S("1234567890"), 5, 1, S("6")); + test(S("abcdefghij"), 0, 11, S("1234567890"), 5, 2, S("67")); + test(S("abcdefghij"), 0, 11, S("1234567890"), 5, 4, S("6789")); + test(S("abcdefghij"), 0, 11, S("1234567890"), 5, 5, S("67890")); + test(S("abcdefghij"), 0, 11, S("1234567890"), 5, 6, S("67890")); + test(S("abcdefghij"), 0, 11, S("1234567890"), 9, 0, S("")); + test(S("abcdefghij"), 0, 11, S("1234567890"), 9, 1, S("0")); + test(S("abcdefghij"), 0, 11, S("1234567890"), 9, 2, S("0")); + test(S("abcdefghij"), 0, 11, S("1234567890"), 10, 0, S("")); + test(S("abcdefghij"), 0, 11, S("1234567890"), 10, 1, S("")); + test(S("abcdefghij"), 0, 11, S("1234567890"), 11, 0, S("can't happen")); + test(S("abcdefghij"), 0, 11, S("12345678901234567890"), 0, 0, S("")); + test(S("abcdefghij"), 0, 11, S("12345678901234567890"), 0, 1, S("1")); + test(S("abcdefghij"), 0, 11, S("12345678901234567890"), 0, 10, S("1234567890")); + test(S("abcdefghij"), 0, 11, S("12345678901234567890"), 0, 19, S("1234567890123456789")); + test(S("abcdefghij"), 0, 11, S("12345678901234567890"), 0, 20, S("12345678901234567890")); + test(S("abcdefghij"), 0, 11, S("12345678901234567890"), 0, 21, S("12345678901234567890")); + test(S("abcdefghij"), 0, 11, S("12345678901234567890"), 1, 0, S("")); + test(S("abcdefghij"), 0, 11, S("12345678901234567890"), 1, 1, S("2")); + test(S("abcdefghij"), 0, 11, S("12345678901234567890"), 1, 9, S("234567890")); + test(S("abcdefghij"), 0, 11, S("12345678901234567890"), 1, 18, S("234567890123456789")); + test(S("abcdefghij"), 0, 11, S("12345678901234567890"), 1, 19, S("2345678901234567890")); + test(S("abcdefghij"), 0, 11, S("12345678901234567890"), 1, 20, S("2345678901234567890")); + test(S("abcdefghij"), 0, 11, S("12345678901234567890"), 10, 0, S("")); + test(S("abcdefghij"), 0, 11, S("12345678901234567890"), 10, 1, S("1")); + test(S("abcdefghij"), 0, 11, S("12345678901234567890"), 10, 5, S("12345")); + test(S("abcdefghij"), 0, 11, S("12345678901234567890"), 10, 9, S("123456789")); + test(S("abcdefghij"), 0, 11, S("12345678901234567890"), 10, 10, S("1234567890")); + test(S("abcdefghij"), 0, 11, S("12345678901234567890"), 10, 11, S("1234567890")); + test(S("abcdefghij"), 0, 11, S("12345678901234567890"), 19, 0, S("")); + test(S("abcdefghij"), 0, 11, S("12345678901234567890"), 19, 1, S("0")); + test(S("abcdefghij"), 0, 11, S("12345678901234567890"), 19, 2, S("0")); + test(S("abcdefghij"), 0, 11, S("12345678901234567890"), 20, 0, S("")); + test(S("abcdefghij"), 0, 11, S("12345678901234567890"), 20, 1, S("")); + test(S("abcdefghij"), 0, 11, S("12345678901234567890"), 21, 0, S("can't happen")); + test(S("abcdefghij"), 1, 0, S(""), 0, 0, S("abcdefghij")); + test(S("abcdefghij"), 1, 0, S(""), 0, 1, S("abcdefghij")); + test(S("abcdefghij"), 1, 0, S(""), 1, 0, S("can't happen")); + test(S("abcdefghij"), 1, 0, S("12345"), 0, 0, S("abcdefghij")); + test(S("abcdefghij"), 1, 0, S("12345"), 0, 1, S("a1bcdefghij")); + test(S("abcdefghij"), 1, 0, S("12345"), 0, 2, S("a12bcdefghij")); + test(S("abcdefghij"), 1, 0, S("12345"), 0, 4, S("a1234bcdefghij")); + test(S("abcdefghij"), 1, 0, S("12345"), 0, 5, S("a12345bcdefghij")); + test(S("abcdefghij"), 1, 0, S("12345"), 0, 6, S("a12345bcdefghij")); + test(S("abcdefghij"), 1, 0, S("12345"), 1, 0, S("abcdefghij")); + test(S("abcdefghij"), 1, 0, S("12345"), 1, 1, S("a2bcdefghij")); + test(S("abcdefghij"), 1, 0, S("12345"), 1, 2, S("a23bcdefghij")); + test(S("abcdefghij"), 1, 0, S("12345"), 1, 3, S("a234bcdefghij")); + test(S("abcdefghij"), 1, 0, S("12345"), 1, 4, S("a2345bcdefghij")); + test(S("abcdefghij"), 1, 0, S("12345"), 1, 5, S("a2345bcdefghij")); + test(S("abcdefghij"), 1, 0, S("12345"), 2, 0, S("abcdefghij")); + test(S("abcdefghij"), 1, 0, S("12345"), 2, 1, S("a3bcdefghij")); + test(S("abcdefghij"), 1, 0, S("12345"), 2, 2, S("a34bcdefghij")); + test(S("abcdefghij"), 1, 0, S("12345"), 2, 3, S("a345bcdefghij")); + test(S("abcdefghij"), 1, 0, S("12345"), 2, 4, S("a345bcdefghij")); + test(S("abcdefghij"), 1, 0, S("12345"), 4, 0, S("abcdefghij")); + test(S("abcdefghij"), 1, 0, S("12345"), 4, 1, S("a5bcdefghij")); + test(S("abcdefghij"), 1, 0, S("12345"), 4, 2, S("a5bcdefghij")); + test(S("abcdefghij"), 1, 0, S("12345"), 5, 0, S("abcdefghij")); + test(S("abcdefghij"), 1, 0, S("12345"), 5, 1, S("abcdefghij")); + test(S("abcdefghij"), 1, 0, S("12345"), 6, 0, S("can't happen")); + test(S("abcdefghij"), 1, 0, S("1234567890"), 0, 0, S("abcdefghij")); + test(S("abcdefghij"), 1, 0, S("1234567890"), 0, 1, S("a1bcdefghij")); + test(S("abcdefghij"), 1, 0, S("1234567890"), 0, 5, S("a12345bcdefghij")); + test(S("abcdefghij"), 1, 0, S("1234567890"), 0, 9, S("a123456789bcdefghij")); + test(S("abcdefghij"), 1, 0, S("1234567890"), 0, 10, S("a1234567890bcdefghij")); + test(S("abcdefghij"), 1, 0, S("1234567890"), 0, 11, S("a1234567890bcdefghij")); +} + +template +void test24() +{ + test(S("abcdefghij"), 1, 0, S("1234567890"), 1, 0, S("abcdefghij")); + test(S("abcdefghij"), 1, 0, S("1234567890"), 1, 1, S("a2bcdefghij")); + test(S("abcdefghij"), 1, 0, S("1234567890"), 1, 4, S("a2345bcdefghij")); + test(S("abcdefghij"), 1, 0, S("1234567890"), 1, 8, S("a23456789bcdefghij")); + test(S("abcdefghij"), 1, 0, S("1234567890"), 1, 9, S("a234567890bcdefghij")); + test(S("abcdefghij"), 1, 0, S("1234567890"), 1, 10, S("a234567890bcdefghij")); + test(S("abcdefghij"), 1, 0, S("1234567890"), 5, 0, S("abcdefghij")); + test(S("abcdefghij"), 1, 0, S("1234567890"), 5, 1, S("a6bcdefghij")); + test(S("abcdefghij"), 1, 0, S("1234567890"), 5, 2, S("a67bcdefghij")); + test(S("abcdefghij"), 1, 0, S("1234567890"), 5, 4, S("a6789bcdefghij")); + test(S("abcdefghij"), 1, 0, S("1234567890"), 5, 5, S("a67890bcdefghij")); + test(S("abcdefghij"), 1, 0, S("1234567890"), 5, 6, S("a67890bcdefghij")); + test(S("abcdefghij"), 1, 0, S("1234567890"), 9, 0, S("abcdefghij")); + test(S("abcdefghij"), 1, 0, S("1234567890"), 9, 1, S("a0bcdefghij")); + test(S("abcdefghij"), 1, 0, S("1234567890"), 9, 2, S("a0bcdefghij")); + test(S("abcdefghij"), 1, 0, S("1234567890"), 10, 0, S("abcdefghij")); + test(S("abcdefghij"), 1, 0, S("1234567890"), 10, 1, S("abcdefghij")); + test(S("abcdefghij"), 1, 0, S("1234567890"), 11, 0, S("can't happen")); + test(S("abcdefghij"), 1, 0, S("12345678901234567890"), 0, 0, S("abcdefghij")); + test(S("abcdefghij"), 1, 0, S("12345678901234567890"), 0, 1, S("a1bcdefghij")); + test(S("abcdefghij"), 1, 0, S("12345678901234567890"), 0, 10, S("a1234567890bcdefghij")); + test(S("abcdefghij"), 1, 0, S("12345678901234567890"), 0, 19, S("a1234567890123456789bcdefghij")); + test(S("abcdefghij"), 1, 0, S("12345678901234567890"), 0, 20, S("a12345678901234567890bcdefghij")); + test(S("abcdefghij"), 1, 0, S("12345678901234567890"), 0, 21, S("a12345678901234567890bcdefghij")); + test(S("abcdefghij"), 1, 0, S("12345678901234567890"), 1, 0, S("abcdefghij")); + test(S("abcdefghij"), 1, 0, S("12345678901234567890"), 1, 1, S("a2bcdefghij")); + test(S("abcdefghij"), 1, 0, S("12345678901234567890"), 1, 9, S("a234567890bcdefghij")); + test(S("abcdefghij"), 1, 0, S("12345678901234567890"), 1, 18, S("a234567890123456789bcdefghij")); + test(S("abcdefghij"), 1, 0, S("12345678901234567890"), 1, 19, S("a2345678901234567890bcdefghij")); + test(S("abcdefghij"), 1, 0, S("12345678901234567890"), 1, 20, S("a2345678901234567890bcdefghij")); + test(S("abcdefghij"), 1, 0, S("12345678901234567890"), 10, 0, S("abcdefghij")); + test(S("abcdefghij"), 1, 0, S("12345678901234567890"), 10, 1, S("a1bcdefghij")); + test(S("abcdefghij"), 1, 0, S("12345678901234567890"), 10, 5, S("a12345bcdefghij")); + test(S("abcdefghij"), 1, 0, S("12345678901234567890"), 10, 9, S("a123456789bcdefghij")); + test(S("abcdefghij"), 1, 0, S("12345678901234567890"), 10, 10, S("a1234567890bcdefghij")); + test(S("abcdefghij"), 1, 0, S("12345678901234567890"), 10, 11, S("a1234567890bcdefghij")); + test(S("abcdefghij"), 1, 0, S("12345678901234567890"), 19, 0, S("abcdefghij")); + test(S("abcdefghij"), 1, 0, S("12345678901234567890"), 19, 1, S("a0bcdefghij")); + test(S("abcdefghij"), 1, 0, S("12345678901234567890"), 19, 2, S("a0bcdefghij")); + test(S("abcdefghij"), 1, 0, S("12345678901234567890"), 20, 0, S("abcdefghij")); + test(S("abcdefghij"), 1, 0, S("12345678901234567890"), 20, 1, S("abcdefghij")); + test(S("abcdefghij"), 1, 0, S("12345678901234567890"), 21, 0, S("can't happen")); + test(S("abcdefghij"), 1, 1, S(""), 0, 0, S("acdefghij")); + test(S("abcdefghij"), 1, 1, S(""), 0, 1, S("acdefghij")); + test(S("abcdefghij"), 1, 1, S(""), 1, 0, S("can't happen")); + test(S("abcdefghij"), 1, 1, S("12345"), 0, 0, S("acdefghij")); + test(S("abcdefghij"), 1, 1, S("12345"), 0, 1, S("a1cdefghij")); + test(S("abcdefghij"), 1, 1, S("12345"), 0, 2, S("a12cdefghij")); + test(S("abcdefghij"), 1, 1, S("12345"), 0, 4, S("a1234cdefghij")); + test(S("abcdefghij"), 1, 1, S("12345"), 0, 5, S("a12345cdefghij")); + test(S("abcdefghij"), 1, 1, S("12345"), 0, 6, S("a12345cdefghij")); + test(S("abcdefghij"), 1, 1, S("12345"), 1, 0, S("acdefghij")); + test(S("abcdefghij"), 1, 1, S("12345"), 1, 1, S("a2cdefghij")); + test(S("abcdefghij"), 1, 1, S("12345"), 1, 2, S("a23cdefghij")); + test(S("abcdefghij"), 1, 1, S("12345"), 1, 3, S("a234cdefghij")); + test(S("abcdefghij"), 1, 1, S("12345"), 1, 4, S("a2345cdefghij")); + test(S("abcdefghij"), 1, 1, S("12345"), 1, 5, S("a2345cdefghij")); + test(S("abcdefghij"), 1, 1, S("12345"), 2, 0, S("acdefghij")); + test(S("abcdefghij"), 1, 1, S("12345"), 2, 1, S("a3cdefghij")); + test(S("abcdefghij"), 1, 1, S("12345"), 2, 2, S("a34cdefghij")); + test(S("abcdefghij"), 1, 1, S("12345"), 2, 3, S("a345cdefghij")); + test(S("abcdefghij"), 1, 1, S("12345"), 2, 4, S("a345cdefghij")); + test(S("abcdefghij"), 1, 1, S("12345"), 4, 0, S("acdefghij")); + test(S("abcdefghij"), 1, 1, S("12345"), 4, 1, S("a5cdefghij")); + test(S("abcdefghij"), 1, 1, S("12345"), 4, 2, S("a5cdefghij")); + test(S("abcdefghij"), 1, 1, S("12345"), 5, 0, S("acdefghij")); + test(S("abcdefghij"), 1, 1, S("12345"), 5, 1, S("acdefghij")); + test(S("abcdefghij"), 1, 1, S("12345"), 6, 0, S("can't happen")); + test(S("abcdefghij"), 1, 1, S("1234567890"), 0, 0, S("acdefghij")); + test(S("abcdefghij"), 1, 1, S("1234567890"), 0, 1, S("a1cdefghij")); + test(S("abcdefghij"), 1, 1, S("1234567890"), 0, 5, S("a12345cdefghij")); + test(S("abcdefghij"), 1, 1, S("1234567890"), 0, 9, S("a123456789cdefghij")); + test(S("abcdefghij"), 1, 1, S("1234567890"), 0, 10, S("a1234567890cdefghij")); + test(S("abcdefghij"), 1, 1, S("1234567890"), 0, 11, S("a1234567890cdefghij")); + test(S("abcdefghij"), 1, 1, S("1234567890"), 1, 0, S("acdefghij")); + test(S("abcdefghij"), 1, 1, S("1234567890"), 1, 1, S("a2cdefghij")); + test(S("abcdefghij"), 1, 1, S("1234567890"), 1, 4, S("a2345cdefghij")); + test(S("abcdefghij"), 1, 1, S("1234567890"), 1, 8, S("a23456789cdefghij")); + test(S("abcdefghij"), 1, 1, S("1234567890"), 1, 9, S("a234567890cdefghij")); + test(S("abcdefghij"), 1, 1, S("1234567890"), 1, 10, S("a234567890cdefghij")); + test(S("abcdefghij"), 1, 1, S("1234567890"), 5, 0, S("acdefghij")); + test(S("abcdefghij"), 1, 1, S("1234567890"), 5, 1, S("a6cdefghij")); + test(S("abcdefghij"), 1, 1, S("1234567890"), 5, 2, S("a67cdefghij")); + test(S("abcdefghij"), 1, 1, S("1234567890"), 5, 4, S("a6789cdefghij")); + test(S("abcdefghij"), 1, 1, S("1234567890"), 5, 5, S("a67890cdefghij")); + test(S("abcdefghij"), 1, 1, S("1234567890"), 5, 6, S("a67890cdefghij")); + test(S("abcdefghij"), 1, 1, S("1234567890"), 9, 0, S("acdefghij")); + test(S("abcdefghij"), 1, 1, S("1234567890"), 9, 1, S("a0cdefghij")); + test(S("abcdefghij"), 1, 1, S("1234567890"), 9, 2, S("a0cdefghij")); + test(S("abcdefghij"), 1, 1, S("1234567890"), 10, 0, S("acdefghij")); + test(S("abcdefghij"), 1, 1, S("1234567890"), 10, 1, S("acdefghij")); + test(S("abcdefghij"), 1, 1, S("1234567890"), 11, 0, S("can't happen")); + test(S("abcdefghij"), 1, 1, S("12345678901234567890"), 0, 0, S("acdefghij")); + test(S("abcdefghij"), 1, 1, S("12345678901234567890"), 0, 1, S("a1cdefghij")); + test(S("abcdefghij"), 1, 1, S("12345678901234567890"), 0, 10, S("a1234567890cdefghij")); + test(S("abcdefghij"), 1, 1, S("12345678901234567890"), 0, 19, S("a1234567890123456789cdefghij")); + test(S("abcdefghij"), 1, 1, S("12345678901234567890"), 0, 20, S("a12345678901234567890cdefghij")); + test(S("abcdefghij"), 1, 1, S("12345678901234567890"), 0, 21, S("a12345678901234567890cdefghij")); + test(S("abcdefghij"), 1, 1, S("12345678901234567890"), 1, 0, S("acdefghij")); + test(S("abcdefghij"), 1, 1, S("12345678901234567890"), 1, 1, S("a2cdefghij")); +} + +template +void test25() +{ + test(S("abcdefghij"), 1, 1, S("12345678901234567890"), 1, 9, S("a234567890cdefghij")); + test(S("abcdefghij"), 1, 1, S("12345678901234567890"), 1, 18, S("a234567890123456789cdefghij")); + test(S("abcdefghij"), 1, 1, S("12345678901234567890"), 1, 19, S("a2345678901234567890cdefghij")); + test(S("abcdefghij"), 1, 1, S("12345678901234567890"), 1, 20, S("a2345678901234567890cdefghij")); + test(S("abcdefghij"), 1, 1, S("12345678901234567890"), 10, 0, S("acdefghij")); + test(S("abcdefghij"), 1, 1, S("12345678901234567890"), 10, 1, S("a1cdefghij")); + test(S("abcdefghij"), 1, 1, S("12345678901234567890"), 10, 5, S("a12345cdefghij")); + test(S("abcdefghij"), 1, 1, S("12345678901234567890"), 10, 9, S("a123456789cdefghij")); + test(S("abcdefghij"), 1, 1, S("12345678901234567890"), 10, 10, S("a1234567890cdefghij")); + test(S("abcdefghij"), 1, 1, S("12345678901234567890"), 10, 11, S("a1234567890cdefghij")); + test(S("abcdefghij"), 1, 1, S("12345678901234567890"), 19, 0, S("acdefghij")); + test(S("abcdefghij"), 1, 1, S("12345678901234567890"), 19, 1, S("a0cdefghij")); + test(S("abcdefghij"), 1, 1, S("12345678901234567890"), 19, 2, S("a0cdefghij")); + test(S("abcdefghij"), 1, 1, S("12345678901234567890"), 20, 0, S("acdefghij")); + test(S("abcdefghij"), 1, 1, S("12345678901234567890"), 20, 1, S("acdefghij")); + test(S("abcdefghij"), 1, 1, S("12345678901234567890"), 21, 0, S("can't happen")); + test(S("abcdefghij"), 1, 4, S(""), 0, 0, S("afghij")); + test(S("abcdefghij"), 1, 4, S(""), 0, 1, S("afghij")); + test(S("abcdefghij"), 1, 4, S(""), 1, 0, S("can't happen")); + test(S("abcdefghij"), 1, 4, S("12345"), 0, 0, S("afghij")); + test(S("abcdefghij"), 1, 4, S("12345"), 0, 1, S("a1fghij")); + test(S("abcdefghij"), 1, 4, S("12345"), 0, 2, S("a12fghij")); + test(S("abcdefghij"), 1, 4, S("12345"), 0, 4, S("a1234fghij")); + test(S("abcdefghij"), 1, 4, S("12345"), 0, 5, S("a12345fghij")); + test(S("abcdefghij"), 1, 4, S("12345"), 0, 6, S("a12345fghij")); + test(S("abcdefghij"), 1, 4, S("12345"), 1, 0, S("afghij")); + test(S("abcdefghij"), 1, 4, S("12345"), 1, 1, S("a2fghij")); + test(S("abcdefghij"), 1, 4, S("12345"), 1, 2, S("a23fghij")); + test(S("abcdefghij"), 1, 4, S("12345"), 1, 3, S("a234fghij")); + test(S("abcdefghij"), 1, 4, S("12345"), 1, 4, S("a2345fghij")); + test(S("abcdefghij"), 1, 4, S("12345"), 1, 5, S("a2345fghij")); + test(S("abcdefghij"), 1, 4, S("12345"), 2, 0, S("afghij")); + test(S("abcdefghij"), 1, 4, S("12345"), 2, 1, S("a3fghij")); + test(S("abcdefghij"), 1, 4, S("12345"), 2, 2, S("a34fghij")); + test(S("abcdefghij"), 1, 4, S("12345"), 2, 3, S("a345fghij")); + test(S("abcdefghij"), 1, 4, S("12345"), 2, 4, S("a345fghij")); + test(S("abcdefghij"), 1, 4, S("12345"), 4, 0, S("afghij")); + test(S("abcdefghij"), 1, 4, S("12345"), 4, 1, S("a5fghij")); + test(S("abcdefghij"), 1, 4, S("12345"), 4, 2, S("a5fghij")); + test(S("abcdefghij"), 1, 4, S("12345"), 5, 0, S("afghij")); + test(S("abcdefghij"), 1, 4, S("12345"), 5, 1, S("afghij")); + test(S("abcdefghij"), 1, 4, S("12345"), 6, 0, S("can't happen")); + test(S("abcdefghij"), 1, 4, S("1234567890"), 0, 0, S("afghij")); + test(S("abcdefghij"), 1, 4, S("1234567890"), 0, 1, S("a1fghij")); + test(S("abcdefghij"), 1, 4, S("1234567890"), 0, 5, S("a12345fghij")); + test(S("abcdefghij"), 1, 4, S("1234567890"), 0, 9, S("a123456789fghij")); + test(S("abcdefghij"), 1, 4, S("1234567890"), 0, 10, S("a1234567890fghij")); + test(S("abcdefghij"), 1, 4, S("1234567890"), 0, 11, S("a1234567890fghij")); + test(S("abcdefghij"), 1, 4, S("1234567890"), 1, 0, S("afghij")); + test(S("abcdefghij"), 1, 4, S("1234567890"), 1, 1, S("a2fghij")); + test(S("abcdefghij"), 1, 4, S("1234567890"), 1, 4, S("a2345fghij")); + test(S("abcdefghij"), 1, 4, S("1234567890"), 1, 8, S("a23456789fghij")); + test(S("abcdefghij"), 1, 4, S("1234567890"), 1, 9, S("a234567890fghij")); + test(S("abcdefghij"), 1, 4, S("1234567890"), 1, 10, S("a234567890fghij")); + test(S("abcdefghij"), 1, 4, S("1234567890"), 5, 0, S("afghij")); + test(S("abcdefghij"), 1, 4, S("1234567890"), 5, 1, S("a6fghij")); + test(S("abcdefghij"), 1, 4, S("1234567890"), 5, 2, S("a67fghij")); + test(S("abcdefghij"), 1, 4, S("1234567890"), 5, 4, S("a6789fghij")); + test(S("abcdefghij"), 1, 4, S("1234567890"), 5, 5, S("a67890fghij")); + test(S("abcdefghij"), 1, 4, S("1234567890"), 5, 6, S("a67890fghij")); + test(S("abcdefghij"), 1, 4, S("1234567890"), 9, 0, S("afghij")); + test(S("abcdefghij"), 1, 4, S("1234567890"), 9, 1, S("a0fghij")); + test(S("abcdefghij"), 1, 4, S("1234567890"), 9, 2, S("a0fghij")); + test(S("abcdefghij"), 1, 4, S("1234567890"), 10, 0, S("afghij")); + test(S("abcdefghij"), 1, 4, S("1234567890"), 10, 1, S("afghij")); + test(S("abcdefghij"), 1, 4, S("1234567890"), 11, 0, S("can't happen")); + test(S("abcdefghij"), 1, 4, S("12345678901234567890"), 0, 0, S("afghij")); + test(S("abcdefghij"), 1, 4, S("12345678901234567890"), 0, 1, S("a1fghij")); + test(S("abcdefghij"), 1, 4, S("12345678901234567890"), 0, 10, S("a1234567890fghij")); + test(S("abcdefghij"), 1, 4, S("12345678901234567890"), 0, 19, S("a1234567890123456789fghij")); + test(S("abcdefghij"), 1, 4, S("12345678901234567890"), 0, 20, S("a12345678901234567890fghij")); + test(S("abcdefghij"), 1, 4, S("12345678901234567890"), 0, 21, S("a12345678901234567890fghij")); + test(S("abcdefghij"), 1, 4, S("12345678901234567890"), 1, 0, S("afghij")); + test(S("abcdefghij"), 1, 4, S("12345678901234567890"), 1, 1, S("a2fghij")); + test(S("abcdefghij"), 1, 4, S("12345678901234567890"), 1, 9, S("a234567890fghij")); + test(S("abcdefghij"), 1, 4, S("12345678901234567890"), 1, 18, S("a234567890123456789fghij")); + test(S("abcdefghij"), 1, 4, S("12345678901234567890"), 1, 19, S("a2345678901234567890fghij")); + test(S("abcdefghij"), 1, 4, S("12345678901234567890"), 1, 20, S("a2345678901234567890fghij")); + test(S("abcdefghij"), 1, 4, S("12345678901234567890"), 10, 0, S("afghij")); + test(S("abcdefghij"), 1, 4, S("12345678901234567890"), 10, 1, S("a1fghij")); + test(S("abcdefghij"), 1, 4, S("12345678901234567890"), 10, 5, S("a12345fghij")); + test(S("abcdefghij"), 1, 4, S("12345678901234567890"), 10, 9, S("a123456789fghij")); + test(S("abcdefghij"), 1, 4, S("12345678901234567890"), 10, 10, S("a1234567890fghij")); + test(S("abcdefghij"), 1, 4, S("12345678901234567890"), 10, 11, S("a1234567890fghij")); + test(S("abcdefghij"), 1, 4, S("12345678901234567890"), 19, 0, S("afghij")); + test(S("abcdefghij"), 1, 4, S("12345678901234567890"), 19, 1, S("a0fghij")); + test(S("abcdefghij"), 1, 4, S("12345678901234567890"), 19, 2, S("a0fghij")); + test(S("abcdefghij"), 1, 4, S("12345678901234567890"), 20, 0, S("afghij")); + test(S("abcdefghij"), 1, 4, S("12345678901234567890"), 20, 1, S("afghij")); + test(S("abcdefghij"), 1, 4, S("12345678901234567890"), 21, 0, S("can't happen")); + test(S("abcdefghij"), 1, 8, S(""), 0, 0, S("aj")); + test(S("abcdefghij"), 1, 8, S(""), 0, 1, S("aj")); + test(S("abcdefghij"), 1, 8, S(""), 1, 0, S("can't happen")); + test(S("abcdefghij"), 1, 8, S("12345"), 0, 0, S("aj")); + test(S("abcdefghij"), 1, 8, S("12345"), 0, 1, S("a1j")); + test(S("abcdefghij"), 1, 8, S("12345"), 0, 2, S("a12j")); + test(S("abcdefghij"), 1, 8, S("12345"), 0, 4, S("a1234j")); + test(S("abcdefghij"), 1, 8, S("12345"), 0, 5, S("a12345j")); + test(S("abcdefghij"), 1, 8, S("12345"), 0, 6, S("a12345j")); + test(S("abcdefghij"), 1, 8, S("12345"), 1, 0, S("aj")); +} + +template +void test26() +{ + test(S("abcdefghij"), 1, 8, S("12345"), 1, 1, S("a2j")); + test(S("abcdefghij"), 1, 8, S("12345"), 1, 2, S("a23j")); + test(S("abcdefghij"), 1, 8, S("12345"), 1, 3, S("a234j")); + test(S("abcdefghij"), 1, 8, S("12345"), 1, 4, S("a2345j")); + test(S("abcdefghij"), 1, 8, S("12345"), 1, 5, S("a2345j")); + test(S("abcdefghij"), 1, 8, S("12345"), 2, 0, S("aj")); + test(S("abcdefghij"), 1, 8, S("12345"), 2, 1, S("a3j")); + test(S("abcdefghij"), 1, 8, S("12345"), 2, 2, S("a34j")); + test(S("abcdefghij"), 1, 8, S("12345"), 2, 3, S("a345j")); + test(S("abcdefghij"), 1, 8, S("12345"), 2, 4, S("a345j")); + test(S("abcdefghij"), 1, 8, S("12345"), 4, 0, S("aj")); + test(S("abcdefghij"), 1, 8, S("12345"), 4, 1, S("a5j")); + test(S("abcdefghij"), 1, 8, S("12345"), 4, 2, S("a5j")); + test(S("abcdefghij"), 1, 8, S("12345"), 5, 0, S("aj")); + test(S("abcdefghij"), 1, 8, S("12345"), 5, 1, S("aj")); + test(S("abcdefghij"), 1, 8, S("12345"), 6, 0, S("can't happen")); + test(S("abcdefghij"), 1, 8, S("1234567890"), 0, 0, S("aj")); + test(S("abcdefghij"), 1, 8, S("1234567890"), 0, 1, S("a1j")); + test(S("abcdefghij"), 1, 8, S("1234567890"), 0, 5, S("a12345j")); + test(S("abcdefghij"), 1, 8, S("1234567890"), 0, 9, S("a123456789j")); + test(S("abcdefghij"), 1, 8, S("1234567890"), 0, 10, S("a1234567890j")); + test(S("abcdefghij"), 1, 8, S("1234567890"), 0, 11, S("a1234567890j")); + test(S("abcdefghij"), 1, 8, S("1234567890"), 1, 0, S("aj")); + test(S("abcdefghij"), 1, 8, S("1234567890"), 1, 1, S("a2j")); + test(S("abcdefghij"), 1, 8, S("1234567890"), 1, 4, S("a2345j")); + test(S("abcdefghij"), 1, 8, S("1234567890"), 1, 8, S("a23456789j")); + test(S("abcdefghij"), 1, 8, S("1234567890"), 1, 9, S("a234567890j")); + test(S("abcdefghij"), 1, 8, S("1234567890"), 1, 10, S("a234567890j")); + test(S("abcdefghij"), 1, 8, S("1234567890"), 5, 0, S("aj")); + test(S("abcdefghij"), 1, 8, S("1234567890"), 5, 1, S("a6j")); + test(S("abcdefghij"), 1, 8, S("1234567890"), 5, 2, S("a67j")); + test(S("abcdefghij"), 1, 8, S("1234567890"), 5, 4, S("a6789j")); + test(S("abcdefghij"), 1, 8, S("1234567890"), 5, 5, S("a67890j")); + test(S("abcdefghij"), 1, 8, S("1234567890"), 5, 6, S("a67890j")); + test(S("abcdefghij"), 1, 8, S("1234567890"), 9, 0, S("aj")); + test(S("abcdefghij"), 1, 8, S("1234567890"), 9, 1, S("a0j")); + test(S("abcdefghij"), 1, 8, S("1234567890"), 9, 2, S("a0j")); + test(S("abcdefghij"), 1, 8, S("1234567890"), 10, 0, S("aj")); + test(S("abcdefghij"), 1, 8, S("1234567890"), 10, 1, S("aj")); + test(S("abcdefghij"), 1, 8, S("1234567890"), 11, 0, S("can't happen")); + test(S("abcdefghij"), 1, 8, S("12345678901234567890"), 0, 0, S("aj")); + test(S("abcdefghij"), 1, 8, S("12345678901234567890"), 0, 1, S("a1j")); + test(S("abcdefghij"), 1, 8, S("12345678901234567890"), 0, 10, S("a1234567890j")); + test(S("abcdefghij"), 1, 8, S("12345678901234567890"), 0, 19, S("a1234567890123456789j")); + test(S("abcdefghij"), 1, 8, S("12345678901234567890"), 0, 20, S("a12345678901234567890j")); + test(S("abcdefghij"), 1, 8, S("12345678901234567890"), 0, 21, S("a12345678901234567890j")); + test(S("abcdefghij"), 1, 8, S("12345678901234567890"), 1, 0, S("aj")); + test(S("abcdefghij"), 1, 8, S("12345678901234567890"), 1, 1, S("a2j")); + test(S("abcdefghij"), 1, 8, S("12345678901234567890"), 1, 9, S("a234567890j")); + test(S("abcdefghij"), 1, 8, S("12345678901234567890"), 1, 18, S("a234567890123456789j")); + test(S("abcdefghij"), 1, 8, S("12345678901234567890"), 1, 19, S("a2345678901234567890j")); + test(S("abcdefghij"), 1, 8, S("12345678901234567890"), 1, 20, S("a2345678901234567890j")); + test(S("abcdefghij"), 1, 8, S("12345678901234567890"), 10, 0, S("aj")); + test(S("abcdefghij"), 1, 8, S("12345678901234567890"), 10, 1, S("a1j")); + test(S("abcdefghij"), 1, 8, S("12345678901234567890"), 10, 5, S("a12345j")); + test(S("abcdefghij"), 1, 8, S("12345678901234567890"), 10, 9, S("a123456789j")); + test(S("abcdefghij"), 1, 8, S("12345678901234567890"), 10, 10, S("a1234567890j")); + test(S("abcdefghij"), 1, 8, S("12345678901234567890"), 10, 11, S("a1234567890j")); + test(S("abcdefghij"), 1, 8, S("12345678901234567890"), 19, 0, S("aj")); + test(S("abcdefghij"), 1, 8, S("12345678901234567890"), 19, 1, S("a0j")); + test(S("abcdefghij"), 1, 8, S("12345678901234567890"), 19, 2, S("a0j")); + test(S("abcdefghij"), 1, 8, S("12345678901234567890"), 20, 0, S("aj")); + test(S("abcdefghij"), 1, 8, S("12345678901234567890"), 20, 1, S("aj")); + test(S("abcdefghij"), 1, 8, S("12345678901234567890"), 21, 0, S("can't happen")); + test(S("abcdefghij"), 1, 9, S(""), 0, 0, S("a")); + test(S("abcdefghij"), 1, 9, S(""), 0, 1, S("a")); + test(S("abcdefghij"), 1, 9, S(""), 1, 0, S("can't happen")); + test(S("abcdefghij"), 1, 9, S("12345"), 0, 0, S("a")); + test(S("abcdefghij"), 1, 9, S("12345"), 0, 1, S("a1")); + test(S("abcdefghij"), 1, 9, S("12345"), 0, 2, S("a12")); + test(S("abcdefghij"), 1, 9, S("12345"), 0, 4, S("a1234")); + test(S("abcdefghij"), 1, 9, S("12345"), 0, 5, S("a12345")); + test(S("abcdefghij"), 1, 9, S("12345"), 0, 6, S("a12345")); + test(S("abcdefghij"), 1, 9, S("12345"), 1, 0, S("a")); + test(S("abcdefghij"), 1, 9, S("12345"), 1, 1, S("a2")); + test(S("abcdefghij"), 1, 9, S("12345"), 1, 2, S("a23")); + test(S("abcdefghij"), 1, 9, S("12345"), 1, 3, S("a234")); + test(S("abcdefghij"), 1, 9, S("12345"), 1, 4, S("a2345")); + test(S("abcdefghij"), 1, 9, S("12345"), 1, 5, S("a2345")); + test(S("abcdefghij"), 1, 9, S("12345"), 2, 0, S("a")); + test(S("abcdefghij"), 1, 9, S("12345"), 2, 1, S("a3")); + test(S("abcdefghij"), 1, 9, S("12345"), 2, 2, S("a34")); + test(S("abcdefghij"), 1, 9, S("12345"), 2, 3, S("a345")); + test(S("abcdefghij"), 1, 9, S("12345"), 2, 4, S("a345")); + test(S("abcdefghij"), 1, 9, S("12345"), 4, 0, S("a")); + test(S("abcdefghij"), 1, 9, S("12345"), 4, 1, S("a5")); + test(S("abcdefghij"), 1, 9, S("12345"), 4, 2, S("a5")); + test(S("abcdefghij"), 1, 9, S("12345"), 5, 0, S("a")); + test(S("abcdefghij"), 1, 9, S("12345"), 5, 1, S("a")); + test(S("abcdefghij"), 1, 9, S("12345"), 6, 0, S("can't happen")); + test(S("abcdefghij"), 1, 9, S("1234567890"), 0, 0, S("a")); + test(S("abcdefghij"), 1, 9, S("1234567890"), 0, 1, S("a1")); + test(S("abcdefghij"), 1, 9, S("1234567890"), 0, 5, S("a12345")); + test(S("abcdefghij"), 1, 9, S("1234567890"), 0, 9, S("a123456789")); + test(S("abcdefghij"), 1, 9, S("1234567890"), 0, 10, S("a1234567890")); + test(S("abcdefghij"), 1, 9, S("1234567890"), 0, 11, S("a1234567890")); + test(S("abcdefghij"), 1, 9, S("1234567890"), 1, 0, S("a")); + test(S("abcdefghij"), 1, 9, S("1234567890"), 1, 1, S("a2")); + test(S("abcdefghij"), 1, 9, S("1234567890"), 1, 4, S("a2345")); + test(S("abcdefghij"), 1, 9, S("1234567890"), 1, 8, S("a23456789")); +} + +template +void test27() +{ + test(S("abcdefghij"), 1, 9, S("1234567890"), 1, 9, S("a234567890")); + test(S("abcdefghij"), 1, 9, S("1234567890"), 1, 10, S("a234567890")); + test(S("abcdefghij"), 1, 9, S("1234567890"), 5, 0, S("a")); + test(S("abcdefghij"), 1, 9, S("1234567890"), 5, 1, S("a6")); + test(S("abcdefghij"), 1, 9, S("1234567890"), 5, 2, S("a67")); + test(S("abcdefghij"), 1, 9, S("1234567890"), 5, 4, S("a6789")); + test(S("abcdefghij"), 1, 9, S("1234567890"), 5, 5, S("a67890")); + test(S("abcdefghij"), 1, 9, S("1234567890"), 5, 6, S("a67890")); + test(S("abcdefghij"), 1, 9, S("1234567890"), 9, 0, S("a")); + test(S("abcdefghij"), 1, 9, S("1234567890"), 9, 1, S("a0")); + test(S("abcdefghij"), 1, 9, S("1234567890"), 9, 2, S("a0")); + test(S("abcdefghij"), 1, 9, S("1234567890"), 10, 0, S("a")); + test(S("abcdefghij"), 1, 9, S("1234567890"), 10, 1, S("a")); + test(S("abcdefghij"), 1, 9, S("1234567890"), 11, 0, S("can't happen")); + test(S("abcdefghij"), 1, 9, S("12345678901234567890"), 0, 0, S("a")); + test(S("abcdefghij"), 1, 9, S("12345678901234567890"), 0, 1, S("a1")); + test(S("abcdefghij"), 1, 9, S("12345678901234567890"), 0, 10, S("a1234567890")); + test(S("abcdefghij"), 1, 9, S("12345678901234567890"), 0, 19, S("a1234567890123456789")); + test(S("abcdefghij"), 1, 9, S("12345678901234567890"), 0, 20, S("a12345678901234567890")); + test(S("abcdefghij"), 1, 9, S("12345678901234567890"), 0, 21, S("a12345678901234567890")); + test(S("abcdefghij"), 1, 9, S("12345678901234567890"), 1, 0, S("a")); + test(S("abcdefghij"), 1, 9, S("12345678901234567890"), 1, 1, S("a2")); + test(S("abcdefghij"), 1, 9, S("12345678901234567890"), 1, 9, S("a234567890")); + test(S("abcdefghij"), 1, 9, S("12345678901234567890"), 1, 18, S("a234567890123456789")); + test(S("abcdefghij"), 1, 9, S("12345678901234567890"), 1, 19, S("a2345678901234567890")); + test(S("abcdefghij"), 1, 9, S("12345678901234567890"), 1, 20, S("a2345678901234567890")); + test(S("abcdefghij"), 1, 9, S("12345678901234567890"), 10, 0, S("a")); + test(S("abcdefghij"), 1, 9, S("12345678901234567890"), 10, 1, S("a1")); + test(S("abcdefghij"), 1, 9, S("12345678901234567890"), 10, 5, S("a12345")); + test(S("abcdefghij"), 1, 9, S("12345678901234567890"), 10, 9, S("a123456789")); + test(S("abcdefghij"), 1, 9, S("12345678901234567890"), 10, 10, S("a1234567890")); + test(S("abcdefghij"), 1, 9, S("12345678901234567890"), 10, 11, S("a1234567890")); + test(S("abcdefghij"), 1, 9, S("12345678901234567890"), 19, 0, S("a")); + test(S("abcdefghij"), 1, 9, S("12345678901234567890"), 19, 1, S("a0")); + test(S("abcdefghij"), 1, 9, S("12345678901234567890"), 19, 2, S("a0")); + test(S("abcdefghij"), 1, 9, S("12345678901234567890"), 20, 0, S("a")); + test(S("abcdefghij"), 1, 9, S("12345678901234567890"), 20, 1, S("a")); + test(S("abcdefghij"), 1, 9, S("12345678901234567890"), 21, 0, S("can't happen")); + test(S("abcdefghij"), 1, 10, S(""), 0, 0, S("a")); + test(S("abcdefghij"), 1, 10, S(""), 0, 1, S("a")); + test(S("abcdefghij"), 1, 10, S(""), 1, 0, S("can't happen")); + test(S("abcdefghij"), 1, 10, S("12345"), 0, 0, S("a")); + test(S("abcdefghij"), 1, 10, S("12345"), 0, 1, S("a1")); + test(S("abcdefghij"), 1, 10, S("12345"), 0, 2, S("a12")); + test(S("abcdefghij"), 1, 10, S("12345"), 0, 4, S("a1234")); + test(S("abcdefghij"), 1, 10, S("12345"), 0, 5, S("a12345")); + test(S("abcdefghij"), 1, 10, S("12345"), 0, 6, S("a12345")); + test(S("abcdefghij"), 1, 10, S("12345"), 1, 0, S("a")); + test(S("abcdefghij"), 1, 10, S("12345"), 1, 1, S("a2")); + test(S("abcdefghij"), 1, 10, S("12345"), 1, 2, S("a23")); + test(S("abcdefghij"), 1, 10, S("12345"), 1, 3, S("a234")); + test(S("abcdefghij"), 1, 10, S("12345"), 1, 4, S("a2345")); + test(S("abcdefghij"), 1, 10, S("12345"), 1, 5, S("a2345")); + test(S("abcdefghij"), 1, 10, S("12345"), 2, 0, S("a")); + test(S("abcdefghij"), 1, 10, S("12345"), 2, 1, S("a3")); + test(S("abcdefghij"), 1, 10, S("12345"), 2, 2, S("a34")); + test(S("abcdefghij"), 1, 10, S("12345"), 2, 3, S("a345")); + test(S("abcdefghij"), 1, 10, S("12345"), 2, 4, S("a345")); + test(S("abcdefghij"), 1, 10, S("12345"), 4, 0, S("a")); + test(S("abcdefghij"), 1, 10, S("12345"), 4, 1, S("a5")); + test(S("abcdefghij"), 1, 10, S("12345"), 4, 2, S("a5")); + test(S("abcdefghij"), 1, 10, S("12345"), 5, 0, S("a")); + test(S("abcdefghij"), 1, 10, S("12345"), 5, 1, S("a")); + test(S("abcdefghij"), 1, 10, S("12345"), 6, 0, S("can't happen")); + test(S("abcdefghij"), 1, 10, S("1234567890"), 0, 0, S("a")); + test(S("abcdefghij"), 1, 10, S("1234567890"), 0, 1, S("a1")); + test(S("abcdefghij"), 1, 10, S("1234567890"), 0, 5, S("a12345")); + test(S("abcdefghij"), 1, 10, S("1234567890"), 0, 9, S("a123456789")); + test(S("abcdefghij"), 1, 10, S("1234567890"), 0, 10, S("a1234567890")); + test(S("abcdefghij"), 1, 10, S("1234567890"), 0, 11, S("a1234567890")); + test(S("abcdefghij"), 1, 10, S("1234567890"), 1, 0, S("a")); + test(S("abcdefghij"), 1, 10, S("1234567890"), 1, 1, S("a2")); + test(S("abcdefghij"), 1, 10, S("1234567890"), 1, 4, S("a2345")); + test(S("abcdefghij"), 1, 10, S("1234567890"), 1, 8, S("a23456789")); + test(S("abcdefghij"), 1, 10, S("1234567890"), 1, 9, S("a234567890")); + test(S("abcdefghij"), 1, 10, S("1234567890"), 1, 10, S("a234567890")); + test(S("abcdefghij"), 1, 10, S("1234567890"), 5, 0, S("a")); + test(S("abcdefghij"), 1, 10, S("1234567890"), 5, 1, S("a6")); + test(S("abcdefghij"), 1, 10, S("1234567890"), 5, 2, S("a67")); + test(S("abcdefghij"), 1, 10, S("1234567890"), 5, 4, S("a6789")); + test(S("abcdefghij"), 1, 10, S("1234567890"), 5, 5, S("a67890")); + test(S("abcdefghij"), 1, 10, S("1234567890"), 5, 6, S("a67890")); + test(S("abcdefghij"), 1, 10, S("1234567890"), 9, 0, S("a")); + test(S("abcdefghij"), 1, 10, S("1234567890"), 9, 1, S("a0")); + test(S("abcdefghij"), 1, 10, S("1234567890"), 9, 2, S("a0")); + test(S("abcdefghij"), 1, 10, S("1234567890"), 10, 0, S("a")); + test(S("abcdefghij"), 1, 10, S("1234567890"), 10, 1, S("a")); + test(S("abcdefghij"), 1, 10, S("1234567890"), 11, 0, S("can't happen")); + test(S("abcdefghij"), 1, 10, S("12345678901234567890"), 0, 0, S("a")); + test(S("abcdefghij"), 1, 10, S("12345678901234567890"), 0, 1, S("a1")); + test(S("abcdefghij"), 1, 10, S("12345678901234567890"), 0, 10, S("a1234567890")); + test(S("abcdefghij"), 1, 10, S("12345678901234567890"), 0, 19, S("a1234567890123456789")); + test(S("abcdefghij"), 1, 10, S("12345678901234567890"), 0, 20, S("a12345678901234567890")); + test(S("abcdefghij"), 1, 10, S("12345678901234567890"), 0, 21, S("a12345678901234567890")); + test(S("abcdefghij"), 1, 10, S("12345678901234567890"), 1, 0, S("a")); + test(S("abcdefghij"), 1, 10, S("12345678901234567890"), 1, 1, S("a2")); + test(S("abcdefghij"), 1, 10, S("12345678901234567890"), 1, 9, S("a234567890")); + test(S("abcdefghij"), 1, 10, S("12345678901234567890"), 1, 18, S("a234567890123456789")); + test(S("abcdefghij"), 1, 10, S("12345678901234567890"), 1, 19, S("a2345678901234567890")); + test(S("abcdefghij"), 1, 10, S("12345678901234567890"), 1, 20, S("a2345678901234567890")); +} + +template +void test28() +{ + test(S("abcdefghij"), 1, 10, S("12345678901234567890"), 10, 0, S("a")); + test(S("abcdefghij"), 1, 10, S("12345678901234567890"), 10, 1, S("a1")); + test(S("abcdefghij"), 1, 10, S("12345678901234567890"), 10, 5, S("a12345")); + test(S("abcdefghij"), 1, 10, S("12345678901234567890"), 10, 9, S("a123456789")); + test(S("abcdefghij"), 1, 10, S("12345678901234567890"), 10, 10, S("a1234567890")); + test(S("abcdefghij"), 1, 10, S("12345678901234567890"), 10, 11, S("a1234567890")); + test(S("abcdefghij"), 1, 10, S("12345678901234567890"), 19, 0, S("a")); + test(S("abcdefghij"), 1, 10, S("12345678901234567890"), 19, 1, S("a0")); + test(S("abcdefghij"), 1, 10, S("12345678901234567890"), 19, 2, S("a0")); + test(S("abcdefghij"), 1, 10, S("12345678901234567890"), 20, 0, S("a")); + test(S("abcdefghij"), 1, 10, S("12345678901234567890"), 20, 1, S("a")); + test(S("abcdefghij"), 1, 10, S("12345678901234567890"), 21, 0, S("can't happen")); + test(S("abcdefghij"), 5, 0, S(""), 0, 0, S("abcdefghij")); + test(S("abcdefghij"), 5, 0, S(""), 0, 1, S("abcdefghij")); + test(S("abcdefghij"), 5, 0, S(""), 1, 0, S("can't happen")); + test(S("abcdefghij"), 5, 0, S("12345"), 0, 0, S("abcdefghij")); + test(S("abcdefghij"), 5, 0, S("12345"), 0, 1, S("abcde1fghij")); + test(S("abcdefghij"), 5, 0, S("12345"), 0, 2, S("abcde12fghij")); + test(S("abcdefghij"), 5, 0, S("12345"), 0, 4, S("abcde1234fghij")); + test(S("abcdefghij"), 5, 0, S("12345"), 0, 5, S("abcde12345fghij")); + test(S("abcdefghij"), 5, 0, S("12345"), 0, 6, S("abcde12345fghij")); + test(S("abcdefghij"), 5, 0, S("12345"), 1, 0, S("abcdefghij")); + test(S("abcdefghij"), 5, 0, S("12345"), 1, 1, S("abcde2fghij")); + test(S("abcdefghij"), 5, 0, S("12345"), 1, 2, S("abcde23fghij")); + test(S("abcdefghij"), 5, 0, S("12345"), 1, 3, S("abcde234fghij")); + test(S("abcdefghij"), 5, 0, S("12345"), 1, 4, S("abcde2345fghij")); + test(S("abcdefghij"), 5, 0, S("12345"), 1, 5, S("abcde2345fghij")); + test(S("abcdefghij"), 5, 0, S("12345"), 2, 0, S("abcdefghij")); + test(S("abcdefghij"), 5, 0, S("12345"), 2, 1, S("abcde3fghij")); + test(S("abcdefghij"), 5, 0, S("12345"), 2, 2, S("abcde34fghij")); + test(S("abcdefghij"), 5, 0, S("12345"), 2, 3, S("abcde345fghij")); + test(S("abcdefghij"), 5, 0, S("12345"), 2, 4, S("abcde345fghij")); + test(S("abcdefghij"), 5, 0, S("12345"), 4, 0, S("abcdefghij")); + test(S("abcdefghij"), 5, 0, S("12345"), 4, 1, S("abcde5fghij")); + test(S("abcdefghij"), 5, 0, S("12345"), 4, 2, S("abcde5fghij")); + test(S("abcdefghij"), 5, 0, S("12345"), 5, 0, S("abcdefghij")); + test(S("abcdefghij"), 5, 0, S("12345"), 5, 1, S("abcdefghij")); + test(S("abcdefghij"), 5, 0, S("12345"), 6, 0, S("can't happen")); + test(S("abcdefghij"), 5, 0, S("1234567890"), 0, 0, S("abcdefghij")); + test(S("abcdefghij"), 5, 0, S("1234567890"), 0, 1, S("abcde1fghij")); + test(S("abcdefghij"), 5, 0, S("1234567890"), 0, 5, S("abcde12345fghij")); + test(S("abcdefghij"), 5, 0, S("1234567890"), 0, 9, S("abcde123456789fghij")); + test(S("abcdefghij"), 5, 0, S("1234567890"), 0, 10, S("abcde1234567890fghij")); + test(S("abcdefghij"), 5, 0, S("1234567890"), 0, 11, S("abcde1234567890fghij")); + test(S("abcdefghij"), 5, 0, S("1234567890"), 1, 0, S("abcdefghij")); + test(S("abcdefghij"), 5, 0, S("1234567890"), 1, 1, S("abcde2fghij")); + test(S("abcdefghij"), 5, 0, S("1234567890"), 1, 4, S("abcde2345fghij")); + test(S("abcdefghij"), 5, 0, S("1234567890"), 1, 8, S("abcde23456789fghij")); + test(S("abcdefghij"), 5, 0, S("1234567890"), 1, 9, S("abcde234567890fghij")); + test(S("abcdefghij"), 5, 0, S("1234567890"), 1, 10, S("abcde234567890fghij")); + test(S("abcdefghij"), 5, 0, S("1234567890"), 5, 0, S("abcdefghij")); + test(S("abcdefghij"), 5, 0, S("1234567890"), 5, 1, S("abcde6fghij")); + test(S("abcdefghij"), 5, 0, S("1234567890"), 5, 2, S("abcde67fghij")); + test(S("abcdefghij"), 5, 0, S("1234567890"), 5, 4, S("abcde6789fghij")); + test(S("abcdefghij"), 5, 0, S("1234567890"), 5, 5, S("abcde67890fghij")); + test(S("abcdefghij"), 5, 0, S("1234567890"), 5, 6, S("abcde67890fghij")); + test(S("abcdefghij"), 5, 0, S("1234567890"), 9, 0, S("abcdefghij")); + test(S("abcdefghij"), 5, 0, S("1234567890"), 9, 1, S("abcde0fghij")); + test(S("abcdefghij"), 5, 0, S("1234567890"), 9, 2, S("abcde0fghij")); + test(S("abcdefghij"), 5, 0, S("1234567890"), 10, 0, S("abcdefghij")); + test(S("abcdefghij"), 5, 0, S("1234567890"), 10, 1, S("abcdefghij")); + test(S("abcdefghij"), 5, 0, S("1234567890"), 11, 0, S("can't happen")); + test(S("abcdefghij"), 5, 0, S("12345678901234567890"), 0, 0, S("abcdefghij")); + test(S("abcdefghij"), 5, 0, S("12345678901234567890"), 0, 1, S("abcde1fghij")); + test(S("abcdefghij"), 5, 0, S("12345678901234567890"), 0, 10, S("abcde1234567890fghij")); + test(S("abcdefghij"), 5, 0, S("12345678901234567890"), 0, 19, S("abcde1234567890123456789fghij")); + test(S("abcdefghij"), 5, 0, S("12345678901234567890"), 0, 20, S("abcde12345678901234567890fghij")); + test(S("abcdefghij"), 5, 0, S("12345678901234567890"), 0, 21, S("abcde12345678901234567890fghij")); + test(S("abcdefghij"), 5, 0, S("12345678901234567890"), 1, 0, S("abcdefghij")); + test(S("abcdefghij"), 5, 0, S("12345678901234567890"), 1, 1, S("abcde2fghij")); + test(S("abcdefghij"), 5, 0, S("12345678901234567890"), 1, 9, S("abcde234567890fghij")); + test(S("abcdefghij"), 5, 0, S("12345678901234567890"), 1, 18, S("abcde234567890123456789fghij")); + test(S("abcdefghij"), 5, 0, S("12345678901234567890"), 1, 19, S("abcde2345678901234567890fghij")); + test(S("abcdefghij"), 5, 0, S("12345678901234567890"), 1, 20, S("abcde2345678901234567890fghij")); + test(S("abcdefghij"), 5, 0, S("12345678901234567890"), 10, 0, S("abcdefghij")); + test(S("abcdefghij"), 5, 0, S("12345678901234567890"), 10, 1, S("abcde1fghij")); + test(S("abcdefghij"), 5, 0, S("12345678901234567890"), 10, 5, S("abcde12345fghij")); + test(S("abcdefghij"), 5, 0, S("12345678901234567890"), 10, 9, S("abcde123456789fghij")); + test(S("abcdefghij"), 5, 0, S("12345678901234567890"), 10, 10, S("abcde1234567890fghij")); + test(S("abcdefghij"), 5, 0, S("12345678901234567890"), 10, 11, S("abcde1234567890fghij")); + test(S("abcdefghij"), 5, 0, S("12345678901234567890"), 19, 0, S("abcdefghij")); + test(S("abcdefghij"), 5, 0, S("12345678901234567890"), 19, 1, S("abcde0fghij")); + test(S("abcdefghij"), 5, 0, S("12345678901234567890"), 19, 2, S("abcde0fghij")); + test(S("abcdefghij"), 5, 0, S("12345678901234567890"), 20, 0, S("abcdefghij")); + test(S("abcdefghij"), 5, 0, S("12345678901234567890"), 20, 1, S("abcdefghij")); + test(S("abcdefghij"), 5, 0, S("12345678901234567890"), 21, 0, S("can't happen")); + test(S("abcdefghij"), 5, 1, S(""), 0, 0, S("abcdeghij")); + test(S("abcdefghij"), 5, 1, S(""), 0, 1, S("abcdeghij")); + test(S("abcdefghij"), 5, 1, S(""), 1, 0, S("can't happen")); + test(S("abcdefghij"), 5, 1, S("12345"), 0, 0, S("abcdeghij")); + test(S("abcdefghij"), 5, 1, S("12345"), 0, 1, S("abcde1ghij")); + test(S("abcdefghij"), 5, 1, S("12345"), 0, 2, S("abcde12ghij")); + test(S("abcdefghij"), 5, 1, S("12345"), 0, 4, S("abcde1234ghij")); + test(S("abcdefghij"), 5, 1, S("12345"), 0, 5, S("abcde12345ghij")); + test(S("abcdefghij"), 5, 1, S("12345"), 0, 6, S("abcde12345ghij")); + test(S("abcdefghij"), 5, 1, S("12345"), 1, 0, S("abcdeghij")); + test(S("abcdefghij"), 5, 1, S("12345"), 1, 1, S("abcde2ghij")); + test(S("abcdefghij"), 5, 1, S("12345"), 1, 2, S("abcde23ghij")); + test(S("abcdefghij"), 5, 1, S("12345"), 1, 3, S("abcde234ghij")); + test(S("abcdefghij"), 5, 1, S("12345"), 1, 4, S("abcde2345ghij")); +} + +template +void test29() +{ + test(S("abcdefghij"), 5, 1, S("12345"), 1, 5, S("abcde2345ghij")); + test(S("abcdefghij"), 5, 1, S("12345"), 2, 0, S("abcdeghij")); + test(S("abcdefghij"), 5, 1, S("12345"), 2, 1, S("abcde3ghij")); + test(S("abcdefghij"), 5, 1, S("12345"), 2, 2, S("abcde34ghij")); + test(S("abcdefghij"), 5, 1, S("12345"), 2, 3, S("abcde345ghij")); + test(S("abcdefghij"), 5, 1, S("12345"), 2, 4, S("abcde345ghij")); + test(S("abcdefghij"), 5, 1, S("12345"), 4, 0, S("abcdeghij")); + test(S("abcdefghij"), 5, 1, S("12345"), 4, 1, S("abcde5ghij")); + test(S("abcdefghij"), 5, 1, S("12345"), 4, 2, S("abcde5ghij")); + test(S("abcdefghij"), 5, 1, S("12345"), 5, 0, S("abcdeghij")); + test(S("abcdefghij"), 5, 1, S("12345"), 5, 1, S("abcdeghij")); + test(S("abcdefghij"), 5, 1, S("12345"), 6, 0, S("can't happen")); + test(S("abcdefghij"), 5, 1, S("1234567890"), 0, 0, S("abcdeghij")); + test(S("abcdefghij"), 5, 1, S("1234567890"), 0, 1, S("abcde1ghij")); + test(S("abcdefghij"), 5, 1, S("1234567890"), 0, 5, S("abcde12345ghij")); + test(S("abcdefghij"), 5, 1, S("1234567890"), 0, 9, S("abcde123456789ghij")); + test(S("abcdefghij"), 5, 1, S("1234567890"), 0, 10, S("abcde1234567890ghij")); + test(S("abcdefghij"), 5, 1, S("1234567890"), 0, 11, S("abcde1234567890ghij")); + test(S("abcdefghij"), 5, 1, S("1234567890"), 1, 0, S("abcdeghij")); + test(S("abcdefghij"), 5, 1, S("1234567890"), 1, 1, S("abcde2ghij")); + test(S("abcdefghij"), 5, 1, S("1234567890"), 1, 4, S("abcde2345ghij")); + test(S("abcdefghij"), 5, 1, S("1234567890"), 1, 8, S("abcde23456789ghij")); + test(S("abcdefghij"), 5, 1, S("1234567890"), 1, 9, S("abcde234567890ghij")); + test(S("abcdefghij"), 5, 1, S("1234567890"), 1, 10, S("abcde234567890ghij")); + test(S("abcdefghij"), 5, 1, S("1234567890"), 5, 0, S("abcdeghij")); + test(S("abcdefghij"), 5, 1, S("1234567890"), 5, 1, S("abcde6ghij")); + test(S("abcdefghij"), 5, 1, S("1234567890"), 5, 2, S("abcde67ghij")); + test(S("abcdefghij"), 5, 1, S("1234567890"), 5, 4, S("abcde6789ghij")); + test(S("abcdefghij"), 5, 1, S("1234567890"), 5, 5, S("abcde67890ghij")); + test(S("abcdefghij"), 5, 1, S("1234567890"), 5, 6, S("abcde67890ghij")); + test(S("abcdefghij"), 5, 1, S("1234567890"), 9, 0, S("abcdeghij")); + test(S("abcdefghij"), 5, 1, S("1234567890"), 9, 1, S("abcde0ghij")); + test(S("abcdefghij"), 5, 1, S("1234567890"), 9, 2, S("abcde0ghij")); + test(S("abcdefghij"), 5, 1, S("1234567890"), 10, 0, S("abcdeghij")); + test(S("abcdefghij"), 5, 1, S("1234567890"), 10, 1, S("abcdeghij")); + test(S("abcdefghij"), 5, 1, S("1234567890"), 11, 0, S("can't happen")); + test(S("abcdefghij"), 5, 1, S("12345678901234567890"), 0, 0, S("abcdeghij")); + test(S("abcdefghij"), 5, 1, S("12345678901234567890"), 0, 1, S("abcde1ghij")); + test(S("abcdefghij"), 5, 1, S("12345678901234567890"), 0, 10, S("abcde1234567890ghij")); + test(S("abcdefghij"), 5, 1, S("12345678901234567890"), 0, 19, S("abcde1234567890123456789ghij")); + test(S("abcdefghij"), 5, 1, S("12345678901234567890"), 0, 20, S("abcde12345678901234567890ghij")); + test(S("abcdefghij"), 5, 1, S("12345678901234567890"), 0, 21, S("abcde12345678901234567890ghij")); + test(S("abcdefghij"), 5, 1, S("12345678901234567890"), 1, 0, S("abcdeghij")); + test(S("abcdefghij"), 5, 1, S("12345678901234567890"), 1, 1, S("abcde2ghij")); + test(S("abcdefghij"), 5, 1, S("12345678901234567890"), 1, 9, S("abcde234567890ghij")); + test(S("abcdefghij"), 5, 1, S("12345678901234567890"), 1, 18, S("abcde234567890123456789ghij")); + test(S("abcdefghij"), 5, 1, S("12345678901234567890"), 1, 19, S("abcde2345678901234567890ghij")); + test(S("abcdefghij"), 5, 1, S("12345678901234567890"), 1, 20, S("abcde2345678901234567890ghij")); + test(S("abcdefghij"), 5, 1, S("12345678901234567890"), 10, 0, S("abcdeghij")); + test(S("abcdefghij"), 5, 1, S("12345678901234567890"), 10, 1, S("abcde1ghij")); + test(S("abcdefghij"), 5, 1, S("12345678901234567890"), 10, 5, S("abcde12345ghij")); + test(S("abcdefghij"), 5, 1, S("12345678901234567890"), 10, 9, S("abcde123456789ghij")); + test(S("abcdefghij"), 5, 1, S("12345678901234567890"), 10, 10, S("abcde1234567890ghij")); + test(S("abcdefghij"), 5, 1, S("12345678901234567890"), 10, 11, S("abcde1234567890ghij")); + test(S("abcdefghij"), 5, 1, S("12345678901234567890"), 19, 0, S("abcdeghij")); + test(S("abcdefghij"), 5, 1, S("12345678901234567890"), 19, 1, S("abcde0ghij")); + test(S("abcdefghij"), 5, 1, S("12345678901234567890"), 19, 2, S("abcde0ghij")); + test(S("abcdefghij"), 5, 1, S("12345678901234567890"), 20, 0, S("abcdeghij")); + test(S("abcdefghij"), 5, 1, S("12345678901234567890"), 20, 1, S("abcdeghij")); + test(S("abcdefghij"), 5, 1, S("12345678901234567890"), 21, 0, S("can't happen")); + test(S("abcdefghij"), 5, 2, S(""), 0, 0, S("abcdehij")); + test(S("abcdefghij"), 5, 2, S(""), 0, 1, S("abcdehij")); + test(S("abcdefghij"), 5, 2, S(""), 1, 0, S("can't happen")); + test(S("abcdefghij"), 5, 2, S("12345"), 0, 0, S("abcdehij")); + test(S("abcdefghij"), 5, 2, S("12345"), 0, 1, S("abcde1hij")); + test(S("abcdefghij"), 5, 2, S("12345"), 0, 2, S("abcde12hij")); + test(S("abcdefghij"), 5, 2, S("12345"), 0, 4, S("abcde1234hij")); + test(S("abcdefghij"), 5, 2, S("12345"), 0, 5, S("abcde12345hij")); + test(S("abcdefghij"), 5, 2, S("12345"), 0, 6, S("abcde12345hij")); + test(S("abcdefghij"), 5, 2, S("12345"), 1, 0, S("abcdehij")); + test(S("abcdefghij"), 5, 2, S("12345"), 1, 1, S("abcde2hij")); + test(S("abcdefghij"), 5, 2, S("12345"), 1, 2, S("abcde23hij")); + test(S("abcdefghij"), 5, 2, S("12345"), 1, 3, S("abcde234hij")); + test(S("abcdefghij"), 5, 2, S("12345"), 1, 4, S("abcde2345hij")); + test(S("abcdefghij"), 5, 2, S("12345"), 1, 5, S("abcde2345hij")); + test(S("abcdefghij"), 5, 2, S("12345"), 2, 0, S("abcdehij")); + test(S("abcdefghij"), 5, 2, S("12345"), 2, 1, S("abcde3hij")); + test(S("abcdefghij"), 5, 2, S("12345"), 2, 2, S("abcde34hij")); + test(S("abcdefghij"), 5, 2, S("12345"), 2, 3, S("abcde345hij")); + test(S("abcdefghij"), 5, 2, S("12345"), 2, 4, S("abcde345hij")); + test(S("abcdefghij"), 5, 2, S("12345"), 4, 0, S("abcdehij")); + test(S("abcdefghij"), 5, 2, S("12345"), 4, 1, S("abcde5hij")); + test(S("abcdefghij"), 5, 2, S("12345"), 4, 2, S("abcde5hij")); + test(S("abcdefghij"), 5, 2, S("12345"), 5, 0, S("abcdehij")); + test(S("abcdefghij"), 5, 2, S("12345"), 5, 1, S("abcdehij")); + test(S("abcdefghij"), 5, 2, S("12345"), 6, 0, S("can't happen")); + test(S("abcdefghij"), 5, 2, S("1234567890"), 0, 0, S("abcdehij")); + test(S("abcdefghij"), 5, 2, S("1234567890"), 0, 1, S("abcde1hij")); + test(S("abcdefghij"), 5, 2, S("1234567890"), 0, 5, S("abcde12345hij")); + test(S("abcdefghij"), 5, 2, S("1234567890"), 0, 9, S("abcde123456789hij")); + test(S("abcdefghij"), 5, 2, S("1234567890"), 0, 10, S("abcde1234567890hij")); + test(S("abcdefghij"), 5, 2, S("1234567890"), 0, 11, S("abcde1234567890hij")); + test(S("abcdefghij"), 5, 2, S("1234567890"), 1, 0, S("abcdehij")); + test(S("abcdefghij"), 5, 2, S("1234567890"), 1, 1, S("abcde2hij")); + test(S("abcdefghij"), 5, 2, S("1234567890"), 1, 4, S("abcde2345hij")); + test(S("abcdefghij"), 5, 2, S("1234567890"), 1, 8, S("abcde23456789hij")); + test(S("abcdefghij"), 5, 2, S("1234567890"), 1, 9, S("abcde234567890hij")); + test(S("abcdefghij"), 5, 2, S("1234567890"), 1, 10, S("abcde234567890hij")); + test(S("abcdefghij"), 5, 2, S("1234567890"), 5, 0, S("abcdehij")); + test(S("abcdefghij"), 5, 2, S("1234567890"), 5, 1, S("abcde6hij")); +} + +template +void test30() +{ + test(S("abcdefghij"), 5, 2, S("1234567890"), 5, 2, S("abcde67hij")); + test(S("abcdefghij"), 5, 2, S("1234567890"), 5, 4, S("abcde6789hij")); + test(S("abcdefghij"), 5, 2, S("1234567890"), 5, 5, S("abcde67890hij")); + test(S("abcdefghij"), 5, 2, S("1234567890"), 5, 6, S("abcde67890hij")); + test(S("abcdefghij"), 5, 2, S("1234567890"), 9, 0, S("abcdehij")); + test(S("abcdefghij"), 5, 2, S("1234567890"), 9, 1, S("abcde0hij")); + test(S("abcdefghij"), 5, 2, S("1234567890"), 9, 2, S("abcde0hij")); + test(S("abcdefghij"), 5, 2, S("1234567890"), 10, 0, S("abcdehij")); + test(S("abcdefghij"), 5, 2, S("1234567890"), 10, 1, S("abcdehij")); + test(S("abcdefghij"), 5, 2, S("1234567890"), 11, 0, S("can't happen")); + test(S("abcdefghij"), 5, 2, S("12345678901234567890"), 0, 0, S("abcdehij")); + test(S("abcdefghij"), 5, 2, S("12345678901234567890"), 0, 1, S("abcde1hij")); + test(S("abcdefghij"), 5, 2, S("12345678901234567890"), 0, 10, S("abcde1234567890hij")); + test(S("abcdefghij"), 5, 2, S("12345678901234567890"), 0, 19, S("abcde1234567890123456789hij")); + test(S("abcdefghij"), 5, 2, S("12345678901234567890"), 0, 20, S("abcde12345678901234567890hij")); + test(S("abcdefghij"), 5, 2, S("12345678901234567890"), 0, 21, S("abcde12345678901234567890hij")); + test(S("abcdefghij"), 5, 2, S("12345678901234567890"), 1, 0, S("abcdehij")); + test(S("abcdefghij"), 5, 2, S("12345678901234567890"), 1, 1, S("abcde2hij")); + test(S("abcdefghij"), 5, 2, S("12345678901234567890"), 1, 9, S("abcde234567890hij")); + test(S("abcdefghij"), 5, 2, S("12345678901234567890"), 1, 18, S("abcde234567890123456789hij")); + test(S("abcdefghij"), 5, 2, S("12345678901234567890"), 1, 19, S("abcde2345678901234567890hij")); + test(S("abcdefghij"), 5, 2, S("12345678901234567890"), 1, 20, S("abcde2345678901234567890hij")); + test(S("abcdefghij"), 5, 2, S("12345678901234567890"), 10, 0, S("abcdehij")); + test(S("abcdefghij"), 5, 2, S("12345678901234567890"), 10, 1, S("abcde1hij")); + test(S("abcdefghij"), 5, 2, S("12345678901234567890"), 10, 5, S("abcde12345hij")); + test(S("abcdefghij"), 5, 2, S("12345678901234567890"), 10, 9, S("abcde123456789hij")); + test(S("abcdefghij"), 5, 2, S("12345678901234567890"), 10, 10, S("abcde1234567890hij")); + test(S("abcdefghij"), 5, 2, S("12345678901234567890"), 10, 11, S("abcde1234567890hij")); + test(S("abcdefghij"), 5, 2, S("12345678901234567890"), 19, 0, S("abcdehij")); + test(S("abcdefghij"), 5, 2, S("12345678901234567890"), 19, 1, S("abcde0hij")); + test(S("abcdefghij"), 5, 2, S("12345678901234567890"), 19, 2, S("abcde0hij")); + test(S("abcdefghij"), 5, 2, S("12345678901234567890"), 20, 0, S("abcdehij")); + test(S("abcdefghij"), 5, 2, S("12345678901234567890"), 20, 1, S("abcdehij")); + test(S("abcdefghij"), 5, 2, S("12345678901234567890"), 21, 0, S("can't happen")); + test(S("abcdefghij"), 5, 4, S(""), 0, 0, S("abcdej")); + test(S("abcdefghij"), 5, 4, S(""), 0, 1, S("abcdej")); + test(S("abcdefghij"), 5, 4, S(""), 1, 0, S("can't happen")); + test(S("abcdefghij"), 5, 4, S("12345"), 0, 0, S("abcdej")); + test(S("abcdefghij"), 5, 4, S("12345"), 0, 1, S("abcde1j")); + test(S("abcdefghij"), 5, 4, S("12345"), 0, 2, S("abcde12j")); + test(S("abcdefghij"), 5, 4, S("12345"), 0, 4, S("abcde1234j")); + test(S("abcdefghij"), 5, 4, S("12345"), 0, 5, S("abcde12345j")); + test(S("abcdefghij"), 5, 4, S("12345"), 0, 6, S("abcde12345j")); + test(S("abcdefghij"), 5, 4, S("12345"), 1, 0, S("abcdej")); + test(S("abcdefghij"), 5, 4, S("12345"), 1, 1, S("abcde2j")); + test(S("abcdefghij"), 5, 4, S("12345"), 1, 2, S("abcde23j")); + test(S("abcdefghij"), 5, 4, S("12345"), 1, 3, S("abcde234j")); + test(S("abcdefghij"), 5, 4, S("12345"), 1, 4, S("abcde2345j")); + test(S("abcdefghij"), 5, 4, S("12345"), 1, 5, S("abcde2345j")); + test(S("abcdefghij"), 5, 4, S("12345"), 2, 0, S("abcdej")); + test(S("abcdefghij"), 5, 4, S("12345"), 2, 1, S("abcde3j")); + test(S("abcdefghij"), 5, 4, S("12345"), 2, 2, S("abcde34j")); + test(S("abcdefghij"), 5, 4, S("12345"), 2, 3, S("abcde345j")); + test(S("abcdefghij"), 5, 4, S("12345"), 2, 4, S("abcde345j")); + test(S("abcdefghij"), 5, 4, S("12345"), 4, 0, S("abcdej")); + test(S("abcdefghij"), 5, 4, S("12345"), 4, 1, S("abcde5j")); + test(S("abcdefghij"), 5, 4, S("12345"), 4, 2, S("abcde5j")); + test(S("abcdefghij"), 5, 4, S("12345"), 5, 0, S("abcdej")); + test(S("abcdefghij"), 5, 4, S("12345"), 5, 1, S("abcdej")); + test(S("abcdefghij"), 5, 4, S("12345"), 6, 0, S("can't happen")); + test(S("abcdefghij"), 5, 4, S("1234567890"), 0, 0, S("abcdej")); + test(S("abcdefghij"), 5, 4, S("1234567890"), 0, 1, S("abcde1j")); + test(S("abcdefghij"), 5, 4, S("1234567890"), 0, 5, S("abcde12345j")); + test(S("abcdefghij"), 5, 4, S("1234567890"), 0, 9, S("abcde123456789j")); + test(S("abcdefghij"), 5, 4, S("1234567890"), 0, 10, S("abcde1234567890j")); + test(S("abcdefghij"), 5, 4, S("1234567890"), 0, 11, S("abcde1234567890j")); + test(S("abcdefghij"), 5, 4, S("1234567890"), 1, 0, S("abcdej")); + test(S("abcdefghij"), 5, 4, S("1234567890"), 1, 1, S("abcde2j")); + test(S("abcdefghij"), 5, 4, S("1234567890"), 1, 4, S("abcde2345j")); + test(S("abcdefghij"), 5, 4, S("1234567890"), 1, 8, S("abcde23456789j")); + test(S("abcdefghij"), 5, 4, S("1234567890"), 1, 9, S("abcde234567890j")); + test(S("abcdefghij"), 5, 4, S("1234567890"), 1, 10, S("abcde234567890j")); + test(S("abcdefghij"), 5, 4, S("1234567890"), 5, 0, S("abcdej")); + test(S("abcdefghij"), 5, 4, S("1234567890"), 5, 1, S("abcde6j")); + test(S("abcdefghij"), 5, 4, S("1234567890"), 5, 2, S("abcde67j")); + test(S("abcdefghij"), 5, 4, S("1234567890"), 5, 4, S("abcde6789j")); + test(S("abcdefghij"), 5, 4, S("1234567890"), 5, 5, S("abcde67890j")); + test(S("abcdefghij"), 5, 4, S("1234567890"), 5, 6, S("abcde67890j")); + test(S("abcdefghij"), 5, 4, S("1234567890"), 9, 0, S("abcdej")); + test(S("abcdefghij"), 5, 4, S("1234567890"), 9, 1, S("abcde0j")); + test(S("abcdefghij"), 5, 4, S("1234567890"), 9, 2, S("abcde0j")); + test(S("abcdefghij"), 5, 4, S("1234567890"), 10, 0, S("abcdej")); + test(S("abcdefghij"), 5, 4, S("1234567890"), 10, 1, S("abcdej")); + test(S("abcdefghij"), 5, 4, S("1234567890"), 11, 0, S("can't happen")); + test(S("abcdefghij"), 5, 4, S("12345678901234567890"), 0, 0, S("abcdej")); + test(S("abcdefghij"), 5, 4, S("12345678901234567890"), 0, 1, S("abcde1j")); + test(S("abcdefghij"), 5, 4, S("12345678901234567890"), 0, 10, S("abcde1234567890j")); + test(S("abcdefghij"), 5, 4, S("12345678901234567890"), 0, 19, S("abcde1234567890123456789j")); + test(S("abcdefghij"), 5, 4, S("12345678901234567890"), 0, 20, S("abcde12345678901234567890j")); + test(S("abcdefghij"), 5, 4, S("12345678901234567890"), 0, 21, S("abcde12345678901234567890j")); + test(S("abcdefghij"), 5, 4, S("12345678901234567890"), 1, 0, S("abcdej")); + test(S("abcdefghij"), 5, 4, S("12345678901234567890"), 1, 1, S("abcde2j")); + test(S("abcdefghij"), 5, 4, S("12345678901234567890"), 1, 9, S("abcde234567890j")); + test(S("abcdefghij"), 5, 4, S("12345678901234567890"), 1, 18, S("abcde234567890123456789j")); + test(S("abcdefghij"), 5, 4, S("12345678901234567890"), 1, 19, S("abcde2345678901234567890j")); + test(S("abcdefghij"), 5, 4, S("12345678901234567890"), 1, 20, S("abcde2345678901234567890j")); + test(S("abcdefghij"), 5, 4, S("12345678901234567890"), 10, 0, S("abcdej")); + test(S("abcdefghij"), 5, 4, S("12345678901234567890"), 10, 1, S("abcde1j")); + test(S("abcdefghij"), 5, 4, S("12345678901234567890"), 10, 5, S("abcde12345j")); + test(S("abcdefghij"), 5, 4, S("12345678901234567890"), 10, 9, S("abcde123456789j")); +} + +template +void test31() +{ + test(S("abcdefghij"), 5, 4, S("12345678901234567890"), 10, 10, S("abcde1234567890j")); + test(S("abcdefghij"), 5, 4, S("12345678901234567890"), 10, 11, S("abcde1234567890j")); + test(S("abcdefghij"), 5, 4, S("12345678901234567890"), 19, 0, S("abcdej")); + test(S("abcdefghij"), 5, 4, S("12345678901234567890"), 19, 1, S("abcde0j")); + test(S("abcdefghij"), 5, 4, S("12345678901234567890"), 19, 2, S("abcde0j")); + test(S("abcdefghij"), 5, 4, S("12345678901234567890"), 20, 0, S("abcdej")); + test(S("abcdefghij"), 5, 4, S("12345678901234567890"), 20, 1, S("abcdej")); + test(S("abcdefghij"), 5, 4, S("12345678901234567890"), 21, 0, S("can't happen")); + test(S("abcdefghij"), 5, 5, S(""), 0, 0, S("abcde")); + test(S("abcdefghij"), 5, 5, S(""), 0, 1, S("abcde")); + test(S("abcdefghij"), 5, 5, S(""), 1, 0, S("can't happen")); + test(S("abcdefghij"), 5, 5, S("12345"), 0, 0, S("abcde")); + test(S("abcdefghij"), 5, 5, S("12345"), 0, 1, S("abcde1")); + test(S("abcdefghij"), 5, 5, S("12345"), 0, 2, S("abcde12")); + test(S("abcdefghij"), 5, 5, S("12345"), 0, 4, S("abcde1234")); + test(S("abcdefghij"), 5, 5, S("12345"), 0, 5, S("abcde12345")); + test(S("abcdefghij"), 5, 5, S("12345"), 0, 6, S("abcde12345")); + test(S("abcdefghij"), 5, 5, S("12345"), 1, 0, S("abcde")); + test(S("abcdefghij"), 5, 5, S("12345"), 1, 1, S("abcde2")); + test(S("abcdefghij"), 5, 5, S("12345"), 1, 2, S("abcde23")); + test(S("abcdefghij"), 5, 5, S("12345"), 1, 3, S("abcde234")); + test(S("abcdefghij"), 5, 5, S("12345"), 1, 4, S("abcde2345")); + test(S("abcdefghij"), 5, 5, S("12345"), 1, 5, S("abcde2345")); + test(S("abcdefghij"), 5, 5, S("12345"), 2, 0, S("abcde")); + test(S("abcdefghij"), 5, 5, S("12345"), 2, 1, S("abcde3")); + test(S("abcdefghij"), 5, 5, S("12345"), 2, 2, S("abcde34")); + test(S("abcdefghij"), 5, 5, S("12345"), 2, 3, S("abcde345")); + test(S("abcdefghij"), 5, 5, S("12345"), 2, 4, S("abcde345")); + test(S("abcdefghij"), 5, 5, S("12345"), 4, 0, S("abcde")); + test(S("abcdefghij"), 5, 5, S("12345"), 4, 1, S("abcde5")); + test(S("abcdefghij"), 5, 5, S("12345"), 4, 2, S("abcde5")); + test(S("abcdefghij"), 5, 5, S("12345"), 5, 0, S("abcde")); + test(S("abcdefghij"), 5, 5, S("12345"), 5, 1, S("abcde")); + test(S("abcdefghij"), 5, 5, S("12345"), 6, 0, S("can't happen")); + test(S("abcdefghij"), 5, 5, S("1234567890"), 0, 0, S("abcde")); + test(S("abcdefghij"), 5, 5, S("1234567890"), 0, 1, S("abcde1")); + test(S("abcdefghij"), 5, 5, S("1234567890"), 0, 5, S("abcde12345")); + test(S("abcdefghij"), 5, 5, S("1234567890"), 0, 9, S("abcde123456789")); + test(S("abcdefghij"), 5, 5, S("1234567890"), 0, 10, S("abcde1234567890")); + test(S("abcdefghij"), 5, 5, S("1234567890"), 0, 11, S("abcde1234567890")); + test(S("abcdefghij"), 5, 5, S("1234567890"), 1, 0, S("abcde")); + test(S("abcdefghij"), 5, 5, S("1234567890"), 1, 1, S("abcde2")); + test(S("abcdefghij"), 5, 5, S("1234567890"), 1, 4, S("abcde2345")); + test(S("abcdefghij"), 5, 5, S("1234567890"), 1, 8, S("abcde23456789")); + test(S("abcdefghij"), 5, 5, S("1234567890"), 1, 9, S("abcde234567890")); + test(S("abcdefghij"), 5, 5, S("1234567890"), 1, 10, S("abcde234567890")); + test(S("abcdefghij"), 5, 5, S("1234567890"), 5, 0, S("abcde")); + test(S("abcdefghij"), 5, 5, S("1234567890"), 5, 1, S("abcde6")); + test(S("abcdefghij"), 5, 5, S("1234567890"), 5, 2, S("abcde67")); + test(S("abcdefghij"), 5, 5, S("1234567890"), 5, 4, S("abcde6789")); + test(S("abcdefghij"), 5, 5, S("1234567890"), 5, 5, S("abcde67890")); + test(S("abcdefghij"), 5, 5, S("1234567890"), 5, 6, S("abcde67890")); + test(S("abcdefghij"), 5, 5, S("1234567890"), 9, 0, S("abcde")); + test(S("abcdefghij"), 5, 5, S("1234567890"), 9, 1, S("abcde0")); + test(S("abcdefghij"), 5, 5, S("1234567890"), 9, 2, S("abcde0")); + test(S("abcdefghij"), 5, 5, S("1234567890"), 10, 0, S("abcde")); + test(S("abcdefghij"), 5, 5, S("1234567890"), 10, 1, S("abcde")); + test(S("abcdefghij"), 5, 5, S("1234567890"), 11, 0, S("can't happen")); + test(S("abcdefghij"), 5, 5, S("12345678901234567890"), 0, 0, S("abcde")); + test(S("abcdefghij"), 5, 5, S("12345678901234567890"), 0, 1, S("abcde1")); + test(S("abcdefghij"), 5, 5, S("12345678901234567890"), 0, 10, S("abcde1234567890")); + test(S("abcdefghij"), 5, 5, S("12345678901234567890"), 0, 19, S("abcde1234567890123456789")); + test(S("abcdefghij"), 5, 5, S("12345678901234567890"), 0, 20, S("abcde12345678901234567890")); + test(S("abcdefghij"), 5, 5, S("12345678901234567890"), 0, 21, S("abcde12345678901234567890")); + test(S("abcdefghij"), 5, 5, S("12345678901234567890"), 1, 0, S("abcde")); + test(S("abcdefghij"), 5, 5, S("12345678901234567890"), 1, 1, S("abcde2")); + test(S("abcdefghij"), 5, 5, S("12345678901234567890"), 1, 9, S("abcde234567890")); + test(S("abcdefghij"), 5, 5, S("12345678901234567890"), 1, 18, S("abcde234567890123456789")); + test(S("abcdefghij"), 5, 5, S("12345678901234567890"), 1, 19, S("abcde2345678901234567890")); + test(S("abcdefghij"), 5, 5, S("12345678901234567890"), 1, 20, S("abcde2345678901234567890")); + test(S("abcdefghij"), 5, 5, S("12345678901234567890"), 10, 0, S("abcde")); + test(S("abcdefghij"), 5, 5, S("12345678901234567890"), 10, 1, S("abcde1")); + test(S("abcdefghij"), 5, 5, S("12345678901234567890"), 10, 5, S("abcde12345")); + test(S("abcdefghij"), 5, 5, S("12345678901234567890"), 10, 9, S("abcde123456789")); + test(S("abcdefghij"), 5, 5, S("12345678901234567890"), 10, 10, S("abcde1234567890")); + test(S("abcdefghij"), 5, 5, S("12345678901234567890"), 10, 11, S("abcde1234567890")); + test(S("abcdefghij"), 5, 5, S("12345678901234567890"), 19, 0, S("abcde")); + test(S("abcdefghij"), 5, 5, S("12345678901234567890"), 19, 1, S("abcde0")); + test(S("abcdefghij"), 5, 5, S("12345678901234567890"), 19, 2, S("abcde0")); + test(S("abcdefghij"), 5, 5, S("12345678901234567890"), 20, 0, S("abcde")); + test(S("abcdefghij"), 5, 5, S("12345678901234567890"), 20, 1, S("abcde")); + test(S("abcdefghij"), 5, 5, S("12345678901234567890"), 21, 0, S("can't happen")); + test(S("abcdefghij"), 5, 6, S(""), 0, 0, S("abcde")); + test(S("abcdefghij"), 5, 6, S(""), 0, 1, S("abcde")); + test(S("abcdefghij"), 5, 6, S(""), 1, 0, S("can't happen")); + test(S("abcdefghij"), 5, 6, S("12345"), 0, 0, S("abcde")); + test(S("abcdefghij"), 5, 6, S("12345"), 0, 1, S("abcde1")); + test(S("abcdefghij"), 5, 6, S("12345"), 0, 2, S("abcde12")); + test(S("abcdefghij"), 5, 6, S("12345"), 0, 4, S("abcde1234")); + test(S("abcdefghij"), 5, 6, S("12345"), 0, 5, S("abcde12345")); + test(S("abcdefghij"), 5, 6, S("12345"), 0, 6, S("abcde12345")); + test(S("abcdefghij"), 5, 6, S("12345"), 1, 0, S("abcde")); + test(S("abcdefghij"), 5, 6, S("12345"), 1, 1, S("abcde2")); + test(S("abcdefghij"), 5, 6, S("12345"), 1, 2, S("abcde23")); + test(S("abcdefghij"), 5, 6, S("12345"), 1, 3, S("abcde234")); + test(S("abcdefghij"), 5, 6, S("12345"), 1, 4, S("abcde2345")); + test(S("abcdefghij"), 5, 6, S("12345"), 1, 5, S("abcde2345")); + test(S("abcdefghij"), 5, 6, S("12345"), 2, 0, S("abcde")); + test(S("abcdefghij"), 5, 6, S("12345"), 2, 1, S("abcde3")); + test(S("abcdefghij"), 5, 6, S("12345"), 2, 2, S("abcde34")); +} + +template +void test32() +{ + test(S("abcdefghij"), 5, 6, S("12345"), 2, 3, S("abcde345")); + test(S("abcdefghij"), 5, 6, S("12345"), 2, 4, S("abcde345")); + test(S("abcdefghij"), 5, 6, S("12345"), 4, 0, S("abcde")); + test(S("abcdefghij"), 5, 6, S("12345"), 4, 1, S("abcde5")); + test(S("abcdefghij"), 5, 6, S("12345"), 4, 2, S("abcde5")); + test(S("abcdefghij"), 5, 6, S("12345"), 5, 0, S("abcde")); + test(S("abcdefghij"), 5, 6, S("12345"), 5, 1, S("abcde")); + test(S("abcdefghij"), 5, 6, S("12345"), 6, 0, S("can't happen")); + test(S("abcdefghij"), 5, 6, S("1234567890"), 0, 0, S("abcde")); + test(S("abcdefghij"), 5, 6, S("1234567890"), 0, 1, S("abcde1")); + test(S("abcdefghij"), 5, 6, S("1234567890"), 0, 5, S("abcde12345")); + test(S("abcdefghij"), 5, 6, S("1234567890"), 0, 9, S("abcde123456789")); + test(S("abcdefghij"), 5, 6, S("1234567890"), 0, 10, S("abcde1234567890")); + test(S("abcdefghij"), 5, 6, S("1234567890"), 0, 11, S("abcde1234567890")); + test(S("abcdefghij"), 5, 6, S("1234567890"), 1, 0, S("abcde")); + test(S("abcdefghij"), 5, 6, S("1234567890"), 1, 1, S("abcde2")); + test(S("abcdefghij"), 5, 6, S("1234567890"), 1, 4, S("abcde2345")); + test(S("abcdefghij"), 5, 6, S("1234567890"), 1, 8, S("abcde23456789")); + test(S("abcdefghij"), 5, 6, S("1234567890"), 1, 9, S("abcde234567890")); + test(S("abcdefghij"), 5, 6, S("1234567890"), 1, 10, S("abcde234567890")); + test(S("abcdefghij"), 5, 6, S("1234567890"), 5, 0, S("abcde")); + test(S("abcdefghij"), 5, 6, S("1234567890"), 5, 1, S("abcde6")); + test(S("abcdefghij"), 5, 6, S("1234567890"), 5, 2, S("abcde67")); + test(S("abcdefghij"), 5, 6, S("1234567890"), 5, 4, S("abcde6789")); + test(S("abcdefghij"), 5, 6, S("1234567890"), 5, 5, S("abcde67890")); + test(S("abcdefghij"), 5, 6, S("1234567890"), 5, 6, S("abcde67890")); + test(S("abcdefghij"), 5, 6, S("1234567890"), 9, 0, S("abcde")); + test(S("abcdefghij"), 5, 6, S("1234567890"), 9, 1, S("abcde0")); + test(S("abcdefghij"), 5, 6, S("1234567890"), 9, 2, S("abcde0")); + test(S("abcdefghij"), 5, 6, S("1234567890"), 10, 0, S("abcde")); + test(S("abcdefghij"), 5, 6, S("1234567890"), 10, 1, S("abcde")); + test(S("abcdefghij"), 5, 6, S("1234567890"), 11, 0, S("can't happen")); + test(S("abcdefghij"), 5, 6, S("12345678901234567890"), 0, 0, S("abcde")); + test(S("abcdefghij"), 5, 6, S("12345678901234567890"), 0, 1, S("abcde1")); + test(S("abcdefghij"), 5, 6, S("12345678901234567890"), 0, 10, S("abcde1234567890")); + test(S("abcdefghij"), 5, 6, S("12345678901234567890"), 0, 19, S("abcde1234567890123456789")); + test(S("abcdefghij"), 5, 6, S("12345678901234567890"), 0, 20, S("abcde12345678901234567890")); + test(S("abcdefghij"), 5, 6, S("12345678901234567890"), 0, 21, S("abcde12345678901234567890")); + test(S("abcdefghij"), 5, 6, S("12345678901234567890"), 1, 0, S("abcde")); + test(S("abcdefghij"), 5, 6, S("12345678901234567890"), 1, 1, S("abcde2")); + test(S("abcdefghij"), 5, 6, S("12345678901234567890"), 1, 9, S("abcde234567890")); + test(S("abcdefghij"), 5, 6, S("12345678901234567890"), 1, 18, S("abcde234567890123456789")); + test(S("abcdefghij"), 5, 6, S("12345678901234567890"), 1, 19, S("abcde2345678901234567890")); + test(S("abcdefghij"), 5, 6, S("12345678901234567890"), 1, 20, S("abcde2345678901234567890")); + test(S("abcdefghij"), 5, 6, S("12345678901234567890"), 10, 0, S("abcde")); + test(S("abcdefghij"), 5, 6, S("12345678901234567890"), 10, 1, S("abcde1")); + test(S("abcdefghij"), 5, 6, S("12345678901234567890"), 10, 5, S("abcde12345")); + test(S("abcdefghij"), 5, 6, S("12345678901234567890"), 10, 9, S("abcde123456789")); + test(S("abcdefghij"), 5, 6, S("12345678901234567890"), 10, 10, S("abcde1234567890")); + test(S("abcdefghij"), 5, 6, S("12345678901234567890"), 10, 11, S("abcde1234567890")); + test(S("abcdefghij"), 5, 6, S("12345678901234567890"), 19, 0, S("abcde")); + test(S("abcdefghij"), 5, 6, S("12345678901234567890"), 19, 1, S("abcde0")); + test(S("abcdefghij"), 5, 6, S("12345678901234567890"), 19, 2, S("abcde0")); + test(S("abcdefghij"), 5, 6, S("12345678901234567890"), 20, 0, S("abcde")); + test(S("abcdefghij"), 5, 6, S("12345678901234567890"), 20, 1, S("abcde")); + test(S("abcdefghij"), 5, 6, S("12345678901234567890"), 21, 0, S("can't happen")); + test(S("abcdefghij"), 9, 0, S(""), 0, 0, S("abcdefghij")); + test(S("abcdefghij"), 9, 0, S(""), 0, 1, S("abcdefghij")); + test(S("abcdefghij"), 9, 0, S(""), 1, 0, S("can't happen")); + test(S("abcdefghij"), 9, 0, S("12345"), 0, 0, S("abcdefghij")); + test(S("abcdefghij"), 9, 0, S("12345"), 0, 1, S("abcdefghi1j")); + test(S("abcdefghij"), 9, 0, S("12345"), 0, 2, S("abcdefghi12j")); + test(S("abcdefghij"), 9, 0, S("12345"), 0, 4, S("abcdefghi1234j")); + test(S("abcdefghij"), 9, 0, S("12345"), 0, 5, S("abcdefghi12345j")); + test(S("abcdefghij"), 9, 0, S("12345"), 0, 6, S("abcdefghi12345j")); + test(S("abcdefghij"), 9, 0, S("12345"), 1, 0, S("abcdefghij")); + test(S("abcdefghij"), 9, 0, S("12345"), 1, 1, S("abcdefghi2j")); + test(S("abcdefghij"), 9, 0, S("12345"), 1, 2, S("abcdefghi23j")); + test(S("abcdefghij"), 9, 0, S("12345"), 1, 3, S("abcdefghi234j")); + test(S("abcdefghij"), 9, 0, S("12345"), 1, 4, S("abcdefghi2345j")); + test(S("abcdefghij"), 9, 0, S("12345"), 1, 5, S("abcdefghi2345j")); + test(S("abcdefghij"), 9, 0, S("12345"), 2, 0, S("abcdefghij")); + test(S("abcdefghij"), 9, 0, S("12345"), 2, 1, S("abcdefghi3j")); + test(S("abcdefghij"), 9, 0, S("12345"), 2, 2, S("abcdefghi34j")); + test(S("abcdefghij"), 9, 0, S("12345"), 2, 3, S("abcdefghi345j")); + test(S("abcdefghij"), 9, 0, S("12345"), 2, 4, S("abcdefghi345j")); + test(S("abcdefghij"), 9, 0, S("12345"), 4, 0, S("abcdefghij")); + test(S("abcdefghij"), 9, 0, S("12345"), 4, 1, S("abcdefghi5j")); + test(S("abcdefghij"), 9, 0, S("12345"), 4, 2, S("abcdefghi5j")); + test(S("abcdefghij"), 9, 0, S("12345"), 5, 0, S("abcdefghij")); + test(S("abcdefghij"), 9, 0, S("12345"), 5, 1, S("abcdefghij")); + test(S("abcdefghij"), 9, 0, S("12345"), 6, 0, S("can't happen")); + test(S("abcdefghij"), 9, 0, S("1234567890"), 0, 0, S("abcdefghij")); + test(S("abcdefghij"), 9, 0, S("1234567890"), 0, 1, S("abcdefghi1j")); + test(S("abcdefghij"), 9, 0, S("1234567890"), 0, 5, S("abcdefghi12345j")); + test(S("abcdefghij"), 9, 0, S("1234567890"), 0, 9, S("abcdefghi123456789j")); + test(S("abcdefghij"), 9, 0, S("1234567890"), 0, 10, S("abcdefghi1234567890j")); + test(S("abcdefghij"), 9, 0, S("1234567890"), 0, 11, S("abcdefghi1234567890j")); + test(S("abcdefghij"), 9, 0, S("1234567890"), 1, 0, S("abcdefghij")); + test(S("abcdefghij"), 9, 0, S("1234567890"), 1, 1, S("abcdefghi2j")); + test(S("abcdefghij"), 9, 0, S("1234567890"), 1, 4, S("abcdefghi2345j")); + test(S("abcdefghij"), 9, 0, S("1234567890"), 1, 8, S("abcdefghi23456789j")); + test(S("abcdefghij"), 9, 0, S("1234567890"), 1, 9, S("abcdefghi234567890j")); + test(S("abcdefghij"), 9, 0, S("1234567890"), 1, 10, S("abcdefghi234567890j")); + test(S("abcdefghij"), 9, 0, S("1234567890"), 5, 0, S("abcdefghij")); + test(S("abcdefghij"), 9, 0, S("1234567890"), 5, 1, S("abcdefghi6j")); + test(S("abcdefghij"), 9, 0, S("1234567890"), 5, 2, S("abcdefghi67j")); + test(S("abcdefghij"), 9, 0, S("1234567890"), 5, 4, S("abcdefghi6789j")); + test(S("abcdefghij"), 9, 0, S("1234567890"), 5, 5, S("abcdefghi67890j")); + test(S("abcdefghij"), 9, 0, S("1234567890"), 5, 6, S("abcdefghi67890j")); +} + +template +void test33() +{ + test(S("abcdefghij"), 9, 0, S("1234567890"), 9, 0, S("abcdefghij")); + test(S("abcdefghij"), 9, 0, S("1234567890"), 9, 1, S("abcdefghi0j")); + test(S("abcdefghij"), 9, 0, S("1234567890"), 9, 2, S("abcdefghi0j")); + test(S("abcdefghij"), 9, 0, S("1234567890"), 10, 0, S("abcdefghij")); + test(S("abcdefghij"), 9, 0, S("1234567890"), 10, 1, S("abcdefghij")); + test(S("abcdefghij"), 9, 0, S("1234567890"), 11, 0, S("can't happen")); + test(S("abcdefghij"), 9, 0, S("12345678901234567890"), 0, 0, S("abcdefghij")); + test(S("abcdefghij"), 9, 0, S("12345678901234567890"), 0, 1, S("abcdefghi1j")); + test(S("abcdefghij"), 9, 0, S("12345678901234567890"), 0, 10, S("abcdefghi1234567890j")); + test(S("abcdefghij"), 9, 0, S("12345678901234567890"), 0, 19, S("abcdefghi1234567890123456789j")); + test(S("abcdefghij"), 9, 0, S("12345678901234567890"), 0, 20, S("abcdefghi12345678901234567890j")); + test(S("abcdefghij"), 9, 0, S("12345678901234567890"), 0, 21, S("abcdefghi12345678901234567890j")); + test(S("abcdefghij"), 9, 0, S("12345678901234567890"), 1, 0, S("abcdefghij")); + test(S("abcdefghij"), 9, 0, S("12345678901234567890"), 1, 1, S("abcdefghi2j")); + test(S("abcdefghij"), 9, 0, S("12345678901234567890"), 1, 9, S("abcdefghi234567890j")); + test(S("abcdefghij"), 9, 0, S("12345678901234567890"), 1, 18, S("abcdefghi234567890123456789j")); + test(S("abcdefghij"), 9, 0, S("12345678901234567890"), 1, 19, S("abcdefghi2345678901234567890j")); + test(S("abcdefghij"), 9, 0, S("12345678901234567890"), 1, 20, S("abcdefghi2345678901234567890j")); + test(S("abcdefghij"), 9, 0, S("12345678901234567890"), 10, 0, S("abcdefghij")); + test(S("abcdefghij"), 9, 0, S("12345678901234567890"), 10, 1, S("abcdefghi1j")); + test(S("abcdefghij"), 9, 0, S("12345678901234567890"), 10, 5, S("abcdefghi12345j")); + test(S("abcdefghij"), 9, 0, S("12345678901234567890"), 10, 9, S("abcdefghi123456789j")); + test(S("abcdefghij"), 9, 0, S("12345678901234567890"), 10, 10, S("abcdefghi1234567890j")); + test(S("abcdefghij"), 9, 0, S("12345678901234567890"), 10, 11, S("abcdefghi1234567890j")); + test(S("abcdefghij"), 9, 0, S("12345678901234567890"), 19, 0, S("abcdefghij")); + test(S("abcdefghij"), 9, 0, S("12345678901234567890"), 19, 1, S("abcdefghi0j")); + test(S("abcdefghij"), 9, 0, S("12345678901234567890"), 19, 2, S("abcdefghi0j")); + test(S("abcdefghij"), 9, 0, S("12345678901234567890"), 20, 0, S("abcdefghij")); + test(S("abcdefghij"), 9, 0, S("12345678901234567890"), 20, 1, S("abcdefghij")); + test(S("abcdefghij"), 9, 0, S("12345678901234567890"), 21, 0, S("can't happen")); + test(S("abcdefghij"), 9, 1, S(""), 0, 0, S("abcdefghi")); + test(S("abcdefghij"), 9, 1, S(""), 0, 1, S("abcdefghi")); + test(S("abcdefghij"), 9, 1, S(""), 1, 0, S("can't happen")); + test(S("abcdefghij"), 9, 1, S("12345"), 0, 0, S("abcdefghi")); + test(S("abcdefghij"), 9, 1, S("12345"), 0, 1, S("abcdefghi1")); + test(S("abcdefghij"), 9, 1, S("12345"), 0, 2, S("abcdefghi12")); + test(S("abcdefghij"), 9, 1, S("12345"), 0, 4, S("abcdefghi1234")); + test(S("abcdefghij"), 9, 1, S("12345"), 0, 5, S("abcdefghi12345")); + test(S("abcdefghij"), 9, 1, S("12345"), 0, 6, S("abcdefghi12345")); + test(S("abcdefghij"), 9, 1, S("12345"), 1, 0, S("abcdefghi")); + test(S("abcdefghij"), 9, 1, S("12345"), 1, 1, S("abcdefghi2")); + test(S("abcdefghij"), 9, 1, S("12345"), 1, 2, S("abcdefghi23")); + test(S("abcdefghij"), 9, 1, S("12345"), 1, 3, S("abcdefghi234")); + test(S("abcdefghij"), 9, 1, S("12345"), 1, 4, S("abcdefghi2345")); + test(S("abcdefghij"), 9, 1, S("12345"), 1, 5, S("abcdefghi2345")); + test(S("abcdefghij"), 9, 1, S("12345"), 2, 0, S("abcdefghi")); + test(S("abcdefghij"), 9, 1, S("12345"), 2, 1, S("abcdefghi3")); + test(S("abcdefghij"), 9, 1, S("12345"), 2, 2, S("abcdefghi34")); + test(S("abcdefghij"), 9, 1, S("12345"), 2, 3, S("abcdefghi345")); + test(S("abcdefghij"), 9, 1, S("12345"), 2, 4, S("abcdefghi345")); + test(S("abcdefghij"), 9, 1, S("12345"), 4, 0, S("abcdefghi")); + test(S("abcdefghij"), 9, 1, S("12345"), 4, 1, S("abcdefghi5")); + test(S("abcdefghij"), 9, 1, S("12345"), 4, 2, S("abcdefghi5")); + test(S("abcdefghij"), 9, 1, S("12345"), 5, 0, S("abcdefghi")); + test(S("abcdefghij"), 9, 1, S("12345"), 5, 1, S("abcdefghi")); + test(S("abcdefghij"), 9, 1, S("12345"), 6, 0, S("can't happen")); + test(S("abcdefghij"), 9, 1, S("1234567890"), 0, 0, S("abcdefghi")); + test(S("abcdefghij"), 9, 1, S("1234567890"), 0, 1, S("abcdefghi1")); + test(S("abcdefghij"), 9, 1, S("1234567890"), 0, 5, S("abcdefghi12345")); + test(S("abcdefghij"), 9, 1, S("1234567890"), 0, 9, S("abcdefghi123456789")); + test(S("abcdefghij"), 9, 1, S("1234567890"), 0, 10, S("abcdefghi1234567890")); + test(S("abcdefghij"), 9, 1, S("1234567890"), 0, 11, S("abcdefghi1234567890")); + test(S("abcdefghij"), 9, 1, S("1234567890"), 1, 0, S("abcdefghi")); + test(S("abcdefghij"), 9, 1, S("1234567890"), 1, 1, S("abcdefghi2")); + test(S("abcdefghij"), 9, 1, S("1234567890"), 1, 4, S("abcdefghi2345")); + test(S("abcdefghij"), 9, 1, S("1234567890"), 1, 8, S("abcdefghi23456789")); + test(S("abcdefghij"), 9, 1, S("1234567890"), 1, 9, S("abcdefghi234567890")); + test(S("abcdefghij"), 9, 1, S("1234567890"), 1, 10, S("abcdefghi234567890")); + test(S("abcdefghij"), 9, 1, S("1234567890"), 5, 0, S("abcdefghi")); + test(S("abcdefghij"), 9, 1, S("1234567890"), 5, 1, S("abcdefghi6")); + test(S("abcdefghij"), 9, 1, S("1234567890"), 5, 2, S("abcdefghi67")); + test(S("abcdefghij"), 9, 1, S("1234567890"), 5, 4, S("abcdefghi6789")); + test(S("abcdefghij"), 9, 1, S("1234567890"), 5, 5, S("abcdefghi67890")); + test(S("abcdefghij"), 9, 1, S("1234567890"), 5, 6, S("abcdefghi67890")); + test(S("abcdefghij"), 9, 1, S("1234567890"), 9, 0, S("abcdefghi")); + test(S("abcdefghij"), 9, 1, S("1234567890"), 9, 1, S("abcdefghi0")); + test(S("abcdefghij"), 9, 1, S("1234567890"), 9, 2, S("abcdefghi0")); + test(S("abcdefghij"), 9, 1, S("1234567890"), 10, 0, S("abcdefghi")); + test(S("abcdefghij"), 9, 1, S("1234567890"), 10, 1, S("abcdefghi")); + test(S("abcdefghij"), 9, 1, S("1234567890"), 11, 0, S("can't happen")); + test(S("abcdefghij"), 9, 1, S("12345678901234567890"), 0, 0, S("abcdefghi")); + test(S("abcdefghij"), 9, 1, S("12345678901234567890"), 0, 1, S("abcdefghi1")); + test(S("abcdefghij"), 9, 1, S("12345678901234567890"), 0, 10, S("abcdefghi1234567890")); + test(S("abcdefghij"), 9, 1, S("12345678901234567890"), 0, 19, S("abcdefghi1234567890123456789")); + test(S("abcdefghij"), 9, 1, S("12345678901234567890"), 0, 20, S("abcdefghi12345678901234567890")); + test(S("abcdefghij"), 9, 1, S("12345678901234567890"), 0, 21, S("abcdefghi12345678901234567890")); + test(S("abcdefghij"), 9, 1, S("12345678901234567890"), 1, 0, S("abcdefghi")); + test(S("abcdefghij"), 9, 1, S("12345678901234567890"), 1, 1, S("abcdefghi2")); + test(S("abcdefghij"), 9, 1, S("12345678901234567890"), 1, 9, S("abcdefghi234567890")); + test(S("abcdefghij"), 9, 1, S("12345678901234567890"), 1, 18, S("abcdefghi234567890123456789")); + test(S("abcdefghij"), 9, 1, S("12345678901234567890"), 1, 19, S("abcdefghi2345678901234567890")); + test(S("abcdefghij"), 9, 1, S("12345678901234567890"), 1, 20, S("abcdefghi2345678901234567890")); + test(S("abcdefghij"), 9, 1, S("12345678901234567890"), 10, 0, S("abcdefghi")); + test(S("abcdefghij"), 9, 1, S("12345678901234567890"), 10, 1, S("abcdefghi1")); + test(S("abcdefghij"), 9, 1, S("12345678901234567890"), 10, 5, S("abcdefghi12345")); + test(S("abcdefghij"), 9, 1, S("12345678901234567890"), 10, 9, S("abcdefghi123456789")); + test(S("abcdefghij"), 9, 1, S("12345678901234567890"), 10, 10, S("abcdefghi1234567890")); + test(S("abcdefghij"), 9, 1, S("12345678901234567890"), 10, 11, S("abcdefghi1234567890")); + test(S("abcdefghij"), 9, 1, S("12345678901234567890"), 19, 0, S("abcdefghi")); + test(S("abcdefghij"), 9, 1, S("12345678901234567890"), 19, 1, S("abcdefghi0")); +} + +template +void test34() +{ + test(S("abcdefghij"), 9, 1, S("12345678901234567890"), 19, 2, S("abcdefghi0")); + test(S("abcdefghij"), 9, 1, S("12345678901234567890"), 20, 0, S("abcdefghi")); + test(S("abcdefghij"), 9, 1, S("12345678901234567890"), 20, 1, S("abcdefghi")); + test(S("abcdefghij"), 9, 1, S("12345678901234567890"), 21, 0, S("can't happen")); + test(S("abcdefghij"), 9, 2, S(""), 0, 0, S("abcdefghi")); + test(S("abcdefghij"), 9, 2, S(""), 0, 1, S("abcdefghi")); + test(S("abcdefghij"), 9, 2, S(""), 1, 0, S("can't happen")); + test(S("abcdefghij"), 9, 2, S("12345"), 0, 0, S("abcdefghi")); + test(S("abcdefghij"), 9, 2, S("12345"), 0, 1, S("abcdefghi1")); + test(S("abcdefghij"), 9, 2, S("12345"), 0, 2, S("abcdefghi12")); + test(S("abcdefghij"), 9, 2, S("12345"), 0, 4, S("abcdefghi1234")); + test(S("abcdefghij"), 9, 2, S("12345"), 0, 5, S("abcdefghi12345")); + test(S("abcdefghij"), 9, 2, S("12345"), 0, 6, S("abcdefghi12345")); + test(S("abcdefghij"), 9, 2, S("12345"), 1, 0, S("abcdefghi")); + test(S("abcdefghij"), 9, 2, S("12345"), 1, 1, S("abcdefghi2")); + test(S("abcdefghij"), 9, 2, S("12345"), 1, 2, S("abcdefghi23")); + test(S("abcdefghij"), 9, 2, S("12345"), 1, 3, S("abcdefghi234")); + test(S("abcdefghij"), 9, 2, S("12345"), 1, 4, S("abcdefghi2345")); + test(S("abcdefghij"), 9, 2, S("12345"), 1, 5, S("abcdefghi2345")); + test(S("abcdefghij"), 9, 2, S("12345"), 2, 0, S("abcdefghi")); + test(S("abcdefghij"), 9, 2, S("12345"), 2, 1, S("abcdefghi3")); + test(S("abcdefghij"), 9, 2, S("12345"), 2, 2, S("abcdefghi34")); + test(S("abcdefghij"), 9, 2, S("12345"), 2, 3, S("abcdefghi345")); + test(S("abcdefghij"), 9, 2, S("12345"), 2, 4, S("abcdefghi345")); + test(S("abcdefghij"), 9, 2, S("12345"), 4, 0, S("abcdefghi")); + test(S("abcdefghij"), 9, 2, S("12345"), 4, 1, S("abcdefghi5")); + test(S("abcdefghij"), 9, 2, S("12345"), 4, 2, S("abcdefghi5")); + test(S("abcdefghij"), 9, 2, S("12345"), 5, 0, S("abcdefghi")); + test(S("abcdefghij"), 9, 2, S("12345"), 5, 1, S("abcdefghi")); + test(S("abcdefghij"), 9, 2, S("12345"), 6, 0, S("can't happen")); + test(S("abcdefghij"), 9, 2, S("1234567890"), 0, 0, S("abcdefghi")); + test(S("abcdefghij"), 9, 2, S("1234567890"), 0, 1, S("abcdefghi1")); + test(S("abcdefghij"), 9, 2, S("1234567890"), 0, 5, S("abcdefghi12345")); + test(S("abcdefghij"), 9, 2, S("1234567890"), 0, 9, S("abcdefghi123456789")); + test(S("abcdefghij"), 9, 2, S("1234567890"), 0, 10, S("abcdefghi1234567890")); + test(S("abcdefghij"), 9, 2, S("1234567890"), 0, 11, S("abcdefghi1234567890")); + test(S("abcdefghij"), 9, 2, S("1234567890"), 1, 0, S("abcdefghi")); + test(S("abcdefghij"), 9, 2, S("1234567890"), 1, 1, S("abcdefghi2")); + test(S("abcdefghij"), 9, 2, S("1234567890"), 1, 4, S("abcdefghi2345")); + test(S("abcdefghij"), 9, 2, S("1234567890"), 1, 8, S("abcdefghi23456789")); + test(S("abcdefghij"), 9, 2, S("1234567890"), 1, 9, S("abcdefghi234567890")); + test(S("abcdefghij"), 9, 2, S("1234567890"), 1, 10, S("abcdefghi234567890")); + test(S("abcdefghij"), 9, 2, S("1234567890"), 5, 0, S("abcdefghi")); + test(S("abcdefghij"), 9, 2, S("1234567890"), 5, 1, S("abcdefghi6")); + test(S("abcdefghij"), 9, 2, S("1234567890"), 5, 2, S("abcdefghi67")); + test(S("abcdefghij"), 9, 2, S("1234567890"), 5, 4, S("abcdefghi6789")); + test(S("abcdefghij"), 9, 2, S("1234567890"), 5, 5, S("abcdefghi67890")); + test(S("abcdefghij"), 9, 2, S("1234567890"), 5, 6, S("abcdefghi67890")); + test(S("abcdefghij"), 9, 2, S("1234567890"), 9, 0, S("abcdefghi")); + test(S("abcdefghij"), 9, 2, S("1234567890"), 9, 1, S("abcdefghi0")); + test(S("abcdefghij"), 9, 2, S("1234567890"), 9, 2, S("abcdefghi0")); + test(S("abcdefghij"), 9, 2, S("1234567890"), 10, 0, S("abcdefghi")); + test(S("abcdefghij"), 9, 2, S("1234567890"), 10, 1, S("abcdefghi")); + test(S("abcdefghij"), 9, 2, S("1234567890"), 11, 0, S("can't happen")); + test(S("abcdefghij"), 9, 2, S("12345678901234567890"), 0, 0, S("abcdefghi")); + test(S("abcdefghij"), 9, 2, S("12345678901234567890"), 0, 1, S("abcdefghi1")); + test(S("abcdefghij"), 9, 2, S("12345678901234567890"), 0, 10, S("abcdefghi1234567890")); + test(S("abcdefghij"), 9, 2, S("12345678901234567890"), 0, 19, S("abcdefghi1234567890123456789")); + test(S("abcdefghij"), 9, 2, S("12345678901234567890"), 0, 20, S("abcdefghi12345678901234567890")); + test(S("abcdefghij"), 9, 2, S("12345678901234567890"), 0, 21, S("abcdefghi12345678901234567890")); + test(S("abcdefghij"), 9, 2, S("12345678901234567890"), 1, 0, S("abcdefghi")); + test(S("abcdefghij"), 9, 2, S("12345678901234567890"), 1, 1, S("abcdefghi2")); + test(S("abcdefghij"), 9, 2, S("12345678901234567890"), 1, 9, S("abcdefghi234567890")); + test(S("abcdefghij"), 9, 2, S("12345678901234567890"), 1, 18, S("abcdefghi234567890123456789")); + test(S("abcdefghij"), 9, 2, S("12345678901234567890"), 1, 19, S("abcdefghi2345678901234567890")); + test(S("abcdefghij"), 9, 2, S("12345678901234567890"), 1, 20, S("abcdefghi2345678901234567890")); + test(S("abcdefghij"), 9, 2, S("12345678901234567890"), 10, 0, S("abcdefghi")); + test(S("abcdefghij"), 9, 2, S("12345678901234567890"), 10, 1, S("abcdefghi1")); + test(S("abcdefghij"), 9, 2, S("12345678901234567890"), 10, 5, S("abcdefghi12345")); + test(S("abcdefghij"), 9, 2, S("12345678901234567890"), 10, 9, S("abcdefghi123456789")); + test(S("abcdefghij"), 9, 2, S("12345678901234567890"), 10, 10, S("abcdefghi1234567890")); + test(S("abcdefghij"), 9, 2, S("12345678901234567890"), 10, 11, S("abcdefghi1234567890")); + test(S("abcdefghij"), 9, 2, S("12345678901234567890"), 19, 0, S("abcdefghi")); + test(S("abcdefghij"), 9, 2, S("12345678901234567890"), 19, 1, S("abcdefghi0")); + test(S("abcdefghij"), 9, 2, S("12345678901234567890"), 19, 2, S("abcdefghi0")); + test(S("abcdefghij"), 9, 2, S("12345678901234567890"), 20, 0, S("abcdefghi")); + test(S("abcdefghij"), 9, 2, S("12345678901234567890"), 20, 1, S("abcdefghi")); + test(S("abcdefghij"), 9, 2, S("12345678901234567890"), 21, 0, S("can't happen")); + test(S("abcdefghij"), 10, 0, S(""), 0, 0, S("abcdefghij")); + test(S("abcdefghij"), 10, 0, S(""), 0, 1, S("abcdefghij")); + test(S("abcdefghij"), 10, 0, S(""), 1, 0, S("can't happen")); + test(S("abcdefghij"), 10, 0, S("12345"), 0, 0, S("abcdefghij")); + test(S("abcdefghij"), 10, 0, S("12345"), 0, 1, S("abcdefghij1")); + test(S("abcdefghij"), 10, 0, S("12345"), 0, 2, S("abcdefghij12")); + test(S("abcdefghij"), 10, 0, S("12345"), 0, 4, S("abcdefghij1234")); + test(S("abcdefghij"), 10, 0, S("12345"), 0, 5, S("abcdefghij12345")); + test(S("abcdefghij"), 10, 0, S("12345"), 0, 6, S("abcdefghij12345")); + test(S("abcdefghij"), 10, 0, S("12345"), 1, 0, S("abcdefghij")); + test(S("abcdefghij"), 10, 0, S("12345"), 1, 1, S("abcdefghij2")); + test(S("abcdefghij"), 10, 0, S("12345"), 1, 2, S("abcdefghij23")); + test(S("abcdefghij"), 10, 0, S("12345"), 1, 3, S("abcdefghij234")); + test(S("abcdefghij"), 10, 0, S("12345"), 1, 4, S("abcdefghij2345")); + test(S("abcdefghij"), 10, 0, S("12345"), 1, 5, S("abcdefghij2345")); + test(S("abcdefghij"), 10, 0, S("12345"), 2, 0, S("abcdefghij")); + test(S("abcdefghij"), 10, 0, S("12345"), 2, 1, S("abcdefghij3")); + test(S("abcdefghij"), 10, 0, S("12345"), 2, 2, S("abcdefghij34")); + test(S("abcdefghij"), 10, 0, S("12345"), 2, 3, S("abcdefghij345")); + test(S("abcdefghij"), 10, 0, S("12345"), 2, 4, S("abcdefghij345")); + test(S("abcdefghij"), 10, 0, S("12345"), 4, 0, S("abcdefghij")); + test(S("abcdefghij"), 10, 0, S("12345"), 4, 1, S("abcdefghij5")); +} + +template +void test35() +{ + test(S("abcdefghij"), 10, 0, S("12345"), 4, 2, S("abcdefghij5")); + test(S("abcdefghij"), 10, 0, S("12345"), 5, 0, S("abcdefghij")); + test(S("abcdefghij"), 10, 0, S("12345"), 5, 1, S("abcdefghij")); + test(S("abcdefghij"), 10, 0, S("12345"), 6, 0, S("can't happen")); + test(S("abcdefghij"), 10, 0, S("1234567890"), 0, 0, S("abcdefghij")); + test(S("abcdefghij"), 10, 0, S("1234567890"), 0, 1, S("abcdefghij1")); + test(S("abcdefghij"), 10, 0, S("1234567890"), 0, 5, S("abcdefghij12345")); + test(S("abcdefghij"), 10, 0, S("1234567890"), 0, 9, S("abcdefghij123456789")); + test(S("abcdefghij"), 10, 0, S("1234567890"), 0, 10, S("abcdefghij1234567890")); + test(S("abcdefghij"), 10, 0, S("1234567890"), 0, 11, S("abcdefghij1234567890")); + test(S("abcdefghij"), 10, 0, S("1234567890"), 1, 0, S("abcdefghij")); + test(S("abcdefghij"), 10, 0, S("1234567890"), 1, 1, S("abcdefghij2")); + test(S("abcdefghij"), 10, 0, S("1234567890"), 1, 4, S("abcdefghij2345")); + test(S("abcdefghij"), 10, 0, S("1234567890"), 1, 8, S("abcdefghij23456789")); + test(S("abcdefghij"), 10, 0, S("1234567890"), 1, 9, S("abcdefghij234567890")); + test(S("abcdefghij"), 10, 0, S("1234567890"), 1, 10, S("abcdefghij234567890")); + test(S("abcdefghij"), 10, 0, S("1234567890"), 5, 0, S("abcdefghij")); + test(S("abcdefghij"), 10, 0, S("1234567890"), 5, 1, S("abcdefghij6")); + test(S("abcdefghij"), 10, 0, S("1234567890"), 5, 2, S("abcdefghij67")); + test(S("abcdefghij"), 10, 0, S("1234567890"), 5, 4, S("abcdefghij6789")); + test(S("abcdefghij"), 10, 0, S("1234567890"), 5, 5, S("abcdefghij67890")); + test(S("abcdefghij"), 10, 0, S("1234567890"), 5, 6, S("abcdefghij67890")); + test(S("abcdefghij"), 10, 0, S("1234567890"), 9, 0, S("abcdefghij")); + test(S("abcdefghij"), 10, 0, S("1234567890"), 9, 1, S("abcdefghij0")); + test(S("abcdefghij"), 10, 0, S("1234567890"), 9, 2, S("abcdefghij0")); + test(S("abcdefghij"), 10, 0, S("1234567890"), 10, 0, S("abcdefghij")); + test(S("abcdefghij"), 10, 0, S("1234567890"), 10, 1, S("abcdefghij")); + test(S("abcdefghij"), 10, 0, S("1234567890"), 11, 0, S("can't happen")); + test(S("abcdefghij"), 10, 0, S("12345678901234567890"), 0, 0, S("abcdefghij")); + test(S("abcdefghij"), 10, 0, S("12345678901234567890"), 0, 1, S("abcdefghij1")); + test(S("abcdefghij"), 10, 0, S("12345678901234567890"), 0, 10, S("abcdefghij1234567890")); + test(S("abcdefghij"), 10, 0, S("12345678901234567890"), 0, 19, S("abcdefghij1234567890123456789")); + test(S("abcdefghij"), 10, 0, S("12345678901234567890"), 0, 20, S("abcdefghij12345678901234567890")); + test(S("abcdefghij"), 10, 0, S("12345678901234567890"), 0, 21, S("abcdefghij12345678901234567890")); + test(S("abcdefghij"), 10, 0, S("12345678901234567890"), 1, 0, S("abcdefghij")); + test(S("abcdefghij"), 10, 0, S("12345678901234567890"), 1, 1, S("abcdefghij2")); + test(S("abcdefghij"), 10, 0, S("12345678901234567890"), 1, 9, S("abcdefghij234567890")); + test(S("abcdefghij"), 10, 0, S("12345678901234567890"), 1, 18, S("abcdefghij234567890123456789")); + test(S("abcdefghij"), 10, 0, S("12345678901234567890"), 1, 19, S("abcdefghij2345678901234567890")); + test(S("abcdefghij"), 10, 0, S("12345678901234567890"), 1, 20, S("abcdefghij2345678901234567890")); + test(S("abcdefghij"), 10, 0, S("12345678901234567890"), 10, 0, S("abcdefghij")); + test(S("abcdefghij"), 10, 0, S("12345678901234567890"), 10, 1, S("abcdefghij1")); + test(S("abcdefghij"), 10, 0, S("12345678901234567890"), 10, 5, S("abcdefghij12345")); + test(S("abcdefghij"), 10, 0, S("12345678901234567890"), 10, 9, S("abcdefghij123456789")); + test(S("abcdefghij"), 10, 0, S("12345678901234567890"), 10, 10, S("abcdefghij1234567890")); + test(S("abcdefghij"), 10, 0, S("12345678901234567890"), 10, 11, S("abcdefghij1234567890")); + test(S("abcdefghij"), 10, 0, S("12345678901234567890"), 19, 0, S("abcdefghij")); + test(S("abcdefghij"), 10, 0, S("12345678901234567890"), 19, 1, S("abcdefghij0")); + test(S("abcdefghij"), 10, 0, S("12345678901234567890"), 19, 2, S("abcdefghij0")); + test(S("abcdefghij"), 10, 0, S("12345678901234567890"), 20, 0, S("abcdefghij")); + test(S("abcdefghij"), 10, 0, S("12345678901234567890"), 20, 1, S("abcdefghij")); + test(S("abcdefghij"), 10, 0, S("12345678901234567890"), 21, 0, S("can't happen")); + test(S("abcdefghij"), 10, 1, S(""), 0, 0, S("abcdefghij")); + test(S("abcdefghij"), 10, 1, S(""), 0, 1, S("abcdefghij")); + test(S("abcdefghij"), 10, 1, S(""), 1, 0, S("can't happen")); + test(S("abcdefghij"), 10, 1, S("12345"), 0, 0, S("abcdefghij")); + test(S("abcdefghij"), 10, 1, S("12345"), 0, 1, S("abcdefghij1")); + test(S("abcdefghij"), 10, 1, S("12345"), 0, 2, S("abcdefghij12")); + test(S("abcdefghij"), 10, 1, S("12345"), 0, 4, S("abcdefghij1234")); + test(S("abcdefghij"), 10, 1, S("12345"), 0, 5, S("abcdefghij12345")); + test(S("abcdefghij"), 10, 1, S("12345"), 0, 6, S("abcdefghij12345")); + test(S("abcdefghij"), 10, 1, S("12345"), 1, 0, S("abcdefghij")); + test(S("abcdefghij"), 10, 1, S("12345"), 1, 1, S("abcdefghij2")); + test(S("abcdefghij"), 10, 1, S("12345"), 1, 2, S("abcdefghij23")); + test(S("abcdefghij"), 10, 1, S("12345"), 1, 3, S("abcdefghij234")); + test(S("abcdefghij"), 10, 1, S("12345"), 1, 4, S("abcdefghij2345")); + test(S("abcdefghij"), 10, 1, S("12345"), 1, 5, S("abcdefghij2345")); + test(S("abcdefghij"), 10, 1, S("12345"), 2, 0, S("abcdefghij")); + test(S("abcdefghij"), 10, 1, S("12345"), 2, 1, S("abcdefghij3")); + test(S("abcdefghij"), 10, 1, S("12345"), 2, 2, S("abcdefghij34")); + test(S("abcdefghij"), 10, 1, S("12345"), 2, 3, S("abcdefghij345")); + test(S("abcdefghij"), 10, 1, S("12345"), 2, 4, S("abcdefghij345")); + test(S("abcdefghij"), 10, 1, S("12345"), 4, 0, S("abcdefghij")); + test(S("abcdefghij"), 10, 1, S("12345"), 4, 1, S("abcdefghij5")); + test(S("abcdefghij"), 10, 1, S("12345"), 4, 2, S("abcdefghij5")); + test(S("abcdefghij"), 10, 1, S("12345"), 5, 0, S("abcdefghij")); + test(S("abcdefghij"), 10, 1, S("12345"), 5, 1, S("abcdefghij")); + test(S("abcdefghij"), 10, 1, S("12345"), 6, 0, S("can't happen")); + test(S("abcdefghij"), 10, 1, S("1234567890"), 0, 0, S("abcdefghij")); + test(S("abcdefghij"), 10, 1, S("1234567890"), 0, 1, S("abcdefghij1")); + test(S("abcdefghij"), 10, 1, S("1234567890"), 0, 5, S("abcdefghij12345")); + test(S("abcdefghij"), 10, 1, S("1234567890"), 0, 9, S("abcdefghij123456789")); + test(S("abcdefghij"), 10, 1, S("1234567890"), 0, 10, S("abcdefghij1234567890")); + test(S("abcdefghij"), 10, 1, S("1234567890"), 0, 11, S("abcdefghij1234567890")); + test(S("abcdefghij"), 10, 1, S("1234567890"), 1, 0, S("abcdefghij")); + test(S("abcdefghij"), 10, 1, S("1234567890"), 1, 1, S("abcdefghij2")); + test(S("abcdefghij"), 10, 1, S("1234567890"), 1, 4, S("abcdefghij2345")); + test(S("abcdefghij"), 10, 1, S("1234567890"), 1, 8, S("abcdefghij23456789")); + test(S("abcdefghij"), 10, 1, S("1234567890"), 1, 9, S("abcdefghij234567890")); + test(S("abcdefghij"), 10, 1, S("1234567890"), 1, 10, S("abcdefghij234567890")); + test(S("abcdefghij"), 10, 1, S("1234567890"), 5, 0, S("abcdefghij")); + test(S("abcdefghij"), 10, 1, S("1234567890"), 5, 1, S("abcdefghij6")); + test(S("abcdefghij"), 10, 1, S("1234567890"), 5, 2, S("abcdefghij67")); + test(S("abcdefghij"), 10, 1, S("1234567890"), 5, 4, S("abcdefghij6789")); + test(S("abcdefghij"), 10, 1, S("1234567890"), 5, 5, S("abcdefghij67890")); + test(S("abcdefghij"), 10, 1, S("1234567890"), 5, 6, S("abcdefghij67890")); + test(S("abcdefghij"), 10, 1, S("1234567890"), 9, 0, S("abcdefghij")); + test(S("abcdefghij"), 10, 1, S("1234567890"), 9, 1, S("abcdefghij0")); + test(S("abcdefghij"), 10, 1, S("1234567890"), 9, 2, S("abcdefghij0")); + test(S("abcdefghij"), 10, 1, S("1234567890"), 10, 0, S("abcdefghij")); +} + +template +void test36() +{ + test(S("abcdefghij"), 10, 1, S("1234567890"), 10, 1, S("abcdefghij")); + test(S("abcdefghij"), 10, 1, S("1234567890"), 11, 0, S("can't happen")); + test(S("abcdefghij"), 10, 1, S("12345678901234567890"), 0, 0, S("abcdefghij")); + test(S("abcdefghij"), 10, 1, S("12345678901234567890"), 0, 1, S("abcdefghij1")); + test(S("abcdefghij"), 10, 1, S("12345678901234567890"), 0, 10, S("abcdefghij1234567890")); + test(S("abcdefghij"), 10, 1, S("12345678901234567890"), 0, 19, S("abcdefghij1234567890123456789")); + test(S("abcdefghij"), 10, 1, S("12345678901234567890"), 0, 20, S("abcdefghij12345678901234567890")); + test(S("abcdefghij"), 10, 1, S("12345678901234567890"), 0, 21, S("abcdefghij12345678901234567890")); + test(S("abcdefghij"), 10, 1, S("12345678901234567890"), 1, 0, S("abcdefghij")); + test(S("abcdefghij"), 10, 1, S("12345678901234567890"), 1, 1, S("abcdefghij2")); + test(S("abcdefghij"), 10, 1, S("12345678901234567890"), 1, 9, S("abcdefghij234567890")); + test(S("abcdefghij"), 10, 1, S("12345678901234567890"), 1, 18, S("abcdefghij234567890123456789")); + test(S("abcdefghij"), 10, 1, S("12345678901234567890"), 1, 19, S("abcdefghij2345678901234567890")); + test(S("abcdefghij"), 10, 1, S("12345678901234567890"), 1, 20, S("abcdefghij2345678901234567890")); + test(S("abcdefghij"), 10, 1, S("12345678901234567890"), 10, 0, S("abcdefghij")); + test(S("abcdefghij"), 10, 1, S("12345678901234567890"), 10, 1, S("abcdefghij1")); + test(S("abcdefghij"), 10, 1, S("12345678901234567890"), 10, 5, S("abcdefghij12345")); + test(S("abcdefghij"), 10, 1, S("12345678901234567890"), 10, 9, S("abcdefghij123456789")); + test(S("abcdefghij"), 10, 1, S("12345678901234567890"), 10, 10, S("abcdefghij1234567890")); + test(S("abcdefghij"), 10, 1, S("12345678901234567890"), 10, 11, S("abcdefghij1234567890")); + test(S("abcdefghij"), 10, 1, S("12345678901234567890"), 19, 0, S("abcdefghij")); + test(S("abcdefghij"), 10, 1, S("12345678901234567890"), 19, 1, S("abcdefghij0")); + test(S("abcdefghij"), 10, 1, S("12345678901234567890"), 19, 2, S("abcdefghij0")); + test(S("abcdefghij"), 10, 1, S("12345678901234567890"), 20, 0, S("abcdefghij")); + test(S("abcdefghij"), 10, 1, S("12345678901234567890"), 20, 1, S("abcdefghij")); + test(S("abcdefghij"), 10, 1, S("12345678901234567890"), 21, 0, S("can't happen")); + test(S("abcdefghij"), 11, 0, S(""), 0, 0, S("can't happen")); + test(S("abcdefghij"), 11, 0, S(""), 0, 1, S("can't happen")); + test(S("abcdefghij"), 11, 0, S(""), 1, 0, S("can't happen")); + test(S("abcdefghij"), 11, 0, S("12345"), 0, 0, S("can't happen")); + test(S("abcdefghij"), 11, 0, S("12345"), 0, 1, S("can't happen")); + test(S("abcdefghij"), 11, 0, S("12345"), 0, 2, S("can't happen")); + test(S("abcdefghij"), 11, 0, S("12345"), 0, 4, S("can't happen")); + test(S("abcdefghij"), 11, 0, S("12345"), 0, 5, S("can't happen")); + test(S("abcdefghij"), 11, 0, S("12345"), 0, 6, S("can't happen")); + test(S("abcdefghij"), 11, 0, S("12345"), 1, 0, S("can't happen")); + test(S("abcdefghij"), 11, 0, S("12345"), 1, 1, S("can't happen")); + test(S("abcdefghij"), 11, 0, S("12345"), 1, 2, S("can't happen")); + test(S("abcdefghij"), 11, 0, S("12345"), 1, 3, S("can't happen")); + test(S("abcdefghij"), 11, 0, S("12345"), 1, 4, S("can't happen")); + test(S("abcdefghij"), 11, 0, S("12345"), 1, 5, S("can't happen")); + test(S("abcdefghij"), 11, 0, S("12345"), 2, 0, S("can't happen")); + test(S("abcdefghij"), 11, 0, S("12345"), 2, 1, S("can't happen")); + test(S("abcdefghij"), 11, 0, S("12345"), 2, 2, S("can't happen")); + test(S("abcdefghij"), 11, 0, S("12345"), 2, 3, S("can't happen")); + test(S("abcdefghij"), 11, 0, S("12345"), 2, 4, S("can't happen")); + test(S("abcdefghij"), 11, 0, S("12345"), 4, 0, S("can't happen")); + test(S("abcdefghij"), 11, 0, S("12345"), 4, 1, S("can't happen")); + test(S("abcdefghij"), 11, 0, S("12345"), 4, 2, S("can't happen")); + test(S("abcdefghij"), 11, 0, S("12345"), 5, 0, S("can't happen")); + test(S("abcdefghij"), 11, 0, S("12345"), 5, 1, S("can't happen")); + test(S("abcdefghij"), 11, 0, S("12345"), 6, 0, S("can't happen")); + test(S("abcdefghij"), 11, 0, S("1234567890"), 0, 0, S("can't happen")); + test(S("abcdefghij"), 11, 0, S("1234567890"), 0, 1, S("can't happen")); + test(S("abcdefghij"), 11, 0, S("1234567890"), 0, 5, S("can't happen")); + test(S("abcdefghij"), 11, 0, S("1234567890"), 0, 9, S("can't happen")); + test(S("abcdefghij"), 11, 0, S("1234567890"), 0, 10, S("can't happen")); + test(S("abcdefghij"), 11, 0, S("1234567890"), 0, 11, S("can't happen")); + test(S("abcdefghij"), 11, 0, S("1234567890"), 1, 0, S("can't happen")); + test(S("abcdefghij"), 11, 0, S("1234567890"), 1, 1, S("can't happen")); + test(S("abcdefghij"), 11, 0, S("1234567890"), 1, 4, S("can't happen")); + test(S("abcdefghij"), 11, 0, S("1234567890"), 1, 8, S("can't happen")); + test(S("abcdefghij"), 11, 0, S("1234567890"), 1, 9, S("can't happen")); + test(S("abcdefghij"), 11, 0, S("1234567890"), 1, 10, S("can't happen")); + test(S("abcdefghij"), 11, 0, S("1234567890"), 5, 0, S("can't happen")); + test(S("abcdefghij"), 11, 0, S("1234567890"), 5, 1, S("can't happen")); + test(S("abcdefghij"), 11, 0, S("1234567890"), 5, 2, S("can't happen")); + test(S("abcdefghij"), 11, 0, S("1234567890"), 5, 4, S("can't happen")); + test(S("abcdefghij"), 11, 0, S("1234567890"), 5, 5, S("can't happen")); + test(S("abcdefghij"), 11, 0, S("1234567890"), 5, 6, S("can't happen")); + test(S("abcdefghij"), 11, 0, S("1234567890"), 9, 0, S("can't happen")); + test(S("abcdefghij"), 11, 0, S("1234567890"), 9, 1, S("can't happen")); + test(S("abcdefghij"), 11, 0, S("1234567890"), 9, 2, S("can't happen")); + test(S("abcdefghij"), 11, 0, S("1234567890"), 10, 0, S("can't happen")); + test(S("abcdefghij"), 11, 0, S("1234567890"), 10, 1, S("can't happen")); + test(S("abcdefghij"), 11, 0, S("1234567890"), 11, 0, S("can't happen")); + test(S("abcdefghij"), 11, 0, S("12345678901234567890"), 0, 0, S("can't happen")); + test(S("abcdefghij"), 11, 0, S("12345678901234567890"), 0, 1, S("can't happen")); + test(S("abcdefghij"), 11, 0, S("12345678901234567890"), 0, 10, S("can't happen")); + test(S("abcdefghij"), 11, 0, S("12345678901234567890"), 0, 19, S("can't happen")); + test(S("abcdefghij"), 11, 0, S("12345678901234567890"), 0, 20, S("can't happen")); + test(S("abcdefghij"), 11, 0, S("12345678901234567890"), 0, 21, S("can't happen")); + test(S("abcdefghij"), 11, 0, S("12345678901234567890"), 1, 0, S("can't happen")); + test(S("abcdefghij"), 11, 0, S("12345678901234567890"), 1, 1, S("can't happen")); + test(S("abcdefghij"), 11, 0, S("12345678901234567890"), 1, 9, S("can't happen")); + test(S("abcdefghij"), 11, 0, S("12345678901234567890"), 1, 18, S("can't happen")); + test(S("abcdefghij"), 11, 0, S("12345678901234567890"), 1, 19, S("can't happen")); + test(S("abcdefghij"), 11, 0, S("12345678901234567890"), 1, 20, S("can't happen")); + test(S("abcdefghij"), 11, 0, S("12345678901234567890"), 10, 0, S("can't happen")); + test(S("abcdefghij"), 11, 0, S("12345678901234567890"), 10, 1, S("can't happen")); + test(S("abcdefghij"), 11, 0, S("12345678901234567890"), 10, 5, S("can't happen")); + test(S("abcdefghij"), 11, 0, S("12345678901234567890"), 10, 9, S("can't happen")); + test(S("abcdefghij"), 11, 0, S("12345678901234567890"), 10, 10, S("can't happen")); + test(S("abcdefghij"), 11, 0, S("12345678901234567890"), 10, 11, S("can't happen")); + test(S("abcdefghij"), 11, 0, S("12345678901234567890"), 19, 0, S("can't happen")); + test(S("abcdefghij"), 11, 0, S("12345678901234567890"), 19, 1, S("can't happen")); + test(S("abcdefghij"), 11, 0, S("12345678901234567890"), 19, 2, S("can't happen")); + test(S("abcdefghij"), 11, 0, S("12345678901234567890"), 20, 0, S("can't happen")); + test(S("abcdefghij"), 11, 0, S("12345678901234567890"), 20, 1, S("can't happen")); + test(S("abcdefghij"), 11, 0, S("12345678901234567890"), 21, 0, S("can't happen")); +} + +template +void test37() +{ + test(S("abcdefghijklmnopqrst"), 0, 0, S(""), 0, 0, S("abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, 0, S(""), 0, 1, S("abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, 0, S(""), 1, 0, S("can't happen")); + test(S("abcdefghijklmnopqrst"), 0, 0, S("12345"), 0, 0, S("abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, 0, S("12345"), 0, 1, S("1abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, 0, S("12345"), 0, 2, S("12abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, 0, S("12345"), 0, 4, S("1234abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, 0, S("12345"), 0, 5, S("12345abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, 0, S("12345"), 0, 6, S("12345abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, 0, S("12345"), 1, 0, S("abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, 0, S("12345"), 1, 1, S("2abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, 0, S("12345"), 1, 2, S("23abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, 0, S("12345"), 1, 3, S("234abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, 0, S("12345"), 1, 4, S("2345abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, 0, S("12345"), 1, 5, S("2345abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, 0, S("12345"), 2, 0, S("abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, 0, S("12345"), 2, 1, S("3abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, 0, S("12345"), 2, 2, S("34abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, 0, S("12345"), 2, 3, S("345abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, 0, S("12345"), 2, 4, S("345abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, 0, S("12345"), 4, 0, S("abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, 0, S("12345"), 4, 1, S("5abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, 0, S("12345"), 4, 2, S("5abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, 0, S("12345"), 5, 0, S("abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, 0, S("12345"), 5, 1, S("abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, 0, S("12345"), 6, 0, S("can't happen")); + test(S("abcdefghijklmnopqrst"), 0, 0, S("1234567890"), 0, 0, S("abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, 0, S("1234567890"), 0, 1, S("1abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, 0, S("1234567890"), 0, 5, S("12345abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, 0, S("1234567890"), 0, 9, S("123456789abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, 0, S("1234567890"), 0, 10, S("1234567890abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, 0, S("1234567890"), 0, 11, S("1234567890abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, 0, S("1234567890"), 1, 0, S("abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, 0, S("1234567890"), 1, 1, S("2abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, 0, S("1234567890"), 1, 4, S("2345abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, 0, S("1234567890"), 1, 8, S("23456789abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, 0, S("1234567890"), 1, 9, S("234567890abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, 0, S("1234567890"), 1, 10, S("234567890abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, 0, S("1234567890"), 5, 0, S("abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, 0, S("1234567890"), 5, 1, S("6abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, 0, S("1234567890"), 5, 2, S("67abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, 0, S("1234567890"), 5, 4, S("6789abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, 0, S("1234567890"), 5, 5, S("67890abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, 0, S("1234567890"), 5, 6, S("67890abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, 0, S("1234567890"), 9, 0, S("abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, 0, S("1234567890"), 9, 1, S("0abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, 0, S("1234567890"), 9, 2, S("0abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, 0, S("1234567890"), 10, 0, S("abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, 0, S("1234567890"), 10, 1, S("abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, 0, S("1234567890"), 11, 0, S("can't happen")); + test(S("abcdefghijklmnopqrst"), 0, 0, S("12345678901234567890"), 0, 0, S("abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, 0, S("12345678901234567890"), 0, 1, S("1abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, 0, S("12345678901234567890"), 0, 10, S("1234567890abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, 0, S("12345678901234567890"), 0, 19, S("1234567890123456789abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, 0, S("12345678901234567890"), 0, 20, S("12345678901234567890abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, 0, S("12345678901234567890"), 0, 21, S("12345678901234567890abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, 0, S("12345678901234567890"), 1, 0, S("abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, 0, S("12345678901234567890"), 1, 1, S("2abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, 0, S("12345678901234567890"), 1, 9, S("234567890abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, 0, S("12345678901234567890"), 1, 18, S("234567890123456789abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, 0, S("12345678901234567890"), 1, 19, S("2345678901234567890abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, 0, S("12345678901234567890"), 1, 20, S("2345678901234567890abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, 0, S("12345678901234567890"), 10, 0, S("abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, 0, S("12345678901234567890"), 10, 1, S("1abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, 0, S("12345678901234567890"), 10, 5, S("12345abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, 0, S("12345678901234567890"), 10, 9, S("123456789abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, 0, S("12345678901234567890"), 10, 10, S("1234567890abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, 0, S("12345678901234567890"), 10, 11, S("1234567890abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, 0, S("12345678901234567890"), 19, 0, S("abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, 0, S("12345678901234567890"), 19, 1, S("0abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, 0, S("12345678901234567890"), 19, 2, S("0abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, 0, S("12345678901234567890"), 20, 0, S("abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, 0, S("12345678901234567890"), 20, 1, S("abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, 0, S("12345678901234567890"), 21, 0, S("can't happen")); + test(S("abcdefghijklmnopqrst"), 0, 1, S(""), 0, 0, S("bcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, 1, S(""), 0, 1, S("bcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, 1, S(""), 1, 0, S("can't happen")); + test(S("abcdefghijklmnopqrst"), 0, 1, S("12345"), 0, 0, S("bcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, 1, S("12345"), 0, 1, S("1bcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, 1, S("12345"), 0, 2, S("12bcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, 1, S("12345"), 0, 4, S("1234bcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, 1, S("12345"), 0, 5, S("12345bcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, 1, S("12345"), 0, 6, S("12345bcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, 1, S("12345"), 1, 0, S("bcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, 1, S("12345"), 1, 1, S("2bcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, 1, S("12345"), 1, 2, S("23bcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, 1, S("12345"), 1, 3, S("234bcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, 1, S("12345"), 1, 4, S("2345bcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, 1, S("12345"), 1, 5, S("2345bcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, 1, S("12345"), 2, 0, S("bcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, 1, S("12345"), 2, 1, S("3bcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, 1, S("12345"), 2, 2, S("34bcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, 1, S("12345"), 2, 3, S("345bcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, 1, S("12345"), 2, 4, S("345bcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, 1, S("12345"), 4, 0, S("bcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, 1, S("12345"), 4, 1, S("5bcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, 1, S("12345"), 4, 2, S("5bcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, 1, S("12345"), 5, 0, S("bcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, 1, S("12345"), 5, 1, S("bcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, 1, S("12345"), 6, 0, S("can't happen")); +} + +template +void test38() +{ + test(S("abcdefghijklmnopqrst"), 0, 1, S("1234567890"), 0, 0, S("bcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, 1, S("1234567890"), 0, 1, S("1bcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, 1, S("1234567890"), 0, 5, S("12345bcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, 1, S("1234567890"), 0, 9, S("123456789bcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, 1, S("1234567890"), 0, 10, S("1234567890bcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, 1, S("1234567890"), 0, 11, S("1234567890bcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, 1, S("1234567890"), 1, 0, S("bcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, 1, S("1234567890"), 1, 1, S("2bcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, 1, S("1234567890"), 1, 4, S("2345bcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, 1, S("1234567890"), 1, 8, S("23456789bcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, 1, S("1234567890"), 1, 9, S("234567890bcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, 1, S("1234567890"), 1, 10, S("234567890bcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, 1, S("1234567890"), 5, 0, S("bcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, 1, S("1234567890"), 5, 1, S("6bcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, 1, S("1234567890"), 5, 2, S("67bcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, 1, S("1234567890"), 5, 4, S("6789bcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, 1, S("1234567890"), 5, 5, S("67890bcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, 1, S("1234567890"), 5, 6, S("67890bcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, 1, S("1234567890"), 9, 0, S("bcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, 1, S("1234567890"), 9, 1, S("0bcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, 1, S("1234567890"), 9, 2, S("0bcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, 1, S("1234567890"), 10, 0, S("bcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, 1, S("1234567890"), 10, 1, S("bcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, 1, S("1234567890"), 11, 0, S("can't happen")); + test(S("abcdefghijklmnopqrst"), 0, 1, S("12345678901234567890"), 0, 0, S("bcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, 1, S("12345678901234567890"), 0, 1, S("1bcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, 1, S("12345678901234567890"), 0, 10, S("1234567890bcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, 1, S("12345678901234567890"), 0, 19, S("1234567890123456789bcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, 1, S("12345678901234567890"), 0, 20, S("12345678901234567890bcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, 1, S("12345678901234567890"), 0, 21, S("12345678901234567890bcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, 1, S("12345678901234567890"), 1, 0, S("bcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, 1, S("12345678901234567890"), 1, 1, S("2bcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, 1, S("12345678901234567890"), 1, 9, S("234567890bcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, 1, S("12345678901234567890"), 1, 18, S("234567890123456789bcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, 1, S("12345678901234567890"), 1, 19, S("2345678901234567890bcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, 1, S("12345678901234567890"), 1, 20, S("2345678901234567890bcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, 1, S("12345678901234567890"), 10, 0, S("bcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, 1, S("12345678901234567890"), 10, 1, S("1bcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, 1, S("12345678901234567890"), 10, 5, S("12345bcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, 1, S("12345678901234567890"), 10, 9, S("123456789bcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, 1, S("12345678901234567890"), 10, 10, S("1234567890bcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, 1, S("12345678901234567890"), 10, 11, S("1234567890bcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, 1, S("12345678901234567890"), 19, 0, S("bcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, 1, S("12345678901234567890"), 19, 1, S("0bcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, 1, S("12345678901234567890"), 19, 2, S("0bcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, 1, S("12345678901234567890"), 20, 0, S("bcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, 1, S("12345678901234567890"), 20, 1, S("bcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, 1, S("12345678901234567890"), 21, 0, S("can't happen")); + test(S("abcdefghijklmnopqrst"), 0, 10, S(""), 0, 0, S("klmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, 10, S(""), 0, 1, S("klmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, 10, S(""), 1, 0, S("can't happen")); + test(S("abcdefghijklmnopqrst"), 0, 10, S("12345"), 0, 0, S("klmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, 10, S("12345"), 0, 1, S("1klmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, 10, S("12345"), 0, 2, S("12klmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, 10, S("12345"), 0, 4, S("1234klmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, 10, S("12345"), 0, 5, S("12345klmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, 10, S("12345"), 0, 6, S("12345klmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, 10, S("12345"), 1, 0, S("klmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, 10, S("12345"), 1, 1, S("2klmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, 10, S("12345"), 1, 2, S("23klmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, 10, S("12345"), 1, 3, S("234klmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, 10, S("12345"), 1, 4, S("2345klmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, 10, S("12345"), 1, 5, S("2345klmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, 10, S("12345"), 2, 0, S("klmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, 10, S("12345"), 2, 1, S("3klmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, 10, S("12345"), 2, 2, S("34klmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, 10, S("12345"), 2, 3, S("345klmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, 10, S("12345"), 2, 4, S("345klmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, 10, S("12345"), 4, 0, S("klmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, 10, S("12345"), 4, 1, S("5klmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, 10, S("12345"), 4, 2, S("5klmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, 10, S("12345"), 5, 0, S("klmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, 10, S("12345"), 5, 1, S("klmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, 10, S("12345"), 6, 0, S("can't happen")); + test(S("abcdefghijklmnopqrst"), 0, 10, S("1234567890"), 0, 0, S("klmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, 10, S("1234567890"), 0, 1, S("1klmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, 10, S("1234567890"), 0, 5, S("12345klmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, 10, S("1234567890"), 0, 9, S("123456789klmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, 10, S("1234567890"), 0, 10, S("1234567890klmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, 10, S("1234567890"), 0, 11, S("1234567890klmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, 10, S("1234567890"), 1, 0, S("klmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, 10, S("1234567890"), 1, 1, S("2klmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, 10, S("1234567890"), 1, 4, S("2345klmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, 10, S("1234567890"), 1, 8, S("23456789klmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, 10, S("1234567890"), 1, 9, S("234567890klmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, 10, S("1234567890"), 1, 10, S("234567890klmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, 10, S("1234567890"), 5, 0, S("klmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, 10, S("1234567890"), 5, 1, S("6klmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, 10, S("1234567890"), 5, 2, S("67klmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, 10, S("1234567890"), 5, 4, S("6789klmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, 10, S("1234567890"), 5, 5, S("67890klmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, 10, S("1234567890"), 5, 6, S("67890klmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, 10, S("1234567890"), 9, 0, S("klmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, 10, S("1234567890"), 9, 1, S("0klmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, 10, S("1234567890"), 9, 2, S("0klmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, 10, S("1234567890"), 10, 0, S("klmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, 10, S("1234567890"), 10, 1, S("klmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, 10, S("1234567890"), 11, 0, S("can't happen")); + test(S("abcdefghijklmnopqrst"), 0, 10, S("12345678901234567890"), 0, 0, S("klmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, 10, S("12345678901234567890"), 0, 1, S("1klmnopqrst")); +} + +template +void test39() +{ + test(S("abcdefghijklmnopqrst"), 0, 10, S("12345678901234567890"), 0, 10, S("1234567890klmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, 10, S("12345678901234567890"), 0, 19, S("1234567890123456789klmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, 10, S("12345678901234567890"), 0, 20, S("12345678901234567890klmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, 10, S("12345678901234567890"), 0, 21, S("12345678901234567890klmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, 10, S("12345678901234567890"), 1, 0, S("klmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, 10, S("12345678901234567890"), 1, 1, S("2klmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, 10, S("12345678901234567890"), 1, 9, S("234567890klmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, 10, S("12345678901234567890"), 1, 18, S("234567890123456789klmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, 10, S("12345678901234567890"), 1, 19, S("2345678901234567890klmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, 10, S("12345678901234567890"), 1, 20, S("2345678901234567890klmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, 10, S("12345678901234567890"), 10, 0, S("klmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, 10, S("12345678901234567890"), 10, 1, S("1klmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, 10, S("12345678901234567890"), 10, 5, S("12345klmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, 10, S("12345678901234567890"), 10, 9, S("123456789klmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, 10, S("12345678901234567890"), 10, 10, S("1234567890klmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, 10, S("12345678901234567890"), 10, 11, S("1234567890klmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, 10, S("12345678901234567890"), 19, 0, S("klmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, 10, S("12345678901234567890"), 19, 1, S("0klmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, 10, S("12345678901234567890"), 19, 2, S("0klmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, 10, S("12345678901234567890"), 20, 0, S("klmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, 10, S("12345678901234567890"), 20, 1, S("klmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, 10, S("12345678901234567890"), 21, 0, S("can't happen")); + test(S("abcdefghijklmnopqrst"), 0, 19, S(""), 0, 0, S("t")); + test(S("abcdefghijklmnopqrst"), 0, 19, S(""), 0, 1, S("t")); + test(S("abcdefghijklmnopqrst"), 0, 19, S(""), 1, 0, S("can't happen")); + test(S("abcdefghijklmnopqrst"), 0, 19, S("12345"), 0, 0, S("t")); + test(S("abcdefghijklmnopqrst"), 0, 19, S("12345"), 0, 1, S("1t")); + test(S("abcdefghijklmnopqrst"), 0, 19, S("12345"), 0, 2, S("12t")); + test(S("abcdefghijklmnopqrst"), 0, 19, S("12345"), 0, 4, S("1234t")); + test(S("abcdefghijklmnopqrst"), 0, 19, S("12345"), 0, 5, S("12345t")); + test(S("abcdefghijklmnopqrst"), 0, 19, S("12345"), 0, 6, S("12345t")); + test(S("abcdefghijklmnopqrst"), 0, 19, S("12345"), 1, 0, S("t")); + test(S("abcdefghijklmnopqrst"), 0, 19, S("12345"), 1, 1, S("2t")); + test(S("abcdefghijklmnopqrst"), 0, 19, S("12345"), 1, 2, S("23t")); + test(S("abcdefghijklmnopqrst"), 0, 19, S("12345"), 1, 3, S("234t")); + test(S("abcdefghijklmnopqrst"), 0, 19, S("12345"), 1, 4, S("2345t")); + test(S("abcdefghijklmnopqrst"), 0, 19, S("12345"), 1, 5, S("2345t")); + test(S("abcdefghijklmnopqrst"), 0, 19, S("12345"), 2, 0, S("t")); + test(S("abcdefghijklmnopqrst"), 0, 19, S("12345"), 2, 1, S("3t")); + test(S("abcdefghijklmnopqrst"), 0, 19, S("12345"), 2, 2, S("34t")); + test(S("abcdefghijklmnopqrst"), 0, 19, S("12345"), 2, 3, S("345t")); + test(S("abcdefghijklmnopqrst"), 0, 19, S("12345"), 2, 4, S("345t")); + test(S("abcdefghijklmnopqrst"), 0, 19, S("12345"), 4, 0, S("t")); + test(S("abcdefghijklmnopqrst"), 0, 19, S("12345"), 4, 1, S("5t")); + test(S("abcdefghijklmnopqrst"), 0, 19, S("12345"), 4, 2, S("5t")); + test(S("abcdefghijklmnopqrst"), 0, 19, S("12345"), 5, 0, S("t")); + test(S("abcdefghijklmnopqrst"), 0, 19, S("12345"), 5, 1, S("t")); + test(S("abcdefghijklmnopqrst"), 0, 19, S("12345"), 6, 0, S("can't happen")); + test(S("abcdefghijklmnopqrst"), 0, 19, S("1234567890"), 0, 0, S("t")); + test(S("abcdefghijklmnopqrst"), 0, 19, S("1234567890"), 0, 1, S("1t")); + test(S("abcdefghijklmnopqrst"), 0, 19, S("1234567890"), 0, 5, S("12345t")); + test(S("abcdefghijklmnopqrst"), 0, 19, S("1234567890"), 0, 9, S("123456789t")); + test(S("abcdefghijklmnopqrst"), 0, 19, S("1234567890"), 0, 10, S("1234567890t")); + test(S("abcdefghijklmnopqrst"), 0, 19, S("1234567890"), 0, 11, S("1234567890t")); + test(S("abcdefghijklmnopqrst"), 0, 19, S("1234567890"), 1, 0, S("t")); + test(S("abcdefghijklmnopqrst"), 0, 19, S("1234567890"), 1, 1, S("2t")); + test(S("abcdefghijklmnopqrst"), 0, 19, S("1234567890"), 1, 4, S("2345t")); + test(S("abcdefghijklmnopqrst"), 0, 19, S("1234567890"), 1, 8, S("23456789t")); + test(S("abcdefghijklmnopqrst"), 0, 19, S("1234567890"), 1, 9, S("234567890t")); + test(S("abcdefghijklmnopqrst"), 0, 19, S("1234567890"), 1, 10, S("234567890t")); + test(S("abcdefghijklmnopqrst"), 0, 19, S("1234567890"), 5, 0, S("t")); + test(S("abcdefghijklmnopqrst"), 0, 19, S("1234567890"), 5, 1, S("6t")); + test(S("abcdefghijklmnopqrst"), 0, 19, S("1234567890"), 5, 2, S("67t")); + test(S("abcdefghijklmnopqrst"), 0, 19, S("1234567890"), 5, 4, S("6789t")); + test(S("abcdefghijklmnopqrst"), 0, 19, S("1234567890"), 5, 5, S("67890t")); + test(S("abcdefghijklmnopqrst"), 0, 19, S("1234567890"), 5, 6, S("67890t")); + test(S("abcdefghijklmnopqrst"), 0, 19, S("1234567890"), 9, 0, S("t")); + test(S("abcdefghijklmnopqrst"), 0, 19, S("1234567890"), 9, 1, S("0t")); + test(S("abcdefghijklmnopqrst"), 0, 19, S("1234567890"), 9, 2, S("0t")); + test(S("abcdefghijklmnopqrst"), 0, 19, S("1234567890"), 10, 0, S("t")); + test(S("abcdefghijklmnopqrst"), 0, 19, S("1234567890"), 10, 1, S("t")); + test(S("abcdefghijklmnopqrst"), 0, 19, S("1234567890"), 11, 0, S("can't happen")); + test(S("abcdefghijklmnopqrst"), 0, 19, S("12345678901234567890"), 0, 0, S("t")); + test(S("abcdefghijklmnopqrst"), 0, 19, S("12345678901234567890"), 0, 1, S("1t")); + test(S("abcdefghijklmnopqrst"), 0, 19, S("12345678901234567890"), 0, 10, S("1234567890t")); + test(S("abcdefghijklmnopqrst"), 0, 19, S("12345678901234567890"), 0, 19, S("1234567890123456789t")); + test(S("abcdefghijklmnopqrst"), 0, 19, S("12345678901234567890"), 0, 20, S("12345678901234567890t")); + test(S("abcdefghijklmnopqrst"), 0, 19, S("12345678901234567890"), 0, 21, S("12345678901234567890t")); + test(S("abcdefghijklmnopqrst"), 0, 19, S("12345678901234567890"), 1, 0, S("t")); + test(S("abcdefghijklmnopqrst"), 0, 19, S("12345678901234567890"), 1, 1, S("2t")); + test(S("abcdefghijklmnopqrst"), 0, 19, S("12345678901234567890"), 1, 9, S("234567890t")); + test(S("abcdefghijklmnopqrst"), 0, 19, S("12345678901234567890"), 1, 18, S("234567890123456789t")); + test(S("abcdefghijklmnopqrst"), 0, 19, S("12345678901234567890"), 1, 19, S("2345678901234567890t")); + test(S("abcdefghijklmnopqrst"), 0, 19, S("12345678901234567890"), 1, 20, S("2345678901234567890t")); + test(S("abcdefghijklmnopqrst"), 0, 19, S("12345678901234567890"), 10, 0, S("t")); + test(S("abcdefghijklmnopqrst"), 0, 19, S("12345678901234567890"), 10, 1, S("1t")); + test(S("abcdefghijklmnopqrst"), 0, 19, S("12345678901234567890"), 10, 5, S("12345t")); + test(S("abcdefghijklmnopqrst"), 0, 19, S("12345678901234567890"), 10, 9, S("123456789t")); + test(S("abcdefghijklmnopqrst"), 0, 19, S("12345678901234567890"), 10, 10, S("1234567890t")); + test(S("abcdefghijklmnopqrst"), 0, 19, S("12345678901234567890"), 10, 11, S("1234567890t")); + test(S("abcdefghijklmnopqrst"), 0, 19, S("12345678901234567890"), 19, 0, S("t")); + test(S("abcdefghijklmnopqrst"), 0, 19, S("12345678901234567890"), 19, 1, S("0t")); + test(S("abcdefghijklmnopqrst"), 0, 19, S("12345678901234567890"), 19, 2, S("0t")); + test(S("abcdefghijklmnopqrst"), 0, 19, S("12345678901234567890"), 20, 0, S("t")); + test(S("abcdefghijklmnopqrst"), 0, 19, S("12345678901234567890"), 20, 1, S("t")); + test(S("abcdefghijklmnopqrst"), 0, 19, S("12345678901234567890"), 21, 0, S("can't happen")); + test(S("abcdefghijklmnopqrst"), 0, 20, S(""), 0, 0, S("")); + test(S("abcdefghijklmnopqrst"), 0, 20, S(""), 0, 1, S("")); + test(S("abcdefghijklmnopqrst"), 0, 20, S(""), 1, 0, S("can't happen")); + test(S("abcdefghijklmnopqrst"), 0, 20, S("12345"), 0, 0, S("")); +} + +template +void test40() +{ + test(S("abcdefghijklmnopqrst"), 0, 20, S("12345"), 0, 1, S("1")); + test(S("abcdefghijklmnopqrst"), 0, 20, S("12345"), 0, 2, S("12")); + test(S("abcdefghijklmnopqrst"), 0, 20, S("12345"), 0, 4, S("1234")); + test(S("abcdefghijklmnopqrst"), 0, 20, S("12345"), 0, 5, S("12345")); + test(S("abcdefghijklmnopqrst"), 0, 20, S("12345"), 0, 6, S("12345")); + test(S("abcdefghijklmnopqrst"), 0, 20, S("12345"), 1, 0, S("")); + test(S("abcdefghijklmnopqrst"), 0, 20, S("12345"), 1, 1, S("2")); + test(S("abcdefghijklmnopqrst"), 0, 20, S("12345"), 1, 2, S("23")); + test(S("abcdefghijklmnopqrst"), 0, 20, S("12345"), 1, 3, S("234")); + test(S("abcdefghijklmnopqrst"), 0, 20, S("12345"), 1, 4, S("2345")); + test(S("abcdefghijklmnopqrst"), 0, 20, S("12345"), 1, 5, S("2345")); + test(S("abcdefghijklmnopqrst"), 0, 20, S("12345"), 2, 0, S("")); + test(S("abcdefghijklmnopqrst"), 0, 20, S("12345"), 2, 1, S("3")); + test(S("abcdefghijklmnopqrst"), 0, 20, S("12345"), 2, 2, S("34")); + test(S("abcdefghijklmnopqrst"), 0, 20, S("12345"), 2, 3, S("345")); + test(S("abcdefghijklmnopqrst"), 0, 20, S("12345"), 2, 4, S("345")); + test(S("abcdefghijklmnopqrst"), 0, 20, S("12345"), 4, 0, S("")); + test(S("abcdefghijklmnopqrst"), 0, 20, S("12345"), 4, 1, S("5")); + test(S("abcdefghijklmnopqrst"), 0, 20, S("12345"), 4, 2, S("5")); + test(S("abcdefghijklmnopqrst"), 0, 20, S("12345"), 5, 0, S("")); + test(S("abcdefghijklmnopqrst"), 0, 20, S("12345"), 5, 1, S("")); + test(S("abcdefghijklmnopqrst"), 0, 20, S("12345"), 6, 0, S("can't happen")); + test(S("abcdefghijklmnopqrst"), 0, 20, S("1234567890"), 0, 0, S("")); + test(S("abcdefghijklmnopqrst"), 0, 20, S("1234567890"), 0, 1, S("1")); + test(S("abcdefghijklmnopqrst"), 0, 20, S("1234567890"), 0, 5, S("12345")); + test(S("abcdefghijklmnopqrst"), 0, 20, S("1234567890"), 0, 9, S("123456789")); + test(S("abcdefghijklmnopqrst"), 0, 20, S("1234567890"), 0, 10, S("1234567890")); + test(S("abcdefghijklmnopqrst"), 0, 20, S("1234567890"), 0, 11, S("1234567890")); + test(S("abcdefghijklmnopqrst"), 0, 20, S("1234567890"), 1, 0, S("")); + test(S("abcdefghijklmnopqrst"), 0, 20, S("1234567890"), 1, 1, S("2")); + test(S("abcdefghijklmnopqrst"), 0, 20, S("1234567890"), 1, 4, S("2345")); + test(S("abcdefghijklmnopqrst"), 0, 20, S("1234567890"), 1, 8, S("23456789")); + test(S("abcdefghijklmnopqrst"), 0, 20, S("1234567890"), 1, 9, S("234567890")); + test(S("abcdefghijklmnopqrst"), 0, 20, S("1234567890"), 1, 10, S("234567890")); + test(S("abcdefghijklmnopqrst"), 0, 20, S("1234567890"), 5, 0, S("")); + test(S("abcdefghijklmnopqrst"), 0, 20, S("1234567890"), 5, 1, S("6")); + test(S("abcdefghijklmnopqrst"), 0, 20, S("1234567890"), 5, 2, S("67")); + test(S("abcdefghijklmnopqrst"), 0, 20, S("1234567890"), 5, 4, S("6789")); + test(S("abcdefghijklmnopqrst"), 0, 20, S("1234567890"), 5, 5, S("67890")); + test(S("abcdefghijklmnopqrst"), 0, 20, S("1234567890"), 5, 6, S("67890")); + test(S("abcdefghijklmnopqrst"), 0, 20, S("1234567890"), 9, 0, S("")); + test(S("abcdefghijklmnopqrst"), 0, 20, S("1234567890"), 9, 1, S("0")); + test(S("abcdefghijklmnopqrst"), 0, 20, S("1234567890"), 9, 2, S("0")); + test(S("abcdefghijklmnopqrst"), 0, 20, S("1234567890"), 10, 0, S("")); + test(S("abcdefghijklmnopqrst"), 0, 20, S("1234567890"), 10, 1, S("")); + test(S("abcdefghijklmnopqrst"), 0, 20, S("1234567890"), 11, 0, S("can't happen")); + test(S("abcdefghijklmnopqrst"), 0, 20, S("12345678901234567890"), 0, 0, S("")); + test(S("abcdefghijklmnopqrst"), 0, 20, S("12345678901234567890"), 0, 1, S("1")); + test(S("abcdefghijklmnopqrst"), 0, 20, S("12345678901234567890"), 0, 10, S("1234567890")); + test(S("abcdefghijklmnopqrst"), 0, 20, S("12345678901234567890"), 0, 19, S("1234567890123456789")); + test(S("abcdefghijklmnopqrst"), 0, 20, S("12345678901234567890"), 0, 20, S("12345678901234567890")); + test(S("abcdefghijklmnopqrst"), 0, 20, S("12345678901234567890"), 0, 21, S("12345678901234567890")); + test(S("abcdefghijklmnopqrst"), 0, 20, S("12345678901234567890"), 1, 0, S("")); + test(S("abcdefghijklmnopqrst"), 0, 20, S("12345678901234567890"), 1, 1, S("2")); + test(S("abcdefghijklmnopqrst"), 0, 20, S("12345678901234567890"), 1, 9, S("234567890")); + test(S("abcdefghijklmnopqrst"), 0, 20, S("12345678901234567890"), 1, 18, S("234567890123456789")); + test(S("abcdefghijklmnopqrst"), 0, 20, S("12345678901234567890"), 1, 19, S("2345678901234567890")); + test(S("abcdefghijklmnopqrst"), 0, 20, S("12345678901234567890"), 1, 20, S("2345678901234567890")); + test(S("abcdefghijklmnopqrst"), 0, 20, S("12345678901234567890"), 10, 0, S("")); + test(S("abcdefghijklmnopqrst"), 0, 20, S("12345678901234567890"), 10, 1, S("1")); + test(S("abcdefghijklmnopqrst"), 0, 20, S("12345678901234567890"), 10, 5, S("12345")); + test(S("abcdefghijklmnopqrst"), 0, 20, S("12345678901234567890"), 10, 9, S("123456789")); + test(S("abcdefghijklmnopqrst"), 0, 20, S("12345678901234567890"), 10, 10, S("1234567890")); + test(S("abcdefghijklmnopqrst"), 0, 20, S("12345678901234567890"), 10, 11, S("1234567890")); + test(S("abcdefghijklmnopqrst"), 0, 20, S("12345678901234567890"), 19, 0, S("")); + test(S("abcdefghijklmnopqrst"), 0, 20, S("12345678901234567890"), 19, 1, S("0")); + test(S("abcdefghijklmnopqrst"), 0, 20, S("12345678901234567890"), 19, 2, S("0")); + test(S("abcdefghijklmnopqrst"), 0, 20, S("12345678901234567890"), 20, 0, S("")); + test(S("abcdefghijklmnopqrst"), 0, 20, S("12345678901234567890"), 20, 1, S("")); + test(S("abcdefghijklmnopqrst"), 0, 20, S("12345678901234567890"), 21, 0, S("can't happen")); + test(S("abcdefghijklmnopqrst"), 0, 21, S(""), 0, 0, S("")); + test(S("abcdefghijklmnopqrst"), 0, 21, S(""), 0, 1, S("")); + test(S("abcdefghijklmnopqrst"), 0, 21, S(""), 1, 0, S("can't happen")); + test(S("abcdefghijklmnopqrst"), 0, 21, S("12345"), 0, 0, S("")); + test(S("abcdefghijklmnopqrst"), 0, 21, S("12345"), 0, 1, S("1")); + test(S("abcdefghijklmnopqrst"), 0, 21, S("12345"), 0, 2, S("12")); + test(S("abcdefghijklmnopqrst"), 0, 21, S("12345"), 0, 4, S("1234")); + test(S("abcdefghijklmnopqrst"), 0, 21, S("12345"), 0, 5, S("12345")); + test(S("abcdefghijklmnopqrst"), 0, 21, S("12345"), 0, 6, S("12345")); + test(S("abcdefghijklmnopqrst"), 0, 21, S("12345"), 1, 0, S("")); + test(S("abcdefghijklmnopqrst"), 0, 21, S("12345"), 1, 1, S("2")); + test(S("abcdefghijklmnopqrst"), 0, 21, S("12345"), 1, 2, S("23")); + test(S("abcdefghijklmnopqrst"), 0, 21, S("12345"), 1, 3, S("234")); + test(S("abcdefghijklmnopqrst"), 0, 21, S("12345"), 1, 4, S("2345")); + test(S("abcdefghijklmnopqrst"), 0, 21, S("12345"), 1, 5, S("2345")); + test(S("abcdefghijklmnopqrst"), 0, 21, S("12345"), 2, 0, S("")); + test(S("abcdefghijklmnopqrst"), 0, 21, S("12345"), 2, 1, S("3")); + test(S("abcdefghijklmnopqrst"), 0, 21, S("12345"), 2, 2, S("34")); + test(S("abcdefghijklmnopqrst"), 0, 21, S("12345"), 2, 3, S("345")); + test(S("abcdefghijklmnopqrst"), 0, 21, S("12345"), 2, 4, S("345")); + test(S("abcdefghijklmnopqrst"), 0, 21, S("12345"), 4, 0, S("")); + test(S("abcdefghijklmnopqrst"), 0, 21, S("12345"), 4, 1, S("5")); + test(S("abcdefghijklmnopqrst"), 0, 21, S("12345"), 4, 2, S("5")); + test(S("abcdefghijklmnopqrst"), 0, 21, S("12345"), 5, 0, S("")); + test(S("abcdefghijklmnopqrst"), 0, 21, S("12345"), 5, 1, S("")); + test(S("abcdefghijklmnopqrst"), 0, 21, S("12345"), 6, 0, S("can't happen")); + test(S("abcdefghijklmnopqrst"), 0, 21, S("1234567890"), 0, 0, S("")); + test(S("abcdefghijklmnopqrst"), 0, 21, S("1234567890"), 0, 1, S("1")); + test(S("abcdefghijklmnopqrst"), 0, 21, S("1234567890"), 0, 5, S("12345")); + test(S("abcdefghijklmnopqrst"), 0, 21, S("1234567890"), 0, 9, S("123456789")); +} + +template +void test41() +{ + test(S("abcdefghijklmnopqrst"), 0, 21, S("1234567890"), 0, 10, S("1234567890")); + test(S("abcdefghijklmnopqrst"), 0, 21, S("1234567890"), 0, 11, S("1234567890")); + test(S("abcdefghijklmnopqrst"), 0, 21, S("1234567890"), 1, 0, S("")); + test(S("abcdefghijklmnopqrst"), 0, 21, S("1234567890"), 1, 1, S("2")); + test(S("abcdefghijklmnopqrst"), 0, 21, S("1234567890"), 1, 4, S("2345")); + test(S("abcdefghijklmnopqrst"), 0, 21, S("1234567890"), 1, 8, S("23456789")); + test(S("abcdefghijklmnopqrst"), 0, 21, S("1234567890"), 1, 9, S("234567890")); + test(S("abcdefghijklmnopqrst"), 0, 21, S("1234567890"), 1, 10, S("234567890")); + test(S("abcdefghijklmnopqrst"), 0, 21, S("1234567890"), 5, 0, S("")); + test(S("abcdefghijklmnopqrst"), 0, 21, S("1234567890"), 5, 1, S("6")); + test(S("abcdefghijklmnopqrst"), 0, 21, S("1234567890"), 5, 2, S("67")); + test(S("abcdefghijklmnopqrst"), 0, 21, S("1234567890"), 5, 4, S("6789")); + test(S("abcdefghijklmnopqrst"), 0, 21, S("1234567890"), 5, 5, S("67890")); + test(S("abcdefghijklmnopqrst"), 0, 21, S("1234567890"), 5, 6, S("67890")); + test(S("abcdefghijklmnopqrst"), 0, 21, S("1234567890"), 9, 0, S("")); + test(S("abcdefghijklmnopqrst"), 0, 21, S("1234567890"), 9, 1, S("0")); + test(S("abcdefghijklmnopqrst"), 0, 21, S("1234567890"), 9, 2, S("0")); + test(S("abcdefghijklmnopqrst"), 0, 21, S("1234567890"), 10, 0, S("")); + test(S("abcdefghijklmnopqrst"), 0, 21, S("1234567890"), 10, 1, S("")); + test(S("abcdefghijklmnopqrst"), 0, 21, S("1234567890"), 11, 0, S("can't happen")); + test(S("abcdefghijklmnopqrst"), 0, 21, S("12345678901234567890"), 0, 0, S("")); + test(S("abcdefghijklmnopqrst"), 0, 21, S("12345678901234567890"), 0, 1, S("1")); + test(S("abcdefghijklmnopqrst"), 0, 21, S("12345678901234567890"), 0, 10, S("1234567890")); + test(S("abcdefghijklmnopqrst"), 0, 21, S("12345678901234567890"), 0, 19, S("1234567890123456789")); + test(S("abcdefghijklmnopqrst"), 0, 21, S("12345678901234567890"), 0, 20, S("12345678901234567890")); + test(S("abcdefghijklmnopqrst"), 0, 21, S("12345678901234567890"), 0, 21, S("12345678901234567890")); + test(S("abcdefghijklmnopqrst"), 0, 21, S("12345678901234567890"), 1, 0, S("")); + test(S("abcdefghijklmnopqrst"), 0, 21, S("12345678901234567890"), 1, 1, S("2")); + test(S("abcdefghijklmnopqrst"), 0, 21, S("12345678901234567890"), 1, 9, S("234567890")); + test(S("abcdefghijklmnopqrst"), 0, 21, S("12345678901234567890"), 1, 18, S("234567890123456789")); + test(S("abcdefghijklmnopqrst"), 0, 21, S("12345678901234567890"), 1, 19, S("2345678901234567890")); + test(S("abcdefghijklmnopqrst"), 0, 21, S("12345678901234567890"), 1, 20, S("2345678901234567890")); + test(S("abcdefghijklmnopqrst"), 0, 21, S("12345678901234567890"), 10, 0, S("")); + test(S("abcdefghijklmnopqrst"), 0, 21, S("12345678901234567890"), 10, 1, S("1")); + test(S("abcdefghijklmnopqrst"), 0, 21, S("12345678901234567890"), 10, 5, S("12345")); + test(S("abcdefghijklmnopqrst"), 0, 21, S("12345678901234567890"), 10, 9, S("123456789")); + test(S("abcdefghijklmnopqrst"), 0, 21, S("12345678901234567890"), 10, 10, S("1234567890")); + test(S("abcdefghijklmnopqrst"), 0, 21, S("12345678901234567890"), 10, 11, S("1234567890")); + test(S("abcdefghijklmnopqrst"), 0, 21, S("12345678901234567890"), 19, 0, S("")); + test(S("abcdefghijklmnopqrst"), 0, 21, S("12345678901234567890"), 19, 1, S("0")); + test(S("abcdefghijklmnopqrst"), 0, 21, S("12345678901234567890"), 19, 2, S("0")); + test(S("abcdefghijklmnopqrst"), 0, 21, S("12345678901234567890"), 20, 0, S("")); + test(S("abcdefghijklmnopqrst"), 0, 21, S("12345678901234567890"), 20, 1, S("")); + test(S("abcdefghijklmnopqrst"), 0, 21, S("12345678901234567890"), 21, 0, S("can't happen")); + test(S("abcdefghijklmnopqrst"), 1, 0, S(""), 0, 0, S("abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, 0, S(""), 0, 1, S("abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, 0, S(""), 1, 0, S("can't happen")); + test(S("abcdefghijklmnopqrst"), 1, 0, S("12345"), 0, 0, S("abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, 0, S("12345"), 0, 1, S("a1bcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, 0, S("12345"), 0, 2, S("a12bcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, 0, S("12345"), 0, 4, S("a1234bcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, 0, S("12345"), 0, 5, S("a12345bcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, 0, S("12345"), 0, 6, S("a12345bcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, 0, S("12345"), 1, 0, S("abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, 0, S("12345"), 1, 1, S("a2bcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, 0, S("12345"), 1, 2, S("a23bcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, 0, S("12345"), 1, 3, S("a234bcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, 0, S("12345"), 1, 4, S("a2345bcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, 0, S("12345"), 1, 5, S("a2345bcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, 0, S("12345"), 2, 0, S("abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, 0, S("12345"), 2, 1, S("a3bcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, 0, S("12345"), 2, 2, S("a34bcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, 0, S("12345"), 2, 3, S("a345bcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, 0, S("12345"), 2, 4, S("a345bcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, 0, S("12345"), 4, 0, S("abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, 0, S("12345"), 4, 1, S("a5bcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, 0, S("12345"), 4, 2, S("a5bcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, 0, S("12345"), 5, 0, S("abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, 0, S("12345"), 5, 1, S("abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, 0, S("12345"), 6, 0, S("can't happen")); + test(S("abcdefghijklmnopqrst"), 1, 0, S("1234567890"), 0, 0, S("abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, 0, S("1234567890"), 0, 1, S("a1bcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, 0, S("1234567890"), 0, 5, S("a12345bcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, 0, S("1234567890"), 0, 9, S("a123456789bcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, 0, S("1234567890"), 0, 10, S("a1234567890bcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, 0, S("1234567890"), 0, 11, S("a1234567890bcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, 0, S("1234567890"), 1, 0, S("abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, 0, S("1234567890"), 1, 1, S("a2bcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, 0, S("1234567890"), 1, 4, S("a2345bcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, 0, S("1234567890"), 1, 8, S("a23456789bcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, 0, S("1234567890"), 1, 9, S("a234567890bcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, 0, S("1234567890"), 1, 10, S("a234567890bcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, 0, S("1234567890"), 5, 0, S("abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, 0, S("1234567890"), 5, 1, S("a6bcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, 0, S("1234567890"), 5, 2, S("a67bcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, 0, S("1234567890"), 5, 4, S("a6789bcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, 0, S("1234567890"), 5, 5, S("a67890bcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, 0, S("1234567890"), 5, 6, S("a67890bcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, 0, S("1234567890"), 9, 0, S("abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, 0, S("1234567890"), 9, 1, S("a0bcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, 0, S("1234567890"), 9, 2, S("a0bcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, 0, S("1234567890"), 10, 0, S("abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, 0, S("1234567890"), 10, 1, S("abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, 0, S("1234567890"), 11, 0, S("can't happen")); + test(S("abcdefghijklmnopqrst"), 1, 0, S("12345678901234567890"), 0, 0, S("abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, 0, S("12345678901234567890"), 0, 1, S("a1bcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, 0, S("12345678901234567890"), 0, 10, S("a1234567890bcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, 0, S("12345678901234567890"), 0, 19, S("a1234567890123456789bcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, 0, S("12345678901234567890"), 0, 20, S("a12345678901234567890bcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, 0, S("12345678901234567890"), 0, 21, S("a12345678901234567890bcdefghijklmnopqrst")); +} + +template +void test42() +{ + test(S("abcdefghijklmnopqrst"), 1, 0, S("12345678901234567890"), 1, 0, S("abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, 0, S("12345678901234567890"), 1, 1, S("a2bcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, 0, S("12345678901234567890"), 1, 9, S("a234567890bcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, 0, S("12345678901234567890"), 1, 18, S("a234567890123456789bcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, 0, S("12345678901234567890"), 1, 19, S("a2345678901234567890bcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, 0, S("12345678901234567890"), 1, 20, S("a2345678901234567890bcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, 0, S("12345678901234567890"), 10, 0, S("abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, 0, S("12345678901234567890"), 10, 1, S("a1bcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, 0, S("12345678901234567890"), 10, 5, S("a12345bcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, 0, S("12345678901234567890"), 10, 9, S("a123456789bcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, 0, S("12345678901234567890"), 10, 10, S("a1234567890bcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, 0, S("12345678901234567890"), 10, 11, S("a1234567890bcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, 0, S("12345678901234567890"), 19, 0, S("abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, 0, S("12345678901234567890"), 19, 1, S("a0bcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, 0, S("12345678901234567890"), 19, 2, S("a0bcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, 0, S("12345678901234567890"), 20, 0, S("abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, 0, S("12345678901234567890"), 20, 1, S("abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, 0, S("12345678901234567890"), 21, 0, S("can't happen")); + test(S("abcdefghijklmnopqrst"), 1, 1, S(""), 0, 0, S("acdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, 1, S(""), 0, 1, S("acdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, 1, S(""), 1, 0, S("can't happen")); + test(S("abcdefghijklmnopqrst"), 1, 1, S("12345"), 0, 0, S("acdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, 1, S("12345"), 0, 1, S("a1cdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, 1, S("12345"), 0, 2, S("a12cdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, 1, S("12345"), 0, 4, S("a1234cdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, 1, S("12345"), 0, 5, S("a12345cdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, 1, S("12345"), 0, 6, S("a12345cdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, 1, S("12345"), 1, 0, S("acdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, 1, S("12345"), 1, 1, S("a2cdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, 1, S("12345"), 1, 2, S("a23cdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, 1, S("12345"), 1, 3, S("a234cdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, 1, S("12345"), 1, 4, S("a2345cdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, 1, S("12345"), 1, 5, S("a2345cdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, 1, S("12345"), 2, 0, S("acdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, 1, S("12345"), 2, 1, S("a3cdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, 1, S("12345"), 2, 2, S("a34cdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, 1, S("12345"), 2, 3, S("a345cdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, 1, S("12345"), 2, 4, S("a345cdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, 1, S("12345"), 4, 0, S("acdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, 1, S("12345"), 4, 1, S("a5cdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, 1, S("12345"), 4, 2, S("a5cdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, 1, S("12345"), 5, 0, S("acdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, 1, S("12345"), 5, 1, S("acdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, 1, S("12345"), 6, 0, S("can't happen")); + test(S("abcdefghijklmnopqrst"), 1, 1, S("1234567890"), 0, 0, S("acdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, 1, S("1234567890"), 0, 1, S("a1cdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, 1, S("1234567890"), 0, 5, S("a12345cdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, 1, S("1234567890"), 0, 9, S("a123456789cdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, 1, S("1234567890"), 0, 10, S("a1234567890cdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, 1, S("1234567890"), 0, 11, S("a1234567890cdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, 1, S("1234567890"), 1, 0, S("acdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, 1, S("1234567890"), 1, 1, S("a2cdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, 1, S("1234567890"), 1, 4, S("a2345cdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, 1, S("1234567890"), 1, 8, S("a23456789cdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, 1, S("1234567890"), 1, 9, S("a234567890cdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, 1, S("1234567890"), 1, 10, S("a234567890cdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, 1, S("1234567890"), 5, 0, S("acdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, 1, S("1234567890"), 5, 1, S("a6cdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, 1, S("1234567890"), 5, 2, S("a67cdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, 1, S("1234567890"), 5, 4, S("a6789cdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, 1, S("1234567890"), 5, 5, S("a67890cdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, 1, S("1234567890"), 5, 6, S("a67890cdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, 1, S("1234567890"), 9, 0, S("acdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, 1, S("1234567890"), 9, 1, S("a0cdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, 1, S("1234567890"), 9, 2, S("a0cdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, 1, S("1234567890"), 10, 0, S("acdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, 1, S("1234567890"), 10, 1, S("acdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, 1, S("1234567890"), 11, 0, S("can't happen")); + test(S("abcdefghijklmnopqrst"), 1, 1, S("12345678901234567890"), 0, 0, S("acdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, 1, S("12345678901234567890"), 0, 1, S("a1cdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, 1, S("12345678901234567890"), 0, 10, S("a1234567890cdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, 1, S("12345678901234567890"), 0, 19, S("a1234567890123456789cdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, 1, S("12345678901234567890"), 0, 20, S("a12345678901234567890cdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, 1, S("12345678901234567890"), 0, 21, S("a12345678901234567890cdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, 1, S("12345678901234567890"), 1, 0, S("acdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, 1, S("12345678901234567890"), 1, 1, S("a2cdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, 1, S("12345678901234567890"), 1, 9, S("a234567890cdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, 1, S("12345678901234567890"), 1, 18, S("a234567890123456789cdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, 1, S("12345678901234567890"), 1, 19, S("a2345678901234567890cdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, 1, S("12345678901234567890"), 1, 20, S("a2345678901234567890cdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, 1, S("12345678901234567890"), 10, 0, S("acdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, 1, S("12345678901234567890"), 10, 1, S("a1cdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, 1, S("12345678901234567890"), 10, 5, S("a12345cdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, 1, S("12345678901234567890"), 10, 9, S("a123456789cdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, 1, S("12345678901234567890"), 10, 10, S("a1234567890cdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, 1, S("12345678901234567890"), 10, 11, S("a1234567890cdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, 1, S("12345678901234567890"), 19, 0, S("acdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, 1, S("12345678901234567890"), 19, 1, S("a0cdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, 1, S("12345678901234567890"), 19, 2, S("a0cdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, 1, S("12345678901234567890"), 20, 0, S("acdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, 1, S("12345678901234567890"), 20, 1, S("acdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, 1, S("12345678901234567890"), 21, 0, S("can't happen")); + test(S("abcdefghijklmnopqrst"), 1, 9, S(""), 0, 0, S("aklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, 9, S(""), 0, 1, S("aklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, 9, S(""), 1, 0, S("can't happen")); + test(S("abcdefghijklmnopqrst"), 1, 9, S("12345"), 0, 0, S("aklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, 9, S("12345"), 0, 1, S("a1klmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, 9, S("12345"), 0, 2, S("a12klmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, 9, S("12345"), 0, 4, S("a1234klmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, 9, S("12345"), 0, 5, S("a12345klmnopqrst")); +} + +template +void test43() +{ + test(S("abcdefghijklmnopqrst"), 1, 9, S("12345"), 0, 6, S("a12345klmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, 9, S("12345"), 1, 0, S("aklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, 9, S("12345"), 1, 1, S("a2klmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, 9, S("12345"), 1, 2, S("a23klmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, 9, S("12345"), 1, 3, S("a234klmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, 9, S("12345"), 1, 4, S("a2345klmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, 9, S("12345"), 1, 5, S("a2345klmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, 9, S("12345"), 2, 0, S("aklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, 9, S("12345"), 2, 1, S("a3klmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, 9, S("12345"), 2, 2, S("a34klmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, 9, S("12345"), 2, 3, S("a345klmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, 9, S("12345"), 2, 4, S("a345klmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, 9, S("12345"), 4, 0, S("aklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, 9, S("12345"), 4, 1, S("a5klmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, 9, S("12345"), 4, 2, S("a5klmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, 9, S("12345"), 5, 0, S("aklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, 9, S("12345"), 5, 1, S("aklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, 9, S("12345"), 6, 0, S("can't happen")); + test(S("abcdefghijklmnopqrst"), 1, 9, S("1234567890"), 0, 0, S("aklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, 9, S("1234567890"), 0, 1, S("a1klmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, 9, S("1234567890"), 0, 5, S("a12345klmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, 9, S("1234567890"), 0, 9, S("a123456789klmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, 9, S("1234567890"), 0, 10, S("a1234567890klmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, 9, S("1234567890"), 0, 11, S("a1234567890klmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, 9, S("1234567890"), 1, 0, S("aklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, 9, S("1234567890"), 1, 1, S("a2klmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, 9, S("1234567890"), 1, 4, S("a2345klmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, 9, S("1234567890"), 1, 8, S("a23456789klmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, 9, S("1234567890"), 1, 9, S("a234567890klmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, 9, S("1234567890"), 1, 10, S("a234567890klmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, 9, S("1234567890"), 5, 0, S("aklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, 9, S("1234567890"), 5, 1, S("a6klmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, 9, S("1234567890"), 5, 2, S("a67klmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, 9, S("1234567890"), 5, 4, S("a6789klmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, 9, S("1234567890"), 5, 5, S("a67890klmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, 9, S("1234567890"), 5, 6, S("a67890klmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, 9, S("1234567890"), 9, 0, S("aklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, 9, S("1234567890"), 9, 1, S("a0klmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, 9, S("1234567890"), 9, 2, S("a0klmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, 9, S("1234567890"), 10, 0, S("aklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, 9, S("1234567890"), 10, 1, S("aklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, 9, S("1234567890"), 11, 0, S("can't happen")); + test(S("abcdefghijklmnopqrst"), 1, 9, S("12345678901234567890"), 0, 0, S("aklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, 9, S("12345678901234567890"), 0, 1, S("a1klmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, 9, S("12345678901234567890"), 0, 10, S("a1234567890klmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, 9, S("12345678901234567890"), 0, 19, S("a1234567890123456789klmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, 9, S("12345678901234567890"), 0, 20, S("a12345678901234567890klmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, 9, S("12345678901234567890"), 0, 21, S("a12345678901234567890klmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, 9, S("12345678901234567890"), 1, 0, S("aklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, 9, S("12345678901234567890"), 1, 1, S("a2klmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, 9, S("12345678901234567890"), 1, 9, S("a234567890klmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, 9, S("12345678901234567890"), 1, 18, S("a234567890123456789klmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, 9, S("12345678901234567890"), 1, 19, S("a2345678901234567890klmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, 9, S("12345678901234567890"), 1, 20, S("a2345678901234567890klmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, 9, S("12345678901234567890"), 10, 0, S("aklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, 9, S("12345678901234567890"), 10, 1, S("a1klmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, 9, S("12345678901234567890"), 10, 5, S("a12345klmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, 9, S("12345678901234567890"), 10, 9, S("a123456789klmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, 9, S("12345678901234567890"), 10, 10, S("a1234567890klmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, 9, S("12345678901234567890"), 10, 11, S("a1234567890klmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, 9, S("12345678901234567890"), 19, 0, S("aklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, 9, S("12345678901234567890"), 19, 1, S("a0klmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, 9, S("12345678901234567890"), 19, 2, S("a0klmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, 9, S("12345678901234567890"), 20, 0, S("aklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, 9, S("12345678901234567890"), 20, 1, S("aklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, 9, S("12345678901234567890"), 21, 0, S("can't happen")); + test(S("abcdefghijklmnopqrst"), 1, 18, S(""), 0, 0, S("at")); + test(S("abcdefghijklmnopqrst"), 1, 18, S(""), 0, 1, S("at")); + test(S("abcdefghijklmnopqrst"), 1, 18, S(""), 1, 0, S("can't happen")); + test(S("abcdefghijklmnopqrst"), 1, 18, S("12345"), 0, 0, S("at")); + test(S("abcdefghijklmnopqrst"), 1, 18, S("12345"), 0, 1, S("a1t")); + test(S("abcdefghijklmnopqrst"), 1, 18, S("12345"), 0, 2, S("a12t")); + test(S("abcdefghijklmnopqrst"), 1, 18, S("12345"), 0, 4, S("a1234t")); + test(S("abcdefghijklmnopqrst"), 1, 18, S("12345"), 0, 5, S("a12345t")); + test(S("abcdefghijklmnopqrst"), 1, 18, S("12345"), 0, 6, S("a12345t")); + test(S("abcdefghijklmnopqrst"), 1, 18, S("12345"), 1, 0, S("at")); + test(S("abcdefghijklmnopqrst"), 1, 18, S("12345"), 1, 1, S("a2t")); + test(S("abcdefghijklmnopqrst"), 1, 18, S("12345"), 1, 2, S("a23t")); + test(S("abcdefghijklmnopqrst"), 1, 18, S("12345"), 1, 3, S("a234t")); + test(S("abcdefghijklmnopqrst"), 1, 18, S("12345"), 1, 4, S("a2345t")); + test(S("abcdefghijklmnopqrst"), 1, 18, S("12345"), 1, 5, S("a2345t")); + test(S("abcdefghijklmnopqrst"), 1, 18, S("12345"), 2, 0, S("at")); + test(S("abcdefghijklmnopqrst"), 1, 18, S("12345"), 2, 1, S("a3t")); + test(S("abcdefghijklmnopqrst"), 1, 18, S("12345"), 2, 2, S("a34t")); + test(S("abcdefghijklmnopqrst"), 1, 18, S("12345"), 2, 3, S("a345t")); + test(S("abcdefghijklmnopqrst"), 1, 18, S("12345"), 2, 4, S("a345t")); + test(S("abcdefghijklmnopqrst"), 1, 18, S("12345"), 4, 0, S("at")); + test(S("abcdefghijklmnopqrst"), 1, 18, S("12345"), 4, 1, S("a5t")); + test(S("abcdefghijklmnopqrst"), 1, 18, S("12345"), 4, 2, S("a5t")); + test(S("abcdefghijklmnopqrst"), 1, 18, S("12345"), 5, 0, S("at")); + test(S("abcdefghijklmnopqrst"), 1, 18, S("12345"), 5, 1, S("at")); + test(S("abcdefghijklmnopqrst"), 1, 18, S("12345"), 6, 0, S("can't happen")); + test(S("abcdefghijklmnopqrst"), 1, 18, S("1234567890"), 0, 0, S("at")); + test(S("abcdefghijklmnopqrst"), 1, 18, S("1234567890"), 0, 1, S("a1t")); + test(S("abcdefghijklmnopqrst"), 1, 18, S("1234567890"), 0, 5, S("a12345t")); + test(S("abcdefghijklmnopqrst"), 1, 18, S("1234567890"), 0, 9, S("a123456789t")); + test(S("abcdefghijklmnopqrst"), 1, 18, S("1234567890"), 0, 10, S("a1234567890t")); + test(S("abcdefghijklmnopqrst"), 1, 18, S("1234567890"), 0, 11, S("a1234567890t")); + test(S("abcdefghijklmnopqrst"), 1, 18, S("1234567890"), 1, 0, S("at")); + test(S("abcdefghijklmnopqrst"), 1, 18, S("1234567890"), 1, 1, S("a2t")); +} + +template +void test44() +{ + test(S("abcdefghijklmnopqrst"), 1, 18, S("1234567890"), 1, 4, S("a2345t")); + test(S("abcdefghijklmnopqrst"), 1, 18, S("1234567890"), 1, 8, S("a23456789t")); + test(S("abcdefghijklmnopqrst"), 1, 18, S("1234567890"), 1, 9, S("a234567890t")); + test(S("abcdefghijklmnopqrst"), 1, 18, S("1234567890"), 1, 10, S("a234567890t")); + test(S("abcdefghijklmnopqrst"), 1, 18, S("1234567890"), 5, 0, S("at")); + test(S("abcdefghijklmnopqrst"), 1, 18, S("1234567890"), 5, 1, S("a6t")); + test(S("abcdefghijklmnopqrst"), 1, 18, S("1234567890"), 5, 2, S("a67t")); + test(S("abcdefghijklmnopqrst"), 1, 18, S("1234567890"), 5, 4, S("a6789t")); + test(S("abcdefghijklmnopqrst"), 1, 18, S("1234567890"), 5, 5, S("a67890t")); + test(S("abcdefghijklmnopqrst"), 1, 18, S("1234567890"), 5, 6, S("a67890t")); + test(S("abcdefghijklmnopqrst"), 1, 18, S("1234567890"), 9, 0, S("at")); + test(S("abcdefghijklmnopqrst"), 1, 18, S("1234567890"), 9, 1, S("a0t")); + test(S("abcdefghijklmnopqrst"), 1, 18, S("1234567890"), 9, 2, S("a0t")); + test(S("abcdefghijklmnopqrst"), 1, 18, S("1234567890"), 10, 0, S("at")); + test(S("abcdefghijklmnopqrst"), 1, 18, S("1234567890"), 10, 1, S("at")); + test(S("abcdefghijklmnopqrst"), 1, 18, S("1234567890"), 11, 0, S("can't happen")); + test(S("abcdefghijklmnopqrst"), 1, 18, S("12345678901234567890"), 0, 0, S("at")); + test(S("abcdefghijklmnopqrst"), 1, 18, S("12345678901234567890"), 0, 1, S("a1t")); + test(S("abcdefghijklmnopqrst"), 1, 18, S("12345678901234567890"), 0, 10, S("a1234567890t")); + test(S("abcdefghijklmnopqrst"), 1, 18, S("12345678901234567890"), 0, 19, S("a1234567890123456789t")); + test(S("abcdefghijklmnopqrst"), 1, 18, S("12345678901234567890"), 0, 20, S("a12345678901234567890t")); + test(S("abcdefghijklmnopqrst"), 1, 18, S("12345678901234567890"), 0, 21, S("a12345678901234567890t")); + test(S("abcdefghijklmnopqrst"), 1, 18, S("12345678901234567890"), 1, 0, S("at")); + test(S("abcdefghijklmnopqrst"), 1, 18, S("12345678901234567890"), 1, 1, S("a2t")); + test(S("abcdefghijklmnopqrst"), 1, 18, S("12345678901234567890"), 1, 9, S("a234567890t")); + test(S("abcdefghijklmnopqrst"), 1, 18, S("12345678901234567890"), 1, 18, S("a234567890123456789t")); + test(S("abcdefghijklmnopqrst"), 1, 18, S("12345678901234567890"), 1, 19, S("a2345678901234567890t")); + test(S("abcdefghijklmnopqrst"), 1, 18, S("12345678901234567890"), 1, 20, S("a2345678901234567890t")); + test(S("abcdefghijklmnopqrst"), 1, 18, S("12345678901234567890"), 10, 0, S("at")); + test(S("abcdefghijklmnopqrst"), 1, 18, S("12345678901234567890"), 10, 1, S("a1t")); + test(S("abcdefghijklmnopqrst"), 1, 18, S("12345678901234567890"), 10, 5, S("a12345t")); + test(S("abcdefghijklmnopqrst"), 1, 18, S("12345678901234567890"), 10, 9, S("a123456789t")); + test(S("abcdefghijklmnopqrst"), 1, 18, S("12345678901234567890"), 10, 10, S("a1234567890t")); + test(S("abcdefghijklmnopqrst"), 1, 18, S("12345678901234567890"), 10, 11, S("a1234567890t")); + test(S("abcdefghijklmnopqrst"), 1, 18, S("12345678901234567890"), 19, 0, S("at")); + test(S("abcdefghijklmnopqrst"), 1, 18, S("12345678901234567890"), 19, 1, S("a0t")); + test(S("abcdefghijklmnopqrst"), 1, 18, S("12345678901234567890"), 19, 2, S("a0t")); + test(S("abcdefghijklmnopqrst"), 1, 18, S("12345678901234567890"), 20, 0, S("at")); + test(S("abcdefghijklmnopqrst"), 1, 18, S("12345678901234567890"), 20, 1, S("at")); + test(S("abcdefghijklmnopqrst"), 1, 18, S("12345678901234567890"), 21, 0, S("can't happen")); + test(S("abcdefghijklmnopqrst"), 1, 19, S(""), 0, 0, S("a")); + test(S("abcdefghijklmnopqrst"), 1, 19, S(""), 0, 1, S("a")); + test(S("abcdefghijklmnopqrst"), 1, 19, S(""), 1, 0, S("can't happen")); + test(S("abcdefghijklmnopqrst"), 1, 19, S("12345"), 0, 0, S("a")); + test(S("abcdefghijklmnopqrst"), 1, 19, S("12345"), 0, 1, S("a1")); + test(S("abcdefghijklmnopqrst"), 1, 19, S("12345"), 0, 2, S("a12")); + test(S("abcdefghijklmnopqrst"), 1, 19, S("12345"), 0, 4, S("a1234")); + test(S("abcdefghijklmnopqrst"), 1, 19, S("12345"), 0, 5, S("a12345")); + test(S("abcdefghijklmnopqrst"), 1, 19, S("12345"), 0, 6, S("a12345")); + test(S("abcdefghijklmnopqrst"), 1, 19, S("12345"), 1, 0, S("a")); + test(S("abcdefghijklmnopqrst"), 1, 19, S("12345"), 1, 1, S("a2")); + test(S("abcdefghijklmnopqrst"), 1, 19, S("12345"), 1, 2, S("a23")); + test(S("abcdefghijklmnopqrst"), 1, 19, S("12345"), 1, 3, S("a234")); + test(S("abcdefghijklmnopqrst"), 1, 19, S("12345"), 1, 4, S("a2345")); + test(S("abcdefghijklmnopqrst"), 1, 19, S("12345"), 1, 5, S("a2345")); + test(S("abcdefghijklmnopqrst"), 1, 19, S("12345"), 2, 0, S("a")); + test(S("abcdefghijklmnopqrst"), 1, 19, S("12345"), 2, 1, S("a3")); + test(S("abcdefghijklmnopqrst"), 1, 19, S("12345"), 2, 2, S("a34")); + test(S("abcdefghijklmnopqrst"), 1, 19, S("12345"), 2, 3, S("a345")); + test(S("abcdefghijklmnopqrst"), 1, 19, S("12345"), 2, 4, S("a345")); + test(S("abcdefghijklmnopqrst"), 1, 19, S("12345"), 4, 0, S("a")); + test(S("abcdefghijklmnopqrst"), 1, 19, S("12345"), 4, 1, S("a5")); + test(S("abcdefghijklmnopqrst"), 1, 19, S("12345"), 4, 2, S("a5")); + test(S("abcdefghijklmnopqrst"), 1, 19, S("12345"), 5, 0, S("a")); + test(S("abcdefghijklmnopqrst"), 1, 19, S("12345"), 5, 1, S("a")); + test(S("abcdefghijklmnopqrst"), 1, 19, S("12345"), 6, 0, S("can't happen")); + test(S("abcdefghijklmnopqrst"), 1, 19, S("1234567890"), 0, 0, S("a")); + test(S("abcdefghijklmnopqrst"), 1, 19, S("1234567890"), 0, 1, S("a1")); + test(S("abcdefghijklmnopqrst"), 1, 19, S("1234567890"), 0, 5, S("a12345")); + test(S("abcdefghijklmnopqrst"), 1, 19, S("1234567890"), 0, 9, S("a123456789")); + test(S("abcdefghijklmnopqrst"), 1, 19, S("1234567890"), 0, 10, S("a1234567890")); + test(S("abcdefghijklmnopqrst"), 1, 19, S("1234567890"), 0, 11, S("a1234567890")); + test(S("abcdefghijklmnopqrst"), 1, 19, S("1234567890"), 1, 0, S("a")); + test(S("abcdefghijklmnopqrst"), 1, 19, S("1234567890"), 1, 1, S("a2")); + test(S("abcdefghijklmnopqrst"), 1, 19, S("1234567890"), 1, 4, S("a2345")); + test(S("abcdefghijklmnopqrst"), 1, 19, S("1234567890"), 1, 8, S("a23456789")); + test(S("abcdefghijklmnopqrst"), 1, 19, S("1234567890"), 1, 9, S("a234567890")); + test(S("abcdefghijklmnopqrst"), 1, 19, S("1234567890"), 1, 10, S("a234567890")); + test(S("abcdefghijklmnopqrst"), 1, 19, S("1234567890"), 5, 0, S("a")); + test(S("abcdefghijklmnopqrst"), 1, 19, S("1234567890"), 5, 1, S("a6")); + test(S("abcdefghijklmnopqrst"), 1, 19, S("1234567890"), 5, 2, S("a67")); + test(S("abcdefghijklmnopqrst"), 1, 19, S("1234567890"), 5, 4, S("a6789")); + test(S("abcdefghijklmnopqrst"), 1, 19, S("1234567890"), 5, 5, S("a67890")); + test(S("abcdefghijklmnopqrst"), 1, 19, S("1234567890"), 5, 6, S("a67890")); + test(S("abcdefghijklmnopqrst"), 1, 19, S("1234567890"), 9, 0, S("a")); + test(S("abcdefghijklmnopqrst"), 1, 19, S("1234567890"), 9, 1, S("a0")); + test(S("abcdefghijklmnopqrst"), 1, 19, S("1234567890"), 9, 2, S("a0")); + test(S("abcdefghijklmnopqrst"), 1, 19, S("1234567890"), 10, 0, S("a")); + test(S("abcdefghijklmnopqrst"), 1, 19, S("1234567890"), 10, 1, S("a")); + test(S("abcdefghijklmnopqrst"), 1, 19, S("1234567890"), 11, 0, S("can't happen")); + test(S("abcdefghijklmnopqrst"), 1, 19, S("12345678901234567890"), 0, 0, S("a")); + test(S("abcdefghijklmnopqrst"), 1, 19, S("12345678901234567890"), 0, 1, S("a1")); + test(S("abcdefghijklmnopqrst"), 1, 19, S("12345678901234567890"), 0, 10, S("a1234567890")); + test(S("abcdefghijklmnopqrst"), 1, 19, S("12345678901234567890"), 0, 19, S("a1234567890123456789")); + test(S("abcdefghijklmnopqrst"), 1, 19, S("12345678901234567890"), 0, 20, S("a12345678901234567890")); + test(S("abcdefghijklmnopqrst"), 1, 19, S("12345678901234567890"), 0, 21, S("a12345678901234567890")); + test(S("abcdefghijklmnopqrst"), 1, 19, S("12345678901234567890"), 1, 0, S("a")); + test(S("abcdefghijklmnopqrst"), 1, 19, S("12345678901234567890"), 1, 1, S("a2")); + test(S("abcdefghijklmnopqrst"), 1, 19, S("12345678901234567890"), 1, 9, S("a234567890")); + test(S("abcdefghijklmnopqrst"), 1, 19, S("12345678901234567890"), 1, 18, S("a234567890123456789")); +} + +template +void test45() +{ + test(S("abcdefghijklmnopqrst"), 1, 19, S("12345678901234567890"), 1, 19, S("a2345678901234567890")); + test(S("abcdefghijklmnopqrst"), 1, 19, S("12345678901234567890"), 1, 20, S("a2345678901234567890")); + test(S("abcdefghijklmnopqrst"), 1, 19, S("12345678901234567890"), 10, 0, S("a")); + test(S("abcdefghijklmnopqrst"), 1, 19, S("12345678901234567890"), 10, 1, S("a1")); + test(S("abcdefghijklmnopqrst"), 1, 19, S("12345678901234567890"), 10, 5, S("a12345")); + test(S("abcdefghijklmnopqrst"), 1, 19, S("12345678901234567890"), 10, 9, S("a123456789")); + test(S("abcdefghijklmnopqrst"), 1, 19, S("12345678901234567890"), 10, 10, S("a1234567890")); + test(S("abcdefghijklmnopqrst"), 1, 19, S("12345678901234567890"), 10, 11, S("a1234567890")); + test(S("abcdefghijklmnopqrst"), 1, 19, S("12345678901234567890"), 19, 0, S("a")); + test(S("abcdefghijklmnopqrst"), 1, 19, S("12345678901234567890"), 19, 1, S("a0")); + test(S("abcdefghijklmnopqrst"), 1, 19, S("12345678901234567890"), 19, 2, S("a0")); + test(S("abcdefghijklmnopqrst"), 1, 19, S("12345678901234567890"), 20, 0, S("a")); + test(S("abcdefghijklmnopqrst"), 1, 19, S("12345678901234567890"), 20, 1, S("a")); + test(S("abcdefghijklmnopqrst"), 1, 19, S("12345678901234567890"), 21, 0, S("can't happen")); + test(S("abcdefghijklmnopqrst"), 1, 20, S(""), 0, 0, S("a")); + test(S("abcdefghijklmnopqrst"), 1, 20, S(""), 0, 1, S("a")); + test(S("abcdefghijklmnopqrst"), 1, 20, S(""), 1, 0, S("can't happen")); + test(S("abcdefghijklmnopqrst"), 1, 20, S("12345"), 0, 0, S("a")); + test(S("abcdefghijklmnopqrst"), 1, 20, S("12345"), 0, 1, S("a1")); + test(S("abcdefghijklmnopqrst"), 1, 20, S("12345"), 0, 2, S("a12")); + test(S("abcdefghijklmnopqrst"), 1, 20, S("12345"), 0, 4, S("a1234")); + test(S("abcdefghijklmnopqrst"), 1, 20, S("12345"), 0, 5, S("a12345")); + test(S("abcdefghijklmnopqrst"), 1, 20, S("12345"), 0, 6, S("a12345")); + test(S("abcdefghijklmnopqrst"), 1, 20, S("12345"), 1, 0, S("a")); + test(S("abcdefghijklmnopqrst"), 1, 20, S("12345"), 1, 1, S("a2")); + test(S("abcdefghijklmnopqrst"), 1, 20, S("12345"), 1, 2, S("a23")); + test(S("abcdefghijklmnopqrst"), 1, 20, S("12345"), 1, 3, S("a234")); + test(S("abcdefghijklmnopqrst"), 1, 20, S("12345"), 1, 4, S("a2345")); + test(S("abcdefghijklmnopqrst"), 1, 20, S("12345"), 1, 5, S("a2345")); + test(S("abcdefghijklmnopqrst"), 1, 20, S("12345"), 2, 0, S("a")); + test(S("abcdefghijklmnopqrst"), 1, 20, S("12345"), 2, 1, S("a3")); + test(S("abcdefghijklmnopqrst"), 1, 20, S("12345"), 2, 2, S("a34")); + test(S("abcdefghijklmnopqrst"), 1, 20, S("12345"), 2, 3, S("a345")); + test(S("abcdefghijklmnopqrst"), 1, 20, S("12345"), 2, 4, S("a345")); + test(S("abcdefghijklmnopqrst"), 1, 20, S("12345"), 4, 0, S("a")); + test(S("abcdefghijklmnopqrst"), 1, 20, S("12345"), 4, 1, S("a5")); + test(S("abcdefghijklmnopqrst"), 1, 20, S("12345"), 4, 2, S("a5")); + test(S("abcdefghijklmnopqrst"), 1, 20, S("12345"), 5, 0, S("a")); + test(S("abcdefghijklmnopqrst"), 1, 20, S("12345"), 5, 1, S("a")); + test(S("abcdefghijklmnopqrst"), 1, 20, S("12345"), 6, 0, S("can't happen")); + test(S("abcdefghijklmnopqrst"), 1, 20, S("1234567890"), 0, 0, S("a")); + test(S("abcdefghijklmnopqrst"), 1, 20, S("1234567890"), 0, 1, S("a1")); + test(S("abcdefghijklmnopqrst"), 1, 20, S("1234567890"), 0, 5, S("a12345")); + test(S("abcdefghijklmnopqrst"), 1, 20, S("1234567890"), 0, 9, S("a123456789")); + test(S("abcdefghijklmnopqrst"), 1, 20, S("1234567890"), 0, 10, S("a1234567890")); + test(S("abcdefghijklmnopqrst"), 1, 20, S("1234567890"), 0, 11, S("a1234567890")); + test(S("abcdefghijklmnopqrst"), 1, 20, S("1234567890"), 1, 0, S("a")); + test(S("abcdefghijklmnopqrst"), 1, 20, S("1234567890"), 1, 1, S("a2")); + test(S("abcdefghijklmnopqrst"), 1, 20, S("1234567890"), 1, 4, S("a2345")); + test(S("abcdefghijklmnopqrst"), 1, 20, S("1234567890"), 1, 8, S("a23456789")); + test(S("abcdefghijklmnopqrst"), 1, 20, S("1234567890"), 1, 9, S("a234567890")); + test(S("abcdefghijklmnopqrst"), 1, 20, S("1234567890"), 1, 10, S("a234567890")); + test(S("abcdefghijklmnopqrst"), 1, 20, S("1234567890"), 5, 0, S("a")); + test(S("abcdefghijklmnopqrst"), 1, 20, S("1234567890"), 5, 1, S("a6")); + test(S("abcdefghijklmnopqrst"), 1, 20, S("1234567890"), 5, 2, S("a67")); + test(S("abcdefghijklmnopqrst"), 1, 20, S("1234567890"), 5, 4, S("a6789")); + test(S("abcdefghijklmnopqrst"), 1, 20, S("1234567890"), 5, 5, S("a67890")); + test(S("abcdefghijklmnopqrst"), 1, 20, S("1234567890"), 5, 6, S("a67890")); + test(S("abcdefghijklmnopqrst"), 1, 20, S("1234567890"), 9, 0, S("a")); + test(S("abcdefghijklmnopqrst"), 1, 20, S("1234567890"), 9, 1, S("a0")); + test(S("abcdefghijklmnopqrst"), 1, 20, S("1234567890"), 9, 2, S("a0")); + test(S("abcdefghijklmnopqrst"), 1, 20, S("1234567890"), 10, 0, S("a")); + test(S("abcdefghijklmnopqrst"), 1, 20, S("1234567890"), 10, 1, S("a")); + test(S("abcdefghijklmnopqrst"), 1, 20, S("1234567890"), 11, 0, S("can't happen")); + test(S("abcdefghijklmnopqrst"), 1, 20, S("12345678901234567890"), 0, 0, S("a")); + test(S("abcdefghijklmnopqrst"), 1, 20, S("12345678901234567890"), 0, 1, S("a1")); + test(S("abcdefghijklmnopqrst"), 1, 20, S("12345678901234567890"), 0, 10, S("a1234567890")); + test(S("abcdefghijklmnopqrst"), 1, 20, S("12345678901234567890"), 0, 19, S("a1234567890123456789")); + test(S("abcdefghijklmnopqrst"), 1, 20, S("12345678901234567890"), 0, 20, S("a12345678901234567890")); + test(S("abcdefghijklmnopqrst"), 1, 20, S("12345678901234567890"), 0, 21, S("a12345678901234567890")); + test(S("abcdefghijklmnopqrst"), 1, 20, S("12345678901234567890"), 1, 0, S("a")); + test(S("abcdefghijklmnopqrst"), 1, 20, S("12345678901234567890"), 1, 1, S("a2")); + test(S("abcdefghijklmnopqrst"), 1, 20, S("12345678901234567890"), 1, 9, S("a234567890")); + test(S("abcdefghijklmnopqrst"), 1, 20, S("12345678901234567890"), 1, 18, S("a234567890123456789")); + test(S("abcdefghijklmnopqrst"), 1, 20, S("12345678901234567890"), 1, 19, S("a2345678901234567890")); + test(S("abcdefghijklmnopqrst"), 1, 20, S("12345678901234567890"), 1, 20, S("a2345678901234567890")); + test(S("abcdefghijklmnopqrst"), 1, 20, S("12345678901234567890"), 10, 0, S("a")); + test(S("abcdefghijklmnopqrst"), 1, 20, S("12345678901234567890"), 10, 1, S("a1")); + test(S("abcdefghijklmnopqrst"), 1, 20, S("12345678901234567890"), 10, 5, S("a12345")); + test(S("abcdefghijklmnopqrst"), 1, 20, S("12345678901234567890"), 10, 9, S("a123456789")); + test(S("abcdefghijklmnopqrst"), 1, 20, S("12345678901234567890"), 10, 10, S("a1234567890")); + test(S("abcdefghijklmnopqrst"), 1, 20, S("12345678901234567890"), 10, 11, S("a1234567890")); + test(S("abcdefghijklmnopqrst"), 1, 20, S("12345678901234567890"), 19, 0, S("a")); + test(S("abcdefghijklmnopqrst"), 1, 20, S("12345678901234567890"), 19, 1, S("a0")); + test(S("abcdefghijklmnopqrst"), 1, 20, S("12345678901234567890"), 19, 2, S("a0")); + test(S("abcdefghijklmnopqrst"), 1, 20, S("12345678901234567890"), 20, 0, S("a")); + test(S("abcdefghijklmnopqrst"), 1, 20, S("12345678901234567890"), 20, 1, S("a")); + test(S("abcdefghijklmnopqrst"), 1, 20, S("12345678901234567890"), 21, 0, S("can't happen")); + test(S("abcdefghijklmnopqrst"), 10, 0, S(""), 0, 0, S("abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 10, 0, S(""), 0, 1, S("abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 10, 0, S(""), 1, 0, S("can't happen")); + test(S("abcdefghijklmnopqrst"), 10, 0, S("12345"), 0, 0, S("abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 10, 0, S("12345"), 0, 1, S("abcdefghij1klmnopqrst")); + test(S("abcdefghijklmnopqrst"), 10, 0, S("12345"), 0, 2, S("abcdefghij12klmnopqrst")); + test(S("abcdefghijklmnopqrst"), 10, 0, S("12345"), 0, 4, S("abcdefghij1234klmnopqrst")); + test(S("abcdefghijklmnopqrst"), 10, 0, S("12345"), 0, 5, S("abcdefghij12345klmnopqrst")); + test(S("abcdefghijklmnopqrst"), 10, 0, S("12345"), 0, 6, S("abcdefghij12345klmnopqrst")); + test(S("abcdefghijklmnopqrst"), 10, 0, S("12345"), 1, 0, S("abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 10, 0, S("12345"), 1, 1, S("abcdefghij2klmnopqrst")); + test(S("abcdefghijklmnopqrst"), 10, 0, S("12345"), 1, 2, S("abcdefghij23klmnopqrst")); +} + +template +void test46() +{ + test(S("abcdefghijklmnopqrst"), 10, 0, S("12345"), 1, 3, S("abcdefghij234klmnopqrst")); + test(S("abcdefghijklmnopqrst"), 10, 0, S("12345"), 1, 4, S("abcdefghij2345klmnopqrst")); + test(S("abcdefghijklmnopqrst"), 10, 0, S("12345"), 1, 5, S("abcdefghij2345klmnopqrst")); + test(S("abcdefghijklmnopqrst"), 10, 0, S("12345"), 2, 0, S("abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 10, 0, S("12345"), 2, 1, S("abcdefghij3klmnopqrst")); + test(S("abcdefghijklmnopqrst"), 10, 0, S("12345"), 2, 2, S("abcdefghij34klmnopqrst")); + test(S("abcdefghijklmnopqrst"), 10, 0, S("12345"), 2, 3, S("abcdefghij345klmnopqrst")); + test(S("abcdefghijklmnopqrst"), 10, 0, S("12345"), 2, 4, S("abcdefghij345klmnopqrst")); + test(S("abcdefghijklmnopqrst"), 10, 0, S("12345"), 4, 0, S("abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 10, 0, S("12345"), 4, 1, S("abcdefghij5klmnopqrst")); + test(S("abcdefghijklmnopqrst"), 10, 0, S("12345"), 4, 2, S("abcdefghij5klmnopqrst")); + test(S("abcdefghijklmnopqrst"), 10, 0, S("12345"), 5, 0, S("abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 10, 0, S("12345"), 5, 1, S("abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 10, 0, S("12345"), 6, 0, S("can't happen")); + test(S("abcdefghijklmnopqrst"), 10, 0, S("1234567890"), 0, 0, S("abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 10, 0, S("1234567890"), 0, 1, S("abcdefghij1klmnopqrst")); + test(S("abcdefghijklmnopqrst"), 10, 0, S("1234567890"), 0, 5, S("abcdefghij12345klmnopqrst")); + test(S("abcdefghijklmnopqrst"), 10, 0, S("1234567890"), 0, 9, S("abcdefghij123456789klmnopqrst")); + test(S("abcdefghijklmnopqrst"), 10, 0, S("1234567890"), 0, 10, S("abcdefghij1234567890klmnopqrst")); + test(S("abcdefghijklmnopqrst"), 10, 0, S("1234567890"), 0, 11, S("abcdefghij1234567890klmnopqrst")); + test(S("abcdefghijklmnopqrst"), 10, 0, S("1234567890"), 1, 0, S("abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 10, 0, S("1234567890"), 1, 1, S("abcdefghij2klmnopqrst")); + test(S("abcdefghijklmnopqrst"), 10, 0, S("1234567890"), 1, 4, S("abcdefghij2345klmnopqrst")); + test(S("abcdefghijklmnopqrst"), 10, 0, S("1234567890"), 1, 8, S("abcdefghij23456789klmnopqrst")); + test(S("abcdefghijklmnopqrst"), 10, 0, S("1234567890"), 1, 9, S("abcdefghij234567890klmnopqrst")); + test(S("abcdefghijklmnopqrst"), 10, 0, S("1234567890"), 1, 10, S("abcdefghij234567890klmnopqrst")); + test(S("abcdefghijklmnopqrst"), 10, 0, S("1234567890"), 5, 0, S("abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 10, 0, S("1234567890"), 5, 1, S("abcdefghij6klmnopqrst")); + test(S("abcdefghijklmnopqrst"), 10, 0, S("1234567890"), 5, 2, S("abcdefghij67klmnopqrst")); + test(S("abcdefghijklmnopqrst"), 10, 0, S("1234567890"), 5, 4, S("abcdefghij6789klmnopqrst")); + test(S("abcdefghijklmnopqrst"), 10, 0, S("1234567890"), 5, 5, S("abcdefghij67890klmnopqrst")); + test(S("abcdefghijklmnopqrst"), 10, 0, S("1234567890"), 5, 6, S("abcdefghij67890klmnopqrst")); + test(S("abcdefghijklmnopqrst"), 10, 0, S("1234567890"), 9, 0, S("abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 10, 0, S("1234567890"), 9, 1, S("abcdefghij0klmnopqrst")); + test(S("abcdefghijklmnopqrst"), 10, 0, S("1234567890"), 9, 2, S("abcdefghij0klmnopqrst")); + test(S("abcdefghijklmnopqrst"), 10, 0, S("1234567890"), 10, 0, S("abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 10, 0, S("1234567890"), 10, 1, S("abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 10, 0, S("1234567890"), 11, 0, S("can't happen")); + test(S("abcdefghijklmnopqrst"), 10, 0, S("12345678901234567890"), 0, 0, S("abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 10, 0, S("12345678901234567890"), 0, 1, S("abcdefghij1klmnopqrst")); + test(S("abcdefghijklmnopqrst"), 10, 0, S("12345678901234567890"), 0, 10, S("abcdefghij1234567890klmnopqrst")); + test(S("abcdefghijklmnopqrst"), 10, 0, S("12345678901234567890"), 0, 19, S("abcdefghij1234567890123456789klmnopqrst")); + test(S("abcdefghijklmnopqrst"), 10, 0, S("12345678901234567890"), 0, 20, S("abcdefghij12345678901234567890klmnopqrst")); + test(S("abcdefghijklmnopqrst"), 10, 0, S("12345678901234567890"), 0, 21, S("abcdefghij12345678901234567890klmnopqrst")); + test(S("abcdefghijklmnopqrst"), 10, 0, S("12345678901234567890"), 1, 0, S("abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 10, 0, S("12345678901234567890"), 1, 1, S("abcdefghij2klmnopqrst")); + test(S("abcdefghijklmnopqrst"), 10, 0, S("12345678901234567890"), 1, 9, S("abcdefghij234567890klmnopqrst")); + test(S("abcdefghijklmnopqrst"), 10, 0, S("12345678901234567890"), 1, 18, S("abcdefghij234567890123456789klmnopqrst")); + test(S("abcdefghijklmnopqrst"), 10, 0, S("12345678901234567890"), 1, 19, S("abcdefghij2345678901234567890klmnopqrst")); + test(S("abcdefghijklmnopqrst"), 10, 0, S("12345678901234567890"), 1, 20, S("abcdefghij2345678901234567890klmnopqrst")); + test(S("abcdefghijklmnopqrst"), 10, 0, S("12345678901234567890"), 10, 0, S("abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 10, 0, S("12345678901234567890"), 10, 1, S("abcdefghij1klmnopqrst")); + test(S("abcdefghijklmnopqrst"), 10, 0, S("12345678901234567890"), 10, 5, S("abcdefghij12345klmnopqrst")); + test(S("abcdefghijklmnopqrst"), 10, 0, S("12345678901234567890"), 10, 9, S("abcdefghij123456789klmnopqrst")); + test(S("abcdefghijklmnopqrst"), 10, 0, S("12345678901234567890"), 10, 10, S("abcdefghij1234567890klmnopqrst")); + test(S("abcdefghijklmnopqrst"), 10, 0, S("12345678901234567890"), 10, 11, S("abcdefghij1234567890klmnopqrst")); + test(S("abcdefghijklmnopqrst"), 10, 0, S("12345678901234567890"), 19, 0, S("abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 10, 0, S("12345678901234567890"), 19, 1, S("abcdefghij0klmnopqrst")); + test(S("abcdefghijklmnopqrst"), 10, 0, S("12345678901234567890"), 19, 2, S("abcdefghij0klmnopqrst")); + test(S("abcdefghijklmnopqrst"), 10, 0, S("12345678901234567890"), 20, 0, S("abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 10, 0, S("12345678901234567890"), 20, 1, S("abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 10, 0, S("12345678901234567890"), 21, 0, S("can't happen")); + test(S("abcdefghijklmnopqrst"), 10, 1, S(""), 0, 0, S("abcdefghijlmnopqrst")); + test(S("abcdefghijklmnopqrst"), 10, 1, S(""), 0, 1, S("abcdefghijlmnopqrst")); + test(S("abcdefghijklmnopqrst"), 10, 1, S(""), 1, 0, S("can't happen")); + test(S("abcdefghijklmnopqrst"), 10, 1, S("12345"), 0, 0, S("abcdefghijlmnopqrst")); + test(S("abcdefghijklmnopqrst"), 10, 1, S("12345"), 0, 1, S("abcdefghij1lmnopqrst")); + test(S("abcdefghijklmnopqrst"), 10, 1, S("12345"), 0, 2, S("abcdefghij12lmnopqrst")); + test(S("abcdefghijklmnopqrst"), 10, 1, S("12345"), 0, 4, S("abcdefghij1234lmnopqrst")); + test(S("abcdefghijklmnopqrst"), 10, 1, S("12345"), 0, 5, S("abcdefghij12345lmnopqrst")); + test(S("abcdefghijklmnopqrst"), 10, 1, S("12345"), 0, 6, S("abcdefghij12345lmnopqrst")); + test(S("abcdefghijklmnopqrst"), 10, 1, S("12345"), 1, 0, S("abcdefghijlmnopqrst")); + test(S("abcdefghijklmnopqrst"), 10, 1, S("12345"), 1, 1, S("abcdefghij2lmnopqrst")); + test(S("abcdefghijklmnopqrst"), 10, 1, S("12345"), 1, 2, S("abcdefghij23lmnopqrst")); + test(S("abcdefghijklmnopqrst"), 10, 1, S("12345"), 1, 3, S("abcdefghij234lmnopqrst")); + test(S("abcdefghijklmnopqrst"), 10, 1, S("12345"), 1, 4, S("abcdefghij2345lmnopqrst")); + test(S("abcdefghijklmnopqrst"), 10, 1, S("12345"), 1, 5, S("abcdefghij2345lmnopqrst")); + test(S("abcdefghijklmnopqrst"), 10, 1, S("12345"), 2, 0, S("abcdefghijlmnopqrst")); + test(S("abcdefghijklmnopqrst"), 10, 1, S("12345"), 2, 1, S("abcdefghij3lmnopqrst")); + test(S("abcdefghijklmnopqrst"), 10, 1, S("12345"), 2, 2, S("abcdefghij34lmnopqrst")); + test(S("abcdefghijklmnopqrst"), 10, 1, S("12345"), 2, 3, S("abcdefghij345lmnopqrst")); + test(S("abcdefghijklmnopqrst"), 10, 1, S("12345"), 2, 4, S("abcdefghij345lmnopqrst")); + test(S("abcdefghijklmnopqrst"), 10, 1, S("12345"), 4, 0, S("abcdefghijlmnopqrst")); + test(S("abcdefghijklmnopqrst"), 10, 1, S("12345"), 4, 1, S("abcdefghij5lmnopqrst")); + test(S("abcdefghijklmnopqrst"), 10, 1, S("12345"), 4, 2, S("abcdefghij5lmnopqrst")); + test(S("abcdefghijklmnopqrst"), 10, 1, S("12345"), 5, 0, S("abcdefghijlmnopqrst")); + test(S("abcdefghijklmnopqrst"), 10, 1, S("12345"), 5, 1, S("abcdefghijlmnopqrst")); + test(S("abcdefghijklmnopqrst"), 10, 1, S("12345"), 6, 0, S("can't happen")); + test(S("abcdefghijklmnopqrst"), 10, 1, S("1234567890"), 0, 0, S("abcdefghijlmnopqrst")); + test(S("abcdefghijklmnopqrst"), 10, 1, S("1234567890"), 0, 1, S("abcdefghij1lmnopqrst")); + test(S("abcdefghijklmnopqrst"), 10, 1, S("1234567890"), 0, 5, S("abcdefghij12345lmnopqrst")); + test(S("abcdefghijklmnopqrst"), 10, 1, S("1234567890"), 0, 9, S("abcdefghij123456789lmnopqrst")); + test(S("abcdefghijklmnopqrst"), 10, 1, S("1234567890"), 0, 10, S("abcdefghij1234567890lmnopqrst")); + test(S("abcdefghijklmnopqrst"), 10, 1, S("1234567890"), 0, 11, S("abcdefghij1234567890lmnopqrst")); + test(S("abcdefghijklmnopqrst"), 10, 1, S("1234567890"), 1, 0, S("abcdefghijlmnopqrst")); + test(S("abcdefghijklmnopqrst"), 10, 1, S("1234567890"), 1, 1, S("abcdefghij2lmnopqrst")); + test(S("abcdefghijklmnopqrst"), 10, 1, S("1234567890"), 1, 4, S("abcdefghij2345lmnopqrst")); + test(S("abcdefghijklmnopqrst"), 10, 1, S("1234567890"), 1, 8, S("abcdefghij23456789lmnopqrst")); + test(S("abcdefghijklmnopqrst"), 10, 1, S("1234567890"), 1, 9, S("abcdefghij234567890lmnopqrst")); + test(S("abcdefghijklmnopqrst"), 10, 1, S("1234567890"), 1, 10, S("abcdefghij234567890lmnopqrst")); +} + +template +void test47() +{ + test(S("abcdefghijklmnopqrst"), 10, 1, S("1234567890"), 5, 0, S("abcdefghijlmnopqrst")); + test(S("abcdefghijklmnopqrst"), 10, 1, S("1234567890"), 5, 1, S("abcdefghij6lmnopqrst")); + test(S("abcdefghijklmnopqrst"), 10, 1, S("1234567890"), 5, 2, S("abcdefghij67lmnopqrst")); + test(S("abcdefghijklmnopqrst"), 10, 1, S("1234567890"), 5, 4, S("abcdefghij6789lmnopqrst")); + test(S("abcdefghijklmnopqrst"), 10, 1, S("1234567890"), 5, 5, S("abcdefghij67890lmnopqrst")); + test(S("abcdefghijklmnopqrst"), 10, 1, S("1234567890"), 5, 6, S("abcdefghij67890lmnopqrst")); + test(S("abcdefghijklmnopqrst"), 10, 1, S("1234567890"), 9, 0, S("abcdefghijlmnopqrst")); + test(S("abcdefghijklmnopqrst"), 10, 1, S("1234567890"), 9, 1, S("abcdefghij0lmnopqrst")); + test(S("abcdefghijklmnopqrst"), 10, 1, S("1234567890"), 9, 2, S("abcdefghij0lmnopqrst")); + test(S("abcdefghijklmnopqrst"), 10, 1, S("1234567890"), 10, 0, S("abcdefghijlmnopqrst")); + test(S("abcdefghijklmnopqrst"), 10, 1, S("1234567890"), 10, 1, S("abcdefghijlmnopqrst")); + test(S("abcdefghijklmnopqrst"), 10, 1, S("1234567890"), 11, 0, S("can't happen")); + test(S("abcdefghijklmnopqrst"), 10, 1, S("12345678901234567890"), 0, 0, S("abcdefghijlmnopqrst")); + test(S("abcdefghijklmnopqrst"), 10, 1, S("12345678901234567890"), 0, 1, S("abcdefghij1lmnopqrst")); + test(S("abcdefghijklmnopqrst"), 10, 1, S("12345678901234567890"), 0, 10, S("abcdefghij1234567890lmnopqrst")); + test(S("abcdefghijklmnopqrst"), 10, 1, S("12345678901234567890"), 0, 19, S("abcdefghij1234567890123456789lmnopqrst")); + test(S("abcdefghijklmnopqrst"), 10, 1, S("12345678901234567890"), 0, 20, S("abcdefghij12345678901234567890lmnopqrst")); + test(S("abcdefghijklmnopqrst"), 10, 1, S("12345678901234567890"), 0, 21, S("abcdefghij12345678901234567890lmnopqrst")); + test(S("abcdefghijklmnopqrst"), 10, 1, S("12345678901234567890"), 1, 0, S("abcdefghijlmnopqrst")); + test(S("abcdefghijklmnopqrst"), 10, 1, S("12345678901234567890"), 1, 1, S("abcdefghij2lmnopqrst")); + test(S("abcdefghijklmnopqrst"), 10, 1, S("12345678901234567890"), 1, 9, S("abcdefghij234567890lmnopqrst")); + test(S("abcdefghijklmnopqrst"), 10, 1, S("12345678901234567890"), 1, 18, S("abcdefghij234567890123456789lmnopqrst")); + test(S("abcdefghijklmnopqrst"), 10, 1, S("12345678901234567890"), 1, 19, S("abcdefghij2345678901234567890lmnopqrst")); + test(S("abcdefghijklmnopqrst"), 10, 1, S("12345678901234567890"), 1, 20, S("abcdefghij2345678901234567890lmnopqrst")); + test(S("abcdefghijklmnopqrst"), 10, 1, S("12345678901234567890"), 10, 0, S("abcdefghijlmnopqrst")); + test(S("abcdefghijklmnopqrst"), 10, 1, S("12345678901234567890"), 10, 1, S("abcdefghij1lmnopqrst")); + test(S("abcdefghijklmnopqrst"), 10, 1, S("12345678901234567890"), 10, 5, S("abcdefghij12345lmnopqrst")); + test(S("abcdefghijklmnopqrst"), 10, 1, S("12345678901234567890"), 10, 9, S("abcdefghij123456789lmnopqrst")); + test(S("abcdefghijklmnopqrst"), 10, 1, S("12345678901234567890"), 10, 10, S("abcdefghij1234567890lmnopqrst")); + test(S("abcdefghijklmnopqrst"), 10, 1, S("12345678901234567890"), 10, 11, S("abcdefghij1234567890lmnopqrst")); + test(S("abcdefghijklmnopqrst"), 10, 1, S("12345678901234567890"), 19, 0, S("abcdefghijlmnopqrst")); + test(S("abcdefghijklmnopqrst"), 10, 1, S("12345678901234567890"), 19, 1, S("abcdefghij0lmnopqrst")); + test(S("abcdefghijklmnopqrst"), 10, 1, S("12345678901234567890"), 19, 2, S("abcdefghij0lmnopqrst")); + test(S("abcdefghijklmnopqrst"), 10, 1, S("12345678901234567890"), 20, 0, S("abcdefghijlmnopqrst")); + test(S("abcdefghijklmnopqrst"), 10, 1, S("12345678901234567890"), 20, 1, S("abcdefghijlmnopqrst")); + test(S("abcdefghijklmnopqrst"), 10, 1, S("12345678901234567890"), 21, 0, S("can't happen")); + test(S("abcdefghijklmnopqrst"), 10, 5, S(""), 0, 0, S("abcdefghijpqrst")); + test(S("abcdefghijklmnopqrst"), 10, 5, S(""), 0, 1, S("abcdefghijpqrst")); + test(S("abcdefghijklmnopqrst"), 10, 5, S(""), 1, 0, S("can't happen")); + test(S("abcdefghijklmnopqrst"), 10, 5, S("12345"), 0, 0, S("abcdefghijpqrst")); + test(S("abcdefghijklmnopqrst"), 10, 5, S("12345"), 0, 1, S("abcdefghij1pqrst")); + test(S("abcdefghijklmnopqrst"), 10, 5, S("12345"), 0, 2, S("abcdefghij12pqrst")); + test(S("abcdefghijklmnopqrst"), 10, 5, S("12345"), 0, 4, S("abcdefghij1234pqrst")); + test(S("abcdefghijklmnopqrst"), 10, 5, S("12345"), 0, 5, S("abcdefghij12345pqrst")); + test(S("abcdefghijklmnopqrst"), 10, 5, S("12345"), 0, 6, S("abcdefghij12345pqrst")); + test(S("abcdefghijklmnopqrst"), 10, 5, S("12345"), 1, 0, S("abcdefghijpqrst")); + test(S("abcdefghijklmnopqrst"), 10, 5, S("12345"), 1, 1, S("abcdefghij2pqrst")); + test(S("abcdefghijklmnopqrst"), 10, 5, S("12345"), 1, 2, S("abcdefghij23pqrst")); + test(S("abcdefghijklmnopqrst"), 10, 5, S("12345"), 1, 3, S("abcdefghij234pqrst")); + test(S("abcdefghijklmnopqrst"), 10, 5, S("12345"), 1, 4, S("abcdefghij2345pqrst")); + test(S("abcdefghijklmnopqrst"), 10, 5, S("12345"), 1, 5, S("abcdefghij2345pqrst")); + test(S("abcdefghijklmnopqrst"), 10, 5, S("12345"), 2, 0, S("abcdefghijpqrst")); + test(S("abcdefghijklmnopqrst"), 10, 5, S("12345"), 2, 1, S("abcdefghij3pqrst")); + test(S("abcdefghijklmnopqrst"), 10, 5, S("12345"), 2, 2, S("abcdefghij34pqrst")); + test(S("abcdefghijklmnopqrst"), 10, 5, S("12345"), 2, 3, S("abcdefghij345pqrst")); + test(S("abcdefghijklmnopqrst"), 10, 5, S("12345"), 2, 4, S("abcdefghij345pqrst")); + test(S("abcdefghijklmnopqrst"), 10, 5, S("12345"), 4, 0, S("abcdefghijpqrst")); + test(S("abcdefghijklmnopqrst"), 10, 5, S("12345"), 4, 1, S("abcdefghij5pqrst")); + test(S("abcdefghijklmnopqrst"), 10, 5, S("12345"), 4, 2, S("abcdefghij5pqrst")); + test(S("abcdefghijklmnopqrst"), 10, 5, S("12345"), 5, 0, S("abcdefghijpqrst")); + test(S("abcdefghijklmnopqrst"), 10, 5, S("12345"), 5, 1, S("abcdefghijpqrst")); + test(S("abcdefghijklmnopqrst"), 10, 5, S("12345"), 6, 0, S("can't happen")); + test(S("abcdefghijklmnopqrst"), 10, 5, S("1234567890"), 0, 0, S("abcdefghijpqrst")); + test(S("abcdefghijklmnopqrst"), 10, 5, S("1234567890"), 0, 1, S("abcdefghij1pqrst")); + test(S("abcdefghijklmnopqrst"), 10, 5, S("1234567890"), 0, 5, S("abcdefghij12345pqrst")); + test(S("abcdefghijklmnopqrst"), 10, 5, S("1234567890"), 0, 9, S("abcdefghij123456789pqrst")); + test(S("abcdefghijklmnopqrst"), 10, 5, S("1234567890"), 0, 10, S("abcdefghij1234567890pqrst")); + test(S("abcdefghijklmnopqrst"), 10, 5, S("1234567890"), 0, 11, S("abcdefghij1234567890pqrst")); + test(S("abcdefghijklmnopqrst"), 10, 5, S("1234567890"), 1, 0, S("abcdefghijpqrst")); + test(S("abcdefghijklmnopqrst"), 10, 5, S("1234567890"), 1, 1, S("abcdefghij2pqrst")); + test(S("abcdefghijklmnopqrst"), 10, 5, S("1234567890"), 1, 4, S("abcdefghij2345pqrst")); + test(S("abcdefghijklmnopqrst"), 10, 5, S("1234567890"), 1, 8, S("abcdefghij23456789pqrst")); + test(S("abcdefghijklmnopqrst"), 10, 5, S("1234567890"), 1, 9, S("abcdefghij234567890pqrst")); + test(S("abcdefghijklmnopqrst"), 10, 5, S("1234567890"), 1, 10, S("abcdefghij234567890pqrst")); + test(S("abcdefghijklmnopqrst"), 10, 5, S("1234567890"), 5, 0, S("abcdefghijpqrst")); + test(S("abcdefghijklmnopqrst"), 10, 5, S("1234567890"), 5, 1, S("abcdefghij6pqrst")); + test(S("abcdefghijklmnopqrst"), 10, 5, S("1234567890"), 5, 2, S("abcdefghij67pqrst")); + test(S("abcdefghijklmnopqrst"), 10, 5, S("1234567890"), 5, 4, S("abcdefghij6789pqrst")); + test(S("abcdefghijklmnopqrst"), 10, 5, S("1234567890"), 5, 5, S("abcdefghij67890pqrst")); + test(S("abcdefghijklmnopqrst"), 10, 5, S("1234567890"), 5, 6, S("abcdefghij67890pqrst")); + test(S("abcdefghijklmnopqrst"), 10, 5, S("1234567890"), 9, 0, S("abcdefghijpqrst")); + test(S("abcdefghijklmnopqrst"), 10, 5, S("1234567890"), 9, 1, S("abcdefghij0pqrst")); + test(S("abcdefghijklmnopqrst"), 10, 5, S("1234567890"), 9, 2, S("abcdefghij0pqrst")); + test(S("abcdefghijklmnopqrst"), 10, 5, S("1234567890"), 10, 0, S("abcdefghijpqrst")); + test(S("abcdefghijklmnopqrst"), 10, 5, S("1234567890"), 10, 1, S("abcdefghijpqrst")); + test(S("abcdefghijklmnopqrst"), 10, 5, S("1234567890"), 11, 0, S("can't happen")); + test(S("abcdefghijklmnopqrst"), 10, 5, S("12345678901234567890"), 0, 0, S("abcdefghijpqrst")); + test(S("abcdefghijklmnopqrst"), 10, 5, S("12345678901234567890"), 0, 1, S("abcdefghij1pqrst")); + test(S("abcdefghijklmnopqrst"), 10, 5, S("12345678901234567890"), 0, 10, S("abcdefghij1234567890pqrst")); + test(S("abcdefghijklmnopqrst"), 10, 5, S("12345678901234567890"), 0, 19, S("abcdefghij1234567890123456789pqrst")); + test(S("abcdefghijklmnopqrst"), 10, 5, S("12345678901234567890"), 0, 20, S("abcdefghij12345678901234567890pqrst")); + test(S("abcdefghijklmnopqrst"), 10, 5, S("12345678901234567890"), 0, 21, S("abcdefghij12345678901234567890pqrst")); + test(S("abcdefghijklmnopqrst"), 10, 5, S("12345678901234567890"), 1, 0, S("abcdefghijpqrst")); + test(S("abcdefghijklmnopqrst"), 10, 5, S("12345678901234567890"), 1, 1, S("abcdefghij2pqrst")); + test(S("abcdefghijklmnopqrst"), 10, 5, S("12345678901234567890"), 1, 9, S("abcdefghij234567890pqrst")); + test(S("abcdefghijklmnopqrst"), 10, 5, S("12345678901234567890"), 1, 18, S("abcdefghij234567890123456789pqrst")); + test(S("abcdefghijklmnopqrst"), 10, 5, S("12345678901234567890"), 1, 19, S("abcdefghij2345678901234567890pqrst")); + test(S("abcdefghijklmnopqrst"), 10, 5, S("12345678901234567890"), 1, 20, S("abcdefghij2345678901234567890pqrst")); + test(S("abcdefghijklmnopqrst"), 10, 5, S("12345678901234567890"), 10, 0, S("abcdefghijpqrst")); + test(S("abcdefghijklmnopqrst"), 10, 5, S("12345678901234567890"), 10, 1, S("abcdefghij1pqrst")); +} + +template +void test48() +{ + test(S("abcdefghijklmnopqrst"), 10, 5, S("12345678901234567890"), 10, 5, S("abcdefghij12345pqrst")); + test(S("abcdefghijklmnopqrst"), 10, 5, S("12345678901234567890"), 10, 9, S("abcdefghij123456789pqrst")); + test(S("abcdefghijklmnopqrst"), 10, 5, S("12345678901234567890"), 10, 10, S("abcdefghij1234567890pqrst")); + test(S("abcdefghijklmnopqrst"), 10, 5, S("12345678901234567890"), 10, 11, S("abcdefghij1234567890pqrst")); + test(S("abcdefghijklmnopqrst"), 10, 5, S("12345678901234567890"), 19, 0, S("abcdefghijpqrst")); + test(S("abcdefghijklmnopqrst"), 10, 5, S("12345678901234567890"), 19, 1, S("abcdefghij0pqrst")); + test(S("abcdefghijklmnopqrst"), 10, 5, S("12345678901234567890"), 19, 2, S("abcdefghij0pqrst")); + test(S("abcdefghijklmnopqrst"), 10, 5, S("12345678901234567890"), 20, 0, S("abcdefghijpqrst")); + test(S("abcdefghijklmnopqrst"), 10, 5, S("12345678901234567890"), 20, 1, S("abcdefghijpqrst")); + test(S("abcdefghijklmnopqrst"), 10, 5, S("12345678901234567890"), 21, 0, S("can't happen")); + test(S("abcdefghijklmnopqrst"), 10, 9, S(""), 0, 0, S("abcdefghijt")); + test(S("abcdefghijklmnopqrst"), 10, 9, S(""), 0, 1, S("abcdefghijt")); + test(S("abcdefghijklmnopqrst"), 10, 9, S(""), 1, 0, S("can't happen")); + test(S("abcdefghijklmnopqrst"), 10, 9, S("12345"), 0, 0, S("abcdefghijt")); + test(S("abcdefghijklmnopqrst"), 10, 9, S("12345"), 0, 1, S("abcdefghij1t")); + test(S("abcdefghijklmnopqrst"), 10, 9, S("12345"), 0, 2, S("abcdefghij12t")); + test(S("abcdefghijklmnopqrst"), 10, 9, S("12345"), 0, 4, S("abcdefghij1234t")); + test(S("abcdefghijklmnopqrst"), 10, 9, S("12345"), 0, 5, S("abcdefghij12345t")); + test(S("abcdefghijklmnopqrst"), 10, 9, S("12345"), 0, 6, S("abcdefghij12345t")); + test(S("abcdefghijklmnopqrst"), 10, 9, S("12345"), 1, 0, S("abcdefghijt")); + test(S("abcdefghijklmnopqrst"), 10, 9, S("12345"), 1, 1, S("abcdefghij2t")); + test(S("abcdefghijklmnopqrst"), 10, 9, S("12345"), 1, 2, S("abcdefghij23t")); + test(S("abcdefghijklmnopqrst"), 10, 9, S("12345"), 1, 3, S("abcdefghij234t")); + test(S("abcdefghijklmnopqrst"), 10, 9, S("12345"), 1, 4, S("abcdefghij2345t")); + test(S("abcdefghijklmnopqrst"), 10, 9, S("12345"), 1, 5, S("abcdefghij2345t")); + test(S("abcdefghijklmnopqrst"), 10, 9, S("12345"), 2, 0, S("abcdefghijt")); + test(S("abcdefghijklmnopqrst"), 10, 9, S("12345"), 2, 1, S("abcdefghij3t")); + test(S("abcdefghijklmnopqrst"), 10, 9, S("12345"), 2, 2, S("abcdefghij34t")); + test(S("abcdefghijklmnopqrst"), 10, 9, S("12345"), 2, 3, S("abcdefghij345t")); + test(S("abcdefghijklmnopqrst"), 10, 9, S("12345"), 2, 4, S("abcdefghij345t")); + test(S("abcdefghijklmnopqrst"), 10, 9, S("12345"), 4, 0, S("abcdefghijt")); + test(S("abcdefghijklmnopqrst"), 10, 9, S("12345"), 4, 1, S("abcdefghij5t")); + test(S("abcdefghijklmnopqrst"), 10, 9, S("12345"), 4, 2, S("abcdefghij5t")); + test(S("abcdefghijklmnopqrst"), 10, 9, S("12345"), 5, 0, S("abcdefghijt")); + test(S("abcdefghijklmnopqrst"), 10, 9, S("12345"), 5, 1, S("abcdefghijt")); + test(S("abcdefghijklmnopqrst"), 10, 9, S("12345"), 6, 0, S("can't happen")); + test(S("abcdefghijklmnopqrst"), 10, 9, S("1234567890"), 0, 0, S("abcdefghijt")); + test(S("abcdefghijklmnopqrst"), 10, 9, S("1234567890"), 0, 1, S("abcdefghij1t")); + test(S("abcdefghijklmnopqrst"), 10, 9, S("1234567890"), 0, 5, S("abcdefghij12345t")); + test(S("abcdefghijklmnopqrst"), 10, 9, S("1234567890"), 0, 9, S("abcdefghij123456789t")); + test(S("abcdefghijklmnopqrst"), 10, 9, S("1234567890"), 0, 10, S("abcdefghij1234567890t")); + test(S("abcdefghijklmnopqrst"), 10, 9, S("1234567890"), 0, 11, S("abcdefghij1234567890t")); + test(S("abcdefghijklmnopqrst"), 10, 9, S("1234567890"), 1, 0, S("abcdefghijt")); + test(S("abcdefghijklmnopqrst"), 10, 9, S("1234567890"), 1, 1, S("abcdefghij2t")); + test(S("abcdefghijklmnopqrst"), 10, 9, S("1234567890"), 1, 4, S("abcdefghij2345t")); + test(S("abcdefghijklmnopqrst"), 10, 9, S("1234567890"), 1, 8, S("abcdefghij23456789t")); + test(S("abcdefghijklmnopqrst"), 10, 9, S("1234567890"), 1, 9, S("abcdefghij234567890t")); + test(S("abcdefghijklmnopqrst"), 10, 9, S("1234567890"), 1, 10, S("abcdefghij234567890t")); + test(S("abcdefghijklmnopqrst"), 10, 9, S("1234567890"), 5, 0, S("abcdefghijt")); + test(S("abcdefghijklmnopqrst"), 10, 9, S("1234567890"), 5, 1, S("abcdefghij6t")); + test(S("abcdefghijklmnopqrst"), 10, 9, S("1234567890"), 5, 2, S("abcdefghij67t")); + test(S("abcdefghijklmnopqrst"), 10, 9, S("1234567890"), 5, 4, S("abcdefghij6789t")); + test(S("abcdefghijklmnopqrst"), 10, 9, S("1234567890"), 5, 5, S("abcdefghij67890t")); + test(S("abcdefghijklmnopqrst"), 10, 9, S("1234567890"), 5, 6, S("abcdefghij67890t")); + test(S("abcdefghijklmnopqrst"), 10, 9, S("1234567890"), 9, 0, S("abcdefghijt")); + test(S("abcdefghijklmnopqrst"), 10, 9, S("1234567890"), 9, 1, S("abcdefghij0t")); + test(S("abcdefghijklmnopqrst"), 10, 9, S("1234567890"), 9, 2, S("abcdefghij0t")); + test(S("abcdefghijklmnopqrst"), 10, 9, S("1234567890"), 10, 0, S("abcdefghijt")); + test(S("abcdefghijklmnopqrst"), 10, 9, S("1234567890"), 10, 1, S("abcdefghijt")); + test(S("abcdefghijklmnopqrst"), 10, 9, S("1234567890"), 11, 0, S("can't happen")); + test(S("abcdefghijklmnopqrst"), 10, 9, S("12345678901234567890"), 0, 0, S("abcdefghijt")); + test(S("abcdefghijklmnopqrst"), 10, 9, S("12345678901234567890"), 0, 1, S("abcdefghij1t")); + test(S("abcdefghijklmnopqrst"), 10, 9, S("12345678901234567890"), 0, 10, S("abcdefghij1234567890t")); + test(S("abcdefghijklmnopqrst"), 10, 9, S("12345678901234567890"), 0, 19, S("abcdefghij1234567890123456789t")); + test(S("abcdefghijklmnopqrst"), 10, 9, S("12345678901234567890"), 0, 20, S("abcdefghij12345678901234567890t")); + test(S("abcdefghijklmnopqrst"), 10, 9, S("12345678901234567890"), 0, 21, S("abcdefghij12345678901234567890t")); + test(S("abcdefghijklmnopqrst"), 10, 9, S("12345678901234567890"), 1, 0, S("abcdefghijt")); + test(S("abcdefghijklmnopqrst"), 10, 9, S("12345678901234567890"), 1, 1, S("abcdefghij2t")); + test(S("abcdefghijklmnopqrst"), 10, 9, S("12345678901234567890"), 1, 9, S("abcdefghij234567890t")); + test(S("abcdefghijklmnopqrst"), 10, 9, S("12345678901234567890"), 1, 18, S("abcdefghij234567890123456789t")); + test(S("abcdefghijklmnopqrst"), 10, 9, S("12345678901234567890"), 1, 19, S("abcdefghij2345678901234567890t")); + test(S("abcdefghijklmnopqrst"), 10, 9, S("12345678901234567890"), 1, 20, S("abcdefghij2345678901234567890t")); + test(S("abcdefghijklmnopqrst"), 10, 9, S("12345678901234567890"), 10, 0, S("abcdefghijt")); + test(S("abcdefghijklmnopqrst"), 10, 9, S("12345678901234567890"), 10, 1, S("abcdefghij1t")); + test(S("abcdefghijklmnopqrst"), 10, 9, S("12345678901234567890"), 10, 5, S("abcdefghij12345t")); + test(S("abcdefghijklmnopqrst"), 10, 9, S("12345678901234567890"), 10, 9, S("abcdefghij123456789t")); + test(S("abcdefghijklmnopqrst"), 10, 9, S("12345678901234567890"), 10, 10, S("abcdefghij1234567890t")); + test(S("abcdefghijklmnopqrst"), 10, 9, S("12345678901234567890"), 10, 11, S("abcdefghij1234567890t")); + test(S("abcdefghijklmnopqrst"), 10, 9, S("12345678901234567890"), 19, 0, S("abcdefghijt")); + test(S("abcdefghijklmnopqrst"), 10, 9, S("12345678901234567890"), 19, 1, S("abcdefghij0t")); + test(S("abcdefghijklmnopqrst"), 10, 9, S("12345678901234567890"), 19, 2, S("abcdefghij0t")); + test(S("abcdefghijklmnopqrst"), 10, 9, S("12345678901234567890"), 20, 0, S("abcdefghijt")); + test(S("abcdefghijklmnopqrst"), 10, 9, S("12345678901234567890"), 20, 1, S("abcdefghijt")); + test(S("abcdefghijklmnopqrst"), 10, 9, S("12345678901234567890"), 21, 0, S("can't happen")); + test(S("abcdefghijklmnopqrst"), 10, 10, S(""), 0, 0, S("abcdefghij")); + test(S("abcdefghijklmnopqrst"), 10, 10, S(""), 0, 1, S("abcdefghij")); + test(S("abcdefghijklmnopqrst"), 10, 10, S(""), 1, 0, S("can't happen")); + test(S("abcdefghijklmnopqrst"), 10, 10, S("12345"), 0, 0, S("abcdefghij")); + test(S("abcdefghijklmnopqrst"), 10, 10, S("12345"), 0, 1, S("abcdefghij1")); + test(S("abcdefghijklmnopqrst"), 10, 10, S("12345"), 0, 2, S("abcdefghij12")); + test(S("abcdefghijklmnopqrst"), 10, 10, S("12345"), 0, 4, S("abcdefghij1234")); + test(S("abcdefghijklmnopqrst"), 10, 10, S("12345"), 0, 5, S("abcdefghij12345")); + test(S("abcdefghijklmnopqrst"), 10, 10, S("12345"), 0, 6, S("abcdefghij12345")); + test(S("abcdefghijklmnopqrst"), 10, 10, S("12345"), 1, 0, S("abcdefghij")); + test(S("abcdefghijklmnopqrst"), 10, 10, S("12345"), 1, 1, S("abcdefghij2")); + test(S("abcdefghijklmnopqrst"), 10, 10, S("12345"), 1, 2, S("abcdefghij23")); + test(S("abcdefghijklmnopqrst"), 10, 10, S("12345"), 1, 3, S("abcdefghij234")); + test(S("abcdefghijklmnopqrst"), 10, 10, S("12345"), 1, 4, S("abcdefghij2345")); + test(S("abcdefghijklmnopqrst"), 10, 10, S("12345"), 1, 5, S("abcdefghij2345")); + test(S("abcdefghijklmnopqrst"), 10, 10, S("12345"), 2, 0, S("abcdefghij")); +} + +template +void test49() +{ + test(S("abcdefghijklmnopqrst"), 10, 10, S("12345"), 2, 1, S("abcdefghij3")); + test(S("abcdefghijklmnopqrst"), 10, 10, S("12345"), 2, 2, S("abcdefghij34")); + test(S("abcdefghijklmnopqrst"), 10, 10, S("12345"), 2, 3, S("abcdefghij345")); + test(S("abcdefghijklmnopqrst"), 10, 10, S("12345"), 2, 4, S("abcdefghij345")); + test(S("abcdefghijklmnopqrst"), 10, 10, S("12345"), 4, 0, S("abcdefghij")); + test(S("abcdefghijklmnopqrst"), 10, 10, S("12345"), 4, 1, S("abcdefghij5")); + test(S("abcdefghijklmnopqrst"), 10, 10, S("12345"), 4, 2, S("abcdefghij5")); + test(S("abcdefghijklmnopqrst"), 10, 10, S("12345"), 5, 0, S("abcdefghij")); + test(S("abcdefghijklmnopqrst"), 10, 10, S("12345"), 5, 1, S("abcdefghij")); + test(S("abcdefghijklmnopqrst"), 10, 10, S("12345"), 6, 0, S("can't happen")); + test(S("abcdefghijklmnopqrst"), 10, 10, S("1234567890"), 0, 0, S("abcdefghij")); + test(S("abcdefghijklmnopqrst"), 10, 10, S("1234567890"), 0, 1, S("abcdefghij1")); + test(S("abcdefghijklmnopqrst"), 10, 10, S("1234567890"), 0, 5, S("abcdefghij12345")); + test(S("abcdefghijklmnopqrst"), 10, 10, S("1234567890"), 0, 9, S("abcdefghij123456789")); + test(S("abcdefghijklmnopqrst"), 10, 10, S("1234567890"), 0, 10, S("abcdefghij1234567890")); + test(S("abcdefghijklmnopqrst"), 10, 10, S("1234567890"), 0, 11, S("abcdefghij1234567890")); + test(S("abcdefghijklmnopqrst"), 10, 10, S("1234567890"), 1, 0, S("abcdefghij")); + test(S("abcdefghijklmnopqrst"), 10, 10, S("1234567890"), 1, 1, S("abcdefghij2")); + test(S("abcdefghijklmnopqrst"), 10, 10, S("1234567890"), 1, 4, S("abcdefghij2345")); + test(S("abcdefghijklmnopqrst"), 10, 10, S("1234567890"), 1, 8, S("abcdefghij23456789")); + test(S("abcdefghijklmnopqrst"), 10, 10, S("1234567890"), 1, 9, S("abcdefghij234567890")); + test(S("abcdefghijklmnopqrst"), 10, 10, S("1234567890"), 1, 10, S("abcdefghij234567890")); + test(S("abcdefghijklmnopqrst"), 10, 10, S("1234567890"), 5, 0, S("abcdefghij")); + test(S("abcdefghijklmnopqrst"), 10, 10, S("1234567890"), 5, 1, S("abcdefghij6")); + test(S("abcdefghijklmnopqrst"), 10, 10, S("1234567890"), 5, 2, S("abcdefghij67")); + test(S("abcdefghijklmnopqrst"), 10, 10, S("1234567890"), 5, 4, S("abcdefghij6789")); + test(S("abcdefghijklmnopqrst"), 10, 10, S("1234567890"), 5, 5, S("abcdefghij67890")); + test(S("abcdefghijklmnopqrst"), 10, 10, S("1234567890"), 5, 6, S("abcdefghij67890")); + test(S("abcdefghijklmnopqrst"), 10, 10, S("1234567890"), 9, 0, S("abcdefghij")); + test(S("abcdefghijklmnopqrst"), 10, 10, S("1234567890"), 9, 1, S("abcdefghij0")); + test(S("abcdefghijklmnopqrst"), 10, 10, S("1234567890"), 9, 2, S("abcdefghij0")); + test(S("abcdefghijklmnopqrst"), 10, 10, S("1234567890"), 10, 0, S("abcdefghij")); + test(S("abcdefghijklmnopqrst"), 10, 10, S("1234567890"), 10, 1, S("abcdefghij")); + test(S("abcdefghijklmnopqrst"), 10, 10, S("1234567890"), 11, 0, S("can't happen")); + test(S("abcdefghijklmnopqrst"), 10, 10, S("12345678901234567890"), 0, 0, S("abcdefghij")); + test(S("abcdefghijklmnopqrst"), 10, 10, S("12345678901234567890"), 0, 1, S("abcdefghij1")); + test(S("abcdefghijklmnopqrst"), 10, 10, S("12345678901234567890"), 0, 10, S("abcdefghij1234567890")); + test(S("abcdefghijklmnopqrst"), 10, 10, S("12345678901234567890"), 0, 19, S("abcdefghij1234567890123456789")); + test(S("abcdefghijklmnopqrst"), 10, 10, S("12345678901234567890"), 0, 20, S("abcdefghij12345678901234567890")); + test(S("abcdefghijklmnopqrst"), 10, 10, S("12345678901234567890"), 0, 21, S("abcdefghij12345678901234567890")); + test(S("abcdefghijklmnopqrst"), 10, 10, S("12345678901234567890"), 1, 0, S("abcdefghij")); + test(S("abcdefghijklmnopqrst"), 10, 10, S("12345678901234567890"), 1, 1, S("abcdefghij2")); + test(S("abcdefghijklmnopqrst"), 10, 10, S("12345678901234567890"), 1, 9, S("abcdefghij234567890")); + test(S("abcdefghijklmnopqrst"), 10, 10, S("12345678901234567890"), 1, 18, S("abcdefghij234567890123456789")); + test(S("abcdefghijklmnopqrst"), 10, 10, S("12345678901234567890"), 1, 19, S("abcdefghij2345678901234567890")); + test(S("abcdefghijklmnopqrst"), 10, 10, S("12345678901234567890"), 1, 20, S("abcdefghij2345678901234567890")); + test(S("abcdefghijklmnopqrst"), 10, 10, S("12345678901234567890"), 10, 0, S("abcdefghij")); + test(S("abcdefghijklmnopqrst"), 10, 10, S("12345678901234567890"), 10, 1, S("abcdefghij1")); + test(S("abcdefghijklmnopqrst"), 10, 10, S("12345678901234567890"), 10, 5, S("abcdefghij12345")); + test(S("abcdefghijklmnopqrst"), 10, 10, S("12345678901234567890"), 10, 9, S("abcdefghij123456789")); + test(S("abcdefghijklmnopqrst"), 10, 10, S("12345678901234567890"), 10, 10, S("abcdefghij1234567890")); + test(S("abcdefghijklmnopqrst"), 10, 10, S("12345678901234567890"), 10, 11, S("abcdefghij1234567890")); + test(S("abcdefghijklmnopqrst"), 10, 10, S("12345678901234567890"), 19, 0, S("abcdefghij")); + test(S("abcdefghijklmnopqrst"), 10, 10, S("12345678901234567890"), 19, 1, S("abcdefghij0")); + test(S("abcdefghijklmnopqrst"), 10, 10, S("12345678901234567890"), 19, 2, S("abcdefghij0")); + test(S("abcdefghijklmnopqrst"), 10, 10, S("12345678901234567890"), 20, 0, S("abcdefghij")); + test(S("abcdefghijklmnopqrst"), 10, 10, S("12345678901234567890"), 20, 1, S("abcdefghij")); + test(S("abcdefghijklmnopqrst"), 10, 10, S("12345678901234567890"), 21, 0, S("can't happen")); + test(S("abcdefghijklmnopqrst"), 10, 11, S(""), 0, 0, S("abcdefghij")); + test(S("abcdefghijklmnopqrst"), 10, 11, S(""), 0, 1, S("abcdefghij")); + test(S("abcdefghijklmnopqrst"), 10, 11, S(""), 1, 0, S("can't happen")); + test(S("abcdefghijklmnopqrst"), 10, 11, S("12345"), 0, 0, S("abcdefghij")); + test(S("abcdefghijklmnopqrst"), 10, 11, S("12345"), 0, 1, S("abcdefghij1")); + test(S("abcdefghijklmnopqrst"), 10, 11, S("12345"), 0, 2, S("abcdefghij12")); + test(S("abcdefghijklmnopqrst"), 10, 11, S("12345"), 0, 4, S("abcdefghij1234")); + test(S("abcdefghijklmnopqrst"), 10, 11, S("12345"), 0, 5, S("abcdefghij12345")); + test(S("abcdefghijklmnopqrst"), 10, 11, S("12345"), 0, 6, S("abcdefghij12345")); + test(S("abcdefghijklmnopqrst"), 10, 11, S("12345"), 1, 0, S("abcdefghij")); + test(S("abcdefghijklmnopqrst"), 10, 11, S("12345"), 1, 1, S("abcdefghij2")); + test(S("abcdefghijklmnopqrst"), 10, 11, S("12345"), 1, 2, S("abcdefghij23")); + test(S("abcdefghijklmnopqrst"), 10, 11, S("12345"), 1, 3, S("abcdefghij234")); + test(S("abcdefghijklmnopqrst"), 10, 11, S("12345"), 1, 4, S("abcdefghij2345")); + test(S("abcdefghijklmnopqrst"), 10, 11, S("12345"), 1, 5, S("abcdefghij2345")); + test(S("abcdefghijklmnopqrst"), 10, 11, S("12345"), 2, 0, S("abcdefghij")); + test(S("abcdefghijklmnopqrst"), 10, 11, S("12345"), 2, 1, S("abcdefghij3")); + test(S("abcdefghijklmnopqrst"), 10, 11, S("12345"), 2, 2, S("abcdefghij34")); + test(S("abcdefghijklmnopqrst"), 10, 11, S("12345"), 2, 3, S("abcdefghij345")); + test(S("abcdefghijklmnopqrst"), 10, 11, S("12345"), 2, 4, S("abcdefghij345")); + test(S("abcdefghijklmnopqrst"), 10, 11, S("12345"), 4, 0, S("abcdefghij")); + test(S("abcdefghijklmnopqrst"), 10, 11, S("12345"), 4, 1, S("abcdefghij5")); + test(S("abcdefghijklmnopqrst"), 10, 11, S("12345"), 4, 2, S("abcdefghij5")); + test(S("abcdefghijklmnopqrst"), 10, 11, S("12345"), 5, 0, S("abcdefghij")); + test(S("abcdefghijklmnopqrst"), 10, 11, S("12345"), 5, 1, S("abcdefghij")); + test(S("abcdefghijklmnopqrst"), 10, 11, S("12345"), 6, 0, S("can't happen")); + test(S("abcdefghijklmnopqrst"), 10, 11, S("1234567890"), 0, 0, S("abcdefghij")); + test(S("abcdefghijklmnopqrst"), 10, 11, S("1234567890"), 0, 1, S("abcdefghij1")); + test(S("abcdefghijklmnopqrst"), 10, 11, S("1234567890"), 0, 5, S("abcdefghij12345")); + test(S("abcdefghijklmnopqrst"), 10, 11, S("1234567890"), 0, 9, S("abcdefghij123456789")); + test(S("abcdefghijklmnopqrst"), 10, 11, S("1234567890"), 0, 10, S("abcdefghij1234567890")); + test(S("abcdefghijklmnopqrst"), 10, 11, S("1234567890"), 0, 11, S("abcdefghij1234567890")); + test(S("abcdefghijklmnopqrst"), 10, 11, S("1234567890"), 1, 0, S("abcdefghij")); + test(S("abcdefghijklmnopqrst"), 10, 11, S("1234567890"), 1, 1, S("abcdefghij2")); + test(S("abcdefghijklmnopqrst"), 10, 11, S("1234567890"), 1, 4, S("abcdefghij2345")); + test(S("abcdefghijklmnopqrst"), 10, 11, S("1234567890"), 1, 8, S("abcdefghij23456789")); + test(S("abcdefghijklmnopqrst"), 10, 11, S("1234567890"), 1, 9, S("abcdefghij234567890")); + test(S("abcdefghijklmnopqrst"), 10, 11, S("1234567890"), 1, 10, S("abcdefghij234567890")); + test(S("abcdefghijklmnopqrst"), 10, 11, S("1234567890"), 5, 0, S("abcdefghij")); + test(S("abcdefghijklmnopqrst"), 10, 11, S("1234567890"), 5, 1, S("abcdefghij6")); + test(S("abcdefghijklmnopqrst"), 10, 11, S("1234567890"), 5, 2, S("abcdefghij67")); + test(S("abcdefghijklmnopqrst"), 10, 11, S("1234567890"), 5, 4, S("abcdefghij6789")); +} + +template +void test50() +{ + test(S("abcdefghijklmnopqrst"), 10, 11, S("1234567890"), 5, 5, S("abcdefghij67890")); + test(S("abcdefghijklmnopqrst"), 10, 11, S("1234567890"), 5, 6, S("abcdefghij67890")); + test(S("abcdefghijklmnopqrst"), 10, 11, S("1234567890"), 9, 0, S("abcdefghij")); + test(S("abcdefghijklmnopqrst"), 10, 11, S("1234567890"), 9, 1, S("abcdefghij0")); + test(S("abcdefghijklmnopqrst"), 10, 11, S("1234567890"), 9, 2, S("abcdefghij0")); + test(S("abcdefghijklmnopqrst"), 10, 11, S("1234567890"), 10, 0, S("abcdefghij")); + test(S("abcdefghijklmnopqrst"), 10, 11, S("1234567890"), 10, 1, S("abcdefghij")); + test(S("abcdefghijklmnopqrst"), 10, 11, S("1234567890"), 11, 0, S("can't happen")); + test(S("abcdefghijklmnopqrst"), 10, 11, S("12345678901234567890"), 0, 0, S("abcdefghij")); + test(S("abcdefghijklmnopqrst"), 10, 11, S("12345678901234567890"), 0, 1, S("abcdefghij1")); + test(S("abcdefghijklmnopqrst"), 10, 11, S("12345678901234567890"), 0, 10, S("abcdefghij1234567890")); + test(S("abcdefghijklmnopqrst"), 10, 11, S("12345678901234567890"), 0, 19, S("abcdefghij1234567890123456789")); + test(S("abcdefghijklmnopqrst"), 10, 11, S("12345678901234567890"), 0, 20, S("abcdefghij12345678901234567890")); + test(S("abcdefghijklmnopqrst"), 10, 11, S("12345678901234567890"), 0, 21, S("abcdefghij12345678901234567890")); + test(S("abcdefghijklmnopqrst"), 10, 11, S("12345678901234567890"), 1, 0, S("abcdefghij")); + test(S("abcdefghijklmnopqrst"), 10, 11, S("12345678901234567890"), 1, 1, S("abcdefghij2")); + test(S("abcdefghijklmnopqrst"), 10, 11, S("12345678901234567890"), 1, 9, S("abcdefghij234567890")); + test(S("abcdefghijklmnopqrst"), 10, 11, S("12345678901234567890"), 1, 18, S("abcdefghij234567890123456789")); + test(S("abcdefghijklmnopqrst"), 10, 11, S("12345678901234567890"), 1, 19, S("abcdefghij2345678901234567890")); + test(S("abcdefghijklmnopqrst"), 10, 11, S("12345678901234567890"), 1, 20, S("abcdefghij2345678901234567890")); + test(S("abcdefghijklmnopqrst"), 10, 11, S("12345678901234567890"), 10, 0, S("abcdefghij")); + test(S("abcdefghijklmnopqrst"), 10, 11, S("12345678901234567890"), 10, 1, S("abcdefghij1")); + test(S("abcdefghijklmnopqrst"), 10, 11, S("12345678901234567890"), 10, 5, S("abcdefghij12345")); + test(S("abcdefghijklmnopqrst"), 10, 11, S("12345678901234567890"), 10, 9, S("abcdefghij123456789")); + test(S("abcdefghijklmnopqrst"), 10, 11, S("12345678901234567890"), 10, 10, S("abcdefghij1234567890")); + test(S("abcdefghijklmnopqrst"), 10, 11, S("12345678901234567890"), 10, 11, S("abcdefghij1234567890")); + test(S("abcdefghijklmnopqrst"), 10, 11, S("12345678901234567890"), 19, 0, S("abcdefghij")); + test(S("abcdefghijklmnopqrst"), 10, 11, S("12345678901234567890"), 19, 1, S("abcdefghij0")); + test(S("abcdefghijklmnopqrst"), 10, 11, S("12345678901234567890"), 19, 2, S("abcdefghij0")); + test(S("abcdefghijklmnopqrst"), 10, 11, S("12345678901234567890"), 20, 0, S("abcdefghij")); + test(S("abcdefghijklmnopqrst"), 10, 11, S("12345678901234567890"), 20, 1, S("abcdefghij")); + test(S("abcdefghijklmnopqrst"), 10, 11, S("12345678901234567890"), 21, 0, S("can't happen")); + test(S("abcdefghijklmnopqrst"), 19, 0, S(""), 0, 0, S("abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 19, 0, S(""), 0, 1, S("abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 19, 0, S(""), 1, 0, S("can't happen")); + test(S("abcdefghijklmnopqrst"), 19, 0, S("12345"), 0, 0, S("abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 19, 0, S("12345"), 0, 1, S("abcdefghijklmnopqrs1t")); + test(S("abcdefghijklmnopqrst"), 19, 0, S("12345"), 0, 2, S("abcdefghijklmnopqrs12t")); + test(S("abcdefghijklmnopqrst"), 19, 0, S("12345"), 0, 4, S("abcdefghijklmnopqrs1234t")); + test(S("abcdefghijklmnopqrst"), 19, 0, S("12345"), 0, 5, S("abcdefghijklmnopqrs12345t")); + test(S("abcdefghijklmnopqrst"), 19, 0, S("12345"), 0, 6, S("abcdefghijklmnopqrs12345t")); + test(S("abcdefghijklmnopqrst"), 19, 0, S("12345"), 1, 0, S("abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 19, 0, S("12345"), 1, 1, S("abcdefghijklmnopqrs2t")); + test(S("abcdefghijklmnopqrst"), 19, 0, S("12345"), 1, 2, S("abcdefghijklmnopqrs23t")); + test(S("abcdefghijklmnopqrst"), 19, 0, S("12345"), 1, 3, S("abcdefghijklmnopqrs234t")); + test(S("abcdefghijklmnopqrst"), 19, 0, S("12345"), 1, 4, S("abcdefghijklmnopqrs2345t")); + test(S("abcdefghijklmnopqrst"), 19, 0, S("12345"), 1, 5, S("abcdefghijklmnopqrs2345t")); + test(S("abcdefghijklmnopqrst"), 19, 0, S("12345"), 2, 0, S("abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 19, 0, S("12345"), 2, 1, S("abcdefghijklmnopqrs3t")); + test(S("abcdefghijklmnopqrst"), 19, 0, S("12345"), 2, 2, S("abcdefghijklmnopqrs34t")); + test(S("abcdefghijklmnopqrst"), 19, 0, S("12345"), 2, 3, S("abcdefghijklmnopqrs345t")); + test(S("abcdefghijklmnopqrst"), 19, 0, S("12345"), 2, 4, S("abcdefghijklmnopqrs345t")); + test(S("abcdefghijklmnopqrst"), 19, 0, S("12345"), 4, 0, S("abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 19, 0, S("12345"), 4, 1, S("abcdefghijklmnopqrs5t")); + test(S("abcdefghijklmnopqrst"), 19, 0, S("12345"), 4, 2, S("abcdefghijklmnopqrs5t")); + test(S("abcdefghijklmnopqrst"), 19, 0, S("12345"), 5, 0, S("abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 19, 0, S("12345"), 5, 1, S("abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 19, 0, S("12345"), 6, 0, S("can't happen")); + test(S("abcdefghijklmnopqrst"), 19, 0, S("1234567890"), 0, 0, S("abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 19, 0, S("1234567890"), 0, 1, S("abcdefghijklmnopqrs1t")); + test(S("abcdefghijklmnopqrst"), 19, 0, S("1234567890"), 0, 5, S("abcdefghijklmnopqrs12345t")); + test(S("abcdefghijklmnopqrst"), 19, 0, S("1234567890"), 0, 9, S("abcdefghijklmnopqrs123456789t")); + test(S("abcdefghijklmnopqrst"), 19, 0, S("1234567890"), 0, 10, S("abcdefghijklmnopqrs1234567890t")); + test(S("abcdefghijklmnopqrst"), 19, 0, S("1234567890"), 0, 11, S("abcdefghijklmnopqrs1234567890t")); + test(S("abcdefghijklmnopqrst"), 19, 0, S("1234567890"), 1, 0, S("abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 19, 0, S("1234567890"), 1, 1, S("abcdefghijklmnopqrs2t")); + test(S("abcdefghijklmnopqrst"), 19, 0, S("1234567890"), 1, 4, S("abcdefghijklmnopqrs2345t")); + test(S("abcdefghijklmnopqrst"), 19, 0, S("1234567890"), 1, 8, S("abcdefghijklmnopqrs23456789t")); + test(S("abcdefghijklmnopqrst"), 19, 0, S("1234567890"), 1, 9, S("abcdefghijklmnopqrs234567890t")); + test(S("abcdefghijklmnopqrst"), 19, 0, S("1234567890"), 1, 10, S("abcdefghijklmnopqrs234567890t")); + test(S("abcdefghijklmnopqrst"), 19, 0, S("1234567890"), 5, 0, S("abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 19, 0, S("1234567890"), 5, 1, S("abcdefghijklmnopqrs6t")); + test(S("abcdefghijklmnopqrst"), 19, 0, S("1234567890"), 5, 2, S("abcdefghijklmnopqrs67t")); + test(S("abcdefghijklmnopqrst"), 19, 0, S("1234567890"), 5, 4, S("abcdefghijklmnopqrs6789t")); + test(S("abcdefghijklmnopqrst"), 19, 0, S("1234567890"), 5, 5, S("abcdefghijklmnopqrs67890t")); + test(S("abcdefghijklmnopqrst"), 19, 0, S("1234567890"), 5, 6, S("abcdefghijklmnopqrs67890t")); + test(S("abcdefghijklmnopqrst"), 19, 0, S("1234567890"), 9, 0, S("abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 19, 0, S("1234567890"), 9, 1, S("abcdefghijklmnopqrs0t")); + test(S("abcdefghijklmnopqrst"), 19, 0, S("1234567890"), 9, 2, S("abcdefghijklmnopqrs0t")); + test(S("abcdefghijklmnopqrst"), 19, 0, S("1234567890"), 10, 0, S("abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 19, 0, S("1234567890"), 10, 1, S("abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 19, 0, S("1234567890"), 11, 0, S("can't happen")); + test(S("abcdefghijklmnopqrst"), 19, 0, S("12345678901234567890"), 0, 0, S("abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 19, 0, S("12345678901234567890"), 0, 1, S("abcdefghijklmnopqrs1t")); + test(S("abcdefghijklmnopqrst"), 19, 0, S("12345678901234567890"), 0, 10, S("abcdefghijklmnopqrs1234567890t")); + test(S("abcdefghijklmnopqrst"), 19, 0, S("12345678901234567890"), 0, 19, S("abcdefghijklmnopqrs1234567890123456789t")); + test(S("abcdefghijklmnopqrst"), 19, 0, S("12345678901234567890"), 0, 20, S("abcdefghijklmnopqrs12345678901234567890t")); + test(S("abcdefghijklmnopqrst"), 19, 0, S("12345678901234567890"), 0, 21, S("abcdefghijklmnopqrs12345678901234567890t")); + test(S("abcdefghijklmnopqrst"), 19, 0, S("12345678901234567890"), 1, 0, S("abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 19, 0, S("12345678901234567890"), 1, 1, S("abcdefghijklmnopqrs2t")); + test(S("abcdefghijklmnopqrst"), 19, 0, S("12345678901234567890"), 1, 9, S("abcdefghijklmnopqrs234567890t")); + test(S("abcdefghijklmnopqrst"), 19, 0, S("12345678901234567890"), 1, 18, S("abcdefghijklmnopqrs234567890123456789t")); + test(S("abcdefghijklmnopqrst"), 19, 0, S("12345678901234567890"), 1, 19, S("abcdefghijklmnopqrs2345678901234567890t")); + test(S("abcdefghijklmnopqrst"), 19, 0, S("12345678901234567890"), 1, 20, S("abcdefghijklmnopqrs2345678901234567890t")); + test(S("abcdefghijklmnopqrst"), 19, 0, S("12345678901234567890"), 10, 0, S("abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 19, 0, S("12345678901234567890"), 10, 1, S("abcdefghijklmnopqrs1t")); + test(S("abcdefghijklmnopqrst"), 19, 0, S("12345678901234567890"), 10, 5, S("abcdefghijklmnopqrs12345t")); + test(S("abcdefghijklmnopqrst"), 19, 0, S("12345678901234567890"), 10, 9, S("abcdefghijklmnopqrs123456789t")); + test(S("abcdefghijklmnopqrst"), 19, 0, S("12345678901234567890"), 10, 10, S("abcdefghijklmnopqrs1234567890t")); + test(S("abcdefghijklmnopqrst"), 19, 0, S("12345678901234567890"), 10, 11, S("abcdefghijklmnopqrs1234567890t")); +} + +template +void test51() +{ + test(S("abcdefghijklmnopqrst"), 19, 0, S("12345678901234567890"), 19, 0, S("abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 19, 0, S("12345678901234567890"), 19, 1, S("abcdefghijklmnopqrs0t")); + test(S("abcdefghijklmnopqrst"), 19, 0, S("12345678901234567890"), 19, 2, S("abcdefghijklmnopqrs0t")); + test(S("abcdefghijklmnopqrst"), 19, 0, S("12345678901234567890"), 20, 0, S("abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 19, 0, S("12345678901234567890"), 20, 1, S("abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 19, 0, S("12345678901234567890"), 21, 0, S("can't happen")); + test(S("abcdefghijklmnopqrst"), 19, 1, S(""), 0, 0, S("abcdefghijklmnopqrs")); + test(S("abcdefghijklmnopqrst"), 19, 1, S(""), 0, 1, S("abcdefghijklmnopqrs")); + test(S("abcdefghijklmnopqrst"), 19, 1, S(""), 1, 0, S("can't happen")); + test(S("abcdefghijklmnopqrst"), 19, 1, S("12345"), 0, 0, S("abcdefghijklmnopqrs")); + test(S("abcdefghijklmnopqrst"), 19, 1, S("12345"), 0, 1, S("abcdefghijklmnopqrs1")); + test(S("abcdefghijklmnopqrst"), 19, 1, S("12345"), 0, 2, S("abcdefghijklmnopqrs12")); + test(S("abcdefghijklmnopqrst"), 19, 1, S("12345"), 0, 4, S("abcdefghijklmnopqrs1234")); + test(S("abcdefghijklmnopqrst"), 19, 1, S("12345"), 0, 5, S("abcdefghijklmnopqrs12345")); + test(S("abcdefghijklmnopqrst"), 19, 1, S("12345"), 0, 6, S("abcdefghijklmnopqrs12345")); + test(S("abcdefghijklmnopqrst"), 19, 1, S("12345"), 1, 0, S("abcdefghijklmnopqrs")); + test(S("abcdefghijklmnopqrst"), 19, 1, S("12345"), 1, 1, S("abcdefghijklmnopqrs2")); + test(S("abcdefghijklmnopqrst"), 19, 1, S("12345"), 1, 2, S("abcdefghijklmnopqrs23")); + test(S("abcdefghijklmnopqrst"), 19, 1, S("12345"), 1, 3, S("abcdefghijklmnopqrs234")); + test(S("abcdefghijklmnopqrst"), 19, 1, S("12345"), 1, 4, S("abcdefghijklmnopqrs2345")); + test(S("abcdefghijklmnopqrst"), 19, 1, S("12345"), 1, 5, S("abcdefghijklmnopqrs2345")); + test(S("abcdefghijklmnopqrst"), 19, 1, S("12345"), 2, 0, S("abcdefghijklmnopqrs")); + test(S("abcdefghijklmnopqrst"), 19, 1, S("12345"), 2, 1, S("abcdefghijklmnopqrs3")); + test(S("abcdefghijklmnopqrst"), 19, 1, S("12345"), 2, 2, S("abcdefghijklmnopqrs34")); + test(S("abcdefghijklmnopqrst"), 19, 1, S("12345"), 2, 3, S("abcdefghijklmnopqrs345")); + test(S("abcdefghijklmnopqrst"), 19, 1, S("12345"), 2, 4, S("abcdefghijklmnopqrs345")); + test(S("abcdefghijklmnopqrst"), 19, 1, S("12345"), 4, 0, S("abcdefghijklmnopqrs")); + test(S("abcdefghijklmnopqrst"), 19, 1, S("12345"), 4, 1, S("abcdefghijklmnopqrs5")); + test(S("abcdefghijklmnopqrst"), 19, 1, S("12345"), 4, 2, S("abcdefghijklmnopqrs5")); + test(S("abcdefghijklmnopqrst"), 19, 1, S("12345"), 5, 0, S("abcdefghijklmnopqrs")); + test(S("abcdefghijklmnopqrst"), 19, 1, S("12345"), 5, 1, S("abcdefghijklmnopqrs")); + test(S("abcdefghijklmnopqrst"), 19, 1, S("12345"), 6, 0, S("can't happen")); + test(S("abcdefghijklmnopqrst"), 19, 1, S("1234567890"), 0, 0, S("abcdefghijklmnopqrs")); + test(S("abcdefghijklmnopqrst"), 19, 1, S("1234567890"), 0, 1, S("abcdefghijklmnopqrs1")); + test(S("abcdefghijklmnopqrst"), 19, 1, S("1234567890"), 0, 5, S("abcdefghijklmnopqrs12345")); + test(S("abcdefghijklmnopqrst"), 19, 1, S("1234567890"), 0, 9, S("abcdefghijklmnopqrs123456789")); + test(S("abcdefghijklmnopqrst"), 19, 1, S("1234567890"), 0, 10, S("abcdefghijklmnopqrs1234567890")); + test(S("abcdefghijklmnopqrst"), 19, 1, S("1234567890"), 0, 11, S("abcdefghijklmnopqrs1234567890")); + test(S("abcdefghijklmnopqrst"), 19, 1, S("1234567890"), 1, 0, S("abcdefghijklmnopqrs")); + test(S("abcdefghijklmnopqrst"), 19, 1, S("1234567890"), 1, 1, S("abcdefghijklmnopqrs2")); + test(S("abcdefghijklmnopqrst"), 19, 1, S("1234567890"), 1, 4, S("abcdefghijklmnopqrs2345")); + test(S("abcdefghijklmnopqrst"), 19, 1, S("1234567890"), 1, 8, S("abcdefghijklmnopqrs23456789")); + test(S("abcdefghijklmnopqrst"), 19, 1, S("1234567890"), 1, 9, S("abcdefghijklmnopqrs234567890")); + test(S("abcdefghijklmnopqrst"), 19, 1, S("1234567890"), 1, 10, S("abcdefghijklmnopqrs234567890")); + test(S("abcdefghijklmnopqrst"), 19, 1, S("1234567890"), 5, 0, S("abcdefghijklmnopqrs")); + test(S("abcdefghijklmnopqrst"), 19, 1, S("1234567890"), 5, 1, S("abcdefghijklmnopqrs6")); + test(S("abcdefghijklmnopqrst"), 19, 1, S("1234567890"), 5, 2, S("abcdefghijklmnopqrs67")); + test(S("abcdefghijklmnopqrst"), 19, 1, S("1234567890"), 5, 4, S("abcdefghijklmnopqrs6789")); + test(S("abcdefghijklmnopqrst"), 19, 1, S("1234567890"), 5, 5, S("abcdefghijklmnopqrs67890")); + test(S("abcdefghijklmnopqrst"), 19, 1, S("1234567890"), 5, 6, S("abcdefghijklmnopqrs67890")); + test(S("abcdefghijklmnopqrst"), 19, 1, S("1234567890"), 9, 0, S("abcdefghijklmnopqrs")); + test(S("abcdefghijklmnopqrst"), 19, 1, S("1234567890"), 9, 1, S("abcdefghijklmnopqrs0")); + test(S("abcdefghijklmnopqrst"), 19, 1, S("1234567890"), 9, 2, S("abcdefghijklmnopqrs0")); + test(S("abcdefghijklmnopqrst"), 19, 1, S("1234567890"), 10, 0, S("abcdefghijklmnopqrs")); + test(S("abcdefghijklmnopqrst"), 19, 1, S("1234567890"), 10, 1, S("abcdefghijklmnopqrs")); + test(S("abcdefghijklmnopqrst"), 19, 1, S("1234567890"), 11, 0, S("can't happen")); + test(S("abcdefghijklmnopqrst"), 19, 1, S("12345678901234567890"), 0, 0, S("abcdefghijklmnopqrs")); + test(S("abcdefghijklmnopqrst"), 19, 1, S("12345678901234567890"), 0, 1, S("abcdefghijklmnopqrs1")); + test(S("abcdefghijklmnopqrst"), 19, 1, S("12345678901234567890"), 0, 10, S("abcdefghijklmnopqrs1234567890")); + test(S("abcdefghijklmnopqrst"), 19, 1, S("12345678901234567890"), 0, 19, S("abcdefghijklmnopqrs1234567890123456789")); + test(S("abcdefghijklmnopqrst"), 19, 1, S("12345678901234567890"), 0, 20, S("abcdefghijklmnopqrs12345678901234567890")); + test(S("abcdefghijklmnopqrst"), 19, 1, S("12345678901234567890"), 0, 21, S("abcdefghijklmnopqrs12345678901234567890")); + test(S("abcdefghijklmnopqrst"), 19, 1, S("12345678901234567890"), 1, 0, S("abcdefghijklmnopqrs")); + test(S("abcdefghijklmnopqrst"), 19, 1, S("12345678901234567890"), 1, 1, S("abcdefghijklmnopqrs2")); + test(S("abcdefghijklmnopqrst"), 19, 1, S("12345678901234567890"), 1, 9, S("abcdefghijklmnopqrs234567890")); + test(S("abcdefghijklmnopqrst"), 19, 1, S("12345678901234567890"), 1, 18, S("abcdefghijklmnopqrs234567890123456789")); + test(S("abcdefghijklmnopqrst"), 19, 1, S("12345678901234567890"), 1, 19, S("abcdefghijklmnopqrs2345678901234567890")); + test(S("abcdefghijklmnopqrst"), 19, 1, S("12345678901234567890"), 1, 20, S("abcdefghijklmnopqrs2345678901234567890")); + test(S("abcdefghijklmnopqrst"), 19, 1, S("12345678901234567890"), 10, 0, S("abcdefghijklmnopqrs")); + test(S("abcdefghijklmnopqrst"), 19, 1, S("12345678901234567890"), 10, 1, S("abcdefghijklmnopqrs1")); + test(S("abcdefghijklmnopqrst"), 19, 1, S("12345678901234567890"), 10, 5, S("abcdefghijklmnopqrs12345")); + test(S("abcdefghijklmnopqrst"), 19, 1, S("12345678901234567890"), 10, 9, S("abcdefghijklmnopqrs123456789")); + test(S("abcdefghijklmnopqrst"), 19, 1, S("12345678901234567890"), 10, 10, S("abcdefghijklmnopqrs1234567890")); + test(S("abcdefghijklmnopqrst"), 19, 1, S("12345678901234567890"), 10, 11, S("abcdefghijklmnopqrs1234567890")); + test(S("abcdefghijklmnopqrst"), 19, 1, S("12345678901234567890"), 19, 0, S("abcdefghijklmnopqrs")); + test(S("abcdefghijklmnopqrst"), 19, 1, S("12345678901234567890"), 19, 1, S("abcdefghijklmnopqrs0")); + test(S("abcdefghijklmnopqrst"), 19, 1, S("12345678901234567890"), 19, 2, S("abcdefghijklmnopqrs0")); + test(S("abcdefghijklmnopqrst"), 19, 1, S("12345678901234567890"), 20, 0, S("abcdefghijklmnopqrs")); + test(S("abcdefghijklmnopqrst"), 19, 1, S("12345678901234567890"), 20, 1, S("abcdefghijklmnopqrs")); + test(S("abcdefghijklmnopqrst"), 19, 1, S("12345678901234567890"), 21, 0, S("can't happen")); + test(S("abcdefghijklmnopqrst"), 19, 2, S(""), 0, 0, S("abcdefghijklmnopqrs")); + test(S("abcdefghijklmnopqrst"), 19, 2, S(""), 0, 1, S("abcdefghijklmnopqrs")); + test(S("abcdefghijklmnopqrst"), 19, 2, S(""), 1, 0, S("can't happen")); + test(S("abcdefghijklmnopqrst"), 19, 2, S("12345"), 0, 0, S("abcdefghijklmnopqrs")); + test(S("abcdefghijklmnopqrst"), 19, 2, S("12345"), 0, 1, S("abcdefghijklmnopqrs1")); + test(S("abcdefghijklmnopqrst"), 19, 2, S("12345"), 0, 2, S("abcdefghijklmnopqrs12")); + test(S("abcdefghijklmnopqrst"), 19, 2, S("12345"), 0, 4, S("abcdefghijklmnopqrs1234")); + test(S("abcdefghijklmnopqrst"), 19, 2, S("12345"), 0, 5, S("abcdefghijklmnopqrs12345")); + test(S("abcdefghijklmnopqrst"), 19, 2, S("12345"), 0, 6, S("abcdefghijklmnopqrs12345")); + test(S("abcdefghijklmnopqrst"), 19, 2, S("12345"), 1, 0, S("abcdefghijklmnopqrs")); + test(S("abcdefghijklmnopqrst"), 19, 2, S("12345"), 1, 1, S("abcdefghijklmnopqrs2")); + test(S("abcdefghijklmnopqrst"), 19, 2, S("12345"), 1, 2, S("abcdefghijklmnopqrs23")); + test(S("abcdefghijklmnopqrst"), 19, 2, S("12345"), 1, 3, S("abcdefghijklmnopqrs234")); + test(S("abcdefghijklmnopqrst"), 19, 2, S("12345"), 1, 4, S("abcdefghijklmnopqrs2345")); + test(S("abcdefghijklmnopqrst"), 19, 2, S("12345"), 1, 5, S("abcdefghijklmnopqrs2345")); + test(S("abcdefghijklmnopqrst"), 19, 2, S("12345"), 2, 0, S("abcdefghijklmnopqrs")); + test(S("abcdefghijklmnopqrst"), 19, 2, S("12345"), 2, 1, S("abcdefghijklmnopqrs3")); + test(S("abcdefghijklmnopqrst"), 19, 2, S("12345"), 2, 2, S("abcdefghijklmnopqrs34")); + test(S("abcdefghijklmnopqrst"), 19, 2, S("12345"), 2, 3, S("abcdefghijklmnopqrs345")); + test(S("abcdefghijklmnopqrst"), 19, 2, S("12345"), 2, 4, S("abcdefghijklmnopqrs345")); +} + +template +void test52() +{ + test(S("abcdefghijklmnopqrst"), 19, 2, S("12345"), 4, 0, S("abcdefghijklmnopqrs")); + test(S("abcdefghijklmnopqrst"), 19, 2, S("12345"), 4, 1, S("abcdefghijklmnopqrs5")); + test(S("abcdefghijklmnopqrst"), 19, 2, S("12345"), 4, 2, S("abcdefghijklmnopqrs5")); + test(S("abcdefghijklmnopqrst"), 19, 2, S("12345"), 5, 0, S("abcdefghijklmnopqrs")); + test(S("abcdefghijklmnopqrst"), 19, 2, S("12345"), 5, 1, S("abcdefghijklmnopqrs")); + test(S("abcdefghijklmnopqrst"), 19, 2, S("12345"), 6, 0, S("can't happen")); + test(S("abcdefghijklmnopqrst"), 19, 2, S("1234567890"), 0, 0, S("abcdefghijklmnopqrs")); + test(S("abcdefghijklmnopqrst"), 19, 2, S("1234567890"), 0, 1, S("abcdefghijklmnopqrs1")); + test(S("abcdefghijklmnopqrst"), 19, 2, S("1234567890"), 0, 5, S("abcdefghijklmnopqrs12345")); + test(S("abcdefghijklmnopqrst"), 19, 2, S("1234567890"), 0, 9, S("abcdefghijklmnopqrs123456789")); + test(S("abcdefghijklmnopqrst"), 19, 2, S("1234567890"), 0, 10, S("abcdefghijklmnopqrs1234567890")); + test(S("abcdefghijklmnopqrst"), 19, 2, S("1234567890"), 0, 11, S("abcdefghijklmnopqrs1234567890")); + test(S("abcdefghijklmnopqrst"), 19, 2, S("1234567890"), 1, 0, S("abcdefghijklmnopqrs")); + test(S("abcdefghijklmnopqrst"), 19, 2, S("1234567890"), 1, 1, S("abcdefghijklmnopqrs2")); + test(S("abcdefghijklmnopqrst"), 19, 2, S("1234567890"), 1, 4, S("abcdefghijklmnopqrs2345")); + test(S("abcdefghijklmnopqrst"), 19, 2, S("1234567890"), 1, 8, S("abcdefghijklmnopqrs23456789")); + test(S("abcdefghijklmnopqrst"), 19, 2, S("1234567890"), 1, 9, S("abcdefghijklmnopqrs234567890")); + test(S("abcdefghijklmnopqrst"), 19, 2, S("1234567890"), 1, 10, S("abcdefghijklmnopqrs234567890")); + test(S("abcdefghijklmnopqrst"), 19, 2, S("1234567890"), 5, 0, S("abcdefghijklmnopqrs")); + test(S("abcdefghijklmnopqrst"), 19, 2, S("1234567890"), 5, 1, S("abcdefghijklmnopqrs6")); + test(S("abcdefghijklmnopqrst"), 19, 2, S("1234567890"), 5, 2, S("abcdefghijklmnopqrs67")); + test(S("abcdefghijklmnopqrst"), 19, 2, S("1234567890"), 5, 4, S("abcdefghijklmnopqrs6789")); + test(S("abcdefghijklmnopqrst"), 19, 2, S("1234567890"), 5, 5, S("abcdefghijklmnopqrs67890")); + test(S("abcdefghijklmnopqrst"), 19, 2, S("1234567890"), 5, 6, S("abcdefghijklmnopqrs67890")); + test(S("abcdefghijklmnopqrst"), 19, 2, S("1234567890"), 9, 0, S("abcdefghijklmnopqrs")); + test(S("abcdefghijklmnopqrst"), 19, 2, S("1234567890"), 9, 1, S("abcdefghijklmnopqrs0")); + test(S("abcdefghijklmnopqrst"), 19, 2, S("1234567890"), 9, 2, S("abcdefghijklmnopqrs0")); + test(S("abcdefghijklmnopqrst"), 19, 2, S("1234567890"), 10, 0, S("abcdefghijklmnopqrs")); + test(S("abcdefghijklmnopqrst"), 19, 2, S("1234567890"), 10, 1, S("abcdefghijklmnopqrs")); + test(S("abcdefghijklmnopqrst"), 19, 2, S("1234567890"), 11, 0, S("can't happen")); + test(S("abcdefghijklmnopqrst"), 19, 2, S("12345678901234567890"), 0, 0, S("abcdefghijklmnopqrs")); + test(S("abcdefghijklmnopqrst"), 19, 2, S("12345678901234567890"), 0, 1, S("abcdefghijklmnopqrs1")); + test(S("abcdefghijklmnopqrst"), 19, 2, S("12345678901234567890"), 0, 10, S("abcdefghijklmnopqrs1234567890")); + test(S("abcdefghijklmnopqrst"), 19, 2, S("12345678901234567890"), 0, 19, S("abcdefghijklmnopqrs1234567890123456789")); + test(S("abcdefghijklmnopqrst"), 19, 2, S("12345678901234567890"), 0, 20, S("abcdefghijklmnopqrs12345678901234567890")); + test(S("abcdefghijklmnopqrst"), 19, 2, S("12345678901234567890"), 0, 21, S("abcdefghijklmnopqrs12345678901234567890")); + test(S("abcdefghijklmnopqrst"), 19, 2, S("12345678901234567890"), 1, 0, S("abcdefghijklmnopqrs")); + test(S("abcdefghijklmnopqrst"), 19, 2, S("12345678901234567890"), 1, 1, S("abcdefghijklmnopqrs2")); + test(S("abcdefghijklmnopqrst"), 19, 2, S("12345678901234567890"), 1, 9, S("abcdefghijklmnopqrs234567890")); + test(S("abcdefghijklmnopqrst"), 19, 2, S("12345678901234567890"), 1, 18, S("abcdefghijklmnopqrs234567890123456789")); + test(S("abcdefghijklmnopqrst"), 19, 2, S("12345678901234567890"), 1, 19, S("abcdefghijklmnopqrs2345678901234567890")); + test(S("abcdefghijklmnopqrst"), 19, 2, S("12345678901234567890"), 1, 20, S("abcdefghijklmnopqrs2345678901234567890")); + test(S("abcdefghijklmnopqrst"), 19, 2, S("12345678901234567890"), 10, 0, S("abcdefghijklmnopqrs")); + test(S("abcdefghijklmnopqrst"), 19, 2, S("12345678901234567890"), 10, 1, S("abcdefghijklmnopqrs1")); + test(S("abcdefghijklmnopqrst"), 19, 2, S("12345678901234567890"), 10, 5, S("abcdefghijklmnopqrs12345")); + test(S("abcdefghijklmnopqrst"), 19, 2, S("12345678901234567890"), 10, 9, S("abcdefghijklmnopqrs123456789")); + test(S("abcdefghijklmnopqrst"), 19, 2, S("12345678901234567890"), 10, 10, S("abcdefghijklmnopqrs1234567890")); + test(S("abcdefghijklmnopqrst"), 19, 2, S("12345678901234567890"), 10, 11, S("abcdefghijklmnopqrs1234567890")); + test(S("abcdefghijklmnopqrst"), 19, 2, S("12345678901234567890"), 19, 0, S("abcdefghijklmnopqrs")); + test(S("abcdefghijklmnopqrst"), 19, 2, S("12345678901234567890"), 19, 1, S("abcdefghijklmnopqrs0")); + test(S("abcdefghijklmnopqrst"), 19, 2, S("12345678901234567890"), 19, 2, S("abcdefghijklmnopqrs0")); + test(S("abcdefghijklmnopqrst"), 19, 2, S("12345678901234567890"), 20, 0, S("abcdefghijklmnopqrs")); + test(S("abcdefghijklmnopqrst"), 19, 2, S("12345678901234567890"), 20, 1, S("abcdefghijklmnopqrs")); + test(S("abcdefghijklmnopqrst"), 19, 2, S("12345678901234567890"), 21, 0, S("can't happen")); + test(S("abcdefghijklmnopqrst"), 20, 0, S(""), 0, 0, S("abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 20, 0, S(""), 0, 1, S("abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 20, 0, S(""), 1, 0, S("can't happen")); + test(S("abcdefghijklmnopqrst"), 20, 0, S("12345"), 0, 0, S("abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 20, 0, S("12345"), 0, 1, S("abcdefghijklmnopqrst1")); + test(S("abcdefghijklmnopqrst"), 20, 0, S("12345"), 0, 2, S("abcdefghijklmnopqrst12")); + test(S("abcdefghijklmnopqrst"), 20, 0, S("12345"), 0, 4, S("abcdefghijklmnopqrst1234")); + test(S("abcdefghijklmnopqrst"), 20, 0, S("12345"), 0, 5, S("abcdefghijklmnopqrst12345")); + test(S("abcdefghijklmnopqrst"), 20, 0, S("12345"), 0, 6, S("abcdefghijklmnopqrst12345")); + test(S("abcdefghijklmnopqrst"), 20, 0, S("12345"), 1, 0, S("abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 20, 0, S("12345"), 1, 1, S("abcdefghijklmnopqrst2")); + test(S("abcdefghijklmnopqrst"), 20, 0, S("12345"), 1, 2, S("abcdefghijklmnopqrst23")); + test(S("abcdefghijklmnopqrst"), 20, 0, S("12345"), 1, 3, S("abcdefghijklmnopqrst234")); + test(S("abcdefghijklmnopqrst"), 20, 0, S("12345"), 1, 4, S("abcdefghijklmnopqrst2345")); + test(S("abcdefghijklmnopqrst"), 20, 0, S("12345"), 1, 5, S("abcdefghijklmnopqrst2345")); + test(S("abcdefghijklmnopqrst"), 20, 0, S("12345"), 2, 0, S("abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 20, 0, S("12345"), 2, 1, S("abcdefghijklmnopqrst3")); + test(S("abcdefghijklmnopqrst"), 20, 0, S("12345"), 2, 2, S("abcdefghijklmnopqrst34")); + test(S("abcdefghijklmnopqrst"), 20, 0, S("12345"), 2, 3, S("abcdefghijklmnopqrst345")); + test(S("abcdefghijklmnopqrst"), 20, 0, S("12345"), 2, 4, S("abcdefghijklmnopqrst345")); + test(S("abcdefghijklmnopqrst"), 20, 0, S("12345"), 4, 0, S("abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 20, 0, S("12345"), 4, 1, S("abcdefghijklmnopqrst5")); + test(S("abcdefghijklmnopqrst"), 20, 0, S("12345"), 4, 2, S("abcdefghijklmnopqrst5")); + test(S("abcdefghijklmnopqrst"), 20, 0, S("12345"), 5, 0, S("abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 20, 0, S("12345"), 5, 1, S("abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 20, 0, S("12345"), 6, 0, S("can't happen")); + test(S("abcdefghijklmnopqrst"), 20, 0, S("1234567890"), 0, 0, S("abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 20, 0, S("1234567890"), 0, 1, S("abcdefghijklmnopqrst1")); + test(S("abcdefghijklmnopqrst"), 20, 0, S("1234567890"), 0, 5, S("abcdefghijklmnopqrst12345")); + test(S("abcdefghijklmnopqrst"), 20, 0, S("1234567890"), 0, 9, S("abcdefghijklmnopqrst123456789")); + test(S("abcdefghijklmnopqrst"), 20, 0, S("1234567890"), 0, 10, S("abcdefghijklmnopqrst1234567890")); + test(S("abcdefghijklmnopqrst"), 20, 0, S("1234567890"), 0, 11, S("abcdefghijklmnopqrst1234567890")); + test(S("abcdefghijklmnopqrst"), 20, 0, S("1234567890"), 1, 0, S("abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 20, 0, S("1234567890"), 1, 1, S("abcdefghijklmnopqrst2")); + test(S("abcdefghijklmnopqrst"), 20, 0, S("1234567890"), 1, 4, S("abcdefghijklmnopqrst2345")); + test(S("abcdefghijklmnopqrst"), 20, 0, S("1234567890"), 1, 8, S("abcdefghijklmnopqrst23456789")); + test(S("abcdefghijklmnopqrst"), 20, 0, S("1234567890"), 1, 9, S("abcdefghijklmnopqrst234567890")); + test(S("abcdefghijklmnopqrst"), 20, 0, S("1234567890"), 1, 10, S("abcdefghijklmnopqrst234567890")); + test(S("abcdefghijklmnopqrst"), 20, 0, S("1234567890"), 5, 0, S("abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 20, 0, S("1234567890"), 5, 1, S("abcdefghijklmnopqrst6")); + test(S("abcdefghijklmnopqrst"), 20, 0, S("1234567890"), 5, 2, S("abcdefghijklmnopqrst67")); + test(S("abcdefghijklmnopqrst"), 20, 0, S("1234567890"), 5, 4, S("abcdefghijklmnopqrst6789")); + test(S("abcdefghijklmnopqrst"), 20, 0, S("1234567890"), 5, 5, S("abcdefghijklmnopqrst67890")); + test(S("abcdefghijklmnopqrst"), 20, 0, S("1234567890"), 5, 6, S("abcdefghijklmnopqrst67890")); + test(S("abcdefghijklmnopqrst"), 20, 0, S("1234567890"), 9, 0, S("abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 20, 0, S("1234567890"), 9, 1, S("abcdefghijklmnopqrst0")); +} + +template +void test53() +{ + test(S("abcdefghijklmnopqrst"), 20, 0, S("1234567890"), 9, 2, S("abcdefghijklmnopqrst0")); + test(S("abcdefghijklmnopqrst"), 20, 0, S("1234567890"), 10, 0, S("abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 20, 0, S("1234567890"), 10, 1, S("abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 20, 0, S("1234567890"), 11, 0, S("can't happen")); + test(S("abcdefghijklmnopqrst"), 20, 0, S("12345678901234567890"), 0, 0, S("abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 20, 0, S("12345678901234567890"), 0, 1, S("abcdefghijklmnopqrst1")); + test(S("abcdefghijklmnopqrst"), 20, 0, S("12345678901234567890"), 0, 10, S("abcdefghijklmnopqrst1234567890")); + test(S("abcdefghijklmnopqrst"), 20, 0, S("12345678901234567890"), 0, 19, S("abcdefghijklmnopqrst1234567890123456789")); + test(S("abcdefghijklmnopqrst"), 20, 0, S("12345678901234567890"), 0, 20, S("abcdefghijklmnopqrst12345678901234567890")); + test(S("abcdefghijklmnopqrst"), 20, 0, S("12345678901234567890"), 0, 21, S("abcdefghijklmnopqrst12345678901234567890")); + test(S("abcdefghijklmnopqrst"), 20, 0, S("12345678901234567890"), 1, 0, S("abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 20, 0, S("12345678901234567890"), 1, 1, S("abcdefghijklmnopqrst2")); + test(S("abcdefghijklmnopqrst"), 20, 0, S("12345678901234567890"), 1, 9, S("abcdefghijklmnopqrst234567890")); + test(S("abcdefghijklmnopqrst"), 20, 0, S("12345678901234567890"), 1, 18, S("abcdefghijklmnopqrst234567890123456789")); + test(S("abcdefghijklmnopqrst"), 20, 0, S("12345678901234567890"), 1, 19, S("abcdefghijklmnopqrst2345678901234567890")); + test(S("abcdefghijklmnopqrst"), 20, 0, S("12345678901234567890"), 1, 20, S("abcdefghijklmnopqrst2345678901234567890")); + test(S("abcdefghijklmnopqrst"), 20, 0, S("12345678901234567890"), 10, 0, S("abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 20, 0, S("12345678901234567890"), 10, 1, S("abcdefghijklmnopqrst1")); + test(S("abcdefghijklmnopqrst"), 20, 0, S("12345678901234567890"), 10, 5, S("abcdefghijklmnopqrst12345")); + test(S("abcdefghijklmnopqrst"), 20, 0, S("12345678901234567890"), 10, 9, S("abcdefghijklmnopqrst123456789")); + test(S("abcdefghijklmnopqrst"), 20, 0, S("12345678901234567890"), 10, 10, S("abcdefghijklmnopqrst1234567890")); + test(S("abcdefghijklmnopqrst"), 20, 0, S("12345678901234567890"), 10, 11, S("abcdefghijklmnopqrst1234567890")); + test(S("abcdefghijklmnopqrst"), 20, 0, S("12345678901234567890"), 19, 0, S("abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 20, 0, S("12345678901234567890"), 19, 1, S("abcdefghijklmnopqrst0")); + test(S("abcdefghijklmnopqrst"), 20, 0, S("12345678901234567890"), 19, 2, S("abcdefghijklmnopqrst0")); + test(S("abcdefghijklmnopqrst"), 20, 0, S("12345678901234567890"), 20, 0, S("abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 20, 0, S("12345678901234567890"), 20, 1, S("abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 20, 0, S("12345678901234567890"), 21, 0, S("can't happen")); + test(S("abcdefghijklmnopqrst"), 20, 1, S(""), 0, 0, S("abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 20, 1, S(""), 0, 1, S("abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 20, 1, S(""), 1, 0, S("can't happen")); + test(S("abcdefghijklmnopqrst"), 20, 1, S("12345"), 0, 0, S("abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 20, 1, S("12345"), 0, 1, S("abcdefghijklmnopqrst1")); + test(S("abcdefghijklmnopqrst"), 20, 1, S("12345"), 0, 2, S("abcdefghijklmnopqrst12")); + test(S("abcdefghijklmnopqrst"), 20, 1, S("12345"), 0, 4, S("abcdefghijklmnopqrst1234")); + test(S("abcdefghijklmnopqrst"), 20, 1, S("12345"), 0, 5, S("abcdefghijklmnopqrst12345")); + test(S("abcdefghijklmnopqrst"), 20, 1, S("12345"), 0, 6, S("abcdefghijklmnopqrst12345")); + test(S("abcdefghijklmnopqrst"), 20, 1, S("12345"), 1, 0, S("abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 20, 1, S("12345"), 1, 1, S("abcdefghijklmnopqrst2")); + test(S("abcdefghijklmnopqrst"), 20, 1, S("12345"), 1, 2, S("abcdefghijklmnopqrst23")); + test(S("abcdefghijklmnopqrst"), 20, 1, S("12345"), 1, 3, S("abcdefghijklmnopqrst234")); + test(S("abcdefghijklmnopqrst"), 20, 1, S("12345"), 1, 4, S("abcdefghijklmnopqrst2345")); + test(S("abcdefghijklmnopqrst"), 20, 1, S("12345"), 1, 5, S("abcdefghijklmnopqrst2345")); + test(S("abcdefghijklmnopqrst"), 20, 1, S("12345"), 2, 0, S("abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 20, 1, S("12345"), 2, 1, S("abcdefghijklmnopqrst3")); + test(S("abcdefghijklmnopqrst"), 20, 1, S("12345"), 2, 2, S("abcdefghijklmnopqrst34")); + test(S("abcdefghijklmnopqrst"), 20, 1, S("12345"), 2, 3, S("abcdefghijklmnopqrst345")); + test(S("abcdefghijklmnopqrst"), 20, 1, S("12345"), 2, 4, S("abcdefghijklmnopqrst345")); + test(S("abcdefghijklmnopqrst"), 20, 1, S("12345"), 4, 0, S("abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 20, 1, S("12345"), 4, 1, S("abcdefghijklmnopqrst5")); + test(S("abcdefghijklmnopqrst"), 20, 1, S("12345"), 4, 2, S("abcdefghijklmnopqrst5")); + test(S("abcdefghijklmnopqrst"), 20, 1, S("12345"), 5, 0, S("abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 20, 1, S("12345"), 5, 1, S("abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 20, 1, S("12345"), 6, 0, S("can't happen")); + test(S("abcdefghijklmnopqrst"), 20, 1, S("1234567890"), 0, 0, S("abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 20, 1, S("1234567890"), 0, 1, S("abcdefghijklmnopqrst1")); + test(S("abcdefghijklmnopqrst"), 20, 1, S("1234567890"), 0, 5, S("abcdefghijklmnopqrst12345")); + test(S("abcdefghijklmnopqrst"), 20, 1, S("1234567890"), 0, 9, S("abcdefghijklmnopqrst123456789")); + test(S("abcdefghijklmnopqrst"), 20, 1, S("1234567890"), 0, 10, S("abcdefghijklmnopqrst1234567890")); + test(S("abcdefghijklmnopqrst"), 20, 1, S("1234567890"), 0, 11, S("abcdefghijklmnopqrst1234567890")); + test(S("abcdefghijklmnopqrst"), 20, 1, S("1234567890"), 1, 0, S("abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 20, 1, S("1234567890"), 1, 1, S("abcdefghijklmnopqrst2")); + test(S("abcdefghijklmnopqrst"), 20, 1, S("1234567890"), 1, 4, S("abcdefghijklmnopqrst2345")); + test(S("abcdefghijklmnopqrst"), 20, 1, S("1234567890"), 1, 8, S("abcdefghijklmnopqrst23456789")); + test(S("abcdefghijklmnopqrst"), 20, 1, S("1234567890"), 1, 9, S("abcdefghijklmnopqrst234567890")); + test(S("abcdefghijklmnopqrst"), 20, 1, S("1234567890"), 1, 10, S("abcdefghijklmnopqrst234567890")); + test(S("abcdefghijklmnopqrst"), 20, 1, S("1234567890"), 5, 0, S("abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 20, 1, S("1234567890"), 5, 1, S("abcdefghijklmnopqrst6")); + test(S("abcdefghijklmnopqrst"), 20, 1, S("1234567890"), 5, 2, S("abcdefghijklmnopqrst67")); + test(S("abcdefghijklmnopqrst"), 20, 1, S("1234567890"), 5, 4, S("abcdefghijklmnopqrst6789")); + test(S("abcdefghijklmnopqrst"), 20, 1, S("1234567890"), 5, 5, S("abcdefghijklmnopqrst67890")); + test(S("abcdefghijklmnopqrst"), 20, 1, S("1234567890"), 5, 6, S("abcdefghijklmnopqrst67890")); + test(S("abcdefghijklmnopqrst"), 20, 1, S("1234567890"), 9, 0, S("abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 20, 1, S("1234567890"), 9, 1, S("abcdefghijklmnopqrst0")); + test(S("abcdefghijklmnopqrst"), 20, 1, S("1234567890"), 9, 2, S("abcdefghijklmnopqrst0")); + test(S("abcdefghijklmnopqrst"), 20, 1, S("1234567890"), 10, 0, S("abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 20, 1, S("1234567890"), 10, 1, S("abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 20, 1, S("1234567890"), 11, 0, S("can't happen")); + test(S("abcdefghijklmnopqrst"), 20, 1, S("12345678901234567890"), 0, 0, S("abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 20, 1, S("12345678901234567890"), 0, 1, S("abcdefghijklmnopqrst1")); + test(S("abcdefghijklmnopqrst"), 20, 1, S("12345678901234567890"), 0, 10, S("abcdefghijklmnopqrst1234567890")); + test(S("abcdefghijklmnopqrst"), 20, 1, S("12345678901234567890"), 0, 19, S("abcdefghijklmnopqrst1234567890123456789")); + test(S("abcdefghijklmnopqrst"), 20, 1, S("12345678901234567890"), 0, 20, S("abcdefghijklmnopqrst12345678901234567890")); + test(S("abcdefghijklmnopqrst"), 20, 1, S("12345678901234567890"), 0, 21, S("abcdefghijklmnopqrst12345678901234567890")); + test(S("abcdefghijklmnopqrst"), 20, 1, S("12345678901234567890"), 1, 0, S("abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 20, 1, S("12345678901234567890"), 1, 1, S("abcdefghijklmnopqrst2")); + test(S("abcdefghijklmnopqrst"), 20, 1, S("12345678901234567890"), 1, 9, S("abcdefghijklmnopqrst234567890")); + test(S("abcdefghijklmnopqrst"), 20, 1, S("12345678901234567890"), 1, 18, S("abcdefghijklmnopqrst234567890123456789")); + test(S("abcdefghijklmnopqrst"), 20, 1, S("12345678901234567890"), 1, 19, S("abcdefghijklmnopqrst2345678901234567890")); + test(S("abcdefghijklmnopqrst"), 20, 1, S("12345678901234567890"), 1, 20, S("abcdefghijklmnopqrst2345678901234567890")); + test(S("abcdefghijklmnopqrst"), 20, 1, S("12345678901234567890"), 10, 0, S("abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 20, 1, S("12345678901234567890"), 10, 1, S("abcdefghijklmnopqrst1")); + test(S("abcdefghijklmnopqrst"), 20, 1, S("12345678901234567890"), 10, 5, S("abcdefghijklmnopqrst12345")); + test(S("abcdefghijklmnopqrst"), 20, 1, S("12345678901234567890"), 10, 9, S("abcdefghijklmnopqrst123456789")); + test(S("abcdefghijklmnopqrst"), 20, 1, S("12345678901234567890"), 10, 10, S("abcdefghijklmnopqrst1234567890")); + test(S("abcdefghijklmnopqrst"), 20, 1, S("12345678901234567890"), 10, 11, S("abcdefghijklmnopqrst1234567890")); + test(S("abcdefghijklmnopqrst"), 20, 1, S("12345678901234567890"), 19, 0, S("abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 20, 1, S("12345678901234567890"), 19, 1, S("abcdefghijklmnopqrst0")); + test(S("abcdefghijklmnopqrst"), 20, 1, S("12345678901234567890"), 19, 2, S("abcdefghijklmnopqrst0")); + test(S("abcdefghijklmnopqrst"), 20, 1, S("12345678901234567890"), 20, 0, S("abcdefghijklmnopqrst")); +} + +template +void test54() +{ + test(S("abcdefghijklmnopqrst"), 20, 1, S("12345678901234567890"), 20, 1, S("abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 20, 1, S("12345678901234567890"), 21, 0, S("can't happen")); + test(S("abcdefghijklmnopqrst"), 21, 0, S(""), 0, 0, S("can't happen")); + test(S("abcdefghijklmnopqrst"), 21, 0, S(""), 0, 1, S("can't happen")); + test(S("abcdefghijklmnopqrst"), 21, 0, S(""), 1, 0, S("can't happen")); + test(S("abcdefghijklmnopqrst"), 21, 0, S("12345"), 0, 0, S("can't happen")); + test(S("abcdefghijklmnopqrst"), 21, 0, S("12345"), 0, 1, S("can't happen")); + test(S("abcdefghijklmnopqrst"), 21, 0, S("12345"), 0, 2, S("can't happen")); + test(S("abcdefghijklmnopqrst"), 21, 0, S("12345"), 0, 4, S("can't happen")); + test(S("abcdefghijklmnopqrst"), 21, 0, S("12345"), 0, 5, S("can't happen")); + test(S("abcdefghijklmnopqrst"), 21, 0, S("12345"), 0, 6, S("can't happen")); + test(S("abcdefghijklmnopqrst"), 21, 0, S("12345"), 1, 0, S("can't happen")); + test(S("abcdefghijklmnopqrst"), 21, 0, S("12345"), 1, 1, S("can't happen")); + test(S("abcdefghijklmnopqrst"), 21, 0, S("12345"), 1, 2, S("can't happen")); + test(S("abcdefghijklmnopqrst"), 21, 0, S("12345"), 1, 3, S("can't happen")); + test(S("abcdefghijklmnopqrst"), 21, 0, S("12345"), 1, 4, S("can't happen")); + test(S("abcdefghijklmnopqrst"), 21, 0, S("12345"), 1, 5, S("can't happen")); + test(S("abcdefghijklmnopqrst"), 21, 0, S("12345"), 2, 0, S("can't happen")); + test(S("abcdefghijklmnopqrst"), 21, 0, S("12345"), 2, 1, S("can't happen")); + test(S("abcdefghijklmnopqrst"), 21, 0, S("12345"), 2, 2, S("can't happen")); + test(S("abcdefghijklmnopqrst"), 21, 0, S("12345"), 2, 3, S("can't happen")); + test(S("abcdefghijklmnopqrst"), 21, 0, S("12345"), 2, 4, S("can't happen")); + test(S("abcdefghijklmnopqrst"), 21, 0, S("12345"), 4, 0, S("can't happen")); + test(S("abcdefghijklmnopqrst"), 21, 0, S("12345"), 4, 1, S("can't happen")); + test(S("abcdefghijklmnopqrst"), 21, 0, S("12345"), 4, 2, S("can't happen")); + test(S("abcdefghijklmnopqrst"), 21, 0, S("12345"), 5, 0, S("can't happen")); + test(S("abcdefghijklmnopqrst"), 21, 0, S("12345"), 5, 1, S("can't happen")); + test(S("abcdefghijklmnopqrst"), 21, 0, S("12345"), 6, 0, S("can't happen")); + test(S("abcdefghijklmnopqrst"), 21, 0, S("1234567890"), 0, 0, S("can't happen")); + test(S("abcdefghijklmnopqrst"), 21, 0, S("1234567890"), 0, 1, S("can't happen")); + test(S("abcdefghijklmnopqrst"), 21, 0, S("1234567890"), 0, 5, S("can't happen")); + test(S("abcdefghijklmnopqrst"), 21, 0, S("1234567890"), 0, 9, S("can't happen")); + test(S("abcdefghijklmnopqrst"), 21, 0, S("1234567890"), 0, 10, S("can't happen")); + test(S("abcdefghijklmnopqrst"), 21, 0, S("1234567890"), 0, 11, S("can't happen")); + test(S("abcdefghijklmnopqrst"), 21, 0, S("1234567890"), 1, 0, S("can't happen")); + test(S("abcdefghijklmnopqrst"), 21, 0, S("1234567890"), 1, 1, S("can't happen")); + test(S("abcdefghijklmnopqrst"), 21, 0, S("1234567890"), 1, 4, S("can't happen")); + test(S("abcdefghijklmnopqrst"), 21, 0, S("1234567890"), 1, 8, S("can't happen")); + test(S("abcdefghijklmnopqrst"), 21, 0, S("1234567890"), 1, 9, S("can't happen")); + test(S("abcdefghijklmnopqrst"), 21, 0, S("1234567890"), 1, 10, S("can't happen")); + test(S("abcdefghijklmnopqrst"), 21, 0, S("1234567890"), 5, 0, S("can't happen")); + test(S("abcdefghijklmnopqrst"), 21, 0, S("1234567890"), 5, 1, S("can't happen")); + test(S("abcdefghijklmnopqrst"), 21, 0, S("1234567890"), 5, 2, S("can't happen")); + test(S("abcdefghijklmnopqrst"), 21, 0, S("1234567890"), 5, 4, S("can't happen")); + test(S("abcdefghijklmnopqrst"), 21, 0, S("1234567890"), 5, 5, S("can't happen")); + test(S("abcdefghijklmnopqrst"), 21, 0, S("1234567890"), 5, 6, S("can't happen")); + test(S("abcdefghijklmnopqrst"), 21, 0, S("1234567890"), 9, 0, S("can't happen")); + test(S("abcdefghijklmnopqrst"), 21, 0, S("1234567890"), 9, 1, S("can't happen")); + test(S("abcdefghijklmnopqrst"), 21, 0, S("1234567890"), 9, 2, S("can't happen")); + test(S("abcdefghijklmnopqrst"), 21, 0, S("1234567890"), 10, 0, S("can't happen")); + test(S("abcdefghijklmnopqrst"), 21, 0, S("1234567890"), 10, 1, S("can't happen")); + test(S("abcdefghijklmnopqrst"), 21, 0, S("1234567890"), 11, 0, S("can't happen")); + test(S("abcdefghijklmnopqrst"), 21, 0, S("12345678901234567890"), 0, 0, S("can't happen")); + test(S("abcdefghijklmnopqrst"), 21, 0, S("12345678901234567890"), 0, 1, S("can't happen")); + test(S("abcdefghijklmnopqrst"), 21, 0, S("12345678901234567890"), 0, 10, S("can't happen")); + test(S("abcdefghijklmnopqrst"), 21, 0, S("12345678901234567890"), 0, 19, S("can't happen")); + test(S("abcdefghijklmnopqrst"), 21, 0, S("12345678901234567890"), 0, 20, S("can't happen")); + test(S("abcdefghijklmnopqrst"), 21, 0, S("12345678901234567890"), 0, 21, S("can't happen")); + test(S("abcdefghijklmnopqrst"), 21, 0, S("12345678901234567890"), 1, 0, S("can't happen")); + test(S("abcdefghijklmnopqrst"), 21, 0, S("12345678901234567890"), 1, 1, S("can't happen")); + test(S("abcdefghijklmnopqrst"), 21, 0, S("12345678901234567890"), 1, 9, S("can't happen")); + test(S("abcdefghijklmnopqrst"), 21, 0, S("12345678901234567890"), 1, 18, S("can't happen")); + test(S("abcdefghijklmnopqrst"), 21, 0, S("12345678901234567890"), 1, 19, S("can't happen")); + test(S("abcdefghijklmnopqrst"), 21, 0, S("12345678901234567890"), 1, 20, S("can't happen")); + test(S("abcdefghijklmnopqrst"), 21, 0, S("12345678901234567890"), 10, 0, S("can't happen")); + test(S("abcdefghijklmnopqrst"), 21, 0, S("12345678901234567890"), 10, 1, S("can't happen")); + test(S("abcdefghijklmnopqrst"), 21, 0, S("12345678901234567890"), 10, 5, S("can't happen")); + test(S("abcdefghijklmnopqrst"), 21, 0, S("12345678901234567890"), 10, 9, S("can't happen")); + test(S("abcdefghijklmnopqrst"), 21, 0, S("12345678901234567890"), 10, 10, S("can't happen")); + test(S("abcdefghijklmnopqrst"), 21, 0, S("12345678901234567890"), 10, 11, S("can't happen")); + test(S("abcdefghijklmnopqrst"), 21, 0, S("12345678901234567890"), 19, 0, S("can't happen")); + test(S("abcdefghijklmnopqrst"), 21, 0, S("12345678901234567890"), 19, 1, S("can't happen")); + test(S("abcdefghijklmnopqrst"), 21, 0, S("12345678901234567890"), 19, 2, S("can't happen")); + test(S("abcdefghijklmnopqrst"), 21, 0, S("12345678901234567890"), 20, 0, S("can't happen")); + test(S("abcdefghijklmnopqrst"), 21, 0, S("12345678901234567890"), 20, 1, S("can't happen")); + test(S("abcdefghijklmnopqrst"), 21, 0, S("12345678901234567890"), 21, 0, S("can't happen")); +} + +template +void test55() +{ + test_npos(S("abcdefghij"), 9, 1, S("12345678901234567890"), 10, S("abcdefghi1234567890")); + test_npos(S("abcdefghij"), 9, 1, S("12345678901234567890"), 19, S("abcdefghi0")); + test_npos(S("abcdefghij"), 9, 1, S("12345678901234567890"), 20, S("abcdefghi")); + test_npos(S("abcdefghij"), 9, 1, S("12345678901234567890"), 20, S("abcdefghi")); + test_npos(S("abcdefghij"), 9, 1, S("12345678901234567890"), 21, S("can't happen")); + test_npos(S("abcdefghij"), 9, 2, S(""), 0, S("abcdefghi")); + test_npos(S("abcdefghij"), 9, 2, S(""), 1, S("can't happen")); + test_npos(S("abcdefghij"), 9, 2, S("12345"), 0, S("abcdefghi12345")); + test_npos(S("abcdefghij"), 9, 2, S("12345"), 1, S("abcdefghi2345")); + test_npos(S("abcdefghij"), 9, 2, S("12345"), 2, S("abcdefghi345")); + test_npos(S("abcdefghij"), 9, 2, S("12345"), 4, S("abcdefghi5")); + test_npos(S("abcdefghij"), 9, 2, S("12345"), 5, S("abcdefghi")); + test_npos(S("abcdefghij"), 9, 2, S("12345"), 6, S("can't happen")); +} + +int main() +{ + { + typedef std::string S; + test0(); + test1(); + test2(); + test3(); + test4(); + test5(); + test6(); + test7(); + test8(); + test9(); + test10(); + test11(); + test12(); + test13(); + test14(); + test15(); + test16(); + test17(); + test18(); + test19(); + test20(); + test21(); + test22(); + test23(); + test24(); + test25(); + test26(); + test27(); + test28(); + test29(); + test30(); + test31(); + test32(); + test33(); + test34(); + test35(); + test36(); + test37(); + test38(); + test39(); + test40(); + test41(); + test42(); + test43(); + test44(); + test45(); + test46(); + test47(); + test48(); + test49(); + test50(); + test51(); + test52(); + test53(); + test54(); + test55(); + } +#if TEST_STD_VER >= 11 + { + typedef std::basic_string, min_allocator> S; + test0(); + test1(); + test2(); + test3(); + test4(); + test5(); + test6(); + test7(); + test8(); + test9(); + test10(); + test11(); + test12(); + test13(); + test14(); + test15(); + test16(); + test17(); + test18(); + test19(); + test20(); + test21(); + test22(); + test23(); + test24(); + test25(); + test26(); + test27(); + test28(); + test29(); + test30(); + test31(); + test32(); + test33(); + test34(); + test35(); + test36(); + test37(); + test38(); + test39(); + test40(); + test41(); + test42(); + test43(); + test44(); + test45(); + test46(); + test47(); + test48(); + test49(); + test50(); + test51(); + test52(); + test53(); + test54(); + test55(); + } +#endif +} diff --git a/tests/external/libcxx/basic_string/string.modifiers/string_replace/size_size_string_view.pass.cpp b/tests/external/libcxx/basic_string/string.modifiers/string_replace/size_size_string_view.pass.cpp new file mode 100644 index 0000000..60ecd67 --- /dev/null +++ b/tests/external/libcxx/basic_string/string.modifiers/string_replace/size_size_string_view.pass.cpp @@ -0,0 +1,384 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// + +// basic_string& +// replace(size_type pos1, size_type n1, basic_string_view sv); + +#include +#include +#include +#include + +#include "test_macros.h" +#include "min_allocator.h" + +template +void +test(S s, typename S::size_type pos1, typename S::size_type n1, SV sv, S expected) +{ + const typename S::size_type old_size = s.size(); + S s0 = s; + if (pos1 <= old_size) + { + s.replace(pos1, n1, sv); + LIBCPP_ASSERT(s.__invariants()); + assert(s == expected); + typename S::size_type xlen = std::min(n1, old_size - pos1); + typename S::size_type rlen = sv.size(); + assert(s.size() == old_size - xlen + rlen); + } +#ifndef TEST_HAS_NO_EXCEPTIONS + else + { + try + { + s.replace(pos1, n1, sv); + assert(false); + } + catch (std::out_of_range&) + { + assert(pos1 > old_size); + assert(s == s0); + } + } +#endif +} + +template +void test0() +{ + test(S(""), 0, 0, SV(""), S("")); + test(S(""), 0, 0, SV("12345"), S("12345")); + test(S(""), 0, 0, SV("1234567890"), S("1234567890")); + test(S(""), 0, 0, SV("12345678901234567890"), S("12345678901234567890")); + test(S(""), 0, 1, SV(""), S("")); + test(S(""), 0, 1, SV("12345"), S("12345")); + test(S(""), 0, 1, SV("1234567890"), S("1234567890")); + test(S(""), 0, 1, SV("12345678901234567890"), S("12345678901234567890")); + test(S(""), 1, 0, SV(""), S("can't happen")); + test(S(""), 1, 0, SV("12345"), S("can't happen")); + test(S(""), 1, 0, SV("1234567890"), S("can't happen")); + test(S(""), 1, 0, SV("12345678901234567890"), S("can't happen")); + test(S("abcde"), 0, 0, SV(""), S("abcde")); + test(S("abcde"), 0, 0, SV("12345"), S("12345abcde")); + test(S("abcde"), 0, 0, SV("1234567890"), S("1234567890abcde")); + test(S("abcde"), 0, 0, SV("12345678901234567890"), S("12345678901234567890abcde")); + test(S("abcde"), 0, 1, SV(""), S("bcde")); + test(S("abcde"), 0, 1, SV("12345"), S("12345bcde")); + test(S("abcde"), 0, 1, SV("1234567890"), S("1234567890bcde")); + test(S("abcde"), 0, 1, SV("12345678901234567890"), S("12345678901234567890bcde")); + test(S("abcde"), 0, 2, SV(""), S("cde")); + test(S("abcde"), 0, 2, SV("12345"), S("12345cde")); + test(S("abcde"), 0, 2, SV("1234567890"), S("1234567890cde")); + test(S("abcde"), 0, 2, SV("12345678901234567890"), S("12345678901234567890cde")); + test(S("abcde"), 0, 4, SV(""), S("e")); + test(S("abcde"), 0, 4, SV("12345"), S("12345e")); + test(S("abcde"), 0, 4, SV("1234567890"), S("1234567890e")); + test(S("abcde"), 0, 4, SV("12345678901234567890"), S("12345678901234567890e")); + test(S("abcde"), 0, 5, SV(""), S("")); + test(S("abcde"), 0, 5, SV("12345"), S("12345")); + test(S("abcde"), 0, 5, SV("1234567890"), S("1234567890")); + test(S("abcde"), 0, 5, SV("12345678901234567890"), S("12345678901234567890")); + test(S("abcde"), 0, 6, SV(""), S("")); + test(S("abcde"), 0, 6, SV("12345"), S("12345")); + test(S("abcde"), 0, 6, SV("1234567890"), S("1234567890")); + test(S("abcde"), 0, 6, SV("12345678901234567890"), S("12345678901234567890")); + test(S("abcde"), 1, 0, SV(""), S("abcde")); + test(S("abcde"), 1, 0, SV("12345"), S("a12345bcde")); + test(S("abcde"), 1, 0, SV("1234567890"), S("a1234567890bcde")); + test(S("abcde"), 1, 0, SV("12345678901234567890"), S("a12345678901234567890bcde")); + test(S("abcde"), 1, 1, SV(""), S("acde")); + test(S("abcde"), 1, 1, SV("12345"), S("a12345cde")); + test(S("abcde"), 1, 1, SV("1234567890"), S("a1234567890cde")); + test(S("abcde"), 1, 1, SV("12345678901234567890"), S("a12345678901234567890cde")); + test(S("abcde"), 1, 2, SV(""), S("ade")); + test(S("abcde"), 1, 2, SV("12345"), S("a12345de")); + test(S("abcde"), 1, 2, SV("1234567890"), S("a1234567890de")); + test(S("abcde"), 1, 2, SV("12345678901234567890"), S("a12345678901234567890de")); + test(S("abcde"), 1, 3, SV(""), S("ae")); + test(S("abcde"), 1, 3, SV("12345"), S("a12345e")); + test(S("abcde"), 1, 3, SV("1234567890"), S("a1234567890e")); + test(S("abcde"), 1, 3, SV("12345678901234567890"), S("a12345678901234567890e")); + test(S("abcde"), 1, 4, SV(""), S("a")); + test(S("abcde"), 1, 4, SV("12345"), S("a12345")); + test(S("abcde"), 1, 4, SV("1234567890"), S("a1234567890")); + test(S("abcde"), 1, 4, SV("12345678901234567890"), S("a12345678901234567890")); + test(S("abcde"), 1, 5, SV(""), S("a")); + test(S("abcde"), 1, 5, SV("12345"), S("a12345")); + test(S("abcde"), 1, 5, SV("1234567890"), S("a1234567890")); + test(S("abcde"), 1, 5, SV("12345678901234567890"), S("a12345678901234567890")); + test(S("abcde"), 2, 0, SV(""), S("abcde")); + test(S("abcde"), 2, 0, SV("12345"), S("ab12345cde")); + test(S("abcde"), 2, 0, SV("1234567890"), S("ab1234567890cde")); + test(S("abcde"), 2, 0, SV("12345678901234567890"), S("ab12345678901234567890cde")); + test(S("abcde"), 2, 1, SV(""), S("abde")); + test(S("abcde"), 2, 1, SV("12345"), S("ab12345de")); + test(S("abcde"), 2, 1, SV("1234567890"), S("ab1234567890de")); + test(S("abcde"), 2, 1, SV("12345678901234567890"), S("ab12345678901234567890de")); + test(S("abcde"), 2, 2, SV(""), S("abe")); + test(S("abcde"), 2, 2, SV("12345"), S("ab12345e")); + test(S("abcde"), 2, 2, SV("1234567890"), S("ab1234567890e")); + test(S("abcde"), 2, 2, SV("12345678901234567890"), S("ab12345678901234567890e")); + test(S("abcde"), 2, 3, SV(""), S("ab")); + test(S("abcde"), 2, 3, SV("12345"), S("ab12345")); + test(S("abcde"), 2, 3, SV("1234567890"), S("ab1234567890")); + test(S("abcde"), 2, 3, SV("12345678901234567890"), S("ab12345678901234567890")); + test(S("abcde"), 2, 4, SV(""), S("ab")); + test(S("abcde"), 2, 4, SV("12345"), S("ab12345")); + test(S("abcde"), 2, 4, SV("1234567890"), S("ab1234567890")); + test(S("abcde"), 2, 4, SV("12345678901234567890"), S("ab12345678901234567890")); + test(S("abcde"), 4, 0, SV(""), S("abcde")); + test(S("abcde"), 4, 0, SV("12345"), S("abcd12345e")); + test(S("abcde"), 4, 0, SV("1234567890"), S("abcd1234567890e")); + test(S("abcde"), 4, 0, SV("12345678901234567890"), S("abcd12345678901234567890e")); + test(S("abcde"), 4, 1, SV(""), S("abcd")); + test(S("abcde"), 4, 1, SV("12345"), S("abcd12345")); + test(S("abcde"), 4, 1, SV("1234567890"), S("abcd1234567890")); + test(S("abcde"), 4, 1, SV("12345678901234567890"), S("abcd12345678901234567890")); + test(S("abcde"), 4, 2, SV(""), S("abcd")); + test(S("abcde"), 4, 2, SV("12345"), S("abcd12345")); + test(S("abcde"), 4, 2, SV("1234567890"), S("abcd1234567890")); + test(S("abcde"), 4, 2, SV("12345678901234567890"), S("abcd12345678901234567890")); + test(S("abcde"), 5, 0, SV(""), S("abcde")); + test(S("abcde"), 5, 0, SV("12345"), S("abcde12345")); + test(S("abcde"), 5, 0, SV("1234567890"), S("abcde1234567890")); + test(S("abcde"), 5, 0, SV("12345678901234567890"), S("abcde12345678901234567890")); + test(S("abcde"), 5, 1, SV(""), S("abcde")); + test(S("abcde"), 5, 1, SV("12345"), S("abcde12345")); + test(S("abcde"), 5, 1, SV("1234567890"), S("abcde1234567890")); + test(S("abcde"), 5, 1, SV("12345678901234567890"), S("abcde12345678901234567890")); +} + +template +void test1() +{ + test(S("abcde"), 6, 0, SV(""), S("can't happen")); + test(S("abcde"), 6, 0, SV("12345"), S("can't happen")); + test(S("abcde"), 6, 0, SV("1234567890"), S("can't happen")); + test(S("abcde"), 6, 0, SV("12345678901234567890"), S("can't happen")); + test(S("abcdefghij"), 0, 0, SV(""), S("abcdefghij")); + test(S("abcdefghij"), 0, 0, SV("12345"), S("12345abcdefghij")); + test(S("abcdefghij"), 0, 0, SV("1234567890"), S("1234567890abcdefghij")); + test(S("abcdefghij"), 0, 0, SV("12345678901234567890"), S("12345678901234567890abcdefghij")); + test(S("abcdefghij"), 0, 1, SV(""), S("bcdefghij")); + test(S("abcdefghij"), 0, 1, SV("12345"), S("12345bcdefghij")); + test(S("abcdefghij"), 0, 1, SV("1234567890"), S("1234567890bcdefghij")); + test(S("abcdefghij"), 0, 1, SV("12345678901234567890"), S("12345678901234567890bcdefghij")); + test(S("abcdefghij"), 0, 5, SV(""), S("fghij")); + test(S("abcdefghij"), 0, 5, SV("12345"), S("12345fghij")); + test(S("abcdefghij"), 0, 5, SV("1234567890"), S("1234567890fghij")); + test(S("abcdefghij"), 0, 5, SV("12345678901234567890"), S("12345678901234567890fghij")); + test(S("abcdefghij"), 0, 9, SV(""), S("j")); + test(S("abcdefghij"), 0, 9, SV("12345"), S("12345j")); + test(S("abcdefghij"), 0, 9, SV("1234567890"), S("1234567890j")); + test(S("abcdefghij"), 0, 9, SV("12345678901234567890"), S("12345678901234567890j")); + test(S("abcdefghij"), 0, 10, SV(""), S("")); + test(S("abcdefghij"), 0, 10, SV("12345"), S("12345")); + test(S("abcdefghij"), 0, 10, SV("1234567890"), S("1234567890")); + test(S("abcdefghij"), 0, 10, SV("12345678901234567890"), S("12345678901234567890")); + test(S("abcdefghij"), 0, 11, SV(""), S("")); + test(S("abcdefghij"), 0, 11, SV("12345"), S("12345")); + test(S("abcdefghij"), 0, 11, SV("1234567890"), S("1234567890")); + test(S("abcdefghij"), 0, 11, SV("12345678901234567890"), S("12345678901234567890")); + test(S("abcdefghij"), 1, 0, SV(""), S("abcdefghij")); + test(S("abcdefghij"), 1, 0, SV("12345"), S("a12345bcdefghij")); + test(S("abcdefghij"), 1, 0, SV("1234567890"), S("a1234567890bcdefghij")); + test(S("abcdefghij"), 1, 0, SV("12345678901234567890"), S("a12345678901234567890bcdefghij")); + test(S("abcdefghij"), 1, 1, SV(""), S("acdefghij")); + test(S("abcdefghij"), 1, 1, SV("12345"), S("a12345cdefghij")); + test(S("abcdefghij"), 1, 1, SV("1234567890"), S("a1234567890cdefghij")); + test(S("abcdefghij"), 1, 1, SV("12345678901234567890"), S("a12345678901234567890cdefghij")); + test(S("abcdefghij"), 1, 4, SV(""), S("afghij")); + test(S("abcdefghij"), 1, 4, SV("12345"), S("a12345fghij")); + test(S("abcdefghij"), 1, 4, SV("1234567890"), S("a1234567890fghij")); + test(S("abcdefghij"), 1, 4, SV("12345678901234567890"), S("a12345678901234567890fghij")); + test(S("abcdefghij"), 1, 8, SV(""), S("aj")); + test(S("abcdefghij"), 1, 8, SV("12345"), S("a12345j")); + test(S("abcdefghij"), 1, 8, SV("1234567890"), S("a1234567890j")); + test(S("abcdefghij"), 1, 8, SV("12345678901234567890"), S("a12345678901234567890j")); + test(S("abcdefghij"), 1, 9, SV(""), S("a")); + test(S("abcdefghij"), 1, 9, SV("12345"), S("a12345")); + test(S("abcdefghij"), 1, 9, SV("1234567890"), S("a1234567890")); + test(S("abcdefghij"), 1, 9, SV("12345678901234567890"), S("a12345678901234567890")); + test(S("abcdefghij"), 1, 10, SV(""), S("a")); + test(S("abcdefghij"), 1, 10, SV("12345"), S("a12345")); + test(S("abcdefghij"), 1, 10, SV("1234567890"), S("a1234567890")); + test(S("abcdefghij"), 1, 10, SV("12345678901234567890"), S("a12345678901234567890")); + test(S("abcdefghij"), 5, 0, SV(""), S("abcdefghij")); + test(S("abcdefghij"), 5, 0, SV("12345"), S("abcde12345fghij")); + test(S("abcdefghij"), 5, 0, SV("1234567890"), S("abcde1234567890fghij")); + test(S("abcdefghij"), 5, 0, SV("12345678901234567890"), S("abcde12345678901234567890fghij")); + test(S("abcdefghij"), 5, 1, SV(""), S("abcdeghij")); + test(S("abcdefghij"), 5, 1, SV("12345"), S("abcde12345ghij")); + test(S("abcdefghij"), 5, 1, SV("1234567890"), S("abcde1234567890ghij")); + test(S("abcdefghij"), 5, 1, SV("12345678901234567890"), S("abcde12345678901234567890ghij")); + test(S("abcdefghij"), 5, 2, SV(""), S("abcdehij")); + test(S("abcdefghij"), 5, 2, SV("12345"), S("abcde12345hij")); + test(S("abcdefghij"), 5, 2, SV("1234567890"), S("abcde1234567890hij")); + test(S("abcdefghij"), 5, 2, SV("12345678901234567890"), S("abcde12345678901234567890hij")); + test(S("abcdefghij"), 5, 4, SV(""), S("abcdej")); + test(S("abcdefghij"), 5, 4, SV("12345"), S("abcde12345j")); + test(S("abcdefghij"), 5, 4, SV("1234567890"), S("abcde1234567890j")); + test(S("abcdefghij"), 5, 4, SV("12345678901234567890"), S("abcde12345678901234567890j")); + test(S("abcdefghij"), 5, 5, SV(""), S("abcde")); + test(S("abcdefghij"), 5, 5, SV("12345"), S("abcde12345")); + test(S("abcdefghij"), 5, 5, SV("1234567890"), S("abcde1234567890")); + test(S("abcdefghij"), 5, 5, SV("12345678901234567890"), S("abcde12345678901234567890")); + test(S("abcdefghij"), 5, 6, SV(""), S("abcde")); + test(S("abcdefghij"), 5, 6, SV("12345"), S("abcde12345")); + test(S("abcdefghij"), 5, 6, SV("1234567890"), S("abcde1234567890")); + test(S("abcdefghij"), 5, 6, SV("12345678901234567890"), S("abcde12345678901234567890")); + test(S("abcdefghij"), 9, 0, SV(""), S("abcdefghij")); + test(S("abcdefghij"), 9, 0, SV("12345"), S("abcdefghi12345j")); + test(S("abcdefghij"), 9, 0, SV("1234567890"), S("abcdefghi1234567890j")); + test(S("abcdefghij"), 9, 0, SV("12345678901234567890"), S("abcdefghi12345678901234567890j")); + test(S("abcdefghij"), 9, 1, SV(""), S("abcdefghi")); + test(S("abcdefghij"), 9, 1, SV("12345"), S("abcdefghi12345")); + test(S("abcdefghij"), 9, 1, SV("1234567890"), S("abcdefghi1234567890")); + test(S("abcdefghij"), 9, 1, SV("12345678901234567890"), S("abcdefghi12345678901234567890")); + test(S("abcdefghij"), 9, 2, SV(""), S("abcdefghi")); + test(S("abcdefghij"), 9, 2, SV("12345"), S("abcdefghi12345")); + test(S("abcdefghij"), 9, 2, SV("1234567890"), S("abcdefghi1234567890")); + test(S("abcdefghij"), 9, 2, SV("12345678901234567890"), S("abcdefghi12345678901234567890")); + test(S("abcdefghij"), 10, 0, SV(""), S("abcdefghij")); + test(S("abcdefghij"), 10, 0, SV("12345"), S("abcdefghij12345")); + test(S("abcdefghij"), 10, 0, SV("1234567890"), S("abcdefghij1234567890")); + test(S("abcdefghij"), 10, 0, SV("12345678901234567890"), S("abcdefghij12345678901234567890")); + test(S("abcdefghij"), 10, 1, SV(""), S("abcdefghij")); + test(S("abcdefghij"), 10, 1, SV("12345"), S("abcdefghij12345")); + test(S("abcdefghij"), 10, 1, SV("1234567890"), S("abcdefghij1234567890")); + test(S("abcdefghij"), 10, 1, SV("12345678901234567890"), S("abcdefghij12345678901234567890")); + test(S("abcdefghij"), 11, 0, SV(""), S("can't happen")); + test(S("abcdefghij"), 11, 0, SV("12345"), S("can't happen")); + test(S("abcdefghij"), 11, 0, SV("1234567890"), S("can't happen")); + test(S("abcdefghij"), 11, 0, SV("12345678901234567890"), S("can't happen")); +} + +template +void test2() +{ + test(S("abcdefghijklmnopqrst"), 0, 0, SV(""), S("abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, 0, SV("12345"), S("12345abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, 0, SV("1234567890"), S("1234567890abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, 0, SV("12345678901234567890"), S("12345678901234567890abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, 1, SV(""), S("bcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, 1, SV("12345"), S("12345bcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, 1, SV("1234567890"), S("1234567890bcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, 1, SV("12345678901234567890"), S("12345678901234567890bcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, 10, SV(""), S("klmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, 10, SV("12345"), S("12345klmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, 10, SV("1234567890"), S("1234567890klmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, 10, SV("12345678901234567890"), S("12345678901234567890klmnopqrst")); + test(S("abcdefghijklmnopqrst"), 0, 19, SV(""), S("t")); + test(S("abcdefghijklmnopqrst"), 0, 19, SV("12345"), S("12345t")); + test(S("abcdefghijklmnopqrst"), 0, 19, SV("1234567890"), S("1234567890t")); + test(S("abcdefghijklmnopqrst"), 0, 19, SV("12345678901234567890"), S("12345678901234567890t")); + test(S("abcdefghijklmnopqrst"), 0, 20, SV(""), S("")); + test(S("abcdefghijklmnopqrst"), 0, 20, SV("12345"), S("12345")); + test(S("abcdefghijklmnopqrst"), 0, 20, SV("1234567890"), S("1234567890")); + test(S("abcdefghijklmnopqrst"), 0, 20, SV("12345678901234567890"), S("12345678901234567890")); + test(S("abcdefghijklmnopqrst"), 0, 21, SV(""), S("")); + test(S("abcdefghijklmnopqrst"), 0, 21, SV("12345"), S("12345")); + test(S("abcdefghijklmnopqrst"), 0, 21, SV("1234567890"), S("1234567890")); + test(S("abcdefghijklmnopqrst"), 0, 21, SV("12345678901234567890"), S("12345678901234567890")); + test(S("abcdefghijklmnopqrst"), 1, 0, SV(""), S("abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, 0, SV("12345"), S("a12345bcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, 0, SV("1234567890"), S("a1234567890bcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, 0, SV("12345678901234567890"), S("a12345678901234567890bcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, 1, SV(""), S("acdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, 1, SV("12345"), S("a12345cdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, 1, SV("1234567890"), S("a1234567890cdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, 1, SV("12345678901234567890"), S("a12345678901234567890cdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, 9, SV(""), S("aklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, 9, SV("12345"), S("a12345klmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, 9, SV("1234567890"), S("a1234567890klmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, 9, SV("12345678901234567890"), S("a12345678901234567890klmnopqrst")); + test(S("abcdefghijklmnopqrst"), 1, 18, SV(""), S("at")); + test(S("abcdefghijklmnopqrst"), 1, 18, SV("12345"), S("a12345t")); + test(S("abcdefghijklmnopqrst"), 1, 18, SV("1234567890"), S("a1234567890t")); + test(S("abcdefghijklmnopqrst"), 1, 18, SV("12345678901234567890"), S("a12345678901234567890t")); + test(S("abcdefghijklmnopqrst"), 1, 19, SV(""), S("a")); + test(S("abcdefghijklmnopqrst"), 1, 19, SV("12345"), S("a12345")); + test(S("abcdefghijklmnopqrst"), 1, 19, SV("1234567890"), S("a1234567890")); + test(S("abcdefghijklmnopqrst"), 1, 19, SV("12345678901234567890"), S("a12345678901234567890")); + test(S("abcdefghijklmnopqrst"), 1, 20, SV(""), S("a")); + test(S("abcdefghijklmnopqrst"), 1, 20, SV("12345"), S("a12345")); + test(S("abcdefghijklmnopqrst"), 1, 20, SV("1234567890"), S("a1234567890")); + test(S("abcdefghijklmnopqrst"), 1, 20, SV("12345678901234567890"), S("a12345678901234567890")); + test(S("abcdefghijklmnopqrst"), 10, 0, SV(""), S("abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 10, 0, SV("12345"), S("abcdefghij12345klmnopqrst")); + test(S("abcdefghijklmnopqrst"), 10, 0, SV("1234567890"), S("abcdefghij1234567890klmnopqrst")); + test(S("abcdefghijklmnopqrst"), 10, 0, SV("12345678901234567890"), S("abcdefghij12345678901234567890klmnopqrst")); + test(S("abcdefghijklmnopqrst"), 10, 1, SV(""), S("abcdefghijlmnopqrst")); + test(S("abcdefghijklmnopqrst"), 10, 1, SV("12345"), S("abcdefghij12345lmnopqrst")); + test(S("abcdefghijklmnopqrst"), 10, 1, SV("1234567890"), S("abcdefghij1234567890lmnopqrst")); + test(S("abcdefghijklmnopqrst"), 10, 1, SV("12345678901234567890"), S("abcdefghij12345678901234567890lmnopqrst")); + test(S("abcdefghijklmnopqrst"), 10, 5, SV(""), S("abcdefghijpqrst")); + test(S("abcdefghijklmnopqrst"), 10, 5, SV("12345"), S("abcdefghij12345pqrst")); + test(S("abcdefghijklmnopqrst"), 10, 5, SV("1234567890"), S("abcdefghij1234567890pqrst")); + test(S("abcdefghijklmnopqrst"), 10, 5, SV("12345678901234567890"), S("abcdefghij12345678901234567890pqrst")); + test(S("abcdefghijklmnopqrst"), 10, 9, SV(""), S("abcdefghijt")); + test(S("abcdefghijklmnopqrst"), 10, 9, SV("12345"), S("abcdefghij12345t")); + test(S("abcdefghijklmnopqrst"), 10, 9, SV("1234567890"), S("abcdefghij1234567890t")); + test(S("abcdefghijklmnopqrst"), 10, 9, SV("12345678901234567890"), S("abcdefghij12345678901234567890t")); + test(S("abcdefghijklmnopqrst"), 10, 10, SV(""), S("abcdefghij")); + test(S("abcdefghijklmnopqrst"), 10, 10, SV("12345"), S("abcdefghij12345")); + test(S("abcdefghijklmnopqrst"), 10, 10, SV("1234567890"), S("abcdefghij1234567890")); + test(S("abcdefghijklmnopqrst"), 10, 10, SV("12345678901234567890"), S("abcdefghij12345678901234567890")); + test(S("abcdefghijklmnopqrst"), 10, 11, SV(""), S("abcdefghij")); + test(S("abcdefghijklmnopqrst"), 10, 11, SV("12345"), S("abcdefghij12345")); + test(S("abcdefghijklmnopqrst"), 10, 11, SV("1234567890"), S("abcdefghij1234567890")); + test(S("abcdefghijklmnopqrst"), 10, 11, SV("12345678901234567890"), S("abcdefghij12345678901234567890")); + test(S("abcdefghijklmnopqrst"), 19, 0, SV(""), S("abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 19, 0, SV("12345"), S("abcdefghijklmnopqrs12345t")); + test(S("abcdefghijklmnopqrst"), 19, 0, SV("1234567890"), S("abcdefghijklmnopqrs1234567890t")); + test(S("abcdefghijklmnopqrst"), 19, 0, SV("12345678901234567890"), S("abcdefghijklmnopqrs12345678901234567890t")); + test(S("abcdefghijklmnopqrst"), 19, 1, SV(""), S("abcdefghijklmnopqrs")); + test(S("abcdefghijklmnopqrst"), 19, 1, SV("12345"), S("abcdefghijklmnopqrs12345")); + test(S("abcdefghijklmnopqrst"), 19, 1, SV("1234567890"), S("abcdefghijklmnopqrs1234567890")); + test(S("abcdefghijklmnopqrst"), 19, 1, SV("12345678901234567890"), S("abcdefghijklmnopqrs12345678901234567890")); + test(S("abcdefghijklmnopqrst"), 19, 2, SV(""), S("abcdefghijklmnopqrs")); + test(S("abcdefghijklmnopqrst"), 19, 2, SV("12345"), S("abcdefghijklmnopqrs12345")); + test(S("abcdefghijklmnopqrst"), 19, 2, SV("1234567890"), S("abcdefghijklmnopqrs1234567890")); + test(S("abcdefghijklmnopqrst"), 19, 2, SV("12345678901234567890"), S("abcdefghijklmnopqrs12345678901234567890")); + test(S("abcdefghijklmnopqrst"), 20, 0, SV(""), S("abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 20, 0, SV("12345"), S("abcdefghijklmnopqrst12345")); + test(S("abcdefghijklmnopqrst"), 20, 0, SV("1234567890"), S("abcdefghijklmnopqrst1234567890")); + test(S("abcdefghijklmnopqrst"), 20, 0, SV("12345678901234567890"), S("abcdefghijklmnopqrst12345678901234567890")); + test(S("abcdefghijklmnopqrst"), 20, 1, SV(""), S("abcdefghijklmnopqrst")); + test(S("abcdefghijklmnopqrst"), 20, 1, SV("12345"), S("abcdefghijklmnopqrst12345")); + test(S("abcdefghijklmnopqrst"), 20, 1, SV("1234567890"), S("abcdefghijklmnopqrst1234567890")); + test(S("abcdefghijklmnopqrst"), 20, 1, SV("12345678901234567890"), S("abcdefghijklmnopqrst12345678901234567890")); + test(S("abcdefghijklmnopqrst"), 21, 0, SV(""), S("can't happen")); + test(S("abcdefghijklmnopqrst"), 21, 0, SV("12345"), S("can't happen")); + test(S("abcdefghijklmnopqrst"), 21, 0, SV("1234567890"), S("can't happen")); + test(S("abcdefghijklmnopqrst"), 21, 0, SV("12345678901234567890"), S("can't happen")); +} + +int main() +{ + { + typedef std::string S; + typedef std::string_view SV; + test0(); + test1(); + test2(); + } +#if TEST_STD_VER >= 11 + { + typedef std::basic_string, min_allocator> S; + typedef std::string_view SV; + test0(); + test1(); + test2(); + } +#endif +} diff --git a/tests/external/libcxx/basic_string/string.modifiers/string_swap/swap.pass.cpp b/tests/external/libcxx/basic_string/string.modifiers/string_swap/swap.pass.cpp new file mode 100644 index 0000000..fe2ee1f --- /dev/null +++ b/tests/external/libcxx/basic_string/string.modifiers/string_swap/swap.pass.cpp @@ -0,0 +1,77 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// + +// void swap(basic_string& s); + +#include +#include +#include +#include + +#include "test_macros.h" +#include "min_allocator.h" + +template +void +test(S s1, S s2) +{ + S s1_ = s1; + S s2_ = s2; + s1.swap(s2); + LIBCPP_ASSERT(s1.__invariants()); + LIBCPP_ASSERT(s2.__invariants()); + assert(s1 == s2_); + assert(s2 == s1_); +} + +int main() +{ + { + typedef std::string S; + test(S(""), S("")); + test(S(""), S("12345")); + test(S(""), S("1234567890")); + test(S(""), S("12345678901234567890")); + test(S("abcde"), S("")); + test(S("abcde"), S("12345")); + test(S("abcde"), S("1234567890")); + test(S("abcde"), S("12345678901234567890")); + test(S("abcdefghij"), S("")); + test(S("abcdefghij"), S("12345")); + test(S("abcdefghij"), S("1234567890")); + test(S("abcdefghij"), S("12345678901234567890")); + test(S("abcdefghijklmnopqrst"), S("")); + test(S("abcdefghijklmnopqrst"), S("12345")); + test(S("abcdefghijklmnopqrst"), S("1234567890")); + test(S("abcdefghijklmnopqrst"), S("12345678901234567890")); + } +#if TEST_STD_VER >= 11 + { + typedef std::basic_string, min_allocator> S; + test(S(""), S("")); + test(S(""), S("12345")); + test(S(""), S("1234567890")); + test(S(""), S("12345678901234567890")); + test(S("abcde"), S("")); + test(S("abcde"), S("12345")); + test(S("abcde"), S("1234567890")); + test(S("abcde"), S("12345678901234567890")); + test(S("abcdefghij"), S("")); + test(S("abcdefghij"), S("12345")); + test(S("abcdefghij"), S("1234567890")); + test(S("abcdefghij"), S("12345678901234567890")); + test(S("abcdefghijklmnopqrst"), S("")); + test(S("abcdefghijklmnopqrst"), S("12345")); + test(S("abcdefghijklmnopqrst"), S("1234567890")); + test(S("abcdefghijklmnopqrst"), S("12345678901234567890")); + } +#endif +} diff --git a/tests/external/libcxx/basic_string/string.nonmembers/string.io/get_line.pass.cpp b/tests/external/libcxx/basic_string/string.nonmembers/string.io/get_line.pass.cpp new file mode 100644 index 0000000..6011ea1 --- /dev/null +++ b/tests/external/libcxx/basic_string/string.nonmembers/string.io/get_line.pass.cpp @@ -0,0 +1,81 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// + +// template +// basic_istream& +// getline(basic_istream& is, +// basic_string& str); + +#include +#include +#include + +#include "min_allocator.h" + +int main() +{ + { + std::istringstream in(" abc\n def\n ghij"); + std::string s("initial text"); + getline(in, s); + assert(in.good()); + assert(s == " abc"); + getline(in, s); + assert(in.good()); + assert(s == " def"); + getline(in, s); + assert(in.eof()); + assert(s == " ghij"); + } + { + std::wistringstream in(L" abc\n def\n ghij"); + std::wstring s(L"initial text"); + getline(in, s); + assert(in.good()); + assert(s == L" abc"); + getline(in, s); + assert(in.good()); + assert(s == L" def"); + getline(in, s); + assert(in.eof()); + assert(s == L" ghij"); + } +#if TEST_STD_VER >= 11 + { + typedef std::basic_string, min_allocator> S; + std::istringstream in(" abc\n def\n ghij"); + S s("initial text"); + getline(in, s); + assert(in.good()); + assert(s == " abc"); + getline(in, s); + assert(in.good()); + assert(s == " def"); + getline(in, s); + assert(in.eof()); + assert(s == " ghij"); + } + { + typedef std::basic_string, min_allocator> S; + std::wistringstream in(L" abc\n def\n ghij"); + S s(L"initial text"); + getline(in, s); + assert(in.good()); + assert(s == L" abc"); + getline(in, s); + assert(in.good()); + assert(s == L" def"); + getline(in, s); + assert(in.eof()); + assert(s == L" ghij"); + } +#endif +} diff --git a/tests/external/libcxx/basic_string/string.nonmembers/string.io/get_line_delim.pass.cpp b/tests/external/libcxx/basic_string/string.nonmembers/string.io/get_line_delim.pass.cpp new file mode 100644 index 0000000..7985233 --- /dev/null +++ b/tests/external/libcxx/basic_string/string.nonmembers/string.io/get_line_delim.pass.cpp @@ -0,0 +1,93 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// + +// template +// basic_istream& +// getline(basic_istream& is, +// basic_string& str, charT delim); + +#include +#include +#include + +#include "min_allocator.h" + +int main() +{ + { + std::istringstream in(" abc* def** ghij"); + std::string s("initial text"); + getline(in, s, '*'); + assert(in.good()); + assert(s == " abc"); + getline(in, s, '*'); + assert(in.good()); + assert(s == " def"); + getline(in, s, '*'); + assert(in.good()); + assert(s == ""); + getline(in, s, '*'); + assert(in.eof()); + assert(s == " ghij"); + } + { + std::wistringstream in(L" abc* def** ghij"); + std::wstring s(L"initial text"); + getline(in, s, L'*'); + assert(in.good()); + assert(s == L" abc"); + getline(in, s, L'*'); + assert(in.good()); + assert(s == L" def"); + getline(in, s, L'*'); + assert(in.good()); + assert(s == L""); + getline(in, s, L'*'); + assert(in.eof()); + assert(s == L" ghij"); + } +#if TEST_STD_VER >= 11 + { + typedef std::basic_string, min_allocator> S; + std::istringstream in(" abc* def** ghij"); + S s("initial text"); + getline(in, s, '*'); + assert(in.good()); + assert(s == " abc"); + getline(in, s, '*'); + assert(in.good()); + assert(s == " def"); + getline(in, s, '*'); + assert(in.good()); + assert(s == ""); + getline(in, s, '*'); + assert(in.eof()); + assert(s == " ghij"); + } + { + typedef std::basic_string, min_allocator> S; + std::wistringstream in(L" abc* def** ghij"); + S s(L"initial text"); + getline(in, s, L'*'); + assert(in.good()); + assert(s == L" abc"); + getline(in, s, L'*'); + assert(in.good()); + assert(s == L" def"); + getline(in, s, L'*'); + assert(in.good()); + assert(s == L""); + getline(in, s, L'*'); + assert(in.eof()); + assert(s == L" ghij"); + } +#endif +} diff --git a/tests/external/libcxx/basic_string/string.nonmembers/string.io/get_line_delim_rv.pass.cpp b/tests/external/libcxx/basic_string/string.nonmembers/string.io/get_line_delim_rv.pass.cpp new file mode 100644 index 0000000..5dbfe9d --- /dev/null +++ b/tests/external/libcxx/basic_string/string.nonmembers/string.io/get_line_delim_rv.pass.cpp @@ -0,0 +1,49 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// UNSUPPORTED: c++98, c++03 + +// + +// template +// basic_istream& +// getline(basic_istream&& is, +// basic_string& str, charT delim); + +#include +#include +#include + +#include "min_allocator.h" + +int main() +{ + { + std::string s("initial text"); + getline(std::istringstream(" abc* def* ghij"), s, '*'); + assert(s == " abc"); + } + { + std::wstring s(L"initial text"); + getline(std::wistringstream(L" abc* def* ghij"), s, L'*'); + assert(s == L" abc"); + } + { + typedef std::basic_string, min_allocator> S; + S s("initial text"); + getline(std::istringstream(" abc* def* ghij"), s, '*'); + assert(s == " abc"); + } + { + typedef std::basic_string, min_allocator> S; + S s(L"initial text"); + getline(std::wistringstream(L" abc* def* ghij"), s, L'*'); + assert(s == L" abc"); + } +} diff --git a/tests/external/libcxx/basic_string/string.nonmembers/string.io/get_line_rv.pass.cpp b/tests/external/libcxx/basic_string/string.nonmembers/string.io/get_line_rv.pass.cpp new file mode 100644 index 0000000..0c1fa82 --- /dev/null +++ b/tests/external/libcxx/basic_string/string.nonmembers/string.io/get_line_rv.pass.cpp @@ -0,0 +1,49 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// UNSUPPORTED: c++98, c++03 + +// + +// template +// basic_istream& +// getline(basic_istream&& is, +// basic_string& str); + +#include +#include +#include + +#include "min_allocator.h" + +int main() +{ + { + std::string s("initial text"); + getline(std::istringstream(" abc\n def\n ghij"), s); + assert(s == " abc"); + } + { + std::wstring s(L"initial text"); + getline(std::wistringstream(L" abc\n def\n ghij"), s); + assert(s == L" abc"); + } + { + typedef std::basic_string, min_allocator> S; + S s("initial text"); + getline(std::istringstream(" abc\n def\n ghij"), s); + assert(s == " abc"); + } + { + typedef std::basic_string, min_allocator> S; + S s(L"initial text"); + getline(std::wistringstream(L" abc\n def\n ghij"), s); + assert(s == L" abc"); + } +} diff --git a/tests/external/libcxx/basic_string/string.nonmembers/string.io/stream_extract.pass.cpp b/tests/external/libcxx/basic_string/string.nonmembers/string.io/stream_extract.pass.cpp new file mode 100644 index 0000000..30e7dc6 --- /dev/null +++ b/tests/external/libcxx/basic_string/string.nonmembers/string.io/stream_extract.pass.cpp @@ -0,0 +1,117 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// + +// template +// basic_istream& +// operator>>(basic_istream& is, +// basic_string& str); + +#include +#include +#include + +#include "min_allocator.h" + +int main() +{ + { + std::istringstream in("a bc defghij"); + std::string s("initial text"); + in >> s; + assert(in.good()); + assert(s == "a"); + assert(in.peek() == ' '); + in >> s; + assert(in.good()); + assert(s == "bc"); + assert(in.peek() == ' '); + in.width(3); + in >> s; + assert(in.good()); + assert(s == "def"); + assert(in.peek() == 'g'); + in >> s; + assert(in.eof()); + assert(s == "ghij"); + in >> s; + assert(in.fail()); + } + { + std::wistringstream in(L"a bc defghij"); + std::wstring s(L"initial text"); + in >> s; + assert(in.good()); + assert(s == L"a"); + assert(in.peek() == L' '); + in >> s; + assert(in.good()); + assert(s == L"bc"); + assert(in.peek() == L' '); + in.width(3); + in >> s; + assert(in.good()); + assert(s == L"def"); + assert(in.peek() == L'g'); + in >> s; + assert(in.eof()); + assert(s == L"ghij"); + in >> s; + assert(in.fail()); + } +#if TEST_STD_VER >= 11 + { + typedef std::basic_string, min_allocator> S; + std::istringstream in("a bc defghij"); + S s("initial text"); + in >> s; + assert(in.good()); + assert(s == "a"); + assert(in.peek() == ' '); + in >> s; + assert(in.good()); + assert(s == "bc"); + assert(in.peek() == ' '); + in.width(3); + in >> s; + assert(in.good()); + assert(s == "def"); + assert(in.peek() == 'g'); + in >> s; + assert(in.eof()); + assert(s == "ghij"); + in >> s; + assert(in.fail()); + } + { + typedef std::basic_string, min_allocator> S; + std::wistringstream in(L"a bc defghij"); + S s(L"initial text"); + in >> s; + assert(in.good()); + assert(s == L"a"); + assert(in.peek() == L' '); + in >> s; + assert(in.good()); + assert(s == L"bc"); + assert(in.peek() == L' '); + in.width(3); + in >> s; + assert(in.good()); + assert(s == L"def"); + assert(in.peek() == L'g'); + in >> s; + assert(in.eof()); + assert(s == L"ghij"); + in >> s; + assert(in.fail()); + } +#endif +} diff --git a/tests/external/libcxx/basic_string/string.nonmembers/string.io/stream_insert.pass.cpp b/tests/external/libcxx/basic_string/string.nonmembers/string.io/stream_insert.pass.cpp new file mode 100644 index 0000000..6489ddf --- /dev/null +++ b/tests/external/libcxx/basic_string/string.nonmembers/string.io/stream_insert.pass.cpp @@ -0,0 +1,91 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// + +// template +// basic_ostream& +// operator<<(basic_ostream& os, +// const basic_string& str); + +#include +#include +#include + +#include "min_allocator.h" + +int main() +{ + { + std::ostringstream out; + std::string s("some text"); + out << s; + assert(out.good()); + assert(s == out.str()); + } + { + std::ostringstream out; + std::string s("some text"); + out.width(12); + out << s; + assert(out.good()); + assert(" " + s == out.str()); + } + { + std::wostringstream out; + std::wstring s(L"some text"); + out << s; + assert(out.good()); + assert(s == out.str()); + } + { + std::wostringstream out; + std::wstring s(L"some text"); + out.width(12); + out << s; + assert(out.good()); + assert(L" " + s == out.str()); + } +#if TEST_STD_VER >= 11 + { + typedef std::basic_string, min_allocator> S; + std::basic_ostringstream out; + S s("some text"); + out << s; + assert(out.good()); + assert(s == out.str()); + } + { + typedef std::basic_string, min_allocator> S; + std::basic_ostringstream out; + S s("some text"); + out.width(12); + out << s; + assert(out.good()); + assert(" " + s == out.str()); + } + { + typedef std::basic_string, min_allocator> S; + std::basic_ostringstream out; + S s(L"some text"); + out << s; + assert(out.good()); + assert(s == out.str()); + } + { + typedef std::basic_string, min_allocator> S; + std::basic_ostringstream out; + S s(L"some text"); + out.width(12); + out << s; + assert(out.good()); + assert(L" " + s == out.str()); + } +#endif +} diff --git a/tests/external/libcxx/basic_string/string.nonmembers/string.special/swap.pass.cpp b/tests/external/libcxx/basic_string/string.nonmembers/string.special/swap.pass.cpp new file mode 100644 index 0000000..a2e2519 --- /dev/null +++ b/tests/external/libcxx/basic_string/string.nonmembers/string.special/swap.pass.cpp @@ -0,0 +1,79 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// + +// template +// void swap(basic_string& lhs, +// basic_string& rhs); + +#include +#include +#include +#include + +#include "test_macros.h" +#include "min_allocator.h" + +template +void +test(S s1, S s2) +{ + S s1_ = s1; + S s2_ = s2; + swap(s1, s2); + LIBCPP_ASSERT(s1.__invariants()); + LIBCPP_ASSERT(s2.__invariants()); + assert(s1 == s2_); + assert(s2 == s1_); +} + +int main() +{ + { + typedef std::string S; + test(S(""), S("")); + test(S(""), S("12345")); + test(S(""), S("1234567890")); + test(S(""), S("12345678901234567890")); + test(S("abcde"), S("")); + test(S("abcde"), S("12345")); + test(S("abcde"), S("1234567890")); + test(S("abcde"), S("12345678901234567890")); + test(S("abcdefghij"), S("")); + test(S("abcdefghij"), S("12345")); + test(S("abcdefghij"), S("1234567890")); + test(S("abcdefghij"), S("12345678901234567890")); + test(S("abcdefghijklmnopqrst"), S("")); + test(S("abcdefghijklmnopqrst"), S("12345")); + test(S("abcdefghijklmnopqrst"), S("1234567890")); + test(S("abcdefghijklmnopqrst"), S("12345678901234567890")); + } +#if TEST_STD_VER >= 11 + { + typedef std::basic_string, min_allocator> S; + test(S(""), S("")); + test(S(""), S("12345")); + test(S(""), S("1234567890")); + test(S(""), S("12345678901234567890")); + test(S("abcde"), S("")); + test(S("abcde"), S("12345")); + test(S("abcde"), S("1234567890")); + test(S("abcde"), S("12345678901234567890")); + test(S("abcdefghij"), S("")); + test(S("abcdefghij"), S("12345")); + test(S("abcdefghij"), S("1234567890")); + test(S("abcdefghij"), S("12345678901234567890")); + test(S("abcdefghijklmnopqrst"), S("")); + test(S("abcdefghijklmnopqrst"), S("12345")); + test(S("abcdefghijklmnopqrst"), S("1234567890")); + test(S("abcdefghijklmnopqrst"), S("12345678901234567890")); + } +#endif +} diff --git a/tests/external/libcxx/basic_string/string.nonmembers/string.special/swap_noexcept.pass.cpp b/tests/external/libcxx/basic_string/string.nonmembers/string.special/swap_noexcept.pass.cpp new file mode 100644 index 0000000..c8b784c --- /dev/null +++ b/tests/external/libcxx/basic_string/string.nonmembers/string.special/swap_noexcept.pass.cpp @@ -0,0 +1,85 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// UNSUPPORTED: c++98, c++03 + +// + +// void swap(basic_string& c) +// noexcept(!allocator_type::propagate_on_container_swap::value || +// __is_nothrow_swappable::value); +// +// In C++17, the standard says that swap shall have: +// noexcept(allocator_traits::propagate_on_container_swap::value || +// allocator_traits::is_always_equal::value); + +// This tests a conforming extension + +#include +#include +#include + +#include "test_macros.h" +#include "test_allocator.h" + +template +struct some_alloc +{ + typedef T value_type; + + some_alloc() {} + some_alloc(const some_alloc&); + T *allocate(size_t); + void deallocate(void*, unsigned) {} + typedef std::true_type propagate_on_container_swap; +}; + +template +struct some_alloc2 +{ + typedef T value_type; + + some_alloc2() {} + some_alloc2(const some_alloc2&); + T *allocate(size_t); + void deallocate(void*, unsigned) {} + + typedef std::false_type propagate_on_container_swap; + typedef std::true_type is_always_equal; +}; + +int main() +{ + { + typedef std::string C; + static_assert(noexcept(swap(std::declval(), std::declval())), ""); + } +#if defined(_LIBCPP_VERSION) + { + typedef std::basic_string, test_allocator> C; + static_assert(noexcept(swap(std::declval(), std::declval())), ""); + } +#endif // _LIBCPP_VERSION + { + typedef std::basic_string, some_alloc> C; +#if TEST_STD_VER >= 14 + // In C++14, if POCS is set, swapping the allocator is required not to throw + static_assert( noexcept(swap(std::declval(), std::declval())), ""); +#else + static_assert(!noexcept(swap(std::declval(), std::declval())), ""); +#endif + } +#if TEST_STD_VER >= 14 + { + typedef std::basic_string, some_alloc2> C; + // if the allocators are always equal, then the swap can be noexcept + static_assert( noexcept(swap(std::declval(), std::declval())), ""); + } +#endif +} diff --git a/tests/external/libcxx/basic_string/string.nonmembers/string_op+/char_string.pass.cpp b/tests/external/libcxx/basic_string/string.nonmembers/string_op+/char_string.pass.cpp new file mode 100644 index 0000000..7bf7da8 --- /dev/null +++ b/tests/external/libcxx/basic_string/string.nonmembers/string_op+/char_string.pass.cpp @@ -0,0 +1,70 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// + +// template +// basic_string +// operator+(charT lhs, const basic_string& rhs); + +// template +// basic_string&& +// operator+(charT lhs, basic_string&& rhs); + +#include +#include +#include + +#include "test_macros.h" +#include "min_allocator.h" + +template +void test0(typename S::value_type lhs, const S& rhs, const S& x) { + assert(lhs + rhs == x); +} + +#if TEST_STD_VER >= 11 +template +void test1(typename S::value_type lhs, S&& rhs, const S& x) { + assert(lhs + move(rhs) == x); +} +#endif + +int main() { + { + typedef std::string S; + test0('a', S(""), S("a")); + test0('a', S("12345"), S("a12345")); + test0('a', S("1234567890"), S("a1234567890")); + test0('a', S("12345678901234567890"), S("a12345678901234567890")); + } +#if TEST_STD_VER >= 11 + { + typedef std::string S; + test1('a', S(""), S("a")); + test1('a', S("12345"), S("a12345")); + test1('a', S("1234567890"), S("a1234567890")); + test1('a', S("12345678901234567890"), S("a12345678901234567890")); + } + { + typedef std::basic_string, + min_allocator > + S; + test0('a', S(""), S("a")); + test0('a', S("12345"), S("a12345")); + test0('a', S("1234567890"), S("a1234567890")); + test0('a', S("12345678901234567890"), S("a12345678901234567890")); + + test1('a', S(""), S("a")); + test1('a', S("12345"), S("a12345")); + test1('a', S("1234567890"), S("a1234567890")); + test1('a', S("12345678901234567890"), S("a12345678901234567890")); + } +#endif +} diff --git a/tests/external/libcxx/basic_string/string.nonmembers/string_op+/pointer_string.pass.cpp b/tests/external/libcxx/basic_string/string.nonmembers/string_op+/pointer_string.pass.cpp new file mode 100644 index 0000000..090707f --- /dev/null +++ b/tests/external/libcxx/basic_string/string.nonmembers/string_op+/pointer_string.pass.cpp @@ -0,0 +1,131 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// + +// template +// basic_string +// operator+(const charT* lhs, const basic_string& rhs); + +// template +// basic_string&& +// operator+(const charT* lhs, basic_string&& rhs); + +#include +#include +#include + +#include "test_macros.h" +#include "min_allocator.h" + +template +void test0(const typename S::value_type* lhs, const S& rhs, const S& x) { + assert(lhs + rhs == x); +} + +#if TEST_STD_VER >= 11 +template +void test1(const typename S::value_type* lhs, S&& rhs, const S& x) { + assert(lhs + move(rhs) == x); +} +#endif + +int main() { + { + typedef std::string S; + test0("", S(""), S("")); + test0("", S("12345"), S("12345")); + test0("", S("1234567890"), S("1234567890")); + test0("", S("12345678901234567890"), S("12345678901234567890")); + test0("abcde", S(""), S("abcde")); + test0("abcde", S("12345"), S("abcde12345")); + test0("abcde", S("1234567890"), S("abcde1234567890")); + test0("abcde", S("12345678901234567890"), S("abcde12345678901234567890")); + test0("abcdefghij", S(""), S("abcdefghij")); + test0("abcdefghij", S("12345"), S("abcdefghij12345")); + test0("abcdefghij", S("1234567890"), S("abcdefghij1234567890")); + test0("abcdefghij", S("12345678901234567890"), + S("abcdefghij12345678901234567890")); + test0("abcdefghijklmnopqrst", S(""), S("abcdefghijklmnopqrst")); + test0("abcdefghijklmnopqrst", S("12345"), S("abcdefghijklmnopqrst12345")); + test0("abcdefghijklmnopqrst", S("1234567890"), + S("abcdefghijklmnopqrst1234567890")); + test0("abcdefghijklmnopqrst", S("12345678901234567890"), + S("abcdefghijklmnopqrst12345678901234567890")); + } + +#if TEST_STD_VER >= 11 + { + typedef std::string S; + test1("", S(""), S("")); + test1("", S("12345"), S("12345")); + test1("", S("1234567890"), S("1234567890")); + test1("", S("12345678901234567890"), S("12345678901234567890")); + test1("abcde", S(""), S("abcde")); + test1("abcde", S("12345"), S("abcde12345")); + test1("abcde", S("1234567890"), S("abcde1234567890")); + test1("abcde", S("12345678901234567890"), S("abcde12345678901234567890")); + test1("abcdefghij", S(""), S("abcdefghij")); + test1("abcdefghij", S("12345"), S("abcdefghij12345")); + test1("abcdefghij", S("1234567890"), S("abcdefghij1234567890")); + test1("abcdefghij", S("12345678901234567890"), + S("abcdefghij12345678901234567890")); + test1("abcdefghijklmnopqrst", S(""), S("abcdefghijklmnopqrst")); + test1("abcdefghijklmnopqrst", S("12345"), S("abcdefghijklmnopqrst12345")); + test1("abcdefghijklmnopqrst", S("1234567890"), + S("abcdefghijklmnopqrst1234567890")); + test1("abcdefghijklmnopqrst", S("12345678901234567890"), + S("abcdefghijklmnopqrst12345678901234567890")); + } + { + typedef std::basic_string, + min_allocator > + S; + test0("", S(""), S("")); + test0("", S("12345"), S("12345")); + test0("", S("1234567890"), S("1234567890")); + test0("", S("12345678901234567890"), S("12345678901234567890")); + test0("abcde", S(""), S("abcde")); + test0("abcde", S("12345"), S("abcde12345")); + test0("abcde", S("1234567890"), S("abcde1234567890")); + test0("abcde", S("12345678901234567890"), S("abcde12345678901234567890")); + test0("abcdefghij", S(""), S("abcdefghij")); + test0("abcdefghij", S("12345"), S("abcdefghij12345")); + test0("abcdefghij", S("1234567890"), S("abcdefghij1234567890")); + test0("abcdefghij", S("12345678901234567890"), + S("abcdefghij12345678901234567890")); + test0("abcdefghijklmnopqrst", S(""), S("abcdefghijklmnopqrst")); + test0("abcdefghijklmnopqrst", S("12345"), S("abcdefghijklmnopqrst12345")); + test0("abcdefghijklmnopqrst", S("1234567890"), + S("abcdefghijklmnopqrst1234567890")); + test0("abcdefghijklmnopqrst", S("12345678901234567890"), + S("abcdefghijklmnopqrst12345678901234567890")); + + test1("", S(""), S("")); + test1("", S("12345"), S("12345")); + test1("", S("1234567890"), S("1234567890")); + test1("", S("12345678901234567890"), S("12345678901234567890")); + test1("abcde", S(""), S("abcde")); + test1("abcde", S("12345"), S("abcde12345")); + test1("abcde", S("1234567890"), S("abcde1234567890")); + test1("abcde", S("12345678901234567890"), S("abcde12345678901234567890")); + test1("abcdefghij", S(""), S("abcdefghij")); + test1("abcdefghij", S("12345"), S("abcdefghij12345")); + test1("abcdefghij", S("1234567890"), S("abcdefghij1234567890")); + test1("abcdefghij", S("12345678901234567890"), + S("abcdefghij12345678901234567890")); + test1("abcdefghijklmnopqrst", S(""), S("abcdefghijklmnopqrst")); + test1("abcdefghijklmnopqrst", S("12345"), S("abcdefghijklmnopqrst12345")); + test1("abcdefghijklmnopqrst", S("1234567890"), + S("abcdefghijklmnopqrst1234567890")); + test1("abcdefghijklmnopqrst", S("12345678901234567890"), + S("abcdefghijklmnopqrst12345678901234567890")); + } +#endif +} diff --git a/tests/external/libcxx/basic_string/string.nonmembers/string_op+/string_char.pass.cpp b/tests/external/libcxx/basic_string/string.nonmembers/string_op+/string_char.pass.cpp new file mode 100644 index 0000000..9bc3a4d --- /dev/null +++ b/tests/external/libcxx/basic_string/string.nonmembers/string_op+/string_char.pass.cpp @@ -0,0 +1,70 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// + +// template +// basic_string +// operator+(const basic_string& lhs, charT rhs); + +// template +// basic_string&& +// operator+(basic_string&& lhs, charT rhs); + +#include +#include +#include + +#include "test_macros.h" +#include "min_allocator.h" + +template +void test0(const S& lhs, typename S::value_type rhs, const S& x) { + assert(lhs + rhs == x); +} + +#if TEST_STD_VER >= 11 +template +void test1(S&& lhs, typename S::value_type rhs, const S& x) { + assert(move(lhs) + rhs == x); +} +#endif + +int main() { + { + typedef std::string S; + test0(S(""), '1', S("1")); + test0(S("abcde"), '1', S("abcde1")); + test0(S("abcdefghij"), '1', S("abcdefghij1")); + test0(S("abcdefghijklmnopqrst"), '1', S("abcdefghijklmnopqrst1")); + } +#if TEST_STD_VER >= 11 + { + typedef std::string S; + test1(S(""), '1', S("1")); + test1(S("abcde"), '1', S("abcde1")); + test1(S("abcdefghij"), '1', S("abcdefghij1")); + test1(S("abcdefghijklmnopqrst"), '1', S("abcdefghijklmnopqrst1")); + } + { + typedef std::basic_string, + min_allocator > + S; + test0(S(""), '1', S("1")); + test0(S("abcde"), '1', S("abcde1")); + test0(S("abcdefghij"), '1', S("abcdefghij1")); + test0(S("abcdefghijklmnopqrst"), '1', S("abcdefghijklmnopqrst1")); + + test1(S(""), '1', S("1")); + test1(S("abcde"), '1', S("abcde1")); + test1(S("abcdefghij"), '1', S("abcdefghij1")); + test1(S("abcdefghijklmnopqrst"), '1', S("abcdefghijklmnopqrst1")); + } +#endif +} diff --git a/tests/external/libcxx/basic_string/string.nonmembers/string_op+/string_pointer.pass.cpp b/tests/external/libcxx/basic_string/string.nonmembers/string_op+/string_pointer.pass.cpp new file mode 100644 index 0000000..a9aa92f --- /dev/null +++ b/tests/external/libcxx/basic_string/string.nonmembers/string_op+/string_pointer.pass.cpp @@ -0,0 +1,130 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// + +// template +// basic_string +// operator+(const basic_string& lhs, const charT* rhs); + +// template +// basic_string&& +// operator+(basic_string&& lhs, const charT* rhs); + +#include +#include +#include + +#include "test_macros.h" +#include "min_allocator.h" + +template +void test0(const S& lhs, const typename S::value_type* rhs, const S& x) { + assert(lhs + rhs == x); +} + +#if TEST_STD_VER >= 11 +template +void test1(S&& lhs, const typename S::value_type* rhs, const S& x) { + assert(move(lhs) + rhs == x); +} +#endif + +int main() { + { + typedef std::string S; + test0(S(""), "", S("")); + test0(S(""), "12345", S("12345")); + test0(S(""), "1234567890", S("1234567890")); + test0(S(""), "12345678901234567890", S("12345678901234567890")); + test0(S("abcde"), "", S("abcde")); + test0(S("abcde"), "12345", S("abcde12345")); + test0(S("abcde"), "1234567890", S("abcde1234567890")); + test0(S("abcde"), "12345678901234567890", S("abcde12345678901234567890")); + test0(S("abcdefghij"), "", S("abcdefghij")); + test0(S("abcdefghij"), "12345", S("abcdefghij12345")); + test0(S("abcdefghij"), "1234567890", S("abcdefghij1234567890")); + test0(S("abcdefghij"), "12345678901234567890", + S("abcdefghij12345678901234567890")); + test0(S("abcdefghijklmnopqrst"), "", S("abcdefghijklmnopqrst")); + test0(S("abcdefghijklmnopqrst"), "12345", S("abcdefghijklmnopqrst12345")); + test0(S("abcdefghijklmnopqrst"), "1234567890", + S("abcdefghijklmnopqrst1234567890")); + test0(S("abcdefghijklmnopqrst"), "12345678901234567890", + S("abcdefghijklmnopqrst12345678901234567890")); + } +#if TEST_STD_VER >= 11 + { + typedef std::string S; + test1(S(""), "", S("")); + test1(S(""), "12345", S("12345")); + test1(S(""), "1234567890", S("1234567890")); + test1(S(""), "12345678901234567890", S("12345678901234567890")); + test1(S("abcde"), "", S("abcde")); + test1(S("abcde"), "12345", S("abcde12345")); + test1(S("abcde"), "1234567890", S("abcde1234567890")); + test1(S("abcde"), "12345678901234567890", S("abcde12345678901234567890")); + test1(S("abcdefghij"), "", S("abcdefghij")); + test1(S("abcdefghij"), "12345", S("abcdefghij12345")); + test1(S("abcdefghij"), "1234567890", S("abcdefghij1234567890")); + test1(S("abcdefghij"), "12345678901234567890", + S("abcdefghij12345678901234567890")); + test1(S("abcdefghijklmnopqrst"), "", S("abcdefghijklmnopqrst")); + test1(S("abcdefghijklmnopqrst"), "12345", S("abcdefghijklmnopqrst12345")); + test1(S("abcdefghijklmnopqrst"), "1234567890", + S("abcdefghijklmnopqrst1234567890")); + test1(S("abcdefghijklmnopqrst"), "12345678901234567890", + S("abcdefghijklmnopqrst12345678901234567890")); + } + { + typedef std::basic_string, + min_allocator > + S; + test0(S(""), "", S("")); + test0(S(""), "12345", S("12345")); + test0(S(""), "1234567890", S("1234567890")); + test0(S(""), "12345678901234567890", S("12345678901234567890")); + test0(S("abcde"), "", S("abcde")); + test0(S("abcde"), "12345", S("abcde12345")); + test0(S("abcde"), "1234567890", S("abcde1234567890")); + test0(S("abcde"), "12345678901234567890", S("abcde12345678901234567890")); + test0(S("abcdefghij"), "", S("abcdefghij")); + test0(S("abcdefghij"), "12345", S("abcdefghij12345")); + test0(S("abcdefghij"), "1234567890", S("abcdefghij1234567890")); + test0(S("abcdefghij"), "12345678901234567890", + S("abcdefghij12345678901234567890")); + test0(S("abcdefghijklmnopqrst"), "", S("abcdefghijklmnopqrst")); + test0(S("abcdefghijklmnopqrst"), "12345", S("abcdefghijklmnopqrst12345")); + test0(S("abcdefghijklmnopqrst"), "1234567890", + S("abcdefghijklmnopqrst1234567890")); + test0(S("abcdefghijklmnopqrst"), "12345678901234567890", + S("abcdefghijklmnopqrst12345678901234567890")); + + test1(S(""), "", S("")); + test1(S(""), "12345", S("12345")); + test1(S(""), "1234567890", S("1234567890")); + test1(S(""), "12345678901234567890", S("12345678901234567890")); + test1(S("abcde"), "", S("abcde")); + test1(S("abcde"), "12345", S("abcde12345")); + test1(S("abcde"), "1234567890", S("abcde1234567890")); + test1(S("abcde"), "12345678901234567890", S("abcde12345678901234567890")); + test1(S("abcdefghij"), "", S("abcdefghij")); + test1(S("abcdefghij"), "12345", S("abcdefghij12345")); + test1(S("abcdefghij"), "1234567890", S("abcdefghij1234567890")); + test1(S("abcdefghij"), "12345678901234567890", + S("abcdefghij12345678901234567890")); + test1(S("abcdefghijklmnopqrst"), "", S("abcdefghijklmnopqrst")); + test1(S("abcdefghijklmnopqrst"), "12345", S("abcdefghijklmnopqrst12345")); + test1(S("abcdefghijklmnopqrst"), "1234567890", + S("abcdefghijklmnopqrst1234567890")); + test1(S("abcdefghijklmnopqrst"), "12345678901234567890", + S("abcdefghijklmnopqrst12345678901234567890")); + } +#endif +} diff --git a/tests/external/libcxx/basic_string/string.nonmembers/string_op+/string_string.pass.cpp b/tests/external/libcxx/basic_string/string.nonmembers/string_op+/string_string.pass.cpp new file mode 100644 index 0000000..fbef646 --- /dev/null +++ b/tests/external/libcxx/basic_string/string.nonmembers/string_op+/string_string.pass.cpp @@ -0,0 +1,249 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// + +// template +// basic_string +// operator+(const basic_string& lhs, +// const basic_string& rhs); + +// template +// basic_string&& +// operator+(const basic_string&& lhs, +// const basic_string& rhs); + +// template +// basic_string&& +// operator+(const basic_string& lhs, +// const basic_string&& rhs); + +// template +// basic_string&& +// operator+(const basic_string&& lhs, +// const basic_string&& rhs); + +#include +#include +#include + +#include "test_macros.h" +#include "min_allocator.h" + +template +void test0(const S& lhs, const S& rhs, const S& x) { + assert(lhs + rhs == x); +} + +#if TEST_STD_VER >= 11 +template +void test1(S&& lhs, const S& rhs, const S& x) { + assert(move(lhs) + rhs == x); +} + +template +void test2(const S& lhs, S&& rhs, const S& x) { + assert(lhs + move(rhs) == x); +} + +template +void test3(S&& lhs, S&& rhs, const S& x) { + assert(move(lhs) + move(rhs) == x); +} + +#endif + +int main() { + { + typedef std::string S; + test0(S(""), S(""), S("")); + test0(S(""), S("12345"), S("12345")); + test0(S(""), S("1234567890"), S("1234567890")); + test0(S(""), S("12345678901234567890"), S("12345678901234567890")); + test0(S("abcde"), S(""), S("abcde")); + test0(S("abcde"), S("12345"), S("abcde12345")); + test0(S("abcde"), S("1234567890"), S("abcde1234567890")); + test0(S("abcde"), S("12345678901234567890"), + S("abcde12345678901234567890")); + test0(S("abcdefghij"), S(""), S("abcdefghij")); + test0(S("abcdefghij"), S("12345"), S("abcdefghij12345")); + test0(S("abcdefghij"), S("1234567890"), S("abcdefghij1234567890")); + test0(S("abcdefghij"), S("12345678901234567890"), + S("abcdefghij12345678901234567890")); + test0(S("abcdefghijklmnopqrst"), S(""), S("abcdefghijklmnopqrst")); + test0(S("abcdefghijklmnopqrst"), S("12345"), + S("abcdefghijklmnopqrst12345")); + test0(S("abcdefghijklmnopqrst"), S("1234567890"), + S("abcdefghijklmnopqrst1234567890")); + test0(S("abcdefghijklmnopqrst"), S("12345678901234567890"), + S("abcdefghijklmnopqrst12345678901234567890")); + } +#if TEST_STD_VER >= 11 + { + typedef std::string S; + test1(S(""), S(""), S("")); + test1(S(""), S("12345"), S("12345")); + test1(S(""), S("1234567890"), S("1234567890")); + test1(S(""), S("12345678901234567890"), S("12345678901234567890")); + test1(S("abcde"), S(""), S("abcde")); + test1(S("abcde"), S("12345"), S("abcde12345")); + test1(S("abcde"), S("1234567890"), S("abcde1234567890")); + test1(S("abcde"), S("12345678901234567890"), + S("abcde12345678901234567890")); + test1(S("abcdefghij"), S(""), S("abcdefghij")); + test1(S("abcdefghij"), S("12345"), S("abcdefghij12345")); + test1(S("abcdefghij"), S("1234567890"), S("abcdefghij1234567890")); + test1(S("abcdefghij"), S("12345678901234567890"), + S("abcdefghij12345678901234567890")); + test1(S("abcdefghijklmnopqrst"), S(""), S("abcdefghijklmnopqrst")); + test1(S("abcdefghijklmnopqrst"), S("12345"), + S("abcdefghijklmnopqrst12345")); + test1(S("abcdefghijklmnopqrst"), S("1234567890"), + S("abcdefghijklmnopqrst1234567890")); + test1(S("abcdefghijklmnopqrst"), S("12345678901234567890"), + S("abcdefghijklmnopqrst12345678901234567890")); + + test2(S(""), S(""), S("")); + test2(S(""), S("12345"), S("12345")); + test2(S(""), S("1234567890"), S("1234567890")); + test2(S(""), S("12345678901234567890"), S("12345678901234567890")); + test2(S("abcde"), S(""), S("abcde")); + test2(S("abcde"), S("12345"), S("abcde12345")); + test2(S("abcde"), S("1234567890"), S("abcde1234567890")); + test2(S("abcde"), S("12345678901234567890"), + S("abcde12345678901234567890")); + test2(S("abcdefghij"), S(""), S("abcdefghij")); + test2(S("abcdefghij"), S("12345"), S("abcdefghij12345")); + test2(S("abcdefghij"), S("1234567890"), S("abcdefghij1234567890")); + test2(S("abcdefghij"), S("12345678901234567890"), + S("abcdefghij12345678901234567890")); + test2(S("abcdefghijklmnopqrst"), S(""), S("abcdefghijklmnopqrst")); + test2(S("abcdefghijklmnopqrst"), S("12345"), + S("abcdefghijklmnopqrst12345")); + test2(S("abcdefghijklmnopqrst"), S("1234567890"), + S("abcdefghijklmnopqrst1234567890")); + test2(S("abcdefghijklmnopqrst"), S("12345678901234567890"), + S("abcdefghijklmnopqrst12345678901234567890")); + + test3(S(""), S(""), S("")); + test3(S(""), S("12345"), S("12345")); + test3(S(""), S("1234567890"), S("1234567890")); + test3(S(""), S("12345678901234567890"), S("12345678901234567890")); + test3(S("abcde"), S(""), S("abcde")); + test3(S("abcde"), S("12345"), S("abcde12345")); + test3(S("abcde"), S("1234567890"), S("abcde1234567890")); + test3(S("abcde"), S("12345678901234567890"), + S("abcde12345678901234567890")); + test3(S("abcdefghij"), S(""), S("abcdefghij")); + test3(S("abcdefghij"), S("12345"), S("abcdefghij12345")); + test3(S("abcdefghij"), S("1234567890"), S("abcdefghij1234567890")); + test3(S("abcdefghij"), S("12345678901234567890"), + S("abcdefghij12345678901234567890")); + test3(S("abcdefghijklmnopqrst"), S(""), S("abcdefghijklmnopqrst")); + test3(S("abcdefghijklmnopqrst"), S("12345"), + S("abcdefghijklmnopqrst12345")); + test3(S("abcdefghijklmnopqrst"), S("1234567890"), + S("abcdefghijklmnopqrst1234567890")); + test3(S("abcdefghijklmnopqrst"), S("12345678901234567890"), + S("abcdefghijklmnopqrst12345678901234567890")); + } + { + typedef std::basic_string, + min_allocator > + S; + test0(S(""), S(""), S("")); + test0(S(""), S("12345"), S("12345")); + test0(S(""), S("1234567890"), S("1234567890")); + test0(S(""), S("12345678901234567890"), S("12345678901234567890")); + test0(S("abcde"), S(""), S("abcde")); + test0(S("abcde"), S("12345"), S("abcde12345")); + test0(S("abcde"), S("1234567890"), S("abcde1234567890")); + test0(S("abcde"), S("12345678901234567890"), + S("abcde12345678901234567890")); + test0(S("abcdefghij"), S(""), S("abcdefghij")); + test0(S("abcdefghij"), S("12345"), S("abcdefghij12345")); + test0(S("abcdefghij"), S("1234567890"), S("abcdefghij1234567890")); + test0(S("abcdefghij"), S("12345678901234567890"), + S("abcdefghij12345678901234567890")); + test0(S("abcdefghijklmnopqrst"), S(""), S("abcdefghijklmnopqrst")); + test0(S("abcdefghijklmnopqrst"), S("12345"), + S("abcdefghijklmnopqrst12345")); + test0(S("abcdefghijklmnopqrst"), S("1234567890"), + S("abcdefghijklmnopqrst1234567890")); + test0(S("abcdefghijklmnopqrst"), S("12345678901234567890"), + S("abcdefghijklmnopqrst12345678901234567890")); + + test1(S(""), S(""), S("")); + test1(S(""), S("12345"), S("12345")); + test1(S(""), S("1234567890"), S("1234567890")); + test1(S(""), S("12345678901234567890"), S("12345678901234567890")); + test1(S("abcde"), S(""), S("abcde")); + test1(S("abcde"), S("12345"), S("abcde12345")); + test1(S("abcde"), S("1234567890"), S("abcde1234567890")); + test1(S("abcde"), S("12345678901234567890"), + S("abcde12345678901234567890")); + test1(S("abcdefghij"), S(""), S("abcdefghij")); + test1(S("abcdefghij"), S("12345"), S("abcdefghij12345")); + test1(S("abcdefghij"), S("1234567890"), S("abcdefghij1234567890")); + test1(S("abcdefghij"), S("12345678901234567890"), + S("abcdefghij12345678901234567890")); + test1(S("abcdefghijklmnopqrst"), S(""), S("abcdefghijklmnopqrst")); + test1(S("abcdefghijklmnopqrst"), S("12345"), + S("abcdefghijklmnopqrst12345")); + test1(S("abcdefghijklmnopqrst"), S("1234567890"), + S("abcdefghijklmnopqrst1234567890")); + test1(S("abcdefghijklmnopqrst"), S("12345678901234567890"), + S("abcdefghijklmnopqrst12345678901234567890")); + + test2(S(""), S(""), S("")); + test2(S(""), S("12345"), S("12345")); + test2(S(""), S("1234567890"), S("1234567890")); + test2(S(""), S("12345678901234567890"), S("12345678901234567890")); + test2(S("abcde"), S(""), S("abcde")); + test2(S("abcde"), S("12345"), S("abcde12345")); + test2(S("abcde"), S("1234567890"), S("abcde1234567890")); + test2(S("abcde"), S("12345678901234567890"), + S("abcde12345678901234567890")); + test2(S("abcdefghij"), S(""), S("abcdefghij")); + test2(S("abcdefghij"), S("12345"), S("abcdefghij12345")); + test2(S("abcdefghij"), S("1234567890"), S("abcdefghij1234567890")); + test2(S("abcdefghij"), S("12345678901234567890"), + S("abcdefghij12345678901234567890")); + test2(S("abcdefghijklmnopqrst"), S(""), S("abcdefghijklmnopqrst")); + test2(S("abcdefghijklmnopqrst"), S("12345"), + S("abcdefghijklmnopqrst12345")); + test2(S("abcdefghijklmnopqrst"), S("1234567890"), + S("abcdefghijklmnopqrst1234567890")); + test2(S("abcdefghijklmnopqrst"), S("12345678901234567890"), + S("abcdefghijklmnopqrst12345678901234567890")); + + test3(S(""), S(""), S("")); + test3(S(""), S("12345"), S("12345")); + test3(S(""), S("1234567890"), S("1234567890")); + test3(S(""), S("12345678901234567890"), S("12345678901234567890")); + test3(S("abcde"), S(""), S("abcde")); + test3(S("abcde"), S("12345"), S("abcde12345")); + test3(S("abcde"), S("1234567890"), S("abcde1234567890")); + test3(S("abcde"), S("12345678901234567890"), + S("abcde12345678901234567890")); + test3(S("abcdefghij"), S(""), S("abcdefghij")); + test3(S("abcdefghij"), S("12345"), S("abcdefghij12345")); + test3(S("abcdefghij"), S("1234567890"), S("abcdefghij1234567890")); + test3(S("abcdefghij"), S("12345678901234567890"), + S("abcdefghij12345678901234567890")); + test3(S("abcdefghijklmnopqrst"), S(""), S("abcdefghijklmnopqrst")); + test3(S("abcdefghijklmnopqrst"), S("12345"), + S("abcdefghijklmnopqrst12345")); + test3(S("abcdefghijklmnopqrst"), S("1234567890"), + S("abcdefghijklmnopqrst1234567890")); + test3(S("abcdefghijklmnopqrst"), S("12345678901234567890"), + S("abcdefghijklmnopqrst12345678901234567890")); + } +#endif // TEST_STD_VER >= 11 +} diff --git a/tests/external/libcxx/basic_string/string.nonmembers/string_opeq/pointer_string.pass.cpp b/tests/external/libcxx/basic_string/string.nonmembers/string_opeq/pointer_string.pass.cpp new file mode 100644 index 0000000..31db2e1 --- /dev/null +++ b/tests/external/libcxx/basic_string/string.nonmembers/string_opeq/pointer_string.pass.cpp @@ -0,0 +1,106 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// Copyright 2019, Intel Corporation +// +// Modified to test pmem::obj containers +// + +#include "unittest.hpp" + +#include +#include +#include +#include +#include + +namespace pmem_exp = pmem::obj::experimental; +namespace nvobj = pmem::obj; + +struct root { + nvobj::persistent_ptr s1, s2, s3, s4; +}; + +template +void +test(const typename S::value_type *lhs, const S &rhs, bool x) +{ + UT_ASSERT((lhs == rhs) == x); +} + +void +run(pmem::obj::pool &pop) +{ + auto r = pop.root(); + + try { + nvobj::transaction::run(pop, [&] { + r->s1 = nvobj::make_persistent(""); + r->s2 = nvobj::make_persistent( + "abcde"); + r->s3 = nvobj::make_persistent( + "abcdefghij"); + r->s4 = nvobj::make_persistent( + "abcdefghijklmnopqrst"); + }); + + test("", *r->s1, true); + test("", *r->s2, false); + test("", *r->s3, false); + test("", *r->s4, false); + test("abcde", *r->s1, false); + test("abcde", *r->s2, true); + test("abcde", *r->s3, false); + test("abcde", *r->s4, false); + test("abcdefghij", *r->s1, false); + test("abcdefghij", *r->s2, false); + test("abcdefghij", *r->s3, true); + test("abcdefghij", *r->s4, false); + test("abcdefghijklmnopqrst", *r->s1, false); + test("abcdefghijklmnopqrst", *r->s2, false); + test("abcdefghijklmnopqrst", *r->s3, false); + test("abcdefghijklmnopqrst", *r->s4, true); + + nvobj::transaction::run(pop, [&] { + nvobj::delete_persistent(r->s1); + nvobj::delete_persistent(r->s2); + nvobj::delete_persistent(r->s3); + nvobj::delete_persistent(r->s4); + }); + } catch (std::exception &e) { + UT_FATALexc(e); + } +} + +int +main(int argc, char *argv[]) +{ + START(); + + if (argc != 2) + UT_FATAL("usage: %s file-name", argv[0]); + + const char *path = argv[1]; + + pmem::obj::pool pop; + + try { + pop = pmem::obj::pool::create(path, "basic_string", + PMEMOBJ_MIN_POOL, + S_IWUSR | S_IRUSR); + } catch (...) { + UT_FATAL("!pmemobj_create: %s", path); + } + + run(pop); + + pop.close(); + + return 0; +} diff --git a/tests/external/libcxx/basic_string/string.nonmembers/string_opeq/string_pointer.pass.cpp b/tests/external/libcxx/basic_string/string.nonmembers/string_opeq/string_pointer.pass.cpp new file mode 100644 index 0000000..ec9754a --- /dev/null +++ b/tests/external/libcxx/basic_string/string.nonmembers/string_opeq/string_pointer.pass.cpp @@ -0,0 +1,106 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// Copyright 2019, Intel Corporation +// +// Modified to test pmem::obj containers +// + +#include "unittest.hpp" + +#include +#include +#include +#include +#include + +namespace pmem_exp = pmem::obj::experimental; +namespace nvobj = pmem::obj; + +struct root { + nvobj::persistent_ptr s1, s2, s3, s4; +}; + +template +void +test(const S &lhs, const typename S::value_type *rhs, bool x) +{ + UT_ASSERT((lhs == rhs) == x); +} + +void +run(pmem::obj::pool &pop) +{ + auto r = pop.root(); + + try { + nvobj::transaction::run(pop, [&] { + r->s1 = nvobj::make_persistent(""); + r->s2 = nvobj::make_persistent( + "abcde"); + r->s3 = nvobj::make_persistent( + "abcdefghij"); + r->s4 = nvobj::make_persistent( + "abcdefghijklmnopqrst"); + }); + + test(*r->s1, "", true); + test(*r->s1, "abcde", false); + test(*r->s1, "abcdefghij", false); + test(*r->s1, "abcdefghijklmnopqrst", false); + test(*r->s2, "", false); + test(*r->s2, "abcde", true); + test(*r->s2, "abcdefghij", false); + test(*r->s2, "abcdefghijklmnopqrst", false); + test(*r->s3, "", false); + test(*r->s3, "abcde", false); + test(*r->s3, "abcdefghij", true); + test(*r->s3, "abcdefghijklmnopqrst", false); + test(*r->s4, "", false); + test(*r->s4, "abcde", false); + test(*r->s4, "abcdefghij", false); + test(*r->s4, "abcdefghijklmnopqrst", true); + + nvobj::transaction::run(pop, [&] { + nvobj::delete_persistent(r->s1); + nvobj::delete_persistent(r->s2); + nvobj::delete_persistent(r->s3); + nvobj::delete_persistent(r->s4); + }); + } catch (std::exception &e) { + UT_FATALexc(e); + } +} + +int +main(int argc, char *argv[]) +{ + START(); + + if (argc != 2) + UT_FATAL("usage: %s file-name", argv[0]); + + const char *path = argv[1]; + + pmem::obj::pool pop; + + try { + pop = pmem::obj::pool::create(path, "basic_string", + PMEMOBJ_MIN_POOL, + S_IWUSR | S_IRUSR); + } catch (...) { + UT_FATAL("!pmemobj_create: %s", path); + } + + run(pop); + + pop.close(); + + return 0; +} diff --git a/tests/external/libcxx/basic_string/string.nonmembers/string_opeq/string_string.pass.cpp b/tests/external/libcxx/basic_string/string.nonmembers/string_opeq/string_string.pass.cpp new file mode 100644 index 0000000..40a2ffa --- /dev/null +++ b/tests/external/libcxx/basic_string/string.nonmembers/string_opeq/string_string.pass.cpp @@ -0,0 +1,106 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// Copyright 2019, Intel Corporation +// +// Modified to test pmem::obj containers +// + +#include "unittest.hpp" + +#include +#include +#include +#include +#include + +namespace pmem_exp = pmem::obj::experimental; +namespace nvobj = pmem::obj; + +struct root { + nvobj::persistent_ptr s1, s2, s3, s4; +}; + +template +void +test(const S &lhs, const S &rhs, bool x) +{ + UT_ASSERT((lhs == rhs) == x); +} + +void +run(pmem::obj::pool &pop) +{ + auto r = pop.root(); + + try { + nvobj::transaction::run(pop, [&] { + r->s1 = nvobj::make_persistent(""); + r->s2 = nvobj::make_persistent( + "abcde"); + r->s3 = nvobj::make_persistent( + "abcdefghij"); + r->s4 = nvobj::make_persistent( + "abcdefghijklmnopqrst"); + }); + + test(*r->s1, *r->s1, true); + test(*r->s1, *r->s2, false); + test(*r->s1, *r->s3, false); + test(*r->s1, *r->s4, false); + test(*r->s2, *r->s1, false); + test(*r->s2, *r->s2, true); + test(*r->s2, *r->s3, false); + test(*r->s2, *r->s4, false); + test(*r->s3, *r->s1, false); + test(*r->s3, *r->s2, false); + test(*r->s3, *r->s3, true); + test(*r->s3, *r->s4, false); + test(*r->s4, *r->s1, false); + test(*r->s4, *r->s2, false); + test(*r->s4, *r->s3, false); + test(*r->s4, *r->s4, true); + + nvobj::transaction::run(pop, [&] { + nvobj::delete_persistent(r->s1); + nvobj::delete_persistent(r->s2); + nvobj::delete_persistent(r->s3); + nvobj::delete_persistent(r->s4); + }); + } catch (std::exception &e) { + UT_FATALexc(e); + } +} + +int +main(int argc, char *argv[]) +{ + START(); + + if (argc != 2) + UT_FATAL("usage: %s file-name", argv[0]); + + const char *path = argv[1]; + + pmem::obj::pool pop; + + try { + pop = pmem::obj::pool::create(path, "basic_string", + PMEMOBJ_MIN_POOL, + S_IWUSR | S_IRUSR); + } catch (...) { + UT_FATAL("!pmemobj_create: %s", path); + } + + run(pop); + + pop.close(); + + return 0; +} diff --git a/tests/external/libcxx/basic_string/string.nonmembers/string_opeq/string_string_view.pass.cpp b/tests/external/libcxx/basic_string/string.nonmembers/string_opeq/string_string_view.pass.cpp new file mode 100644 index 0000000..dec8f6f --- /dev/null +++ b/tests/external/libcxx/basic_string/string.nonmembers/string_opeq/string_string_view.pass.cpp @@ -0,0 +1,70 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// + +// we get this comparison "for free" because the string implicitly converts to the string_view + +#include +#include + +#include "min_allocator.h" + +template +void +test(const S& lhs, SV rhs, bool x) +{ + assert((lhs == rhs) == x); +} + +int main() +{ + { + typedef std::string S; + typedef std::string_view SV; + test(S(""), SV(""), true); + test(S(""), SV("abcde"), false); + test(S(""), SV("abcdefghij"), false); + test(S(""), SV("abcdefghijklmnopqrst"), false); + test(S("abcde"), SV(""), false); + test(S("abcde"), SV("abcde"), true); + test(S("abcde"), SV("abcdefghij"), false); + test(S("abcde"), SV("abcdefghijklmnopqrst"), false); + test(S("abcdefghij"), SV(""), false); + test(S("abcdefghij"), SV("abcde"), false); + test(S("abcdefghij"), SV("abcdefghij"), true); + test(S("abcdefghij"), SV("abcdefghijklmnopqrst"), false); + test(S("abcdefghijklmnopqrst"), SV(""), false); + test(S("abcdefghijklmnopqrst"), SV("abcde"), false); + test(S("abcdefghijklmnopqrst"), SV("abcdefghij"), false); + test(S("abcdefghijklmnopqrst"), SV("abcdefghijklmnopqrst"), true); + } +#if TEST_STD_VER >= 11 + { + typedef std::basic_string , min_allocator> S; + typedef std::basic_string_view> SV; + test(S(""), SV(""), true); + test(S(""), SV("abcde"), false); + test(S(""), SV("abcdefghij"), false); + test(S(""), SV("abcdefghijklmnopqrst"), false); + test(S("abcde"), SV(""), false); + test(S("abcde"), SV("abcde"), true); + test(S("abcde"), SV("abcdefghij"), false); + test(S("abcde"), SV("abcdefghijklmnopqrst"), false); + test(S("abcdefghij"), SV(""), false); + test(S("abcdefghij"), SV("abcde"), false); + test(S("abcdefghij"), SV("abcdefghij"), true); + test(S("abcdefghij"), SV("abcdefghijklmnopqrst"), false); + test(S("abcdefghijklmnopqrst"), SV(""), false); + test(S("abcdefghijklmnopqrst"), SV("abcde"), false); + test(S("abcdefghijklmnopqrst"), SV("abcdefghij"), false); + test(S("abcdefghijklmnopqrst"), SV("abcdefghijklmnopqrst"), true); + } +#endif +} diff --git a/tests/external/libcxx/basic_string/string.nonmembers/string_opeq/string_view_string.pass.cpp b/tests/external/libcxx/basic_string/string.nonmembers/string_opeq/string_view_string.pass.cpp new file mode 100644 index 0000000..2cd8086 --- /dev/null +++ b/tests/external/libcxx/basic_string/string.nonmembers/string_opeq/string_view_string.pass.cpp @@ -0,0 +1,70 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// + +// we get this comparison "for free" because the string implicitly converts to the string_view + +#include +#include + +#include "min_allocator.h" + +template +void +test(SV lhs, const S& rhs, bool x) +{ + assert((lhs == rhs) == x); +} + +int main() +{ + { + typedef std::string S; + typedef std::string_view SV; + test(SV(""), S(""), true); + test(SV(""), S("abcde"), false); + test(SV(""), S("abcdefghij"), false); + test(SV(""), S("abcdefghijklmnopqrst"), false); + test(SV("abcde"), S(""), false); + test(SV("abcde"), S("abcde"), true); + test(SV("abcde"), S("abcdefghij"), false); + test(SV("abcde"), S("abcdefghijklmnopqrst"), false); + test(SV("abcdefghij"), S(""), false); + test(SV("abcdefghij"), S("abcde"), false); + test(SV("abcdefghij"), S("abcdefghij"), true); + test(SV("abcdefghij"), S("abcdefghijklmnopqrst"), false); + test(SV("abcdefghijklmnopqrst"), S(""), false); + test(SV("abcdefghijklmnopqrst"), S("abcde"), false); + test(SV("abcdefghijklmnopqrst"), S("abcdefghij"), false); + test(SV("abcdefghijklmnopqrst"), S("abcdefghijklmnopqrst"), true); + } +#if TEST_STD_VER >= 11 + { + typedef std::basic_string, min_allocator> S; + typedef std::basic_string_view> SV; + test(SV(""), S(""), true); + test(SV(""), S("abcde"), false); + test(SV(""), S("abcdefghij"), false); + test(SV(""), S("abcdefghijklmnopqrst"), false); + test(SV("abcde"), S(""), false); + test(SV("abcde"), S("abcde"), true); + test(SV("abcde"), S("abcdefghij"), false); + test(SV("abcde"), S("abcdefghijklmnopqrst"), false); + test(SV("abcdefghij"), S(""), false); + test(SV("abcdefghij"), S("abcde"), false); + test(SV("abcdefghij"), S("abcdefghij"), true); + test(SV("abcdefghij"), S("abcdefghijklmnopqrst"), false); + test(SV("abcdefghijklmnopqrst"), S(""), false); + test(SV("abcdefghijklmnopqrst"), S("abcde"), false); + test(SV("abcdefghijklmnopqrst"), S("abcdefghij"), false); + test(SV("abcdefghijklmnopqrst"), S("abcdefghijklmnopqrst"), true); + } +#endif +} diff --git a/tests/external/libcxx/basic_string/string.nonmembers/string_opge/pointer_string.pass.cpp b/tests/external/libcxx/basic_string/string.nonmembers/string_opge/pointer_string.pass.cpp new file mode 100644 index 0000000..a2ef207 --- /dev/null +++ b/tests/external/libcxx/basic_string/string.nonmembers/string_opge/pointer_string.pass.cpp @@ -0,0 +1,106 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// Copyright 2019, Intel Corporation +// +// Modified to test pmem::obj containers +// + +#include "unittest.hpp" + +#include +#include +#include +#include +#include + +namespace pmem_exp = pmem::obj::experimental; +namespace nvobj = pmem::obj; + +struct root { + nvobj::persistent_ptr s1, s2, s3, s4; +}; + +template +void +test(const typename S::value_type *lhs, const S &rhs, bool x) +{ + UT_ASSERT((lhs >= rhs) == x); +} + +void +run(pmem::obj::pool &pop) +{ + auto r = pop.root(); + + try { + nvobj::transaction::run(pop, [&] { + r->s1 = nvobj::make_persistent(""); + r->s2 = nvobj::make_persistent( + "abcde"); + r->s3 = nvobj::make_persistent( + "abcdefghij"); + r->s4 = nvobj::make_persistent( + "abcdefghijklmnopqrst"); + }); + + test("", *r->s1, true); + test("", *r->s2, false); + test("", *r->s3, false); + test("", *r->s4, false); + test("abcde", *r->s1, true); + test("abcde", *r->s2, true); + test("abcde", *r->s3, false); + test("abcde", *r->s4, false); + test("abcdefghij", *r->s1, true); + test("abcdefghij", *r->s2, true); + test("abcdefghij", *r->s3, true); + test("abcdefghij", *r->s4, false); + test("abcdefghijklmnopqrst", *r->s1, true); + test("abcdefghijklmnopqrst", *r->s2, true); + test("abcdefghijklmnopqrst", *r->s3, true); + test("abcdefghijklmnopqrst", *r->s4, true); + + nvobj::transaction::run(pop, [&] { + nvobj::delete_persistent(r->s1); + nvobj::delete_persistent(r->s2); + nvobj::delete_persistent(r->s3); + nvobj::delete_persistent(r->s4); + }); + } catch (std::exception &e) { + UT_FATALexc(e); + } +} + +int +main(int argc, char *argv[]) +{ + START(); + + if (argc != 2) + UT_FATAL("usage: %s file-name", argv[0]); + + const char *path = argv[1]; + + pmem::obj::pool pop; + + try { + pop = pmem::obj::pool::create(path, "basic_string", + PMEMOBJ_MIN_POOL, + S_IWUSR | S_IRUSR); + } catch (...) { + UT_FATAL("!pmemobj_create: %s", path); + } + + run(pop); + + pop.close(); + + return 0; +} diff --git a/tests/external/libcxx/basic_string/string.nonmembers/string_opge/string_pointer.pass.cpp b/tests/external/libcxx/basic_string/string.nonmembers/string_opge/string_pointer.pass.cpp new file mode 100644 index 0000000..4fff512 --- /dev/null +++ b/tests/external/libcxx/basic_string/string.nonmembers/string_opge/string_pointer.pass.cpp @@ -0,0 +1,106 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// Copyright 2019, Intel Corporation +// +// Modified to test pmem::obj containers +// + +#include "unittest.hpp" + +#include +#include +#include +#include +#include + +namespace pmem_exp = pmem::obj::experimental; +namespace nvobj = pmem::obj; + +struct root { + nvobj::persistent_ptr s1, s2, s3, s4; +}; + +template +void +test(const S &lhs, const typename S::value_type *rhs, bool x) +{ + UT_ASSERT((lhs >= rhs) == x); +} + +void +run(pmem::obj::pool &pop) +{ + auto r = pop.root(); + + try { + nvobj::transaction::run(pop, [&] { + r->s1 = nvobj::make_persistent(""); + r->s2 = nvobj::make_persistent( + "abcde"); + r->s3 = nvobj::make_persistent( + "abcdefghij"); + r->s4 = nvobj::make_persistent( + "abcdefghijklmnopqrst"); + }); + + test(*r->s1, "", true); + test(*r->s1, "abcde", false); + test(*r->s1, "abcdefghij", false); + test(*r->s1, "abcdefghijklmnopqrst", false); + test(*r->s2, "", true); + test(*r->s2, "abcde", true); + test(*r->s2, "abcdefghij", false); + test(*r->s2, "abcdefghijklmnopqrst", false); + test(*r->s3, "", true); + test(*r->s3, "abcde", true); + test(*r->s3, "abcdefghij", true); + test(*r->s3, "abcdefghijklmnopqrst", false); + test(*r->s4, "", true); + test(*r->s4, "abcde", true); + test(*r->s4, "abcdefghij", true); + test(*r->s4, "abcdefghijklmnopqrst", true); + + nvobj::transaction::run(pop, [&] { + nvobj::delete_persistent(r->s1); + nvobj::delete_persistent(r->s2); + nvobj::delete_persistent(r->s3); + nvobj::delete_persistent(r->s4); + }); + } catch (std::exception &e) { + UT_FATALexc(e); + } +} + +int +main(int argc, char *argv[]) +{ + START(); + + if (argc != 2) + UT_FATAL("usage: %s file-name", argv[0]); + + const char *path = argv[1]; + + pmem::obj::pool pop; + + try { + pop = pmem::obj::pool::create(path, "basic_string", + PMEMOBJ_MIN_POOL, + S_IWUSR | S_IRUSR); + } catch (...) { + UT_FATAL("!pmemobj_create: %s", path); + } + + run(pop); + + pop.close(); + + return 0; +} diff --git a/tests/external/libcxx/basic_string/string.nonmembers/string_opge/string_string.pass.cpp b/tests/external/libcxx/basic_string/string.nonmembers/string_opge/string_string.pass.cpp new file mode 100644 index 0000000..4402fa0 --- /dev/null +++ b/tests/external/libcxx/basic_string/string.nonmembers/string_opge/string_string.pass.cpp @@ -0,0 +1,106 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// Copyright 2019, Intel Corporation +// +// Modified to test pmem::obj containers +// + +#include "unittest.hpp" + +#include +#include +#include +#include +#include + +namespace pmem_exp = pmem::obj::experimental; +namespace nvobj = pmem::obj; + +struct root { + nvobj::persistent_ptr s1, s2, s3, s4; +}; + +template +void +test(const S &lhs, const S &rhs, bool x) +{ + UT_ASSERT((lhs >= rhs) == x); +} + +void +run(pmem::obj::pool &pop) +{ + auto r = pop.root(); + + try { + nvobj::transaction::run(pop, [&] { + r->s1 = nvobj::make_persistent(""); + r->s2 = nvobj::make_persistent( + "abcde"); + r->s3 = nvobj::make_persistent( + "abcdefghij"); + r->s4 = nvobj::make_persistent( + "abcdefghijklmnopqrst"); + }); + + test(*r->s1, *r->s1, true); + test(*r->s1, *r->s2, false); + test(*r->s1, *r->s3, false); + test(*r->s1, *r->s4, false); + test(*r->s2, *r->s1, true); + test(*r->s2, *r->s2, true); + test(*r->s2, *r->s3, false); + test(*r->s2, *r->s4, false); + test(*r->s3, *r->s1, true); + test(*r->s3, *r->s2, true); + test(*r->s3, *r->s3, true); + test(*r->s3, *r->s4, false); + test(*r->s4, *r->s1, true); + test(*r->s4, *r->s2, true); + test(*r->s4, *r->s3, true); + test(*r->s4, *r->s4, true); + + nvobj::transaction::run(pop, [&] { + nvobj::delete_persistent(r->s1); + nvobj::delete_persistent(r->s2); + nvobj::delete_persistent(r->s3); + nvobj::delete_persistent(r->s4); + }); + } catch (std::exception &e) { + UT_FATALexc(e); + } +} + +int +main(int argc, char *argv[]) +{ + START(); + + if (argc != 2) + UT_FATAL("usage: %s file-name", argv[0]); + + const char *path = argv[1]; + + pmem::obj::pool pop; + + try { + pop = pmem::obj::pool::create(path, "basic_string", + PMEMOBJ_MIN_POOL, + S_IWUSR | S_IRUSR); + } catch (...) { + UT_FATAL("!pmemobj_create: %s", path); + } + + run(pop); + + pop.close(); + + return 0; +} diff --git a/tests/external/libcxx/basic_string/string.nonmembers/string_opge/string_string_view.pass.cpp b/tests/external/libcxx/basic_string/string.nonmembers/string_opge/string_string_view.pass.cpp new file mode 100644 index 0000000..5b9671f --- /dev/null +++ b/tests/external/libcxx/basic_string/string.nonmembers/string_opge/string_string_view.pass.cpp @@ -0,0 +1,70 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// + +// we get this comparison "for free" because the string implicitly converts to the string_view + +#include +#include + +#include "min_allocator.h" + +template +void +test(const S& lhs, SV rhs, bool x) +{ + assert((lhs >= rhs) == x); +} + +int main() +{ + { + typedef std::string S; + typedef std::string_view SV; + test(S(""), SV(""), true); + test(S(""), SV("abcde"), false); + test(S(""), SV("abcdefghij"), false); + test(S(""), SV("abcdefghijklmnopqrst"), false); + test(S("abcde"), SV(""), true); + test(S("abcde"), SV("abcde"), true); + test(S("abcde"), SV("abcdefghij"), false); + test(S("abcde"), SV("abcdefghijklmnopqrst"), false); + test(S("abcdefghij"), SV(""), true); + test(S("abcdefghij"), SV("abcde"), true); + test(S("abcdefghij"), SV("abcdefghij"), true); + test(S("abcdefghij"), SV("abcdefghijklmnopqrst"), false); + test(S("abcdefghijklmnopqrst"), SV(""), true); + test(S("abcdefghijklmnopqrst"), SV("abcde"), true); + test(S("abcdefghijklmnopqrst"), SV("abcdefghij"), true); + test(S("abcdefghijklmnopqrst"), SV("abcdefghijklmnopqrst"), true); + } +#if TEST_STD_VER >= 11 + { + typedef std::basic_string, min_allocator> S; + typedef std::basic_string_view> SV; + test(S(""), SV(""), true); + test(S(""), SV("abcde"), false); + test(S(""), SV("abcdefghij"), false); + test(S(""), SV("abcdefghijklmnopqrst"), false); + test(S("abcde"), SV(""), true); + test(S("abcde"), SV("abcde"), true); + test(S("abcde"), SV("abcdefghij"), false); + test(S("abcde"), SV("abcdefghijklmnopqrst"), false); + test(S("abcdefghij"), SV(""), true); + test(S("abcdefghij"), SV("abcde"), true); + test(S("abcdefghij"), SV("abcdefghij"), true); + test(S("abcdefghij"), SV("abcdefghijklmnopqrst"), false); + test(S("abcdefghijklmnopqrst"), SV(""), true); + test(S("abcdefghijklmnopqrst"), SV("abcde"), true); + test(S("abcdefghijklmnopqrst"), SV("abcdefghij"), true); + test(S("abcdefghijklmnopqrst"), SV("abcdefghijklmnopqrst"), true); + } +#endif +} diff --git a/tests/external/libcxx/basic_string/string.nonmembers/string_opge/string_view_string.pass.cpp b/tests/external/libcxx/basic_string/string.nonmembers/string_opge/string_view_string.pass.cpp new file mode 100644 index 0000000..07c8282 --- /dev/null +++ b/tests/external/libcxx/basic_string/string.nonmembers/string_opge/string_view_string.pass.cpp @@ -0,0 +1,70 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// + +// we get this comparison "for free" because the string implicitly converts to the string_view + +#include +#include + +#include "min_allocator.h" + +template +void +test(SV lhs, const S& rhs, bool x) +{ + assert((lhs >= rhs) == x); +} + +int main() +{ + { + typedef std::string S; + typedef std::string_view SV; + test(SV(""), S(""), true); + test(SV(""), S("abcde"), false); + test(SV(""), S("abcdefghij"), false); + test(SV(""), S("abcdefghijklmnopqrst"), false); + test(SV("abcde"), S(""), true); + test(SV("abcde"), S("abcde"), true); + test(SV("abcde"), S("abcdefghij"), false); + test(SV("abcde"), S("abcdefghijklmnopqrst"), false); + test(SV("abcdefghij"), S(""), true); + test(SV("abcdefghij"), S("abcde"), true); + test(SV("abcdefghij"), S("abcdefghij"), true); + test(SV("abcdefghij"), S("abcdefghijklmnopqrst"), false); + test(SV("abcdefghijklmnopqrst"), S(""), true); + test(SV("abcdefghijklmnopqrst"), S("abcde"), true); + test(SV("abcdefghijklmnopqrst"), S("abcdefghij"), true); + test(SV("abcdefghijklmnopqrst"), S("abcdefghijklmnopqrst"), true); + } +#if TEST_STD_VER >= 11 + { + typedef std::basic_string, min_allocator> S; + typedef std::basic_string_view> SV; + test(SV(""), S(""), true); + test(SV(""), S("abcde"), false); + test(SV(""), S("abcdefghij"), false); + test(SV(""), S("abcdefghijklmnopqrst"), false); + test(SV("abcde"), S(""), true); + test(SV("abcde"), S("abcde"), true); + test(SV("abcde"), S("abcdefghij"), false); + test(SV("abcde"), S("abcdefghijklmnopqrst"), false); + test(SV("abcdefghij"), S(""), true); + test(SV("abcdefghij"), S("abcde"), true); + test(SV("abcdefghij"), S("abcdefghij"), true); + test(SV("abcdefghij"), S("abcdefghijklmnopqrst"), false); + test(SV("abcdefghijklmnopqrst"), S(""), true); + test(SV("abcdefghijklmnopqrst"), S("abcde"), true); + test(SV("abcdefghijklmnopqrst"), S("abcdefghij"), true); + test(SV("abcdefghijklmnopqrst"), S("abcdefghijklmnopqrst"), true); + } +#endif +} diff --git a/tests/external/libcxx/basic_string/string.nonmembers/string_opgt/pointer_string.pass.cpp b/tests/external/libcxx/basic_string/string.nonmembers/string_opgt/pointer_string.pass.cpp new file mode 100644 index 0000000..4ea3f49 --- /dev/null +++ b/tests/external/libcxx/basic_string/string.nonmembers/string_opgt/pointer_string.pass.cpp @@ -0,0 +1,106 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// Copyright 2019, Intel Corporation +// +// Modified to test pmem::obj containers +// + +#include "unittest.hpp" + +#include +#include +#include +#include +#include + +namespace pmem_exp = pmem::obj::experimental; +namespace nvobj = pmem::obj; + +struct root { + nvobj::persistent_ptr s1, s2, s3, s4; +}; + +template +void +test(const typename S::value_type *lhs, const S &rhs, bool x) +{ + UT_ASSERT((lhs > rhs) == x); +} + +void +run(pmem::obj::pool &pop) +{ + auto r = pop.root(); + + try { + nvobj::transaction::run(pop, [&] { + r->s1 = nvobj::make_persistent(""); + r->s2 = nvobj::make_persistent( + "abcde"); + r->s3 = nvobj::make_persistent( + "abcdefghij"); + r->s4 = nvobj::make_persistent( + "abcdefghijklmnopqrst"); + }); + + test("", *r->s1, false); + test("", *r->s2, false); + test("", *r->s3, false); + test("", *r->s4, false); + test("abcde", *r->s1, true); + test("abcde", *r->s2, false); + test("abcde", *r->s3, false); + test("abcde", *r->s4, false); + test("abcdefghij", *r->s1, true); + test("abcdefghij", *r->s2, true); + test("abcdefghij", *r->s3, false); + test("abcdefghij", *r->s4, false); + test("abcdefghijklmnopqrst", *r->s1, true); + test("abcdefghijklmnopqrst", *r->s2, true); + test("abcdefghijklmnopqrst", *r->s3, true); + test("abcdefghijklmnopqrst", *r->s4, false); + + nvobj::transaction::run(pop, [&] { + nvobj::delete_persistent(r->s1); + nvobj::delete_persistent(r->s2); + nvobj::delete_persistent(r->s3); + nvobj::delete_persistent(r->s4); + }); + } catch (std::exception &e) { + UT_FATALexc(e); + } +} + +int +main(int argc, char *argv[]) +{ + START(); + + if (argc != 2) + UT_FATAL("usage: %s file-name", argv[0]); + + const char *path = argv[1]; + + pmem::obj::pool pop; + + try { + pop = pmem::obj::pool::create(path, "basic_string", + PMEMOBJ_MIN_POOL, + S_IWUSR | S_IRUSR); + } catch (...) { + UT_FATAL("!pmemobj_create: %s", path); + } + + run(pop); + + pop.close(); + + return 0; +} diff --git a/tests/external/libcxx/basic_string/string.nonmembers/string_opgt/string_pointer.pass.cpp b/tests/external/libcxx/basic_string/string.nonmembers/string_opgt/string_pointer.pass.cpp new file mode 100644 index 0000000..b12dee8 --- /dev/null +++ b/tests/external/libcxx/basic_string/string.nonmembers/string_opgt/string_pointer.pass.cpp @@ -0,0 +1,106 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// Copyright 2019, Intel Corporation +// +// Modified to test pmem::obj containers +// + +#include "unittest.hpp" + +#include +#include +#include +#include +#include + +namespace pmem_exp = pmem::obj::experimental; +namespace nvobj = pmem::obj; + +struct root { + nvobj::persistent_ptr s1, s2, s3, s4; +}; + +template +void +test(const S &lhs, const typename S::value_type *rhs, bool x) +{ + UT_ASSERT((lhs > rhs) == x); +} + +void +run(pmem::obj::pool &pop) +{ + auto r = pop.root(); + + try { + nvobj::transaction::run(pop, [&] { + r->s1 = nvobj::make_persistent(""); + r->s2 = nvobj::make_persistent( + "abcde"); + r->s3 = nvobj::make_persistent( + "abcdefghij"); + r->s4 = nvobj::make_persistent( + "abcdefghijklmnopqrst"); + }); + + test(*r->s1, "", false); + test(*r->s1, "abcde", false); + test(*r->s1, "abcdefghij", false); + test(*r->s1, "abcdefghijklmnopqrst", false); + test(*r->s2, "", true); + test(*r->s2, "abcde", false); + test(*r->s2, "abcdefghij", false); + test(*r->s2, "abcdefghijklmnopqrst", false); + test(*r->s3, "", true); + test(*r->s3, "abcde", true); + test(*r->s3, "abcdefghij", false); + test(*r->s3, "abcdefghijklmnopqrst", false); + test(*r->s4, "", true); + test(*r->s4, "abcde", true); + test(*r->s4, "abcdefghij", true); + test(*r->s4, "abcdefghijklmnopqrst", false); + + nvobj::transaction::run(pop, [&] { + nvobj::delete_persistent(r->s1); + nvobj::delete_persistent(r->s2); + nvobj::delete_persistent(r->s3); + nvobj::delete_persistent(r->s4); + }); + } catch (std::exception &e) { + UT_FATALexc(e); + } +} + +int +main(int argc, char *argv[]) +{ + START(); + + if (argc != 2) + UT_FATAL("usage: %s file-name", argv[0]); + + const char *path = argv[1]; + + pmem::obj::pool pop; + + try { + pop = pmem::obj::pool::create(path, "basic_string", + PMEMOBJ_MIN_POOL, + S_IWUSR | S_IRUSR); + } catch (...) { + UT_FATAL("!pmemobj_create: %s", path); + } + + run(pop); + + pop.close(); + + return 0; +} diff --git a/tests/external/libcxx/basic_string/string.nonmembers/string_opgt/string_string.pass.cpp b/tests/external/libcxx/basic_string/string.nonmembers/string_opgt/string_string.pass.cpp new file mode 100644 index 0000000..a187043 --- /dev/null +++ b/tests/external/libcxx/basic_string/string.nonmembers/string_opgt/string_string.pass.cpp @@ -0,0 +1,106 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// Copyright 2019, Intel Corporation +// +// Modified to test pmem::obj containers +// + +#include "unittest.hpp" + +#include +#include +#include +#include +#include + +namespace pmem_exp = pmem::obj::experimental; +namespace nvobj = pmem::obj; + +struct root { + nvobj::persistent_ptr s1, s2, s3, s4; +}; + +template +void +test(const S &lhs, const S &rhs, bool x) +{ + UT_ASSERT((lhs > rhs) == x); +} + +void +run(pmem::obj::pool &pop) +{ + auto r = pop.root(); + + try { + nvobj::transaction::run(pop, [&] { + r->s1 = nvobj::make_persistent(""); + r->s2 = nvobj::make_persistent( + "abcde"); + r->s3 = nvobj::make_persistent( + "abcdefghij"); + r->s4 = nvobj::make_persistent( + "abcdefghijklmnopqrst"); + }); + + test(*r->s1, *r->s1, false); + test(*r->s1, *r->s2, false); + test(*r->s1, *r->s3, false); + test(*r->s1, *r->s4, false); + test(*r->s2, *r->s1, true); + test(*r->s2, *r->s2, false); + test(*r->s2, *r->s3, false); + test(*r->s2, *r->s4, false); + test(*r->s3, *r->s1, true); + test(*r->s3, *r->s2, true); + test(*r->s3, *r->s3, false); + test(*r->s3, *r->s4, false); + test(*r->s4, *r->s1, true); + test(*r->s4, *r->s2, true); + test(*r->s4, *r->s3, true); + test(*r->s4, *r->s4, false); + + nvobj::transaction::run(pop, [&] { + nvobj::delete_persistent(r->s1); + nvobj::delete_persistent(r->s2); + nvobj::delete_persistent(r->s3); + nvobj::delete_persistent(r->s4); + }); + } catch (std::exception &e) { + UT_FATALexc(e); + } +} + +int +main(int argc, char *argv[]) +{ + START(); + + if (argc != 2) + UT_FATAL("usage: %s file-name", argv[0]); + + const char *path = argv[1]; + + pmem::obj::pool pop; + + try { + pop = pmem::obj::pool::create(path, "basic_string", + PMEMOBJ_MIN_POOL, + S_IWUSR | S_IRUSR); + } catch (...) { + UT_FATAL("!pmemobj_create: %s", path); + } + + run(pop); + + pop.close(); + + return 0; +} diff --git a/tests/external/libcxx/basic_string/string.nonmembers/string_opgt/string_string_view.pass.cpp b/tests/external/libcxx/basic_string/string.nonmembers/string_opgt/string_string_view.pass.cpp new file mode 100644 index 0000000..d9f5d71 --- /dev/null +++ b/tests/external/libcxx/basic_string/string.nonmembers/string_opgt/string_string_view.pass.cpp @@ -0,0 +1,70 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// + +// we get this comparison "for free" because the string implicitly converts to the string_view + +#include +#include + +#include "min_allocator.h" + +template +void +test(const S& lhs, SV rhs, bool x) +{ + assert((lhs > rhs) == x); +} + +int main() +{ + { + typedef std::string S; + typedef std::string_view SV; + test(S(""), SV(""), false); + test(S(""), SV("abcde"), false); + test(S(""), SV("abcdefghij"), false); + test(S(""), SV("abcdefghijklmnopqrst"), false); + test(S("abcde"), SV(""), true); + test(S("abcde"), SV("abcde"), false); + test(S("abcde"), SV("abcdefghij"), false); + test(S("abcde"), SV("abcdefghijklmnopqrst"), false); + test(S("abcdefghij"), SV(""), true); + test(S("abcdefghij"), SV("abcde"), true); + test(S("abcdefghij"), SV("abcdefghij"), false); + test(S("abcdefghij"), SV("abcdefghijklmnopqrst"), false); + test(S("abcdefghijklmnopqrst"), SV(""), true); + test(S("abcdefghijklmnopqrst"), SV("abcde"), true); + test(S("abcdefghijklmnopqrst"), SV("abcdefghij"), true); + test(S("abcdefghijklmnopqrst"), SV("abcdefghijklmnopqrst"), false); + } +#if TEST_STD_VER >= 11 + { + typedef std::basic_string , min_allocator> S; + typedef std::basic_string_view> SV; + test(S(""), SV(""), false); + test(S(""), SV("abcde"), false); + test(S(""), SV("abcdefghij"), false); + test(S(""), SV("abcdefghijklmnopqrst"), false); + test(S("abcde"), SV(""), true); + test(S("abcde"), SV("abcde"), false); + test(S("abcde"), SV("abcdefghij"), false); + test(S("abcde"), SV("abcdefghijklmnopqrst"), false); + test(S("abcdefghij"), SV(""), true); + test(S("abcdefghij"), SV("abcde"), true); + test(S("abcdefghij"), SV("abcdefghij"), false); + test(S("abcdefghij"), SV("abcdefghijklmnopqrst"), false); + test(S("abcdefghijklmnopqrst"), SV(""), true); + test(S("abcdefghijklmnopqrst"), SV("abcde"), true); + test(S("abcdefghijklmnopqrst"), SV("abcdefghij"), true); + test(S("abcdefghijklmnopqrst"), SV("abcdefghijklmnopqrst"), false); + } +#endif +} diff --git a/tests/external/libcxx/basic_string/string.nonmembers/string_opgt/string_view_string.pass.cpp b/tests/external/libcxx/basic_string/string.nonmembers/string_opgt/string_view_string.pass.cpp new file mode 100644 index 0000000..c685bab --- /dev/null +++ b/tests/external/libcxx/basic_string/string.nonmembers/string_opgt/string_view_string.pass.cpp @@ -0,0 +1,70 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// + +// we get this comparison "for free" because the string implicitly converts to the string_view + +#include +#include + +#include "min_allocator.h" + +template +void +test(SV lhs, const S& rhs, bool x) +{ + assert((lhs > rhs) == x); +} + +int main() +{ + { + typedef std::string S; + typedef std::string_view SV; + test(SV(""), S(""), false); + test(SV(""), S("abcde"), false); + test(SV(""), S("abcdefghij"), false); + test(SV(""), S("abcdefghijklmnopqrst"), false); + test(SV("abcde"), S(""), true); + test(SV("abcde"), S("abcde"), false); + test(SV("abcde"), S("abcdefghij"), false); + test(SV("abcde"), S("abcdefghijklmnopqrst"), false); + test(SV("abcdefghij"), S(""), true); + test(SV("abcdefghij"), S("abcde"), true); + test(SV("abcdefghij"), S("abcdefghij"), false); + test(SV("abcdefghij"), S("abcdefghijklmnopqrst"), false); + test(SV("abcdefghijklmnopqrst"), S(""), true); + test(SV("abcdefghijklmnopqrst"), S("abcde"), true); + test(SV("abcdefghijklmnopqrst"), S("abcdefghij"), true); + test(SV("abcdefghijklmnopqrst"), S("abcdefghijklmnopqrst"), false); + } +#if TEST_STD_VER >= 11 + { + typedef std::basic_string , min_allocator> S; + typedef std::basic_string_view> SV; + test(SV(""), S(""), false); + test(SV(""), S("abcde"), false); + test(SV(""), S("abcdefghij"), false); + test(SV(""), S("abcdefghijklmnopqrst"), false); + test(SV("abcde"), S(""), true); + test(SV("abcde"), S("abcde"), false); + test(SV("abcde"), S("abcdefghij"), false); + test(SV("abcde"), S("abcdefghijklmnopqrst"), false); + test(SV("abcdefghij"), S(""), true); + test(SV("abcdefghij"), S("abcde"), true); + test(SV("abcdefghij"), S("abcdefghij"), false); + test(SV("abcdefghij"), S("abcdefghijklmnopqrst"), false); + test(SV("abcdefghijklmnopqrst"), S(""), true); + test(SV("abcdefghijklmnopqrst"), S("abcde"), true); + test(SV("abcdefghijklmnopqrst"), S("abcdefghij"), true); + test(SV("abcdefghijklmnopqrst"), S("abcdefghijklmnopqrst"), false); + } +#endif +} diff --git a/tests/external/libcxx/basic_string/string.nonmembers/string_ople/pointer_string.pass.cpp b/tests/external/libcxx/basic_string/string.nonmembers/string_ople/pointer_string.pass.cpp new file mode 100644 index 0000000..b119afd --- /dev/null +++ b/tests/external/libcxx/basic_string/string.nonmembers/string_ople/pointer_string.pass.cpp @@ -0,0 +1,106 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// Copyright 2019, Intel Corporation +// +// Modified to test pmem::obj containers +// + +#include "unittest.hpp" + +#include +#include +#include +#include +#include + +namespace pmem_exp = pmem::obj::experimental; +namespace nvobj = pmem::obj; + +struct root { + nvobj::persistent_ptr s1, s2, s3, s4; +}; + +template +void +test(const typename S::value_type *lhs, const S &rhs, bool x) +{ + UT_ASSERT((lhs <= rhs) == x); +} + +void +run(pmem::obj::pool &pop) +{ + auto r = pop.root(); + + try { + nvobj::transaction::run(pop, [&] { + r->s1 = nvobj::make_persistent(""); + r->s2 = nvobj::make_persistent( + "abcde"); + r->s3 = nvobj::make_persistent( + "abcdefghij"); + r->s4 = nvobj::make_persistent( + "abcdefghijklmnopqrst"); + }); + + test("", *r->s1, true); + test("", *r->s2, true); + test("", *r->s3, true); + test("", *r->s4, true); + test("abcde", *r->s1, false); + test("abcde", *r->s2, true); + test("abcde", *r->s3, true); + test("abcde", *r->s4, true); + test("abcdefghij", *r->s1, false); + test("abcdefghij", *r->s2, false); + test("abcdefghij", *r->s3, true); + test("abcdefghij", *r->s4, true); + test("abcdefghijklmnopqrst", *r->s1, false); + test("abcdefghijklmnopqrst", *r->s2, false); + test("abcdefghijklmnopqrst", *r->s3, false); + test("abcdefghijklmnopqrst", *r->s4, true); + + nvobj::transaction::run(pop, [&] { + nvobj::delete_persistent(r->s1); + nvobj::delete_persistent(r->s2); + nvobj::delete_persistent(r->s3); + nvobj::delete_persistent(r->s4); + }); + } catch (std::exception &e) { + UT_FATALexc(e); + } +} + +int +main(int argc, char *argv[]) +{ + START(); + + if (argc != 2) + UT_FATAL("usage: %s file-name", argv[0]); + + const char *path = argv[1]; + + pmem::obj::pool pop; + + try { + pop = pmem::obj::pool::create(path, "basic_string", + PMEMOBJ_MIN_POOL, + S_IWUSR | S_IRUSR); + } catch (...) { + UT_FATAL("!pmemobj_create: %s", path); + } + + run(pop); + + pop.close(); + + return 0; +} diff --git a/tests/external/libcxx/basic_string/string.nonmembers/string_ople/string_pointer.pass.cpp b/tests/external/libcxx/basic_string/string.nonmembers/string_ople/string_pointer.pass.cpp new file mode 100644 index 0000000..a00fc9e --- /dev/null +++ b/tests/external/libcxx/basic_string/string.nonmembers/string_ople/string_pointer.pass.cpp @@ -0,0 +1,106 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// Copyright 2019, Intel Corporation +// +// Modified to test pmem::obj containers +// + +#include "unittest.hpp" + +#include +#include +#include +#include +#include + +namespace pmem_exp = pmem::obj::experimental; +namespace nvobj = pmem::obj; + +struct root { + nvobj::persistent_ptr s1, s2, s3, s4; +}; + +template +void +test(const S &lhs, const typename S::value_type *rhs, bool x) +{ + UT_ASSERT((lhs <= rhs) == x); +} + +void +run(pmem::obj::pool &pop) +{ + auto r = pop.root(); + + try { + nvobj::transaction::run(pop, [&] { + r->s1 = nvobj::make_persistent(""); + r->s2 = nvobj::make_persistent( + "abcde"); + r->s3 = nvobj::make_persistent( + "abcdefghij"); + r->s4 = nvobj::make_persistent( + "abcdefghijklmnopqrst"); + }); + + test(*r->s1, "", true); + test(*r->s1, "abcde", true); + test(*r->s1, "abcdefghij", true); + test(*r->s1, "abcdefghijklmnopqrst", true); + test(*r->s2, "", false); + test(*r->s2, "abcde", true); + test(*r->s2, "abcdefghij", true); + test(*r->s2, "abcdefghijklmnopqrst", true); + test(*r->s3, "", false); + test(*r->s3, "abcde", false); + test(*r->s3, "abcdefghij", true); + test(*r->s3, "abcdefghijklmnopqrst", true); + test(*r->s4, "", false); + test(*r->s4, "abcde", false); + test(*r->s4, "abcdefghij", false); + test(*r->s4, "abcdefghijklmnopqrst", true); + + nvobj::transaction::run(pop, [&] { + nvobj::delete_persistent(r->s1); + nvobj::delete_persistent(r->s2); + nvobj::delete_persistent(r->s3); + nvobj::delete_persistent(r->s4); + }); + } catch (std::exception &e) { + UT_FATALexc(e); + } +} + +int +main(int argc, char *argv[]) +{ + START(); + + if (argc != 2) + UT_FATAL("usage: %s file-name", argv[0]); + + const char *path = argv[1]; + + pmem::obj::pool pop; + + try { + pop = pmem::obj::pool::create(path, "basic_string", + PMEMOBJ_MIN_POOL, + S_IWUSR | S_IRUSR); + } catch (...) { + UT_FATAL("!pmemobj_create: %s", path); + } + + run(pop); + + pop.close(); + + return 0; +} diff --git a/tests/external/libcxx/basic_string/string.nonmembers/string_ople/string_string.pass.cpp b/tests/external/libcxx/basic_string/string.nonmembers/string_ople/string_string.pass.cpp new file mode 100644 index 0000000..9793534 --- /dev/null +++ b/tests/external/libcxx/basic_string/string.nonmembers/string_ople/string_string.pass.cpp @@ -0,0 +1,106 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// Copyright 2019, Intel Corporation +// +// Modified to test pmem::obj containers +// + +#include "unittest.hpp" + +#include +#include +#include +#include +#include + +namespace pmem_exp = pmem::obj::experimental; +namespace nvobj = pmem::obj; + +struct root { + nvobj::persistent_ptr s1, s2, s3, s4; +}; + +template +void +test(const S &lhs, const S &rhs, bool x) +{ + UT_ASSERT((lhs <= rhs) == x); +} + +void +run(pmem::obj::pool &pop) +{ + auto r = pop.root(); + + try { + nvobj::transaction::run(pop, [&] { + r->s1 = nvobj::make_persistent(""); + r->s2 = nvobj::make_persistent( + "abcde"); + r->s3 = nvobj::make_persistent( + "abcdefghij"); + r->s4 = nvobj::make_persistent( + "abcdefghijklmnopqrst"); + }); + + test(*r->s1, *r->s1, true); + test(*r->s1, *r->s2, true); + test(*r->s1, *r->s3, true); + test(*r->s1, *r->s4, true); + test(*r->s2, *r->s1, false); + test(*r->s2, *r->s2, true); + test(*r->s2, *r->s3, true); + test(*r->s2, *r->s4, true); + test(*r->s3, *r->s1, false); + test(*r->s3, *r->s2, false); + test(*r->s3, *r->s3, true); + test(*r->s3, *r->s4, true); + test(*r->s4, *r->s1, false); + test(*r->s4, *r->s2, false); + test(*r->s4, *r->s3, false); + test(*r->s4, *r->s4, true); + + nvobj::transaction::run(pop, [&] { + nvobj::delete_persistent(r->s1); + nvobj::delete_persistent(r->s2); + nvobj::delete_persistent(r->s3); + nvobj::delete_persistent(r->s4); + }); + } catch (std::exception &e) { + UT_FATALexc(e); + } +} + +int +main(int argc, char *argv[]) +{ + START(); + + if (argc != 2) + UT_FATAL("usage: %s file-name", argv[0]); + + const char *path = argv[1]; + + pmem::obj::pool pop; + + try { + pop = pmem::obj::pool::create(path, "basic_string", + PMEMOBJ_MIN_POOL, + S_IWUSR | S_IRUSR); + } catch (...) { + UT_FATAL("!pmemobj_create: %s", path); + } + + run(pop); + + pop.close(); + + return 0; +} diff --git a/tests/external/libcxx/basic_string/string.nonmembers/string_ople/string_string_view.pass.cpp b/tests/external/libcxx/basic_string/string.nonmembers/string_ople/string_string_view.pass.cpp new file mode 100644 index 0000000..97a9d7c --- /dev/null +++ b/tests/external/libcxx/basic_string/string.nonmembers/string_ople/string_string_view.pass.cpp @@ -0,0 +1,70 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// + +// we get this comparison "for free" because the string implicitly converts to the string_view + +#include +#include + +#include "min_allocator.h" + +template +void +test(const S& lhs, SV rhs, bool x) +{ + assert((lhs <= rhs) == x); +} + +int main() +{ + { + typedef std::string S; + typedef std::string_view SV; + test(S(""), SV(""), true); + test(S(""), SV("abcde"), true); + test(S(""), SV("abcdefghij"), true); + test(S(""), SV("abcdefghijklmnopqrst"), true); + test(S("abcde"), SV(""), false); + test(S("abcde"), SV("abcde"), true); + test(S("abcde"), SV("abcdefghij"), true); + test(S("abcde"), SV("abcdefghijklmnopqrst"), true); + test(S("abcdefghij"), SV(""), false); + test(S("abcdefghij"), SV("abcde"), false); + test(S("abcdefghij"), SV("abcdefghij"), true); + test(S("abcdefghij"), SV("abcdefghijklmnopqrst"), true); + test(S("abcdefghijklmnopqrst"), SV(""), false); + test(S("abcdefghijklmnopqrst"), SV("abcde"), false); + test(S("abcdefghijklmnopqrst"), SV("abcdefghij"), false); + test(S("abcdefghijklmnopqrst"), SV("abcdefghijklmnopqrst"), true); + } +#if TEST_STD_VER >= 11 + { + typedef std::basic_string, min_allocator> S; + typedef std::basic_string_view> SV; + test(S(""), SV(""), true); + test(S(""), SV("abcde"), true); + test(S(""), SV("abcdefghij"), true); + test(S(""), SV("abcdefghijklmnopqrst"), true); + test(S("abcde"), SV(""), false); + test(S("abcde"), SV("abcde"), true); + test(S("abcde"), SV("abcdefghij"), true); + test(S("abcde"), SV("abcdefghijklmnopqrst"), true); + test(S("abcdefghij"), SV(""), false); + test(S("abcdefghij"), SV("abcde"), false); + test(S("abcdefghij"), SV("abcdefghij"), true); + test(S("abcdefghij"), SV("abcdefghijklmnopqrst"), true); + test(S("abcdefghijklmnopqrst"), SV(""), false); + test(S("abcdefghijklmnopqrst"), SV("abcde"), false); + test(S("abcdefghijklmnopqrst"), SV("abcdefghij"), false); + test(S("abcdefghijklmnopqrst"), SV("abcdefghijklmnopqrst"), true); + } +#endif +} diff --git a/tests/external/libcxx/basic_string/string.nonmembers/string_ople/string_view_string.pass.cpp b/tests/external/libcxx/basic_string/string.nonmembers/string_ople/string_view_string.pass.cpp new file mode 100644 index 0000000..f19a4aa --- /dev/null +++ b/tests/external/libcxx/basic_string/string.nonmembers/string_ople/string_view_string.pass.cpp @@ -0,0 +1,70 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// + +// we get this comparison "for free" because the string implicitly converts to the string_view + +#include +#include + +#include "min_allocator.h" + +template +void +test(SV lhs, const S& rhs, bool x) +{ + assert((lhs <= rhs) == x); +} + +int main() +{ + { + typedef std::string S; + typedef std::string_view SV; + test(SV(""), S(""), true); + test(SV(""), S("abcde"), true); + test(SV(""), S("abcdefghij"), true); + test(SV(""), S("abcdefghijklmnopqrst"), true); + test(SV("abcde"), S(""), false); + test(SV("abcde"), S("abcde"), true); + test(SV("abcde"), S("abcdefghij"), true); + test(SV("abcde"), S("abcdefghijklmnopqrst"), true); + test(SV("abcdefghij"), S(""), false); + test(SV("abcdefghij"), S("abcde"), false); + test(SV("abcdefghij"), S("abcdefghij"), true); + test(SV("abcdefghij"), S("abcdefghijklmnopqrst"), true); + test(SV("abcdefghijklmnopqrst"), S(""), false); + test(SV("abcdefghijklmnopqrst"), S("abcde"), false); + test(SV("abcdefghijklmnopqrst"), S("abcdefghij"), false); + test(SV("abcdefghijklmnopqrst"), S("abcdefghijklmnopqrst"), true); + } +#if TEST_STD_VER >= 11 + { + typedef std::basic_string, min_allocator> S; + typedef std::basic_string_view> SV; + test(SV(""), S(""), true); + test(SV(""), S("abcde"), true); + test(SV(""), S("abcdefghij"), true); + test(SV(""), S("abcdefghijklmnopqrst"), true); + test(SV("abcde"), S(""), false); + test(SV("abcde"), S("abcde"), true); + test(SV("abcde"), S("abcdefghij"), true); + test(SV("abcde"), S("abcdefghijklmnopqrst"), true); + test(SV("abcdefghij"), S(""), false); + test(SV("abcdefghij"), S("abcde"), false); + test(SV("abcdefghij"), S("abcdefghij"), true); + test(SV("abcdefghij"), S("abcdefghijklmnopqrst"), true); + test(SV("abcdefghijklmnopqrst"), S(""), false); + test(SV("abcdefghijklmnopqrst"), S("abcde"), false); + test(SV("abcdefghijklmnopqrst"), S("abcdefghij"), false); + test(SV("abcdefghijklmnopqrst"), S("abcdefghijklmnopqrst"), true); + } +#endif +} diff --git a/tests/external/libcxx/basic_string/string.nonmembers/string_oplt/pointer_string.pass.cpp b/tests/external/libcxx/basic_string/string.nonmembers/string_oplt/pointer_string.pass.cpp new file mode 100644 index 0000000..5c39164 --- /dev/null +++ b/tests/external/libcxx/basic_string/string.nonmembers/string_oplt/pointer_string.pass.cpp @@ -0,0 +1,106 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// Copyright 2019, Intel Corporation +// +// Modified to test pmem::obj containers +// + +#include "unittest.hpp" + +#include +#include +#include +#include +#include + +namespace pmem_exp = pmem::obj::experimental; +namespace nvobj = pmem::obj; + +struct root { + nvobj::persistent_ptr s1, s2, s3, s4; +}; + +template +void +test(const typename S::value_type *lhs, const S &rhs, bool x) +{ + UT_ASSERT((lhs < rhs) == x); +} + +void +run(pmem::obj::pool &pop) +{ + auto r = pop.root(); + + try { + nvobj::transaction::run(pop, [&] { + r->s1 = nvobj::make_persistent(""); + r->s2 = nvobj::make_persistent( + "abcde"); + r->s3 = nvobj::make_persistent( + "abcdefghij"); + r->s4 = nvobj::make_persistent( + "abcdefghijklmnopqrst"); + }); + + test("", *r->s1, false); + test("", *r->s2, true); + test("", *r->s3, true); + test("", *r->s4, true); + test("abcde", *r->s1, false); + test("abcde", *r->s2, false); + test("abcde", *r->s3, true); + test("abcde", *r->s4, true); + test("abcdefghij", *r->s1, false); + test("abcdefghij", *r->s2, false); + test("abcdefghij", *r->s3, false); + test("abcdefghij", *r->s4, true); + test("abcdefghijklmnopqrst", *r->s1, false); + test("abcdefghijklmnopqrst", *r->s2, false); + test("abcdefghijklmnopqrst", *r->s3, false); + test("abcdefghijklmnopqrst", *r->s4, false); + + nvobj::transaction::run(pop, [&] { + nvobj::delete_persistent(r->s1); + nvobj::delete_persistent(r->s2); + nvobj::delete_persistent(r->s3); + nvobj::delete_persistent(r->s4); + }); + } catch (std::exception &e) { + UT_FATALexc(e); + } +} + +int +main(int argc, char *argv[]) +{ + START(); + + if (argc != 2) + UT_FATAL("usage: %s file-name", argv[0]); + + const char *path = argv[1]; + + pmem::obj::pool pop; + + try { + pop = pmem::obj::pool::create(path, "basic_string", + PMEMOBJ_MIN_POOL, + S_IWUSR | S_IRUSR); + } catch (...) { + UT_FATAL("!pmemobj_create: %s", path); + } + + run(pop); + + pop.close(); + + return 0; +} diff --git a/tests/external/libcxx/basic_string/string.nonmembers/string_oplt/string_pointer.pass.cpp b/tests/external/libcxx/basic_string/string.nonmembers/string_oplt/string_pointer.pass.cpp new file mode 100644 index 0000000..0f6388d --- /dev/null +++ b/tests/external/libcxx/basic_string/string.nonmembers/string_oplt/string_pointer.pass.cpp @@ -0,0 +1,106 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// Copyright 2019, Intel Corporation +// +// Modified to test pmem::obj containers +// + +#include "unittest.hpp" + +#include +#include +#include +#include +#include + +namespace pmem_exp = pmem::obj::experimental; +namespace nvobj = pmem::obj; + +struct root { + nvobj::persistent_ptr s1, s2, s3, s4; +}; + +template +void +test(const S &lhs, const typename S::value_type *rhs, bool x) +{ + UT_ASSERT((lhs < rhs) == x); +} + +void +run(pmem::obj::pool &pop) +{ + auto r = pop.root(); + + try { + nvobj::transaction::run(pop, [&] { + r->s1 = nvobj::make_persistent(""); + r->s2 = nvobj::make_persistent( + "abcde"); + r->s3 = nvobj::make_persistent( + "abcdefghij"); + r->s4 = nvobj::make_persistent( + "abcdefghijklmnopqrst"); + }); + + test(*r->s1, "", false); + test(*r->s1, "abcde", true); + test(*r->s1, "abcdefghij", true); + test(*r->s1, "abcdefghijklmnopqrst", true); + test(*r->s2, "", false); + test(*r->s2, "abcde", false); + test(*r->s2, "abcdefghij", true); + test(*r->s2, "abcdefghijklmnopqrst", true); + test(*r->s3, "", false); + test(*r->s3, "abcde", false); + test(*r->s3, "abcdefghij", false); + test(*r->s3, "abcdefghijklmnopqrst", true); + test(*r->s4, "", false); + test(*r->s4, "abcde", false); + test(*r->s4, "abcdefghij", false); + test(*r->s4, "abcdefghijklmnopqrst", false); + + nvobj::transaction::run(pop, [&] { + nvobj::delete_persistent(r->s1); + nvobj::delete_persistent(r->s2); + nvobj::delete_persistent(r->s3); + nvobj::delete_persistent(r->s4); + }); + } catch (std::exception &e) { + UT_FATALexc(e); + } +} + +int +main(int argc, char *argv[]) +{ + START(); + + if (argc != 2) + UT_FATAL("usage: %s file-name", argv[0]); + + const char *path = argv[1]; + + pmem::obj::pool pop; + + try { + pop = pmem::obj::pool::create(path, "basic_string", + PMEMOBJ_MIN_POOL, + S_IWUSR | S_IRUSR); + } catch (...) { + UT_FATAL("!pmemobj_create: %s", path); + } + + run(pop); + + pop.close(); + + return 0; +} diff --git a/tests/external/libcxx/basic_string/string.nonmembers/string_oplt/string_string.pass.cpp b/tests/external/libcxx/basic_string/string.nonmembers/string_oplt/string_string.pass.cpp new file mode 100644 index 0000000..a59ec30 --- /dev/null +++ b/tests/external/libcxx/basic_string/string.nonmembers/string_oplt/string_string.pass.cpp @@ -0,0 +1,106 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// Copyright 2019, Intel Corporation +// +// Modified to test pmem::obj containers +// + +#include "unittest.hpp" + +#include +#include +#include +#include +#include + +namespace pmem_exp = pmem::obj::experimental; +namespace nvobj = pmem::obj; + +struct root { + nvobj::persistent_ptr s1, s2, s3, s4; +}; + +template +void +test(const S &lhs, const S &rhs, bool x) +{ + UT_ASSERT((lhs < rhs) == x); +} + +void +run(pmem::obj::pool &pop) +{ + auto r = pop.root(); + + try { + nvobj::transaction::run(pop, [&] { + r->s1 = nvobj::make_persistent(""); + r->s2 = nvobj::make_persistent( + "abcde"); + r->s3 = nvobj::make_persistent( + "abcdefghij"); + r->s4 = nvobj::make_persistent( + "abcdefghijklmnopqrst"); + }); + + test(*r->s1, *r->s1, false); + test(*r->s1, *r->s2, true); + test(*r->s1, *r->s3, true); + test(*r->s1, *r->s4, true); + test(*r->s2, *r->s1, false); + test(*r->s2, *r->s2, false); + test(*r->s2, *r->s3, true); + test(*r->s2, *r->s4, true); + test(*r->s3, *r->s1, false); + test(*r->s3, *r->s2, false); + test(*r->s3, *r->s3, false); + test(*r->s3, *r->s4, true); + test(*r->s4, *r->s1, false); + test(*r->s4, *r->s2, false); + test(*r->s4, *r->s3, false); + test(*r->s4, *r->s4, false); + + nvobj::transaction::run(pop, [&] { + nvobj::delete_persistent(r->s1); + nvobj::delete_persistent(r->s2); + nvobj::delete_persistent(r->s3); + nvobj::delete_persistent(r->s4); + }); + } catch (std::exception &e) { + UT_FATALexc(e); + } +} + +int +main(int argc, char *argv[]) +{ + START(); + + if (argc != 2) + UT_FATAL("usage: %s file-name", argv[0]); + + const char *path = argv[1]; + + pmem::obj::pool pop; + + try { + pop = pmem::obj::pool::create(path, "basic_string", + PMEMOBJ_MIN_POOL, + S_IWUSR | S_IRUSR); + } catch (...) { + UT_FATAL("!pmemobj_create: %s", path); + } + + run(pop); + + pop.close(); + + return 0; +} diff --git a/tests/external/libcxx/basic_string/string.nonmembers/string_oplt/string_string_view.pass.cpp b/tests/external/libcxx/basic_string/string.nonmembers/string_oplt/string_string_view.pass.cpp new file mode 100644 index 0000000..8fef8e6 --- /dev/null +++ b/tests/external/libcxx/basic_string/string.nonmembers/string_oplt/string_string_view.pass.cpp @@ -0,0 +1,70 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// + +// we get this comparison "for free" because the string implicitly converts to the string_view + +#include +#include + +#include "min_allocator.h" + +template +void +test(const S& lhs, SV rhs, bool x) +{ + assert((lhs < rhs) == x); +} + +int main() +{ + { + typedef std::string S; + typedef std::string_view SV; + test(S(""), SV(""), false); + test(S(""), SV("abcde"), true); + test(S(""), SV("abcdefghij"), true); + test(S(""), SV("abcdefghijklmnopqrst"), true); + test(S("abcde"), SV(""), false); + test(S("abcde"), SV("abcde"), false); + test(S("abcde"), SV("abcdefghij"), true); + test(S("abcde"), SV("abcdefghijklmnopqrst"), true); + test(S("abcdefghij"), SV(""), false); + test(S("abcdefghij"), SV("abcde"), false); + test(S("abcdefghij"), SV("abcdefghij"), false); + test(S("abcdefghij"), SV("abcdefghijklmnopqrst"), true); + test(S("abcdefghijklmnopqrst"), SV(""), false); + test(S("abcdefghijklmnopqrst"), SV("abcde"), false); + test(S("abcdefghijklmnopqrst"), SV("abcdefghij"), false); + test(S("abcdefghijklmnopqrst"), SV("abcdefghijklmnopqrst"), false); + } +#if TEST_STD_VER >= 11 + { + typedef std::basic_string, min_allocator> S; + typedef std::basic_string_view> SV; + test(S(""), SV(""), false); + test(S(""), SV("abcde"), true); + test(S(""), SV("abcdefghij"), true); + test(S(""), SV("abcdefghijklmnopqrst"), true); + test(S("abcde"), SV(""), false); + test(S("abcde"), SV("abcde"), false); + test(S("abcde"), SV("abcdefghij"), true); + test(S("abcde"), SV("abcdefghijklmnopqrst"), true); + test(S("abcdefghij"), SV(""), false); + test(S("abcdefghij"), SV("abcde"), false); + test(S("abcdefghij"), SV("abcdefghij"), false); + test(S("abcdefghij"), SV("abcdefghijklmnopqrst"), true); + test(S("abcdefghijklmnopqrst"), SV(""), false); + test(S("abcdefghijklmnopqrst"), SV("abcde"), false); + test(S("abcdefghijklmnopqrst"), SV("abcdefghij"), false); + test(S("abcdefghijklmnopqrst"), SV("abcdefghijklmnopqrst"), false); + } +#endif +} diff --git a/tests/external/libcxx/basic_string/string.nonmembers/string_oplt/string_view_string.pass.cpp b/tests/external/libcxx/basic_string/string.nonmembers/string_oplt/string_view_string.pass.cpp new file mode 100644 index 0000000..80da8cd --- /dev/null +++ b/tests/external/libcxx/basic_string/string.nonmembers/string_oplt/string_view_string.pass.cpp @@ -0,0 +1,70 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// + +// we get this comparison "for free" because the string implicitly converts to the string_view + +#include +#include + +#include "min_allocator.h" + +template +void +test(SV lhs, const S& rhs, bool x) +{ + assert((lhs < rhs) == x); +} + +int main() +{ + { + typedef std::string S; + typedef std::string_view SV; + test(SV(""), S(""), false); + test(SV(""), S("abcde"), true); + test(SV(""), S("abcdefghij"), true); + test(SV(""), S("abcdefghijklmnopqrst"), true); + test(SV("abcde"), S(""), false); + test(SV("abcde"), S("abcde"), false); + test(SV("abcde"), S("abcdefghij"), true); + test(SV("abcde"), S("abcdefghijklmnopqrst"), true); + test(SV("abcdefghij"), S(""), false); + test(SV("abcdefghij"), S("abcde"), false); + test(SV("abcdefghij"), S("abcdefghij"), false); + test(SV("abcdefghij"), S("abcdefghijklmnopqrst"), true); + test(SV("abcdefghijklmnopqrst"), S(""), false); + test(SV("abcdefghijklmnopqrst"), S("abcde"), false); + test(SV("abcdefghijklmnopqrst"), S("abcdefghij"), false); + test(SV("abcdefghijklmnopqrst"), S("abcdefghijklmnopqrst"), false); + } +#if TEST_STD_VER >= 11 + { + typedef std::basic_string, min_allocator> S; + typedef std::basic_string_view> SV; + test(SV(""), S(""), false); + test(SV(""), S("abcde"), true); + test(SV(""), S("abcdefghij"), true); + test(SV(""), S("abcdefghijklmnopqrst"), true); + test(SV("abcde"), S(""), false); + test(SV("abcde"), S("abcde"), false); + test(SV("abcde"), S("abcdefghij"), true); + test(SV("abcde"), S("abcdefghijklmnopqrst"), true); + test(SV("abcdefghij"), S(""), false); + test(SV("abcdefghij"), S("abcde"), false); + test(SV("abcdefghij"), S("abcdefghij"), false); + test(SV("abcdefghij"), S("abcdefghijklmnopqrst"), true); + test(SV("abcdefghijklmnopqrst"), S(""), false); + test(SV("abcdefghijklmnopqrst"), S("abcde"), false); + test(SV("abcdefghijklmnopqrst"), S("abcdefghij"), false); + test(SV("abcdefghijklmnopqrst"), S("abcdefghijklmnopqrst"), false); + } +#endif +} diff --git a/tests/external/libcxx/basic_string/string.nonmembers/string_opne/pointer_string.pass.cpp b/tests/external/libcxx/basic_string/string.nonmembers/string_opne/pointer_string.pass.cpp new file mode 100644 index 0000000..430f0c6 --- /dev/null +++ b/tests/external/libcxx/basic_string/string.nonmembers/string_opne/pointer_string.pass.cpp @@ -0,0 +1,106 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// Copyright 2019, Intel Corporation +// +// Modified to test pmem::obj containers +// + +#include "unittest.hpp" + +#include +#include +#include +#include +#include + +namespace pmem_exp = pmem::obj::experimental; +namespace nvobj = pmem::obj; + +struct root { + nvobj::persistent_ptr s1, s2, s3, s4; +}; + +template +void +test(const typename S::value_type *lhs, const S &rhs, bool x) +{ + UT_ASSERT((lhs != rhs) == x); +} + +void +run(pmem::obj::pool &pop) +{ + auto r = pop.root(); + + try { + nvobj::transaction::run(pop, [&] { + r->s1 = nvobj::make_persistent(""); + r->s2 = nvobj::make_persistent( + "abcde"); + r->s3 = nvobj::make_persistent( + "abcdefghij"); + r->s4 = nvobj::make_persistent( + "abcdefghijklmnopqrst"); + }); + + test("", *r->s1, false); + test("", *r->s2, true); + test("", *r->s3, true); + test("", *r->s4, true); + test("abcde", *r->s1, true); + test("abcde", *r->s2, false); + test("abcde", *r->s3, true); + test("abcde", *r->s4, true); + test("abcdefghij", *r->s1, true); + test("abcdefghij", *r->s2, true); + test("abcdefghij", *r->s3, false); + test("abcdefghij", *r->s4, true); + test("abcdefghijklmnopqrst", *r->s1, true); + test("abcdefghijklmnopqrst", *r->s2, true); + test("abcdefghijklmnopqrst", *r->s3, true); + test("abcdefghijklmnopqrst", *r->s4, false); + + nvobj::transaction::run(pop, [&] { + nvobj::delete_persistent(r->s1); + nvobj::delete_persistent(r->s2); + nvobj::delete_persistent(r->s3); + nvobj::delete_persistent(r->s4); + }); + } catch (std::exception &e) { + UT_FATALexc(e); + } +} + +int +main(int argc, char *argv[]) +{ + START(); + + if (argc != 2) + UT_FATAL("usage: %s file-name", argv[0]); + + const char *path = argv[1]; + + pmem::obj::pool pop; + + try { + pop = pmem::obj::pool::create(path, "basic_string", + PMEMOBJ_MIN_POOL, + S_IWUSR | S_IRUSR); + } catch (...) { + UT_FATAL("!pmemobj_create: %s", path); + } + + run(pop); + + pop.close(); + + return 0; +} diff --git a/tests/external/libcxx/basic_string/string.nonmembers/string_opne/string_pointer.pass.cpp b/tests/external/libcxx/basic_string/string.nonmembers/string_opne/string_pointer.pass.cpp new file mode 100644 index 0000000..dbdf105 --- /dev/null +++ b/tests/external/libcxx/basic_string/string.nonmembers/string_opne/string_pointer.pass.cpp @@ -0,0 +1,106 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// Copyright 2019, Intel Corporation +// +// Modified to test pmem::obj containers +// + +#include "unittest.hpp" + +#include +#include +#include +#include +#include + +namespace pmem_exp = pmem::obj::experimental; +namespace nvobj = pmem::obj; + +struct root { + nvobj::persistent_ptr s1, s2, s3, s4; +}; + +template +void +test(const S &lhs, const typename S::value_type *rhs, bool x) +{ + UT_ASSERT((lhs != rhs) == x); +} + +void +run(pmem::obj::pool &pop) +{ + auto r = pop.root(); + + try { + nvobj::transaction::run(pop, [&] { + r->s1 = nvobj::make_persistent(""); + r->s2 = nvobj::make_persistent( + "abcde"); + r->s3 = nvobj::make_persistent( + "abcdefghij"); + r->s4 = nvobj::make_persistent( + "abcdefghijklmnopqrst"); + }); + + test(*r->s1, "", false); + test(*r->s1, "abcde", true); + test(*r->s1, "abcdefghij", true); + test(*r->s1, "abcdefghijklmnopqrst", true); + test(*r->s2, "", true); + test(*r->s2, "abcde", false); + test(*r->s2, "abcdefghij", true); + test(*r->s2, "abcdefghijklmnopqrst", true); + test(*r->s3, "", true); + test(*r->s3, "abcde", true); + test(*r->s3, "abcdefghij", false); + test(*r->s3, "abcdefghijklmnopqrst", true); + test(*r->s4, "", true); + test(*r->s4, "abcde", true); + test(*r->s4, "abcdefghij", true); + test(*r->s4, "abcdefghijklmnopqrst", false); + + nvobj::transaction::run(pop, [&] { + nvobj::delete_persistent(r->s1); + nvobj::delete_persistent(r->s2); + nvobj::delete_persistent(r->s3); + nvobj::delete_persistent(r->s4); + }); + } catch (std::exception &e) { + UT_FATALexc(e); + } +} + +int +main(int argc, char *argv[]) +{ + START(); + + if (argc != 2) + UT_FATAL("usage: %s file-name", argv[0]); + + const char *path = argv[1]; + + pmem::obj::pool pop; + + try { + pop = pmem::obj::pool::create(path, "basic_string", + PMEMOBJ_MIN_POOL, + S_IWUSR | S_IRUSR); + } catch (...) { + UT_FATAL("!pmemobj_create: %s", path); + } + + run(pop); + + pop.close(); + + return 0; +} diff --git a/tests/external/libcxx/basic_string/string.nonmembers/string_opne/string_string.pass.cpp b/tests/external/libcxx/basic_string/string.nonmembers/string_opne/string_string.pass.cpp new file mode 100644 index 0000000..45d7078 --- /dev/null +++ b/tests/external/libcxx/basic_string/string.nonmembers/string_opne/string_string.pass.cpp @@ -0,0 +1,106 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// Copyright 2019, Intel Corporation +// +// Modified to test pmem::obj containers +// + +#include "unittest.hpp" + +#include +#include +#include +#include +#include + +namespace pmem_exp = pmem::obj::experimental; +namespace nvobj = pmem::obj; + +struct root { + nvobj::persistent_ptr s1, s2, s3, s4; +}; + +template +void +test(const S &lhs, const S &rhs, bool x) +{ + UT_ASSERT((lhs != rhs) == x); +} + +void +run(pmem::obj::pool &pop) +{ + auto r = pop.root(); + + try { + nvobj::transaction::run(pop, [&] { + r->s1 = nvobj::make_persistent(""); + r->s2 = nvobj::make_persistent( + "abcde"); + r->s3 = nvobj::make_persistent( + "abcdefghij"); + r->s4 = nvobj::make_persistent( + "abcdefghijklmnopqrst"); + }); + + test(*r->s1, *r->s1, false); + test(*r->s1, *r->s2, true); + test(*r->s1, *r->s3, true); + test(*r->s1, *r->s4, true); + test(*r->s2, *r->s1, true); + test(*r->s2, *r->s2, false); + test(*r->s2, *r->s3, true); + test(*r->s2, *r->s4, true); + test(*r->s3, *r->s1, true); + test(*r->s3, *r->s2, true); + test(*r->s3, *r->s3, false); + test(*r->s3, *r->s4, true); + test(*r->s4, *r->s1, true); + test(*r->s4, *r->s2, true); + test(*r->s4, *r->s3, true); + test(*r->s4, *r->s4, false); + + nvobj::transaction::run(pop, [&] { + nvobj::delete_persistent(r->s1); + nvobj::delete_persistent(r->s2); + nvobj::delete_persistent(r->s3); + nvobj::delete_persistent(r->s4); + }); + } catch (std::exception &e) { + UT_FATALexc(e); + } +} + +int +main(int argc, char *argv[]) +{ + START(); + + if (argc != 2) + UT_FATAL("usage: %s file-name", argv[0]); + + const char *path = argv[1]; + + pmem::obj::pool pop; + + try { + pop = pmem::obj::pool::create(path, "basic_string", + PMEMOBJ_MIN_POOL, + S_IWUSR | S_IRUSR); + } catch (...) { + UT_FATAL("!pmemobj_create: %s", path); + } + + run(pop); + + pop.close(); + + return 0; +} diff --git a/tests/external/libcxx/basic_string/string.nonmembers/string_opne/string_string_view.pass.cpp b/tests/external/libcxx/basic_string/string.nonmembers/string_opne/string_string_view.pass.cpp new file mode 100644 index 0000000..6564946 --- /dev/null +++ b/tests/external/libcxx/basic_string/string.nonmembers/string_opne/string_string_view.pass.cpp @@ -0,0 +1,70 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// + +// we get this comparison "for free" because the string implicitly converts to the string_view + +#include +#include + +#include "min_allocator.h" + +template +void +test(const S& lhs, SV rhs, bool x) +{ + assert((lhs != rhs) == x); +} + +int main() +{ + { + typedef std::string S; + typedef std::string SV; + test(S(""), SV(""), false); + test(S(""), SV("abcde"), true); + test(S(""), SV("abcdefghij"), true); + test(S(""), SV("abcdefghijklmnopqrst"), true); + test(S("abcde"), SV(""), true); + test(S("abcde"), SV("abcde"), false); + test(S("abcde"), SV("abcdefghij"), true); + test(S("abcde"), SV("abcdefghijklmnopqrst"), true); + test(S("abcdefghij"), SV(""), true); + test(S("abcdefghij"), SV("abcde"), true); + test(S("abcdefghij"), SV("abcdefghij"), false); + test(S("abcdefghij"), SV("abcdefghijklmnopqrst"), true); + test(S("abcdefghijklmnopqrst"), SV(""), true); + test(S("abcdefghijklmnopqrst"), SV("abcde"), true); + test(S("abcdefghijklmnopqrst"), SV("abcdefghij"), true); + test(S("abcdefghijklmnopqrst"), SV("abcdefghijklmnopqrst"), false); + } +#if TEST_STD_VER >= 11 + { + typedef std::basic_string, min_allocator> S; + typedef std::basic_string_view> SV; + test(S(""), SV(""), false); + test(S(""), SV("abcde"), true); + test(S(""), SV("abcdefghij"), true); + test(S(""), SV("abcdefghijklmnopqrst"), true); + test(S("abcde"), SV(""), true); + test(S("abcde"), SV("abcde"), false); + test(S("abcde"), SV("abcdefghij"), true); + test(S("abcde"), SV("abcdefghijklmnopqrst"), true); + test(S("abcdefghij"), SV(""), true); + test(S("abcdefghij"), SV("abcde"), true); + test(S("abcdefghij"), SV("abcdefghij"), false); + test(S("abcdefghij"), SV("abcdefghijklmnopqrst"), true); + test(S("abcdefghijklmnopqrst"), SV(""), true); + test(S("abcdefghijklmnopqrst"), SV("abcde"), true); + test(S("abcdefghijklmnopqrst"), SV("abcdefghij"), true); + test(S("abcdefghijklmnopqrst"), SV("abcdefghijklmnopqrst"), false); + } +#endif +} diff --git a/tests/external/libcxx/basic_string/string.nonmembers/string_opne/string_view_string.pass.cpp b/tests/external/libcxx/basic_string/string.nonmembers/string_opne/string_view_string.pass.cpp new file mode 100644 index 0000000..88c758c --- /dev/null +++ b/tests/external/libcxx/basic_string/string.nonmembers/string_opne/string_view_string.pass.cpp @@ -0,0 +1,70 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// + +// we get this comparison "for free" because the string implicitly converts to the string_view + +#include +#include + +#include "min_allocator.h" + +template +void +test(SV lhs, const S& rhs, bool x) +{ + assert((lhs != rhs) == x); +} + +int main() +{ + { + typedef std::string S; + typedef std::string_view SV; + test(SV(""), S(""), false); + test(SV(""), S("abcde"), true); + test(SV(""), S("abcdefghij"), true); + test(SV(""), S("abcdefghijklmnopqrst"), true); + test(SV("abcde"), S(""), true); + test(SV("abcde"), S("abcde"), false); + test(SV("abcde"), S("abcdefghij"), true); + test(SV("abcde"), S("abcdefghijklmnopqrst"), true); + test(SV("abcdefghij"), S(""), true); + test(SV("abcdefghij"), S("abcde"), true); + test(SV("abcdefghij"), S("abcdefghij"), false); + test(SV("abcdefghij"), S("abcdefghijklmnopqrst"), true); + test(SV("abcdefghijklmnopqrst"), S(""), true); + test(SV("abcdefghijklmnopqrst"), S("abcde"), true); + test(SV("abcdefghijklmnopqrst"), S("abcdefghij"), true); + test(SV("abcdefghijklmnopqrst"), S("abcdefghijklmnopqrst"), false); + } +#if TEST_STD_VER >= 11 + { + typedef std::basic_string, min_allocator> S; + typedef std::basic_string_view> SV; + test(SV(""), S(""), false); + test(SV(""), S("abcde"), true); + test(SV(""), S("abcdefghij"), true); + test(SV(""), S("abcdefghijklmnopqrst"), true); + test(SV("abcde"), S(""), true); + test(SV("abcde"), S("abcde"), false); + test(SV("abcde"), S("abcdefghij"), true); + test(SV("abcde"), S("abcdefghijklmnopqrst"), true); + test(SV("abcdefghij"), S(""), true); + test(SV("abcdefghij"), S("abcde"), true); + test(SV("abcdefghij"), S("abcdefghij"), false); + test(SV("abcdefghij"), S("abcdefghijklmnopqrst"), true); + test(SV("abcdefghijklmnopqrst"), S(""), true); + test(SV("abcdefghijklmnopqrst"), S("abcde"), true); + test(SV("abcdefghijklmnopqrst"), S("abcdefghij"), true); + test(SV("abcdefghijklmnopqrst"), S("abcdefghijklmnopqrst"), false); + } +#endif +} diff --git a/tests/external/libcxx/basic_string/string.ops/string.accessors/c_str.pass.cpp b/tests/external/libcxx/basic_string/string.ops/string.accessors/c_str.pass.cpp new file mode 100644 index 0000000..d6695b0 --- /dev/null +++ b/tests/external/libcxx/basic_string/string.ops/string.accessors/c_str.pass.cpp @@ -0,0 +1,52 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// + +// const charT* c_str() const; + +#include +#include + +#include "min_allocator.h" + +template +void +test(const S& s) +{ + typedef typename S::traits_type T; + const typename S::value_type* str = s.c_str(); + if (s.size() > 0) + { + assert(T::compare(str, &s[0], s.size()) == 0); + assert(T::eq(str[s.size()], typename S::value_type())); + } + else + assert(T::eq(str[0], typename S::value_type())); +} + +int main() +{ + { + typedef std::string S; + test(S("")); + test(S("abcde")); + test(S("abcdefghij")); + test(S("abcdefghijklmnopqrst")); + } +#if TEST_STD_VER >= 11 + { + typedef std::basic_string, min_allocator> S; + test(S("")); + test(S("abcde")); + test(S("abcdefghij")); + test(S("abcdefghijklmnopqrst")); + } +#endif +} diff --git a/tests/external/libcxx/basic_string/string.ops/string.accessors/data.pass.cpp b/tests/external/libcxx/basic_string/string.ops/string.accessors/data.pass.cpp new file mode 100644 index 0000000..9b66cb0 --- /dev/null +++ b/tests/external/libcxx/basic_string/string.ops/string.accessors/data.pass.cpp @@ -0,0 +1,78 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// + +// const charT* data() const; +// charT* data(); // C++17 + +#include +#include + +#include "test_macros.h" +#include "min_allocator.h" + +template +void +test_const(const S& s) +{ + typedef typename S::traits_type T; + const typename S::value_type* str = s.data(); + if (s.size() > 0) + { + assert(T::compare(str, &s[0], s.size()) == 0); + assert(T::eq(str[s.size()], typename S::value_type())); + } + else + assert(T::eq(str[0], typename S::value_type())); +} + +template +void +test_nonconst(S& s) +{ + typedef typename S::traits_type T; + typename S::value_type* str = s.data(); + if (s.size() > 0) + { + assert(T::compare(str, &s[0], s.size()) == 0); + assert(T::eq(str[s.size()], typename S::value_type())); + } + else + assert(T::eq(str[0], typename S::value_type())); +} + +int main() +{ + { + typedef std::string S; + test_const(S("")); + test_const(S("abcde")); + test_const(S("abcdefghij")); + test_const(S("abcdefghijklmnopqrst")); + } +#if TEST_STD_VER >= 11 + { + typedef std::basic_string, min_allocator> S; + test_const(S("")); + test_const(S("abcde")); + test_const(S("abcdefghij")); + test_const(S("abcdefghijklmnopqrst")); + } +#endif +#if TEST_STD_VER > 14 + { + typedef std::string S; + S s1(""); test_nonconst(s1); + S s2("abcde"); test_nonconst(s2); + S s3("abcdefghij"); test_nonconst(s3); + S s4("abcdefghijklmnopqrst"); test_nonconst(s4); + } +#endif +} diff --git a/tests/external/libcxx/basic_string/string.ops/string.accessors/get_allocator.pass.cpp b/tests/external/libcxx/basic_string/string.ops/string.accessors/get_allocator.pass.cpp new file mode 100644 index 0000000..e50c61f --- /dev/null +++ b/tests/external/libcxx/basic_string/string.ops/string.accessors/get_allocator.pass.cpp @@ -0,0 +1,47 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// + +// allocator_type get_allocator() const; + +#include +#include + +#include "test_allocator.h" +#include "min_allocator.h" + +template +void +test(const S& s, const typename S::allocator_type& a) +{ + assert(s.get_allocator() == a); +} + +int main() +{ + { + typedef test_allocator A; + typedef std::basic_string, A> S; + test(S(""), A()); + test(S("abcde", A(1)), A(1)); + test(S("abcdefghij", A(2)), A(2)); + test(S("abcdefghijklmnopqrst", A(3)), A(3)); + } +#if TEST_STD_VER >= 11 + { + typedef min_allocator A; + typedef std::basic_string, A> S; + test(S(""), A()); + test(S("abcde", A()), A()); + test(S("abcdefghij", A()), A()); + test(S("abcdefghijklmnopqrst", A()), A()); + } +#endif +} diff --git a/tests/external/libcxx/basic_string/string.ops/string_compare/pointer.pass.cpp b/tests/external/libcxx/basic_string/string.ops/string_compare/pointer.pass.cpp new file mode 100644 index 0000000..8b88646 --- /dev/null +++ b/tests/external/libcxx/basic_string/string.ops/string_compare/pointer.pass.cpp @@ -0,0 +1,131 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// Copyright 2019, Intel Corporation +// +// Modified to test pmem::obj containers +// + +#include "unittest.hpp" + +#include +#include +#include +#include +#include + +namespace pmem_exp = pmem::obj::experimental; +namespace nvobj = pmem::obj; + +struct root { + nvobj::persistent_ptr s1, s2, s3, s4, s5; +}; + +int +sign(int x) +{ + if (x == 0) + return 0; + if (x < 0) + return -1; + return 1; +} + +template +void +test(const S &s, const typename S::value_type *str, int x) +{ + UT_ASSERT(sign(s.compare(str)) == sign(x)); +} + +void +run(pmem::obj::pool &pop) +{ + auto r = pop.root(); + + try { + nvobj::transaction::run(pop, [&] { + r->s1 = nvobj::make_persistent(""); + r->s2 = nvobj::make_persistent( + "abcde"); + r->s3 = nvobj::make_persistent( + "abcdefghij"); + r->s4 = nvobj::make_persistent( + "abcdefghijklmnopqrst"); + r->s5 = nvobj::make_persistent( + "12345678901234567890" + "12345678901234567890" + "12345678901234567890" + "1234567890"); + }); + + test(*r->s1, "", 0); + test(*r->s1, "abcde", -5); + test(*r->s1, "abcdefghij", -10); + test(*r->s1, "abcdefghijklmnopqrst", -20); + test(*r->s2, "", 5); + test(*r->s2, "abcde", 0); + test(*r->s2, "abcdefghij", -5); + test(*r->s2, "abcdefghijklmnopqrst", -15); + test(*r->s3, "", 10); + test(*r->s3, "abcde", 5); + test(*r->s3, "abcdefghij", 0); + test(*r->s3, "abcdefghijklmnopqrst", -10); + test(*r->s4, "", 20); + test(*r->s4, "abcde", 15); + test(*r->s4, "abcdefghij", 10); + test(*r->s4, "abcdefghijklmnopqrst", 0); + test(*r->s5, "", 20); + test(*r->s5, "12345", 15); + test(*r->s5, "1234567890", 10); + test(*r->s5, + "12345678901234567890" + "12345678901234567890" + "12345678901234567890" + "1234567890", + 0); + + nvobj::transaction::run(pop, [&] { + nvobj::delete_persistent(r->s1); + nvobj::delete_persistent(r->s2); + nvobj::delete_persistent(r->s3); + nvobj::delete_persistent(r->s4); + nvobj::delete_persistent(r->s5); + }); + } catch (std::exception &e) { + UT_FATALexc(e); + } +} + +int +main(int argc, char *argv[]) +{ + START(); + + if (argc != 2) + UT_FATAL("usage: %s file-name", argv[0]); + + const char *path = argv[1]; + + pmem::obj::pool pop; + + try { + pop = pmem::obj::pool::create(path, "basic_string", + PMEMOBJ_MIN_POOL, + S_IWUSR | S_IRUSR); + } catch (...) { + UT_FATAL("!pmemobj_create: %s", path); + } + + run(pop); + + pop.close(); + + return 0; +} diff --git a/tests/external/libcxx/basic_string/string.ops/string_compare/size_size_T_size_size.pass.cpp b/tests/external/libcxx/basic_string/string.ops/string_compare/size_size_T_size_size.pass.cpp new file mode 100644 index 0000000..94f7890 --- /dev/null +++ b/tests/external/libcxx/basic_string/string.ops/string_compare/size_size_T_size_size.pass.cpp @@ -0,0 +1,5993 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// + +// template +// int compare(size_type pos1, size_type n1, const T& t, +// size_type pos2, size_type n2=npos) const; +// +// Mostly we're testing string_view here + +#include +#include +#include + +#include "min_allocator.h" + +#include "test_macros.h" + +int sign(int x) +{ + if (x == 0) + return 0; + if (x < 0) + return -1; + return 1; +} + +template +void +test(const S& s, typename S::size_type pos1, typename S::size_type n1, + SV sv, typename S::size_type pos2, typename S::size_type n2, int x) +{ + static_assert((!std::is_same::value), ""); + if (pos1 <= s.size() && pos2 <= sv.size()) + assert(sign(s.compare(pos1, n1, sv, pos2, n2)) == sign(x)); +#ifndef TEST_HAS_NO_EXCEPTIONS + else + { + try + { + TEST_IGNORE_NODISCARD s.compare(pos1, n1, sv, pos2, n2); + assert(false); + } + catch (const std::out_of_range&) + { + assert(pos1 > s.size() || pos2 > sv.size()); + } + } +#endif +} + +template +void +test_npos(const S& s, typename S::size_type pos1, typename S::size_type n1, + SV sv, typename S::size_type pos2, int x) +{ + static_assert((!std::is_same::value), ""); + if (pos1 <= s.size() && pos2 <= sv.size()) + assert(sign(s.compare(pos1, n1, sv, pos2)) == sign(x)); +#ifndef TEST_HAS_NO_EXCEPTIONS + else + { + try + { + TEST_IGNORE_NODISCARD s.compare(pos1, n1, sv, pos2); + assert(false); + } + catch (const std::out_of_range&) + { + assert(pos1 > s.size() || pos2 > sv.size()); + } + } +#endif +} + +template +void test0() +{ + test(S(""), 0, 0, SV(""), 0, 0, 0); + test(S(""), 0, 0, SV(""), 0, 1, 0); + test(S(""), 0, 0, SV(""), 1, 0, 0); + test(S(""), 0, 0, SV("abcde"), 0, 0, 0); + test(S(""), 0, 0, SV("abcde"), 0, 1, -1); + test(S(""), 0, 0, SV("abcde"), 0, 2, -2); + test(S(""), 0, 0, SV("abcde"), 0, 4, -4); + test(S(""), 0, 0, SV("abcde"), 0, 5, -5); + test(S(""), 0, 0, SV("abcde"), 0, 6, -5); + test(S(""), 0, 0, SV("abcde"), 1, 0, 0); + test(S(""), 0, 0, SV("abcde"), 1, 1, -1); + test(S(""), 0, 0, SV("abcde"), 1, 2, -2); + test(S(""), 0, 0, SV("abcde"), 1, 3, -3); + test(S(""), 0, 0, SV("abcde"), 1, 4, -4); + test(S(""), 0, 0, SV("abcde"), 1, 5, -4); + test(S(""), 0, 0, SV("abcde"), 2, 0, 0); + test(S(""), 0, 0, SV("abcde"), 2, 1, -1); + test(S(""), 0, 0, SV("abcde"), 2, 2, -2); + test(S(""), 0, 0, SV("abcde"), 2, 3, -3); + test(S(""), 0, 0, SV("abcde"), 2, 4, -3); + test(S(""), 0, 0, SV("abcde"), 4, 0, 0); + test(S(""), 0, 0, SV("abcde"), 4, 1, -1); + test(S(""), 0, 0, SV("abcde"), 4, 2, -1); + test(S(""), 0, 0, SV("abcde"), 5, 0, 0); + test(S(""), 0, 0, SV("abcde"), 5, 1, 0); + test(S(""), 0, 0, SV("abcde"), 6, 0, 0); + test(S(""), 0, 0, SV("abcdefghij"), 0, 0, 0); + test(S(""), 0, 0, SV("abcdefghij"), 0, 1, -1); + test(S(""), 0, 0, SV("abcdefghij"), 0, 5, -5); + test(S(""), 0, 0, SV("abcdefghij"), 0, 9, -9); + test(S(""), 0, 0, SV("abcdefghij"), 0, 10, -10); + test(S(""), 0, 0, SV("abcdefghij"), 0, 11, -10); + test(S(""), 0, 0, SV("abcdefghij"), 1, 0, 0); + test(S(""), 0, 0, SV("abcdefghij"), 1, 1, -1); + test(S(""), 0, 0, SV("abcdefghij"), 1, 4, -4); + test(S(""), 0, 0, SV("abcdefghij"), 1, 8, -8); + test(S(""), 0, 0, SV("abcdefghij"), 1, 9, -9); + test(S(""), 0, 0, SV("abcdefghij"), 1, 10, -9); + test(S(""), 0, 0, SV("abcdefghij"), 5, 0, 0); + test(S(""), 0, 0, SV("abcdefghij"), 5, 1, -1); + test(S(""), 0, 0, SV("abcdefghij"), 5, 2, -2); + test(S(""), 0, 0, SV("abcdefghij"), 5, 4, -4); + test(S(""), 0, 0, SV("abcdefghij"), 5, 5, -5); + test(S(""), 0, 0, SV("abcdefghij"), 5, 6, -5); + test(S(""), 0, 0, SV("abcdefghij"), 9, 0, 0); + test(S(""), 0, 0, SV("abcdefghij"), 9, 1, -1); + test(S(""), 0, 0, SV("abcdefghij"), 9, 2, -1); + test(S(""), 0, 0, SV("abcdefghij"), 10, 0, 0); + test(S(""), 0, 0, SV("abcdefghij"), 10, 1, 0); + test(S(""), 0, 0, SV("abcdefghij"), 11, 0, 0); + test(S(""), 0, 0, SV("abcdefghijklmnopqrst"), 0, 0, 0); + test(S(""), 0, 0, SV("abcdefghijklmnopqrst"), 0, 1, -1); + test(S(""), 0, 0, SV("abcdefghijklmnopqrst"), 0, 10, -10); + test(S(""), 0, 0, SV("abcdefghijklmnopqrst"), 0, 19, -19); + test(S(""), 0, 0, SV("abcdefghijklmnopqrst"), 0, 20, -20); + test(S(""), 0, 0, SV("abcdefghijklmnopqrst"), 0, 21, -20); + test(S(""), 0, 0, SV("abcdefghijklmnopqrst"), 1, 0, 0); + test(S(""), 0, 0, SV("abcdefghijklmnopqrst"), 1, 1, -1); + test(S(""), 0, 0, SV("abcdefghijklmnopqrst"), 1, 9, -9); + test(S(""), 0, 0, SV("abcdefghijklmnopqrst"), 1, 18, -18); + test(S(""), 0, 0, SV("abcdefghijklmnopqrst"), 1, 19, -19); + test(S(""), 0, 0, SV("abcdefghijklmnopqrst"), 1, 20, -19); + test(S(""), 0, 0, SV("abcdefghijklmnopqrst"), 10, 0, 0); + test(S(""), 0, 0, SV("abcdefghijklmnopqrst"), 10, 1, -1); + test(S(""), 0, 0, SV("abcdefghijklmnopqrst"), 10, 5, -5); + test(S(""), 0, 0, SV("abcdefghijklmnopqrst"), 10, 9, -9); + test(S(""), 0, 0, SV("abcdefghijklmnopqrst"), 10, 10, -10); + test(S(""), 0, 0, SV("abcdefghijklmnopqrst"), 10, 11, -10); + test(S(""), 0, 0, SV("abcdefghijklmnopqrst"), 19, 0, 0); + test(S(""), 0, 0, SV("abcdefghijklmnopqrst"), 19, 1, -1); + test(S(""), 0, 0, SV("abcdefghijklmnopqrst"), 19, 2, -1); + test(S(""), 0, 0, SV("abcdefghijklmnopqrst"), 20, 0, 0); + test(S(""), 0, 0, SV("abcdefghijklmnopqrst"), 20, 1, 0); + test(S(""), 0, 0, SV("abcdefghijklmnopqrst"), 21, 0, 0); + test(S(""), 0, 1, SV(""), 0, 0, 0); + test(S(""), 0, 1, SV(""), 0, 1, 0); + test(S(""), 0, 1, SV(""), 1, 0, 0); + test(S(""), 0, 1, SV("abcde"), 0, 0, 0); + test(S(""), 0, 1, SV("abcde"), 0, 1, -1); + test(S(""), 0, 1, SV("abcde"), 0, 2, -2); + test(S(""), 0, 1, SV("abcde"), 0, 4, -4); + test(S(""), 0, 1, SV("abcde"), 0, 5, -5); + test(S(""), 0, 1, SV("abcde"), 0, 6, -5); + test(S(""), 0, 1, SV("abcde"), 1, 0, 0); + test(S(""), 0, 1, SV("abcde"), 1, 1, -1); + test(S(""), 0, 1, SV("abcde"), 1, 2, -2); + test(S(""), 0, 1, SV("abcde"), 1, 3, -3); + test(S(""), 0, 1, SV("abcde"), 1, 4, -4); + test(S(""), 0, 1, SV("abcde"), 1, 5, -4); + test(S(""), 0, 1, SV("abcde"), 2, 0, 0); + test(S(""), 0, 1, SV("abcde"), 2, 1, -1); + test(S(""), 0, 1, SV("abcde"), 2, 2, -2); + test(S(""), 0, 1, SV("abcde"), 2, 3, -3); + test(S(""), 0, 1, SV("abcde"), 2, 4, -3); + test(S(""), 0, 1, SV("abcde"), 4, 0, 0); + test(S(""), 0, 1, SV("abcde"), 4, 1, -1); + test(S(""), 0, 1, SV("abcde"), 4, 2, -1); + test(S(""), 0, 1, SV("abcde"), 5, 0, 0); + test(S(""), 0, 1, SV("abcde"), 5, 1, 0); + test(S(""), 0, 1, SV("abcde"), 6, 0, 0); +} + +template +void test1() +{ + test(S(""), 0, 1, SV("abcdefghij"), 0, 0, 0); + test(S(""), 0, 1, SV("abcdefghij"), 0, 1, -1); + test(S(""), 0, 1, SV("abcdefghij"), 0, 5, -5); + test(S(""), 0, 1, SV("abcdefghij"), 0, 9, -9); + test(S(""), 0, 1, SV("abcdefghij"), 0, 10, -10); + test(S(""), 0, 1, SV("abcdefghij"), 0, 11, -10); + test(S(""), 0, 1, SV("abcdefghij"), 1, 0, 0); + test(S(""), 0, 1, SV("abcdefghij"), 1, 1, -1); + test(S(""), 0, 1, SV("abcdefghij"), 1, 4, -4); + test(S(""), 0, 1, SV("abcdefghij"), 1, 8, -8); + test(S(""), 0, 1, SV("abcdefghij"), 1, 9, -9); + test(S(""), 0, 1, SV("abcdefghij"), 1, 10, -9); + test(S(""), 0, 1, SV("abcdefghij"), 5, 0, 0); + test(S(""), 0, 1, SV("abcdefghij"), 5, 1, -1); + test(S(""), 0, 1, SV("abcdefghij"), 5, 2, -2); + test(S(""), 0, 1, SV("abcdefghij"), 5, 4, -4); + test(S(""), 0, 1, SV("abcdefghij"), 5, 5, -5); + test(S(""), 0, 1, SV("abcdefghij"), 5, 6, -5); + test(S(""), 0, 1, SV("abcdefghij"), 9, 0, 0); + test(S(""), 0, 1, SV("abcdefghij"), 9, 1, -1); + test(S(""), 0, 1, SV("abcdefghij"), 9, 2, -1); + test(S(""), 0, 1, SV("abcdefghij"), 10, 0, 0); + test(S(""), 0, 1, SV("abcdefghij"), 10, 1, 0); + test(S(""), 0, 1, SV("abcdefghij"), 11, 0, 0); + test(S(""), 0, 1, SV("abcdefghijklmnopqrst"), 0, 0, 0); + test(S(""), 0, 1, SV("abcdefghijklmnopqrst"), 0, 1, -1); + test(S(""), 0, 1, SV("abcdefghijklmnopqrst"), 0, 10, -10); + test(S(""), 0, 1, SV("abcdefghijklmnopqrst"), 0, 19, -19); + test(S(""), 0, 1, SV("abcdefghijklmnopqrst"), 0, 20, -20); + test(S(""), 0, 1, SV("abcdefghijklmnopqrst"), 0, 21, -20); + test(S(""), 0, 1, SV("abcdefghijklmnopqrst"), 1, 0, 0); + test(S(""), 0, 1, SV("abcdefghijklmnopqrst"), 1, 1, -1); + test(S(""), 0, 1, SV("abcdefghijklmnopqrst"), 1, 9, -9); + test(S(""), 0, 1, SV("abcdefghijklmnopqrst"), 1, 18, -18); + test(S(""), 0, 1, SV("abcdefghijklmnopqrst"), 1, 19, -19); + test(S(""), 0, 1, SV("abcdefghijklmnopqrst"), 1, 20, -19); + test(S(""), 0, 1, SV("abcdefghijklmnopqrst"), 10, 0, 0); + test(S(""), 0, 1, SV("abcdefghijklmnopqrst"), 10, 1, -1); + test(S(""), 0, 1, SV("abcdefghijklmnopqrst"), 10, 5, -5); + test(S(""), 0, 1, SV("abcdefghijklmnopqrst"), 10, 9, -9); + test(S(""), 0, 1, SV("abcdefghijklmnopqrst"), 10, 10, -10); + test(S(""), 0, 1, SV("abcdefghijklmnopqrst"), 10, 11, -10); + test(S(""), 0, 1, SV("abcdefghijklmnopqrst"), 19, 0, 0); + test(S(""), 0, 1, SV("abcdefghijklmnopqrst"), 19, 1, -1); + test(S(""), 0, 1, SV("abcdefghijklmnopqrst"), 19, 2, -1); + test(S(""), 0, 1, SV("abcdefghijklmnopqrst"), 20, 0, 0); + test(S(""), 0, 1, SV("abcdefghijklmnopqrst"), 20, 1, 0); + test(S(""), 0, 1, SV("abcdefghijklmnopqrst"), 21, 0, 0); + test(S(""), 1, 0, SV(""), 0, 0, 0); + test(S(""), 1, 0, SV(""), 0, 1, 0); + test(S(""), 1, 0, SV(""), 1, 0, 0); + test(S(""), 1, 0, SV("abcde"), 0, 0, 0); + test(S(""), 1, 0, SV("abcde"), 0, 1, 0); + test(S(""), 1, 0, SV("abcde"), 0, 2, 0); + test(S(""), 1, 0, SV("abcde"), 0, 4, 0); + test(S(""), 1, 0, SV("abcde"), 0, 5, 0); + test(S(""), 1, 0, SV("abcde"), 0, 6, 0); + test(S(""), 1, 0, SV("abcde"), 1, 0, 0); + test(S(""), 1, 0, SV("abcde"), 1, 1, 0); + test(S(""), 1, 0, SV("abcde"), 1, 2, 0); + test(S(""), 1, 0, SV("abcde"), 1, 3, 0); + test(S(""), 1, 0, SV("abcde"), 1, 4, 0); + test(S(""), 1, 0, SV("abcde"), 1, 5, 0); + test(S(""), 1, 0, SV("abcde"), 2, 0, 0); + test(S(""), 1, 0, SV("abcde"), 2, 1, 0); + test(S(""), 1, 0, SV("abcde"), 2, 2, 0); + test(S(""), 1, 0, SV("abcde"), 2, 3, 0); + test(S(""), 1, 0, SV("abcde"), 2, 4, 0); + test(S(""), 1, 0, SV("abcde"), 4, 0, 0); + test(S(""), 1, 0, SV("abcde"), 4, 1, 0); + test(S(""), 1, 0, SV("abcde"), 4, 2, 0); + test(S(""), 1, 0, SV("abcde"), 5, 0, 0); + test(S(""), 1, 0, SV("abcde"), 5, 1, 0); + test(S(""), 1, 0, SV("abcde"), 6, 0, 0); + test(S(""), 1, 0, SV("abcdefghij"), 0, 0, 0); + test(S(""), 1, 0, SV("abcdefghij"), 0, 1, 0); + test(S(""), 1, 0, SV("abcdefghij"), 0, 5, 0); + test(S(""), 1, 0, SV("abcdefghij"), 0, 9, 0); + test(S(""), 1, 0, SV("abcdefghij"), 0, 10, 0); + test(S(""), 1, 0, SV("abcdefghij"), 0, 11, 0); + test(S(""), 1, 0, SV("abcdefghij"), 1, 0, 0); + test(S(""), 1, 0, SV("abcdefghij"), 1, 1, 0); + test(S(""), 1, 0, SV("abcdefghij"), 1, 4, 0); + test(S(""), 1, 0, SV("abcdefghij"), 1, 8, 0); + test(S(""), 1, 0, SV("abcdefghij"), 1, 9, 0); + test(S(""), 1, 0, SV("abcdefghij"), 1, 10, 0); + test(S(""), 1, 0, SV("abcdefghij"), 5, 0, 0); + test(S(""), 1, 0, SV("abcdefghij"), 5, 1, 0); + test(S(""), 1, 0, SV("abcdefghij"), 5, 2, 0); + test(S(""), 1, 0, SV("abcdefghij"), 5, 4, 0); + test(S(""), 1, 0, SV("abcdefghij"), 5, 5, 0); + test(S(""), 1, 0, SV("abcdefghij"), 5, 6, 0); + test(S(""), 1, 0, SV("abcdefghij"), 9, 0, 0); + test(S(""), 1, 0, SV("abcdefghij"), 9, 1, 0); + test(S(""), 1, 0, SV("abcdefghij"), 9, 2, 0); + test(S(""), 1, 0, SV("abcdefghij"), 10, 0, 0); + test(S(""), 1, 0, SV("abcdefghij"), 10, 1, 0); + test(S(""), 1, 0, SV("abcdefghij"), 11, 0, 0); + test(S(""), 1, 0, SV("abcdefghijklmnopqrst"), 0, 0, 0); + test(S(""), 1, 0, SV("abcdefghijklmnopqrst"), 0, 1, 0); +} + +template +void test2() +{ + test(S(""), 1, 0, SV("abcdefghijklmnopqrst"), 0, 10, 0); + test(S(""), 1, 0, SV("abcdefghijklmnopqrst"), 0, 19, 0); + test(S(""), 1, 0, SV("abcdefghijklmnopqrst"), 0, 20, 0); + test(S(""), 1, 0, SV("abcdefghijklmnopqrst"), 0, 21, 0); + test(S(""), 1, 0, SV("abcdefghijklmnopqrst"), 1, 0, 0); + test(S(""), 1, 0, SV("abcdefghijklmnopqrst"), 1, 1, 0); + test(S(""), 1, 0, SV("abcdefghijklmnopqrst"), 1, 9, 0); + test(S(""), 1, 0, SV("abcdefghijklmnopqrst"), 1, 18, 0); + test(S(""), 1, 0, SV("abcdefghijklmnopqrst"), 1, 19, 0); + test(S(""), 1, 0, SV("abcdefghijklmnopqrst"), 1, 20, 0); + test(S(""), 1, 0, SV("abcdefghijklmnopqrst"), 10, 0, 0); + test(S(""), 1, 0, SV("abcdefghijklmnopqrst"), 10, 1, 0); + test(S(""), 1, 0, SV("abcdefghijklmnopqrst"), 10, 5, 0); + test(S(""), 1, 0, SV("abcdefghijklmnopqrst"), 10, 9, 0); + test(S(""), 1, 0, SV("abcdefghijklmnopqrst"), 10, 10, 0); + test(S(""), 1, 0, SV("abcdefghijklmnopqrst"), 10, 11, 0); + test(S(""), 1, 0, SV("abcdefghijklmnopqrst"), 19, 0, 0); + test(S(""), 1, 0, SV("abcdefghijklmnopqrst"), 19, 1, 0); + test(S(""), 1, 0, SV("abcdefghijklmnopqrst"), 19, 2, 0); + test(S(""), 1, 0, SV("abcdefghijklmnopqrst"), 20, 0, 0); + test(S(""), 1, 0, SV("abcdefghijklmnopqrst"), 20, 1, 0); + test(S(""), 1, 0, SV("abcdefghijklmnopqrst"), 21, 0, 0); + test(S("abcde"), 0, 0, SV(""), 0, 0, 0); + test(S("abcde"), 0, 0, SV(""), 0, 1, 0); + test(S("abcde"), 0, 0, SV(""), 1, 0, 0); + test(S("abcde"), 0, 0, SV("abcde"), 0, 0, 0); + test(S("abcde"), 0, 0, SV("abcde"), 0, 1, -1); + test(S("abcde"), 0, 0, SV("abcde"), 0, 2, -2); + test(S("abcde"), 0, 0, SV("abcde"), 0, 4, -4); + test(S("abcde"), 0, 0, SV("abcde"), 0, 5, -5); + test(S("abcde"), 0, 0, SV("abcde"), 0, 6, -5); + test(S("abcde"), 0, 0, SV("abcde"), 1, 0, 0); + test(S("abcde"), 0, 0, SV("abcde"), 1, 1, -1); + test(S("abcde"), 0, 0, SV("abcde"), 1, 2, -2); + test(S("abcde"), 0, 0, SV("abcde"), 1, 3, -3); + test(S("abcde"), 0, 0, SV("abcde"), 1, 4, -4); + test(S("abcde"), 0, 0, SV("abcde"), 1, 5, -4); + test(S("abcde"), 0, 0, SV("abcde"), 2, 0, 0); + test(S("abcde"), 0, 0, SV("abcde"), 2, 1, -1); + test(S("abcde"), 0, 0, SV("abcde"), 2, 2, -2); + test(S("abcde"), 0, 0, SV("abcde"), 2, 3, -3); + test(S("abcde"), 0, 0, SV("abcde"), 2, 4, -3); + test(S("abcde"), 0, 0, SV("abcde"), 4, 0, 0); + test(S("abcde"), 0, 0, SV("abcde"), 4, 1, -1); + test(S("abcde"), 0, 0, SV("abcde"), 4, 2, -1); + test(S("abcde"), 0, 0, SV("abcde"), 5, 0, 0); + test(S("abcde"), 0, 0, SV("abcde"), 5, 1, 0); + test(S("abcde"), 0, 0, SV("abcde"), 6, 0, 0); + test(S("abcde"), 0, 0, SV("abcdefghij"), 0, 0, 0); + test(S("abcde"), 0, 0, SV("abcdefghij"), 0, 1, -1); + test(S("abcde"), 0, 0, SV("abcdefghij"), 0, 5, -5); + test(S("abcde"), 0, 0, SV("abcdefghij"), 0, 9, -9); + test(S("abcde"), 0, 0, SV("abcdefghij"), 0, 10, -10); + test(S("abcde"), 0, 0, SV("abcdefghij"), 0, 11, -10); + test(S("abcde"), 0, 0, SV("abcdefghij"), 1, 0, 0); + test(S("abcde"), 0, 0, SV("abcdefghij"), 1, 1, -1); + test(S("abcde"), 0, 0, SV("abcdefghij"), 1, 4, -4); + test(S("abcde"), 0, 0, SV("abcdefghij"), 1, 8, -8); + test(S("abcde"), 0, 0, SV("abcdefghij"), 1, 9, -9); + test(S("abcde"), 0, 0, SV("abcdefghij"), 1, 10, -9); + test(S("abcde"), 0, 0, SV("abcdefghij"), 5, 0, 0); + test(S("abcde"), 0, 0, SV("abcdefghij"), 5, 1, -1); + test(S("abcde"), 0, 0, SV("abcdefghij"), 5, 2, -2); + test(S("abcde"), 0, 0, SV("abcdefghij"), 5, 4, -4); + test(S("abcde"), 0, 0, SV("abcdefghij"), 5, 5, -5); + test(S("abcde"), 0, 0, SV("abcdefghij"), 5, 6, -5); + test(S("abcde"), 0, 0, SV("abcdefghij"), 9, 0, 0); + test(S("abcde"), 0, 0, SV("abcdefghij"), 9, 1, -1); + test(S("abcde"), 0, 0, SV("abcdefghij"), 9, 2, -1); + test(S("abcde"), 0, 0, SV("abcdefghij"), 10, 0, 0); + test(S("abcde"), 0, 0, SV("abcdefghij"), 10, 1, 0); + test(S("abcde"), 0, 0, SV("abcdefghij"), 11, 0, 0); + test(S("abcde"), 0, 0, SV("abcdefghijklmnopqrst"), 0, 0, 0); + test(S("abcde"), 0, 0, SV("abcdefghijklmnopqrst"), 0, 1, -1); + test(S("abcde"), 0, 0, SV("abcdefghijklmnopqrst"), 0, 10, -10); + test(S("abcde"), 0, 0, SV("abcdefghijklmnopqrst"), 0, 19, -19); + test(S("abcde"), 0, 0, SV("abcdefghijklmnopqrst"), 0, 20, -20); + test(S("abcde"), 0, 0, SV("abcdefghijklmnopqrst"), 0, 21, -20); + test(S("abcde"), 0, 0, SV("abcdefghijklmnopqrst"), 1, 0, 0); + test(S("abcde"), 0, 0, SV("abcdefghijklmnopqrst"), 1, 1, -1); + test(S("abcde"), 0, 0, SV("abcdefghijklmnopqrst"), 1, 9, -9); + test(S("abcde"), 0, 0, SV("abcdefghijklmnopqrst"), 1, 18, -18); + test(S("abcde"), 0, 0, SV("abcdefghijklmnopqrst"), 1, 19, -19); + test(S("abcde"), 0, 0, SV("abcdefghijklmnopqrst"), 1, 20, -19); + test(S("abcde"), 0, 0, SV("abcdefghijklmnopqrst"), 10, 0, 0); + test(S("abcde"), 0, 0, SV("abcdefghijklmnopqrst"), 10, 1, -1); + test(S("abcde"), 0, 0, SV("abcdefghijklmnopqrst"), 10, 5, -5); + test(S("abcde"), 0, 0, SV("abcdefghijklmnopqrst"), 10, 9, -9); + test(S("abcde"), 0, 0, SV("abcdefghijklmnopqrst"), 10, 10, -10); + test(S("abcde"), 0, 0, SV("abcdefghijklmnopqrst"), 10, 11, -10); + test(S("abcde"), 0, 0, SV("abcdefghijklmnopqrst"), 19, 0, 0); + test(S("abcde"), 0, 0, SV("abcdefghijklmnopqrst"), 19, 1, -1); + test(S("abcde"), 0, 0, SV("abcdefghijklmnopqrst"), 19, 2, -1); + test(S("abcde"), 0, 0, SV("abcdefghijklmnopqrst"), 20, 0, 0); + test(S("abcde"), 0, 0, SV("abcdefghijklmnopqrst"), 20, 1, 0); + test(S("abcde"), 0, 0, SV("abcdefghijklmnopqrst"), 21, 0, 0); + test(S("abcde"), 0, 1, SV(""), 0, 0, 1); + test(S("abcde"), 0, 1, SV(""), 0, 1, 1); + test(S("abcde"), 0, 1, SV(""), 1, 0, 0); + test(S("abcde"), 0, 1, SV("abcde"), 0, 0, 1); +} + +template +void test3() +{ + test(S("abcde"), 0, 1, SV("abcde"), 0, 1, 0); + test(S("abcde"), 0, 1, SV("abcde"), 0, 2, -1); + test(S("abcde"), 0, 1, SV("abcde"), 0, 4, -3); + test(S("abcde"), 0, 1, SV("abcde"), 0, 5, -4); + test(S("abcde"), 0, 1, SV("abcde"), 0, 6, -4); + test(S("abcde"), 0, 1, SV("abcde"), 1, 0, 1); + test(S("abcde"), 0, 1, SV("abcde"), 1, 1, -1); + test(S("abcde"), 0, 1, SV("abcde"), 1, 2, -1); + test(S("abcde"), 0, 1, SV("abcde"), 1, 3, -1); + test(S("abcde"), 0, 1, SV("abcde"), 1, 4, -1); + test(S("abcde"), 0, 1, SV("abcde"), 1, 5, -1); + test(S("abcde"), 0, 1, SV("abcde"), 2, 0, 1); + test(S("abcde"), 0, 1, SV("abcde"), 2, 1, -2); + test(S("abcde"), 0, 1, SV("abcde"), 2, 2, -2); + test(S("abcde"), 0, 1, SV("abcde"), 2, 3, -2); + test(S("abcde"), 0, 1, SV("abcde"), 2, 4, -2); + test(S("abcde"), 0, 1, SV("abcde"), 4, 0, 1); + test(S("abcde"), 0, 1, SV("abcde"), 4, 1, -4); + test(S("abcde"), 0, 1, SV("abcde"), 4, 2, -4); + test(S("abcde"), 0, 1, SV("abcde"), 5, 0, 1); + test(S("abcde"), 0, 1, SV("abcde"), 5, 1, 1); + test(S("abcde"), 0, 1, SV("abcde"), 6, 0, 0); + test(S("abcde"), 0, 1, SV("abcdefghij"), 0, 0, 1); + test(S("abcde"), 0, 1, SV("abcdefghij"), 0, 1, 0); + test(S("abcde"), 0, 1, SV("abcdefghij"), 0, 5, -4); + test(S("abcde"), 0, 1, SV("abcdefghij"), 0, 9, -8); + test(S("abcde"), 0, 1, SV("abcdefghij"), 0, 10, -9); + test(S("abcde"), 0, 1, SV("abcdefghij"), 0, 11, -9); + test(S("abcde"), 0, 1, SV("abcdefghij"), 1, 0, 1); + test(S("abcde"), 0, 1, SV("abcdefghij"), 1, 1, -1); + test(S("abcde"), 0, 1, SV("abcdefghij"), 1, 4, -1); + test(S("abcde"), 0, 1, SV("abcdefghij"), 1, 8, -1); + test(S("abcde"), 0, 1, SV("abcdefghij"), 1, 9, -1); + test(S("abcde"), 0, 1, SV("abcdefghij"), 1, 10, -1); + test(S("abcde"), 0, 1, SV("abcdefghij"), 5, 0, 1); + test(S("abcde"), 0, 1, SV("abcdefghij"), 5, 1, -5); + test(S("abcde"), 0, 1, SV("abcdefghij"), 5, 2, -5); + test(S("abcde"), 0, 1, SV("abcdefghij"), 5, 4, -5); + test(S("abcde"), 0, 1, SV("abcdefghij"), 5, 5, -5); + test(S("abcde"), 0, 1, SV("abcdefghij"), 5, 6, -5); + test(S("abcde"), 0, 1, SV("abcdefghij"), 9, 0, 1); + test(S("abcde"), 0, 1, SV("abcdefghij"), 9, 1, -9); + test(S("abcde"), 0, 1, SV("abcdefghij"), 9, 2, -9); + test(S("abcde"), 0, 1, SV("abcdefghij"), 10, 0, 1); + test(S("abcde"), 0, 1, SV("abcdefghij"), 10, 1, 1); + test(S("abcde"), 0, 1, SV("abcdefghij"), 11, 0, 0); + test(S("abcde"), 0, 1, SV("abcdefghijklmnopqrst"), 0, 0, 1); + test(S("abcde"), 0, 1, SV("abcdefghijklmnopqrst"), 0, 1, 0); + test(S("abcde"), 0, 1, SV("abcdefghijklmnopqrst"), 0, 10, -9); + test(S("abcde"), 0, 1, SV("abcdefghijklmnopqrst"), 0, 19, -18); + test(S("abcde"), 0, 1, SV("abcdefghijklmnopqrst"), 0, 20, -19); + test(S("abcde"), 0, 1, SV("abcdefghijklmnopqrst"), 0, 21, -19); + test(S("abcde"), 0, 1, SV("abcdefghijklmnopqrst"), 1, 0, 1); + test(S("abcde"), 0, 1, SV("abcdefghijklmnopqrst"), 1, 1, -1); + test(S("abcde"), 0, 1, SV("abcdefghijklmnopqrst"), 1, 9, -1); + test(S("abcde"), 0, 1, SV("abcdefghijklmnopqrst"), 1, 18, -1); + test(S("abcde"), 0, 1, SV("abcdefghijklmnopqrst"), 1, 19, -1); + test(S("abcde"), 0, 1, SV("abcdefghijklmnopqrst"), 1, 20, -1); + test(S("abcde"), 0, 1, SV("abcdefghijklmnopqrst"), 10, 0, 1); + test(S("abcde"), 0, 1, SV("abcdefghijklmnopqrst"), 10, 1, -10); + test(S("abcde"), 0, 1, SV("abcdefghijklmnopqrst"), 10, 5, -10); + test(S("abcde"), 0, 1, SV("abcdefghijklmnopqrst"), 10, 9, -10); + test(S("abcde"), 0, 1, SV("abcdefghijklmnopqrst"), 10, 10, -10); + test(S("abcde"), 0, 1, SV("abcdefghijklmnopqrst"), 10, 11, -10); + test(S("abcde"), 0, 1, SV("abcdefghijklmnopqrst"), 19, 0, 1); + test(S("abcde"), 0, 1, SV("abcdefghijklmnopqrst"), 19, 1, -19); + test(S("abcde"), 0, 1, SV("abcdefghijklmnopqrst"), 19, 2, -19); + test(S("abcde"), 0, 1, SV("abcdefghijklmnopqrst"), 20, 0, 1); + test(S("abcde"), 0, 1, SV("abcdefghijklmnopqrst"), 20, 1, 1); + test(S("abcde"), 0, 1, SV("abcdefghijklmnopqrst"), 21, 0, 0); + test(S("abcde"), 0, 2, SV(""), 0, 0, 2); + test(S("abcde"), 0, 2, SV(""), 0, 1, 2); + test(S("abcde"), 0, 2, SV(""), 1, 0, 0); + test(S("abcde"), 0, 2, SV("abcde"), 0, 0, 2); + test(S("abcde"), 0, 2, SV("abcde"), 0, 1, 1); + test(S("abcde"), 0, 2, SV("abcde"), 0, 2, 0); + test(S("abcde"), 0, 2, SV("abcde"), 0, 4, -2); + test(S("abcde"), 0, 2, SV("abcde"), 0, 5, -3); + test(S("abcde"), 0, 2, SV("abcde"), 0, 6, -3); + test(S("abcde"), 0, 2, SV("abcde"), 1, 0, 2); + test(S("abcde"), 0, 2, SV("abcde"), 1, 1, -1); + test(S("abcde"), 0, 2, SV("abcde"), 1, 2, -1); + test(S("abcde"), 0, 2, SV("abcde"), 1, 3, -1); + test(S("abcde"), 0, 2, SV("abcde"), 1, 4, -1); + test(S("abcde"), 0, 2, SV("abcde"), 1, 5, -1); + test(S("abcde"), 0, 2, SV("abcde"), 2, 0, 2); + test(S("abcde"), 0, 2, SV("abcde"), 2, 1, -2); + test(S("abcde"), 0, 2, SV("abcde"), 2, 2, -2); + test(S("abcde"), 0, 2, SV("abcde"), 2, 3, -2); + test(S("abcde"), 0, 2, SV("abcde"), 2, 4, -2); + test(S("abcde"), 0, 2, SV("abcde"), 4, 0, 2); + test(S("abcde"), 0, 2, SV("abcde"), 4, 1, -4); + test(S("abcde"), 0, 2, SV("abcde"), 4, 2, -4); + test(S("abcde"), 0, 2, SV("abcde"), 5, 0, 2); + test(S("abcde"), 0, 2, SV("abcde"), 5, 1, 2); + test(S("abcde"), 0, 2, SV("abcde"), 6, 0, 0); + test(S("abcde"), 0, 2, SV("abcdefghij"), 0, 0, 2); + test(S("abcde"), 0, 2, SV("abcdefghij"), 0, 1, 1); + test(S("abcde"), 0, 2, SV("abcdefghij"), 0, 5, -3); + test(S("abcde"), 0, 2, SV("abcdefghij"), 0, 9, -7); +} + +template +void test4() +{ + test(S("abcde"), 0, 2, SV("abcdefghij"), 0, 10, -8); + test(S("abcde"), 0, 2, SV("abcdefghij"), 0, 11, -8); + test(S("abcde"), 0, 2, SV("abcdefghij"), 1, 0, 2); + test(S("abcde"), 0, 2, SV("abcdefghij"), 1, 1, -1); + test(S("abcde"), 0, 2, SV("abcdefghij"), 1, 4, -1); + test(S("abcde"), 0, 2, SV("abcdefghij"), 1, 8, -1); + test(S("abcde"), 0, 2, SV("abcdefghij"), 1, 9, -1); + test(S("abcde"), 0, 2, SV("abcdefghij"), 1, 10, -1); + test(S("abcde"), 0, 2, SV("abcdefghij"), 5, 0, 2); + test(S("abcde"), 0, 2, SV("abcdefghij"), 5, 1, -5); + test(S("abcde"), 0, 2, SV("abcdefghij"), 5, 2, -5); + test(S("abcde"), 0, 2, SV("abcdefghij"), 5, 4, -5); + test(S("abcde"), 0, 2, SV("abcdefghij"), 5, 5, -5); + test(S("abcde"), 0, 2, SV("abcdefghij"), 5, 6, -5); + test(S("abcde"), 0, 2, SV("abcdefghij"), 9, 0, 2); + test(S("abcde"), 0, 2, SV("abcdefghij"), 9, 1, -9); + test(S("abcde"), 0, 2, SV("abcdefghij"), 9, 2, -9); + test(S("abcde"), 0, 2, SV("abcdefghij"), 10, 0, 2); + test(S("abcde"), 0, 2, SV("abcdefghij"), 10, 1, 2); + test(S("abcde"), 0, 2, SV("abcdefghij"), 11, 0, 0); + test(S("abcde"), 0, 2, SV("abcdefghijklmnopqrst"), 0, 0, 2); + test(S("abcde"), 0, 2, SV("abcdefghijklmnopqrst"), 0, 1, 1); + test(S("abcde"), 0, 2, SV("abcdefghijklmnopqrst"), 0, 10, -8); + test(S("abcde"), 0, 2, SV("abcdefghijklmnopqrst"), 0, 19, -17); + test(S("abcde"), 0, 2, SV("abcdefghijklmnopqrst"), 0, 20, -18); + test(S("abcde"), 0, 2, SV("abcdefghijklmnopqrst"), 0, 21, -18); + test(S("abcde"), 0, 2, SV("abcdefghijklmnopqrst"), 1, 0, 2); + test(S("abcde"), 0, 2, SV("abcdefghijklmnopqrst"), 1, 1, -1); + test(S("abcde"), 0, 2, SV("abcdefghijklmnopqrst"), 1, 9, -1); + test(S("abcde"), 0, 2, SV("abcdefghijklmnopqrst"), 1, 18, -1); + test(S("abcde"), 0, 2, SV("abcdefghijklmnopqrst"), 1, 19, -1); + test(S("abcde"), 0, 2, SV("abcdefghijklmnopqrst"), 1, 20, -1); + test(S("abcde"), 0, 2, SV("abcdefghijklmnopqrst"), 10, 0, 2); + test(S("abcde"), 0, 2, SV("abcdefghijklmnopqrst"), 10, 1, -10); + test(S("abcde"), 0, 2, SV("abcdefghijklmnopqrst"), 10, 5, -10); + test(S("abcde"), 0, 2, SV("abcdefghijklmnopqrst"), 10, 9, -10); + test(S("abcde"), 0, 2, SV("abcdefghijklmnopqrst"), 10, 10, -10); + test(S("abcde"), 0, 2, SV("abcdefghijklmnopqrst"), 10, 11, -10); + test(S("abcde"), 0, 2, SV("abcdefghijklmnopqrst"), 19, 0, 2); + test(S("abcde"), 0, 2, SV("abcdefghijklmnopqrst"), 19, 1, -19); + test(S("abcde"), 0, 2, SV("abcdefghijklmnopqrst"), 19, 2, -19); + test(S("abcde"), 0, 2, SV("abcdefghijklmnopqrst"), 20, 0, 2); + test(S("abcde"), 0, 2, SV("abcdefghijklmnopqrst"), 20, 1, 2); + test(S("abcde"), 0, 2, SV("abcdefghijklmnopqrst"), 21, 0, 0); + test(S("abcde"), 0, 4, SV(""), 0, 0, 4); + test(S("abcde"), 0, 4, SV(""), 0, 1, 4); + test(S("abcde"), 0, 4, SV(""), 1, 0, 0); + test(S("abcde"), 0, 4, SV("abcde"), 0, 0, 4); + test(S("abcde"), 0, 4, SV("abcde"), 0, 1, 3); + test(S("abcde"), 0, 4, SV("abcde"), 0, 2, 2); + test(S("abcde"), 0, 4, SV("abcde"), 0, 4, 0); + test(S("abcde"), 0, 4, SV("abcde"), 0, 5, -1); + test(S("abcde"), 0, 4, SV("abcde"), 0, 6, -1); + test(S("abcde"), 0, 4, SV("abcde"), 1, 0, 4); + test(S("abcde"), 0, 4, SV("abcde"), 1, 1, -1); + test(S("abcde"), 0, 4, SV("abcde"), 1, 2, -1); + test(S("abcde"), 0, 4, SV("abcde"), 1, 3, -1); + test(S("abcde"), 0, 4, SV("abcde"), 1, 4, -1); + test(S("abcde"), 0, 4, SV("abcde"), 1, 5, -1); + test(S("abcde"), 0, 4, SV("abcde"), 2, 0, 4); + test(S("abcde"), 0, 4, SV("abcde"), 2, 1, -2); + test(S("abcde"), 0, 4, SV("abcde"), 2, 2, -2); + test(S("abcde"), 0, 4, SV("abcde"), 2, 3, -2); + test(S("abcde"), 0, 4, SV("abcde"), 2, 4, -2); + test(S("abcde"), 0, 4, SV("abcde"), 4, 0, 4); + test(S("abcde"), 0, 4, SV("abcde"), 4, 1, -4); + test(S("abcde"), 0, 4, SV("abcde"), 4, 2, -4); + test(S("abcde"), 0, 4, SV("abcde"), 5, 0, 4); + test(S("abcde"), 0, 4, SV("abcde"), 5, 1, 4); + test(S("abcde"), 0, 4, SV("abcde"), 6, 0, 0); + test(S("abcde"), 0, 4, SV("abcdefghij"), 0, 0, 4); + test(S("abcde"), 0, 4, SV("abcdefghij"), 0, 1, 3); + test(S("abcde"), 0, 4, SV("abcdefghij"), 0, 5, -1); + test(S("abcde"), 0, 4, SV("abcdefghij"), 0, 9, -5); + test(S("abcde"), 0, 4, SV("abcdefghij"), 0, 10, -6); + test(S("abcde"), 0, 4, SV("abcdefghij"), 0, 11, -6); + test(S("abcde"), 0, 4, SV("abcdefghij"), 1, 0, 4); + test(S("abcde"), 0, 4, SV("abcdefghij"), 1, 1, -1); + test(S("abcde"), 0, 4, SV("abcdefghij"), 1, 4, -1); + test(S("abcde"), 0, 4, SV("abcdefghij"), 1, 8, -1); + test(S("abcde"), 0, 4, SV("abcdefghij"), 1, 9, -1); + test(S("abcde"), 0, 4, SV("abcdefghij"), 1, 10, -1); + test(S("abcde"), 0, 4, SV("abcdefghij"), 5, 0, 4); + test(S("abcde"), 0, 4, SV("abcdefghij"), 5, 1, -5); + test(S("abcde"), 0, 4, SV("abcdefghij"), 5, 2, -5); + test(S("abcde"), 0, 4, SV("abcdefghij"), 5, 4, -5); + test(S("abcde"), 0, 4, SV("abcdefghij"), 5, 5, -5); + test(S("abcde"), 0, 4, SV("abcdefghij"), 5, 6, -5); + test(S("abcde"), 0, 4, SV("abcdefghij"), 9, 0, 4); + test(S("abcde"), 0, 4, SV("abcdefghij"), 9, 1, -9); + test(S("abcde"), 0, 4, SV("abcdefghij"), 9, 2, -9); + test(S("abcde"), 0, 4, SV("abcdefghij"), 10, 0, 4); + test(S("abcde"), 0, 4, SV("abcdefghij"), 10, 1, 4); + test(S("abcde"), 0, 4, SV("abcdefghij"), 11, 0, 0); + test(S("abcde"), 0, 4, SV("abcdefghijklmnopqrst"), 0, 0, 4); + test(S("abcde"), 0, 4, SV("abcdefghijklmnopqrst"), 0, 1, 3); + test(S("abcde"), 0, 4, SV("abcdefghijklmnopqrst"), 0, 10, -6); + test(S("abcde"), 0, 4, SV("abcdefghijklmnopqrst"), 0, 19, -15); + test(S("abcde"), 0, 4, SV("abcdefghijklmnopqrst"), 0, 20, -16); + test(S("abcde"), 0, 4, SV("abcdefghijklmnopqrst"), 0, 21, -16); +} + +template +void test5() +{ + test(S("abcde"), 0, 4, SV("abcdefghijklmnopqrst"), 1, 0, 4); + test(S("abcde"), 0, 4, SV("abcdefghijklmnopqrst"), 1, 1, -1); + test(S("abcde"), 0, 4, SV("abcdefghijklmnopqrst"), 1, 9, -1); + test(S("abcde"), 0, 4, SV("abcdefghijklmnopqrst"), 1, 18, -1); + test(S("abcde"), 0, 4, SV("abcdefghijklmnopqrst"), 1, 19, -1); + test(S("abcde"), 0, 4, SV("abcdefghijklmnopqrst"), 1, 20, -1); + test(S("abcde"), 0, 4, SV("abcdefghijklmnopqrst"), 10, 0, 4); + test(S("abcde"), 0, 4, SV("abcdefghijklmnopqrst"), 10, 1, -10); + test(S("abcde"), 0, 4, SV("abcdefghijklmnopqrst"), 10, 5, -10); + test(S("abcde"), 0, 4, SV("abcdefghijklmnopqrst"), 10, 9, -10); + test(S("abcde"), 0, 4, SV("abcdefghijklmnopqrst"), 10, 10, -10); + test(S("abcde"), 0, 4, SV("abcdefghijklmnopqrst"), 10, 11, -10); + test(S("abcde"), 0, 4, SV("abcdefghijklmnopqrst"), 19, 0, 4); + test(S("abcde"), 0, 4, SV("abcdefghijklmnopqrst"), 19, 1, -19); + test(S("abcde"), 0, 4, SV("abcdefghijklmnopqrst"), 19, 2, -19); + test(S("abcde"), 0, 4, SV("abcdefghijklmnopqrst"), 20, 0, 4); + test(S("abcde"), 0, 4, SV("abcdefghijklmnopqrst"), 20, 1, 4); + test(S("abcde"), 0, 4, SV("abcdefghijklmnopqrst"), 21, 0, 0); + test(S("abcde"), 0, 5, SV(""), 0, 0, 5); + test(S("abcde"), 0, 5, SV(""), 0, 1, 5); + test(S("abcde"), 0, 5, SV(""), 1, 0, 0); + test(S("abcde"), 0, 5, SV("abcde"), 0, 0, 5); + test(S("abcde"), 0, 5, SV("abcde"), 0, 1, 4); + test(S("abcde"), 0, 5, SV("abcde"), 0, 2, 3); + test(S("abcde"), 0, 5, SV("abcde"), 0, 4, 1); + test(S("abcde"), 0, 5, SV("abcde"), 0, 5, 0); + test(S("abcde"), 0, 5, SV("abcde"), 0, 6, 0); + test(S("abcde"), 0, 5, SV("abcde"), 1, 0, 5); + test(S("abcde"), 0, 5, SV("abcde"), 1, 1, -1); + test(S("abcde"), 0, 5, SV("abcde"), 1, 2, -1); + test(S("abcde"), 0, 5, SV("abcde"), 1, 3, -1); + test(S("abcde"), 0, 5, SV("abcde"), 1, 4, -1); + test(S("abcde"), 0, 5, SV("abcde"), 1, 5, -1); + test(S("abcde"), 0, 5, SV("abcde"), 2, 0, 5); + test(S("abcde"), 0, 5, SV("abcde"), 2, 1, -2); + test(S("abcde"), 0, 5, SV("abcde"), 2, 2, -2); + test(S("abcde"), 0, 5, SV("abcde"), 2, 3, -2); + test(S("abcde"), 0, 5, SV("abcde"), 2, 4, -2); + test(S("abcde"), 0, 5, SV("abcde"), 4, 0, 5); + test(S("abcde"), 0, 5, SV("abcde"), 4, 1, -4); + test(S("abcde"), 0, 5, SV("abcde"), 4, 2, -4); + test(S("abcde"), 0, 5, SV("abcde"), 5, 0, 5); + test(S("abcde"), 0, 5, SV("abcde"), 5, 1, 5); + test(S("abcde"), 0, 5, SV("abcde"), 6, 0, 0); + test(S("abcde"), 0, 5, SV("abcdefghij"), 0, 0, 5); + test(S("abcde"), 0, 5, SV("abcdefghij"), 0, 1, 4); + test(S("abcde"), 0, 5, SV("abcdefghij"), 0, 5, 0); + test(S("abcde"), 0, 5, SV("abcdefghij"), 0, 9, -4); + test(S("abcde"), 0, 5, SV("abcdefghij"), 0, 10, -5); + test(S("abcde"), 0, 5, SV("abcdefghij"), 0, 11, -5); + test(S("abcde"), 0, 5, SV("abcdefghij"), 1, 0, 5); + test(S("abcde"), 0, 5, SV("abcdefghij"), 1, 1, -1); + test(S("abcde"), 0, 5, SV("abcdefghij"), 1, 4, -1); + test(S("abcde"), 0, 5, SV("abcdefghij"), 1, 8, -1); + test(S("abcde"), 0, 5, SV("abcdefghij"), 1, 9, -1); + test(S("abcde"), 0, 5, SV("abcdefghij"), 1, 10, -1); + test(S("abcde"), 0, 5, SV("abcdefghij"), 5, 0, 5); + test(S("abcde"), 0, 5, SV("abcdefghij"), 5, 1, -5); + test(S("abcde"), 0, 5, SV("abcdefghij"), 5, 2, -5); + test(S("abcde"), 0, 5, SV("abcdefghij"), 5, 4, -5); + test(S("abcde"), 0, 5, SV("abcdefghij"), 5, 5, -5); + test(S("abcde"), 0, 5, SV("abcdefghij"), 5, 6, -5); + test(S("abcde"), 0, 5, SV("abcdefghij"), 9, 0, 5); + test(S("abcde"), 0, 5, SV("abcdefghij"), 9, 1, -9); + test(S("abcde"), 0, 5, SV("abcdefghij"), 9, 2, -9); + test(S("abcde"), 0, 5, SV("abcdefghij"), 10, 0, 5); + test(S("abcde"), 0, 5, SV("abcdefghij"), 10, 1, 5); + test(S("abcde"), 0, 5, SV("abcdefghij"), 11, 0, 0); + test(S("abcde"), 0, 5, SV("abcdefghijklmnopqrst"), 0, 0, 5); + test(S("abcde"), 0, 5, SV("abcdefghijklmnopqrst"), 0, 1, 4); + test(S("abcde"), 0, 5, SV("abcdefghijklmnopqrst"), 0, 10, -5); + test(S("abcde"), 0, 5, SV("abcdefghijklmnopqrst"), 0, 19, -14); + test(S("abcde"), 0, 5, SV("abcdefghijklmnopqrst"), 0, 20, -15); + test(S("abcde"), 0, 5, SV("abcdefghijklmnopqrst"), 0, 21, -15); + test(S("abcde"), 0, 5, SV("abcdefghijklmnopqrst"), 1, 0, 5); + test(S("abcde"), 0, 5, SV("abcdefghijklmnopqrst"), 1, 1, -1); + test(S("abcde"), 0, 5, SV("abcdefghijklmnopqrst"), 1, 9, -1); + test(S("abcde"), 0, 5, SV("abcdefghijklmnopqrst"), 1, 18, -1); + test(S("abcde"), 0, 5, SV("abcdefghijklmnopqrst"), 1, 19, -1); + test(S("abcde"), 0, 5, SV("abcdefghijklmnopqrst"), 1, 20, -1); + test(S("abcde"), 0, 5, SV("abcdefghijklmnopqrst"), 10, 0, 5); + test(S("abcde"), 0, 5, SV("abcdefghijklmnopqrst"), 10, 1, -10); + test(S("abcde"), 0, 5, SV("abcdefghijklmnopqrst"), 10, 5, -10); + test(S("abcde"), 0, 5, SV("abcdefghijklmnopqrst"), 10, 9, -10); + test(S("abcde"), 0, 5, SV("abcdefghijklmnopqrst"), 10, 10, -10); + test(S("abcde"), 0, 5, SV("abcdefghijklmnopqrst"), 10, 11, -10); + test(S("abcde"), 0, 5, SV("abcdefghijklmnopqrst"), 19, 0, 5); + test(S("abcde"), 0, 5, SV("abcdefghijklmnopqrst"), 19, 1, -19); + test(S("abcde"), 0, 5, SV("abcdefghijklmnopqrst"), 19, 2, -19); + test(S("abcde"), 0, 5, SV("abcdefghijklmnopqrst"), 20, 0, 5); + test(S("abcde"), 0, 5, SV("abcdefghijklmnopqrst"), 20, 1, 5); + test(S("abcde"), 0, 5, SV("abcdefghijklmnopqrst"), 21, 0, 0); + test(S("abcde"), 0, 6, SV(""), 0, 0, 5); + test(S("abcde"), 0, 6, SV(""), 0, 1, 5); + test(S("abcde"), 0, 6, SV(""), 1, 0, 0); + test(S("abcde"), 0, 6, SV("abcde"), 0, 0, 5); + test(S("abcde"), 0, 6, SV("abcde"), 0, 1, 4); + test(S("abcde"), 0, 6, SV("abcde"), 0, 2, 3); + test(S("abcde"), 0, 6, SV("abcde"), 0, 4, 1); + test(S("abcde"), 0, 6, SV("abcde"), 0, 5, 0); +} + +template +void test6() +{ + test(S("abcde"), 0, 6, SV("abcde"), 0, 6, 0); + test(S("abcde"), 0, 6, SV("abcde"), 1, 0, 5); + test(S("abcde"), 0, 6, SV("abcde"), 1, 1, -1); + test(S("abcde"), 0, 6, SV("abcde"), 1, 2, -1); + test(S("abcde"), 0, 6, SV("abcde"), 1, 3, -1); + test(S("abcde"), 0, 6, SV("abcde"), 1, 4, -1); + test(S("abcde"), 0, 6, SV("abcde"), 1, 5, -1); + test(S("abcde"), 0, 6, SV("abcde"), 2, 0, 5); + test(S("abcde"), 0, 6, SV("abcde"), 2, 1, -2); + test(S("abcde"), 0, 6, SV("abcde"), 2, 2, -2); + test(S("abcde"), 0, 6, SV("abcde"), 2, 3, -2); + test(S("abcde"), 0, 6, SV("abcde"), 2, 4, -2); + test(S("abcde"), 0, 6, SV("abcde"), 4, 0, 5); + test(S("abcde"), 0, 6, SV("abcde"), 4, 1, -4); + test(S("abcde"), 0, 6, SV("abcde"), 4, 2, -4); + test(S("abcde"), 0, 6, SV("abcde"), 5, 0, 5); + test(S("abcde"), 0, 6, SV("abcde"), 5, 1, 5); + test(S("abcde"), 0, 6, SV("abcde"), 6, 0, 0); + test(S("abcde"), 0, 6, SV("abcdefghij"), 0, 0, 5); + test(S("abcde"), 0, 6, SV("abcdefghij"), 0, 1, 4); + test(S("abcde"), 0, 6, SV("abcdefghij"), 0, 5, 0); + test(S("abcde"), 0, 6, SV("abcdefghij"), 0, 9, -4); + test(S("abcde"), 0, 6, SV("abcdefghij"), 0, 10, -5); + test(S("abcde"), 0, 6, SV("abcdefghij"), 0, 11, -5); + test(S("abcde"), 0, 6, SV("abcdefghij"), 1, 0, 5); + test(S("abcde"), 0, 6, SV("abcdefghij"), 1, 1, -1); + test(S("abcde"), 0, 6, SV("abcdefghij"), 1, 4, -1); + test(S("abcde"), 0, 6, SV("abcdefghij"), 1, 8, -1); + test(S("abcde"), 0, 6, SV("abcdefghij"), 1, 9, -1); + test(S("abcde"), 0, 6, SV("abcdefghij"), 1, 10, -1); + test(S("abcde"), 0, 6, SV("abcdefghij"), 5, 0, 5); + test(S("abcde"), 0, 6, SV("abcdefghij"), 5, 1, -5); + test(S("abcde"), 0, 6, SV("abcdefghij"), 5, 2, -5); + test(S("abcde"), 0, 6, SV("abcdefghij"), 5, 4, -5); + test(S("abcde"), 0, 6, SV("abcdefghij"), 5, 5, -5); + test(S("abcde"), 0, 6, SV("abcdefghij"), 5, 6, -5); + test(S("abcde"), 0, 6, SV("abcdefghij"), 9, 0, 5); + test(S("abcde"), 0, 6, SV("abcdefghij"), 9, 1, -9); + test(S("abcde"), 0, 6, SV("abcdefghij"), 9, 2, -9); + test(S("abcde"), 0, 6, SV("abcdefghij"), 10, 0, 5); + test(S("abcde"), 0, 6, SV("abcdefghij"), 10, 1, 5); + test(S("abcde"), 0, 6, SV("abcdefghij"), 11, 0, 0); + test(S("abcde"), 0, 6, SV("abcdefghijklmnopqrst"), 0, 0, 5); + test(S("abcde"), 0, 6, SV("abcdefghijklmnopqrst"), 0, 1, 4); + test(S("abcde"), 0, 6, SV("abcdefghijklmnopqrst"), 0, 10, -5); + test(S("abcde"), 0, 6, SV("abcdefghijklmnopqrst"), 0, 19, -14); + test(S("abcde"), 0, 6, SV("abcdefghijklmnopqrst"), 0, 20, -15); + test(S("abcde"), 0, 6, SV("abcdefghijklmnopqrst"), 0, 21, -15); + test(S("abcde"), 0, 6, SV("abcdefghijklmnopqrst"), 1, 0, 5); + test(S("abcde"), 0, 6, SV("abcdefghijklmnopqrst"), 1, 1, -1); + test(S("abcde"), 0, 6, SV("abcdefghijklmnopqrst"), 1, 9, -1); + test(S("abcde"), 0, 6, SV("abcdefghijklmnopqrst"), 1, 18, -1); + test(S("abcde"), 0, 6, SV("abcdefghijklmnopqrst"), 1, 19, -1); + test(S("abcde"), 0, 6, SV("abcdefghijklmnopqrst"), 1, 20, -1); + test(S("abcde"), 0, 6, SV("abcdefghijklmnopqrst"), 10, 0, 5); + test(S("abcde"), 0, 6, SV("abcdefghijklmnopqrst"), 10, 1, -10); + test(S("abcde"), 0, 6, SV("abcdefghijklmnopqrst"), 10, 5, -10); + test(S("abcde"), 0, 6, SV("abcdefghijklmnopqrst"), 10, 9, -10); + test(S("abcde"), 0, 6, SV("abcdefghijklmnopqrst"), 10, 10, -10); + test(S("abcde"), 0, 6, SV("abcdefghijklmnopqrst"), 10, 11, -10); + test(S("abcde"), 0, 6, SV("abcdefghijklmnopqrst"), 19, 0, 5); + test(S("abcde"), 0, 6, SV("abcdefghijklmnopqrst"), 19, 1, -19); + test(S("abcde"), 0, 6, SV("abcdefghijklmnopqrst"), 19, 2, -19); + test(S("abcde"), 0, 6, SV("abcdefghijklmnopqrst"), 20, 0, 5); + test(S("abcde"), 0, 6, SV("abcdefghijklmnopqrst"), 20, 1, 5); + test(S("abcde"), 0, 6, SV("abcdefghijklmnopqrst"), 21, 0, 0); + test(S("abcde"), 1, 0, SV(""), 0, 0, 0); + test(S("abcde"), 1, 0, SV(""), 0, 1, 0); + test(S("abcde"), 1, 0, SV(""), 1, 0, 0); + test(S("abcde"), 1, 0, SV("abcde"), 0, 0, 0); + test(S("abcde"), 1, 0, SV("abcde"), 0, 1, -1); + test(S("abcde"), 1, 0, SV("abcde"), 0, 2, -2); + test(S("abcde"), 1, 0, SV("abcde"), 0, 4, -4); + test(S("abcde"), 1, 0, SV("abcde"), 0, 5, -5); + test(S("abcde"), 1, 0, SV("abcde"), 0, 6, -5); + test(S("abcde"), 1, 0, SV("abcde"), 1, 0, 0); + test(S("abcde"), 1, 0, SV("abcde"), 1, 1, -1); + test(S("abcde"), 1, 0, SV("abcde"), 1, 2, -2); + test(S("abcde"), 1, 0, SV("abcde"), 1, 3, -3); + test(S("abcde"), 1, 0, SV("abcde"), 1, 4, -4); + test(S("abcde"), 1, 0, SV("abcde"), 1, 5, -4); + test(S("abcde"), 1, 0, SV("abcde"), 2, 0, 0); + test(S("abcde"), 1, 0, SV("abcde"), 2, 1, -1); + test(S("abcde"), 1, 0, SV("abcde"), 2, 2, -2); + test(S("abcde"), 1, 0, SV("abcde"), 2, 3, -3); + test(S("abcde"), 1, 0, SV("abcde"), 2, 4, -3); + test(S("abcde"), 1, 0, SV("abcde"), 4, 0, 0); + test(S("abcde"), 1, 0, SV("abcde"), 4, 1, -1); + test(S("abcde"), 1, 0, SV("abcde"), 4, 2, -1); + test(S("abcde"), 1, 0, SV("abcde"), 5, 0, 0); + test(S("abcde"), 1, 0, SV("abcde"), 5, 1, 0); + test(S("abcde"), 1, 0, SV("abcde"), 6, 0, 0); + test(S("abcde"), 1, 0, SV("abcdefghij"), 0, 0, 0); + test(S("abcde"), 1, 0, SV("abcdefghij"), 0, 1, -1); + test(S("abcde"), 1, 0, SV("abcdefghij"), 0, 5, -5); + test(S("abcde"), 1, 0, SV("abcdefghij"), 0, 9, -9); + test(S("abcde"), 1, 0, SV("abcdefghij"), 0, 10, -10); + test(S("abcde"), 1, 0, SV("abcdefghij"), 0, 11, -10); + test(S("abcde"), 1, 0, SV("abcdefghij"), 1, 0, 0); + test(S("abcde"), 1, 0, SV("abcdefghij"), 1, 1, -1); +} + +template +void test7() +{ + test(S("abcde"), 1, 0, SV("abcdefghij"), 1, 4, -4); + test(S("abcde"), 1, 0, SV("abcdefghij"), 1, 8, -8); + test(S("abcde"), 1, 0, SV("abcdefghij"), 1, 9, -9); + test(S("abcde"), 1, 0, SV("abcdefghij"), 1, 10, -9); + test(S("abcde"), 1, 0, SV("abcdefghij"), 5, 0, 0); + test(S("abcde"), 1, 0, SV("abcdefghij"), 5, 1, -1); + test(S("abcde"), 1, 0, SV("abcdefghij"), 5, 2, -2); + test(S("abcde"), 1, 0, SV("abcdefghij"), 5, 4, -4); + test(S("abcde"), 1, 0, SV("abcdefghij"), 5, 5, -5); + test(S("abcde"), 1, 0, SV("abcdefghij"), 5, 6, -5); + test(S("abcde"), 1, 0, SV("abcdefghij"), 9, 0, 0); + test(S("abcde"), 1, 0, SV("abcdefghij"), 9, 1, -1); + test(S("abcde"), 1, 0, SV("abcdefghij"), 9, 2, -1); + test(S("abcde"), 1, 0, SV("abcdefghij"), 10, 0, 0); + test(S("abcde"), 1, 0, SV("abcdefghij"), 10, 1, 0); + test(S("abcde"), 1, 0, SV("abcdefghij"), 11, 0, 0); + test(S("abcde"), 1, 0, SV("abcdefghijklmnopqrst"), 0, 0, 0); + test(S("abcde"), 1, 0, SV("abcdefghijklmnopqrst"), 0, 1, -1); + test(S("abcde"), 1, 0, SV("abcdefghijklmnopqrst"), 0, 10, -10); + test(S("abcde"), 1, 0, SV("abcdefghijklmnopqrst"), 0, 19, -19); + test(S("abcde"), 1, 0, SV("abcdefghijklmnopqrst"), 0, 20, -20); + test(S("abcde"), 1, 0, SV("abcdefghijklmnopqrst"), 0, 21, -20); + test(S("abcde"), 1, 0, SV("abcdefghijklmnopqrst"), 1, 0, 0); + test(S("abcde"), 1, 0, SV("abcdefghijklmnopqrst"), 1, 1, -1); + test(S("abcde"), 1, 0, SV("abcdefghijklmnopqrst"), 1, 9, -9); + test(S("abcde"), 1, 0, SV("abcdefghijklmnopqrst"), 1, 18, -18); + test(S("abcde"), 1, 0, SV("abcdefghijklmnopqrst"), 1, 19, -19); + test(S("abcde"), 1, 0, SV("abcdefghijklmnopqrst"), 1, 20, -19); + test(S("abcde"), 1, 0, SV("abcdefghijklmnopqrst"), 10, 0, 0); + test(S("abcde"), 1, 0, SV("abcdefghijklmnopqrst"), 10, 1, -1); + test(S("abcde"), 1, 0, SV("abcdefghijklmnopqrst"), 10, 5, -5); + test(S("abcde"), 1, 0, SV("abcdefghijklmnopqrst"), 10, 9, -9); + test(S("abcde"), 1, 0, SV("abcdefghijklmnopqrst"), 10, 10, -10); + test(S("abcde"), 1, 0, SV("abcdefghijklmnopqrst"), 10, 11, -10); + test(S("abcde"), 1, 0, SV("abcdefghijklmnopqrst"), 19, 0, 0); + test(S("abcde"), 1, 0, SV("abcdefghijklmnopqrst"), 19, 1, -1); + test(S("abcde"), 1, 0, SV("abcdefghijklmnopqrst"), 19, 2, -1); + test(S("abcde"), 1, 0, SV("abcdefghijklmnopqrst"), 20, 0, 0); + test(S("abcde"), 1, 0, SV("abcdefghijklmnopqrst"), 20, 1, 0); + test(S("abcde"), 1, 0, SV("abcdefghijklmnopqrst"), 21, 0, 0); + test(S("abcde"), 1, 1, SV(""), 0, 0, 1); + test(S("abcde"), 1, 1, SV(""), 0, 1, 1); + test(S("abcde"), 1, 1, SV(""), 1, 0, 0); + test(S("abcde"), 1, 1, SV("abcde"), 0, 0, 1); + test(S("abcde"), 1, 1, SV("abcde"), 0, 1, 1); + test(S("abcde"), 1, 1, SV("abcde"), 0, 2, 1); + test(S("abcde"), 1, 1, SV("abcde"), 0, 4, 1); + test(S("abcde"), 1, 1, SV("abcde"), 0, 5, 1); + test(S("abcde"), 1, 1, SV("abcde"), 0, 6, 1); + test(S("abcde"), 1, 1, SV("abcde"), 1, 0, 1); + test(S("abcde"), 1, 1, SV("abcde"), 1, 1, 0); + test(S("abcde"), 1, 1, SV("abcde"), 1, 2, -1); + test(S("abcde"), 1, 1, SV("abcde"), 1, 3, -2); + test(S("abcde"), 1, 1, SV("abcde"), 1, 4, -3); + test(S("abcde"), 1, 1, SV("abcde"), 1, 5, -3); + test(S("abcde"), 1, 1, SV("abcde"), 2, 0, 1); + test(S("abcde"), 1, 1, SV("abcde"), 2, 1, -1); + test(S("abcde"), 1, 1, SV("abcde"), 2, 2, -1); + test(S("abcde"), 1, 1, SV("abcde"), 2, 3, -1); + test(S("abcde"), 1, 1, SV("abcde"), 2, 4, -1); + test(S("abcde"), 1, 1, SV("abcde"), 4, 0, 1); + test(S("abcde"), 1, 1, SV("abcde"), 4, 1, -3); + test(S("abcde"), 1, 1, SV("abcde"), 4, 2, -3); + test(S("abcde"), 1, 1, SV("abcde"), 5, 0, 1); + test(S("abcde"), 1, 1, SV("abcde"), 5, 1, 1); + test(S("abcde"), 1, 1, SV("abcde"), 6, 0, 0); + test(S("abcde"), 1, 1, SV("abcdefghij"), 0, 0, 1); + test(S("abcde"), 1, 1, SV("abcdefghij"), 0, 1, 1); + test(S("abcde"), 1, 1, SV("abcdefghij"), 0, 5, 1); + test(S("abcde"), 1, 1, SV("abcdefghij"), 0, 9, 1); + test(S("abcde"), 1, 1, SV("abcdefghij"), 0, 10, 1); + test(S("abcde"), 1, 1, SV("abcdefghij"), 0, 11, 1); + test(S("abcde"), 1, 1, SV("abcdefghij"), 1, 0, 1); + test(S("abcde"), 1, 1, SV("abcdefghij"), 1, 1, 0); + test(S("abcde"), 1, 1, SV("abcdefghij"), 1, 4, -3); + test(S("abcde"), 1, 1, SV("abcdefghij"), 1, 8, -7); + test(S("abcde"), 1, 1, SV("abcdefghij"), 1, 9, -8); + test(S("abcde"), 1, 1, SV("abcdefghij"), 1, 10, -8); + test(S("abcde"), 1, 1, SV("abcdefghij"), 5, 0, 1); + test(S("abcde"), 1, 1, SV("abcdefghij"), 5, 1, -4); + test(S("abcde"), 1, 1, SV("abcdefghij"), 5, 2, -4); + test(S("abcde"), 1, 1, SV("abcdefghij"), 5, 4, -4); + test(S("abcde"), 1, 1, SV("abcdefghij"), 5, 5, -4); + test(S("abcde"), 1, 1, SV("abcdefghij"), 5, 6, -4); + test(S("abcde"), 1, 1, SV("abcdefghij"), 9, 0, 1); + test(S("abcde"), 1, 1, SV("abcdefghij"), 9, 1, -8); + test(S("abcde"), 1, 1, SV("abcdefghij"), 9, 2, -8); + test(S("abcde"), 1, 1, SV("abcdefghij"), 10, 0, 1); + test(S("abcde"), 1, 1, SV("abcdefghij"), 10, 1, 1); + test(S("abcde"), 1, 1, SV("abcdefghij"), 11, 0, 0); + test(S("abcde"), 1, 1, SV("abcdefghijklmnopqrst"), 0, 0, 1); + test(S("abcde"), 1, 1, SV("abcdefghijklmnopqrst"), 0, 1, 1); + test(S("abcde"), 1, 1, SV("abcdefghijklmnopqrst"), 0, 10, 1); + test(S("abcde"), 1, 1, SV("abcdefghijklmnopqrst"), 0, 19, 1); + test(S("abcde"), 1, 1, SV("abcdefghijklmnopqrst"), 0, 20, 1); + test(S("abcde"), 1, 1, SV("abcdefghijklmnopqrst"), 0, 21, 1); + test(S("abcde"), 1, 1, SV("abcdefghijklmnopqrst"), 1, 0, 1); + test(S("abcde"), 1, 1, SV("abcdefghijklmnopqrst"), 1, 1, 0); + test(S("abcde"), 1, 1, SV("abcdefghijklmnopqrst"), 1, 9, -8); + test(S("abcde"), 1, 1, SV("abcdefghijklmnopqrst"), 1, 18, -17); +} + +template +void test8() +{ + test(S("abcde"), 1, 1, SV("abcdefghijklmnopqrst"), 1, 19, -18); + test(S("abcde"), 1, 1, SV("abcdefghijklmnopqrst"), 1, 20, -18); + test(S("abcde"), 1, 1, SV("abcdefghijklmnopqrst"), 10, 0, 1); + test(S("abcde"), 1, 1, SV("abcdefghijklmnopqrst"), 10, 1, -9); + test(S("abcde"), 1, 1, SV("abcdefghijklmnopqrst"), 10, 5, -9); + test(S("abcde"), 1, 1, SV("abcdefghijklmnopqrst"), 10, 9, -9); + test(S("abcde"), 1, 1, SV("abcdefghijklmnopqrst"), 10, 10, -9); + test(S("abcde"), 1, 1, SV("abcdefghijklmnopqrst"), 10, 11, -9); + test(S("abcde"), 1, 1, SV("abcdefghijklmnopqrst"), 19, 0, 1); + test(S("abcde"), 1, 1, SV("abcdefghijklmnopqrst"), 19, 1, -18); + test(S("abcde"), 1, 1, SV("abcdefghijklmnopqrst"), 19, 2, -18); + test(S("abcde"), 1, 1, SV("abcdefghijklmnopqrst"), 20, 0, 1); + test(S("abcde"), 1, 1, SV("abcdefghijklmnopqrst"), 20, 1, 1); + test(S("abcde"), 1, 1, SV("abcdefghijklmnopqrst"), 21, 0, 0); + test(S("abcde"), 1, 2, SV(""), 0, 0, 2); + test(S("abcde"), 1, 2, SV(""), 0, 1, 2); + test(S("abcde"), 1, 2, SV(""), 1, 0, 0); + test(S("abcde"), 1, 2, SV("abcde"), 0, 0, 2); + test(S("abcde"), 1, 2, SV("abcde"), 0, 1, 1); + test(S("abcde"), 1, 2, SV("abcde"), 0, 2, 1); + test(S("abcde"), 1, 2, SV("abcde"), 0, 4, 1); + test(S("abcde"), 1, 2, SV("abcde"), 0, 5, 1); + test(S("abcde"), 1, 2, SV("abcde"), 0, 6, 1); + test(S("abcde"), 1, 2, SV("abcde"), 1, 0, 2); + test(S("abcde"), 1, 2, SV("abcde"), 1, 1, 1); + test(S("abcde"), 1, 2, SV("abcde"), 1, 2, 0); + test(S("abcde"), 1, 2, SV("abcde"), 1, 3, -1); + test(S("abcde"), 1, 2, SV("abcde"), 1, 4, -2); + test(S("abcde"), 1, 2, SV("abcde"), 1, 5, -2); + test(S("abcde"), 1, 2, SV("abcde"), 2, 0, 2); + test(S("abcde"), 1, 2, SV("abcde"), 2, 1, -1); + test(S("abcde"), 1, 2, SV("abcde"), 2, 2, -1); + test(S("abcde"), 1, 2, SV("abcde"), 2, 3, -1); + test(S("abcde"), 1, 2, SV("abcde"), 2, 4, -1); + test(S("abcde"), 1, 2, SV("abcde"), 4, 0, 2); + test(S("abcde"), 1, 2, SV("abcde"), 4, 1, -3); + test(S("abcde"), 1, 2, SV("abcde"), 4, 2, -3); + test(S("abcde"), 1, 2, SV("abcde"), 5, 0, 2); + test(S("abcde"), 1, 2, SV("abcde"), 5, 1, 2); + test(S("abcde"), 1, 2, SV("abcde"), 6, 0, 0); + test(S("abcde"), 1, 2, SV("abcdefghij"), 0, 0, 2); + test(S("abcde"), 1, 2, SV("abcdefghij"), 0, 1, 1); + test(S("abcde"), 1, 2, SV("abcdefghij"), 0, 5, 1); + test(S("abcde"), 1, 2, SV("abcdefghij"), 0, 9, 1); + test(S("abcde"), 1, 2, SV("abcdefghij"), 0, 10, 1); + test(S("abcde"), 1, 2, SV("abcdefghij"), 0, 11, 1); + test(S("abcde"), 1, 2, SV("abcdefghij"), 1, 0, 2); + test(S("abcde"), 1, 2, SV("abcdefghij"), 1, 1, 1); + test(S("abcde"), 1, 2, SV("abcdefghij"), 1, 4, -2); + test(S("abcde"), 1, 2, SV("abcdefghij"), 1, 8, -6); + test(S("abcde"), 1, 2, SV("abcdefghij"), 1, 9, -7); + test(S("abcde"), 1, 2, SV("abcdefghij"), 1, 10, -7); + test(S("abcde"), 1, 2, SV("abcdefghij"), 5, 0, 2); + test(S("abcde"), 1, 2, SV("abcdefghij"), 5, 1, -4); + test(S("abcde"), 1, 2, SV("abcdefghij"), 5, 2, -4); + test(S("abcde"), 1, 2, SV("abcdefghij"), 5, 4, -4); + test(S("abcde"), 1, 2, SV("abcdefghij"), 5, 5, -4); + test(S("abcde"), 1, 2, SV("abcdefghij"), 5, 6, -4); + test(S("abcde"), 1, 2, SV("abcdefghij"), 9, 0, 2); + test(S("abcde"), 1, 2, SV("abcdefghij"), 9, 1, -8); + test(S("abcde"), 1, 2, SV("abcdefghij"), 9, 2, -8); + test(S("abcde"), 1, 2, SV("abcdefghij"), 10, 0, 2); + test(S("abcde"), 1, 2, SV("abcdefghij"), 10, 1, 2); + test(S("abcde"), 1, 2, SV("abcdefghij"), 11, 0, 0); + test(S("abcde"), 1, 2, SV("abcdefghijklmnopqrst"), 0, 0, 2); + test(S("abcde"), 1, 2, SV("abcdefghijklmnopqrst"), 0, 1, 1); + test(S("abcde"), 1, 2, SV("abcdefghijklmnopqrst"), 0, 10, 1); + test(S("abcde"), 1, 2, SV("abcdefghijklmnopqrst"), 0, 19, 1); + test(S("abcde"), 1, 2, SV("abcdefghijklmnopqrst"), 0, 20, 1); + test(S("abcde"), 1, 2, SV("abcdefghijklmnopqrst"), 0, 21, 1); + test(S("abcde"), 1, 2, SV("abcdefghijklmnopqrst"), 1, 0, 2); + test(S("abcde"), 1, 2, SV("abcdefghijklmnopqrst"), 1, 1, 1); + test(S("abcde"), 1, 2, SV("abcdefghijklmnopqrst"), 1, 9, -7); + test(S("abcde"), 1, 2, SV("abcdefghijklmnopqrst"), 1, 18, -16); + test(S("abcde"), 1, 2, SV("abcdefghijklmnopqrst"), 1, 19, -17); + test(S("abcde"), 1, 2, SV("abcdefghijklmnopqrst"), 1, 20, -17); + test(S("abcde"), 1, 2, SV("abcdefghijklmnopqrst"), 10, 0, 2); + test(S("abcde"), 1, 2, SV("abcdefghijklmnopqrst"), 10, 1, -9); + test(S("abcde"), 1, 2, SV("abcdefghijklmnopqrst"), 10, 5, -9); + test(S("abcde"), 1, 2, SV("abcdefghijklmnopqrst"), 10, 9, -9); + test(S("abcde"), 1, 2, SV("abcdefghijklmnopqrst"), 10, 10, -9); + test(S("abcde"), 1, 2, SV("abcdefghijklmnopqrst"), 10, 11, -9); + test(S("abcde"), 1, 2, SV("abcdefghijklmnopqrst"), 19, 0, 2); + test(S("abcde"), 1, 2, SV("abcdefghijklmnopqrst"), 19, 1, -18); + test(S("abcde"), 1, 2, SV("abcdefghijklmnopqrst"), 19, 2, -18); + test(S("abcde"), 1, 2, SV("abcdefghijklmnopqrst"), 20, 0, 2); + test(S("abcde"), 1, 2, SV("abcdefghijklmnopqrst"), 20, 1, 2); + test(S("abcde"), 1, 2, SV("abcdefghijklmnopqrst"), 21, 0, 0); + test(S("abcde"), 1, 3, SV(""), 0, 0, 3); + test(S("abcde"), 1, 3, SV(""), 0, 1, 3); + test(S("abcde"), 1, 3, SV(""), 1, 0, 0); + test(S("abcde"), 1, 3, SV("abcde"), 0, 0, 3); + test(S("abcde"), 1, 3, SV("abcde"), 0, 1, 1); + test(S("abcde"), 1, 3, SV("abcde"), 0, 2, 1); + test(S("abcde"), 1, 3, SV("abcde"), 0, 4, 1); + test(S("abcde"), 1, 3, SV("abcde"), 0, 5, 1); + test(S("abcde"), 1, 3, SV("abcde"), 0, 6, 1); + test(S("abcde"), 1, 3, SV("abcde"), 1, 0, 3); + test(S("abcde"), 1, 3, SV("abcde"), 1, 1, 2); + test(S("abcde"), 1, 3, SV("abcde"), 1, 2, 1); +} + +template +void test9() +{ + test(S("abcde"), 1, 3, SV("abcde"), 1, 3, 0); + test(S("abcde"), 1, 3, SV("abcde"), 1, 4, -1); + test(S("abcde"), 1, 3, SV("abcde"), 1, 5, -1); + test(S("abcde"), 1, 3, SV("abcde"), 2, 0, 3); + test(S("abcde"), 1, 3, SV("abcde"), 2, 1, -1); + test(S("abcde"), 1, 3, SV("abcde"), 2, 2, -1); + test(S("abcde"), 1, 3, SV("abcde"), 2, 3, -1); + test(S("abcde"), 1, 3, SV("abcde"), 2, 4, -1); + test(S("abcde"), 1, 3, SV("abcde"), 4, 0, 3); + test(S("abcde"), 1, 3, SV("abcde"), 4, 1, -3); + test(S("abcde"), 1, 3, SV("abcde"), 4, 2, -3); + test(S("abcde"), 1, 3, SV("abcde"), 5, 0, 3); + test(S("abcde"), 1, 3, SV("abcde"), 5, 1, 3); + test(S("abcde"), 1, 3, SV("abcde"), 6, 0, 0); + test(S("abcde"), 1, 3, SV("abcdefghij"), 0, 0, 3); + test(S("abcde"), 1, 3, SV("abcdefghij"), 0, 1, 1); + test(S("abcde"), 1, 3, SV("abcdefghij"), 0, 5, 1); + test(S("abcde"), 1, 3, SV("abcdefghij"), 0, 9, 1); + test(S("abcde"), 1, 3, SV("abcdefghij"), 0, 10, 1); + test(S("abcde"), 1, 3, SV("abcdefghij"), 0, 11, 1); + test(S("abcde"), 1, 3, SV("abcdefghij"), 1, 0, 3); + test(S("abcde"), 1, 3, SV("abcdefghij"), 1, 1, 2); + test(S("abcde"), 1, 3, SV("abcdefghij"), 1, 4, -1); + test(S("abcde"), 1, 3, SV("abcdefghij"), 1, 8, -5); + test(S("abcde"), 1, 3, SV("abcdefghij"), 1, 9, -6); + test(S("abcde"), 1, 3, SV("abcdefghij"), 1, 10, -6); + test(S("abcde"), 1, 3, SV("abcdefghij"), 5, 0, 3); + test(S("abcde"), 1, 3, SV("abcdefghij"), 5, 1, -4); + test(S("abcde"), 1, 3, SV("abcdefghij"), 5, 2, -4); + test(S("abcde"), 1, 3, SV("abcdefghij"), 5, 4, -4); + test(S("abcde"), 1, 3, SV("abcdefghij"), 5, 5, -4); + test(S("abcde"), 1, 3, SV("abcdefghij"), 5, 6, -4); + test(S("abcde"), 1, 3, SV("abcdefghij"), 9, 0, 3); + test(S("abcde"), 1, 3, SV("abcdefghij"), 9, 1, -8); + test(S("abcde"), 1, 3, SV("abcdefghij"), 9, 2, -8); + test(S("abcde"), 1, 3, SV("abcdefghij"), 10, 0, 3); + test(S("abcde"), 1, 3, SV("abcdefghij"), 10, 1, 3); + test(S("abcde"), 1, 3, SV("abcdefghij"), 11, 0, 0); + test(S("abcde"), 1, 3, SV("abcdefghijklmnopqrst"), 0, 0, 3); + test(S("abcde"), 1, 3, SV("abcdefghijklmnopqrst"), 0, 1, 1); + test(S("abcde"), 1, 3, SV("abcdefghijklmnopqrst"), 0, 10, 1); + test(S("abcde"), 1, 3, SV("abcdefghijklmnopqrst"), 0, 19, 1); + test(S("abcde"), 1, 3, SV("abcdefghijklmnopqrst"), 0, 20, 1); + test(S("abcde"), 1, 3, SV("abcdefghijklmnopqrst"), 0, 21, 1); + test(S("abcde"), 1, 3, SV("abcdefghijklmnopqrst"), 1, 0, 3); + test(S("abcde"), 1, 3, SV("abcdefghijklmnopqrst"), 1, 1, 2); + test(S("abcde"), 1, 3, SV("abcdefghijklmnopqrst"), 1, 9, -6); + test(S("abcde"), 1, 3, SV("abcdefghijklmnopqrst"), 1, 18, -15); + test(S("abcde"), 1, 3, SV("abcdefghijklmnopqrst"), 1, 19, -16); + test(S("abcde"), 1, 3, SV("abcdefghijklmnopqrst"), 1, 20, -16); + test(S("abcde"), 1, 3, SV("abcdefghijklmnopqrst"), 10, 0, 3); + test(S("abcde"), 1, 3, SV("abcdefghijklmnopqrst"), 10, 1, -9); + test(S("abcde"), 1, 3, SV("abcdefghijklmnopqrst"), 10, 5, -9); + test(S("abcde"), 1, 3, SV("abcdefghijklmnopqrst"), 10, 9, -9); + test(S("abcde"), 1, 3, SV("abcdefghijklmnopqrst"), 10, 10, -9); + test(S("abcde"), 1, 3, SV("abcdefghijklmnopqrst"), 10, 11, -9); + test(S("abcde"), 1, 3, SV("abcdefghijklmnopqrst"), 19, 0, 3); + test(S("abcde"), 1, 3, SV("abcdefghijklmnopqrst"), 19, 1, -18); + test(S("abcde"), 1, 3, SV("abcdefghijklmnopqrst"), 19, 2, -18); + test(S("abcde"), 1, 3, SV("abcdefghijklmnopqrst"), 20, 0, 3); + test(S("abcde"), 1, 3, SV("abcdefghijklmnopqrst"), 20, 1, 3); + test(S("abcde"), 1, 3, SV("abcdefghijklmnopqrst"), 21, 0, 0); + test(S("abcde"), 1, 4, SV(""), 0, 0, 4); + test(S("abcde"), 1, 4, SV(""), 0, 1, 4); + test(S("abcde"), 1, 4, SV(""), 1, 0, 0); + test(S("abcde"), 1, 4, SV("abcde"), 0, 0, 4); + test(S("abcde"), 1, 4, SV("abcde"), 0, 1, 1); + test(S("abcde"), 1, 4, SV("abcde"), 0, 2, 1); + test(S("abcde"), 1, 4, SV("abcde"), 0, 4, 1); + test(S("abcde"), 1, 4, SV("abcde"), 0, 5, 1); + test(S("abcde"), 1, 4, SV("abcde"), 0, 6, 1); + test(S("abcde"), 1, 4, SV("abcde"), 1, 0, 4); + test(S("abcde"), 1, 4, SV("abcde"), 1, 1, 3); + test(S("abcde"), 1, 4, SV("abcde"), 1, 2, 2); + test(S("abcde"), 1, 4, SV("abcde"), 1, 3, 1); + test(S("abcde"), 1, 4, SV("abcde"), 1, 4, 0); + test(S("abcde"), 1, 4, SV("abcde"), 1, 5, 0); + test(S("abcde"), 1, 4, SV("abcde"), 2, 0, 4); + test(S("abcde"), 1, 4, SV("abcde"), 2, 1, -1); + test(S("abcde"), 1, 4, SV("abcde"), 2, 2, -1); + test(S("abcde"), 1, 4, SV("abcde"), 2, 3, -1); + test(S("abcde"), 1, 4, SV("abcde"), 2, 4, -1); + test(S("abcde"), 1, 4, SV("abcde"), 4, 0, 4); + test(S("abcde"), 1, 4, SV("abcde"), 4, 1, -3); + test(S("abcde"), 1, 4, SV("abcde"), 4, 2, -3); + test(S("abcde"), 1, 4, SV("abcde"), 5, 0, 4); + test(S("abcde"), 1, 4, SV("abcde"), 5, 1, 4); + test(S("abcde"), 1, 4, SV("abcde"), 6, 0, 0); + test(S("abcde"), 1, 4, SV("abcdefghij"), 0, 0, 4); + test(S("abcde"), 1, 4, SV("abcdefghij"), 0, 1, 1); + test(S("abcde"), 1, 4, SV("abcdefghij"), 0, 5, 1); + test(S("abcde"), 1, 4, SV("abcdefghij"), 0, 9, 1); + test(S("abcde"), 1, 4, SV("abcdefghij"), 0, 10, 1); + test(S("abcde"), 1, 4, SV("abcdefghij"), 0, 11, 1); + test(S("abcde"), 1, 4, SV("abcdefghij"), 1, 0, 4); + test(S("abcde"), 1, 4, SV("abcdefghij"), 1, 1, 3); + test(S("abcde"), 1, 4, SV("abcdefghij"), 1, 4, 0); + test(S("abcde"), 1, 4, SV("abcdefghij"), 1, 8, -4); + test(S("abcde"), 1, 4, SV("abcdefghij"), 1, 9, -5); + test(S("abcde"), 1, 4, SV("abcdefghij"), 1, 10, -5); +} + +template +void test10() +{ + test(S("abcde"), 1, 4, SV("abcdefghij"), 5, 0, 4); + test(S("abcde"), 1, 4, SV("abcdefghij"), 5, 1, -4); + test(S("abcde"), 1, 4, SV("abcdefghij"), 5, 2, -4); + test(S("abcde"), 1, 4, SV("abcdefghij"), 5, 4, -4); + test(S("abcde"), 1, 4, SV("abcdefghij"), 5, 5, -4); + test(S("abcde"), 1, 4, SV("abcdefghij"), 5, 6, -4); + test(S("abcde"), 1, 4, SV("abcdefghij"), 9, 0, 4); + test(S("abcde"), 1, 4, SV("abcdefghij"), 9, 1, -8); + test(S("abcde"), 1, 4, SV("abcdefghij"), 9, 2, -8); + test(S("abcde"), 1, 4, SV("abcdefghij"), 10, 0, 4); + test(S("abcde"), 1, 4, SV("abcdefghij"), 10, 1, 4); + test(S("abcde"), 1, 4, SV("abcdefghij"), 11, 0, 0); + test(S("abcde"), 1, 4, SV("abcdefghijklmnopqrst"), 0, 0, 4); + test(S("abcde"), 1, 4, SV("abcdefghijklmnopqrst"), 0, 1, 1); + test(S("abcde"), 1, 4, SV("abcdefghijklmnopqrst"), 0, 10, 1); + test(S("abcde"), 1, 4, SV("abcdefghijklmnopqrst"), 0, 19, 1); + test(S("abcde"), 1, 4, SV("abcdefghijklmnopqrst"), 0, 20, 1); + test(S("abcde"), 1, 4, SV("abcdefghijklmnopqrst"), 0, 21, 1); + test(S("abcde"), 1, 4, SV("abcdefghijklmnopqrst"), 1, 0, 4); + test(S("abcde"), 1, 4, SV("abcdefghijklmnopqrst"), 1, 1, 3); + test(S("abcde"), 1, 4, SV("abcdefghijklmnopqrst"), 1, 9, -5); + test(S("abcde"), 1, 4, SV("abcdefghijklmnopqrst"), 1, 18, -14); + test(S("abcde"), 1, 4, SV("abcdefghijklmnopqrst"), 1, 19, -15); + test(S("abcde"), 1, 4, SV("abcdefghijklmnopqrst"), 1, 20, -15); + test(S("abcde"), 1, 4, SV("abcdefghijklmnopqrst"), 10, 0, 4); + test(S("abcde"), 1, 4, SV("abcdefghijklmnopqrst"), 10, 1, -9); + test(S("abcde"), 1, 4, SV("abcdefghijklmnopqrst"), 10, 5, -9); + test(S("abcde"), 1, 4, SV("abcdefghijklmnopqrst"), 10, 9, -9); + test(S("abcde"), 1, 4, SV("abcdefghijklmnopqrst"), 10, 10, -9); + test(S("abcde"), 1, 4, SV("abcdefghijklmnopqrst"), 10, 11, -9); + test(S("abcde"), 1, 4, SV("abcdefghijklmnopqrst"), 19, 0, 4); + test(S("abcde"), 1, 4, SV("abcdefghijklmnopqrst"), 19, 1, -18); + test(S("abcde"), 1, 4, SV("abcdefghijklmnopqrst"), 19, 2, -18); + test(S("abcde"), 1, 4, SV("abcdefghijklmnopqrst"), 20, 0, 4); + test(S("abcde"), 1, 4, SV("abcdefghijklmnopqrst"), 20, 1, 4); + test(S("abcde"), 1, 4, SV("abcdefghijklmnopqrst"), 21, 0, 0); + test(S("abcde"), 1, 5, SV(""), 0, 0, 4); + test(S("abcde"), 1, 5, SV(""), 0, 1, 4); + test(S("abcde"), 1, 5, SV(""), 1, 0, 0); + test(S("abcde"), 1, 5, SV("abcde"), 0, 0, 4); + test(S("abcde"), 1, 5, SV("abcde"), 0, 1, 1); + test(S("abcde"), 1, 5, SV("abcde"), 0, 2, 1); + test(S("abcde"), 1, 5, SV("abcde"), 0, 4, 1); + test(S("abcde"), 1, 5, SV("abcde"), 0, 5, 1); + test(S("abcde"), 1, 5, SV("abcde"), 0, 6, 1); + test(S("abcde"), 1, 5, SV("abcde"), 1, 0, 4); + test(S("abcde"), 1, 5, SV("abcde"), 1, 1, 3); + test(S("abcde"), 1, 5, SV("abcde"), 1, 2, 2); + test(S("abcde"), 1, 5, SV("abcde"), 1, 3, 1); + test(S("abcde"), 1, 5, SV("abcde"), 1, 4, 0); + test(S("abcde"), 1, 5, SV("abcde"), 1, 5, 0); + test(S("abcde"), 1, 5, SV("abcde"), 2, 0, 4); + test(S("abcde"), 1, 5, SV("abcde"), 2, 1, -1); + test(S("abcde"), 1, 5, SV("abcde"), 2, 2, -1); + test(S("abcde"), 1, 5, SV("abcde"), 2, 3, -1); + test(S("abcde"), 1, 5, SV("abcde"), 2, 4, -1); + test(S("abcde"), 1, 5, SV("abcde"), 4, 0, 4); + test(S("abcde"), 1, 5, SV("abcde"), 4, 1, -3); + test(S("abcde"), 1, 5, SV("abcde"), 4, 2, -3); + test(S("abcde"), 1, 5, SV("abcde"), 5, 0, 4); + test(S("abcde"), 1, 5, SV("abcde"), 5, 1, 4); + test(S("abcde"), 1, 5, SV("abcde"), 6, 0, 0); + test(S("abcde"), 1, 5, SV("abcdefghij"), 0, 0, 4); + test(S("abcde"), 1, 5, SV("abcdefghij"), 0, 1, 1); + test(S("abcde"), 1, 5, SV("abcdefghij"), 0, 5, 1); + test(S("abcde"), 1, 5, SV("abcdefghij"), 0, 9, 1); + test(S("abcde"), 1, 5, SV("abcdefghij"), 0, 10, 1); + test(S("abcde"), 1, 5, SV("abcdefghij"), 0, 11, 1); + test(S("abcde"), 1, 5, SV("abcdefghij"), 1, 0, 4); + test(S("abcde"), 1, 5, SV("abcdefghij"), 1, 1, 3); + test(S("abcde"), 1, 5, SV("abcdefghij"), 1, 4, 0); + test(S("abcde"), 1, 5, SV("abcdefghij"), 1, 8, -4); + test(S("abcde"), 1, 5, SV("abcdefghij"), 1, 9, -5); + test(S("abcde"), 1, 5, SV("abcdefghij"), 1, 10, -5); + test(S("abcde"), 1, 5, SV("abcdefghij"), 5, 0, 4); + test(S("abcde"), 1, 5, SV("abcdefghij"), 5, 1, -4); + test(S("abcde"), 1, 5, SV("abcdefghij"), 5, 2, -4); + test(S("abcde"), 1, 5, SV("abcdefghij"), 5, 4, -4); + test(S("abcde"), 1, 5, SV("abcdefghij"), 5, 5, -4); + test(S("abcde"), 1, 5, SV("abcdefghij"), 5, 6, -4); + test(S("abcde"), 1, 5, SV("abcdefghij"), 9, 0, 4); + test(S("abcde"), 1, 5, SV("abcdefghij"), 9, 1, -8); + test(S("abcde"), 1, 5, SV("abcdefghij"), 9, 2, -8); + test(S("abcde"), 1, 5, SV("abcdefghij"), 10, 0, 4); + test(S("abcde"), 1, 5, SV("abcdefghij"), 10, 1, 4); + test(S("abcde"), 1, 5, SV("abcdefghij"), 11, 0, 0); + test(S("abcde"), 1, 5, SV("abcdefghijklmnopqrst"), 0, 0, 4); + test(S("abcde"), 1, 5, SV("abcdefghijklmnopqrst"), 0, 1, 1); + test(S("abcde"), 1, 5, SV("abcdefghijklmnopqrst"), 0, 10, 1); + test(S("abcde"), 1, 5, SV("abcdefghijklmnopqrst"), 0, 19, 1); + test(S("abcde"), 1, 5, SV("abcdefghijklmnopqrst"), 0, 20, 1); + test(S("abcde"), 1, 5, SV("abcdefghijklmnopqrst"), 0, 21, 1); + test(S("abcde"), 1, 5, SV("abcdefghijklmnopqrst"), 1, 0, 4); + test(S("abcde"), 1, 5, SV("abcdefghijklmnopqrst"), 1, 1, 3); + test(S("abcde"), 1, 5, SV("abcdefghijklmnopqrst"), 1, 9, -5); + test(S("abcde"), 1, 5, SV("abcdefghijklmnopqrst"), 1, 18, -14); + test(S("abcde"), 1, 5, SV("abcdefghijklmnopqrst"), 1, 19, -15); + test(S("abcde"), 1, 5, SV("abcdefghijklmnopqrst"), 1, 20, -15); + test(S("abcde"), 1, 5, SV("abcdefghijklmnopqrst"), 10, 0, 4); + test(S("abcde"), 1, 5, SV("abcdefghijklmnopqrst"), 10, 1, -9); +} + +template +void test11() +{ + test(S("abcde"), 1, 5, SV("abcdefghijklmnopqrst"), 10, 5, -9); + test(S("abcde"), 1, 5, SV("abcdefghijklmnopqrst"), 10, 9, -9); + test(S("abcde"), 1, 5, SV("abcdefghijklmnopqrst"), 10, 10, -9); + test(S("abcde"), 1, 5, SV("abcdefghijklmnopqrst"), 10, 11, -9); + test(S("abcde"), 1, 5, SV("abcdefghijklmnopqrst"), 19, 0, 4); + test(S("abcde"), 1, 5, SV("abcdefghijklmnopqrst"), 19, 1, -18); + test(S("abcde"), 1, 5, SV("abcdefghijklmnopqrst"), 19, 2, -18); + test(S("abcde"), 1, 5, SV("abcdefghijklmnopqrst"), 20, 0, 4); + test(S("abcde"), 1, 5, SV("abcdefghijklmnopqrst"), 20, 1, 4); + test(S("abcde"), 1, 5, SV("abcdefghijklmnopqrst"), 21, 0, 0); + test(S("abcde"), 2, 0, SV(""), 0, 0, 0); + test(S("abcde"), 2, 0, SV(""), 0, 1, 0); + test(S("abcde"), 2, 0, SV(""), 1, 0, 0); + test(S("abcde"), 2, 0, SV("abcde"), 0, 0, 0); + test(S("abcde"), 2, 0, SV("abcde"), 0, 1, -1); + test(S("abcde"), 2, 0, SV("abcde"), 0, 2, -2); + test(S("abcde"), 2, 0, SV("abcde"), 0, 4, -4); + test(S("abcde"), 2, 0, SV("abcde"), 0, 5, -5); + test(S("abcde"), 2, 0, SV("abcde"), 0, 6, -5); + test(S("abcde"), 2, 0, SV("abcde"), 1, 0, 0); + test(S("abcde"), 2, 0, SV("abcde"), 1, 1, -1); + test(S("abcde"), 2, 0, SV("abcde"), 1, 2, -2); + test(S("abcde"), 2, 0, SV("abcde"), 1, 3, -3); + test(S("abcde"), 2, 0, SV("abcde"), 1, 4, -4); + test(S("abcde"), 2, 0, SV("abcde"), 1, 5, -4); + test(S("abcde"), 2, 0, SV("abcde"), 2, 0, 0); + test(S("abcde"), 2, 0, SV("abcde"), 2, 1, -1); + test(S("abcde"), 2, 0, SV("abcde"), 2, 2, -2); + test(S("abcde"), 2, 0, SV("abcde"), 2, 3, -3); + test(S("abcde"), 2, 0, SV("abcde"), 2, 4, -3); + test(S("abcde"), 2, 0, SV("abcde"), 4, 0, 0); + test(S("abcde"), 2, 0, SV("abcde"), 4, 1, -1); + test(S("abcde"), 2, 0, SV("abcde"), 4, 2, -1); + test(S("abcde"), 2, 0, SV("abcde"), 5, 0, 0); + test(S("abcde"), 2, 0, SV("abcde"), 5, 1, 0); + test(S("abcde"), 2, 0, SV("abcde"), 6, 0, 0); + test(S("abcde"), 2, 0, SV("abcdefghij"), 0, 0, 0); + test(S("abcde"), 2, 0, SV("abcdefghij"), 0, 1, -1); + test(S("abcde"), 2, 0, SV("abcdefghij"), 0, 5, -5); + test(S("abcde"), 2, 0, SV("abcdefghij"), 0, 9, -9); + test(S("abcde"), 2, 0, SV("abcdefghij"), 0, 10, -10); + test(S("abcde"), 2, 0, SV("abcdefghij"), 0, 11, -10); + test(S("abcde"), 2, 0, SV("abcdefghij"), 1, 0, 0); + test(S("abcde"), 2, 0, SV("abcdefghij"), 1, 1, -1); + test(S("abcde"), 2, 0, SV("abcdefghij"), 1, 4, -4); + test(S("abcde"), 2, 0, SV("abcdefghij"), 1, 8, -8); + test(S("abcde"), 2, 0, SV("abcdefghij"), 1, 9, -9); + test(S("abcde"), 2, 0, SV("abcdefghij"), 1, 10, -9); + test(S("abcde"), 2, 0, SV("abcdefghij"), 5, 0, 0); + test(S("abcde"), 2, 0, SV("abcdefghij"), 5, 1, -1); + test(S("abcde"), 2, 0, SV("abcdefghij"), 5, 2, -2); + test(S("abcde"), 2, 0, SV("abcdefghij"), 5, 4, -4); + test(S("abcde"), 2, 0, SV("abcdefghij"), 5, 5, -5); + test(S("abcde"), 2, 0, SV("abcdefghij"), 5, 6, -5); + test(S("abcde"), 2, 0, SV("abcdefghij"), 9, 0, 0); + test(S("abcde"), 2, 0, SV("abcdefghij"), 9, 1, -1); + test(S("abcde"), 2, 0, SV("abcdefghij"), 9, 2, -1); + test(S("abcde"), 2, 0, SV("abcdefghij"), 10, 0, 0); + test(S("abcde"), 2, 0, SV("abcdefghij"), 10, 1, 0); + test(S("abcde"), 2, 0, SV("abcdefghij"), 11, 0, 0); + test(S("abcde"), 2, 0, SV("abcdefghijklmnopqrst"), 0, 0, 0); + test(S("abcde"), 2, 0, SV("abcdefghijklmnopqrst"), 0, 1, -1); + test(S("abcde"), 2, 0, SV("abcdefghijklmnopqrst"), 0, 10, -10); + test(S("abcde"), 2, 0, SV("abcdefghijklmnopqrst"), 0, 19, -19); + test(S("abcde"), 2, 0, SV("abcdefghijklmnopqrst"), 0, 20, -20); + test(S("abcde"), 2, 0, SV("abcdefghijklmnopqrst"), 0, 21, -20); + test(S("abcde"), 2, 0, SV("abcdefghijklmnopqrst"), 1, 0, 0); + test(S("abcde"), 2, 0, SV("abcdefghijklmnopqrst"), 1, 1, -1); + test(S("abcde"), 2, 0, SV("abcdefghijklmnopqrst"), 1, 9, -9); + test(S("abcde"), 2, 0, SV("abcdefghijklmnopqrst"), 1, 18, -18); + test(S("abcde"), 2, 0, SV("abcdefghijklmnopqrst"), 1, 19, -19); + test(S("abcde"), 2, 0, SV("abcdefghijklmnopqrst"), 1, 20, -19); + test(S("abcde"), 2, 0, SV("abcdefghijklmnopqrst"), 10, 0, 0); + test(S("abcde"), 2, 0, SV("abcdefghijklmnopqrst"), 10, 1, -1); + test(S("abcde"), 2, 0, SV("abcdefghijklmnopqrst"), 10, 5, -5); + test(S("abcde"), 2, 0, SV("abcdefghijklmnopqrst"), 10, 9, -9); + test(S("abcde"), 2, 0, SV("abcdefghijklmnopqrst"), 10, 10, -10); + test(S("abcde"), 2, 0, SV("abcdefghijklmnopqrst"), 10, 11, -10); + test(S("abcde"), 2, 0, SV("abcdefghijklmnopqrst"), 19, 0, 0); + test(S("abcde"), 2, 0, SV("abcdefghijklmnopqrst"), 19, 1, -1); + test(S("abcde"), 2, 0, SV("abcdefghijklmnopqrst"), 19, 2, -1); + test(S("abcde"), 2, 0, SV("abcdefghijklmnopqrst"), 20, 0, 0); + test(S("abcde"), 2, 0, SV("abcdefghijklmnopqrst"), 20, 1, 0); + test(S("abcde"), 2, 0, SV("abcdefghijklmnopqrst"), 21, 0, 0); + test(S("abcde"), 2, 1, SV(""), 0, 0, 1); + test(S("abcde"), 2, 1, SV(""), 0, 1, 1); + test(S("abcde"), 2, 1, SV(""), 1, 0, 0); + test(S("abcde"), 2, 1, SV("abcde"), 0, 0, 1); + test(S("abcde"), 2, 1, SV("abcde"), 0, 1, 2); + test(S("abcde"), 2, 1, SV("abcde"), 0, 2, 2); + test(S("abcde"), 2, 1, SV("abcde"), 0, 4, 2); + test(S("abcde"), 2, 1, SV("abcde"), 0, 5, 2); + test(S("abcde"), 2, 1, SV("abcde"), 0, 6, 2); + test(S("abcde"), 2, 1, SV("abcde"), 1, 0, 1); + test(S("abcde"), 2, 1, SV("abcde"), 1, 1, 1); + test(S("abcde"), 2, 1, SV("abcde"), 1, 2, 1); + test(S("abcde"), 2, 1, SV("abcde"), 1, 3, 1); + test(S("abcde"), 2, 1, SV("abcde"), 1, 4, 1); + test(S("abcde"), 2, 1, SV("abcde"), 1, 5, 1); + test(S("abcde"), 2, 1, SV("abcde"), 2, 0, 1); +} + +template +void test12() +{ + test(S("abcde"), 2, 1, SV("abcde"), 2, 1, 0); + test(S("abcde"), 2, 1, SV("abcde"), 2, 2, -1); + test(S("abcde"), 2, 1, SV("abcde"), 2, 3, -2); + test(S("abcde"), 2, 1, SV("abcde"), 2, 4, -2); + test(S("abcde"), 2, 1, SV("abcde"), 4, 0, 1); + test(S("abcde"), 2, 1, SV("abcde"), 4, 1, -2); + test(S("abcde"), 2, 1, SV("abcde"), 4, 2, -2); + test(S("abcde"), 2, 1, SV("abcde"), 5, 0, 1); + test(S("abcde"), 2, 1, SV("abcde"), 5, 1, 1); + test(S("abcde"), 2, 1, SV("abcde"), 6, 0, 0); + test(S("abcde"), 2, 1, SV("abcdefghij"), 0, 0, 1); + test(S("abcde"), 2, 1, SV("abcdefghij"), 0, 1, 2); + test(S("abcde"), 2, 1, SV("abcdefghij"), 0, 5, 2); + test(S("abcde"), 2, 1, SV("abcdefghij"), 0, 9, 2); + test(S("abcde"), 2, 1, SV("abcdefghij"), 0, 10, 2); + test(S("abcde"), 2, 1, SV("abcdefghij"), 0, 11, 2); + test(S("abcde"), 2, 1, SV("abcdefghij"), 1, 0, 1); + test(S("abcde"), 2, 1, SV("abcdefghij"), 1, 1, 1); + test(S("abcde"), 2, 1, SV("abcdefghij"), 1, 4, 1); + test(S("abcde"), 2, 1, SV("abcdefghij"), 1, 8, 1); + test(S("abcde"), 2, 1, SV("abcdefghij"), 1, 9, 1); + test(S("abcde"), 2, 1, SV("abcdefghij"), 1, 10, 1); + test(S("abcde"), 2, 1, SV("abcdefghij"), 5, 0, 1); + test(S("abcde"), 2, 1, SV("abcdefghij"), 5, 1, -3); + test(S("abcde"), 2, 1, SV("abcdefghij"), 5, 2, -3); + test(S("abcde"), 2, 1, SV("abcdefghij"), 5, 4, -3); + test(S("abcde"), 2, 1, SV("abcdefghij"), 5, 5, -3); + test(S("abcde"), 2, 1, SV("abcdefghij"), 5, 6, -3); + test(S("abcde"), 2, 1, SV("abcdefghij"), 9, 0, 1); + test(S("abcde"), 2, 1, SV("abcdefghij"), 9, 1, -7); + test(S("abcde"), 2, 1, SV("abcdefghij"), 9, 2, -7); + test(S("abcde"), 2, 1, SV("abcdefghij"), 10, 0, 1); + test(S("abcde"), 2, 1, SV("abcdefghij"), 10, 1, 1); + test(S("abcde"), 2, 1, SV("abcdefghij"), 11, 0, 0); + test(S("abcde"), 2, 1, SV("abcdefghijklmnopqrst"), 0, 0, 1); + test(S("abcde"), 2, 1, SV("abcdefghijklmnopqrst"), 0, 1, 2); + test(S("abcde"), 2, 1, SV("abcdefghijklmnopqrst"), 0, 10, 2); + test(S("abcde"), 2, 1, SV("abcdefghijklmnopqrst"), 0, 19, 2); + test(S("abcde"), 2, 1, SV("abcdefghijklmnopqrst"), 0, 20, 2); + test(S("abcde"), 2, 1, SV("abcdefghijklmnopqrst"), 0, 21, 2); + test(S("abcde"), 2, 1, SV("abcdefghijklmnopqrst"), 1, 0, 1); + test(S("abcde"), 2, 1, SV("abcdefghijklmnopqrst"), 1, 1, 1); + test(S("abcde"), 2, 1, SV("abcdefghijklmnopqrst"), 1, 9, 1); + test(S("abcde"), 2, 1, SV("abcdefghijklmnopqrst"), 1, 18, 1); + test(S("abcde"), 2, 1, SV("abcdefghijklmnopqrst"), 1, 19, 1); + test(S("abcde"), 2, 1, SV("abcdefghijklmnopqrst"), 1, 20, 1); + test(S("abcde"), 2, 1, SV("abcdefghijklmnopqrst"), 10, 0, 1); + test(S("abcde"), 2, 1, SV("abcdefghijklmnopqrst"), 10, 1, -8); + test(S("abcde"), 2, 1, SV("abcdefghijklmnopqrst"), 10, 5, -8); + test(S("abcde"), 2, 1, SV("abcdefghijklmnopqrst"), 10, 9, -8); + test(S("abcde"), 2, 1, SV("abcdefghijklmnopqrst"), 10, 10, -8); + test(S("abcde"), 2, 1, SV("abcdefghijklmnopqrst"), 10, 11, -8); + test(S("abcde"), 2, 1, SV("abcdefghijklmnopqrst"), 19, 0, 1); + test(S("abcde"), 2, 1, SV("abcdefghijklmnopqrst"), 19, 1, -17); + test(S("abcde"), 2, 1, SV("abcdefghijklmnopqrst"), 19, 2, -17); + test(S("abcde"), 2, 1, SV("abcdefghijklmnopqrst"), 20, 0, 1); + test(S("abcde"), 2, 1, SV("abcdefghijklmnopqrst"), 20, 1, 1); + test(S("abcde"), 2, 1, SV("abcdefghijklmnopqrst"), 21, 0, 0); + test(S("abcde"), 2, 2, SV(""), 0, 0, 2); + test(S("abcde"), 2, 2, SV(""), 0, 1, 2); + test(S("abcde"), 2, 2, SV(""), 1, 0, 0); + test(S("abcde"), 2, 2, SV("abcde"), 0, 0, 2); + test(S("abcde"), 2, 2, SV("abcde"), 0, 1, 2); + test(S("abcde"), 2, 2, SV("abcde"), 0, 2, 2); + test(S("abcde"), 2, 2, SV("abcde"), 0, 4, 2); + test(S("abcde"), 2, 2, SV("abcde"), 0, 5, 2); + test(S("abcde"), 2, 2, SV("abcde"), 0, 6, 2); + test(S("abcde"), 2, 2, SV("abcde"), 1, 0, 2); + test(S("abcde"), 2, 2, SV("abcde"), 1, 1, 1); + test(S("abcde"), 2, 2, SV("abcde"), 1, 2, 1); + test(S("abcde"), 2, 2, SV("abcde"), 1, 3, 1); + test(S("abcde"), 2, 2, SV("abcde"), 1, 4, 1); + test(S("abcde"), 2, 2, SV("abcde"), 1, 5, 1); + test(S("abcde"), 2, 2, SV("abcde"), 2, 0, 2); + test(S("abcde"), 2, 2, SV("abcde"), 2, 1, 1); + test(S("abcde"), 2, 2, SV("abcde"), 2, 2, 0); + test(S("abcde"), 2, 2, SV("abcde"), 2, 3, -1); + test(S("abcde"), 2, 2, SV("abcde"), 2, 4, -1); + test(S("abcde"), 2, 2, SV("abcde"), 4, 0, 2); + test(S("abcde"), 2, 2, SV("abcde"), 4, 1, -2); + test(S("abcde"), 2, 2, SV("abcde"), 4, 2, -2); + test(S("abcde"), 2, 2, SV("abcde"), 5, 0, 2); + test(S("abcde"), 2, 2, SV("abcde"), 5, 1, 2); + test(S("abcde"), 2, 2, SV("abcde"), 6, 0, 0); + test(S("abcde"), 2, 2, SV("abcdefghij"), 0, 0, 2); + test(S("abcde"), 2, 2, SV("abcdefghij"), 0, 1, 2); + test(S("abcde"), 2, 2, SV("abcdefghij"), 0, 5, 2); + test(S("abcde"), 2, 2, SV("abcdefghij"), 0, 9, 2); + test(S("abcde"), 2, 2, SV("abcdefghij"), 0, 10, 2); + test(S("abcde"), 2, 2, SV("abcdefghij"), 0, 11, 2); + test(S("abcde"), 2, 2, SV("abcdefghij"), 1, 0, 2); + test(S("abcde"), 2, 2, SV("abcdefghij"), 1, 1, 1); + test(S("abcde"), 2, 2, SV("abcdefghij"), 1, 4, 1); + test(S("abcde"), 2, 2, SV("abcdefghij"), 1, 8, 1); + test(S("abcde"), 2, 2, SV("abcdefghij"), 1, 9, 1); + test(S("abcde"), 2, 2, SV("abcdefghij"), 1, 10, 1); + test(S("abcde"), 2, 2, SV("abcdefghij"), 5, 0, 2); + test(S("abcde"), 2, 2, SV("abcdefghij"), 5, 1, -3); + test(S("abcde"), 2, 2, SV("abcdefghij"), 5, 2, -3); + test(S("abcde"), 2, 2, SV("abcdefghij"), 5, 4, -3); +} + +template +void test13() +{ + test(S("abcde"), 2, 2, SV("abcdefghij"), 5, 5, -3); + test(S("abcde"), 2, 2, SV("abcdefghij"), 5, 6, -3); + test(S("abcde"), 2, 2, SV("abcdefghij"), 9, 0, 2); + test(S("abcde"), 2, 2, SV("abcdefghij"), 9, 1, -7); + test(S("abcde"), 2, 2, SV("abcdefghij"), 9, 2, -7); + test(S("abcde"), 2, 2, SV("abcdefghij"), 10, 0, 2); + test(S("abcde"), 2, 2, SV("abcdefghij"), 10, 1, 2); + test(S("abcde"), 2, 2, SV("abcdefghij"), 11, 0, 0); + test(S("abcde"), 2, 2, SV("abcdefghijklmnopqrst"), 0, 0, 2); + test(S("abcde"), 2, 2, SV("abcdefghijklmnopqrst"), 0, 1, 2); + test(S("abcde"), 2, 2, SV("abcdefghijklmnopqrst"), 0, 10, 2); + test(S("abcde"), 2, 2, SV("abcdefghijklmnopqrst"), 0, 19, 2); + test(S("abcde"), 2, 2, SV("abcdefghijklmnopqrst"), 0, 20, 2); + test(S("abcde"), 2, 2, SV("abcdefghijklmnopqrst"), 0, 21, 2); + test(S("abcde"), 2, 2, SV("abcdefghijklmnopqrst"), 1, 0, 2); + test(S("abcde"), 2, 2, SV("abcdefghijklmnopqrst"), 1, 1, 1); + test(S("abcde"), 2, 2, SV("abcdefghijklmnopqrst"), 1, 9, 1); + test(S("abcde"), 2, 2, SV("abcdefghijklmnopqrst"), 1, 18, 1); + test(S("abcde"), 2, 2, SV("abcdefghijklmnopqrst"), 1, 19, 1); + test(S("abcde"), 2, 2, SV("abcdefghijklmnopqrst"), 1, 20, 1); + test(S("abcde"), 2, 2, SV("abcdefghijklmnopqrst"), 10, 0, 2); + test(S("abcde"), 2, 2, SV("abcdefghijklmnopqrst"), 10, 1, -8); + test(S("abcde"), 2, 2, SV("abcdefghijklmnopqrst"), 10, 5, -8); + test(S("abcde"), 2, 2, SV("abcdefghijklmnopqrst"), 10, 9, -8); + test(S("abcde"), 2, 2, SV("abcdefghijklmnopqrst"), 10, 10, -8); + test(S("abcde"), 2, 2, SV("abcdefghijklmnopqrst"), 10, 11, -8); + test(S("abcde"), 2, 2, SV("abcdefghijklmnopqrst"), 19, 0, 2); + test(S("abcde"), 2, 2, SV("abcdefghijklmnopqrst"), 19, 1, -17); + test(S("abcde"), 2, 2, SV("abcdefghijklmnopqrst"), 19, 2, -17); + test(S("abcde"), 2, 2, SV("abcdefghijklmnopqrst"), 20, 0, 2); + test(S("abcde"), 2, 2, SV("abcdefghijklmnopqrst"), 20, 1, 2); + test(S("abcde"), 2, 2, SV("abcdefghijklmnopqrst"), 21, 0, 0); + test(S("abcde"), 2, 3, SV(""), 0, 0, 3); + test(S("abcde"), 2, 3, SV(""), 0, 1, 3); + test(S("abcde"), 2, 3, SV(""), 1, 0, 0); + test(S("abcde"), 2, 3, SV("abcde"), 0, 0, 3); + test(S("abcde"), 2, 3, SV("abcde"), 0, 1, 2); + test(S("abcde"), 2, 3, SV("abcde"), 0, 2, 2); + test(S("abcde"), 2, 3, SV("abcde"), 0, 4, 2); + test(S("abcde"), 2, 3, SV("abcde"), 0, 5, 2); + test(S("abcde"), 2, 3, SV("abcde"), 0, 6, 2); + test(S("abcde"), 2, 3, SV("abcde"), 1, 0, 3); + test(S("abcde"), 2, 3, SV("abcde"), 1, 1, 1); + test(S("abcde"), 2, 3, SV("abcde"), 1, 2, 1); + test(S("abcde"), 2, 3, SV("abcde"), 1, 3, 1); + test(S("abcde"), 2, 3, SV("abcde"), 1, 4, 1); + test(S("abcde"), 2, 3, SV("abcde"), 1, 5, 1); + test(S("abcde"), 2, 3, SV("abcde"), 2, 0, 3); + test(S("abcde"), 2, 3, SV("abcde"), 2, 1, 2); + test(S("abcde"), 2, 3, SV("abcde"), 2, 2, 1); + test(S("abcde"), 2, 3, SV("abcde"), 2, 3, 0); + test(S("abcde"), 2, 3, SV("abcde"), 2, 4, 0); + test(S("abcde"), 2, 3, SV("abcde"), 4, 0, 3); + test(S("abcde"), 2, 3, SV("abcde"), 4, 1, -2); + test(S("abcde"), 2, 3, SV("abcde"), 4, 2, -2); + test(S("abcde"), 2, 3, SV("abcde"), 5, 0, 3); + test(S("abcde"), 2, 3, SV("abcde"), 5, 1, 3); + test(S("abcde"), 2, 3, SV("abcde"), 6, 0, 0); + test(S("abcde"), 2, 3, SV("abcdefghij"), 0, 0, 3); + test(S("abcde"), 2, 3, SV("abcdefghij"), 0, 1, 2); + test(S("abcde"), 2, 3, SV("abcdefghij"), 0, 5, 2); + test(S("abcde"), 2, 3, SV("abcdefghij"), 0, 9, 2); + test(S("abcde"), 2, 3, SV("abcdefghij"), 0, 10, 2); + test(S("abcde"), 2, 3, SV("abcdefghij"), 0, 11, 2); + test(S("abcde"), 2, 3, SV("abcdefghij"), 1, 0, 3); + test(S("abcde"), 2, 3, SV("abcdefghij"), 1, 1, 1); + test(S("abcde"), 2, 3, SV("abcdefghij"), 1, 4, 1); + test(S("abcde"), 2, 3, SV("abcdefghij"), 1, 8, 1); + test(S("abcde"), 2, 3, SV("abcdefghij"), 1, 9, 1); + test(S("abcde"), 2, 3, SV("abcdefghij"), 1, 10, 1); + test(S("abcde"), 2, 3, SV("abcdefghij"), 5, 0, 3); + test(S("abcde"), 2, 3, SV("abcdefghij"), 5, 1, -3); + test(S("abcde"), 2, 3, SV("abcdefghij"), 5, 2, -3); + test(S("abcde"), 2, 3, SV("abcdefghij"), 5, 4, -3); + test(S("abcde"), 2, 3, SV("abcdefghij"), 5, 5, -3); + test(S("abcde"), 2, 3, SV("abcdefghij"), 5, 6, -3); + test(S("abcde"), 2, 3, SV("abcdefghij"), 9, 0, 3); + test(S("abcde"), 2, 3, SV("abcdefghij"), 9, 1, -7); + test(S("abcde"), 2, 3, SV("abcdefghij"), 9, 2, -7); + test(S("abcde"), 2, 3, SV("abcdefghij"), 10, 0, 3); + test(S("abcde"), 2, 3, SV("abcdefghij"), 10, 1, 3); + test(S("abcde"), 2, 3, SV("abcdefghij"), 11, 0, 0); + test(S("abcde"), 2, 3, SV("abcdefghijklmnopqrst"), 0, 0, 3); + test(S("abcde"), 2, 3, SV("abcdefghijklmnopqrst"), 0, 1, 2); + test(S("abcde"), 2, 3, SV("abcdefghijklmnopqrst"), 0, 10, 2); + test(S("abcde"), 2, 3, SV("abcdefghijklmnopqrst"), 0, 19, 2); + test(S("abcde"), 2, 3, SV("abcdefghijklmnopqrst"), 0, 20, 2); + test(S("abcde"), 2, 3, SV("abcdefghijklmnopqrst"), 0, 21, 2); + test(S("abcde"), 2, 3, SV("abcdefghijklmnopqrst"), 1, 0, 3); + test(S("abcde"), 2, 3, SV("abcdefghijklmnopqrst"), 1, 1, 1); + test(S("abcde"), 2, 3, SV("abcdefghijklmnopqrst"), 1, 9, 1); + test(S("abcde"), 2, 3, SV("abcdefghijklmnopqrst"), 1, 18, 1); + test(S("abcde"), 2, 3, SV("abcdefghijklmnopqrst"), 1, 19, 1); + test(S("abcde"), 2, 3, SV("abcdefghijklmnopqrst"), 1, 20, 1); + test(S("abcde"), 2, 3, SV("abcdefghijklmnopqrst"), 10, 0, 3); + test(S("abcde"), 2, 3, SV("abcdefghijklmnopqrst"), 10, 1, -8); + test(S("abcde"), 2, 3, SV("abcdefghijklmnopqrst"), 10, 5, -8); + test(S("abcde"), 2, 3, SV("abcdefghijklmnopqrst"), 10, 9, -8); + test(S("abcde"), 2, 3, SV("abcdefghijklmnopqrst"), 10, 10, -8); + test(S("abcde"), 2, 3, SV("abcdefghijklmnopqrst"), 10, 11, -8); +} + +template +void test14() +{ + test(S("abcde"), 2, 3, SV("abcdefghijklmnopqrst"), 19, 0, 3); + test(S("abcde"), 2, 3, SV("abcdefghijklmnopqrst"), 19, 1, -17); + test(S("abcde"), 2, 3, SV("abcdefghijklmnopqrst"), 19, 2, -17); + test(S("abcde"), 2, 3, SV("abcdefghijklmnopqrst"), 20, 0, 3); + test(S("abcde"), 2, 3, SV("abcdefghijklmnopqrst"), 20, 1, 3); + test(S("abcde"), 2, 3, SV("abcdefghijklmnopqrst"), 21, 0, 0); + test(S("abcde"), 2, 4, SV(""), 0, 0, 3); + test(S("abcde"), 2, 4, SV(""), 0, 1, 3); + test(S("abcde"), 2, 4, SV(""), 1, 0, 0); + test(S("abcde"), 2, 4, SV("abcde"), 0, 0, 3); + test(S("abcde"), 2, 4, SV("abcde"), 0, 1, 2); + test(S("abcde"), 2, 4, SV("abcde"), 0, 2, 2); + test(S("abcde"), 2, 4, SV("abcde"), 0, 4, 2); + test(S("abcde"), 2, 4, SV("abcde"), 0, 5, 2); + test(S("abcde"), 2, 4, SV("abcde"), 0, 6, 2); + test(S("abcde"), 2, 4, SV("abcde"), 1, 0, 3); + test(S("abcde"), 2, 4, SV("abcde"), 1, 1, 1); + test(S("abcde"), 2, 4, SV("abcde"), 1, 2, 1); + test(S("abcde"), 2, 4, SV("abcde"), 1, 3, 1); + test(S("abcde"), 2, 4, SV("abcde"), 1, 4, 1); + test(S("abcde"), 2, 4, SV("abcde"), 1, 5, 1); + test(S("abcde"), 2, 4, SV("abcde"), 2, 0, 3); + test(S("abcde"), 2, 4, SV("abcde"), 2, 1, 2); + test(S("abcde"), 2, 4, SV("abcde"), 2, 2, 1); + test(S("abcde"), 2, 4, SV("abcde"), 2, 3, 0); + test(S("abcde"), 2, 4, SV("abcde"), 2, 4, 0); + test(S("abcde"), 2, 4, SV("abcde"), 4, 0, 3); + test(S("abcde"), 2, 4, SV("abcde"), 4, 1, -2); + test(S("abcde"), 2, 4, SV("abcde"), 4, 2, -2); + test(S("abcde"), 2, 4, SV("abcde"), 5, 0, 3); + test(S("abcde"), 2, 4, SV("abcde"), 5, 1, 3); + test(S("abcde"), 2, 4, SV("abcde"), 6, 0, 0); + test(S("abcde"), 2, 4, SV("abcdefghij"), 0, 0, 3); + test(S("abcde"), 2, 4, SV("abcdefghij"), 0, 1, 2); + test(S("abcde"), 2, 4, SV("abcdefghij"), 0, 5, 2); + test(S("abcde"), 2, 4, SV("abcdefghij"), 0, 9, 2); + test(S("abcde"), 2, 4, SV("abcdefghij"), 0, 10, 2); + test(S("abcde"), 2, 4, SV("abcdefghij"), 0, 11, 2); + test(S("abcde"), 2, 4, SV("abcdefghij"), 1, 0, 3); + test(S("abcde"), 2, 4, SV("abcdefghij"), 1, 1, 1); + test(S("abcde"), 2, 4, SV("abcdefghij"), 1, 4, 1); + test(S("abcde"), 2, 4, SV("abcdefghij"), 1, 8, 1); + test(S("abcde"), 2, 4, SV("abcdefghij"), 1, 9, 1); + test(S("abcde"), 2, 4, SV("abcdefghij"), 1, 10, 1); + test(S("abcde"), 2, 4, SV("abcdefghij"), 5, 0, 3); + test(S("abcde"), 2, 4, SV("abcdefghij"), 5, 1, -3); + test(S("abcde"), 2, 4, SV("abcdefghij"), 5, 2, -3); + test(S("abcde"), 2, 4, SV("abcdefghij"), 5, 4, -3); + test(S("abcde"), 2, 4, SV("abcdefghij"), 5, 5, -3); + test(S("abcde"), 2, 4, SV("abcdefghij"), 5, 6, -3); + test(S("abcde"), 2, 4, SV("abcdefghij"), 9, 0, 3); + test(S("abcde"), 2, 4, SV("abcdefghij"), 9, 1, -7); + test(S("abcde"), 2, 4, SV("abcdefghij"), 9, 2, -7); + test(S("abcde"), 2, 4, SV("abcdefghij"), 10, 0, 3); + test(S("abcde"), 2, 4, SV("abcdefghij"), 10, 1, 3); + test(S("abcde"), 2, 4, SV("abcdefghij"), 11, 0, 0); + test(S("abcde"), 2, 4, SV("abcdefghijklmnopqrst"), 0, 0, 3); + test(S("abcde"), 2, 4, SV("abcdefghijklmnopqrst"), 0, 1, 2); + test(S("abcde"), 2, 4, SV("abcdefghijklmnopqrst"), 0, 10, 2); + test(S("abcde"), 2, 4, SV("abcdefghijklmnopqrst"), 0, 19, 2); + test(S("abcde"), 2, 4, SV("abcdefghijklmnopqrst"), 0, 20, 2); + test(S("abcde"), 2, 4, SV("abcdefghijklmnopqrst"), 0, 21, 2); + test(S("abcde"), 2, 4, SV("abcdefghijklmnopqrst"), 1, 0, 3); + test(S("abcde"), 2, 4, SV("abcdefghijklmnopqrst"), 1, 1, 1); + test(S("abcde"), 2, 4, SV("abcdefghijklmnopqrst"), 1, 9, 1); + test(S("abcde"), 2, 4, SV("abcdefghijklmnopqrst"), 1, 18, 1); + test(S("abcde"), 2, 4, SV("abcdefghijklmnopqrst"), 1, 19, 1); + test(S("abcde"), 2, 4, SV("abcdefghijklmnopqrst"), 1, 20, 1); + test(S("abcde"), 2, 4, SV("abcdefghijklmnopqrst"), 10, 0, 3); + test(S("abcde"), 2, 4, SV("abcdefghijklmnopqrst"), 10, 1, -8); + test(S("abcde"), 2, 4, SV("abcdefghijklmnopqrst"), 10, 5, -8); + test(S("abcde"), 2, 4, SV("abcdefghijklmnopqrst"), 10, 9, -8); + test(S("abcde"), 2, 4, SV("abcdefghijklmnopqrst"), 10, 10, -8); + test(S("abcde"), 2, 4, SV("abcdefghijklmnopqrst"), 10, 11, -8); + test(S("abcde"), 2, 4, SV("abcdefghijklmnopqrst"), 19, 0, 3); + test(S("abcde"), 2, 4, SV("abcdefghijklmnopqrst"), 19, 1, -17); + test(S("abcde"), 2, 4, SV("abcdefghijklmnopqrst"), 19, 2, -17); + test(S("abcde"), 2, 4, SV("abcdefghijklmnopqrst"), 20, 0, 3); + test(S("abcde"), 2, 4, SV("abcdefghijklmnopqrst"), 20, 1, 3); + test(S("abcde"), 2, 4, SV("abcdefghijklmnopqrst"), 21, 0, 0); + test(S("abcde"), 4, 0, SV(""), 0, 0, 0); + test(S("abcde"), 4, 0, SV(""), 0, 1, 0); + test(S("abcde"), 4, 0, SV(""), 1, 0, 0); + test(S("abcde"), 4, 0, SV("abcde"), 0, 0, 0); + test(S("abcde"), 4, 0, SV("abcde"), 0, 1, -1); + test(S("abcde"), 4, 0, SV("abcde"), 0, 2, -2); + test(S("abcde"), 4, 0, SV("abcde"), 0, 4, -4); + test(S("abcde"), 4, 0, SV("abcde"), 0, 5, -5); + test(S("abcde"), 4, 0, SV("abcde"), 0, 6, -5); + test(S("abcde"), 4, 0, SV("abcde"), 1, 0, 0); + test(S("abcde"), 4, 0, SV("abcde"), 1, 1, -1); + test(S("abcde"), 4, 0, SV("abcde"), 1, 2, -2); + test(S("abcde"), 4, 0, SV("abcde"), 1, 3, -3); + test(S("abcde"), 4, 0, SV("abcde"), 1, 4, -4); + test(S("abcde"), 4, 0, SV("abcde"), 1, 5, -4); + test(S("abcde"), 4, 0, SV("abcde"), 2, 0, 0); + test(S("abcde"), 4, 0, SV("abcde"), 2, 1, -1); + test(S("abcde"), 4, 0, SV("abcde"), 2, 2, -2); + test(S("abcde"), 4, 0, SV("abcde"), 2, 3, -3); + test(S("abcde"), 4, 0, SV("abcde"), 2, 4, -3); +} + +template +void test15() +{ + test(S("abcde"), 4, 0, SV("abcde"), 4, 0, 0); + test(S("abcde"), 4, 0, SV("abcde"), 4, 1, -1); + test(S("abcde"), 4, 0, SV("abcde"), 4, 2, -1); + test(S("abcde"), 4, 0, SV("abcde"), 5, 0, 0); + test(S("abcde"), 4, 0, SV("abcde"), 5, 1, 0); + test(S("abcde"), 4, 0, SV("abcde"), 6, 0, 0); + test(S("abcde"), 4, 0, SV("abcdefghij"), 0, 0, 0); + test(S("abcde"), 4, 0, SV("abcdefghij"), 0, 1, -1); + test(S("abcde"), 4, 0, SV("abcdefghij"), 0, 5, -5); + test(S("abcde"), 4, 0, SV("abcdefghij"), 0, 9, -9); + test(S("abcde"), 4, 0, SV("abcdefghij"), 0, 10, -10); + test(S("abcde"), 4, 0, SV("abcdefghij"), 0, 11, -10); + test(S("abcde"), 4, 0, SV("abcdefghij"), 1, 0, 0); + test(S("abcde"), 4, 0, SV("abcdefghij"), 1, 1, -1); + test(S("abcde"), 4, 0, SV("abcdefghij"), 1, 4, -4); + test(S("abcde"), 4, 0, SV("abcdefghij"), 1, 8, -8); + test(S("abcde"), 4, 0, SV("abcdefghij"), 1, 9, -9); + test(S("abcde"), 4, 0, SV("abcdefghij"), 1, 10, -9); + test(S("abcde"), 4, 0, SV("abcdefghij"), 5, 0, 0); + test(S("abcde"), 4, 0, SV("abcdefghij"), 5, 1, -1); + test(S("abcde"), 4, 0, SV("abcdefghij"), 5, 2, -2); + test(S("abcde"), 4, 0, SV("abcdefghij"), 5, 4, -4); + test(S("abcde"), 4, 0, SV("abcdefghij"), 5, 5, -5); + test(S("abcde"), 4, 0, SV("abcdefghij"), 5, 6, -5); + test(S("abcde"), 4, 0, SV("abcdefghij"), 9, 0, 0); + test(S("abcde"), 4, 0, SV("abcdefghij"), 9, 1, -1); + test(S("abcde"), 4, 0, SV("abcdefghij"), 9, 2, -1); + test(S("abcde"), 4, 0, SV("abcdefghij"), 10, 0, 0); + test(S("abcde"), 4, 0, SV("abcdefghij"), 10, 1, 0); + test(S("abcde"), 4, 0, SV("abcdefghij"), 11, 0, 0); + test(S("abcde"), 4, 0, SV("abcdefghijklmnopqrst"), 0, 0, 0); + test(S("abcde"), 4, 0, SV("abcdefghijklmnopqrst"), 0, 1, -1); + test(S("abcde"), 4, 0, SV("abcdefghijklmnopqrst"), 0, 10, -10); + test(S("abcde"), 4, 0, SV("abcdefghijklmnopqrst"), 0, 19, -19); + test(S("abcde"), 4, 0, SV("abcdefghijklmnopqrst"), 0, 20, -20); + test(S("abcde"), 4, 0, SV("abcdefghijklmnopqrst"), 0, 21, -20); + test(S("abcde"), 4, 0, SV("abcdefghijklmnopqrst"), 1, 0, 0); + test(S("abcde"), 4, 0, SV("abcdefghijklmnopqrst"), 1, 1, -1); + test(S("abcde"), 4, 0, SV("abcdefghijklmnopqrst"), 1, 9, -9); + test(S("abcde"), 4, 0, SV("abcdefghijklmnopqrst"), 1, 18, -18); + test(S("abcde"), 4, 0, SV("abcdefghijklmnopqrst"), 1, 19, -19); + test(S("abcde"), 4, 0, SV("abcdefghijklmnopqrst"), 1, 20, -19); + test(S("abcde"), 4, 0, SV("abcdefghijklmnopqrst"), 10, 0, 0); + test(S("abcde"), 4, 0, SV("abcdefghijklmnopqrst"), 10, 1, -1); + test(S("abcde"), 4, 0, SV("abcdefghijklmnopqrst"), 10, 5, -5); + test(S("abcde"), 4, 0, SV("abcdefghijklmnopqrst"), 10, 9, -9); + test(S("abcde"), 4, 0, SV("abcdefghijklmnopqrst"), 10, 10, -10); + test(S("abcde"), 4, 0, SV("abcdefghijklmnopqrst"), 10, 11, -10); + test(S("abcde"), 4, 0, SV("abcdefghijklmnopqrst"), 19, 0, 0); + test(S("abcde"), 4, 0, SV("abcdefghijklmnopqrst"), 19, 1, -1); + test(S("abcde"), 4, 0, SV("abcdefghijklmnopqrst"), 19, 2, -1); + test(S("abcde"), 4, 0, SV("abcdefghijklmnopqrst"), 20, 0, 0); + test(S("abcde"), 4, 0, SV("abcdefghijklmnopqrst"), 20, 1, 0); + test(S("abcde"), 4, 0, SV("abcdefghijklmnopqrst"), 21, 0, 0); + test(S("abcde"), 4, 1, SV(""), 0, 0, 1); + test(S("abcde"), 4, 1, SV(""), 0, 1, 1); + test(S("abcde"), 4, 1, SV(""), 1, 0, 0); + test(S("abcde"), 4, 1, SV("abcde"), 0, 0, 1); + test(S("abcde"), 4, 1, SV("abcde"), 0, 1, 4); + test(S("abcde"), 4, 1, SV("abcde"), 0, 2, 4); + test(S("abcde"), 4, 1, SV("abcde"), 0, 4, 4); + test(S("abcde"), 4, 1, SV("abcde"), 0, 5, 4); + test(S("abcde"), 4, 1, SV("abcde"), 0, 6, 4); + test(S("abcde"), 4, 1, SV("abcde"), 1, 0, 1); + test(S("abcde"), 4, 1, SV("abcde"), 1, 1, 3); + test(S("abcde"), 4, 1, SV("abcde"), 1, 2, 3); + test(S("abcde"), 4, 1, SV("abcde"), 1, 3, 3); + test(S("abcde"), 4, 1, SV("abcde"), 1, 4, 3); + test(S("abcde"), 4, 1, SV("abcde"), 1, 5, 3); + test(S("abcde"), 4, 1, SV("abcde"), 2, 0, 1); + test(S("abcde"), 4, 1, SV("abcde"), 2, 1, 2); + test(S("abcde"), 4, 1, SV("abcde"), 2, 2, 2); + test(S("abcde"), 4, 1, SV("abcde"), 2, 3, 2); + test(S("abcde"), 4, 1, SV("abcde"), 2, 4, 2); + test(S("abcde"), 4, 1, SV("abcde"), 4, 0, 1); + test(S("abcde"), 4, 1, SV("abcde"), 4, 1, 0); + test(S("abcde"), 4, 1, SV("abcde"), 4, 2, 0); + test(S("abcde"), 4, 1, SV("abcde"), 5, 0, 1); + test(S("abcde"), 4, 1, SV("abcde"), 5, 1, 1); + test(S("abcde"), 4, 1, SV("abcde"), 6, 0, 0); + test(S("abcde"), 4, 1, SV("abcdefghij"), 0, 0, 1); + test(S("abcde"), 4, 1, SV("abcdefghij"), 0, 1, 4); + test(S("abcde"), 4, 1, SV("abcdefghij"), 0, 5, 4); + test(S("abcde"), 4, 1, SV("abcdefghij"), 0, 9, 4); + test(S("abcde"), 4, 1, SV("abcdefghij"), 0, 10, 4); + test(S("abcde"), 4, 1, SV("abcdefghij"), 0, 11, 4); + test(S("abcde"), 4, 1, SV("abcdefghij"), 1, 0, 1); + test(S("abcde"), 4, 1, SV("abcdefghij"), 1, 1, 3); + test(S("abcde"), 4, 1, SV("abcdefghij"), 1, 4, 3); + test(S("abcde"), 4, 1, SV("abcdefghij"), 1, 8, 3); + test(S("abcde"), 4, 1, SV("abcdefghij"), 1, 9, 3); + test(S("abcde"), 4, 1, SV("abcdefghij"), 1, 10, 3); + test(S("abcde"), 4, 1, SV("abcdefghij"), 5, 0, 1); + test(S("abcde"), 4, 1, SV("abcdefghij"), 5, 1, -1); + test(S("abcde"), 4, 1, SV("abcdefghij"), 5, 2, -1); + test(S("abcde"), 4, 1, SV("abcdefghij"), 5, 4, -1); + test(S("abcde"), 4, 1, SV("abcdefghij"), 5, 5, -1); + test(S("abcde"), 4, 1, SV("abcdefghij"), 5, 6, -1); + test(S("abcde"), 4, 1, SV("abcdefghij"), 9, 0, 1); + test(S("abcde"), 4, 1, SV("abcdefghij"), 9, 1, -5); +} + +template +void test16() +{ + test(S("abcde"), 4, 1, SV("abcdefghij"), 9, 2, -5); + test(S("abcde"), 4, 1, SV("abcdefghij"), 10, 0, 1); + test(S("abcde"), 4, 1, SV("abcdefghij"), 10, 1, 1); + test(S("abcde"), 4, 1, SV("abcdefghij"), 11, 0, 0); + test(S("abcde"), 4, 1, SV("abcdefghijklmnopqrst"), 0, 0, 1); + test(S("abcde"), 4, 1, SV("abcdefghijklmnopqrst"), 0, 1, 4); + test(S("abcde"), 4, 1, SV("abcdefghijklmnopqrst"), 0, 10, 4); + test(S("abcde"), 4, 1, SV("abcdefghijklmnopqrst"), 0, 19, 4); + test(S("abcde"), 4, 1, SV("abcdefghijklmnopqrst"), 0, 20, 4); + test(S("abcde"), 4, 1, SV("abcdefghijklmnopqrst"), 0, 21, 4); + test(S("abcde"), 4, 1, SV("abcdefghijklmnopqrst"), 1, 0, 1); + test(S("abcde"), 4, 1, SV("abcdefghijklmnopqrst"), 1, 1, 3); + test(S("abcde"), 4, 1, SV("abcdefghijklmnopqrst"), 1, 9, 3); + test(S("abcde"), 4, 1, SV("abcdefghijklmnopqrst"), 1, 18, 3); + test(S("abcde"), 4, 1, SV("abcdefghijklmnopqrst"), 1, 19, 3); + test(S("abcde"), 4, 1, SV("abcdefghijklmnopqrst"), 1, 20, 3); + test(S("abcde"), 4, 1, SV("abcdefghijklmnopqrst"), 10, 0, 1); + test(S("abcde"), 4, 1, SV("abcdefghijklmnopqrst"), 10, 1, -6); + test(S("abcde"), 4, 1, SV("abcdefghijklmnopqrst"), 10, 5, -6); + test(S("abcde"), 4, 1, SV("abcdefghijklmnopqrst"), 10, 9, -6); + test(S("abcde"), 4, 1, SV("abcdefghijklmnopqrst"), 10, 10, -6); + test(S("abcde"), 4, 1, SV("abcdefghijklmnopqrst"), 10, 11, -6); + test(S("abcde"), 4, 1, SV("abcdefghijklmnopqrst"), 19, 0, 1); + test(S("abcde"), 4, 1, SV("abcdefghijklmnopqrst"), 19, 1, -15); + test(S("abcde"), 4, 1, SV("abcdefghijklmnopqrst"), 19, 2, -15); + test(S("abcde"), 4, 1, SV("abcdefghijklmnopqrst"), 20, 0, 1); + test(S("abcde"), 4, 1, SV("abcdefghijklmnopqrst"), 20, 1, 1); + test(S("abcde"), 4, 1, SV("abcdefghijklmnopqrst"), 21, 0, 0); + test(S("abcde"), 4, 2, SV(""), 0, 0, 1); + test(S("abcde"), 4, 2, SV(""), 0, 1, 1); + test(S("abcde"), 4, 2, SV(""), 1, 0, 0); + test(S("abcde"), 4, 2, SV("abcde"), 0, 0, 1); + test(S("abcde"), 4, 2, SV("abcde"), 0, 1, 4); + test(S("abcde"), 4, 2, SV("abcde"), 0, 2, 4); + test(S("abcde"), 4, 2, SV("abcde"), 0, 4, 4); + test(S("abcde"), 4, 2, SV("abcde"), 0, 5, 4); + test(S("abcde"), 4, 2, SV("abcde"), 0, 6, 4); + test(S("abcde"), 4, 2, SV("abcde"), 1, 0, 1); + test(S("abcde"), 4, 2, SV("abcde"), 1, 1, 3); + test(S("abcde"), 4, 2, SV("abcde"), 1, 2, 3); + test(S("abcde"), 4, 2, SV("abcde"), 1, 3, 3); + test(S("abcde"), 4, 2, SV("abcde"), 1, 4, 3); + test(S("abcde"), 4, 2, SV("abcde"), 1, 5, 3); + test(S("abcde"), 4, 2, SV("abcde"), 2, 0, 1); + test(S("abcde"), 4, 2, SV("abcde"), 2, 1, 2); + test(S("abcde"), 4, 2, SV("abcde"), 2, 2, 2); + test(S("abcde"), 4, 2, SV("abcde"), 2, 3, 2); + test(S("abcde"), 4, 2, SV("abcde"), 2, 4, 2); + test(S("abcde"), 4, 2, SV("abcde"), 4, 0, 1); + test(S("abcde"), 4, 2, SV("abcde"), 4, 1, 0); + test(S("abcde"), 4, 2, SV("abcde"), 4, 2, 0); + test(S("abcde"), 4, 2, SV("abcde"), 5, 0, 1); + test(S("abcde"), 4, 2, SV("abcde"), 5, 1, 1); + test(S("abcde"), 4, 2, SV("abcde"), 6, 0, 0); + test(S("abcde"), 4, 2, SV("abcdefghij"), 0, 0, 1); + test(S("abcde"), 4, 2, SV("abcdefghij"), 0, 1, 4); + test(S("abcde"), 4, 2, SV("abcdefghij"), 0, 5, 4); + test(S("abcde"), 4, 2, SV("abcdefghij"), 0, 9, 4); + test(S("abcde"), 4, 2, SV("abcdefghij"), 0, 10, 4); + test(S("abcde"), 4, 2, SV("abcdefghij"), 0, 11, 4); + test(S("abcde"), 4, 2, SV("abcdefghij"), 1, 0, 1); + test(S("abcde"), 4, 2, SV("abcdefghij"), 1, 1, 3); + test(S("abcde"), 4, 2, SV("abcdefghij"), 1, 4, 3); + test(S("abcde"), 4, 2, SV("abcdefghij"), 1, 8, 3); + test(S("abcde"), 4, 2, SV("abcdefghij"), 1, 9, 3); + test(S("abcde"), 4, 2, SV("abcdefghij"), 1, 10, 3); + test(S("abcde"), 4, 2, SV("abcdefghij"), 5, 0, 1); + test(S("abcde"), 4, 2, SV("abcdefghij"), 5, 1, -1); + test(S("abcde"), 4, 2, SV("abcdefghij"), 5, 2, -1); + test(S("abcde"), 4, 2, SV("abcdefghij"), 5, 4, -1); + test(S("abcde"), 4, 2, SV("abcdefghij"), 5, 5, -1); + test(S("abcde"), 4, 2, SV("abcdefghij"), 5, 6, -1); + test(S("abcde"), 4, 2, SV("abcdefghij"), 9, 0, 1); + test(S("abcde"), 4, 2, SV("abcdefghij"), 9, 1, -5); + test(S("abcde"), 4, 2, SV("abcdefghij"), 9, 2, -5); + test(S("abcde"), 4, 2, SV("abcdefghij"), 10, 0, 1); + test(S("abcde"), 4, 2, SV("abcdefghij"), 10, 1, 1); + test(S("abcde"), 4, 2, SV("abcdefghij"), 11, 0, 0); + test(S("abcde"), 4, 2, SV("abcdefghijklmnopqrst"), 0, 0, 1); + test(S("abcde"), 4, 2, SV("abcdefghijklmnopqrst"), 0, 1, 4); + test(S("abcde"), 4, 2, SV("abcdefghijklmnopqrst"), 0, 10, 4); + test(S("abcde"), 4, 2, SV("abcdefghijklmnopqrst"), 0, 19, 4); + test(S("abcde"), 4, 2, SV("abcdefghijklmnopqrst"), 0, 20, 4); + test(S("abcde"), 4, 2, SV("abcdefghijklmnopqrst"), 0, 21, 4); + test(S("abcde"), 4, 2, SV("abcdefghijklmnopqrst"), 1, 0, 1); + test(S("abcde"), 4, 2, SV("abcdefghijklmnopqrst"), 1, 1, 3); + test(S("abcde"), 4, 2, SV("abcdefghijklmnopqrst"), 1, 9, 3); + test(S("abcde"), 4, 2, SV("abcdefghijklmnopqrst"), 1, 18, 3); + test(S("abcde"), 4, 2, SV("abcdefghijklmnopqrst"), 1, 19, 3); + test(S("abcde"), 4, 2, SV("abcdefghijklmnopqrst"), 1, 20, 3); + test(S("abcde"), 4, 2, SV("abcdefghijklmnopqrst"), 10, 0, 1); + test(S("abcde"), 4, 2, SV("abcdefghijklmnopqrst"), 10, 1, -6); + test(S("abcde"), 4, 2, SV("abcdefghijklmnopqrst"), 10, 5, -6); + test(S("abcde"), 4, 2, SV("abcdefghijklmnopqrst"), 10, 9, -6); + test(S("abcde"), 4, 2, SV("abcdefghijklmnopqrst"), 10, 10, -6); + test(S("abcde"), 4, 2, SV("abcdefghijklmnopqrst"), 10, 11, -6); + test(S("abcde"), 4, 2, SV("abcdefghijklmnopqrst"), 19, 0, 1); + test(S("abcde"), 4, 2, SV("abcdefghijklmnopqrst"), 19, 1, -15); + test(S("abcde"), 4, 2, SV("abcdefghijklmnopqrst"), 19, 2, -15); + test(S("abcde"), 4, 2, SV("abcdefghijklmnopqrst"), 20, 0, 1); +} + +template +void test17() +{ + test(S("abcde"), 4, 2, SV("abcdefghijklmnopqrst"), 20, 1, 1); + test(S("abcde"), 4, 2, SV("abcdefghijklmnopqrst"), 21, 0, 0); + test(S("abcde"), 5, 0, SV(""), 0, 0, 0); + test(S("abcde"), 5, 0, SV(""), 0, 1, 0); + test(S("abcde"), 5, 0, SV(""), 1, 0, 0); + test(S("abcde"), 5, 0, SV("abcde"), 0, 0, 0); + test(S("abcde"), 5, 0, SV("abcde"), 0, 1, -1); + test(S("abcde"), 5, 0, SV("abcde"), 0, 2, -2); + test(S("abcde"), 5, 0, SV("abcde"), 0, 4, -4); + test(S("abcde"), 5, 0, SV("abcde"), 0, 5, -5); + test(S("abcde"), 5, 0, SV("abcde"), 0, 6, -5); + test(S("abcde"), 5, 0, SV("abcde"), 1, 0, 0); + test(S("abcde"), 5, 0, SV("abcde"), 1, 1, -1); + test(S("abcde"), 5, 0, SV("abcde"), 1, 2, -2); + test(S("abcde"), 5, 0, SV("abcde"), 1, 3, -3); + test(S("abcde"), 5, 0, SV("abcde"), 1, 4, -4); + test(S("abcde"), 5, 0, SV("abcde"), 1, 5, -4); + test(S("abcde"), 5, 0, SV("abcde"), 2, 0, 0); + test(S("abcde"), 5, 0, SV("abcde"), 2, 1, -1); + test(S("abcde"), 5, 0, SV("abcde"), 2, 2, -2); + test(S("abcde"), 5, 0, SV("abcde"), 2, 3, -3); + test(S("abcde"), 5, 0, SV("abcde"), 2, 4, -3); + test(S("abcde"), 5, 0, SV("abcde"), 4, 0, 0); + test(S("abcde"), 5, 0, SV("abcde"), 4, 1, -1); + test(S("abcde"), 5, 0, SV("abcde"), 4, 2, -1); + test(S("abcde"), 5, 0, SV("abcde"), 5, 0, 0); + test(S("abcde"), 5, 0, SV("abcde"), 5, 1, 0); + test(S("abcde"), 5, 0, SV("abcde"), 6, 0, 0); + test(S("abcde"), 5, 0, SV("abcdefghij"), 0, 0, 0); + test(S("abcde"), 5, 0, SV("abcdefghij"), 0, 1, -1); + test(S("abcde"), 5, 0, SV("abcdefghij"), 0, 5, -5); + test(S("abcde"), 5, 0, SV("abcdefghij"), 0, 9, -9); + test(S("abcde"), 5, 0, SV("abcdefghij"), 0, 10, -10); + test(S("abcde"), 5, 0, SV("abcdefghij"), 0, 11, -10); + test(S("abcde"), 5, 0, SV("abcdefghij"), 1, 0, 0); + test(S("abcde"), 5, 0, SV("abcdefghij"), 1, 1, -1); + test(S("abcde"), 5, 0, SV("abcdefghij"), 1, 4, -4); + test(S("abcde"), 5, 0, SV("abcdefghij"), 1, 8, -8); + test(S("abcde"), 5, 0, SV("abcdefghij"), 1, 9, -9); + test(S("abcde"), 5, 0, SV("abcdefghij"), 1, 10, -9); + test(S("abcde"), 5, 0, SV("abcdefghij"), 5, 0, 0); + test(S("abcde"), 5, 0, SV("abcdefghij"), 5, 1, -1); + test(S("abcde"), 5, 0, SV("abcdefghij"), 5, 2, -2); + test(S("abcde"), 5, 0, SV("abcdefghij"), 5, 4, -4); + test(S("abcde"), 5, 0, SV("abcdefghij"), 5, 5, -5); + test(S("abcde"), 5, 0, SV("abcdefghij"), 5, 6, -5); + test(S("abcde"), 5, 0, SV("abcdefghij"), 9, 0, 0); + test(S("abcde"), 5, 0, SV("abcdefghij"), 9, 1, -1); + test(S("abcde"), 5, 0, SV("abcdefghij"), 9, 2, -1); + test(S("abcde"), 5, 0, SV("abcdefghij"), 10, 0, 0); + test(S("abcde"), 5, 0, SV("abcdefghij"), 10, 1, 0); + test(S("abcde"), 5, 0, SV("abcdefghij"), 11, 0, 0); + test(S("abcde"), 5, 0, SV("abcdefghijklmnopqrst"), 0, 0, 0); + test(S("abcde"), 5, 0, SV("abcdefghijklmnopqrst"), 0, 1, -1); + test(S("abcde"), 5, 0, SV("abcdefghijklmnopqrst"), 0, 10, -10); + test(S("abcde"), 5, 0, SV("abcdefghijklmnopqrst"), 0, 19, -19); + test(S("abcde"), 5, 0, SV("abcdefghijklmnopqrst"), 0, 20, -20); + test(S("abcde"), 5, 0, SV("abcdefghijklmnopqrst"), 0, 21, -20); + test(S("abcde"), 5, 0, SV("abcdefghijklmnopqrst"), 1, 0, 0); + test(S("abcde"), 5, 0, SV("abcdefghijklmnopqrst"), 1, 1, -1); + test(S("abcde"), 5, 0, SV("abcdefghijklmnopqrst"), 1, 9, -9); + test(S("abcde"), 5, 0, SV("abcdefghijklmnopqrst"), 1, 18, -18); + test(S("abcde"), 5, 0, SV("abcdefghijklmnopqrst"), 1, 19, -19); + test(S("abcde"), 5, 0, SV("abcdefghijklmnopqrst"), 1, 20, -19); + test(S("abcde"), 5, 0, SV("abcdefghijklmnopqrst"), 10, 0, 0); + test(S("abcde"), 5, 0, SV("abcdefghijklmnopqrst"), 10, 1, -1); + test(S("abcde"), 5, 0, SV("abcdefghijklmnopqrst"), 10, 5, -5); + test(S("abcde"), 5, 0, SV("abcdefghijklmnopqrst"), 10, 9, -9); + test(S("abcde"), 5, 0, SV("abcdefghijklmnopqrst"), 10, 10, -10); + test(S("abcde"), 5, 0, SV("abcdefghijklmnopqrst"), 10, 11, -10); + test(S("abcde"), 5, 0, SV("abcdefghijklmnopqrst"), 19, 0, 0); + test(S("abcde"), 5, 0, SV("abcdefghijklmnopqrst"), 19, 1, -1); + test(S("abcde"), 5, 0, SV("abcdefghijklmnopqrst"), 19, 2, -1); + test(S("abcde"), 5, 0, SV("abcdefghijklmnopqrst"), 20, 0, 0); + test(S("abcde"), 5, 0, SV("abcdefghijklmnopqrst"), 20, 1, 0); + test(S("abcde"), 5, 0, SV("abcdefghijklmnopqrst"), 21, 0, 0); + test(S("abcde"), 5, 1, SV(""), 0, 0, 0); + test(S("abcde"), 5, 1, SV(""), 0, 1, 0); + test(S("abcde"), 5, 1, SV(""), 1, 0, 0); + test(S("abcde"), 5, 1, SV("abcde"), 0, 0, 0); + test(S("abcde"), 5, 1, SV("abcde"), 0, 1, -1); + test(S("abcde"), 5, 1, SV("abcde"), 0, 2, -2); + test(S("abcde"), 5, 1, SV("abcde"), 0, 4, -4); + test(S("abcde"), 5, 1, SV("abcde"), 0, 5, -5); + test(S("abcde"), 5, 1, SV("abcde"), 0, 6, -5); + test(S("abcde"), 5, 1, SV("abcde"), 1, 0, 0); + test(S("abcde"), 5, 1, SV("abcde"), 1, 1, -1); + test(S("abcde"), 5, 1, SV("abcde"), 1, 2, -2); + test(S("abcde"), 5, 1, SV("abcde"), 1, 3, -3); + test(S("abcde"), 5, 1, SV("abcde"), 1, 4, -4); + test(S("abcde"), 5, 1, SV("abcde"), 1, 5, -4); + test(S("abcde"), 5, 1, SV("abcde"), 2, 0, 0); + test(S("abcde"), 5, 1, SV("abcde"), 2, 1, -1); + test(S("abcde"), 5, 1, SV("abcde"), 2, 2, -2); + test(S("abcde"), 5, 1, SV("abcde"), 2, 3, -3); + test(S("abcde"), 5, 1, SV("abcde"), 2, 4, -3); + test(S("abcde"), 5, 1, SV("abcde"), 4, 0, 0); + test(S("abcde"), 5, 1, SV("abcde"), 4, 1, -1); + test(S("abcde"), 5, 1, SV("abcde"), 4, 2, -1); + test(S("abcde"), 5, 1, SV("abcde"), 5, 0, 0); +} + +template +void test18() +{ + test(S("abcde"), 5, 1, SV("abcde"), 5, 1, 0); + test(S("abcde"), 5, 1, SV("abcde"), 6, 0, 0); + test(S("abcde"), 5, 1, SV("abcdefghij"), 0, 0, 0); + test(S("abcde"), 5, 1, SV("abcdefghij"), 0, 1, -1); + test(S("abcde"), 5, 1, SV("abcdefghij"), 0, 5, -5); + test(S("abcde"), 5, 1, SV("abcdefghij"), 0, 9, -9); + test(S("abcde"), 5, 1, SV("abcdefghij"), 0, 10, -10); + test(S("abcde"), 5, 1, SV("abcdefghij"), 0, 11, -10); + test(S("abcde"), 5, 1, SV("abcdefghij"), 1, 0, 0); + test(S("abcde"), 5, 1, SV("abcdefghij"), 1, 1, -1); + test(S("abcde"), 5, 1, SV("abcdefghij"), 1, 4, -4); + test(S("abcde"), 5, 1, SV("abcdefghij"), 1, 8, -8); + test(S("abcde"), 5, 1, SV("abcdefghij"), 1, 9, -9); + test(S("abcde"), 5, 1, SV("abcdefghij"), 1, 10, -9); + test(S("abcde"), 5, 1, SV("abcdefghij"), 5, 0, 0); + test(S("abcde"), 5, 1, SV("abcdefghij"), 5, 1, -1); + test(S("abcde"), 5, 1, SV("abcdefghij"), 5, 2, -2); + test(S("abcde"), 5, 1, SV("abcdefghij"), 5, 4, -4); + test(S("abcde"), 5, 1, SV("abcdefghij"), 5, 5, -5); + test(S("abcde"), 5, 1, SV("abcdefghij"), 5, 6, -5); + test(S("abcde"), 5, 1, SV("abcdefghij"), 9, 0, 0); + test(S("abcde"), 5, 1, SV("abcdefghij"), 9, 1, -1); + test(S("abcde"), 5, 1, SV("abcdefghij"), 9, 2, -1); + test(S("abcde"), 5, 1, SV("abcdefghij"), 10, 0, 0); + test(S("abcde"), 5, 1, SV("abcdefghij"), 10, 1, 0); + test(S("abcde"), 5, 1, SV("abcdefghij"), 11, 0, 0); + test(S("abcde"), 5, 1, SV("abcdefghijklmnopqrst"), 0, 0, 0); + test(S("abcde"), 5, 1, SV("abcdefghijklmnopqrst"), 0, 1, -1); + test(S("abcde"), 5, 1, SV("abcdefghijklmnopqrst"), 0, 10, -10); + test(S("abcde"), 5, 1, SV("abcdefghijklmnopqrst"), 0, 19, -19); + test(S("abcde"), 5, 1, SV("abcdefghijklmnopqrst"), 0, 20, -20); + test(S("abcde"), 5, 1, SV("abcdefghijklmnopqrst"), 0, 21, -20); + test(S("abcde"), 5, 1, SV("abcdefghijklmnopqrst"), 1, 0, 0); + test(S("abcde"), 5, 1, SV("abcdefghijklmnopqrst"), 1, 1, -1); + test(S("abcde"), 5, 1, SV("abcdefghijklmnopqrst"), 1, 9, -9); + test(S("abcde"), 5, 1, SV("abcdefghijklmnopqrst"), 1, 18, -18); + test(S("abcde"), 5, 1, SV("abcdefghijklmnopqrst"), 1, 19, -19); + test(S("abcde"), 5, 1, SV("abcdefghijklmnopqrst"), 1, 20, -19); + test(S("abcde"), 5, 1, SV("abcdefghijklmnopqrst"), 10, 0, 0); + test(S("abcde"), 5, 1, SV("abcdefghijklmnopqrst"), 10, 1, -1); + test(S("abcde"), 5, 1, SV("abcdefghijklmnopqrst"), 10, 5, -5); + test(S("abcde"), 5, 1, SV("abcdefghijklmnopqrst"), 10, 9, -9); + test(S("abcde"), 5, 1, SV("abcdefghijklmnopqrst"), 10, 10, -10); + test(S("abcde"), 5, 1, SV("abcdefghijklmnopqrst"), 10, 11, -10); + test(S("abcde"), 5, 1, SV("abcdefghijklmnopqrst"), 19, 0, 0); + test(S("abcde"), 5, 1, SV("abcdefghijklmnopqrst"), 19, 1, -1); + test(S("abcde"), 5, 1, SV("abcdefghijklmnopqrst"), 19, 2, -1); + test(S("abcde"), 5, 1, SV("abcdefghijklmnopqrst"), 20, 0, 0); + test(S("abcde"), 5, 1, SV("abcdefghijklmnopqrst"), 20, 1, 0); + test(S("abcde"), 5, 1, SV("abcdefghijklmnopqrst"), 21, 0, 0); + test(S("abcde"), 6, 0, SV(""), 0, 0, 0); + test(S("abcde"), 6, 0, SV(""), 0, 1, 0); + test(S("abcde"), 6, 0, SV(""), 1, 0, 0); + test(S("abcde"), 6, 0, SV("abcde"), 0, 0, 0); + test(S("abcde"), 6, 0, SV("abcde"), 0, 1, 0); + test(S("abcde"), 6, 0, SV("abcde"), 0, 2, 0); + test(S("abcde"), 6, 0, SV("abcde"), 0, 4, 0); + test(S("abcde"), 6, 0, SV("abcde"), 0, 5, 0); + test(S("abcde"), 6, 0, SV("abcde"), 0, 6, 0); + test(S("abcde"), 6, 0, SV("abcde"), 1, 0, 0); + test(S("abcde"), 6, 0, SV("abcde"), 1, 1, 0); + test(S("abcde"), 6, 0, SV("abcde"), 1, 2, 0); + test(S("abcde"), 6, 0, SV("abcde"), 1, 3, 0); + test(S("abcde"), 6, 0, SV("abcde"), 1, 4, 0); + test(S("abcde"), 6, 0, SV("abcde"), 1, 5, 0); + test(S("abcde"), 6, 0, SV("abcde"), 2, 0, 0); + test(S("abcde"), 6, 0, SV("abcde"), 2, 1, 0); + test(S("abcde"), 6, 0, SV("abcde"), 2, 2, 0); + test(S("abcde"), 6, 0, SV("abcde"), 2, 3, 0); + test(S("abcde"), 6, 0, SV("abcde"), 2, 4, 0); + test(S("abcde"), 6, 0, SV("abcde"), 4, 0, 0); + test(S("abcde"), 6, 0, SV("abcde"), 4, 1, 0); + test(S("abcde"), 6, 0, SV("abcde"), 4, 2, 0); + test(S("abcde"), 6, 0, SV("abcde"), 5, 0, 0); + test(S("abcde"), 6, 0, SV("abcde"), 5, 1, 0); + test(S("abcde"), 6, 0, SV("abcde"), 6, 0, 0); + test(S("abcde"), 6, 0, SV("abcdefghij"), 0, 0, 0); + test(S("abcde"), 6, 0, SV("abcdefghij"), 0, 1, 0); + test(S("abcde"), 6, 0, SV("abcdefghij"), 0, 5, 0); + test(S("abcde"), 6, 0, SV("abcdefghij"), 0, 9, 0); + test(S("abcde"), 6, 0, SV("abcdefghij"), 0, 10, 0); + test(S("abcde"), 6, 0, SV("abcdefghij"), 0, 11, 0); + test(S("abcde"), 6, 0, SV("abcdefghij"), 1, 0, 0); + test(S("abcde"), 6, 0, SV("abcdefghij"), 1, 1, 0); + test(S("abcde"), 6, 0, SV("abcdefghij"), 1, 4, 0); + test(S("abcde"), 6, 0, SV("abcdefghij"), 1, 8, 0); + test(S("abcde"), 6, 0, SV("abcdefghij"), 1, 9, 0); + test(S("abcde"), 6, 0, SV("abcdefghij"), 1, 10, 0); + test(S("abcde"), 6, 0, SV("abcdefghij"), 5, 0, 0); + test(S("abcde"), 6, 0, SV("abcdefghij"), 5, 1, 0); + test(S("abcde"), 6, 0, SV("abcdefghij"), 5, 2, 0); + test(S("abcde"), 6, 0, SV("abcdefghij"), 5, 4, 0); + test(S("abcde"), 6, 0, SV("abcdefghij"), 5, 5, 0); + test(S("abcde"), 6, 0, SV("abcdefghij"), 5, 6, 0); + test(S("abcde"), 6, 0, SV("abcdefghij"), 9, 0, 0); + test(S("abcde"), 6, 0, SV("abcdefghij"), 9, 1, 0); + test(S("abcde"), 6, 0, SV("abcdefghij"), 9, 2, 0); + test(S("abcde"), 6, 0, SV("abcdefghij"), 10, 0, 0); + test(S("abcde"), 6, 0, SV("abcdefghij"), 10, 1, 0); + test(S("abcde"), 6, 0, SV("abcdefghij"), 11, 0, 0); +} + +template +void test19() +{ + test(S("abcde"), 6, 0, SV("abcdefghijklmnopqrst"), 0, 0, 0); + test(S("abcde"), 6, 0, SV("abcdefghijklmnopqrst"), 0, 1, 0); + test(S("abcde"), 6, 0, SV("abcdefghijklmnopqrst"), 0, 10, 0); + test(S("abcde"), 6, 0, SV("abcdefghijklmnopqrst"), 0, 19, 0); + test(S("abcde"), 6, 0, SV("abcdefghijklmnopqrst"), 0, 20, 0); + test(S("abcde"), 6, 0, SV("abcdefghijklmnopqrst"), 0, 21, 0); + test(S("abcde"), 6, 0, SV("abcdefghijklmnopqrst"), 1, 0, 0); + test(S("abcde"), 6, 0, SV("abcdefghijklmnopqrst"), 1, 1, 0); + test(S("abcde"), 6, 0, SV("abcdefghijklmnopqrst"), 1, 9, 0); + test(S("abcde"), 6, 0, SV("abcdefghijklmnopqrst"), 1, 18, 0); + test(S("abcde"), 6, 0, SV("abcdefghijklmnopqrst"), 1, 19, 0); + test(S("abcde"), 6, 0, SV("abcdefghijklmnopqrst"), 1, 20, 0); + test(S("abcde"), 6, 0, SV("abcdefghijklmnopqrst"), 10, 0, 0); + test(S("abcde"), 6, 0, SV("abcdefghijklmnopqrst"), 10, 1, 0); + test(S("abcde"), 6, 0, SV("abcdefghijklmnopqrst"), 10, 5, 0); + test(S("abcde"), 6, 0, SV("abcdefghijklmnopqrst"), 10, 9, 0); + test(S("abcde"), 6, 0, SV("abcdefghijklmnopqrst"), 10, 10, 0); + test(S("abcde"), 6, 0, SV("abcdefghijklmnopqrst"), 10, 11, 0); + test(S("abcde"), 6, 0, SV("abcdefghijklmnopqrst"), 19, 0, 0); + test(S("abcde"), 6, 0, SV("abcdefghijklmnopqrst"), 19, 1, 0); + test(S("abcde"), 6, 0, SV("abcdefghijklmnopqrst"), 19, 2, 0); + test(S("abcde"), 6, 0, SV("abcdefghijklmnopqrst"), 20, 0, 0); + test(S("abcde"), 6, 0, SV("abcdefghijklmnopqrst"), 20, 1, 0); + test(S("abcde"), 6, 0, SV("abcdefghijklmnopqrst"), 21, 0, 0); + test(S("abcdefghij"), 0, 0, SV(""), 0, 0, 0); + test(S("abcdefghij"), 0, 0, SV(""), 0, 1, 0); + test(S("abcdefghij"), 0, 0, SV(""), 1, 0, 0); + test(S("abcdefghij"), 0, 0, SV("abcde"), 0, 0, 0); + test(S("abcdefghij"), 0, 0, SV("abcde"), 0, 1, -1); + test(S("abcdefghij"), 0, 0, SV("abcde"), 0, 2, -2); + test(S("abcdefghij"), 0, 0, SV("abcde"), 0, 4, -4); + test(S("abcdefghij"), 0, 0, SV("abcde"), 0, 5, -5); + test(S("abcdefghij"), 0, 0, SV("abcde"), 0, 6, -5); + test(S("abcdefghij"), 0, 0, SV("abcde"), 1, 0, 0); + test(S("abcdefghij"), 0, 0, SV("abcde"), 1, 1, -1); + test(S("abcdefghij"), 0, 0, SV("abcde"), 1, 2, -2); + test(S("abcdefghij"), 0, 0, SV("abcde"), 1, 3, -3); + test(S("abcdefghij"), 0, 0, SV("abcde"), 1, 4, -4); + test(S("abcdefghij"), 0, 0, SV("abcde"), 1, 5, -4); + test(S("abcdefghij"), 0, 0, SV("abcde"), 2, 0, 0); + test(S("abcdefghij"), 0, 0, SV("abcde"), 2, 1, -1); + test(S("abcdefghij"), 0, 0, SV("abcde"), 2, 2, -2); + test(S("abcdefghij"), 0, 0, SV("abcde"), 2, 3, -3); + test(S("abcdefghij"), 0, 0, SV("abcde"), 2, 4, -3); + test(S("abcdefghij"), 0, 0, SV("abcde"), 4, 0, 0); + test(S("abcdefghij"), 0, 0, SV("abcde"), 4, 1, -1); + test(S("abcdefghij"), 0, 0, SV("abcde"), 4, 2, -1); + test(S("abcdefghij"), 0, 0, SV("abcde"), 5, 0, 0); + test(S("abcdefghij"), 0, 0, SV("abcde"), 5, 1, 0); + test(S("abcdefghij"), 0, 0, SV("abcde"), 6, 0, 0); + test(S("abcdefghij"), 0, 0, SV("abcdefghij"), 0, 0, 0); + test(S("abcdefghij"), 0, 0, SV("abcdefghij"), 0, 1, -1); + test(S("abcdefghij"), 0, 0, SV("abcdefghij"), 0, 5, -5); + test(S("abcdefghij"), 0, 0, SV("abcdefghij"), 0, 9, -9); + test(S("abcdefghij"), 0, 0, SV("abcdefghij"), 0, 10, -10); + test(S("abcdefghij"), 0, 0, SV("abcdefghij"), 0, 11, -10); + test(S("abcdefghij"), 0, 0, SV("abcdefghij"), 1, 0, 0); + test(S("abcdefghij"), 0, 0, SV("abcdefghij"), 1, 1, -1); + test(S("abcdefghij"), 0, 0, SV("abcdefghij"), 1, 4, -4); + test(S("abcdefghij"), 0, 0, SV("abcdefghij"), 1, 8, -8); + test(S("abcdefghij"), 0, 0, SV("abcdefghij"), 1, 9, -9); + test(S("abcdefghij"), 0, 0, SV("abcdefghij"), 1, 10, -9); + test(S("abcdefghij"), 0, 0, SV("abcdefghij"), 5, 0, 0); + test(S("abcdefghij"), 0, 0, SV("abcdefghij"), 5, 1, -1); + test(S("abcdefghij"), 0, 0, SV("abcdefghij"), 5, 2, -2); + test(S("abcdefghij"), 0, 0, SV("abcdefghij"), 5, 4, -4); + test(S("abcdefghij"), 0, 0, SV("abcdefghij"), 5, 5, -5); + test(S("abcdefghij"), 0, 0, SV("abcdefghij"), 5, 6, -5); + test(S("abcdefghij"), 0, 0, SV("abcdefghij"), 9, 0, 0); + test(S("abcdefghij"), 0, 0, SV("abcdefghij"), 9, 1, -1); + test(S("abcdefghij"), 0, 0, SV("abcdefghij"), 9, 2, -1); + test(S("abcdefghij"), 0, 0, SV("abcdefghij"), 10, 0, 0); + test(S("abcdefghij"), 0, 0, SV("abcdefghij"), 10, 1, 0); + test(S("abcdefghij"), 0, 0, SV("abcdefghij"), 11, 0, 0); + test(S("abcdefghij"), 0, 0, SV("abcdefghijklmnopqrst"), 0, 0, 0); + test(S("abcdefghij"), 0, 0, SV("abcdefghijklmnopqrst"), 0, 1, -1); + test(S("abcdefghij"), 0, 0, SV("abcdefghijklmnopqrst"), 0, 10, -10); + test(S("abcdefghij"), 0, 0, SV("abcdefghijklmnopqrst"), 0, 19, -19); + test(S("abcdefghij"), 0, 0, SV("abcdefghijklmnopqrst"), 0, 20, -20); + test(S("abcdefghij"), 0, 0, SV("abcdefghijklmnopqrst"), 0, 21, -20); + test(S("abcdefghij"), 0, 0, SV("abcdefghijklmnopqrst"), 1, 0, 0); + test(S("abcdefghij"), 0, 0, SV("abcdefghijklmnopqrst"), 1, 1, -1); + test(S("abcdefghij"), 0, 0, SV("abcdefghijklmnopqrst"), 1, 9, -9); + test(S("abcdefghij"), 0, 0, SV("abcdefghijklmnopqrst"), 1, 18, -18); + test(S("abcdefghij"), 0, 0, SV("abcdefghijklmnopqrst"), 1, 19, -19); + test(S("abcdefghij"), 0, 0, SV("abcdefghijklmnopqrst"), 1, 20, -19); + test(S("abcdefghij"), 0, 0, SV("abcdefghijklmnopqrst"), 10, 0, 0); + test(S("abcdefghij"), 0, 0, SV("abcdefghijklmnopqrst"), 10, 1, -1); + test(S("abcdefghij"), 0, 0, SV("abcdefghijklmnopqrst"), 10, 5, -5); + test(S("abcdefghij"), 0, 0, SV("abcdefghijklmnopqrst"), 10, 9, -9); + test(S("abcdefghij"), 0, 0, SV("abcdefghijklmnopqrst"), 10, 10, -10); + test(S("abcdefghij"), 0, 0, SV("abcdefghijklmnopqrst"), 10, 11, -10); + test(S("abcdefghij"), 0, 0, SV("abcdefghijklmnopqrst"), 19, 0, 0); + test(S("abcdefghij"), 0, 0, SV("abcdefghijklmnopqrst"), 19, 1, -1); + test(S("abcdefghij"), 0, 0, SV("abcdefghijklmnopqrst"), 19, 2, -1); + test(S("abcdefghij"), 0, 0, SV("abcdefghijklmnopqrst"), 20, 0, 0); + test(S("abcdefghij"), 0, 0, SV("abcdefghijklmnopqrst"), 20, 1, 0); + test(S("abcdefghij"), 0, 0, SV("abcdefghijklmnopqrst"), 21, 0, 0); + test(S("abcdefghij"), 0, 1, SV(""), 0, 0, 1); + test(S("abcdefghij"), 0, 1, SV(""), 0, 1, 1); +} + +template +void test20() +{ + test(S("abcdefghij"), 0, 1, SV(""), 1, 0, 0); + test(S("abcdefghij"), 0, 1, SV("abcde"), 0, 0, 1); + test(S("abcdefghij"), 0, 1, SV("abcde"), 0, 1, 0); + test(S("abcdefghij"), 0, 1, SV("abcde"), 0, 2, -1); + test(S("abcdefghij"), 0, 1, SV("abcde"), 0, 4, -3); + test(S("abcdefghij"), 0, 1, SV("abcde"), 0, 5, -4); + test(S("abcdefghij"), 0, 1, SV("abcde"), 0, 6, -4); + test(S("abcdefghij"), 0, 1, SV("abcde"), 1, 0, 1); + test(S("abcdefghij"), 0, 1, SV("abcde"), 1, 1, -1); + test(S("abcdefghij"), 0, 1, SV("abcde"), 1, 2, -1); + test(S("abcdefghij"), 0, 1, SV("abcde"), 1, 3, -1); + test(S("abcdefghij"), 0, 1, SV("abcde"), 1, 4, -1); + test(S("abcdefghij"), 0, 1, SV("abcde"), 1, 5, -1); + test(S("abcdefghij"), 0, 1, SV("abcde"), 2, 0, 1); + test(S("abcdefghij"), 0, 1, SV("abcde"), 2, 1, -2); + test(S("abcdefghij"), 0, 1, SV("abcde"), 2, 2, -2); + test(S("abcdefghij"), 0, 1, SV("abcde"), 2, 3, -2); + test(S("abcdefghij"), 0, 1, SV("abcde"), 2, 4, -2); + test(S("abcdefghij"), 0, 1, SV("abcde"), 4, 0, 1); + test(S("abcdefghij"), 0, 1, SV("abcde"), 4, 1, -4); + test(S("abcdefghij"), 0, 1, SV("abcde"), 4, 2, -4); + test(S("abcdefghij"), 0, 1, SV("abcde"), 5, 0, 1); + test(S("abcdefghij"), 0, 1, SV("abcde"), 5, 1, 1); + test(S("abcdefghij"), 0, 1, SV("abcde"), 6, 0, 0); + test(S("abcdefghij"), 0, 1, SV("abcdefghij"), 0, 0, 1); + test(S("abcdefghij"), 0, 1, SV("abcdefghij"), 0, 1, 0); + test(S("abcdefghij"), 0, 1, SV("abcdefghij"), 0, 5, -4); + test(S("abcdefghij"), 0, 1, SV("abcdefghij"), 0, 9, -8); + test(S("abcdefghij"), 0, 1, SV("abcdefghij"), 0, 10, -9); + test(S("abcdefghij"), 0, 1, SV("abcdefghij"), 0, 11, -9); + test(S("abcdefghij"), 0, 1, SV("abcdefghij"), 1, 0, 1); + test(S("abcdefghij"), 0, 1, SV("abcdefghij"), 1, 1, -1); + test(S("abcdefghij"), 0, 1, SV("abcdefghij"), 1, 4, -1); + test(S("abcdefghij"), 0, 1, SV("abcdefghij"), 1, 8, -1); + test(S("abcdefghij"), 0, 1, SV("abcdefghij"), 1, 9, -1); + test(S("abcdefghij"), 0, 1, SV("abcdefghij"), 1, 10, -1); + test(S("abcdefghij"), 0, 1, SV("abcdefghij"), 5, 0, 1); + test(S("abcdefghij"), 0, 1, SV("abcdefghij"), 5, 1, -5); + test(S("abcdefghij"), 0, 1, SV("abcdefghij"), 5, 2, -5); + test(S("abcdefghij"), 0, 1, SV("abcdefghij"), 5, 4, -5); + test(S("abcdefghij"), 0, 1, SV("abcdefghij"), 5, 5, -5); + test(S("abcdefghij"), 0, 1, SV("abcdefghij"), 5, 6, -5); + test(S("abcdefghij"), 0, 1, SV("abcdefghij"), 9, 0, 1); + test(S("abcdefghij"), 0, 1, SV("abcdefghij"), 9, 1, -9); + test(S("abcdefghij"), 0, 1, SV("abcdefghij"), 9, 2, -9); + test(S("abcdefghij"), 0, 1, SV("abcdefghij"), 10, 0, 1); + test(S("abcdefghij"), 0, 1, SV("abcdefghij"), 10, 1, 1); + test(S("abcdefghij"), 0, 1, SV("abcdefghij"), 11, 0, 0); + test(S("abcdefghij"), 0, 1, SV("abcdefghijklmnopqrst"), 0, 0, 1); + test(S("abcdefghij"), 0, 1, SV("abcdefghijklmnopqrst"), 0, 1, 0); + test(S("abcdefghij"), 0, 1, SV("abcdefghijklmnopqrst"), 0, 10, -9); + test(S("abcdefghij"), 0, 1, SV("abcdefghijklmnopqrst"), 0, 19, -18); + test(S("abcdefghij"), 0, 1, SV("abcdefghijklmnopqrst"), 0, 20, -19); + test(S("abcdefghij"), 0, 1, SV("abcdefghijklmnopqrst"), 0, 21, -19); + test(S("abcdefghij"), 0, 1, SV("abcdefghijklmnopqrst"), 1, 0, 1); + test(S("abcdefghij"), 0, 1, SV("abcdefghijklmnopqrst"), 1, 1, -1); + test(S("abcdefghij"), 0, 1, SV("abcdefghijklmnopqrst"), 1, 9, -1); + test(S("abcdefghij"), 0, 1, SV("abcdefghijklmnopqrst"), 1, 18, -1); + test(S("abcdefghij"), 0, 1, SV("abcdefghijklmnopqrst"), 1, 19, -1); + test(S("abcdefghij"), 0, 1, SV("abcdefghijklmnopqrst"), 1, 20, -1); + test(S("abcdefghij"), 0, 1, SV("abcdefghijklmnopqrst"), 10, 0, 1); + test(S("abcdefghij"), 0, 1, SV("abcdefghijklmnopqrst"), 10, 1, -10); + test(S("abcdefghij"), 0, 1, SV("abcdefghijklmnopqrst"), 10, 5, -10); + test(S("abcdefghij"), 0, 1, SV("abcdefghijklmnopqrst"), 10, 9, -10); + test(S("abcdefghij"), 0, 1, SV("abcdefghijklmnopqrst"), 10, 10, -10); + test(S("abcdefghij"), 0, 1, SV("abcdefghijklmnopqrst"), 10, 11, -10); + test(S("abcdefghij"), 0, 1, SV("abcdefghijklmnopqrst"), 19, 0, 1); + test(S("abcdefghij"), 0, 1, SV("abcdefghijklmnopqrst"), 19, 1, -19); + test(S("abcdefghij"), 0, 1, SV("abcdefghijklmnopqrst"), 19, 2, -19); + test(S("abcdefghij"), 0, 1, SV("abcdefghijklmnopqrst"), 20, 0, 1); + test(S("abcdefghij"), 0, 1, SV("abcdefghijklmnopqrst"), 20, 1, 1); + test(S("abcdefghij"), 0, 1, SV("abcdefghijklmnopqrst"), 21, 0, 0); + test(S("abcdefghij"), 0, 5, SV(""), 0, 0, 5); + test(S("abcdefghij"), 0, 5, SV(""), 0, 1, 5); + test(S("abcdefghij"), 0, 5, SV(""), 1, 0, 0); + test(S("abcdefghij"), 0, 5, SV("abcde"), 0, 0, 5); + test(S("abcdefghij"), 0, 5, SV("abcde"), 0, 1, 4); + test(S("abcdefghij"), 0, 5, SV("abcde"), 0, 2, 3); + test(S("abcdefghij"), 0, 5, SV("abcde"), 0, 4, 1); + test(S("abcdefghij"), 0, 5, SV("abcde"), 0, 5, 0); + test(S("abcdefghij"), 0, 5, SV("abcde"), 0, 6, 0); + test(S("abcdefghij"), 0, 5, SV("abcde"), 1, 0, 5); + test(S("abcdefghij"), 0, 5, SV("abcde"), 1, 1, -1); + test(S("abcdefghij"), 0, 5, SV("abcde"), 1, 2, -1); + test(S("abcdefghij"), 0, 5, SV("abcde"), 1, 3, -1); + test(S("abcdefghij"), 0, 5, SV("abcde"), 1, 4, -1); + test(S("abcdefghij"), 0, 5, SV("abcde"), 1, 5, -1); + test(S("abcdefghij"), 0, 5, SV("abcde"), 2, 0, 5); + test(S("abcdefghij"), 0, 5, SV("abcde"), 2, 1, -2); + test(S("abcdefghij"), 0, 5, SV("abcde"), 2, 2, -2); + test(S("abcdefghij"), 0, 5, SV("abcde"), 2, 3, -2); + test(S("abcdefghij"), 0, 5, SV("abcde"), 2, 4, -2); + test(S("abcdefghij"), 0, 5, SV("abcde"), 4, 0, 5); + test(S("abcdefghij"), 0, 5, SV("abcde"), 4, 1, -4); + test(S("abcdefghij"), 0, 5, SV("abcde"), 4, 2, -4); + test(S("abcdefghij"), 0, 5, SV("abcde"), 5, 0, 5); + test(S("abcdefghij"), 0, 5, SV("abcde"), 5, 1, 5); + test(S("abcdefghij"), 0, 5, SV("abcde"), 6, 0, 0); + test(S("abcdefghij"), 0, 5, SV("abcdefghij"), 0, 0, 5); + test(S("abcdefghij"), 0, 5, SV("abcdefghij"), 0, 1, 4); +} + +template +void test21() +{ + test(S("abcdefghij"), 0, 5, SV("abcdefghij"), 0, 5, 0); + test(S("abcdefghij"), 0, 5, SV("abcdefghij"), 0, 9, -4); + test(S("abcdefghij"), 0, 5, SV("abcdefghij"), 0, 10, -5); + test(S("abcdefghij"), 0, 5, SV("abcdefghij"), 0, 11, -5); + test(S("abcdefghij"), 0, 5, SV("abcdefghij"), 1, 0, 5); + test(S("abcdefghij"), 0, 5, SV("abcdefghij"), 1, 1, -1); + test(S("abcdefghij"), 0, 5, SV("abcdefghij"), 1, 4, -1); + test(S("abcdefghij"), 0, 5, SV("abcdefghij"), 1, 8, -1); + test(S("abcdefghij"), 0, 5, SV("abcdefghij"), 1, 9, -1); + test(S("abcdefghij"), 0, 5, SV("abcdefghij"), 1, 10, -1); + test(S("abcdefghij"), 0, 5, SV("abcdefghij"), 5, 0, 5); + test(S("abcdefghij"), 0, 5, SV("abcdefghij"), 5, 1, -5); + test(S("abcdefghij"), 0, 5, SV("abcdefghij"), 5, 2, -5); + test(S("abcdefghij"), 0, 5, SV("abcdefghij"), 5, 4, -5); + test(S("abcdefghij"), 0, 5, SV("abcdefghij"), 5, 5, -5); + test(S("abcdefghij"), 0, 5, SV("abcdefghij"), 5, 6, -5); + test(S("abcdefghij"), 0, 5, SV("abcdefghij"), 9, 0, 5); + test(S("abcdefghij"), 0, 5, SV("abcdefghij"), 9, 1, -9); + test(S("abcdefghij"), 0, 5, SV("abcdefghij"), 9, 2, -9); + test(S("abcdefghij"), 0, 5, SV("abcdefghij"), 10, 0, 5); + test(S("abcdefghij"), 0, 5, SV("abcdefghij"), 10, 1, 5); + test(S("abcdefghij"), 0, 5, SV("abcdefghij"), 11, 0, 0); + test(S("abcdefghij"), 0, 5, SV("abcdefghijklmnopqrst"), 0, 0, 5); + test(S("abcdefghij"), 0, 5, SV("abcdefghijklmnopqrst"), 0, 1, 4); + test(S("abcdefghij"), 0, 5, SV("abcdefghijklmnopqrst"), 0, 10, -5); + test(S("abcdefghij"), 0, 5, SV("abcdefghijklmnopqrst"), 0, 19, -14); + test(S("abcdefghij"), 0, 5, SV("abcdefghijklmnopqrst"), 0, 20, -15); + test(S("abcdefghij"), 0, 5, SV("abcdefghijklmnopqrst"), 0, 21, -15); + test(S("abcdefghij"), 0, 5, SV("abcdefghijklmnopqrst"), 1, 0, 5); + test(S("abcdefghij"), 0, 5, SV("abcdefghijklmnopqrst"), 1, 1, -1); + test(S("abcdefghij"), 0, 5, SV("abcdefghijklmnopqrst"), 1, 9, -1); + test(S("abcdefghij"), 0, 5, SV("abcdefghijklmnopqrst"), 1, 18, -1); + test(S("abcdefghij"), 0, 5, SV("abcdefghijklmnopqrst"), 1, 19, -1); + test(S("abcdefghij"), 0, 5, SV("abcdefghijklmnopqrst"), 1, 20, -1); + test(S("abcdefghij"), 0, 5, SV("abcdefghijklmnopqrst"), 10, 0, 5); + test(S("abcdefghij"), 0, 5, SV("abcdefghijklmnopqrst"), 10, 1, -10); + test(S("abcdefghij"), 0, 5, SV("abcdefghijklmnopqrst"), 10, 5, -10); + test(S("abcdefghij"), 0, 5, SV("abcdefghijklmnopqrst"), 10, 9, -10); + test(S("abcdefghij"), 0, 5, SV("abcdefghijklmnopqrst"), 10, 10, -10); + test(S("abcdefghij"), 0, 5, SV("abcdefghijklmnopqrst"), 10, 11, -10); + test(S("abcdefghij"), 0, 5, SV("abcdefghijklmnopqrst"), 19, 0, 5); + test(S("abcdefghij"), 0, 5, SV("abcdefghijklmnopqrst"), 19, 1, -19); + test(S("abcdefghij"), 0, 5, SV("abcdefghijklmnopqrst"), 19, 2, -19); + test(S("abcdefghij"), 0, 5, SV("abcdefghijklmnopqrst"), 20, 0, 5); + test(S("abcdefghij"), 0, 5, SV("abcdefghijklmnopqrst"), 20, 1, 5); + test(S("abcdefghij"), 0, 5, SV("abcdefghijklmnopqrst"), 21, 0, 0); + test(S("abcdefghij"), 0, 9, SV(""), 0, 0, 9); + test(S("abcdefghij"), 0, 9, SV(""), 0, 1, 9); + test(S("abcdefghij"), 0, 9, SV(""), 1, 0, 0); + test(S("abcdefghij"), 0, 9, SV("abcde"), 0, 0, 9); + test(S("abcdefghij"), 0, 9, SV("abcde"), 0, 1, 8); + test(S("abcdefghij"), 0, 9, SV("abcde"), 0, 2, 7); + test(S("abcdefghij"), 0, 9, SV("abcde"), 0, 4, 5); + test(S("abcdefghij"), 0, 9, SV("abcde"), 0, 5, 4); + test(S("abcdefghij"), 0, 9, SV("abcde"), 0, 6, 4); + test(S("abcdefghij"), 0, 9, SV("abcde"), 1, 0, 9); + test(S("abcdefghij"), 0, 9, SV("abcde"), 1, 1, -1); + test(S("abcdefghij"), 0, 9, SV("abcde"), 1, 2, -1); + test(S("abcdefghij"), 0, 9, SV("abcde"), 1, 3, -1); + test(S("abcdefghij"), 0, 9, SV("abcde"), 1, 4, -1); + test(S("abcdefghij"), 0, 9, SV("abcde"), 1, 5, -1); + test(S("abcdefghij"), 0, 9, SV("abcde"), 2, 0, 9); + test(S("abcdefghij"), 0, 9, SV("abcde"), 2, 1, -2); + test(S("abcdefghij"), 0, 9, SV("abcde"), 2, 2, -2); + test(S("abcdefghij"), 0, 9, SV("abcde"), 2, 3, -2); + test(S("abcdefghij"), 0, 9, SV("abcde"), 2, 4, -2); + test(S("abcdefghij"), 0, 9, SV("abcde"), 4, 0, 9); + test(S("abcdefghij"), 0, 9, SV("abcde"), 4, 1, -4); + test(S("abcdefghij"), 0, 9, SV("abcde"), 4, 2, -4); + test(S("abcdefghij"), 0, 9, SV("abcde"), 5, 0, 9); + test(S("abcdefghij"), 0, 9, SV("abcde"), 5, 1, 9); + test(S("abcdefghij"), 0, 9, SV("abcde"), 6, 0, 0); + test(S("abcdefghij"), 0, 9, SV("abcdefghij"), 0, 0, 9); + test(S("abcdefghij"), 0, 9, SV("abcdefghij"), 0, 1, 8); + test(S("abcdefghij"), 0, 9, SV("abcdefghij"), 0, 5, 4); + test(S("abcdefghij"), 0, 9, SV("abcdefghij"), 0, 9, 0); + test(S("abcdefghij"), 0, 9, SV("abcdefghij"), 0, 10, -1); + test(S("abcdefghij"), 0, 9, SV("abcdefghij"), 0, 11, -1); + test(S("abcdefghij"), 0, 9, SV("abcdefghij"), 1, 0, 9); + test(S("abcdefghij"), 0, 9, SV("abcdefghij"), 1, 1, -1); + test(S("abcdefghij"), 0, 9, SV("abcdefghij"), 1, 4, -1); + test(S("abcdefghij"), 0, 9, SV("abcdefghij"), 1, 8, -1); + test(S("abcdefghij"), 0, 9, SV("abcdefghij"), 1, 9, -1); + test(S("abcdefghij"), 0, 9, SV("abcdefghij"), 1, 10, -1); + test(S("abcdefghij"), 0, 9, SV("abcdefghij"), 5, 0, 9); + test(S("abcdefghij"), 0, 9, SV("abcdefghij"), 5, 1, -5); + test(S("abcdefghij"), 0, 9, SV("abcdefghij"), 5, 2, -5); + test(S("abcdefghij"), 0, 9, SV("abcdefghij"), 5, 4, -5); + test(S("abcdefghij"), 0, 9, SV("abcdefghij"), 5, 5, -5); + test(S("abcdefghij"), 0, 9, SV("abcdefghij"), 5, 6, -5); + test(S("abcdefghij"), 0, 9, SV("abcdefghij"), 9, 0, 9); + test(S("abcdefghij"), 0, 9, SV("abcdefghij"), 9, 1, -9); + test(S("abcdefghij"), 0, 9, SV("abcdefghij"), 9, 2, -9); + test(S("abcdefghij"), 0, 9, SV("abcdefghij"), 10, 0, 9); + test(S("abcdefghij"), 0, 9, SV("abcdefghij"), 10, 1, 9); + test(S("abcdefghij"), 0, 9, SV("abcdefghij"), 11, 0, 0); + test(S("abcdefghij"), 0, 9, SV("abcdefghijklmnopqrst"), 0, 0, 9); + test(S("abcdefghij"), 0, 9, SV("abcdefghijklmnopqrst"), 0, 1, 8); + test(S("abcdefghij"), 0, 9, SV("abcdefghijklmnopqrst"), 0, 10, -1); + test(S("abcdefghij"), 0, 9, SV("abcdefghijklmnopqrst"), 0, 19, -10); +} + +template +void test22() +{ + test(S("abcdefghij"), 0, 9, SV("abcdefghijklmnopqrst"), 0, 20, -11); + test(S("abcdefghij"), 0, 9, SV("abcdefghijklmnopqrst"), 0, 21, -11); + test(S("abcdefghij"), 0, 9, SV("abcdefghijklmnopqrst"), 1, 0, 9); + test(S("abcdefghij"), 0, 9, SV("abcdefghijklmnopqrst"), 1, 1, -1); + test(S("abcdefghij"), 0, 9, SV("abcdefghijklmnopqrst"), 1, 9, -1); + test(S("abcdefghij"), 0, 9, SV("abcdefghijklmnopqrst"), 1, 18, -1); + test(S("abcdefghij"), 0, 9, SV("abcdefghijklmnopqrst"), 1, 19, -1); + test(S("abcdefghij"), 0, 9, SV("abcdefghijklmnopqrst"), 1, 20, -1); + test(S("abcdefghij"), 0, 9, SV("abcdefghijklmnopqrst"), 10, 0, 9); + test(S("abcdefghij"), 0, 9, SV("abcdefghijklmnopqrst"), 10, 1, -10); + test(S("abcdefghij"), 0, 9, SV("abcdefghijklmnopqrst"), 10, 5, -10); + test(S("abcdefghij"), 0, 9, SV("abcdefghijklmnopqrst"), 10, 9, -10); + test(S("abcdefghij"), 0, 9, SV("abcdefghijklmnopqrst"), 10, 10, -10); + test(S("abcdefghij"), 0, 9, SV("abcdefghijklmnopqrst"), 10, 11, -10); + test(S("abcdefghij"), 0, 9, SV("abcdefghijklmnopqrst"), 19, 0, 9); + test(S("abcdefghij"), 0, 9, SV("abcdefghijklmnopqrst"), 19, 1, -19); + test(S("abcdefghij"), 0, 9, SV("abcdefghijklmnopqrst"), 19, 2, -19); + test(S("abcdefghij"), 0, 9, SV("abcdefghijklmnopqrst"), 20, 0, 9); + test(S("abcdefghij"), 0, 9, SV("abcdefghijklmnopqrst"), 20, 1, 9); + test(S("abcdefghij"), 0, 9, SV("abcdefghijklmnopqrst"), 21, 0, 0); + test(S("abcdefghij"), 0, 10, SV(""), 0, 0, 10); + test(S("abcdefghij"), 0, 10, SV(""), 0, 1, 10); + test(S("abcdefghij"), 0, 10, SV(""), 1, 0, 0); + test(S("abcdefghij"), 0, 10, SV("abcde"), 0, 0, 10); + test(S("abcdefghij"), 0, 10, SV("abcde"), 0, 1, 9); + test(S("abcdefghij"), 0, 10, SV("abcde"), 0, 2, 8); + test(S("abcdefghij"), 0, 10, SV("abcde"), 0, 4, 6); + test(S("abcdefghij"), 0, 10, SV("abcde"), 0, 5, 5); + test(S("abcdefghij"), 0, 10, SV("abcde"), 0, 6, 5); + test(S("abcdefghij"), 0, 10, SV("abcde"), 1, 0, 10); + test(S("abcdefghij"), 0, 10, SV("abcde"), 1, 1, -1); + test(S("abcdefghij"), 0, 10, SV("abcde"), 1, 2, -1); + test(S("abcdefghij"), 0, 10, SV("abcde"), 1, 3, -1); + test(S("abcdefghij"), 0, 10, SV("abcde"), 1, 4, -1); + test(S("abcdefghij"), 0, 10, SV("abcde"), 1, 5, -1); + test(S("abcdefghij"), 0, 10, SV("abcde"), 2, 0, 10); + test(S("abcdefghij"), 0, 10, SV("abcde"), 2, 1, -2); + test(S("abcdefghij"), 0, 10, SV("abcde"), 2, 2, -2); + test(S("abcdefghij"), 0, 10, SV("abcde"), 2, 3, -2); + test(S("abcdefghij"), 0, 10, SV("abcde"), 2, 4, -2); + test(S("abcdefghij"), 0, 10, SV("abcde"), 4, 0, 10); + test(S("abcdefghij"), 0, 10, SV("abcde"), 4, 1, -4); + test(S("abcdefghij"), 0, 10, SV("abcde"), 4, 2, -4); + test(S("abcdefghij"), 0, 10, SV("abcde"), 5, 0, 10); + test(S("abcdefghij"), 0, 10, SV("abcde"), 5, 1, 10); + test(S("abcdefghij"), 0, 10, SV("abcde"), 6, 0, 0); + test(S("abcdefghij"), 0, 10, SV("abcdefghij"), 0, 0, 10); + test(S("abcdefghij"), 0, 10, SV("abcdefghij"), 0, 1, 9); + test(S("abcdefghij"), 0, 10, SV("abcdefghij"), 0, 5, 5); + test(S("abcdefghij"), 0, 10, SV("abcdefghij"), 0, 9, 1); + test(S("abcdefghij"), 0, 10, SV("abcdefghij"), 0, 10, 0); + test(S("abcdefghij"), 0, 10, SV("abcdefghij"), 0, 11, 0); + test(S("abcdefghij"), 0, 10, SV("abcdefghij"), 1, 0, 10); + test(S("abcdefghij"), 0, 10, SV("abcdefghij"), 1, 1, -1); + test(S("abcdefghij"), 0, 10, SV("abcdefghij"), 1, 4, -1); + test(S("abcdefghij"), 0, 10, SV("abcdefghij"), 1, 8, -1); + test(S("abcdefghij"), 0, 10, SV("abcdefghij"), 1, 9, -1); + test(S("abcdefghij"), 0, 10, SV("abcdefghij"), 1, 10, -1); + test(S("abcdefghij"), 0, 10, SV("abcdefghij"), 5, 0, 10); + test(S("abcdefghij"), 0, 10, SV("abcdefghij"), 5, 1, -5); + test(S("abcdefghij"), 0, 10, SV("abcdefghij"), 5, 2, -5); + test(S("abcdefghij"), 0, 10, SV("abcdefghij"), 5, 4, -5); + test(S("abcdefghij"), 0, 10, SV("abcdefghij"), 5, 5, -5); + test(S("abcdefghij"), 0, 10, SV("abcdefghij"), 5, 6, -5); + test(S("abcdefghij"), 0, 10, SV("abcdefghij"), 9, 0, 10); + test(S("abcdefghij"), 0, 10, SV("abcdefghij"), 9, 1, -9); + test(S("abcdefghij"), 0, 10, SV("abcdefghij"), 9, 2, -9); + test(S("abcdefghij"), 0, 10, SV("abcdefghij"), 10, 0, 10); + test(S("abcdefghij"), 0, 10, SV("abcdefghij"), 10, 1, 10); + test(S("abcdefghij"), 0, 10, SV("abcdefghij"), 11, 0, 0); + test(S("abcdefghij"), 0, 10, SV("abcdefghijklmnopqrst"), 0, 0, 10); + test(S("abcdefghij"), 0, 10, SV("abcdefghijklmnopqrst"), 0, 1, 9); + test(S("abcdefghij"), 0, 10, SV("abcdefghijklmnopqrst"), 0, 10, 0); + test(S("abcdefghij"), 0, 10, SV("abcdefghijklmnopqrst"), 0, 19, -9); + test(S("abcdefghij"), 0, 10, SV("abcdefghijklmnopqrst"), 0, 20, -10); + test(S("abcdefghij"), 0, 10, SV("abcdefghijklmnopqrst"), 0, 21, -10); + test(S("abcdefghij"), 0, 10, SV("abcdefghijklmnopqrst"), 1, 0, 10); + test(S("abcdefghij"), 0, 10, SV("abcdefghijklmnopqrst"), 1, 1, -1); + test(S("abcdefghij"), 0, 10, SV("abcdefghijklmnopqrst"), 1, 9, -1); + test(S("abcdefghij"), 0, 10, SV("abcdefghijklmnopqrst"), 1, 18, -1); + test(S("abcdefghij"), 0, 10, SV("abcdefghijklmnopqrst"), 1, 19, -1); + test(S("abcdefghij"), 0, 10, SV("abcdefghijklmnopqrst"), 1, 20, -1); + test(S("abcdefghij"), 0, 10, SV("abcdefghijklmnopqrst"), 10, 0, 10); + test(S("abcdefghij"), 0, 10, SV("abcdefghijklmnopqrst"), 10, 1, -10); + test(S("abcdefghij"), 0, 10, SV("abcdefghijklmnopqrst"), 10, 5, -10); + test(S("abcdefghij"), 0, 10, SV("abcdefghijklmnopqrst"), 10, 9, -10); + test(S("abcdefghij"), 0, 10, SV("abcdefghijklmnopqrst"), 10, 10, -10); + test(S("abcdefghij"), 0, 10, SV("abcdefghijklmnopqrst"), 10, 11, -10); + test(S("abcdefghij"), 0, 10, SV("abcdefghijklmnopqrst"), 19, 0, 10); + test(S("abcdefghij"), 0, 10, SV("abcdefghijklmnopqrst"), 19, 1, -19); + test(S("abcdefghij"), 0, 10, SV("abcdefghijklmnopqrst"), 19, 2, -19); + test(S("abcdefghij"), 0, 10, SV("abcdefghijklmnopqrst"), 20, 0, 10); + test(S("abcdefghij"), 0, 10, SV("abcdefghijklmnopqrst"), 20, 1, 10); + test(S("abcdefghij"), 0, 10, SV("abcdefghijklmnopqrst"), 21, 0, 0); + test(S("abcdefghij"), 0, 11, SV(""), 0, 0, 10); + test(S("abcdefghij"), 0, 11, SV(""), 0, 1, 10); + test(S("abcdefghij"), 0, 11, SV(""), 1, 0, 0); + test(S("abcdefghij"), 0, 11, SV("abcde"), 0, 0, 10); + test(S("abcdefghij"), 0, 11, SV("abcde"), 0, 1, 9); + test(S("abcdefghij"), 0, 11, SV("abcde"), 0, 2, 8); +} + +template +void test23() +{ + test(S("abcdefghij"), 0, 11, SV("abcde"), 0, 4, 6); + test(S("abcdefghij"), 0, 11, SV("abcde"), 0, 5, 5); + test(S("abcdefghij"), 0, 11, SV("abcde"), 0, 6, 5); + test(S("abcdefghij"), 0, 11, SV("abcde"), 1, 0, 10); + test(S("abcdefghij"), 0, 11, SV("abcde"), 1, 1, -1); + test(S("abcdefghij"), 0, 11, SV("abcde"), 1, 2, -1); + test(S("abcdefghij"), 0, 11, SV("abcde"), 1, 3, -1); + test(S("abcdefghij"), 0, 11, SV("abcde"), 1, 4, -1); + test(S("abcdefghij"), 0, 11, SV("abcde"), 1, 5, -1); + test(S("abcdefghij"), 0, 11, SV("abcde"), 2, 0, 10); + test(S("abcdefghij"), 0, 11, SV("abcde"), 2, 1, -2); + test(S("abcdefghij"), 0, 11, SV("abcde"), 2, 2, -2); + test(S("abcdefghij"), 0, 11, SV("abcde"), 2, 3, -2); + test(S("abcdefghij"), 0, 11, SV("abcde"), 2, 4, -2); + test(S("abcdefghij"), 0, 11, SV("abcde"), 4, 0, 10); + test(S("abcdefghij"), 0, 11, SV("abcde"), 4, 1, -4); + test(S("abcdefghij"), 0, 11, SV("abcde"), 4, 2, -4); + test(S("abcdefghij"), 0, 11, SV("abcde"), 5, 0, 10); + test(S("abcdefghij"), 0, 11, SV("abcde"), 5, 1, 10); + test(S("abcdefghij"), 0, 11, SV("abcde"), 6, 0, 0); + test(S("abcdefghij"), 0, 11, SV("abcdefghij"), 0, 0, 10); + test(S("abcdefghij"), 0, 11, SV("abcdefghij"), 0, 1, 9); + test(S("abcdefghij"), 0, 11, SV("abcdefghij"), 0, 5, 5); + test(S("abcdefghij"), 0, 11, SV("abcdefghij"), 0, 9, 1); + test(S("abcdefghij"), 0, 11, SV("abcdefghij"), 0, 10, 0); + test(S("abcdefghij"), 0, 11, SV("abcdefghij"), 0, 11, 0); + test(S("abcdefghij"), 0, 11, SV("abcdefghij"), 1, 0, 10); + test(S("abcdefghij"), 0, 11, SV("abcdefghij"), 1, 1, -1); + test(S("abcdefghij"), 0, 11, SV("abcdefghij"), 1, 4, -1); + test(S("abcdefghij"), 0, 11, SV("abcdefghij"), 1, 8, -1); + test(S("abcdefghij"), 0, 11, SV("abcdefghij"), 1, 9, -1); + test(S("abcdefghij"), 0, 11, SV("abcdefghij"), 1, 10, -1); + test(S("abcdefghij"), 0, 11, SV("abcdefghij"), 5, 0, 10); + test(S("abcdefghij"), 0, 11, SV("abcdefghij"), 5, 1, -5); + test(S("abcdefghij"), 0, 11, SV("abcdefghij"), 5, 2, -5); + test(S("abcdefghij"), 0, 11, SV("abcdefghij"), 5, 4, -5); + test(S("abcdefghij"), 0, 11, SV("abcdefghij"), 5, 5, -5); + test(S("abcdefghij"), 0, 11, SV("abcdefghij"), 5, 6, -5); + test(S("abcdefghij"), 0, 11, SV("abcdefghij"), 9, 0, 10); + test(S("abcdefghij"), 0, 11, SV("abcdefghij"), 9, 1, -9); + test(S("abcdefghij"), 0, 11, SV("abcdefghij"), 9, 2, -9); + test(S("abcdefghij"), 0, 11, SV("abcdefghij"), 10, 0, 10); + test(S("abcdefghij"), 0, 11, SV("abcdefghij"), 10, 1, 10); + test(S("abcdefghij"), 0, 11, SV("abcdefghij"), 11, 0, 0); + test(S("abcdefghij"), 0, 11, SV("abcdefghijklmnopqrst"), 0, 0, 10); + test(S("abcdefghij"), 0, 11, SV("abcdefghijklmnopqrst"), 0, 1, 9); + test(S("abcdefghij"), 0, 11, SV("abcdefghijklmnopqrst"), 0, 10, 0); + test(S("abcdefghij"), 0, 11, SV("abcdefghijklmnopqrst"), 0, 19, -9); + test(S("abcdefghij"), 0, 11, SV("abcdefghijklmnopqrst"), 0, 20, -10); + test(S("abcdefghij"), 0, 11, SV("abcdefghijklmnopqrst"), 0, 21, -10); + test(S("abcdefghij"), 0, 11, SV("abcdefghijklmnopqrst"), 1, 0, 10); + test(S("abcdefghij"), 0, 11, SV("abcdefghijklmnopqrst"), 1, 1, -1); + test(S("abcdefghij"), 0, 11, SV("abcdefghijklmnopqrst"), 1, 9, -1); + test(S("abcdefghij"), 0, 11, SV("abcdefghijklmnopqrst"), 1, 18, -1); + test(S("abcdefghij"), 0, 11, SV("abcdefghijklmnopqrst"), 1, 19, -1); + test(S("abcdefghij"), 0, 11, SV("abcdefghijklmnopqrst"), 1, 20, -1); + test(S("abcdefghij"), 0, 11, SV("abcdefghijklmnopqrst"), 10, 0, 10); + test(S("abcdefghij"), 0, 11, SV("abcdefghijklmnopqrst"), 10, 1, -10); + test(S("abcdefghij"), 0, 11, SV("abcdefghijklmnopqrst"), 10, 5, -10); + test(S("abcdefghij"), 0, 11, SV("abcdefghijklmnopqrst"), 10, 9, -10); + test(S("abcdefghij"), 0, 11, SV("abcdefghijklmnopqrst"), 10, 10, -10); + test(S("abcdefghij"), 0, 11, SV("abcdefghijklmnopqrst"), 10, 11, -10); + test(S("abcdefghij"), 0, 11, SV("abcdefghijklmnopqrst"), 19, 0, 10); + test(S("abcdefghij"), 0, 11, SV("abcdefghijklmnopqrst"), 19, 1, -19); + test(S("abcdefghij"), 0, 11, SV("abcdefghijklmnopqrst"), 19, 2, -19); + test(S("abcdefghij"), 0, 11, SV("abcdefghijklmnopqrst"), 20, 0, 10); + test(S("abcdefghij"), 0, 11, SV("abcdefghijklmnopqrst"), 20, 1, 10); + test(S("abcdefghij"), 0, 11, SV("abcdefghijklmnopqrst"), 21, 0, 0); + test(S("abcdefghij"), 1, 0, SV(""), 0, 0, 0); + test(S("abcdefghij"), 1, 0, SV(""), 0, 1, 0); + test(S("abcdefghij"), 1, 0, SV(""), 1, 0, 0); + test(S("abcdefghij"), 1, 0, SV("abcde"), 0, 0, 0); + test(S("abcdefghij"), 1, 0, SV("abcde"), 0, 1, -1); + test(S("abcdefghij"), 1, 0, SV("abcde"), 0, 2, -2); + test(S("abcdefghij"), 1, 0, SV("abcde"), 0, 4, -4); + test(S("abcdefghij"), 1, 0, SV("abcde"), 0, 5, -5); + test(S("abcdefghij"), 1, 0, SV("abcde"), 0, 6, -5); + test(S("abcdefghij"), 1, 0, SV("abcde"), 1, 0, 0); + test(S("abcdefghij"), 1, 0, SV("abcde"), 1, 1, -1); + test(S("abcdefghij"), 1, 0, SV("abcde"), 1, 2, -2); + test(S("abcdefghij"), 1, 0, SV("abcde"), 1, 3, -3); + test(S("abcdefghij"), 1, 0, SV("abcde"), 1, 4, -4); + test(S("abcdefghij"), 1, 0, SV("abcde"), 1, 5, -4); + test(S("abcdefghij"), 1, 0, SV("abcde"), 2, 0, 0); + test(S("abcdefghij"), 1, 0, SV("abcde"), 2, 1, -1); + test(S("abcdefghij"), 1, 0, SV("abcde"), 2, 2, -2); + test(S("abcdefghij"), 1, 0, SV("abcde"), 2, 3, -3); + test(S("abcdefghij"), 1, 0, SV("abcde"), 2, 4, -3); + test(S("abcdefghij"), 1, 0, SV("abcde"), 4, 0, 0); + test(S("abcdefghij"), 1, 0, SV("abcde"), 4, 1, -1); + test(S("abcdefghij"), 1, 0, SV("abcde"), 4, 2, -1); + test(S("abcdefghij"), 1, 0, SV("abcde"), 5, 0, 0); + test(S("abcdefghij"), 1, 0, SV("abcde"), 5, 1, 0); + test(S("abcdefghij"), 1, 0, SV("abcde"), 6, 0, 0); + test(S("abcdefghij"), 1, 0, SV("abcdefghij"), 0, 0, 0); + test(S("abcdefghij"), 1, 0, SV("abcdefghij"), 0, 1, -1); + test(S("abcdefghij"), 1, 0, SV("abcdefghij"), 0, 5, -5); + test(S("abcdefghij"), 1, 0, SV("abcdefghij"), 0, 9, -9); + test(S("abcdefghij"), 1, 0, SV("abcdefghij"), 0, 10, -10); + test(S("abcdefghij"), 1, 0, SV("abcdefghij"), 0, 11, -10); +} + +template +void test24() +{ + test(S("abcdefghij"), 1, 0, SV("abcdefghij"), 1, 0, 0); + test(S("abcdefghij"), 1, 0, SV("abcdefghij"), 1, 1, -1); + test(S("abcdefghij"), 1, 0, SV("abcdefghij"), 1, 4, -4); + test(S("abcdefghij"), 1, 0, SV("abcdefghij"), 1, 8, -8); + test(S("abcdefghij"), 1, 0, SV("abcdefghij"), 1, 9, -9); + test(S("abcdefghij"), 1, 0, SV("abcdefghij"), 1, 10, -9); + test(S("abcdefghij"), 1, 0, SV("abcdefghij"), 5, 0, 0); + test(S("abcdefghij"), 1, 0, SV("abcdefghij"), 5, 1, -1); + test(S("abcdefghij"), 1, 0, SV("abcdefghij"), 5, 2, -2); + test(S("abcdefghij"), 1, 0, SV("abcdefghij"), 5, 4, -4); + test(S("abcdefghij"), 1, 0, SV("abcdefghij"), 5, 5, -5); + test(S("abcdefghij"), 1, 0, SV("abcdefghij"), 5, 6, -5); + test(S("abcdefghij"), 1, 0, SV("abcdefghij"), 9, 0, 0); + test(S("abcdefghij"), 1, 0, SV("abcdefghij"), 9, 1, -1); + test(S("abcdefghij"), 1, 0, SV("abcdefghij"), 9, 2, -1); + test(S("abcdefghij"), 1, 0, SV("abcdefghij"), 10, 0, 0); + test(S("abcdefghij"), 1, 0, SV("abcdefghij"), 10, 1, 0); + test(S("abcdefghij"), 1, 0, SV("abcdefghij"), 11, 0, 0); + test(S("abcdefghij"), 1, 0, SV("abcdefghijklmnopqrst"), 0, 0, 0); + test(S("abcdefghij"), 1, 0, SV("abcdefghijklmnopqrst"), 0, 1, -1); + test(S("abcdefghij"), 1, 0, SV("abcdefghijklmnopqrst"), 0, 10, -10); + test(S("abcdefghij"), 1, 0, SV("abcdefghijklmnopqrst"), 0, 19, -19); + test(S("abcdefghij"), 1, 0, SV("abcdefghijklmnopqrst"), 0, 20, -20); + test(S("abcdefghij"), 1, 0, SV("abcdefghijklmnopqrst"), 0, 21, -20); + test(S("abcdefghij"), 1, 0, SV("abcdefghijklmnopqrst"), 1, 0, 0); + test(S("abcdefghij"), 1, 0, SV("abcdefghijklmnopqrst"), 1, 1, -1); + test(S("abcdefghij"), 1, 0, SV("abcdefghijklmnopqrst"), 1, 9, -9); + test(S("abcdefghij"), 1, 0, SV("abcdefghijklmnopqrst"), 1, 18, -18); + test(S("abcdefghij"), 1, 0, SV("abcdefghijklmnopqrst"), 1, 19, -19); + test(S("abcdefghij"), 1, 0, SV("abcdefghijklmnopqrst"), 1, 20, -19); + test(S("abcdefghij"), 1, 0, SV("abcdefghijklmnopqrst"), 10, 0, 0); + test(S("abcdefghij"), 1, 0, SV("abcdefghijklmnopqrst"), 10, 1, -1); + test(S("abcdefghij"), 1, 0, SV("abcdefghijklmnopqrst"), 10, 5, -5); + test(S("abcdefghij"), 1, 0, SV("abcdefghijklmnopqrst"), 10, 9, -9); + test(S("abcdefghij"), 1, 0, SV("abcdefghijklmnopqrst"), 10, 10, -10); + test(S("abcdefghij"), 1, 0, SV("abcdefghijklmnopqrst"), 10, 11, -10); + test(S("abcdefghij"), 1, 0, SV("abcdefghijklmnopqrst"), 19, 0, 0); + test(S("abcdefghij"), 1, 0, SV("abcdefghijklmnopqrst"), 19, 1, -1); + test(S("abcdefghij"), 1, 0, SV("abcdefghijklmnopqrst"), 19, 2, -1); + test(S("abcdefghij"), 1, 0, SV("abcdefghijklmnopqrst"), 20, 0, 0); + test(S("abcdefghij"), 1, 0, SV("abcdefghijklmnopqrst"), 20, 1, 0); + test(S("abcdefghij"), 1, 0, SV("abcdefghijklmnopqrst"), 21, 0, 0); + test(S("abcdefghij"), 1, 1, SV(""), 0, 0, 1); + test(S("abcdefghij"), 1, 1, SV(""), 0, 1, 1); + test(S("abcdefghij"), 1, 1, SV(""), 1, 0, 0); + test(S("abcdefghij"), 1, 1, SV("abcde"), 0, 0, 1); + test(S("abcdefghij"), 1, 1, SV("abcde"), 0, 1, 1); + test(S("abcdefghij"), 1, 1, SV("abcde"), 0, 2, 1); + test(S("abcdefghij"), 1, 1, SV("abcde"), 0, 4, 1); + test(S("abcdefghij"), 1, 1, SV("abcde"), 0, 5, 1); + test(S("abcdefghij"), 1, 1, SV("abcde"), 0, 6, 1); + test(S("abcdefghij"), 1, 1, SV("abcde"), 1, 0, 1); + test(S("abcdefghij"), 1, 1, SV("abcde"), 1, 1, 0); + test(S("abcdefghij"), 1, 1, SV("abcde"), 1, 2, -1); + test(S("abcdefghij"), 1, 1, SV("abcde"), 1, 3, -2); + test(S("abcdefghij"), 1, 1, SV("abcde"), 1, 4, -3); + test(S("abcdefghij"), 1, 1, SV("abcde"), 1, 5, -3); + test(S("abcdefghij"), 1, 1, SV("abcde"), 2, 0, 1); + test(S("abcdefghij"), 1, 1, SV("abcde"), 2, 1, -1); + test(S("abcdefghij"), 1, 1, SV("abcde"), 2, 2, -1); + test(S("abcdefghij"), 1, 1, SV("abcde"), 2, 3, -1); + test(S("abcdefghij"), 1, 1, SV("abcde"), 2, 4, -1); + test(S("abcdefghij"), 1, 1, SV("abcde"), 4, 0, 1); + test(S("abcdefghij"), 1, 1, SV("abcde"), 4, 1, -3); + test(S("abcdefghij"), 1, 1, SV("abcde"), 4, 2, -3); + test(S("abcdefghij"), 1, 1, SV("abcde"), 5, 0, 1); + test(S("abcdefghij"), 1, 1, SV("abcde"), 5, 1, 1); + test(S("abcdefghij"), 1, 1, SV("abcde"), 6, 0, 0); + test(S("abcdefghij"), 1, 1, SV("abcdefghij"), 0, 0, 1); + test(S("abcdefghij"), 1, 1, SV("abcdefghij"), 0, 1, 1); + test(S("abcdefghij"), 1, 1, SV("abcdefghij"), 0, 5, 1); + test(S("abcdefghij"), 1, 1, SV("abcdefghij"), 0, 9, 1); + test(S("abcdefghij"), 1, 1, SV("abcdefghij"), 0, 10, 1); + test(S("abcdefghij"), 1, 1, SV("abcdefghij"), 0, 11, 1); + test(S("abcdefghij"), 1, 1, SV("abcdefghij"), 1, 0, 1); + test(S("abcdefghij"), 1, 1, SV("abcdefghij"), 1, 1, 0); + test(S("abcdefghij"), 1, 1, SV("abcdefghij"), 1, 4, -3); + test(S("abcdefghij"), 1, 1, SV("abcdefghij"), 1, 8, -7); + test(S("abcdefghij"), 1, 1, SV("abcdefghij"), 1, 9, -8); + test(S("abcdefghij"), 1, 1, SV("abcdefghij"), 1, 10, -8); + test(S("abcdefghij"), 1, 1, SV("abcdefghij"), 5, 0, 1); + test(S("abcdefghij"), 1, 1, SV("abcdefghij"), 5, 1, -4); + test(S("abcdefghij"), 1, 1, SV("abcdefghij"), 5, 2, -4); + test(S("abcdefghij"), 1, 1, SV("abcdefghij"), 5, 4, -4); + test(S("abcdefghij"), 1, 1, SV("abcdefghij"), 5, 5, -4); + test(S("abcdefghij"), 1, 1, SV("abcdefghij"), 5, 6, -4); + test(S("abcdefghij"), 1, 1, SV("abcdefghij"), 9, 0, 1); + test(S("abcdefghij"), 1, 1, SV("abcdefghij"), 9, 1, -8); + test(S("abcdefghij"), 1, 1, SV("abcdefghij"), 9, 2, -8); + test(S("abcdefghij"), 1, 1, SV("abcdefghij"), 10, 0, 1); + test(S("abcdefghij"), 1, 1, SV("abcdefghij"), 10, 1, 1); + test(S("abcdefghij"), 1, 1, SV("abcdefghij"), 11, 0, 0); + test(S("abcdefghij"), 1, 1, SV("abcdefghijklmnopqrst"), 0, 0, 1); + test(S("abcdefghij"), 1, 1, SV("abcdefghijklmnopqrst"), 0, 1, 1); + test(S("abcdefghij"), 1, 1, SV("abcdefghijklmnopqrst"), 0, 10, 1); + test(S("abcdefghij"), 1, 1, SV("abcdefghijklmnopqrst"), 0, 19, 1); + test(S("abcdefghij"), 1, 1, SV("abcdefghijklmnopqrst"), 0, 20, 1); + test(S("abcdefghij"), 1, 1, SV("abcdefghijklmnopqrst"), 0, 21, 1); + test(S("abcdefghij"), 1, 1, SV("abcdefghijklmnopqrst"), 1, 0, 1); + test(S("abcdefghij"), 1, 1, SV("abcdefghijklmnopqrst"), 1, 1, 0); +} + +template +void test25() +{ + test(S("abcdefghij"), 1, 1, SV("abcdefghijklmnopqrst"), 1, 9, -8); + test(S("abcdefghij"), 1, 1, SV("abcdefghijklmnopqrst"), 1, 18, -17); + test(S("abcdefghij"), 1, 1, SV("abcdefghijklmnopqrst"), 1, 19, -18); + test(S("abcdefghij"), 1, 1, SV("abcdefghijklmnopqrst"), 1, 20, -18); + test(S("abcdefghij"), 1, 1, SV("abcdefghijklmnopqrst"), 10, 0, 1); + test(S("abcdefghij"), 1, 1, SV("abcdefghijklmnopqrst"), 10, 1, -9); + test(S("abcdefghij"), 1, 1, SV("abcdefghijklmnopqrst"), 10, 5, -9); + test(S("abcdefghij"), 1, 1, SV("abcdefghijklmnopqrst"), 10, 9, -9); + test(S("abcdefghij"), 1, 1, SV("abcdefghijklmnopqrst"), 10, 10, -9); + test(S("abcdefghij"), 1, 1, SV("abcdefghijklmnopqrst"), 10, 11, -9); + test(S("abcdefghij"), 1, 1, SV("abcdefghijklmnopqrst"), 19, 0, 1); + test(S("abcdefghij"), 1, 1, SV("abcdefghijklmnopqrst"), 19, 1, -18); + test(S("abcdefghij"), 1, 1, SV("abcdefghijklmnopqrst"), 19, 2, -18); + test(S("abcdefghij"), 1, 1, SV("abcdefghijklmnopqrst"), 20, 0, 1); + test(S("abcdefghij"), 1, 1, SV("abcdefghijklmnopqrst"), 20, 1, 1); + test(S("abcdefghij"), 1, 1, SV("abcdefghijklmnopqrst"), 21, 0, 0); + test(S("abcdefghij"), 1, 4, SV(""), 0, 0, 4); + test(S("abcdefghij"), 1, 4, SV(""), 0, 1, 4); + test(S("abcdefghij"), 1, 4, SV(""), 1, 0, 0); + test(S("abcdefghij"), 1, 4, SV("abcde"), 0, 0, 4); + test(S("abcdefghij"), 1, 4, SV("abcde"), 0, 1, 1); + test(S("abcdefghij"), 1, 4, SV("abcde"), 0, 2, 1); + test(S("abcdefghij"), 1, 4, SV("abcde"), 0, 4, 1); + test(S("abcdefghij"), 1, 4, SV("abcde"), 0, 5, 1); + test(S("abcdefghij"), 1, 4, SV("abcde"), 0, 6, 1); + test(S("abcdefghij"), 1, 4, SV("abcde"), 1, 0, 4); + test(S("abcdefghij"), 1, 4, SV("abcde"), 1, 1, 3); + test(S("abcdefghij"), 1, 4, SV("abcde"), 1, 2, 2); + test(S("abcdefghij"), 1, 4, SV("abcde"), 1, 3, 1); + test(S("abcdefghij"), 1, 4, SV("abcde"), 1, 4, 0); + test(S("abcdefghij"), 1, 4, SV("abcde"), 1, 5, 0); + test(S("abcdefghij"), 1, 4, SV("abcde"), 2, 0, 4); + test(S("abcdefghij"), 1, 4, SV("abcde"), 2, 1, -1); + test(S("abcdefghij"), 1, 4, SV("abcde"), 2, 2, -1); + test(S("abcdefghij"), 1, 4, SV("abcde"), 2, 3, -1); + test(S("abcdefghij"), 1, 4, SV("abcde"), 2, 4, -1); + test(S("abcdefghij"), 1, 4, SV("abcde"), 4, 0, 4); + test(S("abcdefghij"), 1, 4, SV("abcde"), 4, 1, -3); + test(S("abcdefghij"), 1, 4, SV("abcde"), 4, 2, -3); + test(S("abcdefghij"), 1, 4, SV("abcde"), 5, 0, 4); + test(S("abcdefghij"), 1, 4, SV("abcde"), 5, 1, 4); + test(S("abcdefghij"), 1, 4, SV("abcde"), 6, 0, 0); + test(S("abcdefghij"), 1, 4, SV("abcdefghij"), 0, 0, 4); + test(S("abcdefghij"), 1, 4, SV("abcdefghij"), 0, 1, 1); + test(S("abcdefghij"), 1, 4, SV("abcdefghij"), 0, 5, 1); + test(S("abcdefghij"), 1, 4, SV("abcdefghij"), 0, 9, 1); + test(S("abcdefghij"), 1, 4, SV("abcdefghij"), 0, 10, 1); + test(S("abcdefghij"), 1, 4, SV("abcdefghij"), 0, 11, 1); + test(S("abcdefghij"), 1, 4, SV("abcdefghij"), 1, 0, 4); + test(S("abcdefghij"), 1, 4, SV("abcdefghij"), 1, 1, 3); + test(S("abcdefghij"), 1, 4, SV("abcdefghij"), 1, 4, 0); + test(S("abcdefghij"), 1, 4, SV("abcdefghij"), 1, 8, -4); + test(S("abcdefghij"), 1, 4, SV("abcdefghij"), 1, 9, -5); + test(S("abcdefghij"), 1, 4, SV("abcdefghij"), 1, 10, -5); + test(S("abcdefghij"), 1, 4, SV("abcdefghij"), 5, 0, 4); + test(S("abcdefghij"), 1, 4, SV("abcdefghij"), 5, 1, -4); + test(S("abcdefghij"), 1, 4, SV("abcdefghij"), 5, 2, -4); + test(S("abcdefghij"), 1, 4, SV("abcdefghij"), 5, 4, -4); + test(S("abcdefghij"), 1, 4, SV("abcdefghij"), 5, 5, -4); + test(S("abcdefghij"), 1, 4, SV("abcdefghij"), 5, 6, -4); + test(S("abcdefghij"), 1, 4, SV("abcdefghij"), 9, 0, 4); + test(S("abcdefghij"), 1, 4, SV("abcdefghij"), 9, 1, -8); + test(S("abcdefghij"), 1, 4, SV("abcdefghij"), 9, 2, -8); + test(S("abcdefghij"), 1, 4, SV("abcdefghij"), 10, 0, 4); + test(S("abcdefghij"), 1, 4, SV("abcdefghij"), 10, 1, 4); + test(S("abcdefghij"), 1, 4, SV("abcdefghij"), 11, 0, 0); + test(S("abcdefghij"), 1, 4, SV("abcdefghijklmnopqrst"), 0, 0, 4); + test(S("abcdefghij"), 1, 4, SV("abcdefghijklmnopqrst"), 0, 1, 1); + test(S("abcdefghij"), 1, 4, SV("abcdefghijklmnopqrst"), 0, 10, 1); + test(S("abcdefghij"), 1, 4, SV("abcdefghijklmnopqrst"), 0, 19, 1); + test(S("abcdefghij"), 1, 4, SV("abcdefghijklmnopqrst"), 0, 20, 1); + test(S("abcdefghij"), 1, 4, SV("abcdefghijklmnopqrst"), 0, 21, 1); + test(S("abcdefghij"), 1, 4, SV("abcdefghijklmnopqrst"), 1, 0, 4); + test(S("abcdefghij"), 1, 4, SV("abcdefghijklmnopqrst"), 1, 1, 3); + test(S("abcdefghij"), 1, 4, SV("abcdefghijklmnopqrst"), 1, 9, -5); + test(S("abcdefghij"), 1, 4, SV("abcdefghijklmnopqrst"), 1, 18, -14); + test(S("abcdefghij"), 1, 4, SV("abcdefghijklmnopqrst"), 1, 19, -15); + test(S("abcdefghij"), 1, 4, SV("abcdefghijklmnopqrst"), 1, 20, -15); + test(S("abcdefghij"), 1, 4, SV("abcdefghijklmnopqrst"), 10, 0, 4); + test(S("abcdefghij"), 1, 4, SV("abcdefghijklmnopqrst"), 10, 1, -9); + test(S("abcdefghij"), 1, 4, SV("abcdefghijklmnopqrst"), 10, 5, -9); + test(S("abcdefghij"), 1, 4, SV("abcdefghijklmnopqrst"), 10, 9, -9); + test(S("abcdefghij"), 1, 4, SV("abcdefghijklmnopqrst"), 10, 10, -9); + test(S("abcdefghij"), 1, 4, SV("abcdefghijklmnopqrst"), 10, 11, -9); + test(S("abcdefghij"), 1, 4, SV("abcdefghijklmnopqrst"), 19, 0, 4); + test(S("abcdefghij"), 1, 4, SV("abcdefghijklmnopqrst"), 19, 1, -18); + test(S("abcdefghij"), 1, 4, SV("abcdefghijklmnopqrst"), 19, 2, -18); + test(S("abcdefghij"), 1, 4, SV("abcdefghijklmnopqrst"), 20, 0, 4); + test(S("abcdefghij"), 1, 4, SV("abcdefghijklmnopqrst"), 20, 1, 4); + test(S("abcdefghij"), 1, 4, SV("abcdefghijklmnopqrst"), 21, 0, 0); + test(S("abcdefghij"), 1, 8, SV(""), 0, 0, 8); + test(S("abcdefghij"), 1, 8, SV(""), 0, 1, 8); + test(S("abcdefghij"), 1, 8, SV(""), 1, 0, 0); + test(S("abcdefghij"), 1, 8, SV("abcde"), 0, 0, 8); + test(S("abcdefghij"), 1, 8, SV("abcde"), 0, 1, 1); + test(S("abcdefghij"), 1, 8, SV("abcde"), 0, 2, 1); + test(S("abcdefghij"), 1, 8, SV("abcde"), 0, 4, 1); + test(S("abcdefghij"), 1, 8, SV("abcde"), 0, 5, 1); + test(S("abcdefghij"), 1, 8, SV("abcde"), 0, 6, 1); + test(S("abcdefghij"), 1, 8, SV("abcde"), 1, 0, 8); +} + +template +void test26() +{ + test(S("abcdefghij"), 1, 8, SV("abcde"), 1, 1, 7); + test(S("abcdefghij"), 1, 8, SV("abcde"), 1, 2, 6); + test(S("abcdefghij"), 1, 8, SV("abcde"), 1, 3, 5); + test(S("abcdefghij"), 1, 8, SV("abcde"), 1, 4, 4); + test(S("abcdefghij"), 1, 8, SV("abcde"), 1, 5, 4); + test(S("abcdefghij"), 1, 8, SV("abcde"), 2, 0, 8); + test(S("abcdefghij"), 1, 8, SV("abcde"), 2, 1, -1); + test(S("abcdefghij"), 1, 8, SV("abcde"), 2, 2, -1); + test(S("abcdefghij"), 1, 8, SV("abcde"), 2, 3, -1); + test(S("abcdefghij"), 1, 8, SV("abcde"), 2, 4, -1); + test(S("abcdefghij"), 1, 8, SV("abcde"), 4, 0, 8); + test(S("abcdefghij"), 1, 8, SV("abcde"), 4, 1, -3); + test(S("abcdefghij"), 1, 8, SV("abcde"), 4, 2, -3); + test(S("abcdefghij"), 1, 8, SV("abcde"), 5, 0, 8); + test(S("abcdefghij"), 1, 8, SV("abcde"), 5, 1, 8); + test(S("abcdefghij"), 1, 8, SV("abcde"), 6, 0, 0); + test(S("abcdefghij"), 1, 8, SV("abcdefghij"), 0, 0, 8); + test(S("abcdefghij"), 1, 8, SV("abcdefghij"), 0, 1, 1); + test(S("abcdefghij"), 1, 8, SV("abcdefghij"), 0, 5, 1); + test(S("abcdefghij"), 1, 8, SV("abcdefghij"), 0, 9, 1); + test(S("abcdefghij"), 1, 8, SV("abcdefghij"), 0, 10, 1); + test(S("abcdefghij"), 1, 8, SV("abcdefghij"), 0, 11, 1); + test(S("abcdefghij"), 1, 8, SV("abcdefghij"), 1, 0, 8); + test(S("abcdefghij"), 1, 8, SV("abcdefghij"), 1, 1, 7); + test(S("abcdefghij"), 1, 8, SV("abcdefghij"), 1, 4, 4); + test(S("abcdefghij"), 1, 8, SV("abcdefghij"), 1, 8, 0); + test(S("abcdefghij"), 1, 8, SV("abcdefghij"), 1, 9, -1); + test(S("abcdefghij"), 1, 8, SV("abcdefghij"), 1, 10, -1); + test(S("abcdefghij"), 1, 8, SV("abcdefghij"), 5, 0, 8); + test(S("abcdefghij"), 1, 8, SV("abcdefghij"), 5, 1, -4); + test(S("abcdefghij"), 1, 8, SV("abcdefghij"), 5, 2, -4); + test(S("abcdefghij"), 1, 8, SV("abcdefghij"), 5, 4, -4); + test(S("abcdefghij"), 1, 8, SV("abcdefghij"), 5, 5, -4); + test(S("abcdefghij"), 1, 8, SV("abcdefghij"), 5, 6, -4); + test(S("abcdefghij"), 1, 8, SV("abcdefghij"), 9, 0, 8); + test(S("abcdefghij"), 1, 8, SV("abcdefghij"), 9, 1, -8); + test(S("abcdefghij"), 1, 8, SV("abcdefghij"), 9, 2, -8); + test(S("abcdefghij"), 1, 8, SV("abcdefghij"), 10, 0, 8); + test(S("abcdefghij"), 1, 8, SV("abcdefghij"), 10, 1, 8); + test(S("abcdefghij"), 1, 8, SV("abcdefghij"), 11, 0, 0); + test(S("abcdefghij"), 1, 8, SV("abcdefghijklmnopqrst"), 0, 0, 8); + test(S("abcdefghij"), 1, 8, SV("abcdefghijklmnopqrst"), 0, 1, 1); + test(S("abcdefghij"), 1, 8, SV("abcdefghijklmnopqrst"), 0, 10, 1); + test(S("abcdefghij"), 1, 8, SV("abcdefghijklmnopqrst"), 0, 19, 1); + test(S("abcdefghij"), 1, 8, SV("abcdefghijklmnopqrst"), 0, 20, 1); + test(S("abcdefghij"), 1, 8, SV("abcdefghijklmnopqrst"), 0, 21, 1); + test(S("abcdefghij"), 1, 8, SV("abcdefghijklmnopqrst"), 1, 0, 8); + test(S("abcdefghij"), 1, 8, SV("abcdefghijklmnopqrst"), 1, 1, 7); + test(S("abcdefghij"), 1, 8, SV("abcdefghijklmnopqrst"), 1, 9, -1); + test(S("abcdefghij"), 1, 8, SV("abcdefghijklmnopqrst"), 1, 18, -10); + test(S("abcdefghij"), 1, 8, SV("abcdefghijklmnopqrst"), 1, 19, -11); + test(S("abcdefghij"), 1, 8, SV("abcdefghijklmnopqrst"), 1, 20, -11); + test(S("abcdefghij"), 1, 8, SV("abcdefghijklmnopqrst"), 10, 0, 8); + test(S("abcdefghij"), 1, 8, SV("abcdefghijklmnopqrst"), 10, 1, -9); + test(S("abcdefghij"), 1, 8, SV("abcdefghijklmnopqrst"), 10, 5, -9); + test(S("abcdefghij"), 1, 8, SV("abcdefghijklmnopqrst"), 10, 9, -9); + test(S("abcdefghij"), 1, 8, SV("abcdefghijklmnopqrst"), 10, 10, -9); + test(S("abcdefghij"), 1, 8, SV("abcdefghijklmnopqrst"), 10, 11, -9); + test(S("abcdefghij"), 1, 8, SV("abcdefghijklmnopqrst"), 19, 0, 8); + test(S("abcdefghij"), 1, 8, SV("abcdefghijklmnopqrst"), 19, 1, -18); + test(S("abcdefghij"), 1, 8, SV("abcdefghijklmnopqrst"), 19, 2, -18); + test(S("abcdefghij"), 1, 8, SV("abcdefghijklmnopqrst"), 20, 0, 8); + test(S("abcdefghij"), 1, 8, SV("abcdefghijklmnopqrst"), 20, 1, 8); + test(S("abcdefghij"), 1, 8, SV("abcdefghijklmnopqrst"), 21, 0, 0); + test(S("abcdefghij"), 1, 9, SV(""), 0, 0, 9); + test(S("abcdefghij"), 1, 9, SV(""), 0, 1, 9); + test(S("abcdefghij"), 1, 9, SV(""), 1, 0, 0); + test(S("abcdefghij"), 1, 9, SV("abcde"), 0, 0, 9); + test(S("abcdefghij"), 1, 9, SV("abcde"), 0, 1, 1); + test(S("abcdefghij"), 1, 9, SV("abcde"), 0, 2, 1); + test(S("abcdefghij"), 1, 9, SV("abcde"), 0, 4, 1); + test(S("abcdefghij"), 1, 9, SV("abcde"), 0, 5, 1); + test(S("abcdefghij"), 1, 9, SV("abcde"), 0, 6, 1); + test(S("abcdefghij"), 1, 9, SV("abcde"), 1, 0, 9); + test(S("abcdefghij"), 1, 9, SV("abcde"), 1, 1, 8); + test(S("abcdefghij"), 1, 9, SV("abcde"), 1, 2, 7); + test(S("abcdefghij"), 1, 9, SV("abcde"), 1, 3, 6); + test(S("abcdefghij"), 1, 9, SV("abcde"), 1, 4, 5); + test(S("abcdefghij"), 1, 9, SV("abcde"), 1, 5, 5); + test(S("abcdefghij"), 1, 9, SV("abcde"), 2, 0, 9); + test(S("abcdefghij"), 1, 9, SV("abcde"), 2, 1, -1); + test(S("abcdefghij"), 1, 9, SV("abcde"), 2, 2, -1); + test(S("abcdefghij"), 1, 9, SV("abcde"), 2, 3, -1); + test(S("abcdefghij"), 1, 9, SV("abcde"), 2, 4, -1); + test(S("abcdefghij"), 1, 9, SV("abcde"), 4, 0, 9); + test(S("abcdefghij"), 1, 9, SV("abcde"), 4, 1, -3); + test(S("abcdefghij"), 1, 9, SV("abcde"), 4, 2, -3); + test(S("abcdefghij"), 1, 9, SV("abcde"), 5, 0, 9); + test(S("abcdefghij"), 1, 9, SV("abcde"), 5, 1, 9); + test(S("abcdefghij"), 1, 9, SV("abcde"), 6, 0, 0); + test(S("abcdefghij"), 1, 9, SV("abcdefghij"), 0, 0, 9); + test(S("abcdefghij"), 1, 9, SV("abcdefghij"), 0, 1, 1); + test(S("abcdefghij"), 1, 9, SV("abcdefghij"), 0, 5, 1); + test(S("abcdefghij"), 1, 9, SV("abcdefghij"), 0, 9, 1); + test(S("abcdefghij"), 1, 9, SV("abcdefghij"), 0, 10, 1); + test(S("abcdefghij"), 1, 9, SV("abcdefghij"), 0, 11, 1); + test(S("abcdefghij"), 1, 9, SV("abcdefghij"), 1, 0, 9); + test(S("abcdefghij"), 1, 9, SV("abcdefghij"), 1, 1, 8); + test(S("abcdefghij"), 1, 9, SV("abcdefghij"), 1, 4, 5); + test(S("abcdefghij"), 1, 9, SV("abcdefghij"), 1, 8, 1); +} + +template +void test27() +{ + test(S("abcdefghij"), 1, 9, SV("abcdefghij"), 1, 9, 0); + test(S("abcdefghij"), 1, 9, SV("abcdefghij"), 1, 10, 0); + test(S("abcdefghij"), 1, 9, SV("abcdefghij"), 5, 0, 9); + test(S("abcdefghij"), 1, 9, SV("abcdefghij"), 5, 1, -4); + test(S("abcdefghij"), 1, 9, SV("abcdefghij"), 5, 2, -4); + test(S("abcdefghij"), 1, 9, SV("abcdefghij"), 5, 4, -4); + test(S("abcdefghij"), 1, 9, SV("abcdefghij"), 5, 5, -4); + test(S("abcdefghij"), 1, 9, SV("abcdefghij"), 5, 6, -4); + test(S("abcdefghij"), 1, 9, SV("abcdefghij"), 9, 0, 9); + test(S("abcdefghij"), 1, 9, SV("abcdefghij"), 9, 1, -8); + test(S("abcdefghij"), 1, 9, SV("abcdefghij"), 9, 2, -8); + test(S("abcdefghij"), 1, 9, SV("abcdefghij"), 10, 0, 9); + test(S("abcdefghij"), 1, 9, SV("abcdefghij"), 10, 1, 9); + test(S("abcdefghij"), 1, 9, SV("abcdefghij"), 11, 0, 0); + test(S("abcdefghij"), 1, 9, SV("abcdefghijklmnopqrst"), 0, 0, 9); + test(S("abcdefghij"), 1, 9, SV("abcdefghijklmnopqrst"), 0, 1, 1); + test(S("abcdefghij"), 1, 9, SV("abcdefghijklmnopqrst"), 0, 10, 1); + test(S("abcdefghij"), 1, 9, SV("abcdefghijklmnopqrst"), 0, 19, 1); + test(S("abcdefghij"), 1, 9, SV("abcdefghijklmnopqrst"), 0, 20, 1); + test(S("abcdefghij"), 1, 9, SV("abcdefghijklmnopqrst"), 0, 21, 1); + test(S("abcdefghij"), 1, 9, SV("abcdefghijklmnopqrst"), 1, 0, 9); + test(S("abcdefghij"), 1, 9, SV("abcdefghijklmnopqrst"), 1, 1, 8); + test(S("abcdefghij"), 1, 9, SV("abcdefghijklmnopqrst"), 1, 9, 0); + test(S("abcdefghij"), 1, 9, SV("abcdefghijklmnopqrst"), 1, 18, -9); + test(S("abcdefghij"), 1, 9, SV("abcdefghijklmnopqrst"), 1, 19, -10); + test(S("abcdefghij"), 1, 9, SV("abcdefghijklmnopqrst"), 1, 20, -10); + test(S("abcdefghij"), 1, 9, SV("abcdefghijklmnopqrst"), 10, 0, 9); + test(S("abcdefghij"), 1, 9, SV("abcdefghijklmnopqrst"), 10, 1, -9); + test(S("abcdefghij"), 1, 9, SV("abcdefghijklmnopqrst"), 10, 5, -9); + test(S("abcdefghij"), 1, 9, SV("abcdefghijklmnopqrst"), 10, 9, -9); + test(S("abcdefghij"), 1, 9, SV("abcdefghijklmnopqrst"), 10, 10, -9); + test(S("abcdefghij"), 1, 9, SV("abcdefghijklmnopqrst"), 10, 11, -9); + test(S("abcdefghij"), 1, 9, SV("abcdefghijklmnopqrst"), 19, 0, 9); + test(S("abcdefghij"), 1, 9, SV("abcdefghijklmnopqrst"), 19, 1, -18); + test(S("abcdefghij"), 1, 9, SV("abcdefghijklmnopqrst"), 19, 2, -18); + test(S("abcdefghij"), 1, 9, SV("abcdefghijklmnopqrst"), 20, 0, 9); + test(S("abcdefghij"), 1, 9, SV("abcdefghijklmnopqrst"), 20, 1, 9); + test(S("abcdefghij"), 1, 9, SV("abcdefghijklmnopqrst"), 21, 0, 0); + test(S("abcdefghij"), 1, 10, SV(""), 0, 0, 9); + test(S("abcdefghij"), 1, 10, SV(""), 0, 1, 9); + test(S("abcdefghij"), 1, 10, SV(""), 1, 0, 0); + test(S("abcdefghij"), 1, 10, SV("abcde"), 0, 0, 9); + test(S("abcdefghij"), 1, 10, SV("abcde"), 0, 1, 1); + test(S("abcdefghij"), 1, 10, SV("abcde"), 0, 2, 1); + test(S("abcdefghij"), 1, 10, SV("abcde"), 0, 4, 1); + test(S("abcdefghij"), 1, 10, SV("abcde"), 0, 5, 1); + test(S("abcdefghij"), 1, 10, SV("abcde"), 0, 6, 1); + test(S("abcdefghij"), 1, 10, SV("abcde"), 1, 0, 9); + test(S("abcdefghij"), 1, 10, SV("abcde"), 1, 1, 8); + test(S("abcdefghij"), 1, 10, SV("abcde"), 1, 2, 7); + test(S("abcdefghij"), 1, 10, SV("abcde"), 1, 3, 6); + test(S("abcdefghij"), 1, 10, SV("abcde"), 1, 4, 5); + test(S("abcdefghij"), 1, 10, SV("abcde"), 1, 5, 5); + test(S("abcdefghij"), 1, 10, SV("abcde"), 2, 0, 9); + test(S("abcdefghij"), 1, 10, SV("abcde"), 2, 1, -1); + test(S("abcdefghij"), 1, 10, SV("abcde"), 2, 2, -1); + test(S("abcdefghij"), 1, 10, SV("abcde"), 2, 3, -1); + test(S("abcdefghij"), 1, 10, SV("abcde"), 2, 4, -1); + test(S("abcdefghij"), 1, 10, SV("abcde"), 4, 0, 9); + test(S("abcdefghij"), 1, 10, SV("abcde"), 4, 1, -3); + test(S("abcdefghij"), 1, 10, SV("abcde"), 4, 2, -3); + test(S("abcdefghij"), 1, 10, SV("abcde"), 5, 0, 9); + test(S("abcdefghij"), 1, 10, SV("abcde"), 5, 1, 9); + test(S("abcdefghij"), 1, 10, SV("abcde"), 6, 0, 0); + test(S("abcdefghij"), 1, 10, SV("abcdefghij"), 0, 0, 9); + test(S("abcdefghij"), 1, 10, SV("abcdefghij"), 0, 1, 1); + test(S("abcdefghij"), 1, 10, SV("abcdefghij"), 0, 5, 1); + test(S("abcdefghij"), 1, 10, SV("abcdefghij"), 0, 9, 1); + test(S("abcdefghij"), 1, 10, SV("abcdefghij"), 0, 10, 1); + test(S("abcdefghij"), 1, 10, SV("abcdefghij"), 0, 11, 1); + test(S("abcdefghij"), 1, 10, SV("abcdefghij"), 1, 0, 9); + test(S("abcdefghij"), 1, 10, SV("abcdefghij"), 1, 1, 8); + test(S("abcdefghij"), 1, 10, SV("abcdefghij"), 1, 4, 5); + test(S("abcdefghij"), 1, 10, SV("abcdefghij"), 1, 8, 1); + test(S("abcdefghij"), 1, 10, SV("abcdefghij"), 1, 9, 0); + test(S("abcdefghij"), 1, 10, SV("abcdefghij"), 1, 10, 0); + test(S("abcdefghij"), 1, 10, SV("abcdefghij"), 5, 0, 9); + test(S("abcdefghij"), 1, 10, SV("abcdefghij"), 5, 1, -4); + test(S("abcdefghij"), 1, 10, SV("abcdefghij"), 5, 2, -4); + test(S("abcdefghij"), 1, 10, SV("abcdefghij"), 5, 4, -4); + test(S("abcdefghij"), 1, 10, SV("abcdefghij"), 5, 5, -4); + test(S("abcdefghij"), 1, 10, SV("abcdefghij"), 5, 6, -4); + test(S("abcdefghij"), 1, 10, SV("abcdefghij"), 9, 0, 9); + test(S("abcdefghij"), 1, 10, SV("abcdefghij"), 9, 1, -8); + test(S("abcdefghij"), 1, 10, SV("abcdefghij"), 9, 2, -8); + test(S("abcdefghij"), 1, 10, SV("abcdefghij"), 10, 0, 9); + test(S("abcdefghij"), 1, 10, SV("abcdefghij"), 10, 1, 9); + test(S("abcdefghij"), 1, 10, SV("abcdefghij"), 11, 0, 0); + test(S("abcdefghij"), 1, 10, SV("abcdefghijklmnopqrst"), 0, 0, 9); + test(S("abcdefghij"), 1, 10, SV("abcdefghijklmnopqrst"), 0, 1, 1); + test(S("abcdefghij"), 1, 10, SV("abcdefghijklmnopqrst"), 0, 10, 1); + test(S("abcdefghij"), 1, 10, SV("abcdefghijklmnopqrst"), 0, 19, 1); + test(S("abcdefghij"), 1, 10, SV("abcdefghijklmnopqrst"), 0, 20, 1); + test(S("abcdefghij"), 1, 10, SV("abcdefghijklmnopqrst"), 0, 21, 1); + test(S("abcdefghij"), 1, 10, SV("abcdefghijklmnopqrst"), 1, 0, 9); + test(S("abcdefghij"), 1, 10, SV("abcdefghijklmnopqrst"), 1, 1, 8); + test(S("abcdefghij"), 1, 10, SV("abcdefghijklmnopqrst"), 1, 9, 0); + test(S("abcdefghij"), 1, 10, SV("abcdefghijklmnopqrst"), 1, 18, -9); + test(S("abcdefghij"), 1, 10, SV("abcdefghijklmnopqrst"), 1, 19, -10); + test(S("abcdefghij"), 1, 10, SV("abcdefghijklmnopqrst"), 1, 20, -10); +} + +template +void test28() +{ + test(S("abcdefghij"), 1, 10, SV("abcdefghijklmnopqrst"), 10, 0, 9); + test(S("abcdefghij"), 1, 10, SV("abcdefghijklmnopqrst"), 10, 1, -9); + test(S("abcdefghij"), 1, 10, SV("abcdefghijklmnopqrst"), 10, 5, -9); + test(S("abcdefghij"), 1, 10, SV("abcdefghijklmnopqrst"), 10, 9, -9); + test(S("abcdefghij"), 1, 10, SV("abcdefghijklmnopqrst"), 10, 10, -9); + test(S("abcdefghij"), 1, 10, SV("abcdefghijklmnopqrst"), 10, 11, -9); + test(S("abcdefghij"), 1, 10, SV("abcdefghijklmnopqrst"), 19, 0, 9); + test(S("abcdefghij"), 1, 10, SV("abcdefghijklmnopqrst"), 19, 1, -18); + test(S("abcdefghij"), 1, 10, SV("abcdefghijklmnopqrst"), 19, 2, -18); + test(S("abcdefghij"), 1, 10, SV("abcdefghijklmnopqrst"), 20, 0, 9); + test(S("abcdefghij"), 1, 10, SV("abcdefghijklmnopqrst"), 20, 1, 9); + test(S("abcdefghij"), 1, 10, SV("abcdefghijklmnopqrst"), 21, 0, 0); + test(S("abcdefghij"), 5, 0, SV(""), 0, 0, 0); + test(S("abcdefghij"), 5, 0, SV(""), 0, 1, 0); + test(S("abcdefghij"), 5, 0, SV(""), 1, 0, 0); + test(S("abcdefghij"), 5, 0, SV("abcde"), 0, 0, 0); + test(S("abcdefghij"), 5, 0, SV("abcde"), 0, 1, -1); + test(S("abcdefghij"), 5, 0, SV("abcde"), 0, 2, -2); + test(S("abcdefghij"), 5, 0, SV("abcde"), 0, 4, -4); + test(S("abcdefghij"), 5, 0, SV("abcde"), 0, 5, -5); + test(S("abcdefghij"), 5, 0, SV("abcde"), 0, 6, -5); + test(S("abcdefghij"), 5, 0, SV("abcde"), 1, 0, 0); + test(S("abcdefghij"), 5, 0, SV("abcde"), 1, 1, -1); + test(S("abcdefghij"), 5, 0, SV("abcde"), 1, 2, -2); + test(S("abcdefghij"), 5, 0, SV("abcde"), 1, 3, -3); + test(S("abcdefghij"), 5, 0, SV("abcde"), 1, 4, -4); + test(S("abcdefghij"), 5, 0, SV("abcde"), 1, 5, -4); + test(S("abcdefghij"), 5, 0, SV("abcde"), 2, 0, 0); + test(S("abcdefghij"), 5, 0, SV("abcde"), 2, 1, -1); + test(S("abcdefghij"), 5, 0, SV("abcde"), 2, 2, -2); + test(S("abcdefghij"), 5, 0, SV("abcde"), 2, 3, -3); + test(S("abcdefghij"), 5, 0, SV("abcde"), 2, 4, -3); + test(S("abcdefghij"), 5, 0, SV("abcde"), 4, 0, 0); + test(S("abcdefghij"), 5, 0, SV("abcde"), 4, 1, -1); + test(S("abcdefghij"), 5, 0, SV("abcde"), 4, 2, -1); + test(S("abcdefghij"), 5, 0, SV("abcde"), 5, 0, 0); + test(S("abcdefghij"), 5, 0, SV("abcde"), 5, 1, 0); + test(S("abcdefghij"), 5, 0, SV("abcde"), 6, 0, 0); + test(S("abcdefghij"), 5, 0, SV("abcdefghij"), 0, 0, 0); + test(S("abcdefghij"), 5, 0, SV("abcdefghij"), 0, 1, -1); + test(S("abcdefghij"), 5, 0, SV("abcdefghij"), 0, 5, -5); + test(S("abcdefghij"), 5, 0, SV("abcdefghij"), 0, 9, -9); + test(S("abcdefghij"), 5, 0, SV("abcdefghij"), 0, 10, -10); + test(S("abcdefghij"), 5, 0, SV("abcdefghij"), 0, 11, -10); + test(S("abcdefghij"), 5, 0, SV("abcdefghij"), 1, 0, 0); + test(S("abcdefghij"), 5, 0, SV("abcdefghij"), 1, 1, -1); + test(S("abcdefghij"), 5, 0, SV("abcdefghij"), 1, 4, -4); + test(S("abcdefghij"), 5, 0, SV("abcdefghij"), 1, 8, -8); + test(S("abcdefghij"), 5, 0, SV("abcdefghij"), 1, 9, -9); + test(S("abcdefghij"), 5, 0, SV("abcdefghij"), 1, 10, -9); + test(S("abcdefghij"), 5, 0, SV("abcdefghij"), 5, 0, 0); + test(S("abcdefghij"), 5, 0, SV("abcdefghij"), 5, 1, -1); + test(S("abcdefghij"), 5, 0, SV("abcdefghij"), 5, 2, -2); + test(S("abcdefghij"), 5, 0, SV("abcdefghij"), 5, 4, -4); + test(S("abcdefghij"), 5, 0, SV("abcdefghij"), 5, 5, -5); + test(S("abcdefghij"), 5, 0, SV("abcdefghij"), 5, 6, -5); + test(S("abcdefghij"), 5, 0, SV("abcdefghij"), 9, 0, 0); + test(S("abcdefghij"), 5, 0, SV("abcdefghij"), 9, 1, -1); + test(S("abcdefghij"), 5, 0, SV("abcdefghij"), 9, 2, -1); + test(S("abcdefghij"), 5, 0, SV("abcdefghij"), 10, 0, 0); + test(S("abcdefghij"), 5, 0, SV("abcdefghij"), 10, 1, 0); + test(S("abcdefghij"), 5, 0, SV("abcdefghij"), 11, 0, 0); + test(S("abcdefghij"), 5, 0, SV("abcdefghijklmnopqrst"), 0, 0, 0); + test(S("abcdefghij"), 5, 0, SV("abcdefghijklmnopqrst"), 0, 1, -1); + test(S("abcdefghij"), 5, 0, SV("abcdefghijklmnopqrst"), 0, 10, -10); + test(S("abcdefghij"), 5, 0, SV("abcdefghijklmnopqrst"), 0, 19, -19); + test(S("abcdefghij"), 5, 0, SV("abcdefghijklmnopqrst"), 0, 20, -20); + test(S("abcdefghij"), 5, 0, SV("abcdefghijklmnopqrst"), 0, 21, -20); + test(S("abcdefghij"), 5, 0, SV("abcdefghijklmnopqrst"), 1, 0, 0); + test(S("abcdefghij"), 5, 0, SV("abcdefghijklmnopqrst"), 1, 1, -1); + test(S("abcdefghij"), 5, 0, SV("abcdefghijklmnopqrst"), 1, 9, -9); + test(S("abcdefghij"), 5, 0, SV("abcdefghijklmnopqrst"), 1, 18, -18); + test(S("abcdefghij"), 5, 0, SV("abcdefghijklmnopqrst"), 1, 19, -19); + test(S("abcdefghij"), 5, 0, SV("abcdefghijklmnopqrst"), 1, 20, -19); + test(S("abcdefghij"), 5, 0, SV("abcdefghijklmnopqrst"), 10, 0, 0); + test(S("abcdefghij"), 5, 0, SV("abcdefghijklmnopqrst"), 10, 1, -1); + test(S("abcdefghij"), 5, 0, SV("abcdefghijklmnopqrst"), 10, 5, -5); + test(S("abcdefghij"), 5, 0, SV("abcdefghijklmnopqrst"), 10, 9, -9); + test(S("abcdefghij"), 5, 0, SV("abcdefghijklmnopqrst"), 10, 10, -10); + test(S("abcdefghij"), 5, 0, SV("abcdefghijklmnopqrst"), 10, 11, -10); + test(S("abcdefghij"), 5, 0, SV("abcdefghijklmnopqrst"), 19, 0, 0); + test(S("abcdefghij"), 5, 0, SV("abcdefghijklmnopqrst"), 19, 1, -1); + test(S("abcdefghij"), 5, 0, SV("abcdefghijklmnopqrst"), 19, 2, -1); + test(S("abcdefghij"), 5, 0, SV("abcdefghijklmnopqrst"), 20, 0, 0); + test(S("abcdefghij"), 5, 0, SV("abcdefghijklmnopqrst"), 20, 1, 0); + test(S("abcdefghij"), 5, 0, SV("abcdefghijklmnopqrst"), 21, 0, 0); + test(S("abcdefghij"), 5, 1, SV(""), 0, 0, 1); + test(S("abcdefghij"), 5, 1, SV(""), 0, 1, 1); + test(S("abcdefghij"), 5, 1, SV(""), 1, 0, 0); + test(S("abcdefghij"), 5, 1, SV("abcde"), 0, 0, 1); + test(S("abcdefghij"), 5, 1, SV("abcde"), 0, 1, 5); + test(S("abcdefghij"), 5, 1, SV("abcde"), 0, 2, 5); + test(S("abcdefghij"), 5, 1, SV("abcde"), 0, 4, 5); + test(S("abcdefghij"), 5, 1, SV("abcde"), 0, 5, 5); + test(S("abcdefghij"), 5, 1, SV("abcde"), 0, 6, 5); + test(S("abcdefghij"), 5, 1, SV("abcde"), 1, 0, 1); + test(S("abcdefghij"), 5, 1, SV("abcde"), 1, 1, 4); + test(S("abcdefghij"), 5, 1, SV("abcde"), 1, 2, 4); + test(S("abcdefghij"), 5, 1, SV("abcde"), 1, 3, 4); + test(S("abcdefghij"), 5, 1, SV("abcde"), 1, 4, 4); +} + +template +void test29() +{ + test(S("abcdefghij"), 5, 1, SV("abcde"), 1, 5, 4); + test(S("abcdefghij"), 5, 1, SV("abcde"), 2, 0, 1); + test(S("abcdefghij"), 5, 1, SV("abcde"), 2, 1, 3); + test(S("abcdefghij"), 5, 1, SV("abcde"), 2, 2, 3); + test(S("abcdefghij"), 5, 1, SV("abcde"), 2, 3, 3); + test(S("abcdefghij"), 5, 1, SV("abcde"), 2, 4, 3); + test(S("abcdefghij"), 5, 1, SV("abcde"), 4, 0, 1); + test(S("abcdefghij"), 5, 1, SV("abcde"), 4, 1, 1); + test(S("abcdefghij"), 5, 1, SV("abcde"), 4, 2, 1); + test(S("abcdefghij"), 5, 1, SV("abcde"), 5, 0, 1); + test(S("abcdefghij"), 5, 1, SV("abcde"), 5, 1, 1); + test(S("abcdefghij"), 5, 1, SV("abcde"), 6, 0, 0); + test(S("abcdefghij"), 5, 1, SV("abcdefghij"), 0, 0, 1); + test(S("abcdefghij"), 5, 1, SV("abcdefghij"), 0, 1, 5); + test(S("abcdefghij"), 5, 1, SV("abcdefghij"), 0, 5, 5); + test(S("abcdefghij"), 5, 1, SV("abcdefghij"), 0, 9, 5); + test(S("abcdefghij"), 5, 1, SV("abcdefghij"), 0, 10, 5); + test(S("abcdefghij"), 5, 1, SV("abcdefghij"), 0, 11, 5); + test(S("abcdefghij"), 5, 1, SV("abcdefghij"), 1, 0, 1); + test(S("abcdefghij"), 5, 1, SV("abcdefghij"), 1, 1, 4); + test(S("abcdefghij"), 5, 1, SV("abcdefghij"), 1, 4, 4); + test(S("abcdefghij"), 5, 1, SV("abcdefghij"), 1, 8, 4); + test(S("abcdefghij"), 5, 1, SV("abcdefghij"), 1, 9, 4); + test(S("abcdefghij"), 5, 1, SV("abcdefghij"), 1, 10, 4); + test(S("abcdefghij"), 5, 1, SV("abcdefghij"), 5, 0, 1); + test(S("abcdefghij"), 5, 1, SV("abcdefghij"), 5, 1, 0); + test(S("abcdefghij"), 5, 1, SV("abcdefghij"), 5, 2, -1); + test(S("abcdefghij"), 5, 1, SV("abcdefghij"), 5, 4, -3); + test(S("abcdefghij"), 5, 1, SV("abcdefghij"), 5, 5, -4); + test(S("abcdefghij"), 5, 1, SV("abcdefghij"), 5, 6, -4); + test(S("abcdefghij"), 5, 1, SV("abcdefghij"), 9, 0, 1); + test(S("abcdefghij"), 5, 1, SV("abcdefghij"), 9, 1, -4); + test(S("abcdefghij"), 5, 1, SV("abcdefghij"), 9, 2, -4); + test(S("abcdefghij"), 5, 1, SV("abcdefghij"), 10, 0, 1); + test(S("abcdefghij"), 5, 1, SV("abcdefghij"), 10, 1, 1); + test(S("abcdefghij"), 5, 1, SV("abcdefghij"), 11, 0, 0); + test(S("abcdefghij"), 5, 1, SV("abcdefghijklmnopqrst"), 0, 0, 1); + test(S("abcdefghij"), 5, 1, SV("abcdefghijklmnopqrst"), 0, 1, 5); + test(S("abcdefghij"), 5, 1, SV("abcdefghijklmnopqrst"), 0, 10, 5); + test(S("abcdefghij"), 5, 1, SV("abcdefghijklmnopqrst"), 0, 19, 5); + test(S("abcdefghij"), 5, 1, SV("abcdefghijklmnopqrst"), 0, 20, 5); + test(S("abcdefghij"), 5, 1, SV("abcdefghijklmnopqrst"), 0, 21, 5); + test(S("abcdefghij"), 5, 1, SV("abcdefghijklmnopqrst"), 1, 0, 1); + test(S("abcdefghij"), 5, 1, SV("abcdefghijklmnopqrst"), 1, 1, 4); + test(S("abcdefghij"), 5, 1, SV("abcdefghijklmnopqrst"), 1, 9, 4); + test(S("abcdefghij"), 5, 1, SV("abcdefghijklmnopqrst"), 1, 18, 4); + test(S("abcdefghij"), 5, 1, SV("abcdefghijklmnopqrst"), 1, 19, 4); + test(S("abcdefghij"), 5, 1, SV("abcdefghijklmnopqrst"), 1, 20, 4); + test(S("abcdefghij"), 5, 1, SV("abcdefghijklmnopqrst"), 10, 0, 1); + test(S("abcdefghij"), 5, 1, SV("abcdefghijklmnopqrst"), 10, 1, -5); + test(S("abcdefghij"), 5, 1, SV("abcdefghijklmnopqrst"), 10, 5, -5); + test(S("abcdefghij"), 5, 1, SV("abcdefghijklmnopqrst"), 10, 9, -5); + test(S("abcdefghij"), 5, 1, SV("abcdefghijklmnopqrst"), 10, 10, -5); + test(S("abcdefghij"), 5, 1, SV("abcdefghijklmnopqrst"), 10, 11, -5); + test(S("abcdefghij"), 5, 1, SV("abcdefghijklmnopqrst"), 19, 0, 1); + test(S("abcdefghij"), 5, 1, SV("abcdefghijklmnopqrst"), 19, 1, -14); + test(S("abcdefghij"), 5, 1, SV("abcdefghijklmnopqrst"), 19, 2, -14); + test(S("abcdefghij"), 5, 1, SV("abcdefghijklmnopqrst"), 20, 0, 1); + test(S("abcdefghij"), 5, 1, SV("abcdefghijklmnopqrst"), 20, 1, 1); + test(S("abcdefghij"), 5, 1, SV("abcdefghijklmnopqrst"), 21, 0, 0); + test(S("abcdefghij"), 5, 2, SV(""), 0, 0, 2); + test(S("abcdefghij"), 5, 2, SV(""), 0, 1, 2); + test(S("abcdefghij"), 5, 2, SV(""), 1, 0, 0); + test(S("abcdefghij"), 5, 2, SV("abcde"), 0, 0, 2); + test(S("abcdefghij"), 5, 2, SV("abcde"), 0, 1, 5); + test(S("abcdefghij"), 5, 2, SV("abcde"), 0, 2, 5); + test(S("abcdefghij"), 5, 2, SV("abcde"), 0, 4, 5); + test(S("abcdefghij"), 5, 2, SV("abcde"), 0, 5, 5); + test(S("abcdefghij"), 5, 2, SV("abcde"), 0, 6, 5); + test(S("abcdefghij"), 5, 2, SV("abcde"), 1, 0, 2); + test(S("abcdefghij"), 5, 2, SV("abcde"), 1, 1, 4); + test(S("abcdefghij"), 5, 2, SV("abcde"), 1, 2, 4); + test(S("abcdefghij"), 5, 2, SV("abcde"), 1, 3, 4); + test(S("abcdefghij"), 5, 2, SV("abcde"), 1, 4, 4); + test(S("abcdefghij"), 5, 2, SV("abcde"), 1, 5, 4); + test(S("abcdefghij"), 5, 2, SV("abcde"), 2, 0, 2); + test(S("abcdefghij"), 5, 2, SV("abcde"), 2, 1, 3); + test(S("abcdefghij"), 5, 2, SV("abcde"), 2, 2, 3); + test(S("abcdefghij"), 5, 2, SV("abcde"), 2, 3, 3); + test(S("abcdefghij"), 5, 2, SV("abcde"), 2, 4, 3); + test(S("abcdefghij"), 5, 2, SV("abcde"), 4, 0, 2); + test(S("abcdefghij"), 5, 2, SV("abcde"), 4, 1, 1); + test(S("abcdefghij"), 5, 2, SV("abcde"), 4, 2, 1); + test(S("abcdefghij"), 5, 2, SV("abcde"), 5, 0, 2); + test(S("abcdefghij"), 5, 2, SV("abcde"), 5, 1, 2); + test(S("abcdefghij"), 5, 2, SV("abcde"), 6, 0, 0); + test(S("abcdefghij"), 5, 2, SV("abcdefghij"), 0, 0, 2); + test(S("abcdefghij"), 5, 2, SV("abcdefghij"), 0, 1, 5); + test(S("abcdefghij"), 5, 2, SV("abcdefghij"), 0, 5, 5); + test(S("abcdefghij"), 5, 2, SV("abcdefghij"), 0, 9, 5); + test(S("abcdefghij"), 5, 2, SV("abcdefghij"), 0, 10, 5); + test(S("abcdefghij"), 5, 2, SV("abcdefghij"), 0, 11, 5); + test(S("abcdefghij"), 5, 2, SV("abcdefghij"), 1, 0, 2); + test(S("abcdefghij"), 5, 2, SV("abcdefghij"), 1, 1, 4); + test(S("abcdefghij"), 5, 2, SV("abcdefghij"), 1, 4, 4); + test(S("abcdefghij"), 5, 2, SV("abcdefghij"), 1, 8, 4); + test(S("abcdefghij"), 5, 2, SV("abcdefghij"), 1, 9, 4); + test(S("abcdefghij"), 5, 2, SV("abcdefghij"), 1, 10, 4); + test(S("abcdefghij"), 5, 2, SV("abcdefghij"), 5, 0, 2); + test(S("abcdefghij"), 5, 2, SV("abcdefghij"), 5, 1, 1); +} + +template +void test30() +{ + test(S("abcdefghij"), 5, 2, SV("abcdefghij"), 5, 2, 0); + test(S("abcdefghij"), 5, 2, SV("abcdefghij"), 5, 4, -2); + test(S("abcdefghij"), 5, 2, SV("abcdefghij"), 5, 5, -3); + test(S("abcdefghij"), 5, 2, SV("abcdefghij"), 5, 6, -3); + test(S("abcdefghij"), 5, 2, SV("abcdefghij"), 9, 0, 2); + test(S("abcdefghij"), 5, 2, SV("abcdefghij"), 9, 1, -4); + test(S("abcdefghij"), 5, 2, SV("abcdefghij"), 9, 2, -4); + test(S("abcdefghij"), 5, 2, SV("abcdefghij"), 10, 0, 2); + test(S("abcdefghij"), 5, 2, SV("abcdefghij"), 10, 1, 2); + test(S("abcdefghij"), 5, 2, SV("abcdefghij"), 11, 0, 0); + test(S("abcdefghij"), 5, 2, SV("abcdefghijklmnopqrst"), 0, 0, 2); + test(S("abcdefghij"), 5, 2, SV("abcdefghijklmnopqrst"), 0, 1, 5); + test(S("abcdefghij"), 5, 2, SV("abcdefghijklmnopqrst"), 0, 10, 5); + test(S("abcdefghij"), 5, 2, SV("abcdefghijklmnopqrst"), 0, 19, 5); + test(S("abcdefghij"), 5, 2, SV("abcdefghijklmnopqrst"), 0, 20, 5); + test(S("abcdefghij"), 5, 2, SV("abcdefghijklmnopqrst"), 0, 21, 5); + test(S("abcdefghij"), 5, 2, SV("abcdefghijklmnopqrst"), 1, 0, 2); + test(S("abcdefghij"), 5, 2, SV("abcdefghijklmnopqrst"), 1, 1, 4); + test(S("abcdefghij"), 5, 2, SV("abcdefghijklmnopqrst"), 1, 9, 4); + test(S("abcdefghij"), 5, 2, SV("abcdefghijklmnopqrst"), 1, 18, 4); + test(S("abcdefghij"), 5, 2, SV("abcdefghijklmnopqrst"), 1, 19, 4); + test(S("abcdefghij"), 5, 2, SV("abcdefghijklmnopqrst"), 1, 20, 4); + test(S("abcdefghij"), 5, 2, SV("abcdefghijklmnopqrst"), 10, 0, 2); + test(S("abcdefghij"), 5, 2, SV("abcdefghijklmnopqrst"), 10, 1, -5); + test(S("abcdefghij"), 5, 2, SV("abcdefghijklmnopqrst"), 10, 5, -5); + test(S("abcdefghij"), 5, 2, SV("abcdefghijklmnopqrst"), 10, 9, -5); + test(S("abcdefghij"), 5, 2, SV("abcdefghijklmnopqrst"), 10, 10, -5); + test(S("abcdefghij"), 5, 2, SV("abcdefghijklmnopqrst"), 10, 11, -5); + test(S("abcdefghij"), 5, 2, SV("abcdefghijklmnopqrst"), 19, 0, 2); + test(S("abcdefghij"), 5, 2, SV("abcdefghijklmnopqrst"), 19, 1, -14); + test(S("abcdefghij"), 5, 2, SV("abcdefghijklmnopqrst"), 19, 2, -14); + test(S("abcdefghij"), 5, 2, SV("abcdefghijklmnopqrst"), 20, 0, 2); + test(S("abcdefghij"), 5, 2, SV("abcdefghijklmnopqrst"), 20, 1, 2); + test(S("abcdefghij"), 5, 2, SV("abcdefghijklmnopqrst"), 21, 0, 0); + test(S("abcdefghij"), 5, 4, SV(""), 0, 0, 4); + test(S("abcdefghij"), 5, 4, SV(""), 0, 1, 4); + test(S("abcdefghij"), 5, 4, SV(""), 1, 0, 0); + test(S("abcdefghij"), 5, 4, SV("abcde"), 0, 0, 4); + test(S("abcdefghij"), 5, 4, SV("abcde"), 0, 1, 5); + test(S("abcdefghij"), 5, 4, SV("abcde"), 0, 2, 5); + test(S("abcdefghij"), 5, 4, SV("abcde"), 0, 4, 5); + test(S("abcdefghij"), 5, 4, SV("abcde"), 0, 5, 5); + test(S("abcdefghij"), 5, 4, SV("abcde"), 0, 6, 5); + test(S("abcdefghij"), 5, 4, SV("abcde"), 1, 0, 4); + test(S("abcdefghij"), 5, 4, SV("abcde"), 1, 1, 4); + test(S("abcdefghij"), 5, 4, SV("abcde"), 1, 2, 4); + test(S("abcdefghij"), 5, 4, SV("abcde"), 1, 3, 4); + test(S("abcdefghij"), 5, 4, SV("abcde"), 1, 4, 4); + test(S("abcdefghij"), 5, 4, SV("abcde"), 1, 5, 4); + test(S("abcdefghij"), 5, 4, SV("abcde"), 2, 0, 4); + test(S("abcdefghij"), 5, 4, SV("abcde"), 2, 1, 3); + test(S("abcdefghij"), 5, 4, SV("abcde"), 2, 2, 3); + test(S("abcdefghij"), 5, 4, SV("abcde"), 2, 3, 3); + test(S("abcdefghij"), 5, 4, SV("abcde"), 2, 4, 3); + test(S("abcdefghij"), 5, 4, SV("abcde"), 4, 0, 4); + test(S("abcdefghij"), 5, 4, SV("abcde"), 4, 1, 1); + test(S("abcdefghij"), 5, 4, SV("abcde"), 4, 2, 1); + test(S("abcdefghij"), 5, 4, SV("abcde"), 5, 0, 4); + test(S("abcdefghij"), 5, 4, SV("abcde"), 5, 1, 4); + test(S("abcdefghij"), 5, 4, SV("abcde"), 6, 0, 0); + test(S("abcdefghij"), 5, 4, SV("abcdefghij"), 0, 0, 4); + test(S("abcdefghij"), 5, 4, SV("abcdefghij"), 0, 1, 5); + test(S("abcdefghij"), 5, 4, SV("abcdefghij"), 0, 5, 5); + test(S("abcdefghij"), 5, 4, SV("abcdefghij"), 0, 9, 5); + test(S("abcdefghij"), 5, 4, SV("abcdefghij"), 0, 10, 5); + test(S("abcdefghij"), 5, 4, SV("abcdefghij"), 0, 11, 5); + test(S("abcdefghij"), 5, 4, SV("abcdefghij"), 1, 0, 4); + test(S("abcdefghij"), 5, 4, SV("abcdefghij"), 1, 1, 4); + test(S("abcdefghij"), 5, 4, SV("abcdefghij"), 1, 4, 4); + test(S("abcdefghij"), 5, 4, SV("abcdefghij"), 1, 8, 4); + test(S("abcdefghij"), 5, 4, SV("abcdefghij"), 1, 9, 4); + test(S("abcdefghij"), 5, 4, SV("abcdefghij"), 1, 10, 4); + test(S("abcdefghij"), 5, 4, SV("abcdefghij"), 5, 0, 4); + test(S("abcdefghij"), 5, 4, SV("abcdefghij"), 5, 1, 3); + test(S("abcdefghij"), 5, 4, SV("abcdefghij"), 5, 2, 2); + test(S("abcdefghij"), 5, 4, SV("abcdefghij"), 5, 4, 0); + test(S("abcdefghij"), 5, 4, SV("abcdefghij"), 5, 5, -1); + test(S("abcdefghij"), 5, 4, SV("abcdefghij"), 5, 6, -1); + test(S("abcdefghij"), 5, 4, SV("abcdefghij"), 9, 0, 4); + test(S("abcdefghij"), 5, 4, SV("abcdefghij"), 9, 1, -4); + test(S("abcdefghij"), 5, 4, SV("abcdefghij"), 9, 2, -4); + test(S("abcdefghij"), 5, 4, SV("abcdefghij"), 10, 0, 4); + test(S("abcdefghij"), 5, 4, SV("abcdefghij"), 10, 1, 4); + test(S("abcdefghij"), 5, 4, SV("abcdefghij"), 11, 0, 0); + test(S("abcdefghij"), 5, 4, SV("abcdefghijklmnopqrst"), 0, 0, 4); + test(S("abcdefghij"), 5, 4, SV("abcdefghijklmnopqrst"), 0, 1, 5); + test(S("abcdefghij"), 5, 4, SV("abcdefghijklmnopqrst"), 0, 10, 5); + test(S("abcdefghij"), 5, 4, SV("abcdefghijklmnopqrst"), 0, 19, 5); + test(S("abcdefghij"), 5, 4, SV("abcdefghijklmnopqrst"), 0, 20, 5); + test(S("abcdefghij"), 5, 4, SV("abcdefghijklmnopqrst"), 0, 21, 5); + test(S("abcdefghij"), 5, 4, SV("abcdefghijklmnopqrst"), 1, 0, 4); + test(S("abcdefghij"), 5, 4, SV("abcdefghijklmnopqrst"), 1, 1, 4); + test(S("abcdefghij"), 5, 4, SV("abcdefghijklmnopqrst"), 1, 9, 4); + test(S("abcdefghij"), 5, 4, SV("abcdefghijklmnopqrst"), 1, 18, 4); + test(S("abcdefghij"), 5, 4, SV("abcdefghijklmnopqrst"), 1, 19, 4); + test(S("abcdefghij"), 5, 4, SV("abcdefghijklmnopqrst"), 1, 20, 4); + test(S("abcdefghij"), 5, 4, SV("abcdefghijklmnopqrst"), 10, 0, 4); + test(S("abcdefghij"), 5, 4, SV("abcdefghijklmnopqrst"), 10, 1, -5); + test(S("abcdefghij"), 5, 4, SV("abcdefghijklmnopqrst"), 10, 5, -5); + test(S("abcdefghij"), 5, 4, SV("abcdefghijklmnopqrst"), 10, 9, -5); +} + +template +void test31() +{ + test(S("abcdefghij"), 5, 4, SV("abcdefghijklmnopqrst"), 10, 10, -5); + test(S("abcdefghij"), 5, 4, SV("abcdefghijklmnopqrst"), 10, 11, -5); + test(S("abcdefghij"), 5, 4, SV("abcdefghijklmnopqrst"), 19, 0, 4); + test(S("abcdefghij"), 5, 4, SV("abcdefghijklmnopqrst"), 19, 1, -14); + test(S("abcdefghij"), 5, 4, SV("abcdefghijklmnopqrst"), 19, 2, -14); + test(S("abcdefghij"), 5, 4, SV("abcdefghijklmnopqrst"), 20, 0, 4); + test(S("abcdefghij"), 5, 4, SV("abcdefghijklmnopqrst"), 20, 1, 4); + test(S("abcdefghij"), 5, 4, SV("abcdefghijklmnopqrst"), 21, 0, 0); + test(S("abcdefghij"), 5, 5, SV(""), 0, 0, 5); + test(S("abcdefghij"), 5, 5, SV(""), 0, 1, 5); + test(S("abcdefghij"), 5, 5, SV(""), 1, 0, 0); + test(S("abcdefghij"), 5, 5, SV("abcde"), 0, 0, 5); + test(S("abcdefghij"), 5, 5, SV("abcde"), 0, 1, 5); + test(S("abcdefghij"), 5, 5, SV("abcde"), 0, 2, 5); + test(S("abcdefghij"), 5, 5, SV("abcde"), 0, 4, 5); + test(S("abcdefghij"), 5, 5, SV("abcde"), 0, 5, 5); + test(S("abcdefghij"), 5, 5, SV("abcde"), 0, 6, 5); + test(S("abcdefghij"), 5, 5, SV("abcde"), 1, 0, 5); + test(S("abcdefghij"), 5, 5, SV("abcde"), 1, 1, 4); + test(S("abcdefghij"), 5, 5, SV("abcde"), 1, 2, 4); + test(S("abcdefghij"), 5, 5, SV("abcde"), 1, 3, 4); + test(S("abcdefghij"), 5, 5, SV("abcde"), 1, 4, 4); + test(S("abcdefghij"), 5, 5, SV("abcde"), 1, 5, 4); + test(S("abcdefghij"), 5, 5, SV("abcde"), 2, 0, 5); + test(S("abcdefghij"), 5, 5, SV("abcde"), 2, 1, 3); + test(S("abcdefghij"), 5, 5, SV("abcde"), 2, 2, 3); + test(S("abcdefghij"), 5, 5, SV("abcde"), 2, 3, 3); + test(S("abcdefghij"), 5, 5, SV("abcde"), 2, 4, 3); + test(S("abcdefghij"), 5, 5, SV("abcde"), 4, 0, 5); + test(S("abcdefghij"), 5, 5, SV("abcde"), 4, 1, 1); + test(S("abcdefghij"), 5, 5, SV("abcde"), 4, 2, 1); + test(S("abcdefghij"), 5, 5, SV("abcde"), 5, 0, 5); + test(S("abcdefghij"), 5, 5, SV("abcde"), 5, 1, 5); + test(S("abcdefghij"), 5, 5, SV("abcde"), 6, 0, 0); + test(S("abcdefghij"), 5, 5, SV("abcdefghij"), 0, 0, 5); + test(S("abcdefghij"), 5, 5, SV("abcdefghij"), 0, 1, 5); + test(S("abcdefghij"), 5, 5, SV("abcdefghij"), 0, 5, 5); + test(S("abcdefghij"), 5, 5, SV("abcdefghij"), 0, 9, 5); + test(S("abcdefghij"), 5, 5, SV("abcdefghij"), 0, 10, 5); + test(S("abcdefghij"), 5, 5, SV("abcdefghij"), 0, 11, 5); + test(S("abcdefghij"), 5, 5, SV("abcdefghij"), 1, 0, 5); + test(S("abcdefghij"), 5, 5, SV("abcdefghij"), 1, 1, 4); + test(S("abcdefghij"), 5, 5, SV("abcdefghij"), 1, 4, 4); + test(S("abcdefghij"), 5, 5, SV("abcdefghij"), 1, 8, 4); + test(S("abcdefghij"), 5, 5, SV("abcdefghij"), 1, 9, 4); + test(S("abcdefghij"), 5, 5, SV("abcdefghij"), 1, 10, 4); + test(S("abcdefghij"), 5, 5, SV("abcdefghij"), 5, 0, 5); + test(S("abcdefghij"), 5, 5, SV("abcdefghij"), 5, 1, 4); + test(S("abcdefghij"), 5, 5, SV("abcdefghij"), 5, 2, 3); + test(S("abcdefghij"), 5, 5, SV("abcdefghij"), 5, 4, 1); + test(S("abcdefghij"), 5, 5, SV("abcdefghij"), 5, 5, 0); + test(S("abcdefghij"), 5, 5, SV("abcdefghij"), 5, 6, 0); + test(S("abcdefghij"), 5, 5, SV("abcdefghij"), 9, 0, 5); + test(S("abcdefghij"), 5, 5, SV("abcdefghij"), 9, 1, -4); + test(S("abcdefghij"), 5, 5, SV("abcdefghij"), 9, 2, -4); + test(S("abcdefghij"), 5, 5, SV("abcdefghij"), 10, 0, 5); + test(S("abcdefghij"), 5, 5, SV("abcdefghij"), 10, 1, 5); + test(S("abcdefghij"), 5, 5, SV("abcdefghij"), 11, 0, 0); + test(S("abcdefghij"), 5, 5, SV("abcdefghijklmnopqrst"), 0, 0, 5); + test(S("abcdefghij"), 5, 5, SV("abcdefghijklmnopqrst"), 0, 1, 5); + test(S("abcdefghij"), 5, 5, SV("abcdefghijklmnopqrst"), 0, 10, 5); + test(S("abcdefghij"), 5, 5, SV("abcdefghijklmnopqrst"), 0, 19, 5); + test(S("abcdefghij"), 5, 5, SV("abcdefghijklmnopqrst"), 0, 20, 5); + test(S("abcdefghij"), 5, 5, SV("abcdefghijklmnopqrst"), 0, 21, 5); + test(S("abcdefghij"), 5, 5, SV("abcdefghijklmnopqrst"), 1, 0, 5); + test(S("abcdefghij"), 5, 5, SV("abcdefghijklmnopqrst"), 1, 1, 4); + test(S("abcdefghij"), 5, 5, SV("abcdefghijklmnopqrst"), 1, 9, 4); + test(S("abcdefghij"), 5, 5, SV("abcdefghijklmnopqrst"), 1, 18, 4); + test(S("abcdefghij"), 5, 5, SV("abcdefghijklmnopqrst"), 1, 19, 4); + test(S("abcdefghij"), 5, 5, SV("abcdefghijklmnopqrst"), 1, 20, 4); + test(S("abcdefghij"), 5, 5, SV("abcdefghijklmnopqrst"), 10, 0, 5); + test(S("abcdefghij"), 5, 5, SV("abcdefghijklmnopqrst"), 10, 1, -5); + test(S("abcdefghij"), 5, 5, SV("abcdefghijklmnopqrst"), 10, 5, -5); + test(S("abcdefghij"), 5, 5, SV("abcdefghijklmnopqrst"), 10, 9, -5); + test(S("abcdefghij"), 5, 5, SV("abcdefghijklmnopqrst"), 10, 10, -5); + test(S("abcdefghij"), 5, 5, SV("abcdefghijklmnopqrst"), 10, 11, -5); + test(S("abcdefghij"), 5, 5, SV("abcdefghijklmnopqrst"), 19, 0, 5); + test(S("abcdefghij"), 5, 5, SV("abcdefghijklmnopqrst"), 19, 1, -14); + test(S("abcdefghij"), 5, 5, SV("abcdefghijklmnopqrst"), 19, 2, -14); + test(S("abcdefghij"), 5, 5, SV("abcdefghijklmnopqrst"), 20, 0, 5); + test(S("abcdefghij"), 5, 5, SV("abcdefghijklmnopqrst"), 20, 1, 5); + test(S("abcdefghij"), 5, 5, SV("abcdefghijklmnopqrst"), 21, 0, 0); + test(S("abcdefghij"), 5, 6, SV(""), 0, 0, 5); + test(S("abcdefghij"), 5, 6, SV(""), 0, 1, 5); + test(S("abcdefghij"), 5, 6, SV(""), 1, 0, 0); + test(S("abcdefghij"), 5, 6, SV("abcde"), 0, 0, 5); + test(S("abcdefghij"), 5, 6, SV("abcde"), 0, 1, 5); + test(S("abcdefghij"), 5, 6, SV("abcde"), 0, 2, 5); + test(S("abcdefghij"), 5, 6, SV("abcde"), 0, 4, 5); + test(S("abcdefghij"), 5, 6, SV("abcde"), 0, 5, 5); + test(S("abcdefghij"), 5, 6, SV("abcde"), 0, 6, 5); + test(S("abcdefghij"), 5, 6, SV("abcde"), 1, 0, 5); + test(S("abcdefghij"), 5, 6, SV("abcde"), 1, 1, 4); + test(S("abcdefghij"), 5, 6, SV("abcde"), 1, 2, 4); + test(S("abcdefghij"), 5, 6, SV("abcde"), 1, 3, 4); + test(S("abcdefghij"), 5, 6, SV("abcde"), 1, 4, 4); + test(S("abcdefghij"), 5, 6, SV("abcde"), 1, 5, 4); + test(S("abcdefghij"), 5, 6, SV("abcde"), 2, 0, 5); + test(S("abcdefghij"), 5, 6, SV("abcde"), 2, 1, 3); + test(S("abcdefghij"), 5, 6, SV("abcde"), 2, 2, 3); +} + +template +void test32() +{ + test(S("abcdefghij"), 5, 6, SV("abcde"), 2, 3, 3); + test(S("abcdefghij"), 5, 6, SV("abcde"), 2, 4, 3); + test(S("abcdefghij"), 5, 6, SV("abcde"), 4, 0, 5); + test(S("abcdefghij"), 5, 6, SV("abcde"), 4, 1, 1); + test(S("abcdefghij"), 5, 6, SV("abcde"), 4, 2, 1); + test(S("abcdefghij"), 5, 6, SV("abcde"), 5, 0, 5); + test(S("abcdefghij"), 5, 6, SV("abcde"), 5, 1, 5); + test(S("abcdefghij"), 5, 6, SV("abcde"), 6, 0, 0); + test(S("abcdefghij"), 5, 6, SV("abcdefghij"), 0, 0, 5); + test(S("abcdefghij"), 5, 6, SV("abcdefghij"), 0, 1, 5); + test(S("abcdefghij"), 5, 6, SV("abcdefghij"), 0, 5, 5); + test(S("abcdefghij"), 5, 6, SV("abcdefghij"), 0, 9, 5); + test(S("abcdefghij"), 5, 6, SV("abcdefghij"), 0, 10, 5); + test(S("abcdefghij"), 5, 6, SV("abcdefghij"), 0, 11, 5); + test(S("abcdefghij"), 5, 6, SV("abcdefghij"), 1, 0, 5); + test(S("abcdefghij"), 5, 6, SV("abcdefghij"), 1, 1, 4); + test(S("abcdefghij"), 5, 6, SV("abcdefghij"), 1, 4, 4); + test(S("abcdefghij"), 5, 6, SV("abcdefghij"), 1, 8, 4); + test(S("abcdefghij"), 5, 6, SV("abcdefghij"), 1, 9, 4); + test(S("abcdefghij"), 5, 6, SV("abcdefghij"), 1, 10, 4); + test(S("abcdefghij"), 5, 6, SV("abcdefghij"), 5, 0, 5); + test(S("abcdefghij"), 5, 6, SV("abcdefghij"), 5, 1, 4); + test(S("abcdefghij"), 5, 6, SV("abcdefghij"), 5, 2, 3); + test(S("abcdefghij"), 5, 6, SV("abcdefghij"), 5, 4, 1); + test(S("abcdefghij"), 5, 6, SV("abcdefghij"), 5, 5, 0); + test(S("abcdefghij"), 5, 6, SV("abcdefghij"), 5, 6, 0); + test(S("abcdefghij"), 5, 6, SV("abcdefghij"), 9, 0, 5); + test(S("abcdefghij"), 5, 6, SV("abcdefghij"), 9, 1, -4); + test(S("abcdefghij"), 5, 6, SV("abcdefghij"), 9, 2, -4); + test(S("abcdefghij"), 5, 6, SV("abcdefghij"), 10, 0, 5); + test(S("abcdefghij"), 5, 6, SV("abcdefghij"), 10, 1, 5); + test(S("abcdefghij"), 5, 6, SV("abcdefghij"), 11, 0, 0); + test(S("abcdefghij"), 5, 6, SV("abcdefghijklmnopqrst"), 0, 0, 5); + test(S("abcdefghij"), 5, 6, SV("abcdefghijklmnopqrst"), 0, 1, 5); + test(S("abcdefghij"), 5, 6, SV("abcdefghijklmnopqrst"), 0, 10, 5); + test(S("abcdefghij"), 5, 6, SV("abcdefghijklmnopqrst"), 0, 19, 5); + test(S("abcdefghij"), 5, 6, SV("abcdefghijklmnopqrst"), 0, 20, 5); + test(S("abcdefghij"), 5, 6, SV("abcdefghijklmnopqrst"), 0, 21, 5); + test(S("abcdefghij"), 5, 6, SV("abcdefghijklmnopqrst"), 1, 0, 5); + test(S("abcdefghij"), 5, 6, SV("abcdefghijklmnopqrst"), 1, 1, 4); + test(S("abcdefghij"), 5, 6, SV("abcdefghijklmnopqrst"), 1, 9, 4); + test(S("abcdefghij"), 5, 6, SV("abcdefghijklmnopqrst"), 1, 18, 4); + test(S("abcdefghij"), 5, 6, SV("abcdefghijklmnopqrst"), 1, 19, 4); + test(S("abcdefghij"), 5, 6, SV("abcdefghijklmnopqrst"), 1, 20, 4); + test(S("abcdefghij"), 5, 6, SV("abcdefghijklmnopqrst"), 10, 0, 5); + test(S("abcdefghij"), 5, 6, SV("abcdefghijklmnopqrst"), 10, 1, -5); + test(S("abcdefghij"), 5, 6, SV("abcdefghijklmnopqrst"), 10, 5, -5); + test(S("abcdefghij"), 5, 6, SV("abcdefghijklmnopqrst"), 10, 9, -5); + test(S("abcdefghij"), 5, 6, SV("abcdefghijklmnopqrst"), 10, 10, -5); + test(S("abcdefghij"), 5, 6, SV("abcdefghijklmnopqrst"), 10, 11, -5); + test(S("abcdefghij"), 5, 6, SV("abcdefghijklmnopqrst"), 19, 0, 5); + test(S("abcdefghij"), 5, 6, SV("abcdefghijklmnopqrst"), 19, 1, -14); + test(S("abcdefghij"), 5, 6, SV("abcdefghijklmnopqrst"), 19, 2, -14); + test(S("abcdefghij"), 5, 6, SV("abcdefghijklmnopqrst"), 20, 0, 5); + test(S("abcdefghij"), 5, 6, SV("abcdefghijklmnopqrst"), 20, 1, 5); + test(S("abcdefghij"), 5, 6, SV("abcdefghijklmnopqrst"), 21, 0, 0); + test(S("abcdefghij"), 9, 0, SV(""), 0, 0, 0); + test(S("abcdefghij"), 9, 0, SV(""), 0, 1, 0); + test(S("abcdefghij"), 9, 0, SV(""), 1, 0, 0); + test(S("abcdefghij"), 9, 0, SV("abcde"), 0, 0, 0); + test(S("abcdefghij"), 9, 0, SV("abcde"), 0, 1, -1); + test(S("abcdefghij"), 9, 0, SV("abcde"), 0, 2, -2); + test(S("abcdefghij"), 9, 0, SV("abcde"), 0, 4, -4); + test(S("abcdefghij"), 9, 0, SV("abcde"), 0, 5, -5); + test(S("abcdefghij"), 9, 0, SV("abcde"), 0, 6, -5); + test(S("abcdefghij"), 9, 0, SV("abcde"), 1, 0, 0); + test(S("abcdefghij"), 9, 0, SV("abcde"), 1, 1, -1); + test(S("abcdefghij"), 9, 0, SV("abcde"), 1, 2, -2); + test(S("abcdefghij"), 9, 0, SV("abcde"), 1, 3, -3); + test(S("abcdefghij"), 9, 0, SV("abcde"), 1, 4, -4); + test(S("abcdefghij"), 9, 0, SV("abcde"), 1, 5, -4); + test(S("abcdefghij"), 9, 0, SV("abcde"), 2, 0, 0); + test(S("abcdefghij"), 9, 0, SV("abcde"), 2, 1, -1); + test(S("abcdefghij"), 9, 0, SV("abcde"), 2, 2, -2); + test(S("abcdefghij"), 9, 0, SV("abcde"), 2, 3, -3); + test(S("abcdefghij"), 9, 0, SV("abcde"), 2, 4, -3); + test(S("abcdefghij"), 9, 0, SV("abcde"), 4, 0, 0); + test(S("abcdefghij"), 9, 0, SV("abcde"), 4, 1, -1); + test(S("abcdefghij"), 9, 0, SV("abcde"), 4, 2, -1); + test(S("abcdefghij"), 9, 0, SV("abcde"), 5, 0, 0); + test(S("abcdefghij"), 9, 0, SV("abcde"), 5, 1, 0); + test(S("abcdefghij"), 9, 0, SV("abcde"), 6, 0, 0); + test(S("abcdefghij"), 9, 0, SV("abcdefghij"), 0, 0, 0); + test(S("abcdefghij"), 9, 0, SV("abcdefghij"), 0, 1, -1); + test(S("abcdefghij"), 9, 0, SV("abcdefghij"), 0, 5, -5); + test(S("abcdefghij"), 9, 0, SV("abcdefghij"), 0, 9, -9); + test(S("abcdefghij"), 9, 0, SV("abcdefghij"), 0, 10, -10); + test(S("abcdefghij"), 9, 0, SV("abcdefghij"), 0, 11, -10); + test(S("abcdefghij"), 9, 0, SV("abcdefghij"), 1, 0, 0); + test(S("abcdefghij"), 9, 0, SV("abcdefghij"), 1, 1, -1); + test(S("abcdefghij"), 9, 0, SV("abcdefghij"), 1, 4, -4); + test(S("abcdefghij"), 9, 0, SV("abcdefghij"), 1, 8, -8); + test(S("abcdefghij"), 9, 0, SV("abcdefghij"), 1, 9, -9); + test(S("abcdefghij"), 9, 0, SV("abcdefghij"), 1, 10, -9); + test(S("abcdefghij"), 9, 0, SV("abcdefghij"), 5, 0, 0); + test(S("abcdefghij"), 9, 0, SV("abcdefghij"), 5, 1, -1); + test(S("abcdefghij"), 9, 0, SV("abcdefghij"), 5, 2, -2); + test(S("abcdefghij"), 9, 0, SV("abcdefghij"), 5, 4, -4); + test(S("abcdefghij"), 9, 0, SV("abcdefghij"), 5, 5, -5); + test(S("abcdefghij"), 9, 0, SV("abcdefghij"), 5, 6, -5); +} + +template +void test33() +{ + test(S("abcdefghij"), 9, 0, SV("abcdefghij"), 9, 0, 0); + test(S("abcdefghij"), 9, 0, SV("abcdefghij"), 9, 1, -1); + test(S("abcdefghij"), 9, 0, SV("abcdefghij"), 9, 2, -1); + test(S("abcdefghij"), 9, 0, SV("abcdefghij"), 10, 0, 0); + test(S("abcdefghij"), 9, 0, SV("abcdefghij"), 10, 1, 0); + test(S("abcdefghij"), 9, 0, SV("abcdefghij"), 11, 0, 0); + test(S("abcdefghij"), 9, 0, SV("abcdefghijklmnopqrst"), 0, 0, 0); + test(S("abcdefghij"), 9, 0, SV("abcdefghijklmnopqrst"), 0, 1, -1); + test(S("abcdefghij"), 9, 0, SV("abcdefghijklmnopqrst"), 0, 10, -10); + test(S("abcdefghij"), 9, 0, SV("abcdefghijklmnopqrst"), 0, 19, -19); + test(S("abcdefghij"), 9, 0, SV("abcdefghijklmnopqrst"), 0, 20, -20); + test(S("abcdefghij"), 9, 0, SV("abcdefghijklmnopqrst"), 0, 21, -20); + test(S("abcdefghij"), 9, 0, SV("abcdefghijklmnopqrst"), 1, 0, 0); + test(S("abcdefghij"), 9, 0, SV("abcdefghijklmnopqrst"), 1, 1, -1); + test(S("abcdefghij"), 9, 0, SV("abcdefghijklmnopqrst"), 1, 9, -9); + test(S("abcdefghij"), 9, 0, SV("abcdefghijklmnopqrst"), 1, 18, -18); + test(S("abcdefghij"), 9, 0, SV("abcdefghijklmnopqrst"), 1, 19, -19); + test(S("abcdefghij"), 9, 0, SV("abcdefghijklmnopqrst"), 1, 20, -19); + test(S("abcdefghij"), 9, 0, SV("abcdefghijklmnopqrst"), 10, 0, 0); + test(S("abcdefghij"), 9, 0, SV("abcdefghijklmnopqrst"), 10, 1, -1); + test(S("abcdefghij"), 9, 0, SV("abcdefghijklmnopqrst"), 10, 5, -5); + test(S("abcdefghij"), 9, 0, SV("abcdefghijklmnopqrst"), 10, 9, -9); + test(S("abcdefghij"), 9, 0, SV("abcdefghijklmnopqrst"), 10, 10, -10); + test(S("abcdefghij"), 9, 0, SV("abcdefghijklmnopqrst"), 10, 11, -10); + test(S("abcdefghij"), 9, 0, SV("abcdefghijklmnopqrst"), 19, 0, 0); + test(S("abcdefghij"), 9, 0, SV("abcdefghijklmnopqrst"), 19, 1, -1); + test(S("abcdefghij"), 9, 0, SV("abcdefghijklmnopqrst"), 19, 2, -1); + test(S("abcdefghij"), 9, 0, SV("abcdefghijklmnopqrst"), 20, 0, 0); + test(S("abcdefghij"), 9, 0, SV("abcdefghijklmnopqrst"), 20, 1, 0); + test(S("abcdefghij"), 9, 0, SV("abcdefghijklmnopqrst"), 21, 0, 0); + test(S("abcdefghij"), 9, 1, SV(""), 0, 0, 1); + test(S("abcdefghij"), 9, 1, SV(""), 0, 1, 1); + test(S("abcdefghij"), 9, 1, SV(""), 1, 0, 0); + test(S("abcdefghij"), 9, 1, SV("abcde"), 0, 0, 1); + test(S("abcdefghij"), 9, 1, SV("abcde"), 0, 1, 9); + test(S("abcdefghij"), 9, 1, SV("abcde"), 0, 2, 9); + test(S("abcdefghij"), 9, 1, SV("abcde"), 0, 4, 9); + test(S("abcdefghij"), 9, 1, SV("abcde"), 0, 5, 9); + test(S("abcdefghij"), 9, 1, SV("abcde"), 0, 6, 9); + test(S("abcdefghij"), 9, 1, SV("abcde"), 1, 0, 1); + test(S("abcdefghij"), 9, 1, SV("abcde"), 1, 1, 8); + test(S("abcdefghij"), 9, 1, SV("abcde"), 1, 2, 8); + test(S("abcdefghij"), 9, 1, SV("abcde"), 1, 3, 8); + test(S("abcdefghij"), 9, 1, SV("abcde"), 1, 4, 8); + test(S("abcdefghij"), 9, 1, SV("abcde"), 1, 5, 8); + test(S("abcdefghij"), 9, 1, SV("abcde"), 2, 0, 1); + test(S("abcdefghij"), 9, 1, SV("abcde"), 2, 1, 7); + test(S("abcdefghij"), 9, 1, SV("abcde"), 2, 2, 7); + test(S("abcdefghij"), 9, 1, SV("abcde"), 2, 3, 7); + test(S("abcdefghij"), 9, 1, SV("abcde"), 2, 4, 7); + test(S("abcdefghij"), 9, 1, SV("abcde"), 4, 0, 1); + test(S("abcdefghij"), 9, 1, SV("abcde"), 4, 1, 5); + test(S("abcdefghij"), 9, 1, SV("abcde"), 4, 2, 5); + test(S("abcdefghij"), 9, 1, SV("abcde"), 5, 0, 1); + test(S("abcdefghij"), 9, 1, SV("abcde"), 5, 1, 1); + test(S("abcdefghij"), 9, 1, SV("abcde"), 6, 0, 0); + test(S("abcdefghij"), 9, 1, SV("abcdefghij"), 0, 0, 1); + test(S("abcdefghij"), 9, 1, SV("abcdefghij"), 0, 1, 9); + test(S("abcdefghij"), 9, 1, SV("abcdefghij"), 0, 5, 9); + test(S("abcdefghij"), 9, 1, SV("abcdefghij"), 0, 9, 9); + test(S("abcdefghij"), 9, 1, SV("abcdefghij"), 0, 10, 9); + test(S("abcdefghij"), 9, 1, SV("abcdefghij"), 0, 11, 9); + test(S("abcdefghij"), 9, 1, SV("abcdefghij"), 1, 0, 1); + test(S("abcdefghij"), 9, 1, SV("abcdefghij"), 1, 1, 8); + test(S("abcdefghij"), 9, 1, SV("abcdefghij"), 1, 4, 8); + test(S("abcdefghij"), 9, 1, SV("abcdefghij"), 1, 8, 8); + test(S("abcdefghij"), 9, 1, SV("abcdefghij"), 1, 9, 8); + test(S("abcdefghij"), 9, 1, SV("abcdefghij"), 1, 10, 8); + test(S("abcdefghij"), 9, 1, SV("abcdefghij"), 5, 0, 1); + test(S("abcdefghij"), 9, 1, SV("abcdefghij"), 5, 1, 4); + test(S("abcdefghij"), 9, 1, SV("abcdefghij"), 5, 2, 4); + test(S("abcdefghij"), 9, 1, SV("abcdefghij"), 5, 4, 4); + test(S("abcdefghij"), 9, 1, SV("abcdefghij"), 5, 5, 4); + test(S("abcdefghij"), 9, 1, SV("abcdefghij"), 5, 6, 4); + test(S("abcdefghij"), 9, 1, SV("abcdefghij"), 9, 0, 1); + test(S("abcdefghij"), 9, 1, SV("abcdefghij"), 9, 1, 0); + test(S("abcdefghij"), 9, 1, SV("abcdefghij"), 9, 2, 0); + test(S("abcdefghij"), 9, 1, SV("abcdefghij"), 10, 0, 1); + test(S("abcdefghij"), 9, 1, SV("abcdefghij"), 10, 1, 1); + test(S("abcdefghij"), 9, 1, SV("abcdefghij"), 11, 0, 0); + test(S("abcdefghij"), 9, 1, SV("abcdefghijklmnopqrst"), 0, 0, 1); + test(S("abcdefghij"), 9, 1, SV("abcdefghijklmnopqrst"), 0, 1, 9); + test(S("abcdefghij"), 9, 1, SV("abcdefghijklmnopqrst"), 0, 10, 9); + test(S("abcdefghij"), 9, 1, SV("abcdefghijklmnopqrst"), 0, 19, 9); + test(S("abcdefghij"), 9, 1, SV("abcdefghijklmnopqrst"), 0, 20, 9); + test(S("abcdefghij"), 9, 1, SV("abcdefghijklmnopqrst"), 0, 21, 9); + test(S("abcdefghij"), 9, 1, SV("abcdefghijklmnopqrst"), 1, 0, 1); + test(S("abcdefghij"), 9, 1, SV("abcdefghijklmnopqrst"), 1, 1, 8); + test(S("abcdefghij"), 9, 1, SV("abcdefghijklmnopqrst"), 1, 9, 8); + test(S("abcdefghij"), 9, 1, SV("abcdefghijklmnopqrst"), 1, 18, 8); + test(S("abcdefghij"), 9, 1, SV("abcdefghijklmnopqrst"), 1, 19, 8); + test(S("abcdefghij"), 9, 1, SV("abcdefghijklmnopqrst"), 1, 20, 8); + test(S("abcdefghij"), 9, 1, SV("abcdefghijklmnopqrst"), 10, 0, 1); + test(S("abcdefghij"), 9, 1, SV("abcdefghijklmnopqrst"), 10, 1, -1); + test(S("abcdefghij"), 9, 1, SV("abcdefghijklmnopqrst"), 10, 5, -1); + test(S("abcdefghij"), 9, 1, SV("abcdefghijklmnopqrst"), 10, 9, -1); + test(S("abcdefghij"), 9, 1, SV("abcdefghijklmnopqrst"), 10, 10, -1); + test(S("abcdefghij"), 9, 1, SV("abcdefghijklmnopqrst"), 10, 11, -1); + test(S("abcdefghij"), 9, 1, SV("abcdefghijklmnopqrst"), 19, 0, 1); + test(S("abcdefghij"), 9, 1, SV("abcdefghijklmnopqrst"), 19, 1, -10); +} + +template +void test34() +{ + test(S("abcdefghij"), 9, 1, SV("abcdefghijklmnopqrst"), 19, 2, -10); + test(S("abcdefghij"), 9, 1, SV("abcdefghijklmnopqrst"), 20, 0, 1); + test(S("abcdefghij"), 9, 1, SV("abcdefghijklmnopqrst"), 20, 1, 1); + test(S("abcdefghij"), 9, 1, SV("abcdefghijklmnopqrst"), 21, 0, 0); + test(S("abcdefghij"), 9, 2, SV(""), 0, 0, 1); + test(S("abcdefghij"), 9, 2, SV(""), 0, 1, 1); + test(S("abcdefghij"), 9, 2, SV(""), 1, 0, 0); + test(S("abcdefghij"), 9, 2, SV("abcde"), 0, 0, 1); + test(S("abcdefghij"), 9, 2, SV("abcde"), 0, 1, 9); + test(S("abcdefghij"), 9, 2, SV("abcde"), 0, 2, 9); + test(S("abcdefghij"), 9, 2, SV("abcde"), 0, 4, 9); + test(S("abcdefghij"), 9, 2, SV("abcde"), 0, 5, 9); + test(S("abcdefghij"), 9, 2, SV("abcde"), 0, 6, 9); + test(S("abcdefghij"), 9, 2, SV("abcde"), 1, 0, 1); + test(S("abcdefghij"), 9, 2, SV("abcde"), 1, 1, 8); + test(S("abcdefghij"), 9, 2, SV("abcde"), 1, 2, 8); + test(S("abcdefghij"), 9, 2, SV("abcde"), 1, 3, 8); + test(S("abcdefghij"), 9, 2, SV("abcde"), 1, 4, 8); + test(S("abcdefghij"), 9, 2, SV("abcde"), 1, 5, 8); + test(S("abcdefghij"), 9, 2, SV("abcde"), 2, 0, 1); + test(S("abcdefghij"), 9, 2, SV("abcde"), 2, 1, 7); + test(S("abcdefghij"), 9, 2, SV("abcde"), 2, 2, 7); + test(S("abcdefghij"), 9, 2, SV("abcde"), 2, 3, 7); + test(S("abcdefghij"), 9, 2, SV("abcde"), 2, 4, 7); + test(S("abcdefghij"), 9, 2, SV("abcde"), 4, 0, 1); + test(S("abcdefghij"), 9, 2, SV("abcde"), 4, 1, 5); + test(S("abcdefghij"), 9, 2, SV("abcde"), 4, 2, 5); + test(S("abcdefghij"), 9, 2, SV("abcde"), 5, 0, 1); + test(S("abcdefghij"), 9, 2, SV("abcde"), 5, 1, 1); + test(S("abcdefghij"), 9, 2, SV("abcde"), 6, 0, 0); + test(S("abcdefghij"), 9, 2, SV("abcdefghij"), 0, 0, 1); + test(S("abcdefghij"), 9, 2, SV("abcdefghij"), 0, 1, 9); + test(S("abcdefghij"), 9, 2, SV("abcdefghij"), 0, 5, 9); + test(S("abcdefghij"), 9, 2, SV("abcdefghij"), 0, 9, 9); + test(S("abcdefghij"), 9, 2, SV("abcdefghij"), 0, 10, 9); + test(S("abcdefghij"), 9, 2, SV("abcdefghij"), 0, 11, 9); + test(S("abcdefghij"), 9, 2, SV("abcdefghij"), 1, 0, 1); + test(S("abcdefghij"), 9, 2, SV("abcdefghij"), 1, 1, 8); + test(S("abcdefghij"), 9, 2, SV("abcdefghij"), 1, 4, 8); + test(S("abcdefghij"), 9, 2, SV("abcdefghij"), 1, 8, 8); + test(S("abcdefghij"), 9, 2, SV("abcdefghij"), 1, 9, 8); + test(S("abcdefghij"), 9, 2, SV("abcdefghij"), 1, 10, 8); + test(S("abcdefghij"), 9, 2, SV("abcdefghij"), 5, 0, 1); + test(S("abcdefghij"), 9, 2, SV("abcdefghij"), 5, 1, 4); + test(S("abcdefghij"), 9, 2, SV("abcdefghij"), 5, 2, 4); + test(S("abcdefghij"), 9, 2, SV("abcdefghij"), 5, 4, 4); + test(S("abcdefghij"), 9, 2, SV("abcdefghij"), 5, 5, 4); + test(S("abcdefghij"), 9, 2, SV("abcdefghij"), 5, 6, 4); + test(S("abcdefghij"), 9, 2, SV("abcdefghij"), 9, 0, 1); + test(S("abcdefghij"), 9, 2, SV("abcdefghij"), 9, 1, 0); + test(S("abcdefghij"), 9, 2, SV("abcdefghij"), 9, 2, 0); + test(S("abcdefghij"), 9, 2, SV("abcdefghij"), 10, 0, 1); + test(S("abcdefghij"), 9, 2, SV("abcdefghij"), 10, 1, 1); + test(S("abcdefghij"), 9, 2, SV("abcdefghij"), 11, 0, 0); + test(S("abcdefghij"), 9, 2, SV("abcdefghijklmnopqrst"), 0, 0, 1); + test(S("abcdefghij"), 9, 2, SV("abcdefghijklmnopqrst"), 0, 1, 9); + test(S("abcdefghij"), 9, 2, SV("abcdefghijklmnopqrst"), 0, 10, 9); + test(S("abcdefghij"), 9, 2, SV("abcdefghijklmnopqrst"), 0, 19, 9); + test(S("abcdefghij"), 9, 2, SV("abcdefghijklmnopqrst"), 0, 20, 9); + test(S("abcdefghij"), 9, 2, SV("abcdefghijklmnopqrst"), 0, 21, 9); + test(S("abcdefghij"), 9, 2, SV("abcdefghijklmnopqrst"), 1, 0, 1); + test(S("abcdefghij"), 9, 2, SV("abcdefghijklmnopqrst"), 1, 1, 8); + test(S("abcdefghij"), 9, 2, SV("abcdefghijklmnopqrst"), 1, 9, 8); + test(S("abcdefghij"), 9, 2, SV("abcdefghijklmnopqrst"), 1, 18, 8); + test(S("abcdefghij"), 9, 2, SV("abcdefghijklmnopqrst"), 1, 19, 8); + test(S("abcdefghij"), 9, 2, SV("abcdefghijklmnopqrst"), 1, 20, 8); + test(S("abcdefghij"), 9, 2, SV("abcdefghijklmnopqrst"), 10, 0, 1); + test(S("abcdefghij"), 9, 2, SV("abcdefghijklmnopqrst"), 10, 1, -1); + test(S("abcdefghij"), 9, 2, SV("abcdefghijklmnopqrst"), 10, 5, -1); + test(S("abcdefghij"), 9, 2, SV("abcdefghijklmnopqrst"), 10, 9, -1); + test(S("abcdefghij"), 9, 2, SV("abcdefghijklmnopqrst"), 10, 10, -1); + test(S("abcdefghij"), 9, 2, SV("abcdefghijklmnopqrst"), 10, 11, -1); + test(S("abcdefghij"), 9, 2, SV("abcdefghijklmnopqrst"), 19, 0, 1); + test(S("abcdefghij"), 9, 2, SV("abcdefghijklmnopqrst"), 19, 1, -10); + test(S("abcdefghij"), 9, 2, SV("abcdefghijklmnopqrst"), 19, 2, -10); + test(S("abcdefghij"), 9, 2, SV("abcdefghijklmnopqrst"), 20, 0, 1); + test(S("abcdefghij"), 9, 2, SV("abcdefghijklmnopqrst"), 20, 1, 1); + test(S("abcdefghij"), 9, 2, SV("abcdefghijklmnopqrst"), 21, 0, 0); + test(S("abcdefghij"), 10, 0, SV(""), 0, 0, 0); + test(S("abcdefghij"), 10, 0, SV(""), 0, 1, 0); + test(S("abcdefghij"), 10, 0, SV(""), 1, 0, 0); + test(S("abcdefghij"), 10, 0, SV("abcde"), 0, 0, 0); + test(S("abcdefghij"), 10, 0, SV("abcde"), 0, 1, -1); + test(S("abcdefghij"), 10, 0, SV("abcde"), 0, 2, -2); + test(S("abcdefghij"), 10, 0, SV("abcde"), 0, 4, -4); + test(S("abcdefghij"), 10, 0, SV("abcde"), 0, 5, -5); + test(S("abcdefghij"), 10, 0, SV("abcde"), 0, 6, -5); + test(S("abcdefghij"), 10, 0, SV("abcde"), 1, 0, 0); + test(S("abcdefghij"), 10, 0, SV("abcde"), 1, 1, -1); + test(S("abcdefghij"), 10, 0, SV("abcde"), 1, 2, -2); + test(S("abcdefghij"), 10, 0, SV("abcde"), 1, 3, -3); + test(S("abcdefghij"), 10, 0, SV("abcde"), 1, 4, -4); + test(S("abcdefghij"), 10, 0, SV("abcde"), 1, 5, -4); + test(S("abcdefghij"), 10, 0, SV("abcde"), 2, 0, 0); + test(S("abcdefghij"), 10, 0, SV("abcde"), 2, 1, -1); + test(S("abcdefghij"), 10, 0, SV("abcde"), 2, 2, -2); + test(S("abcdefghij"), 10, 0, SV("abcde"), 2, 3, -3); + test(S("abcdefghij"), 10, 0, SV("abcde"), 2, 4, -3); + test(S("abcdefghij"), 10, 0, SV("abcde"), 4, 0, 0); + test(S("abcdefghij"), 10, 0, SV("abcde"), 4, 1, -1); +} + +template +void test35() +{ + test(S("abcdefghij"), 10, 0, SV("abcde"), 4, 2, -1); + test(S("abcdefghij"), 10, 0, SV("abcde"), 5, 0, 0); + test(S("abcdefghij"), 10, 0, SV("abcde"), 5, 1, 0); + test(S("abcdefghij"), 10, 0, SV("abcde"), 6, 0, 0); + test(S("abcdefghij"), 10, 0, SV("abcdefghij"), 0, 0, 0); + test(S("abcdefghij"), 10, 0, SV("abcdefghij"), 0, 1, -1); + test(S("abcdefghij"), 10, 0, SV("abcdefghij"), 0, 5, -5); + test(S("abcdefghij"), 10, 0, SV("abcdefghij"), 0, 9, -9); + test(S("abcdefghij"), 10, 0, SV("abcdefghij"), 0, 10, -10); + test(S("abcdefghij"), 10, 0, SV("abcdefghij"), 0, 11, -10); + test(S("abcdefghij"), 10, 0, SV("abcdefghij"), 1, 0, 0); + test(S("abcdefghij"), 10, 0, SV("abcdefghij"), 1, 1, -1); + test(S("abcdefghij"), 10, 0, SV("abcdefghij"), 1, 4, -4); + test(S("abcdefghij"), 10, 0, SV("abcdefghij"), 1, 8, -8); + test(S("abcdefghij"), 10, 0, SV("abcdefghij"), 1, 9, -9); + test(S("abcdefghij"), 10, 0, SV("abcdefghij"), 1, 10, -9); + test(S("abcdefghij"), 10, 0, SV("abcdefghij"), 5, 0, 0); + test(S("abcdefghij"), 10, 0, SV("abcdefghij"), 5, 1, -1); + test(S("abcdefghij"), 10, 0, SV("abcdefghij"), 5, 2, -2); + test(S("abcdefghij"), 10, 0, SV("abcdefghij"), 5, 4, -4); + test(S("abcdefghij"), 10, 0, SV("abcdefghij"), 5, 5, -5); + test(S("abcdefghij"), 10, 0, SV("abcdefghij"), 5, 6, -5); + test(S("abcdefghij"), 10, 0, SV("abcdefghij"), 9, 0, 0); + test(S("abcdefghij"), 10, 0, SV("abcdefghij"), 9, 1, -1); + test(S("abcdefghij"), 10, 0, SV("abcdefghij"), 9, 2, -1); + test(S("abcdefghij"), 10, 0, SV("abcdefghij"), 10, 0, 0); + test(S("abcdefghij"), 10, 0, SV("abcdefghij"), 10, 1, 0); + test(S("abcdefghij"), 10, 0, SV("abcdefghij"), 11, 0, 0); + test(S("abcdefghij"), 10, 0, SV("abcdefghijklmnopqrst"), 0, 0, 0); + test(S("abcdefghij"), 10, 0, SV("abcdefghijklmnopqrst"), 0, 1, -1); + test(S("abcdefghij"), 10, 0, SV("abcdefghijklmnopqrst"), 0, 10, -10); + test(S("abcdefghij"), 10, 0, SV("abcdefghijklmnopqrst"), 0, 19, -19); + test(S("abcdefghij"), 10, 0, SV("abcdefghijklmnopqrst"), 0, 20, -20); + test(S("abcdefghij"), 10, 0, SV("abcdefghijklmnopqrst"), 0, 21, -20); + test(S("abcdefghij"), 10, 0, SV("abcdefghijklmnopqrst"), 1, 0, 0); + test(S("abcdefghij"), 10, 0, SV("abcdefghijklmnopqrst"), 1, 1, -1); + test(S("abcdefghij"), 10, 0, SV("abcdefghijklmnopqrst"), 1, 9, -9); + test(S("abcdefghij"), 10, 0, SV("abcdefghijklmnopqrst"), 1, 18, -18); + test(S("abcdefghij"), 10, 0, SV("abcdefghijklmnopqrst"), 1, 19, -19); + test(S("abcdefghij"), 10, 0, SV("abcdefghijklmnopqrst"), 1, 20, -19); + test(S("abcdefghij"), 10, 0, SV("abcdefghijklmnopqrst"), 10, 0, 0); + test(S("abcdefghij"), 10, 0, SV("abcdefghijklmnopqrst"), 10, 1, -1); + test(S("abcdefghij"), 10, 0, SV("abcdefghijklmnopqrst"), 10, 5, -5); + test(S("abcdefghij"), 10, 0, SV("abcdefghijklmnopqrst"), 10, 9, -9); + test(S("abcdefghij"), 10, 0, SV("abcdefghijklmnopqrst"), 10, 10, -10); + test(S("abcdefghij"), 10, 0, SV("abcdefghijklmnopqrst"), 10, 11, -10); + test(S("abcdefghij"), 10, 0, SV("abcdefghijklmnopqrst"), 19, 0, 0); + test(S("abcdefghij"), 10, 0, SV("abcdefghijklmnopqrst"), 19, 1, -1); + test(S("abcdefghij"), 10, 0, SV("abcdefghijklmnopqrst"), 19, 2, -1); + test(S("abcdefghij"), 10, 0, SV("abcdefghijklmnopqrst"), 20, 0, 0); + test(S("abcdefghij"), 10, 0, SV("abcdefghijklmnopqrst"), 20, 1, 0); + test(S("abcdefghij"), 10, 0, SV("abcdefghijklmnopqrst"), 21, 0, 0); + test(S("abcdefghij"), 10, 1, SV(""), 0, 0, 0); + test(S("abcdefghij"), 10, 1, SV(""), 0, 1, 0); + test(S("abcdefghij"), 10, 1, SV(""), 1, 0, 0); + test(S("abcdefghij"), 10, 1, SV("abcde"), 0, 0, 0); + test(S("abcdefghij"), 10, 1, SV("abcde"), 0, 1, -1); + test(S("abcdefghij"), 10, 1, SV("abcde"), 0, 2, -2); + test(S("abcdefghij"), 10, 1, SV("abcde"), 0, 4, -4); + test(S("abcdefghij"), 10, 1, SV("abcde"), 0, 5, -5); + test(S("abcdefghij"), 10, 1, SV("abcde"), 0, 6, -5); + test(S("abcdefghij"), 10, 1, SV("abcde"), 1, 0, 0); + test(S("abcdefghij"), 10, 1, SV("abcde"), 1, 1, -1); + test(S("abcdefghij"), 10, 1, SV("abcde"), 1, 2, -2); + test(S("abcdefghij"), 10, 1, SV("abcde"), 1, 3, -3); + test(S("abcdefghij"), 10, 1, SV("abcde"), 1, 4, -4); + test(S("abcdefghij"), 10, 1, SV("abcde"), 1, 5, -4); + test(S("abcdefghij"), 10, 1, SV("abcde"), 2, 0, 0); + test(S("abcdefghij"), 10, 1, SV("abcde"), 2, 1, -1); + test(S("abcdefghij"), 10, 1, SV("abcde"), 2, 2, -2); + test(S("abcdefghij"), 10, 1, SV("abcde"), 2, 3, -3); + test(S("abcdefghij"), 10, 1, SV("abcde"), 2, 4, -3); + test(S("abcdefghij"), 10, 1, SV("abcde"), 4, 0, 0); + test(S("abcdefghij"), 10, 1, SV("abcde"), 4, 1, -1); + test(S("abcdefghij"), 10, 1, SV("abcde"), 4, 2, -1); + test(S("abcdefghij"), 10, 1, SV("abcde"), 5, 0, 0); + test(S("abcdefghij"), 10, 1, SV("abcde"), 5, 1, 0); + test(S("abcdefghij"), 10, 1, SV("abcde"), 6, 0, 0); + test(S("abcdefghij"), 10, 1, SV("abcdefghij"), 0, 0, 0); + test(S("abcdefghij"), 10, 1, SV("abcdefghij"), 0, 1, -1); + test(S("abcdefghij"), 10, 1, SV("abcdefghij"), 0, 5, -5); + test(S("abcdefghij"), 10, 1, SV("abcdefghij"), 0, 9, -9); + test(S("abcdefghij"), 10, 1, SV("abcdefghij"), 0, 10, -10); + test(S("abcdefghij"), 10, 1, SV("abcdefghij"), 0, 11, -10); + test(S("abcdefghij"), 10, 1, SV("abcdefghij"), 1, 0, 0); + test(S("abcdefghij"), 10, 1, SV("abcdefghij"), 1, 1, -1); + test(S("abcdefghij"), 10, 1, SV("abcdefghij"), 1, 4, -4); + test(S("abcdefghij"), 10, 1, SV("abcdefghij"), 1, 8, -8); + test(S("abcdefghij"), 10, 1, SV("abcdefghij"), 1, 9, -9); + test(S("abcdefghij"), 10, 1, SV("abcdefghij"), 1, 10, -9); + test(S("abcdefghij"), 10, 1, SV("abcdefghij"), 5, 0, 0); + test(S("abcdefghij"), 10, 1, SV("abcdefghij"), 5, 1, -1); + test(S("abcdefghij"), 10, 1, SV("abcdefghij"), 5, 2, -2); + test(S("abcdefghij"), 10, 1, SV("abcdefghij"), 5, 4, -4); + test(S("abcdefghij"), 10, 1, SV("abcdefghij"), 5, 5, -5); + test(S("abcdefghij"), 10, 1, SV("abcdefghij"), 5, 6, -5); + test(S("abcdefghij"), 10, 1, SV("abcdefghij"), 9, 0, 0); + test(S("abcdefghij"), 10, 1, SV("abcdefghij"), 9, 1, -1); + test(S("abcdefghij"), 10, 1, SV("abcdefghij"), 9, 2, -1); + test(S("abcdefghij"), 10, 1, SV("abcdefghij"), 10, 0, 0); +} + +template +void test36() +{ + test(S("abcdefghij"), 10, 1, SV("abcdefghij"), 10, 1, 0); + test(S("abcdefghij"), 10, 1, SV("abcdefghij"), 11, 0, 0); + test(S("abcdefghij"), 10, 1, SV("abcdefghijklmnopqrst"), 0, 0, 0); + test(S("abcdefghij"), 10, 1, SV("abcdefghijklmnopqrst"), 0, 1, -1); + test(S("abcdefghij"), 10, 1, SV("abcdefghijklmnopqrst"), 0, 10, -10); + test(S("abcdefghij"), 10, 1, SV("abcdefghijklmnopqrst"), 0, 19, -19); + test(S("abcdefghij"), 10, 1, SV("abcdefghijklmnopqrst"), 0, 20, -20); + test(S("abcdefghij"), 10, 1, SV("abcdefghijklmnopqrst"), 0, 21, -20); + test(S("abcdefghij"), 10, 1, SV("abcdefghijklmnopqrst"), 1, 0, 0); + test(S("abcdefghij"), 10, 1, SV("abcdefghijklmnopqrst"), 1, 1, -1); + test(S("abcdefghij"), 10, 1, SV("abcdefghijklmnopqrst"), 1, 9, -9); + test(S("abcdefghij"), 10, 1, SV("abcdefghijklmnopqrst"), 1, 18, -18); + test(S("abcdefghij"), 10, 1, SV("abcdefghijklmnopqrst"), 1, 19, -19); + test(S("abcdefghij"), 10, 1, SV("abcdefghijklmnopqrst"), 1, 20, -19); + test(S("abcdefghij"), 10, 1, SV("abcdefghijklmnopqrst"), 10, 0, 0); + test(S("abcdefghij"), 10, 1, SV("abcdefghijklmnopqrst"), 10, 1, -1); + test(S("abcdefghij"), 10, 1, SV("abcdefghijklmnopqrst"), 10, 5, -5); + test(S("abcdefghij"), 10, 1, SV("abcdefghijklmnopqrst"), 10, 9, -9); + test(S("abcdefghij"), 10, 1, SV("abcdefghijklmnopqrst"), 10, 10, -10); + test(S("abcdefghij"), 10, 1, SV("abcdefghijklmnopqrst"), 10, 11, -10); + test(S("abcdefghij"), 10, 1, SV("abcdefghijklmnopqrst"), 19, 0, 0); + test(S("abcdefghij"), 10, 1, SV("abcdefghijklmnopqrst"), 19, 1, -1); + test(S("abcdefghij"), 10, 1, SV("abcdefghijklmnopqrst"), 19, 2, -1); + test(S("abcdefghij"), 10, 1, SV("abcdefghijklmnopqrst"), 20, 0, 0); + test(S("abcdefghij"), 10, 1, SV("abcdefghijklmnopqrst"), 20, 1, 0); + test(S("abcdefghij"), 10, 1, SV("abcdefghijklmnopqrst"), 21, 0, 0); + test(S("abcdefghij"), 11, 0, SV(""), 0, 0, 0); + test(S("abcdefghij"), 11, 0, SV(""), 0, 1, 0); + test(S("abcdefghij"), 11, 0, SV(""), 1, 0, 0); + test(S("abcdefghij"), 11, 0, SV("abcde"), 0, 0, 0); + test(S("abcdefghij"), 11, 0, SV("abcde"), 0, 1, 0); + test(S("abcdefghij"), 11, 0, SV("abcde"), 0, 2, 0); + test(S("abcdefghij"), 11, 0, SV("abcde"), 0, 4, 0); + test(S("abcdefghij"), 11, 0, SV("abcde"), 0, 5, 0); + test(S("abcdefghij"), 11, 0, SV("abcde"), 0, 6, 0); + test(S("abcdefghij"), 11, 0, SV("abcde"), 1, 0, 0); + test(S("abcdefghij"), 11, 0, SV("abcde"), 1, 1, 0); + test(S("abcdefghij"), 11, 0, SV("abcde"), 1, 2, 0); + test(S("abcdefghij"), 11, 0, SV("abcde"), 1, 3, 0); + test(S("abcdefghij"), 11, 0, SV("abcde"), 1, 4, 0); + test(S("abcdefghij"), 11, 0, SV("abcde"), 1, 5, 0); + test(S("abcdefghij"), 11, 0, SV("abcde"), 2, 0, 0); + test(S("abcdefghij"), 11, 0, SV("abcde"), 2, 1, 0); + test(S("abcdefghij"), 11, 0, SV("abcde"), 2, 2, 0); + test(S("abcdefghij"), 11, 0, SV("abcde"), 2, 3, 0); + test(S("abcdefghij"), 11, 0, SV("abcde"), 2, 4, 0); + test(S("abcdefghij"), 11, 0, SV("abcde"), 4, 0, 0); + test(S("abcdefghij"), 11, 0, SV("abcde"), 4, 1, 0); + test(S("abcdefghij"), 11, 0, SV("abcde"), 4, 2, 0); + test(S("abcdefghij"), 11, 0, SV("abcde"), 5, 0, 0); + test(S("abcdefghij"), 11, 0, SV("abcde"), 5, 1, 0); + test(S("abcdefghij"), 11, 0, SV("abcde"), 6, 0, 0); + test(S("abcdefghij"), 11, 0, SV("abcdefghij"), 0, 0, 0); + test(S("abcdefghij"), 11, 0, SV("abcdefghij"), 0, 1, 0); + test(S("abcdefghij"), 11, 0, SV("abcdefghij"), 0, 5, 0); + test(S("abcdefghij"), 11, 0, SV("abcdefghij"), 0, 9, 0); + test(S("abcdefghij"), 11, 0, SV("abcdefghij"), 0, 10, 0); + test(S("abcdefghij"), 11, 0, SV("abcdefghij"), 0, 11, 0); + test(S("abcdefghij"), 11, 0, SV("abcdefghij"), 1, 0, 0); + test(S("abcdefghij"), 11, 0, SV("abcdefghij"), 1, 1, 0); + test(S("abcdefghij"), 11, 0, SV("abcdefghij"), 1, 4, 0); + test(S("abcdefghij"), 11, 0, SV("abcdefghij"), 1, 8, 0); + test(S("abcdefghij"), 11, 0, SV("abcdefghij"), 1, 9, 0); + test(S("abcdefghij"), 11, 0, SV("abcdefghij"), 1, 10, 0); + test(S("abcdefghij"), 11, 0, SV("abcdefghij"), 5, 0, 0); + test(S("abcdefghij"), 11, 0, SV("abcdefghij"), 5, 1, 0); + test(S("abcdefghij"), 11, 0, SV("abcdefghij"), 5, 2, 0); + test(S("abcdefghij"), 11, 0, SV("abcdefghij"), 5, 4, 0); + test(S("abcdefghij"), 11, 0, SV("abcdefghij"), 5, 5, 0); + test(S("abcdefghij"), 11, 0, SV("abcdefghij"), 5, 6, 0); + test(S("abcdefghij"), 11, 0, SV("abcdefghij"), 9, 0, 0); + test(S("abcdefghij"), 11, 0, SV("abcdefghij"), 9, 1, 0); + test(S("abcdefghij"), 11, 0, SV("abcdefghij"), 9, 2, 0); + test(S("abcdefghij"), 11, 0, SV("abcdefghij"), 10, 0, 0); + test(S("abcdefghij"), 11, 0, SV("abcdefghij"), 10, 1, 0); + test(S("abcdefghij"), 11, 0, SV("abcdefghij"), 11, 0, 0); + test(S("abcdefghij"), 11, 0, SV("abcdefghijklmnopqrst"), 0, 0, 0); + test(S("abcdefghij"), 11, 0, SV("abcdefghijklmnopqrst"), 0, 1, 0); + test(S("abcdefghij"), 11, 0, SV("abcdefghijklmnopqrst"), 0, 10, 0); + test(S("abcdefghij"), 11, 0, SV("abcdefghijklmnopqrst"), 0, 19, 0); + test(S("abcdefghij"), 11, 0, SV("abcdefghijklmnopqrst"), 0, 20, 0); + test(S("abcdefghij"), 11, 0, SV("abcdefghijklmnopqrst"), 0, 21, 0); + test(S("abcdefghij"), 11, 0, SV("abcdefghijklmnopqrst"), 1, 0, 0); + test(S("abcdefghij"), 11, 0, SV("abcdefghijklmnopqrst"), 1, 1, 0); + test(S("abcdefghij"), 11, 0, SV("abcdefghijklmnopqrst"), 1, 9, 0); + test(S("abcdefghij"), 11, 0, SV("abcdefghijklmnopqrst"), 1, 18, 0); + test(S("abcdefghij"), 11, 0, SV("abcdefghijklmnopqrst"), 1, 19, 0); + test(S("abcdefghij"), 11, 0, SV("abcdefghijklmnopqrst"), 1, 20, 0); + test(S("abcdefghij"), 11, 0, SV("abcdefghijklmnopqrst"), 10, 0, 0); + test(S("abcdefghij"), 11, 0, SV("abcdefghijklmnopqrst"), 10, 1, 0); + test(S("abcdefghij"), 11, 0, SV("abcdefghijklmnopqrst"), 10, 5, 0); + test(S("abcdefghij"), 11, 0, SV("abcdefghijklmnopqrst"), 10, 9, 0); + test(S("abcdefghij"), 11, 0, SV("abcdefghijklmnopqrst"), 10, 10, 0); + test(S("abcdefghij"), 11, 0, SV("abcdefghijklmnopqrst"), 10, 11, 0); + test(S("abcdefghij"), 11, 0, SV("abcdefghijklmnopqrst"), 19, 0, 0); + test(S("abcdefghij"), 11, 0, SV("abcdefghijklmnopqrst"), 19, 1, 0); + test(S("abcdefghij"), 11, 0, SV("abcdefghijklmnopqrst"), 19, 2, 0); + test(S("abcdefghij"), 11, 0, SV("abcdefghijklmnopqrst"), 20, 0, 0); + test(S("abcdefghij"), 11, 0, SV("abcdefghijklmnopqrst"), 20, 1, 0); + test(S("abcdefghij"), 11, 0, SV("abcdefghijklmnopqrst"), 21, 0, 0); +} + +template +void test37() +{ + test(S("abcdefghijklmnopqrst"), 0, 0, SV(""), 0, 0, 0); + test(S("abcdefghijklmnopqrst"), 0, 0, SV(""), 0, 1, 0); + test(S("abcdefghijklmnopqrst"), 0, 0, SV(""), 1, 0, 0); + test(S("abcdefghijklmnopqrst"), 0, 0, SV("abcde"), 0, 0, 0); + test(S("abcdefghijklmnopqrst"), 0, 0, SV("abcde"), 0, 1, -1); + test(S("abcdefghijklmnopqrst"), 0, 0, SV("abcde"), 0, 2, -2); + test(S("abcdefghijklmnopqrst"), 0, 0, SV("abcde"), 0, 4, -4); + test(S("abcdefghijklmnopqrst"), 0, 0, SV("abcde"), 0, 5, -5); + test(S("abcdefghijklmnopqrst"), 0, 0, SV("abcde"), 0, 6, -5); + test(S("abcdefghijklmnopqrst"), 0, 0, SV("abcde"), 1, 0, 0); + test(S("abcdefghijklmnopqrst"), 0, 0, SV("abcde"), 1, 1, -1); + test(S("abcdefghijklmnopqrst"), 0, 0, SV("abcde"), 1, 2, -2); + test(S("abcdefghijklmnopqrst"), 0, 0, SV("abcde"), 1, 3, -3); + test(S("abcdefghijklmnopqrst"), 0, 0, SV("abcde"), 1, 4, -4); + test(S("abcdefghijklmnopqrst"), 0, 0, SV("abcde"), 1, 5, -4); + test(S("abcdefghijklmnopqrst"), 0, 0, SV("abcde"), 2, 0, 0); + test(S("abcdefghijklmnopqrst"), 0, 0, SV("abcde"), 2, 1, -1); + test(S("abcdefghijklmnopqrst"), 0, 0, SV("abcde"), 2, 2, -2); + test(S("abcdefghijklmnopqrst"), 0, 0, SV("abcde"), 2, 3, -3); + test(S("abcdefghijklmnopqrst"), 0, 0, SV("abcde"), 2, 4, -3); + test(S("abcdefghijklmnopqrst"), 0, 0, SV("abcde"), 4, 0, 0); + test(S("abcdefghijklmnopqrst"), 0, 0, SV("abcde"), 4, 1, -1); + test(S("abcdefghijklmnopqrst"), 0, 0, SV("abcde"), 4, 2, -1); + test(S("abcdefghijklmnopqrst"), 0, 0, SV("abcde"), 5, 0, 0); + test(S("abcdefghijklmnopqrst"), 0, 0, SV("abcde"), 5, 1, 0); + test(S("abcdefghijklmnopqrst"), 0, 0, SV("abcde"), 6, 0, 0); + test(S("abcdefghijklmnopqrst"), 0, 0, SV("abcdefghij"), 0, 0, 0); + test(S("abcdefghijklmnopqrst"), 0, 0, SV("abcdefghij"), 0, 1, -1); + test(S("abcdefghijklmnopqrst"), 0, 0, SV("abcdefghij"), 0, 5, -5); + test(S("abcdefghijklmnopqrst"), 0, 0, SV("abcdefghij"), 0, 9, -9); + test(S("abcdefghijklmnopqrst"), 0, 0, SV("abcdefghij"), 0, 10, -10); + test(S("abcdefghijklmnopqrst"), 0, 0, SV("abcdefghij"), 0, 11, -10); + test(S("abcdefghijklmnopqrst"), 0, 0, SV("abcdefghij"), 1, 0, 0); + test(S("abcdefghijklmnopqrst"), 0, 0, SV("abcdefghij"), 1, 1, -1); + test(S("abcdefghijklmnopqrst"), 0, 0, SV("abcdefghij"), 1, 4, -4); + test(S("abcdefghijklmnopqrst"), 0, 0, SV("abcdefghij"), 1, 8, -8); + test(S("abcdefghijklmnopqrst"), 0, 0, SV("abcdefghij"), 1, 9, -9); + test(S("abcdefghijklmnopqrst"), 0, 0, SV("abcdefghij"), 1, 10, -9); + test(S("abcdefghijklmnopqrst"), 0, 0, SV("abcdefghij"), 5, 0, 0); + test(S("abcdefghijklmnopqrst"), 0, 0, SV("abcdefghij"), 5, 1, -1); + test(S("abcdefghijklmnopqrst"), 0, 0, SV("abcdefghij"), 5, 2, -2); + test(S("abcdefghijklmnopqrst"), 0, 0, SV("abcdefghij"), 5, 4, -4); + test(S("abcdefghijklmnopqrst"), 0, 0, SV("abcdefghij"), 5, 5, -5); + test(S("abcdefghijklmnopqrst"), 0, 0, SV("abcdefghij"), 5, 6, -5); + test(S("abcdefghijklmnopqrst"), 0, 0, SV("abcdefghij"), 9, 0, 0); + test(S("abcdefghijklmnopqrst"), 0, 0, SV("abcdefghij"), 9, 1, -1); + test(S("abcdefghijklmnopqrst"), 0, 0, SV("abcdefghij"), 9, 2, -1); + test(S("abcdefghijklmnopqrst"), 0, 0, SV("abcdefghij"), 10, 0, 0); + test(S("abcdefghijklmnopqrst"), 0, 0, SV("abcdefghij"), 10, 1, 0); + test(S("abcdefghijklmnopqrst"), 0, 0, SV("abcdefghij"), 11, 0, 0); + test(S("abcdefghijklmnopqrst"), 0, 0, SV("abcdefghijklmnopqrst"), 0, 0, 0); + test(S("abcdefghijklmnopqrst"), 0, 0, SV("abcdefghijklmnopqrst"), 0, 1, -1); + test(S("abcdefghijklmnopqrst"), 0, 0, SV("abcdefghijklmnopqrst"), 0, 10, -10); + test(S("abcdefghijklmnopqrst"), 0, 0, SV("abcdefghijklmnopqrst"), 0, 19, -19); + test(S("abcdefghijklmnopqrst"), 0, 0, SV("abcdefghijklmnopqrst"), 0, 20, -20); + test(S("abcdefghijklmnopqrst"), 0, 0, SV("abcdefghijklmnopqrst"), 0, 21, -20); + test(S("abcdefghijklmnopqrst"), 0, 0, SV("abcdefghijklmnopqrst"), 1, 0, 0); + test(S("abcdefghijklmnopqrst"), 0, 0, SV("abcdefghijklmnopqrst"), 1, 1, -1); + test(S("abcdefghijklmnopqrst"), 0, 0, SV("abcdefghijklmnopqrst"), 1, 9, -9); + test(S("abcdefghijklmnopqrst"), 0, 0, SV("abcdefghijklmnopqrst"), 1, 18, -18); + test(S("abcdefghijklmnopqrst"), 0, 0, SV("abcdefghijklmnopqrst"), 1, 19, -19); + test(S("abcdefghijklmnopqrst"), 0, 0, SV("abcdefghijklmnopqrst"), 1, 20, -19); + test(S("abcdefghijklmnopqrst"), 0, 0, SV("abcdefghijklmnopqrst"), 10, 0, 0); + test(S("abcdefghijklmnopqrst"), 0, 0, SV("abcdefghijklmnopqrst"), 10, 1, -1); + test(S("abcdefghijklmnopqrst"), 0, 0, SV("abcdefghijklmnopqrst"), 10, 5, -5); + test(S("abcdefghijklmnopqrst"), 0, 0, SV("abcdefghijklmnopqrst"), 10, 9, -9); + test(S("abcdefghijklmnopqrst"), 0, 0, SV("abcdefghijklmnopqrst"), 10, 10, -10); + test(S("abcdefghijklmnopqrst"), 0, 0, SV("abcdefghijklmnopqrst"), 10, 11, -10); + test(S("abcdefghijklmnopqrst"), 0, 0, SV("abcdefghijklmnopqrst"), 19, 0, 0); + test(S("abcdefghijklmnopqrst"), 0, 0, SV("abcdefghijklmnopqrst"), 19, 1, -1); + test(S("abcdefghijklmnopqrst"), 0, 0, SV("abcdefghijklmnopqrst"), 19, 2, -1); + test(S("abcdefghijklmnopqrst"), 0, 0, SV("abcdefghijklmnopqrst"), 20, 0, 0); + test(S("abcdefghijklmnopqrst"), 0, 0, SV("abcdefghijklmnopqrst"), 20, 1, 0); + test(S("abcdefghijklmnopqrst"), 0, 0, SV("abcdefghijklmnopqrst"), 21, 0, 0); + test(S("abcdefghijklmnopqrst"), 0, 1, SV(""), 0, 0, 1); + test(S("abcdefghijklmnopqrst"), 0, 1, SV(""), 0, 1, 1); + test(S("abcdefghijklmnopqrst"), 0, 1, SV(""), 1, 0, 0); + test(S("abcdefghijklmnopqrst"), 0, 1, SV("abcde"), 0, 0, 1); + test(S("abcdefghijklmnopqrst"), 0, 1, SV("abcde"), 0, 1, 0); + test(S("abcdefghijklmnopqrst"), 0, 1, SV("abcde"), 0, 2, -1); + test(S("abcdefghijklmnopqrst"), 0, 1, SV("abcde"), 0, 4, -3); + test(S("abcdefghijklmnopqrst"), 0, 1, SV("abcde"), 0, 5, -4); + test(S("abcdefghijklmnopqrst"), 0, 1, SV("abcde"), 0, 6, -4); + test(S("abcdefghijklmnopqrst"), 0, 1, SV("abcde"), 1, 0, 1); + test(S("abcdefghijklmnopqrst"), 0, 1, SV("abcde"), 1, 1, -1); + test(S("abcdefghijklmnopqrst"), 0, 1, SV("abcde"), 1, 2, -1); + test(S("abcdefghijklmnopqrst"), 0, 1, SV("abcde"), 1, 3, -1); + test(S("abcdefghijklmnopqrst"), 0, 1, SV("abcde"), 1, 4, -1); + test(S("abcdefghijklmnopqrst"), 0, 1, SV("abcde"), 1, 5, -1); + test(S("abcdefghijklmnopqrst"), 0, 1, SV("abcde"), 2, 0, 1); + test(S("abcdefghijklmnopqrst"), 0, 1, SV("abcde"), 2, 1, -2); + test(S("abcdefghijklmnopqrst"), 0, 1, SV("abcde"), 2, 2, -2); + test(S("abcdefghijklmnopqrst"), 0, 1, SV("abcde"), 2, 3, -2); + test(S("abcdefghijklmnopqrst"), 0, 1, SV("abcde"), 2, 4, -2); + test(S("abcdefghijklmnopqrst"), 0, 1, SV("abcde"), 4, 0, 1); + test(S("abcdefghijklmnopqrst"), 0, 1, SV("abcde"), 4, 1, -4); + test(S("abcdefghijklmnopqrst"), 0, 1, SV("abcde"), 4, 2, -4); + test(S("abcdefghijklmnopqrst"), 0, 1, SV("abcde"), 5, 0, 1); + test(S("abcdefghijklmnopqrst"), 0, 1, SV("abcde"), 5, 1, 1); + test(S("abcdefghijklmnopqrst"), 0, 1, SV("abcde"), 6, 0, 0); +} + +template +void test38() +{ + test(S("abcdefghijklmnopqrst"), 0, 1, SV("abcdefghij"), 0, 0, 1); + test(S("abcdefghijklmnopqrst"), 0, 1, SV("abcdefghij"), 0, 1, 0); + test(S("abcdefghijklmnopqrst"), 0, 1, SV("abcdefghij"), 0, 5, -4); + test(S("abcdefghijklmnopqrst"), 0, 1, SV("abcdefghij"), 0, 9, -8); + test(S("abcdefghijklmnopqrst"), 0, 1, SV("abcdefghij"), 0, 10, -9); + test(S("abcdefghijklmnopqrst"), 0, 1, SV("abcdefghij"), 0, 11, -9); + test(S("abcdefghijklmnopqrst"), 0, 1, SV("abcdefghij"), 1, 0, 1); + test(S("abcdefghijklmnopqrst"), 0, 1, SV("abcdefghij"), 1, 1, -1); + test(S("abcdefghijklmnopqrst"), 0, 1, SV("abcdefghij"), 1, 4, -1); + test(S("abcdefghijklmnopqrst"), 0, 1, SV("abcdefghij"), 1, 8, -1); + test(S("abcdefghijklmnopqrst"), 0, 1, SV("abcdefghij"), 1, 9, -1); + test(S("abcdefghijklmnopqrst"), 0, 1, SV("abcdefghij"), 1, 10, -1); + test(S("abcdefghijklmnopqrst"), 0, 1, SV("abcdefghij"), 5, 0, 1); + test(S("abcdefghijklmnopqrst"), 0, 1, SV("abcdefghij"), 5, 1, -5); + test(S("abcdefghijklmnopqrst"), 0, 1, SV("abcdefghij"), 5, 2, -5); + test(S("abcdefghijklmnopqrst"), 0, 1, SV("abcdefghij"), 5, 4, -5); + test(S("abcdefghijklmnopqrst"), 0, 1, SV("abcdefghij"), 5, 5, -5); + test(S("abcdefghijklmnopqrst"), 0, 1, SV("abcdefghij"), 5, 6, -5); + test(S("abcdefghijklmnopqrst"), 0, 1, SV("abcdefghij"), 9, 0, 1); + test(S("abcdefghijklmnopqrst"), 0, 1, SV("abcdefghij"), 9, 1, -9); + test(S("abcdefghijklmnopqrst"), 0, 1, SV("abcdefghij"), 9, 2, -9); + test(S("abcdefghijklmnopqrst"), 0, 1, SV("abcdefghij"), 10, 0, 1); + test(S("abcdefghijklmnopqrst"), 0, 1, SV("abcdefghij"), 10, 1, 1); + test(S("abcdefghijklmnopqrst"), 0, 1, SV("abcdefghij"), 11, 0, 0); + test(S("abcdefghijklmnopqrst"), 0, 1, SV("abcdefghijklmnopqrst"), 0, 0, 1); + test(S("abcdefghijklmnopqrst"), 0, 1, SV("abcdefghijklmnopqrst"), 0, 1, 0); + test(S("abcdefghijklmnopqrst"), 0, 1, SV("abcdefghijklmnopqrst"), 0, 10, -9); + test(S("abcdefghijklmnopqrst"), 0, 1, SV("abcdefghijklmnopqrst"), 0, 19, -18); + test(S("abcdefghijklmnopqrst"), 0, 1, SV("abcdefghijklmnopqrst"), 0, 20, -19); + test(S("abcdefghijklmnopqrst"), 0, 1, SV("abcdefghijklmnopqrst"), 0, 21, -19); + test(S("abcdefghijklmnopqrst"), 0, 1, SV("abcdefghijklmnopqrst"), 1, 0, 1); + test(S("abcdefghijklmnopqrst"), 0, 1, SV("abcdefghijklmnopqrst"), 1, 1, -1); + test(S("abcdefghijklmnopqrst"), 0, 1, SV("abcdefghijklmnopqrst"), 1, 9, -1); + test(S("abcdefghijklmnopqrst"), 0, 1, SV("abcdefghijklmnopqrst"), 1, 18, -1); + test(S("abcdefghijklmnopqrst"), 0, 1, SV("abcdefghijklmnopqrst"), 1, 19, -1); + test(S("abcdefghijklmnopqrst"), 0, 1, SV("abcdefghijklmnopqrst"), 1, 20, -1); + test(S("abcdefghijklmnopqrst"), 0, 1, SV("abcdefghijklmnopqrst"), 10, 0, 1); + test(S("abcdefghijklmnopqrst"), 0, 1, SV("abcdefghijklmnopqrst"), 10, 1, -10); + test(S("abcdefghijklmnopqrst"), 0, 1, SV("abcdefghijklmnopqrst"), 10, 5, -10); + test(S("abcdefghijklmnopqrst"), 0, 1, SV("abcdefghijklmnopqrst"), 10, 9, -10); + test(S("abcdefghijklmnopqrst"), 0, 1, SV("abcdefghijklmnopqrst"), 10, 10, -10); + test(S("abcdefghijklmnopqrst"), 0, 1, SV("abcdefghijklmnopqrst"), 10, 11, -10); + test(S("abcdefghijklmnopqrst"), 0, 1, SV("abcdefghijklmnopqrst"), 19, 0, 1); + test(S("abcdefghijklmnopqrst"), 0, 1, SV("abcdefghijklmnopqrst"), 19, 1, -19); + test(S("abcdefghijklmnopqrst"), 0, 1, SV("abcdefghijklmnopqrst"), 19, 2, -19); + test(S("abcdefghijklmnopqrst"), 0, 1, SV("abcdefghijklmnopqrst"), 20, 0, 1); + test(S("abcdefghijklmnopqrst"), 0, 1, SV("abcdefghijklmnopqrst"), 20, 1, 1); + test(S("abcdefghijklmnopqrst"), 0, 1, SV("abcdefghijklmnopqrst"), 21, 0, 0); + test(S("abcdefghijklmnopqrst"), 0, 10, SV(""), 0, 0, 10); + test(S("abcdefghijklmnopqrst"), 0, 10, SV(""), 0, 1, 10); + test(S("abcdefghijklmnopqrst"), 0, 10, SV(""), 1, 0, 0); + test(S("abcdefghijklmnopqrst"), 0, 10, SV("abcde"), 0, 0, 10); + test(S("abcdefghijklmnopqrst"), 0, 10, SV("abcde"), 0, 1, 9); + test(S("abcdefghijklmnopqrst"), 0, 10, SV("abcde"), 0, 2, 8); + test(S("abcdefghijklmnopqrst"), 0, 10, SV("abcde"), 0, 4, 6); + test(S("abcdefghijklmnopqrst"), 0, 10, SV("abcde"), 0, 5, 5); + test(S("abcdefghijklmnopqrst"), 0, 10, SV("abcde"), 0, 6, 5); + test(S("abcdefghijklmnopqrst"), 0, 10, SV("abcde"), 1, 0, 10); + test(S("abcdefghijklmnopqrst"), 0, 10, SV("abcde"), 1, 1, -1); + test(S("abcdefghijklmnopqrst"), 0, 10, SV("abcde"), 1, 2, -1); + test(S("abcdefghijklmnopqrst"), 0, 10, SV("abcde"), 1, 3, -1); + test(S("abcdefghijklmnopqrst"), 0, 10, SV("abcde"), 1, 4, -1); + test(S("abcdefghijklmnopqrst"), 0, 10, SV("abcde"), 1, 5, -1); + test(S("abcdefghijklmnopqrst"), 0, 10, SV("abcde"), 2, 0, 10); + test(S("abcdefghijklmnopqrst"), 0, 10, SV("abcde"), 2, 1, -2); + test(S("abcdefghijklmnopqrst"), 0, 10, SV("abcde"), 2, 2, -2); + test(S("abcdefghijklmnopqrst"), 0, 10, SV("abcde"), 2, 3, -2); + test(S("abcdefghijklmnopqrst"), 0, 10, SV("abcde"), 2, 4, -2); + test(S("abcdefghijklmnopqrst"), 0, 10, SV("abcde"), 4, 0, 10); + test(S("abcdefghijklmnopqrst"), 0, 10, SV("abcde"), 4, 1, -4); + test(S("abcdefghijklmnopqrst"), 0, 10, SV("abcde"), 4, 2, -4); + test(S("abcdefghijklmnopqrst"), 0, 10, SV("abcde"), 5, 0, 10); + test(S("abcdefghijklmnopqrst"), 0, 10, SV("abcde"), 5, 1, 10); + test(S("abcdefghijklmnopqrst"), 0, 10, SV("abcde"), 6, 0, 0); + test(S("abcdefghijklmnopqrst"), 0, 10, SV("abcdefghij"), 0, 0, 10); + test(S("abcdefghijklmnopqrst"), 0, 10, SV("abcdefghij"), 0, 1, 9); + test(S("abcdefghijklmnopqrst"), 0, 10, SV("abcdefghij"), 0, 5, 5); + test(S("abcdefghijklmnopqrst"), 0, 10, SV("abcdefghij"), 0, 9, 1); + test(S("abcdefghijklmnopqrst"), 0, 10, SV("abcdefghij"), 0, 10, 0); + test(S("abcdefghijklmnopqrst"), 0, 10, SV("abcdefghij"), 0, 11, 0); + test(S("abcdefghijklmnopqrst"), 0, 10, SV("abcdefghij"), 1, 0, 10); + test(S("abcdefghijklmnopqrst"), 0, 10, SV("abcdefghij"), 1, 1, -1); + test(S("abcdefghijklmnopqrst"), 0, 10, SV("abcdefghij"), 1, 4, -1); + test(S("abcdefghijklmnopqrst"), 0, 10, SV("abcdefghij"), 1, 8, -1); + test(S("abcdefghijklmnopqrst"), 0, 10, SV("abcdefghij"), 1, 9, -1); + test(S("abcdefghijklmnopqrst"), 0, 10, SV("abcdefghij"), 1, 10, -1); + test(S("abcdefghijklmnopqrst"), 0, 10, SV("abcdefghij"), 5, 0, 10); + test(S("abcdefghijklmnopqrst"), 0, 10, SV("abcdefghij"), 5, 1, -5); + test(S("abcdefghijklmnopqrst"), 0, 10, SV("abcdefghij"), 5, 2, -5); + test(S("abcdefghijklmnopqrst"), 0, 10, SV("abcdefghij"), 5, 4, -5); + test(S("abcdefghijklmnopqrst"), 0, 10, SV("abcdefghij"), 5, 5, -5); + test(S("abcdefghijklmnopqrst"), 0, 10, SV("abcdefghij"), 5, 6, -5); + test(S("abcdefghijklmnopqrst"), 0, 10, SV("abcdefghij"), 9, 0, 10); + test(S("abcdefghijklmnopqrst"), 0, 10, SV("abcdefghij"), 9, 1, -9); + test(S("abcdefghijklmnopqrst"), 0, 10, SV("abcdefghij"), 9, 2, -9); + test(S("abcdefghijklmnopqrst"), 0, 10, SV("abcdefghij"), 10, 0, 10); + test(S("abcdefghijklmnopqrst"), 0, 10, SV("abcdefghij"), 10, 1, 10); + test(S("abcdefghijklmnopqrst"), 0, 10, SV("abcdefghij"), 11, 0, 0); + test(S("abcdefghijklmnopqrst"), 0, 10, SV("abcdefghijklmnopqrst"), 0, 0, 10); + test(S("abcdefghijklmnopqrst"), 0, 10, SV("abcdefghijklmnopqrst"), 0, 1, 9); +} + +template +void test39() +{ + test(S("abcdefghijklmnopqrst"), 0, 10, SV("abcdefghijklmnopqrst"), 0, 10, 0); + test(S("abcdefghijklmnopqrst"), 0, 10, SV("abcdefghijklmnopqrst"), 0, 19, -9); + test(S("abcdefghijklmnopqrst"), 0, 10, SV("abcdefghijklmnopqrst"), 0, 20, -10); + test(S("abcdefghijklmnopqrst"), 0, 10, SV("abcdefghijklmnopqrst"), 0, 21, -10); + test(S("abcdefghijklmnopqrst"), 0, 10, SV("abcdefghijklmnopqrst"), 1, 0, 10); + test(S("abcdefghijklmnopqrst"), 0, 10, SV("abcdefghijklmnopqrst"), 1, 1, -1); + test(S("abcdefghijklmnopqrst"), 0, 10, SV("abcdefghijklmnopqrst"), 1, 9, -1); + test(S("abcdefghijklmnopqrst"), 0, 10, SV("abcdefghijklmnopqrst"), 1, 18, -1); + test(S("abcdefghijklmnopqrst"), 0, 10, SV("abcdefghijklmnopqrst"), 1, 19, -1); + test(S("abcdefghijklmnopqrst"), 0, 10, SV("abcdefghijklmnopqrst"), 1, 20, -1); + test(S("abcdefghijklmnopqrst"), 0, 10, SV("abcdefghijklmnopqrst"), 10, 0, 10); + test(S("abcdefghijklmnopqrst"), 0, 10, SV("abcdefghijklmnopqrst"), 10, 1, -10); + test(S("abcdefghijklmnopqrst"), 0, 10, SV("abcdefghijklmnopqrst"), 10, 5, -10); + test(S("abcdefghijklmnopqrst"), 0, 10, SV("abcdefghijklmnopqrst"), 10, 9, -10); + test(S("abcdefghijklmnopqrst"), 0, 10, SV("abcdefghijklmnopqrst"), 10, 10, -10); + test(S("abcdefghijklmnopqrst"), 0, 10, SV("abcdefghijklmnopqrst"), 10, 11, -10); + test(S("abcdefghijklmnopqrst"), 0, 10, SV("abcdefghijklmnopqrst"), 19, 0, 10); + test(S("abcdefghijklmnopqrst"), 0, 10, SV("abcdefghijklmnopqrst"), 19, 1, -19); + test(S("abcdefghijklmnopqrst"), 0, 10, SV("abcdefghijklmnopqrst"), 19, 2, -19); + test(S("abcdefghijklmnopqrst"), 0, 10, SV("abcdefghijklmnopqrst"), 20, 0, 10); + test(S("abcdefghijklmnopqrst"), 0, 10, SV("abcdefghijklmnopqrst"), 20, 1, 10); + test(S("abcdefghijklmnopqrst"), 0, 10, SV("abcdefghijklmnopqrst"), 21, 0, 0); + test(S("abcdefghijklmnopqrst"), 0, 19, SV(""), 0, 0, 19); + test(S("abcdefghijklmnopqrst"), 0, 19, SV(""), 0, 1, 19); + test(S("abcdefghijklmnopqrst"), 0, 19, SV(""), 1, 0, 0); + test(S("abcdefghijklmnopqrst"), 0, 19, SV("abcde"), 0, 0, 19); + test(S("abcdefghijklmnopqrst"), 0, 19, SV("abcde"), 0, 1, 18); + test(S("abcdefghijklmnopqrst"), 0, 19, SV("abcde"), 0, 2, 17); + test(S("abcdefghijklmnopqrst"), 0, 19, SV("abcde"), 0, 4, 15); + test(S("abcdefghijklmnopqrst"), 0, 19, SV("abcde"), 0, 5, 14); + test(S("abcdefghijklmnopqrst"), 0, 19, SV("abcde"), 0, 6, 14); + test(S("abcdefghijklmnopqrst"), 0, 19, SV("abcde"), 1, 0, 19); + test(S("abcdefghijklmnopqrst"), 0, 19, SV("abcde"), 1, 1, -1); + test(S("abcdefghijklmnopqrst"), 0, 19, SV("abcde"), 1, 2, -1); + test(S("abcdefghijklmnopqrst"), 0, 19, SV("abcde"), 1, 3, -1); + test(S("abcdefghijklmnopqrst"), 0, 19, SV("abcde"), 1, 4, -1); + test(S("abcdefghijklmnopqrst"), 0, 19, SV("abcde"), 1, 5, -1); + test(S("abcdefghijklmnopqrst"), 0, 19, SV("abcde"), 2, 0, 19); + test(S("abcdefghijklmnopqrst"), 0, 19, SV("abcde"), 2, 1, -2); + test(S("abcdefghijklmnopqrst"), 0, 19, SV("abcde"), 2, 2, -2); + test(S("abcdefghijklmnopqrst"), 0, 19, SV("abcde"), 2, 3, -2); + test(S("abcdefghijklmnopqrst"), 0, 19, SV("abcde"), 2, 4, -2); + test(S("abcdefghijklmnopqrst"), 0, 19, SV("abcde"), 4, 0, 19); + test(S("abcdefghijklmnopqrst"), 0, 19, SV("abcde"), 4, 1, -4); + test(S("abcdefghijklmnopqrst"), 0, 19, SV("abcde"), 4, 2, -4); + test(S("abcdefghijklmnopqrst"), 0, 19, SV("abcde"), 5, 0, 19); + test(S("abcdefghijklmnopqrst"), 0, 19, SV("abcde"), 5, 1, 19); + test(S("abcdefghijklmnopqrst"), 0, 19, SV("abcde"), 6, 0, 0); + test(S("abcdefghijklmnopqrst"), 0, 19, SV("abcdefghij"), 0, 0, 19); + test(S("abcdefghijklmnopqrst"), 0, 19, SV("abcdefghij"), 0, 1, 18); + test(S("abcdefghijklmnopqrst"), 0, 19, SV("abcdefghij"), 0, 5, 14); + test(S("abcdefghijklmnopqrst"), 0, 19, SV("abcdefghij"), 0, 9, 10); + test(S("abcdefghijklmnopqrst"), 0, 19, SV("abcdefghij"), 0, 10, 9); + test(S("abcdefghijklmnopqrst"), 0, 19, SV("abcdefghij"), 0, 11, 9); + test(S("abcdefghijklmnopqrst"), 0, 19, SV("abcdefghij"), 1, 0, 19); + test(S("abcdefghijklmnopqrst"), 0, 19, SV("abcdefghij"), 1, 1, -1); + test(S("abcdefghijklmnopqrst"), 0, 19, SV("abcdefghij"), 1, 4, -1); + test(S("abcdefghijklmnopqrst"), 0, 19, SV("abcdefghij"), 1, 8, -1); + test(S("abcdefghijklmnopqrst"), 0, 19, SV("abcdefghij"), 1, 9, -1); + test(S("abcdefghijklmnopqrst"), 0, 19, SV("abcdefghij"), 1, 10, -1); + test(S("abcdefghijklmnopqrst"), 0, 19, SV("abcdefghij"), 5, 0, 19); + test(S("abcdefghijklmnopqrst"), 0, 19, SV("abcdefghij"), 5, 1, -5); + test(S("abcdefghijklmnopqrst"), 0, 19, SV("abcdefghij"), 5, 2, -5); + test(S("abcdefghijklmnopqrst"), 0, 19, SV("abcdefghij"), 5, 4, -5); + test(S("abcdefghijklmnopqrst"), 0, 19, SV("abcdefghij"), 5, 5, -5); + test(S("abcdefghijklmnopqrst"), 0, 19, SV("abcdefghij"), 5, 6, -5); + test(S("abcdefghijklmnopqrst"), 0, 19, SV("abcdefghij"), 9, 0, 19); + test(S("abcdefghijklmnopqrst"), 0, 19, SV("abcdefghij"), 9, 1, -9); + test(S("abcdefghijklmnopqrst"), 0, 19, SV("abcdefghij"), 9, 2, -9); + test(S("abcdefghijklmnopqrst"), 0, 19, SV("abcdefghij"), 10, 0, 19); + test(S("abcdefghijklmnopqrst"), 0, 19, SV("abcdefghij"), 10, 1, 19); + test(S("abcdefghijklmnopqrst"), 0, 19, SV("abcdefghij"), 11, 0, 0); + test(S("abcdefghijklmnopqrst"), 0, 19, SV("abcdefghijklmnopqrst"), 0, 0, 19); + test(S("abcdefghijklmnopqrst"), 0, 19, SV("abcdefghijklmnopqrst"), 0, 1, 18); + test(S("abcdefghijklmnopqrst"), 0, 19, SV("abcdefghijklmnopqrst"), 0, 10, 9); + test(S("abcdefghijklmnopqrst"), 0, 19, SV("abcdefghijklmnopqrst"), 0, 19, 0); + test(S("abcdefghijklmnopqrst"), 0, 19, SV("abcdefghijklmnopqrst"), 0, 20, -1); + test(S("abcdefghijklmnopqrst"), 0, 19, SV("abcdefghijklmnopqrst"), 0, 21, -1); + test(S("abcdefghijklmnopqrst"), 0, 19, SV("abcdefghijklmnopqrst"), 1, 0, 19); + test(S("abcdefghijklmnopqrst"), 0, 19, SV("abcdefghijklmnopqrst"), 1, 1, -1); + test(S("abcdefghijklmnopqrst"), 0, 19, SV("abcdefghijklmnopqrst"), 1, 9, -1); + test(S("abcdefghijklmnopqrst"), 0, 19, SV("abcdefghijklmnopqrst"), 1, 18, -1); + test(S("abcdefghijklmnopqrst"), 0, 19, SV("abcdefghijklmnopqrst"), 1, 19, -1); + test(S("abcdefghijklmnopqrst"), 0, 19, SV("abcdefghijklmnopqrst"), 1, 20, -1); + test(S("abcdefghijklmnopqrst"), 0, 19, SV("abcdefghijklmnopqrst"), 10, 0, 19); + test(S("abcdefghijklmnopqrst"), 0, 19, SV("abcdefghijklmnopqrst"), 10, 1, -10); + test(S("abcdefghijklmnopqrst"), 0, 19, SV("abcdefghijklmnopqrst"), 10, 5, -10); + test(S("abcdefghijklmnopqrst"), 0, 19, SV("abcdefghijklmnopqrst"), 10, 9, -10); + test(S("abcdefghijklmnopqrst"), 0, 19, SV("abcdefghijklmnopqrst"), 10, 10, -10); + test(S("abcdefghijklmnopqrst"), 0, 19, SV("abcdefghijklmnopqrst"), 10, 11, -10); + test(S("abcdefghijklmnopqrst"), 0, 19, SV("abcdefghijklmnopqrst"), 19, 0, 19); + test(S("abcdefghijklmnopqrst"), 0, 19, SV("abcdefghijklmnopqrst"), 19, 1, -19); + test(S("abcdefghijklmnopqrst"), 0, 19, SV("abcdefghijklmnopqrst"), 19, 2, -19); + test(S("abcdefghijklmnopqrst"), 0, 19, SV("abcdefghijklmnopqrst"), 20, 0, 19); + test(S("abcdefghijklmnopqrst"), 0, 19, SV("abcdefghijklmnopqrst"), 20, 1, 19); + test(S("abcdefghijklmnopqrst"), 0, 19, SV("abcdefghijklmnopqrst"), 21, 0, 0); + test(S("abcdefghijklmnopqrst"), 0, 20, SV(""), 0, 0, 20); + test(S("abcdefghijklmnopqrst"), 0, 20, SV(""), 0, 1, 20); + test(S("abcdefghijklmnopqrst"), 0, 20, SV(""), 1, 0, 0); + test(S("abcdefghijklmnopqrst"), 0, 20, SV("abcde"), 0, 0, 20); +} + +template +void test40() +{ + test(S("abcdefghijklmnopqrst"), 0, 20, SV("abcde"), 0, 1, 19); + test(S("abcdefghijklmnopqrst"), 0, 20, SV("abcde"), 0, 2, 18); + test(S("abcdefghijklmnopqrst"), 0, 20, SV("abcde"), 0, 4, 16); + test(S("abcdefghijklmnopqrst"), 0, 20, SV("abcde"), 0, 5, 15); + test(S("abcdefghijklmnopqrst"), 0, 20, SV("abcde"), 0, 6, 15); + test(S("abcdefghijklmnopqrst"), 0, 20, SV("abcde"), 1, 0, 20); + test(S("abcdefghijklmnopqrst"), 0, 20, SV("abcde"), 1, 1, -1); + test(S("abcdefghijklmnopqrst"), 0, 20, SV("abcde"), 1, 2, -1); + test(S("abcdefghijklmnopqrst"), 0, 20, SV("abcde"), 1, 3, -1); + test(S("abcdefghijklmnopqrst"), 0, 20, SV("abcde"), 1, 4, -1); + test(S("abcdefghijklmnopqrst"), 0, 20, SV("abcde"), 1, 5, -1); + test(S("abcdefghijklmnopqrst"), 0, 20, SV("abcde"), 2, 0, 20); + test(S("abcdefghijklmnopqrst"), 0, 20, SV("abcde"), 2, 1, -2); + test(S("abcdefghijklmnopqrst"), 0, 20, SV("abcde"), 2, 2, -2); + test(S("abcdefghijklmnopqrst"), 0, 20, SV("abcde"), 2, 3, -2); + test(S("abcdefghijklmnopqrst"), 0, 20, SV("abcde"), 2, 4, -2); + test(S("abcdefghijklmnopqrst"), 0, 20, SV("abcde"), 4, 0, 20); + test(S("abcdefghijklmnopqrst"), 0, 20, SV("abcde"), 4, 1, -4); + test(S("abcdefghijklmnopqrst"), 0, 20, SV("abcde"), 4, 2, -4); + test(S("abcdefghijklmnopqrst"), 0, 20, SV("abcde"), 5, 0, 20); + test(S("abcdefghijklmnopqrst"), 0, 20, SV("abcde"), 5, 1, 20); + test(S("abcdefghijklmnopqrst"), 0, 20, SV("abcde"), 6, 0, 0); + test(S("abcdefghijklmnopqrst"), 0, 20, SV("abcdefghij"), 0, 0, 20); + test(S("abcdefghijklmnopqrst"), 0, 20, SV("abcdefghij"), 0, 1, 19); + test(S("abcdefghijklmnopqrst"), 0, 20, SV("abcdefghij"), 0, 5, 15); + test(S("abcdefghijklmnopqrst"), 0, 20, SV("abcdefghij"), 0, 9, 11); + test(S("abcdefghijklmnopqrst"), 0, 20, SV("abcdefghij"), 0, 10, 10); + test(S("abcdefghijklmnopqrst"), 0, 20, SV("abcdefghij"), 0, 11, 10); + test(S("abcdefghijklmnopqrst"), 0, 20, SV("abcdefghij"), 1, 0, 20); + test(S("abcdefghijklmnopqrst"), 0, 20, SV("abcdefghij"), 1, 1, -1); + test(S("abcdefghijklmnopqrst"), 0, 20, SV("abcdefghij"), 1, 4, -1); + test(S("abcdefghijklmnopqrst"), 0, 20, SV("abcdefghij"), 1, 8, -1); + test(S("abcdefghijklmnopqrst"), 0, 20, SV("abcdefghij"), 1, 9, -1); + test(S("abcdefghijklmnopqrst"), 0, 20, SV("abcdefghij"), 1, 10, -1); + test(S("abcdefghijklmnopqrst"), 0, 20, SV("abcdefghij"), 5, 0, 20); + test(S("abcdefghijklmnopqrst"), 0, 20, SV("abcdefghij"), 5, 1, -5); + test(S("abcdefghijklmnopqrst"), 0, 20, SV("abcdefghij"), 5, 2, -5); + test(S("abcdefghijklmnopqrst"), 0, 20, SV("abcdefghij"), 5, 4, -5); + test(S("abcdefghijklmnopqrst"), 0, 20, SV("abcdefghij"), 5, 5, -5); + test(S("abcdefghijklmnopqrst"), 0, 20, SV("abcdefghij"), 5, 6, -5); + test(S("abcdefghijklmnopqrst"), 0, 20, SV("abcdefghij"), 9, 0, 20); + test(S("abcdefghijklmnopqrst"), 0, 20, SV("abcdefghij"), 9, 1, -9); + test(S("abcdefghijklmnopqrst"), 0, 20, SV("abcdefghij"), 9, 2, -9); + test(S("abcdefghijklmnopqrst"), 0, 20, SV("abcdefghij"), 10, 0, 20); + test(S("abcdefghijklmnopqrst"), 0, 20, SV("abcdefghij"), 10, 1, 20); + test(S("abcdefghijklmnopqrst"), 0, 20, SV("abcdefghij"), 11, 0, 0); + test(S("abcdefghijklmnopqrst"), 0, 20, SV("abcdefghijklmnopqrst"), 0, 0, 20); + test(S("abcdefghijklmnopqrst"), 0, 20, SV("abcdefghijklmnopqrst"), 0, 1, 19); + test(S("abcdefghijklmnopqrst"), 0, 20, SV("abcdefghijklmnopqrst"), 0, 10, 10); + test(S("abcdefghijklmnopqrst"), 0, 20, SV("abcdefghijklmnopqrst"), 0, 19, 1); + test(S("abcdefghijklmnopqrst"), 0, 20, SV("abcdefghijklmnopqrst"), 0, 20, 0); + test(S("abcdefghijklmnopqrst"), 0, 20, SV("abcdefghijklmnopqrst"), 0, 21, 0); + test(S("abcdefghijklmnopqrst"), 0, 20, SV("abcdefghijklmnopqrst"), 1, 0, 20); + test(S("abcdefghijklmnopqrst"), 0, 20, SV("abcdefghijklmnopqrst"), 1, 1, -1); + test(S("abcdefghijklmnopqrst"), 0, 20, SV("abcdefghijklmnopqrst"), 1, 9, -1); + test(S("abcdefghijklmnopqrst"), 0, 20, SV("abcdefghijklmnopqrst"), 1, 18, -1); + test(S("abcdefghijklmnopqrst"), 0, 20, SV("abcdefghijklmnopqrst"), 1, 19, -1); + test(S("abcdefghijklmnopqrst"), 0, 20, SV("abcdefghijklmnopqrst"), 1, 20, -1); + test(S("abcdefghijklmnopqrst"), 0, 20, SV("abcdefghijklmnopqrst"), 10, 0, 20); + test(S("abcdefghijklmnopqrst"), 0, 20, SV("abcdefghijklmnopqrst"), 10, 1, -10); + test(S("abcdefghijklmnopqrst"), 0, 20, SV("abcdefghijklmnopqrst"), 10, 5, -10); + test(S("abcdefghijklmnopqrst"), 0, 20, SV("abcdefghijklmnopqrst"), 10, 9, -10); + test(S("abcdefghijklmnopqrst"), 0, 20, SV("abcdefghijklmnopqrst"), 10, 10, -10); + test(S("abcdefghijklmnopqrst"), 0, 20, SV("abcdefghijklmnopqrst"), 10, 11, -10); + test(S("abcdefghijklmnopqrst"), 0, 20, SV("abcdefghijklmnopqrst"), 19, 0, 20); + test(S("abcdefghijklmnopqrst"), 0, 20, SV("abcdefghijklmnopqrst"), 19, 1, -19); + test(S("abcdefghijklmnopqrst"), 0, 20, SV("abcdefghijklmnopqrst"), 19, 2, -19); + test(S("abcdefghijklmnopqrst"), 0, 20, SV("abcdefghijklmnopqrst"), 20, 0, 20); + test(S("abcdefghijklmnopqrst"), 0, 20, SV("abcdefghijklmnopqrst"), 20, 1, 20); + test(S("abcdefghijklmnopqrst"), 0, 20, SV("abcdefghijklmnopqrst"), 21, 0, 0); + test(S("abcdefghijklmnopqrst"), 0, 21, SV(""), 0, 0, 20); + test(S("abcdefghijklmnopqrst"), 0, 21, SV(""), 0, 1, 20); + test(S("abcdefghijklmnopqrst"), 0, 21, SV(""), 1, 0, 0); + test(S("abcdefghijklmnopqrst"), 0, 21, SV("abcde"), 0, 0, 20); + test(S("abcdefghijklmnopqrst"), 0, 21, SV("abcde"), 0, 1, 19); + test(S("abcdefghijklmnopqrst"), 0, 21, SV("abcde"), 0, 2, 18); + test(S("abcdefghijklmnopqrst"), 0, 21, SV("abcde"), 0, 4, 16); + test(S("abcdefghijklmnopqrst"), 0, 21, SV("abcde"), 0, 5, 15); + test(S("abcdefghijklmnopqrst"), 0, 21, SV("abcde"), 0, 6, 15); + test(S("abcdefghijklmnopqrst"), 0, 21, SV("abcde"), 1, 0, 20); + test(S("abcdefghijklmnopqrst"), 0, 21, SV("abcde"), 1, 1, -1); + test(S("abcdefghijklmnopqrst"), 0, 21, SV("abcde"), 1, 2, -1); + test(S("abcdefghijklmnopqrst"), 0, 21, SV("abcde"), 1, 3, -1); + test(S("abcdefghijklmnopqrst"), 0, 21, SV("abcde"), 1, 4, -1); + test(S("abcdefghijklmnopqrst"), 0, 21, SV("abcde"), 1, 5, -1); + test(S("abcdefghijklmnopqrst"), 0, 21, SV("abcde"), 2, 0, 20); + test(S("abcdefghijklmnopqrst"), 0, 21, SV("abcde"), 2, 1, -2); + test(S("abcdefghijklmnopqrst"), 0, 21, SV("abcde"), 2, 2, -2); + test(S("abcdefghijklmnopqrst"), 0, 21, SV("abcde"), 2, 3, -2); + test(S("abcdefghijklmnopqrst"), 0, 21, SV("abcde"), 2, 4, -2); + test(S("abcdefghijklmnopqrst"), 0, 21, SV("abcde"), 4, 0, 20); + test(S("abcdefghijklmnopqrst"), 0, 21, SV("abcde"), 4, 1, -4); + test(S("abcdefghijklmnopqrst"), 0, 21, SV("abcde"), 4, 2, -4); + test(S("abcdefghijklmnopqrst"), 0, 21, SV("abcde"), 5, 0, 20); + test(S("abcdefghijklmnopqrst"), 0, 21, SV("abcde"), 5, 1, 20); + test(S("abcdefghijklmnopqrst"), 0, 21, SV("abcde"), 6, 0, 0); + test(S("abcdefghijklmnopqrst"), 0, 21, SV("abcdefghij"), 0, 0, 20); + test(S("abcdefghijklmnopqrst"), 0, 21, SV("abcdefghij"), 0, 1, 19); + test(S("abcdefghijklmnopqrst"), 0, 21, SV("abcdefghij"), 0, 5, 15); + test(S("abcdefghijklmnopqrst"), 0, 21, SV("abcdefghij"), 0, 9, 11); +} + +template +void test41() +{ + test(S("abcdefghijklmnopqrst"), 0, 21, SV("abcdefghij"), 0, 10, 10); + test(S("abcdefghijklmnopqrst"), 0, 21, SV("abcdefghij"), 0, 11, 10); + test(S("abcdefghijklmnopqrst"), 0, 21, SV("abcdefghij"), 1, 0, 20); + test(S("abcdefghijklmnopqrst"), 0, 21, SV("abcdefghij"), 1, 1, -1); + test(S("abcdefghijklmnopqrst"), 0, 21, SV("abcdefghij"), 1, 4, -1); + test(S("abcdefghijklmnopqrst"), 0, 21, SV("abcdefghij"), 1, 8, -1); + test(S("abcdefghijklmnopqrst"), 0, 21, SV("abcdefghij"), 1, 9, -1); + test(S("abcdefghijklmnopqrst"), 0, 21, SV("abcdefghij"), 1, 10, -1); + test(S("abcdefghijklmnopqrst"), 0, 21, SV("abcdefghij"), 5, 0, 20); + test(S("abcdefghijklmnopqrst"), 0, 21, SV("abcdefghij"), 5, 1, -5); + test(S("abcdefghijklmnopqrst"), 0, 21, SV("abcdefghij"), 5, 2, -5); + test(S("abcdefghijklmnopqrst"), 0, 21, SV("abcdefghij"), 5, 4, -5); + test(S("abcdefghijklmnopqrst"), 0, 21, SV("abcdefghij"), 5, 5, -5); + test(S("abcdefghijklmnopqrst"), 0, 21, SV("abcdefghij"), 5, 6, -5); + test(S("abcdefghijklmnopqrst"), 0, 21, SV("abcdefghij"), 9, 0, 20); + test(S("abcdefghijklmnopqrst"), 0, 21, SV("abcdefghij"), 9, 1, -9); + test(S("abcdefghijklmnopqrst"), 0, 21, SV("abcdefghij"), 9, 2, -9); + test(S("abcdefghijklmnopqrst"), 0, 21, SV("abcdefghij"), 10, 0, 20); + test(S("abcdefghijklmnopqrst"), 0, 21, SV("abcdefghij"), 10, 1, 20); + test(S("abcdefghijklmnopqrst"), 0, 21, SV("abcdefghij"), 11, 0, 0); + test(S("abcdefghijklmnopqrst"), 0, 21, SV("abcdefghijklmnopqrst"), 0, 0, 20); + test(S("abcdefghijklmnopqrst"), 0, 21, SV("abcdefghijklmnopqrst"), 0, 1, 19); + test(S("abcdefghijklmnopqrst"), 0, 21, SV("abcdefghijklmnopqrst"), 0, 10, 10); + test(S("abcdefghijklmnopqrst"), 0, 21, SV("abcdefghijklmnopqrst"), 0, 19, 1); + test(S("abcdefghijklmnopqrst"), 0, 21, SV("abcdefghijklmnopqrst"), 0, 20, 0); + test(S("abcdefghijklmnopqrst"), 0, 21, SV("abcdefghijklmnopqrst"), 0, 21, 0); + test(S("abcdefghijklmnopqrst"), 0, 21, SV("abcdefghijklmnopqrst"), 1, 0, 20); + test(S("abcdefghijklmnopqrst"), 0, 21, SV("abcdefghijklmnopqrst"), 1, 1, -1); + test(S("abcdefghijklmnopqrst"), 0, 21, SV("abcdefghijklmnopqrst"), 1, 9, -1); + test(S("abcdefghijklmnopqrst"), 0, 21, SV("abcdefghijklmnopqrst"), 1, 18, -1); + test(S("abcdefghijklmnopqrst"), 0, 21, SV("abcdefghijklmnopqrst"), 1, 19, -1); + test(S("abcdefghijklmnopqrst"), 0, 21, SV("abcdefghijklmnopqrst"), 1, 20, -1); + test(S("abcdefghijklmnopqrst"), 0, 21, SV("abcdefghijklmnopqrst"), 10, 0, 20); + test(S("abcdefghijklmnopqrst"), 0, 21, SV("abcdefghijklmnopqrst"), 10, 1, -10); + test(S("abcdefghijklmnopqrst"), 0, 21, SV("abcdefghijklmnopqrst"), 10, 5, -10); + test(S("abcdefghijklmnopqrst"), 0, 21, SV("abcdefghijklmnopqrst"), 10, 9, -10); + test(S("abcdefghijklmnopqrst"), 0, 21, SV("abcdefghijklmnopqrst"), 10, 10, -10); + test(S("abcdefghijklmnopqrst"), 0, 21, SV("abcdefghijklmnopqrst"), 10, 11, -10); + test(S("abcdefghijklmnopqrst"), 0, 21, SV("abcdefghijklmnopqrst"), 19, 0, 20); + test(S("abcdefghijklmnopqrst"), 0, 21, SV("abcdefghijklmnopqrst"), 19, 1, -19); + test(S("abcdefghijklmnopqrst"), 0, 21, SV("abcdefghijklmnopqrst"), 19, 2, -19); + test(S("abcdefghijklmnopqrst"), 0, 21, SV("abcdefghijklmnopqrst"), 20, 0, 20); + test(S("abcdefghijklmnopqrst"), 0, 21, SV("abcdefghijklmnopqrst"), 20, 1, 20); + test(S("abcdefghijklmnopqrst"), 0, 21, SV("abcdefghijklmnopqrst"), 21, 0, 0); + test(S("abcdefghijklmnopqrst"), 1, 0, SV(""), 0, 0, 0); + test(S("abcdefghijklmnopqrst"), 1, 0, SV(""), 0, 1, 0); + test(S("abcdefghijklmnopqrst"), 1, 0, SV(""), 1, 0, 0); + test(S("abcdefghijklmnopqrst"), 1, 0, SV("abcde"), 0, 0, 0); + test(S("abcdefghijklmnopqrst"), 1, 0, SV("abcde"), 0, 1, -1); + test(S("abcdefghijklmnopqrst"), 1, 0, SV("abcde"), 0, 2, -2); + test(S("abcdefghijklmnopqrst"), 1, 0, SV("abcde"), 0, 4, -4); + test(S("abcdefghijklmnopqrst"), 1, 0, SV("abcde"), 0, 5, -5); + test(S("abcdefghijklmnopqrst"), 1, 0, SV("abcde"), 0, 6, -5); + test(S("abcdefghijklmnopqrst"), 1, 0, SV("abcde"), 1, 0, 0); + test(S("abcdefghijklmnopqrst"), 1, 0, SV("abcde"), 1, 1, -1); + test(S("abcdefghijklmnopqrst"), 1, 0, SV("abcde"), 1, 2, -2); + test(S("abcdefghijklmnopqrst"), 1, 0, SV("abcde"), 1, 3, -3); + test(S("abcdefghijklmnopqrst"), 1, 0, SV("abcde"), 1, 4, -4); + test(S("abcdefghijklmnopqrst"), 1, 0, SV("abcde"), 1, 5, -4); + test(S("abcdefghijklmnopqrst"), 1, 0, SV("abcde"), 2, 0, 0); + test(S("abcdefghijklmnopqrst"), 1, 0, SV("abcde"), 2, 1, -1); + test(S("abcdefghijklmnopqrst"), 1, 0, SV("abcde"), 2, 2, -2); + test(S("abcdefghijklmnopqrst"), 1, 0, SV("abcde"), 2, 3, -3); + test(S("abcdefghijklmnopqrst"), 1, 0, SV("abcde"), 2, 4, -3); + test(S("abcdefghijklmnopqrst"), 1, 0, SV("abcde"), 4, 0, 0); + test(S("abcdefghijklmnopqrst"), 1, 0, SV("abcde"), 4, 1, -1); + test(S("abcdefghijklmnopqrst"), 1, 0, SV("abcde"), 4, 2, -1); + test(S("abcdefghijklmnopqrst"), 1, 0, SV("abcde"), 5, 0, 0); + test(S("abcdefghijklmnopqrst"), 1, 0, SV("abcde"), 5, 1, 0); + test(S("abcdefghijklmnopqrst"), 1, 0, SV("abcde"), 6, 0, 0); + test(S("abcdefghijklmnopqrst"), 1, 0, SV("abcdefghij"), 0, 0, 0); + test(S("abcdefghijklmnopqrst"), 1, 0, SV("abcdefghij"), 0, 1, -1); + test(S("abcdefghijklmnopqrst"), 1, 0, SV("abcdefghij"), 0, 5, -5); + test(S("abcdefghijklmnopqrst"), 1, 0, SV("abcdefghij"), 0, 9, -9); + test(S("abcdefghijklmnopqrst"), 1, 0, SV("abcdefghij"), 0, 10, -10); + test(S("abcdefghijklmnopqrst"), 1, 0, SV("abcdefghij"), 0, 11, -10); + test(S("abcdefghijklmnopqrst"), 1, 0, SV("abcdefghij"), 1, 0, 0); + test(S("abcdefghijklmnopqrst"), 1, 0, SV("abcdefghij"), 1, 1, -1); + test(S("abcdefghijklmnopqrst"), 1, 0, SV("abcdefghij"), 1, 4, -4); + test(S("abcdefghijklmnopqrst"), 1, 0, SV("abcdefghij"), 1, 8, -8); + test(S("abcdefghijklmnopqrst"), 1, 0, SV("abcdefghij"), 1, 9, -9); + test(S("abcdefghijklmnopqrst"), 1, 0, SV("abcdefghij"), 1, 10, -9); + test(S("abcdefghijklmnopqrst"), 1, 0, SV("abcdefghij"), 5, 0, 0); + test(S("abcdefghijklmnopqrst"), 1, 0, SV("abcdefghij"), 5, 1, -1); + test(S("abcdefghijklmnopqrst"), 1, 0, SV("abcdefghij"), 5, 2, -2); + test(S("abcdefghijklmnopqrst"), 1, 0, SV("abcdefghij"), 5, 4, -4); + test(S("abcdefghijklmnopqrst"), 1, 0, SV("abcdefghij"), 5, 5, -5); + test(S("abcdefghijklmnopqrst"), 1, 0, SV("abcdefghij"), 5, 6, -5); + test(S("abcdefghijklmnopqrst"), 1, 0, SV("abcdefghij"), 9, 0, 0); + test(S("abcdefghijklmnopqrst"), 1, 0, SV("abcdefghij"), 9, 1, -1); + test(S("abcdefghijklmnopqrst"), 1, 0, SV("abcdefghij"), 9, 2, -1); + test(S("abcdefghijklmnopqrst"), 1, 0, SV("abcdefghij"), 10, 0, 0); + test(S("abcdefghijklmnopqrst"), 1, 0, SV("abcdefghij"), 10, 1, 0); + test(S("abcdefghijklmnopqrst"), 1, 0, SV("abcdefghij"), 11, 0, 0); + test(S("abcdefghijklmnopqrst"), 1, 0, SV("abcdefghijklmnopqrst"), 0, 0, 0); + test(S("abcdefghijklmnopqrst"), 1, 0, SV("abcdefghijklmnopqrst"), 0, 1, -1); + test(S("abcdefghijklmnopqrst"), 1, 0, SV("abcdefghijklmnopqrst"), 0, 10, -10); + test(S("abcdefghijklmnopqrst"), 1, 0, SV("abcdefghijklmnopqrst"), 0, 19, -19); + test(S("abcdefghijklmnopqrst"), 1, 0, SV("abcdefghijklmnopqrst"), 0, 20, -20); + test(S("abcdefghijklmnopqrst"), 1, 0, SV("abcdefghijklmnopqrst"), 0, 21, -20); +} + +template +void test42() +{ + test(S("abcdefghijklmnopqrst"), 1, 0, SV("abcdefghijklmnopqrst"), 1, 0, 0); + test(S("abcdefghijklmnopqrst"), 1, 0, SV("abcdefghijklmnopqrst"), 1, 1, -1); + test(S("abcdefghijklmnopqrst"), 1, 0, SV("abcdefghijklmnopqrst"), 1, 9, -9); + test(S("abcdefghijklmnopqrst"), 1, 0, SV("abcdefghijklmnopqrst"), 1, 18, -18); + test(S("abcdefghijklmnopqrst"), 1, 0, SV("abcdefghijklmnopqrst"), 1, 19, -19); + test(S("abcdefghijklmnopqrst"), 1, 0, SV("abcdefghijklmnopqrst"), 1, 20, -19); + test(S("abcdefghijklmnopqrst"), 1, 0, SV("abcdefghijklmnopqrst"), 10, 0, 0); + test(S("abcdefghijklmnopqrst"), 1, 0, SV("abcdefghijklmnopqrst"), 10, 1, -1); + test(S("abcdefghijklmnopqrst"), 1, 0, SV("abcdefghijklmnopqrst"), 10, 5, -5); + test(S("abcdefghijklmnopqrst"), 1, 0, SV("abcdefghijklmnopqrst"), 10, 9, -9); + test(S("abcdefghijklmnopqrst"), 1, 0, SV("abcdefghijklmnopqrst"), 10, 10, -10); + test(S("abcdefghijklmnopqrst"), 1, 0, SV("abcdefghijklmnopqrst"), 10, 11, -10); + test(S("abcdefghijklmnopqrst"), 1, 0, SV("abcdefghijklmnopqrst"), 19, 0, 0); + test(S("abcdefghijklmnopqrst"), 1, 0, SV("abcdefghijklmnopqrst"), 19, 1, -1); + test(S("abcdefghijklmnopqrst"), 1, 0, SV("abcdefghijklmnopqrst"), 19, 2, -1); + test(S("abcdefghijklmnopqrst"), 1, 0, SV("abcdefghijklmnopqrst"), 20, 0, 0); + test(S("abcdefghijklmnopqrst"), 1, 0, SV("abcdefghijklmnopqrst"), 20, 1, 0); + test(S("abcdefghijklmnopqrst"), 1, 0, SV("abcdefghijklmnopqrst"), 21, 0, 0); + test(S("abcdefghijklmnopqrst"), 1, 1, SV(""), 0, 0, 1); + test(S("abcdefghijklmnopqrst"), 1, 1, SV(""), 0, 1, 1); + test(S("abcdefghijklmnopqrst"), 1, 1, SV(""), 1, 0, 0); + test(S("abcdefghijklmnopqrst"), 1, 1, SV("abcde"), 0, 0, 1); + test(S("abcdefghijklmnopqrst"), 1, 1, SV("abcde"), 0, 1, 1); + test(S("abcdefghijklmnopqrst"), 1, 1, SV("abcde"), 0, 2, 1); + test(S("abcdefghijklmnopqrst"), 1, 1, SV("abcde"), 0, 4, 1); + test(S("abcdefghijklmnopqrst"), 1, 1, SV("abcde"), 0, 5, 1); + test(S("abcdefghijklmnopqrst"), 1, 1, SV("abcde"), 0, 6, 1); + test(S("abcdefghijklmnopqrst"), 1, 1, SV("abcde"), 1, 0, 1); + test(S("abcdefghijklmnopqrst"), 1, 1, SV("abcde"), 1, 1, 0); + test(S("abcdefghijklmnopqrst"), 1, 1, SV("abcde"), 1, 2, -1); + test(S("abcdefghijklmnopqrst"), 1, 1, SV("abcde"), 1, 3, -2); + test(S("abcdefghijklmnopqrst"), 1, 1, SV("abcde"), 1, 4, -3); + test(S("abcdefghijklmnopqrst"), 1, 1, SV("abcde"), 1, 5, -3); + test(S("abcdefghijklmnopqrst"), 1, 1, SV("abcde"), 2, 0, 1); + test(S("abcdefghijklmnopqrst"), 1, 1, SV("abcde"), 2, 1, -1); + test(S("abcdefghijklmnopqrst"), 1, 1, SV("abcde"), 2, 2, -1); + test(S("abcdefghijklmnopqrst"), 1, 1, SV("abcde"), 2, 3, -1); + test(S("abcdefghijklmnopqrst"), 1, 1, SV("abcde"), 2, 4, -1); + test(S("abcdefghijklmnopqrst"), 1, 1, SV("abcde"), 4, 0, 1); + test(S("abcdefghijklmnopqrst"), 1, 1, SV("abcde"), 4, 1, -3); + test(S("abcdefghijklmnopqrst"), 1, 1, SV("abcde"), 4, 2, -3); + test(S("abcdefghijklmnopqrst"), 1, 1, SV("abcde"), 5, 0, 1); + test(S("abcdefghijklmnopqrst"), 1, 1, SV("abcde"), 5, 1, 1); + test(S("abcdefghijklmnopqrst"), 1, 1, SV("abcde"), 6, 0, 0); + test(S("abcdefghijklmnopqrst"), 1, 1, SV("abcdefghij"), 0, 0, 1); + test(S("abcdefghijklmnopqrst"), 1, 1, SV("abcdefghij"), 0, 1, 1); + test(S("abcdefghijklmnopqrst"), 1, 1, SV("abcdefghij"), 0, 5, 1); + test(S("abcdefghijklmnopqrst"), 1, 1, SV("abcdefghij"), 0, 9, 1); + test(S("abcdefghijklmnopqrst"), 1, 1, SV("abcdefghij"), 0, 10, 1); + test(S("abcdefghijklmnopqrst"), 1, 1, SV("abcdefghij"), 0, 11, 1); + test(S("abcdefghijklmnopqrst"), 1, 1, SV("abcdefghij"), 1, 0, 1); + test(S("abcdefghijklmnopqrst"), 1, 1, SV("abcdefghij"), 1, 1, 0); + test(S("abcdefghijklmnopqrst"), 1, 1, SV("abcdefghij"), 1, 4, -3); + test(S("abcdefghijklmnopqrst"), 1, 1, SV("abcdefghij"), 1, 8, -7); + test(S("abcdefghijklmnopqrst"), 1, 1, SV("abcdefghij"), 1, 9, -8); + test(S("abcdefghijklmnopqrst"), 1, 1, SV("abcdefghij"), 1, 10, -8); + test(S("abcdefghijklmnopqrst"), 1, 1, SV("abcdefghij"), 5, 0, 1); + test(S("abcdefghijklmnopqrst"), 1, 1, SV("abcdefghij"), 5, 1, -4); + test(S("abcdefghijklmnopqrst"), 1, 1, SV("abcdefghij"), 5, 2, -4); + test(S("abcdefghijklmnopqrst"), 1, 1, SV("abcdefghij"), 5, 4, -4); + test(S("abcdefghijklmnopqrst"), 1, 1, SV("abcdefghij"), 5, 5, -4); + test(S("abcdefghijklmnopqrst"), 1, 1, SV("abcdefghij"), 5, 6, -4); + test(S("abcdefghijklmnopqrst"), 1, 1, SV("abcdefghij"), 9, 0, 1); + test(S("abcdefghijklmnopqrst"), 1, 1, SV("abcdefghij"), 9, 1, -8); + test(S("abcdefghijklmnopqrst"), 1, 1, SV("abcdefghij"), 9, 2, -8); + test(S("abcdefghijklmnopqrst"), 1, 1, SV("abcdefghij"), 10, 0, 1); + test(S("abcdefghijklmnopqrst"), 1, 1, SV("abcdefghij"), 10, 1, 1); + test(S("abcdefghijklmnopqrst"), 1, 1, SV("abcdefghij"), 11, 0, 0); + test(S("abcdefghijklmnopqrst"), 1, 1, SV("abcdefghijklmnopqrst"), 0, 0, 1); + test(S("abcdefghijklmnopqrst"), 1, 1, SV("abcdefghijklmnopqrst"), 0, 1, 1); + test(S("abcdefghijklmnopqrst"), 1, 1, SV("abcdefghijklmnopqrst"), 0, 10, 1); + test(S("abcdefghijklmnopqrst"), 1, 1, SV("abcdefghijklmnopqrst"), 0, 19, 1); + test(S("abcdefghijklmnopqrst"), 1, 1, SV("abcdefghijklmnopqrst"), 0, 20, 1); + test(S("abcdefghijklmnopqrst"), 1, 1, SV("abcdefghijklmnopqrst"), 0, 21, 1); + test(S("abcdefghijklmnopqrst"), 1, 1, SV("abcdefghijklmnopqrst"), 1, 0, 1); + test(S("abcdefghijklmnopqrst"), 1, 1, SV("abcdefghijklmnopqrst"), 1, 1, 0); + test(S("abcdefghijklmnopqrst"), 1, 1, SV("abcdefghijklmnopqrst"), 1, 9, -8); + test(S("abcdefghijklmnopqrst"), 1, 1, SV("abcdefghijklmnopqrst"), 1, 18, -17); + test(S("abcdefghijklmnopqrst"), 1, 1, SV("abcdefghijklmnopqrst"), 1, 19, -18); + test(S("abcdefghijklmnopqrst"), 1, 1, SV("abcdefghijklmnopqrst"), 1, 20, -18); + test(S("abcdefghijklmnopqrst"), 1, 1, SV("abcdefghijklmnopqrst"), 10, 0, 1); + test(S("abcdefghijklmnopqrst"), 1, 1, SV("abcdefghijklmnopqrst"), 10, 1, -9); + test(S("abcdefghijklmnopqrst"), 1, 1, SV("abcdefghijklmnopqrst"), 10, 5, -9); + test(S("abcdefghijklmnopqrst"), 1, 1, SV("abcdefghijklmnopqrst"), 10, 9, -9); + test(S("abcdefghijklmnopqrst"), 1, 1, SV("abcdefghijklmnopqrst"), 10, 10, -9); + test(S("abcdefghijklmnopqrst"), 1, 1, SV("abcdefghijklmnopqrst"), 10, 11, -9); + test(S("abcdefghijklmnopqrst"), 1, 1, SV("abcdefghijklmnopqrst"), 19, 0, 1); + test(S("abcdefghijklmnopqrst"), 1, 1, SV("abcdefghijklmnopqrst"), 19, 1, -18); + test(S("abcdefghijklmnopqrst"), 1, 1, SV("abcdefghijklmnopqrst"), 19, 2, -18); + test(S("abcdefghijklmnopqrst"), 1, 1, SV("abcdefghijklmnopqrst"), 20, 0, 1); + test(S("abcdefghijklmnopqrst"), 1, 1, SV("abcdefghijklmnopqrst"), 20, 1, 1); + test(S("abcdefghijklmnopqrst"), 1, 1, SV("abcdefghijklmnopqrst"), 21, 0, 0); + test(S("abcdefghijklmnopqrst"), 1, 9, SV(""), 0, 0, 9); + test(S("abcdefghijklmnopqrst"), 1, 9, SV(""), 0, 1, 9); + test(S("abcdefghijklmnopqrst"), 1, 9, SV(""), 1, 0, 0); + test(S("abcdefghijklmnopqrst"), 1, 9, SV("abcde"), 0, 0, 9); + test(S("abcdefghijklmnopqrst"), 1, 9, SV("abcde"), 0, 1, 1); + test(S("abcdefghijklmnopqrst"), 1, 9, SV("abcde"), 0, 2, 1); + test(S("abcdefghijklmnopqrst"), 1, 9, SV("abcde"), 0, 4, 1); + test(S("abcdefghijklmnopqrst"), 1, 9, SV("abcde"), 0, 5, 1); +} + +template +void test43() +{ + test(S("abcdefghijklmnopqrst"), 1, 9, SV("abcde"), 0, 6, 1); + test(S("abcdefghijklmnopqrst"), 1, 9, SV("abcde"), 1, 0, 9); + test(S("abcdefghijklmnopqrst"), 1, 9, SV("abcde"), 1, 1, 8); + test(S("abcdefghijklmnopqrst"), 1, 9, SV("abcde"), 1, 2, 7); + test(S("abcdefghijklmnopqrst"), 1, 9, SV("abcde"), 1, 3, 6); + test(S("abcdefghijklmnopqrst"), 1, 9, SV("abcde"), 1, 4, 5); + test(S("abcdefghijklmnopqrst"), 1, 9, SV("abcde"), 1, 5, 5); + test(S("abcdefghijklmnopqrst"), 1, 9, SV("abcde"), 2, 0, 9); + test(S("abcdefghijklmnopqrst"), 1, 9, SV("abcde"), 2, 1, -1); + test(S("abcdefghijklmnopqrst"), 1, 9, SV("abcde"), 2, 2, -1); + test(S("abcdefghijklmnopqrst"), 1, 9, SV("abcde"), 2, 3, -1); + test(S("abcdefghijklmnopqrst"), 1, 9, SV("abcde"), 2, 4, -1); + test(S("abcdefghijklmnopqrst"), 1, 9, SV("abcde"), 4, 0, 9); + test(S("abcdefghijklmnopqrst"), 1, 9, SV("abcde"), 4, 1, -3); + test(S("abcdefghijklmnopqrst"), 1, 9, SV("abcde"), 4, 2, -3); + test(S("abcdefghijklmnopqrst"), 1, 9, SV("abcde"), 5, 0, 9); + test(S("abcdefghijklmnopqrst"), 1, 9, SV("abcde"), 5, 1, 9); + test(S("abcdefghijklmnopqrst"), 1, 9, SV("abcde"), 6, 0, 0); + test(S("abcdefghijklmnopqrst"), 1, 9, SV("abcdefghij"), 0, 0, 9); + test(S("abcdefghijklmnopqrst"), 1, 9, SV("abcdefghij"), 0, 1, 1); + test(S("abcdefghijklmnopqrst"), 1, 9, SV("abcdefghij"), 0, 5, 1); + test(S("abcdefghijklmnopqrst"), 1, 9, SV("abcdefghij"), 0, 9, 1); + test(S("abcdefghijklmnopqrst"), 1, 9, SV("abcdefghij"), 0, 10, 1); + test(S("abcdefghijklmnopqrst"), 1, 9, SV("abcdefghij"), 0, 11, 1); + test(S("abcdefghijklmnopqrst"), 1, 9, SV("abcdefghij"), 1, 0, 9); + test(S("abcdefghijklmnopqrst"), 1, 9, SV("abcdefghij"), 1, 1, 8); + test(S("abcdefghijklmnopqrst"), 1, 9, SV("abcdefghij"), 1, 4, 5); + test(S("abcdefghijklmnopqrst"), 1, 9, SV("abcdefghij"), 1, 8, 1); + test(S("abcdefghijklmnopqrst"), 1, 9, SV("abcdefghij"), 1, 9, 0); + test(S("abcdefghijklmnopqrst"), 1, 9, SV("abcdefghij"), 1, 10, 0); + test(S("abcdefghijklmnopqrst"), 1, 9, SV("abcdefghij"), 5, 0, 9); + test(S("abcdefghijklmnopqrst"), 1, 9, SV("abcdefghij"), 5, 1, -4); + test(S("abcdefghijklmnopqrst"), 1, 9, SV("abcdefghij"), 5, 2, -4); + test(S("abcdefghijklmnopqrst"), 1, 9, SV("abcdefghij"), 5, 4, -4); + test(S("abcdefghijklmnopqrst"), 1, 9, SV("abcdefghij"), 5, 5, -4); + test(S("abcdefghijklmnopqrst"), 1, 9, SV("abcdefghij"), 5, 6, -4); + test(S("abcdefghijklmnopqrst"), 1, 9, SV("abcdefghij"), 9, 0, 9); + test(S("abcdefghijklmnopqrst"), 1, 9, SV("abcdefghij"), 9, 1, -8); + test(S("abcdefghijklmnopqrst"), 1, 9, SV("abcdefghij"), 9, 2, -8); + test(S("abcdefghijklmnopqrst"), 1, 9, SV("abcdefghij"), 10, 0, 9); + test(S("abcdefghijklmnopqrst"), 1, 9, SV("abcdefghij"), 10, 1, 9); + test(S("abcdefghijklmnopqrst"), 1, 9, SV("abcdefghij"), 11, 0, 0); + test(S("abcdefghijklmnopqrst"), 1, 9, SV("abcdefghijklmnopqrst"), 0, 0, 9); + test(S("abcdefghijklmnopqrst"), 1, 9, SV("abcdefghijklmnopqrst"), 0, 1, 1); + test(S("abcdefghijklmnopqrst"), 1, 9, SV("abcdefghijklmnopqrst"), 0, 10, 1); + test(S("abcdefghijklmnopqrst"), 1, 9, SV("abcdefghijklmnopqrst"), 0, 19, 1); + test(S("abcdefghijklmnopqrst"), 1, 9, SV("abcdefghijklmnopqrst"), 0, 20, 1); + test(S("abcdefghijklmnopqrst"), 1, 9, SV("abcdefghijklmnopqrst"), 0, 21, 1); + test(S("abcdefghijklmnopqrst"), 1, 9, SV("abcdefghijklmnopqrst"), 1, 0, 9); + test(S("abcdefghijklmnopqrst"), 1, 9, SV("abcdefghijklmnopqrst"), 1, 1, 8); + test(S("abcdefghijklmnopqrst"), 1, 9, SV("abcdefghijklmnopqrst"), 1, 9, 0); + test(S("abcdefghijklmnopqrst"), 1, 9, SV("abcdefghijklmnopqrst"), 1, 18, -9); + test(S("abcdefghijklmnopqrst"), 1, 9, SV("abcdefghijklmnopqrst"), 1, 19, -10); + test(S("abcdefghijklmnopqrst"), 1, 9, SV("abcdefghijklmnopqrst"), 1, 20, -10); + test(S("abcdefghijklmnopqrst"), 1, 9, SV("abcdefghijklmnopqrst"), 10, 0, 9); + test(S("abcdefghijklmnopqrst"), 1, 9, SV("abcdefghijklmnopqrst"), 10, 1, -9); + test(S("abcdefghijklmnopqrst"), 1, 9, SV("abcdefghijklmnopqrst"), 10, 5, -9); + test(S("abcdefghijklmnopqrst"), 1, 9, SV("abcdefghijklmnopqrst"), 10, 9, -9); + test(S("abcdefghijklmnopqrst"), 1, 9, SV("abcdefghijklmnopqrst"), 10, 10, -9); + test(S("abcdefghijklmnopqrst"), 1, 9, SV("abcdefghijklmnopqrst"), 10, 11, -9); + test(S("abcdefghijklmnopqrst"), 1, 9, SV("abcdefghijklmnopqrst"), 19, 0, 9); + test(S("abcdefghijklmnopqrst"), 1, 9, SV("abcdefghijklmnopqrst"), 19, 1, -18); + test(S("abcdefghijklmnopqrst"), 1, 9, SV("abcdefghijklmnopqrst"), 19, 2, -18); + test(S("abcdefghijklmnopqrst"), 1, 9, SV("abcdefghijklmnopqrst"), 20, 0, 9); + test(S("abcdefghijklmnopqrst"), 1, 9, SV("abcdefghijklmnopqrst"), 20, 1, 9); + test(S("abcdefghijklmnopqrst"), 1, 9, SV("abcdefghijklmnopqrst"), 21, 0, 0); + test(S("abcdefghijklmnopqrst"), 1, 18, SV(""), 0, 0, 18); + test(S("abcdefghijklmnopqrst"), 1, 18, SV(""), 0, 1, 18); + test(S("abcdefghijklmnopqrst"), 1, 18, SV(""), 1, 0, 0); + test(S("abcdefghijklmnopqrst"), 1, 18, SV("abcde"), 0, 0, 18); + test(S("abcdefghijklmnopqrst"), 1, 18, SV("abcde"), 0, 1, 1); + test(S("abcdefghijklmnopqrst"), 1, 18, SV("abcde"), 0, 2, 1); + test(S("abcdefghijklmnopqrst"), 1, 18, SV("abcde"), 0, 4, 1); + test(S("abcdefghijklmnopqrst"), 1, 18, SV("abcde"), 0, 5, 1); + test(S("abcdefghijklmnopqrst"), 1, 18, SV("abcde"), 0, 6, 1); + test(S("abcdefghijklmnopqrst"), 1, 18, SV("abcde"), 1, 0, 18); + test(S("abcdefghijklmnopqrst"), 1, 18, SV("abcde"), 1, 1, 17); + test(S("abcdefghijklmnopqrst"), 1, 18, SV("abcde"), 1, 2, 16); + test(S("abcdefghijklmnopqrst"), 1, 18, SV("abcde"), 1, 3, 15); + test(S("abcdefghijklmnopqrst"), 1, 18, SV("abcde"), 1, 4, 14); + test(S("abcdefghijklmnopqrst"), 1, 18, SV("abcde"), 1, 5, 14); + test(S("abcdefghijklmnopqrst"), 1, 18, SV("abcde"), 2, 0, 18); + test(S("abcdefghijklmnopqrst"), 1, 18, SV("abcde"), 2, 1, -1); + test(S("abcdefghijklmnopqrst"), 1, 18, SV("abcde"), 2, 2, -1); + test(S("abcdefghijklmnopqrst"), 1, 18, SV("abcde"), 2, 3, -1); + test(S("abcdefghijklmnopqrst"), 1, 18, SV("abcde"), 2, 4, -1); + test(S("abcdefghijklmnopqrst"), 1, 18, SV("abcde"), 4, 0, 18); + test(S("abcdefghijklmnopqrst"), 1, 18, SV("abcde"), 4, 1, -3); + test(S("abcdefghijklmnopqrst"), 1, 18, SV("abcde"), 4, 2, -3); + test(S("abcdefghijklmnopqrst"), 1, 18, SV("abcde"), 5, 0, 18); + test(S("abcdefghijklmnopqrst"), 1, 18, SV("abcde"), 5, 1, 18); + test(S("abcdefghijklmnopqrst"), 1, 18, SV("abcde"), 6, 0, 0); + test(S("abcdefghijklmnopqrst"), 1, 18, SV("abcdefghij"), 0, 0, 18); + test(S("abcdefghijklmnopqrst"), 1, 18, SV("abcdefghij"), 0, 1, 1); + test(S("abcdefghijklmnopqrst"), 1, 18, SV("abcdefghij"), 0, 5, 1); + test(S("abcdefghijklmnopqrst"), 1, 18, SV("abcdefghij"), 0, 9, 1); + test(S("abcdefghijklmnopqrst"), 1, 18, SV("abcdefghij"), 0, 10, 1); + test(S("abcdefghijklmnopqrst"), 1, 18, SV("abcdefghij"), 0, 11, 1); + test(S("abcdefghijklmnopqrst"), 1, 18, SV("abcdefghij"), 1, 0, 18); + test(S("abcdefghijklmnopqrst"), 1, 18, SV("abcdefghij"), 1, 1, 17); +} + +template +void test44() +{ + test(S("abcdefghijklmnopqrst"), 1, 18, SV("abcdefghij"), 1, 4, 14); + test(S("abcdefghijklmnopqrst"), 1, 18, SV("abcdefghij"), 1, 8, 10); + test(S("abcdefghijklmnopqrst"), 1, 18, SV("abcdefghij"), 1, 9, 9); + test(S("abcdefghijklmnopqrst"), 1, 18, SV("abcdefghij"), 1, 10, 9); + test(S("abcdefghijklmnopqrst"), 1, 18, SV("abcdefghij"), 5, 0, 18); + test(S("abcdefghijklmnopqrst"), 1, 18, SV("abcdefghij"), 5, 1, -4); + test(S("abcdefghijklmnopqrst"), 1, 18, SV("abcdefghij"), 5, 2, -4); + test(S("abcdefghijklmnopqrst"), 1, 18, SV("abcdefghij"), 5, 4, -4); + test(S("abcdefghijklmnopqrst"), 1, 18, SV("abcdefghij"), 5, 5, -4); + test(S("abcdefghijklmnopqrst"), 1, 18, SV("abcdefghij"), 5, 6, -4); + test(S("abcdefghijklmnopqrst"), 1, 18, SV("abcdefghij"), 9, 0, 18); + test(S("abcdefghijklmnopqrst"), 1, 18, SV("abcdefghij"), 9, 1, -8); + test(S("abcdefghijklmnopqrst"), 1, 18, SV("abcdefghij"), 9, 2, -8); + test(S("abcdefghijklmnopqrst"), 1, 18, SV("abcdefghij"), 10, 0, 18); + test(S("abcdefghijklmnopqrst"), 1, 18, SV("abcdefghij"), 10, 1, 18); + test(S("abcdefghijklmnopqrst"), 1, 18, SV("abcdefghij"), 11, 0, 0); + test(S("abcdefghijklmnopqrst"), 1, 18, SV("abcdefghijklmnopqrst"), 0, 0, 18); + test(S("abcdefghijklmnopqrst"), 1, 18, SV("abcdefghijklmnopqrst"), 0, 1, 1); + test(S("abcdefghijklmnopqrst"), 1, 18, SV("abcdefghijklmnopqrst"), 0, 10, 1); + test(S("abcdefghijklmnopqrst"), 1, 18, SV("abcdefghijklmnopqrst"), 0, 19, 1); + test(S("abcdefghijklmnopqrst"), 1, 18, SV("abcdefghijklmnopqrst"), 0, 20, 1); + test(S("abcdefghijklmnopqrst"), 1, 18, SV("abcdefghijklmnopqrst"), 0, 21, 1); + test(S("abcdefghijklmnopqrst"), 1, 18, SV("abcdefghijklmnopqrst"), 1, 0, 18); + test(S("abcdefghijklmnopqrst"), 1, 18, SV("abcdefghijklmnopqrst"), 1, 1, 17); + test(S("abcdefghijklmnopqrst"), 1, 18, SV("abcdefghijklmnopqrst"), 1, 9, 9); + test(S("abcdefghijklmnopqrst"), 1, 18, SV("abcdefghijklmnopqrst"), 1, 18, 0); + test(S("abcdefghijklmnopqrst"), 1, 18, SV("abcdefghijklmnopqrst"), 1, 19, -1); + test(S("abcdefghijklmnopqrst"), 1, 18, SV("abcdefghijklmnopqrst"), 1, 20, -1); + test(S("abcdefghijklmnopqrst"), 1, 18, SV("abcdefghijklmnopqrst"), 10, 0, 18); + test(S("abcdefghijklmnopqrst"), 1, 18, SV("abcdefghijklmnopqrst"), 10, 1, -9); + test(S("abcdefghijklmnopqrst"), 1, 18, SV("abcdefghijklmnopqrst"), 10, 5, -9); + test(S("abcdefghijklmnopqrst"), 1, 18, SV("abcdefghijklmnopqrst"), 10, 9, -9); + test(S("abcdefghijklmnopqrst"), 1, 18, SV("abcdefghijklmnopqrst"), 10, 10, -9); + test(S("abcdefghijklmnopqrst"), 1, 18, SV("abcdefghijklmnopqrst"), 10, 11, -9); + test(S("abcdefghijklmnopqrst"), 1, 18, SV("abcdefghijklmnopqrst"), 19, 0, 18); + test(S("abcdefghijklmnopqrst"), 1, 18, SV("abcdefghijklmnopqrst"), 19, 1, -18); + test(S("abcdefghijklmnopqrst"), 1, 18, SV("abcdefghijklmnopqrst"), 19, 2, -18); + test(S("abcdefghijklmnopqrst"), 1, 18, SV("abcdefghijklmnopqrst"), 20, 0, 18); + test(S("abcdefghijklmnopqrst"), 1, 18, SV("abcdefghijklmnopqrst"), 20, 1, 18); + test(S("abcdefghijklmnopqrst"), 1, 18, SV("abcdefghijklmnopqrst"), 21, 0, 0); + test(S("abcdefghijklmnopqrst"), 1, 19, SV(""), 0, 0, 19); + test(S("abcdefghijklmnopqrst"), 1, 19, SV(""), 0, 1, 19); + test(S("abcdefghijklmnopqrst"), 1, 19, SV(""), 1, 0, 0); + test(S("abcdefghijklmnopqrst"), 1, 19, SV("abcde"), 0, 0, 19); + test(S("abcdefghijklmnopqrst"), 1, 19, SV("abcde"), 0, 1, 1); + test(S("abcdefghijklmnopqrst"), 1, 19, SV("abcde"), 0, 2, 1); + test(S("abcdefghijklmnopqrst"), 1, 19, SV("abcde"), 0, 4, 1); + test(S("abcdefghijklmnopqrst"), 1, 19, SV("abcde"), 0, 5, 1); + test(S("abcdefghijklmnopqrst"), 1, 19, SV("abcde"), 0, 6, 1); + test(S("abcdefghijklmnopqrst"), 1, 19, SV("abcde"), 1, 0, 19); + test(S("abcdefghijklmnopqrst"), 1, 19, SV("abcde"), 1, 1, 18); + test(S("abcdefghijklmnopqrst"), 1, 19, SV("abcde"), 1, 2, 17); + test(S("abcdefghijklmnopqrst"), 1, 19, SV("abcde"), 1, 3, 16); + test(S("abcdefghijklmnopqrst"), 1, 19, SV("abcde"), 1, 4, 15); + test(S("abcdefghijklmnopqrst"), 1, 19, SV("abcde"), 1, 5, 15); + test(S("abcdefghijklmnopqrst"), 1, 19, SV("abcde"), 2, 0, 19); + test(S("abcdefghijklmnopqrst"), 1, 19, SV("abcde"), 2, 1, -1); + test(S("abcdefghijklmnopqrst"), 1, 19, SV("abcde"), 2, 2, -1); + test(S("abcdefghijklmnopqrst"), 1, 19, SV("abcde"), 2, 3, -1); + test(S("abcdefghijklmnopqrst"), 1, 19, SV("abcde"), 2, 4, -1); + test(S("abcdefghijklmnopqrst"), 1, 19, SV("abcde"), 4, 0, 19); + test(S("abcdefghijklmnopqrst"), 1, 19, SV("abcde"), 4, 1, -3); + test(S("abcdefghijklmnopqrst"), 1, 19, SV("abcde"), 4, 2, -3); + test(S("abcdefghijklmnopqrst"), 1, 19, SV("abcde"), 5, 0, 19); + test(S("abcdefghijklmnopqrst"), 1, 19, SV("abcde"), 5, 1, 19); + test(S("abcdefghijklmnopqrst"), 1, 19, SV("abcde"), 6, 0, 0); + test(S("abcdefghijklmnopqrst"), 1, 19, SV("abcdefghij"), 0, 0, 19); + test(S("abcdefghijklmnopqrst"), 1, 19, SV("abcdefghij"), 0, 1, 1); + test(S("abcdefghijklmnopqrst"), 1, 19, SV("abcdefghij"), 0, 5, 1); + test(S("abcdefghijklmnopqrst"), 1, 19, SV("abcdefghij"), 0, 9, 1); + test(S("abcdefghijklmnopqrst"), 1, 19, SV("abcdefghij"), 0, 10, 1); + test(S("abcdefghijklmnopqrst"), 1, 19, SV("abcdefghij"), 0, 11, 1); + test(S("abcdefghijklmnopqrst"), 1, 19, SV("abcdefghij"), 1, 0, 19); + test(S("abcdefghijklmnopqrst"), 1, 19, SV("abcdefghij"), 1, 1, 18); + test(S("abcdefghijklmnopqrst"), 1, 19, SV("abcdefghij"), 1, 4, 15); + test(S("abcdefghijklmnopqrst"), 1, 19, SV("abcdefghij"), 1, 8, 11); + test(S("abcdefghijklmnopqrst"), 1, 19, SV("abcdefghij"), 1, 9, 10); + test(S("abcdefghijklmnopqrst"), 1, 19, SV("abcdefghij"), 1, 10, 10); + test(S("abcdefghijklmnopqrst"), 1, 19, SV("abcdefghij"), 5, 0, 19); + test(S("abcdefghijklmnopqrst"), 1, 19, SV("abcdefghij"), 5, 1, -4); + test(S("abcdefghijklmnopqrst"), 1, 19, SV("abcdefghij"), 5, 2, -4); + test(S("abcdefghijklmnopqrst"), 1, 19, SV("abcdefghij"), 5, 4, -4); + test(S("abcdefghijklmnopqrst"), 1, 19, SV("abcdefghij"), 5, 5, -4); + test(S("abcdefghijklmnopqrst"), 1, 19, SV("abcdefghij"), 5, 6, -4); + test(S("abcdefghijklmnopqrst"), 1, 19, SV("abcdefghij"), 9, 0, 19); + test(S("abcdefghijklmnopqrst"), 1, 19, SV("abcdefghij"), 9, 1, -8); + test(S("abcdefghijklmnopqrst"), 1, 19, SV("abcdefghij"), 9, 2, -8); + test(S("abcdefghijklmnopqrst"), 1, 19, SV("abcdefghij"), 10, 0, 19); + test(S("abcdefghijklmnopqrst"), 1, 19, SV("abcdefghij"), 10, 1, 19); + test(S("abcdefghijklmnopqrst"), 1, 19, SV("abcdefghij"), 11, 0, 0); + test(S("abcdefghijklmnopqrst"), 1, 19, SV("abcdefghijklmnopqrst"), 0, 0, 19); + test(S("abcdefghijklmnopqrst"), 1, 19, SV("abcdefghijklmnopqrst"), 0, 1, 1); + test(S("abcdefghijklmnopqrst"), 1, 19, SV("abcdefghijklmnopqrst"), 0, 10, 1); + test(S("abcdefghijklmnopqrst"), 1, 19, SV("abcdefghijklmnopqrst"), 0, 19, 1); + test(S("abcdefghijklmnopqrst"), 1, 19, SV("abcdefghijklmnopqrst"), 0, 20, 1); + test(S("abcdefghijklmnopqrst"), 1, 19, SV("abcdefghijklmnopqrst"), 0, 21, 1); + test(S("abcdefghijklmnopqrst"), 1, 19, SV("abcdefghijklmnopqrst"), 1, 0, 19); + test(S("abcdefghijklmnopqrst"), 1, 19, SV("abcdefghijklmnopqrst"), 1, 1, 18); + test(S("abcdefghijklmnopqrst"), 1, 19, SV("abcdefghijklmnopqrst"), 1, 9, 10); + test(S("abcdefghijklmnopqrst"), 1, 19, SV("abcdefghijklmnopqrst"), 1, 18, 1); +} + +template +void test45() +{ + test(S("abcdefghijklmnopqrst"), 1, 19, SV("abcdefghijklmnopqrst"), 1, 19, 0); + test(S("abcdefghijklmnopqrst"), 1, 19, SV("abcdefghijklmnopqrst"), 1, 20, 0); + test(S("abcdefghijklmnopqrst"), 1, 19, SV("abcdefghijklmnopqrst"), 10, 0, 19); + test(S("abcdefghijklmnopqrst"), 1, 19, SV("abcdefghijklmnopqrst"), 10, 1, -9); + test(S("abcdefghijklmnopqrst"), 1, 19, SV("abcdefghijklmnopqrst"), 10, 5, -9); + test(S("abcdefghijklmnopqrst"), 1, 19, SV("abcdefghijklmnopqrst"), 10, 9, -9); + test(S("abcdefghijklmnopqrst"), 1, 19, SV("abcdefghijklmnopqrst"), 10, 10, -9); + test(S("abcdefghijklmnopqrst"), 1, 19, SV("abcdefghijklmnopqrst"), 10, 11, -9); + test(S("abcdefghijklmnopqrst"), 1, 19, SV("abcdefghijklmnopqrst"), 19, 0, 19); + test(S("abcdefghijklmnopqrst"), 1, 19, SV("abcdefghijklmnopqrst"), 19, 1, -18); + test(S("abcdefghijklmnopqrst"), 1, 19, SV("abcdefghijklmnopqrst"), 19, 2, -18); + test(S("abcdefghijklmnopqrst"), 1, 19, SV("abcdefghijklmnopqrst"), 20, 0, 19); + test(S("abcdefghijklmnopqrst"), 1, 19, SV("abcdefghijklmnopqrst"), 20, 1, 19); + test(S("abcdefghijklmnopqrst"), 1, 19, SV("abcdefghijklmnopqrst"), 21, 0, 0); + test(S("abcdefghijklmnopqrst"), 1, 20, SV(""), 0, 0, 19); + test(S("abcdefghijklmnopqrst"), 1, 20, SV(""), 0, 1, 19); + test(S("abcdefghijklmnopqrst"), 1, 20, SV(""), 1, 0, 0); + test(S("abcdefghijklmnopqrst"), 1, 20, SV("abcde"), 0, 0, 19); + test(S("abcdefghijklmnopqrst"), 1, 20, SV("abcde"), 0, 1, 1); + test(S("abcdefghijklmnopqrst"), 1, 20, SV("abcde"), 0, 2, 1); + test(S("abcdefghijklmnopqrst"), 1, 20, SV("abcde"), 0, 4, 1); + test(S("abcdefghijklmnopqrst"), 1, 20, SV("abcde"), 0, 5, 1); + test(S("abcdefghijklmnopqrst"), 1, 20, SV("abcde"), 0, 6, 1); + test(S("abcdefghijklmnopqrst"), 1, 20, SV("abcde"), 1, 0, 19); + test(S("abcdefghijklmnopqrst"), 1, 20, SV("abcde"), 1, 1, 18); + test(S("abcdefghijklmnopqrst"), 1, 20, SV("abcde"), 1, 2, 17); + test(S("abcdefghijklmnopqrst"), 1, 20, SV("abcde"), 1, 3, 16); + test(S("abcdefghijklmnopqrst"), 1, 20, SV("abcde"), 1, 4, 15); + test(S("abcdefghijklmnopqrst"), 1, 20, SV("abcde"), 1, 5, 15); + test(S("abcdefghijklmnopqrst"), 1, 20, SV("abcde"), 2, 0, 19); + test(S("abcdefghijklmnopqrst"), 1, 20, SV("abcde"), 2, 1, -1); + test(S("abcdefghijklmnopqrst"), 1, 20, SV("abcde"), 2, 2, -1); + test(S("abcdefghijklmnopqrst"), 1, 20, SV("abcde"), 2, 3, -1); + test(S("abcdefghijklmnopqrst"), 1, 20, SV("abcde"), 2, 4, -1); + test(S("abcdefghijklmnopqrst"), 1, 20, SV("abcde"), 4, 0, 19); + test(S("abcdefghijklmnopqrst"), 1, 20, SV("abcde"), 4, 1, -3); + test(S("abcdefghijklmnopqrst"), 1, 20, SV("abcde"), 4, 2, -3); + test(S("abcdefghijklmnopqrst"), 1, 20, SV("abcde"), 5, 0, 19); + test(S("abcdefghijklmnopqrst"), 1, 20, SV("abcde"), 5, 1, 19); + test(S("abcdefghijklmnopqrst"), 1, 20, SV("abcde"), 6, 0, 0); + test(S("abcdefghijklmnopqrst"), 1, 20, SV("abcdefghij"), 0, 0, 19); + test(S("abcdefghijklmnopqrst"), 1, 20, SV("abcdefghij"), 0, 1, 1); + test(S("abcdefghijklmnopqrst"), 1, 20, SV("abcdefghij"), 0, 5, 1); + test(S("abcdefghijklmnopqrst"), 1, 20, SV("abcdefghij"), 0, 9, 1); + test(S("abcdefghijklmnopqrst"), 1, 20, SV("abcdefghij"), 0, 10, 1); + test(S("abcdefghijklmnopqrst"), 1, 20, SV("abcdefghij"), 0, 11, 1); + test(S("abcdefghijklmnopqrst"), 1, 20, SV("abcdefghij"), 1, 0, 19); + test(S("abcdefghijklmnopqrst"), 1, 20, SV("abcdefghij"), 1, 1, 18); + test(S("abcdefghijklmnopqrst"), 1, 20, SV("abcdefghij"), 1, 4, 15); + test(S("abcdefghijklmnopqrst"), 1, 20, SV("abcdefghij"), 1, 8, 11); + test(S("abcdefghijklmnopqrst"), 1, 20, SV("abcdefghij"), 1, 9, 10); + test(S("abcdefghijklmnopqrst"), 1, 20, SV("abcdefghij"), 1, 10, 10); + test(S("abcdefghijklmnopqrst"), 1, 20, SV("abcdefghij"), 5, 0, 19); + test(S("abcdefghijklmnopqrst"), 1, 20, SV("abcdefghij"), 5, 1, -4); + test(S("abcdefghijklmnopqrst"), 1, 20, SV("abcdefghij"), 5, 2, -4); + test(S("abcdefghijklmnopqrst"), 1, 20, SV("abcdefghij"), 5, 4, -4); + test(S("abcdefghijklmnopqrst"), 1, 20, SV("abcdefghij"), 5, 5, -4); + test(S("abcdefghijklmnopqrst"), 1, 20, SV("abcdefghij"), 5, 6, -4); + test(S("abcdefghijklmnopqrst"), 1, 20, SV("abcdefghij"), 9, 0, 19); + test(S("abcdefghijklmnopqrst"), 1, 20, SV("abcdefghij"), 9, 1, -8); + test(S("abcdefghijklmnopqrst"), 1, 20, SV("abcdefghij"), 9, 2, -8); + test(S("abcdefghijklmnopqrst"), 1, 20, SV("abcdefghij"), 10, 0, 19); + test(S("abcdefghijklmnopqrst"), 1, 20, SV("abcdefghij"), 10, 1, 19); + test(S("abcdefghijklmnopqrst"), 1, 20, SV("abcdefghij"), 11, 0, 0); + test(S("abcdefghijklmnopqrst"), 1, 20, SV("abcdefghijklmnopqrst"), 0, 0, 19); + test(S("abcdefghijklmnopqrst"), 1, 20, SV("abcdefghijklmnopqrst"), 0, 1, 1); + test(S("abcdefghijklmnopqrst"), 1, 20, SV("abcdefghijklmnopqrst"), 0, 10, 1); + test(S("abcdefghijklmnopqrst"), 1, 20, SV("abcdefghijklmnopqrst"), 0, 19, 1); + test(S("abcdefghijklmnopqrst"), 1, 20, SV("abcdefghijklmnopqrst"), 0, 20, 1); + test(S("abcdefghijklmnopqrst"), 1, 20, SV("abcdefghijklmnopqrst"), 0, 21, 1); + test(S("abcdefghijklmnopqrst"), 1, 20, SV("abcdefghijklmnopqrst"), 1, 0, 19); + test(S("abcdefghijklmnopqrst"), 1, 20, SV("abcdefghijklmnopqrst"), 1, 1, 18); + test(S("abcdefghijklmnopqrst"), 1, 20, SV("abcdefghijklmnopqrst"), 1, 9, 10); + test(S("abcdefghijklmnopqrst"), 1, 20, SV("abcdefghijklmnopqrst"), 1, 18, 1); + test(S("abcdefghijklmnopqrst"), 1, 20, SV("abcdefghijklmnopqrst"), 1, 19, 0); + test(S("abcdefghijklmnopqrst"), 1, 20, SV("abcdefghijklmnopqrst"), 1, 20, 0); + test(S("abcdefghijklmnopqrst"), 1, 20, SV("abcdefghijklmnopqrst"), 10, 0, 19); + test(S("abcdefghijklmnopqrst"), 1, 20, SV("abcdefghijklmnopqrst"), 10, 1, -9); + test(S("abcdefghijklmnopqrst"), 1, 20, SV("abcdefghijklmnopqrst"), 10, 5, -9); + test(S("abcdefghijklmnopqrst"), 1, 20, SV("abcdefghijklmnopqrst"), 10, 9, -9); + test(S("abcdefghijklmnopqrst"), 1, 20, SV("abcdefghijklmnopqrst"), 10, 10, -9); + test(S("abcdefghijklmnopqrst"), 1, 20, SV("abcdefghijklmnopqrst"), 10, 11, -9); + test(S("abcdefghijklmnopqrst"), 1, 20, SV("abcdefghijklmnopqrst"), 19, 0, 19); + test(S("abcdefghijklmnopqrst"), 1, 20, SV("abcdefghijklmnopqrst"), 19, 1, -18); + test(S("abcdefghijklmnopqrst"), 1, 20, SV("abcdefghijklmnopqrst"), 19, 2, -18); + test(S("abcdefghijklmnopqrst"), 1, 20, SV("abcdefghijklmnopqrst"), 20, 0, 19); + test(S("abcdefghijklmnopqrst"), 1, 20, SV("abcdefghijklmnopqrst"), 20, 1, 19); + test(S("abcdefghijklmnopqrst"), 1, 20, SV("abcdefghijklmnopqrst"), 21, 0, 0); + test(S("abcdefghijklmnopqrst"), 10, 0, SV(""), 0, 0, 0); + test(S("abcdefghijklmnopqrst"), 10, 0, SV(""), 0, 1, 0); + test(S("abcdefghijklmnopqrst"), 10, 0, SV(""), 1, 0, 0); + test(S("abcdefghijklmnopqrst"), 10, 0, SV("abcde"), 0, 0, 0); + test(S("abcdefghijklmnopqrst"), 10, 0, SV("abcde"), 0, 1, -1); + test(S("abcdefghijklmnopqrst"), 10, 0, SV("abcde"), 0, 2, -2); + test(S("abcdefghijklmnopqrst"), 10, 0, SV("abcde"), 0, 4, -4); + test(S("abcdefghijklmnopqrst"), 10, 0, SV("abcde"), 0, 5, -5); + test(S("abcdefghijklmnopqrst"), 10, 0, SV("abcde"), 0, 6, -5); + test(S("abcdefghijklmnopqrst"), 10, 0, SV("abcde"), 1, 0, 0); + test(S("abcdefghijklmnopqrst"), 10, 0, SV("abcde"), 1, 1, -1); + test(S("abcdefghijklmnopqrst"), 10, 0, SV("abcde"), 1, 2, -2); +} + +template +void test46() +{ + test(S("abcdefghijklmnopqrst"), 10, 0, SV("abcde"), 1, 3, -3); + test(S("abcdefghijklmnopqrst"), 10, 0, SV("abcde"), 1, 4, -4); + test(S("abcdefghijklmnopqrst"), 10, 0, SV("abcde"), 1, 5, -4); + test(S("abcdefghijklmnopqrst"), 10, 0, SV("abcde"), 2, 0, 0); + test(S("abcdefghijklmnopqrst"), 10, 0, SV("abcde"), 2, 1, -1); + test(S("abcdefghijklmnopqrst"), 10, 0, SV("abcde"), 2, 2, -2); + test(S("abcdefghijklmnopqrst"), 10, 0, SV("abcde"), 2, 3, -3); + test(S("abcdefghijklmnopqrst"), 10, 0, SV("abcde"), 2, 4, -3); + test(S("abcdefghijklmnopqrst"), 10, 0, SV("abcde"), 4, 0, 0); + test(S("abcdefghijklmnopqrst"), 10, 0, SV("abcde"), 4, 1, -1); + test(S("abcdefghijklmnopqrst"), 10, 0, SV("abcde"), 4, 2, -1); + test(S("abcdefghijklmnopqrst"), 10, 0, SV("abcde"), 5, 0, 0); + test(S("abcdefghijklmnopqrst"), 10, 0, SV("abcde"), 5, 1, 0); + test(S("abcdefghijklmnopqrst"), 10, 0, SV("abcde"), 6, 0, 0); + test(S("abcdefghijklmnopqrst"), 10, 0, SV("abcdefghij"), 0, 0, 0); + test(S("abcdefghijklmnopqrst"), 10, 0, SV("abcdefghij"), 0, 1, -1); + test(S("abcdefghijklmnopqrst"), 10, 0, SV("abcdefghij"), 0, 5, -5); + test(S("abcdefghijklmnopqrst"), 10, 0, SV("abcdefghij"), 0, 9, -9); + test(S("abcdefghijklmnopqrst"), 10, 0, SV("abcdefghij"), 0, 10, -10); + test(S("abcdefghijklmnopqrst"), 10, 0, SV("abcdefghij"), 0, 11, -10); + test(S("abcdefghijklmnopqrst"), 10, 0, SV("abcdefghij"), 1, 0, 0); + test(S("abcdefghijklmnopqrst"), 10, 0, SV("abcdefghij"), 1, 1, -1); + test(S("abcdefghijklmnopqrst"), 10, 0, SV("abcdefghij"), 1, 4, -4); + test(S("abcdefghijklmnopqrst"), 10, 0, SV("abcdefghij"), 1, 8, -8); + test(S("abcdefghijklmnopqrst"), 10, 0, SV("abcdefghij"), 1, 9, -9); + test(S("abcdefghijklmnopqrst"), 10, 0, SV("abcdefghij"), 1, 10, -9); + test(S("abcdefghijklmnopqrst"), 10, 0, SV("abcdefghij"), 5, 0, 0); + test(S("abcdefghijklmnopqrst"), 10, 0, SV("abcdefghij"), 5, 1, -1); + test(S("abcdefghijklmnopqrst"), 10, 0, SV("abcdefghij"), 5, 2, -2); + test(S("abcdefghijklmnopqrst"), 10, 0, SV("abcdefghij"), 5, 4, -4); + test(S("abcdefghijklmnopqrst"), 10, 0, SV("abcdefghij"), 5, 5, -5); + test(S("abcdefghijklmnopqrst"), 10, 0, SV("abcdefghij"), 5, 6, -5); + test(S("abcdefghijklmnopqrst"), 10, 0, SV("abcdefghij"), 9, 0, 0); + test(S("abcdefghijklmnopqrst"), 10, 0, SV("abcdefghij"), 9, 1, -1); + test(S("abcdefghijklmnopqrst"), 10, 0, SV("abcdefghij"), 9, 2, -1); + test(S("abcdefghijklmnopqrst"), 10, 0, SV("abcdefghij"), 10, 0, 0); + test(S("abcdefghijklmnopqrst"), 10, 0, SV("abcdefghij"), 10, 1, 0); + test(S("abcdefghijklmnopqrst"), 10, 0, SV("abcdefghij"), 11, 0, 0); + test(S("abcdefghijklmnopqrst"), 10, 0, SV("abcdefghijklmnopqrst"), 0, 0, 0); + test(S("abcdefghijklmnopqrst"), 10, 0, SV("abcdefghijklmnopqrst"), 0, 1, -1); + test(S("abcdefghijklmnopqrst"), 10, 0, SV("abcdefghijklmnopqrst"), 0, 10, -10); + test(S("abcdefghijklmnopqrst"), 10, 0, SV("abcdefghijklmnopqrst"), 0, 19, -19); + test(S("abcdefghijklmnopqrst"), 10, 0, SV("abcdefghijklmnopqrst"), 0, 20, -20); + test(S("abcdefghijklmnopqrst"), 10, 0, SV("abcdefghijklmnopqrst"), 0, 21, -20); + test(S("abcdefghijklmnopqrst"), 10, 0, SV("abcdefghijklmnopqrst"), 1, 0, 0); + test(S("abcdefghijklmnopqrst"), 10, 0, SV("abcdefghijklmnopqrst"), 1, 1, -1); + test(S("abcdefghijklmnopqrst"), 10, 0, SV("abcdefghijklmnopqrst"), 1, 9, -9); + test(S("abcdefghijklmnopqrst"), 10, 0, SV("abcdefghijklmnopqrst"), 1, 18, -18); + test(S("abcdefghijklmnopqrst"), 10, 0, SV("abcdefghijklmnopqrst"), 1, 19, -19); + test(S("abcdefghijklmnopqrst"), 10, 0, SV("abcdefghijklmnopqrst"), 1, 20, -19); + test(S("abcdefghijklmnopqrst"), 10, 0, SV("abcdefghijklmnopqrst"), 10, 0, 0); + test(S("abcdefghijklmnopqrst"), 10, 0, SV("abcdefghijklmnopqrst"), 10, 1, -1); + test(S("abcdefghijklmnopqrst"), 10, 0, SV("abcdefghijklmnopqrst"), 10, 5, -5); + test(S("abcdefghijklmnopqrst"), 10, 0, SV("abcdefghijklmnopqrst"), 10, 9, -9); + test(S("abcdefghijklmnopqrst"), 10, 0, SV("abcdefghijklmnopqrst"), 10, 10, -10); + test(S("abcdefghijklmnopqrst"), 10, 0, SV("abcdefghijklmnopqrst"), 10, 11, -10); + test(S("abcdefghijklmnopqrst"), 10, 0, SV("abcdefghijklmnopqrst"), 19, 0, 0); + test(S("abcdefghijklmnopqrst"), 10, 0, SV("abcdefghijklmnopqrst"), 19, 1, -1); + test(S("abcdefghijklmnopqrst"), 10, 0, SV("abcdefghijklmnopqrst"), 19, 2, -1); + test(S("abcdefghijklmnopqrst"), 10, 0, SV("abcdefghijklmnopqrst"), 20, 0, 0); + test(S("abcdefghijklmnopqrst"), 10, 0, SV("abcdefghijklmnopqrst"), 20, 1, 0); + test(S("abcdefghijklmnopqrst"), 10, 0, SV("abcdefghijklmnopqrst"), 21, 0, 0); + test(S("abcdefghijklmnopqrst"), 10, 1, SV(""), 0, 0, 1); + test(S("abcdefghijklmnopqrst"), 10, 1, SV(""), 0, 1, 1); + test(S("abcdefghijklmnopqrst"), 10, 1, SV(""), 1, 0, 0); + test(S("abcdefghijklmnopqrst"), 10, 1, SV("abcde"), 0, 0, 1); + test(S("abcdefghijklmnopqrst"), 10, 1, SV("abcde"), 0, 1, 10); + test(S("abcdefghijklmnopqrst"), 10, 1, SV("abcde"), 0, 2, 10); + test(S("abcdefghijklmnopqrst"), 10, 1, SV("abcde"), 0, 4, 10); + test(S("abcdefghijklmnopqrst"), 10, 1, SV("abcde"), 0, 5, 10); + test(S("abcdefghijklmnopqrst"), 10, 1, SV("abcde"), 0, 6, 10); + test(S("abcdefghijklmnopqrst"), 10, 1, SV("abcde"), 1, 0, 1); + test(S("abcdefghijklmnopqrst"), 10, 1, SV("abcde"), 1, 1, 9); + test(S("abcdefghijklmnopqrst"), 10, 1, SV("abcde"), 1, 2, 9); + test(S("abcdefghijklmnopqrst"), 10, 1, SV("abcde"), 1, 3, 9); + test(S("abcdefghijklmnopqrst"), 10, 1, SV("abcde"), 1, 4, 9); + test(S("abcdefghijklmnopqrst"), 10, 1, SV("abcde"), 1, 5, 9); + test(S("abcdefghijklmnopqrst"), 10, 1, SV("abcde"), 2, 0, 1); + test(S("abcdefghijklmnopqrst"), 10, 1, SV("abcde"), 2, 1, 8); + test(S("abcdefghijklmnopqrst"), 10, 1, SV("abcde"), 2, 2, 8); + test(S("abcdefghijklmnopqrst"), 10, 1, SV("abcde"), 2, 3, 8); + test(S("abcdefghijklmnopqrst"), 10, 1, SV("abcde"), 2, 4, 8); + test(S("abcdefghijklmnopqrst"), 10, 1, SV("abcde"), 4, 0, 1); + test(S("abcdefghijklmnopqrst"), 10, 1, SV("abcde"), 4, 1, 6); + test(S("abcdefghijklmnopqrst"), 10, 1, SV("abcde"), 4, 2, 6); + test(S("abcdefghijklmnopqrst"), 10, 1, SV("abcde"), 5, 0, 1); + test(S("abcdefghijklmnopqrst"), 10, 1, SV("abcde"), 5, 1, 1); + test(S("abcdefghijklmnopqrst"), 10, 1, SV("abcde"), 6, 0, 0); + test(S("abcdefghijklmnopqrst"), 10, 1, SV("abcdefghij"), 0, 0, 1); + test(S("abcdefghijklmnopqrst"), 10, 1, SV("abcdefghij"), 0, 1, 10); + test(S("abcdefghijklmnopqrst"), 10, 1, SV("abcdefghij"), 0, 5, 10); + test(S("abcdefghijklmnopqrst"), 10, 1, SV("abcdefghij"), 0, 9, 10); + test(S("abcdefghijklmnopqrst"), 10, 1, SV("abcdefghij"), 0, 10, 10); + test(S("abcdefghijklmnopqrst"), 10, 1, SV("abcdefghij"), 0, 11, 10); + test(S("abcdefghijklmnopqrst"), 10, 1, SV("abcdefghij"), 1, 0, 1); + test(S("abcdefghijklmnopqrst"), 10, 1, SV("abcdefghij"), 1, 1, 9); + test(S("abcdefghijklmnopqrst"), 10, 1, SV("abcdefghij"), 1, 4, 9); + test(S("abcdefghijklmnopqrst"), 10, 1, SV("abcdefghij"), 1, 8, 9); + test(S("abcdefghijklmnopqrst"), 10, 1, SV("abcdefghij"), 1, 9, 9); + test(S("abcdefghijklmnopqrst"), 10, 1, SV("abcdefghij"), 1, 10, 9); +} + +template +void test47() +{ + test(S("abcdefghijklmnopqrst"), 10, 1, SV("abcdefghij"), 5, 0, 1); + test(S("abcdefghijklmnopqrst"), 10, 1, SV("abcdefghij"), 5, 1, 5); + test(S("abcdefghijklmnopqrst"), 10, 1, SV("abcdefghij"), 5, 2, 5); + test(S("abcdefghijklmnopqrst"), 10, 1, SV("abcdefghij"), 5, 4, 5); + test(S("abcdefghijklmnopqrst"), 10, 1, SV("abcdefghij"), 5, 5, 5); + test(S("abcdefghijklmnopqrst"), 10, 1, SV("abcdefghij"), 5, 6, 5); + test(S("abcdefghijklmnopqrst"), 10, 1, SV("abcdefghij"), 9, 0, 1); + test(S("abcdefghijklmnopqrst"), 10, 1, SV("abcdefghij"), 9, 1, 1); + test(S("abcdefghijklmnopqrst"), 10, 1, SV("abcdefghij"), 9, 2, 1); + test(S("abcdefghijklmnopqrst"), 10, 1, SV("abcdefghij"), 10, 0, 1); + test(S("abcdefghijklmnopqrst"), 10, 1, SV("abcdefghij"), 10, 1, 1); + test(S("abcdefghijklmnopqrst"), 10, 1, SV("abcdefghij"), 11, 0, 0); + test(S("abcdefghijklmnopqrst"), 10, 1, SV("abcdefghijklmnopqrst"), 0, 0, 1); + test(S("abcdefghijklmnopqrst"), 10, 1, SV("abcdefghijklmnopqrst"), 0, 1, 10); + test(S("abcdefghijklmnopqrst"), 10, 1, SV("abcdefghijklmnopqrst"), 0, 10, 10); + test(S("abcdefghijklmnopqrst"), 10, 1, SV("abcdefghijklmnopqrst"), 0, 19, 10); + test(S("abcdefghijklmnopqrst"), 10, 1, SV("abcdefghijklmnopqrst"), 0, 20, 10); + test(S("abcdefghijklmnopqrst"), 10, 1, SV("abcdefghijklmnopqrst"), 0, 21, 10); + test(S("abcdefghijklmnopqrst"), 10, 1, SV("abcdefghijklmnopqrst"), 1, 0, 1); + test(S("abcdefghijklmnopqrst"), 10, 1, SV("abcdefghijklmnopqrst"), 1, 1, 9); + test(S("abcdefghijklmnopqrst"), 10, 1, SV("abcdefghijklmnopqrst"), 1, 9, 9); + test(S("abcdefghijklmnopqrst"), 10, 1, SV("abcdefghijklmnopqrst"), 1, 18, 9); + test(S("abcdefghijklmnopqrst"), 10, 1, SV("abcdefghijklmnopqrst"), 1, 19, 9); + test(S("abcdefghijklmnopqrst"), 10, 1, SV("abcdefghijklmnopqrst"), 1, 20, 9); + test(S("abcdefghijklmnopqrst"), 10, 1, SV("abcdefghijklmnopqrst"), 10, 0, 1); + test(S("abcdefghijklmnopqrst"), 10, 1, SV("abcdefghijklmnopqrst"), 10, 1, 0); + test(S("abcdefghijklmnopqrst"), 10, 1, SV("abcdefghijklmnopqrst"), 10, 5, -4); + test(S("abcdefghijklmnopqrst"), 10, 1, SV("abcdefghijklmnopqrst"), 10, 9, -8); + test(S("abcdefghijklmnopqrst"), 10, 1, SV("abcdefghijklmnopqrst"), 10, 10, -9); + test(S("abcdefghijklmnopqrst"), 10, 1, SV("abcdefghijklmnopqrst"), 10, 11, -9); + test(S("abcdefghijklmnopqrst"), 10, 1, SV("abcdefghijklmnopqrst"), 19, 0, 1); + test(S("abcdefghijklmnopqrst"), 10, 1, SV("abcdefghijklmnopqrst"), 19, 1, -9); + test(S("abcdefghijklmnopqrst"), 10, 1, SV("abcdefghijklmnopqrst"), 19, 2, -9); + test(S("abcdefghijklmnopqrst"), 10, 1, SV("abcdefghijklmnopqrst"), 20, 0, 1); + test(S("abcdefghijklmnopqrst"), 10, 1, SV("abcdefghijklmnopqrst"), 20, 1, 1); + test(S("abcdefghijklmnopqrst"), 10, 1, SV("abcdefghijklmnopqrst"), 21, 0, 0); + test(S("abcdefghijklmnopqrst"), 10, 5, SV(""), 0, 0, 5); + test(S("abcdefghijklmnopqrst"), 10, 5, SV(""), 0, 1, 5); + test(S("abcdefghijklmnopqrst"), 10, 5, SV(""), 1, 0, 0); + test(S("abcdefghijklmnopqrst"), 10, 5, SV("abcde"), 0, 0, 5); + test(S("abcdefghijklmnopqrst"), 10, 5, SV("abcde"), 0, 1, 10); + test(S("abcdefghijklmnopqrst"), 10, 5, SV("abcde"), 0, 2, 10); + test(S("abcdefghijklmnopqrst"), 10, 5, SV("abcde"), 0, 4, 10); + test(S("abcdefghijklmnopqrst"), 10, 5, SV("abcde"), 0, 5, 10); + test(S("abcdefghijklmnopqrst"), 10, 5, SV("abcde"), 0, 6, 10); + test(S("abcdefghijklmnopqrst"), 10, 5, SV("abcde"), 1, 0, 5); + test(S("abcdefghijklmnopqrst"), 10, 5, SV("abcde"), 1, 1, 9); + test(S("abcdefghijklmnopqrst"), 10, 5, SV("abcde"), 1, 2, 9); + test(S("abcdefghijklmnopqrst"), 10, 5, SV("abcde"), 1, 3, 9); + test(S("abcdefghijklmnopqrst"), 10, 5, SV("abcde"), 1, 4, 9); + test(S("abcdefghijklmnopqrst"), 10, 5, SV("abcde"), 1, 5, 9); + test(S("abcdefghijklmnopqrst"), 10, 5, SV("abcde"), 2, 0, 5); + test(S("abcdefghijklmnopqrst"), 10, 5, SV("abcde"), 2, 1, 8); + test(S("abcdefghijklmnopqrst"), 10, 5, SV("abcde"), 2, 2, 8); + test(S("abcdefghijklmnopqrst"), 10, 5, SV("abcde"), 2, 3, 8); + test(S("abcdefghijklmnopqrst"), 10, 5, SV("abcde"), 2, 4, 8); + test(S("abcdefghijklmnopqrst"), 10, 5, SV("abcde"), 4, 0, 5); + test(S("abcdefghijklmnopqrst"), 10, 5, SV("abcde"), 4, 1, 6); + test(S("abcdefghijklmnopqrst"), 10, 5, SV("abcde"), 4, 2, 6); + test(S("abcdefghijklmnopqrst"), 10, 5, SV("abcde"), 5, 0, 5); + test(S("abcdefghijklmnopqrst"), 10, 5, SV("abcde"), 5, 1, 5); + test(S("abcdefghijklmnopqrst"), 10, 5, SV("abcde"), 6, 0, 0); + test(S("abcdefghijklmnopqrst"), 10, 5, SV("abcdefghij"), 0, 0, 5); + test(S("abcdefghijklmnopqrst"), 10, 5, SV("abcdefghij"), 0, 1, 10); + test(S("abcdefghijklmnopqrst"), 10, 5, SV("abcdefghij"), 0, 5, 10); + test(S("abcdefghijklmnopqrst"), 10, 5, SV("abcdefghij"), 0, 9, 10); + test(S("abcdefghijklmnopqrst"), 10, 5, SV("abcdefghij"), 0, 10, 10); + test(S("abcdefghijklmnopqrst"), 10, 5, SV("abcdefghij"), 0, 11, 10); + test(S("abcdefghijklmnopqrst"), 10, 5, SV("abcdefghij"), 1, 0, 5); + test(S("abcdefghijklmnopqrst"), 10, 5, SV("abcdefghij"), 1, 1, 9); + test(S("abcdefghijklmnopqrst"), 10, 5, SV("abcdefghij"), 1, 4, 9); + test(S("abcdefghijklmnopqrst"), 10, 5, SV("abcdefghij"), 1, 8, 9); + test(S("abcdefghijklmnopqrst"), 10, 5, SV("abcdefghij"), 1, 9, 9); + test(S("abcdefghijklmnopqrst"), 10, 5, SV("abcdefghij"), 1, 10, 9); + test(S("abcdefghijklmnopqrst"), 10, 5, SV("abcdefghij"), 5, 0, 5); + test(S("abcdefghijklmnopqrst"), 10, 5, SV("abcdefghij"), 5, 1, 5); + test(S("abcdefghijklmnopqrst"), 10, 5, SV("abcdefghij"), 5, 2, 5); + test(S("abcdefghijklmnopqrst"), 10, 5, SV("abcdefghij"), 5, 4, 5); + test(S("abcdefghijklmnopqrst"), 10, 5, SV("abcdefghij"), 5, 5, 5); + test(S("abcdefghijklmnopqrst"), 10, 5, SV("abcdefghij"), 5, 6, 5); + test(S("abcdefghijklmnopqrst"), 10, 5, SV("abcdefghij"), 9, 0, 5); + test(S("abcdefghijklmnopqrst"), 10, 5, SV("abcdefghij"), 9, 1, 1); + test(S("abcdefghijklmnopqrst"), 10, 5, SV("abcdefghij"), 9, 2, 1); + test(S("abcdefghijklmnopqrst"), 10, 5, SV("abcdefghij"), 10, 0, 5); + test(S("abcdefghijklmnopqrst"), 10, 5, SV("abcdefghij"), 10, 1, 5); + test(S("abcdefghijklmnopqrst"), 10, 5, SV("abcdefghij"), 11, 0, 0); + test(S("abcdefghijklmnopqrst"), 10, 5, SV("abcdefghijklmnopqrst"), 0, 0, 5); + test(S("abcdefghijklmnopqrst"), 10, 5, SV("abcdefghijklmnopqrst"), 0, 1, 10); + test(S("abcdefghijklmnopqrst"), 10, 5, SV("abcdefghijklmnopqrst"), 0, 10, 10); + test(S("abcdefghijklmnopqrst"), 10, 5, SV("abcdefghijklmnopqrst"), 0, 19, 10); + test(S("abcdefghijklmnopqrst"), 10, 5, SV("abcdefghijklmnopqrst"), 0, 20, 10); + test(S("abcdefghijklmnopqrst"), 10, 5, SV("abcdefghijklmnopqrst"), 0, 21, 10); + test(S("abcdefghijklmnopqrst"), 10, 5, SV("abcdefghijklmnopqrst"), 1, 0, 5); + test(S("abcdefghijklmnopqrst"), 10, 5, SV("abcdefghijklmnopqrst"), 1, 1, 9); + test(S("abcdefghijklmnopqrst"), 10, 5, SV("abcdefghijklmnopqrst"), 1, 9, 9); + test(S("abcdefghijklmnopqrst"), 10, 5, SV("abcdefghijklmnopqrst"), 1, 18, 9); + test(S("abcdefghijklmnopqrst"), 10, 5, SV("abcdefghijklmnopqrst"), 1, 19, 9); + test(S("abcdefghijklmnopqrst"), 10, 5, SV("abcdefghijklmnopqrst"), 1, 20, 9); + test(S("abcdefghijklmnopqrst"), 10, 5, SV("abcdefghijklmnopqrst"), 10, 0, 5); + test(S("abcdefghijklmnopqrst"), 10, 5, SV("abcdefghijklmnopqrst"), 10, 1, 4); +} + +template +void test48() +{ + test(S("abcdefghijklmnopqrst"), 10, 5, SV("abcdefghijklmnopqrst"), 10, 5, 0); + test(S("abcdefghijklmnopqrst"), 10, 5, SV("abcdefghijklmnopqrst"), 10, 9, -4); + test(S("abcdefghijklmnopqrst"), 10, 5, SV("abcdefghijklmnopqrst"), 10, 10, -5); + test(S("abcdefghijklmnopqrst"), 10, 5, SV("abcdefghijklmnopqrst"), 10, 11, -5); + test(S("abcdefghijklmnopqrst"), 10, 5, SV("abcdefghijklmnopqrst"), 19, 0, 5); + test(S("abcdefghijklmnopqrst"), 10, 5, SV("abcdefghijklmnopqrst"), 19, 1, -9); + test(S("abcdefghijklmnopqrst"), 10, 5, SV("abcdefghijklmnopqrst"), 19, 2, -9); + test(S("abcdefghijklmnopqrst"), 10, 5, SV("abcdefghijklmnopqrst"), 20, 0, 5); + test(S("abcdefghijklmnopqrst"), 10, 5, SV("abcdefghijklmnopqrst"), 20, 1, 5); + test(S("abcdefghijklmnopqrst"), 10, 5, SV("abcdefghijklmnopqrst"), 21, 0, 0); + test(S("abcdefghijklmnopqrst"), 10, 9, SV(""), 0, 0, 9); + test(S("abcdefghijklmnopqrst"), 10, 9, SV(""), 0, 1, 9); + test(S("abcdefghijklmnopqrst"), 10, 9, SV(""), 1, 0, 0); + test(S("abcdefghijklmnopqrst"), 10, 9, SV("abcde"), 0, 0, 9); + test(S("abcdefghijklmnopqrst"), 10, 9, SV("abcde"), 0, 1, 10); + test(S("abcdefghijklmnopqrst"), 10, 9, SV("abcde"), 0, 2, 10); + test(S("abcdefghijklmnopqrst"), 10, 9, SV("abcde"), 0, 4, 10); + test(S("abcdefghijklmnopqrst"), 10, 9, SV("abcde"), 0, 5, 10); + test(S("abcdefghijklmnopqrst"), 10, 9, SV("abcde"), 0, 6, 10); + test(S("abcdefghijklmnopqrst"), 10, 9, SV("abcde"), 1, 0, 9); + test(S("abcdefghijklmnopqrst"), 10, 9, SV("abcde"), 1, 1, 9); + test(S("abcdefghijklmnopqrst"), 10, 9, SV("abcde"), 1, 2, 9); + test(S("abcdefghijklmnopqrst"), 10, 9, SV("abcde"), 1, 3, 9); + test(S("abcdefghijklmnopqrst"), 10, 9, SV("abcde"), 1, 4, 9); + test(S("abcdefghijklmnopqrst"), 10, 9, SV("abcde"), 1, 5, 9); + test(S("abcdefghijklmnopqrst"), 10, 9, SV("abcde"), 2, 0, 9); + test(S("abcdefghijklmnopqrst"), 10, 9, SV("abcde"), 2, 1, 8); + test(S("abcdefghijklmnopqrst"), 10, 9, SV("abcde"), 2, 2, 8); + test(S("abcdefghijklmnopqrst"), 10, 9, SV("abcde"), 2, 3, 8); + test(S("abcdefghijklmnopqrst"), 10, 9, SV("abcde"), 2, 4, 8); + test(S("abcdefghijklmnopqrst"), 10, 9, SV("abcde"), 4, 0, 9); + test(S("abcdefghijklmnopqrst"), 10, 9, SV("abcde"), 4, 1, 6); + test(S("abcdefghijklmnopqrst"), 10, 9, SV("abcde"), 4, 2, 6); + test(S("abcdefghijklmnopqrst"), 10, 9, SV("abcde"), 5, 0, 9); + test(S("abcdefghijklmnopqrst"), 10, 9, SV("abcde"), 5, 1, 9); + test(S("abcdefghijklmnopqrst"), 10, 9, SV("abcde"), 6, 0, 0); + test(S("abcdefghijklmnopqrst"), 10, 9, SV("abcdefghij"), 0, 0, 9); + test(S("abcdefghijklmnopqrst"), 10, 9, SV("abcdefghij"), 0, 1, 10); + test(S("abcdefghijklmnopqrst"), 10, 9, SV("abcdefghij"), 0, 5, 10); + test(S("abcdefghijklmnopqrst"), 10, 9, SV("abcdefghij"), 0, 9, 10); + test(S("abcdefghijklmnopqrst"), 10, 9, SV("abcdefghij"), 0, 10, 10); + test(S("abcdefghijklmnopqrst"), 10, 9, SV("abcdefghij"), 0, 11, 10); + test(S("abcdefghijklmnopqrst"), 10, 9, SV("abcdefghij"), 1, 0, 9); + test(S("abcdefghijklmnopqrst"), 10, 9, SV("abcdefghij"), 1, 1, 9); + test(S("abcdefghijklmnopqrst"), 10, 9, SV("abcdefghij"), 1, 4, 9); + test(S("abcdefghijklmnopqrst"), 10, 9, SV("abcdefghij"), 1, 8, 9); + test(S("abcdefghijklmnopqrst"), 10, 9, SV("abcdefghij"), 1, 9, 9); + test(S("abcdefghijklmnopqrst"), 10, 9, SV("abcdefghij"), 1, 10, 9); + test(S("abcdefghijklmnopqrst"), 10, 9, SV("abcdefghij"), 5, 0, 9); + test(S("abcdefghijklmnopqrst"), 10, 9, SV("abcdefghij"), 5, 1, 5); + test(S("abcdefghijklmnopqrst"), 10, 9, SV("abcdefghij"), 5, 2, 5); + test(S("abcdefghijklmnopqrst"), 10, 9, SV("abcdefghij"), 5, 4, 5); + test(S("abcdefghijklmnopqrst"), 10, 9, SV("abcdefghij"), 5, 5, 5); + test(S("abcdefghijklmnopqrst"), 10, 9, SV("abcdefghij"), 5, 6, 5); + test(S("abcdefghijklmnopqrst"), 10, 9, SV("abcdefghij"), 9, 0, 9); + test(S("abcdefghijklmnopqrst"), 10, 9, SV("abcdefghij"), 9, 1, 1); + test(S("abcdefghijklmnopqrst"), 10, 9, SV("abcdefghij"), 9, 2, 1); + test(S("abcdefghijklmnopqrst"), 10, 9, SV("abcdefghij"), 10, 0, 9); + test(S("abcdefghijklmnopqrst"), 10, 9, SV("abcdefghij"), 10, 1, 9); + test(S("abcdefghijklmnopqrst"), 10, 9, SV("abcdefghij"), 11, 0, 0); + test(S("abcdefghijklmnopqrst"), 10, 9, SV("abcdefghijklmnopqrst"), 0, 0, 9); + test(S("abcdefghijklmnopqrst"), 10, 9, SV("abcdefghijklmnopqrst"), 0, 1, 10); + test(S("abcdefghijklmnopqrst"), 10, 9, SV("abcdefghijklmnopqrst"), 0, 10, 10); + test(S("abcdefghijklmnopqrst"), 10, 9, SV("abcdefghijklmnopqrst"), 0, 19, 10); + test(S("abcdefghijklmnopqrst"), 10, 9, SV("abcdefghijklmnopqrst"), 0, 20, 10); + test(S("abcdefghijklmnopqrst"), 10, 9, SV("abcdefghijklmnopqrst"), 0, 21, 10); + test(S("abcdefghijklmnopqrst"), 10, 9, SV("abcdefghijklmnopqrst"), 1, 0, 9); + test(S("abcdefghijklmnopqrst"), 10, 9, SV("abcdefghijklmnopqrst"), 1, 1, 9); + test(S("abcdefghijklmnopqrst"), 10, 9, SV("abcdefghijklmnopqrst"), 1, 9, 9); + test(S("abcdefghijklmnopqrst"), 10, 9, SV("abcdefghijklmnopqrst"), 1, 18, 9); + test(S("abcdefghijklmnopqrst"), 10, 9, SV("abcdefghijklmnopqrst"), 1, 19, 9); + test(S("abcdefghijklmnopqrst"), 10, 9, SV("abcdefghijklmnopqrst"), 1, 20, 9); + test(S("abcdefghijklmnopqrst"), 10, 9, SV("abcdefghijklmnopqrst"), 10, 0, 9); + test(S("abcdefghijklmnopqrst"), 10, 9, SV("abcdefghijklmnopqrst"), 10, 1, 8); + test(S("abcdefghijklmnopqrst"), 10, 9, SV("abcdefghijklmnopqrst"), 10, 5, 4); + test(S("abcdefghijklmnopqrst"), 10, 9, SV("abcdefghijklmnopqrst"), 10, 9, 0); + test(S("abcdefghijklmnopqrst"), 10, 9, SV("abcdefghijklmnopqrst"), 10, 10, -1); + test(S("abcdefghijklmnopqrst"), 10, 9, SV("abcdefghijklmnopqrst"), 10, 11, -1); + test(S("abcdefghijklmnopqrst"), 10, 9, SV("abcdefghijklmnopqrst"), 19, 0, 9); + test(S("abcdefghijklmnopqrst"), 10, 9, SV("abcdefghijklmnopqrst"), 19, 1, -9); + test(S("abcdefghijklmnopqrst"), 10, 9, SV("abcdefghijklmnopqrst"), 19, 2, -9); + test(S("abcdefghijklmnopqrst"), 10, 9, SV("abcdefghijklmnopqrst"), 20, 0, 9); + test(S("abcdefghijklmnopqrst"), 10, 9, SV("abcdefghijklmnopqrst"), 20, 1, 9); + test(S("abcdefghijklmnopqrst"), 10, 9, SV("abcdefghijklmnopqrst"), 21, 0, 0); + test(S("abcdefghijklmnopqrst"), 10, 10, SV(""), 0, 0, 10); + test(S("abcdefghijklmnopqrst"), 10, 10, SV(""), 0, 1, 10); + test(S("abcdefghijklmnopqrst"), 10, 10, SV(""), 1, 0, 0); + test(S("abcdefghijklmnopqrst"), 10, 10, SV("abcde"), 0, 0, 10); + test(S("abcdefghijklmnopqrst"), 10, 10, SV("abcde"), 0, 1, 10); + test(S("abcdefghijklmnopqrst"), 10, 10, SV("abcde"), 0, 2, 10); + test(S("abcdefghijklmnopqrst"), 10, 10, SV("abcde"), 0, 4, 10); + test(S("abcdefghijklmnopqrst"), 10, 10, SV("abcde"), 0, 5, 10); + test(S("abcdefghijklmnopqrst"), 10, 10, SV("abcde"), 0, 6, 10); + test(S("abcdefghijklmnopqrst"), 10, 10, SV("abcde"), 1, 0, 10); + test(S("abcdefghijklmnopqrst"), 10, 10, SV("abcde"), 1, 1, 9); + test(S("abcdefghijklmnopqrst"), 10, 10, SV("abcde"), 1, 2, 9); + test(S("abcdefghijklmnopqrst"), 10, 10, SV("abcde"), 1, 3, 9); + test(S("abcdefghijklmnopqrst"), 10, 10, SV("abcde"), 1, 4, 9); + test(S("abcdefghijklmnopqrst"), 10, 10, SV("abcde"), 1, 5, 9); + test(S("abcdefghijklmnopqrst"), 10, 10, SV("abcde"), 2, 0, 10); +} + +template +void test49() +{ + test(S("abcdefghijklmnopqrst"), 10, 10, SV("abcde"), 2, 1, 8); + test(S("abcdefghijklmnopqrst"), 10, 10, SV("abcde"), 2, 2, 8); + test(S("abcdefghijklmnopqrst"), 10, 10, SV("abcde"), 2, 3, 8); + test(S("abcdefghijklmnopqrst"), 10, 10, SV("abcde"), 2, 4, 8); + test(S("abcdefghijklmnopqrst"), 10, 10, SV("abcde"), 4, 0, 10); + test(S("abcdefghijklmnopqrst"), 10, 10, SV("abcde"), 4, 1, 6); + test(S("abcdefghijklmnopqrst"), 10, 10, SV("abcde"), 4, 2, 6); + test(S("abcdefghijklmnopqrst"), 10, 10, SV("abcde"), 5, 0, 10); + test(S("abcdefghijklmnopqrst"), 10, 10, SV("abcde"), 5, 1, 10); + test(S("abcdefghijklmnopqrst"), 10, 10, SV("abcde"), 6, 0, 0); + test(S("abcdefghijklmnopqrst"), 10, 10, SV("abcdefghij"), 0, 0, 10); + test(S("abcdefghijklmnopqrst"), 10, 10, SV("abcdefghij"), 0, 1, 10); + test(S("abcdefghijklmnopqrst"), 10, 10, SV("abcdefghij"), 0, 5, 10); + test(S("abcdefghijklmnopqrst"), 10, 10, SV("abcdefghij"), 0, 9, 10); + test(S("abcdefghijklmnopqrst"), 10, 10, SV("abcdefghij"), 0, 10, 10); + test(S("abcdefghijklmnopqrst"), 10, 10, SV("abcdefghij"), 0, 11, 10); + test(S("abcdefghijklmnopqrst"), 10, 10, SV("abcdefghij"), 1, 0, 10); + test(S("abcdefghijklmnopqrst"), 10, 10, SV("abcdefghij"), 1, 1, 9); + test(S("abcdefghijklmnopqrst"), 10, 10, SV("abcdefghij"), 1, 4, 9); + test(S("abcdefghijklmnopqrst"), 10, 10, SV("abcdefghij"), 1, 8, 9); + test(S("abcdefghijklmnopqrst"), 10, 10, SV("abcdefghij"), 1, 9, 9); + test(S("abcdefghijklmnopqrst"), 10, 10, SV("abcdefghij"), 1, 10, 9); + test(S("abcdefghijklmnopqrst"), 10, 10, SV("abcdefghij"), 5, 0, 10); + test(S("abcdefghijklmnopqrst"), 10, 10, SV("abcdefghij"), 5, 1, 5); + test(S("abcdefghijklmnopqrst"), 10, 10, SV("abcdefghij"), 5, 2, 5); + test(S("abcdefghijklmnopqrst"), 10, 10, SV("abcdefghij"), 5, 4, 5); + test(S("abcdefghijklmnopqrst"), 10, 10, SV("abcdefghij"), 5, 5, 5); + test(S("abcdefghijklmnopqrst"), 10, 10, SV("abcdefghij"), 5, 6, 5); + test(S("abcdefghijklmnopqrst"), 10, 10, SV("abcdefghij"), 9, 0, 10); + test(S("abcdefghijklmnopqrst"), 10, 10, SV("abcdefghij"), 9, 1, 1); + test(S("abcdefghijklmnopqrst"), 10, 10, SV("abcdefghij"), 9, 2, 1); + test(S("abcdefghijklmnopqrst"), 10, 10, SV("abcdefghij"), 10, 0, 10); + test(S("abcdefghijklmnopqrst"), 10, 10, SV("abcdefghij"), 10, 1, 10); + test(S("abcdefghijklmnopqrst"), 10, 10, SV("abcdefghij"), 11, 0, 0); + test(S("abcdefghijklmnopqrst"), 10, 10, SV("abcdefghijklmnopqrst"), 0, 0, 10); + test(S("abcdefghijklmnopqrst"), 10, 10, SV("abcdefghijklmnopqrst"), 0, 1, 10); + test(S("abcdefghijklmnopqrst"), 10, 10, SV("abcdefghijklmnopqrst"), 0, 10, 10); + test(S("abcdefghijklmnopqrst"), 10, 10, SV("abcdefghijklmnopqrst"), 0, 19, 10); + test(S("abcdefghijklmnopqrst"), 10, 10, SV("abcdefghijklmnopqrst"), 0, 20, 10); + test(S("abcdefghijklmnopqrst"), 10, 10, SV("abcdefghijklmnopqrst"), 0, 21, 10); + test(S("abcdefghijklmnopqrst"), 10, 10, SV("abcdefghijklmnopqrst"), 1, 0, 10); + test(S("abcdefghijklmnopqrst"), 10, 10, SV("abcdefghijklmnopqrst"), 1, 1, 9); + test(S("abcdefghijklmnopqrst"), 10, 10, SV("abcdefghijklmnopqrst"), 1, 9, 9); + test(S("abcdefghijklmnopqrst"), 10, 10, SV("abcdefghijklmnopqrst"), 1, 18, 9); + test(S("abcdefghijklmnopqrst"), 10, 10, SV("abcdefghijklmnopqrst"), 1, 19, 9); + test(S("abcdefghijklmnopqrst"), 10, 10, SV("abcdefghijklmnopqrst"), 1, 20, 9); + test(S("abcdefghijklmnopqrst"), 10, 10, SV("abcdefghijklmnopqrst"), 10, 0, 10); + test(S("abcdefghijklmnopqrst"), 10, 10, SV("abcdefghijklmnopqrst"), 10, 1, 9); + test(S("abcdefghijklmnopqrst"), 10, 10, SV("abcdefghijklmnopqrst"), 10, 5, 5); + test(S("abcdefghijklmnopqrst"), 10, 10, SV("abcdefghijklmnopqrst"), 10, 9, 1); + test(S("abcdefghijklmnopqrst"), 10, 10, SV("abcdefghijklmnopqrst"), 10, 10, 0); + test(S("abcdefghijklmnopqrst"), 10, 10, SV("abcdefghijklmnopqrst"), 10, 11, 0); + test(S("abcdefghijklmnopqrst"), 10, 10, SV("abcdefghijklmnopqrst"), 19, 0, 10); + test(S("abcdefghijklmnopqrst"), 10, 10, SV("abcdefghijklmnopqrst"), 19, 1, -9); + test(S("abcdefghijklmnopqrst"), 10, 10, SV("abcdefghijklmnopqrst"), 19, 2, -9); + test(S("abcdefghijklmnopqrst"), 10, 10, SV("abcdefghijklmnopqrst"), 20, 0, 10); + test(S("abcdefghijklmnopqrst"), 10, 10, SV("abcdefghijklmnopqrst"), 20, 1, 10); + test(S("abcdefghijklmnopqrst"), 10, 10, SV("abcdefghijklmnopqrst"), 21, 0, 0); + test(S("abcdefghijklmnopqrst"), 10, 11, SV(""), 0, 0, 10); + test(S("abcdefghijklmnopqrst"), 10, 11, SV(""), 0, 1, 10); + test(S("abcdefghijklmnopqrst"), 10, 11, SV(""), 1, 0, 0); + test(S("abcdefghijklmnopqrst"), 10, 11, SV("abcde"), 0, 0, 10); + test(S("abcdefghijklmnopqrst"), 10, 11, SV("abcde"), 0, 1, 10); + test(S("abcdefghijklmnopqrst"), 10, 11, SV("abcde"), 0, 2, 10); + test(S("abcdefghijklmnopqrst"), 10, 11, SV("abcde"), 0, 4, 10); + test(S("abcdefghijklmnopqrst"), 10, 11, SV("abcde"), 0, 5, 10); + test(S("abcdefghijklmnopqrst"), 10, 11, SV("abcde"), 0, 6, 10); + test(S("abcdefghijklmnopqrst"), 10, 11, SV("abcde"), 1, 0, 10); + test(S("abcdefghijklmnopqrst"), 10, 11, SV("abcde"), 1, 1, 9); + test(S("abcdefghijklmnopqrst"), 10, 11, SV("abcde"), 1, 2, 9); + test(S("abcdefghijklmnopqrst"), 10, 11, SV("abcde"), 1, 3, 9); + test(S("abcdefghijklmnopqrst"), 10, 11, SV("abcde"), 1, 4, 9); + test(S("abcdefghijklmnopqrst"), 10, 11, SV("abcde"), 1, 5, 9); + test(S("abcdefghijklmnopqrst"), 10, 11, SV("abcde"), 2, 0, 10); + test(S("abcdefghijklmnopqrst"), 10, 11, SV("abcde"), 2, 1, 8); + test(S("abcdefghijklmnopqrst"), 10, 11, SV("abcde"), 2, 2, 8); + test(S("abcdefghijklmnopqrst"), 10, 11, SV("abcde"), 2, 3, 8); + test(S("abcdefghijklmnopqrst"), 10, 11, SV("abcde"), 2, 4, 8); + test(S("abcdefghijklmnopqrst"), 10, 11, SV("abcde"), 4, 0, 10); + test(S("abcdefghijklmnopqrst"), 10, 11, SV("abcde"), 4, 1, 6); + test(S("abcdefghijklmnopqrst"), 10, 11, SV("abcde"), 4, 2, 6); + test(S("abcdefghijklmnopqrst"), 10, 11, SV("abcde"), 5, 0, 10); + test(S("abcdefghijklmnopqrst"), 10, 11, SV("abcde"), 5, 1, 10); + test(S("abcdefghijklmnopqrst"), 10, 11, SV("abcde"), 6, 0, 0); + test(S("abcdefghijklmnopqrst"), 10, 11, SV("abcdefghij"), 0, 0, 10); + test(S("abcdefghijklmnopqrst"), 10, 11, SV("abcdefghij"), 0, 1, 10); + test(S("abcdefghijklmnopqrst"), 10, 11, SV("abcdefghij"), 0, 5, 10); + test(S("abcdefghijklmnopqrst"), 10, 11, SV("abcdefghij"), 0, 9, 10); + test(S("abcdefghijklmnopqrst"), 10, 11, SV("abcdefghij"), 0, 10, 10); + test(S("abcdefghijklmnopqrst"), 10, 11, SV("abcdefghij"), 0, 11, 10); + test(S("abcdefghijklmnopqrst"), 10, 11, SV("abcdefghij"), 1, 0, 10); + test(S("abcdefghijklmnopqrst"), 10, 11, SV("abcdefghij"), 1, 1, 9); + test(S("abcdefghijklmnopqrst"), 10, 11, SV("abcdefghij"), 1, 4, 9); + test(S("abcdefghijklmnopqrst"), 10, 11, SV("abcdefghij"), 1, 8, 9); + test(S("abcdefghijklmnopqrst"), 10, 11, SV("abcdefghij"), 1, 9, 9); + test(S("abcdefghijklmnopqrst"), 10, 11, SV("abcdefghij"), 1, 10, 9); + test(S("abcdefghijklmnopqrst"), 10, 11, SV("abcdefghij"), 5, 0, 10); + test(S("abcdefghijklmnopqrst"), 10, 11, SV("abcdefghij"), 5, 1, 5); + test(S("abcdefghijklmnopqrst"), 10, 11, SV("abcdefghij"), 5, 2, 5); + test(S("abcdefghijklmnopqrst"), 10, 11, SV("abcdefghij"), 5, 4, 5); +} + +template +void test50() +{ + test(S("abcdefghijklmnopqrst"), 10, 11, SV("abcdefghij"), 5, 5, 5); + test(S("abcdefghijklmnopqrst"), 10, 11, SV("abcdefghij"), 5, 6, 5); + test(S("abcdefghijklmnopqrst"), 10, 11, SV("abcdefghij"), 9, 0, 10); + test(S("abcdefghijklmnopqrst"), 10, 11, SV("abcdefghij"), 9, 1, 1); + test(S("abcdefghijklmnopqrst"), 10, 11, SV("abcdefghij"), 9, 2, 1); + test(S("abcdefghijklmnopqrst"), 10, 11, SV("abcdefghij"), 10, 0, 10); + test(S("abcdefghijklmnopqrst"), 10, 11, SV("abcdefghij"), 10, 1, 10); + test(S("abcdefghijklmnopqrst"), 10, 11, SV("abcdefghij"), 11, 0, 0); + test(S("abcdefghijklmnopqrst"), 10, 11, SV("abcdefghijklmnopqrst"), 0, 0, 10); + test(S("abcdefghijklmnopqrst"), 10, 11, SV("abcdefghijklmnopqrst"), 0, 1, 10); + test(S("abcdefghijklmnopqrst"), 10, 11, SV("abcdefghijklmnopqrst"), 0, 10, 10); + test(S("abcdefghijklmnopqrst"), 10, 11, SV("abcdefghijklmnopqrst"), 0, 19, 10); + test(S("abcdefghijklmnopqrst"), 10, 11, SV("abcdefghijklmnopqrst"), 0, 20, 10); + test(S("abcdefghijklmnopqrst"), 10, 11, SV("abcdefghijklmnopqrst"), 0, 21, 10); + test(S("abcdefghijklmnopqrst"), 10, 11, SV("abcdefghijklmnopqrst"), 1, 0, 10); + test(S("abcdefghijklmnopqrst"), 10, 11, SV("abcdefghijklmnopqrst"), 1, 1, 9); + test(S("abcdefghijklmnopqrst"), 10, 11, SV("abcdefghijklmnopqrst"), 1, 9, 9); + test(S("abcdefghijklmnopqrst"), 10, 11, SV("abcdefghijklmnopqrst"), 1, 18, 9); + test(S("abcdefghijklmnopqrst"), 10, 11, SV("abcdefghijklmnopqrst"), 1, 19, 9); + test(S("abcdefghijklmnopqrst"), 10, 11, SV("abcdefghijklmnopqrst"), 1, 20, 9); + test(S("abcdefghijklmnopqrst"), 10, 11, SV("abcdefghijklmnopqrst"), 10, 0, 10); + test(S("abcdefghijklmnopqrst"), 10, 11, SV("abcdefghijklmnopqrst"), 10, 1, 9); + test(S("abcdefghijklmnopqrst"), 10, 11, SV("abcdefghijklmnopqrst"), 10, 5, 5); + test(S("abcdefghijklmnopqrst"), 10, 11, SV("abcdefghijklmnopqrst"), 10, 9, 1); + test(S("abcdefghijklmnopqrst"), 10, 11, SV("abcdefghijklmnopqrst"), 10, 10, 0); + test(S("abcdefghijklmnopqrst"), 10, 11, SV("abcdefghijklmnopqrst"), 10, 11, 0); + test(S("abcdefghijklmnopqrst"), 10, 11, SV("abcdefghijklmnopqrst"), 19, 0, 10); + test(S("abcdefghijklmnopqrst"), 10, 11, SV("abcdefghijklmnopqrst"), 19, 1, -9); + test(S("abcdefghijklmnopqrst"), 10, 11, SV("abcdefghijklmnopqrst"), 19, 2, -9); + test(S("abcdefghijklmnopqrst"), 10, 11, SV("abcdefghijklmnopqrst"), 20, 0, 10); + test(S("abcdefghijklmnopqrst"), 10, 11, SV("abcdefghijklmnopqrst"), 20, 1, 10); + test(S("abcdefghijklmnopqrst"), 10, 11, SV("abcdefghijklmnopqrst"), 21, 0, 0); + test(S("abcdefghijklmnopqrst"), 19, 0, SV(""), 0, 0, 0); + test(S("abcdefghijklmnopqrst"), 19, 0, SV(""), 0, 1, 0); + test(S("abcdefghijklmnopqrst"), 19, 0, SV(""), 1, 0, 0); + test(S("abcdefghijklmnopqrst"), 19, 0, SV("abcde"), 0, 0, 0); + test(S("abcdefghijklmnopqrst"), 19, 0, SV("abcde"), 0, 1, -1); + test(S("abcdefghijklmnopqrst"), 19, 0, SV("abcde"), 0, 2, -2); + test(S("abcdefghijklmnopqrst"), 19, 0, SV("abcde"), 0, 4, -4); + test(S("abcdefghijklmnopqrst"), 19, 0, SV("abcde"), 0, 5, -5); + test(S("abcdefghijklmnopqrst"), 19, 0, SV("abcde"), 0, 6, -5); + test(S("abcdefghijklmnopqrst"), 19, 0, SV("abcde"), 1, 0, 0); + test(S("abcdefghijklmnopqrst"), 19, 0, SV("abcde"), 1, 1, -1); + test(S("abcdefghijklmnopqrst"), 19, 0, SV("abcde"), 1, 2, -2); + test(S("abcdefghijklmnopqrst"), 19, 0, SV("abcde"), 1, 3, -3); + test(S("abcdefghijklmnopqrst"), 19, 0, SV("abcde"), 1, 4, -4); + test(S("abcdefghijklmnopqrst"), 19, 0, SV("abcde"), 1, 5, -4); + test(S("abcdefghijklmnopqrst"), 19, 0, SV("abcde"), 2, 0, 0); + test(S("abcdefghijklmnopqrst"), 19, 0, SV("abcde"), 2, 1, -1); + test(S("abcdefghijklmnopqrst"), 19, 0, SV("abcde"), 2, 2, -2); + test(S("abcdefghijklmnopqrst"), 19, 0, SV("abcde"), 2, 3, -3); + test(S("abcdefghijklmnopqrst"), 19, 0, SV("abcde"), 2, 4, -3); + test(S("abcdefghijklmnopqrst"), 19, 0, SV("abcde"), 4, 0, 0); + test(S("abcdefghijklmnopqrst"), 19, 0, SV("abcde"), 4, 1, -1); + test(S("abcdefghijklmnopqrst"), 19, 0, SV("abcde"), 4, 2, -1); + test(S("abcdefghijklmnopqrst"), 19, 0, SV("abcde"), 5, 0, 0); + test(S("abcdefghijklmnopqrst"), 19, 0, SV("abcde"), 5, 1, 0); + test(S("abcdefghijklmnopqrst"), 19, 0, SV("abcde"), 6, 0, 0); + test(S("abcdefghijklmnopqrst"), 19, 0, SV("abcdefghij"), 0, 0, 0); + test(S("abcdefghijklmnopqrst"), 19, 0, SV("abcdefghij"), 0, 1, -1); + test(S("abcdefghijklmnopqrst"), 19, 0, SV("abcdefghij"), 0, 5, -5); + test(S("abcdefghijklmnopqrst"), 19, 0, SV("abcdefghij"), 0, 9, -9); + test(S("abcdefghijklmnopqrst"), 19, 0, SV("abcdefghij"), 0, 10, -10); + test(S("abcdefghijklmnopqrst"), 19, 0, SV("abcdefghij"), 0, 11, -10); + test(S("abcdefghijklmnopqrst"), 19, 0, SV("abcdefghij"), 1, 0, 0); + test(S("abcdefghijklmnopqrst"), 19, 0, SV("abcdefghij"), 1, 1, -1); + test(S("abcdefghijklmnopqrst"), 19, 0, SV("abcdefghij"), 1, 4, -4); + test(S("abcdefghijklmnopqrst"), 19, 0, SV("abcdefghij"), 1, 8, -8); + test(S("abcdefghijklmnopqrst"), 19, 0, SV("abcdefghij"), 1, 9, -9); + test(S("abcdefghijklmnopqrst"), 19, 0, SV("abcdefghij"), 1, 10, -9); + test(S("abcdefghijklmnopqrst"), 19, 0, SV("abcdefghij"), 5, 0, 0); + test(S("abcdefghijklmnopqrst"), 19, 0, SV("abcdefghij"), 5, 1, -1); + test(S("abcdefghijklmnopqrst"), 19, 0, SV("abcdefghij"), 5, 2, -2); + test(S("abcdefghijklmnopqrst"), 19, 0, SV("abcdefghij"), 5, 4, -4); + test(S("abcdefghijklmnopqrst"), 19, 0, SV("abcdefghij"), 5, 5, -5); + test(S("abcdefghijklmnopqrst"), 19, 0, SV("abcdefghij"), 5, 6, -5); + test(S("abcdefghijklmnopqrst"), 19, 0, SV("abcdefghij"), 9, 0, 0); + test(S("abcdefghijklmnopqrst"), 19, 0, SV("abcdefghij"), 9, 1, -1); + test(S("abcdefghijklmnopqrst"), 19, 0, SV("abcdefghij"), 9, 2, -1); + test(S("abcdefghijklmnopqrst"), 19, 0, SV("abcdefghij"), 10, 0, 0); + test(S("abcdefghijklmnopqrst"), 19, 0, SV("abcdefghij"), 10, 1, 0); + test(S("abcdefghijklmnopqrst"), 19, 0, SV("abcdefghij"), 11, 0, 0); + test(S("abcdefghijklmnopqrst"), 19, 0, SV("abcdefghijklmnopqrst"), 0, 0, 0); + test(S("abcdefghijklmnopqrst"), 19, 0, SV("abcdefghijklmnopqrst"), 0, 1, -1); + test(S("abcdefghijklmnopqrst"), 19, 0, SV("abcdefghijklmnopqrst"), 0, 10, -10); + test(S("abcdefghijklmnopqrst"), 19, 0, SV("abcdefghijklmnopqrst"), 0, 19, -19); + test(S("abcdefghijklmnopqrst"), 19, 0, SV("abcdefghijklmnopqrst"), 0, 20, -20); + test(S("abcdefghijklmnopqrst"), 19, 0, SV("abcdefghijklmnopqrst"), 0, 21, -20); + test(S("abcdefghijklmnopqrst"), 19, 0, SV("abcdefghijklmnopqrst"), 1, 0, 0); + test(S("abcdefghijklmnopqrst"), 19, 0, SV("abcdefghijklmnopqrst"), 1, 1, -1); + test(S("abcdefghijklmnopqrst"), 19, 0, SV("abcdefghijklmnopqrst"), 1, 9, -9); + test(S("abcdefghijklmnopqrst"), 19, 0, SV("abcdefghijklmnopqrst"), 1, 18, -18); + test(S("abcdefghijklmnopqrst"), 19, 0, SV("abcdefghijklmnopqrst"), 1, 19, -19); + test(S("abcdefghijklmnopqrst"), 19, 0, SV("abcdefghijklmnopqrst"), 1, 20, -19); + test(S("abcdefghijklmnopqrst"), 19, 0, SV("abcdefghijklmnopqrst"), 10, 0, 0); + test(S("abcdefghijklmnopqrst"), 19, 0, SV("abcdefghijklmnopqrst"), 10, 1, -1); + test(S("abcdefghijklmnopqrst"), 19, 0, SV("abcdefghijklmnopqrst"), 10, 5, -5); + test(S("abcdefghijklmnopqrst"), 19, 0, SV("abcdefghijklmnopqrst"), 10, 9, -9); + test(S("abcdefghijklmnopqrst"), 19, 0, SV("abcdefghijklmnopqrst"), 10, 10, -10); + test(S("abcdefghijklmnopqrst"), 19, 0, SV("abcdefghijklmnopqrst"), 10, 11, -10); +} + +template +void test51() +{ + test(S("abcdefghijklmnopqrst"), 19, 0, SV("abcdefghijklmnopqrst"), 19, 0, 0); + test(S("abcdefghijklmnopqrst"), 19, 0, SV("abcdefghijklmnopqrst"), 19, 1, -1); + test(S("abcdefghijklmnopqrst"), 19, 0, SV("abcdefghijklmnopqrst"), 19, 2, -1); + test(S("abcdefghijklmnopqrst"), 19, 0, SV("abcdefghijklmnopqrst"), 20, 0, 0); + test(S("abcdefghijklmnopqrst"), 19, 0, SV("abcdefghijklmnopqrst"), 20, 1, 0); + test(S("abcdefghijklmnopqrst"), 19, 0, SV("abcdefghijklmnopqrst"), 21, 0, 0); + test(S("abcdefghijklmnopqrst"), 19, 1, SV(""), 0, 0, 1); + test(S("abcdefghijklmnopqrst"), 19, 1, SV(""), 0, 1, 1); + test(S("abcdefghijklmnopqrst"), 19, 1, SV(""), 1, 0, 0); + test(S("abcdefghijklmnopqrst"), 19, 1, SV("abcde"), 0, 0, 1); + test(S("abcdefghijklmnopqrst"), 19, 1, SV("abcde"), 0, 1, 19); + test(S("abcdefghijklmnopqrst"), 19, 1, SV("abcde"), 0, 2, 19); + test(S("abcdefghijklmnopqrst"), 19, 1, SV("abcde"), 0, 4, 19); + test(S("abcdefghijklmnopqrst"), 19, 1, SV("abcde"), 0, 5, 19); + test(S("abcdefghijklmnopqrst"), 19, 1, SV("abcde"), 0, 6, 19); + test(S("abcdefghijklmnopqrst"), 19, 1, SV("abcde"), 1, 0, 1); + test(S("abcdefghijklmnopqrst"), 19, 1, SV("abcde"), 1, 1, 18); + test(S("abcdefghijklmnopqrst"), 19, 1, SV("abcde"), 1, 2, 18); + test(S("abcdefghijklmnopqrst"), 19, 1, SV("abcde"), 1, 3, 18); + test(S("abcdefghijklmnopqrst"), 19, 1, SV("abcde"), 1, 4, 18); + test(S("abcdefghijklmnopqrst"), 19, 1, SV("abcde"), 1, 5, 18); + test(S("abcdefghijklmnopqrst"), 19, 1, SV("abcde"), 2, 0, 1); + test(S("abcdefghijklmnopqrst"), 19, 1, SV("abcde"), 2, 1, 17); + test(S("abcdefghijklmnopqrst"), 19, 1, SV("abcde"), 2, 2, 17); + test(S("abcdefghijklmnopqrst"), 19, 1, SV("abcde"), 2, 3, 17); + test(S("abcdefghijklmnopqrst"), 19, 1, SV("abcde"), 2, 4, 17); + test(S("abcdefghijklmnopqrst"), 19, 1, SV("abcde"), 4, 0, 1); + test(S("abcdefghijklmnopqrst"), 19, 1, SV("abcde"), 4, 1, 15); + test(S("abcdefghijklmnopqrst"), 19, 1, SV("abcde"), 4, 2, 15); + test(S("abcdefghijklmnopqrst"), 19, 1, SV("abcde"), 5, 0, 1); + test(S("abcdefghijklmnopqrst"), 19, 1, SV("abcde"), 5, 1, 1); + test(S("abcdefghijklmnopqrst"), 19, 1, SV("abcde"), 6, 0, 0); + test(S("abcdefghijklmnopqrst"), 19, 1, SV("abcdefghij"), 0, 0, 1); + test(S("abcdefghijklmnopqrst"), 19, 1, SV("abcdefghij"), 0, 1, 19); + test(S("abcdefghijklmnopqrst"), 19, 1, SV("abcdefghij"), 0, 5, 19); + test(S("abcdefghijklmnopqrst"), 19, 1, SV("abcdefghij"), 0, 9, 19); + test(S("abcdefghijklmnopqrst"), 19, 1, SV("abcdefghij"), 0, 10, 19); + test(S("abcdefghijklmnopqrst"), 19, 1, SV("abcdefghij"), 0, 11, 19); + test(S("abcdefghijklmnopqrst"), 19, 1, SV("abcdefghij"), 1, 0, 1); + test(S("abcdefghijklmnopqrst"), 19, 1, SV("abcdefghij"), 1, 1, 18); + test(S("abcdefghijklmnopqrst"), 19, 1, SV("abcdefghij"), 1, 4, 18); + test(S("abcdefghijklmnopqrst"), 19, 1, SV("abcdefghij"), 1, 8, 18); + test(S("abcdefghijklmnopqrst"), 19, 1, SV("abcdefghij"), 1, 9, 18); + test(S("abcdefghijklmnopqrst"), 19, 1, SV("abcdefghij"), 1, 10, 18); + test(S("abcdefghijklmnopqrst"), 19, 1, SV("abcdefghij"), 5, 0, 1); + test(S("abcdefghijklmnopqrst"), 19, 1, SV("abcdefghij"), 5, 1, 14); + test(S("abcdefghijklmnopqrst"), 19, 1, SV("abcdefghij"), 5, 2, 14); + test(S("abcdefghijklmnopqrst"), 19, 1, SV("abcdefghij"), 5, 4, 14); + test(S("abcdefghijklmnopqrst"), 19, 1, SV("abcdefghij"), 5, 5, 14); + test(S("abcdefghijklmnopqrst"), 19, 1, SV("abcdefghij"), 5, 6, 14); + test(S("abcdefghijklmnopqrst"), 19, 1, SV("abcdefghij"), 9, 0, 1); + test(S("abcdefghijklmnopqrst"), 19, 1, SV("abcdefghij"), 9, 1, 10); + test(S("abcdefghijklmnopqrst"), 19, 1, SV("abcdefghij"), 9, 2, 10); + test(S("abcdefghijklmnopqrst"), 19, 1, SV("abcdefghij"), 10, 0, 1); + test(S("abcdefghijklmnopqrst"), 19, 1, SV("abcdefghij"), 10, 1, 1); + test(S("abcdefghijklmnopqrst"), 19, 1, SV("abcdefghij"), 11, 0, 0); + test(S("abcdefghijklmnopqrst"), 19, 1, SV("abcdefghijklmnopqrst"), 0, 0, 1); + test(S("abcdefghijklmnopqrst"), 19, 1, SV("abcdefghijklmnopqrst"), 0, 1, 19); + test(S("abcdefghijklmnopqrst"), 19, 1, SV("abcdefghijklmnopqrst"), 0, 10, 19); + test(S("abcdefghijklmnopqrst"), 19, 1, SV("abcdefghijklmnopqrst"), 0, 19, 19); + test(S("abcdefghijklmnopqrst"), 19, 1, SV("abcdefghijklmnopqrst"), 0, 20, 19); + test(S("abcdefghijklmnopqrst"), 19, 1, SV("abcdefghijklmnopqrst"), 0, 21, 19); + test(S("abcdefghijklmnopqrst"), 19, 1, SV("abcdefghijklmnopqrst"), 1, 0, 1); + test(S("abcdefghijklmnopqrst"), 19, 1, SV("abcdefghijklmnopqrst"), 1, 1, 18); + test(S("abcdefghijklmnopqrst"), 19, 1, SV("abcdefghijklmnopqrst"), 1, 9, 18); + test(S("abcdefghijklmnopqrst"), 19, 1, SV("abcdefghijklmnopqrst"), 1, 18, 18); + test(S("abcdefghijklmnopqrst"), 19, 1, SV("abcdefghijklmnopqrst"), 1, 19, 18); + test(S("abcdefghijklmnopqrst"), 19, 1, SV("abcdefghijklmnopqrst"), 1, 20, 18); + test(S("abcdefghijklmnopqrst"), 19, 1, SV("abcdefghijklmnopqrst"), 10, 0, 1); + test(S("abcdefghijklmnopqrst"), 19, 1, SV("abcdefghijklmnopqrst"), 10, 1, 9); + test(S("abcdefghijklmnopqrst"), 19, 1, SV("abcdefghijklmnopqrst"), 10, 5, 9); + test(S("abcdefghijklmnopqrst"), 19, 1, SV("abcdefghijklmnopqrst"), 10, 9, 9); + test(S("abcdefghijklmnopqrst"), 19, 1, SV("abcdefghijklmnopqrst"), 10, 10, 9); + test(S("abcdefghijklmnopqrst"), 19, 1, SV("abcdefghijklmnopqrst"), 10, 11, 9); + test(S("abcdefghijklmnopqrst"), 19, 1, SV("abcdefghijklmnopqrst"), 19, 0, 1); + test(S("abcdefghijklmnopqrst"), 19, 1, SV("abcdefghijklmnopqrst"), 19, 1, 0); + test(S("abcdefghijklmnopqrst"), 19, 1, SV("abcdefghijklmnopqrst"), 19, 2, 0); + test(S("abcdefghijklmnopqrst"), 19, 1, SV("abcdefghijklmnopqrst"), 20, 0, 1); + test(S("abcdefghijklmnopqrst"), 19, 1, SV("abcdefghijklmnopqrst"), 20, 1, 1); + test(S("abcdefghijklmnopqrst"), 19, 1, SV("abcdefghijklmnopqrst"), 21, 0, 0); + test(S("abcdefghijklmnopqrst"), 19, 2, SV(""), 0, 0, 1); + test(S("abcdefghijklmnopqrst"), 19, 2, SV(""), 0, 1, 1); + test(S("abcdefghijklmnopqrst"), 19, 2, SV(""), 1, 0, 0); + test(S("abcdefghijklmnopqrst"), 19, 2, SV("abcde"), 0, 0, 1); + test(S("abcdefghijklmnopqrst"), 19, 2, SV("abcde"), 0, 1, 19); + test(S("abcdefghijklmnopqrst"), 19, 2, SV("abcde"), 0, 2, 19); + test(S("abcdefghijklmnopqrst"), 19, 2, SV("abcde"), 0, 4, 19); + test(S("abcdefghijklmnopqrst"), 19, 2, SV("abcde"), 0, 5, 19); + test(S("abcdefghijklmnopqrst"), 19, 2, SV("abcde"), 0, 6, 19); + test(S("abcdefghijklmnopqrst"), 19, 2, SV("abcde"), 1, 0, 1); + test(S("abcdefghijklmnopqrst"), 19, 2, SV("abcde"), 1, 1, 18); + test(S("abcdefghijklmnopqrst"), 19, 2, SV("abcde"), 1, 2, 18); + test(S("abcdefghijklmnopqrst"), 19, 2, SV("abcde"), 1, 3, 18); + test(S("abcdefghijklmnopqrst"), 19, 2, SV("abcde"), 1, 4, 18); + test(S("abcdefghijklmnopqrst"), 19, 2, SV("abcde"), 1, 5, 18); + test(S("abcdefghijklmnopqrst"), 19, 2, SV("abcde"), 2, 0, 1); + test(S("abcdefghijklmnopqrst"), 19, 2, SV("abcde"), 2, 1, 17); + test(S("abcdefghijklmnopqrst"), 19, 2, SV("abcde"), 2, 2, 17); + test(S("abcdefghijklmnopqrst"), 19, 2, SV("abcde"), 2, 3, 17); + test(S("abcdefghijklmnopqrst"), 19, 2, SV("abcde"), 2, 4, 17); +} + +template +void test52() +{ + test(S("abcdefghijklmnopqrst"), 19, 2, SV("abcde"), 4, 0, 1); + test(S("abcdefghijklmnopqrst"), 19, 2, SV("abcde"), 4, 1, 15); + test(S("abcdefghijklmnopqrst"), 19, 2, SV("abcde"), 4, 2, 15); + test(S("abcdefghijklmnopqrst"), 19, 2, SV("abcde"), 5, 0, 1); + test(S("abcdefghijklmnopqrst"), 19, 2, SV("abcde"), 5, 1, 1); + test(S("abcdefghijklmnopqrst"), 19, 2, SV("abcde"), 6, 0, 0); + test(S("abcdefghijklmnopqrst"), 19, 2, SV("abcdefghij"), 0, 0, 1); + test(S("abcdefghijklmnopqrst"), 19, 2, SV("abcdefghij"), 0, 1, 19); + test(S("abcdefghijklmnopqrst"), 19, 2, SV("abcdefghij"), 0, 5, 19); + test(S("abcdefghijklmnopqrst"), 19, 2, SV("abcdefghij"), 0, 9, 19); + test(S("abcdefghijklmnopqrst"), 19, 2, SV("abcdefghij"), 0, 10, 19); + test(S("abcdefghijklmnopqrst"), 19, 2, SV("abcdefghij"), 0, 11, 19); + test(S("abcdefghijklmnopqrst"), 19, 2, SV("abcdefghij"), 1, 0, 1); + test(S("abcdefghijklmnopqrst"), 19, 2, SV("abcdefghij"), 1, 1, 18); + test(S("abcdefghijklmnopqrst"), 19, 2, SV("abcdefghij"), 1, 4, 18); + test(S("abcdefghijklmnopqrst"), 19, 2, SV("abcdefghij"), 1, 8, 18); + test(S("abcdefghijklmnopqrst"), 19, 2, SV("abcdefghij"), 1, 9, 18); + test(S("abcdefghijklmnopqrst"), 19, 2, SV("abcdefghij"), 1, 10, 18); + test(S("abcdefghijklmnopqrst"), 19, 2, SV("abcdefghij"), 5, 0, 1); + test(S("abcdefghijklmnopqrst"), 19, 2, SV("abcdefghij"), 5, 1, 14); + test(S("abcdefghijklmnopqrst"), 19, 2, SV("abcdefghij"), 5, 2, 14); + test(S("abcdefghijklmnopqrst"), 19, 2, SV("abcdefghij"), 5, 4, 14); + test(S("abcdefghijklmnopqrst"), 19, 2, SV("abcdefghij"), 5, 5, 14); + test(S("abcdefghijklmnopqrst"), 19, 2, SV("abcdefghij"), 5, 6, 14); + test(S("abcdefghijklmnopqrst"), 19, 2, SV("abcdefghij"), 9, 0, 1); + test(S("abcdefghijklmnopqrst"), 19, 2, SV("abcdefghij"), 9, 1, 10); + test(S("abcdefghijklmnopqrst"), 19, 2, SV("abcdefghij"), 9, 2, 10); + test(S("abcdefghijklmnopqrst"), 19, 2, SV("abcdefghij"), 10, 0, 1); + test(S("abcdefghijklmnopqrst"), 19, 2, SV("abcdefghij"), 10, 1, 1); + test(S("abcdefghijklmnopqrst"), 19, 2, SV("abcdefghij"), 11, 0, 0); + test(S("abcdefghijklmnopqrst"), 19, 2, SV("abcdefghijklmnopqrst"), 0, 0, 1); + test(S("abcdefghijklmnopqrst"), 19, 2, SV("abcdefghijklmnopqrst"), 0, 1, 19); + test(S("abcdefghijklmnopqrst"), 19, 2, SV("abcdefghijklmnopqrst"), 0, 10, 19); + test(S("abcdefghijklmnopqrst"), 19, 2, SV("abcdefghijklmnopqrst"), 0, 19, 19); + test(S("abcdefghijklmnopqrst"), 19, 2, SV("abcdefghijklmnopqrst"), 0, 20, 19); + test(S("abcdefghijklmnopqrst"), 19, 2, SV("abcdefghijklmnopqrst"), 0, 21, 19); + test(S("abcdefghijklmnopqrst"), 19, 2, SV("abcdefghijklmnopqrst"), 1, 0, 1); + test(S("abcdefghijklmnopqrst"), 19, 2, SV("abcdefghijklmnopqrst"), 1, 1, 18); + test(S("abcdefghijklmnopqrst"), 19, 2, SV("abcdefghijklmnopqrst"), 1, 9, 18); + test(S("abcdefghijklmnopqrst"), 19, 2, SV("abcdefghijklmnopqrst"), 1, 18, 18); + test(S("abcdefghijklmnopqrst"), 19, 2, SV("abcdefghijklmnopqrst"), 1, 19, 18); + test(S("abcdefghijklmnopqrst"), 19, 2, SV("abcdefghijklmnopqrst"), 1, 20, 18); + test(S("abcdefghijklmnopqrst"), 19, 2, SV("abcdefghijklmnopqrst"), 10, 0, 1); + test(S("abcdefghijklmnopqrst"), 19, 2, SV("abcdefghijklmnopqrst"), 10, 1, 9); + test(S("abcdefghijklmnopqrst"), 19, 2, SV("abcdefghijklmnopqrst"), 10, 5, 9); + test(S("abcdefghijklmnopqrst"), 19, 2, SV("abcdefghijklmnopqrst"), 10, 9, 9); + test(S("abcdefghijklmnopqrst"), 19, 2, SV("abcdefghijklmnopqrst"), 10, 10, 9); + test(S("abcdefghijklmnopqrst"), 19, 2, SV("abcdefghijklmnopqrst"), 10, 11, 9); + test(S("abcdefghijklmnopqrst"), 19, 2, SV("abcdefghijklmnopqrst"), 19, 0, 1); + test(S("abcdefghijklmnopqrst"), 19, 2, SV("abcdefghijklmnopqrst"), 19, 1, 0); + test(S("abcdefghijklmnopqrst"), 19, 2, SV("abcdefghijklmnopqrst"), 19, 2, 0); + test(S("abcdefghijklmnopqrst"), 19, 2, SV("abcdefghijklmnopqrst"), 20, 0, 1); + test(S("abcdefghijklmnopqrst"), 19, 2, SV("abcdefghijklmnopqrst"), 20, 1, 1); + test(S("abcdefghijklmnopqrst"), 19, 2, SV("abcdefghijklmnopqrst"), 21, 0, 0); + test(S("abcdefghijklmnopqrst"), 20, 0, SV(""), 0, 0, 0); + test(S("abcdefghijklmnopqrst"), 20, 0, SV(""), 0, 1, 0); + test(S("abcdefghijklmnopqrst"), 20, 0, SV(""), 1, 0, 0); + test(S("abcdefghijklmnopqrst"), 20, 0, SV("abcde"), 0, 0, 0); + test(S("abcdefghijklmnopqrst"), 20, 0, SV("abcde"), 0, 1, -1); + test(S("abcdefghijklmnopqrst"), 20, 0, SV("abcde"), 0, 2, -2); + test(S("abcdefghijklmnopqrst"), 20, 0, SV("abcde"), 0, 4, -4); + test(S("abcdefghijklmnopqrst"), 20, 0, SV("abcde"), 0, 5, -5); + test(S("abcdefghijklmnopqrst"), 20, 0, SV("abcde"), 0, 6, -5); + test(S("abcdefghijklmnopqrst"), 20, 0, SV("abcde"), 1, 0, 0); + test(S("abcdefghijklmnopqrst"), 20, 0, SV("abcde"), 1, 1, -1); + test(S("abcdefghijklmnopqrst"), 20, 0, SV("abcde"), 1, 2, -2); + test(S("abcdefghijklmnopqrst"), 20, 0, SV("abcde"), 1, 3, -3); + test(S("abcdefghijklmnopqrst"), 20, 0, SV("abcde"), 1, 4, -4); + test(S("abcdefghijklmnopqrst"), 20, 0, SV("abcde"), 1, 5, -4); + test(S("abcdefghijklmnopqrst"), 20, 0, SV("abcde"), 2, 0, 0); + test(S("abcdefghijklmnopqrst"), 20, 0, SV("abcde"), 2, 1, -1); + test(S("abcdefghijklmnopqrst"), 20, 0, SV("abcde"), 2, 2, -2); + test(S("abcdefghijklmnopqrst"), 20, 0, SV("abcde"), 2, 3, -3); + test(S("abcdefghijklmnopqrst"), 20, 0, SV("abcde"), 2, 4, -3); + test(S("abcdefghijklmnopqrst"), 20, 0, SV("abcde"), 4, 0, 0); + test(S("abcdefghijklmnopqrst"), 20, 0, SV("abcde"), 4, 1, -1); + test(S("abcdefghijklmnopqrst"), 20, 0, SV("abcde"), 4, 2, -1); + test(S("abcdefghijklmnopqrst"), 20, 0, SV("abcde"), 5, 0, 0); + test(S("abcdefghijklmnopqrst"), 20, 0, SV("abcde"), 5, 1, 0); + test(S("abcdefghijklmnopqrst"), 20, 0, SV("abcde"), 6, 0, 0); + test(S("abcdefghijklmnopqrst"), 20, 0, SV("abcdefghij"), 0, 0, 0); + test(S("abcdefghijklmnopqrst"), 20, 0, SV("abcdefghij"), 0, 1, -1); + test(S("abcdefghijklmnopqrst"), 20, 0, SV("abcdefghij"), 0, 5, -5); + test(S("abcdefghijklmnopqrst"), 20, 0, SV("abcdefghij"), 0, 9, -9); + test(S("abcdefghijklmnopqrst"), 20, 0, SV("abcdefghij"), 0, 10, -10); + test(S("abcdefghijklmnopqrst"), 20, 0, SV("abcdefghij"), 0, 11, -10); + test(S("abcdefghijklmnopqrst"), 20, 0, SV("abcdefghij"), 1, 0, 0); + test(S("abcdefghijklmnopqrst"), 20, 0, SV("abcdefghij"), 1, 1, -1); + test(S("abcdefghijklmnopqrst"), 20, 0, SV("abcdefghij"), 1, 4, -4); + test(S("abcdefghijklmnopqrst"), 20, 0, SV("abcdefghij"), 1, 8, -8); + test(S("abcdefghijklmnopqrst"), 20, 0, SV("abcdefghij"), 1, 9, -9); + test(S("abcdefghijklmnopqrst"), 20, 0, SV("abcdefghij"), 1, 10, -9); + test(S("abcdefghijklmnopqrst"), 20, 0, SV("abcdefghij"), 5, 0, 0); + test(S("abcdefghijklmnopqrst"), 20, 0, SV("abcdefghij"), 5, 1, -1); + test(S("abcdefghijklmnopqrst"), 20, 0, SV("abcdefghij"), 5, 2, -2); + test(S("abcdefghijklmnopqrst"), 20, 0, SV("abcdefghij"), 5, 4, -4); + test(S("abcdefghijklmnopqrst"), 20, 0, SV("abcdefghij"), 5, 5, -5); + test(S("abcdefghijklmnopqrst"), 20, 0, SV("abcdefghij"), 5, 6, -5); + test(S("abcdefghijklmnopqrst"), 20, 0, SV("abcdefghij"), 9, 0, 0); + test(S("abcdefghijklmnopqrst"), 20, 0, SV("abcdefghij"), 9, 1, -1); +} + +template +void test53() +{ + test(S("abcdefghijklmnopqrst"), 20, 0, SV("abcdefghij"), 9, 2, -1); + test(S("abcdefghijklmnopqrst"), 20, 0, SV("abcdefghij"), 10, 0, 0); + test(S("abcdefghijklmnopqrst"), 20, 0, SV("abcdefghij"), 10, 1, 0); + test(S("abcdefghijklmnopqrst"), 20, 0, SV("abcdefghij"), 11, 0, 0); + test(S("abcdefghijklmnopqrst"), 20, 0, SV("abcdefghijklmnopqrst"), 0, 0, 0); + test(S("abcdefghijklmnopqrst"), 20, 0, SV("abcdefghijklmnopqrst"), 0, 1, -1); + test(S("abcdefghijklmnopqrst"), 20, 0, SV("abcdefghijklmnopqrst"), 0, 10, -10); + test(S("abcdefghijklmnopqrst"), 20, 0, SV("abcdefghijklmnopqrst"), 0, 19, -19); + test(S("abcdefghijklmnopqrst"), 20, 0, SV("abcdefghijklmnopqrst"), 0, 20, -20); + test(S("abcdefghijklmnopqrst"), 20, 0, SV("abcdefghijklmnopqrst"), 0, 21, -20); + test(S("abcdefghijklmnopqrst"), 20, 0, SV("abcdefghijklmnopqrst"), 1, 0, 0); + test(S("abcdefghijklmnopqrst"), 20, 0, SV("abcdefghijklmnopqrst"), 1, 1, -1); + test(S("abcdefghijklmnopqrst"), 20, 0, SV("abcdefghijklmnopqrst"), 1, 9, -9); + test(S("abcdefghijklmnopqrst"), 20, 0, SV("abcdefghijklmnopqrst"), 1, 18, -18); + test(S("abcdefghijklmnopqrst"), 20, 0, SV("abcdefghijklmnopqrst"), 1, 19, -19); + test(S("abcdefghijklmnopqrst"), 20, 0, SV("abcdefghijklmnopqrst"), 1, 20, -19); + test(S("abcdefghijklmnopqrst"), 20, 0, SV("abcdefghijklmnopqrst"), 10, 0, 0); + test(S("abcdefghijklmnopqrst"), 20, 0, SV("abcdefghijklmnopqrst"), 10, 1, -1); + test(S("abcdefghijklmnopqrst"), 20, 0, SV("abcdefghijklmnopqrst"), 10, 5, -5); + test(S("abcdefghijklmnopqrst"), 20, 0, SV("abcdefghijklmnopqrst"), 10, 9, -9); + test(S("abcdefghijklmnopqrst"), 20, 0, SV("abcdefghijklmnopqrst"), 10, 10, -10); + test(S("abcdefghijklmnopqrst"), 20, 0, SV("abcdefghijklmnopqrst"), 10, 11, -10); + test(S("abcdefghijklmnopqrst"), 20, 0, SV("abcdefghijklmnopqrst"), 19, 0, 0); + test(S("abcdefghijklmnopqrst"), 20, 0, SV("abcdefghijklmnopqrst"), 19, 1, -1); + test(S("abcdefghijklmnopqrst"), 20, 0, SV("abcdefghijklmnopqrst"), 19, 2, -1); + test(S("abcdefghijklmnopqrst"), 20, 0, SV("abcdefghijklmnopqrst"), 20, 0, 0); + test(S("abcdefghijklmnopqrst"), 20, 0, SV("abcdefghijklmnopqrst"), 20, 1, 0); + test(S("abcdefghijklmnopqrst"), 20, 0, SV("abcdefghijklmnopqrst"), 21, 0, 0); + test(S("abcdefghijklmnopqrst"), 20, 1, SV(""), 0, 0, 0); + test(S("abcdefghijklmnopqrst"), 20, 1, SV(""), 0, 1, 0); + test(S("abcdefghijklmnopqrst"), 20, 1, SV(""), 1, 0, 0); + test(S("abcdefghijklmnopqrst"), 20, 1, SV("abcde"), 0, 0, 0); + test(S("abcdefghijklmnopqrst"), 20, 1, SV("abcde"), 0, 1, -1); + test(S("abcdefghijklmnopqrst"), 20, 1, SV("abcde"), 0, 2, -2); + test(S("abcdefghijklmnopqrst"), 20, 1, SV("abcde"), 0, 4, -4); + test(S("abcdefghijklmnopqrst"), 20, 1, SV("abcde"), 0, 5, -5); + test(S("abcdefghijklmnopqrst"), 20, 1, SV("abcde"), 0, 6, -5); + test(S("abcdefghijklmnopqrst"), 20, 1, SV("abcde"), 1, 0, 0); + test(S("abcdefghijklmnopqrst"), 20, 1, SV("abcde"), 1, 1, -1); + test(S("abcdefghijklmnopqrst"), 20, 1, SV("abcde"), 1, 2, -2); + test(S("abcdefghijklmnopqrst"), 20, 1, SV("abcde"), 1, 3, -3); + test(S("abcdefghijklmnopqrst"), 20, 1, SV("abcde"), 1, 4, -4); + test(S("abcdefghijklmnopqrst"), 20, 1, SV("abcde"), 1, 5, -4); + test(S("abcdefghijklmnopqrst"), 20, 1, SV("abcde"), 2, 0, 0); + test(S("abcdefghijklmnopqrst"), 20, 1, SV("abcde"), 2, 1, -1); + test(S("abcdefghijklmnopqrst"), 20, 1, SV("abcde"), 2, 2, -2); + test(S("abcdefghijklmnopqrst"), 20, 1, SV("abcde"), 2, 3, -3); + test(S("abcdefghijklmnopqrst"), 20, 1, SV("abcde"), 2, 4, -3); + test(S("abcdefghijklmnopqrst"), 20, 1, SV("abcde"), 4, 0, 0); + test(S("abcdefghijklmnopqrst"), 20, 1, SV("abcde"), 4, 1, -1); + test(S("abcdefghijklmnopqrst"), 20, 1, SV("abcde"), 4, 2, -1); + test(S("abcdefghijklmnopqrst"), 20, 1, SV("abcde"), 5, 0, 0); + test(S("abcdefghijklmnopqrst"), 20, 1, SV("abcde"), 5, 1, 0); + test(S("abcdefghijklmnopqrst"), 20, 1, SV("abcde"), 6, 0, 0); + test(S("abcdefghijklmnopqrst"), 20, 1, SV("abcdefghij"), 0, 0, 0); + test(S("abcdefghijklmnopqrst"), 20, 1, SV("abcdefghij"), 0, 1, -1); + test(S("abcdefghijklmnopqrst"), 20, 1, SV("abcdefghij"), 0, 5, -5); + test(S("abcdefghijklmnopqrst"), 20, 1, SV("abcdefghij"), 0, 9, -9); + test(S("abcdefghijklmnopqrst"), 20, 1, SV("abcdefghij"), 0, 10, -10); + test(S("abcdefghijklmnopqrst"), 20, 1, SV("abcdefghij"), 0, 11, -10); + test(S("abcdefghijklmnopqrst"), 20, 1, SV("abcdefghij"), 1, 0, 0); + test(S("abcdefghijklmnopqrst"), 20, 1, SV("abcdefghij"), 1, 1, -1); + test(S("abcdefghijklmnopqrst"), 20, 1, SV("abcdefghij"), 1, 4, -4); + test(S("abcdefghijklmnopqrst"), 20, 1, SV("abcdefghij"), 1, 8, -8); + test(S("abcdefghijklmnopqrst"), 20, 1, SV("abcdefghij"), 1, 9, -9); + test(S("abcdefghijklmnopqrst"), 20, 1, SV("abcdefghij"), 1, 10, -9); + test(S("abcdefghijklmnopqrst"), 20, 1, SV("abcdefghij"), 5, 0, 0); + test(S("abcdefghijklmnopqrst"), 20, 1, SV("abcdefghij"), 5, 1, -1); + test(S("abcdefghijklmnopqrst"), 20, 1, SV("abcdefghij"), 5, 2, -2); + test(S("abcdefghijklmnopqrst"), 20, 1, SV("abcdefghij"), 5, 4, -4); + test(S("abcdefghijklmnopqrst"), 20, 1, SV("abcdefghij"), 5, 5, -5); + test(S("abcdefghijklmnopqrst"), 20, 1, SV("abcdefghij"), 5, 6, -5); + test(S("abcdefghijklmnopqrst"), 20, 1, SV("abcdefghij"), 9, 0, 0); + test(S("abcdefghijklmnopqrst"), 20, 1, SV("abcdefghij"), 9, 1, -1); + test(S("abcdefghijklmnopqrst"), 20, 1, SV("abcdefghij"), 9, 2, -1); + test(S("abcdefghijklmnopqrst"), 20, 1, SV("abcdefghij"), 10, 0, 0); + test(S("abcdefghijklmnopqrst"), 20, 1, SV("abcdefghij"), 10, 1, 0); + test(S("abcdefghijklmnopqrst"), 20, 1, SV("abcdefghij"), 11, 0, 0); + test(S("abcdefghijklmnopqrst"), 20, 1, SV("abcdefghijklmnopqrst"), 0, 0, 0); + test(S("abcdefghijklmnopqrst"), 20, 1, SV("abcdefghijklmnopqrst"), 0, 1, -1); + test(S("abcdefghijklmnopqrst"), 20, 1, SV("abcdefghijklmnopqrst"), 0, 10, -10); + test(S("abcdefghijklmnopqrst"), 20, 1, SV("abcdefghijklmnopqrst"), 0, 19, -19); + test(S("abcdefghijklmnopqrst"), 20, 1, SV("abcdefghijklmnopqrst"), 0, 20, -20); + test(S("abcdefghijklmnopqrst"), 20, 1, SV("abcdefghijklmnopqrst"), 0, 21, -20); + test(S("abcdefghijklmnopqrst"), 20, 1, SV("abcdefghijklmnopqrst"), 1, 0, 0); + test(S("abcdefghijklmnopqrst"), 20, 1, SV("abcdefghijklmnopqrst"), 1, 1, -1); + test(S("abcdefghijklmnopqrst"), 20, 1, SV("abcdefghijklmnopqrst"), 1, 9, -9); + test(S("abcdefghijklmnopqrst"), 20, 1, SV("abcdefghijklmnopqrst"), 1, 18, -18); + test(S("abcdefghijklmnopqrst"), 20, 1, SV("abcdefghijklmnopqrst"), 1, 19, -19); + test(S("abcdefghijklmnopqrst"), 20, 1, SV("abcdefghijklmnopqrst"), 1, 20, -19); + test(S("abcdefghijklmnopqrst"), 20, 1, SV("abcdefghijklmnopqrst"), 10, 0, 0); + test(S("abcdefghijklmnopqrst"), 20, 1, SV("abcdefghijklmnopqrst"), 10, 1, -1); + test(S("abcdefghijklmnopqrst"), 20, 1, SV("abcdefghijklmnopqrst"), 10, 5, -5); + test(S("abcdefghijklmnopqrst"), 20, 1, SV("abcdefghijklmnopqrst"), 10, 9, -9); + test(S("abcdefghijklmnopqrst"), 20, 1, SV("abcdefghijklmnopqrst"), 10, 10, -10); + test(S("abcdefghijklmnopqrst"), 20, 1, SV("abcdefghijklmnopqrst"), 10, 11, -10); + test(S("abcdefghijklmnopqrst"), 20, 1, SV("abcdefghijklmnopqrst"), 19, 0, 0); + test(S("abcdefghijklmnopqrst"), 20, 1, SV("abcdefghijklmnopqrst"), 19, 1, -1); + test(S("abcdefghijklmnopqrst"), 20, 1, SV("abcdefghijklmnopqrst"), 19, 2, -1); + test(S("abcdefghijklmnopqrst"), 20, 1, SV("abcdefghijklmnopqrst"), 20, 0, 0); +} + +template +void test54() +{ + test(S("abcdefghijklmnopqrst"), 20, 1, SV("abcdefghijklmnopqrst"), 20, 1, 0); + test(S("abcdefghijklmnopqrst"), 20, 1, SV("abcdefghijklmnopqrst"), 21, 0, 0); + test(S("abcdefghijklmnopqrst"), 21, 0, SV(""), 0, 0, 0); + test(S("abcdefghijklmnopqrst"), 21, 0, SV(""), 0, 1, 0); + test(S("abcdefghijklmnopqrst"), 21, 0, SV(""), 1, 0, 0); + test(S("abcdefghijklmnopqrst"), 21, 0, SV("abcde"), 0, 0, 0); + test(S("abcdefghijklmnopqrst"), 21, 0, SV("abcde"), 0, 1, 0); + test(S("abcdefghijklmnopqrst"), 21, 0, SV("abcde"), 0, 2, 0); + test(S("abcdefghijklmnopqrst"), 21, 0, SV("abcde"), 0, 4, 0); + test(S("abcdefghijklmnopqrst"), 21, 0, SV("abcde"), 0, 5, 0); + test(S("abcdefghijklmnopqrst"), 21, 0, SV("abcde"), 0, 6, 0); + test(S("abcdefghijklmnopqrst"), 21, 0, SV("abcde"), 1, 0, 0); + test(S("abcdefghijklmnopqrst"), 21, 0, SV("abcde"), 1, 1, 0); + test(S("abcdefghijklmnopqrst"), 21, 0, SV("abcde"), 1, 2, 0); + test(S("abcdefghijklmnopqrst"), 21, 0, SV("abcde"), 1, 3, 0); + test(S("abcdefghijklmnopqrst"), 21, 0, SV("abcde"), 1, 4, 0); + test(S("abcdefghijklmnopqrst"), 21, 0, SV("abcde"), 1, 5, 0); + test(S("abcdefghijklmnopqrst"), 21, 0, SV("abcde"), 2, 0, 0); + test(S("abcdefghijklmnopqrst"), 21, 0, SV("abcde"), 2, 1, 0); + test(S("abcdefghijklmnopqrst"), 21, 0, SV("abcde"), 2, 2, 0); + test(S("abcdefghijklmnopqrst"), 21, 0, SV("abcde"), 2, 3, 0); + test(S("abcdefghijklmnopqrst"), 21, 0, SV("abcde"), 2, 4, 0); + test(S("abcdefghijklmnopqrst"), 21, 0, SV("abcde"), 4, 0, 0); + test(S("abcdefghijklmnopqrst"), 21, 0, SV("abcde"), 4, 1, 0); + test(S("abcdefghijklmnopqrst"), 21, 0, SV("abcde"), 4, 2, 0); + test(S("abcdefghijklmnopqrst"), 21, 0, SV("abcde"), 5, 0, 0); + test(S("abcdefghijklmnopqrst"), 21, 0, SV("abcde"), 5, 1, 0); + test(S("abcdefghijklmnopqrst"), 21, 0, SV("abcde"), 6, 0, 0); + test(S("abcdefghijklmnopqrst"), 21, 0, SV("abcdefghij"), 0, 0, 0); + test(S("abcdefghijklmnopqrst"), 21, 0, SV("abcdefghij"), 0, 1, 0); + test(S("abcdefghijklmnopqrst"), 21, 0, SV("abcdefghij"), 0, 5, 0); + test(S("abcdefghijklmnopqrst"), 21, 0, SV("abcdefghij"), 0, 9, 0); + test(S("abcdefghijklmnopqrst"), 21, 0, SV("abcdefghij"), 0, 10, 0); + test(S("abcdefghijklmnopqrst"), 21, 0, SV("abcdefghij"), 0, 11, 0); + test(S("abcdefghijklmnopqrst"), 21, 0, SV("abcdefghij"), 1, 0, 0); + test(S("abcdefghijklmnopqrst"), 21, 0, SV("abcdefghij"), 1, 1, 0); + test(S("abcdefghijklmnopqrst"), 21, 0, SV("abcdefghij"), 1, 4, 0); + test(S("abcdefghijklmnopqrst"), 21, 0, SV("abcdefghij"), 1, 8, 0); + test(S("abcdefghijklmnopqrst"), 21, 0, SV("abcdefghij"), 1, 9, 0); + test(S("abcdefghijklmnopqrst"), 21, 0, SV("abcdefghij"), 1, 10, 0); + test(S("abcdefghijklmnopqrst"), 21, 0, SV("abcdefghij"), 5, 0, 0); + test(S("abcdefghijklmnopqrst"), 21, 0, SV("abcdefghij"), 5, 1, 0); + test(S("abcdefghijklmnopqrst"), 21, 0, SV("abcdefghij"), 5, 2, 0); + test(S("abcdefghijklmnopqrst"), 21, 0, SV("abcdefghij"), 5, 4, 0); + test(S("abcdefghijklmnopqrst"), 21, 0, SV("abcdefghij"), 5, 5, 0); + test(S("abcdefghijklmnopqrst"), 21, 0, SV("abcdefghij"), 5, 6, 0); + test(S("abcdefghijklmnopqrst"), 21, 0, SV("abcdefghij"), 9, 0, 0); + test(S("abcdefghijklmnopqrst"), 21, 0, SV("abcdefghij"), 9, 1, 0); + test(S("abcdefghijklmnopqrst"), 21, 0, SV("abcdefghij"), 9, 2, 0); + test(S("abcdefghijklmnopqrst"), 21, 0, SV("abcdefghij"), 10, 0, 0); + test(S("abcdefghijklmnopqrst"), 21, 0, SV("abcdefghij"), 10, 1, 0); + test(S("abcdefghijklmnopqrst"), 21, 0, SV("abcdefghij"), 11, 0, 0); + test(S("abcdefghijklmnopqrst"), 21, 0, SV("abcdefghijklmnopqrst"), 0, 0, 0); + test(S("abcdefghijklmnopqrst"), 21, 0, SV("abcdefghijklmnopqrst"), 0, 1, 0); + test(S("abcdefghijklmnopqrst"), 21, 0, SV("abcdefghijklmnopqrst"), 0, 10, 0); + test(S("abcdefghijklmnopqrst"), 21, 0, SV("abcdefghijklmnopqrst"), 0, 19, 0); + test(S("abcdefghijklmnopqrst"), 21, 0, SV("abcdefghijklmnopqrst"), 0, 20, 0); + test(S("abcdefghijklmnopqrst"), 21, 0, SV("abcdefghijklmnopqrst"), 0, 21, 0); + test(S("abcdefghijklmnopqrst"), 21, 0, SV("abcdefghijklmnopqrst"), 1, 0, 0); + test(S("abcdefghijklmnopqrst"), 21, 0, SV("abcdefghijklmnopqrst"), 1, 1, 0); + test(S("abcdefghijklmnopqrst"), 21, 0, SV("abcdefghijklmnopqrst"), 1, 9, 0); + test(S("abcdefghijklmnopqrst"), 21, 0, SV("abcdefghijklmnopqrst"), 1, 18, 0); + test(S("abcdefghijklmnopqrst"), 21, 0, SV("abcdefghijklmnopqrst"), 1, 19, 0); + test(S("abcdefghijklmnopqrst"), 21, 0, SV("abcdefghijklmnopqrst"), 1, 20, 0); + test(S("abcdefghijklmnopqrst"), 21, 0, SV("abcdefghijklmnopqrst"), 10, 0, 0); + test(S("abcdefghijklmnopqrst"), 21, 0, SV("abcdefghijklmnopqrst"), 10, 1, 0); + test(S("abcdefghijklmnopqrst"), 21, 0, SV("abcdefghijklmnopqrst"), 10, 5, 0); + test(S("abcdefghijklmnopqrst"), 21, 0, SV("abcdefghijklmnopqrst"), 10, 9, 0); + test(S("abcdefghijklmnopqrst"), 21, 0, SV("abcdefghijklmnopqrst"), 10, 10, 0); + test(S("abcdefghijklmnopqrst"), 21, 0, SV("abcdefghijklmnopqrst"), 10, 11, 0); + test(S("abcdefghijklmnopqrst"), 21, 0, SV("abcdefghijklmnopqrst"), 19, 0, 0); + test(S("abcdefghijklmnopqrst"), 21, 0, SV("abcdefghijklmnopqrst"), 19, 1, 0); + test(S("abcdefghijklmnopqrst"), 21, 0, SV("abcdefghijklmnopqrst"), 19, 2, 0); + test(S("abcdefghijklmnopqrst"), 21, 0, SV("abcdefghijklmnopqrst"), 20, 0, 0); + test(S("abcdefghijklmnopqrst"), 21, 0, SV("abcdefghijklmnopqrst"), 20, 1, 0); + test(S("abcdefghijklmnopqrst"), 21, 0, SV("abcdefghijklmnopqrst"), 21, 0, 0); +} + +template +void test55() +{ + test_npos(S(""), 0, 0, SV(""), 0, 0); + test_npos(S(""), 0, 0, SV("abcde"), 0, -5); + test_npos(S("abcde"), 0, 0, SV("abcdefghij"), 0, -10); + test_npos(S("abcde"), 0, 0, SV("abcdefghij"), 1, -9); + test_npos(S("abcde"), 0, 0, SV("abcdefghij"), 5, -5); +} + +int main() +{ + { + typedef std::string S; + typedef std::string_view SV; + test0(); + test1(); + test2(); + test3(); + test4(); + test5(); + test6(); + test7(); + test8(); + test9(); + test10(); + test11(); + test12(); + test13(); + test14(); + test15(); + test16(); + test17(); + test18(); + test19(); + test20(); + test21(); + test22(); + test23(); + test24(); + test25(); + test26(); + test27(); + test28(); + test29(); + test30(); + test31(); + test32(); + test33(); + test34(); + test35(); + test36(); + test37(); + test38(); + test39(); + test40(); + test41(); + test42(); + test43(); + test44(); + test45(); + test46(); + test47(); + test48(); + test49(); + test50(); + test51(); + test52(); + test53(); + test54(); + test55(); + } +#if TEST_STD_VER >= 11 + { + typedef std::basic_string, min_allocator> S; + typedef std::basic_string_view> SV; + test0(); + test1(); + test2(); + test3(); + test4(); + test5(); + test6(); + test7(); + test8(); + test9(); + test10(); + test11(); + test12(); + test13(); + test14(); + test15(); + test16(); + test17(); + test18(); + test19(); + test20(); + test21(); + test22(); + test23(); + test24(); + test25(); + test26(); + test27(); + test28(); + test29(); + test30(); + test31(); + test32(); + test33(); + test34(); + test35(); + test36(); + test37(); + test38(); + test39(); + test40(); + test41(); + test42(); + test43(); + test44(); + test45(); + test46(); + test47(); + test48(); + test49(); + test50(); + test51(); + test52(); + test53(); + test54(); + test55(); + } +#endif + { + typedef std::string S; + typedef std::string_view SV; + S s = "MNOP"; + SV sv = "CDEF"; + char arr[] = "MNOP"; + +// calls compare(pos, n1, const char *, 0) + assert(s.compare(0, 4, "QRST", 0) > 0); + +// calls compare(pos, n1, string("QRST"), 0, npos) + assert(s.compare(0, 4, "QRST", 0, std::string::npos) < 0); + +// calls compare(pos, n1, T, 0, npos) + assert(s.compare(0, 4, sv, 0) > 0); + +// calls compare(pos, n1, T, 0, npos) + assert(s.compare(0, 4, sv, 0, std::string::npos) > 0); + +// calls compare(pos, n1, const char *, 0) + assert(s.compare(0, 4, arr, 0) > 0); + +// calls compare(size, size, string(arr), 0, npos) + assert(s.compare(0, 4, arr, 0, std::string::npos) == 0); + } +} diff --git a/tests/external/libcxx/basic_string/string.ops/string_compare/size_size_pointer.pass.cpp b/tests/external/libcxx/basic_string/string.ops/string_compare/size_size_pointer.pass.cpp new file mode 100644 index 0000000..abd81a3 --- /dev/null +++ b/tests/external/libcxx/basic_string/string.ops/string_compare/size_size_pointer.pass.cpp @@ -0,0 +1,434 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// Copyright 2019, Intel Corporation +// +// Modified to test pmem::obj containers +// + +#include "unittest.hpp" + +#include +#include +#include +#include +#include + +namespace pmem_exp = pmem::obj::experimental; +namespace nvobj = pmem::obj; + +struct root { + nvobj::persistent_ptr s1, s2, s3, s4; +}; + +int +sign(int x) +{ + if (x == 0) + return 0; + if (x < 0) + return -1; + return 1; +} + +template +void +test(const S &s, typename S::size_type pos1, typename S::size_type n1, + const typename S::value_type *str, int x) +{ + if (pos1 <= s.size()) + UT_ASSERT(sign(s.compare(pos1, n1, str)) == sign(x)); + else { + try { + s.compare(pos1, n1, str); + UT_ASSERT(0); + } catch (std::out_of_range &) { + UT_ASSERT(pos1 > s.size()); + } + } +} + +template +void +test0(pmem::obj::pool &pop) +{ + auto r = pop.root(); + + test(*r->s1, 0, 0, "", 0); + test(*r->s1, 0, 0, "abcde", -5); + test(*r->s1, 0, 0, "abcdefghij", -10); + test(*r->s1, 0, 0, "abcdefghijklmnopqrst", -20); + test(*r->s1, 0, 1, "", 0); + test(*r->s1, 0, 1, "abcde", -5); + test(*r->s1, 0, 1, "abcdefghij", -10); + test(*r->s1, 0, 1, "abcdefghijklmnopqrst", -20); + test(*r->s1, 1, 0, "", 0); + test(*r->s1, 1, 0, "abcde", 0); + test(*r->s1, 1, 0, "abcdefghij", 0); + test(*r->s1, 1, 0, "abcdefghijklmnopqrst", 0); + test(*r->s2, 0, 0, "", 0); + test(*r->s2, 0, 0, "abcde", -5); + test(*r->s2, 0, 0, "abcdefghij", -10); + test(*r->s2, 0, 0, "abcdefghijklmnopqrst", -20); + test(*r->s2, 0, 1, "", 1); + test(*r->s2, 0, 1, "abcde", -4); + test(*r->s2, 0, 1, "abcdefghij", -9); + test(*r->s2, 0, 1, "abcdefghijklmnopqrst", -19); + test(*r->s2, 0, 2, "", 2); + test(*r->s2, 0, 2, "abcde", -3); + test(*r->s2, 0, 2, "abcdefghij", -8); + test(*r->s2, 0, 2, "abcdefghijklmnopqrst", -18); + test(*r->s2, 0, 4, "", 4); + test(*r->s2, 0, 4, "abcde", -1); + test(*r->s2, 0, 4, "abcdefghij", -6); + test(*r->s2, 0, 4, "abcdefghijklmnopqrst", -16); + test(*r->s2, 0, 5, "", 5); + test(*r->s2, 0, 5, "abcde", 0); + test(*r->s2, 0, 5, "abcdefghij", -5); + test(*r->s2, 0, 5, "abcdefghijklmnopqrst", -15); + test(*r->s2, 0, 6, "", 5); + test(*r->s2, 0, 6, "abcde", 0); + test(*r->s2, 0, 6, "abcdefghij", -5); + test(*r->s2, 0, 6, "abcdefghijklmnopqrst", -15); + test(*r->s2, 1, 0, "", 0); + test(*r->s2, 1, 0, "abcde", -5); + test(*r->s2, 1, 0, "abcdefghij", -10); + test(*r->s2, 1, 0, "abcdefghijklmnopqrst", -20); + test(*r->s2, 1, 1, "", 1); + test(*r->s2, 1, 1, "abcde", 1); + test(*r->s2, 1, 1, "abcdefghij", 1); + test(*r->s2, 1, 1, "abcdefghijklmnopqrst", 1); + test(*r->s2, 1, 2, "", 2); + test(*r->s2, 1, 2, "abcde", 1); + test(*r->s2, 1, 2, "abcdefghij", 1); + test(*r->s2, 1, 2, "abcdefghijklmnopqrst", 1); + test(*r->s2, 1, 3, "", 3); + test(*r->s2, 1, 3, "abcde", 1); + test(*r->s2, 1, 3, "abcdefghij", 1); + test(*r->s2, 1, 3, "abcdefghijklmnopqrst", 1); + test(*r->s2, 1, 4, "", 4); + test(*r->s2, 1, 4, "abcde", 1); + test(*r->s2, 1, 4, "abcdefghij", 1); + test(*r->s2, 1, 4, "abcdefghijklmnopqrst", 1); + test(*r->s2, 1, 5, "", 4); + test(*r->s2, 1, 5, "abcde", 1); + test(*r->s2, 1, 5, "abcdefghij", 1); + test(*r->s2, 1, 5, "abcdefghijklmnopqrst", 1); + test(*r->s2, 2, 0, "", 0); + test(*r->s2, 2, 0, "abcde", -5); + test(*r->s2, 2, 0, "abcdefghij", -10); + test(*r->s2, 2, 0, "abcdefghijklmnopqrst", -20); + test(*r->s2, 2, 1, "", 1); + test(*r->s2, 2, 1, "abcde", 2); + test(*r->s2, 2, 1, "abcdefghij", 2); + test(*r->s2, 2, 1, "abcdefghijklmnopqrst", 2); + test(*r->s2, 2, 2, "", 2); + test(*r->s2, 2, 2, "abcde", 2); + test(*r->s2, 2, 2, "abcdefghij", 2); + test(*r->s2, 2, 2, "abcdefghijklmnopqrst", 2); + test(*r->s2, 2, 3, "", 3); + test(*r->s2, 2, 3, "abcde", 2); + test(*r->s2, 2, 3, "abcdefghij", 2); + test(*r->s2, 2, 3, "abcdefghijklmnopqrst", 2); + test(*r->s2, 2, 4, "", 3); + test(*r->s2, 2, 4, "abcde", 2); + test(*r->s2, 2, 4, "abcdefghij", 2); + test(*r->s2, 2, 4, "abcdefghijklmnopqrst", 2); + test(*r->s2, 4, 0, "", 0); + test(*r->s2, 4, 0, "abcde", -5); + test(*r->s2, 4, 0, "abcdefghij", -10); + test(*r->s2, 4, 0, "abcdefghijklmnopqrst", -20); + test(*r->s2, 4, 1, "", 1); + test(*r->s2, 4, 1, "abcde", 4); + test(*r->s2, 4, 1, "abcdefghij", 4); + test(*r->s2, 4, 1, "abcdefghijklmnopqrst", 4); + test(*r->s2, 4, 2, "", 1); + test(*r->s2, 4, 2, "abcde", 4); + test(*r->s2, 4, 2, "abcdefghij", 4); + test(*r->s2, 4, 2, "abcdefghijklmnopqrst", 4); + test(*r->s2, 5, 0, "", 0); + test(*r->s2, 5, 0, "abcde", -5); + test(*r->s2, 5, 0, "abcdefghij", -10); + test(*r->s2, 5, 0, "abcdefghijklmnopqrst", -20); + test(*r->s2, 5, 1, "", 0); + test(*r->s2, 5, 1, "abcde", -5); + test(*r->s2, 5, 1, "abcdefghij", -10); + test(*r->s2, 5, 1, "abcdefghijklmnopqrst", -20); +} + +template +void +test1(pmem::obj::pool &pop) +{ + auto r = pop.root(); + + test(*r->s2, 6, 0, "", 0); + test(*r->s2, 6, 0, "abcde", 0); + test(*r->s2, 6, 0, "abcdefghij", 0); + test(*r->s2, 6, 0, "abcdefghijklmnopqrst", 0); + test(*r->s3, 0, 0, "", 0); + test(*r->s3, 0, 0, "abcde", -5); + test(*r->s3, 0, 0, "abcdefghij", -10); + test(*r->s3, 0, 0, "abcdefghijklmnopqrst", -20); + test(*r->s3, 0, 1, "", 1); + test(*r->s3, 0, 1, "abcde", -4); + test(*r->s3, 0, 1, "abcdefghij", -9); + test(*r->s3, 0, 1, "abcdefghijklmnopqrst", -19); + test(*r->s3, 0, 5, "", 5); + test(*r->s3, 0, 5, "abcde", 0); + test(*r->s3, 0, 5, "abcdefghij", -5); + test(*r->s3, 0, 5, "abcdefghijklmnopqrst", -15); + test(*r->s3, 0, 9, "", 9); + test(*r->s3, 0, 9, "abcde", 4); + test(*r->s3, 0, 9, "abcdefghij", -1); + test(*r->s3, 0, 9, "abcdefghijklmnopqrst", -11); + test(*r->s3, 0, 10, "", 10); + test(*r->s3, 0, 10, "abcde", 5); + test(*r->s3, 0, 10, "abcdefghij", 0); + test(*r->s3, 0, 10, "abcdefghijklmnopqrst", -10); + test(*r->s3, 0, 11, "", 10); + test(*r->s3, 0, 11, "abcde", 5); + test(*r->s3, 0, 11, "abcdefghij", 0); + test(*r->s3, 0, 11, "abcdefghijklmnopqrst", -10); + test(*r->s3, 1, 0, "", 0); + test(*r->s3, 1, 0, "abcde", -5); + test(*r->s3, 1, 0, "abcdefghij", -10); + test(*r->s3, 1, 0, "abcdefghijklmnopqrst", -20); + test(*r->s3, 1, 1, "", 1); + test(*r->s3, 1, 1, "abcde", 1); + test(*r->s3, 1, 1, "abcdefghij", 1); + test(*r->s3, 1, 1, "abcdefghijklmnopqrst", 1); + test(*r->s3, 1, 4, "", 4); + test(*r->s3, 1, 4, "abcde", 1); + test(*r->s3, 1, 4, "abcdefghij", 1); + test(*r->s3, 1, 4, "abcdefghijklmnopqrst", 1); + test(*r->s3, 1, 8, "", 8); + test(*r->s3, 1, 8, "abcde", 1); + test(*r->s3, 1, 8, "abcdefghij", 1); + test(*r->s3, 1, 8, "abcdefghijklmnopqrst", 1); + test(*r->s3, 1, 9, "", 9); + test(*r->s3, 1, 9, "abcde", 1); + test(*r->s3, 1, 9, "abcdefghij", 1); + test(*r->s3, 1, 9, "abcdefghijklmnopqrst", 1); + test(*r->s3, 1, 10, "", 9); + test(*r->s3, 1, 10, "abcde", 1); + test(*r->s3, 1, 10, "abcdefghij", 1); + test(*r->s3, 1, 10, "abcdefghijklmnopqrst", 1); + test(*r->s3, 5, 0, "", 0); + test(*r->s3, 5, 0, "abcde", -5); + test(*r->s3, 5, 0, "abcdefghij", -10); + test(*r->s3, 5, 0, "abcdefghijklmnopqrst", -20); + test(*r->s3, 5, 1, "", 1); + test(*r->s3, 5, 1, "abcde", 5); + test(*r->s3, 5, 1, "abcdefghij", 5); + test(*r->s3, 5, 1, "abcdefghijklmnopqrst", 5); + test(*r->s3, 5, 2, "", 2); + test(*r->s3, 5, 2, "abcde", 5); + test(*r->s3, 5, 2, "abcdefghij", 5); + test(*r->s3, 5, 2, "abcdefghijklmnopqrst", 5); + test(*r->s3, 5, 4, "", 4); + test(*r->s3, 5, 4, "abcde", 5); + test(*r->s3, 5, 4, "abcdefghij", 5); + test(*r->s3, 5, 4, "abcdefghijklmnopqrst", 5); + test(*r->s3, 5, 5, "", 5); + test(*r->s3, 5, 5, "abcde", 5); + test(*r->s3, 5, 5, "abcdefghij", 5); + test(*r->s3, 5, 5, "abcdefghijklmnopqrst", 5); + test(*r->s3, 5, 6, "", 5); + test(*r->s3, 5, 6, "abcde", 5); + test(*r->s3, 5, 6, "abcdefghij", 5); + test(*r->s3, 5, 6, "abcdefghijklmnopqrst", 5); + test(*r->s3, 9, 0, "", 0); + test(*r->s3, 9, 0, "abcde", -5); + test(*r->s3, 9, 0, "abcdefghij", -10); + test(*r->s3, 9, 0, "abcdefghijklmnopqrst", -20); + test(*r->s3, 9, 1, "", 1); + test(*r->s3, 9, 1, "abcde", 9); + test(*r->s3, 9, 1, "abcdefghij", 9); + test(*r->s3, 9, 1, "abcdefghijklmnopqrst", 9); + test(*r->s3, 9, 2, "", 1); + test(*r->s3, 9, 2, "abcde", 9); + test(*r->s3, 9, 2, "abcdefghij", 9); + test(*r->s3, 9, 2, "abcdefghijklmnopqrst", 9); + test(*r->s3, 10, 0, "", 0); + test(*r->s3, 10, 0, "abcde", -5); + test(*r->s3, 10, 0, "abcdefghij", -10); + test(*r->s3, 10, 0, "abcdefghijklmnopqrst", -20); + test(*r->s3, 10, 1, "", 0); + test(*r->s3, 10, 1, "abcde", -5); + test(*r->s3, 10, 1, "abcdefghij", -10); + test(*r->s3, 10, 1, "abcdefghijklmnopqrst", -20); + test(*r->s3, 11, 0, "", 0); + test(*r->s3, 11, 0, "abcde", 0); + test(*r->s3, 11, 0, "abcdefghij", 0); + test(*r->s3, 11, 0, "abcdefghijklmnopqrst", 0); +} + +template +void +test2(pmem::obj::pool &pop) +{ + auto r = pop.root(); + + test(*r->s4, 0, 0, "", 0); + test(*r->s4, 0, 0, "abcde", -5); + test(*r->s4, 0, 0, "abcdefghij", -10); + test(*r->s4, 0, 0, "abcdefghijklmnopqrst", -20); + test(*r->s4, 0, 1, "", 1); + test(*r->s4, 0, 1, "abcde", -4); + test(*r->s4, 0, 1, "abcdefghij", -9); + test(*r->s4, 0, 1, "abcdefghijklmnopqrst", -19); + test(*r->s4, 0, 10, "", 10); + test(*r->s4, 0, 10, "abcde", 5); + test(*r->s4, 0, 10, "abcdefghij", 0); + test(*r->s4, 0, 10, "abcdefghijklmnopqrst", -10); + test(*r->s4, 0, 19, "", 19); + test(*r->s4, 0, 19, "abcde", 14); + test(*r->s4, 0, 19, "abcdefghij", 9); + test(*r->s4, 0, 19, "abcdefghijklmnopqrst", -1); + test(*r->s4, 0, 20, "", 20); + test(*r->s4, 0, 20, "abcde", 15); + test(*r->s4, 0, 20, "abcdefghij", 10); + test(*r->s4, 0, 20, "abcdefghijklmnopqrst", 0); + test(*r->s4, 0, 21, "", 20); + test(*r->s4, 0, 21, "abcde", 15); + test(*r->s4, 0, 21, "abcdefghij", 10); + test(*r->s4, 0, 21, "abcdefghijklmnopqrst", 0); + test(*r->s4, 1, 0, "", 0); + test(*r->s4, 1, 0, "abcde", -5); + test(*r->s4, 1, 0, "abcdefghij", -10); + test(*r->s4, 1, 0, "abcdefghijklmnopqrst", -20); + test(*r->s4, 1, 1, "", 1); + test(*r->s4, 1, 1, "abcde", 1); + test(*r->s4, 1, 1, "abcdefghij", 1); + test(*r->s4, 1, 1, "abcdefghijklmnopqrst", 1); + test(*r->s4, 1, 9, "", 9); + test(*r->s4, 1, 9, "abcde", 1); + test(*r->s4, 1, 9, "abcdefghij", 1); + test(*r->s4, 1, 9, "abcdefghijklmnopqrst", 1); + test(*r->s4, 1, 18, "", 18); + test(*r->s4, 1, 18, "abcde", 1); + test(*r->s4, 1, 18, "abcdefghij", 1); + test(*r->s4, 1, 18, "abcdefghijklmnopqrst", 1); + test(*r->s4, 1, 19, "", 19); + test(*r->s4, 1, 19, "abcde", 1); + test(*r->s4, 1, 19, "abcdefghij", 1); + test(*r->s4, 1, 19, "abcdefghijklmnopqrst", 1); + test(*r->s4, 1, 20, "", 19); + test(*r->s4, 1, 20, "abcde", 1); + test(*r->s4, 1, 20, "abcdefghij", 1); + test(*r->s4, 1, 20, "abcdefghijklmnopqrst", 1); + test(*r->s4, 10, 0, "", 0); + test(*r->s4, 10, 0, "abcde", -5); + test(*r->s4, 10, 0, "abcdefghij", -10); + test(*r->s4, 10, 0, "abcdefghijklmnopqrst", -20); + test(*r->s4, 10, 1, "", 1); + test(*r->s4, 10, 1, "abcde", 10); + test(*r->s4, 10, 1, "abcdefghij", 10); + test(*r->s4, 10, 1, "abcdefghijklmnopqrst", 10); + test(*r->s4, 10, 5, "", 5); + test(*r->s4, 10, 5, "abcde", 10); + test(*r->s4, 10, 5, "abcdefghij", 10); + test(*r->s4, 10, 5, "abcdefghijklmnopqrst", 10); + test(*r->s4, 10, 9, "", 9); + test(*r->s4, 10, 9, "abcde", 10); + test(*r->s4, 10, 9, "abcdefghij", 10); + test(*r->s4, 10, 9, "abcdefghijklmnopqrst", 10); + test(*r->s4, 10, 10, "", 10); + test(*r->s4, 10, 10, "abcde", 10); + test(*r->s4, 10, 10, "abcdefghij", 10); + test(*r->s4, 10, 10, "abcdefghijklmnopqrst", 10); + test(*r->s4, 10, 11, "", 10); + test(*r->s4, 10, 11, "abcde", 10); + test(*r->s4, 10, 11, "abcdefghij", 10); + test(*r->s4, 10, 11, "abcdefghijklmnopqrst", 10); + test(*r->s4, 19, 0, "", 0); + test(*r->s4, 19, 0, "abcde", -5); + test(*r->s4, 19, 0, "abcdefghij", -10); + test(*r->s4, 19, 0, "abcdefghijklmnopqrst", -20); + test(*r->s4, 19, 1, "", 1); + test(*r->s4, 19, 1, "abcde", 19); + test(*r->s4, 19, 1, "abcdefghij", 19); + test(*r->s4, 19, 1, "abcdefghijklmnopqrst", 19); + test(*r->s4, 19, 2, "", 1); + test(*r->s4, 19, 2, "abcde", 19); + test(*r->s4, 19, 2, "abcdefghij", 19); + test(*r->s4, 19, 2, "abcdefghijklmnopqrst", 19); + test(*r->s4, 20, 0, "", 0); + test(*r->s4, 20, 0, "abcde", -5); + test(*r->s4, 20, 0, "abcdefghij", -10); + test(*r->s4, 20, 0, "abcdefghijklmnopqrst", -20); + test(*r->s4, 20, 1, "", 0); + test(*r->s4, 20, 1, "abcde", -5); + test(*r->s4, 20, 1, "abcdefghij", -10); + test(*r->s4, 20, 1, "abcdefghijklmnopqrst", -20); + test(*r->s4, 21, 0, "", 0); + test(*r->s4, 21, 0, "abcde", 0); + test(*r->s4, 21, 0, "abcdefghij", 0); + test(*r->s4, 21, 0, "abcdefghijklmnopqrst", 0); +} + +void +run(pmem::obj::pool &pop) +{ + auto r = pop.root(); + + try { + nvobj::transaction::run(pop, [&] { + r->s1 = nvobj::make_persistent(""); + r->s2 = nvobj::make_persistent( + "abcde"); + r->s3 = nvobj::make_persistent( + "abcdefghij"); + r->s4 = nvobj::make_persistent( + "abcdefghijklmnopqrst"); + }); + + using S = pmem_exp::string; + test0(pop); + test1(pop); + test2(pop); + + nvobj::transaction::run(pop, [&] { + nvobj::delete_persistent(r->s1); + nvobj::delete_persistent(r->s2); + nvobj::delete_persistent(r->s3); + nvobj::delete_persistent(r->s4); + }); + } catch (std::exception &e) { + UT_FATALexc(e); + } +} + +int +main(int argc, char *argv[]) +{ + START(); + + if (argc != 2) + UT_FATAL("usage: %s file-name", argv[0]); + + const char *path = argv[1]; + + pmem::obj::pool pop; + + try { + pop = pmem::obj::pool::create(path, "basic_string", + PMEMOBJ_MIN_POOL, + S_IWUSR | S_IRUSR); + } catch (...) { + UT_FATAL("!pmemobj_create: %s", path); + } + + run(pop); + + pop.close(); + + return 0; +} diff --git a/tests/external/libcxx/basic_string/string.ops/string_compare/size_size_pointer_size.pass.cpp b/tests/external/libcxx/basic_string/string.ops/string_compare/size_size_pointer_size.pass.cpp new file mode 100644 index 0000000..a918a50 --- /dev/null +++ b/tests/external/libcxx/basic_string/string.ops/string_compare/size_size_pointer_size.pass.cpp @@ -0,0 +1,1403 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// Copyright 2019, Intel Corporation +// +// Modified to test pmem::obj containers +// + +#include "unittest.hpp" + +#include +#include +#include +#include +#include + +namespace pmem_exp = pmem::obj::experimental; +namespace nvobj = pmem::obj; + +struct root { + nvobj::persistent_ptr s1, s2, s3, s4; +}; + +int +sign(int x) +{ + if (x == 0) + return 0; + if (x < 0) + return -1; + return 1; +} + +template +void +test(const S &s, typename S::size_type pos, typename S::size_type n1, + const typename S::value_type *str, typename S::size_type n2, int x) +{ + if (pos <= s.size()) + UT_ASSERT(sign(s.compare(pos, n1, str, n2)) == sign(x)); + else { + try { + s.compare(pos, n1, str, n2); + UT_ASSERT(0); + } catch (std::out_of_range &) { + UT_ASSERT(pos > s.size()); + } + } +} + +template +void +test0(pmem::obj::pool &pop) +{ + auto r = pop.root(); + + test(*r->s1, 0, 0, "", 0, 0); + test(*r->s1, 0, 0, "abcde", 0, 0); + test(*r->s1, 0, 0, "abcde", 1, -1); + test(*r->s1, 0, 0, "abcde", 2, -2); + test(*r->s1, 0, 0, "abcde", 4, -4); + test(*r->s1, 0, 0, "abcde", 5, -5); + test(*r->s1, 0, 0, "abcdefghij", 0, 0); + test(*r->s1, 0, 0, "abcdefghij", 1, -1); + test(*r->s1, 0, 0, "abcdefghij", 5, -5); + test(*r->s1, 0, 0, "abcdefghij", 9, -9); + test(*r->s1, 0, 0, "abcdefghij", 10, -10); + test(*r->s1, 0, 0, "abcdefghijklmnopqrst", 0, 0); + test(*r->s1, 0, 0, "abcdefghijklmnopqrst", 1, -1); + test(*r->s1, 0, 0, "abcdefghijklmnopqrst", 10, -10); + test(*r->s1, 0, 0, "abcdefghijklmnopqrst", 19, -19); + test(*r->s1, 0, 0, "abcdefghijklmnopqrst", 20, -20); + test(*r->s1, 0, 1, "", 0, 0); + test(*r->s1, 0, 1, "abcde", 0, 0); + test(*r->s1, 0, 1, "abcde", 1, -1); + test(*r->s1, 0, 1, "abcde", 2, -2); + test(*r->s1, 0, 1, "abcde", 4, -4); + test(*r->s1, 0, 1, "abcde", 5, -5); + test(*r->s1, 0, 1, "abcdefghij", 0, 0); + test(*r->s1, 0, 1, "abcdefghij", 1, -1); + test(*r->s1, 0, 1, "abcdefghij", 5, -5); + test(*r->s1, 0, 1, "abcdefghij", 9, -9); + test(*r->s1, 0, 1, "abcdefghij", 10, -10); + test(*r->s1, 0, 1, "abcdefghijklmnopqrst", 0, 0); + test(*r->s1, 0, 1, "abcdefghijklmnopqrst", 1, -1); + test(*r->s1, 0, 1, "abcdefghijklmnopqrst", 10, -10); + test(*r->s1, 0, 1, "abcdefghijklmnopqrst", 19, -19); + test(*r->s1, 0, 1, "abcdefghijklmnopqrst", 20, -20); + test(*r->s1, 1, 0, "", 0, 0); + test(*r->s1, 1, 0, "abcde", 0, 0); + test(*r->s1, 1, 0, "abcde", 1, 0); + test(*r->s1, 1, 0, "abcde", 2, 0); + test(*r->s1, 1, 0, "abcde", 4, 0); + test(*r->s1, 1, 0, "abcde", 5, 0); + test(*r->s1, 1, 0, "abcdefghij", 0, 0); + test(*r->s1, 1, 0, "abcdefghij", 1, 0); + test(*r->s1, 1, 0, "abcdefghij", 5, 0); + test(*r->s1, 1, 0, "abcdefghij", 9, 0); + test(*r->s1, 1, 0, "abcdefghij", 10, 0); + test(*r->s1, 1, 0, "abcdefghijklmnopqrst", 0, 0); + test(*r->s1, 1, 0, "abcdefghijklmnopqrst", 1, 0); + test(*r->s1, 1, 0, "abcdefghijklmnopqrst", 10, 0); + test(*r->s1, 1, 0, "abcdefghijklmnopqrst", 19, 0); + test(*r->s1, 1, 0, "abcdefghijklmnopqrst", 20, 0); + test(*r->s2, 0, 0, "", 0, 0); + test(*r->s2, 0, 0, "abcde", 0, 0); + test(*r->s2, 0, 0, "abcde", 1, -1); + test(*r->s2, 0, 0, "abcde", 2, -2); + test(*r->s2, 0, 0, "abcde", 4, -4); + test(*r->s2, 0, 0, "abcde", 5, -5); + test(*r->s2, 0, 0, "abcdefghij", 0, 0); + test(*r->s2, 0, 0, "abcdefghij", 1, -1); + test(*r->s2, 0, 0, "abcdefghij", 5, -5); + test(*r->s2, 0, 0, "abcdefghij", 9, -9); + test(*r->s2, 0, 0, "abcdefghij", 10, -10); + test(*r->s2, 0, 0, "abcdefghijklmnopqrst", 0, 0); + test(*r->s2, 0, 0, "abcdefghijklmnopqrst", 1, -1); + test(*r->s2, 0, 0, "abcdefghijklmnopqrst", 10, -10); + test(*r->s2, 0, 0, "abcdefghijklmnopqrst", 19, -19); + test(*r->s2, 0, 0, "abcdefghijklmnopqrst", 20, -20); + test(*r->s2, 0, 1, "", 0, 1); + test(*r->s2, 0, 1, "abcde", 0, 1); + test(*r->s2, 0, 1, "abcde", 1, 0); + test(*r->s2, 0, 1, "abcde", 2, -1); + test(*r->s2, 0, 1, "abcde", 4, -3); + test(*r->s2, 0, 1, "abcde", 5, -4); + test(*r->s2, 0, 1, "abcdefghij", 0, 1); + test(*r->s2, 0, 1, "abcdefghij", 1, 0); + test(*r->s2, 0, 1, "abcdefghij", 5, -4); + test(*r->s2, 0, 1, "abcdefghij", 9, -8); + test(*r->s2, 0, 1, "abcdefghij", 10, -9); + test(*r->s2, 0, 1, "abcdefghijklmnopqrst", 0, 1); + test(*r->s2, 0, 1, "abcdefghijklmnopqrst", 1, 0); + test(*r->s2, 0, 1, "abcdefghijklmnopqrst", 10, -9); + test(*r->s2, 0, 1, "abcdefghijklmnopqrst", 19, -18); + test(*r->s2, 0, 1, "abcdefghijklmnopqrst", 20, -19); + test(*r->s2, 0, 2, "", 0, 2); + test(*r->s2, 0, 2, "abcde", 0, 2); + test(*r->s2, 0, 2, "abcde", 1, 1); + test(*r->s2, 0, 2, "abcde", 2, 0); + test(*r->s2, 0, 2, "abcde", 4, -2); + test(*r->s2, 0, 2, "abcde", 5, -3); + test(*r->s2, 0, 2, "abcdefghij", 0, 2); + test(*r->s2, 0, 2, "abcdefghij", 1, 1); + test(*r->s2, 0, 2, "abcdefghij", 5, -3); + test(*r->s2, 0, 2, "abcdefghij", 9, -7); + test(*r->s2, 0, 2, "abcdefghij", 10, -8); + test(*r->s2, 0, 2, "abcdefghijklmnopqrst", 0, 2); + test(*r->s2, 0, 2, "abcdefghijklmnopqrst", 1, 1); + test(*r->s2, 0, 2, "abcdefghijklmnopqrst", 10, -8); + test(*r->s2, 0, 2, "abcdefghijklmnopqrst", 19, -17); + test(*r->s2, 0, 2, "abcdefghijklmnopqrst", 20, -18); + test(*r->s2, 0, 4, "", 0, 4); + test(*r->s2, 0, 4, "abcde", 0, 4); + test(*r->s2, 0, 4, "abcde", 1, 3); + test(*r->s2, 0, 4, "abcde", 2, 2); +} + +template +void +test1(pmem::obj::pool &pop) +{ + auto r = pop.root(); + + test(*r->s2, 0, 4, "abcde", 4, 0); + test(*r->s2, 0, 4, "abcde", 5, -1); + test(*r->s2, 0, 4, "abcdefghij", 0, 4); + test(*r->s2, 0, 4, "abcdefghij", 1, 3); + test(*r->s2, 0, 4, "abcdefghij", 5, -1); + test(*r->s2, 0, 4, "abcdefghij", 9, -5); + test(*r->s2, 0, 4, "abcdefghij", 10, -6); + test(*r->s2, 0, 4, "abcdefghijklmnopqrst", 0, 4); + test(*r->s2, 0, 4, "abcdefghijklmnopqrst", 1, 3); + test(*r->s2, 0, 4, "abcdefghijklmnopqrst", 10, -6); + test(*r->s2, 0, 4, "abcdefghijklmnopqrst", 19, -15); + test(*r->s2, 0, 4, "abcdefghijklmnopqrst", 20, -16); + test(*r->s2, 0, 5, "", 0, 5); + test(*r->s2, 0, 5, "abcde", 0, 5); + test(*r->s2, 0, 5, "abcde", 1, 4); + test(*r->s2, 0, 5, "abcde", 2, 3); + test(*r->s2, 0, 5, "abcde", 4, 1); + test(*r->s2, 0, 5, "abcde", 5, 0); + test(*r->s2, 0, 5, "abcdefghij", 0, 5); + test(*r->s2, 0, 5, "abcdefghij", 1, 4); + test(*r->s2, 0, 5, "abcdefghij", 5, 0); + test(*r->s2, 0, 5, "abcdefghij", 9, -4); + test(*r->s2, 0, 5, "abcdefghij", 10, -5); + test(*r->s2, 0, 5, "abcdefghijklmnopqrst", 0, 5); + test(*r->s2, 0, 5, "abcdefghijklmnopqrst", 1, 4); + test(*r->s2, 0, 5, "abcdefghijklmnopqrst", 10, -5); + test(*r->s2, 0, 5, "abcdefghijklmnopqrst", 19, -14); + test(*r->s2, 0, 5, "abcdefghijklmnopqrst", 20, -15); + test(*r->s2, 0, 6, "", 0, 5); + test(*r->s2, 0, 6, "abcde", 0, 5); + test(*r->s2, 0, 6, "abcde", 1, 4); + test(*r->s2, 0, 6, "abcde", 2, 3); + test(*r->s2, 0, 6, "abcde", 4, 1); + test(*r->s2, 0, 6, "abcde", 5, 0); + test(*r->s2, 0, 6, "abcdefghij", 0, 5); + test(*r->s2, 0, 6, "abcdefghij", 1, 4); + test(*r->s2, 0, 6, "abcdefghij", 5, 0); + test(*r->s2, 0, 6, "abcdefghij", 9, -4); + test(*r->s2, 0, 6, "abcdefghij", 10, -5); + test(*r->s2, 0, 6, "abcdefghijklmnopqrst", 0, 5); + test(*r->s2, 0, 6, "abcdefghijklmnopqrst", 1, 4); + test(*r->s2, 0, 6, "abcdefghijklmnopqrst", 10, -5); + test(*r->s2, 0, 6, "abcdefghijklmnopqrst", 19, -14); + test(*r->s2, 0, 6, "abcdefghijklmnopqrst", 20, -15); + test(*r->s2, 1, 0, "", 0, 0); + test(*r->s2, 1, 0, "abcde", 0, 0); + test(*r->s2, 1, 0, "abcde", 1, -1); + test(*r->s2, 1, 0, "abcde", 2, -2); + test(*r->s2, 1, 0, "abcde", 4, -4); + test(*r->s2, 1, 0, "abcde", 5, -5); + test(*r->s2, 1, 0, "abcdefghij", 0, 0); + test(*r->s2, 1, 0, "abcdefghij", 1, -1); + test(*r->s2, 1, 0, "abcdefghij", 5, -5); + test(*r->s2, 1, 0, "abcdefghij", 9, -9); + test(*r->s2, 1, 0, "abcdefghij", 10, -10); + test(*r->s2, 1, 0, "abcdefghijklmnopqrst", 0, 0); + test(*r->s2, 1, 0, "abcdefghijklmnopqrst", 1, -1); + test(*r->s2, 1, 0, "abcdefghijklmnopqrst", 10, -10); + test(*r->s2, 1, 0, "abcdefghijklmnopqrst", 19, -19); + test(*r->s2, 1, 0, "abcdefghijklmnopqrst", 20, -20); + test(*r->s2, 1, 1, "", 0, 1); + test(*r->s2, 1, 1, "abcde", 0, 1); + test(*r->s2, 1, 1, "abcde", 1, 1); + test(*r->s2, 1, 1, "abcde", 2, 1); + test(*r->s2, 1, 1, "abcde", 4, 1); + test(*r->s2, 1, 1, "abcde", 5, 1); + test(*r->s2, 1, 1, "abcdefghij", 0, 1); + test(*r->s2, 1, 1, "abcdefghij", 1, 1); + test(*r->s2, 1, 1, "abcdefghij", 5, 1); + test(*r->s2, 1, 1, "abcdefghij", 9, 1); + test(*r->s2, 1, 1, "abcdefghij", 10, 1); + test(*r->s2, 1, 1, "abcdefghijklmnopqrst", 0, 1); + test(*r->s2, 1, 1, "abcdefghijklmnopqrst", 1, 1); + test(*r->s2, 1, 1, "abcdefghijklmnopqrst", 10, 1); + test(*r->s2, 1, 1, "abcdefghijklmnopqrst", 19, 1); + test(*r->s2, 1, 1, "abcdefghijklmnopqrst", 20, 1); + test(*r->s2, 1, 2, "", 0, 2); + test(*r->s2, 1, 2, "abcde", 0, 2); + test(*r->s2, 1, 2, "abcde", 1, 1); + test(*r->s2, 1, 2, "abcde", 2, 1); + test(*r->s2, 1, 2, "abcde", 4, 1); + test(*r->s2, 1, 2, "abcde", 5, 1); + test(*r->s2, 1, 2, "abcdefghij", 0, 2); + test(*r->s2, 1, 2, "abcdefghij", 1, 1); + test(*r->s2, 1, 2, "abcdefghij", 5, 1); + test(*r->s2, 1, 2, "abcdefghij", 9, 1); + test(*r->s2, 1, 2, "abcdefghij", 10, 1); + test(*r->s2, 1, 2, "abcdefghijklmnopqrst", 0, 2); + test(*r->s2, 1, 2, "abcdefghijklmnopqrst", 1, 1); + test(*r->s2, 1, 2, "abcdefghijklmnopqrst", 10, 1); + test(*r->s2, 1, 2, "abcdefghijklmnopqrst", 19, 1); + test(*r->s2, 1, 2, "abcdefghijklmnopqrst", 20, 1); + test(*r->s2, 1, 3, "", 0, 3); + test(*r->s2, 1, 3, "abcde", 0, 3); + test(*r->s2, 1, 3, "abcde", 1, 1); + test(*r->s2, 1, 3, "abcde", 2, 1); + test(*r->s2, 1, 3, "abcde", 4, 1); + test(*r->s2, 1, 3, "abcde", 5, 1); + test(*r->s2, 1, 3, "abcdefghij", 0, 3); + test(*r->s2, 1, 3, "abcdefghij", 1, 1); +} + +template +void +test2(pmem::obj::pool &pop) +{ + auto r = pop.root(); + + test(*r->s2, 1, 3, "abcdefghij", 5, 1); + test(*r->s2, 1, 3, "abcdefghij", 9, 1); + test(*r->s2, 1, 3, "abcdefghij", 10, 1); + test(*r->s2, 1, 3, "abcdefghijklmnopqrst", 0, 3); + test(*r->s2, 1, 3, "abcdefghijklmnopqrst", 1, 1); + test(*r->s2, 1, 3, "abcdefghijklmnopqrst", 10, 1); + test(*r->s2, 1, 3, "abcdefghijklmnopqrst", 19, 1); + test(*r->s2, 1, 3, "abcdefghijklmnopqrst", 20, 1); + test(*r->s2, 1, 4, "", 0, 4); + test(*r->s2, 1, 4, "abcde", 0, 4); + test(*r->s2, 1, 4, "abcde", 1, 1); + test(*r->s2, 1, 4, "abcde", 2, 1); + test(*r->s2, 1, 4, "abcde", 4, 1); + test(*r->s2, 1, 4, "abcde", 5, 1); + test(*r->s2, 1, 4, "abcdefghij", 0, 4); + test(*r->s2, 1, 4, "abcdefghij", 1, 1); + test(*r->s2, 1, 4, "abcdefghij", 5, 1); + test(*r->s2, 1, 4, "abcdefghij", 9, 1); + test(*r->s2, 1, 4, "abcdefghij", 10, 1); + test(*r->s2, 1, 4, "abcdefghijklmnopqrst", 0, 4); + test(*r->s2, 1, 4, "abcdefghijklmnopqrst", 1, 1); + test(*r->s2, 1, 4, "abcdefghijklmnopqrst", 10, 1); + test(*r->s2, 1, 4, "abcdefghijklmnopqrst", 19, 1); + test(*r->s2, 1, 4, "abcdefghijklmnopqrst", 20, 1); + test(*r->s2, 1, 5, "", 0, 4); + test(*r->s2, 1, 5, "abcde", 0, 4); + test(*r->s2, 1, 5, "abcde", 1, 1); + test(*r->s2, 1, 5, "abcde", 2, 1); + test(*r->s2, 1, 5, "abcde", 4, 1); + test(*r->s2, 1, 5, "abcde", 5, 1); + test(*r->s2, 1, 5, "abcdefghij", 0, 4); + test(*r->s2, 1, 5, "abcdefghij", 1, 1); + test(*r->s2, 1, 5, "abcdefghij", 5, 1); + test(*r->s2, 1, 5, "abcdefghij", 9, 1); + test(*r->s2, 1, 5, "abcdefghij", 10, 1); + test(*r->s2, 1, 5, "abcdefghijklmnopqrst", 0, 4); + test(*r->s2, 1, 5, "abcdefghijklmnopqrst", 1, 1); + test(*r->s2, 1, 5, "abcdefghijklmnopqrst", 10, 1); + test(*r->s2, 1, 5, "abcdefghijklmnopqrst", 19, 1); + test(*r->s2, 1, 5, "abcdefghijklmnopqrst", 20, 1); + test(*r->s2, 2, 0, "", 0, 0); + test(*r->s2, 2, 0, "abcde", 0, 0); + test(*r->s2, 2, 0, "abcde", 1, -1); + test(*r->s2, 2, 0, "abcde", 2, -2); + test(*r->s2, 2, 0, "abcde", 4, -4); + test(*r->s2, 2, 0, "abcde", 5, -5); + test(*r->s2, 2, 0, "abcdefghij", 0, 0); + test(*r->s2, 2, 0, "abcdefghij", 1, -1); + test(*r->s2, 2, 0, "abcdefghij", 5, -5); + test(*r->s2, 2, 0, "abcdefghij", 9, -9); + test(*r->s2, 2, 0, "abcdefghij", 10, -10); + test(*r->s2, 2, 0, "abcdefghijklmnopqrst", 0, 0); + test(*r->s2, 2, 0, "abcdefghijklmnopqrst", 1, -1); + test(*r->s2, 2, 0, "abcdefghijklmnopqrst", 10, -10); + test(*r->s2, 2, 0, "abcdefghijklmnopqrst", 19, -19); + test(*r->s2, 2, 0, "abcdefghijklmnopqrst", 20, -20); + test(*r->s2, 2, 1, "", 0, 1); + test(*r->s2, 2, 1, "abcde", 0, 1); + test(*r->s2, 2, 1, "abcde", 1, 2); + test(*r->s2, 2, 1, "abcde", 2, 2); + test(*r->s2, 2, 1, "abcde", 4, 2); + test(*r->s2, 2, 1, "abcde", 5, 2); + test(*r->s2, 2, 1, "abcdefghij", 0, 1); + test(*r->s2, 2, 1, "abcdefghij", 1, 2); + test(*r->s2, 2, 1, "abcdefghij", 5, 2); + test(*r->s2, 2, 1, "abcdefghij", 9, 2); + test(*r->s2, 2, 1, "abcdefghij", 10, 2); + test(*r->s2, 2, 1, "abcdefghijklmnopqrst", 0, 1); + test(*r->s2, 2, 1, "abcdefghijklmnopqrst", 1, 2); + test(*r->s2, 2, 1, "abcdefghijklmnopqrst", 10, 2); + test(*r->s2, 2, 1, "abcdefghijklmnopqrst", 19, 2); + test(*r->s2, 2, 1, "abcdefghijklmnopqrst", 20, 2); + test(*r->s2, 2, 2, "", 0, 2); + test(*r->s2, 2, 2, "abcde", 0, 2); + test(*r->s2, 2, 2, "abcde", 1, 2); + test(*r->s2, 2, 2, "abcde", 2, 2); + test(*r->s2, 2, 2, "abcde", 4, 2); + test(*r->s2, 2, 2, "abcde", 5, 2); + test(*r->s2, 2, 2, "abcdefghij", 0, 2); + test(*r->s2, 2, 2, "abcdefghij", 1, 2); + test(*r->s2, 2, 2, "abcdefghij", 5, 2); + test(*r->s2, 2, 2, "abcdefghij", 9, 2); + test(*r->s2, 2, 2, "abcdefghij", 10, 2); + test(*r->s2, 2, 2, "abcdefghijklmnopqrst", 0, 2); + test(*r->s2, 2, 2, "abcdefghijklmnopqrst", 1, 2); + test(*r->s2, 2, 2, "abcdefghijklmnopqrst", 10, 2); + test(*r->s2, 2, 2, "abcdefghijklmnopqrst", 19, 2); + test(*r->s2, 2, 2, "abcdefghijklmnopqrst", 20, 2); + test(*r->s2, 2, 3, "", 0, 3); + test(*r->s2, 2, 3, "abcde", 0, 3); + test(*r->s2, 2, 3, "abcde", 1, 2); + test(*r->s2, 2, 3, "abcde", 2, 2); + test(*r->s2, 2, 3, "abcde", 4, 2); + test(*r->s2, 2, 3, "abcde", 5, 2); + test(*r->s2, 2, 3, "abcdefghij", 0, 3); + test(*r->s2, 2, 3, "abcdefghij", 1, 2); + test(*r->s2, 2, 3, "abcdefghij", 5, 2); + test(*r->s2, 2, 3, "abcdefghij", 9, 2); + test(*r->s2, 2, 3, "abcdefghij", 10, 2); + test(*r->s2, 2, 3, "abcdefghijklmnopqrst", 0, 3); +} + +template +void +test3(pmem::obj::pool &pop) +{ + auto r = pop.root(); + + test(*r->s2, 2, 3, "abcdefghijklmnopqrst", 1, 2); + test(*r->s2, 2, 3, "abcdefghijklmnopqrst", 10, 2); + test(*r->s2, 2, 3, "abcdefghijklmnopqrst", 19, 2); + test(*r->s2, 2, 3, "abcdefghijklmnopqrst", 20, 2); + test(*r->s2, 2, 4, "", 0, 3); + test(*r->s2, 2, 4, "abcde", 0, 3); + test(*r->s2, 2, 4, "abcde", 1, 2); + test(*r->s2, 2, 4, "abcde", 2, 2); + test(*r->s2, 2, 4, "abcde", 4, 2); + test(*r->s2, 2, 4, "abcde", 5, 2); + test(*r->s2, 2, 4, "abcdefghij", 0, 3); + test(*r->s2, 2, 4, "abcdefghij", 1, 2); + test(*r->s2, 2, 4, "abcdefghij", 5, 2); + test(*r->s2, 2, 4, "abcdefghij", 9, 2); + test(*r->s2, 2, 4, "abcdefghij", 10, 2); + test(*r->s2, 2, 4, "abcdefghijklmnopqrst", 0, 3); + test(*r->s2, 2, 4, "abcdefghijklmnopqrst", 1, 2); + test(*r->s2, 2, 4, "abcdefghijklmnopqrst", 10, 2); + test(*r->s2, 2, 4, "abcdefghijklmnopqrst", 19, 2); + test(*r->s2, 2, 4, "abcdefghijklmnopqrst", 20, 2); + test(*r->s2, 4, 0, "", 0, 0); + test(*r->s2, 4, 0, "abcde", 0, 0); + test(*r->s2, 4, 0, "abcde", 1, -1); + test(*r->s2, 4, 0, "abcde", 2, -2); + test(*r->s2, 4, 0, "abcde", 4, -4); + test(*r->s2, 4, 0, "abcde", 5, -5); + test(*r->s2, 4, 0, "abcdefghij", 0, 0); + test(*r->s2, 4, 0, "abcdefghij", 1, -1); + test(*r->s2, 4, 0, "abcdefghij", 5, -5); + test(*r->s2, 4, 0, "abcdefghij", 9, -9); + test(*r->s2, 4, 0, "abcdefghij", 10, -10); + test(*r->s2, 4, 0, "abcdefghijklmnopqrst", 0, 0); + test(*r->s2, 4, 0, "abcdefghijklmnopqrst", 1, -1); + test(*r->s2, 4, 0, "abcdefghijklmnopqrst", 10, -10); + test(*r->s2, 4, 0, "abcdefghijklmnopqrst", 19, -19); + test(*r->s2, 4, 0, "abcdefghijklmnopqrst", 20, -20); + test(*r->s2, 4, 1, "", 0, 1); + test(*r->s2, 4, 1, "abcde", 0, 1); + test(*r->s2, 4, 1, "abcde", 1, 4); + test(*r->s2, 4, 1, "abcde", 2, 4); + test(*r->s2, 4, 1, "abcde", 4, 4); + test(*r->s2, 4, 1, "abcde", 5, 4); + test(*r->s2, 4, 1, "abcdefghij", 0, 1); + test(*r->s2, 4, 1, "abcdefghij", 1, 4); + test(*r->s2, 4, 1, "abcdefghij", 5, 4); + test(*r->s2, 4, 1, "abcdefghij", 9, 4); + test(*r->s2, 4, 1, "abcdefghij", 10, 4); + test(*r->s2, 4, 1, "abcdefghijklmnopqrst", 0, 1); + test(*r->s2, 4, 1, "abcdefghijklmnopqrst", 1, 4); + test(*r->s2, 4, 1, "abcdefghijklmnopqrst", 10, 4); + test(*r->s2, 4, 1, "abcdefghijklmnopqrst", 19, 4); + test(*r->s2, 4, 1, "abcdefghijklmnopqrst", 20, 4); + test(*r->s2, 4, 2, "", 0, 1); + test(*r->s2, 4, 2, "abcde", 0, 1); + test(*r->s2, 4, 2, "abcde", 1, 4); + test(*r->s2, 4, 2, "abcde", 2, 4); + test(*r->s2, 4, 2, "abcde", 4, 4); + test(*r->s2, 4, 2, "abcde", 5, 4); + test(*r->s2, 4, 2, "abcdefghij", 0, 1); + test(*r->s2, 4, 2, "abcdefghij", 1, 4); + test(*r->s2, 4, 2, "abcdefghij", 5, 4); + test(*r->s2, 4, 2, "abcdefghij", 9, 4); + test(*r->s2, 4, 2, "abcdefghij", 10, 4); + test(*r->s2, 4, 2, "abcdefghijklmnopqrst", 0, 1); + test(*r->s2, 4, 2, "abcdefghijklmnopqrst", 1, 4); + test(*r->s2, 4, 2, "abcdefghijklmnopqrst", 10, 4); + test(*r->s2, 4, 2, "abcdefghijklmnopqrst", 19, 4); + test(*r->s2, 4, 2, "abcdefghijklmnopqrst", 20, 4); + test(*r->s2, 5, 0, "", 0, 0); + test(*r->s2, 5, 0, "abcde", 0, 0); + test(*r->s2, 5, 0, "abcde", 1, -1); + test(*r->s2, 5, 0, "abcde", 2, -2); + test(*r->s2, 5, 0, "abcde", 4, -4); + test(*r->s2, 5, 0, "abcde", 5, -5); + test(*r->s2, 5, 0, "abcdefghij", 0, 0); + test(*r->s2, 5, 0, "abcdefghij", 1, -1); + test(*r->s2, 5, 0, "abcdefghij", 5, -5); + test(*r->s2, 5, 0, "abcdefghij", 9, -9); + test(*r->s2, 5, 0, "abcdefghij", 10, -10); + test(*r->s2, 5, 0, "abcdefghijklmnopqrst", 0, 0); + test(*r->s2, 5, 0, "abcdefghijklmnopqrst", 1, -1); + test(*r->s2, 5, 0, "abcdefghijklmnopqrst", 10, -10); + test(*r->s2, 5, 0, "abcdefghijklmnopqrst", 19, -19); + test(*r->s2, 5, 0, "abcdefghijklmnopqrst", 20, -20); + test(*r->s2, 5, 1, "", 0, 0); + test(*r->s2, 5, 1, "abcde", 0, 0); + test(*r->s2, 5, 1, "abcde", 1, -1); + test(*r->s2, 5, 1, "abcde", 2, -2); + test(*r->s2, 5, 1, "abcde", 4, -4); + test(*r->s2, 5, 1, "abcde", 5, -5); + test(*r->s2, 5, 1, "abcdefghij", 0, 0); + test(*r->s2, 5, 1, "abcdefghij", 1, -1); + test(*r->s2, 5, 1, "abcdefghij", 5, -5); + test(*r->s2, 5, 1, "abcdefghij", 9, -9); + test(*r->s2, 5, 1, "abcdefghij", 10, -10); + test(*r->s2, 5, 1, "abcdefghijklmnopqrst", 0, 0); + test(*r->s2, 5, 1, "abcdefghijklmnopqrst", 1, -1); + test(*r->s2, 5, 1, "abcdefghijklmnopqrst", 10, -10); + test(*r->s2, 5, 1, "abcdefghijklmnopqrst", 19, -19); + test(*r->s2, 5, 1, "abcdefghijklmnopqrst", 20, -20); +} + +template +void +test4(pmem::obj::pool &pop) +{ + auto r = pop.root(); + + test(*r->s2, 6, 0, "", 0, 0); + test(*r->s2, 6, 0, "abcde", 0, 0); + test(*r->s2, 6, 0, "abcde", 1, 0); + test(*r->s2, 6, 0, "abcde", 2, 0); + test(*r->s2, 6, 0, "abcde", 4, 0); + test(*r->s2, 6, 0, "abcde", 5, 0); + test(*r->s2, 6, 0, "abcdefghij", 0, 0); + test(*r->s2, 6, 0, "abcdefghij", 1, 0); + test(*r->s2, 6, 0, "abcdefghij", 5, 0); + test(*r->s2, 6, 0, "abcdefghij", 9, 0); + test(*r->s2, 6, 0, "abcdefghij", 10, 0); + test(*r->s2, 6, 0, "abcdefghijklmnopqrst", 0, 0); + test(*r->s2, 6, 0, "abcdefghijklmnopqrst", 1, 0); + test(*r->s2, 6, 0, "abcdefghijklmnopqrst", 10, 0); + test(*r->s2, 6, 0, "abcdefghijklmnopqrst", 19, 0); + test(*r->s2, 6, 0, "abcdefghijklmnopqrst", 20, 0); + test(*r->s3, 0, 0, "", 0, 0); + test(*r->s3, 0, 0, "abcde", 0, 0); + test(*r->s3, 0, 0, "abcde", 1, -1); + test(*r->s3, 0, 0, "abcde", 2, -2); + test(*r->s3, 0, 0, "abcde", 4, -4); + test(*r->s3, 0, 0, "abcde", 5, -5); + test(*r->s3, 0, 0, "abcdefghij", 0, 0); + test(*r->s3, 0, 0, "abcdefghij", 1, -1); + test(*r->s3, 0, 0, "abcdefghij", 5, -5); + test(*r->s3, 0, 0, "abcdefghij", 9, -9); + test(*r->s3, 0, 0, "abcdefghij", 10, -10); + test(*r->s3, 0, 0, "abcdefghijklmnopqrst", 0, 0); + test(*r->s3, 0, 0, "abcdefghijklmnopqrst", 1, -1); + test(*r->s3, 0, 0, "abcdefghijklmnopqrst", 10, -10); + test(*r->s3, 0, 0, "abcdefghijklmnopqrst", 19, -19); + test(*r->s3, 0, 0, "abcdefghijklmnopqrst", 20, -20); + test(*r->s3, 0, 1, "", 0, 1); + test(*r->s3, 0, 1, "abcde", 0, 1); + test(*r->s3, 0, 1, "abcde", 1, 0); + test(*r->s3, 0, 1, "abcde", 2, -1); + test(*r->s3, 0, 1, "abcde", 4, -3); + test(*r->s3, 0, 1, "abcde", 5, -4); + test(*r->s3, 0, 1, "abcdefghij", 0, 1); + test(*r->s3, 0, 1, "abcdefghij", 1, 0); + test(*r->s3, 0, 1, "abcdefghij", 5, -4); + test(*r->s3, 0, 1, "abcdefghij", 9, -8); + test(*r->s3, 0, 1, "abcdefghij", 10, -9); + test(*r->s3, 0, 1, "abcdefghijklmnopqrst", 0, 1); + test(*r->s3, 0, 1, "abcdefghijklmnopqrst", 1, 0); + test(*r->s3, 0, 1, "abcdefghijklmnopqrst", 10, -9); + test(*r->s3, 0, 1, "abcdefghijklmnopqrst", 19, -18); + test(*r->s3, 0, 1, "abcdefghijklmnopqrst", 20, -19); + test(*r->s3, 0, 5, "", 0, 5); + test(*r->s3, 0, 5, "abcde", 0, 5); + test(*r->s3, 0, 5, "abcde", 1, 4); + test(*r->s3, 0, 5, "abcde", 2, 3); + test(*r->s3, 0, 5, "abcde", 4, 1); + test(*r->s3, 0, 5, "abcde", 5, 0); + test(*r->s3, 0, 5, "abcdefghij", 0, 5); + test(*r->s3, 0, 5, "abcdefghij", 1, 4); + test(*r->s3, 0, 5, "abcdefghij", 5, 0); + test(*r->s3, 0, 5, "abcdefghij", 9, -4); + test(*r->s3, 0, 5, "abcdefghij", 10, -5); + test(*r->s3, 0, 5, "abcdefghijklmnopqrst", 0, 5); + test(*r->s3, 0, 5, "abcdefghijklmnopqrst", 1, 4); + test(*r->s3, 0, 5, "abcdefghijklmnopqrst", 10, -5); + test(*r->s3, 0, 5, "abcdefghijklmnopqrst", 19, -14); + test(*r->s3, 0, 5, "abcdefghijklmnopqrst", 20, -15); + test(*r->s3, 0, 9, "", 0, 9); + test(*r->s3, 0, 9, "abcde", 0, 9); + test(*r->s3, 0, 9, "abcde", 1, 8); + test(*r->s3, 0, 9, "abcde", 2, 7); + test(*r->s3, 0, 9, "abcde", 4, 5); + test(*r->s3, 0, 9, "abcde", 5, 4); + test(*r->s3, 0, 9, "abcdefghij", 0, 9); + test(*r->s3, 0, 9, "abcdefghij", 1, 8); + test(*r->s3, 0, 9, "abcdefghij", 5, 4); + test(*r->s3, 0, 9, "abcdefghij", 9, 0); + test(*r->s3, 0, 9, "abcdefghij", 10, -1); + test(*r->s3, 0, 9, "abcdefghijklmnopqrst", 0, 9); + test(*r->s3, 0, 9, "abcdefghijklmnopqrst", 1, 8); + test(*r->s3, 0, 9, "abcdefghijklmnopqrst", 10, -1); + test(*r->s3, 0, 9, "abcdefghijklmnopqrst", 19, -10); + test(*r->s3, 0, 9, "abcdefghijklmnopqrst", 20, -11); + test(*r->s3, 0, 10, "", 0, 10); + test(*r->s3, 0, 10, "abcde", 0, 10); + test(*r->s3, 0, 10, "abcde", 1, 9); + test(*r->s3, 0, 10, "abcde", 2, 8); + test(*r->s3, 0, 10, "abcde", 4, 6); + test(*r->s3, 0, 10, "abcde", 5, 5); + test(*r->s3, 0, 10, "abcdefghij", 0, 10); + test(*r->s3, 0, 10, "abcdefghij", 1, 9); + test(*r->s3, 0, 10, "abcdefghij", 5, 5); + test(*r->s3, 0, 10, "abcdefghij", 9, 1); + test(*r->s3, 0, 10, "abcdefghij", 10, 0); + test(*r->s3, 0, 10, "abcdefghijklmnopqrst", 0, 10); + test(*r->s3, 0, 10, "abcdefghijklmnopqrst", 1, 9); + test(*r->s3, 0, 10, "abcdefghijklmnopqrst", 10, 0); + test(*r->s3, 0, 10, "abcdefghijklmnopqrst", 19, -9); + test(*r->s3, 0, 10, "abcdefghijklmnopqrst", 20, -10); + test(*r->s3, 0, 11, "", 0, 10); + test(*r->s3, 0, 11, "abcde", 0, 10); + test(*r->s3, 0, 11, "abcde", 1, 9); + test(*r->s3, 0, 11, "abcde", 2, 8); +} + +template +void +test5(pmem::obj::pool &pop) +{ + auto r = pop.root(); + + test(*r->s3, 0, 11, "abcde", 4, 6); + test(*r->s3, 0, 11, "abcde", 5, 5); + test(*r->s3, 0, 11, "abcdefghij", 0, 10); + test(*r->s3, 0, 11, "abcdefghij", 1, 9); + test(*r->s3, 0, 11, "abcdefghij", 5, 5); + test(*r->s3, 0, 11, "abcdefghij", 9, 1); + test(*r->s3, 0, 11, "abcdefghij", 10, 0); + test(*r->s3, 0, 11, "abcdefghijklmnopqrst", 0, 10); + test(*r->s3, 0, 11, "abcdefghijklmnopqrst", 1, 9); + test(*r->s3, 0, 11, "abcdefghijklmnopqrst", 10, 0); + test(*r->s3, 0, 11, "abcdefghijklmnopqrst", 19, -9); + test(*r->s3, 0, 11, "abcdefghijklmnopqrst", 20, -10); + test(*r->s3, 1, 0, "", 0, 0); + test(*r->s3, 1, 0, "abcde", 0, 0); + test(*r->s3, 1, 0, "abcde", 1, -1); + test(*r->s3, 1, 0, "abcde", 2, -2); + test(*r->s3, 1, 0, "abcde", 4, -4); + test(*r->s3, 1, 0, "abcde", 5, -5); + test(*r->s3, 1, 0, "abcdefghij", 0, 0); + test(*r->s3, 1, 0, "abcdefghij", 1, -1); + test(*r->s3, 1, 0, "abcdefghij", 5, -5); + test(*r->s3, 1, 0, "abcdefghij", 9, -9); + test(*r->s3, 1, 0, "abcdefghij", 10, -10); + test(*r->s3, 1, 0, "abcdefghijklmnopqrst", 0, 0); + test(*r->s3, 1, 0, "abcdefghijklmnopqrst", 1, -1); + test(*r->s3, 1, 0, "abcdefghijklmnopqrst", 10, -10); + test(*r->s3, 1, 0, "abcdefghijklmnopqrst", 19, -19); + test(*r->s3, 1, 0, "abcdefghijklmnopqrst", 20, -20); + test(*r->s3, 1, 1, "", 0, 1); + test(*r->s3, 1, 1, "abcde", 0, 1); + test(*r->s3, 1, 1, "abcde", 1, 1); + test(*r->s3, 1, 1, "abcde", 2, 1); + test(*r->s3, 1, 1, "abcde", 4, 1); + test(*r->s3, 1, 1, "abcde", 5, 1); + test(*r->s3, 1, 1, "abcdefghij", 0, 1); + test(*r->s3, 1, 1, "abcdefghij", 1, 1); + test(*r->s3, 1, 1, "abcdefghij", 5, 1); + test(*r->s3, 1, 1, "abcdefghij", 9, 1); + test(*r->s3, 1, 1, "abcdefghij", 10, 1); + test(*r->s3, 1, 1, "abcdefghijklmnopqrst", 0, 1); + test(*r->s3, 1, 1, "abcdefghijklmnopqrst", 1, 1); + test(*r->s3, 1, 1, "abcdefghijklmnopqrst", 10, 1); + test(*r->s3, 1, 1, "abcdefghijklmnopqrst", 19, 1); + test(*r->s3, 1, 1, "abcdefghijklmnopqrst", 20, 1); + test(*r->s3, 1, 4, "", 0, 4); + test(*r->s3, 1, 4, "abcde", 0, 4); + test(*r->s3, 1, 4, "abcde", 1, 1); + test(*r->s3, 1, 4, "abcde", 2, 1); + test(*r->s3, 1, 4, "abcde", 4, 1); + test(*r->s3, 1, 4, "abcde", 5, 1); + test(*r->s3, 1, 4, "abcdefghij", 0, 4); + test(*r->s3, 1, 4, "abcdefghij", 1, 1); + test(*r->s3, 1, 4, "abcdefghij", 5, 1); + test(*r->s3, 1, 4, "abcdefghij", 9, 1); + test(*r->s3, 1, 4, "abcdefghij", 10, 1); + test(*r->s3, 1, 4, "abcdefghijklmnopqrst", 0, 4); + test(*r->s3, 1, 4, "abcdefghijklmnopqrst", 1, 1); + test(*r->s3, 1, 4, "abcdefghijklmnopqrst", 10, 1); + test(*r->s3, 1, 4, "abcdefghijklmnopqrst", 19, 1); + test(*r->s3, 1, 4, "abcdefghijklmnopqrst", 20, 1); + test(*r->s3, 1, 8, "", 0, 8); + test(*r->s3, 1, 8, "abcde", 0, 8); + test(*r->s3, 1, 8, "abcde", 1, 1); + test(*r->s3, 1, 8, "abcde", 2, 1); + test(*r->s3, 1, 8, "abcde", 4, 1); + test(*r->s3, 1, 8, "abcde", 5, 1); + test(*r->s3, 1, 8, "abcdefghij", 0, 8); + test(*r->s3, 1, 8, "abcdefghij", 1, 1); + test(*r->s3, 1, 8, "abcdefghij", 5, 1); + test(*r->s3, 1, 8, "abcdefghij", 9, 1); + test(*r->s3, 1, 8, "abcdefghij", 10, 1); + test(*r->s3, 1, 8, "abcdefghijklmnopqrst", 0, 8); + test(*r->s3, 1, 8, "abcdefghijklmnopqrst", 1, 1); + test(*r->s3, 1, 8, "abcdefghijklmnopqrst", 10, 1); + test(*r->s3, 1, 8, "abcdefghijklmnopqrst", 19, 1); + test(*r->s3, 1, 8, "abcdefghijklmnopqrst", 20, 1); + test(*r->s3, 1, 9, "", 0, 9); + test(*r->s3, 1, 9, "abcde", 0, 9); + test(*r->s3, 1, 9, "abcde", 1, 1); + test(*r->s3, 1, 9, "abcde", 2, 1); + test(*r->s3, 1, 9, "abcde", 4, 1); + test(*r->s3, 1, 9, "abcde", 5, 1); + test(*r->s3, 1, 9, "abcdefghij", 0, 9); + test(*r->s3, 1, 9, "abcdefghij", 1, 1); + test(*r->s3, 1, 9, "abcdefghij", 5, 1); + test(*r->s3, 1, 9, "abcdefghij", 9, 1); + test(*r->s3, 1, 9, "abcdefghij", 10, 1); + test(*r->s3, 1, 9, "abcdefghijklmnopqrst", 0, 9); + test(*r->s3, 1, 9, "abcdefghijklmnopqrst", 1, 1); + test(*r->s3, 1, 9, "abcdefghijklmnopqrst", 10, 1); + test(*r->s3, 1, 9, "abcdefghijklmnopqrst", 19, 1); + test(*r->s3, 1, 9, "abcdefghijklmnopqrst", 20, 1); + test(*r->s3, 1, 10, "", 0, 9); + test(*r->s3, 1, 10, "abcde", 0, 9); + test(*r->s3, 1, 10, "abcde", 1, 1); + test(*r->s3, 1, 10, "abcde", 2, 1); + test(*r->s3, 1, 10, "abcde", 4, 1); + test(*r->s3, 1, 10, "abcde", 5, 1); + test(*r->s3, 1, 10, "abcdefghij", 0, 9); + test(*r->s3, 1, 10, "abcdefghij", 1, 1); +} + +template +void +test6(pmem::obj::pool &pop) +{ + auto r = pop.root(); + + test(*r->s3, 1, 10, "abcdefghij", 5, 1); + test(*r->s3, 1, 10, "abcdefghij", 9, 1); + test(*r->s3, 1, 10, "abcdefghij", 10, 1); + test(*r->s3, 1, 10, "abcdefghijklmnopqrst", 0, 9); + test(*r->s3, 1, 10, "abcdefghijklmnopqrst", 1, 1); + test(*r->s3, 1, 10, "abcdefghijklmnopqrst", 10, 1); + test(*r->s3, 1, 10, "abcdefghijklmnopqrst", 19, 1); + test(*r->s3, 1, 10, "abcdefghijklmnopqrst", 20, 1); + test(*r->s3, 5, 0, "", 0, 0); + test(*r->s3, 5, 0, "abcde", 0, 0); + test(*r->s3, 5, 0, "abcde", 1, -1); + test(*r->s3, 5, 0, "abcde", 2, -2); + test(*r->s3, 5, 0, "abcde", 4, -4); + test(*r->s3, 5, 0, "abcde", 5, -5); + test(*r->s3, 5, 0, "abcdefghij", 0, 0); + test(*r->s3, 5, 0, "abcdefghij", 1, -1); + test(*r->s3, 5, 0, "abcdefghij", 5, -5); + test(*r->s3, 5, 0, "abcdefghij", 9, -9); + test(*r->s3, 5, 0, "abcdefghij", 10, -10); + test(*r->s3, 5, 0, "abcdefghijklmnopqrst", 0, 0); + test(*r->s3, 5, 0, "abcdefghijklmnopqrst", 1, -1); + test(*r->s3, 5, 0, "abcdefghijklmnopqrst", 10, -10); + test(*r->s3, 5, 0, "abcdefghijklmnopqrst", 19, -19); + test(*r->s3, 5, 0, "abcdefghijklmnopqrst", 20, -20); + test(*r->s3, 5, 1, "", 0, 1); + test(*r->s3, 5, 1, "abcde", 0, 1); + test(*r->s3, 5, 1, "abcde", 1, 5); + test(*r->s3, 5, 1, "abcde", 2, 5); + test(*r->s3, 5, 1, "abcde", 4, 5); + test(*r->s3, 5, 1, "abcde", 5, 5); + test(*r->s3, 5, 1, "abcdefghij", 0, 1); + test(*r->s3, 5, 1, "abcdefghij", 1, 5); + test(*r->s3, 5, 1, "abcdefghij", 5, 5); + test(*r->s3, 5, 1, "abcdefghij", 9, 5); + test(*r->s3, 5, 1, "abcdefghij", 10, 5); + test(*r->s3, 5, 1, "abcdefghijklmnopqrst", 0, 1); + test(*r->s3, 5, 1, "abcdefghijklmnopqrst", 1, 5); + test(*r->s3, 5, 1, "abcdefghijklmnopqrst", 10, 5); + test(*r->s3, 5, 1, "abcdefghijklmnopqrst", 19, 5); + test(*r->s3, 5, 1, "abcdefghijklmnopqrst", 20, 5); + test(*r->s3, 5, 2, "", 0, 2); + test(*r->s3, 5, 2, "abcde", 0, 2); + test(*r->s3, 5, 2, "abcde", 1, 5); + test(*r->s3, 5, 2, "abcde", 2, 5); + test(*r->s3, 5, 2, "abcde", 4, 5); + test(*r->s3, 5, 2, "abcde", 5, 5); + test(*r->s3, 5, 2, "abcdefghij", 0, 2); + test(*r->s3, 5, 2, "abcdefghij", 1, 5); + test(*r->s3, 5, 2, "abcdefghij", 5, 5); + test(*r->s3, 5, 2, "abcdefghij", 9, 5); + test(*r->s3, 5, 2, "abcdefghij", 10, 5); + test(*r->s3, 5, 2, "abcdefghijklmnopqrst", 0, 2); + test(*r->s3, 5, 2, "abcdefghijklmnopqrst", 1, 5); + test(*r->s3, 5, 2, "abcdefghijklmnopqrst", 10, 5); + test(*r->s3, 5, 2, "abcdefghijklmnopqrst", 19, 5); + test(*r->s3, 5, 2, "abcdefghijklmnopqrst", 20, 5); + test(*r->s3, 5, 4, "", 0, 4); + test(*r->s3, 5, 4, "abcde", 0, 4); + test(*r->s3, 5, 4, "abcde", 1, 5); + test(*r->s3, 5, 4, "abcde", 2, 5); + test(*r->s3, 5, 4, "abcde", 4, 5); + test(*r->s3, 5, 4, "abcde", 5, 5); + test(*r->s3, 5, 4, "abcdefghij", 0, 4); + test(*r->s3, 5, 4, "abcdefghij", 1, 5); + test(*r->s3, 5, 4, "abcdefghij", 5, 5); + test(*r->s3, 5, 4, "abcdefghij", 9, 5); + test(*r->s3, 5, 4, "abcdefghij", 10, 5); + test(*r->s3, 5, 4, "abcdefghijklmnopqrst", 0, 4); + test(*r->s3, 5, 4, "abcdefghijklmnopqrst", 1, 5); + test(*r->s3, 5, 4, "abcdefghijklmnopqrst", 10, 5); + test(*r->s3, 5, 4, "abcdefghijklmnopqrst", 19, 5); + test(*r->s3, 5, 4, "abcdefghijklmnopqrst", 20, 5); + test(*r->s3, 5, 5, "", 0, 5); + test(*r->s3, 5, 5, "abcde", 0, 5); + test(*r->s3, 5, 5, "abcde", 1, 5); + test(*r->s3, 5, 5, "abcde", 2, 5); + test(*r->s3, 5, 5, "abcde", 4, 5); + test(*r->s3, 5, 5, "abcde", 5, 5); + test(*r->s3, 5, 5, "abcdefghij", 0, 5); + test(*r->s3, 5, 5, "abcdefghij", 1, 5); + test(*r->s3, 5, 5, "abcdefghij", 5, 5); + test(*r->s3, 5, 5, "abcdefghij", 9, 5); + test(*r->s3, 5, 5, "abcdefghij", 10, 5); + test(*r->s3, 5, 5, "abcdefghijklmnopqrst", 0, 5); + test(*r->s3, 5, 5, "abcdefghijklmnopqrst", 1, 5); + test(*r->s3, 5, 5, "abcdefghijklmnopqrst", 10, 5); + test(*r->s3, 5, 5, "abcdefghijklmnopqrst", 19, 5); + test(*r->s3, 5, 5, "abcdefghijklmnopqrst", 20, 5); + test(*r->s3, 5, 6, "", 0, 5); + test(*r->s3, 5, 6, "abcde", 0, 5); + test(*r->s3, 5, 6, "abcde", 1, 5); + test(*r->s3, 5, 6, "abcde", 2, 5); + test(*r->s3, 5, 6, "abcde", 4, 5); + test(*r->s3, 5, 6, "abcde", 5, 5); + test(*r->s3, 5, 6, "abcdefghij", 0, 5); + test(*r->s3, 5, 6, "abcdefghij", 1, 5); + test(*r->s3, 5, 6, "abcdefghij", 5, 5); + test(*r->s3, 5, 6, "abcdefghij", 9, 5); + test(*r->s3, 5, 6, "abcdefghij", 10, 5); + test(*r->s3, 5, 6, "abcdefghijklmnopqrst", 0, 5); +} + +template +void +test7(pmem::obj::pool &pop) +{ + auto r = pop.root(); + + test(*r->s3, 5, 6, "abcdefghijklmnopqrst", 1, 5); + test(*r->s3, 5, 6, "abcdefghijklmnopqrst", 10, 5); + test(*r->s3, 5, 6, "abcdefghijklmnopqrst", 19, 5); + test(*r->s3, 5, 6, "abcdefghijklmnopqrst", 20, 5); + test(*r->s3, 9, 0, "", 0, 0); + test(*r->s3, 9, 0, "abcde", 0, 0); + test(*r->s3, 9, 0, "abcde", 1, -1); + test(*r->s3, 9, 0, "abcde", 2, -2); + test(*r->s3, 9, 0, "abcde", 4, -4); + test(*r->s3, 9, 0, "abcde", 5, -5); + test(*r->s3, 9, 0, "abcdefghij", 0, 0); + test(*r->s3, 9, 0, "abcdefghij", 1, -1); + test(*r->s3, 9, 0, "abcdefghij", 5, -5); + test(*r->s3, 9, 0, "abcdefghij", 9, -9); + test(*r->s3, 9, 0, "abcdefghij", 10, -10); + test(*r->s3, 9, 0, "abcdefghijklmnopqrst", 0, 0); + test(*r->s3, 9, 0, "abcdefghijklmnopqrst", 1, -1); + test(*r->s3, 9, 0, "abcdefghijklmnopqrst", 10, -10); + test(*r->s3, 9, 0, "abcdefghijklmnopqrst", 19, -19); + test(*r->s3, 9, 0, "abcdefghijklmnopqrst", 20, -20); + test(*r->s3, 9, 1, "", 0, 1); + test(*r->s3, 9, 1, "abcde", 0, 1); + test(*r->s3, 9, 1, "abcde", 1, 9); + test(*r->s3, 9, 1, "abcde", 2, 9); + test(*r->s3, 9, 1, "abcde", 4, 9); + test(*r->s3, 9, 1, "abcde", 5, 9); + test(*r->s3, 9, 1, "abcdefghij", 0, 1); + test(*r->s3, 9, 1, "abcdefghij", 1, 9); + test(*r->s3, 9, 1, "abcdefghij", 5, 9); + test(*r->s3, 9, 1, "abcdefghij", 9, 9); + test(*r->s3, 9, 1, "abcdefghij", 10, 9); + test(*r->s3, 9, 1, "abcdefghijklmnopqrst", 0, 1); + test(*r->s3, 9, 1, "abcdefghijklmnopqrst", 1, 9); + test(*r->s3, 9, 1, "abcdefghijklmnopqrst", 10, 9); + test(*r->s3, 9, 1, "abcdefghijklmnopqrst", 19, 9); + test(*r->s3, 9, 1, "abcdefghijklmnopqrst", 20, 9); + test(*r->s3, 9, 2, "", 0, 1); + test(*r->s3, 9, 2, "abcde", 0, 1); + test(*r->s3, 9, 2, "abcde", 1, 9); + test(*r->s3, 9, 2, "abcde", 2, 9); + test(*r->s3, 9, 2, "abcde", 4, 9); + test(*r->s3, 9, 2, "abcde", 5, 9); + test(*r->s3, 9, 2, "abcdefghij", 0, 1); + test(*r->s3, 9, 2, "abcdefghij", 1, 9); + test(*r->s3, 9, 2, "abcdefghij", 5, 9); + test(*r->s3, 9, 2, "abcdefghij", 9, 9); + test(*r->s3, 9, 2, "abcdefghij", 10, 9); + test(*r->s3, 9, 2, "abcdefghijklmnopqrst", 0, 1); + test(*r->s3, 9, 2, "abcdefghijklmnopqrst", 1, 9); + test(*r->s3, 9, 2, "abcdefghijklmnopqrst", 10, 9); + test(*r->s3, 9, 2, "abcdefghijklmnopqrst", 19, 9); + test(*r->s3, 9, 2, "abcdefghijklmnopqrst", 20, 9); + test(*r->s3, 10, 0, "", 0, 0); + test(*r->s3, 10, 0, "abcde", 0, 0); + test(*r->s3, 10, 0, "abcde", 1, -1); + test(*r->s3, 10, 0, "abcde", 2, -2); + test(*r->s3, 10, 0, "abcde", 4, -4); + test(*r->s3, 10, 0, "abcde", 5, -5); + test(*r->s3, 10, 0, "abcdefghij", 0, 0); + test(*r->s3, 10, 0, "abcdefghij", 1, -1); + test(*r->s3, 10, 0, "abcdefghij", 5, -5); + test(*r->s3, 10, 0, "abcdefghij", 9, -9); + test(*r->s3, 10, 0, "abcdefghij", 10, -10); + test(*r->s3, 10, 0, "abcdefghijklmnopqrst", 0, 0); + test(*r->s3, 10, 0, "abcdefghijklmnopqrst", 1, -1); + test(*r->s3, 10, 0, "abcdefghijklmnopqrst", 10, -10); + test(*r->s3, 10, 0, "abcdefghijklmnopqrst", 19, -19); + test(*r->s3, 10, 0, "abcdefghijklmnopqrst", 20, -20); + test(*r->s3, 10, 1, "", 0, 0); + test(*r->s3, 10, 1, "abcde", 0, 0); + test(*r->s3, 10, 1, "abcde", 1, -1); + test(*r->s3, 10, 1, "abcde", 2, -2); + test(*r->s3, 10, 1, "abcde", 4, -4); + test(*r->s3, 10, 1, "abcde", 5, -5); + test(*r->s3, 10, 1, "abcdefghij", 0, 0); + test(*r->s3, 10, 1, "abcdefghij", 1, -1); + test(*r->s3, 10, 1, "abcdefghij", 5, -5); + test(*r->s3, 10, 1, "abcdefghij", 9, -9); + test(*r->s3, 10, 1, "abcdefghij", 10, -10); + test(*r->s3, 10, 1, "abcdefghijklmnopqrst", 0, 0); + test(*r->s3, 10, 1, "abcdefghijklmnopqrst", 1, -1); + test(*r->s3, 10, 1, "abcdefghijklmnopqrst", 10, -10); + test(*r->s3, 10, 1, "abcdefghijklmnopqrst", 19, -19); + test(*r->s3, 10, 1, "abcdefghijklmnopqrst", 20, -20); + test(*r->s3, 11, 0, "", 0, 0); + test(*r->s3, 11, 0, "abcde", 0, 0); + test(*r->s3, 11, 0, "abcde", 1, 0); + test(*r->s3, 11, 0, "abcde", 2, 0); + test(*r->s3, 11, 0, "abcde", 4, 0); + test(*r->s3, 11, 0, "abcde", 5, 0); + test(*r->s3, 11, 0, "abcdefghij", 0, 0); + test(*r->s3, 11, 0, "abcdefghij", 1, 0); + test(*r->s3, 11, 0, "abcdefghij", 5, 0); + test(*r->s3, 11, 0, "abcdefghij", 9, 0); + test(*r->s3, 11, 0, "abcdefghij", 10, 0); + test(*r->s3, 11, 0, "abcdefghijklmnopqrst", 0, 0); + test(*r->s3, 11, 0, "abcdefghijklmnopqrst", 1, 0); + test(*r->s3, 11, 0, "abcdefghijklmnopqrst", 10, 0); + test(*r->s3, 11, 0, "abcdefghijklmnopqrst", 19, 0); + test(*r->s3, 11, 0, "abcdefghijklmnopqrst", 20, 0); +} + +template +void +test8(pmem::obj::pool &pop) +{ + auto r = pop.root(); + + test(*r->s4, 0, 0, "", 0, 0); + test(*r->s4, 0, 0, "abcde", 0, 0); + test(*r->s4, 0, 0, "abcde", 1, -1); + test(*r->s4, 0, 0, "abcde", 2, -2); + test(*r->s4, 0, 0, "abcde", 4, -4); + test(*r->s4, 0, 0, "abcde", 5, -5); + test(*r->s4, 0, 0, "abcdefghij", 0, 0); + test(*r->s4, 0, 0, "abcdefghij", 1, -1); + test(*r->s4, 0, 0, "abcdefghij", 5, -5); + test(*r->s4, 0, 0, "abcdefghij", 9, -9); + test(*r->s4, 0, 0, "abcdefghij", 10, -10); + test(*r->s4, 0, 0, "abcdefghijklmnopqrst", 0, 0); + test(*r->s4, 0, 0, "abcdefghijklmnopqrst", 1, -1); + test(*r->s4, 0, 0, "abcdefghijklmnopqrst", 10, -10); + test(*r->s4, 0, 0, "abcdefghijklmnopqrst", 19, -19); + test(*r->s4, 0, 0, "abcdefghijklmnopqrst", 20, -20); + test(*r->s4, 0, 1, "", 0, 1); + test(*r->s4, 0, 1, "abcde", 0, 1); + test(*r->s4, 0, 1, "abcde", 1, 0); + test(*r->s4, 0, 1, "abcde", 2, -1); + test(*r->s4, 0, 1, "abcde", 4, -3); + test(*r->s4, 0, 1, "abcde", 5, -4); + test(*r->s4, 0, 1, "abcdefghij", 0, 1); + test(*r->s4, 0, 1, "abcdefghij", 1, 0); + test(*r->s4, 0, 1, "abcdefghij", 5, -4); + test(*r->s4, 0, 1, "abcdefghij", 9, -8); + test(*r->s4, 0, 1, "abcdefghij", 10, -9); + test(*r->s4, 0, 1, "abcdefghijklmnopqrst", 0, 1); + test(*r->s4, 0, 1, "abcdefghijklmnopqrst", 1, 0); + test(*r->s4, 0, 1, "abcdefghijklmnopqrst", 10, -9); + test(*r->s4, 0, 1, "abcdefghijklmnopqrst", 19, -18); + test(*r->s4, 0, 1, "abcdefghijklmnopqrst", 20, -19); + test(*r->s4, 0, 10, "", 0, 10); + test(*r->s4, 0, 10, "abcde", 0, 10); + test(*r->s4, 0, 10, "abcde", 1, 9); + test(*r->s4, 0, 10, "abcde", 2, 8); + test(*r->s4, 0, 10, "abcde", 4, 6); + test(*r->s4, 0, 10, "abcde", 5, 5); + test(*r->s4, 0, 10, "abcdefghij", 0, 10); + test(*r->s4, 0, 10, "abcdefghij", 1, 9); + test(*r->s4, 0, 10, "abcdefghij", 5, 5); + test(*r->s4, 0, 10, "abcdefghij", 9, 1); + test(*r->s4, 0, 10, "abcdefghij", 10, 0); + test(*r->s4, 0, 10, "abcdefghijklmnopqrst", 0, 10); + test(*r->s4, 0, 10, "abcdefghijklmnopqrst", 1, 9); + test(*r->s4, 0, 10, "abcdefghijklmnopqrst", 10, 0); + test(*r->s4, 0, 10, "abcdefghijklmnopqrst", 19, -9); + test(*r->s4, 0, 10, "abcdefghijklmnopqrst", 20, -10); + test(*r->s4, 0, 19, "", 0, 19); + test(*r->s4, 0, 19, "abcde", 0, 19); + test(*r->s4, 0, 19, "abcde", 1, 18); + test(*r->s4, 0, 19, "abcde", 2, 17); + test(*r->s4, 0, 19, "abcde", 4, 15); + test(*r->s4, 0, 19, "abcde", 5, 14); + test(*r->s4, 0, 19, "abcdefghij", 0, 19); + test(*r->s4, 0, 19, "abcdefghij", 1, 18); + test(*r->s4, 0, 19, "abcdefghij", 5, 14); + test(*r->s4, 0, 19, "abcdefghij", 9, 10); + test(*r->s4, 0, 19, "abcdefghij", 10, 9); + test(*r->s4, 0, 19, "abcdefghijklmnopqrst", 0, 19); + test(*r->s4, 0, 19, "abcdefghijklmnopqrst", 1, 18); + test(*r->s4, 0, 19, "abcdefghijklmnopqrst", 10, 9); + test(*r->s4, 0, 19, "abcdefghijklmnopqrst", 19, 0); + test(*r->s4, 0, 19, "abcdefghijklmnopqrst", 20, -1); + test(*r->s4, 0, 20, "", 0, 20); + test(*r->s4, 0, 20, "abcde", 0, 20); + test(*r->s4, 0, 20, "abcde", 1, 19); + test(*r->s4, 0, 20, "abcde", 2, 18); + test(*r->s4, 0, 20, "abcde", 4, 16); + test(*r->s4, 0, 20, "abcde", 5, 15); + test(*r->s4, 0, 20, "abcdefghij", 0, 20); + test(*r->s4, 0, 20, "abcdefghij", 1, 19); + test(*r->s4, 0, 20, "abcdefghij", 5, 15); + test(*r->s4, 0, 20, "abcdefghij", 9, 11); + test(*r->s4, 0, 20, "abcdefghij", 10, 10); + test(*r->s4, 0, 20, "abcdefghijklmnopqrst", 0, 20); + test(*r->s4, 0, 20, "abcdefghijklmnopqrst", 1, 19); + test(*r->s4, 0, 20, "abcdefghijklmnopqrst", 10, 10); + test(*r->s4, 0, 20, "abcdefghijklmnopqrst", 19, 1); + test(*r->s4, 0, 20, "abcdefghijklmnopqrst", 20, 0); + test(*r->s4, 0, 21, "", 0, 20); + test(*r->s4, 0, 21, "abcde", 0, 20); + test(*r->s4, 0, 21, "abcde", 1, 19); + test(*r->s4, 0, 21, "abcde", 2, 18); + test(*r->s4, 0, 21, "abcde", 4, 16); + test(*r->s4, 0, 21, "abcde", 5, 15); + test(*r->s4, 0, 21, "abcdefghij", 0, 20); + test(*r->s4, 0, 21, "abcdefghij", 1, 19); + test(*r->s4, 0, 21, "abcdefghij", 5, 15); + test(*r->s4, 0, 21, "abcdefghij", 9, 11); + test(*r->s4, 0, 21, "abcdefghij", 10, 10); + test(*r->s4, 0, 21, "abcdefghijklmnopqrst", 0, 20); + test(*r->s4, 0, 21, "abcdefghijklmnopqrst", 1, 19); + test(*r->s4, 0, 21, "abcdefghijklmnopqrst", 10, 10); + test(*r->s4, 0, 21, "abcdefghijklmnopqrst", 19, 1); + test(*r->s4, 0, 21, "abcdefghijklmnopqrst", 20, 0); + test(*r->s4, 1, 0, "", 0, 0); + test(*r->s4, 1, 0, "abcde", 0, 0); + test(*r->s4, 1, 0, "abcde", 1, -1); + test(*r->s4, 1, 0, "abcde", 2, -2); +} + +template +void +test9(pmem::obj::pool &pop) +{ + auto r = pop.root(); + + test(*r->s4, 1, 0, "abcde", 4, -4); + test(*r->s4, 1, 0, "abcde", 5, -5); + test(*r->s4, 1, 0, "abcdefghij", 0, 0); + test(*r->s4, 1, 0, "abcdefghij", 1, -1); + test(*r->s4, 1, 0, "abcdefghij", 5, -5); + test(*r->s4, 1, 0, "abcdefghij", 9, -9); + test(*r->s4, 1, 0, "abcdefghij", 10, -10); + test(*r->s4, 1, 0, "abcdefghijklmnopqrst", 0, 0); + test(*r->s4, 1, 0, "abcdefghijklmnopqrst", 1, -1); + test(*r->s4, 1, 0, "abcdefghijklmnopqrst", 10, -10); + test(*r->s4, 1, 0, "abcdefghijklmnopqrst", 19, -19); + test(*r->s4, 1, 0, "abcdefghijklmnopqrst", 20, -20); + test(*r->s4, 1, 1, "", 0, 1); + test(*r->s4, 1, 1, "abcde", 0, 1); + test(*r->s4, 1, 1, "abcde", 1, 1); + test(*r->s4, 1, 1, "abcde", 2, 1); + test(*r->s4, 1, 1, "abcde", 4, 1); + test(*r->s4, 1, 1, "abcde", 5, 1); + test(*r->s4, 1, 1, "abcdefghij", 0, 1); + test(*r->s4, 1, 1, "abcdefghij", 1, 1); + test(*r->s4, 1, 1, "abcdefghij", 5, 1); + test(*r->s4, 1, 1, "abcdefghij", 9, 1); + test(*r->s4, 1, 1, "abcdefghij", 10, 1); + test(*r->s4, 1, 1, "abcdefghijklmnopqrst", 0, 1); + test(*r->s4, 1, 1, "abcdefghijklmnopqrst", 1, 1); + test(*r->s4, 1, 1, "abcdefghijklmnopqrst", 10, 1); + test(*r->s4, 1, 1, "abcdefghijklmnopqrst", 19, 1); + test(*r->s4, 1, 1, "abcdefghijklmnopqrst", 20, 1); + test(*r->s4, 1, 9, "", 0, 9); + test(*r->s4, 1, 9, "abcde", 0, 9); + test(*r->s4, 1, 9, "abcde", 1, 1); + test(*r->s4, 1, 9, "abcde", 2, 1); + test(*r->s4, 1, 9, "abcde", 4, 1); + test(*r->s4, 1, 9, "abcde", 5, 1); + test(*r->s4, 1, 9, "abcdefghij", 0, 9); + test(*r->s4, 1, 9, "abcdefghij", 1, 1); + test(*r->s4, 1, 9, "abcdefghij", 5, 1); + test(*r->s4, 1, 9, "abcdefghij", 9, 1); + test(*r->s4, 1, 9, "abcdefghij", 10, 1); + test(*r->s4, 1, 9, "abcdefghijklmnopqrst", 0, 9); + test(*r->s4, 1, 9, "abcdefghijklmnopqrst", 1, 1); + test(*r->s4, 1, 9, "abcdefghijklmnopqrst", 10, 1); + test(*r->s4, 1, 9, "abcdefghijklmnopqrst", 19, 1); + test(*r->s4, 1, 9, "abcdefghijklmnopqrst", 20, 1); + test(*r->s4, 1, 18, "", 0, 18); + test(*r->s4, 1, 18, "abcde", 0, 18); + test(*r->s4, 1, 18, "abcde", 1, 1); + test(*r->s4, 1, 18, "abcde", 2, 1); + test(*r->s4, 1, 18, "abcde", 4, 1); + test(*r->s4, 1, 18, "abcde", 5, 1); + test(*r->s4, 1, 18, "abcdefghij", 0, 18); + test(*r->s4, 1, 18, "abcdefghij", 1, 1); + test(*r->s4, 1, 18, "abcdefghij", 5, 1); + test(*r->s4, 1, 18, "abcdefghij", 9, 1); + test(*r->s4, 1, 18, "abcdefghij", 10, 1); + test(*r->s4, 1, 18, "abcdefghijklmnopqrst", 0, 18); + test(*r->s4, 1, 18, "abcdefghijklmnopqrst", 1, 1); + test(*r->s4, 1, 18, "abcdefghijklmnopqrst", 10, 1); + test(*r->s4, 1, 18, "abcdefghijklmnopqrst", 19, 1); + test(*r->s4, 1, 18, "abcdefghijklmnopqrst", 20, 1); + test(*r->s4, 1, 19, "", 0, 19); + test(*r->s4, 1, 19, "abcde", 0, 19); + test(*r->s4, 1, 19, "abcde", 1, 1); + test(*r->s4, 1, 19, "abcde", 2, 1); + test(*r->s4, 1, 19, "abcde", 4, 1); + test(*r->s4, 1, 19, "abcde", 5, 1); + test(*r->s4, 1, 19, "abcdefghij", 0, 19); + test(*r->s4, 1, 19, "abcdefghij", 1, 1); + test(*r->s4, 1, 19, "abcdefghij", 5, 1); + test(*r->s4, 1, 19, "abcdefghij", 9, 1); + test(*r->s4, 1, 19, "abcdefghij", 10, 1); + test(*r->s4, 1, 19, "abcdefghijklmnopqrst", 0, 19); + test(*r->s4, 1, 19, "abcdefghijklmnopqrst", 1, 1); + test(*r->s4, 1, 19, "abcdefghijklmnopqrst", 10, 1); + test(*r->s4, 1, 19, "abcdefghijklmnopqrst", 19, 1); + test(*r->s4, 1, 19, "abcdefghijklmnopqrst", 20, 1); + test(*r->s4, 1, 20, "", 0, 19); + test(*r->s4, 1, 20, "abcde", 0, 19); + test(*r->s4, 1, 20, "abcde", 1, 1); + test(*r->s4, 1, 20, "abcde", 2, 1); + test(*r->s4, 1, 20, "abcde", 4, 1); + test(*r->s4, 1, 20, "abcde", 5, 1); + test(*r->s4, 1, 20, "abcdefghij", 0, 19); + test(*r->s4, 1, 20, "abcdefghij", 1, 1); + test(*r->s4, 1, 20, "abcdefghij", 5, 1); + test(*r->s4, 1, 20, "abcdefghij", 9, 1); + test(*r->s4, 1, 20, "abcdefghij", 10, 1); + test(*r->s4, 1, 20, "abcdefghijklmnopqrst", 0, 19); + test(*r->s4, 1, 20, "abcdefghijklmnopqrst", 1, 1); + test(*r->s4, 1, 20, "abcdefghijklmnopqrst", 10, 1); + test(*r->s4, 1, 20, "abcdefghijklmnopqrst", 19, 1); + test(*r->s4, 1, 20, "abcdefghijklmnopqrst", 20, 1); + test(*r->s4, 10, 0, "", 0, 0); + test(*r->s4, 10, 0, "abcde", 0, 0); + test(*r->s4, 10, 0, "abcde", 1, -1); + test(*r->s4, 10, 0, "abcde", 2, -2); + test(*r->s4, 10, 0, "abcde", 4, -4); + test(*r->s4, 10, 0, "abcde", 5, -5); + test(*r->s4, 10, 0, "abcdefghij", 0, 0); + test(*r->s4, 10, 0, "abcdefghij", 1, -1); +} + +template +void +test10(pmem::obj::pool &pop) +{ + auto r = pop.root(); + + test(*r->s4, 10, 0, "abcdefghij", 5, -5); + test(*r->s4, 10, 0, "abcdefghij", 9, -9); + test(*r->s4, 10, 0, "abcdefghij", 10, -10); + test(*r->s4, 10, 0, "abcdefghijklmnopqrst", 0, 0); + test(*r->s4, 10, 0, "abcdefghijklmnopqrst", 1, -1); + test(*r->s4, 10, 0, "abcdefghijklmnopqrst", 10, -10); + test(*r->s4, 10, 0, "abcdefghijklmnopqrst", 19, -19); + test(*r->s4, 10, 0, "abcdefghijklmnopqrst", 20, -20); + test(*r->s4, 10, 1, "", 0, 1); + test(*r->s4, 10, 1, "abcde", 0, 1); + test(*r->s4, 10, 1, "abcde", 1, 10); + test(*r->s4, 10, 1, "abcde", 2, 10); + test(*r->s4, 10, 1, "abcde", 4, 10); + test(*r->s4, 10, 1, "abcde", 5, 10); + test(*r->s4, 10, 1, "abcdefghij", 0, 1); + test(*r->s4, 10, 1, "abcdefghij", 1, 10); + test(*r->s4, 10, 1, "abcdefghij", 5, 10); + test(*r->s4, 10, 1, "abcdefghij", 9, 10); + test(*r->s4, 10, 1, "abcdefghij", 10, 10); + test(*r->s4, 10, 1, "abcdefghijklmnopqrst", 0, 1); + test(*r->s4, 10, 1, "abcdefghijklmnopqrst", 1, 10); + test(*r->s4, 10, 1, "abcdefghijklmnopqrst", 10, 10); + test(*r->s4, 10, 1, "abcdefghijklmnopqrst", 19, 10); + test(*r->s4, 10, 1, "abcdefghijklmnopqrst", 20, 10); + test(*r->s4, 10, 5, "", 0, 5); + test(*r->s4, 10, 5, "abcde", 0, 5); + test(*r->s4, 10, 5, "abcde", 1, 10); + test(*r->s4, 10, 5, "abcde", 2, 10); + test(*r->s4, 10, 5, "abcde", 4, 10); + test(*r->s4, 10, 5, "abcde", 5, 10); + test(*r->s4, 10, 5, "abcdefghij", 0, 5); + test(*r->s4, 10, 5, "abcdefghij", 1, 10); + test(*r->s4, 10, 5, "abcdefghij", 5, 10); + test(*r->s4, 10, 5, "abcdefghij", 9, 10); + test(*r->s4, 10, 5, "abcdefghij", 10, 10); + test(*r->s4, 10, 5, "abcdefghijklmnopqrst", 0, 5); + test(*r->s4, 10, 5, "abcdefghijklmnopqrst", 1, 10); + test(*r->s4, 10, 5, "abcdefghijklmnopqrst", 10, 10); + test(*r->s4, 10, 5, "abcdefghijklmnopqrst", 19, 10); + test(*r->s4, 10, 5, "abcdefghijklmnopqrst", 20, 10); + test(*r->s4, 10, 9, "", 0, 9); + test(*r->s4, 10, 9, "abcde", 0, 9); + test(*r->s4, 10, 9, "abcde", 1, 10); + test(*r->s4, 10, 9, "abcde", 2, 10); + test(*r->s4, 10, 9, "abcde", 4, 10); + test(*r->s4, 10, 9, "abcde", 5, 10); + test(*r->s4, 10, 9, "abcdefghij", 0, 9); + test(*r->s4, 10, 9, "abcdefghij", 1, 10); + test(*r->s4, 10, 9, "abcdefghij", 5, 10); + test(*r->s4, 10, 9, "abcdefghij", 9, 10); + test(*r->s4, 10, 9, "abcdefghij", 10, 10); + test(*r->s4, 10, 9, "abcdefghijklmnopqrst", 0, 9); + test(*r->s4, 10, 9, "abcdefghijklmnopqrst", 1, 10); + test(*r->s4, 10, 9, "abcdefghijklmnopqrst", 10, 10); + test(*r->s4, 10, 9, "abcdefghijklmnopqrst", 19, 10); + test(*r->s4, 10, 9, "abcdefghijklmnopqrst", 20, 10); + test(*r->s4, 10, 10, "", 0, 10); + test(*r->s4, 10, 10, "abcde", 0, 10); + test(*r->s4, 10, 10, "abcde", 1, 10); + test(*r->s4, 10, 10, "abcde", 2, 10); + test(*r->s4, 10, 10, "abcde", 4, 10); + test(*r->s4, 10, 10, "abcde", 5, 10); + test(*r->s4, 10, 10, "abcdefghij", 0, 10); + test(*r->s4, 10, 10, "abcdefghij", 1, 10); + test(*r->s4, 10, 10, "abcdefghij", 5, 10); + test(*r->s4, 10, 10, "abcdefghij", 9, 10); + test(*r->s4, 10, 10, "abcdefghij", 10, 10); + test(*r->s4, 10, 10, "abcdefghijklmnopqrst", 0, 10); + test(*r->s4, 10, 10, "abcdefghijklmnopqrst", 1, 10); + test(*r->s4, 10, 10, "abcdefghijklmnopqrst", 10, 10); + test(*r->s4, 10, 10, "abcdefghijklmnopqrst", 19, 10); + test(*r->s4, 10, 10, "abcdefghijklmnopqrst", 20, 10); + test(*r->s4, 10, 11, "", 0, 10); + test(*r->s4, 10, 11, "abcde", 0, 10); + test(*r->s4, 10, 11, "abcde", 1, 10); + test(*r->s4, 10, 11, "abcde", 2, 10); + test(*r->s4, 10, 11, "abcde", 4, 10); + test(*r->s4, 10, 11, "abcde", 5, 10); + test(*r->s4, 10, 11, "abcdefghij", 0, 10); + test(*r->s4, 10, 11, "abcdefghij", 1, 10); + test(*r->s4, 10, 11, "abcdefghij", 5, 10); + test(*r->s4, 10, 11, "abcdefghij", 9, 10); + test(*r->s4, 10, 11, "abcdefghij", 10, 10); + test(*r->s4, 10, 11, "abcdefghijklmnopqrst", 0, 10); + test(*r->s4, 10, 11, "abcdefghijklmnopqrst", 1, 10); + test(*r->s4, 10, 11, "abcdefghijklmnopqrst", 10, 10); + test(*r->s4, 10, 11, "abcdefghijklmnopqrst", 19, 10); + test(*r->s4, 10, 11, "abcdefghijklmnopqrst", 20, 10); + test(*r->s4, 19, 0, "", 0, 0); + test(*r->s4, 19, 0, "abcde", 0, 0); + test(*r->s4, 19, 0, "abcde", 1, -1); + test(*r->s4, 19, 0, "abcde", 2, -2); + test(*r->s4, 19, 0, "abcde", 4, -4); + test(*r->s4, 19, 0, "abcde", 5, -5); + test(*r->s4, 19, 0, "abcdefghij", 0, 0); + test(*r->s4, 19, 0, "abcdefghij", 1, -1); + test(*r->s4, 19, 0, "abcdefghij", 5, -5); + test(*r->s4, 19, 0, "abcdefghij", 9, -9); + test(*r->s4, 19, 0, "abcdefghij", 10, -10); + test(*r->s4, 19, 0, "abcdefghijklmnopqrst", 0, 0); +} + +template +void +test11(pmem::obj::pool &pop) +{ + auto r = pop.root(); + + test(*r->s4, 19, 0, "abcdefghijklmnopqrst", 1, -1); + test(*r->s4, 19, 0, "abcdefghijklmnopqrst", 10, -10); + test(*r->s4, 19, 0, "abcdefghijklmnopqrst", 19, -19); + test(*r->s4, 19, 0, "abcdefghijklmnopqrst", 20, -20); + test(*r->s4, 19, 1, "", 0, 1); + test(*r->s4, 19, 1, "abcde", 0, 1); + test(*r->s4, 19, 1, "abcde", 1, 19); + test(*r->s4, 19, 1, "abcde", 2, 19); + test(*r->s4, 19, 1, "abcde", 4, 19); + test(*r->s4, 19, 1, "abcde", 5, 19); + test(*r->s4, 19, 1, "abcdefghij", 0, 1); + test(*r->s4, 19, 1, "abcdefghij", 1, 19); + test(*r->s4, 19, 1, "abcdefghij", 5, 19); + test(*r->s4, 19, 1, "abcdefghij", 9, 19); + test(*r->s4, 19, 1, "abcdefghij", 10, 19); + test(*r->s4, 19, 1, "abcdefghijklmnopqrst", 0, 1); + test(*r->s4, 19, 1, "abcdefghijklmnopqrst", 1, 19); + test(*r->s4, 19, 1, "abcdefghijklmnopqrst", 10, 19); + test(*r->s4, 19, 1, "abcdefghijklmnopqrst", 19, 19); + test(*r->s4, 19, 1, "abcdefghijklmnopqrst", 20, 19); + test(*r->s4, 19, 2, "", 0, 1); + test(*r->s4, 19, 2, "abcde", 0, 1); + test(*r->s4, 19, 2, "abcde", 1, 19); + test(*r->s4, 19, 2, "abcde", 2, 19); + test(*r->s4, 19, 2, "abcde", 4, 19); + test(*r->s4, 19, 2, "abcde", 5, 19); + test(*r->s4, 19, 2, "abcdefghij", 0, 1); + test(*r->s4, 19, 2, "abcdefghij", 1, 19); + test(*r->s4, 19, 2, "abcdefghij", 5, 19); + test(*r->s4, 19, 2, "abcdefghij", 9, 19); + test(*r->s4, 19, 2, "abcdefghij", 10, 19); + test(*r->s4, 19, 2, "abcdefghijklmnopqrst", 0, 1); + test(*r->s4, 19, 2, "abcdefghijklmnopqrst", 1, 19); + test(*r->s4, 19, 2, "abcdefghijklmnopqrst", 10, 19); + test(*r->s4, 19, 2, "abcdefghijklmnopqrst", 19, 19); + test(*r->s4, 19, 2, "abcdefghijklmnopqrst", 20, 19); + test(*r->s4, 20, 0, "", 0, 0); + test(*r->s4, 20, 0, "abcde", 0, 0); + test(*r->s4, 20, 0, "abcde", 1, -1); + test(*r->s4, 20, 0, "abcde", 2, -2); + test(*r->s4, 20, 0, "abcde", 4, -4); + test(*r->s4, 20, 0, "abcde", 5, -5); + test(*r->s4, 20, 0, "abcdefghij", 0, 0); + test(*r->s4, 20, 0, "abcdefghij", 1, -1); + test(*r->s4, 20, 0, "abcdefghij", 5, -5); + test(*r->s4, 20, 0, "abcdefghij", 9, -9); + test(*r->s4, 20, 0, "abcdefghij", 10, -10); + test(*r->s4, 20, 0, "abcdefghijklmnopqrst", 0, 0); + test(*r->s4, 20, 0, "abcdefghijklmnopqrst", 1, -1); + test(*r->s4, 20, 0, "abcdefghijklmnopqrst", 10, -10); + test(*r->s4, 20, 0, "abcdefghijklmnopqrst", 19, -19); + test(*r->s4, 20, 0, "abcdefghijklmnopqrst", 20, -20); + test(*r->s4, 20, 1, "", 0, 0); + test(*r->s4, 20, 1, "abcde", 0, 0); + test(*r->s4, 20, 1, "abcde", 1, -1); + test(*r->s4, 20, 1, "abcde", 2, -2); + test(*r->s4, 20, 1, "abcde", 4, -4); + test(*r->s4, 20, 1, "abcde", 5, -5); + test(*r->s4, 20, 1, "abcdefghij", 0, 0); + test(*r->s4, 20, 1, "abcdefghij", 1, -1); + test(*r->s4, 20, 1, "abcdefghij", 5, -5); + test(*r->s4, 20, 1, "abcdefghij", 9, -9); + test(*r->s4, 20, 1, "abcdefghij", 10, -10); + test(*r->s4, 20, 1, "abcdefghijklmnopqrst", 0, 0); + test(*r->s4, 20, 1, "abcdefghijklmnopqrst", 1, -1); + test(*r->s4, 20, 1, "abcdefghijklmnopqrst", 10, -10); + test(*r->s4, 20, 1, "abcdefghijklmnopqrst", 19, -19); + test(*r->s4, 20, 1, "abcdefghijklmnopqrst", 20, -20); + test(*r->s4, 21, 0, "", 0, 0); + test(*r->s4, 21, 0, "abcde", 0, 0); + test(*r->s4, 21, 0, "abcde", 1, 0); + test(*r->s4, 21, 0, "abcde", 2, 0); + test(*r->s4, 21, 0, "abcde", 4, 0); + test(*r->s4, 21, 0, "abcde", 5, 0); + test(*r->s4, 21, 0, "abcdefghij", 0, 0); + test(*r->s4, 21, 0, "abcdefghij", 1, 0); + test(*r->s4, 21, 0, "abcdefghij", 5, 0); + test(*r->s4, 21, 0, "abcdefghij", 9, 0); + test(*r->s4, 21, 0, "abcdefghij", 10, 0); + test(*r->s4, 21, 0, "abcdefghijklmnopqrst", 0, 0); + test(*r->s4, 21, 0, "abcdefghijklmnopqrst", 1, 0); + test(*r->s4, 21, 0, "abcdefghijklmnopqrst", 10, 0); + test(*r->s4, 21, 0, "abcdefghijklmnopqrst", 19, 0); + test(*r->s4, 21, 0, "abcdefghijklmnopqrst", 20, 0); +} + +void +run(pmem::obj::pool &pop) +{ + auto r = pop.root(); + + try { + nvobj::transaction::run(pop, [&] { + r->s1 = nvobj::make_persistent(""); + r->s2 = nvobj::make_persistent( + "abcde"); + r->s3 = nvobj::make_persistent( + "abcdefghij"); + r->s4 = nvobj::make_persistent( + "abcdefghijklmnopqrst"); + }); + + using S = pmem_exp::string; + test0(pop); + test1(pop); + test2(pop); + test3(pop); + test4(pop); + test5(pop); + test6(pop); + test7(pop); + test8(pop); + test9(pop); + test10(pop); + test11(pop); + + nvobj::transaction::run(pop, [&] { + nvobj::delete_persistent(r->s1); + nvobj::delete_persistent(r->s2); + nvobj::delete_persistent(r->s3); + nvobj::delete_persistent(r->s4); + }); + } catch (std::exception &e) { + UT_FATALexc(e); + } +} + +int +main(int argc, char *argv[]) +{ + START(); + + if (argc != 2) + UT_FATAL("usage: %s file-name", argv[0]); + + const char *path = argv[1]; + + pmem::obj::pool pop; + + try { + pop = pmem::obj::pool::create(path, "basic_string", + PMEMOBJ_MIN_POOL, + S_IWUSR | S_IRUSR); + } catch (...) { + UT_FATAL("!pmemobj_create: %s", path); + } + + run(pop); + + pop.close(); + + return 0; +} diff --git a/tests/external/libcxx/basic_string/string.ops/string_compare/size_size_string.pass.cpp b/tests/external/libcxx/basic_string/string.ops/string_compare/size_size_string.pass.cpp new file mode 100644 index 0000000..6f16b35 --- /dev/null +++ b/tests/external/libcxx/basic_string/string.ops/string_compare/size_size_string.pass.cpp @@ -0,0 +1,430 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// Copyright 2019, Intel Corporation +// +// Modified to test pmem::obj containers +// + +#include "unittest.hpp" + +#include +#include +#include +#include +#include + +namespace pmem_exp = pmem::obj::experimental; +namespace nvobj = pmem::obj; + +struct root { + nvobj::persistent_ptr s1, s2, s3, s4; +}; + +int +sign(int x) +{ + if (x == 0) + return 0; + if (x < 0) + return -1; + return 1; +} + +template +void +test(const S &s, typename S::size_type pos1, typename S::size_type n1, + const S &str, int x) +{ + if (pos1 <= s.size()) + UT_ASSERT(sign(s.compare(pos1, n1, str)) == sign(x)); + else { + try { + s.compare(pos1, n1, str); + UT_ASSERT(false); + } catch (std::out_of_range &) { + UT_ASSERT(pos1 > s.size()); + } + } +} + +template +void +test0(pmem::obj::persistent_ptr &r) +{ + test(*r->s1, 0, 0, *r->s1, 0); + test(*r->s1, 0, 0, *r->s2, -5); + test(*r->s1, 0, 0, *r->s3, -10); + test(*r->s1, 0, 0, *r->s4, -20); + test(*r->s1, 0, 1, *r->s1, 0); + test(*r->s1, 0, 1, *r->s2, -5); + test(*r->s1, 0, 1, *r->s3, -10); + test(*r->s1, 0, 1, *r->s4, -20); + test(*r->s1, 1, 0, *r->s1, 0); + test(*r->s1, 1, 0, *r->s2, 0); + test(*r->s1, 1, 0, *r->s3, 0); + test(*r->s1, 1, 0, *r->s4, 0); + test(*r->s2, 0, 0, *r->s1, 0); + test(*r->s2, 0, 0, *r->s2, -5); + test(*r->s2, 0, 0, *r->s3, -10); + test(*r->s2, 0, 0, *r->s4, -20); + test(*r->s2, 0, 1, *r->s1, 1); + test(*r->s2, 0, 1, *r->s2, -4); + test(*r->s2, 0, 1, *r->s3, -9); + test(*r->s2, 0, 1, *r->s4, -19); + test(*r->s2, 0, 2, *r->s1, 2); + test(*r->s2, 0, 2, *r->s2, -3); + test(*r->s2, 0, 2, *r->s3, -8); + test(*r->s2, 0, 2, *r->s4, -18); + test(*r->s2, 0, 4, *r->s1, 4); + test(*r->s2, 0, 4, *r->s2, -1); + test(*r->s2, 0, 4, *r->s3, -6); + test(*r->s2, 0, 4, *r->s4, -16); + test(*r->s2, 0, 5, *r->s1, 5); + test(*r->s2, 0, 5, *r->s2, 0); + test(*r->s2, 0, 5, *r->s3, -5); + test(*r->s2, 0, 5, *r->s4, -15); + test(*r->s2, 0, 6, *r->s1, 5); + test(*r->s2, 0, 6, *r->s2, 0); + test(*r->s2, 0, 6, *r->s3, -5); + test(*r->s2, 0, 6, *r->s4, -15); + test(*r->s2, 1, 0, *r->s1, 0); + test(*r->s2, 1, 0, *r->s2, -5); + test(*r->s2, 1, 0, *r->s3, -10); + test(*r->s2, 1, 0, *r->s4, -20); + test(*r->s2, 1, 1, *r->s1, 1); + test(*r->s2, 1, 1, *r->s2, 1); + test(*r->s2, 1, 1, *r->s3, 1); + test(*r->s2, 1, 1, *r->s4, 1); + test(*r->s2, 1, 2, *r->s1, 2); + test(*r->s2, 1, 2, *r->s2, 1); + test(*r->s2, 1, 2, *r->s3, 1); + test(*r->s2, 1, 2, *r->s4, 1); + test(*r->s2, 1, 3, *r->s1, 3); + test(*r->s2, 1, 3, *r->s2, 1); + test(*r->s2, 1, 3, *r->s3, 1); + test(*r->s2, 1, 3, *r->s4, 1); + test(*r->s2, 1, 4, *r->s1, 4); + test(*r->s2, 1, 4, *r->s2, 1); + test(*r->s2, 1, 4, *r->s3, 1); + test(*r->s2, 1, 4, *r->s4, 1); + test(*r->s2, 1, 5, *r->s1, 4); + test(*r->s2, 1, 5, *r->s2, 1); + test(*r->s2, 1, 5, *r->s3, 1); + test(*r->s2, 1, 5, *r->s4, 1); + test(*r->s2, 2, 0, *r->s1, 0); + test(*r->s2, 2, 0, *r->s2, -5); + test(*r->s2, 2, 0, *r->s3, -10); + test(*r->s2, 2, 0, *r->s4, -20); + test(*r->s2, 2, 1, *r->s1, 1); + test(*r->s2, 2, 1, *r->s2, 2); + test(*r->s2, 2, 1, *r->s3, 2); + test(*r->s2, 2, 1, *r->s4, 2); + test(*r->s2, 2, 2, *r->s1, 2); + test(*r->s2, 2, 2, *r->s2, 2); + test(*r->s2, 2, 2, *r->s3, 2); + test(*r->s2, 2, 2, *r->s4, 2); + test(*r->s2, 2, 3, *r->s1, 3); + test(*r->s2, 2, 3, *r->s2, 2); + test(*r->s2, 2, 3, *r->s3, 2); + test(*r->s2, 2, 3, *r->s4, 2); + test(*r->s2, 2, 4, *r->s1, 3); + test(*r->s2, 2, 4, *r->s2, 2); + test(*r->s2, 2, 4, *r->s3, 2); + test(*r->s2, 2, 4, *r->s4, 2); + test(*r->s2, 4, 0, *r->s1, 0); + test(*r->s2, 4, 0, *r->s2, -5); + test(*r->s2, 4, 0, *r->s3, -10); + test(*r->s2, 4, 0, *r->s4, -20); + test(*r->s2, 4, 1, *r->s1, 1); + test(*r->s2, 4, 1, *r->s2, 4); + test(*r->s2, 4, 1, *r->s3, 4); + test(*r->s2, 4, 1, *r->s4, 4); + test(*r->s2, 4, 2, *r->s1, 1); + test(*r->s2, 4, 2, *r->s2, 4); + test(*r->s2, 4, 2, *r->s3, 4); + test(*r->s2, 4, 2, *r->s4, 4); + test(*r->s2, 5, 0, *r->s1, 0); + test(*r->s2, 5, 0, *r->s2, -5); + test(*r->s2, 5, 0, *r->s3, -10); + test(*r->s2, 5, 0, *r->s4, -20); + test(*r->s2, 5, 1, *r->s1, 0); + test(*r->s2, 5, 1, *r->s2, -5); + test(*r->s2, 5, 1, *r->s3, -10); + test(*r->s2, 5, 1, *r->s4, -20); +} + +template +void +test1(pmem::obj::persistent_ptr &r) +{ + test(*r->s2, 6, 0, *r->s1, 0); + test(*r->s2, 6, 0, *r->s2, 0); + test(*r->s2, 6, 0, *r->s3, 0); + test(*r->s2, 6, 0, *r->s4, 0); + test(*r->s3, 0, 0, *r->s1, 0); + test(*r->s3, 0, 0, *r->s2, -5); + test(*r->s3, 0, 0, *r->s3, -10); + test(*r->s3, 0, 0, *r->s4, -20); + test(*r->s3, 0, 1, *r->s1, 1); + test(*r->s3, 0, 1, *r->s2, -4); + test(*r->s3, 0, 1, *r->s3, -9); + test(*r->s3, 0, 1, *r->s4, -19); + test(*r->s3, 0, 5, *r->s1, 5); + test(*r->s3, 0, 5, *r->s2, 0); + test(*r->s3, 0, 5, *r->s3, -5); + test(*r->s3, 0, 5, *r->s4, -15); + test(*r->s3, 0, 9, *r->s1, 9); + test(*r->s3, 0, 9, *r->s2, 4); + test(*r->s3, 0, 9, *r->s3, -1); + test(*r->s3, 0, 9, *r->s4, -11); + test(*r->s3, 0, 10, *r->s1, 10); + test(*r->s3, 0, 10, *r->s2, 5); + test(*r->s3, 0, 10, *r->s3, 0); + test(*r->s3, 0, 10, *r->s4, -10); + test(*r->s3, 0, 11, *r->s1, 10); + test(*r->s3, 0, 11, *r->s2, 5); + test(*r->s3, 0, 11, *r->s3, 0); + test(*r->s3, 0, 11, *r->s4, -10); + test(*r->s3, 1, 0, *r->s1, 0); + test(*r->s3, 1, 0, *r->s2, -5); + test(*r->s3, 1, 0, *r->s3, -10); + test(*r->s3, 1, 0, *r->s4, -20); + test(*r->s3, 1, 1, *r->s1, 1); + test(*r->s3, 1, 1, *r->s2, 1); + test(*r->s3, 1, 1, *r->s3, 1); + test(*r->s3, 1, 1, *r->s4, 1); + test(*r->s3, 1, 4, *r->s1, 4); + test(*r->s3, 1, 4, *r->s2, 1); + test(*r->s3, 1, 4, *r->s3, 1); + test(*r->s3, 1, 4, *r->s4, 1); + test(*r->s3, 1, 8, *r->s1, 8); + test(*r->s3, 1, 8, *r->s2, 1); + test(*r->s3, 1, 8, *r->s3, 1); + test(*r->s3, 1, 8, *r->s4, 1); + test(*r->s3, 1, 9, *r->s1, 9); + test(*r->s3, 1, 9, *r->s2, 1); + test(*r->s3, 1, 9, *r->s3, 1); + test(*r->s3, 1, 9, *r->s4, 1); + test(*r->s3, 1, 10, *r->s1, 9); + test(*r->s3, 1, 10, *r->s2, 1); + test(*r->s3, 1, 10, *r->s3, 1); + test(*r->s3, 1, 10, *r->s4, 1); + test(*r->s3, 5, 0, *r->s1, 0); + test(*r->s3, 5, 0, *r->s2, -5); + test(*r->s3, 5, 0, *r->s3, -10); + test(*r->s3, 5, 0, *r->s4, -20); + test(*r->s3, 5, 1, *r->s1, 1); + test(*r->s3, 5, 1, *r->s2, 5); + test(*r->s3, 5, 1, *r->s3, 5); + test(*r->s3, 5, 1, *r->s4, 5); + test(*r->s3, 5, 2, *r->s1, 2); + test(*r->s3, 5, 2, *r->s2, 5); + test(*r->s3, 5, 2, *r->s3, 5); + test(*r->s3, 5, 2, *r->s4, 5); + test(*r->s3, 5, 4, *r->s1, 4); + test(*r->s3, 5, 4, *r->s2, 5); + test(*r->s3, 5, 4, *r->s3, 5); + test(*r->s3, 5, 4, *r->s4, 5); + test(*r->s3, 5, 5, *r->s1, 5); + test(*r->s3, 5, 5, *r->s2, 5); + test(*r->s3, 5, 5, *r->s3, 5); + test(*r->s3, 5, 5, *r->s4, 5); + test(*r->s3, 5, 6, *r->s1, 5); + test(*r->s3, 5, 6, *r->s2, 5); + test(*r->s3, 5, 6, *r->s3, 5); + test(*r->s3, 5, 6, *r->s4, 5); + test(*r->s3, 9, 0, *r->s1, 0); + test(*r->s3, 9, 0, *r->s2, -5); + test(*r->s3, 9, 0, *r->s3, -10); + test(*r->s3, 9, 0, *r->s4, -20); + test(*r->s3, 9, 1, *r->s1, 1); + test(*r->s3, 9, 1, *r->s2, 9); + test(*r->s3, 9, 1, *r->s3, 9); + test(*r->s3, 9, 1, *r->s4, 9); + test(*r->s3, 9, 2, *r->s1, 1); + test(*r->s3, 9, 2, *r->s2, 9); + test(*r->s3, 9, 2, *r->s3, 9); + test(*r->s3, 9, 2, *r->s4, 9); + test(*r->s3, 10, 0, *r->s1, 0); + test(*r->s3, 10, 0, *r->s2, -5); + test(*r->s3, 10, 0, *r->s3, -10); + test(*r->s3, 10, 0, *r->s4, -20); + test(*r->s3, 10, 1, *r->s1, 0); + test(*r->s3, 10, 1, *r->s2, -5); + test(*r->s3, 10, 1, *r->s3, -10); + test(*r->s3, 10, 1, *r->s4, -20); + test(*r->s3, 11, 0, *r->s1, 0); + test(*r->s3, 11, 0, *r->s2, 0); + test(*r->s3, 11, 0, *r->s3, 0); + test(*r->s3, 11, 0, *r->s4, 0); +} + +template +void +test2(pmem::obj::persistent_ptr &r) +{ + test(*r->s4, 0, 0, *r->s1, 0); + test(*r->s4, 0, 0, *r->s2, -5); + test(*r->s4, 0, 0, *r->s3, -10); + test(*r->s4, 0, 0, *r->s4, -20); + test(*r->s4, 0, 1, *r->s1, 1); + test(*r->s4, 0, 1, *r->s2, -4); + test(*r->s4, 0, 1, *r->s3, -9); + test(*r->s4, 0, 1, *r->s4, -19); + test(*r->s4, 0, 10, *r->s1, 10); + test(*r->s4, 0, 10, *r->s2, 5); + test(*r->s4, 0, 10, *r->s3, 0); + test(*r->s4, 0, 10, *r->s4, -10); + test(*r->s4, 0, 19, *r->s1, 19); + test(*r->s4, 0, 19, *r->s2, 14); + test(*r->s4, 0, 19, *r->s3, 9); + test(*r->s4, 0, 19, *r->s4, -1); + test(*r->s4, 0, 20, *r->s1, 20); + test(*r->s4, 0, 20, *r->s2, 15); + test(*r->s4, 0, 20, *r->s3, 10); + test(*r->s4, 0, 20, *r->s4, 0); + test(*r->s4, 0, 21, *r->s1, 20); + test(*r->s4, 0, 21, *r->s2, 15); + test(*r->s4, 0, 21, *r->s3, 10); + test(*r->s4, 0, 21, *r->s4, 0); + test(*r->s4, 1, 0, *r->s1, 0); + test(*r->s4, 1, 0, *r->s2, -5); + test(*r->s4, 1, 0, *r->s3, -10); + test(*r->s4, 1, 0, *r->s4, -20); + test(*r->s4, 1, 1, *r->s1, 1); + test(*r->s4, 1, 1, *r->s2, 1); + test(*r->s4, 1, 1, *r->s3, 1); + test(*r->s4, 1, 1, *r->s4, 1); + test(*r->s4, 1, 9, *r->s1, 9); + test(*r->s4, 1, 9, *r->s2, 1); + test(*r->s4, 1, 9, *r->s3, 1); + test(*r->s4, 1, 9, *r->s4, 1); + test(*r->s4, 1, 18, *r->s1, 18); + test(*r->s4, 1, 18, *r->s2, 1); + test(*r->s4, 1, 18, *r->s3, 1); + test(*r->s4, 1, 18, *r->s4, 1); + test(*r->s4, 1, 19, *r->s1, 19); + test(*r->s4, 1, 19, *r->s2, 1); + test(*r->s4, 1, 19, *r->s3, 1); + test(*r->s4, 1, 19, *r->s4, 1); + test(*r->s4, 1, 20, *r->s1, 19); + test(*r->s4, 1, 20, *r->s2, 1); + test(*r->s4, 1, 20, *r->s3, 1); + test(*r->s4, 1, 20, *r->s4, 1); + test(*r->s4, 10, 0, *r->s1, 0); + test(*r->s4, 10, 0, *r->s2, -5); + test(*r->s4, 10, 0, *r->s3, -10); + test(*r->s4, 10, 0, *r->s4, -20); + test(*r->s4, 10, 1, *r->s1, 1); + test(*r->s4, 10, 1, *r->s2, 10); + test(*r->s4, 10, 1, *r->s3, 10); + test(*r->s4, 10, 1, *r->s4, 10); + test(*r->s4, 10, 5, *r->s1, 5); + test(*r->s4, 10, 5, *r->s2, 10); + test(*r->s4, 10, 5, *r->s3, 10); + test(*r->s4, 10, 5, *r->s4, 10); + test(*r->s4, 10, 9, *r->s1, 9); + test(*r->s4, 10, 9, *r->s2, 10); + test(*r->s4, 10, 9, *r->s3, 10); + test(*r->s4, 10, 9, *r->s4, 10); + test(*r->s4, 10, 10, *r->s1, 10); + test(*r->s4, 10, 10, *r->s2, 10); + test(*r->s4, 10, 10, *r->s3, 10); + test(*r->s4, 10, 10, *r->s4, 10); + test(*r->s4, 10, 11, *r->s1, 10); + test(*r->s4, 10, 11, *r->s2, 10); + test(*r->s4, 10, 11, *r->s3, 10); + test(*r->s4, 10, 11, *r->s4, 10); + test(*r->s4, 19, 0, *r->s1, 0); + test(*r->s4, 19, 0, *r->s2, -5); + test(*r->s4, 19, 0, *r->s3, -10); + test(*r->s4, 19, 0, *r->s4, -20); + test(*r->s4, 19, 1, *r->s1, 1); + test(*r->s4, 19, 1, *r->s2, 19); + test(*r->s4, 19, 1, *r->s3, 19); + test(*r->s4, 19, 1, *r->s4, 19); + test(*r->s4, 19, 2, *r->s1, 1); + test(*r->s4, 19, 2, *r->s2, 19); + test(*r->s4, 19, 2, *r->s3, 19); + test(*r->s4, 19, 2, *r->s4, 19); + test(*r->s4, 20, 0, *r->s1, 0); + test(*r->s4, 20, 0, *r->s2, -5); + test(*r->s4, 20, 0, *r->s3, -10); + test(*r->s4, 20, 0, *r->s4, -20); + test(*r->s4, 20, 1, *r->s1, 0); + test(*r->s4, 20, 1, *r->s2, -5); + test(*r->s4, 20, 1, *r->s3, -10); + test(*r->s4, 20, 1, *r->s4, -20); + test(*r->s4, 21, 0, *r->s1, 0); + test(*r->s4, 21, 0, *r->s2, 0); + test(*r->s4, 21, 0, *r->s3, 0); + test(*r->s4, 21, 0, *r->s4, 0); +} + +void +run(pmem::obj::pool &pop) +{ + auto r = pop.root(); + + try { + nvobj::transaction::run(pop, [&] { + r->s1 = nvobj::make_persistent(""); + r->s2 = nvobj::make_persistent( + "abcde"); + r->s3 = nvobj::make_persistent( + "abcdefghij"); + r->s4 = nvobj::make_persistent( + "abcdefghijklmnopqrst"); + }); + + { + typedef pmem_exp::string S; + test0(r); + test1(r); + test2(r); + } + + nvobj::transaction::run(pop, [&] { + nvobj::delete_persistent(r->s1); + nvobj::delete_persistent(r->s2); + nvobj::delete_persistent(r->s3); + nvobj::delete_persistent(r->s4); + }); + } catch (std::exception &e) { + UT_FATALexc(e); + } +} + +int +main(int argc, char *argv[]) +{ + START(); + + if (argc != 2) + UT_FATAL("usage: %s file-name", argv[0]); + + const char *path = argv[1]; + + pmem::obj::pool pop; + + try { + pop = pmem::obj::pool::create(path, "basic_string", + PMEMOBJ_MIN_POOL, + S_IWUSR | S_IRUSR); + } catch (...) { + UT_FATAL("!pmemobj_create: %s", path); + } + + run(pop); + + pop.close(); + + return 0; +} diff --git a/tests/external/libcxx/basic_string/string.ops/string_compare/size_size_string_size_size.pass.cpp b/tests/external/libcxx/basic_string/string.ops/string_compare/size_size_string_size_size.pass.cpp new file mode 100644 index 0000000..2dfa48d --- /dev/null +++ b/tests/external/libcxx/basic_string/string.ops/string_compare/size_size_string_size_size.pass.cpp @@ -0,0 +1,6001 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// Copyright 2019, Intel Corporation +// +// Modified to test pmem::obj containers +// + +#include "unittest.hpp" + +#include +#include +#include +#include +#include + +namespace pmem_exp = pmem::obj::experimental; +namespace nvobj = pmem::obj; + +struct root { + nvobj::persistent_ptr s1, s2, s3, s4; +}; + +int +sign(int x) +{ + if (x == 0) + return 0; + if (x < 0) + return -1; + return 1; +} + +template +void +test(const S &s, typename S::size_type pos1, typename S::size_type n1, + const S &str, typename S::size_type pos2, typename S::size_type n2, int x) +{ + if (pos1 <= s.size() && pos2 <= str.size()) + UT_ASSERT(sign(s.compare(pos1, n1, str, pos2, n2)) == sign(x)); + else { + try { + s.compare(pos1, n1, str, pos2, n2); + UT_ASSERT(0); + } catch (const std::out_of_range &) { + UT_ASSERT(pos1 > s.size() || pos2 > str.size()); + } + } +} + +template +void +test_npos(const S &s, typename S::size_type pos1, typename S::size_type n1, + const S &str, typename S::size_type pos2, int x) +{ + if (pos1 <= s.size() && pos2 <= str.size()) + UT_ASSERT(sign(s.compare(pos1, n1, str, pos2)) == sign(x)); + else { + try { + s.compare(pos1, n1, str, pos2); + UT_ASSERT(0); + } catch (const std::out_of_range &) { + UT_ASSERT(pos1 > s.size() || pos2 > str.size()); + } + } +} + +template +void +test0(pmem::obj::persistent_ptr &r) +{ + test(*r->s1, 0, 0, *r->s1, 0, 0, 0); + test(*r->s1, 0, 0, *r->s1, 0, 1, 0); + test(*r->s1, 0, 0, *r->s1, 1, 0, 0); + test(*r->s1, 0, 0, *r->s2, 0, 0, 0); + test(*r->s1, 0, 0, *r->s2, 0, 1, -1); + test(*r->s1, 0, 0, *r->s2, 0, 2, -2); + test(*r->s1, 0, 0, *r->s2, 0, 4, -4); + test(*r->s1, 0, 0, *r->s2, 0, 5, -5); + test(*r->s1, 0, 0, *r->s2, 0, 6, -5); + test(*r->s1, 0, 0, *r->s2, 1, 0, 0); + test(*r->s1, 0, 0, *r->s2, 1, 1, -1); + test(*r->s1, 0, 0, *r->s2, 1, 2, -2); + test(*r->s1, 0, 0, *r->s2, 1, 3, -3); + test(*r->s1, 0, 0, *r->s2, 1, 4, -4); + test(*r->s1, 0, 0, *r->s2, 1, 5, -4); + test(*r->s1, 0, 0, *r->s2, 2, 0, 0); + test(*r->s1, 0, 0, *r->s2, 2, 1, -1); + test(*r->s1, 0, 0, *r->s2, 2, 2, -2); + test(*r->s1, 0, 0, *r->s2, 2, 3, -3); + test(*r->s1, 0, 0, *r->s2, 2, 4, -3); + test(*r->s1, 0, 0, *r->s2, 4, 0, 0); + test(*r->s1, 0, 0, *r->s2, 4, 1, -1); + test(*r->s1, 0, 0, *r->s2, 4, 2, -1); + test(*r->s1, 0, 0, *r->s2, 5, 0, 0); + test(*r->s1, 0, 0, *r->s2, 5, 1, 0); + test(*r->s1, 0, 0, *r->s2, 6, 0, 0); + test(*r->s1, 0, 0, *r->s3, 0, 0, 0); + test(*r->s1, 0, 0, *r->s3, 0, 1, -1); + test(*r->s1, 0, 0, *r->s3, 0, 5, -5); + test(*r->s1, 0, 0, *r->s3, 0, 9, -9); + test(*r->s1, 0, 0, *r->s3, 0, 10, -10); + test(*r->s1, 0, 0, *r->s3, 0, 11, -10); + test(*r->s1, 0, 0, *r->s3, 1, 0, 0); + test(*r->s1, 0, 0, *r->s3, 1, 1, -1); + test(*r->s1, 0, 0, *r->s3, 1, 4, -4); + test(*r->s1, 0, 0, *r->s3, 1, 8, -8); + test(*r->s1, 0, 0, *r->s3, 1, 9, -9); + test(*r->s1, 0, 0, *r->s3, 1, 10, -9); + test(*r->s1, 0, 0, *r->s3, 5, 0, 0); + test(*r->s1, 0, 0, *r->s3, 5, 1, -1); + test(*r->s1, 0, 0, *r->s3, 5, 2, -2); + test(*r->s1, 0, 0, *r->s3, 5, 4, -4); + test(*r->s1, 0, 0, *r->s3, 5, 5, -5); + test(*r->s1, 0, 0, *r->s3, 5, 6, -5); + test(*r->s1, 0, 0, *r->s3, 9, 0, 0); + test(*r->s1, 0, 0, *r->s3, 9, 1, -1); + test(*r->s1, 0, 0, *r->s3, 9, 2, -1); + test(*r->s1, 0, 0, *r->s3, 10, 0, 0); + test(*r->s1, 0, 0, *r->s3, 10, 1, 0); + test(*r->s1, 0, 0, *r->s3, 11, 0, 0); + test(*r->s1, 0, 0, *r->s4, 0, 0, 0); + test(*r->s1, 0, 0, *r->s4, 0, 1, -1); + test(*r->s1, 0, 0, *r->s4, 0, 10, -10); + test(*r->s1, 0, 0, *r->s4, 0, 19, -19); + test(*r->s1, 0, 0, *r->s4, 0, 20, -20); + test(*r->s1, 0, 0, *r->s4, 0, 21, -20); + test(*r->s1, 0, 0, *r->s4, 1, 0, 0); + test(*r->s1, 0, 0, *r->s4, 1, 1, -1); + test(*r->s1, 0, 0, *r->s4, 1, 9, -9); + test(*r->s1, 0, 0, *r->s4, 1, 18, -18); + test(*r->s1, 0, 0, *r->s4, 1, 19, -19); + test(*r->s1, 0, 0, *r->s4, 1, 20, -19); + test(*r->s1, 0, 0, *r->s4, 10, 0, 0); + test(*r->s1, 0, 0, *r->s4, 10, 1, -1); + test(*r->s1, 0, 0, *r->s4, 10, 5, -5); + test(*r->s1, 0, 0, *r->s4, 10, 9, -9); + test(*r->s1, 0, 0, *r->s4, 10, 10, -10); + test(*r->s1, 0, 0, *r->s4, 10, 11, -10); + test(*r->s1, 0, 0, *r->s4, 19, 0, 0); + test(*r->s1, 0, 0, *r->s4, 19, 1, -1); + test(*r->s1, 0, 0, *r->s4, 19, 2, -1); + test(*r->s1, 0, 0, *r->s4, 20, 0, 0); + test(*r->s1, 0, 0, *r->s4, 20, 1, 0); + test(*r->s1, 0, 0, *r->s4, 21, 0, 0); + test(*r->s1, 0, 1, *r->s1, 0, 0, 0); + test(*r->s1, 0, 1, *r->s1, 0, 1, 0); + test(*r->s1, 0, 1, *r->s1, 1, 0, 0); + test(*r->s1, 0, 1, *r->s2, 0, 0, 0); + test(*r->s1, 0, 1, *r->s2, 0, 1, -1); + test(*r->s1, 0, 1, *r->s2, 0, 2, -2); + test(*r->s1, 0, 1, *r->s2, 0, 4, -4); + test(*r->s1, 0, 1, *r->s2, 0, 5, -5); + test(*r->s1, 0, 1, *r->s2, 0, 6, -5); + test(*r->s1, 0, 1, *r->s2, 1, 0, 0); + test(*r->s1, 0, 1, *r->s2, 1, 1, -1); + test(*r->s1, 0, 1, *r->s2, 1, 2, -2); + test(*r->s1, 0, 1, *r->s2, 1, 3, -3); + test(*r->s1, 0, 1, *r->s2, 1, 4, -4); + test(*r->s1, 0, 1, *r->s2, 1, 5, -4); + test(*r->s1, 0, 1, *r->s2, 2, 0, 0); + test(*r->s1, 0, 1, *r->s2, 2, 1, -1); + test(*r->s1, 0, 1, *r->s2, 2, 2, -2); + test(*r->s1, 0, 1, *r->s2, 2, 3, -3); + test(*r->s1, 0, 1, *r->s2, 2, 4, -3); + test(*r->s1, 0, 1, *r->s2, 4, 0, 0); + test(*r->s1, 0, 1, *r->s2, 4, 1, -1); + test(*r->s1, 0, 1, *r->s2, 4, 2, -1); + test(*r->s1, 0, 1, *r->s2, 5, 0, 0); + test(*r->s1, 0, 1, *r->s2, 5, 1, 0); + test(*r->s1, 0, 1, *r->s2, 6, 0, 0); +} + +template +void +test1(pmem::obj::persistent_ptr &r) +{ + test(*r->s1, 0, 1, *r->s3, 0, 0, 0); + test(*r->s1, 0, 1, *r->s3, 0, 1, -1); + test(*r->s1, 0, 1, *r->s3, 0, 5, -5); + test(*r->s1, 0, 1, *r->s3, 0, 9, -9); + test(*r->s1, 0, 1, *r->s3, 0, 10, -10); + test(*r->s1, 0, 1, *r->s3, 0, 11, -10); + test(*r->s1, 0, 1, *r->s3, 1, 0, 0); + test(*r->s1, 0, 1, *r->s3, 1, 1, -1); + test(*r->s1, 0, 1, *r->s3, 1, 4, -4); + test(*r->s1, 0, 1, *r->s3, 1, 8, -8); + test(*r->s1, 0, 1, *r->s3, 1, 9, -9); + test(*r->s1, 0, 1, *r->s3, 1, 10, -9); + test(*r->s1, 0, 1, *r->s3, 5, 0, 0); + test(*r->s1, 0, 1, *r->s3, 5, 1, -1); + test(*r->s1, 0, 1, *r->s3, 5, 2, -2); + test(*r->s1, 0, 1, *r->s3, 5, 4, -4); + test(*r->s1, 0, 1, *r->s3, 5, 5, -5); + test(*r->s1, 0, 1, *r->s3, 5, 6, -5); + test(*r->s1, 0, 1, *r->s3, 9, 0, 0); + test(*r->s1, 0, 1, *r->s3, 9, 1, -1); + test(*r->s1, 0, 1, *r->s3, 9, 2, -1); + test(*r->s1, 0, 1, *r->s3, 10, 0, 0); + test(*r->s1, 0, 1, *r->s3, 10, 1, 0); + test(*r->s1, 0, 1, *r->s3, 11, 0, 0); + test(*r->s1, 0, 1, *r->s4, 0, 0, 0); + test(*r->s1, 0, 1, *r->s4, 0, 1, -1); + test(*r->s1, 0, 1, *r->s4, 0, 10, -10); + test(*r->s1, 0, 1, *r->s4, 0, 19, -19); + test(*r->s1, 0, 1, *r->s4, 0, 20, -20); + test(*r->s1, 0, 1, *r->s4, 0, 21, -20); + test(*r->s1, 0, 1, *r->s4, 1, 0, 0); + test(*r->s1, 0, 1, *r->s4, 1, 1, -1); + test(*r->s1, 0, 1, *r->s4, 1, 9, -9); + test(*r->s1, 0, 1, *r->s4, 1, 18, -18); + test(*r->s1, 0, 1, *r->s4, 1, 19, -19); + test(*r->s1, 0, 1, *r->s4, 1, 20, -19); + test(*r->s1, 0, 1, *r->s4, 10, 0, 0); + test(*r->s1, 0, 1, *r->s4, 10, 1, -1); + test(*r->s1, 0, 1, *r->s4, 10, 5, -5); + test(*r->s1, 0, 1, *r->s4, 10, 9, -9); + test(*r->s1, 0, 1, *r->s4, 10, 10, -10); + test(*r->s1, 0, 1, *r->s4, 10, 11, -10); + test(*r->s1, 0, 1, *r->s4, 19, 0, 0); + test(*r->s1, 0, 1, *r->s4, 19, 1, -1); + test(*r->s1, 0, 1, *r->s4, 19, 2, -1); + test(*r->s1, 0, 1, *r->s4, 20, 0, 0); + test(*r->s1, 0, 1, *r->s4, 20, 1, 0); + test(*r->s1, 0, 1, *r->s4, 21, 0, 0); + test(*r->s1, 1, 0, *r->s1, 0, 0, 0); + test(*r->s1, 1, 0, *r->s1, 0, 1, 0); + test(*r->s1, 1, 0, *r->s1, 1, 0, 0); + test(*r->s1, 1, 0, *r->s2, 0, 0, 0); + test(*r->s1, 1, 0, *r->s2, 0, 1, 0); + test(*r->s1, 1, 0, *r->s2, 0, 2, 0); + test(*r->s1, 1, 0, *r->s2, 0, 4, 0); + test(*r->s1, 1, 0, *r->s2, 0, 5, 0); + test(*r->s1, 1, 0, *r->s2, 0, 6, 0); + test(*r->s1, 1, 0, *r->s2, 1, 0, 0); + test(*r->s1, 1, 0, *r->s2, 1, 1, 0); + test(*r->s1, 1, 0, *r->s2, 1, 2, 0); + test(*r->s1, 1, 0, *r->s2, 1, 3, 0); + test(*r->s1, 1, 0, *r->s2, 1, 4, 0); + test(*r->s1, 1, 0, *r->s2, 1, 5, 0); + test(*r->s1, 1, 0, *r->s2, 2, 0, 0); + test(*r->s1, 1, 0, *r->s2, 2, 1, 0); + test(*r->s1, 1, 0, *r->s2, 2, 2, 0); + test(*r->s1, 1, 0, *r->s2, 2, 3, 0); + test(*r->s1, 1, 0, *r->s2, 2, 4, 0); + test(*r->s1, 1, 0, *r->s2, 4, 0, 0); + test(*r->s1, 1, 0, *r->s2, 4, 1, 0); + test(*r->s1, 1, 0, *r->s2, 4, 2, 0); + test(*r->s1, 1, 0, *r->s2, 5, 0, 0); + test(*r->s1, 1, 0, *r->s2, 5, 1, 0); + test(*r->s1, 1, 0, *r->s2, 6, 0, 0); + test(*r->s1, 1, 0, *r->s3, 0, 0, 0); + test(*r->s1, 1, 0, *r->s3, 0, 1, 0); + test(*r->s1, 1, 0, *r->s3, 0, 5, 0); + test(*r->s1, 1, 0, *r->s3, 0, 9, 0); + test(*r->s1, 1, 0, *r->s3, 0, 10, 0); + test(*r->s1, 1, 0, *r->s3, 0, 11, 0); + test(*r->s1, 1, 0, *r->s3, 1, 0, 0); + test(*r->s1, 1, 0, *r->s3, 1, 1, 0); + test(*r->s1, 1, 0, *r->s3, 1, 4, 0); + test(*r->s1, 1, 0, *r->s3, 1, 8, 0); + test(*r->s1, 1, 0, *r->s3, 1, 9, 0); + test(*r->s1, 1, 0, *r->s3, 1, 10, 0); + test(*r->s1, 1, 0, *r->s3, 5, 0, 0); + test(*r->s1, 1, 0, *r->s3, 5, 1, 0); + test(*r->s1, 1, 0, *r->s3, 5, 2, 0); + test(*r->s1, 1, 0, *r->s3, 5, 4, 0); + test(*r->s1, 1, 0, *r->s3, 5, 5, 0); + test(*r->s1, 1, 0, *r->s3, 5, 6, 0); + test(*r->s1, 1, 0, *r->s3, 9, 0, 0); + test(*r->s1, 1, 0, *r->s3, 9, 1, 0); + test(*r->s1, 1, 0, *r->s3, 9, 2, 0); + test(*r->s1, 1, 0, *r->s3, 10, 0, 0); + test(*r->s1, 1, 0, *r->s3, 10, 1, 0); + test(*r->s1, 1, 0, *r->s3, 11, 0, 0); + test(*r->s1, 1, 0, *r->s4, 0, 0, 0); + test(*r->s1, 1, 0, *r->s4, 0, 1, 0); +} + +template +void +test2(pmem::obj::persistent_ptr &r) +{ + test(*r->s1, 1, 0, *r->s4, 0, 10, 0); + test(*r->s1, 1, 0, *r->s4, 0, 19, 0); + test(*r->s1, 1, 0, *r->s4, 0, 20, 0); + test(*r->s1, 1, 0, *r->s4, 0, 21, 0); + test(*r->s1, 1, 0, *r->s4, 1, 0, 0); + test(*r->s1, 1, 0, *r->s4, 1, 1, 0); + test(*r->s1, 1, 0, *r->s4, 1, 9, 0); + test(*r->s1, 1, 0, *r->s4, 1, 18, 0); + test(*r->s1, 1, 0, *r->s4, 1, 19, 0); + test(*r->s1, 1, 0, *r->s4, 1, 20, 0); + test(*r->s1, 1, 0, *r->s4, 10, 0, 0); + test(*r->s1, 1, 0, *r->s4, 10, 1, 0); + test(*r->s1, 1, 0, *r->s4, 10, 5, 0); + test(*r->s1, 1, 0, *r->s4, 10, 9, 0); + test(*r->s1, 1, 0, *r->s4, 10, 10, 0); + test(*r->s1, 1, 0, *r->s4, 10, 11, 0); + test(*r->s1, 1, 0, *r->s4, 19, 0, 0); + test(*r->s1, 1, 0, *r->s4, 19, 1, 0); + test(*r->s1, 1, 0, *r->s4, 19, 2, 0); + test(*r->s1, 1, 0, *r->s4, 20, 0, 0); + test(*r->s1, 1, 0, *r->s4, 20, 1, 0); + test(*r->s1, 1, 0, *r->s4, 21, 0, 0); + test(*r->s2, 0, 0, *r->s1, 0, 0, 0); + test(*r->s2, 0, 0, *r->s1, 0, 1, 0); + test(*r->s2, 0, 0, *r->s1, 1, 0, 0); + test(*r->s2, 0, 0, *r->s2, 0, 0, 0); + test(*r->s2, 0, 0, *r->s2, 0, 1, -1); + test(*r->s2, 0, 0, *r->s2, 0, 2, -2); + test(*r->s2, 0, 0, *r->s2, 0, 4, -4); + test(*r->s2, 0, 0, *r->s2, 0, 5, -5); + test(*r->s2, 0, 0, *r->s2, 0, 6, -5); + test(*r->s2, 0, 0, *r->s2, 1, 0, 0); + test(*r->s2, 0, 0, *r->s2, 1, 1, -1); + test(*r->s2, 0, 0, *r->s2, 1, 2, -2); + test(*r->s2, 0, 0, *r->s2, 1, 3, -3); + test(*r->s2, 0, 0, *r->s2, 1, 4, -4); + test(*r->s2, 0, 0, *r->s2, 1, 5, -4); + test(*r->s2, 0, 0, *r->s2, 2, 0, 0); + test(*r->s2, 0, 0, *r->s2, 2, 1, -1); + test(*r->s2, 0, 0, *r->s2, 2, 2, -2); + test(*r->s2, 0, 0, *r->s2, 2, 3, -3); + test(*r->s2, 0, 0, *r->s2, 2, 4, -3); + test(*r->s2, 0, 0, *r->s2, 4, 0, 0); + test(*r->s2, 0, 0, *r->s2, 4, 1, -1); + test(*r->s2, 0, 0, *r->s2, 4, 2, -1); + test(*r->s2, 0, 0, *r->s2, 5, 0, 0); + test(*r->s2, 0, 0, *r->s2, 5, 1, 0); + test(*r->s2, 0, 0, *r->s2, 6, 0, 0); + test(*r->s2, 0, 0, *r->s3, 0, 0, 0); + test(*r->s2, 0, 0, *r->s3, 0, 1, -1); + test(*r->s2, 0, 0, *r->s3, 0, 5, -5); + test(*r->s2, 0, 0, *r->s3, 0, 9, -9); + test(*r->s2, 0, 0, *r->s3, 0, 10, -10); + test(*r->s2, 0, 0, *r->s3, 0, 11, -10); + test(*r->s2, 0, 0, *r->s3, 1, 0, 0); + test(*r->s2, 0, 0, *r->s3, 1, 1, -1); + test(*r->s2, 0, 0, *r->s3, 1, 4, -4); + test(*r->s2, 0, 0, *r->s3, 1, 8, -8); + test(*r->s2, 0, 0, *r->s3, 1, 9, -9); + test(*r->s2, 0, 0, *r->s3, 1, 10, -9); + test(*r->s2, 0, 0, *r->s3, 5, 0, 0); + test(*r->s2, 0, 0, *r->s3, 5, 1, -1); + test(*r->s2, 0, 0, *r->s3, 5, 2, -2); + test(*r->s2, 0, 0, *r->s3, 5, 4, -4); + test(*r->s2, 0, 0, *r->s3, 5, 5, -5); + test(*r->s2, 0, 0, *r->s3, 5, 6, -5); + test(*r->s2, 0, 0, *r->s3, 9, 0, 0); + test(*r->s2, 0, 0, *r->s3, 9, 1, -1); + test(*r->s2, 0, 0, *r->s3, 9, 2, -1); + test(*r->s2, 0, 0, *r->s3, 10, 0, 0); + test(*r->s2, 0, 0, *r->s3, 10, 1, 0); + test(*r->s2, 0, 0, *r->s3, 11, 0, 0); + test(*r->s2, 0, 0, *r->s4, 0, 0, 0); + test(*r->s2, 0, 0, *r->s4, 0, 1, -1); + test(*r->s2, 0, 0, *r->s4, 0, 10, -10); + test(*r->s2, 0, 0, *r->s4, 0, 19, -19); + test(*r->s2, 0, 0, *r->s4, 0, 20, -20); + test(*r->s2, 0, 0, *r->s4, 0, 21, -20); + test(*r->s2, 0, 0, *r->s4, 1, 0, 0); + test(*r->s2, 0, 0, *r->s4, 1, 1, -1); + test(*r->s2, 0, 0, *r->s4, 1, 9, -9); + test(*r->s2, 0, 0, *r->s4, 1, 18, -18); + test(*r->s2, 0, 0, *r->s4, 1, 19, -19); + test(*r->s2, 0, 0, *r->s4, 1, 20, -19); + test(*r->s2, 0, 0, *r->s4, 10, 0, 0); + test(*r->s2, 0, 0, *r->s4, 10, 1, -1); + test(*r->s2, 0, 0, *r->s4, 10, 5, -5); + test(*r->s2, 0, 0, *r->s4, 10, 9, -9); + test(*r->s2, 0, 0, *r->s4, 10, 10, -10); + test(*r->s2, 0, 0, *r->s4, 10, 11, -10); + test(*r->s2, 0, 0, *r->s4, 19, 0, 0); + test(*r->s2, 0, 0, *r->s4, 19, 1, -1); + test(*r->s2, 0, 0, *r->s4, 19, 2, -1); + test(*r->s2, 0, 0, *r->s4, 20, 0, 0); + test(*r->s2, 0, 0, *r->s4, 20, 1, 0); + test(*r->s2, 0, 0, *r->s4, 21, 0, 0); + test(*r->s2, 0, 1, *r->s1, 0, 0, 1); + test(*r->s2, 0, 1, *r->s1, 0, 1, 1); + test(*r->s2, 0, 1, *r->s1, 1, 0, 0); + test(*r->s2, 0, 1, *r->s2, 0, 0, 1); +} + +template +void +test3(pmem::obj::persistent_ptr &r) +{ + test(*r->s2, 0, 1, *r->s2, 0, 1, 0); + test(*r->s2, 0, 1, *r->s2, 0, 2, -1); + test(*r->s2, 0, 1, *r->s2, 0, 4, -3); + test(*r->s2, 0, 1, *r->s2, 0, 5, -4); + test(*r->s2, 0, 1, *r->s2, 0, 6, -4); + test(*r->s2, 0, 1, *r->s2, 1, 0, 1); + test(*r->s2, 0, 1, *r->s2, 1, 1, -1); + test(*r->s2, 0, 1, *r->s2, 1, 2, -1); + test(*r->s2, 0, 1, *r->s2, 1, 3, -1); + test(*r->s2, 0, 1, *r->s2, 1, 4, -1); + test(*r->s2, 0, 1, *r->s2, 1, 5, -1); + test(*r->s2, 0, 1, *r->s2, 2, 0, 1); + test(*r->s2, 0, 1, *r->s2, 2, 1, -2); + test(*r->s2, 0, 1, *r->s2, 2, 2, -2); + test(*r->s2, 0, 1, *r->s2, 2, 3, -2); + test(*r->s2, 0, 1, *r->s2, 2, 4, -2); + test(*r->s2, 0, 1, *r->s2, 4, 0, 1); + test(*r->s2, 0, 1, *r->s2, 4, 1, -4); + test(*r->s2, 0, 1, *r->s2, 4, 2, -4); + test(*r->s2, 0, 1, *r->s2, 5, 0, 1); + test(*r->s2, 0, 1, *r->s2, 5, 1, 1); + test(*r->s2, 0, 1, *r->s2, 6, 0, 0); + test(*r->s2, 0, 1, *r->s3, 0, 0, 1); + test(*r->s2, 0, 1, *r->s3, 0, 1, 0); + test(*r->s2, 0, 1, *r->s3, 0, 5, -4); + test(*r->s2, 0, 1, *r->s3, 0, 9, -8); + test(*r->s2, 0, 1, *r->s3, 0, 10, -9); + test(*r->s2, 0, 1, *r->s3, 0, 11, -9); + test(*r->s2, 0, 1, *r->s3, 1, 0, 1); + test(*r->s2, 0, 1, *r->s3, 1, 1, -1); + test(*r->s2, 0, 1, *r->s3, 1, 4, -1); + test(*r->s2, 0, 1, *r->s3, 1, 8, -1); + test(*r->s2, 0, 1, *r->s3, 1, 9, -1); + test(*r->s2, 0, 1, *r->s3, 1, 10, -1); + test(*r->s2, 0, 1, *r->s3, 5, 0, 1); + test(*r->s2, 0, 1, *r->s3, 5, 1, -5); + test(*r->s2, 0, 1, *r->s3, 5, 2, -5); + test(*r->s2, 0, 1, *r->s3, 5, 4, -5); + test(*r->s2, 0, 1, *r->s3, 5, 5, -5); + test(*r->s2, 0, 1, *r->s3, 5, 6, -5); + test(*r->s2, 0, 1, *r->s3, 9, 0, 1); + test(*r->s2, 0, 1, *r->s3, 9, 1, -9); + test(*r->s2, 0, 1, *r->s3, 9, 2, -9); + test(*r->s2, 0, 1, *r->s3, 10, 0, 1); + test(*r->s2, 0, 1, *r->s3, 10, 1, 1); + test(*r->s2, 0, 1, *r->s3, 11, 0, 0); + test(*r->s2, 0, 1, *r->s4, 0, 0, 1); + test(*r->s2, 0, 1, *r->s4, 0, 1, 0); + test(*r->s2, 0, 1, *r->s4, 0, 10, -9); + test(*r->s2, 0, 1, *r->s4, 0, 19, -18); + test(*r->s2, 0, 1, *r->s4, 0, 20, -19); + test(*r->s2, 0, 1, *r->s4, 0, 21, -19); + test(*r->s2, 0, 1, *r->s4, 1, 0, 1); + test(*r->s2, 0, 1, *r->s4, 1, 1, -1); + test(*r->s2, 0, 1, *r->s4, 1, 9, -1); + test(*r->s2, 0, 1, *r->s4, 1, 18, -1); + test(*r->s2, 0, 1, *r->s4, 1, 19, -1); + test(*r->s2, 0, 1, *r->s4, 1, 20, -1); + test(*r->s2, 0, 1, *r->s4, 10, 0, 1); + test(*r->s2, 0, 1, *r->s4, 10, 1, -10); + test(*r->s2, 0, 1, *r->s4, 10, 5, -10); + test(*r->s2, 0, 1, *r->s4, 10, 9, -10); + test(*r->s2, 0, 1, *r->s4, 10, 10, -10); + test(*r->s2, 0, 1, *r->s4, 10, 11, -10); + test(*r->s2, 0, 1, *r->s4, 19, 0, 1); + test(*r->s2, 0, 1, *r->s4, 19, 1, -19); + test(*r->s2, 0, 1, *r->s4, 19, 2, -19); + test(*r->s2, 0, 1, *r->s4, 20, 0, 1); + test(*r->s2, 0, 1, *r->s4, 20, 1, 1); + test(*r->s2, 0, 1, *r->s4, 21, 0, 0); + test(*r->s2, 0, 2, *r->s1, 0, 0, 2); + test(*r->s2, 0, 2, *r->s1, 0, 1, 2); + test(*r->s2, 0, 2, *r->s1, 1, 0, 0); + test(*r->s2, 0, 2, *r->s2, 0, 0, 2); + test(*r->s2, 0, 2, *r->s2, 0, 1, 1); + test(*r->s2, 0, 2, *r->s2, 0, 2, 0); + test(*r->s2, 0, 2, *r->s2, 0, 4, -2); + test(*r->s2, 0, 2, *r->s2, 0, 5, -3); + test(*r->s2, 0, 2, *r->s2, 0, 6, -3); + test(*r->s2, 0, 2, *r->s2, 1, 0, 2); + test(*r->s2, 0, 2, *r->s2, 1, 1, -1); + test(*r->s2, 0, 2, *r->s2, 1, 2, -1); + test(*r->s2, 0, 2, *r->s2, 1, 3, -1); + test(*r->s2, 0, 2, *r->s2, 1, 4, -1); + test(*r->s2, 0, 2, *r->s2, 1, 5, -1); + test(*r->s2, 0, 2, *r->s2, 2, 0, 2); + test(*r->s2, 0, 2, *r->s2, 2, 1, -2); + test(*r->s2, 0, 2, *r->s2, 2, 2, -2); + test(*r->s2, 0, 2, *r->s2, 2, 3, -2); + test(*r->s2, 0, 2, *r->s2, 2, 4, -2); + test(*r->s2, 0, 2, *r->s2, 4, 0, 2); + test(*r->s2, 0, 2, *r->s2, 4, 1, -4); + test(*r->s2, 0, 2, *r->s2, 4, 2, -4); + test(*r->s2, 0, 2, *r->s2, 5, 0, 2); + test(*r->s2, 0, 2, *r->s2, 5, 1, 2); + test(*r->s2, 0, 2, *r->s2, 6, 0, 0); + test(*r->s2, 0, 2, *r->s3, 0, 0, 2); + test(*r->s2, 0, 2, *r->s3, 0, 1, 1); + test(*r->s2, 0, 2, *r->s3, 0, 5, -3); + test(*r->s2, 0, 2, *r->s3, 0, 9, -7); +} + +template +void +test4(pmem::obj::persistent_ptr &r) +{ + test(*r->s2, 0, 2, *r->s3, 0, 10, -8); + test(*r->s2, 0, 2, *r->s3, 0, 11, -8); + test(*r->s2, 0, 2, *r->s3, 1, 0, 2); + test(*r->s2, 0, 2, *r->s3, 1, 1, -1); + test(*r->s2, 0, 2, *r->s3, 1, 4, -1); + test(*r->s2, 0, 2, *r->s3, 1, 8, -1); + test(*r->s2, 0, 2, *r->s3, 1, 9, -1); + test(*r->s2, 0, 2, *r->s3, 1, 10, -1); + test(*r->s2, 0, 2, *r->s3, 5, 0, 2); + test(*r->s2, 0, 2, *r->s3, 5, 1, -5); + test(*r->s2, 0, 2, *r->s3, 5, 2, -5); + test(*r->s2, 0, 2, *r->s3, 5, 4, -5); + test(*r->s2, 0, 2, *r->s3, 5, 5, -5); + test(*r->s2, 0, 2, *r->s3, 5, 6, -5); + test(*r->s2, 0, 2, *r->s3, 9, 0, 2); + test(*r->s2, 0, 2, *r->s3, 9, 1, -9); + test(*r->s2, 0, 2, *r->s3, 9, 2, -9); + test(*r->s2, 0, 2, *r->s3, 10, 0, 2); + test(*r->s2, 0, 2, *r->s3, 10, 1, 2); + test(*r->s2, 0, 2, *r->s3, 11, 0, 0); + test(*r->s2, 0, 2, *r->s4, 0, 0, 2); + test(*r->s2, 0, 2, *r->s4, 0, 1, 1); + test(*r->s2, 0, 2, *r->s4, 0, 10, -8); + test(*r->s2, 0, 2, *r->s4, 0, 19, -17); + test(*r->s2, 0, 2, *r->s4, 0, 20, -18); + test(*r->s2, 0, 2, *r->s4, 0, 21, -18); + test(*r->s2, 0, 2, *r->s4, 1, 0, 2); + test(*r->s2, 0, 2, *r->s4, 1, 1, -1); + test(*r->s2, 0, 2, *r->s4, 1, 9, -1); + test(*r->s2, 0, 2, *r->s4, 1, 18, -1); + test(*r->s2, 0, 2, *r->s4, 1, 19, -1); + test(*r->s2, 0, 2, *r->s4, 1, 20, -1); + test(*r->s2, 0, 2, *r->s4, 10, 0, 2); + test(*r->s2, 0, 2, *r->s4, 10, 1, -10); + test(*r->s2, 0, 2, *r->s4, 10, 5, -10); + test(*r->s2, 0, 2, *r->s4, 10, 9, -10); + test(*r->s2, 0, 2, *r->s4, 10, 10, -10); + test(*r->s2, 0, 2, *r->s4, 10, 11, -10); + test(*r->s2, 0, 2, *r->s4, 19, 0, 2); + test(*r->s2, 0, 2, *r->s4, 19, 1, -19); + test(*r->s2, 0, 2, *r->s4, 19, 2, -19); + test(*r->s2, 0, 2, *r->s4, 20, 0, 2); + test(*r->s2, 0, 2, *r->s4, 20, 1, 2); + test(*r->s2, 0, 2, *r->s4, 21, 0, 0); + test(*r->s2, 0, 4, *r->s1, 0, 0, 4); + test(*r->s2, 0, 4, *r->s1, 0, 1, 4); + test(*r->s2, 0, 4, *r->s1, 1, 0, 0); + test(*r->s2, 0, 4, *r->s2, 0, 0, 4); + test(*r->s2, 0, 4, *r->s2, 0, 1, 3); + test(*r->s2, 0, 4, *r->s2, 0, 2, 2); + test(*r->s2, 0, 4, *r->s2, 0, 4, 0); + test(*r->s2, 0, 4, *r->s2, 0, 5, -1); + test(*r->s2, 0, 4, *r->s2, 0, 6, -1); + test(*r->s2, 0, 4, *r->s2, 1, 0, 4); + test(*r->s2, 0, 4, *r->s2, 1, 1, -1); + test(*r->s2, 0, 4, *r->s2, 1, 2, -1); + test(*r->s2, 0, 4, *r->s2, 1, 3, -1); + test(*r->s2, 0, 4, *r->s2, 1, 4, -1); + test(*r->s2, 0, 4, *r->s2, 1, 5, -1); + test(*r->s2, 0, 4, *r->s2, 2, 0, 4); + test(*r->s2, 0, 4, *r->s2, 2, 1, -2); + test(*r->s2, 0, 4, *r->s2, 2, 2, -2); + test(*r->s2, 0, 4, *r->s2, 2, 3, -2); + test(*r->s2, 0, 4, *r->s2, 2, 4, -2); + test(*r->s2, 0, 4, *r->s2, 4, 0, 4); + test(*r->s2, 0, 4, *r->s2, 4, 1, -4); + test(*r->s2, 0, 4, *r->s2, 4, 2, -4); + test(*r->s2, 0, 4, *r->s2, 5, 0, 4); + test(*r->s2, 0, 4, *r->s2, 5, 1, 4); + test(*r->s2, 0, 4, *r->s2, 6, 0, 0); + test(*r->s2, 0, 4, *r->s3, 0, 0, 4); + test(*r->s2, 0, 4, *r->s3, 0, 1, 3); + test(*r->s2, 0, 4, *r->s3, 0, 5, -1); + test(*r->s2, 0, 4, *r->s3, 0, 9, -5); + test(*r->s2, 0, 4, *r->s3, 0, 10, -6); + test(*r->s2, 0, 4, *r->s3, 0, 11, -6); + test(*r->s2, 0, 4, *r->s3, 1, 0, 4); + test(*r->s2, 0, 4, *r->s3, 1, 1, -1); + test(*r->s2, 0, 4, *r->s3, 1, 4, -1); + test(*r->s2, 0, 4, *r->s3, 1, 8, -1); + test(*r->s2, 0, 4, *r->s3, 1, 9, -1); + test(*r->s2, 0, 4, *r->s3, 1, 10, -1); + test(*r->s2, 0, 4, *r->s3, 5, 0, 4); + test(*r->s2, 0, 4, *r->s3, 5, 1, -5); + test(*r->s2, 0, 4, *r->s3, 5, 2, -5); + test(*r->s2, 0, 4, *r->s3, 5, 4, -5); + test(*r->s2, 0, 4, *r->s3, 5, 5, -5); + test(*r->s2, 0, 4, *r->s3, 5, 6, -5); + test(*r->s2, 0, 4, *r->s3, 9, 0, 4); + test(*r->s2, 0, 4, *r->s3, 9, 1, -9); + test(*r->s2, 0, 4, *r->s3, 9, 2, -9); + test(*r->s2, 0, 4, *r->s3, 10, 0, 4); + test(*r->s2, 0, 4, *r->s3, 10, 1, 4); + test(*r->s2, 0, 4, *r->s3, 11, 0, 0); + test(*r->s2, 0, 4, *r->s4, 0, 0, 4); + test(*r->s2, 0, 4, *r->s4, 0, 1, 3); + test(*r->s2, 0, 4, *r->s4, 0, 10, -6); + test(*r->s2, 0, 4, *r->s4, 0, 19, -15); + test(*r->s2, 0, 4, *r->s4, 0, 20, -16); + test(*r->s2, 0, 4, *r->s4, 0, 21, -16); +} + +template +void +test5(pmem::obj::persistent_ptr &r) +{ + test(*r->s2, 0, 4, *r->s4, 1, 0, 4); + test(*r->s2, 0, 4, *r->s4, 1, 1, -1); + test(*r->s2, 0, 4, *r->s4, 1, 9, -1); + test(*r->s2, 0, 4, *r->s4, 1, 18, -1); + test(*r->s2, 0, 4, *r->s4, 1, 19, -1); + test(*r->s2, 0, 4, *r->s4, 1, 20, -1); + test(*r->s2, 0, 4, *r->s4, 10, 0, 4); + test(*r->s2, 0, 4, *r->s4, 10, 1, -10); + test(*r->s2, 0, 4, *r->s4, 10, 5, -10); + test(*r->s2, 0, 4, *r->s4, 10, 9, -10); + test(*r->s2, 0, 4, *r->s4, 10, 10, -10); + test(*r->s2, 0, 4, *r->s4, 10, 11, -10); + test(*r->s2, 0, 4, *r->s4, 19, 0, 4); + test(*r->s2, 0, 4, *r->s4, 19, 1, -19); + test(*r->s2, 0, 4, *r->s4, 19, 2, -19); + test(*r->s2, 0, 4, *r->s4, 20, 0, 4); + test(*r->s2, 0, 4, *r->s4, 20, 1, 4); + test(*r->s2, 0, 4, *r->s4, 21, 0, 0); + test(*r->s2, 0, 5, *r->s1, 0, 0, 5); + test(*r->s2, 0, 5, *r->s1, 0, 1, 5); + test(*r->s2, 0, 5, *r->s1, 1, 0, 0); + test(*r->s2, 0, 5, *r->s2, 0, 0, 5); + test(*r->s2, 0, 5, *r->s2, 0, 1, 4); + test(*r->s2, 0, 5, *r->s2, 0, 2, 3); + test(*r->s2, 0, 5, *r->s2, 0, 4, 1); + test(*r->s2, 0, 5, *r->s2, 0, 5, 0); + test(*r->s2, 0, 5, *r->s2, 0, 6, 0); + test(*r->s2, 0, 5, *r->s2, 1, 0, 5); + test(*r->s2, 0, 5, *r->s2, 1, 1, -1); + test(*r->s2, 0, 5, *r->s2, 1, 2, -1); + test(*r->s2, 0, 5, *r->s2, 1, 3, -1); + test(*r->s2, 0, 5, *r->s2, 1, 4, -1); + test(*r->s2, 0, 5, *r->s2, 1, 5, -1); + test(*r->s2, 0, 5, *r->s2, 2, 0, 5); + test(*r->s2, 0, 5, *r->s2, 2, 1, -2); + test(*r->s2, 0, 5, *r->s2, 2, 2, -2); + test(*r->s2, 0, 5, *r->s2, 2, 3, -2); + test(*r->s2, 0, 5, *r->s2, 2, 4, -2); + test(*r->s2, 0, 5, *r->s2, 4, 0, 5); + test(*r->s2, 0, 5, *r->s2, 4, 1, -4); + test(*r->s2, 0, 5, *r->s2, 4, 2, -4); + test(*r->s2, 0, 5, *r->s2, 5, 0, 5); + test(*r->s2, 0, 5, *r->s2, 5, 1, 5); + test(*r->s2, 0, 5, *r->s2, 6, 0, 0); + test(*r->s2, 0, 5, *r->s3, 0, 0, 5); + test(*r->s2, 0, 5, *r->s3, 0, 1, 4); + test(*r->s2, 0, 5, *r->s3, 0, 5, 0); + test(*r->s2, 0, 5, *r->s3, 0, 9, -4); + test(*r->s2, 0, 5, *r->s3, 0, 10, -5); + test(*r->s2, 0, 5, *r->s3, 0, 11, -5); + test(*r->s2, 0, 5, *r->s3, 1, 0, 5); + test(*r->s2, 0, 5, *r->s3, 1, 1, -1); + test(*r->s2, 0, 5, *r->s3, 1, 4, -1); + test(*r->s2, 0, 5, *r->s3, 1, 8, -1); + test(*r->s2, 0, 5, *r->s3, 1, 9, -1); + test(*r->s2, 0, 5, *r->s3, 1, 10, -1); + test(*r->s2, 0, 5, *r->s3, 5, 0, 5); + test(*r->s2, 0, 5, *r->s3, 5, 1, -5); + test(*r->s2, 0, 5, *r->s3, 5, 2, -5); + test(*r->s2, 0, 5, *r->s3, 5, 4, -5); + test(*r->s2, 0, 5, *r->s3, 5, 5, -5); + test(*r->s2, 0, 5, *r->s3, 5, 6, -5); + test(*r->s2, 0, 5, *r->s3, 9, 0, 5); + test(*r->s2, 0, 5, *r->s3, 9, 1, -9); + test(*r->s2, 0, 5, *r->s3, 9, 2, -9); + test(*r->s2, 0, 5, *r->s3, 10, 0, 5); + test(*r->s2, 0, 5, *r->s3, 10, 1, 5); + test(*r->s2, 0, 5, *r->s3, 11, 0, 0); + test(*r->s2, 0, 5, *r->s4, 0, 0, 5); + test(*r->s2, 0, 5, *r->s4, 0, 1, 4); + test(*r->s2, 0, 5, *r->s4, 0, 10, -5); + test(*r->s2, 0, 5, *r->s4, 0, 19, -14); + test(*r->s2, 0, 5, *r->s4, 0, 20, -15); + test(*r->s2, 0, 5, *r->s4, 0, 21, -15); + test(*r->s2, 0, 5, *r->s4, 1, 0, 5); + test(*r->s2, 0, 5, *r->s4, 1, 1, -1); + test(*r->s2, 0, 5, *r->s4, 1, 9, -1); + test(*r->s2, 0, 5, *r->s4, 1, 18, -1); + test(*r->s2, 0, 5, *r->s4, 1, 19, -1); + test(*r->s2, 0, 5, *r->s4, 1, 20, -1); + test(*r->s2, 0, 5, *r->s4, 10, 0, 5); + test(*r->s2, 0, 5, *r->s4, 10, 1, -10); + test(*r->s2, 0, 5, *r->s4, 10, 5, -10); + test(*r->s2, 0, 5, *r->s4, 10, 9, -10); + test(*r->s2, 0, 5, *r->s4, 10, 10, -10); + test(*r->s2, 0, 5, *r->s4, 10, 11, -10); + test(*r->s2, 0, 5, *r->s4, 19, 0, 5); + test(*r->s2, 0, 5, *r->s4, 19, 1, -19); + test(*r->s2, 0, 5, *r->s4, 19, 2, -19); + test(*r->s2, 0, 5, *r->s4, 20, 0, 5); + test(*r->s2, 0, 5, *r->s4, 20, 1, 5); + test(*r->s2, 0, 5, *r->s4, 21, 0, 0); + test(*r->s2, 0, 6, *r->s1, 0, 0, 5); + test(*r->s2, 0, 6, *r->s1, 0, 1, 5); + test(*r->s2, 0, 6, *r->s1, 1, 0, 0); + test(*r->s2, 0, 6, *r->s2, 0, 0, 5); + test(*r->s2, 0, 6, *r->s2, 0, 1, 4); + test(*r->s2, 0, 6, *r->s2, 0, 2, 3); + test(*r->s2, 0, 6, *r->s2, 0, 4, 1); + test(*r->s2, 0, 6, *r->s2, 0, 5, 0); +} + +template +void +test6(pmem::obj::persistent_ptr &r) +{ + test(*r->s2, 0, 6, *r->s2, 0, 6, 0); + test(*r->s2, 0, 6, *r->s2, 1, 0, 5); + test(*r->s2, 0, 6, *r->s2, 1, 1, -1); + test(*r->s2, 0, 6, *r->s2, 1, 2, -1); + test(*r->s2, 0, 6, *r->s2, 1, 3, -1); + test(*r->s2, 0, 6, *r->s2, 1, 4, -1); + test(*r->s2, 0, 6, *r->s2, 1, 5, -1); + test(*r->s2, 0, 6, *r->s2, 2, 0, 5); + test(*r->s2, 0, 6, *r->s2, 2, 1, -2); + test(*r->s2, 0, 6, *r->s2, 2, 2, -2); + test(*r->s2, 0, 6, *r->s2, 2, 3, -2); + test(*r->s2, 0, 6, *r->s2, 2, 4, -2); + test(*r->s2, 0, 6, *r->s2, 4, 0, 5); + test(*r->s2, 0, 6, *r->s2, 4, 1, -4); + test(*r->s2, 0, 6, *r->s2, 4, 2, -4); + test(*r->s2, 0, 6, *r->s2, 5, 0, 5); + test(*r->s2, 0, 6, *r->s2, 5, 1, 5); + test(*r->s2, 0, 6, *r->s2, 6, 0, 0); + test(*r->s2, 0, 6, *r->s3, 0, 0, 5); + test(*r->s2, 0, 6, *r->s3, 0, 1, 4); + test(*r->s2, 0, 6, *r->s3, 0, 5, 0); + test(*r->s2, 0, 6, *r->s3, 0, 9, -4); + test(*r->s2, 0, 6, *r->s3, 0, 10, -5); + test(*r->s2, 0, 6, *r->s3, 0, 11, -5); + test(*r->s2, 0, 6, *r->s3, 1, 0, 5); + test(*r->s2, 0, 6, *r->s3, 1, 1, -1); + test(*r->s2, 0, 6, *r->s3, 1, 4, -1); + test(*r->s2, 0, 6, *r->s3, 1, 8, -1); + test(*r->s2, 0, 6, *r->s3, 1, 9, -1); + test(*r->s2, 0, 6, *r->s3, 1, 10, -1); + test(*r->s2, 0, 6, *r->s3, 5, 0, 5); + test(*r->s2, 0, 6, *r->s3, 5, 1, -5); + test(*r->s2, 0, 6, *r->s3, 5, 2, -5); + test(*r->s2, 0, 6, *r->s3, 5, 4, -5); + test(*r->s2, 0, 6, *r->s3, 5, 5, -5); + test(*r->s2, 0, 6, *r->s3, 5, 6, -5); + test(*r->s2, 0, 6, *r->s3, 9, 0, 5); + test(*r->s2, 0, 6, *r->s3, 9, 1, -9); + test(*r->s2, 0, 6, *r->s3, 9, 2, -9); + test(*r->s2, 0, 6, *r->s3, 10, 0, 5); + test(*r->s2, 0, 6, *r->s3, 10, 1, 5); + test(*r->s2, 0, 6, *r->s3, 11, 0, 0); + test(*r->s2, 0, 6, *r->s4, 0, 0, 5); + test(*r->s2, 0, 6, *r->s4, 0, 1, 4); + test(*r->s2, 0, 6, *r->s4, 0, 10, -5); + test(*r->s2, 0, 6, *r->s4, 0, 19, -14); + test(*r->s2, 0, 6, *r->s4, 0, 20, -15); + test(*r->s2, 0, 6, *r->s4, 0, 21, -15); + test(*r->s2, 0, 6, *r->s4, 1, 0, 5); + test(*r->s2, 0, 6, *r->s4, 1, 1, -1); + test(*r->s2, 0, 6, *r->s4, 1, 9, -1); + test(*r->s2, 0, 6, *r->s4, 1, 18, -1); + test(*r->s2, 0, 6, *r->s4, 1, 19, -1); + test(*r->s2, 0, 6, *r->s4, 1, 20, -1); + test(*r->s2, 0, 6, *r->s4, 10, 0, 5); + test(*r->s2, 0, 6, *r->s4, 10, 1, -10); + test(*r->s2, 0, 6, *r->s4, 10, 5, -10); + test(*r->s2, 0, 6, *r->s4, 10, 9, -10); + test(*r->s2, 0, 6, *r->s4, 10, 10, -10); + test(*r->s2, 0, 6, *r->s4, 10, 11, -10); + test(*r->s2, 0, 6, *r->s4, 19, 0, 5); + test(*r->s2, 0, 6, *r->s4, 19, 1, -19); + test(*r->s2, 0, 6, *r->s4, 19, 2, -19); + test(*r->s2, 0, 6, *r->s4, 20, 0, 5); + test(*r->s2, 0, 6, *r->s4, 20, 1, 5); + test(*r->s2, 0, 6, *r->s4, 21, 0, 0); + test(*r->s2, 1, 0, *r->s1, 0, 0, 0); + test(*r->s2, 1, 0, *r->s1, 0, 1, 0); + test(*r->s2, 1, 0, *r->s1, 1, 0, 0); + test(*r->s2, 1, 0, *r->s2, 0, 0, 0); + test(*r->s2, 1, 0, *r->s2, 0, 1, -1); + test(*r->s2, 1, 0, *r->s2, 0, 2, -2); + test(*r->s2, 1, 0, *r->s2, 0, 4, -4); + test(*r->s2, 1, 0, *r->s2, 0, 5, -5); + test(*r->s2, 1, 0, *r->s2, 0, 6, -5); + test(*r->s2, 1, 0, *r->s2, 1, 0, 0); + test(*r->s2, 1, 0, *r->s2, 1, 1, -1); + test(*r->s2, 1, 0, *r->s2, 1, 2, -2); + test(*r->s2, 1, 0, *r->s2, 1, 3, -3); + test(*r->s2, 1, 0, *r->s2, 1, 4, -4); + test(*r->s2, 1, 0, *r->s2, 1, 5, -4); + test(*r->s2, 1, 0, *r->s2, 2, 0, 0); + test(*r->s2, 1, 0, *r->s2, 2, 1, -1); + test(*r->s2, 1, 0, *r->s2, 2, 2, -2); + test(*r->s2, 1, 0, *r->s2, 2, 3, -3); + test(*r->s2, 1, 0, *r->s2, 2, 4, -3); + test(*r->s2, 1, 0, *r->s2, 4, 0, 0); + test(*r->s2, 1, 0, *r->s2, 4, 1, -1); + test(*r->s2, 1, 0, *r->s2, 4, 2, -1); + test(*r->s2, 1, 0, *r->s2, 5, 0, 0); + test(*r->s2, 1, 0, *r->s2, 5, 1, 0); + test(*r->s2, 1, 0, *r->s2, 6, 0, 0); + test(*r->s2, 1, 0, *r->s3, 0, 0, 0); + test(*r->s2, 1, 0, *r->s3, 0, 1, -1); + test(*r->s2, 1, 0, *r->s3, 0, 5, -5); + test(*r->s2, 1, 0, *r->s3, 0, 9, -9); + test(*r->s2, 1, 0, *r->s3, 0, 10, -10); + test(*r->s2, 1, 0, *r->s3, 0, 11, -10); + test(*r->s2, 1, 0, *r->s3, 1, 0, 0); + test(*r->s2, 1, 0, *r->s3, 1, 1, -1); +} + +template +void +test7(pmem::obj::persistent_ptr &r) +{ + test(*r->s2, 1, 0, *r->s3, 1, 4, -4); + test(*r->s2, 1, 0, *r->s3, 1, 8, -8); + test(*r->s2, 1, 0, *r->s3, 1, 9, -9); + test(*r->s2, 1, 0, *r->s3, 1, 10, -9); + test(*r->s2, 1, 0, *r->s3, 5, 0, 0); + test(*r->s2, 1, 0, *r->s3, 5, 1, -1); + test(*r->s2, 1, 0, *r->s3, 5, 2, -2); + test(*r->s2, 1, 0, *r->s3, 5, 4, -4); + test(*r->s2, 1, 0, *r->s3, 5, 5, -5); + test(*r->s2, 1, 0, *r->s3, 5, 6, -5); + test(*r->s2, 1, 0, *r->s3, 9, 0, 0); + test(*r->s2, 1, 0, *r->s3, 9, 1, -1); + test(*r->s2, 1, 0, *r->s3, 9, 2, -1); + test(*r->s2, 1, 0, *r->s3, 10, 0, 0); + test(*r->s2, 1, 0, *r->s3, 10, 1, 0); + test(*r->s2, 1, 0, *r->s3, 11, 0, 0); + test(*r->s2, 1, 0, *r->s4, 0, 0, 0); + test(*r->s2, 1, 0, *r->s4, 0, 1, -1); + test(*r->s2, 1, 0, *r->s4, 0, 10, -10); + test(*r->s2, 1, 0, *r->s4, 0, 19, -19); + test(*r->s2, 1, 0, *r->s4, 0, 20, -20); + test(*r->s2, 1, 0, *r->s4, 0, 21, -20); + test(*r->s2, 1, 0, *r->s4, 1, 0, 0); + test(*r->s2, 1, 0, *r->s4, 1, 1, -1); + test(*r->s2, 1, 0, *r->s4, 1, 9, -9); + test(*r->s2, 1, 0, *r->s4, 1, 18, -18); + test(*r->s2, 1, 0, *r->s4, 1, 19, -19); + test(*r->s2, 1, 0, *r->s4, 1, 20, -19); + test(*r->s2, 1, 0, *r->s4, 10, 0, 0); + test(*r->s2, 1, 0, *r->s4, 10, 1, -1); + test(*r->s2, 1, 0, *r->s4, 10, 5, -5); + test(*r->s2, 1, 0, *r->s4, 10, 9, -9); + test(*r->s2, 1, 0, *r->s4, 10, 10, -10); + test(*r->s2, 1, 0, *r->s4, 10, 11, -10); + test(*r->s2, 1, 0, *r->s4, 19, 0, 0); + test(*r->s2, 1, 0, *r->s4, 19, 1, -1); + test(*r->s2, 1, 0, *r->s4, 19, 2, -1); + test(*r->s2, 1, 0, *r->s4, 20, 0, 0); + test(*r->s2, 1, 0, *r->s4, 20, 1, 0); + test(*r->s2, 1, 0, *r->s4, 21, 0, 0); + test(*r->s2, 1, 1, *r->s1, 0, 0, 1); + test(*r->s2, 1, 1, *r->s1, 0, 1, 1); + test(*r->s2, 1, 1, *r->s1, 1, 0, 0); + test(*r->s2, 1, 1, *r->s2, 0, 0, 1); + test(*r->s2, 1, 1, *r->s2, 0, 1, 1); + test(*r->s2, 1, 1, *r->s2, 0, 2, 1); + test(*r->s2, 1, 1, *r->s2, 0, 4, 1); + test(*r->s2, 1, 1, *r->s2, 0, 5, 1); + test(*r->s2, 1, 1, *r->s2, 0, 6, 1); + test(*r->s2, 1, 1, *r->s2, 1, 0, 1); + test(*r->s2, 1, 1, *r->s2, 1, 1, 0); + test(*r->s2, 1, 1, *r->s2, 1, 2, -1); + test(*r->s2, 1, 1, *r->s2, 1, 3, -2); + test(*r->s2, 1, 1, *r->s2, 1, 4, -3); + test(*r->s2, 1, 1, *r->s2, 1, 5, -3); + test(*r->s2, 1, 1, *r->s2, 2, 0, 1); + test(*r->s2, 1, 1, *r->s2, 2, 1, -1); + test(*r->s2, 1, 1, *r->s2, 2, 2, -1); + test(*r->s2, 1, 1, *r->s2, 2, 3, -1); + test(*r->s2, 1, 1, *r->s2, 2, 4, -1); + test(*r->s2, 1, 1, *r->s2, 4, 0, 1); + test(*r->s2, 1, 1, *r->s2, 4, 1, -3); + test(*r->s2, 1, 1, *r->s2, 4, 2, -3); + test(*r->s2, 1, 1, *r->s2, 5, 0, 1); + test(*r->s2, 1, 1, *r->s2, 5, 1, 1); + test(*r->s2, 1, 1, *r->s2, 6, 0, 0); + test(*r->s2, 1, 1, *r->s3, 0, 0, 1); + test(*r->s2, 1, 1, *r->s3, 0, 1, 1); + test(*r->s2, 1, 1, *r->s3, 0, 5, 1); + test(*r->s2, 1, 1, *r->s3, 0, 9, 1); + test(*r->s2, 1, 1, *r->s3, 0, 10, 1); + test(*r->s2, 1, 1, *r->s3, 0, 11, 1); + test(*r->s2, 1, 1, *r->s3, 1, 0, 1); + test(*r->s2, 1, 1, *r->s3, 1, 1, 0); + test(*r->s2, 1, 1, *r->s3, 1, 4, -3); + test(*r->s2, 1, 1, *r->s3, 1, 8, -7); + test(*r->s2, 1, 1, *r->s3, 1, 9, -8); + test(*r->s2, 1, 1, *r->s3, 1, 10, -8); + test(*r->s2, 1, 1, *r->s3, 5, 0, 1); + test(*r->s2, 1, 1, *r->s3, 5, 1, -4); + test(*r->s2, 1, 1, *r->s3, 5, 2, -4); + test(*r->s2, 1, 1, *r->s3, 5, 4, -4); + test(*r->s2, 1, 1, *r->s3, 5, 5, -4); + test(*r->s2, 1, 1, *r->s3, 5, 6, -4); + test(*r->s2, 1, 1, *r->s3, 9, 0, 1); + test(*r->s2, 1, 1, *r->s3, 9, 1, -8); + test(*r->s2, 1, 1, *r->s3, 9, 2, -8); + test(*r->s2, 1, 1, *r->s3, 10, 0, 1); + test(*r->s2, 1, 1, *r->s3, 10, 1, 1); + test(*r->s2, 1, 1, *r->s3, 11, 0, 0); + test(*r->s2, 1, 1, *r->s4, 0, 0, 1); + test(*r->s2, 1, 1, *r->s4, 0, 1, 1); + test(*r->s2, 1, 1, *r->s4, 0, 10, 1); + test(*r->s2, 1, 1, *r->s4, 0, 19, 1); + test(*r->s2, 1, 1, *r->s4, 0, 20, 1); + test(*r->s2, 1, 1, *r->s4, 0, 21, 1); + test(*r->s2, 1, 1, *r->s4, 1, 0, 1); + test(*r->s2, 1, 1, *r->s4, 1, 1, 0); + test(*r->s2, 1, 1, *r->s4, 1, 9, -8); + test(*r->s2, 1, 1, *r->s4, 1, 18, -17); +} + +template +void +test8(pmem::obj::persistent_ptr &r) +{ + test(*r->s2, 1, 1, *r->s4, 1, 19, -18); + test(*r->s2, 1, 1, *r->s4, 1, 20, -18); + test(*r->s2, 1, 1, *r->s4, 10, 0, 1); + test(*r->s2, 1, 1, *r->s4, 10, 1, -9); + test(*r->s2, 1, 1, *r->s4, 10, 5, -9); + test(*r->s2, 1, 1, *r->s4, 10, 9, -9); + test(*r->s2, 1, 1, *r->s4, 10, 10, -9); + test(*r->s2, 1, 1, *r->s4, 10, 11, -9); + test(*r->s2, 1, 1, *r->s4, 19, 0, 1); + test(*r->s2, 1, 1, *r->s4, 19, 1, -18); + test(*r->s2, 1, 1, *r->s4, 19, 2, -18); + test(*r->s2, 1, 1, *r->s4, 20, 0, 1); + test(*r->s2, 1, 1, *r->s4, 20, 1, 1); + test(*r->s2, 1, 1, *r->s4, 21, 0, 0); + test(*r->s2, 1, 2, *r->s1, 0, 0, 2); + test(*r->s2, 1, 2, *r->s1, 0, 1, 2); + test(*r->s2, 1, 2, *r->s1, 1, 0, 0); + test(*r->s2, 1, 2, *r->s2, 0, 0, 2); + test(*r->s2, 1, 2, *r->s2, 0, 1, 1); + test(*r->s2, 1, 2, *r->s2, 0, 2, 1); + test(*r->s2, 1, 2, *r->s2, 0, 4, 1); + test(*r->s2, 1, 2, *r->s2, 0, 5, 1); + test(*r->s2, 1, 2, *r->s2, 0, 6, 1); + test(*r->s2, 1, 2, *r->s2, 1, 0, 2); + test(*r->s2, 1, 2, *r->s2, 1, 1, 1); + test(*r->s2, 1, 2, *r->s2, 1, 2, 0); + test(*r->s2, 1, 2, *r->s2, 1, 3, -1); + test(*r->s2, 1, 2, *r->s2, 1, 4, -2); + test(*r->s2, 1, 2, *r->s2, 1, 5, -2); + test(*r->s2, 1, 2, *r->s2, 2, 0, 2); + test(*r->s2, 1, 2, *r->s2, 2, 1, -1); + test(*r->s2, 1, 2, *r->s2, 2, 2, -1); + test(*r->s2, 1, 2, *r->s2, 2, 3, -1); + test(*r->s2, 1, 2, *r->s2, 2, 4, -1); + test(*r->s2, 1, 2, *r->s2, 4, 0, 2); + test(*r->s2, 1, 2, *r->s2, 4, 1, -3); + test(*r->s2, 1, 2, *r->s2, 4, 2, -3); + test(*r->s2, 1, 2, *r->s2, 5, 0, 2); + test(*r->s2, 1, 2, *r->s2, 5, 1, 2); + test(*r->s2, 1, 2, *r->s2, 6, 0, 0); + test(*r->s2, 1, 2, *r->s3, 0, 0, 2); + test(*r->s2, 1, 2, *r->s3, 0, 1, 1); + test(*r->s2, 1, 2, *r->s3, 0, 5, 1); + test(*r->s2, 1, 2, *r->s3, 0, 9, 1); + test(*r->s2, 1, 2, *r->s3, 0, 10, 1); + test(*r->s2, 1, 2, *r->s3, 0, 11, 1); + test(*r->s2, 1, 2, *r->s3, 1, 0, 2); + test(*r->s2, 1, 2, *r->s3, 1, 1, 1); + test(*r->s2, 1, 2, *r->s3, 1, 4, -2); + test(*r->s2, 1, 2, *r->s3, 1, 8, -6); + test(*r->s2, 1, 2, *r->s3, 1, 9, -7); + test(*r->s2, 1, 2, *r->s3, 1, 10, -7); + test(*r->s2, 1, 2, *r->s3, 5, 0, 2); + test(*r->s2, 1, 2, *r->s3, 5, 1, -4); + test(*r->s2, 1, 2, *r->s3, 5, 2, -4); + test(*r->s2, 1, 2, *r->s3, 5, 4, -4); + test(*r->s2, 1, 2, *r->s3, 5, 5, -4); + test(*r->s2, 1, 2, *r->s3, 5, 6, -4); + test(*r->s2, 1, 2, *r->s3, 9, 0, 2); + test(*r->s2, 1, 2, *r->s3, 9, 1, -8); + test(*r->s2, 1, 2, *r->s3, 9, 2, -8); + test(*r->s2, 1, 2, *r->s3, 10, 0, 2); + test(*r->s2, 1, 2, *r->s3, 10, 1, 2); + test(*r->s2, 1, 2, *r->s3, 11, 0, 0); + test(*r->s2, 1, 2, *r->s4, 0, 0, 2); + test(*r->s2, 1, 2, *r->s4, 0, 1, 1); + test(*r->s2, 1, 2, *r->s4, 0, 10, 1); + test(*r->s2, 1, 2, *r->s4, 0, 19, 1); + test(*r->s2, 1, 2, *r->s4, 0, 20, 1); + test(*r->s2, 1, 2, *r->s4, 0, 21, 1); + test(*r->s2, 1, 2, *r->s4, 1, 0, 2); + test(*r->s2, 1, 2, *r->s4, 1, 1, 1); + test(*r->s2, 1, 2, *r->s4, 1, 9, -7); + test(*r->s2, 1, 2, *r->s4, 1, 18, -16); + test(*r->s2, 1, 2, *r->s4, 1, 19, -17); + test(*r->s2, 1, 2, *r->s4, 1, 20, -17); + test(*r->s2, 1, 2, *r->s4, 10, 0, 2); + test(*r->s2, 1, 2, *r->s4, 10, 1, -9); + test(*r->s2, 1, 2, *r->s4, 10, 5, -9); + test(*r->s2, 1, 2, *r->s4, 10, 9, -9); + test(*r->s2, 1, 2, *r->s4, 10, 10, -9); + test(*r->s2, 1, 2, *r->s4, 10, 11, -9); + test(*r->s2, 1, 2, *r->s4, 19, 0, 2); + test(*r->s2, 1, 2, *r->s4, 19, 1, -18); + test(*r->s2, 1, 2, *r->s4, 19, 2, -18); + test(*r->s2, 1, 2, *r->s4, 20, 0, 2); + test(*r->s2, 1, 2, *r->s4, 20, 1, 2); + test(*r->s2, 1, 2, *r->s4, 21, 0, 0); + test(*r->s2, 1, 3, *r->s1, 0, 0, 3); + test(*r->s2, 1, 3, *r->s1, 0, 1, 3); + test(*r->s2, 1, 3, *r->s1, 1, 0, 0); + test(*r->s2, 1, 3, *r->s2, 0, 0, 3); + test(*r->s2, 1, 3, *r->s2, 0, 1, 1); + test(*r->s2, 1, 3, *r->s2, 0, 2, 1); + test(*r->s2, 1, 3, *r->s2, 0, 4, 1); + test(*r->s2, 1, 3, *r->s2, 0, 5, 1); + test(*r->s2, 1, 3, *r->s2, 0, 6, 1); + test(*r->s2, 1, 3, *r->s2, 1, 0, 3); + test(*r->s2, 1, 3, *r->s2, 1, 1, 2); + test(*r->s2, 1, 3, *r->s2, 1, 2, 1); +} + +template +void +test9(pmem::obj::persistent_ptr &r) +{ + test(*r->s2, 1, 3, *r->s2, 1, 3, 0); + test(*r->s2, 1, 3, *r->s2, 1, 4, -1); + test(*r->s2, 1, 3, *r->s2, 1, 5, -1); + test(*r->s2, 1, 3, *r->s2, 2, 0, 3); + test(*r->s2, 1, 3, *r->s2, 2, 1, -1); + test(*r->s2, 1, 3, *r->s2, 2, 2, -1); + test(*r->s2, 1, 3, *r->s2, 2, 3, -1); + test(*r->s2, 1, 3, *r->s2, 2, 4, -1); + test(*r->s2, 1, 3, *r->s2, 4, 0, 3); + test(*r->s2, 1, 3, *r->s2, 4, 1, -3); + test(*r->s2, 1, 3, *r->s2, 4, 2, -3); + test(*r->s2, 1, 3, *r->s2, 5, 0, 3); + test(*r->s2, 1, 3, *r->s2, 5, 1, 3); + test(*r->s2, 1, 3, *r->s2, 6, 0, 0); + test(*r->s2, 1, 3, *r->s3, 0, 0, 3); + test(*r->s2, 1, 3, *r->s3, 0, 1, 1); + test(*r->s2, 1, 3, *r->s3, 0, 5, 1); + test(*r->s2, 1, 3, *r->s3, 0, 9, 1); + test(*r->s2, 1, 3, *r->s3, 0, 10, 1); + test(*r->s2, 1, 3, *r->s3, 0, 11, 1); + test(*r->s2, 1, 3, *r->s3, 1, 0, 3); + test(*r->s2, 1, 3, *r->s3, 1, 1, 2); + test(*r->s2, 1, 3, *r->s3, 1, 4, -1); + test(*r->s2, 1, 3, *r->s3, 1, 8, -5); + test(*r->s2, 1, 3, *r->s3, 1, 9, -6); + test(*r->s2, 1, 3, *r->s3, 1, 10, -6); + test(*r->s2, 1, 3, *r->s3, 5, 0, 3); + test(*r->s2, 1, 3, *r->s3, 5, 1, -4); + test(*r->s2, 1, 3, *r->s3, 5, 2, -4); + test(*r->s2, 1, 3, *r->s3, 5, 4, -4); + test(*r->s2, 1, 3, *r->s3, 5, 5, -4); + test(*r->s2, 1, 3, *r->s3, 5, 6, -4); + test(*r->s2, 1, 3, *r->s3, 9, 0, 3); + test(*r->s2, 1, 3, *r->s3, 9, 1, -8); + test(*r->s2, 1, 3, *r->s3, 9, 2, -8); + test(*r->s2, 1, 3, *r->s3, 10, 0, 3); + test(*r->s2, 1, 3, *r->s3, 10, 1, 3); + test(*r->s2, 1, 3, *r->s3, 11, 0, 0); + test(*r->s2, 1, 3, *r->s4, 0, 0, 3); + test(*r->s2, 1, 3, *r->s4, 0, 1, 1); + test(*r->s2, 1, 3, *r->s4, 0, 10, 1); + test(*r->s2, 1, 3, *r->s4, 0, 19, 1); + test(*r->s2, 1, 3, *r->s4, 0, 20, 1); + test(*r->s2, 1, 3, *r->s4, 0, 21, 1); + test(*r->s2, 1, 3, *r->s4, 1, 0, 3); + test(*r->s2, 1, 3, *r->s4, 1, 1, 2); + test(*r->s2, 1, 3, *r->s4, 1, 9, -6); + test(*r->s2, 1, 3, *r->s4, 1, 18, -15); + test(*r->s2, 1, 3, *r->s4, 1, 19, -16); + test(*r->s2, 1, 3, *r->s4, 1, 20, -16); + test(*r->s2, 1, 3, *r->s4, 10, 0, 3); + test(*r->s2, 1, 3, *r->s4, 10, 1, -9); + test(*r->s2, 1, 3, *r->s4, 10, 5, -9); + test(*r->s2, 1, 3, *r->s4, 10, 9, -9); + test(*r->s2, 1, 3, *r->s4, 10, 10, -9); + test(*r->s2, 1, 3, *r->s4, 10, 11, -9); + test(*r->s2, 1, 3, *r->s4, 19, 0, 3); + test(*r->s2, 1, 3, *r->s4, 19, 1, -18); + test(*r->s2, 1, 3, *r->s4, 19, 2, -18); + test(*r->s2, 1, 3, *r->s4, 20, 0, 3); + test(*r->s2, 1, 3, *r->s4, 20, 1, 3); + test(*r->s2, 1, 3, *r->s4, 21, 0, 0); + test(*r->s2, 1, 4, *r->s1, 0, 0, 4); + test(*r->s2, 1, 4, *r->s1, 0, 1, 4); + test(*r->s2, 1, 4, *r->s1, 1, 0, 0); + test(*r->s2, 1, 4, *r->s2, 0, 0, 4); + test(*r->s2, 1, 4, *r->s2, 0, 1, 1); + test(*r->s2, 1, 4, *r->s2, 0, 2, 1); + test(*r->s2, 1, 4, *r->s2, 0, 4, 1); + test(*r->s2, 1, 4, *r->s2, 0, 5, 1); + test(*r->s2, 1, 4, *r->s2, 0, 6, 1); + test(*r->s2, 1, 4, *r->s2, 1, 0, 4); + test(*r->s2, 1, 4, *r->s2, 1, 1, 3); + test(*r->s2, 1, 4, *r->s2, 1, 2, 2); + test(*r->s2, 1, 4, *r->s2, 1, 3, 1); + test(*r->s2, 1, 4, *r->s2, 1, 4, 0); + test(*r->s2, 1, 4, *r->s2, 1, 5, 0); + test(*r->s2, 1, 4, *r->s2, 2, 0, 4); + test(*r->s2, 1, 4, *r->s2, 2, 1, -1); + test(*r->s2, 1, 4, *r->s2, 2, 2, -1); + test(*r->s2, 1, 4, *r->s2, 2, 3, -1); + test(*r->s2, 1, 4, *r->s2, 2, 4, -1); + test(*r->s2, 1, 4, *r->s2, 4, 0, 4); + test(*r->s2, 1, 4, *r->s2, 4, 1, -3); + test(*r->s2, 1, 4, *r->s2, 4, 2, -3); + test(*r->s2, 1, 4, *r->s2, 5, 0, 4); + test(*r->s2, 1, 4, *r->s2, 5, 1, 4); + test(*r->s2, 1, 4, *r->s2, 6, 0, 0); + test(*r->s2, 1, 4, *r->s3, 0, 0, 4); + test(*r->s2, 1, 4, *r->s3, 0, 1, 1); + test(*r->s2, 1, 4, *r->s3, 0, 5, 1); + test(*r->s2, 1, 4, *r->s3, 0, 9, 1); + test(*r->s2, 1, 4, *r->s3, 0, 10, 1); + test(*r->s2, 1, 4, *r->s3, 0, 11, 1); + test(*r->s2, 1, 4, *r->s3, 1, 0, 4); + test(*r->s2, 1, 4, *r->s3, 1, 1, 3); + test(*r->s2, 1, 4, *r->s3, 1, 4, 0); + test(*r->s2, 1, 4, *r->s3, 1, 8, -4); + test(*r->s2, 1, 4, *r->s3, 1, 9, -5); + test(*r->s2, 1, 4, *r->s3, 1, 10, -5); +} + +template +void +test10(pmem::obj::persistent_ptr &r) +{ + test(*r->s2, 1, 4, *r->s3, 5, 0, 4); + test(*r->s2, 1, 4, *r->s3, 5, 1, -4); + test(*r->s2, 1, 4, *r->s3, 5, 2, -4); + test(*r->s2, 1, 4, *r->s3, 5, 4, -4); + test(*r->s2, 1, 4, *r->s3, 5, 5, -4); + test(*r->s2, 1, 4, *r->s3, 5, 6, -4); + test(*r->s2, 1, 4, *r->s3, 9, 0, 4); + test(*r->s2, 1, 4, *r->s3, 9, 1, -8); + test(*r->s2, 1, 4, *r->s3, 9, 2, -8); + test(*r->s2, 1, 4, *r->s3, 10, 0, 4); + test(*r->s2, 1, 4, *r->s3, 10, 1, 4); + test(*r->s2, 1, 4, *r->s3, 11, 0, 0); + test(*r->s2, 1, 4, *r->s4, 0, 0, 4); + test(*r->s2, 1, 4, *r->s4, 0, 1, 1); + test(*r->s2, 1, 4, *r->s4, 0, 10, 1); + test(*r->s2, 1, 4, *r->s4, 0, 19, 1); + test(*r->s2, 1, 4, *r->s4, 0, 20, 1); + test(*r->s2, 1, 4, *r->s4, 0, 21, 1); + test(*r->s2, 1, 4, *r->s4, 1, 0, 4); + test(*r->s2, 1, 4, *r->s4, 1, 1, 3); + test(*r->s2, 1, 4, *r->s4, 1, 9, -5); + test(*r->s2, 1, 4, *r->s4, 1, 18, -14); + test(*r->s2, 1, 4, *r->s4, 1, 19, -15); + test(*r->s2, 1, 4, *r->s4, 1, 20, -15); + test(*r->s2, 1, 4, *r->s4, 10, 0, 4); + test(*r->s2, 1, 4, *r->s4, 10, 1, -9); + test(*r->s2, 1, 4, *r->s4, 10, 5, -9); + test(*r->s2, 1, 4, *r->s4, 10, 9, -9); + test(*r->s2, 1, 4, *r->s4, 10, 10, -9); + test(*r->s2, 1, 4, *r->s4, 10, 11, -9); + test(*r->s2, 1, 4, *r->s4, 19, 0, 4); + test(*r->s2, 1, 4, *r->s4, 19, 1, -18); + test(*r->s2, 1, 4, *r->s4, 19, 2, -18); + test(*r->s2, 1, 4, *r->s4, 20, 0, 4); + test(*r->s2, 1, 4, *r->s4, 20, 1, 4); + test(*r->s2, 1, 4, *r->s4, 21, 0, 0); + test(*r->s2, 1, 5, *r->s1, 0, 0, 4); + test(*r->s2, 1, 5, *r->s1, 0, 1, 4); + test(*r->s2, 1, 5, *r->s1, 1, 0, 0); + test(*r->s2, 1, 5, *r->s2, 0, 0, 4); + test(*r->s2, 1, 5, *r->s2, 0, 1, 1); + test(*r->s2, 1, 5, *r->s2, 0, 2, 1); + test(*r->s2, 1, 5, *r->s2, 0, 4, 1); + test(*r->s2, 1, 5, *r->s2, 0, 5, 1); + test(*r->s2, 1, 5, *r->s2, 0, 6, 1); + test(*r->s2, 1, 5, *r->s2, 1, 0, 4); + test(*r->s2, 1, 5, *r->s2, 1, 1, 3); + test(*r->s2, 1, 5, *r->s2, 1, 2, 2); + test(*r->s2, 1, 5, *r->s2, 1, 3, 1); + test(*r->s2, 1, 5, *r->s2, 1, 4, 0); + test(*r->s2, 1, 5, *r->s2, 1, 5, 0); + test(*r->s2, 1, 5, *r->s2, 2, 0, 4); + test(*r->s2, 1, 5, *r->s2, 2, 1, -1); + test(*r->s2, 1, 5, *r->s2, 2, 2, -1); + test(*r->s2, 1, 5, *r->s2, 2, 3, -1); + test(*r->s2, 1, 5, *r->s2, 2, 4, -1); + test(*r->s2, 1, 5, *r->s2, 4, 0, 4); + test(*r->s2, 1, 5, *r->s2, 4, 1, -3); + test(*r->s2, 1, 5, *r->s2, 4, 2, -3); + test(*r->s2, 1, 5, *r->s2, 5, 0, 4); + test(*r->s2, 1, 5, *r->s2, 5, 1, 4); + test(*r->s2, 1, 5, *r->s2, 6, 0, 0); + test(*r->s2, 1, 5, *r->s3, 0, 0, 4); + test(*r->s2, 1, 5, *r->s3, 0, 1, 1); + test(*r->s2, 1, 5, *r->s3, 0, 5, 1); + test(*r->s2, 1, 5, *r->s3, 0, 9, 1); + test(*r->s2, 1, 5, *r->s3, 0, 10, 1); + test(*r->s2, 1, 5, *r->s3, 0, 11, 1); + test(*r->s2, 1, 5, *r->s3, 1, 0, 4); + test(*r->s2, 1, 5, *r->s3, 1, 1, 3); + test(*r->s2, 1, 5, *r->s3, 1, 4, 0); + test(*r->s2, 1, 5, *r->s3, 1, 8, -4); + test(*r->s2, 1, 5, *r->s3, 1, 9, -5); + test(*r->s2, 1, 5, *r->s3, 1, 10, -5); + test(*r->s2, 1, 5, *r->s3, 5, 0, 4); + test(*r->s2, 1, 5, *r->s3, 5, 1, -4); + test(*r->s2, 1, 5, *r->s3, 5, 2, -4); + test(*r->s2, 1, 5, *r->s3, 5, 4, -4); + test(*r->s2, 1, 5, *r->s3, 5, 5, -4); + test(*r->s2, 1, 5, *r->s3, 5, 6, -4); + test(*r->s2, 1, 5, *r->s3, 9, 0, 4); + test(*r->s2, 1, 5, *r->s3, 9, 1, -8); + test(*r->s2, 1, 5, *r->s3, 9, 2, -8); + test(*r->s2, 1, 5, *r->s3, 10, 0, 4); + test(*r->s2, 1, 5, *r->s3, 10, 1, 4); + test(*r->s2, 1, 5, *r->s3, 11, 0, 0); + test(*r->s2, 1, 5, *r->s4, 0, 0, 4); + test(*r->s2, 1, 5, *r->s4, 0, 1, 1); + test(*r->s2, 1, 5, *r->s4, 0, 10, 1); + test(*r->s2, 1, 5, *r->s4, 0, 19, 1); + test(*r->s2, 1, 5, *r->s4, 0, 20, 1); + test(*r->s2, 1, 5, *r->s4, 0, 21, 1); + test(*r->s2, 1, 5, *r->s4, 1, 0, 4); + test(*r->s2, 1, 5, *r->s4, 1, 1, 3); + test(*r->s2, 1, 5, *r->s4, 1, 9, -5); + test(*r->s2, 1, 5, *r->s4, 1, 18, -14); + test(*r->s2, 1, 5, *r->s4, 1, 19, -15); + test(*r->s2, 1, 5, *r->s4, 1, 20, -15); + test(*r->s2, 1, 5, *r->s4, 10, 0, 4); + test(*r->s2, 1, 5, *r->s4, 10, 1, -9); +} + +template +void +test11(pmem::obj::persistent_ptr &r) +{ + test(*r->s2, 1, 5, *r->s4, 10, 5, -9); + test(*r->s2, 1, 5, *r->s4, 10, 9, -9); + test(*r->s2, 1, 5, *r->s4, 10, 10, -9); + test(*r->s2, 1, 5, *r->s4, 10, 11, -9); + test(*r->s2, 1, 5, *r->s4, 19, 0, 4); + test(*r->s2, 1, 5, *r->s4, 19, 1, -18); + test(*r->s2, 1, 5, *r->s4, 19, 2, -18); + test(*r->s2, 1, 5, *r->s4, 20, 0, 4); + test(*r->s2, 1, 5, *r->s4, 20, 1, 4); + test(*r->s2, 1, 5, *r->s4, 21, 0, 0); + test(*r->s2, 2, 0, *r->s1, 0, 0, 0); + test(*r->s2, 2, 0, *r->s1, 0, 1, 0); + test(*r->s2, 2, 0, *r->s1, 1, 0, 0); + test(*r->s2, 2, 0, *r->s2, 0, 0, 0); + test(*r->s2, 2, 0, *r->s2, 0, 1, -1); + test(*r->s2, 2, 0, *r->s2, 0, 2, -2); + test(*r->s2, 2, 0, *r->s2, 0, 4, -4); + test(*r->s2, 2, 0, *r->s2, 0, 5, -5); + test(*r->s2, 2, 0, *r->s2, 0, 6, -5); + test(*r->s2, 2, 0, *r->s2, 1, 0, 0); + test(*r->s2, 2, 0, *r->s2, 1, 1, -1); + test(*r->s2, 2, 0, *r->s2, 1, 2, -2); + test(*r->s2, 2, 0, *r->s2, 1, 3, -3); + test(*r->s2, 2, 0, *r->s2, 1, 4, -4); + test(*r->s2, 2, 0, *r->s2, 1, 5, -4); + test(*r->s2, 2, 0, *r->s2, 2, 0, 0); + test(*r->s2, 2, 0, *r->s2, 2, 1, -1); + test(*r->s2, 2, 0, *r->s2, 2, 2, -2); + test(*r->s2, 2, 0, *r->s2, 2, 3, -3); + test(*r->s2, 2, 0, *r->s2, 2, 4, -3); + test(*r->s2, 2, 0, *r->s2, 4, 0, 0); + test(*r->s2, 2, 0, *r->s2, 4, 1, -1); + test(*r->s2, 2, 0, *r->s2, 4, 2, -1); + test(*r->s2, 2, 0, *r->s2, 5, 0, 0); + test(*r->s2, 2, 0, *r->s2, 5, 1, 0); + test(*r->s2, 2, 0, *r->s2, 6, 0, 0); + test(*r->s2, 2, 0, *r->s3, 0, 0, 0); + test(*r->s2, 2, 0, *r->s3, 0, 1, -1); + test(*r->s2, 2, 0, *r->s3, 0, 5, -5); + test(*r->s2, 2, 0, *r->s3, 0, 9, -9); + test(*r->s2, 2, 0, *r->s3, 0, 10, -10); + test(*r->s2, 2, 0, *r->s3, 0, 11, -10); + test(*r->s2, 2, 0, *r->s3, 1, 0, 0); + test(*r->s2, 2, 0, *r->s3, 1, 1, -1); + test(*r->s2, 2, 0, *r->s3, 1, 4, -4); + test(*r->s2, 2, 0, *r->s3, 1, 8, -8); + test(*r->s2, 2, 0, *r->s3, 1, 9, -9); + test(*r->s2, 2, 0, *r->s3, 1, 10, -9); + test(*r->s2, 2, 0, *r->s3, 5, 0, 0); + test(*r->s2, 2, 0, *r->s3, 5, 1, -1); + test(*r->s2, 2, 0, *r->s3, 5, 2, -2); + test(*r->s2, 2, 0, *r->s3, 5, 4, -4); + test(*r->s2, 2, 0, *r->s3, 5, 5, -5); + test(*r->s2, 2, 0, *r->s3, 5, 6, -5); + test(*r->s2, 2, 0, *r->s3, 9, 0, 0); + test(*r->s2, 2, 0, *r->s3, 9, 1, -1); + test(*r->s2, 2, 0, *r->s3, 9, 2, -1); + test(*r->s2, 2, 0, *r->s3, 10, 0, 0); + test(*r->s2, 2, 0, *r->s3, 10, 1, 0); + test(*r->s2, 2, 0, *r->s3, 11, 0, 0); + test(*r->s2, 2, 0, *r->s4, 0, 0, 0); + test(*r->s2, 2, 0, *r->s4, 0, 1, -1); + test(*r->s2, 2, 0, *r->s4, 0, 10, -10); + test(*r->s2, 2, 0, *r->s4, 0, 19, -19); + test(*r->s2, 2, 0, *r->s4, 0, 20, -20); + test(*r->s2, 2, 0, *r->s4, 0, 21, -20); + test(*r->s2, 2, 0, *r->s4, 1, 0, 0); + test(*r->s2, 2, 0, *r->s4, 1, 1, -1); + test(*r->s2, 2, 0, *r->s4, 1, 9, -9); + test(*r->s2, 2, 0, *r->s4, 1, 18, -18); + test(*r->s2, 2, 0, *r->s4, 1, 19, -19); + test(*r->s2, 2, 0, *r->s4, 1, 20, -19); + test(*r->s2, 2, 0, *r->s4, 10, 0, 0); + test(*r->s2, 2, 0, *r->s4, 10, 1, -1); + test(*r->s2, 2, 0, *r->s4, 10, 5, -5); + test(*r->s2, 2, 0, *r->s4, 10, 9, -9); + test(*r->s2, 2, 0, *r->s4, 10, 10, -10); + test(*r->s2, 2, 0, *r->s4, 10, 11, -10); + test(*r->s2, 2, 0, *r->s4, 19, 0, 0); + test(*r->s2, 2, 0, *r->s4, 19, 1, -1); + test(*r->s2, 2, 0, *r->s4, 19, 2, -1); + test(*r->s2, 2, 0, *r->s4, 20, 0, 0); + test(*r->s2, 2, 0, *r->s4, 20, 1, 0); + test(*r->s2, 2, 0, *r->s4, 21, 0, 0); + test(*r->s2, 2, 1, *r->s1, 0, 0, 1); + test(*r->s2, 2, 1, *r->s1, 0, 1, 1); + test(*r->s2, 2, 1, *r->s1, 1, 0, 0); + test(*r->s2, 2, 1, *r->s2, 0, 0, 1); + test(*r->s2, 2, 1, *r->s2, 0, 1, 2); + test(*r->s2, 2, 1, *r->s2, 0, 2, 2); + test(*r->s2, 2, 1, *r->s2, 0, 4, 2); + test(*r->s2, 2, 1, *r->s2, 0, 5, 2); + test(*r->s2, 2, 1, *r->s2, 0, 6, 2); + test(*r->s2, 2, 1, *r->s2, 1, 0, 1); + test(*r->s2, 2, 1, *r->s2, 1, 1, 1); + test(*r->s2, 2, 1, *r->s2, 1, 2, 1); + test(*r->s2, 2, 1, *r->s2, 1, 3, 1); + test(*r->s2, 2, 1, *r->s2, 1, 4, 1); + test(*r->s2, 2, 1, *r->s2, 1, 5, 1); + test(*r->s2, 2, 1, *r->s2, 2, 0, 1); +} + +template +void +test12(pmem::obj::persistent_ptr &r) +{ + test(*r->s2, 2, 1, *r->s2, 2, 1, 0); + test(*r->s2, 2, 1, *r->s2, 2, 2, -1); + test(*r->s2, 2, 1, *r->s2, 2, 3, -2); + test(*r->s2, 2, 1, *r->s2, 2, 4, -2); + test(*r->s2, 2, 1, *r->s2, 4, 0, 1); + test(*r->s2, 2, 1, *r->s2, 4, 1, -2); + test(*r->s2, 2, 1, *r->s2, 4, 2, -2); + test(*r->s2, 2, 1, *r->s2, 5, 0, 1); + test(*r->s2, 2, 1, *r->s2, 5, 1, 1); + test(*r->s2, 2, 1, *r->s2, 6, 0, 0); + test(*r->s2, 2, 1, *r->s3, 0, 0, 1); + test(*r->s2, 2, 1, *r->s3, 0, 1, 2); + test(*r->s2, 2, 1, *r->s3, 0, 5, 2); + test(*r->s2, 2, 1, *r->s3, 0, 9, 2); + test(*r->s2, 2, 1, *r->s3, 0, 10, 2); + test(*r->s2, 2, 1, *r->s3, 0, 11, 2); + test(*r->s2, 2, 1, *r->s3, 1, 0, 1); + test(*r->s2, 2, 1, *r->s3, 1, 1, 1); + test(*r->s2, 2, 1, *r->s3, 1, 4, 1); + test(*r->s2, 2, 1, *r->s3, 1, 8, 1); + test(*r->s2, 2, 1, *r->s3, 1, 9, 1); + test(*r->s2, 2, 1, *r->s3, 1, 10, 1); + test(*r->s2, 2, 1, *r->s3, 5, 0, 1); + test(*r->s2, 2, 1, *r->s3, 5, 1, -3); + test(*r->s2, 2, 1, *r->s3, 5, 2, -3); + test(*r->s2, 2, 1, *r->s3, 5, 4, -3); + test(*r->s2, 2, 1, *r->s3, 5, 5, -3); + test(*r->s2, 2, 1, *r->s3, 5, 6, -3); + test(*r->s2, 2, 1, *r->s3, 9, 0, 1); + test(*r->s2, 2, 1, *r->s3, 9, 1, -7); + test(*r->s2, 2, 1, *r->s3, 9, 2, -7); + test(*r->s2, 2, 1, *r->s3, 10, 0, 1); + test(*r->s2, 2, 1, *r->s3, 10, 1, 1); + test(*r->s2, 2, 1, *r->s3, 11, 0, 0); + test(*r->s2, 2, 1, *r->s4, 0, 0, 1); + test(*r->s2, 2, 1, *r->s4, 0, 1, 2); + test(*r->s2, 2, 1, *r->s4, 0, 10, 2); + test(*r->s2, 2, 1, *r->s4, 0, 19, 2); + test(*r->s2, 2, 1, *r->s4, 0, 20, 2); + test(*r->s2, 2, 1, *r->s4, 0, 21, 2); + test(*r->s2, 2, 1, *r->s4, 1, 0, 1); + test(*r->s2, 2, 1, *r->s4, 1, 1, 1); + test(*r->s2, 2, 1, *r->s4, 1, 9, 1); + test(*r->s2, 2, 1, *r->s4, 1, 18, 1); + test(*r->s2, 2, 1, *r->s4, 1, 19, 1); + test(*r->s2, 2, 1, *r->s4, 1, 20, 1); + test(*r->s2, 2, 1, *r->s4, 10, 0, 1); + test(*r->s2, 2, 1, *r->s4, 10, 1, -8); + test(*r->s2, 2, 1, *r->s4, 10, 5, -8); + test(*r->s2, 2, 1, *r->s4, 10, 9, -8); + test(*r->s2, 2, 1, *r->s4, 10, 10, -8); + test(*r->s2, 2, 1, *r->s4, 10, 11, -8); + test(*r->s2, 2, 1, *r->s4, 19, 0, 1); + test(*r->s2, 2, 1, *r->s4, 19, 1, -17); + test(*r->s2, 2, 1, *r->s4, 19, 2, -17); + test(*r->s2, 2, 1, *r->s4, 20, 0, 1); + test(*r->s2, 2, 1, *r->s4, 20, 1, 1); + test(*r->s2, 2, 1, *r->s4, 21, 0, 0); + test(*r->s2, 2, 2, *r->s1, 0, 0, 2); + test(*r->s2, 2, 2, *r->s1, 0, 1, 2); + test(*r->s2, 2, 2, *r->s1, 1, 0, 0); + test(*r->s2, 2, 2, *r->s2, 0, 0, 2); + test(*r->s2, 2, 2, *r->s2, 0, 1, 2); + test(*r->s2, 2, 2, *r->s2, 0, 2, 2); + test(*r->s2, 2, 2, *r->s2, 0, 4, 2); + test(*r->s2, 2, 2, *r->s2, 0, 5, 2); + test(*r->s2, 2, 2, *r->s2, 0, 6, 2); + test(*r->s2, 2, 2, *r->s2, 1, 0, 2); + test(*r->s2, 2, 2, *r->s2, 1, 1, 1); + test(*r->s2, 2, 2, *r->s2, 1, 2, 1); + test(*r->s2, 2, 2, *r->s2, 1, 3, 1); + test(*r->s2, 2, 2, *r->s2, 1, 4, 1); + test(*r->s2, 2, 2, *r->s2, 1, 5, 1); + test(*r->s2, 2, 2, *r->s2, 2, 0, 2); + test(*r->s2, 2, 2, *r->s2, 2, 1, 1); + test(*r->s2, 2, 2, *r->s2, 2, 2, 0); + test(*r->s2, 2, 2, *r->s2, 2, 3, -1); + test(*r->s2, 2, 2, *r->s2, 2, 4, -1); + test(*r->s2, 2, 2, *r->s2, 4, 0, 2); + test(*r->s2, 2, 2, *r->s2, 4, 1, -2); + test(*r->s2, 2, 2, *r->s2, 4, 2, -2); + test(*r->s2, 2, 2, *r->s2, 5, 0, 2); + test(*r->s2, 2, 2, *r->s2, 5, 1, 2); + test(*r->s2, 2, 2, *r->s2, 6, 0, 0); + test(*r->s2, 2, 2, *r->s3, 0, 0, 2); + test(*r->s2, 2, 2, *r->s3, 0, 1, 2); + test(*r->s2, 2, 2, *r->s3, 0, 5, 2); + test(*r->s2, 2, 2, *r->s3, 0, 9, 2); + test(*r->s2, 2, 2, *r->s3, 0, 10, 2); + test(*r->s2, 2, 2, *r->s3, 0, 11, 2); + test(*r->s2, 2, 2, *r->s3, 1, 0, 2); + test(*r->s2, 2, 2, *r->s3, 1, 1, 1); + test(*r->s2, 2, 2, *r->s3, 1, 4, 1); + test(*r->s2, 2, 2, *r->s3, 1, 8, 1); + test(*r->s2, 2, 2, *r->s3, 1, 9, 1); + test(*r->s2, 2, 2, *r->s3, 1, 10, 1); + test(*r->s2, 2, 2, *r->s3, 5, 0, 2); + test(*r->s2, 2, 2, *r->s3, 5, 1, -3); + test(*r->s2, 2, 2, *r->s3, 5, 2, -3); + test(*r->s2, 2, 2, *r->s3, 5, 4, -3); +} + +template +void +test13(pmem::obj::persistent_ptr &r) +{ + test(*r->s2, 2, 2, *r->s3, 5, 5, -3); + test(*r->s2, 2, 2, *r->s3, 5, 6, -3); + test(*r->s2, 2, 2, *r->s3, 9, 0, 2); + test(*r->s2, 2, 2, *r->s3, 9, 1, -7); + test(*r->s2, 2, 2, *r->s3, 9, 2, -7); + test(*r->s2, 2, 2, *r->s3, 10, 0, 2); + test(*r->s2, 2, 2, *r->s3, 10, 1, 2); + test(*r->s2, 2, 2, *r->s3, 11, 0, 0); + test(*r->s2, 2, 2, *r->s4, 0, 0, 2); + test(*r->s2, 2, 2, *r->s4, 0, 1, 2); + test(*r->s2, 2, 2, *r->s4, 0, 10, 2); + test(*r->s2, 2, 2, *r->s4, 0, 19, 2); + test(*r->s2, 2, 2, *r->s4, 0, 20, 2); + test(*r->s2, 2, 2, *r->s4, 0, 21, 2); + test(*r->s2, 2, 2, *r->s4, 1, 0, 2); + test(*r->s2, 2, 2, *r->s4, 1, 1, 1); + test(*r->s2, 2, 2, *r->s4, 1, 9, 1); + test(*r->s2, 2, 2, *r->s4, 1, 18, 1); + test(*r->s2, 2, 2, *r->s4, 1, 19, 1); + test(*r->s2, 2, 2, *r->s4, 1, 20, 1); + test(*r->s2, 2, 2, *r->s4, 10, 0, 2); + test(*r->s2, 2, 2, *r->s4, 10, 1, -8); + test(*r->s2, 2, 2, *r->s4, 10, 5, -8); + test(*r->s2, 2, 2, *r->s4, 10, 9, -8); + test(*r->s2, 2, 2, *r->s4, 10, 10, -8); + test(*r->s2, 2, 2, *r->s4, 10, 11, -8); + test(*r->s2, 2, 2, *r->s4, 19, 0, 2); + test(*r->s2, 2, 2, *r->s4, 19, 1, -17); + test(*r->s2, 2, 2, *r->s4, 19, 2, -17); + test(*r->s2, 2, 2, *r->s4, 20, 0, 2); + test(*r->s2, 2, 2, *r->s4, 20, 1, 2); + test(*r->s2, 2, 2, *r->s4, 21, 0, 0); + test(*r->s2, 2, 3, *r->s1, 0, 0, 3); + test(*r->s2, 2, 3, *r->s1, 0, 1, 3); + test(*r->s2, 2, 3, *r->s1, 1, 0, 0); + test(*r->s2, 2, 3, *r->s2, 0, 0, 3); + test(*r->s2, 2, 3, *r->s2, 0, 1, 2); + test(*r->s2, 2, 3, *r->s2, 0, 2, 2); + test(*r->s2, 2, 3, *r->s2, 0, 4, 2); + test(*r->s2, 2, 3, *r->s2, 0, 5, 2); + test(*r->s2, 2, 3, *r->s2, 0, 6, 2); + test(*r->s2, 2, 3, *r->s2, 1, 0, 3); + test(*r->s2, 2, 3, *r->s2, 1, 1, 1); + test(*r->s2, 2, 3, *r->s2, 1, 2, 1); + test(*r->s2, 2, 3, *r->s2, 1, 3, 1); + test(*r->s2, 2, 3, *r->s2, 1, 4, 1); + test(*r->s2, 2, 3, *r->s2, 1, 5, 1); + test(*r->s2, 2, 3, *r->s2, 2, 0, 3); + test(*r->s2, 2, 3, *r->s2, 2, 1, 2); + test(*r->s2, 2, 3, *r->s2, 2, 2, 1); + test(*r->s2, 2, 3, *r->s2, 2, 3, 0); + test(*r->s2, 2, 3, *r->s2, 2, 4, 0); + test(*r->s2, 2, 3, *r->s2, 4, 0, 3); + test(*r->s2, 2, 3, *r->s2, 4, 1, -2); + test(*r->s2, 2, 3, *r->s2, 4, 2, -2); + test(*r->s2, 2, 3, *r->s2, 5, 0, 3); + test(*r->s2, 2, 3, *r->s2, 5, 1, 3); + test(*r->s2, 2, 3, *r->s2, 6, 0, 0); + test(*r->s2, 2, 3, *r->s3, 0, 0, 3); + test(*r->s2, 2, 3, *r->s3, 0, 1, 2); + test(*r->s2, 2, 3, *r->s3, 0, 5, 2); + test(*r->s2, 2, 3, *r->s3, 0, 9, 2); + test(*r->s2, 2, 3, *r->s3, 0, 10, 2); + test(*r->s2, 2, 3, *r->s3, 0, 11, 2); + test(*r->s2, 2, 3, *r->s3, 1, 0, 3); + test(*r->s2, 2, 3, *r->s3, 1, 1, 1); + test(*r->s2, 2, 3, *r->s3, 1, 4, 1); + test(*r->s2, 2, 3, *r->s3, 1, 8, 1); + test(*r->s2, 2, 3, *r->s3, 1, 9, 1); + test(*r->s2, 2, 3, *r->s3, 1, 10, 1); + test(*r->s2, 2, 3, *r->s3, 5, 0, 3); + test(*r->s2, 2, 3, *r->s3, 5, 1, -3); + test(*r->s2, 2, 3, *r->s3, 5, 2, -3); + test(*r->s2, 2, 3, *r->s3, 5, 4, -3); + test(*r->s2, 2, 3, *r->s3, 5, 5, -3); + test(*r->s2, 2, 3, *r->s3, 5, 6, -3); + test(*r->s2, 2, 3, *r->s3, 9, 0, 3); + test(*r->s2, 2, 3, *r->s3, 9, 1, -7); + test(*r->s2, 2, 3, *r->s3, 9, 2, -7); + test(*r->s2, 2, 3, *r->s3, 10, 0, 3); + test(*r->s2, 2, 3, *r->s3, 10, 1, 3); + test(*r->s2, 2, 3, *r->s3, 11, 0, 0); + test(*r->s2, 2, 3, *r->s4, 0, 0, 3); + test(*r->s2, 2, 3, *r->s4, 0, 1, 2); + test(*r->s2, 2, 3, *r->s4, 0, 10, 2); + test(*r->s2, 2, 3, *r->s4, 0, 19, 2); + test(*r->s2, 2, 3, *r->s4, 0, 20, 2); + test(*r->s2, 2, 3, *r->s4, 0, 21, 2); + test(*r->s2, 2, 3, *r->s4, 1, 0, 3); + test(*r->s2, 2, 3, *r->s4, 1, 1, 1); + test(*r->s2, 2, 3, *r->s4, 1, 9, 1); + test(*r->s2, 2, 3, *r->s4, 1, 18, 1); + test(*r->s2, 2, 3, *r->s4, 1, 19, 1); + test(*r->s2, 2, 3, *r->s4, 1, 20, 1); + test(*r->s2, 2, 3, *r->s4, 10, 0, 3); + test(*r->s2, 2, 3, *r->s4, 10, 1, -8); + test(*r->s2, 2, 3, *r->s4, 10, 5, -8); + test(*r->s2, 2, 3, *r->s4, 10, 9, -8); + test(*r->s2, 2, 3, *r->s4, 10, 10, -8); + test(*r->s2, 2, 3, *r->s4, 10, 11, -8); +} + +template +void +test14(pmem::obj::persistent_ptr &r) +{ + test(*r->s2, 2, 3, *r->s4, 19, 0, 3); + test(*r->s2, 2, 3, *r->s4, 19, 1, -17); + test(*r->s2, 2, 3, *r->s4, 19, 2, -17); + test(*r->s2, 2, 3, *r->s4, 20, 0, 3); + test(*r->s2, 2, 3, *r->s4, 20, 1, 3); + test(*r->s2, 2, 3, *r->s4, 21, 0, 0); + test(*r->s2, 2, 4, *r->s1, 0, 0, 3); + test(*r->s2, 2, 4, *r->s1, 0, 1, 3); + test(*r->s2, 2, 4, *r->s1, 1, 0, 0); + test(*r->s2, 2, 4, *r->s2, 0, 0, 3); + test(*r->s2, 2, 4, *r->s2, 0, 1, 2); + test(*r->s2, 2, 4, *r->s2, 0, 2, 2); + test(*r->s2, 2, 4, *r->s2, 0, 4, 2); + test(*r->s2, 2, 4, *r->s2, 0, 5, 2); + test(*r->s2, 2, 4, *r->s2, 0, 6, 2); + test(*r->s2, 2, 4, *r->s2, 1, 0, 3); + test(*r->s2, 2, 4, *r->s2, 1, 1, 1); + test(*r->s2, 2, 4, *r->s2, 1, 2, 1); + test(*r->s2, 2, 4, *r->s2, 1, 3, 1); + test(*r->s2, 2, 4, *r->s2, 1, 4, 1); + test(*r->s2, 2, 4, *r->s2, 1, 5, 1); + test(*r->s2, 2, 4, *r->s2, 2, 0, 3); + test(*r->s2, 2, 4, *r->s2, 2, 1, 2); + test(*r->s2, 2, 4, *r->s2, 2, 2, 1); + test(*r->s2, 2, 4, *r->s2, 2, 3, 0); + test(*r->s2, 2, 4, *r->s2, 2, 4, 0); + test(*r->s2, 2, 4, *r->s2, 4, 0, 3); + test(*r->s2, 2, 4, *r->s2, 4, 1, -2); + test(*r->s2, 2, 4, *r->s2, 4, 2, -2); + test(*r->s2, 2, 4, *r->s2, 5, 0, 3); + test(*r->s2, 2, 4, *r->s2, 5, 1, 3); + test(*r->s2, 2, 4, *r->s2, 6, 0, 0); + test(*r->s2, 2, 4, *r->s3, 0, 0, 3); + test(*r->s2, 2, 4, *r->s3, 0, 1, 2); + test(*r->s2, 2, 4, *r->s3, 0, 5, 2); + test(*r->s2, 2, 4, *r->s3, 0, 9, 2); + test(*r->s2, 2, 4, *r->s3, 0, 10, 2); + test(*r->s2, 2, 4, *r->s3, 0, 11, 2); + test(*r->s2, 2, 4, *r->s3, 1, 0, 3); + test(*r->s2, 2, 4, *r->s3, 1, 1, 1); + test(*r->s2, 2, 4, *r->s3, 1, 4, 1); + test(*r->s2, 2, 4, *r->s3, 1, 8, 1); + test(*r->s2, 2, 4, *r->s3, 1, 9, 1); + test(*r->s2, 2, 4, *r->s3, 1, 10, 1); + test(*r->s2, 2, 4, *r->s3, 5, 0, 3); + test(*r->s2, 2, 4, *r->s3, 5, 1, -3); + test(*r->s2, 2, 4, *r->s3, 5, 2, -3); + test(*r->s2, 2, 4, *r->s3, 5, 4, -3); + test(*r->s2, 2, 4, *r->s3, 5, 5, -3); + test(*r->s2, 2, 4, *r->s3, 5, 6, -3); + test(*r->s2, 2, 4, *r->s3, 9, 0, 3); + test(*r->s2, 2, 4, *r->s3, 9, 1, -7); + test(*r->s2, 2, 4, *r->s3, 9, 2, -7); + test(*r->s2, 2, 4, *r->s3, 10, 0, 3); + test(*r->s2, 2, 4, *r->s3, 10, 1, 3); + test(*r->s2, 2, 4, *r->s3, 11, 0, 0); + test(*r->s2, 2, 4, *r->s4, 0, 0, 3); + test(*r->s2, 2, 4, *r->s4, 0, 1, 2); + test(*r->s2, 2, 4, *r->s4, 0, 10, 2); + test(*r->s2, 2, 4, *r->s4, 0, 19, 2); + test(*r->s2, 2, 4, *r->s4, 0, 20, 2); + test(*r->s2, 2, 4, *r->s4, 0, 21, 2); + test(*r->s2, 2, 4, *r->s4, 1, 0, 3); + test(*r->s2, 2, 4, *r->s4, 1, 1, 1); + test(*r->s2, 2, 4, *r->s4, 1, 9, 1); + test(*r->s2, 2, 4, *r->s4, 1, 18, 1); + test(*r->s2, 2, 4, *r->s4, 1, 19, 1); + test(*r->s2, 2, 4, *r->s4, 1, 20, 1); + test(*r->s2, 2, 4, *r->s4, 10, 0, 3); + test(*r->s2, 2, 4, *r->s4, 10, 1, -8); + test(*r->s2, 2, 4, *r->s4, 10, 5, -8); + test(*r->s2, 2, 4, *r->s4, 10, 9, -8); + test(*r->s2, 2, 4, *r->s4, 10, 10, -8); + test(*r->s2, 2, 4, *r->s4, 10, 11, -8); + test(*r->s2, 2, 4, *r->s4, 19, 0, 3); + test(*r->s2, 2, 4, *r->s4, 19, 1, -17); + test(*r->s2, 2, 4, *r->s4, 19, 2, -17); + test(*r->s2, 2, 4, *r->s4, 20, 0, 3); + test(*r->s2, 2, 4, *r->s4, 20, 1, 3); + test(*r->s2, 2, 4, *r->s4, 21, 0, 0); + test(*r->s2, 4, 0, *r->s1, 0, 0, 0); + test(*r->s2, 4, 0, *r->s1, 0, 1, 0); + test(*r->s2, 4, 0, *r->s1, 1, 0, 0); + test(*r->s2, 4, 0, *r->s2, 0, 0, 0); + test(*r->s2, 4, 0, *r->s2, 0, 1, -1); + test(*r->s2, 4, 0, *r->s2, 0, 2, -2); + test(*r->s2, 4, 0, *r->s2, 0, 4, -4); + test(*r->s2, 4, 0, *r->s2, 0, 5, -5); + test(*r->s2, 4, 0, *r->s2, 0, 6, -5); + test(*r->s2, 4, 0, *r->s2, 1, 0, 0); + test(*r->s2, 4, 0, *r->s2, 1, 1, -1); + test(*r->s2, 4, 0, *r->s2, 1, 2, -2); + test(*r->s2, 4, 0, *r->s2, 1, 3, -3); + test(*r->s2, 4, 0, *r->s2, 1, 4, -4); + test(*r->s2, 4, 0, *r->s2, 1, 5, -4); + test(*r->s2, 4, 0, *r->s2, 2, 0, 0); + test(*r->s2, 4, 0, *r->s2, 2, 1, -1); + test(*r->s2, 4, 0, *r->s2, 2, 2, -2); + test(*r->s2, 4, 0, *r->s2, 2, 3, -3); + test(*r->s2, 4, 0, *r->s2, 2, 4, -3); +} + +template +void +test15(pmem::obj::persistent_ptr &r) +{ + test(*r->s2, 4, 0, *r->s2, 4, 0, 0); + test(*r->s2, 4, 0, *r->s2, 4, 1, -1); + test(*r->s2, 4, 0, *r->s2, 4, 2, -1); + test(*r->s2, 4, 0, *r->s2, 5, 0, 0); + test(*r->s2, 4, 0, *r->s2, 5, 1, 0); + test(*r->s2, 4, 0, *r->s2, 6, 0, 0); + test(*r->s2, 4, 0, *r->s3, 0, 0, 0); + test(*r->s2, 4, 0, *r->s3, 0, 1, -1); + test(*r->s2, 4, 0, *r->s3, 0, 5, -5); + test(*r->s2, 4, 0, *r->s3, 0, 9, -9); + test(*r->s2, 4, 0, *r->s3, 0, 10, -10); + test(*r->s2, 4, 0, *r->s3, 0, 11, -10); + test(*r->s2, 4, 0, *r->s3, 1, 0, 0); + test(*r->s2, 4, 0, *r->s3, 1, 1, -1); + test(*r->s2, 4, 0, *r->s3, 1, 4, -4); + test(*r->s2, 4, 0, *r->s3, 1, 8, -8); + test(*r->s2, 4, 0, *r->s3, 1, 9, -9); + test(*r->s2, 4, 0, *r->s3, 1, 10, -9); + test(*r->s2, 4, 0, *r->s3, 5, 0, 0); + test(*r->s2, 4, 0, *r->s3, 5, 1, -1); + test(*r->s2, 4, 0, *r->s3, 5, 2, -2); + test(*r->s2, 4, 0, *r->s3, 5, 4, -4); + test(*r->s2, 4, 0, *r->s3, 5, 5, -5); + test(*r->s2, 4, 0, *r->s3, 5, 6, -5); + test(*r->s2, 4, 0, *r->s3, 9, 0, 0); + test(*r->s2, 4, 0, *r->s3, 9, 1, -1); + test(*r->s2, 4, 0, *r->s3, 9, 2, -1); + test(*r->s2, 4, 0, *r->s3, 10, 0, 0); + test(*r->s2, 4, 0, *r->s3, 10, 1, 0); + test(*r->s2, 4, 0, *r->s3, 11, 0, 0); + test(*r->s2, 4, 0, *r->s4, 0, 0, 0); + test(*r->s2, 4, 0, *r->s4, 0, 1, -1); + test(*r->s2, 4, 0, *r->s4, 0, 10, -10); + test(*r->s2, 4, 0, *r->s4, 0, 19, -19); + test(*r->s2, 4, 0, *r->s4, 0, 20, -20); + test(*r->s2, 4, 0, *r->s4, 0, 21, -20); + test(*r->s2, 4, 0, *r->s4, 1, 0, 0); + test(*r->s2, 4, 0, *r->s4, 1, 1, -1); + test(*r->s2, 4, 0, *r->s4, 1, 9, -9); + test(*r->s2, 4, 0, *r->s4, 1, 18, -18); + test(*r->s2, 4, 0, *r->s4, 1, 19, -19); + test(*r->s2, 4, 0, *r->s4, 1, 20, -19); + test(*r->s2, 4, 0, *r->s4, 10, 0, 0); + test(*r->s2, 4, 0, *r->s4, 10, 1, -1); + test(*r->s2, 4, 0, *r->s4, 10, 5, -5); + test(*r->s2, 4, 0, *r->s4, 10, 9, -9); + test(*r->s2, 4, 0, *r->s4, 10, 10, -10); + test(*r->s2, 4, 0, *r->s4, 10, 11, -10); + test(*r->s2, 4, 0, *r->s4, 19, 0, 0); + test(*r->s2, 4, 0, *r->s4, 19, 1, -1); + test(*r->s2, 4, 0, *r->s4, 19, 2, -1); + test(*r->s2, 4, 0, *r->s4, 20, 0, 0); + test(*r->s2, 4, 0, *r->s4, 20, 1, 0); + test(*r->s2, 4, 0, *r->s4, 21, 0, 0); + test(*r->s2, 4, 1, *r->s1, 0, 0, 1); + test(*r->s2, 4, 1, *r->s1, 0, 1, 1); + test(*r->s2, 4, 1, *r->s1, 1, 0, 0); + test(*r->s2, 4, 1, *r->s2, 0, 0, 1); + test(*r->s2, 4, 1, *r->s2, 0, 1, 4); + test(*r->s2, 4, 1, *r->s2, 0, 2, 4); + test(*r->s2, 4, 1, *r->s2, 0, 4, 4); + test(*r->s2, 4, 1, *r->s2, 0, 5, 4); + test(*r->s2, 4, 1, *r->s2, 0, 6, 4); + test(*r->s2, 4, 1, *r->s2, 1, 0, 1); + test(*r->s2, 4, 1, *r->s2, 1, 1, 3); + test(*r->s2, 4, 1, *r->s2, 1, 2, 3); + test(*r->s2, 4, 1, *r->s2, 1, 3, 3); + test(*r->s2, 4, 1, *r->s2, 1, 4, 3); + test(*r->s2, 4, 1, *r->s2, 1, 5, 3); + test(*r->s2, 4, 1, *r->s2, 2, 0, 1); + test(*r->s2, 4, 1, *r->s2, 2, 1, 2); + test(*r->s2, 4, 1, *r->s2, 2, 2, 2); + test(*r->s2, 4, 1, *r->s2, 2, 3, 2); + test(*r->s2, 4, 1, *r->s2, 2, 4, 2); + test(*r->s2, 4, 1, *r->s2, 4, 0, 1); + test(*r->s2, 4, 1, *r->s2, 4, 1, 0); + test(*r->s2, 4, 1, *r->s2, 4, 2, 0); + test(*r->s2, 4, 1, *r->s2, 5, 0, 1); + test(*r->s2, 4, 1, *r->s2, 5, 1, 1); + test(*r->s2, 4, 1, *r->s2, 6, 0, 0); + test(*r->s2, 4, 1, *r->s3, 0, 0, 1); + test(*r->s2, 4, 1, *r->s3, 0, 1, 4); + test(*r->s2, 4, 1, *r->s3, 0, 5, 4); + test(*r->s2, 4, 1, *r->s3, 0, 9, 4); + test(*r->s2, 4, 1, *r->s3, 0, 10, 4); + test(*r->s2, 4, 1, *r->s3, 0, 11, 4); + test(*r->s2, 4, 1, *r->s3, 1, 0, 1); + test(*r->s2, 4, 1, *r->s3, 1, 1, 3); + test(*r->s2, 4, 1, *r->s3, 1, 4, 3); + test(*r->s2, 4, 1, *r->s3, 1, 8, 3); + test(*r->s2, 4, 1, *r->s3, 1, 9, 3); + test(*r->s2, 4, 1, *r->s3, 1, 10, 3); + test(*r->s2, 4, 1, *r->s3, 5, 0, 1); + test(*r->s2, 4, 1, *r->s3, 5, 1, -1); + test(*r->s2, 4, 1, *r->s3, 5, 2, -1); + test(*r->s2, 4, 1, *r->s3, 5, 4, -1); + test(*r->s2, 4, 1, *r->s3, 5, 5, -1); + test(*r->s2, 4, 1, *r->s3, 5, 6, -1); + test(*r->s2, 4, 1, *r->s3, 9, 0, 1); + test(*r->s2, 4, 1, *r->s3, 9, 1, -5); +} + +template +void +test16(pmem::obj::persistent_ptr &r) +{ + test(*r->s2, 4, 1, *r->s3, 9, 2, -5); + test(*r->s2, 4, 1, *r->s3, 10, 0, 1); + test(*r->s2, 4, 1, *r->s3, 10, 1, 1); + test(*r->s2, 4, 1, *r->s3, 11, 0, 0); + test(*r->s2, 4, 1, *r->s4, 0, 0, 1); + test(*r->s2, 4, 1, *r->s4, 0, 1, 4); + test(*r->s2, 4, 1, *r->s4, 0, 10, 4); + test(*r->s2, 4, 1, *r->s4, 0, 19, 4); + test(*r->s2, 4, 1, *r->s4, 0, 20, 4); + test(*r->s2, 4, 1, *r->s4, 0, 21, 4); + test(*r->s2, 4, 1, *r->s4, 1, 0, 1); + test(*r->s2, 4, 1, *r->s4, 1, 1, 3); + test(*r->s2, 4, 1, *r->s4, 1, 9, 3); + test(*r->s2, 4, 1, *r->s4, 1, 18, 3); + test(*r->s2, 4, 1, *r->s4, 1, 19, 3); + test(*r->s2, 4, 1, *r->s4, 1, 20, 3); + test(*r->s2, 4, 1, *r->s4, 10, 0, 1); + test(*r->s2, 4, 1, *r->s4, 10, 1, -6); + test(*r->s2, 4, 1, *r->s4, 10, 5, -6); + test(*r->s2, 4, 1, *r->s4, 10, 9, -6); + test(*r->s2, 4, 1, *r->s4, 10, 10, -6); + test(*r->s2, 4, 1, *r->s4, 10, 11, -6); + test(*r->s2, 4, 1, *r->s4, 19, 0, 1); + test(*r->s2, 4, 1, *r->s4, 19, 1, -15); + test(*r->s2, 4, 1, *r->s4, 19, 2, -15); + test(*r->s2, 4, 1, *r->s4, 20, 0, 1); + test(*r->s2, 4, 1, *r->s4, 20, 1, 1); + test(*r->s2, 4, 1, *r->s4, 21, 0, 0); + test(*r->s2, 4, 2, *r->s1, 0, 0, 1); + test(*r->s2, 4, 2, *r->s1, 0, 1, 1); + test(*r->s2, 4, 2, *r->s1, 1, 0, 0); + test(*r->s2, 4, 2, *r->s2, 0, 0, 1); + test(*r->s2, 4, 2, *r->s2, 0, 1, 4); + test(*r->s2, 4, 2, *r->s2, 0, 2, 4); + test(*r->s2, 4, 2, *r->s2, 0, 4, 4); + test(*r->s2, 4, 2, *r->s2, 0, 5, 4); + test(*r->s2, 4, 2, *r->s2, 0, 6, 4); + test(*r->s2, 4, 2, *r->s2, 1, 0, 1); + test(*r->s2, 4, 2, *r->s2, 1, 1, 3); + test(*r->s2, 4, 2, *r->s2, 1, 2, 3); + test(*r->s2, 4, 2, *r->s2, 1, 3, 3); + test(*r->s2, 4, 2, *r->s2, 1, 4, 3); + test(*r->s2, 4, 2, *r->s2, 1, 5, 3); + test(*r->s2, 4, 2, *r->s2, 2, 0, 1); + test(*r->s2, 4, 2, *r->s2, 2, 1, 2); + test(*r->s2, 4, 2, *r->s2, 2, 2, 2); + test(*r->s2, 4, 2, *r->s2, 2, 3, 2); + test(*r->s2, 4, 2, *r->s2, 2, 4, 2); + test(*r->s2, 4, 2, *r->s2, 4, 0, 1); + test(*r->s2, 4, 2, *r->s2, 4, 1, 0); + test(*r->s2, 4, 2, *r->s2, 4, 2, 0); + test(*r->s2, 4, 2, *r->s2, 5, 0, 1); + test(*r->s2, 4, 2, *r->s2, 5, 1, 1); + test(*r->s2, 4, 2, *r->s2, 6, 0, 0); + test(*r->s2, 4, 2, *r->s3, 0, 0, 1); + test(*r->s2, 4, 2, *r->s3, 0, 1, 4); + test(*r->s2, 4, 2, *r->s3, 0, 5, 4); + test(*r->s2, 4, 2, *r->s3, 0, 9, 4); + test(*r->s2, 4, 2, *r->s3, 0, 10, 4); + test(*r->s2, 4, 2, *r->s3, 0, 11, 4); + test(*r->s2, 4, 2, *r->s3, 1, 0, 1); + test(*r->s2, 4, 2, *r->s3, 1, 1, 3); + test(*r->s2, 4, 2, *r->s3, 1, 4, 3); + test(*r->s2, 4, 2, *r->s3, 1, 8, 3); + test(*r->s2, 4, 2, *r->s3, 1, 9, 3); + test(*r->s2, 4, 2, *r->s3, 1, 10, 3); + test(*r->s2, 4, 2, *r->s3, 5, 0, 1); + test(*r->s2, 4, 2, *r->s3, 5, 1, -1); + test(*r->s2, 4, 2, *r->s3, 5, 2, -1); + test(*r->s2, 4, 2, *r->s3, 5, 4, -1); + test(*r->s2, 4, 2, *r->s3, 5, 5, -1); + test(*r->s2, 4, 2, *r->s3, 5, 6, -1); + test(*r->s2, 4, 2, *r->s3, 9, 0, 1); + test(*r->s2, 4, 2, *r->s3, 9, 1, -5); + test(*r->s2, 4, 2, *r->s3, 9, 2, -5); + test(*r->s2, 4, 2, *r->s3, 10, 0, 1); + test(*r->s2, 4, 2, *r->s3, 10, 1, 1); + test(*r->s2, 4, 2, *r->s3, 11, 0, 0); + test(*r->s2, 4, 2, *r->s4, 0, 0, 1); + test(*r->s2, 4, 2, *r->s4, 0, 1, 4); + test(*r->s2, 4, 2, *r->s4, 0, 10, 4); + test(*r->s2, 4, 2, *r->s4, 0, 19, 4); + test(*r->s2, 4, 2, *r->s4, 0, 20, 4); + test(*r->s2, 4, 2, *r->s4, 0, 21, 4); + test(*r->s2, 4, 2, *r->s4, 1, 0, 1); + test(*r->s2, 4, 2, *r->s4, 1, 1, 3); + test(*r->s2, 4, 2, *r->s4, 1, 9, 3); + test(*r->s2, 4, 2, *r->s4, 1, 18, 3); + test(*r->s2, 4, 2, *r->s4, 1, 19, 3); + test(*r->s2, 4, 2, *r->s4, 1, 20, 3); + test(*r->s2, 4, 2, *r->s4, 10, 0, 1); + test(*r->s2, 4, 2, *r->s4, 10, 1, -6); + test(*r->s2, 4, 2, *r->s4, 10, 5, -6); + test(*r->s2, 4, 2, *r->s4, 10, 9, -6); + test(*r->s2, 4, 2, *r->s4, 10, 10, -6); + test(*r->s2, 4, 2, *r->s4, 10, 11, -6); + test(*r->s2, 4, 2, *r->s4, 19, 0, 1); + test(*r->s2, 4, 2, *r->s4, 19, 1, -15); + test(*r->s2, 4, 2, *r->s4, 19, 2, -15); + test(*r->s2, 4, 2, *r->s4, 20, 0, 1); +} + +template +void +test17(pmem::obj::persistent_ptr &r) +{ + test(*r->s2, 4, 2, *r->s4, 20, 1, 1); + test(*r->s2, 4, 2, *r->s4, 21, 0, 0); + test(*r->s2, 5, 0, *r->s1, 0, 0, 0); + test(*r->s2, 5, 0, *r->s1, 0, 1, 0); + test(*r->s2, 5, 0, *r->s1, 1, 0, 0); + test(*r->s2, 5, 0, *r->s2, 0, 0, 0); + test(*r->s2, 5, 0, *r->s2, 0, 1, -1); + test(*r->s2, 5, 0, *r->s2, 0, 2, -2); + test(*r->s2, 5, 0, *r->s2, 0, 4, -4); + test(*r->s2, 5, 0, *r->s2, 0, 5, -5); + test(*r->s2, 5, 0, *r->s2, 0, 6, -5); + test(*r->s2, 5, 0, *r->s2, 1, 0, 0); + test(*r->s2, 5, 0, *r->s2, 1, 1, -1); + test(*r->s2, 5, 0, *r->s2, 1, 2, -2); + test(*r->s2, 5, 0, *r->s2, 1, 3, -3); + test(*r->s2, 5, 0, *r->s2, 1, 4, -4); + test(*r->s2, 5, 0, *r->s2, 1, 5, -4); + test(*r->s2, 5, 0, *r->s2, 2, 0, 0); + test(*r->s2, 5, 0, *r->s2, 2, 1, -1); + test(*r->s2, 5, 0, *r->s2, 2, 2, -2); + test(*r->s2, 5, 0, *r->s2, 2, 3, -3); + test(*r->s2, 5, 0, *r->s2, 2, 4, -3); + test(*r->s2, 5, 0, *r->s2, 4, 0, 0); + test(*r->s2, 5, 0, *r->s2, 4, 1, -1); + test(*r->s2, 5, 0, *r->s2, 4, 2, -1); + test(*r->s2, 5, 0, *r->s2, 5, 0, 0); + test(*r->s2, 5, 0, *r->s2, 5, 1, 0); + test(*r->s2, 5, 0, *r->s2, 6, 0, 0); + test(*r->s2, 5, 0, *r->s3, 0, 0, 0); + test(*r->s2, 5, 0, *r->s3, 0, 1, -1); + test(*r->s2, 5, 0, *r->s3, 0, 5, -5); + test(*r->s2, 5, 0, *r->s3, 0, 9, -9); + test(*r->s2, 5, 0, *r->s3, 0, 10, -10); + test(*r->s2, 5, 0, *r->s3, 0, 11, -10); + test(*r->s2, 5, 0, *r->s3, 1, 0, 0); + test(*r->s2, 5, 0, *r->s3, 1, 1, -1); + test(*r->s2, 5, 0, *r->s3, 1, 4, -4); + test(*r->s2, 5, 0, *r->s3, 1, 8, -8); + test(*r->s2, 5, 0, *r->s3, 1, 9, -9); + test(*r->s2, 5, 0, *r->s3, 1, 10, -9); + test(*r->s2, 5, 0, *r->s3, 5, 0, 0); + test(*r->s2, 5, 0, *r->s3, 5, 1, -1); + test(*r->s2, 5, 0, *r->s3, 5, 2, -2); + test(*r->s2, 5, 0, *r->s3, 5, 4, -4); + test(*r->s2, 5, 0, *r->s3, 5, 5, -5); + test(*r->s2, 5, 0, *r->s3, 5, 6, -5); + test(*r->s2, 5, 0, *r->s3, 9, 0, 0); + test(*r->s2, 5, 0, *r->s3, 9, 1, -1); + test(*r->s2, 5, 0, *r->s3, 9, 2, -1); + test(*r->s2, 5, 0, *r->s3, 10, 0, 0); + test(*r->s2, 5, 0, *r->s3, 10, 1, 0); + test(*r->s2, 5, 0, *r->s3, 11, 0, 0); + test(*r->s2, 5, 0, *r->s4, 0, 0, 0); + test(*r->s2, 5, 0, *r->s4, 0, 1, -1); + test(*r->s2, 5, 0, *r->s4, 0, 10, -10); + test(*r->s2, 5, 0, *r->s4, 0, 19, -19); + test(*r->s2, 5, 0, *r->s4, 0, 20, -20); + test(*r->s2, 5, 0, *r->s4, 0, 21, -20); + test(*r->s2, 5, 0, *r->s4, 1, 0, 0); + test(*r->s2, 5, 0, *r->s4, 1, 1, -1); + test(*r->s2, 5, 0, *r->s4, 1, 9, -9); + test(*r->s2, 5, 0, *r->s4, 1, 18, -18); + test(*r->s2, 5, 0, *r->s4, 1, 19, -19); + test(*r->s2, 5, 0, *r->s4, 1, 20, -19); + test(*r->s2, 5, 0, *r->s4, 10, 0, 0); + test(*r->s2, 5, 0, *r->s4, 10, 1, -1); + test(*r->s2, 5, 0, *r->s4, 10, 5, -5); + test(*r->s2, 5, 0, *r->s4, 10, 9, -9); + test(*r->s2, 5, 0, *r->s4, 10, 10, -10); + test(*r->s2, 5, 0, *r->s4, 10, 11, -10); + test(*r->s2, 5, 0, *r->s4, 19, 0, 0); + test(*r->s2, 5, 0, *r->s4, 19, 1, -1); + test(*r->s2, 5, 0, *r->s4, 19, 2, -1); + test(*r->s2, 5, 0, *r->s4, 20, 0, 0); + test(*r->s2, 5, 0, *r->s4, 20, 1, 0); + test(*r->s2, 5, 0, *r->s4, 21, 0, 0); + test(*r->s2, 5, 1, *r->s1, 0, 0, 0); + test(*r->s2, 5, 1, *r->s1, 0, 1, 0); + test(*r->s2, 5, 1, *r->s1, 1, 0, 0); + test(*r->s2, 5, 1, *r->s2, 0, 0, 0); + test(*r->s2, 5, 1, *r->s2, 0, 1, -1); + test(*r->s2, 5, 1, *r->s2, 0, 2, -2); + test(*r->s2, 5, 1, *r->s2, 0, 4, -4); + test(*r->s2, 5, 1, *r->s2, 0, 5, -5); + test(*r->s2, 5, 1, *r->s2, 0, 6, -5); + test(*r->s2, 5, 1, *r->s2, 1, 0, 0); + test(*r->s2, 5, 1, *r->s2, 1, 1, -1); + test(*r->s2, 5, 1, *r->s2, 1, 2, -2); + test(*r->s2, 5, 1, *r->s2, 1, 3, -3); + test(*r->s2, 5, 1, *r->s2, 1, 4, -4); + test(*r->s2, 5, 1, *r->s2, 1, 5, -4); + test(*r->s2, 5, 1, *r->s2, 2, 0, 0); + test(*r->s2, 5, 1, *r->s2, 2, 1, -1); + test(*r->s2, 5, 1, *r->s2, 2, 2, -2); + test(*r->s2, 5, 1, *r->s2, 2, 3, -3); + test(*r->s2, 5, 1, *r->s2, 2, 4, -3); + test(*r->s2, 5, 1, *r->s2, 4, 0, 0); + test(*r->s2, 5, 1, *r->s2, 4, 1, -1); + test(*r->s2, 5, 1, *r->s2, 4, 2, -1); + test(*r->s2, 5, 1, *r->s2, 5, 0, 0); +} + +template +void +test18(pmem::obj::persistent_ptr &r) +{ + test(*r->s2, 5, 1, *r->s2, 5, 1, 0); + test(*r->s2, 5, 1, *r->s2, 6, 0, 0); + test(*r->s2, 5, 1, *r->s3, 0, 0, 0); + test(*r->s2, 5, 1, *r->s3, 0, 1, -1); + test(*r->s2, 5, 1, *r->s3, 0, 5, -5); + test(*r->s2, 5, 1, *r->s3, 0, 9, -9); + test(*r->s2, 5, 1, *r->s3, 0, 10, -10); + test(*r->s2, 5, 1, *r->s3, 0, 11, -10); + test(*r->s2, 5, 1, *r->s3, 1, 0, 0); + test(*r->s2, 5, 1, *r->s3, 1, 1, -1); + test(*r->s2, 5, 1, *r->s3, 1, 4, -4); + test(*r->s2, 5, 1, *r->s3, 1, 8, -8); + test(*r->s2, 5, 1, *r->s3, 1, 9, -9); + test(*r->s2, 5, 1, *r->s3, 1, 10, -9); + test(*r->s2, 5, 1, *r->s3, 5, 0, 0); + test(*r->s2, 5, 1, *r->s3, 5, 1, -1); + test(*r->s2, 5, 1, *r->s3, 5, 2, -2); + test(*r->s2, 5, 1, *r->s3, 5, 4, -4); + test(*r->s2, 5, 1, *r->s3, 5, 5, -5); + test(*r->s2, 5, 1, *r->s3, 5, 6, -5); + test(*r->s2, 5, 1, *r->s3, 9, 0, 0); + test(*r->s2, 5, 1, *r->s3, 9, 1, -1); + test(*r->s2, 5, 1, *r->s3, 9, 2, -1); + test(*r->s2, 5, 1, *r->s3, 10, 0, 0); + test(*r->s2, 5, 1, *r->s3, 10, 1, 0); + test(*r->s2, 5, 1, *r->s3, 11, 0, 0); + test(*r->s2, 5, 1, *r->s4, 0, 0, 0); + test(*r->s2, 5, 1, *r->s4, 0, 1, -1); + test(*r->s2, 5, 1, *r->s4, 0, 10, -10); + test(*r->s2, 5, 1, *r->s4, 0, 19, -19); + test(*r->s2, 5, 1, *r->s4, 0, 20, -20); + test(*r->s2, 5, 1, *r->s4, 0, 21, -20); + test(*r->s2, 5, 1, *r->s4, 1, 0, 0); + test(*r->s2, 5, 1, *r->s4, 1, 1, -1); + test(*r->s2, 5, 1, *r->s4, 1, 9, -9); + test(*r->s2, 5, 1, *r->s4, 1, 18, -18); + test(*r->s2, 5, 1, *r->s4, 1, 19, -19); + test(*r->s2, 5, 1, *r->s4, 1, 20, -19); + test(*r->s2, 5, 1, *r->s4, 10, 0, 0); + test(*r->s2, 5, 1, *r->s4, 10, 1, -1); + test(*r->s2, 5, 1, *r->s4, 10, 5, -5); + test(*r->s2, 5, 1, *r->s4, 10, 9, -9); + test(*r->s2, 5, 1, *r->s4, 10, 10, -10); + test(*r->s2, 5, 1, *r->s4, 10, 11, -10); + test(*r->s2, 5, 1, *r->s4, 19, 0, 0); + test(*r->s2, 5, 1, *r->s4, 19, 1, -1); + test(*r->s2, 5, 1, *r->s4, 19, 2, -1); + test(*r->s2, 5, 1, *r->s4, 20, 0, 0); + test(*r->s2, 5, 1, *r->s4, 20, 1, 0); + test(*r->s2, 5, 1, *r->s4, 21, 0, 0); + test(*r->s2, 6, 0, *r->s1, 0, 0, 0); + test(*r->s2, 6, 0, *r->s1, 0, 1, 0); + test(*r->s2, 6, 0, *r->s1, 1, 0, 0); + test(*r->s2, 6, 0, *r->s2, 0, 0, 0); + test(*r->s2, 6, 0, *r->s2, 0, 1, 0); + test(*r->s2, 6, 0, *r->s2, 0, 2, 0); + test(*r->s2, 6, 0, *r->s2, 0, 4, 0); + test(*r->s2, 6, 0, *r->s2, 0, 5, 0); + test(*r->s2, 6, 0, *r->s2, 0, 6, 0); + test(*r->s2, 6, 0, *r->s2, 1, 0, 0); + test(*r->s2, 6, 0, *r->s2, 1, 1, 0); + test(*r->s2, 6, 0, *r->s2, 1, 2, 0); + test(*r->s2, 6, 0, *r->s2, 1, 3, 0); + test(*r->s2, 6, 0, *r->s2, 1, 4, 0); + test(*r->s2, 6, 0, *r->s2, 1, 5, 0); + test(*r->s2, 6, 0, *r->s2, 2, 0, 0); + test(*r->s2, 6, 0, *r->s2, 2, 1, 0); + test(*r->s2, 6, 0, *r->s2, 2, 2, 0); + test(*r->s2, 6, 0, *r->s2, 2, 3, 0); + test(*r->s2, 6, 0, *r->s2, 2, 4, 0); + test(*r->s2, 6, 0, *r->s2, 4, 0, 0); + test(*r->s2, 6, 0, *r->s2, 4, 1, 0); + test(*r->s2, 6, 0, *r->s2, 4, 2, 0); + test(*r->s2, 6, 0, *r->s2, 5, 0, 0); + test(*r->s2, 6, 0, *r->s2, 5, 1, 0); + test(*r->s2, 6, 0, *r->s2, 6, 0, 0); + test(*r->s2, 6, 0, *r->s3, 0, 0, 0); + test(*r->s2, 6, 0, *r->s3, 0, 1, 0); + test(*r->s2, 6, 0, *r->s3, 0, 5, 0); + test(*r->s2, 6, 0, *r->s3, 0, 9, 0); + test(*r->s2, 6, 0, *r->s3, 0, 10, 0); + test(*r->s2, 6, 0, *r->s3, 0, 11, 0); + test(*r->s2, 6, 0, *r->s3, 1, 0, 0); + test(*r->s2, 6, 0, *r->s3, 1, 1, 0); + test(*r->s2, 6, 0, *r->s3, 1, 4, 0); + test(*r->s2, 6, 0, *r->s3, 1, 8, 0); + test(*r->s2, 6, 0, *r->s3, 1, 9, 0); + test(*r->s2, 6, 0, *r->s3, 1, 10, 0); + test(*r->s2, 6, 0, *r->s3, 5, 0, 0); + test(*r->s2, 6, 0, *r->s3, 5, 1, 0); + test(*r->s2, 6, 0, *r->s3, 5, 2, 0); + test(*r->s2, 6, 0, *r->s3, 5, 4, 0); + test(*r->s2, 6, 0, *r->s3, 5, 5, 0); + test(*r->s2, 6, 0, *r->s3, 5, 6, 0); + test(*r->s2, 6, 0, *r->s3, 9, 0, 0); + test(*r->s2, 6, 0, *r->s3, 9, 1, 0); + test(*r->s2, 6, 0, *r->s3, 9, 2, 0); + test(*r->s2, 6, 0, *r->s3, 10, 0, 0); + test(*r->s2, 6, 0, *r->s3, 10, 1, 0); + test(*r->s2, 6, 0, *r->s3, 11, 0, 0); +} + +template +void +test19(pmem::obj::persistent_ptr &r) +{ + test(*r->s2, 6, 0, *r->s4, 0, 0, 0); + test(*r->s2, 6, 0, *r->s4, 0, 1, 0); + test(*r->s2, 6, 0, *r->s4, 0, 10, 0); + test(*r->s2, 6, 0, *r->s4, 0, 19, 0); + test(*r->s2, 6, 0, *r->s4, 0, 20, 0); + test(*r->s2, 6, 0, *r->s4, 0, 21, 0); + test(*r->s2, 6, 0, *r->s4, 1, 0, 0); + test(*r->s2, 6, 0, *r->s4, 1, 1, 0); + test(*r->s2, 6, 0, *r->s4, 1, 9, 0); + test(*r->s2, 6, 0, *r->s4, 1, 18, 0); + test(*r->s2, 6, 0, *r->s4, 1, 19, 0); + test(*r->s2, 6, 0, *r->s4, 1, 20, 0); + test(*r->s2, 6, 0, *r->s4, 10, 0, 0); + test(*r->s2, 6, 0, *r->s4, 10, 1, 0); + test(*r->s2, 6, 0, *r->s4, 10, 5, 0); + test(*r->s2, 6, 0, *r->s4, 10, 9, 0); + test(*r->s2, 6, 0, *r->s4, 10, 10, 0); + test(*r->s2, 6, 0, *r->s4, 10, 11, 0); + test(*r->s2, 6, 0, *r->s4, 19, 0, 0); + test(*r->s2, 6, 0, *r->s4, 19, 1, 0); + test(*r->s2, 6, 0, *r->s4, 19, 2, 0); + test(*r->s2, 6, 0, *r->s4, 20, 0, 0); + test(*r->s2, 6, 0, *r->s4, 20, 1, 0); + test(*r->s2, 6, 0, *r->s4, 21, 0, 0); + test(*r->s3, 0, 0, *r->s1, 0, 0, 0); + test(*r->s3, 0, 0, *r->s1, 0, 1, 0); + test(*r->s3, 0, 0, *r->s1, 1, 0, 0); + test(*r->s3, 0, 0, *r->s2, 0, 0, 0); + test(*r->s3, 0, 0, *r->s2, 0, 1, -1); + test(*r->s3, 0, 0, *r->s2, 0, 2, -2); + test(*r->s3, 0, 0, *r->s2, 0, 4, -4); + test(*r->s3, 0, 0, *r->s2, 0, 5, -5); + test(*r->s3, 0, 0, *r->s2, 0, 6, -5); + test(*r->s3, 0, 0, *r->s2, 1, 0, 0); + test(*r->s3, 0, 0, *r->s2, 1, 1, -1); + test(*r->s3, 0, 0, *r->s2, 1, 2, -2); + test(*r->s3, 0, 0, *r->s2, 1, 3, -3); + test(*r->s3, 0, 0, *r->s2, 1, 4, -4); + test(*r->s3, 0, 0, *r->s2, 1, 5, -4); + test(*r->s3, 0, 0, *r->s2, 2, 0, 0); + test(*r->s3, 0, 0, *r->s2, 2, 1, -1); + test(*r->s3, 0, 0, *r->s2, 2, 2, -2); + test(*r->s3, 0, 0, *r->s2, 2, 3, -3); + test(*r->s3, 0, 0, *r->s2, 2, 4, -3); + test(*r->s3, 0, 0, *r->s2, 4, 0, 0); + test(*r->s3, 0, 0, *r->s2, 4, 1, -1); + test(*r->s3, 0, 0, *r->s2, 4, 2, -1); + test(*r->s3, 0, 0, *r->s2, 5, 0, 0); + test(*r->s3, 0, 0, *r->s2, 5, 1, 0); + test(*r->s3, 0, 0, *r->s2, 6, 0, 0); + test(*r->s3, 0, 0, *r->s3, 0, 0, 0); + test(*r->s3, 0, 0, *r->s3, 0, 1, -1); + test(*r->s3, 0, 0, *r->s3, 0, 5, -5); + test(*r->s3, 0, 0, *r->s3, 0, 9, -9); + test(*r->s3, 0, 0, *r->s3, 0, 10, -10); + test(*r->s3, 0, 0, *r->s3, 0, 11, -10); + test(*r->s3, 0, 0, *r->s3, 1, 0, 0); + test(*r->s3, 0, 0, *r->s3, 1, 1, -1); + test(*r->s3, 0, 0, *r->s3, 1, 4, -4); + test(*r->s3, 0, 0, *r->s3, 1, 8, -8); + test(*r->s3, 0, 0, *r->s3, 1, 9, -9); + test(*r->s3, 0, 0, *r->s3, 1, 10, -9); + test(*r->s3, 0, 0, *r->s3, 5, 0, 0); + test(*r->s3, 0, 0, *r->s3, 5, 1, -1); + test(*r->s3, 0, 0, *r->s3, 5, 2, -2); + test(*r->s3, 0, 0, *r->s3, 5, 4, -4); + test(*r->s3, 0, 0, *r->s3, 5, 5, -5); + test(*r->s3, 0, 0, *r->s3, 5, 6, -5); + test(*r->s3, 0, 0, *r->s3, 9, 0, 0); + test(*r->s3, 0, 0, *r->s3, 9, 1, -1); + test(*r->s3, 0, 0, *r->s3, 9, 2, -1); + test(*r->s3, 0, 0, *r->s3, 10, 0, 0); + test(*r->s3, 0, 0, *r->s3, 10, 1, 0); + test(*r->s3, 0, 0, *r->s3, 11, 0, 0); + test(*r->s3, 0, 0, *r->s4, 0, 0, 0); + test(*r->s3, 0, 0, *r->s4, 0, 1, -1); + test(*r->s3, 0, 0, *r->s4, 0, 10, -10); + test(*r->s3, 0, 0, *r->s4, 0, 19, -19); + test(*r->s3, 0, 0, *r->s4, 0, 20, -20); + test(*r->s3, 0, 0, *r->s4, 0, 21, -20); + test(*r->s3, 0, 0, *r->s4, 1, 0, 0); + test(*r->s3, 0, 0, *r->s4, 1, 1, -1); + test(*r->s3, 0, 0, *r->s4, 1, 9, -9); + test(*r->s3, 0, 0, *r->s4, 1, 18, -18); + test(*r->s3, 0, 0, *r->s4, 1, 19, -19); + test(*r->s3, 0, 0, *r->s4, 1, 20, -19); + test(*r->s3, 0, 0, *r->s4, 10, 0, 0); + test(*r->s3, 0, 0, *r->s4, 10, 1, -1); + test(*r->s3, 0, 0, *r->s4, 10, 5, -5); + test(*r->s3, 0, 0, *r->s4, 10, 9, -9); + test(*r->s3, 0, 0, *r->s4, 10, 10, -10); + test(*r->s3, 0, 0, *r->s4, 10, 11, -10); + test(*r->s3, 0, 0, *r->s4, 19, 0, 0); + test(*r->s3, 0, 0, *r->s4, 19, 1, -1); + test(*r->s3, 0, 0, *r->s4, 19, 2, -1); + test(*r->s3, 0, 0, *r->s4, 20, 0, 0); + test(*r->s3, 0, 0, *r->s4, 20, 1, 0); + test(*r->s3, 0, 0, *r->s4, 21, 0, 0); + test(*r->s3, 0, 1, *r->s1, 0, 0, 1); + test(*r->s3, 0, 1, *r->s1, 0, 1, 1); +} + +template +void +test20(pmem::obj::persistent_ptr &r) +{ + test(*r->s3, 0, 1, *r->s1, 1, 0, 0); + test(*r->s3, 0, 1, *r->s2, 0, 0, 1); + test(*r->s3, 0, 1, *r->s2, 0, 1, 0); + test(*r->s3, 0, 1, *r->s2, 0, 2, -1); + test(*r->s3, 0, 1, *r->s2, 0, 4, -3); + test(*r->s3, 0, 1, *r->s2, 0, 5, -4); + test(*r->s3, 0, 1, *r->s2, 0, 6, -4); + test(*r->s3, 0, 1, *r->s2, 1, 0, 1); + test(*r->s3, 0, 1, *r->s2, 1, 1, -1); + test(*r->s3, 0, 1, *r->s2, 1, 2, -1); + test(*r->s3, 0, 1, *r->s2, 1, 3, -1); + test(*r->s3, 0, 1, *r->s2, 1, 4, -1); + test(*r->s3, 0, 1, *r->s2, 1, 5, -1); + test(*r->s3, 0, 1, *r->s2, 2, 0, 1); + test(*r->s3, 0, 1, *r->s2, 2, 1, -2); + test(*r->s3, 0, 1, *r->s2, 2, 2, -2); + test(*r->s3, 0, 1, *r->s2, 2, 3, -2); + test(*r->s3, 0, 1, *r->s2, 2, 4, -2); + test(*r->s3, 0, 1, *r->s2, 4, 0, 1); + test(*r->s3, 0, 1, *r->s2, 4, 1, -4); + test(*r->s3, 0, 1, *r->s2, 4, 2, -4); + test(*r->s3, 0, 1, *r->s2, 5, 0, 1); + test(*r->s3, 0, 1, *r->s2, 5, 1, 1); + test(*r->s3, 0, 1, *r->s2, 6, 0, 0); + test(*r->s3, 0, 1, *r->s3, 0, 0, 1); + test(*r->s3, 0, 1, *r->s3, 0, 1, 0); + test(*r->s3, 0, 1, *r->s3, 0, 5, -4); + test(*r->s3, 0, 1, *r->s3, 0, 9, -8); + test(*r->s3, 0, 1, *r->s3, 0, 10, -9); + test(*r->s3, 0, 1, *r->s3, 0, 11, -9); + test(*r->s3, 0, 1, *r->s3, 1, 0, 1); + test(*r->s3, 0, 1, *r->s3, 1, 1, -1); + test(*r->s3, 0, 1, *r->s3, 1, 4, -1); + test(*r->s3, 0, 1, *r->s3, 1, 8, -1); + test(*r->s3, 0, 1, *r->s3, 1, 9, -1); + test(*r->s3, 0, 1, *r->s3, 1, 10, -1); + test(*r->s3, 0, 1, *r->s3, 5, 0, 1); + test(*r->s3, 0, 1, *r->s3, 5, 1, -5); + test(*r->s3, 0, 1, *r->s3, 5, 2, -5); + test(*r->s3, 0, 1, *r->s3, 5, 4, -5); + test(*r->s3, 0, 1, *r->s3, 5, 5, -5); + test(*r->s3, 0, 1, *r->s3, 5, 6, -5); + test(*r->s3, 0, 1, *r->s3, 9, 0, 1); + test(*r->s3, 0, 1, *r->s3, 9, 1, -9); + test(*r->s3, 0, 1, *r->s3, 9, 2, -9); + test(*r->s3, 0, 1, *r->s3, 10, 0, 1); + test(*r->s3, 0, 1, *r->s3, 10, 1, 1); + test(*r->s3, 0, 1, *r->s3, 11, 0, 0); + test(*r->s3, 0, 1, *r->s4, 0, 0, 1); + test(*r->s3, 0, 1, *r->s4, 0, 1, 0); + test(*r->s3, 0, 1, *r->s4, 0, 10, -9); + test(*r->s3, 0, 1, *r->s4, 0, 19, -18); + test(*r->s3, 0, 1, *r->s4, 0, 20, -19); + test(*r->s3, 0, 1, *r->s4, 0, 21, -19); + test(*r->s3, 0, 1, *r->s4, 1, 0, 1); + test(*r->s3, 0, 1, *r->s4, 1, 1, -1); + test(*r->s3, 0, 1, *r->s4, 1, 9, -1); + test(*r->s3, 0, 1, *r->s4, 1, 18, -1); + test(*r->s3, 0, 1, *r->s4, 1, 19, -1); + test(*r->s3, 0, 1, *r->s4, 1, 20, -1); + test(*r->s3, 0, 1, *r->s4, 10, 0, 1); + test(*r->s3, 0, 1, *r->s4, 10, 1, -10); + test(*r->s3, 0, 1, *r->s4, 10, 5, -10); + test(*r->s3, 0, 1, *r->s4, 10, 9, -10); + test(*r->s3, 0, 1, *r->s4, 10, 10, -10); + test(*r->s3, 0, 1, *r->s4, 10, 11, -10); + test(*r->s3, 0, 1, *r->s4, 19, 0, 1); + test(*r->s3, 0, 1, *r->s4, 19, 1, -19); + test(*r->s3, 0, 1, *r->s4, 19, 2, -19); + test(*r->s3, 0, 1, *r->s4, 20, 0, 1); + test(*r->s3, 0, 1, *r->s4, 20, 1, 1); + test(*r->s3, 0, 1, *r->s4, 21, 0, 0); + test(*r->s3, 0, 5, *r->s1, 0, 0, 5); + test(*r->s3, 0, 5, *r->s1, 0, 1, 5); + test(*r->s3, 0, 5, *r->s1, 1, 0, 0); + test(*r->s3, 0, 5, *r->s2, 0, 0, 5); + test(*r->s3, 0, 5, *r->s2, 0, 1, 4); + test(*r->s3, 0, 5, *r->s2, 0, 2, 3); + test(*r->s3, 0, 5, *r->s2, 0, 4, 1); + test(*r->s3, 0, 5, *r->s2, 0, 5, 0); + test(*r->s3, 0, 5, *r->s2, 0, 6, 0); + test(*r->s3, 0, 5, *r->s2, 1, 0, 5); + test(*r->s3, 0, 5, *r->s2, 1, 1, -1); + test(*r->s3, 0, 5, *r->s2, 1, 2, -1); + test(*r->s3, 0, 5, *r->s2, 1, 3, -1); + test(*r->s3, 0, 5, *r->s2, 1, 4, -1); + test(*r->s3, 0, 5, *r->s2, 1, 5, -1); + test(*r->s3, 0, 5, *r->s2, 2, 0, 5); + test(*r->s3, 0, 5, *r->s2, 2, 1, -2); + test(*r->s3, 0, 5, *r->s2, 2, 2, -2); + test(*r->s3, 0, 5, *r->s2, 2, 3, -2); + test(*r->s3, 0, 5, *r->s2, 2, 4, -2); + test(*r->s3, 0, 5, *r->s2, 4, 0, 5); + test(*r->s3, 0, 5, *r->s2, 4, 1, -4); + test(*r->s3, 0, 5, *r->s2, 4, 2, -4); + test(*r->s3, 0, 5, *r->s2, 5, 0, 5); + test(*r->s3, 0, 5, *r->s2, 5, 1, 5); + test(*r->s3, 0, 5, *r->s2, 6, 0, 0); + test(*r->s3, 0, 5, *r->s3, 0, 0, 5); + test(*r->s3, 0, 5, *r->s3, 0, 1, 4); +} + +template +void +test21(pmem::obj::persistent_ptr &r) +{ + test(*r->s3, 0, 5, *r->s3, 0, 5, 0); + test(*r->s3, 0, 5, *r->s3, 0, 9, -4); + test(*r->s3, 0, 5, *r->s3, 0, 10, -5); + test(*r->s3, 0, 5, *r->s3, 0, 11, -5); + test(*r->s3, 0, 5, *r->s3, 1, 0, 5); + test(*r->s3, 0, 5, *r->s3, 1, 1, -1); + test(*r->s3, 0, 5, *r->s3, 1, 4, -1); + test(*r->s3, 0, 5, *r->s3, 1, 8, -1); + test(*r->s3, 0, 5, *r->s3, 1, 9, -1); + test(*r->s3, 0, 5, *r->s3, 1, 10, -1); + test(*r->s3, 0, 5, *r->s3, 5, 0, 5); + test(*r->s3, 0, 5, *r->s3, 5, 1, -5); + test(*r->s3, 0, 5, *r->s3, 5, 2, -5); + test(*r->s3, 0, 5, *r->s3, 5, 4, -5); + test(*r->s3, 0, 5, *r->s3, 5, 5, -5); + test(*r->s3, 0, 5, *r->s3, 5, 6, -5); + test(*r->s3, 0, 5, *r->s3, 9, 0, 5); + test(*r->s3, 0, 5, *r->s3, 9, 1, -9); + test(*r->s3, 0, 5, *r->s3, 9, 2, -9); + test(*r->s3, 0, 5, *r->s3, 10, 0, 5); + test(*r->s3, 0, 5, *r->s3, 10, 1, 5); + test(*r->s3, 0, 5, *r->s3, 11, 0, 0); + test(*r->s3, 0, 5, *r->s4, 0, 0, 5); + test(*r->s3, 0, 5, *r->s4, 0, 1, 4); + test(*r->s3, 0, 5, *r->s4, 0, 10, -5); + test(*r->s3, 0, 5, *r->s4, 0, 19, -14); + test(*r->s3, 0, 5, *r->s4, 0, 20, -15); + test(*r->s3, 0, 5, *r->s4, 0, 21, -15); + test(*r->s3, 0, 5, *r->s4, 1, 0, 5); + test(*r->s3, 0, 5, *r->s4, 1, 1, -1); + test(*r->s3, 0, 5, *r->s4, 1, 9, -1); + test(*r->s3, 0, 5, *r->s4, 1, 18, -1); + test(*r->s3, 0, 5, *r->s4, 1, 19, -1); + test(*r->s3, 0, 5, *r->s4, 1, 20, -1); + test(*r->s3, 0, 5, *r->s4, 10, 0, 5); + test(*r->s3, 0, 5, *r->s4, 10, 1, -10); + test(*r->s3, 0, 5, *r->s4, 10, 5, -10); + test(*r->s3, 0, 5, *r->s4, 10, 9, -10); + test(*r->s3, 0, 5, *r->s4, 10, 10, -10); + test(*r->s3, 0, 5, *r->s4, 10, 11, -10); + test(*r->s3, 0, 5, *r->s4, 19, 0, 5); + test(*r->s3, 0, 5, *r->s4, 19, 1, -19); + test(*r->s3, 0, 5, *r->s4, 19, 2, -19); + test(*r->s3, 0, 5, *r->s4, 20, 0, 5); + test(*r->s3, 0, 5, *r->s4, 20, 1, 5); + test(*r->s3, 0, 5, *r->s4, 21, 0, 0); + test(*r->s3, 0, 9, *r->s1, 0, 0, 9); + test(*r->s3, 0, 9, *r->s1, 0, 1, 9); + test(*r->s3, 0, 9, *r->s1, 1, 0, 0); + test(*r->s3, 0, 9, *r->s2, 0, 0, 9); + test(*r->s3, 0, 9, *r->s2, 0, 1, 8); + test(*r->s3, 0, 9, *r->s2, 0, 2, 7); + test(*r->s3, 0, 9, *r->s2, 0, 4, 5); + test(*r->s3, 0, 9, *r->s2, 0, 5, 4); + test(*r->s3, 0, 9, *r->s2, 0, 6, 4); + test(*r->s3, 0, 9, *r->s2, 1, 0, 9); + test(*r->s3, 0, 9, *r->s2, 1, 1, -1); + test(*r->s3, 0, 9, *r->s2, 1, 2, -1); + test(*r->s3, 0, 9, *r->s2, 1, 3, -1); + test(*r->s3, 0, 9, *r->s2, 1, 4, -1); + test(*r->s3, 0, 9, *r->s2, 1, 5, -1); + test(*r->s3, 0, 9, *r->s2, 2, 0, 9); + test(*r->s3, 0, 9, *r->s2, 2, 1, -2); + test(*r->s3, 0, 9, *r->s2, 2, 2, -2); + test(*r->s3, 0, 9, *r->s2, 2, 3, -2); + test(*r->s3, 0, 9, *r->s2, 2, 4, -2); + test(*r->s3, 0, 9, *r->s2, 4, 0, 9); + test(*r->s3, 0, 9, *r->s2, 4, 1, -4); + test(*r->s3, 0, 9, *r->s2, 4, 2, -4); + test(*r->s3, 0, 9, *r->s2, 5, 0, 9); + test(*r->s3, 0, 9, *r->s2, 5, 1, 9); + test(*r->s3, 0, 9, *r->s2, 6, 0, 0); + test(*r->s3, 0, 9, *r->s3, 0, 0, 9); + test(*r->s3, 0, 9, *r->s3, 0, 1, 8); + test(*r->s3, 0, 9, *r->s3, 0, 5, 4); + test(*r->s3, 0, 9, *r->s3, 0, 9, 0); + test(*r->s3, 0, 9, *r->s3, 0, 10, -1); + test(*r->s3, 0, 9, *r->s3, 0, 11, -1); + test(*r->s3, 0, 9, *r->s3, 1, 0, 9); + test(*r->s3, 0, 9, *r->s3, 1, 1, -1); + test(*r->s3, 0, 9, *r->s3, 1, 4, -1); + test(*r->s3, 0, 9, *r->s3, 1, 8, -1); + test(*r->s3, 0, 9, *r->s3, 1, 9, -1); + test(*r->s3, 0, 9, *r->s3, 1, 10, -1); + test(*r->s3, 0, 9, *r->s3, 5, 0, 9); + test(*r->s3, 0, 9, *r->s3, 5, 1, -5); + test(*r->s3, 0, 9, *r->s3, 5, 2, -5); + test(*r->s3, 0, 9, *r->s3, 5, 4, -5); + test(*r->s3, 0, 9, *r->s3, 5, 5, -5); + test(*r->s3, 0, 9, *r->s3, 5, 6, -5); + test(*r->s3, 0, 9, *r->s3, 9, 0, 9); + test(*r->s3, 0, 9, *r->s3, 9, 1, -9); + test(*r->s3, 0, 9, *r->s3, 9, 2, -9); + test(*r->s3, 0, 9, *r->s3, 10, 0, 9); + test(*r->s3, 0, 9, *r->s3, 10, 1, 9); + test(*r->s3, 0, 9, *r->s3, 11, 0, 0); + test(*r->s3, 0, 9, *r->s4, 0, 0, 9); + test(*r->s3, 0, 9, *r->s4, 0, 1, 8); + test(*r->s3, 0, 9, *r->s4, 0, 10, -1); + test(*r->s3, 0, 9, *r->s4, 0, 19, -10); +} + +template +void +test22(pmem::obj::persistent_ptr &r) +{ + test(*r->s3, 0, 9, *r->s4, 0, 20, -11); + test(*r->s3, 0, 9, *r->s4, 0, 21, -11); + test(*r->s3, 0, 9, *r->s4, 1, 0, 9); + test(*r->s3, 0, 9, *r->s4, 1, 1, -1); + test(*r->s3, 0, 9, *r->s4, 1, 9, -1); + test(*r->s3, 0, 9, *r->s4, 1, 18, -1); + test(*r->s3, 0, 9, *r->s4, 1, 19, -1); + test(*r->s3, 0, 9, *r->s4, 1, 20, -1); + test(*r->s3, 0, 9, *r->s4, 10, 0, 9); + test(*r->s3, 0, 9, *r->s4, 10, 1, -10); + test(*r->s3, 0, 9, *r->s4, 10, 5, -10); + test(*r->s3, 0, 9, *r->s4, 10, 9, -10); + test(*r->s3, 0, 9, *r->s4, 10, 10, -10); + test(*r->s3, 0, 9, *r->s4, 10, 11, -10); + test(*r->s3, 0, 9, *r->s4, 19, 0, 9); + test(*r->s3, 0, 9, *r->s4, 19, 1, -19); + test(*r->s3, 0, 9, *r->s4, 19, 2, -19); + test(*r->s3, 0, 9, *r->s4, 20, 0, 9); + test(*r->s3, 0, 9, *r->s4, 20, 1, 9); + test(*r->s3, 0, 9, *r->s4, 21, 0, 0); + test(*r->s3, 0, 10, *r->s1, 0, 0, 10); + test(*r->s3, 0, 10, *r->s1, 0, 1, 10); + test(*r->s3, 0, 10, *r->s1, 1, 0, 0); + test(*r->s3, 0, 10, *r->s2, 0, 0, 10); + test(*r->s3, 0, 10, *r->s2, 0, 1, 9); + test(*r->s3, 0, 10, *r->s2, 0, 2, 8); + test(*r->s3, 0, 10, *r->s2, 0, 4, 6); + test(*r->s3, 0, 10, *r->s2, 0, 5, 5); + test(*r->s3, 0, 10, *r->s2, 0, 6, 5); + test(*r->s3, 0, 10, *r->s2, 1, 0, 10); + test(*r->s3, 0, 10, *r->s2, 1, 1, -1); + test(*r->s3, 0, 10, *r->s2, 1, 2, -1); + test(*r->s3, 0, 10, *r->s2, 1, 3, -1); + test(*r->s3, 0, 10, *r->s2, 1, 4, -1); + test(*r->s3, 0, 10, *r->s2, 1, 5, -1); + test(*r->s3, 0, 10, *r->s2, 2, 0, 10); + test(*r->s3, 0, 10, *r->s2, 2, 1, -2); + test(*r->s3, 0, 10, *r->s2, 2, 2, -2); + test(*r->s3, 0, 10, *r->s2, 2, 3, -2); + test(*r->s3, 0, 10, *r->s2, 2, 4, -2); + test(*r->s3, 0, 10, *r->s2, 4, 0, 10); + test(*r->s3, 0, 10, *r->s2, 4, 1, -4); + test(*r->s3, 0, 10, *r->s2, 4, 2, -4); + test(*r->s3, 0, 10, *r->s2, 5, 0, 10); + test(*r->s3, 0, 10, *r->s2, 5, 1, 10); + test(*r->s3, 0, 10, *r->s2, 6, 0, 0); + test(*r->s3, 0, 10, *r->s3, 0, 0, 10); + test(*r->s3, 0, 10, *r->s3, 0, 1, 9); + test(*r->s3, 0, 10, *r->s3, 0, 5, 5); + test(*r->s3, 0, 10, *r->s3, 0, 9, 1); + test(*r->s3, 0, 10, *r->s3, 0, 10, 0); + test(*r->s3, 0, 10, *r->s3, 0, 11, 0); + test(*r->s3, 0, 10, *r->s3, 1, 0, 10); + test(*r->s3, 0, 10, *r->s3, 1, 1, -1); + test(*r->s3, 0, 10, *r->s3, 1, 4, -1); + test(*r->s3, 0, 10, *r->s3, 1, 8, -1); + test(*r->s3, 0, 10, *r->s3, 1, 9, -1); + test(*r->s3, 0, 10, *r->s3, 1, 10, -1); + test(*r->s3, 0, 10, *r->s3, 5, 0, 10); + test(*r->s3, 0, 10, *r->s3, 5, 1, -5); + test(*r->s3, 0, 10, *r->s3, 5, 2, -5); + test(*r->s3, 0, 10, *r->s3, 5, 4, -5); + test(*r->s3, 0, 10, *r->s3, 5, 5, -5); + test(*r->s3, 0, 10, *r->s3, 5, 6, -5); + test(*r->s3, 0, 10, *r->s3, 9, 0, 10); + test(*r->s3, 0, 10, *r->s3, 9, 1, -9); + test(*r->s3, 0, 10, *r->s3, 9, 2, -9); + test(*r->s3, 0, 10, *r->s3, 10, 0, 10); + test(*r->s3, 0, 10, *r->s3, 10, 1, 10); + test(*r->s3, 0, 10, *r->s3, 11, 0, 0); + test(*r->s3, 0, 10, *r->s4, 0, 0, 10); + test(*r->s3, 0, 10, *r->s4, 0, 1, 9); + test(*r->s3, 0, 10, *r->s4, 0, 10, 0); + test(*r->s3, 0, 10, *r->s4, 0, 19, -9); + test(*r->s3, 0, 10, *r->s4, 0, 20, -10); + test(*r->s3, 0, 10, *r->s4, 0, 21, -10); + test(*r->s3, 0, 10, *r->s4, 1, 0, 10); + test(*r->s3, 0, 10, *r->s4, 1, 1, -1); + test(*r->s3, 0, 10, *r->s4, 1, 9, -1); + test(*r->s3, 0, 10, *r->s4, 1, 18, -1); + test(*r->s3, 0, 10, *r->s4, 1, 19, -1); + test(*r->s3, 0, 10, *r->s4, 1, 20, -1); + test(*r->s3, 0, 10, *r->s4, 10, 0, 10); + test(*r->s3, 0, 10, *r->s4, 10, 1, -10); + test(*r->s3, 0, 10, *r->s4, 10, 5, -10); + test(*r->s3, 0, 10, *r->s4, 10, 9, -10); + test(*r->s3, 0, 10, *r->s4, 10, 10, -10); + test(*r->s3, 0, 10, *r->s4, 10, 11, -10); + test(*r->s3, 0, 10, *r->s4, 19, 0, 10); + test(*r->s3, 0, 10, *r->s4, 19, 1, -19); + test(*r->s3, 0, 10, *r->s4, 19, 2, -19); + test(*r->s3, 0, 10, *r->s4, 20, 0, 10); + test(*r->s3, 0, 10, *r->s4, 20, 1, 10); + test(*r->s3, 0, 10, *r->s4, 21, 0, 0); + test(*r->s3, 0, 11, *r->s1, 0, 0, 10); + test(*r->s3, 0, 11, *r->s1, 0, 1, 10); + test(*r->s3, 0, 11, *r->s1, 1, 0, 0); + test(*r->s3, 0, 11, *r->s2, 0, 0, 10); + test(*r->s3, 0, 11, *r->s2, 0, 1, 9); + test(*r->s3, 0, 11, *r->s2, 0, 2, 8); +} + +template +void +test23(pmem::obj::persistent_ptr &r) +{ + test(*r->s3, 0, 11, *r->s2, 0, 4, 6); + test(*r->s3, 0, 11, *r->s2, 0, 5, 5); + test(*r->s3, 0, 11, *r->s2, 0, 6, 5); + test(*r->s3, 0, 11, *r->s2, 1, 0, 10); + test(*r->s3, 0, 11, *r->s2, 1, 1, -1); + test(*r->s3, 0, 11, *r->s2, 1, 2, -1); + test(*r->s3, 0, 11, *r->s2, 1, 3, -1); + test(*r->s3, 0, 11, *r->s2, 1, 4, -1); + test(*r->s3, 0, 11, *r->s2, 1, 5, -1); + test(*r->s3, 0, 11, *r->s2, 2, 0, 10); + test(*r->s3, 0, 11, *r->s2, 2, 1, -2); + test(*r->s3, 0, 11, *r->s2, 2, 2, -2); + test(*r->s3, 0, 11, *r->s2, 2, 3, -2); + test(*r->s3, 0, 11, *r->s2, 2, 4, -2); + test(*r->s3, 0, 11, *r->s2, 4, 0, 10); + test(*r->s3, 0, 11, *r->s2, 4, 1, -4); + test(*r->s3, 0, 11, *r->s2, 4, 2, -4); + test(*r->s3, 0, 11, *r->s2, 5, 0, 10); + test(*r->s3, 0, 11, *r->s2, 5, 1, 10); + test(*r->s3, 0, 11, *r->s2, 6, 0, 0); + test(*r->s3, 0, 11, *r->s3, 0, 0, 10); + test(*r->s3, 0, 11, *r->s3, 0, 1, 9); + test(*r->s3, 0, 11, *r->s3, 0, 5, 5); + test(*r->s3, 0, 11, *r->s3, 0, 9, 1); + test(*r->s3, 0, 11, *r->s3, 0, 10, 0); + test(*r->s3, 0, 11, *r->s3, 0, 11, 0); + test(*r->s3, 0, 11, *r->s3, 1, 0, 10); + test(*r->s3, 0, 11, *r->s3, 1, 1, -1); + test(*r->s3, 0, 11, *r->s3, 1, 4, -1); + test(*r->s3, 0, 11, *r->s3, 1, 8, -1); + test(*r->s3, 0, 11, *r->s3, 1, 9, -1); + test(*r->s3, 0, 11, *r->s3, 1, 10, -1); + test(*r->s3, 0, 11, *r->s3, 5, 0, 10); + test(*r->s3, 0, 11, *r->s3, 5, 1, -5); + test(*r->s3, 0, 11, *r->s3, 5, 2, -5); + test(*r->s3, 0, 11, *r->s3, 5, 4, -5); + test(*r->s3, 0, 11, *r->s3, 5, 5, -5); + test(*r->s3, 0, 11, *r->s3, 5, 6, -5); + test(*r->s3, 0, 11, *r->s3, 9, 0, 10); + test(*r->s3, 0, 11, *r->s3, 9, 1, -9); + test(*r->s3, 0, 11, *r->s3, 9, 2, -9); + test(*r->s3, 0, 11, *r->s3, 10, 0, 10); + test(*r->s3, 0, 11, *r->s3, 10, 1, 10); + test(*r->s3, 0, 11, *r->s3, 11, 0, 0); + test(*r->s3, 0, 11, *r->s4, 0, 0, 10); + test(*r->s3, 0, 11, *r->s4, 0, 1, 9); + test(*r->s3, 0, 11, *r->s4, 0, 10, 0); + test(*r->s3, 0, 11, *r->s4, 0, 19, -9); + test(*r->s3, 0, 11, *r->s4, 0, 20, -10); + test(*r->s3, 0, 11, *r->s4, 0, 21, -10); + test(*r->s3, 0, 11, *r->s4, 1, 0, 10); + test(*r->s3, 0, 11, *r->s4, 1, 1, -1); + test(*r->s3, 0, 11, *r->s4, 1, 9, -1); + test(*r->s3, 0, 11, *r->s4, 1, 18, -1); + test(*r->s3, 0, 11, *r->s4, 1, 19, -1); + test(*r->s3, 0, 11, *r->s4, 1, 20, -1); + test(*r->s3, 0, 11, *r->s4, 10, 0, 10); + test(*r->s3, 0, 11, *r->s4, 10, 1, -10); + test(*r->s3, 0, 11, *r->s4, 10, 5, -10); + test(*r->s3, 0, 11, *r->s4, 10, 9, -10); + test(*r->s3, 0, 11, *r->s4, 10, 10, -10); + test(*r->s3, 0, 11, *r->s4, 10, 11, -10); + test(*r->s3, 0, 11, *r->s4, 19, 0, 10); + test(*r->s3, 0, 11, *r->s4, 19, 1, -19); + test(*r->s3, 0, 11, *r->s4, 19, 2, -19); + test(*r->s3, 0, 11, *r->s4, 20, 0, 10); + test(*r->s3, 0, 11, *r->s4, 20, 1, 10); + test(*r->s3, 0, 11, *r->s4, 21, 0, 0); + test(*r->s3, 1, 0, *r->s1, 0, 0, 0); + test(*r->s3, 1, 0, *r->s1, 0, 1, 0); + test(*r->s3, 1, 0, *r->s1, 1, 0, 0); + test(*r->s3, 1, 0, *r->s2, 0, 0, 0); + test(*r->s3, 1, 0, *r->s2, 0, 1, -1); + test(*r->s3, 1, 0, *r->s2, 0, 2, -2); + test(*r->s3, 1, 0, *r->s2, 0, 4, -4); + test(*r->s3, 1, 0, *r->s2, 0, 5, -5); + test(*r->s3, 1, 0, *r->s2, 0, 6, -5); + test(*r->s3, 1, 0, *r->s2, 1, 0, 0); + test(*r->s3, 1, 0, *r->s2, 1, 1, -1); + test(*r->s3, 1, 0, *r->s2, 1, 2, -2); + test(*r->s3, 1, 0, *r->s2, 1, 3, -3); + test(*r->s3, 1, 0, *r->s2, 1, 4, -4); + test(*r->s3, 1, 0, *r->s2, 1, 5, -4); + test(*r->s3, 1, 0, *r->s2, 2, 0, 0); + test(*r->s3, 1, 0, *r->s2, 2, 1, -1); + test(*r->s3, 1, 0, *r->s2, 2, 2, -2); + test(*r->s3, 1, 0, *r->s2, 2, 3, -3); + test(*r->s3, 1, 0, *r->s2, 2, 4, -3); + test(*r->s3, 1, 0, *r->s2, 4, 0, 0); + test(*r->s3, 1, 0, *r->s2, 4, 1, -1); + test(*r->s3, 1, 0, *r->s2, 4, 2, -1); + test(*r->s3, 1, 0, *r->s2, 5, 0, 0); + test(*r->s3, 1, 0, *r->s2, 5, 1, 0); + test(*r->s3, 1, 0, *r->s2, 6, 0, 0); + test(*r->s3, 1, 0, *r->s3, 0, 0, 0); + test(*r->s3, 1, 0, *r->s3, 0, 1, -1); + test(*r->s3, 1, 0, *r->s3, 0, 5, -5); + test(*r->s3, 1, 0, *r->s3, 0, 9, -9); + test(*r->s3, 1, 0, *r->s3, 0, 10, -10); + test(*r->s3, 1, 0, *r->s3, 0, 11, -10); +} + +template +void +test24(pmem::obj::persistent_ptr &r) +{ + test(*r->s3, 1, 0, *r->s3, 1, 0, 0); + test(*r->s3, 1, 0, *r->s3, 1, 1, -1); + test(*r->s3, 1, 0, *r->s3, 1, 4, -4); + test(*r->s3, 1, 0, *r->s3, 1, 8, -8); + test(*r->s3, 1, 0, *r->s3, 1, 9, -9); + test(*r->s3, 1, 0, *r->s3, 1, 10, -9); + test(*r->s3, 1, 0, *r->s3, 5, 0, 0); + test(*r->s3, 1, 0, *r->s3, 5, 1, -1); + test(*r->s3, 1, 0, *r->s3, 5, 2, -2); + test(*r->s3, 1, 0, *r->s3, 5, 4, -4); + test(*r->s3, 1, 0, *r->s3, 5, 5, -5); + test(*r->s3, 1, 0, *r->s3, 5, 6, -5); + test(*r->s3, 1, 0, *r->s3, 9, 0, 0); + test(*r->s3, 1, 0, *r->s3, 9, 1, -1); + test(*r->s3, 1, 0, *r->s3, 9, 2, -1); + test(*r->s3, 1, 0, *r->s3, 10, 0, 0); + test(*r->s3, 1, 0, *r->s3, 10, 1, 0); + test(*r->s3, 1, 0, *r->s3, 11, 0, 0); + test(*r->s3, 1, 0, *r->s4, 0, 0, 0); + test(*r->s3, 1, 0, *r->s4, 0, 1, -1); + test(*r->s3, 1, 0, *r->s4, 0, 10, -10); + test(*r->s3, 1, 0, *r->s4, 0, 19, -19); + test(*r->s3, 1, 0, *r->s4, 0, 20, -20); + test(*r->s3, 1, 0, *r->s4, 0, 21, -20); + test(*r->s3, 1, 0, *r->s4, 1, 0, 0); + test(*r->s3, 1, 0, *r->s4, 1, 1, -1); + test(*r->s3, 1, 0, *r->s4, 1, 9, -9); + test(*r->s3, 1, 0, *r->s4, 1, 18, -18); + test(*r->s3, 1, 0, *r->s4, 1, 19, -19); + test(*r->s3, 1, 0, *r->s4, 1, 20, -19); + test(*r->s3, 1, 0, *r->s4, 10, 0, 0); + test(*r->s3, 1, 0, *r->s4, 10, 1, -1); + test(*r->s3, 1, 0, *r->s4, 10, 5, -5); + test(*r->s3, 1, 0, *r->s4, 10, 9, -9); + test(*r->s3, 1, 0, *r->s4, 10, 10, -10); + test(*r->s3, 1, 0, *r->s4, 10, 11, -10); + test(*r->s3, 1, 0, *r->s4, 19, 0, 0); + test(*r->s3, 1, 0, *r->s4, 19, 1, -1); + test(*r->s3, 1, 0, *r->s4, 19, 2, -1); + test(*r->s3, 1, 0, *r->s4, 20, 0, 0); + test(*r->s3, 1, 0, *r->s4, 20, 1, 0); + test(*r->s3, 1, 0, *r->s4, 21, 0, 0); + test(*r->s3, 1, 1, *r->s1, 0, 0, 1); + test(*r->s3, 1, 1, *r->s1, 0, 1, 1); + test(*r->s3, 1, 1, *r->s1, 1, 0, 0); + test(*r->s3, 1, 1, *r->s2, 0, 0, 1); + test(*r->s3, 1, 1, *r->s2, 0, 1, 1); + test(*r->s3, 1, 1, *r->s2, 0, 2, 1); + test(*r->s3, 1, 1, *r->s2, 0, 4, 1); + test(*r->s3, 1, 1, *r->s2, 0, 5, 1); + test(*r->s3, 1, 1, *r->s2, 0, 6, 1); + test(*r->s3, 1, 1, *r->s2, 1, 0, 1); + test(*r->s3, 1, 1, *r->s2, 1, 1, 0); + test(*r->s3, 1, 1, *r->s2, 1, 2, -1); + test(*r->s3, 1, 1, *r->s2, 1, 3, -2); + test(*r->s3, 1, 1, *r->s2, 1, 4, -3); + test(*r->s3, 1, 1, *r->s2, 1, 5, -3); + test(*r->s3, 1, 1, *r->s2, 2, 0, 1); + test(*r->s3, 1, 1, *r->s2, 2, 1, -1); + test(*r->s3, 1, 1, *r->s2, 2, 2, -1); + test(*r->s3, 1, 1, *r->s2, 2, 3, -1); + test(*r->s3, 1, 1, *r->s2, 2, 4, -1); + test(*r->s3, 1, 1, *r->s2, 4, 0, 1); + test(*r->s3, 1, 1, *r->s2, 4, 1, -3); + test(*r->s3, 1, 1, *r->s2, 4, 2, -3); + test(*r->s3, 1, 1, *r->s2, 5, 0, 1); + test(*r->s3, 1, 1, *r->s2, 5, 1, 1); + test(*r->s3, 1, 1, *r->s2, 6, 0, 0); + test(*r->s3, 1, 1, *r->s3, 0, 0, 1); + test(*r->s3, 1, 1, *r->s3, 0, 1, 1); + test(*r->s3, 1, 1, *r->s3, 0, 5, 1); + test(*r->s3, 1, 1, *r->s3, 0, 9, 1); + test(*r->s3, 1, 1, *r->s3, 0, 10, 1); + test(*r->s3, 1, 1, *r->s3, 0, 11, 1); + test(*r->s3, 1, 1, *r->s3, 1, 0, 1); + test(*r->s3, 1, 1, *r->s3, 1, 1, 0); + test(*r->s3, 1, 1, *r->s3, 1, 4, -3); + test(*r->s3, 1, 1, *r->s3, 1, 8, -7); + test(*r->s3, 1, 1, *r->s3, 1, 9, -8); + test(*r->s3, 1, 1, *r->s3, 1, 10, -8); + test(*r->s3, 1, 1, *r->s3, 5, 0, 1); + test(*r->s3, 1, 1, *r->s3, 5, 1, -4); + test(*r->s3, 1, 1, *r->s3, 5, 2, -4); + test(*r->s3, 1, 1, *r->s3, 5, 4, -4); + test(*r->s3, 1, 1, *r->s3, 5, 5, -4); + test(*r->s3, 1, 1, *r->s3, 5, 6, -4); + test(*r->s3, 1, 1, *r->s3, 9, 0, 1); + test(*r->s3, 1, 1, *r->s3, 9, 1, -8); + test(*r->s3, 1, 1, *r->s3, 9, 2, -8); + test(*r->s3, 1, 1, *r->s3, 10, 0, 1); + test(*r->s3, 1, 1, *r->s3, 10, 1, 1); + test(*r->s3, 1, 1, *r->s3, 11, 0, 0); + test(*r->s3, 1, 1, *r->s4, 0, 0, 1); + test(*r->s3, 1, 1, *r->s4, 0, 1, 1); + test(*r->s3, 1, 1, *r->s4, 0, 10, 1); + test(*r->s3, 1, 1, *r->s4, 0, 19, 1); + test(*r->s3, 1, 1, *r->s4, 0, 20, 1); + test(*r->s3, 1, 1, *r->s4, 0, 21, 1); + test(*r->s3, 1, 1, *r->s4, 1, 0, 1); + test(*r->s3, 1, 1, *r->s4, 1, 1, 0); +} + +template +void +test25(pmem::obj::persistent_ptr &r) +{ + test(*r->s3, 1, 1, *r->s4, 1, 9, -8); + test(*r->s3, 1, 1, *r->s4, 1, 18, -17); + test(*r->s3, 1, 1, *r->s4, 1, 19, -18); + test(*r->s3, 1, 1, *r->s4, 1, 20, -18); + test(*r->s3, 1, 1, *r->s4, 10, 0, 1); + test(*r->s3, 1, 1, *r->s4, 10, 1, -9); + test(*r->s3, 1, 1, *r->s4, 10, 5, -9); + test(*r->s3, 1, 1, *r->s4, 10, 9, -9); + test(*r->s3, 1, 1, *r->s4, 10, 10, -9); + test(*r->s3, 1, 1, *r->s4, 10, 11, -9); + test(*r->s3, 1, 1, *r->s4, 19, 0, 1); + test(*r->s3, 1, 1, *r->s4, 19, 1, -18); + test(*r->s3, 1, 1, *r->s4, 19, 2, -18); + test(*r->s3, 1, 1, *r->s4, 20, 0, 1); + test(*r->s3, 1, 1, *r->s4, 20, 1, 1); + test(*r->s3, 1, 1, *r->s4, 21, 0, 0); + test(*r->s3, 1, 4, *r->s1, 0, 0, 4); + test(*r->s3, 1, 4, *r->s1, 0, 1, 4); + test(*r->s3, 1, 4, *r->s1, 1, 0, 0); + test(*r->s3, 1, 4, *r->s2, 0, 0, 4); + test(*r->s3, 1, 4, *r->s2, 0, 1, 1); + test(*r->s3, 1, 4, *r->s2, 0, 2, 1); + test(*r->s3, 1, 4, *r->s2, 0, 4, 1); + test(*r->s3, 1, 4, *r->s2, 0, 5, 1); + test(*r->s3, 1, 4, *r->s2, 0, 6, 1); + test(*r->s3, 1, 4, *r->s2, 1, 0, 4); + test(*r->s3, 1, 4, *r->s2, 1, 1, 3); + test(*r->s3, 1, 4, *r->s2, 1, 2, 2); + test(*r->s3, 1, 4, *r->s2, 1, 3, 1); + test(*r->s3, 1, 4, *r->s2, 1, 4, 0); + test(*r->s3, 1, 4, *r->s2, 1, 5, 0); + test(*r->s3, 1, 4, *r->s2, 2, 0, 4); + test(*r->s3, 1, 4, *r->s2, 2, 1, -1); + test(*r->s3, 1, 4, *r->s2, 2, 2, -1); + test(*r->s3, 1, 4, *r->s2, 2, 3, -1); + test(*r->s3, 1, 4, *r->s2, 2, 4, -1); + test(*r->s3, 1, 4, *r->s2, 4, 0, 4); + test(*r->s3, 1, 4, *r->s2, 4, 1, -3); + test(*r->s3, 1, 4, *r->s2, 4, 2, -3); + test(*r->s3, 1, 4, *r->s2, 5, 0, 4); + test(*r->s3, 1, 4, *r->s2, 5, 1, 4); + test(*r->s3, 1, 4, *r->s2, 6, 0, 0); + test(*r->s3, 1, 4, *r->s3, 0, 0, 4); + test(*r->s3, 1, 4, *r->s3, 0, 1, 1); + test(*r->s3, 1, 4, *r->s3, 0, 5, 1); + test(*r->s3, 1, 4, *r->s3, 0, 9, 1); + test(*r->s3, 1, 4, *r->s3, 0, 10, 1); + test(*r->s3, 1, 4, *r->s3, 0, 11, 1); + test(*r->s3, 1, 4, *r->s3, 1, 0, 4); + test(*r->s3, 1, 4, *r->s3, 1, 1, 3); + test(*r->s3, 1, 4, *r->s3, 1, 4, 0); + test(*r->s3, 1, 4, *r->s3, 1, 8, -4); + test(*r->s3, 1, 4, *r->s3, 1, 9, -5); + test(*r->s3, 1, 4, *r->s3, 1, 10, -5); + test(*r->s3, 1, 4, *r->s3, 5, 0, 4); + test(*r->s3, 1, 4, *r->s3, 5, 1, -4); + test(*r->s3, 1, 4, *r->s3, 5, 2, -4); + test(*r->s3, 1, 4, *r->s3, 5, 4, -4); + test(*r->s3, 1, 4, *r->s3, 5, 5, -4); + test(*r->s3, 1, 4, *r->s3, 5, 6, -4); + test(*r->s3, 1, 4, *r->s3, 9, 0, 4); + test(*r->s3, 1, 4, *r->s3, 9, 1, -8); + test(*r->s3, 1, 4, *r->s3, 9, 2, -8); + test(*r->s3, 1, 4, *r->s3, 10, 0, 4); + test(*r->s3, 1, 4, *r->s3, 10, 1, 4); + test(*r->s3, 1, 4, *r->s3, 11, 0, 0); + test(*r->s3, 1, 4, *r->s4, 0, 0, 4); + test(*r->s3, 1, 4, *r->s4, 0, 1, 1); + test(*r->s3, 1, 4, *r->s4, 0, 10, 1); + test(*r->s3, 1, 4, *r->s4, 0, 19, 1); + test(*r->s3, 1, 4, *r->s4, 0, 20, 1); + test(*r->s3, 1, 4, *r->s4, 0, 21, 1); + test(*r->s3, 1, 4, *r->s4, 1, 0, 4); + test(*r->s3, 1, 4, *r->s4, 1, 1, 3); + test(*r->s3, 1, 4, *r->s4, 1, 9, -5); + test(*r->s3, 1, 4, *r->s4, 1, 18, -14); + test(*r->s3, 1, 4, *r->s4, 1, 19, -15); + test(*r->s3, 1, 4, *r->s4, 1, 20, -15); + test(*r->s3, 1, 4, *r->s4, 10, 0, 4); + test(*r->s3, 1, 4, *r->s4, 10, 1, -9); + test(*r->s3, 1, 4, *r->s4, 10, 5, -9); + test(*r->s3, 1, 4, *r->s4, 10, 9, -9); + test(*r->s3, 1, 4, *r->s4, 10, 10, -9); + test(*r->s3, 1, 4, *r->s4, 10, 11, -9); + test(*r->s3, 1, 4, *r->s4, 19, 0, 4); + test(*r->s3, 1, 4, *r->s4, 19, 1, -18); + test(*r->s3, 1, 4, *r->s4, 19, 2, -18); + test(*r->s3, 1, 4, *r->s4, 20, 0, 4); + test(*r->s3, 1, 4, *r->s4, 20, 1, 4); + test(*r->s3, 1, 4, *r->s4, 21, 0, 0); + test(*r->s3, 1, 8, *r->s1, 0, 0, 8); + test(*r->s3, 1, 8, *r->s1, 0, 1, 8); + test(*r->s3, 1, 8, *r->s1, 1, 0, 0); + test(*r->s3, 1, 8, *r->s2, 0, 0, 8); + test(*r->s3, 1, 8, *r->s2, 0, 1, 1); + test(*r->s3, 1, 8, *r->s2, 0, 2, 1); + test(*r->s3, 1, 8, *r->s2, 0, 4, 1); + test(*r->s3, 1, 8, *r->s2, 0, 5, 1); + test(*r->s3, 1, 8, *r->s2, 0, 6, 1); + test(*r->s3, 1, 8, *r->s2, 1, 0, 8); +} + +template +void +test26(pmem::obj::persistent_ptr &r) +{ + test(*r->s3, 1, 8, *r->s2, 1, 1, 7); + test(*r->s3, 1, 8, *r->s2, 1, 2, 6); + test(*r->s3, 1, 8, *r->s2, 1, 3, 5); + test(*r->s3, 1, 8, *r->s2, 1, 4, 4); + test(*r->s3, 1, 8, *r->s2, 1, 5, 4); + test(*r->s3, 1, 8, *r->s2, 2, 0, 8); + test(*r->s3, 1, 8, *r->s2, 2, 1, -1); + test(*r->s3, 1, 8, *r->s2, 2, 2, -1); + test(*r->s3, 1, 8, *r->s2, 2, 3, -1); + test(*r->s3, 1, 8, *r->s2, 2, 4, -1); + test(*r->s3, 1, 8, *r->s2, 4, 0, 8); + test(*r->s3, 1, 8, *r->s2, 4, 1, -3); + test(*r->s3, 1, 8, *r->s2, 4, 2, -3); + test(*r->s3, 1, 8, *r->s2, 5, 0, 8); + test(*r->s3, 1, 8, *r->s2, 5, 1, 8); + test(*r->s3, 1, 8, *r->s2, 6, 0, 0); + test(*r->s3, 1, 8, *r->s3, 0, 0, 8); + test(*r->s3, 1, 8, *r->s3, 0, 1, 1); + test(*r->s3, 1, 8, *r->s3, 0, 5, 1); + test(*r->s3, 1, 8, *r->s3, 0, 9, 1); + test(*r->s3, 1, 8, *r->s3, 0, 10, 1); + test(*r->s3, 1, 8, *r->s3, 0, 11, 1); + test(*r->s3, 1, 8, *r->s3, 1, 0, 8); + test(*r->s3, 1, 8, *r->s3, 1, 1, 7); + test(*r->s3, 1, 8, *r->s3, 1, 4, 4); + test(*r->s3, 1, 8, *r->s3, 1, 8, 0); + test(*r->s3, 1, 8, *r->s3, 1, 9, -1); + test(*r->s3, 1, 8, *r->s3, 1, 10, -1); + test(*r->s3, 1, 8, *r->s3, 5, 0, 8); + test(*r->s3, 1, 8, *r->s3, 5, 1, -4); + test(*r->s3, 1, 8, *r->s3, 5, 2, -4); + test(*r->s3, 1, 8, *r->s3, 5, 4, -4); + test(*r->s3, 1, 8, *r->s3, 5, 5, -4); + test(*r->s3, 1, 8, *r->s3, 5, 6, -4); + test(*r->s3, 1, 8, *r->s3, 9, 0, 8); + test(*r->s3, 1, 8, *r->s3, 9, 1, -8); + test(*r->s3, 1, 8, *r->s3, 9, 2, -8); + test(*r->s3, 1, 8, *r->s3, 10, 0, 8); + test(*r->s3, 1, 8, *r->s3, 10, 1, 8); + test(*r->s3, 1, 8, *r->s3, 11, 0, 0); + test(*r->s3, 1, 8, *r->s4, 0, 0, 8); + test(*r->s3, 1, 8, *r->s4, 0, 1, 1); + test(*r->s3, 1, 8, *r->s4, 0, 10, 1); + test(*r->s3, 1, 8, *r->s4, 0, 19, 1); + test(*r->s3, 1, 8, *r->s4, 0, 20, 1); + test(*r->s3, 1, 8, *r->s4, 0, 21, 1); + test(*r->s3, 1, 8, *r->s4, 1, 0, 8); + test(*r->s3, 1, 8, *r->s4, 1, 1, 7); + test(*r->s3, 1, 8, *r->s4, 1, 9, -1); + test(*r->s3, 1, 8, *r->s4, 1, 18, -10); + test(*r->s3, 1, 8, *r->s4, 1, 19, -11); + test(*r->s3, 1, 8, *r->s4, 1, 20, -11); + test(*r->s3, 1, 8, *r->s4, 10, 0, 8); + test(*r->s3, 1, 8, *r->s4, 10, 1, -9); + test(*r->s3, 1, 8, *r->s4, 10, 5, -9); + test(*r->s3, 1, 8, *r->s4, 10, 9, -9); + test(*r->s3, 1, 8, *r->s4, 10, 10, -9); + test(*r->s3, 1, 8, *r->s4, 10, 11, -9); + test(*r->s3, 1, 8, *r->s4, 19, 0, 8); + test(*r->s3, 1, 8, *r->s4, 19, 1, -18); + test(*r->s3, 1, 8, *r->s4, 19, 2, -18); + test(*r->s3, 1, 8, *r->s4, 20, 0, 8); + test(*r->s3, 1, 8, *r->s4, 20, 1, 8); + test(*r->s3, 1, 8, *r->s4, 21, 0, 0); + test(*r->s3, 1, 9, *r->s1, 0, 0, 9); + test(*r->s3, 1, 9, *r->s1, 0, 1, 9); + test(*r->s3, 1, 9, *r->s1, 1, 0, 0); + test(*r->s3, 1, 9, *r->s2, 0, 0, 9); + test(*r->s3, 1, 9, *r->s2, 0, 1, 1); + test(*r->s3, 1, 9, *r->s2, 0, 2, 1); + test(*r->s3, 1, 9, *r->s2, 0, 4, 1); + test(*r->s3, 1, 9, *r->s2, 0, 5, 1); + test(*r->s3, 1, 9, *r->s2, 0, 6, 1); + test(*r->s3, 1, 9, *r->s2, 1, 0, 9); + test(*r->s3, 1, 9, *r->s2, 1, 1, 8); + test(*r->s3, 1, 9, *r->s2, 1, 2, 7); + test(*r->s3, 1, 9, *r->s2, 1, 3, 6); + test(*r->s3, 1, 9, *r->s2, 1, 4, 5); + test(*r->s3, 1, 9, *r->s2, 1, 5, 5); + test(*r->s3, 1, 9, *r->s2, 2, 0, 9); + test(*r->s3, 1, 9, *r->s2, 2, 1, -1); + test(*r->s3, 1, 9, *r->s2, 2, 2, -1); + test(*r->s3, 1, 9, *r->s2, 2, 3, -1); + test(*r->s3, 1, 9, *r->s2, 2, 4, -1); + test(*r->s3, 1, 9, *r->s2, 4, 0, 9); + test(*r->s3, 1, 9, *r->s2, 4, 1, -3); + test(*r->s3, 1, 9, *r->s2, 4, 2, -3); + test(*r->s3, 1, 9, *r->s2, 5, 0, 9); + test(*r->s3, 1, 9, *r->s2, 5, 1, 9); + test(*r->s3, 1, 9, *r->s2, 6, 0, 0); + test(*r->s3, 1, 9, *r->s3, 0, 0, 9); + test(*r->s3, 1, 9, *r->s3, 0, 1, 1); + test(*r->s3, 1, 9, *r->s3, 0, 5, 1); + test(*r->s3, 1, 9, *r->s3, 0, 9, 1); + test(*r->s3, 1, 9, *r->s3, 0, 10, 1); + test(*r->s3, 1, 9, *r->s3, 0, 11, 1); + test(*r->s3, 1, 9, *r->s3, 1, 0, 9); + test(*r->s3, 1, 9, *r->s3, 1, 1, 8); + test(*r->s3, 1, 9, *r->s3, 1, 4, 5); + test(*r->s3, 1, 9, *r->s3, 1, 8, 1); +} + +template +void +test27(pmem::obj::persistent_ptr &r) +{ + test(*r->s3, 1, 9, *r->s3, 1, 9, 0); + test(*r->s3, 1, 9, *r->s3, 1, 10, 0); + test(*r->s3, 1, 9, *r->s3, 5, 0, 9); + test(*r->s3, 1, 9, *r->s3, 5, 1, -4); + test(*r->s3, 1, 9, *r->s3, 5, 2, -4); + test(*r->s3, 1, 9, *r->s3, 5, 4, -4); + test(*r->s3, 1, 9, *r->s3, 5, 5, -4); + test(*r->s3, 1, 9, *r->s3, 5, 6, -4); + test(*r->s3, 1, 9, *r->s3, 9, 0, 9); + test(*r->s3, 1, 9, *r->s3, 9, 1, -8); + test(*r->s3, 1, 9, *r->s3, 9, 2, -8); + test(*r->s3, 1, 9, *r->s3, 10, 0, 9); + test(*r->s3, 1, 9, *r->s3, 10, 1, 9); + test(*r->s3, 1, 9, *r->s3, 11, 0, 0); + test(*r->s3, 1, 9, *r->s4, 0, 0, 9); + test(*r->s3, 1, 9, *r->s4, 0, 1, 1); + test(*r->s3, 1, 9, *r->s4, 0, 10, 1); + test(*r->s3, 1, 9, *r->s4, 0, 19, 1); + test(*r->s3, 1, 9, *r->s4, 0, 20, 1); + test(*r->s3, 1, 9, *r->s4, 0, 21, 1); + test(*r->s3, 1, 9, *r->s4, 1, 0, 9); + test(*r->s3, 1, 9, *r->s4, 1, 1, 8); + test(*r->s3, 1, 9, *r->s4, 1, 9, 0); + test(*r->s3, 1, 9, *r->s4, 1, 18, -9); + test(*r->s3, 1, 9, *r->s4, 1, 19, -10); + test(*r->s3, 1, 9, *r->s4, 1, 20, -10); + test(*r->s3, 1, 9, *r->s4, 10, 0, 9); + test(*r->s3, 1, 9, *r->s4, 10, 1, -9); + test(*r->s3, 1, 9, *r->s4, 10, 5, -9); + test(*r->s3, 1, 9, *r->s4, 10, 9, -9); + test(*r->s3, 1, 9, *r->s4, 10, 10, -9); + test(*r->s3, 1, 9, *r->s4, 10, 11, -9); + test(*r->s3, 1, 9, *r->s4, 19, 0, 9); + test(*r->s3, 1, 9, *r->s4, 19, 1, -18); + test(*r->s3, 1, 9, *r->s4, 19, 2, -18); + test(*r->s3, 1, 9, *r->s4, 20, 0, 9); + test(*r->s3, 1, 9, *r->s4, 20, 1, 9); + test(*r->s3, 1, 9, *r->s4, 21, 0, 0); + test(*r->s3, 1, 10, *r->s1, 0, 0, 9); + test(*r->s3, 1, 10, *r->s1, 0, 1, 9); + test(*r->s3, 1, 10, *r->s1, 1, 0, 0); + test(*r->s3, 1, 10, *r->s2, 0, 0, 9); + test(*r->s3, 1, 10, *r->s2, 0, 1, 1); + test(*r->s3, 1, 10, *r->s2, 0, 2, 1); + test(*r->s3, 1, 10, *r->s2, 0, 4, 1); + test(*r->s3, 1, 10, *r->s2, 0, 5, 1); + test(*r->s3, 1, 10, *r->s2, 0, 6, 1); + test(*r->s3, 1, 10, *r->s2, 1, 0, 9); + test(*r->s3, 1, 10, *r->s2, 1, 1, 8); + test(*r->s3, 1, 10, *r->s2, 1, 2, 7); + test(*r->s3, 1, 10, *r->s2, 1, 3, 6); + test(*r->s3, 1, 10, *r->s2, 1, 4, 5); + test(*r->s3, 1, 10, *r->s2, 1, 5, 5); + test(*r->s3, 1, 10, *r->s2, 2, 0, 9); + test(*r->s3, 1, 10, *r->s2, 2, 1, -1); + test(*r->s3, 1, 10, *r->s2, 2, 2, -1); + test(*r->s3, 1, 10, *r->s2, 2, 3, -1); + test(*r->s3, 1, 10, *r->s2, 2, 4, -1); + test(*r->s3, 1, 10, *r->s2, 4, 0, 9); + test(*r->s3, 1, 10, *r->s2, 4, 1, -3); + test(*r->s3, 1, 10, *r->s2, 4, 2, -3); + test(*r->s3, 1, 10, *r->s2, 5, 0, 9); + test(*r->s3, 1, 10, *r->s2, 5, 1, 9); + test(*r->s3, 1, 10, *r->s2, 6, 0, 0); + test(*r->s3, 1, 10, *r->s3, 0, 0, 9); + test(*r->s3, 1, 10, *r->s3, 0, 1, 1); + test(*r->s3, 1, 10, *r->s3, 0, 5, 1); + test(*r->s3, 1, 10, *r->s3, 0, 9, 1); + test(*r->s3, 1, 10, *r->s3, 0, 10, 1); + test(*r->s3, 1, 10, *r->s3, 0, 11, 1); + test(*r->s3, 1, 10, *r->s3, 1, 0, 9); + test(*r->s3, 1, 10, *r->s3, 1, 1, 8); + test(*r->s3, 1, 10, *r->s3, 1, 4, 5); + test(*r->s3, 1, 10, *r->s3, 1, 8, 1); + test(*r->s3, 1, 10, *r->s3, 1, 9, 0); + test(*r->s3, 1, 10, *r->s3, 1, 10, 0); + test(*r->s3, 1, 10, *r->s3, 5, 0, 9); + test(*r->s3, 1, 10, *r->s3, 5, 1, -4); + test(*r->s3, 1, 10, *r->s3, 5, 2, -4); + test(*r->s3, 1, 10, *r->s3, 5, 4, -4); + test(*r->s3, 1, 10, *r->s3, 5, 5, -4); + test(*r->s3, 1, 10, *r->s3, 5, 6, -4); + test(*r->s3, 1, 10, *r->s3, 9, 0, 9); + test(*r->s3, 1, 10, *r->s3, 9, 1, -8); + test(*r->s3, 1, 10, *r->s3, 9, 2, -8); + test(*r->s3, 1, 10, *r->s3, 10, 0, 9); + test(*r->s3, 1, 10, *r->s3, 10, 1, 9); + test(*r->s3, 1, 10, *r->s3, 11, 0, 0); + test(*r->s3, 1, 10, *r->s4, 0, 0, 9); + test(*r->s3, 1, 10, *r->s4, 0, 1, 1); + test(*r->s3, 1, 10, *r->s4, 0, 10, 1); + test(*r->s3, 1, 10, *r->s4, 0, 19, 1); + test(*r->s3, 1, 10, *r->s4, 0, 20, 1); + test(*r->s3, 1, 10, *r->s4, 0, 21, 1); + test(*r->s3, 1, 10, *r->s4, 1, 0, 9); + test(*r->s3, 1, 10, *r->s4, 1, 1, 8); + test(*r->s3, 1, 10, *r->s4, 1, 9, 0); + test(*r->s3, 1, 10, *r->s4, 1, 18, -9); + test(*r->s3, 1, 10, *r->s4, 1, 19, -10); + test(*r->s3, 1, 10, *r->s4, 1, 20, -10); +} + +template +void +test28(pmem::obj::persistent_ptr &r) +{ + test(*r->s3, 1, 10, *r->s4, 10, 0, 9); + test(*r->s3, 1, 10, *r->s4, 10, 1, -9); + test(*r->s3, 1, 10, *r->s4, 10, 5, -9); + test(*r->s3, 1, 10, *r->s4, 10, 9, -9); + test(*r->s3, 1, 10, *r->s4, 10, 10, -9); + test(*r->s3, 1, 10, *r->s4, 10, 11, -9); + test(*r->s3, 1, 10, *r->s4, 19, 0, 9); + test(*r->s3, 1, 10, *r->s4, 19, 1, -18); + test(*r->s3, 1, 10, *r->s4, 19, 2, -18); + test(*r->s3, 1, 10, *r->s4, 20, 0, 9); + test(*r->s3, 1, 10, *r->s4, 20, 1, 9); + test(*r->s3, 1, 10, *r->s4, 21, 0, 0); + test(*r->s3, 5, 0, *r->s1, 0, 0, 0); + test(*r->s3, 5, 0, *r->s1, 0, 1, 0); + test(*r->s3, 5, 0, *r->s1, 1, 0, 0); + test(*r->s3, 5, 0, *r->s2, 0, 0, 0); + test(*r->s3, 5, 0, *r->s2, 0, 1, -1); + test(*r->s3, 5, 0, *r->s2, 0, 2, -2); + test(*r->s3, 5, 0, *r->s2, 0, 4, -4); + test(*r->s3, 5, 0, *r->s2, 0, 5, -5); + test(*r->s3, 5, 0, *r->s2, 0, 6, -5); + test(*r->s3, 5, 0, *r->s2, 1, 0, 0); + test(*r->s3, 5, 0, *r->s2, 1, 1, -1); + test(*r->s3, 5, 0, *r->s2, 1, 2, -2); + test(*r->s3, 5, 0, *r->s2, 1, 3, -3); + test(*r->s3, 5, 0, *r->s2, 1, 4, -4); + test(*r->s3, 5, 0, *r->s2, 1, 5, -4); + test(*r->s3, 5, 0, *r->s2, 2, 0, 0); + test(*r->s3, 5, 0, *r->s2, 2, 1, -1); + test(*r->s3, 5, 0, *r->s2, 2, 2, -2); + test(*r->s3, 5, 0, *r->s2, 2, 3, -3); + test(*r->s3, 5, 0, *r->s2, 2, 4, -3); + test(*r->s3, 5, 0, *r->s2, 4, 0, 0); + test(*r->s3, 5, 0, *r->s2, 4, 1, -1); + test(*r->s3, 5, 0, *r->s2, 4, 2, -1); + test(*r->s3, 5, 0, *r->s2, 5, 0, 0); + test(*r->s3, 5, 0, *r->s2, 5, 1, 0); + test(*r->s3, 5, 0, *r->s2, 6, 0, 0); + test(*r->s3, 5, 0, *r->s3, 0, 0, 0); + test(*r->s3, 5, 0, *r->s3, 0, 1, -1); + test(*r->s3, 5, 0, *r->s3, 0, 5, -5); + test(*r->s3, 5, 0, *r->s3, 0, 9, -9); + test(*r->s3, 5, 0, *r->s3, 0, 10, -10); + test(*r->s3, 5, 0, *r->s3, 0, 11, -10); + test(*r->s3, 5, 0, *r->s3, 1, 0, 0); + test(*r->s3, 5, 0, *r->s3, 1, 1, -1); + test(*r->s3, 5, 0, *r->s3, 1, 4, -4); + test(*r->s3, 5, 0, *r->s3, 1, 8, -8); + test(*r->s3, 5, 0, *r->s3, 1, 9, -9); + test(*r->s3, 5, 0, *r->s3, 1, 10, -9); + test(*r->s3, 5, 0, *r->s3, 5, 0, 0); + test(*r->s3, 5, 0, *r->s3, 5, 1, -1); + test(*r->s3, 5, 0, *r->s3, 5, 2, -2); + test(*r->s3, 5, 0, *r->s3, 5, 4, -4); + test(*r->s3, 5, 0, *r->s3, 5, 5, -5); + test(*r->s3, 5, 0, *r->s3, 5, 6, -5); + test(*r->s3, 5, 0, *r->s3, 9, 0, 0); + test(*r->s3, 5, 0, *r->s3, 9, 1, -1); + test(*r->s3, 5, 0, *r->s3, 9, 2, -1); + test(*r->s3, 5, 0, *r->s3, 10, 0, 0); + test(*r->s3, 5, 0, *r->s3, 10, 1, 0); + test(*r->s3, 5, 0, *r->s3, 11, 0, 0); + test(*r->s3, 5, 0, *r->s4, 0, 0, 0); + test(*r->s3, 5, 0, *r->s4, 0, 1, -1); + test(*r->s3, 5, 0, *r->s4, 0, 10, -10); + test(*r->s3, 5, 0, *r->s4, 0, 19, -19); + test(*r->s3, 5, 0, *r->s4, 0, 20, -20); + test(*r->s3, 5, 0, *r->s4, 0, 21, -20); + test(*r->s3, 5, 0, *r->s4, 1, 0, 0); + test(*r->s3, 5, 0, *r->s4, 1, 1, -1); + test(*r->s3, 5, 0, *r->s4, 1, 9, -9); + test(*r->s3, 5, 0, *r->s4, 1, 18, -18); + test(*r->s3, 5, 0, *r->s4, 1, 19, -19); + test(*r->s3, 5, 0, *r->s4, 1, 20, -19); + test(*r->s3, 5, 0, *r->s4, 10, 0, 0); + test(*r->s3, 5, 0, *r->s4, 10, 1, -1); + test(*r->s3, 5, 0, *r->s4, 10, 5, -5); + test(*r->s3, 5, 0, *r->s4, 10, 9, -9); + test(*r->s3, 5, 0, *r->s4, 10, 10, -10); + test(*r->s3, 5, 0, *r->s4, 10, 11, -10); + test(*r->s3, 5, 0, *r->s4, 19, 0, 0); + test(*r->s3, 5, 0, *r->s4, 19, 1, -1); + test(*r->s3, 5, 0, *r->s4, 19, 2, -1); + test(*r->s3, 5, 0, *r->s4, 20, 0, 0); + test(*r->s3, 5, 0, *r->s4, 20, 1, 0); + test(*r->s3, 5, 0, *r->s4, 21, 0, 0); + test(*r->s3, 5, 1, *r->s1, 0, 0, 1); + test(*r->s3, 5, 1, *r->s1, 0, 1, 1); + test(*r->s3, 5, 1, *r->s1, 1, 0, 0); + test(*r->s3, 5, 1, *r->s2, 0, 0, 1); + test(*r->s3, 5, 1, *r->s2, 0, 1, 5); + test(*r->s3, 5, 1, *r->s2, 0, 2, 5); + test(*r->s3, 5, 1, *r->s2, 0, 4, 5); + test(*r->s3, 5, 1, *r->s2, 0, 5, 5); + test(*r->s3, 5, 1, *r->s2, 0, 6, 5); + test(*r->s3, 5, 1, *r->s2, 1, 0, 1); + test(*r->s3, 5, 1, *r->s2, 1, 1, 4); + test(*r->s3, 5, 1, *r->s2, 1, 2, 4); + test(*r->s3, 5, 1, *r->s2, 1, 3, 4); + test(*r->s3, 5, 1, *r->s2, 1, 4, 4); +} + +template +void +test29(pmem::obj::persistent_ptr &r) +{ + test(*r->s3, 5, 1, *r->s2, 1, 5, 4); + test(*r->s3, 5, 1, *r->s2, 2, 0, 1); + test(*r->s3, 5, 1, *r->s2, 2, 1, 3); + test(*r->s3, 5, 1, *r->s2, 2, 2, 3); + test(*r->s3, 5, 1, *r->s2, 2, 3, 3); + test(*r->s3, 5, 1, *r->s2, 2, 4, 3); + test(*r->s3, 5, 1, *r->s2, 4, 0, 1); + test(*r->s3, 5, 1, *r->s2, 4, 1, 1); + test(*r->s3, 5, 1, *r->s2, 4, 2, 1); + test(*r->s3, 5, 1, *r->s2, 5, 0, 1); + test(*r->s3, 5, 1, *r->s2, 5, 1, 1); + test(*r->s3, 5, 1, *r->s2, 6, 0, 0); + test(*r->s3, 5, 1, *r->s3, 0, 0, 1); + test(*r->s3, 5, 1, *r->s3, 0, 1, 5); + test(*r->s3, 5, 1, *r->s3, 0, 5, 5); + test(*r->s3, 5, 1, *r->s3, 0, 9, 5); + test(*r->s3, 5, 1, *r->s3, 0, 10, 5); + test(*r->s3, 5, 1, *r->s3, 0, 11, 5); + test(*r->s3, 5, 1, *r->s3, 1, 0, 1); + test(*r->s3, 5, 1, *r->s3, 1, 1, 4); + test(*r->s3, 5, 1, *r->s3, 1, 4, 4); + test(*r->s3, 5, 1, *r->s3, 1, 8, 4); + test(*r->s3, 5, 1, *r->s3, 1, 9, 4); + test(*r->s3, 5, 1, *r->s3, 1, 10, 4); + test(*r->s3, 5, 1, *r->s3, 5, 0, 1); + test(*r->s3, 5, 1, *r->s3, 5, 1, 0); + test(*r->s3, 5, 1, *r->s3, 5, 2, -1); + test(*r->s3, 5, 1, *r->s3, 5, 4, -3); + test(*r->s3, 5, 1, *r->s3, 5, 5, -4); + test(*r->s3, 5, 1, *r->s3, 5, 6, -4); + test(*r->s3, 5, 1, *r->s3, 9, 0, 1); + test(*r->s3, 5, 1, *r->s3, 9, 1, -4); + test(*r->s3, 5, 1, *r->s3, 9, 2, -4); + test(*r->s3, 5, 1, *r->s3, 10, 0, 1); + test(*r->s3, 5, 1, *r->s3, 10, 1, 1); + test(*r->s3, 5, 1, *r->s3, 11, 0, 0); + test(*r->s3, 5, 1, *r->s4, 0, 0, 1); + test(*r->s3, 5, 1, *r->s4, 0, 1, 5); + test(*r->s3, 5, 1, *r->s4, 0, 10, 5); + test(*r->s3, 5, 1, *r->s4, 0, 19, 5); + test(*r->s3, 5, 1, *r->s4, 0, 20, 5); + test(*r->s3, 5, 1, *r->s4, 0, 21, 5); + test(*r->s3, 5, 1, *r->s4, 1, 0, 1); + test(*r->s3, 5, 1, *r->s4, 1, 1, 4); + test(*r->s3, 5, 1, *r->s4, 1, 9, 4); + test(*r->s3, 5, 1, *r->s4, 1, 18, 4); + test(*r->s3, 5, 1, *r->s4, 1, 19, 4); + test(*r->s3, 5, 1, *r->s4, 1, 20, 4); + test(*r->s3, 5, 1, *r->s4, 10, 0, 1); + test(*r->s3, 5, 1, *r->s4, 10, 1, -5); + test(*r->s3, 5, 1, *r->s4, 10, 5, -5); + test(*r->s3, 5, 1, *r->s4, 10, 9, -5); + test(*r->s3, 5, 1, *r->s4, 10, 10, -5); + test(*r->s3, 5, 1, *r->s4, 10, 11, -5); + test(*r->s3, 5, 1, *r->s4, 19, 0, 1); + test(*r->s3, 5, 1, *r->s4, 19, 1, -14); + test(*r->s3, 5, 1, *r->s4, 19, 2, -14); + test(*r->s3, 5, 1, *r->s4, 20, 0, 1); + test(*r->s3, 5, 1, *r->s4, 20, 1, 1); + test(*r->s3, 5, 1, *r->s4, 21, 0, 0); + test(*r->s3, 5, 2, *r->s1, 0, 0, 2); + test(*r->s3, 5, 2, *r->s1, 0, 1, 2); + test(*r->s3, 5, 2, *r->s1, 1, 0, 0); + test(*r->s3, 5, 2, *r->s2, 0, 0, 2); + test(*r->s3, 5, 2, *r->s2, 0, 1, 5); + test(*r->s3, 5, 2, *r->s2, 0, 2, 5); + test(*r->s3, 5, 2, *r->s2, 0, 4, 5); + test(*r->s3, 5, 2, *r->s2, 0, 5, 5); + test(*r->s3, 5, 2, *r->s2, 0, 6, 5); + test(*r->s3, 5, 2, *r->s2, 1, 0, 2); + test(*r->s3, 5, 2, *r->s2, 1, 1, 4); + test(*r->s3, 5, 2, *r->s2, 1, 2, 4); + test(*r->s3, 5, 2, *r->s2, 1, 3, 4); + test(*r->s3, 5, 2, *r->s2, 1, 4, 4); + test(*r->s3, 5, 2, *r->s2, 1, 5, 4); + test(*r->s3, 5, 2, *r->s2, 2, 0, 2); + test(*r->s3, 5, 2, *r->s2, 2, 1, 3); + test(*r->s3, 5, 2, *r->s2, 2, 2, 3); + test(*r->s3, 5, 2, *r->s2, 2, 3, 3); + test(*r->s3, 5, 2, *r->s2, 2, 4, 3); + test(*r->s3, 5, 2, *r->s2, 4, 0, 2); + test(*r->s3, 5, 2, *r->s2, 4, 1, 1); + test(*r->s3, 5, 2, *r->s2, 4, 2, 1); + test(*r->s3, 5, 2, *r->s2, 5, 0, 2); + test(*r->s3, 5, 2, *r->s2, 5, 1, 2); + test(*r->s3, 5, 2, *r->s2, 6, 0, 0); + test(*r->s3, 5, 2, *r->s3, 0, 0, 2); + test(*r->s3, 5, 2, *r->s3, 0, 1, 5); + test(*r->s3, 5, 2, *r->s3, 0, 5, 5); + test(*r->s3, 5, 2, *r->s3, 0, 9, 5); + test(*r->s3, 5, 2, *r->s3, 0, 10, 5); + test(*r->s3, 5, 2, *r->s3, 0, 11, 5); + test(*r->s3, 5, 2, *r->s3, 1, 0, 2); + test(*r->s3, 5, 2, *r->s3, 1, 1, 4); + test(*r->s3, 5, 2, *r->s3, 1, 4, 4); + test(*r->s3, 5, 2, *r->s3, 1, 8, 4); + test(*r->s3, 5, 2, *r->s3, 1, 9, 4); + test(*r->s3, 5, 2, *r->s3, 1, 10, 4); + test(*r->s3, 5, 2, *r->s3, 5, 0, 2); + test(*r->s3, 5, 2, *r->s3, 5, 1, 1); +} + +template +void +test30(pmem::obj::persistent_ptr &r) +{ + test(*r->s3, 5, 2, *r->s3, 5, 2, 0); + test(*r->s3, 5, 2, *r->s3, 5, 4, -2); + test(*r->s3, 5, 2, *r->s3, 5, 5, -3); + test(*r->s3, 5, 2, *r->s3, 5, 6, -3); + test(*r->s3, 5, 2, *r->s3, 9, 0, 2); + test(*r->s3, 5, 2, *r->s3, 9, 1, -4); + test(*r->s3, 5, 2, *r->s3, 9, 2, -4); + test(*r->s3, 5, 2, *r->s3, 10, 0, 2); + test(*r->s3, 5, 2, *r->s3, 10, 1, 2); + test(*r->s3, 5, 2, *r->s3, 11, 0, 0); + test(*r->s3, 5, 2, *r->s4, 0, 0, 2); + test(*r->s3, 5, 2, *r->s4, 0, 1, 5); + test(*r->s3, 5, 2, *r->s4, 0, 10, 5); + test(*r->s3, 5, 2, *r->s4, 0, 19, 5); + test(*r->s3, 5, 2, *r->s4, 0, 20, 5); + test(*r->s3, 5, 2, *r->s4, 0, 21, 5); + test(*r->s3, 5, 2, *r->s4, 1, 0, 2); + test(*r->s3, 5, 2, *r->s4, 1, 1, 4); + test(*r->s3, 5, 2, *r->s4, 1, 9, 4); + test(*r->s3, 5, 2, *r->s4, 1, 18, 4); + test(*r->s3, 5, 2, *r->s4, 1, 19, 4); + test(*r->s3, 5, 2, *r->s4, 1, 20, 4); + test(*r->s3, 5, 2, *r->s4, 10, 0, 2); + test(*r->s3, 5, 2, *r->s4, 10, 1, -5); + test(*r->s3, 5, 2, *r->s4, 10, 5, -5); + test(*r->s3, 5, 2, *r->s4, 10, 9, -5); + test(*r->s3, 5, 2, *r->s4, 10, 10, -5); + test(*r->s3, 5, 2, *r->s4, 10, 11, -5); + test(*r->s3, 5, 2, *r->s4, 19, 0, 2); + test(*r->s3, 5, 2, *r->s4, 19, 1, -14); + test(*r->s3, 5, 2, *r->s4, 19, 2, -14); + test(*r->s3, 5, 2, *r->s4, 20, 0, 2); + test(*r->s3, 5, 2, *r->s4, 20, 1, 2); + test(*r->s3, 5, 2, *r->s4, 21, 0, 0); + test(*r->s3, 5, 4, *r->s1, 0, 0, 4); + test(*r->s3, 5, 4, *r->s1, 0, 1, 4); + test(*r->s3, 5, 4, *r->s1, 1, 0, 0); + test(*r->s3, 5, 4, *r->s2, 0, 0, 4); + test(*r->s3, 5, 4, *r->s2, 0, 1, 5); + test(*r->s3, 5, 4, *r->s2, 0, 2, 5); + test(*r->s3, 5, 4, *r->s2, 0, 4, 5); + test(*r->s3, 5, 4, *r->s2, 0, 5, 5); + test(*r->s3, 5, 4, *r->s2, 0, 6, 5); + test(*r->s3, 5, 4, *r->s2, 1, 0, 4); + test(*r->s3, 5, 4, *r->s2, 1, 1, 4); + test(*r->s3, 5, 4, *r->s2, 1, 2, 4); + test(*r->s3, 5, 4, *r->s2, 1, 3, 4); + test(*r->s3, 5, 4, *r->s2, 1, 4, 4); + test(*r->s3, 5, 4, *r->s2, 1, 5, 4); + test(*r->s3, 5, 4, *r->s2, 2, 0, 4); + test(*r->s3, 5, 4, *r->s2, 2, 1, 3); + test(*r->s3, 5, 4, *r->s2, 2, 2, 3); + test(*r->s3, 5, 4, *r->s2, 2, 3, 3); + test(*r->s3, 5, 4, *r->s2, 2, 4, 3); + test(*r->s3, 5, 4, *r->s2, 4, 0, 4); + test(*r->s3, 5, 4, *r->s2, 4, 1, 1); + test(*r->s3, 5, 4, *r->s2, 4, 2, 1); + test(*r->s3, 5, 4, *r->s2, 5, 0, 4); + test(*r->s3, 5, 4, *r->s2, 5, 1, 4); + test(*r->s3, 5, 4, *r->s2, 6, 0, 0); + test(*r->s3, 5, 4, *r->s3, 0, 0, 4); + test(*r->s3, 5, 4, *r->s3, 0, 1, 5); + test(*r->s3, 5, 4, *r->s3, 0, 5, 5); + test(*r->s3, 5, 4, *r->s3, 0, 9, 5); + test(*r->s3, 5, 4, *r->s3, 0, 10, 5); + test(*r->s3, 5, 4, *r->s3, 0, 11, 5); + test(*r->s3, 5, 4, *r->s3, 1, 0, 4); + test(*r->s3, 5, 4, *r->s3, 1, 1, 4); + test(*r->s3, 5, 4, *r->s3, 1, 4, 4); + test(*r->s3, 5, 4, *r->s3, 1, 8, 4); + test(*r->s3, 5, 4, *r->s3, 1, 9, 4); + test(*r->s3, 5, 4, *r->s3, 1, 10, 4); + test(*r->s3, 5, 4, *r->s3, 5, 0, 4); + test(*r->s3, 5, 4, *r->s3, 5, 1, 3); + test(*r->s3, 5, 4, *r->s3, 5, 2, 2); + test(*r->s3, 5, 4, *r->s3, 5, 4, 0); + test(*r->s3, 5, 4, *r->s3, 5, 5, -1); + test(*r->s3, 5, 4, *r->s3, 5, 6, -1); + test(*r->s3, 5, 4, *r->s3, 9, 0, 4); + test(*r->s3, 5, 4, *r->s3, 9, 1, -4); + test(*r->s3, 5, 4, *r->s3, 9, 2, -4); + test(*r->s3, 5, 4, *r->s3, 10, 0, 4); + test(*r->s3, 5, 4, *r->s3, 10, 1, 4); + test(*r->s3, 5, 4, *r->s3, 11, 0, 0); + test(*r->s3, 5, 4, *r->s4, 0, 0, 4); + test(*r->s3, 5, 4, *r->s4, 0, 1, 5); + test(*r->s3, 5, 4, *r->s4, 0, 10, 5); + test(*r->s3, 5, 4, *r->s4, 0, 19, 5); + test(*r->s3, 5, 4, *r->s4, 0, 20, 5); + test(*r->s3, 5, 4, *r->s4, 0, 21, 5); + test(*r->s3, 5, 4, *r->s4, 1, 0, 4); + test(*r->s3, 5, 4, *r->s4, 1, 1, 4); + test(*r->s3, 5, 4, *r->s4, 1, 9, 4); + test(*r->s3, 5, 4, *r->s4, 1, 18, 4); + test(*r->s3, 5, 4, *r->s4, 1, 19, 4); + test(*r->s3, 5, 4, *r->s4, 1, 20, 4); + test(*r->s3, 5, 4, *r->s4, 10, 0, 4); + test(*r->s3, 5, 4, *r->s4, 10, 1, -5); + test(*r->s3, 5, 4, *r->s4, 10, 5, -5); + test(*r->s3, 5, 4, *r->s4, 10, 9, -5); +} + +template +void +test31(pmem::obj::persistent_ptr &r) +{ + test(*r->s3, 5, 4, *r->s4, 10, 10, -5); + test(*r->s3, 5, 4, *r->s4, 10, 11, -5); + test(*r->s3, 5, 4, *r->s4, 19, 0, 4); + test(*r->s3, 5, 4, *r->s4, 19, 1, -14); + test(*r->s3, 5, 4, *r->s4, 19, 2, -14); + test(*r->s3, 5, 4, *r->s4, 20, 0, 4); + test(*r->s3, 5, 4, *r->s4, 20, 1, 4); + test(*r->s3, 5, 4, *r->s4, 21, 0, 0); + test(*r->s3, 5, 5, *r->s1, 0, 0, 5); + test(*r->s3, 5, 5, *r->s1, 0, 1, 5); + test(*r->s3, 5, 5, *r->s1, 1, 0, 0); + test(*r->s3, 5, 5, *r->s2, 0, 0, 5); + test(*r->s3, 5, 5, *r->s2, 0, 1, 5); + test(*r->s3, 5, 5, *r->s2, 0, 2, 5); + test(*r->s3, 5, 5, *r->s2, 0, 4, 5); + test(*r->s3, 5, 5, *r->s2, 0, 5, 5); + test(*r->s3, 5, 5, *r->s2, 0, 6, 5); + test(*r->s3, 5, 5, *r->s2, 1, 0, 5); + test(*r->s3, 5, 5, *r->s2, 1, 1, 4); + test(*r->s3, 5, 5, *r->s2, 1, 2, 4); + test(*r->s3, 5, 5, *r->s2, 1, 3, 4); + test(*r->s3, 5, 5, *r->s2, 1, 4, 4); + test(*r->s3, 5, 5, *r->s2, 1, 5, 4); + test(*r->s3, 5, 5, *r->s2, 2, 0, 5); + test(*r->s3, 5, 5, *r->s2, 2, 1, 3); + test(*r->s3, 5, 5, *r->s2, 2, 2, 3); + test(*r->s3, 5, 5, *r->s2, 2, 3, 3); + test(*r->s3, 5, 5, *r->s2, 2, 4, 3); + test(*r->s3, 5, 5, *r->s2, 4, 0, 5); + test(*r->s3, 5, 5, *r->s2, 4, 1, 1); + test(*r->s3, 5, 5, *r->s2, 4, 2, 1); + test(*r->s3, 5, 5, *r->s2, 5, 0, 5); + test(*r->s3, 5, 5, *r->s2, 5, 1, 5); + test(*r->s3, 5, 5, *r->s2, 6, 0, 0); + test(*r->s3, 5, 5, *r->s3, 0, 0, 5); + test(*r->s3, 5, 5, *r->s3, 0, 1, 5); + test(*r->s3, 5, 5, *r->s3, 0, 5, 5); + test(*r->s3, 5, 5, *r->s3, 0, 9, 5); + test(*r->s3, 5, 5, *r->s3, 0, 10, 5); + test(*r->s3, 5, 5, *r->s3, 0, 11, 5); + test(*r->s3, 5, 5, *r->s3, 1, 0, 5); + test(*r->s3, 5, 5, *r->s3, 1, 1, 4); + test(*r->s3, 5, 5, *r->s3, 1, 4, 4); + test(*r->s3, 5, 5, *r->s3, 1, 8, 4); + test(*r->s3, 5, 5, *r->s3, 1, 9, 4); + test(*r->s3, 5, 5, *r->s3, 1, 10, 4); + test(*r->s3, 5, 5, *r->s3, 5, 0, 5); + test(*r->s3, 5, 5, *r->s3, 5, 1, 4); + test(*r->s3, 5, 5, *r->s3, 5, 2, 3); + test(*r->s3, 5, 5, *r->s3, 5, 4, 1); + test(*r->s3, 5, 5, *r->s3, 5, 5, 0); + test(*r->s3, 5, 5, *r->s3, 5, 6, 0); + test(*r->s3, 5, 5, *r->s3, 9, 0, 5); + test(*r->s3, 5, 5, *r->s3, 9, 1, -4); + test(*r->s3, 5, 5, *r->s3, 9, 2, -4); + test(*r->s3, 5, 5, *r->s3, 10, 0, 5); + test(*r->s3, 5, 5, *r->s3, 10, 1, 5); + test(*r->s3, 5, 5, *r->s3, 11, 0, 0); + test(*r->s3, 5, 5, *r->s4, 0, 0, 5); + test(*r->s3, 5, 5, *r->s4, 0, 1, 5); + test(*r->s3, 5, 5, *r->s4, 0, 10, 5); + test(*r->s3, 5, 5, *r->s4, 0, 19, 5); + test(*r->s3, 5, 5, *r->s4, 0, 20, 5); + test(*r->s3, 5, 5, *r->s4, 0, 21, 5); + test(*r->s3, 5, 5, *r->s4, 1, 0, 5); + test(*r->s3, 5, 5, *r->s4, 1, 1, 4); + test(*r->s3, 5, 5, *r->s4, 1, 9, 4); + test(*r->s3, 5, 5, *r->s4, 1, 18, 4); + test(*r->s3, 5, 5, *r->s4, 1, 19, 4); + test(*r->s3, 5, 5, *r->s4, 1, 20, 4); + test(*r->s3, 5, 5, *r->s4, 10, 0, 5); + test(*r->s3, 5, 5, *r->s4, 10, 1, -5); + test(*r->s3, 5, 5, *r->s4, 10, 5, -5); + test(*r->s3, 5, 5, *r->s4, 10, 9, -5); + test(*r->s3, 5, 5, *r->s4, 10, 10, -5); + test(*r->s3, 5, 5, *r->s4, 10, 11, -5); + test(*r->s3, 5, 5, *r->s4, 19, 0, 5); + test(*r->s3, 5, 5, *r->s4, 19, 1, -14); + test(*r->s3, 5, 5, *r->s4, 19, 2, -14); + test(*r->s3, 5, 5, *r->s4, 20, 0, 5); + test(*r->s3, 5, 5, *r->s4, 20, 1, 5); + test(*r->s3, 5, 5, *r->s4, 21, 0, 0); + test(*r->s3, 5, 6, *r->s1, 0, 0, 5); + test(*r->s3, 5, 6, *r->s1, 0, 1, 5); + test(*r->s3, 5, 6, *r->s1, 1, 0, 0); + test(*r->s3, 5, 6, *r->s2, 0, 0, 5); + test(*r->s3, 5, 6, *r->s2, 0, 1, 5); + test(*r->s3, 5, 6, *r->s2, 0, 2, 5); + test(*r->s3, 5, 6, *r->s2, 0, 4, 5); + test(*r->s3, 5, 6, *r->s2, 0, 5, 5); + test(*r->s3, 5, 6, *r->s2, 0, 6, 5); + test(*r->s3, 5, 6, *r->s2, 1, 0, 5); + test(*r->s3, 5, 6, *r->s2, 1, 1, 4); + test(*r->s3, 5, 6, *r->s2, 1, 2, 4); + test(*r->s3, 5, 6, *r->s2, 1, 3, 4); + test(*r->s3, 5, 6, *r->s2, 1, 4, 4); + test(*r->s3, 5, 6, *r->s2, 1, 5, 4); + test(*r->s3, 5, 6, *r->s2, 2, 0, 5); + test(*r->s3, 5, 6, *r->s2, 2, 1, 3); + test(*r->s3, 5, 6, *r->s2, 2, 2, 3); +} + +template +void +test32(pmem::obj::persistent_ptr &r) +{ + test(*r->s3, 5, 6, *r->s2, 2, 3, 3); + test(*r->s3, 5, 6, *r->s2, 2, 4, 3); + test(*r->s3, 5, 6, *r->s2, 4, 0, 5); + test(*r->s3, 5, 6, *r->s2, 4, 1, 1); + test(*r->s3, 5, 6, *r->s2, 4, 2, 1); + test(*r->s3, 5, 6, *r->s2, 5, 0, 5); + test(*r->s3, 5, 6, *r->s2, 5, 1, 5); + test(*r->s3, 5, 6, *r->s2, 6, 0, 0); + test(*r->s3, 5, 6, *r->s3, 0, 0, 5); + test(*r->s3, 5, 6, *r->s3, 0, 1, 5); + test(*r->s3, 5, 6, *r->s3, 0, 5, 5); + test(*r->s3, 5, 6, *r->s3, 0, 9, 5); + test(*r->s3, 5, 6, *r->s3, 0, 10, 5); + test(*r->s3, 5, 6, *r->s3, 0, 11, 5); + test(*r->s3, 5, 6, *r->s3, 1, 0, 5); + test(*r->s3, 5, 6, *r->s3, 1, 1, 4); + test(*r->s3, 5, 6, *r->s3, 1, 4, 4); + test(*r->s3, 5, 6, *r->s3, 1, 8, 4); + test(*r->s3, 5, 6, *r->s3, 1, 9, 4); + test(*r->s3, 5, 6, *r->s3, 1, 10, 4); + test(*r->s3, 5, 6, *r->s3, 5, 0, 5); + test(*r->s3, 5, 6, *r->s3, 5, 1, 4); + test(*r->s3, 5, 6, *r->s3, 5, 2, 3); + test(*r->s3, 5, 6, *r->s3, 5, 4, 1); + test(*r->s3, 5, 6, *r->s3, 5, 5, 0); + test(*r->s3, 5, 6, *r->s3, 5, 6, 0); + test(*r->s3, 5, 6, *r->s3, 9, 0, 5); + test(*r->s3, 5, 6, *r->s3, 9, 1, -4); + test(*r->s3, 5, 6, *r->s3, 9, 2, -4); + test(*r->s3, 5, 6, *r->s3, 10, 0, 5); + test(*r->s3, 5, 6, *r->s3, 10, 1, 5); + test(*r->s3, 5, 6, *r->s3, 11, 0, 0); + test(*r->s3, 5, 6, *r->s4, 0, 0, 5); + test(*r->s3, 5, 6, *r->s4, 0, 1, 5); + test(*r->s3, 5, 6, *r->s4, 0, 10, 5); + test(*r->s3, 5, 6, *r->s4, 0, 19, 5); + test(*r->s3, 5, 6, *r->s4, 0, 20, 5); + test(*r->s3, 5, 6, *r->s4, 0, 21, 5); + test(*r->s3, 5, 6, *r->s4, 1, 0, 5); + test(*r->s3, 5, 6, *r->s4, 1, 1, 4); + test(*r->s3, 5, 6, *r->s4, 1, 9, 4); + test(*r->s3, 5, 6, *r->s4, 1, 18, 4); + test(*r->s3, 5, 6, *r->s4, 1, 19, 4); + test(*r->s3, 5, 6, *r->s4, 1, 20, 4); + test(*r->s3, 5, 6, *r->s4, 10, 0, 5); + test(*r->s3, 5, 6, *r->s4, 10, 1, -5); + test(*r->s3, 5, 6, *r->s4, 10, 5, -5); + test(*r->s3, 5, 6, *r->s4, 10, 9, -5); + test(*r->s3, 5, 6, *r->s4, 10, 10, -5); + test(*r->s3, 5, 6, *r->s4, 10, 11, -5); + test(*r->s3, 5, 6, *r->s4, 19, 0, 5); + test(*r->s3, 5, 6, *r->s4, 19, 1, -14); + test(*r->s3, 5, 6, *r->s4, 19, 2, -14); + test(*r->s3, 5, 6, *r->s4, 20, 0, 5); + test(*r->s3, 5, 6, *r->s4, 20, 1, 5); + test(*r->s3, 5, 6, *r->s4, 21, 0, 0); + test(*r->s3, 9, 0, *r->s1, 0, 0, 0); + test(*r->s3, 9, 0, *r->s1, 0, 1, 0); + test(*r->s3, 9, 0, *r->s1, 1, 0, 0); + test(*r->s3, 9, 0, *r->s2, 0, 0, 0); + test(*r->s3, 9, 0, *r->s2, 0, 1, -1); + test(*r->s3, 9, 0, *r->s2, 0, 2, -2); + test(*r->s3, 9, 0, *r->s2, 0, 4, -4); + test(*r->s3, 9, 0, *r->s2, 0, 5, -5); + test(*r->s3, 9, 0, *r->s2, 0, 6, -5); + test(*r->s3, 9, 0, *r->s2, 1, 0, 0); + test(*r->s3, 9, 0, *r->s2, 1, 1, -1); + test(*r->s3, 9, 0, *r->s2, 1, 2, -2); + test(*r->s3, 9, 0, *r->s2, 1, 3, -3); + test(*r->s3, 9, 0, *r->s2, 1, 4, -4); + test(*r->s3, 9, 0, *r->s2, 1, 5, -4); + test(*r->s3, 9, 0, *r->s2, 2, 0, 0); + test(*r->s3, 9, 0, *r->s2, 2, 1, -1); + test(*r->s3, 9, 0, *r->s2, 2, 2, -2); + test(*r->s3, 9, 0, *r->s2, 2, 3, -3); + test(*r->s3, 9, 0, *r->s2, 2, 4, -3); + test(*r->s3, 9, 0, *r->s2, 4, 0, 0); + test(*r->s3, 9, 0, *r->s2, 4, 1, -1); + test(*r->s3, 9, 0, *r->s2, 4, 2, -1); + test(*r->s3, 9, 0, *r->s2, 5, 0, 0); + test(*r->s3, 9, 0, *r->s2, 5, 1, 0); + test(*r->s3, 9, 0, *r->s2, 6, 0, 0); + test(*r->s3, 9, 0, *r->s3, 0, 0, 0); + test(*r->s3, 9, 0, *r->s3, 0, 1, -1); + test(*r->s3, 9, 0, *r->s3, 0, 5, -5); + test(*r->s3, 9, 0, *r->s3, 0, 9, -9); + test(*r->s3, 9, 0, *r->s3, 0, 10, -10); + test(*r->s3, 9, 0, *r->s3, 0, 11, -10); + test(*r->s3, 9, 0, *r->s3, 1, 0, 0); + test(*r->s3, 9, 0, *r->s3, 1, 1, -1); + test(*r->s3, 9, 0, *r->s3, 1, 4, -4); + test(*r->s3, 9, 0, *r->s3, 1, 8, -8); + test(*r->s3, 9, 0, *r->s3, 1, 9, -9); + test(*r->s3, 9, 0, *r->s3, 1, 10, -9); + test(*r->s3, 9, 0, *r->s3, 5, 0, 0); + test(*r->s3, 9, 0, *r->s3, 5, 1, -1); + test(*r->s3, 9, 0, *r->s3, 5, 2, -2); + test(*r->s3, 9, 0, *r->s3, 5, 4, -4); + test(*r->s3, 9, 0, *r->s3, 5, 5, -5); + test(*r->s3, 9, 0, *r->s3, 5, 6, -5); +} + +template +void +test33(pmem::obj::persistent_ptr &r) +{ + test(*r->s3, 9, 0, *r->s3, 9, 0, 0); + test(*r->s3, 9, 0, *r->s3, 9, 1, -1); + test(*r->s3, 9, 0, *r->s3, 9, 2, -1); + test(*r->s3, 9, 0, *r->s3, 10, 0, 0); + test(*r->s3, 9, 0, *r->s3, 10, 1, 0); + test(*r->s3, 9, 0, *r->s3, 11, 0, 0); + test(*r->s3, 9, 0, *r->s4, 0, 0, 0); + test(*r->s3, 9, 0, *r->s4, 0, 1, -1); + test(*r->s3, 9, 0, *r->s4, 0, 10, -10); + test(*r->s3, 9, 0, *r->s4, 0, 19, -19); + test(*r->s3, 9, 0, *r->s4, 0, 20, -20); + test(*r->s3, 9, 0, *r->s4, 0, 21, -20); + test(*r->s3, 9, 0, *r->s4, 1, 0, 0); + test(*r->s3, 9, 0, *r->s4, 1, 1, -1); + test(*r->s3, 9, 0, *r->s4, 1, 9, -9); + test(*r->s3, 9, 0, *r->s4, 1, 18, -18); + test(*r->s3, 9, 0, *r->s4, 1, 19, -19); + test(*r->s3, 9, 0, *r->s4, 1, 20, -19); + test(*r->s3, 9, 0, *r->s4, 10, 0, 0); + test(*r->s3, 9, 0, *r->s4, 10, 1, -1); + test(*r->s3, 9, 0, *r->s4, 10, 5, -5); + test(*r->s3, 9, 0, *r->s4, 10, 9, -9); + test(*r->s3, 9, 0, *r->s4, 10, 10, -10); + test(*r->s3, 9, 0, *r->s4, 10, 11, -10); + test(*r->s3, 9, 0, *r->s4, 19, 0, 0); + test(*r->s3, 9, 0, *r->s4, 19, 1, -1); + test(*r->s3, 9, 0, *r->s4, 19, 2, -1); + test(*r->s3, 9, 0, *r->s4, 20, 0, 0); + test(*r->s3, 9, 0, *r->s4, 20, 1, 0); + test(*r->s3, 9, 0, *r->s4, 21, 0, 0); + test(*r->s3, 9, 1, *r->s1, 0, 0, 1); + test(*r->s3, 9, 1, *r->s1, 0, 1, 1); + test(*r->s3, 9, 1, *r->s1, 1, 0, 0); + test(*r->s3, 9, 1, *r->s2, 0, 0, 1); + test(*r->s3, 9, 1, *r->s2, 0, 1, 9); + test(*r->s3, 9, 1, *r->s2, 0, 2, 9); + test(*r->s3, 9, 1, *r->s2, 0, 4, 9); + test(*r->s3, 9, 1, *r->s2, 0, 5, 9); + test(*r->s3, 9, 1, *r->s2, 0, 6, 9); + test(*r->s3, 9, 1, *r->s2, 1, 0, 1); + test(*r->s3, 9, 1, *r->s2, 1, 1, 8); + test(*r->s3, 9, 1, *r->s2, 1, 2, 8); + test(*r->s3, 9, 1, *r->s2, 1, 3, 8); + test(*r->s3, 9, 1, *r->s2, 1, 4, 8); + test(*r->s3, 9, 1, *r->s2, 1, 5, 8); + test(*r->s3, 9, 1, *r->s2, 2, 0, 1); + test(*r->s3, 9, 1, *r->s2, 2, 1, 7); + test(*r->s3, 9, 1, *r->s2, 2, 2, 7); + test(*r->s3, 9, 1, *r->s2, 2, 3, 7); + test(*r->s3, 9, 1, *r->s2, 2, 4, 7); + test(*r->s3, 9, 1, *r->s2, 4, 0, 1); + test(*r->s3, 9, 1, *r->s2, 4, 1, 5); + test(*r->s3, 9, 1, *r->s2, 4, 2, 5); + test(*r->s3, 9, 1, *r->s2, 5, 0, 1); + test(*r->s3, 9, 1, *r->s2, 5, 1, 1); + test(*r->s3, 9, 1, *r->s2, 6, 0, 0); + test(*r->s3, 9, 1, *r->s3, 0, 0, 1); + test(*r->s3, 9, 1, *r->s3, 0, 1, 9); + test(*r->s3, 9, 1, *r->s3, 0, 5, 9); + test(*r->s3, 9, 1, *r->s3, 0, 9, 9); + test(*r->s3, 9, 1, *r->s3, 0, 10, 9); + test(*r->s3, 9, 1, *r->s3, 0, 11, 9); + test(*r->s3, 9, 1, *r->s3, 1, 0, 1); + test(*r->s3, 9, 1, *r->s3, 1, 1, 8); + test(*r->s3, 9, 1, *r->s3, 1, 4, 8); + test(*r->s3, 9, 1, *r->s3, 1, 8, 8); + test(*r->s3, 9, 1, *r->s3, 1, 9, 8); + test(*r->s3, 9, 1, *r->s3, 1, 10, 8); + test(*r->s3, 9, 1, *r->s3, 5, 0, 1); + test(*r->s3, 9, 1, *r->s3, 5, 1, 4); + test(*r->s3, 9, 1, *r->s3, 5, 2, 4); + test(*r->s3, 9, 1, *r->s3, 5, 4, 4); + test(*r->s3, 9, 1, *r->s3, 5, 5, 4); + test(*r->s3, 9, 1, *r->s3, 5, 6, 4); + test(*r->s3, 9, 1, *r->s3, 9, 0, 1); + test(*r->s3, 9, 1, *r->s3, 9, 1, 0); + test(*r->s3, 9, 1, *r->s3, 9, 2, 0); + test(*r->s3, 9, 1, *r->s3, 10, 0, 1); + test(*r->s3, 9, 1, *r->s3, 10, 1, 1); + test(*r->s3, 9, 1, *r->s3, 11, 0, 0); + test(*r->s3, 9, 1, *r->s4, 0, 0, 1); + test(*r->s3, 9, 1, *r->s4, 0, 1, 9); + test(*r->s3, 9, 1, *r->s4, 0, 10, 9); + test(*r->s3, 9, 1, *r->s4, 0, 19, 9); + test(*r->s3, 9, 1, *r->s4, 0, 20, 9); + test(*r->s3, 9, 1, *r->s4, 0, 21, 9); + test(*r->s3, 9, 1, *r->s4, 1, 0, 1); + test(*r->s3, 9, 1, *r->s4, 1, 1, 8); + test(*r->s3, 9, 1, *r->s4, 1, 9, 8); + test(*r->s3, 9, 1, *r->s4, 1, 18, 8); + test(*r->s3, 9, 1, *r->s4, 1, 19, 8); + test(*r->s3, 9, 1, *r->s4, 1, 20, 8); + test(*r->s3, 9, 1, *r->s4, 10, 0, 1); + test(*r->s3, 9, 1, *r->s4, 10, 1, -1); + test(*r->s3, 9, 1, *r->s4, 10, 5, -1); + test(*r->s3, 9, 1, *r->s4, 10, 9, -1); + test(*r->s3, 9, 1, *r->s4, 10, 10, -1); + test(*r->s3, 9, 1, *r->s4, 10, 11, -1); + test(*r->s3, 9, 1, *r->s4, 19, 0, 1); + test(*r->s3, 9, 1, *r->s4, 19, 1, -10); +} + +template +void +test34(pmem::obj::persistent_ptr &r) +{ + test(*r->s3, 9, 1, *r->s4, 19, 2, -10); + test(*r->s3, 9, 1, *r->s4, 20, 0, 1); + test(*r->s3, 9, 1, *r->s4, 20, 1, 1); + test(*r->s3, 9, 1, *r->s4, 21, 0, 0); + test(*r->s3, 9, 2, *r->s1, 0, 0, 1); + test(*r->s3, 9, 2, *r->s1, 0, 1, 1); + test(*r->s3, 9, 2, *r->s1, 1, 0, 0); + test(*r->s3, 9, 2, *r->s2, 0, 0, 1); + test(*r->s3, 9, 2, *r->s2, 0, 1, 9); + test(*r->s3, 9, 2, *r->s2, 0, 2, 9); + test(*r->s3, 9, 2, *r->s2, 0, 4, 9); + test(*r->s3, 9, 2, *r->s2, 0, 5, 9); + test(*r->s3, 9, 2, *r->s2, 0, 6, 9); + test(*r->s3, 9, 2, *r->s2, 1, 0, 1); + test(*r->s3, 9, 2, *r->s2, 1, 1, 8); + test(*r->s3, 9, 2, *r->s2, 1, 2, 8); + test(*r->s3, 9, 2, *r->s2, 1, 3, 8); + test(*r->s3, 9, 2, *r->s2, 1, 4, 8); + test(*r->s3, 9, 2, *r->s2, 1, 5, 8); + test(*r->s3, 9, 2, *r->s2, 2, 0, 1); + test(*r->s3, 9, 2, *r->s2, 2, 1, 7); + test(*r->s3, 9, 2, *r->s2, 2, 2, 7); + test(*r->s3, 9, 2, *r->s2, 2, 3, 7); + test(*r->s3, 9, 2, *r->s2, 2, 4, 7); + test(*r->s3, 9, 2, *r->s2, 4, 0, 1); + test(*r->s3, 9, 2, *r->s2, 4, 1, 5); + test(*r->s3, 9, 2, *r->s2, 4, 2, 5); + test(*r->s3, 9, 2, *r->s2, 5, 0, 1); + test(*r->s3, 9, 2, *r->s2, 5, 1, 1); + test(*r->s3, 9, 2, *r->s2, 6, 0, 0); + test(*r->s3, 9, 2, *r->s3, 0, 0, 1); + test(*r->s3, 9, 2, *r->s3, 0, 1, 9); + test(*r->s3, 9, 2, *r->s3, 0, 5, 9); + test(*r->s3, 9, 2, *r->s3, 0, 9, 9); + test(*r->s3, 9, 2, *r->s3, 0, 10, 9); + test(*r->s3, 9, 2, *r->s3, 0, 11, 9); + test(*r->s3, 9, 2, *r->s3, 1, 0, 1); + test(*r->s3, 9, 2, *r->s3, 1, 1, 8); + test(*r->s3, 9, 2, *r->s3, 1, 4, 8); + test(*r->s3, 9, 2, *r->s3, 1, 8, 8); + test(*r->s3, 9, 2, *r->s3, 1, 9, 8); + test(*r->s3, 9, 2, *r->s3, 1, 10, 8); + test(*r->s3, 9, 2, *r->s3, 5, 0, 1); + test(*r->s3, 9, 2, *r->s3, 5, 1, 4); + test(*r->s3, 9, 2, *r->s3, 5, 2, 4); + test(*r->s3, 9, 2, *r->s3, 5, 4, 4); + test(*r->s3, 9, 2, *r->s3, 5, 5, 4); + test(*r->s3, 9, 2, *r->s3, 5, 6, 4); + test(*r->s3, 9, 2, *r->s3, 9, 0, 1); + test(*r->s3, 9, 2, *r->s3, 9, 1, 0); + test(*r->s3, 9, 2, *r->s3, 9, 2, 0); + test(*r->s3, 9, 2, *r->s3, 10, 0, 1); + test(*r->s3, 9, 2, *r->s3, 10, 1, 1); + test(*r->s3, 9, 2, *r->s3, 11, 0, 0); + test(*r->s3, 9, 2, *r->s4, 0, 0, 1); + test(*r->s3, 9, 2, *r->s4, 0, 1, 9); + test(*r->s3, 9, 2, *r->s4, 0, 10, 9); + test(*r->s3, 9, 2, *r->s4, 0, 19, 9); + test(*r->s3, 9, 2, *r->s4, 0, 20, 9); + test(*r->s3, 9, 2, *r->s4, 0, 21, 9); + test(*r->s3, 9, 2, *r->s4, 1, 0, 1); + test(*r->s3, 9, 2, *r->s4, 1, 1, 8); + test(*r->s3, 9, 2, *r->s4, 1, 9, 8); + test(*r->s3, 9, 2, *r->s4, 1, 18, 8); + test(*r->s3, 9, 2, *r->s4, 1, 19, 8); + test(*r->s3, 9, 2, *r->s4, 1, 20, 8); + test(*r->s3, 9, 2, *r->s4, 10, 0, 1); + test(*r->s3, 9, 2, *r->s4, 10, 1, -1); + test(*r->s3, 9, 2, *r->s4, 10, 5, -1); + test(*r->s3, 9, 2, *r->s4, 10, 9, -1); + test(*r->s3, 9, 2, *r->s4, 10, 10, -1); + test(*r->s3, 9, 2, *r->s4, 10, 11, -1); + test(*r->s3, 9, 2, *r->s4, 19, 0, 1); + test(*r->s3, 9, 2, *r->s4, 19, 1, -10); + test(*r->s3, 9, 2, *r->s4, 19, 2, -10); + test(*r->s3, 9, 2, *r->s4, 20, 0, 1); + test(*r->s3, 9, 2, *r->s4, 20, 1, 1); + test(*r->s3, 9, 2, *r->s4, 21, 0, 0); + test(*r->s3, 10, 0, *r->s1, 0, 0, 0); + test(*r->s3, 10, 0, *r->s1, 0, 1, 0); + test(*r->s3, 10, 0, *r->s1, 1, 0, 0); + test(*r->s3, 10, 0, *r->s2, 0, 0, 0); + test(*r->s3, 10, 0, *r->s2, 0, 1, -1); + test(*r->s3, 10, 0, *r->s2, 0, 2, -2); + test(*r->s3, 10, 0, *r->s2, 0, 4, -4); + test(*r->s3, 10, 0, *r->s2, 0, 5, -5); + test(*r->s3, 10, 0, *r->s2, 0, 6, -5); + test(*r->s3, 10, 0, *r->s2, 1, 0, 0); + test(*r->s3, 10, 0, *r->s2, 1, 1, -1); + test(*r->s3, 10, 0, *r->s2, 1, 2, -2); + test(*r->s3, 10, 0, *r->s2, 1, 3, -3); + test(*r->s3, 10, 0, *r->s2, 1, 4, -4); + test(*r->s3, 10, 0, *r->s2, 1, 5, -4); + test(*r->s3, 10, 0, *r->s2, 2, 0, 0); + test(*r->s3, 10, 0, *r->s2, 2, 1, -1); + test(*r->s3, 10, 0, *r->s2, 2, 2, -2); + test(*r->s3, 10, 0, *r->s2, 2, 3, -3); + test(*r->s3, 10, 0, *r->s2, 2, 4, -3); + test(*r->s3, 10, 0, *r->s2, 4, 0, 0); + test(*r->s3, 10, 0, *r->s2, 4, 1, -1); +} + +template +void +test35(pmem::obj::persistent_ptr &r) +{ + test(*r->s3, 10, 0, *r->s2, 4, 2, -1); + test(*r->s3, 10, 0, *r->s2, 5, 0, 0); + test(*r->s3, 10, 0, *r->s2, 5, 1, 0); + test(*r->s3, 10, 0, *r->s2, 6, 0, 0); + test(*r->s3, 10, 0, *r->s3, 0, 0, 0); + test(*r->s3, 10, 0, *r->s3, 0, 1, -1); + test(*r->s3, 10, 0, *r->s3, 0, 5, -5); + test(*r->s3, 10, 0, *r->s3, 0, 9, -9); + test(*r->s3, 10, 0, *r->s3, 0, 10, -10); + test(*r->s3, 10, 0, *r->s3, 0, 11, -10); + test(*r->s3, 10, 0, *r->s3, 1, 0, 0); + test(*r->s3, 10, 0, *r->s3, 1, 1, -1); + test(*r->s3, 10, 0, *r->s3, 1, 4, -4); + test(*r->s3, 10, 0, *r->s3, 1, 8, -8); + test(*r->s3, 10, 0, *r->s3, 1, 9, -9); + test(*r->s3, 10, 0, *r->s3, 1, 10, -9); + test(*r->s3, 10, 0, *r->s3, 5, 0, 0); + test(*r->s3, 10, 0, *r->s3, 5, 1, -1); + test(*r->s3, 10, 0, *r->s3, 5, 2, -2); + test(*r->s3, 10, 0, *r->s3, 5, 4, -4); + test(*r->s3, 10, 0, *r->s3, 5, 5, -5); + test(*r->s3, 10, 0, *r->s3, 5, 6, -5); + test(*r->s3, 10, 0, *r->s3, 9, 0, 0); + test(*r->s3, 10, 0, *r->s3, 9, 1, -1); + test(*r->s3, 10, 0, *r->s3, 9, 2, -1); + test(*r->s3, 10, 0, *r->s3, 10, 0, 0); + test(*r->s3, 10, 0, *r->s3, 10, 1, 0); + test(*r->s3, 10, 0, *r->s3, 11, 0, 0); + test(*r->s3, 10, 0, *r->s4, 0, 0, 0); + test(*r->s3, 10, 0, *r->s4, 0, 1, -1); + test(*r->s3, 10, 0, *r->s4, 0, 10, -10); + test(*r->s3, 10, 0, *r->s4, 0, 19, -19); + test(*r->s3, 10, 0, *r->s4, 0, 20, -20); + test(*r->s3, 10, 0, *r->s4, 0, 21, -20); + test(*r->s3, 10, 0, *r->s4, 1, 0, 0); + test(*r->s3, 10, 0, *r->s4, 1, 1, -1); + test(*r->s3, 10, 0, *r->s4, 1, 9, -9); + test(*r->s3, 10, 0, *r->s4, 1, 18, -18); + test(*r->s3, 10, 0, *r->s4, 1, 19, -19); + test(*r->s3, 10, 0, *r->s4, 1, 20, -19); + test(*r->s3, 10, 0, *r->s4, 10, 0, 0); + test(*r->s3, 10, 0, *r->s4, 10, 1, -1); + test(*r->s3, 10, 0, *r->s4, 10, 5, -5); + test(*r->s3, 10, 0, *r->s4, 10, 9, -9); + test(*r->s3, 10, 0, *r->s4, 10, 10, -10); + test(*r->s3, 10, 0, *r->s4, 10, 11, -10); + test(*r->s3, 10, 0, *r->s4, 19, 0, 0); + test(*r->s3, 10, 0, *r->s4, 19, 1, -1); + test(*r->s3, 10, 0, *r->s4, 19, 2, -1); + test(*r->s3, 10, 0, *r->s4, 20, 0, 0); + test(*r->s3, 10, 0, *r->s4, 20, 1, 0); + test(*r->s3, 10, 0, *r->s4, 21, 0, 0); + test(*r->s3, 10, 1, *r->s1, 0, 0, 0); + test(*r->s3, 10, 1, *r->s1, 0, 1, 0); + test(*r->s3, 10, 1, *r->s1, 1, 0, 0); + test(*r->s3, 10, 1, *r->s2, 0, 0, 0); + test(*r->s3, 10, 1, *r->s2, 0, 1, -1); + test(*r->s3, 10, 1, *r->s2, 0, 2, -2); + test(*r->s3, 10, 1, *r->s2, 0, 4, -4); + test(*r->s3, 10, 1, *r->s2, 0, 5, -5); + test(*r->s3, 10, 1, *r->s2, 0, 6, -5); + test(*r->s3, 10, 1, *r->s2, 1, 0, 0); + test(*r->s3, 10, 1, *r->s2, 1, 1, -1); + test(*r->s3, 10, 1, *r->s2, 1, 2, -2); + test(*r->s3, 10, 1, *r->s2, 1, 3, -3); + test(*r->s3, 10, 1, *r->s2, 1, 4, -4); + test(*r->s3, 10, 1, *r->s2, 1, 5, -4); + test(*r->s3, 10, 1, *r->s2, 2, 0, 0); + test(*r->s3, 10, 1, *r->s2, 2, 1, -1); + test(*r->s3, 10, 1, *r->s2, 2, 2, -2); + test(*r->s3, 10, 1, *r->s2, 2, 3, -3); + test(*r->s3, 10, 1, *r->s2, 2, 4, -3); + test(*r->s3, 10, 1, *r->s2, 4, 0, 0); + test(*r->s3, 10, 1, *r->s2, 4, 1, -1); + test(*r->s3, 10, 1, *r->s2, 4, 2, -1); + test(*r->s3, 10, 1, *r->s2, 5, 0, 0); + test(*r->s3, 10, 1, *r->s2, 5, 1, 0); + test(*r->s3, 10, 1, *r->s2, 6, 0, 0); + test(*r->s3, 10, 1, *r->s3, 0, 0, 0); + test(*r->s3, 10, 1, *r->s3, 0, 1, -1); + test(*r->s3, 10, 1, *r->s3, 0, 5, -5); + test(*r->s3, 10, 1, *r->s3, 0, 9, -9); + test(*r->s3, 10, 1, *r->s3, 0, 10, -10); + test(*r->s3, 10, 1, *r->s3, 0, 11, -10); + test(*r->s3, 10, 1, *r->s3, 1, 0, 0); + test(*r->s3, 10, 1, *r->s3, 1, 1, -1); + test(*r->s3, 10, 1, *r->s3, 1, 4, -4); + test(*r->s3, 10, 1, *r->s3, 1, 8, -8); + test(*r->s3, 10, 1, *r->s3, 1, 9, -9); + test(*r->s3, 10, 1, *r->s3, 1, 10, -9); + test(*r->s3, 10, 1, *r->s3, 5, 0, 0); + test(*r->s3, 10, 1, *r->s3, 5, 1, -1); + test(*r->s3, 10, 1, *r->s3, 5, 2, -2); + test(*r->s3, 10, 1, *r->s3, 5, 4, -4); + test(*r->s3, 10, 1, *r->s3, 5, 5, -5); + test(*r->s3, 10, 1, *r->s3, 5, 6, -5); + test(*r->s3, 10, 1, *r->s3, 9, 0, 0); + test(*r->s3, 10, 1, *r->s3, 9, 1, -1); + test(*r->s3, 10, 1, *r->s3, 9, 2, -1); + test(*r->s3, 10, 1, *r->s3, 10, 0, 0); +} + +template +void +test36(pmem::obj::persistent_ptr &r) +{ + test(*r->s3, 10, 1, *r->s3, 10, 1, 0); + test(*r->s3, 10, 1, *r->s3, 11, 0, 0); + test(*r->s3, 10, 1, *r->s4, 0, 0, 0); + test(*r->s3, 10, 1, *r->s4, 0, 1, -1); + test(*r->s3, 10, 1, *r->s4, 0, 10, -10); + test(*r->s3, 10, 1, *r->s4, 0, 19, -19); + test(*r->s3, 10, 1, *r->s4, 0, 20, -20); + test(*r->s3, 10, 1, *r->s4, 0, 21, -20); + test(*r->s3, 10, 1, *r->s4, 1, 0, 0); + test(*r->s3, 10, 1, *r->s4, 1, 1, -1); + test(*r->s3, 10, 1, *r->s4, 1, 9, -9); + test(*r->s3, 10, 1, *r->s4, 1, 18, -18); + test(*r->s3, 10, 1, *r->s4, 1, 19, -19); + test(*r->s3, 10, 1, *r->s4, 1, 20, -19); + test(*r->s3, 10, 1, *r->s4, 10, 0, 0); + test(*r->s3, 10, 1, *r->s4, 10, 1, -1); + test(*r->s3, 10, 1, *r->s4, 10, 5, -5); + test(*r->s3, 10, 1, *r->s4, 10, 9, -9); + test(*r->s3, 10, 1, *r->s4, 10, 10, -10); + test(*r->s3, 10, 1, *r->s4, 10, 11, -10); + test(*r->s3, 10, 1, *r->s4, 19, 0, 0); + test(*r->s3, 10, 1, *r->s4, 19, 1, -1); + test(*r->s3, 10, 1, *r->s4, 19, 2, -1); + test(*r->s3, 10, 1, *r->s4, 20, 0, 0); + test(*r->s3, 10, 1, *r->s4, 20, 1, 0); + test(*r->s3, 10, 1, *r->s4, 21, 0, 0); + test(*r->s3, 11, 0, *r->s1, 0, 0, 0); + test(*r->s3, 11, 0, *r->s1, 0, 1, 0); + test(*r->s3, 11, 0, *r->s1, 1, 0, 0); + test(*r->s3, 11, 0, *r->s2, 0, 0, 0); + test(*r->s3, 11, 0, *r->s2, 0, 1, 0); + test(*r->s3, 11, 0, *r->s2, 0, 2, 0); + test(*r->s3, 11, 0, *r->s2, 0, 4, 0); + test(*r->s3, 11, 0, *r->s2, 0, 5, 0); + test(*r->s3, 11, 0, *r->s2, 0, 6, 0); + test(*r->s3, 11, 0, *r->s2, 1, 0, 0); + test(*r->s3, 11, 0, *r->s2, 1, 1, 0); + test(*r->s3, 11, 0, *r->s2, 1, 2, 0); + test(*r->s3, 11, 0, *r->s2, 1, 3, 0); + test(*r->s3, 11, 0, *r->s2, 1, 4, 0); + test(*r->s3, 11, 0, *r->s2, 1, 5, 0); + test(*r->s3, 11, 0, *r->s2, 2, 0, 0); + test(*r->s3, 11, 0, *r->s2, 2, 1, 0); + test(*r->s3, 11, 0, *r->s2, 2, 2, 0); + test(*r->s3, 11, 0, *r->s2, 2, 3, 0); + test(*r->s3, 11, 0, *r->s2, 2, 4, 0); + test(*r->s3, 11, 0, *r->s2, 4, 0, 0); + test(*r->s3, 11, 0, *r->s2, 4, 1, 0); + test(*r->s3, 11, 0, *r->s2, 4, 2, 0); + test(*r->s3, 11, 0, *r->s2, 5, 0, 0); + test(*r->s3, 11, 0, *r->s2, 5, 1, 0); + test(*r->s3, 11, 0, *r->s2, 6, 0, 0); + test(*r->s3, 11, 0, *r->s3, 0, 0, 0); + test(*r->s3, 11, 0, *r->s3, 0, 1, 0); + test(*r->s3, 11, 0, *r->s3, 0, 5, 0); + test(*r->s3, 11, 0, *r->s3, 0, 9, 0); + test(*r->s3, 11, 0, *r->s3, 0, 10, 0); + test(*r->s3, 11, 0, *r->s3, 0, 11, 0); + test(*r->s3, 11, 0, *r->s3, 1, 0, 0); + test(*r->s3, 11, 0, *r->s3, 1, 1, 0); + test(*r->s3, 11, 0, *r->s3, 1, 4, 0); + test(*r->s3, 11, 0, *r->s3, 1, 8, 0); + test(*r->s3, 11, 0, *r->s3, 1, 9, 0); + test(*r->s3, 11, 0, *r->s3, 1, 10, 0); + test(*r->s3, 11, 0, *r->s3, 5, 0, 0); + test(*r->s3, 11, 0, *r->s3, 5, 1, 0); + test(*r->s3, 11, 0, *r->s3, 5, 2, 0); + test(*r->s3, 11, 0, *r->s3, 5, 4, 0); + test(*r->s3, 11, 0, *r->s3, 5, 5, 0); + test(*r->s3, 11, 0, *r->s3, 5, 6, 0); + test(*r->s3, 11, 0, *r->s3, 9, 0, 0); + test(*r->s3, 11, 0, *r->s3, 9, 1, 0); + test(*r->s3, 11, 0, *r->s3, 9, 2, 0); + test(*r->s3, 11, 0, *r->s3, 10, 0, 0); + test(*r->s3, 11, 0, *r->s3, 10, 1, 0); + test(*r->s3, 11, 0, *r->s3, 11, 0, 0); + test(*r->s3, 11, 0, *r->s4, 0, 0, 0); + test(*r->s3, 11, 0, *r->s4, 0, 1, 0); + test(*r->s3, 11, 0, *r->s4, 0, 10, 0); + test(*r->s3, 11, 0, *r->s4, 0, 19, 0); + test(*r->s3, 11, 0, *r->s4, 0, 20, 0); + test(*r->s3, 11, 0, *r->s4, 0, 21, 0); + test(*r->s3, 11, 0, *r->s4, 1, 0, 0); + test(*r->s3, 11, 0, *r->s4, 1, 1, 0); + test(*r->s3, 11, 0, *r->s4, 1, 9, 0); + test(*r->s3, 11, 0, *r->s4, 1, 18, 0); + test(*r->s3, 11, 0, *r->s4, 1, 19, 0); + test(*r->s3, 11, 0, *r->s4, 1, 20, 0); + test(*r->s3, 11, 0, *r->s4, 10, 0, 0); + test(*r->s3, 11, 0, *r->s4, 10, 1, 0); + test(*r->s3, 11, 0, *r->s4, 10, 5, 0); + test(*r->s3, 11, 0, *r->s4, 10, 9, 0); + test(*r->s3, 11, 0, *r->s4, 10, 10, 0); + test(*r->s3, 11, 0, *r->s4, 10, 11, 0); + test(*r->s3, 11, 0, *r->s4, 19, 0, 0); + test(*r->s3, 11, 0, *r->s4, 19, 1, 0); + test(*r->s3, 11, 0, *r->s4, 19, 2, 0); + test(*r->s3, 11, 0, *r->s4, 20, 0, 0); + test(*r->s3, 11, 0, *r->s4, 20, 1, 0); + test(*r->s3, 11, 0, *r->s4, 21, 0, 0); +} + +template +void +test37(pmem::obj::persistent_ptr &r) +{ + test(*r->s4, 0, 0, *r->s1, 0, 0, 0); + test(*r->s4, 0, 0, *r->s1, 0, 1, 0); + test(*r->s4, 0, 0, *r->s1, 1, 0, 0); + test(*r->s4, 0, 0, *r->s2, 0, 0, 0); + test(*r->s4, 0, 0, *r->s2, 0, 1, -1); + test(*r->s4, 0, 0, *r->s2, 0, 2, -2); + test(*r->s4, 0, 0, *r->s2, 0, 4, -4); + test(*r->s4, 0, 0, *r->s2, 0, 5, -5); + test(*r->s4, 0, 0, *r->s2, 0, 6, -5); + test(*r->s4, 0, 0, *r->s2, 1, 0, 0); + test(*r->s4, 0, 0, *r->s2, 1, 1, -1); + test(*r->s4, 0, 0, *r->s2, 1, 2, -2); + test(*r->s4, 0, 0, *r->s2, 1, 3, -3); + test(*r->s4, 0, 0, *r->s2, 1, 4, -4); + test(*r->s4, 0, 0, *r->s2, 1, 5, -4); + test(*r->s4, 0, 0, *r->s2, 2, 0, 0); + test(*r->s4, 0, 0, *r->s2, 2, 1, -1); + test(*r->s4, 0, 0, *r->s2, 2, 2, -2); + test(*r->s4, 0, 0, *r->s2, 2, 3, -3); + test(*r->s4, 0, 0, *r->s2, 2, 4, -3); + test(*r->s4, 0, 0, *r->s2, 4, 0, 0); + test(*r->s4, 0, 0, *r->s2, 4, 1, -1); + test(*r->s4, 0, 0, *r->s2, 4, 2, -1); + test(*r->s4, 0, 0, *r->s2, 5, 0, 0); + test(*r->s4, 0, 0, *r->s2, 5, 1, 0); + test(*r->s4, 0, 0, *r->s2, 6, 0, 0); + test(*r->s4, 0, 0, *r->s3, 0, 0, 0); + test(*r->s4, 0, 0, *r->s3, 0, 1, -1); + test(*r->s4, 0, 0, *r->s3, 0, 5, -5); + test(*r->s4, 0, 0, *r->s3, 0, 9, -9); + test(*r->s4, 0, 0, *r->s3, 0, 10, -10); + test(*r->s4, 0, 0, *r->s3, 0, 11, -10); + test(*r->s4, 0, 0, *r->s3, 1, 0, 0); + test(*r->s4, 0, 0, *r->s3, 1, 1, -1); + test(*r->s4, 0, 0, *r->s3, 1, 4, -4); + test(*r->s4, 0, 0, *r->s3, 1, 8, -8); + test(*r->s4, 0, 0, *r->s3, 1, 9, -9); + test(*r->s4, 0, 0, *r->s3, 1, 10, -9); + test(*r->s4, 0, 0, *r->s3, 5, 0, 0); + test(*r->s4, 0, 0, *r->s3, 5, 1, -1); + test(*r->s4, 0, 0, *r->s3, 5, 2, -2); + test(*r->s4, 0, 0, *r->s3, 5, 4, -4); + test(*r->s4, 0, 0, *r->s3, 5, 5, -5); + test(*r->s4, 0, 0, *r->s3, 5, 6, -5); + test(*r->s4, 0, 0, *r->s3, 9, 0, 0); + test(*r->s4, 0, 0, *r->s3, 9, 1, -1); + test(*r->s4, 0, 0, *r->s3, 9, 2, -1); + test(*r->s4, 0, 0, *r->s3, 10, 0, 0); + test(*r->s4, 0, 0, *r->s3, 10, 1, 0); + test(*r->s4, 0, 0, *r->s3, 11, 0, 0); + test(*r->s4, 0, 0, *r->s4, 0, 0, 0); + test(*r->s4, 0, 0, *r->s4, 0, 1, -1); + test(*r->s4, 0, 0, *r->s4, 0, 10, -10); + test(*r->s4, 0, 0, *r->s4, 0, 19, -19); + test(*r->s4, 0, 0, *r->s4, 0, 20, -20); + test(*r->s4, 0, 0, *r->s4, 0, 21, -20); + test(*r->s4, 0, 0, *r->s4, 1, 0, 0); + test(*r->s4, 0, 0, *r->s4, 1, 1, -1); + test(*r->s4, 0, 0, *r->s4, 1, 9, -9); + test(*r->s4, 0, 0, *r->s4, 1, 18, -18); + test(*r->s4, 0, 0, *r->s4, 1, 19, -19); + test(*r->s4, 0, 0, *r->s4, 1, 20, -19); + test(*r->s4, 0, 0, *r->s4, 10, 0, 0); + test(*r->s4, 0, 0, *r->s4, 10, 1, -1); + test(*r->s4, 0, 0, *r->s4, 10, 5, -5); + test(*r->s4, 0, 0, *r->s4, 10, 9, -9); + test(*r->s4, 0, 0, *r->s4, 10, 10, -10); + test(*r->s4, 0, 0, *r->s4, 10, 11, -10); + test(*r->s4, 0, 0, *r->s4, 19, 0, 0); + test(*r->s4, 0, 0, *r->s4, 19, 1, -1); + test(*r->s4, 0, 0, *r->s4, 19, 2, -1); + test(*r->s4, 0, 0, *r->s4, 20, 0, 0); + test(*r->s4, 0, 0, *r->s4, 20, 1, 0); + test(*r->s4, 0, 0, *r->s4, 21, 0, 0); + test(*r->s4, 0, 1, *r->s1, 0, 0, 1); + test(*r->s4, 0, 1, *r->s1, 0, 1, 1); + test(*r->s4, 0, 1, *r->s1, 1, 0, 0); + test(*r->s4, 0, 1, *r->s2, 0, 0, 1); + test(*r->s4, 0, 1, *r->s2, 0, 1, 0); + test(*r->s4, 0, 1, *r->s2, 0, 2, -1); + test(*r->s4, 0, 1, *r->s2, 0, 4, -3); + test(*r->s4, 0, 1, *r->s2, 0, 5, -4); + test(*r->s4, 0, 1, *r->s2, 0, 6, -4); + test(*r->s4, 0, 1, *r->s2, 1, 0, 1); + test(*r->s4, 0, 1, *r->s2, 1, 1, -1); + test(*r->s4, 0, 1, *r->s2, 1, 2, -1); + test(*r->s4, 0, 1, *r->s2, 1, 3, -1); + test(*r->s4, 0, 1, *r->s2, 1, 4, -1); + test(*r->s4, 0, 1, *r->s2, 1, 5, -1); + test(*r->s4, 0, 1, *r->s2, 2, 0, 1); + test(*r->s4, 0, 1, *r->s2, 2, 1, -2); + test(*r->s4, 0, 1, *r->s2, 2, 2, -2); + test(*r->s4, 0, 1, *r->s2, 2, 3, -2); + test(*r->s4, 0, 1, *r->s2, 2, 4, -2); + test(*r->s4, 0, 1, *r->s2, 4, 0, 1); + test(*r->s4, 0, 1, *r->s2, 4, 1, -4); + test(*r->s4, 0, 1, *r->s2, 4, 2, -4); + test(*r->s4, 0, 1, *r->s2, 5, 0, 1); + test(*r->s4, 0, 1, *r->s2, 5, 1, 1); + test(*r->s4, 0, 1, *r->s2, 6, 0, 0); +} + +template +void +test38(pmem::obj::persistent_ptr &r) +{ + test(*r->s4, 0, 1, *r->s3, 0, 0, 1); + test(*r->s4, 0, 1, *r->s3, 0, 1, 0); + test(*r->s4, 0, 1, *r->s3, 0, 5, -4); + test(*r->s4, 0, 1, *r->s3, 0, 9, -8); + test(*r->s4, 0, 1, *r->s3, 0, 10, -9); + test(*r->s4, 0, 1, *r->s3, 0, 11, -9); + test(*r->s4, 0, 1, *r->s3, 1, 0, 1); + test(*r->s4, 0, 1, *r->s3, 1, 1, -1); + test(*r->s4, 0, 1, *r->s3, 1, 4, -1); + test(*r->s4, 0, 1, *r->s3, 1, 8, -1); + test(*r->s4, 0, 1, *r->s3, 1, 9, -1); + test(*r->s4, 0, 1, *r->s3, 1, 10, -1); + test(*r->s4, 0, 1, *r->s3, 5, 0, 1); + test(*r->s4, 0, 1, *r->s3, 5, 1, -5); + test(*r->s4, 0, 1, *r->s3, 5, 2, -5); + test(*r->s4, 0, 1, *r->s3, 5, 4, -5); + test(*r->s4, 0, 1, *r->s3, 5, 5, -5); + test(*r->s4, 0, 1, *r->s3, 5, 6, -5); + test(*r->s4, 0, 1, *r->s3, 9, 0, 1); + test(*r->s4, 0, 1, *r->s3, 9, 1, -9); + test(*r->s4, 0, 1, *r->s3, 9, 2, -9); + test(*r->s4, 0, 1, *r->s3, 10, 0, 1); + test(*r->s4, 0, 1, *r->s3, 10, 1, 1); + test(*r->s4, 0, 1, *r->s3, 11, 0, 0); + test(*r->s4, 0, 1, *r->s4, 0, 0, 1); + test(*r->s4, 0, 1, *r->s4, 0, 1, 0); + test(*r->s4, 0, 1, *r->s4, 0, 10, -9); + test(*r->s4, 0, 1, *r->s4, 0, 19, -18); + test(*r->s4, 0, 1, *r->s4, 0, 20, -19); + test(*r->s4, 0, 1, *r->s4, 0, 21, -19); + test(*r->s4, 0, 1, *r->s4, 1, 0, 1); + test(*r->s4, 0, 1, *r->s4, 1, 1, -1); + test(*r->s4, 0, 1, *r->s4, 1, 9, -1); + test(*r->s4, 0, 1, *r->s4, 1, 18, -1); + test(*r->s4, 0, 1, *r->s4, 1, 19, -1); + test(*r->s4, 0, 1, *r->s4, 1, 20, -1); + test(*r->s4, 0, 1, *r->s4, 10, 0, 1); + test(*r->s4, 0, 1, *r->s4, 10, 1, -10); + test(*r->s4, 0, 1, *r->s4, 10, 5, -10); + test(*r->s4, 0, 1, *r->s4, 10, 9, -10); + test(*r->s4, 0, 1, *r->s4, 10, 10, -10); + test(*r->s4, 0, 1, *r->s4, 10, 11, -10); + test(*r->s4, 0, 1, *r->s4, 19, 0, 1); + test(*r->s4, 0, 1, *r->s4, 19, 1, -19); + test(*r->s4, 0, 1, *r->s4, 19, 2, -19); + test(*r->s4, 0, 1, *r->s4, 20, 0, 1); + test(*r->s4, 0, 1, *r->s4, 20, 1, 1); + test(*r->s4, 0, 1, *r->s4, 21, 0, 0); + test(*r->s4, 0, 10, *r->s1, 0, 0, 10); + test(*r->s4, 0, 10, *r->s1, 0, 1, 10); + test(*r->s4, 0, 10, *r->s1, 1, 0, 0); + test(*r->s4, 0, 10, *r->s2, 0, 0, 10); + test(*r->s4, 0, 10, *r->s2, 0, 1, 9); + test(*r->s4, 0, 10, *r->s2, 0, 2, 8); + test(*r->s4, 0, 10, *r->s2, 0, 4, 6); + test(*r->s4, 0, 10, *r->s2, 0, 5, 5); + test(*r->s4, 0, 10, *r->s2, 0, 6, 5); + test(*r->s4, 0, 10, *r->s2, 1, 0, 10); + test(*r->s4, 0, 10, *r->s2, 1, 1, -1); + test(*r->s4, 0, 10, *r->s2, 1, 2, -1); + test(*r->s4, 0, 10, *r->s2, 1, 3, -1); + test(*r->s4, 0, 10, *r->s2, 1, 4, -1); + test(*r->s4, 0, 10, *r->s2, 1, 5, -1); + test(*r->s4, 0, 10, *r->s2, 2, 0, 10); + test(*r->s4, 0, 10, *r->s2, 2, 1, -2); + test(*r->s4, 0, 10, *r->s2, 2, 2, -2); + test(*r->s4, 0, 10, *r->s2, 2, 3, -2); + test(*r->s4, 0, 10, *r->s2, 2, 4, -2); + test(*r->s4, 0, 10, *r->s2, 4, 0, 10); + test(*r->s4, 0, 10, *r->s2, 4, 1, -4); + test(*r->s4, 0, 10, *r->s2, 4, 2, -4); + test(*r->s4, 0, 10, *r->s2, 5, 0, 10); + test(*r->s4, 0, 10, *r->s2, 5, 1, 10); + test(*r->s4, 0, 10, *r->s2, 6, 0, 0); + test(*r->s4, 0, 10, *r->s3, 0, 0, 10); + test(*r->s4, 0, 10, *r->s3, 0, 1, 9); + test(*r->s4, 0, 10, *r->s3, 0, 5, 5); + test(*r->s4, 0, 10, *r->s3, 0, 9, 1); + test(*r->s4, 0, 10, *r->s3, 0, 10, 0); + test(*r->s4, 0, 10, *r->s3, 0, 11, 0); + test(*r->s4, 0, 10, *r->s3, 1, 0, 10); + test(*r->s4, 0, 10, *r->s3, 1, 1, -1); + test(*r->s4, 0, 10, *r->s3, 1, 4, -1); + test(*r->s4, 0, 10, *r->s3, 1, 8, -1); + test(*r->s4, 0, 10, *r->s3, 1, 9, -1); + test(*r->s4, 0, 10, *r->s3, 1, 10, -1); + test(*r->s4, 0, 10, *r->s3, 5, 0, 10); + test(*r->s4, 0, 10, *r->s3, 5, 1, -5); + test(*r->s4, 0, 10, *r->s3, 5, 2, -5); + test(*r->s4, 0, 10, *r->s3, 5, 4, -5); + test(*r->s4, 0, 10, *r->s3, 5, 5, -5); + test(*r->s4, 0, 10, *r->s3, 5, 6, -5); + test(*r->s4, 0, 10, *r->s3, 9, 0, 10); + test(*r->s4, 0, 10, *r->s3, 9, 1, -9); + test(*r->s4, 0, 10, *r->s3, 9, 2, -9); + test(*r->s4, 0, 10, *r->s3, 10, 0, 10); + test(*r->s4, 0, 10, *r->s3, 10, 1, 10); + test(*r->s4, 0, 10, *r->s3, 11, 0, 0); + test(*r->s4, 0, 10, *r->s4, 0, 0, 10); + test(*r->s4, 0, 10, *r->s4, 0, 1, 9); +} + +template +void +test39(pmem::obj::persistent_ptr &r) +{ + test(*r->s4, 0, 10, *r->s4, 0, 10, 0); + test(*r->s4, 0, 10, *r->s4, 0, 19, -9); + test(*r->s4, 0, 10, *r->s4, 0, 20, -10); + test(*r->s4, 0, 10, *r->s4, 0, 21, -10); + test(*r->s4, 0, 10, *r->s4, 1, 0, 10); + test(*r->s4, 0, 10, *r->s4, 1, 1, -1); + test(*r->s4, 0, 10, *r->s4, 1, 9, -1); + test(*r->s4, 0, 10, *r->s4, 1, 18, -1); + test(*r->s4, 0, 10, *r->s4, 1, 19, -1); + test(*r->s4, 0, 10, *r->s4, 1, 20, -1); + test(*r->s4, 0, 10, *r->s4, 10, 0, 10); + test(*r->s4, 0, 10, *r->s4, 10, 1, -10); + test(*r->s4, 0, 10, *r->s4, 10, 5, -10); + test(*r->s4, 0, 10, *r->s4, 10, 9, -10); + test(*r->s4, 0, 10, *r->s4, 10, 10, -10); + test(*r->s4, 0, 10, *r->s4, 10, 11, -10); + test(*r->s4, 0, 10, *r->s4, 19, 0, 10); + test(*r->s4, 0, 10, *r->s4, 19, 1, -19); + test(*r->s4, 0, 10, *r->s4, 19, 2, -19); + test(*r->s4, 0, 10, *r->s4, 20, 0, 10); + test(*r->s4, 0, 10, *r->s4, 20, 1, 10); + test(*r->s4, 0, 10, *r->s4, 21, 0, 0); + test(*r->s4, 0, 19, *r->s1, 0, 0, 19); + test(*r->s4, 0, 19, *r->s1, 0, 1, 19); + test(*r->s4, 0, 19, *r->s1, 1, 0, 0); + test(*r->s4, 0, 19, *r->s2, 0, 0, 19); + test(*r->s4, 0, 19, *r->s2, 0, 1, 18); + test(*r->s4, 0, 19, *r->s2, 0, 2, 17); + test(*r->s4, 0, 19, *r->s2, 0, 4, 15); + test(*r->s4, 0, 19, *r->s2, 0, 5, 14); + test(*r->s4, 0, 19, *r->s2, 0, 6, 14); + test(*r->s4, 0, 19, *r->s2, 1, 0, 19); + test(*r->s4, 0, 19, *r->s2, 1, 1, -1); + test(*r->s4, 0, 19, *r->s2, 1, 2, -1); + test(*r->s4, 0, 19, *r->s2, 1, 3, -1); + test(*r->s4, 0, 19, *r->s2, 1, 4, -1); + test(*r->s4, 0, 19, *r->s2, 1, 5, -1); + test(*r->s4, 0, 19, *r->s2, 2, 0, 19); + test(*r->s4, 0, 19, *r->s2, 2, 1, -2); + test(*r->s4, 0, 19, *r->s2, 2, 2, -2); + test(*r->s4, 0, 19, *r->s2, 2, 3, -2); + test(*r->s4, 0, 19, *r->s2, 2, 4, -2); + test(*r->s4, 0, 19, *r->s2, 4, 0, 19); + test(*r->s4, 0, 19, *r->s2, 4, 1, -4); + test(*r->s4, 0, 19, *r->s2, 4, 2, -4); + test(*r->s4, 0, 19, *r->s2, 5, 0, 19); + test(*r->s4, 0, 19, *r->s2, 5, 1, 19); + test(*r->s4, 0, 19, *r->s2, 6, 0, 0); + test(*r->s4, 0, 19, *r->s3, 0, 0, 19); + test(*r->s4, 0, 19, *r->s3, 0, 1, 18); + test(*r->s4, 0, 19, *r->s3, 0, 5, 14); + test(*r->s4, 0, 19, *r->s3, 0, 9, 10); + test(*r->s4, 0, 19, *r->s3, 0, 10, 9); + test(*r->s4, 0, 19, *r->s3, 0, 11, 9); + test(*r->s4, 0, 19, *r->s3, 1, 0, 19); + test(*r->s4, 0, 19, *r->s3, 1, 1, -1); + test(*r->s4, 0, 19, *r->s3, 1, 4, -1); + test(*r->s4, 0, 19, *r->s3, 1, 8, -1); + test(*r->s4, 0, 19, *r->s3, 1, 9, -1); + test(*r->s4, 0, 19, *r->s3, 1, 10, -1); + test(*r->s4, 0, 19, *r->s3, 5, 0, 19); + test(*r->s4, 0, 19, *r->s3, 5, 1, -5); + test(*r->s4, 0, 19, *r->s3, 5, 2, -5); + test(*r->s4, 0, 19, *r->s3, 5, 4, -5); + test(*r->s4, 0, 19, *r->s3, 5, 5, -5); + test(*r->s4, 0, 19, *r->s3, 5, 6, -5); + test(*r->s4, 0, 19, *r->s3, 9, 0, 19); + test(*r->s4, 0, 19, *r->s3, 9, 1, -9); + test(*r->s4, 0, 19, *r->s3, 9, 2, -9); + test(*r->s4, 0, 19, *r->s3, 10, 0, 19); + test(*r->s4, 0, 19, *r->s3, 10, 1, 19); + test(*r->s4, 0, 19, *r->s3, 11, 0, 0); + test(*r->s4, 0, 19, *r->s4, 0, 0, 19); + test(*r->s4, 0, 19, *r->s4, 0, 1, 18); + test(*r->s4, 0, 19, *r->s4, 0, 10, 9); + test(*r->s4, 0, 19, *r->s4, 0, 19, 0); + test(*r->s4, 0, 19, *r->s4, 0, 20, -1); + test(*r->s4, 0, 19, *r->s4, 0, 21, -1); + test(*r->s4, 0, 19, *r->s4, 1, 0, 19); + test(*r->s4, 0, 19, *r->s4, 1, 1, -1); + test(*r->s4, 0, 19, *r->s4, 1, 9, -1); + test(*r->s4, 0, 19, *r->s4, 1, 18, -1); + test(*r->s4, 0, 19, *r->s4, 1, 19, -1); + test(*r->s4, 0, 19, *r->s4, 1, 20, -1); + test(*r->s4, 0, 19, *r->s4, 10, 0, 19); + test(*r->s4, 0, 19, *r->s4, 10, 1, -10); + test(*r->s4, 0, 19, *r->s4, 10, 5, -10); + test(*r->s4, 0, 19, *r->s4, 10, 9, -10); + test(*r->s4, 0, 19, *r->s4, 10, 10, -10); + test(*r->s4, 0, 19, *r->s4, 10, 11, -10); + test(*r->s4, 0, 19, *r->s4, 19, 0, 19); + test(*r->s4, 0, 19, *r->s4, 19, 1, -19); + test(*r->s4, 0, 19, *r->s4, 19, 2, -19); + test(*r->s4, 0, 19, *r->s4, 20, 0, 19); + test(*r->s4, 0, 19, *r->s4, 20, 1, 19); + test(*r->s4, 0, 19, *r->s4, 21, 0, 0); + test(*r->s4, 0, 20, *r->s1, 0, 0, 20); + test(*r->s4, 0, 20, *r->s1, 0, 1, 20); + test(*r->s4, 0, 20, *r->s1, 1, 0, 0); + test(*r->s4, 0, 20, *r->s2, 0, 0, 20); +} + +template +void +test40(pmem::obj::persistent_ptr &r) +{ + test(*r->s4, 0, 20, *r->s2, 0, 1, 19); + test(*r->s4, 0, 20, *r->s2, 0, 2, 18); + test(*r->s4, 0, 20, *r->s2, 0, 4, 16); + test(*r->s4, 0, 20, *r->s2, 0, 5, 15); + test(*r->s4, 0, 20, *r->s2, 0, 6, 15); + test(*r->s4, 0, 20, *r->s2, 1, 0, 20); + test(*r->s4, 0, 20, *r->s2, 1, 1, -1); + test(*r->s4, 0, 20, *r->s2, 1, 2, -1); + test(*r->s4, 0, 20, *r->s2, 1, 3, -1); + test(*r->s4, 0, 20, *r->s2, 1, 4, -1); + test(*r->s4, 0, 20, *r->s2, 1, 5, -1); + test(*r->s4, 0, 20, *r->s2, 2, 0, 20); + test(*r->s4, 0, 20, *r->s2, 2, 1, -2); + test(*r->s4, 0, 20, *r->s2, 2, 2, -2); + test(*r->s4, 0, 20, *r->s2, 2, 3, -2); + test(*r->s4, 0, 20, *r->s2, 2, 4, -2); + test(*r->s4, 0, 20, *r->s2, 4, 0, 20); + test(*r->s4, 0, 20, *r->s2, 4, 1, -4); + test(*r->s4, 0, 20, *r->s2, 4, 2, -4); + test(*r->s4, 0, 20, *r->s2, 5, 0, 20); + test(*r->s4, 0, 20, *r->s2, 5, 1, 20); + test(*r->s4, 0, 20, *r->s2, 6, 0, 0); + test(*r->s4, 0, 20, *r->s3, 0, 0, 20); + test(*r->s4, 0, 20, *r->s3, 0, 1, 19); + test(*r->s4, 0, 20, *r->s3, 0, 5, 15); + test(*r->s4, 0, 20, *r->s3, 0, 9, 11); + test(*r->s4, 0, 20, *r->s3, 0, 10, 10); + test(*r->s4, 0, 20, *r->s3, 0, 11, 10); + test(*r->s4, 0, 20, *r->s3, 1, 0, 20); + test(*r->s4, 0, 20, *r->s3, 1, 1, -1); + test(*r->s4, 0, 20, *r->s3, 1, 4, -1); + test(*r->s4, 0, 20, *r->s3, 1, 8, -1); + test(*r->s4, 0, 20, *r->s3, 1, 9, -1); + test(*r->s4, 0, 20, *r->s3, 1, 10, -1); + test(*r->s4, 0, 20, *r->s3, 5, 0, 20); + test(*r->s4, 0, 20, *r->s3, 5, 1, -5); + test(*r->s4, 0, 20, *r->s3, 5, 2, -5); + test(*r->s4, 0, 20, *r->s3, 5, 4, -5); + test(*r->s4, 0, 20, *r->s3, 5, 5, -5); + test(*r->s4, 0, 20, *r->s3, 5, 6, -5); + test(*r->s4, 0, 20, *r->s3, 9, 0, 20); + test(*r->s4, 0, 20, *r->s3, 9, 1, -9); + test(*r->s4, 0, 20, *r->s3, 9, 2, -9); + test(*r->s4, 0, 20, *r->s3, 10, 0, 20); + test(*r->s4, 0, 20, *r->s3, 10, 1, 20); + test(*r->s4, 0, 20, *r->s3, 11, 0, 0); + test(*r->s4, 0, 20, *r->s4, 0, 0, 20); + test(*r->s4, 0, 20, *r->s4, 0, 1, 19); + test(*r->s4, 0, 20, *r->s4, 0, 10, 10); + test(*r->s4, 0, 20, *r->s4, 0, 19, 1); + test(*r->s4, 0, 20, *r->s4, 0, 20, 0); + test(*r->s4, 0, 20, *r->s4, 0, 21, 0); + test(*r->s4, 0, 20, *r->s4, 1, 0, 20); + test(*r->s4, 0, 20, *r->s4, 1, 1, -1); + test(*r->s4, 0, 20, *r->s4, 1, 9, -1); + test(*r->s4, 0, 20, *r->s4, 1, 18, -1); + test(*r->s4, 0, 20, *r->s4, 1, 19, -1); + test(*r->s4, 0, 20, *r->s4, 1, 20, -1); + test(*r->s4, 0, 20, *r->s4, 10, 0, 20); + test(*r->s4, 0, 20, *r->s4, 10, 1, -10); + test(*r->s4, 0, 20, *r->s4, 10, 5, -10); + test(*r->s4, 0, 20, *r->s4, 10, 9, -10); + test(*r->s4, 0, 20, *r->s4, 10, 10, -10); + test(*r->s4, 0, 20, *r->s4, 10, 11, -10); + test(*r->s4, 0, 20, *r->s4, 19, 0, 20); + test(*r->s4, 0, 20, *r->s4, 19, 1, -19); + test(*r->s4, 0, 20, *r->s4, 19, 2, -19); + test(*r->s4, 0, 20, *r->s4, 20, 0, 20); + test(*r->s4, 0, 20, *r->s4, 20, 1, 20); + test(*r->s4, 0, 20, *r->s4, 21, 0, 0); + test(*r->s4, 0, 21, *r->s1, 0, 0, 20); + test(*r->s4, 0, 21, *r->s1, 0, 1, 20); + test(*r->s4, 0, 21, *r->s1, 1, 0, 0); + test(*r->s4, 0, 21, *r->s2, 0, 0, 20); + test(*r->s4, 0, 21, *r->s2, 0, 1, 19); + test(*r->s4, 0, 21, *r->s2, 0, 2, 18); + test(*r->s4, 0, 21, *r->s2, 0, 4, 16); + test(*r->s4, 0, 21, *r->s2, 0, 5, 15); + test(*r->s4, 0, 21, *r->s2, 0, 6, 15); + test(*r->s4, 0, 21, *r->s2, 1, 0, 20); + test(*r->s4, 0, 21, *r->s2, 1, 1, -1); + test(*r->s4, 0, 21, *r->s2, 1, 2, -1); + test(*r->s4, 0, 21, *r->s2, 1, 3, -1); + test(*r->s4, 0, 21, *r->s2, 1, 4, -1); + test(*r->s4, 0, 21, *r->s2, 1, 5, -1); + test(*r->s4, 0, 21, *r->s2, 2, 0, 20); + test(*r->s4, 0, 21, *r->s2, 2, 1, -2); + test(*r->s4, 0, 21, *r->s2, 2, 2, -2); + test(*r->s4, 0, 21, *r->s2, 2, 3, -2); + test(*r->s4, 0, 21, *r->s2, 2, 4, -2); + test(*r->s4, 0, 21, *r->s2, 4, 0, 20); + test(*r->s4, 0, 21, *r->s2, 4, 1, -4); + test(*r->s4, 0, 21, *r->s2, 4, 2, -4); + test(*r->s4, 0, 21, *r->s2, 5, 0, 20); + test(*r->s4, 0, 21, *r->s2, 5, 1, 20); + test(*r->s4, 0, 21, *r->s2, 6, 0, 0); + test(*r->s4, 0, 21, *r->s3, 0, 0, 20); + test(*r->s4, 0, 21, *r->s3, 0, 1, 19); + test(*r->s4, 0, 21, *r->s3, 0, 5, 15); + test(*r->s4, 0, 21, *r->s3, 0, 9, 11); +} + +template +void +test41(pmem::obj::persistent_ptr &r) +{ + test(*r->s4, 0, 21, *r->s3, 0, 10, 10); + test(*r->s4, 0, 21, *r->s3, 0, 11, 10); + test(*r->s4, 0, 21, *r->s3, 1, 0, 20); + test(*r->s4, 0, 21, *r->s3, 1, 1, -1); + test(*r->s4, 0, 21, *r->s3, 1, 4, -1); + test(*r->s4, 0, 21, *r->s3, 1, 8, -1); + test(*r->s4, 0, 21, *r->s3, 1, 9, -1); + test(*r->s4, 0, 21, *r->s3, 1, 10, -1); + test(*r->s4, 0, 21, *r->s3, 5, 0, 20); + test(*r->s4, 0, 21, *r->s3, 5, 1, -5); + test(*r->s4, 0, 21, *r->s3, 5, 2, -5); + test(*r->s4, 0, 21, *r->s3, 5, 4, -5); + test(*r->s4, 0, 21, *r->s3, 5, 5, -5); + test(*r->s4, 0, 21, *r->s3, 5, 6, -5); + test(*r->s4, 0, 21, *r->s3, 9, 0, 20); + test(*r->s4, 0, 21, *r->s3, 9, 1, -9); + test(*r->s4, 0, 21, *r->s3, 9, 2, -9); + test(*r->s4, 0, 21, *r->s3, 10, 0, 20); + test(*r->s4, 0, 21, *r->s3, 10, 1, 20); + test(*r->s4, 0, 21, *r->s3, 11, 0, 0); + test(*r->s4, 0, 21, *r->s4, 0, 0, 20); + test(*r->s4, 0, 21, *r->s4, 0, 1, 19); + test(*r->s4, 0, 21, *r->s4, 0, 10, 10); + test(*r->s4, 0, 21, *r->s4, 0, 19, 1); + test(*r->s4, 0, 21, *r->s4, 0, 20, 0); + test(*r->s4, 0, 21, *r->s4, 0, 21, 0); + test(*r->s4, 0, 21, *r->s4, 1, 0, 20); + test(*r->s4, 0, 21, *r->s4, 1, 1, -1); + test(*r->s4, 0, 21, *r->s4, 1, 9, -1); + test(*r->s4, 0, 21, *r->s4, 1, 18, -1); + test(*r->s4, 0, 21, *r->s4, 1, 19, -1); + test(*r->s4, 0, 21, *r->s4, 1, 20, -1); + test(*r->s4, 0, 21, *r->s4, 10, 0, 20); + test(*r->s4, 0, 21, *r->s4, 10, 1, -10); + test(*r->s4, 0, 21, *r->s4, 10, 5, -10); + test(*r->s4, 0, 21, *r->s4, 10, 9, -10); + test(*r->s4, 0, 21, *r->s4, 10, 10, -10); + test(*r->s4, 0, 21, *r->s4, 10, 11, -10); + test(*r->s4, 0, 21, *r->s4, 19, 0, 20); + test(*r->s4, 0, 21, *r->s4, 19, 1, -19); + test(*r->s4, 0, 21, *r->s4, 19, 2, -19); + test(*r->s4, 0, 21, *r->s4, 20, 0, 20); + test(*r->s4, 0, 21, *r->s4, 20, 1, 20); + test(*r->s4, 0, 21, *r->s4, 21, 0, 0); + test(*r->s4, 1, 0, *r->s1, 0, 0, 0); + test(*r->s4, 1, 0, *r->s1, 0, 1, 0); + test(*r->s4, 1, 0, *r->s1, 1, 0, 0); + test(*r->s4, 1, 0, *r->s2, 0, 0, 0); + test(*r->s4, 1, 0, *r->s2, 0, 1, -1); + test(*r->s4, 1, 0, *r->s2, 0, 2, -2); + test(*r->s4, 1, 0, *r->s2, 0, 4, -4); + test(*r->s4, 1, 0, *r->s2, 0, 5, -5); + test(*r->s4, 1, 0, *r->s2, 0, 6, -5); + test(*r->s4, 1, 0, *r->s2, 1, 0, 0); + test(*r->s4, 1, 0, *r->s2, 1, 1, -1); + test(*r->s4, 1, 0, *r->s2, 1, 2, -2); + test(*r->s4, 1, 0, *r->s2, 1, 3, -3); + test(*r->s4, 1, 0, *r->s2, 1, 4, -4); + test(*r->s4, 1, 0, *r->s2, 1, 5, -4); + test(*r->s4, 1, 0, *r->s2, 2, 0, 0); + test(*r->s4, 1, 0, *r->s2, 2, 1, -1); + test(*r->s4, 1, 0, *r->s2, 2, 2, -2); + test(*r->s4, 1, 0, *r->s2, 2, 3, -3); + test(*r->s4, 1, 0, *r->s2, 2, 4, -3); + test(*r->s4, 1, 0, *r->s2, 4, 0, 0); + test(*r->s4, 1, 0, *r->s2, 4, 1, -1); + test(*r->s4, 1, 0, *r->s2, 4, 2, -1); + test(*r->s4, 1, 0, *r->s2, 5, 0, 0); + test(*r->s4, 1, 0, *r->s2, 5, 1, 0); + test(*r->s4, 1, 0, *r->s2, 6, 0, 0); + test(*r->s4, 1, 0, *r->s3, 0, 0, 0); + test(*r->s4, 1, 0, *r->s3, 0, 1, -1); + test(*r->s4, 1, 0, *r->s3, 0, 5, -5); + test(*r->s4, 1, 0, *r->s3, 0, 9, -9); + test(*r->s4, 1, 0, *r->s3, 0, 10, -10); + test(*r->s4, 1, 0, *r->s3, 0, 11, -10); + test(*r->s4, 1, 0, *r->s3, 1, 0, 0); + test(*r->s4, 1, 0, *r->s3, 1, 1, -1); + test(*r->s4, 1, 0, *r->s3, 1, 4, -4); + test(*r->s4, 1, 0, *r->s3, 1, 8, -8); + test(*r->s4, 1, 0, *r->s3, 1, 9, -9); + test(*r->s4, 1, 0, *r->s3, 1, 10, -9); + test(*r->s4, 1, 0, *r->s3, 5, 0, 0); + test(*r->s4, 1, 0, *r->s3, 5, 1, -1); + test(*r->s4, 1, 0, *r->s3, 5, 2, -2); + test(*r->s4, 1, 0, *r->s3, 5, 4, -4); + test(*r->s4, 1, 0, *r->s3, 5, 5, -5); + test(*r->s4, 1, 0, *r->s3, 5, 6, -5); + test(*r->s4, 1, 0, *r->s3, 9, 0, 0); + test(*r->s4, 1, 0, *r->s3, 9, 1, -1); + test(*r->s4, 1, 0, *r->s3, 9, 2, -1); + test(*r->s4, 1, 0, *r->s3, 10, 0, 0); + test(*r->s4, 1, 0, *r->s3, 10, 1, 0); + test(*r->s4, 1, 0, *r->s3, 11, 0, 0); + test(*r->s4, 1, 0, *r->s4, 0, 0, 0); + test(*r->s4, 1, 0, *r->s4, 0, 1, -1); + test(*r->s4, 1, 0, *r->s4, 0, 10, -10); + test(*r->s4, 1, 0, *r->s4, 0, 19, -19); + test(*r->s4, 1, 0, *r->s4, 0, 20, -20); + test(*r->s4, 1, 0, *r->s4, 0, 21, -20); +} + +template +void +test42(pmem::obj::persistent_ptr &r) +{ + test(*r->s4, 1, 0, *r->s4, 1, 0, 0); + test(*r->s4, 1, 0, *r->s4, 1, 1, -1); + test(*r->s4, 1, 0, *r->s4, 1, 9, -9); + test(*r->s4, 1, 0, *r->s4, 1, 18, -18); + test(*r->s4, 1, 0, *r->s4, 1, 19, -19); + test(*r->s4, 1, 0, *r->s4, 1, 20, -19); + test(*r->s4, 1, 0, *r->s4, 10, 0, 0); + test(*r->s4, 1, 0, *r->s4, 10, 1, -1); + test(*r->s4, 1, 0, *r->s4, 10, 5, -5); + test(*r->s4, 1, 0, *r->s4, 10, 9, -9); + test(*r->s4, 1, 0, *r->s4, 10, 10, -10); + test(*r->s4, 1, 0, *r->s4, 10, 11, -10); + test(*r->s4, 1, 0, *r->s4, 19, 0, 0); + test(*r->s4, 1, 0, *r->s4, 19, 1, -1); + test(*r->s4, 1, 0, *r->s4, 19, 2, -1); + test(*r->s4, 1, 0, *r->s4, 20, 0, 0); + test(*r->s4, 1, 0, *r->s4, 20, 1, 0); + test(*r->s4, 1, 0, *r->s4, 21, 0, 0); + test(*r->s4, 1, 1, *r->s1, 0, 0, 1); + test(*r->s4, 1, 1, *r->s1, 0, 1, 1); + test(*r->s4, 1, 1, *r->s1, 1, 0, 0); + test(*r->s4, 1, 1, *r->s2, 0, 0, 1); + test(*r->s4, 1, 1, *r->s2, 0, 1, 1); + test(*r->s4, 1, 1, *r->s2, 0, 2, 1); + test(*r->s4, 1, 1, *r->s2, 0, 4, 1); + test(*r->s4, 1, 1, *r->s2, 0, 5, 1); + test(*r->s4, 1, 1, *r->s2, 0, 6, 1); + test(*r->s4, 1, 1, *r->s2, 1, 0, 1); + test(*r->s4, 1, 1, *r->s2, 1, 1, 0); + test(*r->s4, 1, 1, *r->s2, 1, 2, -1); + test(*r->s4, 1, 1, *r->s2, 1, 3, -2); + test(*r->s4, 1, 1, *r->s2, 1, 4, -3); + test(*r->s4, 1, 1, *r->s2, 1, 5, -3); + test(*r->s4, 1, 1, *r->s2, 2, 0, 1); + test(*r->s4, 1, 1, *r->s2, 2, 1, -1); + test(*r->s4, 1, 1, *r->s2, 2, 2, -1); + test(*r->s4, 1, 1, *r->s2, 2, 3, -1); + test(*r->s4, 1, 1, *r->s2, 2, 4, -1); + test(*r->s4, 1, 1, *r->s2, 4, 0, 1); + test(*r->s4, 1, 1, *r->s2, 4, 1, -3); + test(*r->s4, 1, 1, *r->s2, 4, 2, -3); + test(*r->s4, 1, 1, *r->s2, 5, 0, 1); + test(*r->s4, 1, 1, *r->s2, 5, 1, 1); + test(*r->s4, 1, 1, *r->s2, 6, 0, 0); + test(*r->s4, 1, 1, *r->s3, 0, 0, 1); + test(*r->s4, 1, 1, *r->s3, 0, 1, 1); + test(*r->s4, 1, 1, *r->s3, 0, 5, 1); + test(*r->s4, 1, 1, *r->s3, 0, 9, 1); + test(*r->s4, 1, 1, *r->s3, 0, 10, 1); + test(*r->s4, 1, 1, *r->s3, 0, 11, 1); + test(*r->s4, 1, 1, *r->s3, 1, 0, 1); + test(*r->s4, 1, 1, *r->s3, 1, 1, 0); + test(*r->s4, 1, 1, *r->s3, 1, 4, -3); + test(*r->s4, 1, 1, *r->s3, 1, 8, -7); + test(*r->s4, 1, 1, *r->s3, 1, 9, -8); + test(*r->s4, 1, 1, *r->s3, 1, 10, -8); + test(*r->s4, 1, 1, *r->s3, 5, 0, 1); + test(*r->s4, 1, 1, *r->s3, 5, 1, -4); + test(*r->s4, 1, 1, *r->s3, 5, 2, -4); + test(*r->s4, 1, 1, *r->s3, 5, 4, -4); + test(*r->s4, 1, 1, *r->s3, 5, 5, -4); + test(*r->s4, 1, 1, *r->s3, 5, 6, -4); + test(*r->s4, 1, 1, *r->s3, 9, 0, 1); + test(*r->s4, 1, 1, *r->s3, 9, 1, -8); + test(*r->s4, 1, 1, *r->s3, 9, 2, -8); + test(*r->s4, 1, 1, *r->s3, 10, 0, 1); + test(*r->s4, 1, 1, *r->s3, 10, 1, 1); + test(*r->s4, 1, 1, *r->s3, 11, 0, 0); + test(*r->s4, 1, 1, *r->s4, 0, 0, 1); + test(*r->s4, 1, 1, *r->s4, 0, 1, 1); + test(*r->s4, 1, 1, *r->s4, 0, 10, 1); + test(*r->s4, 1, 1, *r->s4, 0, 19, 1); + test(*r->s4, 1, 1, *r->s4, 0, 20, 1); + test(*r->s4, 1, 1, *r->s4, 0, 21, 1); + test(*r->s4, 1, 1, *r->s4, 1, 0, 1); + test(*r->s4, 1, 1, *r->s4, 1, 1, 0); + test(*r->s4, 1, 1, *r->s4, 1, 9, -8); + test(*r->s4, 1, 1, *r->s4, 1, 18, -17); + test(*r->s4, 1, 1, *r->s4, 1, 19, -18); + test(*r->s4, 1, 1, *r->s4, 1, 20, -18); + test(*r->s4, 1, 1, *r->s4, 10, 0, 1); + test(*r->s4, 1, 1, *r->s4, 10, 1, -9); + test(*r->s4, 1, 1, *r->s4, 10, 5, -9); + test(*r->s4, 1, 1, *r->s4, 10, 9, -9); + test(*r->s4, 1, 1, *r->s4, 10, 10, -9); + test(*r->s4, 1, 1, *r->s4, 10, 11, -9); + test(*r->s4, 1, 1, *r->s4, 19, 0, 1); + test(*r->s4, 1, 1, *r->s4, 19, 1, -18); + test(*r->s4, 1, 1, *r->s4, 19, 2, -18); + test(*r->s4, 1, 1, *r->s4, 20, 0, 1); + test(*r->s4, 1, 1, *r->s4, 20, 1, 1); + test(*r->s4, 1, 1, *r->s4, 21, 0, 0); + test(*r->s4, 1, 9, *r->s1, 0, 0, 9); + test(*r->s4, 1, 9, *r->s1, 0, 1, 9); + test(*r->s4, 1, 9, *r->s1, 1, 0, 0); + test(*r->s4, 1, 9, *r->s2, 0, 0, 9); + test(*r->s4, 1, 9, *r->s2, 0, 1, 1); + test(*r->s4, 1, 9, *r->s2, 0, 2, 1); + test(*r->s4, 1, 9, *r->s2, 0, 4, 1); + test(*r->s4, 1, 9, *r->s2, 0, 5, 1); +} + +template +void +test43(pmem::obj::persistent_ptr &r) +{ + test(*r->s4, 1, 9, *r->s2, 0, 6, 1); + test(*r->s4, 1, 9, *r->s2, 1, 0, 9); + test(*r->s4, 1, 9, *r->s2, 1, 1, 8); + test(*r->s4, 1, 9, *r->s2, 1, 2, 7); + test(*r->s4, 1, 9, *r->s2, 1, 3, 6); + test(*r->s4, 1, 9, *r->s2, 1, 4, 5); + test(*r->s4, 1, 9, *r->s2, 1, 5, 5); + test(*r->s4, 1, 9, *r->s2, 2, 0, 9); + test(*r->s4, 1, 9, *r->s2, 2, 1, -1); + test(*r->s4, 1, 9, *r->s2, 2, 2, -1); + test(*r->s4, 1, 9, *r->s2, 2, 3, -1); + test(*r->s4, 1, 9, *r->s2, 2, 4, -1); + test(*r->s4, 1, 9, *r->s2, 4, 0, 9); + test(*r->s4, 1, 9, *r->s2, 4, 1, -3); + test(*r->s4, 1, 9, *r->s2, 4, 2, -3); + test(*r->s4, 1, 9, *r->s2, 5, 0, 9); + test(*r->s4, 1, 9, *r->s2, 5, 1, 9); + test(*r->s4, 1, 9, *r->s2, 6, 0, 0); + test(*r->s4, 1, 9, *r->s3, 0, 0, 9); + test(*r->s4, 1, 9, *r->s3, 0, 1, 1); + test(*r->s4, 1, 9, *r->s3, 0, 5, 1); + test(*r->s4, 1, 9, *r->s3, 0, 9, 1); + test(*r->s4, 1, 9, *r->s3, 0, 10, 1); + test(*r->s4, 1, 9, *r->s3, 0, 11, 1); + test(*r->s4, 1, 9, *r->s3, 1, 0, 9); + test(*r->s4, 1, 9, *r->s3, 1, 1, 8); + test(*r->s4, 1, 9, *r->s3, 1, 4, 5); + test(*r->s4, 1, 9, *r->s3, 1, 8, 1); + test(*r->s4, 1, 9, *r->s3, 1, 9, 0); + test(*r->s4, 1, 9, *r->s3, 1, 10, 0); + test(*r->s4, 1, 9, *r->s3, 5, 0, 9); + test(*r->s4, 1, 9, *r->s3, 5, 1, -4); + test(*r->s4, 1, 9, *r->s3, 5, 2, -4); + test(*r->s4, 1, 9, *r->s3, 5, 4, -4); + test(*r->s4, 1, 9, *r->s3, 5, 5, -4); + test(*r->s4, 1, 9, *r->s3, 5, 6, -4); + test(*r->s4, 1, 9, *r->s3, 9, 0, 9); + test(*r->s4, 1, 9, *r->s3, 9, 1, -8); + test(*r->s4, 1, 9, *r->s3, 9, 2, -8); + test(*r->s4, 1, 9, *r->s3, 10, 0, 9); + test(*r->s4, 1, 9, *r->s3, 10, 1, 9); + test(*r->s4, 1, 9, *r->s3, 11, 0, 0); + test(*r->s4, 1, 9, *r->s4, 0, 0, 9); + test(*r->s4, 1, 9, *r->s4, 0, 1, 1); + test(*r->s4, 1, 9, *r->s4, 0, 10, 1); + test(*r->s4, 1, 9, *r->s4, 0, 19, 1); + test(*r->s4, 1, 9, *r->s4, 0, 20, 1); + test(*r->s4, 1, 9, *r->s4, 0, 21, 1); + test(*r->s4, 1, 9, *r->s4, 1, 0, 9); + test(*r->s4, 1, 9, *r->s4, 1, 1, 8); + test(*r->s4, 1, 9, *r->s4, 1, 9, 0); + test(*r->s4, 1, 9, *r->s4, 1, 18, -9); + test(*r->s4, 1, 9, *r->s4, 1, 19, -10); + test(*r->s4, 1, 9, *r->s4, 1, 20, -10); + test(*r->s4, 1, 9, *r->s4, 10, 0, 9); + test(*r->s4, 1, 9, *r->s4, 10, 1, -9); + test(*r->s4, 1, 9, *r->s4, 10, 5, -9); + test(*r->s4, 1, 9, *r->s4, 10, 9, -9); + test(*r->s4, 1, 9, *r->s4, 10, 10, -9); + test(*r->s4, 1, 9, *r->s4, 10, 11, -9); + test(*r->s4, 1, 9, *r->s4, 19, 0, 9); + test(*r->s4, 1, 9, *r->s4, 19, 1, -18); + test(*r->s4, 1, 9, *r->s4, 19, 2, -18); + test(*r->s4, 1, 9, *r->s4, 20, 0, 9); + test(*r->s4, 1, 9, *r->s4, 20, 1, 9); + test(*r->s4, 1, 9, *r->s4, 21, 0, 0); + test(*r->s4, 1, 18, *r->s1, 0, 0, 18); + test(*r->s4, 1, 18, *r->s1, 0, 1, 18); + test(*r->s4, 1, 18, *r->s1, 1, 0, 0); + test(*r->s4, 1, 18, *r->s2, 0, 0, 18); + test(*r->s4, 1, 18, *r->s2, 0, 1, 1); + test(*r->s4, 1, 18, *r->s2, 0, 2, 1); + test(*r->s4, 1, 18, *r->s2, 0, 4, 1); + test(*r->s4, 1, 18, *r->s2, 0, 5, 1); + test(*r->s4, 1, 18, *r->s2, 0, 6, 1); + test(*r->s4, 1, 18, *r->s2, 1, 0, 18); + test(*r->s4, 1, 18, *r->s2, 1, 1, 17); + test(*r->s4, 1, 18, *r->s2, 1, 2, 16); + test(*r->s4, 1, 18, *r->s2, 1, 3, 15); + test(*r->s4, 1, 18, *r->s2, 1, 4, 14); + test(*r->s4, 1, 18, *r->s2, 1, 5, 14); + test(*r->s4, 1, 18, *r->s2, 2, 0, 18); + test(*r->s4, 1, 18, *r->s2, 2, 1, -1); + test(*r->s4, 1, 18, *r->s2, 2, 2, -1); + test(*r->s4, 1, 18, *r->s2, 2, 3, -1); + test(*r->s4, 1, 18, *r->s2, 2, 4, -1); + test(*r->s4, 1, 18, *r->s2, 4, 0, 18); + test(*r->s4, 1, 18, *r->s2, 4, 1, -3); + test(*r->s4, 1, 18, *r->s2, 4, 2, -3); + test(*r->s4, 1, 18, *r->s2, 5, 0, 18); + test(*r->s4, 1, 18, *r->s2, 5, 1, 18); + test(*r->s4, 1, 18, *r->s2, 6, 0, 0); + test(*r->s4, 1, 18, *r->s3, 0, 0, 18); + test(*r->s4, 1, 18, *r->s3, 0, 1, 1); + test(*r->s4, 1, 18, *r->s3, 0, 5, 1); + test(*r->s4, 1, 18, *r->s3, 0, 9, 1); + test(*r->s4, 1, 18, *r->s3, 0, 10, 1); + test(*r->s4, 1, 18, *r->s3, 0, 11, 1); + test(*r->s4, 1, 18, *r->s3, 1, 0, 18); + test(*r->s4, 1, 18, *r->s3, 1, 1, 17); +} + +template +void +test44(pmem::obj::persistent_ptr &r) +{ + test(*r->s4, 1, 18, *r->s3, 1, 4, 14); + test(*r->s4, 1, 18, *r->s3, 1, 8, 10); + test(*r->s4, 1, 18, *r->s3, 1, 9, 9); + test(*r->s4, 1, 18, *r->s3, 1, 10, 9); + test(*r->s4, 1, 18, *r->s3, 5, 0, 18); + test(*r->s4, 1, 18, *r->s3, 5, 1, -4); + test(*r->s4, 1, 18, *r->s3, 5, 2, -4); + test(*r->s4, 1, 18, *r->s3, 5, 4, -4); + test(*r->s4, 1, 18, *r->s3, 5, 5, -4); + test(*r->s4, 1, 18, *r->s3, 5, 6, -4); + test(*r->s4, 1, 18, *r->s3, 9, 0, 18); + test(*r->s4, 1, 18, *r->s3, 9, 1, -8); + test(*r->s4, 1, 18, *r->s3, 9, 2, -8); + test(*r->s4, 1, 18, *r->s3, 10, 0, 18); + test(*r->s4, 1, 18, *r->s3, 10, 1, 18); + test(*r->s4, 1, 18, *r->s3, 11, 0, 0); + test(*r->s4, 1, 18, *r->s4, 0, 0, 18); + test(*r->s4, 1, 18, *r->s4, 0, 1, 1); + test(*r->s4, 1, 18, *r->s4, 0, 10, 1); + test(*r->s4, 1, 18, *r->s4, 0, 19, 1); + test(*r->s4, 1, 18, *r->s4, 0, 20, 1); + test(*r->s4, 1, 18, *r->s4, 0, 21, 1); + test(*r->s4, 1, 18, *r->s4, 1, 0, 18); + test(*r->s4, 1, 18, *r->s4, 1, 1, 17); + test(*r->s4, 1, 18, *r->s4, 1, 9, 9); + test(*r->s4, 1, 18, *r->s4, 1, 18, 0); + test(*r->s4, 1, 18, *r->s4, 1, 19, -1); + test(*r->s4, 1, 18, *r->s4, 1, 20, -1); + test(*r->s4, 1, 18, *r->s4, 10, 0, 18); + test(*r->s4, 1, 18, *r->s4, 10, 1, -9); + test(*r->s4, 1, 18, *r->s4, 10, 5, -9); + test(*r->s4, 1, 18, *r->s4, 10, 9, -9); + test(*r->s4, 1, 18, *r->s4, 10, 10, -9); + test(*r->s4, 1, 18, *r->s4, 10, 11, -9); + test(*r->s4, 1, 18, *r->s4, 19, 0, 18); + test(*r->s4, 1, 18, *r->s4, 19, 1, -18); + test(*r->s4, 1, 18, *r->s4, 19, 2, -18); + test(*r->s4, 1, 18, *r->s4, 20, 0, 18); + test(*r->s4, 1, 18, *r->s4, 20, 1, 18); + test(*r->s4, 1, 18, *r->s4, 21, 0, 0); + test(*r->s4, 1, 19, *r->s1, 0, 0, 19); + test(*r->s4, 1, 19, *r->s1, 0, 1, 19); + test(*r->s4, 1, 19, *r->s1, 1, 0, 0); + test(*r->s4, 1, 19, *r->s2, 0, 0, 19); + test(*r->s4, 1, 19, *r->s2, 0, 1, 1); + test(*r->s4, 1, 19, *r->s2, 0, 2, 1); + test(*r->s4, 1, 19, *r->s2, 0, 4, 1); + test(*r->s4, 1, 19, *r->s2, 0, 5, 1); + test(*r->s4, 1, 19, *r->s2, 0, 6, 1); + test(*r->s4, 1, 19, *r->s2, 1, 0, 19); + test(*r->s4, 1, 19, *r->s2, 1, 1, 18); + test(*r->s4, 1, 19, *r->s2, 1, 2, 17); + test(*r->s4, 1, 19, *r->s2, 1, 3, 16); + test(*r->s4, 1, 19, *r->s2, 1, 4, 15); + test(*r->s4, 1, 19, *r->s2, 1, 5, 15); + test(*r->s4, 1, 19, *r->s2, 2, 0, 19); + test(*r->s4, 1, 19, *r->s2, 2, 1, -1); + test(*r->s4, 1, 19, *r->s2, 2, 2, -1); + test(*r->s4, 1, 19, *r->s2, 2, 3, -1); + test(*r->s4, 1, 19, *r->s2, 2, 4, -1); + test(*r->s4, 1, 19, *r->s2, 4, 0, 19); + test(*r->s4, 1, 19, *r->s2, 4, 1, -3); + test(*r->s4, 1, 19, *r->s2, 4, 2, -3); + test(*r->s4, 1, 19, *r->s2, 5, 0, 19); + test(*r->s4, 1, 19, *r->s2, 5, 1, 19); + test(*r->s4, 1, 19, *r->s2, 6, 0, 0); + test(*r->s4, 1, 19, *r->s3, 0, 0, 19); + test(*r->s4, 1, 19, *r->s3, 0, 1, 1); + test(*r->s4, 1, 19, *r->s3, 0, 5, 1); + test(*r->s4, 1, 19, *r->s3, 0, 9, 1); + test(*r->s4, 1, 19, *r->s3, 0, 10, 1); + test(*r->s4, 1, 19, *r->s3, 0, 11, 1); + test(*r->s4, 1, 19, *r->s3, 1, 0, 19); + test(*r->s4, 1, 19, *r->s3, 1, 1, 18); + test(*r->s4, 1, 19, *r->s3, 1, 4, 15); + test(*r->s4, 1, 19, *r->s3, 1, 8, 11); + test(*r->s4, 1, 19, *r->s3, 1, 9, 10); + test(*r->s4, 1, 19, *r->s3, 1, 10, 10); + test(*r->s4, 1, 19, *r->s3, 5, 0, 19); + test(*r->s4, 1, 19, *r->s3, 5, 1, -4); + test(*r->s4, 1, 19, *r->s3, 5, 2, -4); + test(*r->s4, 1, 19, *r->s3, 5, 4, -4); + test(*r->s4, 1, 19, *r->s3, 5, 5, -4); + test(*r->s4, 1, 19, *r->s3, 5, 6, -4); + test(*r->s4, 1, 19, *r->s3, 9, 0, 19); + test(*r->s4, 1, 19, *r->s3, 9, 1, -8); + test(*r->s4, 1, 19, *r->s3, 9, 2, -8); + test(*r->s4, 1, 19, *r->s3, 10, 0, 19); + test(*r->s4, 1, 19, *r->s3, 10, 1, 19); + test(*r->s4, 1, 19, *r->s3, 11, 0, 0); + test(*r->s4, 1, 19, *r->s4, 0, 0, 19); + test(*r->s4, 1, 19, *r->s4, 0, 1, 1); + test(*r->s4, 1, 19, *r->s4, 0, 10, 1); + test(*r->s4, 1, 19, *r->s4, 0, 19, 1); + test(*r->s4, 1, 19, *r->s4, 0, 20, 1); + test(*r->s4, 1, 19, *r->s4, 0, 21, 1); + test(*r->s4, 1, 19, *r->s4, 1, 0, 19); + test(*r->s4, 1, 19, *r->s4, 1, 1, 18); + test(*r->s4, 1, 19, *r->s4, 1, 9, 10); + test(*r->s4, 1, 19, *r->s4, 1, 18, 1); +} + +template +void +test45(pmem::obj::persistent_ptr &r) +{ + test(*r->s4, 1, 19, *r->s4, 1, 19, 0); + test(*r->s4, 1, 19, *r->s4, 1, 20, 0); + test(*r->s4, 1, 19, *r->s4, 10, 0, 19); + test(*r->s4, 1, 19, *r->s4, 10, 1, -9); + test(*r->s4, 1, 19, *r->s4, 10, 5, -9); + test(*r->s4, 1, 19, *r->s4, 10, 9, -9); + test(*r->s4, 1, 19, *r->s4, 10, 10, -9); + test(*r->s4, 1, 19, *r->s4, 10, 11, -9); + test(*r->s4, 1, 19, *r->s4, 19, 0, 19); + test(*r->s4, 1, 19, *r->s4, 19, 1, -18); + test(*r->s4, 1, 19, *r->s4, 19, 2, -18); + test(*r->s4, 1, 19, *r->s4, 20, 0, 19); + test(*r->s4, 1, 19, *r->s4, 20, 1, 19); + test(*r->s4, 1, 19, *r->s4, 21, 0, 0); + test(*r->s4, 1, 20, *r->s1, 0, 0, 19); + test(*r->s4, 1, 20, *r->s1, 0, 1, 19); + test(*r->s4, 1, 20, *r->s1, 1, 0, 0); + test(*r->s4, 1, 20, *r->s2, 0, 0, 19); + test(*r->s4, 1, 20, *r->s2, 0, 1, 1); + test(*r->s4, 1, 20, *r->s2, 0, 2, 1); + test(*r->s4, 1, 20, *r->s2, 0, 4, 1); + test(*r->s4, 1, 20, *r->s2, 0, 5, 1); + test(*r->s4, 1, 20, *r->s2, 0, 6, 1); + test(*r->s4, 1, 20, *r->s2, 1, 0, 19); + test(*r->s4, 1, 20, *r->s2, 1, 1, 18); + test(*r->s4, 1, 20, *r->s2, 1, 2, 17); + test(*r->s4, 1, 20, *r->s2, 1, 3, 16); + test(*r->s4, 1, 20, *r->s2, 1, 4, 15); + test(*r->s4, 1, 20, *r->s2, 1, 5, 15); + test(*r->s4, 1, 20, *r->s2, 2, 0, 19); + test(*r->s4, 1, 20, *r->s2, 2, 1, -1); + test(*r->s4, 1, 20, *r->s2, 2, 2, -1); + test(*r->s4, 1, 20, *r->s2, 2, 3, -1); + test(*r->s4, 1, 20, *r->s2, 2, 4, -1); + test(*r->s4, 1, 20, *r->s2, 4, 0, 19); + test(*r->s4, 1, 20, *r->s2, 4, 1, -3); + test(*r->s4, 1, 20, *r->s2, 4, 2, -3); + test(*r->s4, 1, 20, *r->s2, 5, 0, 19); + test(*r->s4, 1, 20, *r->s2, 5, 1, 19); + test(*r->s4, 1, 20, *r->s2, 6, 0, 0); + test(*r->s4, 1, 20, *r->s3, 0, 0, 19); + test(*r->s4, 1, 20, *r->s3, 0, 1, 1); + test(*r->s4, 1, 20, *r->s3, 0, 5, 1); + test(*r->s4, 1, 20, *r->s3, 0, 9, 1); + test(*r->s4, 1, 20, *r->s3, 0, 10, 1); + test(*r->s4, 1, 20, *r->s3, 0, 11, 1); + test(*r->s4, 1, 20, *r->s3, 1, 0, 19); + test(*r->s4, 1, 20, *r->s3, 1, 1, 18); + test(*r->s4, 1, 20, *r->s3, 1, 4, 15); + test(*r->s4, 1, 20, *r->s3, 1, 8, 11); + test(*r->s4, 1, 20, *r->s3, 1, 9, 10); + test(*r->s4, 1, 20, *r->s3, 1, 10, 10); + test(*r->s4, 1, 20, *r->s3, 5, 0, 19); + test(*r->s4, 1, 20, *r->s3, 5, 1, -4); + test(*r->s4, 1, 20, *r->s3, 5, 2, -4); + test(*r->s4, 1, 20, *r->s3, 5, 4, -4); + test(*r->s4, 1, 20, *r->s3, 5, 5, -4); + test(*r->s4, 1, 20, *r->s3, 5, 6, -4); + test(*r->s4, 1, 20, *r->s3, 9, 0, 19); + test(*r->s4, 1, 20, *r->s3, 9, 1, -8); + test(*r->s4, 1, 20, *r->s3, 9, 2, -8); + test(*r->s4, 1, 20, *r->s3, 10, 0, 19); + test(*r->s4, 1, 20, *r->s3, 10, 1, 19); + test(*r->s4, 1, 20, *r->s3, 11, 0, 0); + test(*r->s4, 1, 20, *r->s4, 0, 0, 19); + test(*r->s4, 1, 20, *r->s4, 0, 1, 1); + test(*r->s4, 1, 20, *r->s4, 0, 10, 1); + test(*r->s4, 1, 20, *r->s4, 0, 19, 1); + test(*r->s4, 1, 20, *r->s4, 0, 20, 1); + test(*r->s4, 1, 20, *r->s4, 0, 21, 1); + test(*r->s4, 1, 20, *r->s4, 1, 0, 19); + test(*r->s4, 1, 20, *r->s4, 1, 1, 18); + test(*r->s4, 1, 20, *r->s4, 1, 9, 10); + test(*r->s4, 1, 20, *r->s4, 1, 18, 1); + test(*r->s4, 1, 20, *r->s4, 1, 19, 0); + test(*r->s4, 1, 20, *r->s4, 1, 20, 0); + test(*r->s4, 1, 20, *r->s4, 10, 0, 19); + test(*r->s4, 1, 20, *r->s4, 10, 1, -9); + test(*r->s4, 1, 20, *r->s4, 10, 5, -9); + test(*r->s4, 1, 20, *r->s4, 10, 9, -9); + test(*r->s4, 1, 20, *r->s4, 10, 10, -9); + test(*r->s4, 1, 20, *r->s4, 10, 11, -9); + test(*r->s4, 1, 20, *r->s4, 19, 0, 19); + test(*r->s4, 1, 20, *r->s4, 19, 1, -18); + test(*r->s4, 1, 20, *r->s4, 19, 2, -18); + test(*r->s4, 1, 20, *r->s4, 20, 0, 19); + test(*r->s4, 1, 20, *r->s4, 20, 1, 19); + test(*r->s4, 1, 20, *r->s4, 21, 0, 0); + test(*r->s4, 10, 0, *r->s1, 0, 0, 0); + test(*r->s4, 10, 0, *r->s1, 0, 1, 0); + test(*r->s4, 10, 0, *r->s1, 1, 0, 0); + test(*r->s4, 10, 0, *r->s2, 0, 0, 0); + test(*r->s4, 10, 0, *r->s2, 0, 1, -1); + test(*r->s4, 10, 0, *r->s2, 0, 2, -2); + test(*r->s4, 10, 0, *r->s2, 0, 4, -4); + test(*r->s4, 10, 0, *r->s2, 0, 5, -5); + test(*r->s4, 10, 0, *r->s2, 0, 6, -5); + test(*r->s4, 10, 0, *r->s2, 1, 0, 0); + test(*r->s4, 10, 0, *r->s2, 1, 1, -1); + test(*r->s4, 10, 0, *r->s2, 1, 2, -2); +} + +template +void +test46(pmem::obj::persistent_ptr &r) +{ + test(*r->s4, 10, 0, *r->s2, 1, 3, -3); + test(*r->s4, 10, 0, *r->s2, 1, 4, -4); + test(*r->s4, 10, 0, *r->s2, 1, 5, -4); + test(*r->s4, 10, 0, *r->s2, 2, 0, 0); + test(*r->s4, 10, 0, *r->s2, 2, 1, -1); + test(*r->s4, 10, 0, *r->s2, 2, 2, -2); + test(*r->s4, 10, 0, *r->s2, 2, 3, -3); + test(*r->s4, 10, 0, *r->s2, 2, 4, -3); + test(*r->s4, 10, 0, *r->s2, 4, 0, 0); + test(*r->s4, 10, 0, *r->s2, 4, 1, -1); + test(*r->s4, 10, 0, *r->s2, 4, 2, -1); + test(*r->s4, 10, 0, *r->s2, 5, 0, 0); + test(*r->s4, 10, 0, *r->s2, 5, 1, 0); + test(*r->s4, 10, 0, *r->s2, 6, 0, 0); + test(*r->s4, 10, 0, *r->s3, 0, 0, 0); + test(*r->s4, 10, 0, *r->s3, 0, 1, -1); + test(*r->s4, 10, 0, *r->s3, 0, 5, -5); + test(*r->s4, 10, 0, *r->s3, 0, 9, -9); + test(*r->s4, 10, 0, *r->s3, 0, 10, -10); + test(*r->s4, 10, 0, *r->s3, 0, 11, -10); + test(*r->s4, 10, 0, *r->s3, 1, 0, 0); + test(*r->s4, 10, 0, *r->s3, 1, 1, -1); + test(*r->s4, 10, 0, *r->s3, 1, 4, -4); + test(*r->s4, 10, 0, *r->s3, 1, 8, -8); + test(*r->s4, 10, 0, *r->s3, 1, 9, -9); + test(*r->s4, 10, 0, *r->s3, 1, 10, -9); + test(*r->s4, 10, 0, *r->s3, 5, 0, 0); + test(*r->s4, 10, 0, *r->s3, 5, 1, -1); + test(*r->s4, 10, 0, *r->s3, 5, 2, -2); + test(*r->s4, 10, 0, *r->s3, 5, 4, -4); + test(*r->s4, 10, 0, *r->s3, 5, 5, -5); + test(*r->s4, 10, 0, *r->s3, 5, 6, -5); + test(*r->s4, 10, 0, *r->s3, 9, 0, 0); + test(*r->s4, 10, 0, *r->s3, 9, 1, -1); + test(*r->s4, 10, 0, *r->s3, 9, 2, -1); + test(*r->s4, 10, 0, *r->s3, 10, 0, 0); + test(*r->s4, 10, 0, *r->s3, 10, 1, 0); + test(*r->s4, 10, 0, *r->s3, 11, 0, 0); + test(*r->s4, 10, 0, *r->s4, 0, 0, 0); + test(*r->s4, 10, 0, *r->s4, 0, 1, -1); + test(*r->s4, 10, 0, *r->s4, 0, 10, -10); + test(*r->s4, 10, 0, *r->s4, 0, 19, -19); + test(*r->s4, 10, 0, *r->s4, 0, 20, -20); + test(*r->s4, 10, 0, *r->s4, 0, 21, -20); + test(*r->s4, 10, 0, *r->s4, 1, 0, 0); + test(*r->s4, 10, 0, *r->s4, 1, 1, -1); + test(*r->s4, 10, 0, *r->s4, 1, 9, -9); + test(*r->s4, 10, 0, *r->s4, 1, 18, -18); + test(*r->s4, 10, 0, *r->s4, 1, 19, -19); + test(*r->s4, 10, 0, *r->s4, 1, 20, -19); + test(*r->s4, 10, 0, *r->s4, 10, 0, 0); + test(*r->s4, 10, 0, *r->s4, 10, 1, -1); + test(*r->s4, 10, 0, *r->s4, 10, 5, -5); + test(*r->s4, 10, 0, *r->s4, 10, 9, -9); + test(*r->s4, 10, 0, *r->s4, 10, 10, -10); + test(*r->s4, 10, 0, *r->s4, 10, 11, -10); + test(*r->s4, 10, 0, *r->s4, 19, 0, 0); + test(*r->s4, 10, 0, *r->s4, 19, 1, -1); + test(*r->s4, 10, 0, *r->s4, 19, 2, -1); + test(*r->s4, 10, 0, *r->s4, 20, 0, 0); + test(*r->s4, 10, 0, *r->s4, 20, 1, 0); + test(*r->s4, 10, 0, *r->s4, 21, 0, 0); + test(*r->s4, 10, 1, *r->s1, 0, 0, 1); + test(*r->s4, 10, 1, *r->s1, 0, 1, 1); + test(*r->s4, 10, 1, *r->s1, 1, 0, 0); + test(*r->s4, 10, 1, *r->s2, 0, 0, 1); + test(*r->s4, 10, 1, *r->s2, 0, 1, 10); + test(*r->s4, 10, 1, *r->s2, 0, 2, 10); + test(*r->s4, 10, 1, *r->s2, 0, 4, 10); + test(*r->s4, 10, 1, *r->s2, 0, 5, 10); + test(*r->s4, 10, 1, *r->s2, 0, 6, 10); + test(*r->s4, 10, 1, *r->s2, 1, 0, 1); + test(*r->s4, 10, 1, *r->s2, 1, 1, 9); + test(*r->s4, 10, 1, *r->s2, 1, 2, 9); + test(*r->s4, 10, 1, *r->s2, 1, 3, 9); + test(*r->s4, 10, 1, *r->s2, 1, 4, 9); + test(*r->s4, 10, 1, *r->s2, 1, 5, 9); + test(*r->s4, 10, 1, *r->s2, 2, 0, 1); + test(*r->s4, 10, 1, *r->s2, 2, 1, 8); + test(*r->s4, 10, 1, *r->s2, 2, 2, 8); + test(*r->s4, 10, 1, *r->s2, 2, 3, 8); + test(*r->s4, 10, 1, *r->s2, 2, 4, 8); + test(*r->s4, 10, 1, *r->s2, 4, 0, 1); + test(*r->s4, 10, 1, *r->s2, 4, 1, 6); + test(*r->s4, 10, 1, *r->s2, 4, 2, 6); + test(*r->s4, 10, 1, *r->s2, 5, 0, 1); + test(*r->s4, 10, 1, *r->s2, 5, 1, 1); + test(*r->s4, 10, 1, *r->s2, 6, 0, 0); + test(*r->s4, 10, 1, *r->s3, 0, 0, 1); + test(*r->s4, 10, 1, *r->s3, 0, 1, 10); + test(*r->s4, 10, 1, *r->s3, 0, 5, 10); + test(*r->s4, 10, 1, *r->s3, 0, 9, 10); + test(*r->s4, 10, 1, *r->s3, 0, 10, 10); + test(*r->s4, 10, 1, *r->s3, 0, 11, 10); + test(*r->s4, 10, 1, *r->s3, 1, 0, 1); + test(*r->s4, 10, 1, *r->s3, 1, 1, 9); + test(*r->s4, 10, 1, *r->s3, 1, 4, 9); + test(*r->s4, 10, 1, *r->s3, 1, 8, 9); + test(*r->s4, 10, 1, *r->s3, 1, 9, 9); + test(*r->s4, 10, 1, *r->s3, 1, 10, 9); +} + +template +void +test47(pmem::obj::persistent_ptr &r) +{ + test(*r->s4, 10, 1, *r->s3, 5, 0, 1); + test(*r->s4, 10, 1, *r->s3, 5, 1, 5); + test(*r->s4, 10, 1, *r->s3, 5, 2, 5); + test(*r->s4, 10, 1, *r->s3, 5, 4, 5); + test(*r->s4, 10, 1, *r->s3, 5, 5, 5); + test(*r->s4, 10, 1, *r->s3, 5, 6, 5); + test(*r->s4, 10, 1, *r->s3, 9, 0, 1); + test(*r->s4, 10, 1, *r->s3, 9, 1, 1); + test(*r->s4, 10, 1, *r->s3, 9, 2, 1); + test(*r->s4, 10, 1, *r->s3, 10, 0, 1); + test(*r->s4, 10, 1, *r->s3, 10, 1, 1); + test(*r->s4, 10, 1, *r->s3, 11, 0, 0); + test(*r->s4, 10, 1, *r->s4, 0, 0, 1); + test(*r->s4, 10, 1, *r->s4, 0, 1, 10); + test(*r->s4, 10, 1, *r->s4, 0, 10, 10); + test(*r->s4, 10, 1, *r->s4, 0, 19, 10); + test(*r->s4, 10, 1, *r->s4, 0, 20, 10); + test(*r->s4, 10, 1, *r->s4, 0, 21, 10); + test(*r->s4, 10, 1, *r->s4, 1, 0, 1); + test(*r->s4, 10, 1, *r->s4, 1, 1, 9); + test(*r->s4, 10, 1, *r->s4, 1, 9, 9); + test(*r->s4, 10, 1, *r->s4, 1, 18, 9); + test(*r->s4, 10, 1, *r->s4, 1, 19, 9); + test(*r->s4, 10, 1, *r->s4, 1, 20, 9); + test(*r->s4, 10, 1, *r->s4, 10, 0, 1); + test(*r->s4, 10, 1, *r->s4, 10, 1, 0); + test(*r->s4, 10, 1, *r->s4, 10, 5, -4); + test(*r->s4, 10, 1, *r->s4, 10, 9, -8); + test(*r->s4, 10, 1, *r->s4, 10, 10, -9); + test(*r->s4, 10, 1, *r->s4, 10, 11, -9); + test(*r->s4, 10, 1, *r->s4, 19, 0, 1); + test(*r->s4, 10, 1, *r->s4, 19, 1, -9); + test(*r->s4, 10, 1, *r->s4, 19, 2, -9); + test(*r->s4, 10, 1, *r->s4, 20, 0, 1); + test(*r->s4, 10, 1, *r->s4, 20, 1, 1); + test(*r->s4, 10, 1, *r->s4, 21, 0, 0); + test(*r->s4, 10, 5, *r->s1, 0, 0, 5); + test(*r->s4, 10, 5, *r->s1, 0, 1, 5); + test(*r->s4, 10, 5, *r->s1, 1, 0, 0); + test(*r->s4, 10, 5, *r->s2, 0, 0, 5); + test(*r->s4, 10, 5, *r->s2, 0, 1, 10); + test(*r->s4, 10, 5, *r->s2, 0, 2, 10); + test(*r->s4, 10, 5, *r->s2, 0, 4, 10); + test(*r->s4, 10, 5, *r->s2, 0, 5, 10); + test(*r->s4, 10, 5, *r->s2, 0, 6, 10); + test(*r->s4, 10, 5, *r->s2, 1, 0, 5); + test(*r->s4, 10, 5, *r->s2, 1, 1, 9); + test(*r->s4, 10, 5, *r->s2, 1, 2, 9); + test(*r->s4, 10, 5, *r->s2, 1, 3, 9); + test(*r->s4, 10, 5, *r->s2, 1, 4, 9); + test(*r->s4, 10, 5, *r->s2, 1, 5, 9); + test(*r->s4, 10, 5, *r->s2, 2, 0, 5); + test(*r->s4, 10, 5, *r->s2, 2, 1, 8); + test(*r->s4, 10, 5, *r->s2, 2, 2, 8); + test(*r->s4, 10, 5, *r->s2, 2, 3, 8); + test(*r->s4, 10, 5, *r->s2, 2, 4, 8); + test(*r->s4, 10, 5, *r->s2, 4, 0, 5); + test(*r->s4, 10, 5, *r->s2, 4, 1, 6); + test(*r->s4, 10, 5, *r->s2, 4, 2, 6); + test(*r->s4, 10, 5, *r->s2, 5, 0, 5); + test(*r->s4, 10, 5, *r->s2, 5, 1, 5); + test(*r->s4, 10, 5, *r->s2, 6, 0, 0); + test(*r->s4, 10, 5, *r->s3, 0, 0, 5); + test(*r->s4, 10, 5, *r->s3, 0, 1, 10); + test(*r->s4, 10, 5, *r->s3, 0, 5, 10); + test(*r->s4, 10, 5, *r->s3, 0, 9, 10); + test(*r->s4, 10, 5, *r->s3, 0, 10, 10); + test(*r->s4, 10, 5, *r->s3, 0, 11, 10); + test(*r->s4, 10, 5, *r->s3, 1, 0, 5); + test(*r->s4, 10, 5, *r->s3, 1, 1, 9); + test(*r->s4, 10, 5, *r->s3, 1, 4, 9); + test(*r->s4, 10, 5, *r->s3, 1, 8, 9); + test(*r->s4, 10, 5, *r->s3, 1, 9, 9); + test(*r->s4, 10, 5, *r->s3, 1, 10, 9); + test(*r->s4, 10, 5, *r->s3, 5, 0, 5); + test(*r->s4, 10, 5, *r->s3, 5, 1, 5); + test(*r->s4, 10, 5, *r->s3, 5, 2, 5); + test(*r->s4, 10, 5, *r->s3, 5, 4, 5); + test(*r->s4, 10, 5, *r->s3, 5, 5, 5); + test(*r->s4, 10, 5, *r->s3, 5, 6, 5); + test(*r->s4, 10, 5, *r->s3, 9, 0, 5); + test(*r->s4, 10, 5, *r->s3, 9, 1, 1); + test(*r->s4, 10, 5, *r->s3, 9, 2, 1); + test(*r->s4, 10, 5, *r->s3, 10, 0, 5); + test(*r->s4, 10, 5, *r->s3, 10, 1, 5); + test(*r->s4, 10, 5, *r->s3, 11, 0, 0); + test(*r->s4, 10, 5, *r->s4, 0, 0, 5); + test(*r->s4, 10, 5, *r->s4, 0, 1, 10); + test(*r->s4, 10, 5, *r->s4, 0, 10, 10); + test(*r->s4, 10, 5, *r->s4, 0, 19, 10); + test(*r->s4, 10, 5, *r->s4, 0, 20, 10); + test(*r->s4, 10, 5, *r->s4, 0, 21, 10); + test(*r->s4, 10, 5, *r->s4, 1, 0, 5); + test(*r->s4, 10, 5, *r->s4, 1, 1, 9); + test(*r->s4, 10, 5, *r->s4, 1, 9, 9); + test(*r->s4, 10, 5, *r->s4, 1, 18, 9); + test(*r->s4, 10, 5, *r->s4, 1, 19, 9); + test(*r->s4, 10, 5, *r->s4, 1, 20, 9); + test(*r->s4, 10, 5, *r->s4, 10, 0, 5); + test(*r->s4, 10, 5, *r->s4, 10, 1, 4); +} + +template +void +test48(pmem::obj::persistent_ptr &r) +{ + test(*r->s4, 10, 5, *r->s4, 10, 5, 0); + test(*r->s4, 10, 5, *r->s4, 10, 9, -4); + test(*r->s4, 10, 5, *r->s4, 10, 10, -5); + test(*r->s4, 10, 5, *r->s4, 10, 11, -5); + test(*r->s4, 10, 5, *r->s4, 19, 0, 5); + test(*r->s4, 10, 5, *r->s4, 19, 1, -9); + test(*r->s4, 10, 5, *r->s4, 19, 2, -9); + test(*r->s4, 10, 5, *r->s4, 20, 0, 5); + test(*r->s4, 10, 5, *r->s4, 20, 1, 5); + test(*r->s4, 10, 5, *r->s4, 21, 0, 0); + test(*r->s4, 10, 9, *r->s1, 0, 0, 9); + test(*r->s4, 10, 9, *r->s1, 0, 1, 9); + test(*r->s4, 10, 9, *r->s1, 1, 0, 0); + test(*r->s4, 10, 9, *r->s2, 0, 0, 9); + test(*r->s4, 10, 9, *r->s2, 0, 1, 10); + test(*r->s4, 10, 9, *r->s2, 0, 2, 10); + test(*r->s4, 10, 9, *r->s2, 0, 4, 10); + test(*r->s4, 10, 9, *r->s2, 0, 5, 10); + test(*r->s4, 10, 9, *r->s2, 0, 6, 10); + test(*r->s4, 10, 9, *r->s2, 1, 0, 9); + test(*r->s4, 10, 9, *r->s2, 1, 1, 9); + test(*r->s4, 10, 9, *r->s2, 1, 2, 9); + test(*r->s4, 10, 9, *r->s2, 1, 3, 9); + test(*r->s4, 10, 9, *r->s2, 1, 4, 9); + test(*r->s4, 10, 9, *r->s2, 1, 5, 9); + test(*r->s4, 10, 9, *r->s2, 2, 0, 9); + test(*r->s4, 10, 9, *r->s2, 2, 1, 8); + test(*r->s4, 10, 9, *r->s2, 2, 2, 8); + test(*r->s4, 10, 9, *r->s2, 2, 3, 8); + test(*r->s4, 10, 9, *r->s2, 2, 4, 8); + test(*r->s4, 10, 9, *r->s2, 4, 0, 9); + test(*r->s4, 10, 9, *r->s2, 4, 1, 6); + test(*r->s4, 10, 9, *r->s2, 4, 2, 6); + test(*r->s4, 10, 9, *r->s2, 5, 0, 9); + test(*r->s4, 10, 9, *r->s2, 5, 1, 9); + test(*r->s4, 10, 9, *r->s2, 6, 0, 0); + test(*r->s4, 10, 9, *r->s3, 0, 0, 9); + test(*r->s4, 10, 9, *r->s3, 0, 1, 10); + test(*r->s4, 10, 9, *r->s3, 0, 5, 10); + test(*r->s4, 10, 9, *r->s3, 0, 9, 10); + test(*r->s4, 10, 9, *r->s3, 0, 10, 10); + test(*r->s4, 10, 9, *r->s3, 0, 11, 10); + test(*r->s4, 10, 9, *r->s3, 1, 0, 9); + test(*r->s4, 10, 9, *r->s3, 1, 1, 9); + test(*r->s4, 10, 9, *r->s3, 1, 4, 9); + test(*r->s4, 10, 9, *r->s3, 1, 8, 9); + test(*r->s4, 10, 9, *r->s3, 1, 9, 9); + test(*r->s4, 10, 9, *r->s3, 1, 10, 9); + test(*r->s4, 10, 9, *r->s3, 5, 0, 9); + test(*r->s4, 10, 9, *r->s3, 5, 1, 5); + test(*r->s4, 10, 9, *r->s3, 5, 2, 5); + test(*r->s4, 10, 9, *r->s3, 5, 4, 5); + test(*r->s4, 10, 9, *r->s3, 5, 5, 5); + test(*r->s4, 10, 9, *r->s3, 5, 6, 5); + test(*r->s4, 10, 9, *r->s3, 9, 0, 9); + test(*r->s4, 10, 9, *r->s3, 9, 1, 1); + test(*r->s4, 10, 9, *r->s3, 9, 2, 1); + test(*r->s4, 10, 9, *r->s3, 10, 0, 9); + test(*r->s4, 10, 9, *r->s3, 10, 1, 9); + test(*r->s4, 10, 9, *r->s3, 11, 0, 0); + test(*r->s4, 10, 9, *r->s4, 0, 0, 9); + test(*r->s4, 10, 9, *r->s4, 0, 1, 10); + test(*r->s4, 10, 9, *r->s4, 0, 10, 10); + test(*r->s4, 10, 9, *r->s4, 0, 19, 10); + test(*r->s4, 10, 9, *r->s4, 0, 20, 10); + test(*r->s4, 10, 9, *r->s4, 0, 21, 10); + test(*r->s4, 10, 9, *r->s4, 1, 0, 9); + test(*r->s4, 10, 9, *r->s4, 1, 1, 9); + test(*r->s4, 10, 9, *r->s4, 1, 9, 9); + test(*r->s4, 10, 9, *r->s4, 1, 18, 9); + test(*r->s4, 10, 9, *r->s4, 1, 19, 9); + test(*r->s4, 10, 9, *r->s4, 1, 20, 9); + test(*r->s4, 10, 9, *r->s4, 10, 0, 9); + test(*r->s4, 10, 9, *r->s4, 10, 1, 8); + test(*r->s4, 10, 9, *r->s4, 10, 5, 4); + test(*r->s4, 10, 9, *r->s4, 10, 9, 0); + test(*r->s4, 10, 9, *r->s4, 10, 10, -1); + test(*r->s4, 10, 9, *r->s4, 10, 11, -1); + test(*r->s4, 10, 9, *r->s4, 19, 0, 9); + test(*r->s4, 10, 9, *r->s4, 19, 1, -9); + test(*r->s4, 10, 9, *r->s4, 19, 2, -9); + test(*r->s4, 10, 9, *r->s4, 20, 0, 9); + test(*r->s4, 10, 9, *r->s4, 20, 1, 9); + test(*r->s4, 10, 9, *r->s4, 21, 0, 0); + test(*r->s4, 10, 10, *r->s1, 0, 0, 10); + test(*r->s4, 10, 10, *r->s1, 0, 1, 10); + test(*r->s4, 10, 10, *r->s1, 1, 0, 0); + test(*r->s4, 10, 10, *r->s2, 0, 0, 10); + test(*r->s4, 10, 10, *r->s2, 0, 1, 10); + test(*r->s4, 10, 10, *r->s2, 0, 2, 10); + test(*r->s4, 10, 10, *r->s2, 0, 4, 10); + test(*r->s4, 10, 10, *r->s2, 0, 5, 10); + test(*r->s4, 10, 10, *r->s2, 0, 6, 10); + test(*r->s4, 10, 10, *r->s2, 1, 0, 10); + test(*r->s4, 10, 10, *r->s2, 1, 1, 9); + test(*r->s4, 10, 10, *r->s2, 1, 2, 9); + test(*r->s4, 10, 10, *r->s2, 1, 3, 9); + test(*r->s4, 10, 10, *r->s2, 1, 4, 9); + test(*r->s4, 10, 10, *r->s2, 1, 5, 9); + test(*r->s4, 10, 10, *r->s2, 2, 0, 10); +} + +template +void +test49(pmem::obj::persistent_ptr &r) +{ + test(*r->s4, 10, 10, *r->s2, 2, 1, 8); + test(*r->s4, 10, 10, *r->s2, 2, 2, 8); + test(*r->s4, 10, 10, *r->s2, 2, 3, 8); + test(*r->s4, 10, 10, *r->s2, 2, 4, 8); + test(*r->s4, 10, 10, *r->s2, 4, 0, 10); + test(*r->s4, 10, 10, *r->s2, 4, 1, 6); + test(*r->s4, 10, 10, *r->s2, 4, 2, 6); + test(*r->s4, 10, 10, *r->s2, 5, 0, 10); + test(*r->s4, 10, 10, *r->s2, 5, 1, 10); + test(*r->s4, 10, 10, *r->s2, 6, 0, 0); + test(*r->s4, 10, 10, *r->s3, 0, 0, 10); + test(*r->s4, 10, 10, *r->s3, 0, 1, 10); + test(*r->s4, 10, 10, *r->s3, 0, 5, 10); + test(*r->s4, 10, 10, *r->s3, 0, 9, 10); + test(*r->s4, 10, 10, *r->s3, 0, 10, 10); + test(*r->s4, 10, 10, *r->s3, 0, 11, 10); + test(*r->s4, 10, 10, *r->s3, 1, 0, 10); + test(*r->s4, 10, 10, *r->s3, 1, 1, 9); + test(*r->s4, 10, 10, *r->s3, 1, 4, 9); + test(*r->s4, 10, 10, *r->s3, 1, 8, 9); + test(*r->s4, 10, 10, *r->s3, 1, 9, 9); + test(*r->s4, 10, 10, *r->s3, 1, 10, 9); + test(*r->s4, 10, 10, *r->s3, 5, 0, 10); + test(*r->s4, 10, 10, *r->s3, 5, 1, 5); + test(*r->s4, 10, 10, *r->s3, 5, 2, 5); + test(*r->s4, 10, 10, *r->s3, 5, 4, 5); + test(*r->s4, 10, 10, *r->s3, 5, 5, 5); + test(*r->s4, 10, 10, *r->s3, 5, 6, 5); + test(*r->s4, 10, 10, *r->s3, 9, 0, 10); + test(*r->s4, 10, 10, *r->s3, 9, 1, 1); + test(*r->s4, 10, 10, *r->s3, 9, 2, 1); + test(*r->s4, 10, 10, *r->s3, 10, 0, 10); + test(*r->s4, 10, 10, *r->s3, 10, 1, 10); + test(*r->s4, 10, 10, *r->s3, 11, 0, 0); + test(*r->s4, 10, 10, *r->s4, 0, 0, 10); + test(*r->s4, 10, 10, *r->s4, 0, 1, 10); + test(*r->s4, 10, 10, *r->s4, 0, 10, 10); + test(*r->s4, 10, 10, *r->s4, 0, 19, 10); + test(*r->s4, 10, 10, *r->s4, 0, 20, 10); + test(*r->s4, 10, 10, *r->s4, 0, 21, 10); + test(*r->s4, 10, 10, *r->s4, 1, 0, 10); + test(*r->s4, 10, 10, *r->s4, 1, 1, 9); + test(*r->s4, 10, 10, *r->s4, 1, 9, 9); + test(*r->s4, 10, 10, *r->s4, 1, 18, 9); + test(*r->s4, 10, 10, *r->s4, 1, 19, 9); + test(*r->s4, 10, 10, *r->s4, 1, 20, 9); + test(*r->s4, 10, 10, *r->s4, 10, 0, 10); + test(*r->s4, 10, 10, *r->s4, 10, 1, 9); + test(*r->s4, 10, 10, *r->s4, 10, 5, 5); + test(*r->s4, 10, 10, *r->s4, 10, 9, 1); + test(*r->s4, 10, 10, *r->s4, 10, 10, 0); + test(*r->s4, 10, 10, *r->s4, 10, 11, 0); + test(*r->s4, 10, 10, *r->s4, 19, 0, 10); + test(*r->s4, 10, 10, *r->s4, 19, 1, -9); + test(*r->s4, 10, 10, *r->s4, 19, 2, -9); + test(*r->s4, 10, 10, *r->s4, 20, 0, 10); + test(*r->s4, 10, 10, *r->s4, 20, 1, 10); + test(*r->s4, 10, 10, *r->s4, 21, 0, 0); + test(*r->s4, 10, 11, *r->s1, 0, 0, 10); + test(*r->s4, 10, 11, *r->s1, 0, 1, 10); + test(*r->s4, 10, 11, *r->s1, 1, 0, 0); + test(*r->s4, 10, 11, *r->s2, 0, 0, 10); + test(*r->s4, 10, 11, *r->s2, 0, 1, 10); + test(*r->s4, 10, 11, *r->s2, 0, 2, 10); + test(*r->s4, 10, 11, *r->s2, 0, 4, 10); + test(*r->s4, 10, 11, *r->s2, 0, 5, 10); + test(*r->s4, 10, 11, *r->s2, 0, 6, 10); + test(*r->s4, 10, 11, *r->s2, 1, 0, 10); + test(*r->s4, 10, 11, *r->s2, 1, 1, 9); + test(*r->s4, 10, 11, *r->s2, 1, 2, 9); + test(*r->s4, 10, 11, *r->s2, 1, 3, 9); + test(*r->s4, 10, 11, *r->s2, 1, 4, 9); + test(*r->s4, 10, 11, *r->s2, 1, 5, 9); + test(*r->s4, 10, 11, *r->s2, 2, 0, 10); + test(*r->s4, 10, 11, *r->s2, 2, 1, 8); + test(*r->s4, 10, 11, *r->s2, 2, 2, 8); + test(*r->s4, 10, 11, *r->s2, 2, 3, 8); + test(*r->s4, 10, 11, *r->s2, 2, 4, 8); + test(*r->s4, 10, 11, *r->s2, 4, 0, 10); + test(*r->s4, 10, 11, *r->s2, 4, 1, 6); + test(*r->s4, 10, 11, *r->s2, 4, 2, 6); + test(*r->s4, 10, 11, *r->s2, 5, 0, 10); + test(*r->s4, 10, 11, *r->s2, 5, 1, 10); + test(*r->s4, 10, 11, *r->s2, 6, 0, 0); + test(*r->s4, 10, 11, *r->s3, 0, 0, 10); + test(*r->s4, 10, 11, *r->s3, 0, 1, 10); + test(*r->s4, 10, 11, *r->s3, 0, 5, 10); + test(*r->s4, 10, 11, *r->s3, 0, 9, 10); + test(*r->s4, 10, 11, *r->s3, 0, 10, 10); + test(*r->s4, 10, 11, *r->s3, 0, 11, 10); + test(*r->s4, 10, 11, *r->s3, 1, 0, 10); + test(*r->s4, 10, 11, *r->s3, 1, 1, 9); + test(*r->s4, 10, 11, *r->s3, 1, 4, 9); + test(*r->s4, 10, 11, *r->s3, 1, 8, 9); + test(*r->s4, 10, 11, *r->s3, 1, 9, 9); + test(*r->s4, 10, 11, *r->s3, 1, 10, 9); + test(*r->s4, 10, 11, *r->s3, 5, 0, 10); + test(*r->s4, 10, 11, *r->s3, 5, 1, 5); + test(*r->s4, 10, 11, *r->s3, 5, 2, 5); + test(*r->s4, 10, 11, *r->s3, 5, 4, 5); +} + +template +void +test50(pmem::obj::persistent_ptr &r) +{ + test(*r->s4, 10, 11, *r->s3, 5, 5, 5); + test(*r->s4, 10, 11, *r->s3, 5, 6, 5); + test(*r->s4, 10, 11, *r->s3, 9, 0, 10); + test(*r->s4, 10, 11, *r->s3, 9, 1, 1); + test(*r->s4, 10, 11, *r->s3, 9, 2, 1); + test(*r->s4, 10, 11, *r->s3, 10, 0, 10); + test(*r->s4, 10, 11, *r->s3, 10, 1, 10); + test(*r->s4, 10, 11, *r->s3, 11, 0, 0); + test(*r->s4, 10, 11, *r->s4, 0, 0, 10); + test(*r->s4, 10, 11, *r->s4, 0, 1, 10); + test(*r->s4, 10, 11, *r->s4, 0, 10, 10); + test(*r->s4, 10, 11, *r->s4, 0, 19, 10); + test(*r->s4, 10, 11, *r->s4, 0, 20, 10); + test(*r->s4, 10, 11, *r->s4, 0, 21, 10); + test(*r->s4, 10, 11, *r->s4, 1, 0, 10); + test(*r->s4, 10, 11, *r->s4, 1, 1, 9); + test(*r->s4, 10, 11, *r->s4, 1, 9, 9); + test(*r->s4, 10, 11, *r->s4, 1, 18, 9); + test(*r->s4, 10, 11, *r->s4, 1, 19, 9); + test(*r->s4, 10, 11, *r->s4, 1, 20, 9); + test(*r->s4, 10, 11, *r->s4, 10, 0, 10); + test(*r->s4, 10, 11, *r->s4, 10, 1, 9); + test(*r->s4, 10, 11, *r->s4, 10, 5, 5); + test(*r->s4, 10, 11, *r->s4, 10, 9, 1); + test(*r->s4, 10, 11, *r->s4, 10, 10, 0); + test(*r->s4, 10, 11, *r->s4, 10, 11, 0); + test(*r->s4, 10, 11, *r->s4, 19, 0, 10); + test(*r->s4, 10, 11, *r->s4, 19, 1, -9); + test(*r->s4, 10, 11, *r->s4, 19, 2, -9); + test(*r->s4, 10, 11, *r->s4, 20, 0, 10); + test(*r->s4, 10, 11, *r->s4, 20, 1, 10); + test(*r->s4, 10, 11, *r->s4, 21, 0, 0); + test(*r->s4, 19, 0, *r->s1, 0, 0, 0); + test(*r->s4, 19, 0, *r->s1, 0, 1, 0); + test(*r->s4, 19, 0, *r->s1, 1, 0, 0); + test(*r->s4, 19, 0, *r->s2, 0, 0, 0); + test(*r->s4, 19, 0, *r->s2, 0, 1, -1); + test(*r->s4, 19, 0, *r->s2, 0, 2, -2); + test(*r->s4, 19, 0, *r->s2, 0, 4, -4); + test(*r->s4, 19, 0, *r->s2, 0, 5, -5); + test(*r->s4, 19, 0, *r->s2, 0, 6, -5); + test(*r->s4, 19, 0, *r->s2, 1, 0, 0); + test(*r->s4, 19, 0, *r->s2, 1, 1, -1); + test(*r->s4, 19, 0, *r->s2, 1, 2, -2); + test(*r->s4, 19, 0, *r->s2, 1, 3, -3); + test(*r->s4, 19, 0, *r->s2, 1, 4, -4); + test(*r->s4, 19, 0, *r->s2, 1, 5, -4); + test(*r->s4, 19, 0, *r->s2, 2, 0, 0); + test(*r->s4, 19, 0, *r->s2, 2, 1, -1); + test(*r->s4, 19, 0, *r->s2, 2, 2, -2); + test(*r->s4, 19, 0, *r->s2, 2, 3, -3); + test(*r->s4, 19, 0, *r->s2, 2, 4, -3); + test(*r->s4, 19, 0, *r->s2, 4, 0, 0); + test(*r->s4, 19, 0, *r->s2, 4, 1, -1); + test(*r->s4, 19, 0, *r->s2, 4, 2, -1); + test(*r->s4, 19, 0, *r->s2, 5, 0, 0); + test(*r->s4, 19, 0, *r->s2, 5, 1, 0); + test(*r->s4, 19, 0, *r->s2, 6, 0, 0); + test(*r->s4, 19, 0, *r->s3, 0, 0, 0); + test(*r->s4, 19, 0, *r->s3, 0, 1, -1); + test(*r->s4, 19, 0, *r->s3, 0, 5, -5); + test(*r->s4, 19, 0, *r->s3, 0, 9, -9); + test(*r->s4, 19, 0, *r->s3, 0, 10, -10); + test(*r->s4, 19, 0, *r->s3, 0, 11, -10); + test(*r->s4, 19, 0, *r->s3, 1, 0, 0); + test(*r->s4, 19, 0, *r->s3, 1, 1, -1); + test(*r->s4, 19, 0, *r->s3, 1, 4, -4); + test(*r->s4, 19, 0, *r->s3, 1, 8, -8); + test(*r->s4, 19, 0, *r->s3, 1, 9, -9); + test(*r->s4, 19, 0, *r->s3, 1, 10, -9); + test(*r->s4, 19, 0, *r->s3, 5, 0, 0); + test(*r->s4, 19, 0, *r->s3, 5, 1, -1); + test(*r->s4, 19, 0, *r->s3, 5, 2, -2); + test(*r->s4, 19, 0, *r->s3, 5, 4, -4); + test(*r->s4, 19, 0, *r->s3, 5, 5, -5); + test(*r->s4, 19, 0, *r->s3, 5, 6, -5); + test(*r->s4, 19, 0, *r->s3, 9, 0, 0); + test(*r->s4, 19, 0, *r->s3, 9, 1, -1); + test(*r->s4, 19, 0, *r->s3, 9, 2, -1); + test(*r->s4, 19, 0, *r->s3, 10, 0, 0); + test(*r->s4, 19, 0, *r->s3, 10, 1, 0); + test(*r->s4, 19, 0, *r->s3, 11, 0, 0); + test(*r->s4, 19, 0, *r->s4, 0, 0, 0); + test(*r->s4, 19, 0, *r->s4, 0, 1, -1); + test(*r->s4, 19, 0, *r->s4, 0, 10, -10); + test(*r->s4, 19, 0, *r->s4, 0, 19, -19); + test(*r->s4, 19, 0, *r->s4, 0, 20, -20); + test(*r->s4, 19, 0, *r->s4, 0, 21, -20); + test(*r->s4, 19, 0, *r->s4, 1, 0, 0); + test(*r->s4, 19, 0, *r->s4, 1, 1, -1); + test(*r->s4, 19, 0, *r->s4, 1, 9, -9); + test(*r->s4, 19, 0, *r->s4, 1, 18, -18); + test(*r->s4, 19, 0, *r->s4, 1, 19, -19); + test(*r->s4, 19, 0, *r->s4, 1, 20, -19); + test(*r->s4, 19, 0, *r->s4, 10, 0, 0); + test(*r->s4, 19, 0, *r->s4, 10, 1, -1); + test(*r->s4, 19, 0, *r->s4, 10, 5, -5); + test(*r->s4, 19, 0, *r->s4, 10, 9, -9); + test(*r->s4, 19, 0, *r->s4, 10, 10, -10); + test(*r->s4, 19, 0, *r->s4, 10, 11, -10); +} + +template +void +test51(pmem::obj::persistent_ptr &r) +{ + test(*r->s4, 19, 0, *r->s4, 19, 0, 0); + test(*r->s4, 19, 0, *r->s4, 19, 1, -1); + test(*r->s4, 19, 0, *r->s4, 19, 2, -1); + test(*r->s4, 19, 0, *r->s4, 20, 0, 0); + test(*r->s4, 19, 0, *r->s4, 20, 1, 0); + test(*r->s4, 19, 0, *r->s4, 21, 0, 0); + test(*r->s4, 19, 1, *r->s1, 0, 0, 1); + test(*r->s4, 19, 1, *r->s1, 0, 1, 1); + test(*r->s4, 19, 1, *r->s1, 1, 0, 0); + test(*r->s4, 19, 1, *r->s2, 0, 0, 1); + test(*r->s4, 19, 1, *r->s2, 0, 1, 19); + test(*r->s4, 19, 1, *r->s2, 0, 2, 19); + test(*r->s4, 19, 1, *r->s2, 0, 4, 19); + test(*r->s4, 19, 1, *r->s2, 0, 5, 19); + test(*r->s4, 19, 1, *r->s2, 0, 6, 19); + test(*r->s4, 19, 1, *r->s2, 1, 0, 1); + test(*r->s4, 19, 1, *r->s2, 1, 1, 18); + test(*r->s4, 19, 1, *r->s2, 1, 2, 18); + test(*r->s4, 19, 1, *r->s2, 1, 3, 18); + test(*r->s4, 19, 1, *r->s2, 1, 4, 18); + test(*r->s4, 19, 1, *r->s2, 1, 5, 18); + test(*r->s4, 19, 1, *r->s2, 2, 0, 1); + test(*r->s4, 19, 1, *r->s2, 2, 1, 17); + test(*r->s4, 19, 1, *r->s2, 2, 2, 17); + test(*r->s4, 19, 1, *r->s2, 2, 3, 17); + test(*r->s4, 19, 1, *r->s2, 2, 4, 17); + test(*r->s4, 19, 1, *r->s2, 4, 0, 1); + test(*r->s4, 19, 1, *r->s2, 4, 1, 15); + test(*r->s4, 19, 1, *r->s2, 4, 2, 15); + test(*r->s4, 19, 1, *r->s2, 5, 0, 1); + test(*r->s4, 19, 1, *r->s2, 5, 1, 1); + test(*r->s4, 19, 1, *r->s2, 6, 0, 0); + test(*r->s4, 19, 1, *r->s3, 0, 0, 1); + test(*r->s4, 19, 1, *r->s3, 0, 1, 19); + test(*r->s4, 19, 1, *r->s3, 0, 5, 19); + test(*r->s4, 19, 1, *r->s3, 0, 9, 19); + test(*r->s4, 19, 1, *r->s3, 0, 10, 19); + test(*r->s4, 19, 1, *r->s3, 0, 11, 19); + test(*r->s4, 19, 1, *r->s3, 1, 0, 1); + test(*r->s4, 19, 1, *r->s3, 1, 1, 18); + test(*r->s4, 19, 1, *r->s3, 1, 4, 18); + test(*r->s4, 19, 1, *r->s3, 1, 8, 18); + test(*r->s4, 19, 1, *r->s3, 1, 9, 18); + test(*r->s4, 19, 1, *r->s3, 1, 10, 18); + test(*r->s4, 19, 1, *r->s3, 5, 0, 1); + test(*r->s4, 19, 1, *r->s3, 5, 1, 14); + test(*r->s4, 19, 1, *r->s3, 5, 2, 14); + test(*r->s4, 19, 1, *r->s3, 5, 4, 14); + test(*r->s4, 19, 1, *r->s3, 5, 5, 14); + test(*r->s4, 19, 1, *r->s3, 5, 6, 14); + test(*r->s4, 19, 1, *r->s3, 9, 0, 1); + test(*r->s4, 19, 1, *r->s3, 9, 1, 10); + test(*r->s4, 19, 1, *r->s3, 9, 2, 10); + test(*r->s4, 19, 1, *r->s3, 10, 0, 1); + test(*r->s4, 19, 1, *r->s3, 10, 1, 1); + test(*r->s4, 19, 1, *r->s3, 11, 0, 0); + test(*r->s4, 19, 1, *r->s4, 0, 0, 1); + test(*r->s4, 19, 1, *r->s4, 0, 1, 19); + test(*r->s4, 19, 1, *r->s4, 0, 10, 19); + test(*r->s4, 19, 1, *r->s4, 0, 19, 19); + test(*r->s4, 19, 1, *r->s4, 0, 20, 19); + test(*r->s4, 19, 1, *r->s4, 0, 21, 19); + test(*r->s4, 19, 1, *r->s4, 1, 0, 1); + test(*r->s4, 19, 1, *r->s4, 1, 1, 18); + test(*r->s4, 19, 1, *r->s4, 1, 9, 18); + test(*r->s4, 19, 1, *r->s4, 1, 18, 18); + test(*r->s4, 19, 1, *r->s4, 1, 19, 18); + test(*r->s4, 19, 1, *r->s4, 1, 20, 18); + test(*r->s4, 19, 1, *r->s4, 10, 0, 1); + test(*r->s4, 19, 1, *r->s4, 10, 1, 9); + test(*r->s4, 19, 1, *r->s4, 10, 5, 9); + test(*r->s4, 19, 1, *r->s4, 10, 9, 9); + test(*r->s4, 19, 1, *r->s4, 10, 10, 9); + test(*r->s4, 19, 1, *r->s4, 10, 11, 9); + test(*r->s4, 19, 1, *r->s4, 19, 0, 1); + test(*r->s4, 19, 1, *r->s4, 19, 1, 0); + test(*r->s4, 19, 1, *r->s4, 19, 2, 0); + test(*r->s4, 19, 1, *r->s4, 20, 0, 1); + test(*r->s4, 19, 1, *r->s4, 20, 1, 1); + test(*r->s4, 19, 1, *r->s4, 21, 0, 0); + test(*r->s4, 19, 2, *r->s1, 0, 0, 1); + test(*r->s4, 19, 2, *r->s1, 0, 1, 1); + test(*r->s4, 19, 2, *r->s1, 1, 0, 0); + test(*r->s4, 19, 2, *r->s2, 0, 0, 1); + test(*r->s4, 19, 2, *r->s2, 0, 1, 19); + test(*r->s4, 19, 2, *r->s2, 0, 2, 19); + test(*r->s4, 19, 2, *r->s2, 0, 4, 19); + test(*r->s4, 19, 2, *r->s2, 0, 5, 19); + test(*r->s4, 19, 2, *r->s2, 0, 6, 19); + test(*r->s4, 19, 2, *r->s2, 1, 0, 1); + test(*r->s4, 19, 2, *r->s2, 1, 1, 18); + test(*r->s4, 19, 2, *r->s2, 1, 2, 18); + test(*r->s4, 19, 2, *r->s2, 1, 3, 18); + test(*r->s4, 19, 2, *r->s2, 1, 4, 18); + test(*r->s4, 19, 2, *r->s2, 1, 5, 18); + test(*r->s4, 19, 2, *r->s2, 2, 0, 1); + test(*r->s4, 19, 2, *r->s2, 2, 1, 17); + test(*r->s4, 19, 2, *r->s2, 2, 2, 17); + test(*r->s4, 19, 2, *r->s2, 2, 3, 17); + test(*r->s4, 19, 2, *r->s2, 2, 4, 17); +} + +template +void +test52(pmem::obj::persistent_ptr &r) +{ + test(*r->s4, 19, 2, *r->s2, 4, 0, 1); + test(*r->s4, 19, 2, *r->s2, 4, 1, 15); + test(*r->s4, 19, 2, *r->s2, 4, 2, 15); + test(*r->s4, 19, 2, *r->s2, 5, 0, 1); + test(*r->s4, 19, 2, *r->s2, 5, 1, 1); + test(*r->s4, 19, 2, *r->s2, 6, 0, 0); + test(*r->s4, 19, 2, *r->s3, 0, 0, 1); + test(*r->s4, 19, 2, *r->s3, 0, 1, 19); + test(*r->s4, 19, 2, *r->s3, 0, 5, 19); + test(*r->s4, 19, 2, *r->s3, 0, 9, 19); + test(*r->s4, 19, 2, *r->s3, 0, 10, 19); + test(*r->s4, 19, 2, *r->s3, 0, 11, 19); + test(*r->s4, 19, 2, *r->s3, 1, 0, 1); + test(*r->s4, 19, 2, *r->s3, 1, 1, 18); + test(*r->s4, 19, 2, *r->s3, 1, 4, 18); + test(*r->s4, 19, 2, *r->s3, 1, 8, 18); + test(*r->s4, 19, 2, *r->s3, 1, 9, 18); + test(*r->s4, 19, 2, *r->s3, 1, 10, 18); + test(*r->s4, 19, 2, *r->s3, 5, 0, 1); + test(*r->s4, 19, 2, *r->s3, 5, 1, 14); + test(*r->s4, 19, 2, *r->s3, 5, 2, 14); + test(*r->s4, 19, 2, *r->s3, 5, 4, 14); + test(*r->s4, 19, 2, *r->s3, 5, 5, 14); + test(*r->s4, 19, 2, *r->s3, 5, 6, 14); + test(*r->s4, 19, 2, *r->s3, 9, 0, 1); + test(*r->s4, 19, 2, *r->s3, 9, 1, 10); + test(*r->s4, 19, 2, *r->s3, 9, 2, 10); + test(*r->s4, 19, 2, *r->s3, 10, 0, 1); + test(*r->s4, 19, 2, *r->s3, 10, 1, 1); + test(*r->s4, 19, 2, *r->s3, 11, 0, 0); + test(*r->s4, 19, 2, *r->s4, 0, 0, 1); + test(*r->s4, 19, 2, *r->s4, 0, 1, 19); + test(*r->s4, 19, 2, *r->s4, 0, 10, 19); + test(*r->s4, 19, 2, *r->s4, 0, 19, 19); + test(*r->s4, 19, 2, *r->s4, 0, 20, 19); + test(*r->s4, 19, 2, *r->s4, 0, 21, 19); + test(*r->s4, 19, 2, *r->s4, 1, 0, 1); + test(*r->s4, 19, 2, *r->s4, 1, 1, 18); + test(*r->s4, 19, 2, *r->s4, 1, 9, 18); + test(*r->s4, 19, 2, *r->s4, 1, 18, 18); + test(*r->s4, 19, 2, *r->s4, 1, 19, 18); + test(*r->s4, 19, 2, *r->s4, 1, 20, 18); + test(*r->s4, 19, 2, *r->s4, 10, 0, 1); + test(*r->s4, 19, 2, *r->s4, 10, 1, 9); + test(*r->s4, 19, 2, *r->s4, 10, 5, 9); + test(*r->s4, 19, 2, *r->s4, 10, 9, 9); + test(*r->s4, 19, 2, *r->s4, 10, 10, 9); + test(*r->s4, 19, 2, *r->s4, 10, 11, 9); + test(*r->s4, 19, 2, *r->s4, 19, 0, 1); + test(*r->s4, 19, 2, *r->s4, 19, 1, 0); + test(*r->s4, 19, 2, *r->s4, 19, 2, 0); + test(*r->s4, 19, 2, *r->s4, 20, 0, 1); + test(*r->s4, 19, 2, *r->s4, 20, 1, 1); + test(*r->s4, 19, 2, *r->s4, 21, 0, 0); + test(*r->s4, 20, 0, *r->s1, 0, 0, 0); + test(*r->s4, 20, 0, *r->s1, 0, 1, 0); + test(*r->s4, 20, 0, *r->s1, 1, 0, 0); + test(*r->s4, 20, 0, *r->s2, 0, 0, 0); + test(*r->s4, 20, 0, *r->s2, 0, 1, -1); + test(*r->s4, 20, 0, *r->s2, 0, 2, -2); + test(*r->s4, 20, 0, *r->s2, 0, 4, -4); + test(*r->s4, 20, 0, *r->s2, 0, 5, -5); + test(*r->s4, 20, 0, *r->s2, 0, 6, -5); + test(*r->s4, 20, 0, *r->s2, 1, 0, 0); + test(*r->s4, 20, 0, *r->s2, 1, 1, -1); + test(*r->s4, 20, 0, *r->s2, 1, 2, -2); + test(*r->s4, 20, 0, *r->s2, 1, 3, -3); + test(*r->s4, 20, 0, *r->s2, 1, 4, -4); + test(*r->s4, 20, 0, *r->s2, 1, 5, -4); + test(*r->s4, 20, 0, *r->s2, 2, 0, 0); + test(*r->s4, 20, 0, *r->s2, 2, 1, -1); + test(*r->s4, 20, 0, *r->s2, 2, 2, -2); + test(*r->s4, 20, 0, *r->s2, 2, 3, -3); + test(*r->s4, 20, 0, *r->s2, 2, 4, -3); + test(*r->s4, 20, 0, *r->s2, 4, 0, 0); + test(*r->s4, 20, 0, *r->s2, 4, 1, -1); + test(*r->s4, 20, 0, *r->s2, 4, 2, -1); + test(*r->s4, 20, 0, *r->s2, 5, 0, 0); + test(*r->s4, 20, 0, *r->s2, 5, 1, 0); + test(*r->s4, 20, 0, *r->s2, 6, 0, 0); + test(*r->s4, 20, 0, *r->s3, 0, 0, 0); + test(*r->s4, 20, 0, *r->s3, 0, 1, -1); + test(*r->s4, 20, 0, *r->s3, 0, 5, -5); + test(*r->s4, 20, 0, *r->s3, 0, 9, -9); + test(*r->s4, 20, 0, *r->s3, 0, 10, -10); + test(*r->s4, 20, 0, *r->s3, 0, 11, -10); + test(*r->s4, 20, 0, *r->s3, 1, 0, 0); + test(*r->s4, 20, 0, *r->s3, 1, 1, -1); + test(*r->s4, 20, 0, *r->s3, 1, 4, -4); + test(*r->s4, 20, 0, *r->s3, 1, 8, -8); + test(*r->s4, 20, 0, *r->s3, 1, 9, -9); + test(*r->s4, 20, 0, *r->s3, 1, 10, -9); + test(*r->s4, 20, 0, *r->s3, 5, 0, 0); + test(*r->s4, 20, 0, *r->s3, 5, 1, -1); + test(*r->s4, 20, 0, *r->s3, 5, 2, -2); + test(*r->s4, 20, 0, *r->s3, 5, 4, -4); + test(*r->s4, 20, 0, *r->s3, 5, 5, -5); + test(*r->s4, 20, 0, *r->s3, 5, 6, -5); + test(*r->s4, 20, 0, *r->s3, 9, 0, 0); + test(*r->s4, 20, 0, *r->s3, 9, 1, -1); +} + +template +void +test53(pmem::obj::persistent_ptr &r) +{ + test(*r->s4, 20, 0, *r->s3, 9, 2, -1); + test(*r->s4, 20, 0, *r->s3, 10, 0, 0); + test(*r->s4, 20, 0, *r->s3, 10, 1, 0); + test(*r->s4, 20, 0, *r->s3, 11, 0, 0); + test(*r->s4, 20, 0, *r->s4, 0, 0, 0); + test(*r->s4, 20, 0, *r->s4, 0, 1, -1); + test(*r->s4, 20, 0, *r->s4, 0, 10, -10); + test(*r->s4, 20, 0, *r->s4, 0, 19, -19); + test(*r->s4, 20, 0, *r->s4, 0, 20, -20); + test(*r->s4, 20, 0, *r->s4, 0, 21, -20); + test(*r->s4, 20, 0, *r->s4, 1, 0, 0); + test(*r->s4, 20, 0, *r->s4, 1, 1, -1); + test(*r->s4, 20, 0, *r->s4, 1, 9, -9); + test(*r->s4, 20, 0, *r->s4, 1, 18, -18); + test(*r->s4, 20, 0, *r->s4, 1, 19, -19); + test(*r->s4, 20, 0, *r->s4, 1, 20, -19); + test(*r->s4, 20, 0, *r->s4, 10, 0, 0); + test(*r->s4, 20, 0, *r->s4, 10, 1, -1); + test(*r->s4, 20, 0, *r->s4, 10, 5, -5); + test(*r->s4, 20, 0, *r->s4, 10, 9, -9); + test(*r->s4, 20, 0, *r->s4, 10, 10, -10); + test(*r->s4, 20, 0, *r->s4, 10, 11, -10); + test(*r->s4, 20, 0, *r->s4, 19, 0, 0); + test(*r->s4, 20, 0, *r->s4, 19, 1, -1); + test(*r->s4, 20, 0, *r->s4, 19, 2, -1); + test(*r->s4, 20, 0, *r->s4, 20, 0, 0); + test(*r->s4, 20, 0, *r->s4, 20, 1, 0); + test(*r->s4, 20, 0, *r->s4, 21, 0, 0); + test(*r->s4, 20, 1, *r->s1, 0, 0, 0); + test(*r->s4, 20, 1, *r->s1, 0, 1, 0); + test(*r->s4, 20, 1, *r->s1, 1, 0, 0); + test(*r->s4, 20, 1, *r->s2, 0, 0, 0); + test(*r->s4, 20, 1, *r->s2, 0, 1, -1); + test(*r->s4, 20, 1, *r->s2, 0, 2, -2); + test(*r->s4, 20, 1, *r->s2, 0, 4, -4); + test(*r->s4, 20, 1, *r->s2, 0, 5, -5); + test(*r->s4, 20, 1, *r->s2, 0, 6, -5); + test(*r->s4, 20, 1, *r->s2, 1, 0, 0); + test(*r->s4, 20, 1, *r->s2, 1, 1, -1); + test(*r->s4, 20, 1, *r->s2, 1, 2, -2); + test(*r->s4, 20, 1, *r->s2, 1, 3, -3); + test(*r->s4, 20, 1, *r->s2, 1, 4, -4); + test(*r->s4, 20, 1, *r->s2, 1, 5, -4); + test(*r->s4, 20, 1, *r->s2, 2, 0, 0); + test(*r->s4, 20, 1, *r->s2, 2, 1, -1); + test(*r->s4, 20, 1, *r->s2, 2, 2, -2); + test(*r->s4, 20, 1, *r->s2, 2, 3, -3); + test(*r->s4, 20, 1, *r->s2, 2, 4, -3); + test(*r->s4, 20, 1, *r->s2, 4, 0, 0); + test(*r->s4, 20, 1, *r->s2, 4, 1, -1); + test(*r->s4, 20, 1, *r->s2, 4, 2, -1); + test(*r->s4, 20, 1, *r->s2, 5, 0, 0); + test(*r->s4, 20, 1, *r->s2, 5, 1, 0); + test(*r->s4, 20, 1, *r->s2, 6, 0, 0); + test(*r->s4, 20, 1, *r->s3, 0, 0, 0); + test(*r->s4, 20, 1, *r->s3, 0, 1, -1); + test(*r->s4, 20, 1, *r->s3, 0, 5, -5); + test(*r->s4, 20, 1, *r->s3, 0, 9, -9); + test(*r->s4, 20, 1, *r->s3, 0, 10, -10); + test(*r->s4, 20, 1, *r->s3, 0, 11, -10); + test(*r->s4, 20, 1, *r->s3, 1, 0, 0); + test(*r->s4, 20, 1, *r->s3, 1, 1, -1); + test(*r->s4, 20, 1, *r->s3, 1, 4, -4); + test(*r->s4, 20, 1, *r->s3, 1, 8, -8); + test(*r->s4, 20, 1, *r->s3, 1, 9, -9); + test(*r->s4, 20, 1, *r->s3, 1, 10, -9); + test(*r->s4, 20, 1, *r->s3, 5, 0, 0); + test(*r->s4, 20, 1, *r->s3, 5, 1, -1); + test(*r->s4, 20, 1, *r->s3, 5, 2, -2); + test(*r->s4, 20, 1, *r->s3, 5, 4, -4); + test(*r->s4, 20, 1, *r->s3, 5, 5, -5); + test(*r->s4, 20, 1, *r->s3, 5, 6, -5); + test(*r->s4, 20, 1, *r->s3, 9, 0, 0); + test(*r->s4, 20, 1, *r->s3, 9, 1, -1); + test(*r->s4, 20, 1, *r->s3, 9, 2, -1); + test(*r->s4, 20, 1, *r->s3, 10, 0, 0); + test(*r->s4, 20, 1, *r->s3, 10, 1, 0); + test(*r->s4, 20, 1, *r->s3, 11, 0, 0); + test(*r->s4, 20, 1, *r->s4, 0, 0, 0); + test(*r->s4, 20, 1, *r->s4, 0, 1, -1); + test(*r->s4, 20, 1, *r->s4, 0, 10, -10); + test(*r->s4, 20, 1, *r->s4, 0, 19, -19); + test(*r->s4, 20, 1, *r->s4, 0, 20, -20); + test(*r->s4, 20, 1, *r->s4, 0, 21, -20); + test(*r->s4, 20, 1, *r->s4, 1, 0, 0); + test(*r->s4, 20, 1, *r->s4, 1, 1, -1); + test(*r->s4, 20, 1, *r->s4, 1, 9, -9); + test(*r->s4, 20, 1, *r->s4, 1, 18, -18); + test(*r->s4, 20, 1, *r->s4, 1, 19, -19); + test(*r->s4, 20, 1, *r->s4, 1, 20, -19); + test(*r->s4, 20, 1, *r->s4, 10, 0, 0); + test(*r->s4, 20, 1, *r->s4, 10, 1, -1); + test(*r->s4, 20, 1, *r->s4, 10, 5, -5); + test(*r->s4, 20, 1, *r->s4, 10, 9, -9); + test(*r->s4, 20, 1, *r->s4, 10, 10, -10); + test(*r->s4, 20, 1, *r->s4, 10, 11, -10); + test(*r->s4, 20, 1, *r->s4, 19, 0, 0); + test(*r->s4, 20, 1, *r->s4, 19, 1, -1); + test(*r->s4, 20, 1, *r->s4, 19, 2, -1); + test(*r->s4, 20, 1, *r->s4, 20, 0, 0); +} + +template +void +test54(pmem::obj::persistent_ptr &r) +{ + test(*r->s4, 20, 1, *r->s4, 20, 1, 0); + test(*r->s4, 20, 1, *r->s4, 21, 0, 0); + test(*r->s4, 21, 0, *r->s1, 0, 0, 0); + test(*r->s4, 21, 0, *r->s1, 0, 1, 0); + test(*r->s4, 21, 0, *r->s1, 1, 0, 0); + test(*r->s4, 21, 0, *r->s2, 0, 0, 0); + test(*r->s4, 21, 0, *r->s2, 0, 1, 0); + test(*r->s4, 21, 0, *r->s2, 0, 2, 0); + test(*r->s4, 21, 0, *r->s2, 0, 4, 0); + test(*r->s4, 21, 0, *r->s2, 0, 5, 0); + test(*r->s4, 21, 0, *r->s2, 0, 6, 0); + test(*r->s4, 21, 0, *r->s2, 1, 0, 0); + test(*r->s4, 21, 0, *r->s2, 1, 1, 0); + test(*r->s4, 21, 0, *r->s2, 1, 2, 0); + test(*r->s4, 21, 0, *r->s2, 1, 3, 0); + test(*r->s4, 21, 0, *r->s2, 1, 4, 0); + test(*r->s4, 21, 0, *r->s2, 1, 5, 0); + test(*r->s4, 21, 0, *r->s2, 2, 0, 0); + test(*r->s4, 21, 0, *r->s2, 2, 1, 0); + test(*r->s4, 21, 0, *r->s2, 2, 2, 0); + test(*r->s4, 21, 0, *r->s2, 2, 3, 0); + test(*r->s4, 21, 0, *r->s2, 2, 4, 0); + test(*r->s4, 21, 0, *r->s2, 4, 0, 0); + test(*r->s4, 21, 0, *r->s2, 4, 1, 0); + test(*r->s4, 21, 0, *r->s2, 4, 2, 0); + test(*r->s4, 21, 0, *r->s2, 5, 0, 0); + test(*r->s4, 21, 0, *r->s2, 5, 1, 0); + test(*r->s4, 21, 0, *r->s2, 6, 0, 0); + test(*r->s4, 21, 0, *r->s3, 0, 0, 0); + test(*r->s4, 21, 0, *r->s3, 0, 1, 0); + test(*r->s4, 21, 0, *r->s3, 0, 5, 0); + test(*r->s4, 21, 0, *r->s3, 0, 9, 0); + test(*r->s4, 21, 0, *r->s3, 0, 10, 0); + test(*r->s4, 21, 0, *r->s3, 0, 11, 0); + test(*r->s4, 21, 0, *r->s3, 1, 0, 0); + test(*r->s4, 21, 0, *r->s3, 1, 1, 0); + test(*r->s4, 21, 0, *r->s3, 1, 4, 0); + test(*r->s4, 21, 0, *r->s3, 1, 8, 0); + test(*r->s4, 21, 0, *r->s3, 1, 9, 0); + test(*r->s4, 21, 0, *r->s3, 1, 10, 0); + test(*r->s4, 21, 0, *r->s3, 5, 0, 0); + test(*r->s4, 21, 0, *r->s3, 5, 1, 0); + test(*r->s4, 21, 0, *r->s3, 5, 2, 0); + test(*r->s4, 21, 0, *r->s3, 5, 4, 0); + test(*r->s4, 21, 0, *r->s3, 5, 5, 0); + test(*r->s4, 21, 0, *r->s3, 5, 6, 0); + test(*r->s4, 21, 0, *r->s3, 9, 0, 0); + test(*r->s4, 21, 0, *r->s3, 9, 1, 0); + test(*r->s4, 21, 0, *r->s3, 9, 2, 0); + test(*r->s4, 21, 0, *r->s3, 10, 0, 0); + test(*r->s4, 21, 0, *r->s3, 10, 1, 0); + test(*r->s4, 21, 0, *r->s3, 11, 0, 0); + test(*r->s4, 21, 0, *r->s4, 0, 0, 0); + test(*r->s4, 21, 0, *r->s4, 0, 1, 0); + test(*r->s4, 21, 0, *r->s4, 0, 10, 0); + test(*r->s4, 21, 0, *r->s4, 0, 19, 0); + test(*r->s4, 21, 0, *r->s4, 0, 20, 0); + test(*r->s4, 21, 0, *r->s4, 0, 21, 0); + test(*r->s4, 21, 0, *r->s4, 1, 0, 0); + test(*r->s4, 21, 0, *r->s4, 1, 1, 0); + test(*r->s4, 21, 0, *r->s4, 1, 9, 0); + test(*r->s4, 21, 0, *r->s4, 1, 18, 0); + test(*r->s4, 21, 0, *r->s4, 1, 19, 0); + test(*r->s4, 21, 0, *r->s4, 1, 20, 0); + test(*r->s4, 21, 0, *r->s4, 10, 0, 0); + test(*r->s4, 21, 0, *r->s4, 10, 1, 0); + test(*r->s4, 21, 0, *r->s4, 10, 5, 0); + test(*r->s4, 21, 0, *r->s4, 10, 9, 0); + test(*r->s4, 21, 0, *r->s4, 10, 10, 0); + test(*r->s4, 21, 0, *r->s4, 10, 11, 0); + test(*r->s4, 21, 0, *r->s4, 19, 0, 0); + test(*r->s4, 21, 0, *r->s4, 19, 1, 0); + test(*r->s4, 21, 0, *r->s4, 19, 2, 0); + test(*r->s4, 21, 0, *r->s4, 20, 0, 0); + test(*r->s4, 21, 0, *r->s4, 20, 1, 0); + test(*r->s4, 21, 0, *r->s4, 21, 0, 0); +} + +template +void +test55(pmem::obj::persistent_ptr &r) +{ + test_npos(*r->s1, 0, 0, *r->s1, 0, 0); + test_npos(*r->s1, 0, 0, *r->s2, 0, -5); + test_npos(*r->s2, 0, 0, *r->s3, 0, -10); + test_npos(*r->s2, 0, 0, *r->s3, 1, -9); + test_npos(*r->s2, 0, 0, *r->s3, 5, -5); +} + +void +run(pmem::obj::pool &pop) +{ + auto r = pop.root(); + + try { + nvobj::transaction::run(pop, [&] { + r->s1 = nvobj::make_persistent(""); + r->s2 = nvobj::make_persistent( + "abcde"); + r->s3 = nvobj::make_persistent( + "abcdefghij"); + r->s4 = nvobj::make_persistent( + "abcdefghijklmnopqrst"); + }); + + typedef pmem_exp::string S; + test0(r); + test1(r); + test2(r); + test3(r); + test4(r); + test5(r); + test6(r); + test7(r); + test8(r); + test9(r); + test10(r); + test11(r); + test12(r); + test13(r); + test14(r); + test15(r); + test16(r); + test17(r); + test18(r); + test19(r); + test20(r); + test21(r); + test22(r); + test23(r); + test24(r); + test25(r); + test26(r); + test27(r); + test28(r); + test29(r); + test30(r); + test31(r); + test32(r); + test33(r); + test34(r); + test35(r); + test36(r); + test37(r); + test38(r); + test39(r); + test40(r); + test41(r); + test42(r); + test43(r); + test44(r); + test45(r); + test46(r); + test47(r); + test48(r); + test49(r); + test50(r); + test51(r); + test52(r); + test53(r); + test54(r); + test55(r); + + nvobj::transaction::run(pop, [&] { + nvobj::delete_persistent(r->s1); + nvobj::delete_persistent(r->s2); + nvobj::delete_persistent(r->s3); + nvobj::delete_persistent(r->s4); + }); + } catch (std::exception &e) { + UT_FATALexc(e); + } +} + +int +main(int argc, char *argv[]) +{ + START(); + + if (argc != 2) + UT_FATAL("usage: %s file-name", argv[0]); + + const char *path = argv[1]; + + pmem::obj::pool pop; + + try { + pop = pmem::obj::pool::create(path, "basic_string", + PMEMOBJ_MIN_POOL, + S_IWUSR | S_IRUSR); + } catch (...) { + UT_FATAL("!pmemobj_create: %s", path); + } + + run(pop); + + pop.close(); + + return 0; +} diff --git a/tests/external/libcxx/basic_string/string.ops/string_compare/size_size_string_view.pass.cpp b/tests/external/libcxx/basic_string/string.ops/string_compare/size_size_string_view.pass.cpp new file mode 100644 index 0000000..53114f3 --- /dev/null +++ b/tests/external/libcxx/basic_string/string.ops/string_compare/size_size_string_view.pass.cpp @@ -0,0 +1,383 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// + +// int compare(size_type pos1, size_type n1, basic_string_vew sv) const; + +#include +#include +#include + +#include "min_allocator.h" + +#include "test_macros.h" + +int sign(int x) +{ + if (x == 0) + return 0; + if (x < 0) + return -1; + return 1; +} + +template +void +test(const S& s, typename S::size_type pos1, typename S::size_type n1, + SV sv, int x) +{ + if (pos1 <= s.size()) + assert(sign(s.compare(pos1, n1, sv)) == sign(x)); +#ifndef TEST_HAS_NO_EXCEPTIONS + else + { + try + { + TEST_IGNORE_NODISCARD s.compare(pos1, n1, sv); + assert(false); + } + catch (std::out_of_range&) + { + assert(pos1 > s.size()); + } + } +#endif +} + +template +void test0() +{ + test(S(""), 0, 0, SV(""), 0); + test(S(""), 0, 0, SV("abcde"), -5); + test(S(""), 0, 0, SV("abcdefghij"), -10); + test(S(""), 0, 0, SV("abcdefghijklmnopqrst"), -20); + test(S(""), 0, 1, SV(""), 0); + test(S(""), 0, 1, SV("abcde"), -5); + test(S(""), 0, 1, SV("abcdefghij"), -10); + test(S(""), 0, 1, SV("abcdefghijklmnopqrst"), -20); + test(S(""), 1, 0, SV(""), 0); + test(S(""), 1, 0, SV("abcde"), 0); + test(S(""), 1, 0, SV("abcdefghij"), 0); + test(S(""), 1, 0, SV("abcdefghijklmnopqrst"), 0); + test(S("abcde"), 0, 0, SV(""), 0); + test(S("abcde"), 0, 0, SV("abcde"), -5); + test(S("abcde"), 0, 0, SV("abcdefghij"), -10); + test(S("abcde"), 0, 0, SV("abcdefghijklmnopqrst"), -20); + test(S("abcde"), 0, 1, SV(""), 1); + test(S("abcde"), 0, 1, SV("abcde"), -4); + test(S("abcde"), 0, 1, SV("abcdefghij"), -9); + test(S("abcde"), 0, 1, SV("abcdefghijklmnopqrst"), -19); + test(S("abcde"), 0, 2, SV(""), 2); + test(S("abcde"), 0, 2, SV("abcde"), -3); + test(S("abcde"), 0, 2, SV("abcdefghij"), -8); + test(S("abcde"), 0, 2, SV("abcdefghijklmnopqrst"), -18); + test(S("abcde"), 0, 4, SV(""), 4); + test(S("abcde"), 0, 4, SV("abcde"), -1); + test(S("abcde"), 0, 4, SV("abcdefghij"), -6); + test(S("abcde"), 0, 4, SV("abcdefghijklmnopqrst"), -16); + test(S("abcde"), 0, 5, SV(""), 5); + test(S("abcde"), 0, 5, SV("abcde"), 0); + test(S("abcde"), 0, 5, SV("abcdefghij"), -5); + test(S("abcde"), 0, 5, SV("abcdefghijklmnopqrst"), -15); + test(S("abcde"), 0, 6, SV(""), 5); + test(S("abcde"), 0, 6, SV("abcde"), 0); + test(S("abcde"), 0, 6, SV("abcdefghij"), -5); + test(S("abcde"), 0, 6, SV("abcdefghijklmnopqrst"), -15); + test(S("abcde"), 1, 0, SV(""), 0); + test(S("abcde"), 1, 0, SV("abcde"), -5); + test(S("abcde"), 1, 0, SV("abcdefghij"), -10); + test(S("abcde"), 1, 0, SV("abcdefghijklmnopqrst"), -20); + test(S("abcde"), 1, 1, SV(""), 1); + test(S("abcde"), 1, 1, SV("abcde"), 1); + test(S("abcde"), 1, 1, SV("abcdefghij"), 1); + test(S("abcde"), 1, 1, SV("abcdefghijklmnopqrst"), 1); + test(S("abcde"), 1, 2, SV(""), 2); + test(S("abcde"), 1, 2, SV("abcde"), 1); + test(S("abcde"), 1, 2, SV("abcdefghij"), 1); + test(S("abcde"), 1, 2, SV("abcdefghijklmnopqrst"), 1); + test(S("abcde"), 1, 3, SV(""), 3); + test(S("abcde"), 1, 3, SV("abcde"), 1); + test(S("abcde"), 1, 3, SV("abcdefghij"), 1); + test(S("abcde"), 1, 3, SV("abcdefghijklmnopqrst"), 1); + test(S("abcde"), 1, 4, SV(""), 4); + test(S("abcde"), 1, 4, SV("abcde"), 1); + test(S("abcde"), 1, 4, SV("abcdefghij"), 1); + test(S("abcde"), 1, 4, SV("abcdefghijklmnopqrst"), 1); + test(S("abcde"), 1, 5, SV(""), 4); + test(S("abcde"), 1, 5, SV("abcde"), 1); + test(S("abcde"), 1, 5, SV("abcdefghij"), 1); + test(S("abcde"), 1, 5, SV("abcdefghijklmnopqrst"), 1); + test(S("abcde"), 2, 0, SV(""), 0); + test(S("abcde"), 2, 0, SV("abcde"), -5); + test(S("abcde"), 2, 0, SV("abcdefghij"), -10); + test(S("abcde"), 2, 0, SV("abcdefghijklmnopqrst"), -20); + test(S("abcde"), 2, 1, SV(""), 1); + test(S("abcde"), 2, 1, SV("abcde"), 2); + test(S("abcde"), 2, 1, SV("abcdefghij"), 2); + test(S("abcde"), 2, 1, SV("abcdefghijklmnopqrst"), 2); + test(S("abcde"), 2, 2, SV(""), 2); + test(S("abcde"), 2, 2, SV("abcde"), 2); + test(S("abcde"), 2, 2, SV("abcdefghij"), 2); + test(S("abcde"), 2, 2, SV("abcdefghijklmnopqrst"), 2); + test(S("abcde"), 2, 3, SV(""), 3); + test(S("abcde"), 2, 3, SV("abcde"), 2); + test(S("abcde"), 2, 3, SV("abcdefghij"), 2); + test(S("abcde"), 2, 3, SV("abcdefghijklmnopqrst"), 2); + test(S("abcde"), 2, 4, SV(""), 3); + test(S("abcde"), 2, 4, SV("abcde"), 2); + test(S("abcde"), 2, 4, SV("abcdefghij"), 2); + test(S("abcde"), 2, 4, SV("abcdefghijklmnopqrst"), 2); + test(S("abcde"), 4, 0, SV(""), 0); + test(S("abcde"), 4, 0, SV("abcde"), -5); + test(S("abcde"), 4, 0, SV("abcdefghij"), -10); + test(S("abcde"), 4, 0, SV("abcdefghijklmnopqrst"), -20); + test(S("abcde"), 4, 1, SV(""), 1); + test(S("abcde"), 4, 1, SV("abcde"), 4); + test(S("abcde"), 4, 1, SV("abcdefghij"), 4); + test(S("abcde"), 4, 1, SV("abcdefghijklmnopqrst"), 4); + test(S("abcde"), 4, 2, SV(""), 1); + test(S("abcde"), 4, 2, SV("abcde"), 4); + test(S("abcde"), 4, 2, SV("abcdefghij"), 4); + test(S("abcde"), 4, 2, SV("abcdefghijklmnopqrst"), 4); + test(S("abcde"), 5, 0, SV(""), 0); + test(S("abcde"), 5, 0, SV("abcde"), -5); + test(S("abcde"), 5, 0, SV("abcdefghij"), -10); + test(S("abcde"), 5, 0, SV("abcdefghijklmnopqrst"), -20); + test(S("abcde"), 5, 1, SV(""), 0); + test(S("abcde"), 5, 1, SV("abcde"), -5); + test(S("abcde"), 5, 1, SV("abcdefghij"), -10); + test(S("abcde"), 5, 1, SV("abcdefghijklmnopqrst"), -20); +} + +template +void test1() +{ + test(S("abcde"), 6, 0, SV(""), 0); + test(S("abcde"), 6, 0, SV("abcde"), 0); + test(S("abcde"), 6, 0, SV("abcdefghij"), 0); + test(S("abcde"), 6, 0, SV("abcdefghijklmnopqrst"), 0); + test(S("abcdefghij"), 0, 0, SV(""), 0); + test(S("abcdefghij"), 0, 0, SV("abcde"), -5); + test(S("abcdefghij"), 0, 0, SV("abcdefghij"), -10); + test(S("abcdefghij"), 0, 0, SV("abcdefghijklmnopqrst"), -20); + test(S("abcdefghij"), 0, 1, SV(""), 1); + test(S("abcdefghij"), 0, 1, SV("abcde"), -4); + test(S("abcdefghij"), 0, 1, SV("abcdefghij"), -9); + test(S("abcdefghij"), 0, 1, SV("abcdefghijklmnopqrst"), -19); + test(S("abcdefghij"), 0, 5, SV(""), 5); + test(S("abcdefghij"), 0, 5, SV("abcde"), 0); + test(S("abcdefghij"), 0, 5, SV("abcdefghij"), -5); + test(S("abcdefghij"), 0, 5, SV("abcdefghijklmnopqrst"), -15); + test(S("abcdefghij"), 0, 9, SV(""), 9); + test(S("abcdefghij"), 0, 9, SV("abcde"), 4); + test(S("abcdefghij"), 0, 9, SV("abcdefghij"), -1); + test(S("abcdefghij"), 0, 9, SV("abcdefghijklmnopqrst"), -11); + test(S("abcdefghij"), 0, 10, SV(""), 10); + test(S("abcdefghij"), 0, 10, SV("abcde"), 5); + test(S("abcdefghij"), 0, 10, SV("abcdefghij"), 0); + test(S("abcdefghij"), 0, 10, SV("abcdefghijklmnopqrst"), -10); + test(S("abcdefghij"), 0, 11, SV(""), 10); + test(S("abcdefghij"), 0, 11, SV("abcde"), 5); + test(S("abcdefghij"), 0, 11, SV("abcdefghij"), 0); + test(S("abcdefghij"), 0, 11, SV("abcdefghijklmnopqrst"), -10); + test(S("abcdefghij"), 1, 0, SV(""), 0); + test(S("abcdefghij"), 1, 0, SV("abcde"), -5); + test(S("abcdefghij"), 1, 0, SV("abcdefghij"), -10); + test(S("abcdefghij"), 1, 0, SV("abcdefghijklmnopqrst"), -20); + test(S("abcdefghij"), 1, 1, SV(""), 1); + test(S("abcdefghij"), 1, 1, SV("abcde"), 1); + test(S("abcdefghij"), 1, 1, SV("abcdefghij"), 1); + test(S("abcdefghij"), 1, 1, SV("abcdefghijklmnopqrst"), 1); + test(S("abcdefghij"), 1, 4, SV(""), 4); + test(S("abcdefghij"), 1, 4, SV("abcde"), 1); + test(S("abcdefghij"), 1, 4, SV("abcdefghij"), 1); + test(S("abcdefghij"), 1, 4, SV("abcdefghijklmnopqrst"), 1); + test(S("abcdefghij"), 1, 8, SV(""), 8); + test(S("abcdefghij"), 1, 8, SV("abcde"), 1); + test(S("abcdefghij"), 1, 8, SV("abcdefghij"), 1); + test(S("abcdefghij"), 1, 8, SV("abcdefghijklmnopqrst"), 1); + test(S("abcdefghij"), 1, 9, SV(""), 9); + test(S("abcdefghij"), 1, 9, SV("abcde"), 1); + test(S("abcdefghij"), 1, 9, SV("abcdefghij"), 1); + test(S("abcdefghij"), 1, 9, SV("abcdefghijklmnopqrst"), 1); + test(S("abcdefghij"), 1, 10, SV(""), 9); + test(S("abcdefghij"), 1, 10, SV("abcde"), 1); + test(S("abcdefghij"), 1, 10, SV("abcdefghij"), 1); + test(S("abcdefghij"), 1, 10, SV("abcdefghijklmnopqrst"), 1); + test(S("abcdefghij"), 5, 0, SV(""), 0); + test(S("abcdefghij"), 5, 0, SV("abcde"), -5); + test(S("abcdefghij"), 5, 0, SV("abcdefghij"), -10); + test(S("abcdefghij"), 5, 0, SV("abcdefghijklmnopqrst"), -20); + test(S("abcdefghij"), 5, 1, SV(""), 1); + test(S("abcdefghij"), 5, 1, SV("abcde"), 5); + test(S("abcdefghij"), 5, 1, SV("abcdefghij"), 5); + test(S("abcdefghij"), 5, 1, SV("abcdefghijklmnopqrst"), 5); + test(S("abcdefghij"), 5, 2, SV(""), 2); + test(S("abcdefghij"), 5, 2, SV("abcde"), 5); + test(S("abcdefghij"), 5, 2, SV("abcdefghij"), 5); + test(S("abcdefghij"), 5, 2, SV("abcdefghijklmnopqrst"), 5); + test(S("abcdefghij"), 5, 4, SV(""), 4); + test(S("abcdefghij"), 5, 4, SV("abcde"), 5); + test(S("abcdefghij"), 5, 4, SV("abcdefghij"), 5); + test(S("abcdefghij"), 5, 4, SV("abcdefghijklmnopqrst"), 5); + test(S("abcdefghij"), 5, 5, SV(""), 5); + test(S("abcdefghij"), 5, 5, SV("abcde"), 5); + test(S("abcdefghij"), 5, 5, SV("abcdefghij"), 5); + test(S("abcdefghij"), 5, 5, SV("abcdefghijklmnopqrst"), 5); + test(S("abcdefghij"), 5, 6, SV(""), 5); + test(S("abcdefghij"), 5, 6, SV("abcde"), 5); + test(S("abcdefghij"), 5, 6, SV("abcdefghij"), 5); + test(S("abcdefghij"), 5, 6, SV("abcdefghijklmnopqrst"), 5); + test(S("abcdefghij"), 9, 0, SV(""), 0); + test(S("abcdefghij"), 9, 0, SV("abcde"), -5); + test(S("abcdefghij"), 9, 0, SV("abcdefghij"), -10); + test(S("abcdefghij"), 9, 0, SV("abcdefghijklmnopqrst"), -20); + test(S("abcdefghij"), 9, 1, SV(""), 1); + test(S("abcdefghij"), 9, 1, SV("abcde"), 9); + test(S("abcdefghij"), 9, 1, SV("abcdefghij"), 9); + test(S("abcdefghij"), 9, 1, SV("abcdefghijklmnopqrst"), 9); + test(S("abcdefghij"), 9, 2, SV(""), 1); + test(S("abcdefghij"), 9, 2, SV("abcde"), 9); + test(S("abcdefghij"), 9, 2, SV("abcdefghij"), 9); + test(S("abcdefghij"), 9, 2, SV("abcdefghijklmnopqrst"), 9); + test(S("abcdefghij"), 10, 0, SV(""), 0); + test(S("abcdefghij"), 10, 0, SV("abcde"), -5); + test(S("abcdefghij"), 10, 0, SV("abcdefghij"), -10); + test(S("abcdefghij"), 10, 0, SV("abcdefghijklmnopqrst"), -20); + test(S("abcdefghij"), 10, 1, SV(""), 0); + test(S("abcdefghij"), 10, 1, SV("abcde"), -5); + test(S("abcdefghij"), 10, 1, SV("abcdefghij"), -10); + test(S("abcdefghij"), 10, 1, SV("abcdefghijklmnopqrst"), -20); + test(S("abcdefghij"), 11, 0, SV(""), 0); + test(S("abcdefghij"), 11, 0, SV("abcde"), 0); + test(S("abcdefghij"), 11, 0, SV("abcdefghij"), 0); + test(S("abcdefghij"), 11, 0, SV("abcdefghijklmnopqrst"), 0); +} + +template +void test2() +{ + test(S("abcdefghijklmnopqrst"), 0, 0, SV(""), 0); + test(S("abcdefghijklmnopqrst"), 0, 0, SV("abcde"), -5); + test(S("abcdefghijklmnopqrst"), 0, 0, SV("abcdefghij"), -10); + test(S("abcdefghijklmnopqrst"), 0, 0, SV("abcdefghijklmnopqrst"), -20); + test(S("abcdefghijklmnopqrst"), 0, 1, SV(""), 1); + test(S("abcdefghijklmnopqrst"), 0, 1, SV("abcde"), -4); + test(S("abcdefghijklmnopqrst"), 0, 1, SV("abcdefghij"), -9); + test(S("abcdefghijklmnopqrst"), 0, 1, SV("abcdefghijklmnopqrst"), -19); + test(S("abcdefghijklmnopqrst"), 0, 10, SV(""), 10); + test(S("abcdefghijklmnopqrst"), 0, 10, SV("abcde"), 5); + test(S("abcdefghijklmnopqrst"), 0, 10, SV("abcdefghij"), 0); + test(S("abcdefghijklmnopqrst"), 0, 10, SV("abcdefghijklmnopqrst"), -10); + test(S("abcdefghijklmnopqrst"), 0, 19, SV(""), 19); + test(S("abcdefghijklmnopqrst"), 0, 19, SV("abcde"), 14); + test(S("abcdefghijklmnopqrst"), 0, 19, SV("abcdefghij"), 9); + test(S("abcdefghijklmnopqrst"), 0, 19, SV("abcdefghijklmnopqrst"), -1); + test(S("abcdefghijklmnopqrst"), 0, 20, SV(""), 20); + test(S("abcdefghijklmnopqrst"), 0, 20, SV("abcde"), 15); + test(S("abcdefghijklmnopqrst"), 0, 20, SV("abcdefghij"), 10); + test(S("abcdefghijklmnopqrst"), 0, 20, SV("abcdefghijklmnopqrst"), 0); + test(S("abcdefghijklmnopqrst"), 0, 21, SV(""), 20); + test(S("abcdefghijklmnopqrst"), 0, 21, SV("abcde"), 15); + test(S("abcdefghijklmnopqrst"), 0, 21, SV("abcdefghij"), 10); + test(S("abcdefghijklmnopqrst"), 0, 21, SV("abcdefghijklmnopqrst"), 0); + test(S("abcdefghijklmnopqrst"), 1, 0, SV(""), 0); + test(S("abcdefghijklmnopqrst"), 1, 0, SV("abcde"), -5); + test(S("abcdefghijklmnopqrst"), 1, 0, SV("abcdefghij"), -10); + test(S("abcdefghijklmnopqrst"), 1, 0, SV("abcdefghijklmnopqrst"), -20); + test(S("abcdefghijklmnopqrst"), 1, 1, SV(""), 1); + test(S("abcdefghijklmnopqrst"), 1, 1, SV("abcde"), 1); + test(S("abcdefghijklmnopqrst"), 1, 1, SV("abcdefghij"), 1); + test(S("abcdefghijklmnopqrst"), 1, 1, SV("abcdefghijklmnopqrst"), 1); + test(S("abcdefghijklmnopqrst"), 1, 9, SV(""), 9); + test(S("abcdefghijklmnopqrst"), 1, 9, SV("abcde"), 1); + test(S("abcdefghijklmnopqrst"), 1, 9, SV("abcdefghij"), 1); + test(S("abcdefghijklmnopqrst"), 1, 9, SV("abcdefghijklmnopqrst"), 1); + test(S("abcdefghijklmnopqrst"), 1, 18, SV(""), 18); + test(S("abcdefghijklmnopqrst"), 1, 18, SV("abcde"), 1); + test(S("abcdefghijklmnopqrst"), 1, 18, SV("abcdefghij"), 1); + test(S("abcdefghijklmnopqrst"), 1, 18, SV("abcdefghijklmnopqrst"), 1); + test(S("abcdefghijklmnopqrst"), 1, 19, SV(""), 19); + test(S("abcdefghijklmnopqrst"), 1, 19, SV("abcde"), 1); + test(S("abcdefghijklmnopqrst"), 1, 19, SV("abcdefghij"), 1); + test(S("abcdefghijklmnopqrst"), 1, 19, SV("abcdefghijklmnopqrst"), 1); + test(S("abcdefghijklmnopqrst"), 1, 20, SV(""), 19); + test(S("abcdefghijklmnopqrst"), 1, 20, SV("abcde"), 1); + test(S("abcdefghijklmnopqrst"), 1, 20, SV("abcdefghij"), 1); + test(S("abcdefghijklmnopqrst"), 1, 20, SV("abcdefghijklmnopqrst"), 1); + test(S("abcdefghijklmnopqrst"), 10, 0, SV(""), 0); + test(S("abcdefghijklmnopqrst"), 10, 0, SV("abcde"), -5); + test(S("abcdefghijklmnopqrst"), 10, 0, SV("abcdefghij"), -10); + test(S("abcdefghijklmnopqrst"), 10, 0, SV("abcdefghijklmnopqrst"), -20); + test(S("abcdefghijklmnopqrst"), 10, 1, SV(""), 1); + test(S("abcdefghijklmnopqrst"), 10, 1, SV("abcde"), 10); + test(S("abcdefghijklmnopqrst"), 10, 1, SV("abcdefghij"), 10); + test(S("abcdefghijklmnopqrst"), 10, 1, SV("abcdefghijklmnopqrst"), 10); + test(S("abcdefghijklmnopqrst"), 10, 5, SV(""), 5); + test(S("abcdefghijklmnopqrst"), 10, 5, SV("abcde"), 10); + test(S("abcdefghijklmnopqrst"), 10, 5, SV("abcdefghij"), 10); + test(S("abcdefghijklmnopqrst"), 10, 5, SV("abcdefghijklmnopqrst"), 10); + test(S("abcdefghijklmnopqrst"), 10, 9, SV(""), 9); + test(S("abcdefghijklmnopqrst"), 10, 9, SV("abcde"), 10); + test(S("abcdefghijklmnopqrst"), 10, 9, SV("abcdefghij"), 10); + test(S("abcdefghijklmnopqrst"), 10, 9, SV("abcdefghijklmnopqrst"), 10); + test(S("abcdefghijklmnopqrst"), 10, 10, SV(""), 10); + test(S("abcdefghijklmnopqrst"), 10, 10, SV("abcde"), 10); + test(S("abcdefghijklmnopqrst"), 10, 10, SV("abcdefghij"), 10); + test(S("abcdefghijklmnopqrst"), 10, 10, SV("abcdefghijklmnopqrst"), 10); + test(S("abcdefghijklmnopqrst"), 10, 11, SV(""), 10); + test(S("abcdefghijklmnopqrst"), 10, 11, SV("abcde"), 10); + test(S("abcdefghijklmnopqrst"), 10, 11, SV("abcdefghij"), 10); + test(S("abcdefghijklmnopqrst"), 10, 11, SV("abcdefghijklmnopqrst"), 10); + test(S("abcdefghijklmnopqrst"), 19, 0, SV(""), 0); + test(S("abcdefghijklmnopqrst"), 19, 0, SV("abcde"), -5); + test(S("abcdefghijklmnopqrst"), 19, 0, SV("abcdefghij"), -10); + test(S("abcdefghijklmnopqrst"), 19, 0, SV("abcdefghijklmnopqrst"), -20); + test(S("abcdefghijklmnopqrst"), 19, 1, SV(""), 1); + test(S("abcdefghijklmnopqrst"), 19, 1, SV("abcde"), 19); + test(S("abcdefghijklmnopqrst"), 19, 1, SV("abcdefghij"), 19); + test(S("abcdefghijklmnopqrst"), 19, 1, SV("abcdefghijklmnopqrst"), 19); + test(S("abcdefghijklmnopqrst"), 19, 2, SV(""), 1); + test(S("abcdefghijklmnopqrst"), 19, 2, SV("abcde"), 19); + test(S("abcdefghijklmnopqrst"), 19, 2, SV("abcdefghij"), 19); + test(S("abcdefghijklmnopqrst"), 19, 2, SV("abcdefghijklmnopqrst"), 19); + test(S("abcdefghijklmnopqrst"), 20, 0, SV(""), 0); + test(S("abcdefghijklmnopqrst"), 20, 0, SV("abcde"), -5); + test(S("abcdefghijklmnopqrst"), 20, 0, SV("abcdefghij"), -10); + test(S("abcdefghijklmnopqrst"), 20, 0, SV("abcdefghijklmnopqrst"), -20); + test(S("abcdefghijklmnopqrst"), 20, 1, SV(""), 0); + test(S("abcdefghijklmnopqrst"), 20, 1, SV("abcde"), -5); + test(S("abcdefghijklmnopqrst"), 20, 1, SV("abcdefghij"), -10); + test(S("abcdefghijklmnopqrst"), 20, 1, SV("abcdefghijklmnopqrst"), -20); + test(S("abcdefghijklmnopqrst"), 21, 0, SV(""), 0); + test(S("abcdefghijklmnopqrst"), 21, 0, SV("abcde"), 0); + test(S("abcdefghijklmnopqrst"), 21, 0, SV("abcdefghij"), 0); + test(S("abcdefghijklmnopqrst"), 21, 0, SV("abcdefghijklmnopqrst"), 0); +} + +int main() +{ + { + typedef std::string S; + typedef std::string_view SV; + test0(); + test1(); + test2(); + } +#if TEST_STD_VER >= 11 + { + typedef std::basic_string, min_allocator> S; + typedef std::string_view SV; + test0(); + test1(); + test2(); + } +#endif +} diff --git a/tests/external/libcxx/basic_string/string.ops/string_compare/string.pass.cpp b/tests/external/libcxx/basic_string/string.ops/string_compare/string.pass.cpp new file mode 100644 index 0000000..034f2b6 --- /dev/null +++ b/tests/external/libcxx/basic_string/string.ops/string_compare/string.pass.cpp @@ -0,0 +1,116 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// Copyright 2019, Intel Corporation +// +// Modified to test pmem::obj containers +// + +#include "unittest.hpp" + +#include +#include +#include +#include +#include + +namespace pmem_exp = pmem::obj::experimental; +namespace nvobj = pmem::obj; + +struct root { + nvobj::persistent_ptr s1, s2, s3, s4; +}; + +int +sign(int x) +{ + if (x == 0) + return 0; + if (x < 0) + return -1; + return 1; +} + +template +void +test(const S &s, const S &str, int x) +{ + UT_ASSERT(sign(s.compare(str)) == sign(x)); +} + +void +run(pmem::obj::pool &pop) +{ + auto r = pop.root(); + + try { + nvobj::transaction::run(pop, [&] { + r->s1 = nvobj::make_persistent(""); + r->s2 = nvobj::make_persistent( + "abcde"); + r->s3 = nvobj::make_persistent( + "abcdefghij"); + r->s4 = nvobj::make_persistent( + "abcdefghijklmnopqrst"); + }); + + test(*r->s1, *r->s1, 0); + test(*r->s1, *r->s2, -5); + test(*r->s1, *r->s3, -10); + test(*r->s1, *r->s4, -20); + test(*r->s2, *r->s1, 5); + test(*r->s2, *r->s2, 0); + test(*r->s2, *r->s3, -5); + test(*r->s2, *r->s4, -15); + test(*r->s3, *r->s1, 10); + test(*r->s3, *r->s2, 5); + test(*r->s3, *r->s3, 0); + test(*r->s3, *r->s4, -10); + test(*r->s4, *r->s1, 20); + test(*r->s4, *r->s2, 15); + test(*r->s4, *r->s3, 10); + test(*r->s4, *r->s4, 0); + + nvobj::transaction::run(pop, [&] { + nvobj::delete_persistent(r->s1); + nvobj::delete_persistent(r->s2); + nvobj::delete_persistent(r->s3); + nvobj::delete_persistent(r->s4); + }); + } catch (std::exception &e) { + UT_FATALexc(e); + } +} + +int +main(int argc, char *argv[]) +{ + START(); + + if (argc != 2) + UT_FATAL("usage: %s file-name", argv[0]); + + const char *path = argv[1]; + + pmem::obj::pool pop; + + try { + pop = pmem::obj::pool::create(path, "basic_string", + PMEMOBJ_MIN_POOL, + S_IWUSR | S_IRUSR); + } catch (...) { + UT_FATAL("!pmemobj_create: %s", path); + } + + run(pop); + + pop.close(); + + return 0; +} diff --git a/tests/external/libcxx/basic_string/string.ops/string_compare/string_view.pass.cpp b/tests/external/libcxx/basic_string/string.ops/string_compare/string_view.pass.cpp new file mode 100644 index 0000000..8f0d488 --- /dev/null +++ b/tests/external/libcxx/basic_string/string.ops/string_compare/string_view.pass.cpp @@ -0,0 +1,79 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// + +// int compare(const basic_string_view sv) const + +#include +#include + +#include "min_allocator.h" + +int sign(int x) +{ + if (x == 0) + return 0; + if (x < 0) + return -1; + return 1; +} + +template +void +test(const S& s, SV sv, int x) +{ + assert(sign(s.compare(sv)) == sign(x)); +} + +int main() +{ + { + typedef std::string S; + typedef std::string_view SV; + test(S(""), SV(""), 0); + test(S(""), SV("abcde"), -5); + test(S(""), SV("abcdefghij"), -10); + test(S(""), SV("abcdefghijklmnopqrst"), -20); + test(S("abcde"), SV(""), 5); + test(S("abcde"), SV("abcde"), 0); + test(S("abcde"), SV("abcdefghij"), -5); + test(S("abcde"), SV("abcdefghijklmnopqrst"), -15); + test(S("abcdefghij"), SV(""), 10); + test(S("abcdefghij"), SV("abcde"), 5); + test(S("abcdefghij"), SV("abcdefghij"), 0); + test(S("abcdefghij"), SV("abcdefghijklmnopqrst"), -10); + test(S("abcdefghijklmnopqrst"), SV(""), 20); + test(S("abcdefghijklmnopqrst"), SV("abcde"), 15); + test(S("abcdefghijklmnopqrst"), SV("abcdefghij"), 10); + test(S("abcdefghijklmnopqrst"), SV("abcdefghijklmnopqrst"), 0); + } +#if TEST_STD_VER >= 11 + { + typedef std::basic_string, min_allocator> S; + typedef std::string_view SV; + test(S(""), SV(""), 0); + test(S(""), SV("abcde"), -5); + test(S(""), SV("abcdefghij"), -10); + test(S(""), SV("abcdefghijklmnopqrst"), -20); + test(S("abcde"), SV(""), 5); + test(S("abcde"), SV("abcde"), 0); + test(S("abcde"), SV("abcdefghij"), -5); + test(S("abcde"), SV("abcdefghijklmnopqrst"), -15); + test(S("abcdefghij"), SV(""), 10); + test(S("abcdefghij"), SV("abcde"), 5); + test(S("abcdefghij"), SV("abcdefghij"), 0); + test(S("abcdefghij"), SV("abcdefghijklmnopqrst"), -10); + test(S("abcdefghijklmnopqrst"), SV(""), 20); + test(S("abcdefghijklmnopqrst"), SV("abcde"), 15); + test(S("abcdefghijklmnopqrst"), SV("abcdefghij"), 10); + test(S("abcdefghijklmnopqrst"), SV("abcdefghijklmnopqrst"), 0); + } +#endif +} diff --git a/tests/external/libcxx/basic_string/string.ops/string_find.first.not.of/char_size.pass.cpp b/tests/external/libcxx/basic_string/string.ops/string_find.first.not.of/char_size.pass.cpp new file mode 100644 index 0000000..945f880 --- /dev/null +++ b/tests/external/libcxx/basic_string/string.ops/string_find.first.not.of/char_size.pass.cpp @@ -0,0 +1,102 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// + +// size_type find_first_not_of(charT c, size_type pos = 0) const; + +#include +#include + +#include "min_allocator.h" + +template +void +test(const S& s, typename S::value_type c, typename S::size_type pos, + typename S::size_type x) +{ + assert(s.find_first_not_of(c, pos) == x); + if (x != S::npos) + assert(pos <= x && x < s.size()); +} + +template +void +test(const S& s, typename S::value_type c, typename S::size_type x) +{ + assert(s.find_first_not_of(c) == x); + if (x != S::npos) + assert(x < s.size()); +} + +int main() +{ + { + typedef std::string S; + test(S(""), 'q', 0, S::npos); + test(S(""), 'q', 1, S::npos); + test(S("kitcj"), 'q', 0, 0); + test(S("qkamf"), 'q', 1, 1); + test(S("nhmko"), 'q', 2, 2); + test(S("tpsaf"), 'q', 4, 4); + test(S("lahfb"), 'q', 5, S::npos); + test(S("irkhs"), 'q', 6, S::npos); + test(S("gmfhdaipsr"), 'q', 0, 0); + test(S("kantesmpgj"), 'q', 1, 1); + test(S("odaftiegpm"), 'q', 5, 5); + test(S("oknlrstdpi"), 'q', 9, 9); + test(S("eolhfgpjqk"), 'q', 10, S::npos); + test(S("pcdrofikas"), 'q', 11, S::npos); + test(S("nbatdlmekrgcfqsophij"), 'q', 0, 0); + test(S("bnrpehidofmqtcksjgla"), 'q', 1, 1); + test(S("jdmciepkaqgotsrfnhlb"), 'q', 10, 10); + test(S("jtdaefblsokrmhpgcnqi"), 'q', 19, 19); + test(S("hkbgspofltajcnedqmri"), 'q', 20, S::npos); + test(S("oselktgbcapndfjihrmq"), 'q', 21, S::npos); + + test(S(""), 'q', S::npos); + test(S("q"), 'q', S::npos); + test(S("qqq"), 'q', S::npos); + test(S("csope"), 'q', 0); + test(S("gfsmthlkon"), 'q', 0); + test(S("laenfsbridchgotmkqpj"), 'q', 0); + } +#if TEST_STD_VER >= 11 + { + typedef std::basic_string, min_allocator> S; + test(S(""), 'q', 0, S::npos); + test(S(""), 'q', 1, S::npos); + test(S("kitcj"), 'q', 0, 0); + test(S("qkamf"), 'q', 1, 1); + test(S("nhmko"), 'q', 2, 2); + test(S("tpsaf"), 'q', 4, 4); + test(S("lahfb"), 'q', 5, S::npos); + test(S("irkhs"), 'q', 6, S::npos); + test(S("gmfhdaipsr"), 'q', 0, 0); + test(S("kantesmpgj"), 'q', 1, 1); + test(S("odaftiegpm"), 'q', 5, 5); + test(S("oknlrstdpi"), 'q', 9, 9); + test(S("eolhfgpjqk"), 'q', 10, S::npos); + test(S("pcdrofikas"), 'q', 11, S::npos); + test(S("nbatdlmekrgcfqsophij"), 'q', 0, 0); + test(S("bnrpehidofmqtcksjgla"), 'q', 1, 1); + test(S("jdmciepkaqgotsrfnhlb"), 'q', 10, 10); + test(S("jtdaefblsokrmhpgcnqi"), 'q', 19, 19); + test(S("hkbgspofltajcnedqmri"), 'q', 20, S::npos); + test(S("oselktgbcapndfjihrmq"), 'q', 21, S::npos); + + test(S(""), 'q', S::npos); + test(S("q"), 'q', S::npos); + test(S("qqq"), 'q', S::npos); + test(S("csope"), 'q', 0); + test(S("gfsmthlkon"), 'q', 0); + test(S("laenfsbridchgotmkqpj"), 'q', 0); + } +#endif +} diff --git a/tests/external/libcxx/basic_string/string.ops/string_find.first.not.of/pointer_size.pass.cpp b/tests/external/libcxx/basic_string/string.ops/string_find.first.not.of/pointer_size.pass.cpp new file mode 100644 index 0000000..0c239b3 --- /dev/null +++ b/tests/external/libcxx/basic_string/string.ops/string_find.first.not.of/pointer_size.pass.cpp @@ -0,0 +1,158 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// + +// size_type find_first_not_of(const charT* s, size_type pos = 0) const; + +#include +#include + +#include "min_allocator.h" + +template +void +test(const S& s, const typename S::value_type* str, typename S::size_type pos, + typename S::size_type x) +{ + assert(s.find_first_not_of(str, pos) == x); + if (x != S::npos) + assert(pos <= x && x < s.size()); +} + +template +void +test(const S& s, const typename S::value_type* str, typename S::size_type x) +{ + assert(s.find_first_not_of(str) == x); + if (x != S::npos) + assert(x < s.size()); +} + +template +void test0() +{ + test(S(""), "", 0, S::npos); + test(S(""), "laenf", 0, S::npos); + test(S(""), "pqlnkmbdjo", 0, S::npos); + test(S(""), "qkamfogpnljdcshbreti", 0, S::npos); + test(S(""), "", 1, S::npos); + test(S(""), "bjaht", 1, S::npos); + test(S(""), "hjlcmgpket", 1, S::npos); + test(S(""), "htaobedqikfplcgjsmrn", 1, S::npos); + test(S("fodgq"), "", 0, 0); + test(S("qanej"), "dfkap", 0, 0); + test(S("clbao"), "ihqrfebgad", 0, 0); + test(S("mekdn"), "ngtjfcalbseiqrphmkdo", 0, S::npos); + test(S("srdfq"), "", 1, 1); + test(S("oemth"), "ikcrq", 1, 1); + test(S("cdaih"), "dmajblfhsg", 1, 3); + test(S("qohtk"), "oqftjhdmkgsblacenirp", 1, S::npos); + test(S("cshmd"), "", 2, 2); + test(S("lhcdo"), "oebqi", 2, 2); + test(S("qnsoh"), "kojhpmbsfe", 2, S::npos); + test(S("pkrof"), "acbsjqogpltdkhinfrem", 2, S::npos); + test(S("fmtsp"), "", 4, 4); + test(S("khbpm"), "aobjd", 4, 4); + test(S("pbsji"), "pcbahntsje", 4, 4); + test(S("mprdj"), "fhepcrntkoagbmldqijs", 4, S::npos); + test(S("eqmpa"), "", 5, S::npos); + test(S("omigs"), "kocgb", 5, S::npos); + test(S("onmje"), "fbslrjiqkm", 5, S::npos); + test(S("oqmrj"), "jeidpcmalhfnqbgtrsko", 5, S::npos); + test(S("schfa"), "", 6, S::npos); + test(S("igdsc"), "qngpd", 6, S::npos); + test(S("brqgo"), "rodhqklgmb", 6, S::npos); + test(S("tnrph"), "thdjgafrlbkoiqcspmne", 6, S::npos); + test(S("hcjitbfapl"), "", 0, 0); + test(S("daiprenocl"), "ashjd", 0, 2); + test(S("litpcfdghe"), "mgojkldsqh", 0, 1); + test(S("aidjksrolc"), "imqnaghkfrdtlopbjesc", 0, S::npos); + test(S("qpghtfbaji"), "", 1, 1); + test(S("gfshlcmdjr"), "nadkh", 1, 1); + test(S("nkodajteqp"), "ofdrqmkebl", 1, 4); + test(S("gbmetiprqd"), "bdfjqgatlksriohemnpc", 1, S::npos); + test(S("crnklpmegd"), "", 5, 5); + test(S("jsbtafedoc"), "prqgn", 5, 5); + test(S("qnmodrtkeb"), "pejafmnokr", 5, 6); + test(S("cpebqsfmnj"), "odnqkgijrhabfmcestlp", 5, S::npos); + test(S("lmofqdhpki"), "", 9, 9); + test(S("hnefkqimca"), "rtjpa", 9, S::npos); + test(S("drtasbgmfp"), "ktsrmnqagd", 9, 9); + test(S("lsaijeqhtr"), "rtdhgcisbnmoaqkfpjle", 9, S::npos); + test(S("elgofjmbrq"), "", 10, S::npos); + test(S("mjqdgalkpc"), "dplqa", 10, S::npos); + test(S("kthqnfcerm"), "dkacjoptns", 10, S::npos); + test(S("dfsjhanorc"), "hqfimtrgnbekpdcsjalo", 10, S::npos); + test(S("eqsgalomhb"), "", 11, S::npos); + test(S("akiteljmoh"), "lofbc", 11, S::npos); + test(S("hlbdfreqjo"), "astoegbfpn", 11, S::npos); + test(S("taqobhlerg"), "pdgreqomsncafklhtibj", 11, S::npos); + test(S("snafbdlghrjkpqtoceim"), "", 0, 0); + test(S("aemtbrgcklhndjisfpoq"), "lbtqd", 0, 0); + test(S("pnracgfkjdiholtbqsem"), "tboimldpjh", 0, 1); + test(S("dicfltehbsgrmojnpkaq"), "slcerthdaiqjfnobgkpm", 0, S::npos); + test(S("jlnkraeodhcspfgbqitm"), "", 1, 1); + test(S("lhosrngtmfjikbqpcade"), "aqibs", 1, 1); + test(S("rbtaqjhgkneisldpmfoc"), "gtfblmqinc", 1, 3); + test(S("gpifsqlrdkbonjtmheca"), "mkqpbtdalgniorhfescj", 1, S::npos); + test(S("hdpkobnsalmcfijregtq"), "", 10, 10); + test(S("jtlshdgqaiprkbcoenfm"), "pblas", 10, 11); + test(S("fkdrbqltsgmcoiphneaj"), "arosdhcfme", 10, 13); + test(S("crsplifgtqedjohnabmk"), "blkhjeogicatqfnpdmsr", 10, S::npos); + test(S("niptglfbosehkamrdqcj"), "", 19, 19); + test(S("copqdhstbingamjfkler"), "djkqc", 19, 19); + test(S("mrtaefilpdsgocnhqbjk"), "lgokshjtpb", 19, S::npos); + test(S("kojatdhlcmigpbfrqnes"), "bqjhtkfepimcnsgrlado", 19, S::npos); + test(S("eaintpchlqsbdgrkjofm"), "", 20, S::npos); + test(S("gjnhidfsepkrtaqbmclo"), "nocfa", 20, S::npos); + test(S("spocfaktqdbiejlhngmr"), "bgtajmiedc", 20, S::npos); + test(S("rphmlekgfscndtaobiqj"), "lsckfnqgdahejiopbtmr", 20, S::npos); + test(S("liatsqdoegkmfcnbhrpj"), "", 21, S::npos); + test(S("binjagtfldkrspcomqeh"), "gfsrt", 21, S::npos); + test(S("latkmisecnorjbfhqpdg"), "pfsocbhjtm", 21, S::npos); + test(S("lecfratdjkhnsmqpoigb"), "tpflmdnoicjgkberhqsa", 21, S::npos); +} + +template +void test1() +{ + test(S(""), "", S::npos); + test(S(""), "laenf", S::npos); + test(S(""), "pqlnkmbdjo", S::npos); + test(S(""), "qkamfogpnljdcshbreti", S::npos); + test(S("nhmko"), "", 0); + test(S("lahfb"), "irkhs", 0); + test(S("gmfhd"), "kantesmpgj", 2); + test(S("odaft"), "oknlrstdpiqmjbaghcfe", S::npos); + test(S("eolhfgpjqk"), "", 0); + test(S("nbatdlmekr"), "bnrpe", 2); + test(S("jdmciepkaq"), "jtdaefblso", 2); + test(S("hkbgspoflt"), "oselktgbcapndfjihrmq", S::npos); + test(S("gprdcokbnjhlsfmtieqa"), "", 0); + test(S("qjghlnftcaismkropdeb"), "bjaht", 0); + test(S("pnalfrdtkqcmojiesbhg"), "hjlcmgpket", 1); + test(S("pniotcfrhqsmgdkjbael"), "htaobedqikfplcgjsmrn", S::npos); +} + +int main() +{ + { + typedef std::string S; + test0(); + test1(); + } +#if TEST_STD_VER >= 11 + { + typedef std::basic_string, min_allocator> S; + test0(); + test1(); + } +#endif +} diff --git a/tests/external/libcxx/basic_string/string.ops/string_find.first.not.of/pointer_size_size.pass.cpp b/tests/external/libcxx/basic_string/string.ops/string_find.first.not.of/pointer_size_size.pass.cpp new file mode 100644 index 0000000..0296e2c --- /dev/null +++ b/tests/external/libcxx/basic_string/string.ops/string_find.first.not.of/pointer_size_size.pass.cpp @@ -0,0 +1,387 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// + +// size_type find_first_not_of(const charT* s, size_type pos, size_type n) const; + +#include +#include + +#include "min_allocator.h" + +template +void +test(const S& s, const typename S::value_type* str, typename S::size_type pos, + typename S::size_type n, typename S::size_type x) +{ + assert(s.find_first_not_of(str, pos, n) == x); + if (x != S::npos) + assert(pos <= x && x < s.size()); +} + +template +void test0() +{ + test(S(""), "", 0, 0, S::npos); + test(S(""), "irkhs", 0, 0, S::npos); + test(S(""), "kante", 0, 1, S::npos); + test(S(""), "oknlr", 0, 2, S::npos); + test(S(""), "pcdro", 0, 4, S::npos); + test(S(""), "bnrpe", 0, 5, S::npos); + test(S(""), "jtdaefblso", 0, 0, S::npos); + test(S(""), "oselktgbca", 0, 1, S::npos); + test(S(""), "eqgaplhckj", 0, 5, S::npos); + test(S(""), "bjahtcmnlp", 0, 9, S::npos); + test(S(""), "hjlcmgpket", 0, 10, S::npos); + test(S(""), "htaobedqikfplcgjsmrn", 0, 0, S::npos); + test(S(""), "hpqiarojkcdlsgnmfetb", 0, 1, S::npos); + test(S(""), "dfkaprhjloqetcsimnbg", 0, 10, S::npos); + test(S(""), "ihqrfebgadntlpmjksoc", 0, 19, S::npos); + test(S(""), "ngtjfcalbseiqrphmkdo", 0, 20, S::npos); + test(S(""), "", 1, 0, S::npos); + test(S(""), "lbtqd", 1, 0, S::npos); + test(S(""), "tboim", 1, 1, S::npos); + test(S(""), "slcer", 1, 2, S::npos); + test(S(""), "cbjfs", 1, 4, S::npos); + test(S(""), "aqibs", 1, 5, S::npos); + test(S(""), "gtfblmqinc", 1, 0, S::npos); + test(S(""), "mkqpbtdalg", 1, 1, S::npos); + test(S(""), "kphatlimcd", 1, 5, S::npos); + test(S(""), "pblasqogic", 1, 9, S::npos); + test(S(""), "arosdhcfme", 1, 10, S::npos); + test(S(""), "blkhjeogicatqfnpdmsr", 1, 0, S::npos); + test(S(""), "bmhineprjcoadgstflqk", 1, 1, S::npos); + test(S(""), "djkqcmetslnghpbarfoi", 1, 10, S::npos); + test(S(""), "lgokshjtpbemarcdqnfi", 1, 19, S::npos); + test(S(""), "bqjhtkfepimcnsgrlado", 1, 20, S::npos); + test(S("eaint"), "", 0, 0, 0); + test(S("binja"), "gfsrt", 0, 0, 0); + test(S("latkm"), "pfsoc", 0, 1, 0); + test(S("lecfr"), "tpflm", 0, 2, 0); + test(S("eqkst"), "sgkec", 0, 4, 1); + test(S("cdafr"), "romds", 0, 5, 0); + test(S("prbhe"), "qhjistlgmr", 0, 0, 0); + test(S("lbisk"), "pedfirsglo", 0, 1, 0); + test(S("hrlpd"), "aqcoslgrmk", 0, 5, 0); + test(S("ehmja"), "dabckmepqj", 0, 9, 1); + test(S("mhqgd"), "pqscrjthli", 0, 10, 0); + test(S("tgklq"), "kfphdcsjqmobliagtren", 0, 0, 0); + test(S("bocjs"), "rokpefncljibsdhqtagm", 0, 1, 0); + test(S("grbsd"), "afionmkphlebtcjqsgrd", 0, 10, 0); + test(S("ofjqr"), "aenmqplidhkofrjbctsg", 0, 19, S::npos); + test(S("btlfi"), "osjmbtcadhiklegrpqnf", 0, 20, S::npos); + test(S("clrgb"), "", 1, 0, 1); + test(S("tjmek"), "osmia", 1, 0, 1); + test(S("bgstp"), "ckonl", 1, 1, 1); + test(S("hstrk"), "ilcaj", 1, 2, 1); + test(S("kmspj"), "lasiq", 1, 4, 1); + test(S("tjboh"), "kfqmr", 1, 5, 1); + test(S("ilbcj"), "klnitfaobg", 1, 0, 1); + test(S("jkngf"), "gjhmdlqikp", 1, 1, 1); + test(S("gfcql"), "skbgtahqej", 1, 5, 1); + test(S("dqtlg"), "bjsdgtlpkf", 1, 9, 1); + test(S("bthpg"), "bjgfmnlkio", 1, 10, 1); + test(S("dgsnq"), "lbhepotfsjdqigcnamkr", 1, 0, 1); + test(S("rmfhp"), "tebangckmpsrqdlfojhi", 1, 1, 1); + test(S("jfdam"), "joflqbdkhtegimscpanr", 1, 10, 3); + test(S("edapb"), "adpmcohetfbsrjinlqkg", 1, 19, S::npos); + test(S("brfsm"), "iacldqjpfnogbsrhmetk", 1, 20, S::npos); + test(S("ndrhl"), "", 2, 0, 2); + test(S("mrecp"), "otkgb", 2, 0, 2); + test(S("qlasf"), "cqsjl", 2, 1, 2); + test(S("smaqd"), "dpifl", 2, 2, 2); + test(S("hjeni"), "oapht", 2, 4, 2); + test(S("ocmfj"), "cifts", 2, 5, 2); + test(S("hmftq"), "nmsckbgalo", 2, 0, 2); + test(S("fklad"), "tpksqhamle", 2, 1, 2); + test(S("dirnm"), "tpdrchmkji", 2, 5, 3); + test(S("hrgdc"), "ijagfkblst", 2, 9, 3); + test(S("ifakg"), "kpocsignjb", 2, 10, 2); + test(S("ebrgd"), "pecqtkjsnbdrialgmohf", 2, 0, 2); + test(S("rcjml"), "aiortphfcmkjebgsndql", 2, 1, 2); + test(S("peqmt"), "sdbkeamglhipojqftrcn", 2, 10, 2); + test(S("frehn"), "ljqncehgmfktroapidbs", 2, 19, S::npos); + test(S("tqolf"), "rtcfodilamkbenjghqps", 2, 20, S::npos); + test(S("cjgao"), "", 4, 0, 4); + test(S("kjplq"), "mabns", 4, 0, 4); + test(S("herni"), "bdnrp", 4, 1, 4); + test(S("tadrb"), "scidp", 4, 2, 4); + test(S("pkfeo"), "agbjl", 4, 4, 4); + test(S("hoser"), "jfmpr", 4, 5, S::npos); + test(S("kgrsp"), "rbpefghsmj", 4, 0, 4); + test(S("pgejb"), "apsfntdoqc", 4, 1, 4); + test(S("thlnq"), "ndkjeisgcl", 4, 5, 4); + test(S("nbmit"), "rnfpqatdeo", 4, 9, S::npos); + test(S("jgmib"), "bntjlqrfik", 4, 10, S::npos); + test(S("ncrfj"), "kcrtmpolnaqejghsfdbi", 4, 0, 4); + test(S("ncsik"), "lobheanpkmqidsrtcfgj", 4, 1, 4); + test(S("sgbfh"), "athdkljcnreqbgpmisof", 4, 10, S::npos); + test(S("dktbn"), "qkdmjialrscpbhefgont", 4, 19, S::npos); + test(S("fthqm"), "dmasojntqleribkgfchp", 4, 20, S::npos); + test(S("klopi"), "", 5, 0, S::npos); + test(S("dajhn"), "psthd", 5, 0, S::npos); + test(S("jbgno"), "rpmjd", 5, 1, S::npos); + test(S("hkjae"), "dfsmk", 5, 2, S::npos); +} + +template +void test1() +{ + test(S("gbhqo"), "skqne", 5, 4, S::npos); + test(S("ktdor"), "kipnf", 5, 5, S::npos); + test(S("ldprn"), "hmrnqdgifl", 5, 0, S::npos); + test(S("egmjk"), "fsmjcdairn", 5, 1, S::npos); + test(S("armql"), "pcdgltbrfj", 5, 5, S::npos); + test(S("cdhjo"), "aekfctpirg", 5, 9, S::npos); + test(S("jcons"), "ledihrsgpf", 5, 10, S::npos); + test(S("cbrkp"), "mqcklahsbtirgopefndj", 5, 0, S::npos); + test(S("fhgna"), "kmlthaoqgecrnpdbjfis", 5, 1, S::npos); + test(S("ejfcd"), "sfhbamcdptojlkrenqgi", 5, 10, S::npos); + test(S("kqjhe"), "pbniofmcedrkhlstgaqj", 5, 19, S::npos); + test(S("pbdjl"), "mongjratcskbhqiepfdl", 5, 20, S::npos); + test(S("gajqn"), "", 6, 0, S::npos); + test(S("stedk"), "hrnat", 6, 0, S::npos); + test(S("tjkaf"), "gsqdt", 6, 1, S::npos); + test(S("dthpe"), "bspkd", 6, 2, S::npos); + test(S("klhde"), "ohcmb", 6, 4, S::npos); + test(S("bhlki"), "heatr", 6, 5, S::npos); + test(S("lqmoh"), "pmblckedfn", 6, 0, S::npos); + test(S("mtqin"), "aceqmsrbik", 6, 1, S::npos); + test(S("dpqbr"), "lmbtdehjrn", 6, 5, S::npos); + test(S("kdhmo"), "teqmcrlgib", 6, 9, S::npos); + test(S("jblqp"), "njolbmspac", 6, 10, S::npos); + test(S("qmjgl"), "pofnhidklamecrbqjgst", 6, 0, S::npos); + test(S("rothp"), "jbhckmtgrqnosafedpli", 6, 1, S::npos); + test(S("ghknq"), "dobntpmqklicsahgjerf", 6, 10, S::npos); + test(S("eopfi"), "tpdshainjkbfoemlrgcq", 6, 19, S::npos); + test(S("dsnmg"), "oldpfgeakrnitscbjmqh", 6, 20, S::npos); + test(S("jnkrfhotgl"), "", 0, 0, 0); + test(S("dltjfngbko"), "rqegt", 0, 0, 0); + test(S("bmjlpkiqde"), "dashm", 0, 1, 0); + test(S("skrflobnqm"), "jqirk", 0, 2, 0); + test(S("jkpldtshrm"), "rckeg", 0, 4, 0); + test(S("ghasdbnjqo"), "jscie", 0, 5, 0); + test(S("igrkhpbqjt"), "efsphndliq", 0, 0, 0); + test(S("ikthdgcamf"), "gdicosleja", 0, 1, 0); + test(S("pcofgeniam"), "qcpjibosfl", 0, 5, 2); + test(S("rlfjgesqhc"), "lrhmefnjcq", 0, 9, 4); + test(S("itphbqsker"), "dtablcrseo", 0, 10, 0); + test(S("skjafcirqm"), "apckjsftedbhgomrnilq", 0, 0, 0); + test(S("tcqomarsfd"), "pcbrgflehjtiadnsokqm", 0, 1, 0); + test(S("rocfeldqpk"), "nsiadegjklhobrmtqcpf", 0, 10, 0); + test(S("cfpegndlkt"), "cpmajdqnolikhgsbretf", 0, 19, 1); + test(S("fqbtnkeasj"), "jcflkntmgiqrphdosaeb", 0, 20, S::npos); + test(S("shbcqnmoar"), "", 1, 0, 1); + test(S("bdoshlmfin"), "ontrs", 1, 0, 1); + test(S("khfrebnsgq"), "pfkna", 1, 1, 1); + test(S("getcrsaoji"), "ekosa", 1, 2, 2); + test(S("fjiknedcpq"), "anqhk", 1, 4, 1); + test(S("tkejgnafrm"), "jekca", 1, 5, 4); + test(S("jnakolqrde"), "ikemsjgacf", 1, 0, 1); + test(S("lcjptsmgbe"), "arolgsjkhm", 1, 1, 1); + test(S("itfsmcjorl"), "oftkbldhre", 1, 5, 3); + test(S("omchkfrjea"), "gbkqdoeftl", 1, 9, 1); + test(S("cigfqkated"), "sqcflrgtim", 1, 10, 5); + test(S("tscenjikml"), "fmhbkislrjdpanogqcet", 1, 0, 1); + test(S("qcpaemsinf"), "rnioadktqlgpbcjsmhef", 1, 1, 1); + test(S("gltkojeipd"), "oakgtnldpsefihqmjcbr", 1, 10, 5); + test(S("qistfrgnmp"), "gbnaelosidmcjqktfhpr", 1, 19, 5); + test(S("bdnpfcqaem"), "akbripjhlosndcmqgfet", 1, 20, S::npos); + test(S("ectnhskflp"), "", 5, 0, 5); + test(S("fgtianblpq"), "pijag", 5, 0, 5); + test(S("mfeqklirnh"), "jrckd", 5, 1, 5); + test(S("astedncjhk"), "qcloh", 5, 2, 5); + test(S("fhlqgcajbr"), "thlmp", 5, 4, 5); + test(S("epfhocmdng"), "qidmo", 5, 5, 5); + test(S("apcnsibger"), "lnegpsjqrd", 5, 0, 5); + test(S("aqkocrbign"), "rjqdablmfs", 5, 1, 6); + test(S("ijsmdtqgce"), "enkgpbsjaq", 5, 5, 5); + test(S("clobgsrken"), "kdsgoaijfh", 5, 9, 6); + test(S("jbhcfposld"), "trfqgmckbe", 5, 10, 5); + test(S("oqnpblhide"), "igetsracjfkdnpoblhqm", 5, 0, 5); + test(S("lroeasctif"), "nqctfaogirshlekbdjpm", 5, 1, 5); + test(S("bpjlgmiedh"), "csehfgomljdqinbartkp", 5, 10, 6); + test(S("pamkeoidrj"), "qahoegcmplkfsjbdnitr", 5, 19, 8); + test(S("espogqbthk"), "dpteiajrqmsognhlfbkc", 5, 20, S::npos); + test(S("shoiedtcjb"), "", 9, 0, 9); + test(S("ebcinjgads"), "tqbnh", 9, 0, 9); + test(S("dqmregkcfl"), "akmle", 9, 1, 9); + test(S("ngcrieqajf"), "iqfkm", 9, 2, 9); + test(S("qosmilgnjb"), "tqjsr", 9, 4, 9); + test(S("ikabsjtdfl"), "jplqg", 9, 5, S::npos); + test(S("ersmicafdh"), "oilnrbcgtj", 9, 0, 9); + test(S("fdnplotmgh"), "morkglpesn", 9, 1, 9); + test(S("fdbicojerm"), "dmicerngat", 9, 5, S::npos); + test(S("mbtafndjcq"), "radgeskbtc", 9, 9, 9); + test(S("mlenkpfdtc"), "ljikprsmqo", 9, 10, 9); + test(S("ahlcifdqgs"), "trqihkcgsjamfdbolnpe", 9, 0, 9); + test(S("bgjemaltks"), "lqmthbsrekajgnofcipd", 9, 1, 9); + test(S("pdhslbqrfc"), "jtalmedribkgqsopcnfh", 9, 10, 9); + test(S("dirhtsnjkc"), "spqfoiclmtagejbndkrh", 9, 19, S::npos); + test(S("dlroktbcja"), "nmotklspigjrdhcfaebq", 9, 20, S::npos); + test(S("ncjpmaekbs"), "", 10, 0, S::npos); + test(S("hlbosgmrak"), "hpmsd", 10, 0, S::npos); + test(S("pqfhsgilen"), "qnpor", 10, 1, S::npos); + test(S("gqtjsbdckh"), "otdma", 10, 2, S::npos); + test(S("cfkqpjlegi"), "efhjg", 10, 4, S::npos); + test(S("beanrfodgj"), "odpte", 10, 5, S::npos); + test(S("adtkqpbjfi"), "bctdgfmolr", 10, 0, S::npos); + test(S("iomkfthagj"), "oaklidrbqg", 10, 1, S::npos); +} + +template +void test2() +{ + test(S("sdpcilonqj"), "dnjfsagktr", 10, 5, S::npos); + test(S("gtfbdkqeml"), "nejaktmiqg", 10, 9, S::npos); + test(S("bmeqgcdorj"), "pjqonlebsf", 10, 10, S::npos); + test(S("etqlcanmob"), "dshmnbtolcjepgaikfqr", 10, 0, S::npos); + test(S("roqmkbdtia"), "iogfhpabtjkqlrnemcds", 10, 1, S::npos); + test(S("kadsithljf"), "ngridfabjsecpqltkmoh", 10, 10, S::npos); + test(S("sgtkpbfdmh"), "athmknplcgofrqejsdib", 10, 19, S::npos); + test(S("qgmetnabkl"), "ldobhmqcafnjtkeisgrp", 10, 20, S::npos); + test(S("cqjohampgd"), "", 11, 0, S::npos); + test(S("hobitmpsan"), "aocjb", 11, 0, S::npos); + test(S("tjehkpsalm"), "jbrnk", 11, 1, S::npos); + test(S("ngfbojitcl"), "tqedg", 11, 2, S::npos); + test(S("rcfkdbhgjo"), "nqskp", 11, 4, S::npos); + test(S("qghptonrea"), "eaqkl", 11, 5, S::npos); + test(S("hnprfgqjdl"), "reaoicljqm", 11, 0, S::npos); + test(S("hlmgabenti"), "lsftgajqpm", 11, 1, S::npos); + test(S("ofcjanmrbs"), "rlpfogmits", 11, 5, S::npos); + test(S("jqedtkornm"), "shkncmiaqj", 11, 9, S::npos); + test(S("rfedlasjmg"), "fpnatrhqgs", 11, 10, S::npos); + test(S("talpqjsgkm"), "sjclemqhnpdbgikarfot", 11, 0, S::npos); + test(S("lrkcbtqpie"), "otcmedjikgsfnqbrhpla", 11, 1, S::npos); + test(S("cipogdskjf"), "bonsaefdqiprkhlgtjcm", 11, 10, S::npos); + test(S("nqedcojahi"), "egpscmahijlfnkrodqtb", 11, 19, S::npos); + test(S("hefnrkmctj"), "kmqbfepjthgilscrndoa", 11, 20, S::npos); + test(S("atqirnmekfjolhpdsgcb"), "", 0, 0, 0); + test(S("echfkmlpribjnqsaogtd"), "prboq", 0, 0, 0); + test(S("qnhiftdgcleajbpkrosm"), "fjcqh", 0, 1, 0); + test(S("chamfknorbedjitgslpq"), "fmosa", 0, 2, 0); + test(S("njhqpibfmtlkaecdrgso"), "qdbok", 0, 4, 0); + test(S("ebnghfsqkprmdcljoiat"), "amslg", 0, 5, 0); + test(S("letjomsgihfrpqbkancd"), "smpltjneqb", 0, 0, 0); + test(S("nblgoipcrqeaktshjdmf"), "flitskrnge", 0, 1, 0); + test(S("cehkbngtjoiflqapsmrd"), "pgqihmlbef", 0, 5, 0); + test(S("mignapfoklbhcqjetdrs"), "cfpdqjtgsb", 0, 9, 0); + test(S("ceatbhlsqjgpnokfrmdi"), "htpsiaflom", 0, 10, 0); + test(S("ocihkjgrdelpfnmastqb"), "kpjfiaceghsrdtlbnomq", 0, 0, 0); + test(S("noelgschdtbrjfmiqkap"), "qhtbomidljgafneksprc", 0, 1, 0); + test(S("dkclqfombepritjnghas"), "nhtjobkcefldimpsaqgr", 0, 10, 0); + test(S("miklnresdgbhqcojftap"), "prabcjfqnoeskilmtgdh", 0, 19, 11); + test(S("htbcigojaqmdkfrnlsep"), "dtrgmchilkasqoebfpjn", 0, 20, S::npos); + test(S("febhmqtjanokscdirpgl"), "", 1, 0, 1); + test(S("loakbsqjpcrdhftniegm"), "sqome", 1, 0, 1); + test(S("reagphsqflbitdcjmkno"), "smfte", 1, 1, 1); + test(S("jitlfrqemsdhkopncabg"), "ciboh", 1, 2, 2); + test(S("mhtaepscdnrjqgbkifol"), "haois", 1, 4, 2); + test(S("tocesrfmnglpbjihqadk"), "abfki", 1, 5, 1); + test(S("lpfmctjrhdagneskbqoi"), "frdkocntmq", 1, 0, 1); + test(S("lsmqaepkdhncirbtjfgo"), "oasbpedlnr", 1, 1, 1); + test(S("epoiqmtldrabnkjhcfsg"), "kltqmhgand", 1, 5, 1); + test(S("emgasrilpknqojhtbdcf"), "gdtfjchpmr", 1, 9, 3); + test(S("hnfiagdpcklrjetqbsom"), "ponmcqblet", 1, 10, 2); + test(S("nsdfebgajhmtricpoklq"), "sgphqdnofeiklatbcmjr", 1, 0, 1); + test(S("atjgfsdlpobmeiqhncrk"), "ljqprsmigtfoneadckbh", 1, 1, 1); + test(S("sitodfgnrejlahcbmqkp"), "ligeojhafnkmrcsqtbdp", 1, 10, 2); + test(S("fraghmbiceknltjpqosd"), "lsimqfnjarbopedkhcgt", 1, 19, 13); + test(S("pmafenlhqtdbkirjsogc"), "abedmfjlghniorcqptks", 1, 20, S::npos); + test(S("pihgmoeqtnakrjslcbfd"), "", 10, 0, 10); + test(S("gjdkeprctqblnhiafsom"), "hqtoa", 10, 0, 10); + test(S("mkpnblfdsahrcqijteog"), "cahif", 10, 1, 10); + test(S("gckarqnelodfjhmbptis"), "kehis", 10, 2, 10); + test(S("gqpskidtbclomahnrjfe"), "kdlmh", 10, 4, 11); + test(S("pkldjsqrfgitbhmaecno"), "paeql", 10, 5, 10); + test(S("aftsijrbeklnmcdqhgop"), "aghoqiefnb", 10, 0, 10); + test(S("mtlgdrhafjkbiepqnsoc"), "jrbqaikpdo", 10, 1, 10); + test(S("pqgirnaefthokdmbsclj"), "smjonaeqcl", 10, 5, 10); + test(S("kpdbgjmtherlsfcqoina"), "eqbdrkcfah", 10, 9, 11); + test(S("jrlbothiknqmdgcfasep"), "kapmsienhf", 10, 10, 10); + test(S("mjogldqferckabinptsh"), "jpqotrlenfcsbhkaimdg", 10, 0, 10); + test(S("apoklnefbhmgqcdrisjt"), "jlbmhnfgtcqprikeados", 10, 1, 10); + test(S("ifeopcnrjbhkdgatmqls"), "stgbhfmdaljnpqoicker", 10, 10, 11); + test(S("ckqhaiesmjdnrgolbtpf"), "oihcetflbjagdsrkmqpn", 10, 19, 11); + test(S("bnlgapfimcoterskqdjh"), "adtclebmnpjsrqfkigoh", 10, 20, S::npos); + test(S("kgdlrobpmjcthqsafeni"), "", 19, 0, 19); + test(S("dfkechomjapgnslbtqir"), "beafg", 19, 0, 19); + test(S("rloadknfbqtgmhcsipje"), "iclat", 19, 1, 19); + test(S("mgjhkolrnadqbpetcifs"), "rkhnf", 19, 2, 19); + test(S("cmlfakiojdrgtbsphqen"), "clshq", 19, 4, 19); + test(S("kghbfipeomsntdalrqjc"), "dtcoj", 19, 5, S::npos); + test(S("eldiqckrnmtasbghjfpo"), "rqosnjmfth", 19, 0, 19); + test(S("abqjcfedgotihlnspkrm"), "siatdfqglh", 19, 1, 19); + test(S("qfbadrtjsimkolcenhpg"), "mrlshtpgjq", 19, 5, 19); + test(S("abseghclkjqifmtodrnp"), "adlcskgqjt", 19, 9, 19); + test(S("ibmsnlrjefhtdokacqpg"), "drshcjknaf", 19, 10, 19); + test(S("mrkfciqjebaponsthldg"), "etsaqroinghpkjdlfcbm", 19, 0, 19); + test(S("mjkticdeoqshpalrfbgn"), "sgepdnkqliambtrocfhj", 19, 1, 19); + test(S("rqnoclbdejgiphtfsakm"), "nlmcjaqgbsortfdihkpe", 19, 10, S::npos); + test(S("plkqbhmtfaeodjcrsing"), "racfnpmosldibqkghjet", 19, 19, S::npos); + test(S("oegalhmstjrfickpbndq"), "fjhdsctkqeiolagrnmbp", 19, 20, S::npos); + test(S("rdtgjcaohpblniekmsfq"), "", 20, 0, S::npos); + test(S("ofkqbnjetrmsaidphglc"), "ejanp", 20, 0, S::npos); + test(S("grkpahljcftesdmonqib"), "odife", 20, 1, S::npos); + test(S("jimlgbhfqkteospardcn"), "okaqd", 20, 2, S::npos); + test(S("gftenihpmslrjkqadcob"), "lcdbi", 20, 4, S::npos); + test(S("bmhldogtckrfsanijepq"), "fsqbj", 20, 5, S::npos); + test(S("nfqkrpjdesabgtlcmoih"), "bigdomnplq", 20, 0, S::npos); + test(S("focalnrpiqmdkstehbjg"), "apiblotgcd", 20, 1, S::npos); + test(S("rhqdspkmebiflcotnjga"), "acfhdenops", 20, 5, S::npos); + test(S("rahdtmsckfboqlpniegj"), "jopdeamcrk", 20, 9, S::npos); + test(S("fbkeiopclstmdqranjhg"), "trqncbkgmh", 20, 10, S::npos); + test(S("lifhpdgmbconstjeqark"), "tomglrkencbsfjqpihda", 20, 0, S::npos); +} + +template +void test3() +{ + test(S("pboqganrhedjmltsicfk"), "gbkhdnpoietfcmrslajq", 20, 1, S::npos); + test(S("klchabsimetjnqgorfpd"), "rtfnmbsglkjaichoqedp", 20, 10, S::npos); + test(S("sirfgmjqhctndbklaepo"), "ohkmdpfqbsacrtjnlgei", 20, 19, S::npos); + test(S("rlbdsiceaonqjtfpghkm"), "dlbrteoisgphmkncajfq", 20, 20, S::npos); + test(S("ecgdanriptblhjfqskom"), "", 21, 0, S::npos); + test(S("fdmiarlpgcskbhoteqjn"), "sjrlo", 21, 0, S::npos); + test(S("rlbstjqopignecmfadkh"), "qjpor", 21, 1, S::npos); + test(S("grjpqmbshektdolcafni"), "odhfn", 21, 2, S::npos); + test(S("sakfcohtqnibprjmlged"), "qtfin", 21, 4, S::npos); + test(S("mjtdglasihqpocebrfkn"), "hpqfo", 21, 5, S::npos); + test(S("okaplfrntghqbmeicsdj"), "fabmertkos", 21, 0, S::npos); + test(S("sahngemrtcjidqbklfpo"), "brqtgkmaej", 21, 1, S::npos); + test(S("dlmsipcnekhbgoaftqjr"), "nfrdeihsgl", 21, 5, S::npos); + test(S("ahegrmqnoiklpfsdbcjt"), "hlfrosekpi", 21, 9, S::npos); + test(S("hdsjbnmlegtkqripacof"), "atgbkrjdsm", 21, 10, S::npos); + test(S("pcnedrfjihqbalkgtoms"), "blnrptjgqmaifsdkhoec", 21, 0, S::npos); + test(S("qjidealmtpskrbfhocng"), "ctpmdahebfqjgknloris", 21, 1, S::npos); + test(S("qeindtagmokpfhsclrbj"), "apnkeqthrmlbfodiscgj", 21, 10, S::npos); + test(S("kpfegbjhsrnodltqciam"), "jdgictpframeoqlsbknh", 21, 19, S::npos); + test(S("hnbrcplsjfgiktoedmaq"), "qprlsfojamgndekthibc", 21, 20, S::npos); +} + +int main() +{ + { + typedef std::string S; + test0(); + test1(); + test2(); + test3(); + } +#if TEST_STD_VER >= 11 + { + typedef std::basic_string, min_allocator> S; + test0(); + test1(); + test2(); + test3(); + } +#endif +} diff --git a/tests/external/libcxx/basic_string/string.ops/string_find.first.not.of/string_size.pass.cpp b/tests/external/libcxx/basic_string/string.ops/string_find.first.not.of/string_size.pass.cpp new file mode 100644 index 0000000..4ce3433 --- /dev/null +++ b/tests/external/libcxx/basic_string/string.ops/string_find.first.not.of/string_size.pass.cpp @@ -0,0 +1,165 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// + +// size_type find_first_not_of(const basic_string& str, size_type pos = 0) const; + +#include +#include + +#include "test_macros.h" +#include "min_allocator.h" + +template +void +test(const S& s, const S& str, typename S::size_type pos, typename S::size_type x) +{ + assert(s.find_first_not_of(str, pos) == x); + if (x != S::npos) + assert(pos <= x && x < s.size()); +} + +template +void +test(const S& s, const S& str, typename S::size_type x) +{ + assert(s.find_first_not_of(str) == x); + if (x != S::npos) + assert(x < s.size()); +} + +template +void test0() +{ + test(S(""), S(""), 0, S::npos); + test(S(""), S("laenf"), 0, S::npos); + test(S(""), S("pqlnkmbdjo"), 0, S::npos); + test(S(""), S("qkamfogpnljdcshbreti"), 0, S::npos); + test(S(""), S(""), 1, S::npos); + test(S(""), S("bjaht"), 1, S::npos); + test(S(""), S("hjlcmgpket"), 1, S::npos); + test(S(""), S("htaobedqikfplcgjsmrn"), 1, S::npos); + test(S("fodgq"), S(""), 0, 0); + test(S("qanej"), S("dfkap"), 0, 0); + test(S("clbao"), S("ihqrfebgad"), 0, 0); + test(S("mekdn"), S("ngtjfcalbseiqrphmkdo"), 0, S::npos); + test(S("srdfq"), S(""), 1, 1); + test(S("oemth"), S("ikcrq"), 1, 1); + test(S("cdaih"), S("dmajblfhsg"), 1, 3); + test(S("qohtk"), S("oqftjhdmkgsblacenirp"), 1, S::npos); + test(S("cshmd"), S(""), 2, 2); + test(S("lhcdo"), S("oebqi"), 2, 2); + test(S("qnsoh"), S("kojhpmbsfe"), 2, S::npos); + test(S("pkrof"), S("acbsjqogpltdkhinfrem"), 2, S::npos); + test(S("fmtsp"), S(""), 4, 4); + test(S("khbpm"), S("aobjd"), 4, 4); + test(S("pbsji"), S("pcbahntsje"), 4, 4); + test(S("mprdj"), S("fhepcrntkoagbmldqijs"), 4, S::npos); + test(S("eqmpa"), S(""), 5, S::npos); + test(S("omigs"), S("kocgb"), 5, S::npos); + test(S("onmje"), S("fbslrjiqkm"), 5, S::npos); + test(S("oqmrj"), S("jeidpcmalhfnqbgtrsko"), 5, S::npos); + test(S("schfa"), S(""), 6, S::npos); + test(S("igdsc"), S("qngpd"), 6, S::npos); + test(S("brqgo"), S("rodhqklgmb"), 6, S::npos); + test(S("tnrph"), S("thdjgafrlbkoiqcspmne"), 6, S::npos); + test(S("hcjitbfapl"), S(""), 0, 0); + test(S("daiprenocl"), S("ashjd"), 0, 2); + test(S("litpcfdghe"), S("mgojkldsqh"), 0, 1); + test(S("aidjksrolc"), S("imqnaghkfrdtlopbjesc"), 0, S::npos); + test(S("qpghtfbaji"), S(""), 1, 1); + test(S("gfshlcmdjr"), S("nadkh"), 1, 1); + test(S("nkodajteqp"), S("ofdrqmkebl"), 1, 4); + test(S("gbmetiprqd"), S("bdfjqgatlksriohemnpc"), 1, S::npos); + test(S("crnklpmegd"), S(""), 5, 5); + test(S("jsbtafedoc"), S("prqgn"), 5, 5); + test(S("qnmodrtkeb"), S("pejafmnokr"), 5, 6); + test(S("cpebqsfmnj"), S("odnqkgijrhabfmcestlp"), 5, S::npos); + test(S("lmofqdhpki"), S(""), 9, 9); + test(S("hnefkqimca"), S("rtjpa"), 9, S::npos); + test(S("drtasbgmfp"), S("ktsrmnqagd"), 9, 9); + test(S("lsaijeqhtr"), S("rtdhgcisbnmoaqkfpjle"), 9, S::npos); + test(S("elgofjmbrq"), S(""), 10, S::npos); + test(S("mjqdgalkpc"), S("dplqa"), 10, S::npos); + test(S("kthqnfcerm"), S("dkacjoptns"), 10, S::npos); + test(S("dfsjhanorc"), S("hqfimtrgnbekpdcsjalo"), 10, S::npos); + test(S("eqsgalomhb"), S(""), 11, S::npos); + test(S("akiteljmoh"), S("lofbc"), 11, S::npos); + test(S("hlbdfreqjo"), S("astoegbfpn"), 11, S::npos); + test(S("taqobhlerg"), S("pdgreqomsncafklhtibj"), 11, S::npos); + test(S("snafbdlghrjkpqtoceim"), S(""), 0, 0); + test(S("aemtbrgcklhndjisfpoq"), S("lbtqd"), 0, 0); + test(S("pnracgfkjdiholtbqsem"), S("tboimldpjh"), 0, 1); + test(S("dicfltehbsgrmojnpkaq"), S("slcerthdaiqjfnobgkpm"), 0, S::npos); + test(S("jlnkraeodhcspfgbqitm"), S(""), 1, 1); + test(S("lhosrngtmfjikbqpcade"), S("aqibs"), 1, 1); + test(S("rbtaqjhgkneisldpmfoc"), S("gtfblmqinc"), 1, 3); + test(S("gpifsqlrdkbonjtmheca"), S("mkqpbtdalgniorhfescj"), 1, S::npos); + test(S("hdpkobnsalmcfijregtq"), S(""), 10, 10); + test(S("jtlshdgqaiprkbcoenfm"), S("pblas"), 10, 11); + test(S("fkdrbqltsgmcoiphneaj"), S("arosdhcfme"), 10, 13); + test(S("crsplifgtqedjohnabmk"), S("blkhjeogicatqfnpdmsr"), 10, S::npos); + test(S("niptglfbosehkamrdqcj"), S(""), 19, 19); + test(S("copqdhstbingamjfkler"), S("djkqc"), 19, 19); + test(S("mrtaefilpdsgocnhqbjk"), S("lgokshjtpb"), 19, S::npos); + test(S("kojatdhlcmigpbfrqnes"), S("bqjhtkfepimcnsgrlado"), 19, S::npos); + test(S("eaintpchlqsbdgrkjofm"), S(""), 20, S::npos); + test(S("gjnhidfsepkrtaqbmclo"), S("nocfa"), 20, S::npos); + test(S("spocfaktqdbiejlhngmr"), S("bgtajmiedc"), 20, S::npos); + test(S("rphmlekgfscndtaobiqj"), S("lsckfnqgdahejiopbtmr"), 20, S::npos); + test(S("liatsqdoegkmfcnbhrpj"), S(""), 21, S::npos); + test(S("binjagtfldkrspcomqeh"), S("gfsrt"), 21, S::npos); + test(S("latkmisecnorjbfhqpdg"), S("pfsocbhjtm"), 21, S::npos); + test(S("lecfratdjkhnsmqpoigb"), S("tpflmdnoicjgkberhqsa"), 21, S::npos); +} + +template +void test1() +{ + test(S(""), S(""), S::npos); + test(S(""), S("laenf"), S::npos); + test(S(""), S("pqlnkmbdjo"), S::npos); + test(S(""), S("qkamfogpnljdcshbreti"), S::npos); + test(S("nhmko"), S(""), 0); + test(S("lahfb"), S("irkhs"), 0); + test(S("gmfhd"), S("kantesmpgj"), 2); + test(S("odaft"), S("oknlrstdpiqmjbaghcfe"), S::npos); + test(S("eolhfgpjqk"), S(""), 0); + test(S("nbatdlmekr"), S("bnrpe"), 2); + test(S("jdmciepkaq"), S("jtdaefblso"), 2); + test(S("hkbgspoflt"), S("oselktgbcapndfjihrmq"), S::npos); + test(S("gprdcokbnjhlsfmtieqa"), S(""), 0); + test(S("qjghlnftcaismkropdeb"), S("bjaht"), 0); + test(S("pnalfrdtkqcmojiesbhg"), S("hjlcmgpket"), 1); + test(S("pniotcfrhqsmgdkjbael"), S("htaobedqikfplcgjsmrn"), S::npos); +} + +int main() +{ + { + typedef std::string S; + test0(); + test1(); + } +#if TEST_STD_VER >= 11 + { + typedef std::basic_string, min_allocator> S; + test0(); + test1(); + } +#endif + +#if TEST_STD_VER > 3 + { // LWG 2946 + std::string s = " !"; + assert(s.find_first_not_of({"abc", 1}) == 0); + } +#endif +} diff --git a/tests/external/libcxx/basic_string/string.ops/string_find.first.not.of/string_view_size.pass.cpp b/tests/external/libcxx/basic_string/string.ops/string_find.first.not.of/string_view_size.pass.cpp new file mode 100644 index 0000000..fb69f8b --- /dev/null +++ b/tests/external/libcxx/basic_string/string.ops/string_find.first.not.of/string_view_size.pass.cpp @@ -0,0 +1,159 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// + +// size_type find_first_not_of(basic_string_view sv, size_type pos = 0) const; + +#include +#include + +#include "min_allocator.h" + +template +void +test(const S& s, SV sv, typename S::size_type pos, typename S::size_type x) +{ + assert(s.find_first_not_of(sv, pos) == x); + if (x != S::npos) + assert(pos <= x && x < s.size()); +} + +template +void +test(const S& s, SV sv, typename S::size_type x) +{ + assert(s.find_first_not_of(sv) == x); + if (x != S::npos) + assert(x < s.size()); +} + +template +void test0() +{ + test(S(""), SV(""), 0, S::npos); + test(S(""), SV("laenf"), 0, S::npos); + test(S(""), SV("pqlnkmbdjo"), 0, S::npos); + test(S(""), SV("qkamfogpnljdcshbreti"), 0, S::npos); + test(S(""), SV(""), 1, S::npos); + test(S(""), SV("bjaht"), 1, S::npos); + test(S(""), SV("hjlcmgpket"), 1, S::npos); + test(S(""), SV("htaobedqikfplcgjsmrn"), 1, S::npos); + test(S("fodgq"), SV(""), 0, 0); + test(S("qanej"), SV("dfkap"), 0, 0); + test(S("clbao"), SV("ihqrfebgad"), 0, 0); + test(S("mekdn"), SV("ngtjfcalbseiqrphmkdo"), 0, S::npos); + test(S("srdfq"), SV(""), 1, 1); + test(S("oemth"), SV("ikcrq"), 1, 1); + test(S("cdaih"), SV("dmajblfhsg"), 1, 3); + test(S("qohtk"), SV("oqftjhdmkgsblacenirp"), 1, S::npos); + test(S("cshmd"), SV(""), 2, 2); + test(S("lhcdo"), SV("oebqi"), 2, 2); + test(S("qnsoh"), SV("kojhpmbsfe"), 2, S::npos); + test(S("pkrof"), SV("acbsjqogpltdkhinfrem"), 2, S::npos); + test(S("fmtsp"), SV(""), 4, 4); + test(S("khbpm"), SV("aobjd"), 4, 4); + test(S("pbsji"), SV("pcbahntsje"), 4, 4); + test(S("mprdj"), SV("fhepcrntkoagbmldqijs"), 4, S::npos); + test(S("eqmpa"), SV(""), 5, S::npos); + test(S("omigs"), SV("kocgb"), 5, S::npos); + test(S("onmje"), SV("fbslrjiqkm"), 5, S::npos); + test(S("oqmrj"), SV("jeidpcmalhfnqbgtrsko"), 5, S::npos); + test(S("schfa"), SV(""), 6, S::npos); + test(S("igdsc"), SV("qngpd"), 6, S::npos); + test(S("brqgo"), SV("rodhqklgmb"), 6, S::npos); + test(S("tnrph"), SV("thdjgafrlbkoiqcspmne"), 6, S::npos); + test(S("hcjitbfapl"), SV(""), 0, 0); + test(S("daiprenocl"), SV("ashjd"), 0, 2); + test(S("litpcfdghe"), SV("mgojkldsqh"), 0, 1); + test(S("aidjksrolc"), SV("imqnaghkfrdtlopbjesc"), 0, S::npos); + test(S("qpghtfbaji"), SV(""), 1, 1); + test(S("gfshlcmdjr"), SV("nadkh"), 1, 1); + test(S("nkodajteqp"), SV("ofdrqmkebl"), 1, 4); + test(S("gbmetiprqd"), SV("bdfjqgatlksriohemnpc"), 1, S::npos); + test(S("crnklpmegd"), SV(""), 5, 5); + test(S("jsbtafedoc"), SV("prqgn"), 5, 5); + test(S("qnmodrtkeb"), SV("pejafmnokr"), 5, 6); + test(S("cpebqsfmnj"), SV("odnqkgijrhabfmcestlp"), 5, S::npos); + test(S("lmofqdhpki"), SV(""), 9, 9); + test(S("hnefkqimca"), SV("rtjpa"), 9, S::npos); + test(S("drtasbgmfp"), SV("ktsrmnqagd"), 9, 9); + test(S("lsaijeqhtr"), SV("rtdhgcisbnmoaqkfpjle"), 9, S::npos); + test(S("elgofjmbrq"), SV(""), 10, S::npos); + test(S("mjqdgalkpc"), SV("dplqa"), 10, S::npos); + test(S("kthqnfcerm"), SV("dkacjoptns"), 10, S::npos); + test(S("dfsjhanorc"), SV("hqfimtrgnbekpdcsjalo"), 10, S::npos); + test(S("eqsgalomhb"), SV(""), 11, S::npos); + test(S("akiteljmoh"), SV("lofbc"), 11, S::npos); + test(S("hlbdfreqjo"), SV("astoegbfpn"), 11, S::npos); + test(S("taqobhlerg"), SV("pdgreqomsncafklhtibj"), 11, S::npos); + test(S("snafbdlghrjkpqtoceim"), SV(""), 0, 0); + test(S("aemtbrgcklhndjisfpoq"), SV("lbtqd"), 0, 0); + test(S("pnracgfkjdiholtbqsem"), SV("tboimldpjh"), 0, 1); + test(S("dicfltehbsgrmojnpkaq"), SV("slcerthdaiqjfnobgkpm"), 0, S::npos); + test(S("jlnkraeodhcspfgbqitm"), SV(""), 1, 1); + test(S("lhosrngtmfjikbqpcade"), SV("aqibs"), 1, 1); + test(S("rbtaqjhgkneisldpmfoc"), SV("gtfblmqinc"), 1, 3); + test(S("gpifsqlrdkbonjtmheca"), SV("mkqpbtdalgniorhfescj"), 1, S::npos); + test(S("hdpkobnsalmcfijregtq"), SV(""), 10, 10); + test(S("jtlshdgqaiprkbcoenfm"), SV("pblas"), 10, 11); + test(S("fkdrbqltsgmcoiphneaj"), SV("arosdhcfme"), 10, 13); + test(S("crsplifgtqedjohnabmk"), SV("blkhjeogicatqfnpdmsr"), 10, S::npos); + test(S("niptglfbosehkamrdqcj"), SV(""), 19, 19); + test(S("copqdhstbingamjfkler"), SV("djkqc"), 19, 19); + test(S("mrtaefilpdsgocnhqbjk"), SV("lgokshjtpb"), 19, S::npos); + test(S("kojatdhlcmigpbfrqnes"), SV("bqjhtkfepimcnsgrlado"), 19, S::npos); + test(S("eaintpchlqsbdgrkjofm"), SV(""), 20, S::npos); + test(S("gjnhidfsepkrtaqbmclo"), SV("nocfa"), 20, S::npos); + test(S("spocfaktqdbiejlhngmr"), SV("bgtajmiedc"), 20, S::npos); + test(S("rphmlekgfscndtaobiqj"), SV("lsckfnqgdahejiopbtmr"), 20, S::npos); + test(S("liatsqdoegkmfcnbhrpj"), SV(""), 21, S::npos); + test(S("binjagtfldkrspcomqeh"), SV("gfsrt"), 21, S::npos); + test(S("latkmisecnorjbfhqpdg"), SV("pfsocbhjtm"), 21, S::npos); + test(S("lecfratdjkhnsmqpoigb"), SV("tpflmdnoicjgkberhqsa"), 21, S::npos); +} + +template +void test1() +{ + test(S(""), SV(""), S::npos); + test(S(""), SV("laenf"), S::npos); + test(S(""), SV("pqlnkmbdjo"), S::npos); + test(S(""), SV("qkamfogpnljdcshbreti"), S::npos); + test(S("nhmko"), SV(""), 0); + test(S("lahfb"), SV("irkhs"), 0); + test(S("gmfhd"), SV("kantesmpgj"), 2); + test(S("odaft"), SV("oknlrstdpiqmjbaghcfe"), S::npos); + test(S("eolhfgpjqk"), SV(""), 0); + test(S("nbatdlmekr"), SV("bnrpe"), 2); + test(S("jdmciepkaq"), SV("jtdaefblso"), 2); + test(S("hkbgspoflt"), SV("oselktgbcapndfjihrmq"), S::npos); + test(S("gprdcokbnjhlsfmtieqa"), SV(""), 0); + test(S("qjghlnftcaismkropdeb"), SV("bjaht"), 0); + test(S("pnalfrdtkqcmojiesbhg"), SV("hjlcmgpket"), 1); + test(S("pniotcfrhqsmgdkjbael"), SV("htaobedqikfplcgjsmrn"), S::npos); +} + +int main() +{ + { + typedef std::string S; + typedef std::string_view SV; + test0(); + test1(); + } +#if TEST_STD_VER >= 11 + { + typedef std::basic_string, min_allocator> S; + typedef std::string_view SV; + test0(); + test1(); + } +#endif +} diff --git a/tests/external/libcxx/basic_string/string.ops/string_find.first.of/char_size.pass.cpp b/tests/external/libcxx/basic_string/string.ops/string_find.first.of/char_size.pass.cpp new file mode 100644 index 0000000..494a118 --- /dev/null +++ b/tests/external/libcxx/basic_string/string.ops/string_find.first.of/char_size.pass.cpp @@ -0,0 +1,98 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// + +// size_type find_first_of(charT c, size_type pos = 0) const; + +#include +#include + +#include "min_allocator.h" + +template +void +test(const S& s, typename S::value_type c, typename S::size_type pos, + typename S::size_type x) +{ + assert(s.find_first_of(c, pos) == x); + if (x != S::npos) + assert(pos <= x && x < s.size()); +} + +template +void +test(const S& s, typename S::value_type c, typename S::size_type x) +{ + assert(s.find_first_of(c) == x); + if (x != S::npos) + assert(x < s.size()); +} + +int main() +{ + { + typedef std::string S; + test(S(""), 'e', 0, S::npos); + test(S(""), 'e', 1, S::npos); + test(S("kitcj"), 'e', 0, S::npos); + test(S("qkamf"), 'e', 1, S::npos); + test(S("nhmko"), 'e', 2, S::npos); + test(S("tpsaf"), 'e', 4, S::npos); + test(S("lahfb"), 'e', 5, S::npos); + test(S("irkhs"), 'e', 6, S::npos); + test(S("gmfhdaipsr"), 'e', 0, S::npos); + test(S("kantesmpgj"), 'e', 1, 4); + test(S("odaftiegpm"), 'e', 5, 6); + test(S("oknlrstdpi"), 'e', 9, S::npos); + test(S("eolhfgpjqk"), 'e', 10, S::npos); + test(S("pcdrofikas"), 'e', 11, S::npos); + test(S("nbatdlmekrgcfqsophij"), 'e', 0, 7); + test(S("bnrpehidofmqtcksjgla"), 'e', 1, 4); + test(S("jdmciepkaqgotsrfnhlb"), 'e', 10, S::npos); + test(S("jtdaefblsokrmhpgcnqi"), 'e', 19, S::npos); + test(S("hkbgspofltajcnedqmri"), 'e', 20, S::npos); + test(S("oselktgbcapndfjihrmq"), 'e', 21, S::npos); + + test(S(""), 'e', S::npos); + test(S("csope"), 'e', 4); + test(S("gfsmthlkon"), 'e', S::npos); + test(S("laenfsbridchgotmkqpj"), 'e', 2); + } +#if TEST_STD_VER >= 11 + { + typedef std::basic_string, min_allocator> S; + test(S(""), 'e', 0, S::npos); + test(S(""), 'e', 1, S::npos); + test(S("kitcj"), 'e', 0, S::npos); + test(S("qkamf"), 'e', 1, S::npos); + test(S("nhmko"), 'e', 2, S::npos); + test(S("tpsaf"), 'e', 4, S::npos); + test(S("lahfb"), 'e', 5, S::npos); + test(S("irkhs"), 'e', 6, S::npos); + test(S("gmfhdaipsr"), 'e', 0, S::npos); + test(S("kantesmpgj"), 'e', 1, 4); + test(S("odaftiegpm"), 'e', 5, 6); + test(S("oknlrstdpi"), 'e', 9, S::npos); + test(S("eolhfgpjqk"), 'e', 10, S::npos); + test(S("pcdrofikas"), 'e', 11, S::npos); + test(S("nbatdlmekrgcfqsophij"), 'e', 0, 7); + test(S("bnrpehidofmqtcksjgla"), 'e', 1, 4); + test(S("jdmciepkaqgotsrfnhlb"), 'e', 10, S::npos); + test(S("jtdaefblsokrmhpgcnqi"), 'e', 19, S::npos); + test(S("hkbgspofltajcnedqmri"), 'e', 20, S::npos); + test(S("oselktgbcapndfjihrmq"), 'e', 21, S::npos); + + test(S(""), 'e', S::npos); + test(S("csope"), 'e', 4); + test(S("gfsmthlkon"), 'e', S::npos); + test(S("laenfsbridchgotmkqpj"), 'e', 2); + } +#endif +} diff --git a/tests/external/libcxx/basic_string/string.ops/string_find.first.of/pointer_size.pass.cpp b/tests/external/libcxx/basic_string/string.ops/string_find.first.of/pointer_size.pass.cpp new file mode 100644 index 0000000..b2a05b2 --- /dev/null +++ b/tests/external/libcxx/basic_string/string.ops/string_find.first.of/pointer_size.pass.cpp @@ -0,0 +1,158 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// + +// size_type find_first_of(const charT* s, size_type pos = 0) const; + +#include +#include + +#include "min_allocator.h" + +template +void +test(const S& s, const typename S::value_type* str, typename S::size_type pos, + typename S::size_type x) +{ + assert(s.find_first_of(str, pos) == x); + if (x != S::npos) + assert(pos <= x && x < s.size()); +} + +template +void +test(const S& s, const typename S::value_type* str, typename S::size_type x) +{ + assert(s.find_first_of(str) == x); + if (x != S::npos) + assert(x < s.size()); +} + +template +void test0() +{ + test(S(""), "", 0, S::npos); + test(S(""), "laenf", 0, S::npos); + test(S(""), "pqlnkmbdjo", 0, S::npos); + test(S(""), "qkamfogpnljdcshbreti", 0, S::npos); + test(S(""), "", 1, S::npos); + test(S(""), "bjaht", 1, S::npos); + test(S(""), "hjlcmgpket", 1, S::npos); + test(S(""), "htaobedqikfplcgjsmrn", 1, S::npos); + test(S("fodgq"), "", 0, S::npos); + test(S("qanej"), "dfkap", 0, 1); + test(S("clbao"), "ihqrfebgad", 0, 2); + test(S("mekdn"), "ngtjfcalbseiqrphmkdo", 0, 0); + test(S("srdfq"), "", 1, S::npos); + test(S("oemth"), "ikcrq", 1, S::npos); + test(S("cdaih"), "dmajblfhsg", 1, 1); + test(S("qohtk"), "oqftjhdmkgsblacenirp", 1, 1); + test(S("cshmd"), "", 2, S::npos); + test(S("lhcdo"), "oebqi", 2, 4); + test(S("qnsoh"), "kojhpmbsfe", 2, 2); + test(S("pkrof"), "acbsjqogpltdkhinfrem", 2, 2); + test(S("fmtsp"), "", 4, S::npos); + test(S("khbpm"), "aobjd", 4, S::npos); + test(S("pbsji"), "pcbahntsje", 4, S::npos); + test(S("mprdj"), "fhepcrntkoagbmldqijs", 4, 4); + test(S("eqmpa"), "", 5, S::npos); + test(S("omigs"), "kocgb", 5, S::npos); + test(S("onmje"), "fbslrjiqkm", 5, S::npos); + test(S("oqmrj"), "jeidpcmalhfnqbgtrsko", 5, S::npos); + test(S("schfa"), "", 6, S::npos); + test(S("igdsc"), "qngpd", 6, S::npos); + test(S("brqgo"), "rodhqklgmb", 6, S::npos); + test(S("tnrph"), "thdjgafrlbkoiqcspmne", 6, S::npos); + test(S("hcjitbfapl"), "", 0, S::npos); + test(S("daiprenocl"), "ashjd", 0, 0); + test(S("litpcfdghe"), "mgojkldsqh", 0, 0); + test(S("aidjksrolc"), "imqnaghkfrdtlopbjesc", 0, 0); + test(S("qpghtfbaji"), "", 1, S::npos); + test(S("gfshlcmdjr"), "nadkh", 1, 3); + test(S("nkodajteqp"), "ofdrqmkebl", 1, 1); + test(S("gbmetiprqd"), "bdfjqgatlksriohemnpc", 1, 1); + test(S("crnklpmegd"), "", 5, S::npos); + test(S("jsbtafedoc"), "prqgn", 5, S::npos); + test(S("qnmodrtkeb"), "pejafmnokr", 5, 5); + test(S("cpebqsfmnj"), "odnqkgijrhabfmcestlp", 5, 5); + test(S("lmofqdhpki"), "", 9, S::npos); + test(S("hnefkqimca"), "rtjpa", 9, 9); + test(S("drtasbgmfp"), "ktsrmnqagd", 9, S::npos); + test(S("lsaijeqhtr"), "rtdhgcisbnmoaqkfpjle", 9, 9); + test(S("elgofjmbrq"), "", 10, S::npos); + test(S("mjqdgalkpc"), "dplqa", 10, S::npos); + test(S("kthqnfcerm"), "dkacjoptns", 10, S::npos); + test(S("dfsjhanorc"), "hqfimtrgnbekpdcsjalo", 10, S::npos); + test(S("eqsgalomhb"), "", 11, S::npos); + test(S("akiteljmoh"), "lofbc", 11, S::npos); + test(S("hlbdfreqjo"), "astoegbfpn", 11, S::npos); + test(S("taqobhlerg"), "pdgreqomsncafklhtibj", 11, S::npos); + test(S("snafbdlghrjkpqtoceim"), "", 0, S::npos); + test(S("aemtbrgcklhndjisfpoq"), "lbtqd", 0, 3); + test(S("pnracgfkjdiholtbqsem"), "tboimldpjh", 0, 0); + test(S("dicfltehbsgrmojnpkaq"), "slcerthdaiqjfnobgkpm", 0, 0); + test(S("jlnkraeodhcspfgbqitm"), "", 1, S::npos); + test(S("lhosrngtmfjikbqpcade"), "aqibs", 1, 3); + test(S("rbtaqjhgkneisldpmfoc"), "gtfblmqinc", 1, 1); + test(S("gpifsqlrdkbonjtmheca"), "mkqpbtdalgniorhfescj", 1, 1); + test(S("hdpkobnsalmcfijregtq"), "", 10, S::npos); + test(S("jtlshdgqaiprkbcoenfm"), "pblas", 10, 10); + test(S("fkdrbqltsgmcoiphneaj"), "arosdhcfme", 10, 10); + test(S("crsplifgtqedjohnabmk"), "blkhjeogicatqfnpdmsr", 10, 10); + test(S("niptglfbosehkamrdqcj"), "", 19, S::npos); + test(S("copqdhstbingamjfkler"), "djkqc", 19, S::npos); + test(S("mrtaefilpdsgocnhqbjk"), "lgokshjtpb", 19, 19); + test(S("kojatdhlcmigpbfrqnes"), "bqjhtkfepimcnsgrlado", 19, 19); + test(S("eaintpchlqsbdgrkjofm"), "", 20, S::npos); + test(S("gjnhidfsepkrtaqbmclo"), "nocfa", 20, S::npos); + test(S("spocfaktqdbiejlhngmr"), "bgtajmiedc", 20, S::npos); + test(S("rphmlekgfscndtaobiqj"), "lsckfnqgdahejiopbtmr", 20, S::npos); + test(S("liatsqdoegkmfcnbhrpj"), "", 21, S::npos); + test(S("binjagtfldkrspcomqeh"), "gfsrt", 21, S::npos); + test(S("latkmisecnorjbfhqpdg"), "pfsocbhjtm", 21, S::npos); + test(S("lecfratdjkhnsmqpoigb"), "tpflmdnoicjgkberhqsa", 21, S::npos); +} + +template +void test1() +{ + test(S(""), "", S::npos); + test(S(""), "laenf", S::npos); + test(S(""), "pqlnkmbdjo", S::npos); + test(S(""), "qkamfogpnljdcshbreti", S::npos); + test(S("nhmko"), "", S::npos); + test(S("lahfb"), "irkhs", 2); + test(S("gmfhd"), "kantesmpgj", 0); + test(S("odaft"), "oknlrstdpiqmjbaghcfe", 0); + test(S("eolhfgpjqk"), "", S::npos); + test(S("nbatdlmekr"), "bnrpe", 0); + test(S("jdmciepkaq"), "jtdaefblso", 0); + test(S("hkbgspoflt"), "oselktgbcapndfjihrmq", 0); + test(S("gprdcokbnjhlsfmtieqa"), "", S::npos); + test(S("qjghlnftcaismkropdeb"), "bjaht", 1); + test(S("pnalfrdtkqcmojiesbhg"), "hjlcmgpket", 0); + test(S("pniotcfrhqsmgdkjbael"), "htaobedqikfplcgjsmrn", 0); +} + +int main() +{ + { + typedef std::string S; + test0(); + test1(); + } +#if TEST_STD_VER >= 11 + { + typedef std::basic_string, min_allocator> S; + test0(); + test1(); + } +#endif +} diff --git a/tests/external/libcxx/basic_string/string.ops/string_find.first.of/pointer_size_size.pass.cpp b/tests/external/libcxx/basic_string/string.ops/string_find.first.of/pointer_size_size.pass.cpp new file mode 100644 index 0000000..8b7f7b4 --- /dev/null +++ b/tests/external/libcxx/basic_string/string.ops/string_find.first.of/pointer_size_size.pass.cpp @@ -0,0 +1,387 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// + +// size_type find_first_of(const charT* s, size_type pos, size_type n) const; + +#include +#include + +#include "min_allocator.h" + +template +void +test(const S& s, const typename S::value_type* str, typename S::size_type pos, + typename S::size_type n, typename S::size_type x) +{ + assert(s.find_first_of(str, pos, n) == x); + if (x != S::npos) + assert(pos <= x && x < s.size()); +} + +template +void test0() +{ + test(S(""), "", 0, 0, S::npos); + test(S(""), "irkhs", 0, 0, S::npos); + test(S(""), "kante", 0, 1, S::npos); + test(S(""), "oknlr", 0, 2, S::npos); + test(S(""), "pcdro", 0, 4, S::npos); + test(S(""), "bnrpe", 0, 5, S::npos); + test(S(""), "jtdaefblso", 0, 0, S::npos); + test(S(""), "oselktgbca", 0, 1, S::npos); + test(S(""), "eqgaplhckj", 0, 5, S::npos); + test(S(""), "bjahtcmnlp", 0, 9, S::npos); + test(S(""), "hjlcmgpket", 0, 10, S::npos); + test(S(""), "htaobedqikfplcgjsmrn", 0, 0, S::npos); + test(S(""), "hpqiarojkcdlsgnmfetb", 0, 1, S::npos); + test(S(""), "dfkaprhjloqetcsimnbg", 0, 10, S::npos); + test(S(""), "ihqrfebgadntlpmjksoc", 0, 19, S::npos); + test(S(""), "ngtjfcalbseiqrphmkdo", 0, 20, S::npos); + test(S(""), "", 1, 0, S::npos); + test(S(""), "lbtqd", 1, 0, S::npos); + test(S(""), "tboim", 1, 1, S::npos); + test(S(""), "slcer", 1, 2, S::npos); + test(S(""), "cbjfs", 1, 4, S::npos); + test(S(""), "aqibs", 1, 5, S::npos); + test(S(""), "gtfblmqinc", 1, 0, S::npos); + test(S(""), "mkqpbtdalg", 1, 1, S::npos); + test(S(""), "kphatlimcd", 1, 5, S::npos); + test(S(""), "pblasqogic", 1, 9, S::npos); + test(S(""), "arosdhcfme", 1, 10, S::npos); + test(S(""), "blkhjeogicatqfnpdmsr", 1, 0, S::npos); + test(S(""), "bmhineprjcoadgstflqk", 1, 1, S::npos); + test(S(""), "djkqcmetslnghpbarfoi", 1, 10, S::npos); + test(S(""), "lgokshjtpbemarcdqnfi", 1, 19, S::npos); + test(S(""), "bqjhtkfepimcnsgrlado", 1, 20, S::npos); + test(S("eaint"), "", 0, 0, S::npos); + test(S("binja"), "gfsrt", 0, 0, S::npos); + test(S("latkm"), "pfsoc", 0, 1, S::npos); + test(S("lecfr"), "tpflm", 0, 2, S::npos); + test(S("eqkst"), "sgkec", 0, 4, 0); + test(S("cdafr"), "romds", 0, 5, 1); + test(S("prbhe"), "qhjistlgmr", 0, 0, S::npos); + test(S("lbisk"), "pedfirsglo", 0, 1, S::npos); + test(S("hrlpd"), "aqcoslgrmk", 0, 5, S::npos); + test(S("ehmja"), "dabckmepqj", 0, 9, 0); + test(S("mhqgd"), "pqscrjthli", 0, 10, 1); + test(S("tgklq"), "kfphdcsjqmobliagtren", 0, 0, S::npos); + test(S("bocjs"), "rokpefncljibsdhqtagm", 0, 1, S::npos); + test(S("grbsd"), "afionmkphlebtcjqsgrd", 0, 10, S::npos); + test(S("ofjqr"), "aenmqplidhkofrjbctsg", 0, 19, 0); + test(S("btlfi"), "osjmbtcadhiklegrpqnf", 0, 20, 0); + test(S("clrgb"), "", 1, 0, S::npos); + test(S("tjmek"), "osmia", 1, 0, S::npos); + test(S("bgstp"), "ckonl", 1, 1, S::npos); + test(S("hstrk"), "ilcaj", 1, 2, S::npos); + test(S("kmspj"), "lasiq", 1, 4, 2); + test(S("tjboh"), "kfqmr", 1, 5, S::npos); + test(S("ilbcj"), "klnitfaobg", 1, 0, S::npos); + test(S("jkngf"), "gjhmdlqikp", 1, 1, 3); + test(S("gfcql"), "skbgtahqej", 1, 5, S::npos); + test(S("dqtlg"), "bjsdgtlpkf", 1, 9, 2); + test(S("bthpg"), "bjgfmnlkio", 1, 10, 4); + test(S("dgsnq"), "lbhepotfsjdqigcnamkr", 1, 0, S::npos); + test(S("rmfhp"), "tebangckmpsrqdlfojhi", 1, 1, S::npos); + test(S("jfdam"), "joflqbdkhtegimscpanr", 1, 10, 1); + test(S("edapb"), "adpmcohetfbsrjinlqkg", 1, 19, 1); + test(S("brfsm"), "iacldqjpfnogbsrhmetk", 1, 20, 1); + test(S("ndrhl"), "", 2, 0, S::npos); + test(S("mrecp"), "otkgb", 2, 0, S::npos); + test(S("qlasf"), "cqsjl", 2, 1, S::npos); + test(S("smaqd"), "dpifl", 2, 2, 4); + test(S("hjeni"), "oapht", 2, 4, S::npos); + test(S("ocmfj"), "cifts", 2, 5, 3); + test(S("hmftq"), "nmsckbgalo", 2, 0, S::npos); + test(S("fklad"), "tpksqhamle", 2, 1, S::npos); + test(S("dirnm"), "tpdrchmkji", 2, 5, 2); + test(S("hrgdc"), "ijagfkblst", 2, 9, 2); + test(S("ifakg"), "kpocsignjb", 2, 10, 3); + test(S("ebrgd"), "pecqtkjsnbdrialgmohf", 2, 0, S::npos); + test(S("rcjml"), "aiortphfcmkjebgsndql", 2, 1, S::npos); + test(S("peqmt"), "sdbkeamglhipojqftrcn", 2, 10, 3); + test(S("frehn"), "ljqncehgmfktroapidbs", 2, 19, 2); + test(S("tqolf"), "rtcfodilamkbenjghqps", 2, 20, 2); + test(S("cjgao"), "", 4, 0, S::npos); + test(S("kjplq"), "mabns", 4, 0, S::npos); + test(S("herni"), "bdnrp", 4, 1, S::npos); + test(S("tadrb"), "scidp", 4, 2, S::npos); + test(S("pkfeo"), "agbjl", 4, 4, S::npos); + test(S("hoser"), "jfmpr", 4, 5, 4); + test(S("kgrsp"), "rbpefghsmj", 4, 0, S::npos); + test(S("pgejb"), "apsfntdoqc", 4, 1, S::npos); + test(S("thlnq"), "ndkjeisgcl", 4, 5, S::npos); + test(S("nbmit"), "rnfpqatdeo", 4, 9, 4); + test(S("jgmib"), "bntjlqrfik", 4, 10, 4); + test(S("ncrfj"), "kcrtmpolnaqejghsfdbi", 4, 0, S::npos); + test(S("ncsik"), "lobheanpkmqidsrtcfgj", 4, 1, S::npos); + test(S("sgbfh"), "athdkljcnreqbgpmisof", 4, 10, 4); + test(S("dktbn"), "qkdmjialrscpbhefgont", 4, 19, 4); + test(S("fthqm"), "dmasojntqleribkgfchp", 4, 20, 4); + test(S("klopi"), "", 5, 0, S::npos); + test(S("dajhn"), "psthd", 5, 0, S::npos); + test(S("jbgno"), "rpmjd", 5, 1, S::npos); + test(S("hkjae"), "dfsmk", 5, 2, S::npos); +} + +template +void test1() +{ + test(S("gbhqo"), "skqne", 5, 4, S::npos); + test(S("ktdor"), "kipnf", 5, 5, S::npos); + test(S("ldprn"), "hmrnqdgifl", 5, 0, S::npos); + test(S("egmjk"), "fsmjcdairn", 5, 1, S::npos); + test(S("armql"), "pcdgltbrfj", 5, 5, S::npos); + test(S("cdhjo"), "aekfctpirg", 5, 9, S::npos); + test(S("jcons"), "ledihrsgpf", 5, 10, S::npos); + test(S("cbrkp"), "mqcklahsbtirgopefndj", 5, 0, S::npos); + test(S("fhgna"), "kmlthaoqgecrnpdbjfis", 5, 1, S::npos); + test(S("ejfcd"), "sfhbamcdptojlkrenqgi", 5, 10, S::npos); + test(S("kqjhe"), "pbniofmcedrkhlstgaqj", 5, 19, S::npos); + test(S("pbdjl"), "mongjratcskbhqiepfdl", 5, 20, S::npos); + test(S("gajqn"), "", 6, 0, S::npos); + test(S("stedk"), "hrnat", 6, 0, S::npos); + test(S("tjkaf"), "gsqdt", 6, 1, S::npos); + test(S("dthpe"), "bspkd", 6, 2, S::npos); + test(S("klhde"), "ohcmb", 6, 4, S::npos); + test(S("bhlki"), "heatr", 6, 5, S::npos); + test(S("lqmoh"), "pmblckedfn", 6, 0, S::npos); + test(S("mtqin"), "aceqmsrbik", 6, 1, S::npos); + test(S("dpqbr"), "lmbtdehjrn", 6, 5, S::npos); + test(S("kdhmo"), "teqmcrlgib", 6, 9, S::npos); + test(S("jblqp"), "njolbmspac", 6, 10, S::npos); + test(S("qmjgl"), "pofnhidklamecrbqjgst", 6, 0, S::npos); + test(S("rothp"), "jbhckmtgrqnosafedpli", 6, 1, S::npos); + test(S("ghknq"), "dobntpmqklicsahgjerf", 6, 10, S::npos); + test(S("eopfi"), "tpdshainjkbfoemlrgcq", 6, 19, S::npos); + test(S("dsnmg"), "oldpfgeakrnitscbjmqh", 6, 20, S::npos); + test(S("jnkrfhotgl"), "", 0, 0, S::npos); + test(S("dltjfngbko"), "rqegt", 0, 0, S::npos); + test(S("bmjlpkiqde"), "dashm", 0, 1, 8); + test(S("skrflobnqm"), "jqirk", 0, 2, 8); + test(S("jkpldtshrm"), "rckeg", 0, 4, 1); + test(S("ghasdbnjqo"), "jscie", 0, 5, 3); + test(S("igrkhpbqjt"), "efsphndliq", 0, 0, S::npos); + test(S("ikthdgcamf"), "gdicosleja", 0, 1, 5); + test(S("pcofgeniam"), "qcpjibosfl", 0, 5, 0); + test(S("rlfjgesqhc"), "lrhmefnjcq", 0, 9, 0); + test(S("itphbqsker"), "dtablcrseo", 0, 10, 1); + test(S("skjafcirqm"), "apckjsftedbhgomrnilq", 0, 0, S::npos); + test(S("tcqomarsfd"), "pcbrgflehjtiadnsokqm", 0, 1, S::npos); + test(S("rocfeldqpk"), "nsiadegjklhobrmtqcpf", 0, 10, 4); + test(S("cfpegndlkt"), "cpmajdqnolikhgsbretf", 0, 19, 0); + test(S("fqbtnkeasj"), "jcflkntmgiqrphdosaeb", 0, 20, 0); + test(S("shbcqnmoar"), "", 1, 0, S::npos); + test(S("bdoshlmfin"), "ontrs", 1, 0, S::npos); + test(S("khfrebnsgq"), "pfkna", 1, 1, S::npos); + test(S("getcrsaoji"), "ekosa", 1, 2, 1); + test(S("fjiknedcpq"), "anqhk", 1, 4, 4); + test(S("tkejgnafrm"), "jekca", 1, 5, 1); + test(S("jnakolqrde"), "ikemsjgacf", 1, 0, S::npos); + test(S("lcjptsmgbe"), "arolgsjkhm", 1, 1, S::npos); + test(S("itfsmcjorl"), "oftkbldhre", 1, 5, 1); + test(S("omchkfrjea"), "gbkqdoeftl", 1, 9, 4); + test(S("cigfqkated"), "sqcflrgtim", 1, 10, 1); + test(S("tscenjikml"), "fmhbkislrjdpanogqcet", 1, 0, S::npos); + test(S("qcpaemsinf"), "rnioadktqlgpbcjsmhef", 1, 1, S::npos); + test(S("gltkojeipd"), "oakgtnldpsefihqmjcbr", 1, 10, 1); + test(S("qistfrgnmp"), "gbnaelosidmcjqktfhpr", 1, 19, 1); + test(S("bdnpfcqaem"), "akbripjhlosndcmqgfet", 1, 20, 1); + test(S("ectnhskflp"), "", 5, 0, S::npos); + test(S("fgtianblpq"), "pijag", 5, 0, S::npos); + test(S("mfeqklirnh"), "jrckd", 5, 1, S::npos); + test(S("astedncjhk"), "qcloh", 5, 2, 6); + test(S("fhlqgcajbr"), "thlmp", 5, 4, S::npos); + test(S("epfhocmdng"), "qidmo", 5, 5, 6); + test(S("apcnsibger"), "lnegpsjqrd", 5, 0, S::npos); + test(S("aqkocrbign"), "rjqdablmfs", 5, 1, 5); + test(S("ijsmdtqgce"), "enkgpbsjaq", 5, 5, 7); + test(S("clobgsrken"), "kdsgoaijfh", 5, 9, 5); + test(S("jbhcfposld"), "trfqgmckbe", 5, 10, S::npos); + test(S("oqnpblhide"), "igetsracjfkdnpoblhqm", 5, 0, S::npos); + test(S("lroeasctif"), "nqctfaogirshlekbdjpm", 5, 1, S::npos); + test(S("bpjlgmiedh"), "csehfgomljdqinbartkp", 5, 10, 5); + test(S("pamkeoidrj"), "qahoegcmplkfsjbdnitr", 5, 19, 5); + test(S("espogqbthk"), "dpteiajrqmsognhlfbkc", 5, 20, 5); + test(S("shoiedtcjb"), "", 9, 0, S::npos); + test(S("ebcinjgads"), "tqbnh", 9, 0, S::npos); + test(S("dqmregkcfl"), "akmle", 9, 1, S::npos); + test(S("ngcrieqajf"), "iqfkm", 9, 2, S::npos); + test(S("qosmilgnjb"), "tqjsr", 9, 4, S::npos); + test(S("ikabsjtdfl"), "jplqg", 9, 5, 9); + test(S("ersmicafdh"), "oilnrbcgtj", 9, 0, S::npos); + test(S("fdnplotmgh"), "morkglpesn", 9, 1, S::npos); + test(S("fdbicojerm"), "dmicerngat", 9, 5, 9); + test(S("mbtafndjcq"), "radgeskbtc", 9, 9, S::npos); + test(S("mlenkpfdtc"), "ljikprsmqo", 9, 10, S::npos); + test(S("ahlcifdqgs"), "trqihkcgsjamfdbolnpe", 9, 0, S::npos); + test(S("bgjemaltks"), "lqmthbsrekajgnofcipd", 9, 1, S::npos); + test(S("pdhslbqrfc"), "jtalmedribkgqsopcnfh", 9, 10, S::npos); + test(S("dirhtsnjkc"), "spqfoiclmtagejbndkrh", 9, 19, 9); + test(S("dlroktbcja"), "nmotklspigjrdhcfaebq", 9, 20, 9); + test(S("ncjpmaekbs"), "", 10, 0, S::npos); + test(S("hlbosgmrak"), "hpmsd", 10, 0, S::npos); + test(S("pqfhsgilen"), "qnpor", 10, 1, S::npos); + test(S("gqtjsbdckh"), "otdma", 10, 2, S::npos); + test(S("cfkqpjlegi"), "efhjg", 10, 4, S::npos); + test(S("beanrfodgj"), "odpte", 10, 5, S::npos); + test(S("adtkqpbjfi"), "bctdgfmolr", 10, 0, S::npos); + test(S("iomkfthagj"), "oaklidrbqg", 10, 1, S::npos); +} + +template +void test2() +{ + test(S("sdpcilonqj"), "dnjfsagktr", 10, 5, S::npos); + test(S("gtfbdkqeml"), "nejaktmiqg", 10, 9, S::npos); + test(S("bmeqgcdorj"), "pjqonlebsf", 10, 10, S::npos); + test(S("etqlcanmob"), "dshmnbtolcjepgaikfqr", 10, 0, S::npos); + test(S("roqmkbdtia"), "iogfhpabtjkqlrnemcds", 10, 1, S::npos); + test(S("kadsithljf"), "ngridfabjsecpqltkmoh", 10, 10, S::npos); + test(S("sgtkpbfdmh"), "athmknplcgofrqejsdib", 10, 19, S::npos); + test(S("qgmetnabkl"), "ldobhmqcafnjtkeisgrp", 10, 20, S::npos); + test(S("cqjohampgd"), "", 11, 0, S::npos); + test(S("hobitmpsan"), "aocjb", 11, 0, S::npos); + test(S("tjehkpsalm"), "jbrnk", 11, 1, S::npos); + test(S("ngfbojitcl"), "tqedg", 11, 2, S::npos); + test(S("rcfkdbhgjo"), "nqskp", 11, 4, S::npos); + test(S("qghptonrea"), "eaqkl", 11, 5, S::npos); + test(S("hnprfgqjdl"), "reaoicljqm", 11, 0, S::npos); + test(S("hlmgabenti"), "lsftgajqpm", 11, 1, S::npos); + test(S("ofcjanmrbs"), "rlpfogmits", 11, 5, S::npos); + test(S("jqedtkornm"), "shkncmiaqj", 11, 9, S::npos); + test(S("rfedlasjmg"), "fpnatrhqgs", 11, 10, S::npos); + test(S("talpqjsgkm"), "sjclemqhnpdbgikarfot", 11, 0, S::npos); + test(S("lrkcbtqpie"), "otcmedjikgsfnqbrhpla", 11, 1, S::npos); + test(S("cipogdskjf"), "bonsaefdqiprkhlgtjcm", 11, 10, S::npos); + test(S("nqedcojahi"), "egpscmahijlfnkrodqtb", 11, 19, S::npos); + test(S("hefnrkmctj"), "kmqbfepjthgilscrndoa", 11, 20, S::npos); + test(S("atqirnmekfjolhpdsgcb"), "", 0, 0, S::npos); + test(S("echfkmlpribjnqsaogtd"), "prboq", 0, 0, S::npos); + test(S("qnhiftdgcleajbpkrosm"), "fjcqh", 0, 1, 4); + test(S("chamfknorbedjitgslpq"), "fmosa", 0, 2, 3); + test(S("njhqpibfmtlkaecdrgso"), "qdbok", 0, 4, 3); + test(S("ebnghfsqkprmdcljoiat"), "amslg", 0, 5, 3); + test(S("letjomsgihfrpqbkancd"), "smpltjneqb", 0, 0, S::npos); + test(S("nblgoipcrqeaktshjdmf"), "flitskrnge", 0, 1, 19); + test(S("cehkbngtjoiflqapsmrd"), "pgqihmlbef", 0, 5, 2); + test(S("mignapfoklbhcqjetdrs"), "cfpdqjtgsb", 0, 9, 2); + test(S("ceatbhlsqjgpnokfrmdi"), "htpsiaflom", 0, 10, 2); + test(S("ocihkjgrdelpfnmastqb"), "kpjfiaceghsrdtlbnomq", 0, 0, S::npos); + test(S("noelgschdtbrjfmiqkap"), "qhtbomidljgafneksprc", 0, 1, 16); + test(S("dkclqfombepritjnghas"), "nhtjobkcefldimpsaqgr", 0, 10, 1); + test(S("miklnresdgbhqcojftap"), "prabcjfqnoeskilmtgdh", 0, 19, 0); + test(S("htbcigojaqmdkfrnlsep"), "dtrgmchilkasqoebfpjn", 0, 20, 0); + test(S("febhmqtjanokscdirpgl"), "", 1, 0, S::npos); + test(S("loakbsqjpcrdhftniegm"), "sqome", 1, 0, S::npos); + test(S("reagphsqflbitdcjmkno"), "smfte", 1, 1, 6); + test(S("jitlfrqemsdhkopncabg"), "ciboh", 1, 2, 1); + test(S("mhtaepscdnrjqgbkifol"), "haois", 1, 4, 1); + test(S("tocesrfmnglpbjihqadk"), "abfki", 1, 5, 6); + test(S("lpfmctjrhdagneskbqoi"), "frdkocntmq", 1, 0, S::npos); + test(S("lsmqaepkdhncirbtjfgo"), "oasbpedlnr", 1, 1, 19); + test(S("epoiqmtldrabnkjhcfsg"), "kltqmhgand", 1, 5, 4); + test(S("emgasrilpknqojhtbdcf"), "gdtfjchpmr", 1, 9, 1); + test(S("hnfiagdpcklrjetqbsom"), "ponmcqblet", 1, 10, 1); + test(S("nsdfebgajhmtricpoklq"), "sgphqdnofeiklatbcmjr", 1, 0, S::npos); + test(S("atjgfsdlpobmeiqhncrk"), "ljqprsmigtfoneadckbh", 1, 1, 7); + test(S("sitodfgnrejlahcbmqkp"), "ligeojhafnkmrcsqtbdp", 1, 10, 1); + test(S("fraghmbiceknltjpqosd"), "lsimqfnjarbopedkhcgt", 1, 19, 1); + test(S("pmafenlhqtdbkirjsogc"), "abedmfjlghniorcqptks", 1, 20, 1); + test(S("pihgmoeqtnakrjslcbfd"), "", 10, 0, S::npos); + test(S("gjdkeprctqblnhiafsom"), "hqtoa", 10, 0, S::npos); + test(S("mkpnblfdsahrcqijteog"), "cahif", 10, 1, 12); + test(S("gckarqnelodfjhmbptis"), "kehis", 10, 2, S::npos); + test(S("gqpskidtbclomahnrjfe"), "kdlmh", 10, 4, 10); + test(S("pkldjsqrfgitbhmaecno"), "paeql", 10, 5, 15); + test(S("aftsijrbeklnmcdqhgop"), "aghoqiefnb", 10, 0, S::npos); + test(S("mtlgdrhafjkbiepqnsoc"), "jrbqaikpdo", 10, 1, S::npos); + test(S("pqgirnaefthokdmbsclj"), "smjonaeqcl", 10, 5, 11); + test(S("kpdbgjmtherlsfcqoina"), "eqbdrkcfah", 10, 9, 10); + test(S("jrlbothiknqmdgcfasep"), "kapmsienhf", 10, 10, 11); + test(S("mjogldqferckabinptsh"), "jpqotrlenfcsbhkaimdg", 10, 0, S::npos); + test(S("apoklnefbhmgqcdrisjt"), "jlbmhnfgtcqprikeados", 10, 1, 18); + test(S("ifeopcnrjbhkdgatmqls"), "stgbhfmdaljnpqoicker", 10, 10, 10); + test(S("ckqhaiesmjdnrgolbtpf"), "oihcetflbjagdsrkmqpn", 10, 19, 10); + test(S("bnlgapfimcoterskqdjh"), "adtclebmnpjsrqfkigoh", 10, 20, 10); + test(S("kgdlrobpmjcthqsafeni"), "", 19, 0, S::npos); + test(S("dfkechomjapgnslbtqir"), "beafg", 19, 0, S::npos); + test(S("rloadknfbqtgmhcsipje"), "iclat", 19, 1, S::npos); + test(S("mgjhkolrnadqbpetcifs"), "rkhnf", 19, 2, S::npos); + test(S("cmlfakiojdrgtbsphqen"), "clshq", 19, 4, S::npos); + test(S("kghbfipeomsntdalrqjc"), "dtcoj", 19, 5, 19); + test(S("eldiqckrnmtasbghjfpo"), "rqosnjmfth", 19, 0, S::npos); + test(S("abqjcfedgotihlnspkrm"), "siatdfqglh", 19, 1, S::npos); + test(S("qfbadrtjsimkolcenhpg"), "mrlshtpgjq", 19, 5, S::npos); + test(S("abseghclkjqifmtodrnp"), "adlcskgqjt", 19, 9, S::npos); + test(S("ibmsnlrjefhtdokacqpg"), "drshcjknaf", 19, 10, S::npos); + test(S("mrkfciqjebaponsthldg"), "etsaqroinghpkjdlfcbm", 19, 0, S::npos); + test(S("mjkticdeoqshpalrfbgn"), "sgepdnkqliambtrocfhj", 19, 1, S::npos); + test(S("rqnoclbdejgiphtfsakm"), "nlmcjaqgbsortfdihkpe", 19, 10, 19); + test(S("plkqbhmtfaeodjcrsing"), "racfnpmosldibqkghjet", 19, 19, 19); + test(S("oegalhmstjrfickpbndq"), "fjhdsctkqeiolagrnmbp", 19, 20, 19); + test(S("rdtgjcaohpblniekmsfq"), "", 20, 0, S::npos); + test(S("ofkqbnjetrmsaidphglc"), "ejanp", 20, 0, S::npos); + test(S("grkpahljcftesdmonqib"), "odife", 20, 1, S::npos); + test(S("jimlgbhfqkteospardcn"), "okaqd", 20, 2, S::npos); + test(S("gftenihpmslrjkqadcob"), "lcdbi", 20, 4, S::npos); + test(S("bmhldogtckrfsanijepq"), "fsqbj", 20, 5, S::npos); + test(S("nfqkrpjdesabgtlcmoih"), "bigdomnplq", 20, 0, S::npos); + test(S("focalnrpiqmdkstehbjg"), "apiblotgcd", 20, 1, S::npos); + test(S("rhqdspkmebiflcotnjga"), "acfhdenops", 20, 5, S::npos); + test(S("rahdtmsckfboqlpniegj"), "jopdeamcrk", 20, 9, S::npos); + test(S("fbkeiopclstmdqranjhg"), "trqncbkgmh", 20, 10, S::npos); + test(S("lifhpdgmbconstjeqark"), "tomglrkencbsfjqpihda", 20, 0, S::npos); +} + +template +void test3() +{ + test(S("pboqganrhedjmltsicfk"), "gbkhdnpoietfcmrslajq", 20, 1, S::npos); + test(S("klchabsimetjnqgorfpd"), "rtfnmbsglkjaichoqedp", 20, 10, S::npos); + test(S("sirfgmjqhctndbklaepo"), "ohkmdpfqbsacrtjnlgei", 20, 19, S::npos); + test(S("rlbdsiceaonqjtfpghkm"), "dlbrteoisgphmkncajfq", 20, 20, S::npos); + test(S("ecgdanriptblhjfqskom"), "", 21, 0, S::npos); + test(S("fdmiarlpgcskbhoteqjn"), "sjrlo", 21, 0, S::npos); + test(S("rlbstjqopignecmfadkh"), "qjpor", 21, 1, S::npos); + test(S("grjpqmbshektdolcafni"), "odhfn", 21, 2, S::npos); + test(S("sakfcohtqnibprjmlged"), "qtfin", 21, 4, S::npos); + test(S("mjtdglasihqpocebrfkn"), "hpqfo", 21, 5, S::npos); + test(S("okaplfrntghqbmeicsdj"), "fabmertkos", 21, 0, S::npos); + test(S("sahngemrtcjidqbklfpo"), "brqtgkmaej", 21, 1, S::npos); + test(S("dlmsipcnekhbgoaftqjr"), "nfrdeihsgl", 21, 5, S::npos); + test(S("ahegrmqnoiklpfsdbcjt"), "hlfrosekpi", 21, 9, S::npos); + test(S("hdsjbnmlegtkqripacof"), "atgbkrjdsm", 21, 10, S::npos); + test(S("pcnedrfjihqbalkgtoms"), "blnrptjgqmaifsdkhoec", 21, 0, S::npos); + test(S("qjidealmtpskrbfhocng"), "ctpmdahebfqjgknloris", 21, 1, S::npos); + test(S("qeindtagmokpfhsclrbj"), "apnkeqthrmlbfodiscgj", 21, 10, S::npos); + test(S("kpfegbjhsrnodltqciam"), "jdgictpframeoqlsbknh", 21, 19, S::npos); + test(S("hnbrcplsjfgiktoedmaq"), "qprlsfojamgndekthibc", 21, 20, S::npos); +} + +int main() +{ + { + typedef std::string S; + test0(); + test1(); + test2(); + test3(); + } +#if TEST_STD_VER >= 11 + { + typedef std::basic_string, min_allocator> S; + test0(); + test1(); + test2(); + test3(); + } +#endif +} diff --git a/tests/external/libcxx/basic_string/string.ops/string_find.first.of/string_size.pass.cpp b/tests/external/libcxx/basic_string/string.ops/string_find.first.of/string_size.pass.cpp new file mode 100644 index 0000000..105c2a6 --- /dev/null +++ b/tests/external/libcxx/basic_string/string.ops/string_find.first.of/string_size.pass.cpp @@ -0,0 +1,165 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// + +// size_type find_first_of(const basic_string& str, size_type pos = 0) const; + +#include +#include + +#include "test_macros.h" +#include "min_allocator.h" + +template +void +test(const S& s, const S& str, typename S::size_type pos, typename S::size_type x) +{ + assert(s.find_first_of(str, pos) == x); + if (x != S::npos) + assert(pos <= x && x < s.size()); +} + +template +void +test(const S& s, const S& str, typename S::size_type x) +{ + assert(s.find_first_of(str) == x); + if (x != S::npos) + assert(x < s.size()); +} + +template +void test0() +{ + test(S(""), S(""), 0, S::npos); + test(S(""), S("laenf"), 0, S::npos); + test(S(""), S("pqlnkmbdjo"), 0, S::npos); + test(S(""), S("qkamfogpnljdcshbreti"), 0, S::npos); + test(S(""), S(""), 1, S::npos); + test(S(""), S("bjaht"), 1, S::npos); + test(S(""), S("hjlcmgpket"), 1, S::npos); + test(S(""), S("htaobedqikfplcgjsmrn"), 1, S::npos); + test(S("fodgq"), S(""), 0, S::npos); + test(S("qanej"), S("dfkap"), 0, 1); + test(S("clbao"), S("ihqrfebgad"), 0, 2); + test(S("mekdn"), S("ngtjfcalbseiqrphmkdo"), 0, 0); + test(S("srdfq"), S(""), 1, S::npos); + test(S("oemth"), S("ikcrq"), 1, S::npos); + test(S("cdaih"), S("dmajblfhsg"), 1, 1); + test(S("qohtk"), S("oqftjhdmkgsblacenirp"), 1, 1); + test(S("cshmd"), S(""), 2, S::npos); + test(S("lhcdo"), S("oebqi"), 2, 4); + test(S("qnsoh"), S("kojhpmbsfe"), 2, 2); + test(S("pkrof"), S("acbsjqogpltdkhinfrem"), 2, 2); + test(S("fmtsp"), S(""), 4, S::npos); + test(S("khbpm"), S("aobjd"), 4, S::npos); + test(S("pbsji"), S("pcbahntsje"), 4, S::npos); + test(S("mprdj"), S("fhepcrntkoagbmldqijs"), 4, 4); + test(S("eqmpa"), S(""), 5, S::npos); + test(S("omigs"), S("kocgb"), 5, S::npos); + test(S("onmje"), S("fbslrjiqkm"), 5, S::npos); + test(S("oqmrj"), S("jeidpcmalhfnqbgtrsko"), 5, S::npos); + test(S("schfa"), S(""), 6, S::npos); + test(S("igdsc"), S("qngpd"), 6, S::npos); + test(S("brqgo"), S("rodhqklgmb"), 6, S::npos); + test(S("tnrph"), S("thdjgafrlbkoiqcspmne"), 6, S::npos); + test(S("hcjitbfapl"), S(""), 0, S::npos); + test(S("daiprenocl"), S("ashjd"), 0, 0); + test(S("litpcfdghe"), S("mgojkldsqh"), 0, 0); + test(S("aidjksrolc"), S("imqnaghkfrdtlopbjesc"), 0, 0); + test(S("qpghtfbaji"), S(""), 1, S::npos); + test(S("gfshlcmdjr"), S("nadkh"), 1, 3); + test(S("nkodajteqp"), S("ofdrqmkebl"), 1, 1); + test(S("gbmetiprqd"), S("bdfjqgatlksriohemnpc"), 1, 1); + test(S("crnklpmegd"), S(""), 5, S::npos); + test(S("jsbtafedoc"), S("prqgn"), 5, S::npos); + test(S("qnmodrtkeb"), S("pejafmnokr"), 5, 5); + test(S("cpebqsfmnj"), S("odnqkgijrhabfmcestlp"), 5, 5); + test(S("lmofqdhpki"), S(""), 9, S::npos); + test(S("hnefkqimca"), S("rtjpa"), 9, 9); + test(S("drtasbgmfp"), S("ktsrmnqagd"), 9, S::npos); + test(S("lsaijeqhtr"), S("rtdhgcisbnmoaqkfpjle"), 9, 9); + test(S("elgofjmbrq"), S(""), 10, S::npos); + test(S("mjqdgalkpc"), S("dplqa"), 10, S::npos); + test(S("kthqnfcerm"), S("dkacjoptns"), 10, S::npos); + test(S("dfsjhanorc"), S("hqfimtrgnbekpdcsjalo"), 10, S::npos); + test(S("eqsgalomhb"), S(""), 11, S::npos); + test(S("akiteljmoh"), S("lofbc"), 11, S::npos); + test(S("hlbdfreqjo"), S("astoegbfpn"), 11, S::npos); + test(S("taqobhlerg"), S("pdgreqomsncafklhtibj"), 11, S::npos); + test(S("snafbdlghrjkpqtoceim"), S(""), 0, S::npos); + test(S("aemtbrgcklhndjisfpoq"), S("lbtqd"), 0, 3); + test(S("pnracgfkjdiholtbqsem"), S("tboimldpjh"), 0, 0); + test(S("dicfltehbsgrmojnpkaq"), S("slcerthdaiqjfnobgkpm"), 0, 0); + test(S("jlnkraeodhcspfgbqitm"), S(""), 1, S::npos); + test(S("lhosrngtmfjikbqpcade"), S("aqibs"), 1, 3); + test(S("rbtaqjhgkneisldpmfoc"), S("gtfblmqinc"), 1, 1); + test(S("gpifsqlrdkbonjtmheca"), S("mkqpbtdalgniorhfescj"), 1, 1); + test(S("hdpkobnsalmcfijregtq"), S(""), 10, S::npos); + test(S("jtlshdgqaiprkbcoenfm"), S("pblas"), 10, 10); + test(S("fkdrbqltsgmcoiphneaj"), S("arosdhcfme"), 10, 10); + test(S("crsplifgtqedjohnabmk"), S("blkhjeogicatqfnpdmsr"), 10, 10); + test(S("niptglfbosehkamrdqcj"), S(""), 19, S::npos); + test(S("copqdhstbingamjfkler"), S("djkqc"), 19, S::npos); + test(S("mrtaefilpdsgocnhqbjk"), S("lgokshjtpb"), 19, 19); + test(S("kojatdhlcmigpbfrqnes"), S("bqjhtkfepimcnsgrlado"), 19, 19); + test(S("eaintpchlqsbdgrkjofm"), S(""), 20, S::npos); + test(S("gjnhidfsepkrtaqbmclo"), S("nocfa"), 20, S::npos); + test(S("spocfaktqdbiejlhngmr"), S("bgtajmiedc"), 20, S::npos); + test(S("rphmlekgfscndtaobiqj"), S("lsckfnqgdahejiopbtmr"), 20, S::npos); + test(S("liatsqdoegkmfcnbhrpj"), S(""), 21, S::npos); + test(S("binjagtfldkrspcomqeh"), S("gfsrt"), 21, S::npos); + test(S("latkmisecnorjbfhqpdg"), S("pfsocbhjtm"), 21, S::npos); + test(S("lecfratdjkhnsmqpoigb"), S("tpflmdnoicjgkberhqsa"), 21, S::npos); +} + +template +void test1() +{ + test(S(""), S(""), S::npos); + test(S(""), S("laenf"), S::npos); + test(S(""), S("pqlnkmbdjo"), S::npos); + test(S(""), S("qkamfogpnljdcshbreti"), S::npos); + test(S("nhmko"), S(""), S::npos); + test(S("lahfb"), S("irkhs"), 2); + test(S("gmfhd"), S("kantesmpgj"), 0); + test(S("odaft"), S("oknlrstdpiqmjbaghcfe"), 0); + test(S("eolhfgpjqk"), S(""), S::npos); + test(S("nbatdlmekr"), S("bnrpe"), 0); + test(S("jdmciepkaq"), S("jtdaefblso"), 0); + test(S("hkbgspoflt"), S("oselktgbcapndfjihrmq"), 0); + test(S("gprdcokbnjhlsfmtieqa"), S(""), S::npos); + test(S("qjghlnftcaismkropdeb"), S("bjaht"), 1); + test(S("pnalfrdtkqcmojiesbhg"), S("hjlcmgpket"), 0); + test(S("pniotcfrhqsmgdkjbael"), S("htaobedqikfplcgjsmrn"), 0); +} + +int main() +{ + { + typedef std::string S; + test0(); + test1(); + } +#if TEST_STD_VER >= 11 + { + typedef std::basic_string, min_allocator> S; + test0(); + test1(); + } +#endif + +#if TEST_STD_VER > 3 + { // LWG 2946 + std::string s = " !"; + assert(s.find_first_of({"abc", 1}) == std::string::npos); + } +#endif +} diff --git a/tests/external/libcxx/basic_string/string.ops/string_find.first.of/string_view_size.pass.cpp b/tests/external/libcxx/basic_string/string.ops/string_find.first.of/string_view_size.pass.cpp new file mode 100644 index 0000000..05925af --- /dev/null +++ b/tests/external/libcxx/basic_string/string.ops/string_find.first.of/string_view_size.pass.cpp @@ -0,0 +1,159 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// + +// size_type find_first_of(const basic_string_view sv, size_type pos = 0) const; + +#include +#include + +#include "min_allocator.h" + +template +void +test(const S& s, SV sv, typename S::size_type pos, typename S::size_type x) +{ + assert(s.find_first_of(sv, pos) == x); + if (x != S::npos) + assert(pos <= x && x < s.size()); +} + +template +void +test(const S& s, SV sv, typename S::size_type x) +{ + assert(s.find_first_of(sv) == x); + if (x != S::npos) + assert(x < s.size()); +} + +template +void test0() +{ + test(S(""), SV(""), 0, S::npos); + test(S(""), SV("laenf"), 0, S::npos); + test(S(""), SV("pqlnkmbdjo"), 0, S::npos); + test(S(""), SV("qkamfogpnljdcshbreti"), 0, S::npos); + test(S(""), SV(""), 1, S::npos); + test(S(""), SV("bjaht"), 1, S::npos); + test(S(""), SV("hjlcmgpket"), 1, S::npos); + test(S(""), SV("htaobedqikfplcgjsmrn"), 1, S::npos); + test(S("fodgq"), SV(""), 0, S::npos); + test(S("qanej"), SV("dfkap"), 0, 1); + test(S("clbao"), SV("ihqrfebgad"), 0, 2); + test(S("mekdn"), SV("ngtjfcalbseiqrphmkdo"), 0, 0); + test(S("srdfq"), SV(""), 1, S::npos); + test(S("oemth"), SV("ikcrq"), 1, S::npos); + test(S("cdaih"), SV("dmajblfhsg"), 1, 1); + test(S("qohtk"), SV("oqftjhdmkgsblacenirp"), 1, 1); + test(S("cshmd"), SV(""), 2, S::npos); + test(S("lhcdo"), SV("oebqi"), 2, 4); + test(S("qnsoh"), SV("kojhpmbsfe"), 2, 2); + test(S("pkrof"), SV("acbsjqogpltdkhinfrem"), 2, 2); + test(S("fmtsp"), SV(""), 4, S::npos); + test(S("khbpm"), SV("aobjd"), 4, S::npos); + test(S("pbsji"), SV("pcbahntsje"), 4, S::npos); + test(S("mprdj"), SV("fhepcrntkoagbmldqijs"), 4, 4); + test(S("eqmpa"), SV(""), 5, S::npos); + test(S("omigs"), SV("kocgb"), 5, S::npos); + test(S("onmje"), SV("fbslrjiqkm"), 5, S::npos); + test(S("oqmrj"), SV("jeidpcmalhfnqbgtrsko"), 5, S::npos); + test(S("schfa"), SV(""), 6, S::npos); + test(S("igdsc"), SV("qngpd"), 6, S::npos); + test(S("brqgo"), SV("rodhqklgmb"), 6, S::npos); + test(S("tnrph"), SV("thdjgafrlbkoiqcspmne"), 6, S::npos); + test(S("hcjitbfapl"), SV(""), 0, S::npos); + test(S("daiprenocl"), SV("ashjd"), 0, 0); + test(S("litpcfdghe"), SV("mgojkldsqh"), 0, 0); + test(S("aidjksrolc"), SV("imqnaghkfrdtlopbjesc"), 0, 0); + test(S("qpghtfbaji"), SV(""), 1, S::npos); + test(S("gfshlcmdjr"), SV("nadkh"), 1, 3); + test(S("nkodajteqp"), SV("ofdrqmkebl"), 1, 1); + test(S("gbmetiprqd"), SV("bdfjqgatlksriohemnpc"), 1, 1); + test(S("crnklpmegd"), SV(""), 5, S::npos); + test(S("jsbtafedoc"), SV("prqgn"), 5, S::npos); + test(S("qnmodrtkeb"), SV("pejafmnokr"), 5, 5); + test(S("cpebqsfmnj"), SV("odnqkgijrhabfmcestlp"), 5, 5); + test(S("lmofqdhpki"), SV(""), 9, S::npos); + test(S("hnefkqimca"), SV("rtjpa"), 9, 9); + test(S("drtasbgmfp"), SV("ktsrmnqagd"), 9, S::npos); + test(S("lsaijeqhtr"), SV("rtdhgcisbnmoaqkfpjle"), 9, 9); + test(S("elgofjmbrq"), SV(""), 10, S::npos); + test(S("mjqdgalkpc"), SV("dplqa"), 10, S::npos); + test(S("kthqnfcerm"), SV("dkacjoptns"), 10, S::npos); + test(S("dfsjhanorc"), SV("hqfimtrgnbekpdcsjalo"), 10, S::npos); + test(S("eqsgalomhb"), SV(""), 11, S::npos); + test(S("akiteljmoh"), SV("lofbc"), 11, S::npos); + test(S("hlbdfreqjo"), SV("astoegbfpn"), 11, S::npos); + test(S("taqobhlerg"), SV("pdgreqomsncafklhtibj"), 11, S::npos); + test(S("snafbdlghrjkpqtoceim"), SV(""), 0, S::npos); + test(S("aemtbrgcklhndjisfpoq"), SV("lbtqd"), 0, 3); + test(S("pnracgfkjdiholtbqsem"), SV("tboimldpjh"), 0, 0); + test(S("dicfltehbsgrmojnpkaq"), SV("slcerthdaiqjfnobgkpm"), 0, 0); + test(S("jlnkraeodhcspfgbqitm"), SV(""), 1, S::npos); + test(S("lhosrngtmfjikbqpcade"), SV("aqibs"), 1, 3); + test(S("rbtaqjhgkneisldpmfoc"), SV("gtfblmqinc"), 1, 1); + test(S("gpifsqlrdkbonjtmheca"), SV("mkqpbtdalgniorhfescj"), 1, 1); + test(S("hdpkobnsalmcfijregtq"), SV(""), 10, S::npos); + test(S("jtlshdgqaiprkbcoenfm"), SV("pblas"), 10, 10); + test(S("fkdrbqltsgmcoiphneaj"), SV("arosdhcfme"), 10, 10); + test(S("crsplifgtqedjohnabmk"), SV("blkhjeogicatqfnpdmsr"), 10, 10); + test(S("niptglfbosehkamrdqcj"), SV(""), 19, S::npos); + test(S("copqdhstbingamjfkler"), SV("djkqc"), 19, S::npos); + test(S("mrtaefilpdsgocnhqbjk"), SV("lgokshjtpb"), 19, 19); + test(S("kojatdhlcmigpbfrqnes"), SV("bqjhtkfepimcnsgrlado"), 19, 19); + test(S("eaintpchlqsbdgrkjofm"), SV(""), 20, S::npos); + test(S("gjnhidfsepkrtaqbmclo"), SV("nocfa"), 20, S::npos); + test(S("spocfaktqdbiejlhngmr"), SV("bgtajmiedc"), 20, S::npos); + test(S("rphmlekgfscndtaobiqj"), SV("lsckfnqgdahejiopbtmr"), 20, S::npos); + test(S("liatsqdoegkmfcnbhrpj"), SV(""), 21, S::npos); + test(S("binjagtfldkrspcomqeh"), SV("gfsrt"), 21, S::npos); + test(S("latkmisecnorjbfhqpdg"), SV("pfsocbhjtm"), 21, S::npos); + test(S("lecfratdjkhnsmqpoigb"), SV("tpflmdnoicjgkberhqsa"), 21, S::npos); +} + +template +void test1() +{ + test(S(""), SV(""), S::npos); + test(S(""), SV("laenf"), S::npos); + test(S(""), SV("pqlnkmbdjo"), S::npos); + test(S(""), SV("qkamfogpnljdcshbreti"), S::npos); + test(S("nhmko"), SV(""), S::npos); + test(S("lahfb"), SV("irkhs"), 2); + test(S("gmfhd"), SV("kantesmpgj"), 0); + test(S("odaft"), SV("oknlrstdpiqmjbaghcfe"), 0); + test(S("eolhfgpjqk"), SV(""), S::npos); + test(S("nbatdlmekr"), SV("bnrpe"), 0); + test(S("jdmciepkaq"), SV("jtdaefblso"), 0); + test(S("hkbgspoflt"), SV("oselktgbcapndfjihrmq"), 0); + test(S("gprdcokbnjhlsfmtieqa"), SV(""), S::npos); + test(S("qjghlnftcaismkropdeb"), SV("bjaht"), 1); + test(S("pnalfrdtkqcmojiesbhg"), SV("hjlcmgpket"), 0); + test(S("pniotcfrhqsmgdkjbael"), SV("htaobedqikfplcgjsmrn"), 0); +} + +int main() +{ + { + typedef std::string S; + typedef std::string_view SV; + test0(); + test1(); + } +#if TEST_STD_VER >= 11 + { + typedef std::basic_string, min_allocator> S; + typedef std::string_view SV; + test0(); + test1(); + } +#endif +} diff --git a/tests/external/libcxx/basic_string/string.ops/string_find.last.not.of/char_size.pass.cpp b/tests/external/libcxx/basic_string/string.ops/string_find.last.not.of/char_size.pass.cpp new file mode 100644 index 0000000..3212389 --- /dev/null +++ b/tests/external/libcxx/basic_string/string.ops/string_find.last.not.of/char_size.pass.cpp @@ -0,0 +1,98 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// + +// size_type find_last_not_of(charT c, size_type pos = npos) const; + +#include +#include + +#include "min_allocator.h" + +template +void +test(const S& s, typename S::value_type c, typename S::size_type pos, + typename S::size_type x) +{ + assert(s.find_last_not_of(c, pos) == x); + if (x != S::npos) + assert(x <= pos && x < s.size()); +} + +template +void +test(const S& s, typename S::value_type c, typename S::size_type x) +{ + assert(s.find_last_not_of(c) == x); + if (x != S::npos) + assert(x < s.size()); +} + +int main() +{ + { + typedef std::string S; + test(S(""), 'i', 0, S::npos); + test(S(""), 'i', 1, S::npos); + test(S("kitcj"), 'i', 0, 0); + test(S("qkamf"), 'i', 1, 1); + test(S("nhmko"), 'i', 2, 2); + test(S("tpsaf"), 'i', 4, 4); + test(S("lahfb"), 'i', 5, 4); + test(S("irkhs"), 'i', 6, 4); + test(S("gmfhdaipsr"), 'i', 0, 0); + test(S("kantesmpgj"), 'i', 1, 1); + test(S("odaftiegpm"), 'i', 5, 4); + test(S("oknlrstdpi"), 'i', 9, 8); + test(S("eolhfgpjqk"), 'i', 10, 9); + test(S("pcdrofikas"), 'i', 11, 9); + test(S("nbatdlmekrgcfqsophij"), 'i', 0, 0); + test(S("bnrpehidofmqtcksjgla"), 'i', 1, 1); + test(S("jdmciepkaqgotsrfnhlb"), 'i', 10, 10); + test(S("jtdaefblsokrmhpgcnqi"), 'i', 19, 18); + test(S("hkbgspofltajcnedqmri"), 'i', 20, 18); + test(S("oselktgbcapndfjihrmq"), 'i', 21, 19); + + test(S(""), 'i', S::npos); + test(S("csope"), 'i', 4); + test(S("gfsmthlkon"), 'i', 9); + test(S("laenfsbridchgotmkqpj"), 'i', 19); + } +#if TEST_STD_VER >= 11 + { + typedef std::basic_string, min_allocator> S; + test(S(""), 'i', 0, S::npos); + test(S(""), 'i', 1, S::npos); + test(S("kitcj"), 'i', 0, 0); + test(S("qkamf"), 'i', 1, 1); + test(S("nhmko"), 'i', 2, 2); + test(S("tpsaf"), 'i', 4, 4); + test(S("lahfb"), 'i', 5, 4); + test(S("irkhs"), 'i', 6, 4); + test(S("gmfhdaipsr"), 'i', 0, 0); + test(S("kantesmpgj"), 'i', 1, 1); + test(S("odaftiegpm"), 'i', 5, 4); + test(S("oknlrstdpi"), 'i', 9, 8); + test(S("eolhfgpjqk"), 'i', 10, 9); + test(S("pcdrofikas"), 'i', 11, 9); + test(S("nbatdlmekrgcfqsophij"), 'i', 0, 0); + test(S("bnrpehidofmqtcksjgla"), 'i', 1, 1); + test(S("jdmciepkaqgotsrfnhlb"), 'i', 10, 10); + test(S("jtdaefblsokrmhpgcnqi"), 'i', 19, 18); + test(S("hkbgspofltajcnedqmri"), 'i', 20, 18); + test(S("oselktgbcapndfjihrmq"), 'i', 21, 19); + + test(S(""), 'i', S::npos); + test(S("csope"), 'i', 4); + test(S("gfsmthlkon"), 'i', 9); + test(S("laenfsbridchgotmkqpj"), 'i', 19); + } +#endif +} diff --git a/tests/external/libcxx/basic_string/string.ops/string_find.last.not.of/pointer_size.pass.cpp b/tests/external/libcxx/basic_string/string.ops/string_find.last.not.of/pointer_size.pass.cpp new file mode 100644 index 0000000..7dc7518 --- /dev/null +++ b/tests/external/libcxx/basic_string/string.ops/string_find.last.not.of/pointer_size.pass.cpp @@ -0,0 +1,158 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// + +// size_type find_last_not_of(const charT* s, size_type pos = npos) const; + +#include +#include + +#include "min_allocator.h" + +template +void +test(const S& s, const typename S::value_type* str, typename S::size_type pos, + typename S::size_type x) +{ + assert(s.find_last_not_of(str, pos) == x); + if (x != S::npos) + assert(x <= pos && x < s.size()); +} + +template +void +test(const S& s, const typename S::value_type* str, typename S::size_type x) +{ + assert(s.find_last_not_of(str) == x); + if (x != S::npos) + assert(x < s.size()); +} + +template +void test0() +{ + test(S(""), "", 0, S::npos); + test(S(""), "laenf", 0, S::npos); + test(S(""), "pqlnkmbdjo", 0, S::npos); + test(S(""), "qkamfogpnljdcshbreti", 0, S::npos); + test(S(""), "", 1, S::npos); + test(S(""), "bjaht", 1, S::npos); + test(S(""), "hjlcmgpket", 1, S::npos); + test(S(""), "htaobedqikfplcgjsmrn", 1, S::npos); + test(S("fodgq"), "", 0, 0); + test(S("qanej"), "dfkap", 0, 0); + test(S("clbao"), "ihqrfebgad", 0, 0); + test(S("mekdn"), "ngtjfcalbseiqrphmkdo", 0, S::npos); + test(S("srdfq"), "", 1, 1); + test(S("oemth"), "ikcrq", 1, 1); + test(S("cdaih"), "dmajblfhsg", 1, 0); + test(S("qohtk"), "oqftjhdmkgsblacenirp", 1, S::npos); + test(S("cshmd"), "", 2, 2); + test(S("lhcdo"), "oebqi", 2, 2); + test(S("qnsoh"), "kojhpmbsfe", 2, 1); + test(S("pkrof"), "acbsjqogpltdkhinfrem", 2, S::npos); + test(S("fmtsp"), "", 4, 4); + test(S("khbpm"), "aobjd", 4, 4); + test(S("pbsji"), "pcbahntsje", 4, 4); + test(S("mprdj"), "fhepcrntkoagbmldqijs", 4, S::npos); + test(S("eqmpa"), "", 5, 4); + test(S("omigs"), "kocgb", 5, 4); + test(S("onmje"), "fbslrjiqkm", 5, 4); + test(S("oqmrj"), "jeidpcmalhfnqbgtrsko", 5, S::npos); + test(S("schfa"), "", 6, 4); + test(S("igdsc"), "qngpd", 6, 4); + test(S("brqgo"), "rodhqklgmb", 6, S::npos); + test(S("tnrph"), "thdjgafrlbkoiqcspmne", 6, S::npos); + test(S("hcjitbfapl"), "", 0, 0); + test(S("daiprenocl"), "ashjd", 0, S::npos); + test(S("litpcfdghe"), "mgojkldsqh", 0, S::npos); + test(S("aidjksrolc"), "imqnaghkfrdtlopbjesc", 0, S::npos); + test(S("qpghtfbaji"), "", 1, 1); + test(S("gfshlcmdjr"), "nadkh", 1, 1); + test(S("nkodajteqp"), "ofdrqmkebl", 1, 0); + test(S("gbmetiprqd"), "bdfjqgatlksriohemnpc", 1, S::npos); + test(S("crnklpmegd"), "", 5, 5); + test(S("jsbtafedoc"), "prqgn", 5, 5); + test(S("qnmodrtkeb"), "pejafmnokr", 5, 4); + test(S("cpebqsfmnj"), "odnqkgijrhabfmcestlp", 5, S::npos); + test(S("lmofqdhpki"), "", 9, 9); + test(S("hnefkqimca"), "rtjpa", 9, 8); + test(S("drtasbgmfp"), "ktsrmnqagd", 9, 9); + test(S("lsaijeqhtr"), "rtdhgcisbnmoaqkfpjle", 9, S::npos); + test(S("elgofjmbrq"), "", 10, 9); + test(S("mjqdgalkpc"), "dplqa", 10, 9); + test(S("kthqnfcerm"), "dkacjoptns", 10, 9); + test(S("dfsjhanorc"), "hqfimtrgnbekpdcsjalo", 10, S::npos); + test(S("eqsgalomhb"), "", 11, 9); + test(S("akiteljmoh"), "lofbc", 11, 9); + test(S("hlbdfreqjo"), "astoegbfpn", 11, 8); + test(S("taqobhlerg"), "pdgreqomsncafklhtibj", 11, S::npos); + test(S("snafbdlghrjkpqtoceim"), "", 0, 0); + test(S("aemtbrgcklhndjisfpoq"), "lbtqd", 0, 0); + test(S("pnracgfkjdiholtbqsem"), "tboimldpjh", 0, S::npos); + test(S("dicfltehbsgrmojnpkaq"), "slcerthdaiqjfnobgkpm", 0, S::npos); + test(S("jlnkraeodhcspfgbqitm"), "", 1, 1); + test(S("lhosrngtmfjikbqpcade"), "aqibs", 1, 1); + test(S("rbtaqjhgkneisldpmfoc"), "gtfblmqinc", 1, 0); + test(S("gpifsqlrdkbonjtmheca"), "mkqpbtdalgniorhfescj", 1, S::npos); + test(S("hdpkobnsalmcfijregtq"), "", 10, 10); + test(S("jtlshdgqaiprkbcoenfm"), "pblas", 10, 9); + test(S("fkdrbqltsgmcoiphneaj"), "arosdhcfme", 10, 9); + test(S("crsplifgtqedjohnabmk"), "blkhjeogicatqfnpdmsr", 10, S::npos); + test(S("niptglfbosehkamrdqcj"), "", 19, 19); + test(S("copqdhstbingamjfkler"), "djkqc", 19, 19); + test(S("mrtaefilpdsgocnhqbjk"), "lgokshjtpb", 19, 16); + test(S("kojatdhlcmigpbfrqnes"), "bqjhtkfepimcnsgrlado", 19, S::npos); + test(S("eaintpchlqsbdgrkjofm"), "", 20, 19); + test(S("gjnhidfsepkrtaqbmclo"), "nocfa", 20, 18); + test(S("spocfaktqdbiejlhngmr"), "bgtajmiedc", 20, 19); + test(S("rphmlekgfscndtaobiqj"), "lsckfnqgdahejiopbtmr", 20, S::npos); + test(S("liatsqdoegkmfcnbhrpj"), "", 21, 19); + test(S("binjagtfldkrspcomqeh"), "gfsrt", 21, 19); + test(S("latkmisecnorjbfhqpdg"), "pfsocbhjtm", 21, 19); + test(S("lecfratdjkhnsmqpoigb"), "tpflmdnoicjgkberhqsa", 21, S::npos); +} + +template +void test1() +{ + test(S(""), "", S::npos); + test(S(""), "laenf", S::npos); + test(S(""), "pqlnkmbdjo", S::npos); + test(S(""), "qkamfogpnljdcshbreti", S::npos); + test(S("nhmko"), "", 4); + test(S("lahfb"), "irkhs", 4); + test(S("gmfhd"), "kantesmpgj", 4); + test(S("odaft"), "oknlrstdpiqmjbaghcfe", S::npos); + test(S("eolhfgpjqk"), "", 9); + test(S("nbatdlmekr"), "bnrpe", 8); + test(S("jdmciepkaq"), "jtdaefblso", 9); + test(S("hkbgspoflt"), "oselktgbcapndfjihrmq", S::npos); + test(S("gprdcokbnjhlsfmtieqa"), "", 19); + test(S("qjghlnftcaismkropdeb"), "bjaht", 18); + test(S("pnalfrdtkqcmojiesbhg"), "hjlcmgpket", 17); + test(S("pniotcfrhqsmgdkjbael"), "htaobedqikfplcgjsmrn", S::npos); +} + +int main() +{ + { + typedef std::string S; + test0(); + test1(); + } +#if TEST_STD_VER >= 11 + { + typedef std::basic_string, min_allocator> S; + test0(); + test1(); + } +#endif +} diff --git a/tests/external/libcxx/basic_string/string.ops/string_find.last.not.of/pointer_size_size.pass.cpp b/tests/external/libcxx/basic_string/string.ops/string_find.last.not.of/pointer_size_size.pass.cpp new file mode 100644 index 0000000..2024266 --- /dev/null +++ b/tests/external/libcxx/basic_string/string.ops/string_find.last.not.of/pointer_size_size.pass.cpp @@ -0,0 +1,387 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// + +// size_type find_last_not_of(const charT* s, size_type pos, size_type n) const; + +#include +#include + +#include "min_allocator.h" + +template +void +test(const S& s, const typename S::value_type* str, typename S::size_type pos, + typename S::size_type n, typename S::size_type x) +{ + assert(s.find_last_not_of(str, pos, n) == x); + if (x != S::npos) + assert(x <= pos && x < s.size()); +} + +template +void test0() +{ + test(S(""), "", 0, 0, S::npos); + test(S(""), "irkhs", 0, 0, S::npos); + test(S(""), "kante", 0, 1, S::npos); + test(S(""), "oknlr", 0, 2, S::npos); + test(S(""), "pcdro", 0, 4, S::npos); + test(S(""), "bnrpe", 0, 5, S::npos); + test(S(""), "jtdaefblso", 0, 0, S::npos); + test(S(""), "oselktgbca", 0, 1, S::npos); + test(S(""), "eqgaplhckj", 0, 5, S::npos); + test(S(""), "bjahtcmnlp", 0, 9, S::npos); + test(S(""), "hjlcmgpket", 0, 10, S::npos); + test(S(""), "htaobedqikfplcgjsmrn", 0, 0, S::npos); + test(S(""), "hpqiarojkcdlsgnmfetb", 0, 1, S::npos); + test(S(""), "dfkaprhjloqetcsimnbg", 0, 10, S::npos); + test(S(""), "ihqrfebgadntlpmjksoc", 0, 19, S::npos); + test(S(""), "ngtjfcalbseiqrphmkdo", 0, 20, S::npos); + test(S(""), "", 1, 0, S::npos); + test(S(""), "lbtqd", 1, 0, S::npos); + test(S(""), "tboim", 1, 1, S::npos); + test(S(""), "slcer", 1, 2, S::npos); + test(S(""), "cbjfs", 1, 4, S::npos); + test(S(""), "aqibs", 1, 5, S::npos); + test(S(""), "gtfblmqinc", 1, 0, S::npos); + test(S(""), "mkqpbtdalg", 1, 1, S::npos); + test(S(""), "kphatlimcd", 1, 5, S::npos); + test(S(""), "pblasqogic", 1, 9, S::npos); + test(S(""), "arosdhcfme", 1, 10, S::npos); + test(S(""), "blkhjeogicatqfnpdmsr", 1, 0, S::npos); + test(S(""), "bmhineprjcoadgstflqk", 1, 1, S::npos); + test(S(""), "djkqcmetslnghpbarfoi", 1, 10, S::npos); + test(S(""), "lgokshjtpbemarcdqnfi", 1, 19, S::npos); + test(S(""), "bqjhtkfepimcnsgrlado", 1, 20, S::npos); + test(S("eaint"), "", 0, 0, 0); + test(S("binja"), "gfsrt", 0, 0, 0); + test(S("latkm"), "pfsoc", 0, 1, 0); + test(S("lecfr"), "tpflm", 0, 2, 0); + test(S("eqkst"), "sgkec", 0, 4, S::npos); + test(S("cdafr"), "romds", 0, 5, 0); + test(S("prbhe"), "qhjistlgmr", 0, 0, 0); + test(S("lbisk"), "pedfirsglo", 0, 1, 0); + test(S("hrlpd"), "aqcoslgrmk", 0, 5, 0); + test(S("ehmja"), "dabckmepqj", 0, 9, S::npos); + test(S("mhqgd"), "pqscrjthli", 0, 10, 0); + test(S("tgklq"), "kfphdcsjqmobliagtren", 0, 0, 0); + test(S("bocjs"), "rokpefncljibsdhqtagm", 0, 1, 0); + test(S("grbsd"), "afionmkphlebtcjqsgrd", 0, 10, 0); + test(S("ofjqr"), "aenmqplidhkofrjbctsg", 0, 19, S::npos); + test(S("btlfi"), "osjmbtcadhiklegrpqnf", 0, 20, S::npos); + test(S("clrgb"), "", 1, 0, 1); + test(S("tjmek"), "osmia", 1, 0, 1); + test(S("bgstp"), "ckonl", 1, 1, 1); + test(S("hstrk"), "ilcaj", 1, 2, 1); + test(S("kmspj"), "lasiq", 1, 4, 1); + test(S("tjboh"), "kfqmr", 1, 5, 1); + test(S("ilbcj"), "klnitfaobg", 1, 0, 1); + test(S("jkngf"), "gjhmdlqikp", 1, 1, 1); + test(S("gfcql"), "skbgtahqej", 1, 5, 1); + test(S("dqtlg"), "bjsdgtlpkf", 1, 9, 1); + test(S("bthpg"), "bjgfmnlkio", 1, 10, 1); + test(S("dgsnq"), "lbhepotfsjdqigcnamkr", 1, 0, 1); + test(S("rmfhp"), "tebangckmpsrqdlfojhi", 1, 1, 1); + test(S("jfdam"), "joflqbdkhtegimscpanr", 1, 10, S::npos); + test(S("edapb"), "adpmcohetfbsrjinlqkg", 1, 19, S::npos); + test(S("brfsm"), "iacldqjpfnogbsrhmetk", 1, 20, S::npos); + test(S("ndrhl"), "", 2, 0, 2); + test(S("mrecp"), "otkgb", 2, 0, 2); + test(S("qlasf"), "cqsjl", 2, 1, 2); + test(S("smaqd"), "dpifl", 2, 2, 2); + test(S("hjeni"), "oapht", 2, 4, 2); + test(S("ocmfj"), "cifts", 2, 5, 2); + test(S("hmftq"), "nmsckbgalo", 2, 0, 2); + test(S("fklad"), "tpksqhamle", 2, 1, 2); + test(S("dirnm"), "tpdrchmkji", 2, 5, 1); + test(S("hrgdc"), "ijagfkblst", 2, 9, 1); + test(S("ifakg"), "kpocsignjb", 2, 10, 2); + test(S("ebrgd"), "pecqtkjsnbdrialgmohf", 2, 0, 2); + test(S("rcjml"), "aiortphfcmkjebgsndql", 2, 1, 2); + test(S("peqmt"), "sdbkeamglhipojqftrcn", 2, 10, 2); + test(S("frehn"), "ljqncehgmfktroapidbs", 2, 19, S::npos); + test(S("tqolf"), "rtcfodilamkbenjghqps", 2, 20, S::npos); + test(S("cjgao"), "", 4, 0, 4); + test(S("kjplq"), "mabns", 4, 0, 4); + test(S("herni"), "bdnrp", 4, 1, 4); + test(S("tadrb"), "scidp", 4, 2, 4); + test(S("pkfeo"), "agbjl", 4, 4, 4); + test(S("hoser"), "jfmpr", 4, 5, 3); + test(S("kgrsp"), "rbpefghsmj", 4, 0, 4); + test(S("pgejb"), "apsfntdoqc", 4, 1, 4); + test(S("thlnq"), "ndkjeisgcl", 4, 5, 4); + test(S("nbmit"), "rnfpqatdeo", 4, 9, 3); + test(S("jgmib"), "bntjlqrfik", 4, 10, 2); + test(S("ncrfj"), "kcrtmpolnaqejghsfdbi", 4, 0, 4); + test(S("ncsik"), "lobheanpkmqidsrtcfgj", 4, 1, 4); + test(S("sgbfh"), "athdkljcnreqbgpmisof", 4, 10, 3); + test(S("dktbn"), "qkdmjialrscpbhefgont", 4, 19, 2); + test(S("fthqm"), "dmasojntqleribkgfchp", 4, 20, S::npos); + test(S("klopi"), "", 5, 0, 4); + test(S("dajhn"), "psthd", 5, 0, 4); + test(S("jbgno"), "rpmjd", 5, 1, 4); + test(S("hkjae"), "dfsmk", 5, 2, 4); +} + +template +void test1() +{ + test(S("gbhqo"), "skqne", 5, 4, 4); + test(S("ktdor"), "kipnf", 5, 5, 4); + test(S("ldprn"), "hmrnqdgifl", 5, 0, 4); + test(S("egmjk"), "fsmjcdairn", 5, 1, 4); + test(S("armql"), "pcdgltbrfj", 5, 5, 3); + test(S("cdhjo"), "aekfctpirg", 5, 9, 4); + test(S("jcons"), "ledihrsgpf", 5, 10, 3); + test(S("cbrkp"), "mqcklahsbtirgopefndj", 5, 0, 4); + test(S("fhgna"), "kmlthaoqgecrnpdbjfis", 5, 1, 4); + test(S("ejfcd"), "sfhbamcdptojlkrenqgi", 5, 10, 1); + test(S("kqjhe"), "pbniofmcedrkhlstgaqj", 5, 19, 2); + test(S("pbdjl"), "mongjratcskbhqiepfdl", 5, 20, S::npos); + test(S("gajqn"), "", 6, 0, 4); + test(S("stedk"), "hrnat", 6, 0, 4); + test(S("tjkaf"), "gsqdt", 6, 1, 4); + test(S("dthpe"), "bspkd", 6, 2, 4); + test(S("klhde"), "ohcmb", 6, 4, 4); + test(S("bhlki"), "heatr", 6, 5, 4); + test(S("lqmoh"), "pmblckedfn", 6, 0, 4); + test(S("mtqin"), "aceqmsrbik", 6, 1, 4); + test(S("dpqbr"), "lmbtdehjrn", 6, 5, 4); + test(S("kdhmo"), "teqmcrlgib", 6, 9, 4); + test(S("jblqp"), "njolbmspac", 6, 10, 3); + test(S("qmjgl"), "pofnhidklamecrbqjgst", 6, 0, 4); + test(S("rothp"), "jbhckmtgrqnosafedpli", 6, 1, 4); + test(S("ghknq"), "dobntpmqklicsahgjerf", 6, 10, 1); + test(S("eopfi"), "tpdshainjkbfoemlrgcq", 6, 19, S::npos); + test(S("dsnmg"), "oldpfgeakrnitscbjmqh", 6, 20, S::npos); + test(S("jnkrfhotgl"), "", 0, 0, 0); + test(S("dltjfngbko"), "rqegt", 0, 0, 0); + test(S("bmjlpkiqde"), "dashm", 0, 1, 0); + test(S("skrflobnqm"), "jqirk", 0, 2, 0); + test(S("jkpldtshrm"), "rckeg", 0, 4, 0); + test(S("ghasdbnjqo"), "jscie", 0, 5, 0); + test(S("igrkhpbqjt"), "efsphndliq", 0, 0, 0); + test(S("ikthdgcamf"), "gdicosleja", 0, 1, 0); + test(S("pcofgeniam"), "qcpjibosfl", 0, 5, S::npos); + test(S("rlfjgesqhc"), "lrhmefnjcq", 0, 9, S::npos); + test(S("itphbqsker"), "dtablcrseo", 0, 10, 0); + test(S("skjafcirqm"), "apckjsftedbhgomrnilq", 0, 0, 0); + test(S("tcqomarsfd"), "pcbrgflehjtiadnsokqm", 0, 1, 0); + test(S("rocfeldqpk"), "nsiadegjklhobrmtqcpf", 0, 10, 0); + test(S("cfpegndlkt"), "cpmajdqnolikhgsbretf", 0, 19, S::npos); + test(S("fqbtnkeasj"), "jcflkntmgiqrphdosaeb", 0, 20, S::npos); + test(S("shbcqnmoar"), "", 1, 0, 1); + test(S("bdoshlmfin"), "ontrs", 1, 0, 1); + test(S("khfrebnsgq"), "pfkna", 1, 1, 1); + test(S("getcrsaoji"), "ekosa", 1, 2, 0); + test(S("fjiknedcpq"), "anqhk", 1, 4, 1); + test(S("tkejgnafrm"), "jekca", 1, 5, 0); + test(S("jnakolqrde"), "ikemsjgacf", 1, 0, 1); + test(S("lcjptsmgbe"), "arolgsjkhm", 1, 1, 1); + test(S("itfsmcjorl"), "oftkbldhre", 1, 5, 0); + test(S("omchkfrjea"), "gbkqdoeftl", 1, 9, 1); + test(S("cigfqkated"), "sqcflrgtim", 1, 10, S::npos); + test(S("tscenjikml"), "fmhbkislrjdpanogqcet", 1, 0, 1); + test(S("qcpaemsinf"), "rnioadktqlgpbcjsmhef", 1, 1, 1); + test(S("gltkojeipd"), "oakgtnldpsefihqmjcbr", 1, 10, S::npos); + test(S("qistfrgnmp"), "gbnaelosidmcjqktfhpr", 1, 19, S::npos); + test(S("bdnpfcqaem"), "akbripjhlosndcmqgfet", 1, 20, S::npos); + test(S("ectnhskflp"), "", 5, 0, 5); + test(S("fgtianblpq"), "pijag", 5, 0, 5); + test(S("mfeqklirnh"), "jrckd", 5, 1, 5); + test(S("astedncjhk"), "qcloh", 5, 2, 5); + test(S("fhlqgcajbr"), "thlmp", 5, 4, 5); + test(S("epfhocmdng"), "qidmo", 5, 5, 5); + test(S("apcnsibger"), "lnegpsjqrd", 5, 0, 5); + test(S("aqkocrbign"), "rjqdablmfs", 5, 1, 4); + test(S("ijsmdtqgce"), "enkgpbsjaq", 5, 5, 5); + test(S("clobgsrken"), "kdsgoaijfh", 5, 9, 3); + test(S("jbhcfposld"), "trfqgmckbe", 5, 10, 5); + test(S("oqnpblhide"), "igetsracjfkdnpoblhqm", 5, 0, 5); + test(S("lroeasctif"), "nqctfaogirshlekbdjpm", 5, 1, 5); + test(S("bpjlgmiedh"), "csehfgomljdqinbartkp", 5, 10, 1); + test(S("pamkeoidrj"), "qahoegcmplkfsjbdnitr", 5, 19, S::npos); + test(S("espogqbthk"), "dpteiajrqmsognhlfbkc", 5, 20, S::npos); + test(S("shoiedtcjb"), "", 9, 0, 9); + test(S("ebcinjgads"), "tqbnh", 9, 0, 9); + test(S("dqmregkcfl"), "akmle", 9, 1, 9); + test(S("ngcrieqajf"), "iqfkm", 9, 2, 9); + test(S("qosmilgnjb"), "tqjsr", 9, 4, 9); + test(S("ikabsjtdfl"), "jplqg", 9, 5, 8); + test(S("ersmicafdh"), "oilnrbcgtj", 9, 0, 9); + test(S("fdnplotmgh"), "morkglpesn", 9, 1, 9); + test(S("fdbicojerm"), "dmicerngat", 9, 5, 8); + test(S("mbtafndjcq"), "radgeskbtc", 9, 9, 9); + test(S("mlenkpfdtc"), "ljikprsmqo", 9, 10, 9); + test(S("ahlcifdqgs"), "trqihkcgsjamfdbolnpe", 9, 0, 9); + test(S("bgjemaltks"), "lqmthbsrekajgnofcipd", 9, 1, 9); + test(S("pdhslbqrfc"), "jtalmedribkgqsopcnfh", 9, 10, 9); + test(S("dirhtsnjkc"), "spqfoiclmtagejbndkrh", 9, 19, 3); + test(S("dlroktbcja"), "nmotklspigjrdhcfaebq", 9, 20, S::npos); + test(S("ncjpmaekbs"), "", 10, 0, 9); + test(S("hlbosgmrak"), "hpmsd", 10, 0, 9); + test(S("pqfhsgilen"), "qnpor", 10, 1, 9); + test(S("gqtjsbdckh"), "otdma", 10, 2, 9); + test(S("cfkqpjlegi"), "efhjg", 10, 4, 9); + test(S("beanrfodgj"), "odpte", 10, 5, 9); + test(S("adtkqpbjfi"), "bctdgfmolr", 10, 0, 9); + test(S("iomkfthagj"), "oaklidrbqg", 10, 1, 9); +} + +template +void test2() +{ + test(S("sdpcilonqj"), "dnjfsagktr", 10, 5, 8); + test(S("gtfbdkqeml"), "nejaktmiqg", 10, 9, 9); + test(S("bmeqgcdorj"), "pjqonlebsf", 10, 10, 8); + test(S("etqlcanmob"), "dshmnbtolcjepgaikfqr", 10, 0, 9); + test(S("roqmkbdtia"), "iogfhpabtjkqlrnemcds", 10, 1, 9); + test(S("kadsithljf"), "ngridfabjsecpqltkmoh", 10, 10, 7); + test(S("sgtkpbfdmh"), "athmknplcgofrqejsdib", 10, 19, 5); + test(S("qgmetnabkl"), "ldobhmqcafnjtkeisgrp", 10, 20, S::npos); + test(S("cqjohampgd"), "", 11, 0, 9); + test(S("hobitmpsan"), "aocjb", 11, 0, 9); + test(S("tjehkpsalm"), "jbrnk", 11, 1, 9); + test(S("ngfbojitcl"), "tqedg", 11, 2, 9); + test(S("rcfkdbhgjo"), "nqskp", 11, 4, 9); + test(S("qghptonrea"), "eaqkl", 11, 5, 7); + test(S("hnprfgqjdl"), "reaoicljqm", 11, 0, 9); + test(S("hlmgabenti"), "lsftgajqpm", 11, 1, 9); + test(S("ofcjanmrbs"), "rlpfogmits", 11, 5, 9); + test(S("jqedtkornm"), "shkncmiaqj", 11, 9, 7); + test(S("rfedlasjmg"), "fpnatrhqgs", 11, 10, 8); + test(S("talpqjsgkm"), "sjclemqhnpdbgikarfot", 11, 0, 9); + test(S("lrkcbtqpie"), "otcmedjikgsfnqbrhpla", 11, 1, 9); + test(S("cipogdskjf"), "bonsaefdqiprkhlgtjcm", 11, 10, 8); + test(S("nqedcojahi"), "egpscmahijlfnkrodqtb", 11, 19, S::npos); + test(S("hefnrkmctj"), "kmqbfepjthgilscrndoa", 11, 20, S::npos); + test(S("atqirnmekfjolhpdsgcb"), "", 0, 0, 0); + test(S("echfkmlpribjnqsaogtd"), "prboq", 0, 0, 0); + test(S("qnhiftdgcleajbpkrosm"), "fjcqh", 0, 1, 0); + test(S("chamfknorbedjitgslpq"), "fmosa", 0, 2, 0); + test(S("njhqpibfmtlkaecdrgso"), "qdbok", 0, 4, 0); + test(S("ebnghfsqkprmdcljoiat"), "amslg", 0, 5, 0); + test(S("letjomsgihfrpqbkancd"), "smpltjneqb", 0, 0, 0); + test(S("nblgoipcrqeaktshjdmf"), "flitskrnge", 0, 1, 0); + test(S("cehkbngtjoiflqapsmrd"), "pgqihmlbef", 0, 5, 0); + test(S("mignapfoklbhcqjetdrs"), "cfpdqjtgsb", 0, 9, 0); + test(S("ceatbhlsqjgpnokfrmdi"), "htpsiaflom", 0, 10, 0); + test(S("ocihkjgrdelpfnmastqb"), "kpjfiaceghsrdtlbnomq", 0, 0, 0); + test(S("noelgschdtbrjfmiqkap"), "qhtbomidljgafneksprc", 0, 1, 0); + test(S("dkclqfombepritjnghas"), "nhtjobkcefldimpsaqgr", 0, 10, 0); + test(S("miklnresdgbhqcojftap"), "prabcjfqnoeskilmtgdh", 0, 19, S::npos); + test(S("htbcigojaqmdkfrnlsep"), "dtrgmchilkasqoebfpjn", 0, 20, S::npos); + test(S("febhmqtjanokscdirpgl"), "", 1, 0, 1); + test(S("loakbsqjpcrdhftniegm"), "sqome", 1, 0, 1); + test(S("reagphsqflbitdcjmkno"), "smfte", 1, 1, 1); + test(S("jitlfrqemsdhkopncabg"), "ciboh", 1, 2, 0); + test(S("mhtaepscdnrjqgbkifol"), "haois", 1, 4, 0); + test(S("tocesrfmnglpbjihqadk"), "abfki", 1, 5, 1); + test(S("lpfmctjrhdagneskbqoi"), "frdkocntmq", 1, 0, 1); + test(S("lsmqaepkdhncirbtjfgo"), "oasbpedlnr", 1, 1, 1); + test(S("epoiqmtldrabnkjhcfsg"), "kltqmhgand", 1, 5, 1); + test(S("emgasrilpknqojhtbdcf"), "gdtfjchpmr", 1, 9, 0); + test(S("hnfiagdpcklrjetqbsom"), "ponmcqblet", 1, 10, 0); + test(S("nsdfebgajhmtricpoklq"), "sgphqdnofeiklatbcmjr", 1, 0, 1); + test(S("atjgfsdlpobmeiqhncrk"), "ljqprsmigtfoneadckbh", 1, 1, 1); + test(S("sitodfgnrejlahcbmqkp"), "ligeojhafnkmrcsqtbdp", 1, 10, 0); + test(S("fraghmbiceknltjpqosd"), "lsimqfnjarbopedkhcgt", 1, 19, S::npos); + test(S("pmafenlhqtdbkirjsogc"), "abedmfjlghniorcqptks", 1, 20, S::npos); + test(S("pihgmoeqtnakrjslcbfd"), "", 10, 0, 10); + test(S("gjdkeprctqblnhiafsom"), "hqtoa", 10, 0, 10); + test(S("mkpnblfdsahrcqijteog"), "cahif", 10, 1, 10); + test(S("gckarqnelodfjhmbptis"), "kehis", 10, 2, 10); + test(S("gqpskidtbclomahnrjfe"), "kdlmh", 10, 4, 9); + test(S("pkldjsqrfgitbhmaecno"), "paeql", 10, 5, 10); + test(S("aftsijrbeklnmcdqhgop"), "aghoqiefnb", 10, 0, 10); + test(S("mtlgdrhafjkbiepqnsoc"), "jrbqaikpdo", 10, 1, 10); + test(S("pqgirnaefthokdmbsclj"), "smjonaeqcl", 10, 5, 10); + test(S("kpdbgjmtherlsfcqoina"), "eqbdrkcfah", 10, 9, 8); + test(S("jrlbothiknqmdgcfasep"), "kapmsienhf", 10, 10, 10); + test(S("mjogldqferckabinptsh"), "jpqotrlenfcsbhkaimdg", 10, 0, 10); + test(S("apoklnefbhmgqcdrisjt"), "jlbmhnfgtcqprikeados", 10, 1, 10); + test(S("ifeopcnrjbhkdgatmqls"), "stgbhfmdaljnpqoicker", 10, 10, 8); + test(S("ckqhaiesmjdnrgolbtpf"), "oihcetflbjagdsrkmqpn", 10, 19, S::npos); + test(S("bnlgapfimcoterskqdjh"), "adtclebmnpjsrqfkigoh", 10, 20, S::npos); + test(S("kgdlrobpmjcthqsafeni"), "", 19, 0, 19); + test(S("dfkechomjapgnslbtqir"), "beafg", 19, 0, 19); + test(S("rloadknfbqtgmhcsipje"), "iclat", 19, 1, 19); + test(S("mgjhkolrnadqbpetcifs"), "rkhnf", 19, 2, 19); + test(S("cmlfakiojdrgtbsphqen"), "clshq", 19, 4, 19); + test(S("kghbfipeomsntdalrqjc"), "dtcoj", 19, 5, 17); + test(S("eldiqckrnmtasbghjfpo"), "rqosnjmfth", 19, 0, 19); + test(S("abqjcfedgotihlnspkrm"), "siatdfqglh", 19, 1, 19); + test(S("qfbadrtjsimkolcenhpg"), "mrlshtpgjq", 19, 5, 19); + test(S("abseghclkjqifmtodrnp"), "adlcskgqjt", 19, 9, 19); + test(S("ibmsnlrjefhtdokacqpg"), "drshcjknaf", 19, 10, 19); + test(S("mrkfciqjebaponsthldg"), "etsaqroinghpkjdlfcbm", 19, 0, 19); + test(S("mjkticdeoqshpalrfbgn"), "sgepdnkqliambtrocfhj", 19, 1, 19); + test(S("rqnoclbdejgiphtfsakm"), "nlmcjaqgbsortfdihkpe", 19, 10, 18); + test(S("plkqbhmtfaeodjcrsing"), "racfnpmosldibqkghjet", 19, 19, 7); + test(S("oegalhmstjrfickpbndq"), "fjhdsctkqeiolagrnmbp", 19, 20, S::npos); + test(S("rdtgjcaohpblniekmsfq"), "", 20, 0, 19); + test(S("ofkqbnjetrmsaidphglc"), "ejanp", 20, 0, 19); + test(S("grkpahljcftesdmonqib"), "odife", 20, 1, 19); + test(S("jimlgbhfqkteospardcn"), "okaqd", 20, 2, 19); + test(S("gftenihpmslrjkqadcob"), "lcdbi", 20, 4, 18); + test(S("bmhldogtckrfsanijepq"), "fsqbj", 20, 5, 18); + test(S("nfqkrpjdesabgtlcmoih"), "bigdomnplq", 20, 0, 19); + test(S("focalnrpiqmdkstehbjg"), "apiblotgcd", 20, 1, 19); + test(S("rhqdspkmebiflcotnjga"), "acfhdenops", 20, 5, 18); + test(S("rahdtmsckfboqlpniegj"), "jopdeamcrk", 20, 9, 18); + test(S("fbkeiopclstmdqranjhg"), "trqncbkgmh", 20, 10, 17); + test(S("lifhpdgmbconstjeqark"), "tomglrkencbsfjqpihda", 20, 0, 19); +} + +template +void test3() +{ + test(S("pboqganrhedjmltsicfk"), "gbkhdnpoietfcmrslajq", 20, 1, 19); + test(S("klchabsimetjnqgorfpd"), "rtfnmbsglkjaichoqedp", 20, 10, 19); + test(S("sirfgmjqhctndbklaepo"), "ohkmdpfqbsacrtjnlgei", 20, 19, 1); + test(S("rlbdsiceaonqjtfpghkm"), "dlbrteoisgphmkncajfq", 20, 20, S::npos); + test(S("ecgdanriptblhjfqskom"), "", 21, 0, 19); + test(S("fdmiarlpgcskbhoteqjn"), "sjrlo", 21, 0, 19); + test(S("rlbstjqopignecmfadkh"), "qjpor", 21, 1, 19); + test(S("grjpqmbshektdolcafni"), "odhfn", 21, 2, 19); + test(S("sakfcohtqnibprjmlged"), "qtfin", 21, 4, 19); + test(S("mjtdglasihqpocebrfkn"), "hpqfo", 21, 5, 19); + test(S("okaplfrntghqbmeicsdj"), "fabmertkos", 21, 0, 19); + test(S("sahngemrtcjidqbklfpo"), "brqtgkmaej", 21, 1, 19); + test(S("dlmsipcnekhbgoaftqjr"), "nfrdeihsgl", 21, 5, 18); + test(S("ahegrmqnoiklpfsdbcjt"), "hlfrosekpi", 21, 9, 19); + test(S("hdsjbnmlegtkqripacof"), "atgbkrjdsm", 21, 10, 19); + test(S("pcnedrfjihqbalkgtoms"), "blnrptjgqmaifsdkhoec", 21, 0, 19); + test(S("qjidealmtpskrbfhocng"), "ctpmdahebfqjgknloris", 21, 1, 19); + test(S("qeindtagmokpfhsclrbj"), "apnkeqthrmlbfodiscgj", 21, 10, 19); + test(S("kpfegbjhsrnodltqciam"), "jdgictpframeoqlsbknh", 21, 19, 7); + test(S("hnbrcplsjfgiktoedmaq"), "qprlsfojamgndekthibc", 21, 20, S::npos); +} + +int main() +{ + { + typedef std::string S; + test0(); + test1(); + test2(); + test3(); + } +#if TEST_STD_VER >= 11 + { + typedef std::basic_string, min_allocator> S; + test0(); + test1(); + test2(); + test3(); + } +#endif +} diff --git a/tests/external/libcxx/basic_string/string.ops/string_find.last.not.of/string_size.pass.cpp b/tests/external/libcxx/basic_string/string.ops/string_find.last.not.of/string_size.pass.cpp new file mode 100644 index 0000000..57fab60 --- /dev/null +++ b/tests/external/libcxx/basic_string/string.ops/string_find.last.not.of/string_size.pass.cpp @@ -0,0 +1,165 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// + +// size_type find_last_not_of(const basic_string& str, size_type pos = npos) const; + +#include +#include + +#include "test_macros.h" +#include "min_allocator.h" + +template +void +test(const S& s, const S& str, typename S::size_type pos, typename S::size_type x) +{ + assert(s.find_last_not_of(str, pos) == x); + if (x != S::npos) + assert(x <= pos && x < s.size()); +} + +template +void +test(const S& s, const S& str, typename S::size_type x) +{ + assert(s.find_last_not_of(str) == x); + if (x != S::npos) + assert(x < s.size()); +} + +template +void test0() +{ + test(S(""), S(""), 0, S::npos); + test(S(""), S("laenf"), 0, S::npos); + test(S(""), S("pqlnkmbdjo"), 0, S::npos); + test(S(""), S("qkamfogpnljdcshbreti"), 0, S::npos); + test(S(""), S(""), 1, S::npos); + test(S(""), S("bjaht"), 1, S::npos); + test(S(""), S("hjlcmgpket"), 1, S::npos); + test(S(""), S("htaobedqikfplcgjsmrn"), 1, S::npos); + test(S("fodgq"), S(""), 0, 0); + test(S("qanej"), S("dfkap"), 0, 0); + test(S("clbao"), S("ihqrfebgad"), 0, 0); + test(S("mekdn"), S("ngtjfcalbseiqrphmkdo"), 0, S::npos); + test(S("srdfq"), S(""), 1, 1); + test(S("oemth"), S("ikcrq"), 1, 1); + test(S("cdaih"), S("dmajblfhsg"), 1, 0); + test(S("qohtk"), S("oqftjhdmkgsblacenirp"), 1, S::npos); + test(S("cshmd"), S(""), 2, 2); + test(S("lhcdo"), S("oebqi"), 2, 2); + test(S("qnsoh"), S("kojhpmbsfe"), 2, 1); + test(S("pkrof"), S("acbsjqogpltdkhinfrem"), 2, S::npos); + test(S("fmtsp"), S(""), 4, 4); + test(S("khbpm"), S("aobjd"), 4, 4); + test(S("pbsji"), S("pcbahntsje"), 4, 4); + test(S("mprdj"), S("fhepcrntkoagbmldqijs"), 4, S::npos); + test(S("eqmpa"), S(""), 5, 4); + test(S("omigs"), S("kocgb"), 5, 4); + test(S("onmje"), S("fbslrjiqkm"), 5, 4); + test(S("oqmrj"), S("jeidpcmalhfnqbgtrsko"), 5, S::npos); + test(S("schfa"), S(""), 6, 4); + test(S("igdsc"), S("qngpd"), 6, 4); + test(S("brqgo"), S("rodhqklgmb"), 6, S::npos); + test(S("tnrph"), S("thdjgafrlbkoiqcspmne"), 6, S::npos); + test(S("hcjitbfapl"), S(""), 0, 0); + test(S("daiprenocl"), S("ashjd"), 0, S::npos); + test(S("litpcfdghe"), S("mgojkldsqh"), 0, S::npos); + test(S("aidjksrolc"), S("imqnaghkfrdtlopbjesc"), 0, S::npos); + test(S("qpghtfbaji"), S(""), 1, 1); + test(S("gfshlcmdjr"), S("nadkh"), 1, 1); + test(S("nkodajteqp"), S("ofdrqmkebl"), 1, 0); + test(S("gbmetiprqd"), S("bdfjqgatlksriohemnpc"), 1, S::npos); + test(S("crnklpmegd"), S(""), 5, 5); + test(S("jsbtafedoc"), S("prqgn"), 5, 5); + test(S("qnmodrtkeb"), S("pejafmnokr"), 5, 4); + test(S("cpebqsfmnj"), S("odnqkgijrhabfmcestlp"), 5, S::npos); + test(S("lmofqdhpki"), S(""), 9, 9); + test(S("hnefkqimca"), S("rtjpa"), 9, 8); + test(S("drtasbgmfp"), S("ktsrmnqagd"), 9, 9); + test(S("lsaijeqhtr"), S("rtdhgcisbnmoaqkfpjle"), 9, S::npos); + test(S("elgofjmbrq"), S(""), 10, 9); + test(S("mjqdgalkpc"), S("dplqa"), 10, 9); + test(S("kthqnfcerm"), S("dkacjoptns"), 10, 9); + test(S("dfsjhanorc"), S("hqfimtrgnbekpdcsjalo"), 10, S::npos); + test(S("eqsgalomhb"), S(""), 11, 9); + test(S("akiteljmoh"), S("lofbc"), 11, 9); + test(S("hlbdfreqjo"), S("astoegbfpn"), 11, 8); + test(S("taqobhlerg"), S("pdgreqomsncafklhtibj"), 11, S::npos); + test(S("snafbdlghrjkpqtoceim"), S(""), 0, 0); + test(S("aemtbrgcklhndjisfpoq"), S("lbtqd"), 0, 0); + test(S("pnracgfkjdiholtbqsem"), S("tboimldpjh"), 0, S::npos); + test(S("dicfltehbsgrmojnpkaq"), S("slcerthdaiqjfnobgkpm"), 0, S::npos); + test(S("jlnkraeodhcspfgbqitm"), S(""), 1, 1); + test(S("lhosrngtmfjikbqpcade"), S("aqibs"), 1, 1); + test(S("rbtaqjhgkneisldpmfoc"), S("gtfblmqinc"), 1, 0); + test(S("gpifsqlrdkbonjtmheca"), S("mkqpbtdalgniorhfescj"), 1, S::npos); + test(S("hdpkobnsalmcfijregtq"), S(""), 10, 10); + test(S("jtlshdgqaiprkbcoenfm"), S("pblas"), 10, 9); + test(S("fkdrbqltsgmcoiphneaj"), S("arosdhcfme"), 10, 9); + test(S("crsplifgtqedjohnabmk"), S("blkhjeogicatqfnpdmsr"), 10, S::npos); + test(S("niptglfbosehkamrdqcj"), S(""), 19, 19); + test(S("copqdhstbingamjfkler"), S("djkqc"), 19, 19); + test(S("mrtaefilpdsgocnhqbjk"), S("lgokshjtpb"), 19, 16); + test(S("kojatdhlcmigpbfrqnes"), S("bqjhtkfepimcnsgrlado"), 19, S::npos); + test(S("eaintpchlqsbdgrkjofm"), S(""), 20, 19); + test(S("gjnhidfsepkrtaqbmclo"), S("nocfa"), 20, 18); + test(S("spocfaktqdbiejlhngmr"), S("bgtajmiedc"), 20, 19); + test(S("rphmlekgfscndtaobiqj"), S("lsckfnqgdahejiopbtmr"), 20, S::npos); + test(S("liatsqdoegkmfcnbhrpj"), S(""), 21, 19); + test(S("binjagtfldkrspcomqeh"), S("gfsrt"), 21, 19); + test(S("latkmisecnorjbfhqpdg"), S("pfsocbhjtm"), 21, 19); + test(S("lecfratdjkhnsmqpoigb"), S("tpflmdnoicjgkberhqsa"), 21, S::npos); +} + +template +void test1() +{ + test(S(""), S(""), S::npos); + test(S(""), S("laenf"), S::npos); + test(S(""), S("pqlnkmbdjo"), S::npos); + test(S(""), S("qkamfogpnljdcshbreti"), S::npos); + test(S("nhmko"), S(""), 4); + test(S("lahfb"), S("irkhs"), 4); + test(S("gmfhd"), S("kantesmpgj"), 4); + test(S("odaft"), S("oknlrstdpiqmjbaghcfe"), S::npos); + test(S("eolhfgpjqk"), S(""), 9); + test(S("nbatdlmekr"), S("bnrpe"), 8); + test(S("jdmciepkaq"), S("jtdaefblso"), 9); + test(S("hkbgspoflt"), S("oselktgbcapndfjihrmq"), S::npos); + test(S("gprdcokbnjhlsfmtieqa"), S(""), 19); + test(S("qjghlnftcaismkropdeb"), S("bjaht"), 18); + test(S("pnalfrdtkqcmojiesbhg"), S("hjlcmgpket"), 17); + test(S("pniotcfrhqsmgdkjbael"), S("htaobedqikfplcgjsmrn"), S::npos); +} + +int main() +{ + { + typedef std::string S; + test0(); + test1(); + } +#if TEST_STD_VER >= 11 + { + typedef std::basic_string, min_allocator> S; + test0(); + test1(); + } +#endif + +#if TEST_STD_VER > 3 + { // LWG 2946 + std::string s = " !"; + assert(s.find_last_not_of({"abc", 1}) == s.size() - 1); + } +#endif +} diff --git a/tests/external/libcxx/basic_string/string.ops/string_find.last.not.of/string_view_size.pass.cpp b/tests/external/libcxx/basic_string/string.ops/string_find.last.not.of/string_view_size.pass.cpp new file mode 100644 index 0000000..7e46ff7 --- /dev/null +++ b/tests/external/libcxx/basic_string/string.ops/string_find.last.not.of/string_view_size.pass.cpp @@ -0,0 +1,159 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// + +// size_type find_last_not_of(basic_string_view sv, size_type pos = npos) const; + +#include +#include + +#include "min_allocator.h" + +template +void +test(const S& s, SV sv, typename S::size_type pos, typename S::size_type x) +{ + assert(s.find_last_not_of(sv, pos) == x); + if (x != S::npos) + assert(x <= pos && x < s.size()); +} + +template +void +test(const S& s, SV sv, typename S::size_type x) +{ + assert(s.find_last_not_of(sv) == x); + if (x != S::npos) + assert(x < s.size()); +} + +template +void test0() +{ + test(S(""), SV(""), 0, S::npos); + test(S(""), SV("laenf"), 0, S::npos); + test(S(""), SV("pqlnkmbdjo"), 0, S::npos); + test(S(""), SV("qkamfogpnljdcshbreti"), 0, S::npos); + test(S(""), SV(""), 1, S::npos); + test(S(""), SV("bjaht"), 1, S::npos); + test(S(""), SV("hjlcmgpket"), 1, S::npos); + test(S(""), SV("htaobedqikfplcgjsmrn"), 1, S::npos); + test(S("fodgq"), SV(""), 0, 0); + test(S("qanej"), SV("dfkap"), 0, 0); + test(S("clbao"), SV("ihqrfebgad"), 0, 0); + test(S("mekdn"), SV("ngtjfcalbseiqrphmkdo"), 0, S::npos); + test(S("srdfq"), SV(""), 1, 1); + test(S("oemth"), SV("ikcrq"), 1, 1); + test(S("cdaih"), SV("dmajblfhsg"), 1, 0); + test(S("qohtk"), SV("oqftjhdmkgsblacenirp"), 1, S::npos); + test(S("cshmd"), SV(""), 2, 2); + test(S("lhcdo"), SV("oebqi"), 2, 2); + test(S("qnsoh"), SV("kojhpmbsfe"), 2, 1); + test(S("pkrof"), SV("acbsjqogpltdkhinfrem"), 2, S::npos); + test(S("fmtsp"), SV(""), 4, 4); + test(S("khbpm"), SV("aobjd"), 4, 4); + test(S("pbsji"), SV("pcbahntsje"), 4, 4); + test(S("mprdj"), SV("fhepcrntkoagbmldqijs"), 4, S::npos); + test(S("eqmpa"), SV(""), 5, 4); + test(S("omigs"), SV("kocgb"), 5, 4); + test(S("onmje"), SV("fbslrjiqkm"), 5, 4); + test(S("oqmrj"), SV("jeidpcmalhfnqbgtrsko"), 5, S::npos); + test(S("schfa"), SV(""), 6, 4); + test(S("igdsc"), SV("qngpd"), 6, 4); + test(S("brqgo"), SV("rodhqklgmb"), 6, S::npos); + test(S("tnrph"), SV("thdjgafrlbkoiqcspmne"), 6, S::npos); + test(S("hcjitbfapl"), SV(""), 0, 0); + test(S("daiprenocl"), SV("ashjd"), 0, S::npos); + test(S("litpcfdghe"), SV("mgojkldsqh"), 0, S::npos); + test(S("aidjksrolc"), SV("imqnaghkfrdtlopbjesc"), 0, S::npos); + test(S("qpghtfbaji"), SV(""), 1, 1); + test(S("gfshlcmdjr"), SV("nadkh"), 1, 1); + test(S("nkodajteqp"), SV("ofdrqmkebl"), 1, 0); + test(S("gbmetiprqd"), SV("bdfjqgatlksriohemnpc"), 1, S::npos); + test(S("crnklpmegd"), SV(""), 5, 5); + test(S("jsbtafedoc"), SV("prqgn"), 5, 5); + test(S("qnmodrtkeb"), SV("pejafmnokr"), 5, 4); + test(S("cpebqsfmnj"), SV("odnqkgijrhabfmcestlp"), 5, S::npos); + test(S("lmofqdhpki"), SV(""), 9, 9); + test(S("hnefkqimca"), SV("rtjpa"), 9, 8); + test(S("drtasbgmfp"), SV("ktsrmnqagd"), 9, 9); + test(S("lsaijeqhtr"), SV("rtdhgcisbnmoaqkfpjle"), 9, S::npos); + test(S("elgofjmbrq"), SV(""), 10, 9); + test(S("mjqdgalkpc"), SV("dplqa"), 10, 9); + test(S("kthqnfcerm"), SV("dkacjoptns"), 10, 9); + test(S("dfsjhanorc"), SV("hqfimtrgnbekpdcsjalo"), 10, S::npos); + test(S("eqsgalomhb"), SV(""), 11, 9); + test(S("akiteljmoh"), SV("lofbc"), 11, 9); + test(S("hlbdfreqjo"), SV("astoegbfpn"), 11, 8); + test(S("taqobhlerg"), SV("pdgreqomsncafklhtibj"), 11, S::npos); + test(S("snafbdlghrjkpqtoceim"), SV(""), 0, 0); + test(S("aemtbrgcklhndjisfpoq"), SV("lbtqd"), 0, 0); + test(S("pnracgfkjdiholtbqsem"), SV("tboimldpjh"), 0, S::npos); + test(S("dicfltehbsgrmojnpkaq"), SV("slcerthdaiqjfnobgkpm"), 0, S::npos); + test(S("jlnkraeodhcspfgbqitm"), SV(""), 1, 1); + test(S("lhosrngtmfjikbqpcade"), SV("aqibs"), 1, 1); + test(S("rbtaqjhgkneisldpmfoc"), SV("gtfblmqinc"), 1, 0); + test(S("gpifsqlrdkbonjtmheca"), SV("mkqpbtdalgniorhfescj"), 1, S::npos); + test(S("hdpkobnsalmcfijregtq"), SV(""), 10, 10); + test(S("jtlshdgqaiprkbcoenfm"), SV("pblas"), 10, 9); + test(S("fkdrbqltsgmcoiphneaj"), SV("arosdhcfme"), 10, 9); + test(S("crsplifgtqedjohnabmk"), SV("blkhjeogicatqfnpdmsr"), 10, S::npos); + test(S("niptglfbosehkamrdqcj"), SV(""), 19, 19); + test(S("copqdhstbingamjfkler"), SV("djkqc"), 19, 19); + test(S("mrtaefilpdsgocnhqbjk"), SV("lgokshjtpb"), 19, 16); + test(S("kojatdhlcmigpbfrqnes"), SV("bqjhtkfepimcnsgrlado"), 19, S::npos); + test(S("eaintpchlqsbdgrkjofm"), SV(""), 20, 19); + test(S("gjnhidfsepkrtaqbmclo"), SV("nocfa"), 20, 18); + test(S("spocfaktqdbiejlhngmr"), SV("bgtajmiedc"), 20, 19); + test(S("rphmlekgfscndtaobiqj"), SV("lsckfnqgdahejiopbtmr"), 20, S::npos); + test(S("liatsqdoegkmfcnbhrpj"), SV(""), 21, 19); + test(S("binjagtfldkrspcomqeh"), SV("gfsrt"), 21, 19); + test(S("latkmisecnorjbfhqpdg"), SV("pfsocbhjtm"), 21, 19); + test(S("lecfratdjkhnsmqpoigb"), SV("tpflmdnoicjgkberhqsa"), 21, S::npos); +} + +template +void test1() +{ + test(S(""), SV(""), S::npos); + test(S(""), SV("laenf"), S::npos); + test(S(""), SV("pqlnkmbdjo"), S::npos); + test(S(""), SV("qkamfogpnljdcshbreti"), S::npos); + test(S("nhmko"), SV(""), 4); + test(S("lahfb"), SV("irkhs"), 4); + test(S("gmfhd"), SV("kantesmpgj"), 4); + test(S("odaft"), SV("oknlrstdpiqmjbaghcfe"), S::npos); + test(S("eolhfgpjqk"), SV(""), 9); + test(S("nbatdlmekr"), SV("bnrpe"), 8); + test(S("jdmciepkaq"), SV("jtdaefblso"), 9); + test(S("hkbgspoflt"), SV("oselktgbcapndfjihrmq"), S::npos); + test(S("gprdcokbnjhlsfmtieqa"), SV(""), 19); + test(S("qjghlnftcaismkropdeb"), SV("bjaht"), 18); + test(S("pnalfrdtkqcmojiesbhg"), SV("hjlcmgpket"), 17); + test(S("pniotcfrhqsmgdkjbael"), SV("htaobedqikfplcgjsmrn"), S::npos); +} + +int main() +{ + { + typedef std::string S; + typedef std::string_view SV; + test0(); + test1(); + } +#if TEST_STD_VER >= 11 + { +// typedef std::basic_string, min_allocator> S; +// typedef std::string_view SV; +// test0(); +// test1(); + } +#endif +} diff --git a/tests/external/libcxx/basic_string/string.ops/string_find.last.of/char_size.pass.cpp b/tests/external/libcxx/basic_string/string.ops/string_find.last.of/char_size.pass.cpp new file mode 100644 index 0000000..e0bbd82 --- /dev/null +++ b/tests/external/libcxx/basic_string/string.ops/string_find.last.of/char_size.pass.cpp @@ -0,0 +1,98 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// + +// size_type find_last_of(charT c, size_type pos = npos) const; + +#include +#include + +#include "min_allocator.h" + +template +void +test(const S& s, typename S::value_type c, typename S::size_type pos, + typename S::size_type x) +{ + assert(s.find_last_of(c, pos) == x); + if (x != S::npos) + assert(x <= pos && x < s.size()); +} + +template +void +test(const S& s, typename S::value_type c, typename S::size_type x) +{ + assert(s.find_last_of(c) == x); + if (x != S::npos) + assert(x < s.size()); +} + +int main() +{ + { + typedef std::string S; + test(S(""), 'm', 0, S::npos); + test(S(""), 'm', 1, S::npos); + test(S("kitcj"), 'm', 0, S::npos); + test(S("qkamf"), 'm', 1, S::npos); + test(S("nhmko"), 'm', 2, 2); + test(S("tpsaf"), 'm', 4, S::npos); + test(S("lahfb"), 'm', 5, S::npos); + test(S("irkhs"), 'm', 6, S::npos); + test(S("gmfhdaipsr"), 'm', 0, S::npos); + test(S("kantesmpgj"), 'm', 1, S::npos); + test(S("odaftiegpm"), 'm', 5, S::npos); + test(S("oknlrstdpi"), 'm', 9, S::npos); + test(S("eolhfgpjqk"), 'm', 10, S::npos); + test(S("pcdrofikas"), 'm', 11, S::npos); + test(S("nbatdlmekrgcfqsophij"), 'm', 0, S::npos); + test(S("bnrpehidofmqtcksjgla"), 'm', 1, S::npos); + test(S("jdmciepkaqgotsrfnhlb"), 'm', 10, 2); + test(S("jtdaefblsokrmhpgcnqi"), 'm', 19, 12); + test(S("hkbgspofltajcnedqmri"), 'm', 20, 17); + test(S("oselktgbcapndfjihrmq"), 'm', 21, 18); + + test(S(""), 'm', S::npos); + test(S("csope"), 'm', S::npos); + test(S("gfsmthlkon"), 'm', 3); + test(S("laenfsbridchgotmkqpj"), 'm', 15); + } +#if TEST_STD_VER >= 11 + { + typedef std::basic_string, min_allocator> S; + test(S(""), 'm', 0, S::npos); + test(S(""), 'm', 1, S::npos); + test(S("kitcj"), 'm', 0, S::npos); + test(S("qkamf"), 'm', 1, S::npos); + test(S("nhmko"), 'm', 2, 2); + test(S("tpsaf"), 'm', 4, S::npos); + test(S("lahfb"), 'm', 5, S::npos); + test(S("irkhs"), 'm', 6, S::npos); + test(S("gmfhdaipsr"), 'm', 0, S::npos); + test(S("kantesmpgj"), 'm', 1, S::npos); + test(S("odaftiegpm"), 'm', 5, S::npos); + test(S("oknlrstdpi"), 'm', 9, S::npos); + test(S("eolhfgpjqk"), 'm', 10, S::npos); + test(S("pcdrofikas"), 'm', 11, S::npos); + test(S("nbatdlmekrgcfqsophij"), 'm', 0, S::npos); + test(S("bnrpehidofmqtcksjgla"), 'm', 1, S::npos); + test(S("jdmciepkaqgotsrfnhlb"), 'm', 10, 2); + test(S("jtdaefblsokrmhpgcnqi"), 'm', 19, 12); + test(S("hkbgspofltajcnedqmri"), 'm', 20, 17); + test(S("oselktgbcapndfjihrmq"), 'm', 21, 18); + + test(S(""), 'm', S::npos); + test(S("csope"), 'm', S::npos); + test(S("gfsmthlkon"), 'm', 3); + test(S("laenfsbridchgotmkqpj"), 'm', 15); + } +#endif +} diff --git a/tests/external/libcxx/basic_string/string.ops/string_find.last.of/pointer_size.pass.cpp b/tests/external/libcxx/basic_string/string.ops/string_find.last.of/pointer_size.pass.cpp new file mode 100644 index 0000000..c3d6044 --- /dev/null +++ b/tests/external/libcxx/basic_string/string.ops/string_find.last.of/pointer_size.pass.cpp @@ -0,0 +1,158 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// + +// size_type find_last_of(const charT* s, size_type pos = npos) const; + +#include +#include + +#include "min_allocator.h" + +template +void +test(const S& s, const typename S::value_type* str, typename S::size_type pos, + typename S::size_type x) +{ + assert(s.find_last_of(str, pos) == x); + if (x != S::npos) + assert(x <= pos && x < s.size()); +} + +template +void +test(const S& s, const typename S::value_type* str, typename S::size_type x) +{ + assert(s.find_last_of(str) == x); + if (x != S::npos) + assert(x < s.size()); +} + +template +void test0() +{ + test(S(""), "", 0, S::npos); + test(S(""), "laenf", 0, S::npos); + test(S(""), "pqlnkmbdjo", 0, S::npos); + test(S(""), "qkamfogpnljdcshbreti", 0, S::npos); + test(S(""), "", 1, S::npos); + test(S(""), "bjaht", 1, S::npos); + test(S(""), "hjlcmgpket", 1, S::npos); + test(S(""), "htaobedqikfplcgjsmrn", 1, S::npos); + test(S("fodgq"), "", 0, S::npos); + test(S("qanej"), "dfkap", 0, S::npos); + test(S("clbao"), "ihqrfebgad", 0, S::npos); + test(S("mekdn"), "ngtjfcalbseiqrphmkdo", 0, 0); + test(S("srdfq"), "", 1, S::npos); + test(S("oemth"), "ikcrq", 1, S::npos); + test(S("cdaih"), "dmajblfhsg", 1, 1); + test(S("qohtk"), "oqftjhdmkgsblacenirp", 1, 1); + test(S("cshmd"), "", 2, S::npos); + test(S("lhcdo"), "oebqi", 2, S::npos); + test(S("qnsoh"), "kojhpmbsfe", 2, 2); + test(S("pkrof"), "acbsjqogpltdkhinfrem", 2, 2); + test(S("fmtsp"), "", 4, S::npos); + test(S("khbpm"), "aobjd", 4, 2); + test(S("pbsji"), "pcbahntsje", 4, 3); + test(S("mprdj"), "fhepcrntkoagbmldqijs", 4, 4); + test(S("eqmpa"), "", 5, S::npos); + test(S("omigs"), "kocgb", 5, 3); + test(S("onmje"), "fbslrjiqkm", 5, 3); + test(S("oqmrj"), "jeidpcmalhfnqbgtrsko", 5, 4); + test(S("schfa"), "", 6, S::npos); + test(S("igdsc"), "qngpd", 6, 2); + test(S("brqgo"), "rodhqklgmb", 6, 4); + test(S("tnrph"), "thdjgafrlbkoiqcspmne", 6, 4); + test(S("hcjitbfapl"), "", 0, S::npos); + test(S("daiprenocl"), "ashjd", 0, 0); + test(S("litpcfdghe"), "mgojkldsqh", 0, 0); + test(S("aidjksrolc"), "imqnaghkfrdtlopbjesc", 0, 0); + test(S("qpghtfbaji"), "", 1, S::npos); + test(S("gfshlcmdjr"), "nadkh", 1, S::npos); + test(S("nkodajteqp"), "ofdrqmkebl", 1, 1); + test(S("gbmetiprqd"), "bdfjqgatlksriohemnpc", 1, 1); + test(S("crnklpmegd"), "", 5, S::npos); + test(S("jsbtafedoc"), "prqgn", 5, S::npos); + test(S("qnmodrtkeb"), "pejafmnokr", 5, 5); + test(S("cpebqsfmnj"), "odnqkgijrhabfmcestlp", 5, 5); + test(S("lmofqdhpki"), "", 9, S::npos); + test(S("hnefkqimca"), "rtjpa", 9, 9); + test(S("drtasbgmfp"), "ktsrmnqagd", 9, 7); + test(S("lsaijeqhtr"), "rtdhgcisbnmoaqkfpjle", 9, 9); + test(S("elgofjmbrq"), "", 10, S::npos); + test(S("mjqdgalkpc"), "dplqa", 10, 8); + test(S("kthqnfcerm"), "dkacjoptns", 10, 6); + test(S("dfsjhanorc"), "hqfimtrgnbekpdcsjalo", 10, 9); + test(S("eqsgalomhb"), "", 11, S::npos); + test(S("akiteljmoh"), "lofbc", 11, 8); + test(S("hlbdfreqjo"), "astoegbfpn", 11, 9); + test(S("taqobhlerg"), "pdgreqomsncafklhtibj", 11, 9); + test(S("snafbdlghrjkpqtoceim"), "", 0, S::npos); + test(S("aemtbrgcklhndjisfpoq"), "lbtqd", 0, S::npos); + test(S("pnracgfkjdiholtbqsem"), "tboimldpjh", 0, 0); + test(S("dicfltehbsgrmojnpkaq"), "slcerthdaiqjfnobgkpm", 0, 0); + test(S("jlnkraeodhcspfgbqitm"), "", 1, S::npos); + test(S("lhosrngtmfjikbqpcade"), "aqibs", 1, S::npos); + test(S("rbtaqjhgkneisldpmfoc"), "gtfblmqinc", 1, 1); + test(S("gpifsqlrdkbonjtmheca"), "mkqpbtdalgniorhfescj", 1, 1); + test(S("hdpkobnsalmcfijregtq"), "", 10, S::npos); + test(S("jtlshdgqaiprkbcoenfm"), "pblas", 10, 10); + test(S("fkdrbqltsgmcoiphneaj"), "arosdhcfme", 10, 10); + test(S("crsplifgtqedjohnabmk"), "blkhjeogicatqfnpdmsr", 10, 10); + test(S("niptglfbosehkamrdqcj"), "", 19, S::npos); + test(S("copqdhstbingamjfkler"), "djkqc", 19, 16); + test(S("mrtaefilpdsgocnhqbjk"), "lgokshjtpb", 19, 19); + test(S("kojatdhlcmigpbfrqnes"), "bqjhtkfepimcnsgrlado", 19, 19); + test(S("eaintpchlqsbdgrkjofm"), "", 20, S::npos); + test(S("gjnhidfsepkrtaqbmclo"), "nocfa", 20, 19); + test(S("spocfaktqdbiejlhngmr"), "bgtajmiedc", 20, 18); + test(S("rphmlekgfscndtaobiqj"), "lsckfnqgdahejiopbtmr", 20, 19); + test(S("liatsqdoegkmfcnbhrpj"), "", 21, S::npos); + test(S("binjagtfldkrspcomqeh"), "gfsrt", 21, 12); + test(S("latkmisecnorjbfhqpdg"), "pfsocbhjtm", 21, 17); + test(S("lecfratdjkhnsmqpoigb"), "tpflmdnoicjgkberhqsa", 21, 19); +} + +template +void test1() +{ + test(S(""), "", S::npos); + test(S(""), "laenf", S::npos); + test(S(""), "pqlnkmbdjo", S::npos); + test(S(""), "qkamfogpnljdcshbreti", S::npos); + test(S("nhmko"), "", S::npos); + test(S("lahfb"), "irkhs", 2); + test(S("gmfhd"), "kantesmpgj", 1); + test(S("odaft"), "oknlrstdpiqmjbaghcfe", 4); + test(S("eolhfgpjqk"), "", S::npos); + test(S("nbatdlmekr"), "bnrpe", 9); + test(S("jdmciepkaq"), "jtdaefblso", 8); + test(S("hkbgspoflt"), "oselktgbcapndfjihrmq", 9); + test(S("gprdcokbnjhlsfmtieqa"), "", S::npos); + test(S("qjghlnftcaismkropdeb"), "bjaht", 19); + test(S("pnalfrdtkqcmojiesbhg"), "hjlcmgpket", 19); + test(S("pniotcfrhqsmgdkjbael"), "htaobedqikfplcgjsmrn", 19); +} + +int main() +{ + { + typedef std::string S; + test0(); + test1(); + } +#if TEST_STD_VER >= 11 + { + typedef std::basic_string, min_allocator> S; + test0(); + test1(); + } +#endif +} diff --git a/tests/external/libcxx/basic_string/string.ops/string_find.last.of/pointer_size_size.pass.cpp b/tests/external/libcxx/basic_string/string.ops/string_find.last.of/pointer_size_size.pass.cpp new file mode 100644 index 0000000..42a076a --- /dev/null +++ b/tests/external/libcxx/basic_string/string.ops/string_find.last.of/pointer_size_size.pass.cpp @@ -0,0 +1,387 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// + +// size_type find_last_of(const charT* s, size_type pos, size_type n) const; + +#include +#include + +#include "min_allocator.h" + +template +void +test(const S& s, const typename S::value_type* str, typename S::size_type pos, + typename S::size_type n, typename S::size_type x) +{ + assert(s.find_last_of(str, pos, n) == x); + if (x != S::npos) + assert(x <= pos && x < s.size()); +} + +template +void test0() +{ + test(S(""), "", 0, 0, S::npos); + test(S(""), "irkhs", 0, 0, S::npos); + test(S(""), "kante", 0, 1, S::npos); + test(S(""), "oknlr", 0, 2, S::npos); + test(S(""), "pcdro", 0, 4, S::npos); + test(S(""), "bnrpe", 0, 5, S::npos); + test(S(""), "jtdaefblso", 0, 0, S::npos); + test(S(""), "oselktgbca", 0, 1, S::npos); + test(S(""), "eqgaplhckj", 0, 5, S::npos); + test(S(""), "bjahtcmnlp", 0, 9, S::npos); + test(S(""), "hjlcmgpket", 0, 10, S::npos); + test(S(""), "htaobedqikfplcgjsmrn", 0, 0, S::npos); + test(S(""), "hpqiarojkcdlsgnmfetb", 0, 1, S::npos); + test(S(""), "dfkaprhjloqetcsimnbg", 0, 10, S::npos); + test(S(""), "ihqrfebgadntlpmjksoc", 0, 19, S::npos); + test(S(""), "ngtjfcalbseiqrphmkdo", 0, 20, S::npos); + test(S(""), "", 1, 0, S::npos); + test(S(""), "lbtqd", 1, 0, S::npos); + test(S(""), "tboim", 1, 1, S::npos); + test(S(""), "slcer", 1, 2, S::npos); + test(S(""), "cbjfs", 1, 4, S::npos); + test(S(""), "aqibs", 1, 5, S::npos); + test(S(""), "gtfblmqinc", 1, 0, S::npos); + test(S(""), "mkqpbtdalg", 1, 1, S::npos); + test(S(""), "kphatlimcd", 1, 5, S::npos); + test(S(""), "pblasqogic", 1, 9, S::npos); + test(S(""), "arosdhcfme", 1, 10, S::npos); + test(S(""), "blkhjeogicatqfnpdmsr", 1, 0, S::npos); + test(S(""), "bmhineprjcoadgstflqk", 1, 1, S::npos); + test(S(""), "djkqcmetslnghpbarfoi", 1, 10, S::npos); + test(S(""), "lgokshjtpbemarcdqnfi", 1, 19, S::npos); + test(S(""), "bqjhtkfepimcnsgrlado", 1, 20, S::npos); + test(S("eaint"), "", 0, 0, S::npos); + test(S("binja"), "gfsrt", 0, 0, S::npos); + test(S("latkm"), "pfsoc", 0, 1, S::npos); + test(S("lecfr"), "tpflm", 0, 2, S::npos); + test(S("eqkst"), "sgkec", 0, 4, 0); + test(S("cdafr"), "romds", 0, 5, S::npos); + test(S("prbhe"), "qhjistlgmr", 0, 0, S::npos); + test(S("lbisk"), "pedfirsglo", 0, 1, S::npos); + test(S("hrlpd"), "aqcoslgrmk", 0, 5, S::npos); + test(S("ehmja"), "dabckmepqj", 0, 9, 0); + test(S("mhqgd"), "pqscrjthli", 0, 10, S::npos); + test(S("tgklq"), "kfphdcsjqmobliagtren", 0, 0, S::npos); + test(S("bocjs"), "rokpefncljibsdhqtagm", 0, 1, S::npos); + test(S("grbsd"), "afionmkphlebtcjqsgrd", 0, 10, S::npos); + test(S("ofjqr"), "aenmqplidhkofrjbctsg", 0, 19, 0); + test(S("btlfi"), "osjmbtcadhiklegrpqnf", 0, 20, 0); + test(S("clrgb"), "", 1, 0, S::npos); + test(S("tjmek"), "osmia", 1, 0, S::npos); + test(S("bgstp"), "ckonl", 1, 1, S::npos); + test(S("hstrk"), "ilcaj", 1, 2, S::npos); + test(S("kmspj"), "lasiq", 1, 4, S::npos); + test(S("tjboh"), "kfqmr", 1, 5, S::npos); + test(S("ilbcj"), "klnitfaobg", 1, 0, S::npos); + test(S("jkngf"), "gjhmdlqikp", 1, 1, S::npos); + test(S("gfcql"), "skbgtahqej", 1, 5, 0); + test(S("dqtlg"), "bjsdgtlpkf", 1, 9, 0); + test(S("bthpg"), "bjgfmnlkio", 1, 10, 0); + test(S("dgsnq"), "lbhepotfsjdqigcnamkr", 1, 0, S::npos); + test(S("rmfhp"), "tebangckmpsrqdlfojhi", 1, 1, S::npos); + test(S("jfdam"), "joflqbdkhtegimscpanr", 1, 10, 1); + test(S("edapb"), "adpmcohetfbsrjinlqkg", 1, 19, 1); + test(S("brfsm"), "iacldqjpfnogbsrhmetk", 1, 20, 1); + test(S("ndrhl"), "", 2, 0, S::npos); + test(S("mrecp"), "otkgb", 2, 0, S::npos); + test(S("qlasf"), "cqsjl", 2, 1, S::npos); + test(S("smaqd"), "dpifl", 2, 2, S::npos); + test(S("hjeni"), "oapht", 2, 4, 0); + test(S("ocmfj"), "cifts", 2, 5, 1); + test(S("hmftq"), "nmsckbgalo", 2, 0, S::npos); + test(S("fklad"), "tpksqhamle", 2, 1, S::npos); + test(S("dirnm"), "tpdrchmkji", 2, 5, 2); + test(S("hrgdc"), "ijagfkblst", 2, 9, 2); + test(S("ifakg"), "kpocsignjb", 2, 10, 0); + test(S("ebrgd"), "pecqtkjsnbdrialgmohf", 2, 0, S::npos); + test(S("rcjml"), "aiortphfcmkjebgsndql", 2, 1, S::npos); + test(S("peqmt"), "sdbkeamglhipojqftrcn", 2, 10, 1); + test(S("frehn"), "ljqncehgmfktroapidbs", 2, 19, 2); + test(S("tqolf"), "rtcfodilamkbenjghqps", 2, 20, 2); + test(S("cjgao"), "", 4, 0, S::npos); + test(S("kjplq"), "mabns", 4, 0, S::npos); + test(S("herni"), "bdnrp", 4, 1, S::npos); + test(S("tadrb"), "scidp", 4, 2, S::npos); + test(S("pkfeo"), "agbjl", 4, 4, S::npos); + test(S("hoser"), "jfmpr", 4, 5, 4); + test(S("kgrsp"), "rbpefghsmj", 4, 0, S::npos); + test(S("pgejb"), "apsfntdoqc", 4, 1, S::npos); + test(S("thlnq"), "ndkjeisgcl", 4, 5, 3); + test(S("nbmit"), "rnfpqatdeo", 4, 9, 4); + test(S("jgmib"), "bntjlqrfik", 4, 10, 4); + test(S("ncrfj"), "kcrtmpolnaqejghsfdbi", 4, 0, S::npos); + test(S("ncsik"), "lobheanpkmqidsrtcfgj", 4, 1, S::npos); + test(S("sgbfh"), "athdkljcnreqbgpmisof", 4, 10, 4); + test(S("dktbn"), "qkdmjialrscpbhefgont", 4, 19, 4); + test(S("fthqm"), "dmasojntqleribkgfchp", 4, 20, 4); + test(S("klopi"), "", 5, 0, S::npos); + test(S("dajhn"), "psthd", 5, 0, S::npos); + test(S("jbgno"), "rpmjd", 5, 1, S::npos); + test(S("hkjae"), "dfsmk", 5, 2, S::npos); +} + +template +void test1() +{ + test(S("gbhqo"), "skqne", 5, 4, 3); + test(S("ktdor"), "kipnf", 5, 5, 0); + test(S("ldprn"), "hmrnqdgifl", 5, 0, S::npos); + test(S("egmjk"), "fsmjcdairn", 5, 1, S::npos); + test(S("armql"), "pcdgltbrfj", 5, 5, 4); + test(S("cdhjo"), "aekfctpirg", 5, 9, 0); + test(S("jcons"), "ledihrsgpf", 5, 10, 4); + test(S("cbrkp"), "mqcklahsbtirgopefndj", 5, 0, S::npos); + test(S("fhgna"), "kmlthaoqgecrnpdbjfis", 5, 1, S::npos); + test(S("ejfcd"), "sfhbamcdptojlkrenqgi", 5, 10, 4); + test(S("kqjhe"), "pbniofmcedrkhlstgaqj", 5, 19, 4); + test(S("pbdjl"), "mongjratcskbhqiepfdl", 5, 20, 4); + test(S("gajqn"), "", 6, 0, S::npos); + test(S("stedk"), "hrnat", 6, 0, S::npos); + test(S("tjkaf"), "gsqdt", 6, 1, S::npos); + test(S("dthpe"), "bspkd", 6, 2, S::npos); + test(S("klhde"), "ohcmb", 6, 4, 2); + test(S("bhlki"), "heatr", 6, 5, 1); + test(S("lqmoh"), "pmblckedfn", 6, 0, S::npos); + test(S("mtqin"), "aceqmsrbik", 6, 1, S::npos); + test(S("dpqbr"), "lmbtdehjrn", 6, 5, 3); + test(S("kdhmo"), "teqmcrlgib", 6, 9, 3); + test(S("jblqp"), "njolbmspac", 6, 10, 4); + test(S("qmjgl"), "pofnhidklamecrbqjgst", 6, 0, S::npos); + test(S("rothp"), "jbhckmtgrqnosafedpli", 6, 1, S::npos); + test(S("ghknq"), "dobntpmqklicsahgjerf", 6, 10, 4); + test(S("eopfi"), "tpdshainjkbfoemlrgcq", 6, 19, 4); + test(S("dsnmg"), "oldpfgeakrnitscbjmqh", 6, 20, 4); + test(S("jnkrfhotgl"), "", 0, 0, S::npos); + test(S("dltjfngbko"), "rqegt", 0, 0, S::npos); + test(S("bmjlpkiqde"), "dashm", 0, 1, S::npos); + test(S("skrflobnqm"), "jqirk", 0, 2, S::npos); + test(S("jkpldtshrm"), "rckeg", 0, 4, S::npos); + test(S("ghasdbnjqo"), "jscie", 0, 5, S::npos); + test(S("igrkhpbqjt"), "efsphndliq", 0, 0, S::npos); + test(S("ikthdgcamf"), "gdicosleja", 0, 1, S::npos); + test(S("pcofgeniam"), "qcpjibosfl", 0, 5, 0); + test(S("rlfjgesqhc"), "lrhmefnjcq", 0, 9, 0); + test(S("itphbqsker"), "dtablcrseo", 0, 10, S::npos); + test(S("skjafcirqm"), "apckjsftedbhgomrnilq", 0, 0, S::npos); + test(S("tcqomarsfd"), "pcbrgflehjtiadnsokqm", 0, 1, S::npos); + test(S("rocfeldqpk"), "nsiadegjklhobrmtqcpf", 0, 10, S::npos); + test(S("cfpegndlkt"), "cpmajdqnolikhgsbretf", 0, 19, 0); + test(S("fqbtnkeasj"), "jcflkntmgiqrphdosaeb", 0, 20, 0); + test(S("shbcqnmoar"), "", 1, 0, S::npos); + test(S("bdoshlmfin"), "ontrs", 1, 0, S::npos); + test(S("khfrebnsgq"), "pfkna", 1, 1, S::npos); + test(S("getcrsaoji"), "ekosa", 1, 2, 1); + test(S("fjiknedcpq"), "anqhk", 1, 4, S::npos); + test(S("tkejgnafrm"), "jekca", 1, 5, 1); + test(S("jnakolqrde"), "ikemsjgacf", 1, 0, S::npos); + test(S("lcjptsmgbe"), "arolgsjkhm", 1, 1, S::npos); + test(S("itfsmcjorl"), "oftkbldhre", 1, 5, 1); + test(S("omchkfrjea"), "gbkqdoeftl", 1, 9, 0); + test(S("cigfqkated"), "sqcflrgtim", 1, 10, 1); + test(S("tscenjikml"), "fmhbkislrjdpanogqcet", 1, 0, S::npos); + test(S("qcpaemsinf"), "rnioadktqlgpbcjsmhef", 1, 1, S::npos); + test(S("gltkojeipd"), "oakgtnldpsefihqmjcbr", 1, 10, 1); + test(S("qistfrgnmp"), "gbnaelosidmcjqktfhpr", 1, 19, 1); + test(S("bdnpfcqaem"), "akbripjhlosndcmqgfet", 1, 20, 1); + test(S("ectnhskflp"), "", 5, 0, S::npos); + test(S("fgtianblpq"), "pijag", 5, 0, S::npos); + test(S("mfeqklirnh"), "jrckd", 5, 1, S::npos); + test(S("astedncjhk"), "qcloh", 5, 2, S::npos); + test(S("fhlqgcajbr"), "thlmp", 5, 4, 2); + test(S("epfhocmdng"), "qidmo", 5, 5, 4); + test(S("apcnsibger"), "lnegpsjqrd", 5, 0, S::npos); + test(S("aqkocrbign"), "rjqdablmfs", 5, 1, 5); + test(S("ijsmdtqgce"), "enkgpbsjaq", 5, 5, S::npos); + test(S("clobgsrken"), "kdsgoaijfh", 5, 9, 5); + test(S("jbhcfposld"), "trfqgmckbe", 5, 10, 4); + test(S("oqnpblhide"), "igetsracjfkdnpoblhqm", 5, 0, S::npos); + test(S("lroeasctif"), "nqctfaogirshlekbdjpm", 5, 1, S::npos); + test(S("bpjlgmiedh"), "csehfgomljdqinbartkp", 5, 10, 5); + test(S("pamkeoidrj"), "qahoegcmplkfsjbdnitr", 5, 19, 5); + test(S("espogqbthk"), "dpteiajrqmsognhlfbkc", 5, 20, 5); + test(S("shoiedtcjb"), "", 9, 0, S::npos); + test(S("ebcinjgads"), "tqbnh", 9, 0, S::npos); + test(S("dqmregkcfl"), "akmle", 9, 1, S::npos); + test(S("ngcrieqajf"), "iqfkm", 9, 2, 6); + test(S("qosmilgnjb"), "tqjsr", 9, 4, 8); + test(S("ikabsjtdfl"), "jplqg", 9, 5, 9); + test(S("ersmicafdh"), "oilnrbcgtj", 9, 0, S::npos); + test(S("fdnplotmgh"), "morkglpesn", 9, 1, 7); + test(S("fdbicojerm"), "dmicerngat", 9, 5, 9); + test(S("mbtafndjcq"), "radgeskbtc", 9, 9, 6); + test(S("mlenkpfdtc"), "ljikprsmqo", 9, 10, 5); + test(S("ahlcifdqgs"), "trqihkcgsjamfdbolnpe", 9, 0, S::npos); + test(S("bgjemaltks"), "lqmthbsrekajgnofcipd", 9, 1, 6); + test(S("pdhslbqrfc"), "jtalmedribkgqsopcnfh", 9, 10, 7); + test(S("dirhtsnjkc"), "spqfoiclmtagejbndkrh", 9, 19, 9); + test(S("dlroktbcja"), "nmotklspigjrdhcfaebq", 9, 20, 9); + test(S("ncjpmaekbs"), "", 10, 0, S::npos); + test(S("hlbosgmrak"), "hpmsd", 10, 0, S::npos); + test(S("pqfhsgilen"), "qnpor", 10, 1, 1); + test(S("gqtjsbdckh"), "otdma", 10, 2, 2); + test(S("cfkqpjlegi"), "efhjg", 10, 4, 7); + test(S("beanrfodgj"), "odpte", 10, 5, 7); + test(S("adtkqpbjfi"), "bctdgfmolr", 10, 0, S::npos); + test(S("iomkfthagj"), "oaklidrbqg", 10, 1, 1); +} + +template +void test2() +{ + test(S("sdpcilonqj"), "dnjfsagktr", 10, 5, 9); + test(S("gtfbdkqeml"), "nejaktmiqg", 10, 9, 8); + test(S("bmeqgcdorj"), "pjqonlebsf", 10, 10, 9); + test(S("etqlcanmob"), "dshmnbtolcjepgaikfqr", 10, 0, S::npos); + test(S("roqmkbdtia"), "iogfhpabtjkqlrnemcds", 10, 1, 8); + test(S("kadsithljf"), "ngridfabjsecpqltkmoh", 10, 10, 9); + test(S("sgtkpbfdmh"), "athmknplcgofrqejsdib", 10, 19, 9); + test(S("qgmetnabkl"), "ldobhmqcafnjtkeisgrp", 10, 20, 9); + test(S("cqjohampgd"), "", 11, 0, S::npos); + test(S("hobitmpsan"), "aocjb", 11, 0, S::npos); + test(S("tjehkpsalm"), "jbrnk", 11, 1, 1); + test(S("ngfbojitcl"), "tqedg", 11, 2, 7); + test(S("rcfkdbhgjo"), "nqskp", 11, 4, 3); + test(S("qghptonrea"), "eaqkl", 11, 5, 9); + test(S("hnprfgqjdl"), "reaoicljqm", 11, 0, S::npos); + test(S("hlmgabenti"), "lsftgajqpm", 11, 1, 1); + test(S("ofcjanmrbs"), "rlpfogmits", 11, 5, 7); + test(S("jqedtkornm"), "shkncmiaqj", 11, 9, 9); + test(S("rfedlasjmg"), "fpnatrhqgs", 11, 10, 9); + test(S("talpqjsgkm"), "sjclemqhnpdbgikarfot", 11, 0, S::npos); + test(S("lrkcbtqpie"), "otcmedjikgsfnqbrhpla", 11, 1, S::npos); + test(S("cipogdskjf"), "bonsaefdqiprkhlgtjcm", 11, 10, 9); + test(S("nqedcojahi"), "egpscmahijlfnkrodqtb", 11, 19, 9); + test(S("hefnrkmctj"), "kmqbfepjthgilscrndoa", 11, 20, 9); + test(S("atqirnmekfjolhpdsgcb"), "", 0, 0, S::npos); + test(S("echfkmlpribjnqsaogtd"), "prboq", 0, 0, S::npos); + test(S("qnhiftdgcleajbpkrosm"), "fjcqh", 0, 1, S::npos); + test(S("chamfknorbedjitgslpq"), "fmosa", 0, 2, S::npos); + test(S("njhqpibfmtlkaecdrgso"), "qdbok", 0, 4, S::npos); + test(S("ebnghfsqkprmdcljoiat"), "amslg", 0, 5, S::npos); + test(S("letjomsgihfrpqbkancd"), "smpltjneqb", 0, 0, S::npos); + test(S("nblgoipcrqeaktshjdmf"), "flitskrnge", 0, 1, S::npos); + test(S("cehkbngtjoiflqapsmrd"), "pgqihmlbef", 0, 5, S::npos); + test(S("mignapfoklbhcqjetdrs"), "cfpdqjtgsb", 0, 9, S::npos); + test(S("ceatbhlsqjgpnokfrmdi"), "htpsiaflom", 0, 10, S::npos); + test(S("ocihkjgrdelpfnmastqb"), "kpjfiaceghsrdtlbnomq", 0, 0, S::npos); + test(S("noelgschdtbrjfmiqkap"), "qhtbomidljgafneksprc", 0, 1, S::npos); + test(S("dkclqfombepritjnghas"), "nhtjobkcefldimpsaqgr", 0, 10, S::npos); + test(S("miklnresdgbhqcojftap"), "prabcjfqnoeskilmtgdh", 0, 19, 0); + test(S("htbcigojaqmdkfrnlsep"), "dtrgmchilkasqoebfpjn", 0, 20, 0); + test(S("febhmqtjanokscdirpgl"), "", 1, 0, S::npos); + test(S("loakbsqjpcrdhftniegm"), "sqome", 1, 0, S::npos); + test(S("reagphsqflbitdcjmkno"), "smfte", 1, 1, S::npos); + test(S("jitlfrqemsdhkopncabg"), "ciboh", 1, 2, 1); + test(S("mhtaepscdnrjqgbkifol"), "haois", 1, 4, 1); + test(S("tocesrfmnglpbjihqadk"), "abfki", 1, 5, S::npos); + test(S("lpfmctjrhdagneskbqoi"), "frdkocntmq", 1, 0, S::npos); + test(S("lsmqaepkdhncirbtjfgo"), "oasbpedlnr", 1, 1, S::npos); + test(S("epoiqmtldrabnkjhcfsg"), "kltqmhgand", 1, 5, S::npos); + test(S("emgasrilpknqojhtbdcf"), "gdtfjchpmr", 1, 9, 1); + test(S("hnfiagdpcklrjetqbsom"), "ponmcqblet", 1, 10, 1); + test(S("nsdfebgajhmtricpoklq"), "sgphqdnofeiklatbcmjr", 1, 0, S::npos); + test(S("atjgfsdlpobmeiqhncrk"), "ljqprsmigtfoneadckbh", 1, 1, S::npos); + test(S("sitodfgnrejlahcbmqkp"), "ligeojhafnkmrcsqtbdp", 1, 10, 1); + test(S("fraghmbiceknltjpqosd"), "lsimqfnjarbopedkhcgt", 1, 19, 1); + test(S("pmafenlhqtdbkirjsogc"), "abedmfjlghniorcqptks", 1, 20, 1); + test(S("pihgmoeqtnakrjslcbfd"), "", 10, 0, S::npos); + test(S("gjdkeprctqblnhiafsom"), "hqtoa", 10, 0, S::npos); + test(S("mkpnblfdsahrcqijteog"), "cahif", 10, 1, S::npos); + test(S("gckarqnelodfjhmbptis"), "kehis", 10, 2, 7); + test(S("gqpskidtbclomahnrjfe"), "kdlmh", 10, 4, 10); + test(S("pkldjsqrfgitbhmaecno"), "paeql", 10, 5, 6); + test(S("aftsijrbeklnmcdqhgop"), "aghoqiefnb", 10, 0, S::npos); + test(S("mtlgdrhafjkbiepqnsoc"), "jrbqaikpdo", 10, 1, 9); + test(S("pqgirnaefthokdmbsclj"), "smjonaeqcl", 10, 5, 5); + test(S("kpdbgjmtherlsfcqoina"), "eqbdrkcfah", 10, 9, 10); + test(S("jrlbothiknqmdgcfasep"), "kapmsienhf", 10, 10, 9); + test(S("mjogldqferckabinptsh"), "jpqotrlenfcsbhkaimdg", 10, 0, S::npos); + test(S("apoklnefbhmgqcdrisjt"), "jlbmhnfgtcqprikeados", 10, 1, S::npos); + test(S("ifeopcnrjbhkdgatmqls"), "stgbhfmdaljnpqoicker", 10, 10, 10); + test(S("ckqhaiesmjdnrgolbtpf"), "oihcetflbjagdsrkmqpn", 10, 19, 10); + test(S("bnlgapfimcoterskqdjh"), "adtclebmnpjsrqfkigoh", 10, 20, 10); + test(S("kgdlrobpmjcthqsafeni"), "", 19, 0, S::npos); + test(S("dfkechomjapgnslbtqir"), "beafg", 19, 0, S::npos); + test(S("rloadknfbqtgmhcsipje"), "iclat", 19, 1, 16); + test(S("mgjhkolrnadqbpetcifs"), "rkhnf", 19, 2, 7); + test(S("cmlfakiojdrgtbsphqen"), "clshq", 19, 4, 16); + test(S("kghbfipeomsntdalrqjc"), "dtcoj", 19, 5, 19); + test(S("eldiqckrnmtasbghjfpo"), "rqosnjmfth", 19, 0, S::npos); + test(S("abqjcfedgotihlnspkrm"), "siatdfqglh", 19, 1, 15); + test(S("qfbadrtjsimkolcenhpg"), "mrlshtpgjq", 19, 5, 17); + test(S("abseghclkjqifmtodrnp"), "adlcskgqjt", 19, 9, 16); + test(S("ibmsnlrjefhtdokacqpg"), "drshcjknaf", 19, 10, 16); + test(S("mrkfciqjebaponsthldg"), "etsaqroinghpkjdlfcbm", 19, 0, S::npos); + test(S("mjkticdeoqshpalrfbgn"), "sgepdnkqliambtrocfhj", 19, 1, 10); + test(S("rqnoclbdejgiphtfsakm"), "nlmcjaqgbsortfdihkpe", 19, 10, 19); + test(S("plkqbhmtfaeodjcrsing"), "racfnpmosldibqkghjet", 19, 19, 19); + test(S("oegalhmstjrfickpbndq"), "fjhdsctkqeiolagrnmbp", 19, 20, 19); + test(S("rdtgjcaohpblniekmsfq"), "", 20, 0, S::npos); + test(S("ofkqbnjetrmsaidphglc"), "ejanp", 20, 0, S::npos); + test(S("grkpahljcftesdmonqib"), "odife", 20, 1, 15); + test(S("jimlgbhfqkteospardcn"), "okaqd", 20, 2, 12); + test(S("gftenihpmslrjkqadcob"), "lcdbi", 20, 4, 19); + test(S("bmhldogtckrfsanijepq"), "fsqbj", 20, 5, 19); + test(S("nfqkrpjdesabgtlcmoih"), "bigdomnplq", 20, 0, S::npos); + test(S("focalnrpiqmdkstehbjg"), "apiblotgcd", 20, 1, 3); + test(S("rhqdspkmebiflcotnjga"), "acfhdenops", 20, 5, 19); + test(S("rahdtmsckfboqlpniegj"), "jopdeamcrk", 20, 9, 19); + test(S("fbkeiopclstmdqranjhg"), "trqncbkgmh", 20, 10, 19); + test(S("lifhpdgmbconstjeqark"), "tomglrkencbsfjqpihda", 20, 0, S::npos); +} + +template +void test3() +{ + test(S("pboqganrhedjmltsicfk"), "gbkhdnpoietfcmrslajq", 20, 1, 4); + test(S("klchabsimetjnqgorfpd"), "rtfnmbsglkjaichoqedp", 20, 10, 17); + test(S("sirfgmjqhctndbklaepo"), "ohkmdpfqbsacrtjnlgei", 20, 19, 19); + test(S("rlbdsiceaonqjtfpghkm"), "dlbrteoisgphmkncajfq", 20, 20, 19); + test(S("ecgdanriptblhjfqskom"), "", 21, 0, S::npos); + test(S("fdmiarlpgcskbhoteqjn"), "sjrlo", 21, 0, S::npos); + test(S("rlbstjqopignecmfadkh"), "qjpor", 21, 1, 6); + test(S("grjpqmbshektdolcafni"), "odhfn", 21, 2, 13); + test(S("sakfcohtqnibprjmlged"), "qtfin", 21, 4, 10); + test(S("mjtdglasihqpocebrfkn"), "hpqfo", 21, 5, 17); + test(S("okaplfrntghqbmeicsdj"), "fabmertkos", 21, 0, S::npos); + test(S("sahngemrtcjidqbklfpo"), "brqtgkmaej", 21, 1, 14); + test(S("dlmsipcnekhbgoaftqjr"), "nfrdeihsgl", 21, 5, 19); + test(S("ahegrmqnoiklpfsdbcjt"), "hlfrosekpi", 21, 9, 14); + test(S("hdsjbnmlegtkqripacof"), "atgbkrjdsm", 21, 10, 16); + test(S("pcnedrfjihqbalkgtoms"), "blnrptjgqmaifsdkhoec", 21, 0, S::npos); + test(S("qjidealmtpskrbfhocng"), "ctpmdahebfqjgknloris", 21, 1, 17); + test(S("qeindtagmokpfhsclrbj"), "apnkeqthrmlbfodiscgj", 21, 10, 17); + test(S("kpfegbjhsrnodltqciam"), "jdgictpframeoqlsbknh", 21, 19, 19); + test(S("hnbrcplsjfgiktoedmaq"), "qprlsfojamgndekthibc", 21, 20, 19); +} + +int main() +{ + { + typedef std::string S; + test0(); + test1(); + test2(); + test3(); + } +#if TEST_STD_VER >= 11 + { + typedef std::basic_string, min_allocator> S; + test0(); + test1(); + test2(); + test3(); + } +#endif +} diff --git a/tests/external/libcxx/basic_string/string.ops/string_find.last.of/string_size.pass.cpp b/tests/external/libcxx/basic_string/string.ops/string_find.last.of/string_size.pass.cpp new file mode 100644 index 0000000..b6b5b8f --- /dev/null +++ b/tests/external/libcxx/basic_string/string.ops/string_find.last.of/string_size.pass.cpp @@ -0,0 +1,165 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// + +// size_type find_last_of(const basic_string& str, size_type pos = npos) const; + +#include +#include + +#include "test_macros.h" +#include "min_allocator.h" + +template +void +test(const S& s, const S& str, typename S::size_type pos, typename S::size_type x) +{ + assert(s.find_last_of(str, pos) == x); + if (x != S::npos) + assert(x <= pos && x < s.size()); +} + +template +void +test(const S& s, const S& str, typename S::size_type x) +{ + assert(s.find_last_of(str) == x); + if (x != S::npos) + assert(x < s.size()); +} + +template +void test0() +{ + test(S(""), S(""), 0, S::npos); + test(S(""), S("laenf"), 0, S::npos); + test(S(""), S("pqlnkmbdjo"), 0, S::npos); + test(S(""), S("qkamfogpnljdcshbreti"), 0, S::npos); + test(S(""), S(""), 1, S::npos); + test(S(""), S("bjaht"), 1, S::npos); + test(S(""), S("hjlcmgpket"), 1, S::npos); + test(S(""), S("htaobedqikfplcgjsmrn"), 1, S::npos); + test(S("fodgq"), S(""), 0, S::npos); + test(S("qanej"), S("dfkap"), 0, S::npos); + test(S("clbao"), S("ihqrfebgad"), 0, S::npos); + test(S("mekdn"), S("ngtjfcalbseiqrphmkdo"), 0, 0); + test(S("srdfq"), S(""), 1, S::npos); + test(S("oemth"), S("ikcrq"), 1, S::npos); + test(S("cdaih"), S("dmajblfhsg"), 1, 1); + test(S("qohtk"), S("oqftjhdmkgsblacenirp"), 1, 1); + test(S("cshmd"), S(""), 2, S::npos); + test(S("lhcdo"), S("oebqi"), 2, S::npos); + test(S("qnsoh"), S("kojhpmbsfe"), 2, 2); + test(S("pkrof"), S("acbsjqogpltdkhinfrem"), 2, 2); + test(S("fmtsp"), S(""), 4, S::npos); + test(S("khbpm"), S("aobjd"), 4, 2); + test(S("pbsji"), S("pcbahntsje"), 4, 3); + test(S("mprdj"), S("fhepcrntkoagbmldqijs"), 4, 4); + test(S("eqmpa"), S(""), 5, S::npos); + test(S("omigs"), S("kocgb"), 5, 3); + test(S("onmje"), S("fbslrjiqkm"), 5, 3); + test(S("oqmrj"), S("jeidpcmalhfnqbgtrsko"), 5, 4); + test(S("schfa"), S(""), 6, S::npos); + test(S("igdsc"), S("qngpd"), 6, 2); + test(S("brqgo"), S("rodhqklgmb"), 6, 4); + test(S("tnrph"), S("thdjgafrlbkoiqcspmne"), 6, 4); + test(S("hcjitbfapl"), S(""), 0, S::npos); + test(S("daiprenocl"), S("ashjd"), 0, 0); + test(S("litpcfdghe"), S("mgojkldsqh"), 0, 0); + test(S("aidjksrolc"), S("imqnaghkfrdtlopbjesc"), 0, 0); + test(S("qpghtfbaji"), S(""), 1, S::npos); + test(S("gfshlcmdjr"), S("nadkh"), 1, S::npos); + test(S("nkodajteqp"), S("ofdrqmkebl"), 1, 1); + test(S("gbmetiprqd"), S("bdfjqgatlksriohemnpc"), 1, 1); + test(S("crnklpmegd"), S(""), 5, S::npos); + test(S("jsbtafedoc"), S("prqgn"), 5, S::npos); + test(S("qnmodrtkeb"), S("pejafmnokr"), 5, 5); + test(S("cpebqsfmnj"), S("odnqkgijrhabfmcestlp"), 5, 5); + test(S("lmofqdhpki"), S(""), 9, S::npos); + test(S("hnefkqimca"), S("rtjpa"), 9, 9); + test(S("drtasbgmfp"), S("ktsrmnqagd"), 9, 7); + test(S("lsaijeqhtr"), S("rtdhgcisbnmoaqkfpjle"), 9, 9); + test(S("elgofjmbrq"), S(""), 10, S::npos); + test(S("mjqdgalkpc"), S("dplqa"), 10, 8); + test(S("kthqnfcerm"), S("dkacjoptns"), 10, 6); + test(S("dfsjhanorc"), S("hqfimtrgnbekpdcsjalo"), 10, 9); + test(S("eqsgalomhb"), S(""), 11, S::npos); + test(S("akiteljmoh"), S("lofbc"), 11, 8); + test(S("hlbdfreqjo"), S("astoegbfpn"), 11, 9); + test(S("taqobhlerg"), S("pdgreqomsncafklhtibj"), 11, 9); + test(S("snafbdlghrjkpqtoceim"), S(""), 0, S::npos); + test(S("aemtbrgcklhndjisfpoq"), S("lbtqd"), 0, S::npos); + test(S("pnracgfkjdiholtbqsem"), S("tboimldpjh"), 0, 0); + test(S("dicfltehbsgrmojnpkaq"), S("slcerthdaiqjfnobgkpm"), 0, 0); + test(S("jlnkraeodhcspfgbqitm"), S(""), 1, S::npos); + test(S("lhosrngtmfjikbqpcade"), S("aqibs"), 1, S::npos); + test(S("rbtaqjhgkneisldpmfoc"), S("gtfblmqinc"), 1, 1); + test(S("gpifsqlrdkbonjtmheca"), S("mkqpbtdalgniorhfescj"), 1, 1); + test(S("hdpkobnsalmcfijregtq"), S(""), 10, S::npos); + test(S("jtlshdgqaiprkbcoenfm"), S("pblas"), 10, 10); + test(S("fkdrbqltsgmcoiphneaj"), S("arosdhcfme"), 10, 10); + test(S("crsplifgtqedjohnabmk"), S("blkhjeogicatqfnpdmsr"), 10, 10); + test(S("niptglfbosehkamrdqcj"), S(""), 19, S::npos); + test(S("copqdhstbingamjfkler"), S("djkqc"), 19, 16); + test(S("mrtaefilpdsgocnhqbjk"), S("lgokshjtpb"), 19, 19); + test(S("kojatdhlcmigpbfrqnes"), S("bqjhtkfepimcnsgrlado"), 19, 19); + test(S("eaintpchlqsbdgrkjofm"), S(""), 20, S::npos); + test(S("gjnhidfsepkrtaqbmclo"), S("nocfa"), 20, 19); + test(S("spocfaktqdbiejlhngmr"), S("bgtajmiedc"), 20, 18); + test(S("rphmlekgfscndtaobiqj"), S("lsckfnqgdahejiopbtmr"), 20, 19); + test(S("liatsqdoegkmfcnbhrpj"), S(""), 21, S::npos); + test(S("binjagtfldkrspcomqeh"), S("gfsrt"), 21, 12); + test(S("latkmisecnorjbfhqpdg"), S("pfsocbhjtm"), 21, 17); + test(S("lecfratdjkhnsmqpoigb"), S("tpflmdnoicjgkberhqsa"), 21, 19); +} + +template +void test1() +{ + test(S(""), S(""), S::npos); + test(S(""), S("laenf"), S::npos); + test(S(""), S("pqlnkmbdjo"), S::npos); + test(S(""), S("qkamfogpnljdcshbreti"), S::npos); + test(S("nhmko"), S(""), S::npos); + test(S("lahfb"), S("irkhs"), 2); + test(S("gmfhd"), S("kantesmpgj"), 1); + test(S("odaft"), S("oknlrstdpiqmjbaghcfe"), 4); + test(S("eolhfgpjqk"), S(""), S::npos); + test(S("nbatdlmekr"), S("bnrpe"), 9); + test(S("jdmciepkaq"), S("jtdaefblso"), 8); + test(S("hkbgspoflt"), S("oselktgbcapndfjihrmq"), 9); + test(S("gprdcokbnjhlsfmtieqa"), S(""), S::npos); + test(S("qjghlnftcaismkropdeb"), S("bjaht"), 19); + test(S("pnalfrdtkqcmojiesbhg"), S("hjlcmgpket"), 19); + test(S("pniotcfrhqsmgdkjbael"), S("htaobedqikfplcgjsmrn"), 19); +} + +int main() +{ + { + typedef std::string S; + test0(); + test1(); + } +#if TEST_STD_VER >= 11 + { + typedef std::basic_string, min_allocator> S; + test0(); + test1(); + } +#endif + +#if TEST_STD_VER > 3 + { // LWG 2946 + std::string s = " !"; + assert(s.find_last_of({"abc", 1}) == std::string::npos); + } +#endif +} diff --git a/tests/external/libcxx/basic_string/string.ops/string_find.last.of/string_view_size.pass.cpp b/tests/external/libcxx/basic_string/string.ops/string_find.last.of/string_view_size.pass.cpp new file mode 100644 index 0000000..fb8ca34 --- /dev/null +++ b/tests/external/libcxx/basic_string/string.ops/string_find.last.of/string_view_size.pass.cpp @@ -0,0 +1,159 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// + +// size_type find_last_of(const basic_string_view sv, size_type pos = npos) const; + +#include +#include + +#include "min_allocator.h" + +template +void +test(const S& s, SV sv, typename S::size_type pos, typename S::size_type x) +{ + assert(s.find_last_of(sv, pos) == x); + if (x != S::npos) + assert(x <= pos && x < s.size()); +} + +template +void +test(const S& s, SV sv, typename S::size_type x) +{ + assert(s.find_last_of(sv) == x); + if (x != S::npos) + assert(x < s.size()); +} + +template +void test0() +{ + test(S(""), SV(""), 0, S::npos); + test(S(""), SV("laenf"), 0, S::npos); + test(S(""), SV("pqlnkmbdjo"), 0, S::npos); + test(S(""), SV("qkamfogpnljdcshbreti"), 0, S::npos); + test(S(""), SV(""), 1, S::npos); + test(S(""), SV("bjaht"), 1, S::npos); + test(S(""), SV("hjlcmgpket"), 1, S::npos); + test(S(""), SV("htaobedqikfplcgjsmrn"), 1, S::npos); + test(S("fodgq"), SV(""), 0, S::npos); + test(S("qanej"), SV("dfkap"), 0, S::npos); + test(S("clbao"), SV("ihqrfebgad"), 0, S::npos); + test(S("mekdn"), SV("ngtjfcalbseiqrphmkdo"), 0, 0); + test(S("srdfq"), SV(""), 1, S::npos); + test(S("oemth"), SV("ikcrq"), 1, S::npos); + test(S("cdaih"), SV("dmajblfhsg"), 1, 1); + test(S("qohtk"), SV("oqftjhdmkgsblacenirp"), 1, 1); + test(S("cshmd"), SV(""), 2, S::npos); + test(S("lhcdo"), SV("oebqi"), 2, S::npos); + test(S("qnsoh"), SV("kojhpmbsfe"), 2, 2); + test(S("pkrof"), SV("acbsjqogpltdkhinfrem"), 2, 2); + test(S("fmtsp"), SV(""), 4, S::npos); + test(S("khbpm"), SV("aobjd"), 4, 2); + test(S("pbsji"), SV("pcbahntsje"), 4, 3); + test(S("mprdj"), SV("fhepcrntkoagbmldqijs"), 4, 4); + test(S("eqmpa"), SV(""), 5, S::npos); + test(S("omigs"), SV("kocgb"), 5, 3); + test(S("onmje"), SV("fbslrjiqkm"), 5, 3); + test(S("oqmrj"), SV("jeidpcmalhfnqbgtrsko"), 5, 4); + test(S("schfa"), SV(""), 6, S::npos); + test(S("igdsc"), SV("qngpd"), 6, 2); + test(S("brqgo"), SV("rodhqklgmb"), 6, 4); + test(S("tnrph"), SV("thdjgafrlbkoiqcspmne"), 6, 4); + test(S("hcjitbfapl"), SV(""), 0, S::npos); + test(S("daiprenocl"), SV("ashjd"), 0, 0); + test(S("litpcfdghe"), SV("mgojkldsqh"), 0, 0); + test(S("aidjksrolc"), SV("imqnaghkfrdtlopbjesc"), 0, 0); + test(S("qpghtfbaji"), SV(""), 1, S::npos); + test(S("gfshlcmdjr"), SV("nadkh"), 1, S::npos); + test(S("nkodajteqp"), SV("ofdrqmkebl"), 1, 1); + test(S("gbmetiprqd"), SV("bdfjqgatlksriohemnpc"), 1, 1); + test(S("crnklpmegd"), SV(""), 5, S::npos); + test(S("jsbtafedoc"), SV("prqgn"), 5, S::npos); + test(S("qnmodrtkeb"), SV("pejafmnokr"), 5, 5); + test(S("cpebqsfmnj"), SV("odnqkgijrhabfmcestlp"), 5, 5); + test(S("lmofqdhpki"), SV(""), 9, S::npos); + test(S("hnefkqimca"), SV("rtjpa"), 9, 9); + test(S("drtasbgmfp"), SV("ktsrmnqagd"), 9, 7); + test(S("lsaijeqhtr"), SV("rtdhgcisbnmoaqkfpjle"), 9, 9); + test(S("elgofjmbrq"), SV(""), 10, S::npos); + test(S("mjqdgalkpc"), SV("dplqa"), 10, 8); + test(S("kthqnfcerm"), SV("dkacjoptns"), 10, 6); + test(S("dfsjhanorc"), SV("hqfimtrgnbekpdcsjalo"), 10, 9); + test(S("eqsgalomhb"), SV(""), 11, S::npos); + test(S("akiteljmoh"), SV("lofbc"), 11, 8); + test(S("hlbdfreqjo"), SV("astoegbfpn"), 11, 9); + test(S("taqobhlerg"), SV("pdgreqomsncafklhtibj"), 11, 9); + test(S("snafbdlghrjkpqtoceim"), SV(""), 0, S::npos); + test(S("aemtbrgcklhndjisfpoq"), SV("lbtqd"), 0, S::npos); + test(S("pnracgfkjdiholtbqsem"), SV("tboimldpjh"), 0, 0); + test(S("dicfltehbsgrmojnpkaq"), SV("slcerthdaiqjfnobgkpm"), 0, 0); + test(S("jlnkraeodhcspfgbqitm"), SV(""), 1, S::npos); + test(S("lhosrngtmfjikbqpcade"), SV("aqibs"), 1, S::npos); + test(S("rbtaqjhgkneisldpmfoc"), SV("gtfblmqinc"), 1, 1); + test(S("gpifsqlrdkbonjtmheca"), SV("mkqpbtdalgniorhfescj"), 1, 1); + test(S("hdpkobnsalmcfijregtq"), SV(""), 10, S::npos); + test(S("jtlshdgqaiprkbcoenfm"), SV("pblas"), 10, 10); + test(S("fkdrbqltsgmcoiphneaj"), SV("arosdhcfme"), 10, 10); + test(S("crsplifgtqedjohnabmk"), SV("blkhjeogicatqfnpdmsr"), 10, 10); + test(S("niptglfbosehkamrdqcj"), SV(""), 19, S::npos); + test(S("copqdhstbingamjfkler"), SV("djkqc"), 19, 16); + test(S("mrtaefilpdsgocnhqbjk"), SV("lgokshjtpb"), 19, 19); + test(S("kojatdhlcmigpbfrqnes"), SV("bqjhtkfepimcnsgrlado"), 19, 19); + test(S("eaintpchlqsbdgrkjofm"), SV(""), 20, S::npos); + test(S("gjnhidfsepkrtaqbmclo"), SV("nocfa"), 20, 19); + test(S("spocfaktqdbiejlhngmr"), SV("bgtajmiedc"), 20, 18); + test(S("rphmlekgfscndtaobiqj"), SV("lsckfnqgdahejiopbtmr"), 20, 19); + test(S("liatsqdoegkmfcnbhrpj"), SV(""), 21, S::npos); + test(S("binjagtfldkrspcomqeh"), SV("gfsrt"), 21, 12); + test(S("latkmisecnorjbfhqpdg"), SV("pfsocbhjtm"), 21, 17); + test(S("lecfratdjkhnsmqpoigb"), SV("tpflmdnoicjgkberhqsa"), 21, 19); +} + +template +void test1() +{ + test(S(""), SV(""), S::npos); + test(S(""), SV("laenf"), S::npos); + test(S(""), SV("pqlnkmbdjo"), S::npos); + test(S(""), SV("qkamfogpnljdcshbreti"), S::npos); + test(S("nhmko"), SV(""), S::npos); + test(S("lahfb"), SV("irkhs"), 2); + test(S("gmfhd"), SV("kantesmpgj"), 1); + test(S("odaft"), SV("oknlrstdpiqmjbaghcfe"), 4); + test(S("eolhfgpjqk"), SV(""), S::npos); + test(S("nbatdlmekr"), SV("bnrpe"), 9); + test(S("jdmciepkaq"), SV("jtdaefblso"), 8); + test(S("hkbgspoflt"), SV("oselktgbcapndfjihrmq"), 9); + test(S("gprdcokbnjhlsfmtieqa"), SV(""), S::npos); + test(S("qjghlnftcaismkropdeb"), SV("bjaht"), 19); + test(S("pnalfrdtkqcmojiesbhg"), SV("hjlcmgpket"), 19); + test(S("pniotcfrhqsmgdkjbael"), SV("htaobedqikfplcgjsmrn"), 19); +} + +int main() +{ + { + typedef std::string S; + typedef std::string_view SV; + test0(); + test1(); + } +#if TEST_STD_VER >= 11 + { + typedef std::basic_string, min_allocator> S; + typedef std::string_view SV; + test0(); + test1(); + } +#endif +} diff --git a/tests/external/libcxx/basic_string/string.ops/string_find/char_size.pass.cpp b/tests/external/libcxx/basic_string/string.ops/string_find/char_size.pass.cpp new file mode 100644 index 0000000..a084348 --- /dev/null +++ b/tests/external/libcxx/basic_string/string.ops/string_find/char_size.pass.cpp @@ -0,0 +1,98 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// + +// size_type find(charT c, size_type pos = 0) const; + +#include +#include + +#include "min_allocator.h" + +template +void +test(const S& s, typename S::value_type c, typename S::size_type pos, + typename S::size_type x) +{ + assert(s.find(c, pos) == x); + if (x != S::npos) + assert(pos <= x && x + 1 <= s.size()); +} + +template +void +test(const S& s, typename S::value_type c, typename S::size_type x) +{ + assert(s.find(c) == x); + if (x != S::npos) + assert(0 <= x && x + 1 <= s.size()); +} + +int main() +{ + { + typedef std::string S; + test(S(""), 'c', 0, S::npos); + test(S(""), 'c', 1, S::npos); + test(S("abcde"), 'c', 0, 2); + test(S("abcde"), 'c', 1, 2); + test(S("abcde"), 'c', 2, 2); + test(S("abcde"), 'c', 4, S::npos); + test(S("abcde"), 'c', 5, S::npos); + test(S("abcde"), 'c', 6, S::npos); + test(S("abcdeabcde"), 'c', 0, 2); + test(S("abcdeabcde"), 'c', 1, 2); + test(S("abcdeabcde"), 'c', 5, 7); + test(S("abcdeabcde"), 'c', 9, S::npos); + test(S("abcdeabcde"), 'c', 10, S::npos); + test(S("abcdeabcde"), 'c', 11, S::npos); + test(S("abcdeabcdeabcdeabcde"), 'c', 0, 2); + test(S("abcdeabcdeabcdeabcde"), 'c', 1, 2); + test(S("abcdeabcdeabcdeabcde"), 'c', 10, 12); + test(S("abcdeabcdeabcdeabcde"), 'c', 19, S::npos); + test(S("abcdeabcdeabcdeabcde"), 'c', 20, S::npos); + test(S("abcdeabcdeabcdeabcde"), 'c', 21, S::npos); + + test(S(""), 'c', S::npos); + test(S("abcde"), 'c', 2); + test(S("abcdeabcde"), 'c', 2); + test(S("abcdeabcdeabcdeabcde"), 'c', 2); + } +#if TEST_STD_VER >= 11 + { + typedef std::basic_string, min_allocator> S; + test(S(""), 'c', 0, S::npos); + test(S(""), 'c', 1, S::npos); + test(S("abcde"), 'c', 0, 2); + test(S("abcde"), 'c', 1, 2); + test(S("abcde"), 'c', 2, 2); + test(S("abcde"), 'c', 4, S::npos); + test(S("abcde"), 'c', 5, S::npos); + test(S("abcde"), 'c', 6, S::npos); + test(S("abcdeabcde"), 'c', 0, 2); + test(S("abcdeabcde"), 'c', 1, 2); + test(S("abcdeabcde"), 'c', 5, 7); + test(S("abcdeabcde"), 'c', 9, S::npos); + test(S("abcdeabcde"), 'c', 10, S::npos); + test(S("abcdeabcde"), 'c', 11, S::npos); + test(S("abcdeabcdeabcdeabcde"), 'c', 0, 2); + test(S("abcdeabcdeabcdeabcde"), 'c', 1, 2); + test(S("abcdeabcdeabcdeabcde"), 'c', 10, 12); + test(S("abcdeabcdeabcdeabcde"), 'c', 19, S::npos); + test(S("abcdeabcdeabcdeabcde"), 'c', 20, S::npos); + test(S("abcdeabcdeabcdeabcde"), 'c', 21, S::npos); + + test(S(""), 'c', S::npos); + test(S("abcde"), 'c', 2); + test(S("abcdeabcde"), 'c', 2); + test(S("abcdeabcdeabcdeabcde"), 'c', 2); + } +#endif +} diff --git a/tests/external/libcxx/basic_string/string.ops/string_find/pointer_size.pass.cpp b/tests/external/libcxx/basic_string/string.ops/string_find/pointer_size.pass.cpp new file mode 100644 index 0000000..0257e12 --- /dev/null +++ b/tests/external/libcxx/basic_string/string.ops/string_find/pointer_size.pass.cpp @@ -0,0 +1,164 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// + +// size_type find(const charT* s, size_type pos = 0) const; + +#include +#include + +#include "min_allocator.h" + +template +void +test(const S& s, const typename S::value_type* str, typename S::size_type pos, + typename S::size_type x) +{ + assert(s.find(str, pos) == x); + if (x != S::npos) + { + typename S::size_type n = S::traits_type::length(str); + assert(pos <= x && x + n <= s.size()); + } +} + +template +void +test(const S& s, const typename S::value_type* str, typename S::size_type x) +{ + assert(s.find(str) == x); + if (x != S::npos) + { + typename S::size_type n = S::traits_type::length(str); + assert(0 <= x && x + n <= s.size()); + } +} + +template +void test0() +{ + test(S(""), "", 0, 0); + test(S(""), "abcde", 0, S::npos); + test(S(""), "abcdeabcde", 0, S::npos); + test(S(""), "abcdeabcdeabcdeabcde", 0, S::npos); + test(S(""), "", 1, S::npos); + test(S(""), "abcde", 1, S::npos); + test(S(""), "abcdeabcde", 1, S::npos); + test(S(""), "abcdeabcdeabcdeabcde", 1, S::npos); + test(S("abcde"), "", 0, 0); + test(S("abcde"), "abcde", 0, 0); + test(S("abcde"), "abcdeabcde", 0, S::npos); + test(S("abcde"), "abcdeabcdeabcdeabcde", 0, S::npos); + test(S("abcde"), "", 1, 1); + test(S("abcde"), "abcde", 1, S::npos); + test(S("abcde"), "abcdeabcde", 1, S::npos); + test(S("abcde"), "abcdeabcdeabcdeabcde", 1, S::npos); + test(S("abcde"), "", 2, 2); + test(S("abcde"), "abcde", 2, S::npos); + test(S("abcde"), "abcdeabcde", 2, S::npos); + test(S("abcde"), "abcdeabcdeabcdeabcde", 2, S::npos); + test(S("abcde"), "", 4, 4); + test(S("abcde"), "abcde", 4, S::npos); + test(S("abcde"), "abcdeabcde", 4, S::npos); + test(S("abcde"), "abcdeabcdeabcdeabcde", 4, S::npos); + test(S("abcde"), "", 5, 5); + test(S("abcde"), "abcde", 5, S::npos); + test(S("abcde"), "abcdeabcde", 5, S::npos); + test(S("abcde"), "abcdeabcdeabcdeabcde", 5, S::npos); + test(S("abcde"), "", 6, S::npos); + test(S("abcde"), "abcde", 6, S::npos); + test(S("abcde"), "abcdeabcde", 6, S::npos); + test(S("abcde"), "abcdeabcdeabcdeabcde", 6, S::npos); + test(S("abcdeabcde"), "", 0, 0); + test(S("abcdeabcde"), "abcde", 0, 0); + test(S("abcdeabcde"), "abcdeabcde", 0, 0); + test(S("abcdeabcde"), "abcdeabcdeabcdeabcde", 0, S::npos); + test(S("abcdeabcde"), "", 1, 1); + test(S("abcdeabcde"), "abcde", 1, 5); + test(S("abcdeabcde"), "abcdeabcde", 1, S::npos); + test(S("abcdeabcde"), "abcdeabcdeabcdeabcde", 1, S::npos); + test(S("abcdeabcde"), "", 5, 5); + test(S("abcdeabcde"), "abcde", 5, 5); + test(S("abcdeabcde"), "abcdeabcde", 5, S::npos); + test(S("abcdeabcde"), "abcdeabcdeabcdeabcde", 5, S::npos); + test(S("abcdeabcde"), "", 9, 9); + test(S("abcdeabcde"), "abcde", 9, S::npos); + test(S("abcdeabcde"), "abcdeabcde", 9, S::npos); + test(S("abcdeabcde"), "abcdeabcdeabcdeabcde", 9, S::npos); + test(S("abcdeabcde"), "", 10, 10); + test(S("abcdeabcde"), "abcde", 10, S::npos); + test(S("abcdeabcde"), "abcdeabcde", 10, S::npos); + test(S("abcdeabcde"), "abcdeabcdeabcdeabcde", 10, S::npos); + test(S("abcdeabcde"), "", 11, S::npos); + test(S("abcdeabcde"), "abcde", 11, S::npos); + test(S("abcdeabcde"), "abcdeabcde", 11, S::npos); + test(S("abcdeabcde"), "abcdeabcdeabcdeabcde", 11, S::npos); + test(S("abcdeabcdeabcdeabcde"), "", 0, 0); + test(S("abcdeabcdeabcdeabcde"), "abcde", 0, 0); + test(S("abcdeabcdeabcdeabcde"), "abcdeabcde", 0, 0); + test(S("abcdeabcdeabcdeabcde"), "abcdeabcdeabcdeabcde", 0, 0); + test(S("abcdeabcdeabcdeabcde"), "", 1, 1); + test(S("abcdeabcdeabcdeabcde"), "abcde", 1, 5); + test(S("abcdeabcdeabcdeabcde"), "abcdeabcde", 1, 5); + test(S("abcdeabcdeabcdeabcde"), "abcdeabcdeabcdeabcde", 1, S::npos); + test(S("abcdeabcdeabcdeabcde"), "", 10, 10); + test(S("abcdeabcdeabcdeabcde"), "abcde", 10, 10); + test(S("abcdeabcdeabcdeabcde"), "abcdeabcde", 10, 10); + test(S("abcdeabcdeabcdeabcde"), "abcdeabcdeabcdeabcde", 10, S::npos); + test(S("abcdeabcdeabcdeabcde"), "", 19, 19); + test(S("abcdeabcdeabcdeabcde"), "abcde", 19, S::npos); + test(S("abcdeabcdeabcdeabcde"), "abcdeabcde", 19, S::npos); + test(S("abcdeabcdeabcdeabcde"), "abcdeabcdeabcdeabcde", 19, S::npos); + test(S("abcdeabcdeabcdeabcde"), "", 20, 20); + test(S("abcdeabcdeabcdeabcde"), "abcde", 20, S::npos); + test(S("abcdeabcdeabcdeabcde"), "abcdeabcde", 20, S::npos); + test(S("abcdeabcdeabcdeabcde"), "abcdeabcdeabcdeabcde", 20, S::npos); + test(S("abcdeabcdeabcdeabcde"), "", 21, S::npos); + test(S("abcdeabcdeabcdeabcde"), "abcde", 21, S::npos); + test(S("abcdeabcdeabcdeabcde"), "abcdeabcde", 21, S::npos); + test(S("abcdeabcdeabcdeabcde"), "abcdeabcdeabcdeabcde", 21, S::npos); +} + +template +void test1() +{ + test(S(""), "", 0); + test(S(""), "abcde", S::npos); + test(S(""), "abcdeabcde", S::npos); + test(S(""), "abcdeabcdeabcdeabcde", S::npos); + test(S("abcde"), "", 0); + test(S("abcde"), "abcde", 0); + test(S("abcde"), "abcdeabcde", S::npos); + test(S("abcde"), "abcdeabcdeabcdeabcde", S::npos); + test(S("abcdeabcde"), "", 0); + test(S("abcdeabcde"), "abcde", 0); + test(S("abcdeabcde"), "abcdeabcde", 0); + test(S("abcdeabcde"), "abcdeabcdeabcdeabcde", S::npos); + test(S("abcdeabcdeabcdeabcde"), "", 0); + test(S("abcdeabcdeabcdeabcde"), "abcde", 0); + test(S("abcdeabcdeabcdeabcde"), "abcdeabcde", 0); + test(S("abcdeabcdeabcdeabcde"), "abcdeabcdeabcdeabcde", 0); +} + +int main() +{ + { + typedef std::string S; + test0(); + test1(); + } +#if TEST_STD_VER >= 11 + { + typedef std::basic_string, min_allocator> S; + test0(); + test1(); + } +#endif +} diff --git a/tests/external/libcxx/basic_string/string.ops/string_find/pointer_size_size.pass.cpp b/tests/external/libcxx/basic_string/string.ops/string_find/pointer_size_size.pass.cpp new file mode 100644 index 0000000..9a380f7 --- /dev/null +++ b/tests/external/libcxx/basic_string/string.ops/string_find/pointer_size_size.pass.cpp @@ -0,0 +1,387 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// + +// size_type find(const charT* s, size_type pos, size_type n) const; + +#include +#include + +#include "min_allocator.h" + +template +void +test(const S& s, const typename S::value_type* str, typename S::size_type pos, + typename S::size_type n, typename S::size_type x) +{ + assert(s.find(str, pos, n) == x); + if (x != S::npos) + assert(pos <= x && x + n <= s.size()); +} + +template +void test0() +{ + test(S(""), "", 0, 0, 0); + test(S(""), "abcde", 0, 0, 0); + test(S(""), "abcde", 0, 1, S::npos); + test(S(""), "abcde", 0, 2, S::npos); + test(S(""), "abcde", 0, 4, S::npos); + test(S(""), "abcde", 0, 5, S::npos); + test(S(""), "abcdeabcde", 0, 0, 0); + test(S(""), "abcdeabcde", 0, 1, S::npos); + test(S(""), "abcdeabcde", 0, 5, S::npos); + test(S(""), "abcdeabcde", 0, 9, S::npos); + test(S(""), "abcdeabcde", 0, 10, S::npos); + test(S(""), "abcdeabcdeabcdeabcde", 0, 0, 0); + test(S(""), "abcdeabcdeabcdeabcde", 0, 1, S::npos); + test(S(""), "abcdeabcdeabcdeabcde", 0, 10, S::npos); + test(S(""), "abcdeabcdeabcdeabcde", 0, 19, S::npos); + test(S(""), "abcdeabcdeabcdeabcde", 0, 20, S::npos); + test(S(""), "", 1, 0, S::npos); + test(S(""), "abcde", 1, 0, S::npos); + test(S(""), "abcde", 1, 1, S::npos); + test(S(""), "abcde", 1, 2, S::npos); + test(S(""), "abcde", 1, 4, S::npos); + test(S(""), "abcde", 1, 5, S::npos); + test(S(""), "abcdeabcde", 1, 0, S::npos); + test(S(""), "abcdeabcde", 1, 1, S::npos); + test(S(""), "abcdeabcde", 1, 5, S::npos); + test(S(""), "abcdeabcde", 1, 9, S::npos); + test(S(""), "abcdeabcde", 1, 10, S::npos); + test(S(""), "abcdeabcdeabcdeabcde", 1, 0, S::npos); + test(S(""), "abcdeabcdeabcdeabcde", 1, 1, S::npos); + test(S(""), "abcdeabcdeabcdeabcde", 1, 10, S::npos); + test(S(""), "abcdeabcdeabcdeabcde", 1, 19, S::npos); + test(S(""), "abcdeabcdeabcdeabcde", 1, 20, S::npos); + test(S("abcde"), "", 0, 0, 0); + test(S("abcde"), "abcde", 0, 0, 0); + test(S("abcde"), "abcde", 0, 1, 0); + test(S("abcde"), "abcde", 0, 2, 0); + test(S("abcde"), "abcde", 0, 4, 0); + test(S("abcde"), "abcde", 0, 5, 0); + test(S("abcde"), "abcdeabcde", 0, 0, 0); + test(S("abcde"), "abcdeabcde", 0, 1, 0); + test(S("abcde"), "abcdeabcde", 0, 5, 0); + test(S("abcde"), "abcdeabcde", 0, 9, S::npos); + test(S("abcde"), "abcdeabcde", 0, 10, S::npos); + test(S("abcde"), "abcdeabcdeabcdeabcde", 0, 0, 0); + test(S("abcde"), "abcdeabcdeabcdeabcde", 0, 1, 0); + test(S("abcde"), "abcdeabcdeabcdeabcde", 0, 10, S::npos); + test(S("abcde"), "abcdeabcdeabcdeabcde", 0, 19, S::npos); + test(S("abcde"), "abcdeabcdeabcdeabcde", 0, 20, S::npos); + test(S("abcde"), "", 1, 0, 1); + test(S("abcde"), "abcde", 1, 0, 1); + test(S("abcde"), "abcde", 1, 1, S::npos); + test(S("abcde"), "abcde", 1, 2, S::npos); + test(S("abcde"), "abcde", 1, 4, S::npos); + test(S("abcde"), "abcde", 1, 5, S::npos); + test(S("abcde"), "abcdeabcde", 1, 0, 1); + test(S("abcde"), "abcdeabcde", 1, 1, S::npos); + test(S("abcde"), "abcdeabcde", 1, 5, S::npos); + test(S("abcde"), "abcdeabcde", 1, 9, S::npos); + test(S("abcde"), "abcdeabcde", 1, 10, S::npos); + test(S("abcde"), "abcdeabcdeabcdeabcde", 1, 0, 1); + test(S("abcde"), "abcdeabcdeabcdeabcde", 1, 1, S::npos); + test(S("abcde"), "abcdeabcdeabcdeabcde", 1, 10, S::npos); + test(S("abcde"), "abcdeabcdeabcdeabcde", 1, 19, S::npos); + test(S("abcde"), "abcdeabcdeabcdeabcde", 1, 20, S::npos); + test(S("abcde"), "", 2, 0, 2); + test(S("abcde"), "abcde", 2, 0, 2); + test(S("abcde"), "abcde", 2, 1, S::npos); + test(S("abcde"), "abcde", 2, 2, S::npos); + test(S("abcde"), "abcde", 2, 4, S::npos); + test(S("abcde"), "abcde", 2, 5, S::npos); + test(S("abcde"), "abcdeabcde", 2, 0, 2); + test(S("abcde"), "abcdeabcde", 2, 1, S::npos); + test(S("abcde"), "abcdeabcde", 2, 5, S::npos); + test(S("abcde"), "abcdeabcde", 2, 9, S::npos); + test(S("abcde"), "abcdeabcde", 2, 10, S::npos); + test(S("abcde"), "abcdeabcdeabcdeabcde", 2, 0, 2); + test(S("abcde"), "abcdeabcdeabcdeabcde", 2, 1, S::npos); + test(S("abcde"), "abcdeabcdeabcdeabcde", 2, 10, S::npos); + test(S("abcde"), "abcdeabcdeabcdeabcde", 2, 19, S::npos); + test(S("abcde"), "abcdeabcdeabcdeabcde", 2, 20, S::npos); + test(S("abcde"), "", 4, 0, 4); + test(S("abcde"), "abcde", 4, 0, 4); + test(S("abcde"), "abcde", 4, 1, S::npos); + test(S("abcde"), "abcde", 4, 2, S::npos); + test(S("abcde"), "abcde", 4, 4, S::npos); + test(S("abcde"), "abcde", 4, 5, S::npos); + test(S("abcde"), "abcdeabcde", 4, 0, 4); + test(S("abcde"), "abcdeabcde", 4, 1, S::npos); + test(S("abcde"), "abcdeabcde", 4, 5, S::npos); + test(S("abcde"), "abcdeabcde", 4, 9, S::npos); + test(S("abcde"), "abcdeabcde", 4, 10, S::npos); + test(S("abcde"), "abcdeabcdeabcdeabcde", 4, 0, 4); + test(S("abcde"), "abcdeabcdeabcdeabcde", 4, 1, S::npos); + test(S("abcde"), "abcdeabcdeabcdeabcde", 4, 10, S::npos); + test(S("abcde"), "abcdeabcdeabcdeabcde", 4, 19, S::npos); + test(S("abcde"), "abcdeabcdeabcdeabcde", 4, 20, S::npos); + test(S("abcde"), "", 5, 0, 5); + test(S("abcde"), "abcde", 5, 0, 5); + test(S("abcde"), "abcde", 5, 1, S::npos); + test(S("abcde"), "abcde", 5, 2, S::npos); +} + +template +void test1() +{ + test(S("abcde"), "abcde", 5, 4, S::npos); + test(S("abcde"), "abcde", 5, 5, S::npos); + test(S("abcde"), "abcdeabcde", 5, 0, 5); + test(S("abcde"), "abcdeabcde", 5, 1, S::npos); + test(S("abcde"), "abcdeabcde", 5, 5, S::npos); + test(S("abcde"), "abcdeabcde", 5, 9, S::npos); + test(S("abcde"), "abcdeabcde", 5, 10, S::npos); + test(S("abcde"), "abcdeabcdeabcdeabcde", 5, 0, 5); + test(S("abcde"), "abcdeabcdeabcdeabcde", 5, 1, S::npos); + test(S("abcde"), "abcdeabcdeabcdeabcde", 5, 10, S::npos); + test(S("abcde"), "abcdeabcdeabcdeabcde", 5, 19, S::npos); + test(S("abcde"), "abcdeabcdeabcdeabcde", 5, 20, S::npos); + test(S("abcde"), "", 6, 0, S::npos); + test(S("abcde"), "abcde", 6, 0, S::npos); + test(S("abcde"), "abcde", 6, 1, S::npos); + test(S("abcde"), "abcde", 6, 2, S::npos); + test(S("abcde"), "abcde", 6, 4, S::npos); + test(S("abcde"), "abcde", 6, 5, S::npos); + test(S("abcde"), "abcdeabcde", 6, 0, S::npos); + test(S("abcde"), "abcdeabcde", 6, 1, S::npos); + test(S("abcde"), "abcdeabcde", 6, 5, S::npos); + test(S("abcde"), "abcdeabcde", 6, 9, S::npos); + test(S("abcde"), "abcdeabcde", 6, 10, S::npos); + test(S("abcde"), "abcdeabcdeabcdeabcde", 6, 0, S::npos); + test(S("abcde"), "abcdeabcdeabcdeabcde", 6, 1, S::npos); + test(S("abcde"), "abcdeabcdeabcdeabcde", 6, 10, S::npos); + test(S("abcde"), "abcdeabcdeabcdeabcde", 6, 19, S::npos); + test(S("abcde"), "abcdeabcdeabcdeabcde", 6, 20, S::npos); + test(S("abcdeabcde"), "", 0, 0, 0); + test(S("abcdeabcde"), "abcde", 0, 0, 0); + test(S("abcdeabcde"), "abcde", 0, 1, 0); + test(S("abcdeabcde"), "abcde", 0, 2, 0); + test(S("abcdeabcde"), "abcde", 0, 4, 0); + test(S("abcdeabcde"), "abcde", 0, 5, 0); + test(S("abcdeabcde"), "abcdeabcde", 0, 0, 0); + test(S("abcdeabcde"), "abcdeabcde", 0, 1, 0); + test(S("abcdeabcde"), "abcdeabcde", 0, 5, 0); + test(S("abcdeabcde"), "abcdeabcde", 0, 9, 0); + test(S("abcdeabcde"), "abcdeabcde", 0, 10, 0); + test(S("abcdeabcde"), "abcdeabcdeabcdeabcde", 0, 0, 0); + test(S("abcdeabcde"), "abcdeabcdeabcdeabcde", 0, 1, 0); + test(S("abcdeabcde"), "abcdeabcdeabcdeabcde", 0, 10, 0); + test(S("abcdeabcde"), "abcdeabcdeabcdeabcde", 0, 19, S::npos); + test(S("abcdeabcde"), "abcdeabcdeabcdeabcde", 0, 20, S::npos); + test(S("abcdeabcde"), "", 1, 0, 1); + test(S("abcdeabcde"), "abcde", 1, 0, 1); + test(S("abcdeabcde"), "abcde", 1, 1, 5); + test(S("abcdeabcde"), "abcde", 1, 2, 5); + test(S("abcdeabcde"), "abcde", 1, 4, 5); + test(S("abcdeabcde"), "abcde", 1, 5, 5); + test(S("abcdeabcde"), "abcdeabcde", 1, 0, 1); + test(S("abcdeabcde"), "abcdeabcde", 1, 1, 5); + test(S("abcdeabcde"), "abcdeabcde", 1, 5, 5); + test(S("abcdeabcde"), "abcdeabcde", 1, 9, S::npos); + test(S("abcdeabcde"), "abcdeabcde", 1, 10, S::npos); + test(S("abcdeabcde"), "abcdeabcdeabcdeabcde", 1, 0, 1); + test(S("abcdeabcde"), "abcdeabcdeabcdeabcde", 1, 1, 5); + test(S("abcdeabcde"), "abcdeabcdeabcdeabcde", 1, 10, S::npos); + test(S("abcdeabcde"), "abcdeabcdeabcdeabcde", 1, 19, S::npos); + test(S("abcdeabcde"), "abcdeabcdeabcdeabcde", 1, 20, S::npos); + test(S("abcdeabcde"), "", 5, 0, 5); + test(S("abcdeabcde"), "abcde", 5, 0, 5); + test(S("abcdeabcde"), "abcde", 5, 1, 5); + test(S("abcdeabcde"), "abcde", 5, 2, 5); + test(S("abcdeabcde"), "abcde", 5, 4, 5); + test(S("abcdeabcde"), "abcde", 5, 5, 5); + test(S("abcdeabcde"), "abcdeabcde", 5, 0, 5); + test(S("abcdeabcde"), "abcdeabcde", 5, 1, 5); + test(S("abcdeabcde"), "abcdeabcde", 5, 5, 5); + test(S("abcdeabcde"), "abcdeabcde", 5, 9, S::npos); + test(S("abcdeabcde"), "abcdeabcde", 5, 10, S::npos); + test(S("abcdeabcde"), "abcdeabcdeabcdeabcde", 5, 0, 5); + test(S("abcdeabcde"), "abcdeabcdeabcdeabcde", 5, 1, 5); + test(S("abcdeabcde"), "abcdeabcdeabcdeabcde", 5, 10, S::npos); + test(S("abcdeabcde"), "abcdeabcdeabcdeabcde", 5, 19, S::npos); + test(S("abcdeabcde"), "abcdeabcdeabcdeabcde", 5, 20, S::npos); + test(S("abcdeabcde"), "", 9, 0, 9); + test(S("abcdeabcde"), "abcde", 9, 0, 9); + test(S("abcdeabcde"), "abcde", 9, 1, S::npos); + test(S("abcdeabcde"), "abcde", 9, 2, S::npos); + test(S("abcdeabcde"), "abcde", 9, 4, S::npos); + test(S("abcdeabcde"), "abcde", 9, 5, S::npos); + test(S("abcdeabcde"), "abcdeabcde", 9, 0, 9); + test(S("abcdeabcde"), "abcdeabcde", 9, 1, S::npos); + test(S("abcdeabcde"), "abcdeabcde", 9, 5, S::npos); + test(S("abcdeabcde"), "abcdeabcde", 9, 9, S::npos); + test(S("abcdeabcde"), "abcdeabcde", 9, 10, S::npos); + test(S("abcdeabcde"), "abcdeabcdeabcdeabcde", 9, 0, 9); + test(S("abcdeabcde"), "abcdeabcdeabcdeabcde", 9, 1, S::npos); + test(S("abcdeabcde"), "abcdeabcdeabcdeabcde", 9, 10, S::npos); + test(S("abcdeabcde"), "abcdeabcdeabcdeabcde", 9, 19, S::npos); + test(S("abcdeabcde"), "abcdeabcdeabcdeabcde", 9, 20, S::npos); + test(S("abcdeabcde"), "", 10, 0, 10); + test(S("abcdeabcde"), "abcde", 10, 0, 10); + test(S("abcdeabcde"), "abcde", 10, 1, S::npos); + test(S("abcdeabcde"), "abcde", 10, 2, S::npos); + test(S("abcdeabcde"), "abcde", 10, 4, S::npos); + test(S("abcdeabcde"), "abcde", 10, 5, S::npos); + test(S("abcdeabcde"), "abcdeabcde", 10, 0, 10); + test(S("abcdeabcde"), "abcdeabcde", 10, 1, S::npos); +} + +template +void test2() +{ + test(S("abcdeabcde"), "abcdeabcde", 10, 5, S::npos); + test(S("abcdeabcde"), "abcdeabcde", 10, 9, S::npos); + test(S("abcdeabcde"), "abcdeabcde", 10, 10, S::npos); + test(S("abcdeabcde"), "abcdeabcdeabcdeabcde", 10, 0, 10); + test(S("abcdeabcde"), "abcdeabcdeabcdeabcde", 10, 1, S::npos); + test(S("abcdeabcde"), "abcdeabcdeabcdeabcde", 10, 10, S::npos); + test(S("abcdeabcde"), "abcdeabcdeabcdeabcde", 10, 19, S::npos); + test(S("abcdeabcde"), "abcdeabcdeabcdeabcde", 10, 20, S::npos); + test(S("abcdeabcde"), "", 11, 0, S::npos); + test(S("abcdeabcde"), "abcde", 11, 0, S::npos); + test(S("abcdeabcde"), "abcde", 11, 1, S::npos); + test(S("abcdeabcde"), "abcde", 11, 2, S::npos); + test(S("abcdeabcde"), "abcde", 11, 4, S::npos); + test(S("abcdeabcde"), "abcde", 11, 5, S::npos); + test(S("abcdeabcde"), "abcdeabcde", 11, 0, S::npos); + test(S("abcdeabcde"), "abcdeabcde", 11, 1, S::npos); + test(S("abcdeabcde"), "abcdeabcde", 11, 5, S::npos); + test(S("abcdeabcde"), "abcdeabcde", 11, 9, S::npos); + test(S("abcdeabcde"), "abcdeabcde", 11, 10, S::npos); + test(S("abcdeabcde"), "abcdeabcdeabcdeabcde", 11, 0, S::npos); + test(S("abcdeabcde"), "abcdeabcdeabcdeabcde", 11, 1, S::npos); + test(S("abcdeabcde"), "abcdeabcdeabcdeabcde", 11, 10, S::npos); + test(S("abcdeabcde"), "abcdeabcdeabcdeabcde", 11, 19, S::npos); + test(S("abcdeabcde"), "abcdeabcdeabcdeabcde", 11, 20, S::npos); + test(S("abcdeabcdeabcdeabcde"), "", 0, 0, 0); + test(S("abcdeabcdeabcdeabcde"), "abcde", 0, 0, 0); + test(S("abcdeabcdeabcdeabcde"), "abcde", 0, 1, 0); + test(S("abcdeabcdeabcdeabcde"), "abcde", 0, 2, 0); + test(S("abcdeabcdeabcdeabcde"), "abcde", 0, 4, 0); + test(S("abcdeabcdeabcdeabcde"), "abcde", 0, 5, 0); + test(S("abcdeabcdeabcdeabcde"), "abcdeabcde", 0, 0, 0); + test(S("abcdeabcdeabcdeabcde"), "abcdeabcde", 0, 1, 0); + test(S("abcdeabcdeabcdeabcde"), "abcdeabcde", 0, 5, 0); + test(S("abcdeabcdeabcdeabcde"), "abcdeabcde", 0, 9, 0); + test(S("abcdeabcdeabcdeabcde"), "abcdeabcde", 0, 10, 0); + test(S("abcdeabcdeabcdeabcde"), "abcdeabcdeabcdeabcde", 0, 0, 0); + test(S("abcdeabcdeabcdeabcde"), "abcdeabcdeabcdeabcde", 0, 1, 0); + test(S("abcdeabcdeabcdeabcde"), "abcdeabcdeabcdeabcde", 0, 10, 0); + test(S("abcdeabcdeabcdeabcde"), "abcdeabcdeabcdeabcde", 0, 19, 0); + test(S("abcdeabcdeabcdeabcde"), "abcdeabcdeabcdeabcde", 0, 20, 0); + test(S("abcdeabcdeabcdeabcde"), "", 1, 0, 1); + test(S("abcdeabcdeabcdeabcde"), "abcde", 1, 0, 1); + test(S("abcdeabcdeabcdeabcde"), "abcde", 1, 1, 5); + test(S("abcdeabcdeabcdeabcde"), "abcde", 1, 2, 5); + test(S("abcdeabcdeabcdeabcde"), "abcde", 1, 4, 5); + test(S("abcdeabcdeabcdeabcde"), "abcde", 1, 5, 5); + test(S("abcdeabcdeabcdeabcde"), "abcdeabcde", 1, 0, 1); + test(S("abcdeabcdeabcdeabcde"), "abcdeabcde", 1, 1, 5); + test(S("abcdeabcdeabcdeabcde"), "abcdeabcde", 1, 5, 5); + test(S("abcdeabcdeabcdeabcde"), "abcdeabcde", 1, 9, 5); + test(S("abcdeabcdeabcdeabcde"), "abcdeabcde", 1, 10, 5); + test(S("abcdeabcdeabcdeabcde"), "abcdeabcdeabcdeabcde", 1, 0, 1); + test(S("abcdeabcdeabcdeabcde"), "abcdeabcdeabcdeabcde", 1, 1, 5); + test(S("abcdeabcdeabcdeabcde"), "abcdeabcdeabcdeabcde", 1, 10, 5); + test(S("abcdeabcdeabcdeabcde"), "abcdeabcdeabcdeabcde", 1, 19, S::npos); + test(S("abcdeabcdeabcdeabcde"), "abcdeabcdeabcdeabcde", 1, 20, S::npos); + test(S("abcdeabcdeabcdeabcde"), "", 10, 0, 10); + test(S("abcdeabcdeabcdeabcde"), "abcde", 10, 0, 10); + test(S("abcdeabcdeabcdeabcde"), "abcde", 10, 1, 10); + test(S("abcdeabcdeabcdeabcde"), "abcde", 10, 2, 10); + test(S("abcdeabcdeabcdeabcde"), "abcde", 10, 4, 10); + test(S("abcdeabcdeabcdeabcde"), "abcde", 10, 5, 10); + test(S("abcdeabcdeabcdeabcde"), "abcdeabcde", 10, 0, 10); + test(S("abcdeabcdeabcdeabcde"), "abcdeabcde", 10, 1, 10); + test(S("abcdeabcdeabcdeabcde"), "abcdeabcde", 10, 5, 10); + test(S("abcdeabcdeabcdeabcde"), "abcdeabcde", 10, 9, 10); + test(S("abcdeabcdeabcdeabcde"), "abcdeabcde", 10, 10, 10); + test(S("abcdeabcdeabcdeabcde"), "abcdeabcdeabcdeabcde", 10, 0, 10); + test(S("abcdeabcdeabcdeabcde"), "abcdeabcdeabcdeabcde", 10, 1, 10); + test(S("abcdeabcdeabcdeabcde"), "abcdeabcdeabcdeabcde", 10, 10, 10); + test(S("abcdeabcdeabcdeabcde"), "abcdeabcdeabcdeabcde", 10, 19, S::npos); + test(S("abcdeabcdeabcdeabcde"), "abcdeabcdeabcdeabcde", 10, 20, S::npos); + test(S("abcdeabcdeabcdeabcde"), "", 19, 0, 19); + test(S("abcdeabcdeabcdeabcde"), "abcde", 19, 0, 19); + test(S("abcdeabcdeabcdeabcde"), "abcde", 19, 1, S::npos); + test(S("abcdeabcdeabcdeabcde"), "abcde", 19, 2, S::npos); + test(S("abcdeabcdeabcdeabcde"), "abcde", 19, 4, S::npos); + test(S("abcdeabcdeabcdeabcde"), "abcde", 19, 5, S::npos); + test(S("abcdeabcdeabcdeabcde"), "abcdeabcde", 19, 0, 19); + test(S("abcdeabcdeabcdeabcde"), "abcdeabcde", 19, 1, S::npos); + test(S("abcdeabcdeabcdeabcde"), "abcdeabcde", 19, 5, S::npos); + test(S("abcdeabcdeabcdeabcde"), "abcdeabcde", 19, 9, S::npos); + test(S("abcdeabcdeabcdeabcde"), "abcdeabcde", 19, 10, S::npos); + test(S("abcdeabcdeabcdeabcde"), "abcdeabcdeabcdeabcde", 19, 0, 19); + test(S("abcdeabcdeabcdeabcde"), "abcdeabcdeabcdeabcde", 19, 1, S::npos); + test(S("abcdeabcdeabcdeabcde"), "abcdeabcdeabcdeabcde", 19, 10, S::npos); + test(S("abcdeabcdeabcdeabcde"), "abcdeabcdeabcdeabcde", 19, 19, S::npos); + test(S("abcdeabcdeabcdeabcde"), "abcdeabcdeabcdeabcde", 19, 20, S::npos); + test(S("abcdeabcdeabcdeabcde"), "", 20, 0, 20); + test(S("abcdeabcdeabcdeabcde"), "abcde", 20, 0, 20); + test(S("abcdeabcdeabcdeabcde"), "abcde", 20, 1, S::npos); + test(S("abcdeabcdeabcdeabcde"), "abcde", 20, 2, S::npos); + test(S("abcdeabcdeabcdeabcde"), "abcde", 20, 4, S::npos); + test(S("abcdeabcdeabcdeabcde"), "abcde", 20, 5, S::npos); + test(S("abcdeabcdeabcdeabcde"), "abcdeabcde", 20, 0, 20); + test(S("abcdeabcdeabcdeabcde"), "abcdeabcde", 20, 1, S::npos); + test(S("abcdeabcdeabcdeabcde"), "abcdeabcde", 20, 5, S::npos); + test(S("abcdeabcdeabcdeabcde"), "abcdeabcde", 20, 9, S::npos); + test(S("abcdeabcdeabcdeabcde"), "abcdeabcde", 20, 10, S::npos); + test(S("abcdeabcdeabcdeabcde"), "abcdeabcdeabcdeabcde", 20, 0, 20); +} + +template +void test3() +{ + test(S("abcdeabcdeabcdeabcde"), "abcdeabcdeabcdeabcde", 20, 1, S::npos); + test(S("abcdeabcdeabcdeabcde"), "abcdeabcdeabcdeabcde", 20, 10, S::npos); + test(S("abcdeabcdeabcdeabcde"), "abcdeabcdeabcdeabcde", 20, 19, S::npos); + test(S("abcdeabcdeabcdeabcde"), "abcdeabcdeabcdeabcde", 20, 20, S::npos); + test(S("abcdeabcdeabcdeabcde"), "", 21, 0, S::npos); + test(S("abcdeabcdeabcdeabcde"), "abcde", 21, 0, S::npos); + test(S("abcdeabcdeabcdeabcde"), "abcde", 21, 1, S::npos); + test(S("abcdeabcdeabcdeabcde"), "abcde", 21, 2, S::npos); + test(S("abcdeabcdeabcdeabcde"), "abcde", 21, 4, S::npos); + test(S("abcdeabcdeabcdeabcde"), "abcde", 21, 5, S::npos); + test(S("abcdeabcdeabcdeabcde"), "abcdeabcde", 21, 0, S::npos); + test(S("abcdeabcdeabcdeabcde"), "abcdeabcde", 21, 1, S::npos); + test(S("abcdeabcdeabcdeabcde"), "abcdeabcde", 21, 5, S::npos); + test(S("abcdeabcdeabcdeabcde"), "abcdeabcde", 21, 9, S::npos); + test(S("abcdeabcdeabcdeabcde"), "abcdeabcde", 21, 10, S::npos); + test(S("abcdeabcdeabcdeabcde"), "abcdeabcdeabcdeabcde", 21, 0, S::npos); + test(S("abcdeabcdeabcdeabcde"), "abcdeabcdeabcdeabcde", 21, 1, S::npos); + test(S("abcdeabcdeabcdeabcde"), "abcdeabcdeabcdeabcde", 21, 10, S::npos); + test(S("abcdeabcdeabcdeabcde"), "abcdeabcdeabcdeabcde", 21, 19, S::npos); + test(S("abcdeabcdeabcdeabcde"), "abcdeabcdeabcdeabcde", 21, 20, S::npos); +} + +int main() +{ + { + typedef std::string S; + test0(); + test1(); + test2(); + test3(); + } +#if TEST_STD_VER >= 11 + { + typedef std::basic_string, min_allocator> S; + test0(); + test1(); + test2(); + test3(); + } +#endif +} diff --git a/tests/external/libcxx/basic_string/string.ops/string_find/string_size.pass.cpp b/tests/external/libcxx/basic_string/string.ops/string_find/string_size.pass.cpp new file mode 100644 index 0000000..769b51c --- /dev/null +++ b/tests/external/libcxx/basic_string/string.ops/string_find/string_size.pass.cpp @@ -0,0 +1,165 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// + +// size_type find(const basic_string& str, size_type pos = 0) const; + +#include +#include + +#include "test_macros.h" +#include "min_allocator.h" + +template +void +test(const S& s, const S& str, typename S::size_type pos, typename S::size_type x) +{ + assert(s.find(str, pos) == x); + if (x != S::npos) + assert(pos <= x && x + str.size() <= s.size()); +} + +template +void +test(const S& s, const S& str, typename S::size_type x) +{ + assert(s.find(str) == x); + if (x != S::npos) + assert(0 <= x && x + str.size() <= s.size()); +} + +template +void test0() +{ + test(S(""), S(""), 0, 0); + test(S(""), S("abcde"), 0, S::npos); + test(S(""), S("abcdeabcde"), 0, S::npos); + test(S(""), S("abcdeabcdeabcdeabcde"), 0, S::npos); + test(S(""), S(""), 1, S::npos); + test(S(""), S("abcde"), 1, S::npos); + test(S(""), S("abcdeabcde"), 1, S::npos); + test(S(""), S("abcdeabcdeabcdeabcde"), 1, S::npos); + test(S("abcde"), S(""), 0, 0); + test(S("abcde"), S("abcde"), 0, 0); + test(S("abcde"), S("abcdeabcde"), 0, S::npos); + test(S("abcde"), S("abcdeabcdeabcdeabcde"), 0, S::npos); + test(S("abcde"), S(""), 1, 1); + test(S("abcde"), S("abcde"), 1, S::npos); + test(S("abcde"), S("abcdeabcde"), 1, S::npos); + test(S("abcde"), S("abcdeabcdeabcdeabcde"), 1, S::npos); + test(S("abcde"), S(""), 2, 2); + test(S("abcde"), S("abcde"), 2, S::npos); + test(S("abcde"), S("abcdeabcde"), 2, S::npos); + test(S("abcde"), S("abcdeabcdeabcdeabcde"), 2, S::npos); + test(S("abcde"), S(""), 4, 4); + test(S("abcde"), S("abcde"), 4, S::npos); + test(S("abcde"), S("abcdeabcde"), 4, S::npos); + test(S("abcde"), S("abcdeabcdeabcdeabcde"), 4, S::npos); + test(S("abcde"), S(""), 5, 5); + test(S("abcde"), S("abcde"), 5, S::npos); + test(S("abcde"), S("abcdeabcde"), 5, S::npos); + test(S("abcde"), S("abcdeabcdeabcdeabcde"), 5, S::npos); + test(S("abcde"), S(""), 6, S::npos); + test(S("abcde"), S("abcde"), 6, S::npos); + test(S("abcde"), S("abcdeabcde"), 6, S::npos); + test(S("abcde"), S("abcdeabcdeabcdeabcde"), 6, S::npos); + test(S("abcdeabcde"), S(""), 0, 0); + test(S("abcdeabcde"), S("abcde"), 0, 0); + test(S("abcdeabcde"), S("abcdeabcde"), 0, 0); + test(S("abcdeabcde"), S("abcdeabcdeabcdeabcde"), 0, S::npos); + test(S("abcdeabcde"), S(""), 1, 1); + test(S("abcdeabcde"), S("abcde"), 1, 5); + test(S("abcdeabcde"), S("abcdeabcde"), 1, S::npos); + test(S("abcdeabcde"), S("abcdeabcdeabcdeabcde"), 1, S::npos); + test(S("abcdeabcde"), S(""), 5, 5); + test(S("abcdeabcde"), S("abcde"), 5, 5); + test(S("abcdeabcde"), S("abcdeabcde"), 5, S::npos); + test(S("abcdeabcde"), S("abcdeabcdeabcdeabcde"), 5, S::npos); + test(S("abcdeabcde"), S(""), 9, 9); + test(S("abcdeabcde"), S("abcde"), 9, S::npos); + test(S("abcdeabcde"), S("abcdeabcde"), 9, S::npos); + test(S("abcdeabcde"), S("abcdeabcdeabcdeabcde"), 9, S::npos); + test(S("abcdeabcde"), S(""), 10, 10); + test(S("abcdeabcde"), S("abcde"), 10, S::npos); + test(S("abcdeabcde"), S("abcdeabcde"), 10, S::npos); + test(S("abcdeabcde"), S("abcdeabcdeabcdeabcde"), 10, S::npos); + test(S("abcdeabcde"), S(""), 11, S::npos); + test(S("abcdeabcde"), S("abcde"), 11, S::npos); + test(S("abcdeabcde"), S("abcdeabcde"), 11, S::npos); + test(S("abcdeabcde"), S("abcdeabcdeabcdeabcde"), 11, S::npos); + test(S("abcdeabcdeabcdeabcde"), S(""), 0, 0); + test(S("abcdeabcdeabcdeabcde"), S("abcde"), 0, 0); + test(S("abcdeabcdeabcdeabcde"), S("abcdeabcde"), 0, 0); + test(S("abcdeabcdeabcdeabcde"), S("abcdeabcdeabcdeabcde"), 0, 0); + test(S("abcdeabcdeabcdeabcde"), S(""), 1, 1); + test(S("abcdeabcdeabcdeabcde"), S("abcde"), 1, 5); + test(S("abcdeabcdeabcdeabcde"), S("abcdeabcde"), 1, 5); + test(S("abcdeabcdeabcdeabcde"), S("abcdeabcdeabcdeabcde"), 1, S::npos); + test(S("abcdeabcdeabcdeabcde"), S(""), 10, 10); + test(S("abcdeabcdeabcdeabcde"), S("abcde"), 10, 10); + test(S("abcdeabcdeabcdeabcde"), S("abcdeabcde"), 10, 10); + test(S("abcdeabcdeabcdeabcde"), S("abcdeabcdeabcdeabcde"), 10, S::npos); + test(S("abcdeabcdeabcdeabcde"), S(""), 19, 19); + test(S("abcdeabcdeabcdeabcde"), S("abcde"), 19, S::npos); + test(S("abcdeabcdeabcdeabcde"), S("abcdeabcde"), 19, S::npos); + test(S("abcdeabcdeabcdeabcde"), S("abcdeabcdeabcdeabcde"), 19, S::npos); + test(S("abcdeabcdeabcdeabcde"), S(""), 20, 20); + test(S("abcdeabcdeabcdeabcde"), S("abcde"), 20, S::npos); + test(S("abcdeabcdeabcdeabcde"), S("abcdeabcde"), 20, S::npos); + test(S("abcdeabcdeabcdeabcde"), S("abcdeabcdeabcdeabcde"), 20, S::npos); + test(S("abcdeabcdeabcdeabcde"), S(""), 21, S::npos); + test(S("abcdeabcdeabcdeabcde"), S("abcde"), 21, S::npos); + test(S("abcdeabcdeabcdeabcde"), S("abcdeabcde"), 21, S::npos); + test(S("abcdeabcdeabcdeabcde"), S("abcdeabcdeabcdeabcde"), 21, S::npos); +} + +template +void test1() +{ + test(S(""), S(""), 0); + test(S(""), S("abcde"), S::npos); + test(S(""), S("abcdeabcde"), S::npos); + test(S(""), S("abcdeabcdeabcdeabcde"), S::npos); + test(S("abcde"), S(""), 0); + test(S("abcde"), S("abcde"), 0); + test(S("abcde"), S("abcdeabcde"), S::npos); + test(S("abcde"), S("abcdeabcdeabcdeabcde"), S::npos); + test(S("abcdeabcde"), S(""), 0); + test(S("abcdeabcde"), S("abcde"), 0); + test(S("abcdeabcde"), S("abcdeabcde"), 0); + test(S("abcdeabcde"), S("abcdeabcdeabcdeabcde"), S::npos); + test(S("abcdeabcdeabcdeabcde"), S(""), 0); + test(S("abcdeabcdeabcdeabcde"), S("abcde"), 0); + test(S("abcdeabcdeabcdeabcde"), S("abcdeabcde"), 0); + test(S("abcdeabcdeabcdeabcde"), S("abcdeabcdeabcdeabcde"), 0); +} + +int main() +{ + { + typedef std::string S; + test0(); + test1(); + } +#if TEST_STD_VER >= 11 + { + typedef std::basic_string, min_allocator> S; + test0(); + test1(); + } +#endif + +#if TEST_STD_VER > 3 + { // LWG 2946 + std::string s = " !"; + assert(s.find({"abc", 1}) == std::string::npos); + } +#endif +} diff --git a/tests/external/libcxx/basic_string/string.ops/string_find/string_view_size.pass.cpp b/tests/external/libcxx/basic_string/string.ops/string_find/string_view_size.pass.cpp new file mode 100644 index 0000000..096f47e --- /dev/null +++ b/tests/external/libcxx/basic_string/string.ops/string_find/string_view_size.pass.cpp @@ -0,0 +1,159 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// + +// size_type find(basic_string_view sv, size_type pos = 0) const; + +#include +#include + +#include "min_allocator.h" + +template +void +test(const S& s, SV sv, typename S::size_type pos, typename S::size_type x) +{ + assert(s.find(sv, pos) == x); + if (x != S::npos) + assert(pos <= x && x + sv.size() <= s.size()); +} + +template +void +test(const S& s, SV sv, typename S::size_type x) +{ + assert(s.find(sv) == x); + if (x != S::npos) + assert(0 <= x && x + sv.size() <= s.size()); +} + +template +void test0() +{ + test(S(""), SV(""), 0, 0); + test(S(""), SV("abcde"), 0, S::npos); + test(S(""), SV("abcdeabcde"), 0, S::npos); + test(S(""), SV("abcdeabcdeabcdeabcde"), 0, S::npos); + test(S(""), SV(""), 1, S::npos); + test(S(""), SV("abcde"), 1, S::npos); + test(S(""), SV("abcdeabcde"), 1, S::npos); + test(S(""), SV("abcdeabcdeabcdeabcde"), 1, S::npos); + test(S("abcde"), SV(""), 0, 0); + test(S("abcde"), SV("abcde"), 0, 0); + test(S("abcde"), SV("abcdeabcde"), 0, S::npos); + test(S("abcde"), SV("abcdeabcdeabcdeabcde"), 0, S::npos); + test(S("abcde"), SV(""), 1, 1); + test(S("abcde"), SV("abcde"), 1, S::npos); + test(S("abcde"), SV("abcdeabcde"), 1, S::npos); + test(S("abcde"), SV("abcdeabcdeabcdeabcde"), 1, S::npos); + test(S("abcde"), SV(""), 2, 2); + test(S("abcde"), SV("abcde"), 2, S::npos); + test(S("abcde"), SV("abcdeabcde"), 2, S::npos); + test(S("abcde"), SV("abcdeabcdeabcdeabcde"), 2, S::npos); + test(S("abcde"), SV(""), 4, 4); + test(S("abcde"), SV("abcde"), 4, S::npos); + test(S("abcde"), SV("abcdeabcde"), 4, S::npos); + test(S("abcde"), SV("abcdeabcdeabcdeabcde"), 4, S::npos); + test(S("abcde"), SV(""), 5, 5); + test(S("abcde"), SV("abcde"), 5, S::npos); + test(S("abcde"), SV("abcdeabcde"), 5, S::npos); + test(S("abcde"), SV("abcdeabcdeabcdeabcde"), 5, S::npos); + test(S("abcde"), SV(""), 6, S::npos); + test(S("abcde"), SV("abcde"), 6, S::npos); + test(S("abcde"), SV("abcdeabcde"), 6, S::npos); + test(S("abcde"), SV("abcdeabcdeabcdeabcde"), 6, S::npos); + test(S("abcdeabcde"), SV(""), 0, 0); + test(S("abcdeabcde"), SV("abcde"), 0, 0); + test(S("abcdeabcde"), SV("abcdeabcde"), 0, 0); + test(S("abcdeabcde"), SV("abcdeabcdeabcdeabcde"), 0, S::npos); + test(S("abcdeabcde"), SV(""), 1, 1); + test(S("abcdeabcde"), SV("abcde"), 1, 5); + test(S("abcdeabcde"), SV("abcdeabcde"), 1, S::npos); + test(S("abcdeabcde"), SV("abcdeabcdeabcdeabcde"), 1, S::npos); + test(S("abcdeabcde"), SV(""), 5, 5); + test(S("abcdeabcde"), SV("abcde"), 5, 5); + test(S("abcdeabcde"), SV("abcdeabcde"), 5, S::npos); + test(S("abcdeabcde"), SV("abcdeabcdeabcdeabcde"), 5, S::npos); + test(S("abcdeabcde"), SV(""), 9, 9); + test(S("abcdeabcde"), SV("abcde"), 9, S::npos); + test(S("abcdeabcde"), SV("abcdeabcde"), 9, S::npos); + test(S("abcdeabcde"), SV("abcdeabcdeabcdeabcde"), 9, S::npos); + test(S("abcdeabcde"), SV(""), 10, 10); + test(S("abcdeabcde"), SV("abcde"), 10, S::npos); + test(S("abcdeabcde"), SV("abcdeabcde"), 10, S::npos); + test(S("abcdeabcde"), SV("abcdeabcdeabcdeabcde"), 10, S::npos); + test(S("abcdeabcde"), SV(""), 11, S::npos); + test(S("abcdeabcde"), SV("abcde"), 11, S::npos); + test(S("abcdeabcde"), SV("abcdeabcde"), 11, S::npos); + test(S("abcdeabcde"), SV("abcdeabcdeabcdeabcde"), 11, S::npos); + test(S("abcdeabcdeabcdeabcde"), SV(""), 0, 0); + test(S("abcdeabcdeabcdeabcde"), SV("abcde"), 0, 0); + test(S("abcdeabcdeabcdeabcde"), SV("abcdeabcde"), 0, 0); + test(S("abcdeabcdeabcdeabcde"), SV("abcdeabcdeabcdeabcde"), 0, 0); + test(S("abcdeabcdeabcdeabcde"), SV(""), 1, 1); + test(S("abcdeabcdeabcdeabcde"), SV("abcde"), 1, 5); + test(S("abcdeabcdeabcdeabcde"), SV("abcdeabcde"), 1, 5); + test(S("abcdeabcdeabcdeabcde"), SV("abcdeabcdeabcdeabcde"), 1, S::npos); + test(S("abcdeabcdeabcdeabcde"), SV(""), 10, 10); + test(S("abcdeabcdeabcdeabcde"), SV("abcde"), 10, 10); + test(S("abcdeabcdeabcdeabcde"), SV("abcdeabcde"), 10, 10); + test(S("abcdeabcdeabcdeabcde"), SV("abcdeabcdeabcdeabcde"), 10, S::npos); + test(S("abcdeabcdeabcdeabcde"), SV(""), 19, 19); + test(S("abcdeabcdeabcdeabcde"), SV("abcde"), 19, S::npos); + test(S("abcdeabcdeabcdeabcde"), SV("abcdeabcde"), 19, S::npos); + test(S("abcdeabcdeabcdeabcde"), SV("abcdeabcdeabcdeabcde"), 19, S::npos); + test(S("abcdeabcdeabcdeabcde"), SV(""), 20, 20); + test(S("abcdeabcdeabcdeabcde"), SV("abcde"), 20, S::npos); + test(S("abcdeabcdeabcdeabcde"), SV("abcdeabcde"), 20, S::npos); + test(S("abcdeabcdeabcdeabcde"), SV("abcdeabcdeabcdeabcde"), 20, S::npos); + test(S("abcdeabcdeabcdeabcde"), SV(""), 21, S::npos); + test(S("abcdeabcdeabcdeabcde"), SV("abcde"), 21, S::npos); + test(S("abcdeabcdeabcdeabcde"), SV("abcdeabcde"), 21, S::npos); + test(S("abcdeabcdeabcdeabcde"), SV("abcdeabcdeabcdeabcde"), 21, S::npos); +} + +template +void test1() +{ + test(S(""), SV(""), 0); + test(S(""), SV("abcde"), S::npos); + test(S(""), SV("abcdeabcde"), S::npos); + test(S(""), SV("abcdeabcdeabcdeabcde"), S::npos); + test(S("abcde"), SV(""), 0); + test(S("abcde"), SV("abcde"), 0); + test(S("abcde"), SV("abcdeabcde"), S::npos); + test(S("abcde"), SV("abcdeabcdeabcdeabcde"), S::npos); + test(S("abcdeabcde"), SV(""), 0); + test(S("abcdeabcde"), SV("abcde"), 0); + test(S("abcdeabcde"), SV("abcdeabcde"), 0); + test(S("abcdeabcde"), SV("abcdeabcdeabcdeabcde"), S::npos); + test(S("abcdeabcdeabcdeabcde"), SV(""), 0); + test(S("abcdeabcdeabcdeabcde"), SV("abcde"), 0); + test(S("abcdeabcdeabcdeabcde"), SV("abcdeabcde"), 0); + test(S("abcdeabcdeabcdeabcde"), SV("abcdeabcdeabcdeabcde"), 0); +} + +int main() +{ + { + typedef std::string S; + typedef std::string_view SV; + test0(); + test1(); + } +#if TEST_STD_VER >= 11 + { + typedef std::basic_string, min_allocator> S; + typedef std::string_view SV; + test0(); + test1(); + } +#endif +} diff --git a/tests/external/libcxx/basic_string/string.ops/string_rfind/char_size.pass.cpp b/tests/external/libcxx/basic_string/string.ops/string_rfind/char_size.pass.cpp new file mode 100644 index 0000000..c53d77f --- /dev/null +++ b/tests/external/libcxx/basic_string/string.ops/string_rfind/char_size.pass.cpp @@ -0,0 +1,98 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// + +// size_type rfind(charT c, size_type pos = npos) const; + +#include +#include + +#include "min_allocator.h" + +template +void +test(const S& s, typename S::value_type c, typename S::size_type pos, + typename S::size_type x) +{ + assert(s.rfind(c, pos) == x); + if (x != S::npos) + assert(x <= pos && x + 1 <= s.size()); +} + +template +void +test(const S& s, typename S::value_type c, typename S::size_type x) +{ + assert(s.rfind(c) == x); + if (x != S::npos) + assert(x + 1 <= s.size()); +} + +int main() +{ + { + typedef std::string S; + test(S(""), 'b', 0, S::npos); + test(S(""), 'b', 1, S::npos); + test(S("abcde"), 'b', 0, S::npos); + test(S("abcde"), 'b', 1, 1); + test(S("abcde"), 'b', 2, 1); + test(S("abcde"), 'b', 4, 1); + test(S("abcde"), 'b', 5, 1); + test(S("abcde"), 'b', 6, 1); + test(S("abcdeabcde"), 'b', 0, S::npos); + test(S("abcdeabcde"), 'b', 1, 1); + test(S("abcdeabcde"), 'b', 5, 1); + test(S("abcdeabcde"), 'b', 9, 6); + test(S("abcdeabcde"), 'b', 10, 6); + test(S("abcdeabcde"), 'b', 11, 6); + test(S("abcdeabcdeabcdeabcde"), 'b', 0, S::npos); + test(S("abcdeabcdeabcdeabcde"), 'b', 1, 1); + test(S("abcdeabcdeabcdeabcde"), 'b', 10, 6); + test(S("abcdeabcdeabcdeabcde"), 'b', 19, 16); + test(S("abcdeabcdeabcdeabcde"), 'b', 20, 16); + test(S("abcdeabcdeabcdeabcde"), 'b', 21, 16); + + test(S(""), 'b', S::npos); + test(S("abcde"), 'b', 1); + test(S("abcdeabcde"), 'b', 6); + test(S("abcdeabcdeabcdeabcde"), 'b', 16); + } +#if TEST_STD_VER >= 11 + { + typedef std::basic_string, min_allocator> S; + test(S(""), 'b', 0, S::npos); + test(S(""), 'b', 1, S::npos); + test(S("abcde"), 'b', 0, S::npos); + test(S("abcde"), 'b', 1, 1); + test(S("abcde"), 'b', 2, 1); + test(S("abcde"), 'b', 4, 1); + test(S("abcde"), 'b', 5, 1); + test(S("abcde"), 'b', 6, 1); + test(S("abcdeabcde"), 'b', 0, S::npos); + test(S("abcdeabcde"), 'b', 1, 1); + test(S("abcdeabcde"), 'b', 5, 1); + test(S("abcdeabcde"), 'b', 9, 6); + test(S("abcdeabcde"), 'b', 10, 6); + test(S("abcdeabcde"), 'b', 11, 6); + test(S("abcdeabcdeabcdeabcde"), 'b', 0, S::npos); + test(S("abcdeabcdeabcdeabcde"), 'b', 1, 1); + test(S("abcdeabcdeabcdeabcde"), 'b', 10, 6); + test(S("abcdeabcdeabcdeabcde"), 'b', 19, 16); + test(S("abcdeabcdeabcdeabcde"), 'b', 20, 16); + test(S("abcdeabcdeabcdeabcde"), 'b', 21, 16); + + test(S(""), 'b', S::npos); + test(S("abcde"), 'b', 1); + test(S("abcdeabcde"), 'b', 6); + test(S("abcdeabcdeabcdeabcde"), 'b', 16); + } +#endif +} diff --git a/tests/external/libcxx/basic_string/string.ops/string_rfind/pointer_size.pass.cpp b/tests/external/libcxx/basic_string/string.ops/string_rfind/pointer_size.pass.cpp new file mode 100644 index 0000000..ebcb0ea --- /dev/null +++ b/tests/external/libcxx/basic_string/string.ops/string_rfind/pointer_size.pass.cpp @@ -0,0 +1,165 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// + +// size_type rfind(const charT* s, size_type pos = npos) const; + +#include +#include + +#include "min_allocator.h" + +template +void +test(const S& s, const typename S::value_type* str, typename S::size_type pos, + typename S::size_type x) +{ + assert(s.rfind(str, pos) == x); + if (x != S::npos) + { + typename S::size_type n = S::traits_type::length(str); + assert(x <= pos && x + n <= s.size()); + } +} + +template +void +test(const S& s, const typename S::value_type* str, typename S::size_type x) +{ + assert(s.rfind(str) == x); + if (x != S::npos) + { + typename S::size_type pos = s.size(); + typename S::size_type n = S::traits_type::length(str); + assert(x <= pos && x + n <= s.size()); + } +} + +template +void test0() +{ + test(S(""), "", 0, 0); + test(S(""), "abcde", 0, S::npos); + test(S(""), "abcdeabcde", 0, S::npos); + test(S(""), "abcdeabcdeabcdeabcde", 0, S::npos); + test(S(""), "", 1, 0); + test(S(""), "abcde", 1, S::npos); + test(S(""), "abcdeabcde", 1, S::npos); + test(S(""), "abcdeabcdeabcdeabcde", 1, S::npos); + test(S("abcde"), "", 0, 0); + test(S("abcde"), "abcde", 0, 0); + test(S("abcde"), "abcdeabcde", 0, S::npos); + test(S("abcde"), "abcdeabcdeabcdeabcde", 0, S::npos); + test(S("abcde"), "", 1, 1); + test(S("abcde"), "abcde", 1, 0); + test(S("abcde"), "abcdeabcde", 1, S::npos); + test(S("abcde"), "abcdeabcdeabcdeabcde", 1, S::npos); + test(S("abcde"), "", 2, 2); + test(S("abcde"), "abcde", 2, 0); + test(S("abcde"), "abcdeabcde", 2, S::npos); + test(S("abcde"), "abcdeabcdeabcdeabcde", 2, S::npos); + test(S("abcde"), "", 4, 4); + test(S("abcde"), "abcde", 4, 0); + test(S("abcde"), "abcdeabcde", 4, S::npos); + test(S("abcde"), "abcdeabcdeabcdeabcde", 4, S::npos); + test(S("abcde"), "", 5, 5); + test(S("abcde"), "abcde", 5, 0); + test(S("abcde"), "abcdeabcde", 5, S::npos); + test(S("abcde"), "abcdeabcdeabcdeabcde", 5, S::npos); + test(S("abcde"), "", 6, 5); + test(S("abcde"), "abcde", 6, 0); + test(S("abcde"), "abcdeabcde", 6, S::npos); + test(S("abcde"), "abcdeabcdeabcdeabcde", 6, S::npos); + test(S("abcdeabcde"), "", 0, 0); + test(S("abcdeabcde"), "abcde", 0, 0); + test(S("abcdeabcde"), "abcdeabcde", 0, 0); + test(S("abcdeabcde"), "abcdeabcdeabcdeabcde", 0, S::npos); + test(S("abcdeabcde"), "", 1, 1); + test(S("abcdeabcde"), "abcde", 1, 0); + test(S("abcdeabcde"), "abcdeabcde", 1, 0); + test(S("abcdeabcde"), "abcdeabcdeabcdeabcde", 1, S::npos); + test(S("abcdeabcde"), "", 5, 5); + test(S("abcdeabcde"), "abcde", 5, 5); + test(S("abcdeabcde"), "abcdeabcde", 5, 0); + test(S("abcdeabcde"), "abcdeabcdeabcdeabcde", 5, S::npos); + test(S("abcdeabcde"), "", 9, 9); + test(S("abcdeabcde"), "abcde", 9, 5); + test(S("abcdeabcde"), "abcdeabcde", 9, 0); + test(S("abcdeabcde"), "abcdeabcdeabcdeabcde", 9, S::npos); + test(S("abcdeabcde"), "", 10, 10); + test(S("abcdeabcde"), "abcde", 10, 5); + test(S("abcdeabcde"), "abcdeabcde", 10, 0); + test(S("abcdeabcde"), "abcdeabcdeabcdeabcde", 10, S::npos); + test(S("abcdeabcde"), "", 11, 10); + test(S("abcdeabcde"), "abcde", 11, 5); + test(S("abcdeabcde"), "abcdeabcde", 11, 0); + test(S("abcdeabcde"), "abcdeabcdeabcdeabcde", 11, S::npos); + test(S("abcdeabcdeabcdeabcde"), "", 0, 0); + test(S("abcdeabcdeabcdeabcde"), "abcde", 0, 0); + test(S("abcdeabcdeabcdeabcde"), "abcdeabcde", 0, 0); + test(S("abcdeabcdeabcdeabcde"), "abcdeabcdeabcdeabcde", 0, 0); + test(S("abcdeabcdeabcdeabcde"), "", 1, 1); + test(S("abcdeabcdeabcdeabcde"), "abcde", 1, 0); + test(S("abcdeabcdeabcdeabcde"), "abcdeabcde", 1, 0); + test(S("abcdeabcdeabcdeabcde"), "abcdeabcdeabcdeabcde", 1, 0); + test(S("abcdeabcdeabcdeabcde"), "", 10, 10); + test(S("abcdeabcdeabcdeabcde"), "abcde", 10, 10); + test(S("abcdeabcdeabcdeabcde"), "abcdeabcde", 10, 10); + test(S("abcdeabcdeabcdeabcde"), "abcdeabcdeabcdeabcde", 10, 0); + test(S("abcdeabcdeabcdeabcde"), "", 19, 19); + test(S("abcdeabcdeabcdeabcde"), "abcde", 19, 15); + test(S("abcdeabcdeabcdeabcde"), "abcdeabcde", 19, 10); + test(S("abcdeabcdeabcdeabcde"), "abcdeabcdeabcdeabcde", 19, 0); + test(S("abcdeabcdeabcdeabcde"), "", 20, 20); + test(S("abcdeabcdeabcdeabcde"), "abcde", 20, 15); + test(S("abcdeabcdeabcdeabcde"), "abcdeabcde", 20, 10); + test(S("abcdeabcdeabcdeabcde"), "abcdeabcdeabcdeabcde", 20, 0); + test(S("abcdeabcdeabcdeabcde"), "", 21, 20); + test(S("abcdeabcdeabcdeabcde"), "abcde", 21, 15); + test(S("abcdeabcdeabcdeabcde"), "abcdeabcde", 21, 10); + test(S("abcdeabcdeabcdeabcde"), "abcdeabcdeabcdeabcde", 21, 0); +} + +template +void test1() +{ + test(S(""), "", 0); + test(S(""), "abcde", S::npos); + test(S(""), "abcdeabcde", S::npos); + test(S(""), "abcdeabcdeabcdeabcde", S::npos); + test(S("abcde"), "", 5); + test(S("abcde"), "abcde", 0); + test(S("abcde"), "abcdeabcde", S::npos); + test(S("abcde"), "abcdeabcdeabcdeabcde", S::npos); + test(S("abcdeabcde"), "", 10); + test(S("abcdeabcde"), "abcde", 5); + test(S("abcdeabcde"), "abcdeabcde", 0); + test(S("abcdeabcde"), "abcdeabcdeabcdeabcde", S::npos); + test(S("abcdeabcdeabcdeabcde"), "", 20); + test(S("abcdeabcdeabcdeabcde"), "abcde", 15); + test(S("abcdeabcdeabcdeabcde"), "abcdeabcde", 10); + test(S("abcdeabcdeabcdeabcde"), "abcdeabcdeabcdeabcde", 0); +} + +int main() +{ + { + typedef std::string S; + test0(); + test1(); + } +#if TEST_STD_VER >= 11 + { + typedef std::basic_string, min_allocator> S; + test0(); + test1(); + } +#endif +} diff --git a/tests/external/libcxx/basic_string/string.ops/string_rfind/pointer_size_size.pass.cpp b/tests/external/libcxx/basic_string/string.ops/string_rfind/pointer_size_size.pass.cpp new file mode 100644 index 0000000..e8d0c6b --- /dev/null +++ b/tests/external/libcxx/basic_string/string.ops/string_rfind/pointer_size_size.pass.cpp @@ -0,0 +1,387 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// + +// size_type rfind(const charT* s, size_type pos, size_type n) const; + +#include +#include + +#include "min_allocator.h" + +template +void +test(const S& s, const typename S::value_type* str, typename S::size_type pos, + typename S::size_type n, typename S::size_type x) +{ + assert(s.rfind(str, pos, n) == x); + if (x != S::npos) + assert(x <= pos && x + n <= s.size()); +} + +template +void test0() +{ + test(S(""), "", 0, 0, 0); + test(S(""), "abcde", 0, 0, 0); + test(S(""), "abcde", 0, 1, S::npos); + test(S(""), "abcde", 0, 2, S::npos); + test(S(""), "abcde", 0, 4, S::npos); + test(S(""), "abcde", 0, 5, S::npos); + test(S(""), "abcdeabcde", 0, 0, 0); + test(S(""), "abcdeabcde", 0, 1, S::npos); + test(S(""), "abcdeabcde", 0, 5, S::npos); + test(S(""), "abcdeabcde", 0, 9, S::npos); + test(S(""), "abcdeabcde", 0, 10, S::npos); + test(S(""), "abcdeabcdeabcdeabcde", 0, 0, 0); + test(S(""), "abcdeabcdeabcdeabcde", 0, 1, S::npos); + test(S(""), "abcdeabcdeabcdeabcde", 0, 10, S::npos); + test(S(""), "abcdeabcdeabcdeabcde", 0, 19, S::npos); + test(S(""), "abcdeabcdeabcdeabcde", 0, 20, S::npos); + test(S(""), "", 1, 0, 0); + test(S(""), "abcde", 1, 0, 0); + test(S(""), "abcde", 1, 1, S::npos); + test(S(""), "abcde", 1, 2, S::npos); + test(S(""), "abcde", 1, 4, S::npos); + test(S(""), "abcde", 1, 5, S::npos); + test(S(""), "abcdeabcde", 1, 0, 0); + test(S(""), "abcdeabcde", 1, 1, S::npos); + test(S(""), "abcdeabcde", 1, 5, S::npos); + test(S(""), "abcdeabcde", 1, 9, S::npos); + test(S(""), "abcdeabcde", 1, 10, S::npos); + test(S(""), "abcdeabcdeabcdeabcde", 1, 0, 0); + test(S(""), "abcdeabcdeabcdeabcde", 1, 1, S::npos); + test(S(""), "abcdeabcdeabcdeabcde", 1, 10, S::npos); + test(S(""), "abcdeabcdeabcdeabcde", 1, 19, S::npos); + test(S(""), "abcdeabcdeabcdeabcde", 1, 20, S::npos); + test(S("abcde"), "", 0, 0, 0); + test(S("abcde"), "abcde", 0, 0, 0); + test(S("abcde"), "abcde", 0, 1, 0); + test(S("abcde"), "abcde", 0, 2, 0); + test(S("abcde"), "abcde", 0, 4, 0); + test(S("abcde"), "abcde", 0, 5, 0); + test(S("abcde"), "abcdeabcde", 0, 0, 0); + test(S("abcde"), "abcdeabcde", 0, 1, 0); + test(S("abcde"), "abcdeabcde", 0, 5, 0); + test(S("abcde"), "abcdeabcde", 0, 9, S::npos); + test(S("abcde"), "abcdeabcde", 0, 10, S::npos); + test(S("abcde"), "abcdeabcdeabcdeabcde", 0, 0, 0); + test(S("abcde"), "abcdeabcdeabcdeabcde", 0, 1, 0); + test(S("abcde"), "abcdeabcdeabcdeabcde", 0, 10, S::npos); + test(S("abcde"), "abcdeabcdeabcdeabcde", 0, 19, S::npos); + test(S("abcde"), "abcdeabcdeabcdeabcde", 0, 20, S::npos); + test(S("abcde"), "", 1, 0, 1); + test(S("abcde"), "abcde", 1, 0, 1); + test(S("abcde"), "abcde", 1, 1, 0); + test(S("abcde"), "abcde", 1, 2, 0); + test(S("abcde"), "abcde", 1, 4, 0); + test(S("abcde"), "abcde", 1, 5, 0); + test(S("abcde"), "abcdeabcde", 1, 0, 1); + test(S("abcde"), "abcdeabcde", 1, 1, 0); + test(S("abcde"), "abcdeabcde", 1, 5, 0); + test(S("abcde"), "abcdeabcde", 1, 9, S::npos); + test(S("abcde"), "abcdeabcde", 1, 10, S::npos); + test(S("abcde"), "abcdeabcdeabcdeabcde", 1, 0, 1); + test(S("abcde"), "abcdeabcdeabcdeabcde", 1, 1, 0); + test(S("abcde"), "abcdeabcdeabcdeabcde", 1, 10, S::npos); + test(S("abcde"), "abcdeabcdeabcdeabcde", 1, 19, S::npos); + test(S("abcde"), "abcdeabcdeabcdeabcde", 1, 20, S::npos); + test(S("abcde"), "", 2, 0, 2); + test(S("abcde"), "abcde", 2, 0, 2); + test(S("abcde"), "abcde", 2, 1, 0); + test(S("abcde"), "abcde", 2, 2, 0); + test(S("abcde"), "abcde", 2, 4, 0); + test(S("abcde"), "abcde", 2, 5, 0); + test(S("abcde"), "abcdeabcde", 2, 0, 2); + test(S("abcde"), "abcdeabcde", 2, 1, 0); + test(S("abcde"), "abcdeabcde", 2, 5, 0); + test(S("abcde"), "abcdeabcde", 2, 9, S::npos); + test(S("abcde"), "abcdeabcde", 2, 10, S::npos); + test(S("abcde"), "abcdeabcdeabcdeabcde", 2, 0, 2); + test(S("abcde"), "abcdeabcdeabcdeabcde", 2, 1, 0); + test(S("abcde"), "abcdeabcdeabcdeabcde", 2, 10, S::npos); + test(S("abcde"), "abcdeabcdeabcdeabcde", 2, 19, S::npos); + test(S("abcde"), "abcdeabcdeabcdeabcde", 2, 20, S::npos); + test(S("abcde"), "", 4, 0, 4); + test(S("abcde"), "abcde", 4, 0, 4); + test(S("abcde"), "abcde", 4, 1, 0); + test(S("abcde"), "abcde", 4, 2, 0); + test(S("abcde"), "abcde", 4, 4, 0); + test(S("abcde"), "abcde", 4, 5, 0); + test(S("abcde"), "abcdeabcde", 4, 0, 4); + test(S("abcde"), "abcdeabcde", 4, 1, 0); + test(S("abcde"), "abcdeabcde", 4, 5, 0); + test(S("abcde"), "abcdeabcde", 4, 9, S::npos); + test(S("abcde"), "abcdeabcde", 4, 10, S::npos); + test(S("abcde"), "abcdeabcdeabcdeabcde", 4, 0, 4); + test(S("abcde"), "abcdeabcdeabcdeabcde", 4, 1, 0); + test(S("abcde"), "abcdeabcdeabcdeabcde", 4, 10, S::npos); + test(S("abcde"), "abcdeabcdeabcdeabcde", 4, 19, S::npos); + test(S("abcde"), "abcdeabcdeabcdeabcde", 4, 20, S::npos); + test(S("abcde"), "", 5, 0, 5); + test(S("abcde"), "abcde", 5, 0, 5); + test(S("abcde"), "abcde", 5, 1, 0); + test(S("abcde"), "abcde", 5, 2, 0); +} + +template +void test1() +{ + test(S("abcde"), "abcde", 5, 4, 0); + test(S("abcde"), "abcde", 5, 5, 0); + test(S("abcde"), "abcdeabcde", 5, 0, 5); + test(S("abcde"), "abcdeabcde", 5, 1, 0); + test(S("abcde"), "abcdeabcde", 5, 5, 0); + test(S("abcde"), "abcdeabcde", 5, 9, S::npos); + test(S("abcde"), "abcdeabcde", 5, 10, S::npos); + test(S("abcde"), "abcdeabcdeabcdeabcde", 5, 0, 5); + test(S("abcde"), "abcdeabcdeabcdeabcde", 5, 1, 0); + test(S("abcde"), "abcdeabcdeabcdeabcde", 5, 10, S::npos); + test(S("abcde"), "abcdeabcdeabcdeabcde", 5, 19, S::npos); + test(S("abcde"), "abcdeabcdeabcdeabcde", 5, 20, S::npos); + test(S("abcde"), "", 6, 0, 5); + test(S("abcde"), "abcde", 6, 0, 5); + test(S("abcde"), "abcde", 6, 1, 0); + test(S("abcde"), "abcde", 6, 2, 0); + test(S("abcde"), "abcde", 6, 4, 0); + test(S("abcde"), "abcde", 6, 5, 0); + test(S("abcde"), "abcdeabcde", 6, 0, 5); + test(S("abcde"), "abcdeabcde", 6, 1, 0); + test(S("abcde"), "abcdeabcde", 6, 5, 0); + test(S("abcde"), "abcdeabcde", 6, 9, S::npos); + test(S("abcde"), "abcdeabcde", 6, 10, S::npos); + test(S("abcde"), "abcdeabcdeabcdeabcde", 6, 0, 5); + test(S("abcde"), "abcdeabcdeabcdeabcde", 6, 1, 0); + test(S("abcde"), "abcdeabcdeabcdeabcde", 6, 10, S::npos); + test(S("abcde"), "abcdeabcdeabcdeabcde", 6, 19, S::npos); + test(S("abcde"), "abcdeabcdeabcdeabcde", 6, 20, S::npos); + test(S("abcdeabcde"), "", 0, 0, 0); + test(S("abcdeabcde"), "abcde", 0, 0, 0); + test(S("abcdeabcde"), "abcde", 0, 1, 0); + test(S("abcdeabcde"), "abcde", 0, 2, 0); + test(S("abcdeabcde"), "abcde", 0, 4, 0); + test(S("abcdeabcde"), "abcde", 0, 5, 0); + test(S("abcdeabcde"), "abcdeabcde", 0, 0, 0); + test(S("abcdeabcde"), "abcdeabcde", 0, 1, 0); + test(S("abcdeabcde"), "abcdeabcde", 0, 5, 0); + test(S("abcdeabcde"), "abcdeabcde", 0, 9, 0); + test(S("abcdeabcde"), "abcdeabcde", 0, 10, 0); + test(S("abcdeabcde"), "abcdeabcdeabcdeabcde", 0, 0, 0); + test(S("abcdeabcde"), "abcdeabcdeabcdeabcde", 0, 1, 0); + test(S("abcdeabcde"), "abcdeabcdeabcdeabcde", 0, 10, 0); + test(S("abcdeabcde"), "abcdeabcdeabcdeabcde", 0, 19, S::npos); + test(S("abcdeabcde"), "abcdeabcdeabcdeabcde", 0, 20, S::npos); + test(S("abcdeabcde"), "", 1, 0, 1); + test(S("abcdeabcde"), "abcde", 1, 0, 1); + test(S("abcdeabcde"), "abcde", 1, 1, 0); + test(S("abcdeabcde"), "abcde", 1, 2, 0); + test(S("abcdeabcde"), "abcde", 1, 4, 0); + test(S("abcdeabcde"), "abcde", 1, 5, 0); + test(S("abcdeabcde"), "abcdeabcde", 1, 0, 1); + test(S("abcdeabcde"), "abcdeabcde", 1, 1, 0); + test(S("abcdeabcde"), "abcdeabcde", 1, 5, 0); + test(S("abcdeabcde"), "abcdeabcde", 1, 9, 0); + test(S("abcdeabcde"), "abcdeabcde", 1, 10, 0); + test(S("abcdeabcde"), "abcdeabcdeabcdeabcde", 1, 0, 1); + test(S("abcdeabcde"), "abcdeabcdeabcdeabcde", 1, 1, 0); + test(S("abcdeabcde"), "abcdeabcdeabcdeabcde", 1, 10, 0); + test(S("abcdeabcde"), "abcdeabcdeabcdeabcde", 1, 19, S::npos); + test(S("abcdeabcde"), "abcdeabcdeabcdeabcde", 1, 20, S::npos); + test(S("abcdeabcde"), "", 5, 0, 5); + test(S("abcdeabcde"), "abcde", 5, 0, 5); + test(S("abcdeabcde"), "abcde", 5, 1, 5); + test(S("abcdeabcde"), "abcde", 5, 2, 5); + test(S("abcdeabcde"), "abcde", 5, 4, 5); + test(S("abcdeabcde"), "abcde", 5, 5, 5); + test(S("abcdeabcde"), "abcdeabcde", 5, 0, 5); + test(S("abcdeabcde"), "abcdeabcde", 5, 1, 5); + test(S("abcdeabcde"), "abcdeabcde", 5, 5, 5); + test(S("abcdeabcde"), "abcdeabcde", 5, 9, 0); + test(S("abcdeabcde"), "abcdeabcde", 5, 10, 0); + test(S("abcdeabcde"), "abcdeabcdeabcdeabcde", 5, 0, 5); + test(S("abcdeabcde"), "abcdeabcdeabcdeabcde", 5, 1, 5); + test(S("abcdeabcde"), "abcdeabcdeabcdeabcde", 5, 10, 0); + test(S("abcdeabcde"), "abcdeabcdeabcdeabcde", 5, 19, S::npos); + test(S("abcdeabcde"), "abcdeabcdeabcdeabcde", 5, 20, S::npos); + test(S("abcdeabcde"), "", 9, 0, 9); + test(S("abcdeabcde"), "abcde", 9, 0, 9); + test(S("abcdeabcde"), "abcde", 9, 1, 5); + test(S("abcdeabcde"), "abcde", 9, 2, 5); + test(S("abcdeabcde"), "abcde", 9, 4, 5); + test(S("abcdeabcde"), "abcde", 9, 5, 5); + test(S("abcdeabcde"), "abcdeabcde", 9, 0, 9); + test(S("abcdeabcde"), "abcdeabcde", 9, 1, 5); + test(S("abcdeabcde"), "abcdeabcde", 9, 5, 5); + test(S("abcdeabcde"), "abcdeabcde", 9, 9, 0); + test(S("abcdeabcde"), "abcdeabcde", 9, 10, 0); + test(S("abcdeabcde"), "abcdeabcdeabcdeabcde", 9, 0, 9); + test(S("abcdeabcde"), "abcdeabcdeabcdeabcde", 9, 1, 5); + test(S("abcdeabcde"), "abcdeabcdeabcdeabcde", 9, 10, 0); + test(S("abcdeabcde"), "abcdeabcdeabcdeabcde", 9, 19, S::npos); + test(S("abcdeabcde"), "abcdeabcdeabcdeabcde", 9, 20, S::npos); + test(S("abcdeabcde"), "", 10, 0, 10); + test(S("abcdeabcde"), "abcde", 10, 0, 10); + test(S("abcdeabcde"), "abcde", 10, 1, 5); + test(S("abcdeabcde"), "abcde", 10, 2, 5); + test(S("abcdeabcde"), "abcde", 10, 4, 5); + test(S("abcdeabcde"), "abcde", 10, 5, 5); + test(S("abcdeabcde"), "abcdeabcde", 10, 0, 10); + test(S("abcdeabcde"), "abcdeabcde", 10, 1, 5); +} + +template +void test2() +{ + test(S("abcdeabcde"), "abcdeabcde", 10, 5, 5); + test(S("abcdeabcde"), "abcdeabcde", 10, 9, 0); + test(S("abcdeabcde"), "abcdeabcde", 10, 10, 0); + test(S("abcdeabcde"), "abcdeabcdeabcdeabcde", 10, 0, 10); + test(S("abcdeabcde"), "abcdeabcdeabcdeabcde", 10, 1, 5); + test(S("abcdeabcde"), "abcdeabcdeabcdeabcde", 10, 10, 0); + test(S("abcdeabcde"), "abcdeabcdeabcdeabcde", 10, 19, S::npos); + test(S("abcdeabcde"), "abcdeabcdeabcdeabcde", 10, 20, S::npos); + test(S("abcdeabcde"), "", 11, 0, 10); + test(S("abcdeabcde"), "abcde", 11, 0, 10); + test(S("abcdeabcde"), "abcde", 11, 1, 5); + test(S("abcdeabcde"), "abcde", 11, 2, 5); + test(S("abcdeabcde"), "abcde", 11, 4, 5); + test(S("abcdeabcde"), "abcde", 11, 5, 5); + test(S("abcdeabcde"), "abcdeabcde", 11, 0, 10); + test(S("abcdeabcde"), "abcdeabcde", 11, 1, 5); + test(S("abcdeabcde"), "abcdeabcde", 11, 5, 5); + test(S("abcdeabcde"), "abcdeabcde", 11, 9, 0); + test(S("abcdeabcde"), "abcdeabcde", 11, 10, 0); + test(S("abcdeabcde"), "abcdeabcdeabcdeabcde", 11, 0, 10); + test(S("abcdeabcde"), "abcdeabcdeabcdeabcde", 11, 1, 5); + test(S("abcdeabcde"), "abcdeabcdeabcdeabcde", 11, 10, 0); + test(S("abcdeabcde"), "abcdeabcdeabcdeabcde", 11, 19, S::npos); + test(S("abcdeabcde"), "abcdeabcdeabcdeabcde", 11, 20, S::npos); + test(S("abcdeabcdeabcdeabcde"), "", 0, 0, 0); + test(S("abcdeabcdeabcdeabcde"), "abcde", 0, 0, 0); + test(S("abcdeabcdeabcdeabcde"), "abcde", 0, 1, 0); + test(S("abcdeabcdeabcdeabcde"), "abcde", 0, 2, 0); + test(S("abcdeabcdeabcdeabcde"), "abcde", 0, 4, 0); + test(S("abcdeabcdeabcdeabcde"), "abcde", 0, 5, 0); + test(S("abcdeabcdeabcdeabcde"), "abcdeabcde", 0, 0, 0); + test(S("abcdeabcdeabcdeabcde"), "abcdeabcde", 0, 1, 0); + test(S("abcdeabcdeabcdeabcde"), "abcdeabcde", 0, 5, 0); + test(S("abcdeabcdeabcdeabcde"), "abcdeabcde", 0, 9, 0); + test(S("abcdeabcdeabcdeabcde"), "abcdeabcde", 0, 10, 0); + test(S("abcdeabcdeabcdeabcde"), "abcdeabcdeabcdeabcde", 0, 0, 0); + test(S("abcdeabcdeabcdeabcde"), "abcdeabcdeabcdeabcde", 0, 1, 0); + test(S("abcdeabcdeabcdeabcde"), "abcdeabcdeabcdeabcde", 0, 10, 0); + test(S("abcdeabcdeabcdeabcde"), "abcdeabcdeabcdeabcde", 0, 19, 0); + test(S("abcdeabcdeabcdeabcde"), "abcdeabcdeabcdeabcde", 0, 20, 0); + test(S("abcdeabcdeabcdeabcde"), "", 1, 0, 1); + test(S("abcdeabcdeabcdeabcde"), "abcde", 1, 0, 1); + test(S("abcdeabcdeabcdeabcde"), "abcde", 1, 1, 0); + test(S("abcdeabcdeabcdeabcde"), "abcde", 1, 2, 0); + test(S("abcdeabcdeabcdeabcde"), "abcde", 1, 4, 0); + test(S("abcdeabcdeabcdeabcde"), "abcde", 1, 5, 0); + test(S("abcdeabcdeabcdeabcde"), "abcdeabcde", 1, 0, 1); + test(S("abcdeabcdeabcdeabcde"), "abcdeabcde", 1, 1, 0); + test(S("abcdeabcdeabcdeabcde"), "abcdeabcde", 1, 5, 0); + test(S("abcdeabcdeabcdeabcde"), "abcdeabcde", 1, 9, 0); + test(S("abcdeabcdeabcdeabcde"), "abcdeabcde", 1, 10, 0); + test(S("abcdeabcdeabcdeabcde"), "abcdeabcdeabcdeabcde", 1, 0, 1); + test(S("abcdeabcdeabcdeabcde"), "abcdeabcdeabcdeabcde", 1, 1, 0); + test(S("abcdeabcdeabcdeabcde"), "abcdeabcdeabcdeabcde", 1, 10, 0); + test(S("abcdeabcdeabcdeabcde"), "abcdeabcdeabcdeabcde", 1, 19, 0); + test(S("abcdeabcdeabcdeabcde"), "abcdeabcdeabcdeabcde", 1, 20, 0); + test(S("abcdeabcdeabcdeabcde"), "", 10, 0, 10); + test(S("abcdeabcdeabcdeabcde"), "abcde", 10, 0, 10); + test(S("abcdeabcdeabcdeabcde"), "abcde", 10, 1, 10); + test(S("abcdeabcdeabcdeabcde"), "abcde", 10, 2, 10); + test(S("abcdeabcdeabcdeabcde"), "abcde", 10, 4, 10); + test(S("abcdeabcdeabcdeabcde"), "abcde", 10, 5, 10); + test(S("abcdeabcdeabcdeabcde"), "abcdeabcde", 10, 0, 10); + test(S("abcdeabcdeabcdeabcde"), "abcdeabcde", 10, 1, 10); + test(S("abcdeabcdeabcdeabcde"), "abcdeabcde", 10, 5, 10); + test(S("abcdeabcdeabcdeabcde"), "abcdeabcde", 10, 9, 10); + test(S("abcdeabcdeabcdeabcde"), "abcdeabcde", 10, 10, 10); + test(S("abcdeabcdeabcdeabcde"), "abcdeabcdeabcdeabcde", 10, 0, 10); + test(S("abcdeabcdeabcdeabcde"), "abcdeabcdeabcdeabcde", 10, 1, 10); + test(S("abcdeabcdeabcdeabcde"), "abcdeabcdeabcdeabcde", 10, 10, 10); + test(S("abcdeabcdeabcdeabcde"), "abcdeabcdeabcdeabcde", 10, 19, 0); + test(S("abcdeabcdeabcdeabcde"), "abcdeabcdeabcdeabcde", 10, 20, 0); + test(S("abcdeabcdeabcdeabcde"), "", 19, 0, 19); + test(S("abcdeabcdeabcdeabcde"), "abcde", 19, 0, 19); + test(S("abcdeabcdeabcdeabcde"), "abcde", 19, 1, 15); + test(S("abcdeabcdeabcdeabcde"), "abcde", 19, 2, 15); + test(S("abcdeabcdeabcdeabcde"), "abcde", 19, 4, 15); + test(S("abcdeabcdeabcdeabcde"), "abcde", 19, 5, 15); + test(S("abcdeabcdeabcdeabcde"), "abcdeabcde", 19, 0, 19); + test(S("abcdeabcdeabcdeabcde"), "abcdeabcde", 19, 1, 15); + test(S("abcdeabcdeabcdeabcde"), "abcdeabcde", 19, 5, 15); + test(S("abcdeabcdeabcdeabcde"), "abcdeabcde", 19, 9, 10); + test(S("abcdeabcdeabcdeabcde"), "abcdeabcde", 19, 10, 10); + test(S("abcdeabcdeabcdeabcde"), "abcdeabcdeabcdeabcde", 19, 0, 19); + test(S("abcdeabcdeabcdeabcde"), "abcdeabcdeabcdeabcde", 19, 1, 15); + test(S("abcdeabcdeabcdeabcde"), "abcdeabcdeabcdeabcde", 19, 10, 10); + test(S("abcdeabcdeabcdeabcde"), "abcdeabcdeabcdeabcde", 19, 19, 0); + test(S("abcdeabcdeabcdeabcde"), "abcdeabcdeabcdeabcde", 19, 20, 0); + test(S("abcdeabcdeabcdeabcde"), "", 20, 0, 20); + test(S("abcdeabcdeabcdeabcde"), "abcde", 20, 0, 20); + test(S("abcdeabcdeabcdeabcde"), "abcde", 20, 1, 15); + test(S("abcdeabcdeabcdeabcde"), "abcde", 20, 2, 15); + test(S("abcdeabcdeabcdeabcde"), "abcde", 20, 4, 15); + test(S("abcdeabcdeabcdeabcde"), "abcde", 20, 5, 15); + test(S("abcdeabcdeabcdeabcde"), "abcdeabcde", 20, 0, 20); + test(S("abcdeabcdeabcdeabcde"), "abcdeabcde", 20, 1, 15); + test(S("abcdeabcdeabcdeabcde"), "abcdeabcde", 20, 5, 15); + test(S("abcdeabcdeabcdeabcde"), "abcdeabcde", 20, 9, 10); + test(S("abcdeabcdeabcdeabcde"), "abcdeabcde", 20, 10, 10); + test(S("abcdeabcdeabcdeabcde"), "abcdeabcdeabcdeabcde", 20, 0, 20); +} + +template +void test3() +{ + test(S("abcdeabcdeabcdeabcde"), "abcdeabcdeabcdeabcde", 20, 1, 15); + test(S("abcdeabcdeabcdeabcde"), "abcdeabcdeabcdeabcde", 20, 10, 10); + test(S("abcdeabcdeabcdeabcde"), "abcdeabcdeabcdeabcde", 20, 19, 0); + test(S("abcdeabcdeabcdeabcde"), "abcdeabcdeabcdeabcde", 20, 20, 0); + test(S("abcdeabcdeabcdeabcde"), "", 21, 0, 20); + test(S("abcdeabcdeabcdeabcde"), "abcde", 21, 0, 20); + test(S("abcdeabcdeabcdeabcde"), "abcde", 21, 1, 15); + test(S("abcdeabcdeabcdeabcde"), "abcde", 21, 2, 15); + test(S("abcdeabcdeabcdeabcde"), "abcde", 21, 4, 15); + test(S("abcdeabcdeabcdeabcde"), "abcde", 21, 5, 15); + test(S("abcdeabcdeabcdeabcde"), "abcdeabcde", 21, 0, 20); + test(S("abcdeabcdeabcdeabcde"), "abcdeabcde", 21, 1, 15); + test(S("abcdeabcdeabcdeabcde"), "abcdeabcde", 21, 5, 15); + test(S("abcdeabcdeabcdeabcde"), "abcdeabcde", 21, 9, 10); + test(S("abcdeabcdeabcdeabcde"), "abcdeabcde", 21, 10, 10); + test(S("abcdeabcdeabcdeabcde"), "abcdeabcdeabcdeabcde", 21, 0, 20); + test(S("abcdeabcdeabcdeabcde"), "abcdeabcdeabcdeabcde", 21, 1, 15); + test(S("abcdeabcdeabcdeabcde"), "abcdeabcdeabcdeabcde", 21, 10, 10); + test(S("abcdeabcdeabcdeabcde"), "abcdeabcdeabcdeabcde", 21, 19, 0); + test(S("abcdeabcdeabcdeabcde"), "abcdeabcdeabcdeabcde", 21, 20, 0); +} + +int main() +{ + { + typedef std::string S; + test0(); + test1(); + test2(); + test3(); + } +#if TEST_STD_VER >= 11 + { + typedef std::basic_string, min_allocator> S; + test0(); + test1(); + test2(); + test3(); + } +#endif +} diff --git a/tests/external/libcxx/basic_string/string.ops/string_rfind/string_size.pass.cpp b/tests/external/libcxx/basic_string/string.ops/string_rfind/string_size.pass.cpp new file mode 100644 index 0000000..d7908ad --- /dev/null +++ b/tests/external/libcxx/basic_string/string.ops/string_rfind/string_size.pass.cpp @@ -0,0 +1,165 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// + +// size_type rfind(const basic_string& str, size_type pos = npos) const; + +#include +#include + +#include "test_macros.h" +#include "min_allocator.h" + +template +void +test(const S& s, const S& str, typename S::size_type pos, typename S::size_type x) +{ + assert(s.rfind(str, pos) == x); + if (x != S::npos) + assert(x <= pos && x + str.size() <= s.size()); +} + +template +void +test(const S& s, const S& str, typename S::size_type x) +{ + assert(s.rfind(str) == x); + if (x != S::npos) + assert(0 <= x && x + str.size() <= s.size()); +} + +template +void test0() +{ + test(S(""), S(""), 0, 0); + test(S(""), S("abcde"), 0, S::npos); + test(S(""), S("abcdeabcde"), 0, S::npos); + test(S(""), S("abcdeabcdeabcdeabcde"), 0, S::npos); + test(S(""), S(""), 1, 0); + test(S(""), S("abcde"), 1, S::npos); + test(S(""), S("abcdeabcde"), 1, S::npos); + test(S(""), S("abcdeabcdeabcdeabcde"), 1, S::npos); + test(S("abcde"), S(""), 0, 0); + test(S("abcde"), S("abcde"), 0, 0); + test(S("abcde"), S("abcdeabcde"), 0, S::npos); + test(S("abcde"), S("abcdeabcdeabcdeabcde"), 0, S::npos); + test(S("abcde"), S(""), 1, 1); + test(S("abcde"), S("abcde"), 1, 0); + test(S("abcde"), S("abcdeabcde"), 1, S::npos); + test(S("abcde"), S("abcdeabcdeabcdeabcde"), 1, S::npos); + test(S("abcde"), S(""), 2, 2); + test(S("abcde"), S("abcde"), 2, 0); + test(S("abcde"), S("abcdeabcde"), 2, S::npos); + test(S("abcde"), S("abcdeabcdeabcdeabcde"), 2, S::npos); + test(S("abcde"), S(""), 4, 4); + test(S("abcde"), S("abcde"), 4, 0); + test(S("abcde"), S("abcdeabcde"), 4, S::npos); + test(S("abcde"), S("abcdeabcdeabcdeabcde"), 4, S::npos); + test(S("abcde"), S(""), 5, 5); + test(S("abcde"), S("abcde"), 5, 0); + test(S("abcde"), S("abcdeabcde"), 5, S::npos); + test(S("abcde"), S("abcdeabcdeabcdeabcde"), 5, S::npos); + test(S("abcde"), S(""), 6, 5); + test(S("abcde"), S("abcde"), 6, 0); + test(S("abcde"), S("abcdeabcde"), 6, S::npos); + test(S("abcde"), S("abcdeabcdeabcdeabcde"), 6, S::npos); + test(S("abcdeabcde"), S(""), 0, 0); + test(S("abcdeabcde"), S("abcde"), 0, 0); + test(S("abcdeabcde"), S("abcdeabcde"), 0, 0); + test(S("abcdeabcde"), S("abcdeabcdeabcdeabcde"), 0, S::npos); + test(S("abcdeabcde"), S(""), 1, 1); + test(S("abcdeabcde"), S("abcde"), 1, 0); + test(S("abcdeabcde"), S("abcdeabcde"), 1, 0); + test(S("abcdeabcde"), S("abcdeabcdeabcdeabcde"), 1, S::npos); + test(S("abcdeabcde"), S(""), 5, 5); + test(S("abcdeabcde"), S("abcde"), 5, 5); + test(S("abcdeabcde"), S("abcdeabcde"), 5, 0); + test(S("abcdeabcde"), S("abcdeabcdeabcdeabcde"), 5, S::npos); + test(S("abcdeabcde"), S(""), 9, 9); + test(S("abcdeabcde"), S("abcde"), 9, 5); + test(S("abcdeabcde"), S("abcdeabcde"), 9, 0); + test(S("abcdeabcde"), S("abcdeabcdeabcdeabcde"), 9, S::npos); + test(S("abcdeabcde"), S(""), 10, 10); + test(S("abcdeabcde"), S("abcde"), 10, 5); + test(S("abcdeabcde"), S("abcdeabcde"), 10, 0); + test(S("abcdeabcde"), S("abcdeabcdeabcdeabcde"), 10, S::npos); + test(S("abcdeabcde"), S(""), 11, 10); + test(S("abcdeabcde"), S("abcde"), 11, 5); + test(S("abcdeabcde"), S("abcdeabcde"), 11, 0); + test(S("abcdeabcde"), S("abcdeabcdeabcdeabcde"), 11, S::npos); + test(S("abcdeabcdeabcdeabcde"), S(""), 0, 0); + test(S("abcdeabcdeabcdeabcde"), S("abcde"), 0, 0); + test(S("abcdeabcdeabcdeabcde"), S("abcdeabcde"), 0, 0); + test(S("abcdeabcdeabcdeabcde"), S("abcdeabcdeabcdeabcde"), 0, 0); + test(S("abcdeabcdeabcdeabcde"), S(""), 1, 1); + test(S("abcdeabcdeabcdeabcde"), S("abcde"), 1, 0); + test(S("abcdeabcdeabcdeabcde"), S("abcdeabcde"), 1, 0); + test(S("abcdeabcdeabcdeabcde"), S("abcdeabcdeabcdeabcde"), 1, 0); + test(S("abcdeabcdeabcdeabcde"), S(""), 10, 10); + test(S("abcdeabcdeabcdeabcde"), S("abcde"), 10, 10); + test(S("abcdeabcdeabcdeabcde"), S("abcdeabcde"), 10, 10); + test(S("abcdeabcdeabcdeabcde"), S("abcdeabcdeabcdeabcde"), 10, 0); + test(S("abcdeabcdeabcdeabcde"), S(""), 19, 19); + test(S("abcdeabcdeabcdeabcde"), S("abcde"), 19, 15); + test(S("abcdeabcdeabcdeabcde"), S("abcdeabcde"), 19, 10); + test(S("abcdeabcdeabcdeabcde"), S("abcdeabcdeabcdeabcde"), 19, 0); + test(S("abcdeabcdeabcdeabcde"), S(""), 20, 20); + test(S("abcdeabcdeabcdeabcde"), S("abcde"), 20, 15); + test(S("abcdeabcdeabcdeabcde"), S("abcdeabcde"), 20, 10); + test(S("abcdeabcdeabcdeabcde"), S("abcdeabcdeabcdeabcde"), 20, 0); + test(S("abcdeabcdeabcdeabcde"), S(""), 21, 20); + test(S("abcdeabcdeabcdeabcde"), S("abcde"), 21, 15); + test(S("abcdeabcdeabcdeabcde"), S("abcdeabcde"), 21, 10); + test(S("abcdeabcdeabcdeabcde"), S("abcdeabcdeabcdeabcde"), 21, 0); +} + +template +void test1() +{ + test(S(""), S(""), 0); + test(S(""), S("abcde"), S::npos); + test(S(""), S("abcdeabcde"), S::npos); + test(S(""), S("abcdeabcdeabcdeabcde"), S::npos); + test(S("abcde"), S(""), 5); + test(S("abcde"), S("abcde"), 0); + test(S("abcde"), S("abcdeabcde"), S::npos); + test(S("abcde"), S("abcdeabcdeabcdeabcde"), S::npos); + test(S("abcdeabcde"), S(""), 10); + test(S("abcdeabcde"), S("abcde"), 5); + test(S("abcdeabcde"), S("abcdeabcde"), 0); + test(S("abcdeabcde"), S("abcdeabcdeabcdeabcde"), S::npos); + test(S("abcdeabcdeabcdeabcde"), S(""), 20); + test(S("abcdeabcdeabcdeabcde"), S("abcde"), 15); + test(S("abcdeabcdeabcdeabcde"), S("abcdeabcde"), 10); + test(S("abcdeabcdeabcdeabcde"), S("abcdeabcdeabcdeabcde"), 0); +} + +int main() +{ + { + typedef std::string S; + test0(); + test1(); + } +#if TEST_STD_VER >= 11 + { + typedef std::basic_string, min_allocator> S; + test0(); + test1(); + } +#endif + +#if TEST_STD_VER > 3 + { // LWG 2946 + std::string s = " !"; + assert(s.rfind({"abc", 1}) == std::string::npos); + } +#endif +} diff --git a/tests/external/libcxx/basic_string/string.ops/string_rfind/string_view_size.pass.cpp b/tests/external/libcxx/basic_string/string.ops/string_rfind/string_view_size.pass.cpp new file mode 100644 index 0000000..230c455 --- /dev/null +++ b/tests/external/libcxx/basic_string/string.ops/string_rfind/string_view_size.pass.cpp @@ -0,0 +1,159 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// + +// size_type rfind(basic_string_view sv, size_type pos = npos) const; + +#include +#include + +#include "min_allocator.h" + +template +void +test(const S& s, SV sv, typename S::size_type pos, typename S::size_type x) +{ + assert(s.rfind(sv, pos) == x); + if (x != S::npos) + assert(x <= pos && x + sv.size() <= s.size()); +} + +template +void +test(const S& s, SV sv, typename S::size_type x) +{ + assert(s.rfind(sv) == x); + if (x != S::npos) + assert(0 <= x && x + sv.size() <= s.size()); +} + +template +void test0() +{ + test(S(""), SV(""), 0, 0); + test(S(""), SV("abcde"), 0, S::npos); + test(S(""), SV("abcdeabcde"), 0, S::npos); + test(S(""), SV("abcdeabcdeabcdeabcde"), 0, S::npos); + test(S(""), SV(""), 1, 0); + test(S(""), SV("abcde"), 1, S::npos); + test(S(""), SV("abcdeabcde"), 1, S::npos); + test(S(""), SV("abcdeabcdeabcdeabcde"), 1, S::npos); + test(S("abcde"), SV(""), 0, 0); + test(S("abcde"), SV("abcde"), 0, 0); + test(S("abcde"), SV("abcdeabcde"), 0, S::npos); + test(S("abcde"), SV("abcdeabcdeabcdeabcde"), 0, S::npos); + test(S("abcde"), SV(""), 1, 1); + test(S("abcde"), SV("abcde"), 1, 0); + test(S("abcde"), SV("abcdeabcde"), 1, S::npos); + test(S("abcde"), SV("abcdeabcdeabcdeabcde"), 1, S::npos); + test(S("abcde"), SV(""), 2, 2); + test(S("abcde"), SV("abcde"), 2, 0); + test(S("abcde"), SV("abcdeabcde"), 2, S::npos); + test(S("abcde"), SV("abcdeabcdeabcdeabcde"), 2, S::npos); + test(S("abcde"), SV(""), 4, 4); + test(S("abcde"), SV("abcde"), 4, 0); + test(S("abcde"), SV("abcdeabcde"), 4, S::npos); + test(S("abcde"), SV("abcdeabcdeabcdeabcde"), 4, S::npos); + test(S("abcde"), SV(""), 5, 5); + test(S("abcde"), SV("abcde"), 5, 0); + test(S("abcde"), SV("abcdeabcde"), 5, S::npos); + test(S("abcde"), SV("abcdeabcdeabcdeabcde"), 5, S::npos); + test(S("abcde"), SV(""), 6, 5); + test(S("abcde"), SV("abcde"), 6, 0); + test(S("abcde"), SV("abcdeabcde"), 6, S::npos); + test(S("abcde"), SV("abcdeabcdeabcdeabcde"), 6, S::npos); + test(S("abcdeabcde"), SV(""), 0, 0); + test(S("abcdeabcde"), SV("abcde"), 0, 0); + test(S("abcdeabcde"), SV("abcdeabcde"), 0, 0); + test(S("abcdeabcde"), SV("abcdeabcdeabcdeabcde"), 0, S::npos); + test(S("abcdeabcde"), SV(""), 1, 1); + test(S("abcdeabcde"), SV("abcde"), 1, 0); + test(S("abcdeabcde"), SV("abcdeabcde"), 1, 0); + test(S("abcdeabcde"), SV("abcdeabcdeabcdeabcde"), 1, S::npos); + test(S("abcdeabcde"), SV(""), 5, 5); + test(S("abcdeabcde"), SV("abcde"), 5, 5); + test(S("abcdeabcde"), SV("abcdeabcde"), 5, 0); + test(S("abcdeabcde"), SV("abcdeabcdeabcdeabcde"), 5, S::npos); + test(S("abcdeabcde"), SV(""), 9, 9); + test(S("abcdeabcde"), SV("abcde"), 9, 5); + test(S("abcdeabcde"), SV("abcdeabcde"), 9, 0); + test(S("abcdeabcde"), SV("abcdeabcdeabcdeabcde"), 9, S::npos); + test(S("abcdeabcde"), SV(""), 10, 10); + test(S("abcdeabcde"), SV("abcde"), 10, 5); + test(S("abcdeabcde"), SV("abcdeabcde"), 10, 0); + test(S("abcdeabcde"), SV("abcdeabcdeabcdeabcde"), 10, S::npos); + test(S("abcdeabcde"), SV(""), 11, 10); + test(S("abcdeabcde"), SV("abcde"), 11, 5); + test(S("abcdeabcde"), SV("abcdeabcde"), 11, 0); + test(S("abcdeabcde"), SV("abcdeabcdeabcdeabcde"), 11, S::npos); + test(S("abcdeabcdeabcdeabcde"), SV(""), 0, 0); + test(S("abcdeabcdeabcdeabcde"), SV("abcde"), 0, 0); + test(S("abcdeabcdeabcdeabcde"), SV("abcdeabcde"), 0, 0); + test(S("abcdeabcdeabcdeabcde"), SV("abcdeabcdeabcdeabcde"), 0, 0); + test(S("abcdeabcdeabcdeabcde"), SV(""), 1, 1); + test(S("abcdeabcdeabcdeabcde"), SV("abcde"), 1, 0); + test(S("abcdeabcdeabcdeabcde"), SV("abcdeabcde"), 1, 0); + test(S("abcdeabcdeabcdeabcde"), SV("abcdeabcdeabcdeabcde"), 1, 0); + test(S("abcdeabcdeabcdeabcde"), SV(""), 10, 10); + test(S("abcdeabcdeabcdeabcde"), SV("abcde"), 10, 10); + test(S("abcdeabcdeabcdeabcde"), SV("abcdeabcde"), 10, 10); + test(S("abcdeabcdeabcdeabcde"), SV("abcdeabcdeabcdeabcde"), 10, 0); + test(S("abcdeabcdeabcdeabcde"), SV(""), 19, 19); + test(S("abcdeabcdeabcdeabcde"), SV("abcde"), 19, 15); + test(S("abcdeabcdeabcdeabcde"), SV("abcdeabcde"), 19, 10); + test(S("abcdeabcdeabcdeabcde"), SV("abcdeabcdeabcdeabcde"), 19, 0); + test(S("abcdeabcdeabcdeabcde"), SV(""), 20, 20); + test(S("abcdeabcdeabcdeabcde"), SV("abcde"), 20, 15); + test(S("abcdeabcdeabcdeabcde"), SV("abcdeabcde"), 20, 10); + test(S("abcdeabcdeabcdeabcde"), SV("abcdeabcdeabcdeabcde"), 20, 0); + test(S("abcdeabcdeabcdeabcde"), SV(""), 21, 20); + test(S("abcdeabcdeabcdeabcde"), SV("abcde"), 21, 15); + test(S("abcdeabcdeabcdeabcde"), SV("abcdeabcde"), 21, 10); + test(S("abcdeabcdeabcdeabcde"), SV("abcdeabcdeabcdeabcde"), 21, 0); +} + +template +void test1() +{ + test(S(""), SV(""), 0); + test(S(""), SV("abcde"), S::npos); + test(S(""), SV("abcdeabcde"), S::npos); + test(S(""), SV("abcdeabcdeabcdeabcde"), S::npos); + test(S("abcde"), SV(""), 5); + test(S("abcde"), SV("abcde"), 0); + test(S("abcde"), SV("abcdeabcde"), S::npos); + test(S("abcde"), SV("abcdeabcdeabcdeabcde"), S::npos); + test(S("abcdeabcde"), SV(""), 10); + test(S("abcdeabcde"), SV("abcde"), 5); + test(S("abcdeabcde"), SV("abcdeabcde"), 0); + test(S("abcdeabcde"), SV("abcdeabcdeabcdeabcde"), S::npos); + test(S("abcdeabcdeabcdeabcde"), SV(""), 20); + test(S("abcdeabcdeabcdeabcde"), SV("abcde"), 15); + test(S("abcdeabcdeabcdeabcde"), SV("abcdeabcde"), 10); + test(S("abcdeabcdeabcdeabcde"), SV("abcdeabcdeabcdeabcde"), 0); +} + +int main() +{ + { + typedef std::string S; + typedef std::string_view SV; + test0(); + test1(); + } +#if TEST_STD_VER >= 11 + { + typedef std::basic_string, min_allocator> S; + typedef std::string_view SV; + test0(); + test1(); + } +#endif +} diff --git a/tests/external/libcxx/basic_string/string.ops/string_substr/substr.pass.cpp b/tests/external/libcxx/basic_string/string.ops/string_substr/substr.pass.cpp new file mode 100644 index 0000000..f94739e --- /dev/null +++ b/tests/external/libcxx/basic_string/string.ops/string_substr/substr.pass.cpp @@ -0,0 +1,177 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// + +// basic_string substr(size_type pos = 0, size_type n = npos) const; + +#include +#include +#include +#include + +#include "test_macros.h" +#include "min_allocator.h" + +template +void +test(const S& s, typename S::size_type pos, typename S::size_type n) +{ + if (pos <= s.size()) + { + S str = s.substr(pos, n); + LIBCPP_ASSERT(str.__invariants()); + assert(pos <= s.size()); + typename S::size_type rlen = std::min(n, s.size() - pos); + assert(str.size() == rlen); + assert(S::traits_type::compare(s.data()+pos, str.data(), rlen) == 0); + } +#ifndef TEST_HAS_NO_EXCEPTIONS + else + { + try + { + S str = s.substr(pos, n); + assert(false); + } + catch (std::out_of_range&) + { + assert(pos > s.size()); + } + } +#endif +} + +int main() +{ + { + typedef std::string S; + test(S(""), 0, 0); + test(S(""), 1, 0); + test(S("pniot"), 0, 0); + test(S("htaob"), 0, 1); + test(S("fodgq"), 0, 2); + test(S("hpqia"), 0, 4); + test(S("qanej"), 0, 5); + test(S("dfkap"), 1, 0); + test(S("clbao"), 1, 1); + test(S("ihqrf"), 1, 2); + test(S("mekdn"), 1, 3); + test(S("ngtjf"), 1, 4); + test(S("srdfq"), 2, 0); + test(S("qkdrs"), 2, 1); + test(S("ikcrq"), 2, 2); + test(S("cdaih"), 2, 3); + test(S("dmajb"), 4, 0); + test(S("karth"), 4, 1); + test(S("lhcdo"), 5, 0); + test(S("acbsj"), 6, 0); + test(S("pbsjikaole"), 0, 0); + test(S("pcbahntsje"), 0, 1); + test(S("mprdjbeiak"), 0, 5); + test(S("fhepcrntko"), 0, 9); + test(S("eqmpaidtls"), 0, 10); + test(S("joidhalcmq"), 1, 0); + test(S("omigsphflj"), 1, 1); + test(S("kocgbphfji"), 1, 4); + test(S("onmjekafbi"), 1, 8); + test(S("fbslrjiqkm"), 1, 9); + test(S("oqmrjahnkg"), 5, 0); + test(S("jeidpcmalh"), 5, 1); + test(S("schfalibje"), 5, 2); + test(S("crliponbqe"), 5, 4); + test(S("igdscopqtm"), 5, 5); + test(S("qngpdkimlc"), 9, 0); + test(S("thdjgafrlb"), 9, 1); + test(S("hcjitbfapl"), 10, 0); + test(S("mgojkldsqh"), 11, 0); + test(S("gfshlcmdjreqipbontak"), 0, 0); + test(S("nadkhpfemgclosibtjrq"), 0, 1); + test(S("nkodajteqplrbifhmcgs"), 0, 10); + test(S("ofdrqmkeblthacpgijsn"), 0, 19); + test(S("gbmetiprqdoasckjfhln"), 0, 20); + test(S("bdfjqgatlksriohemnpc"), 1, 0); + test(S("crnklpmegdqfiashtojb"), 1, 1); + test(S("ejqcnahdrkfsmptilgbo"), 1, 9); + test(S("jsbtafedocnirgpmkhql"), 1, 18); + test(S("prqgnlbaejsmkhdctoif"), 1, 19); + test(S("qnmodrtkebhpasifgcjl"), 10, 0); + test(S("pejafmnokrqhtisbcdgl"), 10, 1); + test(S("cpebqsfmnjdolhkratgi"), 10, 5); + test(S("odnqkgijrhabfmcestlp"), 10, 9); + test(S("lmofqdhpkibagnrcjste"), 10, 10); + test(S("lgjqketopbfahrmnsicd"), 19, 0); + test(S("ktsrmnqagdecfhijpobl"), 19, 1); + test(S("lsaijeqhtrbgcdmpfkno"), 20, 0); + test(S("dplqartnfgejichmoskb"), 21, 0); + } +#if TEST_STD_VER >= 11 + { + typedef std::basic_string, min_allocator> S; + test(S(""), 0, 0); + test(S(""), 1, 0); + test(S("pniot"), 0, 0); + test(S("htaob"), 0, 1); + test(S("fodgq"), 0, 2); + test(S("hpqia"), 0, 4); + test(S("qanej"), 0, 5); + test(S("dfkap"), 1, 0); + test(S("clbao"), 1, 1); + test(S("ihqrf"), 1, 2); + test(S("mekdn"), 1, 3); + test(S("ngtjf"), 1, 4); + test(S("srdfq"), 2, 0); + test(S("qkdrs"), 2, 1); + test(S("ikcrq"), 2, 2); + test(S("cdaih"), 2, 3); + test(S("dmajb"), 4, 0); + test(S("karth"), 4, 1); + test(S("lhcdo"), 5, 0); + test(S("acbsj"), 6, 0); + test(S("pbsjikaole"), 0, 0); + test(S("pcbahntsje"), 0, 1); + test(S("mprdjbeiak"), 0, 5); + test(S("fhepcrntko"), 0, 9); + test(S("eqmpaidtls"), 0, 10); + test(S("joidhalcmq"), 1, 0); + test(S("omigsphflj"), 1, 1); + test(S("kocgbphfji"), 1, 4); + test(S("onmjekafbi"), 1, 8); + test(S("fbslrjiqkm"), 1, 9); + test(S("oqmrjahnkg"), 5, 0); + test(S("jeidpcmalh"), 5, 1); + test(S("schfalibje"), 5, 2); + test(S("crliponbqe"), 5, 4); + test(S("igdscopqtm"), 5, 5); + test(S("qngpdkimlc"), 9, 0); + test(S("thdjgafrlb"), 9, 1); + test(S("hcjitbfapl"), 10, 0); + test(S("mgojkldsqh"), 11, 0); + test(S("gfshlcmdjreqipbontak"), 0, 0); + test(S("nadkhpfemgclosibtjrq"), 0, 1); + test(S("nkodajteqplrbifhmcgs"), 0, 10); + test(S("ofdrqmkeblthacpgijsn"), 0, 19); + test(S("gbmetiprqdoasckjfhln"), 0, 20); + test(S("bdfjqgatlksriohemnpc"), 1, 0); + test(S("crnklpmegdqfiashtojb"), 1, 1); + test(S("ejqcnahdrkfsmptilgbo"), 1, 9); + test(S("jsbtafedocnirgpmkhql"), 1, 18); + test(S("prqgnlbaejsmkhdctoif"), 1, 19); + test(S("qnmodrtkebhpasifgcjl"), 10, 0); + test(S("pejafmnokrqhtisbcdgl"), 10, 1); + test(S("cpebqsfmnjdolhkratgi"), 10, 5); + test(S("odnqkgijrhabfmcestlp"), 10, 9); + test(S("lmofqdhpkibagnrcjste"), 10, 10); + test(S("lgjqketopbfahrmnsicd"), 19, 0); + test(S("ktsrmnqagdecfhijpobl"), 19, 1); + test(S("lsaijeqhtrbgcdmpfkno"), 20, 0); + test(S("dplqartnfgejichmoskb"), 21, 0); + } +#endif +} diff --git a/tests/external/libcxx/basic_string/string.require/contiguous.pass.cpp b/tests/external/libcxx/basic_string/string.require/contiguous.pass.cpp new file mode 100644 index 0000000..1cc8e96 --- /dev/null +++ b/tests/external/libcxx/basic_string/string.require/contiguous.pass.cpp @@ -0,0 +1,53 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// + +// An string is a contiguous container + +#include +#include + +#include "test_allocator.h" +#include "min_allocator.h" + + +template +void test_contiguous ( const C &c ) +{ + for ( size_t i = 0; i < c.size(); ++i ) + assert ( *(c.begin() + static_cast(i)) == *(std::addressof(*c.begin()) + i)); +} + +int main() +{ + { + typedef std::string S; + test_contiguous(S()); + test_contiguous(S("1")); + test_contiguous(S("1234567890123456789012345678901234567890123456789012345678901234567890")); + } + + { + typedef test_allocator A; + typedef std::basic_string, A> S; + test_contiguous(S(A(3))); + test_contiguous(S("1", A(5))); + test_contiguous(S("1234567890123456789012345678901234567890123456789012345678901234567890", A(7))); + } +#if TEST_STD_VER >= 11 + { + typedef min_allocator A; + typedef std::basic_string, A> S; + test_contiguous(S(A{})); + test_contiguous(S("1", A())); + test_contiguous(S("1234567890123456789012345678901234567890123456789012345678901234567890", A())); + } +#endif +} diff --git a/tests/external/libcxx/basic_string/string.starts_with/starts_with.char.pass.cpp b/tests/external/libcxx/basic_string/string.starts_with/starts_with.char.pass.cpp new file mode 100644 index 0000000..4be35a7 --- /dev/null +++ b/tests/external/libcxx/basic_string/string.starts_with/starts_with.char.pass.cpp @@ -0,0 +1,34 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// UNSUPPORTED: c++98, c++03, c++11, c++14, c++17 + +// + +// bool starts_with(charT x) const noexcept; + +#include +#include + +#include "test_macros.h" + +int main() +{ + { + typedef std::string S; + S s1 {}; + S s2 { "abcde", 5 }; + + ASSERT_NOEXCEPT(s1.starts_with('e')); + + assert (!s1.starts_with('a')); + assert (!s1.starts_with('x')); + assert ( s2.starts_with('a')); + assert (!s2.starts_with('x')); + } +} diff --git a/tests/external/libcxx/basic_string/string.starts_with/starts_with.ptr.pass.cpp b/tests/external/libcxx/basic_string/string.starts_with/starts_with.ptr.pass.cpp new file mode 100644 index 0000000..5dec215 --- /dev/null +++ b/tests/external/libcxx/basic_string/string.starts_with/starts_with.ptr.pass.cpp @@ -0,0 +1,62 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// UNSUPPORTED: c++98, c++03, c++11, c++14, c++17 + +// + +// bool starts_with(const CharT *x) const; + +#include +#include + +#include "test_macros.h" + +int main() +{ + { + typedef std::string S; + const char *s = "abcde"; + S s0 {}; + S s1 { s, 1 }; + S s2 { s, 2 }; +// S s3 { s, 3 }; +// S s4 { s, 4 }; +// S s5 { s, 5 }; + S sNot {"def", 3 }; + + LIBCPP_ASSERT_NOEXCEPT(s0.starts_with("")); + + assert ( s0.starts_with("")); + assert (!s0.starts_with("a")); + + assert ( s1.starts_with("")); + assert ( s1.starts_with("a")); + assert (!s1.starts_with("ab")); + assert (!s1.starts_with("abc")); + assert (!s1.starts_with("abcd")); + assert (!s1.starts_with("abcde")); + assert (!s1.starts_with("def")); + + assert ( s2.starts_with("")); + assert ( s2.starts_with("a")); + assert ( s2.starts_with("ab")); + assert (!s2.starts_with("abc")); + assert (!s2.starts_with("abcd")); + assert (!s2.starts_with("abcde")); + assert (!s2.starts_with("def")); + + assert ( sNot.starts_with("")); + assert (!sNot.starts_with("a")); + assert (!sNot.starts_with("ab")); + assert (!sNot.starts_with("abc")); + assert (!sNot.starts_with("abcd")); + assert (!sNot.starts_with("abcde")); + assert ( sNot.starts_with("def")); + } +} diff --git a/tests/external/libcxx/basic_string/string.starts_with/starts_with.string_view.pass.cpp b/tests/external/libcxx/basic_string/string.starts_with/starts_with.string_view.pass.cpp new file mode 100644 index 0000000..d542d3d --- /dev/null +++ b/tests/external/libcxx/basic_string/string.starts_with/starts_with.string_view.pass.cpp @@ -0,0 +1,72 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// UNSUPPORTED: c++98, c++03, c++11, c++14, c++17 + +// + +// bool starts_with(string_view x) const noexcept; + +#include +#include + +#include "test_macros.h" + +int main() +{ + { + typedef std::string S; + typedef std::string_view SV; + const char *s = "abcde"; + + S s0; + S s1 { s, 1 }; + S s2 { s, 2 }; +// S s3 { s, 3 }; +// S s4 { s, 4 }; +// S s5 { s, 5 }; + S sNot { "def", 3 }; + + SV sv0; + SV sv1 { s, 1 }; + SV sv2 { s, 2 }; + SV sv3 { s, 3 }; + SV sv4 { s, 4 }; + SV sv5 { s, 5 }; + SV svNot {"def", 3 }; + + ASSERT_NOEXCEPT(s0.starts_with(sv0)); + + assert ( s0.starts_with(sv0)); + assert (!s0.starts_with(sv1)); + + assert ( s1.starts_with(sv0)); + assert ( s1.starts_with(sv1)); + assert (!s1.starts_with(sv2)); + assert (!s1.starts_with(sv3)); + assert (!s1.starts_with(sv4)); + assert (!s1.starts_with(sv5)); + assert (!s1.starts_with(svNot)); + + assert ( s2.starts_with(sv0)); + assert ( s2.starts_with(sv1)); + assert ( s2.starts_with(sv2)); + assert (!s2.starts_with(sv3)); + assert (!s2.starts_with(sv4)); + assert (!s2.starts_with(sv5)); + assert (!s2.starts_with(svNot)); + + assert ( sNot.starts_with(sv0)); + assert (!sNot.starts_with(sv1)); + assert (!sNot.starts_with(sv2)); + assert (!sNot.starts_with(sv3)); + assert (!sNot.starts_with(sv4)); + assert (!sNot.starts_with(sv5)); + assert ( sNot.starts_with(svNot)); + } +} diff --git a/tests/external/libcxx/basic_string/test_traits.h b/tests/external/libcxx/basic_string/test_traits.h new file mode 100644 index 0000000..f635b1d --- /dev/null +++ b/tests/external/libcxx/basic_string/test_traits.h @@ -0,0 +1,19 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#ifndef TEST_TRAITS_H +#define TEST_TRAITS_H + +template +struct test_traits +{ + typedef charT char_type; +}; + +#endif // TEST_TRAITS_H diff --git a/tests/external/libcxx/basic_string/traits_mismatch.fail.cpp b/tests/external/libcxx/basic_string/traits_mismatch.fail.cpp new file mode 100644 index 0000000..1d54238 --- /dev/null +++ b/tests/external/libcxx/basic_string/traits_mismatch.fail.cpp @@ -0,0 +1,18 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// +// The strings's value type must be the same as the traits's char_type + +#include + +int main() +{ + std::basic_string> s; +} diff --git a/tests/external/libcxx/basic_string/types.pass.cpp b/tests/external/libcxx/basic_string/types.pass.cpp new file mode 100644 index 0000000..a6832a1 --- /dev/null +++ b/tests/external/libcxx/basic_string/types.pass.cpp @@ -0,0 +1,85 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// + +// Test nested types and default template args: + +// template, +// class Allocator = allocator > +// { +// public: +// // types: +// typedef traits traits_type; +// typedef typename traits::char_type value_type; +// typedef Allocator allocator_type; +// typedef typename Allocator::size_type size_type; +// typedef typename Allocator::difference_type difference_type; +// typedef typename Allocator::reference reference; +// typedef typename Allocator::const_reference const_reference; +// typedef typename Allocator::pointer pointer; +// typedef typename Allocator::const_pointer const_pointer; +// typedef implementation-defined iterator; // See 23.1 +// typedef implementation-defined const_iterator; // See 23.1 +// typedef std::reverse_iterator reverse_iterator; +// typedef std::reverse_iterator const_reverse_iterator; +// static const size_type npos = -1; +// }; + +#include +#include +#include + +#include "test_traits.h" +#include "test_allocator.h" +#include "min_allocator.h" + +template +void +test() +{ + typedef std::basic_string S; + + static_assert((std::is_same::value), ""); + static_assert((std::is_same::value), ""); + static_assert((std::is_same::value), ""); + static_assert((std::is_same::value), ""); + static_assert((std::is_same::size_type>::value), ""); + static_assert((std::is_same::difference_type>::value), ""); + static_assert((std::is_same::value), ""); + static_assert((std::is_same::value), ""); + static_assert((std::is_same::pointer>::value), ""); + static_assert((std::is_same::const_pointer>::value), ""); + static_assert((std::is_same< + typename std::iterator_traits::iterator_category, + std::random_access_iterator_tag>::value), ""); + static_assert((std::is_same< + typename std::iterator_traits::iterator_category, + std::random_access_iterator_tag>::value), ""); + static_assert((std::is_same< + typename S::reverse_iterator, + std::reverse_iterator >::value), ""); + static_assert((std::is_same< + typename S::const_reverse_iterator, + std::reverse_iterator >::value), ""); + static_assert(S::npos == -1, ""); +} + +int main() +{ + test, test_allocator >(); + test, std::allocator >(); + static_assert((std::is_same::traits_type, + std::char_traits >::value), ""); + static_assert((std::is_same::allocator_type, + std::allocator >::value), ""); +#if TEST_STD_VER >= 11 + test, min_allocator >(); +#endif +} diff --git a/tests/external/libcxx/vector/contiguous.pass.cpp b/tests/external/libcxx/vector/contiguous.pass.cpp new file mode 100644 index 0000000..0d4610c --- /dev/null +++ b/tests/external/libcxx/vector/contiguous.pass.cpp @@ -0,0 +1,74 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// Copyright 2019, Intel Corporation +// +// Modified to test pmem::obj containers +// + +#include "unittest.hpp" + +#include +#include + +namespace nvobj = pmem::obj; +namespace pmem_exp = nvobj::experimental; + +using vector_type = pmem_exp::vector; + +struct root { + nvobj::persistent_ptr v1; + nvobj::persistent_ptr v2; +}; + +void +test_contiguous(const vector_type &c) +{ + for (size_t i = 0; i < c.size(); ++i) + UT_ASSERT(*(c.begin() + + static_cast( + i)) == *(std::addressof(*c.begin()) + i)); +} + +int +main(int argc, char *argv[]) +{ + START(); + + if (argc < 2) { + std::cerr << "usage: " << argv[0] << " file-name" << std::endl; + return 1; + } + + auto path = argv[1]; + auto pop = + nvobj::pool::create(path, "VectorTest: contiguous.pass", + PMEMOBJ_MIN_POOL, S_IWUSR | S_IRUSR); + + auto r = pop.root(); + + try { + nvobj::transaction::run(pop, [&] { + r->v1 = nvobj::make_persistent(); + r->v2 = nvobj::make_persistent(3U, 5); + + test_contiguous(*r->v1); + test_contiguous(*r->v2); + + nvobj::delete_persistent(r->v1); + nvobj::delete_persistent(r->v2); + }); + } catch (std::exception &e) { + UT_FATALexc(e); + } + + pop.close(); + + return 0; +} diff --git a/tests/external/libcxx/vector/iterators.pass.cpp b/tests/external/libcxx/vector/iterators.pass.cpp new file mode 100644 index 0000000..c925b56 --- /dev/null +++ b/tests/external/libcxx/vector/iterators.pass.cpp @@ -0,0 +1,124 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// Copyright 2019, Intel Corporation +// +// Modified to test pmem::obj containers +// + +#include "unittest.hpp" + +#include +#include + +namespace nvobj = pmem::obj; +namespace pmem_exp = nvobj::experimental; +using vector_type = pmem_exp::vector; + +struct root { + nvobj::persistent_ptr v_pptr; +}; + +int +main(int argc, char *argv[]) +{ + START(); + + if (argc < 2) { + std::cerr << "usage: " << argv[0] << " file-name" << std::endl; + return 1; + } + + auto path = argv[1]; + auto pop = + nvobj::pool::create(path, "VectorTest: iterators.pass", + PMEMOBJ_MIN_POOL, S_IWUSR | S_IRUSR); + + auto r = pop.root(); + + try { + nvobj::transaction::run(pop, [&] { + r->v_pptr = nvobj::make_persistent(); + { + vector_type::iterator i = r->v_pptr->begin(); + vector_type::iterator j = r->v_pptr->end(); + UT_ASSERT(std::distance(i, j) == 0); + UT_ASSERT(i == j); + } + { + vector_type::const_iterator i = + r->v_pptr->begin(); + vector_type::const_iterator j = + r->v_pptr->end(); + UT_ASSERT(std::distance(i, j) == 0); + UT_ASSERT(i == j); + } + { + vector_type::const_iterator i = + r->v_pptr->cbegin(); + vector_type::const_iterator j = + r->v_pptr->cend(); + UT_ASSERT(std::distance(i, j) == 0); + UT_ASSERT(i == j); + UT_ASSERT(i == r->v_pptr->end()); + } + { + vector_type::iterator i; + vector_type::const_iterator j; + (void)i; + (void)j; + } + nvobj::delete_persistent(r->v_pptr); + + const int a[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9}; + r->v_pptr = nvobj::make_persistent( + std::begin(a), std::end(a)); + + { + vector_type::iterator i = r->v_pptr->begin(); + UT_ASSERT(*i == 0); + ++i; + UT_ASSERT(*i == 1); + *i = 10; + UT_ASSERT(*i == 10); + UT_ASSERT(std::distance(r->v_pptr->begin(), + r->v_pptr->end()) == + 10); + } + { + vector_type::iterator ii1{}, ii2{}; + vector_type::iterator ii4 = ii1; + vector_type::const_iterator cii{}; + UT_ASSERT(ii1 == ii2); + UT_ASSERT(ii1 == ii4); + UT_ASSERT(!(ii1 != ii2)); + UT_ASSERT((ii1 == cii)); + UT_ASSERT((cii == ii1)); + UT_ASSERT(!(ii1 != cii)); + UT_ASSERT(!(cii != ii1)); + UT_ASSERT(!(ii1 < cii)); + UT_ASSERT(!(cii < ii1)); + UT_ASSERT((ii1 <= cii)); + UT_ASSERT((cii <= ii1)); + UT_ASSERT(!(ii1 > cii)); + UT_ASSERT(!(cii > ii1)); + UT_ASSERT((ii1 >= cii)); + UT_ASSERT((cii >= ii1)); + UT_ASSERT(cii - ii1 == 0); + UT_ASSERT(ii1 - cii == 0); + } + }); + } catch (std::exception &e) { + UT_FATALexc(e); + } + + pop.close(); + + return 0; +} diff --git a/tests/external/libcxx/vector/types.pass.cpp b/tests/external/libcxx/vector/types.pass.cpp new file mode 100644 index 0000000..eb3c18d --- /dev/null +++ b/tests/external/libcxx/vector/types.pass.cpp @@ -0,0 +1,82 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// Copyright 2019, Intel Corporation +// +// Modified to test pmem::obj containers +// + +#include "unittest.hpp" + +#include +#include +#include + +template +void +test() +{ + using C = pmem::obj::experimental::vector; + + static_assert(std::is_same::value, ""); + + static_assert(std::is_signed::value, ""); + static_assert(std::is_unsigned::value, ""); + + static_assert( + std::is_same< + typename C::difference_type, + typename std::iterator_traits< + typename C::iterator>::difference_type>::value, + ""); + static_assert(std::is_same:: + difference_type>::value, + ""); + + static_assert( + std::is_same::iterator_category, + std::random_access_iterator_tag>::value, + ""); + static_assert( + std::is_same< + typename std::iterator_traits< + typename C::const_iterator>::iterator_category, + std::random_access_iterator_tag>::value, + ""); + static_assert( + std::is_same< + typename C::reverse_iterator, + std::reverse_iterator>::value, + ""); + static_assert(std::is_same>::value, + ""); + static_assert( + (std::is_same::value), + ""); +} + +int +main() +{ + START(); + + test(); + test(); + + using C = pmem::obj::experimental::vector; + static_assert(std::is_same::value, ""); + static_assert(std::is_same::value, ""); + + return 0; +} diff --git a/tests/external/libcxx/vector/vector.capacity/capacity.pass.cpp b/tests/external/libcxx/vector/vector.capacity/capacity.pass.cpp new file mode 100644 index 0000000..1804968 --- /dev/null +++ b/tests/external/libcxx/vector/vector.capacity/capacity.pass.cpp @@ -0,0 +1,83 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// Copyright 2019, Intel Corporation +// +// Modified to test pmem::obj containers +// + +#include "unittest.hpp" + +#include +#include + +namespace nvobj = pmem::obj; +namespace pmem_exp = nvobj::experimental; + +using C = pmem_exp::vector; + +struct root { + nvobj::persistent_ptr v; +}; + +int +main(int argc, char *argv[]) +{ + START(); + + if (argc < 2) { + std::cerr << "usage: " << argv[0] << " file-name" << std::endl; + return 1; + } + + auto path = argv[1]; + auto pop = + nvobj::pool::create(path, "VectorTest: capacity", + PMEMOBJ_MIN_POOL, S_IWUSR | S_IRUSR); + + auto r = pop.root(); + { + try { + nvobj::transaction::run(pop, [&] { + r->v = nvobj::make_persistent(); + }); + + UT_ASSERT(r->v->capacity() == 0); + + nvobj::transaction::run(pop, [&] { + nvobj::delete_persistent(r->v); + }); + } catch (std::exception &e) { + UT_FATALexc(e); + } + } + { + try { + nvobj::transaction::run(pop, [&] { + r->v = nvobj::make_persistent(100U); + }); + + UT_ASSERT(r->v->capacity() == 100); + + r->v->push_back(0); + + UT_ASSERT(r->v->capacity() > 101); + + nvobj::transaction::run(pop, [&] { + nvobj::delete_persistent(r->v); + }); + } catch (std::exception &e) { + UT_FATALexc(e); + } + } + + pop.close(); + + return 0; +} diff --git a/tests/external/libcxx/vector/vector.capacity/empty.pass.cpp b/tests/external/libcxx/vector/vector.capacity/empty.pass.cpp new file mode 100644 index 0000000..296a66e --- /dev/null +++ b/tests/external/libcxx/vector/vector.capacity/empty.pass.cpp @@ -0,0 +1,65 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// Copyright 2019, Intel Corporation +// +// Modified to test pmem::obj containers +// + +#include "unittest.hpp" + +#include +#include + +namespace nvobj = pmem::obj; +namespace pmem_exp = nvobj::experimental; + +using C = pmem_exp::vector; + +struct root { + nvobj::persistent_ptr v; +}; + +int +main(int argc, char *argv[]) +{ + START(); + + if (argc < 2) { + std::cerr << "usage: " << argv[0] << " file-name" << std::endl; + return 1; + } + + auto path = argv[1]; + auto pop = nvobj::pool::create( + path, "VectorTest: empty", PMEMOBJ_MIN_POOL, S_IWUSR | S_IRUSR); + + auto r = pop.root(); + + try { + nvobj::transaction::run( + pop, [&] { r->v = nvobj::make_persistent(); }); + + UT_ASSERT(r->v->empty()); + r->v->push_back(C::value_type(1)); + UT_ASSERT(!r->v->empty()); + r->v->clear(); + UT_ASSERT(r->v->empty()); + + nvobj::transaction::run( + pop, [&] { nvobj::delete_persistent(r->v); }); + + } catch (std::exception &e) { + UT_FATALexc(e); + } + + pop.close(); + + return 0; +} diff --git a/tests/external/libcxx/vector/vector.capacity/max_size.pass.cpp b/tests/external/libcxx/vector/vector.capacity/max_size.pass.cpp new file mode 100644 index 0000000..a0f2e70 --- /dev/null +++ b/tests/external/libcxx/vector/vector.capacity/max_size.pass.cpp @@ -0,0 +1,66 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// Copyright 2019, Intel Corporation +// +// Modified to test pmem::obj containers +// + +#include "unittest.hpp" + +#include +#include + +namespace nvobj = pmem::obj; +namespace pmem_exp = nvobj::experimental; + +using C = pmem_exp::vector; + +struct root { + nvobj::persistent_ptr v; +}; + +int +main(int argc, char *argv[]) +{ + START(); + + if (argc < 2) { + std::cerr << "usage: " << argv[0] << " file-name" << std::endl; + return 1; + } + + auto path = argv[1]; + auto pop = + nvobj::pool::create(path, "VectorTest: max_size", + PMEMOBJ_MIN_POOL, S_IWUSR | S_IRUSR); + + auto r = pop.root(); + + try { + const C::difference_type max_dist = + static_cast( + std::numeric_limits::max()); + + nvobj::transaction::run( + pop, [&] { r->v = nvobj::make_persistent(); }); + + UT_ASSERT(r->v->max_size() <= max_dist); + + nvobj::transaction::run( + pop, [&] { nvobj::delete_persistent(r->v); }); + + } catch (std::exception &e) { + UT_FATALexc(e); + } + + pop.close(); + + return 0; +} diff --git a/tests/external/libcxx/vector/vector.capacity/reserve.pass.cpp b/tests/external/libcxx/vector/vector.capacity/reserve.pass.cpp new file mode 100644 index 0000000..f7e887a --- /dev/null +++ b/tests/external/libcxx/vector/vector.capacity/reserve.pass.cpp @@ -0,0 +1,92 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// Copyright 2019, Intel Corporation +// +// Modified to test pmem::obj containers +// + +#include "unittest.hpp" + +#include +#include + +namespace nvobj = pmem::obj; +namespace pmem_exp = nvobj::experimental; + +using C = pmem_exp::vector; + +struct root { + nvobj::persistent_ptr v; +}; + +int +main(int argc, char *argv[]) +{ + START(); + + if (argc < 2) { + std::cerr << "usage: " << argv[0] << " file-name" << std::endl; + return 1; + } + + auto path = argv[1]; + auto pop = + nvobj::pool::create(path, "VectorTest: reserve", + PMEMOBJ_MIN_POOL, S_IWUSR | S_IRUSR); + + auto r = pop.root(); + + { + try { + nvobj::transaction::run(pop, [&] { + r->v = nvobj::make_persistent(); + }); + + r->v->reserve(10); + UT_ASSERT(r->v->capacity() >= 10); + + nvobj::transaction::run(pop, [&] { + nvobj::delete_persistent(r->v); + }); + + } catch (std::exception &e) { + UT_FATALexc(e); + } + } + + { + try { + nvobj::transaction::run(pop, [&] { + r->v = nvobj::make_persistent(100U); + }); + + UT_ASSERT(r->v->capacity() == 100); + + r->v->reserve(50); + UT_ASSERT(r->v->size() == 100); + UT_ASSERT(r->v->capacity() == 100); + + r->v->reserve(150); + UT_ASSERT(r->v->size() == 100); + UT_ASSERT(r->v->capacity() == 150); + + nvobj::transaction::run(pop, [&] { + nvobj::delete_persistent(r->v); + }); + + } catch (std::exception &e) { + UT_FATALexc(e); + } + } + + pop.close(); + + return 0; +} diff --git a/tests/external/libcxx/vector/vector.capacity/resize_size.pass.cpp b/tests/external/libcxx/vector/vector.capacity/resize_size.pass.cpp new file mode 100644 index 0000000..fe61618 --- /dev/null +++ b/tests/external/libcxx/vector/vector.capacity/resize_size.pass.cpp @@ -0,0 +1,100 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// Copyright 2019, Intel Corporation +// +// Modified to test pmem::obj containers +// + +#include "helper_classes.hpp" + +#include +#include + +namespace nvobj = pmem::obj; +namespace pmem_exp = nvobj::experimental; + +using C = pmem_exp::vector; +using C2 = pmem_exp::vector; + +struct root { + nvobj::persistent_ptr v1; + nvobj::persistent_ptr v2; +}; + +int +main(int argc, char *argv[]) +{ + START(); + + if (argc < 2) { + std::cerr << "usage: " << argv[0] << " file-name" << std::endl; + return 1; + } + + auto path = argv[1]; + auto pop = + nvobj::pool::create(path, "VectorTest: resize_size", + PMEMOBJ_MIN_POOL, S_IWUSR | S_IRUSR); + + auto r = pop.root(); + + { + try { + nvobj::transaction::run(pop, [&] { + r->v1 = nvobj::make_persistent(100U); + }); + + r->v1->resize(50); + UT_ASSERT(r->v1->size() == 50); + UT_ASSERT(r->v1->capacity() == 100); + + r->v1->resize(200); + UT_ASSERT(r->v1->size() == 200); + UT_ASSERT(r->v1->capacity() >= 200); + + r->v1->resize(200); + UT_ASSERT(r->v1->size() == 200); + UT_ASSERT(r->v1->capacity() >= 200); + + nvobj::transaction::run(pop, [&] { + nvobj::delete_persistent(r->v1); + }); + + } catch (std::exception &e) { + UT_FATALexc(e); + } + } + { + try { + nvobj::transaction::run(pop, [&] { + r->v2 = nvobj::make_persistent(100U); + }); + + r->v2->resize(50); + UT_ASSERT(r->v2->size() == 50); + UT_ASSERT(r->v2->capacity() == 100); + + r->v2->resize(200); + UT_ASSERT(r->v2->size() == 200); + UT_ASSERT(r->v2->capacity() >= 200); + + nvobj::transaction::run(pop, [&] { + nvobj::delete_persistent(r->v2); + }); + + } catch (std::exception &e) { + UT_FATALexc(e); + } + } + + pop.close(); + + return 0; +} diff --git a/tests/external/libcxx/vector/vector.capacity/resize_size_value.pass.cpp b/tests/external/libcxx/vector/vector.capacity/resize_size_value.pass.cpp new file mode 100644 index 0000000..9ed5571 --- /dev/null +++ b/tests/external/libcxx/vector/vector.capacity/resize_size_value.pass.cpp @@ -0,0 +1,90 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// Copyright 2019, Intel Corporation +// +// Modified to test pmem::obj containers +// + +#include "unittest.hpp" + +#include +#include + +namespace nvobj = pmem::obj; +namespace pmem_exp = nvobj::experimental; + +using C = pmem_exp::vector; + +struct root { + nvobj::persistent_ptr v; +}; + +int +main(int argc, char *argv[]) +{ + START(); + + if (argc < 2) { + std::cerr << "usage: " << argv[0] << " file-name" << std::endl; + return 1; + } + + auto path = argv[1]; + auto pop = + nvobj::pool::create(path, "VectorTest: resize_size_value", + PMEMOBJ_MIN_POOL, S_IWUSR | S_IRUSR); + + auto r = pop.root(); + + try { + nvobj::transaction::run( + pop, [&] { r->v = nvobj::make_persistent(100U); }); + + r->v->resize(50, 1); + UT_ASSERT(r->v->size() == 50); + UT_ASSERT(r->v->capacity() == 100); + + nvobj::transaction::run(pop, [&] { + nvobj::persistent_ptr v_tmp = + nvobj::make_persistent(50U); + UT_ASSERT(*r->v == *v_tmp); + nvobj::delete_persistent(v_tmp); + }); + + r->v->resize(200, 1); + UT_ASSERT(r->v->size() == 200); + UT_ASSERT(r->v->capacity() >= 200); + + for (unsigned i = 0; i < 50; ++i) + UT_ASSERT((*r->v)[i] == 0); + for (unsigned i = 50; i < 200; ++i) + UT_ASSERT((*r->v)[i] == 1); + + /* test count == capacity() */ + r->v->resize(r->v->capacity(), 1); + UT_ASSERT(r->v->size() == 200); + UT_ASSERT(r->v->capacity() >= 200); + + for (unsigned i = 0; i < 50; ++i) + UT_ASSERT((*r->v)[i] == 0); + for (unsigned i = 50; i < 200; ++i) + UT_ASSERT((*r->v)[i] == 1); + + nvobj::transaction::run( + pop, [&] { nvobj::delete_persistent(r->v); }); + + } catch (std::exception &e) { + UT_FATALexc(e); + } + + pop.close(); + + return 0; +} diff --git a/tests/external/libcxx/vector/vector.capacity/shrink_to_fit.pass.cpp b/tests/external/libcxx/vector/vector.capacity/shrink_to_fit.pass.cpp new file mode 100644 index 0000000..aacb149 --- /dev/null +++ b/tests/external/libcxx/vector/vector.capacity/shrink_to_fit.pass.cpp @@ -0,0 +1,69 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// Copyright 2019, Intel Corporation +// +// Modified to test pmem::obj containers +// + +#include "unittest.hpp" + +#include +#include + +namespace nvobj = pmem::obj; +namespace pmem_exp = nvobj::experimental; + +using C = pmem_exp::vector; + +struct root { + nvobj::persistent_ptr v; +}; + +int +main(int argc, char *argv[]) +{ + START(); + + if (argc < 2) { + std::cerr << "usage: " << argv[0] << " file-name" << std::endl; + return 1; + } + + auto path = argv[1]; + auto pop = + nvobj::pool::create(path, "VectorTest: shrink_to_fit", + PMEMOBJ_MIN_POOL, S_IWUSR | S_IRUSR); + + auto r = pop.root(); + + try { + nvobj::transaction::run( + pop, [&] { r->v = nvobj::make_persistent(100U); }); + r->v->push_back(1); + + r->v->shrink_to_fit(); + UT_ASSERT(r->v->capacity() == 101); + UT_ASSERT(r->v->size() == 101); + + r->v->shrink_to_fit(); + UT_ASSERT(r->v->capacity() == 101); + UT_ASSERT(r->v->size() == 101); + + nvobj::transaction::run( + pop, [&] { nvobj::delete_persistent(r->v); }); + + } catch (std::exception &e) { + UT_FATALexc(e); + } + + pop.close(); + + return 0; +} diff --git a/tests/external/libcxx/vector/vector.capacity/size.pass.cpp b/tests/external/libcxx/vector/vector.capacity/size.pass.cpp new file mode 100644 index 0000000..5fa2598 --- /dev/null +++ b/tests/external/libcxx/vector/vector.capacity/size.pass.cpp @@ -0,0 +1,78 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// Copyright 2019, Intel Corporation +// +// Modified to test pmem::obj containers +// + +#include "unittest.hpp" + +#include +#include + +namespace nvobj = pmem::obj; +namespace pmem_exp = nvobj::experimental; + +using C = pmem_exp::vector; + +struct root { + nvobj::persistent_ptr v; +}; + +int +main(int argc, char *argv[]) +{ + START(); + + if (argc < 2) { + std::cerr << "usage: " << argv[0] << " file-name" << std::endl; + return 1; + } + + auto path = argv[1]; + auto pop = nvobj::pool::create( + path, "VectorTest: size", PMEMOBJ_MIN_POOL, S_IWUSR | S_IRUSR); + + auto r = pop.root(); + + try { + nvobj::transaction::run( + pop, [&] { r->v = nvobj::make_persistent(); }); + UT_ASSERT(r->v->size() == 0); + + r->v->push_back(C::value_type(2)); + UT_ASSERT(r->v->size() == 1); + + r->v->push_back(C::value_type(1)); + UT_ASSERT(r->v->size() == 2); + + r->v->push_back(C::value_type(3)); + UT_ASSERT(r->v->size() == 3); + + r->v->erase(r->v->begin()); + UT_ASSERT(r->v->size() == 2); + + r->v->erase(r->v->begin()); + UT_ASSERT(r->v->size() == 1); + + r->v->erase(r->v->begin()); + UT_ASSERT(r->v->size() == 0); + + nvobj::transaction::run( + pop, [&] { nvobj::delete_persistent(r->v); }); + + } catch (std::exception &e) { + UT_FATALexc(e); + } + + pop.close(); + + return 0; +} diff --git a/tests/external/libcxx/vector/vector.capacity/swap.pass.cpp b/tests/external/libcxx/vector/vector.capacity/swap.pass.cpp new file mode 100644 index 0000000..bd1c5ed --- /dev/null +++ b/tests/external/libcxx/vector/vector.capacity/swap.pass.cpp @@ -0,0 +1,72 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// Copyright 2019, Intel Corporation +// +// Modified to test pmem::obj containers +// + +#include "unittest.hpp" + +#include +#include +#include + +namespace nvobj = pmem::obj; +namespace pmem_exp = nvobj::experimental; + +using C = pmem_exp::vector; + +struct root { + nvobj::persistent_ptr v1; + nvobj::persistent_ptr v2; +}; + +int +main(int argc, char *argv[]) +{ + START(); + + if (argc < 2) { + std::cerr << "usage: " << argv[0] << " file-name" << std::endl; + return 1; + } + + auto path = argv[1]; + auto pop = nvobj::pool::create( + path, "VectorTest: swap", PMEMOBJ_MIN_POOL, S_IWUSR | S_IRUSR); + + auto r = pop.root(); + + try { + nvobj::transaction::run(pop, [&] { + r->v1 = nvobj::make_persistent(100U); + r->v2 = nvobj::make_persistent(200U); + }); + + r->v1->swap(*r->v2); + + UT_ASSERT(r->v1->size() == 200); + UT_ASSERT(r->v1->capacity() == 200); + UT_ASSERT(r->v2->size() == 100); + UT_ASSERT(r->v2->capacity() == 100); + + nvobj::transaction::run(pop, [&] { + nvobj::delete_persistent(r->v1); + nvobj::delete_persistent(r->v2); + }); + + } catch (std::exception &e) { + UT_FATALexc(e); + } + + pop.close(); + + return 0; +} diff --git a/tests/external/libcxx/vector/vector.cons/assign_copy.pass.cpp b/tests/external/libcxx/vector/vector.cons/assign_copy.pass.cpp new file mode 100644 index 0000000..dd3f40f --- /dev/null +++ b/tests/external/libcxx/vector/vector.cons/assign_copy.pass.cpp @@ -0,0 +1,72 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// Copyright 2019, Intel Corporation +// +// Modified to test pmem::obj containers +// + +#include "unittest.hpp" + +#include +#include + +namespace nvobj = pmem::obj; +namespace pmem_exp = nvobj::experimental; +using C = pmem_exp::vector; + +struct root { + nvobj::persistent_ptr v1; + nvobj::persistent_ptr v2; +}; + +template +void +test(nvobj::pool &pop) +{ + auto r = pop.root(); + + try { + nvobj::transaction::run(pop, [&] { + r->v1 = nvobj::make_persistent(3U, 2); + r->v2 = nvobj::make_persistent(*r->v1); + }); + + *r->v2 = *r->v1; + UT_ASSERT(*r->v2 == *r->v1); + + nvobj::transaction::run(pop, [&] { + nvobj::delete_persistent(r->v1); + nvobj::delete_persistent(r->v2); + }); + } catch (std::exception &e) { + UT_FATALexc(e); + } +} + +int +main(int argc, char *argv[]) +{ + START(); + + if (argc < 2) { + std::cerr << "usage: " << argv[0] << " file-name" << std::endl; + return 1; + } + auto path = argv[1]; + auto pop = + nvobj::pool::create(path, "VectorTest: assign_copy.pass", + PMEMOBJ_MIN_POOL, S_IWUSR | S_IRUSR); + + test(pop); + + pop.close(); + + return 0; +} diff --git a/tests/external/libcxx/vector/vector.cons/assign_initializer_list.pass.cpp b/tests/external/libcxx/vector/vector.cons/assign_initializer_list.pass.cpp new file mode 100644 index 0000000..bd90e30 --- /dev/null +++ b/tests/external/libcxx/vector/vector.cons/assign_initializer_list.pass.cpp @@ -0,0 +1,84 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// Copyright 2019, Intel Corporation +// +// Modified to test pmem::obj containers +// + +#include "unittest.hpp" + +#include +#include + +namespace nvobj = pmem::obj; +namespace pmem_exp = nvobj::experimental; +using C = pmem_exp::vector; + +struct root { + nvobj::persistent_ptr v1; + nvobj::persistent_ptr v2; +}; + +template +void +test(nvobj::pool &pop, Vec &v) +{ + try { + v.assign({3, 4, 5, 6}); + UT_ASSERT(v.size() == 4); + + UT_ASSERT(v[0] == 3); + UT_ASSERT(v[1] == 4); + UT_ASSERT(v[2] == 5); + UT_ASSERT(v[3] == 6); + } catch (std::exception &e) { + UT_FATALexc(e); + } +} + +int +main(int argc, char *argv[]) +{ + START(); + + if (argc < 2) { + std::cerr << "usage: " << argv[0] << " file-name" << std::endl; + return 1; + } + auto path = argv[1]; + auto pop = nvobj::pool::create( + path, "VectorTest: assign_initializer_list.pass", + PMEMOBJ_MIN_POOL, S_IWUSR | S_IRUSR); + + auto r = pop.root(); + + try { + nvobj::transaction::run(pop, [&] { + r->v1 = nvobj::make_persistent(); + r->v2 = nvobj::make_persistent(); + }); + + r->v2->reserve(10); + + test(pop, *r->v1); + test(pop, *r->v2); + + nvobj::transaction::run(pop, [&] { + nvobj::delete_persistent(r->v1); + nvobj::delete_persistent(r->v2); + }); + } catch (std::exception &e) { + UT_FATALexc(e); + } + + pop.close(); + + return 0; +} diff --git a/tests/external/libcxx/vector/vector.cons/assign_iter_iter.pass.cpp b/tests/external/libcxx/vector/vector.cons/assign_iter_iter.pass.cpp new file mode 100644 index 0000000..1650e6d --- /dev/null +++ b/tests/external/libcxx/vector/vector.cons/assign_iter_iter.pass.cpp @@ -0,0 +1,133 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// Copyright 2019, Intel Corporation +// +// Modified to test pmem::obj containers +// + +#include "helper_classes.hpp" +#include "unittest.hpp" + +#include +#include + +namespace nvobj = pmem::obj; +namespace pmem_exp = nvobj::experimental; + +using C = pmem_exp::vector>; + +struct root { + nvobj::persistent_ptr v; +}; + +static void +test_emplaceable_concept(nvobj::pool &pop) +{ + int arr1[] = {42}; + int arr2[] = {1, 101, 42}; + + auto r = pop.root(); + /* TEST_1 */ + { + using It = test_support::forward_it; + + try { + nvobj::transaction::run(pop, [&] { + r->v = nvobj::make_persistent(); + }); + + r->v->assign(It(arr1), It(std::end(arr1))); + UT_ASSERT((*r->v)[0].value == 42); + + nvobj::transaction::run(pop, [&] { + nvobj::delete_persistent(r->v); + }); + } catch (std::exception &e) { + UT_FATALexc(e); + } + + try { + nvobj::transaction::run(pop, [&] { + r->v = nvobj::make_persistent(); + }); + + r->v->assign(It(arr2), It(std::end(arr2))); + UT_ASSERT((*r->v)[0].value == 1); + UT_ASSERT((*r->v)[1].value == 101); + UT_ASSERT((*r->v)[2].value == 42); + + nvobj::transaction::run(pop, [&] { + nvobj::delete_persistent(r->v); + }); + } catch (std::exception &e) { + UT_FATALexc(e); + } + } + /* TEST_2 */ + { + using It = test_support::forward_it; + + try { + nvobj::transaction::run(pop, [&] { + r->v = nvobj::make_persistent(); + }); + + r->v->assign(It(arr1), It(std::end(arr1))); + UT_ASSERT((*r->v)[0].value == 42); + UT_ASSERT((*r->v)[0].moved == 0); + + nvobj::transaction::run(pop, [&] { + nvobj::delete_persistent(r->v); + }); + } catch (std::exception &e) { + UT_FATALexc(e); + } + + try { + nvobj::transaction::run(pop, [&] { + r->v = nvobj::make_persistent(); + }); + + r->v->assign(It(arr2), It(std::end(arr2))); + UT_ASSERT((*r->v)[0].value == 1); + UT_ASSERT((*r->v)[1].value == 101); + UT_ASSERT((*r->v)[2].value == 42); + UT_ASSERT((*r->v)[2].moved == 0); + + nvobj::transaction::run(pop, [&] { + nvobj::delete_persistent(r->v); + }); + } catch (std::exception &e) { + UT_FATALexc(e); + } + } +} + +int +main(int argc, char *argv[]) +{ + START(); + + if (argc < 2) { + std::cerr << "usage: " << argv[0] << " file-name" << std::endl; + return 1; + } + + auto path = argv[1]; + auto pop = + nvobj::pool::create(path, "VectorTest: assign_iter_iter", + PMEMOBJ_MIN_POOL, S_IWUSR | S_IRUSR); + + test_emplaceable_concept(pop); + + pop.close(); + + return 0; +} diff --git a/tests/external/libcxx/vector/vector.cons/assign_move.pass.cpp b/tests/external/libcxx/vector/vector.cons/assign_move.pass.cpp new file mode 100644 index 0000000..e7de2e0 --- /dev/null +++ b/tests/external/libcxx/vector/vector.cons/assign_move.pass.cpp @@ -0,0 +1,82 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// Copyright 2019, Intel Corporation +// +// Modified to test pmem::obj containers +// + +#include "helper_classes.hpp" +#include "unittest.hpp" + +#include +#include + +namespace nvobj = pmem::obj; +namespace pmem_exp = nvobj::experimental; +using C = pmem_exp::vector; + +struct root { + nvobj::persistent_ptr l; + nvobj::persistent_ptr lo; + nvobj::persistent_ptr l2; +}; + +template +void +test(nvobj::pool &pop) +{ + auto r = pop.root(); + + try { + nvobj::transaction::run(pop, [&] { + r->l = nvobj::make_persistent(); + r->lo = nvobj::make_persistent(); + r->l2 = nvobj::make_persistent(); + }); + + for (int i = 1; i <= 3; ++i) { + r->l->push_back(i); + r->lo->push_back(i); + } + *r->l2 = std::move(*r->l); + + UT_ASSERT(*r->l2 == *r->lo); + UT_ASSERT(r->l->empty()); + + nvobj::transaction::run(pop, [&] { + nvobj::delete_persistent(r->l); + nvobj::delete_persistent(r->lo); + nvobj::delete_persistent(r->l2); + }); + } catch (std::exception &e) { + UT_FATALexc(e); + } +} + +int +main(int argc, char *argv[]) +{ + START(); + + if (argc < 2) { + std::cerr << "usage: " << argv[0] << " file-name" << std::endl; + return 1; + } + auto path = argv[1]; + auto pop = + nvobj::pool::create(path, "VectorTest: assign_move.pass", + PMEMOBJ_MIN_POOL, S_IWUSR | S_IRUSR); + + test(pop); + + pop.close(); + + return 0; +} diff --git a/tests/external/libcxx/vector/vector.cons/assign_size_value.pass.cpp b/tests/external/libcxx/vector/vector.cons/assign_size_value.pass.cpp new file mode 100644 index 0000000..6377319 --- /dev/null +++ b/tests/external/libcxx/vector/vector.cons/assign_size_value.pass.cpp @@ -0,0 +1,96 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// Copyright 2019, Intel Corporation +// +// Modified to test pmem::obj containers +// + +#include "unittest.hpp" + +#include +#include + +namespace nvobj = pmem::obj; +namespace pmem_exp = nvobj::experimental; +using C = pmem_exp::vector; + +struct root { + nvobj::persistent_ptr v1; + nvobj::persistent_ptr v2; + nvobj::persistent_ptr v3; +}; + +bool +is6(int x) +{ + return x == 6; +} + +/** + * Test pmem::obj::experimental::vector fill version of assign method + * + * Replaces vector's contents with count copies of given value + * Validates size and elements of the vector. + */ +template +void +test(nvobj::pool &pop, Vec &v) +{ + try { + v.assign(5, 6); + UT_ASSERT(v.size() == 5); + std::all_of(v.begin(), v.end(), is6); + } catch (std::exception &e) { + UT_FATALexc(e); + } +} + +int +main(int argc, char *argv[]) +{ + START(); + + if (argc < 2) { + std::cerr << "usage: " << argv[0] << " file-name" << std::endl; + return 1; + } + auto path = argv[1]; + auto pop = nvobj::pool::create( + path, "VectorTest: assign_size_value.pass", PMEMOBJ_MIN_POOL, + S_IWUSR | S_IRUSR); + + auto r = pop.root(); + + try { + nvobj::transaction::run(pop, [&] { + r->v1 = nvobj::make_persistent(); + r->v2 = nvobj::make_persistent(); + r->v3 = nvobj::make_persistent(10U, 1); + }); + + r->v2->reserve(10); // no reallocation during assign + + test(pop, *r->v1); + test(pop, *r->v2); + test(pop, *r->v3); + + nvobj::transaction::run(pop, [&] { + nvobj::delete_persistent(r->v1); + nvobj::delete_persistent(r->v2); + nvobj::delete_persistent(r->v3); + }); + } catch (std::exception &e) { + UT_FATALexc(e); + } + + pop.close(); + + return 0; +} diff --git a/tests/external/libcxx/vector/vector.cons/construct_default.pass.cpp b/tests/external/libcxx/vector/vector.cons/construct_default.pass.cpp new file mode 100644 index 0000000..305ef56 --- /dev/null +++ b/tests/external/libcxx/vector/vector.cons/construct_default.pass.cpp @@ -0,0 +1,83 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// Copyright 2018-2019, Intel Corporation +// +// Modified to test pmem::obj containers +// + +#include "unittest.hpp" + +#include +#include +#include +#include +#include + +namespace nvobj = pmem::obj; +namespace pmem_exp = nvobj::experimental; +using vector_type = pmem_exp::vector; + +struct foo { + vector_type v_1; +#ifdef NO_CLANG_BRACE_INITIALIZATION_NEWEXPR_BUG + vector_type v_2 = {}; +#endif +}; + +struct root { + nvobj::persistent_ptr v_pptr; + nvobj::persistent_ptr foo_pptr; +}; + +/** + * Test pmem::obj::experimental::vector default constructor. + * + * First case: call default constructor in three different ways and check if + * new container is empty. Expect no exception is thrown. + */ +void +test_default_ctor(nvobj::pool &pop) +{ + auto r = pop.root(); + try { + nvobj::transaction::run(pop, [&] { + r->v_pptr = nvobj::make_persistent(); + r->foo_pptr = nvobj::make_persistent(); + }); + UT_ASSERT(r->v_pptr->empty() == 1); + UT_ASSERT(r->foo_pptr->v_1.empty() == 1); +#ifdef NO_CLANG_BRACE_INITIALIZATION_NEWEXPR_BUG + UT_ASSERT(r->foo_pptr->v_2.empty() == 1); +#endif + nvobj::delete_persistent_atomic(r->v_pptr); + nvobj::delete_persistent_atomic(r->foo_pptr); + } catch (std::exception &e) { + UT_FATALexc(e); + } +} + +int +main(int argc, char *argv[]) +{ + START(); + if (argc < 2) { + std::cerr << "usage: " << argv[0] << " file-name" << std::endl; + return 1; + } + auto path = argv[1]; + auto pop = nvobj::pool::create( + path, "VectorTest: construct_default.pass", PMEMOBJ_MIN_POOL, + S_IWUSR | S_IRUSR); + test_default_ctor(pop); + + pop.close(); + + return 0; +} diff --git a/tests/external/libcxx/vector/vector.cons/construct_iter_iter.pass.cpp b/tests/external/libcxx/vector/vector.cons/construct_iter_iter.pass.cpp new file mode 100644 index 0000000..7da6d64 --- /dev/null +++ b/tests/external/libcxx/vector/vector.cons/construct_iter_iter.pass.cpp @@ -0,0 +1,229 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// Copyright 2018-2019, Intel Corporation +// +// Modified to test pmem::obj containers +// + +#include "helper_classes.hpp" +#include "unittest.hpp" + +#include +#include + +namespace nvobj = pmem::obj; +namespace pmem_exp = nvobj::experimental; + +using vector_type = pmem_exp::vector; +using vector_type2 = pmem_exp::vector>; +using vector_type3 = + pmem_exp::vector>; + +struct root { + nvobj::persistent_ptr test1; + nvobj::persistent_ptr test2; + nvobj::persistent_ptr test3; +}; + +template +void +basic_test(nvobj::pool &pop, Iterator first, Iterator last) +{ + auto r = pop.root(); + + /* construct */ + try { + nvobj::transaction::run(pop, [&] { + r->test1 = nvobj::make_persistent(first, last); + }); + } catch (std::exception &e) { + UT_FATALexc(e); + } + /* validate */ + try { + nvobj::transaction::run(pop, [&] { + UT_ASSERTeq(r->test1->size(), + static_cast( + std::distance(first, last))); + + for (typename C::const_iterator i = r->test1->begin(), + e = r->test1->end(); + i != e; ++i, ++first) + UT_ASSERTeq(*i, *first); + + nvobj::delete_persistent(r->test1); + }); + } catch (std::exception &e) { + UT_FATALexc(e); + } +} + +/** + * Test pmem::obj::experimental::vector range constructor + * + * Constructs container with elements within [first, last) range pointed by + * iterators of following categories: Input, Forward, Bidirectional, Random + * access Validates container's size and its elements. Expects no exception is + * thrown. + */ +static void +basic_test_cases(nvobj::pool &pop) +{ + int a[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 8, 7, 6, 5, 4, 3, 1, 0}; + int *an = a + sizeof(a) / sizeof(a[0]); + basic_test(pop, test_support::input_it(a), + test_support::input_it(an)); + basic_test(pop, test_support::forward_it(a), + test_support::forward_it(an)); + basic_test( + pop, test_support::bidirectional_it(a), + test_support::bidirectional_it(an)); + basic_test( + pop, test_support::random_access_it(a), + test_support::random_access_it(an)); +} + +/** + * Test pmem::obj::experimental::vector range constructor + * + * Constructs container with elements within [first, last) range pointed by + * iterators + * TEST_1 - Checks if elements are emplace-constructed from given range, in the + * same order + * + * TEST_2 - additionaly to TEST_1 checks if elements within [first, last) range + * are not moved if iterator does not meet forward iterator requirements + */ +static void +emplaceable_concept_tests(nvobj::pool &pop) +{ + int arr1[] = {42}; + int arr2[] = {1, 101, 42}; + + auto r = pop.root(); + /* TEST_1 */ + { + using It = test_support::forward_it; + /* construct */ + try { + nvobj::transaction::run(pop, [&] { + r->test2 = nvobj::make_persistent( + It(arr1), It(std::end(arr1))); + }); + } catch (std::exception &e) { + UT_FATALexc(e); + } + /* validate */ + try { + UT_ASSERTeq((*r->test2)[0].value, 42); + nvobj::transaction::run(pop, [&] { + nvobj::delete_persistent( + r->test2); + }); + } catch (std::exception &e) { + UT_FATALexc(e); + } + + /* construct */ + try { + nvobj::transaction::run(pop, [&] { + r->test2 = nvobj::make_persistent( + It(arr2), It(std::end(arr2))); + }); + } catch (std::exception &e) { + UT_FATALexc(e); + } + /* validate */ + try { + UT_ASSERTeq((*r->test2)[0].value, 1); + UT_ASSERTeq((*r->test2)[1].value, 101); + UT_ASSERTeq((*r->test2)[2].value, 42); + + nvobj::transaction::run(pop, [&] { + nvobj::delete_persistent( + r->test2); + }); + } catch (std::exception &e) { + UT_FATALexc(e); + } + } + /* TEST_2 */ + { + using It = test_support::input_it; + /* construct */ + try { + nvobj::transaction::run(pop, [&] { + r->test3 = nvobj::make_persistent( + It(arr1), It(std::end(arr1))); + }); + } catch (std::exception &e) { + UT_FATALexc(e); + } + /* validate */ + try { + UT_ASSERTeq((*r->test3)[0].value, 42); + UT_ASSERTeq((*r->test3)[0].moved, 0); + + nvobj::transaction::run(pop, [&] { + nvobj::delete_persistent( + r->test3); + }); + } catch (std::exception &e) { + UT_FATALexc(e); + } + + /* construct */ + try { + nvobj::transaction::run(pop, [&] { + r->test3 = nvobj::make_persistent( + It(arr2), It(std::end(arr2))); + }); + } catch (std::exception &e) { + UT_FATALexc(e); + } + /* validate */ + try { + UT_ASSERTeq((*r->test3)[0].value, 1); + UT_ASSERTeq((*r->test3)[1].value, 101); + UT_ASSERTeq((*r->test3)[2].value, 42); + UT_ASSERTeq((*r->test3)[2].moved, 0); + + nvobj::transaction::run(pop, [&] { + nvobj::delete_persistent( + r->test3); + }); + } catch (std::exception &e) { + UT_FATALexc(e); + } + } +} + +int +main(int argc, char *argv[]) +{ + START(); + + if (argc < 2) { + std::cerr << "usage: " << argv[0] << " file-name" << std::endl; + return 1; + } + + auto path = argv[1]; + auto pop = nvobj::pool::create( + path, "VectorTest: construct_iter_iter", PMEMOBJ_MIN_POOL, + S_IWUSR | S_IRUSR); + + basic_test_cases(pop); + emplaceable_concept_tests(pop); + + pop.close(); + + return 0; +} diff --git a/tests/external/libcxx/vector/vector.cons/construct_size.pass.cpp b/tests/external/libcxx/vector/vector.cons/construct_size.pass.cpp new file mode 100644 index 0000000..9433d56 --- /dev/null +++ b/tests/external/libcxx/vector/vector.cons/construct_size.pass.cpp @@ -0,0 +1,86 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// Copyright 2018-2019, Intel Corporation +// +// Modified to test pmem::obj containers +// + +#include "helper_classes.hpp" +#include "unittest.hpp" + +#include +#include + +namespace nvobj = pmem::obj; +namespace pmem_exp = nvobj::experimental; + +using vector_type = pmem_exp::vector; +using vector_type2 = pmem_exp::vector; + +struct root { + nvobj::persistent_ptr test1; + nvobj::persistent_ptr test2; +}; + +/** + * Test pmem::obj::experimental::vector fill constructor + * + * Constructs container with n default constructed elements. + * Validates container's size and its elements for both fundamental and user + * defined types. Expects no exception is thrown. + */ +template +void +test(nvobj::pool &pop, nvobj::persistent_ptr &pptr, + typename C::size_type n) +{ + try { + nvobj::transaction::run( + pop, [&] { pptr = nvobj::make_persistent(n); }); + + UT_ASSERTeq(pptr->size(), n); + + for (typename C::const_iterator i = pptr->begin(), + e = pptr->end(); + i != e; ++i) + UT_ASSERT(*i == typename C::value_type()); + + nvobj::transaction::run( + pop, [&] { nvobj::delete_persistent(pptr); }); + } catch (std::exception &e) { + UT_FATALexc(e); + } +} + +int +main(int argc, char *argv[]) +{ + START(); + + if (argc < 2) { + std::cerr << "usage: " << argv[0] << " file-name" << std::endl; + return 1; + } + + auto path = argv[1]; + auto pop = + nvobj::pool::create(path, "VectorTest: construct_size", + PMEMOBJ_MIN_POOL, S_IWUSR | S_IRUSR); + auto r = pop.root(); + + test(pop, r->test1, 50); + + test(pop, r->test2, 500); + UT_ASSERT(default_constructible_only::count == 0); + + pop.close(); + + return 0; +} diff --git a/tests/external/libcxx/vector/vector.cons/construct_size_value.pass.cpp b/tests/external/libcxx/vector/vector.cons/construct_size_value.pass.cpp new file mode 100644 index 0000000..1a3a4aa --- /dev/null +++ b/tests/external/libcxx/vector/vector.cons/construct_size_value.pass.cpp @@ -0,0 +1,86 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// Copyright 2018-2019, Intel Corporation +// +// Modified to test pmem::obj containers +// + +#include "unittest.hpp" + +#include +#include + +namespace nvobj = pmem::obj; +namespace pmem_exp = nvobj::experimental; + +using vector_type = pmem_exp::vector; + +struct root { + nvobj::persistent_ptr pptr; +}; + +/** + * Test pmem::obj::experimental::vector fill constructor + * + * Constructs container with n copies of elements with custom value. + * Validates container's size and its elements. Expects no exception is thrown. + */ +template +void +test(nvobj::pool &pop, typename C::size_type n) +{ + const int val = 3; + + auto r = pop.root(); + /* construct */ + try { + nvobj::transaction::run(pop, [&] { + r->pptr = nvobj::make_persistent(n, val); + }); + } catch (std::exception &e) { + UT_FATALexc(e); + } + /* validate */ + try { + UT_ASSERTeq(r->pptr->size(), n); + + for (typename C::const_iterator i = r->pptr->begin(), + e = r->pptr->end(); + i != e; ++i) + UT_ASSERTeq(*i, val); + + nvobj::transaction::run( + pop, [&] { nvobj::delete_persistent(r->pptr); }); + } catch (std::exception &e) { + UT_FATALexc(e); + } +} + +int +main(int argc, char *argv[]) +{ + START(); + + if (argc < 2) { + std::cerr << "usage: " << argv[0] << " file-name" << std::endl; + return 1; + } + + auto path = argv[1]; + auto pop = nvobj::pool::create( + path, "VectorTest: construct_size_value", PMEMOBJ_MIN_POOL, + S_IWUSR | S_IRUSR); + + test(pop, 5); + + pop.close(); + + return 0; +} diff --git a/tests/external/libcxx/vector/vector.cons/copy.pass.cpp b/tests/external/libcxx/vector/vector.cons/copy.pass.cpp new file mode 100644 index 0000000..d49cb5b --- /dev/null +++ b/tests/external/libcxx/vector/vector.cons/copy.pass.cpp @@ -0,0 +1,134 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// Copyright 2019, Intel Corporation +// +// Modified to test pmem::obj containers +// + +#include "unittest.hpp" + +#include +#include + +namespace nvobj = pmem::obj; +namespace pmem_exp = nvobj::experimental; +using vector_type = pmem_exp::vector; + +struct root { + nvobj::persistent_ptr v1; + nvobj::persistent_ptr v2; +}; + +template +void +test_copy_ctor_01(nvobj::pool &pop, const C &x) +{ + typename C::size_type s = x.size(); + + auto r = pop.root(); + + try { + nvobj::transaction::run( + pop, [&] { r->v2 = nvobj::make_persistent(x); }); + } catch (std::exception &e) { + UT_FATALexc(e); + } + + UT_ASSERT(r->v2->size() == s); + UT_ASSERT(*(r->v2) == x); + + try { + nvobj::transaction::run( + pop, [&] { nvobj::delete_persistent(r->v2); }); + } catch (std::exception &e) { + UT_FATALexc(e); + } +} + +template +void +test_copy_ctor_02(nvobj::pool &pop) +{ + auto r = pop.root(); + + try { + nvobj::transaction::run( + pop, [&] { r->v1 = nvobj::make_persistent(3U, 2); }); + } catch (std::exception &e) { + UT_FATALexc(e); + } + + try { + nvobj::transaction::run(pop, [&] { + nvobj::persistent_ptr v3 = + nvobj::make_persistent(*(r->v1)); + UT_ASSERT(*v3 == *(r->v1)); + nvobj::delete_persistent(v3); + }); + } catch (std::exception &e) { + UT_FATALexc(e); + } + + try { + nvobj::transaction::run( + pop, [&] { nvobj::delete_persistent(r->v1); }); + } catch (std::exception &e) { + UT_FATALexc(e); + } +} + +int +main(int argc, char *argv[]) +{ + START(); + + if (argc < 2) { + std::cerr << "usage: " << argv[0] << " file-name" << std::endl; + return 1; + } + + auto path = argv[1]; + auto pop = + nvobj::pool::create(path, "VectorTest: copy.pass", + PMEMOBJ_MIN_POOL, S_IWUSR | S_IRUSR); + + auto r = pop.root(); + { + int a[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, + 9, 8, 7, 6, 5, 4, 3, 1, 0}; + int *an = a + sizeof(a) / sizeof(a[0]); + + try { + nvobj::transaction::run(pop, [&] { + r->v1 = nvobj::make_persistent(a, + an); + }); + } catch (std::exception &e) { + UT_FATALexc(e); + } + + test_copy_ctor_01(pop, *(r->v1)); + + try { + nvobj::transaction::run(pop, [&] { + nvobj::delete_persistent(r->v1); + }); + } catch (std::exception &e) { + UT_FATALexc(e); + } + } + { + test_copy_ctor_02(pop); + } + + pop.close(); + + return 0; +} diff --git a/tests/external/libcxx/vector/vector.cons/dtor_noexcept.pass.cpp b/tests/external/libcxx/vector/vector.cons/dtor_noexcept.pass.cpp new file mode 100644 index 0000000..06d6d5c --- /dev/null +++ b/tests/external/libcxx/vector/vector.cons/dtor_noexcept.pass.cpp @@ -0,0 +1,37 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// Copyright 2018-2019, Intel Corporation +// +// Modified to test pmem::obj containers +// + +#include "unittest.hpp" + +#include + +namespace nvobj = pmem::obj; +namespace pmem_exp = nvobj::experimental; + +int +main() +{ + /** + * Test pmem::obj::experimental::vector destructor + * + * Expects that destructor is not deleted and noexcept + */ + { + using vector_type = pmem_exp::vector; + static_assert(std::is_nothrow_destructible::value, + ""); + } + + return 0; +} diff --git a/tests/external/libcxx/vector/vector.cons/initializer_list.pass.cpp b/tests/external/libcxx/vector/vector.cons/initializer_list.pass.cpp new file mode 100644 index 0000000..05ff706 --- /dev/null +++ b/tests/external/libcxx/vector/vector.cons/initializer_list.pass.cpp @@ -0,0 +1,72 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// Copyright 2019, Intel Corporation +// +// Modified to test pmem::obj containers +// + +#include "unittest.hpp" + +#include +#include + +namespace nvobj = pmem::obj; +namespace pmem_exp = nvobj::experimental; +using vector_type = pmem_exp::vector; + +struct root { + nvobj::persistent_ptr v; +}; + +void +test(nvobj::pool &pop) +{ + auto r = pop.root(); + + try { + nvobj::transaction::run(pop, [&] { + r->v = nvobj::make_persistent( + std::initializer_list{3, 4, 5, 6}); + }); + + UT_ASSERT(r->v->size() == 4); + UT_ASSERT((*r->v)[0] == 3); + UT_ASSERT((*r->v)[1] == 4); + UT_ASSERT((*r->v)[2] == 5); + UT_ASSERT((*r->v)[3] == 6); + + nvobj::transaction::run(pop, [&] { + nvobj::delete_persistent(r->v); + }); + } catch (std::exception &e) { + UT_FATALexc(e); + } +} + +int +main(int argc, char *argv[]) +{ + START(); + + if (argc < 2) { + std::cerr << "usage: " << argv[0] << " file-name" << std::endl; + return 1; + } + auto path = argv[1]; + auto pop = nvobj::pool::create( + path, "VectorTest: initializer_list.pass", PMEMOBJ_MIN_POOL, + S_IWUSR | S_IRUSR); + + test(pop); + + pop.close(); + + return 0; +} diff --git a/tests/external/libcxx/vector/vector.cons/move.pass.cpp b/tests/external/libcxx/vector/vector.cons/move.pass.cpp new file mode 100644 index 0000000..10333d5 --- /dev/null +++ b/tests/external/libcxx/vector/vector.cons/move.pass.cpp @@ -0,0 +1,103 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// Copyright 2019, Intel Corporation +// +// Modified to test pmem::obj containers +// + +#include "helper_classes.hpp" +#include "unittest.hpp" + +#include +#include + +namespace nvobj = pmem::obj; +namespace pmem_exp = nvobj::experimental; +using C = pmem_exp::vector; +using C2 = pmem_exp::vector; + +struct root { + nvobj::persistent_ptr l, lo, l2; + nvobj::persistent_ptr c1, c2; +}; + +int +main(int argc, char *argv[]) +{ + START(); + + if (argc < 2) { + std::cerr << "usage: " << argv[0] << " file-name" << std::endl; + return 1; + } + auto path = argv[1]; + auto pop = nvobj::pool::create( + path, "VectorTest: move", PMEMOBJ_MIN_POOL, S_IWUSR | S_IRUSR); + + auto r = pop.root(); + + { + try { + nvobj::transaction::run(pop, [&] { + r->l = nvobj::make_persistent(5U); + r->lo = nvobj::make_persistent(5U); + }); + for (int i = 1; i <= 3; ++i) { + r->l->push_back(i); + r->lo->push_back(i); + } + + nvobj::transaction::run(pop, [&] { + r->l2 = nvobj::make_persistent( + std::move(*r->l)); + }); + UT_ASSERT(*r->l2 == *r->lo); + UT_ASSERT(r->l->empty()); + + nvobj::transaction::run(pop, [&] { + nvobj::delete_persistent(r->l); + nvobj::delete_persistent(r->lo); + nvobj::delete_persistent(r->l2); + }); + } catch (std::exception &e) { + UT_FATALexc(e); + } + } + { + int a1[] = {1, 3, 7, 9, 10}; + try { + nvobj::transaction::run(pop, [&] { + r->c1 = nvobj::make_persistent( + a1, a1 + sizeof(a1) / sizeof(a1[0])); + }); + + C2::const_iterator i = r->c1->begin(); + + nvobj::transaction::run(pop, [&] { + r->c2 = nvobj::make_persistent( + std::move(*r->c1)); + }); + + C2::iterator j = r->c2->erase(i); + UT_ASSERT(*j == 3); + + nvobj::transaction::run(pop, [&] { + nvobj::delete_persistent(r->c1); + nvobj::delete_persistent(r->c2); + }); + } catch (std::exception &e) { + UT_FATALexc(e); + } + } + + pop.close(); + + return 0; +} diff --git a/tests/external/libcxx/vector/vector.cons/op_equal_initializer_list.pass.cpp b/tests/external/libcxx/vector/vector.cons/op_equal_initializer_list.pass.cpp new file mode 100644 index 0000000..3e619a7 --- /dev/null +++ b/tests/external/libcxx/vector/vector.cons/op_equal_initializer_list.pass.cpp @@ -0,0 +1,64 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// Copyright 2019, Intel Corporation +// +// Modified to test pmem::obj containers +// + +#include "unittest.hpp" + +#include +#include + +namespace nvobj = pmem::obj; +namespace pmem_exp = nvobj::experimental; +using C = pmem_exp::vector; + +struct root { + nvobj::persistent_ptr d; +}; + +int +main(int argc, char *argv[]) +{ + START(); + + if (argc < 2) { + std::cerr << "usage: " << argv[0] << " file-name" << std::endl; + return 1; + } + auto path = argv[1]; + auto pop = nvobj::pool::create( + path, "VectorTest: op_equal_initializer_list.pass", + PMEMOBJ_MIN_POOL, S_IWUSR | S_IRUSR); + + auto r = pop.root(); + + try { + nvobj::transaction::run( + pop, [&] { r->d = nvobj::make_persistent(); }); + *r->d = {3, 4, 5, 6}; + + UT_ASSERT(r->d->size() == 4); + UT_ASSERT((*r->d)[0] == 3); + UT_ASSERT((*r->d)[1] == 4); + UT_ASSERT((*r->d)[2] == 5); + UT_ASSERT((*r->d)[3] == 6); + + nvobj::transaction::run( + pop, [&] { nvobj::delete_persistent(r->d); }); + } catch (std::exception &e) { + UT_FATALexc(e); + } + + pop.close(); + + return 0; +} diff --git a/tests/external/libcxx/vector/vector.data/data.pass.cpp b/tests/external/libcxx/vector/vector.data/data.pass.cpp new file mode 100644 index 0000000..3826dd7 --- /dev/null +++ b/tests/external/libcxx/vector/vector.data/data.pass.cpp @@ -0,0 +1,63 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// Copyright 2019, Intel Corporation +// +// Modified to test pmem::obj containers +// + +#include "unittest.hpp" + +#include +#include + +namespace nvobj = pmem::obj; +namespace pmem_exp = nvobj::experimental; +using vector_type = pmem_exp::vector; + +struct root { + nvobj::persistent_ptr v1; + nvobj::persistent_ptr v2; +}; + +int +main(int argc, char *argv[]) +{ + START(); + + if (argc < 2) { + std::cerr << "usage: " << argv[0] << " file-name" << std::endl; + return 1; + } + + auto path = argv[1]; + auto pop = + nvobj::pool::create(path, "VectorTest: data.pass", + PMEMOBJ_MIN_POOL, S_IWUSR | S_IRUSR); + + auto r = pop.root(); + + try { + nvobj::transaction::run(pop, [&] { + r->v1 = nvobj::make_persistent(); + r->v2 = nvobj::make_persistent(100U); + UT_ASSERT(r->v1->data() == 0); + UT_ASSERT(r->v2->data() == + std::addressof(r->v2->front())); + nvobj::delete_persistent(r->v1); + nvobj::delete_persistent(r->v2); + }); + } catch (std::exception &e) { + UT_FATALexc(e); + } + + pop.close(); + + return 0; +} diff --git a/tests/external/libcxx/vector/vector.data/data_const.pass.cpp b/tests/external/libcxx/vector/vector.data/data_const.pass.cpp new file mode 100644 index 0000000..f19254d --- /dev/null +++ b/tests/external/libcxx/vector/vector.data/data_const.pass.cpp @@ -0,0 +1,70 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// Copyright 2019, Intel Corporation +// +// Modified to test pmem::obj containers +// + +#include "helper_classes.hpp" +#include "unittest.hpp" + +#include +#include + +namespace nvobj = pmem::obj; +namespace pmem_exp = nvobj::experimental; +using v_type_1 = pmem_exp::vector; +using v_type_2 = pmem_exp::vector; + +struct root { + nvobj::persistent_ptr v1; + nvobj::persistent_ptr v2; + nvobj::persistent_ptr v3; +}; + +int +main(int argc, char *argv[]) +{ + START(); + + if (argc < 2) { + std::cerr << "usage: " << argv[0] << " file-name" << std::endl; + return 1; + } + + auto path = argv[1]; + auto pop = + nvobj::pool::create(path, "VectorTest: data_const.pass", + PMEMOBJ_MIN_POOL, S_IWUSR | S_IRUSR); + + auto r = pop.root(); + + try { + nvobj::transaction::run(pop, [&] { + r->v1 = nvobj::make_persistent(); + r->v2 = nvobj::make_persistent(100U); + r->v3 = nvobj::make_persistent(100U); + }); + UT_ASSERT(r->v1->data() == 0); + UT_ASSERT(r->v2->data() == std::addressof(r->v2->front())); + UT_ASSERT(r->v3->data() == std::addressof(r->v3->front())); + nvobj::transaction::run(pop, [&] { + nvobj::delete_persistent(r->v1); + nvobj::delete_persistent(r->v2); + nvobj::delete_persistent(r->v3); + }); + } catch (std::exception &e) { + UT_FATALexc(e); + } + + pop.close(); + + return 0; +} diff --git a/tests/external/libcxx/vector/vector.modifiers/clear.pass.cpp b/tests/external/libcxx/vector/vector.modifiers/clear.pass.cpp new file mode 100644 index 0000000..128c384 --- /dev/null +++ b/tests/external/libcxx/vector/vector.modifiers/clear.pass.cpp @@ -0,0 +1,65 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// Copyright 2019, Intel Corporation +// +// Modified to test pmem::obj containers +// + +#include "unittest.hpp" + +#include +#include + +namespace nvobj = pmem::obj; +namespace pmem_exp = nvobj::experimental; + +using C = pmem_exp::vector; + +struct root { + nvobj::persistent_ptr v; +}; + +int +main(int argc, char *argv[]) +{ + START(); + + if (argc < 2) { + std::cerr << "usage: " << argv[0] << " file-name" << std::endl; + return 1; + } + + auto path = argv[1]; + auto pop = nvobj::pool::create( + path, "VectorTest: clear", PMEMOBJ_MIN_POOL, S_IWUSR | S_IRUSR); + + auto r = pop.root(); + + int a[] = {1, 2, 3}; + + try { + nvobj::transaction::run(pop, [&] { + r->v = nvobj::make_persistent(a, a + 3); + }); + + r->v->clear(); + UT_ASSERT(r->v->empty()); + + nvobj::transaction::run( + pop, [&] { nvobj::delete_persistent(r->v); }); + + } catch (std::exception &e) { + UT_FATALexc(e); + } + + pop.close(); + + return 0; +} diff --git a/tests/external/libcxx/vector/vector.modifiers/emplace.pass.cpp b/tests/external/libcxx/vector/vector.modifiers/emplace.pass.cpp new file mode 100644 index 0000000..06db4ce --- /dev/null +++ b/tests/external/libcxx/vector/vector.modifiers/emplace.pass.cpp @@ -0,0 +1,123 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// Copyright 2019, Intel Corporation +// +// Modified to test pmem::obj containers +// + +#include "unittest.hpp" + +#include +#include + +namespace nvobj = pmem::obj; +namespace pmem_exp = nvobj::experimental; + +class A; + +using C = pmem_exp::vector; + +struct root { + nvobj::persistent_ptr c; +}; + +class A { + int64_t i_; + double d_; + + A(const A &); + A &operator=(const A &); + +public: + A(int64_t i, double d) : i_(i), d_(d) + { + } + + A(A &&a) : i_(a.i_), d_(a.d_) + { + a.i_ = 0; + a.d_ = 0; + } + + A & + operator=(A &&a) + { + i_ = a.i_; + d_ = a.d_; + a.i_ = 0; + a.d_ = 0; + return *this; + } + + int + geti() const + { + return i_; + } + double + getd() const + { + return d_; + } +}; + +int +main(int argc, char *argv[]) +{ + START(); + + if (argc < 2) { + std::cerr << "usage: " << argv[0] << " file-name" << std::endl; + return 1; + } + + auto path = argv[1]; + auto pop = + nvobj::pool::create(path, "VectorTest: emplace", + PMEMOBJ_MIN_POOL, S_IWUSR | S_IRUSR); + + auto r = pop.root(); + + try { + nvobj::transaction::run( + pop, [&] { r->c = nvobj::make_persistent(); }); + + C::iterator i = r->c->emplace(r->c->cbegin(), (int64_t)2, 3.5); + UT_ASSERT(i == r->c->begin()); + UT_ASSERT(r->c->size() == 1); + UT_ASSERT(r->c->front().geti() == 2); + UT_ASSERT(r->c->front().getd() == 3.5); + i = r->c->emplace(r->c->cend(), (int64_t)3, 4.5); + UT_ASSERT(i == r->c->end() - 1); + UT_ASSERT(r->c->size() == 2); + UT_ASSERT(r->c->front().geti() == 2); + UT_ASSERT(r->c->front().getd() == 3.5); + UT_ASSERT(r->c->back().geti() == 3); + UT_ASSERT(r->c->back().getd() == 4.5); + i = r->c->emplace(r->c->cbegin() + 1, (int64_t)4, 6.5); + UT_ASSERT(i == r->c->begin() + 1); + UT_ASSERT(r->c->size() == 3); + UT_ASSERT(r->c->front().geti() == 2); + UT_ASSERT(r->c->front().getd() == 3.5); + UT_ASSERT((*r->c)[1].geti() == 4); + UT_ASSERT((*r->c)[1].getd() == 6.5); + UT_ASSERT(r->c->back().geti() == 3); + UT_ASSERT(r->c->back().getd() == 4.5); + + nvobj::transaction::run( + pop, [&] { nvobj::delete_persistent(r->c); }); + } catch (std::exception &e) { + UT_FATALexc(e); + } + + pop.close(); + + return 0; +} diff --git a/tests/external/libcxx/vector/vector.modifiers/emplace_back.pass.cpp b/tests/external/libcxx/vector/vector.modifiers/emplace_back.pass.cpp new file mode 100644 index 0000000..ded7ef9 --- /dev/null +++ b/tests/external/libcxx/vector/vector.modifiers/emplace_back.pass.cpp @@ -0,0 +1,112 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// Copyright 2019, Intel Corporation +// +// Modified to test pmem::obj containers +// + +#include "unittest.hpp" + +#include +#include + +namespace nvobj = pmem::obj; +namespace pmem_exp = nvobj::experimental; + +class A; + +using C = pmem_exp::vector; + +struct root { + nvobj::persistent_ptr c; +}; + +class A { + int64_t i_; + double d_; + + A(const A &); + A &operator=(const A &); + +public: + A(int64_t i, double d) : i_(i), d_(d) + { + } + + A(A &&a) : i_(a.i_), d_(a.d_) + { + a.i_ = 0; + a.d_ = 0; + } + + A & + operator=(A &&a) + { + i_ = a.i_; + d_ = a.d_; + a.i_ = 0; + a.d_ = 0; + return *this; + } + + int + geti() const + { + return i_; + } + double + getd() const + { + return d_; + } +}; + +int +main(int argc, char *argv[]) +{ + START(); + + if (argc < 2) { + std::cerr << "usage: " << argv[0] << " file-name" << std::endl; + return 1; + } + + auto path = argv[1]; + auto pop = + nvobj::pool::create(path, "VectorTest: emplace_back", + PMEMOBJ_MIN_POOL, S_IWUSR | S_IRUSR); + + auto r = pop.root(); + + try { + nvobj::transaction::run( + pop, [&] { r->c = nvobj::make_persistent(); }); + + r->c->emplace_back((int64_t)2, 3.5); + UT_ASSERT(r->c->size() == 1); + UT_ASSERT(r->c->front().geti() == 2); + UT_ASSERT(r->c->front().getd() == 3.5); + r->c->emplace_back((int64_t)3, 4.5); + UT_ASSERT(r->c->size() == 2); + UT_ASSERT(r->c->front().geti() == 2); + UT_ASSERT(r->c->front().getd() == 3.5); + UT_ASSERT(r->c->back().geti() == 3); + UT_ASSERT(r->c->back().getd() == 4.5); + + nvobj::transaction::run( + pop, [&] { nvobj::delete_persistent(r->c); }); + } catch (std::exception &e) { + UT_FATALexc(e); + } + + pop.close(); + + return 0; +} diff --git a/tests/external/libcxx/vector/vector.modifiers/emplace_extra.pass.cpp b/tests/external/libcxx/vector/vector.modifiers/emplace_extra.pass.cpp new file mode 100644 index 0000000..95e2ee6 --- /dev/null +++ b/tests/external/libcxx/vector/vector.modifiers/emplace_extra.pass.cpp @@ -0,0 +1,85 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// Copyright 2019, Intel Corporation +// +// Modified to test pmem::obj containers +// + +#include "unittest.hpp" + +#include +#include + +namespace nvobj = pmem::obj; +namespace pmem_exp = nvobj::experimental; + +using C = pmem_exp::vector; + +struct root { + nvobj::persistent_ptr v; +}; + +int +main(int argc, char *argv[]) +{ + START(); + + if (argc < 2) { + std::cerr << "usage: " << argv[0] << " file-name" << std::endl; + return 1; + } + + auto path = argv[1]; + auto pop = + nvobj::pool::create(path, "VectorTest: emplace_extra", + PMEMOBJ_MIN_POOL, S_IWUSR | S_IRUSR); + + auto r = pop.root(); + { + try { + nvobj::transaction::run(pop, [&] { + r->v = nvobj::make_persistent(); + }); + + r->v->reserve(3); + *r->v = {1, 2, 3}; + r->v->emplace(r->v->begin(), r->v->back()); + UT_ASSERT((*r->v)[0] == 3); + + nvobj::transaction::run(pop, [&] { + nvobj::delete_persistent(r->v); + }); + } catch (std::exception &e) { + UT_FATALexc(e); + } + } + { + try { + nvobj::transaction::run(pop, [&] { + r->v = nvobj::make_persistent(); + }); + + r->v->reserve(4); + *r->v = {1, 2, 3}; + r->v->emplace(r->v->begin(), r->v->back()); + UT_ASSERTeq((*r->v)[0], 3); + + nvobj::transaction::run(pop, [&] { + nvobj::delete_persistent(r->v); + }); + } catch (std::exception &e) { + UT_FATALexc(e); + } + } + + pop.close(); + + return 0; +} diff --git a/tests/external/libcxx/vector/vector.modifiers/erase_iter.pass.cpp b/tests/external/libcxx/vector/vector.modifiers/erase_iter.pass.cpp new file mode 100644 index 0000000..b55c0a9 --- /dev/null +++ b/tests/external/libcxx/vector/vector.modifiers/erase_iter.pass.cpp @@ -0,0 +1,141 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// Copyright 2019, Intel Corporation +// +// Modified to test pmem::obj containers +// + +#include "unittest.hpp" + +#include +#include + +#include + +namespace nvobj = pmem::obj; +namespace pmem_exp = nvobj::experimental; + +struct Throws; + +using C = pmem_exp::vector; +using C2 = pmem_exp::vector; +using std::distance; +using std::next; + +struct root { + nvobj::persistent_ptr l1; + nvobj::persistent_ptr v; +}; + +struct Throws { + Throws() : v_(0) + { + } + Throws(int v) : v_(v) + { + } + Throws(const Throws &rhs) : v_(rhs.v_) + { + if (sThrows) + throw 1; + } + Throws(Throws &&rhs) : v_(rhs.v_) + { + if (sThrows) + throw 1; + } + Throws & + operator=(const Throws &rhs) + { + v_ = rhs.v_; + return *this; + } + Throws & + operator=(Throws &&rhs) + { + v_ = rhs.v_; + return *this; + } + int v_; + static bool sThrows; +}; + +bool Throws::sThrows = false; + +int +main(int argc, char *argv[]) +{ + START(); + + if (argc < 2) { + std::cerr << "usage: " << argv[0] << " file-name" << std::endl; + return 1; + } + + auto path = argv[1]; + auto pop = + nvobj::pool::create(path, "VectorTest: erase_iter", + PMEMOBJ_MIN_POOL, S_IWUSR | S_IRUSR); + + auto r = pop.root(); + { + int a1[] = {1, 2, 3}; + try { + nvobj::transaction::run(pop, [&] { + r->l1 = nvobj::make_persistent(a1, a1 + 3); + }); + C::const_iterator i = r->l1->begin(); + ++i; + C::iterator j = r->l1->erase(i); + UT_ASSERT(r->l1->size() == 2); + UT_ASSERT(distance(r->l1->begin(), r->l1->end()) == 2); + UT_ASSERT(*j == 3); + UT_ASSERT(*r->l1->begin() == 1); + UT_ASSERT(*std::next(r->l1->begin()) == 3); + j = r->l1->erase(j); + UT_ASSERT(j == r->l1->end()); + UT_ASSERT(r->l1->size() == 1); + UT_ASSERT(distance(r->l1->begin(), r->l1->end()) == 1); + UT_ASSERT(*r->l1->begin() == 1); + j = r->l1->erase(r->l1->begin()); + UT_ASSERT(j == r->l1->end()); + UT_ASSERT(r->l1->size() == 0); + UT_ASSERT(distance(r->l1->begin(), r->l1->end()) == 0); + + nvobj::transaction::run(pop, [&] { + nvobj::delete_persistent(r->l1); + }); + } catch (std::exception &e) { + UT_FATALexc(e); + } + } + { + Throws arr[] = {1, 2, 3}; + try { + nvobj::transaction::run(pop, [&] { + r->v = nvobj::make_persistent(arr, arr + 3); + }); + Throws::sThrows = true; + r->v->erase(r->v->begin()); + r->v->erase(--r->v->end()); + r->v->erase(r->v->begin()); + UT_ASSERT(r->v->size() == 0); + nvobj::transaction::run(pop, [&] { + nvobj::delete_persistent(r->v); + }); + } catch (std::exception &e) { + UT_FATALexc(e); + } + } + + pop.close(); + + return 0; +} diff --git a/tests/external/libcxx/vector/vector.modifiers/erase_iter_iter.pass.cpp b/tests/external/libcxx/vector/vector.modifiers/erase_iter_iter.pass.cpp new file mode 100644 index 0000000..2938200 --- /dev/null +++ b/tests/external/libcxx/vector/vector.modifiers/erase_iter_iter.pass.cpp @@ -0,0 +1,230 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// Copyright 2019, Intel Corporation +// +// Modified to test pmem::obj containers +// + +#include "unittest.hpp" + +#include +#include + +#include + +namespace nvobj = pmem::obj; +namespace pmem_exp = nvobj::experimental; + +struct Throws; + +using C = pmem_exp::vector; +using C2 = pmem_exp::vector; +using C3 = pmem_exp::vector; +using std::distance; +using std::next; + +struct root { + nvobj::persistent_ptr l1; + nvobj::persistent_ptr v; + nvobj::persistent_ptr outer; +}; + +struct Throws { + Throws() : v_(0) + { + } + Throws(int v) : v_(v) + { + } + Throws(const Throws &rhs) : v_(rhs.v_) + { + if (sThrows) + throw 1; + } + Throws(Throws &&rhs) : v_(rhs.v_) + { + if (sThrows) + throw 1; + } + Throws & + operator=(const Throws &rhs) + { + v_ = rhs.v_; + return *this; + } + Throws & + operator=(Throws &&rhs) + { + v_ = rhs.v_; + return *this; + } + int v_; + static bool sThrows; +}; + +bool Throws::sThrows = false; + +int +main(int argc, char *argv[]) +{ + START(); + + if (argc < 2) { + std::cerr << "usage: " << argv[0] << " file-name" << std::endl; + return 1; + } + + auto path = argv[1]; + auto pop = + nvobj::pool::create(path, "VectorTest: erase_iter_iter", + PMEMOBJ_MIN_POOL, S_IWUSR | S_IRUSR); + + auto r = pop.root(); + { + int a1[] = {1, 2, 3}; + { + try { + nvobj::transaction::run(pop, [&] { + r->l1 = nvobj::make_persistent( + a1, a1 + 3); + }); + C::iterator i = r->l1->erase(r->l1->cbegin(), + r->l1->cbegin()); + UT_ASSERT(r->l1->size() == 3); + UT_ASSERT(distance(r->l1->cbegin(), + r->l1->cend()) == 3); + UT_ASSERT(i == r->l1->begin()); + nvobj::transaction::run(pop, [&] { + nvobj::delete_persistent(r->l1); + }); + } catch (std::exception &e) { + UT_FATALexc(e); + } + } + { + try { + nvobj::transaction::run(pop, [&] { + r->l1 = nvobj::make_persistent( + a1, a1 + 3); + }); + C::iterator i = r->l1->erase( + r->l1->cbegin(), next(r->l1->cbegin())); + UT_ASSERTeq(r->l1->size(), 2); + UT_ASSERT(distance(r->l1->cbegin(), + r->l1->cend()) == 2); + UT_ASSERT(i == r->l1->begin()); + + nvobj::transaction::run(pop, [&] { + nvobj::persistent_ptr tmp = + nvobj::make_persistent( + a1 + 1, a1 + 3); + UT_ASSERT(*r->l1 == *tmp); + nvobj::delete_persistent(tmp); + }); + nvobj::transaction::run(pop, [&] { + nvobj::delete_persistent(r->l1); + }); + } catch (std::exception &e) { + UT_FATALexc(e); + } + } + { + try { + nvobj::transaction::run(pop, [&] { + r->l1 = nvobj::make_persistent( + a1, a1 + 3); + }); + C::iterator i = + r->l1->erase(r->l1->cbegin(), + next(r->l1->cbegin(), 2)); + UT_ASSERT(r->l1->size() == 1); + UT_ASSERT(distance(r->l1->cbegin(), + r->l1->cend()) == 1); + UT_ASSERT(i == r->l1->begin()); + + nvobj::transaction::run(pop, [&] { + nvobj::persistent_ptr tmp = + nvobj::make_persistent( + a1 + 2, a1 + 3); + UT_ASSERT(*r->l1 == *tmp); + nvobj::delete_persistent(tmp); + }); + nvobj::transaction::run(pop, [&] { + nvobj::delete_persistent(r->l1); + }); + } catch (std::exception &e) { + UT_FATALexc(e); + } + } + { + try { + nvobj::transaction::run(pop, [&] { + r->l1 = nvobj::make_persistent( + a1, a1 + 3); + }); + C::iterator i = + r->l1->erase(r->l1->cbegin(), + next(r->l1->cbegin(), 3)); + UT_ASSERT(r->l1->size() == 0); + UT_ASSERT(distance(r->l1->cbegin(), + r->l1->cend()) == 0); + UT_ASSERT(i == r->l1->begin()); + nvobj::transaction::run(pop, [&] { + nvobj::delete_persistent(r->l1); + }); + } catch (std::exception &e) { + UT_FATALexc(e); + } + } + { + try { + nvobj::persistent_ptr tmp; + nvobj::transaction::run(pop, [&] { + tmp = nvobj::make_persistent(1U); + r->outer = nvobj::make_persistent( + 2U, *tmp); + }); + r->outer->erase(r->outer->begin(), + r->outer->begin()); + UT_ASSERT(r->outer->size() == 2); + UT_ASSERT((*r->outer)[0].size() == 1); + UT_ASSERT((*r->outer)[1].size() == 1); + nvobj::transaction::run(pop, [&] { + nvobj::delete_persistent(tmp); + nvobj::delete_persistent(r->outer); + }); + } catch (std::exception &e) { + UT_FATALexc(e); + } + } + } + { + Throws arr[] = {1, 2, 3}; + try { + nvobj::transaction::run(pop, [&] { + r->v = nvobj::make_persistent(arr, arr + 3); + }); + Throws::sThrows = true; + r->v->erase(r->v->begin(), --r->v->end()); + UT_ASSERT(r->v->size() == 1); + r->v->erase(r->v->begin(), r->v->end()); + UT_ASSERT(r->v->size() == 0); + nvobj::transaction::run(pop, [&] { + nvobj::delete_persistent(r->v); + }); + } catch (std::exception &e) { + UT_FATALexc(e); + } + } + + pop.close(); + + return 0; +} diff --git a/tests/external/libcxx/vector/vector.modifiers/insert_iter_initializer_list.pass.cpp b/tests/external/libcxx/vector/vector.modifiers/insert_iter_initializer_list.pass.cpp new file mode 100644 index 0000000..0127025 --- /dev/null +++ b/tests/external/libcxx/vector/vector.modifiers/insert_iter_initializer_list.pass.cpp @@ -0,0 +1,77 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// Copyright 2019, Intel Corporation +// +// Modified to test pmem::obj containers +// + +#include "unittest.hpp" + +#include +#include + +namespace nvobj = pmem::obj; +namespace pmem_exp = nvobj::experimental; + +struct Throws; + +using C = pmem_exp::vector; + +struct root { + nvobj::persistent_ptr d; +}; + +int +main(int argc, char *argv[]) +{ + START(); + + if (argc < 2) { + std::cerr << "usage: " << argv[0] << " file-name" << std::endl; + return 1; + } + + auto path = argv[1]; + auto pop = nvobj::pool::create( + path, "VectorTest: insert_iter_initializer_list", + PMEMOBJ_MIN_POOL, S_IWUSR | S_IRUSR); + + auto r = pop.root(); + + try { + nvobj::transaction::run( + pop, [&] { r->d = nvobj::make_persistent(10U, 1); }); + C::iterator i = r->d->insert(r->d->cbegin() + 2, {3, 4, 5, 6}); + UT_ASSERT(r->d->size() == 14); + UT_ASSERT(i == r->d->begin() + 2); + UT_ASSERT((*r->d)[0] == 1); + UT_ASSERT((*r->d)[1] == 1); + UT_ASSERT((*r->d)[2] == 3); + UT_ASSERT((*r->d)[3] == 4); + UT_ASSERT((*r->d)[4] == 5); + UT_ASSERT((*r->d)[5] == 6); + UT_ASSERT((*r->d)[6] == 1); + UT_ASSERT((*r->d)[7] == 1); + UT_ASSERT((*r->d)[8] == 1); + UT_ASSERT((*r->d)[9] == 1); + UT_ASSERT((*r->d)[10] == 1); + UT_ASSERT((*r->d)[11] == 1); + UT_ASSERT((*r->d)[12] == 1); + UT_ASSERT((*r->d)[13] == 1); + nvobj::transaction::run( + pop, [&] { nvobj::delete_persistent(r->d); }); + } catch (std::exception &e) { + UT_FATALexc(e); + } + + pop.close(); + + return 0; +} diff --git a/tests/external/libcxx/vector/vector.modifiers/insert_iter_iter_iter.pass.cpp b/tests/external/libcxx/vector/vector.modifiers/insert_iter_iter_iter.pass.cpp new file mode 100644 index 0000000..09b66b8 --- /dev/null +++ b/tests/external/libcxx/vector/vector.modifiers/insert_iter_iter_iter.pass.cpp @@ -0,0 +1,166 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// Copyright 2019, Intel Corporation +// +// Modified to test pmem::obj containers +// + +#include "iterators_support.hpp" +#include "unittest.hpp" + +#include +#include + +namespace nvobj = pmem::obj; +namespace pmem_exp = nvobj::experimental; + +struct Throws; + +using C = pmem_exp::vector; + +struct root { + nvobj::persistent_ptr v; +}; + +int +main(int argc, char *argv[]) +{ + START(); + + if (argc < 2) { + std::cerr << "usage: " << argv[0] << " file-name" << std::endl; + return 1; + } + + auto path = argv[1]; + auto pop = nvobj::pool::create( + path, "VectorTest: insert_iter_iter_iter", PMEMOBJ_MIN_POOL, + S_IWUSR | S_IRUSR); + + auto r = pop.root(); + + { + try { + nvobj::transaction::run(pop, [&] { + r->v = nvobj::make_persistent(100U); + }); + int a[] = {1, 2, 3, 4, 5}; + const int N = sizeof(a) / sizeof(a[0]); + C::iterator i = r->v->insert( + r->v->cbegin() + 10, + test_support::input_it(a), + test_support::input_it(a + N)); + UT_ASSERT(r->v->size() == 100 + N); + UT_ASSERT(i == r->v->begin() + 10); + unsigned j; + for (j = 0; j < 10; ++j) + UT_ASSERT((*r->v)[j] == 0); + for (std::size_t k = 0; k < N; ++j, ++k) + UT_ASSERT((*r->v)[j] == a[k]); + for (; j < 105; ++j) + UT_ASSERT((*r->v)[j] == 0); + nvobj::transaction::run(pop, [&] { + nvobj::delete_persistent(r->v); + }); + } catch (std::exception &e) { + UT_FATALexc(e); + } + } + { + try { + nvobj::transaction::run(pop, [&] { + r->v = nvobj::make_persistent(100U); + }); + int a[] = {1, 2, 3, 4, 5}; + const int N = sizeof(a) / sizeof(a[0]); + C::iterator i = r->v->insert( + r->v->cbegin() + 10, + test_support::forward_it(a), + test_support::forward_it(a + N)); + UT_ASSERT(r->v->size() == 100 + N); + UT_ASSERT(i == r->v->begin() + 10); + unsigned j; + for (j = 0; j < 10; ++j) + UT_ASSERT((*r->v)[j] == 0); + for (std::size_t k = 0; k < N; ++j, ++k) + UT_ASSERT((*r->v)[j] == a[k]); + for (; j < 105; ++j) + UT_ASSERT((*r->v)[j] == 0); + nvobj::transaction::run(pop, [&] { + nvobj::delete_persistent(r->v); + }); + } catch (std::exception &e) { + UT_FATALexc(e); + } + } + { + try { + nvobj::transaction::run(pop, [&] { + r->v = nvobj::make_persistent(100U); + }); + while (r->v->size() < r->v->capacity()) + r->v->push_back(0); // force reallocation + size_t sz = r->v->size(); + int a[] = {1, 2, 3, 4, 5}; + const int N = sizeof(a) / sizeof(a[0]); + C::iterator i = r->v->insert( + r->v->cbegin() + 10, + test_support::forward_it(a), + test_support::forward_it(a + N)); + UT_ASSERT(r->v->size() == sz + N); + UT_ASSERT(i == r->v->begin() + 10); + std::size_t j; + for (j = 0; j < 10; ++j) + UT_ASSERT((*r->v)[j] == 0); + for (std::size_t k = 0; k < N; ++j, ++k) + UT_ASSERT((*r->v)[j] == a[k]); + for (; j < r->v->size(); ++j) + UT_ASSERT((*r->v)[j] == 0); + nvobj::transaction::run(pop, [&] { + nvobj::delete_persistent(r->v); + }); + } catch (std::exception &e) { + UT_FATALexc(e); + } + } + { + try { + nvobj::transaction::run(pop, [&] { + r->v = nvobj::make_persistent(100U); + }); + r->v->reserve(128); // force no reallocation + size_t sz = r->v->size(); + int a[] = {1, 2, 3, 4, 5}; + const int N = sizeof(a) / sizeof(a[0]); + C::iterator i = r->v->insert( + r->v->cbegin() + 10, + test_support::forward_it(a), + test_support::forward_it(a + N)); + UT_ASSERT(r->v->size() == sz + N); + UT_ASSERT(i == r->v->begin() + 10); + std::size_t j; + for (j = 0; j < 10; ++j) + UT_ASSERT((*r->v)[j] == 0); + for (std::size_t k = 0; k < N; ++j, ++k) + UT_ASSERT((*r->v)[j] == a[k]); + for (; j < r->v->size(); ++j) + UT_ASSERT((*r->v)[j] == 0); + nvobj::transaction::run(pop, [&] { + nvobj::delete_persistent(r->v); + }); + } catch (std::exception &e) { + UT_FATALexc(e); + } + } + + pop.close(); + + return 0; +} diff --git a/tests/external/libcxx/vector/vector.modifiers/insert_iter_rvalue.pass.cpp b/tests/external/libcxx/vector/vector.modifiers/insert_iter_rvalue.pass.cpp new file mode 100644 index 0000000..cd1c977 --- /dev/null +++ b/tests/external/libcxx/vector/vector.modifiers/insert_iter_rvalue.pass.cpp @@ -0,0 +1,68 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// Copyright 2019, Intel Corporation +// +// Modified to test pmem::obj containers +// + +#include "helper_classes.hpp" +#include "unittest.hpp" + +#include +#include + +namespace nvobj = pmem::obj; +namespace pmem_exp = nvobj::experimental; + +using C = pmem_exp::vector; + +struct root { + nvobj::persistent_ptr v; +}; + +int +main(int argc, char *argv[]) +{ + START(); + + if (argc < 2) { + std::cerr << "usage: " << argv[0] << " file-name" << std::endl; + return 1; + } + + auto path = argv[1]; + auto pop = nvobj::pool::create( + path, "VectorTest: insert_iter_rvalue", PMEMOBJ_MIN_POOL, + S_IWUSR | S_IRUSR); + + auto r = pop.root(); + + try { + nvobj::transaction::run( + pop, [&] { r->v = nvobj::make_persistent(100U); }); + C::iterator i = r->v->insert(r->v->cbegin() + 10, move_only(3)); + UT_ASSERT(r->v->size() == 101); + UT_ASSERT(i == r->v->begin() + 10); + unsigned j; + for (j = 0; j < 10; ++j) + UT_ASSERT((*r->v)[j] == move_only()); + UT_ASSERT((*r->v)[j] == move_only(3)); + for (++j; j < 101; ++j) + UT_ASSERT((*r->v)[j] == move_only()); + nvobj::transaction::run( + pop, [&] { nvobj::delete_persistent(r->v); }); + } catch (std::exception &e) { + UT_FATALexc(e); + } + + pop.close(); + + return 0; +} diff --git a/tests/external/libcxx/vector/vector.modifiers/insert_iter_size_value.pass.cpp b/tests/external/libcxx/vector/vector.modifiers/insert_iter_size_value.pass.cpp new file mode 100644 index 0000000..57c8a3d --- /dev/null +++ b/tests/external/libcxx/vector/vector.modifiers/insert_iter_size_value.pass.cpp @@ -0,0 +1,121 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// Copyright 2019, Intel Corporation +// +// Modified to test pmem::obj containers +// + +#include "unittest.hpp" + +#include +#include + +namespace nvobj = pmem::obj; +namespace pmem_exp = nvobj::experimental; + +using C = pmem_exp::vector; + +struct root { + nvobj::persistent_ptr v; +}; + +int +main(int argc, char *argv[]) +{ + START(); + + if (argc < 2) { + std::cerr << "usage: " << argv[0] << " file-name" << std::endl; + return 1; + } + + auto path = argv[1]; + auto pop = nvobj::pool::create( + path, "VectorTest: insert_iter_size_value", PMEMOBJ_MIN_POOL, + S_IWUSR | S_IRUSR); + + auto r = pop.root(); + + { + try { + nvobj::transaction::run(pop, [&] { + r->v = nvobj::make_persistent(100U); + }); + C::iterator i = r->v->insert(r->v->cbegin() + 10, 5, 1); + UT_ASSERT(r->v->size() == 105); + UT_ASSERT(i == r->v->begin() + 10); + unsigned j; + for (j = 0; j < 10; ++j) + UT_ASSERT((*r->v)[j] == 0); + for (; j < 15; ++j) + UT_ASSERT((*r->v)[j] == 1); + for (++j; j < 105; ++j) + UT_ASSERT((*r->v)[j] == 0); + nvobj::transaction::run(pop, [&] { + nvobj::delete_persistent(r->v); + }); + } catch (std::exception &e) { + UT_FATALexc(e); + } + } + { + try { + nvobj::transaction::run(pop, [&] { + r->v = nvobj::make_persistent(100U); + }); + while (r->v->size() < r->v->capacity()) + r->v->push_back(0); // force reallocation + size_t sz = r->v->size(); + C::iterator i = r->v->insert(r->v->cbegin() + 10, 5, 1); + UT_ASSERT(r->v->size() == sz + 5); + UT_ASSERT(i == r->v->begin() + 10); + std::size_t j; + for (j = 0; j < 10; ++j) + UT_ASSERT((*r->v)[j] == 0); + for (; j < 15; ++j) + UT_ASSERT((*r->v)[j] == 1); + for (++j; j < r->v->size(); ++j) + UT_ASSERT((*r->v)[j] == 0); + nvobj::transaction::run(pop, [&] { + nvobj::delete_persistent(r->v); + }); + } catch (std::exception &e) { + UT_FATALexc(e); + } + } + { + try { + nvobj::transaction::run(pop, [&] { + r->v = nvobj::make_persistent(100U); + }); + r->v->reserve(128); // force no reallocation + size_t sz = r->v->size(); + C::iterator i = r->v->insert(r->v->cbegin() + 10, 5, 1); + UT_ASSERT(r->v->size() == sz + 5); + UT_ASSERT(i == r->v->begin() + 10); + std::size_t j; + for (j = 0; j < 10; ++j) + UT_ASSERT((*r->v)[j] == 0); + for (; j < 15; ++j) + UT_ASSERT((*r->v)[j] == 1); + for (++j; j < r->v->size(); ++j) + UT_ASSERT((*r->v)[j] == 0); + nvobj::transaction::run(pop, [&] { + nvobj::delete_persistent(r->v); + }); + } catch (std::exception &e) { + UT_FATALexc(e); + } + } + + pop.close(); + + return 0; +} diff --git a/tests/external/libcxx/vector/vector.modifiers/insert_iter_value.pass.cpp b/tests/external/libcxx/vector/vector.modifiers/insert_iter_value.pass.cpp new file mode 100644 index 0000000..939422c --- /dev/null +++ b/tests/external/libcxx/vector/vector.modifiers/insert_iter_value.pass.cpp @@ -0,0 +1,121 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// Copyright 2019, Intel Corporation +// +// Modified to test pmem::obj containers +// + +#include "unittest.hpp" + +#include +#include + +namespace nvobj = pmem::obj; +namespace pmem_exp = nvobj::experimental; + +using C = pmem_exp::vector; + +struct root { + nvobj::persistent_ptr v; +}; + +int +main(int argc, char *argv[]) +{ + START(); + + if (argc < 2) { + std::cerr << "usage: " << argv[0] << " file-name" << std::endl; + return 1; + } + + auto path = argv[1]; + auto pop = + nvobj::pool::create(path, "VectorTest: insert_iter_value", + PMEMOBJ_MIN_POOL, S_IWUSR | S_IRUSR); + + auto r = pop.root(); + + { + try { + nvobj::transaction::run(pop, [&] { + r->v = nvobj::make_persistent(100U); + }); + C::iterator i = r->v->insert(r->v->cbegin() + 10, 1); + UT_ASSERT(r->v->size() == 101); + UT_ASSERT(i == r->v->begin() + 10); + unsigned j; + for (j = 0; j < 10; ++j) + UT_ASSERT((*r->v)[j] == 0); + UT_ASSERT((*r->v)[j] == 1); + for (++j; j < 101; ++j) + UT_ASSERT((*r->v)[j] == 0); + nvobj::transaction::run(pop, [&] { + nvobj::delete_persistent(r->v); + }); + } catch (std::exception &e) { + UT_FATALexc(e); + } + } + { + try { + nvobj::transaction::run(pop, [&] { + r->v = nvobj::make_persistent(100U); + }); + while (r->v->size() < r->v->capacity()) + r->v->push_back(0); // force reallocation + size_t sz = r->v->size(); + C::iterator i = r->v->insert(r->v->cbegin() + 10, 1); + UT_ASSERT(r->v->size() == sz + 1); + UT_ASSERT(i == r->v->begin() + 10); + std::size_t j; + for (j = 0; j < 10; ++j) + UT_ASSERT((*r->v)[j] == 0); + UT_ASSERT((*r->v)[j] == 1); + for (++j; j < r->v->size(); ++j) + UT_ASSERT((*r->v)[j] == 0); + nvobj::transaction::run(pop, [&] { + nvobj::delete_persistent(r->v); + }); + } catch (std::exception &e) { + UT_FATALexc(e); + } + } + { + try { + nvobj::transaction::run(pop, [&] { + r->v = nvobj::make_persistent(100U); + }); + while (r->v->size() < r->v->capacity()) + r->v->push_back(0); + r->v->pop_back(); + r->v->pop_back(); // force no reallocation + size_t sz = r->v->size(); + C::iterator i = r->v->insert(r->v->cbegin() + 10, 1); + UT_ASSERT(r->v->size() == sz + 1); + UT_ASSERT(i == r->v->begin() + 10); + std::size_t j; + for (j = 0; j < 10; ++j) + UT_ASSERT((*r->v)[j] == 0); + UT_ASSERT((*r->v)[j] == 1); + for (++j; j < r->v->size(); ++j) + UT_ASSERT((*r->v)[j] == 0); + nvobj::transaction::run(pop, [&] { + nvobj::delete_persistent(r->v); + }); + } catch (std::exception &e) { + UT_FATALexc(e); + } + } + + pop.close(); + + return 0; +} diff --git a/tests/external/libcxx/vector/vector.modifiers/pop_back.pass.cpp b/tests/external/libcxx/vector/vector.modifiers/pop_back.pass.cpp new file mode 100644 index 0000000..acc1261 --- /dev/null +++ b/tests/external/libcxx/vector/vector.modifiers/pop_back.pass.cpp @@ -0,0 +1,62 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// Copyright 2019, Intel Corporation +// +// Modified to test pmem::obj containers +// + +#include "unittest.hpp" + +#include +#include + +namespace nvobj = pmem::obj; +namespace pmem_exp = nvobj::experimental; + +using C = pmem_exp::vector; + +struct root { + nvobj::persistent_ptr c; +}; + +int +main(int argc, char *argv[]) +{ + START(); + + if (argc < 2) { + std::cerr << "usage: " << argv[0] << " file-name" << std::endl; + return 1; + } + + auto path = argv[1]; + auto pop = + nvobj::pool::create(path, "VectorTest: pop_back", + PMEMOBJ_MIN_POOL, S_IWUSR | S_IRUSR); + + auto r = pop.root(); + + try { + nvobj::transaction::run( + pop, [&] { r->c = nvobj::make_persistent(); }); + r->c->push_back(1); + UT_ASSERT(r->c->size() == 1); + r->c->pop_back(); + UT_ASSERT(r->c->size() == 0); + nvobj::transaction::run( + pop, [&] { nvobj::delete_persistent(r->c); }); + } catch (std::exception &e) { + UT_FATALexc(e); + } + + pop.close(); + + return 0; +} diff --git a/tests/external/libcxx/vector/vector.modifiers/push_back.pass.cpp b/tests/external/libcxx/vector/vector.modifiers/push_back.pass.cpp new file mode 100644 index 0000000..3faa942 --- /dev/null +++ b/tests/external/libcxx/vector/vector.modifiers/push_back.pass.cpp @@ -0,0 +1,78 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// Copyright 2019, Intel Corporation +// +// Modified to test pmem::obj containers +// + +#include "unittest.hpp" + +#include +#include + +namespace nvobj = pmem::obj; +namespace pmem_exp = nvobj::experimental; + +using C = pmem_exp::vector; + +struct root { + nvobj::persistent_ptr c; +}; + +int +main(int argc, char *argv[]) +{ + START(); + + if (argc < 2) { + std::cerr << "usage: " << argv[0] << " file-name" << std::endl; + return 1; + } + + auto path = argv[1]; + auto pop = + nvobj::pool::create(path, "VectorTest: push_back", + PMEMOBJ_MIN_POOL, S_IWUSR | S_IRUSR); + + auto r = pop.root(); + + try { + nvobj::transaction::run( + pop, [&] { r->c = nvobj::make_persistent(); }); + r->c->push_back(0); + UT_ASSERT(r->c->size() == 1); + for (int j = 0; static_cast(j) < r->c->size(); ++j) + UT_ASSERT((*r->c)[static_cast(j)] == j); + r->c->push_back(1); + UT_ASSERT(r->c->size() == 2); + for (int j = 0; static_cast(j) < r->c->size(); ++j) + UT_ASSERT((*r->c)[static_cast(j)] == j); + r->c->push_back(2); + UT_ASSERT(r->c->size() == 3); + for (int j = 0; static_cast(j) < r->c->size(); ++j) + UT_ASSERT((*r->c)[static_cast(j)] == j); + r->c->push_back(3); + UT_ASSERT(r->c->size() == 4); + for (int j = 0; static_cast(j) < r->c->size(); ++j) + UT_ASSERT((*r->c)[static_cast(j)] == j); + r->c->push_back(4); + UT_ASSERT(r->c->size() == 5); + for (int j = 0; static_cast(j) < r->c->size(); ++j) + UT_ASSERT((*r->c)[static_cast(j)] == j); + nvobj::transaction::run( + pop, [&] { nvobj::delete_persistent(r->c); }); + } catch (std::exception &e) { + UT_FATALexc(e); + } + + pop.close(); + + return 0; +} diff --git a/tests/external/libcxx/vector/vector.modifiers/push_back_exception_safety.pass.cpp b/tests/external/libcxx/vector/vector.modifiers/push_back_exception_safety.pass.cpp new file mode 100644 index 0000000..eabe029 --- /dev/null +++ b/tests/external/libcxx/vector/vector.modifiers/push_back_exception_safety.pass.cpp @@ -0,0 +1,89 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// + +// void push_back(const value_type& x); + +#include +#include + +#include "asan_testing.h" +#include "test_macros.h" + +// Flag that makes the copy constructor for CMyClass throw an exception +static bool gCopyConstructorShouldThrow = false; + +class CMyClass { + public: CMyClass(int tag); + public: CMyClass(const CMyClass& iOther); + public: ~CMyClass(); + + bool equal(const CMyClass &rhs) const + { return fTag == rhs.fTag && fMagicValue == rhs.fMagicValue; } + private: + int fMagicValue; + int fTag; + + private: static int kStartedConstructionMagicValue; + private: static int kFinishedConstructionMagicValue; +}; + +// Value for fMagicValue when the constructor has started running, but not yet finished +int CMyClass::kStartedConstructionMagicValue = 0; +// Value for fMagicValue when the constructor has finished running +int CMyClass::kFinishedConstructionMagicValue = 12345; + +CMyClass::CMyClass(int tag) : + fMagicValue(kStartedConstructionMagicValue), fTag(tag) +{ + // Signal that the constructor has finished running + fMagicValue = kFinishedConstructionMagicValue; +} + +CMyClass::CMyClass(const CMyClass& iOther) : + fMagicValue(kStartedConstructionMagicValue), fTag(iOther.fTag) +{ + // If requested, throw an exception _before_ setting fMagicValue to kFinishedConstructionMagicValue + if (gCopyConstructorShouldThrow) { + TEST_THROW(std::exception()); + } + // Signal that the constructor has finished running + fMagicValue = kFinishedConstructionMagicValue; +} + +CMyClass::~CMyClass() { + // Only instances for which the constructor has finished running should be destructed + assert(fMagicValue == kFinishedConstructionMagicValue); +} + +bool operator==(const CMyClass &lhs, const CMyClass &rhs) { return lhs.equal(rhs); } + +int main() +{ + CMyClass instance(42); + std::vector vec; + + vec.push_back(instance); + std::vector vec2(vec); + assert(is_contiguous_container_asan_correct(vec)); + assert(is_contiguous_container_asan_correct(vec2)); + +#ifndef TEST_HAS_NO_EXCEPTIONS + gCopyConstructorShouldThrow = true; + try { + vec.push_back(instance); + assert(false); + } + catch (...) { + assert(vec==vec2); + assert(is_contiguous_container_asan_correct(vec)); + } +#endif +} diff --git a/tests/external/libcxx/vector/vector.modifiers/push_back_rvalue.pass.cpp b/tests/external/libcxx/vector/vector.modifiers/push_back_rvalue.pass.cpp new file mode 100644 index 0000000..fc39833 --- /dev/null +++ b/tests/external/libcxx/vector/vector.modifiers/push_back_rvalue.pass.cpp @@ -0,0 +1,84 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// Copyright 2019, Intel Corporation +// +// Modified to test pmem::obj containers +// + +#include "helper_classes.hpp" +#include "unittest.hpp" + +#include +#include + +namespace nvobj = pmem::obj; +namespace pmem_exp = nvobj::experimental; + +using C = pmem_exp::vector; + +struct root { + nvobj::persistent_ptr c; +}; + +int +main(int argc, char *argv[]) +{ + START(); + + if (argc < 2) { + std::cerr << "usage: " << argv[0] << " file-name" << std::endl; + return 1; + } + + auto path = argv[1]; + auto pop = + nvobj::pool::create(path, "VectorTest: push_back_rvalue", + PMEMOBJ_MIN_POOL, S_IWUSR | S_IRUSR); + + auto r = pop.root(); + + try { + nvobj::transaction::run( + pop, [&] { r->c = nvobj::make_persistent(); }); + r->c->push_back(move_only(0)); + UT_ASSERT(r->c->size() == 1); + for (std::size_t j = 0; + static_cast(j) < r->c->size(); ++j) + UT_ASSERT((*r->c)[j] == move_only(j)); + r->c->push_back(move_only(1)); + UT_ASSERT(r->c->size() == 2); + for (std::size_t j = 0; + static_cast(j) < r->c->size(); ++j) + UT_ASSERT((*r->c)[j] == move_only(j)); + r->c->push_back(move_only(2)); + UT_ASSERT(r->c->size() == 3); + for (std::size_t j = 0; + static_cast(j) < r->c->size(); ++j) + UT_ASSERT((*r->c)[j] == move_only(j)); + r->c->push_back(move_only(3)); + UT_ASSERT(r->c->size() == 4); + for (std::size_t j = 0; + static_cast(j) < r->c->size(); ++j) + UT_ASSERT((*r->c)[j] == move_only(j)); + r->c->push_back(move_only(4)); + UT_ASSERT(r->c->size() == 5); + for (std::size_t j = 0; + static_cast(j) < r->c->size(); ++j) + UT_ASSERT((*r->c)[j] == move_only(j)); + nvobj::transaction::run( + pop, [&] { nvobj::delete_persistent(r->c); }); + } catch (std::exception &e) { + UT_FATALexc(e); + } + + pop.close(); + + return 0; +} diff --git a/tests/external/libcxx/vector/vector.special/swap.pass.cpp b/tests/external/libcxx/vector/vector.special/swap.pass.cpp new file mode 100644 index 0000000..59266d0 --- /dev/null +++ b/tests/external/libcxx/vector/vector.special/swap.pass.cpp @@ -0,0 +1,183 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// Copyright 2019, Intel Corporation +// +// Modified to test pmem::obj containers +// + +#include "unittest.hpp" + +#include +#include + +#include + +namespace nvobj = pmem::obj; +namespace pmem_exp = nvobj::experimental; + +using C = pmem_exp::vector; + +struct root { + nvobj::persistent_ptr c1; + nvobj::persistent_ptr c2; +}; +int +main(int argc, char *argv[]) +{ + START(); + + if (argc < 2) { + std::cerr << "usage: " << argv[0] << " file-name" << std::endl; + return 1; + } + + auto path = argv[1]; + auto pop = nvobj::pool::create( + path, "VectorTest: swap", PMEMOBJ_MIN_POOL, S_IWUSR | S_IRUSR); + + auto r = pop.root(); + { + int a1[] = {1, 3, 7, 9, 10}; + int a2[] = {0, 2, 4, 5, 6, 8, 11}; + try { + nvobj::transaction::run(pop, [&] { + r->c1 = nvobj::make_persistent( + a1, a1 + sizeof(a1) / sizeof(a1[0])); + r->c2 = nvobj::make_persistent( + a2, a2 + sizeof(a2) / sizeof(a2[0])); + }); + + swap(*r->c1, *r->c2); + + nvobj::transaction::run(pop, [&] { + nvobj::persistent_ptr tmp1 = + nvobj::make_persistent( + a1, + a1 + + sizeof(a1) / + sizeof(a1[0])); + nvobj::persistent_ptr tmp2 = + nvobj::make_persistent( + a2, + a2 + + sizeof(a2) / + sizeof(a2[0])); + UT_ASSERT(*r->c1 == *tmp2); + UT_ASSERT(*r->c2 == *tmp1); + nvobj::delete_persistent(tmp1); + nvobj::delete_persistent(tmp2); + }); + + nvobj::transaction::run(pop, [&] { + nvobj::delete_persistent(r->c1); + nvobj::delete_persistent(r->c2); + }); + } catch (std::exception &e) { + UT_FATALexc(e); + } + } + { + int a1[] = {1, 3, 7, 9, 10}; + int a2[] = {0, 2, 4, 5, 6, 8, 11}; + try { + nvobj::transaction::run(pop, [&] { + r->c1 = nvobj::make_persistent(a1, a1); + r->c2 = nvobj::make_persistent( + a2, a2 + sizeof(a2) / sizeof(a2[0])); + }); + + swap(*r->c1, *r->c2); + + nvobj::transaction::run(pop, [&] { + nvobj::persistent_ptr tmp1 = + nvobj::make_persistent( + a2, + a2 + + sizeof(a2) / + sizeof(a2[0])); + UT_ASSERT(*r->c1 == *tmp1); + UT_ASSERT(r->c2->empty()); + UT_ASSERT(std::distance(r->c2->begin(), + r->c2->end()) == 0); + nvobj::delete_persistent(tmp1); + }); + + nvobj::transaction::run(pop, [&] { + nvobj::delete_persistent(r->c1); + nvobj::delete_persistent(r->c2); + }); + } catch (std::exception &e) { + UT_FATALexc(e); + } + } + { + int a1[] = {1, 3, 7, 9, 10}; + int a2[] = {0, 2, 4, 5, 6, 8, 11}; + try { + nvobj::transaction::run(pop, [&] { + r->c1 = nvobj::make_persistent( + a1, a1 + sizeof(a1) / sizeof(a1[0])); + r->c2 = nvobj::make_persistent(a2, a2); + }); + + swap(*r->c1, *r->c2); + + UT_ASSERT(r->c1->empty()); + UT_ASSERT(std::distance(r->c1->begin(), r->c1->end()) == + 0); + + nvobj::transaction::run(pop, [&] { + nvobj::persistent_ptr tmp1 = + nvobj::make_persistent( + a1, + a1 + + sizeof(a1) / + sizeof(a1[0])); + UT_ASSERT(*r->c2 == *tmp1); + nvobj::delete_persistent(tmp1); + }); + + nvobj::transaction::run(pop, [&] { + nvobj::delete_persistent(r->c1); + nvobj::delete_persistent(r->c2); + }); + } catch (std::exception &e) { + UT_FATALexc(e); + } + } + { + int a1[] = {1, 3, 7, 9, 10}; + int a2[] = {0, 2, 4, 5, 6, 8, 11}; + try { + nvobj::transaction::run(pop, [&] { + r->c1 = nvobj::make_persistent(a1, a1); + r->c2 = nvobj::make_persistent(a2, a2); + }); + + swap(*r->c1, *r->c2); + + UT_ASSERT(r->c1->empty()); + UT_ASSERT(std::distance(r->c1->begin(), r->c1->end()) == + 0); + UT_ASSERT(r->c2->empty()); + UT_ASSERT(std::distance(r->c2->begin(), r->c2->end()) == + 0); + nvobj::transaction::run(pop, [&] { + nvobj::delete_persistent(r->c1); + nvobj::delete_persistent(r->c2); + }); + } catch (std::exception &e) { + UT_FATALexc(e); + } + } + pop.close(); + + return 0; +} diff --git a/tests/external/run_default.cmake b/tests/external/run_default.cmake new file mode 100644 index 0000000..d1e80b3 --- /dev/null +++ b/tests/external/run_default.cmake @@ -0,0 +1,38 @@ +# +# Copyright 2018, Intel Corporation +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# +# * Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# +# * Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in +# the documentation and/or other materials provided with the +# distribution. +# +# * Neither the name of the copyright holder nor the names of its +# contributors may be used to endorse or promote products derived +# from this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +include(${SRC_DIR}/../../helpers.cmake) + +setup() + +execute(${TEST_EXECUTABLE} ${DIR}/testfile) + +finish() diff --git a/tests/helpers.cmake b/tests/helpers.cmake new file mode 100644 index 0000000..c0deb57 --- /dev/null +++ b/tests/helpers.cmake @@ -0,0 +1,336 @@ +# +# Copyright 2018-2019, Intel Corporation +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# +# * Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# +# * Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in +# the documentation and/or other materials provided with the +# distribution. +# +# * Neither the name of the copyright holder nor the names of its +# contributors may be used to endorse or promote products derived +# from this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +set(DIR ${PARENT_DIR}/${TEST_NAME}) + +function(setup) + execute_process(COMMAND ${CMAKE_COMMAND} -E remove_directory ${PARENT_DIR}/${TEST_NAME}) + execute_process(COMMAND ${CMAKE_COMMAND} -E make_directory ${PARENT_DIR}/${TEST_NAME}) + execute_process(COMMAND ${CMAKE_COMMAND} -E remove_directory ${BIN_DIR}) + execute_process(COMMAND ${CMAKE_COMMAND} -E make_directory ${BIN_DIR}) +endfunction() + +function(print_logs) + message(STATUS "Test ${TEST_NAME}:") + if(EXISTS ${BIN_DIR}/${TEST_NAME}.out) + file(READ ${BIN_DIR}/${TEST_NAME}.out OUT) + message(STATUS "Stdout:\n${OUT}") + endif() + if(EXISTS ${BIN_DIR}/${TEST_NAME}.err) + file(READ ${BIN_DIR}/${TEST_NAME}.err ERR) + message(STATUS "Stderr:\n${ERR}") + endif() + if(EXISTS ${BIN_DIR}/${TEST_NAME}.pmreorder) + file(READ ${BIN_DIR}/${TEST_NAME}.pmreorder PMEMREORDER) + message(STATUS "Pmreorder:\n${PMEMREORDER}") + endif() +endfunction() + +# Performs cleanup and log matching. +function(finish) + print_logs() + + if(EXISTS ${SRC_DIR}/${TEST_NAME}.err.match) + match(${BIN_DIR}/${TEST_NAME}.err ${SRC_DIR}/${TEST_NAME}.err.match) + endif() + if(EXISTS ${SRC_DIR}/${TEST_NAME}.out.match) + match(${BIN_DIR}/${TEST_NAME}.out ${SRC_DIR}/${TEST_NAME}.out.match) + endif() + + execute_process(COMMAND ${CMAKE_COMMAND} -E remove_directory ${PARENT_DIR}/${TEST_NAME}) +endfunction() + +# Verifies ${log_file} matches ${match_file} using "match". +function(match log_file match_file) + execute_process(COMMAND + ${PERL_EXECUTABLE} ${MATCH_SCRIPT} -o ${log_file} ${match_file} + RESULT_VARIABLE MATCH_ERROR) + + if(MATCH_ERROR) + message(FATAL_ERROR "Log does not match: ${MATCH_ERROR}") + endif() +endfunction() + +# Verifies file exists +function(check_file_exists file) + if(NOT EXISTS ${file}) + message(FATAL_ERROR "${file} doesn't exist") + endif() +endfunction() + +# Verifies file doesn't exist +function(check_file_doesnt_exist file) + if(EXISTS ${file}) + message(FATAL_ERROR "${file} exists") + endif() +endfunction() + +# https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=810295 +# https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=780173 +# https://bugs.kde.org/show_bug.cgi?id=303877 +# +# valgrind issues an unsuppressable warning when exceeding +# the brk segment, causing matching failures. We can safely +# ignore it because malloc() will fallback to mmap() anyway. +# +# list of ingored warnings should match with the list provided by PMDK: +# https://github.com/pmem/pmdk/blob/master/src/test/unittest/unittest.sh +function(valgrind_ignore_warnings valgrind_log) + execute_process(COMMAND bash "-c" "cat ${valgrind_log} | grep -v \ + -e \"WARNING: Serious error when reading debug info\" \ + -e \"When reading debug info from \" \ + -e \"Ignoring non-Dwarf2/3/4 block in .debug_info\" \ + -e \"Last block truncated in .debug_info; ignoring\" \ + -e \"parse_CU_Header: is neither DWARF2 nor DWARF3 nor DWARF4\" \ + -e \"brk segment overflow\" \ + -e \"see section Limitations in user manual\" \ + -e \"Warning: set address range perms: large range\"\ + -e \"further instances of this message will not be shown\"\ + > ${valgrind_log}.tmp +mv ${valgrind_log}.tmp ${valgrind_log}") +endfunction() + +function(execute_common expect_success output_file name) + if(TESTS_USE_FORCED_PMEM) + set(ENV{PMEM_IS_PMEM_FORCE} 1) + endif() + + if(${TRACER} STREQUAL pmemcheck) + if(TESTS_USE_FORCED_PMEM) + # pmemcheck runs really slow with pmem, disable it + set(ENV{PMEM_IS_PMEM_FORCE} 0) + endif() + set(TRACE valgrind --error-exitcode=99 --tool=pmemcheck) + set(ENV{LIBPMEMOBJ_CPP_TRACER_PMEMCHECK} 1) + elseif(${TRACER} STREQUAL memcheck) + set(TRACE valgrind --error-exitcode=99 --tool=memcheck --leak-check=full + --suppressions=${TEST_ROOT_DIR}/ld.supp --suppressions=${TEST_ROOT_DIR}/memcheck-stdcpp.supp --suppressions=${TEST_ROOT_DIR}/memcheck-libunwind.supp) + set(ENV{LIBPMEMOBJ_CPP_TRACER_MEMCHECK} 1) + elseif(${TRACER} STREQUAL helgrind) + set(TRACE valgrind --error-exitcode=99 --tool=helgrind) + set(ENV{LIBPMEMOBJ_CPP_TRACER_HELGRIND} 1) + elseif(${TRACER} STREQUAL drd) + set(TRACE valgrind --error-exitcode=99 --tool=drd) + set(ENV{LIBPMEMOBJ_CPP_TRACER_DRD} 1) + elseif(${TRACER} MATCHES "none.*") + # nothing + else() + message(FATAL_ERROR "Unknown tracer '${TRACER}'") + endif() + + if (NOT $ENV{CGDB}) + if (NOT WIN32) + set(TRACE timeout -s SIGALRM -k 200s 180s ${TRACE}) + endif() + endif() + + string(REPLACE ";" " " TRACE_STR "${TRACE}") + message(STATUS "Executing: ${TRACE_STR} ${name} ${ARGN}") + + set(cmd ${TRACE} ${name} ${ARGN}) + + if($ENV{CGDB}) + find_program(KONSOLE NAMES konsole) + find_program(GNOME_TERMINAL NAMES gnome-terminal) + find_program(CGDB NAMES cgdb) + + if (NOT KONSOLE AND NOT GNOME_TERMINAL) + message(FATAL_ERROR "konsole or gnome-terminal not found.") + elseif (NOT CGDB) + message(FATAL_ERROR "cdgb not found.") + elseif(NOT (${TRACER} STREQUAL none)) + message(FATAL_ERROR "Cannot use cgdb with ${TRACER}") + else() + if (KONSOLE) + set(cmd konsole -e cgdb --args ${cmd}) + elseif(GNOME_TERMINAL) + set(cmd gnome-terminal --tab --active --wait -- cgdb --args ${cmd}) + endif() + endif() + endif() + + if(${output_file} STREQUAL none) + execute_process(COMMAND ${cmd} + OUTPUT_QUIET + RESULT_VARIABLE res) + else() + execute_process(COMMAND ${cmd} + RESULT_VARIABLE res + OUTPUT_FILE ${BIN_DIR}/${TEST_NAME}.out + ERROR_FILE ${BIN_DIR}/${TEST_NAME}.err) + endif() + + # memcheck and pmemcheck match files should follow name pattern: + # testname_testcasenr_memcheck/pmemcheck.err.match + # If they do exist, ignore test result - it will be verified during + # log matching in finish() function. + if(EXISTS ${SRC_DIR}/${TEST_NAME}.err.match) + valgrind_ignore_warnings(${BIN_DIR}/${TEST_NAME}.err) + # pmemcheck is a special snowflake and it doesn't set exit code when + # it detects an error, so we have to look at its output if match file + # was not found. + else() + if(${TRACER} STREQUAL pmemcheck) + if(NOT EXISTS ${BIN_DIR}/${TEST_NAME}.err) + message(FATAL_ERROR "${TEST_NAME}.err not found.") + endif() + + file(READ ${BIN_DIR}/${TEST_NAME}.err PMEMCHECK_ERR) + message(STATUS "Stderr:\n${PMEMCHECK_ERR}\nEnd of stderr") + if(NOT PMEMCHECK_ERR MATCHES "ERROR SUMMARY: 0") + message(FATAL_ERROR "${TRACE} ${name} ${ARGN} failed: ${res}") + endif() + endif() + + if(res AND expect_success) + print_logs() + message(FATAL_ERROR "${TRACE} ${name} ${ARGN} failed: ${res}") + endif() + + if(NOT res AND NOT expect_success) + print_logs() + message(FATAL_ERROR "${TRACE} ${name} ${ARGN} unexpectedly succeeded: ${res}") + endif() + endif() + + if(${TRACER} STREQUAL pmemcheck) + unset(ENV{LIBPMEMOBJ_CPP_TRACER_PMEMCHECK}) + elseif(${TRACER} STREQUAL memcheck) + unset(ENV{LIBPMEMOBJ_CPP_TRACER_MEMCHECK}) + elseif(${TRACER} STREQUAL helgrind) + unset(ENV{LIBPMEMOBJ_CPP_TRACER_HELGRIND}) + elseif(${TRACER} STREQUAL drd) + unset(ENV{LIBPMEMOBJ_CPP_TRACER_DRD}) + endif() + + if(TESTS_USE_FORCED_PMEM) + unset(ENV{PMEM_IS_PMEM_FORCE}) + endif() +endfunction() + +function(check_target name) + if(NOT EXISTS ${name}) + message(FATAL_ERROR "Tests were not found! If not built, run make first.") + endif() +endfunction() + +# Generic command executor which handles failures and prints command output +# to specified file. +function(execute_with_output out name) + check_target(${name}) + + execute_common(true ${out} ${name} ${ARGN}) +endfunction() + +# Generic command executor which handles failures but ignores output. +function(execute_ignore_output name) + check_target(${name}) + + execute_common(true none ${name} ${ARGN}) +endfunction() + +# Executes test command ${name} and verifies its status. +# First argument of the command is test directory name. +# Optional function arguments are passed as consecutive arguments to +# the command. +function(execute name) + check_target(${name}) + + execute_common(true ${TRACER}_${TESTCASE} ${name} ${ARGN}) +endfunction() + +# Executes command ${name} and creates a storelog. +# First argument is pool file. +# Second argument is test executable. +# Optional function arguments are passed as consecutive arguments to +# the command. +function(pmreorder_create_store_log pool name) + check_target(${name}) + + if(NOT (${TRACER} STREQUAL none)) + message(FATAL_ERROR "Pmreorder test must be run without any tracer.") + endif() + + configure_file(${pool} ${pool}.copy COPYONLY) + + set(ENV{PMREORDER_EMIT_LOG} 1) + + if(DEFINED ENV{PMREORDER_STACKTRACE_DEPTH}) + set(PMREORDER_STACKTRACE_DEPTH $ENV{PMREORDER_STACKTRACE_DEPTH}) + set(PMREORDER_STACKTRACE "yes") + else() + set(PMREORDER_STACKTRACE_DEPTH 1) + set(PMREORDER_STACKTRACE "no") + endif() + + set(cmd valgrind --tool=pmemcheck -q + --log-stores=yes + --print-summary=no + --log-file=${BIN_DIR}/${TEST_NAME}.storelog + --log-stores-stacktraces=${PMREORDER_STACKTRACE} + --log-stores-stacktraces-depth=${PMREORDER_STACKTRACE_DEPTH} + --expect-fence-after-clflush=yes + ${name} ${ARGN}) + + execute_common(true ${TRACER}_${TESTCASE} ${cmd}) + + unset(ENV{PMREORDER_EMIT_LOG}) + + file(REMOVE ${pool}) + configure_file(${pool}.copy ${pool} COPYONLY) +endfunction() + +# Executes pmreorder. +# First argument is expected result. +# Second argument is engine type. +# Third argument is path to configure file. +# Fourth argument is path to the checker program. +# Optional function arguments are passed as consecutive arguments to +# the command. +function(pmreorder_execute expect_success engine conf_file name) + check_target(${name}) + + if(NOT (${TRACER} STREQUAL none)) + message(FATAL_ERROR "Pmreorder test must be run without any tracer.") + endif() + + set(ENV{PMEMOBJ_COW} 1) + + set(cmd pmreorder -l ${BIN_DIR}/${TEST_NAME}.storelog + -o ${BIN_DIR}/${TEST_NAME}.pmreorder + -r ${engine} + -p "${name} ${ARGN}" + -x ${conf_file}) + + execute_common(${expect_success} ${TRACER}_${TESTCASE} ${cmd}) + + unset(ENV{PMEMOBJ_COW}) +endfunction() diff --git a/tests/iterator_traits/iterator_traits.cpp b/tests/iterator_traits/iterator_traits.cpp new file mode 100644 index 0000000..0682c73 --- /dev/null +++ b/tests/iterator_traits/iterator_traits.cpp @@ -0,0 +1,149 @@ +/* + * Copyright 2018-2019, Intel Corporation + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * * Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +/* + * iterator_traits.cpp -- iterator traits tests + */ + +#include "unittest.hpp" + +#include + +void +test_is_type_of_iterator() +{ + /* test is_output_iterator */ + UT_ASSERT(true == + pmem::detail::is_output_iterator< + test_support::output_it>::value); + UT_ASSERT(false == + pmem::detail::is_output_iterator< + test_support::input_it>::value); + UT_ASSERT(false == + pmem::detail::is_output_iterator< + test_support::forward_it>::value); + UT_ASSERT(false == + pmem::detail::is_output_iterator< + test_support::bidirectional_it>::value); + UT_ASSERT(false == + pmem::detail::is_output_iterator< + test_support::random_access_it>::value); + UT_ASSERT(false == pmem::detail::is_output_iterator::value); + + /* test is_input_iterator */ + UT_ASSERT(false == + pmem::detail::is_input_iterator< + test_support::output_it>::value); + UT_ASSERT(true == + pmem::detail::is_input_iterator< + test_support::input_it>::value); + UT_ASSERT(true == + pmem::detail::is_input_iterator< + test_support::forward_it>::value); + UT_ASSERT(true == + pmem::detail::is_input_iterator< + test_support::bidirectional_it>::value); + UT_ASSERT(true == + pmem::detail::is_input_iterator< + test_support::random_access_it>::value); + UT_ASSERT(false == pmem::detail::is_input_iterator::value); + UT_ASSERT(true == pmem::detail::is_input_iterator::value); + + /* test forward_iterator */ + UT_ASSERT(false == + pmem::detail::is_forward_iterator< + test_support::output_it>::value); + UT_ASSERT(false == + pmem::detail::is_forward_iterator< + test_support::input_it>::value); + UT_ASSERT(true == + pmem::detail::is_forward_iterator< + test_support::forward_it>::value); + UT_ASSERT(true == + pmem::detail::is_forward_iterator< + test_support::bidirectional_it>::value); + UT_ASSERT(true == + pmem::detail::is_forward_iterator< + test_support::random_access_it>::value); + UT_ASSERT(false == pmem::detail::is_forward_iterator::value); + UT_ASSERT(true == pmem::detail::is_forward_iterator::value); + + /* test bidirectional_iterator */ + UT_ASSERT(false == + pmem::detail::is_bidirectional_iterator< + test_support::output_it>::value); + UT_ASSERT(false == + pmem::detail::is_bidirectional_iterator< + test_support::input_it>::value); + UT_ASSERT(false == + pmem::detail::is_bidirectional_iterator< + test_support::forward_it>::value); + UT_ASSERT(true == + pmem::detail::is_bidirectional_iterator< + test_support::bidirectional_it>::value); + UT_ASSERT(true == + pmem::detail::is_bidirectional_iterator< + test_support::random_access_it>::value); + UT_ASSERT(false == pmem::detail::is_bidirectional_iterator::value); + UT_ASSERT(true == + pmem::detail::is_bidirectional_iterator::value); + + /* test random_access_iterator */ + UT_ASSERT(false == + pmem::detail::is_random_access_iterator< + test_support::output_it>::value); + UT_ASSERT(false == + pmem::detail::is_random_access_iterator< + test_support::input_it>::value); + UT_ASSERT(false == + pmem::detail::is_random_access_iterator< + test_support::forward_it>::value); + UT_ASSERT(false == + pmem::detail::is_random_access_iterator< + test_support::bidirectional_it>::value); + UT_ASSERT(true == + pmem::detail::is_random_access_iterator< + test_support::random_access_it>::value); + UT_ASSERT(false == pmem::detail::is_random_access_iterator::value); + UT_ASSERT(true == + pmem::detail::is_random_access_iterator::value); +} + +int +main() +{ + START(); + + test_is_type_of_iterator(); + + return 0; +} diff --git a/tests/ld.supp b/tests/ld.supp new file mode 100644 index 0000000..54fa44f --- /dev/null +++ b/tests/ld.supp @@ -0,0 +1,41 @@ +{ + + Memcheck:Cond + fun:index + fun:expand_dynamic_string_token + fun:_dl_map_object + fun:map_doit + fun:_dl_catch_error + fun:do_preload + fun:dl_main + fun:_dl_sysdep_start + fun:_dl_start + obj:/lib/x86_64-linux-gnu/ld-2.*.so + obj:* + obj:* +} +{ + + Memcheck:Cond + fun:index + fun:expand_dynamic_string_token + fun:_dl_map_object + fun:map_doit + fun:_dl_catch_error + fun:do_preload + fun:handle_ld_preload + fun:dl_main + fun:_dl_sysdep_start + fun:_dl_start + obj:/lib/x86_64-linux-gnu/ld-2.*.so + obj:* +} +{ + + Memcheck:Leak + ... + fun:_dl_init + fun:dl_open_worker + fun:_dl_catch_error + ... +} diff --git a/tests/make_persistent/make_persistent.cpp b/tests/make_persistent/make_persistent.cpp new file mode 100644 index 0000000..02f5a6a --- /dev/null +++ b/tests/make_persistent/make_persistent.cpp @@ -0,0 +1,379 @@ +/* + * Copyright 2016-2019, Intel Corporation + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * * Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +/* + * obj_cpp_make_persistent.cpp -- cpp make_persistent test for objects + */ + +#include "unittest.hpp" + +#include +#include +#include +#include +#include +#include + +#define LAYOUT "cpp" + +namespace nvobj = pmem::obj; + +namespace +{ + +const int TEST_ARR_SIZE = 10; + +class foo { +public: + foo() : bar(1) + { + for (int i = 0; i < TEST_ARR_SIZE; ++i) + this->arr[i] = 1; + } + + foo(int val) : bar(val) + { + for (int i = 0; i < TEST_ARR_SIZE; ++i) + this->arr[i] = static_cast(val); + } + + foo(int val, char arr_val) : bar(val) + { + for (int i = 0; i < TEST_ARR_SIZE; ++i) + this->arr[i] = arr_val; + } + + /* + * Assert values of foo. + */ + void + check_foo(int val, char arr_val) + { + UT_ASSERTeq(val, this->bar); + for (int i = 0; i < TEST_ARR_SIZE; ++i) + UT_ASSERTeq(arr_val, this->arr[i]); + } + + nvobj::p bar; + nvobj::p arr[TEST_ARR_SIZE]; +}; + +struct big_struct { + char data[PMEMOBJ_MIN_POOL]; +}; + +struct struct_throwing { + struct_throwing() + { + throw magic_number; + } + + char data[8]; + static constexpr int magic_number = 42; +}; + +struct root { + nvobj::persistent_ptr pfoo; + nvobj::persistent_ptr bstruct; + nvobj::persistent_ptr throwing; +}; + +/* + * test_make_no_args -- (internal) test make_persistent without arguments + */ +void +test_make_no_args(nvobj::pool &pop) +{ + nvobj::persistent_ptr r = pop.root(); + + try { + nvobj::transaction::run(pop, [&] { + UT_ASSERT(r->pfoo == nullptr); + + r->pfoo = nvobj::make_persistent(); + r->pfoo->check_foo(1, 1); + + nvobj::delete_persistent(r->pfoo); + r->pfoo = nullptr; + }); + } catch (...) { + UT_ASSERT(0); + } + + UT_ASSERT(r->pfoo == nullptr); +} + +/* + * test_make_args -- (internal) test make_persistent with arguments + */ +void +test_make_args(nvobj::pool &pop) +{ + nvobj::persistent_ptr r = pop.root(); + + try { + nvobj::transaction::run(pop, [&] { + UT_ASSERT(r->pfoo == nullptr); + + r->pfoo = nvobj::make_persistent(2); + r->pfoo->check_foo(2, 2); + + nvobj::delete_persistent(r->pfoo); + + r->pfoo = nvobj::make_persistent(3, 4); + r->pfoo->check_foo(3, 4); + + nvobj::delete_persistent(r->pfoo); + r->pfoo = nullptr; + }); + } catch (...) { + UT_ASSERT(0); + } + + UT_ASSERT(r->pfoo == nullptr); +} + +/* + * test_additional_delete -- (internal) test double delete and delete rollback + */ +void +test_additional_delete(nvobj::pool &pop) +{ + nvobj::persistent_ptr r = pop.root(); + + try { + nvobj::transaction::run(pop, [&] { + UT_ASSERT(r->pfoo == nullptr); + + r->pfoo = nvobj::make_persistent(); + r->pfoo->check_foo(1, 1); + }); + } catch (...) { + UT_ASSERT(0); + } + + bool exception_thrown = false; + try { + nvobj::transaction::run(pop, [&] { + UT_ASSERT(r->pfoo != nullptr); + nvobj::delete_persistent(r->pfoo); + r->pfoo = nullptr; + nvobj::delete_persistent(r->pfoo); + + nvobj::transaction::abort(EINVAL); + }); + } catch (pmem::manual_tx_abort &) { + exception_thrown = true; + } catch (...) { + UT_ASSERT(0); + } + + UT_ASSERT(exception_thrown); + UT_ASSERT(r->pfoo != nullptr); + r->pfoo->check_foo(1, 1); + + try { + nvobj::transaction::run(pop, [&] { + UT_ASSERT(r->pfoo != nullptr); + nvobj::delete_persistent(r->pfoo); + r->pfoo = nullptr; + }); + } catch (...) { + UT_ASSERT(0); + } + + UT_ASSERT(r->pfoo == nullptr); +} + +/* + * test_exceptions_handling -- (internal) test proper handling of exceptions + * inside make_persistent + */ +void +test_exceptions_handling(nvobj::pool &pop) +{ + nvobj::persistent_ptr r = pop.root(); + + bool scope_error_thrown = false; + try { + /* Run outside of a transaction, expect error */ + r->pfoo = nvobj::make_persistent(); + UT_ASSERT(0); + } catch (pmem::transaction_scope_error &) { + scope_error_thrown = true; + } + UT_ASSERT(scope_error_thrown); + + bool alloc_error_thrown = false; + try { + nvobj::transaction::run(pop, [&] { + UT_ASSERT(r->bstruct == nullptr); + + r->bstruct = nvobj::make_persistent(); + UT_ASSERT(0); + }); + } catch (pmem::transaction_alloc_error &) { + alloc_error_thrown = true; + } + UT_ASSERT(alloc_error_thrown); + + bool scope_error_delete_thrown = false; + try { + nvobj::transaction::run(pop, [&] { + UT_ASSERT(r->pfoo == nullptr); + + r->pfoo = nvobj::make_persistent(); + }); + } catch (...) { + UT_ASSERT(0); + } + try { + /* Run outside of a transaction, expect error */ + nvobj::delete_persistent(r->pfoo); + UT_ASSERT(0); + } catch (pmem::transaction_scope_error &) { + scope_error_delete_thrown = true; + } + UT_ASSERT(scope_error_delete_thrown); + + try { + nvobj::transaction::run(pop, [&] { + UT_ASSERT(r->throwing == nullptr); + + r->throwing = nvobj::make_persistent(); + UT_ASSERT(0); + }); + } catch (int &e) { + UT_ASSERT(e == struct_throwing::magic_number); + } + UT_ASSERT(r->throwing == nullptr); + + try { + nvobj::transaction::run(pop, [&] { + nvobj::delete_persistent(r->pfoo); + r->pfoo = nullptr; + }); + } catch (...) { + UT_ASSERT(0); + } +} + +/* + * test_flags -- (internal) test proper handling of flags + */ +void +test_flags(nvobj::pool &pop) +{ + nvobj::persistent_ptr r = pop.root(); + + auto alloc_class = pop.ctl_set( + "heap.alloc_class.new.desc", + {sizeof(foo) + 16, 0, 200, POBJ_HEADER_COMPACT, 0}); + + try { + nvobj::transaction::run(pop, [&] { + UT_ASSERT(r->pfoo == nullptr); + r->pfoo = nvobj::make_persistent( + nvobj::allocation_flag::class_id( + alloc_class.class_id)); + }); + } catch (std::exception &e) { + UT_FATALexc(e); + } + + UT_ASSERTeq(pmemobj_alloc_usable_size(r->pfoo.raw()), sizeof(foo)); + + try { + nvobj::transaction::run(pop, [&] { + nvobj::delete_persistent(r->pfoo); + r->pfoo = nullptr; + }); + } catch (std::exception &e) { + UT_FATALexc(e); + } + + try { + nvobj::transaction::run(pop, [&] { + UT_ASSERT(r->pfoo == nullptr); + r->pfoo = nvobj::make_persistent( + nvobj::allocation_flag::class_id( + alloc_class.class_id), + 1, 2); + }); + } catch (std::exception &e) { + UT_FATALexc(e); + } + + r->pfoo->check_foo(1, 2); + + UT_ASSERTeq(pmemobj_alloc_usable_size(r->pfoo.raw()), sizeof(foo)); + + try { + nvobj::transaction::run(pop, [&] { + nvobj::delete_persistent(r->pfoo); + r->pfoo = nullptr; + }); + } catch (std::exception &e) { + UT_FATALexc(e); + } +} +} + +int +main(int argc, char *argv[]) +{ + START(); + + if (argc != 2) + UT_FATAL("usage: %s file-name", argv[0]); + + const char *path = argv[1]; + + nvobj::pool pop; + + try { + pop = nvobj::pool::create(path, LAYOUT, PMEMOBJ_MIN_POOL, + S_IWUSR | S_IRUSR); + } catch (pmem::pool_error &pe) { + UT_FATAL("!pool::create: %s %s", pe.what(), path); + } + + test_make_no_args(pop); + test_make_args(pop); + test_additional_delete(pop); + test_exceptions_handling(pop); + test_flags(pop); + + pop.close(); + + return 0; +} diff --git a/tests/make_persistent_array/make_persistent_array.cpp b/tests/make_persistent_array/make_persistent_array.cpp new file mode 100644 index 0000000..afe7f84 --- /dev/null +++ b/tests/make_persistent_array/make_persistent_array.cpp @@ -0,0 +1,485 @@ +/* + * Copyright 2016-2019, Intel Corporation + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * * Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +/* + * obj_cpp_make_persistent_array.cpp -- cpp make_persistent test for arrays + */ + +#include "unittest.hpp" + +#include +#include +#include +#include +#include +#include +#include +#include + +#define LAYOUT "cpp" + +namespace nvobj = pmem::obj; + +namespace +{ + +const int TEST_ARR_SIZE = 10; + +class foo { +public: + foo() : bar(1) + { + for (int i = 0; i < TEST_ARR_SIZE; ++i) + this->arr[i] = 1; + } + + /* + * Assert values of foo. + */ + void + check_foo() + { + UT_ASSERTeq(1, this->bar); + for (int i = 0; i < TEST_ARR_SIZE; ++i) + UT_ASSERTeq(1, this->arr[i]); + } + + ~foo() + { + this->bar = 0; + for (int i = 0; i < TEST_ARR_SIZE; ++i) + this->arr[i] = 0; + } + + nvobj::p bar; + nvobj::p arr[TEST_ARR_SIZE]; +}; + +int ctor_number = 0; + +struct struct_throwing { + struct_throwing() + { + if (ctor_number == throw_after) + throw magic_number; + + ctor_number++; + } + + char data[8]; + static constexpr int magic_number = 42; + static constexpr int throw_after = 5; +}; + +struct root { + nvobj::persistent_ptr pfoo; + nvobj::persistent_ptr throwing; + + nvobj::persistent_ptr pfoo_sized; + nvobj::persistent_ptr pfoo_sized_big; + nvobj::persistent_ptr throwing_sized; +}; + +/* + * test_make_one_d -- (internal) test make_persistent of a 1d array + */ +void +test_make_one_d(nvobj::pool_base &pop) +{ + try { + nvobj::transaction::run(pop, [&] { + auto pfoo = nvobj::make_persistent(5); + for (nvobj::p i = 0; i < 5; ++i) + pfoo[i].check_foo(); + + nvobj::delete_persistent(pfoo, 5); + + auto pfoo2 = nvobj::make_persistent(6); + for (int i = 0; i < 6; ++i) + pfoo2[i].check_foo(); + + nvobj::delete_persistent(pfoo2, 6); + + auto pfooN = nvobj::make_persistent(); + for (int i = 0; i < 5; ++i) + pfooN[i].check_foo(); + + nvobj::delete_persistent(pfooN); + }); + } catch (...) { + UT_ASSERT(0); + } +} + +/* + * test_make_N_d -- (internal) test make_persistent of 2d and 3d arrays + */ +void +test_make_N_d(nvobj::pool_base &pop) +{ + try { + nvobj::transaction::run(pop, [&] { + auto pfoo = nvobj::make_persistent(5); + for (int i = 0; i < 5; ++i) + for (int j = 0; j < 2; j++) + pfoo[i][j].check_foo(); + + nvobj::delete_persistent(pfoo, 5); + + auto pfoo2 = nvobj::make_persistent(6); + for (int i = 0; i < 6; ++i) + for (int j = 0; j < 3; j++) + pfoo2[i][j].check_foo(); + + nvobj::delete_persistent(pfoo2, 6); + + auto pfooN = nvobj::make_persistent(); + for (int i = 0; i < 5; ++i) + for (int j = 0; j < 2; j++) + pfooN[i][j].check_foo(); + + nvobj::delete_persistent(pfooN); + + auto pfoo3 = nvobj::make_persistent(5); + for (int i = 0; i < 5; ++i) + for (int j = 0; j < 2; j++) + for (int k = 0; k < 3; k++) + pfoo3[i][j][k].check_foo(); + + nvobj::delete_persistent(pfoo3, 5); + + auto pfoo3N = nvobj::make_persistent(); + for (int i = 0; i < 5; ++i) + for (int j = 0; j < 2; j++) + for (int k = 0; k < 3; k++) + pfoo3N[i][j][k].check_foo(); + + nvobj::delete_persistent(pfoo3N); + }); + } catch (...) { + UT_ASSERT(0); + } +} + +/* + * test_abort_revert -- (internal) test destruction behavior and revert + */ +void +test_abort_revert(nvobj::pool_base &pop) +{ + nvobj::pool &root_pop = + dynamic_cast &>(pop); + nvobj::persistent_ptr r = root_pop.root(); + + try { + nvobj::transaction::run(pop, [&] { + r->pfoo = nvobj::make_persistent(5); + for (int i = 0; i < 5; ++i) + r->pfoo[i].check_foo(); + }); + } catch (...) { + UT_ASSERT(0); + } + + bool exception_thrown = false; + try { + nvobj::transaction::run(pop, [&] { + UT_ASSERT(r->pfoo != nullptr); + nvobj::delete_persistent(r->pfoo, 5); + r->pfoo = nullptr; + + nvobj::transaction::abort(EINVAL); + }); + } catch (pmem::manual_tx_abort &) { + exception_thrown = true; + } catch (...) { + UT_ASSERT(0); + } + + UT_ASSERT(exception_thrown); + UT_ASSERT(r->pfoo != nullptr); + for (int i = 0; i < 5; ++i) + r->pfoo[i].check_foo(); + + try { + nvobj::transaction::run(pop, [&] { + nvobj::delete_persistent(r->pfoo, 5); + r->pfoo = nullptr; + }); + } catch (...) { + UT_ASSERT(0); + } + + UT_ASSERT(r->pfoo == nullptr); +} + +/* + * test_exceptions_handling -- (internal) test proper handling of exceptions + * inside make_persistent + */ +void +test_exceptions_handling(nvobj::pool &pop) +{ + nvobj::persistent_ptr r = pop.root(); + + bool scope_error_thrown = false; + try { + /* Run outside of a transaction, expect error */ + r->pfoo = nvobj::make_persistent(5); + UT_ASSERT(0); + } catch (pmem::transaction_scope_error &) { + scope_error_thrown = true; + } + UT_ASSERT(scope_error_thrown); + + bool alloc_error_thrown = false; + try { + nvobj::transaction::run(pop, [&] { + UT_ASSERT(r->pfoo == nullptr); + + r->pfoo = + nvobj::make_persistent(PMEMOBJ_MIN_POOL); + UT_ASSERT(0); + }); + } catch (pmem::transaction_alloc_error &) { + alloc_error_thrown = true; + } + UT_ASSERT(alloc_error_thrown); + + bool scope_error_delete_thrown = false; + try { + nvobj::transaction::run(pop, [&] { + UT_ASSERT(r->pfoo == nullptr); + + r->pfoo = nvobj::make_persistent(5); + }); + } catch (...) { + UT_ASSERT(0); + } + try { + /* Run outside of a transaction, expect error */ + nvobj::delete_persistent(r->pfoo, 5); + UT_ASSERT(0); + } catch (pmem::transaction_scope_error &) { + scope_error_delete_thrown = true; + } + UT_ASSERT(scope_error_delete_thrown); + + ctor_number = 0; + + try { + nvobj::transaction::run(pop, [&] { + UT_ASSERT(r->throwing == nullptr); + + r->throwing = + nvobj::make_persistent(10); + UT_ASSERT(0); + }); + } catch (int &e) { + UT_ASSERT(e == struct_throwing::magic_number); + } +} + +/* + * test_exceptions_handling -- (internal) test proper handling of exceptions + * inside make_persistent, version for sized array + */ +void +test_exceptions_handling_sized(nvobj::pool &pop) +{ + nvobj::persistent_ptr r = pop.root(); + + bool scope_error_thrown = false; + try { + /* Run outside of a transaction, expect error */ + r->pfoo_sized = nvobj::make_persistent(); + UT_ASSERT(0); + } catch (pmem::transaction_scope_error &) { + scope_error_thrown = true; + } + UT_ASSERT(scope_error_thrown); + + bool alloc_error_thrown = false; + try { + nvobj::transaction::run(pop, [&] { + UT_ASSERT(r->pfoo_sized == nullptr); + + r->pfoo_sized_big = + nvobj::make_persistent(); + UT_ASSERT(0); + }); + } catch (pmem::transaction_alloc_error &) { + alloc_error_thrown = true; + } + UT_ASSERT(alloc_error_thrown); + + bool scope_error_delete_thrown = false; + try { + nvobj::transaction::run(pop, [&] { + UT_ASSERT(r->pfoo_sized == nullptr); + + r->pfoo_sized = nvobj::make_persistent(); + }); + } catch (...) { + UT_ASSERT(0); + } + try { + /* Run outside of a transaction, expect error */ + nvobj::delete_persistent(r->pfoo_sized); + UT_ASSERT(0); + } catch (pmem::transaction_scope_error &) { + scope_error_delete_thrown = true; + } + UT_ASSERT(scope_error_delete_thrown); + + ctor_number = 0; + + try { + nvobj::transaction::run(pop, [&] { + UT_ASSERT(r->throwing_sized == nullptr); + + r->throwing_sized = + nvobj::make_persistent(); + UT_ASSERT(0); + }); + } catch (int &e) { + UT_ASSERT(e == struct_throwing::magic_number); + } + + try { + nvobj::transaction::run(pop, [&] { + nvobj::delete_persistent(r->pfoo_sized); + r->pfoo_sized = nullptr; + + nvobj::delete_persistent(r->pfoo, 10); + r->pfoo = nullptr; + }); + } catch (std::exception &e) { + UT_FATALexc(e); + } +} + +/* + * test_flags -- (internal) test proper handling of flags + */ +void +test_flags(nvobj::pool &pop) +{ + nvobj::persistent_ptr r = pop.root(); + + auto alloc_class = pop.ctl_set( + "heap.alloc_class.new.desc", + {sizeof(foo), 0, 100, POBJ_HEADER_COMPACT, 0}); + + try { + nvobj::transaction::run(pop, [&] { + UT_ASSERT(r->pfoo_sized == nullptr); + r->pfoo_sized = nvobj::make_persistent( + nvobj::allocation_flag::class_id( + alloc_class.class_id)); + + UT_ASSERT(r->pfoo == nullptr); + r->pfoo = nvobj::make_persistent( + 10, + nvobj::allocation_flag::class_id( + alloc_class.class_id)); + }); + } catch (std::exception &e) { + UT_FATALexc(e); + } + + UT_ASSERTeq(pmemobj_alloc_usable_size(r->pfoo.raw()), sizeof(foo) * 10); + UT_ASSERTeq(pmemobj_alloc_usable_size(r->pfoo_sized.raw()), + sizeof(foo) * 10); + + try { + nvobj::transaction::run(pop, [&] { + nvobj::delete_persistent(r->pfoo_sized); + r->pfoo_sized = nullptr; + + nvobj::delete_persistent(r->pfoo, 10); + r->pfoo = nullptr; + }); + } catch (std::exception &e) { + UT_FATALexc(e); + } +} + +/* + * test_nullptr -- (internal) test proper handling of null pointers + */ +void +test_nullptr(nvobj::pool &pop) +{ + nvobj::transaction::run(pop, [&] { + nvobj::persistent_ptr f; + f = nullptr; + nvobj::delete_persistent(f, 1); + + nvobj::persistent_ptr f2; + f2 = nullptr; + nvobj::delete_persistent(f2); + }); +} +} + +int +main(int argc, char *argv[]) +{ + START(); + + if (argc != 2) + UT_FATAL("usage: %s file-name", argv[0]); + + const char *path = argv[1]; + + nvobj::pool pop; + + try { + pop = nvobj::pool::create( + path, LAYOUT, PMEMOBJ_MIN_POOL, S_IWUSR | S_IRUSR); + } catch (pmem::pool_error &pe) { + UT_FATAL("!pool::create: %s %s", pe.what(), path); + } + + test_make_one_d(pop); + test_make_N_d(pop); + test_abort_revert(pop); + test_exceptions_handling(pop); + test_exceptions_handling_sized(pop); + test_flags(pop); + test_nullptr(pop); + + pop.close(); + + return 0; +} diff --git a/tests/make_persistent_array_atomic/make_persistent_array_atomic.cpp b/tests/make_persistent_array_atomic/make_persistent_array_atomic.cpp new file mode 100644 index 0000000..9d4b6ed --- /dev/null +++ b/tests/make_persistent_array_atomic/make_persistent_array_atomic.cpp @@ -0,0 +1,275 @@ +/* + * Copyright 2016-2019, Intel Corporation + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * * Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +/* + * obj_cpp_make_persistent_array_atomic.cpp -- cpp make_persistent test for + * arrays + */ + +#include "unittest.hpp" + +#include +#include +#include +#include +#include + +#define LAYOUT "cpp" + +namespace nvobj = pmem::obj; + +namespace +{ + +const int TEST_ARR_SIZE = 10; + +class foo { +public: + foo() : bar(1) + { + for (int i = 0; i < TEST_ARR_SIZE; ++i) + this->arr[i] = 1; + } + + /* + * Assert values of foo. + */ + void + check_foo() + { + UT_ASSERTeq(1, this->bar); + for (int i = 0; i < TEST_ARR_SIZE; ++i) + UT_ASSERTeq(1, this->arr[i]); + } + + ~foo() = default; + + nvobj::p bar; + nvobj::p arr[TEST_ARR_SIZE]; +}; + +struct root { + nvobj::persistent_ptr pfoo; +}; + +class bar { +public: + bar() + { + /* throw any exception */ + throw 1; + } +}; + +/* + * test_make_one_d -- (internal) test make_persistent of a 1d array + */ +void +test_make_one_d(nvobj::pool_base &pop) +{ + nvobj::persistent_ptr pfoo; + nvobj::make_persistent_atomic(pop, pfoo, 5); + for (int i = 0; i < 5; ++i) + pfoo[i].check_foo(); + + nvobj::delete_persistent_atomic(pfoo, 5); + + nvobj::make_persistent_atomic(pop, pfoo, 6); + for (int i = 0; i < 6; ++i) + pfoo[i].check_foo(); + + nvobj::delete_persistent_atomic(pfoo, 6); + + nvobj::persistent_ptr pfooN; + nvobj::make_persistent_atomic(pop, pfooN); + for (int i = 0; i < 5; ++i) + pfooN[i].check_foo(); + + nvobj::delete_persistent_atomic(pfooN); +} + +/* + * test_make_N_d -- (internal) test make_persistent of 2d and 3d arrays + */ +void +test_make_N_d(nvobj::pool_base &pop) +{ + nvobj::persistent_ptr pfoo; + nvobj::make_persistent_atomic(pop, pfoo, 5); + for (int i = 0; i < 5; ++i) + for (int j = 0; j < 2; j++) + pfoo[i][j].check_foo(); + + nvobj::delete_persistent_atomic(pfoo, 5); + + nvobj::persistent_ptr pfoo2; + nvobj::make_persistent_atomic(pop, pfoo2, 6); + for (int i = 0; i < 6; ++i) + for (int j = 0; j < 3; j++) + pfoo2[i][j].check_foo(); + + nvobj::delete_persistent_atomic(pfoo2, 6); + + nvobj::persistent_ptr pfooN; + nvobj::make_persistent_atomic(pop, pfooN); + for (int i = 0; i < 5; ++i) + for (int j = 0; j < 2; j++) + pfooN[i][j].check_foo(); + + nvobj::delete_persistent_atomic(pfooN); + + nvobj::persistent_ptr pfoo3; + nvobj::make_persistent_atomic(pop, pfoo3, 5); + for (int i = 0; i < 5; ++i) + for (int j = 0; j < 2; j++) + for (int k = 0; k < 3; k++) + pfoo3[i][j][k].check_foo(); + + nvobj::delete_persistent_atomic(pfoo3, 5); + + nvobj::persistent_ptr pfoo3N; + nvobj::make_persistent_atomic(pop, pfoo3N); + for (int i = 0; i < 5; ++i) + for (int j = 0; j < 2; j++) + for (int k = 0; k < 3; k++) + pfoo3N[i][j][k].check_foo(); + + nvobj::delete_persistent_atomic(pfoo3N); +} + +/* + * test_constructor_exception -- (internal) test exceptions thrown in + * constructors + */ +void +test_constructor_exception(nvobj::pool_base &pop) +{ + nvobj::persistent_ptr pfoo; + bool except = false; + try { + nvobj::make_persistent_atomic(pop, pfoo, 5); + } catch (std::bad_alloc &) { + except = true; + } + + UT_ASSERT(except); +} + +/* + * test_delete_null -- (internal) test atomic delete nullptr + */ +void +test_delete_null() +{ + nvobj::persistent_ptr pfoo; + nvobj::persistent_ptr pbar; + + UT_ASSERT(pfoo == nullptr); + UT_ASSERT(pbar == nullptr); + + try { + nvobj::delete_persistent_atomic(pfoo, 2); + nvobj::delete_persistent_atomic(pbar); + } catch (...) { + UT_ASSERT(0); + } +} + +/* + * test_flags -- (internal) test proper handling of flags + */ +void +test_flags(nvobj::pool &pop) +{ + nvobj::persistent_ptr pfoo = nullptr; + nvobj::persistent_ptr pfoo_sized = nullptr; + + auto alloc_class = pop.ctl_set( + "heap.alloc_class.new.desc", + {sizeof(foo), 0, 200, POBJ_HEADER_COMPACT, 0}); + + try { + nvobj::make_persistent_atomic( + pop, pfoo_sized, + nvobj::allocation_flag_atomic::class_id( + alloc_class.class_id)); + + nvobj::make_persistent_atomic( + pop, pfoo, 10, + nvobj::allocation_flag_atomic::class_id( + alloc_class.class_id)); + } catch (std::exception &e) { + UT_FATALexc(e); + } + + UT_ASSERTeq(pmemobj_alloc_usable_size(pfoo.raw()), sizeof(foo) * 10); + UT_ASSERTeq(pmemobj_alloc_usable_size(pfoo_sized.raw()), + sizeof(foo) * 10); + + try { + nvobj::delete_persistent_atomic(pfoo, 10); + nvobj::delete_persistent_atomic(pfoo_sized); + } catch (std::exception &e) { + UT_FATALexc(e); + } +} +} + +int +main(int argc, char *argv[]) +{ + START(); + + if (argc != 2) + UT_FATAL("usage: %s file-name", argv[0]); + + const char *path = argv[1]; + + nvobj::pool pop; + + try { + pop = nvobj::pool::create( + path, LAYOUT, PMEMOBJ_MIN_POOL, S_IWUSR | S_IRUSR); + } catch (pmem::pool_error &pe) { + UT_FATAL("!pool::create: %s %s", pe.what(), path); + } + + test_make_one_d(pop); + test_make_N_d(pop); + test_constructor_exception(pop); + test_delete_null(); + test_flags(pop); + + pop.close(); + + return 0; +} diff --git a/tests/make_persistent_atomic/make_persistent_atomic.cpp b/tests/make_persistent_atomic/make_persistent_atomic.cpp new file mode 100644 index 0000000..dceb79d --- /dev/null +++ b/tests/make_persistent_atomic/make_persistent_atomic.cpp @@ -0,0 +1,340 @@ +/* + * Copyright 2016-2019, Intel Corporation + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * * Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +/* + * obj_cpp_make_persistent_atomic.cpp -- cpp make_persistent_atomic test for + * objects + */ + +#include "unittest.hpp" + +#include +#include +#include +#include +#include + +#define LAYOUT "cpp" + +namespace nvobj = pmem::obj; + +namespace +{ + +const int TEST_ARR_SIZE = 10; + +struct force_throw { +}; + +class foo { +public: + foo() : bar(1) + { + for (int i = 0; i < TEST_ARR_SIZE; ++i) + this->arr[i] = 1; + } + + foo(const int &val) : bar(val) + { + for (int i = 0; i < TEST_ARR_SIZE; ++i) + this->arr[i] = static_cast(val); + } + + foo(const int &val, char arr_val) : bar(val) + { + for (int i = 0; i < TEST_ARR_SIZE; ++i) + this->arr[i] = arr_val; + } + + explicit foo(struct force_throw &val) + { + throw std::bad_alloc(); + } + + /* + * Assert values of foo. + */ + void + check_foo(int val, char arr_val) + { + UT_ASSERTeq(val, this->bar); + for (int i = 0; i < TEST_ARR_SIZE; ++i) + UT_ASSERTeq(arr_val, this->arr[i]); + } + + nvobj::p bar; + nvobj::p arr[TEST_ARR_SIZE]; +}; + +static int var_bar_copy_ctors_called = 0; +static int var_bar_move_ctors_called = 0; + +struct var_bar { + + /* Expects 'a' to be rvalue ref and 'b' and 'c' to be lvalue ref. */ + template + var_bar(A &&a, B &&b, C &&c) + { + static_assert(std::is_rvalue_reference::value, ""); + static_assert(std::is_lvalue_reference::value, ""); + static_assert(std::is_lvalue_reference::value, ""); + } + + var_bar(const var_bar &a) + { + var_bar_copy_ctors_called++; + } + + var_bar(var_bar &&a) + { + var_bar_move_ctors_called++; + } +}; + +struct root { + nvobj::persistent_ptr pfoo; + nvobj::persistent_ptr pvbar; +}; + +/* + * test_make_no_args -- (internal) test make_persistent without arguments + */ +void +test_make_no_args(nvobj::pool &pop) +{ + nvobj::persistent_ptr r = pop.root(); + + UT_ASSERT(r->pfoo == nullptr); + + nvobj::make_persistent_atomic(pop, r->pfoo); + r->pfoo->check_foo(1, 1); + + nvobj::delete_persistent_atomic(r->pfoo); +} + +/* + * test_make_args -- (internal) test make_persistent with arguments + */ +void +test_make_args(nvobj::pool &pop) +{ + nvobj::persistent_ptr r = pop.root(); + UT_ASSERT(r->pfoo == nullptr); + + nvobj::make_persistent_atomic(pop, r->pfoo, 2); + r->pfoo->check_foo(2, 2); + + nvobj::delete_persistent_atomic(r->pfoo); + + nvobj::make_persistent_atomic(pop, r->pfoo, 3, 4); + r->pfoo->check_foo(3, 4); + + nvobj::delete_persistent_atomic(r->pfoo); +} + +/* + * test_throw -- (internal) test if make_persistent_atomic rethrows constructor + * exception + */ +void +test_throw(nvobj::pool &pop) +{ + nvobj::persistent_ptr r = pop.root(); + UT_ASSERT(r->pfoo == nullptr); + + bool exception_thrown = false; + force_throw val; + try { + nvobj::make_persistent_atomic(pop, r->pfoo, val); + } catch (std::bad_alloc &) { + exception_thrown = true; + } catch (std::exception &e) { + UT_FATALexc(e); + } + + UT_ASSERT(exception_thrown); + UT_ASSERT(r->pfoo == nullptr); +} + +/* + * test_delete_null -- (internal) test atomic delete nullptr + */ +void +test_delete_null(nvobj::pool &pop) +{ + nvobj::persistent_ptr pfoo; + + UT_ASSERT(pfoo == nullptr); + + try { + nvobj::delete_persistent_atomic(pfoo); + } catch (...) { + UT_ASSERT(0); + } +} + +/* + * test_flags -- (internal) test proper handling of flags + */ +void +test_flags(nvobj::pool &pop) +{ + nvobj::persistent_ptr r = pop.root(); + + auto alloc_class = pop.ctl_set( + "heap.alloc_class.new.desc", + {sizeof(foo) + 16, 0, 200, POBJ_HEADER_COMPACT, 0}); + + try { + nvobj::make_persistent_atomic( + pop, r->pfoo, + nvobj::allocation_flag_atomic::class_id( + alloc_class.class_id)); + } catch (std::exception &e) { + UT_FATALexc(e); + } + + UT_ASSERTeq(pmemobj_alloc_usable_size(r->pfoo.raw()), sizeof(foo)); + + try { + nvobj::delete_persistent_atomic(r->pfoo); + } catch (std::exception &e) { + UT_FATALexc(e); + } + + try { + nvobj::make_persistent_atomic( + pop, r->pfoo, + nvobj::allocation_flag_atomic::class_id( + alloc_class.class_id), + 1, 2); + } catch (std::exception &e) { + UT_FATALexc(e); + } + + r->pfoo->check_foo(1, 2); + + UT_ASSERTeq(pmemobj_alloc_usable_size(r->pfoo.raw()), sizeof(foo)); + + try { + nvobj::delete_persistent_atomic(r->pfoo); + } catch (std::exception &e) { + UT_FATALexc(e); + } +} + +/* + * test_rlvalue_parameters -- (internal) test proper forwarding of arguments + * to the constructor (maintaining rvalue and lvalue reference types) + */ +void +test_rlvalue_parameters(nvobj::pool &pop) +{ + auto r = pop.root(); + + int a = 1, b = 2, c = 3; + nvobj::make_persistent_atomic(pop, r->pvbar, std::move(a), b, + c); + + nvobj::persistent_ptr vbar1; + nvobj::persistent_ptr vbar2; + nvobj::persistent_ptr vbar3; + + nvobj::make_persistent_atomic(pop, vbar1, *r->pvbar); + UT_ASSERT(var_bar_copy_ctors_called == 1); + UT_ASSERT(var_bar_move_ctors_called == 0); + + nvobj::make_persistent_atomic(pop, vbar2, *r->pvbar); + UT_ASSERT(var_bar_copy_ctors_called == 2); + UT_ASSERT(var_bar_move_ctors_called == 0); + + nvobj::make_persistent_atomic(pop, vbar3, + std::move(*r->pvbar)); + + UT_ASSERT(var_bar_copy_ctors_called == 2); + UT_ASSERT(var_bar_move_ctors_called == 1); +} + +/* + * test_make_invalid -- (internal) test failure of atomic make_persistent + */ +void +test_make_invalid(nvobj::pool &pop) +{ + nvobj::persistent_ptr pfoo; + + bool thrown = false; + try { + nvobj::make_persistent_atomic( + pop, pfoo, + nvobj::allocation_flag_atomic::class_id(254)); + } catch (std::bad_alloc &e) { + thrown = true; + } catch (std::exception &e) { + UT_FATALexc(e); + } + + UT_ASSERT(thrown); +} +} + +int +main(int argc, char *argv[]) +{ + START(); + + if (argc != 2) + UT_FATAL("usage: %s file-name", argv[0]); + + const char *path = argv[1]; + + nvobj::pool pop; + + try { + pop = nvobj::pool::create( + path, LAYOUT, PMEMOBJ_MIN_POOL, S_IWUSR | S_IRUSR); + } catch (pmem::pool_error &pe) { + UT_FATAL("!pool::create: %s %s", pe.what(), path); + } + + test_make_no_args(pop); + test_make_args(pop); + test_throw(pop); + test_delete_null(pop); + test_flags(pop); + test_rlvalue_parameters(pop); + test_make_invalid(pop); + + pop.close(); + + return 0; +} diff --git a/tests/match b/tests/match new file mode 100755 index 0000000..281843b --- /dev/null +++ b/tests/match @@ -0,0 +1,328 @@ +#!/usr/bin/env perl +# +# Copyright 2014-2018, Intel Corporation +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# +# * Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# +# * Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in +# the documentation and/or other materials provided with the +# distribution. +# +# * Neither the name of the copyright holder nor the names of its +# contributors may be used to endorse or promote products derived +# from this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +# + +# +# match -- compare an output file with expected results +# +# usage: match [-adoqv] [match-file]... +# +# this script compares the output from a test run, stored in a file, with +# the expected output. comparison is done line-by-line until either all +# lines compare correctly (exit code 0) or a miscompare is found (exit +# code nonzero). +# +# expected output is stored in a ".match" file, which contains a copy of +# the expected output with embedded tokens for things that should not be +# exact matches. the supported tokens are: +# +# $(N) an integer (i.e. one or more decimal digits) +# $(NC) one or more decimal digits with comma separators +# $(FP) a floating point number +# $(S) ascii string +# $(X) hex number +# $(XX) hex number prefixed with 0x +# $(W) whitespace +# $(nW) non-whitespace +# $(*) any string +# $(DD) output of a "dd" run +# $(OPT) line is optional (may be missing, matched if found) +# $(OPX) ends a contiguous list of $(OPT)...$(OPX) lines, at least +# one of which must match +# ${string1|string2} string1 OR string2 +# +# Additionally, if any "X.ignore" file exists, strings or phrases found per +# line in the file will be ignored if found as a substring in the +# corresponding output file (making it easy to skip entire output lines). +# +# arguments are: +# +# -a find all files of the form "X.match" in the current +# directory and match them again the corresponding file "X". +# +# -o custom output filename - only one match file can be given +# +# -d debug -- show lots of debug output +# +# -q don't print log files on mismatch +# +# -v verbose -- show every line as it is being matched +# + +use strict; +use Getopt::Std; +use Encode; +use v5.16; + +select STDERR; +binmode(STDOUT, ":utf8"); +binmode(STDERR, ":utf8"); + +my $Me = $0; +$Me =~ s,.*/,,; + +our ($opt_a, $opt_d, $opt_q, $opt_v, $opt_o); + +$SIG{HUP} = $SIG{INT} = $SIG{TERM} = $SIG{__DIE__} = sub { + die @_ if $^S; + my $errstr = shift; + die "FAIL: $Me: $errstr"; +}; + +sub usage { + my $msg = shift; + + warn "$Me: $msg\n" if $msg; + warn "Usage: $Me [-adqv] [match-file]...\n"; + warn " or: $Me [-dqv] -o output-file match-file...\n"; + exit 1; +} + +getopts('adoqv') or usage; + +my %match2file; + +if ($opt_a) { + usage("-a and filename arguments are mutually exclusive") + if $#ARGV != -1; + opendir(DIR, '.') or die "opendir: .: $!\n"; + my @matchfiles = grep { /(.*)\.match$/ && -f $1 } readdir(DIR); + closedir(DIR); + die "no files found to process\n" unless @matchfiles; + foreach my $mfile (@matchfiles) { + die "$mfile: $!\n" unless open(F, $mfile); + close(F); + my $ofile = $mfile; + $ofile =~ s/\.match$//; + die "$mfile found but cannot open $ofile: $!\n" + unless open(F, $ofile); + close(F); + $match2file{$mfile} = $ofile; + } +} elsif ($opt_o) { + usage("-o argument requires two paths") if $#ARGV != 1; + + $match2file{$ARGV[1]} = $ARGV[0]; +} else { + usage("no match-file arguments found") if $#ARGV == -1; + + # to improve the failure case, check all filename args exist and + # are provided in pairs now, before going through and processing them + foreach my $mfile (@ARGV) { + my $ofile = $mfile; + usage("$mfile: not a .match file") unless + $ofile =~ s/\.match$//; + usage("$mfile: $!") unless open(F, $mfile); + close(F); + usage("$ofile: $!") unless open(F, $ofile); + close(F); + $match2file{$mfile} = $ofile; + } +} + +my $mfile; +my $ofile; +my $ifile; +print "Files to be processed:\n" if $opt_v; +foreach $mfile (sort keys %match2file) { + $ofile = $match2file{$mfile}; + $ifile = $ofile . ".ignore"; + $ifile = undef unless (-f $ifile); + if ($opt_v) { + print " match-file \"$mfile\" output-file \"$ofile\""; + if ($ifile) { + print " ignore-file $ifile\n"; + } else { + print "\n"; + } + } + match($mfile, $ofile, $ifile); +} + +exit 0; + +# +# strip_it - user can optionally ignore lines from files that contain +# any number of substrings listed in a file called "X.ignore" where X +# is the name of the output file. +# +sub strip_it { + my ($ifile, $file, $input) = @_; + # if there is no ignore file just return unaltered input + return $input unless $ifile; + my @lines_in = split /^/, $input; + my $output; + my $line_in; + my @i_file = split /^/, snarf($ifile); + my $i_line; + my $ignore_it = 0; + + foreach $line_in (@lines_in) { + my @i_lines = @i_file; + foreach $i_line (@i_lines) { + chop($i_line); + if (index($line_in, $i_line) != -1) { + $ignore_it = 1; + if ($opt_v) { + print "Ignoring (from $file): $line_in"; + } + } + } + if ($ignore_it == 0) { + $output .= $line_in; + } + $ignore_it = 0; + } + return $output; +} + +# +# match -- process a match-file, output-file pair +# +sub match { + my ($mfile, $ofile, $ifile) = @_; + my $pat; + my $output = snarf($ofile); + $output = strip_it($ifile, $ofile, $output); + my $all_lines = $output; + my $line_pat = 0; + my $line_out = 0; + my $opt = 0; + my $opx = 0; + my $opt_found = 0; + my $fstr = snarf($mfile); + $fstr = strip_it($ifile, $mfile, $fstr); + for (split /^/, $fstr) { + $pat = $_; + $line_pat++; + $line_out++; + s/([*+?|{}.\\^\$\[()])/\\$1/g; + s/\\\$\\\(FP\\\)/[-+]?\\d*\\.?\\d+([eE][-+]?\\d+)?/g; + s/\\\$\\\(N\\\)/[-+]?\\d+/g; + s/\\\$\\\(NC\\\)/[-+]?\\d+(,[0-9]+)*/g; + s/\\\$\\\(\\\*\\\)/\\p{Print}*/g; + s/\\\$\\\(S\\\)/\\P{IsC}+/g; + s/\\\$\\\(X\\\)/\\p{XPosixXDigit}+/g; + s/\\\$\\\(XX\\\)/0x\\p{XPosixXDigit}+/g; + s/\\\$\\\(W\\\)/\\p{Blank}*/g; + s/\\\$\\\(nW\\\)/\\p{Graph}*/g; + s/\\\$\\\{([^|]*)\\\|([^|]*)\\\}/($1|$2)/g; + s/\\\$\\\(DD\\\)/\\d+\\+\\d+ records in\n\\d+\\+\\d+ records out\n\\d+ bytes \\\(\\d+ .B\\\) copied, [.0-9e-]+[^,]*, [.0-9]+ .B.s/g; + if (s/\\\$\\\(OPT\\\)//) { + $opt = 1; + } elsif (s/\\\$\\\(OPX\\\)//) { + $opx = 1; + } else { + $opt_found = 0; + } + + if ($opt_v) { + my @lines = split /\n/, $output; + my $line; + if (@lines) { + $line = $lines[0]; + } else { + $line = "[EOF]"; + } + + printf("%s:%-3d %s%s:%-3d %s\n", $mfile, $line_pat, $pat, $ofile, $line_out, $line); + } + + print " => /$_/\n" if $opt_d; + print " [$output]\n" if $opt_d; + unless ($output =~ s/^$_//) { + if ($opt || ($opx && $opt_found)) { + printf("%s:%-3d [skipping optional line]\n", $ofile, $line_out) if $opt_v; + $line_out--; + $opt = 0; + } else { + if (!$opt_v) { + if ($opt_q) { + print "[MATCHING FAILED]\n"; + } else { + print "[MATCHING FAILED, COMPLETE FILE ($ofile) BELOW]\n$all_lines\n[EOF]\n"; + } + $opt_v = 1; + match($mfile, $ofile); + } + + die "$mfile:$line_pat did not match pattern\n"; + } + } elsif ($opt) { + $opt_found = 1; + } + $opx = 0; + } + + if ($output ne '') { + if (!$opt_v) { + if ($opt_q) { + print "[MATCHING FAILED]\n"; + } else { + print "[MATCHING FAILED, COMPLETE FILE ($ofile) BELOW]\n$all_lines\n[EOF]\n"; + } + } + + # make it a little more print-friendly... + $output =~ s/\n/\\n/g; + die "line $line_pat: unexpected output: \"$output\"\n"; + } +} + + +# +# snarf -- slurp an entire file into memory +# +sub snarf { + my ($file) = @_; + my $fh; + open($fh, '<', $file) or die "$file $!\n"; + + local $/; + $_ = <$fh>; + close $fh; + + # check known encodings or die + my $decoded; + my @encodings = ("UTF-8", "UTF-16", "UTF-16LE", "UTF-16BE"); + + foreach my $enc (@encodings) { + eval { $decoded = decode( $enc, $_, Encode::FB_CROAK ) }; + + if (!$@) { + $decoded =~ s/\R/\n/g; + return $decoded; + } + } + + die "$Me: ERROR: Unknown file encoding"; +} diff --git a/tests/memcheck-libunwind.supp b/tests/memcheck-libunwind.supp new file mode 100644 index 0000000..04ee9b1 --- /dev/null +++ b/tests/memcheck-libunwind.supp @@ -0,0 +1,23 @@ +{ + generic libunwind suppression + Memcheck:Param + msync(start) + ... + obj:*libunwind* + ... +} +{ + generic libunwind suppression + Memcheck:Param + rt_sigprocmask(set) + ... + obj:*libunwind* + ... +} +{ + generic libunwind suppression + Memcheck:Addr8 + ... + obj:*libunwind* + ... +} diff --git a/tests/memcheck-stdcpp.supp b/tests/memcheck-stdcpp.supp new file mode 100644 index 0000000..31d4e6a --- /dev/null +++ b/tests/memcheck-stdcpp.supp @@ -0,0 +1,11 @@ +{ + https://bugs.kde.org/show_bug.cgi?id=345307, https://gcc.gnu.org/bugzilla/show_bug.cgi?id=65434, https://gcc.gnu.org/bugzilla/show_bug.cgi?id=64535 + Memcheck:Leak + match-leak-kinds: reachable + fun:malloc + obj:*/libstdc++.so.* + fun:call_init.part.0 + ... + fun:_dl_init + obj:*/ld-*.so +} diff --git a/tests/mutex/mutex.cpp b/tests/mutex/mutex.cpp new file mode 100644 index 0000000..c79761e --- /dev/null +++ b/tests/mutex/mutex.cpp @@ -0,0 +1,210 @@ +/* + * Copyright 2016-2018, Intel Corporation + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * * Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +/* + * obj_cpp_mutex.cpp -- cpp mutex test + */ + +#include "unittest.hpp" + +#include +#include +#include + +#include +#include + +#define LAYOUT "cpp" + +namespace nvobj = pmem::obj; + +namespace +{ + +/* pool root structure */ +struct root { + nvobj::mutex pmutex; + unsigned counter; +}; + +/* number of ops per thread */ +const unsigned num_ops = 200; + +/* the number of threads */ +const unsigned num_threads = 30; + +/* + * increment_pint -- (internal) test the mutex with an std::lock_guard + */ +void +increment_pint(nvobj::persistent_ptr proot) +{ + for (unsigned i = 0; i < num_ops; ++i) { + std::lock_guard lock(proot->pmutex); + (proot->counter)++; + } +} + +/* + * decrement_pint -- (internal) test the mutex with an std::unique_lock + */ +void +decrement_pint(nvobj::persistent_ptr proot) +{ + std::unique_lock lock(proot->pmutex); + for (unsigned i = 0; i < num_ops; ++i) + --(proot->counter); + + lock.unlock(); +} + +/* + * trylock_test -- (internal) test the trylock implementation + */ +void +trylock_test(nvobj::persistent_ptr proot) +{ + for (;;) { + if (proot->pmutex.try_lock()) { + (proot->counter)++; + proot->pmutex.unlock(); + return; + } + } +} + +/* + * mutex_zero_test -- (internal) test the zeroing constructor + */ +void +mutex_zero_test(nvobj::pool &pop) +{ + PMEMoid raw_mutex; + + pmemobj_alloc(pop.handle(), &raw_mutex, sizeof(PMEMmutex), 1, + [](PMEMobjpool *pop, void *ptr, void *) -> int { + PMEMmutex *mtx = static_cast(ptr); + pmemobj_memset_persist(pop, mtx, 1, sizeof(*mtx)); + return 0; + }, + nullptr); + + nvobj::mutex *placed_mtx = new (pmemobj_direct(raw_mutex)) nvobj::mutex; + std::unique_lock lck(*placed_mtx); +} + +/* + * mutex_test -- (internal) launch worker threads to test the pmutex + */ +template +void +mutex_test(nvobj::pool &pop, const Worker &function) +{ + std::thread threads[num_threads]; + + nvobj::persistent_ptr proot = pop.root(); + + for (unsigned i = 0; i < num_threads; ++i) + threads[i] = std::thread(function, proot); + + for (unsigned i = 0; i < num_threads; ++i) + threads[i].join(); +} + +void +test_stack() +{ + /* mutex is not allowed outside of pmem */ + try { + nvobj::mutex stack_mutex; + UT_ASSERT(0); + } catch (pmem::lock_error &le) { + } catch (...) { + UT_ASSERT(0); + } +} + +void +test_error_handling(nvobj::pool &pop) +{ + nvobj::persistent_ptr proot = pop.root(); + + proot->pmutex.lock(); + + /* try_locking already taken lock fails with false */ + UT_ASSERT(proot->pmutex.try_lock() == false); + + proot->pmutex.unlock(); +} +} + +int +main(int argc, char *argv[]) +{ + START(); + + if (argc != 2) + UT_FATAL("usage: %s file-name", argv[0]); + + const char *path = argv[1]; + + nvobj::pool pop; + + try { + pop = nvobj::pool::create( + path, LAYOUT, PMEMOBJ_MIN_POOL, S_IWUSR | S_IRUSR); + } catch (pmem::pool_error &pe) { + UT_FATAL("!pool::create: %s %s", pe.what(), path); + } + + mutex_zero_test(pop); + + mutex_test(pop, increment_pint); + UT_ASSERTeq(pop.root()->counter, num_threads * num_ops); + + mutex_test(pop, decrement_pint); + UT_ASSERTeq(pop.root()->counter, 0); + + mutex_test(pop, trylock_test); + UT_ASSERTeq(pop.root()->counter, num_threads); + + /* pmemcheck related persist */ + pmemobj_persist(pop.handle(), &(pop.root()->counter), + sizeof(pop.root()->counter)); + + test_stack(); + test_error_handling(pop); + + pop.close(); + + return 0; +} diff --git a/tests/mutex_posix/mutex_posix.cpp b/tests/mutex_posix/mutex_posix.cpp new file mode 100644 index 0000000..59c8f42 --- /dev/null +++ b/tests/mutex_posix/mutex_posix.cpp @@ -0,0 +1,192 @@ +/* + * Copyright 2016-2018, Intel Corporation + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * * Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +/* + * obj_cpp_mutex_posix.cpp -- cpp mutex test + */ + +#include "pthread_common.hpp" +#include "unittest.hpp" + +#include +#include +#include + +#include + +#define LAYOUT "cpp" + +namespace nvobj = pmem::obj; + +namespace +{ + +/* pool root structure */ +struct root { + nvobj::mutex pmutex; + unsigned counter; +}; + +/* number of ops per thread */ +const unsigned num_ops = 200; + +/* the number of threads */ +const unsigned num_threads = 30; + +/* + * increment_pint -- (internal) test the mutex with an std::lock_guard + */ +void * +increment_pint(void *arg) +{ + nvobj::persistent_ptr *proot = + static_cast *>(arg); + + for (unsigned i = 0; i < num_ops; ++i) { + std::lock_guard lock((*proot)->pmutex); + ((*proot)->counter)++; + } + return nullptr; +} + +/* + * decrement_pint -- (internal) test the mutex with an std::unique_lock + */ +void * +decrement_pint(void *arg) +{ + nvobj::persistent_ptr *proot = + static_cast *>(arg); + + std::unique_lock lock((*proot)->pmutex); + for (unsigned i = 0; i < num_ops; ++i) + --((*proot)->counter); + + lock.unlock(); + return nullptr; +} + +/* + * trylock_test -- (internal) test the trylock implementation + */ +void * +trylock_test(void *arg) +{ + nvobj::persistent_ptr *proot = + static_cast *>(arg); + for (;;) { + if ((*proot)->pmutex.try_lock()) { + ((*proot)->counter)++; + (*proot)->pmutex.unlock(); + break; + } + } + return nullptr; +} + +/* + * mutex_zero_test -- (internal) test the zeroing constructor + */ +void +mutex_zero_test(nvobj::pool &pop) +{ + PMEMoid raw_mutex; + + pmemobj_alloc(pop.handle(), &raw_mutex, sizeof(PMEMmutex), 1, + [](PMEMobjpool *pop, void *ptr, void *arg) -> int { + PMEMmutex *mtx = static_cast(ptr); + pmemobj_memset_persist(pop, mtx, 1, sizeof(*mtx)); + return 0; + }, + nullptr); + + nvobj::mutex *placed_mtx = new (pmemobj_direct(raw_mutex)) nvobj::mutex; + std::unique_lock lck(*placed_mtx); +} + +/* + * mutex_test -- (internal) launch worker threads to test the pmutex + */ +template +void +mutex_test(nvobj::pool &pop, Worker function) +{ + pthread_t threads[num_threads]; + + nvobj::persistent_ptr proot = pop.root(); + + for (unsigned i = 0; i < num_threads; ++i) + ut_pthread_create(&threads[i], nullptr, function, &proot); + + for (unsigned i = 0; i < num_threads; ++i) + ut_pthread_join(&threads[i], nullptr); +} +} + +int +main(int argc, char *argv[]) +{ + START(); + + if (argc != 2) + UT_FATAL("usage: %s file-name", argv[0]); + + const char *path = argv[1]; + + nvobj::pool pop; + + try { + pop = nvobj::pool::create( + path, LAYOUT, PMEMOBJ_MIN_POOL, S_IWUSR | S_IRUSR); + } catch (pmem::pool_error &pe) { + UT_FATAL("!pool::create: %s %s", pe.what(), path); + } + + mutex_zero_test(pop); + + mutex_test(pop, increment_pint); + UT_ASSERTeq(pop.root()->counter, num_threads * num_ops); + + mutex_test(pop, decrement_pint); + UT_ASSERTeq(pop.root()->counter, 0); + + mutex_test(pop, trylock_test); + UT_ASSERTeq(pop.root()->counter, num_threads); + + /* pmemcheck related persist */ + pmemobj_persist(pop.handle(), &(pop.root()->counter), + sizeof(pop.root()->counter)); + + pop.close(); + + return 0; +} diff --git a/tests/p_ext/p_ext.cpp b/tests/p_ext/p_ext.cpp new file mode 100644 index 0000000..0447fbc --- /dev/null +++ b/tests/p_ext/p_ext.cpp @@ -0,0 +1,401 @@ +/* + * Copyright 2015-2018, Intel Corporation + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * * Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +/* + * obj_cpp_p_ext.c -- cpp p<> property operators test + * + */ + +#include "unittest.hpp" + +#include +#include +#include +#include +#include + +#include +#include + +#define LAYOUT "cpp" + +namespace nvobj = pmem::obj; + +namespace +{ + +struct foo { + nvobj::p pint; + nvobj::p pllong; + nvobj::p puchar; +}; + +struct bar { + nvobj::p pdouble; + nvobj::p pfloat; +}; + +struct root { + nvobj::persistent_ptr bar_ptr; + nvobj::persistent_ptr foo_ptr; +}; + +/* + * init_foobar -- (internal) initialize the root object with specific values + */ +nvobj::persistent_ptr +init_foobar(nvobj::pool_base &pop) +{ + nvobj::pool &root_pop = + dynamic_cast &>(pop); + nvobj::persistent_ptr r = root_pop.root(); + + try { + nvobj::transaction::run(pop, [&] { + UT_ASSERT(r->bar_ptr == nullptr); + UT_ASSERT(r->foo_ptr == nullptr); + + r->bar_ptr = pmemobj_tx_alloc(sizeof(bar), 0); + r->foo_ptr = pmemobj_tx_alloc(sizeof(foo), 0); + + r->bar_ptr->pdouble = 1.0; + r->bar_ptr->pfloat = 2.0; + + r->foo_ptr->puchar = 0; + r->foo_ptr->pint = 1; + r->foo_ptr->pllong = 2; + }); + } catch (...) { + UT_ASSERT(0); + } + + return r; +} + +/* + * cleanup_foobar -- (internal) deallocate and zero out root fields + */ +void +cleanup_foobar(nvobj::pool_base &pop) +{ + nvobj::pool &root_pop = + dynamic_cast &>(pop); + nvobj::persistent_ptr r = root_pop.root(); + + try { + nvobj::transaction::run(pop, [&] { + UT_ASSERT(r->bar_ptr != nullptr); + UT_ASSERT(r->foo_ptr != nullptr); + + pmemobj_tx_free(r->bar_ptr.raw()); + r->bar_ptr = nullptr; + pmemobj_tx_free(r->foo_ptr.raw()); + r->foo_ptr = nullptr; + }); + } catch (...) { + UT_ASSERT(0); + } + + UT_ASSERT(r->bar_ptr == nullptr); + UT_ASSERT(r->foo_ptr == nullptr); +} + +/* + * arithmetic_test -- (internal) perform basic arithmetic tests on p<> + */ +void +arithmetic_test(nvobj::pool_base &pop) +{ + nvobj::persistent_ptr r = init_foobar(pop); + + /* operations test */ + try { + nvobj::transaction::run(pop, [&] { + /* addition */ + r->foo_ptr->puchar += r->foo_ptr->puchar; + r->foo_ptr->puchar += + static_cast(r->foo_ptr->pint); + r->foo_ptr->puchar += 2; + UT_ASSERTeq(r->foo_ptr->puchar, 3); + + r->foo_ptr->pint = + r->foo_ptr->pint + r->foo_ptr->puchar; + r->foo_ptr->pint = r->foo_ptr->pint + r->foo_ptr->pint; + r->foo_ptr->pint = + static_cast(r->foo_ptr->pllong + 8); + UT_ASSERTeq(r->foo_ptr->pint, 10); + + /* for float assertions */ + float epsilon = 0.001F; + + /* subtraction */ + r->bar_ptr->pdouble -= r->foo_ptr->puchar; + r->bar_ptr->pfloat -= 2; + UT_ASSERT(std::fabs(r->bar_ptr->pdouble + 2) < epsilon); + UT_ASSERT(std::fabs(r->bar_ptr->pfloat) < epsilon); + + r->bar_ptr->pfloat = static_cast( + r->bar_ptr->pfloat - r->bar_ptr->pdouble); + r->bar_ptr->pdouble = + r->bar_ptr->pdouble - r->bar_ptr->pfloat; + UT_ASSERT(std::fabs(r->bar_ptr->pfloat - 2) < epsilon); + UT_ASSERT(std::fabs(r->bar_ptr->pdouble + 4) < epsilon); + + /* multiplication */ + r->foo_ptr->puchar *= r->foo_ptr->puchar; + r->foo_ptr->puchar *= + static_cast(r->foo_ptr->pint); + r->foo_ptr->puchar *= + static_cast(r->foo_ptr->pllong); + UT_ASSERTeq(r->foo_ptr->puchar, 180); + + r->foo_ptr->pint = + r->foo_ptr->pint * r->foo_ptr->puchar; + r->foo_ptr->pint = r->foo_ptr->pint * r->foo_ptr->pint; + r->foo_ptr->pint = static_cast(r->foo_ptr->pllong * + r->foo_ptr->pint); + /* no assertions needed at this point */ + + /* division */ + r->bar_ptr->pdouble /= r->foo_ptr->puchar; + r->bar_ptr->pfloat /= r->foo_ptr->pllong; + /* no assertions needed at this point */ + + r->bar_ptr->pfloat = static_cast( + r->bar_ptr->pfloat / r->bar_ptr->pdouble); + r->bar_ptr->pdouble = + r->bar_ptr->pdouble / r->bar_ptr->pfloat; + /* no assertions needed at this point */ + + /* prefix */ + ++r->foo_ptr->pllong; + --r->foo_ptr->pllong; + UT_ASSERTeq(r->foo_ptr->pllong, 2); + + /* postfix */ + r->foo_ptr->pllong++; + r->foo_ptr->pllong--; + UT_ASSERTeq(r->foo_ptr->pllong, 2); + + /* modulo */ + r->foo_ptr->pllong = 12; + r->foo_ptr->pllong %= 7; + UT_ASSERTeq(r->foo_ptr->pllong, 5); + r->foo_ptr->pllong = r->foo_ptr->pllong % 3; + UT_ASSERTeq(r->foo_ptr->pllong, 2); + r->foo_ptr->pllong = + r->foo_ptr->pllong % r->foo_ptr->pllong; + UT_ASSERTeq(r->foo_ptr->pllong, 0); + }); + } catch (...) { + UT_ASSERT(0); + } + + cleanup_foobar(pop); +} + +/* + * bitwise_test -- (internal) perform basic bitwise operator tests on p<> + */ +void +bitwise_test(nvobj::pool_base &pop) +{ + nvobj::persistent_ptr r = init_foobar(pop); + + try { + nvobj::transaction::run(pop, [&] { + /* OR */ + r->foo_ptr->puchar |= r->foo_ptr->pllong; + r->foo_ptr->puchar |= r->foo_ptr->pint; + r->foo_ptr->puchar |= 4; + UT_ASSERTeq(r->foo_ptr->puchar, 7); + + r->foo_ptr->pint = + r->foo_ptr->pint | r->foo_ptr->puchar; + r->foo_ptr->pint = r->foo_ptr->pint | r->foo_ptr->pint; + r->foo_ptr->pint = + static_cast(r->foo_ptr->pllong | 0xF); + UT_ASSERTeq(r->foo_ptr->pint, 15); + + /* AND */ + r->foo_ptr->puchar &= r->foo_ptr->puchar; + r->foo_ptr->puchar &= r->foo_ptr->pint; + r->foo_ptr->puchar &= 2; + UT_ASSERTeq(r->foo_ptr->puchar, 2); + + r->foo_ptr->pint = + r->foo_ptr->pint & r->foo_ptr->puchar; + r->foo_ptr->pint = r->foo_ptr->pint & r->foo_ptr->pint; + r->foo_ptr->pint = r->foo_ptr->pllong & 8; + UT_ASSERTeq(r->foo_ptr->pint, 0); + + /* XOR */ + r->foo_ptr->puchar ^= r->foo_ptr->puchar; + r->foo_ptr->puchar ^= r->foo_ptr->pint; + r->foo_ptr->puchar ^= 2; + UT_ASSERTeq(r->foo_ptr->puchar, 2); + + r->foo_ptr->pint = + r->foo_ptr->pint ^ r->foo_ptr->puchar; + r->foo_ptr->pint = r->foo_ptr->pint ^ r->foo_ptr->pint; + r->foo_ptr->pint = + static_cast(r->foo_ptr->pllong ^ 8); + UT_ASSERTeq(r->foo_ptr->pint, 10); + + /* RSHIFT */ + r->foo_ptr->puchar = 255; + r->foo_ptr->puchar >>= 1; + r->foo_ptr->puchar >>= r->foo_ptr->puchar; + r->foo_ptr->puchar = static_cast( + r->foo_ptr->pllong >> 2); + r->foo_ptr->puchar = static_cast( + r->foo_ptr->pllong >> r->foo_ptr->pllong); + UT_ASSERTeq(r->foo_ptr->puchar, 0); + + /* LSHIFT */ + r->foo_ptr->puchar = 1; + r->foo_ptr->puchar <<= 1; + r->foo_ptr->puchar <<= r->foo_ptr->puchar; + r->foo_ptr->puchar = static_cast( + r->foo_ptr->pllong << 2); + r->foo_ptr->puchar = static_cast( + r->foo_ptr->pllong << r->foo_ptr->pllong); + UT_ASSERTeq(r->foo_ptr->puchar, 8); + + /* COMPLEMENT */ + r->foo_ptr->pint = 1; + UT_ASSERTeq(~r->foo_ptr->pint, ~1); + }); + } catch (...) { + UT_ASSERT(0); + } + + cleanup_foobar(pop); +} + +/* + * stream_test -- (internal) perform basic istream/ostream operator tests on p<> + */ +void +stream_test(nvobj::pool_base &pop) +{ + nvobj::persistent_ptr r = init_foobar(pop); + + try { + nvobj::transaction::run(pop, [&] { + std::stringstream stream("12.4"); + stream >> r->bar_ptr->pdouble; + /* + * clear the stream's EOF, + * we're ok with the buffer realloc + */ + stream.clear(); + stream.str(""); + r->bar_ptr->pdouble += 3.7; + stream << r->bar_ptr->pdouble; + stream >> r->foo_ptr->pint; + UT_ASSERTeq(r->foo_ptr->pint, 16); + }); + } catch (...) { + UT_ASSERT(0); + } + + cleanup_foobar(pop); +} + +/* + * swap_test -- (internal) perform basic swap tests on p<> + */ +void +swap_test(nvobj::pool_base &pop) +{ + struct _bar { + nvobj::p value; + }; + + nvobj::persistent_ptr<_bar> swap_one; + nvobj::persistent_ptr<_bar> swap_two; + try { + nvobj::transaction::run(pop, [&] { + swap_one = pmemobj_tx_zalloc(sizeof(_bar), 0); + swap_two = pmemobj_tx_zalloc(sizeof(_bar), 0); + }); + + nvobj::transaction::run(pop, [&] { + swap_one->value = 1; + swap_two->value = 2; + + swap(swap_one->value, swap_two->value); + UT_ASSERTeq(swap_one->value, 2); + UT_ASSERTeq(swap_two->value, 1); + + swap(swap_two->value, swap_one->value); + UT_ASSERTeq(swap_one->value, 1); + UT_ASSERTeq(swap_two->value, 2); + + pmemobj_tx_free(swap_one.raw()); + pmemobj_tx_free(swap_two.raw()); + }); + } catch (...) { + UT_ASSERT(0); + } +} +} + +int +main(int argc, char *argv[]) +{ + START(); + + if (argc != 2) + UT_FATAL("usage: %s file-name", argv[0]); + + const char *path = argv[1]; + + nvobj::pool pop; + + try { + pop = nvobj::pool::create( + path, LAYOUT, PMEMOBJ_MIN_POOL, S_IWUSR | S_IRUSR); + } catch (pmem::pool_error &pe) { + UT_FATAL("!pool::create: %s %s", pe.what(), path); + } + + arithmetic_test(pop); + bitwise_test(pop); + stream_test(pop); + swap_test(pop); + + pop.close(); + + return 0; +} diff --git a/tests/pmemobj_check_cow/CMakeLists.txt b/tests/pmemobj_check_cow/CMakeLists.txt new file mode 100644 index 0000000..d33c069 --- /dev/null +++ b/tests/pmemobj_check_cow/CMakeLists.txt @@ -0,0 +1,40 @@ +# +# Copyright 2018, Intel Corporation +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# +# * Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# +# * Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in +# the documentation and/or other materials provided with the +# distribution. +# +# * Neither the name of the copyright holder nor the names of its +# contributors may be used to endorse or promote products derived +# from this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +cmake_minimum_required(VERSION 3.3) +project(pmemobj_check_cow CXX) + +include_directories(${LIBPMEMOBJ_INCLUDE_DIRS}) +include_directories(${LIBPMEMOBJ++_INCLUDE_DIRS}) +link_directories(${LIBPMEMOBJ_LIBRARY_DIRS}) +link_libraries(${LIBPMEMOBJ_LIBRARIES}) + +add_executable(pmemobj_check_cow pmemobj_check_cow.cpp) diff --git a/tests/pmemobj_check_cow/pmemobj_check_cow.cpp b/tests/pmemobj_check_cow/pmemobj_check_cow.cpp new file mode 100644 index 0000000..a387b79 --- /dev/null +++ b/tests/pmemobj_check_cow/pmemobj_check_cow.cpp @@ -0,0 +1,115 @@ +/* + * Copyright 2018, Intel Corporation + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * * Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +/* + * pmemobj_check_cow -- checks if pmemobj supports COW on pool opening + * which can be triggered using PMEMOBJ_COW env variable + */ + +#include +#include + +#include +#include + +struct root { + int foo = 0; +}; + +void +init(const std::string &path) +{ + auto pop = pmem::obj::pool::create( + path, "COW_CHECK", PMEMOBJ_MIN_POOL, S_IWUSR | S_IRUSR); + + auto r = pop.root(); + r->foo = 0; + r.persist(); + + pop.close(); +} + +void +open_and_write(const std::string &path) +{ + auto pop = pmem::obj::pool::open(path, "COW_CHECK"); + + auto r = pop.root(); + r->foo = 1; + r.persist(); + + pop.close(); +} + +bool +check_cow_support(const std::string &path) +{ + auto pop = pmem::obj::pool::open(path, "COW_CHECK"); + + bool cow_supported = pop.root()->foo == 0; + + pop.close(); + + return cow_supported; +} + +/* + * return value is: + * - 0 when COW is supported + * - 1 when error occures during this program execution + * - 2 when COW is not supported + */ +int +main(int argc, char *argv[]) +{ + if (argc < 2) { + std::cerr << "usage: " << argv[0] << " " + << " filename\n"; + return 1; + } + + std::string path = argv[1]; + bool supported = false; + + try { + init(path); + open_and_write(path); + supported = check_cow_support(path); + } catch (pmem::pool_error &pe) { + std::cerr << pe.what(); + return 1; + } + + remove(path.c_str()); + + return supported ? 0 : 2; +} diff --git a/tests/pool/pool.cpp b/tests/pool/pool.cpp new file mode 100644 index 0000000..5cd8b10 --- /dev/null +++ b/tests/pool/pool.cpp @@ -0,0 +1,203 @@ +/* + * Copyright 2015-2018, Intel Corporation + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * * Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +/* + * obj_cpp_pool.c -- cpp pool implementation test + */ + +#include "unittest.hpp" + +#include +#include +#include +#include + +namespace nvobj = pmem::obj; + +namespace +{ + +size_t MB = ((size_t)1 << 20); + +struct root { + nvobj::p val; +}; + +/* + * pool_create -- (internal) test pool create + */ +void +pool_create(const char *path, const char *layout, size_t poolsize, + unsigned mode) +{ + nvobj::pool pop; + try { + pop = nvobj::pool::create(path, layout, poolsize, mode); + nvobj::persistent_ptr root = pop.root(); + UT_ASSERT(root != nullptr); + } catch (pmem::pool_error &e) { + UT_OUT("%s: pool::create: %s", path, e.what()); + return; + } + + os_stat_t stbuf; + STAT(path, &stbuf); + + UT_OUT("%s: file size %zu mode 0%o", path, stbuf.st_size, + stbuf.st_mode & 0777); + try { + pop.close(); + } catch (std::logic_error &lr) { + UT_OUT("%s: pool.close: %s", path, lr.what()); + return; + } + + int result = nvobj::pool::check(path, layout); + + if (result < 0) + UT_OUT("!%s: pool::check", path); + else if (result == 0) + UT_OUT("%s: pool::check: not consistent", path); +} + +/* + * pool_open -- (internal) test pool open + */ +void +pool_open(const char *path, const char *layout) +{ + nvobj::pool pop; + try { + pop = nvobj::pool::open(path, layout); + } catch (pmem::pool_error &e) { + UT_OUT("%s: pool::open: %s", path, e.what()); + return; + } + + UT_OUT("%s: pool::open: Success", path); + + try { + pop.close(); + } catch (std::logic_error &lr) { + UT_OUT("%s: pool.close: %s", path, lr.what()); + } +} + +/* + * double_close -- (internal) test double pool close + */ +void +double_close(const char *path, const char *layout, size_t poolsize, + unsigned mode) +{ + nvobj::pool pop; + try { + pop = nvobj::pool::create(path, layout, poolsize, mode); + } catch (pmem::pool_error &) { + UT_OUT("!%s: pool::create", path); + return; + } + + UT_OUT("%s: pool::create: Success", path); + + try { + pop.close(); + UT_OUT("%s: pool.close: Success", path); + pop.close(); + } catch (std::logic_error &lr) { + UT_OUT("%s: pool.close: %s", path, lr.what()); + } +} + +/* + * get_root_closed -- (internal) test get_root on a closed pool + */ +void +get_root_closed() +{ + nvobj::pool pop; + + try { + pop.root(); + } catch (pmem::pool_error &pe) { + UT_OUT("pool.get_root: %s", pe.what()); + } +} + +} /* namespace */ + +int +main(int argc, char *argv[]) +{ + START(); + + if (argc < 4) + UT_FATAL("usage: %s op path layout [poolsize mode]", argv[0]); + + const char *layout = nullptr; + size_t poolsize; + unsigned mode; + + if (strcmp(argv[3], "EMPTY") == 0) + layout = ""; + else if (strcmp(argv[3], "NULL") != 0) + layout = argv[3]; + + switch (argv[1][0]) { + case 'c': + poolsize = std::stoul(argv[4], nullptr, 0) * + MB; /* in megabytes */ + mode = static_cast( + std::stoul(argv[5], nullptr, 8)); + + pool_create(argv[2], layout, poolsize, mode); + break; + case 'o': + pool_open(argv[2], layout); + break; + case 'd': + poolsize = std::stoul(argv[4], nullptr, 0) * + MB; /* in megabytes */ + mode = static_cast( + std::stoul(argv[5], nullptr, 8)); + + double_close(argv[2], layout, poolsize, mode); + break; + case 'i': + get_root_closed(); + break; + default: + UT_FATAL("unknown operation"); + } + + return 0; +} diff --git a/tests/pool/pool_0.cmake b/tests/pool/pool_0.cmake new file mode 100644 index 0000000..e51a0ca --- /dev/null +++ b/tests/pool/pool_0.cmake @@ -0,0 +1,41 @@ +# +# Copyright 2018, Intel Corporation +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# +# * Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# +# * Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in +# the documentation and/or other materials provided with the +# distribution. +# +# * Neither the name of the copyright holder nor the names of its +# contributors may be used to endorse or promote products derived +# from this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +include(${SRC_DIR}/../helpers.cmake) + +setup() + +# non-existing file, poolsize > 0 +execute(${TEST_EXECUTABLE} c ${DIR}/testfile "test" 20 0600) + +check_file_exists(${DIR}/testfile) + +finish() diff --git a/tests/pool/pool_0_none.out.match b/tests/pool/pool_0_none.out.match new file mode 100644 index 0000000..d97f3d9 --- /dev/null +++ b/tests/pool/pool_0_none.out.match @@ -0,0 +1 @@ +$(nW)testfile: file size 20971520 mode 0600 diff --git a/tests/pool/pool_1.cmake b/tests/pool/pool_1.cmake new file mode 100644 index 0000000..2f3fb2e --- /dev/null +++ b/tests/pool/pool_1.cmake @@ -0,0 +1,41 @@ +# +# Copyright 2018, Intel Corporation +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# +# * Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# +# * Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in +# the documentation and/or other materials provided with the +# distribution. +# +# * Neither the name of the copyright holder nor the names of its +# contributors may be used to endorse or promote products derived +# from this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +include(${SRC_DIR}/../helpers.cmake) + +setup() + +# test existing file, file size >= min required size +# layout matches the value from pool header +execute(${TEST_EXECUTABLE} c ${DIR}/testfile "test" 20 0600) +execute(${TEST_EXECUTABLE} o ${DIR}/testfile "test") + +finish() diff --git a/tests/pool/pool_1_none.out.match b/tests/pool/pool_1_none.out.match new file mode 100644 index 0000000..33b4f22 --- /dev/null +++ b/tests/pool/pool_1_none.out.match @@ -0,0 +1 @@ +$(nW)testfile: pool::open: Success diff --git a/tests/pool/pool_2.cmake b/tests/pool/pool_2.cmake new file mode 100644 index 0000000..9c001d3 --- /dev/null +++ b/tests/pool/pool_2.cmake @@ -0,0 +1,41 @@ +# +# Copyright 2018, Intel Corporation +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# +# * Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# +# * Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in +# the documentation and/or other materials provided with the +# distribution. +# +# * Neither the name of the copyright holder nor the names of its +# contributors may be used to endorse or promote products derived +# from this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +include(${SRC_DIR}/../helpers.cmake) + +setup() + +# test non-existing file, poolsize > 0 +execute(${TEST_EXECUTABLE} d ${DIR}/testfile "test" 20 0600) + +check_file_exists(${DIR}/testfile) + +finish() diff --git a/tests/pool/pool_2_none.out.match b/tests/pool/pool_2_none.out.match new file mode 100644 index 0000000..de631f3 --- /dev/null +++ b/tests/pool/pool_2_none.out.match @@ -0,0 +1,3 @@ +$(nW)testfile: pool::create: Success +$(nW)testfile: pool.close: Success +$(nW)testfile: pool.close: Pool already closed diff --git a/tests/pool/pool_3.cmake b/tests/pool/pool_3.cmake new file mode 100644 index 0000000..a6440d1 --- /dev/null +++ b/tests/pool/pool_3.cmake @@ -0,0 +1,39 @@ +# +# Copyright 2018, Intel Corporation +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# +# * Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# +# * Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in +# the documentation and/or other materials provided with the +# distribution. +# +# * Neither the name of the copyright holder nor the names of its +# contributors may be used to endorse or promote products derived +# from this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +include(${SRC_DIR}/../helpers.cmake) + +setup() + +# test for get_root on invalid pool handle +execute(${TEST_EXECUTABLE} i ${DIR}/testfile "test" 20 0600) + +finish() diff --git a/tests/pool/pool_3_none.out.match b/tests/pool/pool_3_none.out.match new file mode 100644 index 0000000..73f08a9 --- /dev/null +++ b/tests/pool/pool_3_none.out.match @@ -0,0 +1 @@ +pool.get_root: Invalid pool handle diff --git a/tests/pool/pool_4.cmake b/tests/pool/pool_4.cmake new file mode 100644 index 0000000..33aa973 --- /dev/null +++ b/tests/pool/pool_4.cmake @@ -0,0 +1,40 @@ +# +# Copyright 2019, Intel Corporation +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# +# * Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# +# * Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in +# the documentation and/or other materials provided with the +# distribution. +# +# * Neither the name of the copyright holder nor the names of its +# contributors may be used to endorse or promote products derived +# from this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +include(${SRC_DIR}/../helpers.cmake) + +setup() + +execute(${TEST_EXECUTABLE} c ${DIR}/non-existent-dir/testfile "test" 20 0600) + +check_file_doesnt_exist(${DIR}/non-existent-dir/testfile) + +finish() diff --git a/tests/pool/pool_4_none.out.match b/tests/pool/pool_4_none.out.match new file mode 100644 index 0000000..06dfba2 --- /dev/null +++ b/tests/pool/pool_4_none.out.match @@ -0,0 +1 @@ +$(nW)testfile: pool::create: Failed creating pool diff --git a/tests/pool/pool_5.cmake b/tests/pool/pool_5.cmake new file mode 100644 index 0000000..42efb0c --- /dev/null +++ b/tests/pool/pool_5.cmake @@ -0,0 +1,38 @@ +# +# Copyright 2019, Intel Corporation +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# +# * Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# +# * Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in +# the documentation and/or other materials provided with the +# distribution. +# +# * Neither the name of the copyright holder nor the names of its +# contributors may be used to endorse or promote products derived +# from this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +include(${SRC_DIR}/../helpers.cmake) + +setup() + +execute(${TEST_EXECUTABLE} o ${DIR}/non-existent-dir/testfile "test") + +finish() diff --git a/tests/pool/pool_5_none.out.match b/tests/pool/pool_5_none.out.match new file mode 100644 index 0000000..b16f803 --- /dev/null +++ b/tests/pool/pool_5_none.out.match @@ -0,0 +1 @@ +$(nW)testfile: pool::open: Failed opening pool diff --git a/tests/pool_primitives/pool_primitives.cpp b/tests/pool_primitives/pool_primitives.cpp new file mode 100644 index 0000000..5145350 --- /dev/null +++ b/tests/pool_primitives/pool_primitives.cpp @@ -0,0 +1,337 @@ +/* + * Copyright 2016-2018, Intel Corporation + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * * Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +/* + * obj_cpp_pool_primitives.c -- cpp pool implementation test for: + * - persist + * - flush + * - drain + * - memcpy_persist + * - memset_persist + */ + +#include "unittest.hpp" + +#include +#include +#include + +namespace nvobj = pmem::obj; + +namespace +{ + +int TEST_VAL = 1; +size_t MB = ((size_t)1 << 20); + +struct root { + nvobj::p val; + nvobj::persistent_ptr me; +}; + +/* + * pool_test_memset -- (internal) test memset_persist primitive + */ +void +pool_test_memset(nvobj::pool &pop) +{ + nvobj::persistent_ptr root = pop.root(); + UT_ASSERT(root != nullptr); + + void *ret = pop.memset_persist(&root->val, TEST_VAL, sizeof(root->val)); + UT_ASSERTeq(ret, &root->val); + + int c; + memset(&c, TEST_VAL, sizeof(c)); + UT_ASSERTeq(root->val, c); +} + +/* + * pool_test_memcpy -- (internal) test memcpy_persist primitive + */ +void +pool_test_memcpy(nvobj::pool &pop) +{ + nvobj::persistent_ptr root = pop.root(); + UT_ASSERT(root != nullptr); + + int v = TEST_VAL; + void *ret = pop.memcpy_persist(&root->val, &v, sizeof(root->val)); + UT_ASSERTeq(ret, &root->val); + UT_ASSERTeq(root->val, v); +} + +/* + * pool_test_drain -- (internal) test drain primitive + */ +void +pool_test_drain(nvobj::pool &pop) +{ + pop.drain(); +} + +/* + * pool_test_flush -- (internal) test flush primitive + */ +void +pool_test_flush(nvobj::pool &pop) +{ + nvobj::persistent_ptr root = pop.root(); + UT_ASSERT(root != nullptr); + + root->val = TEST_VAL; + + pop.flush(&root->val, sizeof(root->val)); +} + +/* + * pool_test_flush_p -- (internal) test flush primitive on pmem property + */ +void +pool_test_flush_p(nvobj::pool &pop) +{ + nvobj::persistent_ptr root = pop.root(); + UT_ASSERT(root != nullptr); + + root->val = TEST_VAL; + + pop.flush(root->val); +} + +/* + * pool_test_flush_ptr -- (internal) test flush primitive on pmem pointer + */ +void +pool_test_flush_ptr(nvobj::pool &pop) +{ + nvobj::persistent_ptr root = pop.root(); + UT_ASSERT(root != nullptr); + + root->me = root; + + pop.flush(root->me); +} + +/* + * pool_test_flush_ptr_obj -- (internal) test flush primitive on pmem pointer + * object + */ +void +pool_test_flush_ptr_obj(nvobj::pool &pop) +{ + nvobj::persistent_ptr root = pop.root(); + UT_ASSERT(root != nullptr); + + root->me = root; + root->val = TEST_VAL; + + root.flush(pop); +} + +/* + * pool_test_flush_ptr_obj_no_pop -- (internal) test flush primitive on + * pmem pointer object, without using pop + */ +void +pool_test_flush_ptr_obj_no_pop(nvobj::pool &pop) +{ + nvobj::persistent_ptr root = pop.root(); + UT_ASSERT(root != nullptr); + + root->me = root; + root->val = TEST_VAL; + + root.flush(); +} + +/* + * pool_test_persist -- (internal) test persist primitive + */ +void +pool_test_persist(nvobj::pool &pop) +{ + nvobj::persistent_ptr root = pop.root(); + UT_ASSERT(root != nullptr); + + root->val = TEST_VAL; + + pop.persist(&root->val, sizeof(root->val)); +} + +/* + * pool_test_persist_p -- (internal) test persist primitive on pmem property + */ +void +pool_test_persist_p(nvobj::pool &pop) +{ + nvobj::persistent_ptr root = pop.root(); + UT_ASSERT(root != nullptr); + + root->val = TEST_VAL; + + pop.persist(root->val); +} + +/* + * pool_test_persist_ptr -- (internal) test persist primitive on pmem pointer + */ +void +pool_test_persist_ptr(nvobj::pool &pop) +{ + nvobj::persistent_ptr root = pop.root(); + UT_ASSERT(root != nullptr); + + root->me = root; + + pop.persist(root->me); +} + +/* + * pool_test_persist_ptr_obj -- (internal) test persist primitive on pmem + * pointer object + */ +void +pool_test_persist_ptr_obj(nvobj::pool &pop) +{ + nvobj::persistent_ptr root = pop.root(); + UT_ASSERT(root != nullptr); + + root->me = root; + root->val = TEST_VAL; + + root.persist(pop); +} + +/* + * pool_test_persist_ptr_obj_no_pop -- (internal) test persist primitive on + * pmem pointer object, without using pop + */ +void +pool_test_persist_ptr_obj_no_pop(nvobj::pool &pop) +{ + nvobj::persistent_ptr root = pop.root(); + UT_ASSERT(root != nullptr); + + root->me = root; + root->val = TEST_VAL; + + root.persist(); +} + +/* + * pool_test_flush_ptr_invalid -- (internal) test flush primitive on + * pptr pointing to closed pool + */ +void +pool_test_flush_ptr_invalid(nvobj::persistent_ptr &root) +{ + bool exc = false; + try { + root.flush(); + } catch (pmem::pool_error &e) { + exc = true; + } catch (std::exception &e) { + UT_FATALexc(e); + } + + UT_ASSERT(exc); +} + +/* + * pool_test_persist_ptr_invalid -- (internal) test persist primitive on + * pptr pointing to closed pool + */ +void +pool_test_persist_ptr_invalid(nvobj::persistent_ptr &root) +{ + bool exc = false; + try { + root.persist(); + } catch (pmem::pool_error &e) { + exc = true; + } catch (std::exception &e) { + UT_FATALexc(e); + } + + UT_ASSERT(exc); +} + +/* + * pool_create -- (internal) test pool create + */ +nvobj::pool +pool_create(const char *path, const char *layout, size_t poolsize, + unsigned mode) +{ + nvobj::pool pop = + nvobj::pool::create(path, layout, poolsize, mode); + nvobj::persistent_ptr root = pop.root(); + UT_ASSERT(root != nullptr); + + return pop; +} + +} /* namespace */ + +int +main(int argc, char *argv[]) +{ + START(); + + if (argc != 2) + UT_FATAL("usage: %s path", argv[0]); + + nvobj::pool pop = pool_create(argv[1], "layout", 32 * MB, 0666); + + pool_test_persist(pop); + pool_test_persist_p(pop); + pool_test_persist_ptr(pop); + pool_test_persist_ptr_obj(pop); + pool_test_persist_ptr_obj_no_pop(pop); + pool_test_flush(pop); + pool_test_flush_p(pop); + pool_test_flush_ptr(pop); + pool_test_flush_ptr_obj(pop); + pool_test_flush_ptr_obj_no_pop(pop); + pool_test_drain(pop); + pool_test_memcpy(pop); + pool_test_memset(pop); + + nvobj::persistent_ptr root = pop.root(); + + pop.close(); + + pool_test_flush_ptr_invalid(root); + pool_test_persist_ptr_invalid(root); + + return 0; +} diff --git a/tests/pool_primitives/pool_primitives_0.cmake b/tests/pool_primitives/pool_primitives_0.cmake new file mode 100644 index 0000000..b04bb69 --- /dev/null +++ b/tests/pool_primitives/pool_primitives_0.cmake @@ -0,0 +1,40 @@ +# +# Copyright 2018, Intel Corporation +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# +# * Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# +# * Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in +# the documentation and/or other materials provided with the +# distribution. +# +# * Neither the name of the copyright holder nor the names of its +# contributors may be used to endorse or promote products derived +# from this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +include(${SRC_DIR}/../helpers.cmake) + +setup() + +execute(${TEST_EXECUTABLE} ${DIR}/testfile) + +check_file_exists(${DIR}/testfile) + +finish() diff --git a/tests/pool_win/pool_win.cpp b/tests/pool_win/pool_win.cpp new file mode 100644 index 0000000..df95f2f --- /dev/null +++ b/tests/pool_win/pool_win.cpp @@ -0,0 +1,208 @@ +/* + * Copyright 2017-2018, Intel Corporation + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * * Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +/* + * obj_cpp_pool_win.c -- cpp pool implementation test + */ + +#include "unittest.hpp" + +#include +#include +#include + +namespace nvobj = pmem::obj; + +namespace +{ + +size_t MB = ((size_t)1 << 20); + +struct root { + nvobj::p val; +}; + +/* + * pool_create -- (internal) test pool create + */ +void +pool_create(const wchar_t *path, const wchar_t *layout, size_t poolsize, + unsigned mode) +{ + std::unique_ptr _path(ut_toUTF8(path)); + + nvobj::pool pop; + + try { + pop = nvobj::pool::create(path, layout, poolsize, mode); + nvobj::persistent_ptr root = pop.root(); + UT_ASSERT(root != nullptr); + } catch (pmem::pool_error &) { + UT_OUT("!%s: pool::create", _path.get()); + return; + } + + os_stat_t stbuf; + STATW(path, &stbuf); + + UT_OUT("%s: file size %zu mode 0%o", _path.get(), stbuf.st_size, + stbuf.st_mode & 0777); + try { + pop.close(); + } catch (std::logic_error &lr) { + UT_OUT("%s: pool.close: %s", _path.get(), lr.what()); + return; + } + + int result = nvobj::pool::check(path, layout); + + if (result < 0) + UT_OUT("!%s: pool::check", _path.get()); + else if (result == 0) + UT_OUT("%s: pool::check: not consistent", _path.get()); +} + +/* + * pool_open -- (internal) test pool open + */ +void +pool_open(const wchar_t *path, const wchar_t *layout) +{ + std::unique_ptr _path(ut_toUTF8(path)); + nvobj::pool pop; + + try { + pop = nvobj::pool::open(path, layout); + } catch (pmem::pool_error &) { + UT_OUT("!%s: pool::open", _path.get()); + return; + } + + UT_OUT("%s: pool::open: Success", _path.get()); + + try { + pop.close(); + } catch (std::logic_error &lr) { + UT_OUT("%s: pool.close: %s", _path.get(), lr.what()); + } +} + +/* + * double_close -- (internal) test double pool close + */ +void +double_close(const wchar_t *path, const wchar_t *layout, size_t poolsize, + unsigned mode) +{ + std::unique_ptr _path(ut_toUTF8(path)); + nvobj::pool pop; + + try { + pop = nvobj::pool::create(path, layout, poolsize, mode); + } catch (pmem::pool_error &) { + UT_OUT("!%s: pool::create", _path.get()); + return; + } + + UT_OUT("%s: pool::create: Success", _path.get()); + + try { + pop.close(); + UT_OUT("%s: pool.close: Success", _path.get()); + pop.close(); + } catch (std::logic_error &lr) { + UT_OUT("%s: pool.close: %s", _path.get(), lr.what()); + } +} + +/* + * get_root_closed -- (internal) test get_root on a closed pool + */ +void +get_root_closed() +{ + nvobj::pool pop; + + try { + pop.root(); + } catch (pmem::pool_error &pe) { + UT_OUT("pool.get_root: %s", pe.what()); + } +} + +} /* namespace */ + +int +wmain(int argc, wchar_t *argv[]) +{ + START(); + + if (argc < 4) + UT_FATAL("usage: %s op path layout [poolsize mode]", + ut_toUTF8(argv[0])); + + const wchar_t *layout = nullptr; + size_t poolsize; + unsigned mode; + + if (wcscmp(argv[3], L"EMPTY") == 0) + layout = L""; + else if (wcscmp(argv[3], L"NULL") != 0) + layout = argv[3]; + + switch (argv[1][0]) { + case 'c': + poolsize = wcstoul(argv[4], nullptr, 0) * + MB; /* in megabytes */ + mode = wcstoul(argv[5], nullptr, 8); + + pool_create(argv[2], layout, poolsize, mode); + break; + case 'o': + pool_open(argv[2], layout); + break; + case 'd': + poolsize = wcstoul(argv[4], nullptr, 0) * + MB; /* in megabytes */ + mode = wcstoul(argv[5], nullptr, 8); + + double_close(argv[2], layout, poolsize, mode); + break; + case 'i': + get_root_closed(); + break; + default: + UT_FATAL("unknown operation"); + } + + return 0; +} diff --git a/tests/pool_win/pool_win_0.cmake b/tests/pool_win/pool_win_0.cmake new file mode 100644 index 0000000..a052193 --- /dev/null +++ b/tests/pool_win/pool_win_0.cmake @@ -0,0 +1,40 @@ +# +# Copyright 2018, Intel Corporation +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# +# * Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# +# * Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in +# the documentation and/or other materials provided with the +# distribution. +# +# * Neither the name of the copyright holder nor the names of its +# contributors may be used to endorse or promote products derived +# from this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +include(${SRC_DIR}/../helpers.cmake) + +setup() + +execute(${TEST_EXECUTABLE} c ${DIR}/testfile "test" 20 0600) + +check_file_exists(${DIR}/testfile) + +finish() diff --git a/tests/pool_win/pool_win_0_none.out.match b/tests/pool_win/pool_win_0_none.out.match new file mode 100644 index 0000000..d97f3d9 --- /dev/null +++ b/tests/pool_win/pool_win_0_none.out.match @@ -0,0 +1 @@ +$(nW)testfile: file size 20971520 mode 0600 diff --git a/tests/pool_win/pool_win_1.cmake b/tests/pool_win/pool_win_1.cmake new file mode 100644 index 0000000..e528a3e --- /dev/null +++ b/tests/pool_win/pool_win_1.cmake @@ -0,0 +1,41 @@ +# +# Copyright 2018, Intel Corporation +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# +# * Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# +# * Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in +# the documentation and/or other materials provided with the +# distribution. +# +# * Neither the name of the copyright holder nor the names of its +# contributors may be used to endorse or promote products derived +# from this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +include(${SRC_DIR}/../helpers.cmake) + +setup() + +execute(${TEST_EXECUTABLE} c ${DIR}/testfile "test" 20 0600) +execute(${TEST_EXECUTABLE} o ${DIR}/testfile "test" 20 0600) + +check_file_exists(${DIR}/testfile) + +finish() diff --git a/tests/pool_win/pool_win_1_none.out.match b/tests/pool_win/pool_win_1_none.out.match new file mode 100644 index 0000000..33b4f22 --- /dev/null +++ b/tests/pool_win/pool_win_1_none.out.match @@ -0,0 +1 @@ +$(nW)testfile: pool::open: Success diff --git a/tests/pool_win/pool_win_2.cmake b/tests/pool_win/pool_win_2.cmake new file mode 100644 index 0000000..30f326e --- /dev/null +++ b/tests/pool_win/pool_win_2.cmake @@ -0,0 +1,40 @@ +# +# Copyright 2018, Intel Corporation +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# +# * Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# +# * Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in +# the documentation and/or other materials provided with the +# distribution. +# +# * Neither the name of the copyright holder nor the names of its +# contributors may be used to endorse or promote products derived +# from this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +include(${SRC_DIR}/../helpers.cmake) + +setup() + +execute(${TEST_EXECUTABLE} d ${DIR}/testfile "test" 20 0600) + +check_file_exists(${DIR}/testfile) + +finish() diff --git a/tests/pool_win/pool_win_2_none.out.match b/tests/pool_win/pool_win_2_none.out.match new file mode 100644 index 0000000..de631f3 --- /dev/null +++ b/tests/pool_win/pool_win_2_none.out.match @@ -0,0 +1,3 @@ +$(nW)testfile: pool::create: Success +$(nW)testfile: pool.close: Success +$(nW)testfile: pool.close: Pool already closed diff --git a/tests/pool_win/pool_win_3.cmake b/tests/pool_win/pool_win_3.cmake new file mode 100644 index 0000000..3d208b4 --- /dev/null +++ b/tests/pool_win/pool_win_3.cmake @@ -0,0 +1,38 @@ +# +# Copyright 2018, Intel Corporation +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# +# * Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# +# * Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in +# the documentation and/or other materials provided with the +# distribution. +# +# * Neither the name of the copyright holder nor the names of its +# contributors may be used to endorse or promote products derived +# from this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +include(${SRC_DIR}/../helpers.cmake) + +setup() + +execute(${TEST_EXECUTABLE} i ${DIR}/testfile "test" 20 0600) + +finish() diff --git a/tests/pool_win/pool_win_3_none.out.match b/tests/pool_win/pool_win_3_none.out.match new file mode 100644 index 0000000..73f08a9 --- /dev/null +++ b/tests/pool_win/pool_win_3_none.out.match @@ -0,0 +1 @@ +pool.get_root: Invalid pool handle diff --git a/tests/ptr/ptr.cpp b/tests/ptr/ptr.cpp new file mode 100644 index 0000000..af1c3b8 --- /dev/null +++ b/tests/ptr/ptr.cpp @@ -0,0 +1,377 @@ +/* + * Copyright 2015-2019, Intel Corporation + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * * Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +/* + * obj_cpp_ptr.c -- cpp bindings test + * + */ + +#include "unittest.hpp" + +#include +#include +#include +#include +#include +#include +#include + +#define LAYOUT "cpp" + +namespace nvobj = pmem::obj; + +namespace +{ + +/* + * test_null_ptr -- verifies if the pointer correctly behaves like a + * nullptr-value + */ +void +test_null_ptr(nvobj::persistent_ptr &f) +{ + UT_ASSERT(OID_IS_NULL(f.raw())); + UT_ASSERT((bool)f == false); + UT_ASSERT(!f); + UT_ASSERTeq(f.get(), nullptr); + UT_ASSERT(f == nullptr); +} + +/* + * get_temp -- returns a temporary persistent_ptr + */ +nvobj::persistent_ptr +get_temp() +{ + nvobj::persistent_ptr int_null = nullptr; + + return int_null; +} + +/* + * test_ptr_operators_null -- verifies various operations on nullptr pointers + */ +void +test_ptr_operators_null() +{ + nvobj::persistent_ptr int_default_null; + test_null_ptr(int_default_null); + + nvobj::persistent_ptr int_explicit_ptr_null = nullptr; + test_null_ptr(int_explicit_ptr_null); + + nvobj::persistent_ptr int_explicit_oid_null = OID_NULL; + test_null_ptr(int_explicit_oid_null); + + nvobj::persistent_ptr int_base = nullptr; + nvobj::persistent_ptr int_same = int_base; + int_same = int_base; + test_null_ptr(int_same); + + swap(int_base, int_same); + + auto temp_ptr = get_temp(); + test_null_ptr(temp_ptr); +} + +const int TEST_INT = 10; +const int TEST_ARR_SIZE = 10; +const char TEST_CHAR = 'a'; + +struct foo { + nvobj::p bar; + nvobj::p arr[TEST_ARR_SIZE]; +}; + +struct nested { + nvobj::persistent_ptr inner; +}; + +struct root { + nvobj::persistent_ptr pfoo; + nvobj::persistent_ptr[TEST_ARR_SIZE]> parr; + + /* This variable is unused, but it's here to check if the persistent_ptr + * does not violate it's own restrictions. + */ + nvobj::persistent_ptr outer; +}; + +/* + * test_ptr_atomic -- verifies the persistent ptr with the atomic C API + */ +void +test_ptr_atomic(nvobj::pool &pop) +{ + nvobj::persistent_ptr pfoo; + + try { + nvobj::make_persistent_atomic(pop, pfoo); + } catch (...) { + UT_ASSERT(0); + } + + UT_ASSERTne(pfoo.get(), nullptr); + + (*pfoo).bar = TEST_INT; + pop.persist(&pfoo->bar, sizeof(pfoo->bar)); + pop.memset_persist(pfoo->arr, TEST_CHAR, sizeof(pfoo->arr)); + + for (auto c : pfoo->arr) { + UT_ASSERTeq(c, TEST_CHAR); + } + + try { + nvobj::delete_persistent_atomic(pfoo); + pfoo = nullptr; + } catch (...) { + UT_ASSERT(0); + } + + UT_ASSERTeq(pfoo.get(), nullptr); +} + +/* + * test_ptr_transactional -- verifies the persistent ptr with the tx C API + */ +void +test_ptr_transactional(nvobj::pool &pop) +{ + auto r = pop.root(); + nvobj::persistent_ptr to_swap; + try { + nvobj::transaction::run(pop, [&] { + UT_ASSERT(r->pfoo == nullptr); + + r->pfoo = nvobj::make_persistent(); + + /* allocate for future swap test */ + to_swap = nvobj::make_persistent(); + }); + } catch (...) { + UT_ASSERT(0); + } + + auto pfoo = r->pfoo; + + try { + nvobj::transaction::run(pop, [&] { + pfoo->bar = TEST_INT; + /* raw memory access requires extra care */ + pmem::detail::conditional_add_to_tx(&pfoo->arr); + memset(&pfoo->arr, TEST_CHAR, sizeof(pfoo->arr)); + + /* do the swap test */ + nvobj::persistent_ptr foo_ptr{r->pfoo}; + nvobj::persistent_ptr swap_ptr{to_swap}; + to_swap.swap(r->pfoo); + UT_ASSERT(to_swap == foo_ptr); + UT_ASSERT(r->pfoo == swap_ptr); + + swap(r->pfoo, to_swap); + UT_ASSERT(to_swap == swap_ptr); + UT_ASSERT(r->pfoo == foo_ptr); + + nvobj::delete_persistent(to_swap); + }); + } catch (...) { + UT_ASSERT(0); + } + + UT_ASSERTeq(pfoo->bar, TEST_INT); + for (auto c : pfoo->arr) { + UT_ASSERTeq(c, TEST_CHAR); + } + + bool exception_thrown = false; + try { + nvobj::transaction::run(pop, [&] { + pfoo->bar = 0; + nvobj::transaction::abort(-1); + }); + } catch (pmem::manual_tx_abort &) { + exception_thrown = true; + } catch (...) { + UT_ASSERT(0); + } + + UT_ASSERT(exception_thrown); + UT_ASSERTeq(pfoo->bar, TEST_INT); + + try { + nvobj::transaction::run( + pop, [&] { nvobj::delete_persistent(r->pfoo); }); + r->pfoo = nullptr; + } catch (...) { + UT_ASSERT(0); + } + + UT_ASSERT(r->pfoo == nullptr); + UT_ASSERT(pfoo != nullptr); +} + +/* + * test_ptr_array -- verifies the array specialization behavior + */ +void +test_ptr_array(nvobj::pool &pop) +{ + nvobj::persistent_ptr[]> parr_vsize; + + try { + nvobj::make_persistent_atomic[]>(pop, parr_vsize, + TEST_ARR_SIZE); + } catch (...) { + UT_ASSERT(0); + } + + { + nvobj::transaction::manual tx(pop); + + for (int i = 0; i < TEST_ARR_SIZE; ++i) + parr_vsize[i] = i; + nvobj::transaction::commit(); + } + + for (int i = 0; i < TEST_ARR_SIZE; ++i) + UT_ASSERTeq(parr_vsize[i], i); + + auto r = pop.root(); + + try { + nvobj::transaction::run(pop, [&] { + r->parr = pmemobj_tx_zalloc(sizeof(int) * TEST_ARR_SIZE, + 0); + }); + } catch (...) { + UT_ASSERT(0); + } + + UT_ASSERT(r->parr != nullptr); + + bool exception_thrown = false; + try { + nvobj::transaction::run(pop, [&] { + for (int i = 0; i < TEST_ARR_SIZE; ++i) + r->parr[i] = TEST_INT; + + nvobj::transaction::abort(-1); + }); + } catch (pmem::manual_tx_abort &) { + exception_thrown = true; + } catch (...) { + UT_ASSERT(0); + } + + UT_ASSERT(exception_thrown); + + exception_thrown = false; + try { + nvobj::transaction::run(pop, [&] { + for (int i = 0; i < TEST_ARR_SIZE; ++i) + r->parr[i] = TEST_INT; + + nvobj::transaction::abort(-1); + }); + } catch (pmem::manual_tx_abort &) { + exception_thrown = true; + } catch (...) { + UT_ASSERT(0); + } + + UT_ASSERT(exception_thrown); + + for (int i = 0; i < TEST_ARR_SIZE; ++i) + UT_ASSERTeq(r->parr[i], 0); +} + +/* + * test_offset -- test offset calculation within a hierarchy + */ +void +test_offset(nvobj::pool &pop) +{ + struct A { + uint64_t a; + }; + + struct B { + uint64_t b; + }; + + struct C : public A, public B { + uint64_t c; + }; + + try { + nvobj::transaction::run(pop, [] { + auto cptr = nvobj::make_persistent(); + nvobj::persistent_ptr bptr = cptr; + UT_ASSERT((bptr.raw().off - cptr.raw().off) == + sizeof(A)); + nvobj::delete_persistent(cptr); + }); + } catch (...) { + UT_ASSERT(0); + } +} +} + +int +main(int argc, char *argv[]) +{ + START(); + + if (argc != 2) + UT_FATAL("usage: %s file-name", argv[0]); + + const char *path = argv[1]; + + nvobj::pool pop; + + try { + pop = nvobj::pool::create( + path, LAYOUT, PMEMOBJ_MIN_POOL, S_IWUSR | S_IRUSR); + } catch (pmem::pool_error &pe) { + UT_FATAL("!pool::create: %s %s", pe.what(), path); + } + + test_ptr_operators_null(); + test_ptr_atomic(pop); + test_ptr_transactional(pop); + test_ptr_array(pop); + test_offset(pop); + + pop.close(); + + return 0; +} diff --git a/tests/ptr/ptr_0.cmake b/tests/ptr/ptr_0.cmake new file mode 100644 index 0000000..b04bb69 --- /dev/null +++ b/tests/ptr/ptr_0.cmake @@ -0,0 +1,40 @@ +# +# Copyright 2018, Intel Corporation +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# +# * Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# +# * Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in +# the documentation and/or other materials provided with the +# distribution. +# +# * Neither the name of the copyright holder nor the names of its +# contributors may be used to endorse or promote products derived +# from this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +include(${SRC_DIR}/../helpers.cmake) + +setup() + +execute(${TEST_EXECUTABLE} ${DIR}/testfile) + +check_file_exists(${DIR}/testfile) + +finish() diff --git a/tests/ptr_arith/ptr_arith.cpp b/tests/ptr_arith/ptr_arith.cpp new file mode 100644 index 0000000..bb50885 --- /dev/null +++ b/tests/ptr_arith/ptr_arith.cpp @@ -0,0 +1,235 @@ +/* + * Copyright 2016-2018, Intel Corporation + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * * Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +/* + * obj_cpp_ptr_arith.cpp -- cpp bindings test + * + */ + +#include "unittest.hpp" + +#include +#include +#include +#include + +#include + +#define LAYOUT "cpp" + +namespace nvobj = pmem::obj; + +namespace +{ + +const int TEST_ARR_SIZE = 10; + +/* + * prepare_array -- preallocate and fill a persistent array + */ +template +nvobj::persistent_ptr +prepare_array(nvobj::pool_base &pop) +{ + int ret; + + nvobj::persistent_ptr parr_vsize; + ret = pmemobj_zalloc(pop.handle(), parr_vsize.raw_ptr(), + sizeof(T) * TEST_ARR_SIZE, 0); + + UT_ASSERTeq(ret, 0); + + T *parray = parr_vsize.get(); + + try { + nvobj::transaction::run(pop, [&] { + for (int i = 0; i < TEST_ARR_SIZE; ++i) { + parray[i] = i; + } + }); + } catch (...) { + UT_FATAL("Transactional prepare_array aborted"); + } + + for (int i = 0; i < TEST_ARR_SIZE; ++i) { + UT_ASSERTeq(parray[i], i); + } + + return parr_vsize; +} + +/* + * test_arith -- test arithmetic operations on persistent pointers + */ +void +test_arith(nvobj::pool_base &pop) +{ + auto parr_vsize = prepare_array>(pop); + + /* test prefix postfix operators */ + for (int i = 0; i < TEST_ARR_SIZE; ++i) { + UT_ASSERTeq(*parr_vsize, i); + parr_vsize++; + } + + for (int i = TEST_ARR_SIZE; i > 0; --i) { + parr_vsize--; + UT_ASSERTeq(*parr_vsize, i - 1); + } + + for (int i = 0; i < TEST_ARR_SIZE; ++i) { + UT_ASSERTeq(*parr_vsize, i); + ++parr_vsize; + } + + for (int i = TEST_ARR_SIZE; i > 0; --i) { + --parr_vsize; + UT_ASSERTeq(*parr_vsize, i - 1); + } + + /* test addition assignment and subtraction */ + parr_vsize += 2; + UT_ASSERTeq(*parr_vsize, 2); + + parr_vsize -= 2; + UT_ASSERTeq(*parr_vsize, 0); + + /* test strange invocations, parameter ignored */ + parr_vsize.operator++(5); + UT_ASSERTeq(*parr_vsize, 1); + + parr_vsize.operator--(2); + UT_ASSERTeq(*parr_vsize, 0); + + /* test subtraction and addition */ + for (int i = 0; i < TEST_ARR_SIZE; ++i) + UT_ASSERTeq(*(parr_vsize + i), i); + + /* using STL one-pas-end style */ + auto parr_end = parr_vsize + TEST_ARR_SIZE; + + for (int i = TEST_ARR_SIZE; i > 0; --i) + UT_ASSERTeq(*(parr_end - i), TEST_ARR_SIZE - i); + + UT_ASSERTeq(parr_end - parr_vsize, TEST_ARR_SIZE); + + /* check ostream operator */ + std::stringstream stream; + stream << parr_vsize; + UT_OUT("%s", stream.str().c_str()); +} + +/* + * test_relational -- test relational operators on persistent pointers + */ +void +test_relational(nvobj::pool_base &pop) +{ + + auto first_elem = prepare_array>(pop); + nvobj::persistent_ptr parray; + auto last_elem = first_elem + TEST_ARR_SIZE - 1; + + UT_ASSERT(first_elem != last_elem); + UT_ASSERT(first_elem <= last_elem); + UT_ASSERT(first_elem < last_elem); + UT_ASSERT(last_elem > first_elem); + UT_ASSERT(last_elem >= first_elem); + UT_ASSERT(first_elem == first_elem); + UT_ASSERT(first_elem >= first_elem); + UT_ASSERT(first_elem <= first_elem); + + /* nullptr comparisons */ + UT_ASSERT(first_elem != nullptr); + UT_ASSERT(nullptr != first_elem); + UT_ASSERT(!(first_elem == nullptr)); + UT_ASSERT(!(nullptr == first_elem)); + + UT_ASSERT(nullptr < first_elem); + UT_ASSERT(!(first_elem < nullptr)); + UT_ASSERT(nullptr <= first_elem); + UT_ASSERT(!(first_elem <= nullptr)); + + UT_ASSERT(first_elem > nullptr); + UT_ASSERT(!(nullptr > first_elem)); + UT_ASSERT(first_elem >= nullptr); + UT_ASSERT(!(nullptr >= first_elem)); + + /* pointer to array */ + UT_ASSERT(parray == nullptr); + UT_ASSERT(nullptr == parray); + UT_ASSERT(!(parray != nullptr)); + UT_ASSERT(!(nullptr != parray)); + + UT_ASSERT(!(nullptr < parray)); + UT_ASSERT(!(parray < nullptr)); + UT_ASSERT(nullptr <= parray); + UT_ASSERT(parray <= nullptr); + + UT_ASSERT(!(parray > nullptr)); + UT_ASSERT(!(nullptr > parray)); + UT_ASSERT(parray >= nullptr); + UT_ASSERT(nullptr >= parray); + + auto different_array = prepare_array>(pop); + + /* only verify if this compiles */ + UT_ASSERT((first_elem < different_array) || true); +} +} + +int +main(int argc, char *argv[]) +{ + START(); + + if (argc != 2) + UT_FATAL("usage: %s file-name", argv[0]); + + const char *path = argv[1]; + + nvobj::pool_base pop; + + try { + pop = nvobj::pool_base::create(path, LAYOUT, PMEMOBJ_MIN_POOL, + S_IWUSR | S_IRUSR); + } catch (pmem::pool_error &pe) { + UT_FATAL("!pool::create: %s %s", pe.what(), path); + } + + test_arith(pop); + test_relational(pop); + + pop.close(); + + return 0; +} diff --git a/tests/run_default.cmake b/tests/run_default.cmake new file mode 100644 index 0000000..05969bf --- /dev/null +++ b/tests/run_default.cmake @@ -0,0 +1,38 @@ +# +# Copyright 2019, Intel Corporation +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# +# * Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# +# * Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in +# the documentation and/or other materials provided with the +# distribution. +# +# * Neither the name of the copyright holder nor the names of its +# contributors may be used to endorse or promote products derived +# from this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +include(${SRC_DIR}/../helpers.cmake) + +setup() + +execute(${TEST_EXECUTABLE} ${DIR}/testfile) + +finish() diff --git a/tests/shared_mutex/shared_mutex.cpp b/tests/shared_mutex/shared_mutex.cpp new file mode 100644 index 0000000..b056b72 --- /dev/null +++ b/tests/shared_mutex/shared_mutex.cpp @@ -0,0 +1,254 @@ +/* + * Copyright 2016-2018, Intel Corporation + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * * Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +/* + * obj_cpp_shared_mutex.cpp -- cpp shared mutex test + */ + +#include "unittest.hpp" + +#include +#include +#include + +#include +#include + +#define LAYOUT "cpp" + +namespace nvobj = pmem::obj; + +namespace +{ + +/* pool root structure */ +struct root { + nvobj::shared_mutex pmutex; + unsigned counter; +}; + +/* number of ops per thread */ +const unsigned num_ops = 200; + +/* the number of threads */ +const unsigned num_threads = 30; + +/* + * writer -- (internal) bump up the counter by 2 + */ +void +writer(nvobj::persistent_ptr proot) +{ + for (unsigned i = 0; i < num_ops; ++i) { + std::lock_guard lock(proot->pmutex); + ++(proot->counter); + ++(proot->counter); + } +} + +/* + * reader -- (internal) verify if the counter is even + */ +void +reader(nvobj::persistent_ptr proot) +{ + for (unsigned i = 0; i < num_ops; ++i) { + proot->pmutex.lock_shared(); + UT_ASSERTeq(proot->counter % 2, 0); + proot->pmutex.unlock_shared(); + } +} + +/* + * writer_trylock -- (internal) trylock bump the counter by 2 + */ +void +writer_trylock(nvobj::persistent_ptr proot) +{ + for (;;) { + if (proot->pmutex.try_lock()) { + --(proot->counter); + --(proot->counter); + proot->pmutex.unlock(); + return; + } + } +} + +/* + * reader_trylock -- (internal) trylock verify that the counter is even + */ +void +reader_trylock(nvobj::persistent_ptr proot) +{ + for (;;) { + if (proot->pmutex.try_lock_shared()) { + UT_ASSERTeq(proot->counter % 2, 0); + proot->pmutex.unlock_shared(); + return; + } + } +} + +/* + * mutex_zero_test -- (internal) test the zeroing constructor + */ +void +mutex_zero_test(nvobj::pool &pop) +{ + PMEMoid raw_mutex; + + pmemobj_alloc(pop.handle(), &raw_mutex, sizeof(PMEMrwlock), 1, + [](PMEMobjpool *pop, void *ptr, void *arg) -> int { + PMEMrwlock *mtx = static_cast(ptr); + pmemobj_memset_persist(pop, mtx, 1, sizeof(*mtx)); + return 0; + }, + nullptr); + + nvobj::shared_mutex *placed_mtx = + new (pmemobj_direct(raw_mutex)) nvobj::shared_mutex; + std::unique_lock lck(*placed_mtx); +} + +/* + * mutex_test -- (internal) launch worker threads to test the pshared_mutex + */ +template +void +mutex_test(nvobj::pool &pop, const Worker &writer, const Worker &reader) +{ + const auto total_threads = num_threads * 2u; + std::thread threads[total_threads]; + + nvobj::persistent_ptr proot = pop.root(); + + for (unsigned i = 0; i < total_threads; i += 2) { + threads[i] = std::thread(writer, proot); + threads[i + 1] = std::thread(reader, proot); + } + + for (unsigned i = 0; i < total_threads; ++i) + threads[i].join(); +} + +void +test_stack() +{ + /* shared_mutex is not allowed outside of pmem */ + try { + nvobj::shared_mutex stack_mutex; + UT_ASSERT(0); + } catch (pmem::lock_error &le) { + } catch (...) { + UT_ASSERT(0); + } +} + +void +test_error_handling(nvobj::pool &pop) +{ + nvobj::persistent_ptr proot = pop.root(); + + proot->pmutex.lock(); + + /* pmemobj doesn't implement this on Windows */ +#if !defined(_WIN32) + /* double wrlock should fail with an exception */ + try { + proot->pmutex.lock(); + } catch (pmem::lock_error &le) { + } catch (...) { + UT_ASSERT(0); + } + + /* + * rdlock should fail with an exception when wrlock is already taken + * by the same thread + */ + try { + proot->pmutex.lock_shared(); + } catch (pmem::lock_error &le) { + } catch (...) { + UT_ASSERT(0); + } +#endif + + /* but try_locking fails with false */ + UT_ASSERT(proot->pmutex.try_lock() == false); + UT_ASSERT(proot->pmutex.try_lock_shared() == false); + + proot->pmutex.unlock(); +} +} + +int +main(int argc, char *argv[]) +{ + START(); + + if (argc != 2) + UT_FATAL("usage: %s file-name", argv[0]); + + const char *path = argv[1]; + + nvobj::pool pop; + + try { + pop = nvobj::pool::create(path, LAYOUT, PMEMOBJ_MIN_POOL, + S_IWUSR | S_IRUSR); + } catch (pmem::pool_error &pe) { + UT_FATAL("!pool::create: %s %s", pe.what(), path); + } + + mutex_zero_test(pop); + + auto expected = num_threads * num_ops * 2; + mutex_test(pop, writer, reader); + UT_ASSERTeq(pop.root()->counter, expected); + + /* trylocks are not tested as exhaustively */ + expected -= num_threads * 2; + mutex_test(pop, writer_trylock, reader_trylock); + UT_ASSERTeq(pop.root()->counter, expected); + + /* pmemcheck related persist */ + pmemobj_persist(pop.handle(), &(pop.root()->counter), + sizeof(pop.root()->counter)); + + test_stack(); + test_error_handling(pop); + + pop.close(); + + return 0; +} diff --git a/tests/shared_mutex_posix/shared_mutex_posix.cpp b/tests/shared_mutex_posix/shared_mutex_posix.cpp new file mode 100644 index 0000000..4a1822c --- /dev/null +++ b/tests/shared_mutex_posix/shared_mutex_posix.cpp @@ -0,0 +1,212 @@ +/* + * Copyright 2016-2018, Intel Corporation + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * * Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +/* + * obj_cpp_shared_mutex_posix.cpp -- cpp shared mutex test + * + */ + +#include "pthread_common.hpp" +#include "unittest.hpp" + +#include +#include +#include + +#include + +#define LAYOUT "cpp" + +namespace nvobj = pmem::obj; + +namespace +{ + +/* pool root structure */ +struct root { + nvobj::shared_mutex pmutex; + unsigned counter; +}; + +/* number of ops per thread */ +const unsigned num_ops = 200; + +/* the number of threads */ +const unsigned num_threads = 30; + +/* + * writer -- (internal) bump up the counter by 2 + */ +void * +writer(void *arg) +{ + auto proot = static_cast *>(arg); + + for (unsigned i = 0; i < num_ops; ++i) { + std::lock_guard lock((*proot)->pmutex); + ++((*proot)->counter); + ++((*proot)->counter); + } + return nullptr; +} + +/* + * reader -- (internal) verify if the counter is even + */ +void * +reader(void *arg) +{ + auto proot = static_cast *>(arg); + for (unsigned i = 0; i < num_ops; ++i) { + (*proot)->pmutex.lock_shared(); + UT_ASSERTeq((*proot)->counter % 2, 0); + (*proot)->pmutex.unlock_shared(); + } + return nullptr; +} + +/* + * writer_trylock -- (internal) trylock bump the counter by 2 + */ +void * +writer_trylock(void *arg) +{ + auto proot = static_cast *>(arg); + for (;;) { + if ((*proot)->pmutex.try_lock()) { + --((*proot)->counter); + --((*proot)->counter); + (*proot)->pmutex.unlock(); + break; + } + } + return nullptr; +} + +/* + * reader_trylock -- (internal) trylock verify that the counter is even + */ +void * +reader_trylock(void *arg) +{ + auto proot = static_cast *>(arg); + for (;;) { + if ((*proot)->pmutex.try_lock_shared()) { + UT_ASSERTeq((*proot)->counter % 2, 0); + (*proot)->pmutex.unlock_shared(); + break; + } + } + return nullptr; +} + +/* + * mutex_zero_test -- (internal) test the zeroing constructor + */ +void +mutex_zero_test(nvobj::pool &pop) +{ + PMEMoid raw_mutex; + + pmemobj_alloc(pop.handle(), &raw_mutex, sizeof(PMEMrwlock), 1, + [](PMEMobjpool *pop, void *ptr, void *arg) -> int { + PMEMrwlock *mtx = static_cast(ptr); + pmemobj_memset_persist(pop, mtx, 1, sizeof(*mtx)); + return 0; + }, + nullptr); + + nvobj::shared_mutex *placed_mtx = + new (pmemobj_direct(raw_mutex)) nvobj::shared_mutex; + std::unique_lock lck(*placed_mtx); +} + +/* + * mutex_test -- (internal) launch worker threads to test the pshared_mutex + */ +template +void +mutex_test(nvobj::pool &pop, Worker writer, Worker reader) +{ + const auto total_threads = num_threads * 2u; + pthread_t threads[total_threads]; + + auto proot = pop.root(); + + for (unsigned i = 0; i < total_threads; i += 2) { + ut_pthread_create(&threads[i], nullptr, writer, &proot); + ut_pthread_create(&threads[i + 1], nullptr, reader, &proot); + } + + for (unsigned i = 0; i < total_threads; ++i) + ut_pthread_join(&threads[i], nullptr); +} +} + +int +main(int argc, char *argv[]) +{ + START(); + + if (argc != 2) + UT_FATAL("usage: %s file-name", argv[0]); + + const char *path = argv[1]; + + nvobj::pool pop; + + try { + pop = nvobj::pool::create(path, LAYOUT, PMEMOBJ_MIN_POOL, + S_IWUSR | S_IRUSR); + } catch (pmem::pool_error &pe) { + UT_FATAL("!pool::create: %s %s", pe.what(), path); + } + + mutex_zero_test(pop); + + auto expected = num_threads * num_ops * 2; + mutex_test(pop, writer, reader); + UT_ASSERTeq(pop.root()->counter, expected); + + /* trylocks are not tested as exhaustively */ + expected -= num_threads * 2; + mutex_test(pop, writer_trylock, reader_trylock); + UT_ASSERTeq(pop.root()->counter, expected); + + /* pmemcheck related persist */ + pmemobj_persist(pop.handle(), &(pop.root()->counter), + sizeof(pop.root()->counter)); + + pop.close(); + + return 0; +} diff --git a/tests/string_access/string_access.cpp b/tests/string_access/string_access.cpp new file mode 100644 index 0000000..57de7fc --- /dev/null +++ b/tests/string_access/string_access.cpp @@ -0,0 +1,214 @@ +/* + * Copyright 2019, Intel Corporation + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * * Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "unittest.hpp" + +#include +#include + +namespace nvobj = pmem::obj; +namespace pmem_exp = nvobj::experimental; +using S = pmem_exp::string; + +struct root { + nvobj::persistent_ptr s1; + nvobj::persistent_ptr s2; +}; + +/* Check if access method can be called out of transaction scope */ +void +check_access_out_of_tx(S &s) +{ + try { + s[0]; + s.at(0); + s.begin(); + s.c_str(); + s.data(); + s.end(); + s.rbegin(); + s.rend(); + s.front(); + s.back(); + + s.const_at(0); + s.cbegin(); + s.cdata(); + s.cend(); + s.crbegin(); + s.crend(); + s.cfront(); + s.cback(); + + static_cast(s)[0]; + static_cast(s).at(0); + static_cast(s).begin(); + static_cast(s).data(); + static_cast(s).end(); + static_cast(s).rbegin(); + static_cast(s).rend(); + static_cast(s).front(); + static_cast(s).back(); + } catch (std::exception &e) { + UT_FATALexc(e); + } +} + +/* + * Check if access methods, iterators and dereference operator add + * elements to transaction. Expect no pmemcheck errors. + */ +void +check_add_to_tx(nvobj::pool &pop, S &s) +{ + try { + nvobj::transaction::run(pop, [&] { s[0] = '1'; }); + nvobj::transaction::run(pop, [&] { s.at(0) = '2'; }); + nvobj::transaction::run(pop, [&] { + auto p = s.data(); + for (unsigned i = 0; i < s.size(); ++i) + *(p + i) = '0'; + }); + nvobj::transaction::run(pop, [&] { *s.begin() = '3'; }); + nvobj::transaction::run(pop, [&] { *(s.end() - 1) = '4'; }); + nvobj::transaction::run(pop, [&] { *s.rbegin() = '5'; }); + nvobj::transaction::run(pop, [&] { *(s.rend() - 1) = '6'; }); + nvobj::transaction::run(pop, [&] { s.front() = '7'; }); + nvobj::transaction::run(pop, [&] { s.back() = '8'; }); + } catch (std::exception &e) { + UT_FATALexc(e); + } +} + +void +assert_tx_abort(pmem::obj::pool &pop, S &s, + std::function f) +{ + bool exception_thrown = false; + try { + nvobj::transaction::run(pop, [&] { + f(); + nvobj::transaction::abort(EINVAL); + }); + } catch (pmem::manual_tx_abort &) { + exception_thrown = true; + } catch (std::exception &e) { + UT_FATALexc(e); + } + UT_ASSERT(exception_thrown); +} + +void +check_tx_abort(pmem::obj::pool &pop, S &s) +{ + try { + assert_tx_abort(pop, s, [&] { s[0] = '5'; }); + UT_ASSERT(s[0] == '0'); + + assert_tx_abort(pop, s, [&] { s.at(0) = '5'; }); + UT_ASSERT(s.at(0) == '0'); + + assert_tx_abort(pop, s, [&] { *s.begin() = '5'; }); + UT_ASSERT(*s.begin() == '0'); + + assert_tx_abort(pop, s, [&] { *(s.end() - 1) = '5'; }); + UT_ASSERT(*(s.end() - 1) == '9'); + + assert_tx_abort(pop, s, [&] { *s.rbegin() = '5'; }); + UT_ASSERT(*s.rbegin() == '9'); + + assert_tx_abort(pop, s, [&] { *(s.rend() - 1) = '5'; }); + UT_ASSERT(*(s.rend() - 1) == '0'); + + assert_tx_abort(pop, s, [&] { s.front() = '5'; }); + UT_ASSERT(s[0] == '0'); + + assert_tx_abort(pop, s, [&] { s.back() = '5'; }); + UT_ASSERT(s[s.size() - 1] == '9'); + } catch (std::exception &e) { + UT_FATALexc(e); + } +} + +int +main(int argc, char *argv[]) +{ + START(); + + if (argc < 2) { + std::cerr << "usage: " << argv[0] << " file-name" << std::endl; + return 1; + } + + auto path = argv[1]; + auto pop = nvobj::pool::create( + path, "StringTest", PMEMOBJ_MIN_POOL, S_IWUSR | S_IRUSR); + + auto r = pop.root(); + + nvobj::transaction::run(pop, [&] { + r->s1 = nvobj::make_persistent("0123456789"); + r->s2 = nvobj::make_persistent( + "0123456789012345678901234567890123456789" + "0123456789012345678901234567890123456789" + "0123456789012345678901234567890123456789" + "0123456789"); + }); + + check_access_out_of_tx(*r->s1); + check_access_out_of_tx(*r->s2); + check_add_to_tx(pop, *r->s1); + check_add_to_tx(pop, *r->s2); + + nvobj::transaction::run(pop, [&] { + nvobj::delete_persistent(r->s1); + nvobj::delete_persistent(r->s2); + r->s1 = nvobj::make_persistent("0123456789"); + r->s2 = nvobj::make_persistent( + "0123456789012345678901234567890123456789" + "0123456789012345678901234567890123456789" + "0123456789012345678901234567890123456789" + "0123456789"); + }); + + check_tx_abort(pop, *r->s1); + check_tx_abort(pop, *r->s2); + + nvobj::transaction::run(pop, [&] { + nvobj::delete_persistent(r->s1); + nvobj::delete_persistent(r->s2); + }); + + pop.close(); + + return 0; +} diff --git a/tests/string_assign_tx_abort/string_assign_tx_abort.cpp b/tests/string_assign_tx_abort/string_assign_tx_abort.cpp new file mode 100644 index 0000000..174a979 --- /dev/null +++ b/tests/string_assign_tx_abort/string_assign_tx_abort.cpp @@ -0,0 +1,300 @@ +/* + * Copyright 2019, Intel Corporation + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * * Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "unittest.hpp" + +#include +#include + +#include + +namespace nvobj = pmem::obj; +namespace pmem_exp = nvobj::experimental; +using S = pmem_exp::string; +using WS = pmem_exp::wstring; +using W16 = pmem_exp::basic_string; + +struct root { + nvobj::persistent_ptr s; + nvobj::persistent_ptr ws; + nvobj::persistent_ptr w16; +}; + +template +void +check_string(nvobj::persistent_ptr> &ptr, + size_t count, CharT value) +{ + UT_ASSERTeq(ptr->size(), count); + + for (unsigned i = 0; i < count; ++i) + UT_ASSERTeq(ptr->const_at(i), value); +} + +void +assert_tx_abort(pmem::obj::pool &pop, std::function f) +{ + bool exception_thrown = false; + try { + nvobj::transaction::run(pop, [&] { + f(); + nvobj::transaction::abort(EINVAL); + }); + } catch (pmem::manual_tx_abort &) { + exception_thrown = true; + } catch (std::exception &e) { + UT_FATALexc(e); + } + UT_ASSERT(exception_thrown); +} + +/** + * Test pmem::obj::experimental::string assign() methods and operator=. + * + * Checks if string's state is reverted when transaction aborts. + */ +template +void +test(nvobj::pool &pop, + nvobj::persistent_ptr> &ptr) +{ + using string_type = pmem_exp::basic_string; + + /* assign() - fill version */ + check_string(ptr, InitialSize, static_cast('a')); + assert_tx_abort(pop, [&] { + ptr->assign(TestSize, static_cast('b')); + check_string(ptr, TestSize, static_cast('b')); + }); + check_string(ptr, InitialSize, static_cast('a')); + + /* assign() - range version */ + assert_tx_abort(pop, [&] { + std::basic_string v2(TestSize, static_cast('b')); + ptr->assign(v2.begin(), v2.end()); + check_string(ptr, TestSize, static_cast('b')); + }); + check_string(ptr, InitialSize, static_cast('a')); + + /* assign() - initializer list version */ + assert_tx_abort(pop, [&] { + ptr->assign({static_cast(2), static_cast(2), + static_cast(2), static_cast(2), + static_cast(2)}); + check_string(ptr, 5, static_cast(2)); + }); + check_string(ptr, InitialSize, static_cast('a')); + + /* assign() - rvalue reference to other string */ + assert_tx_abort(pop, [&] { + auto v2 = nvobj::make_persistent( + TestSize, static_cast('b')); + ptr->assign(std::move(*v2)); + check_string(ptr, TestSize, static_cast('b')); + nvobj::delete_persistent(v2); + }); + check_string(ptr, InitialSize, static_cast('a')); + + /* assign() - lvalue reference to other string */ + assert_tx_abort(pop, [&] { + auto v2 = nvobj::make_persistent( + TestSize, static_cast('b')); + ptr->assign(*v2); + check_string(ptr, TestSize, static_cast('b')); + nvobj::delete_persistent(v2); + }); + check_string(ptr, InitialSize, static_cast('a')); + + /* assign() - C-style string */ + assert_tx_abort(pop, [&] { + auto cstring = new CharT[TestSize + 1]; + std::fill(cstring, cstring + TestSize, static_cast('b')); + cstring[TestSize] = static_cast('\0'); + + ptr->assign(cstring); + check_string(ptr, TestSize, static_cast('b')); + + delete[] cstring; + }); + check_string(ptr, InitialSize, static_cast('a')); + + /* assign() - C-style string, count */ + assert_tx_abort(pop, [&] { + auto cstring = new CharT[TestSize + 11]; + std::fill(cstring, cstring + TestSize + 11, + static_cast('b')); + cstring[TestSize + 10] = static_cast('\0'); + + ptr->assign(cstring, TestSize); + check_string(ptr, TestSize, static_cast('b')); + + delete[] cstring; + }); + check_string(ptr, InitialSize, static_cast('a')); + + /* assign() - pmem::string, pos, count */ + assert_tx_abort(pop, [&] { + auto v2 = nvobj::make_persistent( + TestSize + 20, static_cast('b')); + ptr->assign(*v2, 20, TestSize); + check_string(ptr, TestSize, static_cast('b')); + nvobj::delete_persistent(v2); + }); + + check_string(ptr, InitialSize, static_cast('a')); + + /* assign() - pmem::string, count */ + assert_tx_abort(pop, [&] { + auto v2 = nvobj::make_persistent( + TestSize + 20, static_cast('b')); + ptr->assign(*v2, 20); + check_string(ptr, TestSize, static_cast('b')); + nvobj::delete_persistent(v2); + }); + check_string(ptr, InitialSize, static_cast('a')); + + /* copy assignment operator from C-string */ + assert_tx_abort(pop, [&] { + auto cstring = new CharT[TestSize + 1]; + std::fill(cstring, cstring + TestSize + 1, + static_cast('b')); + cstring[TestSize] = static_cast('\0'); + + *ptr = cstring; + check_string(ptr, TestSize, static_cast('b')); + + delete[] cstring; + }); + check_string(ptr, InitialSize, static_cast('a')); + + /* assignment operator for pmem::string */ + assert_tx_abort(pop, [&] { + auto v2 = nvobj::make_persistent( + TestSize, static_cast('b')); + *ptr = *v2; + check_string(ptr, TestSize, static_cast('b')); + nvobj::delete_persistent(v2); + }); + check_string(ptr, InitialSize, static_cast('a')); + + /* move assignment operator */ + assert_tx_abort(pop, [&] { + auto v2 = nvobj::make_persistent( + TestSize, static_cast('b')); + *ptr = std::move(*v2); + check_string(ptr, TestSize, static_cast('b')); + UT_ASSERT(v2->empty()); + nvobj::delete_persistent(v2); + }); + check_string(ptr, InitialSize, static_cast('a')); + + /* initializer list assignment operator */ + assert_tx_abort(pop, [&] { + *ptr = {static_cast(2), static_cast(2), + static_cast(2), static_cast(2), + static_cast(2)}; + check_string(ptr, 5, static_cast(2)); + nvobj::transaction::abort(EINVAL); + }); + check_string(ptr, InitialSize, static_cast('a')); +} + +int +main(int argc, char *argv[]) +{ + START(); + + if (argc < 2) { + std::cerr << "usage: " << argv[0] << " file-name" << std::endl; + return 1; + } + auto path = argv[1]; + auto pop = + nvobj::pool::create(path, "string_assign_tx_abort", + PMEMOBJ_MIN_POOL, S_IWUSR | S_IRUSR); + + auto r = pop.root(); + + try { + nvobj::transaction::run(pop, [&] { + r->s = nvobj::make_persistent(10U, 'a'); + r->ws = nvobj::make_persistent(10U, L'a'); + r->w16 = + nvobj::make_persistent(10U, char16_t('a')); + }); + + test<10, 20, char>(pop, r->s); + test<10, 11, char>(pop, r->s); + test<10, 9, char>(pop, r->s); + test<10, 5, char>(pop, r->s); + test<10, 100, char>(pop, r->s); + + test<10, 11, wchar_t>(pop, r->ws); + test<10, 100, wchar_t>(pop, r->ws); + + test<10, 101, char16_t>(pop, r->w16); + test<10, 100, char16_t>(pop, r->w16); + + nvobj::transaction::run(pop, [&] { + nvobj::delete_persistent(r->s); + nvobj::delete_persistent(r->ws); + nvobj::delete_persistent(r->w16); + r->s = nvobj::make_persistent(100U, 'a'); + r->ws = nvobj::make_persistent(100U, L'a'); + r->w16 = nvobj::make_persistent(100U, + char16_t('a')); + }); + + test<100, 10, char>(pop, r->s); + test<100, 101, char>(pop, r->s); + test<100, 150, char>(pop, r->s); + test<100, 99, char>(pop, r->s); + test<100, 70, char>(pop, r->s); + + test<100, 10, wchar_t>(pop, r->ws); + test<100, 101, wchar_t>(pop, r->ws); + + test<100, 10, char16_t>(pop, r->w16); + test<100, 101, char16_t>(pop, r->w16); + + nvobj::transaction::run(pop, [&] { + nvobj::delete_persistent(r->s); + nvobj::delete_persistent(r->ws); + }); + } catch (std::exception &e) { + UT_FATALexc(e); + } + + pop.close(); + + return 0; +} diff --git a/tests/string_exceptions/string_exceptions.cpp b/tests/string_exceptions/string_exceptions.cpp new file mode 100644 index 0000000..27d41d4 --- /dev/null +++ b/tests/string_exceptions/string_exceptions.cpp @@ -0,0 +1,224 @@ +/* + * Copyright 2019, Intel Corporation + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * * Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "unittest.hpp" + +#include +#include +#include +#include +#include + +#include + +namespace pmemobj_exp = pmem::obj::experimental; + +using string_type = pmemobj_exp::string; + +struct pmem_string_struct { + pmem_string_struct() : str("abcdefgh"), other("abc") + { + } + + string_type str; + string_type other; +}; + +struct root { + pmem::obj::persistent_ptr p_storage; +}; + +/* + * this function verifies that f() throws pool_error exception. + */ +void +assert_pool_exception(std::function f) +{ + bool exception_thrown = false; + try { + f(); + UT_ASSERT(0); + } catch (pmem::pool_error &) { + exception_thrown = true; + } catch (std::exception &e) { + UT_FATALexc(e); + } + + UT_ASSERT(exception_thrown); +} + +/* + * this function verifies that f() throws transaction_error exception. + */ +void +assert_tx_exception(std::function f) +{ + bool exception_thrown = false; + try { + f(); + UT_ASSERT(0); + } catch (pmem::transaction_error &) { + exception_thrown = true; + } catch (std::exception &e) { + UT_FATALexc(e); + } + + UT_ASSERT(exception_thrown); +} + +void +test_ctor_exceptions_nopmem(pmem::obj::pool &pop) try { + auto r = pop.root(); + + pmem::obj::transaction::run(pop, [&] { + r->p_storage = pmem::obj::make_persistent(); + }); + + pmem::obj::transaction::run(pop, [&] { + assert_pool_exception([&] { string_type str; }); + + assert_pool_exception([&] { string_type str(2, 'a'); }); + + assert_pool_exception( + [&] { string_type str(r->p_storage->str, 2, 2); }); + + assert_pool_exception( + [&] { string_type str(r->p_storage->str, 2); }); + + assert_pool_exception([&] { string_type str("abc", 1); }); + + assert_pool_exception([&] { string_type str("abc"); }); + + assert_pool_exception( + [&] { string_type str(std::move(r->p_storage->str)); }); + + assert_pool_exception([&] { + string_type str({'a', 'b', 'c'}); + }); + }); + + pmem::obj::transaction::run(pop, [&] { + pmem::obj::delete_persistent(r->p_storage); + }); +} catch (std::exception &e) { + UT_FATALexc(e); +} + +void +test_ctor_exceptions_notx(pmem::obj::pool &pop) try { + auto r = pop.root(); + + pmem::obj::transaction::run(pop, [&] { + r->p_storage = pmem::obj::make_persistent(); + }); + + pmem::obj::transaction::run(pop, + [&] { r->p_storage->str.~string_type(); }); + + assert_tx_exception([&] { new (&(r->p_storage->str)) string_type(); }); + + pmem::obj::transaction::run(pop, + [&] { r->p_storage->str.~string_type(); }); + + assert_tx_exception( + [&] { new (&(r->p_storage->str)) string_type(2, 'a'); }); + + pmem::obj::transaction::run(pop, + [&] { r->p_storage->str.~string_type(); }); + + assert_tx_exception([&] { + new (&(r->p_storage->str)) + string_type(r->p_storage->other, 2, 2); + }); + + pmem::obj::transaction::run(pop, + [&] { r->p_storage->str.~string_type(); }); + + assert_tx_exception([&] { + new (&(r->p_storage->str)) string_type(r->p_storage->other, 2); + }); + + pmem::obj::transaction::run(pop, + [&] { r->p_storage->str.~string_type(); }); + + assert_tx_exception( + [&] { new (&(r->p_storage->str)) string_type("abc", 1); }); + + pmem::obj::transaction::run(pop, + [&] { r->p_storage->str.~string_type(); }); + + assert_tx_exception( + [&] { new (&(r->p_storage->str)) string_type("abc"); }); + + pmem::obj::transaction::run(pop, + [&] { r->p_storage->str.~string_type(); }); + + assert_tx_exception([&] { + new (&(r->p_storage->str)) + string_type(std::move(r->p_storage->other)); + }); + + pmem::obj::transaction::run(pop, + [&] { r->p_storage->str.~string_type(); }); + + assert_tx_exception([&] { + new (&(r->p_storage->str)) string_type({'a', 'b', 'c'}); + }); + + pmem::obj::transaction::run(pop, [&] { + pmem::obj::delete_persistent(r->p_storage); + }); +} catch (std::exception &e) { + UT_FATALexc(e); +} + +int +main(int argc, char *argv[]) +{ + START(); + + if (argc < 2) { + std::cerr << "usage: " << argv[0] << " file-name " << std::endl; + return 1; + } + + auto path = argv[1]; + auto pop = pmem::obj::pool::create( + path, "StringTest", PMEMOBJ_MIN_POOL, S_IWUSR | S_IRUSR); + + test_ctor_exceptions_nopmem(pop); + test_ctor_exceptions_notx(pop); + + pop.close(); + + return 0; +} diff --git a/tests/string_snapshot/string_snapshot.cpp b/tests/string_snapshot/string_snapshot.cpp new file mode 100644 index 0000000..480287e --- /dev/null +++ b/tests/string_snapshot/string_snapshot.cpp @@ -0,0 +1,148 @@ +/* + * Copyright 2019, Intel Corporation + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * * Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "unittest.hpp" + +#include +#include +#include +#include +#include + +#include + +namespace pmemobj_exp = pmem::obj::experimental; + +using string_type = pmemobj_exp::string; + +struct root { + pmem::obj::persistent_ptr short_str; + pmem::obj::persistent_ptr long_str; +}; + +static constexpr char short_c_str_ctor[] = "0987654321"; +static constexpr char long_c_str_ctor[] = + "0987654321098765432109876543210987654321" + "0987654321098765432109876543210987654321" + "0987654321098765432109876543210987654321" + "0987654321"; + +static constexpr char short_c_str[] = "1234567890"; +static constexpr char long_c_str[] = "1234567890123456789012345678901234567890" + "1234567890123456789012345678901234567890" + "1234567890123456789012345678901234567890" + "1234567890"; + +void +test_string_snapshot(pmem::obj::pool &pop) +{ + auto r = pop.root(); + + try { + pmem::obj::transaction::run(pop, [&] { + r->short_str = pmem::obj::make_persistent( + short_c_str_ctor); + r->long_str = pmem::obj::make_persistent( + long_c_str_ctor); + + UT_ASSERTeq(r->short_str->size(), + strlen(short_c_str_ctor)); + UT_ASSERTeq(r->long_str->size(), + strlen(long_c_str_ctor)); + }); + } catch (std::exception &e) { + UT_FATALexc(e); + } + + using T = typename string_type::traits_type; + + try { + pmem::obj::transaction::run(pop, [&] { + auto data = r->short_str->data(); + strcpy(data, short_c_str); + + UT_ASSERTeq(T::compare(r->short_str->cdata(), + short_c_str, + r->short_str->size()), + 0); + UT_ASSERTeq(T::length(r->short_str->cdata()), + T::length(short_c_str)); + }); + } catch (std::exception &e) { + UT_FATALexc(e); + } + + try { + pmem::obj::transaction::run(pop, [&] { + auto data = r->long_str->data(); + strcpy(data, long_c_str); + + UT_ASSERTeq(T::compare(r->long_str->cdata(), long_c_str, + r->long_str->size()), + 0); + UT_ASSERTeq(T::length(r->long_str->cdata()), + T::length(long_c_str)); + }); + } catch (std::exception &e) { + UT_FATALexc(e); + } + + try { + pmem::obj::transaction::run(pop, [&] { + pmem::obj::delete_persistent(r->short_str); + pmem::obj::delete_persistent(r->long_str); + }); + } catch (std::exception &e) { + UT_FATALexc(e); + } +} + +int +main(int argc, char *argv[]) +{ + START(); + + if (argc < 2) { + std::cerr << "usage: " << argv[0] << " file-name " << std::endl; + return 1; + } + + auto path = argv[1]; + auto pop = pmem::obj::pool::create( + path, "StringTest", PMEMOBJ_MIN_POOL, S_IWUSR | S_IRUSR); + + test_string_snapshot(pop); + + pop.close(); + + return 0; +} diff --git a/tests/temp_value/temp_value.cpp b/tests/temp_value/temp_value.cpp new file mode 100644 index 0000000..85971f5 --- /dev/null +++ b/tests/temp_value/temp_value.cpp @@ -0,0 +1,120 @@ +/* + * Copyright 2019, Intel Corporation + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * * Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +/* + * temp_value.c -- temp_value caching struct test + */ + +#include "unittest.hpp" + +#include +#include +#include +#include + +namespace nvobj = pmem::obj; +namespace det = pmem::detail; + +const unsigned big_stack_alloc = + LIBPMEMOBJ_CPP_MAX_STACK_ALLOC_SIZE / sizeof(int) + 1; + +struct root { +}; + +struct test_small { + test_small() noexcept {}; + + test_small(int a){}; /* may throw */ +}; + +struct test_big { + int a[big_stack_alloc]; + + test_big() noexcept {}; + + test_big(int a){}; /* may throw */ +}; + +using temp_noexcept_small = det::temp_value; +using temp_throw_small = det::temp_value; +using temp_noexcept_big = det::temp_value; +using temp_throw_big = det::temp_value; + +template +bool +is_pmem(T &ptr) +{ + return nullptr != pmemobj_pool_by_ptr(static_cast(&ptr)); +} + +int +main(int argc, char *argv[]) +{ + START(); + + if (argc != 2) + UT_FATAL("usage: %s file-name", argv[0]); + + const char *path = argv[1]; + + nvobj::pool pop; + + try { + pop = nvobj::pool::create(path, "temp_value test", + PMEMOBJ_MIN_POOL, + S_IWUSR | S_IRUSR); + } catch (pmem::pool_error &pe) { + UT_FATAL("!pool::create: %s %s", pe.what(), path); + } + + try { + nvobj::transaction::run(pop, [&] { + temp_noexcept_small tmp1; + UT_ASSERT(!is_pmem(tmp1.get())); + + temp_throw_small tmp2; + UT_ASSERT(is_pmem(tmp2.get())); + + temp_noexcept_big tmp3; + UT_ASSERT(is_pmem(tmp3.get())); + + temp_throw_big tmp4; + UT_ASSERT(is_pmem(tmp3.get())); + }); + } catch (std::exception &e) { + UT_FATALexc(e); + } + + pop.close(); + + return 0; +} diff --git a/tests/test_backtrace.c b/tests/test_backtrace.c new file mode 100644 index 0000000..b9293d5 --- /dev/null +++ b/tests/test_backtrace.c @@ -0,0 +1,221 @@ +/* + * Copyright 2015-2019, Intel Corporation + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * * Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +/* + * backtrace.c -- backtrace reporting routines + */ + +#ifndef _GNU_SOURCE +#define _GNU_SOURCE +#endif + +#include "test_backtrace.h" +#include +#include +#include +#include +#include + +#ifdef USE_LIBUNWIND + +#define UNW_LOCAL_ONLY +#include +#include + +#define PROCNAMELEN 256 +/* + * test_dump_backtrace -- dump stacktrace to error log using libunwind + */ +void +test_dump_backtrace(void) +{ + unw_context_t context; + unw_proc_info_t pip; + + pip.unwind_info = NULL; + int ret = unw_getcontext(&context); + if (ret) { + printf("unw_getcontext: %s [%d]\n", unw_strerror(ret), ret); + return; + } + + unw_cursor_t cursor; + ret = unw_init_local(&cursor, &context); + if (ret) { + printf("unw_init_local: %s [%d]\n", unw_strerror(ret), ret); + return; + } + + ret = unw_step(&cursor); + + char procname[PROCNAMELEN]; + unsigned i = 0; + + while (ret > 0) { + ret = unw_get_proc_info(&cursor, &pip); + if (ret) { + printf("unw_get_proc_info: %s [%d]\n", + unw_strerror(ret), ret); + break; + } + + unw_word_t off; + ret = unw_get_proc_name(&cursor, procname, PROCNAMELEN, &off); + if (ret && ret != -UNW_ENOMEM) { + if (ret != -UNW_EUNSPEC) { + printf("unw_get_proc_name: %s [%d]\n", + unw_strerror(ret), ret); + } + + strcpy(procname, "?"); + } + + void *ptr = (void *)(pip.start_ip + off); + Dl_info dlinfo; + const char *fname = "?"; + + if (dladdr(ptr, &dlinfo) && dlinfo.dli_fname && + *dlinfo.dli_fname) + fname = dlinfo.dli_fname; + + printf("%u: %s (%s%s+0x%lx) [%p]\n", i++, fname, procname, + ret == -UNW_ENOMEM ? "..." : "", off, ptr); + + ret = unw_step(&cursor); + if (ret < 0) + printf("unw_step: %s [%d]\n", unw_strerror(ret), ret); + } +} +#else /* USE_LIBUNWIND */ + +#define BSIZE 100 + +#ifndef _WIN32 + +#include + +/* + * test_dump_backtrace -- dump stacktrace to error log using libc's backtrace + */ +void +test_dump_backtrace(void) +{ + int j, nptrs; + void *buffer[BSIZE]; + char **strings; + + nptrs = backtrace(buffer, BSIZE); + + strings = backtrace_symbols(buffer, nptrs); + if (strings == NULL) { + printf("backtrace_symbols %s\n", strerror(errno)); + return; + } + + for (j = 0; j < nptrs; j++) + printf("%u: %s\n", j, strings[j]); + + free(strings); +} + +#else /* _WIN32 */ + +#include +#include +#include + +#include + +/* + * test_dump_backtrace -- dump stacktrace to error log + */ +void +test_dump_backtrace(void) +{ + void *buffer[BSIZE]; + unsigned nptrs; + SYMBOL_INFO *symbol; + + HANDLE proc_hndl = GetCurrentProcess(); + SymInitialize(proc_hndl, NULL, TRUE); + + nptrs = CaptureStackBackTrace(0, BSIZE, buffer, NULL); + symbol = calloc(sizeof(SYMBOL_INFO) + MAX_SYM_NAME * sizeof(CHAR), 1); + symbol->MaxNameLen = MAX_SYM_NAME - 1; + symbol->SizeOfStruct = sizeof(SYMBOL_INFO); + + for (unsigned i = 0; i < nptrs; i++) { + if (SymFromAddr(proc_hndl, (DWORD64)buffer[i], 0, symbol)) { + printf("%u: %s [%p]\n", nptrs - i - 1, symbol->Name, + buffer[i]); + } else { + printf("%u: [%p]\n", nptrs - i - 1, buffer[i]); + } + } + + free(symbol); +} + +#endif /* _WIN32 */ + +#endif /* USE_LIBUNWIND */ + +/* + * test_sighandler -- fatal signal handler + */ +void +test_sighandler(int sig) +{ + printf("\nSignal %d, backtrace:\n", sig); + test_dump_backtrace(); + printf("\n"); + exit(128 + sig); +} + +/* + * test_register_sighandlers -- register signal handlers for various fatal + * signals + */ +void +test_register_sighandlers(void) +{ + signal(SIGSEGV, test_sighandler); + signal(SIGABRT, test_sighandler); + signal(SIGILL, test_sighandler); + signal(SIGFPE, test_sighandler); + signal(SIGINT, test_sighandler); +#ifndef _WIN32 + signal(SIGALRM, test_sighandler); + signal(SIGQUIT, test_sighandler); + signal(SIGBUS, test_sighandler); +#endif +} diff --git a/tests/test_backtrace.h b/tests/test_backtrace.h new file mode 100644 index 0000000..4bbdc9b --- /dev/null +++ b/tests/test_backtrace.h @@ -0,0 +1,47 @@ +/* + * Copyright 2015-2017, Intel Corporation + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * * Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef TEST_BACKTRACE_H +#define TEST_BACKTRACE_H + +#ifdef __cplusplus +extern "C" { +#endif + +void test_dump_backtrace(void); +void test_sighandler(int sig); +void test_register_sighandlers(void); + +#ifdef __cplusplus +} +#endif +#endif diff --git a/tests/timed_mtx/timed_mtx.cpp b/tests/timed_mtx/timed_mtx.cpp new file mode 100644 index 0000000..214042f --- /dev/null +++ b/tests/timed_mtx/timed_mtx.cpp @@ -0,0 +1,294 @@ +/* + * Copyright 2016-2018, Intel Corporation + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * * Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +/* + * obj_cpp_mutex.cpp -- cpp mutex test + */ + +#include "unittest.hpp" + +#include +#include +#include + +#include +#include + +#define LAYOUT "cpp" + +namespace nvobj = pmem::obj; + +namespace +{ + +/* pool root structure */ +struct root { + nvobj::timed_mutex pmutex; + unsigned counter; +}; + +/* number of ops per thread */ +const unsigned num_ops = 200; + +/* the number of threads */ +const unsigned num_threads = 30; + +/* timeout for try_lock_for and try_lock_until methods */ +const auto timeout = std::chrono::milliseconds(100); + +/* loop trylock_for|until tests */ +bool loop; + +/* + * Premature wake-up tolerance. + * XXX Windows - this needs to be investigated, it shouldn't timeout this long + * before the actual timeout. + */ +const auto epsilon = std::chrono::milliseconds(16); + +/* + * increment_pint -- (internal) test the mutex with an std::lock_guard + */ +static void +increment_pint(nvobj::persistent_ptr proot) +{ + for (unsigned i = 0; i < num_ops; ++i) { + std::lock_guard lock(proot->pmutex); + (proot->counter)++; + } +} + +/* + * decrement_pint -- (internal) test the mutex with an std::unique_lock + */ +static void +decrement_pint(nvobj::persistent_ptr proot) +{ + std::unique_lock lock(proot->pmutex); + for (unsigned i = 0; i < num_ops; ++i) + --(proot->counter); + + lock.unlock(); +} + +/* + * trylock_test -- (internal) test the trylock implementation + */ +static void +trylock_test(nvobj::persistent_ptr proot) +{ + for (;;) { + if (proot->pmutex.try_lock()) { + (proot->counter)++; + proot->pmutex.unlock(); + return; + } + } +} + +/* + * trylock_for_test -- (internal) test the try_lock_for implementation + */ +static void +trylock_for_test(nvobj::persistent_ptr proot) +{ + using clk = std::chrono::system_clock; + + do { + auto t1 = clk::now(); + if (proot->pmutex.try_lock_for(timeout)) { + (proot->counter)++; + proot->pmutex.unlock(); + break; + } else { + auto t2 = clk::now(); + auto diff = std::chrono::duration_cast< + std::chrono::milliseconds>((t1 + timeout) - t2); + UT_ASSERT(diff < epsilon); + } + } while (loop); + return; +} + +/* + * trylock_until_test -- (internal) test the try_lock_until implementation + */ +static void +trylock_until_test(nvobj::persistent_ptr proot) +{ + using clk = std::chrono::system_clock; + + do { + auto t1 = clk::now(); + if (proot->pmutex.try_lock_until(t1 + timeout)) { + --(proot->counter); + proot->pmutex.unlock(); + break; + } else { + auto t2 = clk::now(); + auto diff = std::chrono::duration_cast< + std::chrono::milliseconds>((t1 + timeout) - t2); + UT_ASSERT(diff < epsilon); + } + } while (loop); + + return; +} + +/* + * mutex_zero_test -- (internal) test the zeroing constructor + */ +void +mutex_zero_test(nvobj::pool &pop) +{ + PMEMoid raw_mutex; + + pmemobj_alloc(pop.handle(), &raw_mutex, sizeof(PMEMmutex), 1, + [](PMEMobjpool *pop, void *ptr, void *) -> int { + PMEMmutex *mtx = static_cast(ptr); + pmemobj_memset_persist(pop, mtx, 1, sizeof(*mtx)); + return 0; + }, + nullptr); + + nvobj::timed_mutex *placed_mtx = + new (pmemobj_direct(raw_mutex)) nvobj::timed_mutex; + std::unique_lock lck(*placed_mtx); +} + +/* + * mutex_test -- (internal) launch worker threads to test the pmutex + */ +template +void +timed_mtx_test(nvobj::pool &pop, const Worker &function) +{ + std::thread threads[num_threads]; + + auto proot = pop.root(); + + for (unsigned i = 0; i < num_threads; ++i) + threads[i] = std::thread(function, proot); + + for (unsigned i = 0; i < num_threads; ++i) + threads[i].join(); +} + +void +test_stack() +{ + /* mutex is not allowed outside of pmem */ + try { + nvobj::timed_mutex stack_mutex; + UT_ASSERT(0); + } catch (pmem::lock_error &le) { + } catch (...) { + UT_ASSERT(0); + } +} + +void +test_error_handling(nvobj::pool &pop) +{ + nvobj::persistent_ptr proot = pop.root(); + + proot->pmutex.lock(); + + /* try_locking already taken lock fails with false */ + UT_ASSERT(proot->pmutex.try_lock() == false); + + proot->pmutex.unlock(); +} +} + +int +main(int argc, char *argv[]) +{ + START(); + + if (argc != 2) + UT_FATAL("usage: %s file-name", argv[0]); + + const char *path = argv[1]; + + nvobj::pool pop; + + try { + pop = nvobj::pool::create(path, LAYOUT, PMEMOBJ_MIN_POOL, + S_IWUSR | S_IRUSR); + } catch (pmem::pool_error &pe) { + UT_FATAL("!pool::create: %s %s", pe.what(), path); + } + + mutex_zero_test(pop); + + timed_mtx_test(pop, increment_pint); + UT_ASSERTeq(pop.root()->counter, num_threads * num_ops); + + timed_mtx_test(pop, decrement_pint); + UT_ASSERTeq(pop.root()->counter, 0); + + timed_mtx_test(pop, trylock_test); + UT_ASSERTeq(pop.root()->counter, num_threads); + + /* loop the next two tests */ + loop = true; + + timed_mtx_test(pop, trylock_until_test); + UT_ASSERTeq(pop.root()->counter, 0); + + timed_mtx_test(pop, trylock_for_test); + UT_ASSERTeq(pop.root()->counter, num_threads); + + loop = false; + + pop.root()->pmutex.lock(); + + timed_mtx_test(pop, trylock_until_test); + UT_ASSERTeq(pop.root()->counter, num_threads); + + timed_mtx_test(pop, trylock_for_test); + UT_ASSERTeq(pop.root()->counter, num_threads); + + pop.root()->pmutex.unlock(); + + /* pmemcheck related persist */ + pmemobj_persist(pop.handle(), &(pop.root()->counter), + sizeof(pop.root()->counter)); + + test_stack(); + test_error_handling(pop); + + pop.close(); + + return 0; +} diff --git a/tests/timed_mtx_posix/timed_mtx_posix.cpp b/tests/timed_mtx_posix/timed_mtx_posix.cpp new file mode 100644 index 0000000..a8400a8 --- /dev/null +++ b/tests/timed_mtx_posix/timed_mtx_posix.cpp @@ -0,0 +1,267 @@ +/* + * Copyright 2016-2018, Intel Corporation + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * * Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +/* + * obj_cpp_mutex_posix.cpp -- cpp mutex test + */ + +#include "pthread_common.hpp" +#include "unittest.hpp" + +#include +#include +#include + +#include + +#define LAYOUT "cpp" + +namespace nvobj = pmem::obj; + +namespace +{ + +/* pool root structure */ +struct root { + nvobj::timed_mutex pmutex; + unsigned counter; +}; + +/* number of ops per thread */ +const unsigned num_ops = 200; + +/* the number of threads */ +const unsigned num_threads = 30; + +/* timeout for try_lock_for and try_lock_until methods */ +const auto timeout = std::chrono::milliseconds(100); + +/* loop trylock_for|until tests */ +bool loop = false; + +/* + * increment_pint -- (internal) test the mutex with an std::lock_guard + */ +static void * +increment_pint(void *arg) +{ + auto proot = static_cast *>(arg); + + for (unsigned i = 0; i < num_ops; ++i) { + std::lock_guard lock((*proot)->pmutex); + ((*proot)->counter)++; + } + return nullptr; +} + +/* + * decrement_pint -- (internal) test the mutex with an std::unique_lock + */ +static void * +decrement_pint(void *arg) +{ + auto proot = static_cast *>(arg); + + std::unique_lock lock((*proot)->pmutex); + for (unsigned i = 0; i < num_ops; ++i) + --((*proot)->counter); + + lock.unlock(); + return nullptr; +} + +/* + * trylock_test -- (internal) test the trylock implementation + */ +static void * +trylock_test(void *arg) +{ + auto proot = static_cast *>(arg); + for (;;) { + if ((*proot)->pmutex.try_lock()) { + ((*proot)->counter)++; + (*proot)->pmutex.unlock(); + break; + } + } + return nullptr; +} + +/* + * trylock_for_test -- (internal) test the try_lock_for implementation + */ +static void * +trylock_for_test(void *arg) +{ + using clk = std::chrono::steady_clock; + auto proot = static_cast *>(arg); + + do { + auto t1 = clk::now(); + if ((*proot)->pmutex.try_lock_for(timeout)) { + ((*proot)->counter)++; + (*proot)->pmutex.unlock(); + break; + } else { + auto t2 = clk::now(); + auto t_diff = t2 - t1; + UT_ASSERT(t_diff >= timeout); + } + } while (loop); + + return nullptr; +} + +/* + * trylock_until_test -- (internal) test the try_lock_until implementation + */ +static void * +trylock_until_test(void *arg) +{ + using clk = std::chrono::steady_clock; + auto proot = static_cast *>(arg); + + do { + auto t1 = clk::now(); + if ((*proot)->pmutex.try_lock_until(t1 + timeout)) { + --((*proot)->counter); + (*proot)->pmutex.unlock(); + break; + } else { + auto t2 = clk::now(); + auto t_diff = t2 - t1; + UT_ASSERT(t_diff >= timeout); + } + } while (loop); + + return nullptr; +} + +/* + * mutex_zero_test -- (internal) test the zeroing constructor + */ +void +mutex_zero_test(nvobj::pool &pop) +{ + PMEMoid raw_mutex; + + pmemobj_alloc(pop.handle(), &raw_mutex, sizeof(PMEMmutex), 1, + [](PMEMobjpool *pop, void *ptr, void *arg) -> int { + PMEMmutex *mtx = static_cast(ptr); + pmemobj_memset_persist(pop, mtx, 1, sizeof(*mtx)); + return 0; + }, + nullptr); + + nvobj::timed_mutex *placed_mtx = + new (pmemobj_direct(raw_mutex)) nvobj::timed_mutex; + std::unique_lock lck(*placed_mtx); +} + +/* + * mutex_test -- (internal) launch worker threads to test the pmutex + */ +template +void +timed_mtx_test(nvobj::pool &pop, Worker function) +{ + pthread_t threads[num_threads]; + + auto proot = pop.root(); + + for (unsigned i = 0; i < num_threads; ++i) + ut_pthread_create(&threads[i], nullptr, function, &proot); + + for (unsigned i = 0; i < num_threads; ++i) + ut_pthread_join(&threads[i], nullptr); +} +} + +int +main(int argc, char *argv[]) +{ + START(); + + if (argc != 2) + UT_FATAL("usage: %s file-name", argv[0]); + + const char *path = argv[1]; + + nvobj::pool pop; + + try { + pop = nvobj::pool::create( + path, LAYOUT, PMEMOBJ_MIN_POOL, S_IWUSR | S_IRUSR); + } catch (pmem::pool_error &pe) { + UT_FATAL("!pool::create: %s %s", pe.what(), path); + } + + mutex_zero_test(pop); + + timed_mtx_test(pop, increment_pint); + UT_ASSERTeq(pop.root()->counter, num_threads * num_ops); + + timed_mtx_test(pop, decrement_pint); + UT_ASSERTeq(pop.root()->counter, 0); + + timed_mtx_test(pop, trylock_test); + UT_ASSERTeq(pop.root()->counter, num_threads); + + /* loop the next two tests */ + loop = true; + + timed_mtx_test(pop, trylock_until_test); + UT_ASSERTeq(pop.root()->counter, 0); + + timed_mtx_test(pop, trylock_for_test); + UT_ASSERTeq(pop.root()->counter, num_threads); + + loop = false; + + pop.root()->pmutex.lock(); + + timed_mtx_test(pop, trylock_until_test); + UT_ASSERTeq(pop.root()->counter, num_threads); + + timed_mtx_test(pop, trylock_for_test); + UT_ASSERTeq(pop.root()->counter, num_threads); + + pop.root()->pmutex.unlock(); + + /* pmemcheck related persist */ + pmemobj_persist(pop.handle(), &(pop.root()->counter), + sizeof(pop.root()->counter)); + + pop.close(); + + return 0; +} diff --git a/tests/transaction/transaction.cpp b/tests/transaction/transaction.cpp new file mode 100644 index 0000000..249f8c2 --- /dev/null +++ b/tests/transaction/transaction.cpp @@ -0,0 +1,897 @@ +/* + * Copyright 2016-2018, Intel Corporation + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * * Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +/* + * obj_cpp_transaction.cpp -- cpp transaction test + */ + +#include "unittest.hpp" + +#include +#include +#include +#include +#include +#include +#include + +namespace +{ +int counter = 0; +} + +/* + * XXX The Microsoft compiler does not follow the ISO SD-6: SG10 Feature + * Test Recommendations. "_MSC_VER" is a workaround. + */ +#if _MSC_VER < 1900 +#ifndef __cpp_lib_uncaught_exceptions +#define __cpp_lib_uncaught_exceptions 201411 +namespace std +{ + +int +uncaught_exceptions() noexcept +{ + return ::counter; +} + +} /* namespace std */ +#endif /* __cpp_lib_uncaught_exceptions */ +#endif /* _MSC_VER */ + +#include + +#define LAYOUT "cpp" +#define POOL_SZIE PMEMOBJ_MIN_POOL + +namespace nvobj = pmem::obj; + +namespace +{ + +struct foo { + nvobj::p bar; + nvobj::shared_mutex smtx; +}; + +struct root { + nvobj::persistent_ptr pfoo; + nvobj::persistent_ptr> parr; + nvobj::mutex mtx; + nvobj::shared_mutex shared_mutex; +}; + +void +fake_commit() +{ +} + +void +real_commit() +{ + nvobj::transaction::commit(); +} + +/* + * Callable object class. + */ +class transaction_test { +public: + /* + * Constructor. + */ + transaction_test(nvobj::pool &pop_) : pop(pop_) + { + } + + /* + * The transaction worker. + */ + void + operator()() + { + auto rootp = this->pop.root(); + + if (rootp->pfoo == nullptr) + rootp->pfoo = nvobj::make_persistent(); + + rootp->pfoo->bar = 42; + } + +private: + nvobj::pool &pop; +}; + +/* + * do_transaction -- internal C-style function transaction. + */ +void +do_transaction(nvobj::pool &pop) +{ + auto rootp = pop.root(); + + rootp->parr = nvobj::make_persistent>(); + + *rootp->parr.get() = 5; +} + +/* + * Closure tests. + */ + +/* + * test_tx_no_throw_no_abort -- test transaction without exceptions and aborts + */ +void +test_tx_no_throw_no_abort(nvobj::pool &pop) +{ + auto rootp = pop.root(); + + UT_ASSERT(rootp->pfoo == nullptr); + UT_ASSERT(rootp->parr == nullptr); + + try { + nvobj::transaction::run(pop, [&]() { + rootp->pfoo = nvobj::make_persistent(); + }); + } catch (...) { + UT_ASSERT(0); + } + + UT_ASSERT(rootp->pfoo != nullptr); + UT_ASSERT(rootp->parr == nullptr); + + try { + nvobj::transaction::run( + pop, std::bind(do_transaction, std::ref(pop)), + rootp->mtx); + } catch (...) { + UT_ASSERT(0); + } + + UT_ASSERT(rootp->pfoo != nullptr); + UT_ASSERT(rootp->parr != nullptr); + UT_ASSERTeq(*rootp->parr.get(), 5); + + try { + nvobj::transaction::run(pop, transaction_test(pop), rootp->mtx, + rootp->pfoo->smtx); + } catch (...) { + UT_ASSERT(0); + } + + UT_ASSERT(rootp->pfoo != nullptr); + UT_ASSERT(rootp->parr != nullptr); + UT_ASSERTeq(*rootp->parr.get(), 5); + UT_ASSERTeq(rootp->pfoo->bar, 42); + + try { + nvobj::transaction::run(pop, [&]() { + nvobj::delete_persistent(rootp->pfoo); + nvobj::delete_persistent>(rootp->parr); + rootp->pfoo = nullptr; + rootp->parr = nullptr; + }); + } catch (...) { + UT_ASSERT(0); + } + + UT_ASSERT(rootp->pfoo == nullptr); + UT_ASSERT(rootp->parr == nullptr); +} + +static bool +test_shared_mutex_self_deadlock() +{ + /* + * Starting transaction with already taken shared_lock should fail. + * + * However: + * - pmemobj prior to 1.5.1 has a bug (see pmem/pmdk#3536) which + * corrupts mutex state by unlocking it when it shouldn't + * - shared_mutexes (rwlocks), as implemented by pmemobj, do not detect + * self-deadlocks on Windows + */ +#if TESTS_LIBPMEMOBJ_VERSION < 0x010501 || defined(_WIN32) + return false; +#else + return true; +#endif +} + +/* + * test_tx_throw_no_abort -- test transaction with exceptions and no aborts + */ +void +test_tx_throw_no_abort(nvobj::pool &pop) +{ + auto rootp = pop.root(); + + UT_ASSERT(rootp->pfoo == nullptr); + UT_ASSERT(rootp->parr == nullptr); + + bool exception_thrown = false; + try { + nvobj::transaction::run(pop, [&]() { + rootp->pfoo = nvobj::make_persistent(); + throw std::runtime_error("error"); + }); + } catch (std::runtime_error &) { + exception_thrown = true; + } catch (...) { + UT_ASSERT(0); + } + + UT_ASSERT(exception_thrown); + exception_thrown = false; + UT_ASSERT(rootp->pfoo == nullptr); + UT_ASSERT(rootp->parr == nullptr); + + try { + nvobj::transaction::run(pop, [&]() { + rootp->pfoo = nvobj::make_persistent(); + nvobj::transaction::run(pop, [&]() { + throw std::runtime_error("error"); + }); + }); + } catch (std::runtime_error &) { + exception_thrown = true; + } catch (...) { + UT_ASSERT(0); + } + + UT_ASSERT(exception_thrown); + exception_thrown = false; + UT_ASSERT(rootp->pfoo == nullptr); + UT_ASSERT(rootp->parr == nullptr); + + try { + nvobj::transaction::run(pop, [&]() { + rootp->pfoo = nvobj::make_persistent(); + try { + nvobj::transaction::run(pop, [&]() { + throw std::runtime_error("error"); + }); + } catch (std::runtime_error &) { + exception_thrown = true; + } catch (...) { + UT_ASSERT(0); + } + UT_ASSERT(exception_thrown); + exception_thrown = false; + }); + } catch (pmem::transaction_error &) { + exception_thrown = true; + } catch (...) { + UT_ASSERT(0); + } + + UT_ASSERT(exception_thrown); + UT_ASSERT(rootp->pfoo == nullptr); + UT_ASSERT(rootp->parr == nullptr); + + if (test_shared_mutex_self_deadlock()) { + exception_thrown = false; + rootp->shared_mutex.lock(); + try { + nvobj::transaction::run(pop, [&]() {}, + rootp->shared_mutex); + } catch (pmem::transaction_error &) { + exception_thrown = true; + } catch (...) { + UT_ASSERT(0); + } + + UT_ASSERT(exception_thrown); + rootp->shared_mutex.unlock(); + } +} + +/* + * test_tx_no_throw_abort -- test transaction with an abort and no exceptions + */ +void +test_tx_no_throw_abort(nvobj::pool &pop) +{ + auto rootp = pop.root(); + + UT_ASSERT(rootp->pfoo == nullptr); + UT_ASSERT(rootp->parr == nullptr); + + bool exception_thrown = false; + try { + nvobj::transaction::run(pop, [&]() { + rootp->pfoo = nvobj::make_persistent(); + nvobj::transaction::abort(-1); + }); + } catch (pmem::manual_tx_abort &) { + exception_thrown = true; + } catch (...) { + UT_ASSERT(0); + } + + UT_ASSERT(exception_thrown); + exception_thrown = false; + UT_ASSERT(rootp->pfoo == nullptr); + UT_ASSERT(rootp->parr == nullptr); + + try { + nvobj::transaction::run(pop, [&]() { + rootp->pfoo = nvobj::make_persistent(); + nvobj::transaction::run( + pop, [&]() { nvobj::transaction::abort(-1); }); + }); + } catch (pmem::manual_tx_abort &) { + exception_thrown = true; + } catch (...) { + UT_ASSERT(0); + } + + UT_ASSERT(exception_thrown); + exception_thrown = false; + UT_ASSERT(rootp->pfoo == nullptr); + UT_ASSERT(rootp->parr == nullptr); + + try { + nvobj::transaction::run(pop, [&]() { + rootp->pfoo = nvobj::make_persistent(); + try { + nvobj::transaction::run(pop, [&]() { + nvobj::transaction::abort(-1); + }); + } catch (pmem::manual_tx_abort &) { + exception_thrown = true; + } catch (...) { + UT_ASSERT(0); + } + }); + } catch (pmem::transaction_error &) { + exception_thrown = true; + } catch (...) { + UT_ASSERT(0); + } + + UT_ASSERT(exception_thrown); + UT_ASSERT(rootp->pfoo == nullptr); + UT_ASSERT(rootp->parr == nullptr); +} + +/* + * Scoped tests. + */ + +/* + * test_tx_no_throw_no_abort_scope -- test transaction without exceptions + * and aborts + */ +template +void +test_tx_no_throw_no_abort_scope(nvobj::pool &pop, + std::function commit) +{ + auto rootp = pop.root(); + + UT_ASSERT(rootp->pfoo == nullptr); + UT_ASSERT(rootp->parr == nullptr); + + try { + T to(pop); + rootp->pfoo = nvobj::make_persistent(); + commit(); + } catch (...) { + UT_ASSERT(0); + } + + UT_ASSERTeq(nvobj::transaction::error(), 0); + UT_ASSERT(rootp->pfoo != nullptr); + UT_ASSERT(rootp->parr == nullptr); + + try { + T to(pop, rootp->mtx); + do_transaction(pop); + commit(); + } catch (...) { + UT_ASSERT(0); + } + + UT_ASSERTeq(nvobj::transaction::error(), 0); + UT_ASSERT(rootp->pfoo != nullptr); + UT_ASSERT(rootp->parr != nullptr); + UT_ASSERTeq(*rootp->parr.get(), 5); + + try { + T to(pop, rootp->mtx, rootp->pfoo->smtx); + transaction_test tt(pop); + tt.operator()(); + commit(); + } catch (...) { + UT_ASSERT(0); + } + + UT_ASSERTeq(nvobj::transaction::error(), 0); + UT_ASSERT(rootp->pfoo != nullptr); + UT_ASSERT(rootp->parr != nullptr); + UT_ASSERTeq(*rootp->parr.get(), 5); + UT_ASSERTeq(rootp->pfoo->bar, 42); + + try { + T to(pop); + nvobj::delete_persistent(rootp->pfoo); + nvobj::delete_persistent>(rootp->parr); + rootp->pfoo = nullptr; + rootp->parr = nullptr; + commit(); + } catch (...) { + UT_ASSERT(0); + } + + UT_ASSERTeq(nvobj::transaction::error(), 0); + UT_ASSERT(rootp->pfoo == nullptr); + UT_ASSERT(rootp->parr == nullptr); +} + +/* + * test_tx_throw_no_abort_scope -- test transaction with exceptions + * and no aborts + */ +template +void +test_tx_throw_no_abort_scope(nvobj::pool &pop) +{ + auto rootp = pop.root(); + + UT_ASSERT(rootp->pfoo == nullptr); + UT_ASSERT(rootp->parr == nullptr); + + bool exception_thrown = false; + try { + counter = 0; + T to(pop); + rootp->pfoo = nvobj::make_persistent(); + counter = 1; + throw std::runtime_error("error"); + } catch (std::runtime_error &) { + exception_thrown = true; + } catch (...) { + UT_ASSERT(0); + } + + UT_ASSERTeq(nvobj::transaction::error(), ECANCELED); + UT_ASSERT(exception_thrown); + exception_thrown = false; + UT_ASSERT(rootp->pfoo == nullptr); + UT_ASSERT(rootp->parr == nullptr); + + try { + counter = 0; + T to(pop); + rootp->pfoo = nvobj::make_persistent(); + { + T to_nested(pop); + counter = 1; + throw std::runtime_error("error"); + } + } catch (std::runtime_error &) { + exception_thrown = true; + } catch (...) { + UT_ASSERT(0); + } + + UT_ASSERTeq(nvobj::transaction::error(), ECANCELED); + UT_ASSERT(exception_thrown); + exception_thrown = false; + UT_ASSERT(rootp->pfoo == nullptr); + UT_ASSERT(rootp->parr == nullptr); + + try { + counter = 0; + T to(pop); + rootp->pfoo = nvobj::make_persistent(); + try { + T to_nested(pop); + counter = 1; + throw std::runtime_error("error"); + } catch (std::runtime_error &) { + exception_thrown = true; + } catch (...) { + UT_ASSERT(0); + } + counter = 0; + UT_ASSERT(exception_thrown); + exception_thrown = false; + } catch (pmem::transaction_error &) { + exception_thrown = true; + } catch (...) { + UT_ASSERT(0); + } + + /* the transaction will be aborted silently */ + UT_ASSERTeq(nvobj::transaction::error(), ECANCELED); + if (std::is_same::value) + UT_ASSERT(exception_thrown); + else + UT_ASSERT(!exception_thrown); + UT_ASSERT(rootp->pfoo == nullptr); + UT_ASSERT(rootp->parr == nullptr); + + /* commiting non-existent transaction should fail with an exception */ + exception_thrown = false; + try { + nvobj::transaction::commit(); + } catch (pmem::transaction_error &te) { + exception_thrown = true; + } catch (...) { + UT_ASSERT(0); + } + UT_ASSERT(exception_thrown); + + if (test_shared_mutex_self_deadlock()) { + exception_thrown = false; + rootp->shared_mutex.lock(); + try { + T t(pop, rootp->shared_mutex); + } catch (pmem::transaction_error &) { + exception_thrown = true; + } catch (...) { + UT_ASSERT(0); + } + + UT_ASSERTeq(nvobj::transaction::error(), EINVAL); + UT_ASSERT(exception_thrown); + rootp->shared_mutex.unlock(); + } +} + +/* + * test_tx_no_throw_abort_scope -- test transaction with an abort + * and no exceptions + */ +template +void +test_tx_no_throw_abort_scope(nvobj::pool &pop) +{ + auto rootp = pop.root(); + + UT_ASSERT(rootp->pfoo == nullptr); + UT_ASSERT(rootp->parr == nullptr); + + bool exception_thrown = false; + try { + counter = 0; + T to(pop); + rootp->pfoo = nvobj::make_persistent(); + counter = 1; + nvobj::transaction::abort(ECANCELED); + } catch (pmem::manual_tx_abort &) { + exception_thrown = true; + } catch (...) { + UT_ASSERT(0); + } + + UT_ASSERTeq(nvobj::transaction::error(), ECANCELED); + UT_ASSERT(exception_thrown); + exception_thrown = false; + UT_ASSERT(rootp->pfoo == nullptr); + UT_ASSERT(rootp->parr == nullptr); + + try { + counter = 0; + T to(pop); + rootp->pfoo = nvobj::make_persistent(); + { + T to_nested(pop); + counter = 1; + nvobj::transaction::abort(EINVAL); + } + } catch (pmem::manual_tx_abort &) { + exception_thrown = true; + } catch (...) { + UT_ASSERT(0); + } + + UT_ASSERTeq(nvobj::transaction::error(), EINVAL); + UT_ASSERT(exception_thrown); + exception_thrown = false; + UT_ASSERT(rootp->pfoo == nullptr); + UT_ASSERT(rootp->parr == nullptr); + + try { + counter = 0; + T to(pop); + rootp->pfoo = nvobj::make_persistent(); + try { + T to_nested(pop); + counter = 1; + nvobj::transaction::abort(-1); + } catch (pmem::manual_tx_abort &) { + exception_thrown = true; + } catch (...) { + UT_ASSERT(0); + } + } catch (pmem::transaction_error &) { + exception_thrown = true; + } catch (...) { + UT_ASSERT(0); + } + + UT_ASSERTeq(nvobj::transaction::error(), -1); + UT_ASSERT(exception_thrown); + UT_ASSERT(rootp->pfoo == nullptr); + UT_ASSERT(rootp->parr == nullptr); +} + +/* + * test_tx_automatic_destructor_throw -- test transaction with a C tx_abort + * and no exceptions + */ +void +test_tx_automatic_destructor_throw(nvobj::pool &pop) +{ + auto rootp = pop.root(); + + UT_ASSERT(rootp->pfoo == nullptr); + UT_ASSERT(rootp->parr == nullptr); + + bool exception_thrown = false; + try { + nvobj::transaction::automatic to(pop); + rootp->pfoo = nvobj::make_persistent(); + pmemobj_tx_abort(ECANCELED); + } catch (pmem::transaction_error &) { + exception_thrown = true; + } catch (...) { + UT_ASSERT(0); + } + + UT_ASSERTeq(nvobj::transaction::error(), ECANCELED); + UT_ASSERT(exception_thrown); + UT_ASSERT(rootp->pfoo == nullptr); + UT_ASSERT(rootp->parr == nullptr); + + exception_thrown = false; + try { + nvobj::transaction::automatic to(pop); + rootp->pfoo = nvobj::make_persistent(); + pmemobj_tx_abort(ECANCELED); + pmemobj_tx_process(); /* move to finally */ + } catch (pmem::transaction_error &) { + exception_thrown = true; + } catch (...) { + UT_ASSERT(0); + } + + UT_ASSERTeq(nvobj::transaction::error(), ECANCELED); + UT_ASSERT(exception_thrown); + UT_ASSERT(rootp->pfoo == nullptr); + UT_ASSERT(rootp->parr == nullptr); + + exception_thrown = false; + try { + nvobj::transaction::automatic to(pop); + pmemobj_tx_commit(); + pmemobj_tx_process(); /* move to finally */ + } catch (pmem::transaction_error &) { + exception_thrown = true; + } catch (...) { + UT_ASSERT(0); + } + + UT_ASSERTeq(nvobj::transaction::error(), 0); + UT_ASSERT(!exception_thrown); + + counter = 0; + try { + nvobj::transaction::automatic to(pop); + rootp->pfoo = nvobj::make_persistent(); + try { + nvobj::transaction::automatic to_nested(pop); + pmemobj_tx_abort(-1); + } catch (pmem::transaction_error &) { + /*verify the exception only */ + counter = 1; + throw; + } catch (...) { + UT_ASSERT(0); + } + } catch (pmem::transaction_error &) { + exception_thrown = true; + } catch (...) { + UT_ASSERT(0); + } + + UT_ASSERTeq(nvobj::transaction::error(), -1); + UT_ASSERT(exception_thrown); + UT_ASSERT(rootp->pfoo == nullptr); + UT_ASSERT(rootp->parr == nullptr); + + try { + nvobj::transaction::automatic to(pop); + rootp->pfoo = nvobj::make_persistent(); + try { + nvobj::transaction::automatic to_nested(pop); + pmemobj_tx_abort(-1); + } catch (pmem::transaction_error &) { + /*verify the exception only */ + } catch (...) { + UT_ASSERT(0); + } + } catch (pmem::transaction_error &) { + exception_thrown = true; + } catch (...) { + UT_ASSERT(0); + } + + UT_ASSERTeq(nvobj::transaction::error(), -1); + UT_ASSERT(exception_thrown); + UT_ASSERT(rootp->pfoo == nullptr); + UT_ASSERT(rootp->parr == nullptr); + + try { + counter = 0; + nvobj::transaction::automatic to(pop); + rootp->pfoo = nvobj::make_persistent(); + try { + nvobj::transaction::automatic to_nested(pop); + counter = 1; + throw std::runtime_error("error"); + } catch (std::runtime_error &) { + exception_thrown = true; + counter = 0; + } catch (...) { + UT_ASSERT(0); + } + UT_ASSERT(exception_thrown); + exception_thrown = false; + } catch (pmem::transaction_error &) { + exception_thrown = true; + } catch (...) { + UT_ASSERT(0); + } + + /* the transaction will be aborted silently */ + UT_ASSERTeq(nvobj::transaction::error(), ECANCELED); + UT_ASSERT(exception_thrown); + UT_ASSERT(rootp->pfoo == nullptr); + UT_ASSERT(rootp->parr == nullptr); +} + +/* + * test_tx_snapshot -- 1) Check if transaction_error is thrown, when snapshot() + * is not called from transaction. + * 2) Check if transaction_error is thrown, when internal call to + * pmemobj_tx_add_range_direct() failed. + * 3) Check if assigning value to pmem object is valid under pmemcheck when + * object was snapshotted beforehand. + * 4) Check if snapshotted value was rolled back in case of transacion abort. + */ +void +test_tx_snapshot(nvobj::pool &pop) +{ + nvobj::persistent_ptr parr; + try { + nvobj::make_persistent_atomic(pop, parr, 5); + } catch (...) { + UT_ASSERT(0); + } + + bool exception_thrown = false; + try { + nvobj::transaction::snapshot(parr.get(), 5); + UT_ASSERT(0); + } catch (pmem::transaction_error &) { + exception_thrown = true; + } catch (...) { + UT_ASSERT(0); + } + UT_ASSERT(exception_thrown); + + exception_thrown = false; + try { + nvobj::transaction::run(pop, [&] { + nvobj::transaction::snapshot(parr.get(), + POOL_SZIE); + }); + UT_ASSERT(0); + } catch (pmem::transaction_error &) { + exception_thrown = true; + } catch (...) { + UT_ASSERT(0); + } + UT_ASSERT(exception_thrown); + + try { + nvobj::transaction::run(pop, [&] { + nvobj::transaction::snapshot(parr.get(), 5); + for (int i = 0; i < 5; ++i) + parr[i] = 1; /* no pmemcheck errors */ + }); + } catch (...) { + UT_ASSERT(0); + } + + try { + nvobj::transaction::run(pop, [&] { + nvobj::transaction::snapshot(parr.get(), 5); + for (int i = 0; i < 5; ++i) + parr[i] = 2; + nvobj::transaction::abort(-1); + }); + UT_ASSERT(0); + } catch (pmem::manual_tx_abort &) { + for (int i = 0; i < 5; ++i) + UT_ASSERT(parr[i] == 1); /* check rolled back values */ + } catch (...) { + UT_ASSERT(0); + } +} +} + +int +main(int argc, char *argv[]) +{ + START(); + + if (argc != 2) + UT_FATAL("usage: %s file-name", argv[0]); + + const char *path = argv[1]; + + nvobj::pool pop; + try { + pop = nvobj::pool::create(path, LAYOUT, POOL_SZIE, + S_IWUSR | S_IRUSR); + } catch (...) { + UT_FATAL("!pmemobj_create: %s", path); + } + + test_tx_no_throw_no_abort(pop); + test_tx_throw_no_abort(pop); + test_tx_no_throw_abort(pop); + + test_tx_no_throw_no_abort_scope( + pop, real_commit); + test_tx_throw_no_abort_scope(pop); + test_tx_no_throw_abort_scope(pop); + + test_tx_no_throw_no_abort_scope( + pop, fake_commit); + test_tx_throw_no_abort_scope(pop); + test_tx_no_throw_abort_scope(pop); + test_tx_automatic_destructor_throw(pop); + + test_tx_snapshot(pop); + + pop.close(); + + return 0; +} diff --git a/tests/true.cmake b/tests/true.cmake new file mode 100644 index 0000000..5963535 --- /dev/null +++ b/tests/true.cmake @@ -0,0 +1,34 @@ +# +# Copyright 2018, Intel Corporation +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# +# * Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# +# * Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in +# the documentation and/or other materials provided with the +# distribution. +# +# * Neither the name of the copyright holder nor the names of its +# contributors may be used to endorse or promote products derived +# from this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +# true.cmake - cmake script which always succeeds + +return() diff --git a/tests/v/v.cpp b/tests/v/v.cpp new file mode 100644 index 0000000..f3ef613 --- /dev/null +++ b/tests/v/v.cpp @@ -0,0 +1,268 @@ +/* + * Copyright 2018-2019, Intel Corporation + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * * Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +/* + * obj_cpp_v.c -- cpp bindings test + * + */ + +#include "unittest.hpp" + +#include +#include +#include +#include +#include +#include +#include + +#define LAYOUT "cpp" + +namespace nvobj = pmem::obj; +namespace nvobj_exp = pmem::obj::experimental; + +namespace +{ + +static const int TEST_VALUE = 10; + +struct emplace_constructible { + emplace_constructible() + { + } + + emplace_constructible(int &a, int &b, int &&c) + : a(a), b(b), c(std::move(c)) + { + } + + int a, b, c; +}; + +struct work_in_destructor { + static int destructor_called; + + work_in_destructor() + { + a = TEST_VALUE; + } + + ~work_in_destructor() + { + destructor_called = 1; + } + + int a; +}; + +int work_in_destructor::destructor_called = 0; + +struct foo { + foo() : counter(TEST_VALUE){}; + int counter; +}; + +struct bar { + nvobj_exp::v vfoo; + + nvobj_exp::v vi; + nvobj_exp::v vi2; + nvobj_exp::v vc; + nvobj_exp::v ndc; + + bar() + { + } +}; + +struct root { + nvobj_exp::v f; + nvobj::persistent_ptr bar_ptr; + nvobj::persistent_ptr> work_ptr; +}; + +/* + * test_init -- test volatile value initialization + */ +void +test_init(nvobj::pool &pop) +{ + UT_ASSERTeq(pop.root()->f.get().counter, TEST_VALUE); + UT_ASSERTeq(pop.root()->bar_ptr->vfoo.get().counter, TEST_VALUE); +} + +/* + * test_conversion -- test v conversion operator + */ +void +test_conversion(nvobj::pool &pop) +{ + auto r = pop.root()->bar_ptr; + + r->vi = 2; + r->vc = 2; + + UT_ASSERT(r->vi == r->vc); + UT_ASSERT(r->vi == 2); + UT_ASSERT(2 == r->vi); + UT_ASSERT(r->vi - 2 == 0); + + int &i1 = r->vi; + char &i2 = r->vc; + + UT_ASSERT(i1 == i2); + i1 = 1; + + UT_ASSERT(r->vi == i1); +} + +/* + * test_operators -- test v assignment operators + */ +void +test_operators(nvobj::pool &pop) +{ + auto r = pop.root()->bar_ptr; + + r->vi = 2; + r->vc = 3; + + UT_ASSERT(r->vi != r->vc); + r->vi = r->vc; + UT_ASSERT(r->vi == r->vc); + + r->vi = 2; + r->vi2 = 3; + std::swap(r->vi, r->vi2); + UT_ASSERT(r->vi == 3); + UT_ASSERT(r->vi2 == 2); + + r->vi2 = 2; + r->vi = r->vi2; + UT_ASSERT(r->vi == 2); +} + +/* + * test_variadic_get -- test v get with arguments + */ +void +test_variadic_get(nvobj::pool &pop) +{ + auto r = pop.root()->bar_ptr; + + int a = 1, b = 2; + auto &ref = r->ndc.get(a, b, 3); + UT_ASSERT(ref.a == 1); + UT_ASSERT(ref.b == 2); + UT_ASSERT(ref.c == 3); + + auto &ref2 = r->ndc.unsafe_get(); + UT_ASSERT(&ref == &ref2); + UT_ASSERT(ref2.a == 1); + UT_ASSERT(ref2.b == 2); + UT_ASSERT(ref2.c == 3); +} + +/* + * test_destructor -- test v destructor + */ +void +test_destructor(nvobj::pool &pop) +{ + auto r = pop.root(); + + try { + nvobj::transaction::run(pop, [&] { + r->work_ptr = nvobj::make_persistent< + nvobj_exp::v>(); + }); + } catch (std::exception &e) { + UT_FATALexc(e); + } + + UT_ASSERT(r->work_ptr->get().a == TEST_VALUE); + UT_ASSERT(work_in_destructor::destructor_called == 0); + + try { + nvobj::transaction::run(pop, [&] { + nvobj::delete_persistent< + nvobj_exp::v>(r->work_ptr); + }); + } catch (std::exception &e) { + UT_FATALexc(e); + } + + /* destructor should not be called */ + UT_ASSERT(work_in_destructor::destructor_called == 0); +} +} + +int +main(int argc, char *argv[]) +{ + START(); + + if (argc != 2) + UT_FATAL("usage: %s file-name", argv[0]); + + const char *path = argv[1]; + + nvobj::pool pop; + + try { + pop = nvobj::pool::create( + path, LAYOUT, PMEMOBJ_MIN_POOL, S_IWUSR | S_IRUSR); + } catch (pmem::pool_error &pe) { + UT_FATAL("!pool::create: %s %s", pe.what(), path); + } + + nvobj::make_persistent_atomic(pop, pop.root()->bar_ptr); + + test_init(pop); + + pop.root()->f.get().counter = 20; + UT_ASSERTeq(pop.root()->f.get().counter, 20); + + pop.close(); + + pop = nvobj::pool::open(path, LAYOUT); + + test_init(pop); + test_conversion(pop); + test_operators(pop); + test_variadic_get(pop); + test_destructor(pop); + + pop.close(); + + return 0; +} diff --git a/tests/v/v_0.cmake b/tests/v/v_0.cmake new file mode 100644 index 0000000..b04bb69 --- /dev/null +++ b/tests/v/v_0.cmake @@ -0,0 +1,40 @@ +# +# Copyright 2018, Intel Corporation +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# +# * Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# +# * Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in +# the documentation and/or other materials provided with the +# distribution. +# +# * Neither the name of the copyright holder nor the names of its +# contributors may be used to endorse or promote products derived +# from this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +include(${SRC_DIR}/../helpers.cmake) + +setup() + +execute(${TEST_EXECUTABLE} ${DIR}/testfile) + +check_file_exists(${DIR}/testfile) + +finish() diff --git a/tests/valgrind_internal.cpp b/tests/valgrind_internal.cpp new file mode 100644 index 0000000..69be909 --- /dev/null +++ b/tests/valgrind_internal.cpp @@ -0,0 +1,59 @@ +/* + * Copyright 2019, Intel Corporation + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * * Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "valgrind_internal.hpp" +#include + +unsigned On_valgrind = 0; +unsigned On_pmemcheck = 0; +unsigned On_memcheck = 0; +unsigned On_helgrind = 0; +unsigned On_drd = 0; + +void +set_valgrind_internals(void) +{ +#if LIBPMEMOBJ_CPP_ANY_VG_TOOL_ENABLED + On_valgrind = RUNNING_ON_VALGRIND; + + if (On_valgrind) { + if (getenv("LIBPMEMOBJ_CPP_TRACER_PMEMCHECK")) + On_pmemcheck = 1; + else if (getenv("LIBPMEMOBJ_CPP_TRACER_MEMCHECK")) + On_memcheck = 1; + else if (getenv("LIBPMEMOBJ_CPP_TRACER_HELGRIND")) + On_helgrind = 1; + else if (getenv("LIBPMEMOBJ_CPP_TRACER_DRD")) + On_drd = 1; + } +#endif /* LIBPMEMOBJ_CPP_ANY_VG_TOOL_ENABLED */ +} diff --git a/tests/valgrind_internal.hpp b/tests/valgrind_internal.hpp new file mode 100644 index 0000000..4359362 --- /dev/null +++ b/tests/valgrind_internal.hpp @@ -0,0 +1,86 @@ +/* + * Copyright 2019, Intel Corporation + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * * Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef VALGRIND_INTERNAL_HPP +#define VALGRIND_INTERNAL_HPP + +extern unsigned On_valgrind; +extern unsigned On_pmemcheck; +extern unsigned On_memcheck; +extern unsigned On_helgrind; +extern unsigned On_drd; + +#if LIBPMEMOBJ_CPP_VG_PMEMCHECK_ENABLED + +#define VALGRIND_ADD_TO_TX(addr, len) \ + do { \ + if (On_pmemcheck) \ + VALGRIND_PMC_ADD_TO_TX(addr, len); \ + } while (0) + +#define VALGRIND_SET_CLEAN(addr, len) \ + do { \ + if (On_pmemcheck) \ + VALGRIND_PMC_SET_CLEAN(addr, len); \ + } while (0) + +#define VALGRIND_REMOVE_FROM_TX(addr, len) \ + do { \ + if (On_pmemcheck) \ + VALGRIND_PMC_REMOVE_FROM_TX(addr, len); \ + } while (0) + +#else + +#define VALGRIND_ADD_TO_TX(addr, len) \ + do { \ + (void)(addr); \ + (void)(len); \ + } while (0) + +#define VALGRIND_SET_CLEAN(addr, len) \ + do { \ + (void)(addr); \ + (void)(len); \ + } while (0) + +#define VALGRIND_REMOVE_FROM_TX(addr, len) \ + do { \ + (void)(addr); \ + (void)(len); \ + } while (0) + +#endif /* LIBPMEMOBJ_CPP_VG_PMEMCHECK_ENABLED */ + +void set_valgrind_internals(void); + +#endif /* VALGRIND_INTERNAL_HPP */ diff --git a/tests/vector_assign_exceptions_length/vector_assign_exceptions_length.cpp b/tests/vector_assign_exceptions_length/vector_assign_exceptions_length.cpp new file mode 100644 index 0000000..a36fc72 --- /dev/null +++ b/tests/vector_assign_exceptions_length/vector_assign_exceptions_length.cpp @@ -0,0 +1,148 @@ +/* + * Copyright 2019, Intel Corporation + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * * Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "unittest.hpp" + +#include +#include + +#include + +namespace nvobj = pmem::obj; +namespace pmem_exp = nvobj::experimental; + +using C = pmem_exp::vector; + +struct root { + nvobj::persistent_ptr v; +}; + +void +check_vector(nvobj::pool &pop, size_t count, int value) +{ + auto r = pop.root(); + + UT_ASSERT(r->v->capacity() == count); + UT_ASSERT(r->v->size() == count); + + for (unsigned i = 0; i < count; ++i) { + UT_ASSERT((*r->v)[i] == value); + } +} + +/** + * Test pmem::obj::experimental::vector assign() methods + * + * Replace content of the vector with content greater than max_size() + * Expect std::length_error exception is thrown + * Methods under test: + * - fill version of assign() + * - range version of assign() + */ +void +test(nvobj::pool &pop) +{ + auto r = pop.root(); + + check_vector(pop, 10, 1); + + auto size = r->v->max_size() + 1; + + /* assign() - fill version */ + bool exception_thrown = false; + + try { + r->v->assign(size, 2); + UT_ASSERT(0); + } catch (std::length_error &) { + exception_thrown = true; + } catch (std::exception &e) { + UT_FATALexc(e); + } + + UT_ASSERT(exception_thrown); + check_vector(pop, 10, 1); + + /* assign() - range version */ + int a[] = {1}; + auto begin = std::begin(a); + /* we won't try to dereference this, it will be used for std::distance() + * calculation only */ + auto end = begin + size; + + exception_thrown = false; + + try { + r->v->assign(begin, end); + UT_ASSERT(0); + } catch (std::length_error &) { + exception_thrown = true; + } catch (std::exception &e) { + UT_FATALexc(e); + } + + UT_ASSERT(exception_thrown); + check_vector(pop, 10, 1); +} + +int +main(int argc, char *argv[]) +{ + START(); + + if (argc < 2) { + std::cerr << "usage: " << argv[0] << " file-name" << std::endl; + return 1; + } + auto path = argv[1]; + auto pop = nvobj::pool::create( + path, "VectorTest: vector_assign_exceptions_length", + PMEMOBJ_MIN_POOL, S_IWUSR | S_IRUSR); + + auto r = pop.root(); + + try { + nvobj::transaction::run( + pop, [&] { r->v = nvobj::make_persistent(10U, 1); }); + + test(pop); + + nvobj::transaction::run( + pop, [&] { nvobj::delete_persistent(r->v); }); + } catch (std::exception &e) { + UT_FATALexc(e); + } + + pop.close(); + + return 0; +} diff --git a/tests/vector_assign_exceptions_oom/vector_assign_exceptions_oom.cpp b/tests/vector_assign_exceptions_oom/vector_assign_exceptions_oom.cpp new file mode 100644 index 0000000..29fb46d --- /dev/null +++ b/tests/vector_assign_exceptions_oom/vector_assign_exceptions_oom.cpp @@ -0,0 +1,146 @@ +/* + * Copyright 2019, Intel Corporation + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * * Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "unittest.hpp" + +#include +#include + +#include + +namespace nvobj = pmem::obj; +namespace pmem_exp = nvobj::experimental; + +using C = pmem_exp::vector; + +struct root { + nvobj::persistent_ptr v; +}; + +void +check_vector(nvobj::pool &pop, size_t count, int value) +{ + auto r = pop.root(); + + UT_ASSERT(r->v->capacity() == count); + UT_ASSERT(r->v->size() == count); + + for (unsigned i = 0; i < count; ++i) { + UT_ASSERT((*r->v)[i] == value); + } +} + +/** + * Test pmem::obj::experimental::vector assign() method + * + * Replace content of the vector with content greater than pool size + * Expect pmem::transaction_allor_error exception is thrown + * Methods under test: + * - fill version of assign() + * - range version of assign() + */ +void +test(nvobj::pool &pop, size_t pool_size) +{ + auto r = pop.root(); + + check_vector(pop, 10, 1); + + bool exception_thrown = false; + + auto size = pool_size / sizeof(int); + + /* assign() - fill version */ + try { + r->v->assign(size, 2); + UT_ASSERT(0); + } catch (pmem::transaction_alloc_error &) { + exception_thrown = true; + } catch (std::exception &e) { + UT_FATALexc(e); + } + + UT_ASSERT(exception_thrown); + check_vector(pop, 10, 1); + + /* assign() - range version */ + std::vector v2(size); + + exception_thrown = false; + + try { + r->v->assign(v2.begin(), v2.end()); + UT_ASSERT(0); + } catch (pmem::transaction_alloc_error &) { + exception_thrown = true; + } catch (std::exception &e) { + UT_FATALexc(e); + } + + UT_ASSERT(exception_thrown); + check_vector(pop, 10, 1); +} + +int +main(int argc, char *argv[]) +{ + START(); + + if (argc < 2) { + std::cerr << "usage: " << argv[0] << " file-name" << std::endl; + return 1; + } + + auto path = argv[1]; + const auto pool_size = PMEMOBJ_MIN_POOL; + auto pop = nvobj::pool::create( + path, "VectorTest: vector_assign_exceptions_oom", pool_size, + S_IWUSR | S_IRUSR); + + auto r = pop.root(); + + try { + nvobj::transaction::run( + pop, [&] { r->v = nvobj::make_persistent(10U, 1); }); + + test(pop, pool_size); + + nvobj::transaction::run( + pop, [&] { nvobj::delete_persistent(r->v); }); + } catch (std::exception &e) { + UT_FATALexc(e); + } + + pop.close(); + + return 0; +} diff --git a/tests/vector_assign_txabort/vector_assign_txabort.cpp b/tests/vector_assign_txabort/vector_assign_txabort.cpp new file mode 100644 index 0000000..a72d88e --- /dev/null +++ b/tests/vector_assign_txabort/vector_assign_txabort.cpp @@ -0,0 +1,258 @@ +/* + * Copyright 2019, Intel Corporation + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * * Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "unittest.hpp" + +#include +#include + +#include + +namespace nvobj = pmem::obj; +namespace pmem_exp = nvobj::experimental; +using C = pmem_exp::vector; + +struct root { + nvobj::persistent_ptr v; +}; + +void +check_vector(nvobj::pool &pop, size_t count, int value) +{ + auto r = pop.root(); + + UT_ASSERTeq(r->v->size(), count); + + for (unsigned i = 0; i < count; ++i) { + UT_ASSERTeq((*r->v)[i], value); + } +} + +/** + * Test pmem::obj::experimental::vector assign() methods + * + * Checks if vector's state is reverted when transaction aborts. + * Methods under test: + * - fill version of assign() + * - range version of assign() + * - initializer list version of assign() + * - copy assignment operator + * - move assignment operator + * - initializer list assignment operator + */ +void +test(nvobj::pool &pop) +{ + auto r = pop.root(); + + check_vector(pop, 10, 1); + + /* assign() - fill version */ + bool exception_thrown = false; + try { + nvobj::transaction::run(pop, [&] { + r->v->assign(100, 2); + check_vector(pop, 100, 2); + nvobj::transaction::abort(EINVAL); + }); + } catch (pmem::manual_tx_abort &) { + exception_thrown = true; + } catch (std::exception &e) { + UT_FATALexc(e); + } + + UT_ASSERT(exception_thrown); + check_vector(pop, 10, 1); + + /* assign() - range version */ + exception_thrown = false; + std::vector v2(100, 2); + try { + nvobj::transaction::run(pop, [&] { + r->v->assign(v2.begin(), v2.end()); + check_vector(pop, 100, 2); + nvobj::transaction::abort(EINVAL); + }); + } catch (pmem::manual_tx_abort &) { + exception_thrown = true; + } catch (std::exception &e) { + UT_FATALexc(e); + } + UT_ASSERT(exception_thrown); + check_vector(pop, 10, 1); + + /* assign() - initializer list version */ + exception_thrown = false; + try { + nvobj::transaction::run(pop, [&] { + r->v->assign({2, 2, 2, 2, 2}); + check_vector(pop, 5, 2); + nvobj::transaction::abort(EINVAL); + }); + } catch (pmem::manual_tx_abort &) { + exception_thrown = true; + } catch (std::exception &e) { + UT_FATALexc(e); + } + UT_ASSERT(exception_thrown); + check_vector(pop, 10, 1); + + /* assign() - copy version */ + exception_thrown = false; + try { + nvobj::transaction::run(pop, [&] { + nvobj::persistent_ptr v2 = + nvobj::make_persistent(100U, 2); + r->v->assign(*v2); + check_vector(pop, 100, 2); + nvobj::delete_persistent(v2); + nvobj::transaction::abort(EINVAL); + }); + } catch (pmem::manual_tx_abort &) { + exception_thrown = true; + } catch (std::exception &e) { + UT_FATALexc(e); + } + UT_ASSERT(exception_thrown); + check_vector(pop, 10, 1); + + /* assign() - move version */ + exception_thrown = false; + try { + nvobj::transaction::run(pop, [&] { + nvobj::persistent_ptr v2 = + nvobj::make_persistent(100U, 2); + r->v->assign(std::move(*v2)); + check_vector(pop, 100, 2); + UT_ASSERT(v2->empty()); + nvobj::delete_persistent(v2); + nvobj::transaction::abort(EINVAL); + }); + } catch (pmem::manual_tx_abort &) { + exception_thrown = true; + } catch (std::exception &e) { + UT_FATALexc(e); + } + UT_ASSERT(exception_thrown); + check_vector(pop, 10, 1); + + /* copy assignment operator */ + exception_thrown = false; + try { + nvobj::transaction::run(pop, [&] { + nvobj::persistent_ptr v2 = + nvobj::make_persistent(100U, 2); + *r->v = *v2; + check_vector(pop, 100, 2); + nvobj::delete_persistent(v2); + nvobj::transaction::abort(EINVAL); + }); + } catch (pmem::manual_tx_abort &) { + exception_thrown = true; + } catch (std::exception &e) { + UT_FATALexc(e); + } + UT_ASSERT(exception_thrown); + check_vector(pop, 10, 1); + + /* move assignment operator */ + exception_thrown = false; + try { + nvobj::transaction::run(pop, [&] { + nvobj::persistent_ptr v2 = + nvobj::make_persistent(100U, 2); + *r->v = std::move(*v2); + check_vector(pop, 100, 2); + UT_ASSERT(v2->empty()); + nvobj::delete_persistent(v2); + nvobj::transaction::abort(EINVAL); + }); + } catch (pmem::manual_tx_abort &) { + exception_thrown = true; + } catch (std::exception &e) { + UT_FATALexc(e); + } + UT_ASSERT(exception_thrown); + check_vector(pop, 10, 1); + + /* initializer list assignment operator */ + exception_thrown = false; + try { + nvobj::transaction::run(pop, [&] { + nvobj::persistent_ptr v2 = + nvobj::make_persistent(100U, 2); + *r->v = {2, 2, 2, 2, 2}; + check_vector(pop, 5, 2); + nvobj::delete_persistent(v2); + nvobj::transaction::abort(EINVAL); + }); + } catch (pmem::manual_tx_abort &) { + exception_thrown = true; + } catch (std::exception &e) { + UT_FATALexc(e); + } + UT_ASSERT(exception_thrown); + check_vector(pop, 10, 1); +} + +int +main(int argc, char *argv[]) +{ + START(); + + if (argc < 2) { + std::cerr << "usage: " << argv[0] << " file-name" << std::endl; + return 1; + } + auto path = argv[1]; + auto pop = + nvobj::pool::create(path, "VectorTest: assign_txabort", + PMEMOBJ_MIN_POOL, S_IWUSR | S_IRUSR); + + auto r = pop.root(); + + try { + nvobj::transaction::run( + pop, [&] { r->v = nvobj::make_persistent(10U, 1); }); + + test(pop); + + nvobj::transaction::run( + pop, [&] { nvobj::delete_persistent(r->v); }); + } catch (std::exception &e) { + UT_FATALexc(e); + } + + pop.close(); + + return 0; +} diff --git a/tests/vector_capacity_exceptions_length/vector_capacity_exceptions_length.cpp b/tests/vector_capacity_exceptions_length/vector_capacity_exceptions_length.cpp new file mode 100644 index 0000000..b7dbda4 --- /dev/null +++ b/tests/vector_capacity_exceptions_length/vector_capacity_exceptions_length.cpp @@ -0,0 +1,106 @@ +/* + * Copyright 2019, Intel Corporation + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * * Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "unittest.hpp" + +#include +#include + +namespace nvobj = pmem::obj; +namespace pmem_exp = nvobj::experimental; +using C = pmem_exp::vector; + +struct root { + nvobj::persistent_ptr v; +}; + +/** + * Test pmem::obj::experimental::vector reserve() method + * + * Increase capacity of the vector to value greater than max_size() + * Expect std::length_error exception is thrown + */ +void +test(nvobj::pool &pop) +{ + auto r = pop.root(); + + UT_ASSERT(r->v->capacity() == 100); + + auto size = r->v->max_size() + 1; + + bool exception_thrown = false; + try { + r->v->reserve(size); + UT_ASSERT(0); + } catch (std::length_error &) { + exception_thrown = true; + } catch (std::exception &e) { + UT_FATALexc(e); + } + UT_ASSERT(exception_thrown); + + UT_ASSERT(r->v->capacity() == 100); +} + +int +main(int argc, char *argv[]) +{ + START(); + + if (argc < 2) { + std::cerr << "usage: " << argv[0] << " file-name" << std::endl; + return 1; + } + auto path = argv[1]; + auto pop = nvobj::pool::create( + path, "VectorTest: vector_capacity_exceptions_length", + PMEMOBJ_MIN_POOL, S_IWUSR | S_IRUSR); + + auto r = pop.root(); + + try { + nvobj::transaction::run( + pop, [&] { r->v = nvobj::make_persistent(100U); }); + + test(pop); + + nvobj::transaction::run( + pop, [&] { nvobj::delete_persistent(r->v); }); + } catch (std::exception &e) { + UT_FATALexc(e); + } + + pop.close(); + + return 0; +} diff --git a/tests/vector_capacity_exceptions_oom/vector_capacity_exceptions_oom.cpp b/tests/vector_capacity_exceptions_oom/vector_capacity_exceptions_oom.cpp new file mode 100644 index 0000000..5a2c0f7 --- /dev/null +++ b/tests/vector_capacity_exceptions_oom/vector_capacity_exceptions_oom.cpp @@ -0,0 +1,111 @@ +/* + * Copyright 2019, Intel Corporation + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * * Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "unittest.hpp" + +#include +#include + +#include + +namespace nvobj = pmem::obj; +namespace pmem_exp = nvobj::experimental; + +using C = pmem_exp::vector; + +struct root { + nvobj::persistent_ptr v; +}; + +/** + * Test pmem::obj::experimental::vector reserve() method + * + * Increase capacity of the vector to value greater than pool size + * Expect pmem::transaction_allor_error exception is thrown + */ +void +test(nvobj::pool &pop) +{ + auto r = pop.root(); + + UT_ASSERT(r->v->capacity() == 100); + + bool exception_thrown = false; + + auto size = r->v->max_size(); + + try { + r->v->reserve(size); + UT_ASSERT(0); + } catch (pmem::transaction_alloc_error &) { + exception_thrown = true; + } catch (std::exception &e) { + UT_FATALexc(e); + } + + UT_ASSERT(exception_thrown); + UT_ASSERT(r->v->capacity() == 100); +} + +int +main(int argc, char *argv[]) +{ + START(); + + if (argc < 2) { + std::cerr << "usage: " << argv[0] << " file-name" << std::endl; + return 1; + } + + auto path = argv[1]; + auto pop = nvobj::pool::create( + path, "VectorTest: vector_capacity_exceptions_oom", + PMEMOBJ_MIN_POOL, S_IWUSR | S_IRUSR); + + auto r = pop.root(); + + try { + nvobj::transaction::run( + pop, [&] { r->v = nvobj::make_persistent(100U); }); + + test(pop); + + nvobj::transaction::run( + pop, [&] { nvobj::delete_persistent(r->v); }); + } catch (std::exception &e) { + UT_FATALexc(e); + } + + pop.close(); + + return 0; +} diff --git a/tests/vector_capacity_txabort/vector_capacity_txabort.cpp b/tests/vector_capacity_txabort/vector_capacity_txabort.cpp new file mode 100644 index 0000000..11f6672 --- /dev/null +++ b/tests/vector_capacity_txabort/vector_capacity_txabort.cpp @@ -0,0 +1,137 @@ +/* + * Copyright 2019, Intel Corporation + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * * Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "unittest.hpp" + +#include +#include + +namespace nvobj = pmem::obj; +namespace pmem_exp = nvobj::experimental; +using C = pmem_exp::vector; + +struct root { + nvobj::persistent_ptr v; +}; + +/** + * Test pmem::obj::experimental::vector capacity methods + * + * Checks if vector's state is reverted when transaction aborts. + * Methods under test: + * - reserve() + * - shrink_to_fit() + */ +void +test(nvobj::pool &pop) +{ + auto r = pop.root(); + + UT_ASSERT(r->v->capacity() == 100); + + bool exception_thrown = false; + + /* test reserve() revert */ + try { + nvobj::transaction::run(pop, [&] { + r->v->reserve(150); + UT_ASSERT(r->v->capacity() == 150); + nvobj::transaction::abort(EINVAL); + }); + } catch (pmem::manual_tx_abort &) { + exception_thrown = true; + } catch (std::exception &e) { + UT_FATALexc(e); + } + + UT_ASSERT(r->v->capacity() == 100); + UT_ASSERT(r->v->size() == 100); + for (unsigned i = 0; i < r->v->size(); ++i) + UT_ASSERT(r->v->const_at(i) == 0); + UT_ASSERT(exception_thrown); + + /* test shrink_to_fit() revert */ + try { + r->v->reserve(150); + UT_ASSERT(r->v->capacity() == 150); + + nvobj::transaction::run(pop, [&] { + r->v->shrink_to_fit(); + UT_ASSERT(r->v->capacity() == 100); + nvobj::transaction::abort(EINVAL); + }); + } catch (pmem::manual_tx_abort &) { + exception_thrown = true; + } catch (std::exception &e) { + UT_FATALexc(e); + } + + UT_ASSERT(r->v->capacity() == 150); + UT_ASSERT(r->v->size() == 100); + for (unsigned i = 0; i < r->v->size(); ++i) + UT_ASSERT(r->v->const_at(i) == 0); + UT_ASSERT(exception_thrown); +} + +int +main(int argc, char *argv[]) +{ + START(); + + if (argc < 2) { + std::cerr << "usage: " << argv[0] << " file-name" << std::endl; + return 1; + } + + auto path = argv[1]; + auto pop = + nvobj::pool::create(path, "VectorTest: capacity_txabort", + PMEMOBJ_MIN_POOL, S_IWUSR | S_IRUSR); + + auto r = pop.root(); + + try { + nvobj::transaction::run( + pop, [&] { r->v = nvobj::make_persistent(100U); }); + + test(pop); + + nvobj::transaction::run( + pop, [&] { nvobj::delete_persistent(r->v); }); + } catch (std::exception &e) { + UT_FATALexc(e); + } + + pop.close(); + + return 0; +} diff --git a/tests/vector_comp_operators/vector_comp_operators.cpp b/tests/vector_comp_operators/vector_comp_operators.cpp new file mode 100644 index 0000000..c171e62 --- /dev/null +++ b/tests/vector_comp_operators/vector_comp_operators.cpp @@ -0,0 +1,148 @@ +/* + * Copyright 2018-2019, Intel Corporation + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * * Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "unittest.hpp" + +#include +#include + +#include + +namespace nvobj = pmem::obj; +namespace pmem_exp = nvobj::experimental; +using vector_type = pmem_exp::vector; + +struct root { + nvobj::persistent_ptr v1; + nvobj::persistent_ptr v2; + nvobj::persistent_ptr v3; +}; + +/** + * Test pmem::obj::experimental::vector comparison operators. + * + * Compares elements in two vector containers using following operators: + * ==, !=, <, <=, >, >=. + */ +void +test_comp_operators(nvobj::pool &pop) +{ + auto r = pop.root(); + + int arr1[] = {0, 1, 2, 3, 4}; + int arr2[] = {0, 1, 2, 3, 4, 5}; + + std::vector stdvec1(std::begin(arr1), std::end(arr1)); + std::vector stdvec2(std::begin(arr2), std::end(arr2)); + std::vector stdvec3(std::begin(arr2) + 1, std::end(arr2)); + + try { + nvobj::transaction::run(pop, [&] { + r->v1 = nvobj::make_persistent( + std::begin(arr1), std::end(arr1)); + r->v2 = nvobj::make_persistent( + std::begin(arr2), std::end(arr2)); + r->v3 = nvobj::make_persistent( + std::begin(arr2) + 1, std::end(arr2)); + }); + } catch (std::exception &e) { + UT_FATALexc(e); + } + + UT_ASSERT(*(r->v1) == *(r->v1)); + UT_ASSERT(*(r->v1) != *(r->v2)); + UT_ASSERT(*(r->v1) != *(r->v3)); + UT_ASSERT(*(r->v1) < *(r->v2)); + UT_ASSERT(*(r->v1) <= *(r->v2)); + UT_ASSERT(*(r->v1) <= *(r->v1)); + UT_ASSERT(*(r->v1) < *(r->v3)); + UT_ASSERT(*(r->v2) > *(r->v1)); + UT_ASSERT(*(r->v2) >= *(r->v1)); + UT_ASSERT(*(r->v2) >= *(r->v2)); + UT_ASSERT(*(r->v3) > *(r->v1)); + + UT_ASSERT(*(r->v1) == stdvec1); + UT_ASSERT(*(r->v1) != stdvec2); + UT_ASSERT(*(r->v1) != stdvec3); + UT_ASSERT(*(r->v1) < stdvec2); + UT_ASSERT(*(r->v1) <= stdvec2); + UT_ASSERT(*(r->v1) <= stdvec1); + UT_ASSERT(*(r->v1) < stdvec3); + UT_ASSERT(*(r->v2) > stdvec1); + UT_ASSERT(*(r->v2) >= stdvec1); + UT_ASSERT(*(r->v2) >= stdvec2); + UT_ASSERT(*(r->v3) > stdvec1); + + UT_ASSERT(stdvec1 == *(r->v1)); + UT_ASSERT(stdvec1 != *(r->v2)); + UT_ASSERT(stdvec1 != *(r->v3)); + UT_ASSERT(stdvec1 < *(r->v2)); + UT_ASSERT(stdvec1 <= *(r->v2)); + UT_ASSERT(stdvec1 <= *(r->v1)); + UT_ASSERT(stdvec1 < *(r->v3)); + UT_ASSERT(stdvec2 > *(r->v1)); + UT_ASSERT(stdvec2 >= *(r->v1)); + UT_ASSERT(stdvec2 >= *(r->v2)); + UT_ASSERT(stdvec3 > *(r->v1)); + + try { + nvobj::transaction::run(pop, [&] { + nvobj::delete_persistent(r->v1); + nvobj::delete_persistent(r->v2); + nvobj::delete_persistent(r->v3); + }); + } catch (std::exception &e) { + UT_FATALexc(e); + } +} + +int +main(int argc, char *argv[]) +{ + START(); + + if (argc < 2) { + std::cerr << "usage: " << argv[0] << " file-name" << std::endl; + return 1; + } + + auto path = argv[1]; + auto pop = + nvobj::pool::create(path, "VectorTest: comp_operators", + PMEMOBJ_MIN_POOL, S_IWUSR | S_IRUSR); + + test_comp_operators(pop); + + pop.close(); + + return 0; +} diff --git a/tests/vector_ctor_capacity/vector_ctor_capacity.cpp b/tests/vector_ctor_capacity/vector_ctor_capacity.cpp new file mode 100644 index 0000000..1ca8fab --- /dev/null +++ b/tests/vector_ctor_capacity/vector_ctor_capacity.cpp @@ -0,0 +1,107 @@ +/* + * Copyright 2019, Intel Corporation + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * * Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "unittest.hpp" + +#include +#include +#include + +namespace nvobj = pmem::obj; +namespace pmem_exp = nvobj::experimental; + +const static size_t pool_size = PMEMOBJ_MIN_POOL; +const static size_t test_val1 = 123U; + +using vector_type = pmem_exp::vector; + +struct root { + nvobj::persistent_ptr pptr1; + nvobj::persistent_ptr pptr2; +}; + +int +main(int argc, char *argv[]) +{ + START(); + + if (argc < 2) { + std::cerr << "usage: " << argv[0] << " file-name" << std::endl; + return 1; + } + + auto path = argv[1]; + auto pop = nvobj::pool::create(path, + "VectorTest: vector_ctor_capacity", + pool_size, S_IWUSR | S_IRUSR); + + auto r = pop.root(); + + try { + nvobj::transaction::run(pop, [&] { + r->pptr1 = nvobj::make_persistent(); + /* test capacity of default-constructed vector */ + UT_ASSERT(0 == r->pptr1->capacity()); + nvobj::delete_persistent(r->pptr1); + + r->pptr1 = nvobj::make_persistent( + test_val1, 0); + /* test capacity of size-value-constructed vector */ + UT_ASSERT(test_val1 == r->pptr1->capacity()); + + r->pptr2 = nvobj::make_persistent( + r->pptr1->begin(), r->pptr1->end()); + /* test capacity of iter-iter-constructed vector */ + UT_ASSERT(test_val1 == r->pptr2->capacity()); + nvobj::delete_persistent(r->pptr2); + + r->pptr2 = + nvobj::make_persistent(*r->pptr1); + /* test capacity of copy-constructed vector */ + UT_ASSERT(test_val1 == r->pptr2->capacity()); + nvobj::delete_persistent(r->pptr2); + + r->pptr2 = nvobj::make_persistent( + std::move(*r->pptr1)); + /* test capacity of move-constructed vector */ + UT_ASSERT(test_val1 == r->pptr2->capacity()); + nvobj::delete_persistent(r->pptr2); + nvobj::delete_persistent(r->pptr1); + }); + } catch (std::exception &e) { + UT_FATALexc(e); + } + + pop.close(); + + return 0; +} diff --git a/tests/vector_ctor_check_copy/vector_ctor_check_copy.cpp b/tests/vector_ctor_check_copy/vector_ctor_check_copy.cpp new file mode 100644 index 0000000..d10fd8d --- /dev/null +++ b/tests/vector_ctor_check_copy/vector_ctor_check_copy.cpp @@ -0,0 +1,139 @@ +/* + * Copyright 2019, Intel Corporation + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * * Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "helper_classes.hpp" +#include "unittest.hpp" + +#include +#include + +namespace nvobj = pmem::obj; +namespace pmem_exp = nvobj::experimental; + +const static size_t pool_size = PMEMOBJ_MIN_POOL; + +using test_type = emplace_constructible_copy_insertable_move_insertable; +using vector_type = pmem_exp::vector; +using It = test_support::input_it; + +struct root { + nvobj::persistent_ptr pptr1; + nvobj::persistent_ptr pptr2; +}; + +int +main(int argc, char *argv[]) +{ + START(); + + if (argc < 2) { + std::cerr << "usage: " << argv[0] << " file-name" << std::endl; + return 1; + } + + auto path = argv[1]; + auto pop = nvobj::pool::create( + path, "VectorTest: vector_ctor_check_copy", pool_size, + S_IWUSR | S_IRUSR); + + auto r = pop.root(); + + /** + * Check if range ctor will construct vector from element's type + * copy ctor. + */ + test_type arr[] = {1, 2, 3, 4}; + + try { + nvobj::transaction::run(pop, [&] { + r->pptr1 = nvobj::make_persistent( + It(std::begin(arr)), It(std::end(arr))); + }); + + UT_ASSERTeq(r->pptr1->const_at(0).value, 1); + UT_ASSERTeq(r->pptr1->const_at(1).value, 2); + UT_ASSERTeq(r->pptr1->const_at(2).value, 3); + UT_ASSERTeq(r->pptr1->const_at(3).value, 4); + + UT_ASSERTeq(r->pptr1->const_at(0).copied, 1); + UT_ASSERTeq(r->pptr1->const_at(1).copied, 1); + UT_ASSERTeq(r->pptr1->const_at(2).copied, 1); + UT_ASSERTeq(r->pptr1->const_at(3).copied, 1); + + UT_ASSERTeq(r->pptr1->const_at(0).moved, 0); + UT_ASSERTeq(r->pptr1->const_at(1).moved, 0); + UT_ASSERTeq(r->pptr1->const_at(2).moved, 0); + UT_ASSERTeq(r->pptr1->const_at(3).moved, 0); + } catch (std::exception &e) { + UT_FATALexc(e); + } + + /** + * Check if copy ctor will construct vector from element's type + * copy ctor. + */ + try { + nvobj::transaction::run(pop, [&] { + r->pptr2 = + nvobj::make_persistent(*r->pptr1); + }); + + UT_ASSERTeq(r->pptr2->const_at(0).value, 1); + UT_ASSERTeq(r->pptr2->const_at(1).value, 2); + UT_ASSERTeq(r->pptr2->const_at(2).value, 3); + UT_ASSERTeq(r->pptr2->const_at(3).value, 4); + + UT_ASSERTeq(r->pptr2->const_at(0).copied, 2); + UT_ASSERTeq(r->pptr2->const_at(1).copied, 2); + UT_ASSERTeq(r->pptr2->const_at(2).copied, 2); + UT_ASSERTeq(r->pptr2->const_at(3).copied, 2); + + UT_ASSERTeq(r->pptr2->const_at(0).moved, 0); + UT_ASSERTeq(r->pptr2->const_at(1).moved, 0); + UT_ASSERTeq(r->pptr2->const_at(2).moved, 0); + UT_ASSERTeq(r->pptr2->const_at(3).moved, 0); + } catch (std::exception &e) { + UT_FATALexc(e); + } + + try { + nvobj::transaction::run(pop, [&] { + nvobj::delete_persistent(r->pptr1); + nvobj::delete_persistent(r->pptr2); + }); + } catch (std::exception &e) { + UT_FATALexc(e); + } + pop.close(); + + return 0; +} diff --git a/tests/vector_ctor_exceptions_nopmem/vector_ctor_exceptions_nopmem.cpp b/tests/vector_ctor_exceptions_nopmem/vector_ctor_exceptions_nopmem.cpp new file mode 100644 index 0000000..6c2f5c5 --- /dev/null +++ b/tests/vector_ctor_exceptions_nopmem/vector_ctor_exceptions_nopmem.cpp @@ -0,0 +1,266 @@ +/* + * Copyright 2018-2019, Intel Corporation + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * * Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "unittest.hpp" + +#include +#include + +namespace nvobj = pmem::obj; +namespace pmem_exp = nvobj::experimental; +using vector_type = pmem_exp::vector; + +struct root { + nvobj::persistent_ptr pptr; +}; + +/** + * Test pmem::obj::experimental::vector default constructor. + * + * Call default constructor for volatile instance of + * pmem::obj::experimental::vector. Expect pmem::pool_error exception is thrown. + */ +void +test_default_ctor() +{ + bool exception_thrown = false; + try { + vector_type v = {}; + (void)v; + UT_ASSERT(0); + } catch (pmem::pool_error &) { + exception_thrown = true; + } catch (std::exception &e) { + UT_FATALexc(e); + } + UT_ASSERT(exception_thrown); +} + +/** + * Test pmem::obj::experimental::vector range constructor. + * + * Call range constructor for volatile instance of + * pmem::obj::experimental::vector. Expect pmem::pool_error exception is thrown. + */ +void +test_iter_iter_ctor() +{ + int a[] = {0, 1, 2, 3, 4, 5}; + + bool exception_thrown = false; + try { + vector_type v(std::begin(a), std::end(a)); + (void)v; + UT_ASSERT(0); + } catch (pmem::pool_error &) { + exception_thrown = true; + } catch (std::exception &e) { + UT_FATALexc(e); + } + UT_ASSERT(exception_thrown); +} + +/** + * Test pmem::obj::experimental::vector fill constructor with elements with + * default values. + * + * Call fill constructor for volatile instance of + * pmem::obj::experimental::vector. Expect pmem::pool_error exception is thrown. + */ +void +test_size_ctor() +{ + bool exception_thrown = false; + try { + vector_type v(100); + (void)v; + UT_ASSERT(0); + } catch (pmem::pool_error &) { + exception_thrown = true; + } catch (std::exception &e) { + UT_FATALexc(e); + } + UT_ASSERT(exception_thrown); +} + +/** + * Test pmem::obj::experimental::vector fill constructor with elements with + * custom values. + * + * Call fill constructor for volatile instance of + * pmem::obj::experimental::vector. Expect pmem::pool_error exception is thrown. + */ +void +test_size_value_ctor() +{ + bool exception_thrown = false; + try { + vector_type v(100, 5); + (void)v; + UT_ASSERT(0); + } catch (pmem::pool_error &) { + exception_thrown = true; + } catch (std::exception &e) { + UT_FATALexc(e); + } + UT_ASSERT(exception_thrown); +} + +/** + * Test pmem::obj::experimental::vector copy constructor + * + * Call copy constructor for volatile instance of + * pmem::obj::experimental::vector. Expect pmem::pool_error exception is thrown. + */ +void +test_copy_ctor(nvobj::pool &pop) +{ + auto r = pop.root(); + + try { + nvobj::transaction::run(pop, [&] { + r->pptr = nvobj::make_persistent(); + }); + } catch (std::exception &e) { + UT_FATALexc(e); + } + + bool exception_thrown = false; + try { + vector_type v(*r->pptr); + (void)v; + UT_ASSERT(0); + } catch (pmem::pool_error &) { + exception_thrown = true; + } catch (std::exception &e) { + UT_FATALexc(e); + } + UT_ASSERT(exception_thrown); + + try { + nvobj::transaction::run(pop, [&] { + nvobj::delete_persistent(r->pptr); + }); + } catch (std::exception &e) { + UT_FATALexc(e); + } +} + +/** + * Test pmem::obj::experimental::vector initializer list constructor + * + * Call initializer list constructor for volatile instance of + * pmem::obj::experimental::vector. Expect pmem::pool_error exception is thrown. + */ +void +test_initializer_list_ctor() +{ + bool exception_thrown = false; + try { + vector_type v(std::initializer_list{1, 2, 3, 4}); + (void)v; + UT_ASSERT(0); + } catch (pmem::pool_error &) { + exception_thrown = true; + } catch (std::exception &e) { + UT_FATALexc(e); + } + UT_ASSERT(exception_thrown); +} + +/** + * Test pmem::obj::experimental::vector move constructor + * + * Call move constructor for volatile instance of + * pmem::obj::experimental::vector. Expect pmem::pool_error exception is thrown. + */ +void +test_move_ctor(nvobj::pool &pop) +{ + auto r = pop.root(); + + try { + nvobj::transaction::run(pop, [&] { + r->pptr = nvobj::make_persistent(); + }); + } catch (std::exception &e) { + UT_FATALexc(e); + } + + bool exception_thrown = false; + try { + vector_type v(std::move(*r->pptr)); + (void)v; + UT_ASSERT(0); + } catch (pmem::pool_error &) { + exception_thrown = true; + } catch (std::exception &e) { + UT_FATALexc(e); + } + UT_ASSERT(exception_thrown); + + try { + nvobj::transaction::run(pop, [&] { + nvobj::delete_persistent(r->pptr); + }); + } catch (std::exception &e) { + UT_FATALexc(e); + } +} + +int +main(int argc, char *argv[]) +{ + START(); + + if (argc < 2) { + std::cerr << "usage: " << argv[0] << " file-name" << std::endl; + return 1; + } + + auto path = argv[1]; + auto pop = + nvobj::pool::create(path, "VectorTest: ctor_nopmem", + PMEMOBJ_MIN_POOL, S_IWUSR | S_IRUSR); + + test_copy_ctor(pop); + test_default_ctor(); + test_initializer_list_ctor(); + test_iter_iter_ctor(); + test_move_ctor(pop); + test_size_ctor(); + test_size_value_ctor(); + + pop.close(); + + return 0; +} diff --git a/tests/vector_ctor_exceptions_notx/vector_ctor_exceptions_notx.cpp b/tests/vector_ctor_exceptions_notx/vector_ctor_exceptions_notx.cpp new file mode 100644 index 0000000..bec2f1c --- /dev/null +++ b/tests/vector_ctor_exceptions_notx/vector_ctor_exceptions_notx.cpp @@ -0,0 +1,302 @@ +/* + * Copyright 2018-2019, Intel Corporation + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * * Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "unittest.hpp" + +#include +#include + +namespace nvobj = pmem::obj; +namespace pmem_exp = nvobj::experimental; + +using vector_type = pmem_exp::vector; + +/** + * Test pmem::obj::experimental::vector default constructor. + * + * Call default constructor out of transaction scope. + * Expect pmem:transaction_error exception is thrown. + */ +void +test_default_ctor(nvobj::pool &pop) +{ + bool exception_thrown = false; + try { + nvobj::persistent_ptr pptr_v = nullptr; + nvobj::transaction::run(pop, [&] { + pptr_v = pmemobj_tx_alloc( + sizeof(vector_type), + pmem::detail::type_num()); + if (pptr_v == nullptr) + UT_ASSERT(0); + }); + pmem::detail::create(&*pptr_v); + } catch (pmem::transaction_error &) { + exception_thrown = true; + } catch (std::exception &e) { + UT_FATALexc(e); + } + UT_ASSERT(exception_thrown); +} + +/** + * Test pmem::obj::experimental::vector range constructor. + * + * Call range constructor out of transaction scope. + * Expect pmem:transaction_error exception is thrown. + */ +void +test_iter_iter_ctor(nvobj::pool &pop) +{ + int a[] = {0, 1, 2, 3, 4, 5}; + + bool exception_thrown = false; + try { + nvobj::persistent_ptr pptr_v = nullptr; + nvobj::transaction::run(pop, [&] { + pptr_v = pmemobj_tx_alloc( + sizeof(vector_type), + pmem::detail::type_num()); + if (pptr_v == nullptr) + UT_ASSERT(0); + }); + pmem::detail::create( + &*pptr_v, std::begin(a), std::end(a)); + } catch (pmem::transaction_error &) { + exception_thrown = true; + } catch (std::exception &e) { + UT_FATALexc(e); + } + UT_ASSERT(exception_thrown); +} + +/** + * Test pmem::obj::experimental::vector fill constructor with elements with + * default values. + * + * Call fill constructor out of transaction scope. + * Expect pmem:transaction_error exception is thrown. + */ +void +test_size_ctor(nvobj::pool &pop) +{ + bool exception_thrown = false; + try { + nvobj::persistent_ptr pptr_v = nullptr; + nvobj::transaction::run(pop, [&] { + pptr_v = pmemobj_tx_alloc( + sizeof(vector_type), + pmem::detail::type_num()); + if (pptr_v == nullptr) + UT_ASSERT(0); + }); + pmem::detail::create( + &*pptr_v, 100); + } catch (pmem::transaction_error &) { + exception_thrown = true; + } catch (std::exception &e) { + UT_FATALexc(e); + } + UT_ASSERT(exception_thrown); +} + +/** + * Test pmem::obj::experimental::vector fill constructor with elements with + * custom values. + * + * Call fill constructor out of transaction scope. + * Expect pmem:transaction_error exception is thrown. + */ +void +test_size_value_ctor(nvobj::pool &pop) +{ + bool exception_thrown = false; + try { + nvobj::persistent_ptr pptr_v = nullptr; + nvobj::transaction::run(pop, [&] { + pptr_v = pmemobj_tx_alloc( + sizeof(vector_type), + pmem::detail::type_num()); + if (pptr_v == nullptr) + UT_ASSERT(0); + }); + pmem::detail::create(&*pptr_v, 100, 5); + } catch (pmem::transaction_error &) { + exception_thrown = true; + } catch (std::exception &e) { + UT_FATALexc(e); + } + UT_ASSERT(exception_thrown); +} + +/** + * Test pmem::obj::experimental::vector copy constructor. + * + * Call copy constructor out of transaction scope. + * Expect pmem:transaction_error exception is thrown. + */ +void +test_copy_ctor(nvobj::pool &pop) +{ + nvobj::persistent_ptr pptr; + + bool exception_thrown = false; + + try { + nvobj::transaction::run(pop, [&] { + pptr = nvobj::make_persistent(); + }); + } catch (std::exception &e) { + UT_FATALexc(e); + }; + + try { + nvobj::persistent_ptr pptr_v = nullptr; + nvobj::transaction::run(pop, [&] { + pptr_v = pmemobj_tx_alloc( + sizeof(vector_type), + pmem::detail::type_num()); + if (pptr_v == nullptr) + UT_ASSERT(0); + }); + pmem::detail::create(&*pptr_v, *pptr); + } catch (pmem::transaction_error &) { + exception_thrown = true; + } catch (std::exception &e) { + UT_FATALexc(e); + }; + UT_ASSERT(exception_thrown); + + try { + nvobj::transaction::run(pop, [&] { + nvobj::delete_persistent(pptr); + }); + } catch (std::exception &e) { + UT_FATALexc(e); + }; +} + +/** + * Test pmem::obj::experimental::vector initializer list constructor. + * + * Call initializer list constructor out of transaction scope. + * Expect pmem:transaction_error exception is thrown. + */ +void +test_initializer_list_ctor(nvobj::pool &pop) +{ + bool exception_thrown = false; + try { + nvobj::persistent_ptr pptr_v = nullptr; + nvobj::transaction::run(pop, [&] { + pptr_v = pmemobj_tx_alloc( + sizeof(vector_type), + pmem::detail::type_num()); + if (pptr_v == nullptr) + UT_ASSERT(0); + }); + pmem::detail::create( + &*pptr_v, std::initializer_list{1, 2, 3, 4}); + } catch (pmem::transaction_error &) { + exception_thrown = true; + } catch (std::exception &e) { + UT_FATALexc(e); + }; + UT_ASSERT(exception_thrown); +} + +/** + * Test pmem::obj::experimental::vector move constructor. + * + * Call move constructor out of transaction scope. + * Expect pmem:transaction_error exception is thrown. + */ +void +test_move_ctor(nvobj::pool &pop) +{ + nvobj::persistent_ptr pptr; + + try { + nvobj::transaction::run(pop, [&] { + pptr = nvobj::make_persistent(); + }); + } catch (std::exception &e) { + UT_FATALexc(e); + }; + + bool exception_thrown = false; + try { + nvobj::persistent_ptr pptr_v = nullptr; + nvobj::transaction::run(pop, [&] { + pptr_v = pmemobj_tx_alloc( + sizeof(vector_type), + pmem::detail::type_num()); + if (pptr_v == nullptr) + UT_ASSERT(0); + }); + pmem::detail::create(&*pptr_v, std::move(*pptr)); + } catch (pmem::transaction_error &) { + exception_thrown = true; + } catch (std::exception &e) { + UT_FATALexc(e); + }; + UT_ASSERT(exception_thrown); +} + +int +main(int argc, char *argv[]) +{ + START(); + + if (argc < 2) { + std::cerr << "usage: " << argv[0] << " file-name" << std::endl; + return 1; + } + auto path = argv[1]; + auto pop = nvobj::pool::create( + path, "VectorTest: vector_ctor_exceptions_notx", + PMEMOBJ_MIN_POOL, S_IWUSR | S_IRUSR); + + test_copy_ctor(pop); + test_default_ctor(pop); + test_initializer_list_ctor(pop); + test_iter_iter_ctor(pop); + test_move_ctor(pop); + test_size_ctor(pop); + test_size_value_ctor(pop); + + pop.close(); + + return 0; +} diff --git a/tests/vector_ctor_exceptions_oom/vector_ctor_exceptions_oom.cpp b/tests/vector_ctor_exceptions_oom/vector_ctor_exceptions_oom.cpp new file mode 100644 index 0000000..4f9e114 --- /dev/null +++ b/tests/vector_ctor_exceptions_oom/vector_ctor_exceptions_oom.cpp @@ -0,0 +1,164 @@ +/* + * Copyright 2018-2019, Intel Corporation + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * * Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "unittest.hpp" + +#include +#include + +#include +#include + +namespace nvobj = pmem::obj; +namespace pmem_exp = nvobj::experimental; + +const static size_t pool_size = 2 * PMEMOBJ_MIN_POOL; +const static size_t test_val = pool_size * 2; + +using vector_type = pmem_exp::vector; + +struct root { + nvobj::persistent_ptr pptr; +}; + +/** + * Test pmem::obj::experimental::vector range constructor. + * + * Call range constructor to exceed available memory of the pool. Expect + * pmem:transaction_alloc_error exception is thrown. + */ +void +test_iter_iter_ctor(nvobj::pool &pop, + nvobj::persistent_ptr &pptr) +{ + static std::vector vec(test_val); + + bool exception_thrown = false; + + try { + nvobj::transaction::run(pop, [&] { + pptr = nvobj::make_persistent( + std::begin(vec), std::end(vec)); + }); + UT_ASSERT(0); + } catch (pmem::transaction_alloc_error &) { + exception_thrown = true; + } catch (std::exception &e) { + UT_FATALexc(e); + } + + UT_ASSERT(exception_thrown); +} + +/** + * Test pmem::obj::experimental::vector fill constructor with elements with + * default values. + * + * Call fill constructor to exceed available memory of the pool. Expect + * pmem:transaction_alloc_error exception is thrown. + */ +void +test_size_ctor(nvobj::pool &pop, + nvobj::persistent_ptr &pptr) +{ + bool exception_thrown = false; + + try { + nvobj::transaction::run(pop, [&] { + pptr = nvobj::make_persistent(test_val); + }); + UT_ASSERT(0); + } catch (pmem::transaction_alloc_error &) { + exception_thrown = true; + } catch (std::exception &e) { + UT_FATALexc(e); + } + + UT_ASSERT(exception_thrown); +} + +/** + * Test pmem::obj::experimental::vector fill constructor with elements with + * custom values. + * + * Call fill constructor to exceed available memory of the pool. + * Expect pmem:transaction_alloc_error exception is thrown. + */ +void +test_size_value_ctor(nvobj::pool &pop, + nvobj::persistent_ptr &pptr) +{ + bool exception_thrown = false; + + try { + nvobj::transaction::run(pop, [&] { + pptr = nvobj::make_persistent(test_val, 1); + }); + UT_ASSERT(0); + } catch (pmem::transaction_alloc_error &) { + exception_thrown = true; + } catch (std::exception &e) { + UT_FATALexc(e); + } + + UT_ASSERT(exception_thrown); +} + +int +main(int argc, char *argv[]) +{ + START(); + + if (argc < 2) { + std::cerr << "usage: " << argv[0] << " file-name" << std::endl; + return 1; + } + + auto path = argv[1]; + auto pop = nvobj::pool::create( + path, "VectorTest: vector_ctor_exceptions_oom", pool_size, + S_IWUSR | S_IRUSR); + + auto pptr = pop.root()->pptr; + + test_iter_iter_ctor(pop, pptr); + test_size_ctor(pop, pptr); + test_size_value_ctor(pop, pptr); + /* XXX: implement following test cases when vector's push_back method is + available */ + // test_copy_ctor(pop); + // test_initializer_list_ctor(pop); + + pop.close(); + + return 0; +} diff --git a/tests/vector_ctor_move/vector_ctor_move.cpp b/tests/vector_ctor_move/vector_ctor_move.cpp new file mode 100644 index 0000000..f2a108a --- /dev/null +++ b/tests/vector_ctor_move/vector_ctor_move.cpp @@ -0,0 +1,135 @@ +/* + * Copyright 2019, Intel Corporation + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * * Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "unittest.hpp" + +#include +#include + +namespace nvobj = pmem::obj; +namespace pmem_exp = nvobj::experimental; + +using vector_type = pmem_exp::vector; + +struct root { + nvobj::persistent_ptr v1; + nvobj::persistent_ptr v2; +}; + +/** + * Test pmem::obj::experimental::vector move constructor. + * + * Checks if vector state is reverted when transaction aborts + */ +void +test_move_ctor_abort(nvobj::pool &pop) +{ + auto r = pop.root(); + + auto size = r->v1->size(); + + UT_ASSERT(r->v2 == nullptr); + try { + nvobj::transaction::run(pop, [&] { + r->v2 = nvobj::make_persistent( + std::move(*r->v1)); + + UT_ASSERT(r->v1->empty()); + UT_ASSERT(r->v2->size() == size); + + for (vector_type::size_type i = 0; i < size; ++i) { + UT_ASSERT((*r->v2)[i] == (int)i); + } + + nvobj::transaction::abort(EINVAL); + }); + } catch (pmem::manual_tx_abort &) { + } catch (std::exception &e) { + UT_FATALexc(e); + } + + UT_ASSERT(r->v2 == nullptr); + UT_ASSERT(r->v1->size() == size); + + try { + nvobj::transaction::run(pop, [&] { + for (vector_type::size_type i = 0; i < size; ++i) { + UT_ASSERT((*r->v1)[i] == (int)i); + } + }); + } catch (std::exception &e) { + UT_FATALexc(e); + } +} + +int +main(int argc, char *argv[]) +{ + START(); + + if (argc < 2) { + std::cerr << "usage: " << argv[0] << " file-name" << std::endl; + return 1; + } + + auto path = argv[1]; + auto pop = + nvobj::pool::create(path, "VectorTest: vector_ctor_move", + PMEMOBJ_MIN_POOL, S_IWUSR | S_IRUSR); + + int arr[] = {0, 1, 2, 3, 4, 5}; + + auto r = pop.root(); + + try { + nvobj::transaction::run(pop, [&] { + r->v1 = nvobj::make_persistent( + std::begin(arr), std::end(arr)); + }); + } catch (std::exception &e) { + UT_FATALexc(e); + } + + test_move_ctor_abort(pop); + + try { + nvobj::transaction::run(pop, [&] { + nvobj::delete_persistent(r->v1); + }); + } catch (std::exception &e) { + UT_FATALexc(e); + } + + pop.close(); + + return 0; +} diff --git a/tests/vector_dtor/vector_dtor.cpp b/tests/vector_dtor/vector_dtor.cpp new file mode 100644 index 0000000..8f445dc --- /dev/null +++ b/tests/vector_dtor/vector_dtor.cpp @@ -0,0 +1,116 @@ +/* + * Copyright 2018-2019, Intel Corporation + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * * Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "unittest.hpp" + +#include +#include +#include +#include + +#include + +namespace nvobj = pmem::obj; +namespace pmem_exp = nvobj::experimental; + +struct X { + static unsigned count; + nvobj::p val; + + X() : val(1) + { + ++count; + }; + ~X() + { + --count; + }; +}; + +unsigned X::count = 0; + +using vector_type = pmem_exp::vector; + +struct root { + nvobj::persistent_ptr pptr; +}; + +/** + * Test pmem::obj::experimental::vector default destructor. + * + * Call default destructor out of transaction scope. + * Expects vector is empty and no exception is thrown. + */ +void +test_dtor(nvobj::pool &pop) +{ + auto r = pop.root(); + + using size_type = vector_type::size_type; + const size_type size = 100; + try { + nvobj::transaction::run(pop, [&] { + r->pptr = nvobj::make_persistent(size); + }); + UT_ASSERTeq(r->pptr->size(), X::count); + UT_ASSERTeq(X::count, size); + + r->pptr->~vector(); + + UT_ASSERT(r->pptr->empty()); + UT_ASSERTeq(X::count, 0); + } catch (std::exception &e) { + UT_FATALexc(e); + } +} + +int +main(int argc, char *argv[]) +{ + START(); + + if (argc < 2) { + std::cerr << "usage: " << argv[0] << " file-name" << std::endl; + return 1; + } + + auto path = argv[1]; + auto pop = + nvobj::pool::create(path, "VectorTest: vector_dtor", + PMEMOBJ_MIN_POOL, S_IWUSR | S_IRUSR); + + test_dtor(pop); + + pop.close(); + + return 0; +} diff --git a/tests/vector_iterators_access/vector_iterators_access.cpp b/tests/vector_iterators_access/vector_iterators_access.cpp new file mode 100644 index 0000000..3cf13d8 --- /dev/null +++ b/tests/vector_iterators_access/vector_iterators_access.cpp @@ -0,0 +1,235 @@ +/* + * Copyright 2019, Intel Corporation + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * * Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "unittest.hpp" + +#include +#include +#include + +namespace nvobj = pmem::obj; +namespace pmem_exp = nvobj::experimental; +using C = pmem_exp::vector; + +struct root { + nvobj::persistent_ptr v; +}; + +/* Check if access method can be called out of transaction scope */ +void +check_access_out_of_tx(nvobj::pool &pop) +{ + auto r = pop.root(); + + try { + r->v->const_at(0); + r->v->cdata(); + r->v->cfront(); + r->v->cback(); + r->v->cbegin(); + r->v->cend(); + r->v->crbegin(); + r->v->crend(); + + (*r->v)[0]; + r->v->at(0); + r->v->data(); + r->v->front(); + r->v->back(); + r->v->begin(); + r->v->end(); + r->v->rbegin(); + r->v->rend(); + + static_cast(*r->v).at(0); + static_cast(*r->v).data(); + static_cast(*r->v).front(); + static_cast(*r->v).back(); + static_cast(*r->v).begin(); + static_cast(*r->v).end(); + static_cast(*r->v).rbegin(); + static_cast(*r->v).rend(); + static_cast(*r->v)[0]; + } catch (std::exception &e) { + UT_FATALexc(e); + } +} + +/* + * Check if access methods, iterators and dereference operator add + * elements to transaction. Expect no pmemcheck errors. + */ +void +check_add_to_tx(nvobj::pool &pop) +{ + auto r = pop.root(); + + try { + nvobj::transaction::run(pop, [&] { (*r->v)[0] = 0; }); + nvobj::transaction::run(pop, [&] { r->v->at(0) = 1; }); + nvobj::transaction::run(pop, [&] { + auto p = r->v->data(); + for (unsigned i = 0; i < r->v->size(); ++i) + *(p + i) = 2; + }); + nvobj::transaction::run(pop, [&] { r->v->front() = 3; }); + nvobj::transaction::run(pop, [&] { r->v->back() = 4; }); + nvobj::transaction::run(pop, [&] { *r->v->begin() = 5; }); + nvobj::transaction::run(pop, [&] { *(r->v->end() - 1) = 6; }); + nvobj::transaction::run(pop, [&] { *r->v->rbegin() = 7; }); + nvobj::transaction::run(pop, [&] { *(r->v->rend() - 1) = 8; }); + } catch (std::exception &e) { + UT_FATALexc(e); + } +} + +void +assert_out_of_range(pmem::obj::pool &pop, + std::function f) +{ + bool exception_thrown = false; + try { + nvobj::transaction::run(pop, [&] { f(); }); + } catch (std::out_of_range &) { + exception_thrown = true; + } catch (std::exception &e) { + UT_FATALexc(e); + } + UT_ASSERT(exception_thrown); +} + +/* + * Access element beyond the vector's bounds. + * Check if std::out_of_range exception is thrown. + */ +void +check_out_of_range(nvobj::pool &pop) +{ + auto r = pop.root(); + + auto size = r->v->size(); + + try { + assert_out_of_range(pop, [&] { r->v->at(size); }); + + assert_out_of_range( + pop, [&] { const_cast(*r->v).at(size); }); + + assert_out_of_range(pop, [&] { r->v->const_at(size); }); + } catch (std::exception &e) { + UT_FATALexc(e); + } +} + +void +assert_tx_abort(pmem::obj::pool &pop, std::function f) +{ + bool exception_thrown = false; + try { + nvobj::transaction::run(pop, [&] { + f(); + nvobj::transaction::abort(EINVAL); + }); + } catch (pmem::manual_tx_abort &) { + exception_thrown = true; + } catch (std::exception &e) { + UT_FATALexc(e); + } + UT_ASSERT(exception_thrown); +} + +/* Checks if vector's state is reverted when transaction aborts. */ +void +check_tx_abort(pmem::obj::pool &pop) +{ + auto r = pop.root(); + + try { + assert_tx_abort(pop, [&] { (*r->v)[0] = 5; }); + UT_ASSERTeq((*r->v)[0], 1); + + assert_tx_abort(pop, [&] { r->v->at(0) = 5; }); + UT_ASSERT(r->v->at(0) == 1); + + assert_tx_abort(pop, [&] { *r->v->begin() = 5; }); + UT_ASSERT(*r->v->begin() == 1); + + assert_tx_abort(pop, [&] { *(r->v->end() - 1) = 5; }); + UT_ASSERT(*(r->v->end() - 1) == 1); + + assert_tx_abort(pop, [&] { *r->v->rbegin() = 5; }); + UT_ASSERT(*r->v->rbegin() == 1); + + assert_tx_abort(pop, [&] { *(r->v->rend() - 1) = 5; }); + UT_ASSERT(*(r->v->rend() - 1) == 1); + + assert_tx_abort(pop, [&] { r->v->front() = 5; }); + UT_ASSERT(r->v->front() == 1); + + assert_tx_abort(pop, [&] { r->v->back() = 5; }); + UT_ASSERT(r->v->back() == 1); + } catch (std::exception &e) { + UT_FATALexc(e); + } +} + +int +main(int argc, char *argv[]) +{ + START(); + + if (argc < 2) { + std::cerr << "usage: " << argv[0] << " file-name" << std::endl; + return 1; + } + + auto path = argv[1]; + auto pop = + nvobj::pool::create(path, "VectorTest: iterators", + PMEMOBJ_MIN_POOL, S_IWUSR | S_IRUSR); + + auto r = pop.root(); + + nvobj::transaction::run( + pop, [&] { r->v = nvobj::make_persistent(10U, 1); }); + + check_access_out_of_tx(pop); + check_out_of_range(pop); + check_tx_abort(pop); + check_add_to_tx(pop); + + nvobj::delete_persistent_atomic(r->v); + + pop.close(); + + return 0; +} diff --git a/tests/vector_modifiers_exceptions_oom/vector_modifiers_exceptions_oom.cpp b/tests/vector_modifiers_exceptions_oom/vector_modifiers_exceptions_oom.cpp new file mode 100644 index 0000000..67106d8 --- /dev/null +++ b/tests/vector_modifiers_exceptions_oom/vector_modifiers_exceptions_oom.cpp @@ -0,0 +1,128 @@ +/* + * Copyright 2019, Intel Corporation + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * * Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "unittest.hpp" + +#include +#include + +namespace nvobj = pmem::obj; +namespace pmem_exp = nvobj::experimental; +using C = pmem_exp::vector; + +struct root { + nvobj::persistent_ptr v; +}; + +/** + * Test pmem::obj::experimental::vector modifiers + * + * Increase size of the vector to value greater than pool size + * Methods under test: + * - resize() + * - resize() with value + * Expect pmem::transaction_allor_error exception is thrown + */ +void +test(nvobj::pool &pop) +{ + auto r = pop.root(); + + UT_ASSERT(r->v->capacity() == 100); + UT_ASSERT(r->v->size() == 100); + + bool exception_thrown = false; + + auto size = r->v->max_size(); + + /* test resize() */ + try { + r->v->resize(size); + UT_ASSERT(0); + } catch (pmem::transaction_alloc_error &) { + exception_thrown = true; + } catch (std::exception &e) { + UT_FATALexc(e); + } + + UT_ASSERT(exception_thrown); + UT_ASSERT(r->v->capacity() == 100); + UT_ASSERT(r->v->size() == 100); + + /* test resize() with value */ + try { + r->v->resize(size, 0); + UT_ASSERT(0); + } catch (pmem::transaction_alloc_error &) { + exception_thrown = true; + } catch (std::exception &e) { + UT_FATALexc(e); + } + + UT_ASSERT(exception_thrown); + UT_ASSERT(r->v->capacity() == 100); + UT_ASSERT(r->v->size() == 100); +} + +int +main(int argc, char *argv[]) +{ + START(); + + if (argc < 2) { + std::cerr << "usage: " << argv[0] << " file-name" << std::endl; + return 1; + } + + auto path = argv[1]; + auto pop = nvobj::pool::create( + path, "VectorTest: modifiers_exceptions_oom", PMEMOBJ_MIN_POOL, + S_IWUSR | S_IRUSR); + + auto r = pop.root(); + + try { + nvobj::transaction::run( + pop, [&] { r->v = nvobj::make_persistent(100U); }); + + test(pop); + + nvobj::transaction::run( + pop, [&] { nvobj::delete_persistent(r->v); }); + } catch (std::exception &e) { + UT_FATALexc(e); + } + + pop.close(); + + return 0; +} diff --git a/tests/vector_modifiers_txabort/vector_modifiers_txabort.cpp b/tests/vector_modifiers_txabort/vector_modifiers_txabort.cpp new file mode 100644 index 0000000..bc6e976 --- /dev/null +++ b/tests/vector_modifiers_txabort/vector_modifiers_txabort.cpp @@ -0,0 +1,509 @@ +/* + * Copyright 2019, Intel Corporation + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * * Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "helper_classes.hpp" + +#include +#include + +#include + +namespace nvobj = pmem::obj; +namespace pmem_exp = nvobj::experimental; + +using C = pmem_exp::vector; +using C2 = pmem_exp::vector; + +struct root { + nvobj::persistent_ptr v1; + nvobj::persistent_ptr v2; + nvobj::persistent_ptr v3; +}; + +using It = C::const_iterator; + +void +check_value(It start, It end, int value) +{ + for (auto it = start; it != end; ++it) { + UT_ASSERTeq(*it, value); + } +} + +void +check_vector(nvobj::persistent_ptr pptr, size_t count, int value) +{ + UT_ASSERTeq(pptr->size(), count); + + check_value(pptr->cbegin(), pptr->cend(), value); +} + +void +check_range(It start, It end, int value) +{ + check_value(start, end, value); +} + +/** + * Test pmem::obj::experimental::vector modifiers + * + * Checks if vector's state is reverted when transaction aborts. + * Methods under test: + * - clear() + * - resize() + * - resize() with value + * - swap() + * - insert() single element version + * - insert() fill version + * - insert() range version + * - insert() move version + * - insert() initializer list version + * - erase() single element version + * - erase() range version + * - pop_back() + * - push_back() copy version + * - push_back() move version + * - emplace() + * - emplace_back() + */ +void +test(nvobj::pool &pop) +{ + auto r = pop.root(); + + check_vector(r->v1, 100, 1); + + bool exception_thrown = false; + + /* test clear() revert */ + try { + nvobj::transaction::run(pop, [&] { + r->v1->clear(); + UT_ASSERT(r->v1->empty()); + nvobj::transaction::abort(EINVAL); + }); + } catch (pmem::manual_tx_abort &) { + exception_thrown = true; + } catch (std::exception &e) { + UT_FATALexc(e); + } + + check_vector(r->v1, 100, 1); + + UT_ASSERT(exception_thrown); + + /* test resize() revert */ + try { + nvobj::transaction::run(pop, [&] { + r->v1->resize(50); + UT_ASSERT(r->v1->size() == 50); + nvobj::transaction::abort(EINVAL); + }); + } catch (pmem::manual_tx_abort &) { + exception_thrown = true; + } catch (std::exception &e) { + UT_FATALexc(e); + } + + check_vector(r->v1, 100, 1); + + UT_ASSERT(exception_thrown); + + /* test resize() overload with value revert */ + try { + nvobj::transaction::run(pop, [&] { + r->v1->resize(150, 2); + UT_ASSERT(r->v1->size() == 150); + nvobj::transaction::abort(EINVAL); + }); + } catch (pmem::manual_tx_abort &) { + exception_thrown = true; + } catch (std::exception &e) { + UT_FATALexc(e); + } + + check_vector(r->v1, 100, 1); + + UT_ASSERT(exception_thrown); + + /* test swap() */ + try { + nvobj::transaction::run(pop, [&] { + r->v1->swap(*r->v2); + + check_vector(r->v1, 50, 2); + check_vector(r->v2, 100, 1); + + nvobj::transaction::abort(EINVAL); + }); + } catch (pmem::manual_tx_abort &) { + exception_thrown = true; + } catch (std::exception &e) { + UT_FATALexc(e); + } + + check_vector(r->v1, 100, 1); + check_vector(r->v2, 50, 2); + + UT_ASSERT(exception_thrown); + + /* test insert() single element version */ + try { + auto pos = r->v1->begin() + 50; + nvobj::transaction::run(pop, [&] { + r->v1->insert(pos, 5); + + /* pos has invalided after reallocation */ + auto pos_new = r->v1->begin() + 50; + + UT_ASSERT(r->v1->size() == 101); + check_range(r->v1->begin(), pos_new, 1); + check_range(pos_new, pos_new + 1, 5); + check_range(pos_new + 1, r->v1->end(), 1); + + nvobj::transaction::abort(EINVAL); + }); + } catch (pmem::manual_tx_abort &) { + exception_thrown = true; + } catch (std::exception &e) { + UT_FATALexc(e); + } + + check_vector(r->v1, 100, 1); + + UT_ASSERT(exception_thrown); + + /* test insert() fill version */ + try { + auto pos = r->v1->begin() + 50; + nvobj::transaction::run(pop, [&] { + r->v1->insert(pos, 10, 5); + + /* pos has invalided after reallocation */ + auto pos_new = r->v1->begin() + 50; + + UT_ASSERT(r->v1->size() == 110); + check_range(r->v1->begin(), pos_new, 1); + check_range(pos_new, pos_new + 10, 5); + check_range(pos_new + 10, r->v1->end(), 1); + + nvobj::transaction::abort(EINVAL); + }); + } catch (pmem::manual_tx_abort &) { + exception_thrown = true; + } catch (std::exception &e) { + UT_FATALexc(e); + } + + check_vector(r->v1, 100, 1); + + UT_ASSERT(exception_thrown); + + /* test insert() range version */ + try { + std::vector v(10, 5); + auto pos = r->v1->begin() + 50; + nvobj::transaction::run(pop, [&] { + r->v1->insert(pos, v.begin(), v.end()); + + /* pos has invalided after reallocation */ + auto pos_new = r->v1->begin() + 50; + + UT_ASSERT(r->v1->size() == 110); + check_range(r->v1->begin(), pos_new, 1); + check_range(pos_new, pos_new + 10, 5); + check_range(pos_new + 10, r->v1->end(), 1); + + nvobj::transaction::abort(EINVAL); + }); + } catch (pmem::manual_tx_abort &) { + exception_thrown = true; + } catch (std::exception &e) { + UT_FATALexc(e); + } + + check_vector(r->v1, 100, 1); + + UT_ASSERT(exception_thrown); + + /* test insert() move version */ + try { + int a = 5; + auto pos = r->v1->begin() + 50; + nvobj::transaction::run(pop, [&] { + r->v1->insert(pos, std::move(a)); + + /* pos has invalided after reallocation */ + auto pos_new = r->v1->begin() + 50; + + UT_ASSERT(r->v1->size() == 101); + check_range(r->v1->begin(), pos_new, 1); + check_range(pos_new, pos_new + 1, 5); + check_range(pos_new + 1, r->v1->end(), 1); + + nvobj::transaction::abort(EINVAL); + }); + } catch (pmem::manual_tx_abort &) { + exception_thrown = true; + } catch (std::exception &e) { + UT_FATALexc(e); + } + + check_vector(r->v1, 100, 1); + + UT_ASSERT(exception_thrown); + + /* test insert() initializer list version */ + try { + auto pos = r->v1->begin() + 50; + nvobj::transaction::run(pop, [&] { + r->v1->insert(pos, {5, 5, 5, 5, 5}); + + /* pos has invalided after reallocation */ + auto pos_new = r->v1->begin() + 50; + + UT_ASSERT(r->v1->size() == 105); + check_range(r->v1->begin(), pos_new, 1); + check_range(pos_new, pos_new + 5, 5); + check_range(pos_new + 5, r->v1->end(), 1); + + nvobj::transaction::abort(EINVAL); + }); + } catch (pmem::manual_tx_abort &) { + exception_thrown = true; + } catch (std::exception &e) { + UT_FATALexc(e); + } + + check_vector(r->v1, 100, 1); + + UT_ASSERT(exception_thrown); + + /* test erase() single element version */ + try { + nvobj::transaction::run(pop, [&] { + r->v1->erase(r->v1->begin()); + + check_vector(r->v1, 99, 1); + + nvobj::transaction::abort(EINVAL); + }); + } catch (pmem::manual_tx_abort &) { + exception_thrown = true; + } catch (std::exception &e) { + UT_FATALexc(e); + } + + check_vector(r->v1, 100, 1); + + UT_ASSERT(exception_thrown); + + /* test erase() range version */ + try { + nvobj::transaction::run(pop, [&] { + auto pos = r->v1->begin(); + r->v1->erase(pos, pos + 10); + + check_vector(r->v1, 90, 1); + + nvobj::transaction::abort(EINVAL); + }); + } catch (pmem::manual_tx_abort &) { + exception_thrown = true; + } catch (std::exception &e) { + UT_FATALexc(e); + } + + check_vector(r->v1, 100, 1); + + UT_ASSERT(exception_thrown); + + /* test pop_back() */ + try { + nvobj::transaction::run(pop, [&] { + r->v1->pop_back(); + + check_vector(r->v1, 99, 1); + + nvobj::transaction::abort(EINVAL); + }); + } catch (pmem::manual_tx_abort &) { + exception_thrown = true; + } catch (std::exception &e) { + UT_FATALexc(e); + } + + check_vector(r->v1, 100, 1); + + UT_ASSERT(exception_thrown); + + /* test push_back() copy version */ + try { + nvobj::transaction::run(pop, [&] { + r->v1->push_back(1); + + check_vector(r->v1, 101, 1); + + nvobj::transaction::abort(EINVAL); + }); + } catch (pmem::manual_tx_abort &) { + exception_thrown = true; + } catch (std::exception &e) { + UT_FATALexc(e); + } + + check_vector(r->v1, 100, 1); + + UT_ASSERT(exception_thrown); + + /* test push_back() move version */ + UT_ASSERT(r->v3->size() == 100); + + try { + nvobj::transaction::run(pop, [&] { + r->v3->push_back(move_only(1)); + + UT_ASSERT(r->v3->size() == 101); + for (auto it = r->v3->cbegin(); it != r->v3->cend(); + ++it) { + UT_ASSERT((*it).value == 1); + } + + nvobj::transaction::abort(EINVAL); + }); + } catch (pmem::manual_tx_abort &) { + exception_thrown = true; + } catch (std::exception &e) { + UT_FATALexc(e); + } + + UT_ASSERT(r->v3->size() == 100); + for (auto it = r->v3->cbegin(); it != r->v3->cend(); ++it) { + UT_ASSERT((*it).value == 1); + } + + UT_ASSERT(exception_thrown); + + /* test emplace() */ + UT_ASSERT(r->v1->size() == 100); + + try { + nvobj::transaction::run(pop, [&] { + r->v1->emplace(r->v1->begin(), 1); + + UT_ASSERT(r->v1->size() == 101); + for (auto it = r->v1->cbegin(); it != r->v1->cend(); + ++it) { + UT_ASSERT(*it == 1); + } + + nvobj::transaction::abort(EINVAL); + }); + } catch (pmem::manual_tx_abort &) { + exception_thrown = true; + } catch (std::exception &e) { + UT_FATALexc(e); + } + + UT_ASSERT(r->v1->size() == 100); + for (auto it = r->v1->cbegin(); it != r->v1->cend(); ++it) { + UT_ASSERT(*it == 1); + } + + UT_ASSERT(exception_thrown); + + /* test emplace_back() */ + try { + nvobj::transaction::run(pop, [&] { + r->v1->emplace_back(1); + + UT_ASSERT(r->v1->size() == 101); + for (auto it = r->v1->cbegin(); it != r->v1->cend(); + ++it) { + UT_ASSERT(*it == 1); + } + + nvobj::transaction::abort(EINVAL); + }); + } catch (pmem::manual_tx_abort &) { + exception_thrown = true; + } catch (std::exception &e) { + UT_FATALexc(e); + } + + UT_ASSERT(r->v1->size() == 100); + for (auto it = r->v1->cbegin(); it != r->v1->cend(); ++it) { + UT_ASSERT(*it == 1); + } + + UT_ASSERT(exception_thrown); +} + +int +main(int argc, char *argv[]) +{ + START(); + + if (argc < 2) { + std::cerr << "usage: " << argv[0] << " file-name" << std::endl; + return 1; + } + + auto path = argv[1]; + auto pop = + nvobj::pool::create(path, "VectorTest: modifiers_txabort", + PMEMOBJ_MIN_POOL, S_IWUSR | S_IRUSR); + + auto r = pop.root(); + + try { + nvobj::transaction::run(pop, [&] { + r->v1 = nvobj::make_persistent(100U, 1); + r->v2 = nvobj::make_persistent(50U, 2); + r->v3 = nvobj::make_persistent(100U); + }); + + test(pop); + + nvobj::transaction::run(pop, [&] { + nvobj::delete_persistent(r->v1); + nvobj::delete_persistent(r->v2); + nvobj::delete_persistent(r->v3); + }); + } catch (std::exception &e) { + UT_FATALexc(e); + } + + pop.close(); + + return 0; +} diff --git a/tests/vector_modifiers_type_requirements/vector_modifiers_type_requirements.cpp b/tests/vector_modifiers_type_requirements/vector_modifiers_type_requirements.cpp new file mode 100644 index 0000000..274ada1 --- /dev/null +++ b/tests/vector_modifiers_type_requirements/vector_modifiers_type_requirements.cpp @@ -0,0 +1,230 @@ +/* + * Copyright 2019, Intel Corporation + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * * Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "helper_classes.hpp" + +#include +#include + +#include + +namespace nvobj = pmem::obj; +namespace pmem_exp = nvobj::experimental; + +using c1 = copy_assignable_copy_insertable; +using C1 = pmem_exp::vector; + +using c2 = emplace_constructible_moveable_and_assignable; +using C2 = pmem_exp::vector; + +using c3 = emplace_constructible_and_move_insertable; +using C3 = pmem_exp::vector; + +using c4 = move_assignable; +using C4 = pmem_exp::vector; + +using c5 = copy_insertable; +using C5 = pmem_exp::vector; + +using c6 = move_insertable; +using C6 = pmem_exp::vector; + +struct root { + nvobj::persistent_ptr v1; + nvobj::persistent_ptr v2; + nvobj::persistent_ptr v3; + nvobj::persistent_ptr v4; + nvobj::persistent_ptr v5; + nvobj::persistent_ptr v6; +}; + +int +main(int argc, char *argv[]) +{ + START(); + + if (argc < 2) { + std::cerr << "usage: " << argv[0] << " file-name" << std::endl; + return 1; + } + + auto path = argv[1]; + auto pop = nvobj::pool::create( + path, "VectorTest: vector_modifiers_type_requirements", + PMEMOBJ_MIN_POOL, S_IWUSR | S_IRUSR); + + auto r = pop.root(); + + try { + nvobj::transaction::run(pop, [&] { + r->v1 = nvobj::make_persistent(); + r->v2 = nvobj::make_persistent(); + r->v3 = nvobj::make_persistent(); + r->v4 = nvobj::make_persistent(10U); + r->v5 = nvobj::make_persistent(); + r->v6 = nvobj::make_persistent(); + }); + + { + /* + * Test if insert(const_iterator, const value_type &) + * works for CopyAssignable and CopyInsertable types. + */ + c1 temp(1); + r->v1->insert(r->v1->cbegin(), temp); + UT_ASSERTeq(r->v1->const_at(0).value, 1); + } + + { + /* + * Test if insert(const_iterator, value_type &&) + * works for MoveAssignable and MoveInsertable types. + */ + c2 temp(1); + r->v2->insert(r->v2->cbegin(), std::move(temp)); + UT_ASSERTeq(r->v2->const_at(0).value, 1); + } + + { + /* + * Test if insert(const_iterator, size_type, const + * value_type &) works for CopyAssignable and + * CopyInsertable types. + */ + c1 temp(1); + r->v1->insert(r->v1->cbegin(), 1, temp); + UT_ASSERTeq(r->v1->const_at(0).value, 1); + } + + { + /* + * Test if insert(const_iterator, InputIt, InputIt) + * works for EmplaceConstructible, Swappable, + * CopyAssignable, CopyConstructible and CopyInsertable + * types. + */ + c1 temp(1); + test_support::random_access_it temp_begin(&temp); + test_support::random_access_it temp_end = + temp_begin + 1; + r->v1->insert(r->v1->cbegin(), temp_begin, temp_end); + UT_ASSERTeq(r->v1->const_at(0).value, 1); + } + + { + /* + * Test if insert(const_iterator, + * std::initializer_list) works for + * EmplaceConstructible, Swappable, CopyAssignable, + * CopyConstructible and CopyInsertable types. + */ + c1 temp(1); + std::initializer_list ilist = {temp}; + r->v1->insert(r->v1->cbegin(), ilist); + UT_ASSERTeq(r->v1->const_at(0).value, 1); + } + + { + /* + * Test if emplace(const_iterator, Args &&...) works for + * MoveAssignable, MoveInsertable and + * EmplaceConstructible types. + */ + r->v2->emplace(r->v2->cbegin(), 1); + UT_ASSERTeq(r->v2->const_at(0).value, 1); + } + + { + /* + * Test if emplace_back(Args &&...) works for + * MoveInsertable and EmplaceConstructible types. + */ + r->v3->emplace_back(1); + UT_ASSERTeq(r->v3->const_at(0).value, 1); + } + + { + /* + * Test if erase(const_iterator) works for + * MoveAssignable types. + */ + UT_ASSERTeq(r->v4->size(), 10); + r->v4->erase(r->v4->cbegin()); + UT_ASSERTeq(r->v4->size(), 9); + } + + { + /* + * Test if erase(const_iterator, const_iterator) works + * for MoveAssignable types. + */ + UT_ASSERTeq(r->v4->size(), 9); + r->v4->erase(r->v4->cbegin(), r->v4->cbegin() + 4); + UT_ASSERTeq(r->v4->size(), 5); + } + + { + /* + * Test if push_back(const value_type &) works for + * CopyInsertable types. + */ + copy_insertable temp(1); + r->v5->push_back(temp); + UT_ASSERTeq(r->v5->const_at(0).value, 1); + } + + { + /* + * Test if push_back(const value_type &&) works for + * MoveInsertable types. + */ + move_insertable temp(1); + r->v6->push_back(std::move(temp)); + UT_ASSERTeq(r->v6->const_at(0).value, 1); + } + + nvobj::transaction::run(pop, [&] { + nvobj::delete_persistent(r->v1); + nvobj::delete_persistent(r->v2); + nvobj::delete_persistent(r->v3); + nvobj::delete_persistent(r->v4); + nvobj::delete_persistent(r->v5); + nvobj::delete_persistent(r->v6); + }); + } catch (std::exception &e) { + UT_FATALexc(e); + } + + pop.close(); + + return 0; +} diff --git a/tests/vector_range/vector_range.cpp b/tests/vector_range/vector_range.cpp new file mode 100644 index 0000000..00105ce --- /dev/null +++ b/tests/vector_range/vector_range.cpp @@ -0,0 +1,214 @@ +/* + * Copyright 2019, Intel Corporation + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * * Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "unittest.hpp" + +#include +#include +#include +#include +#include + +namespace pmemobj = pmem::obj; +namespace pmemobj_exp = pmemobj::experimental; + +using vec_type = pmemobj_exp::vector; + +struct root { + pmemobj::persistent_ptr pptr; +}; + +int +main(int argc, char *argv[]) +{ + START(); + + if (argc < 2) { + std::cerr << "usage: " << argv[0] << " file-name " << std::endl; + return 1; + } + + auto path = argv[1]; + auto pop = pmemobj::pool::create( + path, "VectorTest", PMEMOBJ_MIN_POOL, S_IWUSR | S_IRUSR); + auto r = pop.root(); + + try { + pmemobj::transaction::run(pop, [&] { + r->pptr = pmemobj::make_persistent(10U, 1); + }); + } catch (std::exception &e) { + UT_FATALexc(e); + } + + vec_type &pmem_vec = *(r->pptr); + const vec_type &const_pmem_vec = *(r->pptr); + + /* test std::out_of_range exceptions */ + try { + pmemobj::transaction::run(pop, [&] { + auto slice = + pmem_vec.range(0, 10); /* should not throw */ + (void)slice; + }); + } catch (std::exception &e) { + UT_FATALexc(e); + } + + try { + pmemobj::transaction::run(pop, [&] { + auto slice = + pmem_vec.crange(0, 10); /* should not throw */ + (void)slice; + }); + } catch (std::exception &e) { + UT_FATALexc(e); + } + + try { + pmemobj::transaction::run(pop, [&] { + pmemobj_exp::slice slice = + const_pmem_vec.range(0, + 10); /* should not throw */ + (void)slice; + }); + } catch (std::exception &e) { + UT_FATALexc(e); + } + + try { + pmemobj::transaction::run(pop, [&] { + auto slice = + pmem_vec.range(0, 10, 3); /* should not throw */ + (void)slice; + }); + } catch (std::exception &e) { + UT_FATALexc(e); + } + + bool exception_thrown = false; + try { + pmemobj::transaction::run(pop, [&] { + auto slice = pmem_vec.range(0, 11); /* should throw */ + (void)slice; + }); + UT_ASSERT(0); + } catch (std::out_of_range &) { + exception_thrown = true; + } catch (std::exception &e) { + UT_FATALexc(e); + } + UT_ASSERT(exception_thrown); + + exception_thrown = false; + try { + pmemobj::transaction::run(pop, [&] { + auto slice = + pmem_vec.range(0, 11, 3); /* should throw */ + (void)slice; + }); + UT_ASSERT(0); + } catch (std::out_of_range &) { + exception_thrown = true; + } catch (std::exception &e) { + UT_FATALexc(e); + } + UT_ASSERT(exception_thrown); + + exception_thrown = false; + try { + pmemobj::transaction::run(pop, [&] { + pmemobj_exp::slice slice = + const_pmem_vec.range(0, 11); /* should throw */ + (void)slice; + }); + UT_ASSERT(0); + } catch (std::out_of_range &) { + exception_thrown = true; + } catch (std::exception &e) { + UT_FATALexc(e); + } + UT_ASSERT(exception_thrown); + + exception_thrown = false; + try { + pmemobj::transaction::run(pop, [&] { + auto slice = pmem_vec.crange(0, 11); /* should throw */ + (void)slice; + }); + UT_ASSERT(0); + } catch (std::out_of_range &) { + exception_thrown = true; + } catch (std::exception &e) { + UT_FATALexc(e); + } + UT_ASSERT(exception_thrown); + + /* test returned values */ + try { + pmemobj::transaction::run(pop, [&] { + auto slice1 = pmem_vec.range(0, 3); + + UT_ASSERTeq(&pmem_vec.front(), slice1.begin()); + UT_ASSERTeq(&pmem_vec.front() + 3, slice1.end()); + + auto slice2 = pmem_vec.range(0, 3, 1); + + UT_ASSERTeq(&pmem_vec.front(), &*slice2.begin()); + UT_ASSERTeq(&pmem_vec.front() + 3, &*slice2.end()); + + auto slice3 = pmem_vec.range(0, 10, 11); + + UT_ASSERTeq(&pmem_vec.front(), &*slice3.begin()); + UT_ASSERTeq(&pmem_vec.front() + 10, &*slice3.end()); + + pmemobj_exp::slice slice4 = + const_pmem_vec.range(0, 3); + + UT_ASSERTeq(&const_pmem_vec.front(), slice4.begin()); + UT_ASSERTeq(&const_pmem_vec.front() + 3, slice4.end()); + + auto slice5 = pmem_vec.crange(0, 3); + + UT_ASSERTeq(&pmem_vec.front(), slice5.begin()); + UT_ASSERTeq(&pmem_vec.front() + 3, slice5.end()); + + pmemobj::delete_persistent(r->pptr); + }); + } catch (std::exception &e) { + UT_FATALexc(e); + } + + pop.close(); + + return 0; +} diff --git a/tests/vector_std_arg/vector_std_arg.cpp b/tests/vector_std_arg/vector_std_arg.cpp new file mode 100644 index 0000000..85e4295 --- /dev/null +++ b/tests/vector_std_arg/vector_std_arg.cpp @@ -0,0 +1,105 @@ +/* + * Copyright 2019, Intel Corporation + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * * Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "unittest.hpp" + +#include +#include + +#include + +namespace nvobj = pmem::obj; +namespace pmem_exp = nvobj::experimental; + +using pmem_vec = pmem_exp::vector; +using std_vec = std::vector; + +struct root { + nvobj::persistent_ptr pptr; +}; + +void +check_vector(const pmem_vec &v1, const std_vec &v2) +{ + UT_ASSERTeq(v1.size(), v2.size()); + + for (unsigned i = 0; i < v1.size(); ++i) + UT_ASSERTeq(v1[i], v2[i]); +} + +int +main(int argc, char *argv[]) +{ + START(); + + if (argc < 2) { + std::cerr << "usage: " << argv[0] << " file-name" << std::endl; + return 1; + } + auto path = argv[1]; + auto pop = nvobj::pool::create( + path, "VectorTest", PMEMOBJ_MIN_POOL, S_IWUSR | S_IRUSR); + + auto r = pop.root(); + + try { + std_vec stdvector(10U, 1); + + nvobj::transaction::run(pop, [&] { + r->pptr = nvobj::make_persistent(stdvector); + }); + + pmem_vec &pvector = *(r->pptr); + + check_vector(pvector, stdvector); + + stdvector.assign(20U, 2); + pvector.assign(stdvector); + + check_vector(pvector, stdvector); + + stdvector = std_vec(30U, 3); + pvector = stdvector; + + check_vector(pvector, stdvector); + + nvobj::transaction::run(pop, [&] { + nvobj::delete_persistent(r->pptr); + }); + } catch (std::exception &e) { + UT_FATALexc(e); + } + + pop.close(); + + return 0; +} diff --git a/travis.yml b/travis.yml new file mode 100644 index 0000000..73209c5 --- /dev/null +++ b/travis.yml @@ -0,0 +1,32 @@ +dist: trusty + +sudo: required + +language: cpp + +services: + - docker + +env: + matrix: + - TYPE=normal OS=ubuntu OS_VER=18.04 PUSH_IMAGE=1 + - TYPE=normal OS=fedora OS_VER=28 PUSH_IMAGE=1 AUTO_DOC_UPDATE=1 + - TYPE=normal OS=ubuntu OS_VER=18.04 COVERAGE=1 + - TYPE=coverity OS=ubuntu OS_VER=18.04 + +before_install: + - echo $TRAVIS_COMMIT_RANGE + - export HOST_WORKDIR=`pwd` + - export GITHUB_REPO=pmem/libpmemobj-cpp + - export DOCKERHUB_REPO=pmem/libpmemobj-cpp + - cd utils/docker + - ./pull-or-rebuild-image.sh + - if [[ -f push_image_to_repo_flag ]]; then PUSH_THE_IMAGE=1; fi + - if [[ -f skip_build_package_check ]]; then export SKIP_CHECK=1; fi + - rm -f push_image_to_repo_flag skip_build_package_check + +script: + - ./build.sh + +after_success: + - if [[ $PUSH_THE_IMAGE -eq 1 ]]; then images/push-image.sh $OS-$OS_VER; fi diff --git a/utils/check_license/check-headers.sh b/utils/check_license/check-headers.sh new file mode 100755 index 0000000..a2d2a79 --- /dev/null +++ b/utils/check_license/check-headers.sh @@ -0,0 +1,213 @@ +#!/usr/bin/env bash +# +# Copyright 2016-2018, Intel Corporation +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# +# * Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# +# * Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in +# the documentation and/or other materials provided with the +# distribution. +# +# * Neither the name of the copyright holder nor the names of its +# contributors may be used to endorse or promote products derived +# from this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +# + +# check-headers.sh - check copyright and license in source files + +SELF=$0 + +function usage() { + echo "Usage: $SELF [-h|-v|-a]" + echo " -h, --help this help message" + echo " -v, --verbose verbose mode" + echo " -a, --all check all files (only modified files are checked by default)" +} + +if [ "$#" -lt 3 ]; then + usage >&2 + exit 2 +fi + +SOURCE_ROOT=$1 +shift +CHECK_LICENSE=$1 +shift +LICENSE=$1 +shift + +PATTERN=`mktemp` +TMP=`mktemp` +TMP2=`mktemp` +TEMPFILE=`mktemp` +rm -f $PATTERN $TMP $TMP2 + +function exit_if_not_exist() +{ + if [ ! -f $1 ]; then + echo "Error: file $1 does not exist. Exiting..." >&2 + exit 1 + fi +} + +if [ "$1" == "-h" -o "$1" == "--help" ]; then + usage + exit 0 +fi + +exit_if_not_exist $LICENSE +exit_if_not_exist $CHECK_LICENSE + +export GIT="git -C ${SOURCE_ROOT}" +$GIT rev-parse || exit 1 + +if [ -f $SOURCE_ROOT/.git/shallow ]; then + SHALLOW_CLONE=1 + echo + echo "Warning: This is a shallow clone. Checking dates in copyright headers" + echo " will be skipped in case of files that have no history." + echo +else + SHALLOW_CLONE=0 +fi + +VERBOSE=0 +CHECK_ALL=0 +while [ "$1" != "" ]; do + case $1 in + -v|--verbose) + VERBOSE=1 + ;; + -a|--all) + CHECK_ALL=1 + ;; + esac + shift +done + +if [ $CHECK_ALL -eq 0 ]; then + CURRENT_COMMIT=$($GIT log --pretty=%H -1) + MERGE_BASE=$($GIT merge-base HEAD origin/master 2>/dev/null) + [ -z $MERGE_BASE ] && \ + MERGE_BASE=$($GIT log --pretty="%cN:%H" | grep GitHub | head -n1 | cut -d: -f2) + [ -z $MERGE_BASE -o "$CURRENT_COMMIT" = "$MERGE_BASE" ] && \ + CHECK_ALL=1 +fi + +if [ $CHECK_ALL -eq 1 ]; then + echo "Checking copyright headers of all files..." + GIT_COMMAND="ls-tree -r --name-only HEAD" +else + echo + echo "Warning: will check copyright headers of modified files only," + echo " in order to check all files issue the following command:" + echo " $ $SELF -a" + echo " (e.g.: $ $SELF $SOURCE_ROOT $CHECK_LICENSE $LICENSE -a)" + echo + echo "Checking copyright headers of modified files only..." + GIT_COMMAND="diff --name-only $MERGE_BASE $CURRENT_COMMIT" +fi + +FILES=$($GIT $GIT_COMMAND | ${SOURCE_ROOT}/utils/check_license/file-exceptions.sh | \ + grep -E -e '*\.[chs]$' -e '*\.[ch]pp$' -e '*\.sh$' \ + -e '*\.py$' -e '*\.map$' -e 'Makefile*' -e 'TEST*' \ + -e '/common.inc$' -e '/match$' -e '/check_whitespace$' \ + -e 'LICENSE$' -e 'CMakeLists.txt$' -e '*\.cmake$' | \ + xargs) + +# jemalloc.mk has to be checked always, because of the grep rules above +FILES="$FILES src/jemalloc/jemalloc.mk" + +# create a license pattern file +$CHECK_LICENSE create $LICENSE $PATTERN +[ $? -ne 0 ] && exit 1 + +RV=0 +for file in $FILES ; do + # The src_path is a path which should be used in every command except git. + # git is called with -C flag so filepaths should be relative to SOURCE_ROOT + src_path="${SOURCE_ROOT}/$file" + [ ! -f $src_path ] && continue + # ensure that file is UTF-8 encoded + ENCODING=`file -b --mime-encoding $src_path` + iconv -f $ENCODING -t "UTF-8" $src_path > $TEMPFILE + + YEARS=`$CHECK_LICENSE check-pattern $PATTERN $TEMPFILE $src_path` + if [ $? -ne 0 ]; then + echo -n $YEARS + RV=1 + else + HEADER_FIRST=`echo $YEARS | cut -d"-" -f1` + HEADER_LAST=` echo $YEARS | cut -d"-" -f2` + + if [ $SHALLOW_CLONE -eq 0 ]; then + $GIT log --no-merges --format="%ai %aE" -- $file | sort > $TMP + else + # mark the grafted commits (commits with no parents) + $GIT log --no-merges --format="%ai %aE grafted-%p-commit" -- $file | sort > $TMP + fi + + # skip checking dates for non-Intel commits + [[ ! $(tail -n1 $TMP) =~ "@intel.com" ]] && continue + + # skip checking dates for new files + [ $(cat $TMP | wc -l) -le 1 ] && continue + + # grep out the grafted commits (commits with no parents) + # and skip checking dates for non-Intel commits + grep -v -e "grafted--commit" $TMP | grep -e "@intel.com" > $TMP2 + + [ $(cat $TMP2 | wc -l) -eq 0 ] && continue + + FIRST=`head -n1 $TMP2` + LAST=` tail -n1 $TMP2` + + COMMIT_FIRST=`echo $FIRST | cut -d"-" -f1` + COMMIT_LAST=` echo $LAST | cut -d"-" -f1` + if [ "$COMMIT_FIRST" != "" -a "$COMMIT_LAST" != "" ]; then + if [ $HEADER_LAST -lt $COMMIT_LAST ]; then + if [ $HEADER_FIRST -lt $COMMIT_FIRST ]; then + COMMIT_FIRST=$HEADER_FIRST + fi + COMMIT_LAST=`date +%G` + if [ $COMMIT_FIRST -eq $COMMIT_LAST ]; then + NEW=$COMMIT_LAST + else + NEW=$COMMIT_FIRST-$COMMIT_LAST + fi + echo "$file:1: error: wrong copyright date: (is: $YEARS, should be: $NEW)" >&2 + RV=1 + fi + else + echo "error: unknown commit dates in file: $file" >&2 + RV=1 + fi + fi +done +rm -f $TMP $TMP2 $TEMPFILE + +# check if error found +if [ $RV -eq 0 ]; then + echo "Copyright headers are OK." +else + echo "Error(s) in copyright headers found!" >&2 +fi +exit $RV diff --git a/utils/check_license/check-license.c b/utils/check_license/check-license.c new file mode 100644 index 0000000..0eeae26 --- /dev/null +++ b/utils/check_license/check-license.c @@ -0,0 +1,511 @@ +/* + * Copyright 2016-2017, Intel Corporation + * Copyright (c) 2016, Microsoft Corporation. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * * Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +/* + * check-license.c -- check the license in the file + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define LICENSE_MAX_LEN 2048 +#define COPYRIGHT "Copyright " +#define COPYRIGHT_LEN 10 +#define COPYRIGHT_SYMBOL "(c) " +#define COPYRIGHT_SYMBOL_LEN 4 +#define YEAR_MIN 1900 +#define YEAR_MAX 9999 +#define YEAR_INIT_MIN 9999 +#define YEAR_INIT_MAX 0 +#define YEAR_LEN 4 +#define LICENSE_BEG "Redistribution and use" +#define LICENSE_END "THE POSSIBILITY OF SUCH DAMAGE." +#define DIFF_LEN 50 +#define COMMENT_STR_LEN 5 + +#define STR_MODE_CREATE "create" +#define STR_MODE_PATTERN "check-pattern" +#define STR_MODE_LICENSE "check-license" + +#define ERROR(fmt, ...) fprintf(stderr, "error: " fmt "\n", __VA_ARGS__) +#define ERROR2(fmt, ...) fprintf(stderr, fmt "\n", __VA_ARGS__) + +/* + * help_str -- string for the help message + */ +static const char * const help_str = +"Usage: %s [filename]\n" +"\n" +"Modes:\n" +" create \n" +" - create a license pattern file \n" +" from the license text file \n" +"\n" +" check-pattern \n" +" - check if a license in \n" +" matches the license pattern in ,\n" +" if it does, copyright dates are printed out (see below)\n" +"\n" +" check-license \n" +" - check if a license in \n" +" matches the license text in ,\n" +" if it does, copyright dates are printed out (see below)\n" +"\n" +"In case of 'check_pattern' and 'check_license' modes,\n" +"if the license is correct, it prints out copyright dates\n" +"in the following format: OLDEST_YEAR-NEWEST_YEAR\n" +"\n" +"Return value: returns 0 on success and -1 on error.\n" +"\n"; + +/* + * read_pattern -- read the pattern from the 'path_pattern' file to 'pattern' + */ +static int +read_pattern(const char *path_pattern, char *pattern) +{ + int file_pattern; + ssize_t ret; + + if ((file_pattern = open(path_pattern, O_RDONLY)) == -1) { + ERROR("open(): %s: %s", strerror(errno), path_pattern); + return -1; + } + + ret = read(file_pattern, pattern, LICENSE_MAX_LEN); + close(file_pattern); + + if (ret == -1) { + ERROR("read(): %s: %s", strerror(errno), path_pattern); + return -1; + } else if (ret != LICENSE_MAX_LEN) { + ERROR("read(): incorrect format of the license pattern" + " file (%s)", path_pattern); + return -1; + } + return 0; +} + +/* + * write_pattern -- write 'pattern' to the 'path_pattern' file + */ +static int +write_pattern(const char *path_pattern, char *pattern) +{ + int file_pattern; + ssize_t ret; + + if ((file_pattern = open(path_pattern, O_WRONLY | O_CREAT | O_EXCL, + S_IRUSR | S_IRGRP | S_IROTH)) == -1) { + ERROR("open(): %s: %s", strerror(errno), path_pattern); + return -1; + } + + ret = write(file_pattern, pattern, LICENSE_MAX_LEN); + close(file_pattern); + + if (ret < LICENSE_MAX_LEN) { + ERROR("write(): %s: %s", strerror(errno), path_pattern); + return -1; + } + + return 0; +} + +/* + * strstr2 -- locate two substrings in the string + */ +static int +strstr2(const char *str, const char *sub1, const char *sub2, + char **pos1, char **pos2) +{ + *pos1 = strstr(str, sub1); + *pos2 = strstr(str, sub2); + if (*pos1 == NULL || *pos2 == NULL) + return -1; + return 0; +} + +/* + * format_license -- remove comments and redundant whitespaces from the license + */ +static void +format_license(char *license, size_t length) +{ + char comment_str[COMMENT_STR_LEN]; + char *comment = license; + size_t comment_len; + int was_space; + size_t w, r; + + /* detect a comment string */ + while (*comment != '\n') + comment--; + /* is there any comment? */ + if (comment + 1 != license) { + /* separate out a comment */ + strncpy(comment_str, comment, COMMENT_STR_LEN); + comment = comment_str + 1; + while (isspace(*comment)) + comment++; + while (!isspace(*comment)) + comment++; + *comment = '\0'; + comment_len = strlen(comment_str); + + /* replace comments with spaces */ + if (comment_len > 2) { + while ((comment = strstr(license, comment_str)) != NULL) + for (w = 1; w < comment_len; w++) + comment[w] = ' '; + } else { + while ((comment = strstr(license, comment_str)) != NULL) + comment[1] = ' '; + } + } + + /* replace multiple spaces with one space */ + was_space = 0; + for (r = w = 0; r < length; r++) { + if (!isspace(license[r])) { + if (was_space) { + license[w++] = ' '; + was_space = 0; + } + if (w < r) + license[w] = license[r]; + w++; + } else { + if (!was_space) + was_space = 1; + } + } + license[w] = '\0'; +} + +/* + * analyze_license -- check correctness of the license + */ +static int +analyze_license(const char *path_to_check, + char *buffer, + char **license) +{ + char *_license; + size_t _length; + char *beg_str, *end_str; + + if (strstr2(buffer, LICENSE_BEG, LICENSE_END, + &beg_str, &end_str)) { + if (!beg_str) + ERROR2("%s:1: error: incorrect license" + " (license should start with the string '%s')", + path_to_check, LICENSE_BEG); + else + ERROR2("%s:1: error: incorrect license" + " (license should end with the string '%s')", + path_to_check, LICENSE_END); + return -1; + } + + _license = beg_str; + assert((uintptr_t)end_str > (uintptr_t)beg_str); + _length = (size_t)(end_str - beg_str) + strlen(LICENSE_END); + _license[_length] = '\0'; + + format_license(_license, _length); + + *license = _license; + + return 0; +} + +/* + * create_pattern -- create 'pattern' from the 'path_license' file + */ +static int +create_pattern(const char *path_license, char *pattern) +{ + char buffer[LICENSE_MAX_LEN]; + char *license; + ssize_t ret; + int file_license; + + if ((file_license = open(path_license, O_RDONLY)) == -1) { + ERROR("open(): %s: %s", strerror(errno), path_license); + return -1; + } + + memset(buffer, 0, sizeof(buffer)); + ret = read(file_license, buffer, LICENSE_MAX_LEN); + close(file_license); + + if (ret == -1) { + ERROR("read(): %s: %s", strerror(errno), path_license); + return -1; + } + + if (analyze_license(path_license, buffer, &license) == -1) + return -1; + + memset(pattern, 0, LICENSE_MAX_LEN); + strncpy(pattern, license, strlen(license) + 1); + + return 0; +} + +/* + * print_diff -- print the first difference between 'license' and 'pattern' + */ +static void +print_diff(char *license, char *pattern, size_t len) +{ + size_t i = 0; + + while (i < len && license[i] == pattern[i]) + i++; + license[i + 1] = '\0'; + pattern[i + 1] = '\0'; + + i = (i - DIFF_LEN > 0) ? (i - DIFF_LEN) : 0; + while (i > 0 && license[i] != ' ') + i--; + + fprintf(stderr, " The first difference is at the end of the line:\n"); + fprintf(stderr, " * License: %s\n", license + i); + fprintf(stderr, " * Pattern: %s\n", pattern + i); +} + +/* + * verify_license -- compare 'license' with 'pattern' and check correctness + * of the copyright line + */ +static int +verify_license(const char *path_to_check, char *pattern, const char *filename) +{ + char buffer[LICENSE_MAX_LEN]; + char *license, *copyright; + int file_to_check; + ssize_t ret; + int year_first, year_last; + int min_year_first = YEAR_INIT_MIN; + int max_year_last = YEAR_INIT_MAX; + char *err_str = NULL; + const char *name_to_print = filename ? filename : path_to_check; + + if ((file_to_check = open(path_to_check, O_RDONLY)) == -1) { + ERROR("open(): %s: %s", strerror(errno), path_to_check); + return -1; + } + + memset(buffer, 0, sizeof(buffer)); + ret = read(file_to_check, buffer, LICENSE_MAX_LEN); + close(file_to_check); + + if (ret == -1) { + ERROR("read(): %s: %s", strerror(errno), name_to_print); + return -1; + } + + if (analyze_license(path_to_check, buffer, &license) == -1) + return -1; + + /* check the copyright notice */ + copyright = buffer; + while ((copyright = strstr(copyright, COPYRIGHT)) != NULL) { + copyright += COPYRIGHT_LEN; + + /* skip the copyright symbol '(c)' if any */ + if (strncmp(copyright, COPYRIGHT_SYMBOL, + COPYRIGHT_SYMBOL_LEN) == 0) + copyright += COPYRIGHT_SYMBOL_LEN; + + /* look for the first year */ + if (!isdigit(*copyright)) { + err_str = "no digit just after the 'Copyright ' string"; + break; + } + + year_first = atoi(copyright); + if (year_first < YEAR_MIN || year_first > YEAR_MAX) { + err_str = "the first year is wrong"; + break; + } + copyright += YEAR_LEN; + + if (year_first < min_year_first) + min_year_first = year_first; + if (year_first > max_year_last) + max_year_last = year_first; + + /* check if there is the second year */ + if (*copyright == ',') + continue; + else if (*copyright != '-') { + err_str = "'-' or ',' expected after the first year"; + break; + } + copyright++; + + /* look for the second year */ + if (!isdigit(*copyright)) { + err_str = "no digit after '-'"; + break; + } + + year_last = atoi(copyright); + if (year_last < YEAR_MIN || year_last > YEAR_MAX) { + err_str = "the second year is wrong"; + break; + } + copyright += YEAR_LEN; + + if (year_last > max_year_last) + max_year_last = year_last; + + if (*copyright != ',') { + err_str = "',' expected after the second year"; + break; + } + } + + if (!err_str && min_year_first == YEAR_INIT_MIN) + err_str = "no 'Copyright ' string found"; + + if (err_str) + /* found an error in the copyright notice */ + ERROR2("%s:1: error: incorrect copyright notice: %s", + name_to_print, err_str); + + /* now check the license */ + if (memcmp(license, pattern, strlen(pattern)) != 0) { + ERROR2("%s:1: error: incorrect license", name_to_print); + print_diff(license, pattern, strlen(pattern)); + return -1; + } + + if (err_str) + return -1; + + /* all checks passed */ + if (min_year_first != max_year_last && max_year_last != YEAR_INIT_MAX) { + printf("%i-%i\n", min_year_first, max_year_last); + } else { + printf("%i\n", min_year_first); + } + + return 0; +} + +/* + * mode_create_pattern_file -- 'create' mode function + */ +static int +mode_create_pattern_file(const char *path_license, const char *path_pattern) +{ + char pattern[LICENSE_MAX_LEN]; + + if (create_pattern(path_license, pattern) == -1) + return -1; + + return write_pattern(path_pattern, pattern); +} + +/* + * mode_check_pattern -- 'check_pattern' mode function + */ +static int +mode_check_pattern(const char *path_license, const char *path_to_check) +{ + char pattern[LICENSE_MAX_LEN]; + + if (create_pattern(path_license, pattern) == -1) + return -1; + + return verify_license(path_to_check, pattern, NULL); +} + +/* + * mode_check_license -- 'check_license' mode function + */ +static int +mode_check_license(const char *path_pattern, const char *path_to_check, + const char *filename) +{ + char pattern[LICENSE_MAX_LEN]; + + if (read_pattern(path_pattern, pattern) == -1) + return -1; + + return verify_license(path_to_check, pattern, filename); +} + +int +main(int argc, char *argv[]) +{ + if (strcmp(argv[1], STR_MODE_CREATE) == 0) { + if (argc != 4) + goto invalid_args; + + return mode_create_pattern_file(argv[2], argv[3]); + + } else if (strcmp(argv[1], STR_MODE_PATTERN) == 0) { + if (argc != 5) + goto invalid_args; + + return mode_check_license(argv[2], argv[3], argv[4]); + + } else if (strcmp(argv[1], STR_MODE_LICENSE) == 0) { + if (argc != 4) + goto invalid_args; + + return mode_check_pattern(argv[2], argv[3]); + + } else { + ERROR("wrong mode: %s\n", argv[1]); + } + +invalid_args: + printf(help_str, argv[0]); + return -1; +} diff --git a/utils/check_license/file-exceptions.sh b/utils/check_license/file-exceptions.sh new file mode 100755 index 0000000..eab6c41 --- /dev/null +++ b/utils/check_license/file-exceptions.sh @@ -0,0 +1,36 @@ +#!/bin/sh -e +# +# Copyright 2016-2018, Intel Corporation +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# +# * Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# +# * Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in +# the documentation and/or other materials provided with the +# distribution. +# +# * Neither the name of the copyright holder nor the names of its +# contributors may be used to endorse or promote products derived +# from this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +# + +# file-exceptions.sh - filter out files not checked for copyright and license + +grep -v -E -e 'tests/external/libcxx/' diff --git a/utils/check_whitespace b/utils/check_whitespace new file mode 100755 index 0000000..091002b --- /dev/null +++ b/utils/check_whitespace @@ -0,0 +1,229 @@ +#!/usr/bin/env perl +# +# Copyright 2015-2018, Intel Corporation +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# +# * Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# +# * Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in +# the documentation and/or other materials provided with the +# distribution. +# +# * Neither the name of the copyright holder nor the names of its +# contributors may be used to endorse or promote products derived +# from this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +# +# check_whitespace -- scrub source tree for whitespace errors +# + +use strict; +use warnings; + +use File::Basename; +use File::Find; +use Encode; +use v5.16; + +my $Me = $0; +$Me =~ s,.*/,,; + +$SIG{HUP} = $SIG{INT} = $SIG{TERM} = $SIG{__DIE__} = sub { + die @_ if $^S; + + my $errstr = shift; + + die "$Me: ERROR: $errstr"; +}; + +my $Errcount = 0; + +# +# err -- emit error, keep total error count +# +sub err { + warn @_, "\n"; + $Errcount++; +} + +# +# decode_file_as_string -- slurp an entire file into memory and decode +# +sub decode_file_as_string { + my ($full, $file) = @_; + my $fh; + open($fh, '<', $full) or die "$full $!\n"; + + local $/; + $_ = <$fh>; + close $fh; + + # check known encodings or die + my $decoded; + my @encodings = ("UTF-8", "UTF-16", "UTF-16LE", "UTF-16BE"); + + foreach my $enc (@encodings) { + eval { $decoded = decode( $enc, $_, Encode::FB_CROAK ) }; + + if (!$@) { + $decoded =~ s/\R/\n/g; + return $decoded; + } + } + + die "$Me: ERROR: Unknown file encoding"; +} + +# +# check_whitespace -- run the checks on the given file +# +sub check_whitespace { + my ($full, $file) = @_; + + my $line = 0; + my $eol; + my $nf = 0; + my $fstr = decode_file_as_string($full, $file); + + for (split /^/, $fstr) { + $line++; + $eol = /[\n]/s; + if (/^\.nf$/) { + err("$full:$line: ERROR: nested .nf") if $nf; + $nf = 1; + } elsif (/^\.fi$/) { + $nf = 0; + } elsif ($nf == 0) { + chomp; + err("$full:$line: ERROR: trailing whitespace") if /\s$/; + err("$full:$line: ERROR: spaces before tabs") if / \t/; + } + } + + err("$full:$line: .nf without .fi") if $nf; + err("$full:$line: noeol") unless $eol; +} + +sub check_whitespace_with_exc { + my ($full) = @_; + + $_ = $full; + + return 0 if /^[.\/]*src\/jemalloc.*/; + return 0 if /^[.\/]*src\/common\/queue\.h/; + return 0 if /^[.\/]*src\/common\/valgrind\/.*\.h/; + + $_ = basename($full); + + return 0 unless /^(README.*|LICENSE.*|Makefile.*|CMakeLists.txt|.gitignore|TEST.*|RUNTESTS|check_whitespace|.*\.([chp13s]|sh|map|cpp|hpp|inc|PS1|ps1|py|md|cmake))$/; + return 0 if -z; + + check_whitespace($full, $_); + return 1; +} + +my $verbose = 0; +my $force = 0; +my $recursive = 0; + +sub check { + my ($file) = @_; + my $r; + + if ($force) { + $r = check_whitespace($file, basename($file)); + } else { + $r = check_whitespace_with_exc($file); + } + + if ($verbose) { + if ($r == 0) { + printf("skipped $file\n"); + } else { + printf("checked $file\n"); + } + } +} + +my @files = (); + +foreach my $arg (@ARGV) { + if ($arg eq '-v') { + $verbose = 1; + next; + } + if ($arg eq '-f') { + $force = 1; + next; + } + if ($arg eq '-r') { + $recursive = 1; + next; + } + if ($arg eq '-g') { + @files = `git ls-tree -r --name-only HEAD`; + chomp(@files); + next; + } + if ($arg eq '-h') { + printf "Options: + -g - check all files tracked by git + -r dir - recursively check all files in specified directory + -v verbose - print whether file was checked or not + -f force - disable blacklist\n"; + exit 1; + } + + if ($recursive == 1) { + find(sub { + my $full = $File::Find::name; + + if (!$force && + ($full eq './.git' || + $full eq './src/jemalloc' || + $full eq './src/debug' || + $full eq './src/nondebug' || + $full eq './rpmbuild' || + $full eq './dpkgbuild')) { + $File::Find::prune = 1; + return; + } + + return unless -f; + + push @files, $full; + }, $arg); + + $recursive = 0; + next; + } + + push @files, $arg; +} + +if (!@files) { + printf "Empty file list!\n"; +} + +foreach (@files) { + check($_); +} + +exit $Errcount; diff --git a/utils/cppstyle b/utils/cppstyle new file mode 100755 index 0000000..d29c58f --- /dev/null +++ b/utils/cppstyle @@ -0,0 +1,72 @@ +#!/usr/bin/perl -w +# +# Copyright 2017, Intel Corporation +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# +# * Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# +# * Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in +# the documentation and/or other materials provided with the +# distribution. +# +# * Neither the name of the copyright holder nor the names of its +# contributors may be used to endorse or promote products derived +# from this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +use strict; +use Text::Diff; + +my $clangfmt = shift or die; +my $mode = shift or die; + +sub check { + my ($file) = @_; + my $original; + my $formatted; + + $formatted = `$clangfmt -style=file "$file"`; + + if ($mode eq 'check') { + local $/=undef; + open FILE, "$file" or die "Couldn't open file: $file"; + binmode FILE; + $original = ; + close FILE; + + my $diff = diff \$original, \$formatted; + + if ($diff ne "") { + print "Style check using $clangfmt for file $file failed\n"; + print $diff; + die "Style check using $clangfmt for file $file failed\n"; + } + } elsif ($mode eq 'format') { + local $/=undef; + open FILE, '>', "$file" or die "Couldn't open file: $file"; + print FILE "$formatted"; + close FILE; + } else { + die 'unknown mode'; + } +} + +foreach(@ARGV) { + check($_) +} diff --git a/utils/docker/0001-travis-fix-travisci_build_coverity_scan.sh.patch b/utils/docker/0001-travis-fix-travisci_build_coverity_scan.sh.patch new file mode 100644 index 0000000..9738942 --- /dev/null +++ b/utils/docker/0001-travis-fix-travisci_build_coverity_scan.sh.patch @@ -0,0 +1,27 @@ +From b5179dc4822eaab192361da05aa95d98f523960f Mon Sep 17 00:00:00 2001 +From: Lukasz Dorau +Date: Mon, 7 May 2018 12:05:40 +0200 +Subject: [PATCH] travis: fix travisci_build_coverity_scan.sh + +--- + travisci_build_coverity_scan.sh | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/travisci_build_coverity_scan.sh b/travisci_build_coverity_scan.sh +index ad9d4afcf..562b08bcc 100644 +--- a/travisci_build_coverity_scan.sh ++++ b/travisci_build_coverity_scan.sh +@@ -92,8 +92,8 @@ response=$(curl \ + --form description="Travis CI build" \ + $UPLOAD_URL) + status_code=$(echo "$response" | sed -n '$p') +-if [ "$status_code" != "201" ]; then ++if [ "$status_code" != "200" ]; then + TEXT=$(echo "$response" | sed '$d') +- echo -e "\033[33;1mCoverity Scan upload failed: $TEXT.\033[0m" ++ echo -e "\033[33;1mCoverity Scan upload failed: $response.\033[0m" + exit 1 + fi +-- +2.13.6 + diff --git a/utils/docker/build.sh b/utils/docker/build.sh new file mode 100755 index 0000000..4b0a9d2 --- /dev/null +++ b/utils/docker/build.sh @@ -0,0 +1,130 @@ +#!/usr/bin/env bash +# +# Copyright 2017-2018, Intel Corporation +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# +# * Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# +# * Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in +# the documentation and/or other materials provided with the +# distribution. +# +# * Neither the name of the copyright holder nor the names of its +# contributors may be used to endorse or promote products derived +# from this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +# +# build-local.sh - runs a Docker container from a Docker image with environment +# prepared for running libpmemobj-cpp tests and run those tests. +# +# +# Notes: +# - run this script from its location or set the variable 'HOST_WORKDIR' to +# where the root of this project is on the host machine, +# - set variables 'OS' and 'OS_VER' properly to a system you want to build this +# repo on (for proper values take a look on the list of Dockerfiles at the +# utils/docker/images directory), eg. OS=ubuntu, OS_VER=16.04. +# + +set -e + +# Environment variables that can be customized (default values are after dash): +export KEEP_CONTAINER=${KEEP_CONTAINER:-0} + + +if [[ -z "$OS" || -z "$OS_VER" ]]; then + echo "ERROR: The variables OS and OS_VER have to be set " \ + "(eg. OS=ubuntu, OS_VER=16.04)." + exit 1 +fi + +if [[ -z "$HOST_WORKDIR" ]]; then + HOST_WORKDIR=$(readlink -f ../..) +fi + +chmod -R a+w $HOST_WORKDIR + +if [[ "$TRAVIS_EVENT_TYPE" == "cron" || "$TRAVIS_BRANCH" == "coverity_scan" ]]; then + if [[ $TYPE != coverity ]]; then + echo "Skipping non-Coverity job for cron/Coverity build" + exit 0 + fi +else + if [[ $TYPE = "coverity" ]]; then + echo "Skipping Coverity job for non cron/Coverity build" + exit 0 + fi +fi + +imageName=${DOCKERHUB_REPO}:${OS}-${OS_VER} +containerName=libpmemobj-cpp-${OS}-${OS_VER} + +if [[ "$command" == "" ]]; then + case $TYPE in + normal) + command="./run-build.sh"; + ;; + coverity) + command="./run-coverity.sh"; + ;; + esac +fi + +if [ "$COVERAGE" = "1" ]; then + docker_opts="${docker_opts} `bash <(curl -s https://codecov.io/env)`"; +fi + +if [ -n "$DNS_SERVER" ]; then DNS_SETTING=" --dns=$DNS_SERVER "; fi + +# Only run doc update on pmem/libpmemobj-cpp master branch +if [[ "$TRAVIS_BRANCH" != "master" || "$TRAVIS_PULL_REQUEST" != "false" || "$TRAVIS_REPO_SLUG" != "${GITHUB_REPO}" ]]; then + AUTO_DOC_UPDATE=0 +fi + +WORKDIR=/libpmemobj-cpp +SCRIPTSDIR=$WORKDIR/utils/docker + +echo Building ${OS}-${OS_VER} + +# Run a container with +# - environment variables set (--env) +# - host directory containing source mounted (-v) +# - working directory set (-w) +docker run --privileged=true --name=$containerName -ti \ + $DNS_SETTING \ + ${docker_opts} \ + --env http_proxy=$http_proxy \ + --env https_proxy=$https_proxy \ + --env AUTO_DOC_UPDATE=$AUTO_DOC_UPDATE \ + --env GITHUB_TOKEN=$GITHUB_TOKEN \ + --env WORKDIR=$WORKDIR \ + --env SCRIPTSDIR=$SCRIPTSDIR \ + --env TRAVIS_REPO_SLUG=$TRAVIS_REPO_SLUG \ + --env TRAVIS_BRANCH=$TRAVIS_BRANCH \ + --env TRAVIS_EVENT_TYPE=$TRAVIS_EVENT_TYPE \ + --env COVERITY_SCAN_TOKEN=$COVERITY_SCAN_TOKEN \ + --env COVERITY_SCAN_NOTIFICATION_EMAIL=$COVERITY_SCAN_NOTIFICATION_EMAIL \ + --env COVERAGE=$COVERAGE \ + --env CLANG_FORMAT=clang-format-3.8 \ + --env TZ='Europe/Warsaw' \ + -v $HOST_WORKDIR:$WORKDIR \ + -v /etc/localtime:/etc/localtime \ + -w $SCRIPTSDIR \ + $imageName $command diff --git a/utils/docker/images/Dockerfile.fedora-28 b/utils/docker/images/Dockerfile.fedora-28 new file mode 100644 index 0000000..ff625c2 --- /dev/null +++ b/utils/docker/images/Dockerfile.fedora-28 @@ -0,0 +1,103 @@ +# +# Copyright 2016-2018, Intel Corporation +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# +# * Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# +# * Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in +# the documentation and/or other materials provided with the +# distribution. +# +# * Neither the name of the copyright holder nor the names of its +# contributors may be used to endorse or promote products derived +# from this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +# +# Dockerfile - a 'recipe' for Docker to build an image of fedora-based +# environment prepared for running libpmemobj-cpp tests. +# + +# Pull base image +FROM fedora:28 +MAINTAINER marcin.slusarz@intel.com + +# Install basic tools +RUN dnf update -y \ + && dnf install -y \ + autoconf \ + automake \ + clang \ + cmake \ + doxygen \ + gcc \ + gdb \ + git \ + hub \ + libunwind-devel \ + make \ + man \ + ncurses-devel \ + open-sans-fonts \ + passwd \ + perl-Text-Diff \ + rpm-build \ + rpm-build-libs \ + rpmdevtools \ + SFML-devel \ + sudo \ + tar \ + wget \ + which \ + json-c-devel \ + kmod-devel \ + libudev-devel \ + asciidoc \ + xmlto \ + libuuid-devel \ + libtool \ + bash-completion \ + && dnf clean all + +# Install libndctl +COPY install-libndctl.sh install-libndctl.sh +RUN ./install-libndctl.sh fedora + +# Install valgrind +COPY install-valgrind.sh install-valgrind.sh +RUN ./install-valgrind.sh + +# Install pmdk +COPY install-pmdk.sh install-pmdk.sh +RUN ./install-pmdk.sh rpm + +# Add user +ENV USER user +ENV USERPASS pass +RUN useradd -m $USER +RUN echo $USERPASS | passwd $USER --stdin +RUN gpasswd wheel -a $USER +USER $USER + +# Set required environment variables +ENV OS fedora +ENV OS_VER 28 +ENV PACKAGE_MANAGER rpm +ENV NOTTY 1 + diff --git a/utils/docker/images/Dockerfile.ubuntu-18.04 b/utils/docker/images/Dockerfile.ubuntu-18.04 new file mode 100644 index 0000000..b54440b --- /dev/null +++ b/utils/docker/images/Dockerfile.ubuntu-18.04 @@ -0,0 +1,98 @@ +# +# Copyright 2016-2018, Intel Corporation +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# +# * Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# +# * Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in +# the documentation and/or other materials provided with the +# distribution. +# +# * Neither the name of the copyright holder nor the names of its +# contributors may be used to endorse or promote products derived +# from this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +# +# Dockerfile - a 'recipe' for Docker to build an image of ubuntu-based +# environment prepared for running libpmemobj-cpp tests. +# + +# Pull base image +FROM ubuntu:18.04 +MAINTAINER marcin.slusarz@intel.com + +ENV DEBIAN_FRONTEND noninteractive + +# Update the Apt cache and install basic tools +RUN apt-get update \ + && apt-get install -y software-properties-common \ + tzdata \ + autoconf \ + clang \ + clang-format \ + cmake \ + curl \ + debhelper \ + devscripts \ + doxygen \ + libncurses5-dev \ + gcc \ + gdb \ + git \ + graphviz \ + libunwind-dev \ + libtext-diff-perl \ + pkg-config \ + ruby \ + libsfml-dev \ + llvm \ + sudo \ + wget \ + whois \ + libjson-c-dev \ + asciidoc \ + uuid-dev \ + libkmod-dev \ + libudev-dev \ + && rm -rf /var/lib/apt/lists/* + +# Install libndctl +COPY install-libndctl.sh install-libndctl.sh +RUN ./install-libndctl.sh + +# Install valgrind +COPY install-valgrind.sh install-valgrind.sh +RUN ./install-valgrind.sh + +# Install pmdk +COPY install-pmdk.sh install-pmdk.sh +RUN ./install-pmdk.sh dpkg + +# Add user +ENV USER user +ENV USERPASS pass +RUN useradd -m $USER -g sudo -p `mkpasswd $USERPASS` +USER $USER + +# Set required environment variables +ENV OS ubuntu +ENV OS_VER 18.04 +ENV PACKAGE_MANAGER deb +ENV NOTTY 1 diff --git a/utils/docker/images/build-image.sh b/utils/docker/images/build-image.sh new file mode 100755 index 0000000..606d1df --- /dev/null +++ b/utils/docker/images/build-image.sh @@ -0,0 +1,69 @@ +#!/usr/bin/env bash +# +# Copyright 2016-2018, Intel Corporation +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# +# * Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# +# * Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in +# the documentation and/or other materials provided with the +# distribution. +# +# * Neither the name of the copyright holder nor the names of its +# contributors may be used to endorse or promote products derived +# from this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +# +# build-image.sh - prepares a Docker image with -based +# environment for testing libpmemobj-cpp, according +# to the Dockerfile. file located +# in the same directory. +# +# The script can be run locally. +# + +set -e + +function usage { + echo "Usage:" + echo " build-image.sh " + echo "where , for example, can be 'ubuntu-16.04', provided " \ + "a Dockerfile named 'Dockerfile.ubuntu-16.04' exists in the " \ + "current directory." +} + +# Check if the first and second argument is nonempty +if [[ -z "$1" || -z "$2" ]]; then + usage + exit 1 +fi + +# Check if the file Dockerfile.OS-VER exists +if [[ ! -f "Dockerfile.$2" ]]; then + echo "ERROR: wrong argument." + usage + exit 1 +fi + +# Build a Docker image tagged with ${DOCKERHUB_REPO}:OS-VER +docker build -t $1:$2 \ + --build-arg http_proxy=$http_proxy \ + --build-arg https_proxy=$https_proxy \ + -f Dockerfile.$2 . diff --git a/utils/docker/images/install-libndctl.sh b/utils/docker/images/install-libndctl.sh new file mode 100755 index 0000000..d90cbd0 --- /dev/null +++ b/utils/docker/images/install-libndctl.sh @@ -0,0 +1,92 @@ +#!/usr/bin/env bash +# +# Copyright 2018, Intel Corporation +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# +# * Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# +# * Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in +# the documentation and/or other materials provided with the +# distribution. +# +# * Neither the name of the copyright holder nor the names of its +# contributors may be used to endorse or promote products derived +# from this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +# +# install-libndctl.sh - installs libndctl +# + +set -e + +OS=$1 + +echo "==== clone ndctl repo ====" +git clone https://github.com/pmem/ndctl.git +cd ndctl +git checkout tags/v60.1 + +if [ "$OS" = "fedora" ]; then + +echo "==== setup rpmbuild tree ====" +rpmdev-setuptree + +RPMDIR=$HOME/rpmbuild/ +VERSION=$(./git-version) +SPEC=./rhel/ndctl.spec + +echo "==== create source tarball =====" +git archive --format=tar --prefix="ndctl-${VERSION}/" HEAD | gzip > "$RPMDIR/SOURCES/ndctl-${VERSION}.tar.gz" + +echo "==== build ndctl ====" +./autogen.sh +./configure +make + +echo "==== update ndctl.spec ====" +# XXX: pre-process ndctl.spec to remove dependency on libpmem +# To be removed once ndctl v60 is available. +sed -i -e "/pkgconfig(libpmem)/d" -e "s/--with-libpmem//g" $SPEC + +echo "==== build ndctl packages ====" +rpmbuild -ba $SPEC + +echo "==== install ndctl packages ====" +rpm -i $RPMDIR/RPMS/x86_64/*.rpm + +echo "==== cleanup ====" +rm -rf $RPMDIR + +else + +echo "==== build ndctl ====" +./autogen.sh +./configure +make + +echo "==== install ndctl ====" +make install + +echo "==== cleanup ====" + +fi + +cd .. +rm -rf ndctl diff --git a/utils/docker/images/install-pmdk.sh b/utils/docker/images/install-pmdk.sh new file mode 100755 index 0000000..334cb05 --- /dev/null +++ b/utils/docker/images/install-pmdk.sh @@ -0,0 +1,59 @@ +#!/usr/bin/env bash +# +# Copyright 2018, Intel Corporation +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# +# * Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# +# * Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in +# the documentation and/or other materials provided with the +# distribution. +# +# * Neither the name of the copyright holder nor the names of its +# contributors may be used to endorse or promote products derived +# from this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +# +# install-pmdk.sh - installs libpmem & libpmemobj +# + +set -e + +git clone https://github.com/pmem/pmdk +cd pmdk +git checkout 1.5.1 + +sudo make EXTRA_CFLAGS="-DUSE_COW_ENV" -j2 install prefix=/opt/pmdk + +sudo mkdir /opt/pmdk-pkg + +# Download and save pmdk-1.4 packages +if [ "$1" = "dpkg" ]; then + wget https://github.com/pmem/pmdk/releases/download/1.4/pmdk-1.4-dpkgs.tar.gz + tar -xzf pmdk-1.4-dpkgs.tar.gz + sudo mv *.deb /opt/pmdk-pkg/ +elif [ "$1" = "rpm" ]; then + wget https://github.com/pmem/pmdk/releases/download/1.4/pmdk-1.4-rpms.tar.gz + tar -xzf pmdk-1.4-rpms.tar.gz + sudo mv x86_64/*.rpm /opt/pmdk-pkg/ +fi + +cd .. +rm -rf pmdk diff --git a/utils/docker/images/install-valgrind.sh b/utils/docker/images/install-valgrind.sh new file mode 100755 index 0000000..d27d513 --- /dev/null +++ b/utils/docker/images/install-valgrind.sh @@ -0,0 +1,48 @@ +#!/usr/bin/env bash +# +# Copyright 2016-2019, Intel Corporation +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# +# * Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# +# * Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in +# the documentation and/or other materials provided with the +# distribution. +# +# * Neither the name of the copyright holder nor the names of its +# contributors may be used to endorse or promote products derived +# from this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +# +# install-valgrind.sh - installs valgrind for persistent memory +# + +set -e + +git clone --recursive https://github.com/pmem/valgrind.git +cd valgrind +# pmem-3.14: pmemcheck: add missing Ist_Flush IRStmt handling +git checkout 332b3975989d9130486d09493a9571528d66eaf7 +./autogen.sh +./configure --prefix=/usr +make +make install +cd .. +rm -rf valgrind diff --git a/utils/docker/images/push-image.sh b/utils/docker/images/push-image.sh new file mode 100755 index 0000000..2928243 --- /dev/null +++ b/utils/docker/images/push-image.sh @@ -0,0 +1,71 @@ +#!/usr/bin/env bash +# +# Copyright 2016-2018, Intel Corporation +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# +# * Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# +# * Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in +# the documentation and/or other materials provided with the +# distribution. +# +# * Neither the name of the copyright holder nor the names of its +# contributors may be used to endorse or promote products derived +# from this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +# +# push-image.sh - pushes the Docker image tagged with OS-VER +# to the Docker Hub. +# +# The script utilizes $DOCKERHUB_USER and $DOCKERHUB_PASSWORD variables to log in to +# Docker Hub. The variables can be set in the Travis project's configuration +# for automated builds. +# + +set -e + +function usage { + echo "Usage:" + echo " push-image.sh " + echo "where , for example, can be 'ubuntu-16.04', provided " \ + "a Docker image tagged with ${DOCKERHUB_REPO}:ubuntu-16.04 exists " \ + "locally." +} + +# Check if the first argument is nonempty +if [[ -z "$1" ]]; then + usage + exit 1 +fi + +# Check if the image tagged with ${DOCKERHUB_REPO}:OS-VER exists locally +if [[ ! $(docker images -a | awk -v pattern="^${DOCKERHUB_REPO}:$1\$" \ + '$1":"$2 ~ pattern') ]] +then + echo "ERROR: wrong argument." + usage + exit 1 +fi + +# Log in to the Docker Hub +docker login -u="$DOCKERHUB_USER" -p="$DOCKERHUB_PASSWORD" + +# Push the image to the repository +docker push ${DOCKERHUB_REPO}:$1 diff --git a/utils/docker/pull-or-rebuild-image.sh b/utils/docker/pull-or-rebuild-image.sh new file mode 100755 index 0000000..3cc4761 --- /dev/null +++ b/utils/docker/pull-or-rebuild-image.sh @@ -0,0 +1,148 @@ +#!/usr/bin/env bash +# +# Copyright 2016-2019, Intel Corporation +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# +# * Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# +# * Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in +# the documentation and/or other materials provided with the +# distribution. +# +# * Neither the name of the copyright holder nor the names of its +# contributors may be used to endorse or promote products derived +# from this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +# +# pull-or-rebuild-image.sh - rebuilds the Docker image used in the +# current Travis build if necessary. +# +# The script rebuilds the Docker image if the Dockerfile for the current +# OS version (Dockerfile.${OS}-${OS_VER}) or any .sh script from the directory +# with Dockerfiles were modified and committed. +# +# If the Travis build is not of the "pull_request" type (i.e. in case of +# merge after pull_request) and it succeed, the Docker image should be pushed +# to the Docker Hub repository. An empty file is created to signal that to +# further scripts. +# +# If the Docker image does not have to be rebuilt, it will be pulled from +# Docker Hub. +# + +set -e + +if [[ "$TRAVIS_EVENT_TYPE" != "cron" && "$TRAVIS_BRANCH" != "coverity_scan" \ + && "$COVERITY" -eq 1 ]]; then + echo "INFO: Skip Coverity scan job if build is triggered neither by " \ + "'cron' nor by a push to 'coverity_scan' branch" + exit 0 +fi + +if [[ ( "$TRAVIS_EVENT_TYPE" == "cron" || "$TRAVIS_BRANCH" == "coverity_scan" )\ + && "$COVERITY" -ne 1 ]]; then + echo "INFO: Skip regular jobs if build is triggered either by 'cron'" \ + " or by a push to 'coverity_scan' branch" + exit 0 +fi + +if [[ -z "$OS" || -z "$OS_VER" ]]; then + echo "ERROR: The variables OS and OS_VER have to be set properly " \ + "(eg. OS=ubuntu, OS_VER=16.04)." + exit 1 +fi + +if [[ -z "$HOST_WORKDIR" ]]; then + echo "ERROR: The variable HOST_WORKDIR has to contain a path to " \ + "the root of this project on the host machine" + exit 1 +fi + +# TRAVIS_COMMIT_RANGE is usually invalid for force pushes - ignore such values +# when used with non-upstream repository +if [ -n "$TRAVIS_COMMIT_RANGE" -a $TRAVIS_REPO_SLUG != "${GITHUB_REPO}" ]; then + if ! git rev-list $TRAVIS_COMMIT_RANGE; then + TRAVIS_COMMIT_RANGE= + fi +fi + +# Find all the commits for the current build +if [[ -n "$TRAVIS_COMMIT_RANGE" ]]; then + # $TRAVIS_COMMIT_RANGE contains "..." instead of ".." + # https://github.com/travis-ci/travis-ci/issues/4596 + PR_COMMIT_RANGE="${TRAVIS_COMMIT_RANGE/.../..}" + + commits=$(git rev-list $PR_COMMIT_RANGE) +else + commits=$TRAVIS_COMMIT +fi +echo "Commits in the commit range:" +for commit in $commits; do echo $commit; done + +# Get the list of files modified by the commits +files=$(for commit in $commits; do git diff-tree --no-commit-id --name-only \ + -r $commit; done | sort -u) +echo "Files modified within the commit range:" +for file in $files; do echo $file; done + +# Path to directory with Dockerfiles and image building scripts +images_dir_name=images +base_dir=utils/docker/$images_dir_name + +# Check if committed file modifications require the Docker image to be rebuilt +for file in $files; do + # Check if modified files are relevant to the current build + if [[ $file =~ ^($base_dir)\/Dockerfile\.($OS)-($OS_VER)$ ]] \ + || [[ $file =~ ^($base_dir)\/.*\.sh$ ]] + then + # Rebuild Docker image for the current OS version + echo "Rebuilding the Docker image for the Dockerfile.$OS-$OS_VER" + pushd $images_dir_name + ./build-image.sh ${DOCKERHUB_REPO} ${OS}-${OS_VER} + popd + + # Check if the image has to be pushed to Docker Hub + # (i.e. the build is triggered by commits to the ${GITHUB_REPO} + # repository's master branch, and the Travis build is not + # of the "pull_request" type). In that case, create the empty + # file. + if [[ $TRAVIS_REPO_SLUG == "${GITHUB_REPO}" \ + && $TRAVIS_BRANCH == "master" \ + && $TRAVIS_EVENT_TYPE != "pull_request" + && $PUSH_IMAGE == "1" ]] + then + echo "The image will be pushed to Docker Hub" + touch push_image_to_repo_flag + else + echo "Skip pushing the image to Docker Hub" + fi + + if [[ $PUSH_IMAGE == "1" ]] + then + echo "Skip build package check if image has to be pushed" + touch skip_build_package_check + fi + exit 0 + fi +done + +# Getting here means rebuilding the Docker image is not required. +# Pull the image from Docker Hub. +docker pull ${DOCKERHUB_REPO}:${OS}-${OS_VER} diff --git a/utils/docker/run-build.sh b/utils/docker/run-build.sh new file mode 100755 index 0000000..24da2e7 --- /dev/null +++ b/utils/docker/run-build.sh @@ -0,0 +1,270 @@ +#!/usr/bin/env bash +# +# Copyright 2016-2019, Intel Corporation +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# +# * Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# +# * Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in +# the documentation and/or other materials provided with the +# distribution. +# +# * Neither the name of the copyright holder nor the names of its +# contributors may be used to endorse or promote products derived +# from this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +# +# run-build.sh - is called inside a Docker container; prepares the environment +# and starts a build of libpmemobj-cpp. +# + +set -e + +function cleanup() { + find . -name ".coverage" -exec rm {} \; + find . -name "coverage.xml" -exec rm {} \; + find . -name "*.gcov" -exec rm {} \; + find . -name "*.gcda" -exec rm {} \; +} + +function upload_codecov() { + clang_used=$(cmake -LA -N . | grep CMAKE_CXX_COMPILER | grep clang | wc -c) + + if [[ $clang_used > 0 ]]; then + gcovexe="llvm-cov gcov" + else + gcovexe="gcov" + fi + + # the output is redundant in this case, i.e. we rely on parsed report from codecov on github + bash <(curl -s https://codecov.io/bash) -c -F $1 -x "$gcovexe" > /dev/null + cleanup +} + +function compile_example_standalone() { + rm -rf /tmp/build_example + mkdir /tmp/build_example + cd /tmp/build_example + + cmake $WORKDIR/examples/$1 + + # exit on error + if [[ $? != 0 ]]; then + cd - + return 1 + fi + + make + cd - +} + +function sudo_password() { + echo $USERPASS | sudo -Sk $* +} + +sudo_password mkdir /mnt/pmem +sudo_password chmod 0777 /mnt/pmem +sudo_password mount -o size=2G -t tmpfs none /mnt/pmem + +cd $WORKDIR +INSTALL_DIR=/tmp/libpmemobj-cpp + +mkdir $INSTALL_DIR + +############################################################################### +# BUILD tests_clang_debug_cpp17 llvm +############################################################################### +printf "\n$(tput setaf 1)$(tput setab 7)BUILD tests_clang_debug_cpp17 START$(tput sgr 0)\n" +mkdir build +cd build + +PKG_CONFIG_PATH=/opt/pmdk/lib/pkgconfig/ \ +CC=clang CXX=clang++ \ +cmake .. -DDEVELOPER_MODE=1 \ + -DCMAKE_BUILD_TYPE=Debug \ + -DCMAKE_INSTALL_PREFIX=$INSTALL_DIR \ + -DTRACE_TESTS=1 \ + -DCOVERAGE=$COVERAGE \ + -DCXX_STANDARD=17 \ + -DTESTS_USE_VALGRIND=0 \ + -DTEST_DIR=/mnt/pmem \ + -DTESTS_USE_FORCED_PMEM=1 + +make -j2 +ctest --output-on-failure --timeout 540 +if [ "$COVERAGE" = "1" ]; then + upload_codecov tests_clang_debug_cpp17 +fi + +cd .. +rm -r build +printf "$(tput setaf 1)$(tput setab 7)BUILD tests_clang_debug_cpp17 END$(tput sgr 0)\n\n" + +############################################################################### +# BUILD tests_gcc_debug +############################################################################### +printf "\n$(tput setaf 1)$(tput setab 7)BUILD tests_gcc_debug START$(tput sgr 0)\n" +mkdir build +cd build + +PKG_CONFIG_PATH=/opt/pmdk/lib/pkgconfig/ \ +CC=gcc CXX=g++ \ +cmake .. -DDEVELOPER_MODE=1 \ + -DCMAKE_BUILD_TYPE=Debug \ + -DCMAKE_INSTALL_PREFIX=$INSTALL_DIR \ + -DTRACE_TESTS=1 \ + -DCOVERAGE=$COVERAGE \ + -DTESTS_USE_VALGRIND=1 \ + -DTEST_DIR=/mnt/pmem \ + -DTESTS_USE_FORCED_PMEM=1 + +make -j2 +if [ "$COVERAGE" = "1" ]; then + # valgrind reports error when used with code coverage + ctest -E "_memcheck|_drd|_helgrind|_pmemcheck" --timeout 540 + upload_codecov tests_gcc_debug +else + ctest --output-on-failure --timeout 540 +fi + +cd .. +rm -r build +printf "$(tput setaf 1)$(tput setab 7)BUILD tests_gcc_debug END$(tput sgr 0)\n\n" + +############################################################################### +# BUILD tests_gcc_release_cpp17_no_valgrind +############################################################################### +printf "\n$(tput setaf 1)$(tput setab 7)BUILD tests_gcc_release_cpp17_no_valgrind START$(tput sgr 0)\n" +VALGRIND_PC_PATH=$(find /usr -name "valgrind.pc") +sudo_password mv $VALGRIND_PC_PATH tmp_valgrind_pc +mkdir build +cd build + +PKG_CONFIG_PATH=/opt/pmdk/lib/pkgconfig/ \ +CC=gcc CXX=g++ \ +cmake .. -DCMAKE_BUILD_TYPE=Release \ + -DCMAKE_INSTALL_PREFIX=$INSTALL_DIR \ + -DTRACE_TESTS=1 \ + -DCOVERAGE=$COVERAGE \ + -DCXX_STANDARD=17 \ + -DTESTS_USE_VALGRIND=1 \ + -DTEST_DIR=/mnt/pmem \ + -DBUILD_EXAMPLES=0 \ + -DTESTS_USE_FORCED_PMEM=1 + +make -j2 +ctest --output-on-failure --timeout 540 +if [ "$COVERAGE" = "1" ]; then + upload_codecov tests_gcc_release_cpp17_no_valgrind +fi + +cd .. +rm -r build +sudo_password mv tmp_valgrind_pc $VALGRIND_PC_PATH +printf "$(tput setaf 1)$(tput setab 7)BUILD tests_gcc_release_cpp17_no_valgrind END$(tput sgr 0)\n\n" + +############################################################################### +# BUILD tests_package +############################################################################### +printf "\n$(tput setaf 1)$(tput setab 7)BUILD tests_package START$(tput sgr 0)\n" +mkdir build +cd build + +if [ $PACKAGE_MANAGER = "deb" ]; then + sudo_password dpkg -i /opt/pmdk-pkg/libpmem_*.deb /opt/pmdk-pkg/libpmem-dev_*.deb + sudo_password dpkg -i /opt/pmdk-pkg/libpmemobj_*.deb /opt/pmdk-pkg/libpmemobj-dev_*.deb +elif [ $PACKAGE_MANAGER = "rpm" ]; then + sudo_password rpm -i /opt/pmdk-pkg/libpmem-*.rpm + sudo_password rpm -i /opt/pmdk-pkg/libpmemobj-*.rpm +fi + +CC=gcc CXX=g++ \ +cmake .. -DCMAKE_INSTALL_PREFIX=/usr \ + -DTESTS_USE_VALGRIND=0 \ + -DCPACK_GENERATOR=$PACKAGE_MANAGER + +make -j2 +ctest --output-on-failure --timeout 540 + +make package + +# Make sure there is no libpmemobj++ currently installed +echo "---------------------------- Error expected! ------------------------------" +compile_example_standalone map_cli && exit 1 +echo "---------------------------------------------------------------------------" + +if [ $PACKAGE_MANAGER = "deb" ]; then + sudo_password dpkg -i libpmemobj++*.deb +elif [ $PACKAGE_MANAGER = "rpm" ]; then + sudo_password rpm -i libpmemobj++*.rpm +fi + +cd .. +rm -rf build + +# Verify installed package +compile_example_standalone map_cli + +# Remove pkg-config and force cmake to use find_package while compiling example +if [ $PACKAGE_MANAGER = "deb" ]; then + sudo_password dpkg -r --force-all pkg-config +elif [ $PACKAGE_MANAGER = "rpm" ]; then + sudo_password rpm -e --nodeps pkgconf +fi + +# Verify installed package using find_package +compile_example_standalone map_cli + +printf "$(tput setaf 1)$(tput setab 7)BUILD tests_package END$(tput sgr 0)\n\n" + +############################################################################### +# BUILD test findLIBPMEMOBJ.cmake +############################################################################### +printf "\n$(tput setaf 1)$(tput setab 7)BUILD tests_findLIBPMEMOBJ.cmake START$(tput sgr 0)\n" +mkdir build +cd build + +CC=gcc CXX=g++ \ +cmake .. -DCMAKE_BUILD_TYPE=Release \ + -DCMAKE_INSTALL_PREFIX=$INSTALL_DIR \ + -DTRACE_TESTS=1 \ + -DCOVERAGE=$COVERAGE \ + -DCXX_STANDARD=17 + +make -j2 + +cd .. +rm -r build +printf "$(tput setaf 1)$(tput setab 7)BUILD tests_findLIBPMEMOBJ.cmake END$(tput sgr 0)\n\n" + +rm -r $INSTALL_DIR + +# Trigger auto doc update on master +if [[ "$AUTO_DOC_UPDATE" == "1" ]]; then + echo "Running auto doc update" + + mkdir doc_update + cd doc_update + + $SCRIPTSDIR/run-doc-update.sh + + cd .. + rm -rf doc_update +fi diff --git a/utils/docker/run-coverity.sh b/utils/docker/run-coverity.sh new file mode 100755 index 0000000..7f65ca5 --- /dev/null +++ b/utils/docker/run-coverity.sh @@ -0,0 +1,68 @@ +#!/usr/bin/env bash +# +# Copyright 2018, Intel Corporation +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# +# * Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# +# * Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in +# the documentation and/or other materials provided with the +# distribution. +# +# * Neither the name of the copyright holder nor the names of its +# contributors may be used to endorse or promote products derived +# from this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +# +# run-coverity.sh - runs the Coverity scan build +# + +set -e + +cd $WORKDIR + +mkdir build +cd build +PKG_CONFIG_PATH=/opt/pmdk/lib/pkgconfig/ cmake .. -DCMAKE_BUILD_TYPE=Debug + +export COVERITY_SCAN_PROJECT_NAME="$TRAVIS_REPO_SLUG" +[[ "$TRAVIS_EVENT_TYPE" == "cron" ]] \ + && export COVERITY_SCAN_BRANCH_PATTERN="master" \ + || export COVERITY_SCAN_BRANCH_PATTERN="coverity_scan" +export COVERITY_SCAN_BUILD_COMMAND="make" + +# Run the Coverity scan + +# XXX: Patch the Coverity script. +# Recently, this script regularly exits with an error, even though +# the build is successfully submitted. Probably because the status code +# is missing in response, or it's not 201. +# Changes: +# 1) change the expected status code to 200 and +# 2) print the full response string. +# +# This change should be reverted when the Coverity script is fixed. +# +# The previous version was: +# curl -s https://scan.coverity.com/scripts/travisci_build_coverity_scan.sh | bash + +wget https://scan.coverity.com/scripts/travisci_build_coverity_scan.sh +patch < ../utils/docker/0001-travis-fix-travisci_build_coverity_scan.sh.patch +bash ./travisci_build_coverity_scan.sh diff --git a/utils/docker/run-doc-update.sh b/utils/docker/run-doc-update.sh new file mode 100755 index 0000000..8014273 --- /dev/null +++ b/utils/docker/run-doc-update.sh @@ -0,0 +1,77 @@ +#!/usr/bin/env bash +# +# Copyright 2018, Intel Corporation +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# +# * Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# +# * Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in +# the documentation and/or other materials provided with the +# distribution. +# +# * Neither the name of the copyright holder nor the names of its +# contributors may be used to endorse or promote products derived +# from this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +set -e + +ORIGIN="https://${GITHUB_TOKEN}@github.com/pmem-bot/libpmemobj-cpp" +UPSTREAM="https://github.com/pmem/libpmemobj-cpp" + +# Clone repo +git clone ${ORIGIN} +cd libpmemobj-cpp +git remote add upstream ${UPSTREAM} + +git config --local user.name "pmem-bot" +git config --local user.email "pmem-bot@intel.com" + +git checkout master +git remote update +git rebase upstream/master + +# Build docs +mkdir build +cd build + +cmake -DBUILD_TESTS=OFF -DBUILD_EXAMPLES=OFF .. +make doc +cp -R doc/cpp_html ../.. + +cd .. + +# Checkout gh-pages and copy docs +git checkout -fb gh-pages upstream/gh-pages +git clean -df +cp -r ../cpp_html/* master/doxygen/ + +# Add and push changes. +# git commit command may fail if there is nothing to commit. +# In that case we want to force push anyway (there might be open pull request with +# changes which were reverted). +git add -A +git commit -m "doc: automatic gh-pages docs update" && true +git push -f ${ORIGIN} gh-pages + +# Makes pull request. +# When there is already an open PR or there are no changes an error is thrown, which we ignore. +hub pull-request -f -b pmem:gh-pages -h pmem-bot:gh-pages -m "doc: automatic gh-pages docs update" && true + +exit 0