Derive iterator from std::iterator to reap standarad algorithms.
authorLei Zhang <antiagainst@google.com>
Mon, 15 Aug 2016 15:13:25 +0000 (11:13 -0400)
committerLei Zhang <antiagainst@google.com>
Mon, 15 Aug 2016 20:29:56 +0000 (16:29 -0400)
By deriving from std::iterator, iterator_traits will be properly
set up for our custom iterator type, thus we can use algorithms
from STL with our custom iterators.

source/opt/iterator.h
test/opt/test_ir_loader.cpp

index e31fedf..6ca3dbc 100644 (file)
@@ -27,6 +27,7 @@
 #ifndef LIBSPIRV_OPT_ITERATOR_H_
 #define LIBSPIRV_OPT_ITERATOR_H_
 
+#include <iterator>
 #include <memory>
 #include <type_traits>
 #include <vector>
@@ -39,12 +40,17 @@ namespace ir {
 // std::unique_ptr managed elements in the vector, behaving like we are using
 // std::vector<|ValueType|>.
 template <typename ValueType, bool IsConst = false>
-class UptrVectorIterator {
+class UptrVectorIterator
+    : public std::iterator<std::random_access_iterator_tag,
+                           typename std::conditional<IsConst, const ValueType,
+                                                     ValueType>::type> {
  public:
-  using pointer =
-      typename std::conditional<IsConst, const ValueType*, ValueType*>::type;
-  using reference =
-      typename std::conditional<IsConst, const ValueType&, ValueType&>::type;
+  using super = std::iterator<
+      std::random_access_iterator_tag,
+      typename std::conditional<IsConst, const ValueType, ValueType>::type>;
+
+  using pointer = typename super::pointer;
+  using reference = typename super::reference;
 
   // Type aliases. We need to apply constness properly if |IsConst| is true.
   using Uptr = std::unique_ptr<ValueType>;
index 7d4cca0..8717140 100644 (file)
@@ -25,6 +25,7 @@
 // MATERIALS OR THE USE OR OTHER DEALINGS IN THE MATERIALS.
 
 #include <gtest/gtest.h>
+#include <algorithm>
 
 #include "opt/libspirv.hpp"
 
@@ -212,11 +213,10 @@ TEST(IrBuilder, OpUndefOutsideFunction) {
   std::unique_ptr<ir::Module> module = t.BuildModule(text);
   ASSERT_NE(nullptr, module);
 
-  int opundef_count = 0;
-  for (const auto& inst : module->types_values()) {
-    if (inst.opcode() == SpvOpUndef) ++opundef_count;
-  }
-  EXPECT_EQ(3, opundef_count);
+  const auto opundef_count = std::count_if(
+      module->types_values_begin(), module->types_values_end(),
+      [](const ir::Instruction& inst) { return inst.opcode() == SpvOpUndef; });
+  EXPECT_EQ(3u, opundef_count);
 
   std::vector<uint32_t> binary;
   module->ToBinary(&binary, /* skip_nop = */ false);