| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189 | 
							- /* Distributed under the OSI-approved BSD 3-Clause License.  See accompanying
 
-    file Copyright.txt or https://cmake.org/licensing for details.  */
 
- #pragma once
 
- #include "cmConfigure.h" // IWYU pragma: keep
 
- #include <cassert>
 
- #include <vector>
 
- /**
 
-   @brief A adaptor for traversing a tree structure in a vector
 
-   This class is not intended to be wholly generic like a standard library
 
-   container adaptor.  Mostly it exists to facilitate code sharing for the
 
-   needs of the cmState.  For example, the Truncate() method is a specific
 
-   requirement of the cmState.
 
-   An empty cmLinkedTree provides a Root() method, and an Push() method,
 
-   each of which return iterators.  A Tree can be built up by extending
 
-   from the root, and then extending from any other iterator.
 
-   An iterator resulting from this tree construction can be
 
-   forward-only-iterated toward the root.  Extending the tree never
 
-   invalidates existing iterators.
 
-  */
 
- template <typename T>
 
- class cmLinkedTree
 
- {
 
-   using PositionType = typename std::vector<T>::size_type;
 
-   using PointerType = T*;
 
-   using ReferenceType = T&;
 
- public:
 
-   class iterator
 
-   {
 
-     friend class cmLinkedTree;
 
-     cmLinkedTree* Tree;
 
-     // The Position is always 'one past the end'.
 
-     PositionType Position;
 
-     iterator(cmLinkedTree* tree, PositionType pos)
 
-       : Tree(tree)
 
-       , Position(pos)
 
-     {
 
-     }
 
-   public:
 
-     iterator()
 
-       : Tree(nullptr)
 
-       , Position(0)
 
-     {
 
-     }
 
-     void operator++()
 
-     {
 
-       assert(this->Tree);
 
-       assert(this->Tree->UpPositions.size() == this->Tree->Data.size());
 
-       assert(this->Position <= this->Tree->Data.size());
 
-       assert(this->Position > 0);
 
-       this->Position = this->Tree->UpPositions[this->Position - 1];
 
-     }
 
-     PointerType operator->() const
 
-     {
 
-       assert(this->Tree);
 
-       assert(this->Tree->UpPositions.size() == this->Tree->Data.size());
 
-       assert(this->Position <= this->Tree->Data.size());
 
-       assert(this->Position > 0);
 
-       return this->Tree->GetPointer(this->Position - 1);
 
-     }
 
-     PointerType operator->()
 
-     {
 
-       assert(this->Tree);
 
-       assert(this->Tree->UpPositions.size() == this->Tree->Data.size());
 
-       assert(this->Position <= this->Tree->Data.size());
 
-       assert(this->Position > 0);
 
-       return this->Tree->GetPointer(this->Position - 1);
 
-     }
 
-     ReferenceType operator*() const
 
-     {
 
-       assert(this->Tree);
 
-       assert(this->Tree->UpPositions.size() == this->Tree->Data.size());
 
-       assert(this->Position <= this->Tree->Data.size());
 
-       assert(this->Position > 0);
 
-       return this->Tree->GetReference(this->Position - 1);
 
-     }
 
-     ReferenceType operator*()
 
-     {
 
-       assert(this->Tree);
 
-       assert(this->Tree->UpPositions.size() == this->Tree->Data.size());
 
-       assert(this->Position <= this->Tree->Data.size());
 
-       assert(this->Position > 0);
 
-       return this->Tree->GetReference(this->Position - 1);
 
-     }
 
-     bool operator==(iterator other) const
 
-     {
 
-       assert(this->Tree);
 
-       assert(this->Tree->UpPositions.size() == this->Tree->Data.size());
 
-       assert(this->Tree == other.Tree);
 
-       return this->Position == other.Position;
 
-     }
 
-     bool operator!=(iterator other) const
 
-     {
 
-       assert(this->Tree);
 
-       assert(this->Tree->UpPositions.size() == this->Tree->Data.size());
 
-       return !(*this == other);
 
-     }
 
-     bool IsValid() const
 
-     {
 
-       if (!this->Tree) {
 
-         return false;
 
-       }
 
-       return this->Position <= this->Tree->Data.size();
 
-     }
 
-     bool StrictWeakOrdered(iterator other) const
 
-     {
 
-       assert(this->Tree);
 
-       assert(this->Tree == other.Tree);
 
-       return this->Position < other.Position;
 
-     }
 
-   };
 
-   iterator Root() const
 
-   {
 
-     return iterator(const_cast<cmLinkedTree*>(this), 0);
 
-   }
 
-   iterator Push(iterator it) { return this->Push_impl(it, T()); }
 
-   iterator Push(iterator it, T t) { return this->Push_impl(it, std::move(t)); }
 
-   bool IsLast(iterator it) { return it.Position == this->Data.size(); }
 
-   iterator Pop(iterator it)
 
-   {
 
-     assert(!this->Data.empty());
 
-     assert(this->UpPositions.size() == this->Data.size());
 
-     bool const isLast = this->IsLast(it);
 
-     ++it;
 
-     // If this is the last entry then no other entry can refer
 
-     // to it so we can drop its storage.
 
-     if (isLast) {
 
-       this->Data.pop_back();
 
-       this->UpPositions.pop_back();
 
-     }
 
-     return it;
 
-   }
 
-   iterator Truncate()
 
-   {
 
-     assert(!this->UpPositions.empty());
 
-     this->UpPositions.erase(this->UpPositions.begin() + 1,
 
-                             this->UpPositions.end());
 
-     assert(!this->Data.empty());
 
-     this->Data.erase(this->Data.begin() + 1, this->Data.end());
 
-     return iterator(this, 1);
 
-   }
 
-   void Clear()
 
-   {
 
-     this->UpPositions.clear();
 
-     this->Data.clear();
 
-   }
 
- private:
 
-   T& GetReference(PositionType pos) { return this->Data[pos]; }
 
-   T* GetPointer(PositionType pos) { return &this->Data[pos]; }
 
-   iterator Push_impl(iterator it, T&& t)
 
-   {
 
-     assert(this->UpPositions.size() == this->Data.size());
 
-     assert(it.Position <= this->UpPositions.size());
 
-     this->UpPositions.push_back(it.Position);
 
-     this->Data.push_back(std::move(t));
 
-     return iterator(this, this->UpPositions.size());
 
-   }
 
-   std::vector<T> Data;
 
-   std::vector<PositionType> UpPositions;
 
- };
 
 
  |