Commit ec0d75ce by Maarten L. Hekkelman

documenting more

parent 877a64ad
...@@ -38,6 +38,7 @@ ...@@ -38,6 +38,7 @@
#include "cif++/iterator.hpp" #include "cif++/iterator.hpp"
#include "cif++/row.hpp" #include "cif++/row.hpp"
#include "cif++/validate.hpp" #include "cif++/validate.hpp"
#include "cif++/text.hpp"
#include <array> #include <array>
...@@ -99,11 +100,11 @@ class category ...@@ -99,11 +100,11 @@ class category
{ {
public: public:
/// \cond /// \cond
friend class row_handle; friend class row_handle;
template <typename, typename...> template <typename, typename...>
friend class iterator_impl; friend class iterator_impl;
/// \endcond
using value_type = row_handle; using value_type = row_handle;
using reference = value_type; using reference = value_type;
...@@ -111,6 +112,8 @@ class category ...@@ -111,6 +112,8 @@ class category
using iterator = iterator_impl<category>; using iterator = iterator_impl<category>;
using const_iterator = iterator_impl<const category>; using const_iterator = iterator_impl<const category>;
/// \endcond
category() = default; ///< Default constructor category() = default; ///< Default constructor
category(std::string_view name); ///< Constructor taking a \a name category(std::string_view name); ///< Constructor taking a \a name
category(const category &rhs); ///< Copy constructor category(const category &rhs); ///< Copy constructor
...@@ -210,31 +213,37 @@ class category ...@@ -210,31 +213,37 @@ class category
return { const_cast<category &>(*this), const_cast<row &>(*m_tail) }; return { const_cast<category &>(*this), const_cast<row &>(*m_tail) };
} }
/// Return an iterator to the first row
iterator begin() iterator begin()
{ {
return { *this, m_head }; return { *this, m_head };
} }
/// Return an iterator pointing past the last row
iterator end() iterator end()
{ {
return { *this, nullptr }; return { *this, nullptr };
} }
/// Return a const iterator to the first row
const_iterator begin() const const_iterator begin() const
{ {
return { *this, m_head }; return { *this, m_head };
} }
/// Return a const iterator pointing past the last row
const_iterator end() const const_iterator end() const
{ {
return { *this, nullptr }; return { *this, nullptr };
} }
/// Return a const iterator to the first row
const_iterator cbegin() const const_iterator cbegin() const
{ {
return { *this, m_head }; return { *this, m_head };
} }
/// Return an iterator pointing past the last row
const_iterator cend() const const_iterator cend() const
{ {
return { *this, nullptr }; return { *this, nullptr };
...@@ -329,7 +338,7 @@ class category ...@@ -329,7 +338,7 @@ class category
/// .. // do something with rh /// .. // do something with rh
/// @endcode /// @endcode
/// ///
/// @param cond The @ref condition for the query /// @param cond The condition for the query
/// @return A special iterator that loops over all elements that match. The iterator can be dereferenced /// @return A special iterator that loops over all elements that match. The iterator can be dereferenced
/// to a @ref row_handle /// to a @ref row_handle
...@@ -342,7 +351,7 @@ class category ...@@ -342,7 +351,7 @@ class category
/// starting at @a pos /// starting at @a pos
/// ///
/// @param pos Where to start searching /// @param pos Where to start searching
/// @param cond The @ref condition for the query /// @param cond The condition for the query
/// @return A special iterator that loops over all elements that match. The iterator can be dereferenced /// @return A special iterator that loops over all elements that match. The iterator can be dereferenced
/// to a @ref row_handle /// to a @ref row_handle
...@@ -353,7 +362,7 @@ class category ...@@ -353,7 +362,7 @@ class category
/// @brief Return a special const iterator to loop over all rows that conform to @a cond /// @brief Return a special const iterator to loop over all rows that conform to @a cond
/// ///
/// @param cond The @ref condition for the query /// @param cond The condition for the query
/// @return A special iterator that loops over all elements that match. The iterator can be dereferenced /// @return A special iterator that loops over all elements that match. The iterator can be dereferenced
/// to a @ref const row_handle /// to a @ref const row_handle
...@@ -366,7 +375,7 @@ class category ...@@ -366,7 +375,7 @@ class category
/// starting at @a pos /// starting at @a pos
/// ///
/// @param pos Where to start searching /// @param pos Where to start searching
/// @param cond The @ref condition for the query /// @param cond The condition for the query
/// @return A special iterator that loops over all elements that match. The iterator can be dereferenced /// @return A special iterator that loops over all elements that match. The iterator can be dereferenced
/// to a @ref const row_handle /// to a @ref const row_handle
...@@ -383,7 +392,7 @@ class category ...@@ -383,7 +392,7 @@ class category
/// std::cout << name << ": " << value << std::endl; /// std::cout << name << ": " << value << std::endl;
/// @endcode /// @endcode
/// ///
/// @param cond The @ref condition for the query /// @param cond The condition for the query
/// @tparam Ts The types for the columns requested /// @tparam Ts The types for the columns requested
/// @param names The names for the columns requested /// @param names The names for the columns requested
/// @return A special iterator that loops over all elements that match. /// @return A special iterator that loops over all elements that match.
...@@ -398,7 +407,7 @@ class category ...@@ -398,7 +407,7 @@ class category
/// @brief Return a special const iterator to loop over all rows that conform to @a cond. The resulting /// @brief Return a special const iterator to loop over all rows that conform to @a cond. The resulting
/// iterator can be used in a structured binding context. /// iterator can be used in a structured binding context.
/// ///
/// @param cond The @ref condition for the query /// @param cond The condition for the query
/// @tparam Ts The types for the columns requested /// @tparam Ts The types for the columns requested
/// @param names The names for the columns requested /// @param names The names for the columns requested
/// @return A special iterator that loops over all elements that match. /// @return A special iterator that loops over all elements that match.
...@@ -414,7 +423,7 @@ class category ...@@ -414,7 +423,7 @@ class category
/// The resulting iterator can be used in a structured binding context. /// The resulting iterator can be used in a structured binding context.
/// ///
/// @param pos Iterator pointing to the location where to start /// @param pos Iterator pointing to the location where to start
/// @param cond The @ref condition for the query /// @param cond The condition for the query
/// @tparam Ts The types for the columns requested /// @tparam Ts The types for the columns requested
/// @param names The names for the columns requested /// @param names The names for the columns requested
/// @return A special iterator that loops over all elements that match. /// @return A special iterator that loops over all elements that match.
...@@ -430,7 +439,7 @@ class category ...@@ -430,7 +439,7 @@ class category
/// The resulting iterator can be used in a structured binding context. /// The resulting iterator can be used in a structured binding context.
/// ///
/// @param pos Iterator pointing to the location where to start /// @param pos Iterator pointing to the location where to start
/// @param cond The @ref condition for the query /// @param cond The condition for the query
/// @tparam Ts The types for the columns requested /// @tparam Ts The types for the columns requested
/// @param names The names for the columns requested /// @param names The names for the columns requested
/// @return A special iterator that loops over all elements that match. /// @return A special iterator that loops over all elements that match.
...@@ -795,11 +804,24 @@ class category ...@@ -795,11 +804,24 @@ class category
// -------------------------------------------------------------------- // --------------------------------------------------------------------
/// Using the relations defined in the validator, return whether the row
/// in @a r has any children in other categories
bool has_children(row_handle r) const; bool has_children(row_handle r) const;
/// Using the relations defined in the validator, return whether the row
/// in @a r has any parents in other categories
bool has_parents(row_handle r) const; bool has_parents(row_handle r) const;
/// Using the relations defined in the validator, return the row handles
/// for all rows in @a childCat that are linked to row @a r
std::vector<row_handle> get_children(row_handle r, const category &childCat) const; std::vector<row_handle> get_children(row_handle r, const category &childCat) const;
/// Using the relations defined in the validator, return the row handles
/// for all rows in @a parentCat that are linked to row @a r
std::vector<row_handle> get_parents(row_handle r, const category &parentCat) const; std::vector<row_handle> get_parents(row_handle r, const category &parentCat) const;
/// Using the relations defined in the validator, return the row handles
/// for all rows in @a cat that are in any way linked to row @a r
std::vector<row_handle> get_linked(row_handle r, const category &cat) const; std::vector<row_handle> get_linked(row_handle r, const category &cat) const;
// -------------------------------------------------------------------- // --------------------------------------------------------------------
...@@ -814,20 +836,40 @@ class category ...@@ -814,20 +836,40 @@ class category
// insert_impl(pos, std::move(row)); // insert_impl(pos, std::move(row));
// } // }
/// Erase the row pointed to by @a pos and return the iterator to the
/// row following pos.
iterator erase(iterator pos); iterator erase(iterator pos);
/// Erase row @a rh
void erase(row_handle rh) void erase(row_handle rh)
{ {
erase(iterator(*this, rh.m_row)); erase(iterator(*this, rh.m_row));
} }
/// @brief Erase all rows that match condition @a cond
/// @param cond The condition
/// @return The number of rows that have been erased
size_t erase(condition &&cond); size_t erase(condition &&cond);
/// @brief Erase all rows that match condition @a cond calling
/// the visitor function @a visit for each before actually erasing it.
/// @param cond The condition
/// @param visit The visitor function
/// @return The number of rows that have been erased
size_t erase(condition &&cond, std::function<void(row_handle)> &&visit); size_t erase(condition &&cond, std::function<void(row_handle)> &&visit);
/// @brief Emplace the values in @a ri in a new row
/// @param ri An object containing the values to insert
/// @return iterator to the newly created row
iterator emplace(row_initializer &&ri) iterator emplace(row_initializer &&ri)
{ {
return this->emplace(ri.begin(), ri.end()); return this->emplace(ri.begin(), ri.end());
} }
/// @brief Create a new row and emplace the values in the range @a b to @a e in it
/// @param b Iterator to the beginning of the range of @ref item_value
/// @param e Iterator to the end of the range of @ref item_value
/// @return iterator to the newly created row
template <typename ItemIter> template <typename ItemIter>
iterator emplace(ItemIter b, ItemIter e) iterator emplace(ItemIter b, ItemIter e)
{ {
...@@ -851,6 +893,7 @@ class category ...@@ -851,6 +893,7 @@ class category
return insert_impl(cend(), r); return insert_impl(cend(), r);
} }
/// @brief Completely erase all rows contained in this category
void clear(); void clear();
// -------------------------------------------------------------------- // --------------------------------------------------------------------
...@@ -858,6 +901,11 @@ class category ...@@ -858,6 +901,11 @@ class category
/// based on a sequence number. This function will be called until the /// based on a sequence number. This function will be called until the
/// result is unique in the context of this category /// result is unique in the context of this category
std::string get_unique_id(std::function<std::string(int)> generator = cif::cif_id_for_number); std::string get_unique_id(std::function<std::string(int)> generator = cif::cif_id_for_number);
/// @brief Generate a new, unique ID based on a string prefix followed by a number
/// @param prefix The string prefix
/// @return a new unique ID
std::string get_unique_id(const std::string &prefix) std::string get_unique_id(const std::string &prefix)
{ {
return get_unique_id([prefix](int nr) return get_unique_id([prefix](int nr)
...@@ -866,7 +914,7 @@ class category ...@@ -866,7 +914,7 @@ class category
// -------------------------------------------------------------------- // --------------------------------------------------------------------
/// \brief Rename a single column in the rows that match \a cond to value \a value /// \brief Update a single column named @a tag in the rows that match \a cond to value \a value
/// making sure the linked categories are updated according to the link. /// making sure the linked categories are updated according to the link.
/// That means, child categories are updated if the links are absolute /// That means, child categories are updated if the links are absolute
/// and unique. If they are not, the child category rows are split. /// and unique. If they are not, the child category rows are split.
...@@ -879,6 +927,11 @@ class category ...@@ -879,6 +927,11 @@ class category
update_value(rows, tag, value); update_value(rows, tag, value);
} }
/// \brief Update a single column named @a tag in @a rows to value \a value
/// making sure the linked categories are updated according to the link.
/// That means, child categories are updated if the links are absolute
/// and unique. If they are not, the child category rows are split.
void update_value(const std::vector<row_handle> &rows, std::string_view tag, std::string_view value); void update_value(const std::vector<row_handle> &rows, std::string_view tag, std::string_view value);
// -------------------------------------------------------------------- // --------------------------------------------------------------------
...@@ -904,6 +957,9 @@ class category ...@@ -904,6 +957,9 @@ class category
return result; return result;
} }
/// @brief Return the name for column with index @a ix
/// @param ix The index number
/// @return The name of the column
std::string_view get_column_name(uint16_t ix) const std::string_view get_column_name(uint16_t ix) const
{ {
if (ix >= m_columns.size()) if (ix >= m_columns.size())
...@@ -912,6 +968,9 @@ class category ...@@ -912,6 +968,9 @@ class category
return m_columns[ix].m_name; return m_columns[ix].m_name;
} }
/// @brief Make sure a column with name @a column_name is known and return its index number
/// @param column_name The name of the column
/// @return The index number of the column
uint16_t add_column(std::string_view column_name) uint16_t add_column(std::string_view column_name)
{ {
using namespace std::literals; using namespace std::literals;
...@@ -935,29 +994,55 @@ class category ...@@ -935,29 +994,55 @@ class category
return result; return result;
} }
/// @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
bool has_column(std::string_view name) const bool has_column(std::string_view name) const
{ {
return get_column_ix(name) < m_columns.size(); return get_column_ix(name) < m_columns.size();
} }
/// @brief Return the @ref cif::iset of columns in this category
iset get_columns() const; iset get_columns() const;
// -------------------------------------------------------------------- // --------------------------------------------------------------------
/// @brief Sort the rows using comparator function @a f
/// @param f The comparator function taking two row_handles and returning
/// an int indicating whether the first is smaller, equal or larger than
/// the second. ( respectively a value <0, 0, or >0 )
void sort(std::function<int(row_handle, row_handle)> f); void sort(std::function<int(row_handle, row_handle)> f);
/// @brief Reorder the rows in the category using the index defined by
/// the @ref category_validator
void reorder_by_index(); void reorder_by_index();
// -------------------------------------------------------------------- // --------------------------------------------------------------------
/// This function returns effectively the list of fully qualified column
/// names, that is category_name + '.' + column_name for each column
std::vector<std::string> get_tag_order() const; std::vector<std::string> get_tag_order() const;
/// Write the contents of the category to the std::ostream @a os
void write(std::ostream &os) const; void write(std::ostream &os) const;
/// @brief Write the contents of the category to the std::ostream @a os and
/// use @a order as the order of the columns. If @a addMissingColumns is
/// false, columns that do not contain any value will be suppressed
/// @param os The std::ostream to write to
/// @param order The order in which the columns should appear
/// @param addMissingColumns When false, empty columns are suppressed from the output
void write(std::ostream &os, const std::vector<std::string> &order, bool addMissingColumns = true); void write(std::ostream &os, const std::vector<std::string> &order, bool addMissingColumns = true);
private: private:
void write(std::ostream &os, const std::vector<uint16_t> &order, bool includeEmptyColumns) const; void write(std::ostream &os, const std::vector<uint16_t> &order, bool includeEmptyColumns) const;
public: public:
/// friend function to make it possible to do:
/// @code {.cpp}
/// std::cout << my_category;
/// @endcode
friend std::ostream &operator<<(std::ostream &os, const category &cat) friend std::ostream &operator<<(std::ostream &os, const category &cat)
{ {
cat.write(os); cat.write(os);
...@@ -967,7 +1052,6 @@ class category ...@@ -967,7 +1052,6 @@ class category
private: private:
void update_value(row *row, uint16_t column, std::string_view value, bool updateLinked, bool validate = true); void update_value(row *row, uint16_t column, std::string_view value, bool updateLinked, bool validate = true);
private:
void erase_orphans(condition &&cond, category &parent); void erase_orphans(condition &&cond, category &parent);
using allocator_type = std::allocator<void>; using allocator_type = std::allocator<void>;
......
...@@ -188,7 +188,7 @@ struct iless ...@@ -188,7 +188,7 @@ struct iless
} }
}; };
typedef std::set<std::string, iless> iset; using iset = std::set<std::string, iless>;
// -------------------------------------------------------------------- // --------------------------------------------------------------------
// This really makes a difference, having our own tolower routines // This really makes a difference, having our own tolower routines
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment