Add Instruction begin and end mutable iterators
authorDavid Neto <dneto@google.com>
Thu, 25 Aug 2016 21:45:08 +0000 (17:45 -0400)
committerDavid Neto <dneto@google.com>
Thu, 25 Aug 2016 21:48:58 +0000 (17:48 -0400)
Refactored the instuction test.

source/opt/instruction.h
test/opt/test_instruction.cpp

index 0c08c72..5e6043a 100644 (file)
@@ -79,6 +79,7 @@ struct Operand {
 // needs to change, the user should create a new instruction instead.
 class Instruction {
  public:
+  using iterator = std::vector<Operand>::iterator;
   using const_iterator = std::vector<Operand>::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(); }
index 6e7ee61..fb64ade 100644 (file)
@@ -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<uint32_t>{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<uint32_t>{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<uint32_t>{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