From: David Neto Date: Thu, 25 Aug 2016 21:45:08 +0000 (-0400) Subject: Add Instruction begin and end mutable iterators X-Git-Tag: upstream/2018.6~1099 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=53013cc816328f1e3ce8370f46635f832993948e;p=platform%2Fupstream%2FSPIRV-Tools.git Add Instruction begin and end mutable iterators Refactored the instuction test. --- diff --git a/source/opt/instruction.h b/source/opt/instruction.h index 0c08c72..5e6043a 100644 --- a/source/opt/instruction.h +++ b/source/opt/instruction.h @@ -79,6 +79,7 @@ struct Operand { // needs to change, the user should create a new instruction instead. class Instruction { public: + using iterator = std::vector::iterator; using const_iterator = std::vector::const_iterator; // Creates a default OpNop instruction. @@ -119,6 +120,9 @@ class Instruction { return dbg_line_insts_; } + // Begin and end iterators for operands. + iterator begin() { return operands_.begin(); } + iterator end() { return operands_.end(); } // Const begin and end iterators for operands. const_iterator cbegin() const { return operands_.cbegin(); } const_iterator cend() const { return operands_.cend(); } diff --git a/test/opt/test_instruction.cpp b/test/opt/test_instruction.cpp index 6e7ee61..fb64ade 100644 --- a/test/opt/test_instruction.cpp +++ b/test/opt/test_instruction.cpp @@ -47,6 +47,7 @@ TEST(InstructionTest, CreateTrivial) { EXPECT_EQ(0u, empty.NumOperandWords()); EXPECT_EQ(0u, empty.NumInOperandWords()); EXPECT_EQ(empty.cend(), empty.cbegin()); + EXPECT_EQ(empty.end(), empty.begin()); } TEST(InstructionTest, CreateWithOpcodeAndNoOperands) { @@ -58,48 +59,92 @@ TEST(InstructionTest, CreateWithOpcodeAndNoOperands) { EXPECT_EQ(0u, inst.NumOperandWords()); EXPECT_EQ(0u, inst.NumInOperandWords()); EXPECT_EQ(inst.cend(), inst.cbegin()); + EXPECT_EQ(inst.end(), inst.begin()); } +// The words for an OpTypeInt for 32-bit signed integer resulting in Id 44. +uint32_t kSampleInstructionWords[] = {(4 << 16) | uint32_t(SpvOpTypeInt), 44, + 32, 1}; +// The operands that would be parsed from kSampleInstructionWords +spv_parsed_operand_t kSampleParsedOperands[] = { + {1, 1, SPV_OPERAND_TYPE_RESULT_ID, SPV_NUMBER_NONE, 0}, + {2, 1, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_NUMBER_UNSIGNED_INT, 32}, + {3, 1, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_NUMBER_UNSIGNED_INT, 1}, +}; + +// A valid parse of kSampleParsedOperands. +spv_parsed_instruction_t kSampleParsedInstruction = {kSampleInstructionWords, + uint16_t(4), + uint16_t(SpvOpTypeInt), + SPV_EXT_INST_TYPE_NONE, + 0, // type id + 44, // result id + kSampleParsedOperands, + 3}; TEST(InstructionTest, CreateWithOpcodeAndOperands) { - auto i32 = MakeInstruction(SpvOpTypeInt, {44, 32, 1}); - spv_parsed_operand_t parsed_operands[] = { - {1, 1, SPV_OPERAND_TYPE_RESULT_ID, SPV_NUMBER_NONE, 0}, - {2, 1, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_NUMBER_UNSIGNED_INT, 32}, - {3, 1, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_NUMBER_UNSIGNED_INT, 1}, - }; - spv_parsed_instruction_t parsed_inst{i32.data(), - uint16_t(i32.size()), - uint16_t(SpvOpTypeInt), - SPV_EXT_INST_TYPE_NONE, - 0, // type id - i32[1], // result id - parsed_operands, - 3}; - - Instruction inst(parsed_inst); + Instruction inst(kSampleParsedInstruction); EXPECT_EQ(SpvOpTypeInt, inst.opcode()); EXPECT_EQ(0u, inst.type_id()); EXPECT_EQ(44u, inst.result_id()); EXPECT_EQ(3u, inst.NumOperands()); EXPECT_EQ(3u, inst.NumOperandWords()); EXPECT_EQ(2u, inst.NumInOperandWords()); +} + +TEST(InstructionTest, OperandConstIterators) { + Instruction inst(kSampleParsedInstruction); + // Spot check iteration across operands. auto cbegin = inst.cbegin(); auto cend = inst.cend(); EXPECT_NE(cend, inst.cbegin()); - // Spot check iteration across operands. - auto iter = inst.cbegin(); - for (int i = 0; i < 3; ++i, ++iter) { - const auto& operand = *iter; - EXPECT_THAT(operand.type, Eq(parsed_operands[i].type)); - EXPECT_THAT(operand.words, Eq(std::vector{i32[i + 1]})); - EXPECT_NE(cend, iter); + auto citer = inst.cbegin(); + for (int i = 0; i < 3; ++i, ++citer) { + const auto& operand = *citer; + EXPECT_THAT(operand.type, Eq(kSampleParsedOperands[i].type)); + EXPECT_THAT(operand.words, + Eq(std::vector{kSampleInstructionWords[i + 1]})); + EXPECT_NE(cend, citer); } - EXPECT_EQ(cend, iter); + EXPECT_EQ(cend, citer); // Check that cbegin and cend have not changed. EXPECT_EQ(cbegin, inst.cbegin()); EXPECT_EQ(cend, inst.cend()); + + // Check arithmetic. + const Operand& operand2 = *(inst.cbegin() + 2); + EXPECT_EQ(SPV_OPERAND_TYPE_LITERAL_INTEGER, operand2.type); +} + +TEST(InstructionTest, OperandIterators) { + Instruction inst(kSampleParsedInstruction); + // Spot check iteration across operands, with mutable iterators. + auto begin = inst.begin(); + auto end = inst.end(); + EXPECT_NE(end, inst.begin()); + + auto iter = inst.begin(); + for (int i = 0; i < 3; ++i, ++iter) { + const auto& operand = *iter; + EXPECT_THAT(operand.type, Eq(kSampleParsedOperands[i].type)); + EXPECT_THAT(operand.words, + Eq(std::vector{kSampleInstructionWords[i + 1]})); + EXPECT_NE(end, iter); + } + EXPECT_EQ(end, iter); + + // Check that begin and end have not changed. + EXPECT_EQ(begin, inst.begin()); + EXPECT_EQ(end, inst.end()); + + // Check arithmetic. + Operand& operand2 = *(inst.begin() + 2); + EXPECT_EQ(SPV_OPERAND_TYPE_LITERAL_INTEGER, operand2.type); + + // Check mutation through an iterator. + operand2.type = SPV_OPERAND_TYPE_TYPE_ID; + EXPECT_EQ(SPV_OPERAND_TYPE_TYPE_ID, (*(inst.cbegin() + 2)).type); } } // anonymous namespace