Notes for C

<h3><a href="#remarks-c" id="remarks-c">C</a></h3>
<br/>
<p>1. Functions are named "Az" + class name + "_" + function name in pascalCase. Modules / namespaces do not exist:</p>
<code class="expand">app::App::new() = AzApp_new()</code><br/>
<p>2. Enums are named "Az" + enum name + "_" + variant name:</p>
<code class="expand">LayoutAlignItems::Stretch = AzLayoutAlignItems_Stretch</code><br/>
<p>3. <code>union enum</code>s have special compile-time macros that crate the correct union variant + tag at compile time:</p>
<code class="expand">AzStyleCursorValue cursor = AzStyleCursorValue_Exact(AzStyleCursor_Grab);</code><br/>

<p>4. If a class is marked with <span class="chd">has destructor</span>, it has a corresponding <code>_delete()</code> function. The destructors automatically call the sub-destructors of all fields (i.e. you do not need to recurse and delete every field manually).</p>
<code class="expand"># App is marked as "has_destructor":

AzApp app = AzApp_new(/* ... */); # constructor AzApp_delete(&app); # destructor

value of app is undefined here

<p>5. All classes can be deep-copied via <code>_deepCopy()</code> - note that this might be very expensive for large objects.</p>
<code class="expand">AzWindowCreateOptions w = AzWindowCreateOptions_new();

AzWindowCreateOptions copy = AzWindowCreateOptions_copy(&w);

<p>6. To emulate pattern matching in C, every <code>union enum</code> has a corresponding <code>$union_matchRef$variant()</code> and <code>$union_matchMut$variant()</code> function.
    Both take a pointer to the union and an (uninitialized) pointer to the output. If the union is of variant $variant, the output pointer will be initialized:</p>

// create a union enum AzStyleCursorValue cursor = AzStyleCursorValue_Exact(AzStyleCursor_Grab);

// destructure a union enum AzStyleCursor* result; if AzStyleCursorValue_matchRefExact(&cursor, &result) { printf("ok!\n"); // result is initialized here }
The difference between _matchRef() and _matchMut() is that takes a const * and _matchMut() takes a restrict * to the result. In the example, the lifetime of result is equal to the lifetime of cursor (since result simply points to the payload of the tagged cursor union).


<p>7. Run-time type reflection for <code>RefAny</code> can implemented via the <code>AZ_REFLECT</code> macro:</p>
<code class="expand">typedef struct { int field; } MyStruct;

void MyStruct_delete(MyStruct* restrict A) { } // destructor AZ_REFLECT(MyStruct, MyStruct_delete);

<p>The <code>AZ_REFLECT</code> macro generates functions to upcast from your struct to a
    <code>RefAny</code> as well as to do a checked downcast from a <code>RefAny</code> to your custom data type:</p>
<code class="expand">// create a new RefAny

AzRefAny object = MyStruct_upcast(MyStruct { .field = 5 });

// Creates an uninitialized borrow and downcast it // fails if "object" is already borrowed mutably // or if the "RefAny" is not of type "MyStruct" (type check at runtime) MyStructRef structref = MyStructRef_create(&object); if MyStruct_downcastRef(&object, &structref) { printf!("ok! - %d", structref->ptr.field); }

// unlocks "object" to be borrowed mutably again MyStructRef_delete(&structref);

// Creates a borrow that can MODIFY the contents of the RefAny // (mutable "* restrict" borrow instead of "const*" borrow) // // The object cannot be borrowed referentially and mutably at // the same time - this invariant is checked at runtime. MyStructRefMut structrefmut = MyStructRefMut_create(&object); if MyStruct_downcastRefMut(&object, &structrefmut) { // structrefmut can modify the contents of the RefAny structrefmut->ptr.field = 6; // prints "6", value is now changed, visible to all copies of "object" printf!("ok! - %d", structref->ptr.field); }

MyStructRefMut_delete(&structrefmut);

// decreases the refcount - if refcount is 0, destructor is called if !MyStructRefAny_delete(&object) { /* RefAny is not of type "MyStruct" */ }

8. All *Vec data types have a _empty() constructor macro (to create an empty vec at compile time). The AzString type has an extra _fromConstStr() macro to define compile-time strings:

AzScanCodeVec v = AzScanCodeVec_empty(); AzString s = AzString_fromConstStr("hello"); // evaluated at compile-time

Back to guide index