Commit 160f6016 by Maarten L. Hekkelman

more docs

parent 0855965e
...@@ -199,7 +199,7 @@ enum class radius_type ...@@ -199,7 +199,7 @@ enum class radius_type
type_count ///< Number of radii type_count ///< Number of radii
}; };
/// @brief The number of radii per element which can be requested from @ref atom_type_info /// @brief The number of radii per element which can be requested from atom_type_info
constexpr size_t kRadiusTypeCount = static_cast<size_t>(radius_type::type_count); constexpr size_t kRadiusTypeCount = static_cast<size_t>(radius_type::type_count);
/// An enum used to select either the effective or the crystal radius of an ion. /// An enum used to select either the effective or the crystal radius of an ion.
...@@ -214,11 +214,11 @@ enum class ionic_radius_type ...@@ -214,11 +214,11 @@ enum class ionic_radius_type
/// Requests for an unknown radius value return kNA /// Requests for an unknown radius value return kNA
constexpr float kNA = std::numeric_limits<float>::quiet_NaN(); constexpr float kNA = std::numeric_limits<float>::quiet_NaN();
/// A struct holding the known information for all elements defined in @ref atom_type /// A struct holding the known information for all elements defined in atom_type
struct atom_type_info struct atom_type_info
{ {
/// The type as an @ref atom_type /// The type as an atom_type
atom_type type; atom_type type;
/// The official name for this element /// The official name for this element
...@@ -233,12 +233,12 @@ struct atom_type_info ...@@ -233,12 +233,12 @@ struct atom_type_info
/// A flag indicating whether the element is a metal /// A flag indicating whether the element is a metal
bool metal; bool metal;
/// Array containing all known radii for this element. A value of @ref cif::kNA is /// Array containing all known radii for this element. A value of kNA is
/// stored for unknown values /// stored for unknown values
float radii[kRadiusTypeCount]; float radii[kRadiusTypeCount];
}; };
/// Array of @ref atom_type_info struct for each of the defined elements in @ref atom_type /// Array of atom_type_info struct for each of the defined elements in atom_type
extern CIFPP_EXPORT const atom_type_info kKnownAtoms[]; extern CIFPP_EXPORT const atom_type_info kKnownAtoms[];
...@@ -250,20 +250,20 @@ extern CIFPP_EXPORT const atom_type_info kKnownAtoms[]; ...@@ -250,20 +250,20 @@ extern CIFPP_EXPORT const atom_type_info kKnownAtoms[];
class atom_type_traits class atom_type_traits
{ {
public: public:
/// Constructor taking an @ref atom_type \a a /// Constructor taking an atom_type \a a
atom_type_traits(atom_type a); atom_type_traits(atom_type a);
/// Constructor based on the element as a string in \a symbol /// Constructor based on the element as a string in \a symbol
atom_type_traits(const std::string &symbol); atom_type_traits(const std::string &symbol);
atom_type type() const { return m_info->type; } ///< Returns the @ref atom_type atom_type type() const { return m_info->type; } ///< Returns the atom_type
std::string name() const { return m_info->name; } ///< Returns the name of the element std::string name() const { return m_info->name; } ///< Returns the name of the element
std::string symbol() const { return m_info->symbol; } ///< Returns the symbol of the element std::string symbol() const { return m_info->symbol; } ///< Returns the symbol of the element
float weight() const { return m_info->weight; } ///< Returns the average weight of the element float weight() const { return m_info->weight; } ///< Returns the average weight of the element
bool is_metal() const { return m_info->metal; } ///< Returns true if the element is a metal bool is_metal() const { return m_info->metal; } ///< Returns true if the element is a metal
/// Return true if the symbol in \a symbol actually exists in the list of known elements in @ref atom_type /// Return true if the symbol in \a symbol actually exists in the list of known elements in atom_type
static bool is_element(const std::string &symbol); static bool is_element(const std::string &symbol);
/// Return true if the symbol in \a symbol exists and is a metal /// Return true if the symbol in \a symbol exists and is a metal
...@@ -271,7 +271,7 @@ class atom_type_traits ...@@ -271,7 +271,7 @@ class atom_type_traits
/// @brief Return the radius for the element, use \a type to select which radius to return /// @brief Return the radius for the element, use \a type to select which radius to return
/// @param type The selector for which radius to return /// @param type The selector for which radius to return
/// @return The requested radius or @ref cif::kNA if not known (or applicable) /// @return The requested radius or kNA if not known (or applicable)
float radius(radius_type type = radius_type::single_bond) const float radius(radius_type type = radius_type::single_bond) const
{ {
if (type >= radius_type::type_count) if (type >= radius_type::type_count)
...@@ -312,7 +312,7 @@ class atom_type_traits ...@@ -312,7 +312,7 @@ class atom_type_traits
/** @endcond */ /** @endcond */
}; };
// to get the Cval and Siva scattering factor values, use this constant as charge: /// @brief to get the Cval and Siva scattering factor values, use this constant as charge:
static constexpr int kWKSFVal = -99; static constexpr int kWKSFVal = -99;
/// @brief Return the Waasmaier & Kirfel scattering factor values for the element /// @brief Return the Waasmaier & Kirfel scattering factor values for the element
...@@ -320,12 +320,12 @@ class atom_type_traits ...@@ -320,12 +320,12 @@ class atom_type_traits
/// The coefficients from Waasmaier & Kirfel (1995), Acta Cryst. A51, 416-431. /// The coefficients from Waasmaier & Kirfel (1995), Acta Cryst. A51, 416-431.
/// ///
/// @param charge The charge for which the structure values should be returned, use kWSKFVal to return the *Cval* and *Siva* values /// @param charge The charge for which the structure values should be returned, use kWSKFVal to return the *Cval* and *Siva* values
/// @return The scattering factors as a @ref SFData struct /// @return The scattering factors as a SFData struct
const SFData &wksf(int charge = 0) const; const SFData &wksf(int charge = 0) const;
/// @brief Return the electron scattering factor values for the element /// @brief Return the electron scattering factor values for the element
/// ///
/// @return The scattering factors as a @ref SFData struct /// @return The scattering factors as a SFData struct
const SFData &elsf() const; const SFData &elsf() const;
/// Clipper doesn't like atoms with charges that do not have a scattering factor. And /// Clipper doesn't like atoms with charges that do not have a scattering factor. And
......
...@@ -61,6 +61,9 @@ namespace cif ...@@ -61,6 +61,9 @@ namespace cif
class duplicate_key_error : public std::runtime_error class duplicate_key_error : public std::runtime_error
{ {
public: public:
/**
* @brief Construct a new duplicate key error object
*/
duplicate_key_error(const std::string &msg) duplicate_key_error(const std::string &msg)
: std::runtime_error(msg) : std::runtime_error(msg)
{ {
...@@ -72,6 +75,9 @@ class duplicate_key_error : public std::runtime_error ...@@ -72,6 +75,9 @@ class duplicate_key_error : public std::runtime_error
class multiple_results_error : public std::runtime_error class multiple_results_error : public std::runtime_error
{ {
public: public:
/**
* @brief Construct a new multiple results error object
*/
multiple_results_error() multiple_results_error()
: std::runtime_error("query should have returned exactly one row") : std::runtime_error("query should have returned exactly one row")
{ {
...@@ -130,7 +136,7 @@ class category ...@@ -130,7 +136,7 @@ class category
// -------------------------------------------------------------------- // --------------------------------------------------------------------
const std::string &name() const { return m_name; } ///< Returns the name of the category const std::string &name() const { return m_name; } ///< Returns the name of the category
iset key_fields() const; ///< Returns the @ref cif::iset of key field names. Retrieved from the @ref category_validator for this category iset key_fields() const; ///< Returns the cif::iset of key field names. Retrieved from the @ref category_validator for this category
std::set<uint16_t> key_field_indices() const; ///< Returns a set of indices for the key fields. std::set<uint16_t> key_field_indices() const; ///< Returns a set of indices for the key fields.
/// @brief Set the validator for this category to @a v /// @brief Set the validator for this category to @a v
...@@ -1006,7 +1012,7 @@ class category ...@@ -1006,7 +1012,7 @@ class category
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 /// @brief Return the cif::iset of columns in this category
iset get_columns() const; iset get_columns() const;
// -------------------------------------------------------------------- // --------------------------------------------------------------------
......
...@@ -71,10 +71,10 @@ enum class bond_type ...@@ -71,10 +71,10 @@ enum class bond_type
pi, ///< pi bond pi, ///< pi bond
}; };
/// @brief return the string representation of @ref bond_type @a bondType /// @brief return the string representation of @a bondType
std::string bond_type_to_string(bond_type bondType); std::string bond_type_to_string(bond_type bondType);
/// @brief return the @ref bond_type for the string representation @a bondType /// @brief return the cif::bond_type for the string representation @a bondType
bond_type parse_bond_type_from_string(const std::string &bondType); bond_type parse_bond_type_from_string(const std::string &bondType);
/// \brief The possible stereo config values for a compound_atom. /// \brief The possible stereo config values for a compound_atom.
...@@ -94,10 +94,10 @@ enum class stereo_config_type : uint8_t ...@@ -94,10 +94,10 @@ enum class stereo_config_type : uint8_t
S = 'S' ///< Sinister S = 'S' ///< Sinister
}; };
/// @brief return the string representation of @ref stereo_config_type @a stereo_config /// @brief return the string representation of @a stereo_config
std::string to_string(stereo_config_type stereo_config); std::string to_string(stereo_config_type stereo_config);
/// @brief return the @ref stereo_config_type for the string representation @a stereo_config /// @brief return the cif::stereo_config_type for the string representation @a stereo_config
stereo_config_type parse_stereo_config_from_string(const std::string &stereo_config); stereo_config_type parse_stereo_config_from_string(const std::string &stereo_config);
/// -------------------------------------------------------------------- /// --------------------------------------------------------------------
......
...@@ -364,6 +364,11 @@ struct item_handle ...@@ -364,6 +364,11 @@ struct item_handle
} }
// We may not have C++20 yet... // We may not have C++20 yet...
/**
* @brief Compare the value contained with the value @a value and
* return true if both are not equal.
*/
template <typename T> template <typename T>
bool operator!=(const T &value) const bool operator!=(const T &value) const
{ {
......
...@@ -157,11 +157,17 @@ class row : public std::vector<item_value> ...@@ -157,11 +157,17 @@ class row : public std::vector<item_value>
public: public:
row() = default; row() = default;
/**
* @brief Return the item_value pointer for item at index @a ix
*/
item_value* get(uint16_t ix) item_value* get(uint16_t ix)
{ {
return ix < size() ? &data()[ix] : nullptr; return ix < size() ? &data()[ix] : nullptr;
} }
/**
* @brief Return the const item_value pointer for item at index @a ix
*/
const item_value* get(uint16_t ix) const const item_value* get(uint16_t ix) const
{ {
return ix < size() ? &data()[ix] : nullptr; return ix < size() ? &data()[ix] : nullptr;
......
...@@ -267,19 +267,23 @@ struct sym_op ...@@ -267,19 +267,23 @@ struct sym_op
/// \brief a default spaceship operator /// \brief a default spaceship operator
constexpr auto operator<=>(const sym_op &rhs) const = default; constexpr auto operator<=>(const sym_op &rhs) const = default;
#else #else
/// \brief a default equals operator
constexpr bool operator==(const sym_op &rhs) const constexpr bool operator==(const sym_op &rhs) const
{ {
return m_nr == rhs.m_nr and m_ta == rhs.m_ta and m_tb == rhs.m_tb and m_tc == rhs.m_tc; return m_nr == rhs.m_nr and m_ta == rhs.m_ta and m_tb == rhs.m_tb and m_tc == rhs.m_tc;
} }
/// \brief a default not-equals operator
constexpr bool operator!=(const sym_op &rhs) const constexpr bool operator!=(const sym_op &rhs) const
{ {
return not operator==(rhs); return not operator==(rhs);
} }
#endif #endif
/// @cond
uint8_t m_nr; uint8_t m_nr;
uint8_t m_ta, m_tb, m_tc; uint8_t m_ta, m_tb, m_tc;
/// @endcond
}; };
static_assert(sizeof(sym_op) == 4, "Sym_op should be four bytes"); static_assert(sizeof(sym_op) == 4, "Sym_op should be four bytes");
......
...@@ -537,11 +537,13 @@ std::to_chars_result to_chars(char *first, char *last, FloatType &value, chars_f ...@@ -537,11 +537,13 @@ std::to_chars_result to_chars(char *first, char *last, FloatType &value, chars_f
template <typename T> template <typename T>
struct my_charconv struct my_charconv
{ {
/// @brief Simply call our version of std::from_chars
static std::from_chars_result from_chars(const char *a, const char *b, T &d) static std::from_chars_result from_chars(const char *a, const char *b, T &d)
{ {
return cif::from_chars(a, b, d); return cif::from_chars(a, b, d);
} }
/// @brief Simply call our version of std::to_chars
static std::to_chars_result to_chars(char *first, char *last, T &value, chars_format fmt) static std::to_chars_result to_chars(char *first, char *last, T &value, chars_format fmt)
{ {
return cif::to_chars(first, last, value, fmt); return cif::to_chars(first, last, value, fmt);
...@@ -552,11 +554,13 @@ struct my_charconv ...@@ -552,11 +554,13 @@ struct my_charconv
template <typename T> template <typename T>
struct std_charconv struct std_charconv
{ {
/// @brief Simply call std::from_chars
static std::from_chars_result from_chars(const char *a, const char *b, T &d) static std::from_chars_result from_chars(const char *a, const char *b, T &d)
{ {
return std::from_chars(a, b, d); return std::from_chars(a, b, d);
} }
/// @brief Simply call std::to_chars
static std::to_chars_result to_chars(char *first, char *last, T &value, chars_format fmt) static std::to_chars_result to_chars(char *first, char *last, T &value, chars_format fmt)
{ {
return std::to_chars(first, last, value, fmt); return std::to_chars(first, last, value, fmt);
......
...@@ -32,10 +32,12 @@ ...@@ -32,10 +32,12 @@
#include <iostream> #include <iostream>
#ifndef STDOUT_FILENO #ifndef STDOUT_FILENO
/// @brief For systems that lack this value
#define STDOUT_FILENO 1 #define STDOUT_FILENO 1
#endif #endif
#ifndef STDERR_FILENO #ifndef STDERR_FILENO
/// @brief For systems that lack this value
#define STDERR_FILENO 2 #define STDERR_FILENO 2
#endif #endif
...@@ -77,26 +79,6 @@ std::string get_version_nr(); ...@@ -77,26 +79,6 @@ std::string get_version_nr();
// -------------------------------------------------------------------- // --------------------------------------------------------------------
/**
* When writing out text to the terminal it is often useful to have
* some of the text colourised. But only if the output is really a
* terminal since colouring text is done using escape sequences
* an if output is redirected to a file, these escape sequences end up
* in the file making the real text less easy to read.
*
* The code presented here is rather basic. It mimics the std::quoted
* manipulator in that it will colour a string with optionally
* requested colours and text style.
*
* Example:
*
* @code {.cpp}
* using namespace cif::colour;
* std::cout << cif::coloured("Hello, world!", white, red, bold) << '\n';
* @endcode
*
*/
namespace colour namespace colour
{ {
/// @brief The defined colours /// @brief The defined colours
...@@ -113,6 +95,7 @@ namespace colour ...@@ -113,6 +95,7 @@ namespace colour
none = 9 none = 9
}; };
/// @brief The defined styles
enum style_type enum style_type
{ {
bold = 1, bold = 1,
...@@ -133,6 +116,9 @@ namespace colour ...@@ -133,6 +116,9 @@ namespace colour
static_assert(std::is_reference_v<StringType> or std::is_pointer_v<StringType>, static_assert(std::is_reference_v<StringType> or std::is_pointer_v<StringType>,
"String type must be pointer or reference"); "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(StringType s, colour_type fc, colour_type bc, style_type st)
: m_str(s) : m_str(s)
, m_fore_colour(static_cast<int>(fc) + 30) , m_fore_colour(static_cast<int>(fc) + 30)
...@@ -143,6 +129,9 @@ namespace colour ...@@ -143,6 +129,9 @@ namespace colour
coloured_string_t &operator=(coloured_string_t &) = delete; coloured_string_t &operator=(coloured_string_t &) = delete;
/**
* @brief Write out the string, either coloured or not
*/
template <typename char_type, typename traits_type> template <typename char_type, typename traits_type>
friend std::basic_ostream<char_type, traits_type> &operator<<( friend std::basic_ostream<char_type, traits_type> &operator<<(
std::basic_ostream<char_type, traits_type> &os, const coloured_string_t &cs) std::basic_ostream<char_type, traits_type> &os, const coloured_string_t &cs)
...@@ -164,9 +153,11 @@ namespace colour ...@@ -164,9 +153,11 @@ namespace colour
return os; return os;
} }
/// @cond
StringType m_str; StringType m_str;
int m_fore_colour, m_back_colour; int m_fore_colour, m_back_colour;
int m_style; int m_style;
/// @endcond
}; };
} // namespace detail } // namespace detail
...@@ -174,11 +165,29 @@ namespace colour ...@@ -174,11 +165,29 @@ namespace colour
/** /**
* @brief Manipulator for coloured strings. * @brief Manipulator for coloured strings.
*
* When writing out text to the terminal it is often useful to have
* some of the text colourised. But only if the output is really a
* terminal since colouring text is done using escape sequences
* an if output is redirected to a file, these escape sequences end up
* in the file making the real text less easy to read.
*
* The code presented here is rather basic. It mimics the std::quoted
* manipulator in that it will colour a string with optionally
* requested colours and text style.
*
* Example:
*
* @code {.cpp}
* using namespace cif::colour;
* std::cout << cif::coloured("Hello, world!", white, red, bold) << '\n';
* @endcode
* @param str String to quote. * @param str String to quote.
* @param fg Foreground (=text) colour to use * @param fg Foreground (=text) colour to use
* @param bg Background colour to use * @param bg Background colour to use
* @param st Text style to use * @param st Text style to use
*/ */
template <typename char_type> template <typename char_type>
inline auto coloured(const char_type *str, inline auto coloured(const char_type *str,
colour::colour_type fg, colour::colour_type bg = colour::colour_type::none, colour::colour_type fg, colour::colour_type bg = colour::colour_type::none,
...@@ -214,15 +223,98 @@ inline auto coloured(std::basic_string_view<char_type, traits_type> &str, ...@@ -214,15 +223,98 @@ inline auto coloured(std::basic_string_view<char_type, traits_type> &str,
// -------------------------------------------------------------------- // --------------------------------------------------------------------
// A progress bar // A progress bar
/**
* @brief A simple progress bar class for terminal based output
*
* Using a progress bar is very convenient for the end user when
* you have long running code. It gives feed back on how fast an
* operation is performed and may give an indication how long it
* will take before it is finished.
*
* Using this cif::progress_bar implementation is straightforward:
*
* @code {.cpp}
* using namespace std::chrono_literals;
*
* cif::progress_bar pb(10, "counting to ten");
*
* for (int i = 1; i <= 10; ++i)
* {
* pb.consumed(1);
* std::this_thread::sleep_for(1s);
* }
*
* @endcode
*
* When the progress_bar is created, it first checks
* to see if stdout is to a real TTY and if the VERBOSE
* flag is not less than zero (quiet mode). If this passes
* a thread is started that waits for updates.
*
* The first two seconds, nothing is written to the screen
* so if the work is finished within those two seconds
* the screen stays clean.
*
* After this time, a progress bar is printed that may look
* like this:
*
* @code
* step 3 ========================-------------------------------- 40% ⢁
* @endcode
*
* The first characters contain the initial action name or
* the message text if it was used afterwards.
*
* The thermometer is made up with '=' and '-' characters.
*
* A percentage is also shown and at the end there is a spinner
* that gives feedback that the program is really still working.
*
* The progress bar is removed if the max has been reached
* or if the progress bar is destructed. If any output has
* been generated, the initial action is printed out along
* with the total time spent.
*/
class progress_bar class progress_bar
{ {
public: public:
/**
* @brief Construct a new progress bar object
*
* Progress ranges from 0 (zero) to @a inMax
*
* The action in @a inAction is used for display
*
* @param inMax The maximum value
* @param inAction The description of what is
* going on
*/
progress_bar(int64_t inMax, const std::string &inAction); progress_bar(int64_t inMax, const std::string &inAction);
/**
* @brief Destroy the progress bar object
*
*/
~progress_bar(); ~progress_bar();
/**
* @brief Notify the progress bar that @a inConsumed
* should be added to the internal progress counter
*/
void consumed(int64_t inConsumed); // consumed is relative void consumed(int64_t inConsumed); // consumed is relative
/**
* @brief Notify the progress bar that the internal
* progress counter should be updated to @a inProgress
*/
void progress(int64_t inProgress); // progress is absolute void progress(int64_t inProgress); // progress is absolute
/**
* @brief Replace the action string in the progress bar
* with @a inMessage
*/
void message(const std::string &inMessage); void message(const std::string &inMessage);
private: private:
......
...@@ -213,10 +213,15 @@ void progress_bar_impl::message(const std::string &msg) ...@@ -213,10 +213,15 @@ void progress_bar_impl::message(const std::string &msg)
} }
const char* kSpinner[] = { const char* kSpinner[] = {
// "▉", "▊", "▋", "▌", "▍", "▎", "▏", "▎", "▍", "▌", "▋", "▊", "▉" // ".", "o", "O", "0", "O", "o", ".", " "
".", "o", "O", "0", "O", "o", ".", " " // "⢄", "⢂", "⢁", "⡁", "⡈", "⡐", "⡠"
".", "o", "O", "0", "@", "*", " "
}; };
const size_t kSpinnerCount = sizeof(kSpinner) / sizeof(char*); const size_t kSpinnerCount = sizeof(kSpinner) / sizeof(char*);
const int kSpinnerTimeInterval = 100;
const uint32_t kMinBarWidth = 40, kMinMsgWidth = 12; const uint32_t kMinBarWidth = 40, kMinMsgWidth = 12;
void progress_bar_impl::print_progress() void progress_bar_impl::print_progress()
...@@ -269,7 +274,7 @@ void progress_bar_impl::print_progress() ...@@ -269,7 +274,7 @@ void progress_bar_impl::print_progress()
msg << std::setw(3) << static_cast<int>(std::ceil(progress * 100)) << "% "; msg << std::setw(3) << static_cast<int>(std::ceil(progress * 100)) << "% ";
auto now = std::chrono::system_clock::now(); auto now = std::chrono::system_clock::now();
m_spinner_index = (std::chrono::duration_cast<std::chrono::milliseconds>(now - m_start).count() / 200) % kSpinnerCount; m_spinner_index = (std::chrono::duration_cast<std::chrono::milliseconds>(now - m_start).count() / kSpinnerTimeInterval) % kSpinnerCount;
msg << kSpinner[m_spinner_index]; msg << kSpinner[m_spinner_index];
......
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