Commit f4e860bc by Maarten L. Hekkelman

iterate children, set property of atom

parent b65aa46d
......@@ -1486,6 +1486,12 @@ class RowSet
return iterator(mItems.insert(pos.current(), item), mItems.end());
}
void make_unique()
{
std::sort(mItems.begin(), mItems.end());
mItems.erase(std::unique(mItems.begin(), mItems.end()), mItems.end());
}
private:
Category* mCat;
std::vector<ItemRow*> mItems;
......@@ -1590,6 +1596,9 @@ class Category
bool hasChildren(Row r) const;
RowSet getChildren(Row r, Category& childCat);
RowSet getChildren(Row r, const char* childCat);
bool isValid();
void validateLinks() const;
......
......@@ -104,8 +104,13 @@ class Atom
template<typename T>
T property(const std::string& name) const;
template<typename T>
void property(const std::string& name, const T& value);
void property(const std::string& name, const std::string& value);
template<typename T, std::enable_if_t<std::is_arithmetic_v<T>, int> = 0>
void property(const std::string& name, const T& value)
{
property(name, std::to_string(value));
}
// specifications
std::string labelAtomID() const;
......
......@@ -1858,6 +1858,42 @@ bool Category::hasChildren(Row r) const
return result;
}
RowSet Category::getChildren(Row r, const char* childCat)
{
return getChildren(r, mDb[childCat]);
}
RowSet Category::getChildren(Row r, Category& childCat)
{
assert(mValidator != nullptr);
assert(mCatValidator != nullptr);
RowSet result(childCat);
for (auto& link: mValidator->getLinksForParent(mName))
{
if (link->mChildCategory != childCat.mName)
continue;
Condition cond;
for (size_t ix = 0; ix < link->mParentKeys.size(); ++ix)
{
const char* value = r[link->mParentKeys[ix]].c_str();
cond = std::move(cond) && (Key(link->mChildKeys[ix]) == value);
}
auto children = childCat.find(std::move(cond));
result.insert(result.end(), children.begin(), children.end());
}
// remove duplicates
result.make_unique();
return result;
}
bool Category::isValid()
{
bool result = true;
......
......@@ -343,6 +343,11 @@ struct AtomImpl
return i->second;
}
void property(const std::string& name, const std::string& value)
{
mRow[name] = value;
}
int compare(const AtomImpl& b) const
{
int d = mAsymID.compare(b.mAsymID);
......@@ -378,7 +383,7 @@ struct AtomImpl
bool mSymmetryCopy = false;
bool mClone = false;
std::string mSymmetryOperator;
std::string mSymmetryOperator = "1_555";
// clipper::RTop_orth mRTop;
// Point mD;
// int32_t mRTix;
......@@ -482,6 +487,11 @@ float Atom::property<float>(const std::string& name) const
return stof(impl()->property(name));
}
void Atom::property(const std::string& name, const std::string& value)
{
impl()->property(name, value);
}
const std::string& Atom::id() const
{
return impl()->mID;
......
......@@ -969,6 +969,8 @@ _cat_2.parent_id3
7 3 3 3
)";
// --------------------------------------------------------------------
struct data_membuf : public std::streambuf
{
data_membuf(char* text, size_t length)
......@@ -983,6 +985,22 @@ _cat_2.parent_id3
auto& cat1 = f.firstDatablock()["cat_1"];
auto& cat2 = f.firstDatablock()["cat_2"];
// --------------------------------------------------------------------
// check iterate children
auto PR2set = cat1.find(cif::Key("id") == 2);
BOOST_ASSERT(PR2set.size() == 1);
auto PR2 = PR2set.front();
BOOST_CHECK(PR2["id"].as<int>() == 2);
auto CR2set = cat1.getChildren(PR2, "cat_2");
BOOST_ASSERT(CR2set.size() == 3);
std::vector<int> CRids;
std::transform(CR2set.begin(), CR2set.end(), std::back_inserter(CRids), [](cif::Row r) { return r["id"].as<int>(); });
std::sort(CRids.begin(), CRids.end());
BOOST_CHECK(CRids == std::vector<int>({ 4, 5, 6}));
// check a rename in parent and child
for (auto r: cat1.find(cif::Key("id") == 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