From 0bf3c5f485c9d9967a47869f626c4603f2f5d3ff Mon Sep 17 00:00:00 2001 From: Braden Ganetsky Date: Wed, 20 Aug 2025 20:23:21 -0500 Subject: [PATCH 1/4] Move unordered_printers.hpp into 'detail', where it should have been from the beginning This is not a public header. It is only meant to be consumed as a transitive include. --- include/boost/unordered/detail/foa/core.hpp | 2 +- include/boost/unordered/detail/implementation.hpp | 2 +- .../boost/unordered/{ => detail}/unordered_printers.hpp | 8 ++++---- 3 files changed, 6 insertions(+), 6 deletions(-) rename include/boost/unordered/{ => detail}/unordered_printers.hpp (98%) diff --git a/include/boost/unordered/detail/foa/core.hpp b/include/boost/unordered/detail/foa/core.hpp index ee6cb9270..fab358669 100644 --- a/include/boost/unordered/detail/foa/core.hpp +++ b/include/boost/unordered/detail/foa/core.hpp @@ -29,7 +29,7 @@ #include #include #include -#include +#include #include #include #include diff --git a/include/boost/unordered/detail/implementation.hpp b/include/boost/unordered/detail/implementation.hpp index d2c0cbd05..27e88187d 100644 --- a/include/boost/unordered/detail/implementation.hpp +++ b/include/boost/unordered/detail/implementation.hpp @@ -21,7 +21,7 @@ #include #include #include -#include +#include #include #include diff --git a/include/boost/unordered/unordered_printers.hpp b/include/boost/unordered/detail/unordered_printers.hpp similarity index 98% rename from include/boost/unordered/unordered_printers.hpp rename to include/boost/unordered/detail/unordered_printers.hpp index a7d0d1376..4786da15c 100644 --- a/include/boost/unordered/unordered_printers.hpp +++ b/include/boost/unordered/detail/unordered_printers.hpp @@ -4,8 +4,8 @@ // Generated on 2024-08-25T17:48:54 -#ifndef BOOST_UNORDERED_UNORDERED_PRINTERS_HPP -#define BOOST_UNORDERED_UNORDERED_PRINTERS_HPP +#ifndef BOOST_UNORDERED_DETAIL_UNORDERED_PRINTERS_HPP +#define BOOST_UNORDERED_DETAIL_UNORDERED_PRINTERS_HPP #ifndef BOOST_ALL_NO_EMBEDDED_GDB_SCRIPTS #if defined(__ELF__) @@ -14,7 +14,7 @@ #pragma clang diagnostic ignored "-Woverlength-strings" #endif __asm__(".pushsection \".debug_gdb_scripts\", \"MS\",%progbits,1\n" - ".ascii \"\\4gdb.inlined-script.BOOST_UNORDERED_UNORDERED_PRINTERS_HPP\\n\"\n" + ".ascii \"\\4gdb.inlined-script.BOOST_UNORDERED_DETAIL_UNORDERED_PRINTERS_HPP\\n\"\n" ".ascii \"import gdb.printing\\n\"\n" ".ascii \"import gdb.xmethod\\n\"\n" ".ascii \"import re\\n\"\n" @@ -411,4 +411,4 @@ __asm__(".pushsection \".debug_gdb_scripts\", \"MS\",%progbits,1\n" #endif // defined(__ELF__) #endif // !defined(BOOST_ALL_NO_EMBEDDED_GDB_SCRIPTS) -#endif // !defined(BOOST_UNORDERED_UNORDERED_PRINTERS_HPP) +#endif // !defined(BOOST_UNORDERED_DETAIL_UNORDERED_PRINTERS_HPP) From e2891f04f2341953137fafa1ad38e7eb127a8dd5 Mon Sep 17 00:00:00 2001 From: Braden Ganetsky Date: Wed, 20 Aug 2025 20:45:28 -0500 Subject: [PATCH 2/4] Store self.table instead of self.val --- extra/boost_unordered_printers.py | 27 ++++++++++++++------------- 1 file changed, 14 insertions(+), 13 deletions(-) diff --git a/extra/boost_unordered_printers.py b/extra/boost_unordered_printers.py index 5185f03b0..2ea70f9a4 100644 --- a/extra/boost_unordered_printers.py +++ b/extra/boost_unordered_printers.py @@ -1,4 +1,4 @@ -# Copyright 2024 Braden Ganetsky +# Copyright 2024-2025 Braden Ganetsky # Distributed under the Boost Software License, Version 1.0. # https://www.boost.org/LICENSE_1_0.txt @@ -45,14 +45,15 @@ def __init__(self, any_ptr): class BoostUnorderedFcaPrinter: def __init__(self, val): - self.val = BoostUnorderedHelpers.maybe_unwrap_reference(val) - self.name = f"{self.val.type.strip_typedefs()}".split("<")[0] + val = BoostUnorderedHelpers.maybe_unwrap_reference(val) + self.table = val["table_"] + self.name = f"{val.type.strip_typedefs()}".split("<")[0] self.name = self.name.replace("boost::unordered::", "boost::") self.is_map = self.name.endswith("map") - self.cpo = BoostUnorderedPointerCustomizationPoint(self.val["table_"]["buckets_"]["buckets"]) + self.cpo = BoostUnorderedPointerCustomizationPoint(self.table["buckets_"]["buckets"]) def to_string(self): - size = self.val["table_"]["size_"] + size = self.table["size_"] return f"{self.name} with {size} elements" def display_hint(self): @@ -60,7 +61,7 @@ def display_hint(self): def children(self): def generator(): - grouped_buckets = self.val["table_"]["buckets_"] + grouped_buckets = self.table["buckets_"] size = grouped_buckets["size_"] buckets = grouped_buckets["buckets"] @@ -154,14 +155,15 @@ def build_string(idx): class BoostUnorderedFoaPrinter: def __init__(self, val): - self.val = BoostUnorderedHelpers.maybe_unwrap_reference(val) - self.name = f"{self.val.type.strip_typedefs()}".split("<")[0] + val = BoostUnorderedHelpers.maybe_unwrap_reference(val) + self.table = val["table_"] + self.name = f"{val.type.strip_typedefs()}".split("<")[0] self.name = self.name.replace("boost::unordered::", "boost::") self.is_map = self.name.endswith("map") - self.cpo = BoostUnorderedPointerCustomizationPoint(self.val["table_"]["arrays"]["groups_"]) + self.cpo = BoostUnorderedPointerCustomizationPoint(self.table["arrays"]["groups_"]) def to_string(self): - size = BoostUnorderedHelpers.maybe_unwrap_atomic(self.val["table_"]["size_ctrl"]["size"]) + size = BoostUnorderedHelpers.maybe_unwrap_atomic(self.table["size_ctrl"]["size"]) return f"{self.name} with {size} elements" def display_hint(self): @@ -200,9 +202,8 @@ def is_sentinel(self, group, pos): def children(self): def generator(): - table = self.val["table_"] - groups = self.cpo.to_address(table["arrays"]["groups_"]) - elements = self.cpo.to_address(table["arrays"]["elements_"]) + groups = self.cpo.to_address(self.table["arrays"]["groups_"]) + elements = self.cpo.to_address(self.table["arrays"]["elements_"]) pc_ = groups.cast(gdb.lookup_type("unsigned char").pointer()) p_ = elements From cad6ed62667376a6df6ab26c878da740e280bad2 Mon Sep 17 00:00:00 2001 From: Braden Ganetsky Date: Wed, 20 Aug 2025 21:31:18 -0500 Subject: [PATCH 3/4] Fix pretty-printers not working when constexpr variables are optimized away Also do a few other things. * `groups` and `elements` are now stored inside `self` * `mask`, `n0`, and `n` aren't declared ahead of their first assignment * Remove trailing whitespace --- extra/boost_unordered_printers.py | 59 +++++++++++++++---------------- 1 file changed, 28 insertions(+), 31 deletions(-) diff --git a/extra/boost_unordered_printers.py b/extra/boost_unordered_printers.py index 2ea70f9a4..07e0893ee 100644 --- a/extra/boost_unordered_printers.py +++ b/extra/boost_unordered_printers.py @@ -14,7 +14,7 @@ def maybe_unwrap_atomic(n): return n.cast(underlying_type) else: return n - + def maybe_unwrap_foa_element(e): if f"{e.type.strip_typedefs()}".startswith("boost::unordered::detail::foa::element_type<"): return e["p"] @@ -84,7 +84,7 @@ def generator(): count += 1 node = self.cpo.to_address(node.dereference()["next"]) bucket_index += 1 - + return generator() class BoostUnorderedFcaIteratorPrinter: @@ -119,7 +119,7 @@ def generator(): yield "", member yield "", self.val[member] return generator() - + class BoostUnorderedFoaCumulativeStatsPrinter: def __init__(self, val): self.val = val @@ -128,7 +128,7 @@ def __init__(self, val): def display_hint(self): return "map" - + def children(self): def generator(): yield "", "count" @@ -161,6 +161,11 @@ def __init__(self, val): self.name = self.name.replace("boost::unordered::", "boost::") self.is_map = self.name.endswith("map") self.cpo = BoostUnorderedPointerCustomizationPoint(self.table["arrays"]["groups_"]) + self.groups = self.cpo.to_address(self.table["arrays"]["groups_"]) + self.elements = self.cpo.to_address(self.table["arrays"]["elements_"]) + + self.N = 15 # `self.groups.dereference()["N"]` may be optimized out + self.sentinel_ = 1 # `self.groups.dereference()["sentinel_"]` may be optimized out def to_string(self): size = BoostUnorderedHelpers.maybe_unwrap_atomic(self.table["size_ctrl"]["size"]) @@ -193,29 +198,21 @@ def is_sentinel(self, group, pos): m = group["m"] at = lambda b: BoostUnorderedHelpers.maybe_unwrap_atomic(m[b]["n"]) - N = group["N"] - sentinel_ = group["sentinel_"] if self.is_regular_layout(group): - return pos == N-1 and at(N-1) == sentinel_ + return pos == self.N-1 and at(self.N-1) == self.sentinel_ else: - return pos == N-1 and (at(0) & 0x4000400040004000) == 0x4000 and (at(1) & 0x4000400040004000) == 0 + return pos == self.N-1 and (at(0) & 0x4000400040004000) == 0x4000 and (at(1) & 0x4000400040004000) == 0 def children(self): def generator(): - groups = self.cpo.to_address(self.table["arrays"]["groups_"]) - elements = self.cpo.to_address(self.table["arrays"]["elements_"]) - - pc_ = groups.cast(gdb.lookup_type("unsigned char").pointer()) - p_ = elements + pc_ = self.groups.cast(gdb.lookup_type("unsigned char").pointer()) + p_ = self.elements first_time = True - mask = 0 - n0 = 0 - n = 0 count = 0 while p_ != 0: # This if block mirrors the condition in the begin() call - if (not first_time) or (self.match_occupied(groups.dereference()) & 1): + if (not first_time) or (self.match_occupied(self.groups.dereference()) & 1): pointer = BoostUnorderedHelpers.maybe_unwrap_foa_element(p_) value = self.cpo.to_address(pointer).dereference() if self.is_map: @@ -229,17 +226,17 @@ def generator(): count += 1 first_time = False - n0 = pc_.cast(gdb.lookup_type("uintptr_t")) % groups.dereference().type.sizeof + n0 = pc_.cast(gdb.lookup_type("uintptr_t")) % self.groups.dereference().type.sizeof pc_ = self.cpo.next(pc_, -n0) - mask = (self.match_occupied(pc_.cast(groups.type).dereference()) >> (n0+1)) << (n0+1) + mask = (self.match_occupied(pc_.cast(self.groups.type).dereference()) >> (n0+1)) << (n0+1) while mask == 0: - pc_ = self.cpo.next(pc_, groups.dereference().type.sizeof) - p_ = self.cpo.next(p_, groups.dereference()["N"]) - mask = self.match_occupied(pc_.cast(groups.type).dereference()) - + pc_ = self.cpo.next(pc_, self.groups.dereference().type.sizeof) + p_ = self.cpo.next(p_, self.N) + mask = self.match_occupied(pc_.cast(self.groups.type).dereference()) + n = BoostUnorderedHelpers.countr_zero(mask) - if self.is_sentinel(pc_.cast(groups.type).dereference(), n): + if self.is_sentinel(pc_.cast(self.groups.type).dereference(), n): p_ = 0 else: pc_ = self.cpo.next(pc_, n) @@ -285,7 +282,7 @@ def boost_unordered_build_pretty_printer(): add_template_printer("boost::unordered::concurrent_flat_set", BoostUnorderedFoaPrinter) add_template_printer("boost::unordered::concurrent_node_map", BoostUnorderedFoaPrinter) add_template_printer("boost::unordered::concurrent_node_set", BoostUnorderedFoaPrinter) - + add_template_printer("boost::unordered::detail::foa::table_iterator", BoostUnorderedFoaIteratorPrinter) add_concrete_printer("boost::unordered::detail::foa::table_core_cumulative_stats", BoostUnorderedFoaTableCoreCumulativeStatsPrinter) @@ -302,7 +299,7 @@ def boost_unordered_build_pretty_printer(): class BoostUnorderedFoaGetStatsMethod(gdb.xmethod.XMethod): def __init__(self): gdb.xmethod.XMethod.__init__(self, "get_stats") - + def get_worker(self, method_name): if method_name == "get_stats": return BoostUnorderedFoaGetStatsWorker() @@ -313,19 +310,19 @@ def get_arg_types(self): def get_result_type(self, obj): return gdb.lookup_type("boost::unordered::detail::foa::table_core_cumulative_stats") - + def __call__(self, obj): try: return obj["table_"]["cstats"] except gdb.error: print("Error: Binary was compiled without stats. Recompile with `BOOST_UNORDERED_ENABLE_STATS` defined.") return - + class BoostUnorderedFoaMatcher(gdb.xmethod.XMethodMatcher): def __init__(self): gdb.xmethod.XMethodMatcher.__init__(self, 'BoostUnorderedFoaMatcher') self.methods = [BoostUnorderedFoaGetStatsMethod()] - + def match(self, class_type, method_name): template_name = f"{class_type.strip_typedefs()}".split("<")[0] regex = "^boost::unordered::(unordered|concurrent)_(flat|node)_(map|set)$" @@ -381,12 +378,12 @@ class MyFancyPtrPrinter: def boost_to_address(fancy_ptr): ... return ... - + # Equivalent to `operator+()` def boost_next(raw_ptr, offset): ... return ... - + ... ``` """ From 3f3663c38554ff97418c5045922b8366738a5d23 Mon Sep 17 00:00:00 2001 From: Braden Ganetsky Date: Wed, 20 Aug 2025 22:09:47 -0500 Subject: [PATCH 4/4] Update the generated pretty-printer header --- .../unordered/detail/unordered_printers.hpp | 60 +++++++++---------- 1 file changed, 29 insertions(+), 31 deletions(-) diff --git a/include/boost/unordered/detail/unordered_printers.hpp b/include/boost/unordered/detail/unordered_printers.hpp index 4786da15c..0bb03847b 100644 --- a/include/boost/unordered/detail/unordered_printers.hpp +++ b/include/boost/unordered/detail/unordered_printers.hpp @@ -1,8 +1,8 @@ -// Copyright 2024 Braden Ganetsky +// Copyright 2024-2025 Braden Ganetsky // Distributed under the Boost Software License, Version 1.0. // https://www.boost.org/LICENSE_1_0.txt -// Generated on 2024-08-25T17:48:54 +// Generated on 2025-08-21T03:09:19 #ifndef BOOST_UNORDERED_DETAIL_UNORDERED_PRINTERS_HPP #define BOOST_UNORDERED_DETAIL_UNORDERED_PRINTERS_HPP @@ -58,14 +58,15 @@ __asm__(".pushsection \".debug_gdb_scripts\", \"MS\",%progbits,1\n" ".ascii \"class BoostUnorderedFcaPrinter:\\n\"\n" ".ascii \" def __init__(self, val):\\n\"\n" - ".ascii \" self.val = BoostUnorderedHelpers.maybe_unwrap_reference(val)\\n\"\n" - ".ascii \" self.name = f\\\"{self.val.type.strip_typedefs()}\\\".split(\\\"<\\\")[0]\\n\"\n" + ".ascii \" val = BoostUnorderedHelpers.maybe_unwrap_reference(val)\\n\"\n" + ".ascii \" self.table = val[\\\"table_\\\"]\\n\"\n" + ".ascii \" self.name = f\\\"{val.type.strip_typedefs()}\\\".split(\\\"<\\\")[0]\\n\"\n" ".ascii \" self.name = self.name.replace(\\\"boost::unordered::\\\", \\\"boost::\\\")\\n\"\n" ".ascii \" self.is_map = self.name.endswith(\\\"map\\\")\\n\"\n" - ".ascii \" self.cpo = BoostUnorderedPointerCustomizationPoint(self.val[\\\"table_\\\"][\\\"buckets_\\\"][\\\"buckets\\\"])\\n\"\n" + ".ascii \" self.cpo = BoostUnorderedPointerCustomizationPoint(self.table[\\\"buckets_\\\"][\\\"buckets\\\"])\\n\"\n" ".ascii \" def to_string(self):\\n\"\n" - ".ascii \" size = self.val[\\\"table_\\\"][\\\"size_\\\"]\\n\"\n" + ".ascii \" size = self.table[\\\"size_\\\"]\\n\"\n" ".ascii \" return f\\\"{self.name} with {size} elements\\\"\\n\"\n" ".ascii \" def display_hint(self):\\n\"\n" @@ -73,7 +74,7 @@ __asm__(".pushsection \".debug_gdb_scripts\", \"MS\",%progbits,1\n" ".ascii \" def children(self):\\n\"\n" ".ascii \" def generator():\\n\"\n" - ".ascii \" grouped_buckets = self.val[\\\"table_\\\"][\\\"buckets_\\\"]\\n\"\n" + ".ascii \" grouped_buckets = self.table[\\\"buckets_\\\"]\\n\"\n" ".ascii \" size = grouped_buckets[\\\"size_\\\"]\\n\"\n" ".ascii \" buckets = grouped_buckets[\\\"buckets\\\"]\\n\"\n" @@ -167,14 +168,20 @@ __asm__(".pushsection \".debug_gdb_scripts\", \"MS\",%progbits,1\n" ".ascii \"class BoostUnorderedFoaPrinter:\\n\"\n" ".ascii \" def __init__(self, val):\\n\"\n" - ".ascii \" self.val = BoostUnorderedHelpers.maybe_unwrap_reference(val)\\n\"\n" - ".ascii \" self.name = f\\\"{self.val.type.strip_typedefs()}\\\".split(\\\"<\\\")[0]\\n\"\n" + ".ascii \" val = BoostUnorderedHelpers.maybe_unwrap_reference(val)\\n\"\n" + ".ascii \" self.table = val[\\\"table_\\\"]\\n\"\n" + ".ascii \" self.name = f\\\"{val.type.strip_typedefs()}\\\".split(\\\"<\\\")[0]\\n\"\n" ".ascii \" self.name = self.name.replace(\\\"boost::unordered::\\\", \\\"boost::\\\")\\n\"\n" ".ascii \" self.is_map = self.name.endswith(\\\"map\\\")\\n\"\n" - ".ascii \" self.cpo = BoostUnorderedPointerCustomizationPoint(self.val[\\\"table_\\\"][\\\"arrays\\\"][\\\"groups_\\\"])\\n\"\n" + ".ascii \" self.cpo = BoostUnorderedPointerCustomizationPoint(self.table[\\\"arrays\\\"][\\\"groups_\\\"])\\n\"\n" + ".ascii \" self.groups = self.cpo.to_address(self.table[\\\"arrays\\\"][\\\"groups_\\\"])\\n\"\n" + ".ascii \" self.elements = self.cpo.to_address(self.table[\\\"arrays\\\"][\\\"elements_\\\"])\\n\"\n" + + ".ascii \" self.N = 15 # `self.groups.dereference()[\\\"N\\\"]` may be optimized out\\n\"\n" + ".ascii \" self.sentinel_ = 1 # `self.groups.dereference()[\\\"sentinel_\\\"]` may be optimized out\\n\"\n" ".ascii \" def to_string(self):\\n\"\n" - ".ascii \" size = BoostUnorderedHelpers.maybe_unwrap_atomic(self.val[\\\"table_\\\"][\\\"size_ctrl\\\"][\\\"size\\\"])\\n\"\n" + ".ascii \" size = BoostUnorderedHelpers.maybe_unwrap_atomic(self.table[\\\"size_ctrl\\\"][\\\"size\\\"])\\n\"\n" ".ascii \" return f\\\"{self.name} with {size} elements\\\"\\n\"\n" ".ascii \" def display_hint(self):\\n\"\n" @@ -204,30 +211,21 @@ __asm__(".pushsection \".debug_gdb_scripts\", \"MS\",%progbits,1\n" ".ascii \" m = group[\\\"m\\\"]\\n\"\n" ".ascii \" at = lambda b: BoostUnorderedHelpers.maybe_unwrap_atomic(m[b][\\\"n\\\"])\\n\"\n" - ".ascii \" N = group[\\\"N\\\"]\\n\"\n" - ".ascii \" sentinel_ = group[\\\"sentinel_\\\"]\\n\"\n" ".ascii \" if self.is_regular_layout(group):\\n\"\n" - ".ascii \" return pos == N-1 and at(N-1) == sentinel_\\n\"\n" + ".ascii \" return pos == self.N-1 and at(self.N-1) == self.sentinel_\\n\"\n" ".ascii \" else:\\n\"\n" - ".ascii \" return pos == N-1 and (at(0) & 0x4000400040004000) == 0x4000 and (at(1) & 0x4000400040004000) == 0\\n\"\n" + ".ascii \" return pos == self.N-1 and (at(0) & 0x4000400040004000) == 0x4000 and (at(1) & 0x4000400040004000) == 0\\n\"\n" ".ascii \" def children(self):\\n\"\n" ".ascii \" def generator():\\n\"\n" - ".ascii \" table = self.val[\\\"table_\\\"]\\n\"\n" - ".ascii \" groups = self.cpo.to_address(table[\\\"arrays\\\"][\\\"groups_\\\"])\\n\"\n" - ".ascii \" elements = self.cpo.to_address(table[\\\"arrays\\\"][\\\"elements_\\\"])\\n\"\n" - - ".ascii \" pc_ = groups.cast(gdb.lookup_type(\\\"unsigned char\\\").pointer())\\n\"\n" - ".ascii \" p_ = elements\\n\"\n" + ".ascii \" pc_ = self.groups.cast(gdb.lookup_type(\\\"unsigned char\\\").pointer())\\n\"\n" + ".ascii \" p_ = self.elements\\n\"\n" ".ascii \" first_time = True\\n\"\n" - ".ascii \" mask = 0\\n\"\n" - ".ascii \" n0 = 0\\n\"\n" - ".ascii \" n = 0\\n\"\n" ".ascii \" count = 0\\n\"\n" ".ascii \" while p_ != 0:\\n\"\n" ".ascii \" # This if block mirrors the condition in the begin() call\\n\"\n" - ".ascii \" if (not first_time) or (self.match_occupied(groups.dereference()) & 1):\\n\"\n" + ".ascii \" if (not first_time) or (self.match_occupied(self.groups.dereference()) & 1):\\n\"\n" ".ascii \" pointer = BoostUnorderedHelpers.maybe_unwrap_foa_element(p_)\\n\"\n" ".ascii \" value = self.cpo.to_address(pointer).dereference()\\n\"\n" ".ascii \" if self.is_map:\\n\"\n" @@ -241,17 +239,17 @@ __asm__(".pushsection \".debug_gdb_scripts\", \"MS\",%progbits,1\n" ".ascii \" count += 1\\n\"\n" ".ascii \" first_time = False\\n\"\n" - ".ascii \" n0 = pc_.cast(gdb.lookup_type(\\\"uintptr_t\\\")) % groups.dereference().type.sizeof\\n\"\n" + ".ascii \" n0 = pc_.cast(gdb.lookup_type(\\\"uintptr_t\\\")) % self.groups.dereference().type.sizeof\\n\"\n" ".ascii \" pc_ = self.cpo.next(pc_, -n0)\\n\"\n" - ".ascii \" mask = (self.match_occupied(pc_.cast(groups.type).dereference()) >> (n0+1)) << (n0+1)\\n\"\n" + ".ascii \" mask = (self.match_occupied(pc_.cast(self.groups.type).dereference()) >> (n0+1)) << (n0+1)\\n\"\n" ".ascii \" while mask == 0:\\n\"\n" - ".ascii \" pc_ = self.cpo.next(pc_, groups.dereference().type.sizeof)\\n\"\n" - ".ascii \" p_ = self.cpo.next(p_, groups.dereference()[\\\"N\\\"])\\n\"\n" - ".ascii \" mask = self.match_occupied(pc_.cast(groups.type).dereference())\\n\"\n" + ".ascii \" pc_ = self.cpo.next(pc_, self.groups.dereference().type.sizeof)\\n\"\n" + ".ascii \" p_ = self.cpo.next(p_, self.N)\\n\"\n" + ".ascii \" mask = self.match_occupied(pc_.cast(self.groups.type).dereference())\\n\"\n" ".ascii \" n = BoostUnorderedHelpers.countr_zero(mask)\\n\"\n" - ".ascii \" if self.is_sentinel(pc_.cast(groups.type).dereference(), n):\\n\"\n" + ".ascii \" if self.is_sentinel(pc_.cast(self.groups.type).dereference(), n):\\n\"\n" ".ascii \" p_ = 0\\n\"\n" ".ascii \" else:\\n\"\n" ".ascii \" pc_ = self.cpo.next(pc_, n)\\n\"\n"