Skip to content

Latest commit

 

History

History
141 lines (117 loc) · 6.09 KB

box_api.md

File metadata and controls

141 lines (117 loc) · 6.09 KB

STC box: Smart Pointer (boxed object)

box is a smart pointer to a heap allocated value of type X. A box can be empty. The box_X_cmp(), box_X_drop() methods are defined based on the i_cmp and i_keydrop macros specified. Use box_X_clone(p) to make a deep copy, which uses the i_keyclone macro if defined.

When declaring a container of box values, define i_key_arcbox with the box type instead of defining i_key. This will auto-set i_keydrop, i_keyclone, and i_cmp using functions defined by the specified box.

See similar c++ class std::unique_ptr for a functional reference, or Rust std::boxed::Box

Header file and declaration

#define i_TYPE <ct>,<kt> // shorthand to define i_type,i_key
#define i_type <t>       // box container type name (default: box_{i_key})
#define i_key <t>        // element type: REQUIRED. Note: i_val* may be specified instead of i_key*.
#define i_cmp <f>        // three-way compareison. REQUIRED IF i_key is a non-integral type
                         // Note that containers of arcs will "inherit" i_cmp
                         // when using arc in containers with i_val_arcbox MyArc - ie. the i_type.
#define i_use_cmp        // may be defined instead of i_cmp when i_key is an integral/native-type.
#define i_keydrop <f>    // destroy element func - defaults to empty destruct
#define i_keyclone <f>   // REQUIRED if i_keydrop is defined, unless 'i_opt c_no_clone' is defined.

#define i_keyraw <t>     // convertion type (lookup): default to {i_key}
#define i_keyto <f>      // convertion func i_key* => i_keyraw: REQUIRED IF i_keyraw defined.
#define i_keyfrom <f>    // from-raw func.

#define i_tag <s>        // alternative typename: box_{i_tag}. i_tag defaults to i_key
#define i_key_class <t>  // Use instead of i_key when functions {i_key}_clone,
                         // {i_key}_drop and {i_keyraw}_cmp exist.
#define i_key_arcbox <t> // Use instead of i_key when key is a arc- or a box-type.
#include "stc/box.h"

X should be replaced by the value of i_tag in all of the following documentation. Unless c_use_cmp is defined, comparison between i_key's is not needed/available. Will then compare the pointer addresses when used. Additionally, c_no_clone or i_is_fwd may be defined.

Methods

box_X       box_X_init();                                   // return an empty box
box_X       box_X_from(i_keyraw raw);                       // create a box from raw type. Avail if i_keyraw user defined.
box_X       box_X_from_ptr(i_key* ptr);                     // create a box from a pointer. Takes ownership of ptr.
box_X       box_X_make(i_key val);                          // create a box from unowned val object.

box_X       box_X_clone(box_X other);                       // return deep copied clone
box_X       box_X_move(box_X* self);                        // transfer ownership to receiving box returned. self becomes NULL.
void        box_X_take(box_X* self, box_X unowned);         // take ownership of unowned box object.
void        box_X_assign(box_X* self, box_X* moved);        // transfer ownership from moved to self; moved becomes NULL.
void        box_X_drop(box_X* self);                        // destruct the contained object and free its heap memory.

void        box_X_reset(box_X* self);
void        box_X_reset_to(box_X* self, i_key* p);          // assign new box from ptr. Takes ownership of p.

uint64_t    box_X_hash(const box_X* x);                     // hash value
int         box_X_cmp(const box_X* x, const box_X* y);      // compares pointer addresses if no `i_cmp` is specified.
                                                            // is defined. Otherwise uses 'i_cmp' or default cmp.
bool        box_X_eq(const box_X* x, const box_X* y);       // box_X_cmp() == 0

// functions on pointed to objects.

uint64_t    box_X_value_hash(const i_key* x);
int         box_X_value_cmp(const i_key* x, const i_key* y);
bool        box_X_value_eq(const i_key* x, const i_key* y);

Types and constants

Type name Type definition Used to represent...
box_null {0} Init nullptr const
box_X struct { box_X_value* get; } The box type
box_X_value i_key The box element type

Example

Create a vec and a set with owned pointers to int elements, using box.

#include <stdio.h>
void int_drop(int* x) {
    printf("\n drop %d", *x);
}

#define i_TYPE IBox,int
#define i_keydrop int_drop  // optional func, just to display elements destroyed
#define i_keyclone(x) x     // must be specified when i_keydrop is defined.
#define i_use_cmp           // enable usage of default comparison == and < operators
#include "stc/box.h"

#define i_type ISet
#define i_key_arcbox IBox   // NB: use i_key_arcbox instead of i_key
#include "stc/sset.h"       // ISet : std::set<std::unique_ptr<int>>

#define i_type IVec
#define i_key_arcbox IBox   // NB: use i_key_arcbox instead of i_key
#include "stc/vec.h"        // IVec : std::vector<std::unique_ptr<int>>

int main(void)
{
    IVec vec = c_init(IVec, {2021, 2012, 2022, 2015});
    ISet set = {0};
    c_defer(
      IVec_drop(&vec),
      ISet_drop(&set)
    ){
        printf("vec:");
        c_foreach (i, IVec, vec)
            printf(" %d", *i.ref->get);

        // add odd numbers from vec to set
        c_foreach (i, IVec, vec)
            if (*i.ref->get & 1)
                ISet_insert(&set, IBox_clone(*i.ref));

        // pop the two last elements in vec
        IVec_pop(&vec);
        IVec_pop(&vec);

        printf("\nvec:");
        c_foreach (i, IVec, vec)
            printf(" %d", *i.ref->get);

        printf("\nset:");
        c_foreach (i, ISet, set)
            printf(" %d", *i.ref->get);
    }
}

Output:

vec: 2021 2012 2022 2015
 drop 2015
 drop 2022
vec: 2021 2012
set: 2015 2021
 drop 2021
 drop 2015
 drop 2012
 drop 2021