mirror of
https://github.com/PDB-REDO/libcifpp.git
synced 2026-06-04 13:54:25 +08:00
macOS and Windows fixes,
start using clang-tidy
This commit is contained in:
5
.clang-tidy
Normal file
5
.clang-tidy
Normal file
@@ -0,0 +1,5 @@
|
||||
Checks: '-*,
|
||||
modernize*,
|
||||
-modernize-use-trailing-return-type,
|
||||
-modernize-avoid-c-arrays
|
||||
'
|
||||
661
CMakeLists.txt
661
CMakeLists.txt
@@ -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()
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
/**
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
71
src/cql.cpp
71
src/cql.cpp
@@ -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)
|
||||
{
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user