mirror of
https://github.com/PDB-REDO/libcifpp.git
synced 2026-06-04 13:54:25 +08:00
a start
This commit is contained in:
@@ -249,28 +249,28 @@ write_version_header("${CMAKE_CURRENT_SOURCE_DIR}/src/" LIB_NAME "LibCIFPP")
|
||||
# Sources
|
||||
set(project_sources
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/src/category.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/src/condition.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/src/datablock.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/src/dictionary_parser.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/src/file.cpp
|
||||
# ${CMAKE_CURRENT_SOURCE_DIR}/src/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/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
|
||||
# ${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
|
||||
|
||||
@@ -28,12 +28,13 @@
|
||||
|
||||
#include "cif++/forward_decl.hpp"
|
||||
|
||||
#include "cif++/condition.hpp"
|
||||
// #include "cif++/condition.hpp"
|
||||
#include "cif++/iterator.hpp"
|
||||
#include "cif++/row.hpp"
|
||||
#include "cif++/text.hpp"
|
||||
|
||||
#include <array>
|
||||
// #include <array>
|
||||
#include <functional>
|
||||
|
||||
/** \file category.hpp
|
||||
* Documentation for the cif::category class
|
||||
@@ -181,12 +182,8 @@ class category
|
||||
|
||||
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
|
||||
|
||||
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.
|
||||
|
||||
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
|
||||
@@ -961,7 +958,7 @@ class category
|
||||
for (auto i = b; i != e; ++i)
|
||||
{
|
||||
// item_value *new_item = this->create_item(*i);
|
||||
r->append(add_item(i->name()), { i->value() });
|
||||
r->append(add_item(i->name()), i->value());
|
||||
}
|
||||
}
|
||||
catch (...)
|
||||
@@ -1055,60 +1052,6 @@ class category
|
||||
{ return value; });
|
||||
}
|
||||
|
||||
// --------------------------------------------------------------------
|
||||
// Naming used to be very inconsistent. For backward compatibility,
|
||||
// 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
|
||||
{
|
||||
return get_item_ix(column_name);
|
||||
}
|
||||
|
||||
/// @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
|
||||
{
|
||||
return get_item_name(ix);
|
||||
}
|
||||
|
||||
/// @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)
|
||||
{
|
||||
return add_item(item_name);
|
||||
}
|
||||
|
||||
/** @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)
|
||||
{
|
||||
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)
|
||||
{
|
||||
rename_item(from_name, to_name);
|
||||
}
|
||||
|
||||
/// @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
|
||||
{
|
||||
return has_item(name);
|
||||
}
|
||||
|
||||
/// @brief Return the cif::iset of columns in this category
|
||||
[[deprecated("use get_items instead")]] iset get_columns() const
|
||||
{
|
||||
return get_items();
|
||||
}
|
||||
|
||||
// --------------------------------------------------------------------
|
||||
/// \brief Return the index number for \a item_name
|
||||
|
||||
@@ -1117,7 +1060,7 @@ class category
|
||||
/// @brief Return the name for item with index @a ix
|
||||
/// @param ix The index number
|
||||
/// @return The name of the item
|
||||
std::string_view get_item_name(uint16_t ix) const
|
||||
const std::string &get_item_name(uint16_t ix) const
|
||||
{
|
||||
if (ix >= m_items.size())
|
||||
throw std::out_of_range("item index is out of range");
|
||||
@@ -1200,7 +1143,7 @@ class category
|
||||
}
|
||||
|
||||
private:
|
||||
void update_value(row *row, uint16_t item, std::string_view value, bool updateLinked, bool validate = true);
|
||||
void update_value(row *row, uint16_t item, item_value value, bool updateLinked, bool validate = true);
|
||||
|
||||
void erase_orphans(condition &&cond, category &parent);
|
||||
|
||||
|
||||
@@ -371,7 +371,7 @@ namespace detail
|
||||
{
|
||||
key_equals_condition_impl(item &&i)
|
||||
: m_item_name(i.name())
|
||||
, m_value(std::forward<item>(i).value())
|
||||
, m_value(std::forward<item_value>(i.value()))
|
||||
{
|
||||
}
|
||||
|
||||
@@ -409,7 +409,7 @@ namespace detail
|
||||
std::string m_item_name;
|
||||
uint16_t m_item_ix = 0;
|
||||
bool m_icase = false;
|
||||
std::string m_value;
|
||||
item_value m_value;
|
||||
std::optional<row_handle> m_single_hit;
|
||||
};
|
||||
|
||||
@@ -466,7 +466,7 @@ namespace detail
|
||||
|
||||
std::string m_item_name;
|
||||
uint16_t m_item_ix = 0;
|
||||
std::string m_value;
|
||||
item_value &m_value;
|
||||
bool m_icase = false;
|
||||
std::optional<row_handle> m_single_hit;
|
||||
};
|
||||
|
||||
@@ -93,7 +93,7 @@ enum class item_value_type
|
||||
FLOAT,
|
||||
TEXT,
|
||||
MISSING,
|
||||
EMPTY
|
||||
EMPTY // This is the real NULL in SQL terms
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
@@ -136,20 +136,37 @@ class item_value
|
||||
|
||||
item_value(std::nullptr_t)
|
||||
{
|
||||
m_data.m_type = item_value_type::MISSING;
|
||||
m_data.m_type = item_value_type::EMPTY;
|
||||
}
|
||||
|
||||
item_value(bool v)
|
||||
template <BooleanType T>
|
||||
item_value(T v)
|
||||
{
|
||||
m_data.m_type = item_value_type::BOOLEAN;
|
||||
m_data.m_value = v;
|
||||
}
|
||||
|
||||
template <StringType T>
|
||||
item_value(const T &s)
|
||||
item_value(std::string_view s)
|
||||
{
|
||||
m_data.m_type = item_value_type::TEXT;
|
||||
m_data.m_value = std::string_view{ s };
|
||||
m_data.m_len = s.length();
|
||||
m_data.m_value = s;
|
||||
}
|
||||
|
||||
template <size_t N>
|
||||
item_value(const char(s)[N])
|
||||
: item_value(std::string_view{ s, N })
|
||||
{
|
||||
}
|
||||
|
||||
item_value(const char *s)
|
||||
: item_value(std::string_view{ s })
|
||||
{
|
||||
}
|
||||
|
||||
item_value(const std::string &s)
|
||||
: item_value(std::string_view{ s })
|
||||
{
|
||||
}
|
||||
|
||||
template <IntegralType T>
|
||||
@@ -167,6 +184,12 @@ class item_value
|
||||
m_data.m_len = precision;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
item_value(std::optional<T> v)
|
||||
: item_value(v.has_value() ? *v : nullptr)
|
||||
{
|
||||
}
|
||||
|
||||
item_value(item_value &&rhs) noexcept
|
||||
{
|
||||
swap(*this, rhs);
|
||||
@@ -195,12 +218,12 @@ class item_value
|
||||
bool result;
|
||||
switch (m_data.m_type)
|
||||
{
|
||||
case cif::item_value_type::BOOLEAN: result = m_data.m_value.m_boolean; break;
|
||||
case item_value_type::MISSING: result = false; break;
|
||||
case item_value_type::EMPTY: result = false; break;
|
||||
case item_value_type::BOOLEAN: result = m_data.m_value.m_boolean; break;
|
||||
case item_value_type::INT: result = m_data.m_value.m_integer != 0; break;
|
||||
case item_value_type::FLOAT: result = m_data.m_value.m_float != 0; break;
|
||||
case item_value_type::TEXT: result = m_data.m_len != 0; break;
|
||||
case item_value_type::MISSING:
|
||||
case item_value_type::EMPTY: result = false; break;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
@@ -305,6 +328,24 @@ class item_value
|
||||
}
|
||||
}
|
||||
|
||||
template <BooleanType T>
|
||||
std::remove_cvref_t<T> get() const
|
||||
{
|
||||
switch (m_data.m_type)
|
||||
{
|
||||
case cif::item_value_type::BOOLEAN:
|
||||
return m_data.m_value.m_boolean;
|
||||
case item_value_type::INT:
|
||||
return m_data.m_value.m_integer != 0;
|
||||
case item_value_type::FLOAT:
|
||||
return m_data.m_value.m_float != 0.;
|
||||
case item_value_type::TEXT:
|
||||
return iequals(m_data.sv(), "y") or iequals(m_data.sv(), "yes") or iequals(m_data.sv(), "true");
|
||||
default:
|
||||
return not empty();
|
||||
}
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
std::optional<T> get() const
|
||||
{
|
||||
@@ -329,26 +370,46 @@ class item_value
|
||||
}
|
||||
|
||||
// --------------------------------------------------------------------
|
||||
std::partial_ordering operator<=>(const item_value &rhs) const
|
||||
// std::partial_ordering operator<=>(const item_value &rhs) const
|
||||
// {
|
||||
// if (m_data.m_type == rhs.m_data.m_type)
|
||||
// {
|
||||
// switch (m_data.m_type)
|
||||
// {
|
||||
// case item_value_type::BOOLEAN: return m_data.m_value.m_boolean <=> rhs.m_data.m_value.m_boolean;
|
||||
// case item_value_type::INT: return m_data.m_value.m_integer <=> rhs.m_data.m_value.m_integer;
|
||||
// case item_value_type::FLOAT: return m_data.m_value.m_float <=> rhs.m_data.m_value.m_float;
|
||||
// case item_value_type::TEXT: return m_data.sv() <=> rhs.m_data.sv();
|
||||
// case item_value_type::MISSING:
|
||||
// case item_value_type::EMPTY: return std::strong_ordering::equivalent;
|
||||
// }
|
||||
// }
|
||||
// else
|
||||
// return m_data.m_type <=> rhs.m_data.m_type;
|
||||
// }
|
||||
|
||||
bool operator==(const item_value &rhs) const
|
||||
{
|
||||
if (m_data.m_type == rhs.m_data.m_type)
|
||||
{
|
||||
switch (m_data.m_type)
|
||||
{
|
||||
case item_value_type::MISSING: return std::strong_ordering::equivalent;
|
||||
case item_value_type::EMPTY: return std::strong_ordering::equivalent;
|
||||
case item_value_type::BOOLEAN: return m_data.m_value.m_boolean <=> rhs.m_data.m_value.m_boolean;
|
||||
case item_value_type::INT: return m_data.m_value.m_integer <=> rhs.m_data.m_value.m_integer;
|
||||
case item_value_type::FLOAT: return m_data.m_value.m_float <=> rhs.m_data.m_value.m_float;
|
||||
case item_value_type::TEXT: return m_data.sv() <=> rhs.m_data.sv();
|
||||
case item_value_type::BOOLEAN: return m_data.m_value.m_boolean == rhs.m_data.m_value.m_boolean;
|
||||
case item_value_type::INT: return m_data.m_value.m_integer == rhs.m_data.m_value.m_integer;
|
||||
case item_value_type::FLOAT: return m_data.m_value.m_float == rhs.m_data.m_value.m_float;
|
||||
case item_value_type::TEXT: return m_data.sv() == rhs.m_data.sv();
|
||||
case item_value_type::MISSING:
|
||||
case item_value_type::EMPTY: return true;
|
||||
}
|
||||
}
|
||||
else
|
||||
return m_data.m_type <=> rhs.m_data.m_type;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
int compare(const item_value &b, bool ignore_case = false) const noexcept;
|
||||
|
||||
friend std::ostream operator<<(std::ostream &os, const item_value &v);
|
||||
|
||||
private:
|
||||
union value
|
||||
{
|
||||
@@ -447,88 +508,102 @@ class item
|
||||
|
||||
/// \brief constructor for an item with name \a name and as
|
||||
/// content the character '.', i.e. an inapplicable value.
|
||||
item(std::string_view name)
|
||||
: m_name(name)
|
||||
item(std::string name)
|
||||
: m_name(std::move(name))
|
||||
, m_value(item_value_type::EMPTY)
|
||||
{
|
||||
}
|
||||
|
||||
/// \brief constructor for an item with name \a name and as
|
||||
/// content a single character string with content \a value
|
||||
item(std::string_view name, char value)
|
||||
: m_name(name)
|
||||
, m_value(std::string_view{ &value, 1 })
|
||||
item(std::string name, item_value value)
|
||||
: m_name(std::move(name))
|
||||
, m_value(std::move(value))
|
||||
{
|
||||
}
|
||||
|
||||
/// \brief constructor for an item with name \a name and as
|
||||
/// content the formatted floating point value \a value
|
||||
template <FloatType T>
|
||||
item(std::string_view name, T value)
|
||||
: m_name(name)
|
||||
, m_value(value)
|
||||
{
|
||||
}
|
||||
// /// \brief constructor for an item with name \a name and as
|
||||
// /// content the character '.', i.e. an inapplicable value.
|
||||
// item(std::string_view name, std::nullptr_t)
|
||||
// : m_name(name)
|
||||
// , m_value(item_value_type::EMPTY)
|
||||
// {
|
||||
// }
|
||||
|
||||
/// \brief constructor for an item with name \a name and as
|
||||
/// content the formatted floating point value \a value with
|
||||
/// precision \a precision
|
||||
template <FloatType T>
|
||||
item(std::string_view name, T value, int precision)
|
||||
: m_name(name)
|
||||
, m_value(value, precision)
|
||||
{
|
||||
}
|
||||
// /// \brief constructor for an item with name \a name and as
|
||||
// /// content a single character string with content \a value
|
||||
// item(std::string_view name, char value)
|
||||
// : m_name(name)
|
||||
// , m_value(std::string_view{ &value, 1 })
|
||||
// {
|
||||
// }
|
||||
|
||||
/// \brief constructor for an item with name \a name and as
|
||||
/// content the formatted integral value \a value
|
||||
template <IntegralType T>
|
||||
item(const std::string_view name, T value)
|
||||
: m_name(name)
|
||||
, m_value(value)
|
||||
{
|
||||
}
|
||||
// /// \brief constructor for an item with name \a name and as
|
||||
// /// content the formatted floating point value \a value
|
||||
// template <FloatType T>
|
||||
// item(std::string_view name, T value)
|
||||
// : m_name(name)
|
||||
// , m_value(value)
|
||||
// {
|
||||
// }
|
||||
|
||||
// TODO: Perhaps introduce a real boolean type?
|
||||
/// \brief constructor for an item with name \a name and as
|
||||
/// content the formatted boolean value \a value
|
||||
template <BooleanType T>
|
||||
item(const std::string_view name, T value)
|
||||
: m_name(name)
|
||||
, m_value(value)
|
||||
{
|
||||
}
|
||||
// /// \brief constructor for an item with name \a name and as
|
||||
// /// content the formatted floating point value \a value with
|
||||
// /// precision \a precision
|
||||
// template <FloatType T>
|
||||
// item(std::string_view name, T value, int precision)
|
||||
// : m_name(name)
|
||||
// , m_value(value, precision)
|
||||
// {
|
||||
// }
|
||||
|
||||
/// \brief constructor for an item with name \a name and as
|
||||
/// content value \a value
|
||||
item(const std::string_view name, std::string_view value)
|
||||
: m_name(name)
|
||||
, m_value(value)
|
||||
{
|
||||
}
|
||||
// /// \brief constructor for an item with name \a name and as
|
||||
// /// content the formatted integral value \a value
|
||||
// template <IntegralType T>
|
||||
// item(const std::string_view name, T value)
|
||||
// : m_name(name)
|
||||
// , m_value(value)
|
||||
// {
|
||||
// }
|
||||
|
||||
/// \brief constructor for an item with name \a name and as
|
||||
/// content the optional value \a value
|
||||
template <typename T>
|
||||
item(const std::string_view name, const std::optional<T> &value)
|
||||
: m_name(name)
|
||||
, m_value(item_value_type::MISSING)
|
||||
{
|
||||
if (value.has_value())
|
||||
m_value = *value;
|
||||
}
|
||||
// // TODO: Perhaps introduce a real boolean type?
|
||||
// /// \brief constructor for an item with name \a name and as
|
||||
// /// content the formatted boolean value \a value
|
||||
// template <BooleanType T>
|
||||
// item(const std::string_view name, T value)
|
||||
// : m_name(name)
|
||||
// , m_value(value)
|
||||
// {
|
||||
// }
|
||||
|
||||
/// \brief constructor for an item with name \a name and as
|
||||
/// content the formatted floating point value \a value with
|
||||
/// precision \a precision
|
||||
template <typename T, std::enable_if_t<std::is_floating_point_v<T>, int> = 0>
|
||||
item(std::string_view name, const std::optional<T> &value, int precision)
|
||||
: m_name(name)
|
||||
, m_value(item_value_type::MISSING)
|
||||
{
|
||||
if (value.has_value())
|
||||
m_value = item_value(*value, precision);
|
||||
}
|
||||
// /// \brief constructor for an item with name \a name and as
|
||||
// /// content value \a value
|
||||
// item(const std::string_view name, std::string_view value)
|
||||
// : m_name(name)
|
||||
// , m_value(value)
|
||||
// {
|
||||
// }
|
||||
|
||||
// /// \brief constructor for an item with name \a name and as
|
||||
// /// content the optional value \a value
|
||||
// template <typename T>
|
||||
// item(const std::string_view name, const std::optional<T> &value)
|
||||
// : m_name(name)
|
||||
// , m_value(item_value_type::MISSING)
|
||||
// {
|
||||
// if (value.has_value())
|
||||
// m_value = *value;
|
||||
// }
|
||||
|
||||
// /// \brief constructor for an item with name \a name and as
|
||||
// /// content the formatted floating point value \a value with
|
||||
// /// precision \a precision
|
||||
// template <typename T, std::enable_if_t<std::is_floating_point_v<T>, int> = 0>
|
||||
// item(std::string_view name, const std::optional<T> &value, int precision)
|
||||
// : m_name(name)
|
||||
// , m_value(item_value_type::MISSING)
|
||||
// {
|
||||
// if (value.has_value())
|
||||
// m_value = item_value(*value, precision);
|
||||
// }
|
||||
|
||||
/** @cond */
|
||||
item(const item &rhs) = default;
|
||||
@@ -537,11 +612,12 @@ class item
|
||||
item &operator=(item &&rhs) noexcept = default;
|
||||
/** @endcond */
|
||||
|
||||
std::string_view name() const { return m_name; } ///< Return the name of the item
|
||||
std::string value() const & { return m_value.get<std::string>(); } ///< Return the value of the item
|
||||
const std::string &name() const { return m_name; } ///< Return the name of the item
|
||||
const item_value &value() const & { return m_value; } ///< Return the value of the item
|
||||
item_value &value() & { return m_value; } ///< Return the value of the item
|
||||
|
||||
/// \brief replace the content of the stored value with \a v
|
||||
void value(const item_value &v) { m_value = v; }
|
||||
void value(item_value v) { m_value = std::move(v); }
|
||||
|
||||
/// \brief empty means either null or unknown
|
||||
bool empty() const { return m_value.empty(); }
|
||||
@@ -568,7 +644,7 @@ class item
|
||||
auto operator<=>(const item &rhs) const = default;
|
||||
|
||||
private:
|
||||
std::string_view m_name;
|
||||
std::string m_name;
|
||||
item_value m_value;
|
||||
};
|
||||
|
||||
@@ -657,7 +733,6 @@ class item
|
||||
// }
|
||||
// };
|
||||
|
||||
|
||||
// // --------------------------------------------------------------------
|
||||
// // Transient object to access stored data
|
||||
|
||||
|
||||
@@ -26,6 +26,7 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "cif++/condition.hpp"
|
||||
#include "cif++/row.hpp"
|
||||
|
||||
#include <array>
|
||||
|
||||
@@ -262,7 +262,7 @@ class sac_parser
|
||||
virtual void produce_datablock(std::string_view name) = 0;
|
||||
virtual void produce_category(std::string_view name) = 0;
|
||||
virtual void produce_row() = 0;
|
||||
virtual void produce_item(std::string_view category, std::string_view item, std::string_view value) = 0;
|
||||
virtual void produce_item(std::string_view category, std::string_view item, item_value value) = 0;
|
||||
|
||||
protected:
|
||||
|
||||
@@ -331,7 +331,7 @@ class parser : public sac_parser
|
||||
|
||||
void produce_row() override;
|
||||
|
||||
void produce_item(std::string_view category, std::string_view item, std::string_view value) override;
|
||||
void produce_item(std::string_view category, std::string_view item, item_value value) override;
|
||||
|
||||
protected:
|
||||
file &m_file;
|
||||
|
||||
@@ -173,14 +173,14 @@ class row : public std::vector<item_value>
|
||||
return ix < size() ? &data()[ix] : nullptr;
|
||||
}
|
||||
|
||||
private:
|
||||
// private:
|
||||
friend class category;
|
||||
friend class category_index;
|
||||
|
||||
template <typename, typename...>
|
||||
friend class iterator_impl;
|
||||
|
||||
void append(uint16_t ix, item_value &&iv)
|
||||
void append(uint16_t ix, item_value iv)
|
||||
{
|
||||
if (ix >= size())
|
||||
resize(ix + 1);
|
||||
@@ -303,9 +303,9 @@ class row_handle
|
||||
* checked to see if it conforms to the rules defined in the dictionary
|
||||
*/
|
||||
|
||||
void assign(std::string_view name, std::string_view value, bool updateLinked, bool validate = true)
|
||||
void assign(std::string_view name, item_value value, bool updateLinked, bool validate = true)
|
||||
{
|
||||
assign(add_item(name), value, updateLinked, validate);
|
||||
assign(add_item(name), std::move(value), updateLinked, validate);
|
||||
}
|
||||
|
||||
/** \brief assign the value @a value to item at index @a item
|
||||
@@ -319,7 +319,7 @@ class row_handle
|
||||
* checked to see if it conforms to the rules defined in the dictionary
|
||||
*/
|
||||
|
||||
void assign(uint16_t item, std::string_view value, bool updateLinked, bool validate = true);
|
||||
void assign(uint16_t item, item_value value, bool updateLinked, bool validate = true);
|
||||
|
||||
/// \brief compare two rows
|
||||
bool operator==(const row_handle &rhs) const { return m_category == rhs.m_category and m_row == rhs.m_row; }
|
||||
@@ -343,10 +343,10 @@ class row_handle
|
||||
return m_row;
|
||||
}
|
||||
|
||||
void assign(const item &i, bool updateLinked)
|
||||
void assign(const item &i, bool updateLinked);/*
|
||||
{
|
||||
assign(i.name(), i.value(), updateLinked);
|
||||
}
|
||||
} */
|
||||
|
||||
void swap(uint16_t item, row_handle &r);
|
||||
|
||||
@@ -395,7 +395,7 @@ class row_initializer : public std::vector<item>
|
||||
|
||||
|
||||
/// \brief set the value for item name @a name to @a value
|
||||
void set_value(std::string_view name, std::string_view value);
|
||||
void set_value(std::string name, item_value value);
|
||||
|
||||
/// \brief set the value for item based on @a i
|
||||
void set_value(const item &i)
|
||||
@@ -404,7 +404,7 @@ class row_initializer : public std::vector<item>
|
||||
}
|
||||
|
||||
/// \brief set the value for item name @a name to @a value, but only if the item did not have a value already
|
||||
void set_value_if_empty(std::string_view name, std::string_view value);
|
||||
void set_value_if_empty(std::string name, item_value value);
|
||||
|
||||
/// \brief set the value for item @a i, but only if the item did not have a value already
|
||||
void set_value_if_empty(const item &i)
|
||||
|
||||
3983
src/category.cpp
3983
src/category.cpp
File diff suppressed because it is too large
Load Diff
@@ -864,7 +864,7 @@ void parser::produce_row()
|
||||
// m_row.lineNr(m_line_nr);
|
||||
}
|
||||
|
||||
void parser::produce_item(std::string_view category, std::string_view item, std::string_view value)
|
||||
void parser::produce_item(std::string_view category, std::string_view item, item_value value)
|
||||
{
|
||||
if (VERBOSE >= 4)
|
||||
std::cerr << "producing _" << category << '.' << item << " -> " << value << '\n';
|
||||
@@ -872,7 +872,7 @@ void parser::produce_item(std::string_view category, std::string_view item, std:
|
||||
if (m_category == nullptr or not iequals(category, m_category->name()))
|
||||
error("inconsistent categories in loop_");
|
||||
|
||||
m_row[item] = m_token_value;
|
||||
m_row[item] = std::move(value);
|
||||
}
|
||||
|
||||
} // namespace cif
|
||||
|
||||
45
src/row.cpp
45
src/row.cpp
@@ -24,17 +24,45 @@
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include "cif++/row.hpp"
|
||||
|
||||
#include "cif++/category.hpp"
|
||||
#include "cif++/item.hpp"
|
||||
|
||||
namespace cif
|
||||
{
|
||||
// --------------------------------------------------------------------
|
||||
|
||||
void row_handle::assign(uint16_t item, std::string_view value, bool updateLinked, bool validate)
|
||||
item_value s_null_item;
|
||||
|
||||
item_value &row_handle::operator[](uint16_t item_ix)
|
||||
{
|
||||
return empty() or item_ix >= m_row->size() ? s_null_item : m_row->operator[](item_ix);
|
||||
}
|
||||
|
||||
const item_value &row_handle::operator[](uint16_t item_ix) const
|
||||
{
|
||||
return empty() or item_ix >= m_row->size() ? s_null_item : m_row->operator[](item_ix);
|
||||
}
|
||||
|
||||
item_value &row_handle::operator[](std::string_view item_name)
|
||||
{
|
||||
return operator[](get_item_ix(item_name));
|
||||
}
|
||||
|
||||
const item_value &row_handle::operator[](std::string_view item_name) const
|
||||
{
|
||||
return operator[](get_item_ix(item_name));
|
||||
}
|
||||
|
||||
// --------------------------------------------------------------------
|
||||
|
||||
void row_handle::assign(uint16_t item, item_value value, bool updateLinked, bool validate)
|
||||
{
|
||||
if (not m_category)
|
||||
throw std::runtime_error("uninitialized row");
|
||||
|
||||
m_category->update_value(m_row, item, value, updateLinked, validate);
|
||||
m_category->update_value(m_row, item, std::move(value), updateLinked, validate);
|
||||
}
|
||||
|
||||
uint16_t row_handle::get_item_ix(std::string_view name) const
|
||||
@@ -90,24 +118,25 @@ row_initializer::row_initializer(row_handle rh)
|
||||
}
|
||||
}
|
||||
|
||||
void row_initializer::set_value(std::string_view name, std::string_view value)
|
||||
void row_initializer::set_value(std::string name, item_value value)
|
||||
{
|
||||
for (auto &i : *this)
|
||||
{
|
||||
if (i.name() == name)
|
||||
{
|
||||
i.value(value);
|
||||
i.value(std::move(value));
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
emplace_back(name, value);
|
||||
emplace_back(std::move(name), std::move(value));
|
||||
}
|
||||
|
||||
void row_initializer::set_value_if_empty(std::string_view name, std::string_view value)
|
||||
void row_initializer::set_value_if_empty(std::string name, item_value value)
|
||||
{
|
||||
if (find_if(begin(), end(), [name](auto &i) { return i.name() == name; }) == end())
|
||||
emplace_back(name, value);
|
||||
if (std::ranges::find_if(*this, [name](auto &i)
|
||||
{ return i.name() == name; }) == end())
|
||||
emplace_back(std::move(name), std::move(value));
|
||||
}
|
||||
|
||||
} // namespace cif
|
||||
@@ -263,7 +263,7 @@ int type_validator::compare(std::string_view a, std::string_view b) const
|
||||
|
||||
// --------------------------------------------------------------------
|
||||
|
||||
void item_validator::operator()(std::string_view value) const
|
||||
void item_validator::operator()(const item_value &value) const
|
||||
{
|
||||
std::error_code ec;
|
||||
if (not validate_value(value, ec))
|
||||
|
||||
@@ -41,15 +41,15 @@ list(
|
||||
APPEND
|
||||
CIFPP_tests
|
||||
unit-v2
|
||||
unit-3d
|
||||
model
|
||||
query
|
||||
rename-compound
|
||||
sugar
|
||||
spinner
|
||||
reconstruction
|
||||
validate-pdbx
|
||||
matrix
|
||||
# unit-3d
|
||||
# model
|
||||
# query
|
||||
# rename-compound
|
||||
# sugar
|
||||
# spinner
|
||||
# reconstruction
|
||||
# validate-pdbx
|
||||
# matrix
|
||||
)
|
||||
|
||||
add_library(test-main OBJECT "${CMAKE_CURRENT_SOURCE_DIR}/test-main.cpp")
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
#include "test-main.hpp"
|
||||
|
||||
#include <cif++.hpp>
|
||||
#include <cif++/utilities.hpp>
|
||||
|
||||
std::filesystem::path gTestDir = std::filesystem::current_path();
|
||||
|
||||
@@ -33,7 +33,7 @@ int main(int argc, char *argv[])
|
||||
// initialize CCD location
|
||||
cif::add_file_resource("components.cif", gTestDir / ".." / "rsrc" / "ccd-subset.cif");
|
||||
|
||||
cif::compound_factory::instance().push_dictionary(gTestDir / "HEM.cif");
|
||||
// cif::compound_factory::instance().push_dictionary(gTestDir / "HEM.cif");
|
||||
|
||||
return session.run();
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user