2010-05-10 9 views
6

ostatnio zacząłem używać doskonałego boost :: unordered_map na moim systemie, ale mam jedną wadę: nie mogłem wymyślić jak sprawdzić zawartość. Drukowanie go na gdb daje mi table_ i buckets_, ale nie znalazłem tam, gdzie są przedmioty. Ktoś ma o tym zielonego pojęcia?Bardzo dobre drukowanie :: unordered_map na gdb

Odpowiedz

10

Dla tych, którzy chcieli drukarki, udało mi się ją stworzyć. Oto kod:

class BoostUnorderedMapPrinter: 
    "prints a boost::unordered_map" 

    class _iterator: 
     def __init__ (self, fields): 
      type_1 = fields.val.type.template_argument(0) 
      type_2 = fields.val.type.template_argument(1) 
      self.buckets = fields.val['table_']['buckets_'] 
      self.bucket_count = fields.val['table_']['bucket_count_'] 
      self.current_bucket = 0 
      pair = "std::pair<%s const, %s>" % (type_1, type_2) 
      self.pair_pointer = gdb.lookup_type(pair).pointer() 
      self.base_pointer = gdb.lookup_type("boost::unordered_detail::value_base< %s >" % pair).pointer() 
      self.node_pointer = gdb.lookup_type("boost::unordered_detail::hash_node<std::allocator< %s >, boost::unordered_detail::ungrouped>" % pair).pointer() 
      self.node = self.buckets[self.current_bucket]['next_'] 

     def __iter__(self): 
      return self 

     def next(self): 
      while not self.node: 
       self.current_bucket = self.current_bucket + 1 
       if self.current_bucket >= self.bucket_count: 
        raise StopIteration 
       self.node = self.buckets[self.current_bucket]['next_'] 

      iterator = self.node.cast(self.node_pointer).cast(self.base_pointer).cast(self.pair_pointer).dereference() 
      self.node = self.node['next_'] 

      return ('%s' % iterator['first'], iterator['second']) 

    def __init__(self, val): 
     self.val = val 

    def children(self): 
     return self._iterator(self) 

    def to_string(self): 
     return "boost::unordered_map" 
+10

wiem Trochę się spóźniłem, ale w jaki sposób mogę załadować (i użyć) tej ładnej drukarki w GDB? –

+2

Dzięki za wysłanie tego. To nie działa dla późniejszych wersji (testowałem na 1.58+), ale wziąłem go i zaktualizowałem dziś rano, aby pracować z 1.58. Po nieco dłuższym czasie lotu zgłoszę prośbę o pociągnięcie do https://github.com/ruediger/Boost-Pretty-Printer, jeśli jest to w porządku. –

2

W typowej implementacji tablicy mieszania, segmenty zawierają nagłówek połączonej listy, która faktycznie zawiera wartości odpowiadające temu konkretnemu skrótowi. Dlatego postawiłbym na buckets_.

Inna opcja: istnieją różne biblioteki dla Pythona ładnej drukarki dla gdb teraz i myślę, że można znaleźć taki, który działa z C++ 0x i sprawdzić, gdzie szuka wartości.

+0

Jasne, mam sprawdzone realizacja gcc TR1 i struktury są całkiem różne, a zastąpić nie jest dobre, ponieważ znalazłem realizacja doładowania być szybszy niż odpowiednik tr1 – scooterman