File indexing completed on 2026-08-11 09:16:37
0001
0002
0003
0004
0005
0006
0007 #ifndef BOOST_UNORDERED_DETAIL_UNORDERED_PRINTERS_HPP
0008 #define BOOST_UNORDERED_DETAIL_UNORDERED_PRINTERS_HPP
0009
0010 #ifndef BOOST_ALL_NO_EMBEDDED_GDB_SCRIPTS
0011 #if defined(__ELF__)
0012 #ifdef __clang__
0013 #pragma clang diagnostic push
0014 #pragma clang diagnostic ignored "-Woverlength-strings"
0015 #endif
0016 __asm__(".pushsection \".debug_gdb_scripts\", \"MS\",%progbits,1\n"
0017 ".ascii \"\\4gdb.inlined-script.BOOST_UNORDERED_DETAIL_UNORDERED_PRINTERS_HPP\\n\"\n"
0018 ".ascii \"import gdb.printing\\n\"\n"
0019 ".ascii \"import gdb.xmethod\\n\"\n"
0020 ".ascii \"import re\\n\"\n"
0021 ".ascii \"import math\\n\"\n"
0022
0023 ".ascii \"class BoostUnorderedHelpers:\\n\"\n"
0024 ".ascii \" def maybe_unwrap_atomic(n):\\n\"\n"
0025 ".ascii \" if f\\\"{n.type.strip_typedefs()}\\\".startswith(\\\"std::atomic<\\\"):\\n\"\n"
0026 ".ascii \" underlying_type = n.type.template_argument(0)\\n\"\n"
0027 ".ascii \" return n.cast(underlying_type)\\n\"\n"
0028 ".ascii \" else:\\n\"\n"
0029 ".ascii \" return n\\n\"\n"
0030
0031 ".ascii \" def maybe_unwrap_foa_element(e):\\n\"\n"
0032 ".ascii \" if f\\\"{e.type.strip_typedefs()}\\\".startswith(\\\"boost::unordered::detail::foa::element_type<\\\"):\\n\"\n"
0033 ".ascii \" return e[\\\"p\\\"]\\n\"\n"
0034 ".ascii \" else:\\n\"\n"
0035 ".ascii \" return e\\n\"\n"
0036
0037 ".ascii \" def maybe_unwrap_reference(value):\\n\"\n"
0038 ".ascii \" if value.type.code == gdb.TYPE_CODE_REF:\\n\"\n"
0039 ".ascii \" return value.referenced_value()\\n\"\n"
0040 ".ascii \" else:\\n\"\n"
0041 ".ascii \" return value\\n\"\n"
0042
0043 ".ascii \" def countr_zero(n):\\n\"\n"
0044 ".ascii \" for i in range(32):\\n\"\n"
0045 ".ascii \" if (n & (1 << i)) != 0:\\n\"\n"
0046 ".ascii \" return i\\n\"\n"
0047 ".ascii \" return 32\\n\"\n"
0048
0049 ".ascii \"class BoostUnorderedPointerCustomizationPoint:\\n\"\n"
0050 ".ascii \" def __init__(self, any_ptr):\\n\"\n"
0051 ".ascii \" vis = gdb.default_visualizer(any_ptr)\\n\"\n"
0052 ".ascii \" if vis is None:\\n\"\n"
0053 ".ascii \" self.to_address = lambda ptr: ptr\\n\"\n"
0054 ".ascii \" self.next = lambda ptr, offset: ptr + offset\\n\"\n"
0055 ".ascii \" else:\\n\"\n"
0056 ".ascii \" self.to_address = lambda ptr: ptr if (ptr.type.code == gdb.TYPE_CODE_PTR) else type(vis).boost_to_address(ptr)\\n\"\n"
0057 ".ascii \" self.next = lambda ptr, offset: type(vis).boost_next(ptr, offset)\\n\"\n"
0058
0059 ".ascii \"class BoostUnorderedFcaPrinter:\\n\"\n"
0060 ".ascii \" def __init__(self, val):\\n\"\n"
0061 ".ascii \" val = BoostUnorderedHelpers.maybe_unwrap_reference(val)\\n\"\n"
0062 ".ascii \" self.table = val[\\\"table_\\\"]\\n\"\n"
0063 ".ascii \" self.name = f\\\"{val.type.strip_typedefs()}\\\".split(\\\"<\\\")[0]\\n\"\n"
0064 ".ascii \" self.name = self.name.replace(\\\"boost::unordered::\\\", \\\"boost::\\\")\\n\"\n"
0065 ".ascii \" self.is_map = self.name.endswith(\\\"map\\\")\\n\"\n"
0066 ".ascii \" self.cpo = BoostUnorderedPointerCustomizationPoint(self.table[\\\"buckets_\\\"][\\\"buckets\\\"])\\n\"\n"
0067
0068 ".ascii \" def to_string(self):\\n\"\n"
0069 ".ascii \" size = self.table[\\\"size_\\\"]\\n\"\n"
0070 ".ascii \" return f\\\"{self.name} with {size} elements\\\"\\n\"\n"
0071
0072 ".ascii \" def display_hint(self):\\n\"\n"
0073 ".ascii \" return \\\"map\\\"\\n\"\n"
0074
0075 ".ascii \" def children(self):\\n\"\n"
0076 ".ascii \" def generator():\\n\"\n"
0077 ".ascii \" grouped_buckets = self.table[\\\"buckets_\\\"]\\n\"\n"
0078
0079 ".ascii \" size = grouped_buckets[\\\"size_\\\"]\\n\"\n"
0080 ".ascii \" buckets = grouped_buckets[\\\"buckets\\\"]\\n\"\n"
0081 ".ascii \" bucket_index = 0\\n\"\n"
0082
0083 ".ascii \" count = 0\\n\"\n"
0084 ".ascii \" while bucket_index != size:\\n\"\n"
0085 ".ascii \" current_bucket = self.cpo.next(self.cpo.to_address(buckets), bucket_index)\\n\"\n"
0086 ".ascii \" node = self.cpo.to_address(current_bucket.dereference()[\\\"next\\\"])\\n\"\n"
0087 ".ascii \" while node != 0:\\n\"\n"
0088 ".ascii \" value = node.dereference()[\\\"buf\\\"][\\\"t_\\\"]\\n\"\n"
0089 ".ascii \" if self.is_map:\\n\"\n"
0090 ".ascii \" first = value[\\\"first\\\"]\\n\"\n"
0091 ".ascii \" second = value[\\\"second\\\"]\\n\"\n"
0092 ".ascii \" yield \\\"\\\", first\\n\"\n"
0093 ".ascii \" yield \\\"\\\", second\\n\"\n"
0094 ".ascii \" else:\\n\"\n"
0095 ".ascii \" yield \\\"\\\", count\\n\"\n"
0096 ".ascii \" yield \\\"\\\", value\\n\"\n"
0097 ".ascii \" count += 1\\n\"\n"
0098 ".ascii \" node = self.cpo.to_address(node.dereference()[\\\"next\\\"])\\n\"\n"
0099 ".ascii \" bucket_index += 1\\n\"\n"
0100
0101 ".ascii \" return generator()\\n\"\n"
0102
0103 ".ascii \"class BoostUnorderedFcaIteratorPrinter:\\n\"\n"
0104 ".ascii \" def __init__(self, val):\\n\"\n"
0105 ".ascii \" self.val = val\\n\"\n"
0106 ".ascii \" self.cpo = BoostUnorderedPointerCustomizationPoint(self.val[\\\"p\\\"])\\n\"\n"
0107
0108 ".ascii \" def to_string(self):\\n\"\n"
0109 ".ascii \" if self.valid():\\n\"\n"
0110 ".ascii \" value = self.cpo.to_address(self.val[\\\"p\\\"]).dereference()[\\\"buf\\\"][\\\"t_\\\"]\\n\"\n"
0111 ".ascii \" return f\\\"iterator = {{ {value} }}\\\"\\n\"\n"
0112 ".ascii \" else:\\n\"\n"
0113 ".ascii \" return \\\"iterator = { end iterator }\\\"\\n\"\n"
0114
0115 ".ascii \" def valid(self):\\n\"\n"
0116 ".ascii \" return (self.cpo.to_address(self.val[\\\"p\\\"]) != 0) and (self.cpo.to_address(self.val[\\\"itb\\\"][\\\"p\\\"]) != 0)\\n\"\n"
0117
0118 ".ascii \"class BoostUnorderedFoaTableCoreCumulativeStatsPrinter:\\n\"\n"
0119 ".ascii \" def __init__(self, val):\\n\"\n"
0120 ".ascii \" self.val = val\\n\"\n"
0121
0122 ".ascii \" def to_string(self):\\n\"\n"
0123 ".ascii \" return \\\"[stats]\\\"\\n\"\n"
0124
0125 ".ascii \" def display_hint(self):\\n\"\n"
0126 ".ascii \" return \\\"map\\\"\\n\"\n"
0127
0128 ".ascii \" def children(self):\\n\"\n"
0129 ".ascii \" def generator():\\n\"\n"
0130 ".ascii \" members = [\\\"insertion\\\", \\\"successful_lookup\\\", \\\"unsuccessful_lookup\\\"]\\n\"\n"
0131 ".ascii \" for member in members:\\n\"\n"
0132 ".ascii \" yield \\\"\\\", member\\n\"\n"
0133 ".ascii \" yield \\\"\\\", self.val[member]\\n\"\n"
0134 ".ascii \" return generator()\\n\"\n"
0135
0136 ".ascii \"class BoostUnorderedFoaCumulativeStatsPrinter:\\n\"\n"
0137 ".ascii \" def __init__(self, val):\\n\"\n"
0138 ".ascii \" self.val = val\\n\"\n"
0139 ".ascii \" self.n = self.val[\\\"n\\\"]\\n\"\n"
0140 ".ascii \" self.N = self.val.type.template_argument(0)\\n\"\n"
0141
0142 ".ascii \" def display_hint(self):\\n\"\n"
0143 ".ascii \" return \\\"map\\\"\\n\"\n"
0144
0145 ".ascii \" def children(self):\\n\"\n"
0146 ".ascii \" def generator():\\n\"\n"
0147 ".ascii \" yield \\\"\\\", \\\"count\\\"\\n\"\n"
0148 ".ascii \" yield \\\"\\\", self.n\\n\"\n"
0149
0150 ".ascii \" sequence_stats_data = gdb.lookup_type(\\\"boost::unordered::detail::foa::sequence_stats_data\\\")\\n\"\n"
0151 ".ascii \" data = self.val[\\\"data\\\"]\\n\"\n"
0152 ".ascii \" arr = data.address.reinterpret_cast(sequence_stats_data.pointer())\\n\"\n"
0153 ".ascii \" def build_string(idx):\\n\"\n"
0154 ".ascii \" entry = arr[idx]\\n\"\n"
0155 ".ascii \" avg = float(entry[\\\"m\\\"])\\n\"\n"
0156 ".ascii \" var = float(entry[\\\"s\\\"] / self.n) if (self.n != 0) else 0.0\\n\"\n"
0157 ".ascii \" dev = math.sqrt(var)\\n\"\n"
0158 ".ascii \" return f\\\"{{avg = {avg}, var = {var}, dev = {dev}}}\\\"\\n\"\n"
0159
0160 ".ascii \" if self.N > 0:\\n\"\n"
0161 ".ascii \" yield \\\"\\\", \\\"probe_length\\\"\\n\"\n"
0162 ".ascii \" yield \\\"\\\", build_string(0)\\n\"\n"
0163 ".ascii \" if self.N > 1:\\n\"\n"
0164 ".ascii \" yield \\\"\\\", \\\"num_comparisons\\\"\\n\"\n"
0165 ".ascii \" yield \\\"\\\", build_string(1)\\n\"\n"
0166
0167 ".ascii \" return generator()\\n\"\n"
0168
0169 ".ascii \"class BoostUnorderedFoaPrinter:\\n\"\n"
0170 ".ascii \" def __init__(self, val):\\n\"\n"
0171 ".ascii \" val = BoostUnorderedHelpers.maybe_unwrap_reference(val)\\n\"\n"
0172 ".ascii \" self.table = val[\\\"table_\\\"]\\n\"\n"
0173 ".ascii \" self.name = f\\\"{val.type.strip_typedefs()}\\\".split(\\\"<\\\")[0]\\n\"\n"
0174 ".ascii \" self.name = self.name.replace(\\\"boost::unordered::\\\", \\\"boost::\\\")\\n\"\n"
0175 ".ascii \" self.is_map = self.name.endswith(\\\"map\\\")\\n\"\n"
0176 ".ascii \" self.cpo = BoostUnorderedPointerCustomizationPoint(self.table[\\\"arrays\\\"][\\\"groups_\\\"])\\n\"\n"
0177 ".ascii \" self.groups = self.cpo.to_address(self.table[\\\"arrays\\\"][\\\"groups_\\\"])\\n\"\n"
0178 ".ascii \" self.elements = self.cpo.to_address(self.table[\\\"arrays\\\"][\\\"elements_\\\"])\\n\"\n"
0179
0180 ".ascii \" self.N = 15 # `self.groups.dereference()[\\\"N\\\"]` may be optimized out\\n\"\n"
0181 ".ascii \" self.sentinel_ = 1 # `self.groups.dereference()[\\\"sentinel_\\\"]` may be optimized out\\n\"\n"
0182
0183 ".ascii \" def to_string(self):\\n\"\n"
0184 ".ascii \" size = BoostUnorderedHelpers.maybe_unwrap_atomic(self.table[\\\"size_ctrl\\\"][\\\"size\\\"])\\n\"\n"
0185 ".ascii \" return f\\\"{self.name} with {size} elements\\\"\\n\"\n"
0186
0187 ".ascii \" def display_hint(self):\\n\"\n"
0188 ".ascii \" return \\\"map\\\"\\n\"\n"
0189
0190 ".ascii \" def is_regular_layout(self, group):\\n\"\n"
0191 ".ascii \" typename = group[\\\"m\\\"].type.strip_typedefs()\\n\"\n"
0192 ".ascii \" array_size = typename.sizeof // typename.target().sizeof\\n\"\n"
0193 ".ascii \" if array_size == 16:\\n\"\n"
0194 ".ascii \" return True\\n\"\n"
0195 ".ascii \" elif array_size == 2:\\n\"\n"
0196 ".ascii \" return False\\n\"\n"
0197
0198 ".ascii \" def match_occupied(self, group):\\n\"\n"
0199 ".ascii \" m = group[\\\"m\\\"]\\n\"\n"
0200 ".ascii \" at = lambda b: BoostUnorderedHelpers.maybe_unwrap_atomic(m[b][\\\"n\\\"])\\n\"\n"
0201
0202 ".ascii \" if self.is_regular_layout(group):\\n\"\n"
0203 ".ascii \" bits = [1 << b for b in range(16) if at(b) == 0]\\n\"\n"
0204 ".ascii \" return 0x7FFF & ~sum(bits)\\n\"\n"
0205 ".ascii \" else:\\n\"\n"
0206 ".ascii \" xx = at(0) | at(1)\\n\"\n"
0207 ".ascii \" yy = xx | (xx >> 32)\\n\"\n"
0208 ".ascii \" return 0x7FFF & (yy | (yy >> 16))\\n\"\n"
0209
0210 ".ascii \" def is_sentinel(self, group, pos):\\n\"\n"
0211 ".ascii \" m = group[\\\"m\\\"]\\n\"\n"
0212 ".ascii \" at = lambda b: BoostUnorderedHelpers.maybe_unwrap_atomic(m[b][\\\"n\\\"])\\n\"\n"
0213
0214 ".ascii \" if self.is_regular_layout(group):\\n\"\n"
0215 ".ascii \" return pos == self.N-1 and at(self.N-1) == self.sentinel_\\n\"\n"
0216 ".ascii \" else:\\n\"\n"
0217 ".ascii \" return pos == self.N-1 and (at(0) & 0x4000400040004000) == 0x4000 and (at(1) & 0x4000400040004000) == 0\\n\"\n"
0218
0219 ".ascii \" def children(self):\\n\"\n"
0220 ".ascii \" def generator():\\n\"\n"
0221 ".ascii \" pc_ = self.groups.cast(gdb.lookup_type(\\\"unsigned char\\\").pointer())\\n\"\n"
0222 ".ascii \" p_ = self.elements\\n\"\n"
0223 ".ascii \" first_time = True\\n\"\n"
0224
0225 ".ascii \" count = 0\\n\"\n"
0226 ".ascii \" while p_ != 0:\\n\"\n"
0227 ".ascii \" # This if block mirrors the condition in the begin() call\\n\"\n"
0228 ".ascii \" if (not first_time) or (self.match_occupied(self.groups.dereference()) & 1):\\n\"\n"
0229 ".ascii \" pointer = BoostUnorderedHelpers.maybe_unwrap_foa_element(p_)\\n\"\n"
0230 ".ascii \" value = self.cpo.to_address(pointer).dereference()\\n\"\n"
0231 ".ascii \" if self.is_map:\\n\"\n"
0232 ".ascii \" first = value[\\\"first\\\"]\\n\"\n"
0233 ".ascii \" second = value[\\\"second\\\"]\\n\"\n"
0234 ".ascii \" yield \\\"\\\", first\\n\"\n"
0235 ".ascii \" yield \\\"\\\", second\\n\"\n"
0236 ".ascii \" else:\\n\"\n"
0237 ".ascii \" yield \\\"\\\", count\\n\"\n"
0238 ".ascii \" yield \\\"\\\", value\\n\"\n"
0239 ".ascii \" count += 1\\n\"\n"
0240 ".ascii \" first_time = False\\n\"\n"
0241
0242 ".ascii \" n0 = pc_.cast(gdb.lookup_type(\\\"uintptr_t\\\")) % self.groups.dereference().type.sizeof\\n\"\n"
0243 ".ascii \" pc_ = self.cpo.next(pc_, -n0)\\n\"\n"
0244
0245 ".ascii \" mask = (self.match_occupied(pc_.cast(self.groups.type).dereference()) >> (n0+1)) << (n0+1)\\n\"\n"
0246 ".ascii \" while mask == 0:\\n\"\n"
0247 ".ascii \" pc_ = self.cpo.next(pc_, self.groups.dereference().type.sizeof)\\n\"\n"
0248 ".ascii \" p_ = self.cpo.next(p_, self.N)\\n\"\n"
0249 ".ascii \" mask = self.match_occupied(pc_.cast(self.groups.type).dereference())\\n\"\n"
0250
0251 ".ascii \" n = BoostUnorderedHelpers.countr_zero(mask)\\n\"\n"
0252 ".ascii \" if self.is_sentinel(pc_.cast(self.groups.type).dereference(), n):\\n\"\n"
0253 ".ascii \" p_ = 0\\n\"\n"
0254 ".ascii \" else:\\n\"\n"
0255 ".ascii \" pc_ = self.cpo.next(pc_, n)\\n\"\n"
0256 ".ascii \" p_ = self.cpo.next(p_, n - n0)\\n\"\n"
0257
0258 ".ascii \" return generator()\\n\"\n"
0259
0260 ".ascii \"class BoostUnorderedFoaIteratorPrinter:\\n\"\n"
0261 ".ascii \" def __init__(self, val):\\n\"\n"
0262 ".ascii \" self.val = val\\n\"\n"
0263 ".ascii \" self.cpo = BoostUnorderedPointerCustomizationPoint(self.val[\\\"p_\\\"])\\n\"\n"
0264
0265 ".ascii \" def to_string(self):\\n\"\n"
0266 ".ascii \" if self.valid():\\n\"\n"
0267 ".ascii \" element = self.cpo.to_address(self.val[\\\"p_\\\"])\\n\"\n"
0268 ".ascii \" pointer = BoostUnorderedHelpers.maybe_unwrap_foa_element(element)\\n\"\n"
0269 ".ascii \" value = self.cpo.to_address(pointer).dereference()\\n\"\n"
0270 ".ascii \" return f\\\"iterator = {{ {value} }}\\\"\\n\"\n"
0271 ".ascii \" else:\\n\"\n"
0272 ".ascii \" return \\\"iterator = { end iterator }\\\"\\n\"\n"
0273
0274 ".ascii \" def valid(self):\\n\"\n"
0275 ".ascii \" return (self.cpo.to_address(self.val[\\\"p_\\\"]) != 0) and (self.cpo.to_address(self.val[\\\"pc_\\\"]) != 0)\\n\"\n"
0276
0277 ".ascii \"def boost_unordered_build_pretty_printer():\\n\"\n"
0278 ".ascii \" pp = gdb.printing.RegexpCollectionPrettyPrinter(\\\"boost_unordered\\\")\\n\"\n"
0279 ".ascii \" add_template_printer = lambda name, printer: pp.add_printer(name, f\\\"^{name}<.*>$\\\", printer)\\n\"\n"
0280 ".ascii \" add_concrete_printer = lambda name, printer: pp.add_printer(name, f\\\"^{name}$\\\", printer)\\n\"\n"
0281
0282 ".ascii \" add_template_printer(\\\"boost::unordered::unordered_map\\\", BoostUnorderedFcaPrinter)\\n\"\n"
0283 ".ascii \" add_template_printer(\\\"boost::unordered::unordered_multimap\\\", BoostUnorderedFcaPrinter)\\n\"\n"
0284 ".ascii \" add_template_printer(\\\"boost::unordered::unordered_set\\\", BoostUnorderedFcaPrinter)\\n\"\n"
0285 ".ascii \" add_template_printer(\\\"boost::unordered::unordered_multiset\\\", BoostUnorderedFcaPrinter)\\n\"\n"
0286
0287 ".ascii \" add_template_printer(\\\"boost::unordered::detail::iterator_detail::iterator\\\", BoostUnorderedFcaIteratorPrinter)\\n\"\n"
0288 ".ascii \" add_template_printer(\\\"boost::unordered::detail::iterator_detail::c_iterator\\\", BoostUnorderedFcaIteratorPrinter)\\n\"\n"
0289
0290 ".ascii \" add_template_printer(\\\"boost::unordered::unordered_flat_map\\\", BoostUnorderedFoaPrinter)\\n\"\n"
0291 ".ascii \" add_template_printer(\\\"boost::unordered::unordered_flat_set\\\", BoostUnorderedFoaPrinter)\\n\"\n"
0292 ".ascii \" add_template_printer(\\\"boost::unordered::unordered_node_map\\\", BoostUnorderedFoaPrinter)\\n\"\n"
0293 ".ascii \" add_template_printer(\\\"boost::unordered::unordered_node_set\\\", BoostUnorderedFoaPrinter)\\n\"\n"
0294 ".ascii \" add_template_printer(\\\"boost::unordered::concurrent_flat_map\\\", BoostUnorderedFoaPrinter)\\n\"\n"
0295 ".ascii \" add_template_printer(\\\"boost::unordered::concurrent_flat_set\\\", BoostUnorderedFoaPrinter)\\n\"\n"
0296 ".ascii \" add_template_printer(\\\"boost::unordered::concurrent_node_map\\\", BoostUnorderedFoaPrinter)\\n\"\n"
0297 ".ascii \" add_template_printer(\\\"boost::unordered::concurrent_node_set\\\", BoostUnorderedFoaPrinter)\\n\"\n"
0298
0299 ".ascii \" add_template_printer(\\\"boost::unordered::detail::foa::table_iterator\\\", BoostUnorderedFoaIteratorPrinter)\\n\"\n"
0300
0301 ".ascii \" add_concrete_printer(\\\"boost::unordered::detail::foa::table_core_cumulative_stats\\\", BoostUnorderedFoaTableCoreCumulativeStatsPrinter)\\n\"\n"
0302 ".ascii \" add_template_printer(\\\"boost::unordered::detail::foa::cumulative_stats\\\", BoostUnorderedFoaCumulativeStatsPrinter)\\n\"\n"
0303 ".ascii \" add_template_printer(\\\"boost::unordered::detail::foa::concurrent_cumulative_stats\\\", BoostUnorderedFoaCumulativeStatsPrinter)\\n\"\n"
0304
0305 ".ascii \" return pp\\n\"\n"
0306
0307 ".ascii \"gdb.printing.register_pretty_printer(gdb.current_objfile(), boost_unordered_build_pretty_printer())\\n\"\n"
0308
0309
0310
0311 ".ascii \"# https://sourceware.org/gdb/current/onlinedocs/gdb.html/Writing-an-Xmethod.html\\n\"\n"
0312 ".ascii \"class BoostUnorderedFoaGetStatsMethod(gdb.xmethod.XMethod):\\n\"\n"
0313 ".ascii \" def __init__(self):\\n\"\n"
0314 ".ascii \" gdb.xmethod.XMethod.__init__(self, \\\"get_stats\\\")\\n\"\n"
0315
0316 ".ascii \" def get_worker(self, method_name):\\n\"\n"
0317 ".ascii \" if method_name == \\\"get_stats\\\":\\n\"\n"
0318 ".ascii \" return BoostUnorderedFoaGetStatsWorker()\\n\"\n"
0319
0320 ".ascii \"class BoostUnorderedFoaGetStatsWorker(gdb.xmethod.XMethodWorker):\\n\"\n"
0321 ".ascii \" def get_arg_types(self):\\n\"\n"
0322 ".ascii \" return None\\n\"\n"
0323
0324 ".ascii \" def get_result_type(self, obj):\\n\"\n"
0325 ".ascii \" return gdb.lookup_type(\\\"boost::unordered::detail::foa::table_core_cumulative_stats\\\")\\n\"\n"
0326
0327 ".ascii \" def __call__(self, obj):\\n\"\n"
0328 ".ascii \" try:\\n\"\n"
0329 ".ascii \" return obj[\\\"table_\\\"][\\\"cstats\\\"]\\n\"\n"
0330 ".ascii \" except gdb.error:\\n\"\n"
0331 ".ascii \" print(\\\"Error: Binary was compiled without stats. Recompile with `BOOST_UNORDERED_ENABLE_STATS` defined.\\\")\\n\"\n"
0332 ".ascii \" return\\n\"\n"
0333
0334 ".ascii \"class BoostUnorderedFoaMatcher(gdb.xmethod.XMethodMatcher):\\n\"\n"
0335 ".ascii \" def __init__(self):\\n\"\n"
0336 ".ascii \" gdb.xmethod.XMethodMatcher.__init__(self, 'BoostUnorderedFoaMatcher')\\n\"\n"
0337 ".ascii \" self.methods = [BoostUnorderedFoaGetStatsMethod()]\\n\"\n"
0338
0339 ".ascii \" def match(self, class_type, method_name):\\n\"\n"
0340 ".ascii \" template_name = f\\\"{class_type.strip_typedefs()}\\\".split(\\\"<\\\")[0]\\n\"\n"
0341 ".ascii \" regex = \\\"^boost::unordered::(unordered|concurrent)_(flat|node)_(map|set)$\\\"\\n\"\n"
0342 ".ascii \" if not re.match(regex, template_name):\\n\"\n"
0343 ".ascii \" return None\\n\"\n"
0344
0345 ".ascii \" workers = []\\n\"\n"
0346 ".ascii \" for method in self.methods:\\n\"\n"
0347 ".ascii \" if method.enabled:\\n\"\n"
0348 ".ascii \" worker = method.get_worker(method_name)\\n\"\n"
0349 ".ascii \" if worker:\\n\"\n"
0350 ".ascii \" workers.append(worker)\\n\"\n"
0351 ".ascii \" return workers\\n\"\n"
0352
0353 ".ascii \"gdb.xmethod.register_xmethod_matcher(None, BoostUnorderedFoaMatcher())\\n\"\n"
0354
0355
0356
0357 ".ascii \"\\\"\\\"\\\" Fancy pointer support \\\"\\\"\\\"\\n\"\n"
0358
0359 ".ascii \"\\\"\\\"\\\"\\n\"\n"
0360 ".ascii \"To allow your own fancy pointer type to interact with Boost.Unordered GDB pretty-printers,\\n\"\n"
0361 ".ascii \"create a pretty-printer for your own type with the following additional methods.\\n\"\n"
0362
0363 ".ascii \"(Note, this is assuming the presence of a type alias `pointer` for the underlying\\n\"\n"
0364 ".ascii \"raw pointer type, Substitute whichever name is applicable in your case.)\\n\"\n"
0365
0366 ".ascii \"`boost_to_address(fancy_ptr)`\\n\"\n"
0367 ".ascii \" * A static method, but `@staticmethod` is not required\\n\"\n"
0368 ".ascii \" * Parameter `fancy_ptr` of type `gdb.Value`\\n\"\n"
0369 ".ascii \" * Its `.type` will be your fancy pointer type\\n\"\n"
0370 ".ascii \" * Returns a `gdb.Value` with the raw pointer equivalent to your fancy pointer\\n\"\n"
0371 ".ascii \" * This method should be equivalent to calling `operator->()` on your fancy pointer in C++\\n\"\n"
0372
0373 ".ascii \"`boost_next(raw_ptr, offset)`\\n\"\n"
0374 ".ascii \" * Parameter `raw_ptr` of type `gdb.Value`\\n\"\n"
0375 ".ascii \" * Its `.type` will be `pointer`\\n\"\n"
0376 ".ascii \" * Parameter `offset`\\n\"\n"
0377 ".ascii \" * Either has integer type, or is of type `gdb.Value` with an underlying integer\\n\"\n"
0378 ".ascii \" * Returns a `gdb.Value` with the raw pointer equivalent to your fancy pointer, as if you did the following operations\\n\"\n"
0379 ".ascii \" 1. Convert the incoming raw pointer to your fancy pointer\\n\"\n"
0380 ".ascii \" 2. Use operator+= to add the offset to the fancy pointer\\n\"\n"
0381 ".ascii \" 3. Convert back to the raw pointer\\n\"\n"
0382 ".ascii \" * Note, you will not actually do these operations as stated. You will do equivalent lower-level operations that emulate having done the above\\n\"\n"
0383 ".ascii \" * Ultimately, it will be as if you called `operator+()` on your fancy pointer in C++, but using only raw pointers\\n\"\n"
0384
0385 ".ascii \"Example\\n\"\n"
0386 ".ascii \"```\\n\"\n"
0387 ".ascii \"class MyFancyPtrPrinter:\\n\"\n"
0388 ".ascii \" ...\\n\"\n"
0389
0390 ".ascii \" # Equivalent to `operator->()`\\n\"\n"
0391 ".ascii \" def boost_to_address(fancy_ptr):\\n\"\n"
0392 ".ascii \" ...\\n\"\n"
0393 ".ascii \" return ...\\n\"\n"
0394
0395 ".ascii \" # Equivalent to `operator+()`\\n\"\n"
0396 ".ascii \" def boost_next(raw_ptr, offset):\\n\"\n"
0397 ".ascii \" ...\\n\"\n"
0398 ".ascii \" return ...\\n\"\n"
0399
0400 ".ascii \" ...\\n\"\n"
0401 ".ascii \"```\\n\"\n"
0402 ".ascii \"\\\"\\\"\\\"\\n\"\n"
0403
0404 ".byte 0\n"
0405 ".popsection\n");
0406 #ifdef __clang__
0407 #pragma clang diagnostic pop
0408 #endif
0409 #endif
0410 #endif
0411
0412 #endif