Skip to content

Commit f4d4a01

Browse files
committed
Add "unknown" state for unions passed to opaque functions
1 parent bd42f8d commit f4d4a01

File tree

1 file changed

+13
-7
lines changed

1 file changed

+13
-7
lines changed

experimental/union_test.cpp

Lines changed: 13 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -21,15 +21,18 @@
2121
// NN is large enough to hold the #alternatives in the union)
2222
//
2323
// For an object U of union type that
24-
// has a unique address, when inject a call to this (zero-based alternative #s)
24+
// has a unique address, when Inject a call to this (zero-based alternative #s)
2525
//
2626
// U is created initialized on_set_alternative(&U,0) = the first alternative# is active
2727
//
2828
// U is created uninitialized on_set_alternative(&U,invalid)
2929
//
30-
// U.A = xxx (alt #A is assigned to) on_set_alternative(&U,#A)
30+
// U.A = xxx (alt A is assigned to) on_set_alternative(&U,#A)
3131
//
32-
// U.A (alt #A is otherwise mentioned) on_get_alternative(&U,#A)
32+
// U.A is passed to a function by on_set_alternative(&U,unknown)
33+
// pointer/reference to non-const
34+
//
35+
// U.A (alt A is otherwise used) on_get_alternative(&U,#A)
3336
// and A is not a common initial
3437
// sequence
3538
//
@@ -44,24 +47,27 @@
4447
// std::cout << t.b; union_registry<>::on_get_alternative(&u,1);
4548
// } union_registry<>::on_destroy(&u);
4649
//
47-
// For all unions with under 256 alternatives, use union_registry<>
48-
// For all unions with between 256 and 16k alternatives, use union_registry<uint16_t>
49-
// If you find a union with >16k alternatives, email me the story and use union_registry<uint32_t>
50+
// For all unions with up to 254 alternatives, use union_registry<>
51+
// For all unions with between 255 and 16k-2 alternatives, use union_registry<uint16_t>
52+
// If you find a union with >16k-2 alternatives, email me the story and use union_registry<uint32_t>
5053
//
5154
template<typename Tag = uint8_t>
5255
class union_registry {
5356
inline static auto tags = extrinsic_storage<Tag>{};
5457
inline static auto log = std::ofstream{ "union-violations.log" };
5558
public:
5659
inline static auto invalid = std::numeric_limits<Tag>::max();
60+
inline static auto unknown = std::numeric_limits<Tag>::max()-1;
5761

5862
static auto on_destroy (void* pobj) -> void { tags.erase(pobj); }
5963
static auto on_set_alternative(void* pobj, uint32_t alt) -> void { tags[pobj] = alt; }
6064
static auto on_get_alternative(void* pobj, uint32_t alt, std::source_location where = std::source_location::current()) -> void
6165
{
6266
if (auto active = tags[pobj];
6367
active != alt
64-
) {
68+
&& active != unknown
69+
)
70+
{
6571
log << where.file_name() << '(' << where.line() << ") " << where.function_name()
6672
<< ": union " << pobj
6773
<< ", active " << (active == invalid ? "invalid" : std::to_string(active))

0 commit comments

Comments
 (0)