Commit 160f6016 by Maarten L. Hekkelman

more docs

parent 0855965e
......@@ -199,7 +199,7 @@ enum class radius_type
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);
/// An enum used to select either the effective or the crystal radius of an ion.
......@@ -214,11 +214,11 @@ enum class ionic_radius_type
/// Requests for an unknown radius value return kNA
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
{
/// The type as an @ref atom_type
/// The type as an atom_type
atom_type type;
/// The official name for this element
......@@ -233,12 +233,12 @@ struct atom_type_info
/// A flag indicating whether the element is a 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
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[];
......@@ -250,20 +250,20 @@ extern CIFPP_EXPORT const atom_type_info kKnownAtoms[];
class atom_type_traits
{
public:
/// Constructor taking an @ref atom_type \a a
/// Constructor taking an atom_type \a a
atom_type_traits(atom_type a);
/// Constructor based on the element as a string in \a 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 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
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);
/// Return true if the symbol in \a symbol exists and is a metal
......@@ -271,7 +271,7 @@ class atom_type_traits
/// @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
/// @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
{
if (type >= radius_type::type_count)
......@@ -312,7 +312,7 @@ class atom_type_traits
/** @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;
/// @brief Return the Waasmaier & Kirfel scattering factor values for the element
......@@ -320,12 +320,12 @@ class atom_type_traits
/// 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
/// @return The scattering factors as a @ref SFData struct
/// @return The scattering factors as a SFData struct
const SFData &wksf(int charge = 0) const;
/// @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;
/// Clipper doesn't like atoms with charges that do not have a scattering factor. And
......
......@@ -61,6 +61,9 @@ namespace cif
class duplicate_key_error : public std::runtime_error
{
public:
/**
* @brief Construct a new duplicate key error object
*/
duplicate_key_error(const std::string &msg)
: std::runtime_error(msg)
{
......@@ -72,6 +75,9 @@ class duplicate_key_error : public std::runtime_error
class multiple_results_error : public std::runtime_error
{
public:
/**
* @brief Construct a new multiple results error object
*/
multiple_results_error()
: std::runtime_error("query should have returned exactly one row")
{
......@@ -130,7 +136,7 @@ class 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.
/// @brief Set the validator for this category to @a v
......@@ -1006,7 +1012,7 @@ class category
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;
// --------------------------------------------------------------------
......
......@@ -71,10 +71,10 @@ enum class bond_type
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);
/// @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);
/// \brief The possible stereo config values for a compound_atom.
......@@ -94,10 +94,10 @@ enum class stereo_config_type : uint8_t
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);
/// @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);
/// --------------------------------------------------------------------
......
......@@ -364,6 +364,11 @@ struct item_handle
}
// 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>
bool operator!=(const T &value) const
{
......
......@@ -157,11 +157,17 @@ class row : public std::vector<item_value>
public:
row() = default;
/**
* @brief Return the item_value pointer for item at index @a ix
*/
item_value* get(uint16_t ix)
{
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
{
return ix < size() ? &data()[ix] : nullptr;
......
......@@ -267,19 +267,23 @@ struct sym_op
/// \brief a default spaceship operator
constexpr auto operator<=>(const sym_op &rhs) const = default;
#else
/// \brief a default equals operator
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;
}
/// \brief a default not-equals operator
constexpr bool operator!=(const sym_op &rhs) const
{
return not operator==(rhs);
}
#endif
/// @cond
uint8_t m_nr;
uint8_t m_ta, m_tb, m_tc;
/// @endcond
};
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
template <typename T>
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)
{
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)
{
return cif::to_chars(first, last, value, fmt);
......@@ -552,11 +554,13 @@ struct my_charconv
template <typename T>
struct std_charconv
{
/// @brief Simply call std::from_chars
static std::from_chars_result from_chars(const char *a, const char *b, T &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)
{
return std::to_chars(first, last, value, fmt);
......
......@@ -32,10 +32,12 @@
#include <iostream>
#ifndef STDOUT_FILENO
/// @brief For systems that lack this value
#define STDOUT_FILENO 1
#endif
#ifndef STDERR_FILENO
/// @brief For systems that lack this value
#define STDERR_FILENO 2
#endif
......@@ -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
{
/// @brief The defined colours
......@@ -113,6 +95,7 @@ namespace colour
none = 9
};
/// @brief The defined styles
enum style_type
{
bold = 1,
......@@ -133,6 +116,9 @@ namespace colour
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)
: m_str(s)
, m_fore_colour(static_cast<int>(fc) + 30)
......@@ -143,6 +129,9 @@ namespace colour
coloured_string_t &operator=(coloured_string_t &) = delete;
/**
* @brief Write out the string, either coloured or not
*/
template <typename char_type, typename traits_type>
friend std::basic_ostream<char_type, traits_type> &operator<<(
std::basic_ostream<char_type, traits_type> &os, const coloured_string_t &cs)
......@@ -164,9 +153,11 @@ namespace colour
return os;
}
/// @cond
StringType m_str;
int m_fore_colour, m_back_colour;
int m_style;
/// @endcond
};
} // namespace detail
......@@ -174,11 +165,29 @@ namespace colour
/**
* @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 fg Foreground (=text) colour to use
* @param bg Background colour to use
* @param st Text style to use
*/
template <typename char_type>
inline auto coloured(const char_type *str,
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,
// --------------------------------------------------------------------
// 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
{
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);
/**
* @brief Destroy the progress bar object
*
*/
~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
/**
* @brief Notify the progress bar that the internal
* progress counter should be updated to @a inProgress
*/
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);
private:
......
......@@ -213,10 +213,15 @@ void progress_bar_impl::message(const std::string &msg)
}
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 int kSpinnerTimeInterval = 100;
const uint32_t kMinBarWidth = 40, kMinMsgWidth = 12;
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)) << "% ";
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];
......
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