Skip to content

Commit 6fd63ab

Browse files
authored
Fix pretty-printers not working when constexpr variables are optimized away (#315)
* 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. * Store self.table instead of self.val * 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 * Update the generated pretty-printer header
1 parent 59e2a56 commit 6fd63ab

File tree

4 files changed

+75
-79
lines changed

4 files changed

+75
-79
lines changed

extra/boost_unordered_printers.py

Lines changed: 40 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
# Copyright 2024 Braden Ganetsky
1+
# Copyright 2024-2025 Braden Ganetsky
22
# Distributed under the Boost Software License, Version 1.0.
33
# https://www.boost.org/LICENSE_1_0.txt
44

@@ -14,7 +14,7 @@ def maybe_unwrap_atomic(n):
1414
return n.cast(underlying_type)
1515
else:
1616
return n
17-
17+
1818
def maybe_unwrap_foa_element(e):
1919
if f"{e.type.strip_typedefs()}".startswith("boost::unordered::detail::foa::element_type<"):
2020
return e["p"]
@@ -45,22 +45,23 @@ def __init__(self, any_ptr):
4545

4646
class BoostUnorderedFcaPrinter:
4747
def __init__(self, val):
48-
self.val = BoostUnorderedHelpers.maybe_unwrap_reference(val)
49-
self.name = f"{self.val.type.strip_typedefs()}".split("<")[0]
48+
val = BoostUnorderedHelpers.maybe_unwrap_reference(val)
49+
self.table = val["table_"]
50+
self.name = f"{val.type.strip_typedefs()}".split("<")[0]
5051
self.name = self.name.replace("boost::unordered::", "boost::")
5152
self.is_map = self.name.endswith("map")
52-
self.cpo = BoostUnorderedPointerCustomizationPoint(self.val["table_"]["buckets_"]["buckets"])
53+
self.cpo = BoostUnorderedPointerCustomizationPoint(self.table["buckets_"]["buckets"])
5354

5455
def to_string(self):
55-
size = self.val["table_"]["size_"]
56+
size = self.table["size_"]
5657
return f"{self.name} with {size} elements"
5758

5859
def display_hint(self):
5960
return "map"
6061

6162
def children(self):
6263
def generator():
63-
grouped_buckets = self.val["table_"]["buckets_"]
64+
grouped_buckets = self.table["buckets_"]
6465

6566
size = grouped_buckets["size_"]
6667
buckets = grouped_buckets["buckets"]
@@ -83,7 +84,7 @@ def generator():
8384
count += 1
8485
node = self.cpo.to_address(node.dereference()["next"])
8586
bucket_index += 1
86-
87+
8788
return generator()
8889

8990
class BoostUnorderedFcaIteratorPrinter:
@@ -118,7 +119,7 @@ def generator():
118119
yield "", member
119120
yield "", self.val[member]
120121
return generator()
121-
122+
122123
class BoostUnorderedFoaCumulativeStatsPrinter:
123124
def __init__(self, val):
124125
self.val = val
@@ -127,7 +128,7 @@ def __init__(self, val):
127128

128129
def display_hint(self):
129130
return "map"
130-
131+
131132
def children(self):
132133
def generator():
133134
yield "", "count"
@@ -154,14 +155,20 @@ def build_string(idx):
154155

155156
class BoostUnorderedFoaPrinter:
156157
def __init__(self, val):
157-
self.val = BoostUnorderedHelpers.maybe_unwrap_reference(val)
158-
self.name = f"{self.val.type.strip_typedefs()}".split("<")[0]
158+
val = BoostUnorderedHelpers.maybe_unwrap_reference(val)
159+
self.table = val["table_"]
160+
self.name = f"{val.type.strip_typedefs()}".split("<")[0]
159161
self.name = self.name.replace("boost::unordered::", "boost::")
160162
self.is_map = self.name.endswith("map")
161-
self.cpo = BoostUnorderedPointerCustomizationPoint(self.val["table_"]["arrays"]["groups_"])
163+
self.cpo = BoostUnorderedPointerCustomizationPoint(self.table["arrays"]["groups_"])
164+
self.groups = self.cpo.to_address(self.table["arrays"]["groups_"])
165+
self.elements = self.cpo.to_address(self.table["arrays"]["elements_"])
166+
167+
self.N = 15 # `self.groups.dereference()["N"]` may be optimized out
168+
self.sentinel_ = 1 # `self.groups.dereference()["sentinel_"]` may be optimized out
162169

163170
def to_string(self):
164-
size = BoostUnorderedHelpers.maybe_unwrap_atomic(self.val["table_"]["size_ctrl"]["size"])
171+
size = BoostUnorderedHelpers.maybe_unwrap_atomic(self.table["size_ctrl"]["size"])
165172
return f"{self.name} with {size} elements"
166173

167174
def display_hint(self):
@@ -191,30 +198,21 @@ def is_sentinel(self, group, pos):
191198
m = group["m"]
192199
at = lambda b: BoostUnorderedHelpers.maybe_unwrap_atomic(m[b]["n"])
193200

194-
N = group["N"]
195-
sentinel_ = group["sentinel_"]
196201
if self.is_regular_layout(group):
197-
return pos == N-1 and at(N-1) == sentinel_
202+
return pos == self.N-1 and at(self.N-1) == self.sentinel_
198203
else:
199-
return pos == N-1 and (at(0) & 0x4000400040004000) == 0x4000 and (at(1) & 0x4000400040004000) == 0
204+
return pos == self.N-1 and (at(0) & 0x4000400040004000) == 0x4000 and (at(1) & 0x4000400040004000) == 0
200205

201206
def children(self):
202207
def generator():
203-
table = self.val["table_"]
204-
groups = self.cpo.to_address(table["arrays"]["groups_"])
205-
elements = self.cpo.to_address(table["arrays"]["elements_"])
206-
207-
pc_ = groups.cast(gdb.lookup_type("unsigned char").pointer())
208-
p_ = elements
208+
pc_ = self.groups.cast(gdb.lookup_type("unsigned char").pointer())
209+
p_ = self.elements
209210
first_time = True
210-
mask = 0
211-
n0 = 0
212-
n = 0
213211

214212
count = 0
215213
while p_ != 0:
216214
# This if block mirrors the condition in the begin() call
217-
if (not first_time) or (self.match_occupied(groups.dereference()) & 1):
215+
if (not first_time) or (self.match_occupied(self.groups.dereference()) & 1):
218216
pointer = BoostUnorderedHelpers.maybe_unwrap_foa_element(p_)
219217
value = self.cpo.to_address(pointer).dereference()
220218
if self.is_map:
@@ -228,17 +226,17 @@ def generator():
228226
count += 1
229227
first_time = False
230228

231-
n0 = pc_.cast(gdb.lookup_type("uintptr_t")) % groups.dereference().type.sizeof
229+
n0 = pc_.cast(gdb.lookup_type("uintptr_t")) % self.groups.dereference().type.sizeof
232230
pc_ = self.cpo.next(pc_, -n0)
233231

234-
mask = (self.match_occupied(pc_.cast(groups.type).dereference()) >> (n0+1)) << (n0+1)
232+
mask = (self.match_occupied(pc_.cast(self.groups.type).dereference()) >> (n0+1)) << (n0+1)
235233
while mask == 0:
236-
pc_ = self.cpo.next(pc_, groups.dereference().type.sizeof)
237-
p_ = self.cpo.next(p_, groups.dereference()["N"])
238-
mask = self.match_occupied(pc_.cast(groups.type).dereference())
239-
234+
pc_ = self.cpo.next(pc_, self.groups.dereference().type.sizeof)
235+
p_ = self.cpo.next(p_, self.N)
236+
mask = self.match_occupied(pc_.cast(self.groups.type).dereference())
237+
240238
n = BoostUnorderedHelpers.countr_zero(mask)
241-
if self.is_sentinel(pc_.cast(groups.type).dereference(), n):
239+
if self.is_sentinel(pc_.cast(self.groups.type).dereference(), n):
242240
p_ = 0
243241
else:
244242
pc_ = self.cpo.next(pc_, n)
@@ -284,7 +282,7 @@ def boost_unordered_build_pretty_printer():
284282
add_template_printer("boost::unordered::concurrent_flat_set", BoostUnorderedFoaPrinter)
285283
add_template_printer("boost::unordered::concurrent_node_map", BoostUnorderedFoaPrinter)
286284
add_template_printer("boost::unordered::concurrent_node_set", BoostUnorderedFoaPrinter)
287-
285+
288286
add_template_printer("boost::unordered::detail::foa::table_iterator", BoostUnorderedFoaIteratorPrinter)
289287

290288
add_concrete_printer("boost::unordered::detail::foa::table_core_cumulative_stats", BoostUnorderedFoaTableCoreCumulativeStatsPrinter)
@@ -301,7 +299,7 @@ def boost_unordered_build_pretty_printer():
301299
class BoostUnorderedFoaGetStatsMethod(gdb.xmethod.XMethod):
302300
def __init__(self):
303301
gdb.xmethod.XMethod.__init__(self, "get_stats")
304-
302+
305303
def get_worker(self, method_name):
306304
if method_name == "get_stats":
307305
return BoostUnorderedFoaGetStatsWorker()
@@ -312,19 +310,19 @@ def get_arg_types(self):
312310

313311
def get_result_type(self, obj):
314312
return gdb.lookup_type("boost::unordered::detail::foa::table_core_cumulative_stats")
315-
313+
316314
def __call__(self, obj):
317315
try:
318316
return obj["table_"]["cstats"]
319317
except gdb.error:
320318
print("Error: Binary was compiled without stats. Recompile with `BOOST_UNORDERED_ENABLE_STATS` defined.")
321319
return
322-
320+
323321
class BoostUnorderedFoaMatcher(gdb.xmethod.XMethodMatcher):
324322
def __init__(self):
325323
gdb.xmethod.XMethodMatcher.__init__(self, 'BoostUnorderedFoaMatcher')
326324
self.methods = [BoostUnorderedFoaGetStatsMethod()]
327-
325+
328326
def match(self, class_type, method_name):
329327
template_name = f"{class_type.strip_typedefs()}".split("<")[0]
330328
regex = "^boost::unordered::(unordered|concurrent)_(flat|node)_(map|set)$"
@@ -380,12 +378,12 @@ class MyFancyPtrPrinter:
380378
def boost_to_address(fancy_ptr):
381379
...
382380
return ...
383-
381+
384382
# Equivalent to `operator+()`
385383
def boost_next(raw_ptr, offset):
386384
...
387385
return ...
388-
386+
389387
...
390388
```
391389
"""

include/boost/unordered/detail/foa/core.hpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@
2929
#include <boost/unordered/detail/mulx.hpp>
3030
#include <boost/unordered/detail/static_assert.hpp>
3131
#include <boost/unordered/detail/type_traits.hpp>
32-
#include <boost/unordered/unordered_printers.hpp>
32+
#include <boost/unordered/detail/unordered_printers.hpp>
3333
#include <climits>
3434
#include <cmath>
3535
#include <cstddef>

include/boost/unordered/detail/implementation.hpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@
2121
#include <boost/unordered/detail/serialize_tracked_address.hpp>
2222
#include <boost/unordered/detail/static_assert.hpp>
2323
#include <boost/unordered/detail/type_traits.hpp>
24-
#include <boost/unordered/unordered_printers.hpp>
24+
#include <boost/unordered/detail/unordered_printers.hpp>
2525

2626
#include <boost/assert.hpp>
2727
#include <boost/core/allocator_traits.hpp>

include/boost/unordered/unordered_printers.hpp renamed to include/boost/unordered/detail/unordered_printers.hpp

Lines changed: 33 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
1-
// Copyright 2024 Braden Ganetsky
1+
// Copyright 2024-2025 Braden Ganetsky
22
// Distributed under the Boost Software License, Version 1.0.
33
// https://www.boost.org/LICENSE_1_0.txt
44

5-
// Generated on 2024-08-25T17:48:54
5+
// Generated on 2025-08-21T03:09:19
66

7-
#ifndef BOOST_UNORDERED_UNORDERED_PRINTERS_HPP
8-
#define BOOST_UNORDERED_UNORDERED_PRINTERS_HPP
7+
#ifndef BOOST_UNORDERED_DETAIL_UNORDERED_PRINTERS_HPP
8+
#define BOOST_UNORDERED_DETAIL_UNORDERED_PRINTERS_HPP
99

1010
#ifndef BOOST_ALL_NO_EMBEDDED_GDB_SCRIPTS
1111
#if defined(__ELF__)
@@ -14,7 +14,7 @@
1414
#pragma clang diagnostic ignored "-Woverlength-strings"
1515
#endif
1616
__asm__(".pushsection \".debug_gdb_scripts\", \"MS\",%progbits,1\n"
17-
".ascii \"\\4gdb.inlined-script.BOOST_UNORDERED_UNORDERED_PRINTERS_HPP\\n\"\n"
17+
".ascii \"\\4gdb.inlined-script.BOOST_UNORDERED_DETAIL_UNORDERED_PRINTERS_HPP\\n\"\n"
1818
".ascii \"import gdb.printing\\n\"\n"
1919
".ascii \"import gdb.xmethod\\n\"\n"
2020
".ascii \"import re\\n\"\n"
@@ -58,22 +58,23 @@ __asm__(".pushsection \".debug_gdb_scripts\", \"MS\",%progbits,1\n"
5858

5959
".ascii \"class BoostUnorderedFcaPrinter:\\n\"\n"
6060
".ascii \" def __init__(self, val):\\n\"\n"
61-
".ascii \" self.val = BoostUnorderedHelpers.maybe_unwrap_reference(val)\\n\"\n"
62-
".ascii \" self.name = f\\\"{self.val.type.strip_typedefs()}\\\".split(\\\"<\\\")[0]\\n\"\n"
61+
".ascii \" val = BoostUnorderedHelpers.maybe_unwrap_reference(val)\\n\"\n"
62+
".ascii \" self.table = val[\\\"table_\\\"]\\n\"\n"
63+
".ascii \" self.name = f\\\"{val.type.strip_typedefs()}\\\".split(\\\"<\\\")[0]\\n\"\n"
6364
".ascii \" self.name = self.name.replace(\\\"boost::unordered::\\\", \\\"boost::\\\")\\n\"\n"
6465
".ascii \" self.is_map = self.name.endswith(\\\"map\\\")\\n\"\n"
65-
".ascii \" self.cpo = BoostUnorderedPointerCustomizationPoint(self.val[\\\"table_\\\"][\\\"buckets_\\\"][\\\"buckets\\\"])\\n\"\n"
66+
".ascii \" self.cpo = BoostUnorderedPointerCustomizationPoint(self.table[\\\"buckets_\\\"][\\\"buckets\\\"])\\n\"\n"
6667

6768
".ascii \" def to_string(self):\\n\"\n"
68-
".ascii \" size = self.val[\\\"table_\\\"][\\\"size_\\\"]\\n\"\n"
69+
".ascii \" size = self.table[\\\"size_\\\"]\\n\"\n"
6970
".ascii \" return f\\\"{self.name} with {size} elements\\\"\\n\"\n"
7071

7172
".ascii \" def display_hint(self):\\n\"\n"
7273
".ascii \" return \\\"map\\\"\\n\"\n"
7374

7475
".ascii \" def children(self):\\n\"\n"
7576
".ascii \" def generator():\\n\"\n"
76-
".ascii \" grouped_buckets = self.val[\\\"table_\\\"][\\\"buckets_\\\"]\\n\"\n"
77+
".ascii \" grouped_buckets = self.table[\\\"buckets_\\\"]\\n\"\n"
7778

7879
".ascii \" size = grouped_buckets[\\\"size_\\\"]\\n\"\n"
7980
".ascii \" buckets = grouped_buckets[\\\"buckets\\\"]\\n\"\n"
@@ -167,14 +168,20 @@ __asm__(".pushsection \".debug_gdb_scripts\", \"MS\",%progbits,1\n"
167168

168169
".ascii \"class BoostUnorderedFoaPrinter:\\n\"\n"
169170
".ascii \" def __init__(self, val):\\n\"\n"
170-
".ascii \" self.val = BoostUnorderedHelpers.maybe_unwrap_reference(val)\\n\"\n"
171-
".ascii \" self.name = f\\\"{self.val.type.strip_typedefs()}\\\".split(\\\"<\\\")[0]\\n\"\n"
171+
".ascii \" val = BoostUnorderedHelpers.maybe_unwrap_reference(val)\\n\"\n"
172+
".ascii \" self.table = val[\\\"table_\\\"]\\n\"\n"
173+
".ascii \" self.name = f\\\"{val.type.strip_typedefs()}\\\".split(\\\"<\\\")[0]\\n\"\n"
172174
".ascii \" self.name = self.name.replace(\\\"boost::unordered::\\\", \\\"boost::\\\")\\n\"\n"
173175
".ascii \" self.is_map = self.name.endswith(\\\"map\\\")\\n\"\n"
174-
".ascii \" self.cpo = BoostUnorderedPointerCustomizationPoint(self.val[\\\"table_\\\"][\\\"arrays\\\"][\\\"groups_\\\"])\\n\"\n"
176+
".ascii \" self.cpo = BoostUnorderedPointerCustomizationPoint(self.table[\\\"arrays\\\"][\\\"groups_\\\"])\\n\"\n"
177+
".ascii \" self.groups = self.cpo.to_address(self.table[\\\"arrays\\\"][\\\"groups_\\\"])\\n\"\n"
178+
".ascii \" self.elements = self.cpo.to_address(self.table[\\\"arrays\\\"][\\\"elements_\\\"])\\n\"\n"
179+
180+
".ascii \" self.N = 15 # `self.groups.dereference()[\\\"N\\\"]` may be optimized out\\n\"\n"
181+
".ascii \" self.sentinel_ = 1 # `self.groups.dereference()[\\\"sentinel_\\\"]` may be optimized out\\n\"\n"
175182

176183
".ascii \" def to_string(self):\\n\"\n"
177-
".ascii \" size = BoostUnorderedHelpers.maybe_unwrap_atomic(self.val[\\\"table_\\\"][\\\"size_ctrl\\\"][\\\"size\\\"])\\n\"\n"
184+
".ascii \" size = BoostUnorderedHelpers.maybe_unwrap_atomic(self.table[\\\"size_ctrl\\\"][\\\"size\\\"])\\n\"\n"
178185
".ascii \" return f\\\"{self.name} with {size} elements\\\"\\n\"\n"
179186

180187
".ascii \" def display_hint(self):\\n\"\n"
@@ -204,30 +211,21 @@ __asm__(".pushsection \".debug_gdb_scripts\", \"MS\",%progbits,1\n"
204211
".ascii \" m = group[\\\"m\\\"]\\n\"\n"
205212
".ascii \" at = lambda b: BoostUnorderedHelpers.maybe_unwrap_atomic(m[b][\\\"n\\\"])\\n\"\n"
206213

207-
".ascii \" N = group[\\\"N\\\"]\\n\"\n"
208-
".ascii \" sentinel_ = group[\\\"sentinel_\\\"]\\n\"\n"
209214
".ascii \" if self.is_regular_layout(group):\\n\"\n"
210-
".ascii \" return pos == N-1 and at(N-1) == sentinel_\\n\"\n"
215+
".ascii \" return pos == self.N-1 and at(self.N-1) == self.sentinel_\\n\"\n"
211216
".ascii \" else:\\n\"\n"
212-
".ascii \" return pos == N-1 and (at(0) & 0x4000400040004000) == 0x4000 and (at(1) & 0x4000400040004000) == 0\\n\"\n"
217+
".ascii \" return pos == self.N-1 and (at(0) & 0x4000400040004000) == 0x4000 and (at(1) & 0x4000400040004000) == 0\\n\"\n"
213218

214219
".ascii \" def children(self):\\n\"\n"
215220
".ascii \" def generator():\\n\"\n"
216-
".ascii \" table = self.val[\\\"table_\\\"]\\n\"\n"
217-
".ascii \" groups = self.cpo.to_address(table[\\\"arrays\\\"][\\\"groups_\\\"])\\n\"\n"
218-
".ascii \" elements = self.cpo.to_address(table[\\\"arrays\\\"][\\\"elements_\\\"])\\n\"\n"
219-
220-
".ascii \" pc_ = groups.cast(gdb.lookup_type(\\\"unsigned char\\\").pointer())\\n\"\n"
221-
".ascii \" p_ = elements\\n\"\n"
221+
".ascii \" pc_ = self.groups.cast(gdb.lookup_type(\\\"unsigned char\\\").pointer())\\n\"\n"
222+
".ascii \" p_ = self.elements\\n\"\n"
222223
".ascii \" first_time = True\\n\"\n"
223-
".ascii \" mask = 0\\n\"\n"
224-
".ascii \" n0 = 0\\n\"\n"
225-
".ascii \" n = 0\\n\"\n"
226224

227225
".ascii \" count = 0\\n\"\n"
228226
".ascii \" while p_ != 0:\\n\"\n"
229227
".ascii \" # This if block mirrors the condition in the begin() call\\n\"\n"
230-
".ascii \" if (not first_time) or (self.match_occupied(groups.dereference()) & 1):\\n\"\n"
228+
".ascii \" if (not first_time) or (self.match_occupied(self.groups.dereference()) & 1):\\n\"\n"
231229
".ascii \" pointer = BoostUnorderedHelpers.maybe_unwrap_foa_element(p_)\\n\"\n"
232230
".ascii \" value = self.cpo.to_address(pointer).dereference()\\n\"\n"
233231
".ascii \" if self.is_map:\\n\"\n"
@@ -241,17 +239,17 @@ __asm__(".pushsection \".debug_gdb_scripts\", \"MS\",%progbits,1\n"
241239
".ascii \" count += 1\\n\"\n"
242240
".ascii \" first_time = False\\n\"\n"
243241

244-
".ascii \" n0 = pc_.cast(gdb.lookup_type(\\\"uintptr_t\\\")) % groups.dereference().type.sizeof\\n\"\n"
242+
".ascii \" n0 = pc_.cast(gdb.lookup_type(\\\"uintptr_t\\\")) % self.groups.dereference().type.sizeof\\n\"\n"
245243
".ascii \" pc_ = self.cpo.next(pc_, -n0)\\n\"\n"
246244

247-
".ascii \" mask = (self.match_occupied(pc_.cast(groups.type).dereference()) >> (n0+1)) << (n0+1)\\n\"\n"
245+
".ascii \" mask = (self.match_occupied(pc_.cast(self.groups.type).dereference()) >> (n0+1)) << (n0+1)\\n\"\n"
248246
".ascii \" while mask == 0:\\n\"\n"
249-
".ascii \" pc_ = self.cpo.next(pc_, groups.dereference().type.sizeof)\\n\"\n"
250-
".ascii \" p_ = self.cpo.next(p_, groups.dereference()[\\\"N\\\"])\\n\"\n"
251-
".ascii \" mask = self.match_occupied(pc_.cast(groups.type).dereference())\\n\"\n"
247+
".ascii \" pc_ = self.cpo.next(pc_, self.groups.dereference().type.sizeof)\\n\"\n"
248+
".ascii \" p_ = self.cpo.next(p_, self.N)\\n\"\n"
249+
".ascii \" mask = self.match_occupied(pc_.cast(self.groups.type).dereference())\\n\"\n"
252250

253251
".ascii \" n = BoostUnorderedHelpers.countr_zero(mask)\\n\"\n"
254-
".ascii \" if self.is_sentinel(pc_.cast(groups.type).dereference(), n):\\n\"\n"
252+
".ascii \" if self.is_sentinel(pc_.cast(self.groups.type).dereference(), n):\\n\"\n"
255253
".ascii \" p_ = 0\\n\"\n"
256254
".ascii \" else:\\n\"\n"
257255
".ascii \" pc_ = self.cpo.next(pc_, n)\\n\"\n"
@@ -411,4 +409,4 @@ __asm__(".pushsection \".debug_gdb_scripts\", \"MS\",%progbits,1\n"
411409
#endif // defined(__ELF__)
412410
#endif // !defined(BOOST_ALL_NO_EMBEDDED_GDB_SCRIPTS)
413411

414-
#endif // !defined(BOOST_UNORDERED_UNORDERED_PRINTERS_HPP)
412+
#endif // !defined(BOOST_UNORDERED_DETAIL_UNORDERED_PRINTERS_HPP)

0 commit comments

Comments
 (0)