Commit 2b92cee3 by Maarten L. Hekkelman

some documentation and cleanup of cif::item

parent 80717685
...@@ -34,9 +34,14 @@ ...@@ -34,9 +34,14 @@
#include <memory> #include <memory>
#include <optional> #include <optional>
#include <cif++/forward_decl.hpp>
#include <cif++/text.hpp> #include <cif++/text.hpp>
#include <cif++/forward_decl.hpp> /// \file item.hpp
/// This file contains the declaration of \class item but
/// also the \class item_value and \class item_handle
/// These handle the storage of and access to the data
/// for a single data field.
namespace cif namespace cif
{ {
...@@ -45,12 +50,15 @@ extern int VERBOSE; ...@@ -45,12 +50,15 @@ extern int VERBOSE;
// -------------------------------------------------------------------- // --------------------------------------------------------------------
/// \brief item is a transient class that is used to pass data into rows /// \brief item is a transient class that is used to pass data into rows
/// but it also takes care of formatting data /// but it also takes care of formatting data.
class item class item
{ {
public: public:
/// \brief Default constructor, empty item
item() = default; item() = default;
/// \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) item(std::string_view name, char value)
: m_name(name) : m_name(name)
, m_value(m_buffer, 1) , m_value(m_buffer, 1)
...@@ -59,6 +67,9 @@ class item ...@@ -59,6 +67,9 @@ class item
m_buffer[1] = 0; m_buffer[1] = 0;
} }
/// \brief constructor for an item with name \a name and as
/// content a 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> 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) item(std::string_view name, const T &value, int precision)
: m_name(name) : m_name(name)
...@@ -72,6 +83,9 @@ class item ...@@ -72,6 +83,9 @@ class item
m_value = std::string_view(m_buffer, r.ptr - m_buffer); m_value = std::string_view(m_buffer, r.ptr - m_buffer);
} }
/// \brief constructor for an item with name \a name and as
/// content a formatted floating point value \a value with
/// so-called general formatting
template <typename T, std::enable_if_t<std::is_floating_point_v<T>, int> = 0> template <typename T, std::enable_if_t<std::is_floating_point_v<T>, int> = 0>
item(const std::string_view name, const T &value) item(const std::string_view name, const T &value)
: m_name(name) : m_name(name)
...@@ -85,6 +99,8 @@ class item ...@@ -85,6 +99,8 @@ class item
m_value = std::string_view(m_buffer, r.ptr - m_buffer); m_value = std::string_view(m_buffer, r.ptr - m_buffer);
} }
/// \brief constructor for an item with name \a name and as
/// content a the formatted integral value \a value
template <typename T, std::enable_if_t<std::is_integral_v<T>, int> = 0> template <typename T, std::enable_if_t<std::is_integral_v<T>, int> = 0>
item(const std::string_view name, const T &value) item(const std::string_view name, const T &value)
: m_name(name) : m_name(name)
...@@ -98,6 +114,8 @@ class item ...@@ -98,6 +114,8 @@ class item
m_value = std::string_view(m_buffer, r.ptr - m_buffer); m_value = std::string_view(m_buffer, r.ptr - m_buffer);
} }
/// \brief constructor for an item with name \a name and as
/// content value \a value
item(const std::string_view name, const std::string_view value) item(const std::string_view name, const std::string_view value)
: m_name(name) : m_name(name)
, m_value(value) , m_value(value)
...@@ -115,7 +133,8 @@ class item ...@@ -115,7 +133,8 @@ class item
std::string_view name() const { return m_name; } std::string_view name() const { return m_name; }
std::string_view value() const { return m_value; } std::string_view value() const { return m_value; }
void value(const std::string &v) { m_value = v; } /// \brief replace the content of the stored value with \a v
void value(std::string_view v) { m_value = v; }
/// \brief empty means either null or unknown /// \brief empty means either null or unknown
bool empty() const { return m_value.empty(); } bool empty() const { return m_value.empty(); }
...@@ -126,8 +145,8 @@ class item ...@@ -126,8 +145,8 @@ class item
/// \brief returns true if the field contains '?' /// \brief returns true if the field contains '?'
bool is_unknown() const { return m_value == "?"; } bool is_unknown() const { return m_value == "?"; }
/// \brief the length of the value string
size_t length() const { return m_value.length(); } size_t length() const { return m_value.length(); }
// const char *c_str() const { return m_value.c_str(); }
private: private:
std::string_view m_name; std::string_view m_name;
...@@ -145,6 +164,7 @@ class item ...@@ -145,6 +164,7 @@ class item
struct item_value struct item_value
{ {
/// \brief constructor
item_value(uint16_t column_ix, uint16_t length) item_value(uint16_t column_ix, uint16_t length)
: m_next(nullptr) : m_next(nullptr)
, m_column_ix(column_ix) , m_column_ix(column_ix)
...@@ -167,14 +187,11 @@ struct item_value ...@@ -167,14 +187,11 @@ struct item_value
static constexpr size_t kBufferSize = sizeof(m_local_data); static constexpr size_t kBufferSize = sizeof(m_local_data);
// By using std::string_view instead of c_str we obain a
// nice performance gain since we avoid many calls to strlen.
std::string_view text() const std::string_view text() const
{ {
return {m_length >= kBufferSize ? m_data : m_local_data, m_length}; return { m_length >= kBufferSize ? m_data : m_local_data, m_length };
}
const char *c_str() const
{
return m_length >= kBufferSize ? m_data : m_local_data;
} }
}; };
...@@ -183,6 +200,9 @@ static_assert(sizeof(item_value) == 24, "sizeof(item_value) should be 24 bytes") ...@@ -183,6 +200,9 @@ static_assert(sizeof(item_value) == 24, "sizeof(item_value) should be 24 bytes")
// -------------------------------------------------------------------- // --------------------------------------------------------------------
// Transient object to access stored data // Transient object to access stored data
/// \brief This is \class item_handle, it is used to access
/// the data stored in \class item_value.
struct item_handle struct item_handle
{ {
public: public:
...@@ -193,7 +213,7 @@ struct item_handle ...@@ -193,7 +213,7 @@ struct item_handle
template <typename T> template <typename T>
item_handle &operator=(const T &value) item_handle &operator=(const T &value)
{ {
item v{"", value}; item v{ "", value };
assign_value(v); assign_value(v);
return *this; return *this;
} }
...@@ -266,17 +286,6 @@ struct item_handle ...@@ -266,17 +286,6 @@ struct item_handle
return txt.length() == 1 and txt.front() == '?'; return txt.length() == 1 and txt.front() == '?';
} }
// const char *c_str() const
// {
// for (auto iv = m_row_handle.m_head; iv != nullptr; iv = iv->m_next)
// {
// if (iv->m_column_ix == m_column)
// return iv->m_text;
// }
// return s_empty_result;
// }
std::string_view text() const; std::string_view text() const;
// bool operator!=(const std::string &s) const { return s != c_str(); } // bool operator!=(const std::string &s) const { return s != c_str(); }
...@@ -293,8 +302,6 @@ struct item_handle ...@@ -293,8 +302,6 @@ struct item_handle
row_handle &m_row_handle; row_handle &m_row_handle;
void assign_value(const item &value); void assign_value(const item &value);
static constexpr const char *s_empty_result = "";
}; };
// So sad that the gcc implementation of from_chars does not support floats yet... // So sad that the gcc implementation of from_chars does not support floats yet...
...@@ -465,7 +472,7 @@ struct item_handle::item_value_as<T, std::enable_if_t<std::is_same_v<T, std::str ...@@ -465,7 +472,7 @@ struct item_handle::item_value_as<T, std::enable_if_t<std::is_same_v<T, std::str
{ {
if (ref.empty()) if (ref.empty())
return {}; return {};
return {ref.text().data(), ref.text().size()}; return { ref.text().data(), ref.text().size() };
} }
static int compare(const item_handle &ref, const std::string &value, bool icase) static int compare(const item_handle &ref, const std::string &value, bool icase)
......
...@@ -1291,22 +1291,22 @@ void category::update_value(row *row, size_t column, std::string_view value, boo ...@@ -1291,22 +1291,22 @@ void category::update_value(row *row, size_t column, std::string_view value, boo
auto &col = m_columns[column]; auto &col = m_columns[column];
const char *oldValue = nullptr; std::string_view oldValue;
for (auto iv = row->m_head; iv != nullptr; iv = iv->m_next) for (auto iv = row->m_head; iv != nullptr; iv = iv->m_next)
{ {
assert(iv != iv->m_next and (iv->m_next == nullptr or iv != iv->m_next->m_next)); assert(iv != iv->m_next and (iv->m_next == nullptr or iv != iv->m_next->m_next));
if (iv->m_column_ix == column) if (iv->m_column_ix == column)
{ {
oldValue = iv->c_str(); oldValue = iv->text();
break; break;
} }
} }
if (oldValue != nullptr and value == oldValue) // no need to update if (value == oldValue) // no need to update
return; return;
std::string oldStrValue = oldValue ? oldValue : ""; std::string oldStrValue{ oldValue };
// check the value // check the value
if (col.m_validator and validate) if (col.m_validator and validate)
......
...@@ -31,8 +31,8 @@ ...@@ -31,8 +31,8 @@
#include <cif++.hpp> #include <cif++.hpp>
#include <cif++/parser.hpp>
#include <cif++/dictionary_parser.hpp> #include <cif++/dictionary_parser.hpp>
#include <cif++/parser.hpp>
namespace tt = boost::test_tools; namespace tt = boost::test_tools;
...@@ -78,23 +78,23 @@ bool init_unit_test() ...@@ -78,23 +78,23 @@ bool init_unit_test()
BOOST_AUTO_TEST_CASE(cc_1) BOOST_AUTO_TEST_CASE(cc_1)
{ {
std::tuple<std::string_view, float, char> tests[] = { std::tuple<std::string_view, float, char> tests[] = {
{"1.0", 1.0, 0}, { "1.0", 1.0, 0 },
{"1.0e10", 1.0e10, 0}, { "1.0e10", 1.0e10, 0 },
{"-1.1e10", -1.1e10, 0}, { "-1.1e10", -1.1e10, 0 },
{"-.2e11", -.2e11, 0}, { "-.2e11", -.2e11, 0 },
{"1.3e-10", 1.3e-10, 0}, { "1.3e-10", 1.3e-10, 0 },
{"1.0 ", 1.0, ' '}, { "1.0 ", 1.0, ' ' },
{"1.0e10 ", 1.0e10, ' '}, { "1.0e10 ", 1.0e10, ' ' },
{"-1.1e10 ", -1.1e10, ' '}, { "-1.1e10 ", -1.1e10, ' ' },
{"-.2e11 ", -.2e11, ' '}, { "-.2e11 ", -.2e11, ' ' },
{"1.3e-10 ", 1.3e-10, ' '}, { "1.3e-10 ", 1.3e-10, ' ' },
{"3.0", 3.0, 0}, { "3.0", 3.0, 0 },
{"3.0 ", 3.0, ' '}, { "3.0 ", 3.0, ' ' },
{"3.000000", 3.0, 0}, { "3.000000", 3.0, 0 },
{"3.000000 ", 3.0, ' '}, { "3.000000 ", 3.0, ' ' },
}; };
for (const auto &[txt, val, ch] : tests) for (const auto &[txt, val, ch] : tests)
...@@ -157,9 +157,9 @@ BOOST_AUTO_TEST_CASE(r_1) ...@@ -157,9 +157,9 @@ BOOST_AUTO_TEST_CASE(r_1)
{ {
cif::category c("foo"); cif::category c("foo");
c.emplace({ c.emplace({
{"f-1", 1}, { "f-1", 1 },
{"f-2", "two"}, { "f-2", "two" },
{"f-3", 3.0, 3}, { "f-3", 3.0, 3 },
}); });
auto row = c.front(); auto row = c.front();
...@@ -167,7 +167,7 @@ BOOST_AUTO_TEST_CASE(r_1) ...@@ -167,7 +167,7 @@ BOOST_AUTO_TEST_CASE(r_1)
BOOST_CHECK_EQUAL(row["f-2"].compare("two"), 0); BOOST_CHECK_EQUAL(row["f-2"].compare("two"), 0);
BOOST_CHECK_EQUAL(row["f-3"].compare(3.0), 0); // This fails when running in valgrind... sigh BOOST_CHECK_EQUAL(row["f-3"].compare(3.0), 0); // This fails when running in valgrind... sigh
const auto &[f1, f2, f3] = row.get<int,std::string,float>("f-1", "f-2", "f-3"); const auto &[f1, f2, f3] = row.get<int, std::string, float>("f-1", "f-2", "f-3");
BOOST_CHECK_EQUAL(f1, 1); BOOST_CHECK_EQUAL(f1, 1);
BOOST_CHECK_EQUAL(f2, "two"); BOOST_CHECK_EQUAL(f2, "two");
...@@ -194,8 +194,8 @@ BOOST_AUTO_TEST_CASE(r_2) ...@@ -194,8 +194,8 @@ BOOST_AUTO_TEST_CASE(r_2)
for (size_t i = 1; i < 256; ++i) for (size_t i = 1; i < 256; ++i)
{ {
c.emplace({{"id", i}, c.emplace({ { "id", i },
{"txt", std::string(i, 'x')}}); { "txt", std::string(i, 'x') } });
} }
} }
...@@ -203,13 +203,13 @@ BOOST_AUTO_TEST_CASE(c_1) ...@@ -203,13 +203,13 @@ BOOST_AUTO_TEST_CASE(c_1)
{ {
cif::category c("foo"); cif::category c("foo");
c.emplace({{"id", 1}, {"s", "aap"}}); c.emplace({ { "id", 1 }, { "s", "aap" } });
c.emplace({{"id", 2}, {"s", "noot"}}); c.emplace({ { "id", 2 }, { "s", "noot" } });
c.emplace({{"id", 3}, {"s", "mies"}}); c.emplace({ { "id", 3 }, { "s", "mies" } });
int n = 1; int n = 1;
const char *ts[] = {"aap", "noot", "mies"}; const char *ts[] = { "aap", "noot", "mies" };
for (auto r : c) for (auto r : c)
{ {
...@@ -244,16 +244,16 @@ BOOST_AUTO_TEST_CASE(c_1) ...@@ -244,16 +244,16 @@ BOOST_AUTO_TEST_CASE(c_1)
BOOST_AUTO_TEST_CASE(c_2) BOOST_AUTO_TEST_CASE(c_2)
{ {
std::tuple<int,const char*> D[] = { std::tuple<int, const char *> D[] = {
{1, "aap"}, { 1, "aap" },
{2, "noot"}, { 2, "noot" },
{3, "mies"} { 3, "mies" }
}; };
cif::category c("foo"); cif::category c("foo");
for (const auto &[id, s] : D) for (const auto &[id, s] : D)
c.emplace({ {"id", id}, { "s", s} }); c.emplace({ { "id", id }, { "s", s } });
BOOST_CHECK(not c.empty()); BOOST_CHECK(not c.empty());
BOOST_CHECK_EQUAL(c.size(), 3); BOOST_CHECK_EQUAL(c.size(), 3);
...@@ -284,22 +284,22 @@ BOOST_AUTO_TEST_CASE(c_2) ...@@ -284,22 +284,22 @@ BOOST_AUTO_TEST_CASE(c_2)
BOOST_AUTO_TEST_CASE(c_3) BOOST_AUTO_TEST_CASE(c_3)
{ {
std::tuple<int,const char*> D[] = { std::tuple<int, const char *> D[] = {
{1, "aap"}, { 1, "aap" },
{2, "noot"}, { 2, "noot" },
{3, "mies"} { 3, "mies" }
}; };
cif::category c("foo"); cif::category c("foo");
for (const auto &[id, s] : D) for (const auto &[id, s] : D)
c.emplace({ {"id", id}, { "s", s} }); c.emplace({ { "id", id }, { "s", s } });
cif::category c2("bar"); cif::category c2("bar");
for (auto r : c) for (auto r : c)
c2.emplace(r); c2.emplace(r);
// BOOST_CHECK(c == c2); // BOOST_CHECK(c == c2);
} }
...@@ -307,9 +307,9 @@ BOOST_AUTO_TEST_CASE(ci_1) ...@@ -307,9 +307,9 @@ BOOST_AUTO_TEST_CASE(ci_1)
{ {
cif::category c("foo"); cif::category c("foo");
c.emplace({{"id", 1}, {"s", "aap"}}); c.emplace({ { "id", 1 }, { "s", "aap" } });
c.emplace({{"id", 2}, {"s", "noot"}}); c.emplace({ { "id", 2 }, { "s", "noot" } });
c.emplace({{"id", 3}, {"s", "mies"}}); c.emplace({ { "id", 3 }, { "s", "mies" } });
cif::category::iterator i1 = c.begin(); cif::category::iterator i1 = c.begin();
cif::category::const_iterator i2 = c.cbegin(); cif::category::const_iterator i2 = c.cbegin();
...@@ -324,6 +324,37 @@ BOOST_AUTO_TEST_CASE(ci_1) ...@@ -324,6 +324,37 @@ BOOST_AUTO_TEST_CASE(ci_1)
BOOST_CHECK(i1 == i5); BOOST_CHECK(i1 == i5);
} }
BOOST_AUTO_TEST_CASE(os_1)
{
using namespace cif::literals;
using namespace std::literals;
std::tuple<int, const char *> D[] = {
{ 1, "aap" },
{ 2, "noot" },
{ 3, "mies" }
};
cif::category c("foo");
for (const auto &[id, s] : D)
c.emplace({ { "id", id }, { "s", s } });
for (auto rh : c)
{
rh["o"].os(1, ',', 2, ": ", rh.get<std::string>("s"));
}
for (const auto &[id, s] : D)
{
auto rh = c.find1("id"_key == id);
BOOST_CHECK_EQUAL(rh.get<int>("id"), id);
BOOST_CHECK_EQUAL(rh.get<std::string>("s"), s);
BOOST_CHECK_EQUAL(rh.get<std::string>("o"), "1,2: "s + s);
}
}
// -------------------------------------------------------------------- // --------------------------------------------------------------------
BOOST_AUTO_TEST_CASE(get_1) BOOST_AUTO_TEST_CASE(get_1)
...@@ -383,7 +414,7 @@ _test.name ...@@ -383,7 +414,7 @@ _test.name
auto &test = db["test"]; auto &test = db["test"];
BOOST_CHECK_EQUAL(test.size(), 3); BOOST_CHECK_EQUAL(test.size(), 3);
const char *ts[] = {"aap", "noot", "mies"}; const char *ts[] = { "aap", "noot", "mies" };
int n = 1; int n = 1;
for (const auto &[i, s] : test.rows<int, std::string>("id", "name")) for (const auto &[i, s] : test.rows<int, std::string>("id", "name"))
...@@ -405,6 +436,20 @@ _test.name ...@@ -405,6 +436,20 @@ _test.name
test.clear(); test.clear();
BOOST_CHECK(test.empty()); BOOST_CHECK(test.empty());
// fill again.
test.emplace({ { "id", "1" }, { "name", "aap" } });
test.emplace({ { "id", "2" }, { "name", "noot" } });
test.emplace({ { "id", "3" }, { "name", "mies" } });
n = 1;
for (const auto &[i, s] : test.rows<int, std::string>("id", "name"))
{
BOOST_CHECK_EQUAL(i, n);
BOOST_CHECK_EQUAL(s.compare(ts[n - 1]), 0);
++n;
}
} }
// -------------------------------------------------------------------- // --------------------------------------------------------------------
...@@ -637,10 +682,9 @@ _cat_2.desc ...@@ -637,10 +682,9 @@ _cat_2.desc
// { "desc", "moet fout gaan" } // { "desc", "moet fout gaan" }
// }), std::exception); // }), std::exception);
BOOST_CHECK_THROW(cat2.emplace({ BOOST_CHECK_THROW(cat2.emplace({ { "id", "vijf" }, // <- invalid value
{"id", "vijf"}, // <- invalid value { "parent_id", 2 },
{"parent_id", 2}, { "desc", "moet fout gaan" } }),
{"desc", "moet fout gaan"}}),
std::exception); std::exception);
} }
...@@ -755,19 +799,16 @@ mies Mies ...@@ -755,19 +799,16 @@ mies Mies
BOOST_CHECK_EQUAL(cat1.size(), 2); BOOST_CHECK_EQUAL(cat1.size(), 2);
// should fail with duplicate key: // should fail with duplicate key:
BOOST_CHECK_THROW(cat1.emplace({ BOOST_CHECK_THROW(cat1.emplace({ { "id", "aap" },
{"id", "aap"}, { "c", "2e-aap" } }),
{"c", "2e-aap"} std::exception);
}), std::exception);
cat1.erase(cif::key("id") == "aap"); cat1.erase(cif::key("id") == "aap");
BOOST_CHECK_EQUAL(cat1.size(), 1); BOOST_CHECK_EQUAL(cat1.size(), 1);
cat1.emplace({ cat1.emplace({ { "id", "aap" },
{"id", "aap"}, { "c", "2e-aap" } });
{"c", "2e-aap"}
});
BOOST_CHECK_EQUAL(cat1.size(), 2); BOOST_CHECK_EQUAL(cat1.size(), 2);
} }
...@@ -965,12 +1006,12 @@ _cat_2.desc ...@@ -965,12 +1006,12 @@ _cat_2.desc
cat1.erase(cif::key("id") == 10); cat1.erase(cif::key("id") == 10);
BOOST_CHECK_EQUAL(cat1.size(), 2); BOOST_CHECK_EQUAL(cat1.size(), 2);
BOOST_CHECK_EQUAL(cat2.size(), 3); // TODO: Is this really what we want? BOOST_CHECK_EQUAL(cat2.size(), 3); // TODO: Is this really what we want?
cat1.erase(cif::key("id") == 20); cat1.erase(cif::key("id") == 20);
BOOST_CHECK_EQUAL(cat1.size(), 1); BOOST_CHECK_EQUAL(cat1.size(), 1);
BOOST_CHECK_EQUAL(cat2.size(), 2); // TODO: Is this really what we want? BOOST_CHECK_EQUAL(cat2.size(), 2); // TODO: Is this really what we want?
} }
// -------------------------------------------------------------------- // --------------------------------------------------------------------
...@@ -1364,7 +1405,7 @@ _cat_2.parent_id3 ...@@ -1364,7 +1405,7 @@ _cat_2.parent_id3
std::transform(CR2set.begin(), CR2set.end(), std::back_inserter(CRids), [](cif::row_handle r) std::transform(CR2set.begin(), CR2set.end(), std::back_inserter(CRids), [](cif::row_handle r)
{ return r["id"].as<int>(); }); { return r["id"].as<int>(); });
std::sort(CRids.begin(), CRids.end()); std::sort(CRids.begin(), CRids.end());
BOOST_CHECK(CRids == std::vector<int>({4, 5, 6})); BOOST_CHECK(CRids == std::vector<int>({ 4, 5, 6 }));
// check a rename in parent and child // check a rename in parent and child
...@@ -2098,7 +2139,8 @@ boo.data_.whatever ...@@ -2098,7 +2139,8 @@ boo.data_.whatever
auto &db1 = data1.front(); auto &db1 = data1.front();
auto &test1 = db1["test"]; auto &test1 = db1["test"];
struct T { struct T
{
const char *s; const char *s;
bool q; bool q;
} kS[] = { } kS[] = {
...@@ -2154,13 +2196,15 @@ There it was! ...@@ -2154,13 +2196,15 @@ There it was!
auto &db1 = data1.front(); auto &db1 = data1.front();
auto &test1 = db1["test"]; auto &test1 = db1["test"];
struct T { struct T
{
const char *s; const char *s;
bool q; bool q;
} kS[] = { } kS[] = {
{ "A very, very loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong line", false }, { "A very, very loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong line", false },
{ R"(A line with a newline, look: { R"(A line with a newline, look:
There it was!)", false} There it was!)",
false }
}; };
BOOST_CHECK_EQUAL(test1.size(), sizeof(kS) / sizeof(T)); BOOST_CHECK_EQUAL(test1.size(), sizeof(kS) / sizeof(T));
...@@ -2192,7 +2236,6 @@ There it was!)", false} ...@@ -2192,7 +2236,6 @@ There it was!)", false}
} }
} }
BOOST_AUTO_TEST_CASE(trim_test) BOOST_AUTO_TEST_CASE(trim_test)
{ {
BOOST_CHECK_EQUAL(cif::trim_copy("aap"), "aap"); BOOST_CHECK_EQUAL(cif::trim_copy("aap"), "aap");
...@@ -2215,24 +2258,53 @@ BOOST_AUTO_TEST_CASE(trim_test) ...@@ -2215,24 +2258,53 @@ BOOST_AUTO_TEST_CASE(trim_test)
std::string s; std::string s;
s = "aap"; cif::trim(s); BOOST_CHECK_EQUAL(s, "aap"); s = "aap";
s = " aap"; cif::trim(s); BOOST_CHECK_EQUAL(s, "aap"); cif::trim(s);
s = " aap "; cif::trim(s); BOOST_CHECK_EQUAL(s, "aap"); BOOST_CHECK_EQUAL(s, "aap");
s = "aap "; cif::trim(s); BOOST_CHECK_EQUAL(s, "aap"); s = " aap";
s = " aap "; cif::trim(s); BOOST_CHECK_EQUAL(s, "aap"); cif::trim(s);
BOOST_CHECK_EQUAL(s, "aap");
s = "aap"; cif::trim_left(s); BOOST_CHECK_EQUAL(s, "aap"); s = " aap ";
s = " aap"; cif::trim_left(s); BOOST_CHECK_EQUAL(s, "aap"); cif::trim(s);
s = " aap "; cif::trim_left(s); BOOST_CHECK_EQUAL(s, "aap "); BOOST_CHECK_EQUAL(s, "aap");
s = "aap "; cif::trim_left(s); BOOST_CHECK_EQUAL(s, "aap "); s = "aap ";
s = "aap "; cif::trim_left(s); BOOST_CHECK_EQUAL(s, "aap "); cif::trim(s);
BOOST_CHECK_EQUAL(s, "aap");
s = "aap"; cif::trim_right(s); BOOST_CHECK_EQUAL(s, "aap"); s = " aap ";
s = " aap"; cif::trim_right(s); BOOST_CHECK_EQUAL(s, " aap"); cif::trim(s);
s = " aap "; cif::trim_right(s); BOOST_CHECK_EQUAL(s, " aap"); BOOST_CHECK_EQUAL(s, "aap");
s = "aap "; cif::trim_right(s); BOOST_CHECK_EQUAL(s, "aap");
s = " aap "; cif::trim_right(s); BOOST_CHECK_EQUAL(s, " aap"); s = "aap";
cif::trim_left(s);
BOOST_CHECK_EQUAL(s, "aap");
s = " aap";
cif::trim_left(s);
BOOST_CHECK_EQUAL(s, "aap");
s = " aap ";
cif::trim_left(s);
BOOST_CHECK_EQUAL(s, "aap ");
s = "aap ";
cif::trim_left(s);
BOOST_CHECK_EQUAL(s, "aap ");
s = "aap ";
cif::trim_left(s);
BOOST_CHECK_EQUAL(s, "aap ");
s = "aap";
cif::trim_right(s);
BOOST_CHECK_EQUAL(s, "aap");
s = " aap";
cif::trim_right(s);
BOOST_CHECK_EQUAL(s, " aap");
s = " aap ";
cif::trim_right(s);
BOOST_CHECK_EQUAL(s, " aap");
s = "aap ";
cif::trim_right(s);
BOOST_CHECK_EQUAL(s, "aap");
s = " aap ";
cif::trim_right(s);
BOOST_CHECK_EQUAL(s, " aap");
} }
BOOST_AUTO_TEST_CASE(split_test) BOOST_AUTO_TEST_CASE(split_test)
...@@ -2241,30 +2313,30 @@ BOOST_AUTO_TEST_CASE(split_test) ...@@ -2241,30 +2313,30 @@ BOOST_AUTO_TEST_CASE(split_test)
v = cif::split<>("aap;noot;mies", ";"); v = cif::split<>("aap;noot;mies", ";");
t = std::vector<std::string_view>{ "aap", "noot", "mies" }; t = std::vector<std::string_view>{ "aap", "noot", "mies" };
BOOST_CHECK(v == t); BOOST_CHECK(v == t);
v = cif::split("aap;noot,mies", ";,"); v = cif::split("aap;noot,mies", ";,");
// t = std::vector<std::string>{ "aap", "noot", "mies" }; // t = std::vector<std::string>{ "aap", "noot", "mies" };
BOOST_CHECK(v == t); BOOST_CHECK(v == t);
v = cif::split(";aap;noot,mies;", ";,"); v = cif::split(";aap;noot,mies;", ";,");
t = std::vector<std::string_view>{ "", "aap", "noot", "mies", "" }; t = std::vector<std::string_view>{ "", "aap", "noot", "mies", "" };
BOOST_CHECK(v == t); BOOST_CHECK(v == t);
v = cif::split(";aap;noot,mies;", ";,", true); v = cif::split(";aap;noot,mies;", ";,", true);
t = std::vector<std::string_view>{ "aap", "noot", "mies" }; t = std::vector<std::string_view>{ "aap", "noot", "mies" };
BOOST_CHECK(v == t); BOOST_CHECK(v == t);
} }
BOOST_AUTO_TEST_CASE(join_test) BOOST_AUTO_TEST_CASE(join_test)
{ {
BOOST_CHECK_EQUAL(cif::join(std::vector<std::string>{"aap"}, ", "), "aap"); BOOST_CHECK_EQUAL(cif::join(std::vector<std::string>{ "aap" }, ", "), "aap");
BOOST_CHECK_EQUAL(cif::join(std::vector<std::string>{"aap", "noot"}, ", "), "aap, noot"); BOOST_CHECK_EQUAL(cif::join(std::vector<std::string>{ "aap", "noot" }, ", "), "aap, noot");
BOOST_CHECK_EQUAL(cif::join(std::vector<std::string>{"aap", "noot", "mies"}, ", "), "aap, noot, mies"); BOOST_CHECK_EQUAL(cif::join(std::vector<std::string>{ "aap", "noot", "mies" }, ", "), "aap, noot, mies");
} }
BOOST_AUTO_TEST_CASE(replace_all_test) BOOST_AUTO_TEST_CASE(replace_all_test)
...@@ -2387,9 +2459,9 @@ _cat_1.name ...@@ -2387,9 +2459,9 @@ _cat_1.name
int n = 1; int n = 1;
const char *ts[] = {"Aap", "Noot", "Mies"}; const char *ts[] = { "Aap", "Noot", "Mies" };
for (const auto &[id, name] : cat1.rows<int,std::string>("id", "name")) for (const auto &[id, name] : cat1.rows<int, std::string>("id", "name"))
{ {
BOOST_CHECK_EQUAL(id, n); BOOST_CHECK_EQUAL(id, n);
BOOST_CHECK_EQUAL(name, ts[n - 1]); BOOST_CHECK_EQUAL(name, ts[n - 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