Compare commits

...

53 Commits

Author SHA1 Message Date
Maarten L. Hekkelman
4782a4e07d Merge branch 'develop' into trunk 2023-12-12 09:31:30 +01:00
Maarten L. Hekkelman
dbc14206dc New readme 2023-12-12 09:21:59 +01:00
Maarten L. Hekkelman
f4296d8858 docs ci 2023-12-12 08:26:44 +01:00
Maarten L. Hekkelman
75c4c2286d readme, docs ci 2023-12-12 08:08:40 +01:00
Maarten L. Hekkelman
b14237e8e6 Not nice 2023-12-05 16:01:20 +01:00
Maarten L. Hekkelman
df3263e4bd test 2023-12-05 15:57:51 +01:00
Maarten L. Hekkelman
ff7b413abf windows gunzip workaround 2023-12-05 15:43:52 +01:00
Maarten L. Hekkelman
07224779e6 find_program works a bit different than expected 2023-12-05 15:26:26 +01:00
Maarten L. Hekkelman
c031a3c24e Moved data file components.cif to rsrc 2023-12-05 11:53:39 +01:00
Maarten L. Hekkelman
1e74f7912c using eigen3 2023-12-05 08:59:10 +01:00
Maarten L. Hekkelman
d91f8d0876 Use fetchcontent for eigen, again 2023-12-04 18:59:03 +01:00
Maarten L. Hekkelman
43d4644fba fix license badge 2023-12-03 15:32:55 +01:00
Maarten L. Hekkelman
61a924d208 attempt to build documentation in github 2023-12-03 15:30:40 +01:00
Maarten L. Hekkelman
2692f2c1bf no update script for macOS
install with sudo in CI
2023-11-29 15:22:59 +01:00
Maarten L. Hekkelman
88b3c87bae fixes for automatic update of data 2023-11-29 14:37:28 +01:00
Maarten L. Hekkelman
7fd7dfd937 Work on WIN32 with or without CCP4 2023-11-29 13:11:13 +01:00
Maarten L. Hekkelman
9a76f02709 using gzip, now correct 2023-11-28 16:45:56 +01:00
Maarten L. Hekkelman
81cc1c73c1 use gzip if found 2023-11-28 16:24:18 +01:00
Maarten L. Hekkelman
eabda8f0f7 Fix downloading CCD file 2023-11-28 16:11:02 +01:00
Maarten L. Hekkelman
cb3917457b cleaning up ci file 2023-11-28 13:58:13 +01:00
Maarten L. Hekkelman
2c4f36a8f9 run CI on macOS 2023-11-28 13:47:53 +01:00
Maarten L. Hekkelman
d458be99bc finally read the documentation on cmake set 2023-11-28 11:41:52 +01:00
Maarten L. Hekkelman
a7f4531767 switched last test to Catch2 2023-11-28 11:14:00 +01:00
Maarten L. Hekkelman
08f5a1ad06 link to zlib::zlib
cache_dir may be undefined
2023-11-28 09:58:44 +01:00
Maarten L. Hekkelman
f2de24c851 for CI: install zlib in windows 2023-11-28 09:15:11 +01:00
Maarten L. Hekkelman
ed1eca8fb5 Build zlib if needed 2023-11-28 08:25:23 +01:00
Maarten L. Hekkelman
f792e6f13d correctly use boost::regex 2023-11-27 17:22:59 +01:00
Maarten L. Hekkelman
b1782b7a97 Merge branch 'with-catch2' into develop 2023-11-27 17:02:04 +01:00
Maarten L. Hekkelman
f3c3966e00 Merge branch 'with-catch2' of s4.hekkelman.net:git-repo/libcifpp into with-catch2 2023-11-27 17:01:43 +01:00
Maarten L. Hekkelman
8a9f72c96b boost regex standalone 2023-11-27 17:01:34 +01:00
Maarten L. Hekkelman
402d3a16ae option takes a default value, not type 2023-11-27 13:01:29 +01:00
Maarten L. Hekkelman
458e228b91 Start using postfix d for debug libraries. Rename cmake config files 2023-11-27 12:47:11 +01:00
Maarten L. Hekkelman
a817f09441 Stricter tests 2023-11-25 11:13:40 +01:00
Maarten L. Hekkelman
413ba85538 CI added 2023-11-23 09:42:12 +01:00
Maarten L. Hekkelman
c1807bf1c3 catch2 work 2023-11-23 09:41:49 +01:00
Maarten L. Hekkelman
09dd65499a Change testing framework to Catch2 2023-11-22 17:06:07 +01:00
Maarten L. Hekkelman
640552abad Remove dependency on libzeep 2023-11-22 14:48:23 +01:00
Maarten L. Hekkelman
faee1848e5 cleaner makefile 2023-11-22 14:35:32 +01:00
Maarten L. Hekkelman
c7a217fea7 cleaner makefile 2023-11-22 14:32:33 +01:00
Maarten L. Hekkelman
e4ae19a625 cleaner makefile 2023-11-22 14:30:21 +01:00
Maarten L. Hekkelman
24fe6ee583 Unused comparison result... tssk 2023-11-22 14:15:51 +01:00
Maarten L. Hekkelman
9cba754eb6 Unused comparison result... tssk 2023-11-22 14:12:45 +01:00
Maarten L. Hekkelman
9e6bb5e844 cleaner makefile 2023-11-22 14:08:06 +01:00
Maarten L. Hekkelman
a74ee255fb More info on missing compounds 2023-11-22 14:07:53 +01:00
Maarten L. Hekkelman
b9fc0c0365 Using FetchContent 2023-11-22 10:26:21 +01:00
Maarten L. Hekkelman
2ce16c74f7 Updating CMakeLists.txt 2023-11-22 09:49:09 +01:00
Maarten L. Hekkelman
6d0ea5c6f9 Drop using CCP4 monomers library
version bump
2023-11-21 14:48:51 +01:00
Maarten L. Hekkelman
b83ef112a9 Fix in structure::change_residue 2023-11-13 10:50:27 +01:00
Maarten L. Hekkelman
dd9110a3a8 Add option to not write data files 2023-11-07 16:48:44 +01:00
Maarten L. Hekkelman
88c23e1b0f Add option to not write data files 2023-11-07 16:38:47 +01:00
Maarten L. Hekkelman
dbe40e3ad6 No longer use mon_lib_list as check for existence of compound 2023-11-06 08:39:17 +01:00
Maarten L. Hekkelman
958d3b05c8 Correctly import Eigen3 2023-11-06 08:21:59 +01:00
Maarten L. Hekkelman
4e7b0baafb version bump 2023-11-02 14:29:05 +01:00
97 changed files with 1381 additions and 25088 deletions

View File

@@ -0,0 +1,65 @@
# This starter workflow is for a CMake project running on multiple platforms. There is a different starter workflow if you just want a single platform.
# See: https://github.com/actions/starter-workflows/blob/main/ci/cmake-single-platform.yml
name: publish docs
on:
push:
branches: [ "trunk" ]
permissions:
contents: read
pages: write
id-token: write
concurrency:
group: "pages"
cancel-in-progress: false
jobs:
docs:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v1
- name: Set reusable strings
# Turn repeated input strings (such as the build output directory) into step outputs. These step outputs can be used throughout the workflow file.
id: strings
shell: bash
run: |
echo "build-output-dir=${{ github.workspace }}/build" >> "$GITHUB_OUTPUT"
- name: Install dependencies Ubuntu
run: sudo apt-get update && sudo apt-get install cmake doxygen
- uses: actions/setup-python@v4
with:
python-version: '3.9'
cache: 'pip' # caching pip dependencies
- run: pip install -r docs/requirements.txt
- name: Configure CMake
run: cmake -S . -B ${{ steps.strings.outputs.build-output-dir }} -DBUILD_DOCUMENTATION=ON -DBUILD_TESTING=OFF
- name: Run Sphinx
run: |
cmake --build ${{ steps.strings.outputs.build-output-dir }} --target Sphinx-libcifpp
ls -l ${{ steps.strings.outputs.build-output-dir }}
ls -l ${{ steps.strings.outputs.build-output-dir }}/docs/sphinx
- name: Upload artifact
uses: actions/upload-pages-artifact@v2
with:
path: ${{ steps.strings.outputs.build-output-dir }}/docs/sphinx
deploy:
environment:
name: github-pages
url: ${{ steps.deployment.outputs.page_url }}
runs-on: ubuntu-latest
needs: docs
steps:
- name: Deploy to GitHub Pages
id: deployment
uses: actions/deploy-pages@v2

View File

@@ -0,0 +1,59 @@
name: multi platform test
on:
push:
branches: [ "trunk", "develop" ]
pull_request:
branches: [ "trunk" ]
jobs:
build:
runs-on: ${{ matrix.os }}
strategy:
fail-fast: false
matrix:
os: [ubuntu-latest, windows-latest, macos-latest]
include:
- os: windows-latest
cpp_compiler: cl
- os: ubuntu-latest
cpp_compiler: g++
- os: macos-latest
cpp_compiler: clang++
steps:
- uses: actions/checkout@v3
- name: Set reusable strings
id: strings
shell: bash
run: echo "build-output-dir=${{ github.workspace }}/build" >> "$GITHUB_OUTPUT"
- name: Install dependencies Ubuntu
if: matrix.os == 'ubuntu-latest'
run: sudo apt-get update && sudo apt-get install mrc
- name: Install dependencies Window
if: matrix.os == 'windows-latest'
run: ./tools/depends.cmd
shell: cmd
- name: Configure CMake
run: >
cmake -B ${{ steps.strings.outputs.build-output-dir }}
-DCMAKE_CXX_COMPILER=${{ matrix.cpp_compiler }}
-DCMAKE_BUILD_TYPE=Release
-S ${{ github.workspace }}
- name: Build
run: cmake --build ${{ steps.strings.outputs.build-output-dir }} --config Release
- name: Test
working-directory: ${{ steps.strings.outputs.build-output-dir }}
run: ctest --build-config Release --output-on-failure
- name: Install
if: matrix.os != 'windows-latest'
run: sudo cmake --install ${{ steps.strings.outputs.build-output-dir }} --config Release

5
.gitignore vendored
View File

@@ -2,7 +2,7 @@ build/
.vscode/
.vs/
tools/update-libcifpp-data
data/components.cif*
rsrc/components.cif*
CMakeSettings.json
msvc/
src/revision.hpp
@@ -10,4 +10,5 @@ test/test-create_sugar_?.cif
Testing/
include/cif++/exports.hpp
docs/api
docs/conf.py
docs/conf.py
build_ci/

View File

@@ -25,11 +25,10 @@
cmake_minimum_required(VERSION 3.16)
# set the project name
project(libcifpp VERSION 5.2.3 LANGUAGES CXX)
project(libcifpp VERSION 6.0.0 LANGUAGES CXX)
list(PREPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake")
include(GNUInstallDirs)
include(CheckFunctionExists)
include(CheckIncludeFiles)
include(CheckLibraryExists)
@@ -37,14 +36,19 @@ include(CMakePackageConfigHelpers)
include(CheckCXXSourceCompiles)
include(GenerateExportHeader)
include(CTest)
include(CMakeDependentOption)
include(FetchContent)
include(ExternalProject)
set(CXX_EXTENSIONS OFF)
set(CMAKE_CXX_STANDARD 20)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
# set(CMAKE_CXX_VISIBILITY_PRESET hidden)
# set(CMAKE_VISIBILITY_INLINES_HIDDEN 1)
# When building with ninja-multiconfig, build both debug and release by default
if(CMAKE_GENERATOR STREQUAL "Ninja Multi-Config")
set(CMAKE_CROSS_CONFIGS "Debug;Release")
set(CMAKE_DEFAULT_CONFIGS "Debug;Release")
endif()
if("${CMAKE_CXX_COMPILER_ID}" STREQUAL "GNU")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -Wextra -Wno-unused-parameter -Wno-missing-field-initializers")
elseif(MSVC)
@@ -54,50 +58,40 @@ endif()
# Build documentation?
option(BUILD_DOCUMENTATION "Build the documentation" OFF)
# We do not want to write an export file for all our symbols...
set(CMAKE_WINDOWS_EXPORT_ALL_SYMBOLS ON)
# Optionally build a version to be installed inside CCP4
option(BUILD_FOR_CCP4 "Build a version to be installed in CCP4" OFF)
option(BUILD_FOR_CCP4 "Build a version to be installed in CCP4")
# Building shared libraries?
if(CMAKE_VERSION VERSION_GREATER_EQUAL 3.22)
cmake_policy(SET CMP0127 NEW)
cmake_dependent_option(BUILD_SHARED_LIBS "Build a shared library instead of a static one" OFF "NOT (BUILD_FOR_CCP4 AND WIN32)" ON)
else()
if(NOT(BUILD_FOR_CCP4 AND WIN32))
option(BUILD_SHARED_LIBS "Build a shared library instead of a static one" OFF)
endif()
# Lots of code depend on the availability of the components.cif file
option(CIFPP_DOWNLOAD_CCD "Download the CCD file components.cif during installation" ON)
if(BUILD_FOR_CCP4)
unset(CIFPP_DOWNLOAD_CCD)
unset(CIFPP_INSTALL_UPDATE_SCRIPT)
else()
# Lots of code depend on the availability of the components.cif file
option(CIFPP_DOWNLOAD_CCD "Download the CCD file components.cif during installation" ON)
# An optional cron script can be installed to keep the data files up-to-date
if(UNIX)
option(CIFPP_INSTALL_UPDATE_SCRIPT "Install the script to update CCD and dictionary files" ON)
# An optional cron script can be installed to keep the data files up-to-date
if(UNIX AND NOT APPLE)
option(CIFPP_INSTALL_UPDATE_SCRIPT "Install the script to update CCD and dictionary files" ON)
endif()
endif()
# When CCP4 is sourced in the environment, we can recreate the symmetry operations table
if(EXISTS "$ENV{CCP4}")
if(EXISTS "$ENV{CLIBD}/syminfo.lib")
option(CIFPP_RECREATE_SYMOP_DATA "Recreate SymOp data table in case it is out of date" ON)
else()
set(CIFPP_RECREATE_SYMOP_DATA OFF)
message(WARNING "Symop data table recreation requested, but file syminfo.lib was not found in $ENV{CLIBD}")
endif()
else()
set(CIFPP_RECREATE_SYMOP_DATA OFF)
message("Not trying to recreate symop_table_data.hpp since CCP4 is not defined")
if(EXISTS "$ENV{CCP4}/lib/data/syminfo.lib")
option(CIFPP_RECREATE_SYMOP_DATA "Recreate SymOp data table in case it is out of date" ON)
endif()
# Unit tests
# CCP4 build
if(BUILD_FOR_CCP4)
if("$ENV{CCP4}" STREQUAL "" OR NOT EXISTS $ENV{CCP4})
message(FATAL_ERROR "A CCP4 built was requested but CCP4 was not sourced")
else()
list(APPEND CMAKE_MODULE_PATH "$ENV{CCP4}")
list(APPEND CMAKE_PREFIX_PATH "$ENV{CCP4}")
list(PREPEND CMAKE_MODULE_PATH "$ENV{CCP4}")
list(PREPEND CMAKE_PREFIX_PATH "$ENV{CCP4}")
set(CMAKE_INSTALL_PREFIX "$ENV{CCP4}")
set(CMAKE_INSTALL_FULL_DATADIR "${CMAKE_INSTALL_PREFIX}/share/libcifpp")
if(WIN32)
set(BUILD_SHARED_LIBS ON)
@@ -105,27 +99,33 @@ if(BUILD_FOR_CCP4)
endif()
endif()
# Now include the GNUInstallDirs module
include(GNUInstallDirs)
if(WIN32)
if(${CMAKE_SYSTEM_VERSION} GREATER_EQUAL 10) # Windows 10
add_definitions(-D _WIN32_WINNT=0x0A00)
elseif(${CMAKE_SYSTEM_VERSION} EQUAL 6.3) # Windows 8.1
add_definitions(-D _WIN32_WINNT=0x0603)
elseif(${CMAKE_SYSTEM_VERSION} EQUAL 6.2) # Windows 8
add_definitions(-D _WIN32_WINNT=0x0602)
elseif(${CMAKE_SYSTEM_VERSION} EQUAL 6.1) # Windows 7
add_definitions(-D _WIN32_WINNT=0x0601)
elseif(${CMAKE_SYSTEM_VERSION} EQUAL 6.0) # Windows Vista
add_definitions(-D _WIN32_WINNT=0x0600)
else() # Windows XP (5.1)
add_definitions(-D _WIN32_WINNT=0x0501)
endif()
if(${CMAKE_SYSTEM_VERSION} GREATER_EQUAL 10) # Windows 10
add_definitions(-D _WIN32_WINNT=0x0A00)
elseif(${CMAKE_SYSTEM_VERSION} EQUAL 6.3) # Windows 8.1
add_definitions(-D _WIN32_WINNT=0x0603)
elseif(${CMAKE_SYSTEM_VERSION} EQUAL 6.2) # Windows 8
add_definitions(-D _WIN32_WINNT=0x0602)
elseif(${CMAKE_SYSTEM_VERSION} EQUAL 6.1) # Windows 7
add_definitions(-D _WIN32_WINNT=0x0601)
elseif(${CMAKE_SYSTEM_VERSION} EQUAL 6.0) # Windows Vista
add_definitions(-D _WIN32_WINNT=0x0600)
else() # Windows XP (5.1)
add_definitions(-D _WIN32_WINNT=0x0501)
endif()
add_definitions(-DNOMINMAX)
# We do not want to write an export file for all our symbols...
set(CMAKE_WINDOWS_EXPORT_ALL_SYMBOLS ON)
endif()
if(MSVC)
# make msvc standards compliant...
add_compile_options(/permissive- /bigobj)
# make msvc standards compliant...
add_compile_options(/permissive- /bigobj)
add_link_options(/NODEFAULTLIB:library)
if(BUILD_SHARED_LIBS)
@@ -156,7 +156,20 @@ if(GXX_LIBSTDCPP)
if(STD_REGEX_RUNNING STREQUAL FAILED_TO_RUN)
message(STATUS "You are probably trying to compile using the g++ standard library which contains a crashing std::regex implementation. Will use boost::regex instead")
add_subdirectory(regex EXCLUDE_FROM_ALL)
find_package(Boost 1.80 QUIET COMPONENTS regex)
if(NOT Boost_FOUND)
set(BOOST_REGEX_STANDALONE ON)
FetchContent_Declare(
boost-rx
GIT_REPOSITORY https://github.com/boostorg/regex
GIT_TAG boost-1.83.0
)
FetchContent_MakeAvailable(boost-rx)
endif()
set(BOOST_REGEX ON)
endif()
endif()
@@ -182,6 +195,10 @@ if(MSVC)
unset(_ZLIB_x86)
list(APPEND _ZLIB_SEARCHES _ZLIB_SEARCH_NORMAL)
if(BUILD_FOR_CCP4)
list(PREPEND _ZLIB_SEARCHES "$ENV{CCP4}/lib")
endif()
foreach(search ${_ZLIB_SEARCHES})
find_library(ZLIB_LIBRARY NAMES zlibstatic NAMES_PER_DIR ${${search}} PATH_SUFFIXES lib)
endforeach()
@@ -189,7 +206,29 @@ endif()
find_package(ZLIB REQUIRED)
find_package(Eigen3 REQUIRED)
# Using Eigen3 is a bit of a thing. We don't want to build it completely since we
# only need a couple of header files. Nothing special. But often, eigen3 is already
# installed and then we prefer that.
find_package(Eigen3 3.4 QUIET)
if(Eigen3_FOUND AND TARGET Eigen3::Eigen)
get_target_property(EIGEN_INCLUDE_DIR Eigen3::Eigen INTERFACE_INCLUDE_DIRECTORIES)
else()
# Create a private copy of eigen3 and populate it only, no need to build
FetchContent_Declare(
my-eigen3
GIT_REPOSITORY https://gitlab.com/libeigen/eigen.git
GIT_TAG 3.4.0
)
FetchContent_GetProperties(my-eigen3)
if(NOT my-eigen3_POPULATED)
FetchContent_Populate(my-eigen3)
endif()
set(EIGEN_INCLUDE_DIR ${my-eigen3_SOURCE_DIR})
endif()
include(FindFilesystem)
list(APPEND CIFPP_REQUIRED_LIBRARIES ${STDCPPFS_LIBRARY})
@@ -197,12 +236,6 @@ list(APPEND CIFPP_REQUIRED_LIBRARIES ${STDCPPFS_LIBRARY})
include(FindAtomic)
list(APPEND CIFPP_REQUIRED_LIBRARIES ${STDCPPATOMIC_LIBRARY})
if(MSVC)
# this dependency can go once MSVC supports std::experimental::is_detected
find_package(zeep 5.1.8 REQUIRED)
list(APPEND CIFPP_REQUIRED_LIBRARIES zeep::zeep)
endif()
# Create a revision file, containing the current git version info
include(VersionString)
write_version_header(${PROJECT_SOURCE_DIR}/src/ LIB_NAME "LibCIFPP")
@@ -283,11 +316,15 @@ set(project_headers
add_library(cifpp ${project_sources} ${project_headers} ${PROJECT_SOURCE_DIR}/src/symop_table_data.hpp)
add_library(cifpp::cifpp ALIAS cifpp)
set(CMAKE_DEBUG_POSTFIX d)
set_target_properties(cifpp PROPERTIES DEBUG_POSTFIX "d")
generate_export_header(cifpp EXPORT_FILE_NAME ${PROJECT_SOURCE_DIR}/include/cif++/exports.hpp)
if(BOOST_REGEX)
target_compile_definitions(cifpp PRIVATE USE_BOOST_REGEX=1 BOOST_REGEX_STANDALONE=1)
target_include_directories(cifpp PRIVATE regex/include)
get_target_property(BOOST_REGEX_INCLUDE_DIR Boost::regex INTERFACE_INCLUDE_DIRECTORIES)
endif()
if(MSVC)
@@ -298,11 +335,15 @@ set_target_properties(cifpp PROPERTIES POSITION_INDEPENDENT_CODE ON)
target_include_directories(cifpp
PUBLIC
"$<BUILD_INTERFACE:${PROJECT_SOURCE_DIR}/include;${PROJECT_BINARY_DIR}>"
"$<BUILD_INTERFACE:${PROJECT_SOURCE_DIR}/include>"
"$<INSTALL_INTERFACE:${CMAKE_INSTALL_INCLUDEDIR}>"
PRIVATE
"${BOOST_REGEX_INCLUDE_DIR}"
"${EIGEN_INCLUDE_DIR}"
)
target_link_libraries(cifpp PUBLIC Threads::Threads ZLIB::ZLIB ${CIFPP_REQUIRED_LIBRARIES} PRIVATE Eigen3::Eigen)
target_link_libraries(cifpp
PUBLIC Threads::Threads ZLIB::ZLIB ${CIFPP_REQUIRED_LIBRARIES})
if(CMAKE_CXX_COMPILER_ID STREQUAL "AppleClang")
target_link_options(cifpp PRIVATE -undefined dynamic_lookup)
@@ -310,34 +351,74 @@ endif(CMAKE_CXX_COMPILER_ID STREQUAL "AppleClang")
if(CIFPP_DOWNLOAD_CCD)
# download the components.cif file from CCD
set(COMPONENTS_CIF ${PROJECT_SOURCE_DIR}/data/components.cif)
set(COMPONENTS_CIF ${PROJECT_SOURCE_DIR}/rsrc/components.cif)
if(NOT EXISTS ${COMPONENTS_CIF})
if(NOT EXISTS ${PROJECT_SOURCE_DIR}/data)
file(MAKE_DIRECTORY ${PROJECT_SOURCE_DIR}/data/)
if(EXISTS ${COMPONENTS_CIF})
file(SIZE ${COMPONENTS_CIF} CCD_FILE_SIZE)
if(CCD_FILE_SIZE EQUAL 0)
message(STATUS "Removing empty ${COMPONENTS_CIF} file")
file(REMOVE "${COMPONENTS_CIF}")
endif()
file(DOWNLOAD https://ftp.wwpdb.org/pub/pdb/data/monomers/components.cif ${COMPONENTS_CIF} SHOW_PROGRESS)
endif()
add_custom_target(COMPONENTS ALL DEPENDS ${COMPONENTS_CIF})
if(NOT EXISTS ${COMPONENTS_CIF})
# Since the file(DOWNLOAD) command in cmake does not use
# compression, we try to download the gzipped version and
# decompress it ourselves.
find_program(GUNZIP gunzip)
if(WIN32 OR GUNZIP STREQUAL "GUNZIP-NOTFOUND")
file(DOWNLOAD https://files.wwpdb.org/pub/pdb/data/monomers/components.cif ${COMPONENTS_CIF}
SHOW_PROGRESS STATUS CCD_FETCH_STATUS)
else()
if(NOT EXISTS "${COMPONENTS_CIF}.gz")
file(DOWNLOAD https://files.wwpdb.org/pub/pdb/data/monomers/components.cif.gz ${COMPONENTS_CIF}.gz
SHOW_PROGRESS STATUS CCD_FETCH_STATUS)
endif()
add_custom_command(OUTPUT ${COMPONENTS_CIF}
COMMAND "${GUNZIP}" ${COMPONENTS_CIF}.gz
WORKING_DIRECTORY ${PROJECT_SOURCE_DIR}/rsrc/)
add_custom_target(COMPONENTS ALL DEPENDS ${COMPONENTS_CIF})
endif()
# Do not continue if downloading went wrong
list(POP_FRONT CCD_FETCH_STATUS CCD_FETCH_STATUS_CODE)
if(CCD_FETCH_STATUS_CODE)
message(FATAL_ERROR "Error trying to download CCD file: ${CCD_FETCH_STATUS}")
endif()
endif()
endif()
# Installation directories
set(CIFPP_DATA_DIR "${CMAKE_INSTALL_FULL_DATADIR}/libcifpp" CACHE PATH "The directory where dictionary files are stored")
if(BUILD_FOR_CCP4)
set(CIFPP_DATA_DIR "$ENV{CCP4}/share/libcifpp" CACHE PATH "Directory where dictionary and other static data is stored")
else()
set(CIFPP_DATA_DIR "${CMAKE_INSTALL_FULL_DATADIR}/libcifpp" CACHE PATH "Directory where dictionary and other static data is stored")
endif()
target_compile_definitions(cifpp PUBLIC DATA_DIR="${CIFPP_DATA_DIR}")
if(UNIX)
set(CIFPP_CACHE_DIR "${CMAKE_INSTALL_FULL_LOCALSTATEDIR}/cache/libcifpp"
CACHE PATH "The directory where the update script stores new dictionary files")
if(UNIX AND NOT BUILD_FOR_CCP4)
if("${CMAKE_INSTALL_PREFIX}" STREQUAL "/usr/local")
set(CIFPP_CACHE_DIR "/var/cache/libcifpp" CACHE PATH "The directory where downloaded data files are stored")
else()
set(CIFPP_CACHE_DIR "${CMAKE_INSTALL_FULL_LOCALSTATEDIR}/cache/libcifpp" CACHE PATH "The directory where downloaded data files are stored")
endif()
target_compile_definitions(cifpp PUBLIC CACHE_DIR="${CIFPP_CACHE_DIR}")
set(CIFPP_ETC_DIR "${CMAKE_INSTALL_FULL_SYSCONFDIR}")
set(CIFPP_ETC_DIR "${CMAKE_INSTALL_FULL_SYSCONFDIR}" CACHE PATH "The directory where the update configuration file is stored")
else()
unset(CIFPP_CACHE_DIR)
endif()
# Install rules
install(TARGETS cifpp
EXPORT cifppTargets
EXPORT cifpp-targets
ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}
LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
@@ -350,8 +431,18 @@ if(MSVC AND BUILD_SHARED_LIBS)
OPTIONAL)
endif()
install(EXPORT cifppTargets
FILE "cifppTargets.cmake"
# Clean up old config files (with old names)
file(GLOB OLD_CONFIG_FILES
${CMAKE_INSTALL_FULL_LIBDIR}/cmake/cifpp/cifppConfig*.cmake
${CMAKE_INSTALL_FULL_LIBDIR}/cmake/cifpp/cifppTargets*.cmake)
if(OLD_CONFIG_FILES)
message(STATUS "Installation will remove old config files: ${OLD_CONFIG_FILES}")
install(CODE "file(REMOVE ${OLD_CONFIG_FILES})")
endif()
install(EXPORT cifpp-targets
FILE "cifpp-targets.cmake"
NAMESPACE cifpp::
DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/cifpp
)
@@ -376,7 +467,7 @@ install(FILES
DESTINATION ${CIFPP_DATA_DIR}
)
if(${CIFPP_CACHE_DIR})
if(CIFPP_CACHE_DIR)
install(FILES
${PROJECT_SOURCE_DIR}/rsrc/mmcif_ddl.dic
${PROJECT_SOURCE_DIR}/rsrc/mmcif_pdbx.dic
@@ -386,18 +477,18 @@ if(${CIFPP_CACHE_DIR})
)
endif()
set(CONFIG_TEMPLATE_FILE ${PROJECT_SOURCE_DIR}/cmake/cifppConfig.cmake.in)
set(CONFIG_TEMPLATE_FILE ${PROJECT_SOURCE_DIR}/cmake/cifpp-config.cmake.in)
configure_package_config_file(
${CONFIG_TEMPLATE_FILE}
${CMAKE_CURRENT_BINARY_DIR}/cifpp/cifppConfig.cmake
${CMAKE_CURRENT_BINARY_DIR}/cifpp/cifpp-config.cmake
INSTALL_DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/cifpp
PATH_VARS CIFPP_DATA_DIR
)
install(FILES
"${CMAKE_CURRENT_BINARY_DIR}/cifpp/cifppConfig.cmake"
"${CMAKE_CURRENT_BINARY_DIR}/cifpp/cifppConfigVersion.cmake"
"${CMAKE_CURRENT_BINARY_DIR}/cifpp/cifpp-config.cmake"
"${CMAKE_CURRENT_BINARY_DIR}/cifpp/cifpp-config-version.cmake"
DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/cifpp
COMPONENT Devel
)
@@ -412,23 +503,39 @@ set_property(TARGET cifpp APPEND PROPERTY
)
write_basic_package_version_file(
"${CMAKE_CURRENT_BINARY_DIR}/cifpp/cifppConfigVersion.cmake"
"${CMAKE_CURRENT_BINARY_DIR}/cifpp/cifpp-config-version.cmake"
VERSION ${PROJECT_VERSION}
COMPATIBILITY AnyNewerVersion
)
if(BUILD_TESTING)
find_package(Boost REQUIRED)
# We're using the older version 2 of Catch2
FetchContent_Declare(
Catch2
GIT_REPOSITORY https://github.com/catchorg/Catch2.git
GIT_TAG v2.13.9
)
list(APPEND CIFPP_tests unit-v2 unit-3d format model rename-compound sugar spinner)
FetchContent_MakeAvailable(Catch2)
list(APPEND CIFPP_tests
unit-v2
unit-3d
format
model
rename-compound
sugar
spinner
)
foreach(CIFPP_TEST IN LISTS CIFPP_tests)
set(CIFPP_TEST "${CIFPP_TEST}-test")
set(CIFPP_TEST_SOURCE "${CMAKE_CURRENT_SOURCE_DIR}/test/${CIFPP_TEST}.cpp")
add_executable(${CIFPP_TEST} ${CIFPP_TEST_SOURCE})
add_executable(${CIFPP_TEST} ${CIFPP_TEST_SOURCE} "${CMAKE_CURRENT_SOURCE_DIR}/test/test-main.cpp")
target_link_libraries(${CIFPP_TEST} PRIVATE Threads::Threads cifpp::cifpp Boost::boost)
target_link_libraries(${CIFPP_TEST} PRIVATE Threads::Threads cifpp::cifpp Catch2::Catch2)
target_include_directories(${CIFPP_TEST} PRIVATE "${EIGEN_INCLUDE_DIR}")
if(MSVC)
# Specify unwind semantics so that MSVC knowns how to handle exceptions
@@ -439,19 +546,23 @@ if(BUILD_TESTING)
add_custom_command(
OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/Run${CIFPP_TEST}.touch
COMMAND $<TARGET_FILE:${CIFPP_TEST}> -- ${CMAKE_CURRENT_SOURCE_DIR}/test)
COMMAND $<TARGET_FILE:${CIFPP_TEST}> --data-dir ${CMAKE_CURRENT_SOURCE_DIR}/test)
add_test(NAME ${CIFPP_TEST}
COMMAND $<TARGET_FILE:${CIFPP_TEST}> -- ${CMAKE_CURRENT_SOURCE_DIR}/test)
COMMAND $<TARGET_FILE:${CIFPP_TEST}> --data-dir ${CMAKE_CURRENT_SOURCE_DIR}/test)
endforeach()
endif()
# Optionally install the update scripts for CCD and dictionary files
if(CIFPP_INSTALL_UPDATE_SCRIPT)
if(${CMAKE_SYSTEM_NAME} STREQUAL "Linux" OR ${CMAKE_SYSTEM_NAME} STREQUAL "GNU")
set(CIFPP_CRON_DIR "${CIFPP_ETC_DIR}/cron.weekly")
elseif(UNIX) # assume all others are like FreeBSD...
set(CIFPP_CRON_DIR "${CIFPP_ETC_DIR}/periodic/weekly")
if("${CMAKE_INSTALL_PREFIX}" STREQUAL "/usr/local")
set(CIFPP_CRON_DIR "/etc/cron.weekly" CACHE PATH "The cron directory, for the update script")
else()
set(CIFPP_CRON_DIR "${CIFPP_ETC_DIR}/cron.weekly" CACHE PATH "The cron directory, for the update script")
endif()
elseif(${CMAKE_SYSTEM_NAME} STREQUAL "FreeBSD")
set(CIFPP_CRON_DIR "${CIFPP_ETC_DIR}/periodic/weekly" CACHE PATH "The cron directory, for the update script")
else()
message(FATAL_ERROR "Don't know where to install the update script")
endif()
@@ -464,15 +575,16 @@ if(CIFPP_INSTALL_UPDATE_SCRIPT)
)
install(DIRECTORY DESTINATION ${CIFPP_CACHE_DIR})
install(DIRECTORY DESTINATION "${CIFPP_ETC_DIR}/libcifpp/cache-update.d")
# a config to, to make it complete
# a config file, to make it complete
if(NOT EXISTS "${CIFPP_ETC_DIR}/libcifpp.conf")
file(WRITE ${CMAKE_CURRENT_BINARY_DIR}/libcifpp.conf [[# Uncomment the next line to enable automatic updates
# update=true
]])
install(FILES ${CMAKE_CURRENT_BINARY_DIR}/libcifpp.conf DESTINATION "${CIFPP_ETC_DIR}")
install(CODE "message(\"A configuration file has been written to ${CIFPP_ETC_DIR}/libcifpp.conf, please edit this file to enable automatic updates\")")
install(DIRECTORY DESTINATION "${CIFPP_ETC_DIR}/libcifpp/cache-update.d")
endif()
target_compile_definitions(cifpp PUBLIC CACHE_DIR="${CIFPP_CACHE_DIR}")
@@ -487,7 +599,7 @@ set(CPACK_SOURCE_TGZ ON)
set(CPACK_SOURCE_TBZ2 OFF)
set(CPACK_SOURCE_TXZ OFF)
set(CPACK_SOURCE_TZ OFF)
set(CPACK_SOURCE_IGNORE_FILES "/data/components.cif;/build;/.vscode;/.git")
set(CPACK_SOURCE_IGNORE_FILES "/rsrc/components.cif;/build;/.vscode;/.git")
set(CPACK_PACKAGE_FILE_NAME "${PROJECT_NAME}-${PROJECT_VERSION}")
set(CPACK_SOURCE_PACKAGE_FILE_NAME ${CPACK_PACKAGE_FILE_NAME})
include(CPack)

169
README.md
View File

@@ -1,10 +1,34 @@
[![github CI](https://github.com/pdb-redo/libcifpp/actions/workflows/cmake-multi-platform.yml/badge.svg)](https://github.com/pdb-redo/libcifpp/actions)
[![GitHub License](https://img.shields.io/github/license/pdb-redo/libcifpp)](https://github.com/pdb-redo/libcifpp/LICENSE)
# libcifpp
This library contains code to work with mmCIF and legacy PDB files.
As the name implies, this library was originally written to work with mmCIF files
using C++ as programming language. The design of this library leanes heavily on
the structure of CIF files. These files can be thought of as a text dump of a
relational databank with, often but not always, a very strict schema describing
the data. These schema's are called dictionaries.
Using information from the content of a mmCIF file and an optional schema,
libcifpp allows you to access the data in the file as a collection of datablock
each containing a collection of categories with rows of data. The categories can
be searched for data using queries written in regular C++ syntax. When a dictionary
was specified, inserted data is checked for validity. Likewise removal of data
may result in cascaded removal of linked data in other categories using
parent/child relationship information.
Since there were still many programs using the legacy PDB format at the time
development started, a layer was added that converts data to and from PDB format
into mmCIF format. This means you can manipulate PDB files as if they were
normal mmCIF files.
Apart from this basic functionality, libcifpp also offers code to help with
symmetry calculations, 3d manipulations and obtaining information from the CCD
[Chemical Component Dictionary](https://www.wwpdb.org/data/ccd).
## Documentation
The documentation can be found at https://www.hekkelman.com/libcifpp-doc/
The documentation can be found at [github.io](https://pdb-redo.github.io/libcifpp/)
## Synopsis
@@ -64,57 +88,138 @@ int main(int argc, char *argv[])
You might be able to use libcifpp from a package manager used by your
OS distribution. But most likely this package will be out-of-date.
Therefore it is recommended to build *libcifpp* from code. It is not
hard to do.
hard to do. But it is recommended to read the following instructions
carefully.
### Requirements
The code for this library was written in C++17. You therefore need a
recent compiler to build it. For the development gcc 9.4 and clang 9.0
recent compiler to build it. For the development gcc >= 9.4 and clang >= 9.0
have been used as well as MSVC version 2019.
Other requirements are:
The other requirement you really need to have installed on your computer
is a version of [CMake](https://cmake.org). For now the minimum version
is 3.16 but that may soon change into a higher version. You should also
install the gui version of CMake to set build options easily, on Debian
I prefer to use the curses version installed with `cmake-curses-gui`.
It is very useful to have [mrc](https://github.com/mhekkel/mrc) available.
However, this is only an option if you use Windows or an operating system
using the ELF executable format (i.e. Linux or FreeBSD). MRC is a resource
compiler that allows including data files into the executable making them
easier to install.
Other libraries you might want to install beforehand are:
- [cmake](https://cmake.org) A build tool.
- [mrc](https://github.com/mhekkel/mrc), a resource compiler that
allows including data files into the executable making them easier to
install. Strictly speaking this is optional, but at the expense of
functionality.
- [libeigen](https://eigen.tuxfamily.org/index.php?title=Main_Page), a
library to do amongst others matrix calculations. This usually can be
installed using your package manager, in Debian/Ubuntu it is called
`libeigen3-dev`
- zlib, the development version of this library. On Debian/Ubuntu this
is the package `zlib1g-dev`.
- [boost](https://www.boost.org).
When building using MS Visual Studio, you will also need [libzeep](https://github.com/mhekkel/libzeep)
since MSVC does not yet provide a C++ template required by libcifpp.
The Boost libraries are only needed in case you want to build the test
code or if you are using GCC. That last condition is due to a long
standing bug in the implementation of std::regex. It simply crashes
on the regular expressions used in the mmcif_pdbx dictionary and so
we use the boost regex implementation instead.
- [zlib](https://github.com/madler/zlib), the development version of this
library. On Debian/Ubuntu this is the package `zlib1g-dev`.
- [boost](https://www.boost.org), in Debian/Ubuntu this is `libboost-dev`.
The Boost libraries are only needed in case you are using GCC due to a long
standing bug in GNU's implementation of std::regex. It simply crashes
on the regular expressions used in the mmcif_pdbx dictionary and so
we use the boost regex implementation instead.
### Building
Building the code is as simple as typing:
First you need to download the code:
```console
git clone https://github.com/PDB-REDO/libcifpp.git --recurse-submodules
git clone https://github.com/PDB-REDO/libcifpp.git
cd libcifpp
cmake -S . -B build -DCMAKE_INSTALL_PREFIX=$HOME/.local -DCMAKE_BUILD_TYPE=Release
cmake --build build
cmake --install build
```
This checks out the source code from github, creates a new directory
where cmake stores its files. Run a configure, build the code and then
it installs the library and auxiliary files.
You should start by considering where to install libcifpp. If you have
sufficient permissions on your computer you perhaps should use the
default but libcifpp can be configured to be installed anywhere
including e.g. *$HOME/.local*.
Next step is to configure, for this use the CMake gui application. If you
installed the curses version of cmake you can type `ccmake`. On Windows
you can use `cmake-gui.exe`.
To install in the default location:
```console
ccmake -S . -B build
```
To install elsewhere, e.g. *$HOME/.local*:
```console
ccmake -S . -B build -DCMAKE_INSTALL_PREFIX=$HOME/.local
```
In the cmake window, start the configure command (use button or press 'c').
After the first configure step you will see a list of settable options.
Alter these to match your preferences. Most options are self explaining
and contain a description. Some may need a bit more explanation:
- CIFPP_DATA_DIR, this directory will be used to store initial versions
of the mmcif_pdbx dictionary as well as the optional CCD file.
- CIFPP_DOWNLOAD_CCD
The CCD file is huge and perhaps you think you don't
need it. In that case you can leave this OFF. But that will limit the
use cases.
- CIFPP_INSTALL_UPDATE_SCRIPT
The files in CIFPP_DATA_DIR are quickly becoming out of date. On
FreeBSD and Linux you can install a script that updates these files
on a weekly basis.
- CIFPP_CRON_DIR
The directory where the update script is to be installed.
- CIFPP_ETC_DIR
The update script will only work if the file called *libcifpp.conf*
in this *etc* directory will contain an uncommented line with
```console
update=true
```
- CIFPP_CACHE_DIR
When you installed and enabled the update script, new files are
written to this directory.
- CIFPP_RECREATE_SYMOP_DATA
If you had CCP4 sourced into your environment, this option allows
you to recreate the symop data file.
- BUILD_FOR_CCP4
Build a special version of libcifpp to be installed in the CCP4
environment.
After setting these options you can run the configure step again and
then use generate to create the makefiles.
Building and installing is then as simple as:
```console
cmake --build build
cmake --install build
```
If this fails due to lack of permissions, you can try:
```console
sudo cmake --install build
```
Tests are created by default, and to test the code you can run:
```console
cmake --build build
ctest --test-dir build
ctest --test-dir build
```

View File

@@ -1,3 +1,12 @@
Version 6.0.0
- Drop the use of CCP4's monomer library for compound information
Version 5.2.5
- Correctly import the Eigen3 library
Version 5.2.4
- Changes required to build on Windows
Version 5.2.3
- New constructors for cif::item, one taking std::optional values
and another taking only a name resulting in a value '.' (i.e. inapplicable).

View File

@@ -56,6 +56,7 @@ endif()
cmake_pop_check_state()
set(Atomic_FOUND ${_found} CACHE BOOL "TRUE if we can run a program using std::atomic" FORCE)
mark_as_advanced(Atomic_FOUND)
if(Atomic_FIND_REQUIRED AND NOT Atomic_FOUND)
message(FATAL_ERROR "Cannot run simple program using std::atomic")

View File

@@ -67,6 +67,7 @@ endif()
cmake_pop_check_state()
set(Filesystem_FOUND ${_found} CACHE BOOL "TRUE if we can run a program using std::filesystem" FORCE)
mark_as_advanced(Filesystem_FOUND)
if(Filesystem_FIND_REQUIRED AND NOT Filesystem_FOUND)
message(FATAL_ERROR "Cannot run simple program using std::filesystem")

View File

@@ -0,0 +1,12 @@
@PACKAGE_INIT@
include("${CMAKE_CURRENT_LIST_DIR}/cifpp-targets.cmake")
set_and_check(CIFPP_SHARE_DIR "@PACKAGE_CIFPP_DATA_DIR@")
include(CMakeFindDependencyMacro)
find_dependency(Threads)
find_dependency(ZLIB REQUIRED)
check_required_components(cifpp)

View File

@@ -1,19 +0,0 @@
@PACKAGE_INIT@
include("${CMAKE_CURRENT_LIST_DIR}/cifppTargets.cmake")
# Note that this set_and_check needs te be executed before
# find_dependency of Eigen3, otherwise the path is
# not found....
set_and_check(CIFPP_SHARE_DIR "@PACKAGE_CIFPP_DATA_DIR@")
include(CMakeFindDependencyMacro)
find_dependency(Threads)
find_dependency(ZLIB REQUIRED)
if(MSVC)
find_dependency(zeep REQUIRED)
endif()
check_required_components(cifpp)

View File

@@ -44,11 +44,7 @@
/// The data is loaded by default from a file called `components.cif`. This file
/// is located using load_resource. (See documentation on cif::load_resource for more information)
///
/// But if the CCP4 environment is available at runtime, the compound information
/// may also be generated from the CCP4 monomer library.
///
/// Note that the information in CCP4 and CCD is not equal.
///
/// Note that since version 6 the CCP4 monomer library is no longer used.
/// See also :doc:`/compound` for more information.
@@ -157,10 +153,6 @@ class compound
float formula_weight() const { return m_formula_weight; } ///< Return the formula mass of the chemical component in Daltons.
int formal_charge() const { return m_formal_charge; } ///< Return the formal charge on the chemical component.
/// The group record is only available in CCP4 monomer library files.
/// For CCD entries this value will always contain 'non-polymer'
std::string group() const { return m_group; }
const std::vector<compound_atom> &atoms() const { return m_atoms; } ///< Return the list of atoms for this compound
const std::vector<compound_bond> &bonds() const { return m_bonds; } ///< Return the list of bonds for this compound
@@ -176,8 +168,6 @@ class compound
private:
friend class compound_factory_impl;
friend class CCD_compound_factory_impl;
friend class CCP4_compound_factory_impl;
compound(cif::datablock &db);
compound(cif::datablock &db, const std::string &id, const std::string &name, const std::string &type, const std::string &group);
@@ -246,6 +236,8 @@ class compound_factory
CIFPP_EXPORT static const std::map<std::string, char> kAAMap, ///< Globally accessible static list of the default amino acids
kBaseMap; ///< Globally accessible static list of the default bases
void report_missing_compound(const std::string &compound_id);
private:
compound_factory();

View File

@@ -712,7 +712,7 @@ conditional_iterator_proxy<Category, Ts...>::conditional_iterator_proxy(Category
++mCBegin;
}
else
mCBegin == mCEnd;
mCBegin = mCEnd;
uint16_t i = 0;
((mCix[i++] = m_cat->get_column_ix(names)), ...);

View File

@@ -38,15 +38,44 @@
#include <vector>
#if __has_include(<experimental/type_traits>)
#include <experimental/type_traits>
namespace std_experimental = std::experimental;
#else
// sub optimal, but replicating the same code is worse
#include <zeep/type-traits.hpp>
// A quick hack to work around the missing is_detected in MSVC
namespace std_experimental
{
namespace detail
{
template <class AlwaysVoid, template <class...> class Op, class... Args>
struct detector
{
using value_t = std::false_type;
};
template <template <class...> class Op, class... Args>
struct detector<std::void_t<Op<Args...>>, Op, Args...>
{
using value_t = std::true_type;
};
} // namespace detail
template <template <class...> class Op, class... Args>
using is_detected = typename detail::detector<void, Op, Args...>::value_t;
template <template <class...> class Op, class... Args>
const auto is_detected_v = is_detected<Op, Args...>::value;
} // namespace std_experimental
#endif
/**
* \file text.hpp
*
*
* Various text manipulating routines
*/
@@ -82,15 +111,15 @@ void to_upper(std::string &s);
/**
* @brief Join the strings in the range [ @a a, @a e ) using
* @a sep as separator
*
*
* Example usage:
*
*
* @code {.cpp}
* std::vector<std::string> v{ "aap", "noot", "mies" };
*
*
* assert(cif::join(v.begin(), v.end(), ", ") == "aap, noot, mies");
* @endcode
*
*
*/
template <typename IterType>
std::string join(IterType b, IterType e, std::string_view sep)
@@ -121,15 +150,15 @@ std::string join(IterType b, IterType e, std::string_view sep)
/**
* @brief Join the strings in the array @a arr using @a sep as separator
*
*
* Example usage:
*
*
* @code {.cpp}
* std::list<std::string> v{ "aap", "noot", "mies" };
*
*
* assert(cif::join(v, ", ") == "aap, noot, mies");
* @endcode
*
*
*/
template <typename V>
std::string join(const V &arr, std::string_view sep)
@@ -139,20 +168,20 @@ std::string join(const V &arr, std::string_view sep)
/**
* @brief Split the string in @a s based on the characters in @a separators
*
*
* Each of the characters in @a separators induces a split.
*
*
* When suppress_empty is true, empty strings are not produced in the
* resulting array.
*
*
* Example:
*
*
* @code {.cpp}
* auto v = cif::split("aap:noot,,mies", ":,", true);
*
*
* assert(v == std::vector{"aap", "noot", "mies"});
* @endcode
*
*
*/
template <typename StringType = std::string_view>
std::vector<StringType> split(std::string_view s, std::string_view separators, bool suppress_empty = false)
@@ -183,7 +212,7 @@ std::vector<StringType> split(std::string_view s, std::string_view separators, b
/**
* @brief Replace all occurrences of @a what in string @a s with the string @a with
*
*
* The string @a with may be empty in which case each occurrence of @a what is simply
* deleted.
*/
@@ -270,7 +299,6 @@ struct iless
}
};
/// iset is a std::set of std::string but with a comparator that
/// ignores character case.
using iset = std::set<std::string, iless>;
@@ -290,12 +318,12 @@ inline char tolower(int ch)
// --------------------------------------------------------------------
/** \brief return a tuple consisting of the category and item name for @a tag
*
*
* The category name is stripped of its leading underscore character.
*
*
* If no dot character was found, the category name is empty. That's for
* cif 1.0 formatted data.
*/
*/
std::tuple<std::string, std::string> split_tag_name(std::string_view tag);
@@ -307,7 +335,7 @@ std::string cif_id_for_number(int number);
// --------------------------------------------------------------------
/** \brief custom word wrapping routine.
*
*
* Wrap the text in @a text based on a maximum line width @a width using
* a dynamic programming approach to get the most efficient filling of
* the space.
@@ -574,10 +602,10 @@ using from_chars_function = decltype(std::from_chars(std::declval<const char *>(
/**
* @brief Helper to select the best implementation of charconv based on availability of the
* function in the std:: namespace
*
*
* @tparam T The type for which we want to find a from_chars/to_chars function
*/
template <typename T>
using selected_charconv = typename std::conditional_t<std::experimental::is_detected_v<from_chars_function, T>, std_charconv<T>, my_charconv<T>>;
using selected_charconv = typename std::conditional_t<std_experimental::is_detected_v<from_chars_function, T>, std_charconv<T>, my_charconv<T>>;
} // namespace cif

View File

@@ -365,6 +365,14 @@ std::unique_ptr<std::istream> load_resource(std::filesystem::path name);
void add_file_resource(const std::string &name, std::filesystem::path dataFile);
/**
* @brief List all the file resources added with cif::add_file_resource.
*
* @param os The std::ostream to write the directories to
*/
void list_file_resources(std::ostream &os);
/**
* @brief Add a directory to the list of search directories. This list is
* searched in a last-in-first-out order.
@@ -379,4 +387,12 @@ void add_file_resource(const std::string &name, std::filesystem::path dataFile);
void add_data_directory(std::filesystem::path dataDir);
/**
* @brief List all the data directories, for error reporting on missing resources.
*
* @param os The std::ostream to write the directories to
*/
void list_data_directories(std::ostream &os);
} // namespace cif

View File

@@ -315,11 +315,7 @@ class validator_factory
{
public:
/// @brief Return the singleton instance
static validator_factory &instance()
{
static validator_factory s_instance;
return s_instance;
}
static validator_factory &instance();
/// @brief Return the validator with name @a dictionary_name
const validator &operator[](std::string_view dictionary_name);

View File

@@ -1,69 +0,0 @@
# Copyright 2018 Mike Dev
# Copyright 2019 Peter Dimov
# 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
# We support CMake 3.5, but prefer 3.16 policies and behavior
cmake_minimum_required(VERSION 3.5...3.16)
project(boost_regex VERSION "${BOOST_SUPERPROJECT_VERSION}" LANGUAGES CXX)
add_library(boost_regex INTERFACE)
add_library(Boost::regex ALIAS boost_regex)
target_include_directories(boost_regex INTERFACE include)
option(BOOST_REGEX_STANDALONE "Boost.Regex: Enable Standalone Mode (i.e. no Boost dependencies)")
if(NOT BOOST_REGEX_STANDALONE)
target_link_libraries(boost_regex
INTERFACE
Boost::config
Boost::throw_exception
Boost::predef
Boost::assert
)
else()
target_compile_definitions(boost_regex
INTERFACE BOOST_REGEX_STANDALONE
)
endif()
find_package(ICU COMPONENTS data i18n uc QUIET)
#option(BOOST_REGEX_ENABLE_ICU "Boost.Regex: enable ICU support" ${ICU_FOUND})
if(ICU_FOUND)
add_library(boost_regex_icu INTERFACE)
add_library(Boost::regex_icu ALIAS boost_regex_icu)
target_include_directories(boost_regex_icu INTERFACE include)
if(NOT BOOST_REGEX_STANDALONE)
target_link_libraries(boost_regex_icu
INTERFACE
Boost::config
Boost::throw_exception
Boost::predef
Boost::assert
)
else()
target_compile_definitions(boost_regex_icu
INTERFACE BOOST_REGEX_STANDALONE
)
endif()
find_package(ICU COMPONENTS data i18n uc REQUIRED)
target_link_libraries(boost_regex_icu INTERFACE ICU::data ICU::i18n ICU::uc)
endif()

View File

@@ -1,23 +0,0 @@
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

@@ -1,47 +0,0 @@
Boost Regex Library
============================
The Boost Regex library provides regular expression support for C++, this library is the ancestor to std::regex and still goes beyond
and offers some advantages to, the standard version.
The full documentation is available on [boost.org](http://www.boost.org/doc/libs/release/libs/regex/index.html).
## Standalone Mode ##
This library may now be used in "standalone" mode without the rest of the Boost C++ libraries, in order to do this you must either:
* Have a C++17 compiler that supports __has_include, in this case if <boost/config.hpp> is not present then the library will automoatically enter standalone mode. Or:
* Define BOOST_REGEX_STANDALONE when building.
The main difference between the 2 modes, is that when Boost.Config is present the library will automatically configure itself around various compiler defects. In particular in order to use the library with exception support turned off, you will either need a copy of Boost.Config in your include path, or else manually define BOOST_NO_EXCEPTIONS when building.
In any event, to obtain a standalone version of this library, simply download a .zip of the "master" branch of this repository.
## Support, bugs and feature requests ##
Bugs and feature requests can be reported through the [Gitub issue tracker](https://github.com/boostorg/regex/issues)
(see [open issues](https://github.com/boostorg/regex/issues) and
[closed issues](https://github.com/boostorg/regex/issues?utf8=%E2%9C%93&q=is%3Aissue+is%3Aclosed)).
You can submit your changes through a [pull request](https://github.com/boostorg/regex/pulls).
There is no mailing-list specific to Boost Regex, although you can use the general-purpose Boost [mailing-list](http://lists.boost.org/mailman/listinfo.cgi/boost-users) using the tag [regex].
## Development ##
Clone the whole boost project, which includes the individual Boost projects as submodules ([see boost+git doc](https://github.com/boostorg/boost/wiki/Getting-Started)):
git clone https://github.com/boostorg/boost
cd boost
git submodule update --init
The Boost Regex Library is located in `libs/regex/`.
### Running tests ###
First, make sure you are in `libs/regex/test`.
You can either run all the tests listed in `Jamfile.v2` or run a single test:
../../../b2 <- run all tests
../../../b2 regex_regress <- single test

View File

@@ -1,43 +0,0 @@
/*
*
* Copyright (c) 1998-2002
* John Maddock
*
* Use, modification and distribution are subject to 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)
*
*/
/*
* LOCATION: see http://www.boost.org/libs/regex for most recent version.
* FILE cregex.cpp
* VERSION see <boost/version.hpp>
* DESCRIPTION: Declares POSIX API functions
* + boost::RegEx high level wrapper.
*/
#ifndef BOOST_RE_CREGEX_HPP
#define BOOST_RE_CREGEX_HPP
#ifndef BOOST_REGEX_CONFIG_HPP
#include <boost/regex/config.hpp>
#endif
#ifdef BOOST_REGEX_CXX03
#include <boost/regex/v4/cregex.hpp>
#else
#include <boost/regex/v5/cregex.hpp>
#endif
#endif /* include guard */

View File

@@ -1,100 +0,0 @@
/*
*
* Copyright (c) 1998-2000
* Dr John Maddock
*
* Use, modification and distribution are subject to 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)
*
*/
/*
* LOCATION: see http://www.boost.org/libs/regex for documentation.
* FILE regex.h
* VERSION 3.12
* DESCRIPTION: Declares POSIX API functions
*/
#ifndef BOOST_RE_REGEX_H
#define BOOST_RE_REGEX_H
#include <boost/cregex.hpp>
/*
* add using declarations to bring POSIX API functions into
* global scope, only if this is C++ (and not C).
*/
#ifdef __cplusplus
using boost::regoff_t;
using boost::regex_tA;
using boost::regmatch_t;
using boost::REG_BASIC;
using boost::REG_EXTENDED;
using boost::REG_ICASE;
using boost::REG_NOSUB;
using boost::REG_NEWLINE;
using boost::REG_NOSPEC;
using boost::REG_PEND;
using boost::REG_DUMP;
using boost::REG_NOCOLLATE;
using boost::REG_ESCAPE_IN_LISTS;
using boost::REG_NEWLINE_ALT;
using boost::REG_PERL;
using boost::REG_AWK;
using boost::REG_GREP;
using boost::REG_EGREP;
using boost::REG_ASSERT;
using boost::REG_INVARG;
using boost::REG_ATOI;
using boost::REG_ITOA;
using boost::REG_NOTBOL;
using boost::REG_NOTEOL;
using boost::REG_STARTEND;
using boost::reg_comp_flags;
using boost::reg_exec_flags;
using boost::regcompA;
using boost::regerrorA;
using boost::regexecA;
using boost::regfreeA;
#ifndef BOOST_NO_WREGEX
using boost::regcompW;
using boost::regerrorW;
using boost::regexecW;
using boost::regfreeW;
using boost::regex_tW;
#endif
using boost::REG_NOERROR;
using boost::REG_NOMATCH;
using boost::REG_BADPAT;
using boost::REG_ECOLLATE;
using boost::REG_ECTYPE;
using boost::REG_EESCAPE;
using boost::REG_ESUBREG;
using boost::REG_EBRACK;
using boost::REG_EPAREN;
using boost::REG_EBRACE;
using boost::REG_BADBR;
using boost::REG_ERANGE;
using boost::REG_ESPACE;
using boost::REG_BADRPT;
using boost::REG_EEND;
using boost::REG_ESIZE;
using boost::REG_ERPAREN;
using boost::REG_EMPTY;
using boost::REG_E_MEMORY;
using boost::REG_E_UNKNOWN;
using boost::reg_errcode_t;
#endif /* __cplusplus */
#endif /* BOOST_RE_REGEX_H */

View File

@@ -1,41 +0,0 @@
/*
*
* Copyright (c) 1998-2002
* John Maddock
*
* Use, modification and distribution are subject to 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)
*
*/
/*
* LOCATION: see http://www.boost.org/libs/regex for documentation.
* FILE regex.cpp
* VERSION see <boost/version.hpp>
* DESCRIPTION: Declares boost::basic_regex<> and associated
* functions and classes. This header is the main
* entry point for the template regex code.
*/
/* start with C compatibility API */
#ifndef BOOST_RE_REGEX_HPP
#define BOOST_RE_REGEX_HPP
#ifndef BOOST_REGEX_CONFIG_HPP
#include <boost/regex/config.hpp>
#endif
#ifdef BOOST_REGEX_CXX03
#include <boost/regex/v4/regex.hpp>
#else
#include <boost/regex/v5/regex.hpp>
#endif
#endif // include

File diff suppressed because it is too large Load Diff

View File

@@ -1,480 +0,0 @@
/*
*
* Copyright (c) 1998-2002
* John Maddock
*
* Use, modification and distribution are subject to 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)
*
*/
/*
* LOCATION: see http://www.boost.org for most recent version.
* FILE config.hpp
* VERSION see <boost/version.hpp>
* DESCRIPTION: regex extended config setup.
*/
#ifndef BOOST_REGEX_CONFIG_HPP
#define BOOST_REGEX_CONFIG_HPP
#if !((__cplusplus >= 201103L) || (defined(_MSC_VER) && (_MSC_VER >= 1600)) || defined(BOOST_REGEX_CXX03))
# define BOOST_REGEX_CXX03
#endif
#if defined(BOOST_REGEX_RECURSIVE) && !defined(BOOST_REGEX_CXX03)
# define BOOST_REGEX_CXX03
#endif
#if defined(__has_include)
#if !defined(BOOST_REGEX_STANDALONE) && !__has_include(<boost/version.hpp>)
#define BOOST_REGEX_STANDALONE
#endif
#endif
/*
* Borland C++ Fix/error check
* this has to go *before* we include any std lib headers:
*/
#if defined(__BORLANDC__) && !defined(__clang__)
# include <boost/regex/config/borland.hpp>
#endif
#ifndef BOOST_REGEX_STANDALONE
#include <boost/version.hpp>
#endif
/*************************************************************************
*
* Asserts:
*
*************************************************************************/
#ifdef BOOST_REGEX_STANDALONE
#include <cassert>
# define BOOST_REGEX_ASSERT(x) assert(x)
#else
#include <boost/assert.hpp>
# define BOOST_REGEX_ASSERT(x) BOOST_ASSERT(x)
#endif
/*****************************************************************************
*
* Include all the headers we need here:
*
****************************************************************************/
#ifdef __cplusplus
# ifndef BOOST_REGEX_USER_CONFIG
# define BOOST_REGEX_USER_CONFIG <boost/regex/user.hpp>
# endif
# include BOOST_REGEX_USER_CONFIG
#ifndef BOOST_REGEX_STANDALONE
# include <boost/config.hpp>
# include <boost/predef.h>
#endif
#else
/*
* C build,
* don't include <boost/config.hpp> because that may
* do C++ specific things in future...
*/
# include <stdlib.h>
# include <stddef.h>
# ifdef _MSC_VER
# define BOOST_MSVC _MSC_VER
# endif
#endif
/****************************************************************************
*
* Legacy support:
*
*******************************************************************************/
#if defined(BOOST_NO_STD_LOCALE) || defined(BOOST_NO_CXX11_HDR_MUTEX) || defined(BOOST_NO_CXX11_HDR_TYPE_TRAITS) \
|| defined(BOOST_NO_CXX11_HDR_ATOMIC) || defined(BOOST_NO_CXX11_ALLOCATOR) || defined(BOOST_NO_CXX11_SMART_PTR) \
|| defined(BOOST_NO_CXX11_STATIC_ASSERT) || defined(BOOST_NO_NOEXCEPT)
#ifndef BOOST_REGEX_CXX03
# define BOOST_REGEX_CXX03
#endif
#endif
/*****************************************************************************
*
* Boilerplate regex config options:
*
****************************************************************************/
/* Obsolete macro, use BOOST_VERSION instead: */
#define BOOST_RE_VERSION 500
/* fix: */
#if defined(_UNICODE) && !defined(UNICODE)
#define UNICODE
#endif
#define BOOST_REGEX_JOIN(X, Y) BOOST_REGEX_DO_JOIN(X, Y)
#define BOOST_REGEX_DO_JOIN(X, Y) BOOST_REGEX_DO_JOIN2(X,Y)
#define BOOST_REGEX_DO_JOIN2(X, Y) X##Y
#ifdef BOOST_FALLTHROUGH
# define BOOST_REGEX_FALLTHROUGH BOOST_FALLTHROUGH
#else
#if defined(__clang__) && (__cplusplus >= 201103L) && defined(__has_warning)
# if __has_feature(cxx_attributes) && __has_warning("-Wimplicit-fallthrough")
# define BOOST_REGEX_FALLTHROUGH [[clang::fallthrough]]
# endif
#endif
#if !defined(BOOST_REGEX_FALLTHROUGH) && defined(__INTEL_COMPILER) && (__INTEL_COMPILER >= 1800) && (__cplusplus >= 201703)
# define BOOST_REGEX_FALLTHROUGH [[fallthrough]]
#endif
#if !defined(BOOST_REGEX_FALLTHROUGH) && defined(__GNUC__) && (__GNUC__ >= 7)
# define BOOST_REGEX_FALLTHROUGH __attribute__((fallthrough))
#endif
#if !defined(BOOST_REGEX_FALLTHROUGH)
# define BOOST_REGEX_FALLTHROUGH
#endif
#endif
#ifdef BOOST_NORETURN
# define BOOST_REGEX_NORETURN BOOST_NORETURN
#else
# define BOOST_REGEX_NORETURN
#endif
/*
* Define a macro for the namespace that details are placed in, this includes the Boost
* version number to avoid mismatched header and library versions:
*/
#define BOOST_REGEX_DETAIL_NS BOOST_REGEX_JOIN(re_detail_, BOOST_RE_VERSION)
/*
* Fix for gcc prior to 3.4: std::ctype<wchar_t> doesn't allow
* masks to be combined, for example:
* std::use_facet<std::ctype<wchar_t> >.is(std::ctype_base::lower|std::ctype_base::upper, L'a');
* returns *false*.
*/
#if defined(__GLIBCPP__) && defined(BOOST_REGEX_CXX03)
# define BOOST_REGEX_BUGGY_CTYPE_FACET
#endif
/*
* If there isn't good enough wide character support then there will
* be no wide character regular expressions:
*/
#if (defined(BOOST_NO_CWCHAR) || defined(BOOST_NO_CWCTYPE) || defined(BOOST_NO_STD_WSTRING))
# if !defined(BOOST_NO_WREGEX)
# define BOOST_NO_WREGEX
# endif
#else
# if defined(__sgi) && (defined(__SGI_STL_PORT) || defined(_STLPORT_VERSION))
/* STLPort on IRIX is misconfigured: <cwctype> does not compile
* as a temporary fix include <wctype.h> instead and prevent inclusion
* of STLPort version of <cwctype> */
# include <wctype.h>
# define __STLPORT_CWCTYPE
# define _STLP_CWCTYPE
# endif
#if defined(__cplusplus) && defined(BOOST_REGEX_CXX03)
# include <boost/regex/config/cwchar.hpp>
#endif
#endif
/*
* If Win32 support has been disabled for boost in general, then
* it is for regex in particular:
*/
#if defined(BOOST_DISABLE_WIN32) && !defined(BOOST_REGEX_NO_W32)
# define BOOST_REGEX_NO_W32
#endif
/* disable our own file-iterators and mapfiles if we can't
* support them: */
#if defined(_WIN32)
# if defined(BOOST_REGEX_NO_W32) || BOOST_PLAT_WINDOWS_RUNTIME
# define BOOST_REGEX_NO_FILEITER
# endif
#else /* defined(_WIN32) */
# if !defined(BOOST_HAS_DIRENT_H)
# define BOOST_REGEX_NO_FILEITER
# endif
#endif
/* backwards compatibitity: */
#if defined(BOOST_RE_NO_LIB)
# define BOOST_REGEX_NO_LIB
#endif
#if defined(__GNUC__) && !defined(_MSC_VER) && (defined(_WIN32) || defined(__CYGWIN__))
/* gcc on win32 has problems if you include <windows.h>
(sporadically generates bad code). */
# define BOOST_REGEX_NO_W32
#endif
#if defined(__COMO__) && !defined(BOOST_REGEX_NO_W32) && !defined(_MSC_EXTENSIONS)
# define BOOST_REGEX_NO_W32
#endif
#ifdef BOOST_REGEX_STANDALONE
# if defined(_MSC_VER) && !defined(__clang__) && !defined(__GNUC__)
# define BOOST_REGEX_MSVC _MSC_VER
#endif
#elif defined(BOOST_MSVC)
# define BOOST_REGEX_MSVC BOOST_MSVC
#endif
/*****************************************************************************
*
* Set up dll import/export options:
*
****************************************************************************/
#if (defined(BOOST_REGEX_DYN_LINK) || defined(BOOST_ALL_DYN_LINK)) && !defined(BOOST_REGEX_STATIC_LINK) && defined(BOOST_SYMBOL_IMPORT)
# if defined(BOOST_REGEX_SOURCE)
# define BOOST_REGEX_BUILD_DLL
# define BOOST_REGEX_DECL BOOST_SYMBOL_EXPORT
# else
# define BOOST_REGEX_DECL BOOST_SYMBOL_IMPORT
# endif
#else
# define BOOST_REGEX_DECL
#endif
#ifdef BOOST_REGEX_CXX03
#if !defined(BOOST_REGEX_NO_LIB) && !defined(BOOST_REGEX_SOURCE) && !defined(BOOST_ALL_NO_LIB) && defined(__cplusplus)
# define BOOST_LIB_NAME boost_regex
# if defined(BOOST_REGEX_DYN_LINK) || defined(BOOST_ALL_DYN_LINK)
# define BOOST_DYN_LINK
# endif
# ifdef BOOST_REGEX_DIAG
# define BOOST_LIB_DIAGNOSTIC
# endif
# include <boost/config/auto_link.hpp>
#endif
#endif
/*****************************************************************************
*
* Set up function call type:
*
****************************************************************************/
#if defined(_MSC_VER) && defined(_MSC_EXTENSIONS)
#if defined(_DEBUG) || defined(__MSVC_RUNTIME_CHECKS) || defined(_MANAGED) || defined(BOOST_REGEX_NO_FASTCALL)
# define BOOST_REGEX_CALL __cdecl
#else
# define BOOST_REGEX_CALL __fastcall
#endif
# define BOOST_REGEX_CCALL __cdecl
#endif
#if defined(__BORLANDC__) && !defined(BOOST_DISABLE_WIN32)
#if defined(__clang__)
# define BOOST_REGEX_CALL __cdecl
# define BOOST_REGEX_CCALL __cdecl
#else
# define BOOST_REGEX_CALL __fastcall
# define BOOST_REGEX_CCALL __stdcall
#endif
#endif
#ifndef BOOST_REGEX_CALL
# define BOOST_REGEX_CALL
#endif
#ifndef BOOST_REGEX_CCALL
#define BOOST_REGEX_CCALL
#endif
/*****************************************************************************
*
* Set up localisation model:
*
****************************************************************************/
/* backwards compatibility: */
#ifdef BOOST_RE_LOCALE_C
# define BOOST_REGEX_USE_C_LOCALE
#endif
#ifdef BOOST_RE_LOCALE_CPP
# define BOOST_REGEX_USE_CPP_LOCALE
#endif
#if defined(__CYGWIN__)
# define BOOST_REGEX_USE_C_LOCALE
#endif
/* use C++ locale when targeting windows store */
#if BOOST_PLAT_WINDOWS_RUNTIME
# define BOOST_REGEX_USE_CPP_LOCALE
# define BOOST_REGEX_NO_WIN32_LOCALE
#endif
/* Win32 defaults to native Win32 locale: */
#if defined(_WIN32) && \
!defined(BOOST_REGEX_USE_WIN32_LOCALE) && \
!defined(BOOST_REGEX_USE_C_LOCALE) && \
!defined(BOOST_REGEX_USE_CPP_LOCALE) && \
!defined(BOOST_REGEX_NO_W32) && \
!defined(BOOST_REGEX_NO_WIN32_LOCALE)
# define BOOST_REGEX_USE_WIN32_LOCALE
#endif
/* otherwise use C++ locale if supported: */
#if !defined(BOOST_REGEX_USE_WIN32_LOCALE) && !defined(BOOST_REGEX_USE_C_LOCALE) && !defined(BOOST_REGEX_USE_CPP_LOCALE) && !defined(BOOST_NO_STD_LOCALE)
# define BOOST_REGEX_USE_CPP_LOCALE
#endif
/* otherwise use C locale: */
#if !defined(BOOST_REGEX_USE_WIN32_LOCALE) && !defined(BOOST_REGEX_USE_C_LOCALE) && !defined(BOOST_REGEX_USE_CPP_LOCALE)
# define BOOST_REGEX_USE_C_LOCALE
#endif
#ifndef BOOST_REGEX_MAX_STATE_COUNT
# define BOOST_REGEX_MAX_STATE_COUNT 100000000
#endif
/*****************************************************************************
*
* Error Handling for exception free compilers:
*
****************************************************************************/
#ifdef BOOST_NO_EXCEPTIONS
/*
* If there are no exceptions then we must report critical-errors
* the only way we know how; by terminating.
*/
#include <stdexcept>
#include <string>
#include <boost/throw_exception.hpp>
# define BOOST_REGEX_NOEH_ASSERT(x)\
if(0 == (x))\
{\
std::string s("Error: critical regex++ failure in: ");\
s.append(#x);\
std::runtime_error e(s);\
boost::throw_exception(e);\
}
#else
/*
* With exceptions then error handling is taken care of and
* there is no need for these checks:
*/
# define BOOST_REGEX_NOEH_ASSERT(x)
#endif
/*****************************************************************************
*
* Stack protection under MS Windows:
*
****************************************************************************/
#if !defined(BOOST_REGEX_NO_W32) && !defined(BOOST_REGEX_V3)
# if(defined(_WIN32) || defined(_WIN64) || defined(_WINCE)) \
&& !(defined(__GNUC__) || defined(__BORLANDC__) && defined(__clang__)) \
&& !(defined(__BORLANDC__) && (__BORLANDC__ >= 0x600)) \
&& !(defined(__MWERKS__) && (__MWERKS__ <= 0x3003))
# define BOOST_REGEX_HAS_MS_STACK_GUARD
# endif
#elif defined(BOOST_REGEX_HAS_MS_STACK_GUARD)
# undef BOOST_REGEX_HAS_MS_STACK_GUARD
#endif
#if defined(__cplusplus) && defined(BOOST_REGEX_HAS_MS_STACK_GUARD)
namespace boost{
namespace BOOST_REGEX_DETAIL_NS{
BOOST_REGEX_DECL void BOOST_REGEX_CALL reset_stack_guard_page();
}
}
#endif
/*****************************************************************************
*
* Algorithm selection and configuration.
* These options are now obsolete for C++11 and later (regex v5).
*
****************************************************************************/
#if !defined(BOOST_REGEX_RECURSIVE) && !defined(BOOST_REGEX_NON_RECURSIVE)
# if defined(BOOST_REGEX_HAS_MS_STACK_GUARD) && !defined(_STLP_DEBUG) && !defined(__STL_DEBUG) && !(defined(_MSC_VER) && (_MSC_VER >= 1400)) && defined(BOOST_REGEX_CXX03)
# define BOOST_REGEX_RECURSIVE
# else
# define BOOST_REGEX_NON_RECURSIVE
# endif
#endif
#ifdef BOOST_REGEX_NON_RECURSIVE
# ifdef BOOST_REGEX_RECURSIVE
# error "Can't set both BOOST_REGEX_RECURSIVE and BOOST_REGEX_NON_RECURSIVE"
# endif
# ifndef BOOST_REGEX_BLOCKSIZE
# define BOOST_REGEX_BLOCKSIZE 4096
# endif
# if BOOST_REGEX_BLOCKSIZE < 512
# error "BOOST_REGEX_BLOCKSIZE must be at least 512"
# endif
# ifndef BOOST_REGEX_MAX_BLOCKS
# define BOOST_REGEX_MAX_BLOCKS 1024
# endif
# ifdef BOOST_REGEX_HAS_MS_STACK_GUARD
# undef BOOST_REGEX_HAS_MS_STACK_GUARD
# endif
# ifndef BOOST_REGEX_MAX_CACHE_BLOCKS
# define BOOST_REGEX_MAX_CACHE_BLOCKS 16
# endif
#endif
/*****************************************************************************
*
* Diagnostics:
*
****************************************************************************/
#ifdef BOOST_REGEX_CONFIG_INFO
BOOST_REGEX_DECL void BOOST_REGEX_CALL print_regex_library_info();
#endif
#if defined(BOOST_REGEX_DIAG)
# pragma message ("BOOST_REGEX_DECL" BOOST_STRINGIZE(=BOOST_REGEX_DECL))
# pragma message ("BOOST_REGEX_CALL" BOOST_STRINGIZE(=BOOST_REGEX_CALL))
# pragma message ("BOOST_REGEX_CCALL" BOOST_STRINGIZE(=BOOST_REGEX_CCALL))
#ifdef BOOST_REGEX_USE_C_LOCALE
# pragma message ("Using C locale in regex traits class")
#elif BOOST_REGEX_USE_CPP_LOCALE
# pragma message ("Using C++ locale in regex traits class")
#else
# pragma message ("Using Win32 locale in regex traits class")
#endif
#if defined(BOOST_REGEX_DYN_LINK) || defined(BOOST_ALL_DYN_LINK)
# pragma message ("Dynamic linking enabled")
#endif
#if defined(BOOST_REGEX_NO_LIB) || defined(BOOST_ALL_NO_LIB)
# pragma message ("Auto-linking disabled")
#endif
#ifdef BOOST_REGEX_NO_EXTERNAL_TEMPLATES
# pragma message ("Extern templates disabled")
#endif
#endif
#endif

View File

@@ -1,72 +0,0 @@
/*
*
* Copyright (c) 1998-2002
* John Maddock
*
* Use, modification and distribution are subject to 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)
*
*/
/*
* LOCATION: see http://www.boost.org for most recent version.
* FILE boost/regex/config/borland.hpp
* VERSION see <boost/version.hpp>
* DESCRIPTION: regex borland-specific config setup.
*/
#if defined(__BORLANDC__) && !defined(__clang__)
# if (__BORLANDC__ == 0x550) || (__BORLANDC__ == 0x551)
// problems with std::basic_string and dll RTL:
# if defined(_RTLDLL) && defined(_RWSTD_COMPILE_INSTANTIATE)
# ifdef BOOST_REGEX_BUILD_DLL
# error _RWSTD_COMPILE_INSTANTIATE must not be defined when building regex++ as a DLL
# else
# pragma message("Defining _RWSTD_COMPILE_INSTANTIATE when linking to the DLL version of the RTL may produce memory corruption problems in std::basic_string, as a result of separate versions of basic_string's static data in the RTL and you're exe/dll: be warned!!")
# endif
# endif
# ifndef _RTLDLL
// this is harmless for a staic link:
# define _RWSTD_COMPILE_INSTANTIATE
# endif
// external templates cause problems for some reason:
# define BOOST_REGEX_NO_EXTERNAL_TEMPLATES
# endif
# if (__BORLANDC__ <= 0x540) && !defined(BOOST_REGEX_NO_LIB) && !defined(_NO_VCL)
// C++ Builder 4 and earlier, we can't tell whether we should be using
// the VCL runtime or not, do a static link instead:
# define BOOST_REGEX_STATIC_LINK
# endif
//
// VCL support:
// if we're building a console app then there can't be any VCL (can there?)
# if !defined(__CONSOLE__) && !defined(_NO_VCL)
# define BOOST_REGEX_USE_VCL
# endif
//
// if this isn't Win32 then don't automatically select link
// libraries:
//
# ifndef _Windows
# ifndef BOOST_REGEX_NO_LIB
# define BOOST_REGEX_NO_LIB
# endif
# ifndef BOOST_REGEX_STATIC_LINK
# define BOOST_REGEX_STATIC_LINK
# endif
# endif
#if __BORLANDC__ < 0x600
//
// string workarounds:
//
#include <cstring>
#undef strcmp
#undef strcpy
#endif
#endif

View File

@@ -1,207 +0,0 @@
/*
*
* Copyright (c) 1998-2002
* John Maddock
*
* Use, modification and distribution are subject to 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)
*
*/
/*
* LOCATION: see http://www.boost.org for most recent version.
* FILE boost/regex/config/cwchar.hpp
* VERSION see <boost/version.hpp>
* DESCRIPTION: regex wide character string fixes.
*/
#ifndef BOOST_REGEX_CONFIG_CWCHAR_HPP
#define BOOST_REGEX_CONFIG_CWCHAR_HPP
#include <cwchar>
#include <cwctype>
#include <boost/config.hpp>
#if defined(__STD_RWCOMPILER_H__) || defined(_RWSTD_VER)
// apparently this is required for the RW STL on Linux:
#undef iswalnum
#undef iswalpha
#undef iswblank
#undef iswcntrl
#undef iswdigit
#undef iswgraph
#undef iswlower
#undef iswprint
#undef iswprint
#undef iswpunct
#undef iswspace
#undef iswupper
#undef iswxdigit
#undef iswctype
#undef towlower
#undef towupper
#undef towctrans
#undef wctrans
#undef wctype
#endif
namespace std{
#ifndef BOOST_NO_STDC_NAMESPACE
extern "C"{
#endif
#ifdef iswalnum
inline int (iswalnum)(wint_t i)
{ return iswalnum(i); }
#undef iswalnum
#elif defined(BOOST_NO_STDC_NAMESPACE)
using ::iswalnum;
#endif
#ifdef iswalpha
inline int (iswalpha)(wint_t i)
{ return iswalpha(i); }
#undef iswalpha
#elif defined(BOOST_NO_STDC_NAMESPACE)
using ::iswalpha;
#endif
#ifdef iswcntrl
inline int (iswcntrl)(wint_t i)
{ return iswcntrl(i); }
#undef iswcntrl
#elif defined(BOOST_NO_STDC_NAMESPACE)
using ::iswcntrl;
#endif
#ifdef iswdigit
inline int (iswdigit)(wint_t i)
{ return iswdigit(i); }
#undef iswdigit
#elif defined(BOOST_NO_STDC_NAMESPACE)
using ::iswdigit;
#endif
#ifdef iswgraph
inline int (iswgraph)(wint_t i)
{ return iswgraph(i); }
#undef iswgraph
#elif defined(BOOST_NO_STDC_NAMESPACE)
using ::iswgraph;
#endif
#ifdef iswlower
inline int (iswlower)(wint_t i)
{ return iswlower(i); }
#undef iswlower
#elif defined(BOOST_NO_STDC_NAMESPACE)
using ::iswlower;
#endif
#ifdef iswprint
inline int (iswprint)(wint_t i)
{ return iswprint(i); }
#undef iswprint
#elif defined(BOOST_NO_STDC_NAMESPACE)
using ::iswprint;
#endif
#ifdef iswpunct
inline int (iswpunct)(wint_t i)
{ return iswpunct(i); }
#undef iswpunct
#elif defined(BOOST_NO_STDC_NAMESPACE)
using ::iswpunct;
#endif
#ifdef iswspace
inline int (iswspace)(wint_t i)
{ return iswspace(i); }
#undef iswspace
#elif defined(BOOST_NO_STDC_NAMESPACE)
using ::iswspace;
#endif
#ifdef iswupper
inline int (iswupper)(wint_t i)
{ return iswupper(i); }
#undef iswupper
#elif defined(BOOST_NO_STDC_NAMESPACE)
using ::iswupper;
#endif
#ifdef iswxdigit
inline int (iswxdigit)(wint_t i)
{ return iswxdigit(i); }
#undef iswxdigit
#elif defined(BOOST_NO_STDC_NAMESPACE)
using ::iswxdigit;
#endif
#ifdef towlower
inline wint_t (towlower)(wint_t i)
{ return towlower(i); }
#undef towlower
#elif defined(BOOST_NO_STDC_NAMESPACE)
using ::towlower;
#endif
#ifdef towupper
inline wint_t (towupper)(wint_t i)
{ return towupper(i); }
#undef towupper
#elif defined(BOOST_NO_STDC_NAMESPACE)
using :: towupper;
#endif
#ifdef wcscmp
inline int (wcscmp)(const wchar_t *p1, const wchar_t *p2)
{ return wcscmp(p1,p2); }
#undef wcscmp
#elif defined(BOOST_NO_STDC_NAMESPACE)
using ::wcscmp;
#endif
#ifdef wcscoll
inline int (wcscoll)(const wchar_t *p1, const wchar_t *p2)
{ return wcscoll(p1,p2); }
#undef wcscoll
#elif defined(BOOST_NO_STDC_NAMESPACE) && !defined(UNDER_CE)
using ::wcscoll;
#endif
#ifdef wcscpy
inline wchar_t *(wcscpy)(wchar_t *p1, const wchar_t *p2)
{ return wcscpy(p1,p2); }
#undef wcscpy
#elif defined(BOOST_NO_STDC_NAMESPACE)
using ::wcscpy;
#endif
#ifdef wcslen
inline size_t (wcslen)(const wchar_t *p)
{ return wcslen(p); }
#undef wcslen
#elif defined(BOOST_NO_STDC_NAMESPACE)
using ::wcslen;
#endif
#ifdef wcsxfrm
size_t wcsxfrm(wchar_t *p1, const wchar_t *p2, size_t s)
{ return wcsxfrm(p1,p2,s); }
#undef wcsxfrm
#elif defined(BOOST_NO_STDC_NAMESPACE)
using ::wcsxfrm;
#endif
#ifndef BOOST_NO_STDC_NAMESPACE
} // extern "C"
#endif
} // namespace std
#endif

View File

@@ -1,30 +0,0 @@
/*
*
* Copyright (c) 2020
* John Maddock
*
* Use, modification and distribution are subject to 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)
*
*/
/*
* LOCATION: see http://www.boost.org for most recent version.
* FILE icu.hpp
* VERSION see <boost/version.hpp>
* DESCRIPTION: Unicode regular expressions on top of the ICU Library.
*/
#ifndef BOOST_REGEX_ICU_HPP
#define BOOST_REGEX_ICU_HPP
#include <boost/regex/config.hpp>
#ifdef BOOST_REGEX_CXX03
#include <boost/regex/v4/icu.hpp>
#else
#include <boost/regex/v5/icu.hpp>
#endif
#endif

View File

@@ -1,186 +0,0 @@
/*
*
* Copyright (c) 2004
* John Maddock
*
* Use, modification and distribution are subject to 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)
*
*/
/*
* LOCATION: see http://www.boost.org for most recent version.
* FILE mfc.hpp
* VERSION see <boost/version.hpp>
* DESCRIPTION: Overloads and helpers for using MFC/ATL string types with Boost.Regex.
*/
#ifndef BOOST_REGEX_MFC_HPP
#define BOOST_REGEX_MFC_HPP
#include <atlsimpstr.h>
#include <boost/regex.hpp>
namespace boost{
//
// define the types used for TCHAR's:
typedef basic_regex<TCHAR> tregex;
typedef match_results<TCHAR const*> tmatch;
typedef regex_iterator<TCHAR const*> tregex_iterator;
typedef regex_token_iterator<TCHAR const*> tregex_token_iterator;
// Obsolete. Remove
#define SIMPLE_STRING_PARAM class B, bool b
#define SIMPLE_STRING_ARG_LIST B, b
//
// define regex creation functions:
//
template <class B, bool b>
inline basic_regex<B>
make_regex(const ATL::CSimpleStringT<B, b>& s, ::boost::regex_constants::syntax_option_type f = boost::regex_constants::normal)
{
basic_regex<B> result(s.GetString(), s.GetString() + s.GetLength(), f);
return result;
}
//
// regex_match overloads:
//
template <class B, bool b, class A, class T>
inline bool regex_match(const ATL::CSimpleStringT<B, b>& s,
match_results<const B*, A>& what,
const basic_regex<B, T>& e,
boost::regex_constants::match_flag_type f = boost::regex_constants::match_default)
{
return ::boost::regex_match(s.GetString(),
s.GetString() + s.GetLength(),
what,
e,
f);
}
template <class B, bool b, class T>
inline bool regex_match(const ATL::CSimpleStringT<B, b>& s,
const basic_regex<B, T>& e,
boost::regex_constants::match_flag_type f = boost::regex_constants::match_default)
{
return ::boost::regex_match(s.GetString(),
s.GetString() + s.GetLength(),
e,
f);
}
//
// regex_search overloads:
//
template <class B, bool b, class A, class T>
inline bool regex_search(const ATL::CSimpleStringT<B, b>& s,
match_results<const B*, A>& what,
const basic_regex<B, T>& e,
boost::regex_constants::match_flag_type f = boost::regex_constants::match_default)
{
return ::boost::regex_search(s.GetString(),
s.GetString() + s.GetLength(),
what,
e,
f);
}
template <class B, bool b, class T>
inline bool regex_search(const ATL::CSimpleStringT<B, b>& s,
const basic_regex<B, T>& e,
boost::regex_constants::match_flag_type f = boost::regex_constants::match_default)
{
return ::boost::regex_search(s.GetString(),
s.GetString() + s.GetLength(),
e,
f);
}
//
// regex_iterator creation:
//
template <class B, bool b>
inline regex_iterator<B const*>
make_regex_iterator(const ATL::CSimpleStringT<B, b>& s, const basic_regex<B>& e, ::boost::regex_constants::match_flag_type f = boost::regex_constants::match_default)
{
regex_iterator<B const*> result(s.GetString(), s.GetString() + s.GetLength(), e, f);
return result;
}
template <class B, bool b>
inline regex_token_iterator<B const*>
make_regex_token_iterator(const ATL::CSimpleStringT<B, b>& s, const basic_regex<B>& e, int sub = 0, ::boost::regex_constants::match_flag_type f = boost::regex_constants::match_default)
{
regex_token_iterator<B const*> result(s.GetString(), s.GetString() + s.GetLength(), e, sub, f);
return result;
}
template <class B, bool b>
inline regex_token_iterator<B const*>
make_regex_token_iterator(const ATL::CSimpleStringT<B, b>& s, const basic_regex<B>& e, const std::vector<int>& subs, ::boost::regex_constants::match_flag_type f = boost::regex_constants::match_default)
{
regex_token_iterator<B const*> result(s.GetString(), s.GetString() + s.GetLength(), e, subs, f);
return result;
}
template <class B, bool b, std::size_t N>
inline regex_token_iterator<B const*>
make_regex_token_iterator(const ATL::CSimpleStringT<B, b>& s, const basic_regex<B>& e, const int (& subs)[N], ::boost::regex_constants::match_flag_type f = boost::regex_constants::match_default)
{
regex_token_iterator<B const*> result(s.GetString(), s.GetString() + s.GetLength(), e, subs, f);
return result;
}
template <class OutputIterator, class BidirectionalIterator, class traits,
class B, bool b>
OutputIterator regex_replace(OutputIterator out,
BidirectionalIterator first,
BidirectionalIterator last,
const basic_regex<B, traits>& e,
const ATL::CSimpleStringT<B, b>& fmt,
match_flag_type flags = match_default)
{
return ::boost::regex_replace(out, first, last, e, fmt.GetString(), flags);
}
namespace BOOST_REGEX_DETAIL_NS{
template <class B, bool b>
class mfc_string_out_iterator
{
ATL::CSimpleStringT<B, b>* out;
public:
mfc_string_out_iterator(ATL::CSimpleStringT<B, b>& s) : out(&s) {}
mfc_string_out_iterator& operator++() { return *this; }
mfc_string_out_iterator& operator++(int) { return *this; }
mfc_string_out_iterator& operator*() { return *this; }
mfc_string_out_iterator& operator=(B v)
{
out->AppendChar(v);
return *this;
}
typedef std::ptrdiff_t difference_type;
typedef B value_type;
typedef value_type* pointer;
typedef value_type& reference;
typedef std::output_iterator_tag iterator_category;
};
}
template <class traits, class B, bool b>
ATL::CSimpleStringT<B, b> regex_replace(const ATL::CSimpleStringT<B, b>& s,
const basic_regex<B, traits>& e,
const ATL::CSimpleStringT<B, b>& fmt,
match_flag_type flags = match_default)
{
ATL::CSimpleStringT<B, b> result(s.GetManager());
BOOST_REGEX_DETAIL_NS::mfc_string_out_iterator<B, b> i(result);
regex_replace(i, s.GetString(), s.GetString() + s.GetLength(), e, fmt.GetString(), flags);
return result;
}
} // namespace boost.
#endif

View File

@@ -1,32 +0,0 @@
/*
*
* Copyright (c) 1998-2002
* John Maddock
*
* Use, modification and distribution are subject to 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)
*
*/
/*
* LOCATION: see http://www.boost.org for most recent version.
* FILE pattern_except.hpp
* VERSION see <boost/version.hpp>
* DESCRIPTION: Declares pattern-matching exception classes.
*/
#ifndef BOOST_RE_PAT_EXCEPT_HPP
#define BOOST_RE_PAT_EXCEPT_HPP
#ifndef BOOST_REGEX_CONFIG_HPP
#include <boost/regex/config.hpp>
#endif
#ifdef BOOST_REGEX_CXX03
#include <boost/regex/v4/pattern_except.hpp>
#else
#include <boost/regex/v5/pattern_except.hpp>
#endif
#endif

View File

@@ -1,29 +0,0 @@
/*
*
* Copyright (c) 2004
* John Maddock
*
* Use, modification and distribution are subject to 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)
*
*/
/*
* LOCATION: see http://www.boost.org for most recent version.
* FILE object_cache.hpp
* VERSION see <boost/version.hpp>
* DESCRIPTION: Implements a generic object cache.
*/
#ifndef BOOST_REGEX_OBJECT_CACHE_HPP
#define BOOST_REGEX_OBJECT_CACHE_HPP
#include <boost/regex/config.hpp>
#ifdef BOOST_REGEX_CXX03
#include <boost/regex/v4/object_cache.hpp>
#else
#include <boost/regex/v5/object_cache.hpp>
#endif
#endif

View File

@@ -1,182 +0,0 @@
/*
*
* Copyright (c) 2004
* John Maddock
*
* Use, modification and distribution are subject to 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)
*
*/
/*
* LOCATION: see http://www.boost.org for most recent version.
* FILE static_mutex.hpp
* VERSION see <boost/version.hpp>
* DESCRIPTION: Declares static_mutex lock type, there are three different
* implementations: POSIX pthreads, WIN32 threads, and portable,
* these are described in more detail below.
*/
#ifndef BOOST_REGEX_STATIC_MUTEX_HPP
#define BOOST_REGEX_STATIC_MUTEX_HPP
#include <boost/config.hpp>
#include <boost/regex/config.hpp> // dll import/export options.
#ifdef BOOST_HAS_PTHREADS
#include <pthread.h>
#endif
#if defined(BOOST_HAS_PTHREADS) && defined(PTHREAD_MUTEX_INITIALIZER)
//
// pthreads version:
// simple wrap around a pthread_mutex_t initialized with
// PTHREAD_MUTEX_INITIALIZER.
//
namespace boost{
class static_mutex;
#define BOOST_STATIC_MUTEX_INIT { PTHREAD_MUTEX_INITIALIZER, }
class BOOST_REGEX_DECL scoped_static_mutex_lock
{
public:
scoped_static_mutex_lock(static_mutex& mut, bool lk = true);
~scoped_static_mutex_lock();
inline bool locked()const
{
return m_have_lock;
}
inline operator void const*()const
{
return locked() ? this : 0;
}
void lock();
void unlock();
private:
static_mutex& m_mutex;
bool m_have_lock;
};
class static_mutex
{
public:
typedef scoped_static_mutex_lock scoped_lock;
pthread_mutex_t m_mutex;
};
} // namespace boost
#elif defined(BOOST_HAS_WINTHREADS)
//
// Win32 version:
// Use a 32-bit int as a lock, along with a test-and-set
// implementation using InterlockedCompareExchange.
//
#include <boost/cstdint.hpp>
namespace boost{
class BOOST_REGEX_DECL scoped_static_mutex_lock;
class static_mutex
{
public:
typedef scoped_static_mutex_lock scoped_lock;
boost::int32_t m_mutex;
};
#define BOOST_STATIC_MUTEX_INIT { 0, }
class BOOST_REGEX_DECL scoped_static_mutex_lock
{
public:
scoped_static_mutex_lock(static_mutex& mut, bool lk = true);
~scoped_static_mutex_lock();
operator void const*()const
{
return locked() ? this : 0;
}
bool locked()const
{
return m_have_lock;
}
void lock();
void unlock();
private:
static_mutex& m_mutex;
bool m_have_lock;
scoped_static_mutex_lock(const scoped_static_mutex_lock&);
scoped_static_mutex_lock& operator=(const scoped_static_mutex_lock&);
};
} // namespace
#else
//
// Portable version of a static mutex based on Boost.Thread library:
// This has to use a single mutex shared by all instances of static_mutex
// because boost::call_once doesn't alow us to pass instance information
// down to the initialisation proceedure. In fact the initialisation routine
// may need to be called more than once - but only once per instance.
//
// Since this preprocessor path is almost never taken, we hide these header
// dependencies so that build tools don't find them.
//
#define BOOST_REGEX_H1 <boost/thread/once.hpp>
#define BOOST_REGEX_H2 <boost/thread/recursive_mutex.hpp>
#define BOOST_REGEX_H3 <boost/thread/lock_types.hpp>
#include BOOST_REGEX_H1
#include BOOST_REGEX_H2
#include BOOST_REGEX_H3
#undef BOOST_REGEX_H1
#undef BOOST_REGEX_H2
#undef BOOST_REGEX_H3
namespace boost{
class BOOST_REGEX_DECL scoped_static_mutex_lock;
extern "C" BOOST_REGEX_DECL void boost_regex_free_static_mutex();
class BOOST_REGEX_DECL static_mutex
{
public:
typedef scoped_static_mutex_lock scoped_lock;
static void init();
static boost::recursive_mutex* m_pmutex;
static boost::once_flag m_once;
};
#define BOOST_STATIC_MUTEX_INIT { }
class BOOST_REGEX_DECL scoped_static_mutex_lock
{
public:
scoped_static_mutex_lock(static_mutex& mut, bool lk = true);
~scoped_static_mutex_lock();
operator void const*()const;
bool locked()const;
void lock();
void unlock();
private:
boost::unique_lock<boost::recursive_mutex>* m_plock;
bool m_have_lock;
};
inline scoped_static_mutex_lock::operator void const*()const
{
return locked() ? this : 0;
}
inline bool scoped_static_mutex_lock::locked()const
{
return m_have_lock;
}
} // namespace
#endif
#endif

View File

@@ -1,32 +0,0 @@
/*
*
* Copyright (c) 2020
* John Maddock
*
* Use, modification and distribution are subject to 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)
*
*/
/*
* LOCATION: see http://www.boost.org for most recent version.
* FILE unicode_iterator.hpp
* VERSION see <boost/version.hpp>
* DESCRIPTION: Iterator adapters for converting between different Unicode encodings.
*/
#ifndef BOOST_REGEX_PENDING_UNICODE_ITERATOR_HPP
#define BOOST_REGEX_PENDING_UNICODE_ITERATOR_HPP
#include <boost/regex/config.hpp>
#if defined(BOOST_REGEX_CXX03)
#include <boost/regex/v4/unicode_iterator.hpp>
#else
#include <boost/regex/v5/unicode_iterator.hpp>
#endif
#endif // BOOST_REGEX_PENDING_UNICODE_ITERATOR_HPP

View File

@@ -1,39 +0,0 @@
/*
*
* Copyright (c) 1998-2002
* John Maddock
*
* Use, modification and distribution are subject to 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)
*
*/
/*
* LOCATION: see http://www.boost.org for most recent version.
* FILE regex_traits.hpp
* VERSION see <boost/version.hpp>
* DESCRIPTION: Declares regular expression traits classes.
*/
#ifndef BOOST_REGEX_TRAITS_HPP
#define BOOST_REGEX_TRAITS_HPP
#ifndef BOOST_REGEX_CONFIG_HPP
# include <boost/regex/config.hpp>
#endif
# ifndef BOOST_REGEX_TRAITS_HPP_INCLUDED
#ifdef BOOST_REGEX_CXX03
# include <boost/regex/v4/regex_traits.hpp>
#else
# include <boost/regex/v5/regex_traits.hpp>
#endif
# endif
#endif // include

View File

@@ -1,95 +0,0 @@
/*
*
* Copyright (c) 1998-2002
* John Maddock
*
* Use, modification and distribution are subject to 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)
*
*/
/*
* LOCATION: see http://www.boost.org for most recent version.
* FILE user.hpp
* VERSION see <boost/version.hpp>
* DESCRIPTION: User settable options.
*/
// define if you want the regex library to use the C locale
// even on Win32:
// #define BOOST_REGEX_USE_C_LOCALE
// define this is you want the regex library to use the C++
// locale:
// #define BOOST_REGEX_USE_CPP_LOCALE
// define this if the runtime library is a dll, and you
// want BOOST_REGEX_DYN_LINK to set up dll exports/imports
// with __declspec(dllexport)/__declspec(dllimport.)
// #define BOOST_REGEX_HAS_DLL_RUNTIME
// define this if you want to dynamically link to regex,
// if the runtime library is also a dll (Probably Win32 specific,
// and has no effect unless BOOST_REGEX_HAS_DLL_RUNTIME is set):
// #define BOOST_REGEX_DYN_LINK
// define this if you don't want the lib to automatically
// select its link libraries:
// #define BOOST_REGEX_NO_LIB
// define this if templates with switch statements cause problems:
// #define BOOST_REGEX_NO_TEMPLATE_SWITCH_MERGE
// define this to disable Win32 support when available:
// #define BOOST_REGEX_NO_W32
// define this if bool is not a real type:
// #define BOOST_REGEX_NO_BOOL
// define this if no template instances are to be placed in
// the library rather than users object files:
// #define BOOST_REGEX_NO_EXTERNAL_TEMPLATES
// define this if the forward declarations in regex_fwd.hpp
// cause more problems than they are worth:
// #define BOOST_REGEX_NO_FWD
// define this if your compiler supports MS Windows structured
// exception handling.
// #define BOOST_REGEX_HAS_MS_STACK_GUARD
// define this if you want to use the recursive algorithm
// even if BOOST_REGEX_HAS_MS_STACK_GUARD is not defined.
// NOTE: OBSOLETE!!
// #define BOOST_REGEX_RECURSIVE
// define this if you want to use the non-recursive
// algorithm, even if the recursive version would be the default.
// NOTE: OBSOLETE!!
// #define BOOST_REGEX_NON_RECURSIVE
// define this if you want to set the size of the memory blocks
// used by the non-recursive algorithm.
// #define BOOST_REGEX_BLOCKSIZE 4096
// define this if you want to set the maximum number of memory blocks
// used by the non-recursive algorithm.
// #define BOOST_REGEX_MAX_BLOCKS 1024
// define this if you want to set the maximum number of memory blocks
// cached by the non-recursive algorithm: Normally this is 16, but can be
// higher if you have multiple threads all using boost.regex, or lower
// if you don't want boost.regex to cache memory.
// #define BOOST_REGEX_MAX_CACHE_BLOCKS 16
// define this if you want to be able to access extended capture
// information in your sub_match's (caution this will slow things
// down quite a bit).
// #define BOOST_REGEX_MATCH_EXTRA
// define this if you want to enable support for Unicode via ICU.
// #define BOOST_HAS_ICU
// define this if you want regex to use __cdecl calling convensions, even when __fastcall is available:
// #define BOOST_REGEX_NO_FASTCALL

View File

@@ -1,734 +0,0 @@
/*
*
* Copyright (c) 1998-2004 John Maddock
* Copyright 2011 Garmin Ltd. or its subsidiaries
*
* 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)
*
*/
/*
* LOCATION: see http://www.boost.org/ for most recent version.
* FILE basic_regex.cpp
* VERSION see <boost/version.hpp>
* DESCRIPTION: Declares template class basic_regex.
*/
#ifndef BOOST_REGEX_V5_BASIC_REGEX_HPP
#define BOOST_REGEX_V5_BASIC_REGEX_HPP
#include <vector>
namespace boost{
#ifdef BOOST_REGEX_MSVC
#pragma warning(push)
#pragma warning(disable : 4251)
#if BOOST_REGEX_MSVC < 1700
# pragma warning(disable : 4231)
#endif
#if BOOST_REGEX_MSVC < 1600
#pragma warning(disable : 4660)
#endif
#if BOOST_REGEX_MSVC < 1910
#pragma warning(disable:4800)
#endif
#endif
namespace BOOST_REGEX_DETAIL_NS{
//
// forward declaration, we will need this one later:
//
template <class charT, class traits>
class basic_regex_parser;
template <class I>
void bubble_down_one(I first, I last)
{
if(first != last)
{
I next = last - 1;
while((next != first) && (*next < *(next-1)))
{
(next-1)->swap(*next);
--next;
}
}
}
static const int hash_value_mask = 1 << (std::numeric_limits<int>::digits - 1);
template <class Iterator>
inline int hash_value_from_capture_name(Iterator i, Iterator j)
{
std::size_t r = 0;
while (i != j)
{
r ^= *i + 0x9e3779b9 + (r << 6) + (r >> 2);
++i;
}
r %= ((std::numeric_limits<int>::max)());
return static_cast<int>(r) | hash_value_mask;
}
class named_subexpressions
{
public:
struct name
{
template <class charT>
name(const charT* i, const charT* j, int idx)
: index(idx)
{
hash = hash_value_from_capture_name(i, j);
}
name(int h, int idx)
: index(idx), hash(h)
{
}
int index;
int hash;
bool operator < (const name& other)const
{
return hash < other.hash;
}
bool operator == (const name& other)const
{
return hash == other.hash;
}
void swap(name& other)
{
std::swap(index, other.index);
std::swap(hash, other.hash);
}
};
typedef std::vector<name>::const_iterator const_iterator;
typedef std::pair<const_iterator, const_iterator> range_type;
named_subexpressions(){}
template <class charT>
void set_name(const charT* i, const charT* j, int index)
{
m_sub_names.push_back(name(i, j, index));
bubble_down_one(m_sub_names.begin(), m_sub_names.end());
}
template <class charT>
int get_id(const charT* i, const charT* j)const
{
name t(i, j, 0);
typename std::vector<name>::const_iterator pos = std::lower_bound(m_sub_names.begin(), m_sub_names.end(), t);
if((pos != m_sub_names.end()) && (*pos == t))
{
return pos->index;
}
return -1;
}
template <class charT>
range_type equal_range(const charT* i, const charT* j)const
{
name t(i, j, 0);
return std::equal_range(m_sub_names.begin(), m_sub_names.end(), t);
}
int get_id(int h)const
{
name t(h, 0);
std::vector<name>::const_iterator pos = std::lower_bound(m_sub_names.begin(), m_sub_names.end(), t);
if((pos != m_sub_names.end()) && (*pos == t))
{
return pos->index;
}
return -1;
}
range_type equal_range(int h)const
{
name t(h, 0);
return std::equal_range(m_sub_names.begin(), m_sub_names.end(), t);
}
private:
std::vector<name> m_sub_names;
};
//
// class regex_data:
// represents the data we wish to expose to the matching algorithms.
//
template <class charT, class traits>
struct regex_data : public named_subexpressions
{
typedef regex_constants::syntax_option_type flag_type;
typedef std::size_t size_type;
regex_data(const ::std::shared_ptr<
::boost::regex_traits_wrapper<traits> >& t)
: m_ptraits(t), m_flags(0), m_status(0), m_expression(0), m_expression_len(0),
m_mark_count(0), m_first_state(0), m_restart_type(0),
m_startmap{ 0 },
m_can_be_null(0), m_word_mask(0), m_has_recursions(false), m_disable_match_any(false) {}
regex_data()
: m_ptraits(new ::boost::regex_traits_wrapper<traits>()), m_flags(0), m_status(0), m_expression(0), m_expression_len(0),
m_mark_count(0), m_first_state(0), m_restart_type(0),
m_startmap{ 0 },
m_can_be_null(0), m_word_mask(0), m_has_recursions(false), m_disable_match_any(false) {}
::std::shared_ptr<
::boost::regex_traits_wrapper<traits>
> m_ptraits; // traits class instance
flag_type m_flags; // flags with which we were compiled
int m_status; // error code (0 implies OK).
const charT* m_expression; // the original expression
std::ptrdiff_t m_expression_len; // the length of the original expression
size_type m_mark_count; // the number of marked sub-expressions
BOOST_REGEX_DETAIL_NS::re_syntax_base* m_first_state; // the first state of the machine
unsigned m_restart_type; // search optimisation type
unsigned char m_startmap[1 << CHAR_BIT]; // which characters can start a match
unsigned int m_can_be_null; // whether we can match a null string
BOOST_REGEX_DETAIL_NS::raw_storage m_data; // the buffer in which our states are constructed
typename traits::char_class_type m_word_mask; // mask used to determine if a character is a word character
std::vector<
std::pair<
std::size_t, std::size_t> > m_subs; // Position of sub-expressions within the *string*.
bool m_has_recursions; // whether we have recursive expressions;
bool m_disable_match_any; // when set we need to disable the match_any flag as it causes different/buggy behaviour.
};
//
// class basic_regex_implementation
// pimpl implementation class for basic_regex.
//
template <class charT, class traits>
class basic_regex_implementation
: public regex_data<charT, traits>
{
public:
typedef regex_constants::syntax_option_type flag_type;
typedef std::ptrdiff_t difference_type;
typedef std::size_t size_type;
typedef typename traits::locale_type locale_type;
typedef const charT* const_iterator;
basic_regex_implementation(){}
basic_regex_implementation(const ::std::shared_ptr<
::boost::regex_traits_wrapper<traits> >& t)
: regex_data<charT, traits>(t) {}
void assign(const charT* arg_first,
const charT* arg_last,
flag_type f)
{
regex_data<charT, traits>* pdat = this;
basic_regex_parser<charT, traits> parser(pdat);
parser.parse(arg_first, arg_last, f);
}
locale_type imbue(locale_type l)
{
return this->m_ptraits->imbue(l);
}
locale_type getloc()const
{
return this->m_ptraits->getloc();
}
std::basic_string<charT> str()const
{
std::basic_string<charT> result;
if(this->m_status == 0)
result = std::basic_string<charT>(this->m_expression, this->m_expression_len);
return result;
}
const_iterator expression()const
{
return this->m_expression;
}
std::pair<const_iterator, const_iterator> subexpression(std::size_t n)const
{
const std::pair<std::size_t, std::size_t>& pi = this->m_subs.at(n);
std::pair<const_iterator, const_iterator> p(expression() + pi.first, expression() + pi.second);
return p;
}
//
// begin, end:
const_iterator begin()const
{
return (this->m_status ? 0 : this->m_expression);
}
const_iterator end()const
{
return (this->m_status ? 0 : this->m_expression + this->m_expression_len);
}
flag_type flags()const
{
return this->m_flags;
}
size_type size()const
{
return this->m_expression_len;
}
int status()const
{
return this->m_status;
}
size_type mark_count()const
{
return this->m_mark_count - 1;
}
const BOOST_REGEX_DETAIL_NS::re_syntax_base* get_first_state()const
{
return this->m_first_state;
}
unsigned get_restart_type()const
{
return this->m_restart_type;
}
const unsigned char* get_map()const
{
return this->m_startmap;
}
const ::boost::regex_traits_wrapper<traits>& get_traits()const
{
return *(this->m_ptraits);
}
bool can_be_null()const
{
return this->m_can_be_null;
}
const regex_data<charT, traits>& get_data()const
{
basic_regex_implementation<charT, traits> const* p = this;
return *static_cast<const regex_data<charT, traits>*>(p);
}
};
} // namespace BOOST_REGEX_DETAIL_NS
//
// class basic_regex:
// represents the compiled
// regular expression:
//
#ifdef BOOST_REGEX_NO_FWD
template <class charT, class traits = regex_traits<charT> >
#else
template <class charT, class traits >
#endif
class basic_regex : public regbase
{
public:
// typedefs:
typedef std::size_t traits_size_type;
typedef typename traits::string_type traits_string_type;
typedef charT char_type;
typedef traits traits_type;
typedef charT value_type;
typedef charT& reference;
typedef const charT& const_reference;
typedef const charT* const_iterator;
typedef const_iterator iterator;
typedef std::ptrdiff_t difference_type;
typedef std::size_t size_type;
typedef regex_constants::syntax_option_type flag_type;
// locale_type
// placeholder for actual locale type used by the
// traits class to localise *this.
typedef typename traits::locale_type locale_type;
public:
explicit basic_regex(){}
explicit basic_regex(const charT* p, flag_type f = regex_constants::normal)
{
assign(p, f);
}
basic_regex(const charT* p1, const charT* p2, flag_type f = regex_constants::normal)
{
assign(p1, p2, f);
}
basic_regex(const charT* p, size_type len, flag_type f)
{
assign(p, len, f);
}
basic_regex(const basic_regex& that)
: m_pimpl(that.m_pimpl) {}
~basic_regex(){}
basic_regex& operator=(const basic_regex& that)
{
return assign(that);
}
basic_regex& operator=(const charT* ptr)
{
return assign(ptr);
}
//
// assign:
basic_regex& assign(const basic_regex& that)
{
m_pimpl = that.m_pimpl;
return *this;
}
basic_regex& assign(const charT* p, flag_type f = regex_constants::normal)
{
return assign(p, p + traits::length(p), f);
}
basic_regex& assign(const charT* p, size_type len, flag_type f)
{
return assign(p, p + len, f);
}
private:
basic_regex& do_assign(const charT* p1,
const charT* p2,
flag_type f);
public:
basic_regex& assign(const charT* p1,
const charT* p2,
flag_type f = regex_constants::normal)
{
return do_assign(p1, p2, f);
}
template <class ST, class SA>
unsigned int set_expression(const std::basic_string<charT, ST, SA>& p, flag_type f = regex_constants::normal)
{
return set_expression(p.data(), p.data() + p.size(), f);
}
template <class ST, class SA>
explicit basic_regex(const std::basic_string<charT, ST, SA>& p, flag_type f = regex_constants::normal)
{
assign(p, f);
}
template <class InputIterator>
basic_regex(InputIterator arg_first, InputIterator arg_last, flag_type f = regex_constants::normal)
{
typedef typename traits::string_type seq_type;
seq_type a(arg_first, arg_last);
if(!a.empty())
assign(static_cast<const charT*>(&*a.begin()), static_cast<const charT*>(&*a.begin() + a.size()), f);
else
assign(static_cast<const charT*>(0), static_cast<const charT*>(0), f);
}
template <class ST, class SA>
basic_regex& operator=(const std::basic_string<charT, ST, SA>& p)
{
return assign(p.data(), p.data() + p.size(), regex_constants::normal);
}
template <class string_traits, class A>
basic_regex& assign(
const std::basic_string<charT, string_traits, A>& s,
flag_type f = regex_constants::normal)
{
return assign(s.data(), s.data() + s.size(), f);
}
template <class InputIterator>
basic_regex& assign(InputIterator arg_first,
InputIterator arg_last,
flag_type f = regex_constants::normal)
{
typedef typename traits::string_type seq_type;
seq_type a(arg_first, arg_last);
if(a.size())
{
const charT* p1 = &*a.begin();
const charT* p2 = &*a.begin() + a.size();
return assign(p1, p2, f);
}
return assign(static_cast<const charT*>(0), static_cast<const charT*>(0), f);
}
//
// locale:
locale_type imbue(locale_type l);
locale_type getloc()const
{
return m_pimpl.get() ? m_pimpl->getloc() : locale_type();
}
//
// getflags:
// retained for backwards compatibility only, "flags"
// is now the preferred name:
flag_type getflags()const
{
return flags();
}
flag_type flags()const
{
return m_pimpl.get() ? m_pimpl->flags() : 0;
}
//
// str:
std::basic_string<charT> str()const
{
return m_pimpl.get() ? m_pimpl->str() : std::basic_string<charT>();
}
//
// begin, end, subexpression:
std::pair<const_iterator, const_iterator> subexpression(std::size_t n)const
{
#ifdef BOOST_REGEX_STANDALONE
if (!m_pimpl.get())
throw std::logic_error("Can't access subexpressions in an invalid regex.");
#else
if(!m_pimpl.get())
boost::throw_exception(std::logic_error("Can't access subexpressions in an invalid regex."));
#endif
return m_pimpl->subexpression(n);
}
const_iterator begin()const
{
return (m_pimpl.get() ? m_pimpl->begin() : 0);
}
const_iterator end()const
{
return (m_pimpl.get() ? m_pimpl->end() : 0);
}
//
// swap:
void swap(basic_regex& that)throw()
{
m_pimpl.swap(that.m_pimpl);
}
//
// size:
size_type size()const
{
return (m_pimpl.get() ? m_pimpl->size() : 0);
}
//
// max_size:
size_type max_size()const
{
return UINT_MAX;
}
//
// empty:
bool empty()const
{
return (m_pimpl.get() ? 0 != m_pimpl->status() : true);
}
size_type mark_count()const
{
return (m_pimpl.get() ? m_pimpl->mark_count() : 0);
}
int status()const
{
return (m_pimpl.get() ? m_pimpl->status() : regex_constants::error_empty);
}
int compare(const basic_regex& that) const
{
if(m_pimpl.get() == that.m_pimpl.get())
return 0;
if(!m_pimpl.get())
return -1;
if(!that.m_pimpl.get())
return 1;
if(status() != that.status())
return status() - that.status();
if(flags() != that.flags())
return flags() - that.flags();
return str().compare(that.str());
}
bool operator==(const basic_regex& e)const
{
return compare(e) == 0;
}
bool operator != (const basic_regex& e)const
{
return compare(e) != 0;
}
bool operator<(const basic_regex& e)const
{
return compare(e) < 0;
}
bool operator>(const basic_regex& e)const
{
return compare(e) > 0;
}
bool operator<=(const basic_regex& e)const
{
return compare(e) <= 0;
}
bool operator>=(const basic_regex& e)const
{
return compare(e) >= 0;
}
//
// The following are deprecated as public interfaces
// but are available for compatibility with earlier versions.
const charT* expression()const
{
return (m_pimpl.get() && !m_pimpl->status() ? m_pimpl->expression() : 0);
}
unsigned int set_expression(const charT* p1, const charT* p2, flag_type f = regex_constants::normal)
{
assign(p1, p2, f | regex_constants::no_except);
return status();
}
unsigned int set_expression(const charT* p, flag_type f = regex_constants::normal)
{
assign(p, f | regex_constants::no_except);
return status();
}
unsigned int error_code()const
{
return status();
}
//
// private access methods:
//
const BOOST_REGEX_DETAIL_NS::re_syntax_base* get_first_state()const
{
BOOST_REGEX_ASSERT(0 != m_pimpl.get());
return m_pimpl->get_first_state();
}
unsigned get_restart_type()const
{
BOOST_REGEX_ASSERT(0 != m_pimpl.get());
return m_pimpl->get_restart_type();
}
const unsigned char* get_map()const
{
BOOST_REGEX_ASSERT(0 != m_pimpl.get());
return m_pimpl->get_map();
}
const ::boost::regex_traits_wrapper<traits>& get_traits()const
{
BOOST_REGEX_ASSERT(0 != m_pimpl.get());
return m_pimpl->get_traits();
}
bool can_be_null()const
{
BOOST_REGEX_ASSERT(0 != m_pimpl.get());
return m_pimpl->can_be_null();
}
const BOOST_REGEX_DETAIL_NS::regex_data<charT, traits>& get_data()const
{
BOOST_REGEX_ASSERT(0 != m_pimpl.get());
return m_pimpl->get_data();
}
std::shared_ptr<BOOST_REGEX_DETAIL_NS::named_subexpressions > get_named_subs()const
{
return m_pimpl;
}
private:
std::shared_ptr<BOOST_REGEX_DETAIL_NS::basic_regex_implementation<charT, traits> > m_pimpl;
};
//
// out of line members;
// these are the only members that mutate the basic_regex object,
// and are designed to provide the strong exception guarantee
// (in the event of a throw, the state of the object remains unchanged).
//
template <class charT, class traits>
basic_regex<charT, traits>& basic_regex<charT, traits>::do_assign(const charT* p1,
const charT* p2,
flag_type f)
{
std::shared_ptr<BOOST_REGEX_DETAIL_NS::basic_regex_implementation<charT, traits> > temp;
if(!m_pimpl.get())
{
temp = std::shared_ptr<BOOST_REGEX_DETAIL_NS::basic_regex_implementation<charT, traits> >(new BOOST_REGEX_DETAIL_NS::basic_regex_implementation<charT, traits>());
}
else
{
temp = std::shared_ptr<BOOST_REGEX_DETAIL_NS::basic_regex_implementation<charT, traits> >(new BOOST_REGEX_DETAIL_NS::basic_regex_implementation<charT, traits>(m_pimpl->m_ptraits));
}
temp->assign(p1, p2, f);
temp.swap(m_pimpl);
return *this;
}
template <class charT, class traits>
typename basic_regex<charT, traits>::locale_type basic_regex<charT, traits>::imbue(locale_type l)
{
std::shared_ptr<BOOST_REGEX_DETAIL_NS::basic_regex_implementation<charT, traits> > temp(new BOOST_REGEX_DETAIL_NS::basic_regex_implementation<charT, traits>());
locale_type result = temp->imbue(l);
temp.swap(m_pimpl);
return result;
}
//
// non-members:
//
template <class charT, class traits>
void swap(basic_regex<charT, traits>& e1, basic_regex<charT, traits>& e2)
{
e1.swap(e2);
}
template <class charT, class traits, class traits2>
std::basic_ostream<charT, traits>&
operator << (std::basic_ostream<charT, traits>& os,
const basic_regex<charT, traits2>& e)
{
return (os << e.str());
}
//
// class reg_expression:
// this is provided for backwards compatibility only,
// it is deprecated, no not use!
//
#ifdef BOOST_REGEX_NO_FWD
template <class charT, class traits = regex_traits<charT> >
#else
template <class charT, class traits >
#endif
class reg_expression : public basic_regex<charT, traits>
{
public:
typedef typename basic_regex<charT, traits>::flag_type flag_type;
typedef typename basic_regex<charT, traits>::size_type size_type;
explicit reg_expression(){}
explicit reg_expression(const charT* p, flag_type f = regex_constants::normal)
: basic_regex<charT, traits>(p, f){}
reg_expression(const charT* p1, const charT* p2, flag_type f = regex_constants::normal)
: basic_regex<charT, traits>(p1, p2, f){}
reg_expression(const charT* p, size_type len, flag_type f)
: basic_regex<charT, traits>(p, len, f){}
reg_expression(const reg_expression& that)
: basic_regex<charT, traits>(that) {}
~reg_expression(){}
reg_expression& operator=(const reg_expression& that)
{
return this->assign(that);
}
template <class ST, class SA>
explicit reg_expression(const std::basic_string<charT, ST, SA>& p, flag_type f = regex_constants::normal)
: basic_regex<charT, traits>(p, f)
{
}
template <class InputIterator>
reg_expression(InputIterator arg_first, InputIterator arg_last, flag_type f = regex_constants::normal)
: basic_regex<charT, traits>(arg_first, arg_last, f)
{
}
template <class ST, class SA>
reg_expression& operator=(const std::basic_string<charT, ST, SA>& p)
{
this->assign(p);
return *this;
}
};
#ifdef BOOST_REGEX_MSVC
#pragma warning (pop)
#endif
} // namespace boost
#endif

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -1,474 +0,0 @@
/*
*
* Copyright (c) 2004
* John Maddock
*
* Use, modification and distribution are subject to 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)
*
*/
/*
* LOCATION: see http://www.boost.org for most recent version.
* FILE c_regex_traits.hpp
* VERSION see <boost/version.hpp>
* DESCRIPTION: Declares regular expression traits class that wraps the global C locale.
*/
#ifndef BOOST_C_REGEX_TRAITS_HPP_INCLUDED
#define BOOST_C_REGEX_TRAITS_HPP_INCLUDED
#include <boost/regex/config.hpp>
#include <boost/regex/v5/regex_workaround.hpp>
#include <cctype>
namespace boost{
namespace BOOST_REGEX_DETAIL_NS {
enum
{
char_class_space = 1 << 0,
char_class_print = 1 << 1,
char_class_cntrl = 1 << 2,
char_class_upper = 1 << 3,
char_class_lower = 1 << 4,
char_class_alpha = 1 << 5,
char_class_digit = 1 << 6,
char_class_punct = 1 << 7,
char_class_xdigit = 1 << 8,
char_class_alnum = char_class_alpha | char_class_digit,
char_class_graph = char_class_alnum | char_class_punct,
char_class_blank = 1 << 9,
char_class_word = 1 << 10,
char_class_unicode = 1 << 11,
char_class_horizontal = 1 << 12,
char_class_vertical = 1 << 13
};
}
template <class charT>
struct c_regex_traits;
template<>
struct c_regex_traits<char>
{
c_regex_traits(){}
typedef char char_type;
typedef std::size_t size_type;
typedef std::string string_type;
struct locale_type{};
typedef std::uint32_t char_class_type;
static size_type length(const char_type* p)
{
return (std::strlen)(p);
}
char translate(char c) const
{
return c;
}
char translate_nocase(char c) const
{
return static_cast<char>((std::tolower)(static_cast<unsigned char>(c)));
}
static string_type transform(const char* p1, const char* p2);
static string_type transform_primary(const char* p1, const char* p2);
static char_class_type lookup_classname(const char* p1, const char* p2);
static string_type lookup_collatename(const char* p1, const char* p2);
static bool isctype(char, char_class_type);
static int value(char, int);
locale_type imbue(locale_type l)
{ return l; }
locale_type getloc()const
{ return locale_type(); }
private:
// this type is not copyable:
c_regex_traits(const c_regex_traits&);
c_regex_traits& operator=(const c_regex_traits&);
};
#ifndef BOOST_NO_WREGEX
template<>
struct c_regex_traits<wchar_t>
{
c_regex_traits(){}
typedef wchar_t char_type;
typedef std::size_t size_type;
typedef std::wstring string_type;
struct locale_type{};
typedef std::uint32_t char_class_type;
static size_type length(const char_type* p)
{
return (std::wcslen)(p);
}
wchar_t translate(wchar_t c) const
{
return c;
}
wchar_t translate_nocase(wchar_t c) const
{
return (std::towlower)(c);
}
static string_type transform(const wchar_t* p1, const wchar_t* p2);
static string_type transform_primary(const wchar_t* p1, const wchar_t* p2);
static char_class_type lookup_classname(const wchar_t* p1, const wchar_t* p2);
static string_type lookup_collatename(const wchar_t* p1, const wchar_t* p2);
static bool isctype(wchar_t, char_class_type);
static int value(wchar_t, int);
locale_type imbue(locale_type l)
{ return l; }
locale_type getloc()const
{ return locale_type(); }
private:
// this type is not copyable:
c_regex_traits(const c_regex_traits&);
c_regex_traits& operator=(const c_regex_traits&);
};
#endif // BOOST_NO_WREGEX
inline c_regex_traits<char>::string_type c_regex_traits<char>::transform(const char* p1, const char* p2)
{
std::string result(10, ' ');
std::size_t s = result.size();
std::size_t r;
std::string src(p1, p2);
while (s < (r = std::strxfrm(&*result.begin(), src.c_str(), s)))
{
#if defined(_CPPLIB_VER)
//
// A bug in VC11 and 12 causes the program to hang if we pass a null-string
// to std::strxfrm, but only for certain locales :-(
// Probably effects Intel and Clang or any compiler using the VC std library (Dinkumware).
//
if (r == INT_MAX)
{
result.erase();
result.insert(result.begin(), static_cast<char>(0));
return result;
}
#endif
result.append(r - s + 3, ' ');
s = result.size();
}
result.erase(r);
return result;
}
inline c_regex_traits<char>::string_type c_regex_traits<char>::transform_primary(const char* p1, const char* p2)
{
static char s_delim;
static const int s_collate_type = ::boost::BOOST_REGEX_DETAIL_NS::find_sort_syntax(static_cast<c_regex_traits<char>*>(0), &s_delim);
std::string result;
//
// What we do here depends upon the format of the sort key returned by
// sort key returned by this->transform:
//
switch (s_collate_type)
{
case ::boost::BOOST_REGEX_DETAIL_NS::sort_C:
case ::boost::BOOST_REGEX_DETAIL_NS::sort_unknown:
// the best we can do is translate to lower case, then get a regular sort key:
{
result.assign(p1, p2);
for (std::string::size_type i = 0; i < result.size(); ++i)
result[i] = static_cast<char>((std::tolower)(static_cast<unsigned char>(result[i])));
result = transform(&*result.begin(), &*result.begin() + result.size());
break;
}
case ::boost::BOOST_REGEX_DETAIL_NS::sort_fixed:
{
// get a regular sort key, and then truncate it:
result = transform(p1, p2);
result.erase(s_delim);
break;
}
case ::boost::BOOST_REGEX_DETAIL_NS::sort_delim:
// get a regular sort key, and then truncate everything after the delim:
result = transform(p1, p2);
if ((!result.empty()) && (result[0] == s_delim))
break;
std::size_t i;
for (i = 0; i < result.size(); ++i)
{
if (result[i] == s_delim)
break;
}
result.erase(i);
break;
}
if (result.empty())
result = std::string(1, char(0));
return result;
}
inline c_regex_traits<char>::char_class_type c_regex_traits<char>::lookup_classname(const char* p1, const char* p2)
{
using namespace BOOST_REGEX_DETAIL_NS;
static const char_class_type masks[] =
{
0,
char_class_alnum,
char_class_alpha,
char_class_blank,
char_class_cntrl,
char_class_digit,
char_class_digit,
char_class_graph,
char_class_horizontal,
char_class_lower,
char_class_lower,
char_class_print,
char_class_punct,
char_class_space,
char_class_space,
char_class_upper,
char_class_unicode,
char_class_upper,
char_class_vertical,
char_class_alnum | char_class_word,
char_class_alnum | char_class_word,
char_class_xdigit,
};
int idx = ::boost::BOOST_REGEX_DETAIL_NS::get_default_class_id(p1, p2);
if (idx < 0)
{
std::string s(p1, p2);
for (std::string::size_type i = 0; i < s.size(); ++i)
s[i] = static_cast<char>((std::tolower)(static_cast<unsigned char>(s[i])));
idx = ::boost::BOOST_REGEX_DETAIL_NS::get_default_class_id(&*s.begin(), &*s.begin() + s.size());
}
BOOST_REGEX_ASSERT(std::size_t(idx) + 1u < sizeof(masks) / sizeof(masks[0]));
return masks[idx + 1];
}
inline bool c_regex_traits<char>::isctype(char c, char_class_type mask)
{
using namespace BOOST_REGEX_DETAIL_NS;
return
((mask & char_class_space) && (std::isspace)(static_cast<unsigned char>(c)))
|| ((mask & char_class_print) && (std::isprint)(static_cast<unsigned char>(c)))
|| ((mask & char_class_cntrl) && (std::iscntrl)(static_cast<unsigned char>(c)))
|| ((mask & char_class_upper) && (std::isupper)(static_cast<unsigned char>(c)))
|| ((mask & char_class_lower) && (std::islower)(static_cast<unsigned char>(c)))
|| ((mask & char_class_alpha) && (std::isalpha)(static_cast<unsigned char>(c)))
|| ((mask & char_class_digit) && (std::isdigit)(static_cast<unsigned char>(c)))
|| ((mask & char_class_punct) && (std::ispunct)(static_cast<unsigned char>(c)))
|| ((mask & char_class_xdigit) && (std::isxdigit)(static_cast<unsigned char>(c)))
|| ((mask & char_class_blank) && (std::isspace)(static_cast<unsigned char>(c)) && !::boost::BOOST_REGEX_DETAIL_NS::is_separator(c))
|| ((mask & char_class_word) && (c == '_'))
|| ((mask & char_class_vertical) && (::boost::BOOST_REGEX_DETAIL_NS::is_separator(c) || (c == '\v')))
|| ((mask & char_class_horizontal) && (std::isspace)(static_cast<unsigned char>(c)) && !::boost::BOOST_REGEX_DETAIL_NS::is_separator(c) && (c != '\v'));
}
inline c_regex_traits<char>::string_type c_regex_traits<char>::lookup_collatename(const char* p1, const char* p2)
{
std::string s(p1, p2);
s = ::boost::BOOST_REGEX_DETAIL_NS::lookup_default_collate_name(s);
if (s.empty() && (p2 - p1 == 1))
s.append(1, *p1);
return s;
}
inline int c_regex_traits<char>::value(char c, int radix)
{
char b[2] = { c, '\0', };
char* ep;
int result = std::strtol(b, &ep, radix);
if (ep == b)
return -1;
return result;
}
#ifndef BOOST_NO_WREGEX
inline c_regex_traits<wchar_t>::string_type c_regex_traits<wchar_t>::transform(const wchar_t* p1, const wchar_t* p2)
{
std::size_t r;
std::size_t s = 10;
std::wstring src(p1, p2);
std::wstring result(s, L' ');
while (s < (r = std::wcsxfrm(&*result.begin(), src.c_str(), s)))
{
#if defined(_CPPLIB_VER)
//
// A bug in VC11 and 12 causes the program to hang if we pass a null-string
// to std::strxfrm, but only for certain locales :-(
// Probably effects Intel and Clang or any compiler using the VC std library (Dinkumware).
//
if (r == INT_MAX)
{
result.erase();
result.insert(result.begin(), static_cast<wchar_t>(0));
return result;
}
#endif
result.append(r - s + 3, L' ');
s = result.size();
}
result.erase(r);
return result;
}
inline c_regex_traits<wchar_t>::string_type c_regex_traits<wchar_t>::transform_primary(const wchar_t* p1, const wchar_t* p2)
{
static wchar_t s_delim;
static const int s_collate_type = ::boost::BOOST_REGEX_DETAIL_NS::find_sort_syntax(static_cast<const c_regex_traits<wchar_t>*>(0), &s_delim);
std::wstring result;
//
// What we do here depends upon the format of the sort key returned by
// sort key returned by this->transform:
//
switch (s_collate_type)
{
case ::boost::BOOST_REGEX_DETAIL_NS::sort_C:
case ::boost::BOOST_REGEX_DETAIL_NS::sort_unknown:
// the best we can do is translate to lower case, then get a regular sort key:
{
result.assign(p1, p2);
for (std::wstring::size_type i = 0; i < result.size(); ++i)
result[i] = (std::towlower)(result[i]);
result = c_regex_traits<wchar_t>::transform(&*result.begin(), &*result.begin() + result.size());
break;
}
case ::boost::BOOST_REGEX_DETAIL_NS::sort_fixed:
{
// get a regular sort key, and then truncate it:
result = c_regex_traits<wchar_t>::transform(&*result.begin(), &*result.begin() + result.size());
result.erase(s_delim);
break;
}
case ::boost::BOOST_REGEX_DETAIL_NS::sort_delim:
// get a regular sort key, and then truncate everything after the delim:
result = c_regex_traits<wchar_t>::transform(&*result.begin(), &*result.begin() + result.size());
if ((!result.empty()) && (result[0] == s_delim))
break;
std::size_t i;
for (i = 0; i < result.size(); ++i)
{
if (result[i] == s_delim)
break;
}
result.erase(i);
break;
}
if (result.empty())
result = std::wstring(1, char(0));
return result;
}
inline c_regex_traits<wchar_t>::char_class_type c_regex_traits<wchar_t>::lookup_classname(const wchar_t* p1, const wchar_t* p2)
{
using namespace BOOST_REGEX_DETAIL_NS;
static const char_class_type masks[] =
{
0,
char_class_alnum,
char_class_alpha,
char_class_blank,
char_class_cntrl,
char_class_digit,
char_class_digit,
char_class_graph,
char_class_horizontal,
char_class_lower,
char_class_lower,
char_class_print,
char_class_punct,
char_class_space,
char_class_space,
char_class_upper,
char_class_unicode,
char_class_upper,
char_class_vertical,
char_class_alnum | char_class_word,
char_class_alnum | char_class_word,
char_class_xdigit,
};
int idx = ::boost::BOOST_REGEX_DETAIL_NS::get_default_class_id(p1, p2);
if (idx < 0)
{
std::wstring s(p1, p2);
for (std::wstring::size_type i = 0; i < s.size(); ++i)
s[i] = (std::towlower)(s[i]);
idx = ::boost::BOOST_REGEX_DETAIL_NS::get_default_class_id(&*s.begin(), &*s.begin() + s.size());
}
BOOST_REGEX_ASSERT(idx + 1 < static_cast<int>(sizeof(masks) / sizeof(masks[0])));
return masks[idx + 1];
}
inline bool c_regex_traits<wchar_t>::isctype(wchar_t c, char_class_type mask)
{
using namespace BOOST_REGEX_DETAIL_NS;
return
((mask & char_class_space) && (std::iswspace)(c))
|| ((mask & char_class_print) && (std::iswprint)(c))
|| ((mask & char_class_cntrl) && (std::iswcntrl)(c))
|| ((mask & char_class_upper) && (std::iswupper)(c))
|| ((mask & char_class_lower) && (std::iswlower)(c))
|| ((mask & char_class_alpha) && (std::iswalpha)(c))
|| ((mask & char_class_digit) && (std::iswdigit)(c))
|| ((mask & char_class_punct) && (std::iswpunct)(c))
|| ((mask & char_class_xdigit) && (std::iswxdigit)(c))
|| ((mask & char_class_blank) && (std::iswspace)(c) && !::boost::BOOST_REGEX_DETAIL_NS::is_separator(c))
|| ((mask & char_class_word) && (c == '_'))
|| ((mask & char_class_unicode) && (c & ~static_cast<wchar_t>(0xff)))
|| ((mask & char_class_vertical) && (::boost::BOOST_REGEX_DETAIL_NS::is_separator(c) || (c == L'\v')))
|| ((mask & char_class_horizontal) && (std::iswspace)(c) && !::boost::BOOST_REGEX_DETAIL_NS::is_separator(c) && (c != L'\v'));
}
inline c_regex_traits<wchar_t>::string_type c_regex_traits<wchar_t>::lookup_collatename(const wchar_t* p1, const wchar_t* p2)
{
std::string name;
// Usual msvc warning suppression does not work here with std::string template constructor.... use a workaround instead:
for (const wchar_t* pos = p1; pos != p2; ++pos)
name.push_back((char)*pos);
name = ::boost::BOOST_REGEX_DETAIL_NS::lookup_default_collate_name(name);
if (!name.empty())
return string_type(name.begin(), name.end());
if (p2 - p1 == 1)
return string_type(1, *p1);
return string_type();
}
inline int c_regex_traits<wchar_t>::value(wchar_t c, int radix)
{
#ifdef BOOST_BORLANDC
// workaround for broken wcstol:
if ((std::iswxdigit)(c) == 0)
return -1;
#endif
wchar_t b[2] = { c, '\0', };
wchar_t* ep;
int result = std::wcstol(b, &ep, radix);
if (ep == b)
return -1;
return result;
}
#endif
}
#endif

View File

@@ -1,59 +0,0 @@
/*
*
* Copyright (c) 2002
* John Maddock
*
* Use, modification and distribution are subject to 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)
*
*/
/*
* LOCATION: see http://www.boost.org for most recent version.
* FILE char_regex_traits.cpp
* VERSION see <boost/version.hpp>
* DESCRIPTION: Declares deprecated traits classes char_regex_traits<>.
*/
#ifndef BOOST_REGEX_V5_CHAR_REGEX_TRAITS_HPP
#define BOOST_REGEX_V5_CHAR_REGEX_TRAITS_HPP
namespace boost{
namespace deprecated{
//
// class char_regex_traits_i
// provides case insensitive traits classes (deprecated):
template <class charT>
class char_regex_traits_i : public regex_traits<charT> {};
template<>
class char_regex_traits_i<char> : public regex_traits<char>
{
public:
typedef char char_type;
typedef unsigned char uchar_type;
typedef unsigned int size_type;
typedef regex_traits<char> base_type;
};
#ifndef BOOST_NO_WREGEX
template<>
class char_regex_traits_i<wchar_t> : public regex_traits<wchar_t>
{
public:
typedef wchar_t char_type;
typedef unsigned short uchar_type;
typedef unsigned int size_type;
typedef regex_traits<wchar_t> base_type;
};
#endif
} // namespace deprecated
} // namespace boost
#endif // include

File diff suppressed because it is too large Load Diff

View File

@@ -1,195 +0,0 @@
/*
*
* Copyright (c) 1998-2002
* John Maddock
*
* Use, modification and distribution are subject to 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)
*
*/
/*
* LOCATION: see http://www.boost.org for most recent version.
* FILE cregex.cpp
* VERSION see <boost/version.hpp>
* DESCRIPTION: Declares POSIX API functions
* + boost::RegEx high level wrapper.
*/
#ifndef BOOST_RE_CREGEX_HPP_INCLUDED
#define BOOST_RE_CREGEX_HPP_INCLUDED
#ifndef BOOST_REGEX_CONFIG_HPP
#include <boost/regex/config.hpp>
#endif
#include <boost/regex/v5/match_flags.hpp>
#include <boost/regex/v5/error_type.hpp>
#ifndef BOOST_REGEX_STANDALONE
#if !defined(BOOST_REGEX_NO_LIB) && !defined(BOOST_REGEX_SOURCE) && !defined(BOOST_ALL_NO_LIB) && defined(__cplusplus)
# define BOOST_LIB_NAME boost_regex
# if defined(BOOST_REGEX_DYN_LINK) || defined(BOOST_ALL_DYN_LINK)
# define BOOST_DYN_LINK
# endif
# ifdef BOOST_REGEX_DIAG
# define BOOST_LIB_DIAGNOSTIC
# endif
# include <boost/config/auto_link.hpp>
#endif
#endif
#ifdef __cplusplus
#include <cstddef>
#else
#include <stddef.h>
#endif
/* include these defs only for POSIX compatablity */
#ifdef __cplusplus
namespace boost{
extern "C" {
#endif
#if defined(__cplusplus)
typedef std::ptrdiff_t regoff_t;
typedef std::size_t regsize_t;
#else
typedef ptrdiff_t regoff_t;
typedef size_t regsize_t;
#endif
typedef struct
{
unsigned int re_magic;
#ifdef __cplusplus
std::size_t re_nsub; /* number of parenthesized subexpressions */
#else
size_t re_nsub;
#endif
const char* re_endp; /* end pointer for REG_PEND */
void* guts; /* none of your business :-) */
match_flag_type eflags; /* none of your business :-) */
} regex_tA;
#ifndef BOOST_NO_WREGEX
typedef struct
{
unsigned int re_magic;
#ifdef __cplusplus
std::size_t re_nsub; /* number of parenthesized subexpressions */
#else
size_t re_nsub;
#endif
const wchar_t* re_endp; /* end pointer for REG_PEND */
void* guts; /* none of your business :-) */
match_flag_type eflags; /* none of your business :-) */
} regex_tW;
#endif
typedef struct
{
regoff_t rm_so; /* start of match */
regoff_t rm_eo; /* end of match */
} regmatch_t;
/* regcomp() flags */
typedef enum{
REG_BASIC = 0000,
REG_EXTENDED = 0001,
REG_ICASE = 0002,
REG_NOSUB = 0004,
REG_NEWLINE = 0010,
REG_NOSPEC = 0020,
REG_PEND = 0040,
REG_DUMP = 0200,
REG_NOCOLLATE = 0400,
REG_ESCAPE_IN_LISTS = 01000,
REG_NEWLINE_ALT = 02000,
REG_PERLEX = 04000,
REG_PERL = REG_EXTENDED | REG_NOCOLLATE | REG_ESCAPE_IN_LISTS | REG_PERLEX,
REG_AWK = REG_EXTENDED | REG_ESCAPE_IN_LISTS,
REG_GREP = REG_BASIC | REG_NEWLINE_ALT,
REG_EGREP = REG_EXTENDED | REG_NEWLINE_ALT,
REG_ASSERT = 15,
REG_INVARG = 16,
REG_ATOI = 255, /* convert name to number (!) */
REG_ITOA = 0400 /* convert number to name (!) */
} reg_comp_flags;
/* regexec() flags */
typedef enum{
REG_NOTBOL = 00001,
REG_NOTEOL = 00002,
REG_STARTEND = 00004
} reg_exec_flags;
/*
* POSIX error codes:
*/
typedef unsigned reg_error_t;
typedef reg_error_t reg_errcode_t; /* backwards compatibility */
static const reg_error_t REG_NOERROR = 0; /* Success. */
static const reg_error_t REG_NOMATCH = 1; /* Didn't find a match (for regexec). */
/* POSIX regcomp return error codes. (In the order listed in the
standard.) */
static const reg_error_t REG_BADPAT = 2; /* Invalid pattern. */
static const reg_error_t REG_ECOLLATE = 3; /* Undefined collating element. */
static const reg_error_t REG_ECTYPE = 4; /* Invalid character class name. */
static const reg_error_t REG_EESCAPE = 5; /* Trailing backslash. */
static const reg_error_t REG_ESUBREG = 6; /* Invalid back reference. */
static const reg_error_t REG_EBRACK = 7; /* Unmatched left bracket. */
static const reg_error_t REG_EPAREN = 8; /* Parenthesis imbalance. */
static const reg_error_t REG_EBRACE = 9; /* Unmatched \{. */
static const reg_error_t REG_BADBR = 10; /* Invalid contents of \{\}. */
static const reg_error_t REG_ERANGE = 11; /* Invalid range end. */
static const reg_error_t REG_ESPACE = 12; /* Ran out of memory. */
static const reg_error_t REG_BADRPT = 13; /* No preceding re for repetition op. */
static const reg_error_t REG_EEND = 14; /* unexpected end of expression */
static const reg_error_t REG_ESIZE = 15; /* expression too big */
static const reg_error_t REG_ERPAREN = 8; /* = REG_EPAREN : unmatched right parenthesis */
static const reg_error_t REG_EMPTY = 17; /* empty expression */
static const reg_error_t REG_E_MEMORY = 15; /* = REG_ESIZE : out of memory */
static const reg_error_t REG_ECOMPLEXITY = 18; /* complexity too high */
static const reg_error_t REG_ESTACK = 19; /* out of stack space */
static const reg_error_t REG_E_PERL = 20; /* Perl (?...) error */
static const reg_error_t REG_E_UNKNOWN = 21; /* unknown error */
static const reg_error_t REG_ENOSYS = 21; /* = REG_E_UNKNOWN : Reserved. */
BOOST_REGEX_DECL int BOOST_REGEX_CCALL regcompA(regex_tA*, const char*, int);
BOOST_REGEX_DECL regsize_t BOOST_REGEX_CCALL regerrorA(int, const regex_tA*, char*, regsize_t);
BOOST_REGEX_DECL int BOOST_REGEX_CCALL regexecA(const regex_tA*, const char*, regsize_t, regmatch_t*, int);
BOOST_REGEX_DECL void BOOST_REGEX_CCALL regfreeA(regex_tA*);
#ifndef BOOST_NO_WREGEX
BOOST_REGEX_DECL int BOOST_REGEX_CCALL regcompW(regex_tW*, const wchar_t*, int);
BOOST_REGEX_DECL regsize_t BOOST_REGEX_CCALL regerrorW(int, const regex_tW*, wchar_t*, regsize_t);
BOOST_REGEX_DECL int BOOST_REGEX_CCALL regexecW(const regex_tW*, const wchar_t*, regsize_t, regmatch_t*, int);
BOOST_REGEX_DECL void BOOST_REGEX_CCALL regfreeW(regex_tW*);
#endif
#ifdef UNICODE
#define regcomp regcompW
#define regerror regerrorW
#define regexec regexecW
#define regfree regfreeW
#define regex_t regex_tW
#else
#define regcomp regcompA
#define regerror regerrorA
#define regexec regexecA
#define regfree regfreeA
#define regex_t regex_tA
#endif
#ifdef __cplusplus
} /* extern "C" */
} /* namespace */
#endif
#endif /* include guard */

View File

@@ -1,59 +0,0 @@
/*
*
* Copyright (c) 2003-2005
* John Maddock
*
* Use, modification and distribution are subject to 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)
*
*/
/*
* LOCATION: see http://www.boost.org for most recent version.
* FILE error_type.hpp
* VERSION see <boost/version.hpp>
* DESCRIPTION: Declares regular expression error type enumerator.
*/
#ifndef BOOST_REGEX_ERROR_TYPE_HPP
#define BOOST_REGEX_ERROR_TYPE_HPP
#ifdef __cplusplus
namespace boost{
#endif
#ifdef __cplusplus
namespace regex_constants{
enum error_type{
error_ok = 0, /* not used */
error_no_match = 1, /* not used */
error_bad_pattern = 2,
error_collate = 3,
error_ctype = 4,
error_escape = 5,
error_backref = 6,
error_brack = 7,
error_paren = 8,
error_brace = 9,
error_badbrace = 10,
error_range = 11,
error_space = 12,
error_badrepeat = 13,
error_end = 14, /* not used */
error_size = 15,
error_right_paren = 16, /* not used */
error_empty = 17,
error_complexity = 18,
error_stack = 19,
error_perl_extension = 20,
error_unknown = 21
};
}
}
#endif /* __cplusplus */
#endif

File diff suppressed because it is too large Load Diff

View File

@@ -1,84 +0,0 @@
/*
*
* Copyright (c) 2002
* John Maddock
*
* Use, modification and distribution are subject to 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)
*
*/
/*
* LOCATION: see http://www.boost.org for most recent version.
* FILE regex_match.hpp
* VERSION see <boost/version.hpp>
* DESCRIPTION: Iterator traits for selecting an iterator type as
* an integral constant expression.
*/
#ifndef BOOST_REGEX_ITERATOR_CATEGORY_HPP
#define BOOST_REGEX_ITERATOR_CATEGORY_HPP
#include <iterator>
#include <type_traits>
namespace boost{
namespace detail{
template <class I>
struct is_random_imp
{
private:
typedef typename std::iterator_traits<I>::iterator_category cat;
public:
static const bool value = (std::is_convertible<cat*, std::random_access_iterator_tag*>::value);
};
template <class I>
struct is_random_pointer_imp
{
static const bool value = true;
};
template <bool is_pointer_type>
struct is_random_imp_selector
{
template <class I>
struct rebind
{
typedef is_random_imp<I> type;
};
};
template <>
struct is_random_imp_selector<true>
{
template <class I>
struct rebind
{
typedef is_random_pointer_imp<I> type;
};
};
}
template <class I>
struct is_random_access_iterator
{
private:
typedef detail::is_random_imp_selector< std::is_pointer<I>::value> selector;
typedef typename selector::template rebind<I> bound_type;
typedef typename bound_type::type answer;
public:
static const bool value = answer::value;
};
template <class I>
const bool is_random_access_iterator<I>::value;
}
#endif

View File

@@ -1,32 +0,0 @@
/*
*
* Copyright (c) 1998-2002
* John Maddock
*
* Use, modification and distribution are subject to 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)
*
*/
/*
* LOCATION: see http://www.boost.org for most recent version.
* FILE iterator_traits.cpp
* VERSION see <boost/version.hpp>
* DESCRIPTION: Declares iterator traits workarounds.
*/
#ifndef BOOST_REGEX_V5_ITERATOR_TRAITS_HPP
#define BOOST_REGEX_V5_ITERATOR_TRAITS_HPP
namespace boost{
namespace BOOST_REGEX_DETAIL_NS{
template <class T>
struct regex_iterator_traits : public std::iterator_traits<T> {};
} // namespace BOOST_REGEX_DETAIL_NS
} // namespace boost
#endif

View File

@@ -1,156 +0,0 @@
/*
*
* Copyright (c) 1998-2002
* John Maddock
*
* Use, modification and distribution are subject to 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)
*
*/
/*
* LOCATION: see http://www.boost.org for most recent version.
* FILE match_flags.hpp
* VERSION see <boost/version.hpp>
* DESCRIPTION: Declares match_flags type.
*/
#ifndef BOOST_REGEX_V5_MATCH_FLAGS
#define BOOST_REGEX_V5_MATCH_FLAGS
#ifdef __cplusplus
# include <cstdint>
#endif
#ifdef __cplusplus
namespace boost{
namespace regex_constants{
#endif
#ifdef BOOST_REGEX_MSVC
#pragma warning(push)
#if BOOST_REGEX_MSVC >= 1800
#pragma warning(disable : 26812)
#endif
#endif
typedef enum _match_flags
{
match_default = 0,
match_not_bol = 1, /* first is not start of line */
match_not_eol = match_not_bol << 1, /* last is not end of line */
match_not_bob = match_not_eol << 1, /* first is not start of buffer */
match_not_eob = match_not_bob << 1, /* last is not end of buffer */
match_not_bow = match_not_eob << 1, /* first is not start of word */
match_not_eow = match_not_bow << 1, /* last is not end of word */
match_not_dot_newline = match_not_eow << 1, /* \n is not matched by '.' */
match_not_dot_null = match_not_dot_newline << 1, /* '\0' is not matched by '.' */
match_prev_avail = match_not_dot_null << 1, /* *--first is a valid expression */
match_init = match_prev_avail << 1, /* internal use */
match_any = match_init << 1, /* don't care what we match */
match_not_null = match_any << 1, /* string can't be null */
match_continuous = match_not_null << 1, /* each grep match must continue from */
/* uninterrupted from the previous one */
match_partial = match_continuous << 1, /* find partial matches */
match_stop = match_partial << 1, /* stop after first match (grep) V3 only */
match_not_initial_null = match_stop, /* don't match initial null, V4 only */
match_all = match_stop << 1, /* must find the whole of input even if match_any is set */
match_perl = match_all << 1, /* Use perl matching rules */
match_posix = match_perl << 1, /* Use POSIX matching rules */
match_nosubs = match_posix << 1, /* don't trap marked subs */
match_extra = match_nosubs << 1, /* include full capture information for repeated captures */
match_single_line = match_extra << 1, /* treat text as single line and ignore any \n's when matching ^ and $. */
match_unused1 = match_single_line << 1, /* unused */
match_unused2 = match_unused1 << 1, /* unused */
match_unused3 = match_unused2 << 1, /* unused */
match_max = match_unused3,
format_perl = 0, /* perl style replacement */
format_default = 0, /* ditto. */
format_sed = match_max << 1, /* sed style replacement. */
format_all = format_sed << 1, /* enable all extensions to syntax. */
format_no_copy = format_all << 1, /* don't copy non-matching segments. */
format_first_only = format_no_copy << 1, /* Only replace first occurrence. */
format_is_if = format_first_only << 1, /* internal use only. */
format_literal = format_is_if << 1, /* treat string as a literal */
match_not_any = match_not_bol | match_not_eol | match_not_bob
| match_not_eob | match_not_bow | match_not_eow | match_not_dot_newline
| match_not_dot_null | match_prev_avail | match_init | match_not_null
| match_continuous | match_partial | match_stop | match_not_initial_null
| match_stop | match_all | match_perl | match_posix | match_nosubs
| match_extra | match_single_line | match_unused1 | match_unused2
| match_unused3 | match_max | format_perl | format_default | format_sed
| format_all | format_no_copy | format_first_only | format_is_if
| format_literal
} match_flags;
typedef match_flags match_flag_type;
#ifdef __cplusplus
inline match_flags operator&(match_flags m1, match_flags m2)
{ return static_cast<match_flags>(static_cast<std::int32_t>(m1) & static_cast<std::int32_t>(m2)); }
inline match_flags operator|(match_flags m1, match_flags m2)
{ return static_cast<match_flags>(static_cast<std::int32_t>(m1) | static_cast<std::int32_t>(m2)); }
inline match_flags operator^(match_flags m1, match_flags m2)
{ return static_cast<match_flags>(static_cast<std::int32_t>(m1) ^ static_cast<std::int32_t>(m2)); }
inline match_flags operator~(match_flags m1)
{ return static_cast<match_flags>(~static_cast<std::int32_t>(m1)); }
inline match_flags& operator&=(match_flags& m1, match_flags m2)
{ m1 = m1&m2; return m1; }
inline match_flags& operator|=(match_flags& m1, match_flags m2)
{ m1 = m1|m2; return m1; }
inline match_flags& operator^=(match_flags& m1, match_flags m2)
{ m1 = m1^m2; return m1; }
#endif
#ifdef __cplusplus
} /* namespace regex_constants */
/*
* import names into boost for backwards compatibility:
*/
using regex_constants::match_flag_type;
using regex_constants::match_default;
using regex_constants::match_not_bol;
using regex_constants::match_not_eol;
using regex_constants::match_not_bob;
using regex_constants::match_not_eob;
using regex_constants::match_not_bow;
using regex_constants::match_not_eow;
using regex_constants::match_not_dot_newline;
using regex_constants::match_not_dot_null;
using regex_constants::match_prev_avail;
/* using regex_constants::match_init; */
using regex_constants::match_any;
using regex_constants::match_not_null;
using regex_constants::match_continuous;
using regex_constants::match_partial;
/*using regex_constants::match_stop; */
using regex_constants::match_all;
using regex_constants::match_perl;
using regex_constants::match_posix;
using regex_constants::match_nosubs;
using regex_constants::match_extra;
using regex_constants::match_single_line;
/*using regex_constants::match_max; */
using regex_constants::format_all;
using regex_constants::format_sed;
using regex_constants::format_perl;
using regex_constants::format_default;
using regex_constants::format_no_copy;
using regex_constants::format_first_only;
/*using regex_constants::format_is_if;*/
#ifdef BOOST_REGEX_MSVC
#pragma warning(pop)
#endif
} /* namespace boost */
#endif /* __cplusplus */
#endif /* include guard */

View File

@@ -1,667 +0,0 @@
/*
*
* Copyright (c) 1998-2009
* John Maddock
*
* Use, modification and distribution are subject to 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)
*
*/
/*
* LOCATION: see http://www.boost.org for most recent version.
* FILE match_results.cpp
* VERSION see <boost/version.hpp>
* DESCRIPTION: Declares template class match_results.
*/
#ifndef BOOST_REGEX_V5_MATCH_RESULTS_HPP
#define BOOST_REGEX_V5_MATCH_RESULTS_HPP
namespace boost{
#ifdef BOOST_REGEX_MSVC
#pragma warning(push)
#pragma warning(disable : 4251 4459)
#if BOOST_REGEX_MSVC < 1700
# pragma warning(disable : 4231)
#endif
# if BOOST_REGEX_MSVC < 1600
# pragma warning(disable : 4660)
# endif
#endif
namespace BOOST_REGEX_DETAIL_NS{
class named_subexpressions;
}
template <class BidiIterator, class Allocator>
class match_results
{
private:
typedef std::vector<sub_match<BidiIterator>, Allocator> vector_type;
public:
typedef sub_match<BidiIterator> value_type;
typedef typename std::allocator_traits<Allocator>::value_type const & const_reference;
typedef const_reference reference;
typedef typename vector_type::const_iterator const_iterator;
typedef const_iterator iterator;
typedef typename std::iterator_traits<
BidiIterator>::difference_type difference_type;
typedef typename std::allocator_traits<Allocator>::size_type size_type;
typedef Allocator allocator_type;
typedef typename std::iterator_traits<
BidiIterator>::value_type char_type;
typedef std::basic_string<char_type> string_type;
typedef BOOST_REGEX_DETAIL_NS::named_subexpressions named_sub_type;
// construct/copy/destroy:
explicit match_results(const Allocator& a = Allocator())
: m_subs(a), m_base(), m_null(), m_last_closed_paren(0), m_is_singular(true) {}
//
// IMPORTANT: in the code below, the crazy looking checks around m_is_singular are
// all required because it is illegal to copy a singular iterator.
// See https://svn.boost.org/trac/boost/ticket/3632.
//
match_results(const match_results& m)
: m_subs(m.m_subs), m_base(), m_null(), m_named_subs(m.m_named_subs), m_last_closed_paren(m.m_last_closed_paren), m_is_singular(m.m_is_singular)
{
if(!m_is_singular)
{
m_base = m.m_base;
m_null = m.m_null;
}
}
match_results& operator=(const match_results& m)
{
m_subs = m.m_subs;
m_named_subs = m.m_named_subs;
m_last_closed_paren = m.m_last_closed_paren;
m_is_singular = m.m_is_singular;
if(!m_is_singular)
{
m_base = m.m_base;
m_null = m.m_null;
}
return *this;
}
~match_results(){}
// size:
size_type size() const
{ return empty() ? 0 : m_subs.size() - 2; }
size_type max_size() const
{ return m_subs.max_size(); }
bool empty() const
{ return m_subs.size() < 2; }
// element access:
difference_type length(int sub = 0) const
{
if(m_is_singular)
raise_logic_error();
sub += 2;
if((sub < (int)m_subs.size()) && (sub > 0))
return m_subs[sub].length();
return 0;
}
difference_type length(const char_type* sub) const
{
if(m_is_singular)
raise_logic_error();
const char_type* sub_end = sub;
while(*sub_end) ++sub_end;
return length(named_subexpression_index(sub, sub_end));
}
template <class charT>
difference_type length(const charT* sub) const
{
if(m_is_singular)
raise_logic_error();
const charT* sub_end = sub;
while(*sub_end) ++sub_end;
return length(named_subexpression_index(sub, sub_end));
}
template <class charT, class Traits, class A>
difference_type length(const std::basic_string<charT, Traits, A>& sub) const
{
return length(sub.c_str());
}
difference_type position(size_type sub = 0) const
{
if(m_is_singular)
raise_logic_error();
sub += 2;
if(sub < m_subs.size())
{
const sub_match<BidiIterator>& s = m_subs[sub];
if(s.matched || (sub == 2))
{
return std::distance((BidiIterator)(m_base), (BidiIterator)(s.first));
}
}
return ~static_cast<difference_type>(0);
}
difference_type position(const char_type* sub) const
{
const char_type* sub_end = sub;
while(*sub_end) ++sub_end;
return position(named_subexpression_index(sub, sub_end));
}
template <class charT>
difference_type position(const charT* sub) const
{
const charT* sub_end = sub;
while(*sub_end) ++sub_end;
return position(named_subexpression_index(sub, sub_end));
}
template <class charT, class Traits, class A>
difference_type position(const std::basic_string<charT, Traits, A>& sub) const
{
return position(sub.c_str());
}
string_type str(int sub = 0) const
{
if(m_is_singular)
raise_logic_error();
sub += 2;
string_type result;
if(sub < (int)m_subs.size() && (sub > 0))
{
const sub_match<BidiIterator>& s = m_subs[sub];
if(s.matched)
{
result = s.str();
}
}
return result;
}
string_type str(const char_type* sub) const
{
return (*this)[sub].str();
}
template <class Traits, class A>
string_type str(const std::basic_string<char_type, Traits, A>& sub) const
{
return (*this)[sub].str();
}
template <class charT>
string_type str(const charT* sub) const
{
return (*this)[sub].str();
}
template <class charT, class Traits, class A>
string_type str(const std::basic_string<charT, Traits, A>& sub) const
{
return (*this)[sub].str();
}
const_reference operator[](int sub) const
{
if(m_is_singular && m_subs.empty())
raise_logic_error();
sub += 2;
if(sub < (int)m_subs.size() && (sub >= 0))
{
return m_subs[sub];
}
return m_null;
}
//
// Named sub-expressions:
//
const_reference named_subexpression(const char_type* i, const char_type* j) const
{
//
// Scan for the leftmost *matched* subexpression with the specified named:
//
if(m_is_singular)
raise_logic_error();
BOOST_REGEX_DETAIL_NS::named_subexpressions::range_type r = m_named_subs->equal_range(i, j);
while((r.first != r.second) && ((*this)[r.first->index].matched == false))
++r.first;
return r.first != r.second ? (*this)[r.first->index] : m_null;
}
template <class charT>
const_reference named_subexpression(const charT* i, const charT* j) const
{
static_assert(sizeof(charT) <= sizeof(char_type), "Failed internal logic");
if(i == j)
return m_null;
std::vector<char_type> s;
while(i != j)
s.insert(s.end(), *i++);
return named_subexpression(&*s.begin(), &*s.begin() + s.size());
}
int named_subexpression_index(const char_type* i, const char_type* j) const
{
//
// Scan for the leftmost *matched* subexpression with the specified named.
// If none found then return the leftmost expression with that name,
// otherwise an invalid index:
//
if(m_is_singular)
raise_logic_error();
BOOST_REGEX_DETAIL_NS::named_subexpressions::range_type s, r;
s = r = m_named_subs->equal_range(i, j);
while((r.first != r.second) && ((*this)[r.first->index].matched == false))
++r.first;
if(r.first == r.second)
r = s;
return r.first != r.second ? r.first->index : -20;
}
template <class charT>
int named_subexpression_index(const charT* i, const charT* j) const
{
static_assert(sizeof(charT) <= sizeof(char_type), "Failed internal logic");
if(i == j)
return -20;
std::vector<char_type> s;
while(i != j)
s.insert(s.end(), *i++);
return named_subexpression_index(&*s.begin(), &*s.begin() + s.size());
}
template <class Traits, class A>
const_reference operator[](const std::basic_string<char_type, Traits, A>& s) const
{
return named_subexpression(s.c_str(), s.c_str() + s.size());
}
const_reference operator[](const char_type* p) const
{
const char_type* e = p;
while(*e) ++e;
return named_subexpression(p, e);
}
template <class charT>
const_reference operator[](const charT* p) const
{
static_assert(sizeof(charT) <= sizeof(char_type), "Failed internal logic");
if(*p == 0)
return m_null;
std::vector<char_type> s;
while(*p)
s.insert(s.end(), *p++);
return named_subexpression(&*s.begin(), &*s.begin() + s.size());
}
template <class charT, class Traits, class A>
const_reference operator[](const std::basic_string<charT, Traits, A>& ns) const
{
static_assert(sizeof(charT) <= sizeof(char_type), "Failed internal logic");
if(ns.empty())
return m_null;
std::vector<char_type> s;
for(unsigned i = 0; i < ns.size(); ++i)
s.insert(s.end(), ns[i]);
return named_subexpression(&*s.begin(), &*s.begin() + s.size());
}
const_reference prefix() const
{
if(m_is_singular)
raise_logic_error();
return (*this)[-1];
}
const_reference suffix() const
{
if(m_is_singular)
raise_logic_error();
return (*this)[-2];
}
const_iterator begin() const
{
return (m_subs.size() > 2) ? (m_subs.begin() + 2) : m_subs.end();
}
const_iterator end() const
{
return m_subs.end();
}
// format:
template <class OutputIterator, class Functor>
OutputIterator format(OutputIterator out,
Functor fmt,
match_flag_type flags = format_default) const
{
if(m_is_singular)
raise_logic_error();
typedef typename BOOST_REGEX_DETAIL_NS::compute_functor_type<Functor, match_results<BidiIterator, Allocator>, OutputIterator>::type F;
F func(fmt);
return func(*this, out, flags);
}
template <class Functor>
string_type format(Functor fmt, match_flag_type flags = format_default) const
{
if(m_is_singular)
raise_logic_error();
std::basic_string<char_type> result;
BOOST_REGEX_DETAIL_NS::string_out_iterator<std::basic_string<char_type> > i(result);
typedef typename BOOST_REGEX_DETAIL_NS::compute_functor_type<Functor, match_results<BidiIterator, Allocator>, BOOST_REGEX_DETAIL_NS::string_out_iterator<std::basic_string<char_type> > >::type F;
F func(fmt);
func(*this, i, flags);
return result;
}
// format with locale:
template <class OutputIterator, class Functor, class RegexT>
OutputIterator format(OutputIterator out,
Functor fmt,
match_flag_type flags,
const RegexT& re) const
{
if(m_is_singular)
raise_logic_error();
typedef ::boost::regex_traits_wrapper<typename RegexT::traits_type> traits_type;
typedef typename BOOST_REGEX_DETAIL_NS::compute_functor_type<Functor, match_results<BidiIterator, Allocator>, OutputIterator, traits_type>::type F;
F func(fmt);
return func(*this, out, flags, re.get_traits());
}
template <class RegexT, class Functor>
string_type format(Functor fmt,
match_flag_type flags,
const RegexT& re) const
{
if(m_is_singular)
raise_logic_error();
typedef ::boost::regex_traits_wrapper<typename RegexT::traits_type> traits_type;
std::basic_string<char_type> result;
BOOST_REGEX_DETAIL_NS::string_out_iterator<std::basic_string<char_type> > i(result);
typedef typename BOOST_REGEX_DETAIL_NS::compute_functor_type<Functor, match_results<BidiIterator, Allocator>, BOOST_REGEX_DETAIL_NS::string_out_iterator<std::basic_string<char_type> >, traits_type >::type F;
F func(fmt);
func(*this, i, flags, re.get_traits());
return result;
}
const_reference get_last_closed_paren()const
{
if(m_is_singular)
raise_logic_error();
return m_last_closed_paren == 0 ? m_null : (*this)[m_last_closed_paren];
}
allocator_type get_allocator() const
{
return m_subs.get_allocator();
}
void swap(match_results& that)
{
std::swap(m_subs, that.m_subs);
std::swap(m_named_subs, that.m_named_subs);
std::swap(m_last_closed_paren, that.m_last_closed_paren);
if(m_is_singular)
{
if(!that.m_is_singular)
{
m_base = that.m_base;
m_null = that.m_null;
}
}
else if(that.m_is_singular)
{
that.m_base = m_base;
that.m_null = m_null;
}
else
{
std::swap(m_base, that.m_base);
std::swap(m_null, that.m_null);
}
std::swap(m_is_singular, that.m_is_singular);
}
bool operator==(const match_results& that)const
{
if(m_is_singular)
{
return that.m_is_singular;
}
else if(that.m_is_singular)
{
return false;
}
return (m_subs == that.m_subs) && (m_base == that.m_base) && (m_last_closed_paren == that.m_last_closed_paren);
}
bool operator!=(const match_results& that)const
{ return !(*this == that); }
#ifdef BOOST_REGEX_MATCH_EXTRA
typedef typename sub_match<BidiIterator>::capture_sequence_type capture_sequence_type;
const capture_sequence_type& captures(int i)const
{
if(m_is_singular)
raise_logic_error();
return (*this)[i].captures();
}
#endif
//
// private access functions:
void set_second(BidiIterator i)
{
BOOST_REGEX_ASSERT(m_subs.size() > 2);
m_subs[2].second = i;
m_subs[2].matched = true;
m_subs[0].first = i;
m_subs[0].matched = (m_subs[0].first != m_subs[0].second);
m_null.first = i;
m_null.second = i;
m_null.matched = false;
m_is_singular = false;
}
void set_second(BidiIterator i, size_type pos, bool m = true, bool escape_k = false)
{
if(pos)
m_last_closed_paren = static_cast<int>(pos);
pos += 2;
BOOST_REGEX_ASSERT(m_subs.size() > pos);
m_subs[pos].second = i;
m_subs[pos].matched = m;
if((pos == 2) && !escape_k)
{
m_subs[0].first = i;
m_subs[0].matched = (m_subs[0].first != m_subs[0].second);
m_null.first = i;
m_null.second = i;
m_null.matched = false;
m_is_singular = false;
}
}
void set_size(size_type n, BidiIterator i, BidiIterator j)
{
value_type v(j);
size_type len = m_subs.size();
if(len > n + 2)
{
m_subs.erase(m_subs.begin()+n+2, m_subs.end());
std::fill(m_subs.begin(), m_subs.end(), v);
}
else
{
std::fill(m_subs.begin(), m_subs.end(), v);
if(n+2 != len)
m_subs.insert(m_subs.end(), n+2-len, v);
}
m_subs[1].first = i;
m_last_closed_paren = 0;
}
void set_base(BidiIterator pos)
{
m_base = pos;
}
BidiIterator base()const
{
return m_base;
}
void set_first(BidiIterator i)
{
BOOST_REGEX_ASSERT(m_subs.size() > 2);
// set up prefix:
m_subs[1].second = i;
m_subs[1].matched = (m_subs[1].first != i);
// set up $0:
m_subs[2].first = i;
// zero out everything else:
for(size_type n = 3; n < m_subs.size(); ++n)
{
m_subs[n].first = m_subs[n].second = m_subs[0].second;
m_subs[n].matched = false;
}
}
void set_first(BidiIterator i, size_type pos, bool escape_k = false)
{
BOOST_REGEX_ASSERT(pos+2 < m_subs.size());
if(pos || escape_k)
{
m_subs[pos+2].first = i;
if(escape_k)
{
m_subs[1].second = i;
m_subs[1].matched = (m_subs[1].first != m_subs[1].second);
}
}
else
set_first(i);
}
void maybe_assign(const match_results<BidiIterator, Allocator>& m);
void set_named_subs(std::shared_ptr<named_sub_type> subs)
{
m_named_subs = subs;
}
private:
//
// Error handler called when an uninitialized match_results is accessed:
//
static void raise_logic_error()
{
std::logic_error e("Attempt to access an uninitialized boost::match_results<> class.");
#ifndef BOOST_REGEX_STANDALONE
boost::throw_exception(e);
#else
throw e;
#endif
}
vector_type m_subs; // subexpressions
BidiIterator m_base; // where the search started from
sub_match<BidiIterator> m_null; // a null match
std::shared_ptr<named_sub_type> m_named_subs; // Shared copy of named subs in the regex object
int m_last_closed_paren; // Last ) to be seen - used for formatting
bool m_is_singular; // True if our stored iterators are singular
};
template <class BidiIterator, class Allocator>
void match_results<BidiIterator, Allocator>::maybe_assign(const match_results<BidiIterator, Allocator>& m)
{
if(m_is_singular)
{
*this = m;
return;
}
const_iterator p1, p2;
p1 = begin();
p2 = m.begin();
//
// Distances are measured from the start of *this* match, unless this isn't
// a valid match in which case we use the start of the whole sequence. Note that
// no subsequent match-candidate can ever be to the left of the first match found.
// This ensures that when we are using bidirectional iterators, that distances
// measured are as short as possible, and therefore as efficient as possible
// to compute. Finally note that we don't use the "matched" data member to test
// whether a sub-expression is a valid match, because partial matches set this
// to false for sub-expression 0.
//
BidiIterator l_end = this->suffix().second;
BidiIterator l_base = (p1->first == l_end) ? this->prefix().first : (*this)[0].first;
difference_type len1 = 0;
difference_type len2 = 0;
difference_type base1 = 0;
difference_type base2 = 0;
std::size_t i;
for(i = 0; i < size(); ++i, ++p1, ++p2)
{
//
// Leftmost takes priority over longest; handle special cases
// where distances need not be computed first (an optimisation
// for bidirectional iterators: ensure that we don't accidently
// compute the length of the whole sequence, as this can be really
// expensive).
//
if(p1->first == l_end)
{
if(p2->first != l_end)
{
// p2 must be better than p1, and no need to calculate
// actual distances:
base1 = 1;
base2 = 0;
break;
}
else
{
// *p1 and *p2 are either unmatched or match end-of sequence,
// either way no need to calculate distances:
if((p1->matched == false) && (p2->matched == true))
break;
if((p1->matched == true) && (p2->matched == false))
return;
continue;
}
}
else if(p2->first == l_end)
{
// p1 better than p2, and no need to calculate distances:
return;
}
base1 = std::distance(l_base, p1->first);
base2 = std::distance(l_base, p2->first);
BOOST_REGEX_ASSERT(base1 >= 0);
BOOST_REGEX_ASSERT(base2 >= 0);
if(base1 < base2) return;
if(base2 < base1) break;
len1 = std::distance((BidiIterator)p1->first, (BidiIterator)p1->second);
len2 = std::distance((BidiIterator)p2->first, (BidiIterator)p2->second);
BOOST_REGEX_ASSERT(len1 >= 0);
BOOST_REGEX_ASSERT(len2 >= 0);
if((len1 != len2) || ((p1->matched == false) && (p2->matched == true)))
break;
if((p1->matched == true) && (p2->matched == false))
return;
}
if(i == size())
return;
if(base2 < base1)
*this = m;
else if((len2 > len1) || ((p1->matched == false) && (p2->matched == true)) )
*this = m;
}
template <class BidiIterator, class Allocator>
void swap(match_results<BidiIterator, Allocator>& a, match_results<BidiIterator, Allocator>& b)
{
a.swap(b);
}
template <class charT, class traits, class BidiIterator, class Allocator>
std::basic_ostream<charT, traits>&
operator << (std::basic_ostream<charT, traits>& os,
const match_results<BidiIterator, Allocator>& s)
{
return (os << s.str());
}
#ifdef BOOST_REGEX_MSVC
#pragma warning(pop)
#endif
} // namespace boost
#endif

View File

@@ -1,173 +0,0 @@
/*
* Copyright (c) 2002
* John Maddock
*
* Use, modification and distribution are subject to 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)
*
*/
/*
* LOCATION: see http://www.boost.org for most recent version.
* FILE mem_block_cache.hpp
* VERSION see <boost/version.hpp>
* DESCRIPTION: memory block cache used by the non-recursive matcher.
*/
#ifndef BOOST_REGEX_V5_MEM_BLOCK_CACHE_HPP
#define BOOST_REGEX_V5_MEM_BLOCK_CACHE_HPP
#include <new>
#ifdef BOOST_HAS_THREADS
#include <mutex>
#endif
#ifndef BOOST_NO_CXX11_HDR_ATOMIC
#include <atomic>
#if ATOMIC_POINTER_LOCK_FREE == 2
#define BOOST_REGEX_MEM_BLOCK_CACHE_LOCK_FREE
#define BOOST_REGEX_ATOMIC_POINTER std::atomic
#endif
#endif
namespace boost{
namespace BOOST_REGEX_DETAIL_NS{
#if BOOST_REGEX_MAX_CACHE_BLOCKS != 0
#ifdef BOOST_REGEX_MEM_BLOCK_CACHE_LOCK_FREE /* lock free implementation */
struct mem_block_cache
{
std::atomic<void*> cache[BOOST_REGEX_MAX_CACHE_BLOCKS];
~mem_block_cache()
{
for (size_t i = 0;i < BOOST_REGEX_MAX_CACHE_BLOCKS; ++i) {
if (cache[i].load()) ::operator delete(cache[i].load());
}
}
void* get()
{
for (size_t i = 0;i < BOOST_REGEX_MAX_CACHE_BLOCKS; ++i) {
void* p = cache[i].load();
if (p != NULL) {
if (cache[i].compare_exchange_strong(p, NULL)) return p;
}
}
return ::operator new(BOOST_REGEX_BLOCKSIZE);
}
void put(void* ptr)
{
for (size_t i = 0;i < BOOST_REGEX_MAX_CACHE_BLOCKS; ++i) {
void* p = cache[i].load();
if (p == NULL) {
if (cache[i].compare_exchange_strong(p, ptr)) return;
}
}
::operator delete(ptr);
}
static mem_block_cache& instance()
{
static mem_block_cache block_cache = { { {nullptr} } };
return block_cache;
}
};
#else /* lock-based implementation */
struct mem_block_node
{
mem_block_node* next;
};
struct mem_block_cache
{
// this member has to be statically initialsed:
mem_block_node* next { nullptr };
unsigned cached_blocks { 0 };
#ifdef BOOST_HAS_THREADS
std::mutex mut;
#endif
~mem_block_cache()
{
while(next)
{
mem_block_node* old = next;
next = next->next;
::operator delete(old);
}
}
void* get()
{
#ifdef BOOST_HAS_THREADS
std::lock_guard<std::mutex> g(mut);
#endif
if(next)
{
mem_block_node* result = next;
next = next->next;
--cached_blocks;
return result;
}
return ::operator new(BOOST_REGEX_BLOCKSIZE);
}
void put(void* p)
{
#ifdef BOOST_HAS_THREADS
std::lock_guard<std::mutex> g(mut);
#endif
if(cached_blocks >= BOOST_REGEX_MAX_CACHE_BLOCKS)
{
::operator delete(p);
}
else
{
mem_block_node* old = static_cast<mem_block_node*>(p);
old->next = next;
next = old;
++cached_blocks;
}
}
static mem_block_cache& instance()
{
static mem_block_cache block_cache;
return block_cache;
}
};
#endif
#endif
#if BOOST_REGEX_MAX_CACHE_BLOCKS == 0
inline void* get_mem_block()
{
return ::operator new(BOOST_REGEX_BLOCKSIZE);
}
inline void put_mem_block(void* p)
{
::operator delete(p);
}
#else
inline void* get_mem_block()
{
return mem_block_cache::instance().get();
}
inline void put_mem_block(void* p)
{
mem_block_cache::instance().put(p);
}
#endif
}
} // namespace boost
#endif

View File

@@ -1,160 +0,0 @@
/*
*
* Copyright (c) 2004
* John Maddock
*
* Use, modification and distribution are subject to 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)
*
*/
/*
* LOCATION: see http://www.boost.org for most recent version.
* FILE object_cache.hpp
* VERSION see <boost/version.hpp>
* DESCRIPTION: Implements a generic object cache.
*/
#ifndef BOOST_REGEX_OBJECT_CACHE_HPP
#define BOOST_REGEX_OBJECT_CACHE_HPP
#include <boost/regex/config.hpp>
#include <memory>
#include <map>
#include <list>
#include <stdexcept>
#include <string>
#ifdef BOOST_HAS_THREADS
#include <mutex>
#endif
namespace boost{
template <class Key, class Object>
class object_cache
{
public:
typedef std::pair< ::std::shared_ptr<Object const>, Key const*> value_type;
typedef std::list<value_type> list_type;
typedef typename list_type::iterator list_iterator;
typedef std::map<Key, list_iterator> map_type;
typedef typename map_type::iterator map_iterator;
typedef typename list_type::size_type size_type;
static std::shared_ptr<Object const> get(const Key& k, size_type l_max_cache_size);
private:
static std::shared_ptr<Object const> do_get(const Key& k, size_type l_max_cache_size);
struct data
{
list_type cont;
map_type index;
};
// Needed by compilers not implementing the resolution to DR45. For reference,
// see http://www.open-std.org/JTC1/SC22/WG21/docs/cwg_defects.html#45.
friend struct data;
};
#ifdef BOOST_REGEX_MSVC
#pragma warning(push)
#pragma warning(disable: 4702)
#endif
template <class Key, class Object>
std::shared_ptr<Object const> object_cache<Key, Object>::get(const Key& k, size_type l_max_cache_size)
{
#ifdef BOOST_HAS_THREADS
static std::mutex mut;
std::lock_guard<std::mutex> l(mut);
return do_get(k, l_max_cache_size);
#else
return do_get(k, l_max_cache_size);
#endif
}
#ifdef BOOST_REGEX_MSVC
#pragma warning(pop)
#endif
template <class Key, class Object>
std::shared_ptr<Object const> object_cache<Key, Object>::do_get(const Key& k, size_type l_max_cache_size)
{
typedef typename object_cache<Key, Object>::data object_data;
typedef typename map_type::size_type map_size_type;
static object_data s_data;
//
// see if the object is already in the cache:
//
map_iterator mpos = s_data.index.find(k);
if(mpos != s_data.index.end())
{
//
// Eureka!
// We have a cached item, bump it up the list and return it:
//
if(--(s_data.cont.end()) != mpos->second)
{
// splice out the item we want to move:
list_type temp;
temp.splice(temp.end(), s_data.cont, mpos->second);
// and now place it at the end of the list:
s_data.cont.splice(s_data.cont.end(), temp, temp.begin());
BOOST_REGEX_ASSERT(*(s_data.cont.back().second) == k);
// update index with new position:
mpos->second = --(s_data.cont.end());
BOOST_REGEX_ASSERT(&(mpos->first) == mpos->second->second);
BOOST_REGEX_ASSERT(&(mpos->first) == s_data.cont.back().second);
}
return s_data.cont.back().first;
}
//
// if we get here then the item is not in the cache,
// so create it:
//
std::shared_ptr<Object const> result(new Object(k));
//
// Add it to the list, and index it:
//
s_data.cont.push_back(value_type(result, static_cast<Key const*>(0)));
s_data.index.insert(std::make_pair(k, --(s_data.cont.end())));
s_data.cont.back().second = &(s_data.index.find(k)->first);
map_size_type s = s_data.index.size();
BOOST_REGEX_ASSERT(s_data.index[k]->first.get() == result.get());
BOOST_REGEX_ASSERT(&(s_data.index.find(k)->first) == s_data.cont.back().second);
BOOST_REGEX_ASSERT(s_data.index.find(k)->first == k);
if(s > l_max_cache_size)
{
//
// We have too many items in the list, so we need to start
// popping them off the back of the list, but only if they're
// being held uniquely by us:
//
list_iterator pos = s_data.cont.begin();
list_iterator last = s_data.cont.end();
while((pos != last) && (s > l_max_cache_size))
{
if(pos->first.use_count() == 1)
{
list_iterator condemmed(pos);
++pos;
// now remove the items from our containers,
// then order has to be as follows:
BOOST_REGEX_ASSERT(s_data.index.find(*(condemmed->second)) != s_data.index.end());
s_data.index.erase(*(condemmed->second));
s_data.cont.erase(condemmed);
--s;
}
else
++pos;
}
BOOST_REGEX_ASSERT(s_data.index[k]->first.get() == result.get());
BOOST_REGEX_ASSERT(&(s_data.index.find(k)->first) == s_data.cont.back().second);
BOOST_REGEX_ASSERT(s_data.index.find(k)->first == k);
}
return result;
}
}
#endif

View File

@@ -1,106 +0,0 @@
/*
*
* Copyright (c) 1998-2002
* John Maddock
*
* Use, modification and distribution are subject to 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)
*
*/
/*
* LOCATION: see http://www.boost.org for most recent version.
* FILE pattern_except.hpp
* VERSION see <boost/version.hpp>
* DESCRIPTION: Declares pattern-matching exception classes.
*/
#ifndef BOOST_RE_V5_PAT_EXCEPT_HPP
#define BOOST_RE_V5_PAT_EXCEPT_HPP
#ifndef BOOST_REGEX_CONFIG_HPP
#include <boost/regex/config.hpp>
#endif
#include <cstddef>
#include <stdexcept>
#include <boost/regex/v5/error_type.hpp>
#include <boost/regex/v5/regex_traits_defaults.hpp>
namespace boost{
#ifdef BOOST_REGEX_MSVC
#pragma warning(push)
#pragma warning(disable : 4275)
#if BOOST_REGEX_MSVC >= 1800
#pragma warning(disable : 26812 4459)
#endif
#endif
class regex_error : public std::runtime_error
{
public:
explicit regex_error(const std::string& s, regex_constants::error_type err = regex_constants::error_unknown, std::ptrdiff_t pos = 0)
: std::runtime_error(s)
, m_error_code(err)
, m_position(pos)
{
}
explicit regex_error(regex_constants::error_type err)
: std::runtime_error(::boost::BOOST_REGEX_DETAIL_NS::get_default_error_string(err))
, m_error_code(err)
, m_position(0)
{
}
~regex_error() noexcept override {}
regex_constants::error_type code()const
{ return m_error_code; }
std::ptrdiff_t position()const
{ return m_position; }
void raise()const
{
#ifndef BOOST_NO_EXCEPTIONS
#ifndef BOOST_REGEX_STANDALONE
::boost::throw_exception(*this);
#else
throw* this;
#endif
#endif
}
private:
regex_constants::error_type m_error_code;
std::ptrdiff_t m_position;
};
typedef regex_error bad_pattern;
typedef regex_error bad_expression;
namespace BOOST_REGEX_DETAIL_NS{
template <class E>
inline void raise_runtime_error(const E& ex)
{
#ifndef BOOST_REGEX_STANDALONE
::boost::throw_exception(ex);
#else
throw ex;
#endif
}
template <class traits>
void raise_error(const traits& t, regex_constants::error_type code)
{
(void)t; // warning suppression
regex_error e(t.error_string(code), code, 0);
::boost::BOOST_REGEX_DETAIL_NS::raise_runtime_error(e);
}
}
#ifdef BOOST_REGEX_MSVC
#pragma warning(pop)
#endif
} // namespace boost
#endif

View File

@@ -1,576 +0,0 @@
/*
*
* Copyright (c) 2002
* John Maddock
*
* Use, modification and distribution are subject to the
* Boost Software License, Version 1.0. (See accompanying file
* LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
*
*/
#ifndef BOOST_REGEX_MATCHER_HPP
#define BOOST_REGEX_MATCHER_HPP
#include <boost/regex/v5/iterator_category.hpp>
#ifdef BOOST_REGEX_MSVC
# pragma warning(push)
#pragma warning(disable : 4251 4459)
#if BOOST_REGEX_MSVC < 1700
# pragma warning(disable : 4231)
#endif
# if BOOST_REGEX_MSVC < 1600
# pragma warning(disable : 4660)
# endif
#if BOOST_REGEX_MSVC < 1910
#pragma warning(disable:4800)
#endif
#endif
namespace boost{
namespace BOOST_REGEX_DETAIL_NS{
//
// error checking API:
//
inline void verify_options(boost::regex_constants::syntax_option_type, match_flag_type mf)
{
//
// can't mix match_extra with POSIX matching rules:
//
if ((mf & match_extra) && (mf & match_posix))
{
std::logic_error msg("Usage Error: Can't mix regular expression captures with POSIX matching rules");
#ifndef BOOST_REGEX_STANDALONE
throw_exception(msg);
#else
throw msg;
#endif
}
}
//
// function can_start:
//
template <class charT>
inline bool can_start(charT c, const unsigned char* map, unsigned char mask)
{
return ((c < static_cast<charT>(0)) ? true : ((c >= static_cast<charT>(1 << CHAR_BIT)) ? true : map[c] & mask));
}
inline bool can_start(char c, const unsigned char* map, unsigned char mask)
{
return map[(unsigned char)c] & mask;
}
inline bool can_start(signed char c, const unsigned char* map, unsigned char mask)
{
return map[(unsigned char)c] & mask;
}
inline bool can_start(unsigned char c, const unsigned char* map, unsigned char mask)
{
return map[c] & mask;
}
inline bool can_start(unsigned short c, const unsigned char* map, unsigned char mask)
{
return ((c >= (1 << CHAR_BIT)) ? true : map[c] & mask);
}
#if defined(WCHAR_MIN) && (WCHAR_MIN == 0) && !defined(BOOST_NO_INTRINSIC_WCHAR_T)
inline bool can_start(wchar_t c, const unsigned char* map, unsigned char mask)
{
return ((c >= static_cast<wchar_t>(1u << CHAR_BIT)) ? true : map[c] & mask);
}
#endif
#if !defined(BOOST_NO_INTRINSIC_WCHAR_T)
inline bool can_start(unsigned int c, const unsigned char* map, unsigned char mask)
{
return (((c >= static_cast<unsigned int>(1u << CHAR_BIT)) ? true : map[c] & mask));
}
#endif
template <class C, class T, class A>
inline int string_compare(const std::basic_string<C,T,A>& s, const C* p)
{
if(0 == *p)
{
if(s.empty() || ((s.size() == 1) && (s[0] == 0)))
return 0;
}
return s.compare(p);
}
template <class Seq, class C>
inline int string_compare(const Seq& s, const C* p)
{
std::size_t i = 0;
while((i < s.size()) && (p[i] == s[i]))
{
++i;
}
return (i == s.size()) ? -(int)p[i] : (int)s[i] - (int)p[i];
}
# define STR_COMP(s,p) string_compare(s,p)
template<class charT>
inline const charT* re_skip_past_null(const charT* p)
{
while (*p != static_cast<charT>(0)) ++p;
return ++p;
}
template <class iterator, class charT, class traits_type, class char_classT>
iterator re_is_set_member(iterator next,
iterator last,
const re_set_long<char_classT>* set_,
const regex_data<charT, traits_type>& e, bool icase)
{
const charT* p = reinterpret_cast<const charT*>(set_+1);
iterator ptr;
unsigned int i;
//bool icase = e.m_flags & regex_constants::icase;
if(next == last) return next;
typedef typename traits_type::string_type traits_string_type;
const ::boost::regex_traits_wrapper<traits_type>& traits_inst = *(e.m_ptraits);
// dwa 9/13/00 suppress incorrect MSVC warning - it claims this is never
// referenced
(void)traits_inst;
// try and match a single character, could be a multi-character
// collating element...
for(i = 0; i < set_->csingles; ++i)
{
ptr = next;
if(*p == static_cast<charT>(0))
{
// treat null string as special case:
if(traits_inst.translate(*ptr, icase))
{
++p;
continue;
}
return set_->isnot ? next : (ptr == next) ? ++next : ptr;
}
else
{
while(*p && (ptr != last))
{
if(traits_inst.translate(*ptr, icase) != *p)
break;
++p;
++ptr;
}
if(*p == static_cast<charT>(0)) // if null we've matched
return set_->isnot ? next : (ptr == next) ? ++next : ptr;
p = re_skip_past_null(p); // skip null
}
}
charT col = traits_inst.translate(*next, icase);
if(set_->cranges || set_->cequivalents)
{
traits_string_type s1;
//
// try and match a range, NB only a single character can match
if(set_->cranges)
{
if((e.m_flags & regex_constants::collate) == 0)
s1.assign(1, col);
else
{
charT a[2] = { col, charT(0), };
s1 = traits_inst.transform(a, a + 1);
}
for(i = 0; i < set_->cranges; ++i)
{
if(STR_COMP(s1, p) >= 0)
{
do{ ++p; }while(*p);
++p;
if(STR_COMP(s1, p) <= 0)
return set_->isnot ? next : ++next;
}
else
{
// skip first string
do{ ++p; }while(*p);
++p;
}
// skip second string
do{ ++p; }while(*p);
++p;
}
}
//
// try and match an equivalence class, NB only a single character can match
if(set_->cequivalents)
{
charT a[2] = { col, charT(0), };
s1 = traits_inst.transform_primary(a, a +1);
for(i = 0; i < set_->cequivalents; ++i)
{
if(STR_COMP(s1, p) == 0)
return set_->isnot ? next : ++next;
// skip string
do{ ++p; }while(*p);
++p;
}
}
}
if(traits_inst.isctype(col, set_->cclasses) == true)
return set_->isnot ? next : ++next;
if((set_->cnclasses != 0) && (traits_inst.isctype(col, set_->cnclasses) == false))
return set_->isnot ? next : ++next;
return set_->isnot ? ++next : next;
}
template <class BidiIterator>
class repeater_count
{
repeater_count** stack;
repeater_count* next;
int state_id;
std::size_t count; // the number of iterations so far
BidiIterator start_pos; // where the last repeat started
repeater_count* unwind_until(int n, repeater_count* p, int current_recursion_id)
{
while(p && (p->state_id != n))
{
if(-2 - current_recursion_id == p->state_id)
return 0;
p = p->next;
if(p && (p->state_id < 0))
{
p = unwind_until(p->state_id, p, current_recursion_id);
if(!p)
return p;
p = p->next;
}
}
return p;
}
public:
repeater_count(repeater_count** s) : stack(s), next(0), state_id(-1), count(0), start_pos() {}
repeater_count(int i, repeater_count** s, BidiIterator start, int current_recursion_id)
: start_pos(start)
{
state_id = i;
stack = s;
next = *stack;
*stack = this;
if((state_id > next->state_id) && (next->state_id >= 0))
count = 0;
else
{
repeater_count* p = next;
p = unwind_until(state_id, p, current_recursion_id);
if(p)
{
count = p->count;
start_pos = p->start_pos;
}
else
count = 0;
}
}
~repeater_count()
{
if(next)
*stack = next;
}
std::size_t get_count() { return count; }
int get_id() { return state_id; }
std::size_t operator++() { return ++count; }
bool check_null_repeat(const BidiIterator& pos, std::size_t max)
{
// this is called when we are about to start a new repeat,
// if the last one was NULL move our count to max,
// otherwise save the current position.
bool result = (count == 0) ? false : (pos == start_pos);
if(result)
count = max;
else
start_pos = pos;
return result;
}
};
struct saved_state;
enum saved_state_type
{
saved_type_end = 0,
saved_type_paren = 1,
saved_type_recurse = 2,
saved_type_assertion = 3,
saved_state_alt = 4,
saved_state_repeater_count = 5,
saved_state_extra_block = 6,
saved_state_greedy_single_repeat = 7,
saved_state_rep_slow_dot = 8,
saved_state_rep_fast_dot = 9,
saved_state_rep_char = 10,
saved_state_rep_short_set = 11,
saved_state_rep_long_set = 12,
saved_state_non_greedy_long_repeat = 13,
saved_state_count = 14
};
#ifdef BOOST_REGEX_MSVC
# pragma warning(push)
#if BOOST_REGEX_MSVC >= 1800
#pragma warning(disable:26495)
#endif
#endif
template <class Results>
struct recursion_info
{
typedef typename Results::value_type value_type;
typedef typename value_type::iterator iterator;
int idx;
const re_syntax_base* preturn_address;
Results results;
repeater_count<iterator>* repeater_stack;
iterator location_of_start;
};
#ifdef BOOST_REGEX_MSVC
# pragma warning(pop)
#endif
template <class BidiIterator, class Allocator, class traits>
class perl_matcher
{
public:
typedef typename traits::char_type char_type;
typedef perl_matcher<BidiIterator, Allocator, traits> self_type;
typedef bool (self_type::*matcher_proc_type)();
typedef std::size_t traits_size_type;
typedef typename is_byte<char_type>::width_type width_type;
typedef typename std::iterator_traits<BidiIterator>::difference_type difference_type;
typedef match_results<BidiIterator, Allocator> results_type;
perl_matcher(BidiIterator first, BidiIterator end,
match_results<BidiIterator, Allocator>& what,
const basic_regex<char_type, traits>& e,
match_flag_type f,
BidiIterator l_base)
: m_result(what), base(first), last(end),
position(first), backstop(l_base), re(e), traits_inst(e.get_traits()),
m_independent(false), next_count(&rep_obj), rep_obj(&next_count)
, m_recursions(0)
{
construct_init(e, f);
}
bool match();
bool find();
void setf(match_flag_type f)
{ m_match_flags |= f; }
void unsetf(match_flag_type f)
{ m_match_flags &= ~f; }
private:
void construct_init(const basic_regex<char_type, traits>& e, match_flag_type f);
bool find_imp();
bool match_imp();
void estimate_max_state_count(std::random_access_iterator_tag*);
void estimate_max_state_count(void*);
bool match_prefix();
bool match_all_states();
// match procs, stored in s_match_vtable:
bool match_startmark();
bool match_endmark();
bool match_literal();
bool match_start_line();
bool match_end_line();
bool match_wild();
bool match_match();
bool match_word_boundary();
bool match_within_word();
bool match_word_start();
bool match_word_end();
bool match_buffer_start();
bool match_buffer_end();
bool match_backref();
bool match_long_set();
bool match_set();
bool match_jump();
bool match_alt();
bool match_rep();
bool match_combining();
bool match_soft_buffer_end();
bool match_restart_continue();
bool match_long_set_repeat();
bool match_set_repeat();
bool match_char_repeat();
bool match_dot_repeat_fast();
bool match_dot_repeat_slow();
bool match_dot_repeat_dispatch()
{
return ::boost::is_random_access_iterator<BidiIterator>::value ? match_dot_repeat_fast() : match_dot_repeat_slow();
}
bool match_backstep();
bool match_assert_backref();
bool match_toggle_case();
bool match_recursion();
bool match_fail();
bool match_accept();
bool match_commit();
bool match_then();
bool skip_until_paren(int index, bool match = true);
// find procs stored in s_find_vtable:
bool find_restart_any();
bool find_restart_word();
bool find_restart_line();
bool find_restart_buf();
bool find_restart_lit();
private:
// final result structure to be filled in:
match_results<BidiIterator, Allocator>& m_result;
// temporary result for POSIX matches:
std::unique_ptr<match_results<BidiIterator, Allocator> > m_temp_match;
// pointer to actual result structure to fill in:
match_results<BidiIterator, Allocator>* m_presult;
// start of sequence being searched:
BidiIterator base;
// end of sequence being searched:
BidiIterator last;
// current character being examined:
BidiIterator position;
// where to restart next search after failed match attempt:
BidiIterator restart;
// where the current search started from, acts as base for $` during grep:
BidiIterator search_base;
// how far we can go back when matching lookbehind:
BidiIterator backstop;
// the expression being examined:
const basic_regex<char_type, traits>& re;
// the expression's traits class:
const ::boost::regex_traits_wrapper<traits>& traits_inst;
// the next state in the machine being matched:
const re_syntax_base* pstate;
// matching flags in use:
match_flag_type m_match_flags;
// how many states we have examined so far:
std::ptrdiff_t state_count;
// max number of states to examine before giving up:
std::ptrdiff_t max_state_count;
// whether we should ignore case or not:
bool icase;
// set to true when (position == last), indicates that we may have a partial match:
bool m_has_partial_match;
// set to true whenever we get a match:
bool m_has_found_match;
// set to true whenever we're inside an independent sub-expression:
bool m_independent;
// the current repeat being examined:
repeater_count<BidiIterator>* next_count;
// the first repeat being examined (top of linked list):
repeater_count<BidiIterator> rep_obj;
// the mask to pass when matching word boundaries:
typename traits::char_class_type m_word_mask;
// the bitmask to use when determining whether a match_any matches a newline or not:
unsigned char match_any_mask;
// recursion information:
std::vector<recursion_info<results_type> > recursion_stack;
//
// additional members for non-recursive version:
//
typedef bool (self_type::*unwind_proc_type)(bool);
void extend_stack();
bool unwind(bool);
bool unwind_end(bool);
bool unwind_paren(bool);
bool unwind_recursion_stopper(bool);
bool unwind_assertion(bool);
bool unwind_alt(bool);
bool unwind_repeater_counter(bool);
bool unwind_extra_block(bool);
bool unwind_greedy_single_repeat(bool);
bool unwind_slow_dot_repeat(bool);
bool unwind_fast_dot_repeat(bool);
bool unwind_char_repeat(bool);
bool unwind_short_set_repeat(bool);
bool unwind_long_set_repeat(bool);
bool unwind_non_greedy_repeat(bool);
bool unwind_recursion(bool);
bool unwind_recursion_pop(bool);
bool unwind_commit(bool);
bool unwind_then(bool);
bool unwind_case(bool);
void destroy_single_repeat();
void push_matched_paren(int index, const sub_match<BidiIterator>& sub);
void push_recursion_stopper();
void push_assertion(const re_syntax_base* ps, bool positive);
void push_alt(const re_syntax_base* ps);
void push_repeater_count(int i, repeater_count<BidiIterator>** s);
void push_single_repeat(std::size_t c, const re_repeat* r, BidiIterator last_position, int state_id);
void push_non_greedy_repeat(const re_syntax_base* ps);
void push_recursion(int idx, const re_syntax_base* p, results_type* presults, results_type* presults2);
void push_recursion_pop();
void push_case_change(bool);
// pointer to base of stack:
saved_state* m_stack_base;
// pointer to current stack position:
saved_state* m_backup_state;
// how many memory blocks have we used up?:
unsigned used_block_count;
// determines what value to return when unwinding from recursion,
// allows for mixed recursive/non-recursive algorithm:
bool m_recursive_result;
// We have unwound to a lookahead/lookbehind, used by COMMIT/PRUNE/SKIP:
bool m_unwound_lookahead;
// We have unwound to an alternative, used by THEN:
bool m_unwound_alt;
// We are unwinding a commit - used by independent subs to determine whether to stop there or carry on unwinding:
//bool m_unwind_commit;
// Recursion limit:
unsigned m_recursions;
#ifdef BOOST_REGEX_MSVC
# pragma warning(push)
#if BOOST_REGEX_MSVC >= 1800
#pragma warning(disable:26495)
#endif
#endif
// these operations aren't allowed, so are declared private,
// bodies are provided to keep explicit-instantiation requests happy:
perl_matcher& operator=(const perl_matcher&)
{
return *this;
}
perl_matcher(const perl_matcher& that)
: m_result(that.m_result), re(that.re), traits_inst(that.traits_inst), rep_obj(0) {}
#ifdef BOOST_REGEX_MSVC
# pragma warning(pop)
#endif
};
} // namespace BOOST_REGEX_DETAIL_NS
#ifdef BOOST_REGEX_MSVC
# pragma warning(pop)
#endif
} // namespace boost
//
// include the implementation of perl_matcher:
//
#include <boost/regex/v5/perl_matcher_non_recursive.hpp>
// this one has to be last:
#include <boost/regex/v5/perl_matcher_common.hpp>
#endif

View File

@@ -1,921 +0,0 @@
/*
*
* Copyright (c) 2002
* John Maddock
*
* Use, modification and distribution are subject to 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)
*
*/
/*
* LOCATION: see http://www.boost.org for most recent version.
* FILE perl_matcher_common.cpp
* VERSION see <boost/version.hpp>
* DESCRIPTION: Definitions of perl_matcher member functions that are
* common to both the recursive and non-recursive versions.
*/
#ifndef BOOST_REGEX_V5_PERL_MATCHER_COMMON_HPP
#define BOOST_REGEX_V5_PERL_MATCHER_COMMON_HPP
#ifdef BOOST_REGEX_MSVC
# pragma warning(push)
#pragma warning(disable:4459)
#if BOOST_REGEX_MSVC < 1910
#pragma warning(disable:4800)
#endif
#endif
namespace boost{
namespace BOOST_REGEX_DETAIL_NS{
#ifdef BOOST_REGEX_MSVC
# pragma warning(push)
#pragma warning(disable:26812)
#endif
template <class BidiIterator, class Allocator, class traits>
void perl_matcher<BidiIterator, Allocator, traits>::construct_init(const basic_regex<char_type, traits>& e, match_flag_type f)
{
typedef typename std::iterator_traits<BidiIterator>::iterator_category category;
typedef typename basic_regex<char_type, traits>::flag_type expression_flag_type;
if(e.empty())
{
// precondition failure: e is not a valid regex.
std::invalid_argument ex("Invalid regular expression object");
#ifndef BOOST_REGEX_STANDALONE
boost::throw_exception(ex);
#else
throw e;
#endif
}
pstate = 0;
m_match_flags = f;
estimate_max_state_count(static_cast<category*>(0));
expression_flag_type re_f = re.flags();
icase = re_f & regex_constants::icase;
if(!(m_match_flags & (match_perl|match_posix)))
{
if((re_f & (regbase::main_option_type|regbase::no_perl_ex)) == 0)
m_match_flags |= match_perl;
else if((re_f & (regbase::main_option_type|regbase::emacs_ex)) == (regbase::basic_syntax_group|regbase::emacs_ex))
m_match_flags |= match_perl;
else if((re_f & (regbase::main_option_type|regbase::literal)) == (regbase::literal))
m_match_flags |= match_perl;
else
m_match_flags |= match_posix;
}
if(m_match_flags & match_posix)
{
m_temp_match.reset(new match_results<BidiIterator, Allocator>());
m_presult = m_temp_match.get();
}
else
m_presult = &m_result;
m_stack_base = 0;
m_backup_state = 0;
// find the value to use for matching word boundaries:
m_word_mask = re.get_data().m_word_mask;
// find bitmask to use for matching '.':
match_any_mask = static_cast<unsigned char>((f & match_not_dot_newline) ? BOOST_REGEX_DETAIL_NS::test_not_newline : BOOST_REGEX_DETAIL_NS::test_newline);
// Disable match_any if requested in the state machine:
if(e.get_data().m_disable_match_any)
m_match_flags &= regex_constants::match_not_any;
}
#ifdef BOOST_REGEX_MSVC
# pragma warning(pop)
#endif
template <class BidiIterator, class Allocator, class traits>
void perl_matcher<BidiIterator, Allocator, traits>::estimate_max_state_count(std::random_access_iterator_tag*)
{
//
// How many states should we allow our machine to visit before giving up?
// This is a heuristic: it takes the greater of O(N^2) and O(NS^2)
// where N is the length of the string, and S is the number of states
// in the machine. It's tempting to up this to O(N^2S) or even O(N^2S^2)
// but these take unreasonably amounts of time to bale out in pathological
// cases.
//
// Calculate NS^2 first:
//
static const std::ptrdiff_t k = 100000;
std::ptrdiff_t dist = std::distance(base, last);
if(dist == 0)
dist = 1;
std::ptrdiff_t states = re.size();
if(states == 0)
states = 1;
if ((std::numeric_limits<std::ptrdiff_t>::max)() / states < states)
{
max_state_count = (std::min)((std::ptrdiff_t)BOOST_REGEX_MAX_STATE_COUNT, (std::numeric_limits<std::ptrdiff_t>::max)() - 2);
return;
}
states *= states;
if((std::numeric_limits<std::ptrdiff_t>::max)() / dist < states)
{
max_state_count = (std::min)((std::ptrdiff_t)BOOST_REGEX_MAX_STATE_COUNT, (std::numeric_limits<std::ptrdiff_t>::max)() - 2);
return;
}
states *= dist;
if((std::numeric_limits<std::ptrdiff_t>::max)() - k < states)
{
max_state_count = (std::min)((std::ptrdiff_t)BOOST_REGEX_MAX_STATE_COUNT, (std::numeric_limits<std::ptrdiff_t>::max)() - 2);
return;
}
states += k;
max_state_count = states;
//
// Now calculate N^2:
//
states = dist;
if((std::numeric_limits<std::ptrdiff_t>::max)() / dist < states)
{
max_state_count = (std::min)((std::ptrdiff_t)BOOST_REGEX_MAX_STATE_COUNT, (std::numeric_limits<std::ptrdiff_t>::max)() - 2);
return;
}
states *= dist;
if((std::numeric_limits<std::ptrdiff_t>::max)() - k < states)
{
max_state_count = (std::min)((std::ptrdiff_t)BOOST_REGEX_MAX_STATE_COUNT, (std::numeric_limits<std::ptrdiff_t>::max)() - 2);
return;
}
states += k;
//
// N^2 can be a very large number indeed, to prevent things getting out
// of control, cap the max states:
//
if(states > BOOST_REGEX_MAX_STATE_COUNT)
states = BOOST_REGEX_MAX_STATE_COUNT;
//
// If (the possibly capped) N^2 is larger than our first estimate,
// use this instead:
//
if(states > max_state_count)
max_state_count = states;
}
template <class BidiIterator, class Allocator, class traits>
inline void perl_matcher<BidiIterator, Allocator, traits>::estimate_max_state_count(void*)
{
// we don't know how long the sequence is:
max_state_count = BOOST_REGEX_MAX_STATE_COUNT;
}
template <class BidiIterator, class Allocator, class traits>
inline bool perl_matcher<BidiIterator, Allocator, traits>::match()
{
return match_imp();
}
template <class BidiIterator, class Allocator, class traits>
bool perl_matcher<BidiIterator, Allocator, traits>::match_imp()
{
// initialise our stack if we are non-recursive:
save_state_init init(&m_stack_base, &m_backup_state);
used_block_count = BOOST_REGEX_MAX_BLOCKS;
#if !defined(BOOST_NO_EXCEPTIONS)
try{
#endif
// reset our state machine:
position = base;
search_base = base;
state_count = 0;
m_match_flags |= regex_constants::match_all;
m_presult->set_size((m_match_flags & match_nosubs) ? 1u : static_cast<typename results_type::size_type>(1u + re.mark_count()), search_base, last);
m_presult->set_base(base);
m_presult->set_named_subs(this->re.get_named_subs());
if(m_match_flags & match_posix)
m_result = *m_presult;
verify_options(re.flags(), m_match_flags);
if(0 == match_prefix())
return false;
return (m_result[0].second == last) && (m_result[0].first == base);
#if !defined(BOOST_NO_EXCEPTIONS)
}
catch(...)
{
// unwind all pushed states, apart from anything else this
// ensures that all the states are correctly destructed
// not just the memory freed.
while(unwind(true)){}
throw;
}
#endif
}
template <class BidiIterator, class Allocator, class traits>
inline bool perl_matcher<BidiIterator, Allocator, traits>::find()
{
return find_imp();
}
template <class BidiIterator, class Allocator, class traits>
bool perl_matcher<BidiIterator, Allocator, traits>::find_imp()
{
static matcher_proc_type const s_find_vtable[7] =
{
&perl_matcher<BidiIterator, Allocator, traits>::find_restart_any,
&perl_matcher<BidiIterator, Allocator, traits>::find_restart_word,
&perl_matcher<BidiIterator, Allocator, traits>::find_restart_line,
&perl_matcher<BidiIterator, Allocator, traits>::find_restart_buf,
&perl_matcher<BidiIterator, Allocator, traits>::match_prefix,
&perl_matcher<BidiIterator, Allocator, traits>::find_restart_lit,
&perl_matcher<BidiIterator, Allocator, traits>::find_restart_lit,
};
// initialise our stack if we are non-recursive:
save_state_init init(&m_stack_base, &m_backup_state);
used_block_count = BOOST_REGEX_MAX_BLOCKS;
#if !defined(BOOST_NO_EXCEPTIONS)
try{
#endif
state_count = 0;
if((m_match_flags & regex_constants::match_init) == 0)
{
// reset our state machine:
search_base = position = base;
pstate = re.get_first_state();
m_presult->set_size((m_match_flags & match_nosubs) ? 1u : static_cast<typename results_type::size_type>(1u + re.mark_count()), base, last);
m_presult->set_base(base);
m_presult->set_named_subs(this->re.get_named_subs());
m_match_flags |= regex_constants::match_init;
}
else
{
// start again:
search_base = position = m_result[0].second;
// If last match was null and match_not_null was not set then increment
// our start position, otherwise we go into an infinite loop:
if(((m_match_flags & match_not_null) == 0) && (m_result.length() == 0))
{
if(position == last)
return false;
else
++position;
}
// reset $` start:
m_presult->set_size((m_match_flags & match_nosubs) ? 1u : static_cast<typename results_type::size_type>(1u + re.mark_count()), search_base, last);
//if((base != search_base) && (base == backstop))
// m_match_flags |= match_prev_avail;
}
if(m_match_flags & match_posix)
{
m_result.set_size(static_cast<typename results_type::size_type>(1u + re.mark_count()), base, last);
m_result.set_base(base);
}
verify_options(re.flags(), m_match_flags);
// find out what kind of expression we have:
unsigned type = (m_match_flags & match_continuous) ?
static_cast<unsigned int>(regbase::restart_continue)
: static_cast<unsigned int>(re.get_restart_type());
// call the appropriate search routine:
matcher_proc_type proc = s_find_vtable[type];
return (this->*proc)();
#if !defined(BOOST_NO_EXCEPTIONS)
}
catch(...)
{
// unwind all pushed states, apart from anything else this
// ensures that all the states are correctly destructed
// not just the memory freed.
while(unwind(true)){}
throw;
}
#endif
}
template <class BidiIterator, class Allocator, class traits>
bool perl_matcher<BidiIterator, Allocator, traits>::match_prefix()
{
m_has_partial_match = false;
m_has_found_match = false;
pstate = re.get_first_state();
m_presult->set_first(position);
restart = position;
match_all_states();
if(!m_has_found_match && m_has_partial_match && (m_match_flags & match_partial))
{
m_has_found_match = true;
m_presult->set_second(last, 0, false);
position = last;
if((m_match_flags & match_posix) == match_posix)
{
m_result.maybe_assign(*m_presult);
}
}
#ifdef BOOST_REGEX_MATCH_EXTRA
if(m_has_found_match && (match_extra & m_match_flags))
{
//
// we have a match, reverse the capture information:
//
for(unsigned i = 0; i < m_presult->size(); ++i)
{
typename sub_match<BidiIterator>::capture_sequence_type & seq = ((*m_presult)[i]).get_captures();
std::reverse(seq.begin(), seq.end());
}
}
#endif
if(!m_has_found_match)
position = restart; // reset search postion
return m_has_found_match;
}
template <class BidiIterator, class Allocator, class traits>
bool perl_matcher<BidiIterator, Allocator, traits>::match_literal()
{
unsigned int len = static_cast<const re_literal*>(pstate)->length;
const char_type* what = reinterpret_cast<const char_type*>(static_cast<const re_literal*>(pstate) + 1);
//
// compare string with what we stored in
// our records:
for(unsigned int i = 0; i < len; ++i, ++position)
{
if((position == last) || (traits_inst.translate(*position, icase) != what[i]))
return false;
}
pstate = pstate->next.p;
return true;
}
template <class BidiIterator, class Allocator, class traits>
bool perl_matcher<BidiIterator, Allocator, traits>::match_start_line()
{
if(position == backstop)
{
if((m_match_flags & match_prev_avail) == 0)
{
if((m_match_flags & match_not_bol) == 0)
{
pstate = pstate->next.p;
return true;
}
return false;
}
}
else if(m_match_flags & match_single_line)
return false;
// check the previous value character:
BidiIterator t(position);
--t;
if(position != last)
{
if(is_separator(*t) && !((*t == static_cast<char_type>('\r')) && (*position == static_cast<char_type>('\n'))) )
{
pstate = pstate->next.p;
return true;
}
}
else if(is_separator(*t))
{
pstate = pstate->next.p;
return true;
}
return false;
}
template <class BidiIterator, class Allocator, class traits>
bool perl_matcher<BidiIterator, Allocator, traits>::match_end_line()
{
if(position != last)
{
if(m_match_flags & match_single_line)
return false;
// we're not yet at the end so *first is always valid:
if(is_separator(*position))
{
if((position != backstop) || (m_match_flags & match_prev_avail))
{
// check that we're not in the middle of \r\n sequence
BidiIterator t(position);
--t;
if((*t == static_cast<char_type>('\r')) && (*position == static_cast<char_type>('\n')))
{
return false;
}
}
pstate = pstate->next.p;
return true;
}
}
else if((m_match_flags & match_not_eol) == 0)
{
pstate = pstate->next.p;
return true;
}
return false;
}
template <class BidiIterator, class Allocator, class traits>
bool perl_matcher<BidiIterator, Allocator, traits>::match_wild()
{
if(position == last)
return false;
if(is_separator(*position) && ((match_any_mask & static_cast<const re_dot*>(pstate)->mask) == 0))
return false;
if((*position == char_type(0)) && (m_match_flags & match_not_dot_null))
return false;
pstate = pstate->next.p;
++position;
return true;
}
template <class BidiIterator, class Allocator, class traits>
bool perl_matcher<BidiIterator, Allocator, traits>::match_word_boundary()
{
bool b; // indcates whether next character is a word character
if(position != last)
{
// prev and this character must be opposites:
b = traits_inst.isctype(*position, m_word_mask);
}
else
{
if (m_match_flags & match_not_eow)
return false;
b = false;
}
if((position == backstop) && ((m_match_flags & match_prev_avail) == 0))
{
if(m_match_flags & match_not_bow)
return false;
else
b ^= false;
}
else
{
--position;
b ^= traits_inst.isctype(*position, m_word_mask);
++position;
}
if(b)
{
pstate = pstate->next.p;
return true;
}
return false; // no match if we get to here...
}
template <class BidiIterator, class Allocator, class traits>
bool perl_matcher<BidiIterator, Allocator, traits>::match_within_word()
{
bool b = !match_word_boundary();
if(b)
pstate = pstate->next.p;
return b;
/*
if(position == last)
return false;
// both prev and this character must be m_word_mask:
bool prev = traits_inst.isctype(*position, m_word_mask);
{
bool b;
if((position == backstop) && ((m_match_flags & match_prev_avail) == 0))
return false;
else
{
--position;
b = traits_inst.isctype(*position, m_word_mask);
++position;
}
if(b == prev)
{
pstate = pstate->next.p;
return true;
}
}
return false;
*/
}
template <class BidiIterator, class Allocator, class traits>
bool perl_matcher<BidiIterator, Allocator, traits>::match_word_start()
{
if(position == last)
return false; // can't be starting a word if we're already at the end of input
if(!traits_inst.isctype(*position, m_word_mask))
return false; // next character isn't a word character
if((position == backstop) && ((m_match_flags & match_prev_avail) == 0))
{
if(m_match_flags & match_not_bow)
return false; // no previous input
}
else
{
// otherwise inside buffer:
BidiIterator t(position);
--t;
if(traits_inst.isctype(*t, m_word_mask))
return false; // previous character not non-word
}
// OK we have a match:
pstate = pstate->next.p;
return true;
}
template <class BidiIterator, class Allocator, class traits>
bool perl_matcher<BidiIterator, Allocator, traits>::match_word_end()
{
if((position == backstop) && ((m_match_flags & match_prev_avail) == 0))
return false; // start of buffer can't be end of word
BidiIterator t(position);
--t;
if(traits_inst.isctype(*t, m_word_mask) == false)
return false; // previous character wasn't a word character
if(position == last)
{
if(m_match_flags & match_not_eow)
return false; // end of buffer but not end of word
}
else
{
// otherwise inside buffer:
if(traits_inst.isctype(*position, m_word_mask))
return false; // next character is a word character
}
pstate = pstate->next.p;
return true; // if we fall through to here then we've succeeded
}
template <class BidiIterator, class Allocator, class traits>
bool perl_matcher<BidiIterator, Allocator, traits>::match_buffer_start()
{
if((position != backstop) || (m_match_flags & match_not_bob))
return false;
// OK match:
pstate = pstate->next.p;
return true;
}
template <class BidiIterator, class Allocator, class traits>
bool perl_matcher<BidiIterator, Allocator, traits>::match_buffer_end()
{
if((position != last) || (m_match_flags & match_not_eob))
return false;
// OK match:
pstate = pstate->next.p;
return true;
}
template <class BidiIterator, class Allocator, class traits>
bool perl_matcher<BidiIterator, Allocator, traits>::match_backref()
{
//
// Compare with what we previously matched.
// Note that this succeeds if the backref did not partisipate
// in the match, this is in line with ECMAScript, but not Perl
// or PCRE.
//
int index = static_cast<const re_brace*>(pstate)->index;
if(index >= hash_value_mask)
{
named_subexpressions::range_type r = re.get_data().equal_range(index);
BOOST_REGEX_ASSERT(r.first != r.second);
do
{
index = r.first->index;
++r.first;
}while((r.first != r.second) && ((*m_presult)[index].matched != true));
}
if((m_match_flags & match_perl) && !(*m_presult)[index].matched)
return false;
BidiIterator i = (*m_presult)[index].first;
BidiIterator j = (*m_presult)[index].second;
while(i != j)
{
if((position == last) || (traits_inst.translate(*position, icase) != traits_inst.translate(*i, icase)))
return false;
++i;
++position;
}
pstate = pstate->next.p;
return true;
}
template <class BidiIterator, class Allocator, class traits>
bool perl_matcher<BidiIterator, Allocator, traits>::match_long_set()
{
typedef typename traits::char_class_type char_class_type;
// let the traits class do the work:
if(position == last)
return false;
BidiIterator t = re_is_set_member(position, last, static_cast<const re_set_long<char_class_type>*>(pstate), re.get_data(), icase);
if(t != position)
{
pstate = pstate->next.p;
position = t;
return true;
}
return false;
}
template <class BidiIterator, class Allocator, class traits>
bool perl_matcher<BidiIterator, Allocator, traits>::match_set()
{
if(position == last)
return false;
if(static_cast<const re_set*>(pstate)->_map[static_cast<unsigned char>(traits_inst.translate(*position, icase))])
{
pstate = pstate->next.p;
++position;
return true;
}
return false;
}
template <class BidiIterator, class Allocator, class traits>
bool perl_matcher<BidiIterator, Allocator, traits>::match_jump()
{
pstate = static_cast<const re_jump*>(pstate)->alt.p;
return true;
}
template <class BidiIterator, class Allocator, class traits>
bool perl_matcher<BidiIterator, Allocator, traits>::match_combining()
{
if(position == last)
return false;
if(is_combining(traits_inst.translate(*position, icase)))
return false;
++position;
while((position != last) && is_combining(traits_inst.translate(*position, icase)))
++position;
pstate = pstate->next.p;
return true;
}
template <class BidiIterator, class Allocator, class traits>
bool perl_matcher<BidiIterator, Allocator, traits>::match_soft_buffer_end()
{
if(m_match_flags & match_not_eob)
return false;
BidiIterator p(position);
while((p != last) && is_separator(traits_inst.translate(*p, icase)))++p;
if(p != last)
return false;
pstate = pstate->next.p;
return true;
}
template <class BidiIterator, class Allocator, class traits>
bool perl_matcher<BidiIterator, Allocator, traits>::match_restart_continue()
{
if(position == search_base)
{
pstate = pstate->next.p;
return true;
}
return false;
}
template <class BidiIterator, class Allocator, class traits>
bool perl_matcher<BidiIterator, Allocator, traits>::match_backstep()
{
#ifdef BOOST_REGEX_MSVC
#pragma warning(push)
#pragma warning(disable:4127)
#endif
if( ::boost::is_random_access_iterator<BidiIterator>::value)
{
std::ptrdiff_t maxlen = std::distance(backstop, position);
if(maxlen < static_cast<const re_brace*>(pstate)->index)
return false;
std::advance(position, -static_cast<const re_brace*>(pstate)->index);
}
else
{
int c = static_cast<const re_brace*>(pstate)->index;
while(c--)
{
if(position == backstop)
return false;
--position;
}
}
pstate = pstate->next.p;
return true;
#ifdef BOOST_REGEX_MSVC
#pragma warning(pop)
#endif
}
template <class BidiIterator, class Allocator, class traits>
inline bool perl_matcher<BidiIterator, Allocator, traits>::match_assert_backref()
{
// return true if marked sub-expression N has been matched:
int index = static_cast<const re_brace*>(pstate)->index;
bool result = false;
if(index == 9999)
{
// Magic value for a (DEFINE) block:
return false;
}
else if(index > 0)
{
// Have we matched subexpression "index"?
// Check if index is a hash value:
if(index >= hash_value_mask)
{
named_subexpressions::range_type r = re.get_data().equal_range(index);
while(r.first != r.second)
{
if((*m_presult)[r.first->index].matched)
{
result = true;
break;
}
++r.first;
}
}
else
{
result = (*m_presult)[index].matched;
}
pstate = pstate->next.p;
}
else
{
// Have we recursed into subexpression "index"?
// If index == 0 then check for any recursion at all, otherwise for recursion to -index-1.
int idx = -(index+1);
if(idx >= hash_value_mask)
{
named_subexpressions::range_type r = re.get_data().equal_range(idx);
int stack_index = recursion_stack.empty() ? -1 : recursion_stack.back().idx;
while(r.first != r.second)
{
result |= (stack_index == r.first->index);
if(result)break;
++r.first;
}
}
else
{
result = !recursion_stack.empty() && ((recursion_stack.back().idx == idx) || (index == 0));
}
pstate = pstate->next.p;
}
return result;
}
template <class BidiIterator, class Allocator, class traits>
bool perl_matcher<BidiIterator, Allocator, traits>::match_fail()
{
// Just force a backtrack:
return false;
}
template <class BidiIterator, class Allocator, class traits>
bool perl_matcher<BidiIterator, Allocator, traits>::match_accept()
{
if(!recursion_stack.empty())
{
return skip_until_paren(recursion_stack.back().idx);
}
else
{
return skip_until_paren(INT_MAX);
}
}
template <class BidiIterator, class Allocator, class traits>
bool perl_matcher<BidiIterator, Allocator, traits>::find_restart_any()
{
#ifdef BOOST_REGEX_MSVC
#pragma warning(push)
#pragma warning(disable:4127)
#endif
const unsigned char* _map = re.get_map();
while(true)
{
// skip everything we can't match:
while((position != last) && !can_start(*position, _map, (unsigned char)mask_any) )
++position;
if(position == last)
{
// run out of characters, try a null match if possible:
if(re.can_be_null())
return match_prefix();
break;
}
// now try and obtain a match:
if(match_prefix())
return true;
if(position == last)
return false;
++position;
}
return false;
#ifdef BOOST_REGEX_MSVC
#pragma warning(pop)
#endif
}
template <class BidiIterator, class Allocator, class traits>
bool perl_matcher<BidiIterator, Allocator, traits>::find_restart_word()
{
#ifdef BOOST_REGEX_MSVC
#pragma warning(push)
#pragma warning(disable:4127)
#endif
// do search optimised for word starts:
const unsigned char* _map = re.get_map();
if((m_match_flags & match_prev_avail) || (position != base))
--position;
else if(match_prefix())
return true;
do
{
while((position != last) && traits_inst.isctype(*position, m_word_mask))
++position;
while((position != last) && !traits_inst.isctype(*position, m_word_mask))
++position;
if(position == last)
break;
if(can_start(*position, _map, (unsigned char)mask_any) )
{
if(match_prefix())
return true;
}
if(position == last)
break;
} while(true);
return false;
#ifdef BOOST_REGEX_MSVC
#pragma warning(pop)
#endif
}
template <class BidiIterator, class Allocator, class traits>
bool perl_matcher<BidiIterator, Allocator, traits>::find_restart_line()
{
// do search optimised for line starts:
const unsigned char* _map = re.get_map();
if(match_prefix())
return true;
while(position != last)
{
while((position != last) && !is_separator(*position))
++position;
if(position == last)
return false;
++position;
if(position == last)
{
if(re.can_be_null() && match_prefix())
return true;
return false;
}
if( can_start(*position, _map, (unsigned char)mask_any) )
{
if(match_prefix())
return true;
}
if(position == last)
return false;
//++position;
}
return false;
}
template <class BidiIterator, class Allocator, class traits>
bool perl_matcher<BidiIterator, Allocator, traits>::find_restart_buf()
{
if((position == base) && ((m_match_flags & match_not_bob) == 0))
return match_prefix();
return false;
}
template <class BidiIterator, class Allocator, class traits>
bool perl_matcher<BidiIterator, Allocator, traits>::find_restart_lit()
{
return false;
}
} // namespace BOOST_REGEX_DETAIL_NS
} // namespace boost
#ifdef BOOST_REGEX_MSVC
# pragma warning(pop)
#endif
#endif

File diff suppressed because it is too large Load Diff

View File

@@ -1,120 +0,0 @@
/*
*
* Copyright (c) 1998-2002
* John Maddock
*
* Use, modification and distribution are subject to 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)
*
*/
/*
* LOCATION: see http://www.boost.org for most recent version.
* FILE: primary_transform.hpp
* VERSION: see <boost/version.hpp>
* DESCRIPTION: Heuristically determines the sort string format in use
* by the current locale.
*/
#ifndef BOOST_REGEX_PRIMARY_TRANSFORM
#define BOOST_REGEX_PRIMARY_TRANSFORM
namespace boost{
namespace BOOST_REGEX_DETAIL_NS{
enum{
sort_C,
sort_fixed,
sort_delim,
sort_unknown
};
template <class S, class charT>
unsigned count_chars(const S& s, charT c)
{
//
// Count how many occurrences of character c occur
// in string s: if c is a delimeter between collation
// fields, then this should be the same value for all
// sort keys:
//
unsigned int count = 0;
for(unsigned pos = 0; pos < s.size(); ++pos)
{
if(s[pos] == c) ++count;
}
return count;
}
template <class traits, class charT>
unsigned find_sort_syntax(const traits* pt, charT* delim)
{
//
// compare 'a' with 'A' to see how similar they are,
// should really use a-accute but we can't portably do that,
//
typedef typename traits::string_type string_type;
typedef typename traits::char_type char_type;
// Suppress incorrect warning for MSVC
(void)pt;
char_type a[2] = {'a', '\0', };
string_type sa(pt->transform(a, a+1));
if(sa == a)
{
*delim = 0;
return sort_C;
}
char_type A[2] = { 'A', '\0', };
string_type sA(pt->transform(A, A+1));
char_type c[2] = { ';', '\0', };
string_type sc(pt->transform(c, c+1));
int pos = 0;
while((pos <= static_cast<int>(sa.size())) && (pos <= static_cast<int>(sA.size())) && (sa[pos] == sA[pos])) ++pos;
--pos;
if(pos < 0)
{
*delim = 0;
return sort_unknown;
}
//
// at this point sa[pos] is either the end of a fixed width field
// or the character that acts as a delimiter:
//
charT maybe_delim = sa[pos];
if((pos != 0) && (count_chars(sa, maybe_delim) == count_chars(sA, maybe_delim)) && (count_chars(sa, maybe_delim) == count_chars(sc, maybe_delim)))
{
*delim = maybe_delim;
return sort_delim;
}
//
// OK doen't look like a delimiter, try for fixed width field:
//
if((sa.size() == sA.size()) && (sa.size() == sc.size()))
{
// note assumes that the fixed width field is less than
// (numeric_limits<charT>::max)(), should be true for all types
// I can't imagine 127 character fields...
*delim = static_cast<charT>(++pos);
return sort_fixed;
}
//
// don't know what it is:
//
*delim = 0;
return sort_unknown;
}
} // namespace BOOST_REGEX_DETAIL_NS
} // namespace boost
#endif

View File

@@ -1,158 +0,0 @@
/*
*
* Copyright (c) 1998-2002
* John Maddock
*
* Use, modification and distribution are subject to 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)
*
*/
/*
* LOCATION: see http://www.boost.org for most recent version.
* FILE regbase.cpp
* VERSION see <boost/version.hpp>
* DESCRIPTION: Declares class regbase.
*/
#ifndef BOOST_REGEX_V5_REGBASE_HPP
#define BOOST_REGEX_V5_REGBASE_HPP
namespace boost{
//
// class regbase
// handles error codes and flags
//
class regbase
{
public:
enum flag_type_
{
//
// Divide the flags up into logical groups:
// bits 0-7 indicate main synatx type.
// bits 8-15 indicate syntax subtype.
// bits 16-31 indicate options that are common to all
// regex syntaxes.
// In all cases the default is 0.
//
// Main synatx group:
//
perl_syntax_group = 0, // default
basic_syntax_group = 1, // POSIX basic
literal = 2, // all characters are literals
main_option_type = literal | basic_syntax_group | perl_syntax_group, // everything!
//
// options specific to perl group:
//
no_bk_refs = 1 << 8, // \d not allowed
no_perl_ex = 1 << 9, // disable perl extensions
no_mod_m = 1 << 10, // disable Perl m modifier
mod_x = 1 << 11, // Perl x modifier
mod_s = 1 << 12, // force s modifier on (overrides match_not_dot_newline)
no_mod_s = 1 << 13, // force s modifier off (overrides match_not_dot_newline)
//
// options specific to basic group:
//
no_char_classes = 1 << 8, // [[:CLASS:]] not allowed
no_intervals = 1 << 9, // {x,y} not allowed
bk_plus_qm = 1 << 10, // uses \+ and \?
bk_vbar = 1 << 11, // use \| for alternatives
emacs_ex = 1 << 12, // enables emacs extensions
//
// options common to all groups:
//
no_escape_in_lists = 1 << 16, // '\' not special inside [...]
newline_alt = 1 << 17, // \n is the same as |
no_except = 1 << 18, // no exception on error
failbit = 1 << 19, // error flag
icase = 1 << 20, // characters are matched regardless of case
nocollate = 0, // don't use locale specific collation (deprecated)
collate = 1 << 21, // use locale specific collation
nosubs = 1 << 22, // don't mark sub-expressions
save_subexpression_location = 1 << 23, // save subexpression locations
no_empty_expressions = 1 << 24, // no empty expressions allowed
optimize = 0, // not really supported
basic = basic_syntax_group | collate | no_escape_in_lists,
extended = no_bk_refs | collate | no_perl_ex | no_escape_in_lists,
normal = 0,
emacs = basic_syntax_group | collate | emacs_ex | bk_vbar,
awk = no_bk_refs | collate | no_perl_ex,
grep = basic | newline_alt,
egrep = extended | newline_alt,
sed = basic,
perl = normal,
ECMAScript = normal,
JavaScript = normal,
JScript = normal
};
typedef unsigned int flag_type;
enum restart_info
{
restart_any = 0,
restart_word = 1,
restart_line = 2,
restart_buf = 3,
restart_continue = 4,
restart_lit = 5,
restart_fixed_lit = 6,
restart_count = 7
};
};
//
// provide std lib proposal compatible constants:
//
namespace regex_constants{
enum flag_type_
{
no_except = ::boost::regbase::no_except,
failbit = ::boost::regbase::failbit,
literal = ::boost::regbase::literal,
icase = ::boost::regbase::icase,
nocollate = ::boost::regbase::nocollate,
collate = ::boost::regbase::collate,
nosubs = ::boost::regbase::nosubs,
optimize = ::boost::regbase::optimize,
bk_plus_qm = ::boost::regbase::bk_plus_qm,
bk_vbar = ::boost::regbase::bk_vbar,
no_intervals = ::boost::regbase::no_intervals,
no_char_classes = ::boost::regbase::no_char_classes,
no_escape_in_lists = ::boost::regbase::no_escape_in_lists,
no_mod_m = ::boost::regbase::no_mod_m,
mod_x = ::boost::regbase::mod_x,
mod_s = ::boost::regbase::mod_s,
no_mod_s = ::boost::regbase::no_mod_s,
save_subexpression_location = ::boost::regbase::save_subexpression_location,
no_empty_expressions = ::boost::regbase::no_empty_expressions,
basic = ::boost::regbase::basic,
extended = ::boost::regbase::extended,
normal = ::boost::regbase::normal,
emacs = ::boost::regbase::emacs,
awk = ::boost::regbase::awk,
grep = ::boost::regbase::grep,
egrep = ::boost::regbase::egrep,
sed = basic,
perl = normal,
ECMAScript = normal,
JavaScript = normal,
JScript = normal
};
typedef ::boost::regbase::flag_type syntax_option_type;
} // namespace regex_constants
} // namespace boost
#endif

View File

@@ -1,106 +0,0 @@
/*
*
* Copyright (c) 1998-2002
* John Maddock
*
* Use, modification and distribution are subject to 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)
*
*/
/*
* LOCATION: see http://www.boost.org for most recent version.
* FILE regex.cpp
* VERSION see <boost/version.hpp>
* DESCRIPTION: Declares boost::basic_regex<> and associated
* functions and classes. This header is the main
* entry point for the template regex code.
*/
#ifndef BOOST_RE_REGEX_HPP_INCLUDED
#define BOOST_RE_REGEX_HPP_INCLUDED
#ifdef __cplusplus
// what follows is all C++ don't include in C builds!!
#include <boost/regex/config.hpp>
#include <boost/regex/v5/regex_workaround.hpp>
#include <boost/regex_fwd.hpp>
#include <boost/regex/regex_traits.hpp>
#include <boost/regex/v5/error_type.hpp>
#include <boost/regex/v5/match_flags.hpp>
#include <boost/regex/v5/regex_raw_buffer.hpp>
#include <boost/regex/pattern_except.hpp>
#include <boost/regex/v5/char_regex_traits.hpp>
#include <boost/regex/v5/states.hpp>
#include <boost/regex/v5/regbase.hpp>
#include <boost/regex/v5/basic_regex.hpp>
#include <boost/regex/v5/basic_regex_creator.hpp>
#include <boost/regex/v5/basic_regex_parser.hpp>
#include <boost/regex/v5/sub_match.hpp>
#include <boost/regex/v5/regex_format.hpp>
#include <boost/regex/v5/match_results.hpp>
#include <boost/regex/v5/perl_matcher.hpp>
namespace boost{
#ifdef BOOST_REGEX_NO_FWD
typedef basic_regex<char, regex_traits<char> > regex;
#ifndef BOOST_NO_WREGEX
typedef basic_regex<wchar_t, regex_traits<wchar_t> > wregex;
#endif
#endif
typedef match_results<const char*> cmatch;
typedef match_results<std::string::const_iterator> smatch;
#ifndef BOOST_NO_WREGEX
typedef match_results<const wchar_t*> wcmatch;
typedef match_results<std::wstring::const_iterator> wsmatch;
#endif
} // namespace boost
#include <boost/regex/v5/regex_match.hpp>
#include <boost/regex/v5/regex_search.hpp>
#include <boost/regex/v5/regex_iterator.hpp>
#include <boost/regex/v5/regex_token_iterator.hpp>
#include <boost/regex/v5/regex_grep.hpp>
#include <boost/regex/v5/regex_replace.hpp>
#include <boost/regex/v5/regex_merge.hpp>
#include <boost/regex/v5/regex_split.hpp>
#endif // __cplusplus
#endif // include

File diff suppressed because it is too large Load Diff

View File

@@ -1,73 +0,0 @@
/*
*
* Copyright (c) 1998-2002
* John Maddock
*
* Use, modification and distribution are subject to 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)
*
*/
/*
* LOCATION: see http://www.boost.org for most recent version.
* FILE regex_fwd.cpp
* VERSION see <boost/version.hpp>
* DESCRIPTION: Forward declares boost::basic_regex<> and
* associated typedefs.
*/
#ifndef BOOST_REGEX_FWD_HPP_INCLUDED
#define BOOST_REGEX_FWD_HPP_INCLUDED
#ifndef BOOST_REGEX_CONFIG_HPP
#include <boost/regex/config.hpp>
#endif
//
// define BOOST_REGEX_NO_FWD if this
// header doesn't work!
//
#ifdef BOOST_REGEX_NO_FWD
# ifndef BOOST_RE_REGEX_HPP
# include <boost/regex.hpp>
# endif
#else
namespace boost{
template <class charT>
class cpp_regex_traits;
template <class charT>
struct c_regex_traits;
template <class charT>
class w32_regex_traits;
#ifdef BOOST_REGEX_USE_WIN32_LOCALE
template <class charT, class implementationT = w32_regex_traits<charT> >
struct regex_traits;
#elif defined(BOOST_REGEX_USE_CPP_LOCALE)
template <class charT, class implementationT = cpp_regex_traits<charT> >
struct regex_traits;
#else
template <class charT, class implementationT = c_regex_traits<charT> >
struct regex_traits;
#endif
template <class charT, class traits = regex_traits<charT> >
class basic_regex;
typedef basic_regex<char, regex_traits<char> > regex;
#ifndef BOOST_NO_WREGEX
typedef basic_regex<wchar_t, regex_traits<wchar_t> > wregex;
#endif
} // namespace boost
#endif // BOOST_REGEX_NO_FWD
#endif

View File

@@ -1,98 +0,0 @@
/*
*
* Copyright (c) 1998-2002
* John Maddock
*
* Use, modification and distribution are subject to 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)
*
*/
/*
* LOCATION: see http://www.boost.org for most recent version.
* FILE regex_grep.hpp
* VERSION see <boost/version.hpp>
* DESCRIPTION: Provides regex_grep implementation.
*/
#ifndef BOOST_REGEX_V5_REGEX_GREP_HPP
#define BOOST_REGEX_V5_REGEX_GREP_HPP
namespace boost{
//
// regex_grep:
// find all non-overlapping matches within the sequence first last:
//
template <class Predicate, class BidiIterator, class charT, class traits>
inline unsigned int regex_grep(Predicate foo,
BidiIterator first,
BidiIterator last,
const basic_regex<charT, traits>& e,
match_flag_type flags = match_default)
{
if(e.flags() & regex_constants::failbit)
return false;
typedef typename match_results<BidiIterator>::allocator_type match_allocator_type;
match_results<BidiIterator> m;
BOOST_REGEX_DETAIL_NS::perl_matcher<BidiIterator, match_allocator_type, traits> matcher(first, last, m, e, flags, first);
unsigned int count = 0;
while(matcher.find())
{
++count;
if(0 == foo(m))
return count; // caller doesn't want to go on
if(m[0].second == last)
return count; // we've reached the end, don't try and find an extra null match.
if(m.length() == 0)
{
if(m[0].second == last)
return count;
// we found a NULL-match, now try to find
// a non-NULL one at the same position:
match_results<BidiIterator, match_allocator_type> m2(m);
matcher.setf(match_not_null | match_continuous);
if(matcher.find())
{
++count;
if(0 == foo(m))
return count;
}
else
{
// reset match back to where it was:
m = m2;
}
matcher.unsetf((match_not_null | match_continuous) & ~flags);
}
}
return count;
}
//
// regex_grep convenience interfaces:
//
template <class Predicate, class charT, class traits>
inline unsigned int regex_grep(Predicate foo, const charT* str,
const basic_regex<charT, traits>& e,
match_flag_type flags = match_default)
{
return regex_grep(foo, str, str + traits::length(str), e, flags);
}
template <class Predicate, class ST, class SA, class charT, class traits>
inline unsigned int regex_grep(Predicate foo, const std::basic_string<charT, ST, SA>& s,
const basic_regex<charT, traits>& e,
match_flag_type flags = match_default)
{
return regex_grep(foo, s.begin(), s.end(), e, flags);
}
} // namespace boost
#endif // BOOST_REGEX_V5_REGEX_GREP_HPP

View File

@@ -1,173 +0,0 @@
/*
*
* Copyright (c) 2003
* John Maddock
*
* Use, modification and distribution are subject to 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)
*
*/
/*
* LOCATION: see http://www.boost.org for most recent version.
* FILE regex_iterator.hpp
* VERSION see <boost/version.hpp>
* DESCRIPTION: Provides regex_iterator implementation.
*/
#ifndef BOOST_REGEX_V5_REGEX_ITERATOR_HPP
#define BOOST_REGEX_V5_REGEX_ITERATOR_HPP
#include <memory>
namespace boost{
template <class BidirectionalIterator,
class charT,
class traits>
class regex_iterator_implementation
{
typedef basic_regex<charT, traits> regex_type;
match_results<BidirectionalIterator> what; // current match
BidirectionalIterator base; // start of sequence
BidirectionalIterator end; // end of sequence
const regex_type re; // the expression
match_flag_type flags; // flags for matching
public:
regex_iterator_implementation(const regex_type* p, BidirectionalIterator last, match_flag_type f)
: base(), end(last), re(*p), flags(f){}
regex_iterator_implementation(const regex_iterator_implementation& other)
:what(other.what), base(other.base), end(other.end), re(other.re), flags(other.flags){}
bool init(BidirectionalIterator first)
{
base = first;
return regex_search(first, end, what, re, flags);
}
bool compare(const regex_iterator_implementation& that)
{
if(this == &that) return true;
return (&re.get_data() == &that.re.get_data()) && (end == that.end) && (flags == that.flags) && (what[0].first == that.what[0].first) && (what[0].second == that.what[0].second);
}
const match_results<BidirectionalIterator>& get()
{ return what; }
bool next()
{
//if(what.prefix().first != what[0].second)
// flags |= match_prev_avail;
BidirectionalIterator next_start = what[0].second;
match_flag_type f(flags);
if(!what.length() || (f & regex_constants::match_posix))
f |= regex_constants::match_not_initial_null;
//if(base != next_start)
// f |= regex_constants::match_not_bob;
bool result = regex_search(next_start, end, what, re, f, base);
if(result)
what.set_base(base);
return result;
}
private:
regex_iterator_implementation& operator=(const regex_iterator_implementation&);
};
template <class BidirectionalIterator,
class charT = typename std::iterator_traits<BidirectionalIterator>::value_type,
class traits = regex_traits<charT> >
class regex_iterator
{
private:
typedef regex_iterator_implementation<BidirectionalIterator, charT, traits> impl;
typedef std::shared_ptr<impl> pimpl;
public:
typedef basic_regex<charT, traits> regex_type;
typedef match_results<BidirectionalIterator> value_type;
typedef typename std::iterator_traits<BidirectionalIterator>::difference_type
difference_type;
typedef const value_type* pointer;
typedef const value_type& reference;
typedef std::forward_iterator_tag iterator_category;
regex_iterator(){}
regex_iterator(BidirectionalIterator a, BidirectionalIterator b,
const regex_type& re,
match_flag_type m = match_default)
: pdata(new impl(&re, b, m))
{
if(!pdata->init(a))
{
pdata.reset();
}
}
regex_iterator(const regex_iterator& that)
: pdata(that.pdata) {}
regex_iterator& operator=(const regex_iterator& that)
{
pdata = that.pdata;
return *this;
}
bool operator==(const regex_iterator& that)const
{
if((pdata.get() == 0) || (that.pdata.get() == 0))
return pdata.get() == that.pdata.get();
return pdata->compare(*(that.pdata.get()));
}
bool operator!=(const regex_iterator& that)const
{ return !(*this == that); }
const value_type& operator*()const
{ return pdata->get(); }
const value_type* operator->()const
{ return &(pdata->get()); }
regex_iterator& operator++()
{
cow();
if(0 == pdata->next())
{
pdata.reset();
}
return *this;
}
regex_iterator operator++(int)
{
regex_iterator result(*this);
++(*this);
return result;
}
private:
pimpl pdata;
void cow()
{
// copy-on-write
if(pdata.get() && (pdata.use_count() > 1))
{
pdata.reset(new impl(*(pdata.get())));
}
}
};
typedef regex_iterator<const char*> cregex_iterator;
typedef regex_iterator<std::string::const_iterator> sregex_iterator;
#ifndef BOOST_NO_WREGEX
typedef regex_iterator<const wchar_t*> wcregex_iterator;
typedef regex_iterator<std::wstring::const_iterator> wsregex_iterator;
#endif
// make_regex_iterator:
template <class charT, class traits>
inline regex_iterator<const charT*, charT, traits> make_regex_iterator(const charT* p, const basic_regex<charT, traits>& e, regex_constants::match_flag_type m = regex_constants::match_default)
{
return regex_iterator<const charT*, charT, traits>(p, p+traits::length(p), e, m);
}
template <class charT, class traits, class ST, class SA>
inline regex_iterator<typename std::basic_string<charT, ST, SA>::const_iterator, charT, traits> make_regex_iterator(const std::basic_string<charT, ST, SA>& p, const basic_regex<charT, traits>& e, regex_constants::match_flag_type m = regex_constants::match_default)
{
return regex_iterator<typename std::basic_string<charT, ST, SA>::const_iterator, charT, traits>(p.begin(), p.end(), e, m);
}
} // namespace boost
#endif // BOOST_REGEX_V5_REGEX_ITERATOR_HPP

View File

@@ -1,92 +0,0 @@
/*
*
* Copyright (c) 1998-2002
* John Maddock
*
* Use, modification and distribution are subject to 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)
*
*/
/*
* LOCATION: see http://www.boost.org for most recent version.
* FILE regex_match.hpp
* VERSION see <boost/version.hpp>
* DESCRIPTION: Regular expression matching algorithms.
* Note this is an internal header file included
* by regex.hpp, do not include on its own.
*/
#ifndef BOOST_REGEX_MATCH_HPP
#define BOOST_REGEX_MATCH_HPP
namespace boost{
//
// proc regex_match
// returns true if the specified regular expression matches
// the whole of the input. Fills in what matched in m.
//
template <class BidiIterator, class Allocator, class charT, class traits>
bool regex_match(BidiIterator first, BidiIterator last,
match_results<BidiIterator, Allocator>& m,
const basic_regex<charT, traits>& e,
match_flag_type flags = match_default)
{
BOOST_REGEX_DETAIL_NS::perl_matcher<BidiIterator, Allocator, traits> matcher(first, last, m, e, flags, first);
return matcher.match();
}
template <class iterator, class charT, class traits>
bool regex_match(iterator first, iterator last,
const basic_regex<charT, traits>& e,
match_flag_type flags = match_default)
{
match_results<iterator> m;
return regex_match(first, last, m, e, flags | regex_constants::match_any);
}
//
// query_match convenience interfaces:
//
template <class charT, class Allocator, class traits>
inline bool regex_match(const charT* str,
match_results<const charT*, Allocator>& m,
const basic_regex<charT, traits>& e,
match_flag_type flags = match_default)
{
return regex_match(str, str + traits::length(str), m, e, flags);
}
template <class ST, class SA, class Allocator, class charT, class traits>
inline bool regex_match(const std::basic_string<charT, ST, SA>& s,
match_results<typename std::basic_string<charT, ST, SA>::const_iterator, Allocator>& m,
const basic_regex<charT, traits>& e,
match_flag_type flags = match_default)
{
return regex_match(s.begin(), s.end(), m, e, flags);
}
template <class charT, class traits>
inline bool regex_match(const charT* str,
const basic_regex<charT, traits>& e,
match_flag_type flags = match_default)
{
match_results<const charT*> m;
return regex_match(str, str + traits::length(str), m, e, flags | regex_constants::match_any);
}
template <class ST, class SA, class charT, class traits>
inline bool regex_match(const std::basic_string<charT, ST, SA>& s,
const basic_regex<charT, traits>& e,
match_flag_type flags = match_default)
{
typedef typename std::basic_string<charT, ST, SA>::const_iterator iterator;
match_results<iterator> m;
return regex_match(s.begin(), s.end(), m, e, flags | regex_constants::match_any);
}
} // namespace boost
#endif // BOOST_REGEX_MATCH_HPP

View File

@@ -1,71 +0,0 @@
/*
*
* Copyright (c) 1998-2002
* John Maddock
*
* Use, modification and distribution are subject to 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)
*
*/
/*
* LOCATION: see http://www.boost.org for most recent version.
* FILE regex_format.hpp
* VERSION see <boost/version.hpp>
* DESCRIPTION: Provides formatting output routines for search and replace
* operations. Note this is an internal header file included
* by regex.hpp, do not include on its own.
*/
#ifndef BOOST_REGEX_V5_REGEX_MERGE_HPP
#define BOOST_REGEX_V5_REGEX_MERGE_HPP
namespace boost{
template <class OutputIterator, class Iterator, class traits, class charT>
inline OutputIterator regex_merge(OutputIterator out,
Iterator first,
Iterator last,
const basic_regex<charT, traits>& e,
const charT* fmt,
match_flag_type flags = match_default)
{
return regex_replace(out, first, last, e, fmt, flags);
}
template <class OutputIterator, class Iterator, class traits, class charT>
inline OutputIterator regex_merge(OutputIterator out,
Iterator first,
Iterator last,
const basic_regex<charT, traits>& e,
const std::basic_string<charT>& fmt,
match_flag_type flags = match_default)
{
return regex_merge(out, first, last, e, fmt.c_str(), flags);
}
template <class traits, class charT>
inline std::basic_string<charT> regex_merge(const std::basic_string<charT>& s,
const basic_regex<charT, traits>& e,
const charT* fmt,
match_flag_type flags = match_default)
{
return regex_replace(s, e, fmt, flags);
}
template <class traits, class charT>
inline std::basic_string<charT> regex_merge(const std::basic_string<charT>& s,
const basic_regex<charT, traits>& e,
const std::basic_string<charT>& fmt,
match_flag_type flags = match_default)
{
return regex_replace(s, e, fmt, flags);
}
} // namespace boost
#endif // BOOST_REGEX_V5_REGEX_MERGE_HPP

View File

@@ -1,213 +0,0 @@
/*
*
* Copyright (c) 1998-2002
* John Maddock
*
* Use, modification and distribution are subject to 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)
*
*/
/*
* LOCATION: see http://www.boost.org for most recent version.
* FILE regex_raw_buffer.hpp
* VERSION see <boost/version.hpp>
* DESCRIPTION: Raw character buffer for regex code.
* Note this is an internal header file included
* by regex.hpp, do not include on its own.
*/
#ifndef BOOST_REGEX_RAW_BUFFER_HPP
#define BOOST_REGEX_RAW_BUFFER_HPP
#ifndef BOOST_REGEX_CONFIG_HPP
#include <boost/regex/config.hpp>
#endif
#include <algorithm>
#include <cstddef>
namespace boost{
namespace BOOST_REGEX_DETAIL_NS{
struct empty_padding{};
union padding
{
void* p;
unsigned int i;
};
template <int N>
struct padding3
{
enum{
padding_size = 8,
padding_mask = 7
};
};
template<>
struct padding3<2>
{
enum{
padding_size = 2,
padding_mask = 1
};
};
template<>
struct padding3<4>
{
enum{
padding_size = 4,
padding_mask = 3
};
};
template<>
struct padding3<8>
{
enum{
padding_size = 8,
padding_mask = 7
};
};
template<>
struct padding3<16>
{
enum{
padding_size = 16,
padding_mask = 15
};
};
enum{
padding_size = padding3<sizeof(padding)>::padding_size,
padding_mask = padding3<sizeof(padding)>::padding_mask
};
//
// class raw_storage
// basically this is a simplified vector<unsigned char>
// this is used by basic_regex for expression storage
//
class raw_storage
{
public:
typedef std::size_t size_type;
typedef unsigned char* pointer;
private:
pointer last, start, end;
public:
raw_storage();
raw_storage(size_type n);
~raw_storage()
{
::operator delete(start);
}
void resize(size_type n)
{
size_type newsize = start ? last - start : 1024;
while (newsize < n)
newsize *= 2;
size_type datasize = end - start;
// extend newsize to WORD/DWORD boundary:
newsize = (newsize + padding_mask) & ~(padding_mask);
// allocate and copy data:
pointer ptr = static_cast<pointer>(::operator new(newsize));
BOOST_REGEX_NOEH_ASSERT(ptr)
if (start)
std::memcpy(ptr, start, datasize);
// get rid of old buffer:
::operator delete(start);
// and set up pointers:
start = ptr;
end = ptr + datasize;
last = ptr + newsize;
}
void* extend(size_type n)
{
if(size_type(last - end) < n)
resize(n + (end - start));
pointer result = end;
end += n;
return result;
}
void* insert(size_type pos, size_type n)
{
BOOST_REGEX_ASSERT(pos <= size_type(end - start));
if (size_type(last - end) < n)
resize(n + (end - start));
void* result = start + pos;
std::memmove(start + pos + n, start + pos, (end - start) - pos);
end += n;
return result;
}
size_type size()
{
return size_type(end - start);
}
size_type capacity()
{
return size_type(last - start);
}
void* data()const
{
return start;
}
size_type index(void* ptr)
{
return size_type(static_cast<pointer>(ptr) - static_cast<pointer>(data()));
}
void clear()
{
end = start;
}
void align()
{
// move end up to a boundary:
end = start + (((end - start) + padding_mask) & ~padding_mask);
}
void swap(raw_storage& that)
{
std::swap(start, that.start);
std::swap(end, that.end);
std::swap(last, that.last);
}
};
inline raw_storage::raw_storage()
{
last = start = end = 0;
}
inline raw_storage::raw_storage(size_type n)
{
start = end = static_cast<pointer>(::operator new(n));
BOOST_REGEX_NOEH_ASSERT(start)
last = start + n;
}
} // namespace BOOST_REGEX_DETAIL_NS
} // namespace boost
#endif

View File

@@ -1,77 +0,0 @@
/*
*
* Copyright (c) 1998-2009
* John Maddock
*
* Use, modification and distribution are subject to 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)
*
*/
/*
* LOCATION: see http://www.boost.org for most recent version.
* FILE regex_format.hpp
* VERSION see <boost/version.hpp>
* DESCRIPTION: Provides formatting output routines for search and replace
* operations. Note this is an internal header file included
* by regex.hpp, do not include on its own.
*/
#ifndef BOOST_REGEX_V5_REGEX_REPLACE_HPP
#define BOOST_REGEX_V5_REGEX_REPLACE_HPP
namespace boost{
template <class OutputIterator, class BidirectionalIterator, class traits, class charT, class Formatter>
OutputIterator regex_replace(OutputIterator out,
BidirectionalIterator first,
BidirectionalIterator last,
const basic_regex<charT, traits>& e,
Formatter fmt,
match_flag_type flags = match_default)
{
regex_iterator<BidirectionalIterator, charT, traits> i(first, last, e, flags);
regex_iterator<BidirectionalIterator, charT, traits> j;
if(i == j)
{
if(!(flags & regex_constants::format_no_copy))
out = BOOST_REGEX_DETAIL_NS::copy(first, last, out);
}
else
{
BidirectionalIterator last_m(first);
while(i != j)
{
if(!(flags & regex_constants::format_no_copy))
out = BOOST_REGEX_DETAIL_NS::copy(i->prefix().first, i->prefix().second, out);
out = i->format(out, fmt, flags, e);
last_m = (*i)[0].second;
if(flags & regex_constants::format_first_only)
break;
++i;
}
if(!(flags & regex_constants::format_no_copy))
out = BOOST_REGEX_DETAIL_NS::copy(last_m, last, out);
}
return out;
}
template <class traits, class charT, class Formatter>
std::basic_string<charT> regex_replace(const std::basic_string<charT>& s,
const basic_regex<charT, traits>& e,
Formatter fmt,
match_flag_type flags = match_default)
{
std::basic_string<charT> result;
BOOST_REGEX_DETAIL_NS::string_out_iterator<std::basic_string<charT> > i(result);
regex_replace(i, s.begin(), s.end(), e, fmt, flags);
return result;
}
} // namespace boost
#endif // BOOST_REGEX_V5_REGEX_REPLACE_HPP

View File

@@ -1,103 +0,0 @@
/*
*
* Copyright (c) 1998-2002
* John Maddock
*
* Use, modification and distribution are subject to 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)
*
*/
/*
* LOCATION: see http://www.boost.org for most recent version.
* FILE regex_search.hpp
* VERSION see <boost/version.hpp>
* DESCRIPTION: Provides regex_search implementation.
*/
#ifndef BOOST_REGEX_V5_REGEX_SEARCH_HPP
#define BOOST_REGEX_V5_REGEX_SEARCH_HPP
namespace boost{
template <class BidiIterator, class Allocator, class charT, class traits>
bool regex_search(BidiIterator first, BidiIterator last,
match_results<BidiIterator, Allocator>& m,
const basic_regex<charT, traits>& e,
match_flag_type flags = match_default)
{
return regex_search(first, last, m, e, flags, first);
}
template <class BidiIterator, class Allocator, class charT, class traits>
bool regex_search(BidiIterator first, BidiIterator last,
match_results<BidiIterator, Allocator>& m,
const basic_regex<charT, traits>& e,
match_flag_type flags,
BidiIterator base)
{
if(e.flags() & regex_constants::failbit)
return false;
BOOST_REGEX_DETAIL_NS::perl_matcher<BidiIterator, Allocator, traits> matcher(first, last, m, e, flags, base);
return matcher.find();
}
//
// regex_search convenience interfaces:
//
template <class charT, class Allocator, class traits>
inline bool regex_search(const charT* str,
match_results<const charT*, Allocator>& m,
const basic_regex<charT, traits>& e,
match_flag_type flags = match_default)
{
return regex_search(str, str + traits::length(str), m, e, flags);
}
template <class ST, class SA, class Allocator, class charT, class traits>
inline bool regex_search(const std::basic_string<charT, ST, SA>& s,
match_results<typename std::basic_string<charT, ST, SA>::const_iterator, Allocator>& m,
const basic_regex<charT, traits>& e,
match_flag_type flags = match_default)
{
return regex_search(s.begin(), s.end(), m, e, flags);
}
template <class BidiIterator, class charT, class traits>
bool regex_search(BidiIterator first, BidiIterator last,
const basic_regex<charT, traits>& e,
match_flag_type flags = match_default)
{
if(e.flags() & regex_constants::failbit)
return false;
match_results<BidiIterator> m;
typedef typename match_results<BidiIterator>::allocator_type match_alloc_type;
BOOST_REGEX_DETAIL_NS::perl_matcher<BidiIterator, match_alloc_type, traits> matcher(first, last, m, e, flags | regex_constants::match_any, first);
return matcher.find();
}
template <class charT, class traits>
inline bool regex_search(const charT* str,
const basic_regex<charT, traits>& e,
match_flag_type flags = match_default)
{
return regex_search(str, str + traits::length(str), e, flags);
}
template <class ST, class SA, class charT, class traits>
inline bool regex_search(const std::basic_string<charT, ST, SA>& s,
const basic_regex<charT, traits>& e,
match_flag_type flags = match_default)
{
return regex_search(s.begin(), s.end(), e, flags);
}
} // namespace boost
#endif // BOOST_REGEX_V5_REGEX_SEARCH_HPP

View File

@@ -1,152 +0,0 @@
/*
*
* Copyright (c) 1998-2002
* John Maddock
*
* Use, modification and distribution are subject to 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)
*
*/
/*
* LOCATION: see http://www.boost.org for most recent version.
* FILE regex_split.hpp
* VERSION see <boost/version.hpp>
* DESCRIPTION: Implements regex_split and associated functions.
* Note this is an internal header file included
* by regex.hpp, do not include on its own.
*/
#ifndef BOOST_REGEX_SPLIT_HPP
#define BOOST_REGEX_SPLIT_HPP
namespace boost{
#ifdef BOOST_REGEX_MSVC
# pragma warning(push)
#if BOOST_REGEX_MSVC < 1910
#pragma warning(disable:4800)
#endif
#endif
namespace BOOST_REGEX_DETAIL_NS{
template <class charT>
const basic_regex<charT>& get_default_expression(charT)
{
static const charT expression_text[4] = { '\\', 's', '+', '\00', };
static const basic_regex<charT> e(expression_text);
return e;
}
template <class OutputIterator, class charT, class Traits1, class Alloc1>
class split_pred
{
typedef std::basic_string<charT, Traits1, Alloc1> string_type;
typedef typename string_type::const_iterator iterator_type;
iterator_type* p_last;
OutputIterator* p_out;
std::size_t* p_max;
std::size_t initial_max;
public:
split_pred(iterator_type* a, OutputIterator* b, std::size_t* c)
: p_last(a), p_out(b), p_max(c), initial_max(*c) {}
bool operator()(const match_results<iterator_type>& what);
};
template <class OutputIterator, class charT, class Traits1, class Alloc1>
bool split_pred<OutputIterator, charT, Traits1, Alloc1>::operator()
(const match_results<iterator_type>& what)
{
*p_last = what[0].second;
if(what.size() > 1)
{
// output sub-expressions only:
for(unsigned i = 1; i < what.size(); ++i)
{
*(*p_out) = what.str(i);
++(*p_out);
if(0 == --*p_max) return false;
}
return *p_max != 0;
}
else
{
// output $` only if it's not-null or not at the start of the input:
const sub_match<iterator_type>& sub = what[-1];
if((sub.first != sub.second) || (*p_max != initial_max))
{
*(*p_out) = sub.str();
++(*p_out);
return --*p_max;
}
}
//
// initial null, do nothing:
return true;
}
} // namespace BOOST_REGEX_DETAIL_NS
template <class OutputIterator, class charT, class Traits1, class Alloc1, class Traits2>
std::size_t regex_split(OutputIterator out,
std::basic_string<charT, Traits1, Alloc1>& s,
const basic_regex<charT, Traits2>& e,
match_flag_type flags,
std::size_t max_split)
{
typedef typename std::basic_string<charT, Traits1, Alloc1>::const_iterator ci_t;
//typedef typename match_results<ci_t>::allocator_type match_allocator;
ci_t last = s.begin();
std::size_t init_size = max_split;
BOOST_REGEX_DETAIL_NS::split_pred<OutputIterator, charT, Traits1, Alloc1> pred(&last, &out, &max_split);
ci_t i, j;
i = s.begin();
j = s.end();
regex_grep(pred, i, j, e, flags);
//
// if there is still input left, do a final push as long as max_split
// is not exhausted, and we're not splitting sub-expressions rather
// than whitespace:
if(max_split && (last != s.end()) && (e.mark_count() == 0))
{
*out = std::basic_string<charT, Traits1, Alloc1>((ci_t)last, (ci_t)s.end());
++out;
last = s.end();
--max_split;
}
//
// delete from the string everything that has been processed so far:
s.erase(0, last - s.begin());
//
// return the number of new records pushed:
return init_size - max_split;
}
template <class OutputIterator, class charT, class Traits1, class Alloc1, class Traits2>
inline std::size_t regex_split(OutputIterator out,
std::basic_string<charT, Traits1, Alloc1>& s,
const basic_regex<charT, Traits2>& e,
match_flag_type flags = match_default)
{
return regex_split(out, s, e, flags, UINT_MAX);
}
template <class OutputIterator, class charT, class Traits1, class Alloc1>
inline std::size_t regex_split(OutputIterator out,
std::basic_string<charT, Traits1, Alloc1>& s)
{
return regex_split(out, s, BOOST_REGEX_DETAIL_NS::get_default_expression(charT(0)), match_default, UINT_MAX);
}
#ifdef BOOST_REGEX_MSVC
# pragma warning(pop)
#endif
} // namespace boost
#endif

View File

@@ -1,255 +0,0 @@
/*
*
* Copyright (c) 2003
* John Maddock
*
* Use, modification and distribution are subject to 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)
*
*/
/*
* LOCATION: see http://www.boost.org for most recent version.
* FILE regex_token_iterator.hpp
* VERSION see <boost/version.hpp>
* DESCRIPTION: Provides regex_token_iterator implementation.
*/
#ifndef BOOST_REGEX_V5_REGEX_TOKEN_ITERATOR_HPP
#define BOOST_REGEX_V5_REGEX_TOKEN_ITERATOR_HPP
#include <memory>
namespace boost{
template <class BidirectionalIterator,
class charT,
class traits>
class regex_token_iterator_implementation
{
typedef basic_regex<charT, traits> regex_type;
typedef sub_match<BidirectionalIterator> value_type;
match_results<BidirectionalIterator> what; // current match
BidirectionalIterator base; // start of search area
BidirectionalIterator end; // end of search area
const regex_type re; // the expression
match_flag_type flags; // match flags
value_type result; // the current string result
int N; // the current sub-expression being enumerated
std::vector<int> subs; // the sub-expressions to enumerate
public:
regex_token_iterator_implementation(const regex_type* p, BidirectionalIterator last, int sub, match_flag_type f)
: end(last), re(*p), flags(f), N(0){ subs.push_back(sub); }
regex_token_iterator_implementation(const regex_type* p, BidirectionalIterator last, const std::vector<int>& v, match_flag_type f)
: end(last), re(*p), flags(f), N(0), subs(v){}
template <std::size_t CN>
regex_token_iterator_implementation(const regex_type* p, BidirectionalIterator last, const int (&submatches)[CN], match_flag_type f)
: end(last), re(*p), flags(f), N(0)
{
for(std::size_t i = 0; i < CN; ++i)
{
subs.push_back(submatches[i]);
}
}
regex_token_iterator_implementation(const regex_token_iterator_implementation& other) = default;
bool init(BidirectionalIterator first)
{
N = 0;
base = first;
if(regex_search(first, end, what, re, flags, base) == true)
{
N = 0;
result = ((subs[N] == -1) ? what.prefix() : what[(int)subs[N]]);
return true;
}
else if((subs[N] == -1) && (first != end))
{
result.first = first;
result.second = end;
result.matched = (first != end);
N = -1;
return true;
}
return false;
}
bool compare(const regex_token_iterator_implementation& that)
{
if(this == &that) return true;
return (&re.get_data() == &that.re.get_data())
&& (end == that.end)
&& (flags == that.flags)
&& (N == that.N)
&& (what[0].first == that.what[0].first)
&& (what[0].second == that.what[0].second);
}
const value_type& get()
{ return result; }
bool next()
{
if(N == -1)
return false;
if(N+1 < (int)subs.size())
{
++N;
result =((subs[N] == -1) ? what.prefix() : what[subs[N]]);
return true;
}
//if(what.prefix().first != what[0].second)
// flags |= /*match_prev_avail |*/ regex_constants::match_not_bob;
BidirectionalIterator last_end(what[0].second);
if(regex_search(last_end, end, what, re, ((what[0].first == what[0].second) ? flags | regex_constants::match_not_initial_null : flags), base))
{
N =0;
result =((subs[N] == -1) ? what.prefix() : what[subs[N]]);
return true;
}
else if((last_end != end) && (subs[0] == -1))
{
N =-1;
result.first = last_end;
result.second = end;
result.matched = (last_end != end);
return true;
}
return false;
}
private:
regex_token_iterator_implementation& operator=(const regex_token_iterator_implementation&);
};
template <class BidirectionalIterator,
class charT = typename std::iterator_traits<BidirectionalIterator>::value_type,
class traits = regex_traits<charT> >
class regex_token_iterator
{
private:
typedef regex_token_iterator_implementation<BidirectionalIterator, charT, traits> impl;
typedef std::shared_ptr<impl> pimpl;
public:
typedef basic_regex<charT, traits> regex_type;
typedef sub_match<BidirectionalIterator> value_type;
typedef typename std::iterator_traits<BidirectionalIterator>::difference_type
difference_type;
typedef const value_type* pointer;
typedef const value_type& reference;
typedef std::forward_iterator_tag iterator_category;
regex_token_iterator(){}
regex_token_iterator(BidirectionalIterator a, BidirectionalIterator b, const regex_type& re,
int submatch = 0, match_flag_type m = match_default)
: pdata(new impl(&re, b, submatch, m))
{
if(!pdata->init(a))
pdata.reset();
}
regex_token_iterator(BidirectionalIterator a, BidirectionalIterator b, const regex_type& re,
const std::vector<int>& submatches, match_flag_type m = match_default)
: pdata(new impl(&re, b, submatches, m))
{
if(!pdata->init(a))
pdata.reset();
}
template <std::size_t N>
regex_token_iterator(BidirectionalIterator a, BidirectionalIterator b, const regex_type& re,
const int (&submatches)[N], match_flag_type m = match_default)
: pdata(new impl(&re, b, submatches, m))
{
if(!pdata->init(a))
pdata.reset();
}
regex_token_iterator(const regex_token_iterator& that)
: pdata(that.pdata) {}
regex_token_iterator& operator=(const regex_token_iterator& that)
{
pdata = that.pdata;
return *this;
}
bool operator==(const regex_token_iterator& that)const
{
if((pdata.get() == 0) || (that.pdata.get() == 0))
return pdata.get() == that.pdata.get();
return pdata->compare(*(that.pdata.get()));
}
bool operator!=(const regex_token_iterator& that)const
{ return !(*this == that); }
const value_type& operator*()const
{ return pdata->get(); }
const value_type* operator->()const
{ return &(pdata->get()); }
regex_token_iterator& operator++()
{
cow();
if(0 == pdata->next())
{
pdata.reset();
}
return *this;
}
regex_token_iterator operator++(int)
{
regex_token_iterator result(*this);
++(*this);
return result;
}
private:
pimpl pdata;
void cow()
{
// copy-on-write
if(pdata.get() && (pdata.use_count() > 1))
{
pdata.reset(new impl(*(pdata.get())));
}
}
};
typedef regex_token_iterator<const char*> cregex_token_iterator;
typedef regex_token_iterator<std::string::const_iterator> sregex_token_iterator;
#ifndef BOOST_NO_WREGEX
typedef regex_token_iterator<const wchar_t*> wcregex_token_iterator;
typedef regex_token_iterator<std::wstring::const_iterator> wsregex_token_iterator;
#endif
template <class charT, class traits>
inline regex_token_iterator<const charT*, charT, traits> make_regex_token_iterator(const charT* p, const basic_regex<charT, traits>& e, int submatch = 0, regex_constants::match_flag_type m = regex_constants::match_default)
{
return regex_token_iterator<const charT*, charT, traits>(p, p+traits::length(p), e, submatch, m);
}
template <class charT, class traits, class ST, class SA>
inline regex_token_iterator<typename std::basic_string<charT, ST, SA>::const_iterator, charT, traits> make_regex_token_iterator(const std::basic_string<charT, ST, SA>& p, const basic_regex<charT, traits>& e, int submatch = 0, regex_constants::match_flag_type m = regex_constants::match_default)
{
return regex_token_iterator<typename std::basic_string<charT, ST, SA>::const_iterator, charT, traits>(p.begin(), p.end(), e, submatch, m);
}
template <class charT, class traits, std::size_t N>
inline regex_token_iterator<const charT*, charT, traits> make_regex_token_iterator(const charT* p, const basic_regex<charT, traits>& e, const int (&submatch)[N], regex_constants::match_flag_type m = regex_constants::match_default)
{
return regex_token_iterator<const charT*, charT, traits>(p, p+traits::length(p), e, submatch, m);
}
template <class charT, class traits, class ST, class SA, std::size_t N>
inline regex_token_iterator<typename std::basic_string<charT, ST, SA>::const_iterator, charT, traits> make_regex_token_iterator(const std::basic_string<charT, ST, SA>& p, const basic_regex<charT, traits>& e, const int (&submatch)[N], regex_constants::match_flag_type m = regex_constants::match_default)
{
return regex_token_iterator<typename std::basic_string<charT, ST, SA>::const_iterator, charT, traits>(p.begin(), p.end(), e, submatch, m);
}
template <class charT, class traits>
inline regex_token_iterator<const charT*, charT, traits> make_regex_token_iterator(const charT* p, const basic_regex<charT, traits>& e, const std::vector<int>& submatch, regex_constants::match_flag_type m = regex_constants::match_default)
{
return regex_token_iterator<const charT*, charT, traits>(p, p+traits::length(p), e, submatch, m);
}
template <class charT, class traits, class ST, class SA>
inline regex_token_iterator<typename std::basic_string<charT, ST, SA>::const_iterator, charT, traits> make_regex_token_iterator(const std::basic_string<charT, ST, SA>& p, const basic_regex<charT, traits>& e, const std::vector<int>& submatch, regex_constants::match_flag_type m = regex_constants::match_default)
{
return regex_token_iterator<typename std::basic_string<charT, ST, SA>::const_iterator, charT, traits>(p.begin(), p.end(), e, submatch, m);
}
} // namespace boost
#endif // BOOST_REGEX_V5_REGEX_TOKEN_ITERATOR_HPP

View File

@@ -1,130 +0,0 @@
/*
*
* Copyright (c) 2003
* John Maddock
*
* Use, modification and distribution are subject to 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)
*
*/
/*
* LOCATION: see http://www.boost.org for most recent version.
* FILE regex_traits.hpp
* VERSION see <boost/version.hpp>
* DESCRIPTION: Declares regular expression traits classes.
*/
#ifndef BOOST_REGEX_TRAITS_HPP_INCLUDED
#define BOOST_REGEX_TRAITS_HPP_INCLUDED
#include <boost/regex/config.hpp>
#include <boost/regex/v5/regex_workaround.hpp>
#include <boost/regex/v5/syntax_type.hpp>
#include <boost/regex/v5/error_type.hpp>
#include <boost/regex/v5/regex_traits_defaults.hpp>
#include <boost/regex/v5/cpp_regex_traits.hpp>
#include <boost/regex/v5/c_regex_traits.hpp>
#if defined(_WIN32) && !defined(BOOST_REGEX_NO_W32)
# include <boost/regex/v5/w32_regex_traits.hpp>
#endif
#include <boost/regex_fwd.hpp>
namespace boost{
template <class charT, class implementationT >
struct regex_traits : public implementationT
{
regex_traits() : implementationT() {}
};
//
// class regex_traits_wrapper.
// this is what our implementation will actually store;
// it provides default implementations of the "optional"
// interfaces that we support, in addition to the
// required "standard" ones:
//
namespace BOOST_REGEX_DETAIL_NS{
template <class T>
struct has_boost_extensions_tag
{
template <class U>
static double checker(U*, typename U::boost_extensions_tag* = nullptr);
static char checker(...);
static T* get();
static const bool value = sizeof(checker(get())) > 1;
};
template <class BaseT>
struct default_wrapper : public BaseT
{
typedef typename BaseT::char_type char_type;
std::string error_string(::boost::regex_constants::error_type e)const
{
return ::boost::BOOST_REGEX_DETAIL_NS::get_default_error_string(e);
}
::boost::regex_constants::syntax_type syntax_type(char_type c)const
{
return (char_type(c & 0x7f) == c) ? get_default_syntax_type(static_cast<char>(c)) : ::boost::regex_constants::syntax_char;
}
::boost::regex_constants::escape_syntax_type escape_syntax_type(char_type c)const
{
return (char_type(c & 0x7f) == c) ? get_default_escape_syntax_type(static_cast<char>(c)) : ::boost::regex_constants::escape_type_identity;
}
std::intmax_t toi(const char_type*& p1, const char_type* p2, int radix)const
{
return ::boost::BOOST_REGEX_DETAIL_NS::global_toi(p1, p2, radix, *this);
}
char_type translate(char_type c, bool icase)const
{
return (icase ? this->translate_nocase(c) : this->translate(c));
}
char_type translate(char_type c)const
{
return BaseT::translate(c);
}
char_type tolower(char_type c)const
{
return ::boost::BOOST_REGEX_DETAIL_NS::global_lower(c);
}
char_type toupper(char_type c)const
{
return ::boost::BOOST_REGEX_DETAIL_NS::global_upper(c);
}
};
template <class BaseT, bool has_extensions>
struct compute_wrapper_base
{
typedef BaseT type;
};
template <class BaseT>
struct compute_wrapper_base<BaseT, false>
{
typedef default_wrapper<BaseT> type;
};
} // namespace BOOST_REGEX_DETAIL_NS
template <class BaseT>
struct regex_traits_wrapper
: public ::boost::BOOST_REGEX_DETAIL_NS::compute_wrapper_base<
BaseT,
::boost::BOOST_REGEX_DETAIL_NS::has_boost_extensions_tag<BaseT>::value
>::type
{
regex_traits_wrapper(){}
private:
regex_traits_wrapper(const regex_traits_wrapper&);
regex_traits_wrapper& operator=(const regex_traits_wrapper&);
};
} // namespace boost
#endif // include

View File

@@ -1,996 +0,0 @@
/*
*
* Copyright (c) 2004
* John Maddock
*
* Use, modification and distribution are subject to 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)
*
*/
/*
* LOCATION: see http://www.boost.org for most recent version.
* FILE regex_traits_defaults.hpp
* VERSION see <boost/version.hpp>
* DESCRIPTION: Declares API's for access to regex_traits default properties.
*/
#ifndef BOOST_REGEX_TRAITS_DEFAULTS_HPP_INCLUDED
#define BOOST_REGEX_TRAITS_DEFAULTS_HPP_INCLUDED
#include <boost/regex/config.hpp>
#include <boost/regex/v5/syntax_type.hpp>
#include <boost/regex/v5/error_type.hpp>
#include <boost/regex/v5/regex_workaround.hpp>
#include <type_traits>
#include <cstdint>
#include <cctype>
#include <locale>
#include <cwctype>
#include <limits>
namespace boost{ namespace BOOST_REGEX_DETAIL_NS{
//
// helpers to suppress warnings:
//
template <class charT>
inline bool is_extended(charT c)
{
typedef typename std::make_unsigned<charT>::type unsigned_type;
return (sizeof(charT) > 1) && (static_cast<unsigned_type>(c) >= 256u);
}
inline bool is_extended(char)
{ return false; }
inline const char* get_default_syntax(regex_constants::syntax_type n)
{
// if the user hasn't supplied a message catalog, then this supplies
// default "messages" for us to load in the range 1-100.
const char* messages[] = {
"",
"(",
")",
"$",
"^",
".",
"*",
"+",
"?",
"[",
"]",
"|",
"\\",
"#",
"-",
"{",
"}",
"0123456789",
"b",
"B",
"<",
">",
"",
"",
"A`",
"z'",
"\n",
",",
"a",
"f",
"n",
"r",
"t",
"v",
"x",
"c",
":",
"=",
"e",
"",
"",
"",
"",
"",
"",
"",
"",
"E",
"Q",
"X",
"C",
"Z",
"G",
"!",
"p",
"P",
"N",
"gk",
"K",
"R",
};
return ((n >= (sizeof(messages) / sizeof(messages[1]))) ? "" : messages[n]);
}
inline const char* get_default_error_string(regex_constants::error_type n)
{
static const char* const s_default_error_messages[] = {
"Success", /* REG_NOERROR 0 error_ok */
"No match", /* REG_NOMATCH 1 error_no_match */
"Invalid regular expression.", /* REG_BADPAT 2 error_bad_pattern */
"Invalid collation character.", /* REG_ECOLLATE 3 error_collate */
"Invalid character class name, collating name, or character range.", /* REG_ECTYPE 4 error_ctype */
"Invalid or unterminated escape sequence.", /* REG_EESCAPE 5 error_escape */
"Invalid back reference: specified capturing group does not exist.", /* REG_ESUBREG 6 error_backref */
"Unmatched [ or [^ in character class declaration.", /* REG_EBRACK 7 error_brack */
"Unmatched marking parenthesis ( or \\(.", /* REG_EPAREN 8 error_paren */
"Unmatched quantified repeat operator { or \\{.", /* REG_EBRACE 9 error_brace */
"Invalid content of repeat range.", /* REG_BADBR 10 error_badbrace */
"Invalid range end in character class", /* REG_ERANGE 11 error_range */
"Out of memory.", /* REG_ESPACE 12 error_space NOT USED */
"Invalid preceding regular expression prior to repetition operator.", /* REG_BADRPT 13 error_badrepeat */
"Premature end of regular expression", /* REG_EEND 14 error_end NOT USED */
"Regular expression is too large.", /* REG_ESIZE 15 error_size NOT USED */
"Unmatched ) or \\)", /* REG_ERPAREN 16 error_right_paren NOT USED */
"Empty regular expression.", /* REG_EMPTY 17 error_empty */
"The complexity of matching the regular expression exceeded predefined bounds. "
"Try refactoring the regular expression to make each choice made by the state machine unambiguous. "
"This exception is thrown to prevent \"eternal\" matches that take an "
"indefinite period time to locate.", /* REG_ECOMPLEXITY 18 error_complexity */
"Ran out of stack space trying to match the regular expression.", /* REG_ESTACK 19 error_stack */
"Invalid or unterminated Perl (?...) sequence.", /* REG_E_PERL 20 error_perl */
"Unknown error.", /* REG_E_UNKNOWN 21 error_unknown */
};
return (n > ::boost::regex_constants::error_unknown) ? s_default_error_messages[::boost::regex_constants::error_unknown] : s_default_error_messages[n];
}
inline regex_constants::syntax_type get_default_syntax_type(char c)
{
//
// char_syntax determines how the compiler treats a given character
// in a regular expression.
//
static regex_constants::syntax_type char_syntax[] = {
regex_constants::syntax_char, /**/
regex_constants::syntax_char, /**/
regex_constants::syntax_char, /**/
regex_constants::syntax_char, /**/
regex_constants::syntax_char, /**/
regex_constants::syntax_char, /**/
regex_constants::syntax_char, /**/
regex_constants::syntax_char, /**/
regex_constants::syntax_char, /**/
regex_constants::syntax_char, /**/
regex_constants::syntax_newline, /**/
regex_constants::syntax_char, /**/
regex_constants::syntax_char, /**/
regex_constants::syntax_char, /**/
regex_constants::syntax_char, /**/
regex_constants::syntax_char, /**/
regex_constants::syntax_char, /**/
regex_constants::syntax_char, /**/
regex_constants::syntax_char, /**/
regex_constants::syntax_char, /**/
regex_constants::syntax_char, /**/
regex_constants::syntax_char, /**/
regex_constants::syntax_char, /**/
regex_constants::syntax_char, /**/
regex_constants::syntax_char, /**/
regex_constants::syntax_char, /**/
regex_constants::syntax_char, /**/
regex_constants::syntax_char, /**/
regex_constants::syntax_char, /**/
regex_constants::syntax_char, /**/
regex_constants::syntax_char, /**/
regex_constants::syntax_char, /**/
regex_constants::syntax_char, /* */ // 32
regex_constants::syntax_not, /*!*/
regex_constants::syntax_char, /*"*/
regex_constants::syntax_hash, /*#*/
regex_constants::syntax_dollar, /*$*/
regex_constants::syntax_char, /*%*/
regex_constants::syntax_char, /*&*/
regex_constants::escape_type_end_buffer, /*'*/
regex_constants::syntax_open_mark, /*(*/
regex_constants::syntax_close_mark, /*)*/
regex_constants::syntax_star, /***/
regex_constants::syntax_plus, /*+*/
regex_constants::syntax_comma, /*,*/
regex_constants::syntax_dash, /*-*/
regex_constants::syntax_dot, /*.*/
regex_constants::syntax_char, /*/*/
regex_constants::syntax_digit, /*0*/
regex_constants::syntax_digit, /*1*/
regex_constants::syntax_digit, /*2*/
regex_constants::syntax_digit, /*3*/
regex_constants::syntax_digit, /*4*/
regex_constants::syntax_digit, /*5*/
regex_constants::syntax_digit, /*6*/
regex_constants::syntax_digit, /*7*/
regex_constants::syntax_digit, /*8*/
regex_constants::syntax_digit, /*9*/
regex_constants::syntax_colon, /*:*/
regex_constants::syntax_char, /*;*/
regex_constants::escape_type_left_word, /*<*/
regex_constants::syntax_equal, /*=*/
regex_constants::escape_type_right_word, /*>*/
regex_constants::syntax_question, /*?*/
regex_constants::syntax_char, /*@*/
regex_constants::syntax_char, /*A*/
regex_constants::syntax_char, /*B*/
regex_constants::syntax_char, /*C*/
regex_constants::syntax_char, /*D*/
regex_constants::syntax_char, /*E*/
regex_constants::syntax_char, /*F*/
regex_constants::syntax_char, /*G*/
regex_constants::syntax_char, /*H*/
regex_constants::syntax_char, /*I*/
regex_constants::syntax_char, /*J*/
regex_constants::syntax_char, /*K*/
regex_constants::syntax_char, /*L*/
regex_constants::syntax_char, /*M*/
regex_constants::syntax_char, /*N*/
regex_constants::syntax_char, /*O*/
regex_constants::syntax_char, /*P*/
regex_constants::syntax_char, /*Q*/
regex_constants::syntax_char, /*R*/
regex_constants::syntax_char, /*S*/
regex_constants::syntax_char, /*T*/
regex_constants::syntax_char, /*U*/
regex_constants::syntax_char, /*V*/
regex_constants::syntax_char, /*W*/
regex_constants::syntax_char, /*X*/
regex_constants::syntax_char, /*Y*/
regex_constants::syntax_char, /*Z*/
regex_constants::syntax_open_set, /*[*/
regex_constants::syntax_escape, /*\*/
regex_constants::syntax_close_set, /*]*/
regex_constants::syntax_caret, /*^*/
regex_constants::syntax_char, /*_*/
regex_constants::syntax_char, /*`*/
regex_constants::syntax_char, /*a*/
regex_constants::syntax_char, /*b*/
regex_constants::syntax_char, /*c*/
regex_constants::syntax_char, /*d*/
regex_constants::syntax_char, /*e*/
regex_constants::syntax_char, /*f*/
regex_constants::syntax_char, /*g*/
regex_constants::syntax_char, /*h*/
regex_constants::syntax_char, /*i*/
regex_constants::syntax_char, /*j*/
regex_constants::syntax_char, /*k*/
regex_constants::syntax_char, /*l*/
regex_constants::syntax_char, /*m*/
regex_constants::syntax_char, /*n*/
regex_constants::syntax_char, /*o*/
regex_constants::syntax_char, /*p*/
regex_constants::syntax_char, /*q*/
regex_constants::syntax_char, /*r*/
regex_constants::syntax_char, /*s*/
regex_constants::syntax_char, /*t*/
regex_constants::syntax_char, /*u*/
regex_constants::syntax_char, /*v*/
regex_constants::syntax_char, /*w*/
regex_constants::syntax_char, /*x*/
regex_constants::syntax_char, /*y*/
regex_constants::syntax_char, /*z*/
regex_constants::syntax_open_brace, /*{*/
regex_constants::syntax_or, /*|*/
regex_constants::syntax_close_brace, /*}*/
regex_constants::syntax_char, /*~*/
regex_constants::syntax_char, /**/
regex_constants::syntax_char, /**/
regex_constants::syntax_char, /**/
regex_constants::syntax_char, /**/
regex_constants::syntax_char, /**/
regex_constants::syntax_char, /**/
regex_constants::syntax_char, /**/
regex_constants::syntax_char, /**/
regex_constants::syntax_char, /**/
regex_constants::syntax_char, /**/
regex_constants::syntax_char, /**/
regex_constants::syntax_char, /**/
regex_constants::syntax_char, /**/
regex_constants::syntax_char, /**/
regex_constants::syntax_char, /**/
regex_constants::syntax_char, /**/
regex_constants::syntax_char, /**/
regex_constants::syntax_char, /**/
regex_constants::syntax_char, /**/
regex_constants::syntax_char, /**/
regex_constants::syntax_char, /**/
regex_constants::syntax_char, /**/
regex_constants::syntax_char, /**/
regex_constants::syntax_char, /**/
regex_constants::syntax_char, /**/
regex_constants::syntax_char, /**/
regex_constants::syntax_char, /**/
regex_constants::syntax_char, /**/
regex_constants::syntax_char, /**/
regex_constants::syntax_char, /**/
regex_constants::syntax_char, /**/
regex_constants::syntax_char, /**/
regex_constants::syntax_char, /**/
regex_constants::syntax_char, /**/
regex_constants::syntax_char, /**/
regex_constants::syntax_char, /**/
regex_constants::syntax_char, /**/
regex_constants::syntax_char, /**/
regex_constants::syntax_char, /**/
regex_constants::syntax_char, /**/
regex_constants::syntax_char, /**/
regex_constants::syntax_char, /**/
regex_constants::syntax_char, /**/
regex_constants::syntax_char, /**/
regex_constants::syntax_char, /**/
regex_constants::syntax_char, /**/
regex_constants::syntax_char, /**/
regex_constants::syntax_char, /**/
regex_constants::syntax_char, /**/
regex_constants::syntax_char, /**/
regex_constants::syntax_char, /**/
regex_constants::syntax_char, /**/
regex_constants::syntax_char, /**/
regex_constants::syntax_char, /**/
regex_constants::syntax_char, /**/
regex_constants::syntax_char, /**/
};
return char_syntax[(unsigned char)c];
}
inline regex_constants::escape_syntax_type get_default_escape_syntax_type(char c)
{
//
// char_syntax determines how the compiler treats a given character
// in a regular expression.
//
static regex_constants::escape_syntax_type char_syntax[] = {
regex_constants::escape_type_identity, /**/
regex_constants::escape_type_identity, /**/
regex_constants::escape_type_identity, /**/
regex_constants::escape_type_identity, /**/
regex_constants::escape_type_identity, /**/
regex_constants::escape_type_identity, /**/
regex_constants::escape_type_identity, /**/
regex_constants::escape_type_identity, /**/
regex_constants::escape_type_identity, /**/
regex_constants::escape_type_identity, /**/
regex_constants::escape_type_identity, /**/
regex_constants::escape_type_identity, /**/
regex_constants::escape_type_identity, /**/
regex_constants::escape_type_identity, /**/
regex_constants::escape_type_identity, /**/
regex_constants::escape_type_identity, /**/
regex_constants::escape_type_identity, /**/
regex_constants::escape_type_identity, /**/
regex_constants::escape_type_identity, /**/
regex_constants::escape_type_identity, /**/
regex_constants::escape_type_identity, /**/
regex_constants::escape_type_identity, /**/
regex_constants::escape_type_identity, /**/
regex_constants::escape_type_identity, /**/
regex_constants::escape_type_identity, /**/
regex_constants::escape_type_identity, /**/
regex_constants::escape_type_identity, /**/
regex_constants::escape_type_identity, /**/
regex_constants::escape_type_identity, /**/
regex_constants::escape_type_identity, /**/
regex_constants::escape_type_identity, /**/
regex_constants::escape_type_identity, /**/
regex_constants::escape_type_identity, /* */ // 32
regex_constants::escape_type_identity, /*!*/
regex_constants::escape_type_identity, /*"*/
regex_constants::escape_type_identity, /*#*/
regex_constants::escape_type_identity, /*$*/
regex_constants::escape_type_identity, /*%*/
regex_constants::escape_type_identity, /*&*/
regex_constants::escape_type_end_buffer, /*'*/
regex_constants::syntax_open_mark, /*(*/
regex_constants::syntax_close_mark, /*)*/
regex_constants::escape_type_identity, /***/
regex_constants::syntax_plus, /*+*/
regex_constants::escape_type_identity, /*,*/
regex_constants::escape_type_identity, /*-*/
regex_constants::escape_type_identity, /*.*/
regex_constants::escape_type_identity, /*/*/
regex_constants::escape_type_decimal, /*0*/
regex_constants::escape_type_backref, /*1*/
regex_constants::escape_type_backref, /*2*/
regex_constants::escape_type_backref, /*3*/
regex_constants::escape_type_backref, /*4*/
regex_constants::escape_type_backref, /*5*/
regex_constants::escape_type_backref, /*6*/
regex_constants::escape_type_backref, /*7*/
regex_constants::escape_type_backref, /*8*/
regex_constants::escape_type_backref, /*9*/
regex_constants::escape_type_identity, /*:*/
regex_constants::escape_type_identity, /*;*/
regex_constants::escape_type_left_word, /*<*/
regex_constants::escape_type_identity, /*=*/
regex_constants::escape_type_right_word, /*>*/
regex_constants::syntax_question, /*?*/
regex_constants::escape_type_identity, /*@*/
regex_constants::escape_type_start_buffer, /*A*/
regex_constants::escape_type_not_word_assert, /*B*/
regex_constants::escape_type_C, /*C*/
regex_constants::escape_type_not_class, /*D*/
regex_constants::escape_type_E, /*E*/
regex_constants::escape_type_not_class, /*F*/
regex_constants::escape_type_G, /*G*/
regex_constants::escape_type_not_class, /*H*/
regex_constants::escape_type_not_class, /*I*/
regex_constants::escape_type_not_class, /*J*/
regex_constants::escape_type_reset_start_mark, /*K*/
regex_constants::escape_type_not_class, /*L*/
regex_constants::escape_type_not_class, /*M*/
regex_constants::escape_type_named_char, /*N*/
regex_constants::escape_type_not_class, /*O*/
regex_constants::escape_type_not_property, /*P*/
regex_constants::escape_type_Q, /*Q*/
regex_constants::escape_type_line_ending, /*R*/
regex_constants::escape_type_not_class, /*S*/
regex_constants::escape_type_not_class, /*T*/
regex_constants::escape_type_not_class, /*U*/
regex_constants::escape_type_not_class, /*V*/
regex_constants::escape_type_not_class, /*W*/
regex_constants::escape_type_X, /*X*/
regex_constants::escape_type_not_class, /*Y*/
regex_constants::escape_type_Z, /*Z*/
regex_constants::escape_type_identity, /*[*/
regex_constants::escape_type_identity, /*\*/
regex_constants::escape_type_identity, /*]*/
regex_constants::escape_type_identity, /*^*/
regex_constants::escape_type_identity, /*_*/
regex_constants::escape_type_start_buffer, /*`*/
regex_constants::escape_type_control_a, /*a*/
regex_constants::escape_type_word_assert, /*b*/
regex_constants::escape_type_ascii_control, /*c*/
regex_constants::escape_type_class, /*d*/
regex_constants::escape_type_e, /*e*/
regex_constants::escape_type_control_f, /*f*/
regex_constants::escape_type_extended_backref, /*g*/
regex_constants::escape_type_class, /*h*/
regex_constants::escape_type_class, /*i*/
regex_constants::escape_type_class, /*j*/
regex_constants::escape_type_extended_backref, /*k*/
regex_constants::escape_type_class, /*l*/
regex_constants::escape_type_class, /*m*/
regex_constants::escape_type_control_n, /*n*/
regex_constants::escape_type_class, /*o*/
regex_constants::escape_type_property, /*p*/
regex_constants::escape_type_class, /*q*/
regex_constants::escape_type_control_r, /*r*/
regex_constants::escape_type_class, /*s*/
regex_constants::escape_type_control_t, /*t*/
regex_constants::escape_type_class, /*u*/
regex_constants::escape_type_control_v, /*v*/
regex_constants::escape_type_class, /*w*/
regex_constants::escape_type_hex, /*x*/
regex_constants::escape_type_class, /*y*/
regex_constants::escape_type_end_buffer, /*z*/
regex_constants::syntax_open_brace, /*{*/
regex_constants::syntax_or, /*|*/
regex_constants::syntax_close_brace, /*}*/
regex_constants::escape_type_identity, /*~*/
regex_constants::escape_type_identity, /**/
regex_constants::escape_type_identity, /**/
regex_constants::escape_type_identity, /**/
regex_constants::escape_type_identity, /**/
regex_constants::escape_type_identity, /**/
regex_constants::escape_type_identity, /**/
regex_constants::escape_type_identity, /**/
regex_constants::escape_type_identity, /**/
regex_constants::escape_type_identity, /**/
regex_constants::escape_type_identity, /**/
regex_constants::escape_type_identity, /**/
regex_constants::escape_type_identity, /**/
regex_constants::escape_type_identity, /**/
regex_constants::escape_type_identity, /**/
regex_constants::escape_type_identity, /**/
regex_constants::escape_type_identity, /**/
regex_constants::escape_type_identity, /**/
regex_constants::escape_type_identity, /**/
regex_constants::escape_type_identity, /**/
regex_constants::escape_type_identity, /**/
regex_constants::escape_type_identity, /**/
regex_constants::escape_type_identity, /**/
regex_constants::escape_type_identity, /**/
regex_constants::escape_type_identity, /**/
regex_constants::escape_type_identity, /**/
regex_constants::escape_type_identity, /**/
regex_constants::escape_type_identity, /**/
regex_constants::escape_type_identity, /**/
regex_constants::escape_type_identity, /**/
regex_constants::escape_type_identity, /**/
regex_constants::escape_type_identity, /**/
regex_constants::escape_type_identity, /**/
regex_constants::escape_type_identity, /**/
regex_constants::escape_type_identity, /**/
regex_constants::escape_type_identity, /**/
regex_constants::escape_type_identity, /**/
regex_constants::escape_type_identity, /**/
regex_constants::escape_type_identity, /**/
regex_constants::escape_type_identity, /**/
regex_constants::escape_type_identity, /**/
regex_constants::escape_type_identity, /**/
regex_constants::escape_type_identity, /**/
regex_constants::escape_type_identity, /**/
regex_constants::escape_type_identity, /**/
regex_constants::escape_type_identity, /**/
regex_constants::escape_type_identity, /**/
regex_constants::escape_type_identity, /**/
regex_constants::escape_type_identity, /**/
regex_constants::escape_type_identity, /**/
regex_constants::escape_type_identity, /**/
regex_constants::escape_type_identity, /**/
regex_constants::escape_type_identity, /**/
regex_constants::escape_type_identity, /**/
regex_constants::escape_type_identity, /**/
regex_constants::escape_type_identity, /**/
regex_constants::escape_type_identity, /**/
};
return char_syntax[(unsigned char)c];
}
// is charT c a combining character?
inline bool is_combining_implementation(std::uint_least16_t c)
{
const std::uint_least16_t combining_ranges[] = { 0x0300, 0x0361,
0x0483, 0x0486,
0x0903, 0x0903,
0x093E, 0x0940,
0x0949, 0x094C,
0x0982, 0x0983,
0x09BE, 0x09C0,
0x09C7, 0x09CC,
0x09D7, 0x09D7,
0x0A3E, 0x0A40,
0x0A83, 0x0A83,
0x0ABE, 0x0AC0,
0x0AC9, 0x0ACC,
0x0B02, 0x0B03,
0x0B3E, 0x0B3E,
0x0B40, 0x0B40,
0x0B47, 0x0B4C,
0x0B57, 0x0B57,
0x0B83, 0x0B83,
0x0BBE, 0x0BBF,
0x0BC1, 0x0BCC,
0x0BD7, 0x0BD7,
0x0C01, 0x0C03,
0x0C41, 0x0C44,
0x0C82, 0x0C83,
0x0CBE, 0x0CBE,
0x0CC0, 0x0CC4,
0x0CC7, 0x0CCB,
0x0CD5, 0x0CD6,
0x0D02, 0x0D03,
0x0D3E, 0x0D40,
0x0D46, 0x0D4C,
0x0D57, 0x0D57,
0x0F7F, 0x0F7F,
0x20D0, 0x20E1,
0x3099, 0x309A,
0xFE20, 0xFE23,
0xffff, 0xffff, };
const std::uint_least16_t* p = combining_ranges + 1;
while (*p < c) p += 2;
--p;
if ((c >= *p) && (c <= *(p + 1)))
return true;
return false;
}
template <class charT>
inline bool is_combining(charT c)
{
return (c <= static_cast<charT>(0)) ? false : ((c >= static_cast<charT>((std::numeric_limits<uint_least16_t>::max)())) ? false : is_combining_implementation(static_cast<unsigned short>(c)));
}
template <>
inline bool is_combining<char>(char)
{
return false;
}
template <>
inline bool is_combining<signed char>(signed char)
{
return false;
}
template <>
inline bool is_combining<unsigned char>(unsigned char)
{
return false;
}
#ifdef _MSC_VER
template<>
inline bool is_combining<wchar_t>(wchar_t c)
{
return is_combining_implementation(static_cast<unsigned short>(c));
}
#elif !defined(__DECCXX) && !defined(__osf__) && !defined(__OSF__) && defined(WCHAR_MIN) && (WCHAR_MIN == 0) && !defined(BOOST_NO_INTRINSIC_WCHAR_T)
#if defined(WCHAR_MAX) && (WCHAR_MAX <= USHRT_MAX)
template<>
inline bool is_combining<wchar_t>(wchar_t c)
{
return is_combining_implementation(static_cast<unsigned short>(c));
}
#else
template<>
inline bool is_combining<wchar_t>(wchar_t c)
{
return (c >= (std::numeric_limits<uint_least16_t>::max)()) ? false : is_combining_implementation(static_cast<unsigned short>(c));
}
#endif
#endif
//
// is a charT c a line separator?
//
template <class charT>
inline bool is_separator(charT c)
{
return BOOST_REGEX_MAKE_BOOL(
(c == static_cast<charT>('\n'))
|| (c == static_cast<charT>('\r'))
|| (c == static_cast<charT>('\f'))
|| (static_cast<std::uint16_t>(c) == 0x2028u)
|| (static_cast<std::uint16_t>(c) == 0x2029u)
|| (static_cast<std::uint16_t>(c) == 0x85u));
}
template <>
inline bool is_separator<char>(char c)
{
return BOOST_REGEX_MAKE_BOOL((c == '\n') || (c == '\r') || (c == '\f'));
}
//
// get a default collating element:
//
inline std::string lookup_default_collate_name(const std::string& name)
{
//
// these are the POSIX collating names:
//
static const char* def_coll_names[] = {
"NUL", "SOH", "STX", "ETX", "EOT", "ENQ", "ACK", "alert", "backspace", "tab", "newline",
"vertical-tab", "form-feed", "carriage-return", "SO", "SI", "DLE", "DC1", "DC2", "DC3", "DC4", "NAK",
"SYN", "ETB", "CAN", "EM", "SUB", "ESC", "IS4", "IS3", "IS2", "IS1", "space", "exclamation-mark",
"quotation-mark", "number-sign", "dollar-sign", "percent-sign", "ampersand", "apostrophe",
"left-parenthesis", "right-parenthesis", "asterisk", "plus-sign", "comma", "hyphen",
"period", "slash", "zero", "one", "two", "three", "four", "five", "six", "seven", "eight", "nine",
"colon", "semicolon", "less-than-sign", "equals-sign", "greater-than-sign",
"question-mark", "commercial-at", "A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", "L", "M", "N", "O", "P",
"Q", "R", "S", "T", "U", "V", "W", "X", "Y", "Z", "left-square-bracket", "backslash",
"right-square-bracket", "circumflex", "underscore", "grave-accent", "a", "b", "c", "d", "e", "f",
"g", "h", "i", "j", "k", "l", "m", "n", "o", "p", "q", "r", "s", "t", "u", "v", "w", "x", "y", "z", "left-curly-bracket",
"vertical-line", "right-curly-bracket", "tilde", "DEL", "",
};
// these multi-character collating elements
// should keep most Western-European locales
// happy - we should really localise these a
// little more - but this will have to do for
// now:
static const char* def_multi_coll[] = {
"ae",
"Ae",
"AE",
"ch",
"Ch",
"CH",
"ll",
"Ll",
"LL",
"ss",
"Ss",
"SS",
"nj",
"Nj",
"NJ",
"dz",
"Dz",
"DZ",
"lj",
"Lj",
"LJ",
"",
};
unsigned int i = 0;
while (*def_coll_names[i])
{
if (def_coll_names[i] == name)
{
return std::string(1, char(i));
}
++i;
}
i = 0;
while (*def_multi_coll[i])
{
if (def_multi_coll[i] == name)
{
return def_multi_coll[i];
}
++i;
}
return std::string();
}
//
// get the state_id of a character classification, the individual
// traits classes then transform that state_id into a bitmask:
//
template <class charT>
struct character_pointer_range
{
const charT* p1;
const charT* p2;
bool operator < (const character_pointer_range& r)const
{
return std::lexicographical_compare(p1, p2, r.p1, r.p2);
}
bool operator == (const character_pointer_range& r)const
{
// Not only do we check that the ranges are of equal size before
// calling std::equal, but there is no other algorithm available:
// not even a non-standard MS one. So forward to unchecked_equal
// in the MS case.
#ifdef __cpp_lib_robust_nonmodifying_seq_ops
return std::equal(p1, p2, r.p1, r.p2);
#elif defined(BOOST_REGEX_MSVC)
if (((p2 - p1) != (r.p2 - r.p1)))
return false;
const charT* with = r.p1;
const charT* pos = p1;
while (pos != p2)
if (*pos++ != *with++) return false;
return true;
#else
return ((p2 - p1) == (r.p2 - r.p1)) && std::equal(p1, p2, r.p1);
#endif
}
};
template <class charT>
int get_default_class_id(const charT* p1, const charT* p2)
{
static const charT data[73] = {
'a', 'l', 'n', 'u', 'm',
'a', 'l', 'p', 'h', 'a',
'b', 'l', 'a', 'n', 'k',
'c', 'n', 't', 'r', 'l',
'd', 'i', 'g', 'i', 't',
'g', 'r', 'a', 'p', 'h',
'l', 'o', 'w', 'e', 'r',
'p', 'r', 'i', 'n', 't',
'p', 'u', 'n', 'c', 't',
's', 'p', 'a', 'c', 'e',
'u', 'n', 'i', 'c', 'o', 'd', 'e',
'u', 'p', 'p', 'e', 'r',
'v',
'w', 'o', 'r', 'd',
'x', 'd', 'i', 'g', 'i', 't',
};
static const character_pointer_range<charT> ranges[21] =
{
{data+0, data+5,}, // alnum
{data+5, data+10,}, // alpha
{data+10, data+15,}, // blank
{data+15, data+20,}, // cntrl
{data+20, data+21,}, // d
{data+20, data+25,}, // digit
{data+25, data+30,}, // graph
{data+29, data+30,}, // h
{data+30, data+31,}, // l
{data+30, data+35,}, // lower
{data+35, data+40,}, // print
{data+40, data+45,}, // punct
{data+45, data+46,}, // s
{data+45, data+50,}, // space
{data+57, data+58,}, // u
{data+50, data+57,}, // unicode
{data+57, data+62,}, // upper
{data+62, data+63,}, // v
{data+63, data+64,}, // w
{data+63, data+67,}, // word
{data+67, data+73,}, // xdigit
};
const character_pointer_range<charT>* ranges_begin = ranges;
const character_pointer_range<charT>* ranges_end = ranges + (sizeof(ranges)/sizeof(ranges[0]));
character_pointer_range<charT> t = { p1, p2, };
const character_pointer_range<charT>* p = std::lower_bound(ranges_begin, ranges_end, t);
if((p != ranges_end) && (t == *p))
return static_cast<int>(p - ranges);
return -1;
}
//
// helper functions:
//
template <class charT>
std::ptrdiff_t global_length(const charT* p)
{
std::ptrdiff_t n = 0;
while(*p)
{
++p;
++n;
}
return n;
}
template<>
inline std::ptrdiff_t global_length<char>(const char* p)
{
return (std::strlen)(p);
}
#ifndef BOOST_NO_WREGEX
template<>
inline std::ptrdiff_t global_length<wchar_t>(const wchar_t* p)
{
return (std::ptrdiff_t)(std::wcslen)(p);
}
#endif
template <class charT>
inline charT global_lower(charT c)
{
return c;
}
template <class charT>
inline charT global_upper(charT c)
{
return c;
}
inline char do_global_lower(char c)
{
return static_cast<char>((std::tolower)((unsigned char)c));
}
inline char do_global_upper(char c)
{
return static_cast<char>((std::toupper)((unsigned char)c));
}
#ifndef BOOST_NO_WREGEX
inline wchar_t do_global_lower(wchar_t c)
{
return (std::towlower)(c);
}
inline wchar_t do_global_upper(wchar_t c)
{
return (std::towupper)(c);
}
#endif
//
// This sucks: declare template specialisations of global_lower/global_upper
// that just forward to the non-template implementation functions. We do
// this because there is one compiler (Compaq Tru64 C++) that doesn't seem
// to differentiate between templates and non-template overloads....
// what's more, the primary template, plus all overloads have to be
// defined in the same translation unit (if one is inline they all must be)
// otherwise the "local template instantiation" compiler option can pick
// the wrong instantiation when linking:
//
template<> inline char global_lower<char>(char c) { return do_global_lower(c); }
template<> inline char global_upper<char>(char c) { return do_global_upper(c); }
#ifndef BOOST_NO_WREGEX
template<> inline wchar_t global_lower<wchar_t>(wchar_t c) { return do_global_lower(c); }
template<> inline wchar_t global_upper<wchar_t>(wchar_t c) { return do_global_upper(c); }
#endif
template <class charT>
int global_value(charT c)
{
static const charT zero = '0';
static const charT nine = '9';
static const charT a = 'a';
static const charT f = 'f';
static const charT A = 'A';
static const charT F = 'F';
if(c > f) return -1;
if(c >= a) return 10 + (c - a);
if(c > F) return -1;
if(c >= A) return 10 + (c - A);
if(c > nine) return -1;
if(c >= zero) return c - zero;
return -1;
}
template <class charT, class traits>
std::intmax_t global_toi(const charT*& p1, const charT* p2, int radix, const traits& t)
{
(void)t; // warning suppression
std::intmax_t limit = (std::numeric_limits<std::intmax_t>::max)() / radix;
std::intmax_t next_value = t.value(*p1, radix);
if((p1 == p2) || (next_value < 0) || (next_value >= radix))
return -1;
std::intmax_t result = 0;
while(p1 != p2)
{
next_value = t.value(*p1, radix);
if((next_value < 0) || (next_value >= radix))
break;
result *= radix;
result += next_value;
++p1;
if (result > limit)
return -1;
}
return result;
}
template <class charT>
inline typename std::enable_if<(sizeof(charT) > 1), const charT*>::type get_escape_R_string()
{
#ifdef BOOST_REGEX_MSVC
# pragma warning(push)
# pragma warning(disable:4309 4245)
#endif
static const charT e1[] = { '(', '?', '-', 'x', ':', '(', '?', '>', '\x0D', '\x0A', '?',
'|', '[', '\x0A', '\x0B', '\x0C', static_cast<charT>(0x85), static_cast<charT>(0x2028),
static_cast<charT>(0x2029), ']', ')', ')', '\0' };
static const charT e2[] = { '(', '?', '-', 'x', ':', '(', '?', '>', '\x0D', '\x0A', '?',
'|', '[', '\x0A', '\x0B', '\x0C', static_cast<charT>(0x85), ']', ')', ')', '\0' };
charT c = static_cast<charT>(0x2029u);
bool b = (static_cast<unsigned>(c) == 0x2029u);
return (b ? e1 : e2);
#ifdef BOOST_REGEX_MSVC
# pragma warning(pop)
#endif
}
template <class charT>
inline typename std::enable_if<(sizeof(charT) == 1), const charT*>::type get_escape_R_string()
{
#ifdef BOOST_REGEX_MSVC
# pragma warning(push)
# pragma warning(disable:4309 4245)
#endif
static const charT e2[] = {
static_cast<charT>('('),
static_cast<charT>('?'),
static_cast<charT>('-'),
static_cast<charT>('x'),
static_cast<charT>(':'),
static_cast<charT>('('),
static_cast<charT>('?'),
static_cast<charT>('>'),
static_cast<charT>('\x0D'),
static_cast<charT>('\x0A'),
static_cast<charT>('?'),
static_cast<charT>('|'),
static_cast<charT>('['),
static_cast<charT>('\x0A'),
static_cast<charT>('\x0B'),
static_cast<charT>('\x0C'),
static_cast<charT>('\x85'),
static_cast<charT>(']'),
static_cast<charT>(')'),
static_cast<charT>(')'),
static_cast<charT>('\0')
};
return e2;
#ifdef BOOST_REGEX_MSVC
# pragma warning(pop)
#endif
}
} // BOOST_REGEX_DETAIL_NS
} // boost
#endif

View File

@@ -1,159 +0,0 @@
/*
*
* Copyright (c) 1998-2005
* John Maddock
*
* Use, modification and distribution are subject to 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)
*
*/
/*
* LOCATION: see http://www.boost.org for most recent version.
* FILE regex_workarounds.cpp
* VERSION see <boost/version.hpp>
* DESCRIPTION: Declares Misc workarounds.
*/
#ifndef BOOST_REGEX_WORKAROUND_HPP
#define BOOST_REGEX_WORKAROUND_HPP
#include <boost/regex/config.hpp>
#include <algorithm>
#include <stdexcept>
#include <cstring>
#ifndef BOOST_REGEX_STANDALONE
#include <boost/detail/workaround.hpp>
#include <boost/throw_exception.hpp>
#endif
#ifdef BOOST_REGEX_NO_BOOL
# define BOOST_REGEX_MAKE_BOOL(x) static_cast<bool>((x) ? true : false)
#else
# define BOOST_REGEX_MAKE_BOOL(x) static_cast<bool>(x)
#endif
/*****************************************************************************
*
* helper functions pointer_construct/pointer_destroy:
*
****************************************************************************/
#ifdef __cplusplus
namespace boost{ namespace BOOST_REGEX_DETAIL_NS{
#ifdef BOOST_REGEX_MSVC
#pragma warning (push)
#pragma warning (disable : 4100)
#endif
template <class T>
inline void pointer_destroy(T* p)
{ p->~T(); (void)p; }
#ifdef BOOST_REGEX_MSVC
#pragma warning (pop)
#endif
template <class T>
inline void pointer_construct(T* p, const T& t)
{ new (p) T(t); }
}} // namespaces
#endif
/*****************************************************************************
*
* helper function copy:
*
****************************************************************************/
#if defined(BOOST_WORKAROUND)
#if BOOST_WORKAROUND(BOOST_REGEX_MSVC, >= 1400) && defined(__STDC_WANT_SECURE_LIB__) && __STDC_WANT_SECURE_LIB__
#define BOOST_REGEX_HAS_STRCPY_S
#endif
#endif
#ifdef __cplusplus
namespace boost{ namespace BOOST_REGEX_DETAIL_NS{
#if defined(BOOST_REGEX_MSVC) && (BOOST_REGEX_MSVC < 1910)
//
// MSVC 10 will either emit warnings or else refuse to compile
// code that makes perfectly legitimate use of std::copy, when
// the OutputIterator type is a user-defined class (apparently all user
// defined iterators are "unsafe"). What's more Microsoft have removed their
// non-standard "unchecked" versions, even though they are still in the MS
// documentation!! Work around this as best we can:
//
template<class InputIterator, class OutputIterator>
inline OutputIterator copy(
InputIterator first,
InputIterator last,
OutputIterator dest
)
{
while (first != last)
*dest++ = *first++;
return dest;
}
#else
using std::copy;
#endif
#if defined(BOOST_REGEX_HAS_STRCPY_S)
// use safe versions of strcpy etc:
using ::strcpy_s;
using ::strcat_s;
#else
inline std::size_t strcpy_s(
char *strDestination,
std::size_t sizeInBytes,
const char *strSource
)
{
std::size_t lenSourceWithNull = std::strlen(strSource) + 1;
if (lenSourceWithNull > sizeInBytes)
return 1;
std::memcpy(strDestination, strSource, lenSourceWithNull);
return 0;
}
inline std::size_t strcat_s(
char *strDestination,
std::size_t sizeInBytes,
const char *strSource
)
{
std::size_t lenSourceWithNull = std::strlen(strSource) + 1;
std::size_t lenDestination = std::strlen(strDestination);
if (lenSourceWithNull + lenDestination > sizeInBytes)
return 1;
std::memcpy(strDestination + lenDestination, strSource, lenSourceWithNull);
return 0;
}
#endif
inline void overflow_error_if_not_zero(std::size_t i)
{
if(i)
{
std::overflow_error e("String buffer too small");
#ifndef BOOST_REGEX_STANDALONE
boost::throw_exception(e);
#else
throw e;
#endif
}
}
}} // namespaces
#endif // __cplusplus
#endif // include guard

View File

@@ -1,299 +0,0 @@
/*
*
* Copyright (c) 1998-2002
* John Maddock
*
* Use, modification and distribution are subject to 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)
*
*/
/*
* LOCATION: see http://www.boost.org for most recent version.
* FILE states.cpp
* VERSION see <boost/version.hpp>
* DESCRIPTION: Declares internal state machine structures.
*/
#ifndef BOOST_REGEX_V5_STATES_HPP
#define BOOST_REGEX_V5_STATES_HPP
namespace boost{
namespace BOOST_REGEX_DETAIL_NS{
/*** mask_type *******************************************************
Whenever we have a choice of two alternatives, we use an array of bytes
to indicate which of the two alternatives it is possible to take for any
given input character. If mask_take is set, then we can take the next
state, and if mask_skip is set then we can take the alternative.
***********************************************************************/
enum mask_type
{
mask_take = 1,
mask_skip = 2,
mask_init = 4,
mask_any = mask_skip | mask_take,
mask_all = mask_any
};
/*** helpers **********************************************************
These helpers let us use function overload resolution to detect whether
we have narrow or wide character strings:
***********************************************************************/
struct _narrow_type{};
struct _wide_type{};
template <class charT> struct is_byte;
template<> struct is_byte<char> { typedef _narrow_type width_type; };
template<> struct is_byte<unsigned char>{ typedef _narrow_type width_type; };
template<> struct is_byte<signed char> { typedef _narrow_type width_type; };
template <class charT> struct is_byte { typedef _wide_type width_type; };
/*** enum syntax_element_type ******************************************
Every record in the state machine falls into one of the following types:
***********************************************************************/
enum syntax_element_type
{
// start of a marked sub-expression, or perl-style (?...) extension
syntax_element_startmark = 0,
// end of a marked sub-expression, or perl-style (?...) extension
syntax_element_endmark = syntax_element_startmark + 1,
// any sequence of literal characters
syntax_element_literal = syntax_element_endmark + 1,
// start of line assertion: ^
syntax_element_start_line = syntax_element_literal + 1,
// end of line assertion $
syntax_element_end_line = syntax_element_start_line + 1,
// match any character: .
syntax_element_wild = syntax_element_end_line + 1,
// end of expression: we have a match when we get here
syntax_element_match = syntax_element_wild + 1,
// perl style word boundary: \b
syntax_element_word_boundary = syntax_element_match + 1,
// perl style within word boundary: \B
syntax_element_within_word = syntax_element_word_boundary + 1,
// start of word assertion: \<
syntax_element_word_start = syntax_element_within_word + 1,
// end of word assertion: \>
syntax_element_word_end = syntax_element_word_start + 1,
// start of buffer assertion: \`
syntax_element_buffer_start = syntax_element_word_end + 1,
// end of buffer assertion: \'
syntax_element_buffer_end = syntax_element_buffer_start + 1,
// backreference to previously matched sub-expression
syntax_element_backref = syntax_element_buffer_end + 1,
// either a wide character set [..] or one with multicharacter collating elements:
syntax_element_long_set = syntax_element_backref + 1,
// narrow character set: [...]
syntax_element_set = syntax_element_long_set + 1,
// jump to a new state in the machine:
syntax_element_jump = syntax_element_set + 1,
// choose between two production states:
syntax_element_alt = syntax_element_jump + 1,
// a repeat
syntax_element_rep = syntax_element_alt + 1,
// match a combining character sequence
syntax_element_combining = syntax_element_rep + 1,
// perl style soft buffer end: \z
syntax_element_soft_buffer_end = syntax_element_combining + 1,
// perl style continuation: \G
syntax_element_restart_continue = syntax_element_soft_buffer_end + 1,
// single character repeats:
syntax_element_dot_rep = syntax_element_restart_continue + 1,
syntax_element_char_rep = syntax_element_dot_rep + 1,
syntax_element_short_set_rep = syntax_element_char_rep + 1,
syntax_element_long_set_rep = syntax_element_short_set_rep + 1,
// a backstep for lookbehind repeats:
syntax_element_backstep = syntax_element_long_set_rep + 1,
// an assertion that a mark was matched:
syntax_element_assert_backref = syntax_element_backstep + 1,
syntax_element_toggle_case = syntax_element_assert_backref + 1,
// a recursive expression:
syntax_element_recurse = syntax_element_toggle_case + 1,
// Verbs:
syntax_element_fail = syntax_element_recurse + 1,
syntax_element_accept = syntax_element_fail + 1,
syntax_element_commit = syntax_element_accept + 1,
syntax_element_then = syntax_element_commit + 1
};
#ifdef BOOST_REGEX_DEBUG
// dwa 09/26/00 - This is needed to suppress warnings about an ambiguous conversion
std::ostream& operator<<(std::ostream&, syntax_element_type);
#endif
struct re_syntax_base;
/*** union offset_type ************************************************
Points to another state in the machine. During machine construction
we use integral offsets, but these are converted to pointers before
execution of the machine.
***********************************************************************/
union offset_type
{
re_syntax_base* p;
std::ptrdiff_t i;
};
/*** struct re_syntax_base ********************************************
Base class for all states in the machine.
***********************************************************************/
struct re_syntax_base
{
syntax_element_type type; // what kind of state this is
offset_type next; // next state in the machine
};
/*** struct re_brace **************************************************
A marked parenthesis.
***********************************************************************/
struct re_brace : public re_syntax_base
{
// The index to match, can be zero (don't mark the sub-expression)
// or negative (for perl style (?...) extensions):
int index;
bool icase;
};
/*** struct re_dot **************************************************
Match anything.
***********************************************************************/
enum
{
dont_care = 1,
force_not_newline = 0,
force_newline = 2,
test_not_newline = 2,
test_newline = 3
};
struct re_dot : public re_syntax_base
{
unsigned char mask;
};
/*** struct re_literal ************************************************
A string of literals, following this structure will be an
array of characters: charT[length]
***********************************************************************/
struct re_literal : public re_syntax_base
{
unsigned int length;
};
/*** struct re_case ************************************************
Indicates whether we are moving to a case insensive block or not
***********************************************************************/
struct re_case : public re_syntax_base
{
bool icase;
};
/*** struct re_set_long ***********************************************
A wide character set of characters, following this structure will be
an array of type charT:
First csingles null-terminated strings
Then 2 * cranges NULL terminated strings
Then cequivalents NULL terminated strings
***********************************************************************/
template <class mask_type>
struct re_set_long : public re_syntax_base
{
unsigned int csingles, cranges, cequivalents;
mask_type cclasses;
mask_type cnclasses;
bool isnot;
bool singleton;
};
/*** struct re_set ****************************************************
A set of narrow-characters, matches any of _map which is none-zero
***********************************************************************/
struct re_set : public re_syntax_base
{
unsigned char _map[1 << CHAR_BIT];
};
/*** struct re_jump ***************************************************
Jump to a new location in the machine (not next).
***********************************************************************/
struct re_jump : public re_syntax_base
{
offset_type alt; // location to jump to
};
/*** struct re_alt ***************************************************
Jump to a new location in the machine (possibly next).
***********************************************************************/
struct re_alt : public re_jump
{
unsigned char _map[1 << CHAR_BIT]; // which characters can take the jump
unsigned int can_be_null; // true if we match a NULL string
};
/*** struct re_repeat *************************************************
Repeat a section of the machine
***********************************************************************/
struct re_repeat : public re_alt
{
std::size_t min, max; // min and max allowable repeats
int state_id; // Unique identifier for this repeat
bool leading; // True if this repeat is at the start of the machine (lets us optimize some searches)
bool greedy; // True if this is a greedy repeat
};
/*** struct re_recurse ************************************************
Recurse to a particular subexpression.
**********************************************************************/
struct re_recurse : public re_jump
{
int state_id; // identifier of first nested repeat within the recursion.
};
/*** struct re_commit *************************************************
Used for the PRUNE, SKIP and COMMIT verbs which basically differ only in what happens
if no match is found and we start searching forward.
**********************************************************************/
enum commit_type
{
commit_prune,
commit_skip,
commit_commit
};
struct re_commit : public re_syntax_base
{
commit_type action;
};
/*** enum re_jump_size_type *******************************************
Provides compiled size of re_jump structure (allowing for trailing alignment).
We provide this so we know how manybytes to insert when constructing the machine
(The value of padding_mask is defined in regex_raw_buffer.hpp).
***********************************************************************/
enum re_jump_size_type
{
re_jump_size = (sizeof(re_jump) + padding_mask) & ~(padding_mask),
re_repeater_size = (sizeof(re_repeat) + padding_mask) & ~(padding_mask),
re_alt_size = (sizeof(re_alt) + padding_mask) & ~(padding_mask)
};
/*** proc re_is_set_member *********************************************
Forward declaration: we'll need this one later...
***********************************************************************/
template<class charT, class traits>
struct regex_data;
template <class iterator, class charT, class traits_type, class char_classT>
iterator re_is_set_member(iterator next,
iterator last,
const re_set_long<char_classT>* set_,
const regex_data<charT, traits_type>& e, bool icase);
} // namespace BOOST_REGEX_DETAIL_NS
} // namespace boost
#endif

View File

@@ -1,382 +0,0 @@
/*
*
* Copyright (c) 1998-2002
* John Maddock
*
* Use, modification and distribution are subject to 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)
*
*/
/*
* LOCATION: see http://www.boost.org for most recent version.
* FILE sub_match.cpp
* VERSION see <boost/version.hpp>
* DESCRIPTION: Declares template class sub_match.
*/
#ifndef BOOST_REGEX_V5_SUB_MATCH_HPP
#define BOOST_REGEX_V5_SUB_MATCH_HPP
namespace boost{
template <class BidiIterator>
struct sub_match : public std::pair<BidiIterator, BidiIterator>
{
typedef typename std::iterator_traits<BidiIterator>::value_type value_type;
typedef typename std::iterator_traits<BidiIterator>::difference_type difference_type;
typedef BidiIterator iterator_type;
typedef BidiIterator iterator;
typedef BidiIterator const_iterator;
bool matched;
sub_match() : std::pair<BidiIterator, BidiIterator>(), matched(false) {}
sub_match(BidiIterator i) : std::pair<BidiIterator, BidiIterator>(i, i), matched(false) {}
template <class T, class A>
operator std::basic_string<value_type, T, A> ()const
{
return matched ? std::basic_string<value_type, T, A>(this->first, this->second) : std::basic_string<value_type, T, A>();
}
difference_type length()const
{
difference_type n = matched ? std::distance((BidiIterator)this->first, (BidiIterator)this->second) : 0;
return n;
}
std::basic_string<value_type> str()const
{
std::basic_string<value_type> result;
if(matched)
{
std::size_t len = std::distance((BidiIterator)this->first, (BidiIterator)this->second);
result.reserve(len);
BidiIterator i = this->first;
while(i != this->second)
{
result.append(1, *i);
++i;
}
}
return result;
}
int compare(const sub_match& s)const
{
if(matched != s.matched)
return static_cast<int>(matched) - static_cast<int>(s.matched);
return str().compare(s.str());
}
int compare(const std::basic_string<value_type>& s)const
{
return str().compare(s);
}
int compare(const value_type* p)const
{
return str().compare(p);
}
bool operator==(const sub_match& that)const
{ return compare(that) == 0; }
bool operator !=(const sub_match& that)const
{ return compare(that) != 0; }
bool operator<(const sub_match& that)const
{ return compare(that) < 0; }
bool operator>(const sub_match& that)const
{ return compare(that) > 0; }
bool operator<=(const sub_match& that)const
{ return compare(that) <= 0; }
bool operator>=(const sub_match& that)const
{ return compare(that) >= 0; }
#ifdef BOOST_REGEX_MATCH_EXTRA
typedef std::vector<sub_match<BidiIterator> > capture_sequence_type;
const capture_sequence_type& captures()const
{
if(!m_captures)
m_captures.reset(new capture_sequence_type());
return *m_captures;
}
//
// Private implementation API: DO NOT USE!
//
capture_sequence_type& get_captures()const
{
if(!m_captures)
m_captures.reset(new capture_sequence_type());
return *m_captures;
}
private:
mutable std::unique_ptr<capture_sequence_type> m_captures;
public:
#endif
sub_match(const sub_match& that, bool
#ifdef BOOST_REGEX_MATCH_EXTRA
deep_copy
#endif
= true
)
: std::pair<BidiIterator, BidiIterator>(that),
matched(that.matched)
{
#ifdef BOOST_REGEX_MATCH_EXTRA
if(that.m_captures)
if(deep_copy)
m_captures.reset(new capture_sequence_type(*(that.m_captures)));
#endif
}
sub_match& operator=(const sub_match& that)
{
this->first = that.first;
this->second = that.second;
matched = that.matched;
#ifdef BOOST_REGEX_MATCH_EXTRA
if(that.m_captures)
get_captures() = *(that.m_captures);
#endif
return *this;
}
//
// Make this type a range, for both Boost.Range, and C++11:
//
BidiIterator begin()const { return this->first; }
BidiIterator end()const { return this->second; }
};
typedef sub_match<const char*> csub_match;
typedef sub_match<std::string::const_iterator> ssub_match;
#ifndef BOOST_NO_WREGEX
typedef sub_match<const wchar_t*> wcsub_match;
typedef sub_match<std::wstring::const_iterator> wssub_match;
#endif
// comparison to std::basic_string<> part 1:
template <class RandomAccessIterator, class traits, class Allocator>
inline bool operator == (const std::basic_string<typename std::iterator_traits<RandomAccessIterator>::value_type, traits, Allocator>& s,
const sub_match<RandomAccessIterator>& m)
{ return s.compare(m.str()) == 0; }
template <class RandomAccessIterator, class traits, class Allocator>
inline bool operator != (const std::basic_string<typename std::iterator_traits<RandomAccessIterator>::value_type, traits, Allocator>& s,
const sub_match<RandomAccessIterator>& m)
{ return s.compare(m.str()) != 0; }
template <class RandomAccessIterator, class traits, class Allocator>
inline bool operator < (const std::basic_string<typename std::iterator_traits<RandomAccessIterator>::value_type, traits, Allocator>& s,
const sub_match<RandomAccessIterator>& m)
{ return s.compare(m.str()) < 0; }
template <class RandomAccessIterator, class traits, class Allocator>
inline bool operator <= (const std::basic_string<typename std::iterator_traits<RandomAccessIterator>::value_type, traits, Allocator>& s,
const sub_match<RandomAccessIterator>& m)
{ return s.compare(m.str()) <= 0; }
template <class RandomAccessIterator, class traits, class Allocator>
inline bool operator >= (const std::basic_string<typename std::iterator_traits<RandomAccessIterator>::value_type, traits, Allocator>& s,
const sub_match<RandomAccessIterator>& m)
{ return s.compare(m.str()) >= 0; }
template <class RandomAccessIterator, class traits, class Allocator>
inline bool operator > (const std::basic_string<typename std::iterator_traits<RandomAccessIterator>::value_type, traits, Allocator>& s,
const sub_match<RandomAccessIterator>& m)
{ return s.compare(m.str()) > 0; }
// comparison to std::basic_string<> part 2:
template <class RandomAccessIterator, class traits, class Allocator>
inline bool operator == (const sub_match<RandomAccessIterator>& m,
const std::basic_string<typename std::iterator_traits<RandomAccessIterator>::value_type, traits, Allocator>& s)
{ return m.str().compare(s) == 0; }
template <class RandomAccessIterator, class traits, class Allocator>
inline bool operator != (const sub_match<RandomAccessIterator>& m,
const std::basic_string<typename std::iterator_traits<RandomAccessIterator>::value_type, traits, Allocator>& s)
{ return m.str().compare(s) != 0; }
template <class RandomAccessIterator, class traits, class Allocator>
inline bool operator < (const sub_match<RandomAccessIterator>& m,
const std::basic_string<typename std::iterator_traits<RandomAccessIterator>::value_type, traits, Allocator>& s)
{ return m.str().compare(s) < 0; }
template <class RandomAccessIterator, class traits, class Allocator>
inline bool operator > (const sub_match<RandomAccessIterator>& m,
const std::basic_string<typename std::iterator_traits<RandomAccessIterator>::value_type, traits, Allocator>& s)
{ return m.str().compare(s) > 0; }
template <class RandomAccessIterator, class traits, class Allocator>
inline bool operator <= (const sub_match<RandomAccessIterator>& m,
const std::basic_string<typename std::iterator_traits<RandomAccessIterator>::value_type, traits, Allocator>& s)
{ return m.str().compare(s) <= 0; }
template <class RandomAccessIterator, class traits, class Allocator>
inline bool operator >= (const sub_match<RandomAccessIterator>& m,
const std::basic_string<typename std::iterator_traits<RandomAccessIterator>::value_type, traits, Allocator>& s)
{ return m.str().compare(s) >= 0; }
// comparison to const charT* part 1:
template <class RandomAccessIterator>
inline bool operator == (const sub_match<RandomAccessIterator>& m,
typename std::iterator_traits<RandomAccessIterator>::value_type const* s)
{ return m.str().compare(s) == 0; }
template <class RandomAccessIterator>
inline bool operator != (const sub_match<RandomAccessIterator>& m,
typename std::iterator_traits<RandomAccessIterator>::value_type const* s)
{ return m.str().compare(s) != 0; }
template <class RandomAccessIterator>
inline bool operator > (const sub_match<RandomAccessIterator>& m,
typename std::iterator_traits<RandomAccessIterator>::value_type const* s)
{ return m.str().compare(s) > 0; }
template <class RandomAccessIterator>
inline bool operator < (const sub_match<RandomAccessIterator>& m,
typename std::iterator_traits<RandomAccessIterator>::value_type const* s)
{ return m.str().compare(s) < 0; }
template <class RandomAccessIterator>
inline bool operator >= (const sub_match<RandomAccessIterator>& m,
typename std::iterator_traits<RandomAccessIterator>::value_type const* s)
{ return m.str().compare(s) >= 0; }
template <class RandomAccessIterator>
inline bool operator <= (const sub_match<RandomAccessIterator>& m,
typename std::iterator_traits<RandomAccessIterator>::value_type const* s)
{ return m.str().compare(s) <= 0; }
// comparison to const charT* part 2:
template <class RandomAccessIterator>
inline bool operator == (typename std::iterator_traits<RandomAccessIterator>::value_type const* s,
const sub_match<RandomAccessIterator>& m)
{ return m.str().compare(s) == 0; }
template <class RandomAccessIterator>
inline bool operator != (typename std::iterator_traits<RandomAccessIterator>::value_type const* s,
const sub_match<RandomAccessIterator>& m)
{ return m.str().compare(s) != 0; }
template <class RandomAccessIterator>
inline bool operator < (typename std::iterator_traits<RandomAccessIterator>::value_type const* s,
const sub_match<RandomAccessIterator>& m)
{ return m.str().compare(s) > 0; }
template <class RandomAccessIterator>
inline bool operator > (typename std::iterator_traits<RandomAccessIterator>::value_type const* s,
const sub_match<RandomAccessIterator>& m)
{ return m.str().compare(s) < 0; }
template <class RandomAccessIterator>
inline bool operator <= (typename std::iterator_traits<RandomAccessIterator>::value_type const* s,
const sub_match<RandomAccessIterator>& m)
{ return m.str().compare(s) >= 0; }
template <class RandomAccessIterator>
inline bool operator >= (typename std::iterator_traits<RandomAccessIterator>::value_type const* s,
const sub_match<RandomAccessIterator>& m)
{ return m.str().compare(s) <= 0; }
// comparison to const charT& part 1:
template <class RandomAccessIterator>
inline bool operator == (const sub_match<RandomAccessIterator>& m,
typename std::iterator_traits<RandomAccessIterator>::value_type const& s)
{ return m.str().compare(0, m.length(), &s, 1) == 0; }
template <class RandomAccessIterator>
inline bool operator != (const sub_match<RandomAccessIterator>& m,
typename std::iterator_traits<RandomAccessIterator>::value_type const& s)
{ return m.str().compare(0, m.length(), &s, 1) != 0; }
template <class RandomAccessIterator>
inline bool operator > (const sub_match<RandomAccessIterator>& m,
typename std::iterator_traits<RandomAccessIterator>::value_type const& s)
{ return m.str().compare(0, m.length(), &s, 1) > 0; }
template <class RandomAccessIterator>
inline bool operator < (const sub_match<RandomAccessIterator>& m,
typename std::iterator_traits<RandomAccessIterator>::value_type const& s)
{ return m.str().compare(0, m.length(), &s, 1) < 0; }
template <class RandomAccessIterator>
inline bool operator >= (const sub_match<RandomAccessIterator>& m,
typename std::iterator_traits<RandomAccessIterator>::value_type const& s)
{ return m.str().compare(0, m.length(), &s, 1) >= 0; }
template <class RandomAccessIterator>
inline bool operator <= (const sub_match<RandomAccessIterator>& m,
typename std::iterator_traits<RandomAccessIterator>::value_type const& s)
{ return m.str().compare(0, m.length(), &s, 1) <= 0; }
// comparison to const charT* part 2:
template <class RandomAccessIterator>
inline bool operator == (typename std::iterator_traits<RandomAccessIterator>::value_type const& s,
const sub_match<RandomAccessIterator>& m)
{ return m.str().compare(0, m.length(), &s, 1) == 0; }
template <class RandomAccessIterator>
inline bool operator != (typename std::iterator_traits<RandomAccessIterator>::value_type const& s,
const sub_match<RandomAccessIterator>& m)
{ return m.str().compare(0, m.length(), &s, 1) != 0; }
template <class RandomAccessIterator>
inline bool operator < (typename std::iterator_traits<RandomAccessIterator>::value_type const& s,
const sub_match<RandomAccessIterator>& m)
{ return m.str().compare(0, m.length(), &s, 1) > 0; }
template <class RandomAccessIterator>
inline bool operator > (typename std::iterator_traits<RandomAccessIterator>::value_type const& s,
const sub_match<RandomAccessIterator>& m)
{ return m.str().compare(0, m.length(), &s, 1) < 0; }
template <class RandomAccessIterator>
inline bool operator <= (typename std::iterator_traits<RandomAccessIterator>::value_type const& s,
const sub_match<RandomAccessIterator>& m)
{ return m.str().compare(0, m.length(), &s, 1) >= 0; }
template <class RandomAccessIterator>
inline bool operator >= (typename std::iterator_traits<RandomAccessIterator>::value_type const& s,
const sub_match<RandomAccessIterator>& m)
{ return m.str().compare(0, m.length(), &s, 1) <= 0; }
// addition operators:
template <class RandomAccessIterator, class traits, class Allocator>
inline std::basic_string<typename std::iterator_traits<RandomAccessIterator>::value_type, traits, Allocator>
operator + (const std::basic_string<typename std::iterator_traits<RandomAccessIterator>::value_type, traits, Allocator>& s,
const sub_match<RandomAccessIterator>& m)
{
std::basic_string<typename std::iterator_traits<RandomAccessIterator>::value_type, traits, Allocator> result;
result.reserve(s.size() + m.length() + 1);
return result.append(s).append(m.first, m.second);
}
template <class RandomAccessIterator, class traits, class Allocator>
inline std::basic_string<typename std::iterator_traits<RandomAccessIterator>::value_type, traits, Allocator>
operator + (const sub_match<RandomAccessIterator>& m,
const std::basic_string<typename std::iterator_traits<RandomAccessIterator>::value_type, traits, Allocator>& s)
{
std::basic_string<typename std::iterator_traits<RandomAccessIterator>::value_type, traits, Allocator> result;
result.reserve(s.size() + m.length() + 1);
return result.append(m.first, m.second).append(s);
}
template <class RandomAccessIterator>
inline std::basic_string<typename std::iterator_traits<RandomAccessIterator>::value_type>
operator + (typename std::iterator_traits<RandomAccessIterator>::value_type const* s,
const sub_match<RandomAccessIterator>& m)
{
std::basic_string<typename std::iterator_traits<RandomAccessIterator>::value_type> result;
result.reserve(std::char_traits<typename std::iterator_traits<RandomAccessIterator>::value_type>::length(s) + m.length() + 1);
return result.append(s).append(m.first, m.second);
}
template <class RandomAccessIterator>
inline std::basic_string<typename std::iterator_traits<RandomAccessIterator>::value_type>
operator + (const sub_match<RandomAccessIterator>& m,
typename std::iterator_traits<RandomAccessIterator>::value_type const * s)
{
std::basic_string<typename std::iterator_traits<RandomAccessIterator>::value_type> result;
result.reserve(std::char_traits<typename std::iterator_traits<RandomAccessIterator>::value_type>::length(s) + m.length() + 1);
return result.append(m.first, m.second).append(s);
}
template <class RandomAccessIterator>
inline std::basic_string<typename std::iterator_traits<RandomAccessIterator>::value_type>
operator + (typename std::iterator_traits<RandomAccessIterator>::value_type const& s,
const sub_match<RandomAccessIterator>& m)
{
std::basic_string<typename std::iterator_traits<RandomAccessIterator>::value_type> result;
result.reserve(m.length() + 2);
return result.append(1, s).append(m.first, m.second);
}
template <class RandomAccessIterator>
inline std::basic_string<typename std::iterator_traits<RandomAccessIterator>::value_type>
operator + (const sub_match<RandomAccessIterator>& m,
typename std::iterator_traits<RandomAccessIterator>::value_type const& s)
{
std::basic_string<typename std::iterator_traits<RandomAccessIterator>::value_type> result;
result.reserve(m.length() + 2);
return result.append(m.first, m.second).append(1, s);
}
template <class RandomAccessIterator>
inline std::basic_string<typename std::iterator_traits<RandomAccessIterator>::value_type>
operator + (const sub_match<RandomAccessIterator>& m1,
const sub_match<RandomAccessIterator>& m2)
{
std::basic_string<typename std::iterator_traits<RandomAccessIterator>::value_type> result;
result.reserve(m1.length() + m2.length() + 1);
return result.append(m1.first, m1.second).append(m2.first, m2.second);
}
template <class charT, class traits, class RandomAccessIterator>
std::basic_ostream<charT, traits>&
operator << (std::basic_ostream<charT, traits>& os,
const sub_match<RandomAccessIterator>& s)
{
return (os << s.str());
}
} // namespace boost
#endif

View File

@@ -1,105 +0,0 @@
/*
*
* Copyright (c) 2003
* John Maddock
*
* Use, modification and distribution are subject to 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)
*
*/
/*
* LOCATION: see http://www.boost.org for most recent version.
* FILE syntax_type.hpp
* VERSION see <boost/version.hpp>
* DESCRIPTION: Declares regular expression synatx type enumerator.
*/
#ifndef BOOST_REGEX_SYNTAX_TYPE_HPP
#define BOOST_REGEX_SYNTAX_TYPE_HPP
namespace boost{
namespace regex_constants{
typedef unsigned char syntax_type;
//
// values chosen are binary compatible with previous version:
//
static const syntax_type syntax_char = 0;
static const syntax_type syntax_open_mark = 1;
static const syntax_type syntax_close_mark = 2;
static const syntax_type syntax_dollar = 3;
static const syntax_type syntax_caret = 4;
static const syntax_type syntax_dot = 5;
static const syntax_type syntax_star = 6;
static const syntax_type syntax_plus = 7;
static const syntax_type syntax_question = 8;
static const syntax_type syntax_open_set = 9;
static const syntax_type syntax_close_set = 10;
static const syntax_type syntax_or = 11;
static const syntax_type syntax_escape = 12;
static const syntax_type syntax_dash = 14;
static const syntax_type syntax_open_brace = 15;
static const syntax_type syntax_close_brace = 16;
static const syntax_type syntax_digit = 17;
static const syntax_type syntax_comma = 27;
static const syntax_type syntax_equal = 37;
static const syntax_type syntax_colon = 36;
static const syntax_type syntax_not = 53;
// extensions:
static const syntax_type syntax_hash = 13;
static const syntax_type syntax_newline = 26;
// escapes:
typedef syntax_type escape_syntax_type;
static const escape_syntax_type escape_type_word_assert = 18;
static const escape_syntax_type escape_type_not_word_assert = 19;
static const escape_syntax_type escape_type_control_f = 29;
static const escape_syntax_type escape_type_control_n = 30;
static const escape_syntax_type escape_type_control_r = 31;
static const escape_syntax_type escape_type_control_t = 32;
static const escape_syntax_type escape_type_control_v = 33;
static const escape_syntax_type escape_type_ascii_control = 35;
static const escape_syntax_type escape_type_hex = 34;
static const escape_syntax_type escape_type_unicode = 0; // not used
static const escape_syntax_type escape_type_identity = 0; // not used
static const escape_syntax_type escape_type_backref = syntax_digit;
static const escape_syntax_type escape_type_decimal = syntax_digit; // not used
static const escape_syntax_type escape_type_class = 22;
static const escape_syntax_type escape_type_not_class = 23;
// extensions:
static const escape_syntax_type escape_type_left_word = 20;
static const escape_syntax_type escape_type_right_word = 21;
static const escape_syntax_type escape_type_start_buffer = 24; // for \`
static const escape_syntax_type escape_type_end_buffer = 25; // for \'
static const escape_syntax_type escape_type_control_a = 28; // for \a
static const escape_syntax_type escape_type_e = 38; // for \e
static const escape_syntax_type escape_type_E = 47; // for \Q\E
static const escape_syntax_type escape_type_Q = 48; // for \Q\E
static const escape_syntax_type escape_type_X = 49; // for \X
static const escape_syntax_type escape_type_C = 50; // for \C
static const escape_syntax_type escape_type_Z = 51; // for \Z
static const escape_syntax_type escape_type_G = 52; // for \G
static const escape_syntax_type escape_type_property = 54; // for \p
static const escape_syntax_type escape_type_not_property = 55; // for \P
static const escape_syntax_type escape_type_named_char = 56; // for \N
static const escape_syntax_type escape_type_extended_backref = 57; // for \g
static const escape_syntax_type escape_type_reset_start_mark = 58; // for \K
static const escape_syntax_type escape_type_line_ending = 59; // for \R
static const escape_syntax_type syntax_max = 60;
}
}
#endif

View File

@@ -1,177 +0,0 @@
/*
*
* Copyright (c) 2003
* John Maddock
*
* Use, modification and distribution are subject to 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)
*
*/
/*
* LOCATION: see http://www.boost.org for most recent version.
* FILE u32regex_iterator.hpp
* VERSION see <boost/version.hpp>
* DESCRIPTION: Provides u32regex_iterator implementation.
*/
#ifndef BOOST_REGEX_V5_U32REGEX_ITERATOR_HPP
#define BOOST_REGEX_V5_U32REGEX_ITERATOR_HPP
namespace boost{
template <class BidirectionalIterator>
class u32regex_iterator_implementation
{
typedef u32regex regex_type;
match_results<BidirectionalIterator> what; // current match
BidirectionalIterator base; // start of sequence
BidirectionalIterator end; // end of sequence
const regex_type re; // the expression
match_flag_type flags; // flags for matching
public:
u32regex_iterator_implementation(const regex_type* p, BidirectionalIterator last, match_flag_type f)
: base(), end(last), re(*p), flags(f){}
bool init(BidirectionalIterator first)
{
base = first;
return u32regex_search(first, end, what, re, flags, base);
}
bool compare(const u32regex_iterator_implementation& that)
{
if(this == &that) return true;
return (&re.get_data() == &that.re.get_data()) && (end == that.end) && (flags == that.flags) && (what[0].first == that.what[0].first) && (what[0].second == that.what[0].second);
}
const match_results<BidirectionalIterator>& get()
{ return what; }
bool next()
{
//if(what.prefix().first != what[0].second)
// flags |= match_prev_avail;
BidirectionalIterator next_start = what[0].second;
match_flag_type f(flags);
if(!what.length())
f |= regex_constants::match_not_initial_null;
//if(base != next_start)
// f |= regex_constants::match_not_bob;
bool result = u32regex_search(next_start, end, what, re, f, base);
if(result)
what.set_base(base);
return result;
}
private:
u32regex_iterator_implementation& operator=(const u32regex_iterator_implementation&);
};
template <class BidirectionalIterator>
class u32regex_iterator
{
private:
typedef u32regex_iterator_implementation<BidirectionalIterator> impl;
typedef std::shared_ptr<impl> pimpl;
public:
typedef u32regex regex_type;
typedef match_results<BidirectionalIterator> value_type;
typedef typename std::iterator_traits<BidirectionalIterator>::difference_type
difference_type;
typedef const value_type* pointer;
typedef const value_type& reference;
typedef std::forward_iterator_tag iterator_category;
u32regex_iterator(){}
u32regex_iterator(BidirectionalIterator a, BidirectionalIterator b,
const regex_type& re,
match_flag_type m = match_default)
: pdata(new impl(&re, b, m))
{
if(!pdata->init(a))
{
pdata.reset();
}
}
u32regex_iterator(const u32regex_iterator& that)
: pdata(that.pdata) {}
u32regex_iterator& operator=(const u32regex_iterator& that)
{
pdata = that.pdata;
return *this;
}
bool operator==(const u32regex_iterator& that)const
{
if((pdata.get() == 0) || (that.pdata.get() == 0))
return pdata.get() == that.pdata.get();
return pdata->compare(*(that.pdata.get()));
}
bool operator!=(const u32regex_iterator& that)const
{ return !(*this == that); }
const value_type& operator*()const
{ return pdata->get(); }
const value_type* operator->()const
{ return &(pdata->get()); }
u32regex_iterator& operator++()
{
cow();
if(0 == pdata->next())
{
pdata.reset();
}
return *this;
}
u32regex_iterator operator++(int)
{
u32regex_iterator result(*this);
++(*this);
return result;
}
private:
pimpl pdata;
void cow()
{
// copy-on-write
if(pdata.get() && (pdata.use_count() > 1))
{
pdata.reset(new impl(*(pdata.get())));
}
}
};
typedef u32regex_iterator<const char*> utf8regex_iterator;
typedef u32regex_iterator<const UChar*> utf16regex_iterator;
typedef u32regex_iterator<const UChar32*> utf32regex_iterator;
inline u32regex_iterator<const char*> make_u32regex_iterator(const char* p, const u32regex& e, regex_constants::match_flag_type m = regex_constants::match_default)
{
return u32regex_iterator<const char*>(p, p+std::strlen(p), e, m);
}
#ifndef BOOST_NO_WREGEX
inline u32regex_iterator<const wchar_t*> make_u32regex_iterator(const wchar_t* p, const u32regex& e, regex_constants::match_flag_type m = regex_constants::match_default)
{
return u32regex_iterator<const wchar_t*>(p, p+std::wcslen(p), e, m);
}
#endif
#if !defined(BOOST_REGEX_UCHAR_IS_WCHAR_T)
inline u32regex_iterator<const UChar*> make_u32regex_iterator(const UChar* p, const u32regex& e, regex_constants::match_flag_type m = regex_constants::match_default)
{
return u32regex_iterator<const UChar*>(p, p+u_strlen(p), e, m);
}
#endif
template <class charT, class Traits, class Alloc>
inline u32regex_iterator<typename std::basic_string<charT, Traits, Alloc>::const_iterator> make_u32regex_iterator(const std::basic_string<charT, Traits, Alloc>& p, const u32regex& e, regex_constants::match_flag_type m = regex_constants::match_default)
{
typedef typename std::basic_string<charT, Traits, Alloc>::const_iterator iter_type;
return u32regex_iterator<iter_type>(p.begin(), p.end(), e, m);
}
inline u32regex_iterator<const UChar*> make_u32regex_iterator(const U_NAMESPACE_QUALIFIER UnicodeString& s, const u32regex& e, regex_constants::match_flag_type m = regex_constants::match_default)
{
return u32regex_iterator<const UChar*>(s.getBuffer(), s.getBuffer() + s.length(), e, m);
}
} // namespace boost
#endif // BOOST_REGEX_V5_REGEX_ITERATOR_HPP

View File

@@ -1,312 +0,0 @@
/*
*
* Copyright (c) 2003
* John Maddock
*
* Use, modification and distribution are subject to 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)
*
*/
/*
* LOCATION: see http://www.boost.org for most recent version.
* FILE u32regex_token_iterator.hpp
* VERSION see <boost/version.hpp>
* DESCRIPTION: Provides u32regex_token_iterator implementation.
*/
#ifndef BOOST_REGEX_V5_U32REGEX_TOKEN_ITERATOR_HPP
#define BOOST_REGEX_V5_U32REGEX_TOKEN_ITERATOR_HPP
namespace boost{
#ifdef BOOST_REGEX_MSVC
# pragma warning(push)
# pragma warning(disable:4700)
#endif
template <class BidirectionalIterator>
class u32regex_token_iterator_implementation
{
typedef u32regex regex_type;
typedef sub_match<BidirectionalIterator> value_type;
match_results<BidirectionalIterator> what; // current match
BidirectionalIterator end; // end of search area
BidirectionalIterator base; // start of search area
const regex_type re; // the expression
match_flag_type flags; // match flags
value_type result; // the current string result
int N; // the current sub-expression being enumerated
std::vector<int> subs; // the sub-expressions to enumerate
public:
u32regex_token_iterator_implementation(const regex_type* p, BidirectionalIterator last, int sub, match_flag_type f)
: end(last), re(*p), flags(f){ subs.push_back(sub); }
u32regex_token_iterator_implementation(const regex_type* p, BidirectionalIterator last, const std::vector<int>& v, match_flag_type f)
: end(last), re(*p), flags(f), subs(v){}
template <std::size_t CN>
u32regex_token_iterator_implementation(const regex_type* p, BidirectionalIterator last, const int (&submatches)[CN], match_flag_type f)
: end(last), re(*p), flags(f)
{
for(std::size_t i = 0; i < CN; ++i)
{
subs.push_back(submatches[i]);
}
}
bool init(BidirectionalIterator first)
{
base = first;
N = 0;
if(u32regex_search(first, end, what, re, flags, base) == true)
{
N = 0;
result = ((subs[N] == -1) ? what.prefix() : what[(int)subs[N]]);
return true;
}
else if((subs[N] == -1) && (first != end))
{
result.first = first;
result.second = end;
result.matched = (first != end);
N = -1;
return true;
}
return false;
}
bool compare(const u32regex_token_iterator_implementation& that)
{
if(this == &that) return true;
return (&re.get_data() == &that.re.get_data())
&& (end == that.end)
&& (flags == that.flags)
&& (N == that.N)
&& (what[0].first == that.what[0].first)
&& (what[0].second == that.what[0].second);
}
const value_type& get()
{ return result; }
bool next()
{
if(N == -1)
return false;
if(N+1 < (int)subs.size())
{
++N;
result =((subs[N] == -1) ? what.prefix() : what[subs[N]]);
return true;
}
//if(what.prefix().first != what[0].second)
// flags |= match_prev_avail | regex_constants::match_not_bob;
BidirectionalIterator last_end(what[0].second);
if(u32regex_search(last_end, end, what, re, ((what[0].first == what[0].second) ? flags | regex_constants::match_not_initial_null : flags), base))
{
N =0;
result =((subs[N] == -1) ? what.prefix() : what[subs[N]]);
return true;
}
else if((last_end != end) && (subs[0] == -1))
{
N =-1;
result.first = last_end;
result.second = end;
result.matched = (last_end != end);
return true;
}
return false;
}
private:
u32regex_token_iterator_implementation& operator=(const u32regex_token_iterator_implementation&);
};
template <class BidirectionalIterator>
class u32regex_token_iterator
{
private:
typedef u32regex_token_iterator_implementation<BidirectionalIterator> impl;
typedef std::shared_ptr<impl> pimpl;
public:
typedef u32regex regex_type;
typedef sub_match<BidirectionalIterator> value_type;
typedef typename std::iterator_traits<BidirectionalIterator>::difference_type
difference_type;
typedef const value_type* pointer;
typedef const value_type& reference;
typedef std::forward_iterator_tag iterator_category;
u32regex_token_iterator(){}
u32regex_token_iterator(BidirectionalIterator a, BidirectionalIterator b, const regex_type& re,
int submatch = 0, match_flag_type m = match_default)
: pdata(new impl(&re, b, submatch, m))
{
if(!pdata->init(a))
pdata.reset();
}
u32regex_token_iterator(BidirectionalIterator a, BidirectionalIterator b, const regex_type& re,
const std::vector<int>& submatches, match_flag_type m = match_default)
: pdata(new impl(&re, b, submatches, m))
{
if(!pdata->init(a))
pdata.reset();
}
template <std::size_t N>
u32regex_token_iterator(BidirectionalIterator a, BidirectionalIterator b, const regex_type& re,
const int (&submatches)[N], match_flag_type m = match_default)
: pdata(new impl(&re, b, submatches, m))
{
if(!pdata->init(a))
pdata.reset();
}
u32regex_token_iterator(const u32regex_token_iterator& that)
: pdata(that.pdata) {}
u32regex_token_iterator& operator=(const u32regex_token_iterator& that)
{
pdata = that.pdata;
return *this;
}
bool operator==(const u32regex_token_iterator& that)const
{
if((pdata.get() == 0) || (that.pdata.get() == 0))
return pdata.get() == that.pdata.get();
return pdata->compare(*(that.pdata.get()));
}
bool operator!=(const u32regex_token_iterator& that)const
{ return !(*this == that); }
const value_type& operator*()const
{ return pdata->get(); }
const value_type* operator->()const
{ return &(pdata->get()); }
u32regex_token_iterator& operator++()
{
cow();
if(0 == pdata->next())
{
pdata.reset();
}
return *this;
}
u32regex_token_iterator operator++(int)
{
u32regex_token_iterator result(*this);
++(*this);
return result;
}
private:
pimpl pdata;
void cow()
{
// copy-on-write
if(pdata.get() && (pdata.use_count() > 1))
{
pdata.reset(new impl(*(pdata.get())));
}
}
};
typedef u32regex_token_iterator<const char*> utf8regex_token_iterator;
typedef u32regex_token_iterator<const UChar*> utf16regex_token_iterator;
typedef u32regex_token_iterator<const UChar32*> utf32regex_token_iterator;
// construction from an integral sub_match state_id:
inline u32regex_token_iterator<const char*> make_u32regex_token_iterator(const char* p, const u32regex& e, int submatch = 0, regex_constants::match_flag_type m = regex_constants::match_default)
{
return u32regex_token_iterator<const char*>(p, p+std::strlen(p), e, submatch, m);
}
#ifndef BOOST_NO_WREGEX
inline u32regex_token_iterator<const wchar_t*> make_u32regex_token_iterator(const wchar_t* p, const u32regex& e, int submatch = 0, regex_constants::match_flag_type m = regex_constants::match_default)
{
return u32regex_token_iterator<const wchar_t*>(p, p+std::wcslen(p), e, submatch, m);
}
#endif
#if !defined(BOOST_REGEX_UCHAR_IS_WCHAR_T)
inline u32regex_token_iterator<const UChar*> make_u32regex_token_iterator(const UChar* p, const u32regex& e, int submatch = 0, regex_constants::match_flag_type m = regex_constants::match_default)
{
return u32regex_token_iterator<const UChar*>(p, p+u_strlen(p), e, submatch, m);
}
#endif
template <class charT, class Traits, class Alloc>
inline u32regex_token_iterator<typename std::basic_string<charT, Traits, Alloc>::const_iterator> make_u32regex_token_iterator(const std::basic_string<charT, Traits, Alloc>& p, const u32regex& e, int submatch = 0, regex_constants::match_flag_type m = regex_constants::match_default)
{
typedef typename std::basic_string<charT, Traits, Alloc>::const_iterator iter_type;
return u32regex_token_iterator<iter_type>(p.begin(), p.end(), e, submatch, m);
}
inline u32regex_token_iterator<const UChar*> make_u32regex_token_iterator(const U_NAMESPACE_QUALIFIER UnicodeString& s, const u32regex& e, int submatch = 0, regex_constants::match_flag_type m = regex_constants::match_default)
{
return u32regex_token_iterator<const UChar*>(s.getBuffer(), s.getBuffer() + s.length(), e, submatch, m);
}
// construction from a reference to an array:
template <std::size_t N>
inline u32regex_token_iterator<const char*> make_u32regex_token_iterator(const char* p, const u32regex& e, const int (&submatch)[N], regex_constants::match_flag_type m = regex_constants::match_default)
{
return u32regex_token_iterator<const char*>(p, p+std::strlen(p), e, submatch, m);
}
#ifndef BOOST_NO_WREGEX
template <std::size_t N>
inline u32regex_token_iterator<const wchar_t*> make_u32regex_token_iterator(const wchar_t* p, const u32regex& e, const int (&submatch)[N], regex_constants::match_flag_type m = regex_constants::match_default)
{
return u32regex_token_iterator<const wchar_t*>(p, p+std::wcslen(p), e, submatch, m);
}
#endif
#if !defined(BOOST_REGEX_UCHAR_IS_WCHAR_T)
template <std::size_t N>
inline u32regex_token_iterator<const UChar*> make_u32regex_token_iterator(const UChar* p, const u32regex& e, const int (&submatch)[N], regex_constants::match_flag_type m = regex_constants::match_default)
{
return u32regex_token_iterator<const UChar*>(p, p+u_strlen(p), e, submatch, m);
}
#endif
template <class charT, class Traits, class Alloc, std::size_t N>
inline u32regex_token_iterator<typename std::basic_string<charT, Traits, Alloc>::const_iterator> make_u32regex_token_iterator(const std::basic_string<charT, Traits, Alloc>& p, const u32regex& e, const int (&submatch)[N], regex_constants::match_flag_type m = regex_constants::match_default)
{
typedef typename std::basic_string<charT, Traits, Alloc>::const_iterator iter_type;
return u32regex_token_iterator<iter_type>(p.begin(), p.end(), e, submatch, m);
}
template <std::size_t N>
inline u32regex_token_iterator<const UChar*> make_u32regex_token_iterator(const U_NAMESPACE_QUALIFIER UnicodeString& s, const u32regex& e, const int (&submatch)[N], regex_constants::match_flag_type m = regex_constants::match_default)
{
return u32regex_token_iterator<const UChar*>(s.getBuffer(), s.getBuffer() + s.length(), e, submatch, m);
}
// construction from a vector of sub_match state_id's:
inline u32regex_token_iterator<const char*> make_u32regex_token_iterator(const char* p, const u32regex& e, const std::vector<int>& submatch, regex_constants::match_flag_type m = regex_constants::match_default)
{
return u32regex_token_iterator<const char*>(p, p+std::strlen(p), e, submatch, m);
}
#ifndef BOOST_NO_WREGEX
inline u32regex_token_iterator<const wchar_t*> make_u32regex_token_iterator(const wchar_t* p, const u32regex& e, const std::vector<int>& submatch, regex_constants::match_flag_type m = regex_constants::match_default)
{
return u32regex_token_iterator<const wchar_t*>(p, p+std::wcslen(p), e, submatch, m);
}
#endif
#if !defined(U_WCHAR_IS_UTF16) && (U_SIZEOF_WCHAR_T != 2)
inline u32regex_token_iterator<const UChar*> make_u32regex_token_iterator(const UChar* p, const u32regex& e, const std::vector<int>& submatch, regex_constants::match_flag_type m = regex_constants::match_default)
{
return u32regex_token_iterator<const UChar*>(p, p+u_strlen(p), e, submatch, m);
}
#endif
template <class charT, class Traits, class Alloc>
inline u32regex_token_iterator<typename std::basic_string<charT, Traits, Alloc>::const_iterator> make_u32regex_token_iterator(const std::basic_string<charT, Traits, Alloc>& p, const u32regex& e, const std::vector<int>& submatch, regex_constants::match_flag_type m = regex_constants::match_default)
{
typedef typename std::basic_string<charT, Traits, Alloc>::const_iterator iter_type;
return u32regex_token_iterator<iter_type>(p.begin(), p.end(), e, submatch, m);
}
inline u32regex_token_iterator<const UChar*> make_u32regex_token_iterator(const U_NAMESPACE_QUALIFIER UnicodeString& s, const u32regex& e, const std::vector<int>& submatch, regex_constants::match_flag_type m = regex_constants::match_default)
{
return u32regex_token_iterator<const UChar*>(s.getBuffer(), s.getBuffer() + s.length(), e, submatch, m);
}
#ifdef BOOST_REGEX_MSVC
# pragma warning(pop)
#endif
} // namespace boost
#endif // BOOST_REGEX_V5_REGEX_TOKEN_ITERATOR_HPP

View File

@@ -1,862 +0,0 @@
/*
*
* Copyright (c) 2004
* John Maddock
*
* Use, modification and distribution are subject to 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)
*
*/
/*
* LOCATION: see http://www.boost.org for most recent version.
* FILE unicode_iterator.hpp
* VERSION see <boost/version.hpp>
* DESCRIPTION: Iterator adapters for converting between different Unicode encodings.
*/
/****************************************************************************
Contents:
~~~~~~~~~
1) Read Only, Input Adapters:
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
template <class BaseIterator, class U8Type = std::uint8_t>
class u32_to_u8_iterator;
Adapts sequence of UTF-32 code points to "look like" a sequence of UTF-8.
template <class BaseIterator, class U32Type = std::uint32_t>
class u8_to_u32_iterator;
Adapts sequence of UTF-8 code points to "look like" a sequence of UTF-32.
template <class BaseIterator, class U16Type = std::uint16_t>
class u32_to_u16_iterator;
Adapts sequence of UTF-32 code points to "look like" a sequence of UTF-16.
template <class BaseIterator, class U32Type = std::uint32_t>
class u16_to_u32_iterator;
Adapts sequence of UTF-16 code points to "look like" a sequence of UTF-32.
2) Single pass output iterator adapters:
template <class BaseIterator>
class utf8_output_iterator;
Accepts UTF-32 code points and forwards them on as UTF-8 code points.
template <class BaseIterator>
class utf16_output_iterator;
Accepts UTF-32 code points and forwards them on as UTF-16 code points.
****************************************************************************/
#ifndef BOOST_REGEX_UNICODE_ITERATOR_HPP
#define BOOST_REGEX_UNICODE_ITERATOR_HPP
#include <cstdint>
#include <boost/regex/config.hpp>
#include <stdexcept>
#include <sstream>
#include <ios>
#include <limits.h> // CHAR_BIT
#ifndef BOOST_REGEX_STANDALONE
#include <boost/throw_exception.hpp>
#endif
namespace boost{
namespace detail{
static const std::uint16_t high_surrogate_base = 0xD7C0u;
static const std::uint16_t low_surrogate_base = 0xDC00u;
static const std::uint32_t ten_bit_mask = 0x3FFu;
inline bool is_high_surrogate(std::uint16_t v)
{
return (v & 0xFFFFFC00u) == 0xd800u;
}
inline bool is_low_surrogate(std::uint16_t v)
{
return (v & 0xFFFFFC00u) == 0xdc00u;
}
template <class T>
inline bool is_surrogate(T v)
{
return (v & 0xFFFFF800u) == 0xd800;
}
inline unsigned utf8_byte_count(std::uint8_t c)
{
// if the most significant bit with a zero in it is in position
// 8-N then there are N bytes in this UTF-8 sequence:
std::uint8_t mask = 0x80u;
unsigned result = 0;
while(c & mask)
{
++result;
mask >>= 1;
}
return (result == 0) ? 1 : ((result > 4) ? 4 : result);
}
inline unsigned utf8_trailing_byte_count(std::uint8_t c)
{
return utf8_byte_count(c) - 1;
}
#ifdef BOOST_REGEX_MSVC
#pragma warning(push)
#pragma warning(disable:4100)
#endif
#ifndef BOOST_NO_EXCEPTIONS
BOOST_REGEX_NORETURN
#endif
inline void invalid_utf32_code_point(std::uint32_t val)
{
std::stringstream ss;
ss << "Invalid UTF-32 code point U+" << std::showbase << std::hex << val << " encountered while trying to encode UTF-16 sequence";
std::out_of_range e(ss.str());
#ifndef BOOST_REGEX_STANDALONE
boost::throw_exception(e);
#else
throw e;
#endif
}
#ifdef BOOST_REGEX_MSVC
#pragma warning(pop)
#endif
} // namespace detail
template <class BaseIterator, class U16Type = std::uint16_t>
class u32_to_u16_iterator
{
typedef typename std::iterator_traits<BaseIterator>::value_type base_value_type;
static_assert(sizeof(base_value_type)*CHAR_BIT == 32, "Incorrectly sized template argument");
static_assert(sizeof(U16Type)*CHAR_BIT == 16, "Incorrectly sized template argument");
public:
typedef std::ptrdiff_t difference_type;
typedef U16Type value_type;
typedef value_type const* pointer;
typedef value_type const reference;
typedef std::bidirectional_iterator_tag iterator_category;
reference operator*()const
{
if(m_current == 2)
extract_current();
return m_values[m_current];
}
bool operator==(const u32_to_u16_iterator& that)const
{
if(m_position == that.m_position)
{
// Both m_currents must be equal, or both even
// this is the same as saying their sum must be even:
return (m_current + that.m_current) & 1u ? false : true;
}
return false;
}
bool operator!=(const u32_to_u16_iterator& that)const
{
return !(*this == that);
}
u32_to_u16_iterator& operator++()
{
// if we have a pending read then read now, so that we know whether
// to skip a position, or move to a low-surrogate:
if(m_current == 2)
{
// pending read:
extract_current();
}
// move to the next surrogate position:
++m_current;
// if we've reached the end skip a position:
if(m_values[m_current] == 0)
{
m_current = 2;
++m_position;
}
return *this;
}
u32_to_u16_iterator operator++(int)
{
u32_to_u16_iterator r(*this);
++(*this);
return r;
}
u32_to_u16_iterator& operator--()
{
if(m_current != 1)
{
// decrementing an iterator always leads to a valid position:
--m_position;
extract_current();
m_current = m_values[1] ? 1 : 0;
}
else
{
m_current = 0;
}
return *this;
}
u32_to_u16_iterator operator--(int)
{
u32_to_u16_iterator r(*this);
--(*this);
return r;
}
BaseIterator base()const
{
return m_position;
}
// construct:
u32_to_u16_iterator() : m_position(), m_current(0)
{
m_values[0] = 0;
m_values[1] = 0;
m_values[2] = 0;
}
u32_to_u16_iterator(BaseIterator b) : m_position(b), m_current(2)
{
m_values[0] = 0;
m_values[1] = 0;
m_values[2] = 0;
}
private:
void extract_current()const
{
// begin by checking for a code point out of range:
std::uint32_t v = *m_position;
if(v >= 0x10000u)
{
if(v > 0x10FFFFu)
detail::invalid_utf32_code_point(*m_position);
// split into two surrogates:
m_values[0] = static_cast<U16Type>(v >> 10) + detail::high_surrogate_base;
m_values[1] = static_cast<U16Type>(v & detail::ten_bit_mask) + detail::low_surrogate_base;
m_current = 0;
BOOST_REGEX_ASSERT(detail::is_high_surrogate(m_values[0]));
BOOST_REGEX_ASSERT(detail::is_low_surrogate(m_values[1]));
}
else
{
// 16-bit code point:
m_values[0] = static_cast<U16Type>(*m_position);
m_values[1] = 0;
m_current = 0;
// value must not be a surrogate:
if(detail::is_surrogate(m_values[0]))
detail::invalid_utf32_code_point(*m_position);
}
}
BaseIterator m_position;
mutable U16Type m_values[3];
mutable unsigned m_current;
};
template <class BaseIterator, class U32Type = std::uint32_t>
class u16_to_u32_iterator
{
// special values for pending iterator reads:
static const U32Type pending_read = 0xffffffffu;
typedef typename std::iterator_traits<BaseIterator>::value_type base_value_type;
static_assert(sizeof(base_value_type)*CHAR_BIT == 16, "Incorrectly sized template argument");
static_assert(sizeof(U32Type)*CHAR_BIT == 32, "Incorrectly sized template argument");
public:
typedef std::ptrdiff_t difference_type;
typedef U32Type value_type;
typedef value_type const* pointer;
typedef value_type const reference;
typedef std::bidirectional_iterator_tag iterator_category;
reference operator*()const
{
if(m_value == pending_read)
extract_current();
return m_value;
}
bool operator==(const u16_to_u32_iterator& that)const
{
return m_position == that.m_position;
}
bool operator!=(const u16_to_u32_iterator& that)const
{
return !(*this == that);
}
u16_to_u32_iterator& operator++()
{
// skip high surrogate first if there is one:
if(detail::is_high_surrogate(*m_position)) ++m_position;
++m_position;
m_value = pending_read;
return *this;
}
u16_to_u32_iterator operator++(int)
{
u16_to_u32_iterator r(*this);
++(*this);
return r;
}
u16_to_u32_iterator& operator--()
{
--m_position;
// if we have a low surrogate then go back one more:
if(detail::is_low_surrogate(*m_position))
--m_position;
m_value = pending_read;
return *this;
}
u16_to_u32_iterator operator--(int)
{
u16_to_u32_iterator r(*this);
--(*this);
return r;
}
BaseIterator base()const
{
return m_position;
}
// construct:
u16_to_u32_iterator() : m_position()
{
m_value = pending_read;
}
u16_to_u32_iterator(BaseIterator b) : m_position(b)
{
m_value = pending_read;
}
//
// Range checked version:
//
u16_to_u32_iterator(BaseIterator b, BaseIterator start, BaseIterator end) : m_position(b)
{
m_value = pending_read;
//
// The range must not start with a low surrogate, or end in a high surrogate,
// otherwise we run the risk of running outside the underlying input range.
// Likewise b must not be located at a low surrogate.
//
std::uint16_t val;
if(start != end)
{
if((b != start) && (b != end))
{
val = *b;
if(detail::is_surrogate(val) && ((val & 0xFC00u) == 0xDC00u))
invalid_code_point(val);
}
val = *start;
if(detail::is_surrogate(val) && ((val & 0xFC00u) == 0xDC00u))
invalid_code_point(val);
val = *--end;
if(detail::is_high_surrogate(val))
invalid_code_point(val);
}
}
private:
static void invalid_code_point(std::uint16_t val)
{
std::stringstream ss;
ss << "Misplaced UTF-16 surrogate U+" << std::showbase << std::hex << val << " encountered while trying to encode UTF-32 sequence";
std::out_of_range e(ss.str());
#ifndef BOOST_REGEX_STANDALONE
boost::throw_exception(e);
#else
throw e;
#endif
}
void extract_current()const
{
m_value = static_cast<U32Type>(static_cast< std::uint16_t>(*m_position));
// if the last value is a high surrogate then adjust m_position and m_value as needed:
if(detail::is_high_surrogate(*m_position))
{
// precondition; next value must have be a low-surrogate:
BaseIterator next(m_position);
std::uint16_t t = *++next;
if((t & 0xFC00u) != 0xDC00u)
invalid_code_point(t);
m_value = (m_value - detail::high_surrogate_base) << 10;
m_value |= (static_cast<U32Type>(static_cast< std::uint16_t>(t)) & detail::ten_bit_mask);
}
// postcondition; result must not be a surrogate:
if(detail::is_surrogate(m_value))
invalid_code_point(static_cast< std::uint16_t>(m_value));
}
BaseIterator m_position;
mutable U32Type m_value;
};
template <class BaseIterator, class U8Type = std::uint8_t>
class u32_to_u8_iterator
{
typedef typename std::iterator_traits<BaseIterator>::value_type base_value_type;
static_assert(sizeof(base_value_type)*CHAR_BIT == 32, "Incorrectly sized template argument");
static_assert(sizeof(U8Type)*CHAR_BIT == 8, "Incorrectly sized template argument");
public:
typedef std::ptrdiff_t difference_type;
typedef U8Type value_type;
typedef value_type const* pointer;
typedef value_type const reference;
typedef std::bidirectional_iterator_tag iterator_category;
reference operator*()const
{
if(m_current == 4)
extract_current();
return m_values[m_current];
}
bool operator==(const u32_to_u8_iterator& that)const
{
if(m_position == that.m_position)
{
// either the m_current's must be equal, or one must be 0 and
// the other 4: which means neither must have bits 1 or 2 set:
return (m_current == that.m_current)
|| (((m_current | that.m_current) & 3) == 0);
}
return false;
}
bool operator!=(const u32_to_u8_iterator& that)const
{
return !(*this == that);
}
u32_to_u8_iterator& operator++()
{
// if we have a pending read then read now, so that we know whether
// to skip a position, or move to a low-surrogate:
if(m_current == 4)
{
// pending read:
extract_current();
}
// move to the next surrogate position:
++m_current;
// if we've reached the end skip a position:
if(m_values[m_current] == 0)
{
m_current = 4;
++m_position;
}
return *this;
}
u32_to_u8_iterator operator++(int)
{
u32_to_u8_iterator r(*this);
++(*this);
return r;
}
u32_to_u8_iterator& operator--()
{
if((m_current & 3) == 0)
{
--m_position;
extract_current();
m_current = 3;
while(m_current && (m_values[m_current] == 0))
--m_current;
}
else
--m_current;
return *this;
}
u32_to_u8_iterator operator--(int)
{
u32_to_u8_iterator r(*this);
--(*this);
return r;
}
BaseIterator base()const
{
return m_position;
}
// construct:
u32_to_u8_iterator() : m_position(), m_current(0)
{
m_values[0] = 0;
m_values[1] = 0;
m_values[2] = 0;
m_values[3] = 0;
m_values[4] = 0;
}
u32_to_u8_iterator(BaseIterator b) : m_position(b), m_current(4)
{
m_values[0] = 0;
m_values[1] = 0;
m_values[2] = 0;
m_values[3] = 0;
m_values[4] = 0;
}
private:
void extract_current()const
{
std::uint32_t c = *m_position;
if(c > 0x10FFFFu)
detail::invalid_utf32_code_point(c);
if(c < 0x80u)
{
m_values[0] = static_cast<unsigned char>(c);
m_values[1] = static_cast<unsigned char>(0u);
m_values[2] = static_cast<unsigned char>(0u);
m_values[3] = static_cast<unsigned char>(0u);
}
else if(c < 0x800u)
{
m_values[0] = static_cast<unsigned char>(0xC0u + (c >> 6));
m_values[1] = static_cast<unsigned char>(0x80u + (c & 0x3Fu));
m_values[2] = static_cast<unsigned char>(0u);
m_values[3] = static_cast<unsigned char>(0u);
}
else if(c < 0x10000u)
{
m_values[0] = static_cast<unsigned char>(0xE0u + (c >> 12));
m_values[1] = static_cast<unsigned char>(0x80u + ((c >> 6) & 0x3Fu));
m_values[2] = static_cast<unsigned char>(0x80u + (c & 0x3Fu));
m_values[3] = static_cast<unsigned char>(0u);
}
else
{
m_values[0] = static_cast<unsigned char>(0xF0u + (c >> 18));
m_values[1] = static_cast<unsigned char>(0x80u + ((c >> 12) & 0x3Fu));
m_values[2] = static_cast<unsigned char>(0x80u + ((c >> 6) & 0x3Fu));
m_values[3] = static_cast<unsigned char>(0x80u + (c & 0x3Fu));
}
m_current= 0;
}
BaseIterator m_position;
mutable U8Type m_values[5];
mutable unsigned m_current;
};
template <class BaseIterator, class U32Type = std::uint32_t>
class u8_to_u32_iterator
{
// special values for pending iterator reads:
static const U32Type pending_read = 0xffffffffu;
typedef typename std::iterator_traits<BaseIterator>::value_type base_value_type;
static_assert(sizeof(base_value_type)*CHAR_BIT == 8, "Incorrectly sized template argument");
static_assert(sizeof(U32Type)*CHAR_BIT == 32, "Incorrectly sized template argument");
public:
typedef std::ptrdiff_t difference_type;
typedef U32Type value_type;
typedef value_type const* pointer;
typedef value_type const reference;
typedef std::bidirectional_iterator_tag iterator_category;
reference operator*()const
{
if(m_value == pending_read)
extract_current();
return m_value;
}
bool operator==(const u8_to_u32_iterator& that)const
{
return m_position == that.m_position;
}
bool operator!=(const u8_to_u32_iterator& that)const
{
return !(*this == that);
}
u8_to_u32_iterator& operator++()
{
// We must not start with a continuation character:
if((static_cast<std::uint8_t>(*m_position) & 0xC0) == 0x80)
invalid_sequence();
// skip high surrogate first if there is one:
unsigned c = detail::utf8_byte_count(*m_position);
if(m_value == pending_read)
{
// Since we haven't read in a value, we need to validate the code points:
for(unsigned i = 0; i < c; ++i)
{
++m_position;
// We must have a continuation byte:
if((i != c - 1) && ((static_cast<std::uint8_t>(*m_position) & 0xC0) != 0x80))
invalid_sequence();
}
}
else
{
std::advance(m_position, c);
}
m_value = pending_read;
return *this;
}
u8_to_u32_iterator operator++(int)
{
u8_to_u32_iterator r(*this);
++(*this);
return r;
}
u8_to_u32_iterator& operator--()
{
// Keep backtracking until we don't have a trailing character:
unsigned count = 0;
while((*--m_position & 0xC0u) == 0x80u) ++count;
// now check that the sequence was valid:
if(count != detail::utf8_trailing_byte_count(*m_position))
invalid_sequence();
m_value = pending_read;
return *this;
}
u8_to_u32_iterator operator--(int)
{
u8_to_u32_iterator r(*this);
--(*this);
return r;
}
BaseIterator base()const
{
return m_position;
}
// construct:
u8_to_u32_iterator() : m_position()
{
m_value = pending_read;
}
u8_to_u32_iterator(BaseIterator b) : m_position(b)
{
m_value = pending_read;
}
//
// Checked constructor:
//
u8_to_u32_iterator(BaseIterator b, BaseIterator start, BaseIterator end) : m_position(b)
{
m_value = pending_read;
//
// We must not start with a continuation character, or end with a
// truncated UTF-8 sequence otherwise we run the risk of going past
// the start/end of the underlying sequence:
//
if(start != end)
{
unsigned char v = *start;
if((v & 0xC0u) == 0x80u)
invalid_sequence();
if((b != start) && (b != end) && ((*b & 0xC0u) == 0x80u))
invalid_sequence();
BaseIterator pos = end;
do
{
v = *--pos;
}
while((start != pos) && ((v & 0xC0u) == 0x80u));
std::ptrdiff_t extra = detail::utf8_byte_count(v);
if(std::distance(pos, end) < extra)
invalid_sequence();
}
}
private:
static void invalid_sequence()
{
std::out_of_range e("Invalid UTF-8 sequence encountered while trying to encode UTF-32 character");
#ifndef BOOST_REGEX_STANDALONE
boost::throw_exception(e);
#else
throw e;
#endif
}
void extract_current()const
{
m_value = static_cast<U32Type>(static_cast< std::uint8_t>(*m_position));
// we must not have a continuation character:
if((m_value & 0xC0u) == 0x80u)
invalid_sequence();
// see how many extra bytes we have:
unsigned extra = detail::utf8_trailing_byte_count(*m_position);
// extract the extra bits, 6 from each extra byte:
BaseIterator next(m_position);
for(unsigned c = 0; c < extra; ++c)
{
++next;
m_value <<= 6;
// We must have a continuation byte:
if((static_cast<std::uint8_t>(*next) & 0xC0) != 0x80)
invalid_sequence();
m_value += static_cast<std::uint8_t>(*next) & 0x3Fu;
}
// we now need to remove a few of the leftmost bits, but how many depends
// upon how many extra bytes we've extracted:
static const std::uint32_t masks[4] =
{
0x7Fu,
0x7FFu,
0xFFFFu,
0x1FFFFFu,
};
m_value &= masks[extra];
// check the result is in range:
if(m_value > static_cast<U32Type>(0x10FFFFu))
invalid_sequence();
// The result must not be a surrogate:
if((m_value >= static_cast<U32Type>(0xD800)) && (m_value <= static_cast<U32Type>(0xDFFF)))
invalid_sequence();
// We should not have had an invalidly encoded UTF8 sequence:
if((extra > 0) && (m_value <= static_cast<U32Type>(masks[extra - 1])))
invalid_sequence();
}
BaseIterator m_position;
mutable U32Type m_value;
};
template <class BaseIterator>
class utf16_output_iterator
{
public:
typedef void difference_type;
typedef void value_type;
typedef std::uint32_t* pointer;
typedef std::uint32_t& reference;
typedef std::output_iterator_tag iterator_category;
utf16_output_iterator(const BaseIterator& b)
: m_position(b){}
utf16_output_iterator(const utf16_output_iterator& that)
: m_position(that.m_position){}
utf16_output_iterator& operator=(const utf16_output_iterator& that)
{
m_position = that.m_position;
return *this;
}
const utf16_output_iterator& operator*()const
{
return *this;
}
void operator=(std::uint32_t val)const
{
push(val);
}
utf16_output_iterator& operator++()
{
return *this;
}
utf16_output_iterator& operator++(int)
{
return *this;
}
BaseIterator base()const
{
return m_position;
}
private:
void push(std::uint32_t v)const
{
if(v >= 0x10000u)
{
// begin by checking for a code point out of range:
if(v > 0x10FFFFu)
detail::invalid_utf32_code_point(v);
// split into two surrogates:
*m_position++ = static_cast<std::uint16_t>(v >> 10) + detail::high_surrogate_base;
*m_position++ = static_cast<std::uint16_t>(v & detail::ten_bit_mask) + detail::low_surrogate_base;
}
else
{
// 16-bit code point:
// value must not be a surrogate:
if(detail::is_surrogate(v))
detail::invalid_utf32_code_point(v);
*m_position++ = static_cast<std::uint16_t>(v);
}
}
mutable BaseIterator m_position;
};
template <class BaseIterator>
class utf8_output_iterator
{
public:
typedef void difference_type;
typedef void value_type;
typedef std::uint32_t* pointer;
typedef std::uint32_t& reference;
typedef std::output_iterator_tag iterator_category;
utf8_output_iterator(const BaseIterator& b)
: m_position(b){}
utf8_output_iterator(const utf8_output_iterator& that)
: m_position(that.m_position){}
utf8_output_iterator& operator=(const utf8_output_iterator& that)
{
m_position = that.m_position;
return *this;
}
const utf8_output_iterator& operator*()const
{
return *this;
}
void operator=(std::uint32_t val)const
{
push(val);
}
utf8_output_iterator& operator++()
{
return *this;
}
utf8_output_iterator& operator++(int)
{
return *this;
}
BaseIterator base()const
{
return m_position;
}
private:
void push(std::uint32_t c)const
{
if(c > 0x10FFFFu)
detail::invalid_utf32_code_point(c);
if(c < 0x80u)
{
*m_position++ = static_cast<unsigned char>(c);
}
else if(c < 0x800u)
{
*m_position++ = static_cast<unsigned char>(0xC0u + (c >> 6));
*m_position++ = static_cast<unsigned char>(0x80u + (c & 0x3Fu));
}
else if(c < 0x10000u)
{
*m_position++ = static_cast<unsigned char>(0xE0u + (c >> 12));
*m_position++ = static_cast<unsigned char>(0x80u + ((c >> 6) & 0x3Fu));
*m_position++ = static_cast<unsigned char>(0x80u + (c & 0x3Fu));
}
else
{
*m_position++ = static_cast<unsigned char>(0xF0u + (c >> 18));
*m_position++ = static_cast<unsigned char>(0x80u + ((c >> 12) & 0x3Fu));
*m_position++ = static_cast<unsigned char>(0x80u + ((c >> 6) & 0x3Fu));
*m_position++ = static_cast<unsigned char>(0x80u + (c & 0x3Fu));
}
}
mutable BaseIterator m_position;
};
} // namespace boost
#endif // BOOST_REGEX_UNICODE_ITERATOR_HPP

File diff suppressed because it is too large Load Diff

View File

@@ -1,37 +0,0 @@
/*
*
* Copyright (c) 1998-2002
* John Maddock
*
* Use, modification and distribution are subject to 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)
*
*/
/*
* LOCATION: see http://www.boost.org/libs/regex for documentation.
* FILE regex_fwd.cpp
* VERSION see <boost/version.hpp>
* DESCRIPTION: Forward declares boost::basic_regex<> and
* associated typedefs.
*/
#ifndef BOOST_REGEX_FWD_HPP
#define BOOST_REGEX_FWD_HPP
#ifndef BOOST_REGEX_CONFIG_HPP
#include <boost/regex/config.hpp>
#endif
#ifdef BOOST_REGEX_CXX03
#include <boost/regex/v4/regex_fwd.hpp>
#else
#include <boost/regex/v5/regex_fwd.hpp>
#endif
#endif

View File

@@ -1,21 +0,0 @@
Copyright (c) 1998-2003
John Maddock
* Use, modification and distribution are subject to 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)
************************************************************************
Full instructions for use of this library can be accessed from
libs/regex/docs/index.html
Installation instructions and library overview is are in
libs/regex/docs/introduction.html
This library is part of boost (see www.boost.org), the latest version
of the library is available from the boost web site, or development
snapshots from the boost cvs repository at
http://sourceforge.net/project/?group_id=7586

View File

@@ -313,11 +313,10 @@ const std::map<std::string, char> compound_factory::kBaseMap{
class compound_factory_impl : public std::enable_shared_from_this<compound_factory_impl>
{
public:
compound_factory_impl(std::shared_ptr<compound_factory_impl> next);
compound_factory_impl();
compound_factory_impl(const fs::path &file, std::shared_ptr<compound_factory_impl> next);
virtual ~compound_factory_impl()
~compound_factory_impl()
{
for (auto c : m_compounds)
delete c;
@@ -331,7 +330,7 @@ class compound_factory_impl : public std::enable_shared_from_this<compound_facto
compound *result = nullptr;
// walk the list, see if any of us has the compound already
// walk the list, see if any of the implementations has the compound already
for (auto impl = shared_from_this(); impl; impl = impl->m_next)
{
for (auto cmp : impl->m_compounds)
@@ -363,155 +362,52 @@ class compound_factory_impl : public std::enable_shared_from_this<compound_facto
return result;
}
std::shared_ptr<compound_factory_impl> next() const
std::shared_ptr<compound_factory_impl> next()
{
return m_next;
}
bool is_known_peptide(const std::string &resName)
void describe(std::ostream &os)
{
return m_known_peptides.count(resName) or
(m_next and m_next->is_known_peptide(resName));
if (m_file.empty())
os << "CCD components.cif resource\n";
else
os << "CCD components file: " << std::quoted(m_file.string()) << '\n';
if (m_next)
m_next->describe(os);
}
bool is_known_base(const std::string &resName)
{
return m_known_bases.count(resName) or
(m_next and m_next->is_known_base(resName));
}
protected:
virtual compound *create(const std::string &id)
{
// For the base class we assume every compound is preloaded
return nullptr;
}
private:
compound *create(const std::string &id);
std::shared_timed_mutex mMutex;
fs::path m_file;
cif::parser::datablock_index m_index;
std::vector<compound *> m_compounds;
std::set<std::string> m_known_peptides;
std::set<std::string> m_known_bases;
std::set<std::string> m_missing;
std::shared_ptr<compound_factory_impl> m_next;
};
// --------------------------------------------------------------------
compound_factory_impl::compound_factory_impl(std::shared_ptr<compound_factory_impl> next)
: m_next(next)
compound_factory_impl::compound_factory_impl()
{
for (const auto &[key, value] : compound_factory::kAAMap)
m_known_peptides.insert(key);
for (const auto &[key, value] : compound_factory::kBaseMap)
m_known_bases.insert(key);
}
compound_factory_impl::compound_factory_impl(const fs::path &file, std::shared_ptr<compound_factory_impl> next)
: m_next(next)
: m_file(file)
, m_next(next)
{
cif::file cifFile(file);
if (cifFile.contains("comp_list")) // So this is a CCP4 restraints file, special handling
{
auto &compList = cifFile["comp_list"];
auto &chemComp = compList["chem_comp"];
for (const auto &[id, name, group] : chemComp.rows<std::string, std::string, std::string>("id", "name", "group"))
{
std::string type;
// known groups are (counted from ccp4 monomer dictionary)
// D-pyranose
// DNA
// L-PEPTIDE LINKING
// L-SACCHARIDE
// L-peptide
// L-pyranose
// M-peptide
// NON-POLYMER
// P-peptide
// RNA
// furanose
// non-polymer
// non_polymer
// peptide
// pyranose
// saccharide
if (cif::iequals(id, "gly"))
type = "peptide linking";
else if (cif::iequals(group, "l-peptide") or cif::iequals(group, "L-peptide linking") or cif::iequals(group, "peptide") or cif::iequals(group, "p-peptide"))
type = "L-peptide linking";
else if (cif::iequals(group, "DNA"))
type = "DNA linking";
else if (cif::iequals(group, "RNA"))
type = "RNA linking";
else
type = "non-polymer";
auto &db = cifFile["comp_" + id];
m_compounds.push_back(new compound(db, id, name, type, group));
}
}
else
{
// A CCD components file, validate it first
try
{
cifFile.load_dictionary("mmcif_pdbx.dic");
if (not cifFile.is_valid())
{
std::cerr << "The components file " << file << " is not valid\n";
if (cif::VERBOSE < 1)
std::cerr << "(use --verbose to see why)\n";
}
}
catch (const std::exception &e)
{
std::cerr << "When trying to load the components file " << file << " there was an exception:\n"
<< e.what() << '\n';
}
for (auto &db : cifFile)
m_compounds.push_back(new compound(db));
}
}
// --------------------------------------------------------------------
// Version for the default compounds, based on the cached components.cif file from CCD
class CCD_compound_factory_impl : public compound_factory_impl
{
public:
CCD_compound_factory_impl(std::shared_ptr<compound_factory_impl> next, const fs::path &file)
: compound_factory_impl(next)
, mCompoundsFile(file)
{
}
CCD_compound_factory_impl(std::shared_ptr<compound_factory_impl> next)
: compound_factory_impl(next)
{
}
compound *create(const std::string &id) override;
cif::parser::datablock_index mIndex;
fs::path mCompoundsFile;
};
compound *CCD_compound_factory_impl::create(const std::string &id)
compound *compound_factory_impl::create(const std::string &id)
{
compound *result = nullptr;
std::unique_ptr<std::istream> ccd;
if (mCompoundsFile.empty())
if (m_file.empty())
{
ccd = cif::load_resource("components.cif");
if (not ccd)
@@ -521,11 +417,11 @@ compound *CCD_compound_factory_impl::create(const std::string &id)
}
}
else
ccd.reset(new std::ifstream(mCompoundsFile));
ccd.reset(new std::ifstream(m_file));
cif::file file;
if (mIndex.empty())
if (m_index.empty())
{
if (cif::VERBOSE > 1)
{
@@ -535,20 +431,20 @@ compound *CCD_compound_factory_impl::create(const std::string &id)
}
cif::parser parser(*ccd, file);
mIndex = parser.index_datablocks();
m_index = parser.index_datablocks();
if (cif::VERBOSE > 1)
std::cout << " done" << std::endl;
// reload the resource, perhaps this should be improved...
if (mCompoundsFile.empty())
if (m_file.empty())
{
ccd = cif::load_resource("components.cif");
if (not ccd)
throw std::runtime_error("Could not locate the CCD components.cif file, please make sure the software is installed properly and/or use the update-libcifpp-data to fetch the data.");
}
else
ccd.reset(new std::ifstream(mCompoundsFile));
ccd.reset(new std::ifstream(m_file));
}
if (cif::VERBOSE > 1)
@@ -558,7 +454,7 @@ compound *CCD_compound_factory_impl::create(const std::string &id)
}
cif::parser parser(*ccd, file);
parser.parse_single_datablock(id, mIndex);
parser.parse_single_datablock(id, m_index);
if (cif::VERBOSE > 1)
std::cout << " done" << std::endl;
@@ -575,111 +471,6 @@ compound *CCD_compound_factory_impl::create(const std::string &id)
}
}
if (result == nullptr and cif::VERBOSE > 0)
std::cerr << "Could not locate compound " << id << " in the CCD components file\n";
return result;
}
// --------------------------------------------------------------------
// Version for the default compounds, based on the data found in CCP4's monomers lib
class CCP4_compound_factory_impl : public compound_factory_impl
{
public:
CCP4_compound_factory_impl(const fs::path &clibd_mon, std::shared_ptr<compound_factory_impl> next = nullptr);
compound *create(const std::string &id) override;
private:
cif::file m_file;
fs::path m_CLIBD_MON;
};
CCP4_compound_factory_impl::CCP4_compound_factory_impl(const fs::path &clibd_mon, std::shared_ptr<compound_factory_impl> next)
: compound_factory_impl(next)
, m_file((clibd_mon / "list" / "mon_lib_list.cif").string())
, m_CLIBD_MON(clibd_mon)
{
const std::regex peptideRx("(?:[lmp]-)?peptide", std::regex::icase);
auto &chemComps = m_file["comp_list"]["chem_comp"];
for (const auto &[group, comp_id] : chemComps.rows<std::string, std::string>("group", "id"))
{
if (std::regex_match(group, peptideRx))
m_known_peptides.insert(comp_id);
else if (cif::iequals(group, "DNA") or cif::iequals(group, "RNA"))
m_known_bases.insert(comp_id);
}
}
compound *CCP4_compound_factory_impl::create(const std::string &id)
{
compound *result = nullptr;
auto &cat = m_file["comp_list"]["chem_comp"];
auto rs = cat.find(cif::key("id") == id);
if (rs.size() == 1)
{
auto row = rs.front();
std::string name, group;
uint32_t numberAtomsAll, numberAtomsNh;
cif::tie(name, group, numberAtomsAll, numberAtomsNh) =
row.get("name", "group", "number_atoms_all", "number_atoms_nh");
fs::path resFile = m_CLIBD_MON / cif::to_lower_copy(id.substr(0, 1)) / (id + ".cif");
if (not fs::exists(resFile) and (id == "COM" or id == "CON" or "PRN")) // seriously...
resFile = m_CLIBD_MON / cif::to_lower_copy(id.substr(0, 1)) / (id + '_' + id + ".cif");
if (fs::exists(resFile))
{
cif::file cf(resFile.string());
// locate the datablock
auto &db = cf["comp_" + id];
std::string type;
// known groups are (counted from ccp4 monomer dictionary)
// D-pyranose
// DNA
// L-PEPTIDE LINKING
// L-SACCHARIDE
// L-peptide
// L-pyranose
// M-peptide
// NON-POLYMER
// P-peptide
// RNA
// furanose
// non-polymer
// non_polymer
// peptide
// pyranose
// saccharide
if (cif::iequals(id, "gly"))
type = "peptide linking";
else if (cif::iequals(group, "l-peptide") or cif::iequals(group, "L-peptide linking") or cif::iequals(group, "peptide") or cif::iequals(group, "p-peptide"))
type = "L-peptide linking";
else if (cif::iequals(group, "DNA"))
type = "DNA linking";
else if (cif::iequals(group, "RNA"))
type = "RNA linking";
else
type = "non-polymer";
m_compounds.push_back(new compound(db, id, name, type, group));
result = m_compounds.back();
}
}
return result;
}
@@ -699,15 +490,9 @@ compound_factory::compound_factory()
{
auto ccd = cif::load_resource("components.cif");
if (ccd)
m_impl = std::make_shared<CCD_compound_factory_impl>(m_impl);
m_impl = std::make_shared<compound_factory_impl>();
else if (cif::VERBOSE > 0)
std::cerr << "CCD components.cif file was not found\n";
const char *clibd_mon = getenv("CLIBD_MON");
if (clibd_mon != nullptr and fs::is_directory(clibd_mon))
m_impl = std::make_shared<CCP4_compound_factory_impl>(clibd_mon, m_impl);
else if (cif::VERBOSE > 0)
std::cerr << "CCP4 monomers library not found, CLIBD_MON is not defined\n";
std::cerr << "CCD components.cif resource was not found\n";
}
compound_factory::~compound_factory()
@@ -745,7 +530,7 @@ void compound_factory::set_default_dictionary(const fs::path &inDictFile)
try
{
m_impl.reset(new CCD_compound_factory_impl(m_impl, inDictFile));
m_impl.reset(new compound_factory_impl(inDictFile, m_impl));
}
catch (const std::exception &)
{
@@ -776,17 +561,63 @@ void compound_factory::pop_dictionary()
const compound *compound_factory::create(std::string id)
{
return m_impl ? m_impl->get(id) : nullptr;
auto result = m_impl ? m_impl->get(id) : nullptr;
if (not result)
report_missing_compound(id);
return result;
}
bool compound_factory::is_known_peptide(const std::string &resName) const
{
return m_impl ? m_impl->is_known_peptide(resName) : kAAMap.count(resName) > 0;
return kAAMap.count(resName) > 0;
}
bool compound_factory::is_known_base(const std::string &resName) const
{
return m_impl ? m_impl->is_known_base(resName) : kBaseMap.count(resName) > 0;
return kBaseMap.count(resName) > 0;
}
void compound_factory::report_missing_compound(const std::string &compound_id)
{
static bool s_reported = false;
if (std::exchange(s_reported, true) == false)
{
using namespace cif::colour;
std::clog << "\n" << cif::coloured("Configuration error:", white, red) << "\n\n"
<< "The attempt to retrieve compound information for " << std::quoted(compound_id) << " failed.\n\n"
<< "This information is searched for in a CCD file called components.cif or\n"
<< "components.cif.gz which should be located in one of the following directories:\n\n";
cif::list_data_directories(std::clog);
std::clog << "\n(Note that you can add a directory to the search paths by setting the \n"
<< "LIBCIFPP_DATA_DIR environmental variable)\n\n";
#if defined(CACHE_DIR)
std::clog << "On Linux an optional cron script might have been installed that automatically updates\n"
<< "components.cif and mmCIF dictionary files. This script only works when the file\n"
<< "libcifpp.conf contains an uncommented line with the text:\n\n"
<< "update=true\n\n"
<< "If you do not have a working cron script, you can manually update the files\n"
<< "in /var/cache/libcifpp using the following commands:\n\n"
<< "curl -o " << CACHE_DIR << "/components.cif https://ftp.wwpdb.org/pub/pdb/data/monomers/components.cif.gz\n"
<< "curl -o " << CACHE_DIR << "/mmcif_pdbx.dic https://mmcif.wwpdb.org/dictionaries/ascii/mmcif_pdbx_v50.dic.gz\n"
<< "curl -o " << CACHE_DIR << "/mmcif_ma.dic https://github.com/ihmwg/ModelCIF/raw/master/dist/mmcif_ma.dic\n\n";
#endif
if (m_impl)
{
std::clog << "The current order of compound factory objects is:\n\n";
m_impl->describe(std::clog);
}
else
std::clog << "No compound factory objects are created since none of the data sources is found.\n";
cif::list_file_resources(std::clog);
std::clog.flush();
}
}
} // namespace cif

View File

@@ -2006,7 +2006,10 @@ void structure::change_residue(residue &res, const std::string &newCompound,
continue;
if (a2.empty() or a2 == ".")
{
i->set_property("label_comp_id", newCompound);
remove_atom(*i);
}
else if (a1 != a2)
{
auto ra = r.front();

View File

@@ -608,6 +608,9 @@ sac_parser::datablock_index sac_parser::index_datablocks()
std::string::size_type si = 0;
std::string datablock;
// Seek to beginning of file
m_source.pubseekpos(0);
for (auto ch = m_source.sbumpc(); ch != std::streambuf::traits_type::eof(); ch = m_source.sbumpc())
{
switch (state)
@@ -667,7 +670,7 @@ sac_parser::datablock_index sac_parser::index_datablocks()
case data_name:
if (is_non_blank(ch))
datablock.insert(datablock.end(), char(ch));
datablock.insert(datablock.end(), (char)std::toupper(ch));
else if (is_space(ch))
{
if (not datablock.empty())

View File

@@ -5146,7 +5146,7 @@ void PDBFileParser::ParseConnectivtyAnnotation()
getCategory("struct_conn")->emplace({
{ "id", type + std::to_string(linkNr) },
{ "conn_type_id", type },
{ "conn_type_id", type },
// { "ccp4_link_id", ccp4LinkID },

View File

@@ -845,6 +845,9 @@ class resource_pool
std::unique_ptr<std::istream> load(fs::path name);
const auto data_directories() { return mDirs; }
const auto file_resources() { return mLocalResources; }
private:
resource_pool();
@@ -937,4 +940,22 @@ std::unique_ptr<std::istream> load_resource(std::filesystem::path name)
return resource_pool::instance().load(name);
}
void list_file_resources(std::ostream &os)
{
auto &file_resources = resource_pool::instance().file_resources();
if (not file_resources.empty())
{
os << "\nThe following named resources were loaded:\n";
for (const auto &[name, path] : file_resources)
os << name << " -> " << std::quoted(path.string()) << '\n';
}
}
void list_data_directories(std::ostream &os)
{
for (auto &p : resource_pool::instance().data_directories())
os << p << '\n';
}
} // namespace cif

View File

@@ -381,6 +381,12 @@ void validator::report_error(const std::string &msg, bool fatal) const
// --------------------------------------------------------------------
validator_factory &validator_factory::instance()
{
static validator_factory s_instance;
return s_instance;
}
const validator &validator_factory::operator[](std::string_view dictionary_name)
{
try

Binary file not shown.

View File

@@ -24,69 +24,29 @@
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#define BOOST_TEST_ALTERNATIVE_INIT_API
#include <boost/test/included/unit_test.hpp>
#include <catch2/catch.hpp>
#include <stdexcept>
#include <cif++.hpp>
namespace tt = boost::test_tools;
std::filesystem::path gTestDir = std::filesystem::current_path(); // filled in first test
// --------------------------------------------------------------------
cif::file operator""_cf(const char *text, size_t length)
{
struct membuf : public std::streambuf
{
membuf(char *text, size_t length)
{
this->setg(text, text, text + length);
}
} buffer(const_cast<char *>(text), length);
std::istream is(&buffer);
return cif::file(is);
}
// --------------------------------------------------------------------
bool init_unit_test()
{
cif::VERBOSE = 1;
// // not a test, just initialize test dir
// if (boost::unit_test::framework::master_test_suite().argc == 2)
// gTestDir = boost::unit_test::framework::master_test_suite().argv[1];
// // do this now, avoids the need for installing
// cif::add_file_resource("mmcif_pdbx.dic", gTestDir / ".." / "rsrc" / "mmcif_pdbx.dic");
// // initialize CCD location
// cif::add_file_resource("components.cif", gTestDir / ".." / "data" / "ccd-subset.cif");
return true;
}
// --------------------------------------------------------------------
BOOST_AUTO_TEST_CASE(fmt_1)
TEST_CASE("fmt_1")
{
std::ostringstream os;
std::string world("world");
os << cif::format("Hello, %-10.10s, the magic number is %d and pi is %g", world, 42, cif::kPI);
BOOST_CHECK_EQUAL(os.str(), "Hello, world , the magic number is 42 and pi is 3.14159");
REQUIRE(os.str() == "Hello, world , the magic number is 42 and pi is 3.14159");
BOOST_CHECK_EQUAL(cif::format("Hello, %-10.10s, the magic number is %d and pi is %g", world, 42, cif::kPI).str(),
REQUIRE(cif::format("Hello, %-10.10s, the magic number is %d and pi is %g", world, 42, cif::kPI).str() ==
"Hello, world , the magic number is 42 and pi is 3.14159");
}
// --------------------------------------------------------------------
BOOST_AUTO_TEST_CASE(clr_1)
TEST_CASE("clr_1")
{
using namespace cif::colour;

View File

@@ -1,17 +1,17 @@
/*-
* SPDX-License-Identifier: BSD-2-Clause
*
*
* Copyright (c) 2021 NKI/AVL, Netherlands Cancer Institute
*
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
*
* 1. Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
@@ -24,8 +24,9 @@
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#define BOOST_TEST_ALTERNATIVE_INIT_API
#include <boost/test/included/unit_test.hpp>
#include "test-main.hpp"
#include <catch2/catch.hpp>
#include <stdexcept>
@@ -33,59 +34,30 @@
// --------------------------------------------------------------------
cif::file operator""_cf(const char* text, size_t length)
cif::file operator""_cf(const char *text, size_t length)
{
struct membuf : public std::streambuf
{
membuf(char* text, size_t length)
{
this->setg(text, text, text + length);
}
} buffer(const_cast<char*>(text), length);
std::istream is(&buffer);
return cif::file(is);
}
// --------------------------------------------------------------------
std::filesystem::path gTestDir = std::filesystem::current_path();
bool init_unit_test()
{
cif::VERBOSE = 1;
// not a test, just initialize test dir
if (boost::unit_test::framework::master_test_suite().argc == 2)
gTestDir = boost::unit_test::framework::master_test_suite().argv[1];
else
struct membuf : public std::streambuf
{
while (not gTestDir.empty() and not std::filesystem::exists(gTestDir / "test"))
gTestDir = gTestDir.parent_path();
gTestDir /= "test";
}
membuf(char *text, size_t length)
{
this->setg(text, text, text + length);
}
} buffer(const_cast<char *>(text), length);
// do this now, avoids the need for installing
cif::add_file_resource("mmcif_pdbx.dic", gTestDir / ".." / "rsrc" / "mmcif_pdbx.dic");
// initialize CCD location
cif::add_file_resource("components.cif", gTestDir / ".." / "data" / "ccd-subset.cif");
cif::compound_factory::instance().push_dictionary(gTestDir / "HEM.cif");
return true;
std::istream is(&buffer);
return cif::file(is);
}
// --------------------------------------------------------------------
BOOST_AUTO_TEST_CASE(create_nonpoly_1)
TEST_CASE("create_nonpoly_1")
{
cif::VERBOSE = 1;
cif::VERBOSE = 1;
cif::file file;
file.load_dictionary("mmcif_pdbx.dic");
file.emplace("TEST"); // create a datablock
file.emplace("TEST"); // create a datablock
cif::mm::structure structure(file);
std::string entity_id = structure.create_non_poly_entity("HEM");
@@ -119,7 +91,7 @@ _atom_site.pdbx_formal_charge
auto hem_atoms = atom_site.rows();
std::vector<cif::mm::atom> atom_data;
for (auto hem_atom: hem_atoms)
for (auto hem_atom : hem_atoms)
atom_data.emplace_back(hem_data, hem_atom);
structure.create_non_poly(entity_id, atom_data);
@@ -191,25 +163,25 @@ _atom_type.symbol C
expected.load_dictionary("mmcif_pdbx.dic");
if (not (expected.front() == structure.get_datablock()))
if (not(expected.front() == structure.get_datablock()))
{
BOOST_TEST(false);
REQUIRE(false);
std::cout << expected.front() << '\n'
<< '\n'
<< structure.get_datablock() << '\n';
<< '\n'
<< structure.get_datablock() << '\n';
}
}
// --------------------------------------------------------------------
BOOST_AUTO_TEST_CASE(create_nonpoly_2)
TEST_CASE("create_nonpoly_2")
{
cif::VERBOSE = 1;
cif::VERBOSE = 1;
cif::file file;
file.load_dictionary("mmcif_pdbx.dic");
file.emplace("TEST"); // create a datablock
file.emplace("TEST"); // create a datablock
cif::mm::structure structure(file);
cif::file lig(gTestDir / "HEM.cif");
@@ -218,8 +190,8 @@ BOOST_AUTO_TEST_CASE(create_nonpoly_2)
std::vector<cif::row_initializer> atoms;
for (const auto &[type_symbol, label_atom_id, Cartn_x, Cartn_y, Cartn_z] :
chem_comp_atom.rows<std::string,std::string,float,float,float>(
"type_symbol", "atom_id", "model_Cartn_x", "model_Cartn_y", "model_Cartn_z"))
chem_comp_atom.rows<std::string, std::string, float, float, float>(
"type_symbol", "atom_id", "model_Cartn_x", "model_Cartn_y", "model_Cartn_z"))
{
atoms.emplace_back(cif::row_initializer{
{ "type_symbol", type_symbol },
@@ -227,8 +199,7 @@ BOOST_AUTO_TEST_CASE(create_nonpoly_2)
{ "auth_atom_id", label_atom_id },
{ "Cartn_x", Cartn_x },
{ "Cartn_y", Cartn_y },
{ "Cartn_z", Cartn_z }
});
{ "Cartn_z", Cartn_z } });
if (atoms.size() == 4)
break;
@@ -303,23 +274,23 @@ _atom_type.symbol C
expected.load_dictionary("mmcif_pdbx.dic");
if (not (expected.front() == structure.get_datablock()))
REQUIRE(expected.front() == structure.get_datablock());
if (not(expected.front() == structure.get_datablock()))
{
BOOST_TEST(false);
// REQUIRE(false);
std::cout << expected.front() << '\n'
<< '\n'
<< structure.get_datablock() << '\n';
<< '\n'
<< structure.get_datablock() << '\n';
expected.save("/tmp/a");
file.save("/tmp/b");
}
}
// --------------------------------------------------------------------
BOOST_AUTO_TEST_CASE(test_atom_id)
TEST_CASE("test_atom_id")
{
auto data = R"(
data_TEST
@@ -389,15 +360,15 @@ _struct_asym.details ?
cif::mm::structure s(data);
BOOST_CHECK_EQUAL(s.get_atom_by_id("1").get_label_atom_id(), "CHA");
BOOST_CHECK_EQUAL(s.get_atom_by_id("2").get_label_atom_id(), "CHC");
BOOST_CHECK_EQUAL(s.get_atom_by_id("3").get_label_atom_id(), "CHB");
BOOST_CHECK_EQUAL(s.get_atom_by_id("4").get_label_atom_id(), "CHD");
REQUIRE(s.get_atom_by_id("1").get_label_atom_id() == "CHA");
REQUIRE(s.get_atom_by_id("2").get_label_atom_id() == "CHC");
REQUIRE(s.get_atom_by_id("3").get_label_atom_id() == "CHB");
REQUIRE(s.get_atom_by_id("4").get_label_atom_id() == "CHD");
}
// --------------------------------------------------------------------
BOOST_AUTO_TEST_CASE(atom_numbers_1)
TEST_CASE("atom_numbers_1")
{
const std::filesystem::path test1(gTestDir / ".." / "examples" / "1cbs.cif.gz");
cif::file file(test1.string());
@@ -409,27 +380,27 @@ BOOST_AUTO_TEST_CASE(atom_numbers_1)
auto ai = atoms.begin();
for (const auto &[id, label_asym_id, label_seq_id, label_atom_id, auth_seq_id, label_comp_id] :
db["atom_site"].rows<std::string,std::string,int,std::string,std::string,std::string>("id", "label_asym_id", "label_seq_id", "label_atom_id", "auth_seq_id", "label_comp_id"))
db["atom_site"].rows<std::string, std::string, int, std::string, std::string, std::string>("id", "label_asym_id", "label_seq_id", "label_atom_id", "auth_seq_id", "label_comp_id"))
{
auto atom = structure.get_atom_by_id(id);
BOOST_CHECK_EQUAL(atom.get_label_asym_id(), label_asym_id);
BOOST_CHECK_EQUAL(atom.get_label_seq_id(), label_seq_id);
BOOST_CHECK_EQUAL(atom.get_label_atom_id(), label_atom_id);
BOOST_CHECK_EQUAL(atom.get_auth_seq_id(), auth_seq_id);
BOOST_CHECK_EQUAL(atom.get_label_comp_id(), label_comp_id);
REQUIRE(atom.get_label_asym_id() == label_asym_id);
REQUIRE(atom.get_label_seq_id() == label_seq_id);
REQUIRE(atom.get_label_atom_id() == label_atom_id);
REQUIRE(atom.get_auth_seq_id() == auth_seq_id);
REQUIRE(atom.get_label_comp_id() == label_comp_id);
BOOST_ASSERT(ai != atoms.end());
REQUIRE(ai != atoms.end());
BOOST_CHECK_EQUAL(ai->id(), id);
REQUIRE(ai->id() == id);
++ai;
}
BOOST_ASSERT(ai == atoms.end());
REQUIRE(ai == atoms.end());
}
// --------------------------------------------------------------------
BOOST_AUTO_TEST_CASE(test_load_2)
TEST_CASE("test_load_2")
{
using namespace cif::literals;
@@ -440,17 +411,17 @@ BOOST_AUTO_TEST_CASE(test_load_2)
cif::mm::structure s(file);
BOOST_CHECK(s.polymers().size() == 1);
REQUIRE(s.polymers().size() == 1UL);
auto &pdbx_poly_seq_scheme = db["pdbx_poly_seq_scheme"];
for (auto &poly : s.polymers())
{
BOOST_CHECK_EQUAL(poly.size(), pdbx_poly_seq_scheme.find("asym_id"_key == poly.get_asym_id()).size());
REQUIRE(poly.size() == pdbx_poly_seq_scheme.find("asym_id"_key == poly.get_asym_id()).size());
}
}
BOOST_AUTO_TEST_CASE(remove_residue_1)
TEST_CASE("remove_residue_1")
{
using namespace cif::literals;
@@ -460,5 +431,5 @@ BOOST_AUTO_TEST_CASE(remove_residue_1)
cif::mm::structure s(file);
s.remove_residue(s.get_residue("B"));
BOOST_CHECK_NO_THROW(s.validate_atoms());
REQUIRE_NOTHROW(s.validate_atoms());
}

View File

@@ -24,57 +24,40 @@
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "test-main.hpp"
#include <cif++.hpp>
#include <catch2/catch.hpp>
#include <iostream>
#include <fstream>
int main(int argc, char* argv[])
TEST_CASE("rename")
{
cif::VERBOSE = 3;
try
{
std::filesystem::path testdir = std::filesystem::current_path();
if (std::filesystem::exists(gTestDir / ".." / "rsrc" / "ccd-subset.cif"))
cif::add_file_resource("components.cif", gTestDir / ".." / "rsrc" / "ccd-subset.cif");
if (argc == 3)
testdir = argv[2];
else
{
while (not testdir.empty() and not std::filesystem::exists(testdir / "test"))
testdir = testdir.parent_path();
testdir /= "test";
}
if (std::filesystem::exists(gTestDir / ".." / "rsrc" / "mmcif_pdbx.dic"))
cif::add_file_resource("mmcif_pdbx.dic", gTestDir / ".." / "rsrc" / "mmcif_pdbx.dic");
if (std::filesystem::exists(testdir / ".." / "data" / "ccd-subset.cif"))
cif::add_file_resource("components.cif", testdir / ".." / "data" / "ccd-subset.cif");
cif::compound_factory::instance().push_dictionary(gTestDir / "REA.cif");
cif::compound_factory::instance().push_dictionary(gTestDir / "RXA.cif");
if (std::filesystem::exists(testdir / ".." / "rsrc" / "mmcif_pdbx.dic"))
cif::add_file_resource("mmcif_pdbx.dic", testdir / ".." / "rsrc" / "mmcif_pdbx.dic");
cif::file f(gTestDir / ".."/"examples"/"1cbs.cif.gz");
cif::mm::structure structure(f);
cif::compound_factory::instance().push_dictionary(testdir / "REA.cif");
cif::compound_factory::instance().push_dictionary(testdir / "RXA.cif");
auto &res = structure.get_residue("B");
structure.change_residue(res, "RXA", {});
cif::file f(testdir / ".."/"examples"/"1cbs.cif.gz");
cif::mm::structure structure(f);
structure.cleanup_empty_categories();
auto &res = structure.get_residue("B");
structure.change_residue(res, "RXA", {});
f.save(std::cout);
structure.cleanup_empty_categories();
if (not f.is_valid())
throw std::runtime_error("Invalid");
f.save(std::cout);
if (not f.is_valid())
throw std::runtime_error("Invalid");
f.save(std::cout);
}
catch (const std::exception& e)
{
std::cerr << e.what() << '\n';
exit(1);
}
return 0;
f.save(std::cout);
}

View File

@@ -1,9 +1,11 @@
#include "cif++/utilities.hpp"
#include <catch2/catch.hpp>
#include <random>
#include <thread>
void test_one()
TEST_CASE("test_one")
{
std::random_device rd;
std::mt19937 gen(rd());
@@ -20,7 +22,7 @@ void test_one()
}
}
void test_two()
TEST_CASE("test_two")
{
cif::progress_bar pb(10, "test");
@@ -29,7 +31,7 @@ void test_two()
pb.consumed(1);
}
void test_three()
TEST_CASE("test_three")
{
using namespace std::literals;
@@ -38,12 +40,3 @@ void test_three()
std::this_thread::sleep_for(100ms);
}
int main()
{
test_one();
test_two();
test_three();
return 0;
}

View File

@@ -24,8 +24,9 @@
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#define BOOST_TEST_ALTERNATIVE_INIT_API
#include <boost/test/included/unit_test.hpp>
#include "test-main.hpp"
#include <catch2/catch.hpp>
#include <stdexcept>
@@ -49,30 +50,7 @@ cif::file operator""_cf(const char* text, size_t length)
// --------------------------------------------------------------------
std::filesystem::path gTestDir = std::filesystem::current_path();
bool init_unit_test()
{
cif::VERBOSE = 1;
// not a test, just initialize test dir
if (boost::unit_test::framework::master_test_suite().argc == 2)
gTestDir = boost::unit_test::framework::master_test_suite().argv[1];
// do this now, avoids the need for installing
cif::add_file_resource("mmcif_pdbx.dic", gTestDir / ".." / "rsrc" / "mmcif_pdbx.dic");
// initialize CCD location
cif::add_file_resource("components.cif", gTestDir / ".." / "data" / "ccd-subset.cif");
cif::compound_factory::instance().push_dictionary(gTestDir / "HEM.cif");
return true;
}
// --------------------------------------------------------------------
BOOST_AUTO_TEST_CASE(sugar_name_1)
TEST_CASE("sugar_name_1")
{
using namespace cif::literals;
@@ -85,20 +63,20 @@ BOOST_AUTO_TEST_CASE(sugar_name_1)
auto &branches = s.branches();
BOOST_CHECK_EQUAL(branches.size(), 4);
REQUIRE(branches.size() == 4UL);
for (auto &branch : branches)
{
auto entityID = branch.front().get_entity_id();
auto name = entity.find1<std::string>("id"_key == entityID, "pdbx_description");
BOOST_CHECK_EQUAL(branch.name(), name);
REQUIRE(branch.name() == name);
}
}
// // --------------------------------------------------------------------
// BOOST_AUTO_TEST_CASE(create_sugar_1)
// TEST_CASE("create_sugar_1")
// {
// using namespace cif::literals;
@@ -125,19 +103,19 @@ BOOST_AUTO_TEST_CASE(sugar_name_1)
// auto &branch = s.create_branch(ai);
// BOOST_CHECK_EQUAL(branch.name(), "2-acetamido-2-deoxy-beta-D-glucopyranose");
// BOOST_CHECK_EQUAL(branch.size(), 1);
// REQUIRE(branch.name() == "2-acetamido-2-deoxy-beta-D-glucopyranose");
// REQUIRE(branch.size() == 1);
// BOOST_CHECK_EQUAL(branch[0].atoms().size(), nagAtoms.size());
// REQUIRE(branch[0].atoms().size() == nagAtoms.size());
// BOOST_CHECK(file.is_valid());
// REQUIRE(file.is_valid());
// file.save(gTestDir / "test-create_sugar_1.cif");
// }
// // --------------------------------------------------------------------
// BOOST_AUTO_TEST_CASE(create_sugar_2)
// TEST_CASE("create_sugar_2")
// {
// using namespace cif::literals;
@@ -148,7 +126,7 @@ BOOST_AUTO_TEST_CASE(sugar_name_1)
// // Get branch for H
// auto &bH = s.get_branch_by_asym_id("H");
// BOOST_CHECK_EQUAL(bH.size(), 2);
// REQUIRE(bH.size() == 2);
// std::vector<cif::row_initializer> ai[2];
@@ -163,24 +141,24 @@ BOOST_AUTO_TEST_CASE(sugar_name_1)
// s.remove_branch(bH);
// BOOST_CHECK(file.is_valid());
// REQUIRE(file.is_valid());
// auto &bN = s.create_branch(ai[0]);
// s.extend_branch(bN.get_asym_id(), ai[1], 1, "O4");
// BOOST_CHECK_EQUAL(bN.name(), "2-acetamido-2-deoxy-beta-D-glucopyranose-(1-4)-2-acetamido-2-deoxy-beta-D-glucopyranose");
// BOOST_CHECK_EQUAL(bN.size(), 2);
// REQUIRE(bN.name() == "2-acetamido-2-deoxy-beta-D-glucopyranose-(1-4)-2-acetamido-2-deoxy-beta-D-glucopyranose");
// REQUIRE(bN.size() == 2);
// BOOST_CHECK(file.is_valid());
// REQUIRE(file.is_valid());
// file.save(gTestDir / "test-create_sugar_2.cif");
// BOOST_CHECK_NO_THROW(cif::mm::structure s2(file));
// REQUIRE_NO_THROW(cif::mm::structure s2(file));
// }
// --------------------------------------------------------------------
BOOST_AUTO_TEST_CASE(delete_sugar_1)
TEST_CASE("delete_sugar_1")
{
using namespace cif::literals;
@@ -191,20 +169,20 @@ BOOST_AUTO_TEST_CASE(delete_sugar_1)
// Get branch for H
auto &bG = s.get_branch_by_asym_id("G");
BOOST_CHECK_EQUAL(bG.size(), 4);
REQUIRE(bG.size() == 4UL);
s.remove_residue(bG[1]);
BOOST_CHECK_EQUAL(bG.size(), 1);
REQUIRE(bG.size() == 1UL);
auto &bN = s.get_branch_by_asym_id("G");
BOOST_CHECK_EQUAL(bN.name(), "2-acetamido-2-deoxy-beta-D-glucopyranose");
BOOST_CHECK_EQUAL(bN.size(), 1);
REQUIRE(bN.name() == "2-acetamido-2-deoxy-beta-D-glucopyranose");
REQUIRE(bN.size() == 1UL);
BOOST_CHECK(file.is_valid());
REQUIRE(file.is_valid());
// file.save(gTestDir / "test-create_sugar_3.cif");
BOOST_CHECK_NO_THROW(cif::mm::structure s2(file));
cif::mm::structure s2(file);
}

39
test/test-main.cpp Normal file
View File

@@ -0,0 +1,39 @@
#include "test-main.hpp"
#include <cif++.hpp>
#define CATCH_CONFIG_RUNNER
#include <catch2/catch.hpp>
std::filesystem::path gTestDir = std::filesystem::current_path();
int main(int argc, char *argv[])
{
Catch::Session session; // There must be exactly one instance
// Build a new parser on top of Catch2's
using namespace Catch::clara;
auto cli = session.cli() // Get Catch2's command line parser
| Opt(gTestDir, "data-dir") // bind variable to a new option, with a hint string
["-D"]["--data-dir"] // the option names it will respond to
("The directory containing the data files"); // description string for the help output
// Now pass the new composite back to Catch2 so it uses that
session.cli(cli);
// Let Catch2 (using Clara) parse the command line
int returnCode = session.applyCommandLine(argc, argv);
if (returnCode != 0) // Indicates a command line error
return returnCode;
// do this now, avoids the need for installing
cif::add_file_resource("mmcif_pdbx.dic", gTestDir / ".." / "rsrc" / "mmcif_pdbx.dic");
// initialize CCD location
cif::add_file_resource("components.cif", gTestDir / ".." / "rsrc" / "ccd-subset.cif");
cif::compound_factory::instance().push_dictionary(gTestDir / "HEM.cif");
return session.run();
}

3
test/test-main.hpp Normal file
View File

@@ -0,0 +1,3 @@
#include <filesystem>
extern std::filesystem::path gTestDir;

View File

@@ -24,8 +24,9 @@
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#define BOOST_TEST_ALTERNATIVE_INIT_API
#include <boost/test/included/unit_test.hpp>
#include "test-main.hpp"
#include <catch2/catch.hpp>
#include <stdexcept>
@@ -33,11 +34,6 @@
#include <Eigen/Eigenvalues>
namespace tt = boost::test_tools;
namespace utf = boost::unit_test;
std::filesystem::path gTestDir = std::filesystem::current_path(); // filled in first test
// --------------------------------------------------------------------
cif::file operator""_cf(const char *text, size_t length)
@@ -56,28 +52,9 @@ cif::file operator""_cf(const char *text, size_t length)
// --------------------------------------------------------------------
bool init_unit_test()
{
cif::VERBOSE = 1;
// not a test, just initialize test dir
if (boost::unit_test::framework::master_test_suite().argc == 2)
gTestDir = boost::unit_test::framework::master_test_suite().argv[1];
// do this now, avoids the need for installing
cif::add_file_resource("mmcif_pdbx.dic", gTestDir / ".." / "rsrc" / "mmcif_pdbx.dic");
// initialize CCD location
cif::add_file_resource("components.cif", gTestDir / ".." / "data" / "ccd-subset.cif");
return true;
}
// --------------------------------------------------------------------
// 3d tests
BOOST_AUTO_TEST_CASE(t1)
TEST_CASE("t1")
{
// std::random_device rnd;
// std::mt19937 gen(rnd());
@@ -115,19 +92,19 @@ BOOST_AUTO_TEST_CASE(t1)
const auto &&[angle, axis] = cif::quaternion_to_angle_axis(q2);
BOOST_TEST(std::fmod(360 + angle, 360) == std::fmod(360 - angle0, 360), tt::tolerance(0.01));
REQUIRE_THAT(std::fmod(360 + angle, 360), Catch::Matchers::WithinRel(std::fmod(360 - angle0, 360), 0.01));
for (auto &p : p1)
p.rotate(q2);
auto rmsd = cif::RMSd(p1, p2);
BOOST_TEST(rmsd < 1e-5);
REQUIRE(rmsd < 1e-5);
// std::cout << "rmsd: " << RMSd(p1, p2) << '\n';
}
BOOST_AUTO_TEST_CASE(t2)
TEST_CASE("t2")
{
cif::point p[] = {
{ 1, 1, 0 },
@@ -141,10 +118,10 @@ BOOST_AUTO_TEST_CASE(t2)
auto &&[angle, axis] = cif::quaternion_to_angle_axis(q);
BOOST_TEST(angle == 45, tt::tolerance(0.01));
REQUIRE_THAT(angle, Catch::Matchers::WithinRel(45.f, 0.01f));
}
BOOST_AUTO_TEST_CASE(t3)
TEST_CASE("t3")
{
cif::point p[] = {
{ 1, 1, 0 },
@@ -165,10 +142,10 @@ BOOST_AUTO_TEST_CASE(t3)
double a = cif::angle(v, p[0], p[1]);
BOOST_TEST(a == 45, tt::tolerance(0.01));
REQUIRE_THAT(a, Catch::Matchers::WithinRel(45.f, 0.01f));
}
BOOST_AUTO_TEST_CASE(dh_q_0)
TEST_CASE("dh_q_0")
{
cif::point axis(1, 0, 0);
@@ -182,33 +159,33 @@ BOOST_AUTO_TEST_CASE(dh_q_0)
};
auto a = cif::dihedral_angle(t[0], t[1], t[2], p);
BOOST_TEST(a == 0, tt::tolerance(0.01f));
REQUIRE_THAT(a, Catch::Matchers::WithinRel(0, 0.01f));
auto q = cif::construct_from_angle_axis(90, axis);
p.rotate(q);
BOOST_TEST(p.m_x == 1, tt::tolerance(0.01f));
BOOST_TEST(p.m_y == 0, tt::tolerance(0.01f));
BOOST_TEST(p.m_z == 1, tt::tolerance(0.01f));
REQUIRE_THAT(p.m_x, Catch::Matchers::WithinRel(1, 0.01f));
REQUIRE_THAT(p.m_y, Catch::Matchers::WithinRel(0, 0.01f));
REQUIRE_THAT(p.m_z, Catch::Matchers::WithinRel(1, 0.01f));
a = cif::dihedral_angle(t[0], t[1], t[2], p);
BOOST_TEST(a == 90, tt::tolerance(0.01f));
REQUIRE_THAT(a, Catch::Matchers::WithinRel(90, 0.01f));
q = cif::construct_from_angle_axis(-90, axis);
p.rotate(q);
BOOST_TEST(p.m_x == 1, tt::tolerance(0.01f));
BOOST_TEST(p.m_y == 1, tt::tolerance(0.01f));
BOOST_TEST(p.m_z == 0, tt::tolerance(0.01f));
REQUIRE_THAT(p.m_x, Catch::Matchers::WithinRel(1, 0.01f));
REQUIRE_THAT(p.m_y, Catch::Matchers::WithinRel(1, 0.01f));
REQUIRE_THAT(p.m_z, Catch::Matchers::WithinRel(0, 0.01f));
a = cif::dihedral_angle(t[0], t[1], t[2], p);
BOOST_TEST(a == 0, tt::tolerance(0.01f));
REQUIRE_THAT(a, Catch::Matchers::WithinRel(0, 0.01f));
}
BOOST_AUTO_TEST_CASE(dh_q_1)
TEST_CASE("dh_q_1")
{
struct
{
@@ -247,13 +224,13 @@ BOOST_AUTO_TEST_CASE(dh_q_1)
pts[3].rotate(q, pts[2]);
auto dh = cif::dihedral_angle(pts[0], pts[1], pts[2], pts[3]);
BOOST_TEST(dh == angle, tt::tolerance(0.1f));
REQUIRE_THAT(dh, Catch::Matchers::WithinRel(angle, 0.1f));
}
}
// --------------------------------------------------------------------
BOOST_AUTO_TEST_CASE(m2q_0, *utf::tolerance(0.001f))
TEST_CASE("m2q_0, *utf::tolerance(0.001f)")
{
for (size_t i = 0; i < cif::kSymopNrTableSize; ++i)
{
@@ -310,13 +287,13 @@ BOOST_AUTO_TEST_CASE(m2q_0, *utf::tolerance(0.001f))
cif::point p3 = rot * p1;
BOOST_TEST(p2.m_x == p3.m_x);
BOOST_TEST(p2.m_y == p3.m_y);
BOOST_TEST(p2.m_z == p3.m_z);
REQUIRE_THAT(p2.m_x, Catch::Matchers::WithinRel(p3.m_x, 0.01f));
REQUIRE_THAT(p2.m_y, Catch::Matchers::WithinRel(p3.m_y, 0.01f));
REQUIRE_THAT(p2.m_z, Catch::Matchers::WithinRel(p3.m_z, 0.01f));
}
}
// BOOST_AUTO_TEST_CASE(m2q_1, *utf::tolerance(0.001f))
// "TEST_CASE(m2q_1, *utf::tolerance(0.001f)")
// {
// for (size_t i = 0; i < cif::kSymopNrTableSize; ++i)
// {
@@ -369,15 +346,15 @@ BOOST_AUTO_TEST_CASE(m2q_0, *utf::tolerance(0.001f))
// cif::point p3 = rot * p1;
// BOOST_TEST(p2.m_x == p3.m_x);
// BOOST_TEST(p2.m_y == p3.m_y);
// BOOST_TEST(p2.m_z == p3.m_z);
// REQUIRE(p2.m_x == p3.m_x);
// REQUIRE(p2.m_y == p3.m_y);
// REQUIRE(p2.m_z == p3.m_z);
// }
// }
// --------------------------------------------------------------------
BOOST_AUTO_TEST_CASE(symm_1)
TEST_CASE("symm_1")
{
cif::cell c(10, 10, 10);
@@ -385,37 +362,37 @@ BOOST_AUTO_TEST_CASE(symm_1)
cif::point f = fractional(p, c);
BOOST_TEST(f.m_x == 0.1f, tt::tolerance(0.01));
BOOST_TEST(f.m_y == 0.1f, tt::tolerance(0.01));
BOOST_TEST(f.m_z == 0.1f, tt::tolerance(0.01));
REQUIRE_THAT(f.m_x, Catch::Matchers::WithinRel(0.1f, 0.01f));
REQUIRE_THAT(f.m_y, Catch::Matchers::WithinRel(0.1f, 0.01f));
REQUIRE_THAT(f.m_z, Catch::Matchers::WithinRel(0.1f, 0.01f));
cif::point o = orthogonal(f, c);
BOOST_TEST(o.m_x == 1.f, tt::tolerance(0.01));
BOOST_TEST(o.m_y == 1.f, tt::tolerance(0.01));
BOOST_TEST(o.m_z == 1.f, tt::tolerance(0.01));
REQUIRE_THAT(o.m_x, Catch::Matchers::WithinRel(1.f, 0.01f));
REQUIRE_THAT(o.m_y, Catch::Matchers::WithinRel(1.f, 0.01f));
REQUIRE_THAT(o.m_z, Catch::Matchers::WithinRel(1.f, 0.01f));
}
BOOST_AUTO_TEST_CASE(symm_2)
TEST_CASE("symm_2")
{
using namespace cif::literals;
auto symop = "1_555"_symop;
BOOST_TEST(symop.is_identity() == true);
REQUIRE(symop.is_identity() == true);
}
BOOST_AUTO_TEST_CASE(symm_3)
TEST_CASE("symm_3")
{
using namespace cif::literals;
cif::spacegroup sg(18);
BOOST_TEST(sg.size() == 4);
BOOST_TEST(sg.get_name() == "P 21 21 2");
REQUIRE(sg.size() == 4UL);
REQUIRE(sg.get_name() == "P 21 21 2");
}
BOOST_AUTO_TEST_CASE(symm_4, *utf::tolerance(0.1f))
TEST_CASE("symm_4, *utf::tolerance(0.1f)")
{
using namespace cif::literals;
@@ -427,21 +404,21 @@ BOOST_AUTO_TEST_CASE(symm_4, *utf::tolerance(0.1f))
cif::point b{ -35.356, 33.693, -3.236 }; // CG2 THR D 400
cif::point sb( -6.916, 79.34, 3.236); // 4_565 copy of b
BOOST_TEST(distance(a, sg(a, c, "1_455"_symop)) == static_cast<float>(c.get_a()));
BOOST_TEST(distance(a, sg(a, c, "1_545"_symop)) == static_cast<float>(c.get_b()));
BOOST_TEST(distance(a, sg(a, c, "1_554"_symop)) == static_cast<float>(c.get_c()));
REQUIRE_THAT(distance(a, sg(a, c, "1_455"_symop)), Catch::Matchers::WithinRel(static_cast<float>(c.get_a()), 0.01f));
REQUIRE_THAT(distance(a, sg(a, c, "1_545"_symop)), Catch::Matchers::WithinRel(static_cast<float>(c.get_b()), 0.01f));
REQUIRE_THAT(distance(a, sg(a, c, "1_554"_symop)), Catch::Matchers::WithinRel(static_cast<float>(c.get_c()), 0.01f));
auto sb2 = sg(b, c, "4_565"_symop);
BOOST_TEST(sb.m_x == sb2.m_x);
BOOST_TEST(sb.m_y == sb2.m_y);
BOOST_TEST(sb.m_z == sb2.m_z);
REQUIRE_THAT(sb.m_x, Catch::Matchers::WithinRel(sb2.m_x, 0.01f));
REQUIRE_THAT(sb.m_y, Catch::Matchers::WithinRel(sb2.m_y, 0.01f));
REQUIRE_THAT(sb.m_z, Catch::Matchers::WithinRel(sb2.m_z, 0.01f));
BOOST_TEST(distance(a, sb2) == 7.42f);
REQUIRE_THAT(distance(a, sb2), Catch::Matchers::WithinRel(7.42f, 0.01f));
}
// --------------------------------------------------------------------
BOOST_AUTO_TEST_CASE(symm_4wvp_1, *utf::tolerance(0.1f))
TEST_CASE("symm_4wvp_1, *utf::tolerance(0.1f)")
{
using namespace cif::literals;
@@ -456,21 +433,21 @@ BOOST_AUTO_TEST_CASE(symm_4wvp_1, *utf::tolerance(0.1f))
auto a = s.get_residue("A", 10, "").get_atom_by_atom_id("O");
auto sp1 = c.symmetry_copy(a.get_location(), "2_565"_symop);
BOOST_TEST(sp1.m_x == p.m_x);
BOOST_TEST(sp1.m_y == p.m_y);
BOOST_TEST(sp1.m_z == p.m_z);
REQUIRE_THAT(sp1.m_x, Catch::Matchers::WithinAbs(p.m_x, 0.5f));
REQUIRE_THAT(sp1.m_y, Catch::Matchers::WithinAbs(p.m_y, 0.5f));
REQUIRE_THAT(sp1.m_z, Catch::Matchers::WithinAbs(p.m_z, 0.5f));
const auto &[d, sp2, so] = c.closest_symmetry_copy(p, a.get_location());
BOOST_TEST(d < 1);
REQUIRE(d < 1);
BOOST_TEST(sp2.m_x == p.m_x);
BOOST_TEST(sp2.m_y == p.m_y);
BOOST_TEST(sp2.m_z == p.m_z);
REQUIRE_THAT(sp2.m_x, Catch::Matchers::WithinAbs(p.m_x, 0.5f));
REQUIRE_THAT(sp2.m_y, Catch::Matchers::WithinAbs(p.m_y, 0.5f));
REQUIRE_THAT(sp2.m_z, Catch::Matchers::WithinAbs(p.m_z, 0.5f));
}
BOOST_AUTO_TEST_CASE(symm_2bi3_1, *utf::tolerance(0.1f))
TEST_CASE("symm_2bi3_1, *utf::tolerance(0.1f)")
{
cif::file f(gTestDir / "2bi3.cif.gz");
@@ -502,22 +479,22 @@ BOOST_AUTO_TEST_CASE(symm_2bi3_1, *utf::tolerance(0.1f))
auto sa1 = c.symmetry_copy(a1.get_location(), cif::sym_op(symm1));
auto sa2 = c.symmetry_copy(a2.get_location(), cif::sym_op(symm2));
BOOST_TEST(cif::distance(sa1, sa2) == dist);
REQUIRE_THAT(cif::distance(sa1, sa2), Catch::Matchers::WithinAbs(dist, 0.5f));
auto pa1 = a1.get_location();
const auto &[d, p, so] = c.closest_symmetry_copy(pa1, a2.get_location());
BOOST_TEST(p.m_x == sa2.m_x);
BOOST_TEST(p.m_y == sa2.m_y);
BOOST_TEST(p.m_z == sa2.m_z);
REQUIRE_THAT(p.m_x, Catch::Matchers::WithinAbs(sa2.m_x, 0.5f));
REQUIRE_THAT(p.m_y, Catch::Matchers::WithinAbs(sa2.m_y, 0.5f));
REQUIRE_THAT(p.m_z, Catch::Matchers::WithinAbs(sa2.m_z, 0.5f));
BOOST_TEST(d == dist);
BOOST_TEST(so.string() == symm2);
REQUIRE_THAT(d, Catch::Matchers::WithinAbs(dist, 0.5f));
REQUIRE(so.string() == symm2);
}
}
BOOST_AUTO_TEST_CASE(symm_2bi3_1a, *utf::tolerance(0.1f))
TEST_CASE("symm_2bi3_1a, *utf::tolerance(0.1f)")
{
using namespace cif::literals;
@@ -552,20 +529,20 @@ BOOST_AUTO_TEST_CASE(symm_2bi3_1a, *utf::tolerance(0.1f))
auto sa1 = c.symmetry_copy(p1, cif::sym_op(symm1));
auto sa2 = c.symmetry_copy(p2, cif::sym_op(symm2));
BOOST_TEST(cif::distance(sa1, sa2) == dist);
REQUIRE_THAT(cif::distance(sa1, sa2), Catch::Matchers::WithinAbs(dist, 0.5f));
const auto &[d, p, so] = c.closest_symmetry_copy(p1, p2);
BOOST_TEST(p.m_x == sa2.m_x);
BOOST_TEST(p.m_y == sa2.m_y);
BOOST_TEST(p.m_z == sa2.m_z);
REQUIRE_THAT(p.m_x, Catch::Matchers::WithinAbs(sa2.m_x, 0.5f));
REQUIRE_THAT(p.m_y, Catch::Matchers::WithinAbs(sa2.m_y, 0.5f));
REQUIRE_THAT(p.m_z, Catch::Matchers::WithinAbs(sa2.m_z, 0.5f));
BOOST_TEST(d == dist);
BOOST_TEST(so.string() == symm2);
REQUIRE_THAT(d, Catch::Matchers::WithinAbs(dist, 0.5f));
REQUIRE(so.string() == symm2);
}
}
BOOST_AUTO_TEST_CASE(symm_3bwh_1, *utf::tolerance(0.1f))
TEST_CASE("symm_3bwh_1, *utf::tolerance(0.1f)")
{
cif::file f(gTestDir / "3bwh.cif.gz");
@@ -583,12 +560,12 @@ BOOST_AUTO_TEST_CASE(symm_3bwh_1, *utf::tolerance(0.1f))
const auto&[ d, p, so ] = c.closest_symmetry_copy(a1.get_location(), a2.get_location());
BOOST_TEST(d == distance(a1.get_location(), p));
REQUIRE_THAT(d, Catch::Matchers::WithinAbs(distance(a1.get_location(), p), 0.5f));
}
}
}
BOOST_AUTO_TEST_CASE(volume_3bwh_1, *utf::tolerance(0.1f))
TEST_CASE("volume_3bwh_1, *utf::tolerance(0.1f)")
{
cif::file f(gTestDir / "1juh.cif.gz");
@@ -596,6 +573,6 @@ BOOST_AUTO_TEST_CASE(volume_3bwh_1, *utf::tolerance(0.1f))
cif::crystal c(db);
BOOST_CHECK_EQUAL(c.get_cell().get_volume(), 741009.625f);
REQUIRE_THAT(c.get_cell().get_volume(), Catch::Matchers::WithinRel(741009.625f, 0.01f));
}

File diff suppressed because it is too large Load Diff

22
tools/depends.cmd Normal file
View File

@@ -0,0 +1,22 @@
@ECHO OFF
SET ZLIB_VERSION=1.3
IF NOT EXIST build_ci\libs (
MKDIR build_ci\libs
)
CD build_ci\libs
IF NOT EXIST zlib-%ZLIB_VERSION%.zip (
ECHO Downloading https://github.com/libarchive/zlib/archive/v%ZLIB_VERSION%.zip
curl -L -o zlib-%ZLIB_VERSION%.zip https://github.com/libarchive/zlib/archive/v%ZLIB_VERSION%.zip || EXIT /b 1
)
IF NOT EXIST zlib-%ZLIB_VERSION% (
ECHO Unpacking zlib-%ZLIB_VERSION%.zip
C:\windows\system32\tar.exe -x -f zlib-%ZLIB_VERSION%.zip || EXIT /b 1
)
CD zlib-%ZLIB_VERSION%
cmake -G "Visual Studio 17 2022" . || EXIT /b 1
cmake --build . --target ALL_BUILD --config Release || EXIT /b 1
cmake --build . --target RUN_TESTS --config Release || EXIT /b 1
cmake --build . --target INSTALL --config Release || EXIT /b 1
@EXIT /b 0

View File

@@ -10,7 +10,7 @@ euid=${EUID:-$(id -u)}
if [ "${euid}" -ne 0 ]; then
echo "Please run as root"
exit
exit 1
fi
if [ -f "@CIFPP_ETC_DIR@/libcifpp.conf" ]; then
@@ -19,12 +19,13 @@ fi
# check to see if we're supposed to run at all
if [ "$update" != "true" ]; then
exit
exit 0
fi
# if cache directory doesn't exist, exit.
if ! [ -d "@CIFPP_CACHE_DIR@" ]; then
exit
echo "Cache directory '@CIFPP_CACHE_DIR@' does not exist"
exit 1
fi
# Create a temp file in the right directory and
@@ -60,12 +61,16 @@ update_dictionary() {
# Update the dictionaries
update_dictionary "@CIFPP_CACHE_DIR@/components.cif" "https://ftp.wwpdb.org/pub/pdb/data/monomers/components.cif.gz"
update_dictionary "@CIFPP_CACHE_DIR@/components.cif" "https://files.wwpdb.org/pub/pdb/data/monomers/components.cif.gz"
update_dictionary "@CIFPP_CACHE_DIR@/mmcif_pdbx.dic" "https://mmcif.wwpdb.org/dictionaries/ascii/mmcif_pdbx_v50.dic.gz"
update_dictionary "@CIFPP_CACHE_DIR@/mmcif_ma.dic" "https://github.com/ihmwg/ModelCIF/raw/master/dist/mmcif_ma.dic"
# notify subscribers, will fail on FreeBSD
# notify subscribers, using find instead of run-parts to make it work on FreeBSD as well
if [ -d "@CIFPP_ETC_DIR@/libcifpp/cache-update.d" ] && [ -x /bin/run-parts ]; then
run-parts --arg "@CIFPP_CACHE_DIR@" -- "@CIFPP_ETC_DIR@/libcifpp/cache-update.d"
if [ -d "@CIFPP_ETC_DIR@/libcifpp/cache-update.d" ]; then
find "@CIFPP_ETC_DIR@/libcifpp/cache-update.d" \
-exec test -x {} \; -and -not -exec test -d {} \; \
-exec {} "@CIFPP_CACHE_DIR@" \;
fi
exit 0