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_
#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>;

View 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);