Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
L
libcifpp
Overview
Overview
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
open
libcifpp
Commits
160f6016
Commit
160f6016
authored
Sep 11, 2023
by
Maarten L. Hekkelman
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
more docs
parent
0855965e
Hide whitespace changes
Inline
Side-by-side
Showing
9 changed files
with
163 additions
and
41 deletions
+163
-41
include/cif++/atom_type.hpp
+12
-12
include/cif++/category.hpp
+8
-2
include/cif++/compound.hpp
+4
-4
include/cif++/item.hpp
+5
-0
include/cif++/row.hpp
+6
-0
include/cif++/symmetry.hpp
+4
-0
include/cif++/text.hpp
+4
-0
include/cif++/utilities.hpp
+112
-20
src/utilities.cpp
+8
-3
No files found.
include/cif++/atom_type.hpp
View file @
160f6016
...
@@ -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
...
...
include/cif++/category.hpp
View file @
160f6016
...
@@ -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
;
// --------------------------------------------------------------------
// --------------------------------------------------------------------
...
...
include/cif++/compound.hpp
View file @
160f6016
...
@@ -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
);
/// --------------------------------------------------------------------
/// --------------------------------------------------------------------
...
...
include/cif++/item.hpp
View file @
160f6016
...
@@ -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
{
{
...
...
include/cif++/row.hpp
View file @
160f6016
...
@@ -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
;
...
...
include/cif++/symmetry.hpp
View file @
160f6016
...
@@ -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"
);
...
...
include/cif++/text.hpp
View file @
160f6016
...
@@ -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
);
...
...
include/cif++/utilities.hpp
View file @
160f6016
...
@@ -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
:
...
...
src/utilities.cpp
View file @
160f6016
...
@@ -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
];
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment