Derive iterator from std::iterator to reap standarad algorithms.

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.
This commit is contained in:
Lei Zhang 2016-08-15 11:13:25 -04:00
parent 1eec0ed4b9
commit 9747d33d08
2 changed files with 16 additions and 10 deletions

View File

@ -27,6 +27,7 @@
#ifndef LIBSPIRV_OPT_ITERATOR_H_ #ifndef LIBSPIRV_OPT_ITERATOR_H_
#define LIBSPIRV_OPT_ITERATOR_H_ #define LIBSPIRV_OPT_ITERATOR_H_
#include <iterator>
#include <memory> #include <memory>
#include <type_traits> #include <type_traits>
#include <vector> #include <vector>
@ -39,12 +40,17 @@ namespace ir {
// std::unique_ptr managed elements in the vector, behaving like we are using // std::unique_ptr managed elements in the vector, behaving like we are using
// std::vector<|ValueType|>. // std::vector<|ValueType|>.
template <typename ValueType, bool IsConst = false> 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: public:
using pointer = using super = std::iterator<
typename std::conditional<IsConst, const ValueType*, ValueType*>::type; std::random_access_iterator_tag,
using reference = typename std::conditional<IsConst, const ValueType, ValueType>::type>;
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. // Type aliases. We need to apply constness properly if |IsConst| is true.
using Uptr = std::unique_ptr<ValueType>; using Uptr = std::unique_ptr<ValueType>;

View File

@ -25,6 +25,7 @@
// MATERIALS OR THE USE OR OTHER DEALINGS IN THE MATERIALS. // MATERIALS OR THE USE OR OTHER DEALINGS IN THE MATERIALS.
#include <gtest/gtest.h> #include <gtest/gtest.h>
#include <algorithm>
#include "opt/libspirv.hpp" #include "opt/libspirv.hpp"
@ -212,11 +213,10 @@ TEST(IrBuilder, OpUndefOutsideFunction) {
std::unique_ptr<ir::Module> module = t.BuildModule(text); std::unique_ptr<ir::Module> module = t.BuildModule(text);
ASSERT_NE(nullptr, module); ASSERT_NE(nullptr, module);
int opundef_count = 0; const auto opundef_count = std::count_if(
for (const auto& inst : module->types_values()) { module->types_values_begin(), module->types_values_end(),
if (inst.opcode() == SpvOpUndef) ++opundef_count; [](const ir::Instruction& inst) { return inst.opcode() == SpvOpUndef; });
} EXPECT_EQ(3u, opundef_count);
EXPECT_EQ(3, opundef_count);
std::vector<uint32_t> binary; std::vector<uint32_t> binary;
module->ToBinary(&binary, /* skip_nop = */ false); module->ToBinary(&binary, /* skip_nop = */ false);