# smallstack_type.hpp

Go to the documentation of this file.

    00001 /* $Id$ */
    00002
    00003 /*
    00004  * This file is part of OpenTTD.
    00005  * OpenTTD is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, version 2.
    00006  * OpenTTD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
    00007  * See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with OpenTTD. If not, see <http://www.gnu.org/licenses/>.
    00008  */
    00009
    00012 #ifndef SMALLSTACK_TYPE_HPP
    00013 #define SMALLSTACK_TYPE_HPP
    00014
    00015 #include "pool_type.hpp"
    00016 #include "pool_func.hpp"
    00017
    00022 template <typename Tindex, typename Titem>
    00023 class SmallStackItem {
    00024 protected:
    00025   Tindex next;
    00026   Titem value;
    00027
    00033   inline SmallStackItem(const Titem &value, Tindex next) :
    00034     next(next), value(value) {}
    00035 };
    00036
    00059 template <typename Titem, typename Tindex, Titem Tinvalid, size_t Tgrowth_step, size_t Tmax_size>
    00060 class SmallStack : public SmallStackItem<Tindex, Titem> {
    00061 protected:
    00062   class PooledSmallStack;
    00063
    00067   void Branch()
    00068   {
    00069     if (PooledSmallStack::IsValidID(this->next)) {
    00070       PooledSmallStack::Get(this->next)->CreateBranch();
    00071     }
    00072   }
    00073
    00074 public:
    00075   typedef SmallStackItem<Tindex, Titem> Item;
    00076   typedef Pool<PooledSmallStack, Tindex, Tgrowth_step, Tmax_size, PT_NORMAL, true, false> SmallStackPool;
    00077
    00082   inline SmallStack(const Titem &value = Tinvalid) : Item(value, Tmax_size) {}
    00083
    00087   inline ~SmallStack()
    00088   {
    00089     if (PooledSmallStack::IsValidID(this->next)) {
    00090       PooledSmallStack *item = PooledSmallStack::Get(this->next);
    00091       if (item->NumBranches() == 0) {
    00092         delete item;
    00093       } else {
    00094         item->DeleteBranch();
    00095       }
    00096     }
    00097   }
    00098
    00103   inline SmallStack(const SmallStack &other) : Item(other) { this->Branch(); }
    00104
    00110   inline SmallStack &operator=(const SmallStack &other)
    00111   {
    00112     if (this == &other) return *this;
    00113     this->~SmallStack();
    00114     this->next = other.next;
    00115     this->value = other.value;
    00116     this->Branch();
    00117     return *this;
    00118   }
    00119
    00124   inline void Push(const Titem &item)
    00125   {
    00126     if (this->value != Tinvalid) {
    00127       assert(PooledSmallStack::CanAllocateItem());
    00128       PooledSmallStack *next = new PooledSmallStack(this->value, this->next);
    00129       this->next = next->index;
    00130     }
    00131     this->value = item;
    00132   }
    00133
    00138   inline Titem Pop()
    00139   {
    00140     Titem ret = this->value;
    00141     if (!PooledSmallStack::IsValidID(this->next)) {
    00142       this->value = Tinvalid;
    00143     } else {
    00144       PooledSmallStack *next = PooledSmallStack::Get(this->next);
    00145       static_cast<Item &>(*this) = *next;
    00146       if (next->NumBranches() == 0) {
    00147         delete next;
    00148       } else {
    00149         next->DeleteBranch();
    00150         this->Branch();
    00151       }
    00152     }
    00153     return ret;
    00154   }
    00155
    00160   inline bool IsEmpty() const
    00161   {
    00162     return this->value == Tinvalid && !PooledSmallStack::IsValidID(this->next);
    00163   }
    00164
    00170   inline bool Contains(const Titem &item) const
    00171   {
    00172     if (item == Tinvalid || item == this->value) return true;
    00173     const SmallStack *in_list = this;
    00174     while (PooledSmallStack::IsValidID(in_list->next)) {
    00175       in_list = static_cast<const SmallStack *>(
    00176           static_cast<const Item *>(PooledSmallStack::Get(in_list->next)));
    00177       if (in_list->value == item) return true;
    00178     }
    00179     return false;
    00180   }
    00181
    00182 protected:
    00183   static SmallStackPool _pool;
    00184
    00188   class PooledSmallStack : public Item, public SmallStackPool::template PoolItem<&SmallStack::_pool> {
    00189   private:
    00190     Tindex branch_count;
    00191   public:
    00192     PooledSmallStack(Titem value, Tindex next) : Item(value, next), branch_count(0) {}
    00193
    00194     inline void CreateBranch() { ++this->branch_count; }
    00195     inline void DeleteBranch() { --this->branch_count; }
    00196     inline Tindex NumBranches() { return this->branch_count; }
    00197   };
    00198 };
    00199
    00200
    00201 #endif