mirror of
https://github.com/PDB-REDO/libcifpp.git
synced 2026-06-05 23:04:29 +08:00
Compare commits
61 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
ac98531a2f | ||
|
|
917e0ba79c | ||
|
|
3ebceb7522 | ||
|
|
92bd52da12 | ||
|
|
fb56a9cd6e | ||
|
|
a4680f7d38 | ||
|
|
da8a72a8aa | ||
|
|
ac497932b5 | ||
|
|
9927b5061a | ||
|
|
cedaab9642 | ||
|
|
50bf2145ec | ||
|
|
dc77729f50 | ||
|
|
e3330d667a | ||
|
|
9822f397a1 | ||
|
|
a3b5ce9959 | ||
|
|
9eb06e929a | ||
|
|
629e06d647 | ||
|
|
51ccb92184 | ||
|
|
3cd27f13fd | ||
|
|
ae668530c0 | ||
|
|
4a8b1c056c | ||
|
|
d7a5e598bc | ||
|
|
3f1ee32cc6 | ||
|
|
725d6ead98 | ||
|
|
baf70579de | ||
|
|
cd28ab58a3 | ||
|
|
a78fa0a81d | ||
|
|
82130be5f5 | ||
|
|
510ce62dfb | ||
|
|
be738e7fb1 | ||
|
|
9c78131df3 | ||
|
|
d94f6f4d19 | ||
|
|
9a3eced350 | ||
|
|
2fed7a76fb | ||
|
|
f02e59df1b | ||
|
|
04147a2fe9 | ||
|
|
0e83bc31dc | ||
|
|
75a5f7960f | ||
|
|
3f93c27b07 | ||
|
|
ab781d4516 | ||
|
|
446438bf8c | ||
|
|
4e012cbd48 | ||
|
|
12ee4a792c | ||
|
|
e59750386f | ||
|
|
4e19d54867 | ||
|
|
db603e5438 | ||
|
|
5320cb123a | ||
|
|
30a2ebdbb4 | ||
|
|
a5d43998a3 | ||
|
|
2792caec70 | ||
|
|
fb2b1e984c | ||
|
|
13ab1caf95 | ||
|
|
5d4534fac4 | ||
|
|
f450643861 | ||
|
|
fc14a65511 | ||
|
|
bbd1e27c5e | ||
|
|
369a83b718 | ||
|
|
afc541b956 | ||
|
|
7e4d2ffb4d | ||
|
|
e09913a94f | ||
|
|
b4d1c4cc04 |
185
CMakeLists.txt
185
CMakeLists.txt
@@ -27,7 +27,7 @@ cmake_minimum_required(VERSION 3.16)
|
||||
# set the project name
|
||||
project(
|
||||
libcifpp
|
||||
VERSION 7.0.0
|
||||
VERSION 7.0.3
|
||||
LANGUAGES CXX)
|
||||
|
||||
list(PREPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake")
|
||||
@@ -164,7 +164,7 @@ if(GXX_LIBSTDCPP)
|
||||
|
||||
try_run(STD_REGEX_RUNNING STD_REGEX_COMPILING
|
||||
${CMAKE_CURRENT_BINARY_DIR}/test
|
||||
${PROJECT_SOURCE_DIR}/cmake/test-rx.cpp)
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/cmake/test-rx.cpp)
|
||||
|
||||
if(STD_REGEX_RUNNING STREQUAL FAILED_TO_RUN)
|
||||
message(
|
||||
@@ -255,88 +255,100 @@ list(APPEND CIFPP_REQUIRED_LIBRARIES ${STDCPPATOMIC_LIBRARY})
|
||||
|
||||
# Create a revision file, containing the current git version info
|
||||
include(VersionString)
|
||||
write_version_header(${PROJECT_SOURCE_DIR}/src/ LIB_NAME "LibCIFPP")
|
||||
write_version_header(${CMAKE_CURRENT_SOURCE_DIR}/src/ LIB_NAME "LibCIFPP")
|
||||
|
||||
# SymOp data table
|
||||
if(CIFPP_RECREATE_SYMOP_DATA)
|
||||
# The tool to create the table
|
||||
add_executable(symop-map-generator
|
||||
"${PROJECT_SOURCE_DIR}/src/symop-map-generator.cpp")
|
||||
"${CMAKE_CURRENT_SOURCE_DIR}/src/symop-map-generator.cpp")
|
||||
|
||||
add_custom_command(
|
||||
OUTPUT ${PROJECT_SOURCE_DIR}/src/symop_table_data.hpp
|
||||
OUTPUT ${CMAKE_CURRENT_SOURCE_DIR}/src/symop_table_data.hpp
|
||||
COMMAND
|
||||
$<TARGET_FILE:symop-map-generator> $ENV{CLIBD}/syminfo.lib
|
||||
$ENV{CLIBD}/symop.lib ${PROJECT_SOURCE_DIR}/src/symop_table_data.hpp)
|
||||
$ENV{CLIBD}/symop.lib ${CMAKE_CURRENT_SOURCE_DIR}/src/symop_table_data.hpp)
|
||||
|
||||
add_custom_target(
|
||||
OUTPUT
|
||||
${PROJECT_SOURCE_DIR}/src/symop_table_data.hpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/src/symop_table_data.hpp
|
||||
DEPENDS symop-map-generator "$ENV{CLIBD}/syminfo.lib"
|
||||
"$ENV{CLIBD}/symop.lib")
|
||||
endif()
|
||||
|
||||
# Sources
|
||||
set(project_sources
|
||||
${PROJECT_SOURCE_DIR}/src/category.cpp
|
||||
${PROJECT_SOURCE_DIR}/src/condition.cpp
|
||||
${PROJECT_SOURCE_DIR}/src/datablock.cpp
|
||||
${PROJECT_SOURCE_DIR}/src/dictionary_parser.cpp
|
||||
${PROJECT_SOURCE_DIR}/src/file.cpp
|
||||
${PROJECT_SOURCE_DIR}/src/item.cpp
|
||||
${PROJECT_SOURCE_DIR}/src/parser.cpp
|
||||
${PROJECT_SOURCE_DIR}/src/row.cpp
|
||||
${PROJECT_SOURCE_DIR}/src/validate.cpp
|
||||
${PROJECT_SOURCE_DIR}/src/text.cpp
|
||||
${PROJECT_SOURCE_DIR}/src/utilities.cpp
|
||||
${PROJECT_SOURCE_DIR}/src/atom_type.cpp
|
||||
${PROJECT_SOURCE_DIR}/src/compound.cpp
|
||||
${PROJECT_SOURCE_DIR}/src/point.cpp
|
||||
${PROJECT_SOURCE_DIR}/src/symmetry.cpp
|
||||
${PROJECT_SOURCE_DIR}/src/model.cpp
|
||||
${PROJECT_SOURCE_DIR}/src/pdb/cif2pdb.cpp
|
||||
${PROJECT_SOURCE_DIR}/src/pdb/pdb2cif.cpp
|
||||
${PROJECT_SOURCE_DIR}/src/pdb/pdb_record.hpp
|
||||
${PROJECT_SOURCE_DIR}/src/pdb/pdb2cif_remark_3.hpp
|
||||
${PROJECT_SOURCE_DIR}/src/pdb/pdb2cif_remark_3.cpp
|
||||
${PROJECT_SOURCE_DIR}/src/pdb/reconstruct.cpp
|
||||
${PROJECT_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/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
|
||||
)
|
||||
|
||||
set(project_headers
|
||||
${PROJECT_SOURCE_DIR}/include/cif++.hpp
|
||||
${PROJECT_SOURCE_DIR}/include/cif++/utilities.hpp
|
||||
${PROJECT_SOURCE_DIR}/include/cif++/item.hpp
|
||||
${PROJECT_SOURCE_DIR}/include/cif++/datablock.hpp
|
||||
${PROJECT_SOURCE_DIR}/include/cif++/file.hpp
|
||||
${PROJECT_SOURCE_DIR}/include/cif++/validate.hpp
|
||||
${PROJECT_SOURCE_DIR}/include/cif++/iterator.hpp
|
||||
${PROJECT_SOURCE_DIR}/include/cif++/parser.hpp
|
||||
${PROJECT_SOURCE_DIR}/include/cif++/forward_decl.hpp
|
||||
${PROJECT_SOURCE_DIR}/include/cif++/dictionary_parser.hpp
|
||||
${PROJECT_SOURCE_DIR}/include/cif++/condition.hpp
|
||||
${PROJECT_SOURCE_DIR}/include/cif++/category.hpp
|
||||
${PROJECT_SOURCE_DIR}/include/cif++/row.hpp
|
||||
${PROJECT_SOURCE_DIR}/include/cif++/atom_type.hpp
|
||||
${PROJECT_SOURCE_DIR}/include/cif++/compound.hpp
|
||||
${PROJECT_SOURCE_DIR}/include/cif++/point.hpp
|
||||
${PROJECT_SOURCE_DIR}/include/cif++/symmetry.hpp
|
||||
${PROJECT_SOURCE_DIR}/include/cif++/model.hpp
|
||||
${PROJECT_SOURCE_DIR}/include/cif++/pdb.hpp
|
||||
${PROJECT_SOURCE_DIR}/include/cif++/pdb/cif2pdb.hpp
|
||||
${PROJECT_SOURCE_DIR}/include/cif++/pdb/io.hpp
|
||||
${PROJECT_SOURCE_DIR}/include/cif++/pdb/pdb2cif.hpp
|
||||
${PROJECT_SOURCE_DIR}/include/cif++/pdb/tls.hpp)
|
||||
include/cif++.hpp
|
||||
include/cif++/utilities.hpp
|
||||
include/cif++/item.hpp
|
||||
include/cif++/datablock.hpp
|
||||
include/cif++/exports.hpp
|
||||
include/cif++/file.hpp
|
||||
include/cif++/validate.hpp
|
||||
include/cif++/iterator.hpp
|
||||
include/cif++/parser.hpp
|
||||
include/cif++/forward_decl.hpp
|
||||
include/cif++/dictionary_parser.hpp
|
||||
include/cif++/condition.hpp
|
||||
include/cif++/category.hpp
|
||||
include/cif++/row.hpp
|
||||
include/cif++/atom_type.hpp
|
||||
include/cif++/compound.hpp
|
||||
include/cif++/point.hpp
|
||||
include/cif++/symmetry.hpp
|
||||
include/cif++/model.hpp
|
||||
include/cif++/pdb.hpp
|
||||
include/cif++/pdb/cif2pdb.hpp
|
||||
include/cif++/pdb/io.hpp
|
||||
include/cif++/pdb/pdb2cif.hpp
|
||||
include/cif++/pdb/tls.hpp)
|
||||
|
||||
add_library(cifpp ${project_sources} ${project_headers}
|
||||
${PROJECT_SOURCE_DIR}/src/symop_table_data.hpp)
|
||||
add_library(cifpp STATIC)
|
||||
add_library(cifpp::cifpp ALIAS cifpp)
|
||||
|
||||
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}
|
||||
)
|
||||
|
||||
# The code now really requires C++20
|
||||
target_compile_features(cifpp PUBLIC cxx_std_20)
|
||||
|
||||
set(CMAKE_DEBUG_POSTFIX d)
|
||||
set_target_properties(cifpp PROPERTIES DEBUG_POSTFIX "d")
|
||||
|
||||
generate_export_header(cifpp EXPORT_FILE_NAME
|
||||
${PROJECT_SOURCE_DIR}/include/cif++/exports.hpp)
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/include/cif++/exports.hpp)
|
||||
|
||||
if(BOOST_REGEX)
|
||||
target_compile_definitions(cifpp PRIVATE USE_BOOST_REGEX=1
|
||||
@@ -353,7 +365,7 @@ set_target_properties(cifpp PROPERTIES POSITION_INDEPENDENT_CODE ON)
|
||||
|
||||
target_include_directories(
|
||||
cifpp
|
||||
PUBLIC "$<BUILD_INTERFACE:${PROJECT_SOURCE_DIR}/include>"
|
||||
PUBLIC "$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include>"
|
||||
"$<INSTALL_INTERFACE:${CMAKE_INSTALL_INCLUDEDIR}>"
|
||||
PRIVATE "${BOOST_REGEX_INCLUDE_DIR}" "${EIGEN_INCLUDE_DIR}")
|
||||
|
||||
@@ -366,7 +378,7 @@ endif(CMAKE_CXX_COMPILER_ID STREQUAL "AppleClang")
|
||||
|
||||
if(CIFPP_DOWNLOAD_CCD)
|
||||
# download the components.cif file from CCD
|
||||
set(COMPONENTS_CIF ${PROJECT_SOURCE_DIR}/rsrc/components.cif)
|
||||
set(COMPONENTS_CIF ${CMAKE_CURRENT_SOURCE_DIR}/rsrc/components.cif)
|
||||
|
||||
if(EXISTS ${COMPONENTS_CIF})
|
||||
file(SIZE ${COMPONENTS_CIF} CCD_FILE_SIZE)
|
||||
@@ -401,7 +413,7 @@ if(CIFPP_DOWNLOAD_CCD)
|
||||
add_custom_command(
|
||||
OUTPUT ${COMPONENTS_CIF}
|
||||
COMMAND "${GUNZIP}" ${COMPONENTS_CIF}.gz
|
||||
WORKING_DIRECTORY ${PROJECT_SOURCE_DIR}/rsrc/)
|
||||
WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/rsrc/)
|
||||
|
||||
add_custom_target(COMPONENTS ALL DEPENDS ${COMPONENTS_CIF})
|
||||
endif()
|
||||
@@ -452,14 +464,9 @@ else()
|
||||
endif()
|
||||
|
||||
# Install rules
|
||||
install(
|
||||
TARGETS cifpp
|
||||
EXPORT cifpp-targets
|
||||
ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}
|
||||
LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
|
||||
RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
|
||||
INCLUDES
|
||||
DESTINATION ${CMAKE_INSTALL_INCLUDEDIR})
|
||||
install(TARGETS cifpp
|
||||
EXPORT cifpp
|
||||
FILE_SET cifpp_headers DESTINATION ${CMAKE_INSTALL_INCLUDEDIR})
|
||||
|
||||
if(MSVC AND BUILD_SHARED_LIBS)
|
||||
install(
|
||||
@@ -479,50 +486,38 @@ if(OLD_CONFIG_FILES)
|
||||
install(CODE "file(REMOVE ${OLD_CONFIG_FILES})")
|
||||
endif()
|
||||
|
||||
install(
|
||||
EXPORT cifpp-targets
|
||||
FILE "cifpp-targets.cmake"
|
||||
install(EXPORT cifpp
|
||||
NAMESPACE cifpp::
|
||||
DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/cifpp)
|
||||
FILE "cifpp-targets.cmake"
|
||||
DESTINATION lib/cmake/cifpp)
|
||||
|
||||
install(
|
||||
DIRECTORY include/cif++
|
||||
DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}
|
||||
COMPONENT Devel)
|
||||
|
||||
install(
|
||||
FILES include/cif++.hpp
|
||||
DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}
|
||||
COMPONENT Devel)
|
||||
|
||||
if(CIFPP_DATA_DIR)
|
||||
if(CIFPP_DATA_DIR AND CIFPP_DOWNLOAD_CCD)
|
||||
install(
|
||||
FILES ${PROJECT_SOURCE_DIR}/rsrc/mmcif_ddl.dic
|
||||
${PROJECT_SOURCE_DIR}/rsrc/mmcif_pdbx.dic
|
||||
${PROJECT_SOURCE_DIR}/rsrc/mmcif_ma.dic ${COMPONENTS_CIF}
|
||||
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 ${COMPONENTS_CIF}
|
||||
DESTINATION ${CIFPP_DATA_DIR})
|
||||
endif()
|
||||
|
||||
if(CIFPP_CACHE_DIR)
|
||||
if(CIFPP_CACHE_DIR AND CIFPP_DOWNLOAD_CCD)
|
||||
install(
|
||||
FILES ${PROJECT_SOURCE_DIR}/rsrc/mmcif_ddl.dic
|
||||
${PROJECT_SOURCE_DIR}/rsrc/mmcif_pdbx.dic
|
||||
${PROJECT_SOURCE_DIR}/rsrc/mmcif_ma.dic ${COMPONENTS_CIF}
|
||||
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 ${COMPONENTS_CIF}
|
||||
DESTINATION ${CIFPP_CACHE_DIR})
|
||||
endif()
|
||||
|
||||
set(CONFIG_TEMPLATE_FILE ${PROJECT_SOURCE_DIR}/cmake/cifpp-config.cmake.in)
|
||||
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 ${CMAKE_INSTALL_LIBDIR}/cmake/cifpp
|
||||
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 ${CMAKE_INSTALL_LIBDIR}/cmake/cifpp
|
||||
COMPONENT Devel)
|
||||
DESTINATION lib/cmake/cifpp)
|
||||
|
||||
set_target_properties(
|
||||
cifpp
|
||||
@@ -542,7 +537,7 @@ write_basic_package_version_file(
|
||||
|
||||
# In case we're included as sub_directory:
|
||||
if(NOT PROJECT_IS_TOP_LEVEL)
|
||||
set(CIFPP_SHARE_DIR ${PROJECT_SOURCE_DIR}/rsrc PARENT_SCOPE)
|
||||
set(CIFPP_SHARE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/rsrc PARENT_SCOPE)
|
||||
endif()
|
||||
|
||||
if(BUILD_TESTING)
|
||||
@@ -570,7 +565,7 @@ if(CIFPP_INSTALL_UPDATE_SCRIPT)
|
||||
message(FATAL_ERROR "Don't know where to install the update script")
|
||||
endif()
|
||||
|
||||
configure_file(${PROJECT_SOURCE_DIR}/tools/update-libcifpp-data.in
|
||||
configure_file(${CMAKE_CURRENT_SOURCE_DIR}/tools/update-libcifpp-data.in
|
||||
update-libcifpp-data @ONLY)
|
||||
install(
|
||||
FILES ${CMAKE_CURRENT_BINARY_DIR}/update-libcifpp-data
|
||||
|
||||
12
changelog
12
changelog
@@ -1,3 +1,15 @@
|
||||
Version 7.0.3
|
||||
- Fix installation, write exports.hpp again
|
||||
|
||||
Version 7.0.2
|
||||
- Fix in testing error_code results.
|
||||
|
||||
Version 7.0.1
|
||||
- Various reconstruction fixes
|
||||
- category order in output fixed
|
||||
- better implementation of constructors for file, datablock and category
|
||||
- small optimisation in iterator
|
||||
|
||||
Version 7.0.0
|
||||
- Renaming many methods and parameters to be more
|
||||
consistent with the mmCIF dictionaries.
|
||||
|
||||
@@ -141,31 +141,39 @@ class category
|
||||
|
||||
/// \endcond
|
||||
|
||||
category() = default; ///< Default constructor
|
||||
category(std::string_view name); ///< Constructor taking a \a name
|
||||
category(const category &rhs); ///< Copy constructor
|
||||
category(category &&rhs); ///< Move constructor
|
||||
category &operator=(const category &rhs); ///< Copy assignement operator
|
||||
category &operator=(category &&rhs); ///< Move assignement operator
|
||||
category() = default; ///< Default constructor
|
||||
category(std::string_view name); ///< Constructor taking a \a name
|
||||
category(const category &rhs); ///< Copy constructor
|
||||
|
||||
category(category &&rhs) noexcept ///< Move constructor
|
||||
{
|
||||
swap(*this, rhs);
|
||||
}
|
||||
|
||||
category &operator=(category rhs) ///< assignement operator
|
||||
{
|
||||
swap(*this, rhs);
|
||||
return *this;
|
||||
}
|
||||
|
||||
/// @brief Destructor
|
||||
/// @note Please note that the destructor is not virtual. It is assumed that
|
||||
/// you will not derive from this class.
|
||||
~category();
|
||||
|
||||
friend void swap(category &a, category &b) noexcept;
|
||||
|
||||
// --------------------------------------------------------------------
|
||||
|
||||
const std::string &name() const { return m_name; } ///< Returns the name of the 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
|
||||
[[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
|
||||
iset key_items() 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.
|
||||
[[deprecated("use key_item_indices instead")]] std::set<uint16_t> key_field_indices() const; ///< Returns a set of indices for the key items.
|
||||
|
||||
std::set<uint16_t> key_item_indices() const; ///< Returns a set of indices for the key items.
|
||||
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.
|
||||
@@ -174,7 +182,7 @@ class category
|
||||
|
||||
/// @brief Update the links in this category
|
||||
/// @param db The enclosing @ref datablock
|
||||
void update_links(datablock &db);
|
||||
void update_links(const datablock &db);
|
||||
|
||||
/// @brief Return the global @ref validator for the data
|
||||
/// @return The @ref validator or nullptr if not assigned
|
||||
@@ -1010,7 +1018,8 @@ class category
|
||||
|
||||
void update_value(const std::vector<row_handle> &rows, std::string_view item_name, std::string_view value)
|
||||
{
|
||||
update_value(rows, item_name, [value](std::string_view) { return value; });
|
||||
update_value(rows, item_name, [value](std::string_view)
|
||||
{ return value; });
|
||||
}
|
||||
|
||||
// --------------------------------------------------------------------
|
||||
@@ -1018,8 +1027,7 @@ class category
|
||||
// the old function names are here as deprecated variants.
|
||||
|
||||
/// \brief Return the index number for \a column_name
|
||||
[[deprecated("Use get_item_ix instead")]]
|
||||
uint16_t get_column_ix(std::string_view column_name) const
|
||||
[[deprecated("Use get_item_ix instead")]] uint16_t get_column_ix(std::string_view column_name) const
|
||||
{
|
||||
return get_item_ix(column_name);
|
||||
}
|
||||
@@ -1027,8 +1035,7 @@ class category
|
||||
/// @brief Return the name for column with index @a ix
|
||||
/// @param ix The index number
|
||||
/// @return The name of the column
|
||||
[[deprecated("use get_item_name instead")]]
|
||||
std::string_view get_column_name(uint16_t ix) const
|
||||
[[deprecated("use get_item_name instead")]] std::string_view get_column_name(uint16_t ix) const
|
||||
{
|
||||
return get_item_name(ix);
|
||||
}
|
||||
@@ -1036,8 +1043,7 @@ class category
|
||||
/// @brief Make sure a item with name @a item_name is known and return its index number
|
||||
/// @param item_name The name of the item
|
||||
/// @return The index number of the item
|
||||
[[deprecated("use add_item instead")]]
|
||||
uint16_t add_column(std::string_view item_name)
|
||||
[[deprecated("use add_item instead")]] uint16_t add_column(std::string_view item_name)
|
||||
{
|
||||
return add_item(item_name);
|
||||
}
|
||||
@@ -1045,15 +1051,13 @@ class category
|
||||
/** @brief Remove column name @a colum_name
|
||||
* @param column_name The column to be removed
|
||||
*/
|
||||
[[deprecated("use remove_item instead")]]
|
||||
void remove_column(std::string_view column_name)
|
||||
[[deprecated("use remove_item instead")]] void remove_column(std::string_view column_name)
|
||||
{
|
||||
remove_item(column_name);
|
||||
}
|
||||
|
||||
/** @brief Rename column @a from_name to @a to_name */
|
||||
[[deprecated("use rename_item instead")]]
|
||||
void rename_column(std::string_view from_name, std::string_view to_name)
|
||||
[[deprecated("use rename_item instead")]] void rename_column(std::string_view from_name, std::string_view to_name)
|
||||
{
|
||||
rename_item(from_name, to_name);
|
||||
}
|
||||
@@ -1061,15 +1065,13 @@ class category
|
||||
/// @brief Return whether a column with name @a name exists in this category
|
||||
/// @param name The name of the column
|
||||
/// @return True if the column exists
|
||||
[[deprecated("use has_item instead")]]
|
||||
bool has_column(std::string_view name) const
|
||||
[[deprecated("use has_item instead")]] bool has_column(std::string_view name) const
|
||||
{
|
||||
return has_item(name);
|
||||
}
|
||||
|
||||
/// @brief Return the cif::iset of columns in this category
|
||||
[[deprecated("use get_items instead")]]
|
||||
iset get_columns() const
|
||||
[[deprecated("use get_items instead")]] iset get_columns() const
|
||||
{
|
||||
return get_items();
|
||||
}
|
||||
@@ -1125,7 +1127,7 @@ class category
|
||||
{
|
||||
item_validator = m_cat_validator->get_validator_for_item(item_name);
|
||||
if (item_validator == nullptr)
|
||||
m_validator->report_error( validation_error::item_not_allowed_in_category, m_name, item_name, false);
|
||||
m_validator->report_error(validation_error::item_not_allowed_in_category, m_name, item_name, false);
|
||||
}
|
||||
|
||||
m_items.emplace_back(item_name, item_validator);
|
||||
@@ -1169,8 +1171,7 @@ 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")]] std::vector<std::string> get_tag_order() const
|
||||
{
|
||||
return get_item_order();
|
||||
}
|
||||
@@ -1262,6 +1263,7 @@ class category
|
||||
{
|
||||
}
|
||||
|
||||
// TODO: NEED TO FIX THIS!
|
||||
category *linked;
|
||||
const link_validator *v;
|
||||
};
|
||||
|
||||
@@ -61,12 +61,26 @@ class datablock : public std::list<category>
|
||||
|
||||
/** @cond */
|
||||
datablock(const datablock &);
|
||||
datablock(datablock &&) = default;
|
||||
|
||||
datablock &operator=(const datablock &);
|
||||
datablock &operator=(datablock &&) = default;
|
||||
datablock(datablock &&db) noexcept
|
||||
{
|
||||
swap_(*this, db);
|
||||
}
|
||||
|
||||
datablock &operator=(datablock db)
|
||||
{
|
||||
swap_(*this, db);
|
||||
return *this;
|
||||
}
|
||||
/** @endcond */
|
||||
|
||||
friend void swap_(datablock &a, datablock &b) noexcept
|
||||
{
|
||||
std::swap(a.m_name, b.m_name);
|
||||
std::swap(a.m_validator, b.m_validator);
|
||||
std::swap(static_cast<std::list<category>&>(a), static_cast<std::list<category>&>(b));
|
||||
}
|
||||
|
||||
// --------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
|
||||
@@ -100,10 +100,22 @@ class file : public std::list<datablock>
|
||||
}
|
||||
|
||||
/** @cond */
|
||||
file(const file &) = default;
|
||||
file(file &&) = default;
|
||||
file &operator=(const file &) = default;
|
||||
file &operator=(file &&) = default;
|
||||
file(const file &rhs)
|
||||
: std::list<datablock>(rhs)
|
||||
{
|
||||
}
|
||||
|
||||
file(file &&rhs)
|
||||
{
|
||||
this->swap(rhs);
|
||||
}
|
||||
|
||||
file &operator=(file f)
|
||||
{
|
||||
this->swap(f);
|
||||
return *this;
|
||||
}
|
||||
|
||||
/** @endcond */
|
||||
|
||||
/**
|
||||
|
||||
@@ -117,7 +117,7 @@ class item
|
||||
char buffer[32];
|
||||
|
||||
auto r = to_chars(buffer, buffer + sizeof(buffer) - 1, value, chars_format::fixed, precision);
|
||||
if (r.ec != std::errc())
|
||||
if ((bool)r.ec)
|
||||
throw std::runtime_error("Could not format number");
|
||||
|
||||
m_value.assign(buffer, r.ptr - buffer);
|
||||
@@ -136,7 +136,7 @@ class item
|
||||
char buffer[32];
|
||||
|
||||
auto r = to_chars(buffer, buffer + sizeof(buffer) - 1, value, chars_format::general);
|
||||
if (r.ec != std::errc())
|
||||
if ((bool)r.ec)
|
||||
throw std::runtime_error("Could not format number");
|
||||
|
||||
m_value.assign(buffer, r.ptr - buffer);
|
||||
@@ -151,7 +151,7 @@ class item
|
||||
char buffer[32];
|
||||
|
||||
auto r = std::to_chars(buffer, buffer + sizeof(buffer) - 1, value);
|
||||
if (r.ec != std::errc())
|
||||
if ((bool)r.ec)
|
||||
throw std::runtime_error("Could not format number");
|
||||
|
||||
m_value.assign(buffer, r.ptr - buffer);
|
||||
@@ -288,19 +288,16 @@ struct item_value
|
||||
}
|
||||
|
||||
/** @cond */
|
||||
item_value(item_value &&rhs)
|
||||
item_value(item_value &&rhs) noexcept
|
||||
: m_length(std::exchange(rhs.m_length, 0))
|
||||
, m_storage(std::exchange(rhs.m_storage, 0))
|
||||
{
|
||||
}
|
||||
|
||||
item_value &operator=(item_value &&rhs)
|
||||
item_value &operator=(item_value &&rhs) noexcept
|
||||
{
|
||||
if (this != &rhs)
|
||||
{
|
||||
m_length = std::exchange(rhs.m_length, m_length);
|
||||
m_storage = std::exchange(rhs.m_storage, m_storage);
|
||||
}
|
||||
std::swap(m_length, rhs.m_length);
|
||||
std::swap(m_storage, rhs.m_storage);
|
||||
return *this;
|
||||
}
|
||||
|
||||
@@ -563,7 +560,7 @@ struct item_handle::item_value_as<T, std::enable_if_t<std::is_arithmetic_v<T> an
|
||||
|
||||
std::from_chars_result r = (b + 1 < e and *b == '+' and std::isdigit(b[1])) ? selected_charconv<value_type>::from_chars(b + 1, e, result) : selected_charconv<value_type>::from_chars(b, e, result);
|
||||
|
||||
if (r.ec != std::errc() or r.ptr != e)
|
||||
if ((bool)r.ec or r.ptr != e)
|
||||
{
|
||||
result = {};
|
||||
if (cif::VERBOSE)
|
||||
@@ -598,7 +595,7 @@ struct item_handle::item_value_as<T, std::enable_if_t<std::is_arithmetic_v<T> an
|
||||
|
||||
std::from_chars_result r = (b + 1 < e and *b == '+' and std::isdigit(b[1])) ? selected_charconv<value_type>::from_chars(b + 1, e, v) : selected_charconv<value_type>::from_chars(b, e, v);
|
||||
|
||||
if (r.ec != std::errc() or r.ptr != e)
|
||||
if ((bool)r.ec or r.ptr != e)
|
||||
{
|
||||
if (cif::VERBOSE)
|
||||
{
|
||||
|
||||
@@ -49,7 +49,7 @@ namespace cif
|
||||
/**
|
||||
* @brief Implementation of an iterator that can return
|
||||
* multiple values in a tuple. Of course, that tuple can
|
||||
* then used in structured binding to receive the values
|
||||
* then be used in structured binding to receive the values
|
||||
* in a for loop e.g.
|
||||
*
|
||||
* @tparam Category The category for this iterator
|
||||
@@ -84,11 +84,11 @@ class iterator_impl
|
||||
iterator_impl() = default;
|
||||
|
||||
iterator_impl(const iterator_impl &rhs) = default;
|
||||
iterator_impl(iterator_impl &&rhs) = default;
|
||||
|
||||
template <typename C2, typename... T2s>
|
||||
iterator_impl(const iterator_impl<C2, T2s...> &rhs)
|
||||
: m_category(rhs.m_category)
|
||||
, m_current(rhs.m_current)
|
||||
: m_current(const_cast<row_handle&>(rhs.m_current))
|
||||
, m_value(rhs.m_value)
|
||||
, m_item_ix(rhs.m_item_ix)
|
||||
{
|
||||
@@ -96,8 +96,7 @@ class iterator_impl
|
||||
|
||||
template <typename IRowType>
|
||||
iterator_impl(iterator_impl<IRowType, Ts...> &rhs)
|
||||
: m_category(rhs.m_category)
|
||||
, m_current(const_cast<row_type *>(rhs.m_current))
|
||||
: m_current(const_cast<row_handle&>(rhs.m_current))
|
||||
, m_value(rhs.m_value)
|
||||
, m_item_ix(rhs.m_item_ix)
|
||||
{
|
||||
@@ -106,19 +105,17 @@ class iterator_impl
|
||||
|
||||
template <typename IRowType>
|
||||
iterator_impl(const iterator_impl<IRowType> &rhs, const std::array<uint16_t, N> &cix)
|
||||
: m_category(rhs.m_category)
|
||||
, m_current(rhs.m_current)
|
||||
: m_current(const_cast<row_handle&>(rhs.m_current))
|
||||
, m_item_ix(cix)
|
||||
{
|
||||
m_value = get(std::make_index_sequence<N>());
|
||||
}
|
||||
|
||||
iterator_impl &operator=(const iterator_impl &i)
|
||||
iterator_impl &operator=(iterator_impl i)
|
||||
{
|
||||
m_category = i.m_category;
|
||||
m_current = i.m_current;
|
||||
m_item_ix = i.m_item_ix;
|
||||
m_value = i.m_value;
|
||||
std::swap(m_current, i.m_current);
|
||||
std::swap(m_item_ix, i.m_item_ix);
|
||||
std::swap(m_value, i.m_value);
|
||||
return *this;
|
||||
}
|
||||
|
||||
@@ -136,18 +133,18 @@ class iterator_impl
|
||||
|
||||
operator const row_handle() const
|
||||
{
|
||||
return { *m_category, *m_current };
|
||||
return m_current;
|
||||
}
|
||||
|
||||
operator row_handle()
|
||||
{
|
||||
return { *m_category, *m_current };
|
||||
return m_current;
|
||||
}
|
||||
|
||||
iterator_impl &operator++()
|
||||
{
|
||||
if (m_current != nullptr)
|
||||
m_current = m_current->m_next;
|
||||
if (m_current)
|
||||
m_current.m_row = m_current.m_row->m_next;
|
||||
|
||||
m_value = get(std::make_index_sequence<N>());
|
||||
|
||||
@@ -182,17 +179,10 @@ class iterator_impl
|
||||
template <size_t... Is>
|
||||
tuple_type get(std::index_sequence<Is...>) const
|
||||
{
|
||||
if (m_current != nullptr)
|
||||
{
|
||||
row_handle rh{ *m_category, *m_current };
|
||||
return tuple_type{ rh[m_item_ix[Is]].template as<Ts>()... };
|
||||
}
|
||||
|
||||
return {};
|
||||
return m_current ? tuple_type{ m_current[m_item_ix[Is]].template as<Ts>()... } : tuple_type{};
|
||||
}
|
||||
|
||||
category_type *m_category = nullptr;
|
||||
row_type *m_current = nullptr;
|
||||
row_handle m_current;
|
||||
value_type m_value;
|
||||
std::array<uint16_t, N> m_item_ix;
|
||||
};
|
||||
@@ -219,37 +209,34 @@ class iterator_impl<Category>
|
||||
using iterator_category = std::forward_iterator_tag;
|
||||
using value_type = row_handle;
|
||||
using difference_type = std::ptrdiff_t;
|
||||
using pointer = row_handle;
|
||||
using reference = row_handle;
|
||||
using pointer = value_type *;
|
||||
using reference = value_type &;
|
||||
|
||||
iterator_impl() = default;
|
||||
|
||||
iterator_impl(const iterator_impl &rhs) = default;
|
||||
iterator_impl(iterator_impl &&rhs) = default;
|
||||
|
||||
template <typename C2>
|
||||
iterator_impl(const iterator_impl<C2> &rhs)
|
||||
: m_category(rhs.m_category)
|
||||
, m_current(const_cast<row_type *>(rhs.m_current))
|
||||
: m_current(const_cast<row_handle &>(rhs.m_current))
|
||||
{
|
||||
}
|
||||
|
||||
iterator_impl(Category &cat, row *current)
|
||||
: m_category(const_cast<category_type *>(&cat))
|
||||
, m_current(current)
|
||||
: m_current(cat, *current)
|
||||
{
|
||||
}
|
||||
|
||||
template <typename IRowType>
|
||||
iterator_impl(const iterator_impl<IRowType> &rhs, const std::array<uint16_t, 0> &)
|
||||
: m_category(rhs.m_category)
|
||||
, m_current(rhs.m_current)
|
||||
: m_current(const_cast<row_handle &>(rhs.m_current))
|
||||
{
|
||||
}
|
||||
|
||||
iterator_impl &operator=(const iterator_impl &i)
|
||||
iterator_impl &operator=(iterator_impl i)
|
||||
{
|
||||
m_category = i.m_category;
|
||||
m_current = i.m_current;
|
||||
std::swap(m_current, i.m_current);
|
||||
return *this;
|
||||
}
|
||||
|
||||
@@ -257,7 +244,7 @@ class iterator_impl<Category>
|
||||
|
||||
reference operator*()
|
||||
{
|
||||
return { *m_category, *m_current };
|
||||
return m_current;
|
||||
}
|
||||
|
||||
pointer operator->()
|
||||
@@ -267,18 +254,18 @@ class iterator_impl<Category>
|
||||
|
||||
operator const row_handle() const
|
||||
{
|
||||
return { *m_category, *m_current };
|
||||
return m_current;
|
||||
}
|
||||
|
||||
operator row_handle()
|
||||
{
|
||||
return { *m_category, *m_current };
|
||||
return m_current;
|
||||
}
|
||||
|
||||
iterator_impl &operator++()
|
||||
{
|
||||
if (m_current != nullptr)
|
||||
m_current = m_current->m_next;
|
||||
if (m_current)
|
||||
m_current.m_row = m_current.m_row->m_next;
|
||||
|
||||
return *this;
|
||||
}
|
||||
@@ -308,8 +295,7 @@ class iterator_impl<Category>
|
||||
/** @endcond */
|
||||
|
||||
private:
|
||||
category_type *m_category = nullptr;
|
||||
row_type *m_current = nullptr;
|
||||
row_handle m_current;
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -342,11 +328,11 @@ class iterator_impl<Category, T>
|
||||
iterator_impl() = default;
|
||||
|
||||
iterator_impl(const iterator_impl &rhs) = default;
|
||||
iterator_impl(iterator_impl &&rhs) = default;
|
||||
|
||||
template <typename C2, typename T2>
|
||||
iterator_impl(const iterator_impl<C2, T2> &rhs)
|
||||
: m_category(rhs.m_category)
|
||||
, m_current(rhs.m_current)
|
||||
: m_current(rhs.m_current)
|
||||
, m_value(rhs.m_value)
|
||||
, m_item_ix(rhs.m_item_ix)
|
||||
{
|
||||
@@ -354,29 +340,26 @@ class iterator_impl<Category, T>
|
||||
|
||||
template <typename IRowType>
|
||||
iterator_impl(iterator_impl<IRowType, T> &rhs)
|
||||
: m_category(rhs.m_category)
|
||||
, m_current(const_cast<row_type *>(rhs.m_current))
|
||||
: m_current(const_cast<row_handle&>(rhs.m_current))
|
||||
, m_value(rhs.m_value)
|
||||
, m_item_ix(rhs.m_item_ix)
|
||||
{
|
||||
m_value = get(m_current);
|
||||
m_value = get();
|
||||
}
|
||||
|
||||
template <typename IRowType>
|
||||
iterator_impl(const iterator_impl<IRowType> &rhs, const std::array<uint16_t, 1> &cix)
|
||||
: m_category(rhs.m_category)
|
||||
, m_current(rhs.m_current)
|
||||
: m_current(const_cast<row_handle&>(rhs.m_current))
|
||||
, m_item_ix(cix[0])
|
||||
{
|
||||
m_value = get();
|
||||
}
|
||||
|
||||
iterator_impl &operator=(const iterator_impl &i)
|
||||
iterator_impl &operator=(iterator_impl i)
|
||||
{
|
||||
m_category = i.m_category;
|
||||
m_current = i.m_current;
|
||||
m_item_ix = i.m_item_ix;
|
||||
m_value = i.m_value;
|
||||
std::swap(m_current, i.m_current);
|
||||
std::swap(m_item_ix, i.m_item_ix);
|
||||
std::swap(m_value, i.m_value);
|
||||
return *this;
|
||||
}
|
||||
|
||||
@@ -394,18 +377,18 @@ class iterator_impl<Category, T>
|
||||
|
||||
operator const row_handle() const
|
||||
{
|
||||
return { *m_category, *m_current };
|
||||
return m_current;
|
||||
}
|
||||
|
||||
operator row_handle()
|
||||
{
|
||||
return { *m_category, *m_current };
|
||||
return m_current;
|
||||
}
|
||||
|
||||
iterator_impl &operator++()
|
||||
{
|
||||
if (m_current != nullptr)
|
||||
m_current = m_current->m_next;
|
||||
if (m_current)
|
||||
m_current.m_row = m_current.m_row->m_next;
|
||||
|
||||
m_value = get();
|
||||
|
||||
@@ -439,17 +422,10 @@ class iterator_impl<Category, T>
|
||||
private:
|
||||
value_type get() const
|
||||
{
|
||||
if (m_current != nullptr)
|
||||
{
|
||||
row_handle rh{ *m_category, *m_current };
|
||||
return rh[m_item_ix].template as<T>();
|
||||
}
|
||||
|
||||
return {};
|
||||
return m_current ? m_current[m_item_ix].template as<value_type>() : value_type{};
|
||||
}
|
||||
|
||||
category_type *m_category = nullptr;
|
||||
row_type *m_current = nullptr;
|
||||
row_handle m_current;
|
||||
value_type m_value;
|
||||
uint16_t m_item_ix;
|
||||
};
|
||||
|
||||
@@ -741,7 +741,7 @@ class sugar : public residue
|
||||
{
|
||||
int result;
|
||||
auto r = std::from_chars(m_auth_seq_id.data(), m_auth_seq_id.data() + m_auth_seq_id.length(), result);
|
||||
if (r.ec != std::errc())
|
||||
if ((bool)r.ec)
|
||||
throw std::runtime_error("The auth_seq_id should be a number for a sugar");
|
||||
return result;
|
||||
}
|
||||
|
||||
@@ -208,6 +208,7 @@ class row_handle
|
||||
friend class category;
|
||||
friend class category_index;
|
||||
friend class row_initializer;
|
||||
template <typename, typename...> friend class iterator_impl;
|
||||
|
||||
row_handle() = default;
|
||||
|
||||
|
||||
@@ -383,7 +383,7 @@ std::from_chars_result from_chars(const char *first, const char *last, FloatType
|
||||
int exponent = 0;
|
||||
bool done = false;
|
||||
|
||||
while (not done and result.ec == std::errc())
|
||||
while (not done and not (bool)result.ec)
|
||||
{
|
||||
char ch = result.ptr != last ? *result.ptr : 0;
|
||||
++result.ptr;
|
||||
@@ -467,7 +467,7 @@ std::from_chars_result from_chars(const char *first, const char *last, FloatType
|
||||
}
|
||||
}
|
||||
|
||||
if (result.ec == std::errc())
|
||||
if (not (bool)result.ec)
|
||||
{
|
||||
long double v = f * vi * sign;
|
||||
if (exponent != 0)
|
||||
|
||||
@@ -113,16 +113,12 @@ namespace colour
|
||||
/**
|
||||
* @brief Struct for delimited strings.
|
||||
*/
|
||||
template <typename StringType>
|
||||
struct coloured_string_t
|
||||
{
|
||||
static_assert(std::is_reference_v<StringType> or std::is_pointer_v<StringType>,
|
||||
"String type must be pointer or reference");
|
||||
|
||||
/**
|
||||
* @brief Construct a new coloured string t object
|
||||
*/
|
||||
coloured_string_t(StringType s, colour_type fc, colour_type bc, style_type st)
|
||||
coloured_string_t(std::string_view s, colour_type fc, colour_type bc, style_type st)
|
||||
: m_str(s)
|
||||
, m_fore_colour(static_cast<int>(fc) + 30)
|
||||
, m_back_colour(static_cast<int>(bc) + 40)
|
||||
@@ -152,12 +148,14 @@ namespace colour
|
||||
<< cs.m_str
|
||||
<< "\033[0m";
|
||||
}
|
||||
else
|
||||
os << cs.m_str;
|
||||
|
||||
return os;
|
||||
}
|
||||
|
||||
/// @cond
|
||||
StringType m_str;
|
||||
std::string_view m_str;
|
||||
int m_fore_colour, m_back_colour;
|
||||
int m_style;
|
||||
/// @endcond
|
||||
@@ -191,39 +189,13 @@ namespace colour
|
||||
* @param st Text style to use
|
||||
*/
|
||||
|
||||
template <typename char_type>
|
||||
inline auto coloured(const char_type *str,
|
||||
template <typename T>
|
||||
requires std::is_assignable_v<std::string_view, T>
|
||||
inline auto coloured(T str,
|
||||
colour::colour_type fg, colour::colour_type bg = colour::colour_type::none,
|
||||
colour::style_type st = colour::style_type::regular)
|
||||
{
|
||||
return colour::detail::coloured_string_t<const char_type *>(str, fg, bg, st);
|
||||
}
|
||||
|
||||
/// @brief Manipulator for coloured strings.
|
||||
template <typename char_type, typename traits_type, typename allocator_type>
|
||||
inline auto coloured(const std::basic_string<char_type, traits_type, allocator_type> &str,
|
||||
colour::colour_type fg, colour::colour_type bg = colour::colour_type::none,
|
||||
colour::style_type st = colour::style_type::regular)
|
||||
{
|
||||
return colour::detail::coloured_string_t<const std::basic_string<char_type, traits_type, allocator_type> &>(str, fg, bg, st);
|
||||
}
|
||||
|
||||
/// @brief Manipulator for coloured strings.
|
||||
template <typename char_type, typename traits_type, typename allocator_type>
|
||||
inline auto coloured(std::basic_string<char_type, traits_type, allocator_type> &str,
|
||||
colour::colour_type fg, colour::colour_type bg = colour::colour_type::none,
|
||||
colour::style_type st = colour::style_type::regular)
|
||||
{
|
||||
return colour::detail::coloured_string_t<std::basic_string<char_type, traits_type, allocator_type> &>(str, fg, bg, st);
|
||||
}
|
||||
|
||||
/// @brief Manipulator for coloured strings.
|
||||
template <typename char_type, typename traits_type>
|
||||
inline auto coloured(std::basic_string_view<char_type, traits_type> &str,
|
||||
colour::colour_type fg, colour::colour_type bg = colour::colour_type::none,
|
||||
colour::style_type st = colour::style_type::regular)
|
||||
{
|
||||
return colour::detail::coloured_string_t<std::basic_string_view<char_type, traits_type> &>(str, fg, bg, st);
|
||||
return colour::detail::coloured_string_t(str, fg, bg, st);
|
||||
}
|
||||
|
||||
// --------------------------------------------------------------------
|
||||
|
||||
@@ -120,7 +120,7 @@ class validation_category_impl : public std::error_category
|
||||
case validation_error::missing_key_items:
|
||||
return "An index could not be constructed due to missing key items";
|
||||
case validation_error::item_not_allowed_in_category:
|
||||
return "Requested item allowed in category according to dictionary";
|
||||
return "Requested item not allowed in category according to dictionary";
|
||||
case validation_error::empty_file:
|
||||
return "The file contains no datablocks";
|
||||
case validation_error::empty_datablock:
|
||||
|
||||
@@ -521,71 +521,18 @@ category::category(const category &rhs)
|
||||
m_index = new category_index(*this);
|
||||
}
|
||||
|
||||
category::category(category &&rhs)
|
||||
: m_name(std::move(rhs.m_name))
|
||||
, m_items(std::move(rhs.m_items))
|
||||
, m_validator(rhs.m_validator)
|
||||
, m_cat_validator(rhs.m_cat_validator)
|
||||
, m_parent_links(std::move(rhs.m_parent_links))
|
||||
, m_child_links(std::move(rhs.m_child_links))
|
||||
, m_cascade(rhs.m_cascade)
|
||||
, m_index(rhs.m_index)
|
||||
, m_head(rhs.m_head)
|
||||
, m_tail(rhs.m_tail)
|
||||
void swap(category &a, category &b) noexcept
|
||||
{
|
||||
rhs.m_head = nullptr;
|
||||
rhs.m_tail = nullptr;
|
||||
rhs.m_index = nullptr;
|
||||
}
|
||||
|
||||
category &category::operator=(const category &rhs)
|
||||
{
|
||||
if (this != &rhs)
|
||||
{
|
||||
if (not empty())
|
||||
clear();
|
||||
|
||||
m_name = rhs.m_name;
|
||||
m_items = rhs.m_items;
|
||||
m_cascade = rhs.m_cascade;
|
||||
|
||||
m_validator = nullptr;
|
||||
m_cat_validator = nullptr;
|
||||
|
||||
delete m_index;
|
||||
m_index = nullptr;
|
||||
|
||||
for (auto r = rhs.m_head; r != nullptr; r = r->m_next)
|
||||
insert_impl(cend(), clone_row(*r));
|
||||
|
||||
m_validator = rhs.m_validator;
|
||||
m_cat_validator = rhs.m_cat_validator;
|
||||
|
||||
if (m_cat_validator != nullptr and m_index == nullptr)
|
||||
m_index = new category_index(*this);
|
||||
}
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
category &category::operator=(category &&rhs)
|
||||
{
|
||||
if (this != &rhs)
|
||||
{
|
||||
m_name = std::move(rhs.m_name);
|
||||
m_items = std::move(rhs.m_items);
|
||||
m_cascade = rhs.m_cascade;
|
||||
m_validator = rhs.m_validator;
|
||||
m_cat_validator = rhs.m_cat_validator;
|
||||
m_parent_links = rhs.m_parent_links;
|
||||
m_child_links = rhs.m_child_links;
|
||||
|
||||
std::swap(m_index, rhs.m_index);
|
||||
std::swap(m_head, rhs.m_head);
|
||||
std::swap(m_tail, rhs.m_tail);
|
||||
}
|
||||
|
||||
return *this;
|
||||
std::swap(a.m_name, b.m_name);
|
||||
std::swap(a.m_items, b.m_items);
|
||||
std::swap(a.m_validator, b.m_validator);
|
||||
std::swap(a.m_cat_validator, b.m_cat_validator);
|
||||
std::swap(a.m_parent_links, b.m_parent_links);
|
||||
std::swap(a.m_child_links, b.m_child_links);
|
||||
std::swap(a.m_cascade, b.m_cascade);
|
||||
std::swap(a.m_index, b.m_index);
|
||||
std::swap(a.m_head, b.m_head);
|
||||
std::swap(a.m_tail, b.m_tail);
|
||||
}
|
||||
|
||||
category::~category()
|
||||
@@ -719,7 +666,7 @@ void category::set_validator(const validator *v, datablock &db)
|
||||
update_links(db);
|
||||
}
|
||||
|
||||
void category::update_links(datablock &db)
|
||||
void category::update_links(const datablock &db)
|
||||
{
|
||||
m_child_links.clear();
|
||||
m_parent_links.clear();
|
||||
@@ -728,7 +675,7 @@ void category::update_links(datablock &db)
|
||||
{
|
||||
for (auto link : m_validator->get_links_for_parent(m_name))
|
||||
{
|
||||
auto childCat = db.get(link->m_child_category);
|
||||
auto childCat = const_cast<category *>(db.get(link->m_child_category));
|
||||
if (childCat == nullptr)
|
||||
continue;
|
||||
m_child_links.emplace_back(childCat, link);
|
||||
@@ -736,7 +683,7 @@ void category::update_links(datablock &db)
|
||||
|
||||
for (auto link : m_validator->get_links_for_child(m_name))
|
||||
{
|
||||
auto parentCat = db.get(link->m_parent_category);
|
||||
auto parentCat = const_cast<category *>(db.get(link->m_parent_category));
|
||||
if (parentCat == nullptr)
|
||||
continue;
|
||||
m_parent_links.emplace_back(parentCat, link);
|
||||
@@ -844,7 +791,7 @@ bool category::is_valid() const
|
||||
|
||||
iv->validate_value(vi->text(), ec);
|
||||
|
||||
if (ec != std::errc())
|
||||
if ((bool)ec)
|
||||
{
|
||||
m_validator->report_error(ec, m_name, m_items[cix].m_name, false);
|
||||
continue;
|
||||
@@ -1712,7 +1659,7 @@ category::iterator category::insert_impl(const_iterator pos, row *n)
|
||||
m_index->insert(*this, n);
|
||||
|
||||
// insert at end, most often this is the case
|
||||
if (pos.m_current == nullptr)
|
||||
if (pos.m_current.m_row == nullptr)
|
||||
{
|
||||
if (m_head == nullptr)
|
||||
m_tail = m_head = n;
|
||||
@@ -1723,7 +1670,7 @@ category::iterator category::insert_impl(const_iterator pos, row *n)
|
||||
{
|
||||
assert(m_head != nullptr);
|
||||
|
||||
if (pos.m_current == m_head)
|
||||
if (pos.m_current.m_row == m_head)
|
||||
m_head = n->m_next = m_head;
|
||||
else
|
||||
n = n->m_next = m_head->m_next;
|
||||
|
||||
130
src/compound.cpp
130
src/compound.cpp
@@ -545,12 +545,29 @@ class local_compound_factory_impl : public compound_factory_impl
|
||||
: compound_factory_impl(next)
|
||||
, m_local_file(file)
|
||||
{
|
||||
const std::regex peptideRx("(?:[lmp]-)?peptide", std::regex::icase);
|
||||
|
||||
for (const auto &[id, name, threeLetterCode, group] :
|
||||
file["comp_list"]["chem_comp"].rows<std::string, std::string, std::string, std::string>("id", "name", "three_letter_code", "group"))
|
||||
{
|
||||
auto &rdb = m_local_file["comp_" + id];
|
||||
if (rdb.empty())
|
||||
{
|
||||
std::cerr << "Missing data in restraint file for id " + id + '\n';
|
||||
continue;
|
||||
}
|
||||
|
||||
construct_compound(rdb, id, name, threeLetterCode, group);
|
||||
}
|
||||
}
|
||||
|
||||
compound *create(const std::string &id) override;
|
||||
|
||||
private:
|
||||
const cif::file &m_local_file;
|
||||
|
||||
compound *construct_compound(const datablock &db, const std::string &id, const std::string &name, const std::string &three_letter_code, const std::string &group);
|
||||
|
||||
cif::file m_local_file;
|
||||
};
|
||||
|
||||
compound *local_compound_factory_impl::create(const std::string &id)
|
||||
@@ -561,12 +578,21 @@ compound *local_compound_factory_impl::create(const std::string &id)
|
||||
{
|
||||
if (db.name() == "comp_" + id)
|
||||
{
|
||||
cif::datablock db_copy(db);
|
||||
auto chem_comp = db.get("chem_comp");
|
||||
if (not chem_comp)
|
||||
break;
|
||||
|
||||
result = new compound(db_copy, 1);
|
||||
try
|
||||
{
|
||||
const auto &[id, name, threeLetterCode, group] =
|
||||
chem_comp->front().get<std::string, std::string, std::string, std::string>("id", "name", "three_letter_code", "group");
|
||||
|
||||
std::shared_lock lock(mMutex);
|
||||
m_compounds.push_back(result);
|
||||
result = construct_compound(db, id, name, threeLetterCode, group);
|
||||
}
|
||||
catch (const std::exception &ex)
|
||||
{
|
||||
std::throw_with_nested(std::runtime_error("Error loading compound " + id));
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
@@ -575,6 +601,100 @@ compound *local_compound_factory_impl::create(const std::string &id)
|
||||
return result;
|
||||
}
|
||||
|
||||
compound *local_compound_factory_impl::construct_compound(const datablock &rdb, const std::string &id,
|
||||
const std::string &name, const std::string &three_letter_code, const std::string &group)
|
||||
{
|
||||
cif::datablock db(id);
|
||||
|
||||
float formula_weight = 0;
|
||||
int formal_charge = 0;
|
||||
std::map<std::string,size_t> formula_data;
|
||||
|
||||
for (size_t ord = 1; const auto &[atom_id, type_symbol, type, charge, x, y, z] :
|
||||
rdb["chem_comp_atom"].rows<std::string, std::string, std::string, int, float, float, float>(
|
||||
"atom_id", "type_symbol", "type", "charge", "x", "y", "z"))
|
||||
{
|
||||
auto atom = cif::atom_type_traits(type_symbol);
|
||||
formula_weight += atom.weight();
|
||||
|
||||
formula_data[type_symbol] += 1;
|
||||
|
||||
db["chem_comp_atom"].emplace({
|
||||
{ "comp_id", id },
|
||||
{ "atom_id", atom_id },
|
||||
{ "type_symbol", type_symbol },
|
||||
{ "charge", charge },
|
||||
{ "model_Cartn_x", x, 3 },
|
||||
{ "model_Cartn_y", y, 3 },
|
||||
{ "model_Cartn_z", z, 3 },
|
||||
{ "pdbx_ordinal", ord++ }
|
||||
});
|
||||
|
||||
formal_charge += charge;
|
||||
}
|
||||
|
||||
for (size_t ord = 1; const auto &[atom_id_1, atom_id_2, type, aromatic] :
|
||||
rdb["chem_comp_bond"].rows<std::string, std::string, std::string, bool>("atom_id_1", "atom_id_2", "type", "aromatic"))
|
||||
{
|
||||
std::string value_order("SING");
|
||||
|
||||
if (cif::iequals(type, "single") or cif::iequals(type, "sing"))
|
||||
value_order = "SING";
|
||||
else if (cif::iequals(type, "double") or cif::iequals(type, "doub"))
|
||||
value_order = "DOUB";
|
||||
else if (cif::iequals(type, "triple") or cif::iequals(type, "trip"))
|
||||
value_order = "TRIP";
|
||||
|
||||
db["chem_comp_bond"].emplace({
|
||||
{ "comp_id", id },
|
||||
{ "atom_id_1", atom_id_1 },
|
||||
{ "atom_id_2", atom_id_2 },
|
||||
{ "value_order", value_order },
|
||||
{ "pdbx_aromatic_flag", aromatic },
|
||||
// TODO: fetch stereo_config info from chem_comp_chir
|
||||
{ "pdbx_ordinal", ord++ }
|
||||
});
|
||||
}
|
||||
|
||||
db.emplace_back(rdb["pdbx_chem_comp_descriptor"]);
|
||||
|
||||
std::string formula;
|
||||
for (bool first = true; const auto &[symbol, count]: formula_data)
|
||||
{
|
||||
if (std::exchange(first, false))
|
||||
formula += ' ';
|
||||
formula += symbol;
|
||||
if (count > 1)
|
||||
formula += std::to_string(count);
|
||||
}
|
||||
|
||||
std::string type;
|
||||
if (cif::iequals(group, "peptide") or cif::iequals(group, "l-peptide") or cif::iequals(group, "l-peptide linking"))
|
||||
type = "L-PEPTIDE LINKING";
|
||||
else if (cif::iequals(group, "dna"))
|
||||
type = "DNA LINKING";
|
||||
else if (cif::iequals(group, "rna"))
|
||||
type = "RNA LINKING";
|
||||
else
|
||||
type = "NON-POLYMER";
|
||||
|
||||
db["chem_comp"].emplace({
|
||||
{ "id", id },
|
||||
{ "name", name },
|
||||
{ "type", type },
|
||||
{ "formula", formula },
|
||||
{ "pdbx_formal_charge", formal_charge },
|
||||
{ "formula_weight", formula_weight },
|
||||
{ "three_letter_code", three_letter_code }
|
||||
});
|
||||
|
||||
std::shared_lock lock(mMutex);
|
||||
|
||||
auto result = new compound(db);
|
||||
m_compounds.push_back(result);
|
||||
return result;
|
||||
}
|
||||
|
||||
// --------------------------------------------------------------------
|
||||
|
||||
std::unique_ptr<compound_factory> compound_factory::s_instance;
|
||||
|
||||
@@ -38,21 +38,6 @@ datablock::datablock(const datablock &db)
|
||||
cat.update_links(*this);
|
||||
}
|
||||
|
||||
datablock &datablock::operator=(const datablock &db)
|
||||
{
|
||||
if (this != &db)
|
||||
{
|
||||
std::list<category>::operator=(db);
|
||||
m_name = db.m_name;
|
||||
m_validator = db.m_validator;
|
||||
|
||||
for (auto &cat : *this)
|
||||
cat.update_links(*this);
|
||||
}
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
void datablock::set_validator(const validator *v)
|
||||
{
|
||||
m_validator = v;
|
||||
@@ -123,6 +108,9 @@ bool datablock::validate_links() const
|
||||
{
|
||||
bool result = true;
|
||||
|
||||
for (auto &cat : *this)
|
||||
const_cast<category &>(cat).update_links(*this);
|
||||
|
||||
for (auto &cat : *this)
|
||||
result = cat.validate_links() and result;
|
||||
|
||||
@@ -190,6 +178,11 @@ std::tuple<datablock::iterator, bool> datablock::emplace(std::string_view name)
|
||||
}
|
||||
|
||||
assert(i != end());
|
||||
|
||||
// links may have changed...
|
||||
for (auto &cat : *this)
|
||||
cat.update_links(*this);
|
||||
|
||||
return std::make_tuple(i, is_new);
|
||||
}
|
||||
|
||||
@@ -282,7 +275,11 @@ void datablock::write(std::ostream &os) const
|
||||
cat_order_t cat_order;
|
||||
|
||||
for (auto &cat : *this)
|
||||
{
|
||||
if (cat.name() == "entry" or cat.name() == "audit_conform")
|
||||
continue;
|
||||
cat_order.emplace_back(cat.name(), -1, false);
|
||||
}
|
||||
|
||||
for (auto i = cat_order.begin(); i != cat_order.end(); ++i)
|
||||
calculate_cat_order(cat_order, i, *m_validator);
|
||||
@@ -292,25 +289,18 @@ void datablock::write(std::ostream &os) const
|
||||
const auto &[cat_a, count_a, on_stack_a] = a;
|
||||
const auto &[cat_b, count_b, on_stack_b] = b;
|
||||
|
||||
int d = 0;
|
||||
|
||||
if (cat_a == "audit_conform")
|
||||
d = -1;
|
||||
else if (cat_b == "audit_conform")
|
||||
d = 1;
|
||||
else if (cat_a == "entry")
|
||||
d = -1;
|
||||
else if (cat_b == "entry")
|
||||
d = 1;
|
||||
else
|
||||
{
|
||||
d = std::get<1>(a) - std::get<1>(b);
|
||||
if (d == 0)
|
||||
d = cat_b.compare(cat_a);
|
||||
}
|
||||
int d = std::get<1>(a) - std::get<1>(b);
|
||||
if (d == 0)
|
||||
d = cat_b.compare(cat_a);
|
||||
|
||||
return d < 0; });
|
||||
|
||||
if (auto entry = get("entry"); entry != nullptr)
|
||||
entry->write(os);
|
||||
|
||||
if (auto audit_conform = get("audit_conform"); audit_conform != nullptr)
|
||||
audit_conform->write(os);
|
||||
|
||||
for (auto &&[cat, count, on_stack] : cat_order)
|
||||
get(cat)->write(os);
|
||||
}
|
||||
@@ -320,20 +310,13 @@ void datablock::write(std::ostream &os) const
|
||||
// and if it exists, _AND_ we have a Validator, write out the
|
||||
// audit_conform record.
|
||||
|
||||
for (auto &cat : *this)
|
||||
{
|
||||
if (cat.name() != "entry")
|
||||
continue;
|
||||
|
||||
cat.write(os);
|
||||
|
||||
break;
|
||||
}
|
||||
if (auto entry = get("entry"); entry != nullptr)
|
||||
entry->write(os);
|
||||
|
||||
// If the dictionary declares an audit_conform category, put it in,
|
||||
// but only if it does not exist already!
|
||||
if (get("audit_conform"))
|
||||
get("audit_conform")->write(os);
|
||||
if (auto audit_conform = get("audit_conform"); audit_conform != nullptr)
|
||||
audit_conform->write(os);
|
||||
|
||||
for (auto &cat : *this)
|
||||
{
|
||||
@@ -348,7 +331,7 @@ void datablock::write(std::ostream &os, const std::vector<std::string> &item_nam
|
||||
os << "data_" << m_name << '\n'
|
||||
<< "# \n";
|
||||
|
||||
std::vector<std::string> cat_order;
|
||||
std::vector<std::string> cat_order{ "entry", "audit_conform" };
|
||||
for (auto &o : item_name_order)
|
||||
{
|
||||
std::string cat_name, item_name;
|
||||
|
||||
@@ -74,7 +74,7 @@ int atom::atom_impl::get_property_int(std::string_view name) const
|
||||
auto s = get_property(name);
|
||||
|
||||
std::from_chars_result r = std::from_chars(s.data(), s.data() + s.length(), result);
|
||||
if (r.ec != std::errc() and VERBOSE > 0)
|
||||
if ((bool)r.ec and VERBOSE > 0)
|
||||
std::cerr << "Error converting " << s << " to number for property " << name << '\n';
|
||||
}
|
||||
return result;
|
||||
@@ -88,7 +88,7 @@ float atom::atom_impl::get_property_float(std::string_view name) const
|
||||
auto s = get_property(name);
|
||||
|
||||
std::from_chars_result r = cif::from_chars(s.data(), s.data() + s.length(), result);
|
||||
if (r.ec != std::errc() and VERBOSE > 0)
|
||||
if ((bool)r.ec and VERBOSE > 0)
|
||||
std::cerr << "Error converting " << s << " to number for property " << name << '\n';
|
||||
}
|
||||
return result;
|
||||
|
||||
@@ -681,7 +681,7 @@ class Fi : public FBase
|
||||
{
|
||||
long l = 0;
|
||||
auto r = std::from_chars(s.data(), s.data() + s.length(), l);
|
||||
if (r.ec != std::errc())
|
||||
if ((bool)r.ec)
|
||||
{
|
||||
if (VERBOSE > 0)
|
||||
std::cerr << "Failed to write '" << s << "' as a long from field " << mField << ", this indicates an error in the code for writing PDB files\n";
|
||||
@@ -719,7 +719,7 @@ class Ff : public FBase
|
||||
|
||||
double d = 0;
|
||||
auto r = cif::from_chars(s.data(), s.data() + s.length(), d);
|
||||
if (r.ec != std::errc())
|
||||
if ((bool)r.ec)
|
||||
{
|
||||
if (VERBOSE > 0)
|
||||
std::cerr << "Failed to write '" << s << "' as a double from field " << mField << ", this indicates an error in the code for writing PDB files\n";
|
||||
@@ -3393,7 +3393,7 @@ std::tuple<int, int> WriteCoordinatesForModel(std::ostream &pdbFile, const datab
|
||||
{
|
||||
int nr = 0;
|
||||
auto r = std::from_chars(modelNum.data(), modelNum.data() + modelNum.length(), nr);
|
||||
if (r.ec != std::errc())
|
||||
if ((bool)r.ec)
|
||||
{
|
||||
if (VERBOSE > 0)
|
||||
std::cerr << "Model number '" << modelNum << "' is not a valid integer\n";
|
||||
|
||||
@@ -1132,7 +1132,7 @@ void PDBFileParser::PreParseInput(std::istream &is)
|
||||
if (not cs.empty())
|
||||
{
|
||||
auto r = std::from_chars(cs.data(), cs.data() + cs.length(), result);
|
||||
if (r.ec != std::errc())
|
||||
if ((bool)r.ec)
|
||||
throw std::runtime_error("Continuation std::string '" + cs + "' is not valid");
|
||||
}
|
||||
|
||||
@@ -1397,7 +1397,7 @@ void PDBFileParser::PreParseInput(std::istream &is)
|
||||
{
|
||||
auto f = cur->vF(74, 78);
|
||||
auto r = cif::from_chars(f.data(), f.data() + f.length(), link.distance);
|
||||
if (r.ec != std::errc() and cif::VERBOSE > 0)
|
||||
if ((bool)r.ec and cif::VERBOSE > 0)
|
||||
std::cerr << "Error parsing link distance at line " << cur->mLineNr << '\n';
|
||||
}
|
||||
// 74 – 78 Real(5.2) Length Link distance
|
||||
@@ -4669,47 +4669,6 @@ void PDBFileParser::ConstructEntities()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Finish by calculating the formula_weight for each entity
|
||||
for (auto entity : *getCategory("entity"))
|
||||
{
|
||||
auto entity_id = entity["id"].as<std::string>();
|
||||
float formula_weight = 0;
|
||||
|
||||
if (entity["type"] == "polymer")
|
||||
{
|
||||
int n = 0;
|
||||
|
||||
for (std::string comp_id : getCategory("pdbx_poly_seq_scheme")->find<std::string>(cif::key("entity_id") == entity_id, "mon_id"))
|
||||
{
|
||||
auto compound = cif::compound_factory::instance().create(comp_id);
|
||||
assert(compound);
|
||||
if (not compound)
|
||||
throw std::runtime_error("missing information for compound " + comp_id);
|
||||
formula_weight += compound->formula_weight();
|
||||
++n;
|
||||
}
|
||||
|
||||
formula_weight -= (n - 1) * 18.015;
|
||||
}
|
||||
else if (entity["type"] == "water")
|
||||
formula_weight = 18.015;
|
||||
else
|
||||
{
|
||||
auto comp_id = getCategory("pdbx_nonpoly_scheme")->find_first<std::optional<std::string>>(cif::key("entity_id") == entity_id, "mon_id");
|
||||
if (comp_id.has_value())
|
||||
{
|
||||
auto compound = cif::compound_factory::instance().create(*comp_id);
|
||||
assert(compound);
|
||||
if (not compound)
|
||||
throw std::runtime_error("missing information for compound " + *comp_id);
|
||||
formula_weight = compound->formula_weight();
|
||||
}
|
||||
}
|
||||
|
||||
if (formula_weight > 0)
|
||||
entity.assign({ { "formula_weight", formula_weight, 3 } });
|
||||
}
|
||||
}
|
||||
|
||||
void PDBFileParser::ConstructSugarTrees(int &asymNr)
|
||||
@@ -5347,7 +5306,7 @@ void PDBFileParser::ParseConnectivtyAnnotation()
|
||||
|
||||
double d;
|
||||
auto r = cif::from_chars(distance.data(), distance.data() + distance.length(), d);
|
||||
if (r.ec != std::errc())
|
||||
if ((bool)r.ec)
|
||||
{
|
||||
if (cif::VERBOSE > 0)
|
||||
std::cerr << "Distance value '" << distance << "' is not a valid float in LINK record\n";
|
||||
@@ -6454,11 +6413,11 @@ file read(std::istream &is)
|
||||
{
|
||||
std::throw_with_nested(std::runtime_error("Since the file did not start with a valid PDB HEADER line mmCIF was assumed, but that failed."));
|
||||
}
|
||||
|
||||
// Since we're using the cif::pdb way of reading the file, the data may need
|
||||
// reconstruction
|
||||
reconstruct_pdbx(result);
|
||||
}
|
||||
|
||||
// Since we're using the cif::pdb way of reading the file, the data may need
|
||||
// reconstruction
|
||||
reconstruct_pdbx(result);
|
||||
}
|
||||
|
||||
// Must be a PDB like file, right?
|
||||
|
||||
@@ -92,6 +92,70 @@ condition get_condition(residue_key_type &k)
|
||||
|
||||
// --------------------------------------------------------------------
|
||||
|
||||
void checkEntities(datablock &db)
|
||||
{
|
||||
using namespace cif::literals;
|
||||
|
||||
auto &cf = cif::compound_factory::instance();
|
||||
|
||||
for (auto entity : db["entity"].find("formula_weight"_key == null or "formula_weight"_key == 0))
|
||||
{
|
||||
const auto &[entity_id, type] = entity.get<std::string, std::string>("id", "type");
|
||||
|
||||
float formula_weight = 0;
|
||||
|
||||
if (type == "polymer")
|
||||
{
|
||||
int n = 0;
|
||||
|
||||
for (std::string comp_id : db["pdbx_poly_seq_scheme"].find<std::string>("entity_id"_key == entity_id, "mon_id"))
|
||||
{
|
||||
auto compound = cf.create(comp_id);
|
||||
assert(compound);
|
||||
if (not compound)
|
||||
throw std::runtime_error("missing information for compound " + comp_id);
|
||||
formula_weight += compound->formula_weight();
|
||||
++n;
|
||||
}
|
||||
|
||||
formula_weight -= (n - 1) * 18.015;
|
||||
}
|
||||
else if (type == "water")
|
||||
formula_weight = 18.015;
|
||||
else if (type == "branched")
|
||||
{
|
||||
int n = 0;
|
||||
|
||||
for (std::string comp_id : db["pdbx_entity_branch_list"].find<std::string>("entity_id"_key == entity_id, "comp_id"))
|
||||
{
|
||||
auto compound = cf.create(comp_id);
|
||||
assert(compound);
|
||||
if (not compound)
|
||||
throw std::runtime_error("missing information for compound " + comp_id);
|
||||
formula_weight += compound->formula_weight();
|
||||
++n;
|
||||
}
|
||||
|
||||
formula_weight -= (n - 1) * 18.015;
|
||||
}
|
||||
else if (type == "non-polymer")
|
||||
{
|
||||
auto comp_id = db["pdbx_nonpoly_scheme"].find_first<std::optional<std::string>>("entity_id"_key == entity_id, "mon_id");
|
||||
if (comp_id.has_value())
|
||||
{
|
||||
auto compound = cf.create(*comp_id);
|
||||
assert(compound);
|
||||
if (not compound)
|
||||
throw std::runtime_error("missing information for compound " + *comp_id);
|
||||
formula_weight = compound->formula_weight();
|
||||
}
|
||||
}
|
||||
|
||||
if (formula_weight > 0)
|
||||
entity.assign({ { "formula_weight", formula_weight, 3 } });
|
||||
}
|
||||
}
|
||||
|
||||
void createEntityIDs(datablock &db)
|
||||
{
|
||||
// Suppose the file does not have entity ID's. We have to make up some
|
||||
@@ -348,6 +412,10 @@ void checkAtomRecords(datablock &db)
|
||||
if (atom_site.contains(key("label_seq_id") < 0))
|
||||
fixNegativeSeqID(atom_site);
|
||||
|
||||
std::set<int> polymer_entities;
|
||||
for (int id : db["entity"].find<int>("type"_key == "polymer", "id"))
|
||||
polymer_entities.insert(id);
|
||||
|
||||
for (auto row : atom_site)
|
||||
{
|
||||
residue_key_type k = row.get<std::optional<std::string>,
|
||||
@@ -378,7 +446,7 @@ void checkAtomRecords(datablock &db)
|
||||
std::string asym_id = get_asym_id(k);
|
||||
std::string comp_id = get_comp_id(k);
|
||||
|
||||
bool is_peptide = cf.is_peptide(comp_id);
|
||||
bool is_polymer = polymer_entities.contains(row["label_entity_id"].as<int>());
|
||||
auto compound = cf.create(comp_id);
|
||||
|
||||
if (not compound)
|
||||
@@ -386,12 +454,16 @@ void checkAtomRecords(datablock &db)
|
||||
|
||||
auto chem_comp_entry = chem_comp.find_first("id"_key == comp_id);
|
||||
|
||||
std::optional<bool> non_std;
|
||||
if (cf.is_monomer(comp_id))
|
||||
non_std = cf.is_std_monomer(comp_id);
|
||||
|
||||
if (not chem_comp_entry)
|
||||
{
|
||||
chem_comp.emplace({ //
|
||||
{ "id", comp_id },
|
||||
{ "type", compound->type() },
|
||||
{ "mon_nstd_flag", cf.is_std_monomer(comp_id) ? "y" : "n" },
|
||||
{ "mon_nstd_flag", non_std },
|
||||
{ "name", compound->name() },
|
||||
{ "formula", compound->formula() },
|
||||
{ "formula_weight", compound->formula_weight() } });
|
||||
@@ -402,8 +474,8 @@ void checkAtomRecords(datablock &db)
|
||||
|
||||
if (not chem_comp_entry["type"])
|
||||
items.emplace_back(item{ "type", compound->type() });
|
||||
if (not chem_comp_entry["mon_nstd_flag"])
|
||||
items.emplace_back(item{ "mon_nstd_flag", cf.is_std_monomer(comp_id) ? "y" : "n" });
|
||||
if (not chem_comp_entry["mon_nstd_flag"] and non_std.has_value())
|
||||
items.emplace_back(item{ "mon_nstd_flag", non_std });
|
||||
if (not chem_comp_entry["name"])
|
||||
items.emplace_back(item{ "name", compound->name() });
|
||||
if (not chem_comp_entry["formula"])
|
||||
@@ -415,20 +487,18 @@ void checkAtomRecords(datablock &db)
|
||||
chem_comp_entry.assign(items);
|
||||
}
|
||||
|
||||
if (is_peptide and not has_seq_id(k))
|
||||
if (is_polymer and not has_seq_id(k))
|
||||
throw std::runtime_error("atom_site record has peptide comp_id but no sequence number, cannot continue");
|
||||
|
||||
int seq_id = get_seq_id(k);
|
||||
|
||||
if (row["label_seq_id"].empty())
|
||||
if (is_polymer and row["label_seq_id"].empty() and cf.is_monomer(comp_id))
|
||||
row["label_seq_id"] = std::to_string(seq_id);
|
||||
|
||||
if (row["label_atom_id"].empty())
|
||||
row["label_atom_id"] = row["auth_atom_id"].text();
|
||||
if (row["label_asym_id"].empty())
|
||||
row["label_asym_id"] = row["auth_asym_id"].text();
|
||||
if (row["label_seq_id"].empty())
|
||||
row["label_seq_id"] = row["auth_seq_id"].text();
|
||||
if (row["label_comp_id"].empty())
|
||||
row["label_comp_id"] = row["auth_comp_id"].text();
|
||||
if (row["label_atom_id"].empty())
|
||||
@@ -448,14 +518,14 @@ void checkAtomRecords(datablock &db)
|
||||
|
||||
float v;
|
||||
auto s = row.get<std::string>(item_name);
|
||||
if (auto [ptr, ec] = cif::from_chars(s.data(), s.data() + s.length(), v); ec != std::errc())
|
||||
if (auto [ptr, ec] = cif::from_chars(s.data(), s.data() + s.length(), v); (bool)ec)
|
||||
continue;
|
||||
|
||||
if (s.length() < prec + 1 or s[s.length() - prec - 1] != '.')
|
||||
{
|
||||
char b[12];
|
||||
|
||||
if (auto [ptr, ec] = cif::to_chars(b, b + sizeof(b), v, cif::chars_format::fixed, prec); ec == std::errc())
|
||||
if (auto [ptr, ec] = cif::to_chars(b, b + sizeof(b), v, cif::chars_format::fixed, prec); (bool)ec)
|
||||
row.assign(item_name, { b, static_cast<std::string::size_type>(ptr - b) }, false, false);
|
||||
}
|
||||
}
|
||||
@@ -517,7 +587,7 @@ void checkAtomAnisotropRecords(datablock &db)
|
||||
{
|
||||
if (cif::VERBOSE and std::exchange(warnReplaceTypeSymbol, false))
|
||||
std::clog << "Replacing type_symbol in atom_site_anisotrop record(s)\n";
|
||||
row["type_symbol"] != parent["type_symbol"].text();
|
||||
row["type_symbol"] = parent["type_symbol"].text();
|
||||
}
|
||||
|
||||
if (row["pdbx_auth_alt_id"].empty())
|
||||
@@ -1263,6 +1333,9 @@ bool reconstruct_pdbx(file &file, std::string_view dictionary)
|
||||
if (db.get("entity") == nullptr)
|
||||
createEntity(db);
|
||||
|
||||
// fill in missing formula_weight, e.g.
|
||||
checkEntities(db);
|
||||
|
||||
if (db.get("pdbx_poly_seq_scheme") == nullptr)
|
||||
createPdbxPolySeqScheme(db);
|
||||
|
||||
|
||||
@@ -71,7 +71,7 @@ bool is_valid_pdbx_file(const file &file, std::string_view dictionary)
|
||||
{
|
||||
std::error_code ec;
|
||||
bool result = is_valid_pdbx_file(file, dictionary, ec);
|
||||
return result and ec == std::errc();
|
||||
return result and not (bool)ec;
|
||||
}
|
||||
|
||||
bool is_valid_pdbx_file(const file &file, std::error_code &ec)
|
||||
@@ -326,7 +326,7 @@ bool is_valid_pdbx_file(const file &file, std::string_view dictionary, std::erro
|
||||
ec = make_error_code(validation_error::not_valid_pdbx);
|
||||
}
|
||||
|
||||
if (not result and ec == std::errc())
|
||||
if (not result and (bool)ec)
|
||||
ec = make_error_code(validation_error::not_valid_pdbx);
|
||||
|
||||
return result;
|
||||
|
||||
@@ -111,7 +111,7 @@ sym_op::sym_op(std::string_view s)
|
||||
m_tb = r.ptr[2] - '0';
|
||||
m_tc = r.ptr[3] - '0';
|
||||
|
||||
if (r.ec != std::errc() or rnri > 192 or r.ptr[0] != '_' or m_ta > 9 or m_tb > 9 or m_tc > 9)
|
||||
if ((bool)r.ec or rnri > 192 or r.ptr[0] != '_' or m_ta > 9 or m_tb > 9 or m_tc > 9)
|
||||
throw std::invalid_argument("Could not convert string into sym_op");
|
||||
}
|
||||
|
||||
@@ -119,7 +119,7 @@ std::string sym_op::string() const
|
||||
{
|
||||
char b[9];
|
||||
auto r = std::to_chars(b, b + sizeof(b), m_nr);
|
||||
if (r.ec != std::errc() or r.ptr > b + 4)
|
||||
if ((bool)r.ec or r.ptr > b + 4)
|
||||
throw std::runtime_error("Could not write out symmetry operation to string");
|
||||
|
||||
*r.ptr++ = '_';
|
||||
|
||||
@@ -280,7 +280,7 @@ int main(int argc, char* const argv[])
|
||||
if (std::isdigit(line[0])) // start of new spacegroup
|
||||
{
|
||||
auto r = std::from_chars(line.data(), line.data() + line.length(), sgnr);
|
||||
if (r.ec != std::errc())
|
||||
if ((bool)r.ec)
|
||||
throw std::runtime_error("Error parsing symop.lib file");
|
||||
rnr = 1;
|
||||
continue;
|
||||
|
||||
39
src/text.cpp
39
src/text.cpp
@@ -190,22 +190,41 @@ std::string trim_left_copy(std::string_view s)
|
||||
|
||||
void trim_left(std::string &s)
|
||||
{
|
||||
auto b = s.begin();
|
||||
while (b != s.end())
|
||||
auto in = s.begin(), out = s.begin();
|
||||
|
||||
while (in != s.end() and std::isspace(*in))
|
||||
++in;
|
||||
|
||||
if (in == s.end())
|
||||
s.clear();
|
||||
else if (in != out)
|
||||
{
|
||||
if (not std::isspace(*b))
|
||||
break;
|
||||
|
||||
b = std::next(b);
|
||||
while (in != s.end())
|
||||
*out++ = *in++;
|
||||
s.erase(out, s.end());
|
||||
}
|
||||
|
||||
s.erase(s.begin(), b);
|
||||
}
|
||||
|
||||
void trim(std::string &s)
|
||||
{
|
||||
trim_right(s);
|
||||
trim_left(s);
|
||||
auto in = s.begin(), out = s.begin(), end = s.end();
|
||||
|
||||
while (end != s.begin() and std::isspace(*(end - 1)))
|
||||
--end;
|
||||
|
||||
while (in != end and std::isspace(*in))
|
||||
++in;
|
||||
|
||||
if (in == end)
|
||||
s.clear();
|
||||
else if (in != out)
|
||||
{
|
||||
while (in != end)
|
||||
*out++ = *in++;
|
||||
s.erase(out, s.end());
|
||||
}
|
||||
else if (end != s.end())
|
||||
s.erase(end, s.end());
|
||||
}
|
||||
|
||||
std::string trim_copy(std::string_view s)
|
||||
|
||||
@@ -138,7 +138,7 @@ int type_validator::compare(std::string_view a, std::string_view b) const
|
||||
ra = selected_charconv<double>::from_chars(a.data(), a.data() + a.length(), da);
|
||||
rb = selected_charconv<double>::from_chars(b.data(), b.data() + b.length(), db);
|
||||
|
||||
if (ra.ec == std::errc() and rb.ec == std::errc())
|
||||
if (not (bool)ra.ec and not (bool)rb.ec)
|
||||
{
|
||||
auto d = da - db;
|
||||
if (std::abs(d) > std::numeric_limits<double>::epsilon())
|
||||
@@ -149,7 +149,7 @@ int type_validator::compare(std::string_view a, std::string_view b) const
|
||||
result = -1;
|
||||
}
|
||||
}
|
||||
else if (ra.ec == std::errc())
|
||||
else if ((bool)ra.ec)
|
||||
result = 1;
|
||||
else
|
||||
result = -1;
|
||||
@@ -222,7 +222,7 @@ void item_validator::operator()(std::string_view value) const
|
||||
|
||||
bool item_validator::validate_value(std::string_view value, std::error_code &ec) const noexcept
|
||||
{
|
||||
ec = {};
|
||||
ec.clear();
|
||||
|
||||
if (not value.empty() and value != "?" and value != ".")
|
||||
{
|
||||
@@ -232,7 +232,7 @@ bool item_validator::validate_value(std::string_view value, std::error_code &ec)
|
||||
ec = make_error_code(validation_error::value_is_not_in_enumeration_list);
|
||||
}
|
||||
|
||||
return ec == std::errc();
|
||||
return not (bool)ec;
|
||||
}
|
||||
|
||||
// --------------------------------------------------------------------
|
||||
|
||||
@@ -23,7 +23,7 @@ list(
|
||||
rename-compound
|
||||
sugar
|
||||
spinner
|
||||
reconstruction
|
||||
# reconstruction
|
||||
validate-pdbx)
|
||||
|
||||
add_library(test-main OBJECT "${CMAKE_CURRENT_SOURCE_DIR}/test-main.cpp")
|
||||
|
||||
@@ -54,7 +54,7 @@ TEST_CASE("reconstruct")
|
||||
|
||||
std::error_code ec;
|
||||
CHECK_FALSE(cif::pdb::is_valid_pdbx_file(f, ec));
|
||||
CHECK(ec != std::errc{});
|
||||
CHECK((bool)ec);
|
||||
|
||||
CHECK(cif::pdb::reconstruct_pdbx(f));
|
||||
}
|
||||
|
||||
@@ -101,7 +101,7 @@ TEST_CASE("cc_1")
|
||||
float tv;
|
||||
const auto &[ptr, ec] = cif::from_chars(txt.data(), txt.data() + txt.length(), tv);
|
||||
|
||||
REQUIRE(ec == std::errc());
|
||||
CHECK_FALSE((bool)ec);
|
||||
REQUIRE(tv == val);
|
||||
if (ch != 0)
|
||||
REQUIRE(*ptr == ch);
|
||||
@@ -119,7 +119,7 @@ TEST_CASE("cc_2")
|
||||
char buffer[64];
|
||||
const auto &[ptr, ec] = cif::to_chars(buffer, buffer + sizeof(buffer), val, cif::chars_format::fixed, prec);
|
||||
|
||||
REQUIRE(ec == std::errc());
|
||||
CHECK_FALSE((bool)ec);
|
||||
|
||||
REQUIRE(buffer == test);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user