I'm trying to insert an item at the beginning of a protobuf list of messages. add_foo
appends the item to end. Is there an easy way to insert it at the beginning?
Asked
Active
Viewed 8,107 times
4

Matthew Finlay
- 3,354
- 2
- 27
- 32
1 Answers
10
There's no built-in way to do this with protocol buffers AFAIK. Certainly the docs don't seem to indicate any such option.
A reasonably efficient way might be to add the new element at the end as normal, then reverse iterate through the elements, swapping the new element in front of the previous one until it's at the front of the list. So e.g. for a protobuf message like:
message Bar {
repeated bytes foo = 1;
}
you could do:
Bar bar;
bar.add_foo("two");
bar.add_foo("three");
// Push back new element
bar.add_foo("one");
// Get mutable pointer to repeated field
google::protobuf::RepeatedPtrField<std::string> *foo_field(bar.mutable_foo());
// Reverse iterate, swapping new element in front each time
for (int i(bar.foo_size() - 1); i > 0; --i)
foo_field->SwapElements(i, i - 1);
std::cout << bar.DebugString() << '\n';

Fraser
- 74,704
- 20
- 238
- 215
-
the docs [https://developers.google.com/protocol-buffers/docs/reference/cpp/google.protobuf.repeated_field#RepeatedField.Add.details] seem to indicate there is a Add(Iter begin, Iter end) signature, could you do something like foo_field.add(foo_field().iterator(), foo_field.iterator()) and then the new first elem will be accessible with foo_field.get(0)? – TheoretiCAL Jan 05 '21 at 01:30
-
nope, the `Add(Iter begin, Iter end)` is for appending to one container from another range. What I did was to create a new container, then override the original. – Yomi1984 Sep 22 '22 at 11:56