Browse Source

Using ObjectList::IndexType instead of ObjectList::ListValues::size_type.

Add STL-compatible forward iterator for ObjectList.
ParameterTemplates
Michael Uleysky 8 years ago
parent
commit
c02f46df5e
  1. 78
      include/common.h
  2. 4
      src/globals.cpp

78
include/common.h

@ -7,8 +7,10 @@
#include <list>
#include <memory>
#include <set>
#include <stack>
#include <string>
#include <sstream>
#include <tuple>
#include <typeindex>
#include <typeinfo>
@ -276,13 +278,80 @@ public:
// Class for objects list
class EXPORT ObjectList: public ObjectBase
{
public:
private:
typedef std::deque<const ObjectBase*> ListValues;
public:
typedef ListValues::size_type IndexType;
private:
// Forward iterator for ObjectList (may be later be bidirectional)
class ObjectListIterator: public std::iterator<std::forward_iterator_tag, const ObjectBase*>
{
const ObjectList* list;
std::stack<std::tuple<const ObjectList*, IndexType> > st;
IndexType pos;
void Increment()
{
while(true)
{
OBType<ObjectList> islist(list->At(pos));
if(islist && islist->Size()>0)
{
st.emplace(std::make_tuple(list,pos));
list=islist;
pos=0;
}
else return;
}
}
public:
ObjectListIterator():list(nullptr),pos(0) {}
ObjectListIterator(const ObjectListIterator&) = default;
ObjectListIterator(ObjectListIterator&&) = default;
ObjectListIterator(const ObjectList* l):list(l),pos(0) {if(list) Increment();}
bool operator ==(const ObjectListIterator& i) const {return (list==i.list && pos==i.pos);}
bool operator !=(const ObjectListIterator& i) const {return !operator==(i);}
ObjectListIterator& operator++()
{
if(pos<list->Size()-1)
{
pos++;
Increment();
return *this;
}
while(st.size()>0)
{
std::tie(list,pos)=st.top();
st.pop();
if(pos<list->Size()-1)
{
pos++;
Increment();
return *this;
}
}
// This is the end
list=nullptr;
pos=0;
return *this;
}
ObjectListIterator operator++(int) {ObjectListIterator tmp(*this); operator++(); return tmp;}
const ObjectBase* operator*() const {return list->At(pos);}
const ObjectBase* operator->() const {return list->At(pos);}
};
std::shared_ptr<ListValues> vals;
ObjectList(const ObjectList* o):vals(o->vals) {}
public:
typedef ObjectListIterator iterator;
typedef ObjectListIterator const_iterator;
ObjectList() {vals.reset(new ListValues, [](ListValues* p){for(auto& i: *p) delete i; delete p;});}
ObjectList(const ObjectBase* o) {vals.reset(new ListValues, [](ListValues* p){for(auto& i: *p) delete i; delete p;}); PushBack(o);}
// Pure virtual overrides
@ -305,7 +374,7 @@ public:
}
// Own functions
const ObjectBase* At(ListValues::size_type i) const {return (*vals)[i];}
const ObjectBase* At(IndexType i) const {return (*vals)[i];}
const ObjectBase* Get(const std::string& gname) const
{
const ObjectBase* p=Find(gname);
@ -326,9 +395,12 @@ public:
}
return nullptr;
}
ListValues::size_type Size() const {return vals->size();}
IndexType Size() const {return vals->size();}
ObjectList* PushBack(const ObjectBase* p) {vals->push_back(p); return this;}
ObjectList* PushFront(const ObjectBase* p) {vals->push_front(p); return this;}
// Iterator functions
const_iterator begin() const {return const_iterator(this);}
const_iterator end() const {return const_iterator();}
};
typedef const ObjectBase* (*Func)(const ObjectList*);

4
src/globals.cpp

@ -92,7 +92,7 @@ void RegisterFunction(const std::string& name, Func func)
bool Save(const ObjectList* input)
{
ObjectList::ListValues::size_type sz=input->Size(), i;
ObjectList::IndexType sz=input->Size(), i;
if(sz<2 || sz%2==1 )
{
COUT(ERROR)<<"Number of save arguments must not be "<<sz<<std::endl;
@ -128,7 +128,7 @@ bool Save(const ObjectList* input)
bool Print(const ObjectList* input)
{
ObjectList::ListValues::size_type sz=input->Size(), i;
ObjectList::IndexType sz=input->Size(), i;
if(sz==0) return true;
// Print

Loading…
Cancel
Save