Commit 1719ed69 by Maarten L. Hekkelman

backup of documentation

parent 821895bb
......@@ -275,7 +275,14 @@ set(project_headers
add_library(cifpp ${project_sources} ${project_headers} ${PROJECT_SOURCE_DIR}/src/symop_table_data.hpp)
add_library(cifpp::cifpp ALIAS cifpp)
generate_export_header(cifpp EXPORT_FILE_NAME ${PROJECT_SOURCE_DIR}/include/cif++/exports.hpp)
set(EXPORT_DOXYGEN_CONTENT [[
/** @file exports.hpp */
]])
generate_export_header(cifpp EXPORT_FILE_NAME ${PROJECT_SOURCE_DIR}/include/cif++/exports.hpp
CUSTOM_CONTENT_FROM_VARIABLE EXPORT_DOXYGEN_CONTENT)
if(BOOST_REGEX)
target_compile_definitions(cifpp PRIVATE USE_BOOST_REGEX=1 BOOST_REGEX_STANDALONE=1)
......
......@@ -24,9 +24,10 @@
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/// \file atom_type.hpp
/// This file contains information about all known elements
/** \file atom_type.hpp
*
* This file contains information about all known elements
*/
#pragma once
......@@ -40,7 +41,7 @@
namespace cif
{
/// Atom type as an integer. All known elements are available as a constant.
/** Atom type as an integer. All known elements are available as a constant. */
enum atom_type : uint8_t
{
......
......@@ -26,12 +26,6 @@
#pragma once
/// \file category.hpp
/// Documentation for the cif::category class
///
/// The category class should meet the requirements of Container and
/// SequenceContainer.
#include "cif++/forward_decl.hpp"
#include "cif++/condition.hpp"
......@@ -42,10 +36,17 @@
#include <array>
// TODO: implement all of:
// https://en.cppreference.com/w/cpp/named_req/Container
// https://en.cppreference.com/w/cpp/named_req/SequenceContainer
// and more?
/** \file category.hpp
* Documentation for the cif::category class
*
* The category class should meet the requirements of Container and
* SequenceContainer.
*
* TODO: implement all of:
* https://en.cppreference.com/w/cpp/named_req/Container
* https://en.cppreference.com/w/cpp/named_req/SequenceContainer
* and more?
*/
namespace cif
{
......
......@@ -165,7 +165,10 @@ namespace detail
class condition
{
public:
/** @cond */
using condition_impl = detail::condition_impl;
/** @endcond */
/**
* @brief Construct a new, empty condition object
......@@ -188,6 +191,9 @@ class condition
condition(const condition &) = delete;
/**
* @brief Construct a new condition object moving the data from @a rhs
*/
condition(condition &&rhs) noexcept
: m_impl(nullptr)
{
......@@ -196,6 +202,9 @@ class condition
condition &operator=(const condition &) = delete;
/**
* @brief Assignment operator moving the data from @a rhs
*/
condition &operator=(condition &&rhs) noexcept
{
std::swap(m_impl, rhs.m_impl);
......
......@@ -29,18 +29,31 @@
#include "cif++/category.hpp"
#include "cif++/forward_decl.hpp"
/// \file datablock.hpp
/** \file datablock.hpp
* Each valid mmCIF file contains at least one @ref cif::datablock.
* A datablock has a name and can contain one or more @ref cif::category "categories"
*/
namespace cif
{
// --------------------------------------------------------------------
/**
* @brief A datablock is a list of category objects with some additional features
*
*/
class datablock : public std::list<category>
{
public:
datablock() = default;
/**
* @brief Construct a new datablock object with name @a name
*
* @param name The name for the new datablock
*/
datablock(std::string_view name)
: m_name(name)
{
......@@ -54,34 +67,121 @@ class datablock : public std::list<category>
// --------------------------------------------------------------------
/**
* @brief Return the name of this datablock
*/
const std::string &name() const { return m_name; }
/**
* @brief Set the name of this datablock to @a name
*
* @param name The new name
*/
void set_name(std::string_view name)
{
m_name = name;
}
/**
* @brief Set the validator object to @a v
*
* @param v The new validator object, may be null
*/
void set_validator(const validator *v);
/**
* @brief Get the validator object
*
* @return const validator* The validator or nullptr if there is none
*/
const validator *get_validator() const;
/**
* @brief Validates the content of this datablock and all its content
*
* @return true If the content is valid
* @return false If the content is not valid
*/
bool is_valid() const;
/**
* @brief Validates all contained data for valid links between parents and children
* as defined in the validator
*
* @return true If all links are valid
* @return false If all links are not valid
*/
bool validate_links() const;
// --------------------------------------------------------------------
/**
* @brief Return the category named @a name, will create a new and empty
* category named @a name if it does not exist.
*
* @param name The name of the category to return
* @return category& Reference to the named category
*/
category &operator[](std::string_view name);
/**
* @brief Return the const category named @a name, will return a reference
* to a static empty category if it was not found.
*
* @param name The name of the category to return
* @return category& Reference to the named category
*/
const category &operator[](std::string_view name) const;
/**
* @brief Return a pointer to the category named @a name or nullptr if
* it does not exist.
*
* @param name The name of the category
* @return category* Pointer to the category found or nullptr
*/
category *get(std::string_view name);
/**
* @brief Return a pointer to the category named @a name or nullptr if
* it does not exist.
*
* @param name The name of the category
* @return category* Pointer to the category found or nullptr
*/
const category *get(std::string_view name) const;
/**
* @brief Tries to find a category with name @a name and will create a
* new one if it is not found. The result is a tuple of an iterator
* pointing to the category and a boolean indicating whether the category
* was created or not.
*
* @param name The name for the category
* @return std::tuple<iterator, bool> A tuple containing an iterator pointing
* at the category and a boolean indicating whether the category was newly
* created.
*/
std::tuple<iterator, bool> emplace(std::string_view name);
/**
* @brief Get the preferred order of the categories when writing them
*/
std::vector<std::string> get_tag_order() const;
/**
* @brief Write out the contents to @a os
*/
void write(std::ostream &os) const;
/**
* @brief Write out the contents to @a os using the order defined in @a tag_order
*/
void write(std::ostream &os, const std::vector<std::string> &tag_order);
/**
* @brief Friend operator<< to write datablock @a db to std::ostream @a os
*/
friend std::ostream &operator<<(std::ostream &os, const datablock &db)
{
db.write(os);
......@@ -90,6 +190,9 @@ class datablock : public std::list<category>
// --------------------------------------------------------------------
/**
* @brief Comparison operator to compare two datablock for equal content
*/
bool operator==(const datablock &rhs) const;
private:
......
......@@ -28,10 +28,23 @@
#include "cif++/validate.hpp"
/**
* @file validate.hpp
*
* Functions to create and manipulate validator objects
*/
namespace cif
{
/**
* @brief Parse the contents of @a is and create a new validator object with name @a name
*/
validator parse_dictionary(std::string_view name, std::istream &is);
/**
* @brief Extend the definitions in validator @a v with the contents of stream @a is
*/
void extend_dictionary(validator &v, std::istream &is);
} // namespace cif
......@@ -32,30 +32,60 @@
#include "cif++/datablock.hpp"
#include "cif++/parser.hpp"
/// \file file.hpp
/// The file class defined here encapsulates the contents of an mmCIF file
/// It is mainly a list of @ref cif::datablock objects
/** \file file.hpp
*
* The file class defined here encapsulates the contents of an mmCIF file
* It is mainly a list of @ref cif::datablock objects
*
* The class file has methods to load dictionaries. These dictionaries are
* loaded from resources (if available) or from disk from several locations.
*
* See the documentation on load_resource() in file: utilities.hpp for more
* information on how data is loaded.
*/
namespace cif
{
// --------------------------------------------------------------------
/**
* @brief The class file is actually a list of datablock objects
*
*/
class file : public std::list<datablock>
{
public:
file() = default;
/**
* @brief Construct a new file object using the data in the file @a p as content
*
* @param p Path to a file containing the data to load
*/
explicit file(const std::filesystem::path &p)
{
load(p);
}
/**
* @brief Construct a new file object using the data in the std::istream @a is
*
* @param is The istream containing the data to load
*/
explicit file(std::istream &is)
{
load(is);
}
/**
* @brief Construct a new file object with data in the constant string defined
* by @a data and @a length
*
* @param data The pointer to the character string with data to load
* @param length The length of the data
*/
explicit file(const char *data, size_t length)
{
struct membuf : public std::streambuf
......@@ -75,45 +105,129 @@ class file : public std::list<datablock>
file &operator=(const file &) = default;
file &operator=(file &&) = default;
/**
* @brief Set the validator object to @a v
*/
void set_validator(const validator *v);
/**
* @brief Get the validator object
*/
const validator *get_validator() const
{
return m_validator;
}
/**
* @brief Validate the content and return true if everything was valid.
*
* Will throw an exception if there is no validator defined.
*
* If each category was valid, validate_links will also be called.
*
* @return true If the content is valid
* @return false If the content is not valid
*/
bool is_valid() const;
/**
* @brief Validate the content and return true if everything was valid.
*
* Will attempt to load the referenced dictionary if none was specified.
*
* If each category was valid, validate_links will also be called.
*
* @return true If the content is valid
* @return false If the content is not valid
*/
bool is_valid();
/**
* @brief Validate the links for all datablocks contained.
*
* Will throw an exception if no validator was specified.
*
* @return true If all links were valid
* @return false If all links were not valid
*/
bool validate_links() const;
/**
* @brief Attempt to load a dictionary (validator) based on
* the contents of the *audit_conform* category, if available.
*/
void load_dictionary();
/**
* @brief Attempt to load the named dictionary @a name and
* create a validator based on it.
*
* @param name The name of the dictionary to load
*/
void load_dictionary(std::string_view name);
/**
* @brief Return true if a datablock with the name @a name is part of this file
*/
bool contains(std::string_view name) const;
/**
* @brief return a reference to the first datablock in the file
*/
datablock &front()
{
assert(not empty());
return std::list<datablock>::front();
}
/**
* @brief return a const reference to the first datablock in the file
*/
const datablock &front() const
{
assert(not empty());
return std::list<datablock>::front();
}
/**
* @brief return a reference to the datablock named @a name
*/
datablock &operator[](std::string_view name);
/**
* @brief return a const reference to the datablock named @a name
*/
const datablock &operator[](std::string_view name) const;
/**
* @brief Tries to find a datablock with name @a name and will create a
* new one if it is not found. The result is a tuple of an iterator
* pointing to the datablock and a boolean indicating whether the datablock
* was created or not.
*
* @param name The name for the datablock
* @return std::tuple<iterator, bool> A tuple containing an iterator pointing
* at the datablock and a boolean indicating whether the datablock was newly
* created.
*/
std::tuple<iterator, bool> emplace(std::string_view name);
/** Load the data from the file specified by @a p */
void load(const std::filesystem::path &p);
/** Load the data from @a is */
void load(std::istream &is);
/** Save the data to the file specified by @a p */
void save(const std::filesystem::path &p) const;
/** Save the data to @a is */
void save(std::ostream &os) const;
/**
* @brief Friend operator<< to write file @a f to std::ostream @a os
*/
friend std::ostream &operator<<(std::ostream &os, const file &f)
{
f.save(os);
......
......@@ -28,10 +28,12 @@
#include <string>
/// \file format.hpp
/// File containing a basic reimplementation of boost::format
/// but then a bit more simplistic. Still this allowed me to move my code
/// from using boost::format to something without external dependency easily.
/** \file format.hpp
*
* File containing a basic reimplementation of boost::format
* but then a bit more simplistic. Still this allowed me to move my code
* from using boost::format to something without external dependency easily.
*/
namespace cif
{
......@@ -85,6 +87,8 @@ namespace detail
} // namespace
/** @cond */
template <typename... Args>
class format_plus_arg
{
......@@ -132,6 +136,23 @@ class format_plus_arg
vargs_vector_type m_vargs;
};
/** @endcond */
/**
* @brief A simplistic reimplementation of boost::format, in fact it is
* actually a way to call the C function snprintf to format the arguments
* in @a args into the format string @a fmt
*
* The string in @a fmt should thus be a C style format string.
*
* TODO: Move to C++23 style of printing.
*
* @tparam Args The types of the arguments
* @param fmt The format string
* @param args The arguments
* @return An object that can be written out to a std::ostream using operator<<
*/
template <typename... Args>
constexpr auto format(std::string_view fmt, Args... args)
{
......@@ -144,11 +165,20 @@ constexpr auto format(std::string_view fmt, Args... args)
class fill_out_streambuf : public std::streambuf
{
public:
/** @cond */
using base_type = std::streambuf;
using int_type = base_type::int_type;
using char_type = base_type::char_type;
using traits_type = base_type::traits_type;
/** @endcond */
/**
* @brief Construct a new fill out streambuf object based on ostream @a os and a
* width to fill out to of @a width
*/
fill_out_streambuf(std::ostream &os, int width = 80)
: m_os(os)
, m_upstream(os.rdbuf())
......@@ -156,11 +186,21 @@ class fill_out_streambuf : public std::streambuf
{
}
/** @cond */
~fill_out_streambuf()
{
m_os.rdbuf(m_upstream);
}
/** @endcond */
/**
* @brief The magic happens here. Write out a couple of spaces when
* the last character to write is a newline to make the line as
* wide as the requested width.
*/
virtual int_type
overflow(int_type ic = traits_type::eof())
{
......@@ -191,8 +231,10 @@ class fill_out_streambuf : public std::streambuf
return result;
}
/** Return the upstream streambuf */
std::streambuf *get_upstream() const { return m_upstream; }
/** Return how many lines have been written */
int get_line_count() const { return m_line_count; }
private:
......
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