Merge branch 'master' into random-test-data-generator

This commit is contained in:
Alexey Milovidov 2016-12-13 21:53:53 +03:00
commit 1f017a5f93
4274 changed files with 721864 additions and 22039 deletions

View File

@ -8,7 +8,13 @@ insert_final_newline = true
# Matches multiple files with brace expansion notation
# Set default charset
[*.{c,cpp,cxx,h,hpp,hxx,py}]
[*.{c,cpp,cxx,h,hpp,hxx,py,cmake}]
charset = utf-8
indent_style = tab
indent_size = 4
trim_trailing_whitespace = true
[CMakeLists.txt]
charset = utf-8
indent_style = tab
indent_size = 4

13
.gitignore vendored
View File

@ -156,19 +156,6 @@ utils/zookeeper-dump-tree/zookeeper-dump-tree
utils/zookeeper-remove-by-list/zookeeper-remove-by-list
dbms/src/Storages/tests/remove_symlink_directory
dbms/tests/queries/1_stateful
debian/clickhouse-benchmark-metrika-yandex.postinst
debian/clickhouse-benchmark.docs
debian/clickhouse-client-metrika-yandex.postinst
debian/clickhouse-client.docs
debian/clickhouse-server-base.docs
debian/clickhouse-server-common.docs
debian/clickhouse-server-metrika-yandex.postinst
debian/clickhouse-server-metrika.docs
debian/clickhouse-server.docs
debian/compressor-metrika-yandex.postinst
debian/compressor.docs
debian/config-processor-metrika-yandex.postinst
debian/config-processor.docs
debian/control
debian/copyright
debian/tmp/

View File

@ -2,6 +2,7 @@ The following authors have created the source code of "ClickHouse"
published and distributed by YANDEX LLC as the owner:
Alexey Milovidov <milovidov@yandex-team.ru>
Vitaliy Lyudvichenko <vludv@yandex-team.ru>
Alexey Arno <af-arno@yandex-team.ru>
Andrey Mironov <hertz@yandex-team.ru>
Michael Kolupaev <mkolupaev@yandex-team.ru>

View File

@ -2,12 +2,12 @@ project (ClickHouse)
cmake_minimum_required (VERSION 2.6)
if ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "GNU")
# require at least gcc 5
if (CMAKE_CXX_COMPILER_VERSION VERSION_LESS 5)
# Require at least gcc 5
if (CMAKE_CXX_COMPILER_VERSION VERSION_LESS 5 AND NOT CMAKE_VERSION VERSION_LESS 2.8.9)
message (FATAL_ERROR "GCC version must be at least 5! For example, if GCC 5 is available under gcc-5, g++-5 names, do the following: export CC=gcc-5 CXX=g++-5; rm -rf CMakeCache.txt CMakeFiles; and re run cmake or ./release.")
endif ()
elseif ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "Clang")
# require at least clang 3.8
# Require at least clang 3.8
if (CMAKE_CXX_COMPILER_VERSION VERSION_LESS 3.8)
message (FATAL_ERROR "Clang version must be at least 3.8!")
endif ()
@ -19,16 +19,14 @@ if (APPLE)
set (APPLE_EXTRA_CXX_FLAG "-Dexp10=__exp10") # Also needed for libc++
endif ()
# отключаем варнинг о том, что в каждой директории должен быть CMakeLists.txt
cmake_policy(SET CMP0014 OLD)
cmake_policy (SET CMP0014 OLD) # Ignore warning about CMakeLists.txt in each directory
cmake_policy (SET CMP0012 NEW) # Don't dereference TRUE and FALSE
IF(NOT CMAKE_BUILD_TYPE)
if (NOT CMAKE_BUILD_TYPE)
message (STATUS "CMAKE_BUILD_TYPE is not set, set to default = RELWITHDEBINFO")
SET(CMAKE_BUILD_TYPE "RELWITHDEBINFO")
ENDIF()
MESSAGE( STATUS "CMAKE_BUILD_TYPE: " ${CMAKE_BUILD_TYPE} )
set (CMAKE_BUILD_TYPE "RELWITHDEBINFO")
endif ()
message (STATUS "CMAKE_BUILD_TYPE: " ${CMAKE_BUILD_TYPE} )
# ASan - build type with address sanitizer
# UBSan - build type with undefined behaviour sanitizer
@ -36,73 +34,96 @@ MESSAGE( STATUS "CMAKE_BUILD_TYPE: " ${CMAKE_BUILD_TYPE} )
set (CMAKE_CONFIGURATION_TYPES "RelWithDebInfo;Debug;Release;MinSizeRel;ASan;UBSan" CACHE STRING "" FORCE)
IF (CMAKE_SYSTEM_PROCESSOR MATCHES "^(aarch64.*|AARCH64.*)")
SET(AARCH64 1)
ENDIF()
if (CMAKE_SYSTEM_PROCESSOR MATCHES "^(aarch64.*|AARCH64.*)")
set (AARCH64 1)
endif ()
IF (NOT AARCH64)
SET(MACHINE_FLAGS "-msse4 -mpopcnt")
ENDIF()
if (NOT AARCH64)
set (MACHINE_FLAGS "-msse4 -mpopcnt")
endif ()
SET(COMMON_WARNING_FLAGS "-Wall -Werror")
SET(CXX_WARNING_FLAGS "-Wnon-virtual-dtor -Wold-style-cast")
set (COMMON_WARNING_FLAGS "-Wall -Werror")
set (CXX_WARNING_FLAGS "-Wnon-virtual-dtor")
set (CXX11_ABI "ENABLE" CACHE STRING "Use C++11 ABI: DEFAULT, ENABLE, DISABLE")
option (TEST_COVERAGE "Enables flags for test coverage" OFF)
option (ENABLE_TESTS "Enables tests" ON)
option (USE_STATIC_LIBRARIES "Set to FALSE to use shared libraries" ON)
if (NOT $ENV{USE_STATIC_LIBRARIES})
set (USE_STATIC_LIBRARIES FALSE)
endif ()
set (GLIBC_COMPATIBILITY FALSE CACHE BOOL "Set to TRUE to enable compatibility with older glibc libraries")
set (USE_INTERNAL_BOOST_LIBRARY TRUE CACHE BOOL "Set to FALSE to use system boost library instead of bundled")
if (NOT $ENV{USE_INTERNAL_BOOST_LIBRARY})
set (USE_INTERNAL_BOOST_LIBRARY FALSE)
endif ()
option (GLIBC_COMPATIBILITY "Set to TRUE to enable compatibility with older glibc libraries. Note that it is not compatible with ASan." OFF)
if ($ENV{GLIBC_COMPATIBILITY})
set (GLIBC_COMPATIBILITY TRUE)
endif ()
option (ENABLE_LIBTCMALLOC "Set to TRUE to enable libtcmalloc." ON)
if (NOT $ENV{ENABLE_LIBTCMALLOC})
set (ENABLE_LIBTCMALLOC FALSE)
endif ()
option (DEBUG_LIBTCMALLOC "Set to TRUE to use debug version of libtcmalloc." OFF)
if ($ENV{DEBUG_LIBTCMALLOC})
set (DEBUG_LIBTCMALLOC TRUE)
endif ()
if (GLIBC_COMPATIBILITY)
SET(GLIBC_COMPATIBILITY_COMPILE_FLAGS "-include ${ClickHouse_SOURCE_DIR}/libs/libcommon/include/common/glibc_compatibility.h")
SET(GLIBC_COMPATIBILITY_LINK_FLAGS "-Wl,--wrap=memcpy")
set (GLIBC_COMPATIBILITY_COMPILE_FLAGS "-include ${ClickHouse_SOURCE_DIR}/libs/libcommon/include/common/glibc_compatibility.h")
set (GLIBC_COMPATIBILITY_LINK_FLAGS "-Wl,--wrap=memcpy")
endif ()
if (DISABLE_CXX11_ABI)
SET(CXX11_ABI "-D_GLIBCXX_USE_CXX11_ABI=0")
if ("${CXX11_ABI}" STREQUAL ENABLE)
set (CXX11_ABI_FLAGS "-D_GLIBCXX_USE_CXX11_ABI=1")
elseif ("${CXX11_ABI}" STREQUAL DISABLE)
set (CXX11_ABI_FLAGS "-D_GLIBCXX_USE_CXX11_ABI=0")
else ()
set (CXX11_ABI_FLAGS "")
endif ()
SET(CMAKE_BUILD_COLOR_MAKEFILE ON)
SET(CMAKE_CXX_FLAGS "-std=gnu++1y ${APPLE_EXTRA_CXX_FLAG} -fno-omit-frame-pointer ${COMMON_WARNING_FLAGS} ${CXX_WARNING_FLAGS} ${MACHINE_FLAGS} ${GLIBC_COMPATIBILITY_COMPILE_FLAGS} ${CXX11_ABI}")
SET(CMAKE_CXX_FLAGS_RELEASE "-O3 -DNDEBUG")
SET(CMAKE_CXX_FLAGS_RELWITHDEBINFO "-O3 -g")
SET(CMAKE_CXX_FLAGS_DEBUG "-O0 -g3 -ggdb3 -fno-inline")
set (CMAKE_BUILD_COLOR_MAKEFILE ON)
set (CMAKE_CXX_FLAGS "-std=gnu++1y ${APPLE_EXTRA_CXX_FLAG} -fno-omit-frame-pointer ${COMMON_WARNING_FLAGS} ${CXX_WARNING_FLAGS} ${MACHINE_FLAGS} ${GLIBC_COMPATIBILITY_COMPILE_FLAGS} ${CXX11_ABI_FLAGS}")
set (CMAKE_CXX_FLAGS_RELEASE "-O3 -DNDEBUG")
set (CMAKE_CXX_FLAGS_RELWITHDEBINFO "-O3 -g")
set (CMAKE_CXX_FLAGS_DEBUG "-O0 -g3 -ggdb3 -fno-inline")
SET(CMAKE_C_FLAGS "-fno-omit-frame-pointer ${COMMON_WARNING_FLAGS} ${MACHINE_FLAGS} ${GLIBC_COMPATIBILITY_COMPILE_FLAGS} ${CXX11_ABI}")
SET(CMAKE_C_FLAGS_RELEASE "-O3 -DNDEBUG")
SET(CMAKE_C_FLAGS_RELWITHDEBINFO "-O3 -g")
SET(CMAKE_C_FLAGS_DEBUG "-O0 -g3 -ggdb3 -fno-inline")
set (CMAKE_C_FLAGS "-fno-omit-frame-pointer ${COMMON_WARNING_FLAGS} ${MACHINE_FLAGS} ${GLIBC_COMPATIBILITY_COMPILE_FLAGS} ${CXX11_ABI_FLAGS}")
set (CMAKE_C_FLAGS_RELEASE "-O3 -DNDEBUG")
set (CMAKE_C_FLAGS_RELWITHDEBINFO "-O3 -g")
set (CMAKE_C_FLAGS_DEBUG "-O0 -g3 -ggdb3 -fno-inline")
if (NOT APPLE)
SET(CMAKE_EXE_LINKER_FLAGS "-static-libgcc -static-libstdc++ ${GLIBC_COMPATIBILITY_LINK_FLAGS} ${CXX11_ABI}")
set (CMAKE_EXE_LINKER_FLAGS "-static-libgcc -static-libstdc++ ${GLIBC_COMPATIBILITY_LINK_FLAGS} ${CXX11_ABI_FLAGS}")
endif ()
# -fuse-ld=gold - fix linkage for gcc-5.4, gcc-6.1
# see more in http://stackoverflow.com/questions/37603238/fsanitize-not-using-gold-linker-in-gcc-6-1
SET(CMAKE_CXX_FLAGS_ASAN "-O3 -g -fsanitize=address -fno-omit-frame-pointer -fuse-ld=gold ${CXX11_ABI}")
SET(CMAKE_CXX_FLAGS_UBSAN "-O3 -g -fsanitize=undefined -fno-omit-frame-pointer ${CXX11_ABI}")
SET(CMAKE_C_FLAGS_ASAN "-O3 -g -fsanitize=address -fno-omit-frame-pointer -fuse-ld=gold ${CXX11_ABI}")
SET(CMAKE_C_FLAGS_UBSAN "-O3 -g -fsanitize=undefined -fno-omit-frame-pointer ${CXX11_ABI}")
# See more in http://stackoverflow.com/questions/37603238/fsanitize-not-using-gold-linker-in-gcc-6-1
set (CMAKE_CXX_FLAGS_ASAN "-O3 -g -fsanitize=address -fno-omit-frame-pointer -fuse-ld=gold ${CXX11_ABI_FLAGS}")
set (CMAKE_CXX_FLAGS_UBSAN "-O3 -g -fsanitize=undefined -fno-omit-frame-pointer ${CXX11_ABI_FLAGS}")
set (CMAKE_C_FLAGS_ASAN "-O3 -g -fsanitize=address -fno-omit-frame-pointer -fuse-ld=gold ${CXX11_ABI_FLAGS}")
set (CMAKE_C_FLAGS_UBSAN "-O3 -g -fsanitize=undefined -fno-omit-frame-pointer ${CXX11_ABI_FLAGS}")
# Флаги для test coverage
IF (TEST_COVERAGE)
SET(CMAKE_CXX_FLAGS_DEBUG "-O0 -g -fprofile-arcs -ftest-coverage -fPIC -DIS_DEBUG ${CXX11_ABI}")
ENDIF(TEST_COVERAGE)
# Flags for test coverage
if (TEST_COVERAGE)
set (CMAKE_CXX_FLAGS_DEBUG "-O0 -g -fprofile-arcs -ftest-coverage -fPIC -DIS_DEBUG ${CXX11_ABI_FLAGS}")
endif (TEST_COVERAGE)
# Собирать тесты?
IF (NOT DEFINED TESTS)
MESSAGE(STATUS "Tests are enabled")
SET(TESTS YES)
ENDIF()
# Run tests with "make check"
if (ENABLE_TESTS)
message (STATUS "Tests are enabled")
include (cmake/add_check.cmake)
endif (ENABLE_TESTS)
# тесты запускать с помощью "make check"
IF(TESTS)
INCLUDE(add.test.cmake)
ENDIF(TESTS)
# Префикс для установки
SET(CMAKE_INSTALL_PREFIX /usr)
# Installation prefix
set (CMAKE_INSTALL_PREFIX /usr)
include_directories (${ClickHouse_SOURCE_DIR}/contrib/libcityhash/include/)
include_directories (${ClickHouse_SOURCE_DIR}/contrib/liblz4/include/)
@ -130,6 +151,7 @@ include_directories (${ClickHouse_SOURCE_DIR}/contrib/libpoco/XML/include/)
include_directories (${ClickHouse_SOURCE_DIR}/contrib/libpoco/JSON/include/)
include_directories (${ClickHouse_SOURCE_DIR}/contrib/libpoco/MongoDB/include/)
include_directories (${ClickHouse_SOURCE_DIR}/contrib/libpoco/Zip/include/)
include_directories (${ClickHouse_SOURCE_DIR}/contrib/libboost/boost_1_62_0/)
include_directories (${ClickHouse_SOURCE_DIR}/libs/libcommon/include/)
include_directories (${ClickHouse_BINARY_DIR}/libs/libcommon/include/)
@ -140,61 +162,30 @@ include_directories (${ClickHouse_SOURCE_DIR}/libs/libzkutil/include/)
include_directories (${ClickHouse_SOURCE_DIR}/dbms/include)
include_directories (/usr/local/include/glib-2.0/)
include_directories (/usr/local/lib/glib-2.0/include/)
include_directories (/usr/include/glib-2.0/)
include_directories (/usr/lib64/glib-2.0/include/)
IF (AARCH64)
include_directories (/usr/lib/aarch64-linux-gnu/glib-2.0/include/)
ELSE()
include_directories (/usr/lib/x86_64-linux-gnu/glib-2.0/include/)
ENDIF()
include_directories (/usr/local/include/)
link_directories (/usr/local/lib)
# External libraries
# 1. openssl
include_directories ("/usr/local/opt/openssl/include")
set (OPENSSL_HINTS "/usr/local/opt/openssl/lib")
find_library (LIBSSL libssl.a HINTS ${OPENSSL_HINTS})
find_library (LIBCRYPTO libcrypto.a HINTS ${OPENSSL_HINTS})
set (OPENSSL_LIBS ${LIBSSL} ${LIBCRYPTO})
# 2. icu4c
include_directories ("/usr/local/opt/icu4c/include")
set (ICU_HINTS "/usr/local/opt/icu4c/lib")
find_library (ICUI18N libicui18n.a HINTS ${ICU_HINTS})
find_library (ICUUC libicuuc.a HINTS ${ICU_HINTS})
find_library (ICUDATA libicudata.a HINTS ${ICU_HINTS})
set (ICU_LIBS ${ICUI18N} ${ICUUC} ${ICUDATA})
# 3. boost
set (BOOST_HINTS "/usr/local/opt/boost/lib")
find_library (BOOST_PROGRAM_OPTIONS_LIB libboost_program_options.a HINTS ${BOOST_HINTS})
find_library (BOOST_SYSTEM_LIB libboost_system.a HINTS ${BOOST_HINTS})
find_library (BOOST_FILESYSTEM_LIB libboost_filesystem.a HINTS ${BOOST_HINTS})
find_library (BOOST_REGEX_LIB libboost_regex.a HINTS ${BOOST_HINTS})
find_library (BOOST_THREAD_LIB libboost_thread.a HINTS ${BOOST_HINTS})
# 4. ltdl
set (LTDL_HINTS "/usr/local/opt/libtool/lib")
find_library (LTDL_LIB libltdl.a HINTS ${LTDL_HINTS})
include (cmake/find_openssl.cmake)
include (cmake/find_icu4c.cmake)
include (cmake/find_boost.cmake)
include (cmake/find_libtool.cmake)
include (cmake/find_libmysqlclient.cmake)
include (cmake/find_rt.cmake)
# Directory for Yandex specific files
SET(CLICKHOUSE_PRIVATE_DIR ${ClickHouse_SOURCE_DIR}/private/)
set (CLICKHOUSE_PRIVATE_DIR ${ClickHouse_SOURCE_DIR}/private/)
add_subdirectory (contrib)
add_subdirectory (libs)
add_subdirectory (utils)
add_subdirectory (dbms)
IF (EXISTS ${CLICKHOUSE_PRIVATE_DIR})
if (EXISTS ${CLICKHOUSE_PRIVATE_DIR})
add_subdirectory (private)
ENDIF()
endif ()
message (STATUS "C_FLAGS: =${CMAKE_C_FLAGS}")
message (STATUS "CXX_FLAGS:=${CMAKE_CXX_FLAGS}")
include (cmake/print_include_directories.cmake)

View File

@ -1,6 +1,6 @@
==How to increase maxfiles on MacOS X==
## How to increase maxfiles on Mac OS X
To increase maxfiles on MacOS create the following file:
To increase maxfiles on MacOS, create the following file:
(Note: you'll need to use sudo)
@ -29,11 +29,11 @@ To increase maxfiles on MacOS create the following file:
</plist>
```
execute the following command:
Execute the following command:
```
sudo chown root:wheel /Library/LaunchDaemons/limit.maxfiles.plist
```
Reboot.
To check if it's working, you can use 'ulimit -n' command
To check if it's working, you can use `ulimit -n` command.

View File

@ -1,15 +0,0 @@
# добавляем вывод программы при ошибке теста
enable_testing()
if (CMAKE_CONFIGURATION_TYPES)
add_custom_target(check COMMAND ${CMAKE_CTEST_COMMAND}
--force-new-ctest-process --output-on-failure
--build-config "$<CONFIGURATION>")
else()
add_custom_target(check COMMAND ${CMAKE_CTEST_COMMAND}
--force-new-ctest-process --output-on-failure)
endif()
macro (add_check target)
add_test(NAME test_${target} COMMAND ${target} WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR})
add_dependencies(check ${target})
endmacro (add_check)

15
cmake/add_check.cmake Normal file
View File

@ -0,0 +1,15 @@
# Adding test output on failure
enable_testing ()
if (CMAKE_CONFIGURATION_TYPES)
add_custom_target (check COMMAND ${CMAKE_CTEST_COMMAND}
--force-new-ctest-process --output-on-failure
--build-config "$<CONFIGURATION>")
else ()
add_custom_target (check COMMAND ${CMAKE_CTEST_COMMAND}
--force-new-ctest-process --output-on-failure)
endif ()
macro (add_check target)
add_test (NAME test_${target} COMMAND ${target} WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR})
add_dependencies (check ${target})
endmacro (add_check)

View File

@ -0,0 +1,38 @@
# В этом файле описаны действия для добавления init.d скрипта. Пока в разработке.
# Данный файл нужно включать в CMakeLists.txt в каталоге каждого конкретного демона.
# Пример использования:
# include (${ClickHouse_SOURCE_DIR}/create_init_script.cmake)
# create_init_script (divider Divider)
# Будет создан init.d скрипт с названием divider для демона (бинарника) Divider
macro (create_init_script daemonname)
set (filename ${daemonname}-metrika-yandex)
# Опционально принимаем filename вторым аргументом.
set (extra_args ${ARGN})
list (LENGTH extra_args num_extra_args)
if (${num_extra_args} GREATER 0)
list (GET extra_args 0 optional_arg)
set (filename ${optional_arg})
endif ()
set (tmp_file_name ${filename}.init)
set (SED_INPLACE_SUFFIX "")
if (APPLE)
set (SED_INPLACE_SUFFIX "''")
endif ()
add_custom_command (OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/${tmp_file_name}
COMMAND sed -e 's,[@]DAEMON[@],${daemonname},g' < ${PROJECT_SOURCE_DIR}/tools/init.d/template > ${CMAKE_CURRENT_BINARY_DIR}/${tmp_file_name}
COMMAND sed -i ${SED_INPLACE_SUFFIX} 's,[@]CRONFILE[@],${filename},g' ${CMAKE_CURRENT_BINARY_DIR}/${tmp_file_name}
COMMAND chmod a+x ${CMAKE_CURRENT_BINARY_DIR}/${tmp_file_name}
COMMENT "Building ${daemonname}"
)
add_custom_target (${daemonname}-init.target DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/${tmp_file_name})
install (
FILES ${CMAKE_CURRENT_BINARY_DIR}/${tmp_file_name}
DESTINATION /etc/init.d
RENAME ${filename}
PERMISSIONS OWNER_EXECUTE OWNER_READ GROUP_EXECUTE GROUP_READ WORLD_EXECUTE WORLD_READ
COMPONENT ${daemonname}
)
add_dependencies (${daemonname} ${daemonname}-init.target)
endmacro (create_init_script)

View File

@ -0,0 +1,13 @@
macro(add_glob cur_list)
file(GLOB __tmp RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} ${ARGN})
list(APPEND ${cur_list} ${__tmp})
endmacro()
macro(add_headers_and_sources prefix common_path)
add_glob(${prefix}_headers RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} include/DB/${common_path}/*.h include/DB/${common_path}/*.inl)
add_glob(${prefix}_sources src/${common_path}/*.cpp src/${common_path}/*.h)
endmacro()
macro(add_headers_only prefix common_path)
add_glob(${prefix}_headers RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} include/DB/${common_path}/*.h src/${common_path}/*.h)
endmacro()

22
cmake/find_boost.cmake Normal file
View File

@ -0,0 +1,22 @@
if (${USE_INTERNAL_BOOST_LIBRARY})
set (Boost_PROGRAM_OPTIONS_LIBRARY boost_program_options_internal)
set (Boost_SYSTEM_LIBRARY boost_system_internal)
set (Boost_FILESYSTEM_LIBRARY boost_filesystem_internal)
else ()
set (Boost_USE_STATIC_LIBS ${USE_STATIC_LIBRARIES})
set (BOOST_ROOT "/usr/local")
find_package (Boost 1.62 COMPONENTS program_options system filesystem regex thread)
if (NOT Boost_FOUND)
# Try to find manually.
set (BOOST_HINTS "")
if (USE_STATIC_LIBRARIES)
find_library (Boost_PROGRAM_OPTIONS_LIBRARY libboost_program_options.a HINTS ${BOOST_HINTS})
find_library (Boost_SYSTEM_LIBRARY libboost_system.a HINTS ${BOOST_HINTS})
find_library (Boost_FILESYSTEM_LIBRARY libboost_filesystem.a HINTS ${BOOST_HINTS})
else ()
find_library (Boost_PROGRAM_OPTIONS_LIBRARY boost_program_options HINTS ${BOOST_HINTS})
find_library (Boost_SYSTEM_LIBRARY boost_system HINTS ${BOOST_HINTS})
find_library (Boost_FILESYSTEM_LIBRARY boost_filesystem HINTS ${BOOST_HINTS})
endif ()
endif ()
endif ()

39
cmake/find_glib.cmake Normal file
View File

@ -0,0 +1,39 @@
set (GLIB_HINTS "/usr/local/opt/glib/lib")
set (GLIB_INCLUDE_HINTS
"/usr/local/include/glib-2.0/"
"/usr/local/lib/glib-2.0/include/"
"/usr/include/glib-2.0/"
"/usr/lib64/glib-2.0/include/")
if (AARCH64)
set (GLIB_INCLUDE_HINTS ${GLIB_INCLUDE_HINTS} "/usr/lib/aarch64-linux-gnu/glib-2.0/include/")
else ()
set (GLIB_INCLUDE_HINTS ${GLIB_INCLUDE_HINTS} "/usr/lib/x86_64-linux-gnu/glib-2.0/include/")
endif ()
if (USE_STATIC_LIBRARIES)
find_library (GLIB_LIB libglib-2.0.a HINTS ${GLIB_HINTS})
else ()
find_library (GLIB_LIB glib-2.0 HINTS ${GLIB_HINTS})
endif ()
find_path (GLIB_INCLUDE_DIR NAMES glib.h HINTS ${GLIB_INCLUDE_HINTS})
find_path (GLIB_CONFIG_INCLUDE_DIR NAMES glibconfig.h HINTS ${GLIB_INCLUDE_HINTS})
include_directories (${GLIB_INCLUDE_DIR})
include_directories (${GLIB_CONFIG_INCLUDE_DIR})
if (APPLE)
set (INTL_HINTS "/usr/local/opt/gettext/lib")
if (USE_STATIC_LIBRARIES)
find_library (INTL_LIB libintl.a HINTS ${INTL_HINTS})
else ()
find_library (INTL_LIB intl HINTS ${INTL_HINTS})
endif ()
set (ICONV_HINTS "/usr/local/opt/libiconv/lib")
if (USE_STATIC_LIBRARIES)
find_library (ICONV_LIB libiconv.a HINTS ${ICONV_HINTS})
else ()
find_library (ICONV_LIB iconv HINTS ${ICONV_HINTS})
endif ()
find_library (CORE_FOUNDATION_LIB CoreFoundation)
find_library (CARBON_LIB Carbon)
set (GLIB_LIBS ${GLIB_LIB} ${INTL_LIB} ${ICONV_LIB} ${CORE_FOUNDATION_LIB} ${CARBON_LIB})
else (APPLE)
set (GLIB_LIBS ${GLIB_LIB})
endif (APPLE)

12
cmake/find_icu4c.cmake Normal file
View File

@ -0,0 +1,12 @@
include_directories ("/usr/local/opt/icu4c/include")
set (ICU_HINTS "/usr/local/opt/icu4c/lib")
if (USE_STATIC_LIBRARIES)
find_library (ICUI18N libicui18n.a HINTS ${ICU_HINTS})
find_library (ICUUC libicuuc.a HINTS ${ICU_HINTS})
find_library (ICUDATA libicudata.a HINTS ${ICU_HINTS})
else ()
find_library (ICUI18N icui18n HINTS ${ICU_HINTS})
find_library (ICUUC icuuc HINTS ${ICU_HINTS})
find_library (ICUDATA icudata HINTS ${ICU_HINTS})
endif ()
set (ICU_LIBS ${ICUI18N} ${ICUUC} ${ICUDATA})

View File

@ -0,0 +1,9 @@
set (MYSQL_HINTS "/usr/local/opt/mysql/lib")
set (MYSQL_INCLUDE_HINTS "/usr/local/opt/mysql/include")
if (USE_STATIC_LIBRARIES)
find_library (STATIC_MYSQLCLIENT_LIB libmysqlclient.a HINTS ${MYSQL_HINTS})
else ()
find_library (MYSQLCLIENT_LIB mysqlclient HINTS ${MYSQL_HINTS})
endif ()
find_path (MYSQL_INCLUDE_DIR NAMES mysql.h PATH_SUFFIXES mysql HINTS ${MYSQL_INCLUDE_HINTS})
include_directories (${MYSQL_INCLUDE_DIR})

6
cmake/find_libtool.cmake Normal file
View File

@ -0,0 +1,6 @@
set (LTDL_HINTS "/usr/local/opt/libtool/lib")
if (USE_STATIC_LIBRARIES)
find_library (LTDL_LIB libltdl.a HINTS ${LTDL_HINTS})
else ()
find_library (LTDL_LIB ltdl HINTS ${LTDL_HINTS})
endif ()

21
cmake/find_openssl.cmake Normal file
View File

@ -0,0 +1,21 @@
set (OPENSSL_USE_STATIC_LIBS ${USE_STATIC_LIBRARIES})
if (APPLE)
set (OPENSSL_ROOT_DIR "/usr/local/opt/openssl")
endif ()
find_package (OpenSSL)
if (OPENSSL_FOUND)
include_directories (${OPENSSL_INCLUDE_DIR})
endif ()
if (NOT OPENSSL_FOUND)
# Try to find manually.
include_directories ("/usr/local/opt/openssl/include")
set (OPENSSL_HINTS "/usr/local/opt/openssl/lib")
if (USE_STATIC_LIBRARIES)
find_library (OPENSSL_SSL_LIBRARY libssl.a HINTS ${OPENSSL_HINTS})
find_library (OPENSSL_CRYPTO_LIBRARY libcrypto.a HINTS ${OPENSSL_HINTS})
else ()
find_library (OPENSSL_SSL_LIBRARY ssl HINTS ${OPENSSL_HINTS})
find_library (OPENSSL_CRYPTO_LIBRARY crypto HINTS ${OPENSSL_HINTS})
endif ()
set (OPENSSL_LIBRARIES ${OPENSSL_SSL_LIBRARY} ${OPENSSL_CRYPTO_LIBRARY})
endif ()

16
cmake/find_rt.cmake Normal file
View File

@ -0,0 +1,16 @@
if (APPLE)
set (RT_LIBRARIES "apple_rt")
else ()
if (USE_STATIC_LIBRARIES)
set (RT_LIBRARIES "librt.a")
else ()
set (RT_LIBRARIES "rt")
endif ()
endif ()
function (target_link_rt_by_force TARGET)
if (NOT APPLE)
set (FLAGS "-Wl,-no-as-needed -lrt -Wl,-as-needed")
set_property (TARGET ${TARGET} APPEND PROPERTY LINK_FLAGS "${FLAGS}")
endif ()
endfunction ()

View File

@ -0,0 +1,6 @@
get_property (dirs DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} PROPERTY INCLUDE_DIRECTORIES)
file (WRITE ${CMAKE_CURRENT_BINARY_DIR}/include_directories.txt "")
foreach (dir ${dirs})
string (REPLACE "${ClickHouse_SOURCE_DIR}" "." dir "${dir}")
file (APPEND ${CMAKE_CURRENT_BINARY_DIR}/include_directories.txt "-I ${dir} ")
endforeach ()

View File

@ -1,16 +1,20 @@
SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wno-old-style-cast")
set (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wno-old-style-cast")
add_subdirectory (libcityhash)
add_subdirectory (libboost)
add_subdirectory (libpoco)
add_subdirectory (liblz4)
add_subdirectory (libdouble-conversion)
add_subdirectory (libzstd)
add_subdirectory (libre2)
add_subdirectory (libdouble-conversion)
add_subdirectory (libzookeeper)
add_subdirectory (libcityhash)
add_subdirectory (libfarmhash)
add_subdirectory (libmetrohash)
add_subdirectory (libpoco)
add_subdirectory (libre2)
add_subdirectory (libtcmalloc)
add_subdirectory (libzookeeper)
IF (NOT AARCH64)
if (ENABLE_LIBTCMALLOC)
add_subdirectory (libtcmalloc)
endif ()
if (NOT AARCH64)
add_subdirectory (libcpuid)
ENDIF()
endif ()

View File

@ -0,0 +1,50 @@
add_definitions(-DBOOST_SYSTEM_NO_DEPRECATED)
add_definitions(-Wno-unused-variable)
add_library(boost_program_options_internal
boost_1_62_0/libs/program_options/src/cmdline.cpp
boost_1_62_0/libs/program_options/src/config_file.cpp
boost_1_62_0/libs/program_options/src/convert.cpp
boost_1_62_0/libs/program_options/src/options_description.cpp
boost_1_62_0/libs/program_options/src/parsers.cpp
boost_1_62_0/libs/program_options/src/positional_options.cpp
boost_1_62_0/libs/program_options/src/split.cpp
boost_1_62_0/libs/program_options/src/utf8_codecvt_facet.cpp
boost_1_62_0/libs/program_options/src/value_semantic.cpp
boost_1_62_0/libs/program_options/src/variables_map.cpp
boost_1_62_0/libs/program_options/src/winmain.cpp)
add_library(boost_filesystem_internal
boost_1_62_0/libs/filesystem/src/codecvt_error_category.cpp
boost_1_62_0/libs/filesystem/src/operations.cpp
boost_1_62_0/libs/filesystem/src/path.cpp
boost_1_62_0/libs/filesystem/src/path_traits.cpp
boost_1_62_0/libs/filesystem/src/portability.cpp
boost_1_62_0/libs/filesystem/src/unique_path.cpp
boost_1_62_0/libs/filesystem/src/utf8_codecvt_facet.cpp
boost_1_62_0/libs/filesystem/src/windows_file_codecvt.cpp)
add_library(boost_system_internal
boost_1_62_0/libs/system/src/error_code.cpp)
add_library(boost_test_internal
boost_1_62_0/libs/test/src/compiler_log_formatter.cpp
boost_1_62_0/libs/test/src/cpp_main.cpp
boost_1_62_0/libs/test/src/debug.cpp
boost_1_62_0/libs/test/src/decorator.cpp
boost_1_62_0/libs/test/src/execution_monitor.cpp
boost_1_62_0/libs/test/src/framework.cpp
boost_1_62_0/libs/test/src/junit_log_formatter.cpp
boost_1_62_0/libs/test/src/plain_report_formatter.cpp
boost_1_62_0/libs/test/src/progress_monitor.cpp
boost_1_62_0/libs/test/src/results_collector.cpp
boost_1_62_0/libs/test/src/results_reporter.cpp
boost_1_62_0/libs/test/src/test_main.cpp
boost_1_62_0/libs/test/src/test_tools.cpp
boost_1_62_0/libs/test/src/test_tree.cpp
boost_1_62_0/libs/test/src/unit_test_log.cpp
boost_1_62_0/libs/test/src/unit_test_main.cpp
boost_1_62_0/libs/test/src/unit_test_monitor.cpp
boost_1_62_0/libs/test/src/unit_test_parameters.cpp
boost_1_62_0/libs/test/src/xml_log_formatter.cpp
boost_1_62_0/libs/test/src/xml_report_formatter.cpp)

67
contrib/libboost/README Normal file
View File

@ -0,0 +1,67 @@
Motivation
==========
For reproducible build, we need to control, what exactly version of boost we build,
because different versions of boost obviously have slightly different behaviour.
You may already have installed arbitary version of boost on your system, to build another projects.
We need to have all libraries with C++ interface to be located in tree and to be build together.
This is needed to allow quickly changing build options, that could introduce changes in ABI of that libraries.
Otherwise it will be very hard to rebuild all libraries.
If you have several C++ libraries, that depend on boost, that was compiled separately with different versions of boost,
and then you try to link your program with that libraries, you either will get link error,
or even worse, you will have crashes or wrong behaviour at runtime.
Summary: boost and every library that depend on boost must be located in tree.
How to add more libraries
=========================
This is subset of boost. Feel free to copy more libraries, that you need.
Before doing that, first update boost to latest version.
How to update
=============
Feel free to update boost to latest version at any time.
Temporarily remove system boost library:
sudo mv /usr/include/boost /usr/include/boost_; sudo mv /usr/local/include/boost /usr/local/include/boost_
Download new boost and copy to this directory.
Then clean all unneeded files:
rm -rf boost_*/doc
rm -rf boost_*/tools
find . -name '*.html' | xargs rm
find . -name '*.htm' | xargs rm
find . -name '*.jam' | xargs rm
find . -name '*.xml' | xargs rm
find . -type d -and -name 'doc' | xargs rm -rf
find . -type d -and -name 'example' | xargs rm -rf
find . -type d -and -name 'meta' | xargs rm -rf
find . -name 'sublibs' | xargs rm
find . -type d -and -name 'more' | xargs rm -rf
find . -type d -and -name 'status' | xargs rm -rf
rm boost_*/INSTALL boost_*/Jamroot boost_*/boost.css boost_*/boost.png boost_*/bootstrap.* boost_*/rst.css
find . -name '*.css' | xargs rm
In project root, find out all used libraries:
find . -name '*.h' -or -name '*.cpp' -or -name '*.hpp' | grep -v contrib | xargs grep -h -o -P '<boost/\w+' | sed 's/<boost\///' | sort | uniq
Then manually remove all other libraries, by deleting directories.
Then add all internal dependencies by recursively running this command in contrib/libboost:
make 2>&1 | grep 'No such file' | tee err; grep -o -P ' boost/\w+\.h(pp)?' err | tr -d ' ' | xargs -I{} cp boost_*_/{} boost_*/{}; grep -o -P ' boost/\w+/' err | tr -d ' ' | xargs -I{} cp -r boost_*_/{} boost_*/{}
Then build project and add all missing files.
Move system boost library back:
sudo mv /usr/include/boost_ /usr/include/boost; sudo mv /usr/local/include/boost_ /usr/local/include/boost

View File

@ -0,0 +1,23 @@
Boost Software License - Version 1.0 - August 17th, 2003
Permission is hereby granted, free of charge, to any person or organization
obtaining a copy of the software and accompanying documentation covered by
this license (the "Software") to use, reproduce, display, distribute,
execute, and transmit the Software, and to prepare derivative works of the
Software, and to permit third-parties to whom the Software is furnished to
do so, all subject to the following:
The copyright notices in the Software and this entire statement, including
the above license grant, this restriction and the following disclaimer,
must be included in all copies of the Software, in whole or in part, and
all derivative works of the Software, unless such copies or derivative
works are solely in the form of machine-executable object code generated by
a source language processor.
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, TITLE AND NON-INFRINGEMENT. IN NO EVENT
SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
DEALINGS IN THE SOFTWARE.

View File

@ -0,0 +1,88 @@
/*
Copyright (c) Marshall Clow 2014.
Distributed under the Boost Software License, Version 1.0. (See accompanying
file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
Revision history:
2 Dec 2014 mtc First version; power
*/
/// \file algorithm.hpp
/// \brief Misc Algorithms
/// \author Marshall Clow
///
#ifndef BOOST_ALGORITHM_HPP
#define BOOST_ALGORITHM_HPP
#include <functional> // for plus and multiplies
#include <boost/utility/enable_if.hpp> // for boost::disable_if
#include <boost/type_traits/is_integral.hpp>
namespace boost { namespace algorithm {
template <typename T>
T identity_operation ( std::multiplies<T> ) { return T(1); }
template <typename T>
T identity_operation ( std::plus<T> ) { return T(0); }
/// \fn power ( T x, Integer n )
/// \return the value "x" raised to the power "n"
///
/// \param x The value to be exponentiated
/// \param n The exponent (must be >= 0)
///
// \remark Taken from Knuth, The Art of Computer Programming, Volume 2:
// Seminumerical Algorithms, Section 4.6.3
template <typename T, typename Integer>
typename boost::enable_if<boost::is_integral<Integer>, T>::type
power (T x, Integer n) {
T y = 1; // Should be "T y{1};"
if (n == 0) return y;
while (true) {
if (n % 2 == 1) {
y = x * y;
if (n == 1)
return y;
}
n = n / 2;
x = x * x;
}
return y;
}
/// \fn power ( T x, Integer n, Operation op )
/// \return the value "x" raised to the power "n"
/// using the operation "op".
///
/// \param x The value to be exponentiated
/// \param n The exponent (must be >= 0)
/// \param op The operation used
///
// \remark Taken from Knuth, The Art of Computer Programming, Volume 2:
// Seminumerical Algorithms, Section 4.6.3
template <typename T, typename Integer, typename Operation>
typename boost::enable_if<boost::is_integral<Integer>, T>::type
power (T x, Integer n, Operation op) {
T y = identity_operation(op);
if (n == 0) return y;
while (true) {
if (n % 2 == 1) {
y = op(x, y);
if (n == 1)
return y;
}
n = n / 2;
x = op(x, x);
}
return y;
}
}}
#endif // BOOST_ALGORITHM_HPP

View File

@ -0,0 +1,175 @@
/*
Copyright (c) Marshall Clow 2008-2012.
Distributed under the Boost Software License, Version 1.0. (See accompanying
file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
Revision history:
27 June 2009 mtc First version
23 Oct 2010 mtc Added predicate version
*/
/// \file clamp.hpp
/// \brief Clamp algorithm
/// \author Marshall Clow
///
/// Suggested by olafvdspek in https://svn.boost.org/trac/boost/ticket/3215
#ifndef BOOST_ALGORITHM_CLAMP_HPP
#define BOOST_ALGORITHM_CLAMP_HPP
#include <functional> // For std::less
#include <iterator> // For std::iterator_traits
#include <cassert>
#include <boost/range/begin.hpp>
#include <boost/range/end.hpp>
#include <boost/mpl/identity.hpp> // for identity
#include <boost/utility/enable_if.hpp> // for boost::disable_if
namespace boost { namespace algorithm {
/// \fn clamp ( T const& val,
/// typename boost::mpl::identity<T>::type const & lo,
/// typename boost::mpl::identity<T>::type const & hi, Pred p )
/// \return the value "val" brought into the range [ lo, hi ]
/// using the comparison predicate p.
/// If p ( val, lo ) return lo.
/// If p ( hi, val ) return hi.
/// Otherwise, return the original value.
///
/// \param val The value to be clamped
/// \param lo The lower bound of the range to be clamped to
/// \param hi The upper bound of the range to be clamped to
/// \param p A predicate to use to compare the values.
/// p ( a, b ) returns a boolean.
///
template<typename T, typename Pred>
T const & clamp ( T const& val,
typename boost::mpl::identity<T>::type const & lo,
typename boost::mpl::identity<T>::type const & hi, Pred p )
{
// assert ( !p ( hi, lo )); // Can't assert p ( lo, hi ) b/c they might be equal
return p ( val, lo ) ? lo : p ( hi, val ) ? hi : val;
}
/// \fn clamp ( T const& val,
/// typename boost::mpl::identity<T>::type const & lo,
/// typename boost::mpl::identity<T>::type const & hi )
/// \return the value "val" brought into the range [ lo, hi ].
/// If the value is less than lo, return lo.
/// If the value is greater than "hi", return hi.
/// Otherwise, return the original value.
///
/// \param val The value to be clamped
/// \param lo The lower bound of the range to be clamped to
/// \param hi The upper bound of the range to be clamped to
///
template<typename T>
T const& clamp ( const T& val,
typename boost::mpl::identity<T>::type const & lo,
typename boost::mpl::identity<T>::type const & hi )
{
return (clamp) ( val, lo, hi, std::less<T>());
}
/// \fn clamp_range ( InputIterator first, InputIterator last, OutputIterator out,
/// std::iterator_traits<InputIterator>::value_type const & lo,
/// std::iterator_traits<InputIterator>::value_type const & hi )
/// \return clamp the sequence of values [first, last) into [ lo, hi ]
///
/// \param first The start of the range of values
/// \param last One past the end of the range of input values
/// \param out An output iterator to write the clamped values into
/// \param lo The lower bound of the range to be clamped to
/// \param hi The upper bound of the range to be clamped to
///
template<typename InputIterator, typename OutputIterator>
OutputIterator clamp_range ( InputIterator first, InputIterator last, OutputIterator out,
typename std::iterator_traits<InputIterator>::value_type const & lo,
typename std::iterator_traits<InputIterator>::value_type const & hi )
{
// this could also be written with bind and std::transform
while ( first != last )
*out++ = clamp ( *first++, lo, hi );
return out;
}
/// \fn clamp_range ( const Range &r, OutputIterator out,
/// typename std::iterator_traits<typename boost::range_iterator<const Range>::type>::value_type const & lo,
/// typename std::iterator_traits<typename boost::range_iterator<const Range>::type>::value_type const & hi )
/// \return clamp the sequence of values [first, last) into [ lo, hi ]
///
/// \param r The range of values to be clamped
/// \param out An output iterator to write the clamped values into
/// \param lo The lower bound of the range to be clamped to
/// \param hi The upper bound of the range to be clamped to
///
template<typename Range, typename OutputIterator>
typename boost::disable_if_c<boost::is_same<Range, OutputIterator>::value, OutputIterator>::type
clamp_range ( const Range &r, OutputIterator out,
typename std::iterator_traits<typename boost::range_iterator<const Range>::type>::value_type const & lo,
typename std::iterator_traits<typename boost::range_iterator<const Range>::type>::value_type const & hi )
{
return clamp_range ( boost::begin ( r ), boost::end ( r ), out, lo, hi );
}
/// \fn clamp_range ( InputIterator first, InputIterator last, OutputIterator out,
/// std::iterator_traits<InputIterator>::value_type const & lo,
/// std::iterator_traits<InputIterator>::value_type const & hi, Pred p )
/// \return clamp the sequence of values [first, last) into [ lo, hi ]
/// using the comparison predicate p.
///
/// \param first The start of the range of values
/// \param last One past the end of the range of input values
/// \param out An output iterator to write the clamped values into
/// \param lo The lower bound of the range to be clamped to
/// \param hi The upper bound of the range to be clamped to
/// \param p A predicate to use to compare the values.
/// p ( a, b ) returns a boolean.
///
template<typename InputIterator, typename OutputIterator, typename Pred>
OutputIterator clamp_range ( InputIterator first, InputIterator last, OutputIterator out,
typename std::iterator_traits<InputIterator>::value_type const & lo,
typename std::iterator_traits<InputIterator>::value_type const & hi, Pred p )
{
// this could also be written with bind and std::transform
while ( first != last )
*out++ = clamp ( *first++, lo, hi, p );
return out;
}
/// \fn clamp_range ( const Range &r, OutputIterator out,
/// typename std::iterator_traits<typename boost::range_iterator<const Range>::type>::value_type const & lo,
/// typename std::iterator_traits<typename boost::range_iterator<const Range>::type>::value_type const & hi,
/// Pred p )
/// \return clamp the sequence of values [first, last) into [ lo, hi ]
/// using the comparison predicate p.
///
/// \param r The range of values to be clamped
/// \param out An output iterator to write the clamped values into
/// \param lo The lower bound of the range to be clamped to
/// \param hi The upper bound of the range to be clamped to
/// \param p A predicate to use to compare the values.
/// p ( a, b ) returns a boolean.
//
// Disable this template if the first two parameters are the same type;
// In that case, the user will get the two iterator version.
template<typename Range, typename OutputIterator, typename Pred>
typename boost::disable_if_c<boost::is_same<Range, OutputIterator>::value, OutputIterator>::type
clamp_range ( const Range &r, OutputIterator out,
typename std::iterator_traits<typename boost::range_iterator<const Range>::type>::value_type const & lo,
typename std::iterator_traits<typename boost::range_iterator<const Range>::type>::value_type const & hi,
Pred p )
{
return clamp_range ( boost::begin ( r ), boost::end ( r ), out, lo, hi, p );
}
}}
#endif // BOOST_ALGORITHM_CLAMP_HPP

View File

@ -0,0 +1,83 @@
/*
Copyright (c) Marshall Clow 2008-2012.
Distributed under the Boost Software License, Version 1.0. (See accompanying
file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
*/
/// \file all_of.hpp
/// \brief Test ranges to see if all elements match a value or predicate.
/// \author Marshall Clow
#ifndef BOOST_ALGORITHM_ALL_OF_HPP
#define BOOST_ALGORITHM_ALL_OF_HPP
#include <boost/range/begin.hpp>
#include <boost/range/end.hpp>
namespace boost { namespace algorithm {
/// \fn all_of ( InputIterator first, InputIterator last, Predicate p )
/// \return true if all elements in [first, last) satisfy the predicate 'p'
/// \note returns true on an empty range
///
/// \param first The start of the input sequence
/// \param last One past the end of the input sequence
/// \param p A predicate for testing the elements of the sequence
///
/// \note This function is part of the C++2011 standard library.
template<typename InputIterator, typename Predicate>
bool all_of ( InputIterator first, InputIterator last, Predicate p )
{
for ( ; first != last; ++first )
if ( !p(*first))
return false;
return true;
}
/// \fn all_of ( const Range &r, Predicate p )
/// \return true if all elements in the range satisfy the predicate 'p'
/// \note returns true on an empty range
///
/// \param r The input range
/// \param p A predicate for testing the elements of the range
///
template<typename Range, typename Predicate>
bool all_of ( const Range &r, Predicate p )
{
return boost::algorithm::all_of ( boost::begin (r), boost::end (r), p );
}
/// \fn all_of_equal ( InputIterator first, InputIterator last, const T &val )
/// \return true if all elements in [first, last) are equal to 'val'
/// \note returns true on an empty range
///
/// \param first The start of the input sequence
/// \param last One past the end of the input sequence
/// \param val A value to compare against
///
template<typename InputIterator, typename T>
bool all_of_equal ( InputIterator first, InputIterator last, const T &val )
{
for ( ; first != last; ++first )
if ( val != *first )
return false;
return true;
}
/// \fn all_of_equal ( const Range &r, const T &val )
/// \return true if all elements in the range are equal to 'val'
/// \note returns true on an empty range
///
/// \param r The input range
/// \param val A value to compare against
///
template<typename Range, typename T>
bool all_of_equal ( const Range &r, const T &val )
{
return boost::algorithm::all_of_equal ( boost::begin (r), boost::end (r), val );
}
}} // namespace boost and algorithm
#endif // BOOST_ALGORITHM_ALL_OF_HPP

View File

@ -0,0 +1,84 @@
/*
Copyright (c) Marshall Clow 2008-2012.
Distributed under the Boost Software License, Version 1.0. (See accompanying
file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
For more information, see http://www.boost.org
*/
/// \file
/// \brief Test ranges to see if any elements match a value or predicate.
/// \author Marshall Clow
#ifndef BOOST_ALGORITHM_ANY_OF_HPP
#define BOOST_ALGORITHM_ANY_OF_HPP
#include <boost/range/begin.hpp>
#include <boost/range/end.hpp>
namespace boost { namespace algorithm {
/// \fn any_of ( InputIterator first, InputIterator last, Predicate p )
/// \return true if any of the elements in [first, last) satisfy the predicate
/// \note returns false on an empty range
///
/// \param first The start of the input sequence
/// \param last One past the end of the input sequence
/// \param p A predicate for testing the elements of the sequence
///
template<typename InputIterator, typename Predicate>
bool any_of ( InputIterator first, InputIterator last, Predicate p )
{
for ( ; first != last; ++first )
if ( p(*first))
return true;
return false;
}
/// \fn any_of ( const Range &r, Predicate p )
/// \return true if any elements in the range satisfy the predicate 'p'
/// \note returns false on an empty range
///
/// \param r The input range
/// \param p A predicate for testing the elements of the range
///
template<typename Range, typename Predicate>
bool any_of ( const Range &r, Predicate p )
{
return boost::algorithm::any_of (boost::begin (r), boost::end (r), p);
}
/// \fn any_of_equal ( InputIterator first, InputIterator last, const V &val )
/// \return true if any of the elements in [first, last) are equal to 'val'
/// \note returns false on an empty range
///
/// \param first The start of the input sequence
/// \param last One past the end of the input sequence
/// \param val A value to compare against
///
template<typename InputIterator, typename V>
bool any_of_equal ( InputIterator first, InputIterator last, const V &val )
{
for ( ; first != last; ++first )
if ( val == *first )
return true;
return false;
}
/// \fn any_of_equal ( const Range &r, const V &val )
/// \return true if any of the elements in the range are equal to 'val'
/// \note returns false on an empty range
///
/// \param r The input range
/// \param val A value to compare against
///
template<typename Range, typename V>
bool any_of_equal ( const Range &r, const V &val )
{
return boost::algorithm::any_of_equal (boost::begin (r), boost::end (r), val);
}
}} // namespace boost and algorithm
#endif // BOOST_ALGORITHM_ANY_OF_HPP

View File

@ -0,0 +1,129 @@
/*
Copyright (c) Marshall Clow 2008-2012.
Distributed under the Boost Software License, Version 1.0. (See accompanying
file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
*/
/// \file copy_if.hpp
/// \brief Copy a subset of a sequence to a new sequence
/// \author Marshall Clow
#ifndef BOOST_ALGORITHM_COPY_IF_HPP
#define BOOST_ALGORITHM_COPY_IF_HPP
#include <utility> // for std::pair, std::make_pair
#include <boost/range/begin.hpp>
#include <boost/range/end.hpp>
namespace boost { namespace algorithm {
/// \fn copy_if ( InputIterator first, InputIterator last, OutputIterator result, Predicate p )
/// \brief Copies all the elements from the input range that satisfy the
/// predicate to the output range.
/// \return The updated output iterator
///
/// \param first The start of the input sequence
/// \param last One past the end of the input sequence
/// \param result An output iterator to write the results into
/// \param p A predicate for testing the elements of the range
/// \note This function is part of the C++2011 standard library.
template<typename InputIterator, typename OutputIterator, typename Predicate>
OutputIterator copy_if ( InputIterator first, InputIterator last, OutputIterator result, Predicate p )
{
for ( ; first != last; ++first )
if (p(*first))
*result++ = *first;
return result;
}
/// \fn copy_if ( const Range &r, OutputIterator result, Predicate p )
/// \brief Copies all the elements from the input range that satisfy the
/// predicate to the output range.
/// \return The updated output iterator
///
/// \param r The input range
/// \param result An output iterator to write the results into
/// \param p A predicate for testing the elements of the range
///
template<typename Range, typename OutputIterator, typename Predicate>
OutputIterator copy_if ( const Range &r, OutputIterator result, Predicate p )
{
return boost::algorithm::copy_if (boost::begin (r), boost::end(r), result, p);
}
/// \fn copy_while ( InputIterator first, InputIterator last, OutputIterator result, Predicate p )
/// \brief Copies all the elements at the start of the input range that
/// satisfy the predicate to the output range.
/// \return The updated input and output iterators
///
/// \param first The start of the input sequence
/// \param last One past the end of the input sequence
/// \param result An output iterator to write the results into
/// \param p A predicate for testing the elements of the range
///
template<typename InputIterator, typename OutputIterator, typename Predicate>
std::pair<InputIterator, OutputIterator>
copy_while ( InputIterator first, InputIterator last, OutputIterator result, Predicate p )
{
for ( ; first != last && p(*first); ++first )
*result++ = *first;
return std::make_pair(first, result);
}
/// \fn copy_while ( const Range &r, OutputIterator result, Predicate p )
/// \brief Copies all the elements at the start of the input range that
/// satisfy the predicate to the output range.
/// \return The updated input and output iterators
///
/// \param r The input range
/// \param result An output iterator to write the results into
/// \param p A predicate for testing the elements of the range
///
template<typename Range, typename OutputIterator, typename Predicate>
std::pair<typename boost::range_iterator<const Range>::type, OutputIterator>
copy_while ( const Range &r, OutputIterator result, Predicate p )
{
return boost::algorithm::copy_while (boost::begin (r), boost::end(r), result, p);
}
/// \fn copy_until ( InputIterator first, InputIterator last, OutputIterator result, Predicate p )
/// \brief Copies all the elements at the start of the input range that do not
/// satisfy the predicate to the output range.
/// \return The updated output iterator
///
/// \param first The start of the input sequence
/// \param last One past the end of the input sequence
/// \param result An output iterator to write the results into
/// \param p A predicate for testing the elements of the range
///
template<typename InputIterator, typename OutputIterator, typename Predicate>
std::pair<InputIterator, OutputIterator>
copy_until ( InputIterator first, InputIterator last, OutputIterator result, Predicate p )
{
for ( ; first != last && !p(*first); ++first )
*result++ = *first;
return std::make_pair(first, result);
}
/// \fn copy_until ( const Range &r, OutputIterator result, Predicate p )
/// \brief Copies all the elements at the start of the input range that do not
/// satisfy the predicate to the output range.
/// \return The updated output iterator
///
/// \param r The input range
/// \param result An output iterator to write the results into
/// \param p A predicate for testing the elements of the range
///
template<typename Range, typename OutputIterator, typename Predicate>
std::pair<typename boost::range_iterator<const Range>::type, OutputIterator>
copy_until ( const Range &r, OutputIterator result, Predicate p )
{
return boost::algorithm::copy_until (boost::begin (r), boost::end(r), result, p);
}
}} // namespace boost and algorithm
#endif // BOOST_ALGORITHM_COPY_IF_HPP

View File

@ -0,0 +1,35 @@
/*
Copyright (c) Marshall Clow 2011-2012.
Distributed under the Boost Software License, Version 1.0. (See accompanying
file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
*/
/// \file copy_n.hpp
/// \brief Copy n items from one sequence to another
/// \author Marshall Clow
#ifndef BOOST_ALGORITHM_COPY_N_HPP
#define BOOST_ALGORITHM_COPY_N_HPP
namespace boost { namespace algorithm {
/// \fn copy_n ( InputIterator first, Size n, OutputIterator result )
/// \brief Copies exactly n (n > 0) elements from the range starting at first to
/// the range starting at result.
/// \return The updated output iterator
///
/// \param first The start of the input sequence
/// \param n The number of elements to copy
/// \param result An output iterator to write the results into
/// \note This function is part of the C++2011 standard library.
template <typename InputIterator, typename Size, typename OutputIterator>
OutputIterator copy_n ( InputIterator first, Size n, OutputIterator result )
{
for ( ; n > 0; --n, ++first, ++result )
*result = *first;
return result;
}
}} // namespace boost and algorithm
#endif // BOOST_ALGORITHM_COPY_IF_HPP

View File

@ -0,0 +1,51 @@
/*
Copyright (c) Marshall Clow 2011-2012.
Distributed under the Boost Software License, Version 1.0. (See accompanying
file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
*/
/// \file find_if_not.hpp
/// \brief Find the first element in a sequence that does not satisfy a predicate.
/// \author Marshall Clow
#ifndef BOOST_ALGORITHM_FIND_IF_NOT_HPP
#define BOOST_ALGORITHM_FIND_IF_NOT_HPP
#include <boost/range/begin.hpp>
#include <boost/range/end.hpp>
namespace boost { namespace algorithm {
/// \fn find_if_not(InputIterator first, InputIterator last, Predicate p)
/// \brief Finds the first element in the sequence that does not satisfy the predicate.
/// \return The iterator pointing to the desired element.
///
/// \param first The start of the input sequence
/// \param last One past the end of the input sequence
/// \param p A predicate for testing the elements of the range
/// \note This function is part of the C++2011 standard library.
template<typename InputIterator, typename Predicate>
InputIterator find_if_not ( InputIterator first, InputIterator last, Predicate p )
{
for ( ; first != last; ++first )
if ( !p(*first))
break;
return first;
}
/// \fn find_if_not ( const Range &r, Predicate p )
/// \brief Finds the first element in the sequence that does not satisfy the predicate.
/// \return The iterator pointing to the desired element.
///
/// \param r The input range
/// \param p A predicate for testing the elements of the range
///
template<typename Range, typename Predicate>
typename boost::range_iterator<const Range>::type find_if_not ( const Range &r, Predicate p )
{
return boost::algorithm::find_if_not (boost::begin (r), boost::end(r), p);
}
}}
#endif // BOOST_ALGORITHM_FIND_IF_NOT_HPP

View File

@ -0,0 +1,65 @@
/*
Copyright (c) Marshall Clow 2008-2012.
Distributed under the Boost Software License, Version 1.0. (See accompanying
file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
*/
/// \file iota.hpp
/// \brief Generate an increasing series
/// \author Marshall Clow
#ifndef BOOST_ALGORITHM_IOTA_HPP
#define BOOST_ALGORITHM_IOTA_HPP
#include <boost/range/begin.hpp>
#include <boost/range/end.hpp>
namespace boost { namespace algorithm {
/// \fn iota ( ForwardIterator first, ForwardIterator last, T value )
/// \brief Generates an increasing sequence of values, and stores them in [first, last)
///
/// \param first The start of the input sequence
/// \param last One past the end of the input sequence
/// \param value The initial value of the sequence to be generated
/// \note This function is part of the C++2011 standard library.
template <typename ForwardIterator, typename T>
void iota ( ForwardIterator first, ForwardIterator last, T value )
{
for ( ; first != last; ++first, ++value )
*first = value;
}
/// \fn iota ( Range &r, T value )
/// \brief Generates an increasing sequence of values, and stores them in the input Range.
///
/// \param r The input range
/// \param value The initial value of the sequence to be generated
///
template <typename Range, typename T>
void iota ( Range &r, T value )
{
boost::algorithm::iota (boost::begin(r), boost::end(r), value);
}
/// \fn iota_n ( OutputIterator out, T value, std::size_t n )
/// \brief Generates an increasing sequence of values, and stores them in the input Range.
///
/// \param out An output iterator to write the results into
/// \param value The initial value of the sequence to be generated
/// \param n The number of items to write
///
template <typename OutputIterator, typename T>
OutputIterator iota_n ( OutputIterator out, T value, std::size_t n )
{
for ( ; n > 0; --n, ++value )
*out++ = value;
return out;
}
}}
#endif // BOOST_ALGORITHM_IOTA_HPP

View File

@ -0,0 +1,56 @@
/*
Copyright (c) Marshall Clow 2011-2012.
Distributed under the Boost Software License, Version 1.0. (See accompanying
file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
*/
/// \file is_partitioned.hpp
/// \brief Tell if a sequence is partitioned
/// \author Marshall Clow
#ifndef BOOST_ALGORITHM_IS_PARTITIONED_HPP
#define BOOST_ALGORITHM_IS_PARTITIONED_HPP
#include <boost/range/begin.hpp>
#include <boost/range/end.hpp>
namespace boost { namespace algorithm {
/// \fn is_partitioned ( InputIterator first, InputIterator last, UnaryPredicate p )
/// \brief Tests to see if a sequence is partitioned according to a predicate
///
/// \param first The start of the input sequence
/// \param last One past the end of the input sequence
/// \param p The predicate to test the values with
/// \note This function is part of the C++2011 standard library.
template <typename InputIterator, typename UnaryPredicate>
bool is_partitioned ( InputIterator first, InputIterator last, UnaryPredicate p )
{
// Run through the part that satisfy the predicate
for ( ; first != last; ++first )
if ( !p (*first))
break;
// Now the part that does not satisfy the predicate
for ( ; first != last; ++first )
if ( p (*first))
return false;
return true;
}
/// \fn is_partitioned ( const Range &r, UnaryPredicate p )
/// \brief Generates an increasing sequence of values, and stores them in the input Range.
///
/// \param r The input range
/// \param p The predicate to test the values with
///
template <typename Range, typename UnaryPredicate>
bool is_partitioned ( const Range &r, UnaryPredicate p )
{
return boost::algorithm::is_partitioned (boost::begin(r), boost::end(r), p);
}
}}
#endif // BOOST_ALGORITHM_IS_PARTITIONED_HPP

View File

@ -0,0 +1,185 @@
/*
Copyright (c) Marshall Clow 2011-2012.
Distributed under the Boost Software License, Version 1.0. (See accompanying
file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
*/
/// \file is_permutation.hpp
/// \brief Is a sequence a permutation of another sequence
/// \author Marshall Clow
#ifndef BOOST_ALGORITHM_IS_PERMUTATION11_HPP
#define BOOST_ALGORITHM_IS_PERMUTATION11_HPP
#include <algorithm> // for std::find_if, count_if, mismatch
#include <utility> // for std::pair
#include <functional> // for std::equal_to
#include <iterator>
#include <boost/range/begin.hpp>
#include <boost/range/end.hpp>
#include <boost/utility/enable_if.hpp>
#include <boost/type_traits/is_same.hpp>
namespace boost { namespace algorithm {
/// \cond DOXYGEN_HIDE
namespace detail {
template <typename Predicate, typename Iterator>
struct value_predicate {
value_predicate ( Predicate p, Iterator it ) : p_ ( p ), it_ ( it ) {}
template <typename T1>
bool operator () ( const T1 &t1 ) const { return p_ ( *it_, t1 ); }
private:
Predicate p_;
Iterator it_;
};
// Preconditions:
// 1. The sequences are the same length
// 2. Any common elements on the front have been removed (not necessary for correctness, just for performance)
template< class ForwardIterator1, class ForwardIterator2, class BinaryPredicate >
bool is_permutation_inner ( ForwardIterator1 first1, ForwardIterator1 last1,
ForwardIterator2 first2, ForwardIterator2 last2,
BinaryPredicate p ) {
// for each unique value in the sequence [first1,last1), count how many times
// it occurs, and make sure it occurs the same number of times in [first2, last2)
for ( ForwardIterator1 iter = first1; iter != last1; ++iter ) {
value_predicate<BinaryPredicate, ForwardIterator1> pred ( p, iter );
/* For each value we haven't seen yet... */
if ( std::find_if ( first1, iter, pred ) == iter ) {
std::size_t dest_count = std::count_if ( first2, last2, pred );
if ( dest_count == 0 || dest_count != (std::size_t) std::count_if ( iter, last1, pred ))
return false;
}
}
return true;
}
template< class ForwardIterator1, class ForwardIterator2, class BinaryPredicate>
bool is_permutation_tag ( ForwardIterator1 first1, ForwardIterator1 last1,
ForwardIterator2 first2, ForwardIterator2 last2,
BinaryPredicate p,
std::forward_iterator_tag, std::forward_iterator_tag ) {
// Skip the common prefix (if any)
while ( first1 != last1 && first2 != last2 && p ( *first1, *first2 )) {
++first1;
++first2;
}
if ( first1 != last1 && first2 != last2 )
return boost::algorithm::detail::is_permutation_inner ( first1, last1, first2, last2,
std::equal_to<typename std::iterator_traits<ForwardIterator1>::value_type> ());
return first1 == last1 && first2 == last2;
}
template <class RandomAccessIterator1, class RandomAccessIterator2, class BinaryPredicate>
bool is_permutation_tag ( RandomAccessIterator1 first1, RandomAccessIterator1 last1,
RandomAccessIterator2 first2, RandomAccessIterator2 last2,
BinaryPredicate p,
std::random_access_iterator_tag, std::random_access_iterator_tag ) {
// Cheap check
if ( std::distance ( first1, last1 ) != std::distance ( first2, last2 ))
return false;
// Skip the common prefix (if any)
while ( first1 != last1 && first2 != last2 && p ( *first1, *first2 )) {
++first1;
++first2;
}
if ( first1 != last1 && first2 != last2 )
return is_permutation_inner (first1, last1, first2, last2, p);
return first1 == last1 && first2 == last2;
}
}
/// \endcond
/// \fn is_permutation ( ForwardIterator1 first, ForwardIterator1 last, ForwardIterator2 first2, BinaryPredicate p )
/// \brief Tests to see if the sequence [first,last) is a permutation of the sequence starting at first2
///
/// \param first1 The start of the input sequence
/// \param last1 One past the end of the input sequence
/// \param first2 The start of the second sequence
/// \param p The predicate to compare elements with
///
/// \note This function is part of the C++2011 standard library.
template< class ForwardIterator1, class ForwardIterator2, class BinaryPredicate >
bool is_permutation ( ForwardIterator1 first1, ForwardIterator1 last1,
ForwardIterator2 first2, BinaryPredicate p )
{
// Skip the common prefix (if any)
std::pair<ForwardIterator1, ForwardIterator2> eq = std::mismatch (first1, last1, first2, p);
first1 = eq.first;
first2 = eq.second;
if ( first1 != last1 ) {
// Create last2
ForwardIterator2 last2 = first2;
std::advance ( last2, std::distance (first1, last1));
return boost::algorithm::detail::is_permutation_inner ( first1, last1, first2, last2, p );
}
return true;
}
/// \fn is_permutation ( ForwardIterator1 first, ForwardIterator1 last, ForwardIterator2 first2 )
/// \brief Tests to see if the sequence [first,last) is a permutation of the sequence starting at first2
///
/// \param first1 The start of the input sequence
/// \param last2 One past the end of the input sequence
/// \param first2 The start of the second sequence
/// \note This function is part of the C++2011 standard library.
template< class ForwardIterator1, class ForwardIterator2 >
bool is_permutation ( ForwardIterator1 first1, ForwardIterator1 last1, ForwardIterator2 first2 )
{
// How should I deal with the idea that ForwardIterator1::value_type
// and ForwardIterator2::value_type could be different? Define my own comparison predicate?
// Skip the common prefix (if any)
std::pair<ForwardIterator1, ForwardIterator2> eq = std::mismatch (first1, last1, first2 );
first1 = eq.first;
first2 = eq.second;
if ( first1 != last1 ) {
// Create last2
ForwardIterator2 last2 = first2;
std::advance ( last2, std::distance (first1, last1));
return boost::algorithm::detail::is_permutation_inner ( first1, last1, first2, last2,
std::equal_to<typename std::iterator_traits<ForwardIterator1>::value_type> ());
}
return true;
}
/// \fn is_permutation ( const Range &r, ForwardIterator first2 )
/// \brief Tests to see if the sequence [first,last) is a permutation of the sequence starting at first2
///
/// \param r The input range
/// \param first2 The start of the second sequence
template <typename Range, typename ForwardIterator>
bool is_permutation ( const Range &r, ForwardIterator first2 )
{
return boost::algorithm::is_permutation (boost::begin (r), boost::end (r), first2 );
}
/// \fn is_permutation ( const Range &r, ForwardIterator first2, BinaryPredicate pred )
/// \brief Tests to see if the sequence [first,last) is a permutation of the sequence starting at first2
///
/// \param r The input range
/// \param first2 The start of the second sequence
/// \param pred The predicate to compare elements with
///
// Disable this template when the first two parameters are the same type
// That way the non-range version will be chosen.
template <typename Range, typename ForwardIterator, typename BinaryPredicate>
typename boost::disable_if_c<boost::is_same<Range, ForwardIterator>::value, bool>::type
is_permutation ( const Range &r, ForwardIterator first2, BinaryPredicate pred )
{
return boost::algorithm::is_permutation (boost::begin (r), boost::end (r), first2, pred );
}
}}
#endif // BOOST_ALGORITHM_IS_PERMUTATION11_HPP

View File

@ -0,0 +1,280 @@
// Copyright (c) 2010 Nuovation System Designs, LLC
// Grant Erickson <gerickson@nuovations.com>
//
// Reworked somewhat by Marshall Clow; August 2010
//
// Distributed under the Boost Software License, Version 1.0. (See
// accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
//
// See http://www.boost.org/ for latest version.
//
#ifndef BOOST_ALGORITHM_ORDERED_HPP
#define BOOST_ALGORITHM_ORDERED_HPP
#include <functional>
#include <iterator>
#include <boost/range/begin.hpp>
#include <boost/range/end.hpp>
#include <boost/utility/enable_if.hpp>
#include <boost/type_traits/is_same.hpp>
#include <boost/mpl/identity.hpp>
namespace boost { namespace algorithm {
/// \fn is_sorted_until ( ForwardIterator first, ForwardIterator last, Pred p )
/// \return the point in the sequence [first, last) where the elements are unordered
/// (according to the comparison predicate 'p').
///
/// \param first The start of the sequence to be tested.
/// \param last One past the end of the sequence
/// \param p A binary predicate that returns true if two elements are ordered.
///
template <typename ForwardIterator, typename Pred>
ForwardIterator is_sorted_until ( ForwardIterator first, ForwardIterator last, Pred p )
{
if ( first == last ) return last; // the empty sequence is ordered
ForwardIterator next = first;
while ( ++next != last )
{
if ( p ( *next, *first ))
return next;
first = next;
}
return last;
}
/// \fn is_sorted_until ( ForwardIterator first, ForwardIterator last )
/// \return the point in the sequence [first, last) where the elements are unordered
///
/// \param first The start of the sequence to be tested.
/// \param last One past the end of the sequence
///
template <typename ForwardIterator>
ForwardIterator is_sorted_until ( ForwardIterator first, ForwardIterator last )
{
typedef typename std::iterator_traits<ForwardIterator>::value_type value_type;
return boost::algorithm::is_sorted_until ( first, last, std::less<value_type>());
}
/// \fn is_sorted ( ForwardIterator first, ForwardIterator last, Pred p )
/// \return whether or not the entire sequence is sorted
///
/// \param first The start of the sequence to be tested.
/// \param last One past the end of the sequence
/// \param p A binary predicate that returns true if two elements are ordered.
///
template <typename ForwardIterator, typename Pred>
bool is_sorted ( ForwardIterator first, ForwardIterator last, Pred p )
{
return boost::algorithm::is_sorted_until (first, last, p) == last;
}
/// \fn is_sorted ( ForwardIterator first, ForwardIterator last )
/// \return whether or not the entire sequence is sorted
///
/// \param first The start of the sequence to be tested.
/// \param last One past the end of the sequence
///
template <typename ForwardIterator>
bool is_sorted ( ForwardIterator first, ForwardIterator last )
{
return boost::algorithm::is_sorted_until (first, last) == last;
}
///
/// -- Range based versions of the C++11 functions
///
/// \fn is_sorted_until ( const R &range, Pred p )
/// \return the point in the range R where the elements are unordered
/// (according to the comparison predicate 'p').
///
/// \param range The range to be tested.
/// \param p A binary predicate that returns true if two elements are ordered.
///
template <typename R, typename Pred>
typename boost::lazy_disable_if_c<
boost::is_same<R, Pred>::value,
typename boost::range_iterator<const R>
>::type is_sorted_until ( const R &range, Pred p )
{
return boost::algorithm::is_sorted_until ( boost::begin ( range ), boost::end ( range ), p );
}
/// \fn is_sorted_until ( const R &range )
/// \return the point in the range R where the elements are unordered
///
/// \param range The range to be tested.
///
template <typename R>
typename boost::range_iterator<const R>::type is_sorted_until ( const R &range )
{
return boost::algorithm::is_sorted_until ( boost::begin ( range ), boost::end ( range ));
}
/// \fn is_sorted ( const R &range, Pred p )
/// \return whether or not the entire range R is sorted
/// (according to the comparison predicate 'p').
///
/// \param range The range to be tested.
/// \param p A binary predicate that returns true if two elements are ordered.
///
template <typename R, typename Pred>
typename boost::lazy_disable_if_c< boost::is_same<R, Pred>::value, boost::mpl::identity<bool> >::type
is_sorted ( const R &range, Pred p )
{
return boost::algorithm::is_sorted ( boost::begin ( range ), boost::end ( range ), p );
}
/// \fn is_sorted ( const R &range )
/// \return whether or not the entire range R is sorted
///
/// \param range The range to be tested.
///
template <typename R>
bool is_sorted ( const R &range )
{
return boost::algorithm::is_sorted ( boost::begin ( range ), boost::end ( range ));
}
///
/// -- Range based versions of the C++11 functions
///
/// \fn is_increasing ( ForwardIterator first, ForwardIterator last )
/// \return true if the entire sequence is increasing; i.e, each item is greater than or
/// equal to the previous one.
///
/// \param first The start of the sequence to be tested.
/// \param last One past the end of the sequence
///
/// \note This function will return true for sequences that contain items that compare
/// equal. If that is not what you intended, you should use is_strictly_increasing instead.
template <typename ForwardIterator>
bool is_increasing ( ForwardIterator first, ForwardIterator last )
{
typedef typename std::iterator_traits<ForwardIterator>::value_type value_type;
return boost::algorithm::is_sorted (first, last, std::less<value_type>());
}
/// \fn is_increasing ( const R &range )
/// \return true if the entire sequence is increasing; i.e, each item is greater than or
/// equal to the previous one.
///
/// \param range The range to be tested.
///
/// \note This function will return true for sequences that contain items that compare
/// equal. If that is not what you intended, you should use is_strictly_increasing instead.
template <typename R>
bool is_increasing ( const R &range )
{
return is_increasing ( boost::begin ( range ), boost::end ( range ));
}
/// \fn is_decreasing ( ForwardIterator first, ForwardIterator last )
/// \return true if the entire sequence is decreasing; i.e, each item is less than
/// or equal to the previous one.
///
/// \param first The start of the sequence to be tested.
/// \param last One past the end of the sequence
///
/// \note This function will return true for sequences that contain items that compare
/// equal. If that is not what you intended, you should use is_strictly_decreasing instead.
template <typename ForwardIterator>
bool is_decreasing ( ForwardIterator first, ForwardIterator last )
{
typedef typename std::iterator_traits<ForwardIterator>::value_type value_type;
return boost::algorithm::is_sorted (first, last, std::greater<value_type>());
}
/// \fn is_decreasing ( const R &range )
/// \return true if the entire sequence is decreasing; i.e, each item is less than
/// or equal to the previous one.
///
/// \param range The range to be tested.
///
/// \note This function will return true for sequences that contain items that compare
/// equal. If that is not what you intended, you should use is_strictly_decreasing instead.
template <typename R>
bool is_decreasing ( const R &range )
{
return is_decreasing ( boost::begin ( range ), boost::end ( range ));
}
/// \fn is_strictly_increasing ( ForwardIterator first, ForwardIterator last )
/// \return true if the entire sequence is strictly increasing; i.e, each item is greater
/// than the previous one
///
/// \param first The start of the sequence to be tested.
/// \param last One past the end of the sequence
///
/// \note This function will return false for sequences that contain items that compare
/// equal. If that is not what you intended, you should use is_increasing instead.
template <typename ForwardIterator>
bool is_strictly_increasing ( ForwardIterator first, ForwardIterator last )
{
typedef typename std::iterator_traits<ForwardIterator>::value_type value_type;
return boost::algorithm::is_sorted (first, last, std::less_equal<value_type>());
}
/// \fn is_strictly_increasing ( const R &range )
/// \return true if the entire sequence is strictly increasing; i.e, each item is greater
/// than the previous one
///
/// \param range The range to be tested.
///
/// \note This function will return false for sequences that contain items that compare
/// equal. If that is not what you intended, you should use is_increasing instead.
template <typename R>
bool is_strictly_increasing ( const R &range )
{
return is_strictly_increasing ( boost::begin ( range ), boost::end ( range ));
}
/// \fn is_strictly_decreasing ( ForwardIterator first, ForwardIterator last )
/// \return true if the entire sequence is strictly decreasing; i.e, each item is less than
/// the previous one
///
/// \param first The start of the sequence to be tested.
/// \param last One past the end of the sequence
///
/// \note This function will return false for sequences that contain items that compare
/// equal. If that is not what you intended, you should use is_decreasing instead.
template <typename ForwardIterator>
bool is_strictly_decreasing ( ForwardIterator first, ForwardIterator last )
{
typedef typename std::iterator_traits<ForwardIterator>::value_type value_type;
return boost::algorithm::is_sorted (first, last, std::greater_equal<value_type>());
}
/// \fn is_strictly_decreasing ( const R &range )
/// \return true if the entire sequence is strictly decreasing; i.e, each item is less than
/// the previous one
///
/// \param range The range to be tested.
///
/// \note This function will return false for sequences that contain items that compare
/// equal. If that is not what you intended, you should use is_decreasing instead.
template <typename R>
bool is_strictly_decreasing ( const R &range )
{
return is_strictly_decreasing ( boost::begin ( range ), boost::end ( range ));
}
}} // namespace boost
#endif // BOOST_ALGORITHM_ORDERED_HPP

View File

@ -0,0 +1,82 @@
/*
Copyright (c) Marshall Clow 2008-2012.
Distributed under the Boost Software License, Version 1.0. (See accompanying
file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
*/
/// \file none_of.hpp
/// \brief Test ranges to see if no elements match a value or predicate.
/// \author Marshall Clow
#ifndef BOOST_ALGORITHM_NONE_OF_HPP
#define BOOST_ALGORITHM_NONE_OF_HPP
#include <boost/range/begin.hpp>
#include <boost/range/end.hpp>
namespace boost { namespace algorithm {
/// \fn none_of ( InputIterator first, InputIterator last, Predicate p )
/// \return true if none of the elements in [first, last) satisfy the predicate 'p'
/// \note returns true on an empty range
///
/// \param first The start of the input sequence
/// \param last One past the end of the input sequence
/// \param p A predicate for testing the elements of the sequence
///
template<typename InputIterator, typename Predicate>
bool none_of ( InputIterator first, InputIterator last, Predicate p )
{
for ( ; first != last; ++first )
if ( p(*first))
return false;
return true;
}
/// \fn none_of ( const Range &r, Predicate p )
/// \return true if none of the elements in the range satisfy the predicate 'p'
/// \note returns true on an empty range
///
/// \param r The input range
/// \param p A predicate for testing the elements of the range
///
template<typename Range, typename Predicate>
bool none_of ( const Range &r, Predicate p )
{
return boost::algorithm::none_of (boost::begin (r), boost::end (r), p );
}
/// \fn none_of_equal ( InputIterator first, InputIterator last, const V &val )
/// \return true if none of the elements in [first, last) are equal to 'val'
/// \note returns true on an empty range
///
/// \param first The start of the input sequence
/// \param last One past the end of the input sequence
/// \param val A value to compare against
///
template<typename InputIterator, typename V>
bool none_of_equal ( InputIterator first, InputIterator last, const V &val )
{
for ( ; first != last; ++first )
if ( val == *first )
return false;
return true;
}
/// \fn none_of_equal ( const Range &r, const V &val )
/// \return true if none of the elements in the range are equal to 'val'
/// \note returns true on an empty range
///
/// \param r The input range
/// \param val A value to compare against
///
template<typename Range, typename V>
bool none_of_equal ( const Range &r, const V & val )
{
return boost::algorithm::none_of_equal (boost::begin (r), boost::end (r), val);
}
}} // namespace boost and algorithm
#endif // BOOST_ALGORITHM_NONE_OF_HPP

View File

@ -0,0 +1,82 @@
/*
Copyright (c) Marshall Clow 2008-2012.
Distributed under the Boost Software License, Version 1.0. (See accompanying
file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
*/
/// \file one_of.hpp
/// \brief Test ranges to see if only one element matches a value or predicate.
/// \author Marshall Clow
#ifndef BOOST_ALGORITHM_ONE_OF_HPP
#define BOOST_ALGORITHM_ONE_OF_HPP
#include <algorithm> // for std::find and std::find_if
#include <boost/algorithm/cxx11/none_of.hpp>
#include <boost/range/begin.hpp>
#include <boost/range/end.hpp>
namespace boost { namespace algorithm {
/// \fn one_of ( InputIterator first, InputIterator last, Predicate p )
/// \return true if the predicate 'p' is true for exactly one item in [first, last).
///
/// \param first The start of the input sequence
/// \param last One past the end of the input sequence
/// \param p A predicate for testing the elements of the sequence
///
template<typename InputIterator, typename Predicate>
bool one_of ( InputIterator first, InputIterator last, Predicate p )
{
InputIterator i = std::find_if (first, last, p);
if (i == last)
return false; // Didn't occur at all
return boost::algorithm::none_of (++i, last, p);
}
/// \fn one_of ( const Range &r, Predicate p )
/// \return true if the predicate 'p' is true for exactly one item in the range.
///
/// \param r The input range
/// \param p A predicate for testing the elements of the range
///
template<typename Range, typename Predicate>
bool one_of ( const Range &r, Predicate p )
{
return boost::algorithm::one_of ( boost::begin (r), boost::end (r), p );
}
/// \fn one_of_equal ( InputIterator first, InputIterator last, const V &val )
/// \return true if the value 'val' exists only once in [first, last).
///
/// \param first The start of the input sequence
/// \param last One past the end of the input sequence
/// \param val A value to compare against
///
template<typename InputIterator, typename V>
bool one_of_equal ( InputIterator first, InputIterator last, const V &val )
{
InputIterator i = std::find (first, last, val); // find first occurrence of 'val'
if (i == last)
return false; // Didn't occur at all
return boost::algorithm::none_of_equal (++i, last, val);
}
/// \fn one_of_equal ( const Range &r, const V &val )
/// \return true if the value 'val' exists only once in the range.
///
/// \param r The input range
/// \param val A value to compare against
///
template<typename Range, typename V>
bool one_of_equal ( const Range &r, const V &val )
{
return boost::algorithm::one_of_equal ( boost::begin (r), boost::end (r), val );
}
}} // namespace boost and algorithm
#endif // BOOST_ALGORITHM_ALL_HPP

View File

@ -0,0 +1,70 @@
/*
Copyright (c) Marshall Clow 2011-2012.
Distributed under the Boost Software License, Version 1.0. (See accompanying
file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
*/
/// \file partition_copy.hpp
/// \brief Copy a subset of a sequence to a new sequence
/// \author Marshall Clow
#ifndef BOOST_ALGORITHM_PARTITION_COPY_HPP
#define BOOST_ALGORITHM_PARTITION_COPY_HPP
#include <utility> // for std::pair
#include <boost/range/begin.hpp>
#include <boost/range/end.hpp>
namespace boost { namespace algorithm {
/// \fn partition_copy ( InputIterator first, InputIterator last,
/// OutputIterator1 out_true, OutputIterator2 out_false, UnaryPredicate p )
/// \brief Copies the elements that satisfy the predicate p from the range [first, last)
/// to the range beginning at d_first_true, and
/// copies the elements that do not satisfy p to the range beginning at d_first_false.
///
///
/// \param first The start of the input sequence
/// \param last One past the end of the input sequence
/// \param out_true An output iterator to write the elements that satisfy the predicate into
/// \param out_false An output iterator to write the elements that do not satisfy the predicate into
/// \param p A predicate for dividing the elements of the input sequence.
///
/// \note This function is part of the C++2011 standard library.
template <typename InputIterator,
typename OutputIterator1, typename OutputIterator2, typename UnaryPredicate>
std::pair<OutputIterator1, OutputIterator2>
partition_copy ( InputIterator first, InputIterator last,
OutputIterator1 out_true, OutputIterator2 out_false, UnaryPredicate p )
{
for ( ; first != last; ++first )
if ( p (*first))
*out_true++ = *first;
else
*out_false++ = *first;
return std::pair<OutputIterator1, OutputIterator2> ( out_true, out_false );
}
/// \fn partition_copy ( const Range &r,
/// OutputIterator1 out_true, OutputIterator2 out_false, UnaryPredicate p )
///
/// \param r The input range
/// \param out_true An output iterator to write the elements that satisfy the predicate into
/// \param out_false An output iterator to write the elements that do not satisfy the predicate into
/// \param p A predicate for dividing the elements of the input sequence.
///
template <typename Range, typename OutputIterator1, typename OutputIterator2,
typename UnaryPredicate>
std::pair<OutputIterator1, OutputIterator2>
partition_copy ( const Range &r, OutputIterator1 out_true, OutputIterator2 out_false,
UnaryPredicate p )
{
return boost::algorithm::partition_copy
(boost::begin(r), boost::end(r), out_true, out_false, p );
}
}} // namespace boost and algorithm
#endif // BOOST_ALGORITHM_PARTITION_COPY_HPP

View File

@ -0,0 +1,65 @@
/*
Copyright (c) Marshall Clow 2011-2012.
Distributed under the Boost Software License, Version 1.0. (See accompanying
file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
*/
/// \file partition_point.hpp
/// \brief Find the partition point in a sequence
/// \author Marshall Clow
#ifndef BOOST_ALGORITHM_PARTITION_POINT_HPP
#define BOOST_ALGORITHM_PARTITION_POINT_HPP
#include <iterator> // for std::distance, advance
#include <boost/range/begin.hpp>
#include <boost/range/end.hpp>
namespace boost { namespace algorithm {
/// \fn partition_point ( ForwardIterator first, ForwardIterator last, Predicate p )
/// \brief Given a partitioned range, returns the partition point, i.e, the first element
/// that does not satisfy p
///
/// \param first The start of the input sequence
/// \param last One past the end of the input sequence
/// \param p The predicate to test the values with
/// \note This function is part of the C++2011 standard library.
template <typename ForwardIterator, typename Predicate>
ForwardIterator partition_point ( ForwardIterator first, ForwardIterator last, Predicate p )
{
std::size_t dist = std::distance ( first, last );
while ( first != last ) {
std::size_t d2 = dist / 2;
ForwardIterator ret_val = first;
std::advance (ret_val, d2);
if (p (*ret_val)) {
first = ++ret_val;
dist -= d2 + 1;
}
else {
last = ret_val;
dist = d2;
}
}
return first;
}
/// \fn partition_point ( Range &r, Predicate p )
/// \brief Given a partitioned range, returns the partition point
///
/// \param r The input range
/// \param p The predicate to test the values with
///
template <typename Range, typename Predicate>
typename boost::range_iterator<Range>::type partition_point ( Range &r, Predicate p )
{
return boost::algorithm::partition_point (boost::begin(r), boost::end(r), p);
}
}}
#endif // BOOST_ALGORITHM_PARTITION_POINT_HPP

View File

@ -0,0 +1,98 @@
/*
Copyright (c) Marshall Clow 2008-2012.
Distributed under the Boost Software License, Version 1.0. (See accompanying
file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
*/
/// \file equal.hpp
/// \brief Test ranges to if they are equal
/// \author Marshall Clow
#ifndef BOOST_ALGORITHM_EQUAL_HPP
#define BOOST_ALGORITHM_EQUAL_HPP
#include <algorithm> // for std::equal
#include <functional> // for std::binary_function
#include <iterator>
namespace boost { namespace algorithm {
namespace detail {
template <class T1, class T2>
struct eq : public std::binary_function<T1, T2, bool> {
bool operator () ( const T1& v1, const T2& v2 ) const { return v1 == v2 ;}
};
template <class RandomAccessIterator1, class RandomAccessIterator2, class BinaryPredicate>
bool equal ( RandomAccessIterator1 first1, RandomAccessIterator1 last1,
RandomAccessIterator2 first2, RandomAccessIterator2 last2, BinaryPredicate pred,
std::random_access_iterator_tag, std::random_access_iterator_tag )
{
// Random-access iterators let is check the sizes in constant time
if ( std::distance ( first1, last1 ) != std::distance ( first2, last2 ))
return false;
// If we know that the sequences are the same size, the original version is fine
return std::equal ( first1, last1, first2, pred );
}
template <class InputIterator1, class InputIterator2, class BinaryPredicate>
bool equal ( InputIterator1 first1, InputIterator1 last1,
InputIterator2 first2, InputIterator2 last2, BinaryPredicate pred,
std::input_iterator_tag, std::input_iterator_tag )
{
for (; first1 != last1 && first2 != last2; ++first1, ++first2 )
if ( !pred(*first1, *first2 ))
return false;
return first1 == last1 && first2 == last2;
}
}
/// \fn equal ( InputIterator1 first1, InputIterator1 last1,
/// InputIterator2 first2, InputIterator2 last2,
/// BinaryPredicate pred )
/// \return true if all elements in the two ranges are equal
///
/// \param first1 The start of the first range.
/// \param last1 One past the end of the first range.
/// \param first2 The start of the second range.
/// \param last2 One past the end of the second range.
/// \param pred A predicate for comparing the elements of the ranges
template <class InputIterator1, class InputIterator2, class BinaryPredicate>
bool equal ( InputIterator1 first1, InputIterator1 last1,
InputIterator2 first2, InputIterator2 last2, BinaryPredicate pred )
{
return boost::algorithm::detail::equal (
first1, last1, first2, last2, pred,
typename std::iterator_traits<InputIterator1>::iterator_category (),
typename std::iterator_traits<InputIterator2>::iterator_category ());
}
/// \fn equal ( InputIterator1 first1, InputIterator1 last1,
/// InputIterator2 first2, InputIterator2 last2 )
/// \return true if all elements in the two ranges are equal
///
/// \param first1 The start of the first range.
/// \param last1 One past the end of the first range.
/// \param first2 The start of the second range.
/// \param last2 One past the end of the second range.
template <class InputIterator1, class InputIterator2>
bool equal ( InputIterator1 first1, InputIterator1 last1,
InputIterator2 first2, InputIterator2 last2 )
{
return boost::algorithm::detail::equal (
first1, last1, first2, last2,
boost::algorithm::detail::eq<
typename std::iterator_traits<InputIterator1>::value_type,
typename std::iterator_traits<InputIterator2>::value_type> (),
typename std::iterator_traits<InputIterator1>::iterator_category (),
typename std::iterator_traits<InputIterator2>::iterator_category ());
}
// There are already range-based versions of these.
}} // namespace boost and algorithm
#endif // BOOST_ALGORITHM_EQUAL_HPP

View File

@ -0,0 +1,79 @@
/*
Copyright (c) Marshall Clow 2014.
Distributed under the Boost Software License, Version 1.0. (See accompanying
file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
*/
/// \file is_permutation.hpp
/// \brief Is a sequence a permutation of another sequence (four iterator versions)
/// \author Marshall Clow
#ifndef BOOST_ALGORITHM_IS_PERMUTATION14_HPP
#define BOOST_ALGORITHM_IS_PERMUTATION14_HPP
#include <utility> // for std::pair
#include <functional> // for std::equal_to
#include <iterator>
#include <boost/algorithm/cxx11/is_permutation.hpp>
#include <boost/algorithm/cxx14/mismatch.hpp>
namespace boost { namespace algorithm {
/// \fn is_permutation ( ForwardIterator1 first, ForwardIterator1 last,
/// ForwardIterator2 first2, ForwardIterator2 last2 )
/// \brief Tests to see if the sequence [first,last) is a permutation of the sequence starting at first2
///
/// \param first1 The start of the input sequence
/// \param last2 One past the end of the input sequence
/// \param first2 The start of the second sequence
/// \param last1 One past the end of the second sequence
/// \note This function is part of the C++2014 standard library.
template< class ForwardIterator1, class ForwardIterator2 >
bool is_permutation ( ForwardIterator1 first1, ForwardIterator1 last1,
ForwardIterator2 first2, ForwardIterator2 last2 )
{
// How should I deal with the idea that ForwardIterator1::value_type
// and ForwardIterator2::value_type could be different? Define my own comparison predicate?
std::pair<ForwardIterator1, ForwardIterator2> eq = boost::algorithm::mismatch
( first1, last1, first2, last2 );
if ( eq.first == last1 && eq.second == last2)
return true;
return boost::algorithm::detail::is_permutation_tag (
eq.first, last1, eq.second, last2,
std::equal_to<typename std::iterator_traits<ForwardIterator1>::value_type> (),
typename std::iterator_traits<ForwardIterator1>::iterator_category (),
typename std::iterator_traits<ForwardIterator2>::iterator_category ());
}
/// \fn is_permutation ( ForwardIterator1 first, ForwardIterator1 last,
/// ForwardIterator2 first2, ForwardIterator2 last2,
/// BinaryPredicate p )
/// \brief Tests to see if the sequence [first,last) is a permutation of the sequence starting at first2
///
/// \param first1 The start of the input sequence
/// \param last1 One past the end of the input sequence
/// \param first2 The start of the second sequence
/// \param last2 One past the end of the second sequence
/// \param pred The predicate to compare elements with
///
/// \note This function is part of the C++2014 standard library.
template< class ForwardIterator1, class ForwardIterator2, class BinaryPredicate >
bool is_permutation ( ForwardIterator1 first1, ForwardIterator1 last1,
ForwardIterator2 first2, ForwardIterator2 last2,
BinaryPredicate pred )
{
std::pair<ForwardIterator1, ForwardIterator2> eq = boost::algorithm::mismatch
( first1, last1, first2, last2, pred );
if ( eq.first == last1 && eq.second == last2)
return true;
return boost::algorithm::detail::is_permutation_tag (
first1, last1, first2, last2, pred,
typename std::iterator_traits<ForwardIterator1>::iterator_category (),
typename std::iterator_traits<ForwardIterator2>::iterator_category ());
}
}}
#endif // BOOST_ALGORITHM_IS_PERMUTATION14_HPP

View File

@ -0,0 +1,64 @@
/*
Copyright (c) Marshall Clow 2008-2012.
Distributed under the Boost Software License, Version 1.0. (See accompanying
file LICENSE10.txt or copy at http://www.boost.org/LICENSE10.txt)
*/
/// \file mismatch.hpp
/// \brief Find the first mismatched element in a sequence
/// \author Marshall Clow
#ifndef BOOST_ALGORITHM_MISMATCH_HPP
#define BOOST_ALGORITHM_MISMATCH_HPP
#include <utility> // for std::pair
namespace boost { namespace algorithm {
/// \fn mismatch ( InputIterator1 first1, InputIterator1 last1,
/// InputIterator2 first2, InputIterator2 last2,
/// BinaryPredicate pred )
/// \return a pair of iterators pointing to the first elements in the sequence that do not match
///
/// \param first1 The start of the first range.
/// \param last1 One past the end of the first range.
/// \param first2 The start of the second range.
/// \param last2 One past the end of the second range.
/// \param pred A predicate for comparing the elements of the ranges
template <class InputIterator1, class InputIterator2, class BinaryPredicate>
std::pair<InputIterator1, InputIterator2> mismatch (
InputIterator1 first1, InputIterator1 last1,
InputIterator2 first2, InputIterator2 last2,
BinaryPredicate pred )
{
for (; first1 != last1 && first2 != last2; ++first1, ++first2)
if ( !pred ( *first1, *first2 ))
break;
return std::pair<InputIterator1, InputIterator2>(first1, first2);
}
/// \fn mismatch ( InputIterator1 first1, InputIterator1 last1,
/// InputIterator2 first2, InputIterator2 last2 )
/// \return a pair of iterators pointing to the first elements in the sequence that do not match
///
/// \param first1 The start of the first range.
/// \param last1 One past the end of the first range.
/// \param first2 The start of the second range.
/// \param last2 One past the end of the second range.
template <class InputIterator1, class InputIterator2>
std::pair<InputIterator1, InputIterator2> mismatch (
InputIterator1 first1, InputIterator1 last1,
InputIterator2 first2, InputIterator2 last2 )
{
for (; first1 != last1 && first2 != last2; ++first1, ++first2)
if ( *first1 != *first2 )
break;
return std::pair<InputIterator1, InputIterator2>(first1, first2);
}
// There are already range-based versions of these.
}} // namespace boost and algorithm
#endif // BOOST_ALGORITHM_MISMATCH_HPP

View File

@ -0,0 +1,123 @@
/*
Copyright 2008 Adobe Systems Incorporated
Distributed under the Boost Software License, Version 1.0. (See accompanying
file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
Revision history:
January 2008 mtc Version for Adobe Source Library
January 2013 mtc Version for Boost.Algorithm
*/
/**************************************************************************************************/
/*!
\author Marshall Clow
\date January 2008
*/
#ifndef BOOST_ALGORITHM_GATHER_HPP
#define BOOST_ALGORITHM_GATHER_HPP
#include <algorithm> // for std::stable_partition
#include <functional>
#include <boost/bind.hpp> // for boost::bind
#include <boost/range/begin.hpp> // for boost::begin(range)
#include <boost/range/end.hpp> // for boost::end(range)
/**************************************************************************************************/
/*!
\defgroup gather gather
\ingroup mutating_algorithm
\c gather() takes a collection of elements defined by a pair of iterators and moves
the ones satisfying a predicate to them to a position (called the pivot) within
the sequence. The algorithm is stable. The result is a pair of iterators that
contains the items that satisfy the predicate.
Given an sequence containing:
<pre>
0 1 2 3 4 5 6 7 8 9
</pre>
a call to gather ( arr, arr + 10, arr + 4, IsEven ()) will result in:
<pre>
1 3 0 2 4 6 8 5 7 9
|---|-----|
first | second
pivot
</pre>
The problem is broken down into two basic steps, namely, moving the items before the pivot
and then moving the items from the pivot to the end. These "moves" are done with calls to
stable_partition.
\par Storage Requirements:
The algorithm uses stable_partition, which will attempt to allocate temporary memory,
but will work in-situ if there is none available.
\par Time Complexity:
If there is sufficient memory available, the run time is linear in <code>N</code>.
If there is not any memory available, then the run time is <code>O(N log N)</code>.
*/
/**************************************************************************************************/
namespace boost { namespace algorithm {
/**************************************************************************************************/
/*!
\ingroup gather
\brief iterator-based gather implementation
*/
template <
typename BidirectionalIterator, // Iter models BidirectionalIterator
typename Pred> // Pred models UnaryPredicate
std::pair<BidirectionalIterator, BidirectionalIterator> gather
( BidirectionalIterator first, BidirectionalIterator last, BidirectionalIterator pivot, Pred pred )
{
// The first call partitions everything up to (but not including) the pivot element,
// while the second call partitions the rest of the sequence.
return std::make_pair (
std::stable_partition ( first, pivot, !boost::bind<bool> ( pred, _1 )),
std::stable_partition ( pivot, last, boost::bind<bool> ( pred, _1 )));
}
/**************************************************************************************************/
/*!
\ingroup gather
\brief range-based gather implementation
*/
template <
typename BidirectionalRange, //
typename Pred> // Pred models UnaryPredicate
std::pair<
typename boost::range_iterator<const BidirectionalRange>::type,
typename boost::range_iterator<const BidirectionalRange>::type>
gather (
const BidirectionalRange &range,
typename boost::range_iterator<const BidirectionalRange>::type pivot,
Pred pred )
{
return boost::algorithm::gather ( boost::begin ( range ), boost::end ( range ), pivot, pred );
}
/**************************************************************************************************/
}} // namespace
/**************************************************************************************************/
#endif

View File

@ -0,0 +1,325 @@
/*
Copyright (c) Marshall Clow 2011-2012.
Distributed under the Boost Software License, Version 1.0. (See accompanying
file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
Thanks to Nevin for his comments/help.
*/
/*
General problem - turn a sequence of integral types into a sequence of hexadecimal characters.
- and back.
*/
/// \file hex.hpp
/// \brief Convert sequence of integral types into a sequence of hexadecimal
/// characters and back. Based on the MySQL functions HEX and UNHEX
/// \author Marshall Clow
#ifndef BOOST_ALGORITHM_HEXHPP
#define BOOST_ALGORITHM_HEXHPP
#include <iterator> // for std::iterator_traits
#include <stdexcept>
#include <boost/range/begin.hpp>
#include <boost/range/end.hpp>
#include <boost/exception/exception.hpp>
#include <boost/exception/info.hpp>
#include <boost/throw_exception.hpp>
#include <boost/utility/enable_if.hpp>
#include <boost/type_traits/is_integral.hpp>
namespace boost { namespace algorithm {
/*!
\struct hex_decode_error
\brief Base exception class for all hex decoding errors
*/ /*!
\struct non_hex_input
\brief Thrown when a non-hex value (0-9, A-F) encountered when decoding.
Contains the offending character
*/ /*!
\struct not_enough_input
\brief Thrown when the input sequence unexpectedly ends
*/
struct hex_decode_error : virtual boost::exception, virtual std::exception {};
struct not_enough_input : virtual hex_decode_error {};
struct non_hex_input : virtual hex_decode_error {};
typedef boost::error_info<struct bad_char_,char> bad_char;
namespace detail {
/// \cond DOXYGEN_HIDE
template <typename T, typename OutputIterator>
OutputIterator encode_one ( T val, OutputIterator out, const char * hexDigits ) {
const std::size_t num_hex_digits = 2 * sizeof ( T );
char res [ num_hex_digits ];
char *p = res + num_hex_digits;
for ( std::size_t i = 0; i < num_hex_digits; ++i, val >>= 4 )
*--p = hexDigits [ val & 0x0F ];
return std::copy ( res, res + num_hex_digits, out );
}
template <typename T>
unsigned char hex_char_to_int ( T val ) {
char c = static_cast<char> ( val );
unsigned retval = 0;
if ( c >= '0' && c <= '9' ) retval = c - '0';
else if ( c >= 'A' && c <= 'F' ) retval = c - 'A' + 10;
else if ( c >= 'a' && c <= 'f' ) retval = c - 'a' + 10;
else BOOST_THROW_EXCEPTION (non_hex_input() << bad_char (c));
return retval;
}
// My own iterator_traits class.
// It is here so that I can "reach inside" some kinds of output iterators
// and get the type to write.
template <typename Iterator>
struct hex_iterator_traits {
typedef typename std::iterator_traits<Iterator>::value_type value_type;
};
template<typename Container>
struct hex_iterator_traits< std::back_insert_iterator<Container> > {
typedef typename Container::value_type value_type;
};
template<typename Container>
struct hex_iterator_traits< std::front_insert_iterator<Container> > {
typedef typename Container::value_type value_type;
};
template<typename Container>
struct hex_iterator_traits< std::insert_iterator<Container> > {
typedef typename Container::value_type value_type;
};
// ostream_iterators have three template parameters.
// The first one is the output type, the second one is the character type of
// the underlying stream, the third is the character traits.
// We only care about the first one.
template<typename T, typename charType, typename traits>
struct hex_iterator_traits< std::ostream_iterator<T, charType, traits> > {
typedef T value_type;
};
template <typename Iterator>
bool iter_end ( Iterator current, Iterator last ) { return current == last; }
template <typename T>
bool ptr_end ( const T* ptr, const T* /*end*/ ) { return *ptr == '\0'; }
// What can we assume here about the inputs?
// is std::iterator_traits<InputIterator>::value_type always 'char' ?
// Could it be wchar_t, say? Does it matter?
// We are assuming ASCII for the values - but what about the storage?
template <typename InputIterator, typename OutputIterator, typename EndPred>
typename boost::enable_if<boost::is_integral<typename hex_iterator_traits<OutputIterator>::value_type>, OutputIterator>::type
decode_one ( InputIterator &first, InputIterator last, OutputIterator out, EndPred pred ) {
typedef typename hex_iterator_traits<OutputIterator>::value_type T;
T res (0);
// Need to make sure that we get can read that many chars here.
for ( std::size_t i = 0; i < 2 * sizeof ( T ); ++i, ++first ) {
if ( pred ( first, last ))
BOOST_THROW_EXCEPTION (not_enough_input ());
res = ( 16 * res ) + hex_char_to_int (*first);
}
*out = res;
return ++out;
}
/// \endcond
}
/// \fn hex ( InputIterator first, InputIterator last, OutputIterator out )
/// \brief Converts a sequence of integral types into a hexadecimal sequence of characters.
///
/// \param first The start of the input sequence
/// \param last One past the end of the input sequence
/// \param out An output iterator to the results into
/// \return The updated output iterator
/// \note Based on the MySQL function of the same name
template <typename InputIterator, typename OutputIterator>
typename boost::enable_if<boost::is_integral<typename detail::hex_iterator_traits<InputIterator>::value_type>, OutputIterator>::type
hex ( InputIterator first, InputIterator last, OutputIterator out ) {
for ( ; first != last; ++first )
out = detail::encode_one ( *first, out, "0123456789ABCDEF" );
return out;
}
/// \fn hex_lower ( InputIterator first, InputIterator last, OutputIterator out )
/// \brief Converts a sequence of integral types into a lower case hexadecimal sequence of characters.
///
/// \param first The start of the input sequence
/// \param last One past the end of the input sequence
/// \param out An output iterator to the results into
/// \return The updated output iterator
/// \note Based on the MySQL function of the same name
template <typename InputIterator, typename OutputIterator>
typename boost::enable_if<boost::is_integral<typename detail::hex_iterator_traits<InputIterator>::value_type>, OutputIterator>::type
hex_lower ( InputIterator first, InputIterator last, OutputIterator out ) {
for ( ; first != last; ++first )
out = detail::encode_one ( *first, out, "0123456789abcdef" );
return out;
}
/// \fn hex ( const T *ptr, OutputIterator out )
/// \brief Converts a sequence of integral types into a hexadecimal sequence of characters.
///
/// \param ptr A pointer to a 0-terminated sequence of data.
/// \param out An output iterator to the results into
/// \return The updated output iterator
/// \note Based on the MySQL function of the same name
template <typename T, typename OutputIterator>
typename boost::enable_if<boost::is_integral<T>, OutputIterator>::type
hex ( const T *ptr, OutputIterator out ) {
while ( *ptr )
out = detail::encode_one ( *ptr++, out, "0123456789ABCDEF" );
return out;
}
/// \fn hex_lower ( const T *ptr, OutputIterator out )
/// \brief Converts a sequence of integral types into a lower case hexadecimal sequence of characters.
///
/// \param ptr A pointer to a 0-terminated sequence of data.
/// \param out An output iterator to the results into
/// \return The updated output iterator
/// \note Based on the MySQL function of the same name
template <typename T, typename OutputIterator>
typename boost::enable_if<boost::is_integral<T>, OutputIterator>::type
hex_lower ( const T *ptr, OutputIterator out ) {
while ( *ptr )
out = detail::encode_one ( *ptr++, out, "0123456789abcdef" );
return out;
}
/// \fn hex ( const Range &r, OutputIterator out )
/// \brief Converts a sequence of integral types into a hexadecimal sequence of characters.
///
/// \param r The input range
/// \param out An output iterator to the results into
/// \return The updated output iterator
/// \note Based on the MySQL function of the same name
template <typename Range, typename OutputIterator>
typename boost::enable_if<boost::is_integral<typename detail::hex_iterator_traits<typename Range::iterator>::value_type>, OutputIterator>::type
hex ( const Range &r, OutputIterator out ) {
return hex (boost::begin(r), boost::end(r), out);
}
/// \fn hex_lower ( const Range &r, OutputIterator out )
/// \brief Converts a sequence of integral types into a lower case hexadecimal sequence of characters.
///
/// \param r The input range
/// \param out An output iterator to the results into
/// \return The updated output iterator
/// \note Based on the MySQL function of the same name
template <typename Range, typename OutputIterator>
typename boost::enable_if<boost::is_integral<typename detail::hex_iterator_traits<typename Range::iterator>::value_type>, OutputIterator>::type
hex_lower ( const Range &r, OutputIterator out ) {
return hex_lower (boost::begin(r), boost::end(r), out);
}
/// \fn unhex ( InputIterator first, InputIterator last, OutputIterator out )
/// \brief Converts a sequence of hexadecimal characters into a sequence of integers.
///
/// \param first The start of the input sequence
/// \param last One past the end of the input sequence
/// \param out An output iterator to the results into
/// \return The updated output iterator
/// \note Based on the MySQL function of the same name
template <typename InputIterator, typename OutputIterator>
OutputIterator unhex ( InputIterator first, InputIterator last, OutputIterator out ) {
while ( first != last )
out = detail::decode_one ( first, last, out, detail::iter_end<InputIterator> );
return out;
}
/// \fn unhex ( const T *ptr, OutputIterator out )
/// \brief Converts a sequence of hexadecimal characters into a sequence of integers.
///
/// \param ptr A pointer to a null-terminated input sequence.
/// \param out An output iterator to the results into
/// \return The updated output iterator
/// \note Based on the MySQL function of the same name
template <typename T, typename OutputIterator>
OutputIterator unhex ( const T *ptr, OutputIterator out ) {
// If we run into the terminator while decoding, we will throw a
// malformed input exception. It would be nicer to throw a 'Not enough input'
// exception - but how much extra work would that require?
while ( *ptr )
out = detail::decode_one ( ptr, (const T *) NULL, out, detail::ptr_end<T> );
return out;
}
/// \fn OutputIterator unhex ( const Range &r, OutputIterator out )
/// \brief Converts a sequence of hexadecimal characters into a sequence of integers.
///
/// \param r The input range
/// \param out An output iterator to the results into
/// \return The updated output iterator
/// \note Based on the MySQL function of the same name
template <typename Range, typename OutputIterator>
OutputIterator unhex ( const Range &r, OutputIterator out ) {
return unhex (boost::begin(r), boost::end(r), out);
}
/// \fn String hex ( const String &input )
/// \brief Converts a sequence of integral types into a hexadecimal sequence of characters.
///
/// \param input A container to be converted
/// \return A container with the encoded text
template<typename String>
String hex ( const String &input ) {
String output;
output.reserve (input.size () * (2 * sizeof (typename String::value_type)));
(void) hex (input, std::back_inserter (output));
return output;
}
/// \fn String hex_lower ( const String &input )
/// \brief Converts a sequence of integral types into a lower case hexadecimal sequence of characters.
///
/// \param input A container to be converted
/// \return A container with the encoded text
template<typename String>
String hex_lower ( const String &input ) {
String output;
output.reserve (input.size () * (2 * sizeof (typename String::value_type)));
(void) hex_lower (input, std::back_inserter (output));
return output;
}
/// \fn String unhex ( const String &input )
/// \brief Converts a sequence of hexadecimal characters into a sequence of characters.
///
/// \param input A container to be converted
/// \return A container with the decoded text
template<typename String>
String unhex ( const String &input ) {
String output;
output.reserve (input.size () / (2 * sizeof (typename String::value_type)));
(void) unhex (input, std::back_inserter (output));
return output;
}
}}
#endif // BOOST_ALGORITHM_HEXHPP

View File

@ -0,0 +1,161 @@
/*
Copyright (c) Alexander Zaitsev <zamazan4ik@gmail.com>, 2016
Distributed under the Boost Software License, Version 1.0. (See
accompanying file LICENSE_1_0.txt or copy at
http://www.boost.org/LICENSE_1_0.txt)
See http://www.boost.org/ for latest version.
*/
/// \file is_palindrome.hpp
/// \brief Checks the input sequence on palindrome.
/// \author Alexander Zaitsev
#ifndef BOOST_ALGORITHM_IS_PALINDROME_HPP
#define BOOST_ALGORITHM_IS_PALINDROME_HPP
#include <iterator>
#include <functional>
#include <cstring>
#include <boost/range/begin.hpp>
#include <boost/range/end.hpp>
namespace boost { namespace algorithm {
/// \fn is_palindrome ( BidirectionalIterator begin, BidirectionalIterator end, Predicate p )
/// \return true if the entire sequence is palindrome
///
/// \param begin The start of the input sequence
/// \param end One past the end of the input sequence
/// \param p A predicate used to compare the values.
///
/// \note This function will return true for empty sequences and for palindromes.
/// For other sequences function will return false.
/// Complexity: O(N).
template <typename BidirectionalIterator, typename Predicate>
bool is_palindrome(BidirectionalIterator begin, BidirectionalIterator end, Predicate p )
{
if(begin == end)
{
return true;
}
--end;
while(begin != end)
{
if(!p(*begin, *end))
{
return false;
}
++begin;
if(begin == end)
{
break;
}
--end;
}
return true;
}
/// \fn is_palindrome ( BidirectionalIterator begin, BidirectionalIterator end )
/// \return true if the entire sequence is palindrome
///
/// \param begin The start of the input sequence
/// \param end One past the end of the input sequence
///
/// \note This function will return true for empty sequences and for palindromes.
/// For other sequences function will return false.
/// Complexity: O(N).
template <typename BidirectionalIterator>
bool is_palindrome(BidirectionalIterator begin, BidirectionalIterator end)
{
if(begin == end)
{
return true;
}
--end;
while(begin != end)
{
if(!(*begin == *end))
{
return false;
}
++begin;
if(begin == end)
{
break;
}
--end;
}
return true;
}
/// \fn is_palindrome ( const R& range )
/// \return true if the entire sequence is palindrome
///
/// \param range The range to be tested.
///
/// \note This function will return true for empty sequences and for palindromes.
/// For other sequences function will return false.
/// Complexity: O(N).
template <typename R>
bool is_palindrome(const R& range)
{
return is_palindrome(boost::begin(range), boost::end(range));
}
/// \fn is_palindrome ( const R& range, Predicate p )
/// \return true if the entire sequence is palindrome
///
/// \param range The range to be tested.
/// \param p A predicate used to compare the values.
///
/// \note This function will return true for empty sequences and for palindromes.
/// For other sequences function will return false.
/// Complexity: O(N).
template <typename R, typename Predicate>
bool is_palindrome(const R& range, Predicate p)
{
return is_palindrome(boost::begin(range), boost::end(range), p);
}
/// \fn is_palindrome ( const char* str )
/// \return true if the entire sequence is palindrome
///
/// \param str C-string to be tested.
///
/// \note This function will return true for empty sequences and for palindromes.
/// For other sequences function will return false.
/// Complexity: O(N).
bool is_palindrome(const char* str)
{
if(!str)
return true;
return is_palindrome(str, str + strlen(str));
}
/// \fn is_palindrome ( const char* str, Predicate p )
/// \return true if the entire sequence is palindrome
///
/// \param str C-string to be tested.
/// \param p A predicate used to compare the values.
///
/// \note This function will return true for empty sequences and for palindromes.
/// For other sequences function will return false.
/// Complexity: O(N).
template<typename Predicate>
bool is_palindrome(const char* str, Predicate p)
{
if(!str)
return true;
return is_palindrome(str, str + strlen(str), p);
}
}}
#endif // BOOST_ALGORITHM_IS_PALINDROME_HPP

View File

@ -0,0 +1,47 @@
// (C) Copyright Herve Bronnimann 2004.
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
/*
Revision history:
1 July 2004
Split the code into two headers to lessen dependence on
Boost.tuple. (Herve)
26 June 2004
Added the code for the boost minmax library. (Herve)
*/
#ifndef BOOST_ALGORITHM_MINMAX_HPP
#define BOOST_ALGORITHM_MINMAX_HPP
/* PROPOSED STANDARD EXTENSIONS:
*
* minmax(a, b)
* Effect: (b<a) ? std::make_pair(b,a) : std::make_pair(a,b);
*
* minmax(a, b, comp)
* Effect: comp(b,a) ? std::make_pair(b,a) : std::make_pair(a,b);
*
*/
#include <boost/tuple/tuple.hpp> // for using pairs with boost::cref
#include <boost/ref.hpp>
namespace boost {
template <typename T>
tuple< T const&, T const& >
minmax(T const& a, T const& b) {
return (b<a) ? make_tuple(cref(b),cref(a)) : make_tuple(cref(a),cref(b));
}
template <typename T, class BinaryPredicate>
tuple< T const&, T const& >
minmax(T const& a, T const& b, BinaryPredicate comp) {
return comp(b,a) ? make_tuple(cref(b),cref(a)) : make_tuple(cref(a),cref(b));
}
} // namespace boost
#endif // BOOST_ALGORITHM_MINMAX_HPP

View File

@ -0,0 +1,553 @@
// (C) Copyright Herve Bronnimann 2004.
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
/*
Revision history:
1 July 2004
Split the code into two headers to lessen dependence on
Boost.tuple. (Herve)
26 June 2004
Added the code for the boost minmax library. (Herve)
*/
#ifndef BOOST_ALGORITHM_MINMAX_ELEMENT_HPP
#define BOOST_ALGORITHM_MINMAX_ELEMENT_HPP
/* PROPOSED STANDARD EXTENSIONS:
*
* minmax_element(first, last)
* Effect: std::make_pair( std::min_element(first, last),
* std::max_element(first, last) );
*
* minmax_element(first, last, comp)
* Effect: std::make_pair( std::min_element(first, last, comp),
* std::max_element(first, last, comp) );
*/
#include <utility> // for std::pair and std::make_pair
namespace boost {
namespace detail { // for obtaining a uniform version of minmax_element
// that compiles with VC++ 6.0 -- avoid the iterator_traits by
// having comparison object over iterator, not over dereferenced value
template <typename Iterator>
struct less_over_iter {
bool operator()(Iterator const& it1,
Iterator const& it2) const { return *it1 < *it2; }
};
template <typename Iterator, class BinaryPredicate>
struct binary_pred_over_iter {
explicit binary_pred_over_iter(BinaryPredicate const& p ) : m_p( p ) {}
bool operator()(Iterator const& it1,
Iterator const& it2) const { return m_p(*it1, *it2); }
private:
BinaryPredicate m_p;
};
// common base for the two minmax_element overloads
template <typename ForwardIter, class Compare >
std::pair<ForwardIter,ForwardIter>
basic_minmax_element(ForwardIter first, ForwardIter last, Compare comp)
{
if (first == last)
return std::make_pair(last,last);
ForwardIter min_result = first;
ForwardIter max_result = first;
// if only one element
ForwardIter second = first; ++second;
if (second == last)
return std::make_pair(min_result, max_result);
// treat first pair separately (only one comparison for first two elements)
ForwardIter potential_min_result = last;
if (comp(first, second))
max_result = second;
else {
min_result = second;
potential_min_result = first;
}
// then each element by pairs, with at most 3 comparisons per pair
first = ++second; if (first != last) ++second;
while (second != last) {
if (comp(first, second)) {
if (comp(first, min_result)) {
min_result = first;
potential_min_result = last;
}
if (comp(max_result, second))
max_result = second;
} else {
if (comp(second, min_result)) {
min_result = second;
potential_min_result = first;
}
if (comp(max_result, first))
max_result = first;
}
first = ++second;
if (first != last) ++second;
}
// if odd number of elements, treat last element
if (first != last) { // odd number of elements
if (comp(first, min_result)) {
min_result = first;
potential_min_result = last;
}
else if (comp(max_result, first))
max_result = first;
}
// resolve min_result being incorrect with one extra comparison
// (in which case potential_min_result is necessarily the correct result)
if (potential_min_result != last
&& !comp(min_result, potential_min_result))
min_result = potential_min_result;
return std::make_pair(min_result,max_result);
}
} // namespace detail
template <typename ForwardIter>
std::pair<ForwardIter,ForwardIter>
minmax_element(ForwardIter first, ForwardIter last)
{
return detail::basic_minmax_element(first, last,
detail::less_over_iter<ForwardIter>() );
}
template <typename ForwardIter, class BinaryPredicate>
std::pair<ForwardIter,ForwardIter>
minmax_element(ForwardIter first, ForwardIter last, BinaryPredicate comp)
{
return detail::basic_minmax_element(first, last,
detail::binary_pred_over_iter<ForwardIter,BinaryPredicate>(comp) );
}
}
/* PROPOSED BOOST EXTENSIONS
* In the description below, [rfirst,rlast) denotes the reversed range
* of [first,last). Even though the iterator type of first and last may
* be only a Forward Iterator, it is possible to explain the semantics
* by assuming that it is a Bidirectional Iterator. In the sequel,
* reverse(ForwardIterator&) returns the reverse_iterator adaptor.
* This is not how the functions would be implemented!
*
* first_min_element(first, last)
* Effect: std::min_element(first, last);
*
* first_min_element(first, last, comp)
* Effect: std::min_element(first, last, comp);
*
* last_min_element(first, last)
* Effect: reverse( std::min_element(reverse(last), reverse(first)) );
*
* last_min_element(first, last, comp)
* Effect: reverse( std::min_element(reverse(last), reverse(first), comp) );
*
* first_max_element(first, last)
* Effect: std::max_element(first, last);
*
* first_max_element(first, last, comp)
* Effect: max_element(first, last);
*
* last_max_element(first, last)
* Effect: reverse( std::max_element(reverse(last), reverse(first)) );
*
* last_max_element(first, last, comp)
* Effect: reverse( std::max_element(reverse(last), reverse(first), comp) );
*
* first_min_first_max_element(first, last)
* Effect: std::make_pair( first_min_element(first, last),
* first_max_element(first, last) );
*
* first_min_first_max_element(first, last, comp)
* Effect: std::make_pair( first_min_element(first, last, comp),
* first_max_element(first, last, comp) );
*
* first_min_last_max_element(first, last)
* Effect: std::make_pair( first_min_element(first, last),
* last_max_element(first, last) );
*
* first_min_last_max_element(first, last, comp)
* Effect: std::make_pair( first_min_element(first, last, comp),
* last_max_element(first, last, comp) );
*
* last_min_first_max_element(first, last)
* Effect: std::make_pair( last_min_element(first, last),
* first_max_element(first, last) );
*
* last_min_first_max_element(first, last, comp)
* Effect: std::make_pair( last_min_element(first, last, comp),
* first_max_element(first, last, comp) );
*
* last_min_last_max_element(first, last)
* Effect: std::make_pair( last_min_element(first, last),
* last_max_element(first, last) );
*
* last_min_last_max_element(first, last, comp)
* Effect: std::make_pair( last_min_element(first, last, comp),
* last_max_element(first, last, comp) );
*/
namespace boost {
// Min_element and max_element variants
namespace detail { // common base for the overloads
template <typename ForwardIter, class BinaryPredicate>
ForwardIter
basic_first_min_element(ForwardIter first, ForwardIter last,
BinaryPredicate comp)
{
if (first == last) return last;
ForwardIter min_result = first;
while (++first != last)
if (comp(first, min_result))
min_result = first;
return min_result;
}
template <typename ForwardIter, class BinaryPredicate>
ForwardIter
basic_last_min_element(ForwardIter first, ForwardIter last,
BinaryPredicate comp)
{
if (first == last) return last;
ForwardIter min_result = first;
while (++first != last)
if (!comp(min_result, first))
min_result = first;
return min_result;
}
template <typename ForwardIter, class BinaryPredicate>
ForwardIter
basic_first_max_element(ForwardIter first, ForwardIter last,
BinaryPredicate comp)
{
if (first == last) return last;
ForwardIter max_result = first;
while (++first != last)
if (comp(max_result, first))
max_result = first;
return max_result;
}
template <typename ForwardIter, class BinaryPredicate>
ForwardIter
basic_last_max_element(ForwardIter first, ForwardIter last,
BinaryPredicate comp)
{
if (first == last) return last;
ForwardIter max_result = first;
while (++first != last)
if (!comp(first, max_result))
max_result = first;
return max_result;
}
} // namespace detail
template <typename ForwardIter>
ForwardIter
first_min_element(ForwardIter first, ForwardIter last)
{
return detail::basic_first_min_element(first, last,
detail::less_over_iter<ForwardIter>() );
}
template <typename ForwardIter, class BinaryPredicate>
ForwardIter
first_min_element(ForwardIter first, ForwardIter last, BinaryPredicate comp)
{
return detail::basic_first_min_element(first, last,
detail::binary_pred_over_iter<ForwardIter,BinaryPredicate>(comp) );
}
template <typename ForwardIter>
ForwardIter
last_min_element(ForwardIter first, ForwardIter last)
{
return detail::basic_last_min_element(first, last,
detail::less_over_iter<ForwardIter>() );
}
template <typename ForwardIter, class BinaryPredicate>
ForwardIter
last_min_element(ForwardIter first, ForwardIter last, BinaryPredicate comp)
{
return detail::basic_last_min_element(first, last,
detail::binary_pred_over_iter<ForwardIter,BinaryPredicate>(comp) );
}
template <typename ForwardIter>
ForwardIter
first_max_element(ForwardIter first, ForwardIter last)
{
return detail::basic_first_max_element(first, last,
detail::less_over_iter<ForwardIter>() );
}
template <typename ForwardIter, class BinaryPredicate>
ForwardIter
first_max_element(ForwardIter first, ForwardIter last, BinaryPredicate comp)
{
return detail::basic_first_max_element(first, last,
detail::binary_pred_over_iter<ForwardIter,BinaryPredicate>(comp) );
}
template <typename ForwardIter>
ForwardIter
last_max_element(ForwardIter first, ForwardIter last)
{
return detail::basic_last_max_element(first, last,
detail::less_over_iter<ForwardIter>() );
}
template <typename ForwardIter, class BinaryPredicate>
ForwardIter
last_max_element(ForwardIter first, ForwardIter last, BinaryPredicate comp)
{
return detail::basic_last_max_element(first, last,
detail::binary_pred_over_iter<ForwardIter,BinaryPredicate>(comp) );
}
// Minmax_element variants -- comments removed
namespace detail {
template <typename ForwardIter, class BinaryPredicate>
std::pair<ForwardIter,ForwardIter>
basic_first_min_last_max_element(ForwardIter first, ForwardIter last,
BinaryPredicate comp)
{
if (first == last)
return std::make_pair(last,last);
ForwardIter min_result = first;
ForwardIter max_result = first;
ForwardIter second = ++first;
if (second == last)
return std::make_pair(min_result, max_result);
if (comp(second, min_result))
min_result = second;
else
max_result = second;
first = ++second; if (first != last) ++second;
while (second != last) {
if (!comp(second, first)) {
if (comp(first, min_result))
min_result = first;
if (!comp(second, max_result))
max_result = second;
} else {
if (comp(second, min_result))
min_result = second;
if (!comp(first, max_result))
max_result = first;
}
first = ++second; if (first != last) ++second;
}
if (first != last) {
if (comp(first, min_result))
min_result = first;
else if (!comp(first, max_result))
max_result = first;
}
return std::make_pair(min_result, max_result);
}
template <typename ForwardIter, class BinaryPredicate>
std::pair<ForwardIter,ForwardIter>
basic_last_min_first_max_element(ForwardIter first, ForwardIter last,
BinaryPredicate comp)
{
if (first == last) return std::make_pair(last,last);
ForwardIter min_result = first;
ForwardIter max_result = first;
ForwardIter second = ++first;
if (second == last)
return std::make_pair(min_result, max_result);
if (comp(max_result, second))
max_result = second;
else
min_result = second;
first = ++second; if (first != last) ++second;
while (second != last) {
if (comp(first, second)) {
if (!comp(min_result, first))
min_result = first;
if (comp(max_result, second))
max_result = second;
} else {
if (!comp(min_result, second))
min_result = second;
if (comp(max_result, first))
max_result = first;
}
first = ++second; if (first != last) ++second;
}
if (first != last) {
if (!comp(min_result, first))
min_result = first;
else if (comp(max_result, first))
max_result = first;
}
return std::make_pair(min_result, max_result);
}
template <typename ForwardIter, class BinaryPredicate>
std::pair<ForwardIter,ForwardIter>
basic_last_min_last_max_element(ForwardIter first, ForwardIter last,
BinaryPredicate comp)
{
if (first == last) return std::make_pair(last,last);
ForwardIter min_result = first;
ForwardIter max_result = first;
ForwardIter second = first; ++second;
if (second == last)
return std::make_pair(min_result,max_result);
ForwardIter potential_max_result = last;
if (comp(first, second))
max_result = second;
else {
min_result = second;
potential_max_result = second;
}
first = ++second; if (first != last) ++second;
while (second != last) {
if (comp(first, second)) {
if (!comp(min_result, first))
min_result = first;
if (!comp(second, max_result)) {
max_result = second;
potential_max_result = last;
}
} else {
if (!comp(min_result, second))
min_result = second;
if (!comp(first, max_result)) {
max_result = first;
potential_max_result = second;
}
}
first = ++second;
if (first != last) ++second;
}
if (first != last) {
if (!comp(min_result, first))
min_result = first;
if (!comp(first, max_result)) {
max_result = first;
potential_max_result = last;
}
}
if (potential_max_result != last
&& !comp(potential_max_result, max_result))
max_result = potential_max_result;
return std::make_pair(min_result,max_result);
}
} // namespace detail
template <typename ForwardIter>
inline std::pair<ForwardIter,ForwardIter>
first_min_first_max_element(ForwardIter first, ForwardIter last)
{
return minmax_element(first, last);
}
template <typename ForwardIter, class BinaryPredicate>
inline std::pair<ForwardIter,ForwardIter>
first_min_first_max_element(ForwardIter first, ForwardIter last,
BinaryPredicate comp)
{
return minmax_element(first, last, comp);
}
template <typename ForwardIter>
std::pair<ForwardIter,ForwardIter>
first_min_last_max_element(ForwardIter first, ForwardIter last)
{
return detail::basic_first_min_last_max_element(first, last,
detail::less_over_iter<ForwardIter>() );
}
template <typename ForwardIter, class BinaryPredicate>
inline std::pair<ForwardIter,ForwardIter>
first_min_last_max_element(ForwardIter first, ForwardIter last,
BinaryPredicate comp)
{
return detail::basic_first_min_last_max_element(first, last,
detail::binary_pred_over_iter<ForwardIter,BinaryPredicate>(comp) );
}
template <typename ForwardIter>
std::pair<ForwardIter,ForwardIter>
last_min_first_max_element(ForwardIter first, ForwardIter last)
{
return detail::basic_last_min_first_max_element(first, last,
detail::less_over_iter<ForwardIter>() );
}
template <typename ForwardIter, class BinaryPredicate>
inline std::pair<ForwardIter,ForwardIter>
last_min_first_max_element(ForwardIter first, ForwardIter last,
BinaryPredicate comp)
{
return detail::basic_last_min_first_max_element(first, last,
detail::binary_pred_over_iter<ForwardIter,BinaryPredicate>(comp) );
}
template <typename ForwardIter>
std::pair<ForwardIter,ForwardIter>
last_min_last_max_element(ForwardIter first, ForwardIter last)
{
return detail::basic_last_min_last_max_element(first, last,
detail::less_over_iter<ForwardIter>() );
}
template <typename ForwardIter, class BinaryPredicate>
inline std::pair<ForwardIter,ForwardIter>
last_min_last_max_element(ForwardIter first, ForwardIter last,
BinaryPredicate comp)
{
return detail::basic_last_min_last_max_element(first, last,
detail::binary_pred_over_iter<ForwardIter,BinaryPredicate>(comp) );
}
} // namespace boost
#endif // BOOST_ALGORITHM_MINMAX_ELEMENT_HPP

View File

@ -0,0 +1,272 @@
/*
Copyright (c) Marshall Clow 2010-2012.
Distributed under the Boost Software License, Version 1.0. (See accompanying
file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
For more information, see http://www.boost.org
*/
#ifndef BOOST_ALGORITHM_BOYER_MOORE_SEARCH_HPP
#define BOOST_ALGORITHM_BOYER_MOORE_SEARCH_HPP
#include <iterator> // for std::iterator_traits
#include <boost/assert.hpp>
#include <boost/static_assert.hpp>
#include <boost/range/begin.hpp>
#include <boost/range/end.hpp>
#include <boost/utility/enable_if.hpp>
#include <boost/type_traits/is_same.hpp>
#include <boost/algorithm/searching/detail/bm_traits.hpp>
#include <boost/algorithm/searching/detail/debugging.hpp>
namespace boost { namespace algorithm {
/*
A templated version of the boyer-moore searching algorithm.
References:
http://www.cs.utexas.edu/users/moore/best-ideas/string-searching/
http://www.cs.utexas.edu/~moore/publications/fstrpos.pdf
Explanations:
http://en.wikipedia.org/wiki/Boyer%E2%80%93Moore_string_search_algorithm
http://www.movsd.com/bm.htm
http://www.cs.ucdavis.edu/~gusfield/cs224f09/bnotes.pdf
The Boyer-Moore search algorithm uses two tables, a "bad character" table
to tell how far to skip ahead when it hits a character that is not in the pattern,
and a "good character" table to tell how far to skip ahead when it hits a
mismatch on a character that _is_ in the pattern.
Requirements:
* Random access iterators
* The two iterator types (patIter and corpusIter) must
"point to" the same underlying type and be comparable.
* Additional requirements may be imposed but the skip table, such as:
** Numeric type (array-based skip table)
** Hashable type (map-based skip table)
*/
template <typename patIter, typename traits = detail::BM_traits<patIter> >
class boyer_moore {
typedef typename std::iterator_traits<patIter>::difference_type difference_type;
public:
boyer_moore ( patIter first, patIter last )
: pat_first ( first ), pat_last ( last ),
k_pattern_length ( std::distance ( pat_first, pat_last )),
skip_ ( k_pattern_length, -1 ),
suffix_ ( k_pattern_length + 1 )
{
this->build_skip_table ( first, last );
this->build_suffix_table ( first, last );
}
~boyer_moore () {}
/// \fn operator ( corpusIter corpus_first, corpusIter corpus_last )
/// \brief Searches the corpus for the pattern that was passed into the constructor
///
/// \param corpus_first The start of the data to search (Random Access Iterator)
/// \param corpus_last One past the end of the data to search
///
template <typename corpusIter>
std::pair<corpusIter, corpusIter>
operator () ( corpusIter corpus_first, corpusIter corpus_last ) const {
BOOST_STATIC_ASSERT (( boost::is_same<
typename std::iterator_traits<patIter>::value_type,
typename std::iterator_traits<corpusIter>::value_type>::value ));
if ( corpus_first == corpus_last ) return std::make_pair(corpus_last, corpus_last); // if nothing to search, we didn't find it!
if ( pat_first == pat_last ) return std::make_pair(corpus_first, corpus_first); // empty pattern matches at start
const difference_type k_corpus_length = std::distance ( corpus_first, corpus_last );
// If the pattern is larger than the corpus, we can't find it!
if ( k_corpus_length < k_pattern_length )
return std::make_pair(corpus_last, corpus_last);
// Do the search
return this->do_search ( corpus_first, corpus_last );
}
template <typename Range>
std::pair<typename boost::range_iterator<Range>::type, typename boost::range_iterator<Range>::type>
operator () ( Range &r ) const {
return (*this) (boost::begin(r), boost::end(r));
}
private:
/// \cond DOXYGEN_HIDE
patIter pat_first, pat_last;
const difference_type k_pattern_length;
typename traits::skip_table_t skip_;
std::vector <difference_type> suffix_;
/// \fn operator ( corpusIter corpus_first, corpusIter corpus_last, Pred p )
/// \brief Searches the corpus for the pattern that was passed into the constructor
///
/// \param corpus_first The start of the data to search (Random Access Iterator)
/// \param corpus_last One past the end of the data to search
/// \param p A predicate used for the search comparisons.
///
template <typename corpusIter>
std::pair<corpusIter, corpusIter>
do_search ( corpusIter corpus_first, corpusIter corpus_last ) const {
/* ---- Do the matching ---- */
corpusIter curPos = corpus_first;
const corpusIter lastPos = corpus_last - k_pattern_length;
difference_type j, k, m;
while ( curPos <= lastPos ) {
/* while ( std::distance ( curPos, corpus_last ) >= k_pattern_length ) { */
// Do we match right where we are?
j = k_pattern_length;
while ( pat_first [j-1] == curPos [j-1] ) {
j--;
// We matched - we're done!
if ( j == 0 )
return std::make_pair(curPos, curPos + k_pattern_length);
}
// Since we didn't match, figure out how far to skip forward
k = skip_ [ curPos [ j - 1 ]];
m = j - k - 1;
if ( k < j && m > suffix_ [ j ] )
curPos += m;
else
curPos += suffix_ [ j ];
}
return std::make_pair(corpus_last, corpus_last); // We didn't find anything
}
void build_skip_table ( patIter first, patIter last ) {
for ( std::size_t i = 0; first != last; ++first, ++i )
skip_.insert ( *first, i );
}
template<typename Iter, typename Container>
void compute_bm_prefix ( Iter pat_first, Iter pat_last, Container &prefix ) {
const std::size_t count = std::distance ( pat_first, pat_last );
BOOST_ASSERT ( count > 0 );
BOOST_ASSERT ( prefix.size () == count );
prefix[0] = 0;
std::size_t k = 0;
for ( std::size_t i = 1; i < count; ++i ) {
BOOST_ASSERT ( k < count );
while ( k > 0 && ( pat_first[k] != pat_first[i] )) {
BOOST_ASSERT ( k < count );
k = prefix [ k - 1 ];
}
if ( pat_first[k] == pat_first[i] )
k++;
prefix [ i ] = k;
}
}
void build_suffix_table ( patIter pat_first, patIter pat_last ) {
const std::size_t count = (std::size_t) std::distance ( pat_first, pat_last );
if ( count > 0 ) { // empty pattern
std::vector<typename std::iterator_traits<patIter>::value_type> reversed(count);
(void) std::reverse_copy ( pat_first, pat_last, reversed.begin ());
std::vector<difference_type> prefix (count);
compute_bm_prefix ( pat_first, pat_last, prefix );
std::vector<difference_type> prefix_reversed (count);
compute_bm_prefix ( reversed.begin (), reversed.end (), prefix_reversed );
for ( std::size_t i = 0; i <= count; i++ )
suffix_[i] = count - prefix [count-1];
for ( std::size_t i = 0; i < count; i++ ) {
const std::size_t j = count - prefix_reversed[i];
const difference_type k = i - prefix_reversed[i] + 1;
if (suffix_[j] > k)
suffix_[j] = k;
}
}
}
/// \endcond
};
/* Two ranges as inputs gives us four possibilities; with 2,3,3,4 parameters
Use a bit of TMP to disambiguate the 3-argument templates */
/// \fn boyer_moore_search ( corpusIter corpus_first, corpusIter corpus_last,
/// patIter pat_first, patIter pat_last )
/// \brief Searches the corpus for the pattern.
///
/// \param corpus_first The start of the data to search (Random Access Iterator)
/// \param corpus_last One past the end of the data to search
/// \param pat_first The start of the pattern to search for (Random Access Iterator)
/// \param pat_last One past the end of the data to search for
///
template <typename patIter, typename corpusIter>
std::pair<corpusIter, corpusIter> boyer_moore_search (
corpusIter corpus_first, corpusIter corpus_last,
patIter pat_first, patIter pat_last )
{
boyer_moore<patIter> bm ( pat_first, pat_last );
return bm ( corpus_first, corpus_last );
}
template <typename PatternRange, typename corpusIter>
std::pair<corpusIter, corpusIter> boyer_moore_search (
corpusIter corpus_first, corpusIter corpus_last, const PatternRange &pattern )
{
typedef typename boost::range_iterator<const PatternRange>::type pattern_iterator;
boyer_moore<pattern_iterator> bm ( boost::begin(pattern), boost::end (pattern));
return bm ( corpus_first, corpus_last );
}
template <typename patIter, typename CorpusRange>
typename boost::disable_if_c<
boost::is_same<CorpusRange, patIter>::value,
std::pair<typename boost::range_iterator<CorpusRange>::type, typename boost::range_iterator<CorpusRange>::type> >
::type
boyer_moore_search ( CorpusRange &corpus, patIter pat_first, patIter pat_last )
{
boyer_moore<patIter> bm ( pat_first, pat_last );
return bm (boost::begin (corpus), boost::end (corpus));
}
template <typename PatternRange, typename CorpusRange>
std::pair<typename boost::range_iterator<CorpusRange>::type, typename boost::range_iterator<CorpusRange>::type>
boyer_moore_search ( CorpusRange &corpus, const PatternRange &pattern )
{
typedef typename boost::range_iterator<const PatternRange>::type pattern_iterator;
boyer_moore<pattern_iterator> bm ( boost::begin(pattern), boost::end (pattern));
return bm (boost::begin (corpus), boost::end (corpus));
}
// Creator functions -- take a pattern range, return an object
template <typename Range>
boost::algorithm::boyer_moore<typename boost::range_iterator<const Range>::type>
make_boyer_moore ( const Range &r ) {
return boost::algorithm::boyer_moore
<typename boost::range_iterator<const Range>::type> (boost::begin(r), boost::end(r));
}
template <typename Range>
boost::algorithm::boyer_moore<typename boost::range_iterator<Range>::type>
make_boyer_moore ( Range &r ) {
return boost::algorithm::boyer_moore
<typename boost::range_iterator<Range>::type> (boost::begin(r), boost::end(r));
}
}}
#endif // BOOST_ALGORITHM_BOYER_MOORE_SEARCH_HPP

View File

@ -0,0 +1,202 @@
/*
Copyright (c) Marshall Clow 2010-2012.
Distributed under the Boost Software License, Version 1.0. (See accompanying
file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
For more information, see http://www.boost.org
*/
#ifndef BOOST_ALGORITHM_BOYER_MOORE_HORSPOOOL_SEARCH_HPP
#define BOOST_ALGORITHM_BOYER_MOORE_HORSPOOOL_SEARCH_HPP
#include <iterator> // for std::iterator_traits
#include <boost/assert.hpp>
#include <boost/static_assert.hpp>
#include <boost/range/begin.hpp>
#include <boost/range/end.hpp>
#include <boost/utility/enable_if.hpp>
#include <boost/type_traits/is_same.hpp>
#include <boost/algorithm/searching/detail/bm_traits.hpp>
#include <boost/algorithm/searching/detail/debugging.hpp>
// #define BOOST_ALGORITHM_BOYER_MOORE_HORSPOOL_DEBUG_HPP
namespace boost { namespace algorithm {
/*
A templated version of the boyer-moore-horspool searching algorithm.
Requirements:
* Random access iterators
* The two iterator types (patIter and corpusIter) must
"point to" the same underlying type.
* Additional requirements may be imposed buy the skip table, such as:
** Numeric type (array-based skip table)
** Hashable type (map-based skip table)
http://www-igm.univ-mlv.fr/%7Elecroq/string/node18.html
*/
template <typename patIter, typename traits = detail::BM_traits<patIter> >
class boyer_moore_horspool {
typedef typename std::iterator_traits<patIter>::difference_type difference_type;
public:
boyer_moore_horspool ( patIter first, patIter last )
: pat_first ( first ), pat_last ( last ),
k_pattern_length ( std::distance ( pat_first, pat_last )),
skip_ ( k_pattern_length, k_pattern_length ) {
// Build the skip table
std::size_t i = 0;
if ( first != last ) // empty pattern?
for ( patIter iter = first; iter != last-1; ++iter, ++i )
skip_.insert ( *iter, k_pattern_length - 1 - i );
#ifdef BOOST_ALGORITHM_BOYER_MOORE_HORSPOOL_DEBUG_HPP
skip_.PrintSkipTable ();
#endif
}
~boyer_moore_horspool () {}
/// \fn operator ( corpusIter corpus_first, corpusIter corpus_last)
/// \brief Searches the corpus for the pattern that was passed into the constructor
///
/// \param corpus_first The start of the data to search (Random Access Iterator)
/// \param corpus_last One past the end of the data to search
///
template <typename corpusIter>
std::pair<corpusIter, corpusIter>
operator () ( corpusIter corpus_first, corpusIter corpus_last ) const {
BOOST_STATIC_ASSERT (( boost::is_same<
typename std::iterator_traits<patIter>::value_type,
typename std::iterator_traits<corpusIter>::value_type>::value ));
if ( corpus_first == corpus_last ) return std::make_pair(corpus_last, corpus_last); // if nothing to search, we didn't find it!
if ( pat_first == pat_last ) return std::make_pair(corpus_first, corpus_first); // empty pattern matches at start
const difference_type k_corpus_length = std::distance ( corpus_first, corpus_last );
// If the pattern is larger than the corpus, we can't find it!
if ( k_corpus_length < k_pattern_length )
return std::make_pair(corpus_last, corpus_last);
// Do the search
return this->do_search ( corpus_first, corpus_last );
}
template <typename Range>
std::pair<typename boost::range_iterator<Range>::type, typename boost::range_iterator<Range>::type>
operator () ( Range &r ) const {
return (*this) (boost::begin(r), boost::end(r));
}
private:
/// \cond DOXYGEN_HIDE
patIter pat_first, pat_last;
const difference_type k_pattern_length;
typename traits::skip_table_t skip_;
/// \fn do_search ( corpusIter corpus_first, corpusIter corpus_last )
/// \brief Searches the corpus for the pattern that was passed into the constructor
///
/// \param corpus_first The start of the data to search (Random Access Iterator)
/// \param corpus_last One past the end of the data to search
/// \param k_corpus_length The length of the corpus to search
///
template <typename corpusIter>
std::pair<corpusIter, corpusIter>
do_search ( corpusIter corpus_first, corpusIter corpus_last ) const {
corpusIter curPos = corpus_first;
const corpusIter lastPos = corpus_last - k_pattern_length;
while ( curPos <= lastPos ) {
// Do we match right where we are?
std::size_t j = k_pattern_length - 1;
while ( pat_first [j] == curPos [j] ) {
// We matched - we're done!
if ( j == 0 )
return std::make_pair(curPos, curPos + k_pattern_length);
j--;
}
curPos += skip_ [ curPos [ k_pattern_length - 1 ]];
}
return std::make_pair(corpus_last, corpus_last);
}
// \endcond
};
/* Two ranges as inputs gives us four possibilities; with 2,3,3,4 parameters
Use a bit of TMP to disambiguate the 3-argument templates */
/// \fn boyer_moore_horspool_search ( corpusIter corpus_first, corpusIter corpus_last,
/// patIter pat_first, patIter pat_last )
/// \brief Searches the corpus for the pattern.
///
/// \param corpus_first The start of the data to search (Random Access Iterator)
/// \param corpus_last One past the end of the data to search
/// \param pat_first The start of the pattern to search for (Random Access Iterator)
/// \param pat_last One past the end of the data to search for
///
template <typename patIter, typename corpusIter>
std::pair<corpusIter, corpusIter> boyer_moore_horspool_search (
corpusIter corpus_first, corpusIter corpus_last,
patIter pat_first, patIter pat_last )
{
boyer_moore_horspool<patIter> bmh ( pat_first, pat_last );
return bmh ( corpus_first, corpus_last );
}
template <typename PatternRange, typename corpusIter>
std::pair<corpusIter, corpusIter> boyer_moore_horspool_search (
corpusIter corpus_first, corpusIter corpus_last, const PatternRange &pattern )
{
typedef typename boost::range_iterator<const PatternRange>::type pattern_iterator;
boyer_moore_horspool<pattern_iterator> bmh ( boost::begin(pattern), boost::end (pattern));
return bmh ( corpus_first, corpus_last );
}
template <typename patIter, typename CorpusRange>
typename boost::disable_if_c<
boost::is_same<CorpusRange, patIter>::value,
std::pair<typename boost::range_iterator<CorpusRange>::type, typename boost::range_iterator<CorpusRange>::type> >
::type
boyer_moore_horspool_search ( CorpusRange &corpus, patIter pat_first, patIter pat_last )
{
boyer_moore_horspool<patIter> bmh ( pat_first, pat_last );
return bm (boost::begin (corpus), boost::end (corpus));
}
template <typename PatternRange, typename CorpusRange>
std::pair<typename boost::range_iterator<CorpusRange>::type, typename boost::range_iterator<CorpusRange>::type>
boyer_moore_horspool_search ( CorpusRange &corpus, const PatternRange &pattern )
{
typedef typename boost::range_iterator<const PatternRange>::type pattern_iterator;
boyer_moore_horspool<pattern_iterator> bmh ( boost::begin(pattern), boost::end (pattern));
return bmh (boost::begin (corpus), boost::end (corpus));
}
// Creator functions -- take a pattern range, return an object
template <typename Range>
boost::algorithm::boyer_moore_horspool<typename boost::range_iterator<const Range>::type>
make_boyer_moore_horspool ( const Range &r ) {
return boost::algorithm::boyer_moore_horspool
<typename boost::range_iterator<const Range>::type> (boost::begin(r), boost::end(r));
}
template <typename Range>
boost::algorithm::boyer_moore_horspool<typename boost::range_iterator<Range>::type>
make_boyer_moore_horspool ( Range &r ) {
return boost::algorithm::boyer_moore_horspool
<typename boost::range_iterator<Range>::type> (boost::begin(r), boost::end(r));
}
}}
#endif // BOOST_ALGORITHM_BOYER_MOORE_HORSPOOOL_SEARCH_HPP

View File

@ -0,0 +1,113 @@
/*
Copyright (c) Marshall Clow 2010-2012.
Distributed under the Boost Software License, Version 1.0. (See accompanying
file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
For more information, see http://www.boost.org
*/
#ifndef BOOST_ALGORITHM_SEARCH_DETAIL_BM_TRAITS_HPP
#define BOOST_ALGORITHM_SEARCH_DETAIL_BM_TRAITS_HPP
#include <climits> // for CHAR_BIT
#include <vector>
#include <iterator> // for std::iterator_traits
#include <boost/type_traits/make_unsigned.hpp>
#include <boost/type_traits/is_integral.hpp>
#include <boost/type_traits/remove_pointer.hpp>
#include <boost/type_traits/remove_const.hpp>
#include <boost/array.hpp>
#ifdef BOOST_NO_CXX11_HDR_UNORDERED_MAP
#include <boost/unordered_map.hpp>
#else
#include <unordered_map>
#endif
#include <boost/algorithm/searching/detail/debugging.hpp>
namespace boost { namespace algorithm { namespace detail {
//
// Default implementations of the skip tables for B-M and B-M-H
//
template<typename key_type, typename value_type, bool /*useArray*/> class skip_table;
// General case for data searching other than bytes; use a map
template<typename key_type, typename value_type>
class skip_table<key_type, value_type, false> {
private:
#ifdef BOOST_NO_CXX11_HDR_UNORDERED_MAP
typedef boost::unordered_map<key_type, value_type> skip_map;
#else
typedef std::unordered_map<key_type, value_type> skip_map;
#endif
const value_type k_default_value;
skip_map skip_;
public:
skip_table ( std::size_t patSize, value_type default_value )
: k_default_value ( default_value ), skip_ ( patSize ) {}
void insert ( key_type key, value_type val ) {
skip_ [ key ] = val; // Would skip_.insert (val) be better here?
}
value_type operator [] ( key_type key ) const {
typename skip_map::const_iterator it = skip_.find ( key );
return it == skip_.end () ? k_default_value : it->second;
}
void PrintSkipTable () const {
std::cout << "BM(H) Skip Table <unordered_map>:" << std::endl;
for ( typename skip_map::const_iterator it = skip_.begin (); it != skip_.end (); ++it )
if ( it->second != k_default_value )
std::cout << " " << it->first << ": " << it->second << std::endl;
std::cout << std::endl;
}
};
// Special case small numeric values; use an array
template<typename key_type, typename value_type>
class skip_table<key_type, value_type, true> {
private:
typedef typename boost::make_unsigned<key_type>::type unsigned_key_type;
typedef boost::array<value_type, 1U << (CHAR_BIT * sizeof(key_type))> skip_map;
skip_map skip_;
const value_type k_default_value;
public:
skip_table ( std::size_t /*patSize*/, value_type default_value ) : k_default_value ( default_value ) {
std::fill_n ( skip_.begin(), skip_.size(), default_value );
}
void insert ( key_type key, value_type val ) {
skip_ [ static_cast<unsigned_key_type> ( key ) ] = val;
}
value_type operator [] ( key_type key ) const {
return skip_ [ static_cast<unsigned_key_type> ( key ) ];
}
void PrintSkipTable () const {
std::cout << "BM(H) Skip Table <boost:array>:" << std::endl;
for ( typename skip_map::const_iterator it = skip_.begin (); it != skip_.end (); ++it )
if ( *it != k_default_value )
std::cout << " " << std::distance (skip_.begin (), it) << ": " << *it << std::endl;
std::cout << std::endl;
}
};
template<typename Iterator>
struct BM_traits {
typedef typename std::iterator_traits<Iterator>::difference_type value_type;
typedef typename std::iterator_traits<Iterator>::value_type key_type;
typedef boost::algorithm::detail::skip_table<key_type, value_type,
boost::is_integral<key_type>::value && (sizeof(key_type)==1)> skip_table_t;
};
}}} // namespaces
#endif // BOOST_ALGORITHM_SEARCH_DETAIL_BM_TRAITS_HPP

View File

@ -0,0 +1,30 @@
/*
Copyright (c) Marshall Clow 2010-2012.
Distributed under the Boost Software License, Version 1.0. (See accompanying
file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
For more information, see http://www.boost.org
*/
#ifndef BOOST_ALGORITHM_SEARCH_DETAIL_DEBUG_HPP
#define BOOST_ALGORITHM_SEARCH_DETAIL_DEBUG_HPP
#include <iostream>
/// \cond DOXYGEN_HIDE
namespace boost { namespace algorithm { namespace detail {
// Debugging support
template <typename Iter>
void PrintTable ( Iter first, Iter last ) {
std::cout << std::distance ( first, last ) << ": { ";
for ( Iter iter = first; iter != last; ++iter )
std::cout << *iter << " ";
std::cout << "}" << std::endl;
}
}}}
/// \endcond
#endif // BOOST_ALGORITHM_SEARCH_DETAIL_DEBUG_HPP

View File

@ -0,0 +1,263 @@
/*
Copyright (c) Marshall Clow 2010-2012.
Distributed under the Boost Software License, Version 1.0. (See accompanying
file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
For more information, see http://www.boost.org
*/
#ifndef BOOST_ALGORITHM_KNUTH_MORRIS_PRATT_SEARCH_HPP
#define BOOST_ALGORITHM_KNUTH_MORRIS_PRATT_SEARCH_HPP
#include <vector>
#include <iterator> // for std::iterator_traits
#include <boost/assert.hpp>
#include <boost/static_assert.hpp>
#include <boost/range/begin.hpp>
#include <boost/range/end.hpp>
#include <boost/utility/enable_if.hpp>
#include <boost/type_traits/is_same.hpp>
#include <boost/algorithm/searching/detail/debugging.hpp>
// #define BOOST_ALGORITHM_KNUTH_MORRIS_PRATT_DEBUG
namespace boost { namespace algorithm {
// #define NEW_KMP
/*
A templated version of the Knuth-Morris-Pratt searching algorithm.
Requirements:
* Random-access iterators
* The two iterator types (I1 and I2) must "point to" the same underlying type.
http://en.wikipedia.org/wiki/Knuth-Morris-Pratt_algorithm
http://www.inf.fh-flensburg.de/lang/algorithmen/pattern/kmpen.htm
*/
template <typename patIter>
class knuth_morris_pratt {
typedef typename std::iterator_traits<patIter>::difference_type difference_type;
public:
knuth_morris_pratt ( patIter first, patIter last )
: pat_first ( first ), pat_last ( last ),
k_pattern_length ( std::distance ( pat_first, pat_last )),
skip_ ( k_pattern_length + 1 ) {
#ifdef NEW_KMP
preKmp ( pat_first, pat_last );
#else
init_skip_table ( pat_first, pat_last );
#endif
#ifdef BOOST_ALGORITHM_KNUTH_MORRIS_PRATT_DEBUG
detail::PrintTable ( skip_.begin (), skip_.end ());
#endif
}
~knuth_morris_pratt () {}
/// \fn operator ( corpusIter corpus_first, corpusIter corpus_last, Pred p )
/// \brief Searches the corpus for the pattern that was passed into the constructor
///
/// \param corpus_first The start of the data to search (Random Access Iterator)
/// \param corpus_last One past the end of the data to search
/// \param p A predicate used for the search comparisons.
///
template <typename corpusIter>
std::pair<corpusIter, corpusIter>
operator () ( corpusIter corpus_first, corpusIter corpus_last ) const {
BOOST_STATIC_ASSERT (( boost::is_same<
typename std::iterator_traits<patIter>::value_type,
typename std::iterator_traits<corpusIter>::value_type>::value ));
if ( corpus_first == corpus_last ) return std::make_pair(corpus_last, corpus_last); // if nothing to search, we didn't find it!
if ( pat_first == pat_last ) return std::make_pair(corpus_first, corpus_first); // empty pattern matches at start
const difference_type k_corpus_length = std::distance ( corpus_first, corpus_last );
// If the pattern is larger than the corpus, we can't find it!
if ( k_corpus_length < k_pattern_length )
return std::make_pair(corpus_last, corpus_last);
return do_search ( corpus_first, corpus_last, k_corpus_length );
}
template <typename Range>
std::pair<typename boost::range_iterator<Range>::type, typename boost::range_iterator<Range>::type>
operator () ( Range &r ) const {
return (*this) (boost::begin(r), boost::end(r));
}
private:
/// \cond DOXYGEN_HIDE
patIter pat_first, pat_last;
const difference_type k_pattern_length;
std::vector <difference_type> skip_;
/// \fn operator ( corpusIter corpus_first, corpusIter corpus_last, Pred p )
/// \brief Searches the corpus for the pattern that was passed into the constructor
///
/// \param corpus_first The start of the data to search (Random Access Iterator)
/// \param corpus_last One past the end of the data to search
/// \param p A predicate used for the search comparisons.
///
template <typename corpusIter>
std::pair<corpusIter, corpusIter>
do_search ( corpusIter corpus_first, corpusIter corpus_last,
difference_type k_corpus_length ) const {
difference_type match_start = 0; // position in the corpus that we're matching
#ifdef NEW_KMP
int patternIdx = 0;
while ( match_start < k_corpus_length ) {
while ( patternIdx > -1 && pat_first[patternIdx] != corpus_first [match_start] )
patternIdx = skip_ [patternIdx]; //<--- Shifting the pattern on mismatch
patternIdx++;
match_start++; //<--- corpus is always increased by 1
if ( patternIdx >= (int) k_pattern_length )
return corpus_first + match_start - patternIdx;
}
#else
// At this point, we know:
// k_pattern_length <= k_corpus_length
// for all elements of skip, it holds -1 .. k_pattern_length
//
// In the loop, we have the following invariants
// idx is in the range 0 .. k_pattern_length
// match_start is in the range 0 .. k_corpus_length - k_pattern_length + 1
const difference_type last_match = k_corpus_length - k_pattern_length;
difference_type idx = 0; // position in the pattern we're comparing
while ( match_start <= last_match ) {
while ( pat_first [ idx ] == corpus_first [ match_start + idx ] ) {
if ( ++idx == k_pattern_length )
return std::make_pair(corpus_first + match_start, corpus_first + match_start + k_pattern_length);
}
// Figure out where to start searching again
// assert ( idx - skip_ [ idx ] > 0 ); // we're always moving forward
match_start += idx - skip_ [ idx ];
idx = skip_ [ idx ] >= 0 ? skip_ [ idx ] : 0;
// assert ( idx >= 0 && idx < k_pattern_length );
}
#endif
// We didn't find anything
return std::make_pair(corpus_last, corpus_last);
}
void preKmp ( patIter first, patIter last ) {
const /*std::size_t*/ int count = std::distance ( first, last );
int i, j;
i = 0;
j = skip_[0] = -1;
while (i < count) {
while (j > -1 && first[i] != first[j])
j = skip_[j];
i++;
j++;
if (first[i] == first[j])
skip_[i] = skip_[j];
else
skip_[i] = j;
}
}
void init_skip_table ( patIter first, patIter last ) {
const difference_type count = std::distance ( first, last );
int j;
skip_ [ 0 ] = -1;
for ( int i = 1; i <= count; ++i ) {
j = skip_ [ i - 1 ];
while ( j >= 0 ) {
if ( first [ j ] == first [ i - 1 ] )
break;
j = skip_ [ j ];
}
skip_ [ i ] = j + 1;
}
}
// \endcond
};
/* Two ranges as inputs gives us four possibilities; with 2,3,3,4 parameters
Use a bit of TMP to disambiguate the 3-argument templates */
/// \fn knuth_morris_pratt_search ( corpusIter corpus_first, corpusIter corpus_last,
/// patIter pat_first, patIter pat_last )
/// \brief Searches the corpus for the pattern.
///
/// \param corpus_first The start of the data to search (Random Access Iterator)
/// \param corpus_last One past the end of the data to search
/// \param pat_first The start of the pattern to search for (Random Access Iterator)
/// \param pat_last One past the end of the data to search for
///
template <typename patIter, typename corpusIter>
std::pair<corpusIter, corpusIter> knuth_morris_pratt_search (
corpusIter corpus_first, corpusIter corpus_last,
patIter pat_first, patIter pat_last )
{
knuth_morris_pratt<patIter> kmp ( pat_first, pat_last );
return kmp ( corpus_first, corpus_last );
}
template <typename PatternRange, typename corpusIter>
std::pair<corpusIter, corpusIter> knuth_morris_pratt_search (
corpusIter corpus_first, corpusIter corpus_last, const PatternRange &pattern )
{
typedef typename boost::range_iterator<const PatternRange>::type pattern_iterator;
knuth_morris_pratt<pattern_iterator> kmp ( boost::begin(pattern), boost::end (pattern));
return kmp ( corpus_first, corpus_last );
}
template <typename patIter, typename CorpusRange>
typename boost::disable_if_c<
boost::is_same<CorpusRange, patIter>::value,
std::pair<typename boost::range_iterator<CorpusRange>::type, typename boost::range_iterator<CorpusRange>::type> >
::type
knuth_morris_pratt_search ( CorpusRange &corpus, patIter pat_first, patIter pat_last )
{
knuth_morris_pratt<patIter> kmp ( pat_first, pat_last );
return kmp (boost::begin (corpus), boost::end (corpus));
}
template <typename PatternRange, typename CorpusRange>
std::pair<typename boost::range_iterator<CorpusRange>::type, typename boost::range_iterator<CorpusRange>::type>
knuth_morris_pratt_search ( CorpusRange &corpus, const PatternRange &pattern )
{
typedef typename boost::range_iterator<const PatternRange>::type pattern_iterator;
knuth_morris_pratt<pattern_iterator> kmp ( boost::begin(pattern), boost::end (pattern));
return kmp (boost::begin (corpus), boost::end (corpus));
}
// Creator functions -- take a pattern range, return an object
template <typename Range>
boost::algorithm::knuth_morris_pratt<typename boost::range_iterator<const Range>::type>
make_knuth_morris_pratt ( const Range &r ) {
return boost::algorithm::knuth_morris_pratt
<typename boost::range_iterator<const Range>::type> (boost::begin(r), boost::end(r));
}
template <typename Range>
boost::algorithm::knuth_morris_pratt<typename boost::range_iterator<Range>::type>
make_knuth_morris_pratt ( Range &r ) {
return boost::algorithm::knuth_morris_pratt
<typename boost::range_iterator<Range>::type> (boost::begin(r), boost::end(r));
}
}}
#endif // BOOST_ALGORITHM_KNUTH_MORRIS_PRATT_SEARCH_HPP

View File

@ -0,0 +1,109 @@
/*
Copyright (c) Marshall Clow 2008-2012.
Distributed under the Boost Software License, Version 1.0. (See accompanying
file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
Revision history:
28 Sep 2015 mtc First version
*/
/// \file sort_subrange.hpp
/// \brief Sort a subrange
/// \author Marshall Clow
///
/// Suggested by Sean Parent in his CppCon 2015 keynote
#ifndef BOOST_ALGORITHM_SORT_SUBRANGE_HPP
#define BOOST_ALGORITHM_SORT_SUBRANGE_HPP
#include <functional> // For std::less
#include <iterator> // For std::iterator_traits
#include <algorithm> // For nth_element and partial_sort
#include <boost/range/begin.hpp>
#include <boost/range/end.hpp>
namespace boost { namespace algorithm {
/// \fn sort_subrange ( T const& val,
/// Iterator first, Iterator last,
/// Iterator sub_first, Iterator sub_last,
/// Pred p )
/// \brief Sort the subrange [sub_first, sub_last) that is inside
/// the range [first, last) as if you had sorted the entire range.
///
/// \param first The start of the larger range
/// \param last The end of the larger range
/// \param sub_first The start of the sub range
/// \param sub_last The end of the sub range
/// \param p A predicate to use to compare the values.
/// p ( a, b ) returns a boolean.
///
template<typename Iterator, typename Pred>
void sort_subrange (
Iterator first, Iterator last,
Iterator sub_first, Iterator sub_last,
Pred p)
{
if (sub_first == sub_last) return; // the empty sub-range is already sorted.
if (sub_first != first) { // sub-range is at the start, don't need to partition
(void) std::nth_element(first, sub_first, last, p);
++sub_first;
}
std::partial_sort(sub_first, sub_last, last, p);
}
template<typename Iterator>
void sort_subrange (Iterator first, Iterator last, Iterator sub_first, Iterator sub_last)
{
typedef typename std::iterator_traits<Iterator>::value_type value_type;
return sort_subrange(first, last, sub_first, sub_last, std::less<value_type>());
}
/// range versions?
/// \fn partition_subrange ( T const& val,
/// Iterator first, Iterator last,
/// Iterator sub_first, Iterator sub_last,
/// Pred p )
/// \brief Gather the elements of the subrange [sub_first, sub_last) that is
/// inside the range [first, last) as if you had sorted the entire range.
///
/// \param first The start of the larger range
/// \param last The end of the larger range
/// \param sub_first The start of the sub range
/// \param sub_last The end of the sub range
/// \param p A predicate to use to compare the values.
/// p ( a, b ) returns a boolean.
///
template<typename Iterator, typename Pred>
void partition_subrange (
Iterator first, Iterator last,
Iterator sub_first, Iterator sub_last,
Pred p)
{
if (sub_first != first) {
(void) std::nth_element(first, sub_first, last, p);
++sub_first;
}
if (sub_last != last)
(void) std::nth_element(sub_first, sub_last, last, p);
}
template<typename Iterator>
void partition_subrange (Iterator first, Iterator last, Iterator sub_first, Iterator sub_last)
{
typedef typename std::iterator_traits<Iterator>::value_type value_type;
return partition_subrange(first, last, sub_first, sub_last, std::less<value_type>());
}
}}
#endif // BOOST_ALGORITHM_SORT_SUBRANGE_HPP

View File

@ -0,0 +1,31 @@
// Boost string_algo library string_algo.hpp header file ---------------------------//
// Copyright Pavol Droba 2002-2004.
//
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
// See http://www.boost.org/ for updates, documentation, and revision history.
#ifndef BOOST_STRING_ALGO_HPP
#define BOOST_STRING_ALGO_HPP
/*! \file
Cumulative include for string_algo library
*/
#include <boost/algorithm/string/std_containers_traits.hpp>
#include <boost/algorithm/string/trim.hpp>
#include <boost/algorithm/string/case_conv.hpp>
#include <boost/algorithm/string/predicate.hpp>
#include <boost/algorithm/string/find.hpp>
#include <boost/algorithm/string/split.hpp>
#include <boost/algorithm/string/join.hpp>
#include <boost/algorithm/string/replace.hpp>
#include <boost/algorithm/string/erase.hpp>
#include <boost/algorithm/string/classification.hpp>
#include <boost/algorithm/string/find_iterator.hpp>
#endif // BOOST_STRING_ALGO_HPP

View File

@ -0,0 +1,176 @@
// Boost string_algo library case_conv.hpp header file ---------------------------//
// Copyright Pavol Droba 2002-2003.
//
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
// See http://www.boost.org/ for updates, documentation, and revision history.
#ifndef BOOST_STRING_CASE_CONV_HPP
#define BOOST_STRING_CASE_CONV_HPP
#include <boost/algorithm/string/config.hpp>
#include <algorithm>
#include <locale>
#include <boost/iterator/transform_iterator.hpp>
#include <boost/range/as_literal.hpp>
#include <boost/range/begin.hpp>
#include <boost/range/end.hpp>
#include <boost/range/value_type.hpp>
#include <boost/algorithm/string/detail/case_conv.hpp>
/*! \file
Defines sequence case-conversion algorithms.
Algorithms convert each element in the input sequence to the
desired case using provided locales.
*/
namespace boost {
namespace algorithm {
// to_lower -----------------------------------------------//
//! Convert to lower case
/*!
Each element of the input sequence is converted to lower
case. The result is a copy of the input converted to lower case.
It is returned as a sequence or copied to the output iterator.
\param Output An output iterator to which the result will be copied
\param Input An input range
\param Loc A locale used for conversion
\return
An output iterator pointing just after the last inserted character or
a copy of the input
\note The second variant of this function provides the strong exception-safety guarantee
*/
template<typename OutputIteratorT, typename RangeT>
inline OutputIteratorT
to_lower_copy(
OutputIteratorT Output,
const RangeT& Input,
const std::locale& Loc=std::locale())
{
return ::boost::algorithm::detail::transform_range_copy(
Output,
::boost::as_literal(Input),
::boost::algorithm::detail::to_lowerF<
typename range_value<RangeT>::type >(Loc));
}
//! Convert to lower case
/*!
\overload
*/
template<typename SequenceT>
inline SequenceT to_lower_copy(
const SequenceT& Input,
const std::locale& Loc=std::locale())
{
return ::boost::algorithm::detail::transform_range_copy<SequenceT>(
Input,
::boost::algorithm::detail::to_lowerF<
typename range_value<SequenceT>::type >(Loc));
}
//! Convert to lower case
/*!
Each element of the input sequence is converted to lower
case. The input sequence is modified in-place.
\param Input A range
\param Loc a locale used for conversion
*/
template<typename WritableRangeT>
inline void to_lower(
WritableRangeT& Input,
const std::locale& Loc=std::locale())
{
::boost::algorithm::detail::transform_range(
::boost::as_literal(Input),
::boost::algorithm::detail::to_lowerF<
typename range_value<WritableRangeT>::type >(Loc));
}
// to_upper -----------------------------------------------//
//! Convert to upper case
/*!
Each element of the input sequence is converted to upper
case. The result is a copy of the input converted to upper case.
It is returned as a sequence or copied to the output iterator
\param Output An output iterator to which the result will be copied
\param Input An input range
\param Loc A locale used for conversion
\return
An output iterator pointing just after the last inserted character or
a copy of the input
\note The second variant of this function provides the strong exception-safety guarantee
*/
template<typename OutputIteratorT, typename RangeT>
inline OutputIteratorT
to_upper_copy(
OutputIteratorT Output,
const RangeT& Input,
const std::locale& Loc=std::locale())
{
return ::boost::algorithm::detail::transform_range_copy(
Output,
::boost::as_literal(Input),
::boost::algorithm::detail::to_upperF<
typename range_value<RangeT>::type >(Loc));
}
//! Convert to upper case
/*!
\overload
*/
template<typename SequenceT>
inline SequenceT to_upper_copy(
const SequenceT& Input,
const std::locale& Loc=std::locale())
{
return ::boost::algorithm::detail::transform_range_copy<SequenceT>(
Input,
::boost::algorithm::detail::to_upperF<
typename range_value<SequenceT>::type >(Loc));
}
//! Convert to upper case
/*!
Each element of the input sequence is converted to upper
case. The input sequence is modified in-place.
\param Input An input range
\param Loc a locale used for conversion
*/
template<typename WritableRangeT>
inline void to_upper(
WritableRangeT& Input,
const std::locale& Loc=std::locale())
{
::boost::algorithm::detail::transform_range(
::boost::as_literal(Input),
::boost::algorithm::detail::to_upperF<
typename range_value<WritableRangeT>::type >(Loc));
}
} // namespace algorithm
// pull names to the boost namespace
using algorithm::to_lower;
using algorithm::to_lower_copy;
using algorithm::to_upper;
using algorithm::to_upper_copy;
} // namespace boost
#endif // BOOST_STRING_CASE_CONV_HPP

View File

@ -0,0 +1,312 @@
// Boost string_algo library classification.hpp header file ---------------------------//
// Copyright Pavol Droba 2002-2003.
//
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
// See http://www.boost.org/ for updates, documentation, and revision history.
#ifndef BOOST_STRING_CLASSIFICATION_HPP
#define BOOST_STRING_CLASSIFICATION_HPP
#include <algorithm>
#include <locale>
#include <boost/range/value_type.hpp>
#include <boost/range/as_literal.hpp>
#include <boost/algorithm/string/detail/classification.hpp>
#include <boost/algorithm/string/predicate_facade.hpp>
/*! \file
Classification predicates are included in the library to give
some more convenience when using algorithms like \c trim() and \c all().
They wrap functionality of STL classification functions ( e.g. \c std::isspace() )
into generic functors.
*/
namespace boost {
namespace algorithm {
// classification functor generator -------------------------------------//
//! is_classified predicate
/*!
Construct the \c is_classified predicate. This predicate holds if the input is
of specified \c std::ctype category.
\param Type A \c std::ctype category
\param Loc A locale used for classification
\return An instance of the \c is_classified predicate
*/
inline detail::is_classifiedF
is_classified(std::ctype_base::mask Type, const std::locale& Loc=std::locale())
{
return detail::is_classifiedF(Type, Loc);
}
//! is_space predicate
/*!
Construct the \c is_classified predicate for the \c ctype_base::space category.
\param Loc A locale used for classification
\return An instance of the \c is_classified predicate
*/
inline detail::is_classifiedF
is_space(const std::locale& Loc=std::locale())
{
return detail::is_classifiedF(std::ctype_base::space, Loc);
}
//! is_alnum predicate
/*!
Construct the \c is_classified predicate for the \c ctype_base::alnum category.
\param Loc A locale used for classification
\return An instance of the \c is_classified predicate
*/
inline detail::is_classifiedF
is_alnum(const std::locale& Loc=std::locale())
{
return detail::is_classifiedF(std::ctype_base::alnum, Loc);
}
//! is_alpha predicate
/*!
Construct the \c is_classified predicate for the \c ctype_base::alpha category.
\param Loc A locale used for classification
\return An instance of the \c is_classified predicate
*/
inline detail::is_classifiedF
is_alpha(const std::locale& Loc=std::locale())
{
return detail::is_classifiedF(std::ctype_base::alpha, Loc);
}
//! is_cntrl predicate
/*!
Construct the \c is_classified predicate for the \c ctype_base::cntrl category.
\param Loc A locale used for classification
\return An instance of the \c is_classified predicate
*/
inline detail::is_classifiedF
is_cntrl(const std::locale& Loc=std::locale())
{
return detail::is_classifiedF(std::ctype_base::cntrl, Loc);
}
//! is_digit predicate
/*!
Construct the \c is_classified predicate for the \c ctype_base::digit category.
\param Loc A locale used for classification
\return An instance of the \c is_classified predicate
*/
inline detail::is_classifiedF
is_digit(const std::locale& Loc=std::locale())
{
return detail::is_classifiedF(std::ctype_base::digit, Loc);
}
//! is_graph predicate
/*!
Construct the \c is_classified predicate for the \c ctype_base::graph category.
\param Loc A locale used for classification
\return An instance of the \c is_classified predicate
*/
inline detail::is_classifiedF
is_graph(const std::locale& Loc=std::locale())
{
return detail::is_classifiedF(std::ctype_base::graph, Loc);
}
//! is_lower predicate
/*!
Construct the \c is_classified predicate for the \c ctype_base::lower category.
\param Loc A locale used for classification
\return An instance of \c is_classified predicate
*/
inline detail::is_classifiedF
is_lower(const std::locale& Loc=std::locale())
{
return detail::is_classifiedF(std::ctype_base::lower, Loc);
}
//! is_print predicate
/*!
Construct the \c is_classified predicate for the \c ctype_base::print category.
\param Loc A locale used for classification
\return An instance of the \c is_classified predicate
*/
inline detail::is_classifiedF
is_print(const std::locale& Loc=std::locale())
{
return detail::is_classifiedF(std::ctype_base::print, Loc);
}
//! is_punct predicate
/*!
Construct the \c is_classified predicate for the \c ctype_base::punct category.
\param Loc A locale used for classification
\return An instance of the \c is_classified predicate
*/
inline detail::is_classifiedF
is_punct(const std::locale& Loc=std::locale())
{
return detail::is_classifiedF(std::ctype_base::punct, Loc);
}
//! is_upper predicate
/*!
Construct the \c is_classified predicate for the \c ctype_base::upper category.
\param Loc A locale used for classification
\return An instance of the \c is_classified predicate
*/
inline detail::is_classifiedF
is_upper(const std::locale& Loc=std::locale())
{
return detail::is_classifiedF(std::ctype_base::upper, Loc);
}
//! is_xdigit predicate
/*!
Construct the \c is_classified predicate for the \c ctype_base::xdigit category.
\param Loc A locale used for classification
\return An instance of the \c is_classified predicate
*/
inline detail::is_classifiedF
is_xdigit(const std::locale& Loc=std::locale())
{
return detail::is_classifiedF(std::ctype_base::xdigit, Loc);
}
//! is_any_of predicate
/*!
Construct the \c is_any_of predicate. The predicate holds if the input
is included in the specified set of characters.
\param Set A set of characters to be recognized
\return An instance of the \c is_any_of predicate
*/
template<typename RangeT>
inline detail::is_any_ofF<
BOOST_STRING_TYPENAME range_value<RangeT>::type>
is_any_of( const RangeT& Set )
{
iterator_range<BOOST_STRING_TYPENAME range_const_iterator<RangeT>::type> lit_set(boost::as_literal(Set));
return detail::is_any_ofF<BOOST_STRING_TYPENAME range_value<RangeT>::type>(lit_set);
}
//! is_from_range predicate
/*!
Construct the \c is_from_range predicate. The predicate holds if the input
is included in the specified range. (i.e. From <= Ch <= To )
\param From The start of the range
\param To The end of the range
\return An instance of the \c is_from_range predicate
*/
template<typename CharT>
inline detail::is_from_rangeF<CharT> is_from_range(CharT From, CharT To)
{
return detail::is_from_rangeF<CharT>(From,To);
}
// predicate combinators ---------------------------------------------------//
//! predicate 'and' composition predicate
/*!
Construct the \c class_and predicate. This predicate can be used
to logically combine two classification predicates. \c class_and holds,
if both predicates return true.
\param Pred1 The first predicate
\param Pred2 The second predicate
\return An instance of the \c class_and predicate
*/
template<typename Pred1T, typename Pred2T>
inline detail::pred_andF<Pred1T, Pred2T>
operator&&(
const predicate_facade<Pred1T>& Pred1,
const predicate_facade<Pred2T>& Pred2 )
{
// Doing the static_cast with the pointer instead of the reference
// is a workaround for some compilers which have problems with
// static_cast's of template references, i.e. CW8. /grafik/
return detail::pred_andF<Pred1T,Pred2T>(
*static_cast<const Pred1T*>(&Pred1),
*static_cast<const Pred2T*>(&Pred2) );
}
//! predicate 'or' composition predicate
/*!
Construct the \c class_or predicate. This predicate can be used
to logically combine two classification predicates. \c class_or holds,
if one of the predicates return true.
\param Pred1 The first predicate
\param Pred2 The second predicate
\return An instance of the \c class_or predicate
*/
template<typename Pred1T, typename Pred2T>
inline detail::pred_orF<Pred1T, Pred2T>
operator||(
const predicate_facade<Pred1T>& Pred1,
const predicate_facade<Pred2T>& Pred2 )
{
// Doing the static_cast with the pointer instead of the reference
// is a workaround for some compilers which have problems with
// static_cast's of template references, i.e. CW8. /grafik/
return detail::pred_orF<Pred1T,Pred2T>(
*static_cast<const Pred1T*>(&Pred1),
*static_cast<const Pred2T*>(&Pred2));
}
//! predicate negation operator
/*!
Construct the \c class_not predicate. This predicate represents a negation.
\c class_or holds if of the predicates return false.
\param Pred The predicate to be negated
\return An instance of the \c class_not predicate
*/
template<typename PredT>
inline detail::pred_notF<PredT>
operator!( const predicate_facade<PredT>& Pred )
{
// Doing the static_cast with the pointer instead of the reference
// is a workaround for some compilers which have problems with
// static_cast's of template references, i.e. CW8. /grafik/
return detail::pred_notF<PredT>(*static_cast<const PredT*>(&Pred));
}
} // namespace algorithm
// pull names to the boost namespace
using algorithm::is_classified;
using algorithm::is_space;
using algorithm::is_alnum;
using algorithm::is_alpha;
using algorithm::is_cntrl;
using algorithm::is_digit;
using algorithm::is_graph;
using algorithm::is_lower;
using algorithm::is_upper;
using algorithm::is_print;
using algorithm::is_punct;
using algorithm::is_xdigit;
using algorithm::is_any_of;
using algorithm::is_from_range;
} // namespace boost
#endif // BOOST_STRING_PREDICATE_HPP

View File

@ -0,0 +1,199 @@
// Boost string_algo library compare.hpp header file -------------------------//
// Copyright Pavol Droba 2002-2006.
//
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
// See http://www.boost.org/ for updates, documentation, and revision history.
#ifndef BOOST_STRING_COMPARE_HPP
#define BOOST_STRING_COMPARE_HPP
#include <boost/algorithm/string/config.hpp>
#include <locale>
/*! \file
Defines element comparison predicates. Many algorithms in this library can
take an additional argument with a predicate used to compare elements.
This makes it possible, for instance, to have case insensitive versions
of the algorithms.
*/
namespace boost {
namespace algorithm {
// is_equal functor -----------------------------------------------//
//! is_equal functor
/*!
Standard STL equal_to only handle comparison between arguments
of the same type. This is a less restrictive version which wraps operator ==.
*/
struct is_equal
{
//! Function operator
/*!
Compare two operands for equality
*/
template< typename T1, typename T2 >
bool operator()( const T1& Arg1, const T2& Arg2 ) const
{
return Arg1==Arg2;
}
};
//! case insensitive version of is_equal
/*!
Case insensitive comparison predicate. Comparison is done using
specified locales.
*/
struct is_iequal
{
//! Constructor
/*!
\param Loc locales used for comparison
*/
is_iequal( const std::locale& Loc=std::locale() ) :
m_Loc( Loc ) {}
//! Function operator
/*!
Compare two operands. Case is ignored.
*/
template< typename T1, typename T2 >
bool operator()( const T1& Arg1, const T2& Arg2 ) const
{
#if defined(__BORLANDC__) && (__BORLANDC__ >= 0x560) && (__BORLANDC__ <= 0x564) && !defined(_USE_OLD_RW_STL)
return std::toupper(Arg1)==std::toupper(Arg2);
#else
return std::toupper<T1>(Arg1,m_Loc)==std::toupper<T2>(Arg2,m_Loc);
#endif
}
private:
std::locale m_Loc;
};
// is_less functor -----------------------------------------------//
//! is_less functor
/*!
Convenient version of standard std::less. Operation is templated, therefore it is
not required to specify the exact types upon the construction
*/
struct is_less
{
//! Functor operation
/*!
Compare two operands using > operator
*/
template< typename T1, typename T2 >
bool operator()( const T1& Arg1, const T2& Arg2 ) const
{
return Arg1<Arg2;
}
};
//! case insensitive version of is_less
/*!
Case insensitive comparison predicate. Comparison is done using
specified locales.
*/
struct is_iless
{
//! Constructor
/*!
\param Loc locales used for comparison
*/
is_iless( const std::locale& Loc=std::locale() ) :
m_Loc( Loc ) {}
//! Function operator
/*!
Compare two operands. Case is ignored.
*/
template< typename T1, typename T2 >
bool operator()( const T1& Arg1, const T2& Arg2 ) const
{
#if defined(__BORLANDC__) && (__BORLANDC__ >= 0x560) && (__BORLANDC__ <= 0x564) && !defined(_USE_OLD_RW_STL)
return std::toupper(Arg1)<std::toupper(Arg2);
#else
return std::toupper<T1>(Arg1,m_Loc)<std::toupper<T2>(Arg2,m_Loc);
#endif
}
private:
std::locale m_Loc;
};
// is_not_greater functor -----------------------------------------------//
//! is_not_greater functor
/*!
Convenient version of standard std::not_greater_to. Operation is templated, therefore it is
not required to specify the exact types upon the construction
*/
struct is_not_greater
{
//! Functor operation
/*!
Compare two operands using > operator
*/
template< typename T1, typename T2 >
bool operator()( const T1& Arg1, const T2& Arg2 ) const
{
return Arg1<=Arg2;
}
};
//! case insensitive version of is_not_greater
/*!
Case insensitive comparison predicate. Comparison is done using
specified locales.
*/
struct is_not_igreater
{
//! Constructor
/*!
\param Loc locales used for comparison
*/
is_not_igreater( const std::locale& Loc=std::locale() ) :
m_Loc( Loc ) {}
//! Function operator
/*!
Compare two operands. Case is ignored.
*/
template< typename T1, typename T2 >
bool operator()( const T1& Arg1, const T2& Arg2 ) const
{
#if defined(__BORLANDC__) && (__BORLANDC__ >= 0x560) && (__BORLANDC__ <= 0x564) && !defined(_USE_OLD_RW_STL)
return std::toupper(Arg1)<=std::toupper(Arg2);
#else
return std::toupper<T1>(Arg1,m_Loc)<=std::toupper<T2>(Arg2,m_Loc);
#endif
}
private:
std::locale m_Loc;
};
} // namespace algorithm
// pull names to the boost namespace
using algorithm::is_equal;
using algorithm::is_iequal;
using algorithm::is_less;
using algorithm::is_iless;
using algorithm::is_not_greater;
using algorithm::is_not_igreater;
} // namespace boost
#endif // BOOST_STRING_COMPARE_HPP

View File

@ -0,0 +1,83 @@
// Boost string_algo library concept.hpp header file ---------------------------//
// Copyright Pavol Droba 2002-2003.
//
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
// See http://www.boost.org/ for updates, documentation, and revision history.
#ifndef BOOST_STRING_CONCEPT_HPP
#define BOOST_STRING_CONCEPT_HPP
#include <boost/concept_check.hpp>
#include <boost/range/iterator_range_core.hpp>
#include <boost/range/begin.hpp>
#include <boost/range/end.hpp>
/*! \file
Defines concepts used in string_algo library
*/
namespace boost {
namespace algorithm {
//! Finder concept
/*!
Defines the Finder concept. Finder is a functor which selects
an arbitrary part of a string. Search is performed on
the range specified by starting and ending iterators.
Result of the find operation must be convertible to iterator_range.
*/
template<typename FinderT, typename IteratorT>
struct FinderConcept
{
private:
typedef iterator_range<IteratorT> range;
public:
void constraints()
{
// Operation
r=(*pF)(i,i);
}
private:
range r;
IteratorT i;
FinderT* pF;
}; // Finder_concept
//! Formatter concept
/*!
Defines the Formatter concept. Formatter is a functor, which
takes a result from a finder operation and transforms it
in a specific way.
Result must be a container supported by container_traits,
or a reference to it.
*/
template<typename FormatterT, typename FinderT, typename IteratorT>
struct FormatterConcept
{
public:
void constraints()
{
// Operation
::boost::begin((*pFo)( (*pF)(i,i) ));
::boost::end((*pFo)( (*pF)(i,i) ));
}
private:
IteratorT i;
FinderT* pF;
FormatterT *pFo;
}; // FormatterConcept;
} // namespace algorithm
} // namespace boost
#endif // BOOST_STRING_CONCEPT_HPP

View File

@ -0,0 +1,28 @@
// Boost string_algo library config.hpp header file ---------------------------//
// Copyright Pavol Droba 2002-2003.
//
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
// See http://www.boost.org/ for updates, documentation, and revision history.
#ifndef BOOST_STRING_CONFIG_HPP
#define BOOST_STRING_CONFIG_HPP
#include <boost/config.hpp>
#include <boost/detail/workaround.hpp>
#ifdef BOOST_STRING_DEDUCED_TYPENAME
# error "macro already defined!"
#endif
#define BOOST_STRING_TYPENAME BOOST_DEDUCED_TYPENAME
// Metrowerks workaround
#if BOOST_WORKAROUND(__MWERKS__, <= 0x3003) // 8.x
#pragma parse_func_templ off
#endif
#endif // BOOST_STRING_CONFIG_HPP

View File

@ -0,0 +1,36 @@
// Boost string_algo library constants.hpp header file ---------------------------//
// Copyright Pavol Droba 2002-2003.
//
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
// See http://www.boost.org/ for updates, documentation, and revision history.
#ifndef BOOST_STRING_CONSTANTS_HPP
#define BOOST_STRING_CONSTANTS_HPP
namespace boost {
namespace algorithm {
//! Token compression mode
/*!
Specifies token compression mode for the token_finder.
*/
enum token_compress_mode_type
{
token_compress_on, //!< Compress adjacent tokens
token_compress_off //!< Do not compress adjacent tokens
};
} // namespace algorithm
// pull the names to the boost namespace
using algorithm::token_compress_on;
using algorithm::token_compress_off;
} // namespace boost
#endif // BOOST_STRING_CONSTANTS_HPP

View File

@ -0,0 +1,123 @@
// Boost string_algo library string_funct.hpp header file ---------------------------//
// Copyright Pavol Droba 2002-2003.
//
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
// See http://www.boost.org/ for updates, documentation, and revision history.
#ifndef BOOST_STRING_CASE_CONV_DETAIL_HPP
#define BOOST_STRING_CASE_CONV_DETAIL_HPP
#include <boost/algorithm/string/config.hpp>
#include <locale>
#include <functional>
#include <boost/type_traits/make_unsigned.hpp>
namespace boost {
namespace algorithm {
namespace detail {
// case conversion functors -----------------------------------------------//
#if BOOST_WORKAROUND(BOOST_MSVC, >= 1400)
#pragma warning(push)
#pragma warning(disable:4512) //assignment operator could not be generated
#endif
// a tolower functor
template<typename CharT>
struct to_lowerF : public std::unary_function<CharT, CharT>
{
// Constructor
to_lowerF( const std::locale& Loc ) : m_Loc( &Loc ) {}
// Operation
CharT operator ()( CharT Ch ) const
{
#if defined(__BORLANDC__) && (__BORLANDC__ >= 0x560) && (__BORLANDC__ <= 0x564) && !defined(_USE_OLD_RW_STL)
return std::tolower( static_cast<typename boost::make_unsigned <CharT>::type> ( Ch ));
#else
return std::tolower<CharT>( Ch, *m_Loc );
#endif
}
private:
const std::locale* m_Loc;
};
// a toupper functor
template<typename CharT>
struct to_upperF : public std::unary_function<CharT, CharT>
{
// Constructor
to_upperF( const std::locale& Loc ) : m_Loc( &Loc ) {}
// Operation
CharT operator ()( CharT Ch ) const
{
#if defined(__BORLANDC__) && (__BORLANDC__ >= 0x560) && (__BORLANDC__ <= 0x564) && !defined(_USE_OLD_RW_STL)
return std::toupper( static_cast<typename boost::make_unsigned <CharT>::type> ( Ch ));
#else
return std::toupper<CharT>( Ch, *m_Loc );
#endif
}
private:
const std::locale* m_Loc;
};
#if BOOST_WORKAROUND(BOOST_MSVC, >= 1400)
#pragma warning(pop)
#endif
// algorithm implementation -------------------------------------------------------------------------
// Transform a range
template<typename OutputIteratorT, typename RangeT, typename FunctorT>
OutputIteratorT transform_range_copy(
OutputIteratorT Output,
const RangeT& Input,
FunctorT Functor)
{
return std::transform(
::boost::begin(Input),
::boost::end(Input),
Output,
Functor);
}
// Transform a range (in-place)
template<typename RangeT, typename FunctorT>
void transform_range(
const RangeT& Input,
FunctorT Functor)
{
std::transform(
::boost::begin(Input),
::boost::end(Input),
::boost::begin(Input),
Functor);
}
template<typename SequenceT, typename RangeT, typename FunctorT>
inline SequenceT transform_range_copy(
const RangeT& Input,
FunctorT Functor)
{
return SequenceT(
::boost::make_transform_iterator(
::boost::begin(Input),
Functor),
::boost::make_transform_iterator(
::boost::end(Input),
Functor));
}
} // namespace detail
} // namespace algorithm
} // namespace boost
#endif // BOOST_STRING_CASE_CONV_DETAIL_HPP

View File

@ -0,0 +1,353 @@
// Boost string_algo library classification.hpp header file ---------------------------//
// Copyright Pavol Droba 2002-2003.
//
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
// See http://www.boost.org/ for updates, documentation, and revision history.
#ifndef BOOST_STRING_CLASSIFICATION_DETAIL_HPP
#define BOOST_STRING_CLASSIFICATION_DETAIL_HPP
#include <boost/algorithm/string/config.hpp>
#include <algorithm>
#include <functional>
#include <locale>
#include <boost/range/begin.hpp>
#include <boost/range/end.hpp>
#include <boost/algorithm/string/predicate_facade.hpp>
#include <boost/type_traits/remove_const.hpp>
namespace boost {
namespace algorithm {
namespace detail {
// classification functors -----------------------------------------------//
// is_classified functor
struct is_classifiedF :
public predicate_facade<is_classifiedF>
{
// Boost.ResultOf support
typedef bool result_type;
// Constructor from a locale
is_classifiedF(std::ctype_base::mask Type, std::locale const & Loc = std::locale()) :
m_Type(Type), m_Locale(Loc) {}
// Operation
template<typename CharT>
bool operator()( CharT Ch ) const
{
return std::use_facet< std::ctype<CharT> >(m_Locale).is( m_Type, Ch );
}
#if defined(__BORLANDC__) && (__BORLANDC__ >= 0x560) && (__BORLANDC__ <= 0x582) && !defined(_USE_OLD_RW_STL)
template<>
bool operator()( char const Ch ) const
{
return std::use_facet< std::ctype<char> >(m_Locale).is( m_Type, Ch );
}
#endif
private:
std::ctype_base::mask m_Type;
std::locale m_Locale;
};
// is_any_of functor
/*
returns true if the value is from the specified set
*/
template<typename CharT>
struct is_any_ofF :
public predicate_facade<is_any_ofF<CharT> >
{
private:
// set cannot operate on const value-type
typedef typename ::boost::remove_const<CharT>::type set_value_type;
public:
// Boost.ResultOf support
typedef bool result_type;
// Constructor
template<typename RangeT>
is_any_ofF( const RangeT& Range ) : m_Size(0)
{
// Prepare storage
m_Storage.m_dynSet=0;
std::size_t Size=::boost::distance(Range);
m_Size=Size;
set_value_type* Storage=0;
if(use_fixed_storage(m_Size))
{
// Use fixed storage
Storage=&m_Storage.m_fixSet[0];
}
else
{
// Use dynamic storage
m_Storage.m_dynSet=new set_value_type[m_Size];
Storage=m_Storage.m_dynSet;
}
// Use fixed storage
::std::copy(::boost::begin(Range), ::boost::end(Range), Storage);
::std::sort(Storage, Storage+m_Size);
}
// Copy constructor
is_any_ofF(const is_any_ofF& Other) : m_Size(Other.m_Size)
{
// Prepare storage
m_Storage.m_dynSet=0;
const set_value_type* SrcStorage=0;
set_value_type* DestStorage=0;
if(use_fixed_storage(m_Size))
{
// Use fixed storage
DestStorage=&m_Storage.m_fixSet[0];
SrcStorage=&Other.m_Storage.m_fixSet[0];
}
else
{
// Use dynamic storage
m_Storage.m_dynSet=new set_value_type[m_Size];
DestStorage=m_Storage.m_dynSet;
SrcStorage=Other.m_Storage.m_dynSet;
}
// Use fixed storage
::std::memcpy(DestStorage, SrcStorage, sizeof(set_value_type)*m_Size);
}
// Destructor
~is_any_ofF()
{
if(!use_fixed_storage(m_Size) && m_Storage.m_dynSet!=0)
{
delete [] m_Storage.m_dynSet;
}
}
// Assignment
is_any_ofF& operator=(const is_any_ofF& Other)
{
// Handle self assignment
if(this==&Other) return *this;
// Prepare storage
const set_value_type* SrcStorage;
set_value_type* DestStorage;
if(use_fixed_storage(Other.m_Size))
{
// Use fixed storage
DestStorage=&m_Storage.m_fixSet[0];
SrcStorage=&Other.m_Storage.m_fixSet[0];
// Delete old storage if was present
if(!use_fixed_storage(m_Size) && m_Storage.m_dynSet!=0)
{
delete [] m_Storage.m_dynSet;
}
// Set new size
m_Size=Other.m_Size;
}
else
{
// Other uses dynamic storage
SrcStorage=Other.m_Storage.m_dynSet;
// Check what kind of storage are we using right now
if(use_fixed_storage(m_Size))
{
// Using fixed storage, allocate new
set_value_type* pTemp=new set_value_type[Other.m_Size];
DestStorage=pTemp;
m_Storage.m_dynSet=pTemp;
m_Size=Other.m_Size;
}
else
{
// Using dynamic storage, check if can reuse
if(m_Storage.m_dynSet!=0 && m_Size>=Other.m_Size && m_Size<Other.m_Size*2)
{
// Reuse the current storage
DestStorage=m_Storage.m_dynSet;
m_Size=Other.m_Size;
}
else
{
// Allocate the new one
set_value_type* pTemp=new set_value_type[Other.m_Size];
DestStorage=pTemp;
// Delete old storage if necessary
if(m_Storage.m_dynSet!=0)
{
delete [] m_Storage.m_dynSet;
}
// Store the new storage
m_Storage.m_dynSet=pTemp;
// Set new size
m_Size=Other.m_Size;
}
}
}
// Copy the data
::std::memcpy(DestStorage, SrcStorage, sizeof(set_value_type)*m_Size);
return *this;
}
// Operation
template<typename Char2T>
bool operator()( Char2T Ch ) const
{
const set_value_type* Storage=
(use_fixed_storage(m_Size))
? &m_Storage.m_fixSet[0]
: m_Storage.m_dynSet;
return ::std::binary_search(Storage, Storage+m_Size, Ch);
}
private:
// check if the size is eligible for fixed storage
static bool use_fixed_storage(std::size_t size)
{
return size<=sizeof(set_value_type*)*2;
}
private:
// storage
// The actual used storage is selected on the type
union
{
set_value_type* m_dynSet;
set_value_type m_fixSet[sizeof(set_value_type*)*2];
}
m_Storage;
// storage size
::std::size_t m_Size;
};
// is_from_range functor
/*
returns true if the value is from the specified range.
(i.e. x>=From && x>=To)
*/
template<typename CharT>
struct is_from_rangeF :
public predicate_facade< is_from_rangeF<CharT> >
{
// Boost.ResultOf support
typedef bool result_type;
// Constructor
is_from_rangeF( CharT From, CharT To ) : m_From(From), m_To(To) {}
// Operation
template<typename Char2T>
bool operator()( Char2T Ch ) const
{
return ( m_From <= Ch ) && ( Ch <= m_To );
}
private:
CharT m_From;
CharT m_To;
};
// class_and composition predicate
template<typename Pred1T, typename Pred2T>
struct pred_andF :
public predicate_facade< pred_andF<Pred1T,Pred2T> >
{
public:
// Boost.ResultOf support
typedef bool result_type;
// Constructor
pred_andF( Pred1T Pred1, Pred2T Pred2 ) :
m_Pred1(Pred1), m_Pred2(Pred2) {}
// Operation
template<typename CharT>
bool operator()( CharT Ch ) const
{
return m_Pred1(Ch) && m_Pred2(Ch);
}
private:
Pred1T m_Pred1;
Pred2T m_Pred2;
};
// class_or composition predicate
template<typename Pred1T, typename Pred2T>
struct pred_orF :
public predicate_facade< pred_orF<Pred1T,Pred2T> >
{
public:
// Boost.ResultOf support
typedef bool result_type;
// Constructor
pred_orF( Pred1T Pred1, Pred2T Pred2 ) :
m_Pred1(Pred1), m_Pred2(Pred2) {}
// Operation
template<typename CharT>
bool operator()( CharT Ch ) const
{
return m_Pred1(Ch) || m_Pred2(Ch);
}
private:
Pred1T m_Pred1;
Pred2T m_Pred2;
};
// class_not composition predicate
template< typename PredT >
struct pred_notF :
public predicate_facade< pred_notF<PredT> >
{
public:
// Boost.ResultOf support
typedef bool result_type;
// Constructor
pred_notF( PredT Pred ) : m_Pred(Pred) {}
// Operation
template<typename CharT>
bool operator()( CharT Ch ) const
{
return !m_Pred(Ch);
}
private:
PredT m_Pred;
};
} // namespace detail
} // namespace algorithm
} // namespace boost
#endif // BOOST_STRING_CLASSIFICATION_DETAIL_HPP

View File

@ -0,0 +1,204 @@
// Boost string_algo library find_format.hpp header file ---------------------------//
// Copyright Pavol Droba 2002-2003.
//
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
// See http://www.boost.org/ for updates, documentation, and revision history.
#ifndef BOOST_STRING_FIND_FORMAT_DETAIL_HPP
#define BOOST_STRING_FIND_FORMAT_DETAIL_HPP
#include <boost/algorithm/string/config.hpp>
#include <boost/range/iterator_range_core.hpp>
#include <boost/range/const_iterator.hpp>
#include <boost/range/iterator.hpp>
#include <boost/algorithm/string/detail/find_format_store.hpp>
#include <boost/algorithm/string/detail/replace_storage.hpp>
namespace boost {
namespace algorithm {
namespace detail {
// find_format_copy (iterator variant) implementation -------------------------------//
template<
typename OutputIteratorT,
typename InputT,
typename FormatterT,
typename FindResultT,
typename FormatResultT >
inline OutputIteratorT find_format_copy_impl2(
OutputIteratorT Output,
const InputT& Input,
FormatterT Formatter,
const FindResultT& FindResult,
const FormatResultT& FormatResult )
{
typedef find_format_store<
BOOST_STRING_TYPENAME
range_const_iterator<InputT>::type,
FormatterT,
FormatResultT > store_type;
// Create store for the find result
store_type M( FindResult, FormatResult, Formatter );
if ( !M )
{
// Match not found - return original sequence
Output = std::copy( ::boost::begin(Input), ::boost::end(Input), Output );
return Output;
}
// Copy the beginning of the sequence
Output = std::copy( ::boost::begin(Input), ::boost::begin(M), Output );
// Format find result
// Copy formatted result
Output = std::copy( ::boost::begin(M.format_result()), ::boost::end(M.format_result()), Output );
// Copy the rest of the sequence
Output = std::copy( M.end(), ::boost::end(Input), Output );
return Output;
}
template<
typename OutputIteratorT,
typename InputT,
typename FormatterT,
typename FindResultT >
inline OutputIteratorT find_format_copy_impl(
OutputIteratorT Output,
const InputT& Input,
FormatterT Formatter,
const FindResultT& FindResult )
{
if( ::boost::algorithm::detail::check_find_result(Input, FindResult) ) {
return ::boost::algorithm::detail::find_format_copy_impl2(
Output,
Input,
Formatter,
FindResult,
Formatter(FindResult) );
} else {
return std::copy( ::boost::begin(Input), ::boost::end(Input), Output );
}
}
// find_format_copy implementation --------------------------------------------------//
template<
typename InputT,
typename FormatterT,
typename FindResultT,
typename FormatResultT >
inline InputT find_format_copy_impl2(
const InputT& Input,
FormatterT Formatter,
const FindResultT& FindResult,
const FormatResultT& FormatResult)
{
typedef find_format_store<
BOOST_STRING_TYPENAME
range_const_iterator<InputT>::type,
FormatterT,
FormatResultT > store_type;
// Create store for the find result
store_type M( FindResult, FormatResult, Formatter );
if ( !M )
{
// Match not found - return original sequence
return InputT( Input );
}
InputT Output;
// Copy the beginning of the sequence
boost::algorithm::detail::insert( Output, ::boost::end(Output), ::boost::begin(Input), M.begin() );
// Copy formatted result
boost::algorithm::detail::insert( Output, ::boost::end(Output), M.format_result() );
// Copy the rest of the sequence
boost::algorithm::detail::insert( Output, ::boost::end(Output), M.end(), ::boost::end(Input) );
return Output;
}
template<
typename InputT,
typename FormatterT,
typename FindResultT >
inline InputT find_format_copy_impl(
const InputT& Input,
FormatterT Formatter,
const FindResultT& FindResult)
{
if( ::boost::algorithm::detail::check_find_result(Input, FindResult) ) {
return ::boost::algorithm::detail::find_format_copy_impl2(
Input,
Formatter,
FindResult,
Formatter(FindResult) );
} else {
return Input;
}
}
// replace implementation ----------------------------------------------------//
template<
typename InputT,
typename FormatterT,
typename FindResultT,
typename FormatResultT >
inline void find_format_impl2(
InputT& Input,
FormatterT Formatter,
const FindResultT& FindResult,
const FormatResultT& FormatResult)
{
typedef find_format_store<
BOOST_STRING_TYPENAME
range_iterator<InputT>::type,
FormatterT,
FormatResultT > store_type;
// Create store for the find result
store_type M( FindResult, FormatResult, Formatter );
if ( !M )
{
// Search not found - return original sequence
return;
}
// Replace match
::boost::algorithm::detail::replace( Input, M.begin(), M.end(), M.format_result() );
}
template<
typename InputT,
typename FormatterT,
typename FindResultT >
inline void find_format_impl(
InputT& Input,
FormatterT Formatter,
const FindResultT& FindResult)
{
if( ::boost::algorithm::detail::check_find_result(Input, FindResult) ) {
::boost::algorithm::detail::find_format_impl2(
Input,
Formatter,
FindResult,
Formatter(FindResult) );
}
}
} // namespace detail
} // namespace algorithm
} // namespace boost
#endif // BOOST_STRING_FIND_FORMAT_DETAIL_HPP

View File

@ -0,0 +1,273 @@
// Boost string_algo library find_format_all.hpp header file ---------------------------//
// Copyright Pavol Droba 2002-2003.
//
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
// See http://www.boost.org/ for updates, documentation, and revision history.
#ifndef BOOST_STRING_FIND_FORMAT_ALL_DETAIL_HPP
#define BOOST_STRING_FIND_FORMAT_ALL_DETAIL_HPP
#include <boost/algorithm/string/config.hpp>
#include <boost/range/iterator_range_core.hpp>
#include <boost/range/const_iterator.hpp>
#include <boost/range/value_type.hpp>
#include <boost/algorithm/string/detail/find_format_store.hpp>
#include <boost/algorithm/string/detail/replace_storage.hpp>
namespace boost {
namespace algorithm {
namespace detail {
// find_format_all_copy (iterator variant) implementation ---------------------------//
template<
typename OutputIteratorT,
typename InputT,
typename FinderT,
typename FormatterT,
typename FindResultT,
typename FormatResultT >
inline OutputIteratorT find_format_all_copy_impl2(
OutputIteratorT Output,
const InputT& Input,
FinderT Finder,
FormatterT Formatter,
const FindResultT& FindResult,
const FormatResultT& FormatResult )
{
typedef BOOST_STRING_TYPENAME
range_const_iterator<InputT>::type input_iterator_type;
typedef find_format_store<
input_iterator_type,
FormatterT,
FormatResultT > store_type;
// Create store for the find result
store_type M( FindResult, FormatResult, Formatter );
// Initialize last match
input_iterator_type LastMatch=::boost::begin(Input);
// Iterate through all matches
while( M )
{
// Copy the beginning of the sequence
Output = std::copy( LastMatch, M.begin(), Output );
// Copy formatted result
Output = std::copy( ::boost::begin(M.format_result()), ::boost::end(M.format_result()), Output );
// Proceed to the next match
LastMatch=M.end();
M=Finder( LastMatch, ::boost::end(Input) );
}
// Copy the rest of the sequence
Output = std::copy( LastMatch, ::boost::end(Input), Output );
return Output;
}
template<
typename OutputIteratorT,
typename InputT,
typename FinderT,
typename FormatterT,
typename FindResultT >
inline OutputIteratorT find_format_all_copy_impl(
OutputIteratorT Output,
const InputT& Input,
FinderT Finder,
FormatterT Formatter,
const FindResultT& FindResult )
{
if( ::boost::algorithm::detail::check_find_result(Input, FindResult) ) {
return ::boost::algorithm::detail::find_format_all_copy_impl2(
Output,
Input,
Finder,
Formatter,
FindResult,
Formatter(FindResult) );
} else {
return std::copy( ::boost::begin(Input), ::boost::end(Input), Output );
}
}
// find_format_all_copy implementation ----------------------------------------------//
template<
typename InputT,
typename FinderT,
typename FormatterT,
typename FindResultT,
typename FormatResultT >
inline InputT find_format_all_copy_impl2(
const InputT& Input,
FinderT Finder,
FormatterT Formatter,
const FindResultT& FindResult,
const FormatResultT& FormatResult)
{
typedef BOOST_STRING_TYPENAME
range_const_iterator<InputT>::type input_iterator_type;
typedef find_format_store<
input_iterator_type,
FormatterT,
FormatResultT > store_type;
// Create store for the find result
store_type M( FindResult, FormatResult, Formatter );
// Initialize last match
input_iterator_type LastMatch=::boost::begin(Input);
// Output temporary
InputT Output;
// Iterate through all matches
while( M )
{
// Copy the beginning of the sequence
boost::algorithm::detail::insert( Output, ::boost::end(Output), LastMatch, M.begin() );
// Copy formatted result
boost::algorithm::detail::insert( Output, ::boost::end(Output), M.format_result() );
// Proceed to the next match
LastMatch=M.end();
M=Finder( LastMatch, ::boost::end(Input) );
}
// Copy the rest of the sequence
::boost::algorithm::detail::insert( Output, ::boost::end(Output), LastMatch, ::boost::end(Input) );
return Output;
}
template<
typename InputT,
typename FinderT,
typename FormatterT,
typename FindResultT >
inline InputT find_format_all_copy_impl(
const InputT& Input,
FinderT Finder,
FormatterT Formatter,
const FindResultT& FindResult)
{
if( ::boost::algorithm::detail::check_find_result(Input, FindResult) ) {
return ::boost::algorithm::detail::find_format_all_copy_impl2(
Input,
Finder,
Formatter,
FindResult,
Formatter(FindResult) );
} else {
return Input;
}
}
// find_format_all implementation ------------------------------------------------//
template<
typename InputT,
typename FinderT,
typename FormatterT,
typename FindResultT,
typename FormatResultT >
inline void find_format_all_impl2(
InputT& Input,
FinderT Finder,
FormatterT Formatter,
FindResultT FindResult,
FormatResultT FormatResult)
{
typedef BOOST_STRING_TYPENAME
range_iterator<InputT>::type input_iterator_type;
typedef find_format_store<
input_iterator_type,
FormatterT,
FormatResultT > store_type;
// Create store for the find result
store_type M( FindResult, FormatResult, Formatter );
// Instantiate replacement storage
std::deque<
BOOST_STRING_TYPENAME range_value<InputT>::type> Storage;
// Initialize replacement iterators
input_iterator_type InsertIt=::boost::begin(Input);
input_iterator_type SearchIt=::boost::begin(Input);
while( M )
{
// process the segment
InsertIt=process_segment(
Storage,
Input,
InsertIt,
SearchIt,
M.begin() );
// Adjust search iterator
SearchIt=M.end();
// Copy formatted replace to the storage
::boost::algorithm::detail::copy_to_storage( Storage, M.format_result() );
// Find range for a next match
M=Finder( SearchIt, ::boost::end(Input) );
}
// process the last segment
InsertIt=::boost::algorithm::detail::process_segment(
Storage,
Input,
InsertIt,
SearchIt,
::boost::end(Input) );
if ( Storage.empty() )
{
// Truncate input
::boost::algorithm::detail::erase( Input, InsertIt, ::boost::end(Input) );
}
else
{
// Copy remaining data to the end of input
::boost::algorithm::detail::insert( Input, ::boost::end(Input), Storage.begin(), Storage.end() );
}
}
template<
typename InputT,
typename FinderT,
typename FormatterT,
typename FindResultT >
inline void find_format_all_impl(
InputT& Input,
FinderT Finder,
FormatterT Formatter,
FindResultT FindResult)
{
if( ::boost::algorithm::detail::check_find_result(Input, FindResult) ) {
::boost::algorithm::detail::find_format_all_impl2(
Input,
Finder,
Formatter,
FindResult,
Formatter(FindResult) );
}
}
} // namespace detail
} // namespace algorithm
} // namespace boost
#endif // BOOST_STRING_FIND_FORMAT_ALL_DETAIL_HPP

View File

@ -0,0 +1,89 @@
// Boost string_algo library find_format_store.hpp header file ---------------------------//
// Copyright Pavol Droba 2002-2003.
//
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
// See http://www.boost.org/ for updates, documentation, and revision history.
#ifndef BOOST_STRING_FIND_FORMAT_STORE_DETAIL_HPP
#define BOOST_STRING_FIND_FORMAT_STORE_DETAIL_HPP
#include <boost/algorithm/string/config.hpp>
#include <boost/range/iterator_range_core.hpp>
namespace boost {
namespace algorithm {
namespace detail {
// temporary format and find result storage --------------------------------//
#if BOOST_WORKAROUND(BOOST_MSVC, >= 1400)
#pragma warning(push)
#pragma warning(disable:4512) //assignment operator could not be generated
#endif
template<
typename ForwardIteratorT,
typename FormatterT,
typename FormatResultT >
class find_format_store :
public iterator_range<ForwardIteratorT>
{
public:
// typedefs
typedef iterator_range<ForwardIteratorT> base_type;
typedef FormatterT formatter_type;
typedef FormatResultT format_result_type;
public:
// Construction
find_format_store(
const base_type& FindResult,
const format_result_type& FormatResult,
const formatter_type& Formatter ) :
base_type(FindResult),
m_FormatResult(FormatResult),
m_Formatter(Formatter) {}
// Assignment
template< typename FindResultT >
find_format_store& operator=( FindResultT FindResult )
{
iterator_range<ForwardIteratorT>::operator=(FindResult);
if( !this->empty() ) {
m_FormatResult=m_Formatter(FindResult);
}
return *this;
}
// Retrieve format result
const format_result_type& format_result()
{
return m_FormatResult;
}
private:
format_result_type m_FormatResult;
const formatter_type& m_Formatter;
};
template<typename InputT, typename FindResultT>
bool check_find_result(InputT&, FindResultT& FindResult)
{
typedef BOOST_STRING_TYPENAME
range_const_iterator<InputT>::type input_iterator_type;
iterator_range<input_iterator_type> ResultRange(FindResult);
return !ResultRange.empty();
}
#if BOOST_WORKAROUND(BOOST_MSVC, >= 1400)
#pragma warning(pop)
#endif
} // namespace detail
} // namespace algorithm
} // namespace boost
#endif // BOOST_STRING_FIND_FORMAT_STORE_DETAIL_HPP

View File

@ -0,0 +1,87 @@
// Boost string_algo library find_iterator.hpp header file ---------------------------//
// Copyright Pavol Droba 2002-2003.
//
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
// See http://www.boost.org/ for updates, documentation, and revision history.
#ifndef BOOST_STRING_FIND_ITERATOR_DETAIL_HPP
#define BOOST_STRING_FIND_ITERATOR_DETAIL_HPP
#include <boost/algorithm/string/config.hpp>
#include <boost/range/iterator_range_core.hpp>
#include <boost/iterator/iterator_facade.hpp>
#include <boost/iterator/iterator_categories.hpp>
#include <boost/function.hpp>
namespace boost {
namespace algorithm {
namespace detail {
// find_iterator base -----------------------------------------------//
// Find iterator base
template<typename IteratorT>
class find_iterator_base
{
protected:
// typedefs
typedef IteratorT input_iterator_type;
typedef iterator_range<IteratorT> match_type;
typedef function2<
match_type,
input_iterator_type,
input_iterator_type> finder_type;
protected:
// Protected construction/destruction
// Default constructor
find_iterator_base() {};
// Copy construction
find_iterator_base( const find_iterator_base& Other ) :
m_Finder(Other.m_Finder) {}
// Constructor
template<typename FinderT>
find_iterator_base( FinderT Finder, int ) :
m_Finder(Finder) {}
// Destructor
~find_iterator_base() {}
// Find operation
match_type do_find(
input_iterator_type Begin,
input_iterator_type End ) const
{
if (!m_Finder.empty())
{
return m_Finder(Begin,End);
}
else
{
return match_type(End,End);
}
}
// Check
bool is_null() const
{
return m_Finder.empty();
}
private:
// Finder
finder_type m_Finder;
};
} // namespace detail
} // namespace algorithm
} // namespace boost
#endif // BOOST_STRING_FIND_ITERATOR_DETAIL_HPP

View File

@ -0,0 +1,639 @@
// Boost string_algo library finder.hpp header file ---------------------------//
// Copyright Pavol Droba 2002-2006.
//
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
// See http://www.boost.org/ for updates, documentation, and revision history.
#ifndef BOOST_STRING_FINDER_DETAIL_HPP
#define BOOST_STRING_FINDER_DETAIL_HPP
#include <boost/algorithm/string/config.hpp>
#include <boost/algorithm/string/constants.hpp>
#include <boost/detail/iterator.hpp>
#include <boost/range/iterator_range_core.hpp>
#include <boost/range/begin.hpp>
#include <boost/range/end.hpp>
#include <boost/range/empty.hpp>
#include <boost/range/as_literal.hpp>
namespace boost {
namespace algorithm {
namespace detail {
// find first functor -----------------------------------------------//
// find a subsequence in the sequence ( functor )
/*
Returns a pair <begin,end> marking the subsequence in the sequence.
If the find fails, functor returns <End,End>
*/
template<typename SearchIteratorT,typename PredicateT>
struct first_finderF
{
typedef SearchIteratorT search_iterator_type;
// Construction
template< typename SearchT >
first_finderF( const SearchT& Search, PredicateT Comp ) :
m_Search(::boost::begin(Search), ::boost::end(Search)), m_Comp(Comp) {}
first_finderF(
search_iterator_type SearchBegin,
search_iterator_type SearchEnd,
PredicateT Comp ) :
m_Search(SearchBegin, SearchEnd), m_Comp(Comp) {}
// Operation
template< typename ForwardIteratorT >
iterator_range<ForwardIteratorT>
operator()(
ForwardIteratorT Begin,
ForwardIteratorT End ) const
{
typedef iterator_range<ForwardIteratorT> result_type;
typedef ForwardIteratorT input_iterator_type;
// Outer loop
for(input_iterator_type OuterIt=Begin;
OuterIt!=End;
++OuterIt)
{
// Sanity check
if( boost::empty(m_Search) )
return result_type( End, End );
input_iterator_type InnerIt=OuterIt;
search_iterator_type SubstrIt=m_Search.begin();
for(;
InnerIt!=End && SubstrIt!=m_Search.end();
++InnerIt,++SubstrIt)
{
if( !( m_Comp(*InnerIt,*SubstrIt) ) )
break;
}
// Substring matching succeeded
if ( SubstrIt==m_Search.end() )
return result_type( OuterIt, InnerIt );
}
return result_type( End, End );
}
private:
iterator_range<search_iterator_type> m_Search;
PredicateT m_Comp;
};
// find last functor -----------------------------------------------//
// find the last match a subsequence in the sequence ( functor )
/*
Returns a pair <begin,end> marking the subsequence in the sequence.
If the find fails, returns <End,End>
*/
template<typename SearchIteratorT, typename PredicateT>
struct last_finderF
{
typedef SearchIteratorT search_iterator_type;
typedef first_finderF<
search_iterator_type,
PredicateT> first_finder_type;
// Construction
template< typename SearchT >
last_finderF( const SearchT& Search, PredicateT Comp ) :
m_Search(::boost::begin(Search), ::boost::end(Search)), m_Comp(Comp) {}
last_finderF(
search_iterator_type SearchBegin,
search_iterator_type SearchEnd,
PredicateT Comp ) :
m_Search(SearchBegin, SearchEnd), m_Comp(Comp) {}
// Operation
template< typename ForwardIteratorT >
iterator_range<ForwardIteratorT>
operator()(
ForwardIteratorT Begin,
ForwardIteratorT End ) const
{
typedef iterator_range<ForwardIteratorT> result_type;
if( boost::empty(m_Search) )
return result_type( End, End );
typedef BOOST_STRING_TYPENAME boost::detail::
iterator_traits<ForwardIteratorT>::iterator_category category;
return findit( Begin, End, category() );
}
private:
// forward iterator
template< typename ForwardIteratorT >
iterator_range<ForwardIteratorT>
findit(
ForwardIteratorT Begin,
ForwardIteratorT End,
std::forward_iterator_tag ) const
{
typedef iterator_range<ForwardIteratorT> result_type;
first_finder_type first_finder(
m_Search.begin(), m_Search.end(), m_Comp );
result_type M=first_finder( Begin, End );
result_type Last=M;
while( M )
{
Last=M;
M=first_finder( ::boost::end(M), End );
}
return Last;
}
// bidirectional iterator
template< typename ForwardIteratorT >
iterator_range<ForwardIteratorT>
findit(
ForwardIteratorT Begin,
ForwardIteratorT End,
std::bidirectional_iterator_tag ) const
{
typedef iterator_range<ForwardIteratorT> result_type;
typedef ForwardIteratorT input_iterator_type;
// Outer loop
for(input_iterator_type OuterIt=End;
OuterIt!=Begin; )
{
input_iterator_type OuterIt2=--OuterIt;
input_iterator_type InnerIt=OuterIt2;
search_iterator_type SubstrIt=m_Search.begin();
for(;
InnerIt!=End && SubstrIt!=m_Search.end();
++InnerIt,++SubstrIt)
{
if( !( m_Comp(*InnerIt,*SubstrIt) ) )
break;
}
// Substring matching succeeded
if( SubstrIt==m_Search.end() )
return result_type( OuterIt2, InnerIt );
}
return result_type( End, End );
}
private:
iterator_range<search_iterator_type> m_Search;
PredicateT m_Comp;
};
// find n-th functor -----------------------------------------------//
// find the n-th match of a subsequence in the sequence ( functor )
/*
Returns a pair <begin,end> marking the subsequence in the sequence.
If the find fails, returns <End,End>
*/
template<typename SearchIteratorT, typename PredicateT>
struct nth_finderF
{
typedef SearchIteratorT search_iterator_type;
typedef first_finderF<
search_iterator_type,
PredicateT> first_finder_type;
typedef last_finderF<
search_iterator_type,
PredicateT> last_finder_type;
// Construction
template< typename SearchT >
nth_finderF(
const SearchT& Search,
int Nth,
PredicateT Comp) :
m_Search(::boost::begin(Search), ::boost::end(Search)),
m_Nth(Nth),
m_Comp(Comp) {}
nth_finderF(
search_iterator_type SearchBegin,
search_iterator_type SearchEnd,
int Nth,
PredicateT Comp) :
m_Search(SearchBegin, SearchEnd),
m_Nth(Nth),
m_Comp(Comp) {}
// Operation
template< typename ForwardIteratorT >
iterator_range<ForwardIteratorT>
operator()(
ForwardIteratorT Begin,
ForwardIteratorT End ) const
{
if(m_Nth>=0)
{
return find_forward(Begin, End, m_Nth);
}
else
{
return find_backward(Begin, End, -m_Nth);
}
}
private:
// Implementation helpers
template< typename ForwardIteratorT >
iterator_range<ForwardIteratorT>
find_forward(
ForwardIteratorT Begin,
ForwardIteratorT End,
unsigned int N) const
{
typedef iterator_range<ForwardIteratorT> result_type;
// Sanity check
if( boost::empty(m_Search) )
return result_type( End, End );
// Instantiate find functor
first_finder_type first_finder(
m_Search.begin(), m_Search.end(), m_Comp );
result_type M( Begin, Begin );
for( unsigned int n=0; n<=N; ++n )
{
// find next match
M=first_finder( ::boost::end(M), End );
if ( !M )
{
// Subsequence not found, return
return M;
}
}
return M;
}
template< typename ForwardIteratorT >
iterator_range<ForwardIteratorT>
find_backward(
ForwardIteratorT Begin,
ForwardIteratorT End,
unsigned int N) const
{
typedef iterator_range<ForwardIteratorT> result_type;
// Sanity check
if( boost::empty(m_Search) )
return result_type( End, End );
// Instantiate find functor
last_finder_type last_finder(
m_Search.begin(), m_Search.end(), m_Comp );
result_type M( End, End );
for( unsigned int n=1; n<=N; ++n )
{
// find next match
M=last_finder( Begin, ::boost::begin(M) );
if ( !M )
{
// Subsequence not found, return
return M;
}
}
return M;
}
private:
iterator_range<search_iterator_type> m_Search;
int m_Nth;
PredicateT m_Comp;
};
// find head/tail implementation helpers ---------------------------//
template<typename ForwardIteratorT>
iterator_range<ForwardIteratorT>
find_head_impl(
ForwardIteratorT Begin,
ForwardIteratorT End,
unsigned int N,
std::forward_iterator_tag )
{
typedef ForwardIteratorT input_iterator_type;
typedef iterator_range<ForwardIteratorT> result_type;
input_iterator_type It=Begin;
for(
unsigned int Index=0;
Index<N && It!=End; ++Index,++It ) {};
return result_type( Begin, It );
}
template< typename ForwardIteratorT >
iterator_range<ForwardIteratorT>
find_head_impl(
ForwardIteratorT Begin,
ForwardIteratorT End,
unsigned int N,
std::random_access_iterator_tag )
{
typedef iterator_range<ForwardIteratorT> result_type;
if ( (End<=Begin) || ( static_cast<unsigned int>(End-Begin) < N ) )
return result_type( Begin, End );
return result_type(Begin,Begin+N);
}
// Find head implementation
template<typename ForwardIteratorT>
iterator_range<ForwardIteratorT>
find_head_impl(
ForwardIteratorT Begin,
ForwardIteratorT End,
unsigned int N )
{
typedef BOOST_STRING_TYPENAME boost::detail::
iterator_traits<ForwardIteratorT>::iterator_category category;
return ::boost::algorithm::detail::find_head_impl( Begin, End, N, category() );
}
template< typename ForwardIteratorT >
iterator_range<ForwardIteratorT>
find_tail_impl(
ForwardIteratorT Begin,
ForwardIteratorT End,
unsigned int N,
std::forward_iterator_tag )
{
typedef ForwardIteratorT input_iterator_type;
typedef iterator_range<ForwardIteratorT> result_type;
unsigned int Index=0;
input_iterator_type It=Begin;
input_iterator_type It2=Begin;
// Advance It2 by N increments
for( Index=0; Index<N && It2!=End; ++Index,++It2 ) {};
// Advance It, It2 to the end
for(; It2!=End; ++It,++It2 ) {};
return result_type( It, It2 );
}
template< typename ForwardIteratorT >
iterator_range<ForwardIteratorT>
find_tail_impl(
ForwardIteratorT Begin,
ForwardIteratorT End,
unsigned int N,
std::bidirectional_iterator_tag )
{
typedef ForwardIteratorT input_iterator_type;
typedef iterator_range<ForwardIteratorT> result_type;
input_iterator_type It=End;
for(
unsigned int Index=0;
Index<N && It!=Begin; ++Index,--It ) {};
return result_type( It, End );
}
template< typename ForwardIteratorT >
iterator_range<ForwardIteratorT>
find_tail_impl(
ForwardIteratorT Begin,
ForwardIteratorT End,
unsigned int N,
std::random_access_iterator_tag )
{
typedef iterator_range<ForwardIteratorT> result_type;
if ( (End<=Begin) || ( static_cast<unsigned int>(End-Begin) < N ) )
return result_type( Begin, End );
return result_type( End-N, End );
}
// Operation
template< typename ForwardIteratorT >
iterator_range<ForwardIteratorT>
find_tail_impl(
ForwardIteratorT Begin,
ForwardIteratorT End,
unsigned int N )
{
typedef BOOST_STRING_TYPENAME boost::detail::
iterator_traits<ForwardIteratorT>::iterator_category category;
return ::boost::algorithm::detail::find_tail_impl( Begin, End, N, category() );
}
// find head functor -----------------------------------------------//
// find a head in the sequence ( functor )
/*
This functor find a head of the specified range. For
a specified N, the head is a subsequence of N starting
elements of the range.
*/
struct head_finderF
{
// Construction
head_finderF( int N ) : m_N(N) {}
// Operation
template< typename ForwardIteratorT >
iterator_range<ForwardIteratorT>
operator()(
ForwardIteratorT Begin,
ForwardIteratorT End ) const
{
if(m_N>=0)
{
return ::boost::algorithm::detail::find_head_impl( Begin, End, m_N );
}
else
{
iterator_range<ForwardIteratorT> Res=
::boost::algorithm::detail::find_tail_impl( Begin, End, -m_N );
return ::boost::make_iterator_range(Begin, Res.begin());
}
}
private:
int m_N;
};
// find tail functor -----------------------------------------------//
// find a tail in the sequence ( functor )
/*
This functor find a tail of the specified range. For
a specified N, the head is a subsequence of N starting
elements of the range.
*/
struct tail_finderF
{
// Construction
tail_finderF( int N ) : m_N(N) {}
// Operation
template< typename ForwardIteratorT >
iterator_range<ForwardIteratorT>
operator()(
ForwardIteratorT Begin,
ForwardIteratorT End ) const
{
if(m_N>=0)
{
return ::boost::algorithm::detail::find_tail_impl( Begin, End, m_N );
}
else
{
iterator_range<ForwardIteratorT> Res=
::boost::algorithm::detail::find_head_impl( Begin, End, -m_N );
return ::boost::make_iterator_range(Res.end(), End);
}
}
private:
int m_N;
};
// find token functor -----------------------------------------------//
// find a token in a sequence ( functor )
/*
This find functor finds a token specified be a predicate
in a sequence. It is equivalent of std::find algorithm,
with an exception that it return range instead of a single
iterator.
If bCompress is set to true, adjacent matching tokens are
concatenated into one match.
*/
template< typename PredicateT >
struct token_finderF
{
// Construction
token_finderF(
PredicateT Pred,
token_compress_mode_type eCompress=token_compress_off ) :
m_Pred(Pred), m_eCompress(eCompress) {}
// Operation
template< typename ForwardIteratorT >
iterator_range<ForwardIteratorT>
operator()(
ForwardIteratorT Begin,
ForwardIteratorT End ) const
{
typedef iterator_range<ForwardIteratorT> result_type;
ForwardIteratorT It=std::find_if( Begin, End, m_Pred );
if( It==End )
{
return result_type( End, End );
}
else
{
ForwardIteratorT It2=It;
if( m_eCompress==token_compress_on )
{
// Find first non-matching character
while( It2!=End && m_Pred(*It2) ) ++It2;
}
else
{
// Advance by one position
++It2;
}
return result_type( It, It2 );
}
}
private:
PredicateT m_Pred;
token_compress_mode_type m_eCompress;
};
// find range functor -----------------------------------------------//
// find a range in the sequence ( functor )
/*
This functor actually does not perform any find operation.
It always returns given iterator range as a result.
*/
template<typename ForwardIterator1T>
struct range_finderF
{
typedef ForwardIterator1T input_iterator_type;
typedef iterator_range<input_iterator_type> result_type;
// Construction
range_finderF(
input_iterator_type Begin,
input_iterator_type End ) : m_Range(Begin, End) {}
range_finderF(const iterator_range<input_iterator_type>& Range) :
m_Range(Range) {}
// Operation
template< typename ForwardIterator2T >
iterator_range<ForwardIterator2T>
operator()(
ForwardIterator2T,
ForwardIterator2T ) const
{
#if BOOST_WORKAROUND( __MWERKS__, <= 0x3003 )
return iterator_range<const ForwardIterator2T>(this->m_Range);
#else
return m_Range;
#endif
}
private:
iterator_range<input_iterator_type> m_Range;
};
} // namespace detail
} // namespace algorithm
} // namespace boost
#endif // BOOST_STRING_FINDER_DETAIL_HPP

View File

@ -0,0 +1,122 @@
// Boost string_algo library find_regex.hpp header file ---------------------------//
// Copyright Pavol Droba 2002-2003.
//
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
// See http://www.boost.org/ for updates, documentation, and revision history.
#ifndef BOOST_STRING_FINDER_REGEX_DETAIL_HPP
#define BOOST_STRING_FINDER_REGEX_DETAIL_HPP
#include <boost/algorithm/string/config.hpp>
#include <boost/regex.hpp>
#include <boost/range/iterator_range_core.hpp>
#include <boost/range/begin.hpp>
#include <boost/range/end.hpp>
namespace boost {
namespace algorithm {
namespace detail {
// regex find functor -----------------------------------------------//
// regex search result
template<typename IteratorT>
struct regex_search_result :
public iterator_range<IteratorT>
{
typedef regex_search_result<IteratorT> type;
typedef iterator_range<IteratorT> base_type;
typedef BOOST_STRING_TYPENAME base_type::value_type value_type;
typedef BOOST_STRING_TYPENAME base_type::difference_type difference_type;
typedef BOOST_STRING_TYPENAME base_type::const_iterator const_iterator;
typedef BOOST_STRING_TYPENAME base_type::iterator iterator;
typedef boost::match_results<iterator> match_results_type;
// Construction
// Construction from the match result
regex_search_result( const match_results_type& MatchResults ) :
base_type( MatchResults[0].first, MatchResults[0].second ),
m_MatchResults( MatchResults ) {}
// Construction of empty match. End iterator has to be specified
regex_search_result( IteratorT End ) :
base_type( End, End ) {}
regex_search_result( const regex_search_result& Other ) :
base_type( Other.begin(), Other.end() ),
m_MatchResults( Other.m_MatchResults ) {}
// Assignment
regex_search_result& operator=( const regex_search_result& Other )
{
base_type::operator=( Other );
m_MatchResults=Other.m_MatchResults;
return *this;
}
// Match result retrieval
const match_results_type& match_results() const
{
return m_MatchResults;
}
private:
// Saved match result
match_results_type m_MatchResults;
};
// find_regex
/*
Regex based search functor
*/
template<typename RegExT>
struct find_regexF
{
typedef RegExT regex_type;
typedef const RegExT& regex_reference_type;
// Construction
find_regexF( regex_reference_type Rx, match_flag_type MatchFlags = match_default ) :
m_Rx(Rx), m_MatchFlags(MatchFlags) {}
// Operation
template< typename ForwardIteratorT >
regex_search_result<ForwardIteratorT>
operator()(
ForwardIteratorT Begin,
ForwardIteratorT End ) const
{
typedef ForwardIteratorT input_iterator_type;
typedef regex_search_result<ForwardIteratorT> result_type;
// instantiate match result
match_results<input_iterator_type> result;
// search for a match
if ( ::boost::regex_search( Begin, End, result, m_Rx, m_MatchFlags ) )
{
// construct a result
return result_type( result );
}
else
{
// empty result
return result_type( End );
}
}
private:
regex_reference_type m_Rx; // Regexp
match_flag_type m_MatchFlags; // match flags
};
} // namespace detail
} // namespace algorithm
} // namespace boost
#endif // BOOST_STRING_FIND_DETAIL_HPP

View File

@ -0,0 +1,119 @@
// Boost string_algo library formatter.hpp header file ---------------------------//
// Copyright Pavol Droba 2002-2003.
//
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
// See http://www.boost.org for updates, documentation, and revision history.
#ifndef BOOST_STRING_FORMATTER_DETAIL_HPP
#define BOOST_STRING_FORMATTER_DETAIL_HPP
#include <boost/range/iterator_range_core.hpp>
#include <boost/range/begin.hpp>
#include <boost/range/end.hpp>
#include <boost/range/const_iterator.hpp>
#include <boost/algorithm/string/detail/util.hpp>
// generic replace functors -----------------------------------------------//
namespace boost {
namespace algorithm {
namespace detail {
// const format functor ----------------------------------------------------//
// constant format functor
template<typename RangeT>
struct const_formatF
{
private:
typedef BOOST_STRING_TYPENAME
range_const_iterator<RangeT>::type format_iterator;
typedef iterator_range<format_iterator> result_type;
public:
// Construction
const_formatF(const RangeT& Format) :
m_Format(::boost::begin(Format), ::boost::end(Format)) {}
// Operation
#if BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x564))
template<typename Range2T>
result_type& operator()(const Range2T&)
{
return m_Format;
}
#endif
template<typename Range2T>
const result_type& operator()(const Range2T&) const
{
return m_Format;
}
private:
result_type m_Format;
};
// identity format functor ----------------------------------------------------//
// identity format functor
template<typename RangeT>
struct identity_formatF
{
// Operation
template< typename Range2T >
const RangeT& operator()(const Range2T& Replace) const
{
return RangeT(::boost::begin(Replace), ::boost::end(Replace));
}
};
// empty format functor ( used by erase ) ------------------------------------//
// empty format functor
template< typename CharT >
struct empty_formatF
{
template< typename ReplaceT >
empty_container<CharT> operator()(const ReplaceT&) const
{
return empty_container<CharT>();
}
};
// dissect format functor ----------------------------------------------------//
// dissect format functor
template<typename FinderT>
struct dissect_formatF
{
public:
// Construction
dissect_formatF(FinderT Finder) :
m_Finder(Finder) {}
// Operation
template<typename RangeT>
inline iterator_range<
BOOST_STRING_TYPENAME range_const_iterator<RangeT>::type>
operator()(const RangeT& Replace) const
{
return m_Finder(::boost::begin(Replace), ::boost::end(Replace));
}
private:
FinderT m_Finder;
};
} // namespace detail
} // namespace algorithm
} // namespace boost
#endif // BOOST_STRING_FORMATTER_DETAIL_HPP

View File

@ -0,0 +1,61 @@
// Boost string_algo library formatter_regex.hpp header file ---------------------------//
// Copyright Pavol Droba 2002-2003.
//
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
// See http://www.boost.org/ for updates, documentation, and revision history.
#ifndef BOOST_STRING_FORMATTER_REGEX_DETAIL_HPP
#define BOOST_STRING_FORMATTER_REGEX_DETAIL_HPP
#include <boost/algorithm/string/config.hpp>
#include <string>
#include <boost/regex.hpp>
#include <boost/algorithm/string/detail/finder_regex.hpp>
namespace boost {
namespace algorithm {
namespace detail {
// regex format functor -----------------------------------------//
// regex format functor
template<typename StringT>
struct regex_formatF
{
private:
typedef StringT result_type;
typedef BOOST_STRING_TYPENAME StringT::value_type char_type;
public:
// Construction
regex_formatF( const StringT& Fmt, match_flag_type Flags=format_default ) :
m_Fmt(Fmt), m_Flags( Flags ) {}
template<typename InputIteratorT>
result_type operator()(
const regex_search_result<InputIteratorT>& Replace ) const
{
if ( Replace.empty() )
{
return result_type();
}
else
{
return Replace.match_results().format( m_Fmt, m_Flags );
}
}
private:
const StringT& m_Fmt;
match_flag_type m_Flags;
};
} // namespace detail
} // namespace algorithm
} // namespace boost
#endif // BOOST_STRING_FORMATTER_DETAIL_HPP

View File

@ -0,0 +1,77 @@
// Boost string_algo library predicate.hpp header file ---------------------------//
// Copyright Pavol Droba 2002-2003.
//
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
// See http://www.boost.org/ for updates, documentation, and revision history.
#ifndef BOOST_STRING_PREDICATE_DETAIL_HPP
#define BOOST_STRING_PREDICATE_DETAIL_HPP
#include <iterator>
#include <boost/algorithm/string/find.hpp>
namespace boost {
namespace algorithm {
namespace detail {
// ends_with predicate implementation ----------------------------------//
template<
typename ForwardIterator1T,
typename ForwardIterator2T,
typename PredicateT>
inline bool ends_with_iter_select(
ForwardIterator1T Begin,
ForwardIterator1T End,
ForwardIterator2T SubBegin,
ForwardIterator2T SubEnd,
PredicateT Comp,
std::bidirectional_iterator_tag)
{
ForwardIterator1T it=End;
ForwardIterator2T pit=SubEnd;
for(;it!=Begin && pit!=SubBegin;)
{
if( !(Comp(*(--it),*(--pit))) )
return false;
}
return pit==SubBegin;
}
template<
typename ForwardIterator1T,
typename ForwardIterator2T,
typename PredicateT>
inline bool ends_with_iter_select(
ForwardIterator1T Begin,
ForwardIterator1T End,
ForwardIterator2T SubBegin,
ForwardIterator2T SubEnd,
PredicateT Comp,
std::forward_iterator_tag)
{
if ( SubBegin==SubEnd )
{
// empty subsequence check
return true;
}
iterator_range<ForwardIterator1T> Result
=last_finder(
::boost::make_iterator_range(SubBegin, SubEnd),
Comp)(Begin, End);
return !Result.empty() && Result.end()==End;
}
} // namespace detail
} // namespace algorithm
} // namespace boost
#endif // BOOST_STRING_PREDICATE_DETAIL_HPP

View File

@ -0,0 +1,159 @@
// Boost string_algo library replace_storage.hpp header file ---------------------------//
// Copyright Pavol Droba 2002-2003.
//
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
// See http://www.boost.org/ for updates, documentation, and revision history.
#ifndef BOOST_STRING_REPLACE_STORAGE_DETAIL_HPP
#define BOOST_STRING_REPLACE_STORAGE_DETAIL_HPP
#include <boost/algorithm/string/config.hpp>
#include <algorithm>
#include <boost/mpl/bool.hpp>
#include <boost/algorithm/string/sequence_traits.hpp>
#include <boost/algorithm/string/detail/sequence.hpp>
namespace boost {
namespace algorithm {
namespace detail {
// storage handling routines -----------------------------------------------//
template< typename StorageT, typename OutputIteratorT >
inline OutputIteratorT move_from_storage(
StorageT& Storage,
OutputIteratorT DestBegin,
OutputIteratorT DestEnd )
{
OutputIteratorT OutputIt=DestBegin;
while( !Storage.empty() && OutputIt!=DestEnd )
{
*OutputIt=Storage.front();
Storage.pop_front();
++OutputIt;
}
return OutputIt;
}
template< typename StorageT, typename WhatT >
inline void copy_to_storage(
StorageT& Storage,
const WhatT& What )
{
Storage.insert( Storage.end(), ::boost::begin(What), ::boost::end(What) );
}
// process segment routine -----------------------------------------------//
template< bool HasStableIterators >
struct process_segment_helper
{
// Optimized version of process_segment for generic sequence
template<
typename StorageT,
typename InputT,
typename ForwardIteratorT >
ForwardIteratorT operator()(
StorageT& Storage,
InputT& /*Input*/,
ForwardIteratorT InsertIt,
ForwardIteratorT SegmentBegin,
ForwardIteratorT SegmentEnd )
{
// Copy data from the storage until the beginning of the segment
ForwardIteratorT It=::boost::algorithm::detail::move_from_storage( Storage, InsertIt, SegmentBegin );
// 3 cases are possible :
// a) Storage is empty, It==SegmentBegin
// b) Storage is empty, It!=SegmentBegin
// c) Storage is not empty
if( Storage.empty() )
{
if( It==SegmentBegin )
{
// Case a) everything is grand, just return end of segment
return SegmentEnd;
}
else
{
// Case b) move the segment backwards
return std::copy( SegmentBegin, SegmentEnd, It );
}
}
else
{
// Case c) -> shift the segment to the left and keep the overlap in the storage
while( It!=SegmentEnd )
{
// Store value into storage
Storage.push_back( *It );
// Get the top from the storage and put it here
*It=Storage.front();
Storage.pop_front();
// Advance
++It;
}
return It;
}
}
};
template<>
struct process_segment_helper< true >
{
// Optimized version of process_segment for list-like sequence
template<
typename StorageT,
typename InputT,
typename ForwardIteratorT >
ForwardIteratorT operator()(
StorageT& Storage,
InputT& Input,
ForwardIteratorT InsertIt,
ForwardIteratorT SegmentBegin,
ForwardIteratorT SegmentEnd )
{
// Call replace to do the job
::boost::algorithm::detail::replace( Input, InsertIt, SegmentBegin, Storage );
// Empty the storage
Storage.clear();
// Iterators were not changed, simply return the end of segment
return SegmentEnd;
}
};
// Process one segment in the replace_all algorithm
template<
typename StorageT,
typename InputT,
typename ForwardIteratorT >
inline ForwardIteratorT process_segment(
StorageT& Storage,
InputT& Input,
ForwardIteratorT InsertIt,
ForwardIteratorT SegmentBegin,
ForwardIteratorT SegmentEnd )
{
return
process_segment_helper<
has_stable_iterators<InputT>::value>()(
Storage, Input, InsertIt, SegmentBegin, SegmentEnd );
}
} // namespace detail
} // namespace algorithm
} // namespace boost
#endif // BOOST_STRING_REPLACE_STORAGE_DETAIL_HPP

View File

@ -0,0 +1,200 @@
// Boost string_algo library sequence.hpp header file ---------------------------//
// Copyright Pavol Droba 2002-2003.
//
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
// See http://www.boost.org/ for updates, documentation, and revision history.
#ifndef BOOST_STRING_DETAIL_SEQUENCE_HPP
#define BOOST_STRING_DETAIL_SEQUENCE_HPP
#include <boost/algorithm/string/config.hpp>
#include <boost/mpl/bool.hpp>
#include <boost/mpl/logical.hpp>
#include <boost/range/begin.hpp>
#include <boost/range/end.hpp>
#include <boost/algorithm/string/sequence_traits.hpp>
namespace boost {
namespace algorithm {
namespace detail {
// insert helpers -------------------------------------------------//
template< typename InputT, typename ForwardIteratorT >
inline void insert(
InputT& Input,
BOOST_STRING_TYPENAME InputT::iterator At,
ForwardIteratorT Begin,
ForwardIteratorT End )
{
Input.insert( At, Begin, End );
}
template< typename InputT, typename InsertT >
inline void insert(
InputT& Input,
BOOST_STRING_TYPENAME InputT::iterator At,
const InsertT& Insert )
{
::boost::algorithm::detail::insert( Input, At, ::boost::begin(Insert), ::boost::end(Insert) );
}
// erase helper ---------------------------------------------------//
// Erase a range in the sequence
/*
Returns the iterator pointing just after the erase subrange
*/
template< typename InputT >
inline typename InputT::iterator erase(
InputT& Input,
BOOST_STRING_TYPENAME InputT::iterator From,
BOOST_STRING_TYPENAME InputT::iterator To )
{
return Input.erase( From, To );
}
// replace helper implementation ----------------------------------//
// Optimized version of replace for generic sequence containers
// Assumption: insert and erase are expensive
template< bool HasConstTimeOperations >
struct replace_const_time_helper
{
template< typename InputT, typename ForwardIteratorT >
void operator()(
InputT& Input,
BOOST_STRING_TYPENAME InputT::iterator From,
BOOST_STRING_TYPENAME InputT::iterator To,
ForwardIteratorT Begin,
ForwardIteratorT End )
{
// Copy data to the container ( as much as possible )
ForwardIteratorT InsertIt=Begin;
BOOST_STRING_TYPENAME InputT::iterator InputIt=From;
for(; InsertIt!=End && InputIt!=To; InsertIt++, InputIt++ )
{
*InputIt=*InsertIt;
}
if ( InsertIt!=End )
{
// Replace sequence is longer, insert it
Input.insert( InputIt, InsertIt, End );
}
else
{
if ( InputIt!=To )
{
// Replace sequence is shorter, erase the rest
Input.erase( InputIt, To );
}
}
}
};
template<>
struct replace_const_time_helper< true >
{
// Const-time erase and insert methods -> use them
template< typename InputT, typename ForwardIteratorT >
void operator()(
InputT& Input,
BOOST_STRING_TYPENAME InputT::iterator From,
BOOST_STRING_TYPENAME InputT::iterator To,
ForwardIteratorT Begin,
ForwardIteratorT End )
{
BOOST_STRING_TYPENAME InputT::iterator At=Input.erase( From, To );
if ( Begin!=End )
{
if(!Input.empty())
{
Input.insert( At, Begin, End );
}
else
{
Input.insert( Input.begin(), Begin, End );
}
}
}
};
// No native replace method
template< bool HasNative >
struct replace_native_helper
{
template< typename InputT, typename ForwardIteratorT >
void operator()(
InputT& Input,
BOOST_STRING_TYPENAME InputT::iterator From,
BOOST_STRING_TYPENAME InputT::iterator To,
ForwardIteratorT Begin,
ForwardIteratorT End )
{
replace_const_time_helper<
boost::mpl::and_<
has_const_time_insert<InputT>,
has_const_time_erase<InputT> >::value >()(
Input, From, To, Begin, End );
}
};
// Container has native replace method
template<>
struct replace_native_helper< true >
{
template< typename InputT, typename ForwardIteratorT >
void operator()(
InputT& Input,
BOOST_STRING_TYPENAME InputT::iterator From,
BOOST_STRING_TYPENAME InputT::iterator To,
ForwardIteratorT Begin,
ForwardIteratorT End )
{
Input.replace( From, To, Begin, End );
}
};
// replace helper -------------------------------------------------//
template< typename InputT, typename ForwardIteratorT >
inline void replace(
InputT& Input,
BOOST_STRING_TYPENAME InputT::iterator From,
BOOST_STRING_TYPENAME InputT::iterator To,
ForwardIteratorT Begin,
ForwardIteratorT End )
{
replace_native_helper< has_native_replace<InputT>::value >()(
Input, From, To, Begin, End );
}
template< typename InputT, typename InsertT >
inline void replace(
InputT& Input,
BOOST_STRING_TYPENAME InputT::iterator From,
BOOST_STRING_TYPENAME InputT::iterator To,
const InsertT& Insert )
{
if(From!=To)
{
::boost::algorithm::detail::replace( Input, From, To, ::boost::begin(Insert), ::boost::end(Insert) );
}
else
{
::boost::algorithm::detail::insert( Input, From, ::boost::begin(Insert), ::boost::end(Insert) );
}
}
} // namespace detail
} // namespace algorithm
} // namespace boost
#endif // BOOST_STRING_DETAIL_SEQUENCE_HPP

View File

@ -0,0 +1,95 @@
// Boost string_algo library trim.hpp header file ---------------------------//
// Copyright Pavol Droba 2002-2003.
//
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
// See http://www.boost.org/ for updates, documentation, and revision history.
#ifndef BOOST_STRING_TRIM_DETAIL_HPP
#define BOOST_STRING_TRIM_DETAIL_HPP
#include <boost/algorithm/string/config.hpp>
#include <boost/detail/iterator.hpp>
namespace boost {
namespace algorithm {
namespace detail {
// trim iterator helper -----------------------------------------------//
template< typename ForwardIteratorT, typename PredicateT >
inline ForwardIteratorT trim_end_iter_select(
ForwardIteratorT InBegin,
ForwardIteratorT InEnd,
PredicateT IsSpace,
std::forward_iterator_tag )
{
ForwardIteratorT TrimIt=InBegin;
for( ForwardIteratorT It=InBegin; It!=InEnd; ++It )
{
if ( !IsSpace(*It) )
{
TrimIt=It;
++TrimIt;
}
}
return TrimIt;
}
template< typename ForwardIteratorT, typename PredicateT >
inline ForwardIteratorT trim_end_iter_select(
ForwardIteratorT InBegin,
ForwardIteratorT InEnd,
PredicateT IsSpace,
std::bidirectional_iterator_tag )
{
for( ForwardIteratorT It=InEnd; It!=InBegin; )
{
if ( !IsSpace(*(--It)) )
return ++It;
}
return InBegin;
}
// Search for first non matching character from the beginning of the sequence
template< typename ForwardIteratorT, typename PredicateT >
inline ForwardIteratorT trim_begin(
ForwardIteratorT InBegin,
ForwardIteratorT InEnd,
PredicateT IsSpace )
{
ForwardIteratorT It=InBegin;
for(; It!=InEnd; ++It )
{
if (!IsSpace(*It))
return It;
}
return It;
}
// Search for first non matching character from the end of the sequence
template< typename ForwardIteratorT, typename PredicateT >
inline ForwardIteratorT trim_end(
ForwardIteratorT InBegin,
ForwardIteratorT InEnd,
PredicateT IsSpace )
{
typedef BOOST_STRING_TYPENAME boost::detail::
iterator_traits<ForwardIteratorT>::iterator_category category;
return ::boost::algorithm::detail::trim_end_iter_select( InBegin, InEnd, IsSpace, category() );
}
} // namespace detail
} // namespace algorithm
} // namespace boost
#endif // BOOST_STRING_TRIM_DETAIL_HPP

View File

@ -0,0 +1,106 @@
// Boost string_algo library util.hpp header file ---------------------------//
// Copyright Pavol Droba 2002-2003.
//
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
// See http://www.boost.org/ for updates, documentation, and revision history.
#ifndef BOOST_STRING_UTIL_DETAIL_HPP
#define BOOST_STRING_UTIL_DETAIL_HPP
#include <boost/algorithm/string/config.hpp>
#include <functional>
#include <boost/range/iterator_range_core.hpp>
namespace boost {
namespace algorithm {
namespace detail {
// empty container -----------------------------------------------//
// empty_container
/*
This class represents always empty container,
containing elements of type CharT.
It is supposed to be used in a const version only
*/
template< typename CharT >
struct empty_container
{
typedef empty_container<CharT> type;
typedef CharT value_type;
typedef std::size_t size_type;
typedef std::ptrdiff_t difference_type;
typedef const value_type& reference;
typedef const value_type& const_reference;
typedef const value_type* iterator;
typedef const value_type* const_iterator;
// Operations
const_iterator begin() const
{
return reinterpret_cast<const_iterator>(0);
}
const_iterator end() const
{
return reinterpret_cast<const_iterator>(0);
}
bool empty() const
{
return false;
}
size_type size() const
{
return 0;
}
};
// bounded copy algorithm -----------------------------------------------//
// Bounded version of the std::copy algorithm
template<typename InputIteratorT, typename OutputIteratorT>
inline OutputIteratorT bounded_copy(
InputIteratorT First,
InputIteratorT Last,
OutputIteratorT DestFirst,
OutputIteratorT DestLast )
{
InputIteratorT InputIt=First;
OutputIteratorT OutputIt=DestFirst;
for(; InputIt!=Last && OutputIt!=DestLast; InputIt++, OutputIt++ )
{
*OutputIt=*InputIt;
}
return OutputIt;
}
// iterator range utilities -----------------------------------------//
// copy range functor
template<
typename SeqT,
typename IteratorT=BOOST_STRING_TYPENAME SeqT::const_iterator >
struct copy_iterator_rangeF :
public std::unary_function< iterator_range<IteratorT>, SeqT >
{
SeqT operator()( const iterator_range<IteratorT>& Range ) const
{
return copy_range<SeqT>(Range);
}
};
} // namespace detail
} // namespace algorithm
} // namespace boost
#endif // BOOST_STRING_UTIL_DETAIL_HPP

View File

@ -0,0 +1,844 @@
// Boost string_algo library erase.hpp header file ---------------------------//
// Copyright Pavol Droba 2002-2006.
//
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
// See http://www.boost.org/ for updates, documentation, and revision history.
#ifndef BOOST_STRING_ERASE_HPP
#define BOOST_STRING_ERASE_HPP
#include <boost/algorithm/string/config.hpp>
#include <boost/range/iterator_range_core.hpp>
#include <boost/range/begin.hpp>
#include <boost/range/end.hpp>
#include <boost/range/iterator.hpp>
#include <boost/range/const_iterator.hpp>
#include <boost/algorithm/string/find_format.hpp>
#include <boost/algorithm/string/finder.hpp>
#include <boost/algorithm/string/formatter.hpp>
/*! \file
Defines various erase algorithms. Each algorithm removes
part(s) of the input according to a searching criteria.
*/
namespace boost {
namespace algorithm {
// erase_range -------------------------------------------------------//
//! Erase range algorithm
/*!
Remove the given range from the input. The result is a modified copy of
the input. It is returned as a sequence or copied to the output iterator.
\param Output An output iterator to which the result will be copied
\param Input An input sequence
\param SearchRange A range in the input to be removed
\return An output iterator pointing just after the last inserted character or
a modified copy of the input
\note The second variant of this function provides the strong exception-safety guarantee
*/
template<typename OutputIteratorT, typename RangeT>
inline OutputIteratorT erase_range_copy(
OutputIteratorT Output,
const RangeT& Input,
const iterator_range<
BOOST_STRING_TYPENAME
range_const_iterator<RangeT>::type>& SearchRange )
{
return ::boost::algorithm::find_format_copy(
Output,
Input,
::boost::algorithm::range_finder(SearchRange),
::boost::algorithm::empty_formatter(Input) );
}
//! Erase range algorithm
/*!
\overload
*/
template<typename SequenceT>
inline SequenceT erase_range_copy(
const SequenceT& Input,
const iterator_range<
BOOST_STRING_TYPENAME
range_const_iterator<SequenceT>::type>& SearchRange )
{
return ::boost::algorithm::find_format_copy(
Input,
::boost::algorithm::range_finder(SearchRange),
::boost::algorithm::empty_formatter(Input) );
}
//! Erase range algorithm
/*!
Remove the given range from the input.
The input sequence is modified in-place.
\param Input An input sequence
\param SearchRange A range in the input to be removed
*/
template<typename SequenceT>
inline void erase_range(
SequenceT& Input,
const iterator_range<
BOOST_STRING_TYPENAME
range_iterator<SequenceT>::type>& SearchRange )
{
::boost::algorithm::find_format(
Input,
::boost::algorithm::range_finder(SearchRange),
::boost::algorithm::empty_formatter(Input) );
}
// erase_first --------------------------------------------------------//
//! Erase first algorithm
/*!
Remove the first occurrence of the substring from the input.
The result is a modified copy of the input. It is returned as a sequence
or copied to the output iterator.
\param Output An output iterator to which the result will be copied
\param Input An input string
\param Search A substring to be searched for
\return An output iterator pointing just after the last inserted character or
a modified copy of the input
\note The second variant of this function provides the strong exception-safety guarantee
*/
template<
typename OutputIteratorT,
typename Range1T,
typename Range2T>
inline OutputIteratorT erase_first_copy(
OutputIteratorT Output,
const Range1T& Input,
const Range2T& Search )
{
return ::boost::algorithm::find_format_copy(
Output,
Input,
::boost::algorithm::first_finder(Search),
::boost::algorithm::empty_formatter(Input) );
}
//! Erase first algorithm
/*!
\overload
*/
template<typename SequenceT, typename RangeT>
inline SequenceT erase_first_copy(
const SequenceT& Input,
const RangeT& Search )
{
return ::boost::algorithm::find_format_copy(
Input,
::boost::algorithm::first_finder(Search),
::boost::algorithm::empty_formatter(Input) );
}
//! Erase first algorithm
/*!
Remove the first occurrence of the substring from the input.
The input sequence is modified in-place.
\param Input An input string
\param Search A substring to be searched for.
*/
template<typename SequenceT, typename RangeT>
inline void erase_first(
SequenceT& Input,
const RangeT& Search )
{
::boost::algorithm::find_format(
Input,
::boost::algorithm::first_finder(Search),
::boost::algorithm::empty_formatter(Input) );
}
// erase_first ( case insensitive ) ------------------------------------//
//! Erase first algorithm ( case insensitive )
/*!
Remove the first occurrence of the substring from the input.
The result is a modified copy of the input. It is returned as a sequence
or copied to the output iterator.
Searching is case insensitive.
\param Output An output iterator to which the result will be copied
\param Input An input string
\param Search A substring to be searched for
\param Loc A locale used for case insensitive comparison
\return An output iterator pointing just after the last inserted character or
a modified copy of the input
\note The second variant of this function provides the strong exception-safety guarantee
*/
template<
typename OutputIteratorT,
typename Range1T,
typename Range2T>
inline OutputIteratorT ierase_first_copy(
OutputIteratorT Output,
const Range1T& Input,
const Range2T& Search,
const std::locale& Loc=std::locale() )
{
return ::boost::algorithm::find_format_copy(
Output,
Input,
::boost::algorithm::first_finder(Search, is_iequal(Loc)),
::boost::algorithm::empty_formatter(Input) );
}
//! Erase first algorithm ( case insensitive )
/*!
\overload
*/
template<typename SequenceT, typename RangeT>
inline SequenceT ierase_first_copy(
const SequenceT& Input,
const RangeT& Search,
const std::locale& Loc=std::locale() )
{
return ::boost::algorithm::find_format_copy(
Input,
::boost::algorithm::first_finder(Search, is_iequal(Loc)),
::boost::algorithm::empty_formatter(Input) );
}
//! Erase first algorithm ( case insensitive )
/*!
Remove the first occurrence of the substring from the input.
The input sequence is modified in-place. Searching is case insensitive.
\param Input An input string
\param Search A substring to be searched for
\param Loc A locale used for case insensitive comparison
*/
template<typename SequenceT, typename RangeT>
inline void ierase_first(
SequenceT& Input,
const RangeT& Search,
const std::locale& Loc=std::locale() )
{
::boost::algorithm::find_format(
Input,
::boost::algorithm::first_finder(Search, is_iequal(Loc)),
::boost::algorithm::empty_formatter(Input) );
}
// erase_last --------------------------------------------------------//
//! Erase last algorithm
/*!
Remove the last occurrence of the substring from the input.
The result is a modified copy of the input. It is returned as a sequence
or copied to the output iterator.
\param Output An output iterator to which the result will be copied
\param Input An input string
\param Search A substring to be searched for.
\return An output iterator pointing just after the last inserted character or
a modified copy of the input
\note The second variant of this function provides the strong exception-safety guarantee
*/
template<
typename OutputIteratorT,
typename Range1T,
typename Range2T>
inline OutputIteratorT erase_last_copy(
OutputIteratorT Output,
const Range1T& Input,
const Range2T& Search )
{
return ::boost::algorithm::find_format_copy(
Output,
Input,
::boost::algorithm::last_finder(Search),
::boost::algorithm::empty_formatter(Input) );
}
//! Erase last algorithm
/*!
\overload
*/
template<typename SequenceT, typename RangeT>
inline SequenceT erase_last_copy(
const SequenceT& Input,
const RangeT& Search )
{
return ::boost::algorithm::find_format_copy(
Input,
::boost::algorithm::last_finder(Search),
::boost::algorithm::empty_formatter(Input) );
}
//! Erase last algorithm
/*!
Remove the last occurrence of the substring from the input.
The input sequence is modified in-place.
\param Input An input string
\param Search A substring to be searched for
*/
template<typename SequenceT, typename RangeT>
inline void erase_last(
SequenceT& Input,
const RangeT& Search )
{
::boost::algorithm::find_format(
Input,
::boost::algorithm::last_finder(Search),
::boost::algorithm::empty_formatter(Input) );
}
// erase_last ( case insensitive ) ------------------------------------//
//! Erase last algorithm ( case insensitive )
/*!
Remove the last occurrence of the substring from the input.
The result is a modified copy of the input. It is returned as a sequence
or copied to the output iterator.
Searching is case insensitive.
\param Output An output iterator to which the result will be copied
\param Input An input string
\param Search A substring to be searched for
\param Loc A locale used for case insensitive comparison
\return An output iterator pointing just after the last inserted character or
a modified copy of the input
\note The second variant of this function provides the strong exception-safety guarantee
*/
template<
typename OutputIteratorT,
typename Range1T,
typename Range2T>
inline OutputIteratorT ierase_last_copy(
OutputIteratorT Output,
const Range1T& Input,
const Range2T& Search,
const std::locale& Loc=std::locale() )
{
return ::boost::algorithm::find_format_copy(
Output,
Input,
::boost::algorithm::last_finder(Search, is_iequal(Loc)),
::boost::algorithm::empty_formatter(Input) );
}
//! Erase last algorithm ( case insensitive )
/*!
\overload
*/
template<typename SequenceT, typename RangeT>
inline SequenceT ierase_last_copy(
const SequenceT& Input,
const RangeT& Search,
const std::locale& Loc=std::locale() )
{
return ::boost::algorithm::find_format_copy(
Input,
::boost::algorithm::last_finder(Search, is_iequal(Loc)),
::boost::algorithm::empty_formatter(Input) );
}
//! Erase last algorithm ( case insensitive )
/*!
Remove the last occurrence of the substring from the input.
The input sequence is modified in-place. Searching is case insensitive.
\param Input An input string
\param Search A substring to be searched for
\param Loc A locale used for case insensitive comparison
*/
template<typename SequenceT, typename RangeT>
inline void ierase_last(
SequenceT& Input,
const RangeT& Search,
const std::locale& Loc=std::locale() )
{
::boost::algorithm::find_format(
Input,
::boost::algorithm::last_finder(Search, is_iequal(Loc)),
::boost::algorithm::empty_formatter(Input) );
}
// erase_nth --------------------------------------------------------------------//
//! Erase nth algorithm
/*!
Remove the Nth occurrence of the substring in the input.
The result is a modified copy of the input. It is returned as a sequence
or copied to the output iterator.
\param Output An output iterator to which the result will be copied
\param Input An input string
\param Search A substring to be searched for
\param Nth An index of the match to be replaced. The index is 0-based.
For negative N, matches are counted from the end of string.
\return An output iterator pointing just after the last inserted character or
a modified copy of the input
\note The second variant of this function provides the strong exception-safety guarantee
*/
template<
typename OutputIteratorT,
typename Range1T,
typename Range2T>
inline OutputIteratorT erase_nth_copy(
OutputIteratorT Output,
const Range1T& Input,
const Range2T& Search,
int Nth )
{
return ::boost::algorithm::find_format_copy(
Output,
Input,
::boost::algorithm::nth_finder(Search, Nth),
::boost::algorithm::empty_formatter(Input) );
}
//! Erase nth algorithm
/*!
\overload
*/
template<typename SequenceT, typename RangeT>
inline SequenceT erase_nth_copy(
const SequenceT& Input,
const RangeT& Search,
int Nth )
{
return ::boost::algorithm::find_format_copy(
Input,
::boost::algorithm::nth_finder(Search, Nth),
::boost::algorithm::empty_formatter(Input) );
}
//! Erase nth algorithm
/*!
Remove the Nth occurrence of the substring in the input.
The input sequence is modified in-place.
\param Input An input string
\param Search A substring to be searched for.
\param Nth An index of the match to be replaced. The index is 0-based.
For negative N, matches are counted from the end of string.
*/
template<typename SequenceT, typename RangeT>
inline void erase_nth(
SequenceT& Input,
const RangeT& Search,
int Nth )
{
::boost::algorithm::find_format(
Input,
::boost::algorithm::nth_finder(Search, Nth),
::boost::algorithm::empty_formatter(Input) );
}
// erase_nth ( case insensitive ) ---------------------------------------------//
//! Erase nth algorithm ( case insensitive )
/*!
Remove the Nth occurrence of the substring in the input.
The result is a modified copy of the input. It is returned as a sequence
or copied to the output iterator.
Searching is case insensitive.
\param Output An output iterator to which the result will be copied
\param Input An input string
\param Search A substring to be searched for.
\param Nth An index of the match to be replaced. The index is 0-based.
For negative N, matches are counted from the end of string.
\param Loc A locale used for case insensitive comparison
\return An output iterator pointing just after the last inserted character or
a modified copy of the input
\note The second variant of this function provides the strong exception-safety guarantee
*/
template<
typename OutputIteratorT,
typename Range1T,
typename Range2T>
inline OutputIteratorT ierase_nth_copy(
OutputIteratorT Output,
const Range1T& Input,
const Range2T& Search,
int Nth,
const std::locale& Loc=std::locale() )
{
return ::boost::algorithm::find_format_copy(
Output,
Input,
::boost::algorithm::nth_finder(Search, Nth, is_iequal(Loc)),
::boost::algorithm::empty_formatter(Input) );
}
//! Erase nth algorithm
/*!
\overload
*/
template<typename SequenceT, typename RangeT>
inline SequenceT ierase_nth_copy(
const SequenceT& Input,
const RangeT& Search,
int Nth,
const std::locale& Loc=std::locale() )
{
return ::boost::algorithm::find_format_copy(
Input,
::boost::algorithm::nth_finder(Search, Nth, is_iequal(Loc)),
empty_formatter(Input) );
}
//! Erase nth algorithm
/*!
Remove the Nth occurrence of the substring in the input.
The input sequence is modified in-place. Searching is case insensitive.
\param Input An input string
\param Search A substring to be searched for.
\param Nth An index of the match to be replaced. The index is 0-based.
For negative N, matches are counted from the end of string.
\param Loc A locale used for case insensitive comparison
*/
template<typename SequenceT, typename RangeT>
inline void ierase_nth(
SequenceT& Input,
const RangeT& Search,
int Nth,
const std::locale& Loc=std::locale() )
{
::boost::algorithm::find_format(
Input,
::boost::algorithm::nth_finder(Search, Nth, is_iequal(Loc)),
::boost::algorithm::empty_formatter(Input) );
}
// erase_all --------------------------------------------------------//
//! Erase all algorithm
/*!
Remove all the occurrences of the string from the input.
The result is a modified copy of the input. It is returned as a sequence
or copied to the output iterator.
\param Output An output iterator to which the result will be copied
\param Input An input sequence
\param Search A substring to be searched for.
\return An output iterator pointing just after the last inserted character or
a modified copy of the input
\note The second variant of this function provides the strong exception-safety guarantee
*/
template<
typename OutputIteratorT,
typename Range1T,
typename Range2T>
inline OutputIteratorT erase_all_copy(
OutputIteratorT Output,
const Range1T& Input,
const Range2T& Search )
{
return ::boost::algorithm::find_format_all_copy(
Output,
Input,
::boost::algorithm::first_finder(Search),
::boost::algorithm::empty_formatter(Input) );
}
//! Erase all algorithm
/*!
\overload
*/
template<typename SequenceT, typename RangeT>
inline SequenceT erase_all_copy(
const SequenceT& Input,
const RangeT& Search )
{
return ::boost::algorithm::find_format_all_copy(
Input,
::boost::algorithm::first_finder(Search),
::boost::algorithm::empty_formatter(Input) );
}
//! Erase all algorithm
/*!
Remove all the occurrences of the string from the input.
The input sequence is modified in-place.
\param Input An input string
\param Search A substring to be searched for.
*/
template<typename SequenceT, typename RangeT>
inline void erase_all(
SequenceT& Input,
const RangeT& Search )
{
::boost::algorithm::find_format_all(
Input,
::boost::algorithm::first_finder(Search),
::boost::algorithm::empty_formatter(Input) );
}
// erase_all ( case insensitive ) ------------------------------------//
//! Erase all algorithm ( case insensitive )
/*!
Remove all the occurrences of the string from the input.
The result is a modified copy of the input. It is returned as a sequence
or copied to the output iterator.
Searching is case insensitive.
\param Output An output iterator to which the result will be copied
\param Input An input string
\param Search A substring to be searched for
\param Loc A locale used for case insensitive comparison
\return An output iterator pointing just after the last inserted character or
a modified copy of the input
\note The second variant of this function provides the strong exception-safety guarantee
*/
template<
typename OutputIteratorT,
typename Range1T,
typename Range2T>
inline OutputIteratorT ierase_all_copy(
OutputIteratorT Output,
const Range1T& Input,
const Range2T& Search,
const std::locale& Loc=std::locale() )
{
return ::boost::algorithm::find_format_all_copy(
Output,
Input,
::boost::algorithm::first_finder(Search, is_iequal(Loc)),
::boost::algorithm::empty_formatter(Input) );
}
//! Erase all algorithm ( case insensitive )
/*!
\overload
*/
template<typename SequenceT, typename RangeT>
inline SequenceT ierase_all_copy(
const SequenceT& Input,
const RangeT& Search,
const std::locale& Loc=std::locale() )
{
return ::boost::algorithm::find_format_all_copy(
Input,
::boost::algorithm::first_finder(Search, is_iequal(Loc)),
::boost::algorithm::empty_formatter(Input) );
}
//! Erase all algorithm ( case insensitive )
/*!
Remove all the occurrences of the string from the input.
The input sequence is modified in-place. Searching is case insensitive.
\param Input An input string
\param Search A substring to be searched for.
\param Loc A locale used for case insensitive comparison
*/
template<typename SequenceT, typename RangeT>
inline void ierase_all(
SequenceT& Input,
const RangeT& Search,
const std::locale& Loc=std::locale() )
{
::boost::algorithm::find_format_all(
Input,
::boost::algorithm::first_finder(Search, is_iequal(Loc)),
::boost::algorithm::empty_formatter(Input) );
}
// erase_head --------------------------------------------------------------------//
//! Erase head algorithm
/*!
Remove the head from the input. The head is a prefix of a sequence of given size.
If the sequence is shorter then required, the whole string is
considered to be the head. The result is a modified copy of the input.
It is returned as a sequence or copied to the output iterator.
\param Output An output iterator to which the result will be copied
\param Input An input string
\param N Length of the head.
For N>=0, at most N characters are extracted.
For N<0, size(Input)-|N| characters are extracted.
\return An output iterator pointing just after the last inserted character or
a modified copy of the input
\note The second variant of this function provides the strong exception-safety guarantee
*/
template<
typename OutputIteratorT,
typename RangeT>
inline OutputIteratorT erase_head_copy(
OutputIteratorT Output,
const RangeT& Input,
int N )
{
return ::boost::algorithm::find_format_copy(
Output,
Input,
::boost::algorithm::head_finder(N),
::boost::algorithm::empty_formatter( Input ) );
}
//! Erase head algorithm
/*!
\overload
*/
template<typename SequenceT>
inline SequenceT erase_head_copy(
const SequenceT& Input,
int N )
{
return ::boost::algorithm::find_format_copy(
Input,
::boost::algorithm::head_finder(N),
::boost::algorithm::empty_formatter( Input ) );
}
//! Erase head algorithm
/*!
Remove the head from the input. The head is a prefix of a sequence of given size.
If the sequence is shorter then required, the whole string is
considered to be the head. The input sequence is modified in-place.
\param Input An input string
\param N Length of the head
For N>=0, at most N characters are extracted.
For N<0, size(Input)-|N| characters are extracted.
*/
template<typename SequenceT>
inline void erase_head(
SequenceT& Input,
int N )
{
::boost::algorithm::find_format(
Input,
::boost::algorithm::head_finder(N),
::boost::algorithm::empty_formatter( Input ) );
}
// erase_tail --------------------------------------------------------------------//
//! Erase tail algorithm
/*!
Remove the tail from the input. The tail is a suffix of a sequence of given size.
If the sequence is shorter then required, the whole string is
considered to be the tail.
The result is a modified copy of the input. It is returned as a sequence
or copied to the output iterator.
\param Output An output iterator to which the result will be copied
\param Input An input string
\param N Length of the tail.
For N>=0, at most N characters are extracted.
For N<0, size(Input)-|N| characters are extracted.
\return An output iterator pointing just after the last inserted character or
a modified copy of the input
\note The second variant of this function provides the strong exception-safety guarantee
*/
template<
typename OutputIteratorT,
typename RangeT>
inline OutputIteratorT erase_tail_copy(
OutputIteratorT Output,
const RangeT& Input,
int N )
{
return ::boost::algorithm::find_format_copy(
Output,
Input,
::boost::algorithm::tail_finder(N),
::boost::algorithm::empty_formatter( Input ) );
}
//! Erase tail algorithm
/*!
\overload
*/
template<typename SequenceT>
inline SequenceT erase_tail_copy(
const SequenceT& Input,
int N )
{
return ::boost::algorithm::find_format_copy(
Input,
::boost::algorithm::tail_finder(N),
::boost::algorithm::empty_formatter( Input ) );
}
//! Erase tail algorithm
/*!
Remove the tail from the input. The tail is a suffix of a sequence of given size.
If the sequence is shorter then required, the whole string is
considered to be the tail. The input sequence is modified in-place.
\param Input An input string
\param N Length of the tail
For N>=0, at most N characters are extracted.
For N<0, size(Input)-|N| characters are extracted.
*/
template<typename SequenceT>
inline void erase_tail(
SequenceT& Input,
int N )
{
::boost::algorithm::find_format(
Input,
::boost::algorithm::tail_finder(N),
::boost::algorithm::empty_formatter( Input ) );
}
} // namespace algorithm
// pull names into the boost namespace
using algorithm::erase_range_copy;
using algorithm::erase_range;
using algorithm::erase_first_copy;
using algorithm::erase_first;
using algorithm::ierase_first_copy;
using algorithm::ierase_first;
using algorithm::erase_last_copy;
using algorithm::erase_last;
using algorithm::ierase_last_copy;
using algorithm::ierase_last;
using algorithm::erase_nth_copy;
using algorithm::erase_nth;
using algorithm::ierase_nth_copy;
using algorithm::ierase_nth;
using algorithm::erase_all_copy;
using algorithm::erase_all;
using algorithm::ierase_all_copy;
using algorithm::ierase_all;
using algorithm::erase_head_copy;
using algorithm::erase_head;
using algorithm::erase_tail_copy;
using algorithm::erase_tail;
} // namespace boost
#endif // BOOST_ERASE_HPP

View File

@ -0,0 +1,334 @@
// Boost string_algo library find.hpp header file ---------------------------//
// Copyright Pavol Droba 2002-2003.
//
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
// See http://www.boost.org/ for updates, documentation, and revision history.
#ifndef BOOST_STRING_FIND_HPP
#define BOOST_STRING_FIND_HPP
#include <boost/algorithm/string/config.hpp>
#include <boost/range/iterator_range_core.hpp>
#include <boost/range/begin.hpp>
#include <boost/range/end.hpp>
#include <boost/range/iterator.hpp>
#include <boost/range/as_literal.hpp>
#include <boost/algorithm/string/finder.hpp>
#include <boost/algorithm/string/compare.hpp>
#include <boost/algorithm/string/constants.hpp>
/*! \file
Defines a set of find algorithms. The algorithms are searching
for a substring of the input. The result is given as an \c iterator_range
delimiting the substring.
*/
namespace boost {
namespace algorithm {
// Generic find -----------------------------------------------//
//! Generic find algorithm
/*!
Search the input using the given finder.
\param Input A string which will be searched.
\param Finder Finder object used for searching.
\return
An \c iterator_range delimiting the match.
Returned iterator is either \c RangeT::iterator or
\c RangeT::const_iterator, depending on the constness of
the input parameter.
*/
template<typename RangeT, typename FinderT>
inline iterator_range<
BOOST_STRING_TYPENAME range_iterator<RangeT>::type>
find(
RangeT& Input,
const FinderT& Finder)
{
iterator_range<BOOST_STRING_TYPENAME range_iterator<RangeT>::type> lit_input(::boost::as_literal(Input));
return Finder(::boost::begin(lit_input),::boost::end(lit_input));
}
// find_first -----------------------------------------------//
//! Find first algorithm
/*!
Search for the first occurrence of the substring in the input.
\param Input A string which will be searched.
\param Search A substring to be searched for.
\return
An \c iterator_range delimiting the match.
Returned iterator is either \c RangeT::iterator or
\c RangeT::const_iterator, depending on the constness of
the input parameter.
\note This function provides the strong exception-safety guarantee
*/
template<typename Range1T, typename Range2T>
inline iterator_range<
BOOST_STRING_TYPENAME range_iterator<Range1T>::type>
find_first(
Range1T& Input,
const Range2T& Search)
{
return ::boost::algorithm::find(Input, ::boost::algorithm::first_finder(Search));
}
//! Find first algorithm ( case insensitive )
/*!
Search for the first occurrence of the substring in the input.
Searching is case insensitive.
\param Input A string which will be searched.
\param Search A substring to be searched for.
\param Loc A locale used for case insensitive comparison
\return
An \c iterator_range delimiting the match.
Returned iterator is either \c Range1T::iterator or
\c Range1T::const_iterator, depending on the constness of
the input parameter.
\note This function provides the strong exception-safety guarantee
*/
template<typename Range1T, typename Range2T>
inline iterator_range<
BOOST_STRING_TYPENAME range_iterator<Range1T>::type>
ifind_first(
Range1T& Input,
const Range2T& Search,
const std::locale& Loc=std::locale())
{
return ::boost::algorithm::find(Input, ::boost::algorithm::first_finder(Search,is_iequal(Loc)));
}
// find_last -----------------------------------------------//
//! Find last algorithm
/*!
Search for the last occurrence of the substring in the input.
\param Input A string which will be searched.
\param Search A substring to be searched for.
\return
An \c iterator_range delimiting the match.
Returned iterator is either \c Range1T::iterator or
\c Range1T::const_iterator, depending on the constness of
the input parameter.
\note This function provides the strong exception-safety guarantee
*/
template<typename Range1T, typename Range2T>
inline iterator_range<
BOOST_STRING_TYPENAME range_iterator<Range1T>::type>
find_last(
Range1T& Input,
const Range2T& Search)
{
return ::boost::algorithm::find(Input, ::boost::algorithm::last_finder(Search));
}
//! Find last algorithm ( case insensitive )
/*!
Search for the last match a string in the input.
Searching is case insensitive.
\param Input A string which will be searched.
\param Search A substring to be searched for.
\param Loc A locale used for case insensitive comparison
\return
An \c iterator_range delimiting the match.
Returned iterator is either \c Range1T::iterator or
\c Range1T::const_iterator, depending on the constness of
the input parameter.
\note This function provides the strong exception-safety guarantee
*/
template<typename Range1T, typename Range2T>
inline iterator_range<
BOOST_STRING_TYPENAME range_iterator<Range1T>::type>
ifind_last(
Range1T& Input,
const Range2T& Search,
const std::locale& Loc=std::locale())
{
return ::boost::algorithm::find(Input, ::boost::algorithm::last_finder(Search, is_iequal(Loc)));
}
// find_nth ----------------------------------------------------------------------//
//! Find n-th algorithm
/*!
Search for the n-th (zero-indexed) occurrence of the substring in the
input.
\param Input A string which will be searched.
\param Search A substring to be searched for.
\param Nth An index (zero-indexed) of the match to be found.
For negative N, the matches are counted from the end of string.
\return
An \c iterator_range delimiting the match.
Returned iterator is either \c Range1T::iterator or
\c Range1T::const_iterator, depending on the constness of
the input parameter.
*/
template<typename Range1T, typename Range2T>
inline iterator_range<
BOOST_STRING_TYPENAME range_iterator<Range1T>::type>
find_nth(
Range1T& Input,
const Range2T& Search,
int Nth)
{
return ::boost::algorithm::find(Input, ::boost::algorithm::nth_finder(Search,Nth));
}
//! Find n-th algorithm ( case insensitive ).
/*!
Search for the n-th (zero-indexed) occurrence of the substring in the
input. Searching is case insensitive.
\param Input A string which will be searched.
\param Search A substring to be searched for.
\param Nth An index (zero-indexed) of the match to be found.
For negative N, the matches are counted from the end of string.
\param Loc A locale used for case insensitive comparison
\return
An \c iterator_range delimiting the match.
Returned iterator is either \c Range1T::iterator or
\c Range1T::const_iterator, depending on the constness of
the input parameter.
\note This function provides the strong exception-safety guarantee
*/
template<typename Range1T, typename Range2T>
inline iterator_range<
BOOST_STRING_TYPENAME range_iterator<Range1T>::type>
ifind_nth(
Range1T& Input,
const Range2T& Search,
int Nth,
const std::locale& Loc=std::locale())
{
return ::boost::algorithm::find(Input, ::boost::algorithm::nth_finder(Search,Nth,is_iequal(Loc)));
}
// find_head ----------------------------------------------------------------------//
//! Find head algorithm
/*!
Get the head of the input. Head is a prefix of the string of the
given size. If the input is shorter then required, whole input is considered
to be the head.
\param Input An input string
\param N Length of the head
For N>=0, at most N characters are extracted.
For N<0, at most size(Input)-|N| characters are extracted.
\return
An \c iterator_range delimiting the match.
Returned iterator is either \c Range1T::iterator or
\c Range1T::const_iterator, depending on the constness of
the input parameter.
\note This function provides the strong exception-safety guarantee
*/
template<typename RangeT>
inline iterator_range<
BOOST_STRING_TYPENAME range_iterator<RangeT>::type>
find_head(
RangeT& Input,
int N)
{
return ::boost::algorithm::find(Input, ::boost::algorithm::head_finder(N));
}
// find_tail ----------------------------------------------------------------------//
//! Find tail algorithm
/*!
Get the tail of the input. Tail is a suffix of the string of the
given size. If the input is shorter then required, whole input is considered
to be the tail.
\param Input An input string
\param N Length of the tail.
For N>=0, at most N characters are extracted.
For N<0, at most size(Input)-|N| characters are extracted.
\return
An \c iterator_range delimiting the match.
Returned iterator is either \c RangeT::iterator or
\c RangeT::const_iterator, depending on the constness of
the input parameter.
\note This function provides the strong exception-safety guarantee
*/
template<typename RangeT>
inline iterator_range<
BOOST_STRING_TYPENAME range_iterator<RangeT>::type>
find_tail(
RangeT& Input,
int N)
{
return ::boost::algorithm::find(Input, ::boost::algorithm::tail_finder(N));
}
// find_token --------------------------------------------------------------------//
//! Find token algorithm
/*!
Look for a given token in the string. Token is a character that matches the
given predicate.
If the "token compress mode" is enabled, adjacent tokens are considered to be one match.
\param Input A input string.
\param Pred A unary predicate to identify a token
\param eCompress Enable/Disable compressing of adjacent tokens
\return
An \c iterator_range delimiting the match.
Returned iterator is either \c RangeT::iterator or
\c RangeT::const_iterator, depending on the constness of
the input parameter.
\note This function provides the strong exception-safety guarantee
*/
template<typename RangeT, typename PredicateT>
inline iterator_range<
BOOST_STRING_TYPENAME range_iterator<RangeT>::type>
find_token(
RangeT& Input,
PredicateT Pred,
token_compress_mode_type eCompress=token_compress_off)
{
return ::boost::algorithm::find(Input, ::boost::algorithm::token_finder(Pred, eCompress));
}
} // namespace algorithm
// pull names to the boost namespace
using algorithm::find;
using algorithm::find_first;
using algorithm::ifind_first;
using algorithm::find_last;
using algorithm::ifind_last;
using algorithm::find_nth;
using algorithm::ifind_nth;
using algorithm::find_head;
using algorithm::find_tail;
using algorithm::find_token;
} // namespace boost
#endif // BOOST_STRING_FIND_HPP

View File

@ -0,0 +1,287 @@
// Boost string_algo library find_format.hpp header file ---------------------------//
// Copyright Pavol Droba 2002-2003.
//
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
// See http://www.boost.org/ for updates, documentation, and revision history.
#ifndef BOOST_STRING_FIND_FORMAT_HPP
#define BOOST_STRING_FIND_FORMAT_HPP
#include <deque>
#include <boost/detail/iterator.hpp>
#include <boost/range/iterator_range_core.hpp>
#include <boost/range/begin.hpp>
#include <boost/range/end.hpp>
#include <boost/range/const_iterator.hpp>
#include <boost/range/as_literal.hpp>
#include <boost/algorithm/string/concept.hpp>
#include <boost/algorithm/string/detail/find_format.hpp>
#include <boost/algorithm/string/detail/find_format_all.hpp>
/*! \file
Defines generic replace algorithms. Each algorithm replaces
part(s) of the input. The part to be replaced is looked up using a Finder object.
Result of finding is then used by a Formatter object to generate the replacement.
*/
namespace boost {
namespace algorithm {
// generic replace -----------------------------------------------------------------//
//! Generic replace algorithm
/*!
Use the Finder to search for a substring. Use the Formatter to format
this substring and replace it in the input.
The result is a modified copy of the input. It is returned as a sequence
or copied to the output iterator.
\param Output An output iterator to which the result will be copied
\param Input An input sequence
\param Finder A Finder object used to search for a match to be replaced
\param Formatter A Formatter object used to format a match
\return An output iterator pointing just after the last inserted character or
a modified copy of the input
\note The second variant of this function provides the strong exception-safety guarantee
*/
template<
typename OutputIteratorT,
typename RangeT,
typename FinderT,
typename FormatterT>
inline OutputIteratorT find_format_copy(
OutputIteratorT Output,
const RangeT& Input,
FinderT Finder,
FormatterT Formatter )
{
// Concept check
BOOST_CONCEPT_ASSERT((
FinderConcept<
FinderT,
BOOST_STRING_TYPENAME range_const_iterator<RangeT>::type>
));
BOOST_CONCEPT_ASSERT((
FormatterConcept<
FormatterT,
FinderT,BOOST_STRING_TYPENAME range_const_iterator<RangeT>::type>
));
iterator_range<BOOST_STRING_TYPENAME range_const_iterator<RangeT>::type> lit_input(::boost::as_literal(Input));
return detail::find_format_copy_impl(
Output,
lit_input,
Formatter,
Finder( ::boost::begin(lit_input), ::boost::end(lit_input) ) );
}
//! Generic replace algorithm
/*!
\overload
*/
template<
typename SequenceT,
typename FinderT,
typename FormatterT>
inline SequenceT find_format_copy(
const SequenceT& Input,
FinderT Finder,
FormatterT Formatter )
{
// Concept check
BOOST_CONCEPT_ASSERT((
FinderConcept<
FinderT,
BOOST_STRING_TYPENAME range_const_iterator<SequenceT>::type>
));
BOOST_CONCEPT_ASSERT((
FormatterConcept<
FormatterT,
FinderT,BOOST_STRING_TYPENAME range_const_iterator<SequenceT>::type>
));
return detail::find_format_copy_impl(
Input,
Formatter,
Finder(::boost::begin(Input), ::boost::end(Input)));
}
//! Generic replace algorithm
/*!
Use the Finder to search for a substring. Use the Formatter to format
this substring and replace it in the input. The input is modified in-place.
\param Input An input sequence
\param Finder A Finder object used to search for a match to be replaced
\param Formatter A Formatter object used to format a match
*/
template<
typename SequenceT,
typename FinderT,
typename FormatterT>
inline void find_format(
SequenceT& Input,
FinderT Finder,
FormatterT Formatter)
{
// Concept check
BOOST_CONCEPT_ASSERT((
FinderConcept<
FinderT,
BOOST_STRING_TYPENAME range_const_iterator<SequenceT>::type>
));
BOOST_CONCEPT_ASSERT((
FormatterConcept<
FormatterT,
FinderT,BOOST_STRING_TYPENAME range_const_iterator<SequenceT>::type>
));
detail::find_format_impl(
Input,
Formatter,
Finder(::boost::begin(Input), ::boost::end(Input)));
}
// find_format_all generic ----------------------------------------------------------------//
//! Generic replace all algorithm
/*!
Use the Finder to search for a substring. Use the Formatter to format
this substring and replace it in the input. Repeat this for all matching
substrings.
The result is a modified copy of the input. It is returned as a sequence
or copied to the output iterator.
\param Output An output iterator to which the result will be copied
\param Input An input sequence
\param Finder A Finder object used to search for a match to be replaced
\param Formatter A Formatter object used to format a match
\return An output iterator pointing just after the last inserted character or
a modified copy of the input
\note The second variant of this function provides the strong exception-safety guarantee
*/
template<
typename OutputIteratorT,
typename RangeT,
typename FinderT,
typename FormatterT>
inline OutputIteratorT find_format_all_copy(
OutputIteratorT Output,
const RangeT& Input,
FinderT Finder,
FormatterT Formatter)
{
// Concept check
BOOST_CONCEPT_ASSERT((
FinderConcept<
FinderT,
BOOST_STRING_TYPENAME range_const_iterator<RangeT>::type>
));
BOOST_CONCEPT_ASSERT((
FormatterConcept<
FormatterT,
FinderT,BOOST_STRING_TYPENAME range_const_iterator<RangeT>::type>
));
iterator_range<BOOST_STRING_TYPENAME range_const_iterator<RangeT>::type> lit_input(::boost::as_literal(Input));
return detail::find_format_all_copy_impl(
Output,
lit_input,
Finder,
Formatter,
Finder(::boost::begin(lit_input), ::boost::end(lit_input)));
}
//! Generic replace all algorithm
/*!
\overload
*/
template<
typename SequenceT,
typename FinderT,
typename FormatterT >
inline SequenceT find_format_all_copy(
const SequenceT& Input,
FinderT Finder,
FormatterT Formatter )
{
// Concept check
BOOST_CONCEPT_ASSERT((
FinderConcept<
FinderT,
BOOST_STRING_TYPENAME range_const_iterator<SequenceT>::type>
));
BOOST_CONCEPT_ASSERT((
FormatterConcept<
FormatterT,
FinderT,BOOST_STRING_TYPENAME range_const_iterator<SequenceT>::type>
));
return detail::find_format_all_copy_impl(
Input,
Finder,
Formatter,
Finder( ::boost::begin(Input), ::boost::end(Input) ) );
}
//! Generic replace all algorithm
/*!
Use the Finder to search for a substring. Use the Formatter to format
this substring and replace it in the input. Repeat this for all matching
substrings.The input is modified in-place.
\param Input An input sequence
\param Finder A Finder object used to search for a match to be replaced
\param Formatter A Formatter object used to format a match
*/
template<
typename SequenceT,
typename FinderT,
typename FormatterT >
inline void find_format_all(
SequenceT& Input,
FinderT Finder,
FormatterT Formatter )
{
// Concept check
BOOST_CONCEPT_ASSERT((
FinderConcept<
FinderT,
BOOST_STRING_TYPENAME range_const_iterator<SequenceT>::type>
));
BOOST_CONCEPT_ASSERT((
FormatterConcept<
FormatterT,
FinderT,BOOST_STRING_TYPENAME range_const_iterator<SequenceT>::type>
));
detail::find_format_all_impl(
Input,
Finder,
Formatter,
Finder(::boost::begin(Input), ::boost::end(Input)));
}
} // namespace algorithm
// pull the names to the boost namespace
using algorithm::find_format_copy;
using algorithm::find_format;
using algorithm::find_format_all_copy;
using algorithm::find_format_all;
} // namespace boost
#endif // BOOST_STRING_FIND_FORMAT_HPP

View File

@ -0,0 +1,388 @@
// Boost string_algo library find_iterator.hpp header file ---------------------------//
// Copyright Pavol Droba 2002-2004.
//
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
// See http://www.boost.org/ for updates, documentation, and revision history.
#ifndef BOOST_STRING_FIND_ITERATOR_HPP
#define BOOST_STRING_FIND_ITERATOR_HPP
#include <boost/algorithm/string/config.hpp>
#include <boost/iterator/iterator_facade.hpp>
#include <boost/iterator/iterator_categories.hpp>
#include <boost/range/iterator_range_core.hpp>
#include <boost/range/begin.hpp>
#include <boost/range/end.hpp>
#include <boost/range/iterator.hpp>
#include <boost/range/as_literal.hpp>
#include <boost/algorithm/string/detail/find_iterator.hpp>
/*! \file
Defines find iterator classes. Find iterator repeatedly applies a Finder
to the specified input string to search for matches. Dereferencing
the iterator yields the current match or a range between the last and the current
match depending on the iterator used.
*/
namespace boost {
namespace algorithm {
// find_iterator -----------------------------------------------//
//! find_iterator
/*!
Find iterator encapsulates a Finder and allows
for incremental searching in a string.
Each increment moves the iterator to the next match.
Find iterator is a readable forward traversal iterator.
Dereferencing the iterator yields an iterator_range delimiting
the current match.
*/
template<typename IteratorT>
class find_iterator :
public iterator_facade<
find_iterator<IteratorT>,
const iterator_range<IteratorT>,
forward_traversal_tag >,
private detail::find_iterator_base<IteratorT>
{
private:
// facade support
friend class ::boost::iterator_core_access;
private:
// typedefs
typedef detail::find_iterator_base<IteratorT> base_type;
typedef BOOST_STRING_TYPENAME
base_type::input_iterator_type input_iterator_type;
typedef BOOST_STRING_TYPENAME
base_type::match_type match_type;
public:
//! Default constructor
/*!
Construct null iterator. All null iterators are equal.
\post eof()==true
*/
find_iterator() {}
//! Copy constructor
/*!
Construct a copy of the find_iterator
*/
find_iterator( const find_iterator& Other ) :
base_type(Other),
m_Match(Other.m_Match),
m_End(Other.m_End) {}
//! Constructor
/*!
Construct new find_iterator for a given finder
and a range.
*/
template<typename FinderT>
find_iterator(
IteratorT Begin,
IteratorT End,
FinderT Finder ) :
detail::find_iterator_base<IteratorT>(Finder,0),
m_Match(Begin,Begin),
m_End(End)
{
increment();
}
//! Constructor
/*!
Construct new find_iterator for a given finder
and a range.
*/
template<typename FinderT, typename RangeT>
find_iterator(
RangeT& Col,
FinderT Finder ) :
detail::find_iterator_base<IteratorT>(Finder,0)
{
iterator_range<BOOST_STRING_TYPENAME range_iterator<RangeT>::type> lit_col(::boost::as_literal(Col));
m_Match=::boost::make_iterator_range(::boost::begin(lit_col), ::boost::begin(lit_col));
m_End=::boost::end(lit_col);
increment();
}
private:
// iterator operations
// dereference
const match_type& dereference() const
{
return m_Match;
}
// increment
void increment()
{
m_Match=this->do_find(m_Match.end(),m_End);
}
// comparison
bool equal( const find_iterator& Other ) const
{
bool bEof=eof();
bool bOtherEof=Other.eof();
return bEof || bOtherEof ? bEof==bOtherEof :
(
m_Match==Other.m_Match &&
m_End==Other.m_End
);
}
public:
// operations
//! Eof check
/*!
Check the eof condition. Eof condition means that
there is nothing more to be searched i.e. find_iterator
is after the last match.
*/
bool eof() const
{
return
this->is_null() ||
(
m_Match.begin() == m_End &&
m_Match.end() == m_End
);
}
private:
// Attributes
match_type m_Match;
input_iterator_type m_End;
};
//! find iterator construction helper
/*!
* Construct a find iterator to iterate through the specified string
*/
template<typename RangeT, typename FinderT>
inline find_iterator<
BOOST_STRING_TYPENAME range_iterator<RangeT>::type>
make_find_iterator(
RangeT& Collection,
FinderT Finder)
{
return find_iterator<BOOST_STRING_TYPENAME range_iterator<RangeT>::type>(
Collection, Finder);
}
// split iterator -----------------------------------------------//
//! split_iterator
/*!
Split iterator encapsulates a Finder and allows
for incremental searching in a string.
Unlike the find iterator, split iterator iterates
through gaps between matches.
Find iterator is a readable forward traversal iterator.
Dereferencing the iterator yields an iterator_range delimiting
the current match.
*/
template<typename IteratorT>
class split_iterator :
public iterator_facade<
split_iterator<IteratorT>,
const iterator_range<IteratorT>,
forward_traversal_tag >,
private detail::find_iterator_base<IteratorT>
{
private:
// facade support
friend class ::boost::iterator_core_access;
private:
// typedefs
typedef detail::find_iterator_base<IteratorT> base_type;
typedef BOOST_STRING_TYPENAME
base_type::input_iterator_type input_iterator_type;
typedef BOOST_STRING_TYPENAME
base_type::match_type match_type;
public:
//! Default constructor
/*!
Construct null iterator. All null iterators are equal.
\post eof()==true
*/
split_iterator() :
m_Next(),
m_End(),
m_bEof(true)
{}
//! Copy constructor
/*!
Construct a copy of the split_iterator
*/
split_iterator( const split_iterator& Other ) :
base_type(Other),
m_Match(Other.m_Match),
m_Next(Other.m_Next),
m_End(Other.m_End),
m_bEof(Other.m_bEof)
{}
//! Constructor
/*!
Construct new split_iterator for a given finder
and a range.
*/
template<typename FinderT>
split_iterator(
IteratorT Begin,
IteratorT End,
FinderT Finder ) :
detail::find_iterator_base<IteratorT>(Finder,0),
m_Match(Begin,Begin),
m_Next(Begin),
m_End(End),
m_bEof(false)
{
// force the correct behavior for empty sequences and yield at least one token
if(Begin!=End)
{
increment();
}
}
//! Constructor
/*!
Construct new split_iterator for a given finder
and a collection.
*/
template<typename FinderT, typename RangeT>
split_iterator(
RangeT& Col,
FinderT Finder ) :
detail::find_iterator_base<IteratorT>(Finder,0),
m_bEof(false)
{
iterator_range<BOOST_STRING_TYPENAME range_iterator<RangeT>::type> lit_col(::boost::as_literal(Col));
m_Match=make_iterator_range(::boost::begin(lit_col), ::boost::begin(lit_col));
m_Next=::boost::begin(lit_col);
m_End=::boost::end(lit_col);
// force the correct behavior for empty sequences and yield at least one token
if(m_Next!=m_End)
{
increment();
}
}
private:
// iterator operations
// dereference
const match_type& dereference() const
{
return m_Match;
}
// increment
void increment()
{
match_type FindMatch=this->do_find( m_Next, m_End );
if(FindMatch.begin()==m_End && FindMatch.end()==m_End)
{
if(m_Match.end()==m_End)
{
// Mark iterator as eof
m_bEof=true;
}
}
m_Match=match_type( m_Next, FindMatch.begin() );
m_Next=FindMatch.end();
}
// comparison
bool equal( const split_iterator& Other ) const
{
bool bEof=eof();
bool bOtherEof=Other.eof();
return bEof || bOtherEof ? bEof==bOtherEof :
(
m_Match==Other.m_Match &&
m_Next==Other.m_Next &&
m_End==Other.m_End
);
}
public:
// operations
//! Eof check
/*!
Check the eof condition. Eof condition means that
there is nothing more to be searched i.e. find_iterator
is after the last match.
*/
bool eof() const
{
return this->is_null() || m_bEof;
}
private:
// Attributes
match_type m_Match;
input_iterator_type m_Next;
input_iterator_type m_End;
bool m_bEof;
};
//! split iterator construction helper
/*!
* Construct a split iterator to iterate through the specified collection
*/
template<typename RangeT, typename FinderT>
inline split_iterator<
BOOST_STRING_TYPENAME range_iterator<RangeT>::type>
make_split_iterator(
RangeT& Collection,
FinderT Finder)
{
return split_iterator<BOOST_STRING_TYPENAME range_iterator<RangeT>::type>(
Collection, Finder);
}
} // namespace algorithm
// pull names to the boost namespace
using algorithm::find_iterator;
using algorithm::make_find_iterator;
using algorithm::split_iterator;
using algorithm::make_split_iterator;
} // namespace boost
#endif // BOOST_STRING_FIND_ITERATOR_HPP

View File

@ -0,0 +1,270 @@
// Boost string_algo library finder.hpp header file ---------------------------//
// Copyright Pavol Droba 2002-2006.
//
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
// See http://www.boost.org/ for updates, documentation, and revision history.
#ifndef BOOST_STRING_FINDER_HPP
#define BOOST_STRING_FINDER_HPP
#include <boost/algorithm/string/config.hpp>
#include <boost/range/iterator_range_core.hpp>
#include <boost/range/begin.hpp>
#include <boost/range/end.hpp>
#include <boost/range/iterator.hpp>
#include <boost/range/const_iterator.hpp>
#include <boost/algorithm/string/constants.hpp>
#include <boost/algorithm/string/detail/finder.hpp>
#include <boost/algorithm/string/compare.hpp>
/*! \file
Defines Finder generators. Finder object is a functor which is able to
find a substring matching a specific criteria in the input.
Finders are used as a pluggable components for replace, find
and split facilities. This header contains generator functions
for finders provided in this library.
*/
namespace boost {
namespace algorithm {
// Finder generators ------------------------------------------//
//! "First" finder
/*!
Construct the \c first_finder. The finder searches for the first
occurrence of the string in a given input.
The result is given as an \c iterator_range delimiting the match.
\param Search A substring to be searched for.
\param Comp An element comparison predicate
\return An instance of the \c first_finder object
*/
template<typename RangeT>
inline detail::first_finderF<
BOOST_STRING_TYPENAME range_const_iterator<RangeT>::type,
is_equal>
first_finder( const RangeT& Search )
{
return
detail::first_finderF<
BOOST_STRING_TYPENAME
range_const_iterator<RangeT>::type,
is_equal>( ::boost::as_literal(Search), is_equal() ) ;
}
//! "First" finder
/*!
\overload
*/
template<typename RangeT,typename PredicateT>
inline detail::first_finderF<
BOOST_STRING_TYPENAME range_const_iterator<RangeT>::type,
PredicateT>
first_finder(
const RangeT& Search, PredicateT Comp )
{
return
detail::first_finderF<
BOOST_STRING_TYPENAME
range_const_iterator<RangeT>::type,
PredicateT>( ::boost::as_literal(Search), Comp );
}
//! "Last" finder
/*!
Construct the \c last_finder. The finder searches for the last
occurrence of the string in a given input.
The result is given as an \c iterator_range delimiting the match.
\param Search A substring to be searched for.
\param Comp An element comparison predicate
\return An instance of the \c last_finder object
*/
template<typename RangeT>
inline detail::last_finderF<
BOOST_STRING_TYPENAME range_const_iterator<RangeT>::type,
is_equal>
last_finder( const RangeT& Search )
{
return
detail::last_finderF<
BOOST_STRING_TYPENAME
range_const_iterator<RangeT>::type,
is_equal>( ::boost::as_literal(Search), is_equal() );
}
//! "Last" finder
/*!
\overload
*/
template<typename RangeT, typename PredicateT>
inline detail::last_finderF<
BOOST_STRING_TYPENAME range_const_iterator<RangeT>::type,
PredicateT>
last_finder( const RangeT& Search, PredicateT Comp )
{
return
detail::last_finderF<
BOOST_STRING_TYPENAME
range_const_iterator<RangeT>::type,
PredicateT>( ::boost::as_literal(Search), Comp ) ;
}
//! "Nth" finder
/*!
Construct the \c nth_finder. The finder searches for the n-th (zero-indexed)
occurrence of the string in a given input.
The result is given as an \c iterator_range delimiting the match.
\param Search A substring to be searched for.
\param Nth An index of the match to be find
\param Comp An element comparison predicate
\return An instance of the \c nth_finder object
*/
template<typename RangeT>
inline detail::nth_finderF<
BOOST_STRING_TYPENAME range_const_iterator<RangeT>::type,
is_equal>
nth_finder(
const RangeT& Search,
int Nth)
{
return
detail::nth_finderF<
BOOST_STRING_TYPENAME
range_const_iterator<RangeT>::type,
is_equal>( ::boost::as_literal(Search), Nth, is_equal() ) ;
}
//! "Nth" finder
/*!
\overload
*/
template<typename RangeT, typename PredicateT>
inline detail::nth_finderF<
BOOST_STRING_TYPENAME range_const_iterator<RangeT>::type,
PredicateT>
nth_finder(
const RangeT& Search,
int Nth,
PredicateT Comp )
{
return
detail::nth_finderF<
BOOST_STRING_TYPENAME
range_const_iterator<RangeT>::type,
PredicateT>( ::boost::as_literal(Search), Nth, Comp );
}
//! "Head" finder
/*!
Construct the \c head_finder. The finder returns a head of a given
input. The head is a prefix of a string up to n elements in
size. If an input has less then n elements, whole input is
considered a head.
The result is given as an \c iterator_range delimiting the match.
\param N The size of the head
\return An instance of the \c head_finder object
*/
inline detail::head_finderF
head_finder( int N )
{
return detail::head_finderF(N);
}
//! "Tail" finder
/*!
Construct the \c tail_finder. The finder returns a tail of a given
input. The tail is a suffix of a string up to n elements in
size. If an input has less then n elements, whole input is
considered a head.
The result is given as an \c iterator_range delimiting the match.
\param N The size of the head
\return An instance of the \c tail_finder object
*/
inline detail::tail_finderF
tail_finder( int N )
{
return detail::tail_finderF(N);
}
//! "Token" finder
/*!
Construct the \c token_finder. The finder searches for a token
specified by a predicate. It is similar to std::find_if
algorithm, with an exception that it return a range of
instead of a single iterator.
If "compress token mode" is enabled, adjacent matching tokens are
concatenated into one match. Thus the finder can be used to
search for continuous segments of characters satisfying the
given predicate.
The result is given as an \c iterator_range delimiting the match.
\param Pred An element selection predicate
\param eCompress Compress flag
\return An instance of the \c token_finder object
*/
template< typename PredicateT >
inline detail::token_finderF<PredicateT>
token_finder(
PredicateT Pred,
token_compress_mode_type eCompress=token_compress_off )
{
return detail::token_finderF<PredicateT>( Pred, eCompress );
}
//! "Range" finder
/*!
Construct the \c range_finder. The finder does not perform
any operation. It simply returns the given range for
any input.
\param Begin Beginning of the range
\param End End of the range
\param Range The range.
\return An instance of the \c range_finger object
*/
template< typename ForwardIteratorT >
inline detail::range_finderF<ForwardIteratorT>
range_finder(
ForwardIteratorT Begin,
ForwardIteratorT End )
{
return detail::range_finderF<ForwardIteratorT>( Begin, End );
}
//! "Range" finder
/*!
\overload
*/
template< typename ForwardIteratorT >
inline detail::range_finderF<ForwardIteratorT>
range_finder( iterator_range<ForwardIteratorT> Range )
{
return detail::range_finderF<ForwardIteratorT>( Range );
}
} // namespace algorithm
// pull the names to the boost namespace
using algorithm::first_finder;
using algorithm::last_finder;
using algorithm::nth_finder;
using algorithm::head_finder;
using algorithm::tail_finder;
using algorithm::token_finder;
using algorithm::range_finder;
} // namespace boost
#endif // BOOST_STRING_FINDER_HPP

View File

@ -0,0 +1,120 @@
// Boost string_algo library formatter.hpp header file ---------------------------//
// Copyright Pavol Droba 2002-2003.
//
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
// See http://www.boost.org/ for updates, documentation, and revision history.
#ifndef BOOST_STRING_FORMATTER_HPP
#define BOOST_STRING_FORMATTER_HPP
#include <boost/detail/iterator.hpp>
#include <boost/range/value_type.hpp>
#include <boost/range/iterator_range_core.hpp>
#include <boost/range/as_literal.hpp>
#include <boost/algorithm/string/detail/formatter.hpp>
/*! \file
Defines Formatter generators. Formatter is a functor which formats
a string according to given parameters. A Formatter works
in conjunction with a Finder. A Finder can provide additional information
for a specific Formatter. An example of such a cooperation is regex_finder
and regex_formatter.
Formatters are used as pluggable components for replace facilities.
This header contains generator functions for the Formatters provided in this library.
*/
namespace boost {
namespace algorithm {
// generic formatters ---------------------------------------------------------------//
//! Constant formatter
/*!
Constructs a \c const_formatter. Const formatter always returns
the same value, regardless of the parameter.
\param Format A predefined value used as a result for formatting
\return An instance of the \c const_formatter object.
*/
template<typename RangeT>
inline detail::const_formatF<
iterator_range<
BOOST_STRING_TYPENAME range_const_iterator<RangeT>::type> >
const_formatter(const RangeT& Format)
{
return detail::const_formatF<
iterator_range<
BOOST_STRING_TYPENAME range_const_iterator<RangeT>::type> >(::boost::as_literal(Format));
}
//! Identity formatter
/*!
Constructs an \c identity_formatter. Identity formatter always returns
the parameter.
\return An instance of the \c identity_formatter object.
*/
template<typename RangeT>
inline detail::identity_formatF<
iterator_range<
BOOST_STRING_TYPENAME range_const_iterator<RangeT>::type> >
identity_formatter()
{
return detail::identity_formatF<
iterator_range<
BOOST_STRING_TYPENAME range_const_iterator<RangeT>::type> >();
}
//! Empty formatter
/*!
Constructs an \c empty_formatter. Empty formatter always returns an empty
sequence.
\param Input container used to select a correct value_type for the
resulting empty_container<>.
\return An instance of the \c empty_formatter object.
*/
template<typename RangeT>
inline detail::empty_formatF<
BOOST_STRING_TYPENAME range_value<RangeT>::type>
empty_formatter(const RangeT&)
{
return detail::empty_formatF<
BOOST_STRING_TYPENAME range_value<RangeT>::type>();
}
//! Empty formatter
/*!
Constructs a \c dissect_formatter. Dissect formatter uses a specified finder
to extract a portion of the formatted sequence. The first finder's match is returned
as a result
\param Finder a finder used to select a portion of the formatted sequence
\return An instance of the \c dissect_formatter object.
*/
template<typename FinderT>
inline detail::dissect_formatF< FinderT >
dissect_formatter(const FinderT& Finder)
{
return detail::dissect_formatF<FinderT>(Finder);
}
} // namespace algorithm
// pull the names to the boost namespace
using algorithm::const_formatter;
using algorithm::identity_formatter;
using algorithm::empty_formatter;
using algorithm::dissect_formatter;
} // namespace boost
#endif // BOOST_FORMATTER_HPP

View File

@ -0,0 +1,193 @@
// Boost string_algo library iter_find.hpp header file ---------------------------//
// Copyright Pavol Droba 2002-2003.
//
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
// See http://www.boost.org/ for updates, documentation, and revision history.
#ifndef BOOST_STRING_ITER_FIND_HPP
#define BOOST_STRING_ITER_FIND_HPP
#include <boost/algorithm/string/config.hpp>
#include <algorithm>
#include <iterator>
#include <boost/iterator/transform_iterator.hpp>
#include <boost/range/iterator_range_core.hpp>
#include <boost/range/begin.hpp>
#include <boost/range/end.hpp>
#include <boost/range/iterator.hpp>
#include <boost/range/value_type.hpp>
#include <boost/range/as_literal.hpp>
#include <boost/algorithm/string/concept.hpp>
#include <boost/algorithm/string/find_iterator.hpp>
#include <boost/algorithm/string/detail/util.hpp>
/*! \file
Defines generic split algorithms. Split algorithms can be
used to divide a sequence into several part according
to a given criteria. Result is given as a 'container
of containers' where elements are copies or references
to extracted parts.
There are two algorithms provided. One iterates over matching
substrings, the other one over the gaps between these matches.
*/
namespace boost {
namespace algorithm {
// iterate find ---------------------------------------------------//
//! Iter find algorithm
/*!
This algorithm executes a given finder in iteration on the input,
until the end of input is reached, or no match is found.
Iteration is done using built-in find_iterator, so the real
searching is performed only when needed.
In each iteration new match is found and added to the result.
\param Result A 'container container' to contain the result of search.
Both outer and inner container must have constructor taking a pair
of iterators as an argument.
Typical type of the result is
\c std::vector<boost::iterator_range<iterator>>
(each element of such a vector will container a range delimiting
a match).
\param Input A container which will be searched.
\param Finder A Finder object used for searching
\return A reference to the result
\note Prior content of the result will be overwritten.
*/
template<
typename SequenceSequenceT,
typename RangeT,
typename FinderT >
inline SequenceSequenceT&
iter_find(
SequenceSequenceT& Result,
RangeT& Input,
FinderT Finder )
{
BOOST_CONCEPT_ASSERT((
FinderConcept<
FinderT,
BOOST_STRING_TYPENAME range_iterator<RangeT>::type>
));
iterator_range<BOOST_STRING_TYPENAME range_iterator<RangeT>::type> lit_input(::boost::as_literal(Input));
typedef BOOST_STRING_TYPENAME
range_iterator<RangeT>::type input_iterator_type;
typedef find_iterator<input_iterator_type> find_iterator_type;
typedef detail::copy_iterator_rangeF<
BOOST_STRING_TYPENAME
range_value<SequenceSequenceT>::type,
input_iterator_type> copy_range_type;
input_iterator_type InputEnd=::boost::end(lit_input);
typedef transform_iterator<copy_range_type, find_iterator_type>
transform_iter_type;
transform_iter_type itBegin=
::boost::make_transform_iterator(
find_iterator_type( ::boost::begin(lit_input), InputEnd, Finder ),
copy_range_type());
transform_iter_type itEnd=
::boost::make_transform_iterator(
find_iterator_type(),
copy_range_type());
SequenceSequenceT Tmp(itBegin, itEnd);
Result.swap(Tmp);
return Result;
}
// iterate split ---------------------------------------------------//
//! Split find algorithm
/*!
This algorithm executes a given finder in iteration on the input,
until the end of input is reached, or no match is found.
Iteration is done using built-in find_iterator, so the real
searching is performed only when needed.
Each match is used as a separator of segments. These segments are then
returned in the result.
\param Result A 'container container' to contain the result of search.
Both outer and inner container must have constructor taking a pair
of iterators as an argument.
Typical type of the result is
\c std::vector<boost::iterator_range<iterator>>
(each element of such a vector will container a range delimiting
a match).
\param Input A container which will be searched.
\param Finder A finder object used for searching
\return A reference to the result
\note Prior content of the result will be overwritten.
*/
template<
typename SequenceSequenceT,
typename RangeT,
typename FinderT >
inline SequenceSequenceT&
iter_split(
SequenceSequenceT& Result,
RangeT& Input,
FinderT Finder )
{
BOOST_CONCEPT_ASSERT((
FinderConcept<FinderT,
BOOST_STRING_TYPENAME range_iterator<RangeT>::type>
));
iterator_range<BOOST_STRING_TYPENAME range_iterator<RangeT>::type> lit_input(::boost::as_literal(Input));
typedef BOOST_STRING_TYPENAME
range_iterator<RangeT>::type input_iterator_type;
typedef split_iterator<input_iterator_type> find_iterator_type;
typedef detail::copy_iterator_rangeF<
BOOST_STRING_TYPENAME
range_value<SequenceSequenceT>::type,
input_iterator_type> copy_range_type;
input_iterator_type InputEnd=::boost::end(lit_input);
typedef transform_iterator<copy_range_type, find_iterator_type>
transform_iter_type;
transform_iter_type itBegin=
::boost::make_transform_iterator(
find_iterator_type( ::boost::begin(lit_input), InputEnd, Finder ),
copy_range_type() );
transform_iter_type itEnd=
::boost::make_transform_iterator(
find_iterator_type(),
copy_range_type() );
SequenceSequenceT Tmp(itBegin, itEnd);
Result.swap(Tmp);
return Result;
}
} // namespace algorithm
// pull names to the boost namespace
using algorithm::iter_find;
using algorithm::iter_split;
} // namespace boost
#endif // BOOST_STRING_ITER_FIND_HPP

View File

@ -0,0 +1,145 @@
// Boost string_algo library join.hpp header file ---------------------------//
// Copyright Pavol Droba 2002-2006.
//
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
// See http://www.boost.org/ for updates, documentation, and revision history.
#ifndef BOOST_STRING_JOIN_HPP
#define BOOST_STRING_JOIN_HPP
#include <boost/algorithm/string/config.hpp>
#include <boost/algorithm/string/detail/sequence.hpp>
#include <boost/range/value_type.hpp>
#include <boost/range/as_literal.hpp>
/*! \file
Defines join algorithm.
Join algorithm is a counterpart to split algorithms.
It joins strings from a 'list' by adding user defined separator.
Additionally there is a version that allows simple filtering
by providing a predicate.
*/
namespace boost {
namespace algorithm {
// join --------------------------------------------------------------//
//! Join algorithm
/*!
This algorithm joins all strings in a 'list' into one long string.
Segments are concatenated by given separator.
\param Input A container that holds the input strings. It must be a container-of-containers.
\param Separator A string that will separate the joined segments.
\return Concatenated string.
\note This function provides the strong exception-safety guarantee
*/
template< typename SequenceSequenceT, typename Range1T>
inline typename range_value<SequenceSequenceT>::type
join(
const SequenceSequenceT& Input,
const Range1T& Separator)
{
// Define working types
typedef typename range_value<SequenceSequenceT>::type ResultT;
typedef typename range_const_iterator<SequenceSequenceT>::type InputIteratorT;
// Parse input
InputIteratorT itBegin=::boost::begin(Input);
InputIteratorT itEnd=::boost::end(Input);
// Construct container to hold the result
ResultT Result;
// Append first element
if(itBegin!=itEnd)
{
detail::insert(Result, ::boost::end(Result), *itBegin);
++itBegin;
}
for(;itBegin!=itEnd; ++itBegin)
{
// Add separator
detail::insert(Result, ::boost::end(Result), ::boost::as_literal(Separator));
// Add element
detail::insert(Result, ::boost::end(Result), *itBegin);
}
return Result;
}
// join_if ----------------------------------------------------------//
//! Conditional join algorithm
/*!
This algorithm joins all strings in a 'list' into one long string.
Segments are concatenated by given separator. Only segments that
satisfy the predicate will be added to the result.
\param Input A container that holds the input strings. It must be a container-of-containers.
\param Separator A string that will separate the joined segments.
\param Pred A segment selection predicate
\return Concatenated string.
\note This function provides the strong exception-safety guarantee
*/
template< typename SequenceSequenceT, typename Range1T, typename PredicateT>
inline typename range_value<SequenceSequenceT>::type
join_if(
const SequenceSequenceT& Input,
const Range1T& Separator,
PredicateT Pred)
{
// Define working types
typedef typename range_value<SequenceSequenceT>::type ResultT;
typedef typename range_const_iterator<SequenceSequenceT>::type InputIteratorT;
// Parse input
InputIteratorT itBegin=::boost::begin(Input);
InputIteratorT itEnd=::boost::end(Input);
// Construct container to hold the result
ResultT Result;
// Roll to the first element that will be added
while(itBegin!=itEnd && !Pred(*itBegin)) ++itBegin;
// Add this element
if(itBegin!=itEnd)
{
detail::insert(Result, ::boost::end(Result), *itBegin);
++itBegin;
}
for(;itBegin!=itEnd; ++itBegin)
{
if(Pred(*itBegin))
{
// Add separator
detail::insert(Result, ::boost::end(Result), ::boost::as_literal(Separator));
// Add element
detail::insert(Result, ::boost::end(Result), *itBegin);
}
}
return Result;
}
} // namespace algorithm
// pull names to the boost namespace
using algorithm::join;
using algorithm::join_if;
} // namespace boost
#endif // BOOST_STRING_JOIN_HPP

View File

@ -0,0 +1,475 @@
// Boost string_algo library predicate.hpp header file ---------------------------//
// Copyright Pavol Droba 2002-2003.
//
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
// See http://www.boost.org/ for updates, documentation, and revision history.
#ifndef BOOST_STRING_PREDICATE_HPP
#define BOOST_STRING_PREDICATE_HPP
#include <boost/algorithm/string/config.hpp>
#include <boost/range/begin.hpp>
#include <boost/range/end.hpp>
#include <boost/range/iterator.hpp>
#include <boost/range/const_iterator.hpp>
#include <boost/range/as_literal.hpp>
#include <boost/range/iterator_range_core.hpp>
#include <boost/algorithm/string/compare.hpp>
#include <boost/algorithm/string/find.hpp>
#include <boost/algorithm/string/detail/predicate.hpp>
/*! \file boost/algorithm/string/predicate.hpp
Defines string-related predicates.
The predicates determine whether a substring is contained in the input string
under various conditions: a string starts with the substring, ends with the
substring, simply contains the substring or if both strings are equal.
Additionaly the algorithm \c all() checks all elements of a container to satisfy a
condition.
All predicates provide the strong exception guarantee.
*/
namespace boost {
namespace algorithm {
// starts_with predicate -----------------------------------------------//
//! 'Starts with' predicate
/*!
This predicate holds when the test string is a prefix of the Input.
In other words, if the input starts with the test.
When the optional predicate is specified, it is used for character-wise
comparison.
\param Input An input sequence
\param Test A test sequence
\param Comp An element comparison predicate
\return The result of the test
\note This function provides the strong exception-safety guarantee
*/
template<typename Range1T, typename Range2T, typename PredicateT>
inline bool starts_with(
const Range1T& Input,
const Range2T& Test,
PredicateT Comp)
{
iterator_range<BOOST_STRING_TYPENAME range_const_iterator<Range1T>::type> lit_input(::boost::as_literal(Input));
iterator_range<BOOST_STRING_TYPENAME range_const_iterator<Range2T>::type> lit_test(::boost::as_literal(Test));
typedef BOOST_STRING_TYPENAME
range_const_iterator<Range1T>::type Iterator1T;
typedef BOOST_STRING_TYPENAME
range_const_iterator<Range2T>::type Iterator2T;
Iterator1T InputEnd=::boost::end(lit_input);
Iterator2T TestEnd=::boost::end(lit_test);
Iterator1T it=::boost::begin(lit_input);
Iterator2T pit=::boost::begin(lit_test);
for(;
it!=InputEnd && pit!=TestEnd;
++it,++pit)
{
if( !(Comp(*it,*pit)) )
return false;
}
return pit==TestEnd;
}
//! 'Starts with' predicate
/*!
\overload
*/
template<typename Range1T, typename Range2T>
inline bool starts_with(
const Range1T& Input,
const Range2T& Test)
{
return ::boost::algorithm::starts_with(Input, Test, is_equal());
}
//! 'Starts with' predicate ( case insensitive )
/*!
This predicate holds when the test string is a prefix of the Input.
In other words, if the input starts with the test.
Elements are compared case insensitively.
\param Input An input sequence
\param Test A test sequence
\param Loc A locale used for case insensitive comparison
\return The result of the test
\note This function provides the strong exception-safety guarantee
*/
template<typename Range1T, typename Range2T>
inline bool istarts_with(
const Range1T& Input,
const Range2T& Test,
const std::locale& Loc=std::locale())
{
return ::boost::algorithm::starts_with(Input, Test, is_iequal(Loc));
}
// ends_with predicate -----------------------------------------------//
//! 'Ends with' predicate
/*!
This predicate holds when the test string is a suffix of the Input.
In other words, if the input ends with the test.
When the optional predicate is specified, it is used for character-wise
comparison.
\param Input An input sequence
\param Test A test sequence
\param Comp An element comparison predicate
\return The result of the test
\note This function provides the strong exception-safety guarantee
*/
template<typename Range1T, typename Range2T, typename PredicateT>
inline bool ends_with(
const Range1T& Input,
const Range2T& Test,
PredicateT Comp)
{
iterator_range<BOOST_STRING_TYPENAME range_const_iterator<Range1T>::type> lit_input(::boost::as_literal(Input));
iterator_range<BOOST_STRING_TYPENAME range_const_iterator<Range2T>::type> lit_test(::boost::as_literal(Test));
typedef BOOST_STRING_TYPENAME
range_const_iterator<Range1T>::type Iterator1T;
typedef BOOST_STRING_TYPENAME boost::detail::
iterator_traits<Iterator1T>::iterator_category category;
return detail::
ends_with_iter_select(
::boost::begin(lit_input),
::boost::end(lit_input),
::boost::begin(lit_test),
::boost::end(lit_test),
Comp,
category());
}
//! 'Ends with' predicate
/*!
\overload
*/
template<typename Range1T, typename Range2T>
inline bool ends_with(
const Range1T& Input,
const Range2T& Test)
{
return ::boost::algorithm::ends_with(Input, Test, is_equal());
}
//! 'Ends with' predicate ( case insensitive )
/*!
This predicate holds when the test container is a suffix of the Input.
In other words, if the input ends with the test.
Elements are compared case insensitively.
\param Input An input sequence
\param Test A test sequence
\param Loc A locale used for case insensitive comparison
\return The result of the test
\note This function provides the strong exception-safety guarantee
*/
template<typename Range1T, typename Range2T>
inline bool iends_with(
const Range1T& Input,
const Range2T& Test,
const std::locale& Loc=std::locale())
{
return ::boost::algorithm::ends_with(Input, Test, is_iequal(Loc));
}
// contains predicate -----------------------------------------------//
//! 'Contains' predicate
/*!
This predicate holds when the test container is contained in the Input.
When the optional predicate is specified, it is used for character-wise
comparison.
\param Input An input sequence
\param Test A test sequence
\param Comp An element comparison predicate
\return The result of the test
\note This function provides the strong exception-safety guarantee
*/
template<typename Range1T, typename Range2T, typename PredicateT>
inline bool contains(
const Range1T& Input,
const Range2T& Test,
PredicateT Comp)
{
iterator_range<BOOST_STRING_TYPENAME range_const_iterator<Range1T>::type> lit_input(::boost::as_literal(Input));
iterator_range<BOOST_STRING_TYPENAME range_const_iterator<Range2T>::type> lit_test(::boost::as_literal(Test));
if (::boost::empty(lit_test))
{
// Empty range is contained always
return true;
}
// Use the temporary variable to make VACPP happy
bool bResult=(::boost::algorithm::first_finder(lit_test,Comp)(::boost::begin(lit_input), ::boost::end(lit_input)));
return bResult;
}
//! 'Contains' predicate
/*!
\overload
*/
template<typename Range1T, typename Range2T>
inline bool contains(
const Range1T& Input,
const Range2T& Test)
{
return ::boost::algorithm::contains(Input, Test, is_equal());
}
//! 'Contains' predicate ( case insensitive )
/*!
This predicate holds when the test container is contained in the Input.
Elements are compared case insensitively.
\param Input An input sequence
\param Test A test sequence
\param Loc A locale used for case insensitive comparison
\return The result of the test
\note This function provides the strong exception-safety guarantee
*/
template<typename Range1T, typename Range2T>
inline bool icontains(
const Range1T& Input,
const Range2T& Test,
const std::locale& Loc=std::locale())
{
return ::boost::algorithm::contains(Input, Test, is_iequal(Loc));
}
// equals predicate -----------------------------------------------//
//! 'Equals' predicate
/*!
This predicate holds when the test container is equal to the
input container i.e. all elements in both containers are same.
When the optional predicate is specified, it is used for character-wise
comparison.
\param Input An input sequence
\param Test A test sequence
\param Comp An element comparison predicate
\return The result of the test
\note This is a two-way version of \c std::equal algorithm
\note This function provides the strong exception-safety guarantee
*/
template<typename Range1T, typename Range2T, typename PredicateT>
inline bool equals(
const Range1T& Input,
const Range2T& Test,
PredicateT Comp)
{
iterator_range<BOOST_STRING_TYPENAME range_const_iterator<Range1T>::type> lit_input(::boost::as_literal(Input));
iterator_range<BOOST_STRING_TYPENAME range_const_iterator<Range2T>::type> lit_test(::boost::as_literal(Test));
typedef BOOST_STRING_TYPENAME
range_const_iterator<Range1T>::type Iterator1T;
typedef BOOST_STRING_TYPENAME
range_const_iterator<Range2T>::type Iterator2T;
Iterator1T InputEnd=::boost::end(lit_input);
Iterator2T TestEnd=::boost::end(lit_test);
Iterator1T it=::boost::begin(lit_input);
Iterator2T pit=::boost::begin(lit_test);
for(;
it!=InputEnd && pit!=TestEnd;
++it,++pit)
{
if( !(Comp(*it,*pit)) )
return false;
}
return (pit==TestEnd) && (it==InputEnd);
}
//! 'Equals' predicate
/*!
\overload
*/
template<typename Range1T, typename Range2T>
inline bool equals(
const Range1T& Input,
const Range2T& Test)
{
return ::boost::algorithm::equals(Input, Test, is_equal());
}
//! 'Equals' predicate ( case insensitive )
/*!
This predicate holds when the test container is equal to the
input container i.e. all elements in both containers are same.
Elements are compared case insensitively.
\param Input An input sequence
\param Test A test sequence
\param Loc A locale used for case insensitive comparison
\return The result of the test
\note This is a two-way version of \c std::equal algorithm
\note This function provides the strong exception-safety guarantee
*/
template<typename Range1T, typename Range2T>
inline bool iequals(
const Range1T& Input,
const Range2T& Test,
const std::locale& Loc=std::locale())
{
return ::boost::algorithm::equals(Input, Test, is_iequal(Loc));
}
// lexicographical_compare predicate -----------------------------//
//! Lexicographical compare predicate
/*!
This predicate is an overload of std::lexicographical_compare
for range arguments
It check whether the first argument is lexicographically less
then the second one.
If the optional predicate is specified, it is used for character-wise
comparison
\param Arg1 First argument
\param Arg2 Second argument
\param Pred Comparison predicate
\return The result of the test
\note This function provides the strong exception-safety guarantee
*/
template<typename Range1T, typename Range2T, typename PredicateT>
inline bool lexicographical_compare(
const Range1T& Arg1,
const Range2T& Arg2,
PredicateT Pred)
{
iterator_range<BOOST_STRING_TYPENAME range_const_iterator<Range1T>::type> lit_arg1(::boost::as_literal(Arg1));
iterator_range<BOOST_STRING_TYPENAME range_const_iterator<Range2T>::type> lit_arg2(::boost::as_literal(Arg2));
return std::lexicographical_compare(
::boost::begin(lit_arg1),
::boost::end(lit_arg1),
::boost::begin(lit_arg2),
::boost::end(lit_arg2),
Pred);
}
//! Lexicographical compare predicate
/*!
\overload
*/
template<typename Range1T, typename Range2T>
inline bool lexicographical_compare(
const Range1T& Arg1,
const Range2T& Arg2)
{
return ::boost::algorithm::lexicographical_compare(Arg1, Arg2, is_less());
}
//! Lexicographical compare predicate (case-insensitive)
/*!
This predicate is an overload of std::lexicographical_compare
for range arguments.
It check whether the first argument is lexicographically less
then the second one.
Elements are compared case insensitively
\param Arg1 First argument
\param Arg2 Second argument
\param Loc A locale used for case insensitive comparison
\return The result of the test
\note This function provides the strong exception-safety guarantee
*/
template<typename Range1T, typename Range2T>
inline bool ilexicographical_compare(
const Range1T& Arg1,
const Range2T& Arg2,
const std::locale& Loc=std::locale())
{
return ::boost::algorithm::lexicographical_compare(Arg1, Arg2, is_iless(Loc));
}
// all predicate -----------------------------------------------//
//! 'All' predicate
/*!
This predicate holds it all its elements satisfy a given
condition, represented by the predicate.
\param Input An input sequence
\param Pred A predicate
\return The result of the test
\note This function provides the strong exception-safety guarantee
*/
template<typename RangeT, typename PredicateT>
inline bool all(
const RangeT& Input,
PredicateT Pred)
{
iterator_range<BOOST_STRING_TYPENAME range_const_iterator<RangeT>::type> lit_input(::boost::as_literal(Input));
typedef BOOST_STRING_TYPENAME
range_const_iterator<RangeT>::type Iterator1T;
Iterator1T InputEnd=::boost::end(lit_input);
for( Iterator1T It=::boost::begin(lit_input); It!=InputEnd; ++It)
{
if (!Pred(*It))
return false;
}
return true;
}
} // namespace algorithm
// pull names to the boost namespace
using algorithm::starts_with;
using algorithm::istarts_with;
using algorithm::ends_with;
using algorithm::iends_with;
using algorithm::contains;
using algorithm::icontains;
using algorithm::equals;
using algorithm::iequals;
using algorithm::all;
using algorithm::lexicographical_compare;
using algorithm::ilexicographical_compare;
} // namespace boost
#endif // BOOST_STRING_PREDICATE_HPP

View File

@ -0,0 +1,42 @@
// Boost string_algo library predicate_facade.hpp header file ---------------------------//
// Copyright Pavol Droba 2002-2003.
//
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
// See http://www.boost.org/ for updates, documentation, and revision history.
#ifndef BOOST_STRING_PREDICATE_FACADE_HPP
#define BOOST_STRING_PREDICATE_FACADE_HPP
#include <boost/algorithm/string/config.hpp>
/*
\file boost/algorith/string/predicate_facade.hpp
This file contains predicate_facade definition. This template class is used
to identify classification predicates, so they can be combined using
composition operators.
*/
namespace boost {
namespace algorithm {
// predicate facade ------------------------------------------------------//
//! Predicate facade
/*!
This class allows to recognize classification
predicates, so that they can be combined using
composition operators.
Every classification predicate must be derived from this class.
*/
template<typename Derived>
struct predicate_facade {};
} // namespace algorithm
} // namespace boost
#endif // BOOST_STRING_CLASSIFICATION_DETAIL_HPP

View File

@ -0,0 +1,646 @@
// Boost string_algo library regex.hpp header file ---------------------------//
// Copyright Pavol Droba 2002-2003.
//
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
// See http://www.boost.org/ for updates, documentation, and revision history.
#ifndef BOOST_STRING_REGEX_HPP
#define BOOST_STRING_REGEX_HPP
#include <boost/algorithm/string/config.hpp>
#include <boost/regex.hpp>
#include <boost/range/iterator_range_core.hpp>
#include <boost/range/begin.hpp>
#include <boost/range/end.hpp>
#include <boost/range/iterator.hpp>
#include <boost/range/as_literal.hpp>
#include <boost/algorithm/string/find_format.hpp>
#include <boost/algorithm/string/regex_find_format.hpp>
#include <boost/algorithm/string/formatter.hpp>
#include <boost/algorithm/string/iter_find.hpp>
/*! \file
Defines regex variants of the algorithms.
*/
namespace boost {
namespace algorithm {
// find_regex -----------------------------------------------//
//! Find regex algorithm
/*!
Search for a substring matching the given regex in the input.
\param Input A container which will be searched.
\param Rx A regular expression
\param Flags Regex options
\return
An \c iterator_range delimiting the match.
Returned iterator is either \c RangeT::iterator or
\c RangeT::const_iterator, depending on the constness of
the input parameter.
\note This function provides the strong exception-safety guarantee
*/
template<
typename RangeT,
typename CharT,
typename RegexTraitsT>
inline iterator_range<
BOOST_STRING_TYPENAME range_iterator<RangeT>::type >
find_regex(
RangeT& Input,
const basic_regex<CharT, RegexTraitsT>& Rx,
match_flag_type Flags=match_default )
{
iterator_range<BOOST_STRING_TYPENAME range_iterator<RangeT>::type> lit_input(::boost::as_literal(Input));
return ::boost::algorithm::regex_finder(Rx,Flags)(
::boost::begin(lit_input), ::boost::end(lit_input) );
}
// replace_regex --------------------------------------------------------------------//
//! Replace regex algorithm
/*!
Search for a substring matching given regex and format it with
the specified format.
The result is a modified copy of the input. It is returned as a sequence
or copied to the output iterator.
\param Output An output iterator to which the result will be copied
\param Input An input string
\param Rx A regular expression
\param Format Regex format definition
\param Flags Regex options
\return An output iterator pointing just after the last inserted character or
a modified copy of the input
\note The second variant of this function provides the strong exception-safety guarantee
*/
template<
typename OutputIteratorT,
typename RangeT,
typename CharT,
typename RegexTraitsT,
typename FormatStringTraitsT, typename FormatStringAllocatorT >
inline OutputIteratorT replace_regex_copy(
OutputIteratorT Output,
const RangeT& Input,
const basic_regex<CharT, RegexTraitsT>& Rx,
const std::basic_string<CharT, FormatStringTraitsT, FormatStringAllocatorT>& Format,
match_flag_type Flags=match_default | format_default )
{
return ::boost::algorithm::find_format_copy(
Output,
Input,
::boost::algorithm::regex_finder( Rx, Flags ),
::boost::algorithm::regex_formatter( Format, Flags ) );
}
//! Replace regex algorithm
/*!
\overload
*/
template<
typename SequenceT,
typename CharT,
typename RegexTraitsT,
typename FormatStringTraitsT, typename FormatStringAllocatorT >
inline SequenceT replace_regex_copy(
const SequenceT& Input,
const basic_regex<CharT, RegexTraitsT>& Rx,
const std::basic_string<CharT, FormatStringTraitsT, FormatStringAllocatorT>& Format,
match_flag_type Flags=match_default | format_default )
{
return ::boost::algorithm::find_format_copy(
Input,
::boost::algorithm::regex_finder( Rx, Flags ),
::boost::algorithm::regex_formatter( Format, Flags ) );
}
//! Replace regex algorithm
/*!
Search for a substring matching given regex and format it with
the specified format. The input string is modified in-place.
\param Input An input string
\param Rx A regular expression
\param Format Regex format definition
\param Flags Regex options
*/
template<
typename SequenceT,
typename CharT,
typename RegexTraitsT,
typename FormatStringTraitsT, typename FormatStringAllocatorT >
inline void replace_regex(
SequenceT& Input,
const basic_regex<CharT, RegexTraitsT>& Rx,
const std::basic_string<CharT, FormatStringTraitsT, FormatStringAllocatorT>& Format,
match_flag_type Flags=match_default | format_default )
{
::boost::algorithm::find_format(
Input,
::boost::algorithm::regex_finder( Rx, Flags ),
::boost::algorithm::regex_formatter( Format, Flags ) );
}
// replace_all_regex --------------------------------------------------------------------//
//! Replace all regex algorithm
/*!
Format all substrings, matching given regex, with the specified format.
The result is a modified copy of the input. It is returned as a sequence
or copied to the output iterator.
\param Output An output iterator to which the result will be copied
\param Input An input string
\param Rx A regular expression
\param Format Regex format definition
\param Flags Regex options
\return An output iterator pointing just after the last inserted character or
a modified copy of the input
\note The second variant of this function provides the strong exception-safety guarantee
*/
template<
typename OutputIteratorT,
typename RangeT,
typename CharT,
typename RegexTraitsT,
typename FormatStringTraitsT, typename FormatStringAllocatorT >
inline OutputIteratorT replace_all_regex_copy(
OutputIteratorT Output,
const RangeT& Input,
const basic_regex<CharT, RegexTraitsT>& Rx,
const std::basic_string<CharT, FormatStringTraitsT, FormatStringAllocatorT>& Format,
match_flag_type Flags=match_default | format_default )
{
return ::boost::algorithm::find_format_all_copy(
Output,
Input,
::boost::algorithm::regex_finder( Rx, Flags ),
::boost::algorithm::regex_formatter( Format, Flags ) );
}
//! Replace all regex algorithm
/*!
\overload
*/
template<
typename SequenceT,
typename CharT,
typename RegexTraitsT,
typename FormatStringTraitsT, typename FormatStringAllocatorT >
inline SequenceT replace_all_regex_copy(
const SequenceT& Input,
const basic_regex<CharT, RegexTraitsT>& Rx,
const std::basic_string<CharT, FormatStringTraitsT, FormatStringAllocatorT>& Format,
match_flag_type Flags=match_default | format_default )
{
return ::boost::algorithm::find_format_all_copy(
Input,
::boost::algorithm::regex_finder( Rx, Flags ),
::boost::algorithm::regex_formatter( Format, Flags ) );
}
//! Replace all regex algorithm
/*!
Format all substrings, matching given regex, with the specified format.
The input string is modified in-place.
\param Input An input string
\param Rx A regular expression
\param Format Regex format definition
\param Flags Regex options
*/
template<
typename SequenceT,
typename CharT,
typename RegexTraitsT,
typename FormatStringTraitsT, typename FormatStringAllocatorT >
inline void replace_all_regex(
SequenceT& Input,
const basic_regex<CharT, RegexTraitsT>& Rx,
const std::basic_string<CharT, FormatStringTraitsT, FormatStringAllocatorT>& Format,
match_flag_type Flags=match_default | format_default )
{
::boost::algorithm::find_format_all(
Input,
::boost::algorithm::regex_finder( Rx, Flags ),
::boost::algorithm::regex_formatter( Format, Flags ) );
}
// erase_regex --------------------------------------------------------------------//
//! Erase regex algorithm
/*!
Remove a substring matching given regex from the input.
The result is a modified copy of the input. It is returned as a sequence
or copied to the output iterator.
\param Output An output iterator to which the result will be copied
\param Input An input string
\param Rx A regular expression
\param Flags Regex options
\return An output iterator pointing just after the last inserted character or
a modified copy of the input
\note The second variant of this function provides the strong exception-safety guarantee
*/
template<
typename OutputIteratorT,
typename RangeT,
typename CharT,
typename RegexTraitsT >
inline OutputIteratorT erase_regex_copy(
OutputIteratorT Output,
const RangeT& Input,
const basic_regex<CharT, RegexTraitsT>& Rx,
match_flag_type Flags=match_default )
{
return ::boost::algorithm::find_format_copy(
Output,
Input,
::boost::algorithm::regex_finder( Rx, Flags ),
::boost::algorithm::empty_formatter( Input ) );
}
//! Erase regex algorithm
/*!
\overload
*/
template<
typename SequenceT,
typename CharT,
typename RegexTraitsT >
inline SequenceT erase_regex_copy(
const SequenceT& Input,
const basic_regex<CharT, RegexTraitsT>& Rx,
match_flag_type Flags=match_default )
{
return ::boost::algorithm::find_format_copy(
Input,
::boost::algorithm::regex_finder( Rx, Flags ),
::boost::algorithm::empty_formatter( Input ) );
}
//! Erase regex algorithm
/*!
Remove a substring matching given regex from the input.
The input string is modified in-place.
\param Input An input string
\param Rx A regular expression
\param Flags Regex options
*/
template<
typename SequenceT,
typename CharT,
typename RegexTraitsT >
inline void erase_regex(
SequenceT& Input,
const basic_regex<CharT, RegexTraitsT>& Rx,
match_flag_type Flags=match_default )
{
::boost::algorithm::find_format(
Input,
::boost::algorithm::regex_finder( Rx, Flags ),
::boost::algorithm::empty_formatter( Input ) );
}
// erase_all_regex --------------------------------------------------------------------//
//! Erase all regex algorithm
/*!
Erase all substrings, matching given regex, from the input.
The result is a modified copy of the input. It is returned as a sequence
or copied to the output iterator.
\param Output An output iterator to which the result will be copied
\param Input An input string
\param Rx A regular expression
\param Flags Regex options
\return An output iterator pointing just after the last inserted character or
a modified copy of the input
\note The second variant of this function provides the strong exception-safety guarantee
*/
template<
typename OutputIteratorT,
typename RangeT,
typename CharT,
typename RegexTraitsT >
inline OutputIteratorT erase_all_regex_copy(
OutputIteratorT Output,
const RangeT& Input,
const basic_regex<CharT, RegexTraitsT>& Rx,
match_flag_type Flags=match_default )
{
return ::boost::algorithm::find_format_all_copy(
Output,
Input,
::boost::algorithm::regex_finder( Rx, Flags ),
::boost::algorithm::empty_formatter( Input ) );
}
//! Erase all regex algorithm
/*!
\overload
*/
template<
typename SequenceT,
typename CharT,
typename RegexTraitsT >
inline SequenceT erase_all_regex_copy(
const SequenceT& Input,
const basic_regex<CharT, RegexTraitsT>& Rx,
match_flag_type Flags=match_default )
{
return ::boost::algorithm::find_format_all_copy(
Input,
::boost::algorithm::regex_finder( Rx, Flags ),
::boost::algorithm::empty_formatter( Input ) );
}
//! Erase all regex algorithm
/*!
Erase all substrings, matching given regex, from the input.
The input string is modified in-place.
\param Input An input string
\param Rx A regular expression
\param Flags Regex options
*/
template<
typename SequenceT,
typename CharT,
typename RegexTraitsT>
inline void erase_all_regex(
SequenceT& Input,
const basic_regex<CharT, RegexTraitsT>& Rx,
match_flag_type Flags=match_default )
{
::boost::algorithm::find_format_all(
Input,
::boost::algorithm::regex_finder( Rx, Flags ),
::boost::algorithm::empty_formatter( Input ) );
}
// find_all_regex ------------------------------------------------------------------//
//! Find all regex algorithm
/*!
This algorithm finds all substrings matching the give regex
in the input.
Each part is copied and added as a new element to the output container.
Thus the result container must be able to hold copies
of the matches (in a compatible structure like std::string) or
a reference to it (e.g. using the iterator range class).
Examples of such a container are \c std::vector<std::string>
or \c std::list<boost::iterator_range<std::string::iterator>>
\param Result A container that can hold copies of references to the substrings.
\param Input A container which will be searched.
\param Rx A regular expression
\param Flags Regex options
\return A reference to the result
\note Prior content of the result will be overwritten.
\note This function provides the strong exception-safety guarantee
*/
template<
typename SequenceSequenceT,
typename RangeT,
typename CharT,
typename RegexTraitsT >
inline SequenceSequenceT& find_all_regex(
SequenceSequenceT& Result,
const RangeT& Input,
const basic_regex<CharT, RegexTraitsT>& Rx,
match_flag_type Flags=match_default )
{
return ::boost::algorithm::iter_find(
Result,
Input,
::boost::algorithm::regex_finder(Rx,Flags) );
}
// split_regex ------------------------------------------------------------------//
//! Split regex algorithm
/*!
Tokenize expression. This function is equivalent to C strtok. Input
sequence is split into tokens, separated by separators. Separator
is an every match of the given regex.
Each part is copied and added as a new element to the output container.
Thus the result container must be able to hold copies
of the matches (in a compatible structure like std::string) or
a reference to it (e.g. using the iterator range class).
Examples of such a container are \c std::vector<std::string>
or \c std::list<boost::iterator_range<std::string::iterator>>
\param Result A container that can hold copies of references to the substrings.
\param Input A container which will be searched.
\param Rx A regular expression
\param Flags Regex options
\return A reference to the result
\note Prior content of the result will be overwritten.
\note This function provides the strong exception-safety guarantee
*/
template<
typename SequenceSequenceT,
typename RangeT,
typename CharT,
typename RegexTraitsT >
inline SequenceSequenceT& split_regex(
SequenceSequenceT& Result,
const RangeT& Input,
const basic_regex<CharT, RegexTraitsT>& Rx,
match_flag_type Flags=match_default )
{
return ::boost::algorithm::iter_split(
Result,
Input,
::boost::algorithm::regex_finder(Rx,Flags) );
}
// join_if ------------------------------------------------------------------//
#ifndef BOOST_NO_FUNCTION_TEMPLATE_ORDERING
//! Conditional join algorithm
/*!
This algorithm joins all strings in a 'list' into one long string.
Segments are concatenated by given separator. Only segments that
match the given regular expression will be added to the result
This is a specialization of join_if algorithm.
\param Input A container that holds the input strings. It must be a container-of-containers.
\param Separator A string that will separate the joined segments.
\param Rx A regular expression
\param Flags Regex options
\return Concatenated string.
\note This function provides the strong exception-safety guarantee
*/
template<
typename SequenceSequenceT,
typename Range1T,
typename CharT,
typename RegexTraitsT >
inline typename range_value<SequenceSequenceT>::type
join_if(
const SequenceSequenceT& Input,
const Range1T& Separator,
const basic_regex<CharT, RegexTraitsT>& Rx,
match_flag_type Flags=match_default )
{
// Define working types
typedef typename range_value<SequenceSequenceT>::type ResultT;
typedef typename range_const_iterator<SequenceSequenceT>::type InputIteratorT;
// Parse input
InputIteratorT itBegin=::boost::begin(Input);
InputIteratorT itEnd=::boost::end(Input);
// Construct container to hold the result
ResultT Result;
// Roll to the first element that will be added
while(
itBegin!=itEnd &&
!::boost::regex_match(::boost::begin(*itBegin), ::boost::end(*itBegin), Rx, Flags)) ++itBegin;
// Add this element
if(itBegin!=itEnd)
{
detail::insert(Result, ::boost::end(Result), *itBegin);
++itBegin;
}
for(;itBegin!=itEnd; ++itBegin)
{
if(::boost::regex_match(::boost::begin(*itBegin), ::boost::end(*itBegin), Rx, Flags))
{
// Add separator
detail::insert(Result, ::boost::end(Result), ::boost::as_literal(Separator));
// Add element
detail::insert(Result, ::boost::end(Result), *itBegin);
}
}
return Result;
}
#else // BOOST_NO_FUNCTION_TEMPLATE_ORDERING
//! Conditional join algorithm
/*!
This algorithm joins all strings in a 'list' into one long string.
Segments are concatenated by given separator. Only segments that
match the given regular expression will be added to the result
This is a specialization of join_if algorithm.
\param Input A container that holds the input strings. It must be a container-of-containers.
\param Separator A string that will separate the joined segments.
\param Rx A regular expression
\param Flags Regex options
\return Concatenated string.
\note This function provides the strong exception-safety guarantee
*/
template<
typename SequenceSequenceT,
typename Range1T,
typename CharT,
typename RegexTraitsT >
inline typename range_value<SequenceSequenceT>::type
join_if_regex(
const SequenceSequenceT& Input,
const Range1T& Separator,
const basic_regex<CharT, RegexTraitsT>& Rx,
match_flag_type Flags=match_default )
{
// Define working types
typedef typename range_value<SequenceSequenceT>::type ResultT;
typedef typename range_const_iterator<SequenceSequenceT>::type InputIteratorT;
// Parse input
InputIteratorT itBegin=::boost::begin(Input);
InputIteratorT itEnd=::boost::end(Input);
// Construct container to hold the result
ResultT Result;
// Roll to the first element that will be added
while(
itBegin!=itEnd &&
!::boost::regex_match(::boost::begin(*itBegin), ::boost::end(*itBegin), Rx, Flags)) ++itBegin;
// Add this element
if(itBegin!=itEnd)
{
detail::insert(Result, ::boost::end(Result), *itBegin);
++itBegin;
}
for(;itBegin!=itEnd; ++itBegin)
{
if(::boost::regex_match(::boost::begin(*itBegin), ::boost::end(*itBegin), Rx, Flags))
{
// Add separator
detail::insert(Result, ::boost::end(Result), ::boost::as_literal(Separator));
// Add element
detail::insert(Result, ::boost::end(Result), *itBegin);
}
}
return Result;
}
#endif // BOOST_NO_FUNCTION_TEMPLATE_ORDERING
} // namespace algorithm
// pull names into the boost namespace
using algorithm::find_regex;
using algorithm::replace_regex;
using algorithm::replace_regex_copy;
using algorithm::replace_all_regex;
using algorithm::replace_all_regex_copy;
using algorithm::erase_regex;
using algorithm::erase_regex_copy;
using algorithm::erase_all_regex;
using algorithm::erase_all_regex_copy;
using algorithm::find_all_regex;
using algorithm::split_regex;
#ifndef BOOST_NO_FUNCTION_TEMPLATE_ORDERING
using algorithm::join_if;
#else // BOOST_NO_FUNCTION_TEMPLATE_ORDERING
using algorithm::join_if_regex;
#endif // BOOST_NO_FUNCTION_TEMPLATE_ORDERING
} // namespace boost
#endif // BOOST_STRING_REGEX_HPP

View File

@ -0,0 +1,90 @@
// Boost string_algo library regex_find_format.hpp header file ---------------------------//
// Copyright Pavol Droba 2002-2003.
//
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
// See http://www.boost.org/ for updates, documentation, and revision history.
#ifndef BOOST_STRING_REGEX_FIND_FORMAT_HPP
#define BOOST_STRING_REGEX_FIND_FORMAT_HPP
#include <boost/algorithm/string/config.hpp>
#include <boost/regex.hpp>
#include <boost/algorithm/string/detail/finder_regex.hpp>
#include <boost/algorithm/string/detail/formatter_regex.hpp>
/*! \file
Defines the \c regex_finder and \c regex_formatter generators. These two functors
are designed to work together. \c regex_formatter uses additional information
about a match contained in the regex_finder search result.
*/
namespace boost {
namespace algorithm {
// regex_finder -----------------------------------------------//
//! "Regex" finder
/*!
Construct the \c regex_finder. Finder uses the regex engine to search
for a match.
Result is given in \c regex_search_result. This is an extension
of the iterator_range. In addition it contains match results
from the \c regex_search algorithm.
\param Rx A regular expression
\param MatchFlags Regex search options
\return An instance of the \c regex_finder object
*/
template<
typename CharT,
typename RegexTraitsT>
inline detail::find_regexF< basic_regex<CharT, RegexTraitsT> >
regex_finder(
const basic_regex<CharT, RegexTraitsT>& Rx,
match_flag_type MatchFlags=match_default )
{
return detail::
find_regexF<
basic_regex<CharT, RegexTraitsT> >( Rx, MatchFlags );
}
// regex_formater ---------------------------------------------//
//! Regex formatter
/*!
Construct the \c regex_formatter. Regex formatter uses the regex engine to
format a match found by the \c regex_finder.
This formatted it designed to closely cooperate with \c regex_finder.
\param Format Regex format definition
\param Flags Format flags
\return An instance of the \c regex_formatter functor
*/
template<
typename CharT,
typename TraitsT, typename AllocT >
inline detail::regex_formatF< std::basic_string< CharT, TraitsT, AllocT > >
regex_formatter(
const std::basic_string<CharT, TraitsT, AllocT>& Format,
match_flag_type Flags=format_default )
{
return
detail::regex_formatF< std::basic_string<CharT, TraitsT, AllocT> >(
Format,
Flags );
}
} // namespace algorithm
// pull the names to the boost namespace
using algorithm::regex_finder;
using algorithm::regex_formatter;
} // namespace boost
#endif // BOOST_STRING_REGEX_FIND_FORMAT_HPP

View File

@ -0,0 +1,926 @@
// Boost string_algo library replace.hpp header file ---------------------------//
// Copyright Pavol Droba 2002-2006.
//
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
// See http://www.boost.org/ for updates, documentation, and revision history.
#ifndef BOOST_STRING_REPLACE_HPP
#define BOOST_STRING_REPLACE_HPP
#include <boost/algorithm/string/config.hpp>
#include <boost/range/iterator_range_core.hpp>
#include <boost/range/begin.hpp>
#include <boost/range/end.hpp>
#include <boost/range/iterator.hpp>
#include <boost/range/const_iterator.hpp>
#include <boost/algorithm/string/find_format.hpp>
#include <boost/algorithm/string/finder.hpp>
#include <boost/algorithm/string/formatter.hpp>
#include <boost/algorithm/string/compare.hpp>
/*! \file
Defines various replace algorithms. Each algorithm replaces
part(s) of the input according to set of searching and replace criteria.
*/
namespace boost {
namespace algorithm {
// replace_range --------------------------------------------------------------------//
//! Replace range algorithm
/*!
Replace the given range in the input string.
The result is a modified copy of the input. It is returned as a sequence
or copied to the output iterator.
\param Output An output iterator to which the result will be copied
\param Input An input string
\param SearchRange A range in the input to be substituted
\param Format A substitute string
\return An output iterator pointing just after the last inserted character or
a modified copy of the input
\note The second variant of this function provides the strong exception-safety guarantee
*/
template<
typename OutputIteratorT,
typename Range1T,
typename Range2T>
inline OutputIteratorT replace_range_copy(
OutputIteratorT Output,
const Range1T& Input,
const iterator_range<
BOOST_STRING_TYPENAME
range_const_iterator<Range1T>::type>& SearchRange,
const Range2T& Format)
{
return ::boost::algorithm::find_format_copy(
Output,
Input,
::boost::algorithm::range_finder(SearchRange),
::boost::algorithm::const_formatter(Format));
}
//! Replace range algorithm
/*!
\overload
*/
template<typename SequenceT, typename RangeT>
inline SequenceT replace_range_copy(
const SequenceT& Input,
const iterator_range<
BOOST_STRING_TYPENAME
range_const_iterator<SequenceT>::type>& SearchRange,
const RangeT& Format)
{
return ::boost::algorithm::find_format_copy(
Input,
::boost::algorithm::range_finder(SearchRange),
::boost::algorithm::const_formatter(Format));
}
//! Replace range algorithm
/*!
Replace the given range in the input string.
The input sequence is modified in-place.
\param Input An input string
\param SearchRange A range in the input to be substituted
\param Format A substitute string
*/
template<typename SequenceT, typename RangeT>
inline void replace_range(
SequenceT& Input,
const iterator_range<
BOOST_STRING_TYPENAME
range_iterator<SequenceT>::type>& SearchRange,
const RangeT& Format)
{
::boost::algorithm::find_format(
Input,
::boost::algorithm::range_finder(SearchRange),
::boost::algorithm::const_formatter(Format));
}
// replace_first --------------------------------------------------------------------//
//! Replace first algorithm
/*!
Replace the first match of the search substring in the input
with the format string.
The result is a modified copy of the input. It is returned as a sequence
or copied to the output iterator.
\param Output An output iterator to which the result will be copied
\param Input An input string
\param Search A substring to be searched for
\param Format A substitute string
\return An output iterator pointing just after the last inserted character or
a modified copy of the input
\note The second variant of this function provides the strong exception-safety guarantee
*/
template<
typename OutputIteratorT,
typename Range1T,
typename Range2T,
typename Range3T>
inline OutputIteratorT replace_first_copy(
OutputIteratorT Output,
const Range1T& Input,
const Range2T& Search,
const Range3T& Format)
{
return ::boost::algorithm::find_format_copy(
Output,
Input,
::boost::algorithm::first_finder(Search),
::boost::algorithm::const_formatter(Format) );
}
//! Replace first algorithm
/*!
\overload
*/
template<typename SequenceT, typename Range1T, typename Range2T>
inline SequenceT replace_first_copy(
const SequenceT& Input,
const Range1T& Search,
const Range2T& Format )
{
return ::boost::algorithm::find_format_copy(
Input,
::boost::algorithm::first_finder(Search),
::boost::algorithm::const_formatter(Format) );
}
//! Replace first algorithm
/*!
replace the first match of the search substring in the input
with the format string. The input sequence is modified in-place.
\param Input An input string
\param Search A substring to be searched for
\param Format A substitute string
*/
template<typename SequenceT, typename Range1T, typename Range2T>
inline void replace_first(
SequenceT& Input,
const Range1T& Search,
const Range2T& Format )
{
::boost::algorithm::find_format(
Input,
::boost::algorithm::first_finder(Search),
::boost::algorithm::const_formatter(Format) );
}
// replace_first ( case insensitive ) ---------------------------------------------//
//! Replace first algorithm ( case insensitive )
/*!
Replace the first match of the search substring in the input
with the format string.
The result is a modified copy of the input. It is returned as a sequence
or copied to the output iterator.
Searching is case insensitive.
\param Output An output iterator to which the result will be copied
\param Input An input string
\param Search A substring to be searched for
\param Format A substitute string
\param Loc A locale used for case insensitive comparison
\return An output iterator pointing just after the last inserted character or
a modified copy of the input
\note The second variant of this function provides the strong exception-safety guarantee
*/
template<
typename OutputIteratorT,
typename Range1T,
typename Range2T,
typename Range3T>
inline OutputIteratorT ireplace_first_copy(
OutputIteratorT Output,
const Range1T& Input,
const Range2T& Search,
const Range3T& Format,
const std::locale& Loc=std::locale() )
{
return ::boost::algorithm::find_format_copy(
Output,
Input,
::boost::algorithm::first_finder(Search, is_iequal(Loc)),
::boost::algorithm::const_formatter(Format) );
}
//! Replace first algorithm ( case insensitive )
/*!
\overload
*/
template<typename SequenceT, typename Range2T, typename Range1T>
inline SequenceT ireplace_first_copy(
const SequenceT& Input,
const Range2T& Search,
const Range1T& Format,
const std::locale& Loc=std::locale() )
{
return ::boost::algorithm::find_format_copy(
Input,
::boost::algorithm::first_finder(Search, is_iequal(Loc)),
::boost::algorithm::const_formatter(Format) );
}
//! Replace first algorithm ( case insensitive )
/*!
Replace the first match of the search substring in the input
with the format string. Input sequence is modified in-place.
Searching is case insensitive.
\param Input An input string
\param Search A substring to be searched for
\param Format A substitute string
\param Loc A locale used for case insensitive comparison
*/
template<typename SequenceT, typename Range1T, typename Range2T>
inline void ireplace_first(
SequenceT& Input,
const Range1T& Search,
const Range2T& Format,
const std::locale& Loc=std::locale() )
{
::boost::algorithm::find_format(
Input,
::boost::algorithm::first_finder(Search, is_iequal(Loc)),
::boost::algorithm::const_formatter(Format) );
}
// replace_last --------------------------------------------------------------------//
//! Replace last algorithm
/*!
Replace the last match of the search string in the input
with the format string.
The result is a modified copy of the input. It is returned as a sequence
or copied to the output iterator.
\param Output An output iterator to which the result will be copied
\param Input An input string
\param Search A substring to be searched for
\param Format A substitute string
\return An output iterator pointing just after the last inserted character or
a modified copy of the input
\note The second variant of this function provides the strong exception-safety guarantee
*/
template<
typename OutputIteratorT,
typename Range1T,
typename Range2T,
typename Range3T>
inline OutputIteratorT replace_last_copy(
OutputIteratorT Output,
const Range1T& Input,
const Range2T& Search,
const Range3T& Format )
{
return ::boost::algorithm::find_format_copy(
Output,
Input,
::boost::algorithm::last_finder(Search),
::boost::algorithm::const_formatter(Format) );
}
//! Replace last algorithm
/*!
\overload
*/
template<typename SequenceT, typename Range1T, typename Range2T>
inline SequenceT replace_last_copy(
const SequenceT& Input,
const Range1T& Search,
const Range2T& Format )
{
return ::boost::algorithm::find_format_copy(
Input,
::boost::algorithm::last_finder(Search),
::boost::algorithm::const_formatter(Format) );
}
//! Replace last algorithm
/*!
Replace the last match of the search string in the input
with the format string. Input sequence is modified in-place.
\param Input An input string
\param Search A substring to be searched for
\param Format A substitute string
*/
template<typename SequenceT, typename Range1T, typename Range2T>
inline void replace_last(
SequenceT& Input,
const Range1T& Search,
const Range2T& Format )
{
::boost::algorithm::find_format(
Input,
::boost::algorithm::last_finder(Search),
::boost::algorithm::const_formatter(Format) );
}
// replace_last ( case insensitive ) -----------------------------------------------//
//! Replace last algorithm ( case insensitive )
/*!
Replace the last match of the search string in the input
with the format string.
The result is a modified copy of the input. It is returned as a sequence
or copied to the output iterator.
Searching is case insensitive.
\param Output An output iterator to which the result will be copied
\param Input An input string
\param Search A substring to be searched for
\param Format A substitute string
\param Loc A locale used for case insensitive comparison
\return An output iterator pointing just after the last inserted character or
a modified copy of the input
\note The second variant of this function provides the strong exception-safety guarantee
*/
template<
typename OutputIteratorT,
typename Range1T,
typename Range2T,
typename Range3T>
inline OutputIteratorT ireplace_last_copy(
OutputIteratorT Output,
const Range1T& Input,
const Range2T& Search,
const Range3T& Format,
const std::locale& Loc=std::locale() )
{
return ::boost::algorithm::find_format_copy(
Output,
Input,
::boost::algorithm::last_finder(Search, is_iequal(Loc)),
::boost::algorithm::const_formatter(Format) );
}
//! Replace last algorithm ( case insensitive )
/*!
\overload
*/
template<typename SequenceT, typename Range1T, typename Range2T>
inline SequenceT ireplace_last_copy(
const SequenceT& Input,
const Range1T& Search,
const Range2T& Format,
const std::locale& Loc=std::locale() )
{
return ::boost::algorithm::find_format_copy(
Input,
::boost::algorithm::last_finder(Search, is_iequal(Loc)),
::boost::algorithm::const_formatter(Format) );
}
//! Replace last algorithm ( case insensitive )
/*!
Replace the last match of the search string in the input
with the format string.The input sequence is modified in-place.
Searching is case insensitive.
\param Input An input string
\param Search A substring to be searched for
\param Format A substitute string
\param Loc A locale used for case insensitive comparison
*/
template<typename SequenceT, typename Range1T, typename Range2T>
inline void ireplace_last(
SequenceT& Input,
const Range1T& Search,
const Range2T& Format,
const std::locale& Loc=std::locale() )
{
::boost::algorithm::find_format(
Input,
::boost::algorithm::last_finder(Search, is_iequal(Loc)),
::boost::algorithm::const_formatter(Format) );
}
// replace_nth --------------------------------------------------------------------//
//! Replace nth algorithm
/*!
Replace an Nth (zero-indexed) match of the search string in the input
with the format string.
The result is a modified copy of the input. It is returned as a sequence
or copied to the output iterator.
\param Output An output iterator to which the result will be copied
\param Input An input string
\param Search A substring to be searched for
\param Nth An index of the match to be replaced. The index is 0-based.
For negative N, matches are counted from the end of string.
\param Format A substitute string
\return An output iterator pointing just after the last inserted character or
a modified copy of the input
\note The second variant of this function provides the strong exception-safety guarantee
*/
template<
typename OutputIteratorT,
typename Range1T,
typename Range2T,
typename Range3T>
inline OutputIteratorT replace_nth_copy(
OutputIteratorT Output,
const Range1T& Input,
const Range2T& Search,
int Nth,
const Range3T& Format )
{
return ::boost::algorithm::find_format_copy(
Output,
Input,
::boost::algorithm::nth_finder(Search, Nth),
::boost::algorithm::const_formatter(Format) );
}
//! Replace nth algorithm
/*!
\overload
*/
template<typename SequenceT, typename Range1T, typename Range2T>
inline SequenceT replace_nth_copy(
const SequenceT& Input,
const Range1T& Search,
int Nth,
const Range2T& Format )
{
return ::boost::algorithm::find_format_copy(
Input,
::boost::algorithm::nth_finder(Search, Nth),
::boost::algorithm::const_formatter(Format) );
}
//! Replace nth algorithm
/*!
Replace an Nth (zero-indexed) match of the search string in the input
with the format string. Input sequence is modified in-place.
\param Input An input string
\param Search A substring to be searched for
\param Nth An index of the match to be replaced. The index is 0-based.
For negative N, matches are counted from the end of string.
\param Format A substitute string
*/
template<typename SequenceT, typename Range1T, typename Range2T>
inline void replace_nth(
SequenceT& Input,
const Range1T& Search,
int Nth,
const Range2T& Format )
{
::boost::algorithm::find_format(
Input,
::boost::algorithm::nth_finder(Search, Nth),
::boost::algorithm::const_formatter(Format) );
}
// replace_nth ( case insensitive ) -----------------------------------------------//
//! Replace nth algorithm ( case insensitive )
/*!
Replace an Nth (zero-indexed) match of the search string in the input
with the format string.
The result is a modified copy of the input. It is returned as a sequence
or copied to the output iterator.
Searching is case insensitive.
\param Output An output iterator to which the result will be copied
\param Input An input string
\param Search A substring to be searched for
\param Nth An index of the match to be replaced. The index is 0-based.
For negative N, matches are counted from the end of string.
\param Format A substitute string
\param Loc A locale used for case insensitive comparison
\return An output iterator pointing just after the last inserted character or
a modified copy of the input
\note The second variant of this function provides the strong exception-safety guarantee
*/
template<
typename OutputIteratorT,
typename Range1T,
typename Range2T,
typename Range3T>
inline OutputIteratorT ireplace_nth_copy(
OutputIteratorT Output,
const Range1T& Input,
const Range2T& Search,
int Nth,
const Range3T& Format,
const std::locale& Loc=std::locale() )
{
return ::boost::algorithm::find_format_copy(
Output,
Input,
::boost::algorithm::nth_finder(Search, Nth, is_iequal(Loc) ),
::boost::algorithm::const_formatter(Format) );
}
//! Replace nth algorithm ( case insensitive )
/*!
\overload
*/
template<typename SequenceT, typename Range1T, typename Range2T>
inline SequenceT ireplace_nth_copy(
const SequenceT& Input,
const Range1T& Search,
int Nth,
const Range2T& Format,
const std::locale& Loc=std::locale() )
{
return ::boost::algorithm::find_format_copy(
Input,
::boost::algorithm::nth_finder(Search, Nth, is_iequal(Loc)),
::boost::algorithm::const_formatter(Format) );
}
//! Replace nth algorithm ( case insensitive )
/*!
Replace an Nth (zero-indexed) match of the search string in the input
with the format string. Input sequence is modified in-place.
Searching is case insensitive.
\param Input An input string
\param Search A substring to be searched for
\param Nth An index of the match to be replaced. The index is 0-based.
For negative N, matches are counted from the end of string.
\param Format A substitute string
\param Loc A locale used for case insensitive comparison
*/
template<typename SequenceT, typename Range1T, typename Range2T>
inline void ireplace_nth(
SequenceT& Input,
const Range1T& Search,
int Nth,
const Range2T& Format,
const std::locale& Loc=std::locale() )
{
::boost::algorithm::find_format(
Input,
::boost::algorithm::nth_finder(Search, Nth, is_iequal(Loc)),
::boost::algorithm::const_formatter(Format) );
}
// replace_all --------------------------------------------------------------------//
//! Replace all algorithm
/*!
Replace all occurrences of the search string in the input
with the format string.
The result is a modified copy of the input. It is returned as a sequence
or copied to the output iterator.
\param Output An output iterator to which the result will be copied
\param Input An input string
\param Search A substring to be searched for
\param Format A substitute string
\return An output iterator pointing just after the last inserted character or
a modified copy of the input
\note The second variant of this function provides the strong exception-safety guarantee
*/
template<
typename OutputIteratorT,
typename Range1T,
typename Range2T,
typename Range3T>
inline OutputIteratorT replace_all_copy(
OutputIteratorT Output,
const Range1T& Input,
const Range2T& Search,
const Range3T& Format )
{
return ::boost::algorithm::find_format_all_copy(
Output,
Input,
::boost::algorithm::first_finder(Search),
::boost::algorithm::const_formatter(Format) );
}
//! Replace all algorithm
/*!
\overload
*/
template<typename SequenceT, typename Range1T, typename Range2T>
inline SequenceT replace_all_copy(
const SequenceT& Input,
const Range1T& Search,
const Range2T& Format )
{
return ::boost::algorithm::find_format_all_copy(
Input,
::boost::algorithm::first_finder(Search),
::boost::algorithm::const_formatter(Format) );
}
//! Replace all algorithm
/*!
Replace all occurrences of the search string in the input
with the format string. The input sequence is modified in-place.
\param Input An input string
\param Search A substring to be searched for
\param Format A substitute string
*/
template<typename SequenceT, typename Range1T, typename Range2T>
inline void replace_all(
SequenceT& Input,
const Range1T& Search,
const Range2T& Format )
{
::boost::algorithm::find_format_all(
Input,
::boost::algorithm::first_finder(Search),
::boost::algorithm::const_formatter(Format) );
}
// replace_all ( case insensitive ) -----------------------------------------------//
//! Replace all algorithm ( case insensitive )
/*!
Replace all occurrences of the search string in the input
with the format string.
The result is a modified copy of the input. It is returned as a sequence
or copied to the output iterator.
Searching is case insensitive.
\param Output An output iterator to which the result will be copied
\param Input An input string
\param Search A substring to be searched for
\param Format A substitute string
\param Loc A locale used for case insensitive comparison
\return An output iterator pointing just after the last inserted character or
a modified copy of the input
\note The second variant of this function provides the strong exception-safety guarantee
*/
template<
typename OutputIteratorT,
typename Range1T,
typename Range2T,
typename Range3T>
inline OutputIteratorT ireplace_all_copy(
OutputIteratorT Output,
const Range1T& Input,
const Range2T& Search,
const Range3T& Format,
const std::locale& Loc=std::locale() )
{
return ::boost::algorithm::find_format_all_copy(
Output,
Input,
::boost::algorithm::first_finder(Search, is_iequal(Loc)),
::boost::algorithm::const_formatter(Format) );
}
//! Replace all algorithm ( case insensitive )
/*!
\overload
*/
template<typename SequenceT, typename Range1T, typename Range2T>
inline SequenceT ireplace_all_copy(
const SequenceT& Input,
const Range1T& Search,
const Range2T& Format,
const std::locale& Loc=std::locale() )
{
return ::boost::algorithm::find_format_all_copy(
Input,
::boost::algorithm::first_finder(Search, is_iequal(Loc)),
::boost::algorithm::const_formatter(Format) );
}
//! Replace all algorithm ( case insensitive )
/*!
Replace all occurrences of the search string in the input
with the format string.The input sequence is modified in-place.
Searching is case insensitive.
\param Input An input string
\param Search A substring to be searched for
\param Format A substitute string
\param Loc A locale used for case insensitive comparison
*/
template<typename SequenceT, typename Range1T, typename Range2T>
inline void ireplace_all(
SequenceT& Input,
const Range1T& Search,
const Range2T& Format,
const std::locale& Loc=std::locale() )
{
::boost::algorithm::find_format_all(
Input,
::boost::algorithm::first_finder(Search, is_iequal(Loc)),
::boost::algorithm::const_formatter(Format) );
}
// replace_head --------------------------------------------------------------------//
//! Replace head algorithm
/*!
Replace the head of the input with the given format string.
The head is a prefix of a string of given size.
If the sequence is shorter then required, whole string if
considered to be the head.
The result is a modified copy of the input. It is returned as a sequence
or copied to the output iterator.
\param Output An output iterator to which the result will be copied
\param Input An input string
\param N Length of the head.
For N>=0, at most N characters are extracted.
For N<0, size(Input)-|N| characters are extracted.
\param Format A substitute string
\return An output iterator pointing just after the last inserted character or
a modified copy of the input
\note The second variant of this function provides the strong exception-safety guarantee
*/
template<
typename OutputIteratorT,
typename Range1T,
typename Range2T>
inline OutputIteratorT replace_head_copy(
OutputIteratorT Output,
const Range1T& Input,
int N,
const Range2T& Format )
{
return ::boost::algorithm::find_format_copy(
Output,
Input,
::boost::algorithm::head_finder(N),
::boost::algorithm::const_formatter(Format) );
}
//! Replace head algorithm
/*!
\overload
*/
template<typename SequenceT, typename RangeT>
inline SequenceT replace_head_copy(
const SequenceT& Input,
int N,
const RangeT& Format )
{
return ::boost::algorithm::find_format_copy(
Input,
::boost::algorithm::head_finder(N),
::boost::algorithm::const_formatter(Format) );
}
//! Replace head algorithm
/*!
Replace the head of the input with the given format string.
The head is a prefix of a string of given size.
If the sequence is shorter then required, the whole string is
considered to be the head. The input sequence is modified in-place.
\param Input An input string
\param N Length of the head.
For N>=0, at most N characters are extracted.
For N<0, size(Input)-|N| characters are extracted.
\param Format A substitute string
*/
template<typename SequenceT, typename RangeT>
inline void replace_head(
SequenceT& Input,
int N,
const RangeT& Format )
{
::boost::algorithm::find_format(
Input,
::boost::algorithm::head_finder(N),
::boost::algorithm::const_formatter(Format) );
}
// replace_tail --------------------------------------------------------------------//
//! Replace tail algorithm
/*!
Replace the tail of the input with the given format string.
The tail is a suffix of a string of given size.
If the sequence is shorter then required, whole string is
considered to be the tail.
The result is a modified copy of the input. It is returned as a sequence
or copied to the output iterator.
\param Output An output iterator to which the result will be copied
\param Input An input string
\param N Length of the tail.
For N>=0, at most N characters are extracted.
For N<0, size(Input)-|N| characters are extracted.
\param Format A substitute string
\return An output iterator pointing just after the last inserted character or
a modified copy of the input
\note The second variant of this function provides the strong exception-safety guarantee
*/
template<
typename OutputIteratorT,
typename Range1T,
typename Range2T>
inline OutputIteratorT replace_tail_copy(
OutputIteratorT Output,
const Range1T& Input,
int N,
const Range2T& Format )
{
return ::boost::algorithm::find_format_copy(
Output,
Input,
::boost::algorithm::tail_finder(N),
::boost::algorithm::const_formatter(Format) );
}
//! Replace tail algorithm
/*!
\overload
*/
template<typename SequenceT, typename RangeT>
inline SequenceT replace_tail_copy(
const SequenceT& Input,
int N,
const RangeT& Format )
{
return ::boost::algorithm::find_format_copy(
Input,
::boost::algorithm::tail_finder(N),
::boost::algorithm::const_formatter(Format) );
}
//! Replace tail algorithm
/*!
Replace the tail of the input with the given format sequence.
The tail is a suffix of a string of given size.
If the sequence is shorter then required, the whole string is
considered to be the tail. The input sequence is modified in-place.
\param Input An input string
\param N Length of the tail.
For N>=0, at most N characters are extracted.
For N<0, size(Input)-|N| characters are extracted.
\param Format A substitute string
*/
template<typename SequenceT, typename RangeT>
inline void replace_tail(
SequenceT& Input,
int N,
const RangeT& Format )
{
::boost::algorithm::find_format(
Input,
::boost::algorithm::tail_finder(N),
::boost::algorithm::const_formatter(Format) );
}
} // namespace algorithm
// pull names to the boost namespace
using algorithm::replace_range_copy;
using algorithm::replace_range;
using algorithm::replace_first_copy;
using algorithm::replace_first;
using algorithm::ireplace_first_copy;
using algorithm::ireplace_first;
using algorithm::replace_last_copy;
using algorithm::replace_last;
using algorithm::ireplace_last_copy;
using algorithm::ireplace_last;
using algorithm::replace_nth_copy;
using algorithm::replace_nth;
using algorithm::ireplace_nth_copy;
using algorithm::ireplace_nth;
using algorithm::replace_all_copy;
using algorithm::replace_all;
using algorithm::ireplace_all_copy;
using algorithm::ireplace_all;
using algorithm::replace_head_copy;
using algorithm::replace_head;
using algorithm::replace_tail_copy;
using algorithm::replace_tail;
} // namespace boost
#endif // BOOST_REPLACE_HPP

View File

@ -0,0 +1,120 @@
// Boost string_algo library sequence_traits.hpp header file ---------------------------//
// Copyright Pavol Droba 2002-2003.
//
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
// See http://www.boost.org/ for updates, documentation, and revision history.
#ifndef BOOST_STRING_SEQUENCE_TRAITS_HPP
#define BOOST_STRING_SEQUENCE_TRAITS_HPP
#include <boost/config.hpp>
#include <boost/mpl/bool.hpp>
#include <boost/algorithm/string/yes_no_type.hpp>
/*! \file
Traits defined in this header are used by various algorithms to achieve
better performance for specific containers.
Traits provide fail-safe defaults. If a container supports some of these
features, it is possible to specialize the specific trait for this container.
For lacking compilers, it is possible of define an override for a specific tester
function.
Due to a language restriction, it is not currently possible to define specializations for
stl containers without including the corresponding header. To decrease the overhead
needed by this inclusion, user can selectively include a specialization
header for a specific container. They are located in boost/algorithm/string/stl
directory. Alternatively she can include boost/algorithm/string/std_collection_traits.hpp
header which contains specializations for all stl containers.
*/
namespace boost {
namespace algorithm {
// sequence traits -----------------------------------------------//
//! Native replace trait
/*!
This trait specifies that the sequence has \c std::string like replace method
*/
template< typename T >
class has_native_replace
{
public:
# if BOOST_WORKAROUND( __IBMCPP__, <= 600 )
enum { value = false };
# else
BOOST_STATIC_CONSTANT(bool, value=false);
# endif // BOOST_WORKAROUND( __IBMCPP__, <= 600 )
typedef mpl::bool_<has_native_replace<T>::value> type;
};
//! Stable iterators trait
/*!
This trait specifies that the sequence has stable iterators. It means
that operations like insert/erase/replace do not invalidate iterators.
*/
template< typename T >
class has_stable_iterators
{
public:
# if BOOST_WORKAROUND( __IBMCPP__, <= 600 )
enum { value = false };
# else
BOOST_STATIC_CONSTANT(bool, value=false);
# endif // BOOST_WORKAROUND( __IBMCPP__, <= 600 )
typedef mpl::bool_<has_stable_iterators<T>::value> type;
};
//! Const time insert trait
/*!
This trait specifies that the sequence's insert method has
constant time complexity.
*/
template< typename T >
class has_const_time_insert
{
public:
# if BOOST_WORKAROUND( __IBMCPP__, <= 600 )
enum { value = false };
# else
BOOST_STATIC_CONSTANT(bool, value=false);
# endif // BOOST_WORKAROUND( __IBMCPP__, <= 600 )
typedef mpl::bool_<has_const_time_insert<T>::value> type;
};
//! Const time erase trait
/*!
This trait specifies that the sequence's erase method has
constant time complexity.
*/
template< typename T >
class has_const_time_erase
{
public:
# if BOOST_WORKAROUND( __IBMCPP__, <= 600 )
enum { value = false };
# else
BOOST_STATIC_CONSTANT(bool, value=false);
# endif // BOOST_WORKAROUND( __IBMCPP__, <= 600 )
typedef mpl::bool_<has_const_time_erase<T>::value> type;
};
} // namespace algorithm
} // namespace boost
#endif // BOOST_STRING_SEQUENCE_TRAITS_HPP

View File

@ -0,0 +1,163 @@
// Boost string_algo library split.hpp header file ---------------------------//
// Copyright Pavol Droba 2002-2006.
//
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
// See http://www.boost.org/ for updates, documentation, and revision history.
#ifndef BOOST_STRING_SPLIT_HPP
#define BOOST_STRING_SPLIT_HPP
#include <boost/algorithm/string/config.hpp>
#include <boost/algorithm/string/iter_find.hpp>
#include <boost/algorithm/string/finder.hpp>
#include <boost/algorithm/string/compare.hpp>
/*! \file
Defines basic split algorithms.
Split algorithms can be used to divide a string
into several parts according to given criteria.
Each part is copied and added as a new element to the
output container.
Thus the result container must be able to hold copies
of the matches (in a compatible structure like std::string) or
a reference to it (e.g. using the iterator range class).
Examples of such a container are \c std::vector<std::string>
or \c std::list<boost::iterator_range<std::string::iterator>>
*/
namespace boost {
namespace algorithm {
// find_all ------------------------------------------------------------//
//! Find all algorithm
/*!
This algorithm finds all occurrences of the search string
in the input.
Each part is copied and added as a new element to the
output container.
Thus the result container must be able to hold copies
of the matches (in a compatible structure like std::string) or
a reference to it (e.g. using the iterator range class).
Examples of such a container are \c std::vector<std::string>
or \c std::list<boost::iterator_range<std::string::iterator>>
\param Result A container that can hold copies of references to the substrings
\param Input A container which will be searched.
\param Search A substring to be searched for.
\return A reference the result
\note Prior content of the result will be overwritten.
\note This function provides the strong exception-safety guarantee
*/
template< typename SequenceSequenceT, typename Range1T, typename Range2T >
inline SequenceSequenceT& find_all(
SequenceSequenceT& Result,
Range1T& Input,
const Range2T& Search)
{
return ::boost::algorithm::iter_find(
Result,
Input,
::boost::algorithm::first_finder(Search) );
}
//! Find all algorithm ( case insensitive )
/*!
This algorithm finds all occurrences of the search string
in the input.
Each part is copied and added as a new element to the
output container. Thus the result container must be able to hold copies
of the matches (in a compatible structure like std::string) or
a reference to it (e.g. using the iterator range class).
Examples of such a container are \c std::vector<std::string>
or \c std::list<boost::iterator_range<std::string::iterator>>
Searching is case insensitive.
\param Result A container that can hold copies of references to the substrings
\param Input A container which will be searched.
\param Search A substring to be searched for.
\param Loc A locale used for case insensitive comparison
\return A reference the result
\note Prior content of the result will be overwritten.
\note This function provides the strong exception-safety guarantee
*/
template< typename SequenceSequenceT, typename Range1T, typename Range2T >
inline SequenceSequenceT& ifind_all(
SequenceSequenceT& Result,
Range1T& Input,
const Range2T& Search,
const std::locale& Loc=std::locale() )
{
return ::boost::algorithm::iter_find(
Result,
Input,
::boost::algorithm::first_finder(Search, is_iequal(Loc) ) );
}
// tokenize -------------------------------------------------------------//
//! Split algorithm
/*!
Tokenize expression. This function is equivalent to C strtok. Input
sequence is split into tokens, separated by separators. Separators
are given by means of the predicate.
Each part is copied and added as a new element to the
output container.
Thus the result container must be able to hold copies
of the matches (in a compatible structure like std::string) or
a reference to it (e.g. using the iterator range class).
Examples of such a container are \c std::vector<std::string>
or \c std::list<boost::iterator_range<std::string::iterator>>
\param Result A container that can hold copies of references to the substrings
\param Input A container which will be searched.
\param Pred A predicate to identify separators. This predicate is
supposed to return true if a given element is a separator.
\param eCompress If eCompress argument is set to token_compress_on, adjacent
separators are merged together. Otherwise, every two separators
delimit a token.
\return A reference the result
\note Prior content of the result will be overwritten.
\note This function provides the strong exception-safety guarantee
*/
template< typename SequenceSequenceT, typename RangeT, typename PredicateT >
inline SequenceSequenceT& split(
SequenceSequenceT& Result,
RangeT& Input,
PredicateT Pred,
token_compress_mode_type eCompress=token_compress_off )
{
return ::boost::algorithm::iter_split(
Result,
Input,
::boost::algorithm::token_finder( Pred, eCompress ) );
}
} // namespace algorithm
// pull names to the boost namespace
using algorithm::find_all;
using algorithm::ifind_all;
using algorithm::split;
} // namespace boost
#endif // BOOST_STRING_SPLIT_HPP

View File

@ -0,0 +1,68 @@
// Boost string_algo library list_traits.hpp header file ---------------------------//
// Copyright Pavol Droba 2002-2003.
//
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
// See http://www.boost.org/ for updates, documentation, and revision history.
#ifndef BOOST_STRING_STD_LIST_TRAITS_HPP
#define BOOST_STRING_STD_LIST_TRAITS_HPP
#include <boost/algorithm/string/yes_no_type.hpp>
#include <list>
#include <boost/algorithm/string/sequence_traits.hpp>
namespace boost {
namespace algorithm {
// std::list<> traits -----------------------------------------------//
// stable iterators trait
template<typename T, typename AllocT>
class has_stable_iterators< ::std::list<T,AllocT> >
{
public:
#if BOOST_WORKAROUND( __IBMCPP__, <= 600 )
enum { value = true };
#else
BOOST_STATIC_CONSTANT(bool, value=true);
#endif // BOOST_WORKAROUND( __IBMCPP__, <= 600 )
typedef mpl::bool_<has_stable_iterators<T>::value> type;
};
// const time insert trait
template<typename T, typename AllocT>
class has_const_time_insert< ::std::list<T,AllocT> >
{
public:
#if BOOST_WORKAROUND( __IBMCPP__, <= 600 )
enum { value = true };
#else
BOOST_STATIC_CONSTANT(bool, value=true);
#endif // BOOST_WORKAROUND( __IBMCPP__, <= 600 )
typedef mpl::bool_<has_const_time_insert<T>::value> type;
};
// const time erase trait
template<typename T, typename AllocT>
class has_const_time_erase< ::std::list<T,AllocT> >
{
public:
#if BOOST_WORKAROUND( __IBMCPP__, <= 600 )
enum { value = true };
#else
BOOST_STATIC_CONSTANT(bool, value=true);
#endif // BOOST_WORKAROUND( __IBMCPP__, <= 600 )
typedef mpl::bool_<has_const_time_erase<T>::value> type;
};
} // namespace algorithm
} // namespace boost
#endif // BOOST_STRING_STD_LIST_TRAITS_HPP

View File

@ -0,0 +1,81 @@
// Boost string_algo library string_traits.hpp header file ---------------------------//
// Copyright Pavol Droba 2002-2003.
//
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
// See http://www.boost.org/ for updates, documentation, and revision history.
#ifndef BOOST_STRING_STD_ROPE_TRAITS_HPP
#define BOOST_STRING_STD_ROPE_TRAITS_HPP
#include <boost/algorithm/string/yes_no_type.hpp>
#include <rope>
#include <boost/algorithm/string/sequence_traits.hpp>
namespace boost {
namespace algorithm {
// SGI's std::rope<> traits -----------------------------------------------//
// native replace trait
template<typename T, typename TraitsT, typename AllocT>
class has_native_replace< std::rope<T,TraitsT,AllocT> >
{
public:
#if BOOST_WORKAROUND( __IBMCPP__, <= 600 )
enum { value = true };
#else
BOOST_STATIC_CONSTANT(bool, value=true);
#endif // BOOST_WORKAROUND( __IBMCPP__, <= 600 )
typedef mpl::bool_<value> type;
};
// stable iterators trait
template<typename T, typename TraitsT, typename AllocT>
class has_stable_iterators< std::rope<T,TraitsT,AllocT> >
{
public:
#if BOOST_WORKAROUND( __IBMCPP__, <= 600 )
enum { value = true };
#else
BOOST_STATIC_CONSTANT(bool, value=true);
#endif // BOOST_WORKAROUND( __IBMCPP__, <= 600 )
typedef mpl::bool_<value> type;
};
// const time insert trait
template<typename T, typename TraitsT, typename AllocT>
class has_const_time_insert< std::rope<T,TraitsT,AllocT> >
{
public:
#if BOOST_WORKAROUND( __IBMCPP__, <= 600 )
enum { value = true };
#else
BOOST_STATIC_CONSTANT(bool, value=true);
#endif // BOOST_WORKAROUND( __IBMCPP__, <= 600 )
typedef mpl::bool_<value> type;
};
// const time erase trait
template<typename T, typename TraitsT, typename AllocT>
class has_const_time_erase< std::rope<T,TraitsT,AllocT> >
{
public:
#if BOOST_WORKAROUND( __IBMCPP__, <= 600 )
enum { value = true };
#else
BOOST_STATIC_CONSTANT(bool, value=true);
#endif // BOOST_WORKAROUND( __IBMCPP__, <= 600 )
typedef mpl::bool_<value> type;
};
} // namespace algorithm
} // namespace boost
#endif // BOOST_STRING_ROPE_TRAITS_HPP

View File

@ -0,0 +1,69 @@
// Boost string_algo library slist_traits.hpp header file ---------------------------//
// Copyright Pavol Droba 2002-2003.
//
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
// See http://www.boost.org/ for updates, documentation, and revision history.
#ifndef BOOST_STRING_STD_SLIST_TRAITS_HPP
#define BOOST_STRING_STD_SLIST_TRAITS_HPP
#include <boost/algorithm/string/config.hpp>
#include <boost/algorithm/string/yes_no_type.hpp>
#include BOOST_SLIST_HEADER
#include <boost/algorithm/string/sequence_traits.hpp>
namespace boost {
namespace algorithm {
// SGI's std::slist<> traits -----------------------------------------------//
// stable iterators trait
template<typename T, typename AllocT>
class has_stable_iterators< BOOST_STD_EXTENSION_NAMESPACE::slist<T,AllocT> >
{
public:
#if BOOST_WORKAROUND( __IBMCPP__, <= 600 )
enum { value = true };
#else
BOOST_STATIC_CONSTANT(bool, value=true);
#endif // BOOST_WORKAROUND( __IBMCPP__, <= 600 )
typedef mpl::bool_<has_stable_iterators<T>::value> type;
};
// const time insert trait
template<typename T, typename AllocT>
class has_const_time_insert< BOOST_STD_EXTENSION_NAMESPACE::slist<T,AllocT> >
{
public:
#if BOOST_WORKAROUND( __IBMCPP__, <= 600 )
enum { value = true };
#else
BOOST_STATIC_CONSTANT(bool, value=true);
#endif // BOOST_WORKAROUND( __IBMCPP__, <= 600 )
typedef mpl::bool_<has_const_time_insert<T>::value> type;
};
// const time erase trait
template<typename T, typename AllocT>
class has_const_time_erase< BOOST_STD_EXTENSION_NAMESPACE::slist<T,AllocT> >
{
public:
#if BOOST_WORKAROUND( __IBMCPP__, <= 600 )
enum { value = true };
#else
BOOST_STATIC_CONSTANT(bool, value=true);
#endif // BOOST_WORKAROUND( __IBMCPP__, <= 600 )
typedef mpl::bool_<has_const_time_erase<T>::value> type;
};
} // namespace algorithm
} // namespace boost
#endif // BOOST_STRING_STD_LIST_TRAITS_HPP

View File

@ -0,0 +1,44 @@
// Boost string_algo library string_traits.hpp header file ---------------------------//
// Copyright Pavol Droba 2002-2003.
//
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
// See http://www.boost.org/ for updates, documentation, and revision history.
#ifndef BOOST_STRING_STD_STRING_TRAITS_HPP
#define BOOST_STRING_STD_STRING_TRAITS_HPP
#include <boost/algorithm/string/yes_no_type.hpp>
#include <string>
#include <boost/algorithm/string/sequence_traits.hpp>
namespace boost {
namespace algorithm {
// std::basic_string<> traits -----------------------------------------------//
// native replace trait
template<typename T, typename TraitsT, typename AllocT>
class has_native_replace< std::basic_string<T, TraitsT, AllocT> >
{
public:
#if BOOST_WORKAROUND( __IBMCPP__, <= 600 )
enum { value = true } ;
#else
BOOST_STATIC_CONSTANT(bool, value=true);
#endif // BOOST_WORKAROUND( __IBMCPP__, <= 600 )
typedef mpl::bool_<has_native_replace<T>::value> type;
};
} // namespace algorithm
} // namespace boost
#endif // BOOST_STRING_LIST_TRAITS_HPP

View File

@ -0,0 +1,26 @@
// Boost string_algo library std_containers_traits.hpp header file ---------------------------//
// Copyright Pavol Droba 2002-2003.
//
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
// See http://www.boost.org/ for updates, documentation, and revision history.
#ifndef BOOST_STRING_STD_CONTAINERS_TRAITS_HPP
#define BOOST_STRING_STD_CONTAINERS_TRAITS_HPP
/*!\file
This file includes sequence traits for stl containers.
*/
#include <boost/config.hpp>
#include <boost/algorithm/string/std/string_traits.hpp>
#include <boost/algorithm/string/std/list_traits.hpp>
#ifdef BOOST_HAS_SLIST
# include <boost/algorithm/string/std/slist_traits.hpp>
#endif
#endif // BOOST_STRING_STD_CONTAINERS_TRAITS_HPP

View File

@ -0,0 +1,398 @@
// Boost string_algo library trim.hpp header file ---------------------------//
// Copyright Pavol Droba 2002-2003.
//
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
// See http://www.boost.org/ for updates, documentation, and revision history.
#ifndef BOOST_STRING_TRIM_HPP
#define BOOST_STRING_TRIM_HPP
#include <boost/algorithm/string/config.hpp>
#include <boost/range/begin.hpp>
#include <boost/range/end.hpp>
#include <boost/range/const_iterator.hpp>
#include <boost/range/as_literal.hpp>
#include <boost/range/iterator_range_core.hpp>
#include <boost/algorithm/string/detail/trim.hpp>
#include <boost/algorithm/string/classification.hpp>
#include <locale>
/*! \file
Defines trim algorithms.
Trim algorithms are used to remove trailing and leading spaces from a
sequence (string). Space is recognized using given locales.
Parametric (\c _if) variants use a predicate (functor) to select which characters
are to be trimmed..
Functions take a selection predicate as a parameter, which is used to determine
whether a character is a space. Common predicates are provided in classification.hpp header.
*/
namespace boost {
namespace algorithm {
// left trim -----------------------------------------------//
//! Left trim - parametric
/*!
Remove all leading spaces from the input.
The supplied predicate is used to determine which characters are considered spaces.
The result is a trimmed copy of the input. It is returned as a sequence
or copied to the output iterator
\param Output An output iterator to which the result will be copied
\param Input An input range
\param IsSpace A unary predicate identifying spaces
\return
An output iterator pointing just after the last inserted character or
a copy of the input
\note The second variant of this function provides the strong exception-safety guarantee
*/
template<typename OutputIteratorT, typename RangeT, typename PredicateT>
inline OutputIteratorT trim_left_copy_if(
OutputIteratorT Output,
const RangeT& Input,
PredicateT IsSpace)
{
iterator_range<BOOST_STRING_TYPENAME range_const_iterator<RangeT>::type> lit_range(::boost::as_literal(Input));
std::copy(
::boost::algorithm::detail::trim_begin(
::boost::begin(lit_range),
::boost::end(lit_range),
IsSpace ),
::boost::end(lit_range),
Output);
return Output;
}
//! Left trim - parametric
/*!
\overload
*/
template<typename SequenceT, typename PredicateT>
inline SequenceT trim_left_copy_if(const SequenceT& Input, PredicateT IsSpace)
{
return SequenceT(
::boost::algorithm::detail::trim_begin(
::boost::begin(Input),
::boost::end(Input),
IsSpace ),
::boost::end(Input));
}
//! Left trim - parametric
/*!
Remove all leading spaces from the input.
The result is a trimmed copy of the input.
\param Input An input sequence
\param Loc a locale used for 'space' classification
\return A trimmed copy of the input
\note This function provides the strong exception-safety guarantee
*/
template<typename SequenceT>
inline SequenceT trim_left_copy(const SequenceT& Input, const std::locale& Loc=std::locale())
{
return
::boost::algorithm::trim_left_copy_if(
Input,
is_space(Loc));
}
//! Left trim
/*!
Remove all leading spaces from the input. The supplied predicate is
used to determine which characters are considered spaces.
The input sequence is modified in-place.
\param Input An input sequence
\param IsSpace A unary predicate identifying spaces
*/
template<typename SequenceT, typename PredicateT>
inline void trim_left_if(SequenceT& Input, PredicateT IsSpace)
{
Input.erase(
::boost::begin(Input),
::boost::algorithm::detail::trim_begin(
::boost::begin(Input),
::boost::end(Input),
IsSpace));
}
//! Left trim
/*!
Remove all leading spaces from the input.
The Input sequence is modified in-place.
\param Input An input sequence
\param Loc A locale used for 'space' classification
*/
template<typename SequenceT>
inline void trim_left(SequenceT& Input, const std::locale& Loc=std::locale())
{
::boost::algorithm::trim_left_if(
Input,
is_space(Loc));
}
// right trim -----------------------------------------------//
//! Right trim - parametric
/*!
Remove all trailing spaces from the input.
The supplied predicate is used to determine which characters are considered spaces.
The result is a trimmed copy of the input. It is returned as a sequence
or copied to the output iterator
\param Output An output iterator to which the result will be copied
\param Input An input range
\param IsSpace A unary predicate identifying spaces
\return
An output iterator pointing just after the last inserted character or
a copy of the input
\note The second variant of this function provides the strong exception-safety guarantee
*/
template<typename OutputIteratorT, typename RangeT, typename PredicateT>
inline OutputIteratorT trim_right_copy_if(
OutputIteratorT Output,
const RangeT& Input,
PredicateT IsSpace )
{
iterator_range<BOOST_STRING_TYPENAME range_const_iterator<RangeT>::type> lit_range(::boost::as_literal(Input));
std::copy(
::boost::begin(lit_range),
::boost::algorithm::detail::trim_end(
::boost::begin(lit_range),
::boost::end(lit_range),
IsSpace ),
Output );
return Output;
}
//! Right trim - parametric
/*!
\overload
*/
template<typename SequenceT, typename PredicateT>
inline SequenceT trim_right_copy_if(const SequenceT& Input, PredicateT IsSpace)
{
return SequenceT(
::boost::begin(Input),
::boost::algorithm::detail::trim_end(
::boost::begin(Input),
::boost::end(Input),
IsSpace)
);
}
//! Right trim
/*!
Remove all trailing spaces from the input.
The result is a trimmed copy of the input
\param Input An input sequence
\param Loc A locale used for 'space' classification
\return A trimmed copy of the input
\note This function provides the strong exception-safety guarantee
*/
template<typename SequenceT>
inline SequenceT trim_right_copy(const SequenceT& Input, const std::locale& Loc=std::locale())
{
return
::boost::algorithm::trim_right_copy_if(
Input,
is_space(Loc));
}
//! Right trim - parametric
/*!
Remove all trailing spaces from the input.
The supplied predicate is used to determine which characters are considered spaces.
The input sequence is modified in-place.
\param Input An input sequence
\param IsSpace A unary predicate identifying spaces
*/
template<typename SequenceT, typename PredicateT>
inline void trim_right_if(SequenceT& Input, PredicateT IsSpace)
{
Input.erase(
::boost::algorithm::detail::trim_end(
::boost::begin(Input),
::boost::end(Input),
IsSpace ),
::boost::end(Input)
);
}
//! Right trim
/*!
Remove all trailing spaces from the input.
The input sequence is modified in-place.
\param Input An input sequence
\param Loc A locale used for 'space' classification
*/
template<typename SequenceT>
inline void trim_right(SequenceT& Input, const std::locale& Loc=std::locale())
{
::boost::algorithm::trim_right_if(
Input,
is_space(Loc) );
}
// both side trim -----------------------------------------------//
//! Trim - parametric
/*!
Remove all trailing and leading spaces from the input.
The supplied predicate is used to determine which characters are considered spaces.
The result is a trimmed copy of the input. It is returned as a sequence
or copied to the output iterator
\param Output An output iterator to which the result will be copied
\param Input An input range
\param IsSpace A unary predicate identifying spaces
\return
An output iterator pointing just after the last inserted character or
a copy of the input
\note The second variant of this function provides the strong exception-safety guarantee
*/
template<typename OutputIteratorT, typename RangeT, typename PredicateT>
inline OutputIteratorT trim_copy_if(
OutputIteratorT Output,
const RangeT& Input,
PredicateT IsSpace)
{
iterator_range<BOOST_STRING_TYPENAME range_const_iterator<RangeT>::type> lit_range(::boost::as_literal(Input));
BOOST_STRING_TYPENAME
range_const_iterator<RangeT>::type TrimEnd=
::boost::algorithm::detail::trim_end(
::boost::begin(lit_range),
::boost::end(lit_range),
IsSpace);
std::copy(
detail::trim_begin(
::boost::begin(lit_range), TrimEnd, IsSpace),
TrimEnd,
Output
);
return Output;
}
//! Trim - parametric
/*!
\overload
*/
template<typename SequenceT, typename PredicateT>
inline SequenceT trim_copy_if(const SequenceT& Input, PredicateT IsSpace)
{
BOOST_STRING_TYPENAME
range_const_iterator<SequenceT>::type TrimEnd=
::boost::algorithm::detail::trim_end(
::boost::begin(Input),
::boost::end(Input),
IsSpace);
return SequenceT(
detail::trim_begin(
::boost::begin(Input),
TrimEnd,
IsSpace),
TrimEnd
);
}
//! Trim
/*!
Remove all leading and trailing spaces from the input.
The result is a trimmed copy of the input
\param Input An input sequence
\param Loc A locale used for 'space' classification
\return A trimmed copy of the input
\note This function provides the strong exception-safety guarantee
*/
template<typename SequenceT>
inline SequenceT trim_copy( const SequenceT& Input, const std::locale& Loc=std::locale() )
{
return
::boost::algorithm::trim_copy_if(
Input,
is_space(Loc) );
}
//! Trim
/*!
Remove all leading and trailing spaces from the input.
The supplied predicate is used to determine which characters are considered spaces.
The input sequence is modified in-place.
\param Input An input sequence
\param IsSpace A unary predicate identifying spaces
*/
template<typename SequenceT, typename PredicateT>
inline void trim_if(SequenceT& Input, PredicateT IsSpace)
{
::boost::algorithm::trim_right_if( Input, IsSpace );
::boost::algorithm::trim_left_if( Input, IsSpace );
}
//! Trim
/*!
Remove all leading and trailing spaces from the input.
The input sequence is modified in-place.
\param Input An input sequence
\param Loc A locale used for 'space' classification
*/
template<typename SequenceT>
inline void trim(SequenceT& Input, const std::locale& Loc=std::locale())
{
::boost::algorithm::trim_if(
Input,
is_space( Loc ) );
}
} // namespace algorithm
// pull names to the boost namespace
using algorithm::trim_left;
using algorithm::trim_left_if;
using algorithm::trim_left_copy;
using algorithm::trim_left_copy_if;
using algorithm::trim_right;
using algorithm::trim_right_if;
using algorithm::trim_right_copy;
using algorithm::trim_right_copy_if;
using algorithm::trim;
using algorithm::trim_if;
using algorithm::trim_copy;
using algorithm::trim_copy_if;
} // namespace boost
#endif // BOOST_STRING_TRIM_HPP

View File

@ -0,0 +1,217 @@
// Boost string_algo library trim.hpp header file ---------------------------//
// Copyright Pavol Droba 2002-2003.
//
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
// See http://www.boost.org/ for updates, documentation, and revision history.
#ifndef BOOST_STRING_TRIM_ALL_HPP
#define BOOST_STRING_TRIM_ALL_HPP
#include <boost/algorithm/string/config.hpp>
#include <boost/algorithm/string/trim.hpp>
#include <boost/algorithm/string/classification.hpp>
#include <boost/algorithm/string/find_format.hpp>
#include <boost/algorithm/string/formatter.hpp>
#include <boost/algorithm/string/finder.hpp>
#include <locale>
/*! \file
Defines trim_all algorithms.
Just like \c trim, \c trim_all removes all trailing and leading spaces from a
sequence (string). In addition, spaces in the middle of the sequence are truncated
to just one character. Space is recognized using given locales.
\c trim_fill acts as trim_all, but the spaces in the middle are replaces with
a user-define sequence of character.
Parametric (\c _if) variants use a predicate (functor) to select which characters
are to be trimmed..
Functions take a selection predicate as a parameter, which is used to determine
whether a character is a space. Common predicates are provided in classification.hpp header.
*/
namespace boost {
namespace algorithm {
// multi line trim ----------------------------------------------- //
//! Trim All - parametric
/*!
Remove all leading and trailing spaces from the input and
compress all other spaces to a single character.
The result is a trimmed copy of the input
\param Input An input sequence
\param IsSpace A unary predicate identifying spaces
\return A trimmed copy of the input
*/
template<typename SequenceT, typename PredicateT>
inline SequenceT trim_all_copy_if(const SequenceT& Input, PredicateT IsSpace)
{
return
::boost::find_format_all_copy(
::boost::trim_copy_if(Input, IsSpace),
::boost::token_finder(IsSpace, ::boost::token_compress_on),
::boost::dissect_formatter(::boost::head_finder(1)));
}
//! Trim All
/*!
Remove all leading and trailing spaces from the input and
compress all other spaces to a single character.
The input sequence is modified in-place.
\param Input An input sequence
\param IsSpace A unary predicate identifying spaces
*/
template<typename SequenceT, typename PredicateT>
inline void trim_all_if(SequenceT& Input, PredicateT IsSpace)
{
::boost::trim_if(Input, IsSpace);
::boost::find_format_all(
Input,
::boost::token_finder(IsSpace, ::boost::token_compress_on),
::boost::dissect_formatter(::boost::head_finder(1)));
}
//! Trim All
/*!
Remove all leading and trailing spaces from the input and
compress all other spaces to a single character.
The result is a trimmed copy of the input
\param Input An input sequence
\param Loc A locale used for 'space' classification
\return A trimmed copy of the input
*/
template<typename SequenceT>
inline SequenceT trim_all_copy(const SequenceT& Input, const std::locale& Loc =std::locale())
{
return trim_all_copy_if(Input, ::boost::is_space(Loc));
}
//! Trim All
/*!
Remove all leading and trailing spaces from the input and
compress all other spaces to a single character.
The input sequence is modified in-place.
\param Input An input sequence
\param Loc A locale used for 'space' classification
\return A trimmed copy of the input
*/
template<typename SequenceT>
inline void trim_all(SequenceT& Input, const std::locale& Loc =std::locale())
{
trim_all_if(Input, ::boost::is_space(Loc));
}
//! Trim Fill - parametric
/*!
Remove all leading and trailing spaces from the input and
replace all every block of consecutive spaces with a fill string
defined by user.
The result is a trimmed copy of the input
\param Input An input sequence
\param Fill A string used to fill the inner spaces
\param IsSpace A unary predicate identifying spaces
\return A trimmed copy of the input
*/
template<typename SequenceT, typename RangeT, typename PredicateT>
inline SequenceT trim_fill_copy_if(const SequenceT& Input, const RangeT& Fill, PredicateT IsSpace)
{
return
::boost::find_format_all_copy(
::boost::trim_copy_if(Input, IsSpace),
::boost::token_finder(IsSpace, ::boost::token_compress_on),
::boost::const_formatter(::boost::as_literal(Fill)));
}
//! Trim Fill
/*!
Remove all leading and trailing spaces from the input and
replace all every block of consecutive spaces with a fill string
defined by user.
The input sequence is modified in-place.
\param Input An input sequence
\param Fill A string used to fill the inner spaces
\param IsSpace A unary predicate identifying spaces
*/
template<typename SequenceT, typename RangeT, typename PredicateT>
inline void trim_fill_if(SequenceT& Input, const RangeT& Fill, PredicateT IsSpace)
{
::boost::trim_if(Input, IsSpace);
::boost::find_format_all(
Input,
::boost::token_finder(IsSpace, ::boost::token_compress_on),
::boost::const_formatter(::boost::as_literal(Fill)));
}
//! Trim Fill
/*!
Remove all leading and trailing spaces from the input and
replace all every block of consecutive spaces with a fill string
defined by user.
The result is a trimmed copy of the input
\param Input An input sequence
\param Fill A string used to fill the inner spaces
\param Loc A locale used for 'space' classification
\return A trimmed copy of the input
*/
template<typename SequenceT, typename RangeT>
inline SequenceT trim_fill_copy(const SequenceT& Input, const RangeT& Fill, const std::locale& Loc =std::locale())
{
return trim_fill_copy_if(Input, Fill, ::boost::is_space(Loc));
}
//! Trim Fill
/*!
Remove all leading and trailing spaces from the input and
replace all every block of consecutive spaces with a fill string
defined by user.
The input sequence is modified in-place.
\param Input An input sequence
\param Fill A string used to fill the inner spaces
\param Loc A locale used for 'space' classification
\return A trimmed copy of the input
*/
template<typename SequenceT, typename RangeT>
inline void trim_fill(SequenceT& Input, const RangeT& Fill, const std::locale& Loc =std::locale())
{
trim_fill_if(Input, Fill, ::boost::is_space(Loc));
}
} // namespace algorithm
// pull names to the boost namespace
using algorithm::trim_all;
using algorithm::trim_all_if;
using algorithm::trim_all_copy;
using algorithm::trim_all_copy_if;
using algorithm::trim_fill;
using algorithm::trim_fill_if;
using algorithm::trim_fill_copy;
using algorithm::trim_fill_copy_if;
} // namespace boost
#endif // BOOST_STRING_TRIM_ALL_HPP

View File

@ -0,0 +1,33 @@
// Boost string_algo library yes_no_type.hpp header file ---------------------------//
// Copyright Pavol Droba 2002-2003.
//
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
// See http://www.boost.org/ for updates, documentation, and revision history.
#ifndef BOOST_STRING_YES_NO_TYPE_DETAIL_HPP
#define BOOST_STRING_YES_NO_TYPE_DETAIL_HPP
namespace boost {
namespace algorithm {
// taken from boost mailing-list
// when yes_no_type will become officially
// a part of boost distribution, this header
// will be deprecated
template<int I> struct size_descriptor
{
typedef char (& type)[I];
};
typedef size_descriptor<1>::type yes_type;
typedef size_descriptor<2>::type no_type;
} // namespace algorithm
} // namespace boost
#endif // BOOST_STRING_YES_NO_TYPE_DETAIL_HPP

View File

@ -0,0 +1,23 @@
// Boost string_algo library string_regex.hpp header file ---------------------------//
// Copyright Pavol Droba 2002-2004.
//
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
// See http://www.boost.org/ for updates, documentation, and revision history.
#ifndef BOOST_STRING_ALGO_REGEX_HPP
#define BOOST_STRING_ALGO_REGEX_HPP
/*! \file
Cumulative include for string_algo library.
In addition to string.hpp contains also regex-related stuff.
*/
#include <boost/regex.hpp>
#include <boost/algorithm/string.hpp>
#include <boost/algorithm/string/regex.hpp>
#endif // BOOST_STRING_ALGO_REGEX_HPP

View File

@ -0,0 +1,20 @@
/*
(c) 2014-2015 Glen Joseph Fernandes
<glenjofe -at- gmail.com>
Distributed under the Boost Software
License, Version 1.0.
http://boost.org/LICENSE_1_0.txt
*/
#ifndef BOOST_ALIGN_ALIGN_HPP
#define BOOST_ALIGN_ALIGN_HPP
#include <boost/config.hpp>
#if !defined(BOOST_NO_CXX11_STD_ALIGN)
#include <boost/align/detail/align_cxx11.hpp>
#else
#include <boost/align/detail/align.hpp>
#endif
#endif

View File

@ -0,0 +1,27 @@
/*
(c) 2015 Glen Joseph Fernandes
<glenjofe -at- gmail.com>
Distributed under the Boost Software
License, Version 1.0.
http://boost.org/LICENSE_1_0.txt
*/
#ifndef BOOST_ALIGN_ALIGN_DOWN_HPP
#define BOOST_ALIGN_ALIGN_DOWN_HPP
#include <boost/align/detail/align_down.hpp>
#include <boost/align/align_down_forward.hpp>
namespace boost {
namespace alignment {
BOOST_CONSTEXPR inline std::size_t align_down(std::size_t value,
std::size_t alignment) BOOST_NOEXCEPT
{
return value & ~(alignment - 1);
}
} /* .alignment */
} /* .boost */
#endif

View File

@ -0,0 +1,24 @@
/*
(c) 2015 Glen Joseph Fernandes
<glenjofe -at- gmail.com>
Distributed under the Boost Software
License, Version 1.0.
http://boost.org/LICENSE_1_0.txt
*/
#ifndef BOOST_ALIGN_ALIGN_DOWN_FORWARD_HPP
#define BOOST_ALIGN_ALIGN_DOWN_FORWARD_HPP
#include <boost/config.hpp>
#include <cstddef>
namespace boost {
namespace alignment {
BOOST_CONSTEXPR std::size_t align_down(std::size_t value,
std::size_t alignment) BOOST_NOEXCEPT;
} /* .alignment */
} /* .boost */
#endif

View File

@ -0,0 +1,27 @@
/*
(c) 2015 Glen Joseph Fernandes
<glenjofe -at- gmail.com>
Distributed under the Boost Software
License, Version 1.0.
http://boost.org/LICENSE_1_0.txt
*/
#ifndef BOOST_ALIGN_ALIGN_UP_HPP
#define BOOST_ALIGN_ALIGN_UP_HPP
#include <boost/align/detail/align_up.hpp>
#include <boost/align/align_up_forward.hpp>
namespace boost {
namespace alignment {
BOOST_CONSTEXPR inline std::size_t align_up(std::size_t value,
std::size_t alignment) BOOST_NOEXCEPT
{
return (value + alignment - 1) & ~(alignment - 1);
}
} /* .alignment */
} /* .boost */
#endif

Some files were not shown because too many files have changed in this diff Show More