#line 13 "/home/travis/build/felix-lang/felix/src/packages/pointers.fdoc"
  
  Felix and C pointers.
  Felix pointer ptr[T] = &T.
  C pointer cptr[T] = &T.
  See also carray for incrementable pointers carray[T] = +T.
  open class Cptr
  {
    Type of a Felix pointer.
    Always points to an object.
    Cannot be NULL.
    Cannot be incremented.
    typedef ptr[T] = &T;
  
    Dereference a Felx pointer.
    lvalue fun deref[T]: &T -> T = "*$1";
  
    Type of a C pointer.
    Either pointes to an object or is NULL.
    Cannot be incremented.
    union cptr[T] = | nullptr | Ptr of &T;
  
    Demote a Felix pointer to a C pointer. Safe.
    ctor[T] cptr[T]: &T = "$1";
  
    Promote a C pointer to a Felix pointer.
    Conversion is checked.
    Aborts with match failure if NULL.
    ctor[T] ptr[T]( px:cptr[T]) => let Ptr  p = px in p; // match failure if null
  
    Checked dereference of C pointer.
    fun deref[T] (px:cptr[T])=> *(px.ptr);
  
    Test if a C pointer is NULL.
    fun is_nullptr[T] (px:cptr[T])=> match px with | #nullptr => true | _ => false endmatch;
  
    instance[T] Eq[cptr[T]] {
      Equality of C pointers.
      fun == : cptr[T] * cptr[T] -> bool = "$1==$2";
    }
    instance[T] Tord[cptr[T]] {
      Total ordering of C pointer.
      NULL is the least element.
      fun < : cptr[T] * cptr[T] -> bool = "$1<$2";
    }
  
    Allocate unmanaged C++ object on the heap and return pointer.
    Felix does not check the argument type, but C++ does.
    The argument must select a suitable C++ constructor.
    gen cnew[T,A] : A -> &T = "new (?1)($a)";
  
    Delete unmanaged C++ object from heap
    proc delete[T] : &T = "delete $1;";
  
    Allocate managed C++ object directly on heap.
    Felix does not check the argument type, but C++ does.
    The argument must select a suitable constructor.
    gen gcnew[T,A] : A -> &T = "new (*PTF gcp, @?1,true) (?1)($a)";
  
  }
  
  open[T] Eq[cptr[T]];
  open[T] Tord[cptr[T]];
  
  Special notation @T for  type of a C pointer.
  typedef fun n"@" (T:TYPE) : TYPE => cptr[T];