constraints.i 6.88 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224
/* -----------------------------------------------------------------------------
 * constraints.i
 *
 * SWIG constraints library.
 *
 * SWIG library file containing typemaps for implementing various kinds of 
 * constraints.  Depends upon the SWIG exception library for generating
 * errors in a language-independent manner.
 * ----------------------------------------------------------------------------- */

#ifdef AUTODOC
%text %{
%include <constraints.i>

This library provides support for applying constraints to function
arguments.  Using a constraint, you can restrict arguments to be
positive numbers, non-NULL pointers, and so on.   The following
constraints are available :

      Number  POSITIVE        - Positive number (not zero)
      Number  NEGATIVE        - Negative number (not zero)
      Number  NONZERO         - Nonzero number
      Number  NONNEGATIVE     - Positive number (including zero)
      Number  NONPOSITIVE     - Negative number (including zero)
      Pointer NONNULL         - Non-NULL pointer
      Pointer ALIGN8          - 8-byte aligned pointer
      Pointer ALIGN4          - 4-byte aligned pointer
      Pointer ALIGN2          - 2-byte aligned pointer

To use the constraints, you need to "apply" them to specific
function arguments in your code.  This is done using the %apply
directive.   For example :

  %apply Number NONNEGATIVE { double nonneg };
  double sqrt(double nonneg);         // Name of argument must match
  
  %apply Pointer NONNULL { void *ptr };
  void *malloc(int POSITIVE);       // May return a NULL pointer
  void free(void *ptr);             // May not accept a NULL pointer

Any function argument of the type you specify with the %apply directive
will be checked with the appropriate constraint.   Multiple types may
be specified as follows :

  %apply Pointer NONNULL { void *, Vector *, List *, double *};

In this case, all of the types listed would be checked for non-NULL 
pointers.

The common datatypes of int, short, long, unsigned int, unsigned long,
unsigned short, unsigned char, signed char, float, and double can be
checked without using the %apply directive by simply using the 
constraint name as the parameter name. For example :

  double sqrt(double NONNEGATIVE);
  double log(double POSITIVE);

If you have used typedef to change type-names, you can also do this :

  %apply double { Real };       // Make everything defined for doubles
                                // work for Reals.
  Real sqrt(Real NONNEGATIVE);
  Real log(Real POSITIVE);

%}
#endif

%include <exception.i>

#ifdef SWIGCSHARP
// Required attribute for C# exception handling
#define SWIGCSHARPCANTHROW , canthrow=1
#else
#define SWIGCSHARPCANTHROW
#endif


// Positive numbers

%typemap(check SWIGCSHARPCANTHROW) 
                int               POSITIVE,
                short             POSITIVE,
                long              POSITIVE,
                unsigned int      POSITIVE,
                unsigned short    POSITIVE,
                unsigned long     POSITIVE,
                signed char       POSITIVE,
                unsigned char     POSITIVE,
                float             POSITIVE,
                double            POSITIVE,
                Number            POSITIVE
{
  if ($1 <= 0) {
    SWIG_exception(SWIG_ValueError,"Expected a positive value.");
  }
}

// Negative numbers

%typemap(check SWIGCSHARPCANTHROW) 
                int               NEGATIVE,
                short             NEGATIVE,
                long              NEGATIVE,
                unsigned int      NEGATIVE,
                unsigned short    NEGATIVE,
                unsigned long     NEGATIVE,
                signed char       NEGATIVE,
                unsigned char     NEGATIVE,
                float             NEGATIVE,
                double            NEGATIVE,
                Number            NEGATIVE
{
  if ($1 >= 0) {
    SWIG_exception(SWIG_ValueError,"Expected a negative value.");
  }
}

// Nonzero numbers

%typemap(check SWIGCSHARPCANTHROW) 
                int               NONZERO,
                short             NONZERO,
                long              NONZERO,
                unsigned int      NONZERO,
                unsigned short    NONZERO,
                unsigned long     NONZERO,
                signed char       NONZERO,
                unsigned char     NONZERO,
                float             NONZERO,
                double            NONZERO,
                Number            NONZERO
{
  if ($1 == 0) {
    SWIG_exception(SWIG_ValueError,"Expected a nonzero value.");
  }
}

// Nonnegative numbers

%typemap(check SWIGCSHARPCANTHROW) 
                int               NONNEGATIVE,
                short             NONNEGATIVE,
                long              NONNEGATIVE,
                unsigned int      NONNEGATIVE,
                unsigned short    NONNEGATIVE,
                unsigned long     NONNEGATIVE,
                signed char       NONNEGATIVE,
                unsigned char     NONNEGATIVE,
                float             NONNEGATIVE,
                double            NONNEGATIVE,
                Number            NONNEGATIVE
{
  if ($1 < 0) {
    SWIG_exception(SWIG_ValueError,"Expected a non-negative value.");
  }
}

// Nonpositive numbers

%typemap(check SWIGCSHARPCANTHROW) 
                int               NONPOSITIVE,
                short             NONPOSITIVE,
                long              NONPOSITIVE,
                unsigned int      NONPOSITIVE,
                unsigned short    NONPOSITIVE,
                unsigned long     NONPOSITIVE,
                signed char       NONPOSITIVE,
                unsigned char     NONPOSITIVE,
                float             NONPOSITIVE,
                double            NONPOSITIVE,
                Number            NONPOSITIVE
{
  if ($1 > 0) {
    SWIG_exception(SWIG_ValueError,"Expected a non-positive value.");
  }
}
                
// Non-NULL pointer

%typemap(check SWIGCSHARPCANTHROW) 
                void *            NONNULL,
                Pointer           NONNULL
{
  if (!$1) {
    SWIG_exception(SWIG_ValueError,"Received a NULL pointer.");
  }
}

// Aligned pointers

%typemap(check SWIGCSHARPCANTHROW) 
                void *            ALIGN8,
                Pointer           ALIGN8
{
   unsigned long long tmp;
   tmp = (unsigned long long) $1;
   if (tmp & 7) {
     SWIG_exception(SWIG_ValueError,"Pointer must be 8-byte aligned.");
   }
}

%typemap(check SWIGCSHARPCANTHROW) 
                void *            ALIGN4,
                Pointer           ALIGN4
{
   unsigned long long tmp;
   tmp = (unsigned long long) $1;
   if (tmp & 3) {
     SWIG_exception(SWIG_ValueError,"Pointer must be 4-byte aligned.");
   }
}

%typemap(check SWIGCSHARPCANTHROW) 
                void *            ALIGN2,
                Pointer           ALIGN2
{
   unsigned long long tmp;
   tmp = (unsigned long long) $1;
   if (tmp & 1) {
     SWIG_exception(SWIG_ValueError,"Pointer must be 2-byte aligned.");
   }
}