/* -----------------------------------------------------------------------------
 * cpointer.swg
 *
 * This library file contains macros that can be used to manipulate simple
 * pointer objects.
 *
 * ----------------------------------------------------------------------------- */

/* -----------------------------------------------------------------------------
 * %pointer_class(type,name)
 *
 * Places a simple proxy around a simple type like 'int', 'float', or whatever.
 * The proxy provides this interface:
 *
 *       class type {
 *       public:
 *           type();
 *          ~type();
 *           type value();
 *           void assign(type value);
 *       };
 *         
 * Example:
 *
 *    %pointer_class(int, intp);
 *
 *    int add(int *x, int *y) { return *x + *y; }
 *
 * In python (with proxies)
 *
 *    >>> a = intp()
 *    >>> a.assign(10)
 *    >>> a.value()
 *    10
 *    >>> b = intp()
 *    >>> b.assign(20)
 *    >>> print add(a,b)
 *    30
 *
 * As a general rule, this macro should not be used on class/structures that
 * are already defined in the interface.
 * ----------------------------------------------------------------------------- */


%define %pointer_class(TYPE, NAME)
%{
typedef TYPE NAME;
%}

typedef struct {
} NAME;

%extend NAME {
  NAME() {
    return %new_instance(TYPE);
  }
  ~NAME() {
    %delete($self);
  }
}

%extend NAME {

  void assign(TYPE value) {
    *$self = value;
  }
  TYPE value() {
    return *$self;
  }
  TYPE * cast() {
    return $self;
  }
  static NAME * frompointer(TYPE *t) {
    return (NAME *) t;
  }
}

%types(NAME = TYPE);

%enddef

/* ----------------------------------------------------------------------------- 
 * %pointer_functions(type,name)
 *
 * Create functions for allocating/deallocating pointers.   This can be used
 * if you don't want to create a proxy class or if the pointer is complex.
 *
 *    %pointer_functions(int, intp)
 *
 *    int add(int *x, int *y) { return *x + *y; }
 *
 * In python (with proxies)
 *
 *    >>> a = copy_intp(10)
 *    >>> intp_value(a)
 *    10
 *    >>> b = new_intp()
 *    >>> intp_assign(b,20)
 *    >>> print add(a,b)
 *    30
 *    >>> delete_intp(a)
 *    >>> delete_intp(b)
 * 
 * ----------------------------------------------------------------------------- */

%define %pointer_functions(TYPE,NAME)
%{
  static TYPE *new_##NAME(void) {
    return %new_instance(TYPE);
  }
  
  static TYPE *copy_##NAME(TYPE value) { 
    return %new_copy(value, TYPE);
  }

  static void delete_##NAME(TYPE *obj) { 
    %delete(obj);
  }

  static void NAME ##_assign(TYPE *obj, TYPE value) {
    *obj = value;
  }

  static TYPE NAME ##_value(TYPE *obj) {
    return *obj;
  }
%}

TYPE *new_##NAME(void);
TYPE *copy_##NAME(TYPE value);
void  delete_##NAME(TYPE *obj);
void  NAME##_assign(TYPE *obj, TYPE value);
TYPE  NAME##_value(TYPE *obj);

%enddef

/* -----------------------------------------------------------------------------
 * %pointer_cast(type1,type2,name)
 *
 * Generates a pointer casting function.
 * ----------------------------------------------------------------------------- */

%define %pointer_cast(TYPE1,TYPE2,NAME)
%inline %{
TYPE2 NAME(TYPE1 x) {
   return %static_cast(x, TYPE2);
}
%}
%enddef








