summaryrefslogtreecommitdiff
path: root/disas/libvixl/vixl/invalset.h
diff options
context:
space:
mode:
Diffstat (limited to 'disas/libvixl/vixl/invalset.h')
-rw-r--r--disas/libvixl/vixl/invalset.h775
1 files changed, 0 insertions, 775 deletions
diff --git a/disas/libvixl/vixl/invalset.h b/disas/libvixl/vixl/invalset.h
deleted file mode 100644
index 2e0871f8c3..0000000000
--- a/disas/libvixl/vixl/invalset.h
+++ /dev/null
@@ -1,775 +0,0 @@
-// Copyright 2015, ARM Limited
-// All rights reserved.
-//
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are met:
-//
-// * Redistributions of source code must retain the above copyright notice,
-// this list of conditions and the following disclaimer.
-// * Redistributions in binary form must reproduce the above copyright notice,
-// this list of conditions and the following disclaimer in the documentation
-// and/or other materials provided with the distribution.
-// * Neither the name of ARM Limited nor the names of its contributors may be
-// used to endorse or promote products derived from this software without
-// specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS CONTRIBUTORS "AS IS" AND
-// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
-// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
-// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
-// FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
-// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
-// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
-// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
-// OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-#ifndef VIXL_INVALSET_H_
-#define VIXL_INVALSET_H_
-
-#include <cstring>
-
-#include <algorithm>
-#include <vector>
-
-#include "vixl/globals.h"
-
-namespace vixl {
-
-// We define a custom data structure template and its iterator as `std`
-// containers do not fit the performance requirements for some of our use cases.
-//
-// The structure behaves like an iterable unordered set with special properties
-// and restrictions. "InvalSet" stands for "Invalidatable Set".
-//
-// Restrictions and requirements:
-// - Adding an element already present in the set is illegal. In debug mode,
-// this is checked at insertion time.
-// - The templated class `ElementType` must provide comparison operators so that
-// `std::sort()` can be used.
-// - A key must be available to represent invalid elements.
-// - Elements with an invalid key must compare higher or equal to any other
-// element.
-//
-// Use cases and performance considerations:
-// Our use cases present two specificities that allow us to design this
-// structure to provide fast insertion *and* fast search and deletion
-// operations:
-// - Elements are (generally) inserted in order (sorted according to their key).
-// - A key is available to mark elements as invalid (deleted).
-// The backing `std::vector` allows for fast insertions. When
-// searching for an element we ensure the elements are sorted (this is generally
-// the case) and perform a binary search. When deleting an element we do not
-// free the associated memory immediately. Instead, an element to be deleted is
-// marked with the 'invalid' key. Other methods of the container take care of
-// ignoring entries marked as invalid.
-// To avoid the overhead of the `std::vector` container when only few entries
-// are used, a number of elements are preallocated.
-
-// 'ElementType' and 'KeyType' are respectively the types of the elements and
-// their key. The structure only reclaims memory when safe to do so, if the
-// number of elements that can be reclaimed is greater than `RECLAIM_FROM` and
-// greater than `<total number of elements> / RECLAIM_FACTOR.
-#define TEMPLATE_INVALSET_P_DECL \
- class ElementType, \
- unsigned N_PREALLOCATED_ELEMENTS, \
- class KeyType, \
- KeyType INVALID_KEY, \
- size_t RECLAIM_FROM, \
- unsigned RECLAIM_FACTOR
-
-#define TEMPLATE_INVALSET_P_DEF \
-ElementType, N_PREALLOCATED_ELEMENTS, \
-KeyType, INVALID_KEY, RECLAIM_FROM, RECLAIM_FACTOR
-
-template<class S> class InvalSetIterator; // Forward declaration.
-
-template<TEMPLATE_INVALSET_P_DECL> class InvalSet {
- public:
- InvalSet();
- ~InvalSet();
-
- static const size_t kNPreallocatedElements = N_PREALLOCATED_ELEMENTS;
- static const KeyType kInvalidKey = INVALID_KEY;
-
- // It is illegal to insert an element already present in the set.
- void insert(const ElementType& element);
-
- // Looks for the specified element in the set and - if found - deletes it.
- void erase(const ElementType& element);
-
- // This indicates the number of (valid) elements stored in this set.
- size_t size() const;
-
- // Returns true if no elements are stored in the set.
- // Note that this does not mean the the backing storage is empty: it can still
- // contain invalid elements.
- bool empty() const;
-
- void clear();
-
- const ElementType min_element();
-
- // This returns the key of the minimum element in the set.
- KeyType min_element_key();
-
- static bool IsValid(const ElementType& element);
- static KeyType Key(const ElementType& element);
- static void SetKey(ElementType* element, KeyType key);
-
- protected:
- // Returns a pointer to the element in vector_ if it was found, or NULL
- // otherwise.
- ElementType* Search(const ElementType& element);
-
- // The argument *must* point to an element stored in *this* set.
- // This function is not allowed to move elements in the backing vector
- // storage.
- void EraseInternal(ElementType* element);
-
- // The elements in the range searched must be sorted.
- ElementType* BinarySearch(const ElementType& element,
- ElementType* start,
- ElementType* end) const;
-
- // Sort the elements.
- enum SortType {
- // The 'hard' version guarantees that invalid elements are moved to the end
- // of the container.
- kHardSort,
- // The 'soft' version only guarantees that the elements will be sorted.
- // Invalid elements may still be present anywhere in the set.
- kSoftSort
- };
- void Sort(SortType sort_type);
-
- // Delete the elements that have an invalid key. The complexity is linear
- // with the size of the vector.
- void Clean();
-
- const ElementType Front() const;
- const ElementType Back() const;
-
- // Delete invalid trailing elements and return the last valid element in the
- // set.
- const ElementType CleanBack();
-
- // Returns a pointer to the start or end of the backing storage.
- const ElementType* StorageBegin() const;
- const ElementType* StorageEnd() const;
- ElementType* StorageBegin();
- ElementType* StorageEnd();
-
- // Returns the index of the element within the backing storage. The element
- // must belong to the backing storage.
- size_t ElementIndex(const ElementType* element) const;
-
- // Returns the element at the specified index in the backing storage.
- const ElementType* ElementAt(size_t index) const;
- ElementType* ElementAt(size_t index);
-
- static const ElementType* FirstValidElement(const ElementType* from,
- const ElementType* end);
-
- void CacheMinElement();
- const ElementType CachedMinElement() const;
-
- bool ShouldReclaimMemory() const;
- void ReclaimMemory();
-
- bool IsUsingVector() const { return vector_ != NULL; }
- void set_sorted(bool sorted) { sorted_ = sorted; }
-
- // We cache some data commonly required by users to improve performance.
- // We cannot cache pointers to elements as we do not control the backing
- // storage.
- bool valid_cached_min_;
- size_t cached_min_index_; // Valid iff `valid_cached_min_` is true.
- KeyType cached_min_key_; // Valid iff `valid_cached_min_` is true.
-
- // Indicates whether the elements are sorted.
- bool sorted_;
-
- // This represents the number of (valid) elements in this set.
- size_t size_;
-
- // The backing storage is either the array of preallocated elements or the
- // vector. The structure starts by using the preallocated elements, and
- // transitions (permanently) to using the vector once more than
- // kNPreallocatedElements are used.
- // Elements are only invalidated when using the vector. The preallocated
- // storage always only contains valid elements.
- ElementType preallocated_[kNPreallocatedElements];
- std::vector<ElementType>* vector_;
-
-#ifdef VIXL_DEBUG
- // Iterators acquire and release this monitor. While a set is acquired,
- // certain operations are illegal to ensure that the iterator will
- // correctly iterate over the elements in the set.
- int monitor_;
- int monitor() const { return monitor_; }
- void Acquire() { monitor_++; }
- void Release() {
- monitor_--;
- VIXL_ASSERT(monitor_ >= 0);
- }
-#endif
-
- friend class InvalSetIterator<InvalSet<TEMPLATE_INVALSET_P_DEF> >;
- typedef ElementType _ElementType;
- typedef KeyType _KeyType;
-};
-
-
-template<class S> class InvalSetIterator {
- private:
- // Redefine types to mirror the associated set types.
- typedef typename S::_ElementType ElementType;
- typedef typename S::_KeyType KeyType;
-
- public:
- explicit InvalSetIterator(S* inval_set);
- ~InvalSetIterator();
-
- ElementType* Current() const;
- void Advance();
- bool Done() const;
-
- // Mark this iterator as 'done'.
- void Finish();
-
- // Delete the current element and advance the iterator to point to the next
- // element.
- void DeleteCurrentAndAdvance();
-
- static bool IsValid(const ElementType& element);
- static KeyType Key(const ElementType& element);
-
- protected:
- void MoveToValidElement();
-
- // Indicates if the iterator is looking at the vector or at the preallocated
- // elements.
- const bool using_vector_;
- // Used when looking at the preallocated elements, or in debug mode when using
- // the vector to track how many times the iterator has advanced.
- size_t index_;
- typename std::vector<ElementType>::iterator iterator_;
- S* inval_set_;
-};
-
-
-template<TEMPLATE_INVALSET_P_DECL>
-InvalSet<TEMPLATE_INVALSET_P_DEF>::InvalSet()
- : valid_cached_min_(false),
- sorted_(true), size_(0), vector_(NULL) {
-#ifdef VIXL_DEBUG
- monitor_ = 0;
-#endif
-}
-
-
-template<TEMPLATE_INVALSET_P_DECL>
-InvalSet<TEMPLATE_INVALSET_P_DEF>::~InvalSet() {
- VIXL_ASSERT(monitor_ == 0);
- delete vector_;
-}
-
-
-template<TEMPLATE_INVALSET_P_DECL>
-void InvalSet<TEMPLATE_INVALSET_P_DEF>::insert(const ElementType& element) {
- VIXL_ASSERT(monitor() == 0);
- VIXL_ASSERT(IsValid(element));
- VIXL_ASSERT(Search(element) == NULL);
- set_sorted(empty() || (sorted_ && (element > CleanBack())));
- if (IsUsingVector()) {
- vector_->push_back(element);
- } else {
- if (size_ < kNPreallocatedElements) {
- preallocated_[size_] = element;
- } else {
- // Transition to using the vector.
- vector_ = new std::vector<ElementType>(preallocated_,
- preallocated_ + size_);
- vector_->push_back(element);
- }
- }
- size_++;
-
- if (valid_cached_min_ && (element < min_element())) {
- cached_min_index_ = IsUsingVector() ? vector_->size() - 1 : size_ - 1;
- cached_min_key_ = Key(element);
- valid_cached_min_ = true;
- }
-
- if (ShouldReclaimMemory()) {
- ReclaimMemory();
- }
-}
-
-
-template<TEMPLATE_INVALSET_P_DECL>
-void InvalSet<TEMPLATE_INVALSET_P_DEF>::erase(const ElementType& element) {
- VIXL_ASSERT(monitor() == 0);
- VIXL_ASSERT(IsValid(element));
- ElementType* local_element = Search(element);
- if (local_element != NULL) {
- EraseInternal(local_element);
- }
-}
-
-
-template<TEMPLATE_INVALSET_P_DECL>
-ElementType* InvalSet<TEMPLATE_INVALSET_P_DEF>::Search(
- const ElementType& element) {
- VIXL_ASSERT(monitor() == 0);
- if (empty()) {
- return NULL;
- }
- if (ShouldReclaimMemory()) {
- ReclaimMemory();
- }
- if (!sorted_) {
- Sort(kHardSort);
- }
- if (!valid_cached_min_) {
- CacheMinElement();
- }
- return BinarySearch(element, ElementAt(cached_min_index_), StorageEnd());
-}
-
-
-template<TEMPLATE_INVALSET_P_DECL>
-size_t InvalSet<TEMPLATE_INVALSET_P_DEF>::size() const {
- return size_;
-}
-
-
-template<TEMPLATE_INVALSET_P_DECL>
-bool InvalSet<TEMPLATE_INVALSET_P_DEF>::empty() const {
- return size_ == 0;
-}
-
-
-template<TEMPLATE_INVALSET_P_DECL>
-void InvalSet<TEMPLATE_INVALSET_P_DEF>::clear() {
- VIXL_ASSERT(monitor() == 0);
- size_ = 0;
- if (IsUsingVector()) {
- vector_->clear();
- }
- set_sorted(true);
- valid_cached_min_ = false;
-}
-
-
-template<TEMPLATE_INVALSET_P_DECL>
-const ElementType InvalSet<TEMPLATE_INVALSET_P_DEF>::min_element() {
- VIXL_ASSERT(monitor() == 0);
- VIXL_ASSERT(!empty());
- CacheMinElement();
- return *ElementAt(cached_min_index_);
-}
-
-
-template<TEMPLATE_INVALSET_P_DECL>
-KeyType InvalSet<TEMPLATE_INVALSET_P_DEF>::min_element_key() {
- VIXL_ASSERT(monitor() == 0);
- if (valid_cached_min_) {
- return cached_min_key_;
- } else {
- return Key(min_element());
- }
-}
-
-
-template<TEMPLATE_INVALSET_P_DECL>
-bool InvalSet<TEMPLATE_INVALSET_P_DEF>::IsValid(const ElementType& element) {
- return Key(element) != kInvalidKey;
-}
-
-
-template<TEMPLATE_INVALSET_P_DECL>
-void InvalSet<TEMPLATE_INVALSET_P_DEF>::EraseInternal(ElementType* element) {
- // Note that this function must be safe even while an iterator has acquired
- // this set.
- VIXL_ASSERT(element != NULL);
- size_t deleted_index = ElementIndex(element);
- if (IsUsingVector()) {
- VIXL_ASSERT((&(vector_->front()) <= element) &&
- (element <= &(vector_->back())));
- SetKey(element, kInvalidKey);
- } else {
- VIXL_ASSERT((preallocated_ <= element) &&
- (element < (preallocated_ + kNPreallocatedElements)));
- ElementType* end = preallocated_ + kNPreallocatedElements;
- size_t copy_size = sizeof(*element) * (end - element - 1);
- memmove(element, element + 1, copy_size);
- }
- size_--;
-
- if (valid_cached_min_ &&
- (deleted_index == cached_min_index_)) {
- if (sorted_ && !empty()) {
- const ElementType* min = FirstValidElement(element, StorageEnd());
- cached_min_index_ = ElementIndex(min);
- cached_min_key_ = Key(*min);
- valid_cached_min_ = true;
- } else {
- valid_cached_min_ = false;
- }
- }
-}
-
-
-template<TEMPLATE_INVALSET_P_DECL>
-ElementType* InvalSet<TEMPLATE_INVALSET_P_DEF>::BinarySearch(
- const ElementType& element, ElementType* start, ElementType* end) const {
- if (start == end) {
- return NULL;
- }
- VIXL_ASSERT(sorted_);
- VIXL_ASSERT(start < end);
- VIXL_ASSERT(!empty());
-
- // Perform a binary search through the elements while ignoring invalid
- // elements.
- ElementType* elements = start;
- size_t low = 0;
- size_t high = (end - start) - 1;
- while (low < high) {
- // Find valid bounds.
- while (!IsValid(elements[low]) && (low < high)) ++low;
- while (!IsValid(elements[high]) && (low < high)) --high;
- VIXL_ASSERT(low <= high);
- // Avoid overflow when computing the middle index.
- size_t middle = low / 2 + high / 2 + (low & high & 1);
- if ((middle == low) || (middle == high)) {
- break;
- }
- while (!IsValid(elements[middle]) && (middle < high - 1)) ++middle;
- while (!IsValid(elements[middle]) && (low + 1 < middle)) --middle;
- if (!IsValid(elements[middle])) {
- break;
- }
- if (elements[middle] < element) {
- low = middle;
- } else {
- high = middle;
- }
- }
-
- if (elements[low] == element) return &elements[low];
- if (elements[high] == element) return &elements[high];
- return NULL;
-}
-
-
-template<TEMPLATE_INVALSET_P_DECL>
-void InvalSet<TEMPLATE_INVALSET_P_DEF>::Sort(SortType sort_type) {
- VIXL_ASSERT(monitor() == 0);
- if (sort_type == kSoftSort) {
- if (sorted_) {
- return;
- }
- }
- if (empty()) {
- return;
- }
-
- Clean();
- std::sort(StorageBegin(), StorageEnd());
-
- set_sorted(true);
- cached_min_index_ = 0;
- cached_min_key_ = Key(Front());
- valid_cached_min_ = true;
-}
-
-
-template<TEMPLATE_INVALSET_P_DECL>
-void InvalSet<TEMPLATE_INVALSET_P_DEF>::Clean() {
- VIXL_ASSERT(monitor() == 0);
- if (empty() || !IsUsingVector()) {
- return;
- }
- // Manually iterate through the vector storage to discard invalid elements.
- ElementType* start = &(vector_->front());
- ElementType* end = start + vector_->size();
- ElementType* c = start;
- ElementType* first_invalid;
- ElementType* first_valid;
- ElementType* next_invalid;
-
- while (c < end && IsValid(*c)) { c++; }
- first_invalid = c;
-
- while (c < end) {
- while (c < end && !IsValid(*c)) { c++; }
- first_valid = c;
- while (c < end && IsValid(*c)) { c++; }
- next_invalid = c;
-
- ptrdiff_t n_moved_elements = (next_invalid - first_valid);
- memmove(first_invalid, first_valid, n_moved_elements * sizeof(*c));
- first_invalid = first_invalid + n_moved_elements;
- c = next_invalid;
- }
-
- // Delete the trailing invalid elements.
- vector_->erase(vector_->begin() + (first_invalid - start), vector_->end());
- VIXL_ASSERT(vector_->size() == size_);
-
- if (sorted_) {
- valid_cached_min_ = true;
- cached_min_index_ = 0;
- cached_min_key_ = Key(*ElementAt(0));
- } else {
- valid_cached_min_ = false;
- }
-}
-
-
-template<TEMPLATE_INVALSET_P_DECL>
-const ElementType InvalSet<TEMPLATE_INVALSET_P_DEF>::Front() const {
- VIXL_ASSERT(!empty());
- return IsUsingVector() ? vector_->front() : preallocated_[0];
-}
-
-
-template<TEMPLATE_INVALSET_P_DECL>
-const ElementType InvalSet<TEMPLATE_INVALSET_P_DEF>::Back() const {
- VIXL_ASSERT(!empty());
- return IsUsingVector() ? vector_->back() : preallocated_[size_ - 1];
-}
-
-
-template<TEMPLATE_INVALSET_P_DECL>
-const ElementType InvalSet<TEMPLATE_INVALSET_P_DEF>::CleanBack() {
- VIXL_ASSERT(monitor() == 0);
- if (IsUsingVector()) {
- // Delete the invalid trailing elements.
- typename std::vector<ElementType>::reverse_iterator it = vector_->rbegin();
- while (!IsValid(*it)) {
- it++;
- }
- vector_->erase(it.base(), vector_->end());
- }
- return Back();
-}
-
-
-template<TEMPLATE_INVALSET_P_DECL>
-const ElementType* InvalSet<TEMPLATE_INVALSET_P_DEF>::StorageBegin() const {
- return IsUsingVector() ? &(vector_->front()) : preallocated_;
-}
-
-
-template<TEMPLATE_INVALSET_P_DECL>
-const ElementType* InvalSet<TEMPLATE_INVALSET_P_DEF>::StorageEnd() const {
- return IsUsingVector() ? &(vector_->back()) + 1 : preallocated_ + size_;
-}
-
-
-template<TEMPLATE_INVALSET_P_DECL>
-ElementType* InvalSet<TEMPLATE_INVALSET_P_DEF>::StorageBegin() {
- return IsUsingVector() ? &(vector_->front()) : preallocated_;
-}
-
-
-template<TEMPLATE_INVALSET_P_DECL>
-ElementType* InvalSet<TEMPLATE_INVALSET_P_DEF>::StorageEnd() {
- return IsUsingVector() ? &(vector_->back()) + 1 : preallocated_ + size_;
-}
-
-
-template<TEMPLATE_INVALSET_P_DECL>
-size_t InvalSet<TEMPLATE_INVALSET_P_DEF>::ElementIndex(
- const ElementType* element) const {
- VIXL_ASSERT((StorageBegin() <= element) && (element < StorageEnd()));
- return element - StorageBegin();
-}
-
-
-template<TEMPLATE_INVALSET_P_DECL>
-const ElementType* InvalSet<TEMPLATE_INVALSET_P_DEF>::ElementAt(
- size_t index) const {
- VIXL_ASSERT(
- (IsUsingVector() && (index < vector_->size())) || (index < size_));
- return StorageBegin() + index;
-}
-
-template<TEMPLATE_INVALSET_P_DECL>
-ElementType* InvalSet<TEMPLATE_INVALSET_P_DEF>::ElementAt(size_t index) {
- VIXL_ASSERT(
- (IsUsingVector() && (index < vector_->size())) || (index < size_));
- return StorageBegin() + index;
-}
-
-template<TEMPLATE_INVALSET_P_DECL>
-const ElementType* InvalSet<TEMPLATE_INVALSET_P_DEF>::FirstValidElement(
- const ElementType* from, const ElementType* end) {
- while ((from < end) && !IsValid(*from)) {
- from++;
- }
- return from;
-}
-
-
-template<TEMPLATE_INVALSET_P_DECL>
-void InvalSet<TEMPLATE_INVALSET_P_DEF>::CacheMinElement() {
- VIXL_ASSERT(monitor() == 0);
- VIXL_ASSERT(!empty());
-
- if (valid_cached_min_) {
- return;
- }
-
- if (sorted_) {
- const ElementType* min = FirstValidElement(StorageBegin(), StorageEnd());
- cached_min_index_ = ElementIndex(min);
- cached_min_key_ = Key(*min);
- valid_cached_min_ = true;
- } else {
- Sort(kHardSort);
- }
- VIXL_ASSERT(valid_cached_min_);
-}
-
-
-template<TEMPLATE_INVALSET_P_DECL>
-bool InvalSet<TEMPLATE_INVALSET_P_DEF>::ShouldReclaimMemory() const {
- if (!IsUsingVector()) {
- return false;
- }
- size_t n_invalid_elements = vector_->size() - size_;
- return (n_invalid_elements > RECLAIM_FROM) &&
- (n_invalid_elements > vector_->size() / RECLAIM_FACTOR);
-}
-
-
-template<TEMPLATE_INVALSET_P_DECL>
-void InvalSet<TEMPLATE_INVALSET_P_DEF>::ReclaimMemory() {
- VIXL_ASSERT(monitor() == 0);
- Clean();
-}
-
-
-template<class S>
-InvalSetIterator<S>::InvalSetIterator(S* inval_set)
- : using_vector_((inval_set != NULL) && inval_set->IsUsingVector()),
- index_(0),
- inval_set_(inval_set) {
- if (inval_set != NULL) {
- inval_set->Sort(S::kSoftSort);
-#ifdef VIXL_DEBUG
- inval_set->Acquire();
-#endif
- if (using_vector_) {
- iterator_ = typename std::vector<ElementType>::iterator(
- inval_set_->vector_->begin());
- }
- MoveToValidElement();
- }
-}
-
-
-template<class S>
-InvalSetIterator<S>::~InvalSetIterator() {
-#ifdef VIXL_DEBUG
- if (inval_set_ != NULL) {
- inval_set_->Release();
- }
-#endif
-}
-
-
-template<class S>
-typename S::_ElementType* InvalSetIterator<S>::Current() const {
- VIXL_ASSERT(!Done());
- if (using_vector_) {
- return &(*iterator_);
- } else {
- return &(inval_set_->preallocated_[index_]);
- }
-}
-
-
-template<class S>
-void InvalSetIterator<S>::Advance() {
- VIXL_ASSERT(!Done());
- if (using_vector_) {
- iterator_++;
-#ifdef VIXL_DEBUG
- index_++;
-#endif
- MoveToValidElement();
- } else {
- index_++;
- }
-}
-
-
-template<class S>
-bool InvalSetIterator<S>::Done() const {
- if (using_vector_) {
- bool done = (iterator_ == inval_set_->vector_->end());
- VIXL_ASSERT(done == (index_ == inval_set_->size()));
- return done;
- } else {
- return index_ == inval_set_->size();
- }
-}
-
-
-template<class S>
-void InvalSetIterator<S>::Finish() {
- VIXL_ASSERT(inval_set_->sorted_);
- if (using_vector_) {
- iterator_ = inval_set_->vector_->end();
- }
- index_ = inval_set_->size();
-}
-
-
-template<class S>
-void InvalSetIterator<S>::DeleteCurrentAndAdvance() {
- if (using_vector_) {
- inval_set_->EraseInternal(&(*iterator_));
- MoveToValidElement();
- } else {
- inval_set_->EraseInternal(inval_set_->preallocated_ + index_);
- }
-}
-
-
-template<class S>
-bool InvalSetIterator<S>::IsValid(const ElementType& element) {
- return S::IsValid(element);
-}
-
-
-template<class S>
-typename S::_KeyType InvalSetIterator<S>::Key(const ElementType& element) {
- return S::Key(element);
-}
-
-
-template<class S>
-void InvalSetIterator<S>::MoveToValidElement() {
- if (using_vector_) {
- while ((iterator_ != inval_set_->vector_->end()) && !IsValid(*iterator_)) {
- iterator_++;
- }
- } else {
- VIXL_ASSERT(inval_set_->empty() || IsValid(inval_set_->preallocated_[0]));
- // Nothing to do.
- }
-}
-
-#undef TEMPLATE_INVALSET_P_DECL
-#undef TEMPLATE_INVALSET_P_DEF
-
-} // namespace vixl
-
-#endif // VIXL_INVALSET_H_