#line 1722 "/home/travis/build/felix-lang/felix/src/packages/gc.fdoc"
  class Collector
  {
    open Rtti;
    struct pointer_data_t
    {
       pointer: address;
       head: address;
       max_elements: size;  // dynamic slots
       used_elements: size; // dynamic slots used
       shape:gc_shape_t;
    };
  
    private type raw_pointer_data_t = "::flx::gc::generic::pointer_data_t" ;
    private fun get_raw_pointer_data: address -> raw_pointer_data_t =
      "PTF gcp->collector->get_pointer_data($1)"
      requires property "needs_gc"
    ;
    fun get_pointer_data (p:address) => C_hack::reinterpret[pointer_data_t](get_raw_pointer_data p);
  
    fun is_felix_pointer (pd: pointer_data_t) => not (isNULL pd.head);
    fun is_head_pointer (pd: pointer_data_t) => pd.pointer == pd.head;
    fun repeat_count (pd: pointer_data_t) => pd.used_elements *  pd.shape.number_of_elements;
    fun allocated_bytes (pd: pointer_data_t) => pd.max_elements *
      pd.shape.number_of_elements * pd.shape.bytes_per_element
    ;
  
    Diagnostic routine, dump pointer data and
    computed values.
    proc print_pointer_data (pd: pointer_data_t)
    {
      println$ "Candidate pointer = " + pd.pointer.str;
      println$ "Valid=" + pd.Collector::is_felix_pointer.str;
      if pd.Collector::is_felix_pointer do
        println$ "Is head=" + pd.Collector::is_head_pointer.str;
        var shape = pd.shape;
        println$ "Element type =  " + shape.cname.string;
        println$ "Pod[has no finaliser] = " + shape.finaliser.address.isNULL.str;
        var bpe = shape.bytes_per_element;
        println$ "Bytes per element = " + bpe.str;
        println$ "Static array length = " + shape.number_of_elements.str;
        println$ "Dynamic array length = " + pd.used_elements.str;
        println$ "Max dynamic array length = " + pd.max_elements.str;
        var nelts = pd.used_elements * shape.number_of_elements;
        println$ "Aggregate number of used elements " + nelts.str;
        println$ "Store to serialise: " + (nelts * bpe) . str;
      done
    }
  
    Diagnostic routine, print info about a pointer.
    proc print_pointer_data (p:address)
    {
      var pd = Collector::get_pointer_data p;
      print_pointer_data (pd);
    }
    proc print_pointer_data[T] (p:&T) => print_pointer_data (C_hack::cast[address] p);
    proc print_pointer_data[T] (p:cptr[T]) => print_pointer_data (C_hack::cast[address] p);
    proc print_pointer_data[T] (p:+T) => print_pointer_data (C_hack::cast[address] p);
  
  }