Commit 24fa80ba by Maarten L. Hekkelman

parser just started working again, a bit

parent 3999d792
...@@ -432,22 +432,190 @@ class category_t ...@@ -432,22 +432,190 @@ class category_t
if (result == m_columns.size()) if (result == m_columns.size())
{ {
const ValidateItem *itemValidator = nullptr; const ValidateItem *item_validator = nullptr;
// if (mCatValidator != nullptr) // if (mCatValidator != nullptr)
// { // {
// itemValidator = mCatValidator->getValidatorForItem(column_name); // item_validator = mCatValidator->getValidatorForItem(column_name);
// if (itemValidator == nullptr) // if (item_validator == nullptr)
// mValidator->reportError("tag " + std::string(column_name) + " not allowed in Category " + mName, false); // m_validator->reportError("tag " + std::string(column_name) + " not allowed in Category " + mName, false);
// } // }
m_columns.emplace_back(column_name, itemValidator); m_columns.emplace_back(column_name, item_validator);
} }
return result; return result;
} }
private: private:
void update_value(row *row, size_t column, std::string_view value, bool updateLinked, bool validate = true)
{
auto &col = m_columns[column];
const char *oldValue = nullptr;
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));
if (iv->m_column_ix == column)
{
oldValue = iv->c_str();
break;
}
}
if (oldValue != nullptr and value == oldValue) // no need to update
return;
std::string oldStrValue = oldValue ? oldValue : "";
// // check the value
// if (col.m_validator and validate)
// (*col.m_validator)(value);
// If the field is part of the Key for this Category, remove it from the index
// before updating
bool reinsert = false;
// if (updateLinked and // an update of an Item's value
// cat->mIndex != nullptr and cat->keyFieldsByIndex().count(column))
// {
// reinsert = cat->mIndex->find(mData);
// if (reinsert)
// cat->mIndex->erase(mData);
// }
// first remove old value with cix
if (row->m_head == nullptr)
; // nothing to do
else if (row->m_head->m_column_ix == column)
{
auto iv = row->m_head;
row->m_head = iv->m_next;
iv->m_next = nullptr;
delete_item(iv);
}
else
{
for (auto iv = row->m_head; iv->m_next != nullptr; iv = iv->m_next)
{
if (iv->m_next->m_column_ix != column)
continue;
auto nv = iv->m_next;
iv->m_next = nv->m_next;
nv->m_next = nullptr;
delete_item(nv);
break;
}
}
if (not value.empty())
{
auto nv = create_item(column, value);
if (row->m_head == nullptr)
row->m_head = nv;
else
{
auto iv = row->m_head;
while (iv->m_next != nullptr)
iv = iv->m_next;
iv->m_next = nv;
}
}
// if (reinsert)
// cat->mIndex->insert(mData);
// // see if we need to update any child categories that depend on this value
// auto iv = col.m_validator;
// if (not skipUpdateLinked and iv != nullptr and mCascade)
// {
// for (auto &&[childCat, linked] : cat->mChildLinks)
// {
// if (find(linked->mParentKeys.begin(), linked->mParentKeys.end(), iv->mTag) == linked->mParentKeys.end())
// continue;
// Condition cond;
// std::string childTag;
// for (size_t ix = 0; ix < linked->mParentKeys.size(); ++ix)
// {
// std::string pk = linked->mParentKeys[ix];
// std::string ck = linked->mChildKeys[ix];
// // TODO add code to *NOT* test mandatory fields for Empty
// if (pk == iv->mTag)
// {
// childTag = ck;
// cond = std::move(cond) && Key(ck) == oldStrValue;
// }
// else
// {
// const char *pk_value = (*this)[pk].c_str();
// if (*pk_value == 0)
// cond = std::move(cond) && Key(ck) == Empty();
// else
// cond = std::move(cond) && ((Key(ck) == pk_value) or Key(ck) == Empty());
// }
// }
// auto rows = childCat->find(std::move(cond));
// if (rows.empty())
// continue;
// // if (cif::VERBOSE > 2)
// // {
// // std::cerr << "Parent: " << linked->mParentCategory << " Child: " << linked->mChildCategory << std::endl
// // << cond << std::endl;
// // }
// // Now, suppose there are already rows in child that conform to the new value,
// // we then skip this renam
// Condition cond_n;
// for (size_t ix = 0; ix < linked->mParentKeys.size(); ++ix)
// {
// std::string pk = linked->mParentKeys[ix];
// std::string ck = linked->mChildKeys[ix];
// // TODO add code to *NOT* test mandatory fields for Empty
// if (pk == iv->mTag)
// cond_n = std::move(cond_n) && Key(ck) == value;
// else
// {
// const char *pk_value = (*this)[pk].c_str();
// if (*pk_value == 0)
// cond_n = std::move(cond_n) && Key(ck) == Empty();
// else
// cond_n = std::move(cond_n) && ((Key(ck) == pk_value) or Key(ck) == Empty());
// }
// }
// auto rows_n = childCat->find(std::move(cond_n));
// if (not rows_n.empty())
// {
// if (cif::VERBOSE > 0)
// std::cerr << "Will not rename in child category since there are already rows that link to the parent" << std::endl;
// continue;
// }
// for (auto &cr : rows)
// cr.assign(childTag, value, false);
// }
// }
}
private:
using char_allocator_type = typename std::allocator_traits<Alloc>::template rebind_alloc<char>; using char_allocator_type = typename std::allocator_traits<Alloc>::template rebind_alloc<char>;
using char_allocator_traits = std::allocator_traits<char_allocator_type>; using char_allocator_traits = std::allocator_traits<char_allocator_type>;
......
...@@ -34,17 +34,22 @@ namespace cif::v2 ...@@ -34,17 +34,22 @@ namespace cif::v2
// -------------------------------------------------------------------- // --------------------------------------------------------------------
template < template <
typename Category = category, typename Alloc = std::allocator<void>,
typename Alloc = std::allocator<Category>> typename Category = category_t<Alloc>>
class datablock_t : public std::list<Category, Alloc> class datablock_t
{ {
public: public:
using category_type = Category; using category_type = Category;
using base_type = std::list<category_type, Alloc>;
using allocator_type = Alloc; using allocator_type = Alloc;
datablock_t(const std::string &name, const allocator_type &alloc = allocator_type()) using category_allocator_type = typename std::allocator_traits<Alloc>::template rebind_alloc<category_type>;
: base_type(alloc) using category_type_list = std::list<category_type, category_allocator_type>;
using iterator = category_type_list::iterator;
using const_iterator = category_type_list::const_iterator;
datablock_t(std::string_view name, const allocator_type &alloc = allocator_type())
: m_categories(alloc)
, m_name(name) , m_name(name)
{ {
} }
...@@ -53,19 +58,19 @@ class datablock_t : public std::list<Category, Alloc> ...@@ -53,19 +58,19 @@ class datablock_t : public std::list<Category, Alloc>
datablock_t(datablock_t &&) = default; datablock_t(datablock_t &&) = default;
template <typename Alloc2> // template <typename Alloc2>
datablock_t(const datablock_t &db, const Alloc2 &a) // datablock_t(const datablock_t &db, const Alloc2 &a)
: base_type(db, a) // : m_categories(db, a)
, m_name(db.m_name) // , m_name(db.m_name)
{ // {
} // }
template <typename Alloc2> // template <typename Alloc2>
datablock_t(datablock_t &&db, const Alloc2 &a) // datablock_t(datablock_t &&db, const Alloc2 &a)
: base_type(std::move(db), a) // : base_type(std::move(db), a)
, m_name(db.m_name) // , m_name(db.m_name)
{ // {
} // }
datablock_t &operator=(const datablock_t &) = default; datablock_t &operator=(const datablock_t &) = default;
datablock_t &operator=(datablock_t &&) = default; datablock_t &operator=(datablock_t &&) = default;
...@@ -78,19 +83,57 @@ class datablock_t : public std::list<Category, Alloc> ...@@ -78,19 +83,57 @@ class datablock_t : public std::list<Category, Alloc>
category_type &operator[](std::string_view name) category_type &operator[](std::string_view name)
{ {
auto i = std::find_if(this->begin(), this->end(), [name](const category_type &c) auto i = std::find_if(m_categories.begin(), m_categories.end(), [name](const category_type &c)
{ return iequals(c.name(), name); }); { return iequals(c.name(), name); });
if (i == this->end())
i = this->emplace(name); if (i != m_categories.end())
return *i; return *i;
m_categories.emplace_back(name);
return m_categories.back();
} }
const category_type &operator[](std::string_view name) const const category_type &operator[](std::string_view name) const
{ {
static const category_type s_empty; static const category_type s_empty;
auto i = std::find_if(this->begin(), this->end(), [name](const category_type &c) auto i = std::find_if(m_categories.begin(), m_categories.end(), [name](const category_type &c)
{ return iequals(c.name(), name); }); { return iequals(c.name(), name); });
return i == this->end() ? s_empty : *i; return i == m_categories.end() ? s_empty : *i;
}
std::tuple<iterator, bool> emplace(std::string_view name)
{
bool is_new = true;
auto i = m_categories.begin();
while (i != m_categories.end())
{
if (iequals(name, i->name()))
{
is_new = false;
if (i != m_categories.begin())
{
auto n = std::next(i);
m_categories.splice(m_categories.begin(), m_categories, i, n);
}
break;
}
++i;
}
if (is_new)
{
m_categories.emplace(m_categories.begin(), name);
// m_categories.emplace(begin(), *this, std::string(name), mValidator);
// for (auto &cat : mCategories)
// cat.updateLinks();
}
return std::make_tuple(m_categories.begin(), is_new);
} }
void write(std::ostream &os) const void write(std::ostream &os) const
...@@ -104,7 +147,7 @@ class datablock_t : public std::list<Category, Alloc> ...@@ -104,7 +147,7 @@ class datablock_t : public std::list<Category, Alloc>
// and if it exists, _AND_ we have a Validator, write out the // and if it exists, _AND_ we have a Validator, write out the
// audit_conform record. // audit_conform record.
for (auto &cat : *this) for (auto &cat : m_categories)
{ {
if (cat.name() != "entry") if (cat.name() != "entry")
continue; continue;
...@@ -122,7 +165,7 @@ class datablock_t : public std::list<Category, Alloc> ...@@ -122,7 +165,7 @@ class datablock_t : public std::list<Category, Alloc>
break; break;
} }
for (auto &cat : *this) for (auto &cat : m_categories)
{ {
if (cat.name() != "entry" and cat.name() != "audit_conform") if (cat.name() != "entry" and cat.name() != "audit_conform")
cat.write(os); cat.write(os);
...@@ -136,6 +179,7 @@ class datablock_t : public std::list<Category, Alloc> ...@@ -136,6 +179,7 @@ class datablock_t : public std::list<Category, Alloc>
} }
private: private:
category_type_list m_categories;
std::string m_name; std::string m_name;
}; };
......
...@@ -27,6 +27,7 @@ ...@@ -27,6 +27,7 @@
#pragma once #pragma once
#include "datablock.hpp" #include "datablock.hpp"
#include "parser.hpp"
namespace cif::v2 namespace cif::v2
{ {
...@@ -34,25 +35,121 @@ namespace cif::v2 ...@@ -34,25 +35,121 @@ namespace cif::v2
// -------------------------------------------------------------------- // --------------------------------------------------------------------
template < template <
typename Datablock = datablock, typename Alloc = std::allocator<void>,
typename Alloc = std::allocator<Datablock>> typename Datablock = datablock_t<Alloc>,
class file_t : public std::list<Datablock, Alloc> typename Category = typename Datablock::category_type>
class file_t
{ {
public: public:
using value_type = Datablock;
using base_type = std::list<value_type, Alloc>;
using allocator_type = Alloc; using allocator_type = Alloc;
using datablock_type = Datablock;
using category_type = typename datablock_type::category_type;
using datablock_allocator_type = typename std::allocator_traits<Alloc>::template rebind_alloc<datablock_type>;
using datablock_list = std::list<datablock_type, datablock_allocator_type>;
using value_type = datablock_list::value_type;
using reference = datablock_list::reference;
using pointer = datablock_list::pointer;
using iterator = datablock_list::iterator;
using const_iterator = datablock_list::const_iterator;
using parser_type = parser_t<file_t, datablock_type, category_type>;
file_t() = default; file_t() = default;
file_t(const allocator_type &a = allocator_type())
: m_datablocks(a)
{
}
file_t(std::istream &is, const allocator_type &alloc = allocator_type()) file_t(std::istream &is, const allocator_type &alloc = allocator_type())
: m_datablocks(alloc)
{ {
load(is);
} }
file_t(const file_t &) = default; file_t(const file_t &) = default;
file_t(file_t &&) = default; file_t(file_t &&) = default;
file_t &operator=(const file_t &) = default; file_t &operator=(const file_t &) = default;
file_t &operator=(file_t &&) = default; file_t &operator=(file_t &&) = default;
datablock_type &operator[](std::string_view name)
{
auto i = std::find_if(m_datablocks.begin(), m_datablocks.end(), [name](const datablock_type &c)
{ return iequals(c.name(), name); });
if (i != m_datablocks.end())
return *i;
m_datablocks.emplace_back(name);
return m_datablocks.back();
}
const datablock_type &operator[](std::string_view name) const
{
static const datablock_type s_empty;
auto i = std::find_if(m_datablocks.begin(), m_datablocks.end(), [name](const datablock_type &c)
{ return iequals(c.name(), name); });
return i == m_datablocks.end() ? s_empty : *i;
}
std::tuple<iterator, bool> emplace(std::string_view name)
{
bool is_new = true;
auto i = m_datablocks.begin();
while (i != m_datablocks.end())
{
if (iequals(name, i->name()))
{
is_new = false;
if (i != m_datablocks.begin())
{
auto n = std::next(i);
m_datablocks.splice(m_datablocks.begin(), m_datablocks, i, n);
}
break;
}
++i;
}
if (is_new)
m_datablocks.emplace(m_datablocks.begin(), name);
return std::make_tuple(m_datablocks.begin(), is_new);
}
bool empty() const { return m_datablocks.empty(); }
size_t size() const { return m_datablocks.size(); }
reference front() { return m_datablocks.front(); }
reference back() { return m_datablocks.back(); }
void load(std::istream &is)
{
// auto saved = mValidator;
// setValidator(nullptr);
parser_type p(is, *this);
p.parseFile();
// if (saved != nullptr)
// {
// setValidator(saved);
// (void)isValid();
// }
}
private:
datablock_list m_datablocks;
}; };
using file = file_t<>; using file = file_t<>;
......
...@@ -66,7 +66,7 @@ class item ...@@ -66,7 +66,7 @@ class item
auto r = cif::to_chars(m_buffer, m_buffer + sizeof(m_buffer) - 1, value, cif::chars_format::fixed, precision); auto r = cif::to_chars(m_buffer, m_buffer + sizeof(m_buffer) - 1, value, cif::chars_format::fixed, precision);
if (r.ec != std::errc()) if (r.ec != std::errc())
throw std::runtime_error("Could not format number"); throw std::runtime_error("Could not format number");
assert(r.ptr >= m_buffer and r.ptr < m_buffer + sizeof(m_buffer)); assert(r.ptr >= m_buffer and r.ptr < m_buffer + sizeof(m_buffer));
*r.ptr = 0; *r.ptr = 0;
m_value = std::string_view(m_buffer, r.ptr - m_buffer); m_value = std::string_view(m_buffer, r.ptr - m_buffer);
...@@ -94,7 +94,7 @@ class item ...@@ -94,7 +94,7 @@ class item
auto r = std::to_chars(m_buffer, m_buffer + sizeof(m_buffer) - 1, value); auto r = std::to_chars(m_buffer, m_buffer + sizeof(m_buffer) - 1, value);
if (r.ec != std::errc()) if (r.ec != std::errc())
throw std::runtime_error("Could not format number"); throw std::runtime_error("Could not format number");
assert(r.ptr >= m_buffer and r.ptr < m_buffer + sizeof(m_buffer)); assert(r.ptr >= m_buffer and r.ptr < m_buffer + sizeof(m_buffer));
*r.ptr = 0; *r.ptr = 0;
m_value = std::string_view(m_buffer, r.ptr - m_buffer); m_value = std::string_view(m_buffer, r.ptr - m_buffer);
...@@ -134,44 +134,52 @@ class item ...@@ -134,44 +134,52 @@ class item
private: private:
std::string_view m_name; std::string_view m_name;
std::string_view m_value; std::string_view m_value;
char m_buffer[64]; // TODO: optimize this magic number, might be too large char m_buffer[64]; // TODO: optimize this magic number, might be too large
}; };
// -------------------------------------------------------------------- // --------------------------------------------------------------------
// Transient object to access stored data // Transient object to access stored data
template <typename Row> template <typename RowHandle>
struct item_handle struct item_handle
{ {
using row_type = Row; using row_handle_type = RowHandle;
public: public:
// conversion helper class // conversion helper class
template <typename T, typename = void> template <typename T, typename = void>
struct item_value_as; struct item_value_as;
template <typename T, std::enable_if_t<std::is_arithmetic_v<T>, int> = 0> template <typename T>
item_handle &operator=(const T &value) item_handle &operator=(const T &value)
{ {
this->operator=(std::to_string(value)); item v{"", value};
m_row_handle.assign(m_column, v.value(), false);
return *this; return *this;
} }
template <typename T> // template <typename T, std::enable_if_t<std::is_arithmetic_v<T>, int> = 0>
item_handle &operator=(const std::optional<T> &value) // item_handle &operator=(const T &value)
{ // {
if (value) // this->operator=(std::to_string(value));
this->operator=(*value); // return *this;
else // }
this->operator=("?");
return *this;
}
item_handle &operator=(const std::string &value) // template <typename T>
{ // item_handle &operator=(const std::optional<T> &value)
m_row.assign(m_column, value, false); // {
return *this; // if (value)
} // this->operator=(*value);
// else
// this->operator=("?");
// return *this;
// }
// item_handle &operator=(std::string_view value)
// {
// m_row_handle.assign(m_column, value, false);
// return *this;
// }
template <typename... Ts> template <typename... Ts>
void os(const Ts &...v) void os(const Ts &...v)
...@@ -227,7 +235,7 @@ struct item_handle ...@@ -227,7 +235,7 @@ struct item_handle
// const char *c_str() const // const char *c_str() const
// { // {
// for (auto iv = m_row.m_head; iv != nullptr; iv = iv->m_next) // for (auto iv = m_row_handle.m_head; iv != nullptr; iv = iv->m_next)
// { // {
// if (iv->m_column_ix == m_column) // if (iv->m_column_ix == m_column)
// return iv->m_text; // return iv->m_text;
...@@ -238,7 +246,7 @@ struct item_handle ...@@ -238,7 +246,7 @@ struct item_handle
std::string_view text() const std::string_view text() const
{ {
for (auto iv = m_row.m_head; iv != nullptr; iv = iv->m_next) for (auto iv = m_row_handle.m_row->m_head; iv != nullptr; iv = iv->m_next)
{ {
if (iv->m_column_ix == m_column) if (iv->m_column_ix == m_column)
return iv->text(); return iv->text();
...@@ -250,15 +258,15 @@ struct item_handle ...@@ -250,15 +258,15 @@ struct item_handle
// bool operator!=(const std::string &s) const { return s != c_str(); } // bool operator!=(const std::string &s) const { return s != c_str(); }
// bool operator==(const std::string &s) const { return s == c_str(); } // bool operator==(const std::string &s) const { return s == c_str(); }
item_handle(uint16_t column, row_type &row) item_handle(uint16_t column, row_handle_type &row)
: m_column(column) : m_column(column)
, m_row(row) , m_row_handle(row)
{ {
} }
private: private:
uint16_t m_column; uint16_t m_column;
row_type &m_row; row_handle_type &m_row_handle;
// bool mConst = false; // bool mConst = false;
static constexpr const char *s_empty_result = ""; static constexpr const char *s_empty_result = "";
......
...@@ -55,6 +55,8 @@ class iterator_impl ...@@ -55,6 +55,8 @@ class iterator_impl
using pointer = std::conditional_t<N == 0, row_handle_type, value_type *>; using pointer = std::conditional_t<N == 0, row_handle_type, value_type *>;
using reference = std::conditional_t<N == 0, row_handle_type, value_type &>; using reference = std::conditional_t<N == 0, row_handle_type, value_type &>;
iterator_impl() = default;
iterator_impl(const iterator_impl &rhs) = default; iterator_impl(const iterator_impl &rhs) = default;
template<typename C2, typename... T2s> template<typename C2, typename... T2s>
...@@ -188,8 +190,8 @@ class iterator_impl ...@@ -188,8 +190,8 @@ class iterator_impl
return {}; return {};
} }
category_type *m_category; category_type *m_category = nullptr;
row_type *m_current; row_type *m_current = nullptr;
value_type m_value; value_type m_value;
std::array<size_t, N> m_column_ix; std::array<size_t, N> m_column_ix;
}; };
......
...@@ -120,9 +120,14 @@ class row_handle ...@@ -120,9 +120,14 @@ class row_handle
using category_type = Category; using category_type = Category;
using row_type = std::conditional_t<std::is_const_v<category_type>, const typename category_type::row, typename category_type::row>; using row_type = std::conditional_t<std::is_const_v<category_type>, const typename category_type::row, typename category_type::row>;
using item_handle_type = item_handle<row_handle>;
template <typename> template <typename>
friend class row_handle; friend class row_handle;
template <typename>
friend class item_handle;
row_handle() = default; row_handle() = default;
row_handle(const row_handle &) = default; row_handle(const row_handle &) = default;
...@@ -149,24 +154,24 @@ class row_handle ...@@ -149,24 +154,24 @@ class row_handle
return m_cat != nullptr and m_row != nullptr; return m_cat != nullptr and m_row != nullptr;
} }
item_handle<row_type> operator[](uint32_t column_ix) item_handle_type operator[](uint32_t column_ix)
{ {
return item_handle<row_type>(column_ix, *m_row); return item_handle_type(column_ix, *this);
} }
const item_handle<const row_type> operator[](uint32_t column_ix) const const item_handle_type operator[](uint32_t column_ix) const
{ {
return item_handle<const row_type>(column_ix, *m_row); return item_handle_type(column_ix, const_cast<row_handle &>(*this));
} }
item_handle<row_type> operator[](std::string_view column_name) item_handle_type operator[](std::string_view column_name)
{ {
return item_handle<row_type>(get_column_ix(column_name), *m_row); return item_handle_type(add_column(column_name), *this);
} }
const item_handle<const row_type> operator[](std::string_view column_name) const const item_handle_type operator[](std::string_view column_name) const
{ {
return item_handle<const row_type>(get_column_ix(column_name), *m_row); return item_handle_type(get_column_ix(column_name), *this);
} }
template <typename... Ts, size_t N> template <typename... Ts, size_t N>
...@@ -186,12 +191,85 @@ class row_handle ...@@ -186,12 +191,85 @@ class row_handle
return detail::get_row_result<category_type, C...>(*this, {get_column_ix(columns)...}); return detail::get_row_result<category_type, C...>(*this, {get_column_ix(columns)...});
} }
void assign(const std::vector<item> &values)
{
// std::map<std::string, std::tuple<size_t, std::string, std::string>> changed;
for (auto &value : values)
{
assign(value, true);
// auto columnIx = cat->add_column(value.name());
// auto &col = cat->m_columns[columnIx];
// std::string tag = col.mValidator ? col.mValidator->mTag : std::to_string(columnIx);
// changed[tag] = std::make_tuple(columnIx, operator[](columnIx).c_str(), value.value());
// assign(columnIx, value.value(), true);
}
// // see if we need to update any child categories that depend on these values
// // auto iv = col.mValidator;
// if (mCascade)
// {
// for (auto &&[childCat, linked] : cat->mChildLinks)
// {
// Condition cond;
// std::string childTag;
// std::vector<Item> newValues;
// for (size_t ix = 0; ix < linked->mParentKeys.size(); ++ix)
// {
// std::string pk = linked->mParentKeys[ix];
// std::string ck = linked->mChildKeys[ix];
// if (changed.count(pk) > 0)
// {
// childTag = ck;
// cond = std::move(cond) && (Key(ck) == std::get<1>(changed[pk]));
// newValues.emplace_back(ck, std::get<2>(changed[pk]));
// }
// else
// {
// const char *value = (*this)[pk].c_str();
// cond = std::move(cond) && (Key(ck) == value);
// }
// }
// auto rows = childCat->find(std::move(cond));
// for (auto &cr : rows)
// cr.assign(newValues);
// }
// }
}
void assign(std::string_view name, std::string_view value, bool updateLinked, bool validate = true)
{
assign(m_cat->add_column(name), value, updateLinked, validate);
}
void assign(size_t column, std::string_view value, bool updateLinked, bool validate = true)
{
m_cat->update_value(m_row, column, value, updateLinked, validate);
}
private: private:
uint32_t get_column_ix(std::string_view name) const uint16_t get_column_ix(std::string_view name) const
{ {
return m_cat->get_column_ix(name); return m_cat->get_column_ix(name);
} }
uint16_t add_column(std::string_view name)
{
return m_cat->add_column(name);
}
void assign(const item &i, bool updateLinked)
{
assign(i.name(), i.value(), updateLinked);
}
category_type *m_cat = nullptr; category_type *m_cat = nullptr;
row_type *m_row = nullptr; row_type *m_row = nullptr;
}; };
......
This diff is collapsed. Click to expand it.
...@@ -35,6 +35,8 @@ ...@@ -35,6 +35,8 @@
// #include <cif++/CifValidator.hpp> // #include <cif++/CifValidator.hpp>
// #include <cif++/CifParser.hpp> // #include <cif++/CifParser.hpp>
#include <cif++/v2/parser.hpp>
namespace tt = boost::test_tools; namespace tt = boost::test_tools;
std::filesystem::path gTestDir = std::filesystem::current_path(); // filled in first test std::filesystem::path gTestDir = std::filesystem::current_path(); // filled in first test
...@@ -264,45 +266,54 @@ BOOST_AUTO_TEST_CASE(ci_1) ...@@ -264,45 +266,54 @@ BOOST_AUTO_TEST_CASE(ci_1)
// -------------------------------------------------------------------- // --------------------------------------------------------------------
// BOOST_AUTO_TEST_CASE(f_1) BOOST_AUTO_TEST_CASE(f_1)
// { {
// // using namespace mmcif; // using namespace mmcif;
// auto f = R"(data_TEST auto f = R"(data_TEST
// # #
// loop_ loop_
// _test.id _test.id
// _test.name _test.name
// 1 aap 1 aap
// 2 noot 2 noot
// 3 mies 3 mies
// )"_cf; )"_cf;
// BOOST_ASSERT(not f.empty()); BOOST_ASSERT(not f.empty());
// BOOST_ASSERT(f.size() == 1); BOOST_ASSERT(f.size() == 1);
// auto &db = f.front(); auto &db = f.front();
// BOOST_CHECK(db.name() == "TEST"); BOOST_CHECK(db.name() == "TEST");
// auto &test = db["test"]; auto &test = db["test"];
// BOOST_CHECK(test.size() == 3); BOOST_CHECK(test.size() == 3);
// // wrong! the next lines will crash. And that's OK, don't do that const char *ts[] = {"aap", "noot", "mies"};
// // for (auto r: test)
// // test.erase(r);
// // BOOST_CHECK(test.empty()); int 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;
}
// // test.purge(); // for (auto r: test)
// test.erase(r);
// // auto n = test.erase(cif::Key("id") == 1, [](const cif::Row &r) // BOOST_CHECK(test.empty());
// // {
// // BOOST_CHECK_EQUAL(r["id"].as<int>(), 1);
// // BOOST_CHECK_EQUAL(r["name"].as<std::string>(), "aap"); });
// // BOOST_CHECK_EQUAL(n, 1); // test.clear();
// }
// auto n = test.erase(cif::Key("id") == 1, [](const cif::Row &r)
// {
// BOOST_CHECK_EQUAL(r["id"].as<int>(), 1);
// BOOST_CHECK_EQUAL(r["name"].as<std::string>(), "aap"); });
// BOOST_CHECK_EQUAL(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