Class: AutoC::Reference

Inherits:
Type show all
Extended by:
Forwardable
Defined in:
lib/autoc/type.rb

Overview

Reference represents a managed counted reference for any type. It can be used with any type, including AutoC collections themselves.

Generated C interface

Type management

Type * typeNew(…​)

Create and return a reference to Type with reference count set to one.

The storage for the returned instance is malloc()'ed. The instance is constructed with the type’s constructor typeCtor(…​).

NOTE: The generated method borrows the second and subsequent arguments from the respective constructor.

Type * typeRef(Type * self)

Increment the self's reference count and return self.

void typeFree(Type * self)

Decrement the self's reference count. If the reference count reaches zero, free the storage and destroy the instance with the type’s destructor typeDtor().

Instance Attribute Summary

Attributes inherited from Type

#type, #type_ref

Instance Method Summary collapse

Methods inherited from Type

#abort, #assert, #calloc, coerce, #comparable?, #constructible?, #copyable?, #destructible?, #extern, #free, #hash, #hashable?, #inline, #malloc, #method_missing, #orderable?, #prefix, #private?, #public?, #static, #static?, #write_decls, #write_defs, #write_intf

Methods inherited from Code

#attach, #priority, #source_size, #write_decls, #write_defs, #write_intf

Constructor Details

#initialize(target) ⇒ Reference

Returns a new instance of Reference.



381
382
383
384
385
386
387
388
389
390
391
# File 'lib/autoc/type.rb', line 381

def initialize(target)
  @target = Type.coerce(target)
  super(@target.type_ref) # NOTE : the type of the Reference instance itself is actually a pointer type
  @ctor_params = Dispatcher::ParameterArray.new(@target.ctor.parameters[1..-1]) # Capture extra parameters from the target type constructor
  define_callable(:ctor, @ctor_params) {def call(obj, *params) "((#{obj}) = #{@ref.new?}(#{params.join(',')}))" end}
  define_callable(:dtor, [type]) {def call(obj) "#{@ref.free?}(#{obj})" end}
  define_callable(:copy, [type, type]) {def call(dst, src) "((#{dst}) = #{@ref.ref?}(#{src}))" end}
  define_callable(:equal, [type, type]) {def call(lt, rt) @target.equal("*#{lt}", "*#{rt}") end}
  define_callable(:less, [type, type]) {def call(lt, rt) @target.less("*#{lt}", "*#{rt}") end}
  define_callable(:identify, [type]) {def call(obj) @target.identify("*#{obj}") end}
end

Dynamic Method Handling

This class handles dynamic methods through the method_missing method in the class AutoC::Type

Instance Method Details

#==(other) ⇒ Object Also known as: eql?



393
# File 'lib/autoc/type.rb', line 393

def ==(other) @target == other.instance_variable_get(:@target) end

#entitiesObject



397
# File 'lib/autoc/type.rb', line 397

def entities; super << @target end

#write_impls(stream, define) ⇒ Object



410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
# File 'lib/autoc/type.rb', line 410

def write_impls(stream, define)
  stream << %$
  #define AUTOC_COUNTER(p) (*(size_t*)((char*)(p) + sizeof(#{@target.type})))
    #{define} #{type} #{new?}(#{@ctor_params.definition}) {
      #{type} self = (#{type})#{malloc}(sizeof(#{@target.type}) + sizeof(size_t)); #{assert}(self);
      #{@target.ctor("*self", *@ctor_params.names)};
      AUTOC_COUNTER(self) = 1;
      return self;
    }
    #{define} #{type} #{ref?}(#{type} self) {
      #{assert}(self);
      ++AUTOC_COUNTER(self);
      return self;
    }
    #{define} void #{free?}(#{type} self) {
      #{assert}(self);
      if(--AUTOC_COUNTER(self) == 0) {
        #{@target.dtor("*self")};
        #{free}(self);
      }
    }
    #undef AUTOC_COUNTER
  $
end

#write_intf_decls(stream, declare, define) ⇒ Object



399
400
401
402
403
404
405
406
407
408
# File 'lib/autoc/type.rb', line 399

def write_intf_decls(stream, declare, define)
  stream << %$
    /***
    ****  <#{type}> (#{self.class})
    ***/
    #{declare} #{type} #{new?}(#{@ctor_params.declaration});
    #{declare} #{type} #{ref?}(#{type});
    #{declare} void #{free?}(#{type});
  $
end