LAL 7.7.1.1-bf6a62b
SWIGOctave.i
Go to the documentation of this file.
1//
2// Copyright (C) 2011--2017, 2022 Karl Wette
3//
4// This program is free software; you can redistribute it and/or modify
5// it under the terms of the GNU General Public License as published by
6// the Free Software Foundation; either version 2 of the License, or
7// (at your option) any later version.
8//
9// This program is distributed in the hope that it will be useful,
10// but WITHOUT ANY WARRANTY; without even the implied warranty of
11// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12// GNU General Public License for more details.
13//
14// You should have received a copy of the GNU General Public License
15// along with with program; see the file COPYING. If not, write to the
16// Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
17// MA 02110-1301 USA
18//
19
20// SWIG interface code specific to Octave.
21// Author: Karl Wette
22
23//
24// General SWIG directives and interface code
25//
26
27// In SWIG Octave modules, only variables are namespaced, everything else
28// is inserted in the global symbol table, so we rename only variables
29#define SWIGLAL_MODULE_RENAME_VARIABLES
30
31// Include SWIG Octave headers.
32%include <octcomplex.swg>
33
34// Include Octave headers and set versioning macros.
35%header %{
36extern "C++" {
37#include <octave/ov-cell.h>
38#include <octave/ov-int-traits.h>
39#include <octave/ov-flt-re-mat.h>
40#include <octave/ov-re-mat.h>
41#include <octave/ov-flt-cx-mat.h>
42#include <octave/ov-cx-mat.h>
43#include <octave/Array-util.h>
44}
45%}
46
47// Evaluates true if an octave_value is not empty, false otherwise.
48%header %{
49#define swiglal_not_empty(v) (!(v).is_empty())
50%}
51
52// Name of octave_value containing the SWIG wrapping of the struct whose members are being accessed.
53%header %{
54#define swiglal_self() (args.length() > 0 ? args(0) : octave_value())
55#define swiglal_no_self() (octave_value())
56%}
57
58// Name of octave_value containing the SWIG wrapping of the first argument to a function.
59%header %{
60#define swiglal_1starg() (args.length() > 0 ? args(0) : octave_value())
61%}
62
63// Return a reference to the supplied octave_value; since Octave handles reference counting, just return it.
64%header %{
65#define swiglal_get_reference(v) (v)
66%}
67
68// Remove the first argument (i.e. the XLAL error code) from the output argument list of an
69// Octave SWIG-wrapped function, if the list has more than one output argument.
70%header %{
71#define swiglal_maybe_return_int() \
72 if (_out.length() > 1) _out = _out.slice(1, _out.length() - 1)
73%}
74
75// Evaluates true if an octave_value represents a null pointer, false otherwise.
76%header %{
77#define swiglal_null_ptr(v) (!(v).is_string() && (v).is_matrix_type() && (v).rows() == 0 && (v).columns() == 0)
78%}
79
80// Python-specific function for standard output/error redirection
81%header %{
82SWIGINTERN int swiglal_output_stdouterr(void) {
83
84 // Flush and rewind temporary files
85 fflush(swiglal_tmp_stdout);
86 rewind(swiglal_tmp_stdout);
87 fflush(swiglal_tmp_stderr);
88 rewind(swiglal_tmp_stderr);
89
90 // Write standard output
91 {
92 octave_value_list args = feval("stdout", octave_value_list(), 1);
93 if (args.length() < 1) {
94 return 0;
95 }
96 args.resize(3);
97 args(1) = octave_value(std::string("%s"));
98 char buf[512];
99 while (fgets(buf, sizeof(buf), swiglal_tmp_stdout) != NULL) {
100 args(2) = octave_value(std::string(buf));
101 feval("fprintf", args, 0);
102 }
103 }
104
105 // Write standard error
106 {
107 octave_value_list args = feval("stderr", octave_value_list(), 1);
108 if (args.length() < 1) {
109 return 0;
110 }
111 args.resize(3);
112 args(1) = octave_value(std::string("%s"));
113 char buf[512];
114 while (fgets(buf, sizeof(buf), swiglal_tmp_stderr) != NULL) {
115 args(2) = octave_value(std::string(buf));
116 feval("fprintf", args, 0);
117 }
118 }
119
120 // Close temporary files
121 fclose(swiglal_tmp_stdout);
122 fclose(swiglal_tmp_stderr);
123
124 return 1;
125
126}
127%}
128
129//
130// SWIG directives for operators
131//
132
133// Unary operators which return a new object, and thus require %newobject to be set.
134%define %swiglal_oct_urn_op(NAME, OCTNAME)
135%rename(__##OCTNAME##__) *::__##NAME##__;
136%newobject *::__##NAME##__;
137%enddef
138%swiglal_oct_urn_op(abs, abs);
139%swiglal_oct_urn_op(neg, uminus);
140%swiglal_oct_urn_op(pos, uplus);
141
142// Binary operators, which always must return a new object, and thus require %newobject to be set.
143%define %swiglal_oct_bin_op(NAME)
144%newobject *::__##NAME##__;
145%newobject *::__r##NAME##__;
146%enddef
147%swiglal_oct_bin_op(add);
148%swiglal_oct_bin_op(and);
149%swiglal_oct_bin_op(div);
150%swiglal_oct_bin_op(lshift);
151%swiglal_oct_bin_op(mod);
152%swiglal_oct_bin_op(mul);
153%swiglal_oct_bin_op(or);
154%swiglal_oct_bin_op(pow);
155%swiglal_oct_bin_op(rshift);
156%swiglal_oct_bin_op(sub);
157%swiglal_oct_bin_op(xor);
158
159// Octave __pow__() operator takes 2 arguments, so we ignore the 3rd.
160%typemap(in, numinputs=0) void* SWIGLAL_OP_POW_3RDARG "";
161
162// Comparison operators.
163%typemap(in, numinputs=0, noblock=1) int SWIGLAL_CMP_OP_RETN_HACK "";
164
165//
166// Octave-specific extensions to structs
167//
168
169// Extend a struct TAGNAME.
170%define %swiglal_struct_extend_specific(TAGNAME, OPAQUE, DTORFUNC)
171
172%enddef // %swiglal_struct_extend_specific
173
174//
175// General fragments, typemaps, and macros
176//
177
178// SWIG conversion fragments and typemaps for GSL complex numbers.
179%swig_cplxflt_convn(gsl_complex_float, gsl_complex_float_rect, GSL_REAL, GSL_IMAG);
180%swig_cplxdbl_convn(gsl_complex, gsl_complex_rect, GSL_REAL, GSL_IMAG);
181%typemaps_primitive(%checkcode(CPLXFLT), gsl_complex_float);
182%typemaps_primitive(%checkcode(CPLXDBL), gsl_complex);
183
184// SWIG conversion fragments and typemaps for LAL complex numbers.
185%swig_cplxflt_convn(COMPLEX8, crectf, crealf, cimagf);
186%swig_cplxdbl_convn(COMPLEX16, crect, creal, cimag);
187%typemaps_primitive(%checkcode(CPLXFLT), COMPLEX8);
188%typemaps_primitive(%checkcode(CPLXDBL), COMPLEX16);
189
190// Typemaps which convert to/from the C broken-down date/time struct.
191%typemap(in, fragment=SWIG_AsVal_frag(double)) struct tm* (struct tm temptm) {
192
193 // Convert '$input' to an Octave date number 'datenum'
194 octave_value_list datenum_args;
195 if ($input.is_string()) {
196 datenum_args.append($input);
197 } else {
198 dim_vector dims = $input.dims();
199 if (dims.length() == 2 && dims.num_ones() == 1 && 3 <= dims.numel() && dims.numel() <= 6) {
200 RowVector datevec = $input.row_vector_value();
201 for (int i = 0; i < datevec.numel(); ++i) {
202 datenum_args.append(octave_value(datevec(i)));
203 }
204 }
205 }
206 octave_value_list retn;
207 if (datenum_args.length() > 0) {
208 retn = feval("datenum", datenum_args, 1);
209 }
210 if (retn.length() == 0) {
211 %argument_fail(SWIG_ValueError, "$type", $symname, $argnum);
212 }
213 double datenum = 0;
214 int res = SWIG_AsVal(double)(retn(0), &datenum);
215 if (!SWIG_IsOK(res)) {
216 %argument_fail(res, "$type", $symname, $argnum);
217 }
218
219 // Convert 'datenum' to a C time_t 't', using the following:
220 // 1970-01-01 00:00:00 +0000: 'datenum'=719529, 't'=0
221 // 1970-01-02 00:00:00 +0000: 'datenum'=719530, 't'=86400
222 time_t t = (time_t) llround((datenum - 719529) * 86400);
223
224 // Convert 't' to a C struct tm 'temptm'
225 memset(&temptm, 0, sizeof(temptm));
226 if (gmtime_r(&t, &temptm) == NULL) {
227 %argument_fail(SWIG_RuntimeError, "$type", $symname, $argnum);
228 }
229
230 $1 = &temptm;
231
232}
233%typemap(freearg) struct tm* "";
234%typemap(out) struct tm* {
235
236 // Create an Octave date vector 'datevec'
237 RowVector datevec(6);
238
239 // Assign members 'datevec', converting 'tm' struct date ranges to Octave date ranges
240 datevec(0) = $1->tm_year + 1900; // Octave stores 4-digit years
241 datevec(1) = $1->tm_mon + 1; // Octave months start from 1
242 datevec(2) = $1->tm_mday;
243 datevec(3) = $1->tm_hour;
244 datevec(4) = $1->tm_min;
245 datevec(5) = $1->tm_sec;
246
247 $result = octave_value(datevec);
248
249}
250
251//
252// Runtime data
253//
254
255%fragment("SWIG_AsCharPtrAndSize");
256%fragment("SWIG_FromCharPtr");
257%init %{
258
259// Check for consistent SWIG runtime version number between SWIGLAL wrappers.
260{
261 const char* const swig_runtime_version_name = "__SWIGLAL_RUNTIME_DATA_swig_runtime_version__";
262 const char* const last_swiglal_wrapper_name = "__SWIGLAL_RUNTIME_DATA_last_swiglal_wrapper__";
263 octave_value ov = SWIG_Octave_GetGlobalValue(swig_runtime_version_name);
264 octave_value ov2 = SWIG_Octave_GetGlobalValue(last_swiglal_wrapper_name);
265 char *swig_runtime_version_str = NULL;
266 int alloc = 0;
267 int res = SWIG_AsCharPtrAndSize(ov, &swig_runtime_version_str, NULL, &alloc);
268 if (SWIG_IsOK(res)) {
269 char *last_swiglal_wrapper_str = NULL;
270 int alloc2 = 0;
271 int res2 = SWIG_AsCharPtrAndSize(ov2, &last_swiglal_wrapper_str, NULL, &alloc2);
272 assert(SWIG_IsOK(res2));
273 if (strcmp(swig_runtime_version_str, SWIG_RUNTIME_VERSION) != 0) {
274 error(
275 "Mismatch in SWIG runtime versions: %s is version %s, but %s has already been loaded with version %s",
276 SWIGLAL_PACKAGE, SWIG_RUNTIME_VERSION, last_swiglal_wrapper_str, swig_runtime_version_str
277 );
278 if (alloc) {
279 free(swig_runtime_version_str);
280 }
281 if (alloc2) {
282 free(last_swiglal_wrapper_str);
283 }
284 return false;
285 }
286 if (alloc) {
287 free(swig_runtime_version_str);
288 }
289 if (alloc2) {
290 free(last_swiglal_wrapper_str);
291 }
292 } else {
293 ov = SWIG_FromCharPtr(SWIG_RUNTIME_VERSION);
294 SWIG_Octave_SetGlobalValue(swig_runtime_version_name, ov);
295 }
296 ov2 = SWIG_FromCharPtr(SWIGLAL_PACKAGE);
297 SWIG_Octave_SetGlobalValue(last_swiglal_wrapper_name, ov2);
298}
299
300%} // %init
301
302//
303// Interface code to track object parents
304//
305
306// Interface code which tracks the parent structs of SWIG-wrapped struct members, so that the
307// parent struct is not destroyed as long as a SWIG-wrapped object containing any of its
308// members exists.
309%header %{
310
311#include <map>
312
313// Internal map from member pointers to octave_values containing the member parent struct, as well
314// as an internal reference count of how many SWIG-wrapped member objects are extant.
315typedef std::pair<octave_value, int> swiglal_oct_parent;
316typedef std::pair<void*, swiglal_oct_parent> swiglal_oct_parent_pair;
317typedef std::map<void*, swiglal_oct_parent> swiglal_oct_parent_map;
318static swiglal_oct_parent_map* parent_map = 0;
319
320// Store a reference to the parent of ptr in the internal map. If there is already such a reference,
321// increment the internal reference count instead.
322SWIGINTERN void swiglal_store_parent(void* ptr, octave_value parent) {
323 assert(ptr);
324 assert(parent.is_defined());
325 swiglal_oct_parent_map::iterator i = parent_map->find(ptr);
326 if (i == parent_map->end()) {
327 parent_map->insert(swiglal_oct_parent_pair(ptr, swiglal_oct_parent(parent, 1)));
328 }
329 else {
330 ++i->second.second;
331 }
332}
333
334// Check if ptr stored a reference to a parent struct. If there is no parent object, then ptr
335// *really* owns its memory, and it's okay for it to destroy it (so return true). Otherwise,
336// decrement the internal reference count, erase the parent map entry if it reaches zero, and
337// return false to prevent any destructors being called.
338SWIGINTERN bool swiglal_release_parent(void *ptr) {
339 bool retn = true;
340 assert(ptr);
341 swiglal_oct_parent_map::iterator i = parent_map->find(ptr);
342 if (i != parent_map->end()) {
343 retn = false;
344 if (--i->second.second == 0) {
345 parent_map->erase(i);
346 }
347 }
348 return retn;
349}
350
351%} // %header
352%init %{
353
354// Get a pointer to the internal parent map. Look for a global variable
355// '__SWIGLAL_RUNTIME_DATA_parent_map__', then try to extract a pointer to the parent map from
356// a SWIG packed object. If the packed object does not yet exist, create a new map, pack its
357// pointer in a SWIG packed object, then assign it to global variable. Thus each binding gets a
358// pointer to the same map.
359{
360 const char* const parent_map_name = "__SWIGLAL_RUNTIME_DATA_parent_map__";
361 octave_value ov = SWIG_Octave_GetGlobalValue(parent_map_name);
362 int res = SWIG_ConvertPacked(ov, &parent_map, sizeof(parent_map), 0);
363 if (!SWIG_IsOK(res)) {
364 parent_map = new swiglal_oct_parent_map();
365 ov = SWIG_NewPackedObj(&parent_map, sizeof(parent_map), 0);
366 SWIG_Octave_SetGlobalValue(parent_map_name, ov);
367 }
368 assert(parent_map);
369}
370
371%} // %init
372
373//
374// Fragments and typemaps for arrays
375//
376
377// This section implements a series of array view classes, through which arbitrary C array data can
378// be viewed as native Octave matrices, etc.
379
380// Name of array view class for array conversion type ACFTYPE.
381#define %swiglal_oct_array_view_class(ACFTYPE) swiglal_oct_array_view_##ACFTYPE
382
383// Name of helper class for array view class for array conversion type ACFTYPE.
384#define %swiglal_oct_array_view_helper_class(ACFTYPE) swiglal_oct_array_view_helper_##ACFTYPE
385
386// Name of base array view template for array conversion type ACFTYPE.
387#define %swiglal_oct_array_view_tmpl(ACFTYPE) swiglal_oct_array_view<%swiglal_oct_array_view_helper_class(ACFTYPE) >
388
389// String denoting octave_value type of array view class for array conversion type ACFTYPE.
390#define %swiglal_oct_array_view_ovtype(ACFTYPE) "swiglal_oct_array_view_" %str(ACFTYPE)
391
392// Name of fragment containing array view class for array conversion type ACFTYPE.
393#define %swiglal_oct_array_view_frag(ACFTYPE) "swiglal_oct_array_view_" %str(ACFTYPE)
394
395// Name of fragment containing initialisation code for array view class for array conversion type
396// ACFTYPE.
397#define %swiglal_oct_array_view_init_frag(ACFTYPE) "swiglal_oct_array_view_init_" %str(ACFTYPE)
398
399// Fragment defining a base array view template, where all functionality is implemented, and from
400// which ACFTYPE-specific array view classes inherit. The template argument is a helper class which
401// supplied ACFTYPE-specific functions and types.
402%fragment("swiglal_oct_array_view", "header") {
403
404 extern "C++" {
405
406 template<class HELPER>
407 class swiglal_oct_array_view : public octave_base_value {
408
409 private:
410
411 // Instance of the corresponding octave_base_value-derived class of the array view class, for
412 // consulting as to various properties.
413 const typename HELPER::OVClass sloav_class;
414
415 // Keep a reference to the SWIG-wrapped struct containing the C array being viewed, to prevent
416 // it being destroyed if the struct goes out of scope by the array view remains.
417 const octave_value sloav_parent;
418
419 // Parameters of the C array data being viewed, and associated SWIG type information.
420 void *const sloav_ptr;
421 const size_t sloav_esize;
422 const size_t sloav_ndims;
423 const dim_vector sloav_dims;
424 const dim_vector sloav_strides;
425 const bool sloav_isptr;
426 swig_type_info *const sloav_tinfo;
427 const int sloav_tflags;
428
429 // Construct an Octave dim_vector from a C array.
430 static dim_vector sloav_make_dim_vector(const size_t n, const size_t v[]) {
431 dim_vector dv(n, 1);
432 for (size_t i = 0; i < n; ++i) {
433 dv(i) = v[i];
434 }
435 return dv;
436 }
437
438 // Numeric conversion function for converting an array view into an Octave array.
439 static octave_base_value* sloav_numeric_conversion_function(const octave_base_value& v) {
440 const swiglal_oct_array_view& oav = dynamic_cast<const swiglal_oct_array_view&>(v);
441 octave_value ov = oav.sloav_array_out();
442 return new typename HELPER::OVClass(HELPER::ovvalue(ov));
443 }
444
445 // Compute the scalar index of the C array element, and return a pointer to the element itself.
446 void* sloav_get_element_ptr(Array<octave_idx_type>& idx) const {
447 size_t elemidx = 0;
448 for (size_t j = 0; j < sloav_ndims; ++j) {
449 elemidx += idx(j) * sloav_strides(j);
450 }
451 return reinterpret_cast<void*>(reinterpret_cast<char*>(sloav_ptr) + elemidx*sloav_esize);
452 }
453
454 // Increment the Octave array index in row-major order, to match the ordering of the C array.
455 void sloav_increment_idx(Array<octave_idx_type>& idx) const {
456 for (int j = sloav_ndims-1; j >= 0; --j) {
457 if (++idx(j) < sloav_dims(j)) {
458 break;
459 }
460 idx(j) = 0;
461 }
462 }
463
464 public:
465
466 virtual ~swiglal_oct_array_view()
467 { }
468
469 swiglal_oct_array_view()
470 : octave_base_value(), sloav_class(typename HELPER::OVClass()),
471 sloav_parent(), sloav_ptr(0), sloav_esize(0), sloav_ndims(0),
472 sloav_dims(), sloav_strides(),
473 sloav_isptr(false), sloav_tinfo(0), sloav_tflags(0)
474 { }
475
476 swiglal_oct_array_view(const octave_value& parent,
477 void* ptr,
478 const size_t esize,
479 const size_t ndims,
480 const size_t dims[],
481 const size_t strides[],
482 const bool isptr,
483 swig_type_info* tinfo,
484 const int tflags)
485 : octave_base_value(), sloav_class(typename HELPER::OVClass()),
486 sloav_parent(parent), sloav_ptr(ptr), sloav_esize(esize), sloav_ndims(ndims),
487 sloav_dims(sloav_make_dim_vector(ndims, dims)),
488 sloav_strides(sloav_make_dim_vector(ndims, strides)),
489 sloav_isptr(isptr), sloav_tinfo(tinfo), sloav_tflags(tflags)
490 { }
491
492 // Copy the Octave array obj to the C array.
493 int sloav_array_in(octave_value& obj, int *pelemalloc, const int tflags) {
494
495 // Check that C array pointer is valid.
496 if (!sloav_ptr) {
497 return SWIG_MemoryError;
498 }
499
500 // Check that Octave array dimensions are consistent with C array dimensions. 1-D arrays
501 // are a special case, since Octave arrays are always at least 2-dimensional, so need to
502 // check that one of those dimensions is singular.
503 dim_vector objdims = obj.dims();
504 if (sloav_ndims == 1) {
505 if (objdims.length() > 2 || objdims.num_ones() == 0 || objdims.numel() != sloav_dims(0)) {
506 return SWIG_ValueError;
507 }
508 }
509 else if (objdims != sloav_dims) {
510 return SWIG_ValueError;
511 }
512
513 // Iterate over all elements in the C array.
514 Array<octave_idx_type> idx(dim_vector(1, sloav_ndims), 0);
515 std::list<octave_value_list> objidx(1);
516 for (int i = 0; i < objdims.numel(); ++i) {
517
518 // Get the scalar index of the Octave array element, and the element itself.
519 objidx.front()(0) = get_scalar_idx(idx, objdims) + 1;
520 octave_value objelem = obj.subsref(obj.is_cell() ? "{" : "(", objidx);
521
522 // Copy the Octave array element to the C array.
523 int res = HELPER::incall(sloav_parent, objelem, sloav_get_element_ptr(idx), pelemalloc, sloav_esize, sloav_isptr, sloav_tinfo, sloav_tflags | tflags);
524 if (!SWIG_IsOK(res)) {
525 return res;
526 }
527
528 // Increment the Octave array index.
529 sloav_increment_idx(idx);
530
531 }
532
533 return SWIG_OK;
534
535 }
536
537 // Copy the C array to the returned Octave array.
538 octave_value sloav_array_out(const bool copyobj = false) const {
539
540 // Check that C array pointer is valid.
541 if (!sloav_ptr) {
542 return octave_value();
543 }
544
545 // Create a new Octave array.
546 dim_vector objdims = sloav_dims;
547 typename HELPER::OVType objval(objdims);
548 octave_value obj(objval);
549
550 // Iterate over all elements in the C array.
551 Array<octave_idx_type> idx(dim_vector(1, sloav_ndims), 0);
552 std::list<octave_value_list> objidx(1);
553 for (int i = 0; i < objdims.numel(); ++i) {
554
555 // Get the scalar index of the Octave array element.
556 objidx.front()(0) = get_scalar_idx(idx, objdims) + 1;
557
558 // Copy the C array element to the Octave array.
559 octave_value objelem = HELPER::outcall(sloav_parent, copyobj, sloav_get_element_ptr(idx), sloav_esize, sloav_isptr, sloav_tinfo, sloav_tflags);
560 obj = obj.subsasgn(obj.is_cell() ? "{" : "(", objidx, objelem);
561
562 // Increment the Octave array index.
563 sloav_increment_idx(idx);
564
565 }
566
567 return obj;
568
569 }
570
571 // The following methods override virtual methods in octave_base_value.
572
573 // Array dimensions.
574 dim_vector dims() const {
575 return sloav_dims;
576 }
577
578 // Return an Octave array.
579 octave_value full_value() const {
580 return sloav_array_out();
581 }
582
583 // Return an empty Octave array.
584 octave_base_value* empty_clone() const {
585 return sloav_array_out().empty_clone();
586 }
587
588 // Return the numeric conversion function.
589 octave_base_value::type_conv_info numeric_conversion_function() const {
590 return octave_base_value::type_conv_info(sloav_numeric_conversion_function, sloav_class.type_id());
591 }
592
593 // Do indexing without resizing.
594 octave_value do_index_op(const octave_value_list& idx, bool resize_ok) {
595 return sloav_array_out().do_index_op(idx, false);
596 }
597 octave_value_list do_multi_index_op(int nargout, const octave_value_list& idx) {
598 return sloav_array_out().do_multi_index_op(nargout, idx);
599 }
600
601 // Do subscripting on Octave array.
602 octave_value subsref(const std::string& type, const std::list<octave_value_list>& idx) {
603 return sloav_array_out().subsref(type, idx);
604 }
605 octave_value_list subsref(const std::string& type, const std::list<octave_value_list>& idx, int nargout) {
606 return sloav_array_out().subsref(type, idx, nargout);
607 }
608
609 // Do subscript assignment, and copy result back to C array.
610 octave_value subsasgn(const std::string& type, const std::list<octave_value_list>& idx, const octave_value& rhs) {
611 octave_value obj = sloav_array_out().subsasgn(type, idx, rhs);
612 int elemalloc = 0;
613 // When assigning Octave objects to a C array of pointers, assume the struct
614 // who owns the C array takes ownership of the memory of the C array element.
615 // The Octave object wrapping the C array element should therefore disown the
616 // underlying memory.
617 // When assigning Octave objects to a C array of data blocks, however, the C
618 // array just struct-copies the object rather than taking ownership of its
619 // pointer, and so the Octave object should not be disowned so that it can
620 // be garbage-collected later.
621 int res = sloav_array_in(obj, &elemalloc, sloav_isptr ? SWIG_POINTER_DISOWN : 0);
622 if (!SWIG_IsOK(res)) {
623 std::string n = type_name();
624 std::string e = SWIG_ErrorType(res).string_value();
625 error("failed to perform indexed assignment for %s type: %s", n.c_str(), e.c_str());
626 return octave_value();
627 }
628 count++;
629 return octave_value(this);
630 }
631
632 // Save and load from ASCII.
633 bool save_ascii (std::ostream& os) {
634 return sloav_array_out().save_ascii(os);
635 }
636 bool load_ascii(std::istream& is) {
637 octave_value obj = sloav_array_out();
638 int elemalloc = 0;
639 return obj.load_ascii(is) && SWIG_IsOK(sloav_array_in(obj, &elemalloc, 0));
640 }
641
642 // Save and load from binary.
643 bool save_binary(std::ostream& os, bool& save_as_floats) {
644 return sloav_array_out().save_binary(os, save_as_floats);
645 }
646 bool load_binary(std::istream& is, bool swap, oct_mach_info::float_format fmt) {
647 octave_value obj = sloav_array_out();
648 int elemalloc = 0;
649 return obj.load_binary(is, swap, fmt) && SWIG_IsOK(sloav_array_in(obj, &elemalloc, 0));
650 }
651
652 // Save and load from HDF5.
653%#ifdef HAVE_HDF5
654%#if SWIG_OCTAVE_PREREQ(4,0,0)
655 bool save_hdf5(octave_hdf5_id loc_id, const char *name, bool save_as_floats) {
656 return sloav_array_out().save_hdf5(loc_id, name, save_as_floats);
657 }
658%#else
659 bool save_hdf5(hid_t loc_id, const char *name, bool save_as_floats) {
660 return sloav_array_out().save_hdf5(loc_id, name, save_as_floats);
661 }
662%#endif
663%#if SWIG_OCTAVE_PREREQ(4,0,0)
664 bool load_hdf5(octave_hdf5_id loc_id, const char *name) {
665 octave_value obj = sloav_array_out();
666 int elemalloc = 0;
667 return obj.load_hdf5(loc_id, name) && SWIG_IsOK(sloav_array_in(obj, &elemalloc, 0));
668 }
669%#elif SWIG_OCTAVE_PREREQ(3,3,52)
670 bool load_hdf5(hid_t loc_id, const char *name) {
671 octave_value obj = sloav_array_out();
672 int elemalloc = 0;
673 return obj.load_hdf5(loc_id, name) && SWIG_IsOK(sloav_array_in(obj, &elemalloc, 0));
674 }
675%#else
676 bool load_hdf5(hid_t loc_id, const char *name, bool have_h5giterate_bug) {
677 octave_value obj = sloav_array_out();
678 int elemalloc = 0;
679 return obj.load_hdf5(loc_id, name, have_h5giterate_bug) && SWIG_IsOK(sloav_array_in(obj, &elemalloc, 0));
680 }
681%#endif
682%#endif
683
684 // Print array.
685%#if SWIG_OCTAVE_PREREQ(4,0,0)
686 void print(std::ostream &os, bool pr_as_read_syntax = false)
687%#else
688 void print(std::ostream &os, bool pr_as_read_syntax = false) const
689%#endif
690 {
691 return sloav_array_out().print(os, pr_as_read_syntax);
692 }
693
694 // The following methods override virtual const-methods in octave_base_value. These methods
695 // are mapped to the equivalent method of the octave_base_value-derived class of the array
696 // view class.
697
698#define SLOAV_OBV_METH_FROM_CLASS_0(N, R) R N() const { return sloav_class.N(); }
699 SLOAV_OBV_METH_FROM_CLASS_0(is_all_va_args, bool);
700 SLOAV_OBV_METH_FROM_CLASS_0(is_bool_matrix, bool);
701 SLOAV_OBV_METH_FROM_CLASS_0(is_bool_scalar, bool);
702 SLOAV_OBV_METH_FROM_CLASS_0(is_bool_type, bool);
703 SLOAV_OBV_METH_FROM_CLASS_0(is_builtin_function, bool);
704%#if SWIG_OCTAVE_PREREQ(4,4,0)
705 SLOAV_OBV_METH_FROM_CLASS_0(iscell, bool);
706 SLOAV_OBV_METH_FROM_CLASS_0(iscellstr, bool);
707%#else
708 SLOAV_OBV_METH_FROM_CLASS_0(is_cell, bool);
709 SLOAV_OBV_METH_FROM_CLASS_0(is_cellstr, bool);
710%#endif
711 SLOAV_OBV_METH_FROM_CLASS_0(is_char_matrix, bool);
712 SLOAV_OBV_METH_FROM_CLASS_0(is_classdef_meta, bool);
713 SLOAV_OBV_METH_FROM_CLASS_0(is_classdef_object, bool);
714 SLOAV_OBV_METH_FROM_CLASS_0(is_classdef_superclass_ref, bool);
715 SLOAV_OBV_METH_FROM_CLASS_0(is_complex_matrix, bool);
716 SLOAV_OBV_METH_FROM_CLASS_0(is_complex_scalar, bool);
717 SLOAV_OBV_METH_FROM_CLASS_0(is_complex_type, bool);
718 SLOAV_OBV_METH_FROM_CLASS_0(is_constant, bool);
719 SLOAV_OBV_METH_FROM_CLASS_0(is_cs_list, bool);
720 SLOAV_OBV_METH_FROM_CLASS_0(is_defined, bool);
721 SLOAV_OBV_METH_FROM_CLASS_0(is_diag_matrix, bool);
722 SLOAV_OBV_METH_FROM_CLASS_0(is_dld_function, bool);
723 SLOAV_OBV_METH_FROM_CLASS_0(is_double_type, bool);
724 SLOAV_OBV_METH_FROM_CLASS_0(is_float_type, bool);
725 SLOAV_OBV_METH_FROM_CLASS_0(is_function, bool);
726 SLOAV_OBV_METH_FROM_CLASS_0(is_function_handle, bool);
727 SLOAV_OBV_METH_FROM_CLASS_0(is_inline_function, bool);
728 SLOAV_OBV_METH_FROM_CLASS_0(is_int16_type, bool);
729 SLOAV_OBV_METH_FROM_CLASS_0(is_int32_type, bool);
730 SLOAV_OBV_METH_FROM_CLASS_0(is_int64_type, bool);
731 SLOAV_OBV_METH_FROM_CLASS_0(is_int8_type, bool);
732 SLOAV_OBV_METH_FROM_CLASS_0(is_integer_type, bool);
733 SLOAV_OBV_METH_FROM_CLASS_0(is_list, bool);
734 SLOAV_OBV_METH_FROM_CLASS_0(is_magic_colon, bool);
735 SLOAV_OBV_METH_FROM_CLASS_0(is_map, bool);
736 SLOAV_OBV_METH_FROM_CLASS_0(is_matrix_type, bool);
737 SLOAV_OBV_METH_FROM_CLASS_0(is_mex_function, bool);
738 SLOAV_OBV_METH_FROM_CLASS_0(is_null_value, bool);
739 SLOAV_OBV_METH_FROM_CLASS_0(is_numeric_type, bool);
740 SLOAV_OBV_METH_FROM_CLASS_0(is_object, bool);
741 SLOAV_OBV_METH_FROM_CLASS_0(is_perm_matrix, bool);
742 SLOAV_OBV_METH_FROM_CLASS_0(is_range, bool);
743 SLOAV_OBV_METH_FROM_CLASS_0(is_real_matrix, bool);
744 SLOAV_OBV_METH_FROM_CLASS_0(is_real_nd_array, bool);
745 SLOAV_OBV_METH_FROM_CLASS_0(is_real_scalar, bool);
746 SLOAV_OBV_METH_FROM_CLASS_0(is_real_type, bool);
747 SLOAV_OBV_METH_FROM_CLASS_0(is_scalar_type, bool);
748 SLOAV_OBV_METH_FROM_CLASS_0(is_single_type, bool);
749 SLOAV_OBV_METH_FROM_CLASS_0(is_sparse_type, bool);
750 SLOAV_OBV_METH_FROM_CLASS_0(is_sq_string, bool);
751 SLOAV_OBV_METH_FROM_CLASS_0(is_string, bool);
752 SLOAV_OBV_METH_FROM_CLASS_0(is_true, bool);
753 SLOAV_OBV_METH_FROM_CLASS_0(is_uint16_type, bool);
754 SLOAV_OBV_METH_FROM_CLASS_0(is_uint32_type, bool);
755 SLOAV_OBV_METH_FROM_CLASS_0(is_uint64_type, bool);
756 SLOAV_OBV_METH_FROM_CLASS_0(is_uint8_type, bool);
757 SLOAV_OBV_METH_FROM_CLASS_0(is_user_code, bool);
758 SLOAV_OBV_METH_FROM_CLASS_0(is_user_function, bool);
759 SLOAV_OBV_METH_FROM_CLASS_0(is_user_script, bool);
760 SLOAV_OBV_METH_FROM_CLASS_0(isjava, bool);
761 SLOAV_OBV_METH_FROM_CLASS_0(isobject, bool);
762 SLOAV_OBV_METH_FROM_CLASS_0(isstruct, bool);
763#undef SLOAV_OBV_METH_FROM_CLASS_0
764
765 // The following methods override virtual const-methods in octave_base_value. These methods
766 // are mapped to the equivalent method of the Octave array.
767
768#define SLOAV_OBV_METH_FROM_ARRAY_0(N, R) R N() const { return sloav_array_out().N(); }
769#define SLOAV_OBV_METH_FROM_ARRAY_1(N, R, A) R N(A a) const { return sloav_array_out().N(a); }
770#define SLOAV_OBV_METH_FROM_ARRAY_2(N, R, A, B) R N(A a, B b) const { return sloav_array_out().N(a, b); }
771#define SLOAV_OBV_METH_FROM_ARRAY_3(N, R, A, B, C) R N(A a, B b, C c) const { return sloav_array_out().N(a, b, c); }
772#define SLOAV_OBV_METH_FROM_ARRAY_4(N, R, A, B, C, D) R N(A a, B b, C c, D d) const { return sloav_array_out().N(a, b, c, d); }
773#define SLOAV_OBV_METH_FROM_ARRAY_5(N, R, A, B, C, D, E) R N(A a, B b, C c, D d, E e) const { return sloav_array_out().N(a, b, c, d, e); }
774%#if SWIG_OCTAVE_PREREQ(4,2,0)
775 SLOAV_OBV_METH_FROM_ARRAY_0(as_double, octave_value);
776 SLOAV_OBV_METH_FROM_ARRAY_0(as_single, octave_value);
777%#endif
778%#if SWIG_OCTAVE_PREREQ(3,3,52)
779 SLOAV_OBV_METH_FROM_ARRAY_0(map_value, octave_map);
780%#else
781 SLOAV_OBV_METH_FROM_ARRAY_0(map_value, Octave_map);
782%#endif
783 SLOAV_OBV_METH_FROM_ARRAY_0(abs, octave_value);
784 SLOAV_OBV_METH_FROM_ARRAY_0(acos, octave_value);
785 SLOAV_OBV_METH_FROM_ARRAY_0(acosh, octave_value);
786 SLOAV_OBV_METH_FROM_ARRAY_0(angle, octave_value);
787 SLOAV_OBV_METH_FROM_ARRAY_0(arg, octave_value);
788 SLOAV_OBV_METH_FROM_ARRAY_0(asin, octave_value);
789 SLOAV_OBV_METH_FROM_ARRAY_0(asinh, octave_value);
790 SLOAV_OBV_METH_FROM_ARRAY_0(atan, octave_value);
791 SLOAV_OBV_METH_FROM_ARRAY_0(atanh, octave_value);
792 SLOAV_OBV_METH_FROM_ARRAY_0(byte_size, size_t);
793 SLOAV_OBV_METH_FROM_ARRAY_0(ceil, octave_value);
794 SLOAV_OBV_METH_FROM_ARRAY_0(cell_value, Cell);
795 SLOAV_OBV_METH_FROM_ARRAY_0(cellstr_value, Array<std::string>);
796 SLOAV_OBV_METH_FROM_ARRAY_0(conj, octave_value);
797 SLOAV_OBV_METH_FROM_ARRAY_0(cos, octave_value);
798 SLOAV_OBV_METH_FROM_ARRAY_0(cosh, octave_value);
799 SLOAV_OBV_METH_FROM_ARRAY_0(erf, octave_value);
800 SLOAV_OBV_METH_FROM_ARRAY_0(erfc, octave_value);
801 SLOAV_OBV_METH_FROM_ARRAY_0(exp, octave_value);
802 SLOAV_OBV_METH_FROM_ARRAY_0(expm1, octave_value);
803 SLOAV_OBV_METH_FROM_ARRAY_0(finite, octave_value);
804 SLOAV_OBV_METH_FROM_ARRAY_0(fix, octave_value);
805 SLOAV_OBV_METH_FROM_ARRAY_0(floor, octave_value);
806 SLOAV_OBV_METH_FROM_ARRAY_0(gamma, octave_value);
807 SLOAV_OBV_METH_FROM_ARRAY_0(imag, octave_value);
808 SLOAV_OBV_METH_FROM_ARRAY_0(index_vector, idx_vector);
809 SLOAV_OBV_METH_FROM_ARRAY_0(int16_array_value, int16NDArray);
810 SLOAV_OBV_METH_FROM_ARRAY_0(int16_scalar_value, octave_int16);
811 SLOAV_OBV_METH_FROM_ARRAY_0(int32_array_value, int32NDArray);
812 SLOAV_OBV_METH_FROM_ARRAY_0(int32_scalar_value, octave_int32);
813 SLOAV_OBV_METH_FROM_ARRAY_0(int64_array_value, int64NDArray);
814 SLOAV_OBV_METH_FROM_ARRAY_0(int64_scalar_value, octave_int64);
815 SLOAV_OBV_METH_FROM_ARRAY_0(int8_array_value, int8NDArray);
816 SLOAV_OBV_METH_FROM_ARRAY_0(int8_scalar_value, octave_int8);
817 SLOAV_OBV_METH_FROM_ARRAY_0(isinf, octave_value);
818 SLOAV_OBV_METH_FROM_ARRAY_0(isna, octave_value);
819 SLOAV_OBV_METH_FROM_ARRAY_0(isnan, octave_value);
820 SLOAV_OBV_METH_FROM_ARRAY_0(lgamma, octave_value);
821 SLOAV_OBV_METH_FROM_ARRAY_0(log, octave_value);
822 SLOAV_OBV_METH_FROM_ARRAY_0(log10, octave_value);
823 SLOAV_OBV_METH_FROM_ARRAY_0(log1p, octave_value);
824 SLOAV_OBV_METH_FROM_ARRAY_0(log2, octave_value);
825 SLOAV_OBV_METH_FROM_ARRAY_0(matrix_type, MatrixType);
826 SLOAV_OBV_METH_FROM_ARRAY_0(nnz, octave_idx_type);
827 SLOAV_OBV_METH_FROM_ARRAY_0(nzmax, octave_idx_type);
828 SLOAV_OBV_METH_FROM_ARRAY_0(perm_matrix_value, PermMatrix);
829 SLOAV_OBV_METH_FROM_ARRAY_0(range_value, Range);
830 SLOAV_OBV_METH_FROM_ARRAY_0(real, octave_value);
831 SLOAV_OBV_METH_FROM_ARRAY_0(round, octave_value);
832 SLOAV_OBV_METH_FROM_ARRAY_0(roundb, octave_value);
833 SLOAV_OBV_METH_FROM_ARRAY_0(signum, octave_value);
834 SLOAV_OBV_METH_FROM_ARRAY_0(sin, octave_value);
835 SLOAV_OBV_METH_FROM_ARRAY_0(sinh, octave_value);
836 SLOAV_OBV_METH_FROM_ARRAY_0(sqrt, octave_value);
837 SLOAV_OBV_METH_FROM_ARRAY_0(tan, octave_value);
838 SLOAV_OBV_METH_FROM_ARRAY_0(tanh, octave_value);
839 SLOAV_OBV_METH_FROM_ARRAY_0(uint16_array_value, uint16NDArray);
840 SLOAV_OBV_METH_FROM_ARRAY_0(uint16_scalar_value, octave_uint16);
841 SLOAV_OBV_METH_FROM_ARRAY_0(uint32_array_value, uint32NDArray);
842 SLOAV_OBV_METH_FROM_ARRAY_0(uint32_scalar_value, octave_uint32);
843 SLOAV_OBV_METH_FROM_ARRAY_0(uint64_array_value, uint64NDArray);
844 SLOAV_OBV_METH_FROM_ARRAY_0(uint64_scalar_value, octave_uint64);
845 SLOAV_OBV_METH_FROM_ARRAY_0(uint8_array_value, uint8NDArray);
846 SLOAV_OBV_METH_FROM_ARRAY_0(uint8_scalar_value, octave_uint8);
847 SLOAV_OBV_METH_FROM_ARRAY_0(xisalnum, octave_value);
848 SLOAV_OBV_METH_FROM_ARRAY_0(xisalpha, octave_value);
849 SLOAV_OBV_METH_FROM_ARRAY_0(xisascii, octave_value);
850 SLOAV_OBV_METH_FROM_ARRAY_0(xiscntrl, octave_value);
851 SLOAV_OBV_METH_FROM_ARRAY_0(xisdigit, octave_value);
852 SLOAV_OBV_METH_FROM_ARRAY_0(xisgraph, octave_value);
853 SLOAV_OBV_METH_FROM_ARRAY_0(xislower, octave_value);
854 SLOAV_OBV_METH_FROM_ARRAY_0(xisprint, octave_value);
855 SLOAV_OBV_METH_FROM_ARRAY_0(xispunct, octave_value);
856 SLOAV_OBV_METH_FROM_ARRAY_0(xisspace, octave_value);
857 SLOAV_OBV_METH_FROM_ARRAY_0(xisupper, octave_value);
858 SLOAV_OBV_METH_FROM_ARRAY_0(xisxdigit, octave_value);
859 SLOAV_OBV_METH_FROM_ARRAY_0(xtoascii, octave_value);
860 SLOAV_OBV_METH_FROM_ARRAY_0(xtolower, octave_value);
861 SLOAV_OBV_METH_FROM_ARRAY_0(xtoupper, octave_value);
862 SLOAV_OBV_METH_FROM_ARRAY_1(all, octave_value, int);
863 SLOAV_OBV_METH_FROM_ARRAY_1(all_strings, string_vector, bool);
864 SLOAV_OBV_METH_FROM_ARRAY_1(any, octave_value, int);
865 SLOAV_OBV_METH_FROM_ARRAY_1(array_value, NDArray, bool);
866 SLOAV_OBV_METH_FROM_ARRAY_1(bool_array_value, boolNDArray, bool);
867 SLOAV_OBV_METH_FROM_ARRAY_1(bool_matrix_value, boolMatrix, bool);
868 SLOAV_OBV_METH_FROM_ARRAY_1(bool_value, bool, bool);
869 SLOAV_OBV_METH_FROM_ARRAY_1(char_array_value, charNDArray, bool);
870 SLOAV_OBV_METH_FROM_ARRAY_1(char_matrix_value, charMatrix, bool);
871 SLOAV_OBV_METH_FROM_ARRAY_1(complex_array_value, ComplexNDArray, bool);
872 SLOAV_OBV_METH_FROM_ARRAY_1(complex_diag_matrix_value, ComplexDiagMatrix, bool);
873 SLOAV_OBV_METH_FROM_ARRAY_1(complex_matrix_value, ComplexMatrix, bool);
874 SLOAV_OBV_METH_FROM_ARRAY_1(complex_value, Complex, bool);
875 SLOAV_OBV_METH_FROM_ARRAY_1(diag, octave_value, octave_idx_type);
876 SLOAV_OBV_METH_FROM_ARRAY_1(diag_matrix_value, DiagMatrix, bool);
877 SLOAV_OBV_METH_FROM_ARRAY_1(double_value, double, bool);
878 SLOAV_OBV_METH_FROM_ARRAY_1(float_array_value, FloatNDArray, bool);
879 SLOAV_OBV_METH_FROM_ARRAY_1(float_complex_array_value, FloatComplexNDArray, bool);
880 SLOAV_OBV_METH_FROM_ARRAY_1(float_complex_diag_matrix_value, FloatComplexDiagMatrix, bool);
881 SLOAV_OBV_METH_FROM_ARRAY_1(float_complex_matrix_value, FloatComplexMatrix, bool);
882 SLOAV_OBV_METH_FROM_ARRAY_1(float_complex_value, FloatComplex, bool);
883 SLOAV_OBV_METH_FROM_ARRAY_1(float_diag_matrix_value, FloatDiagMatrix, bool);
884 SLOAV_OBV_METH_FROM_ARRAY_1(float_matrix_value, FloatMatrix, bool);
885 SLOAV_OBV_METH_FROM_ARRAY_1(float_value, float, bool);
886 SLOAV_OBV_METH_FROM_ARRAY_1(is_sorted, sortmode, sortmode);
887 SLOAV_OBV_METH_FROM_ARRAY_1(is_sorted_rows, sortmode, sortmode);
888 SLOAV_OBV_METH_FROM_ARRAY_1(matrix_value, Matrix, bool);
889 SLOAV_OBV_METH_FROM_ARRAY_1(reshape, octave_value, const dim_vector&);
890 SLOAV_OBV_METH_FROM_ARRAY_1(sort_rows_ids, Array<octave_idx_type>, sortmode);
891 SLOAV_OBV_METH_FROM_ARRAY_1(sparse_bool_matrix_value, SparseBoolMatrix, bool);
892 SLOAV_OBV_METH_FROM_ARRAY_1(sparse_complex_matrix_value, SparseComplexMatrix, bool);
893 SLOAV_OBV_METH_FROM_ARRAY_1(sparse_matrix_value, SparseMatrix, bool);
894 SLOAV_OBV_METH_FROM_ARRAY_1(string_value, std::string, bool);
895 SLOAV_OBV_METH_FROM_ARRAY_2(int_value, int, bool, bool);
896 SLOAV_OBV_METH_FROM_ARRAY_2(long_value, long int, bool, bool);
897 SLOAV_OBV_METH_FROM_ARRAY_2(permute, octave_value, const Array<int>&, bool);
898 SLOAV_OBV_METH_FROM_ARRAY_2(print_info, void, std::ostream&, bool);
899 SLOAV_OBV_METH_FROM_ARRAY_2(print_raw, void, std::ostream&, bool);
900 SLOAV_OBV_METH_FROM_ARRAY_2(resize, octave_value, const dim_vector&, bool);
901 SLOAV_OBV_METH_FROM_ARRAY_2(short_value, short int, bool, bool);
902 SLOAV_OBV_METH_FROM_ARRAY_2(sort, octave_value, octave_idx_type, sortmode);
903 SLOAV_OBV_METH_FROM_ARRAY_2(uint_value, unsigned int, bool, bool);
904 SLOAV_OBV_METH_FROM_ARRAY_2(ulong_value, unsigned long int, bool, bool);
905 SLOAV_OBV_METH_FROM_ARRAY_2(ushort_value, unsigned short int, bool, bool);
906 SLOAV_OBV_METH_FROM_ARRAY_3(convert_to_str_internal, octave_value, bool, bool, char);
907 SLOAV_OBV_METH_FROM_ARRAY_3(sort, octave_value, Array<octave_idx_type>&, octave_idx_type, sortmode);
908 SLOAV_OBV_METH_FROM_ARRAY_5(write, int, octave_stream&, int, oct_data_conv::data_type, int, oct_mach_info::float_format);
909#undef SLOAV_OBV_METH_FROM_ARRAY_0
910#undef SLOAV_OBV_METH_FROM_ARRAY_1
911#undef SLOAV_OBV_METH_FROM_ARRAY_2
912#undef SLOAV_OBV_METH_FROM_ARRAY_3
913#undef SLOAV_OBV_METH_FROM_ARRAY_4
914#undef SLOAV_OBV_METH_FROM_ARRAY_5
915
916 }; // class swiglal_oct_array_view
917
918 } // extern "C++"
919
920} // fragment swiglal_oct_array_view
921
922// Macro which generates fragments which define ACFTYPE-specific array view classes and conversion
923// functions:
924// - IN/OUTFRAG are names of fragments required by the in/out conversion functions IN/OUTCALL.
925// - OVCLASS is the octave_base_value-derived class of the array view class.
926// - OVTYPE is the type of octave_value array value.
927// - OVVALUE() is the method of octave_value which returns an OVTYPE.
928// - ISOVTYPEEXPR returns true if the octave_value 'obj' is of type OVTYPE.
929%define %swiglal_oct_array_frags(ACFTYPE, INFRAG, OUTFRAG, INCALL, OUTCALL, OVCLASS, OVTYPE, OVVALUE, ISOVTYPEEXPR)
930
931// Register the ACFTYPE-specific array view class as an Octave type.
932%fragment(%swiglal_oct_array_view_init_frag(ACFTYPE), "init") %{
933#if SWIG_OCTAVE_PREREQ(4,4,0)
934 {
935 octave::type_info& typeinfo = octave::interpreter::the_interpreter()->get_type_info();
936 string_vector types = typeinfo.installed_type_names();
937 bool register_octave_array_view_class = true;
938 bool register_octave_swig_packed = true;
939 for (int i = 0; i < types.numel(); ++i) {
940 if (types(i) == %swiglal_oct_array_view_class(ACFTYPE)::static_type_name()) {
941 register_octave_array_view_class = false;
942 }
943 }
944 if (register_octave_array_view_class) {
945 %swiglal_oct_array_view_class(ACFTYPE)::register_type();
946 }
947 }
948#else
949 %swiglal_oct_array_view_class(ACFTYPE)::register_type();
950#endif
951%}
952
953// ACFTYPE-specific array view class fragment.
954%fragment(%swiglal_oct_array_view_frag(ACFTYPE), "header",
955 fragment=%swiglal_oct_array_view_init_frag(ACFTYPE),
956 fragment="swiglal_oct_array_view", fragment=INFRAG, fragment=OUTFRAG)
957%{
958
959 extern "C++" {
960
961 // Helper class which supplies ACFTYPE-specific types and functions to the base template
962 // swiglal_oct_array_view<>.
963 class %swiglal_oct_array_view_helper_class(ACFTYPE) {
964
965 public:
966
967 // Octave array-related types.
968 typedef OVCLASS OVClass;
969 typedef OVTYPE OVType;
970
971 // Extract an OVType from an octave_value.
972 static OVType ovvalue(octave_value& ov) {
973 return ov.OVVALUE();
974 }
975
976 // Convert the octave_value objelem to an array element stored at elemptr.
977 static int incall(const octave_value& parent, octave_value& objelem, void *elemptr, int *pelemalloc, const size_t esize, const bool isptr, swig_type_info *const tinfo, const int tflags)
978 {
979 return INCALL;
980 }
981
982 // Convert the array element stored at elemptr to an octave_value.
983 static octave_value outcall(const octave_value& parent, const bool copyobj, void *elemptr, const size_t esize, const bool isptr, swig_type_info *const tinfo, const int tflags) {
984 return OUTCALL;
985 }
986
987 };
988
989 // ACFTYPE-specific array view class fragment.
990 class OCTINTERP_API %swiglal_oct_array_view_class(ACFTYPE) : public %swiglal_oct_array_view_tmpl(ACFTYPE) {
991
992 private:
993
994 // Octave type constructs.
995#if !SWIG_OCTAVE_PREREQ(4,0,0)
996 DECLARE_OCTAVE_ALLOCATOR;
997#endif
998 DECLARE_OV_TYPEID_FUNCTIONS_AND_DATA;
999
1000 protected:
1001
1002 public:
1003
1004 virtual ~%swiglal_oct_array_view_class(ACFTYPE)()
1005 { }
1006
1007 %swiglal_oct_array_view_class(ACFTYPE)()
1008 : %swiglal_oct_array_view_tmpl(ACFTYPE)()
1009 { }
1010
1011 %swiglal_oct_array_view_class(ACFTYPE)(const octave_value& parent,
1012 void* ptr,
1013 const size_t esize,
1014 const size_t ndims,
1015 const size_t dims[],
1016 const size_t strides[],
1017 const bool isptr,
1018 swig_type_info* tinfo,
1019 const int tflags)
1020 : %swiglal_oct_array_view_tmpl(ACFTYPE)(parent, ptr, esize, ndims, dims, strides, isptr, tinfo, tflags)
1021 { }
1022
1023 };
1024
1025 // Octave type constructs.
1026#if !SWIG_OCTAVE_PREREQ(4,0,0)
1027 DEFINE_OCTAVE_ALLOCATOR(%swiglal_oct_array_view_class(ACFTYPE));
1028#endif
1029 DEFINE_OV_TYPEID_FUNCTIONS_AND_DATA(%swiglal_oct_array_view_class(ACFTYPE),
1030 %swiglal_oct_array_view_ovtype(ACFTYPE),
1031 OVCLASS::static_class_name());
1032
1033 } // extern "C++"
1034
1035%} // %swiglal_oct_array_view_frag()
1036
1037// Input copy conversion fragment for arrays of type ACFTYPE.
1038%fragment(%swiglal_array_copyin_frag(ACFTYPE), "header",
1039 fragment=%swiglal_oct_array_view_frag(ACFTYPE))
1040%{
1041 SWIGINTERN int %swiglal_array_copyin_func(ACFTYPE)(const octave_value& parent,
1042 octave_value obj,
1043 void* ptr,
1044 int *pelemalloc,
1045 const size_t esize,
1046 const size_t ndims,
1047 const size_t dims[],
1048 const size_t strides[],
1049 const bool isptr,
1050 swig_type_info *tinfo,
1051 const int tflags)
1052 {
1053 // Create a local array view, then use its sloav_array_in() member to copy the input Octave
1054 // array to the viewed C array.
1055 %swiglal_oct_array_view_class(ACFTYPE) arrview(parent, ptr, esize, ndims, dims, strides, isptr, tinfo, tflags);
1056 return arrview.sloav_array_in(obj, pelemalloc, 0);
1057 }
1058%}
1059
1060// Output copy conversion fragment for arrays of type ACFTYPE.
1061%fragment(%swiglal_array_copyout_frag(ACFTYPE), "header",
1062 fragment=%swiglal_oct_array_view_frag(ACFTYPE))
1063%{
1064 SWIGINTERN octave_value %swiglal_array_copyout_func(ACFTYPE)(const octave_value& parent,
1065 void* ptr,
1066 const size_t esize,
1067 const size_t ndims,
1068 const size_t dims[],
1069 const size_t strides[],
1070 const bool isptr,
1071 swig_type_info *tinfo,
1072 const int tflags)
1073 {
1074 // Create a local array view, then use its sloav_array_out() member to copy the viewed C array
1075 // to the output Octave array.
1076 %swiglal_oct_array_view_class(ACFTYPE) arrview(parent, ptr, esize, ndims, dims, strides, isptr, tinfo, tflags);
1077 return arrview.sloav_array_out(true);
1078 }
1079%}
1080
1081// Input view conversion fragment for arrays of type ACFTYPE.
1082%fragment(%swiglal_array_viewin_frag(ACFTYPE), "header",
1083 fragment=%swiglal_oct_array_view_frag(ACFTYPE))
1084%{
1085 SWIGINTERN int %swiglal_array_viewin_func(ACFTYPE)(const octave_value& parent,
1086 octave_value obj,
1087 void** ptr,
1088 const size_t esize,
1089 const size_t ndims,
1090 size_t dims[],
1091 const bool isptr,
1092 swig_type_info *tinfo,
1093 const int tflags)
1094 {
1095
1096 // Check that C array pointer is valid.
1097 if (ptr == NULL) {
1098 return SWIG_MemoryError;
1099 }
1100
1101 // Convert 'obj' to the desired OVTYPE, store in 'val'.
1102 OVTYPE val = obj.OVVALUE();
1103
1104 // Check that 'val' has the correct number of dimensions.
1105 // - 1-D arrays are a special case, since Octave arrays are always at least
1106 // 2-dimensional, so need to check that one of those dimensions is singular.
1107 dim_vector valdims = val.dims();
1108 if (ndims == 1) {
1109 if (valdims.length() > 2 || valdims.num_ones() == 0) {
1110 return SWIG_ValueError;
1111 }
1112 }
1113 else if (val.ndims() != %reinterpret_cast(ndims, octave_idx_type)) {
1114 return SWIG_ValueError;
1115 }
1116
1117 // Return dimensions of Octave array.
1118 if (ndims == 1) {
1119 dims[0] = val.numel();
1120 } else {
1121 for (size_t i = 0; i < ndims; ++i) {
1122 dims[i] = valdims(i);
1123 }
1124 }
1125
1126 // Cannot view an array of pointers.
1127 if (isptr) {
1128 return SWIG_TypeError;
1129 }
1130
1131 // Cannot view an array which is not itself an Octave view of a C array.
1132 if (obj.type_name().find("swiglal_oct_array_view_") == 0) {
1133 return SWIG_TypeError;
1134 }
1135
1136 // Since Octave stores arrays in column-major order, we can only view 1-D arrays.
1137 if (ndims != 1) {
1138 return SWIG_ValueError;
1139 }
1140
1141 // Check that 'obj' is of the correct type.
1142 if (!(ISOVTYPEEXPR)) {
1143 return SWIG_TypeError;
1144 }
1145
1146 // Check that the elements of 'val' have the correct size.
1147 if (val.byte_size() != val.numel() * esize) {
1148 return SWIG_TypeError;
1149 }
1150
1151 // Get pointer to Octave array data, a highly complicated and dodgy process! Usually
1152 // mex_get_data() does the job, apart from complex arrays where that creates a copy ...
1153 // in which case try data() and try to detect copying ...
1154 if (obj.is_complex_type() && !obj.is_scalar_type()) {
1155 if (obj.is_double_type()) {
1156 Complex c;
1157 {
1158 const ComplexNDArray t = obj.complex_array_value();
1159 *ptr = %reinterpret_cast(t.data(), void*);
1160 c = *((Complex*) *ptr);
1161 }
1162 if (c != *((Complex*) *ptr)) {
1163 return SWIG_UnknownError;
1164 }
1165 } else if (obj.is_single_type()) {
1166 FloatComplex c;
1167 {
1168 const FloatComplexNDArray t = obj.float_complex_array_value();
1169 *ptr = %reinterpret_cast(t.data(), void*);
1170 c = *((FloatComplex*) *ptr);
1171 }
1172 if (c != *((FloatComplex*) *ptr)) {
1173 return SWIG_UnknownError;
1174 }
1175 } else {
1176 return SWIG_TypeError;
1177 }
1178 } else {
1179 *ptr = %reinterpret_cast(obj.mex_get_data(), void*);
1180 }
1181 if (!*ptr) {
1182 return SWIG_ValueError;
1183 }
1184
1185 return SWIG_OK;
1186
1187 }
1188%}
1189
1190// Output view conversion fragment for arrays of type ACFTYPE.
1191%fragment(%swiglal_array_viewout_frag(ACFTYPE), "header",
1192 fragment=%swiglal_oct_array_view_frag(ACFTYPE))
1193%{
1194 SWIGINTERN octave_value %swiglal_array_viewout_func(ACFTYPE)(const octave_value& parent,
1195 void* ptr,
1196 const size_t esize,
1197 const size_t ndims,
1198 const size_t dims[],
1199 const size_t strides[],
1200 const bool isptr,
1201 swig_type_info *tinfo,
1202 const int tflags)
1203 {
1204 // Return an Octave array view of the C array.
1205 octave_base_value *objval = new %swiglal_oct_array_view_class(ACFTYPE)(parent, ptr, esize, ndims, dims, strides, isptr, tinfo, tflags);
1206 return octave_value(objval);
1207 }
1208%}
1209
1210%enddef // %swiglal_oct_array_frags
1211
1212// Array conversion fragments for generic arrays, e.g. SWIG-wrapped types. Note that input views
1213// are not supported, and so ISOVTYPEEXPR is 'false'.
1214%swiglal_oct_array_frags(SWIGTYPE, "swiglal_as_SWIGTYPE", "swiglal_from_SWIGTYPE",
1215 %arg(swiglal_as_SWIGTYPE(parent, objelem, elemptr, esize, isptr, tinfo, tflags)),
1216 %arg(swiglal_from_SWIGTYPE(parent, copyobj, elemptr, esize, isptr, tinfo, tflags)),
1217 octave_cell, Cell, cell_value, false);
1218
1219// Array conversion fragments for arrays of LAL strings. Note that input views are not supported,
1220// and so ISOVTYPEEXPR is 'false'.
1221%swiglal_oct_array_frags(LALchar, "SWIG_AsLALcharPtrAndSize", "SWIG_FromLALcharPtr",
1222 %arg(SWIG_AsLALcharPtrAndSize(objelem, %reinterpret_cast(elemptr, char**), 0, pelemalloc)),
1223 %arg(SWIG_FromLALcharPtr(*%reinterpret_cast(elemptr, char**))),
1224 octave_cell, Cell, cell_value, false);
1225
1226// Macro which generates array conversion function fragments to/from Octave arrays for real/fragment
1227// TYPEs which use SWIG_AsVal/From fragments.
1228%define %swiglal_oct_array_asvalfrom_frags(TYPE, OVCLASS, OVTYPE, OVVALUE, ISOVTYPEEXPR)
1229%swiglal_oct_array_frags(TYPE, SWIG_AsVal_frag(TYPE), SWIG_From_frag(TYPE),
1230 %arg(SWIG_AsVal(TYPE)(objelem, %reinterpret_cast(elemptr, TYPE*))),
1231 %arg(SWIG_From(TYPE)(*%reinterpret_cast(elemptr, TYPE*))),
1232 OVCLASS, OVTYPE, OVVALUE, ISOVTYPEEXPR);
1233%enddef
1234
1235// Array conversion fragments for integer arrays.
1236%swiglal_oct_array_asvalfrom_frags(int8_t, octave_int8_matrix, intNDArray<octave_int<int8_t> >, int8_array_value, obj.is_int8_type());
1237%swiglal_oct_array_asvalfrom_frags(uint8_t, octave_uint8_matrix, intNDArray<octave_int<uint8_t> >, uint8_array_value, obj.is_uint8_type());
1238%swiglal_oct_array_asvalfrom_frags(int16_t, octave_int16_matrix, intNDArray<octave_int<int16_t> >, int16_array_value, obj.is_int16_type());
1239%swiglal_oct_array_asvalfrom_frags(uint16_t, octave_uint16_matrix, intNDArray<octave_int<uint16_t> >, uint16_array_value, obj.is_uint16_type());
1240%swiglal_oct_array_asvalfrom_frags(int32_t, octave_int32_matrix, intNDArray<octave_int<int32_t> >, int32_array_value, obj.is_int32_type());
1241%swiglal_oct_array_asvalfrom_frags(uint32_t, octave_uint32_matrix, intNDArray<octave_int<uint32_t> >, uint32_array_value, obj.is_uint32_type());
1242%swiglal_oct_array_asvalfrom_frags(int64_t, octave_int64_matrix, intNDArray<octave_int<int64_t> >, int64_array_value, obj.is_int64_type());
1243%swiglal_oct_array_asvalfrom_frags(uint64_t, octave_uint64_matrix, intNDArray<octave_int<uint64_t> >, uint64_array_value, obj.is_uint64_type());
1244
1245// Array conversion fragments for floating-precision real arrays.
1246%swiglal_oct_array_asvalfrom_frags(float, octave_float_matrix, FloatMatrix, float_matrix_value, obj.is_real_type() && obj.is_single_type());
1247%swiglal_oct_array_asvalfrom_frags(double, octave_matrix, Matrix, matrix_value, obj.is_real_type() && obj.is_double_type());
1248
1249// Array conversion fragments for floating-precision complex arrays.
1250%swiglal_oct_array_asvalfrom_frags(gsl_complex_float, octave_float_complex_matrix, FloatComplexMatrix, float_complex_matrix_value, obj.is_complex_type() && obj.is_single_type());
1251%swiglal_oct_array_asvalfrom_frags(gsl_complex, octave_complex_matrix, ComplexMatrix, complex_matrix_value, obj.is_complex_type() && obj.is_double_type());
1252%swiglal_oct_array_asvalfrom_frags(COMPLEX8, octave_float_complex_matrix, FloatComplexMatrix, float_complex_matrix_value, obj.is_complex_type() && obj.is_single_type());
1253%swiglal_oct_array_asvalfrom_frags(COMPLEX16, octave_complex_matrix, ComplexMatrix, complex_matrix_value, obj.is_complex_type() && obj.is_double_type());
1254
1255// Local Variables:
1256// mode: c
1257// End:
#define TYPE
double cosh(double)
double acosh(double)
#define gmtime_r(timep, result)
Definition: GPSTimeNow.c:26
static REAL8TimeSeries * error(const REAL8TimeSeries *s1, const REAL8TimeSeries *s0)
const char *const name
type name
Definition: UserInput.c:198
#define crect(re, im)
Construct a COMPLEX16 from real and imaginary parts.
double complex COMPLEX16
Double-precision floating-point complex number (16 bytes total)
#define crectf(re, im)
Construct a COMPLEX8 from real and imaginary parts.
float complex COMPLEX8
Single-precision floating-point complex number (8 bytes total)