[ Web Proxy ]
URL:
Viewing: https://raw.githubusercontent.com/clayne/cppfront/main/experimental/union_test.cpp [Back]  [Original]

//  Copyright 2022-2024 Herb Sutter
//  SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//  
//  Part of the Cppfront Project, under the Apache License v2.0 with LLVM Exceptions.
//  See https://github.com/hsutter/cppfront/blob/main/LICENSE for license information.

//#include "extrinsic_storage_std_locked.h"
#include "extrinsic_storage.h"

#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 


//-------------------------------------------------------------------------------
//  Union instrumentation API for compiler integration
// 
//  Template parameters
//      Tag             discriminator tag to store for each object (uintNN_t where
//                      NN is large enough to hold the #alternatives in the union)
//
//  For an object U of union type that
//  has a unique address, when              Inject a call to this (zero-based alternative #s)
//
//    U is created initialized                on_set_alternative(&U,0) = the first alternative# is active
//
//    U is created uninitialized              on_set_alternative(&U,invalid)
//
//    U.A = xxx (alt A is assigned to)        on_set_alternative(&U,#A)
//
//    U or U.A is passed to a function by     on_set_alternative(&U,unknown)
//      pointer/reference to non-const
//      and we don't know the function
//      is compiled in this mode
//
//    U.A (alt A is otherwise used)           on_get_alternative(&U,#A)
//      and A is not a common initial
//      sequence
//
//    U is destroyed / goes out of scope      on_destroy(&U)
//
//  That's it. Here's an example:
//    {
//      union Test { int a; double b; };
//      Test t = {42};                        union_registry::on_set_alternative(&u,0);
//      std::cout  void { tags.erase(pobj); }

    static inline auto on_set_alternative(void* pobj, uint32_t alt) noexcept -> void {
        if (auto p = tags.find_or_insert(pobj)) { *p = alt; }
    }
    
    static inline auto on_get_alternative(void* pobj, uint32_t alt, std::source_location where = std::source_location::current()) -> void {
        if (auto active = tags.find(pobj);
            active                  // if we have discriminator info for this union
            && *active != alt       // and the discriminator not what is expected
            && *active != unknown   // and is not unknown
            )
        { 
            log 

Web Proxy Viewer  |  New URL  |  Original Page