Commit bb9d8161 by Maarten L. Hekkelman

alternative for find

parent 02460700
...@@ -647,12 +647,16 @@ class Condition ...@@ -647,12 +647,16 @@ class Condition
Condition() : mImpl(nullptr) {} Condition() : mImpl(nullptr) {}
Condition(detail::ConditionImpl* impl) : mImpl(impl) {} Condition(detail::ConditionImpl* impl) : mImpl(impl) {}
Condition(const Condition&) = delete;
Condition(Condition&& rhs) Condition(Condition&& rhs)
: mImpl(nullptr) : mImpl(nullptr)
{ {
std::swap(mImpl, rhs.mImpl); std::swap(mImpl, rhs.mImpl);
} }
Condition& operator=(const Condition&) = delete;
Condition& operator=(Condition&& rhs) Condition& operator=(Condition&& rhs)
{ {
std::swap(mImpl, rhs.mImpl); std::swap(mImpl, rhs.mImpl);
...@@ -662,6 +666,7 @@ class Condition ...@@ -662,6 +666,7 @@ class Condition
~Condition() ~Condition()
{ {
delete mImpl; delete mImpl;
mImpl = nullptr;
} }
void prepare(const Category& c) void prepare(const Category& c)
...@@ -1002,8 +1007,11 @@ struct Empty {}; ...@@ -1002,8 +1007,11 @@ struct Empty {};
struct Key struct Key
{ {
Key(const string& ItemTag) : mItemTag(ItemTag) {} Key(const string& itemTag) : mItemTag(itemTag) {}
Key(const char* ItemTag) : mItemTag(ItemTag) {} Key(const char* itemTag) : mItemTag(itemTag) {}
Key(const Key&) = delete;
Key& operator=(const Key&) = delete;
template<typename T> template<typename T>
Condition operator==(const T& v) const Condition operator==(const T& v) const
...@@ -1045,29 +1053,29 @@ struct Key ...@@ -1045,29 +1053,29 @@ struct Key
template<typename T> template<typename T>
Condition operator>(const T& v) const Condition operator>(const T& v) const
{ {
auto comp = [this, v](const Category& c, const Row& r) -> bool { return r[this->mItemTag].as<T>() > v; }; return Condition(new detail::KeyCompareConditionImpl(mItemTag, [this, v](const Category& c, const Row& r)
return Condition(new detail::KeyCompareConditionImpl<decltype(comp)>(mItemTag, std::move(comp))); { return r[this->mItemTag].as<T>() > v; }));
} }
template<typename T> template<typename T>
Condition operator>=(const T& v) const Condition operator>=(const T& v) const
{ {
auto comp = [this, v](const Category& c, const Row& r) -> bool { return r[this->mItemTag].as<T>() >= v; }; return Condition(new detail::KeyCompareConditionImpl(mItemTag, [this, v](const Category& c, const Row& r)
return Condition(new detail::KeyCompareConditionImpl<decltype(comp)>(mItemTag, std::move(comp))); { return r[this->mItemTag].as<T>() >= v; }));
} }
template<typename T> template<typename T>
Condition operator<(const T& v) const Condition operator<(const T& v) const
{ {
auto comp = [this, v](const Category& c, const Row& r) -> bool { return r[this->mItemTag].as<T>() < v; }; return Condition(new detail::KeyCompareConditionImpl(mItemTag, [this, v](const Category& c, const Row& r)
return Condition(new detail::KeyCompareConditionImpl<decltype(comp)>(mItemTag, std::move(comp))); { return r[this->mItemTag].as<T>() < v; }));
} }
template<typename T> template<typename T>
Condition operator<=(const T& v) const Condition operator<=(const T& v) const
{ {
auto comp = [this, v](const Category& c, const Row& r) -> bool { return r[this->mItemTag].as<T>() <= v; }; return Condition(new detail::KeyCompareConditionImpl(mItemTag, [this, v](const Category& c, const Row& r)
return Condition(new detail::KeyCompareConditionImpl<decltype(comp)>(mItemTag, std::move(comp))); { return r[this->mItemTag].as<T>() <= v; }));
} }
string mItemTag; string mItemTag;
...@@ -1131,6 +1139,10 @@ class iterator_impl ...@@ -1131,6 +1139,10 @@ class iterator_impl
iterator_impl(ItemRow* data) : mCurrent(data) {} iterator_impl(ItemRow* data) : mCurrent(data) {}
iterator_impl(const iterator_impl& i) : mCurrent(i.mCurrent) {} iterator_impl(const iterator_impl& i) : mCurrent(i.mCurrent) {}
template<typename IteratorType>
iterator_impl(IteratorType& i)
: mCurrent(*i) {}
iterator_impl& operator=(const iterator_impl& i) iterator_impl& operator=(const iterator_impl& i)
{ {
mCurrent = i.mCurrent; mCurrent = i.mCurrent;
...@@ -1170,6 +1182,8 @@ class conditional_iterator_proxy ...@@ -1170,6 +1182,8 @@ class conditional_iterator_proxy
{ {
public: public:
using base_iterator = iterator_impl<RowType>;
class conditional_iterator_impl class conditional_iterator_impl
{ {
public: public:
...@@ -1179,8 +1193,6 @@ class conditional_iterator_proxy ...@@ -1179,8 +1193,6 @@ class conditional_iterator_proxy
using pointer = RowType*; using pointer = RowType*;
using reference = RowType&; using reference = RowType&;
using base_iterator = iterator_impl<RowType>;
conditional_iterator_impl(Category& cat, base_iterator pos, const Condition& cond); conditional_iterator_impl(Category& cat, base_iterator pos, const Condition& cond);
conditional_iterator_impl(const conditional_iterator_impl& i) = default; conditional_iterator_impl(const conditional_iterator_impl& i) = default;
conditional_iterator_impl& operator=(const conditional_iterator_impl& i) = default; conditional_iterator_impl& operator=(const conditional_iterator_impl& i) = default;
...@@ -1223,11 +1235,7 @@ class conditional_iterator_proxy ...@@ -1223,11 +1235,7 @@ class conditional_iterator_proxy
using iterator = conditional_iterator_impl; using iterator = conditional_iterator_impl;
using reference = typename iterator::reference; using reference = typename iterator::reference;
conditional_iterator_proxy(Category& cat, Condition&& cond) conditional_iterator_proxy(Category& cat, base_iterator pos, Condition&& cond);
: mCat(&cat), mCondition(std::move(cond))
{
mCondition.prepare(cat);
}
conditional_iterator_proxy(conditional_iterator_proxy&& p); conditional_iterator_proxy(conditional_iterator_proxy&& p);
conditional_iterator_proxy& operator=(conditional_iterator_proxy&& p); conditional_iterator_proxy& operator=(conditional_iterator_proxy&& p);
...@@ -1238,7 +1246,7 @@ class conditional_iterator_proxy ...@@ -1238,7 +1246,7 @@ class conditional_iterator_proxy
iterator begin() const; iterator begin() const;
iterator end() const; iterator end() const;
bool empty() { return begin() == end(); } bool empty() const;
size_t size() const { return std::distance(begin(), end()); } size_t size() const { return std::distance(begin(), end()); }
RowType front() { return *begin(); } RowType front() { return *begin(); }
...@@ -1250,6 +1258,7 @@ class conditional_iterator_proxy ...@@ -1250,6 +1258,7 @@ class conditional_iterator_proxy
private: private:
Category* mCat; Category* mCat;
Condition mCondition; Condition mCondition;
base_iterator mCBegin, mCEnd;
}; };
// -------------------------------------------------------------------- // --------------------------------------------------------------------
...@@ -1440,7 +1449,12 @@ class Category ...@@ -1440,7 +1449,12 @@ class Category
conditional_iterator_proxy<Row> find(Condition&& cond) conditional_iterator_proxy<Row> find(Condition&& cond)
{ {
return { *this, std::move(cond) }; return { *this, begin(), std::forward<Condition>(cond) };
}
conditional_iterator_proxy<Row> find(const_iterator pos, Condition&& cond)
{
return { *this, pos, std::forward<Condition>(cond) };
} }
bool exists(Condition&& cond) const; bool exists(Condition&& cond) const;
...@@ -1701,7 +1715,7 @@ template<typename RowType> ...@@ -1701,7 +1715,7 @@ template<typename RowType>
conditional_iterator_proxy<RowType>::conditional_iterator_impl::conditional_iterator_impl(Category& cat, base_iterator pos, const Condition& cond) 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) : mCat(&cat), mBegin(pos), mEnd(cat.end()), mCondition(&cond)
{ {
// skip if until the first row matching cond // skip until the first row matching cond
while (mBegin != mEnd and not (*mCondition)(*mCat, *mBegin)) while (mBegin != mEnd and not (*mCondition)(*mCat, *mBegin))
++mBegin; ++mBegin;
...@@ -1709,8 +1723,22 @@ conditional_iterator_proxy<RowType>::conditional_iterator_impl::conditional_iter ...@@ -1709,8 +1723,22 @@ conditional_iterator_proxy<RowType>::conditional_iterator_impl::conditional_iter
template<typename RowType> template<typename RowType>
conditional_iterator_proxy<RowType>::conditional_iterator_proxy(conditional_iterator_proxy&& p) conditional_iterator_proxy<RowType>::conditional_iterator_proxy(conditional_iterator_proxy&& p)
: mCat(nullptr), mCBegin(p.mCBegin), mCEnd(p.mCEnd)
{ {
swap(p); std::swap(mCat, p.mCat);
mCondition.swap(p.mCondition);
}
template<typename RowType>
conditional_iterator_proxy<RowType>::conditional_iterator_proxy(Category& cat, base_iterator pos, Condition&& cond)
: mCat(&cat), mCondition(std::move(cond))
, mCBegin(pos)
, mCEnd(cat.end())
{
mCondition.prepare(cat);
while (mCBegin != mCEnd and not mCondition(*mCat, *mCBegin))
++mCBegin;
} }
template<typename RowType> template<typename RowType>
...@@ -1723,13 +1751,19 @@ conditional_iterator_proxy<RowType>& conditional_iterator_proxy<RowType>::operat ...@@ -1723,13 +1751,19 @@ conditional_iterator_proxy<RowType>& conditional_iterator_proxy<RowType>::operat
template<typename RowType> template<typename RowType>
typename conditional_iterator_proxy<RowType>::iterator conditional_iterator_proxy<RowType>::begin() const typename conditional_iterator_proxy<RowType>::iterator conditional_iterator_proxy<RowType>::begin() const
{ {
return iterator(*mCat, mCat->begin(), mCondition); return iterator(*mCat, mCBegin, mCondition);
} }
template<typename RowType> template<typename RowType>
typename conditional_iterator_proxy<RowType>::iterator conditional_iterator_proxy<RowType>::end() const typename conditional_iterator_proxy<RowType>::iterator conditional_iterator_proxy<RowType>::end() const
{ {
return iterator(*mCat, mCat->end(), mCondition); return iterator(*mCat, mCEnd, mCondition);
}
template<typename RowType>
bool conditional_iterator_proxy<RowType>::empty() const
{
return mCBegin != mCEnd;
} }
template<typename RowType> template<typename RowType>
...@@ -1737,8 +1771,9 @@ void conditional_iterator_proxy<RowType>::swap(conditional_iterator_proxy& rhs) ...@@ -1737,8 +1771,9 @@ void conditional_iterator_proxy<RowType>::swap(conditional_iterator_proxy& rhs)
{ {
std::swap(mCat, rhs.mCat); std::swap(mCat, rhs.mCat);
mCondition.swap(rhs.mCondition); mCondition.swap(rhs.mCondition);
std::swap(mCBegin, rhs.mCBegin);
std::swap(mCEnd, rhs.mCEnd);
} }
} }
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