Commit b6e8f79c by maarten

- fix in prepper code

- added erase_nocascade

git-svn-id: svn+ssh://gitlab/srv/svn-repos/pdb-redo/trunk@515 a1961a4f-ab94-4bcc-80e8-33b5a54de466
parent eda40b8e
...@@ -1217,9 +1217,27 @@ class Category ...@@ -1217,9 +1217,27 @@ class Category
template<class Iter> template<class Iter>
std::tuple<Row,bool> emplace(Iter b, Iter e); std::tuple<Row,bool> emplace(Iter b, Iter e);
void erase(Condition&& cond); size_t erase(Condition&& cond);
size_t erase(Condition&& cond, std::function<void(const Row&)>&& visit);
void erase(Row r); void erase(Row r);
void erase(iterator ri); iterator erase(iterator ri);
// erase without cascade, should only be used when speed is needed
size_t erase_nocascade(Condition&& cond)
{
return erase_nocascade(std::forward<Condition>(cond), [](auto r){});
}
size_t erase_nocascade(Condition&& cond, std::function<void(const Row&)>&& visit)
{
auto savedValidator = mValidator;
mValidator = nullptr;
auto result = erase(std::forward<Condition>(cond), std::forward<std::function<void(const Row&)>>(visit));
mValidator = savedValidator;
return result;
}
void eraseOrphans(Condition&& cond); void eraseOrphans(Condition&& cond);
......
...@@ -16,7 +16,7 @@ int GetSpacegroupNumber(std::string spacegroup); // alternative for clipper's pa ...@@ -16,7 +16,7 @@ int GetSpacegroupNumber(std::string spacegroup); // alternative for clipper's pa
// std::string SpacegroupToHall(std::string spacegroup); // std::string SpacegroupToHall(std::string spacegroup);
// -------------------------------------------------------------------- // --------------------------------------------------------------------
// To iterate over all near symmetry copies of an atom // To iterate over all symmetry copies of an atom
class SymmetryAtomIteratorFactory class SymmetryAtomIteratorFactory
{ {
......
...@@ -1513,20 +1513,47 @@ tuple<Row,bool> Category::emplace(Row r) ...@@ -1513,20 +1513,47 @@ tuple<Row,bool> Category::emplace(Row r)
return emplace(r.begin(), r.end()); return emplace(r.begin(), r.end());
} }
void Category::erase(Condition&& cond) size_t Category::erase(Condition&& cond)
{ {
RowSet remove(*this); size_t result = 0;
cond.prepare(*this); cond.prepare(*this);
for (auto r: *this) auto ri = begin();
while (ri != end())
{ {
if (cond(*this, r)) if (cond(*this, *ri))
remove.push_back(r); {
ri = erase(ri);
++result;
}
else
++ri;
} }
for (auto r: remove) return result;
erase(r); }
size_t Category::erase(Condition&& cond, std::function<void(const Row&)>&& verbose)
{
size_t result = 0;
cond.prepare(*this);
auto ri = begin();
while (ri != end())
{
if (cond(*this, *ri))
{
verbose(*ri);
ri = erase(ri);
++result;
}
else
++ri;
}
return result;
} }
void Category::eraseOrphans(Condition&& cond) void Category::eraseOrphans(Condition&& cond)
...@@ -1552,13 +1579,16 @@ void Category::eraseOrphans(Condition&& cond) ...@@ -1552,13 +1579,16 @@ void Category::eraseOrphans(Condition&& cond)
erase(r); erase(r);
} }
void Category::erase(iterator p) void Category::erase(Row r)
{ {
erase(*p); erase(iterator(r.mData));
} }
void Category::erase(Row r) auto Category::erase(iterator pos) -> iterator
{ {
auto r = *pos;
iterator result = ++pos;
iset keys; iset keys;
if (mCatValidator) if (mCatValidator)
keys = iset(mCatValidator->mKeys.begin(), mCatValidator->mKeys.end()); keys = iset(mCatValidator->mKeys.begin(), mCatValidator->mKeys.end());
...@@ -1595,6 +1625,8 @@ void Category::erase(Row r) ...@@ -1595,6 +1625,8 @@ void Category::erase(Row r)
// If all values in a child are the same as the specified parent ones // If all values in a child are the same as the specified parent ones
// the child is removed as well, recursively of course. // the child is removed as well, recursively of course.
if (mValidator != nullptr)
{
for (auto& link: mValidator->getLinksForParent(mName)) for (auto& link: mValidator->getLinksForParent(mName))
{ {
auto childCat = mDb.get(link->mChildCategory); auto childCat = mDb.get(link->mChildCategory);
...@@ -1612,6 +1644,7 @@ void Category::erase(Row r) ...@@ -1612,6 +1644,7 @@ void Category::erase(Row r)
childCat->eraseOrphans(move(cond)); childCat->eraseOrphans(move(cond));
} }
}
delete r.mData; delete r.mData;
...@@ -1623,6 +1656,8 @@ void Category::erase(Row r) ...@@ -1623,6 +1656,8 @@ void Category::erase(Row r)
while (mTail->mNext != nullptr) while (mTail->mNext != nullptr)
mTail = mTail->mNext; mTail = mTail->mNext;
} }
return result;
} }
void Category::getTagOrder(vector<string>& tags) const void Category::getTagOrder(vector<string>& tags) const
......
#define BOOST_TEST_MODULE LibCifPP_Test
#include <boost/test/included/unit_test.hpp>
#include "cif++/DistanceMap.h"
// --------------------------------------------------------------------
cif::File operator""_cf(const char* text, size_t length)
{
struct membuf : public std::streambuf
{
membuf(char* text, size_t length)
{
this->setg(text, text, text + length);
}
} buffer(const_cast<char*>(text), length);
std::istream is(&buffer);
return cif::File(is);
}
// --------------------------------------------------------------------
BOOST_AUTO_TEST_CASE(ut1)
{
using namespace mmcif;
auto f = R"(data_TEST
#
loop_
_test.id
_test.name
1 aap
2 noot
3 mies
)"_cf;
auto& db = f.firstDatablock();
BOOST_CHECK(db.getName() == "TEST");
auto& test = db["test"];
BOOST_CHECK(test.size() == 3);
// wrong! the next lines will crash. And that's OK, don't do that
// for (auto r: test)
// test.erase(r);
// BOOST_CHECK(test.empty());
// test.purge();
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);
}
\ No newline at end of file
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