Commit 29446f21 by Maarten L. Hekkelman

new cif::item constructors

version bump
parent abb86735
......@@ -25,7 +25,7 @@
cmake_minimum_required(VERSION 3.16)
# set the project name
project(libcifpp VERSION 5.2.2 LANGUAGES CXX)
project(libcifpp VERSION 5.2.3 LANGUAGES CXX)
list(PREPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake")
......
Version 5.2.3
- New constructors for cif::item, one taking std::optional values
and another taking only a name resulting in a value '.' (i.e. inapplicable).
Version 5.2.2
- Remove dependency on Eigen3 for users of libcifpp
- Fix typos in documentation
......
......@@ -51,8 +51,37 @@ namespace cif
{
// --------------------------------------------------------------------
/// \brief item is a transient class that is used to pass data into rows
/// but it also takes care of formatting data.
/** @brief item is a transient class that is used to pass data into rows
* but it also takes care of formatting data.
*
*
*
* The class cif::item is often used implicitly when creating a row in a category
* using the emplace function.
*
* @code{.cpp}
* cif::category cat("my-cat");
* cat.emplace({
* { "item-1", 1 }, // <- stores an item with value 1
* { "item-2", 1.0, 2 }, // <- stores an item with value 1.00
* { "item-3", std::optional<int>() }, // <- stores an item with value ?
* { "item-4", std::make_optional<int>(42) }, // <- stores an item with value 42
* { "item-5" } // <- stores an item with value .
* });
*
* std::cout << cat << '\n';
* @endcode
*
* Will result in:
*
* @code{.txt}
* _my-cat.item-1 1
* _my-cat.item-2 1.00
* _my-cat.item-3 ?
* _my-cat.item-4 42
* _my-cat.item-5 .
* @endcode
*/
class item
{
public:
......@@ -60,6 +89,14 @@ class item
item() = default;
/// \brief constructor for an item with name \a name and as
/// content the character '.', i.e. an inapplicable value.
item(std::string_view name)
: m_name(name)
, m_value({ '.' })
{
}
/// \brief constructor for an item with name \a name and as
/// content a single character string with content \a value
item(std::string_view name, char value)
: m_name(name)
......@@ -68,7 +105,7 @@ class item
}
/// \brief constructor for an item with name \a name and as
/// content a the formatted floating point value \a value with
/// content the formatted floating point value \a value with
/// precision \a precision
template <typename T, std::enable_if_t<std::is_floating_point_v<T>, int> = 0>
item(std::string_view name, const T &value, int precision)
......@@ -110,7 +147,7 @@ class item
}
/// \brief constructor for an item with name \a name and as
/// content a the formatted integral value \a value
/// content the formatted integral value \a value
template <typename T, std::enable_if_t<std::is_integral_v<T> and not std::is_same_v<T, bool>, int> = 0>
item(const std::string_view name, const T &value)
: m_name(name)
......@@ -127,7 +164,7 @@ class item
}
/// \brief constructor for an item with name \a name and as
/// content a the formatted boolean value \a value
/// content the formatted boolean value \a value
template <typename T, std::enable_if_t<std::is_same_v<T, bool>, int> = 0>
item(const std::string_view name, const T &value)
: m_name(name)
......@@ -143,6 +180,37 @@ class item
{
}
/// \brief constructor for an item with name \a name and as
/// content the optional value \a value
template <typename T>
item(const std::string_view name, const std::optional<T> &value)
: m_name(name)
{
if (value.has_value())
{
item tmp(name, *value);
std::swap(tmp.m_value, m_value);
}
else
m_value.assign("?");
}
/// \brief constructor for an item with name \a name and as
/// content the formatted floating point value \a value with
/// precision \a precision
template <typename T, std::enable_if_t<std::is_floating_point_v<T>, int> = 0>
item(std::string_view name, const std::optional<T> &value, int precision)
: m_name(name)
{
if (value.has_value())
{
item tmp(name, *value, precision);
std::swap(tmp.m_value, m_value);
}
else
m_value.assign("?");
}
/** @cond */
item(const item &rhs) = default;
item(item &&rhs) noexcept = default;
......@@ -462,9 +530,7 @@ struct item_handle::item_value_as<T, std::enable_if_t<std::is_arithmetic_v<T> an
auto b = txt.data();
auto e = txt.data() + txt.size();
std::from_chars_result r = (b + 1 < e and *b == '+' and std::isdigit(b[1])) ?
selected_charconv<value_type>::from_chars(b + 1, e, result) :
selected_charconv<value_type>::from_chars(b, e, result);
std::from_chars_result r = (b + 1 < e and *b == '+' and std::isdigit(b[1])) ? selected_charconv<value_type>::from_chars(b + 1, e, result) : selected_charconv<value_type>::from_chars(b, e, result);
if (r.ec != std::errc() or r.ptr != e)
{
......@@ -499,9 +565,7 @@ struct item_handle::item_value_as<T, std::enable_if_t<std::is_arithmetic_v<T> an
auto b = txt.data();
auto e = txt.data() + txt.size();
std::from_chars_result r = (b + 1 < e and *b == '+' and std::isdigit(b[1])) ?
selected_charconv<value_type>::from_chars(b + 1, e, v) :
selected_charconv<value_type>::from_chars(b, e, v);
std::from_chars_result r = (b + 1 < e and *b == '+' and std::isdigit(b[1])) ? selected_charconv<value_type>::from_chars(b + 1, e, v) : selected_charconv<value_type>::from_chars(b, e, v);
if (r.ec != std::errc() or r.ptr != e)
{
......
......@@ -204,6 +204,26 @@ BOOST_AUTO_TEST_CASE(item_1)
BOOST_CHECK(ci3.empty());
}
BOOST_AUTO_TEST_CASE(item_2)
{
using namespace cif;
cif::item i0("test1");
BOOST_CHECK(i0.value() == ".");
cif::item i1("test1", std:: optional<float>());
BOOST_CHECK(i1.value() == "?");
cif::item i2("test1", std::make_optional<float>(1));
BOOST_CHECK(i2.value() == "1");
cif::item i3("test1", std::optional<float>(), 2);
BOOST_CHECK(i3.value() == "?");
cif::item i4("test1", std::make_optional<float>(1), 2);
BOOST_CHECK(i4.value() == "1.00");
}
// --------------------------------------------------------------------
BOOST_AUTO_TEST_CASE(r_1)
......
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