BWAPI
SPAR/AIModule/SparAIModule/Utils/SafeList.h
Go to the documentation of this file.
00001 #pragma once
00002 #include <list>
00003 #include <cassert>
00004 
00005 template <class T> class ConstSafeListAdaptor;
00006 template <class T> class SafeListAdaptor;
00007 
00012 class SafeListBase
00013 {
00014 public:
00015   struct ConstFunctionReturn
00016   {
00017     ConstFunctionReturn()
00018       : breakIteration(false) {}
00019     ConstFunctionReturn(bool _breakIteration)
00020       : breakIteration(_breakIteration) {}
00021     bool breakIteration;
00022   };
00023 
00024   struct FunctionReturn : ConstFunctionReturn
00025   {
00026     FunctionReturn()
00027       : ConstFunctionReturn(), deleteCurrent(false) {}
00028     FunctionReturn(bool _deleteCurrent, bool _breakIteration)
00029       : ConstFunctionReturn(_breakIteration), deleteCurrent(_deleteCurrent) {}
00030     FunctionReturn(ConstFunctionReturn r)
00031       : ConstFunctionReturn(r), deleteCurrent(false) {}
00032     bool deleteCurrent;
00033   };
00034 };
00035 
00044 template <class T>
00045 class SafeList : public SafeListBase
00046 {
00047 protected:
00048   friend class ConstSafeListAdaptor<T>;
00049   friend class SafeListAdaptor<T>;
00054   class Wrapper
00055   {
00056   public:
00057     Wrapper(T t)
00058       : m_t(t), m_deleted(false) {}
00062     bool isDeleted() const { return m_deleted; }
00063     operator T&() { return m_t; }
00064     operator const T&() const { return m_t; }
00065     bool operator==(const Wrapper& other) const { return m_t == other.m_t; }
00066     bool operator!=(const Wrapper& other) const { return m_t != other.m_t; }
00067   protected:
00068     friend class SafeList;
00072     T m_t;
00076     mutable bool m_deleted;
00077   };
00078 
00079 public:
00080   typedef typename std::list<Wrapper>::iterator iterator;
00081   typedef typename std::list<Wrapper>::const_iterator const_iterator;
00082 
00086   SafeList()
00087     : m_size(0)
00088     , m_nbCurrentIterations(0)
00089   {
00090   }
00091 
00092   SafeList(const SafeList& other)
00093     : m_size(0)
00094     , m_nbCurrentIterations(0)
00095   {
00096     for (std::list<Wrapper>::const_iterator it = other.m_list.begin(); it != other.m_list.end(); ++it)
00097     {
00098       if (!it->isDeleted())
00099         add(*it);
00100     }
00101   }
00102 
00108   iterator add(const T& t)
00109   {
00110     ++m_size;
00111     return m_list.insert(m_list.end(), t);
00112   }
00113 
00122   template <class Function>
00123   Function do_while(Function function)
00124   {
00125     Iteration iteration(*this);
00126 
00127     bool breakIteration = false;
00128     for (std::list<Wrapper>::iterator it = m_list.begin(); !breakIteration && it != m_list.end(); ++it)
00129     {
00130       if (!(*it).m_deleted)
00131       {
00132         FunctionReturn result = function((*it).m_t);
00133         if (result.deleteCurrent)
00134         {
00135           (*it).m_deleted = true;
00136           --m_size;
00137         }
00138         breakIteration = result.breakIteration;
00139       }
00140     }
00141 
00142     return function;
00143   }
00144 
00152   template <class Function>
00153   Function do_while(Function function) const
00154   {
00155     Iteration iteration(*this);
00156 
00157     bool breakIteration = false;
00158     for (std::list<Wrapper>::const_iterator it = m_list.begin(); !breakIteration && it != m_list.end(); ++it)
00159     {
00160       if (!(*it).m_deleted)
00161       {
00162         ConstFunctionReturn result = function((*it).m_t);
00163         breakIteration = result.breakIteration;
00164       }
00165     }
00166 
00167     return function;
00168   }
00169 
00178   template <class Function>
00179   Function for_each(Function function)
00180   {
00181     Iteration iteration(*this);
00182 
00183     if (!m_list.empty())
00184     {
00185       std::list<Wrapper>::iterator stop = m_list.end();
00186       --stop;
00187       std::list<Wrapper>::iterator it = m_list.begin();
00188       bool breakIteration = false;
00189       do
00190       {
00191         if (!(*it).m_deleted)
00192         {
00193           FunctionReturn result = function((*it).m_t);
00194           if (result.deleteCurrent)
00195           {
00196             (*it).m_deleted = true;
00197             --m_size;
00198           }
00199           breakIteration = result.breakIteration;
00200         }
00201       } while (!breakIteration && it++ != stop);
00202     }
00203 
00204     return function;
00205   }
00206 
00214   template <class Function>
00215   Function for_each(Function function) const
00216   {
00217     Iteration iteration(*this);
00218 
00219     if (!m_list.empty())
00220     {
00221       std::list<Wrapper>::const_iterator stop = m_list.end();
00222       --stop;
00223       std::list<Wrapper>::const_iterator it = m_list.begin();
00224       bool breakIteration = false;
00225       do
00226       {
00227         if (!(*it).m_deleted)
00228         {
00229           ConstFunctionReturn result = function((*it).m_t);
00230           breakIteration = result.breakIteration;
00231         }
00232       } while (!breakIteration && it++ != stop);
00233     }
00234 
00235     return function;
00236   }
00237 
00242   void erase(iterator position)
00243   {
00244     assert(!(*position).m_deleted);
00245     (*position).m_deleted = true;
00246     --m_size;
00247     if (m_nbCurrentIterations == 0)
00248     {
00249       m_list.erase(position);
00250     }
00251   }
00252 
00256   size_t size() const
00257   {
00258     assert(m_nbCurrentIterations != 0 || m_size == m_list.size()); // m_list includes deleted elements if m_nbCurrentIterations > 0
00259     return m_size;
00260   }
00261 
00265   bool empty() const
00266   {
00267     return size() == 0;
00268   }
00269 
00270 protected:
00271   SafeList& operator=(const SafeList& other) const;
00272 
00276   class Iteration
00277   {
00278   public:
00279     Iteration(const SafeList& safeList)
00280       : m_safeList(safeList)
00281     {
00282       m_safeList.iterationStarted(*this);
00283     }
00284     ~Iteration()
00285     {
00286       m_safeList.iterationEnded(*this);
00287     }
00288   private:
00289     Iteration(const Iteration&);
00290     Iteration& operator=(const Iteration&);
00291 
00292     const SafeList& m_safeList;
00293   };
00294   friend class Iteration;
00295 
00301   void iterationStarted(Iteration& iteration) const
00302   {
00303     unused(iteration);
00304 
00305     ++m_nbCurrentIterations;
00306   }
00307 
00314   void iterationEnded(Iteration& iteration) const
00315   {
00316     unused(iteration);
00317 
00318     if (--m_nbCurrentIterations == 0)
00319     {
00320       std::list<Wrapper>::iterator it = m_list.begin();
00321       while (it != m_list.end())
00322       {
00323         std::list<Wrapper>::iterator next = it;
00324         ++next;
00325         if ((*it).m_deleted)
00326         {
00327           m_list.erase(it);
00328         }
00329         it = next;
00330       }
00331     }
00332   }
00333 
00338   mutable std::list<Wrapper> m_list;
00342   mutable size_t m_nbCurrentIterations;
00348   size_t m_size;
00349 };
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines