Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 5 additions & 5 deletions include/protozero/iterators.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -243,30 +243,30 @@ class const_fixed_iterator {
}

const_fixed_iterator& operator+=(difference_type val) noexcept {
m_data += (sizeof(value_type) * val);
m_data += (static_cast<difference_type>(sizeof(value_type)) * val);
return *this;
}

friend const_fixed_iterator operator+(const_fixed_iterator lhs, difference_type rhs) noexcept {
const_fixed_iterator tmp{lhs};
tmp.m_data += (sizeof(value_type) * rhs);
tmp.m_data += (static_cast<difference_type>(sizeof(value_type)) * rhs);
return tmp;
}

friend const_fixed_iterator operator+(difference_type lhs, const_fixed_iterator rhs) noexcept {
const_fixed_iterator tmp{rhs};
tmp.m_data += (sizeof(value_type) * lhs);
tmp.m_data += (static_cast<difference_type>(sizeof(value_type)) * lhs);
return tmp;
}

const_fixed_iterator& operator-=(difference_type val) noexcept {
m_data -= (sizeof(value_type) * val);
m_data -= (static_cast<difference_type>(sizeof(value_type)) * val);
return *this;
}

friend const_fixed_iterator operator-(const_fixed_iterator lhs, difference_type rhs) noexcept {
const_fixed_iterator tmp{lhs};
tmp.m_data -= (sizeof(value_type) * rhs);
tmp.m_data -= (static_cast<difference_type>(sizeof(value_type)) * rhs);
return tmp;
}

Expand Down
28 changes: 28 additions & 0 deletions test/unit/test_iterators.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -40,3 +40,31 @@ TEST_CASE("get_packed varint rejects a truncated trailing varint") {
REQUIRE_THROWS_AS(item.get_packed_uint64(), protozero::end_of_buffer_exception);
}


TEST_CASE("fixed_iterator supports negative offsets") {
// field 1, wire type 2; length 12; fixed32 values 1, 2 and 3.
const std::string buffer{"\x0a\x0c\x01\x00\x00\x00\x02\x00\x00\x00\x03\x00\x00\x00", 14};
protozero::pbf_reader item{buffer};

REQUIRE(item.next());
const auto range = item.get_packed_fixed32();
const auto end = range.end();

REQUIRE(*std::prev(end) == 3);
REQUIRE(end[-1] == 3);
REQUIRE(end[-3] == 1);
REQUIRE(*(end + -2) == 2);
REQUIRE(*(-2 + end) == 2);
REQUIRE(*(end - 2) == 2);
REQUIRE(*(range.begin() - -1) == 2);

auto it = end;
it += -1;
REQUIRE(*it == 3);
it -= 1;
REQUIRE(*it == 2);
it -= -1;
REQUIRE(*it == 3);
REQUIRE(it - end == -1);
REQUIRE(range.begin() - end == -3);
}
Loading