(doc Pointer "is a data type for representing C pointers.") (defmodule Pointer (doc eq "checks two pointers for equality.") (deftemplate eq (Fn [(Ptr p) (Ptr p)] Bool) "bool $NAME($p *p1, $p *p2)" " $DECL { return p1 == p2; }") (implements = Pointer.eq) (doc eq "checks two pointer references for equality.") (deftemplate ref-eq (Fn [(Ref (Ptr p)) (Ref (Ptr p))] Bool) "bool $NAME($p **p1, $p **p2)" " $DECL { return *p1 == *p2; }") (implements = Pointer.ref-eq) (doc address "returns the memory address of a reference. Equivalent to the `&` operator when placed before a variable in C.") (deftemplate address (Fn [(Ref a)] (Ptr a)) "$a * $NAME($a * a)" "$DECL { return a; }") (doc to-ref "converts a pointer to a reference type. The user will have to ensure themselves that this is a safe operation.") (deftemplate to-ref (Fn [(Ptr p)] (Ref p)) "$p* $NAME($p* p)" " $DECL { return p; }") (doc to-value "converts a pointer to a value. The user will have to ensure themselves that this is a safe operation.") (deftemplate to-value (Fn [(Ptr p)] p) "$p $NAME($p* p)" " $DECL { return *p; }") (doc add "adds a long integer value to a pointer.") (deftemplate add (Fn [(Ptr p) Long] (Ptr p)) "$p* $NAME($p* p, Long x)" " $DECL { return p + x; }") (doc sub "subtracts a long integer value from a pointer.") (deftemplate sub (Fn [(Ptr p) Long] (Ptr p)) "$p* $NAME($p* p, Long x)" " $DECL { return p - x; }") (doc width "gets the byte size of a pointer.") (deftemplate width (Fn [(Ptr p)] Long) "Long $NAME($p* p)" " $DECL { return sizeof(*p); }") (doc to-long "converts a pointer to a long integer.") (deftemplate to-long (Fn [(Ptr p)] Long) "Long $NAME($p* p)" " $DECL { return (Long)p; }") (doc from-long "converts a long integer to a pointer.") (deftemplate from-long (Fn [Long] (Ptr p)) "$p* $NAME(Long p)" " $DECL { return ($p*)p; }") (doc unsafe-set "Sets the value of a pointer to a value of any type." "The user will have to ensure this operation is safe.") (deftemplate unsafe-set (Fn [(Ptr p) a] Unit) "void $NAME($p* p, $a a)" "$DECL { *p = ($p)a; }") (doc unsafe-alloc "Allocate a new pointer to the value `a`." ("This pointer won't be managed by Carp's borrow checker and will cause " false) "memory leaks unless explicitly freed using `Pointer.free`." "" ("See `Unsafe.leak` if you want to prevent Carp's automatic memory management " false) "from deallocating a value without performing an allocation." "" "```" "(let-do [x (Pointer.unsafe-alloc @\"c\")]" " (Pointer.set x @\"carp\")" " (println* (Pointer.to-value x))" " (Pointer.free x))" "```") (deftemplate unsafe-alloc (Fn [a] (Ptr a)) "$a* $NAME($a r)" "$DECL { void *leak = CARP_MALLOC(sizeof($a)); *($a*)leak= r; return ($a*)leak;}") (doc free "Free a pointer, deallocating the memory associated with it." ("Carp's borrow checker handles deallocation automatically for managed types. " false) ("The Ptr type is unmanaged, so pointers allocated with functions " false) "such as `Pointer.unsafe-alloc` need to be deallocated manually using this function." "Users need to manually verify that this operation is safe." "" "```" "(let-do [x (Pointer.unsafe-alloc @\"c\")]" " (Pointer.set x @\"carp\")" " (println* (Pointer.to-value x))" " (Pointer.free x))" "```") (deftemplate free (Fn [(Ptr p)] Unit) "void $NAME($p* p)" "$DECL {CARP_FREE(p);}") (doc set "Sets the value of a pointer.") (deftemplate set (Fn [(Ptr p) p] Unit) "void $NAME($p* p, $p a)" "$DECL { *p = a; }") (defn inc [a] (Pointer.add a 1l)) (implements inc Pointer.inc) (defn dec [a] (Pointer.sub a 1l)) (implements dec Pointer.dec) )