]> granicus.if.org Git - clang/commitdiff
Implement PreprocessingRecord's and LazyVector's iterators on top of iterator_adaptor...
authorBenjamin Kramer <benny.kra@googlemail.com>
Sun, 15 Mar 2015 15:27:19 +0000 (15:27 +0000)
committerBenjamin Kramer <benny.kra@googlemail.com>
Sun, 15 Mar 2015 15:27:19 +0000 (15:27 +0000)
This basically creates a wrapper around an 'int' that poses as an iterator.
While that looks a bit counter-intuitive it works just fine because iterator
operations and basic integer arithmetic works in exactly the same way.

Remove the manual integer wrapping code and reduce the reliance on iterator
internals in the implementation. No functionality change intended.

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@232322 91177308-0d34-0410-b5e6-96231b3b80d8

include/clang/AST/ExternalASTSource.h
include/clang/Lex/PreprocessingRecord.h
lib/Lex/PreprocessingRecord.cpp

index f35639c19188b0f887942a610ff99fb0f62dff39..728af7c7a3b527b3ce68838a048a55784b0ae1a3 100644 (file)
@@ -477,132 +477,42 @@ class LazyVector {
   SmallVector<T, LocalStorage> Local;
 
 public:
-  // Iteration over the elements in the vector.
-  class iterator {
+  /// Iteration over the elements in the vector.
+  ///
+  /// In a complete iteration, the iterator walks the range [-M, N),
+  /// where negative values are used to indicate elements
+  /// loaded from the external source while non-negative values are used to
+  /// indicate elements added via \c push_back().
+  /// However, to provide iteration in source order (for, e.g., chained
+  /// precompiled headers), dereferencing the iterator flips the negative
+  /// values (corresponding to loaded entities), so that position -M
+  /// corresponds to element 0 in the loaded entities vector, position -M+1
+  /// corresponds to element 1 in the loaded entities vector, etc. This
+  /// gives us a reasonably efficient, source-order walk.
+  ///
+  /// We define this as a wrapping iterator around an int. The
+  /// iterator_adaptor_base class forwards the iterator methods to basic integer
+  /// arithmetic.
+  class iterator : public llvm::iterator_adaptor_base<
+                       iterator, int, std::random_access_iterator_tag, T, int> {
     LazyVector *Self;
-    
-    /// \brief Position within the vector..
-    ///
-    /// In a complete iteration, the Position field walks the range [-M, N),
-    /// where negative values are used to indicate elements
-    /// loaded from the external source while non-negative values are used to
-    /// indicate elements added via \c push_back().
-    /// However, to provide iteration in source order (for, e.g., chained
-    /// precompiled headers), dereferencing the iterator flips the negative
-    /// values (corresponding to loaded entities), so that position -M 
-    /// corresponds to element 0 in the loaded entities vector, position -M+1
-    /// corresponds to element 1 in the loaded entities vector, etc. This
-    /// gives us a reasonably efficient, source-order walk.
-    int Position;
-    
+
+    iterator(LazyVector *Self, int Position)
+        : iterator::iterator_adaptor_base(Position), Self(Self) {}
+
+    bool isLoaded() const { return this->I < 0; }
     friend class LazyVector;
-    
+
   public:
-    typedef T                   value_type;
-    typedef value_type&         reference;
-    typedef value_type*         pointer;
-    typedef std::random_access_iterator_tag iterator_category;
-    typedef int                 difference_type;
-    
-    iterator() : Self(0), Position(0) { }
-    
-    iterator(LazyVector *Self, int Position) 
-      : Self(Self), Position(Position) { }
-    
-    reference operator*() const {
-      if (Position < 0)
-        return Self->Loaded.end()[Position];
-      return Self->Local[Position];
-    }
-    
-    pointer operator->() const {
-      if (Position < 0)
-        return &Self->Loaded.end()[Position];
-      
-      return &Self->Local[Position];        
-    }
-    
-    reference operator[](difference_type D) {
-      return *(*this + D);
-    }
-    
-    iterator &operator++() {
-      ++Position;
-      return *this;
-    }
-    
-    iterator operator++(int) {
-      iterator Prev(*this);
-      ++Position;
-      return Prev;
-    }
-    
-    iterator &operator--() {
-      --Position;
-      return *this;
-    }
-    
-    iterator operator--(int) {
-      iterator Prev(*this);
-      --Position;
-      return Prev;
-    }
-    
-    friend bool operator==(const iterator &X, const iterator &Y) {
-      return X.Position == Y.Position;
-    }
-    
-    friend bool operator!=(const iterator &X, const iterator &Y) {
-      return X.Position != Y.Position;
-    }
-    
-    friend bool operator<(const iterator &X, const iterator &Y) {
-      return X.Position < Y.Position;
-    }
-    
-    friend bool operator>(const iterator &X, const iterator &Y) {
-      return X.Position > Y.Position;
-    }
-    
-    friend bool operator<=(const iterator &X, const iterator &Y) {
-      return X.Position < Y.Position;
-    }
-    
-    friend bool operator>=(const iterator &X, const iterator &Y) {
-      return X.Position > Y.Position;
-    }
-    
-    friend iterator& operator+=(iterator &X, difference_type D) {
-      X.Position += D;
-      return X;
-    }
-    
-    friend iterator& operator-=(iterator &X, difference_type D) {
-      X.Position -= D;
-      return X;
-    }
-    
-    friend iterator operator+(iterator X, difference_type D) {
-      X.Position += D;
-      return X;
-    }
-    
-    friend iterator operator+(difference_type D, iterator X) {
-      X.Position += D;
-      return X;
-    }
-    
-    friend difference_type operator-(const iterator &X, const iterator &Y) {
-      return X.Position - Y.Position;
-    }
-    
-    friend iterator operator-(iterator X, difference_type D) {
-      X.Position -= D;
-      return X;
+    iterator() : iterator(nullptr, 0) {}
+
+    typename iterator::reference operator*() const {
+      if (isLoaded())
+        return Self->Loaded.end()[this->I];
+      return Self->Local.begin()[this->I];
     }
   };
-  friend class iterator;
-  
+
   iterator begin(Source *source, bool LocalOnly = false) {
     if (LocalOnly)
       return iterator(this, 0);
@@ -621,17 +531,17 @@ public:
   }
   
   void erase(iterator From, iterator To) {
-    if (From.Position < 0 && To.Position < 0) {
-      Loaded.erase(Loaded.end() + From.Position, Loaded.end() + To.Position);
+    if (From.isLoaded() && To.isLoaded()) {
+      Loaded.erase(&*From, &*To);
       return;
     }
-    
-    if (From.Position < 0) {
-      Loaded.erase(Loaded.end() + From.Position, Loaded.end());
+
+    if (From.isLoaded()) {
+      Loaded.erase(&*From, Loaded.end());
       From = begin(nullptr, true);
     }
-    
-    Local.erase(Local.begin() + From.Position, Local.begin() + To.Position);
+
+    Local.erase(&*From, &*To);
   }
 };
 
index 3f9679c77c369eda05123b40613f7aa79f73c9b4..e379dbdbceab6440c32e72e5b14be6889cf04bc9 100644 (file)
@@ -20,6 +20,7 @@
 #include "llvm/ADT/DenseMap.h"
 #include "llvm/ADT/Optional.h"
 #include "llvm/ADT/SmallVector.h"
+#include "llvm/ADT/iterator.h"
 #include "llvm/Support/Allocator.h"
 #include "llvm/Support/Compiler.h"
 #include <vector>
@@ -378,125 +379,44 @@ namespace clang {
 
     SourceManager &getSourceManager() const { return SourceMgr; }
 
-    // Iteration over the preprocessed entities.
-    class iterator {
+    /// Iteration over the preprocessed entities.
+    ///
+    /// In a complete iteration, the iterator walks the range [-M, N),
+    /// where negative values are used to indicate preprocessed entities
+    /// loaded from the external source while non-negative values are used to
+    /// indicate preprocessed entities introduced by the current preprocessor.
+    /// However, to provide iteration in source order (for, e.g., chained
+    /// precompiled headers), dereferencing the iterator flips the negative
+    /// values (corresponding to loaded entities), so that position -M
+    /// corresponds to element 0 in the loaded entities vector, position -M+1
+    /// corresponds to element 1 in the loaded entities vector, etc. This
+    /// gives us a reasonably efficient, source-order walk.
+    ///
+    /// We define this as a wrapping iterator around an int. The
+    /// iterator_adaptor_base class forwards the iterator methods to basic
+    /// integer arithmetic.
+    class iterator : public llvm::iterator_adaptor_base<
+                         iterator, int, std::random_access_iterator_tag,
+                         PreprocessedEntity *, int, PreprocessedEntity *,
+                         PreprocessedEntity *> {
       PreprocessingRecord *Self;
-      
-      /// \brief Position within the preprocessed entity sequence.
-      ///
-      /// In a complete iteration, the Position field walks the range [-M, N),
-      /// where negative values are used to indicate preprocessed entities
-      /// loaded from the external source while non-negative values are used to
-      /// indicate preprocessed entities introduced by the current preprocessor.
-      /// However, to provide iteration in source order (for, e.g., chained
-      /// precompiled headers), dereferencing the iterator flips the negative
-      /// values (corresponding to loaded entities), so that position -M 
-      /// corresponds to element 0 in the loaded entities vector, position -M+1
-      /// corresponds to element 1 in the loaded entities vector, etc. This
-      /// gives us a reasonably efficient, source-order walk.
-      int Position;
-      
-    public:
-      typedef PreprocessedEntity *value_type;
-      typedef value_type&         reference;
-      typedef value_type*         pointer;
-      typedef std::random_access_iterator_tag iterator_category;
-      typedef int                 difference_type;
-      
-      iterator() : Self(nullptr), Position(0) { }
-      
+
       iterator(PreprocessingRecord *Self, int Position)
-        : Self(Self), Position(Position) { }
-      
-      value_type operator*() const {
-        bool isLoaded = Position < 0;
+          : iterator::iterator_adaptor_base(Position), Self(Self) {}
+      friend class PreprocessingRecord;
+
+    public:
+      iterator() : iterator(nullptr, 0) {}
+
+      PreprocessedEntity *operator*() const {
+        bool isLoaded = this->I < 0;
         unsigned Index = isLoaded ?
-            Self->LoadedPreprocessedEntities.size() + Position : Position;
+            Self->LoadedPreprocessedEntities.size() + this->I : this->I;
         PPEntityID ID = Self->getPPEntityID(Index, isLoaded);
         return Self->getPreprocessedEntity(ID);
       }
-      
-      value_type operator[](difference_type D) {
-        return *(*this + D);
-      }
-      
-      iterator &operator++() {
-        ++Position;
-        return *this;
-      }
-      
-      iterator operator++(int) {
-        iterator Prev(*this);
-        ++Position;
-        return Prev;
-      }
-
-      iterator &operator--() {
-        --Position;
-        return *this;
-      }
-      
-      iterator operator--(int) {
-        iterator Prev(*this);
-        --Position;
-        return Prev;
-      }
-
-      friend bool operator==(const iterator &X, const iterator &Y) {
-        return X.Position == Y.Position;
-      }
-
-      friend bool operator!=(const iterator &X, const iterator &Y) {
-        return X.Position != Y.Position;
-      }
-      
-      friend bool operator<(const iterator &X, const iterator &Y) {
-        return X.Position < Y.Position;
-      }
-
-      friend bool operator>(const iterator &X, const iterator &Y) {
-        return X.Position > Y.Position;
-      }
-
-      friend bool operator<=(const iterator &X, const iterator &Y) {
-        return X.Position < Y.Position;
-      }
-      
-      friend bool operator>=(const iterator &X, const iterator &Y) {
-        return X.Position > Y.Position;
-      }
-
-      friend iterator& operator+=(iterator &X, difference_type D) {
-        X.Position += D;
-        return X;
-      }
-
-      friend iterator& operator-=(iterator &X, difference_type D) {
-        X.Position -= D;
-        return X;
-      }
-
-      friend iterator operator+(iterator X, difference_type D) {
-        X.Position += D;
-        return X;
-      }
-
-      friend iterator operator+(difference_type D, iterator X) {
-        X.Position += D;
-        return X;
-      }
-
-      friend difference_type operator-(const iterator &X, const iterator &Y) {
-        return X.Position - Y.Position;
-      }
-
-      friend iterator operator-(iterator X, difference_type D) {
-        X.Position -= D;
-        return X;
-      }
-      friend class PreprocessingRecord;
+      PreprocessedEntity *operator->() const { return **this; }
     };
-    friend class iterator;
 
     /// \brief Begin iterator for all preprocessed entities.
     iterator begin() {
index c5f042a66c6cb518c9e9cb2ecd101a5a985b6319..dafcbbe58c91421ecc092e31536c6fe0d7f908e9 100644 (file)
@@ -88,7 +88,7 @@ bool PreprocessingRecord::isEntityInFileID(iterator PPEI, FileID FID) {
   if (FID.isInvalid())
     return false;
 
-  int Pos = PPEI.Position;
+  int Pos = std::distance(iterator(this, 0), PPEI);
   if (Pos < 0) {
     if (unsigned(-Pos-1) >= LoadedPreprocessedEntities.size()) {
       assert(0 && "Out-of bounds loaded preprocessed entity");