Compare commits

...

61 Commits

Author SHA1 Message Date
Maarten L. Hekkelman
ac98531a2f Fix writing exports file, version bump 2024-03-12 12:55:59 +01:00
Maarten L. Hekkelman
917e0ba79c Merge branch 'develop' of github.com:pdb-redo/libcifpp into develop 2024-03-12 10:12:55 +01:00
Maarten L. Hekkelman
3ebceb7522 do not number non-polymer residues 2024-03-12 10:12:50 +01:00
Maarten L. Hekkelman
92bd52da12 get that code compiling 2024-03-09 14:13:37 +01:00
Maarten L. Hekkelman
fb56a9cd6e version bump 2024-03-09 14:03:45 +01:00
Maarten L. Hekkelman
a4680f7d38 error_code should be checked differently? 2024-03-09 13:54:53 +01:00
Maarten L. Hekkelman
da8a72a8aa Merge branch 'develop' into trunk 2024-03-06 16:50:33 +01:00
Maarten L. Hekkelman
ac497932b5 Fix loading embedded restraint data 2024-03-06 16:50:12 +01:00
Maarten L. Hekkelman
9927b5061a Merge branch 'develop' of github.com:PDB-REDO/libcifpp into develop 2024-03-06 16:21:15 +01:00
Maarten L. Hekkelman
cedaab9642 load compound info from appended restraint info 2024-03-06 16:20:43 +01:00
Maarten L. Hekkelman
50bf2145ec Merge branch 'develop' into trunk 2024-03-06 15:54:56 +01:00
Maarten L. Hekkelman
dc77729f50 update changelog 2024-03-06 15:48:17 +01:00
Maarten L. Hekkelman
e3330d667a formatting 2024-03-06 13:22:00 +01:00
Maarten L. Hekkelman
9822f397a1 update libcifpp makefile 2024-03-06 12:58:50 +01:00
Maarten L. Hekkelman
a3b5ce9959 loading extra compound info changed
cif::file constructors
2024-03-06 12:33:58 +01:00
Maarten L. Hekkelman
9eb06e929a fixes in iterators 2024-03-05 15:52:36 +01:00
Maarten L. Hekkelman
629e06d647 write uncoloured text 2024-03-05 15:22:05 +01:00
Maarten L. Hekkelman
51ccb92184 small changes in constructors 2024-03-05 13:41:05 +01:00
Maarten L. Hekkelman
3cd27f13fd calculate formula_weight when missing 2024-03-05 13:02:31 +01:00
Maarten L. Hekkelman
ae668530c0 do not install files if they are not downloaded 2024-03-05 11:40:33 +01:00
Maarten L. Hekkelman
4a8b1c056c do not install files if they are not downloaded 2024-03-05 11:39:45 +01:00
Maarten L. Hekkelman
d7a5e598bc Merge branch 'develop' of github.com:pdb-redo/libcifpp into develop 2024-03-05 11:33:25 +01:00
Maarten L. Hekkelman
3f1ee32cc6 better trim 2024-03-05 11:33:19 +01:00
Maarten L. Hekkelman
725d6ead98 stupid typo 2024-02-29 14:56:45 +01:00
Maarten L. Hekkelman
baf70579de version bump 2024-02-27 15:23:51 +01:00
Maarten L. Hekkelman
cd28ab58a3 typo in error message 2024-02-27 14:40:56 +01:00
Maarten L. Hekkelman
a78fa0a81d reconstruction fixes 2024-02-27 13:36:45 +01:00
Maarten L. Hekkelman
82130be5f5 oops 2024-02-27 13:29:38 +01:00
Maarten L. Hekkelman
510ce62dfb reconstruction fixes 2024-02-27 13:24:53 +01:00
Maarten L. Hekkelman
be738e7fb1 catch22 2024-02-17 15:37:53 +01:00
Maarten L. Hekkelman
9c78131df3 Use Catch2 version 3 if installed 2024-02-17 15:20:11 +01:00
Maarten L. Hekkelman
d94f6f4d19 test builds faster now 2024-02-05 13:01:28 +01:00
Maarten L. Hekkelman
9a3eced350 new update_value in category 2024-01-31 16:20:49 +01:00
Maarten L. Hekkelman
2fed7a76fb Fix operator= for item_handle 2024-01-30 16:51:12 +01:00
Maarten L. Hekkelman
f02e59df1b Fix operator= for item_handle 2024-01-30 16:40:02 +01:00
Maarten L. Hekkelman
04147a2fe9 Fix url in compound message 2024-01-30 16:39:32 +01:00
Maarten L. Hekkelman
0e83bc31dc some small optimisations 2024-01-30 16:29:22 +01:00
Maarten L. Hekkelman
75a5f7960f formatting 2024-01-30 11:12:29 +01:00
Maarten L. Hekkelman
3f93c27b07 fix reconstruct sequence 2024-01-29 17:40:24 +01:00
Maarten L. Hekkelman
ab781d4516 work around bug in old gcc 2024-01-29 16:33:53 +01:00
Maarten L. Hekkelman
446438bf8c Fixing pdb2cif, and sequence checking 2024-01-29 16:12:01 +01:00
Maarten L. Hekkelman
4e012cbd48 gcc diagnostics and clipper 2024-01-29 16:11:08 +01:00
Maarten L. Hekkelman
12ee4a792c pdb2cif work 2024-01-29 13:00:50 +01:00
Maarten L. Hekkelman
e59750386f - changed compound::is_known_peptide/is_know_base
- Add audit_conform only if file is really valid
- Added reconstruction code for PDBx
2024-01-24 16:14:08 +01:00
Maarten L. Hekkelman
4e19d54867 atom_site_anisotrop check 2024-01-23 14:08:25 +01:00
Maarten L. Hekkelman
db603e5438 version bump 2024-01-23 11:57:29 +01:00
Maarten L. Hekkelman
5320cb123a Fix validate pdbx 2024-01-23 11:57:21 +01:00
Maarten L. Hekkelman
30a2ebdbb4 Merge remote-tracking branch 'github/develop-cif2fasta' into develop 2024-01-23 11:42:12 +01:00
Maarten L. Hekkelman
a5d43998a3 replace tag with item or item_name 2024-01-23 11:41:13 +01:00
Maarten L. Hekkelman
2792caec70 renaming field and column to item 2024-01-23 11:23:20 +01:00
Maarten L. Hekkelman
fb2b1e984c Fixed serious bug in emplace of both datablock and file. 2024-01-22 16:04:57 +01:00
Maarten L. Hekkelman
13ab1caf95 macOS... 2024-01-22 15:33:43 +01:00
Maarten L. Hekkelman
5d4534fac4 Added rename_column
Added item_alias
Rename columns in reconstruct
2024-01-22 15:15:11 +01:00
Maarten L. Hekkelman
f450643861 Added remove column 2024-01-22 14:03:22 +01:00
Maarten L. Hekkelman
fc14a65511 attempt 2 to build on macOS 2024-01-22 13:08:25 +01:00
Maarten L. Hekkelman
bbd1e27c5e Attempt to get code compiling on macOS 2024-01-22 12:49:11 +01:00
Maarten L. Hekkelman
369a83b718 Version bump 2024-01-22 12:00:38 +01:00
Maarten L. Hekkelman
afc541b956 Merge remote-tracking branch 'github/develop-cif2fasta' into develop 2024-01-22 12:00:11 +01:00
Maarten L. Hekkelman
7e4d2ffb4d formatting data in reconstruction 2024-01-22 11:43:56 +01:00
Maarten L. Hekkelman
e09913a94f - checking and optionally dropping ndb_poly_seq_scheme
- fix in iterator_proxy
2024-01-22 11:18:00 +01:00
Maarten L. Hekkelman
b4d1c4cc04 - renamed exists to contains
- fix compare for ints where item is empty
2024-01-17 16:31:18 +01:00
27 changed files with 540 additions and 458 deletions

View File

@@ -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

View File

@@ -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.

View File

@@ -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;
};

View File

@@ -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));
}
// --------------------------------------------------------------------
/**

View File

@@ -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 */
/**

View File

@@ -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)
{

View File

@@ -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;
};

View File

@@ -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;
}

View File

@@ -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;

View File

@@ -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)

View File

@@ -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);
}
// --------------------------------------------------------------------

View File

@@ -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:

View File

@@ -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;

View File

@@ -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;

View File

@@ -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;

View File

@@ -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;

View File

@@ -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";

View File

@@ -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?

View File

@@ -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);

View File

@@ -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;

View File

@@ -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++ = '_';

View File

@@ -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;

View File

@@ -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)

View File

@@ -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;
}
// --------------------------------------------------------------------

View File

@@ -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")

View File

@@ -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));
}

View File

@@ -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);
}