Commit 31ce1615 by Maarten L. Hekkelman

changed RowSet and added conditional_iterator for category

parent 359538e1
......@@ -44,10 +44,10 @@ DEBUG = @DEBUG@
ifeq "$(DEBUG)" "1"
DEFINES += DEBUG
CXXFLAGS += -g -O0 -fstandalone-debug
CXXFLAGS += -g -O0
LDFLAGS += -g
else
CXXFLAGS += -O3
CXXFLAGS += -O2
DEFINES += NDEBUG
endif
......
......@@ -4,6 +4,8 @@ dnl Switch to a C++ compiler, and check if it works.
AC_LANG(C++)
AX_CXX_COMPILE_STDCXX_17([noext])
AX_CHECK_COMPILE_FLAG([-fstandalone-debug], , , [-Werror])
AC_CONFIG_SRCDIR([src/AtomShape.cpp])
AC_CONFIG_AUX_DIR(config)
AC_CONFIG_MACRO_DIR([config/m4])
......
......@@ -476,7 +476,10 @@ class Row
friend class detail::ItemReference;
friend class RowSet;
Row(ItemRow* data = nullptr)
Row()
: mData(nullptr) {}
Row(ItemRow* data)
: mData(data) {}
Row(const ItemRow* data)
......@@ -485,6 +488,9 @@ class Row
Row(const Row& rhs);
Row& operator=(const Row& rhs);
Row(Row&& rhs);
Row& operator=(Row&& rhs);
~Row();
void setCascading(bool cascade)
......@@ -521,7 +527,7 @@ class Row
};
// checks for an initialized Row:
operator bool() const { return mData != nullptr; }
explicit operator bool() const { return mData != nullptr; }
// for debugging
uint32_t lineNr() const;
......@@ -686,6 +692,12 @@ class Condition
friend struct detail::andConditionImpl;
friend struct detail::notConditionImpl;
void swap(Condition& rhs)
{
std::swap(mImpl, rhs.mImpl);
std::swap(mPrepared, rhs.mPrepared);
}
private:
detail::ConditionImpl* mImpl;
bool mPrepared = false;
......@@ -1150,43 +1162,95 @@ class iterator_impl
Row mCurrent;
};
// template<typename RowType>
// class conditional_iterator_proxy
// {
// public:
// --------------------------------------------------------------------
// Iterator proxy to iterate over a subset of rows selected by a Condition
template<typename RowType>
class conditional_iterator_proxy
{
public:
// using iterator = iterator_impl<RowType>;
// using reference = typename iterator::reference;
class conditional_iterator_impl
{
public:
using iterator_category = std::forward_iterator_tag;
using value_type = RowType;
using difference_type = std::ptrdiff_t;
using pointer = RowType*;
using reference = RowType&;
// conditional_iterator_proxy(ItemRow* head, Category& cat, Condition&& cond)
// : mHead(head), mCat(cat), mCondition(std::forward<Condition>(cond))
// {
// mCondition.prepare(cat);
// }
using base_iterator = iterator_impl<RowType>;
// conditional_iterator_proxy(conditional_iterator_proxy&& p);
conditional_iterator_impl(Category& cat, base_iterator pos, const Condition& cond);
conditional_iterator_impl(const conditional_iterator_impl& i) = default;
conditional_iterator_impl& operator=(const conditional_iterator_impl& i) = default;
// conditional_iterator_proxy(const conditional_iterator_proxy&) = delete;
// conditional_iterator_proxy& operator=(const conditional_iterator_proxy&) = delete;
virtual ~conditional_iterator_impl() = default;
// iterator begin() const { return iterator(mHead, mCat, mCondition); }
// iterator end() const { return iterator(nullptr, mCat, mCondition); }
reference operator*() { return *mBegin; }
pointer operator->() { return &*mBegin; }
conditional_iterator_impl& operator++()
{
while (mBegin != mEnd)
{
if (++mBegin == mEnd)
break;
if ((*mCondition)(*mCat, *mBegin))
break;
}
// bool empty() { return begin() == end(); }
// size_t size() const { return std::distance(begin(), end()); }
return *this;
}
// reference front() { return *begin(); }
conditional_iterator_impl operator++(int)
{
conditional_iterator_impl result(*this);
this->operator++();
return result;
}
bool operator==(const conditional_iterator_impl& rhs) const { return mBegin == rhs.mBegin; }
bool operator!=(const conditional_iterator_impl& rhs) const { return not (mBegin == rhs.mBegin); }
private:
Category* mCat;
base_iterator mBegin, mEnd;
const Condition* mCondition;
};
// Category& category() const { return mCat;}
using iterator = conditional_iterator_impl;
using reference = typename iterator::reference;
conditional_iterator_proxy(Category& cat, Condition&& cond)
: mCat(&cat), mCondition(std::move(cond))
{
mCondition.prepare(cat);
}
conditional_iterator_proxy(conditional_iterator_proxy&& p);
conditional_iterator_proxy& operator=(conditional_iterator_proxy&& p);
conditional_iterator_proxy(const conditional_iterator_proxy&) = delete;
conditional_iterator_proxy& operator=(const conditional_iterator_proxy&) = delete;
iterator begin() const;
iterator end() const;
// private:
// bool mAtEnd = false;
// ItemRow* mCurrent;
// Category& mCat;
// Condition mCondition;
// };
bool empty() { return begin() == end(); }
size_t size() const { return std::distance(begin(), end()); }
RowType front() { return *begin(); }
Category& category() const { return *mCat;}
void swap(conditional_iterator_proxy& rhs);
private:
Category* mCat;
Condition mCondition;
};
// --------------------------------------------------------------------
// class RowSet is used to return find results. Use it to re-order the results
......@@ -1374,9 +1438,9 @@ class Category
Row operator[](Condition&& cond);
RowSet find(Condition&& cond)
conditional_iterator_proxy<Row> find(Condition&& cond)
{
return RowSet(*this, std::forward<Condition>(cond));
return { *this, std::move(cond) };
}
bool exists(Condition&& cond) const;
......@@ -1631,5 +1695,50 @@ void KeyCompareConditionImpl<T>::prepare(const Category& c)
}
// --------------------------------------------------------------------
template<typename RowType>
conditional_iterator_proxy<RowType>::conditional_iterator_impl::conditional_iterator_impl(Category& cat, base_iterator pos, const Condition& cond)
: mCat(&cat), mBegin(pos), mEnd(cat.end()), mCondition(&cond)
{
// skip if until the first row matching cond
while (mBegin != mEnd and not (*mCondition)(*mCat, *mBegin))
++mBegin;
}
template<typename RowType>
conditional_iterator_proxy<RowType>::conditional_iterator_proxy(conditional_iterator_proxy&& p)
{
swap(p);
}
template<typename RowType>
conditional_iterator_proxy<RowType>& conditional_iterator_proxy<RowType>::operator=(conditional_iterator_proxy&& p)
{
swap(p);
return *this;
}
template<typename RowType>
typename conditional_iterator_proxy<RowType>::iterator conditional_iterator_proxy<RowType>::begin() const
{
return iterator(*mCat, mCat->begin(), mCondition);
}
template<typename RowType>
typename conditional_iterator_proxy<RowType>::iterator conditional_iterator_proxy<RowType>::end() const
{
return iterator(*mCat, mCat->end(), mCondition);
}
template<typename RowType>
void conditional_iterator_proxy<RowType>::swap(conditional_iterator_proxy& rhs)
{
std::swap(mCat, rhs.mCat);
mCondition.swap(rhs.mCondition);
}
}
......@@ -1401,6 +1401,7 @@ Row Category::operator[](Condition&& cond)
// RowSet Category::find(Condition&& cond)
// {
// // return RowSet(*this, std::forward<Condition>(cond));
// RowSet result(*this);
// cond.prepare(*this);
......@@ -1408,7 +1409,7 @@ Row Category::operator[](Condition&& cond)
// for (auto r: *this)
// {
// if (cond(*this, r))
// result.push_back(r);
// result.insert(result.end(), r);
// }
// return result;
// }
......@@ -2252,6 +2253,13 @@ Row::Row(const Row& rhs)
{
}
Row::Row(Row&& rhs)
: mData(rhs.mData)
, mCascade(rhs.mCascade)
{
rhs.mData = nullptr;
}
Row::~Row()
{
......@@ -2263,6 +2271,13 @@ void Row::next()
mData = mData->mNext;
}
Row& Row::operator=(Row&& rhs)
{
mData = rhs.mData; rhs.mData = nullptr;
mCascade = rhs.mCascade;
return *this;
}
Row& Row::operator=(const Row& rhs)
{
mData = rhs.mData;
......@@ -2654,7 +2669,7 @@ void Row::swap(size_t cix, ItemRow* a, ItemRow* b)
}
}
RowSet rs[2] = { *childCat, *childCat };
std::vector<conditional_iterator_proxy<Row>> rs;
// first find the respective rows, then flip values, otherwise you won't find them anymore!
for (size_t ab = 0; ab < 2; ++ab)
......@@ -2666,8 +2681,7 @@ void Row::swap(size_t cix, ItemRow* a, ItemRow* b)
cerr << "Fixing link from " << cat->mName << " to " << childCat->mName << " with " << endl
<< cond[ab] << endl;
auto rsci = childCat->find(move(cond[ab]));
rs[ab] = rsci;
rs.push_back(childCat->find(move(cond[ab])));
}
for (size_t ab = 0; ab < 2; ++ab)
......
......@@ -1468,7 +1468,7 @@ bool Monomer::isCis(const mmcif::Monomer& a, const mmcif::Monomer& b)
Polymer::Polymer(const Structure& s, const string& entityID, const string& asymID)
: mStructure(const_cast<Structure*>(&s)), mEntityID(entityID), mAsymID(asymID)
, mPolySeq(s.category("pdbx_poly_seq_scheme").find(cif::Key("asym_id") == mAsymID and cif::Key("entity_id") == mEntityID))
, mPolySeq(s.category("pdbx_poly_seq_scheme"), cif::Key("asym_id") == mAsymID and cif::Key("entity_id") == mEntityID)
{
map<uint32_t,uint32_t> ix;
......@@ -2097,23 +2097,26 @@ void Structure::swapAtoms(Atom& a1, Atom& a2)
cif::Datablock& db = *mFile.impl().mDb;
auto& atomSites = db["atom_site"];
auto r1 = atomSites.find(cif::Key("id") == a1.id());
auto r2 = atomSites.find(cif::Key("id") == a2.id());
auto rs1 = atomSites.find(cif::Key("id") == a1.id());
auto rs2 = atomSites.find(cif::Key("id") == a2.id());
if (r1.size() != 1)
throw runtime_error("Cannot swap atoms since the number of atoms with id " + a1.id() + " is " + to_string(r1.size()));
if (rs1.size() != 1)
throw runtime_error("Cannot swap atoms since the number of atoms with id " + a1.id() + " is " + to_string(rs1.size()));
if (r2.size() != 1)
throw runtime_error("Cannot swap atoms since the number of atoms with id " + a2.id() + " is " + to_string(r2.size()));
if (rs2.size() != 1)
throw runtime_error("Cannot swap atoms since the number of atoms with id " + a2.id() + " is " + to_string(rs2.size()));
auto l1 = r1.front()["label_atom_id"];
auto l2 = r2.front()["label_atom_id"];
auto r1 = rs1.front();
auto r2 = rs2.front();
auto l1 = r1["label_atom_id"];
auto l2 = r2["label_atom_id"];
l1.swap(l2);
a1.impl()->swapAtomLabels(*a2.impl());
auto l3 = r1.front()["auth_atom_id"];
auto l4 = r2.front()["auth_atom_id"];
auto l3 = r1["auth_atom_id"];
auto l4 = r2["auth_atom_id"];
l3.swap(l4);
}
......
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