A `std::vector ` value.
| 497 | |
| 498 | |
| 499 | class StdVector(Sequence): |
| 500 | """ |
| 501 | A `std::vector<T>` value. |
| 502 | """ |
| 503 | |
| 504 | def __init__(self, val): |
| 505 | self.val = val |
| 506 | try: |
| 507 | # libstdc++ internals |
| 508 | impl = self.val['_M_impl'] |
| 509 | self._data = impl['_M_start'] |
| 510 | self._size = int(impl['_M_finish'] - self._data) |
| 511 | except gdb.error: |
| 512 | # fallback for other C++ standard libraries |
| 513 | self._data = int(gdb.parse_and_eval( |
| 514 | f"{for_evaluation(self.val)}.data()")) |
| 515 | self._size = int(gdb.parse_and_eval( |
| 516 | f"{for_evaluation(self.val)}.size()")) |
| 517 | |
| 518 | def _check_index(self, index): |
| 519 | if index < 0 or index >= self._size: |
| 520 | raise IndexError( |
| 521 | f"Index {index} out of bounds (should be in [0, {self._size - 1}])") |
| 522 | |
| 523 | def __len__(self): |
| 524 | return self._size |
| 525 | |
| 526 | def __getitem__(self, index): |
| 527 | self._check_index(index) |
| 528 | return self._data[index] |
| 529 | |
| 530 | def eval_at(self, index, eval_format): |
| 531 | """ |
| 532 | Run `eval_format` with the value at `index`. |
| 533 | |
| 534 | For example, if `eval_format` is "{}.get()", this will evaluate |
| 535 | "{self[index]}.get()". |
| 536 | """ |
| 537 | self._check_index(index) |
| 538 | return gdb.parse_and_eval( |
| 539 | eval_format.format(for_evaluation(self._data[index]))) |
| 540 | |
| 541 | def iter_eval(self, eval_format): |
| 542 | data_eval = for_evaluation(self._data) |
| 543 | for i in range(self._size): |
| 544 | yield gdb.parse_and_eval( |
| 545 | eval_format.format(f"{data_eval}[{i}]")) |
| 546 | |
| 547 | @property |
| 548 | def size(self): |
| 549 | return self._size |
| 550 | |
| 551 | |
| 552 | class StdPtrVector(StdVector): |