macOS and Windows fixes,

start using clang-tidy
This commit is contained in:
Maarten L. Hekkelman
2026-01-05 12:59:59 +01:00
parent 2a265bb5c8
commit 656c82838a
9 changed files with 496 additions and 478 deletions

5
.clang-tidy Normal file
View File

@@ -0,0 +1,5 @@
Checks: '-*,
modernize*,
-modernize-use-trailing-return-type,
-modernize-avoid-c-arrays
'

View File

@@ -27,15 +27,15 @@ cmake_minimum_required(VERSION 3.23)
cmake_policy(SET CMP0135 NEW)
if(CMAKE_SOURCE_DIR STREQUAL CMAKE_CURRENT_SOURCE_DIR AND NOT CMAKE_BUILD_TYPE AND NOT CMAKE_CONFIGURATION_TYPES)
set(CMAKE_BUILD_TYPE Release CACHE STRING "Build type" FORCE)
set_property(CACHE CMAKE_BUILD_TYPE PROPERTY STRINGS "Debug" "Release" "MinSizeRel" "RelWithDebInfo")
set(CMAKE_BUILD_TYPE Release CACHE STRING "Build type" FORCE)
set_property(CACHE CMAKE_BUILD_TYPE PROPERTY STRINGS "Debug" "Release" "MinSizeRel" "RelWithDebInfo")
endif()
# set the project name
project(
libcifpp
VERSION 10.0.0
LANGUAGES CXX C)
libcifpp
VERSION 10.0.0
LANGUAGES CXX C)
list(PREPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake")
@@ -49,16 +49,16 @@ include(VersionString)
# 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")
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"
)
set(CMAKE_CXX_FLAGS
"${CMAKE_CXX_FLAGS} -Wall -Wextra -Wno-unused-parameter -Wno-missing-field-initializers"
)
elseif(MSVC)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /W4")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /W4")
endif()
# Build documentation?
@@ -72,144 +72,144 @@ set(BUILD_SQLITE_INTERFACE ON CACHE BOOL "Build the sqlite interface")
# Building shared libraries?
if(NOT (BUILD_FOR_CCP4 AND WIN32))
set(BUILD_SHARED_LIBS OFF CACHE BOOL "Build a shared library instead of a static one")
set(BUILD_SHARED_LIBS OFF CACHE BOOL "Build a shared library instead of a static one")
endif()
if(PROJECT_IS_TOP_LEVEL AND NOT BUILD_FOR_CCP4)
# Lots of code depend on the availability of the components.cif file
set(CIFPP_DOWNLOAD_CCD ON CACHE BOOL "Download the CCD file components.cif during installation")
# Lots of code depend on the availability of the components.cif file
set(CIFPP_DOWNLOAD_CCD ON CACHE BOOL "Download the CCD file components.cif during installation")
# An optional cron script can be installed to keep the data files up-to-date
if(UNIX AND NOT APPLE)
set(CIFPP_INSTALL_UPDATE_SCRIPT ON CACHE BOOL "Install the script to update CCD and dictionary files")
endif()
# An optional cron script can be installed to keep the data files up-to-date
if(UNIX AND NOT APPLE)
set(CIFPP_INSTALL_UPDATE_SCRIPT ON CACHE BOOL "Install the script to update CCD and dictionary files")
endif()
else()
unset(CIFPP_DOWNLOAD_CCD)
unset(CIFPP_INSTALL_UPDATE_SCRIPT)
unset(CIFPP_DOWNLOAD_CCD)
unset(CIFPP_INSTALL_UPDATE_SCRIPT)
endif()
# When CCP4 is sourced in the environment, we can recreate the symmetry
# operations table
if(EXISTS "$ENV{CCP4}/lib/data/syminfo.lib")
set(CIFPP_RECREATE_SYMOP_DATA ON CACHE BOOL "Recreate SymOp data table in case it is out of date")
set(CIFPP_RECREATE_SYMOP_DATA ON CACHE BOOL "Recreate SymOp data table in case it is out of date")
endif()
# CCP4 build
if(BUILD_FOR_CCP4)
if("$ENV{CCP4}" STREQUAL "" OR NOT EXISTS $ENV{CCP4})
message(FATAL_ERROR "cifpp: A CCP4 built was requested but CCP4 was not sourced")
else()
list(PREPEND CMAKE_MODULE_PATH "$ENV{CCP4}")
list(PREPEND CMAKE_PREFIX_PATH "$ENV{CCP4}")
set(CMAKE_INSTALL_PREFIX "$ENV{CCP4}")
if("$ENV{CCP4}" STREQUAL "" OR NOT EXISTS $ENV{CCP4})
message(FATAL_ERROR "cifpp: A CCP4 built was requested but CCP4 was not sourced")
else()
list(PREPEND CMAKE_MODULE_PATH "$ENV{CCP4}")
list(PREPEND CMAKE_PREFIX_PATH "$ENV{CCP4}")
set(CMAKE_INSTALL_PREFIX "$ENV{CCP4}")
if(WIN32)
set(BUILD_SHARED_LIBS ON)
endif()
endif()
if(WIN32)
set(BUILD_SHARED_LIBS ON)
endif()
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()
# We do not want to write an export file for all our symbols...
set(CMAKE_WINDOWS_EXPORT_ALL_SYMBOLS ON)
# 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)
add_link_options(/NODEFAULTLIB:library)
# make msvc standards compliant...
add_compile_options(/permissive- /bigobj)
add_link_options(/NODEFAULTLIB:library)
# This is dubious...
if(BUILD_SHARED_LIBS)
set(CMAKE_MSVC_RUNTIME_LIBRARY "MultiThreaded$<$<CONFIG:Debug>:Debug>DLL")
else()
set(CMAKE_MSVC_RUNTIME_LIBRARY "MultiThreaded$<$<CONFIG:Debug>:Debug>")
endif()
# This is dubious...
if(BUILD_SHARED_LIBS)
set(CMAKE_MSVC_RUNTIME_LIBRARY "MultiThreaded$<$<CONFIG:Debug>:Debug>DLL")
else()
set(CMAKE_MSVC_RUNTIME_LIBRARY "MultiThreaded$<$<CONFIG:Debug>:Debug>")
endif()
endif()
# Libraries
if(MSVC)
# Avoid linking the shared library of zlib. Search ZLIB_ROOT first if it is
# set.
if(ZLIB_ROOT)
set(_ZLIB_SEARCH_ROOT PATHS ${ZLIB_ROOT} NO_DEFAULT_PATH)
list(APPEND _ZLIB_SEARCHES _ZLIB_SEARCH_ROOT)
endif()
# Avoid linking the shared library of zlib. Search ZLIB_ROOT first if it is
# set.
if(ZLIB_ROOT)
set(_ZLIB_SEARCH_ROOT PATHS ${ZLIB_ROOT} NO_DEFAULT_PATH)
list(APPEND _ZLIB_SEARCHES _ZLIB_SEARCH_ROOT)
endif()
# Normal search.
set(_ZLIB_x86 "(x86)")
set(_ZLIB_SEARCH_NORMAL
PATHS "[HKEY_LOCAL_MACHINE\\SOFTWARE\\GnuWin32\\Zlib;InstallPath]"
"$ENV{ProgramFiles}/zlib" "$ENV{ProgramFiles${_ZLIB_x86}}/zlib")
unset(_ZLIB_x86)
list(APPEND _ZLIB_SEARCHES _ZLIB_SEARCH_NORMAL)
# Normal search.
set(_ZLIB_x86 "(x86)")
set(_ZLIB_SEARCH_NORMAL
PATHS "[HKEY_LOCAL_MACHINE\\SOFTWARE\\GnuWin32\\Zlib;InstallPath]"
"$ENV{ProgramFiles}/zlib" "$ENV{ProgramFiles${_ZLIB_x86}}/zlib")
unset(_ZLIB_x86)
list(APPEND _ZLIB_SEARCHES _ZLIB_SEARCH_NORMAL)
if(BUILD_FOR_CCP4)
list(PREPEND _ZLIB_SEARCHES "$ENV{CCP4}/lib")
endif()
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()
foreach(search ${_ZLIB_SEARCHES})
find_library(
ZLIB_LIBRARY
NAMES zlibstatic NAMES_PER_DIR ${${search}}
PATH_SUFFIXES lib)
endforeach()
endif()
set(CMAKE_CXX_STANDARD 20)
# Using fast_float for float parsing, but only if needed
try_compile(STD_CHARCONV_COMPILING
SOURCES ${CMAKE_CURRENT_SOURCE_DIR}/cmake/test-charconv.cpp
CXX_STANDARD 20
CXX_STANDARD_REQUIRED ON)
SOURCES ${CMAKE_CURRENT_SOURCE_DIR}/cmake/test-charconv.cpp
CXX_STANDARD 20
CXX_STANDARD_REQUIRED ON)
if(NOT STD_CHARCONV_COMPILING)
message(NOTICE "libcifpp: Using fast_float for std::from_chars")
find_package(FastFloat 8.0 QUIET CONFIG)
if(NOT FastFloat_FOUND)
message(STATUS "FastFloat not found in system, fetching from GitHub")
FetchContent_Declare(fastfloat
GIT_REPOSITORY "https://github.com/fastfloat/fast_float"
GIT_TAG v8.0.2
EXCLUDE_FROM_ALL)
FetchContent_MakeAvailable(fastfloat)
endif()
message(NOTICE "libcifpp: Using fast_float for std::from_chars")
find_package(FastFloat 8.0 QUIET CONFIG)
if(NOT FastFloat_FOUND)
message(STATUS "FastFloat not found in system, fetching from GitHub")
FetchContent_Declare(fastfloat
GIT_REPOSITORY "https://github.com/fastfloat/fast_float"
GIT_TAG v8.0.2
EXCLUDE_FROM_ALL)
FetchContent_MakeAvailable(fastfloat)
endif()
endif()
find_package(Threads)
find_package(ZLIB QUIET)
if(NOT ZLIB_FOUND)
message(FATAL_ERROR "cifpp: The zlib development files were not found you this system, please install them and try again (hint: on debian/ubuntu use apt-get install zlib1g-dev)")
message(FATAL_ERROR "cifpp: The zlib development files were not found you this system, please install them and try again (hint: on debian/ubuntu use apt-get install zlib1g-dev)")
endif()
include(FindPkgConfig)
if(PKG_CONFIG_FOUND)
pkg_check_modules(PCRE2 IMPORTED_TARGET libpcre2-8)
pkg_check_modules(PCRE2 IMPORTED_TARGET libpcre2-8)
endif()
if(NOT PCRE2_FOUND)
add_subdirectory(pcre2-simple)
add_subdirectory(pcre2-simple)
endif()
# Using Eigen3 is a bit of a thing. We don't want to build it completely since
@@ -218,40 +218,40 @@ endif()
find_package(Eigen3 3.4 QUIET)
if(Eigen3_FOUND AND TARGET Eigen3::Eigen)
get_target_property(EIGEN_INCLUDE_DIR Eigen3::Eigen
INTERFACE_INCLUDE_DIRECTORIES)
get_target_property(EIGEN_INCLUDE_DIR Eigen3::Eigen
INTERFACE_INCLUDE_DIRECTORIES)
else()
# Use ExternalProject since FetchContent always tries to install the result...
ExternalProject_Add(my-eigen3
URL https://gitlab.com/libeigen/eigen/-/archive/3.4.0/eigen-3.4.0.zip
DOWNLOAD_EXTRACT_TIMESTAMP TRUE
CONFIGURE_COMMAND ""
BUILD_COMMAND ""
INSTALL_COMMAND "")
# Use ExternalProject since FetchContent always tries to install the result...
ExternalProject_Add(my-eigen3
URL https://gitlab.com/libeigen/eigen/-/archive/3.4.0/eigen-3.4.0.zip
DOWNLOAD_EXTRACT_TIMESTAMP TRUE
CONFIGURE_COMMAND ""
BUILD_COMMAND ""
INSTALL_COMMAND "")
ExternalProject_Get_Property(my-eigen3 SOURCE_DIR)
set(EIGEN_INCLUDE_DIR ${SOURCE_DIR})
ExternalProject_Get_Property(my-eigen3 SOURCE_DIR)
set(EIGEN_INCLUDE_DIR ${SOURCE_DIR})
endif()
# SymOp data table
if(CIFPP_RECREATE_SYMOP_DATA)
# The tool to create the table
add_executable(symop-map-generator
"${CMAKE_CURRENT_SOURCE_DIR}/src/symop-map-generator.cpp")
# The tool to create the table
add_executable(symop-map-generator
"${CMAKE_CURRENT_SOURCE_DIR}/src/symop-map-generator.cpp")
target_compile_features(symop-map-generator PUBLIC cxx_std_20)
target_compile_features(symop-map-generator PUBLIC cxx_std_20)
add_custom_command(
OUTPUT ${CMAKE_CURRENT_SOURCE_DIR}/src/symop_table_data.hpp
COMMAND
$<TARGET_FILE:symop-map-generator> $ENV{CLIBD}/syminfo.lib
$ENV{CLIBD}/symop.lib ${CMAKE_CURRENT_SOURCE_DIR}/src/symop_table_data.hpp)
add_custom_command(
OUTPUT ${CMAKE_CURRENT_SOURCE_DIR}/src/symop_table_data.hpp
COMMAND
$<TARGET_FILE:symop-map-generator> $ENV{CLIBD}/syminfo.lib
$ENV{CLIBD}/symop.lib ${CMAKE_CURRENT_SOURCE_DIR}/src/symop_table_data.hpp)
add_custom_target(
OUTPUT
${CMAKE_CURRENT_SOURCE_DIR}/src/symop_table_data.hpp
DEPENDS symop-map-generator "$ENV{CLIBD}/syminfo.lib"
"$ENV{CLIBD}/symop.lib")
add_custom_target(
OUTPUT
${CMAKE_CURRENT_SOURCE_DIR}/src/symop_table_data.hpp
DEPENDS symop-map-generator "$ENV{CLIBD}/syminfo.lib"
"$ENV{CLIBD}/symop.lib")
endif()
# Create a revision file, containing the current git version info
@@ -262,324 +262,333 @@ add_library(cifpp::cifpp ALIAS cifpp)
# Sources
list(APPEND project_sources
${CMAKE_CURRENT_SOURCE_DIR}/src/category.cpp
${CMAKE_CURRENT_SOURCE_DIR}/src/condition.cpp
${CMAKE_CURRENT_SOURCE_DIR}/src/datablock.cpp
${CMAKE_CURRENT_SOURCE_DIR}/src/dictionary_parser.cpp
${CMAKE_CURRENT_SOURCE_DIR}/src/file.cpp
${CMAKE_CURRENT_SOURCE_DIR}/src/item.cpp
${CMAKE_CURRENT_SOURCE_DIR}/src/parser.cpp
${CMAKE_CURRENT_SOURCE_DIR}/src/row.cpp
${CMAKE_CURRENT_SOURCE_DIR}/src/validate.cpp
${CMAKE_CURRENT_SOURCE_DIR}/src/text.cpp
${CMAKE_CURRENT_SOURCE_DIR}/src/utilities.cpp
${CMAKE_CURRENT_SOURCE_DIR}/src/atom_type.cpp
${CMAKE_CURRENT_SOURCE_DIR}/src/compound.cpp
${CMAKE_CURRENT_SOURCE_DIR}/src/point.cpp
${CMAKE_CURRENT_SOURCE_DIR}/src/symmetry.cpp
${CMAKE_CURRENT_SOURCE_DIR}/src/model.cpp
${CMAKE_CURRENT_SOURCE_DIR}/src/cql.cpp
${CMAKE_CURRENT_SOURCE_DIR}/src/pdb/cif2pdb.cpp
${CMAKE_CURRENT_SOURCE_DIR}/src/pdb/pdb2cif.cpp
${CMAKE_CURRENT_SOURCE_DIR}/src/pdb/pdb_record.hpp
${CMAKE_CURRENT_SOURCE_DIR}/src/pdb/pdb2cif_remark_3.hpp
${CMAKE_CURRENT_SOURCE_DIR}/src/pdb/pdb2cif_remark_3.cpp
${CMAKE_CURRENT_SOURCE_DIR}/src/pdb/reconstruct.cpp
${CMAKE_CURRENT_SOURCE_DIR}/src/pdb/validate-pdbx.cpp
${CMAKE_CURRENT_SOURCE_DIR}/src/category.cpp
${CMAKE_CURRENT_SOURCE_DIR}/src/condition.cpp
${CMAKE_CURRENT_SOURCE_DIR}/src/datablock.cpp
${CMAKE_CURRENT_SOURCE_DIR}/src/dictionary_parser.cpp
${CMAKE_CURRENT_SOURCE_DIR}/src/file.cpp
${CMAKE_CURRENT_SOURCE_DIR}/src/item.cpp
${CMAKE_CURRENT_SOURCE_DIR}/src/parser.cpp
${CMAKE_CURRENT_SOURCE_DIR}/src/row.cpp
${CMAKE_CURRENT_SOURCE_DIR}/src/validate.cpp
${CMAKE_CURRENT_SOURCE_DIR}/src/text.cpp
${CMAKE_CURRENT_SOURCE_DIR}/src/utilities.cpp
${CMAKE_CURRENT_SOURCE_DIR}/src/atom_type.cpp
${CMAKE_CURRENT_SOURCE_DIR}/src/compound.cpp
${CMAKE_CURRENT_SOURCE_DIR}/src/point.cpp
${CMAKE_CURRENT_SOURCE_DIR}/src/symmetry.cpp
${CMAKE_CURRENT_SOURCE_DIR}/src/model.cpp
${CMAKE_CURRENT_SOURCE_DIR}/src/cql.cpp
${CMAKE_CURRENT_SOURCE_DIR}/src/pdb/cif2pdb.cpp
${CMAKE_CURRENT_SOURCE_DIR}/src/pdb/pdb2cif.cpp
${CMAKE_CURRENT_SOURCE_DIR}/src/pdb/pdb_record.hpp
${CMAKE_CURRENT_SOURCE_DIR}/src/pdb/pdb2cif_remark_3.hpp
${CMAKE_CURRENT_SOURCE_DIR}/src/pdb/pdb2cif_remark_3.cpp
${CMAKE_CURRENT_SOURCE_DIR}/src/pdb/reconstruct.cpp
${CMAKE_CURRENT_SOURCE_DIR}/src/pdb/validate-pdbx.cpp
)
if(BUILD_SQLITE_INTERFACE)
find_package(sqlite3 QUIET)
if(sqlite3_FOUND)
target_link_libraries(cifpp PRIVATE sqlite3)
else()
FetchContent_Populate(sqlite3
URL https://sqlite.org/2025/sqlite-amalgamation-3510100.zip
URL_HASH SHA3_256=856b52ffe7383d779bb86a0ed1ddc19c41b0e5751fa14ce6312f27534e629b64
EXCLUDE_FROM_ALL)
find_package(sqlite3 QUIET)
if(sqlite3_FOUND)
target_link_libraries(cifpp PRIVATE sqlite3)
else()
FetchContent_Populate(sqlite3
URL https://sqlite.org/2025/sqlite-amalgamation-3510100.zip
URL_HASH SHA3_256=856b52ffe7383d779bb86a0ed1ddc19c41b0e5751fa14ce6312f27534e629b64
EXCLUDE_FROM_ALL)
list(APPEND project_sources $<BUILD_INTERFACE:${sqlite3_SOURCE_DIR}>/sqlite3.c)
target_include_directories(cifpp PRIVATE $<BUILD_INTERFACE:${sqlite3_SOURCE_DIR}>)
endif()
list(APPEND project_sources $<BUILD_INTERFACE:${sqlite3_SOURCE_DIR}>/sqlite3.c)
target_include_directories(cifpp PRIVATE $<BUILD_INTERFACE:${sqlite3_SOURCE_DIR}>)
endif()
endif()
list(APPEND project_headers
include/cif++.hpp
include/cif++/atom_type.hpp
include/cif++/category.hpp
include/cif++/compound.hpp
include/cif++/condition.hpp
include/cif++/datablock.hpp
include/cif++/dictionary_parser.hpp
include/cif++/exports.hpp
include/cif++/file.hpp
include/cif++/format.hpp
include/cif++/forward_decl.hpp
include/cif++/gzio.hpp
include/cif++/item.hpp
include/cif++/iterator.hpp
include/cif++/matrix.hpp
include/cif++/model.hpp
include/cif++/parser.hpp
include/cif++/pdb.hpp
include/cif++/point.hpp
include/cif++/row.hpp
include/cif++/symmetry.hpp
include/cif++/text.hpp
include/cif++/cql.hpp
include/cif++/utilities.hpp
include/cif++/validate.hpp
include/cif++.hpp
include/cif++/atom_type.hpp
include/cif++/category.hpp
include/cif++/compound.hpp
include/cif++/condition.hpp
include/cif++/datablock.hpp
include/cif++/dictionary_parser.hpp
include/cif++/exports.hpp
include/cif++/file.hpp
include/cif++/format.hpp
include/cif++/forward_decl.hpp
include/cif++/gzio.hpp
include/cif++/item.hpp
include/cif++/iterator.hpp
include/cif++/matrix.hpp
include/cif++/model.hpp
include/cif++/parser.hpp
include/cif++/pdb.hpp
include/cif++/point.hpp
include/cif++/row.hpp
include/cif++/symmetry.hpp
include/cif++/text.hpp
include/cif++/cql.hpp
include/cif++/utilities.hpp
include/cif++/validate.hpp
)
if(TARGET my-eigen3)
add_dependencies(cifpp my-eigen3)
add_dependencies(cifpp my-eigen3)
endif()
target_sources(cifpp
PRIVATE ${project_sources}
${CMAKE_CURRENT_SOURCE_DIR}/src/symop_table_data.hpp
PUBLIC
FILE_SET cifpp_headers TYPE HEADERS
BASE_DIRS ${CMAKE_CURRENT_SOURCE_DIR}/include
FILES ${project_headers}
PRIVATE ${project_sources}
${CMAKE_CURRENT_SOURCE_DIR}/src/symop_table_data.hpp
PUBLIC
FILE_SET cifpp_headers TYPE HEADERS
BASE_DIRS ${CMAKE_CURRENT_SOURCE_DIR}/include
FILES ${project_headers}
)
# The code now really requires C++20
target_compile_features(cifpp PUBLIC cxx_std_20)
find_program(CLANG_TIDY_EXE "clang-tidy")
if(CLANG_TIDY_EXE)
message(STATUS "clang-tidy found: ${CLANG_TIDY_EXE}")
set(CMAKE_CXX_CLANG_TIDY ${CLANG_TIDY_EXE} --warnings-as-errors=-*)
else()
message(WARNING "clang-tidy not found!")
endif()
generate_export_header(cifpp EXPORT_FILE_NAME
${CMAKE_CURRENT_SOURCE_DIR}/include/cif++/exports.hpp)
${CMAKE_CURRENT_SOURCE_DIR}/include/cif++/exports.hpp)
if(MSVC)
target_compile_definitions(cifpp PUBLIC NOMINMAX=1)
target_compile_definitions(cifpp PUBLIC NOMINMAX=1)
endif()
set_target_properties(cifpp PROPERTIES POSITION_INDEPENDENT_CODE ON)
target_include_directories(
cifpp
PUBLIC "$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include>"
"$<INSTALL_INTERFACE:${CMAKE_INSTALL_INCLUDEDIR}>"
PRIVATE "${EIGEN_INCLUDE_DIR}")
cifpp
PUBLIC "$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include>"
"$<INSTALL_INTERFACE:${CMAKE_INSTALL_INCLUDEDIR}>"
PRIVATE "${EIGEN_INCLUDE_DIR}")
target_link_libraries(cifpp
PUBLIC Threads::Threads ZLIB::ZLIB $<$<TARGET_EXISTS:std::atomic>:std::atomic>)
PUBLIC Threads::Threads ZLIB::ZLIB $<$<TARGET_EXISTS:std::atomic>:std::atomic>)
if(PCRE2_FOUND)
target_include_directories(cifpp PRIVATE ${PCRE2_INCLUDE_DIRS})
target_link_libraries(cifpp PRIVATE ${PCRE2_LINK_LIBRARIES})
target_include_directories(cifpp PRIVATE ${PCRE2_INCLUDE_DIRS})
target_link_libraries(cifpp PRIVATE ${PCRE2_LINK_LIBRARIES})
else()
target_link_libraries(cifpp PRIVATE $<BUILD_INTERFACE:pcre2s>)
target_link_libraries(cifpp PRIVATE $<BUILD_INTERFACE:pcre2s>)
endif()
if(NOT STD_CHARCONV_COMPILING)
target_link_libraries(cifpp PRIVATE FastFloat::fast_float)
target_link_libraries(cifpp PRIVATE FastFloat::fast_float)
endif()
if(CMAKE_CXX_COMPILER_ID STREQUAL "AppleClang")
target_link_options(cifpp PRIVATE -undefined dynamic_lookup)
target_link_options(cifpp PRIVATE -undefined dynamic_lookup)
endif(CMAKE_CXX_COMPILER_ID STREQUAL "AppleClang")
if(CIFPP_DOWNLOAD_CCD)
# download the components.cif file from CCD
set(COMPONENTS_CIF ${CMAKE_CURRENT_SOURCE_DIR}/rsrc/components.cif)
# download the components.cif file from CCD
set(COMPONENTS_CIF ${CMAKE_CURRENT_SOURCE_DIR}/rsrc/components.cif)
if(EXISTS ${COMPONENTS_CIF})
file(SIZE ${COMPONENTS_CIF} CCD_FILE_SIZE)
if(EXISTS ${COMPONENTS_CIF})
file(SIZE ${COMPONENTS_CIF} CCD_FILE_SIZE)
if(CCD_FILE_SIZE EQUAL 0)
message(STATUS "cifpp: Removing empty ${COMPONENTS_CIF} file")
file(REMOVE "${COMPONENTS_CIF}")
endif()
endif()
if(CCD_FILE_SIZE EQUAL 0)
message(STATUS "cifpp: Removing empty ${COMPONENTS_CIF} file")
file(REMOVE "${COMPONENTS_CIF}")
endif()
endif()
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(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()
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 ${CMAKE_CURRENT_SOURCE_DIR}/rsrc/)
add_custom_command(
OUTPUT ${COMPONENTS_CIF}
COMMAND "${GUNZIP}" ${COMPONENTS_CIF}.gz
WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/rsrc/)
add_custom_target(COMPONENTS ALL DEPENDS ${COMPONENTS_CIF})
endif()
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)
# 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 "cifpp: Error trying to download CCD file: ${CCD_FETCH_STATUS}")
endif()
endif()
if(CCD_FETCH_STATUS_CODE)
message(
FATAL_ERROR "cifpp: Error trying to download CCD file: ${CCD_FETCH_STATUS}")
endif()
endif()
endif()
# Installation directories
if(BUILD_FOR_CCP4)
set(CIFPP_DATA_DIR
"$ENV{CCP4}/share/libcifpp"
CACHE PATH "Directory where dictionary and other static data is stored")
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")
set(CIFPP_DATA_DIR
"${CMAKE_INSTALL_FULL_DATADIR}/libcifpp"
CACHE PATH "Directory where dictionary and other static data is stored")
endif()
if(CIFPP_DATA_DIR)
target_compile_definitions(cifpp PUBLIC DATA_DIR="${CIFPP_DATA_DIR}")
set_target_properties(cifpp PROPERTIES CIFPP_DATA_DIR ${CIFPP_DATA_DIR})
target_compile_definitions(cifpp PUBLIC DATA_DIR="${CIFPP_DATA_DIR}")
set_target_properties(cifpp PROPERTIES CIFPP_DATA_DIR ${CIFPP_DATA_DIR})
endif()
if(NOT PROJECT_IS_TOP_LEVEL)
set(CIFPP_SHARE_DIR ${CIFPP_DATA_DIR} PARENT_SCOPE)
set(CIFPP_SHARE_DIR ${CIFPP_DATA_DIR} PARENT_SCOPE)
endif()
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()
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}")
target_compile_definitions(cifpp PUBLIC CACHE_DIR="${CIFPP_CACHE_DIR}")
set(CIFPP_ETC_DIR
"${CMAKE_INSTALL_FULL_SYSCONFDIR}"
CACHE PATH "The directory where the update configuration file is stored")
set(CIFPP_ETC_DIR
"${CMAKE_INSTALL_FULL_SYSCONFDIR}"
CACHE PATH "The directory where the update configuration file is stored")
else()
unset(CIFPP_CACHE_DIR)
unset(CIFPP_CACHE_DIR)
endif()
# Install rules
install(TARGETS cifpp
EXPORT cifpp
FILE_SET cifpp_headers DESTINATION ${CMAKE_INSTALL_INCLUDEDIR})
EXPORT cifpp
FILE_SET cifpp_headers DESTINATION ${CMAKE_INSTALL_INCLUDEDIR})
if(MSVC AND BUILD_SHARED_LIBS)
install(
FILES $<TARGET_PDB_FILE:cifpp>
DESTINATION ${CMAKE_INSTALL_LIBDIR}
OPTIONAL)
install(
FILES $<TARGET_PDB_FILE:cifpp>
DESTINATION ${CMAKE_INSTALL_LIBDIR}
OPTIONAL)
endif()
# 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)
${CMAKE_INSTALL_FULL_LIBDIR}/cmake/cifpp/cifppConfig*.cmake
${CMAKE_INSTALL_FULL_LIBDIR}/cmake/cifpp/cifppTargets*.cmake)
if(OLD_CONFIG_FILES)
message(
STATUS "cifpp: Installation will remove old config files: ${OLD_CONFIG_FILES}")
install(CODE "file(REMOVE ${OLD_CONFIG_FILES})")
message(
STATUS "cifpp: Installation will remove old config files: ${OLD_CONFIG_FILES}")
install(CODE "file(REMOVE ${OLD_CONFIG_FILES})")
endif()
install(EXPORT cifpp
NAMESPACE cifpp::
FILE "cifpp-targets.cmake"
DESTINATION lib/cmake/cifpp)
NAMESPACE cifpp::
FILE "cifpp-targets.cmake"
DESTINATION lib/cmake/cifpp)
install(
FILES ${CMAKE_CURRENT_SOURCE_DIR}/rsrc/mmcif_ddl.dic
${CMAKE_CURRENT_SOURCE_DIR}/rsrc/mmcif_pdbx.dic
${CMAKE_CURRENT_SOURCE_DIR}/rsrc/mmcif_ma.dic
DESTINATION ${CMAKE_INSTALL_DATADIR}/libcifpp)
FILES ${CMAKE_CURRENT_SOURCE_DIR}/rsrc/mmcif_ddl.dic
${CMAKE_CURRENT_SOURCE_DIR}/rsrc/mmcif_pdbx.dic
${CMAKE_CURRENT_SOURCE_DIR}/rsrc/mmcif_ma.dic
DESTINATION ${CMAKE_INSTALL_DATADIR}/libcifpp)
if(CIFPP_DATA_DIR AND CIFPP_DOWNLOAD_CCD)
install(FILES ${COMPONENTS_CIF}
DESTINATION ${CMAKE_INSTALL_DATADIR}/libcifpp)
install(FILES ${COMPONENTS_CIF}
DESTINATION ${CMAKE_INSTALL_DATADIR}/libcifpp)
endif()
set(CONFIG_TEMPLATE_FILE ${CMAKE_CURRENT_SOURCE_DIR}/cmake/cifpp-config.cmake.in)
configure_package_config_file(
${CONFIG_TEMPLATE_FILE} ${CMAKE_CURRENT_BINARY_DIR}/cifpp/cifpp-config.cmake
INSTALL_DESTINATION lib/cmake/cifpp
PATH_VARS CIFPP_DATA_DIR)
${CONFIG_TEMPLATE_FILE} ${CMAKE_CURRENT_BINARY_DIR}/cifpp/cifpp-config.cmake
INSTALL_DESTINATION lib/cmake/cifpp
PATH_VARS CIFPP_DATA_DIR)
install(
FILES "${CMAKE_CURRENT_BINARY_DIR}/cifpp/cifpp-config.cmake"
"${CMAKE_CURRENT_BINARY_DIR}/cifpp/cifpp-config-version.cmake"
DESTINATION lib/cmake/cifpp)
FILES "${CMAKE_CURRENT_BINARY_DIR}/cifpp/cifpp-config.cmake"
"${CMAKE_CURRENT_BINARY_DIR}/cifpp/cifpp-config-version.cmake"
DESTINATION lib/cmake/cifpp)
set_target_properties(
cifpp
PROPERTIES VERSION ${PROJECT_VERSION}
SOVERSION "${PROJECT_VERSION_MAJOR}.${PROJECT_VERSION_MINOR}"
INTERFACE_cifpp_MAJOR_VERSION ${PROJECT_VERSION_MAJOR})
cifpp
PROPERTIES VERSION ${PROJECT_VERSION}
SOVERSION "${PROJECT_VERSION_MAJOR}.${PROJECT_VERSION_MINOR}"
INTERFACE_cifpp_MAJOR_VERSION ${PROJECT_VERSION_MAJOR})
set_property(
TARGET cifpp
APPEND
PROPERTY COMPATIBLE_INTERFACE_STRING cifpp_MAJOR_VERSION)
TARGET cifpp
APPEND
PROPERTY COMPATIBLE_INTERFACE_STRING cifpp_MAJOR_VERSION)
write_basic_package_version_file(
"${CMAKE_CURRENT_BINARY_DIR}/cifpp/cifpp-config-version.cmake"
VERSION ${PROJECT_VERSION}
COMPATIBILITY AnyNewerVersion)
"${CMAKE_CURRENT_BINARY_DIR}/cifpp/cifpp-config-version.cmake"
VERSION ${PROJECT_VERSION}
COMPATIBILITY AnyNewerVersion)
if(BUILD_TESTING AND PROJECT_IS_TOP_LEVEL)
add_subdirectory(test)
add_subdirectory(test)
endif()
# Optionally install the update scripts for CCD and dictionary files
if(CIFPP_INSTALL_UPDATE_SCRIPT)
configure_file(${CMAKE_CURRENT_SOURCE_DIR}/tools/update-libcifpp-data.in
update-libcifpp-data @ONLY)
configure_file(${CMAKE_CURRENT_SOURCE_DIR}/tools/update-libcifpp-data.in
update-libcifpp-data @ONLY)
if(${CMAKE_SYSTEM_NAME} STREQUAL "Linux" OR
${CMAKE_SYSTEM_NAME} STREQUAL "GNU" OR
${CMAKE_SYSTEM_NAME} STREQUAL "FreeBSD")
install(
FILES ${CMAKE_CURRENT_BINARY_DIR}/update-libcifpp-data
DESTINATION ${CMAKE_INSTALL_SYSCONFDIR}/cron.weekly
PERMISSIONS OWNER_EXECUTE OWNER_READ GROUP_EXECUTE GROUP_READ WORLD_EXECUTE
WORLD_READ)
else()
message(FATAL_ERROR "cifpp: Don't know where to install the update script")
endif()
if(${CMAKE_SYSTEM_NAME} STREQUAL "Linux" OR
${CMAKE_SYSTEM_NAME} STREQUAL "GNU" OR
${CMAKE_SYSTEM_NAME} STREQUAL "FreeBSD")
install(
FILES ${CMAKE_CURRENT_BINARY_DIR}/update-libcifpp-data
DESTINATION ${CMAKE_INSTALL_SYSCONFDIR}/cron.weekly
PERMISSIONS OWNER_EXECUTE OWNER_READ GROUP_EXECUTE GROUP_READ WORLD_EXECUTE
WORLD_READ)
else()
message(FATAL_ERROR "cifpp: Don't know where to install the update script")
endif()
# a config file, to make it complete
# install(DIRECTORY DESTINATION "${CMAKE_INSTALL_LOCALSTATEDIR}/libcifpp")
if(NOT EXISTS "${CMAKE_INSTALL_SYSCONFDIR}/libcifpp.conf")
file(
WRITE ${CMAKE_CURRENT_BINARY_DIR}/libcifpp.conf
[[# Uncomment the next line to enable automatic updates
# a config file, to make it complete
# install(DIRECTORY DESTINATION "${CMAKE_INSTALL_LOCALSTATEDIR}/libcifpp")
if(NOT EXISTS "${CMAKE_INSTALL_SYSCONFDIR}/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 ${CMAKE_INSTALL_SYSCONFDIR})
install(
CODE "message(\"cifpp: A configuration file has been written to ${CIFPP_ETC_DIR}/libcifpp.conf, please edit this file to enable automatic updates\")"
)
install(FILES ${CMAKE_CURRENT_BINARY_DIR}/libcifpp.conf
DESTINATION ${CMAKE_INSTALL_SYSCONFDIR})
install(
CODE "message(\"cifpp: A configuration file has been written to ${CIFPP_ETC_DIR}/libcifpp.conf, please edit this file to enable automatic updates\")"
)
install(DIRECTORY DESTINATION ${CMAKE_INSTALL_SYSCONFDIR}/libcifpp/cache-update.d)
endif()
install(DIRECTORY DESTINATION ${CMAKE_INSTALL_SYSCONFDIR}/libcifpp/cache-update.d)
endif()
target_compile_definitions(cifpp PUBLIC CACHE_DIR="${CIFPP_CACHE_DIR}")
target_compile_definitions(cifpp PUBLIC CACHE_DIR="${CIFPP_CACHE_DIR}")
endif()
if(BUILD_DOCUMENTATION)
add_subdirectory(docs)
add_subdirectory(docs)
endif()

View File

@@ -33,6 +33,7 @@
#include "cif++/exports.hpp"
#include <array>
#include <cstdint>
#include <limits>
#include <stdexcept>
@@ -235,7 +236,7 @@ struct atom_type_info
/// Array containing all known radii for this element. A value of kNA is
/// stored for unknown values
float radii[kRadiusTypeCount];
std::array<float, kRadiusTypeCount> radii;
};
/// Array of atom_type_info struct for each of the defined elements in atom_type
@@ -256,12 +257,12 @@ class atom_type_traits
/// Constructor based on the element as a string in \a symbol
atom_type_traits(const std::string &symbol);
atom_type type() const { return m_info->type; } ///< Returns the atom_type
std::string name() const { return m_info->name; } ///< Returns the name of the element
std::string symbol() const { return m_info->symbol; } ///< Returns the symbol of the element
float weight() const { return m_info->weight; } ///< Returns the average weight of the element
[[nodiscard]] atom_type type() const { return m_info->type; } ///< Returns the atom_type
[[nodiscard]] std::string name() const { return m_info->name; } ///< Returns the name of the element
[[nodiscard]] std::string symbol() const { return m_info->symbol; } ///< Returns the symbol of the element
[[nodiscard]] float weight() const { return m_info->weight; } ///< Returns the average weight of the element
bool is_metal() const { return m_info->metal; } ///< Returns true if the element is a metal
[[nodiscard]] bool is_metal() const { return m_info->metal; } ///< Returns true if the element is a metal
/// Return true if the symbol in \a symbol actually exists in the list of known elements in atom_type
static bool is_element(const std::string &symbol);
@@ -272,7 +273,7 @@ class atom_type_traits
/// @brief Return the radius for the element, use \a type to select which radius to return
/// @param type The selector for which radius to return
/// @return The requested radius or kNA if not known (or applicable)
float radius(radius_type type = radius_type::single_bond) const
[[nodiscard]] float radius(radius_type type = radius_type::single_bond) const
{
if (type >= radius_type::type_count)
throw std::invalid_argument("invalid radius requested");
@@ -283,20 +284,20 @@ class atom_type_traits
///
/// \param charge The charge of the ion
/// \return The radius of the ion
float crystal_ionic_radius(int charge) const;
[[nodiscard]] float crystal_ionic_radius(int charge) const;
/// \brief Return the radius for a charged version of this atom in a non-solid environment
///
/// \param charge The charge of the ion
/// \return The radius of the ion
float effective_ionic_radius(int charge) const;
[[nodiscard]] float effective_ionic_radius(int charge) const;
/// \brief Return the radius for a charged version of this atom, returns the effective radius by default
///
/// \param charge The charge of the ion
/// \param type The requested ion radius type
/// \return The radius of the ion
float ionic_radius(int charge, ionic_radius_type type = ionic_radius_type::effective) const
[[nodiscard]] float ionic_radius(int charge, ionic_radius_type type = ionic_radius_type::effective) const
{
return type == ionic_radius_type::effective ? effective_ionic_radius(charge) : crystal_ionic_radius(charge);
}

View File

@@ -26,6 +26,8 @@
#pragma once
#include <utility>
#include "cif++/condition.hpp"
#include "cif++/forward_decl.hpp"
#include "cif++/iterator.hpp"
@@ -79,13 +81,13 @@ class missing_key_error : public std::runtime_error
/**
* @brief Construct a new duplicate key error object
*/
missing_key_error(const std::string &msg, const std::string &key)
missing_key_error(const std::string &msg, std::string key)
: std::runtime_error(msg)
, m_key(key)
, m_key(std::move(key))
{
}
const std::string &get_key() const noexcept { return m_key; }
[[nodiscard]] const std::string &get_key() const noexcept { return m_key; }
private:
std::string m_key;
@@ -99,7 +101,7 @@ class multiple_results_error : public std::runtime_error
/**
* @brief Construct a new multiple results error object
*/
multiple_results_error()
multiple_results_error() // NOLINT
: std::runtime_error("query should have returned exactly one row")
{
}
@@ -176,7 +178,7 @@ class category
// --------------------------------------------------------------------
const std::string &name() const { return m_name; } ///< Returns the name of the category
[[nodiscard]] const std::string &name() const { return m_name; } ///< Returns the name of the category
/// \brief Rename category to @a new_name
void name(std::string_view new_name)
@@ -186,7 +188,7 @@ class category
}
/// \brief Return true if the category has been modified since last open/save
constexpr bool is_dirty() const
[[nodiscard]] constexpr bool is_dirty() const
{
return m_dirty;
}
@@ -198,14 +200,14 @@ class category
}
// --------------------------------------------------------------------
[[deprecated("use key_items instead")]] iset key_fields() const; ///< Returns the cif::iset of key item names. Retrieved from the @ref category_validator for this category
iset key_items() const; ///< Returns the cif::iset of key item names. Retrieved from the @ref category_validator for this category
[[deprecated("use key_items instead")]] [[nodiscard]] iset key_fields() const; ///< Returns the cif::iset of key item names. Retrieved from the @ref category_validator for this category
[[deprecated("use key_item_indices instead")]] std::set<uint16_t> key_field_indices() const; ///< Returns a set of indices for the key items.
[[nodiscard]] iset key_items() const; ///< Returns the cif::iset of key item names. Retrieved from the @ref category_validator for this category
std::set<uint16_t> key_item_indices() const; ///< Returns a set of indices for the key items.
[[deprecated("use key_item_indices instead")]] [[nodiscard]] std::set<uint16_t> key_field_indices() const; ///< Returns a set of indices for the key items.
[[nodiscard]] std::set<uint16_t> key_item_indices() const; ///< Returns a set of indices for the key items.
/// @brief Set the validator for this category to @a v
/// @param v The category_validator to assign. A nullptr value is allowed.
@@ -218,15 +220,15 @@ class category
/// @brief Return the global @ref validator for the data
/// @return The @ref validator or nullptr if not assigned
const validator *get_validator() const { return m_validator; }
[[nodiscard]] const validator *get_validator() const { return m_validator; }
/// @brief Return the category validator for this category
/// @return The @ref category_validator or nullptr if not assigned
const category_validator *get_cat_validator() const { return m_cat_validator; }
[[nodiscard]] const category_validator *get_cat_validator() const { return m_cat_validator; }
/// @brief Validate the data stored using the assigned @ref category_validator
/// @return Returns true is all validations pass
bool is_valid() const;
[[nodiscard]] bool is_valid() const;
/// @brief Validate links, that means, values in this category should have an
/// accompanying value in parent categories.
@@ -239,7 +241,7 @@ class category
/// parent in those categories.
///
/// @return Returns true is all validations pass
bool validate_links() const;
[[nodiscard]] bool validate_links() const;
/**
* @brief Strip removes items from this category that are invalid according to the assigned validator
@@ -272,7 +274,7 @@ class category
/// @brief Return a const reference to the first row in this category.
/// @return const reference to the first row in this category. The result is undefined if
/// the category is empty.
const_reference front() const
[[nodiscard]] const_reference front() const
{
return { const_cast<category &>(*this), const_cast<row &>(*m_head) };
}
@@ -288,7 +290,7 @@ class category
/// @brief Return a const reference to the last row in this category.
/// @return const reference to the last row in this category. The result is undefined if
/// the category is empty.
const_reference back() const
[[nodiscard]] const_reference back() const
{
return { const_cast<category &>(*this), const_cast<row &>(*m_tail) };
}
@@ -306,43 +308,43 @@ class category
}
/// Return a const iterator to the first row
const_iterator begin() const
[[nodiscard]] const_iterator begin() const
{
return { *this, m_head };
}
/// Return a const iterator pointing past the last row
const_iterator end() const
[[nodiscard]] const_iterator end() const
{
return { *this, nullptr };
}
/// Return a const iterator to the first row
const_iterator cbegin() const
[[nodiscard]] const_iterator cbegin() const
{
return { *this, m_head };
}
/// Return an iterator pointing past the last row
const_iterator cend() const
[[nodiscard]] const_iterator cend() const
{
return { *this, nullptr };
}
/// Return a count of the rows in this container
std::size_t size() const
[[nodiscard]] std::size_t size() const
{
return std::distance(cbegin(), cend());
}
/// Return the theoretical maximum number or rows that can be stored
std::size_t max_size() const
[[nodiscard]] std::size_t max_size() const
{
return std::numeric_limits<std::size_t>::max(); // this is a bit optimistic, I guess
}
/// Return true if the category is empty
bool empty() const
[[nodiscard]] bool empty() const
{
return m_head == nullptr;
}
@@ -610,8 +612,9 @@ class category
/// @param cond The condition to search for
/// @param item The name of the item to return the value for
/// @return The value found
template <typename T, std::enable_if_t<not is_optional_v<T>, int> = 0>
template <typename T>
T find1(const_iterator pos, condition &&cond, std::string_view item) const
requires(not is_optional_v<T>)
{
auto h = find<T>(pos, std::move(cond), item);
@@ -629,8 +632,9 @@ class category
/// @param cond The condition to search for
/// @param item The name of the item to return the value for
/// @return The value found, can be empty if no row matches the condition
template <typename T, std::enable_if_t<is_optional_v<T>, int> = 0>
template <typename T>
T find1(const_iterator pos, condition &&cond, std::string_view item) const
requires(is_optional_v<T>)
{
auto h = find<typename T::value_type>(pos, std::move(cond), item);
@@ -905,23 +909,23 @@ class category
/// Using the relations defined in the validator, return whether the row
/// in @a r has any children in other categories
bool has_children(row_handle r) const;
[[nodiscard]] bool has_children(row_handle r) const;
/// Using the relations defined in the validator, return whether the row
/// in @a r has any parents in other categories
bool has_parents(row_handle r) const;
[[nodiscard]] bool has_parents(row_handle r) const;
/// Using the relations defined in the validator, return the row handles
/// for all rows in @a childCat that are linked to row @a r
std::vector<row_handle> get_children(row_handle r, const category &childCat) const;
[[nodiscard]] std::vector<row_handle> get_children(row_handle r, const category &childCat) const;
/// Using the relations defined in the validator, return the row handles
/// for all rows in @a parentCat that are linked to row @a r
std::vector<row_handle> get_parents(row_handle r, const category &parentCat) const;
[[nodiscard]] std::vector<row_handle> get_parents(row_handle r, const category &parentCat) const;
/// Using the relations defined in the validator, return the row handles
/// for all rows in @a cat that are in any way linked to row @a r
std::vector<row_handle> get_linked(row_handle r, const category &cat) const;
[[nodiscard]] std::vector<row_handle> get_linked(row_handle r, const category &cat) const;
// --------------------------------------------------------------------
@@ -1066,12 +1070,12 @@ class category
// --------------------------------------------------------------------
/// \brief Return the index number for \a item_name
uint16_t get_item_ix(std::string_view item_name) const;
[[nodiscard]] uint16_t get_item_ix(std::string_view item_name) const;
/// @brief Return the name for item with index @a ix
/// @param ix The index number
/// @return The name of the item
std::string_view get_item_name(uint16_t ix) const
[[nodiscard]] std::string_view get_item_name(uint16_t ix) const
{
if (ix >= m_items.size())
throw std::out_of_range("item index is out of range");
@@ -1098,16 +1102,16 @@ class category
/// @brief Return whether a item with name @a name exists in this category
/// @param name The name of the item
/// @return True if the item exists
bool has_item(std::string_view name) const
[[nodiscard]] bool has_item(std::string_view name) const
{
return get_item_ix(name) < m_items.size();
}
/// @brief Return the items in this category
std::vector<std::string> get_items() const;
[[nodiscard]] std::vector<std::string> get_items() const;
/// @brief Return the number of items (colums) in this category
size_t get_item_count() const noexcept
[[nodiscard]] size_t get_item_count() const noexcept
{
return m_items.size();
}
@@ -1128,14 +1132,14 @@ class category
/// This function returns effectively the list of fully qualified item
/// names, that is category_name + '.' + item_name for each item
[[deprecated("use get_item_order instead")]] std::vector<std::string> get_tag_order() const
[[deprecated("use get_item_order instead")]] [[nodiscard]] std::vector<std::string> get_tag_order() const
{
return get_item_order();
}
/// This function returns effectively the list of fully qualified item
/// names, that is category_name + '.' + item_name for each item
std::vector<std::string> get_item_order() const;
[[nodiscard]] std::vector<std::string> get_item_order() const;
/// Write the contents of the category to the std::ostream @a os
void write(std::ostream &os) const;
@@ -1143,13 +1147,13 @@ class category
/// \brief Various supported output formats
enum class output_format
{
cif, // Output in mmCIF format
cif, // Output in mmCIF format
csv, // comma separated values
tsv, // tab separated values
list, // values delimited by a '|' character
column, // output in columns
markdown, //
table, // ascii art table
table, // ascii art table
box, // table with unicode line characters
};
@@ -1201,7 +1205,7 @@ class category
using allocator_type = std::allocator<void>;
constexpr allocator_type get_allocator() const
[[nodiscard]] constexpr allocator_type get_allocator() const
{
return {};
}
@@ -1265,8 +1269,8 @@ class category
// --------------------------------------------------------------------
condition get_parents_condition(row_handle rh, const category &parentCat) const;
condition get_children_condition(row_handle rh, const category &childCat) const;
[[nodiscard]] condition get_parents_condition(row_handle rh, const category &parentCat) const;
[[nodiscard]] condition get_children_condition(row_handle rh, const category &childCat) const;
// --------------------------------------------------------------------
@@ -1283,7 +1287,7 @@ class category
class category_index *m_index = nullptr;
row *m_head = nullptr, *m_tail = nullptr;
bool m_dirty = false; // Keep track of modifications
bool m_dirty = false; // Keep track of modifications
};
} // namespace cif

View File

@@ -116,7 +116,7 @@ struct compound_atom
z; ///< The z component of the coordinates for each atom specified as orthogonal angstroms.
/// Return the location of the atom as a point
point get_location() const
[[nodiscard]] point get_location() const
{
return { x, y, z };
}
@@ -146,34 +146,34 @@ class compound
public:
// accessors
std::string id() const { return m_id; } ///< Return the alphanumeric code for the chemical component.
std::string name() const { return m_name; } ///< Return the name of the chemical component.
std::string type() const { return m_type; } ///< Return the type of monomer.
std::string formula() const { return m_formula; } ///< Return the chemical formula of the chemical component.
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.
[[nodiscard]] std::string id() const { return m_id; } ///< Return the alphanumeric code for the chemical component.
[[nodiscard]] std::string name() const { return m_name; } ///< Return the name of the chemical component.
[[nodiscard]] std::string type() const { return m_type; } ///< Return the type of monomer.
[[nodiscard]] std::string formula() const { return m_formula; } ///< Return the chemical formula of the chemical component.
[[nodiscard]] float formula_weight() const { return m_formula_weight; } ///< Return the formula mass of the chemical component in Daltons.
[[nodiscard]] int formal_charge() const { return m_formal_charge; } ///< Return the formal charge on the chemical component.
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
[[nodiscard]] const std::vector<compound_atom> &atoms() const { return m_atoms; } ///< Return the list of atoms for this compound
[[nodiscard]] const std::vector<compound_bond> &bonds() const { return m_bonds; } ///< Return the list of bonds for this compound
compound_atom get_atom_by_atom_id(const std::string &atom_id) const; ///< Return the atom with id @a atom_id
[[nodiscard]] compound_atom get_atom_by_atom_id(const std::string &atom_id) const; ///< Return the atom with id @a atom_id
bool atoms_bonded(const std::string &atomId_1, const std::string &atomId_2) const; ///< Return true if @a atomId_1 is bonded to @a atomId_2
float bond_length(const std::string &atomId_1, const std::string &atomId_2) const; ///< Return the bond length between @a atomId_1 and @a atomId_2
[[nodiscard]] bool atoms_bonded(const std::string &atomId_1, const std::string &atomId_2) const; ///< Return true if @a atomId_1 is bonded to @a atomId_2
[[nodiscard]] float bond_length(const std::string &atomId_1, const std::string &atomId_2) const; ///< Return the bond length between @a atomId_1 and @a atomId_2
bool is_water() const ///< Return if the compound is actually a water
[[nodiscard]] bool is_water() const ///< Return if the compound is actually a water
{
return m_id == "HOH" or m_id == "H2O" or m_id == "WAT";
}
/** \brief Return whether this compound has a type of either 'peptide linking' or 'L-peptide linking' */
bool is_peptide() const;
[[nodiscard]] bool is_peptide() const;
/** \brief Return whether this compound has a type of either 'DNA linking' or 'RNA linking' */
bool is_base() const;
[[nodiscard]] bool is_base() const;
char one_letter_code() const { return m_one_letter_code; }; ///< Return the one letter code to use in a canonical sequence. If unknown the value '\0' is returned
std::string parent_id() const { return m_parent_id; }; ///< Return the parent id code in case a parent is specified (e.g. MET for MSE)
[[nodiscard]] char one_letter_code() const { return m_one_letter_code; }; ///< Return the one letter code to use in a canonical sequence. If unknown the value '\0' is returned
[[nodiscard]] std::string parent_id() const { return m_parent_id; }; ///< Return the parent id code in case a parent is specified (e.g. MET for MSE)
private:
friend class compound_factory_impl;

View File

@@ -88,7 +88,7 @@ namespace colour
/// @brief The defined colours
enum colour_type
{
black = 0,
black,
red,
green,
yellow,
@@ -96,7 +96,8 @@ namespace colour
magenta,
cyan,
white,
none = 9
_unused,
none
};
/// @brief The defined styles
@@ -127,6 +128,7 @@ namespace colour
{
}
coloured_string_t(coloured_string_t &) = delete;
coloured_string_t &operator=(coloured_string_t &) = delete;
/**

View File

@@ -31,6 +31,7 @@
#include "cif++/utilities.hpp"
#include "cif++/validate.hpp"
#include <algorithm>
#include <numeric>
#include <stack>
#include <utility>
@@ -68,7 +69,8 @@ class row_comparator
using namespace std::placeholders;
m_comparator.emplace_back(ix, std::bind(&type_validator::compare, tv, _1, _2));
m_comparator.emplace_back(ix, [tv](auto &&a1, auto &&a2)
{ return tv->compare(std::forward<decltype(a1)>(a1), std::forward<decltype(a2)>(a2)); });
}
}
@@ -145,8 +147,8 @@ class category_index
delete m_root;
}
row *find(const category &cat, row *k) const;
row *find_by_value(const category &cat, const category::key_type &k) const;
[[nodiscard]] row *find(const category &cat, row *k) const;
[[nodiscard]] row *find_by_value(const category &cat, const category::key_type &k) const;
void insert(category &cat, row *r);
void erase(category &cat, row *r);
@@ -169,7 +171,7 @@ class category_index
return result;
}
std::size_t size() const;
[[nodiscard]] std::size_t size() const;
// bool isValid() const;
private:
@@ -177,9 +179,6 @@ class category_index
{
entry(row *r)
: m_row(r)
, m_left(nullptr)
, m_right(nullptr)
, m_red(true)
{
}
@@ -190,9 +189,9 @@ class category_index
}
row *m_row;
entry *m_left;
entry *m_right;
bool m_red;
entry *m_left = nullptr;
entry *m_right = nullptr;
bool m_red = true;
};
entry *insert(category &cat, entry *h, row *v);
@@ -328,12 +327,11 @@ class category_index
}
row_comparator m_row_comparator;
entry *m_root;
entry *m_root = nullptr;
};
category_index::category_index(category &cat)
: m_row_comparator(cat)
, m_root(nullptr)
{
for (auto r : cat)
insert(cat, r.get_row());
@@ -611,7 +609,7 @@ void category::remove_item(std::string_view item_name)
void category::drop_empty_items()
{
std::vector<bool> is_empty(m_items.size(), true);
for (auto &row : *this)
{
for (size_t ix = 0; ix < m_items.size(); ++ix)
@@ -634,13 +632,13 @@ void category::drop_empty_items()
void category::rename_item(std::string_view from_name, std::string_view to_name)
{
for (std::size_t ix = 0; ix < m_items.size(); ++ix)
for (auto &item : m_items)
{
if (not iequals(from_name, m_items[ix].m_name))
if (not iequals(from_name, item.m_name))
continue;
m_items[ix].m_name = to_name;
m_items[ix].m_validator = m_cat_validator ? m_cat_validator->get_validator_for_item(to_name) : nullptr;
item.m_name = to_name;
item.m_validator = m_cat_validator ? m_cat_validator->get_validator_for_item(to_name) : nullptr;
break;
}
@@ -988,9 +986,9 @@ condition category::get_parents_condition(row_handle rh, const category &parentC
condition result;
auto links = m_validator->get_links_for_child(m_name);
links.erase(remove_if(links.begin(), links.end(), [n = parentCat.m_name](auto &l)
{ return l->m_parent_category != n; }),
links.end());
auto e = std::ranges::remove_if(links, [n = parentCat.m_name](auto &l)
{ return l->m_parent_category != n; });
links.erase(e.begin(), e.end());
if (not links.empty())
{
@@ -1030,9 +1028,9 @@ condition category::get_children_condition(row_handle rh, const category &childC
mandatoryChildItems = childCatValidator->m_mandatory_items;
auto links = m_validator->get_links_for_parent(m_name);
links.erase(remove_if(links.begin(), links.end(), [n = childCat.m_name](auto &l)
{ return l->m_child_category != n; }),
links.end());
auto e = std::ranges::remove_if(links, [n = childCat.m_name](auto &l)
{ return l->m_child_category != n; });
links.erase(e.begin(), e.end());
if (not links.empty())
{
@@ -1105,7 +1103,7 @@ std::vector<row_handle> category::get_children(row_handle r, const category &chi
for (auto child : childCat.find(get_children_condition(r, childCat)))
{
if (std::find(result.begin(), result.end(), child) == result.end())
if (std::ranges::find(result, child) == result.end())
result.push_back(child);
}
@@ -1121,7 +1119,7 @@ std::vector<row_handle> category::get_parents(row_handle r, const category &pare
for (auto parent : parentCat.find(get_parents_condition(r, parentCat)))
{
if (std::find(result.begin(), result.end(), parent) == result.end())
if (std::ranges::find(result, parent) == result.end())
result.push_back(parent);
}
@@ -1327,7 +1325,7 @@ std::string category::get_unique_id(std::function<std::string(int)> generator)
for (;;)
{
if (m_index->find_by_value(*this, { { id_name, result } }) == nullptr)
if (m_index->find_by_value(*this, { { .name = id_name, .value = result } }) == nullptr)
break;
result = generator(static_cast<int>(m_last_unique_num++));
}
@@ -1356,7 +1354,7 @@ std::string category::get_unique_value(std::string_view item_name)
if (iv and iv->m_type and iv->m_type->m_primitive_type == DDL_PrimitiveType::Numb)
{
uint64_t v = find_max<uint64_t>(item_name);
auto v = find_max<uint64_t>(item_name);
result = std::to_string(v + 1);
}
}
@@ -1414,7 +1412,7 @@ void category::update_value(const std::vector<row_handle> &rows, std::string_vie
for (auto &&[childCat, linked] : m_child_links)
{
if (std::find(linked->m_parent_keys.begin(), linked->m_parent_keys.end(), item_name) == linked->m_parent_keys.end())
if (std::ranges::find(linked->m_parent_keys, item_name) == linked->m_parent_keys.end())
continue;
condition cond;
@@ -1560,7 +1558,7 @@ void category::update_value(row *row, uint16_t item, std::string_view value, boo
for (auto &&[childCat, linked] : m_child_links)
{
if (std::find(linked->m_parent_keys.begin(), linked->m_parent_keys.end(), iv->m_item_name) == linked->m_parent_keys.end())
if (std::ranges::find(linked->m_parent_keys, iv->m_item_name) == linked->m_parent_keys.end())
continue;
condition cond;
@@ -1770,7 +1768,7 @@ category::iterator category::insert_impl(const_iterator pos, row *n)
m_dirty = true;
return iterator(*this, n);
return { *this, n };
}
catch (const std::exception &e)
{
@@ -1814,11 +1812,8 @@ void category::sort(std::function<int(row_handle, row_handle)> f)
for (auto itemRow = m_head; itemRow != nullptr; itemRow = itemRow->m_next)
rows.emplace_back(*this, *itemRow);
std::stable_sort(rows.begin(), rows.end(),
[&f](row_handle ia, row_handle ib)
{
return f(ia, ib) < 0;
});
std::ranges::stable_sort(rows, [&f](row_handle ia, row_handle ib)
{ return f(ia, ib) < 0; });
m_head = rows.front().get_row();
m_tail = rows.back().get_row();
@@ -1968,7 +1963,7 @@ void category::write(std::ostream &os, output_format fmt, const std::vector<std:
{
for (uint16_t i = 0; i < m_items.size(); ++i)
{
if (std::find(order.begin(), order.end(), i) == order.end())
if (std::ranges::find(order, i) == order.end())
order.push_back(i);
}
}
@@ -2621,7 +2616,7 @@ bool category::operator==(const category &rhs) const
if (validator != nullptr)
catValidator = validator->get_validator_for_category(a.name());
typedef std::function<int(std::string_view, std::string_view)> compType;
using compType = std::function<int(std::string_view, std::string_view)>;
std::vector<std::tuple<std::string, compType>> item_names;
std::vector<std::string> keys;
std::vector<std::size_t> keyIx;
@@ -2630,8 +2625,8 @@ bool category::operator==(const category &rhs) const
{
for (auto &item_name : a.get_items())
{
item_names.push_back(std::make_tuple(item_name, [](std::string_view va, std::string_view vb)
{ return va.compare(vb); }));
item_names.emplace_back(item_name, [](std::string_view va, std::string_view vb)
{ return va.compare(vb); });
keyIx.push_back(keys.size());
keys.push_back(item_name);
}
@@ -2648,13 +2643,14 @@ bool category::operator==(const category &rhs) const
auto tv = iv->m_type;
if (tv == nullptr)
throw std::runtime_error("missing type validator");
item_names.push_back(std::make_tuple(item_name, std::bind(&cif::type_validator::compare, tv, std::placeholders::_1, std::placeholders::_2)));
item_names.emplace_back(item_name, [tv](auto &&a1, auto &&a2)
{ return tv->compare(std::forward<decltype(a1)>(a1), std::forward<decltype(a2)>(a2)); });
auto pred = [item_name](const std::string &s) -> bool
{
return cif::iequals(item_name, s) == 0;
};
if (find_if(keys.begin(), keys.end(), pred) == keys.end())
if (std::ranges::find_if(keys, pred) == keys.end())
keyIx.push_back(item_names.size() - 1);
}
}

View File

@@ -35,14 +35,15 @@
#include "cif++/text.hpp"
#include "cif++/validate.hpp"
#include <sqlite3.h>
#include <algorithm>
#include <cstdint>
#include <exception>
#include <iomanip>
#include <memory>
#include <regex>
#include <sqlite3.h>
#include <sstream>
#include <stack>
#include <stdexcept>
#include <system_error>
#include <utility>
@@ -77,7 +78,7 @@ field_ref row_ref::operator[](std::string_view name) const
// --------------------------------------------------------------------
result::result(category &&cat, const std::string &query)
: m_impl(new result_impl{ std::forward<category>(cat), query })
: m_impl(new result_impl{ .m_cat = std::forward<category>(cat), .m_query = query })
{
}
@@ -208,16 +209,16 @@ sqlite3_module connection_impl::s_module{
/* xRowid */ Rowid,
/* xUpdate */ Update,
/* xBegin */ Begin,
/* xSync */ 0,
/* xSync */ nullptr,
/* xCommit */ Commit,
/* xRollback */ Rollback,
/* xFindFunction */ 0,
/* xFindFunction */ nullptr,
/* xRename */ Rename,
/* xSavepoint */ 0,
/* xRelease */ 0,
/* xRollbackTo */ 0,
/* xShadowName */ 0,
/* xIntegrity */ 0
/* xSavepoint */ nullptr,
/* xRelease */ nullptr,
/* xRollbackTo */ nullptr,
/* xShadowName */ nullptr,
/* xIntegrity */ nullptr
};
/*
@@ -236,7 +237,7 @@ sqlite3_module connection_impl::s_module{
int connection_impl::Connect(sqlite3 *db, void *pAux, int argc, const char *const *argv, sqlite3_vtab **ppVtab, char **pzErr)
{
connection_impl *impl = reinterpret_cast<connection_impl *>(pAux);
auto *impl = reinterpret_cast<connection_impl *>(pAux);
try
{
return impl->Connect(db, argc, argv, ppVtab, pzErr);
@@ -280,7 +281,7 @@ int connection_impl::Connect(sqlite3 *db, int argc, const char *const *argv, sql
for (auto iv : cv->m_item_validators)
{
if (std::find(items.begin(), items.end(), iv.m_item_name) == items.end())
if (std::ranges::find(items, iv.m_item_name) == items.end())
items.emplace_back(iv.m_item_name);
}
@@ -334,10 +335,11 @@ int connection_impl::Connect(sqlite3 *db, int argc, const char *const *argv, sql
*/
int connection_impl::Destroy(sqlite3_vtab *pVtab)
{
virtual_table *p = reinterpret_cast<virtual_table *>(pVtab);
auto *p = reinterpret_cast<virtual_table *>(pVtab);
auto &conn = p->m_connection_impl;
conn.m_vtabs.erase(std::remove(conn.m_vtabs.begin(), conn.m_vtabs.end(), p), conn.m_vtabs.end());
auto e = std::ranges::remove(conn.m_vtabs, p);
conn.m_vtabs.erase(e.begin(), e.end());
auto &db = p->m_db;
db.remove(p->m_cat);
@@ -351,10 +353,11 @@ int connection_impl::Destroy(sqlite3_vtab *pVtab)
*/
int connection_impl::Disconnect(sqlite3_vtab *pVtab)
{
virtual_table *p = reinterpret_cast<virtual_table *>(pVtab);
auto *p = reinterpret_cast<virtual_table *>(pVtab);
auto &conn = p->m_connection_impl;
conn.m_vtabs.erase(std::remove(conn.m_vtabs.begin(), conn.m_vtabs.end(), p), conn.m_vtabs.end());
auto e = std::ranges::remove(conn.m_vtabs, p);
conn.m_vtabs.erase(e.begin(), e.end());
delete p;
@@ -524,7 +527,7 @@ int connection_impl::Filter(sqlite3_vtab_cursor *pVtabCursor, int idxNum, const
else
{
double value;
const auto &[ptr, ec] = std::from_chars(m[3].str().data(), m[3].str().data() + m[3].str().length(), value);
const auto &[ptr, ec] = cif::from_chars(m[3].str().data(), m[3].str().data() + m[3].str().length(), value);
if (ec != std::errc{})
throw std::system_error(std::make_error_code(ec));
@@ -569,7 +572,7 @@ int connection_impl::Filter(sqlite3_vtab_cursor *pVtabCursor, int idxNum, const
*/
int connection_impl::BestIndex(sqlite3_vtab *pVtab, sqlite3_index_info *pIdxInfo)
{
virtual_table *p = reinterpret_cast<virtual_table *>(pVtab);
auto *p = reinterpret_cast<virtual_table *>(pVtab);
try
{
@@ -615,7 +618,7 @@ int connection_impl::BestIndex(sqlite3_vtab *pVtab, sqlite3_index_info *pIdxInfo
break;
default:
{
std::string s = (const char *)sqlite3_value_text(val);
std::string s = reinterpret_cast<const char *>(sqlite3_value_text(val));
if (s.find("\n") == std::string::npos)
os << std::quoted(s) << "\n";
else
@@ -713,7 +716,7 @@ int connection_impl::BestIndex(sqlite3_vtab *pVtab, sqlite3_index_info *pIdxInfo
int connection_impl::Update(sqlite3_vtab *pVTab, int argc, sqlite3_value **argv, sqlite_int64 *pRowid)
{
virtual_table *p = reinterpret_cast<virtual_table *>(pVTab);
auto *p = reinterpret_cast<virtual_table *>(pVTab);
int rc = SQLITE_ERROR;
@@ -789,7 +792,7 @@ int connection_impl::Update(sqlite3_vtab *pVTab, int argc, sqlite3_value **argv,
data.emplace_back(p->m_items[i - 2], "?");
break;
default:
data.emplace_back(p->m_items[i - 2], (const char *)sqlite3_value_text(argv[i]));
data.emplace_back(p->m_items[i - 2], reinterpret_cast<const char *>(sqlite3_value_text(argv[i])));
break;
}
}
@@ -818,7 +821,7 @@ int connection_impl::Update(sqlite3_vtab *pVTab, int argc, sqlite3_value **argv,
data.emplace_back(p->m_items[i - 2], "?");
break;
default:
data.emplace_back(p->m_items[i - 2], (const char *)sqlite3_value_text(argv[i]));
data.emplace_back(p->m_items[i - 2], reinterpret_cast<const char *>(sqlite3_value_text(argv[i])));
break;
}
}
@@ -833,12 +836,12 @@ int connection_impl::Update(sqlite3_vtab *pVTab, int argc, sqlite3_value **argv,
if (childCat == nullptr)
continue;
std::vector<std::tuple<int,std::string_view>> ixs;
std::vector<std::tuple<int, std::string_view>> ixs;
for (auto &ri : data)
{
auto i = std::find(link->m_parent_keys.begin(), link->m_parent_keys.end(), ri.name());
auto i = std::ranges::find(link->m_parent_keys, ri.name());
if (i == link->m_parent_keys.end())
continue; // no update needed
continue; // no update needed
ixs.emplace_back(i - link->m_parent_keys.begin(), ri.value());
}
@@ -847,14 +850,14 @@ int connection_impl::Update(sqlite3_vtab *pVTab, int argc, sqlite3_value **argv,
std::ostringstream sql;
sql << "UPDATE " << link->m_child_category;
for (bool first = true; auto [i, txt] : ixs)
{
if (not std::exchange(first, false))
sql << ",";
sql << " SET " << link->m_child_keys[i] << " = ?" << (i + 1);
}
sql << " WHERE ";
for (bool first = true; auto [i, txt] : ixs)
{
@@ -870,7 +873,7 @@ int connection_impl::Update(sqlite3_vtab *pVTab, int argc, sqlite3_value **argv,
for (auto [i, txt] : ixs)
{
// set
if (rc == SQLITE_OK)
if (rc == SQLITE_OK)
rc = sqlite3_bind_text(sub_stmt, i + 1, txt.data(), txt.length(), nullptr);
// where
@@ -889,8 +892,6 @@ int connection_impl::Update(sqlite3_vtab *pVTab, int argc, sqlite3_value **argv,
}
}
rh.assign(data);
*pRowid = addr;
rc = SQLITE_OK;
@@ -907,21 +908,21 @@ int connection_impl::Update(sqlite3_vtab *pVTab, int argc, sqlite3_value **argv,
int connection_impl::Rename(sqlite3_vtab *pVtab, const char *zNew)
{
virtual_table *p = reinterpret_cast<virtual_table *>(pVtab);
auto *p = reinterpret_cast<virtual_table *>(pVtab);
p->m_cat.name(zNew);
return SQLITE_OK;
}
int connection_impl::Begin(sqlite3_vtab *pVTab)
{
virtual_table *p = reinterpret_cast<virtual_table *>(pVTab);
auto *p = reinterpret_cast<virtual_table *>(pVTab);
p->m_rollback_buffer.push(p->m_cat);
return SQLITE_OK;
}
int connection_impl::Commit(sqlite3_vtab *pVTab)
{
virtual_table *p = reinterpret_cast<virtual_table *>(pVTab);
auto *p = reinterpret_cast<virtual_table *>(pVTab);
if (not p->m_rollback_buffer.empty())
p->m_rollback_buffer.pop();
return SQLITE_OK;
@@ -929,7 +930,7 @@ int connection_impl::Commit(sqlite3_vtab *pVTab)
int connection_impl::Rollback(sqlite3_vtab *pVTab)
{
virtual_table *p = reinterpret_cast<virtual_table *>(pVTab);
auto *p = reinterpret_cast<virtual_table *>(pVTab);
if (not p->m_rollback_buffer.empty())
{
std::swap(p->m_cat, p->m_rollback_buffer.top());
@@ -1078,7 +1079,7 @@ result connection::exec(std::string query, std::string &tail)
sqlite3_finalize(stmt);
return result(std::move(cat), sql);
return { std::move(cat), sql };
}
catch (const std::exception &ex)
{

View File

@@ -268,7 +268,7 @@ std::string cif_id_for_number(int number)
number = (number - r) / 26 - 1;
} while (number >= 0);
std::reverse(result.begin(), result.end());
std::ranges::reverse(result);
assert(not result.empty());
@@ -494,7 +494,7 @@ std::vector<std::string> wrapLine(const std::string &text, std::size_t width)
j = i;
}
reverse(result.begin(), result.end());
std::ranges::reverse(result);
return result;
}
@@ -506,7 +506,7 @@ std::vector<std::string> word_wrap(const std::string &text, std::size_t width)
{
if (p.empty())
{
result.push_back("");
result.emplace_back("");
continue;
}